aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-03-18 13:46:37 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-03-18 13:46:37 -0400
commitd3e458d78167102cc961237cfceef6fffc80c0b3 (patch)
treee9195c1294daf053614e63ac52b0b44a28479017 /sound
parentf2e1fbb5f2177227f71c4fc0491e531dd7acd385 (diff)
parentd351cf4603edb2a5bfa9a48d06c425511c63f2a3 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6: (308 commits) ALSA: sound/pci/asihpi: check adapter index in hpi_ioctl ALSA: aloop - Fix possible IRQ lock inversion ALSA: sound/core: merge list_del()/list_add_tail() to list_move_tail() ALSA: ctxfi - use list_move() instead of list_del()/list_add() combination ALSA: firewire - msleep needs delay.h ALSA: firewire-lib, firewire-speakers: handle packet queueing errors ALSA: firewire-lib: allocate DMA buffer separately ALSA: firewire-lib: use no-info SYT for packets without SYT sample ALSA: add LaCie FireWire Speakers/Griffin FireWave Surround driver ALSA: hda - Remove an unused variable in patch_realtek.c ALSA: hda - pin-adc-mux-dmic auto-configuration of 92HD8X codecs ALSA: hda - fix digital mic selection in mixer on 92HD8X codecs ALSA: hda - Move default input-src selection to init part ALSA: hda - Initialize special cases for input src in init phase ALSA: ctxfi - Clear input settings before initialization ALSA: ctxfi - Fix SPDIF status retrieval ALSA: ctxfi - Fix incorrect SPDIF status bit mask ALSA: ctxfi - Fix microphone boost codes/comments ALSA: atiixp - Fix wrong time-out checks during ac-link reset ALSA: intel8x0m: append 'm' to "r_intel8x0" ...
Diffstat (limited to 'sound')
-rw-r--r--sound/Kconfig2
-rw-r--r--sound/Makefile2
-rw-r--r--sound/core/control.c68
-rw-r--r--sound/core/device.c7
-rw-r--r--sound/core/memalloc.c3
-rw-r--r--sound/core/oss/linear.c7
-rw-r--r--sound/core/oss/mixer_oss.c10
-rw-r--r--sound/core/oss/mulaw.c2
-rw-r--r--sound/core/oss/pcm_oss.c51
-rw-r--r--sound/core/oss/pcm_plugin.c40
-rw-r--r--sound/core/oss/pcm_plugin.h11
-rw-r--r--sound/core/oss/route.c6
-rw-r--r--sound/core/pcm.c10
-rw-r--r--sound/core/pcm_misc.c35
-rw-r--r--sound/core/pcm_native.c2
-rw-r--r--sound/core/seq/seq_clientmgr.c7
-rw-r--r--sound/core/seq/seq_memory.c6
-rw-r--r--sound/core/seq/seq_memory.h4
-rw-r--r--sound/core/seq/seq_ports.c2
-rw-r--r--sound/core/timer.c8
-rw-r--r--sound/core/vmaster.c2
-rw-r--r--sound/drivers/aloop.c19
-rw-r--r--sound/firewire/Kconfig25
-rw-r--r--sound/firewire/Makefile6
-rw-r--r--sound/firewire/amdtp.c562
-rw-r--r--sound/firewire/amdtp.h169
-rw-r--r--sound/firewire/cmp.c308
-rw-r--r--sound/firewire/cmp.h41
-rw-r--r--sound/firewire/fcp.c224
-rw-r--r--sound/firewire/fcp.h12
-rw-r--r--sound/firewire/iso-resources.c232
-rw-r--r--sound/firewire/iso-resources.h39
-rw-r--r--sound/firewire/lib.c85
-rw-r--r--sound/firewire/lib.h19
-rw-r--r--sound/firewire/packets-buffer.c74
-rw-r--r--sound/firewire/packets-buffer.h26
-rw-r--r--sound/firewire/speakers.c858
-rw-r--r--sound/oss/soundcard.c56
-rw-r--r--sound/pci/Kconfig12
-rw-r--r--sound/pci/ac97/ac97_codec.c90
-rw-r--r--sound/pci/ac97/ac97_patch.c52
-rw-r--r--sound/pci/asihpi/asihpi.c774
-rw-r--r--sound/pci/asihpi/hpi.h1214
-rw-r--r--sound/pci/asihpi/hpi6000.c299
-rw-r--r--sound/pci/asihpi/hpi6205.c603
-rw-r--r--sound/pci/asihpi/hpi6205.h7
-rw-r--r--sound/pci/asihpi/hpi_internal.h1118
-rw-r--r--sound/pci/asihpi/hpicmn.c480
-rw-r--r--sound/pci/asihpi/hpicmn.h24
-rw-r--r--sound/pci/asihpi/hpidebug.c157
-rw-r--r--sound/pci/asihpi/hpidebug.h323
-rw-r--r--sound/pci/asihpi/hpidspcd.c37
-rw-r--r--sound/pci/asihpi/hpidspcd.h2
-rw-r--r--sound/pci/asihpi/hpifunc.c2498
-rw-r--r--sound/pci/asihpi/hpimsginit.c18
-rw-r--r--sound/pci/asihpi/hpimsginit.h12
-rw-r--r--sound/pci/asihpi/hpimsgx.c203
-rw-r--r--sound/pci/asihpi/hpioctl.c90
-rw-r--r--sound/pci/asihpi/hpios.h10
-rw-r--r--sound/pci/atiixp.c2
-rw-r--r--sound/pci/atiixp_modem.c2
-rw-r--r--sound/pci/au88x0/au88x0_eq.c3
-rw-r--r--sound/pci/azt3328.c450
-rw-r--r--sound/pci/ctxfi/ctatc.c2
-rw-r--r--sound/pci/ctxfi/ctdaio.c2
-rw-r--r--sound/pci/ctxfi/cthw20k2.c28
-rw-r--r--sound/pci/ctxfi/ctmixer.c19
-rw-r--r--sound/pci/ctxfi/ctvmem.c3
-rw-r--r--sound/pci/emu10k1/emu10k1_main.c2
-rw-r--r--sound/pci/hda/hda_codec.c105
-rw-r--r--sound/pci/hda/hda_codec.h5
-rw-r--r--sound/pci/hda/hda_intel.c7
-rw-r--r--sound/pci/hda/hda_local.h24
-rw-r--r--sound/pci/hda/patch_analog.c117
-rw-r--r--sound/pci/hda/patch_conexant.c124
-rw-r--r--sound/pci/hda/patch_hdmi.c22
-rw-r--r--sound/pci/hda/patch_realtek.c206
-rw-r--r--sound/pci/hda/patch_sigmatel.c318
-rw-r--r--sound/pci/intel8x0m.c107
-rw-r--r--sound/pci/rme9652/hdspm.c4466
-rw-r--r--sound/ppc/pmac.c6
-rw-r--r--sound/soc/Kconfig2
-rw-r--r--sound/soc/Makefile2
-rw-r--r--sound/soc/codecs/Kconfig34
-rw-r--r--sound/soc/codecs/Makefile18
-rw-r--r--sound/soc/codecs/ak4104.c1
-rw-r--r--sound/soc/codecs/ak4642.c24
-rw-r--r--sound/soc/codecs/cs4270.c8
-rw-r--r--sound/soc/codecs/cs4271.c667
-rw-r--r--sound/soc/codecs/dfbmcs320.c72
-rw-r--r--sound/soc/codecs/lm4857.c276
-rw-r--r--sound/soc/codecs/max98088.c2
-rw-r--r--sound/soc/codecs/max9850.c389
-rw-r--r--sound/soc/codecs/max9850.h38
-rw-r--r--sound/soc/codecs/sgtl5000.c1513
-rw-r--r--sound/soc/codecs/sgtl5000.h400
-rw-r--r--sound/soc/codecs/sn95031.c949
-rw-r--r--sound/soc/codecs/sn95031.h132
-rw-r--r--sound/soc/codecs/tlv320aic32x4.c794
-rw-r--r--sound/soc/codecs/tlv320aic32x4.h143
-rw-r--r--sound/soc/codecs/tlv320dac33.c1
-rw-r--r--sound/soc/codecs/twl6040.c4
-rw-r--r--sound/soc/codecs/wm2000.c14
-rw-r--r--sound/soc/codecs/wm8523.c8
-rw-r--r--sound/soc/codecs/wm8741.c13
-rw-r--r--sound/soc/codecs/wm8753.c296
-rw-r--r--sound/soc/codecs/wm8804.c2
-rw-r--r--sound/soc/codecs/wm8900.c2
-rw-r--r--sound/soc/codecs/wm8903.c641
-rw-r--r--sound/soc/codecs/wm8903.h8
-rw-r--r--sound/soc/codecs/wm8904.c43
-rw-r--r--sound/soc/codecs/wm8955.c27
-rw-r--r--sound/soc/codecs/wm8961.c2
-rw-r--r--sound/soc/codecs/wm8962.c36
-rw-r--r--sound/soc/codecs/wm8978.c7
-rw-r--r--sound/soc/codecs/wm8991.c1427
-rw-r--r--sound/soc/codecs/wm8991.h833
-rw-r--r--sound/soc/codecs/wm8993.c2
-rw-r--r--sound/soc/codecs/wm8994-tables.c12
-rw-r--r--sound/soc/codecs/wm8994.c127
-rw-r--r--sound/soc/codecs/wm8994.h2
-rw-r--r--sound/soc/codecs/wm8995.c103
-rw-r--r--sound/soc/codecs/wm9081.c84
-rw-r--r--sound/soc/codecs/wm9090.c45
-rw-r--r--sound/soc/codecs/wm_hubs.c3
-rw-r--r--sound/soc/davinci/davinci-i2s.c28
-rw-r--r--sound/soc/davinci/davinci-mcasp.c29
-rw-r--r--sound/soc/ep93xx/Kconfig9
-rw-r--r--sound/soc/ep93xx/Makefile2
-rw-r--r--sound/soc/ep93xx/edb93xx.c142
-rw-r--r--sound/soc/ep93xx/ep93xx-ac97.c1
-rw-r--r--sound/soc/ep93xx/ep93xx-i2s.c31
-rw-r--r--sound/soc/ep93xx/ep93xx-pcm.c4
-rw-r--r--sound/soc/fsl/mpc8610_hpcd.c6
-rw-r--r--sound/soc/fsl/p1022_ds.c6
-rw-r--r--sound/soc/imx/Kconfig10
-rw-r--r--sound/soc/imx/Makefile2
-rw-r--r--sound/soc/imx/imx-ssi.c5
-rw-r--r--sound/soc/imx/mx27vis-aic32x4.c137
-rw-r--r--sound/soc/mid-x86/Kconfig14
-rw-r--r--sound/soc/mid-x86/Makefile5
-rw-r--r--sound/soc/mid-x86/mfld_machine.c452
-rw-r--r--sound/soc/mid-x86/sst_platform.c474
-rw-r--r--sound/soc/mid-x86/sst_platform.h63
-rw-r--r--sound/soc/omap/Kconfig1
-rw-r--r--sound/soc/omap/rx51.c131
-rw-r--r--sound/soc/pxa/raumfeld.c20
-rw-r--r--sound/soc/pxa/tosa.c4
-rw-r--r--sound/soc/pxa/z2.c7
-rw-r--r--sound/soc/pxa/zylonite.c9
-rw-r--r--sound/soc/samsung/Kconfig19
-rw-r--r--sound/soc/samsung/Makefile2
-rw-r--r--sound/soc/samsung/ac97.c8
-rw-r--r--sound/soc/samsung/ac97.h21
-rw-r--r--sound/soc/samsung/dma.c13
-rw-r--r--sound/soc/samsung/dma.h8
-rw-r--r--sound/soc/samsung/goni_wm8994.c10
-rw-r--r--sound/soc/samsung/h1940_uda1380.c9
-rw-r--r--sound/soc/samsung/i2s.c3
-rw-r--r--sound/soc/samsung/jive_wm8750.c11
-rw-r--r--sound/soc/samsung/lm4857.h32
-rw-r--r--sound/soc/samsung/ln2440sbc_alc650.c7
-rw-r--r--sound/soc/samsung/neo1973_gta02_wm8753.c504
-rw-r--r--sound/soc/samsung/neo1973_wm8753.c635
-rw-r--r--sound/soc/samsung/pcm.c118
-rw-r--r--sound/soc/samsung/pcm.h107
-rw-r--r--sound/soc/samsung/rx1950_uda1380.c11
-rw-r--r--sound/soc/samsung/s3c-i2s-v2.c3
-rw-r--r--sound/soc/samsung/s3c2412-i2s.c12
-rw-r--r--sound/soc/samsung/s3c24xx-i2s.c14
-rw-r--r--sound/soc/samsung/s3c24xx_simtec.c7
-rw-r--r--sound/soc/samsung/s3c24xx_simtec_hermes.c10
-rw-r--r--sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c12
-rw-r--r--sound/soc/samsung/s3c24xx_uda134x.c9
-rw-r--r--sound/soc/samsung/smartq_wm8987.c6
-rw-r--r--sound/soc/samsung/smdk2443_wm9710.c7
-rw-r--r--sound/soc/samsung/smdk_spdif.c5
-rw-r--r--sound/soc/samsung/smdk_wm8580.c7
-rw-r--r--sound/soc/samsung/smdk_wm9713.c5
-rw-r--r--sound/soc/samsung/spdif.c3
-rw-r--r--sound/soc/sh/fsi-ak4642.c24
-rw-r--r--sound/soc/sh/fsi-da7210.c13
-rw-r--r--sound/soc/sh/fsi-hdmi.c77
-rw-r--r--sound/soc/sh/fsi.c203
-rw-r--r--sound/soc/soc-cache.c386
-rw-r--r--sound/soc/soc-core.c548
-rw-r--r--sound/soc/soc-dapm.c257
-rw-r--r--sound/soc/soc-jack.c58
-rw-r--r--sound/soc/soc-utils.c23
-rw-r--r--sound/soc/tegra/Kconfig26
-rw-r--r--sound/soc/tegra/Makefile15
-rw-r--r--sound/soc/tegra/harmony.c393
-rw-r--r--sound/soc/tegra/tegra_asoc_utils.c155
-rw-r--r--sound/soc/tegra/tegra_asoc_utils.h45
-rw-r--r--sound/soc/tegra/tegra_das.c265
-rw-r--r--sound/soc/tegra/tegra_das.h135
-rw-r--r--sound/soc/tegra/tegra_i2s.c503
-rw-r--r--sound/soc/tegra/tegra_i2s.h165
-rw-r--r--sound/soc/tegra/tegra_pcm.c404
-rw-r--r--sound/soc/tegra/tegra_pcm.h55
-rw-r--r--sound/sound_core.c3
-rw-r--r--sound/usb/6fire/Makefile3
-rw-r--r--sound/usb/6fire/chip.c232
-rw-r--r--sound/usb/6fire/chip.h32
-rw-r--r--sound/usb/6fire/comm.c176
-rw-r--r--sound/usb/6fire/comm.h44
-rw-r--r--sound/usb/6fire/common.h30
-rw-r--r--sound/usb/6fire/control.c275
-rw-r--r--sound/usb/6fire/control.h37
-rw-r--r--sound/usb/6fire/firmware.c426
-rw-r--r--sound/usb/6fire/firmware.h27
-rw-r--r--sound/usb/6fire/midi.c203
-rw-r--r--sound/usb/6fire/midi.h46
-rw-r--r--sound/usb/6fire/pcm.c688
-rw-r--r--sound/usb/6fire/pcm.h76
-rw-r--r--sound/usb/Kconfig17
-rw-r--r--sound/usb/Makefile2
-rw-r--r--sound/usb/caiaq/audio.c1
-rw-r--r--sound/usb/caiaq/device.c6
-rw-r--r--sound/usb/caiaq/device.h1
-rw-r--r--sound/usb/card.c64
-rw-r--r--sound/usb/midi.c8
-rw-r--r--sound/usb/mixer.c65
-rw-r--r--sound/usb/mixer.h2
-rw-r--r--sound/usb/mixer_quirks.c174
-rw-r--r--sound/usb/pcm.c20
-rw-r--r--sound/usb/power.h17
-rw-r--r--sound/usb/quirks-table.h14
-rw-r--r--sound/usb/quirks.c56
-rw-r--r--sound/usb/usbaudio.h6
230 files changed, 26575 insertions, 9425 deletions
diff --git a/sound/Kconfig b/sound/Kconfig
index fcad760f5691..1fef141ef8e7 100644
--- a/sound/Kconfig
+++ b/sound/Kconfig
@@ -97,6 +97,8 @@ source "sound/sh/Kconfig"
97# here assuming USB is defined before ALSA 97# here assuming USB is defined before ALSA
98source "sound/usb/Kconfig" 98source "sound/usb/Kconfig"
99 99
100source "sound/firewire/Kconfig"
101
100# the following will depend on the order of config. 102# the following will depend on the order of config.
101# here assuming PCMCIA is defined before ALSA 103# here assuming PCMCIA is defined before ALSA
102source "sound/pcmcia/Kconfig" 104source "sound/pcmcia/Kconfig"
diff --git a/sound/Makefile b/sound/Makefile
index ec467decfa79..ce9132b1c395 100644
--- a/sound/Makefile
+++ b/sound/Makefile
@@ -6,7 +6,7 @@ obj-$(CONFIG_SOUND_PRIME) += sound_firmware.o
6obj-$(CONFIG_SOUND_PRIME) += oss/ 6obj-$(CONFIG_SOUND_PRIME) += oss/
7obj-$(CONFIG_DMASOUND) += oss/ 7obj-$(CONFIG_DMASOUND) += oss/
8obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ sh/ synth/ usb/ \ 8obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ sh/ synth/ usb/ \
9 sparc/ spi/ parisc/ pcmcia/ mips/ soc/ atmel/ 9 firewire/ sparc/ spi/ parisc/ pcmcia/ mips/ soc/ atmel/
10obj-$(CONFIG_SND_AOA) += aoa/ 10obj-$(CONFIG_SND_AOA) += aoa/
11 11
12# This one must be compilable even if sound is configured out 12# This one must be compilable even if sound is configured out
diff --git a/sound/core/control.c b/sound/core/control.c
index 9ce00ed20fba..a08ad57c49b6 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -279,33 +279,31 @@ void snd_ctl_free_one(struct snd_kcontrol *kcontrol)
279 279
280EXPORT_SYMBOL(snd_ctl_free_one); 280EXPORT_SYMBOL(snd_ctl_free_one);
281 281
282static unsigned int snd_ctl_hole_check(struct snd_card *card, 282static bool snd_ctl_remove_numid_conflict(struct snd_card *card,
283 unsigned int count) 283 unsigned int count)
284{ 284{
285 struct snd_kcontrol *kctl; 285 struct snd_kcontrol *kctl;
286 286
287 list_for_each_entry(kctl, &card->controls, list) { 287 list_for_each_entry(kctl, &card->controls, list) {
288 if ((kctl->id.numid <= card->last_numid && 288 if (kctl->id.numid < card->last_numid + 1 + count &&
289 kctl->id.numid + kctl->count > card->last_numid) || 289 kctl->id.numid + kctl->count > card->last_numid + 1) {
290 (kctl->id.numid <= card->last_numid + count - 1 && 290 card->last_numid = kctl->id.numid + kctl->count - 1;
291 kctl->id.numid + kctl->count > card->last_numid + count - 1)) 291 return true;
292 return card->last_numid = kctl->id.numid + kctl->count - 1; 292 }
293 } 293 }
294 return card->last_numid; 294 return false;
295} 295}
296 296
297static int snd_ctl_find_hole(struct snd_card *card, unsigned int count) 297static int snd_ctl_find_hole(struct snd_card *card, unsigned int count)
298{ 298{
299 unsigned int last_numid, iter = 100000; 299 unsigned int iter = 100000;
300 300
301 last_numid = card->last_numid; 301 while (snd_ctl_remove_numid_conflict(card, count)) {
302 while (last_numid != snd_ctl_hole_check(card, count)) {
303 if (--iter == 0) { 302 if (--iter == 0) {
304 /* this situation is very unlikely */ 303 /* this situation is very unlikely */
305 snd_printk(KERN_ERR "unable to allocate new control numid\n"); 304 snd_printk(KERN_ERR "unable to allocate new control numid\n");
306 return -ENOMEM; 305 return -ENOMEM;
307 } 306 }
308 last_numid = card->last_numid;
309 } 307 }
310 return 0; 308 return 0;
311} 309}
@@ -466,6 +464,52 @@ error:
466} 464}
467 465
468/** 466/**
467 * snd_ctl_activate_id - activate/inactivate the control of the given id
468 * @card: the card instance
469 * @id: the control id to activate/inactivate
470 * @active: non-zero to activate
471 *
472 * Finds the control instance with the given id, and activate or
473 * inactivate the control together with notification, if changed.
474 *
475 * Returns 0 if unchanged, 1 if changed, or a negative error code on failure.
476 */
477int snd_ctl_activate_id(struct snd_card *card, struct snd_ctl_elem_id *id,
478 int active)
479{
480 struct snd_kcontrol *kctl;
481 struct snd_kcontrol_volatile *vd;
482 unsigned int index_offset;
483 int ret;
484
485 down_write(&card->controls_rwsem);
486 kctl = snd_ctl_find_id(card, id);
487 if (kctl == NULL) {
488 ret = -ENOENT;
489 goto unlock;
490 }
491 index_offset = snd_ctl_get_ioff(kctl, &kctl->id);
492 vd = &kctl->vd[index_offset];
493 ret = 0;
494 if (active) {
495 if (!(vd->access & SNDRV_CTL_ELEM_ACCESS_INACTIVE))
496 goto unlock;
497 vd->access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
498 } else {
499 if (vd->access & SNDRV_CTL_ELEM_ACCESS_INACTIVE)
500 goto unlock;
501 vd->access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
502 }
503 ret = 1;
504 unlock:
505 up_write(&card->controls_rwsem);
506 if (ret > 0)
507 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_INFO, id);
508 return ret;
509}
510EXPORT_SYMBOL_GPL(snd_ctl_activate_id);
511
512/**
469 * snd_ctl_rename_id - replace the id of a control on the card 513 * snd_ctl_rename_id - replace the id of a control on the card
470 * @card: the card instance 514 * @card: the card instance
471 * @src_id: the old id 515 * @src_id: the old id
diff --git a/sound/core/device.c b/sound/core/device.c
index a67dfac08c03..2d1ad4b0cd65 100644
--- a/sound/core/device.c
+++ b/sound/core/device.c
@@ -225,15 +225,16 @@ int snd_device_free_all(struct snd_card *card, snd_device_cmd_t cmd)
225{ 225{
226 struct snd_device *dev; 226 struct snd_device *dev;
227 int err; 227 int err;
228 unsigned int range_low, range_high; 228 unsigned int range_low, range_high, type;
229 229
230 if (snd_BUG_ON(!card)) 230 if (snd_BUG_ON(!card))
231 return -ENXIO; 231 return -ENXIO;
232 range_low = cmd * SNDRV_DEV_TYPE_RANGE_SIZE; 232 range_low = (__force unsigned int)cmd * SNDRV_DEV_TYPE_RANGE_SIZE;
233 range_high = range_low + SNDRV_DEV_TYPE_RANGE_SIZE - 1; 233 range_high = range_low + SNDRV_DEV_TYPE_RANGE_SIZE - 1;
234 __again: 234 __again:
235 list_for_each_entry(dev, &card->devices, list) { 235 list_for_each_entry(dev, &card->devices, list) {
236 if (dev->type >= range_low && dev->type <= range_high) { 236 type = (__force unsigned int)dev->type;
237 if (type >= range_low && type <= range_high) {
237 if ((err = snd_device_free(card, dev->device_data)) < 0) 238 if ((err = snd_device_free(card, dev->device_data)) < 0)
238 return err; 239 return err;
239 goto __again; 240 goto __again;
diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c
index 9e92441f9b78..16bd9c03679b 100644
--- a/sound/core/memalloc.c
+++ b/sound/core/memalloc.c
@@ -192,7 +192,8 @@ int snd_dma_alloc_pages(int type, struct device *device, size_t size,
192 dmab->bytes = 0; 192 dmab->bytes = 0;
193 switch (type) { 193 switch (type) {
194 case SNDRV_DMA_TYPE_CONTINUOUS: 194 case SNDRV_DMA_TYPE_CONTINUOUS:
195 dmab->area = snd_malloc_pages(size, (unsigned long)device); 195 dmab->area = snd_malloc_pages(size,
196 (__force gfp_t)(unsigned long)device);
196 dmab->addr = 0; 197 dmab->addr = 0;
197 break; 198 break;
198#ifdef CONFIG_HAS_DMA 199#ifdef CONFIG_HAS_DMA
diff --git a/sound/core/oss/linear.c b/sound/core/oss/linear.c
index 4c1d16827199..13b3f6f49fae 100644
--- a/sound/core/oss/linear.c
+++ b/sound/core/oss/linear.c
@@ -114,7 +114,8 @@ static snd_pcm_sframes_t linear_transfer(struct snd_pcm_plugin *plugin,
114 return frames; 114 return frames;
115} 115}
116 116
117static void init_data(struct linear_priv *data, int src_format, int dst_format) 117static void init_data(struct linear_priv *data,
118 snd_pcm_format_t src_format, snd_pcm_format_t dst_format)
118{ 119{
119 int src_le, dst_le, src_bytes, dst_bytes; 120 int src_le, dst_le, src_bytes, dst_bytes;
120 121
@@ -140,9 +141,9 @@ static void init_data(struct linear_priv *data, int src_format, int dst_format)
140 if (snd_pcm_format_signed(src_format) != 141 if (snd_pcm_format_signed(src_format) !=
141 snd_pcm_format_signed(dst_format)) { 142 snd_pcm_format_signed(dst_format)) {
142 if (dst_le) 143 if (dst_le)
143 data->flip = cpu_to_le32(0x80000000); 144 data->flip = (__force u32)cpu_to_le32(0x80000000);
144 else 145 else
145 data->flip = cpu_to_be32(0x80000000); 146 data->flip = (__force u32)cpu_to_be32(0x80000000);
146 } 147 }
147} 148}
148 149
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c
index 822dd56993ca..d8359cfeca15 100644
--- a/sound/core/oss/mixer_oss.c
+++ b/sound/core/oss/mixer_oss.c
@@ -190,9 +190,10 @@ static int snd_mixer_oss_get_recsrc(struct snd_mixer_oss_file *fmixer)
190 return -EIO; 190 return -EIO;
191 if (mixer->put_recsrc && mixer->get_recsrc) { /* exclusive */ 191 if (mixer->put_recsrc && mixer->get_recsrc) { /* exclusive */
192 int err; 192 int err;
193 if ((err = mixer->get_recsrc(fmixer, &result)) < 0) 193 unsigned int index;
194 if ((err = mixer->get_recsrc(fmixer, &index)) < 0)
194 return err; 195 return err;
195 result = 1 << result; 196 result = 1 << index;
196 } else { 197 } else {
197 struct snd_mixer_oss_slot *pslot; 198 struct snd_mixer_oss_slot *pslot;
198 int chn; 199 int chn;
@@ -214,6 +215,7 @@ static int snd_mixer_oss_set_recsrc(struct snd_mixer_oss_file *fmixer, int recsr
214 struct snd_mixer_oss *mixer = fmixer->mixer; 215 struct snd_mixer_oss *mixer = fmixer->mixer;
215 struct snd_mixer_oss_slot *pslot; 216 struct snd_mixer_oss_slot *pslot;
216 int chn, active; 217 int chn, active;
218 unsigned int index;
217 int result = 0; 219 int result = 0;
218 220
219 if (mixer == NULL) 221 if (mixer == NULL)
@@ -222,8 +224,8 @@ static int snd_mixer_oss_set_recsrc(struct snd_mixer_oss_file *fmixer, int recsr
222 if (recsrc & ~mixer->oss_recsrc) 224 if (recsrc & ~mixer->oss_recsrc)
223 recsrc &= ~mixer->oss_recsrc; 225 recsrc &= ~mixer->oss_recsrc;
224 mixer->put_recsrc(fmixer, ffz(~recsrc)); 226 mixer->put_recsrc(fmixer, ffz(~recsrc));
225 mixer->get_recsrc(fmixer, &result); 227 mixer->get_recsrc(fmixer, &index);
226 result = 1 << result; 228 result = 1 << index;
227 } 229 }
228 for (chn = 0; chn < 31; chn++) { 230 for (chn = 0; chn < 31; chn++) {
229 pslot = &mixer->slots[chn]; 231 pslot = &mixer->slots[chn];
diff --git a/sound/core/oss/mulaw.c b/sound/core/oss/mulaw.c
index f7649d4d950b..7915564bd394 100644
--- a/sound/core/oss/mulaw.c
+++ b/sound/core/oss/mulaw.c
@@ -274,7 +274,7 @@ static snd_pcm_sframes_t mulaw_transfer(struct snd_pcm_plugin *plugin,
274 return frames; 274 return frames;
275} 275}
276 276
277static void init_data(struct mulaw_priv *data, int format) 277static void init_data(struct mulaw_priv *data, snd_pcm_format_t format)
278{ 278{
279#ifdef SNDRV_LITTLE_ENDIAN 279#ifdef SNDRV_LITTLE_ENDIAN
280 data->cvt_endian = snd_pcm_format_big_endian(format) > 0; 280 data->cvt_endian = snd_pcm_format_big_endian(format) > 0;
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index a2e4eb324699..23c34a02894b 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -41,6 +41,7 @@
41#include <sound/info.h> 41#include <sound/info.h>
42#include <linux/soundcard.h> 42#include <linux/soundcard.h>
43#include <sound/initval.h> 43#include <sound/initval.h>
44#include <sound/mixer_oss.h>
44 45
45#define OSS_ALSAEMULVER _SIOR ('M', 249, int) 46#define OSS_ALSAEMULVER _SIOR ('M', 249, int)
46 47
@@ -60,7 +61,6 @@ MODULE_PARM_DESC(nonblock_open, "Don't block opening busy PCM devices.");
60MODULE_ALIAS_SNDRV_MINOR(SNDRV_MINOR_OSS_PCM); 61MODULE_ALIAS_SNDRV_MINOR(SNDRV_MINOR_OSS_PCM);
61MODULE_ALIAS_SNDRV_MINOR(SNDRV_MINOR_OSS_PCM1); 62MODULE_ALIAS_SNDRV_MINOR(SNDRV_MINOR_OSS_PCM1);
62 63
63extern int snd_mixer_oss_ioctl_card(struct snd_card *card, unsigned int cmd, unsigned long arg);
64static int snd_pcm_oss_get_rate(struct snd_pcm_oss_file *pcm_oss_file); 64static int snd_pcm_oss_get_rate(struct snd_pcm_oss_file *pcm_oss_file);
65static int snd_pcm_oss_get_channels(struct snd_pcm_oss_file *pcm_oss_file); 65static int snd_pcm_oss_get_channels(struct snd_pcm_oss_file *pcm_oss_file);
66static int snd_pcm_oss_get_format(struct snd_pcm_oss_file *pcm_oss_file); 66static int snd_pcm_oss_get_format(struct snd_pcm_oss_file *pcm_oss_file);
@@ -656,7 +656,7 @@ snd_pcm_uframes_t get_hw_ptr_period(struct snd_pcm_runtime *runtime)
656#define AFMT_AC3 0x00000400 656#define AFMT_AC3 0x00000400
657#define AFMT_VORBIS 0x00000800 657#define AFMT_VORBIS 0x00000800
658 658
659static int snd_pcm_oss_format_from(int format) 659static snd_pcm_format_t snd_pcm_oss_format_from(int format)
660{ 660{
661 switch (format) { 661 switch (format) {
662 case AFMT_MU_LAW: return SNDRV_PCM_FORMAT_MU_LAW; 662 case AFMT_MU_LAW: return SNDRV_PCM_FORMAT_MU_LAW;
@@ -680,7 +680,7 @@ static int snd_pcm_oss_format_from(int format)
680 } 680 }
681} 681}
682 682
683static int snd_pcm_oss_format_to(int format) 683static int snd_pcm_oss_format_to(snd_pcm_format_t format)
684{ 684{
685 switch (format) { 685 switch (format) {
686 case SNDRV_PCM_FORMAT_MU_LAW: return AFMT_MU_LAW; 686 case SNDRV_PCM_FORMAT_MU_LAW: return AFMT_MU_LAW;
@@ -843,7 +843,8 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream)
843 size_t oss_frame_size; 843 size_t oss_frame_size;
844 int err; 844 int err;
845 int direct; 845 int direct;
846 int format, sformat, n; 846 snd_pcm_format_t format, sformat;
847 int n;
847 struct snd_mask sformat_mask; 848 struct snd_mask sformat_mask;
848 struct snd_mask mask; 849 struct snd_mask mask;
849 850
@@ -868,11 +869,11 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream)
868 _snd_pcm_hw_param_min(sparams, SNDRV_PCM_HW_PARAM_PERIODS, 2, 0); 869 _snd_pcm_hw_param_min(sparams, SNDRV_PCM_HW_PARAM_PERIODS, 2, 0);
869 snd_mask_none(&mask); 870 snd_mask_none(&mask);
870 if (atomic_read(&substream->mmap_count)) 871 if (atomic_read(&substream->mmap_count))
871 snd_mask_set(&mask, SNDRV_PCM_ACCESS_MMAP_INTERLEAVED); 872 snd_mask_set(&mask, (__force int)SNDRV_PCM_ACCESS_MMAP_INTERLEAVED);
872 else { 873 else {
873 snd_mask_set(&mask, SNDRV_PCM_ACCESS_RW_INTERLEAVED); 874 snd_mask_set(&mask, (__force int)SNDRV_PCM_ACCESS_RW_INTERLEAVED);
874 if (!direct) 875 if (!direct)
875 snd_mask_set(&mask, SNDRV_PCM_ACCESS_RW_NONINTERLEAVED); 876 snd_mask_set(&mask, (__force int)SNDRV_PCM_ACCESS_RW_NONINTERLEAVED);
876 } 877 }
877 err = snd_pcm_hw_param_mask(substream, sparams, SNDRV_PCM_HW_PARAM_ACCESS, &mask); 878 err = snd_pcm_hw_param_mask(substream, sparams, SNDRV_PCM_HW_PARAM_ACCESS, &mask);
878 if (err < 0) { 879 if (err < 0) {
@@ -891,19 +892,22 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream)
891 else 892 else
892 sformat = snd_pcm_plug_slave_format(format, &sformat_mask); 893 sformat = snd_pcm_plug_slave_format(format, &sformat_mask);
893 894
894 if (sformat < 0 || !snd_mask_test(&sformat_mask, sformat)) { 895 if ((__force int)sformat < 0 ||
895 for (sformat = 0; sformat <= SNDRV_PCM_FORMAT_LAST; sformat++) { 896 !snd_mask_test(&sformat_mask, (__force int)sformat)) {
896 if (snd_mask_test(&sformat_mask, sformat) && 897 for (sformat = (__force snd_pcm_format_t)0;
898 (__force int)sformat <= (__force int)SNDRV_PCM_FORMAT_LAST;
899 sformat = (__force snd_pcm_format_t)((__force int)sformat + 1)) {
900 if (snd_mask_test(&sformat_mask, (__force int)sformat) &&
897 snd_pcm_oss_format_to(sformat) >= 0) 901 snd_pcm_oss_format_to(sformat) >= 0)
898 break; 902 break;
899 } 903 }
900 if (sformat > SNDRV_PCM_FORMAT_LAST) { 904 if ((__force int)sformat > (__force int)SNDRV_PCM_FORMAT_LAST) {
901 snd_printd("Cannot find a format!!!\n"); 905 snd_printd("Cannot find a format!!!\n");
902 err = -EINVAL; 906 err = -EINVAL;
903 goto failure; 907 goto failure;
904 } 908 }
905 } 909 }
906 err = _snd_pcm_hw_param_set(sparams, SNDRV_PCM_HW_PARAM_FORMAT, sformat, 0); 910 err = _snd_pcm_hw_param_set(sparams, SNDRV_PCM_HW_PARAM_FORMAT, (__force int)sformat, 0);
907 if (err < 0) 911 if (err < 0)
908 goto failure; 912 goto failure;
909 913
@@ -912,9 +916,9 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream)
912 } else { 916 } else {
913 _snd_pcm_hw_params_any(params); 917 _snd_pcm_hw_params_any(params);
914 _snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_ACCESS, 918 _snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_ACCESS,
915 SNDRV_PCM_ACCESS_RW_INTERLEAVED, 0); 919 (__force int)SNDRV_PCM_ACCESS_RW_INTERLEAVED, 0);
916 _snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_FORMAT, 920 _snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_FORMAT,
917 snd_pcm_oss_format_from(runtime->oss.format), 0); 921 (__force int)snd_pcm_oss_format_from(runtime->oss.format), 0);
918 _snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_CHANNELS, 922 _snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_CHANNELS,
919 runtime->oss.channels, 0); 923 runtime->oss.channels, 0);
920 _snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_RATE, 924 _snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_RATE,
@@ -1185,10 +1189,10 @@ snd_pcm_sframes_t snd_pcm_oss_write3(struct snd_pcm_substream *substream, const
1185 if (in_kernel) { 1189 if (in_kernel) {
1186 mm_segment_t fs; 1190 mm_segment_t fs;
1187 fs = snd_enter_user(); 1191 fs = snd_enter_user();
1188 ret = snd_pcm_lib_write(substream, (void __user *)ptr, frames); 1192 ret = snd_pcm_lib_write(substream, (void __force __user *)ptr, frames);
1189 snd_leave_user(fs); 1193 snd_leave_user(fs);
1190 } else { 1194 } else {
1191 ret = snd_pcm_lib_write(substream, (void __user *)ptr, frames); 1195 ret = snd_pcm_lib_write(substream, (void __force __user *)ptr, frames);
1192 } 1196 }
1193 if (ret != -EPIPE && ret != -ESTRPIPE) 1197 if (ret != -EPIPE && ret != -ESTRPIPE)
1194 break; 1198 break;
@@ -1230,10 +1234,10 @@ snd_pcm_sframes_t snd_pcm_oss_read3(struct snd_pcm_substream *substream, char *p
1230 if (in_kernel) { 1234 if (in_kernel) {
1231 mm_segment_t fs; 1235 mm_segment_t fs;
1232 fs = snd_enter_user(); 1236 fs = snd_enter_user();
1233 ret = snd_pcm_lib_read(substream, (void __user *)ptr, frames); 1237 ret = snd_pcm_lib_read(substream, (void __force __user *)ptr, frames);
1234 snd_leave_user(fs); 1238 snd_leave_user(fs);
1235 } else { 1239 } else {
1236 ret = snd_pcm_lib_read(substream, (void __user *)ptr, frames); 1240 ret = snd_pcm_lib_read(substream, (void __force __user *)ptr, frames);
1237 } 1241 }
1238 if (ret == -EPIPE) { 1242 if (ret == -EPIPE) {
1239 if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) { 1243 if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) {
@@ -1333,7 +1337,7 @@ static ssize_t snd_pcm_oss_write2(struct snd_pcm_substream *substream, const cha
1333 struct snd_pcm_plugin_channel *channels; 1337 struct snd_pcm_plugin_channel *channels;
1334 size_t oss_frame_bytes = (runtime->oss.plugin_first->src_width * runtime->oss.plugin_first->src_format.channels) / 8; 1338 size_t oss_frame_bytes = (runtime->oss.plugin_first->src_width * runtime->oss.plugin_first->src_format.channels) / 8;
1335 if (!in_kernel) { 1339 if (!in_kernel) {
1336 if (copy_from_user(runtime->oss.buffer, (const char __user *)buf, bytes)) 1340 if (copy_from_user(runtime->oss.buffer, (const char __force __user *)buf, bytes))
1337 return -EFAULT; 1341 return -EFAULT;
1338 buf = runtime->oss.buffer; 1342 buf = runtime->oss.buffer;
1339 } 1343 }
@@ -1429,7 +1433,7 @@ static ssize_t snd_pcm_oss_read2(struct snd_pcm_substream *substream, char *buf,
1429 struct snd_pcm_runtime *runtime = substream->runtime; 1433 struct snd_pcm_runtime *runtime = substream->runtime;
1430 snd_pcm_sframes_t frames, frames1; 1434 snd_pcm_sframes_t frames, frames1;
1431#ifdef CONFIG_SND_PCM_OSS_PLUGINS 1435#ifdef CONFIG_SND_PCM_OSS_PLUGINS
1432 char __user *final_dst = (char __user *)buf; 1436 char __user *final_dst = (char __force __user *)buf;
1433 if (runtime->oss.plugin_first) { 1437 if (runtime->oss.plugin_first) {
1434 struct snd_pcm_plugin_channel *channels; 1438 struct snd_pcm_plugin_channel *channels;
1435 size_t oss_frame_bytes = (runtime->oss.plugin_last->dst_width * runtime->oss.plugin_last->dst_format.channels) / 8; 1439 size_t oss_frame_bytes = (runtime->oss.plugin_last->dst_width * runtime->oss.plugin_last->dst_format.channels) / 8;
@@ -1549,6 +1553,7 @@ static int snd_pcm_oss_sync1(struct snd_pcm_substream *substream, size_t size)
1549{ 1553{
1550 struct snd_pcm_runtime *runtime; 1554 struct snd_pcm_runtime *runtime;
1551 ssize_t result = 0; 1555 ssize_t result = 0;
1556 snd_pcm_state_t state;
1552 long res; 1557 long res;
1553 wait_queue_t wait; 1558 wait_queue_t wait;
1554 1559
@@ -1570,9 +1575,9 @@ static int snd_pcm_oss_sync1(struct snd_pcm_substream *substream, size_t size)
1570 result = 0; 1575 result = 0;
1571 set_current_state(TASK_INTERRUPTIBLE); 1576 set_current_state(TASK_INTERRUPTIBLE);
1572 snd_pcm_stream_lock_irq(substream); 1577 snd_pcm_stream_lock_irq(substream);
1573 res = runtime->status->state; 1578 state = runtime->status->state;
1574 snd_pcm_stream_unlock_irq(substream); 1579 snd_pcm_stream_unlock_irq(substream);
1575 if (res != SNDRV_PCM_STATE_RUNNING) { 1580 if (state != SNDRV_PCM_STATE_RUNNING) {
1576 set_current_state(TASK_RUNNING); 1581 set_current_state(TASK_RUNNING);
1577 break; 1582 break;
1578 } 1583 }
@@ -1658,7 +1663,7 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file)
1658 size1); 1663 size1);
1659 size1 /= runtime->channels; /* frames */ 1664 size1 /= runtime->channels; /* frames */
1660 fs = snd_enter_user(); 1665 fs = snd_enter_user();
1661 snd_pcm_lib_write(substream, (void __user *)runtime->oss.buffer, size1); 1666 snd_pcm_lib_write(substream, (void __force __user *)runtime->oss.buffer, size1);
1662 snd_leave_user(fs); 1667 snd_leave_user(fs);
1663 } 1668 }
1664 } else if (runtime->access == SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) { 1669 } else if (runtime->access == SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) {
diff --git a/sound/core/oss/pcm_plugin.c b/sound/core/oss/pcm_plugin.c
index 6751daa3bb50..71cc3ddf5c15 100644
--- a/sound/core/oss/pcm_plugin.c
+++ b/sound/core/oss/pcm_plugin.c
@@ -264,7 +264,7 @@ snd_pcm_sframes_t snd_pcm_plug_slave_size(struct snd_pcm_substream *plug, snd_pc
264 return frames; 264 return frames;
265} 265}
266 266
267static int snd_pcm_plug_formats(struct snd_mask *mask, int format) 267static int snd_pcm_plug_formats(struct snd_mask *mask, snd_pcm_format_t format)
268{ 268{
269 struct snd_mask formats = *mask; 269 struct snd_mask formats = *mask;
270 u64 linfmts = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8 | 270 u64 linfmts = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8 |
@@ -276,16 +276,16 @@ static int snd_pcm_plug_formats(struct snd_mask *mask, int format)
276 SNDRV_PCM_FMTBIT_U24_3BE | SNDRV_PCM_FMTBIT_S24_3BE | 276 SNDRV_PCM_FMTBIT_U24_3BE | SNDRV_PCM_FMTBIT_S24_3BE |
277 SNDRV_PCM_FMTBIT_U32_LE | SNDRV_PCM_FMTBIT_S32_LE | 277 SNDRV_PCM_FMTBIT_U32_LE | SNDRV_PCM_FMTBIT_S32_LE |
278 SNDRV_PCM_FMTBIT_U32_BE | SNDRV_PCM_FMTBIT_S32_BE); 278 SNDRV_PCM_FMTBIT_U32_BE | SNDRV_PCM_FMTBIT_S32_BE);
279 snd_mask_set(&formats, SNDRV_PCM_FORMAT_MU_LAW); 279 snd_mask_set(&formats, (__force int)SNDRV_PCM_FORMAT_MU_LAW);
280 280
281 if (formats.bits[0] & (u32)linfmts) 281 if (formats.bits[0] & (u32)linfmts)
282 formats.bits[0] |= (u32)linfmts; 282 formats.bits[0] |= (u32)linfmts;
283 if (formats.bits[1] & (u32)(linfmts >> 32)) 283 if (formats.bits[1] & (u32)(linfmts >> 32))
284 formats.bits[1] |= (u32)(linfmts >> 32); 284 formats.bits[1] |= (u32)(linfmts >> 32);
285 return snd_mask_test(&formats, format); 285 return snd_mask_test(&formats, (__force int)format);
286} 286}
287 287
288static int preferred_formats[] = { 288static snd_pcm_format_t preferred_formats[] = {
289 SNDRV_PCM_FORMAT_S16_LE, 289 SNDRV_PCM_FORMAT_S16_LE,
290 SNDRV_PCM_FORMAT_S16_BE, 290 SNDRV_PCM_FORMAT_S16_BE,
291 SNDRV_PCM_FORMAT_U16_LE, 291 SNDRV_PCM_FORMAT_U16_LE,
@@ -306,24 +306,25 @@ static int preferred_formats[] = {
306 SNDRV_PCM_FORMAT_U8 306 SNDRV_PCM_FORMAT_U8
307}; 307};
308 308
309int snd_pcm_plug_slave_format(int format, struct snd_mask *format_mask) 309snd_pcm_format_t snd_pcm_plug_slave_format(snd_pcm_format_t format,
310 struct snd_mask *format_mask)
310{ 311{
311 int i; 312 int i;
312 313
313 if (snd_mask_test(format_mask, format)) 314 if (snd_mask_test(format_mask, (__force int)format))
314 return format; 315 return format;
315 if (! snd_pcm_plug_formats(format_mask, format)) 316 if (!snd_pcm_plug_formats(format_mask, format))
316 return -EINVAL; 317 return (__force snd_pcm_format_t)-EINVAL;
317 if (snd_pcm_format_linear(format)) { 318 if (snd_pcm_format_linear(format)) {
318 unsigned int width = snd_pcm_format_width(format); 319 unsigned int width = snd_pcm_format_width(format);
319 int unsignd = snd_pcm_format_unsigned(format) > 0; 320 int unsignd = snd_pcm_format_unsigned(format) > 0;
320 int big = snd_pcm_format_big_endian(format) > 0; 321 int big = snd_pcm_format_big_endian(format) > 0;
321 unsigned int badness, best = -1; 322 unsigned int badness, best = -1;
322 int best_format = -1; 323 snd_pcm_format_t best_format = (__force snd_pcm_format_t)-1;
323 for (i = 0; i < ARRAY_SIZE(preferred_formats); i++) { 324 for (i = 0; i < ARRAY_SIZE(preferred_formats); i++) {
324 int f = preferred_formats[i]; 325 snd_pcm_format_t f = preferred_formats[i];
325 unsigned int w; 326 unsigned int w;
326 if (!snd_mask_test(format_mask, f)) 327 if (!snd_mask_test(format_mask, (__force int)f))
327 continue; 328 continue;
328 w = snd_pcm_format_width(f); 329 w = snd_pcm_format_width(f);
329 if (w >= width) 330 if (w >= width)
@@ -337,17 +338,20 @@ int snd_pcm_plug_slave_format(int format, struct snd_mask *format_mask)
337 best = badness; 338 best = badness;
338 } 339 }
339 } 340 }
340 return best_format >= 0 ? best_format : -EINVAL; 341 if ((__force int)best_format >= 0)
342 return best_format;
343 else
344 return (__force snd_pcm_format_t)-EINVAL;
341 } else { 345 } else {
342 switch (format) { 346 switch (format) {
343 case SNDRV_PCM_FORMAT_MU_LAW: 347 case SNDRV_PCM_FORMAT_MU_LAW:
344 for (i = 0; i < ARRAY_SIZE(preferred_formats); ++i) { 348 for (i = 0; i < ARRAY_SIZE(preferred_formats); ++i) {
345 int format1 = preferred_formats[i]; 349 snd_pcm_format_t format1 = preferred_formats[i];
346 if (snd_mask_test(format_mask, format1)) 350 if (snd_mask_test(format_mask, (__force int)format1))
347 return format1; 351 return format1;
348 } 352 }
349 default: 353 default:
350 return -EINVAL; 354 return (__force snd_pcm_format_t)-EINVAL;
351 } 355 }
352 } 356 }
353} 357}
@@ -359,7 +363,7 @@ int snd_pcm_plug_format_plugins(struct snd_pcm_substream *plug,
359 struct snd_pcm_plugin_format tmpformat; 363 struct snd_pcm_plugin_format tmpformat;
360 struct snd_pcm_plugin_format dstformat; 364 struct snd_pcm_plugin_format dstformat;
361 struct snd_pcm_plugin_format srcformat; 365 struct snd_pcm_plugin_format srcformat;
362 int src_access, dst_access; 366 snd_pcm_access_t src_access, dst_access;
363 struct snd_pcm_plugin *plugin = NULL; 367 struct snd_pcm_plugin *plugin = NULL;
364 int err; 368 int err;
365 int stream = snd_pcm_plug_stream(plug); 369 int stream = snd_pcm_plug_stream(plug);
@@ -641,7 +645,7 @@ snd_pcm_sframes_t snd_pcm_plug_read_transfer(struct snd_pcm_substream *plug, str
641} 645}
642 646
643int snd_pcm_area_silence(const struct snd_pcm_channel_area *dst_area, size_t dst_offset, 647int snd_pcm_area_silence(const struct snd_pcm_channel_area *dst_area, size_t dst_offset,
644 size_t samples, int format) 648 size_t samples, snd_pcm_format_t format)
645{ 649{
646 /* FIXME: sub byte resolution and odd dst_offset */ 650 /* FIXME: sub byte resolution and odd dst_offset */
647 unsigned char *dst; 651 unsigned char *dst;
@@ -688,7 +692,7 @@ int snd_pcm_area_silence(const struct snd_pcm_channel_area *dst_area, size_t dst
688 692
689int snd_pcm_area_copy(const struct snd_pcm_channel_area *src_area, size_t src_offset, 693int snd_pcm_area_copy(const struct snd_pcm_channel_area *src_area, size_t src_offset,
690 const struct snd_pcm_channel_area *dst_area, size_t dst_offset, 694 const struct snd_pcm_channel_area *dst_area, size_t dst_offset,
691 size_t samples, int format) 695 size_t samples, snd_pcm_format_t format)
692{ 696{
693 /* FIXME: sub byte resolution and odd dst_offset */ 697 /* FIXME: sub byte resolution and odd dst_offset */
694 char *src, *dst; 698 char *src, *dst;
diff --git a/sound/core/oss/pcm_plugin.h b/sound/core/oss/pcm_plugin.h
index b9afab603711..a5035c2369a6 100644
--- a/sound/core/oss/pcm_plugin.h
+++ b/sound/core/oss/pcm_plugin.h
@@ -46,7 +46,7 @@ struct snd_pcm_plugin_channel {
46}; 46};
47 47
48struct snd_pcm_plugin_format { 48struct snd_pcm_plugin_format {
49 int format; 49 snd_pcm_format_t format;
50 unsigned int rate; 50 unsigned int rate;
51 unsigned int channels; 51 unsigned int channels;
52}; 52};
@@ -58,7 +58,7 @@ struct snd_pcm_plugin {
58 struct snd_pcm_plugin_format dst_format; /* destination format */ 58 struct snd_pcm_plugin_format dst_format; /* destination format */
59 int src_width; /* sample width in bits */ 59 int src_width; /* sample width in bits */
60 int dst_width; /* sample width in bits */ 60 int dst_width; /* sample width in bits */
61 int access; 61 snd_pcm_access_t access;
62 snd_pcm_sframes_t (*src_frames)(struct snd_pcm_plugin *plugin, snd_pcm_uframes_t dst_frames); 62 snd_pcm_sframes_t (*src_frames)(struct snd_pcm_plugin *plugin, snd_pcm_uframes_t dst_frames);
63 snd_pcm_sframes_t (*dst_frames)(struct snd_pcm_plugin *plugin, snd_pcm_uframes_t src_frames); 63 snd_pcm_sframes_t (*dst_frames)(struct snd_pcm_plugin *plugin, snd_pcm_uframes_t src_frames);
64 snd_pcm_sframes_t (*client_channels)(struct snd_pcm_plugin *plugin, 64 snd_pcm_sframes_t (*client_channels)(struct snd_pcm_plugin *plugin,
@@ -125,7 +125,8 @@ int snd_pcm_plug_format_plugins(struct snd_pcm_substream *substream,
125 struct snd_pcm_hw_params *params, 125 struct snd_pcm_hw_params *params,
126 struct snd_pcm_hw_params *slave_params); 126 struct snd_pcm_hw_params *slave_params);
127 127
128int snd_pcm_plug_slave_format(int format, struct snd_mask *format_mask); 128snd_pcm_format_t snd_pcm_plug_slave_format(snd_pcm_format_t format,
129 struct snd_mask *format_mask);
129 130
130int snd_pcm_plugin_append(struct snd_pcm_plugin *plugin); 131int snd_pcm_plugin_append(struct snd_pcm_plugin *plugin);
131 132
@@ -146,12 +147,12 @@ snd_pcm_sframes_t snd_pcm_plugin_client_channels(struct snd_pcm_plugin *plugin,
146 147
147int snd_pcm_area_silence(const struct snd_pcm_channel_area *dst_channel, 148int snd_pcm_area_silence(const struct snd_pcm_channel_area *dst_channel,
148 size_t dst_offset, 149 size_t dst_offset,
149 size_t samples, int format); 150 size_t samples, snd_pcm_format_t format);
150int snd_pcm_area_copy(const struct snd_pcm_channel_area *src_channel, 151int snd_pcm_area_copy(const struct snd_pcm_channel_area *src_channel,
151 size_t src_offset, 152 size_t src_offset,
152 const struct snd_pcm_channel_area *dst_channel, 153 const struct snd_pcm_channel_area *dst_channel,
153 size_t dst_offset, 154 size_t dst_offset,
154 size_t samples, int format); 155 size_t samples, snd_pcm_format_t format);
155 156
156void *snd_pcm_plug_buf_alloc(struct snd_pcm_substream *plug, snd_pcm_uframes_t size); 157void *snd_pcm_plug_buf_alloc(struct snd_pcm_substream *plug, snd_pcm_uframes_t size);
157void snd_pcm_plug_buf_unlock(struct snd_pcm_substream *plug, void *ptr); 158void snd_pcm_plug_buf_unlock(struct snd_pcm_substream *plug, void *ptr);
diff --git a/sound/core/oss/route.c b/sound/core/oss/route.c
index bbe25d8c450a..c8171f5783c8 100644
--- a/sound/core/oss/route.c
+++ b/sound/core/oss/route.c
@@ -25,7 +25,7 @@
25#include "pcm_plugin.h" 25#include "pcm_plugin.h"
26 26
27static void zero_areas(struct snd_pcm_plugin_channel *dvp, int ndsts, 27static void zero_areas(struct snd_pcm_plugin_channel *dvp, int ndsts,
28 snd_pcm_uframes_t frames, int format) 28 snd_pcm_uframes_t frames, snd_pcm_format_t format)
29{ 29{
30 int dst = 0; 30 int dst = 0;
31 for (; dst < ndsts; ++dst) { 31 for (; dst < ndsts; ++dst) {
@@ -38,7 +38,7 @@ static void zero_areas(struct snd_pcm_plugin_channel *dvp, int ndsts,
38 38
39static inline void copy_area(const struct snd_pcm_plugin_channel *src_channel, 39static inline void copy_area(const struct snd_pcm_plugin_channel *src_channel,
40 struct snd_pcm_plugin_channel *dst_channel, 40 struct snd_pcm_plugin_channel *dst_channel,
41 snd_pcm_uframes_t frames, int format) 41 snd_pcm_uframes_t frames, snd_pcm_format_t format)
42{ 42{
43 dst_channel->enabled = 1; 43 dst_channel->enabled = 1;
44 snd_pcm_area_copy(&src_channel->area, 0, &dst_channel->area, 0, frames, format); 44 snd_pcm_area_copy(&src_channel->area, 0, &dst_channel->area, 0, frames, format);
@@ -51,7 +51,7 @@ static snd_pcm_sframes_t route_transfer(struct snd_pcm_plugin *plugin,
51{ 51{
52 int nsrcs, ndsts, dst; 52 int nsrcs, ndsts, dst;
53 struct snd_pcm_plugin_channel *dvp; 53 struct snd_pcm_plugin_channel *dvp;
54 int format; 54 snd_pcm_format_t format;
55 55
56 if (snd_BUG_ON(!plugin || !src_channels || !dst_channels)) 56 if (snd_BUG_ON(!plugin || !src_channels || !dst_channels))
57 return -ENXIO; 57 return -ENXIO;
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 6b4b1287b314..ee9abb2d9001 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -211,9 +211,9 @@ static char *snd_pcm_format_names[] = {
211 211
212const char *snd_pcm_format_name(snd_pcm_format_t format) 212const char *snd_pcm_format_name(snd_pcm_format_t format)
213{ 213{
214 if (format >= ARRAY_SIZE(snd_pcm_format_names)) 214 if ((__force unsigned int)format >= ARRAY_SIZE(snd_pcm_format_names))
215 return "Unknown"; 215 return "Unknown";
216 return snd_pcm_format_names[format]; 216 return snd_pcm_format_names[(__force unsigned int)format];
217} 217}
218EXPORT_SYMBOL_GPL(snd_pcm_format_name); 218EXPORT_SYMBOL_GPL(snd_pcm_format_name);
219 219
@@ -269,12 +269,12 @@ static const char *snd_pcm_stream_name(int stream)
269 269
270static const char *snd_pcm_access_name(snd_pcm_access_t access) 270static const char *snd_pcm_access_name(snd_pcm_access_t access)
271{ 271{
272 return snd_pcm_access_names[access]; 272 return snd_pcm_access_names[(__force int)access];
273} 273}
274 274
275static const char *snd_pcm_subformat_name(snd_pcm_subformat_t subformat) 275static const char *snd_pcm_subformat_name(snd_pcm_subformat_t subformat)
276{ 276{
277 return snd_pcm_subformat_names[subformat]; 277 return snd_pcm_subformat_names[(__force int)subformat];
278} 278}
279 279
280static const char *snd_pcm_tstamp_mode_name(int mode) 280static const char *snd_pcm_tstamp_mode_name(int mode)
@@ -284,7 +284,7 @@ static const char *snd_pcm_tstamp_mode_name(int mode)
284 284
285static const char *snd_pcm_state_name(snd_pcm_state_t state) 285static const char *snd_pcm_state_name(snd_pcm_state_t state)
286{ 286{
287 return snd_pcm_state_names[state]; 287 return snd_pcm_state_names[(__force int)state];
288} 288}
289 289
290#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE) 290#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
diff --git a/sound/core/pcm_misc.c b/sound/core/pcm_misc.c
index 434af3c56d52..88f02e3866e0 100644
--- a/sound/core/pcm_misc.c
+++ b/sound/core/pcm_misc.c
@@ -35,7 +35,10 @@ struct pcm_format_data {
35 unsigned char silence[8]; /* silence data to fill */ 35 unsigned char silence[8]; /* silence data to fill */
36}; 36};
37 37
38static struct pcm_format_data pcm_formats[SNDRV_PCM_FORMAT_LAST+1] = { 38/* we do lots of calculations on snd_pcm_format_t; shut up sparse */
39#define INT __force int
40
41static struct pcm_format_data pcm_formats[(INT)SNDRV_PCM_FORMAT_LAST+1] = {
39 [SNDRV_PCM_FORMAT_S8] = { 42 [SNDRV_PCM_FORMAT_S8] = {
40 .width = 8, .phys = 8, .le = -1, .signd = 1, 43 .width = 8, .phys = 8, .le = -1, .signd = 1,
41 .silence = {}, 44 .silence = {},
@@ -215,9 +218,9 @@ static struct pcm_format_data pcm_formats[SNDRV_PCM_FORMAT_LAST+1] = {
215int snd_pcm_format_signed(snd_pcm_format_t format) 218int snd_pcm_format_signed(snd_pcm_format_t format)
216{ 219{
217 int val; 220 int val;
218 if (format < 0 || format > SNDRV_PCM_FORMAT_LAST) 221 if ((INT)format < 0 || (INT)format > (INT)SNDRV_PCM_FORMAT_LAST)
219 return -EINVAL; 222 return -EINVAL;
220 if ((val = pcm_formats[format].signd) < 0) 223 if ((val = pcm_formats[(INT)format].signd) < 0)
221 return -EINVAL; 224 return -EINVAL;
222 return val; 225 return val;
223} 226}
@@ -266,9 +269,9 @@ EXPORT_SYMBOL(snd_pcm_format_linear);
266int snd_pcm_format_little_endian(snd_pcm_format_t format) 269int snd_pcm_format_little_endian(snd_pcm_format_t format)
267{ 270{
268 int val; 271 int val;
269 if (format < 0 || format > SNDRV_PCM_FORMAT_LAST) 272 if ((INT)format < 0 || (INT)format > (INT)SNDRV_PCM_FORMAT_LAST)
270 return -EINVAL; 273 return -EINVAL;
271 if ((val = pcm_formats[format].le) < 0) 274 if ((val = pcm_formats[(INT)format].le) < 0)
272 return -EINVAL; 275 return -EINVAL;
273 return val; 276 return val;
274} 277}
@@ -304,9 +307,9 @@ EXPORT_SYMBOL(snd_pcm_format_big_endian);
304int snd_pcm_format_width(snd_pcm_format_t format) 307int snd_pcm_format_width(snd_pcm_format_t format)
305{ 308{
306 int val; 309 int val;
307 if (format < 0 || format > SNDRV_PCM_FORMAT_LAST) 310 if ((INT)format < 0 || (INT)format > (INT)SNDRV_PCM_FORMAT_LAST)
308 return -EINVAL; 311 return -EINVAL;
309 if ((val = pcm_formats[format].width) == 0) 312 if ((val = pcm_formats[(INT)format].width) == 0)
310 return -EINVAL; 313 return -EINVAL;
311 return val; 314 return val;
312} 315}
@@ -323,9 +326,9 @@ EXPORT_SYMBOL(snd_pcm_format_width);
323int snd_pcm_format_physical_width(snd_pcm_format_t format) 326int snd_pcm_format_physical_width(snd_pcm_format_t format)
324{ 327{
325 int val; 328 int val;
326 if (format < 0 || format > SNDRV_PCM_FORMAT_LAST) 329 if ((INT)format < 0 || (INT)format > (INT)SNDRV_PCM_FORMAT_LAST)
327 return -EINVAL; 330 return -EINVAL;
328 if ((val = pcm_formats[format].phys) == 0) 331 if ((val = pcm_formats[(INT)format].phys) == 0)
329 return -EINVAL; 332 return -EINVAL;
330 return val; 333 return val;
331} 334}
@@ -358,11 +361,11 @@ EXPORT_SYMBOL(snd_pcm_format_size);
358 */ 361 */
359const unsigned char *snd_pcm_format_silence_64(snd_pcm_format_t format) 362const unsigned char *snd_pcm_format_silence_64(snd_pcm_format_t format)
360{ 363{
361 if (format < 0 || format > SNDRV_PCM_FORMAT_LAST) 364 if ((INT)format < 0 || (INT)format > (INT)SNDRV_PCM_FORMAT_LAST)
362 return NULL; 365 return NULL;
363 if (! pcm_formats[format].phys) 366 if (! pcm_formats[(INT)format].phys)
364 return NULL; 367 return NULL;
365 return pcm_formats[format].silence; 368 return pcm_formats[(INT)format].silence;
366} 369}
367 370
368EXPORT_SYMBOL(snd_pcm_format_silence_64); 371EXPORT_SYMBOL(snd_pcm_format_silence_64);
@@ -382,16 +385,16 @@ int snd_pcm_format_set_silence(snd_pcm_format_t format, void *data, unsigned int
382 int width; 385 int width;
383 unsigned char *dst, *pat; 386 unsigned char *dst, *pat;
384 387
385 if (format < 0 || format > SNDRV_PCM_FORMAT_LAST) 388 if ((INT)format < 0 || (INT)format > (INT)SNDRV_PCM_FORMAT_LAST)
386 return -EINVAL; 389 return -EINVAL;
387 if (samples == 0) 390 if (samples == 0)
388 return 0; 391 return 0;
389 width = pcm_formats[format].phys; /* physical width */ 392 width = pcm_formats[(INT)format].phys; /* physical width */
390 pat = pcm_formats[format].silence; 393 pat = pcm_formats[(INT)format].silence;
391 if (! width) 394 if (! width)
392 return -EINVAL; 395 return -EINVAL;
393 /* signed or 1 byte data */ 396 /* signed or 1 byte data */
394 if (pcm_formats[format].signd == 1 || width <= 8) { 397 if (pcm_formats[(INT)format].signd == 1 || width <= 8) {
395 unsigned int bytes = samples * width / 8; 398 unsigned int bytes = samples * width / 8;
396 memset(data, *pat, bytes); 399 memset(data, *pat, bytes);
397 return 0; 400 return 0;
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 4be45e7be8ad..ae42b6509ce4 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -941,7 +941,7 @@ static struct action_ops snd_pcm_action_stop = {
941 * 941 *
942 * The state of each stream is then changed to the given state unconditionally. 942 * The state of each stream is then changed to the given state unconditionally.
943 */ 943 */
944int snd_pcm_stop(struct snd_pcm_substream *substream, int state) 944int snd_pcm_stop(struct snd_pcm_substream *substream, snd_pcm_state_t state)
945{ 945{
946 return snd_pcm_action(&snd_pcm_action_stop, substream, state); 946 return snd_pcm_action(&snd_pcm_action_stop, substream, state);
947} 947}
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
index 99a485f13648..f2436d33fbf7 100644
--- a/sound/core/seq/seq_clientmgr.c
+++ b/sound/core/seq/seq_clientmgr.c
@@ -1052,7 +1052,7 @@ static ssize_t snd_seq_write(struct file *file, const char __user *buf,
1052 } else { 1052 } else {
1053#ifdef CONFIG_COMPAT 1053#ifdef CONFIG_COMPAT
1054 if (client->convert32 && snd_seq_ev_is_varusr(&event)) { 1054 if (client->convert32 && snd_seq_ev_is_varusr(&event)) {
1055 void *ptr = compat_ptr(event.data.raw32.d[1]); 1055 void *ptr = (void __force *)compat_ptr(event.data.raw32.d[1]);
1056 event.data.ext.ptr = ptr; 1056 event.data.ext.ptr = ptr;
1057 } 1057 }
1058#endif 1058#endif
@@ -2407,7 +2407,7 @@ int snd_seq_kernel_client_ctl(int clientid, unsigned int cmd, void *arg)
2407 if (client == NULL) 2407 if (client == NULL)
2408 return -ENXIO; 2408 return -ENXIO;
2409 fs = snd_enter_user(); 2409 fs = snd_enter_user();
2410 result = snd_seq_do_ioctl(client, cmd, (void __user *)arg); 2410 result = snd_seq_do_ioctl(client, cmd, (void __force __user *)arg);
2411 snd_leave_user(fs); 2411 snd_leave_user(fs);
2412 return result; 2412 return result;
2413} 2413}
@@ -2497,9 +2497,6 @@ static void snd_seq_info_dump_ports(struct snd_info_buffer *buffer,
2497} 2497}
2498 2498
2499 2499
2500void snd_seq_info_pool(struct snd_info_buffer *buffer,
2501 struct snd_seq_pool *pool, char *space);
2502
2503/* exported to seq_info.c */ 2500/* exported to seq_info.c */
2504void snd_seq_info_clients_read(struct snd_info_entry *entry, 2501void snd_seq_info_clients_read(struct snd_info_entry *entry,
2505 struct snd_info_buffer *buffer) 2502 struct snd_info_buffer *buffer)
diff --git a/sound/core/seq/seq_memory.c b/sound/core/seq/seq_memory.c
index 7fb55436287f..7f50c1437675 100644
--- a/sound/core/seq/seq_memory.c
+++ b/sound/core/seq/seq_memory.c
@@ -86,7 +86,7 @@ int snd_seq_dump_var_event(const struct snd_seq_event *event,
86 86
87 if (event->data.ext.len & SNDRV_SEQ_EXT_USRPTR) { 87 if (event->data.ext.len & SNDRV_SEQ_EXT_USRPTR) {
88 char buf[32]; 88 char buf[32];
89 char __user *curptr = (char __user *)event->data.ext.ptr; 89 char __user *curptr = (char __force __user *)event->data.ext.ptr;
90 while (len > 0) { 90 while (len > 0) {
91 int size = sizeof(buf); 91 int size = sizeof(buf);
92 if (len < size) 92 if (len < size)
@@ -157,7 +157,7 @@ int snd_seq_expand_var_event(const struct snd_seq_event *event, int count, char
157 if (event->data.ext.len & SNDRV_SEQ_EXT_USRPTR) { 157 if (event->data.ext.len & SNDRV_SEQ_EXT_USRPTR) {
158 if (! in_kernel) 158 if (! in_kernel)
159 return -EINVAL; 159 return -EINVAL;
160 if (copy_from_user(buf, (void __user *)event->data.ext.ptr, len)) 160 if (copy_from_user(buf, (void __force __user *)event->data.ext.ptr, len))
161 return -EFAULT; 161 return -EFAULT;
162 return newlen; 162 return newlen;
163 } 163 }
@@ -343,7 +343,7 @@ int snd_seq_event_dup(struct snd_seq_pool *pool, struct snd_seq_event *event,
343 tmp->event = src->event; 343 tmp->event = src->event;
344 src = src->next; 344 src = src->next;
345 } else if (is_usrptr) { 345 } else if (is_usrptr) {
346 if (copy_from_user(&tmp->event, (char __user *)buf, size)) { 346 if (copy_from_user(&tmp->event, (char __force __user *)buf, size)) {
347 err = -EFAULT; 347 err = -EFAULT;
348 goto __error; 348 goto __error;
349 } 349 }
diff --git a/sound/core/seq/seq_memory.h b/sound/core/seq/seq_memory.h
index 63e91431a29f..4a2ec779b8a7 100644
--- a/sound/core/seq/seq_memory.h
+++ b/sound/core/seq/seq_memory.h
@@ -24,6 +24,8 @@
24#include <sound/seq_kernel.h> 24#include <sound/seq_kernel.h>
25#include <linux/poll.h> 25#include <linux/poll.h>
26 26
27struct snd_info_buffer;
28
27/* container for sequencer event (internal use) */ 29/* container for sequencer event (internal use) */
28struct snd_seq_event_cell { 30struct snd_seq_event_cell {
29 struct snd_seq_event event; 31 struct snd_seq_event event;
@@ -99,5 +101,7 @@ void snd_sequencer_memory_done(void);
99/* polling */ 101/* polling */
100int snd_seq_pool_poll_wait(struct snd_seq_pool *pool, struct file *file, poll_table *wait); 102int snd_seq_pool_poll_wait(struct snd_seq_pool *pool, struct file *file, poll_table *wait);
101 103
104void snd_seq_info_pool(struct snd_info_buffer *buffer,
105 struct snd_seq_pool *pool, char *space);
102 106
103#endif 107#endif
diff --git a/sound/core/seq/seq_ports.c b/sound/core/seq/seq_ports.c
index 3bf7d73ac52e..e12bcd94b6db 100644
--- a/sound/core/seq/seq_ports.c
+++ b/sound/core/seq/seq_ports.c
@@ -412,7 +412,7 @@ int snd_seq_get_port_info(struct snd_seq_client_port * port,
412 * initialization or termination of devices (see seq_midi.c). 412 * initialization or termination of devices (see seq_midi.c).
413 * 413 *
414 * If callback_all option is set, the callback function is invoked 414 * If callback_all option is set, the callback function is invoked
415 * at each connnection/disconnection. 415 * at each connection/disconnection.
416 */ 416 */
417 417
418static int subscribe_port(struct snd_seq_client *client, 418static int subscribe_port(struct snd_seq_client *client,
diff --git a/sound/core/timer.c b/sound/core/timer.c
index ed016329e911..7c1cbf0a0dc4 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -186,9 +186,8 @@ static void snd_timer_check_slave(struct snd_timer_instance *slave)
186 list_for_each_entry(master, &timer->open_list_head, open_list) { 186 list_for_each_entry(master, &timer->open_list_head, open_list) {
187 if (slave->slave_class == master->slave_class && 187 if (slave->slave_class == master->slave_class &&
188 slave->slave_id == master->slave_id) { 188 slave->slave_id == master->slave_id) {
189 list_del(&slave->open_list); 189 list_move_tail(&slave->open_list,
190 list_add_tail(&slave->open_list, 190 &master->slave_list_head);
191 &master->slave_list_head);
192 spin_lock_irq(&slave_active_lock); 191 spin_lock_irq(&slave_active_lock);
193 slave->master = master; 192 slave->master = master;
194 slave->timer = master->timer; 193 slave->timer = master->timer;
@@ -414,8 +413,7 @@ static void snd_timer_notify1(struct snd_timer_instance *ti, int event)
414static int snd_timer_start1(struct snd_timer *timer, struct snd_timer_instance *timeri, 413static int snd_timer_start1(struct snd_timer *timer, struct snd_timer_instance *timeri,
415 unsigned long sticks) 414 unsigned long sticks)
416{ 415{
417 list_del(&timeri->active_list); 416 list_move_tail(&timeri->active_list, &timer->active_list_head);
418 list_add_tail(&timeri->active_list, &timer->active_list_head);
419 if (timer->running) { 417 if (timer->running) {
420 if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE) 418 if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE)
421 goto __start_now; 419 goto __start_now;
diff --git a/sound/core/vmaster.c b/sound/core/vmaster.c
index 3b9b550109cb..a89948ae9e8d 100644
--- a/sound/core/vmaster.c
+++ b/sound/core/vmaster.c
@@ -18,7 +18,7 @@
18 * a subset of information returned via ctl info callback 18 * a subset of information returned via ctl info callback
19 */ 19 */
20struct link_ctl_info { 20struct link_ctl_info {
21 int type; /* value type */ 21 snd_ctl_elem_type_t type; /* value type */
22 int count; /* item count */ 22 int count; /* item count */
23 int min_val, max_val; /* min, max values */ 23 int min_val, max_val; /* min, max values */
24}; 24};
diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c
index 12b44b0b6777..a0da7755fcea 100644
--- a/sound/drivers/aloop.c
+++ b/sound/drivers/aloop.c
@@ -482,8 +482,9 @@ static unsigned int loopback_pos_update(struct loopback_cable *cable)
482 cable->streams[SNDRV_PCM_STREAM_CAPTURE]; 482 cable->streams[SNDRV_PCM_STREAM_CAPTURE];
483 unsigned long delta_play = 0, delta_capt = 0; 483 unsigned long delta_play = 0, delta_capt = 0;
484 unsigned int running; 484 unsigned int running;
485 unsigned long flags;
485 486
486 spin_lock(&cable->lock); 487 spin_lock_irqsave(&cable->lock, flags);
487 running = cable->running ^ cable->pause; 488 running = cable->running ^ cable->pause;
488 if (running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) { 489 if (running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) {
489 delta_play = jiffies - dpcm_play->last_jiffies; 490 delta_play = jiffies - dpcm_play->last_jiffies;
@@ -495,10 +496,8 @@ static unsigned int loopback_pos_update(struct loopback_cable *cable)
495 dpcm_capt->last_jiffies += delta_capt; 496 dpcm_capt->last_jiffies += delta_capt;
496 } 497 }
497 498
498 if (delta_play == 0 && delta_capt == 0) { 499 if (delta_play == 0 && delta_capt == 0)
499 spin_unlock(&cable->lock); 500 goto unlock;
500 return running;
501 }
502 501
503 if (delta_play > delta_capt) { 502 if (delta_play > delta_capt) {
504 loopback_bytepos_update(dpcm_play, delta_play - delta_capt, 503 loopback_bytepos_update(dpcm_play, delta_play - delta_capt,
@@ -510,14 +509,14 @@ static unsigned int loopback_pos_update(struct loopback_cable *cable)
510 delta_capt = delta_play; 509 delta_capt = delta_play;
511 } 510 }
512 511
513 if (delta_play == 0 && delta_capt == 0) { 512 if (delta_play == 0 && delta_capt == 0)
514 spin_unlock(&cable->lock); 513 goto unlock;
515 return running; 514
516 }
517 /* note delta_capt == delta_play at this moment */ 515 /* note delta_capt == delta_play at this moment */
518 loopback_bytepos_update(dpcm_capt, delta_capt, BYTEPOS_UPDATE_COPY); 516 loopback_bytepos_update(dpcm_capt, delta_capt, BYTEPOS_UPDATE_COPY);
519 loopback_bytepos_update(dpcm_play, delta_play, BYTEPOS_UPDATE_POSONLY); 517 loopback_bytepos_update(dpcm_play, delta_play, BYTEPOS_UPDATE_POSONLY);
520 spin_unlock(&cable->lock); 518 unlock:
519 spin_unlock_irqrestore(&cable->lock, flags);
521 return running; 520 return running;
522} 521}
523 522
diff --git a/sound/firewire/Kconfig b/sound/firewire/Kconfig
new file mode 100644
index 000000000000..e486f48660fb
--- /dev/null
+++ b/sound/firewire/Kconfig
@@ -0,0 +1,25 @@
1menuconfig SND_FIREWIRE
2 bool "FireWire sound devices"
3 depends on FIREWIRE
4 default y
5 help
6 Support for IEEE-1394/FireWire/iLink sound devices.
7
8if SND_FIREWIRE && FIREWIRE
9
10config SND_FIREWIRE_LIB
11 tristate
12 depends on SND_PCM
13
14config SND_FIREWIRE_SPEAKERS
15 tristate "FireWire speakers"
16 select SND_PCM
17 select SND_FIREWIRE_LIB
18 help
19 Say Y here to include support for the Griffin FireWave Surround
20 and the LaCie FireWire Speakers.
21
22 To compile this driver as a module, choose M here: the module
23 will be called snd-firewire-speakers.
24
25endif # SND_FIREWIRE
diff --git a/sound/firewire/Makefile b/sound/firewire/Makefile
new file mode 100644
index 000000000000..e5b1634d9ad4
--- /dev/null
+++ b/sound/firewire/Makefile
@@ -0,0 +1,6 @@
1snd-firewire-lib-objs := lib.o iso-resources.o packets-buffer.o \
2 fcp.o cmp.o amdtp.o
3snd-firewire-speakers-objs := speakers.o
4
5obj-$(CONFIG_SND_FIREWIRE_LIB) += snd-firewire-lib.o
6obj-$(CONFIG_SND_FIREWIRE_SPEAKERS) += snd-firewire-speakers.o
diff --git a/sound/firewire/amdtp.c b/sound/firewire/amdtp.c
new file mode 100644
index 000000000000..b18140ff2b93
--- /dev/null
+++ b/sound/firewire/amdtp.c
@@ -0,0 +1,562 @@
1/*
2 * Audio and Music Data Transmission Protocol (IEC 61883-6) streams
3 * with Common Isochronous Packet (IEC 61883-1) headers
4 *
5 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
6 * Licensed under the terms of the GNU General Public License, version 2.
7 */
8
9#include <linux/device.h>
10#include <linux/err.h>
11#include <linux/firewire.h>
12#include <linux/module.h>
13#include <linux/slab.h>
14#include <sound/pcm.h>
15#include "amdtp.h"
16
17#define TICKS_PER_CYCLE 3072
18#define CYCLES_PER_SECOND 8000
19#define TICKS_PER_SECOND (TICKS_PER_CYCLE * CYCLES_PER_SECOND)
20
21#define TRANSFER_DELAY_TICKS 0x2e00 /* 479.17 µs */
22
23#define TAG_CIP 1
24
25#define CIP_EOH (1u << 31)
26#define CIP_FMT_AM (0x10 << 24)
27#define AMDTP_FDF_AM824 (0 << 19)
28#define AMDTP_FDF_SFC_SHIFT 16
29
30/* TODO: make these configurable */
31#define INTERRUPT_INTERVAL 16
32#define QUEUE_LENGTH 48
33
34/**
35 * amdtp_out_stream_init - initialize an AMDTP output stream structure
36 * @s: the AMDTP output stream to initialize
37 * @unit: the target of the stream
38 * @flags: the packet transmission method to use
39 */
40int amdtp_out_stream_init(struct amdtp_out_stream *s, struct fw_unit *unit,
41 enum cip_out_flags flags)
42{
43 if (flags != CIP_NONBLOCKING)
44 return -EINVAL;
45
46 s->unit = fw_unit_get(unit);
47 s->flags = flags;
48 s->context = ERR_PTR(-1);
49 mutex_init(&s->mutex);
50 s->packet_index = 0;
51
52 return 0;
53}
54EXPORT_SYMBOL(amdtp_out_stream_init);
55
56/**
57 * amdtp_out_stream_destroy - free stream resources
58 * @s: the AMDTP output stream to destroy
59 */
60void amdtp_out_stream_destroy(struct amdtp_out_stream *s)
61{
62 WARN_ON(!IS_ERR(s->context));
63 mutex_destroy(&s->mutex);
64 fw_unit_put(s->unit);
65}
66EXPORT_SYMBOL(amdtp_out_stream_destroy);
67
68/**
69 * amdtp_out_stream_set_rate - set the sample rate
70 * @s: the AMDTP output stream to configure
71 * @rate: the sample rate
72 *
73 * The sample rate must be set before the stream is started, and must not be
74 * changed while the stream is running.
75 */
76void amdtp_out_stream_set_rate(struct amdtp_out_stream *s, unsigned int rate)
77{
78 static const struct {
79 unsigned int rate;
80 unsigned int syt_interval;
81 } rate_info[] = {
82 [CIP_SFC_32000] = { 32000, 8, },
83 [CIP_SFC_44100] = { 44100, 8, },
84 [CIP_SFC_48000] = { 48000, 8, },
85 [CIP_SFC_88200] = { 88200, 16, },
86 [CIP_SFC_96000] = { 96000, 16, },
87 [CIP_SFC_176400] = { 176400, 32, },
88 [CIP_SFC_192000] = { 192000, 32, },
89 };
90 unsigned int sfc;
91
92 if (WARN_ON(!IS_ERR(s->context)))
93 return;
94
95 for (sfc = 0; sfc < ARRAY_SIZE(rate_info); ++sfc)
96 if (rate_info[sfc].rate == rate) {
97 s->sfc = sfc;
98 s->syt_interval = rate_info[sfc].syt_interval;
99 return;
100 }
101 WARN_ON(1);
102}
103EXPORT_SYMBOL(amdtp_out_stream_set_rate);
104
105/**
106 * amdtp_out_stream_get_max_payload - get the stream's packet size
107 * @s: the AMDTP output stream
108 *
109 * This function must not be called before the stream has been configured
110 * with amdtp_out_stream_set_hw_params(), amdtp_out_stream_set_pcm(), and
111 * amdtp_out_stream_set_midi().
112 */
113unsigned int amdtp_out_stream_get_max_payload(struct amdtp_out_stream *s)
114{
115 static const unsigned int max_data_blocks[] = {
116 [CIP_SFC_32000] = 4,
117 [CIP_SFC_44100] = 6,
118 [CIP_SFC_48000] = 6,
119 [CIP_SFC_88200] = 12,
120 [CIP_SFC_96000] = 12,
121 [CIP_SFC_176400] = 23,
122 [CIP_SFC_192000] = 24,
123 };
124
125 s->data_block_quadlets = s->pcm_channels;
126 s->data_block_quadlets += DIV_ROUND_UP(s->midi_ports, 8);
127
128 return 8 + max_data_blocks[s->sfc] * 4 * s->data_block_quadlets;
129}
130EXPORT_SYMBOL(amdtp_out_stream_get_max_payload);
131
132static void amdtp_write_s16(struct amdtp_out_stream *s,
133 struct snd_pcm_substream *pcm,
134 __be32 *buffer, unsigned int frames);
135static void amdtp_write_s32(struct amdtp_out_stream *s,
136 struct snd_pcm_substream *pcm,
137 __be32 *buffer, unsigned int frames);
138
139/**
140 * amdtp_out_stream_set_pcm_format - set the PCM format
141 * @s: the AMDTP output stream to configure
142 * @format: the format of the ALSA PCM device
143 *
144 * The sample format must be set before the stream is started, and must not be
145 * changed while the stream is running.
146 */
147void amdtp_out_stream_set_pcm_format(struct amdtp_out_stream *s,
148 snd_pcm_format_t format)
149{
150 if (WARN_ON(!IS_ERR(s->context)))
151 return;
152
153 switch (format) {
154 default:
155 WARN_ON(1);
156 /* fall through */
157 case SNDRV_PCM_FORMAT_S16:
158 s->transfer_samples = amdtp_write_s16;
159 break;
160 case SNDRV_PCM_FORMAT_S32:
161 s->transfer_samples = amdtp_write_s32;
162 break;
163 }
164}
165EXPORT_SYMBOL(amdtp_out_stream_set_pcm_format);
166
167static unsigned int calculate_data_blocks(struct amdtp_out_stream *s)
168{
169 unsigned int phase, data_blocks;
170
171 if (!cip_sfc_is_base_44100(s->sfc)) {
172 /* Sample_rate / 8000 is an integer, and precomputed. */
173 data_blocks = s->data_block_state;
174 } else {
175 phase = s->data_block_state;
176
177 /*
178 * This calculates the number of data blocks per packet so that
179 * 1) the overall rate is correct and exactly synchronized to
180 * the bus clock, and
181 * 2) packets with a rounded-up number of blocks occur as early
182 * as possible in the sequence (to prevent underruns of the
183 * device's buffer).
184 */
185 if (s->sfc == CIP_SFC_44100)
186 /* 6 6 5 6 5 6 5 ... */
187 data_blocks = 5 + ((phase & 1) ^
188 (phase == 0 || phase >= 40));
189 else
190 /* 12 11 11 11 11 ... or 23 22 22 22 22 ... */
191 data_blocks = 11 * (s->sfc >> 1) + (phase == 0);
192 if (++phase >= (80 >> (s->sfc >> 1)))
193 phase = 0;
194 s->data_block_state = phase;
195 }
196
197 return data_blocks;
198}
199
200static unsigned int calculate_syt(struct amdtp_out_stream *s,
201 unsigned int cycle)
202{
203 unsigned int syt_offset, phase, index, syt;
204
205 if (s->last_syt_offset < TICKS_PER_CYCLE) {
206 if (!cip_sfc_is_base_44100(s->sfc))
207 syt_offset = s->last_syt_offset + s->syt_offset_state;
208 else {
209 /*
210 * The time, in ticks, of the n'th SYT_INTERVAL sample is:
211 * n * SYT_INTERVAL * 24576000 / sample_rate
212 * Modulo TICKS_PER_CYCLE, the difference between successive
213 * elements is about 1386.23. Rounding the results of this
214 * formula to the SYT precision results in a sequence of
215 * differences that begins with:
216 * 1386 1386 1387 1386 1386 1386 1387 1386 1386 1386 1387 ...
217 * This code generates _exactly_ the same sequence.
218 */
219 phase = s->syt_offset_state;
220 index = phase % 13;
221 syt_offset = s->last_syt_offset;
222 syt_offset += 1386 + ((index && !(index & 3)) ||
223 phase == 146);
224 if (++phase >= 147)
225 phase = 0;
226 s->syt_offset_state = phase;
227 }
228 } else
229 syt_offset = s->last_syt_offset - TICKS_PER_CYCLE;
230 s->last_syt_offset = syt_offset;
231
232 if (syt_offset < TICKS_PER_CYCLE) {
233 syt_offset += TRANSFER_DELAY_TICKS - TICKS_PER_CYCLE;
234 syt = (cycle + syt_offset / TICKS_PER_CYCLE) << 12;
235 syt += syt_offset % TICKS_PER_CYCLE;
236
237 return syt & 0xffff;
238 } else {
239 return 0xffff; /* no info */
240 }
241}
242
243static void amdtp_write_s32(struct amdtp_out_stream *s,
244 struct snd_pcm_substream *pcm,
245 __be32 *buffer, unsigned int frames)
246{
247 struct snd_pcm_runtime *runtime = pcm->runtime;
248 unsigned int channels, remaining_frames, frame_step, i, c;
249 const u32 *src;
250
251 channels = s->pcm_channels;
252 src = (void *)runtime->dma_area +
253 s->pcm_buffer_pointer * (runtime->frame_bits / 8);
254 remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
255 frame_step = s->data_block_quadlets - channels;
256
257 for (i = 0; i < frames; ++i) {
258 for (c = 0; c < channels; ++c) {
259 *buffer = cpu_to_be32((*src >> 8) | 0x40000000);
260 src++;
261 buffer++;
262 }
263 buffer += frame_step;
264 if (--remaining_frames == 0)
265 src = (void *)runtime->dma_area;
266 }
267}
268
269static void amdtp_write_s16(struct amdtp_out_stream *s,
270 struct snd_pcm_substream *pcm,
271 __be32 *buffer, unsigned int frames)
272{
273 struct snd_pcm_runtime *runtime = pcm->runtime;
274 unsigned int channels, remaining_frames, frame_step, i, c;
275 const u16 *src;
276
277 channels = s->pcm_channels;
278 src = (void *)runtime->dma_area +
279 s->pcm_buffer_pointer * (runtime->frame_bits / 8);
280 remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
281 frame_step = s->data_block_quadlets - channels;
282
283 for (i = 0; i < frames; ++i) {
284 for (c = 0; c < channels; ++c) {
285 *buffer = cpu_to_be32((*src << 8) | 0x40000000);
286 src++;
287 buffer++;
288 }
289 buffer += frame_step;
290 if (--remaining_frames == 0)
291 src = (void *)runtime->dma_area;
292 }
293}
294
295static void amdtp_fill_pcm_silence(struct amdtp_out_stream *s,
296 __be32 *buffer, unsigned int frames)
297{
298 unsigned int i, c;
299
300 for (i = 0; i < frames; ++i) {
301 for (c = 0; c < s->pcm_channels; ++c)
302 buffer[c] = cpu_to_be32(0x40000000);
303 buffer += s->data_block_quadlets;
304 }
305}
306
307static void amdtp_fill_midi(struct amdtp_out_stream *s,
308 __be32 *buffer, unsigned int frames)
309{
310 unsigned int i;
311
312 for (i = 0; i < frames; ++i)
313 buffer[s->pcm_channels + i * s->data_block_quadlets] =
314 cpu_to_be32(0x80000000);
315}
316
317static void queue_out_packet(struct amdtp_out_stream *s, unsigned int cycle)
318{
319 __be32 *buffer;
320 unsigned int index, data_blocks, syt, ptr;
321 struct snd_pcm_substream *pcm;
322 struct fw_iso_packet packet;
323 int err;
324
325 if (s->packet_index < 0)
326 return;
327 index = s->packet_index;
328
329 data_blocks = calculate_data_blocks(s);
330 syt = calculate_syt(s, cycle);
331
332 buffer = s->buffer.packets[index].buffer;
333 buffer[0] = cpu_to_be32(ACCESS_ONCE(s->source_node_id_field) |
334 (s->data_block_quadlets << 16) |
335 s->data_block_counter);
336 buffer[1] = cpu_to_be32(CIP_EOH | CIP_FMT_AM | AMDTP_FDF_AM824 |
337 (s->sfc << AMDTP_FDF_SFC_SHIFT) | syt);
338 buffer += 2;
339
340 pcm = ACCESS_ONCE(s->pcm);
341 if (pcm)
342 s->transfer_samples(s, pcm, buffer, data_blocks);
343 else
344 amdtp_fill_pcm_silence(s, buffer, data_blocks);
345 if (s->midi_ports)
346 amdtp_fill_midi(s, buffer, data_blocks);
347
348 s->data_block_counter = (s->data_block_counter + data_blocks) & 0xff;
349
350 packet.payload_length = 8 + data_blocks * 4 * s->data_block_quadlets;
351 packet.interrupt = IS_ALIGNED(index + 1, INTERRUPT_INTERVAL);
352 packet.skip = 0;
353 packet.tag = TAG_CIP;
354 packet.sy = 0;
355 packet.header_length = 0;
356
357 err = fw_iso_context_queue(s->context, &packet, &s->buffer.iso_buffer,
358 s->buffer.packets[index].offset);
359 if (err < 0) {
360 dev_err(&s->unit->device, "queueing error: %d\n", err);
361 s->packet_index = -1;
362 amdtp_out_stream_pcm_abort(s);
363 return;
364 }
365
366 if (++index >= QUEUE_LENGTH)
367 index = 0;
368 s->packet_index = index;
369
370 if (pcm) {
371 ptr = s->pcm_buffer_pointer + data_blocks;
372 if (ptr >= pcm->runtime->buffer_size)
373 ptr -= pcm->runtime->buffer_size;
374 ACCESS_ONCE(s->pcm_buffer_pointer) = ptr;
375
376 s->pcm_period_pointer += data_blocks;
377 if (s->pcm_period_pointer >= pcm->runtime->period_size) {
378 s->pcm_period_pointer -= pcm->runtime->period_size;
379 snd_pcm_period_elapsed(pcm);
380 }
381 }
382}
383
384static void out_packet_callback(struct fw_iso_context *context, u32 cycle,
385 size_t header_length, void *header, void *data)
386{
387 struct amdtp_out_stream *s = data;
388 unsigned int i, packets = header_length / 4;
389
390 /*
391 * Compute the cycle of the last queued packet.
392 * (We need only the four lowest bits for the SYT, so we can ignore
393 * that bits 0-11 must wrap around at 3072.)
394 */
395 cycle += QUEUE_LENGTH - packets;
396
397 for (i = 0; i < packets; ++i)
398 queue_out_packet(s, ++cycle);
399}
400
401static int queue_initial_skip_packets(struct amdtp_out_stream *s)
402{
403 struct fw_iso_packet skip_packet = {
404 .skip = 1,
405 };
406 unsigned int i;
407 int err;
408
409 for (i = 0; i < QUEUE_LENGTH; ++i) {
410 skip_packet.interrupt = IS_ALIGNED(s->packet_index + 1,
411 INTERRUPT_INTERVAL);
412 err = fw_iso_context_queue(s->context, &skip_packet, NULL, 0);
413 if (err < 0)
414 return err;
415 if (++s->packet_index >= QUEUE_LENGTH)
416 s->packet_index = 0;
417 }
418
419 return 0;
420}
421
422/**
423 * amdtp_out_stream_start - start sending packets
424 * @s: the AMDTP output stream to start
425 * @channel: the isochronous channel on the bus
426 * @speed: firewire speed code
427 *
428 * The stream cannot be started until it has been configured with
429 * amdtp_out_stream_set_hw_params(), amdtp_out_stream_set_pcm(), and
430 * amdtp_out_stream_set_midi(); and it must be started before any
431 * PCM or MIDI device can be started.
432 */
433int amdtp_out_stream_start(struct amdtp_out_stream *s, int channel, int speed)
434{
435 static const struct {
436 unsigned int data_block;
437 unsigned int syt_offset;
438 } initial_state[] = {
439 [CIP_SFC_32000] = { 4, 3072 },
440 [CIP_SFC_48000] = { 6, 1024 },
441 [CIP_SFC_96000] = { 12, 1024 },
442 [CIP_SFC_192000] = { 24, 1024 },
443 [CIP_SFC_44100] = { 0, 67 },
444 [CIP_SFC_88200] = { 0, 67 },
445 [CIP_SFC_176400] = { 0, 67 },
446 };
447 int err;
448
449 mutex_lock(&s->mutex);
450
451 if (WARN_ON(!IS_ERR(s->context) ||
452 (!s->pcm_channels && !s->midi_ports))) {
453 err = -EBADFD;
454 goto err_unlock;
455 }
456
457 s->data_block_state = initial_state[s->sfc].data_block;
458 s->syt_offset_state = initial_state[s->sfc].syt_offset;
459 s->last_syt_offset = TICKS_PER_CYCLE;
460
461 err = iso_packets_buffer_init(&s->buffer, s->unit, QUEUE_LENGTH,
462 amdtp_out_stream_get_max_payload(s),
463 DMA_TO_DEVICE);
464 if (err < 0)
465 goto err_unlock;
466
467 s->context = fw_iso_context_create(fw_parent_device(s->unit)->card,
468 FW_ISO_CONTEXT_TRANSMIT,
469 channel, speed, 0,
470 out_packet_callback, s);
471 if (IS_ERR(s->context)) {
472 err = PTR_ERR(s->context);
473 if (err == -EBUSY)
474 dev_err(&s->unit->device,
475 "no free output stream on this controller\n");
476 goto err_buffer;
477 }
478
479 amdtp_out_stream_update(s);
480
481 s->packet_index = 0;
482 s->data_block_counter = 0;
483 err = queue_initial_skip_packets(s);
484 if (err < 0)
485 goto err_context;
486
487 err = fw_iso_context_start(s->context, -1, 0, 0);
488 if (err < 0)
489 goto err_context;
490
491 mutex_unlock(&s->mutex);
492
493 return 0;
494
495err_context:
496 fw_iso_context_destroy(s->context);
497 s->context = ERR_PTR(-1);
498err_buffer:
499 iso_packets_buffer_destroy(&s->buffer, s->unit);
500err_unlock:
501 mutex_unlock(&s->mutex);
502
503 return err;
504}
505EXPORT_SYMBOL(amdtp_out_stream_start);
506
507/**
508 * amdtp_out_stream_update - update the stream after a bus reset
509 * @s: the AMDTP output stream
510 */
511void amdtp_out_stream_update(struct amdtp_out_stream *s)
512{
513 ACCESS_ONCE(s->source_node_id_field) =
514 (fw_parent_device(s->unit)->card->node_id & 0x3f) << 24;
515}
516EXPORT_SYMBOL(amdtp_out_stream_update);
517
518/**
519 * amdtp_out_stream_stop - stop sending packets
520 * @s: the AMDTP output stream to stop
521 *
522 * All PCM and MIDI devices of the stream must be stopped before the stream
523 * itself can be stopped.
524 */
525void amdtp_out_stream_stop(struct amdtp_out_stream *s)
526{
527 mutex_lock(&s->mutex);
528
529 if (IS_ERR(s->context)) {
530 mutex_unlock(&s->mutex);
531 return;
532 }
533
534 fw_iso_context_stop(s->context);
535 fw_iso_context_destroy(s->context);
536 s->context = ERR_PTR(-1);
537 iso_packets_buffer_destroy(&s->buffer, s->unit);
538
539 mutex_unlock(&s->mutex);
540}
541EXPORT_SYMBOL(amdtp_out_stream_stop);
542
543/**
544 * amdtp_out_stream_pcm_abort - abort the running PCM device
545 * @s: the AMDTP stream about to be stopped
546 *
547 * If the isochronous stream needs to be stopped asynchronously, call this
548 * function first to stop the PCM device.
549 */
550void amdtp_out_stream_pcm_abort(struct amdtp_out_stream *s)
551{
552 struct snd_pcm_substream *pcm;
553
554 pcm = ACCESS_ONCE(s->pcm);
555 if (pcm) {
556 snd_pcm_stream_lock_irq(pcm);
557 if (snd_pcm_running(pcm))
558 snd_pcm_stop(pcm, SNDRV_PCM_STATE_XRUN);
559 snd_pcm_stream_unlock_irq(pcm);
560 }
561}
562EXPORT_SYMBOL(amdtp_out_stream_pcm_abort);
diff --git a/sound/firewire/amdtp.h b/sound/firewire/amdtp.h
new file mode 100644
index 000000000000..537a9cb83581
--- /dev/null
+++ b/sound/firewire/amdtp.h
@@ -0,0 +1,169 @@
1#ifndef SOUND_FIREWIRE_AMDTP_H_INCLUDED
2#define SOUND_FIREWIRE_AMDTP_H_INCLUDED
3
4#include <linux/mutex.h>
5#include <linux/spinlock.h>
6#include "packets-buffer.h"
7
8/**
9 * enum cip_out_flags - describes details of the streaming protocol
10 * @CIP_NONBLOCKING: In non-blocking mode, each packet contains
11 * sample_rate/8000 samples, with rounding up or down to adjust
12 * for clock skew and left-over fractional samples. This should
13 * be used if supported by the device.
14 */
15enum cip_out_flags {
16 CIP_NONBLOCKING = 0,
17};
18
19/**
20 * enum cip_sfc - a stream's sample rate
21 */
22enum cip_sfc {
23 CIP_SFC_32000 = 0,
24 CIP_SFC_44100 = 1,
25 CIP_SFC_48000 = 2,
26 CIP_SFC_88200 = 3,
27 CIP_SFC_96000 = 4,
28 CIP_SFC_176400 = 5,
29 CIP_SFC_192000 = 6,
30};
31
32#define AMDTP_OUT_PCM_FORMAT_BITS (SNDRV_PCM_FMTBIT_S16 | \
33 SNDRV_PCM_FMTBIT_S32)
34
35struct fw_unit;
36struct fw_iso_context;
37struct snd_pcm_substream;
38
39struct amdtp_out_stream {
40 struct fw_unit *unit;
41 enum cip_out_flags flags;
42 struct fw_iso_context *context;
43 struct mutex mutex;
44
45 enum cip_sfc sfc;
46 unsigned int data_block_quadlets;
47 unsigned int pcm_channels;
48 unsigned int midi_ports;
49 void (*transfer_samples)(struct amdtp_out_stream *s,
50 struct snd_pcm_substream *pcm,
51 __be32 *buffer, unsigned int frames);
52
53 unsigned int syt_interval;
54 unsigned int source_node_id_field;
55 struct iso_packets_buffer buffer;
56
57 struct snd_pcm_substream *pcm;
58
59 int packet_index;
60 unsigned int data_block_counter;
61
62 unsigned int data_block_state;
63
64 unsigned int last_syt_offset;
65 unsigned int syt_offset_state;
66
67 unsigned int pcm_buffer_pointer;
68 unsigned int pcm_period_pointer;
69};
70
71int amdtp_out_stream_init(struct amdtp_out_stream *s, struct fw_unit *unit,
72 enum cip_out_flags flags);
73void amdtp_out_stream_destroy(struct amdtp_out_stream *s);
74
75void amdtp_out_stream_set_rate(struct amdtp_out_stream *s, unsigned int rate);
76unsigned int amdtp_out_stream_get_max_payload(struct amdtp_out_stream *s);
77
78int amdtp_out_stream_start(struct amdtp_out_stream *s, int channel, int speed);
79void amdtp_out_stream_update(struct amdtp_out_stream *s);
80void amdtp_out_stream_stop(struct amdtp_out_stream *s);
81
82void amdtp_out_stream_set_pcm_format(struct amdtp_out_stream *s,
83 snd_pcm_format_t format);
84void amdtp_out_stream_pcm_abort(struct amdtp_out_stream *s);
85
86/**
87 * amdtp_out_stream_set_pcm - configure format of PCM samples
88 * @s: the AMDTP output stream to be configured
89 * @pcm_channels: the number of PCM samples in each data block, to be encoded
90 * as AM824 multi-bit linear audio
91 *
92 * This function must not be called while the stream is running.
93 */
94static inline void amdtp_out_stream_set_pcm(struct amdtp_out_stream *s,
95 unsigned int pcm_channels)
96{
97 s->pcm_channels = pcm_channels;
98}
99
100/**
101 * amdtp_out_stream_set_midi - configure format of MIDI data
102 * @s: the AMDTP output stream to be configured
103 * @midi_ports: the number of MIDI ports (i.e., MPX-MIDI Data Channels)
104 *
105 * This function must not be called while the stream is running.
106 */
107static inline void amdtp_out_stream_set_midi(struct amdtp_out_stream *s,
108 unsigned int midi_ports)
109{
110 s->midi_ports = midi_ports;
111}
112
113/**
114 * amdtp_out_streaming_error - check for streaming error
115 * @s: the AMDTP output stream
116 *
117 * If this function returns true, the stream's packet queue has stopped due to
118 * an asynchronous error.
119 */
120static inline bool amdtp_out_streaming_error(struct amdtp_out_stream *s)
121{
122 return s->packet_index < 0;
123}
124
125/**
126 * amdtp_out_stream_pcm_prepare - prepare PCM device for running
127 * @s: the AMDTP output stream
128 *
129 * This function should be called from the PCM device's .prepare callback.
130 */
131static inline void amdtp_out_stream_pcm_prepare(struct amdtp_out_stream *s)
132{
133 s->pcm_buffer_pointer = 0;
134 s->pcm_period_pointer = 0;
135}
136
137/**
138 * amdtp_out_stream_pcm_trigger - start/stop playback from a PCM device
139 * @s: the AMDTP output stream
140 * @pcm: the PCM device to be started, or %NULL to stop the current device
141 *
142 * Call this function on a running isochronous stream to enable the actual
143 * transmission of PCM data. This function should be called from the PCM
144 * device's .trigger callback.
145 */
146static inline void amdtp_out_stream_pcm_trigger(struct amdtp_out_stream *s,
147 struct snd_pcm_substream *pcm)
148{
149 ACCESS_ONCE(s->pcm) = pcm;
150}
151
152/**
153 * amdtp_out_stream_pcm_pointer - get the PCM buffer position
154 * @s: the AMDTP output stream that transports the PCM data
155 *
156 * Returns the current buffer position, in frames.
157 */
158static inline unsigned long
159amdtp_out_stream_pcm_pointer(struct amdtp_out_stream *s)
160{
161 return ACCESS_ONCE(s->pcm_buffer_pointer);
162}
163
164static inline bool cip_sfc_is_base_44100(enum cip_sfc sfc)
165{
166 return sfc & 1;
167}
168
169#endif
diff --git a/sound/firewire/cmp.c b/sound/firewire/cmp.c
new file mode 100644
index 000000000000..4a37f3a6fab9
--- /dev/null
+++ b/sound/firewire/cmp.c
@@ -0,0 +1,308 @@
1/*
2 * Connection Management Procedures (IEC 61883-1) helper functions
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 <linux/device.h>
9#include <linux/firewire.h>
10#include <linux/firewire-constants.h>
11#include <linux/module.h>
12#include <linux/sched.h>
13#include "lib.h"
14#include "iso-resources.h"
15#include "cmp.h"
16
17#define IMPR_SPEED_MASK 0xc0000000
18#define IMPR_SPEED_SHIFT 30
19#define IMPR_XSPEED_MASK 0x00000060
20#define IMPR_XSPEED_SHIFT 5
21#define IMPR_PLUGS_MASK 0x0000001f
22
23#define IPCR_ONLINE 0x80000000
24#define IPCR_BCAST_CONN 0x40000000
25#define IPCR_P2P_CONN_MASK 0x3f000000
26#define IPCR_P2P_CONN_SHIFT 24
27#define IPCR_CHANNEL_MASK 0x003f0000
28#define IPCR_CHANNEL_SHIFT 16
29
30enum bus_reset_handling {
31 ABORT_ON_BUS_RESET,
32 SUCCEED_ON_BUS_RESET,
33};
34
35static __attribute__((format(printf, 2, 3)))
36void cmp_error(struct cmp_connection *c, const char *fmt, ...)
37{
38 va_list va;
39
40 va_start(va, fmt);
41 dev_err(&c->resources.unit->device, "%cPCR%u: %pV",
42 'i', c->pcr_index, &(struct va_format){ fmt, &va });
43 va_end(va);
44}
45
46static int pcr_modify(struct cmp_connection *c,
47 __be32 (*modify)(struct cmp_connection *c, __be32 old),
48 int (*check)(struct cmp_connection *c, __be32 pcr),
49 enum bus_reset_handling bus_reset_handling)
50{
51 struct fw_device *device = fw_parent_device(c->resources.unit);
52 __be32 *buffer = c->resources.buffer;
53 int generation = c->resources.generation;
54 int rcode, errors = 0;
55 __be32 old_arg;
56 int err;
57
58 buffer[0] = c->last_pcr_value;
59 for (;;) {
60 old_arg = buffer[0];
61 buffer[1] = modify(c, buffer[0]);
62
63 rcode = fw_run_transaction(
64 device->card, TCODE_LOCK_COMPARE_SWAP,
65 device->node_id, generation, device->max_speed,
66 CSR_REGISTER_BASE + CSR_IPCR(c->pcr_index),
67 buffer, 8);
68
69 if (rcode == RCODE_COMPLETE) {
70 if (buffer[0] == old_arg) /* success? */
71 break;
72
73 if (check) {
74 err = check(c, buffer[0]);
75 if (err < 0)
76 return err;
77 }
78 } else if (rcode == RCODE_GENERATION)
79 goto bus_reset;
80 else if (rcode_is_permanent_error(rcode) || ++errors >= 3)
81 goto io_error;
82 }
83 c->last_pcr_value = buffer[1];
84
85 return 0;
86
87io_error:
88 cmp_error(c, "transaction failed: %s\n", rcode_string(rcode));
89 return -EIO;
90
91bus_reset:
92 return bus_reset_handling == ABORT_ON_BUS_RESET ? -EAGAIN : 0;
93}
94
95
96/**
97 * cmp_connection_init - initializes a connection manager
98 * @c: the connection manager to initialize
99 * @unit: a unit of the target device
100 * @ipcr_index: the index of the iPCR on the target device
101 */
102int cmp_connection_init(struct cmp_connection *c,
103 struct fw_unit *unit,
104 unsigned int ipcr_index)
105{
106 __be32 impr_be;
107 u32 impr;
108 int err;
109
110 err = snd_fw_transaction(unit, TCODE_READ_QUADLET_REQUEST,
111 CSR_REGISTER_BASE + CSR_IMPR,
112 &impr_be, 4);
113 if (err < 0)
114 return err;
115 impr = be32_to_cpu(impr_be);
116
117 if (ipcr_index >= (impr & IMPR_PLUGS_MASK))
118 return -EINVAL;
119
120 err = fw_iso_resources_init(&c->resources, unit);
121 if (err < 0)
122 return err;
123
124 c->connected = false;
125 mutex_init(&c->mutex);
126 c->last_pcr_value = cpu_to_be32(0x80000000);
127 c->pcr_index = ipcr_index;
128 c->max_speed = (impr & IMPR_SPEED_MASK) >> IMPR_SPEED_SHIFT;
129 if (c->max_speed == SCODE_BETA)
130 c->max_speed += (impr & IMPR_XSPEED_MASK) >> IMPR_XSPEED_SHIFT;
131
132 return 0;
133}
134EXPORT_SYMBOL(cmp_connection_init);
135
136/**
137 * cmp_connection_destroy - free connection manager resources
138 * @c: the connection manager
139 */
140void cmp_connection_destroy(struct cmp_connection *c)
141{
142 WARN_ON(c->connected);
143 mutex_destroy(&c->mutex);
144 fw_iso_resources_destroy(&c->resources);
145}
146EXPORT_SYMBOL(cmp_connection_destroy);
147
148
149static __be32 ipcr_set_modify(struct cmp_connection *c, __be32 ipcr)
150{
151 ipcr &= ~cpu_to_be32(IPCR_BCAST_CONN |
152 IPCR_P2P_CONN_MASK |
153 IPCR_CHANNEL_MASK);
154 ipcr |= cpu_to_be32(1 << IPCR_P2P_CONN_SHIFT);
155 ipcr |= cpu_to_be32(c->resources.channel << IPCR_CHANNEL_SHIFT);
156
157 return ipcr;
158}
159
160static int ipcr_set_check(struct cmp_connection *c, __be32 ipcr)
161{
162 if (ipcr & cpu_to_be32(IPCR_BCAST_CONN |
163 IPCR_P2P_CONN_MASK)) {
164 cmp_error(c, "plug is already in use\n");
165 return -EBUSY;
166 }
167 if (!(ipcr & cpu_to_be32(IPCR_ONLINE))) {
168 cmp_error(c, "plug is not on-line\n");
169 return -ECONNREFUSED;
170 }
171
172 return 0;
173}
174
175/**
176 * cmp_connection_establish - establish a connection to the target
177 * @c: the connection manager
178 * @max_payload_bytes: the amount of data (including CIP headers) per packet
179 *
180 * This function establishes a point-to-point connection from the local
181 * computer to the target by allocating isochronous resources (channel and
182 * bandwidth) and setting the target's input plug control register. When this
183 * function succeeds, the caller is responsible for starting transmitting
184 * packets.
185 */
186int cmp_connection_establish(struct cmp_connection *c,
187 unsigned int max_payload_bytes)
188{
189 int err;
190
191 if (WARN_ON(c->connected))
192 return -EISCONN;
193
194 c->speed = min(c->max_speed,
195 fw_parent_device(c->resources.unit)->max_speed);
196
197 mutex_lock(&c->mutex);
198
199retry_after_bus_reset:
200 err = fw_iso_resources_allocate(&c->resources,
201 max_payload_bytes, c->speed);
202 if (err < 0)
203 goto err_mutex;
204
205 err = pcr_modify(c, ipcr_set_modify, ipcr_set_check,
206 ABORT_ON_BUS_RESET);
207 if (err == -EAGAIN) {
208 fw_iso_resources_free(&c->resources);
209 goto retry_after_bus_reset;
210 }
211 if (err < 0)
212 goto err_resources;
213
214 c->connected = true;
215
216 mutex_unlock(&c->mutex);
217
218 return 0;
219
220err_resources:
221 fw_iso_resources_free(&c->resources);
222err_mutex:
223 mutex_unlock(&c->mutex);
224
225 return err;
226}
227EXPORT_SYMBOL(cmp_connection_establish);
228
229/**
230 * cmp_connection_update - update the connection after a bus reset
231 * @c: the connection manager
232 *
233 * This function must be called from the driver's .update handler to reestablish
234 * any connection that might have been active.
235 *
236 * Returns zero on success, or a negative error code. On an error, the
237 * connection is broken and the caller must stop transmitting iso packets.
238 */
239int cmp_connection_update(struct cmp_connection *c)
240{
241 int err;
242
243 mutex_lock(&c->mutex);
244
245 if (!c->connected) {
246 mutex_unlock(&c->mutex);
247 return 0;
248 }
249
250 err = fw_iso_resources_update(&c->resources);
251 if (err < 0)
252 goto err_unconnect;
253
254 err = pcr_modify(c, ipcr_set_modify, ipcr_set_check,
255 SUCCEED_ON_BUS_RESET);
256 if (err < 0)
257 goto err_resources;
258
259 mutex_unlock(&c->mutex);
260
261 return 0;
262
263err_resources:
264 fw_iso_resources_free(&c->resources);
265err_unconnect:
266 c->connected = false;
267 mutex_unlock(&c->mutex);
268
269 return err;
270}
271EXPORT_SYMBOL(cmp_connection_update);
272
273
274static __be32 ipcr_break_modify(struct cmp_connection *c, __be32 ipcr)
275{
276 return ipcr & ~cpu_to_be32(IPCR_BCAST_CONN | IPCR_P2P_CONN_MASK);
277}
278
279/**
280 * cmp_connection_break - break the connection to the target
281 * @c: the connection manager
282 *
283 * This function deactives the connection in the target's input plug control
284 * register, and frees the isochronous resources of the connection. Before
285 * calling this function, the caller should cease transmitting packets.
286 */
287void cmp_connection_break(struct cmp_connection *c)
288{
289 int err;
290
291 mutex_lock(&c->mutex);
292
293 if (!c->connected) {
294 mutex_unlock(&c->mutex);
295 return;
296 }
297
298 err = pcr_modify(c, ipcr_break_modify, NULL, SUCCEED_ON_BUS_RESET);
299 if (err < 0)
300 cmp_error(c, "plug is still connected\n");
301
302 fw_iso_resources_free(&c->resources);
303
304 c->connected = false;
305
306 mutex_unlock(&c->mutex);
307}
308EXPORT_SYMBOL(cmp_connection_break);
diff --git a/sound/firewire/cmp.h b/sound/firewire/cmp.h
new file mode 100644
index 000000000000..f47de08feb12
--- /dev/null
+++ b/sound/firewire/cmp.h
@@ -0,0 +1,41 @@
1#ifndef SOUND_FIREWIRE_CMP_H_INCLUDED
2#define SOUND_FIREWIRE_CMP_H_INCLUDED
3
4#include <linux/mutex.h>
5#include <linux/types.h>
6#include "iso-resources.h"
7
8struct fw_unit;
9
10/**
11 * struct cmp_connection - manages an isochronous connection to a device
12 * @speed: the connection's actual speed
13 *
14 * This structure manages (using CMP) an isochronous stream from the local
15 * computer to a device's input plug (iPCR).
16 *
17 * There is no corresponding oPCR created on the local computer, so it is not
18 * possible to overlay connections on top of this one.
19 */
20struct cmp_connection {
21 int speed;
22 /* private: */
23 bool connected;
24 struct mutex mutex;
25 struct fw_iso_resources resources;
26 __be32 last_pcr_value;
27 unsigned int pcr_index;
28 unsigned int max_speed;
29};
30
31int cmp_connection_init(struct cmp_connection *connection,
32 struct fw_unit *unit,
33 unsigned int ipcr_index);
34void cmp_connection_destroy(struct cmp_connection *connection);
35
36int cmp_connection_establish(struct cmp_connection *connection,
37 unsigned int max_payload);
38int cmp_connection_update(struct cmp_connection *connection);
39void cmp_connection_break(struct cmp_connection *connection);
40
41#endif
diff --git a/sound/firewire/fcp.c b/sound/firewire/fcp.c
new file mode 100644
index 000000000000..ec578b5ad8da
--- /dev/null
+++ b/sound/firewire/fcp.c
@@ -0,0 +1,224 @@
1/*
2 * Function Control Protocol (IEC 61883-1) helper functions
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 <linux/device.h>
9#include <linux/firewire.h>
10#include <linux/firewire-constants.h>
11#include <linux/list.h>
12#include <linux/module.h>
13#include <linux/sched.h>
14#include <linux/spinlock.h>
15#include <linux/wait.h>
16#include <linux/delay.h>
17#include "fcp.h"
18#include "lib.h"
19
20#define CTS_AVC 0x00
21
22#define ERROR_RETRIES 3
23#define ERROR_DELAY_MS 5
24#define FCP_TIMEOUT_MS 125
25
26static DEFINE_SPINLOCK(transactions_lock);
27static LIST_HEAD(transactions);
28
29enum fcp_state {
30 STATE_PENDING,
31 STATE_BUS_RESET,
32 STATE_COMPLETE,
33};
34
35struct fcp_transaction {
36 struct list_head list;
37 struct fw_unit *unit;
38 void *response_buffer;
39 unsigned int response_size;
40 unsigned int response_match_bytes;
41 enum fcp_state state;
42 wait_queue_head_t wait;
43};
44
45/**
46 * fcp_avc_transaction - send an AV/C command and wait for its response
47 * @unit: a unit on the target device
48 * @command: a buffer containing the command frame; must be DMA-able
49 * @command_size: the size of @command
50 * @response: a buffer for the response frame
51 * @response_size: the maximum size of @response
52 * @response_match_bytes: a bitmap specifying the bytes used to detect the
53 * correct response frame
54 *
55 * This function sends a FCP command frame to the target and waits for the
56 * corresponding response frame to be returned.
57 *
58 * Because it is possible for multiple FCP transactions to be active at the
59 * same time, the correct response frame is detected by the value of certain
60 * bytes. These bytes must be set in @response before calling this function,
61 * and the corresponding bits must be set in @response_match_bytes.
62 *
63 * @command and @response can point to the same buffer.
64 *
65 * Asynchronous operation (INTERIM, NOTIFY) is not supported at the moment.
66 *
67 * Returns the actual size of the response frame, or a negative error code.
68 */
69int fcp_avc_transaction(struct fw_unit *unit,
70 const void *command, unsigned int command_size,
71 void *response, unsigned int response_size,
72 unsigned int response_match_bytes)
73{
74 struct fcp_transaction t;
75 int tcode, ret, tries = 0;
76
77 t.unit = unit;
78 t.response_buffer = response;
79 t.response_size = response_size;
80 t.response_match_bytes = response_match_bytes;
81 t.state = STATE_PENDING;
82 init_waitqueue_head(&t.wait);
83
84 spin_lock_irq(&transactions_lock);
85 list_add_tail(&t.list, &transactions);
86 spin_unlock_irq(&transactions_lock);
87
88 for (;;) {
89 tcode = command_size == 4 ? TCODE_WRITE_QUADLET_REQUEST
90 : TCODE_WRITE_BLOCK_REQUEST;
91 ret = snd_fw_transaction(t.unit, tcode,
92 CSR_REGISTER_BASE + CSR_FCP_COMMAND,
93 (void *)command, command_size);
94 if (ret < 0)
95 break;
96
97 wait_event_timeout(t.wait, t.state != STATE_PENDING,
98 msecs_to_jiffies(FCP_TIMEOUT_MS));
99
100 if (t.state == STATE_COMPLETE) {
101 ret = t.response_size;
102 break;
103 } else if (t.state == STATE_BUS_RESET) {
104 msleep(ERROR_DELAY_MS);
105 } else if (++tries >= ERROR_RETRIES) {
106 dev_err(&t.unit->device, "FCP command timed out\n");
107 ret = -EIO;
108 break;
109 }
110 }
111
112 spin_lock_irq(&transactions_lock);
113 list_del(&t.list);
114 spin_unlock_irq(&transactions_lock);
115
116 return ret;
117}
118EXPORT_SYMBOL(fcp_avc_transaction);
119
120/**
121 * fcp_bus_reset - inform the target handler about a bus reset
122 * @unit: the unit that might be used by fcp_avc_transaction()
123 *
124 * This function must be called from the driver's .update handler to inform
125 * the FCP transaction handler that a bus reset has happened. Any pending FCP
126 * transactions are retried.
127 */
128void fcp_bus_reset(struct fw_unit *unit)
129{
130 struct fcp_transaction *t;
131
132 spin_lock_irq(&transactions_lock);
133 list_for_each_entry(t, &transactions, list) {
134 if (t->unit == unit &&
135 t->state == STATE_PENDING) {
136 t->state = STATE_BUS_RESET;
137 wake_up(&t->wait);
138 }
139 }
140 spin_unlock_irq(&transactions_lock);
141}
142EXPORT_SYMBOL(fcp_bus_reset);
143
144/* checks whether the response matches the masked bytes in response_buffer */
145static bool is_matching_response(struct fcp_transaction *transaction,
146 const void *response, size_t length)
147{
148 const u8 *p1, *p2;
149 unsigned int mask, i;
150
151 p1 = response;
152 p2 = transaction->response_buffer;
153 mask = transaction->response_match_bytes;
154
155 for (i = 0; ; ++i) {
156 if ((mask & 1) && p1[i] != p2[i])
157 return false;
158 mask >>= 1;
159 if (!mask)
160 return true;
161 if (--length == 0)
162 return false;
163 }
164}
165
166static void fcp_response(struct fw_card *card, struct fw_request *request,
167 int tcode, int destination, int source,
168 int generation, unsigned long long offset,
169 void *data, size_t length, void *callback_data)
170{
171 struct fcp_transaction *t;
172 unsigned long flags;
173
174 if (length < 1 || (*(const u8 *)data & 0xf0) != CTS_AVC)
175 return;
176
177 spin_lock_irqsave(&transactions_lock, flags);
178 list_for_each_entry(t, &transactions, list) {
179 struct fw_device *device = fw_parent_device(t->unit);
180 if (device->card != card ||
181 device->generation != generation)
182 continue;
183 smp_rmb(); /* node_id vs. generation */
184 if (device->node_id != source)
185 continue;
186
187 if (t->state == STATE_PENDING &&
188 is_matching_response(t, data, length)) {
189 t->state = STATE_COMPLETE;
190 t->response_size = min((unsigned int)length,
191 t->response_size);
192 memcpy(t->response_buffer, data, t->response_size);
193 wake_up(&t->wait);
194 }
195 }
196 spin_unlock_irqrestore(&transactions_lock, flags);
197}
198
199static struct fw_address_handler response_register_handler = {
200 .length = 0x200,
201 .address_callback = fcp_response,
202};
203
204static int __init fcp_module_init(void)
205{
206 static const struct fw_address_region response_register_region = {
207 .start = CSR_REGISTER_BASE + CSR_FCP_RESPONSE,
208 .end = CSR_REGISTER_BASE + CSR_FCP_END,
209 };
210
211 fw_core_add_address_handler(&response_register_handler,
212 &response_register_region);
213
214 return 0;
215}
216
217static void __exit fcp_module_exit(void)
218{
219 WARN_ON(!list_empty(&transactions));
220 fw_core_remove_address_handler(&response_register_handler);
221}
222
223module_init(fcp_module_init);
224module_exit(fcp_module_exit);
diff --git a/sound/firewire/fcp.h b/sound/firewire/fcp.h
new file mode 100644
index 000000000000..86595688bd91
--- /dev/null
+++ b/sound/firewire/fcp.h
@@ -0,0 +1,12 @@
1#ifndef SOUND_FIREWIRE_FCP_H_INCLUDED
2#define SOUND_FIREWIRE_FCP_H_INCLUDED
3
4struct fw_unit;
5
6int fcp_avc_transaction(struct fw_unit *unit,
7 const void *command, unsigned int command_size,
8 void *response, unsigned int response_size,
9 unsigned int response_match_bytes);
10void fcp_bus_reset(struct fw_unit *unit);
11
12#endif
diff --git a/sound/firewire/iso-resources.c b/sound/firewire/iso-resources.c
new file mode 100644
index 000000000000..775dbd5f3445
--- /dev/null
+++ b/sound/firewire/iso-resources.c
@@ -0,0 +1,232 @@
1/*
2 * isochronous resources helper functions
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 <linux/device.h>
9#include <linux/firewire.h>
10#include <linux/firewire-constants.h>
11#include <linux/jiffies.h>
12#include <linux/mutex.h>
13#include <linux/sched.h>
14#include <linux/slab.h>
15#include <linux/spinlock.h>
16#include "iso-resources.h"
17
18/**
19 * fw_iso_resources_init - initializes a &struct fw_iso_resources
20 * @r: the resource manager to initialize
21 * @unit: the device unit for which the resources will be needed
22 *
23 * If the device does not support all channel numbers, change @r->channels_mask
24 * after calling this function.
25 */
26int fw_iso_resources_init(struct fw_iso_resources *r, struct fw_unit *unit)
27{
28 r->buffer = kmalloc(2 * 4, GFP_KERNEL);
29 if (!r->buffer)
30 return -ENOMEM;
31
32 r->channels_mask = ~0uLL;
33 r->unit = fw_unit_get(unit);
34 mutex_init(&r->mutex);
35 r->allocated = false;
36
37 return 0;
38}
39
40/**
41 * fw_iso_resources_destroy - destroy a resource manager
42 * @r: the resource manager that is no longer needed
43 */
44void fw_iso_resources_destroy(struct fw_iso_resources *r)
45{
46 WARN_ON(r->allocated);
47 kfree(r->buffer);
48 mutex_destroy(&r->mutex);
49 fw_unit_put(r->unit);
50}
51
52static unsigned int packet_bandwidth(unsigned int max_payload_bytes, int speed)
53{
54 unsigned int bytes, s400_bytes;
55
56 /* iso packets have three header quadlets and quadlet-aligned payload */
57 bytes = 3 * 4 + ALIGN(max_payload_bytes, 4);
58
59 /* convert to bandwidth units (quadlets at S1600 = bytes at S400) */
60 if (speed <= SCODE_400)
61 s400_bytes = bytes * (1 << (SCODE_400 - speed));
62 else
63 s400_bytes = DIV_ROUND_UP(bytes, 1 << (speed - SCODE_400));
64
65 return s400_bytes;
66}
67
68static int current_bandwidth_overhead(struct fw_card *card)
69{
70 /*
71 * Under the usual pessimistic assumption (cable length 4.5 m), the
72 * isochronous overhead for N cables is 1.797 µs + N * 0.494 µs, or
73 * 88.3 + N * 24.3 in bandwidth units.
74 *
75 * The calculation below tries to deduce N from the current gap count.
76 * If the gap count has been optimized by measuring the actual packet
77 * transmission time, this derived overhead should be near the actual
78 * overhead as well.
79 */
80 return card->gap_count < 63 ? card->gap_count * 97 / 10 + 89 : 512;
81}
82
83static int wait_isoch_resource_delay_after_bus_reset(struct fw_card *card)
84{
85 for (;;) {
86 s64 delay = (card->reset_jiffies + HZ) - get_jiffies_64();
87 if (delay <= 0)
88 return 0;
89 if (schedule_timeout_interruptible(delay) > 0)
90 return -ERESTARTSYS;
91 }
92}
93
94/**
95 * fw_iso_resources_allocate - allocate isochronous channel and bandwidth
96 * @r: the resource manager
97 * @max_payload_bytes: the amount of data (including CIP headers) per packet
98 * @speed: the speed (e.g., SCODE_400) at which the packets will be sent
99 *
100 * This function allocates one isochronous channel and enough bandwidth for the
101 * specified packet size.
102 *
103 * Returns the channel number that the caller must use for streaming, or
104 * a negative error code. Due to potentionally long delays, this function is
105 * interruptible and can return -ERESTARTSYS. On success, the caller is
106 * responsible for calling fw_iso_resources_update() on bus resets, and
107 * fw_iso_resources_free() when the resources are not longer needed.
108 */
109int fw_iso_resources_allocate(struct fw_iso_resources *r,
110 unsigned int max_payload_bytes, int speed)
111{
112 struct fw_card *card = fw_parent_device(r->unit)->card;
113 int bandwidth, channel, err;
114
115 if (WARN_ON(r->allocated))
116 return -EBADFD;
117
118 r->bandwidth = packet_bandwidth(max_payload_bytes, speed);
119
120retry_after_bus_reset:
121 spin_lock_irq(&card->lock);
122 r->generation = card->generation;
123 r->bandwidth_overhead = current_bandwidth_overhead(card);
124 spin_unlock_irq(&card->lock);
125
126 err = wait_isoch_resource_delay_after_bus_reset(card);
127 if (err < 0)
128 return err;
129
130 mutex_lock(&r->mutex);
131
132 bandwidth = r->bandwidth + r->bandwidth_overhead;
133 fw_iso_resource_manage(card, r->generation, r->channels_mask,
134 &channel, &bandwidth, true, r->buffer);
135 if (channel == -EAGAIN) {
136 mutex_unlock(&r->mutex);
137 goto retry_after_bus_reset;
138 }
139 if (channel >= 0) {
140 r->channel = channel;
141 r->allocated = true;
142 } else {
143 if (channel == -EBUSY)
144 dev_err(&r->unit->device,
145 "isochronous resources exhausted\n");
146 else
147 dev_err(&r->unit->device,
148 "isochronous resource allocation failed\n");
149 }
150
151 mutex_unlock(&r->mutex);
152
153 return channel;
154}
155
156/**
157 * fw_iso_resources_update - update resource allocations after a bus reset
158 * @r: the resource manager
159 *
160 * This function must be called from the driver's .update handler to reallocate
161 * any resources that were allocated before the bus reset. It is safe to call
162 * this function if no resources are currently allocated.
163 *
164 * Returns a negative error code on failure. If this happens, the caller must
165 * stop streaming.
166 */
167int fw_iso_resources_update(struct fw_iso_resources *r)
168{
169 struct fw_card *card = fw_parent_device(r->unit)->card;
170 int bandwidth, channel;
171
172 mutex_lock(&r->mutex);
173
174 if (!r->allocated) {
175 mutex_unlock(&r->mutex);
176 return 0;
177 }
178
179 spin_lock_irq(&card->lock);
180 r->generation = card->generation;
181 r->bandwidth_overhead = current_bandwidth_overhead(card);
182 spin_unlock_irq(&card->lock);
183
184 bandwidth = r->bandwidth + r->bandwidth_overhead;
185
186 fw_iso_resource_manage(card, r->generation, 1uLL << r->channel,
187 &channel, &bandwidth, true, r->buffer);
188 /*
189 * When another bus reset happens, pretend that the allocation
190 * succeeded; we will try again for the new generation later.
191 */
192 if (channel < 0 && channel != -EAGAIN) {
193 r->allocated = false;
194 if (channel == -EBUSY)
195 dev_err(&r->unit->device,
196 "isochronous resources exhausted\n");
197 else
198 dev_err(&r->unit->device,
199 "isochronous resource allocation failed\n");
200 }
201
202 mutex_unlock(&r->mutex);
203
204 return channel;
205}
206
207/**
208 * fw_iso_resources_free - frees allocated resources
209 * @r: the resource manager
210 *
211 * This function deallocates the channel and bandwidth, if allocated.
212 */
213void fw_iso_resources_free(struct fw_iso_resources *r)
214{
215 struct fw_card *card = fw_parent_device(r->unit)->card;
216 int bandwidth, channel;
217
218 mutex_lock(&r->mutex);
219
220 if (r->allocated) {
221 bandwidth = r->bandwidth + r->bandwidth_overhead;
222 fw_iso_resource_manage(card, r->generation, 1uLL << r->channel,
223 &channel, &bandwidth, false, r->buffer);
224 if (channel < 0)
225 dev_err(&r->unit->device,
226 "isochronous resource deallocation failed\n");
227
228 r->allocated = false;
229 }
230
231 mutex_unlock(&r->mutex);
232}
diff --git a/sound/firewire/iso-resources.h b/sound/firewire/iso-resources.h
new file mode 100644
index 000000000000..3f0730e4d841
--- /dev/null
+++ b/sound/firewire/iso-resources.h
@@ -0,0 +1,39 @@
1#ifndef SOUND_FIREWIRE_ISO_RESOURCES_H_INCLUDED
2#define SOUND_FIREWIRE_ISO_RESOURCES_H_INCLUDED
3
4#include <linux/mutex.h>
5#include <linux/types.h>
6
7struct fw_unit;
8
9/**
10 * struct fw_iso_resources - manages channel/bandwidth allocation
11 * @channels_mask: if the device does not support all channel numbers, set this
12 * bit mask to something else than the default (all ones)
13 *
14 * This structure manages (de)allocation of isochronous resources (channel and
15 * bandwidth) for one isochronous stream.
16 */
17struct fw_iso_resources {
18 u64 channels_mask;
19 /* private: */
20 struct fw_unit *unit;
21 struct mutex mutex;
22 unsigned int channel;
23 unsigned int bandwidth; /* in bandwidth units, without overhead */
24 unsigned int bandwidth_overhead;
25 int generation; /* in which allocation is valid */
26 bool allocated;
27 __be32 *buffer;
28};
29
30int fw_iso_resources_init(struct fw_iso_resources *r,
31 struct fw_unit *unit);
32void fw_iso_resources_destroy(struct fw_iso_resources *r);
33
34int fw_iso_resources_allocate(struct fw_iso_resources *r,
35 unsigned int max_payload_bytes, int speed);
36int fw_iso_resources_update(struct fw_iso_resources *r);
37void fw_iso_resources_free(struct fw_iso_resources *r);
38
39#endif
diff --git a/sound/firewire/lib.c b/sound/firewire/lib.c
new file mode 100644
index 000000000000..4750cea2210e
--- /dev/null
+++ b/sound/firewire/lib.c
@@ -0,0 +1,85 @@
1/*
2 * miscellaneous helper functions
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 <linux/delay.h>
9#include <linux/device.h>
10#include <linux/firewire.h>
11#include <linux/module.h>
12#include "lib.h"
13
14#define ERROR_RETRY_DELAY_MS 5
15
16/**
17 * rcode_string - convert a firewire result code to a string
18 * @rcode: the result
19 */
20const char *rcode_string(unsigned int rcode)
21{
22 static const char *const names[] = {
23 [RCODE_COMPLETE] = "complete",
24 [RCODE_CONFLICT_ERROR] = "conflict error",
25 [RCODE_DATA_ERROR] = "data error",
26 [RCODE_TYPE_ERROR] = "type error",
27 [RCODE_ADDRESS_ERROR] = "address error",
28 [RCODE_SEND_ERROR] = "send error",
29 [RCODE_CANCELLED] = "cancelled",
30 [RCODE_BUSY] = "busy",
31 [RCODE_GENERATION] = "generation",
32 [RCODE_NO_ACK] = "no ack",
33 };
34
35 if (rcode < ARRAY_SIZE(names) && names[rcode])
36 return names[rcode];
37 else
38 return "unknown";
39}
40EXPORT_SYMBOL(rcode_string);
41
42/**
43 * snd_fw_transaction - send a request and wait for its completion
44 * @unit: the driver's unit on the target device
45 * @tcode: the transaction code
46 * @offset: the address in the target's address space
47 * @buffer: input/output data
48 * @length: length of @buffer
49 *
50 * Submits an asynchronous request to the target device, and waits for the
51 * response. The node ID and the current generation are derived from @unit.
52 * On a bus reset or an error, the transaction is retried a few times.
53 * Returns zero on success, or a negative error code.
54 */
55int snd_fw_transaction(struct fw_unit *unit, int tcode,
56 u64 offset, void *buffer, size_t length)
57{
58 struct fw_device *device = fw_parent_device(unit);
59 int generation, rcode, tries = 0;
60
61 for (;;) {
62 generation = device->generation;
63 smp_rmb(); /* node_id vs. generation */
64 rcode = fw_run_transaction(device->card, tcode,
65 device->node_id, generation,
66 device->max_speed, offset,
67 buffer, length);
68
69 if (rcode == RCODE_COMPLETE)
70 return 0;
71
72 if (rcode_is_permanent_error(rcode) || ++tries >= 3) {
73 dev_err(&unit->device, "transaction failed: %s\n",
74 rcode_string(rcode));
75 return -EIO;
76 }
77
78 msleep(ERROR_RETRY_DELAY_MS);
79 }
80}
81EXPORT_SYMBOL(snd_fw_transaction);
82
83MODULE_DESCRIPTION("FireWire audio helper functions");
84MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
85MODULE_LICENSE("GPL v2");
diff --git a/sound/firewire/lib.h b/sound/firewire/lib.h
new file mode 100644
index 000000000000..064f3fd9ab06
--- /dev/null
+++ b/sound/firewire/lib.h
@@ -0,0 +1,19 @@
1#ifndef SOUND_FIREWIRE_LIB_H_INCLUDED
2#define SOUND_FIREWIRE_LIB_H_INCLUDED
3
4#include <linux/firewire-constants.h>
5#include <linux/types.h>
6
7struct fw_unit;
8
9int snd_fw_transaction(struct fw_unit *unit, int tcode,
10 u64 offset, void *buffer, size_t length);
11const char *rcode_string(unsigned int rcode);
12
13/* returns true if retrying the transaction would not make sense */
14static inline bool rcode_is_permanent_error(int rcode)
15{
16 return rcode == RCODE_TYPE_ERROR || rcode == RCODE_ADDRESS_ERROR;
17}
18
19#endif
diff --git a/sound/firewire/packets-buffer.c b/sound/firewire/packets-buffer.c
new file mode 100644
index 000000000000..1e20e60ba6a6
--- /dev/null
+++ b/sound/firewire/packets-buffer.c
@@ -0,0 +1,74 @@
1/*
2 * helpers for managing a buffer for many packets
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 <linux/firewire.h>
9#include <linux/slab.h>
10#include "packets-buffer.h"
11
12/**
13 * iso_packets_buffer_init - allocates the memory for packets
14 * @b: the buffer structure to initialize
15 * @unit: the device at the other end of the stream
16 * @count: the number of packets
17 * @packet_size: the (maximum) size of a packet, in bytes
18 * @direction: %DMA_TO_DEVICE or %DMA_FROM_DEVICE
19 */
20int iso_packets_buffer_init(struct iso_packets_buffer *b, struct fw_unit *unit,
21 unsigned int count, unsigned int packet_size,
22 enum dma_data_direction direction)
23{
24 unsigned int packets_per_page, pages;
25 unsigned int i, page_index, offset_in_page;
26 void *p;
27 int err;
28
29 b->packets = kmalloc(count * sizeof(*b->packets), GFP_KERNEL);
30 if (!b->packets) {
31 err = -ENOMEM;
32 goto error;
33 }
34
35 packet_size = L1_CACHE_ALIGN(packet_size);
36 packets_per_page = PAGE_SIZE / packet_size;
37 if (WARN_ON(!packets_per_page)) {
38 err = -EINVAL;
39 goto error;
40 }
41 pages = DIV_ROUND_UP(count, packets_per_page);
42
43 err = fw_iso_buffer_init(&b->iso_buffer, fw_parent_device(unit)->card,
44 pages, direction);
45 if (err < 0)
46 goto err_packets;
47
48 for (i = 0; i < count; ++i) {
49 page_index = i / packets_per_page;
50 p = page_address(b->iso_buffer.pages[page_index]);
51 offset_in_page = (i % packets_per_page) * packet_size;
52 b->packets[i].buffer = p + offset_in_page;
53 b->packets[i].offset = page_index * PAGE_SIZE + offset_in_page;
54 }
55
56 return 0;
57
58err_packets:
59 kfree(b->packets);
60error:
61 return err;
62}
63
64/**
65 * iso_packets_buffer_destroy - frees packet buffer resources
66 * @b: the buffer structure to free
67 * @unit: the device at the other end of the stream
68 */
69void iso_packets_buffer_destroy(struct iso_packets_buffer *b,
70 struct fw_unit *unit)
71{
72 fw_iso_buffer_destroy(&b->iso_buffer, fw_parent_device(unit)->card);
73 kfree(b->packets);
74}
diff --git a/sound/firewire/packets-buffer.h b/sound/firewire/packets-buffer.h
new file mode 100644
index 000000000000..6513c5cb6ea9
--- /dev/null
+++ b/sound/firewire/packets-buffer.h
@@ -0,0 +1,26 @@
1#ifndef SOUND_FIREWIRE_PACKETS_BUFFER_H_INCLUDED
2#define SOUND_FIREWIRE_PACKETS_BUFFER_H_INCLUDED
3
4#include <linux/dma-mapping.h>
5#include <linux/firewire.h>
6
7/**
8 * struct iso_packets_buffer - manages a buffer for many packets
9 * @iso_buffer: the memory containing the packets
10 * @packets: an array, with each element pointing to one packet
11 */
12struct iso_packets_buffer {
13 struct fw_iso_buffer iso_buffer;
14 struct {
15 void *buffer;
16 unsigned int offset;
17 } *packets;
18};
19
20int iso_packets_buffer_init(struct iso_packets_buffer *b, struct fw_unit *unit,
21 unsigned int count, unsigned int packet_size,
22 enum dma_data_direction direction);
23void iso_packets_buffer_destroy(struct iso_packets_buffer *b,
24 struct fw_unit *unit);
25
26#endif
diff --git a/sound/firewire/speakers.c b/sound/firewire/speakers.c
new file mode 100644
index 000000000000..0fce9218abb1
--- /dev/null
+++ b/sound/firewire/speakers.c
@@ -0,0 +1,858 @@
1/*
2 * OXFW970-based speakers 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 <linux/device.h>
9#include <linux/firewire.h>
10#include <linux/firewire-constants.h>
11#include <linux/module.h>
12#include <linux/mod_devicetable.h>
13#include <linux/mutex.h>
14#include <linux/slab.h>
15#include <sound/control.h>
16#include <sound/core.h>
17#include <sound/initval.h>
18#include <sound/pcm.h>
19#include <sound/pcm_params.h>
20#include "cmp.h"
21#include "fcp.h"
22#include "amdtp.h"
23#include "lib.h"
24
25#define OXFORD_FIRMWARE_ID_ADDRESS (CSR_REGISTER_BASE + 0x50000)
26/* 0x970?vvvv or 0x971?vvvv, where vvvv = firmware version */
27
28#define OXFORD_HARDWARE_ID_ADDRESS (CSR_REGISTER_BASE + 0x90020)
29#define OXFORD_HARDWARE_ID_OXFW970 0x39443841
30#define OXFORD_HARDWARE_ID_OXFW971 0x39373100
31
32#define VENDOR_GRIFFIN 0x001292
33#define VENDOR_LACIE 0x00d04b
34
35#define SPECIFIER_1394TA 0x00a02d
36#define VERSION_AVC 0x010001
37
38struct device_info {
39 const char *driver_name;
40 const char *short_name;
41 const char *long_name;
42 int (*pcm_constraints)(struct snd_pcm_runtime *runtime);
43 unsigned int mixer_channels;
44 u8 mute_fb_id;
45 u8 volume_fb_id;
46};
47
48struct fwspk {
49 struct snd_card *card;
50 struct fw_unit *unit;
51 const struct device_info *device_info;
52 struct snd_pcm_substream *pcm;
53 struct mutex mutex;
54 struct cmp_connection connection;
55 struct amdtp_out_stream stream;
56 bool stream_running;
57 bool mute;
58 s16 volume[6];
59 s16 volume_min;
60 s16 volume_max;
61};
62
63MODULE_DESCRIPTION("FireWire speakers driver");
64MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
65MODULE_LICENSE("GPL v2");
66
67static int firewave_rate_constraint(struct snd_pcm_hw_params *params,
68 struct snd_pcm_hw_rule *rule)
69{
70 static unsigned int stereo_rates[] = { 48000, 96000 };
71 struct snd_interval *channels =
72 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
73 struct snd_interval *rate =
74 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
75
76 /* two channels work only at 48/96 kHz */
77 if (snd_interval_max(channels) < 6)
78 return snd_interval_list(rate, 2, stereo_rates, 0);
79 return 0;
80}
81
82static int firewave_channels_constraint(struct snd_pcm_hw_params *params,
83 struct snd_pcm_hw_rule *rule)
84{
85 static const struct snd_interval all_channels = { .min = 6, .max = 6 };
86 struct snd_interval *rate =
87 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
88 struct snd_interval *channels =
89 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
90
91 /* 32/44.1 kHz work only with all six channels */
92 if (snd_interval_max(rate) < 48000)
93 return snd_interval_refine(channels, &all_channels);
94 return 0;
95}
96
97static int firewave_constraints(struct snd_pcm_runtime *runtime)
98{
99 static unsigned int channels_list[] = { 2, 6 };
100 static struct snd_pcm_hw_constraint_list channels_list_constraint = {
101 .count = 2,
102 .list = channels_list,
103 };
104 int err;
105
106 runtime->hw.rates = SNDRV_PCM_RATE_32000 |
107 SNDRV_PCM_RATE_44100 |
108 SNDRV_PCM_RATE_48000 |
109 SNDRV_PCM_RATE_96000;
110 runtime->hw.channels_max = 6;
111
112 err = snd_pcm_hw_constraint_list(runtime, 0,
113 SNDRV_PCM_HW_PARAM_CHANNELS,
114 &channels_list_constraint);
115 if (err < 0)
116 return err;
117 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
118 firewave_rate_constraint, NULL,
119 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
120 if (err < 0)
121 return err;
122 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
123 firewave_channels_constraint, NULL,
124 SNDRV_PCM_HW_PARAM_RATE, -1);
125 if (err < 0)
126 return err;
127
128 return 0;
129}
130
131static int lacie_speakers_constraints(struct snd_pcm_runtime *runtime)
132{
133 runtime->hw.rates = SNDRV_PCM_RATE_32000 |
134 SNDRV_PCM_RATE_44100 |
135 SNDRV_PCM_RATE_48000 |
136 SNDRV_PCM_RATE_88200 |
137 SNDRV_PCM_RATE_96000;
138
139 return 0;
140}
141
142static int fwspk_open(struct snd_pcm_substream *substream)
143{
144 static const struct snd_pcm_hardware hardware = {
145 .info = SNDRV_PCM_INFO_MMAP |
146 SNDRV_PCM_INFO_MMAP_VALID |
147 SNDRV_PCM_INFO_BATCH |
148 SNDRV_PCM_INFO_INTERLEAVED |
149 SNDRV_PCM_INFO_BLOCK_TRANSFER,
150 .formats = AMDTP_OUT_PCM_FORMAT_BITS,
151 .channels_min = 2,
152 .channels_max = 2,
153 .buffer_bytes_max = 4 * 1024 * 1024,
154 .period_bytes_min = 1,
155 .period_bytes_max = UINT_MAX,
156 .periods_min = 1,
157 .periods_max = UINT_MAX,
158 };
159 struct fwspk *fwspk = substream->private_data;
160 struct snd_pcm_runtime *runtime = substream->runtime;
161 int err;
162
163 runtime->hw = hardware;
164
165 err = fwspk->device_info->pcm_constraints(runtime);
166 if (err < 0)
167 return err;
168 err = snd_pcm_limit_hw_rates(runtime);
169 if (err < 0)
170 return err;
171
172 err = snd_pcm_hw_constraint_minmax(runtime,
173 SNDRV_PCM_HW_PARAM_PERIOD_TIME,
174 5000, 8192000);
175 if (err < 0)
176 return err;
177
178 err = snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
179 if (err < 0)
180 return err;
181
182 return 0;
183}
184
185static int fwspk_close(struct snd_pcm_substream *substream)
186{
187 return 0;
188}
189
190static void fwspk_stop_stream(struct fwspk *fwspk)
191{
192 if (fwspk->stream_running) {
193 amdtp_out_stream_stop(&fwspk->stream);
194 cmp_connection_break(&fwspk->connection);
195 fwspk->stream_running = false;
196 }
197}
198
199static int fwspk_set_rate(struct fwspk *fwspk, unsigned int sfc)
200{
201 u8 *buf;
202 int err;
203
204 buf = kmalloc(8, GFP_KERNEL);
205 if (!buf)
206 return -ENOMEM;
207
208 buf[0] = 0x00; /* AV/C, CONTROL */
209 buf[1] = 0xff; /* unit */
210 buf[2] = 0x19; /* INPUT PLUG SIGNAL FORMAT */
211 buf[3] = 0x00; /* plug 0 */
212 buf[4] = 0x90; /* format: audio */
213 buf[5] = 0x00 | sfc; /* AM824, frequency */
214 buf[6] = 0xff; /* SYT (not used) */
215 buf[7] = 0xff;
216
217 err = fcp_avc_transaction(fwspk->unit, buf, 8, buf, 8,
218 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5));
219 if (err < 0)
220 goto error;
221 if (err < 6 || buf[0] != 0x09 /* ACCEPTED */) {
222 dev_err(&fwspk->unit->device, "failed to set sample rate\n");
223 err = -EIO;
224 goto error;
225 }
226
227 err = 0;
228
229error:
230 kfree(buf);
231
232 return err;
233}
234
235static int fwspk_hw_params(struct snd_pcm_substream *substream,
236 struct snd_pcm_hw_params *hw_params)
237{
238 struct fwspk *fwspk = substream->private_data;
239 int err;
240
241 mutex_lock(&fwspk->mutex);
242 fwspk_stop_stream(fwspk);
243 mutex_unlock(&fwspk->mutex);
244
245 err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
246 params_buffer_bytes(hw_params));
247 if (err < 0)
248 goto error;
249
250 amdtp_out_stream_set_rate(&fwspk->stream, params_rate(hw_params));
251 amdtp_out_stream_set_pcm(&fwspk->stream, params_channels(hw_params));
252
253 amdtp_out_stream_set_pcm_format(&fwspk->stream,
254 params_format(hw_params));
255
256 err = fwspk_set_rate(fwspk, fwspk->stream.sfc);
257 if (err < 0)
258 goto err_buffer;
259
260 return 0;
261
262err_buffer:
263 snd_pcm_lib_free_vmalloc_buffer(substream);
264error:
265 return err;
266}
267
268static int fwspk_hw_free(struct snd_pcm_substream *substream)
269{
270 struct fwspk *fwspk = substream->private_data;
271
272 mutex_lock(&fwspk->mutex);
273 fwspk_stop_stream(fwspk);
274 mutex_unlock(&fwspk->mutex);
275
276 return snd_pcm_lib_free_vmalloc_buffer(substream);
277}
278
279static int fwspk_prepare(struct snd_pcm_substream *substream)
280{
281 struct fwspk *fwspk = substream->private_data;
282 int err;
283
284 mutex_lock(&fwspk->mutex);
285
286 if (amdtp_out_streaming_error(&fwspk->stream))
287 fwspk_stop_stream(fwspk);
288
289 if (!fwspk->stream_running) {
290 err = cmp_connection_establish(&fwspk->connection,
291 amdtp_out_stream_get_max_payload(&fwspk->stream));
292 if (err < 0)
293 goto err_mutex;
294
295 err = amdtp_out_stream_start(&fwspk->stream,
296 fwspk->connection.resources.channel,
297 fwspk->connection.speed);
298 if (err < 0)
299 goto err_connection;
300
301 fwspk->stream_running = true;
302 }
303
304 mutex_unlock(&fwspk->mutex);
305
306 amdtp_out_stream_pcm_prepare(&fwspk->stream);
307
308 return 0;
309
310err_connection:
311 cmp_connection_break(&fwspk->connection);
312err_mutex:
313 mutex_unlock(&fwspk->mutex);
314
315 return err;
316}
317
318static int fwspk_trigger(struct snd_pcm_substream *substream, int cmd)
319{
320 struct fwspk *fwspk = substream->private_data;
321 struct snd_pcm_substream *pcm;
322
323 switch (cmd) {
324 case SNDRV_PCM_TRIGGER_START:
325 pcm = substream;
326 break;
327 case SNDRV_PCM_TRIGGER_STOP:
328 pcm = NULL;
329 break;
330 default:
331 return -EINVAL;
332 }
333 amdtp_out_stream_pcm_trigger(&fwspk->stream, pcm);
334 return 0;
335}
336
337static snd_pcm_uframes_t fwspk_pointer(struct snd_pcm_substream *substream)
338{
339 struct fwspk *fwspk = substream->private_data;
340
341 return amdtp_out_stream_pcm_pointer(&fwspk->stream);
342}
343
344static int fwspk_create_pcm(struct fwspk *fwspk)
345{
346 static struct snd_pcm_ops ops = {
347 .open = fwspk_open,
348 .close = fwspk_close,
349 .ioctl = snd_pcm_lib_ioctl,
350 .hw_params = fwspk_hw_params,
351 .hw_free = fwspk_hw_free,
352 .prepare = fwspk_prepare,
353 .trigger = fwspk_trigger,
354 .pointer = fwspk_pointer,
355 .page = snd_pcm_lib_get_vmalloc_page,
356 .mmap = snd_pcm_lib_mmap_vmalloc,
357 };
358 struct snd_pcm *pcm;
359 int err;
360
361 err = snd_pcm_new(fwspk->card, "OXFW970", 0, 1, 0, &pcm);
362 if (err < 0)
363 return err;
364 pcm->private_data = fwspk;
365 strcpy(pcm->name, fwspk->device_info->short_name);
366 fwspk->pcm = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
367 fwspk->pcm->ops = &ops;
368 return 0;
369}
370
371enum control_action { CTL_READ, CTL_WRITE };
372enum control_attribute {
373 CTL_MIN = 0x02,
374 CTL_MAX = 0x03,
375 CTL_CURRENT = 0x10,
376};
377
378static int fwspk_mute_command(struct fwspk *fwspk, bool *value,
379 enum control_action action)
380{
381 u8 *buf;
382 u8 response_ok;
383 int err;
384
385 buf = kmalloc(11, GFP_KERNEL);
386 if (!buf)
387 return -ENOMEM;
388
389 if (action == CTL_READ) {
390 buf[0] = 0x01; /* AV/C, STATUS */
391 response_ok = 0x0c; /* STABLE */
392 } else {
393 buf[0] = 0x00; /* AV/C, CONTROL */
394 response_ok = 0x09; /* ACCEPTED */
395 }
396 buf[1] = 0x08; /* audio unit 0 */
397 buf[2] = 0xb8; /* FUNCTION BLOCK */
398 buf[3] = 0x81; /* function block type: feature */
399 buf[4] = fwspk->device_info->mute_fb_id; /* function block ID */
400 buf[5] = 0x10; /* control attribute: current */
401 buf[6] = 0x02; /* selector length */
402 buf[7] = 0x00; /* audio channel number */
403 buf[8] = 0x01; /* control selector: mute */
404 buf[9] = 0x01; /* control data length */
405 if (action == CTL_READ)
406 buf[10] = 0xff;
407 else
408 buf[10] = *value ? 0x70 : 0x60;
409
410 err = fcp_avc_transaction(fwspk->unit, buf, 11, buf, 11, 0x3fe);
411 if (err < 0)
412 goto error;
413 if (err < 11) {
414 dev_err(&fwspk->unit->device, "short FCP response\n");
415 err = -EIO;
416 goto error;
417 }
418 if (buf[0] != response_ok) {
419 dev_err(&fwspk->unit->device, "mute command failed\n");
420 err = -EIO;
421 goto error;
422 }
423 if (action == CTL_READ)
424 *value = buf[10] == 0x70;
425
426 err = 0;
427
428error:
429 kfree(buf);
430
431 return err;
432}
433
434static int fwspk_volume_command(struct fwspk *fwspk, s16 *value,
435 unsigned int channel,
436 enum control_attribute attribute,
437 enum control_action action)
438{
439 u8 *buf;
440 u8 response_ok;
441 int err;
442
443 buf = kmalloc(12, GFP_KERNEL);
444 if (!buf)
445 return -ENOMEM;
446
447 if (action == CTL_READ) {
448 buf[0] = 0x01; /* AV/C, STATUS */
449 response_ok = 0x0c; /* STABLE */
450 } else {
451 buf[0] = 0x00; /* AV/C, CONTROL */
452 response_ok = 0x09; /* ACCEPTED */
453 }
454 buf[1] = 0x08; /* audio unit 0 */
455 buf[2] = 0xb8; /* FUNCTION BLOCK */
456 buf[3] = 0x81; /* function block type: feature */
457 buf[4] = fwspk->device_info->volume_fb_id; /* function block ID */
458 buf[5] = attribute; /* control attribute */
459 buf[6] = 0x02; /* selector length */
460 buf[7] = channel; /* audio channel number */
461 buf[8] = 0x02; /* control selector: volume */
462 buf[9] = 0x02; /* control data length */
463 if (action == CTL_READ) {
464 buf[10] = 0xff;
465 buf[11] = 0xff;
466 } else {
467 buf[10] = *value >> 8;
468 buf[11] = *value;
469 }
470
471 err = fcp_avc_transaction(fwspk->unit, buf, 12, buf, 12, 0x3fe);
472 if (err < 0)
473 goto error;
474 if (err < 12) {
475 dev_err(&fwspk->unit->device, "short FCP response\n");
476 err = -EIO;
477 goto error;
478 }
479 if (buf[0] != response_ok) {
480 dev_err(&fwspk->unit->device, "volume command failed\n");
481 err = -EIO;
482 goto error;
483 }
484 if (action == CTL_READ)
485 *value = (buf[10] << 8) | buf[11];
486
487 err = 0;
488
489error:
490 kfree(buf);
491
492 return err;
493}
494
495static int fwspk_mute_get(struct snd_kcontrol *control,
496 struct snd_ctl_elem_value *value)
497{
498 struct fwspk *fwspk = control->private_data;
499
500 value->value.integer.value[0] = !fwspk->mute;
501
502 return 0;
503}
504
505static int fwspk_mute_put(struct snd_kcontrol *control,
506 struct snd_ctl_elem_value *value)
507{
508 struct fwspk *fwspk = control->private_data;
509 bool mute;
510 int err;
511
512 mute = !value->value.integer.value[0];
513
514 if (mute == fwspk->mute)
515 return 0;
516
517 err = fwspk_mute_command(fwspk, &mute, CTL_WRITE);
518 if (err < 0)
519 return err;
520 fwspk->mute = mute;
521
522 return 1;
523}
524
525static int fwspk_volume_info(struct snd_kcontrol *control,
526 struct snd_ctl_elem_info *info)
527{
528 struct fwspk *fwspk = control->private_data;
529
530 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
531 info->count = fwspk->device_info->mixer_channels;
532 info->value.integer.min = fwspk->volume_min;
533 info->value.integer.max = fwspk->volume_max;
534
535 return 0;
536}
537
538static const u8 channel_map[6] = { 0, 1, 4, 5, 2, 3 };
539
540static int fwspk_volume_get(struct snd_kcontrol *control,
541 struct snd_ctl_elem_value *value)
542{
543 struct fwspk *fwspk = control->private_data;
544 unsigned int i;
545
546 for (i = 0; i < fwspk->device_info->mixer_channels; ++i)
547 value->value.integer.value[channel_map[i]] = fwspk->volume[i];
548
549 return 0;
550}
551
552static int fwspk_volume_put(struct snd_kcontrol *control,
553 struct snd_ctl_elem_value *value)
554{
555 struct fwspk *fwspk = control->private_data;
556 unsigned int i, changed_channels;
557 bool equal_values = true;
558 s16 volume;
559 int err;
560
561 for (i = 0; i < fwspk->device_info->mixer_channels; ++i) {
562 if (value->value.integer.value[i] < fwspk->volume_min ||
563 value->value.integer.value[i] > fwspk->volume_max)
564 return -EINVAL;
565 if (value->value.integer.value[i] !=
566 value->value.integer.value[0])
567 equal_values = false;
568 }
569
570 changed_channels = 0;
571 for (i = 0; i < fwspk->device_info->mixer_channels; ++i)
572 if (value->value.integer.value[channel_map[i]] !=
573 fwspk->volume[i])
574 changed_channels |= 1 << (i + 1);
575
576 if (equal_values && changed_channels != 0)
577 changed_channels = 1 << 0;
578
579 for (i = 0; i <= fwspk->device_info->mixer_channels; ++i) {
580 volume = value->value.integer.value[channel_map[i ? i - 1 : 0]];
581 if (changed_channels & (1 << i)) {
582 err = fwspk_volume_command(fwspk, &volume, i,
583 CTL_CURRENT, CTL_WRITE);
584 if (err < 0)
585 return err;
586 }
587 if (i > 0)
588 fwspk->volume[i - 1] = volume;
589 }
590
591 return changed_channels != 0;
592}
593
594static int fwspk_create_mixer(struct fwspk *fwspk)
595{
596 static const struct snd_kcontrol_new controls[] = {
597 {
598 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
599 .name = "PCM Playback Switch",
600 .info = snd_ctl_boolean_mono_info,
601 .get = fwspk_mute_get,
602 .put = fwspk_mute_put,
603 },
604 {
605 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
606 .name = "PCM Playback Volume",
607 .info = fwspk_volume_info,
608 .get = fwspk_volume_get,
609 .put = fwspk_volume_put,
610 },
611 };
612 unsigned int i, first_ch;
613 int err;
614
615 err = fwspk_volume_command(fwspk, &fwspk->volume_min,
616 0, CTL_MIN, CTL_READ);
617 if (err < 0)
618 return err;
619 err = fwspk_volume_command(fwspk, &fwspk->volume_max,
620 0, CTL_MAX, CTL_READ);
621 if (err < 0)
622 return err;
623
624 err = fwspk_mute_command(fwspk, &fwspk->mute, CTL_READ);
625 if (err < 0)
626 return err;
627
628 first_ch = fwspk->device_info->mixer_channels == 1 ? 0 : 1;
629 for (i = 0; i < fwspk->device_info->mixer_channels; ++i) {
630 err = fwspk_volume_command(fwspk, &fwspk->volume[i],
631 first_ch + i, CTL_CURRENT, CTL_READ);
632 if (err < 0)
633 return err;
634 }
635
636 for (i = 0; i < ARRAY_SIZE(controls); ++i) {
637 err = snd_ctl_add(fwspk->card,
638 snd_ctl_new1(&controls[i], fwspk));
639 if (err < 0)
640 return err;
641 }
642
643 return 0;
644}
645
646static u32 fwspk_read_firmware_version(struct fw_unit *unit)
647{
648 __be32 data;
649 int err;
650
651 err = snd_fw_transaction(unit, TCODE_READ_QUADLET_REQUEST,
652 OXFORD_FIRMWARE_ID_ADDRESS, &data, 4);
653 return err >= 0 ? be32_to_cpu(data) : 0;
654}
655
656static void fwspk_card_free(struct snd_card *card)
657{
658 struct fwspk *fwspk = card->private_data;
659 struct fw_device *dev = fw_parent_device(fwspk->unit);
660
661 amdtp_out_stream_destroy(&fwspk->stream);
662 cmp_connection_destroy(&fwspk->connection);
663 fw_unit_put(fwspk->unit);
664 fw_device_put(dev);
665 mutex_destroy(&fwspk->mutex);
666}
667
668static const struct device_info *__devinit fwspk_detect(struct fw_device *dev)
669{
670 static const struct device_info griffin_firewave = {
671 .driver_name = "FireWave",
672 .short_name = "FireWave",
673 .long_name = "Griffin FireWave Surround",
674 .pcm_constraints = firewave_constraints,
675 .mixer_channels = 6,
676 .mute_fb_id = 0x01,
677 .volume_fb_id = 0x02,
678 };
679 static const struct device_info lacie_speakers = {
680 .driver_name = "FWSpeakers",
681 .short_name = "FireWire Speakers",
682 .long_name = "LaCie FireWire Speakers",
683 .pcm_constraints = lacie_speakers_constraints,
684 .mixer_channels = 1,
685 .mute_fb_id = 0x01,
686 .volume_fb_id = 0x01,
687 };
688 struct fw_csr_iterator i;
689 int key, value;
690
691 fw_csr_iterator_init(&i, dev->config_rom);
692 while (fw_csr_iterator_next(&i, &key, &value))
693 if (key == CSR_VENDOR)
694 switch (value) {
695 case VENDOR_GRIFFIN:
696 return &griffin_firewave;
697 case VENDOR_LACIE:
698 return &lacie_speakers;
699 }
700
701 return NULL;
702}
703
704static int __devinit fwspk_probe(struct device *unit_dev)
705{
706 struct fw_unit *unit = fw_unit(unit_dev);
707 struct fw_device *fw_dev = fw_parent_device(unit);
708 struct snd_card *card;
709 struct fwspk *fwspk;
710 u32 firmware;
711 int err;
712
713 err = snd_card_create(-1, NULL, THIS_MODULE, sizeof(*fwspk), &card);
714 if (err < 0)
715 return err;
716 snd_card_set_dev(card, unit_dev);
717
718 fwspk = card->private_data;
719 fwspk->card = card;
720 mutex_init(&fwspk->mutex);
721 fw_device_get(fw_dev);
722 fwspk->unit = fw_unit_get(unit);
723 fwspk->device_info = fwspk_detect(fw_dev);
724 if (!fwspk->device_info) {
725 err = -ENODEV;
726 goto err_unit;
727 }
728
729 err = cmp_connection_init(&fwspk->connection, unit, 0);
730 if (err < 0)
731 goto err_unit;
732
733 err = amdtp_out_stream_init(&fwspk->stream, unit, CIP_NONBLOCKING);
734 if (err < 0)
735 goto err_connection;
736
737 card->private_free = fwspk_card_free;
738
739 strcpy(card->driver, fwspk->device_info->driver_name);
740 strcpy(card->shortname, fwspk->device_info->short_name);
741 firmware = fwspk_read_firmware_version(unit);
742 snprintf(card->longname, sizeof(card->longname),
743 "%s (OXFW%x %04x), GUID %08x%08x at %s, S%d",
744 fwspk->device_info->long_name,
745 firmware >> 20, firmware & 0xffff,
746 fw_dev->config_rom[3], fw_dev->config_rom[4],
747 dev_name(&unit->device), 100 << fw_dev->max_speed);
748 strcpy(card->mixername, "OXFW970");
749
750 err = fwspk_create_pcm(fwspk);
751 if (err < 0)
752 goto error;
753
754 err = fwspk_create_mixer(fwspk);
755 if (err < 0)
756 goto error;
757
758 err = snd_card_register(card);
759 if (err < 0)
760 goto error;
761
762 dev_set_drvdata(unit_dev, fwspk);
763
764 return 0;
765
766err_connection:
767 cmp_connection_destroy(&fwspk->connection);
768err_unit:
769 fw_unit_put(fwspk->unit);
770 fw_device_put(fw_dev);
771 mutex_destroy(&fwspk->mutex);
772error:
773 snd_card_free(card);
774 return err;
775}
776
777static int __devexit fwspk_remove(struct device *dev)
778{
779 struct fwspk *fwspk = dev_get_drvdata(dev);
780
781 snd_card_disconnect(fwspk->card);
782
783 mutex_lock(&fwspk->mutex);
784 amdtp_out_stream_pcm_abort(&fwspk->stream);
785 fwspk_stop_stream(fwspk);
786 mutex_unlock(&fwspk->mutex);
787
788 snd_card_free_when_closed(fwspk->card);
789
790 return 0;
791}
792
793static void fwspk_bus_reset(struct fw_unit *unit)
794{
795 struct fwspk *fwspk = dev_get_drvdata(&unit->device);
796
797 fcp_bus_reset(fwspk->unit);
798
799 if (cmp_connection_update(&fwspk->connection) < 0) {
800 mutex_lock(&fwspk->mutex);
801 amdtp_out_stream_pcm_abort(&fwspk->stream);
802 fwspk_stop_stream(fwspk);
803 mutex_unlock(&fwspk->mutex);
804 return;
805 }
806
807 amdtp_out_stream_update(&fwspk->stream);
808}
809
810static const struct ieee1394_device_id fwspk_id_table[] = {
811 {
812 .match_flags = IEEE1394_MATCH_VENDOR_ID |
813 IEEE1394_MATCH_MODEL_ID |
814 IEEE1394_MATCH_SPECIFIER_ID |
815 IEEE1394_MATCH_VERSION,
816 .vendor_id = VENDOR_GRIFFIN,
817 .model_id = 0x00f970,
818 .specifier_id = SPECIFIER_1394TA,
819 .version = VERSION_AVC,
820 },
821 {
822 .match_flags = IEEE1394_MATCH_VENDOR_ID |
823 IEEE1394_MATCH_MODEL_ID |
824 IEEE1394_MATCH_SPECIFIER_ID |
825 IEEE1394_MATCH_VERSION,
826 .vendor_id = VENDOR_LACIE,
827 .model_id = 0x00f970,
828 .specifier_id = SPECIFIER_1394TA,
829 .version = VERSION_AVC,
830 },
831 { }
832};
833MODULE_DEVICE_TABLE(ieee1394, fwspk_id_table);
834
835static struct fw_driver fwspk_driver = {
836 .driver = {
837 .owner = THIS_MODULE,
838 .name = KBUILD_MODNAME,
839 .bus = &fw_bus_type,
840 .probe = fwspk_probe,
841 .remove = __devexit_p(fwspk_remove),
842 },
843 .update = fwspk_bus_reset,
844 .id_table = fwspk_id_table,
845};
846
847static int __init alsa_fwspk_init(void)
848{
849 return driver_register(&fwspk_driver.driver);
850}
851
852static void __exit alsa_fwspk_exit(void)
853{
854 driver_unregister(&fwspk_driver.driver);
855}
856
857module_init(alsa_fwspk_init);
858module_exit(alsa_fwspk_exit);
diff --git a/sound/oss/soundcard.c b/sound/oss/soundcard.c
index fcb14a099822..7c7793a0eb25 100644
--- a/sound/oss/soundcard.c
+++ b/sound/oss/soundcard.c
@@ -526,31 +526,21 @@ bad:
526} 526}
527 527
528 528
529/* These device names follow the official Linux device list,
530 * Documentation/devices.txt. Let us know if there are other
531 * common names we should support for compatibility.
532 * Only those devices not created by the generic code in sound_core.c are
533 * registered here.
534 */
535static const struct {
536 unsigned short minor;
537 char *name;
538 umode_t mode;
539 int *num;
540} dev_list[] = { /* list of minor devices */
541/* seems to be some confusion here -- this device is not in the device list */
542 {SND_DEV_DSP16, "dspW", S_IWUGO | S_IRUSR | S_IRGRP,
543 &num_audiodevs},
544 {SND_DEV_AUDIO, "audio", S_IWUGO | S_IRUSR | S_IRGRP,
545 &num_audiodevs},
546};
547
548static int dmabuf; 529static int dmabuf;
549static int dmabug; 530static int dmabug;
550 531
551module_param(dmabuf, int, 0444); 532module_param(dmabuf, int, 0444);
552module_param(dmabug, int, 0444); 533module_param(dmabug, int, 0444);
553 534
535/* additional minors for compatibility */
536struct oss_minor_dev {
537 unsigned short minor;
538 unsigned int enabled;
539} dev_list[] = {
540 { SND_DEV_DSP16 },
541 { SND_DEV_AUDIO },
542};
543
554static int __init oss_init(void) 544static int __init oss_init(void)
555{ 545{
556 int err; 546 int err;
@@ -571,18 +561,12 @@ static int __init oss_init(void)
571 sound_dmap_flag = (dmabuf > 0 ? 1 : 0); 561 sound_dmap_flag = (dmabuf > 0 ? 1 : 0);
572 562
573 for (i = 0; i < ARRAY_SIZE(dev_list); i++) { 563 for (i = 0; i < ARRAY_SIZE(dev_list); i++) {
574 device_create(sound_class, NULL, 564 j = 0;
575 MKDEV(SOUND_MAJOR, dev_list[i].minor), NULL, 565 do {
576 "%s", dev_list[i].name); 566 unsigned short minor = dev_list[i].minor + j * 0x10;
577 567 if (!register_sound_special(&oss_sound_fops, minor))
578 if (!dev_list[i].num) 568 dev_list[i].enabled = (1 << j);
579 continue; 569 } while (++j < num_audiodevs);
580
581 for (j = 1; j < *dev_list[i].num; j++)
582 device_create(sound_class, NULL,
583 MKDEV(SOUND_MAJOR,
584 dev_list[i].minor + (j*0x10)),
585 NULL, "%s%d", dev_list[i].name, j);
586 } 570 }
587 571
588 if (sound_nblocks >= MAX_MEM_BLOCKS - 1) 572 if (sound_nblocks >= MAX_MEM_BLOCKS - 1)
@@ -596,11 +580,11 @@ static void __exit oss_cleanup(void)
596 int i, j; 580 int i, j;
597 581
598 for (i = 0; i < ARRAY_SIZE(dev_list); i++) { 582 for (i = 0; i < ARRAY_SIZE(dev_list); i++) {
599 device_destroy(sound_class, MKDEV(SOUND_MAJOR, dev_list[i].minor)); 583 j = 0;
600 if (!dev_list[i].num) 584 do {
601 continue; 585 if (dev_list[i].enabled & (1 << j))
602 for (j = 1; j < *dev_list[i].num; j++) 586 unregister_sound_special(dev_list[i].minor);
603 device_destroy(sound_class, MKDEV(SOUND_MAJOR, dev_list[i].minor + (j*0x10))); 587 } while (++j < num_audiodevs);
604 } 588 }
605 589
606 unregister_sound_special(1); 590 unregister_sound_special(1);
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index 9823d59d7ad7..389cd7931668 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -152,10 +152,16 @@ config SND_AZT3328
152 select SND_MPU401_UART 152 select SND_MPU401_UART
153 select SND_PCM 153 select SND_PCM
154 select SND_RAWMIDI 154 select SND_RAWMIDI
155 select SND_AC97_CODEC
155 help 156 help
156 Say Y here to include support for Aztech AZF3328 (PCI168) 157 Say Y here to include support for Aztech AZF3328 (PCI168)
157 soundcards. 158 soundcards.
158 159
160 Supported features: AC97-"conformant" mixer, MPU401/OPL3, analog I/O
161 (16bit/8bit, many sample rates [<= 66.2kHz], NO hardware mixing),
162 Digital Enhanced Game Port, 1.024MHz multimedia sequencer timer,
163 ext. codec (I2S port), onboard amp (4W/4Ohms/ch), suspend/resume.
164
159 To compile this driver as a module, choose M here: the module 165 To compile this driver as a module, choose M here: the module
160 will be called snd-azt3328. 166 will be called snd-azt3328.
161 167
@@ -572,13 +578,13 @@ comment "Don't forget to add built-in firmwares for HDSP driver"
572 depends on SND_HDSP=y 578 depends on SND_HDSP=y
573 579
574config SND_HDSPM 580config SND_HDSPM
575 tristate "RME Hammerfall DSP MADI" 581 tristate "RME Hammerfall DSP MADI/RayDAT/AIO"
576 select SND_HWDEP 582 select SND_HWDEP
577 select SND_RAWMIDI 583 select SND_RAWMIDI
578 select SND_PCM 584 select SND_PCM
579 help 585 help
580 Say Y here to include support for RME Hammerfall DSP MADI 586 Say Y here to include support for RME Hammerfall DSP MADI,
581 soundcards. 587 RayDAT and AIO soundcards.
582 588
583 To compile this driver as a module, choose M here: the module 589 To compile this driver as a module, choose M here: the module
584 will be called snd-hdspm. 590 will be called snd-hdspm.
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
index cb62d178b3e0..7f4d619f4ddb 100644
--- a/sound/pci/ac97/ac97_codec.c
+++ b/sound/pci/ac97/ac97_codec.c
@@ -71,6 +71,12 @@ static const struct ac97_codec_id snd_ac97_codec_id_vendors[] = {
71{ 0x414b4d00, 0xffffff00, "Asahi Kasei", NULL, NULL }, 71{ 0x414b4d00, 0xffffff00, "Asahi Kasei", NULL, NULL },
72{ 0x414c4300, 0xffffff00, "Realtek", NULL, NULL }, 72{ 0x414c4300, 0xffffff00, "Realtek", NULL, NULL },
73{ 0x414c4700, 0xffffff00, "Realtek", NULL, NULL }, 73{ 0x414c4700, 0xffffff00, "Realtek", NULL, NULL },
74/*
75 * This is an _inofficial_ Aztech Labs entry
76 * (value might differ from unknown official Aztech ID),
77 * currently used by the AC97 emulation of the almost-AC97 PCI168 card.
78 */
79{ 0x415a5400, 0xffffff00, "Aztech Labs (emulated)", NULL, NULL },
74{ 0x434d4900, 0xffffff00, "C-Media Electronics", NULL, NULL }, 80{ 0x434d4900, 0xffffff00, "C-Media Electronics", NULL, NULL },
75{ 0x43525900, 0xffffff00, "Cirrus Logic", NULL, NULL }, 81{ 0x43525900, 0xffffff00, "Cirrus Logic", NULL, NULL },
76{ 0x43585400, 0xffffff00, "Conexant", NULL, NULL }, 82{ 0x43585400, 0xffffff00, "Conexant", NULL, NULL },
@@ -127,6 +133,7 @@ static const struct ac97_codec_id snd_ac97_codec_ids[] = {
127{ 0x414c4781, 0xffffffff, "ALC658D", NULL, NULL }, /* already patched */ 133{ 0x414c4781, 0xffffffff, "ALC658D", NULL, NULL }, /* already patched */
128{ 0x414c4780, 0xfffffff0, "ALC658", patch_alc655, NULL }, 134{ 0x414c4780, 0xfffffff0, "ALC658", patch_alc655, NULL },
129{ 0x414c4790, 0xfffffff0, "ALC850", patch_alc850, NULL }, 135{ 0x414c4790, 0xfffffff0, "ALC850", patch_alc850, NULL },
136{ 0x415a5401, 0xffffffff, "AZF3328", patch_aztech_azf3328, NULL },
130{ 0x434d4941, 0xffffffff, "CMI9738", patch_cm9738, NULL }, 137{ 0x434d4941, 0xffffffff, "CMI9738", patch_cm9738, NULL },
131{ 0x434d4961, 0xffffffff, "CMI9739", patch_cm9739, NULL }, 138{ 0x434d4961, 0xffffffff, "CMI9739", patch_cm9739, NULL },
132{ 0x434d4969, 0xffffffff, "CMI9780", patch_cm9780, NULL }, 139{ 0x434d4969, 0xffffffff, "CMI9780", patch_cm9780, NULL },
@@ -590,9 +597,9 @@ static int snd_ac97_put_volsw(struct snd_kcontrol *kcontrol,
590 snd_ac97_page_restore(ac97, page_save); 597 snd_ac97_page_restore(ac97, page_save);
591#ifdef CONFIG_SND_AC97_POWER_SAVE 598#ifdef CONFIG_SND_AC97_POWER_SAVE
592 /* check analog mixer power-down */ 599 /* check analog mixer power-down */
593 if ((val_mask & 0x8000) && 600 if ((val_mask & AC97_PD_EAPD) &&
594 (kcontrol->private_value & (1<<30))) { 601 (kcontrol->private_value & (1<<30))) {
595 if (val & 0x8000) 602 if (val & AC97_PD_EAPD)
596 ac97->power_up &= ~(1 << (reg>>1)); 603 ac97->power_up &= ~(1 << (reg>>1));
597 else 604 else
598 ac97->power_up |= 1 << (reg>>1); 605 ac97->power_up |= 1 << (reg>>1);
@@ -1035,20 +1042,20 @@ static int snd_ac97_dev_free(struct snd_device *device)
1035 1042
1036static int snd_ac97_try_volume_mix(struct snd_ac97 * ac97, int reg) 1043static int snd_ac97_try_volume_mix(struct snd_ac97 * ac97, int reg)
1037{ 1044{
1038 unsigned short val, mask = 0x8000; 1045 unsigned short val, mask = AC97_MUTE_MASK_MONO;
1039 1046
1040 if (! snd_ac97_valid_reg(ac97, reg)) 1047 if (! snd_ac97_valid_reg(ac97, reg))
1041 return 0; 1048 return 0;
1042 1049
1043 switch (reg) { 1050 switch (reg) {
1044 case AC97_MASTER_TONE: 1051 case AC97_MASTER_TONE:
1045 return ac97->caps & 0x04 ? 1 : 0; 1052 return ac97->caps & AC97_BC_BASS_TREBLE ? 1 : 0;
1046 case AC97_HEADPHONE: 1053 case AC97_HEADPHONE:
1047 return ac97->caps & 0x10 ? 1 : 0; 1054 return ac97->caps & AC97_BC_HEADPHONE ? 1 : 0;
1048 case AC97_REC_GAIN_MIC: 1055 case AC97_REC_GAIN_MIC:
1049 return ac97->caps & 0x01 ? 1 : 0; 1056 return ac97->caps & AC97_BC_DEDICATED_MIC ? 1 : 0;
1050 case AC97_3D_CONTROL: 1057 case AC97_3D_CONTROL:
1051 if (ac97->caps & 0x7c00) { 1058 if (ac97->caps & AC97_BC_3D_TECH_ID_MASK) {
1052 val = snd_ac97_read(ac97, reg); 1059 val = snd_ac97_read(ac97, reg);
1053 /* if nonzero - fixed and we can't set it */ 1060 /* if nonzero - fixed and we can't set it */
1054 return val == 0; 1061 return val == 0;
@@ -1104,7 +1111,10 @@ static void check_volume_resolution(struct snd_ac97 *ac97, int reg, unsigned cha
1104 *lo_max = *hi_max = 0; 1111 *lo_max = *hi_max = 0;
1105 for (i = 0 ; i < ARRAY_SIZE(cbit); i++) { 1112 for (i = 0 ; i < ARRAY_SIZE(cbit); i++) {
1106 unsigned short val; 1113 unsigned short val;
1107 snd_ac97_write(ac97, reg, 0x8080 | cbit[i] | (cbit[i] << 8)); 1114 snd_ac97_write(
1115 ac97, reg,
1116 AC97_MUTE_MASK_STEREO | cbit[i] | (cbit[i] << 8)
1117 );
1108 /* Do the read twice due to buffers on some ac97 codecs. 1118 /* Do the read twice due to buffers on some ac97 codecs.
1109 * e.g. The STAC9704 returns exactly what you wrote to the register 1119 * e.g. The STAC9704 returns exactly what you wrote to the register
1110 * if you read it immediately. This causes the detect routine to fail. 1120 * if you read it immediately. This causes the detect routine to fail.
@@ -1139,14 +1149,14 @@ static void snd_ac97_change_volume_params2(struct snd_ac97 * ac97, int reg, int
1139 unsigned short val, val1; 1149 unsigned short val, val1;
1140 1150
1141 *max = 63; 1151 *max = 63;
1142 val = 0x8080 | (0x20 << shift); 1152 val = AC97_MUTE_MASK_STEREO | (0x20 << shift);
1143 snd_ac97_write(ac97, reg, val); 1153 snd_ac97_write(ac97, reg, val);
1144 val1 = snd_ac97_read(ac97, reg); 1154 val1 = snd_ac97_read(ac97, reg);
1145 if (val != val1) { 1155 if (val != val1) {
1146 *max = 31; 1156 *max = 31;
1147 } 1157 }
1148 /* reset volume to zero */ 1158 /* reset volume to zero */
1149 snd_ac97_write_cache(ac97, reg, 0x8080); 1159 snd_ac97_write_cache(ac97, reg, AC97_MUTE_MASK_STEREO);
1150} 1160}
1151 1161
1152static inline int printable(unsigned int x) 1162static inline int printable(unsigned int x)
@@ -1183,16 +1193,16 @@ static int snd_ac97_cmute_new_stereo(struct snd_card *card, char *name, int reg,
1183 if (! snd_ac97_valid_reg(ac97, reg)) 1193 if (! snd_ac97_valid_reg(ac97, reg))
1184 return 0; 1194 return 0;
1185 1195
1186 mute_mask = 0x8000; 1196 mute_mask = AC97_MUTE_MASK_MONO;
1187 val = snd_ac97_read(ac97, reg); 1197 val = snd_ac97_read(ac97, reg);
1188 if (check_stereo || (ac97->flags & AC97_STEREO_MUTES)) { 1198 if (check_stereo || (ac97->flags & AC97_STEREO_MUTES)) {
1189 /* check whether both mute bits work */ 1199 /* check whether both mute bits work */
1190 val1 = val | 0x8080; 1200 val1 = val | AC97_MUTE_MASK_STEREO;
1191 snd_ac97_write(ac97, reg, val1); 1201 snd_ac97_write(ac97, reg, val1);
1192 if (val1 == snd_ac97_read(ac97, reg)) 1202 if (val1 == snd_ac97_read(ac97, reg))
1193 mute_mask = 0x8080; 1203 mute_mask = AC97_MUTE_MASK_STEREO;
1194 } 1204 }
1195 if (mute_mask == 0x8080) { 1205 if (mute_mask == AC97_MUTE_MASK_STEREO) {
1196 struct snd_kcontrol_new tmp = AC97_DOUBLE(name, reg, 15, 7, 1, 1); 1206 struct snd_kcontrol_new tmp = AC97_DOUBLE(name, reg, 15, 7, 1, 1);
1197 if (check_amix) 1207 if (check_amix)
1198 tmp.private_value |= (1 << 30); 1208 tmp.private_value |= (1 << 30);
@@ -1268,9 +1278,11 @@ static int snd_ac97_cvol_new(struct snd_card *card, char *name, int reg, unsigne
1268 err = snd_ctl_add(card, kctl); 1278 err = snd_ctl_add(card, kctl);
1269 if (err < 0) 1279 if (err < 0)
1270 return err; 1280 return err;
1271 snd_ac97_write_cache(ac97, reg, 1281 snd_ac97_write_cache(
1272 (snd_ac97_read(ac97, reg) & 0x8080) | 1282 ac97, reg,
1273 lo_max | (hi_max << 8)); 1283 (snd_ac97_read(ac97, reg) & AC97_MUTE_MASK_STEREO)
1284 | lo_max | (hi_max << 8)
1285 );
1274 return 0; 1286 return 0;
1275} 1287}
1276 1288
@@ -1332,7 +1344,7 @@ static int snd_ac97_mixer_build(struct snd_ac97 * ac97)
1332 return err; 1344 return err;
1333 } 1345 }
1334 1346
1335 ac97->regs[AC97_CENTER_LFE_MASTER] = 0x8080; 1347 ac97->regs[AC97_CENTER_LFE_MASTER] = AC97_MUTE_MASK_STEREO;
1336 1348
1337 /* build center controls */ 1349 /* build center controls */
1338 if ((snd_ac97_try_volume_mix(ac97, AC97_CENTER_LFE_MASTER)) 1350 if ((snd_ac97_try_volume_mix(ac97, AC97_CENTER_LFE_MASTER))
@@ -1410,8 +1422,12 @@ static int snd_ac97_mixer_build(struct snd_ac97 * ac97)
1410 if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_pc_beep[idx], ac97))) < 0) 1422 if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_pc_beep[idx], ac97))) < 0)
1411 return err; 1423 return err;
1412 set_tlv_db_scale(kctl, db_scale_4bit); 1424 set_tlv_db_scale(kctl, db_scale_4bit);
1413 snd_ac97_write_cache(ac97, AC97_PC_BEEP, 1425 snd_ac97_write_cache(
1414 snd_ac97_read(ac97, AC97_PC_BEEP) | 0x801e); 1426 ac97,
1427 AC97_PC_BEEP,
1428 (snd_ac97_read(ac97, AC97_PC_BEEP)
1429 | AC97_MUTE_MASK_MONO | 0x001e)
1430 );
1415 } 1431 }
1416 1432
1417 /* build Phone controls */ 1433 /* build Phone controls */
@@ -1545,7 +1561,7 @@ static int snd_ac97_mixer_build(struct snd_ac97 * ac97)
1545 } 1561 }
1546 1562
1547 /* build Simulated Stereo Enhancement control */ 1563 /* build Simulated Stereo Enhancement control */
1548 if (ac97->caps & 0x0008) { 1564 if (ac97->caps & AC97_BC_SIM_STEREO) {
1549 if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_general[AC97_GENERAL_STEREO_ENHANCEMENT], ac97))) < 0) 1565 if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_general[AC97_GENERAL_STEREO_ENHANCEMENT], ac97))) < 0)
1550 return err; 1566 return err;
1551 } 1567 }
@@ -1557,7 +1573,7 @@ static int snd_ac97_mixer_build(struct snd_ac97 * ac97)
1557 } 1573 }
1558 1574
1559 /* build Loudness control */ 1575 /* build Loudness control */
1560 if (ac97->caps & 0x0020) { 1576 if (ac97->caps & AC97_BC_LOUDNESS) {
1561 if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_general[AC97_GENERAL_LOUDNESS], ac97))) < 0) 1577 if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_general[AC97_GENERAL_LOUDNESS], ac97))) < 0)
1562 return err; 1578 return err;
1563 } 1579 }
@@ -2542,8 +2558,8 @@ void snd_ac97_resume(struct snd_ac97 *ac97)
2542 schedule_timeout_uninterruptible(1); 2558 schedule_timeout_uninterruptible(1);
2543 } while (time_after_eq(end_time, jiffies)); 2559 } while (time_after_eq(end_time, jiffies));
2544 /* FIXME: extra delay */ 2560 /* FIXME: extra delay */
2545 ac97->bus->ops->write(ac97, AC97_MASTER, 0x8000); 2561 ac97->bus->ops->write(ac97, AC97_MASTER, AC97_MUTE_MASK_MONO);
2546 if (snd_ac97_read(ac97, AC97_MASTER) != 0x8000) 2562 if (snd_ac97_read(ac97, AC97_MASTER) != AC97_MUTE_MASK_MONO)
2547 msleep(250); 2563 msleep(250);
2548 } else { 2564 } else {
2549 end_time = jiffies + msecs_to_jiffies(100); 2565 end_time = jiffies + msecs_to_jiffies(100);
@@ -2747,12 +2763,12 @@ static int master_mute_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem
2747 int rshift = (kcontrol->private_value >> 12) & 0x0f; 2763 int rshift = (kcontrol->private_value >> 12) & 0x0f;
2748 unsigned short mask; 2764 unsigned short mask;
2749 if (shift != rshift) 2765 if (shift != rshift)
2750 mask = 0x8080; 2766 mask = AC97_MUTE_MASK_STEREO;
2751 else 2767 else
2752 mask = 0x8000; 2768 mask = AC97_MUTE_MASK_MONO;
2753 snd_ac97_update_bits(ac97, AC97_POWERDOWN, 0x8000, 2769 snd_ac97_update_bits(ac97, AC97_POWERDOWN, AC97_PD_EAPD,
2754 (ac97->regs[AC97_MASTER] & mask) == mask ? 2770 (ac97->regs[AC97_MASTER] & mask) == mask ?
2755 0x8000 : 0); 2771 AC97_PD_EAPD : 0);
2756 } 2772 }
2757 return err; 2773 return err;
2758} 2774}
@@ -2765,7 +2781,10 @@ static int tune_mute_led(struct snd_ac97 *ac97)
2765 return -ENOENT; 2781 return -ENOENT;
2766 msw->put = master_mute_sw_put; 2782 msw->put = master_mute_sw_put;
2767 snd_ac97_remove_ctl(ac97, "External Amplifier", NULL); 2783 snd_ac97_remove_ctl(ac97, "External Amplifier", NULL);
2768 snd_ac97_update_bits(ac97, AC97_POWERDOWN, 0x8000, 0x8000); /* mute LED on */ 2784 snd_ac97_update_bits(
2785 ac97, AC97_POWERDOWN,
2786 AC97_PD_EAPD, AC97_PD_EAPD /* mute LED on */
2787 );
2769 ac97->scaps |= AC97_SCAP_EAPD_LED; 2788 ac97->scaps |= AC97_SCAP_EAPD_LED;
2770 return 0; 2789 return 0;
2771} 2790}
@@ -2780,12 +2799,12 @@ static int hp_master_mute_sw_put(struct snd_kcontrol *kcontrol,
2780 int rshift = (kcontrol->private_value >> 12) & 0x0f; 2799 int rshift = (kcontrol->private_value >> 12) & 0x0f;
2781 unsigned short mask; 2800 unsigned short mask;
2782 if (shift != rshift) 2801 if (shift != rshift)
2783 mask = 0x8080; 2802 mask = AC97_MUTE_MASK_STEREO;
2784 else 2803 else
2785 mask = 0x8000; 2804 mask = AC97_MUTE_MASK_MONO;
2786 snd_ac97_update_bits(ac97, AC97_POWERDOWN, 0x8000, 2805 snd_ac97_update_bits(ac97, AC97_POWERDOWN, AC97_PD_EAPD,
2787 (ac97->regs[AC97_MASTER] & mask) == mask ? 2806 (ac97->regs[AC97_MASTER] & mask) == mask ?
2788 0x8000 : 0); 2807 AC97_PD_EAPD : 0);
2789 } 2808 }
2790 return err; 2809 return err;
2791} 2810}
@@ -2801,7 +2820,10 @@ static int tune_hp_mute_led(struct snd_ac97 *ac97)
2801 snd_ac97_remove_ctl(ac97, "External Amplifier", NULL); 2820 snd_ac97_remove_ctl(ac97, "External Amplifier", NULL);
2802 snd_ac97_remove_ctl(ac97, "Headphone Playback", "Switch"); 2821 snd_ac97_remove_ctl(ac97, "Headphone Playback", "Switch");
2803 snd_ac97_remove_ctl(ac97, "Headphone Playback", "Volume"); 2822 snd_ac97_remove_ctl(ac97, "Headphone Playback", "Volume");
2804 snd_ac97_update_bits(ac97, AC97_POWERDOWN, 0x8000, 0x8000); /* mute LED on */ 2823 snd_ac97_update_bits(
2824 ac97, AC97_POWERDOWN,
2825 AC97_PD_EAPD, AC97_PD_EAPD /* mute LED on */
2826 );
2805 return 0; 2827 return 0;
2806} 2828}
2807 2829
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
index bf47574ca1f0..200c9a1d48b7 100644
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -27,6 +27,15 @@
27#include "ac97_patch.h" 27#include "ac97_patch.h"
28 28
29/* 29/*
30 * Forward declarations
31 */
32
33static struct snd_kcontrol *snd_ac97_find_mixer_ctl(struct snd_ac97 *ac97,
34 const char *name);
35static int snd_ac97_add_vmaster(struct snd_ac97 *ac97, char *name,
36 const unsigned int *tlv, const char **slaves);
37
38/*
30 * Chip specific initialization 39 * Chip specific initialization
31 */ 40 */
32 41
@@ -2940,6 +2949,49 @@ static int patch_alc850(struct snd_ac97 *ac97)
2940 return 0; 2949 return 0;
2941} 2950}
2942 2951
2952static int patch_aztech_azf3328_specific(struct snd_ac97 *ac97)
2953{
2954 struct snd_kcontrol *kctl_3d_center =
2955 snd_ac97_find_mixer_ctl(ac97, "3D Control - Center");
2956 struct snd_kcontrol *kctl_3d_depth =
2957 snd_ac97_find_mixer_ctl(ac97, "3D Control - Depth");
2958
2959 /*
2960 * 3D register is different from AC97 standard layout
2961 * (also do some renaming, to resemble Windows driver naming)
2962 */
2963 if (kctl_3d_center) {
2964 kctl_3d_center->private_value =
2965 AC97_SINGLE_VALUE(AC97_3D_CONTROL, 1, 0x07, 0);
2966 snd_ac97_rename_vol_ctl(ac97,
2967 "3D Control - Center", "3D Control - Width"
2968 );
2969 }
2970 if (kctl_3d_depth)
2971 kctl_3d_depth->private_value =
2972 AC97_SINGLE_VALUE(AC97_3D_CONTROL, 8, 0x03, 0);
2973
2974 /* Aztech Windows driver calls the
2975 equivalent control "Modem Playback", thus rename it: */
2976 snd_ac97_rename_vol_ctl(ac97,
2977 "Master Mono Playback", "Modem Playback"
2978 );
2979 snd_ac97_rename_vol_ctl(ac97,
2980 "Headphone Playback", "FM Synth Playback"
2981 );
2982
2983 return 0;
2984}
2985
2986static const struct snd_ac97_build_ops patch_aztech_azf3328_ops = {
2987 .build_specific = patch_aztech_azf3328_specific
2988};
2989
2990static int patch_aztech_azf3328(struct snd_ac97 *ac97)
2991{
2992 ac97->build_ops = &patch_aztech_azf3328_ops;
2993 return 0;
2994}
2943 2995
2944/* 2996/*
2945 * C-Media CM97xx codecs 2997 * C-Media CM97xx codecs
diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c
index c80b0b863c54..0ac1f98d91a1 100644
--- a/sound/pci/asihpi/asihpi.c
+++ b/sound/pci/asihpi/asihpi.c
@@ -21,6 +21,7 @@
21 * would appreciate it if you grant us the right to use those modifications 21 * would appreciate it if you grant us the right to use those modifications
22 * for any purpose including commercial applications. 22 * for any purpose including commercial applications.
23 */ 23 */
24
24/* >0: print Hw params, timer vars. >1: print stream write/copy sizes */ 25/* >0: print Hw params, timer vars. >1: print stream write/copy sizes */
25#define REALLY_VERBOSE_LOGGING 0 26#define REALLY_VERBOSE_LOGGING 0
26 27
@@ -36,16 +37,12 @@
36#define VPRINTK2(...) 37#define VPRINTK2(...)
37#endif 38#endif
38 39
39#ifndef ASI_STYLE_NAMES
40/* not sure how ALSA style name should look */
41#define ASI_STYLE_NAMES 1
42#endif
43
44#include "hpi_internal.h" 40#include "hpi_internal.h"
45#include "hpimsginit.h" 41#include "hpimsginit.h"
46#include "hpioctl.h" 42#include "hpioctl.h"
47 43
48#include <linux/pci.h> 44#include <linux/pci.h>
45#include <linux/version.h>
49#include <linux/init.h> 46#include <linux/init.h>
50#include <linux/jiffies.h> 47#include <linux/jiffies.h>
51#include <linux/slab.h> 48#include <linux/slab.h>
@@ -85,11 +82,11 @@ MODULE_PARM_DESC(enable_hpi_hwdep,
85 82
86/* identify driver */ 83/* identify driver */
87#ifdef KERNEL_ALSA_BUILD 84#ifdef KERNEL_ALSA_BUILD
88static char *build_info = "built using headers from kernel source"; 85static char *build_info = "Built using headers from kernel source";
89module_param(build_info, charp, S_IRUGO); 86module_param(build_info, charp, S_IRUGO);
90MODULE_PARM_DESC(build_info, "built using headers from kernel source"); 87MODULE_PARM_DESC(build_info, "built using headers from kernel source");
91#else 88#else
92static char *build_info = "built within ALSA source"; 89static char *build_info = "Built within ALSA source";
93module_param(build_info, charp, S_IRUGO); 90module_param(build_info, charp, S_IRUGO);
94MODULE_PARM_DESC(build_info, "built within ALSA source"); 91MODULE_PARM_DESC(build_info, "built within ALSA source");
95#endif 92#endif
@@ -100,13 +97,14 @@ static const int mixer_dump;
100#define DEFAULT_SAMPLERATE 44100 97#define DEFAULT_SAMPLERATE 44100
101static int adapter_fs = DEFAULT_SAMPLERATE; 98static int adapter_fs = DEFAULT_SAMPLERATE;
102 99
103static struct hpi_hsubsys *ss; /* handle to HPI audio subsystem */
104
105/* defaults */ 100/* defaults */
106#define PERIODS_MIN 2 101#define PERIODS_MIN 2
107#define PERIOD_BYTES_MIN 2304 102#define PERIOD_BYTES_MIN 2048
108#define BUFFER_BYTES_MAX (512 * 1024) 103#define BUFFER_BYTES_MAX (512 * 1024)
109 104
105/* convert stream to character */
106#define SCHR(s) ((s == SNDRV_PCM_STREAM_PLAYBACK) ? 'P' : 'C')
107
110/*#define TIMER_MILLISECONDS 20 108/*#define TIMER_MILLISECONDS 20
111#define FORCE_TIMER_JIFFIES ((TIMER_MILLISECONDS * HZ + 999)/1000) 109#define FORCE_TIMER_JIFFIES ((TIMER_MILLISECONDS * HZ + 999)/1000)
112*/ 110*/
@@ -152,11 +150,12 @@ struct snd_card_asihpi_pcm {
152 struct timer_list timer; 150 struct timer_list timer;
153 unsigned int respawn_timer; 151 unsigned int respawn_timer;
154 unsigned int hpi_buffer_attached; 152 unsigned int hpi_buffer_attached;
155 unsigned int pcm_size; 153 unsigned int buffer_bytes;
156 unsigned int pcm_count; 154 unsigned int period_bytes;
157 unsigned int bytes_per_sec; 155 unsigned int bytes_per_sec;
158 unsigned int pcm_irq_pos; /* IRQ position */ 156 unsigned int pcm_buf_host_rw_ofs; /* Host R/W pos */
159 unsigned int pcm_buf_pos; /* position in buffer */ 157 unsigned int pcm_buf_dma_ofs; /* DMA R/W offset in buffer */
158 unsigned int pcm_buf_elapsed_dma_ofs; /* DMA R/W offset in buffer */
160 struct snd_pcm_substream *substream; 159 struct snd_pcm_substream *substream;
161 u32 h_stream; 160 u32 h_stream;
162 struct hpi_format format; 161 struct hpi_format format;
@@ -167,7 +166,6 @@ struct snd_card_asihpi_pcm {
167/* Functions to allow driver to give a buffer to HPI for busmastering */ 166/* Functions to allow driver to give a buffer to HPI for busmastering */
168 167
169static u16 hpi_stream_host_buffer_attach( 168static u16 hpi_stream_host_buffer_attach(
170 struct hpi_hsubsys *hS,
171 u32 h_stream, /* handle to outstream. */ 169 u32 h_stream, /* handle to outstream. */
172 u32 size_in_bytes, /* size in bytes of bus mastering buffer */ 170 u32 size_in_bytes, /* size in bytes of bus mastering buffer */
173 u32 pci_address 171 u32 pci_address
@@ -194,10 +192,7 @@ static u16 hpi_stream_host_buffer_attach(
194 return hr.error; 192 return hr.error;
195} 193}
196 194
197static u16 hpi_stream_host_buffer_detach( 195static u16 hpi_stream_host_buffer_detach(u32 h_stream)
198 struct hpi_hsubsys *hS,
199 u32 h_stream
200)
201{ 196{
202 struct hpi_message hm; 197 struct hpi_message hm;
203 struct hpi_response hr; 198 struct hpi_response hr;
@@ -218,24 +213,23 @@ static u16 hpi_stream_host_buffer_detach(
218 return hr.error; 213 return hr.error;
219} 214}
220 215
221static inline u16 hpi_stream_start(struct hpi_hsubsys *hS, u32 h_stream) 216static inline u16 hpi_stream_start(u32 h_stream)
222{ 217{
223 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM) 218 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
224 return hpi_outstream_start(hS, h_stream); 219 return hpi_outstream_start(h_stream);
225 else 220 else
226 return hpi_instream_start(hS, h_stream); 221 return hpi_instream_start(h_stream);
227} 222}
228 223
229static inline u16 hpi_stream_stop(struct hpi_hsubsys *hS, u32 h_stream) 224static inline u16 hpi_stream_stop(u32 h_stream)
230{ 225{
231 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM) 226 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
232 return hpi_outstream_stop(hS, h_stream); 227 return hpi_outstream_stop(h_stream);
233 else 228 else
234 return hpi_instream_stop(hS, h_stream); 229 return hpi_instream_stop(h_stream);
235} 230}
236 231
237static inline u16 hpi_stream_get_info_ex( 232static inline u16 hpi_stream_get_info_ex(
238 struct hpi_hsubsys *hS,
239 u32 h_stream, 233 u32 h_stream,
240 u16 *pw_state, 234 u16 *pw_state,
241 u32 *pbuffer_size, 235 u32 *pbuffer_size,
@@ -244,42 +238,43 @@ static inline u16 hpi_stream_get_info_ex(
244 u32 *pauxiliary_data 238 u32 *pauxiliary_data
245) 239)
246{ 240{
241 u16 e;
247 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM) 242 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
248 return hpi_outstream_get_info_ex(hS, h_stream, pw_state, 243 e = hpi_outstream_get_info_ex(h_stream, pw_state,
249 pbuffer_size, pdata_in_buffer, 244 pbuffer_size, pdata_in_buffer,
250 psample_count, pauxiliary_data); 245 psample_count, pauxiliary_data);
251 else 246 else
252 return hpi_instream_get_info_ex(hS, h_stream, pw_state, 247 e = hpi_instream_get_info_ex(h_stream, pw_state,
253 pbuffer_size, pdata_in_buffer, 248 pbuffer_size, pdata_in_buffer,
254 psample_count, pauxiliary_data); 249 psample_count, pauxiliary_data);
250 return e;
255} 251}
256 252
257static inline u16 hpi_stream_group_add(struct hpi_hsubsys *hS, 253static inline u16 hpi_stream_group_add(
258 u32 h_master, 254 u32 h_master,
259 u32 h_stream) 255 u32 h_stream)
260{ 256{
261 if (hpi_handle_object(h_master) == HPI_OBJ_OSTREAM) 257 if (hpi_handle_object(h_master) == HPI_OBJ_OSTREAM)
262 return hpi_outstream_group_add(hS, h_master, h_stream); 258 return hpi_outstream_group_add(h_master, h_stream);
263 else 259 else
264 return hpi_instream_group_add(hS, h_master, h_stream); 260 return hpi_instream_group_add(h_master, h_stream);
265} 261}
266 262
267static inline u16 hpi_stream_group_reset(struct hpi_hsubsys *hS, 263static inline u16 hpi_stream_group_reset(u32 h_stream)
268 u32 h_stream)
269{ 264{
270 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM) 265 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
271 return hpi_outstream_group_reset(hS, h_stream); 266 return hpi_outstream_group_reset(h_stream);
272 else 267 else
273 return hpi_instream_group_reset(hS, h_stream); 268 return hpi_instream_group_reset(h_stream);
274} 269}
275 270
276static inline u16 hpi_stream_group_get_map(struct hpi_hsubsys *hS, 271static inline u16 hpi_stream_group_get_map(
277 u32 h_stream, u32 *mo, u32 *mi) 272 u32 h_stream, u32 *mo, u32 *mi)
278{ 273{
279 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM) 274 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
280 return hpi_outstream_group_get_map(hS, h_stream, mo, mi); 275 return hpi_outstream_group_get_map(h_stream, mo, mi);
281 else 276 else
282 return hpi_instream_group_get_map(hS, h_stream, mo, mi); 277 return hpi_instream_group_get_map(h_stream, mo, mi);
283} 278}
284 279
285static u16 handle_error(u16 err, int line, char *filename) 280static u16 handle_error(u16 err, int line, char *filename)
@@ -299,11 +294,11 @@ static void print_hwparams(struct snd_pcm_hw_params *p)
299{ 294{
300 snd_printd("HWPARAMS \n"); 295 snd_printd("HWPARAMS \n");
301 snd_printd("samplerate %d \n", params_rate(p)); 296 snd_printd("samplerate %d \n", params_rate(p));
302 snd_printd("channels %d \n", params_channels(p)); 297 snd_printd("Channels %d \n", params_channels(p));
303 snd_printd("format %d \n", params_format(p)); 298 snd_printd("Format %d \n", params_format(p));
304 snd_printd("subformat %d \n", params_subformat(p)); 299 snd_printd("subformat %d \n", params_subformat(p));
305 snd_printd("buffer bytes %d \n", params_buffer_bytes(p)); 300 snd_printd("Buffer bytes %d \n", params_buffer_bytes(p));
306 snd_printd("period bytes %d \n", params_period_bytes(p)); 301 snd_printd("Period bytes %d \n", params_period_bytes(p));
307 snd_printd("access %d \n", params_access(p)); 302 snd_printd("access %d \n", params_access(p));
308 snd_printd("period_size %d \n", params_period_size(p)); 303 snd_printd("period_size %d \n", params_period_size(p));
309 snd_printd("periods %d \n", params_periods(p)); 304 snd_printd("periods %d \n", params_periods(p));
@@ -335,7 +330,7 @@ static snd_pcm_format_t hpi_to_alsa_formats[] = {
335 */ 330 */
336 -1 331 -1
337#else 332#else
338 /* SNDRV_PCM_FORMAT_S24_3LE */ /* { HPI_FORMAT_PCM24_SIGNED 15 */ 333 /* SNDRV_PCM_FORMAT_S24_3LE */ /* HPI_FORMAT_PCM24_SIGNED 15 */
339#endif 334#endif
340}; 335};
341 336
@@ -378,20 +373,20 @@ static void snd_card_asihpi_pcm_samplerates(struct snd_card_asihpi *asihpi,
378 } else { 373 } else {
379 /* on cards without SRC, 374 /* on cards without SRC,
380 valid rates are determined by sampleclock */ 375 valid rates are determined by sampleclock */
381 err = hpi_mixer_get_control(ss, asihpi->h_mixer, 376 err = hpi_mixer_get_control(asihpi->h_mixer,
382 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0, 377 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
383 HPI_CONTROL_SAMPLECLOCK, &h_control); 378 HPI_CONTROL_SAMPLECLOCK, &h_control);
384 if (err) { 379 if (err) {
385 snd_printk(KERN_ERR 380 snd_printk(KERN_ERR
386 "no local sampleclock, err %d\n", err); 381 "No local sampleclock, err %d\n", err);
387 } 382 }
388 383
389 for (idx = 0; idx < 100; idx++) { 384 for (idx = 0; idx < 100; idx++) {
390 if (hpi_sample_clock_query_local_rate(ss, 385 if (hpi_sample_clock_query_local_rate(
391 h_control, idx, &sample_rate)) { 386 h_control, idx, &sample_rate)) {
392 if (!idx) 387 if (!idx)
393 snd_printk(KERN_ERR 388 snd_printk(KERN_ERR
394 "local rate query failed\n"); 389 "Local rate query failed\n");
395 390
396 break; 391 break;
397 } 392 }
@@ -480,10 +475,10 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream,
480 format, params_rate(params), 0, 0)); 475 format, params_rate(params), 0, 0));
481 476
482 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { 477 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
483 if (hpi_instream_reset(ss, dpcm->h_stream) != 0) 478 if (hpi_instream_reset(dpcm->h_stream) != 0)
484 return -EINVAL; 479 return -EINVAL;
485 480
486 if (hpi_instream_set_format(ss, 481 if (hpi_instream_set_format(
487 dpcm->h_stream, &dpcm->format) != 0) 482 dpcm->h_stream, &dpcm->format) != 0)
488 return -EINVAL; 483 return -EINVAL;
489 } 484 }
@@ -491,10 +486,10 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream,
491 dpcm->hpi_buffer_attached = 0; 486 dpcm->hpi_buffer_attached = 0;
492 if (card->support_mmap) { 487 if (card->support_mmap) {
493 488
494 err = hpi_stream_host_buffer_attach(ss, dpcm->h_stream, 489 err = hpi_stream_host_buffer_attach(dpcm->h_stream,
495 params_buffer_bytes(params), runtime->dma_addr); 490 params_buffer_bytes(params), runtime->dma_addr);
496 if (err == 0) { 491 if (err == 0) {
497 snd_printd(KERN_INFO 492 VPRINTK1(KERN_INFO
498 "stream_host_buffer_attach succeeded %u %lu\n", 493 "stream_host_buffer_attach succeeded %u %lu\n",
499 params_buffer_bytes(params), 494 params_buffer_bytes(params),
500 (unsigned long)runtime->dma_addr); 495 (unsigned long)runtime->dma_addr);
@@ -505,11 +500,11 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream,
505 return -ENOMEM; 500 return -ENOMEM;
506 } 501 }
507 502
508 err = hpi_stream_get_info_ex(ss, dpcm->h_stream, NULL, 503 err = hpi_stream_get_info_ex(dpcm->h_stream, NULL,
509 &dpcm->hpi_buffer_attached, 504 &dpcm->hpi_buffer_attached,
510 NULL, NULL, NULL); 505 NULL, NULL, NULL);
511 506
512 snd_printd(KERN_INFO "stream_host_buffer_attach status 0x%x\n", 507 VPRINTK1(KERN_INFO "stream_host_buffer_attach status 0x%x\n",
513 dpcm->hpi_buffer_attached); 508 dpcm->hpi_buffer_attached);
514 } 509 }
515 bytes_per_sec = params_rate(params) * params_channels(params); 510 bytes_per_sec = params_rate(params) * params_channels(params);
@@ -520,16 +515,32 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream,
520 return -EINVAL; 515 return -EINVAL;
521 516
522 dpcm->bytes_per_sec = bytes_per_sec; 517 dpcm->bytes_per_sec = bytes_per_sec;
523 dpcm->pcm_size = params_buffer_bytes(params); 518 dpcm->buffer_bytes = params_buffer_bytes(params);
524 dpcm->pcm_count = params_period_bytes(params); 519 dpcm->period_bytes = params_period_bytes(params);
525 snd_printd(KERN_INFO "pcm_size=%d, pcm_count=%d, bps=%d\n", 520 VPRINTK1(KERN_INFO "buffer_bytes=%d, period_bytes=%d, bps=%d\n",
526 dpcm->pcm_size, dpcm->pcm_count, bytes_per_sec); 521 dpcm->buffer_bytes, dpcm->period_bytes, bytes_per_sec);
527 522
528 dpcm->pcm_irq_pos = 0;
529 dpcm->pcm_buf_pos = 0;
530 return 0; 523 return 0;
531} 524}
532 525
526static int
527snd_card_asihpi_hw_free(struct snd_pcm_substream *substream)
528{
529 struct snd_pcm_runtime *runtime = substream->runtime;
530 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
531 if (dpcm->hpi_buffer_attached)
532 hpi_stream_host_buffer_detach(dpcm->h_stream);
533
534 snd_pcm_lib_free_pages(substream);
535 return 0;
536}
537
538static void snd_card_asihpi_runtime_free(struct snd_pcm_runtime *runtime)
539{
540 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
541 kfree(dpcm);
542}
543
533static void snd_card_asihpi_pcm_timer_start(struct snd_pcm_substream * 544static void snd_card_asihpi_pcm_timer_start(struct snd_pcm_substream *
534 substream) 545 substream)
535{ 546{
@@ -537,9 +548,9 @@ static void snd_card_asihpi_pcm_timer_start(struct snd_pcm_substream *
537 struct snd_card_asihpi_pcm *dpcm = runtime->private_data; 548 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
538 int expiry; 549 int expiry;
539 550
540 expiry = (dpcm->pcm_count * HZ / dpcm->bytes_per_sec); 551 expiry = HZ / 200;
541 /* wait longer the first time, for samples to propagate */ 552 /*? (dpcm->period_bytes * HZ / dpcm->bytes_per_sec); */
542 expiry = max(expiry, 20); 553 expiry = max(expiry, 1); /* don't let it be zero! */
543 dpcm->timer.expires = jiffies + expiry; 554 dpcm->timer.expires = jiffies + expiry;
544 dpcm->respawn_timer = 1; 555 dpcm->respawn_timer = 1;
545 add_timer(&dpcm->timer); 556 add_timer(&dpcm->timer);
@@ -562,37 +573,44 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,
562 struct snd_pcm_substream *s; 573 struct snd_pcm_substream *s;
563 u16 e; 574 u16 e;
564 575
565 snd_printd("trigger %dstream %d\n", 576 VPRINTK1(KERN_INFO "%c%d trigger\n",
566 substream->stream, substream->number); 577 SCHR(substream->stream), substream->number);
567 switch (cmd) { 578 switch (cmd) {
568 case SNDRV_PCM_TRIGGER_START: 579 case SNDRV_PCM_TRIGGER_START:
569 snd_pcm_group_for_each_entry(s, substream) { 580 snd_pcm_group_for_each_entry(s, substream) {
570 struct snd_card_asihpi_pcm *ds; 581 struct snd_pcm_runtime *runtime = s->runtime;
571 ds = s->runtime->private_data; 582 struct snd_card_asihpi_pcm *ds = runtime->private_data;
572 583
573 if (snd_pcm_substream_chip(s) != card) 584 if (snd_pcm_substream_chip(s) != card)
574 continue; 585 continue;
575 586
587 /* don't link Cap and Play */
588 if (substream->stream != s->stream)
589 continue;
590
576 if ((s->stream == SNDRV_PCM_STREAM_PLAYBACK) && 591 if ((s->stream == SNDRV_PCM_STREAM_PLAYBACK) &&
577 (card->support_mmap)) { 592 (card->support_mmap)) {
578 /* How do I know how much valid data is present 593 /* How do I know how much valid data is present
579 * in buffer? Just guessing 2 periods, but if 594 * in buffer? Must be at least one period!
595 * Guessing 2 periods, but if
580 * buffer is bigger it may contain even more 596 * buffer is bigger it may contain even more
581 * data?? 597 * data??
582 */ 598 */
583 unsigned int preload = ds->pcm_count * 2; 599 unsigned int preload = ds->period_bytes * 1;
584 VPRINTK2("preload %d\n", preload); 600 VPRINTK2(KERN_INFO "%d preload x%x\n", s->number, preload);
585 hpi_handle_error(hpi_outstream_write_buf( 601 hpi_handle_error(hpi_outstream_write_buf(
586 ss, ds->h_stream, 602 ds->h_stream,
587 &s->runtime->dma_area[0], 603 &runtime->dma_area[0],
588 preload, 604 preload,
589 &ds->format)); 605 &ds->format));
606 ds->pcm_buf_host_rw_ofs = preload;
590 } 607 }
591 608
592 if (card->support_grouping) { 609 if (card->support_grouping) {
593 VPRINTK1("\t_group %dstream %d\n", s->stream, 610 VPRINTK1(KERN_INFO "\t%c%d group\n",
611 SCHR(s->stream),
594 s->number); 612 s->number);
595 e = hpi_stream_group_add(ss, 613 e = hpi_stream_group_add(
596 dpcm->h_stream, 614 dpcm->h_stream,
597 ds->h_stream); 615 ds->h_stream);
598 if (!e) { 616 if (!e) {
@@ -604,10 +622,12 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,
604 } else 622 } else
605 break; 623 break;
606 } 624 }
607 snd_printd("start\n"); 625 VPRINTK1(KERN_INFO "start\n");
608 /* start the master stream */ 626 /* start the master stream */
609 snd_card_asihpi_pcm_timer_start(substream); 627 snd_card_asihpi_pcm_timer_start(substream);
610 hpi_handle_error(hpi_stream_start(ss, dpcm->h_stream)); 628 if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE) ||
629 !card->support_mmap)
630 hpi_handle_error(hpi_stream_start(dpcm->h_stream));
611 break; 631 break;
612 632
613 case SNDRV_PCM_TRIGGER_STOP: 633 case SNDRV_PCM_TRIGGER_STOP:
@@ -615,88 +635,73 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,
615 snd_pcm_group_for_each_entry(s, substream) { 635 snd_pcm_group_for_each_entry(s, substream) {
616 if (snd_pcm_substream_chip(s) != card) 636 if (snd_pcm_substream_chip(s) != card)
617 continue; 637 continue;
638 /* don't link Cap and Play */
639 if (substream->stream != s->stream)
640 continue;
618 641
619 /*? workaround linked streams don't 642 /*? workaround linked streams don't
620 transition to SETUP 20070706*/ 643 transition to SETUP 20070706*/
621 s->runtime->status->state = SNDRV_PCM_STATE_SETUP; 644 s->runtime->status->state = SNDRV_PCM_STATE_SETUP;
622 645
623 if (card->support_grouping) { 646 if (card->support_grouping) {
624 VPRINTK1("\t_group %dstream %d\n", s->stream, 647 VPRINTK1(KERN_INFO "\t%c%d group\n",
648 SCHR(s->stream),
625 s->number); 649 s->number);
626 snd_pcm_trigger_done(s, substream); 650 snd_pcm_trigger_done(s, substream);
627 } else 651 } else
628 break; 652 break;
629 } 653 }
630 snd_printd("stop\n"); 654 VPRINTK1(KERN_INFO "stop\n");
631 655
632 /* _prepare and _hwparams reset the stream */ 656 /* _prepare and _hwparams reset the stream */
633 hpi_handle_error(hpi_stream_stop(ss, dpcm->h_stream)); 657 hpi_handle_error(hpi_stream_stop(dpcm->h_stream));
634 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 658 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
635 hpi_handle_error( 659 hpi_handle_error(
636 hpi_outstream_reset(ss, dpcm->h_stream)); 660 hpi_outstream_reset(dpcm->h_stream));
637 661
638 if (card->support_grouping) 662 if (card->support_grouping)
639 hpi_handle_error(hpi_stream_group_reset(ss, 663 hpi_handle_error(hpi_stream_group_reset(dpcm->h_stream));
640 dpcm->h_stream));
641 break; 664 break;
642 665
643 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 666 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
644 snd_printd("pause release\n"); 667 VPRINTK1(KERN_INFO "pause release\n");
645 hpi_handle_error(hpi_stream_start(ss, dpcm->h_stream)); 668 hpi_handle_error(hpi_stream_start(dpcm->h_stream));
646 snd_card_asihpi_pcm_timer_start(substream); 669 snd_card_asihpi_pcm_timer_start(substream);
647 break; 670 break;
648 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 671 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
649 snd_printd("pause\n"); 672 VPRINTK1(KERN_INFO "pause\n");
650 snd_card_asihpi_pcm_timer_stop(substream); 673 snd_card_asihpi_pcm_timer_stop(substream);
651 hpi_handle_error(hpi_stream_stop(ss, dpcm->h_stream)); 674 hpi_handle_error(hpi_stream_stop(dpcm->h_stream));
652 break; 675 break;
653 default: 676 default:
654 snd_printd("\tINVALID\n"); 677 snd_printd(KERN_ERR "\tINVALID\n");
655 return -EINVAL; 678 return -EINVAL;
656 } 679 }
657 680
658 return 0; 681 return 0;
659} 682}
660 683
661static int
662snd_card_asihpi_hw_free(struct snd_pcm_substream *substream)
663{
664 struct snd_pcm_runtime *runtime = substream->runtime;
665 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
666 if (dpcm->hpi_buffer_attached)
667 hpi_stream_host_buffer_detach(ss, dpcm->h_stream);
668
669 snd_pcm_lib_free_pages(substream);
670 return 0;
671}
672
673static void snd_card_asihpi_runtime_free(struct snd_pcm_runtime *runtime)
674{
675 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
676 kfree(dpcm);
677}
678
679/*algorithm outline 684/*algorithm outline
680 Without linking degenerates to getting single stream pos etc 685 Without linking degenerates to getting single stream pos etc
681 Without mmap 2nd loop degenerates to snd_pcm_period_elapsed 686 Without mmap 2nd loop degenerates to snd_pcm_period_elapsed
682*/ 687*/
683/* 688/*
684buf_pos=get_buf_pos(s); 689pcm_buf_dma_ofs=get_buf_pos(s);
685for_each_linked_stream(s) { 690for_each_linked_stream(s) {
686 buf_pos=get_buf_pos(s); 691 pcm_buf_dma_ofs=get_buf_pos(s);
687 min_buf_pos = modulo_min(min_buf_pos, buf_pos, pcm_size) 692 min_buf_pos = modulo_min(min_buf_pos, pcm_buf_dma_ofs, buffer_bytes)
688 new_data = min(new_data, calc_new_data(buf_pos,irq_pos) 693 new_data = min(new_data, calc_new_data(pcm_buf_dma_ofs,irq_pos)
689} 694}
690timer.expires = jiffies + predict_next_period_ready(min_buf_pos); 695timer.expires = jiffies + predict_next_period_ready(min_buf_pos);
691for_each_linked_stream(s) { 696for_each_linked_stream(s) {
692 s->buf_pos = min_buf_pos; 697 s->pcm_buf_dma_ofs = min_buf_pos;
693 if (new_data > pcm_count) { 698 if (new_data > period_bytes) {
694 if (mmap) { 699 if (mmap) {
695 irq_pos = (irq_pos + pcm_count) % pcm_size; 700 irq_pos = (irq_pos + period_bytes) % buffer_bytes;
696 if (playback) { 701 if (playback) {
697 write(pcm_count); 702 write(period_bytes);
698 } else { 703 } else {
699 read(pcm_count); 704 read(period_bytes);
700 } 705 }
701 } 706 }
702 snd_pcm_period_elapsed(s); 707 snd_pcm_period_elapsed(s);
@@ -724,105 +729,136 @@ static inline unsigned int modulo_min(unsigned int a, unsigned int b,
724static void snd_card_asihpi_timer_function(unsigned long data) 729static void snd_card_asihpi_timer_function(unsigned long data)
725{ 730{
726 struct snd_card_asihpi_pcm *dpcm = (struct snd_card_asihpi_pcm *)data; 731 struct snd_card_asihpi_pcm *dpcm = (struct snd_card_asihpi_pcm *)data;
727 struct snd_card_asihpi *card = snd_pcm_substream_chip(dpcm->substream); 732 struct snd_pcm_substream *substream = dpcm->substream;
733 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
728 struct snd_pcm_runtime *runtime; 734 struct snd_pcm_runtime *runtime;
729 struct snd_pcm_substream *s; 735 struct snd_pcm_substream *s;
730 unsigned int newdata = 0; 736 unsigned int newdata = 0;
731 unsigned int buf_pos, min_buf_pos = 0; 737 unsigned int pcm_buf_dma_ofs, min_buf_pos = 0;
732 unsigned int remdata, xfercount, next_jiffies; 738 unsigned int remdata, xfercount, next_jiffies;
733 int first = 1; 739 int first = 1;
740 int loops = 0;
734 u16 state; 741 u16 state;
735 u32 buffer_size, data_avail, samples_played, aux; 742 u32 buffer_size, bytes_avail, samples_played, on_card_bytes;
743
744 VPRINTK1(KERN_INFO "%c%d snd_card_asihpi_timer_function\n",
745 SCHR(substream->stream), substream->number);
736 746
737 /* find minimum newdata and buffer pos in group */ 747 /* find minimum newdata and buffer pos in group */
738 snd_pcm_group_for_each_entry(s, dpcm->substream) { 748 snd_pcm_group_for_each_entry(s, substream) {
739 struct snd_card_asihpi_pcm *ds = s->runtime->private_data; 749 struct snd_card_asihpi_pcm *ds = s->runtime->private_data;
740 runtime = s->runtime; 750 runtime = s->runtime;
741 751
742 if (snd_pcm_substream_chip(s) != card) 752 if (snd_pcm_substream_chip(s) != card)
743 continue; 753 continue;
744 754
745 hpi_handle_error(hpi_stream_get_info_ex(ss, 755 /* don't link Cap and Play */
756 if (substream->stream != s->stream)
757 continue;
758
759 hpi_handle_error(hpi_stream_get_info_ex(
746 ds->h_stream, &state, 760 ds->h_stream, &state,
747 &buffer_size, &data_avail, 761 &buffer_size, &bytes_avail,
748 &samples_played, &aux)); 762 &samples_played, &on_card_bytes));
749 763
750 /* number of bytes in on-card buffer */ 764 /* number of bytes in on-card buffer */
751 runtime->delay = aux; 765 runtime->delay = on_card_bytes;
752
753 if (state == HPI_STATE_DRAINED) {
754 snd_printd(KERN_WARNING "outstream %d drained\n",
755 s->number);
756 snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN);
757 return;
758 }
759 766
760 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) { 767 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
761 buf_pos = frames_to_bytes(runtime, samples_played); 768 pcm_buf_dma_ofs = ds->pcm_buf_host_rw_ofs - bytes_avail;
762 } else { 769 if (state == HPI_STATE_STOPPED) {
763 buf_pos = data_avail + ds->pcm_irq_pos; 770 if ((bytes_avail == 0) &&
764 } 771 (on_card_bytes < ds->pcm_buf_host_rw_ofs)) {
772 hpi_handle_error(hpi_stream_start(ds->h_stream));
773 VPRINTK1(KERN_INFO "P%d start\n", s->number);
774 }
775 } else if (state == HPI_STATE_DRAINED) {
776 VPRINTK1(KERN_WARNING "P%d drained\n",
777 s->number);
778 /*snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN);
779 continue; */
780 }
781 } else
782 pcm_buf_dma_ofs = bytes_avail + ds->pcm_buf_host_rw_ofs;
765 783
766 if (first) { 784 if (first) {
767 /* can't statically init min when wrap is involved */ 785 /* can't statically init min when wrap is involved */
768 min_buf_pos = buf_pos; 786 min_buf_pos = pcm_buf_dma_ofs;
769 newdata = (buf_pos - ds->pcm_irq_pos) % ds->pcm_size; 787 newdata = (pcm_buf_dma_ofs - ds->pcm_buf_elapsed_dma_ofs) % ds->buffer_bytes;
770 first = 0; 788 first = 0;
771 } else { 789 } else {
772 min_buf_pos = 790 min_buf_pos =
773 modulo_min(min_buf_pos, buf_pos, UINT_MAX+1L); 791 modulo_min(min_buf_pos, pcm_buf_dma_ofs, UINT_MAX+1L);
774 newdata = min( 792 newdata = min(
775 (buf_pos - ds->pcm_irq_pos) % ds->pcm_size, 793 (pcm_buf_dma_ofs - ds->pcm_buf_elapsed_dma_ofs) % ds->buffer_bytes,
776 newdata); 794 newdata);
777 } 795 }
778 796
779 VPRINTK1("PB timer hw_ptr x%04lX, appl_ptr x%04lX\n", 797 VPRINTK1(KERN_INFO "PB timer hw_ptr x%04lX, appl_ptr x%04lX\n",
780 (unsigned long)frames_to_bytes(runtime, 798 (unsigned long)frames_to_bytes(runtime,
781 runtime->status->hw_ptr), 799 runtime->status->hw_ptr),
782 (unsigned long)frames_to_bytes(runtime, 800 (unsigned long)frames_to_bytes(runtime,
783 runtime->control->appl_ptr)); 801 runtime->control->appl_ptr));
784 VPRINTK1("%d S=%d, irq=%04X, pos=x%04X, left=x%04X," 802
785 " aux=x%04X space=x%04X\n", s->number, 803 VPRINTK1(KERN_INFO "%d %c%d S=%d, rw=%04X, dma=x%04X, left=x%04X,"
786 state, ds->pcm_irq_pos, buf_pos, (int)data_avail, 804 " aux=x%04X space=x%04X\n",
787 (int)aux, buffer_size-data_avail); 805 loops, SCHR(s->stream), s->number,
806 state, ds->pcm_buf_host_rw_ofs, pcm_buf_dma_ofs, (int)bytes_avail,
807 (int)on_card_bytes, buffer_size-bytes_avail);
808 loops++;
788 } 809 }
810 pcm_buf_dma_ofs = min_buf_pos;
789 811
790 remdata = newdata % dpcm->pcm_count; 812 remdata = newdata % dpcm->period_bytes;
791 xfercount = newdata - remdata; /* a multiple of pcm_count */ 813 xfercount = newdata - remdata; /* a multiple of period_bytes */
792 next_jiffies = ((dpcm->pcm_count-remdata) * HZ / dpcm->bytes_per_sec)+1; 814 /* come back when on_card_bytes has decreased enough to allow
793 next_jiffies = max(next_jiffies, 2U * HZ / 1000U); 815 write to happen, or when data has been consumed to make another
816 period
817 */
818 if (xfercount && (on_card_bytes > dpcm->period_bytes))
819 next_jiffies = ((on_card_bytes - dpcm->period_bytes) * HZ / dpcm->bytes_per_sec);
820 else
821 next_jiffies = ((dpcm->period_bytes - remdata) * HZ / dpcm->bytes_per_sec);
822
823 next_jiffies = max(next_jiffies, 1U);
794 dpcm->timer.expires = jiffies + next_jiffies; 824 dpcm->timer.expires = jiffies + next_jiffies;
795 VPRINTK1("jif %d buf pos x%04X newdata x%04X xc x%04X\n", 825 VPRINTK1(KERN_INFO "jif %d buf pos x%04X newdata x%04X xfer x%04X\n",
796 next_jiffies, min_buf_pos, newdata, xfercount); 826 next_jiffies, pcm_buf_dma_ofs, newdata, xfercount);
797 827
798 snd_pcm_group_for_each_entry(s, dpcm->substream) { 828 snd_pcm_group_for_each_entry(s, substream) {
799 struct snd_card_asihpi_pcm *ds = s->runtime->private_data; 829 struct snd_card_asihpi_pcm *ds = s->runtime->private_data;
800 ds->pcm_buf_pos = min_buf_pos;
801 830
802 if (xfercount) { 831 /* don't link Cap and Play */
832 if (substream->stream != s->stream)
833 continue;
834
835 ds->pcm_buf_dma_ofs = pcm_buf_dma_ofs;
836
837 if (xfercount && (on_card_bytes <= ds->period_bytes)) {
803 if (card->support_mmap) { 838 if (card->support_mmap) {
804 ds->pcm_irq_pos = ds->pcm_irq_pos + xfercount;
805 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) { 839 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
806 VPRINTK2("write OS%d x%04x\n", 840 VPRINTK2(KERN_INFO "P%d write x%04x\n",
807 s->number, 841 s->number,
808 ds->pcm_count); 842 ds->period_bytes);
809 hpi_handle_error( 843 hpi_handle_error(
810 hpi_outstream_write_buf( 844 hpi_outstream_write_buf(
811 ss, ds->h_stream, 845 ds->h_stream,
812 &s->runtime-> 846 &s->runtime->
813 dma_area[0], 847 dma_area[0],
814 xfercount, 848 xfercount,
815 &ds->format)); 849 &ds->format));
816 } else { 850 } else {
817 VPRINTK2("read IS%d x%04x\n", 851 VPRINTK2(KERN_INFO "C%d read x%04x\n",
818 s->number, 852 s->number,
819 dpcm->pcm_count); 853 xfercount);
820 hpi_handle_error( 854 hpi_handle_error(
821 hpi_instream_read_buf( 855 hpi_instream_read_buf(
822 ss, ds->h_stream, 856 ds->h_stream,
823 NULL, xfercount)); 857 NULL, xfercount));
824 } 858 }
859 ds->pcm_buf_host_rw_ofs = ds->pcm_buf_host_rw_ofs + xfercount;
825 } /* else R/W will be handled by read/write callbacks */ 860 } /* else R/W will be handled by read/write callbacks */
861 ds->pcm_buf_elapsed_dma_ofs = pcm_buf_dma_ofs;
826 snd_pcm_period_elapsed(s); 862 snd_pcm_period_elapsed(s);
827 } 863 }
828 } 864 }
@@ -845,12 +881,12 @@ static int snd_card_asihpi_playback_prepare(struct snd_pcm_substream *
845 struct snd_pcm_runtime *runtime = substream->runtime; 881 struct snd_pcm_runtime *runtime = substream->runtime;
846 struct snd_card_asihpi_pcm *dpcm = runtime->private_data; 882 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
847 883
848 snd_printd(KERN_INFO "playback prepare %d\n", substream->number); 884 VPRINTK1(KERN_INFO "playback prepare %d\n", substream->number);
849
850 hpi_handle_error(hpi_outstream_reset(ss, dpcm->h_stream));
851 dpcm->pcm_irq_pos = 0;
852 dpcm->pcm_buf_pos = 0;
853 885
886 hpi_handle_error(hpi_outstream_reset(dpcm->h_stream));
887 dpcm->pcm_buf_host_rw_ofs = 0;
888 dpcm->pcm_buf_dma_ofs = 0;
889 dpcm->pcm_buf_elapsed_dma_ofs = 0;
854 return 0; 890 return 0;
855} 891}
856 892
@@ -861,27 +897,8 @@ snd_card_asihpi_playback_pointer(struct snd_pcm_substream *substream)
861 struct snd_card_asihpi_pcm *dpcm = runtime->private_data; 897 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
862 snd_pcm_uframes_t ptr; 898 snd_pcm_uframes_t ptr;
863 899
864 u32 samples_played; 900 ptr = bytes_to_frames(runtime, dpcm->pcm_buf_dma_ofs % dpcm->buffer_bytes);
865 u16 err; 901 /* VPRINTK2(KERN_INFO "playback_pointer=x%04lx\n", (unsigned long)ptr); */
866
867 if (!snd_pcm_stream_linked(substream)) {
868 /* NOTE, can use samples played for playback position here and
869 * in timer fn because it LAGS the actual read pointer, and is a
870 * better representation of actual playout position
871 */
872 err = hpi_outstream_get_info_ex(ss, dpcm->h_stream, NULL,
873 NULL, NULL,
874 &samples_played, NULL);
875 hpi_handle_error(err);
876
877 dpcm->pcm_buf_pos = frames_to_bytes(runtime, samples_played);
878 }
879 /* else must return most conservative value found in timer func
880 * by looping over all streams
881 */
882
883 ptr = bytes_to_frames(runtime, dpcm->pcm_buf_pos % dpcm->pcm_size);
884 VPRINTK2("playback_pointer=%04ld\n", (unsigned long)ptr);
885 return ptr; 902 return ptr;
886} 903}
887 904
@@ -898,12 +915,12 @@ static void snd_card_asihpi_playback_format(struct snd_card_asihpi *asihpi,
898 /* on cards without SRC, must query at valid rate, 915 /* on cards without SRC, must query at valid rate,
899 * maybe set by external sync 916 * maybe set by external sync
900 */ 917 */
901 err = hpi_mixer_get_control(ss, asihpi->h_mixer, 918 err = hpi_mixer_get_control(asihpi->h_mixer,
902 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0, 919 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
903 HPI_CONTROL_SAMPLECLOCK, &h_control); 920 HPI_CONTROL_SAMPLECLOCK, &h_control);
904 921
905 if (!err) 922 if (!err)
906 err = hpi_sample_clock_get_sample_rate(ss, h_control, 923 err = hpi_sample_clock_get_sample_rate(h_control,
907 &sample_rate); 924 &sample_rate);
908 925
909 for (format = HPI_FORMAT_PCM8_UNSIGNED; 926 for (format = HPI_FORMAT_PCM8_UNSIGNED;
@@ -911,7 +928,7 @@ static void snd_card_asihpi_playback_format(struct snd_card_asihpi *asihpi,
911 err = hpi_format_create(&hpi_format, 928 err = hpi_format_create(&hpi_format,
912 2, format, sample_rate, 128000, 0); 929 2, format, sample_rate, 128000, 0);
913 if (!err) 930 if (!err)
914 err = hpi_outstream_query_format(ss, h_stream, 931 err = hpi_outstream_query_format(h_stream,
915 &hpi_format); 932 &hpi_format);
916 if (!err && (hpi_to_alsa_formats[format] != -1)) 933 if (!err && (hpi_to_alsa_formats[format] != -1))
917 pcmhw->formats |= 934 pcmhw->formats |=
@@ -942,7 +959,7 @@ static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream)
942 return -ENOMEM; 959 return -ENOMEM;
943 960
944 err = 961 err =
945 hpi_outstream_open(ss, card->adapter_index, 962 hpi_outstream_open(card->adapter_index,
946 substream->number, &dpcm->h_stream); 963 substream->number, &dpcm->h_stream);
947 hpi_handle_error(err); 964 hpi_handle_error(err);
948 if (err) 965 if (err)
@@ -998,11 +1015,11 @@ static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream)
998 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 1015 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
999 card->update_interval_frames); 1016 card->update_interval_frames);
1000 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 1017 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
1001 card->update_interval_frames * 4, UINT_MAX); 1018 card->update_interval_frames * 2, UINT_MAX);
1002 1019
1003 snd_pcm_set_sync(substream); 1020 snd_pcm_set_sync(substream);
1004 1021
1005 snd_printd(KERN_INFO "playback open\n"); 1022 VPRINTK1(KERN_INFO "playback open\n");
1006 1023
1007 return 0; 1024 return 0;
1008} 1025}
@@ -1012,8 +1029,8 @@ static int snd_card_asihpi_playback_close(struct snd_pcm_substream *substream)
1012 struct snd_pcm_runtime *runtime = substream->runtime; 1029 struct snd_pcm_runtime *runtime = substream->runtime;
1013 struct snd_card_asihpi_pcm *dpcm = runtime->private_data; 1030 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1014 1031
1015 hpi_handle_error(hpi_outstream_close(ss, dpcm->h_stream)); 1032 hpi_handle_error(hpi_outstream_close(dpcm->h_stream));
1016 snd_printd(KERN_INFO "playback close\n"); 1033 VPRINTK1(KERN_INFO "playback close\n");
1017 1034
1018 return 0; 1035 return 0;
1019} 1036}
@@ -1036,9 +1053,11 @@ static int snd_card_asihpi_playback_copy(struct snd_pcm_substream *substream,
1036 VPRINTK2(KERN_DEBUG "playback copy%d %u bytes\n", 1053 VPRINTK2(KERN_DEBUG "playback copy%d %u bytes\n",
1037 substream->number, len); 1054 substream->number, len);
1038 1055
1039 hpi_handle_error(hpi_outstream_write_buf(ss, dpcm->h_stream, 1056 hpi_handle_error(hpi_outstream_write_buf(dpcm->h_stream,
1040 runtime->dma_area, len, &dpcm->format)); 1057 runtime->dma_area, len, &dpcm->format));
1041 1058
1059 dpcm->pcm_buf_host_rw_ofs = dpcm->pcm_buf_host_rw_ofs + len;
1060
1042 return 0; 1061 return 0;
1043} 1062}
1044 1063
@@ -1052,10 +1071,10 @@ static int snd_card_asihpi_playback_silence(struct snd_pcm_substream *
1052 struct snd_card_asihpi_pcm *dpcm = runtime->private_data; 1071 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1053 1072
1054 len = frames_to_bytes(runtime, count); 1073 len = frames_to_bytes(runtime, count);
1055 snd_printd(KERN_INFO "playback silence %u bytes\n", len); 1074 VPRINTK1(KERN_INFO "playback silence %u bytes\n", len);
1056 1075
1057 memset(runtime->dma_area, 0, len); 1076 memset(runtime->dma_area, 0, len);
1058 hpi_handle_error(hpi_outstream_write_buf(ss, dpcm->h_stream, 1077 hpi_handle_error(hpi_outstream_write_buf(dpcm->h_stream,
1059 runtime->dma_area, len, &dpcm->format)); 1078 runtime->dma_area, len, &dpcm->format));
1060 return 0; 1079 return 0;
1061} 1080}
@@ -1091,13 +1110,13 @@ snd_card_asihpi_capture_pointer(struct snd_pcm_substream *substream)
1091 struct snd_pcm_runtime *runtime = substream->runtime; 1110 struct snd_pcm_runtime *runtime = substream->runtime;
1092 struct snd_card_asihpi_pcm *dpcm = runtime->private_data; 1111 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1093 1112
1094 VPRINTK2("capture pointer %d=%d\n", 1113 VPRINTK2(KERN_INFO "capture pointer %d=%d\n",
1095 substream->number, dpcm->pcm_buf_pos); 1114 substream->number, dpcm->pcm_buf_dma_ofs);
1096 /* NOTE Unlike playback can't use actual dwSamplesPlayed 1115 /* NOTE Unlike playback can't use actual samples_played
1097 for the capture position, because those samples aren't yet in 1116 for the capture position, because those samples aren't yet in
1098 the local buffer available for reading. 1117 the local buffer available for reading.
1099 */ 1118 */
1100 return bytes_to_frames(runtime, dpcm->pcm_buf_pos % dpcm->pcm_size); 1119 return bytes_to_frames(runtime, dpcm->pcm_buf_dma_ofs % dpcm->buffer_bytes);
1101} 1120}
1102 1121
1103static int snd_card_asihpi_capture_ioctl(struct snd_pcm_substream *substream, 1122static int snd_card_asihpi_capture_ioctl(struct snd_pcm_substream *substream,
@@ -1111,11 +1130,12 @@ static int snd_card_asihpi_capture_prepare(struct snd_pcm_substream *substream)
1111 struct snd_pcm_runtime *runtime = substream->runtime; 1130 struct snd_pcm_runtime *runtime = substream->runtime;
1112 struct snd_card_asihpi_pcm *dpcm = runtime->private_data; 1131 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1113 1132
1114 hpi_handle_error(hpi_instream_reset(ss, dpcm->h_stream)); 1133 hpi_handle_error(hpi_instream_reset(dpcm->h_stream));
1115 dpcm->pcm_irq_pos = 0; 1134 dpcm->pcm_buf_host_rw_ofs = 0;
1116 dpcm->pcm_buf_pos = 0; 1135 dpcm->pcm_buf_dma_ofs = 0;
1136 dpcm->pcm_buf_elapsed_dma_ofs = 0;
1117 1137
1118 snd_printd("capture prepare %d\n", substream->number); 1138 VPRINTK1("Capture Prepare %d\n", substream->number);
1119 return 0; 1139 return 0;
1120} 1140}
1121 1141
@@ -1133,12 +1153,12 @@ static void snd_card_asihpi_capture_format(struct snd_card_asihpi *asihpi,
1133 1153
1134 /* on cards without SRC, must query at valid rate, 1154 /* on cards without SRC, must query at valid rate,
1135 maybe set by external sync */ 1155 maybe set by external sync */
1136 err = hpi_mixer_get_control(ss, asihpi->h_mixer, 1156 err = hpi_mixer_get_control(asihpi->h_mixer,
1137 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0, 1157 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
1138 HPI_CONTROL_SAMPLECLOCK, &h_control); 1158 HPI_CONTROL_SAMPLECLOCK, &h_control);
1139 1159
1140 if (!err) 1160 if (!err)
1141 err = hpi_sample_clock_get_sample_rate(ss, h_control, 1161 err = hpi_sample_clock_get_sample_rate(h_control,
1142 &sample_rate); 1162 &sample_rate);
1143 1163
1144 for (format = HPI_FORMAT_PCM8_UNSIGNED; 1164 for (format = HPI_FORMAT_PCM8_UNSIGNED;
@@ -1147,7 +1167,7 @@ static void snd_card_asihpi_capture_format(struct snd_card_asihpi *asihpi,
1147 err = hpi_format_create(&hpi_format, 2, format, 1167 err = hpi_format_create(&hpi_format, 2, format,
1148 sample_rate, 128000, 0); 1168 sample_rate, 128000, 0);
1149 if (!err) 1169 if (!err)
1150 err = hpi_instream_query_format(ss, h_stream, 1170 err = hpi_instream_query_format(h_stream,
1151 &hpi_format); 1171 &hpi_format);
1152 if (!err) 1172 if (!err)
1153 pcmhw->formats |= 1173 pcmhw->formats |=
@@ -1178,11 +1198,11 @@ static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream)
1178 if (dpcm == NULL) 1198 if (dpcm == NULL)
1179 return -ENOMEM; 1199 return -ENOMEM;
1180 1200
1181 snd_printd("hpi_instream_open adapter %d stream %d\n", 1201 VPRINTK1("hpi_instream_open adapter %d stream %d\n",
1182 card->adapter_index, substream->number); 1202 card->adapter_index, substream->number);
1183 1203
1184 err = hpi_handle_error( 1204 err = hpi_handle_error(
1185 hpi_instream_open(ss, card->adapter_index, 1205 hpi_instream_open(card->adapter_index,
1186 substream->number, &dpcm->h_stream)); 1206 substream->number, &dpcm->h_stream));
1187 if (err) 1207 if (err)
1188 kfree(dpcm); 1208 kfree(dpcm);
@@ -1209,6 +1229,9 @@ static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream)
1209 snd_card_asihpi_capture.info |= SNDRV_PCM_INFO_MMAP | 1229 snd_card_asihpi_capture.info |= SNDRV_PCM_INFO_MMAP |
1210 SNDRV_PCM_INFO_MMAP_VALID; 1230 SNDRV_PCM_INFO_MMAP_VALID;
1211 1231
1232 if (card->support_grouping)
1233 snd_card_asihpi_capture.info |= SNDRV_PCM_INFO_SYNC_START;
1234
1212 runtime->hw = snd_card_asihpi_capture; 1235 runtime->hw = snd_card_asihpi_capture;
1213 1236
1214 if (card->support_mmap) 1237 if (card->support_mmap)
@@ -1231,7 +1254,7 @@ static int snd_card_asihpi_capture_close(struct snd_pcm_substream *substream)
1231{ 1254{
1232 struct snd_card_asihpi_pcm *dpcm = substream->runtime->private_data; 1255 struct snd_card_asihpi_pcm *dpcm = substream->runtime->private_data;
1233 1256
1234 hpi_handle_error(hpi_instream_close(ss, dpcm->h_stream)); 1257 hpi_handle_error(hpi_instream_close(dpcm->h_stream));
1235 return 0; 1258 return 0;
1236} 1259}
1237 1260
@@ -1241,18 +1264,17 @@ static int snd_card_asihpi_capture_copy(struct snd_pcm_substream *substream,
1241{ 1264{
1242 struct snd_pcm_runtime *runtime = substream->runtime; 1265 struct snd_pcm_runtime *runtime = substream->runtime;
1243 struct snd_card_asihpi_pcm *dpcm = runtime->private_data; 1266 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1244 u32 data_size; 1267 u32 len;
1245 1268
1246 data_size = frames_to_bytes(runtime, count); 1269 len = frames_to_bytes(runtime, count);
1247 1270
1248 VPRINTK2("capture copy%d %d bytes\n", substream->number, data_size); 1271 VPRINTK2(KERN_INFO "capture copy%d %d bytes\n", substream->number, len);
1249 hpi_handle_error(hpi_instream_read_buf(ss, dpcm->h_stream, 1272 hpi_handle_error(hpi_instream_read_buf(dpcm->h_stream,
1250 runtime->dma_area, data_size)); 1273 runtime->dma_area, len));
1251 1274
1252 /* Used by capture_pointer */ 1275 dpcm->pcm_buf_host_rw_ofs = dpcm->pcm_buf_host_rw_ofs + len;
1253 dpcm->pcm_irq_pos = dpcm->pcm_irq_pos + data_size;
1254 1276
1255 if (copy_to_user(dst, runtime->dma_area, data_size)) 1277 if (copy_to_user(dst, runtime->dma_area, len))
1256 return -EFAULT; 1278 return -EFAULT;
1257 1279
1258 return 0; 1280 return 0;
@@ -1287,7 +1309,7 @@ static int __devinit snd_card_asihpi_pcm_new(struct snd_card_asihpi *asihpi,
1287 struct snd_pcm *pcm; 1309 struct snd_pcm *pcm;
1288 int err; 1310 int err;
1289 1311
1290 err = snd_pcm_new(asihpi->card, "asihpi PCM", device, 1312 err = snd_pcm_new(asihpi->card, "Asihpi PCM", device,
1291 asihpi->num_outstreams, asihpi->num_instreams, 1313 asihpi->num_outstreams, asihpi->num_instreams,
1292 &pcm); 1314 &pcm);
1293 if (err < 0) 1315 if (err < 0)
@@ -1307,7 +1329,7 @@ static int __devinit snd_card_asihpi_pcm_new(struct snd_card_asihpi *asihpi,
1307 1329
1308 pcm->private_data = asihpi; 1330 pcm->private_data = asihpi;
1309 pcm->info_flags = 0; 1331 pcm->info_flags = 0;
1310 strcpy(pcm->name, "asihpi PCM"); 1332 strcpy(pcm->name, "Asihpi PCM");
1311 1333
1312 /*? do we want to emulate MMAP for non-BBM cards? 1334 /*? do we want to emulate MMAP for non-BBM cards?
1313 Jack doesn't work with ALSAs MMAP emulation - WHY NOT? */ 1335 Jack doesn't work with ALSAs MMAP emulation - WHY NOT? */
@@ -1330,8 +1352,7 @@ struct hpi_control {
1330 char name[44]; /* copied to snd_ctl_elem_id.name[44]; */ 1352 char name[44]; /* copied to snd_ctl_elem_id.name[44]; */
1331}; 1353};
1332 1354
1333static char *asihpi_tuner_band_names[] = 1355static const char * const asihpi_tuner_band_names[] = {
1334{
1335 "invalid", 1356 "invalid",
1336 "AM", 1357 "AM",
1337 "FM mono", 1358 "FM mono",
@@ -1349,70 +1370,36 @@ compile_time_assert(
1349 (HPI_TUNER_BAND_LAST+1)), 1370 (HPI_TUNER_BAND_LAST+1)),
1350 assert_tuner_band_names_size); 1371 assert_tuner_band_names_size);
1351 1372
1352#if ASI_STYLE_NAMES 1373static const char * const asihpi_src_names[] = {
1353static char *asihpi_src_names[] =
1354{
1355 "no source", 1374 "no source",
1356 "outstream", 1375 "PCM",
1357 "line_in", 1376 "Line",
1358 "aes_in", 1377 "Digital",
1359 "tuner", 1378 "Tuner",
1360 "RF", 1379 "RF",
1361 "clock", 1380 "Clock",
1362 "bitstr", 1381 "Bitstream",
1363 "mic", 1382 "Microphone",
1364 "cobranet", 1383 "Cobranet",
1365 "analog_in", 1384 "Analog",
1366 "adapter", 1385 "Adapter",
1367}; 1386};
1368#else
1369static char *asihpi_src_names[] =
1370{
1371 "no source",
1372 "PCM playback",
1373 "line in",
1374 "digital in",
1375 "tuner",
1376 "RF",
1377 "clock",
1378 "bitstream",
1379 "mic",
1380 "cobranet in",
1381 "analog in",
1382 "adapter",
1383};
1384#endif
1385 1387
1386compile_time_assert( 1388compile_time_assert(
1387 (ARRAY_SIZE(asihpi_src_names) == 1389 (ARRAY_SIZE(asihpi_src_names) ==
1388 (HPI_SOURCENODE_LAST_INDEX-HPI_SOURCENODE_NONE+1)), 1390 (HPI_SOURCENODE_LAST_INDEX-HPI_SOURCENODE_NONE+1)),
1389 assert_src_names_size); 1391 assert_src_names_size);
1390 1392
1391#if ASI_STYLE_NAMES 1393static const char * const asihpi_dst_names[] = {
1392static char *asihpi_dst_names[] =
1393{
1394 "no destination",
1395 "instream",
1396 "line_out",
1397 "aes_out",
1398 "RF",
1399 "speaker" ,
1400 "cobranet",
1401 "analog_out",
1402};
1403#else
1404static char *asihpi_dst_names[] =
1405{
1406 "no destination", 1394 "no destination",
1407 "PCM capture", 1395 "PCM",
1408 "line out", 1396 "Line",
1409 "digital out", 1397 "Digital",
1410 "RF", 1398 "RF",
1411 "speaker", 1399 "Speaker",
1412 "cobranet out", 1400 "Cobranet Out",
1413 "analog out" 1401 "Analog"
1414}; 1402};
1415#endif
1416 1403
1417compile_time_assert( 1404compile_time_assert(
1418 (ARRAY_SIZE(asihpi_dst_names) == 1405 (ARRAY_SIZE(asihpi_dst_names) ==
@@ -1438,30 +1425,45 @@ static void asihpi_ctl_init(struct snd_kcontrol_new *snd_control,
1438 struct hpi_control *hpi_ctl, 1425 struct hpi_control *hpi_ctl,
1439 char *name) 1426 char *name)
1440{ 1427{
1428 char *dir = "";
1441 memset(snd_control, 0, sizeof(*snd_control)); 1429 memset(snd_control, 0, sizeof(*snd_control));
1442 snd_control->name = hpi_ctl->name; 1430 snd_control->name = hpi_ctl->name;
1443 snd_control->private_value = hpi_ctl->h_control; 1431 snd_control->private_value = hpi_ctl->h_control;
1444 snd_control->iface = SNDRV_CTL_ELEM_IFACE_MIXER; 1432 snd_control->iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1445 snd_control->index = 0; 1433 snd_control->index = 0;
1446 1434
1435 if (hpi_ctl->dst_node_type + HPI_DESTNODE_NONE == HPI_DESTNODE_ISTREAM)
1436 dir = "Capture "; /* On or towards a PCM capture destination*/
1437 else if ((hpi_ctl->src_node_type + HPI_SOURCENODE_NONE != HPI_SOURCENODE_OSTREAM) &&
1438 (!hpi_ctl->dst_node_type))
1439 dir = "Capture "; /* On a source node that is not PCM playback */
1440 else if (hpi_ctl->src_node_type &&
1441 (hpi_ctl->src_node_type + HPI_SOURCENODE_NONE != HPI_SOURCENODE_OSTREAM) &&
1442 (hpi_ctl->dst_node_type))
1443 dir = "Monitor Playback "; /* Between an input and an output */
1444 else
1445 dir = "Playback "; /* PCM Playback source, or output node */
1446
1447 if (hpi_ctl->src_node_type && hpi_ctl->dst_node_type) 1447 if (hpi_ctl->src_node_type && hpi_ctl->dst_node_type)
1448 sprintf(hpi_ctl->name, "%s%d to %s%d %s", 1448 sprintf(hpi_ctl->name, "%s%d %s%d %s%s",
1449 asihpi_src_names[hpi_ctl->src_node_type], 1449 asihpi_src_names[hpi_ctl->src_node_type],
1450 hpi_ctl->src_node_index, 1450 hpi_ctl->src_node_index,
1451 asihpi_dst_names[hpi_ctl->dst_node_type], 1451 asihpi_dst_names[hpi_ctl->dst_node_type],
1452 hpi_ctl->dst_node_index, 1452 hpi_ctl->dst_node_index,
1453 name); 1453 dir, name);
1454 else if (hpi_ctl->dst_node_type) { 1454 else if (hpi_ctl->dst_node_type) {
1455 sprintf(hpi_ctl->name, "%s%d %s", 1455 sprintf(hpi_ctl->name, "%s %d %s%s",
1456 asihpi_dst_names[hpi_ctl->dst_node_type], 1456 asihpi_dst_names[hpi_ctl->dst_node_type],
1457 hpi_ctl->dst_node_index, 1457 hpi_ctl->dst_node_index,
1458 name); 1458 dir, name);
1459 } else { 1459 } else {
1460 sprintf(hpi_ctl->name, "%s%d %s", 1460 sprintf(hpi_ctl->name, "%s %d %s%s",
1461 asihpi_src_names[hpi_ctl->src_node_type], 1461 asihpi_src_names[hpi_ctl->src_node_type],
1462 hpi_ctl->src_node_index, 1462 hpi_ctl->src_node_index,
1463 name); 1463 dir, name);
1464 } 1464 }
1465 /* printk(KERN_INFO "Adding %s %d to %d ", hpi_ctl->name,
1466 hpi_ctl->wSrcNodeType, hpi_ctl->wDstNodeType); */
1465} 1467}
1466 1468
1467/*------------------------------------------------------------ 1469/*------------------------------------------------------------
@@ -1478,7 +1480,7 @@ static int snd_asihpi_volume_info(struct snd_kcontrol *kcontrol,
1478 short max_gain_mB; 1480 short max_gain_mB;
1479 short step_gain_mB; 1481 short step_gain_mB;
1480 1482
1481 err = hpi_volume_query_range(ss, h_control, 1483 err = hpi_volume_query_range(h_control,
1482 &min_gain_mB, &max_gain_mB, &step_gain_mB); 1484 &min_gain_mB, &max_gain_mB, &step_gain_mB);
1483 if (err) { 1485 if (err) {
1484 max_gain_mB = 0; 1486 max_gain_mB = 0;
@@ -1500,7 +1502,7 @@ static int snd_asihpi_volume_get(struct snd_kcontrol *kcontrol,
1500 u32 h_control = kcontrol->private_value; 1502 u32 h_control = kcontrol->private_value;
1501 short an_gain_mB[HPI_MAX_CHANNELS]; 1503 short an_gain_mB[HPI_MAX_CHANNELS];
1502 1504
1503 hpi_handle_error(hpi_volume_get_gain(ss, h_control, an_gain_mB)); 1505 hpi_handle_error(hpi_volume_get_gain(h_control, an_gain_mB));
1504 ucontrol->value.integer.value[0] = an_gain_mB[0] / VOL_STEP_mB; 1506 ucontrol->value.integer.value[0] = an_gain_mB[0] / VOL_STEP_mB;
1505 ucontrol->value.integer.value[1] = an_gain_mB[1] / VOL_STEP_mB; 1507 ucontrol->value.integer.value[1] = an_gain_mB[1] / VOL_STEP_mB;
1506 1508
@@ -1522,7 +1524,7 @@ static int snd_asihpi_volume_put(struct snd_kcontrol *kcontrol,
1522 asihpi->mixer_volume[addr][1] != right; 1524 asihpi->mixer_volume[addr][1] != right;
1523 */ 1525 */
1524 change = 1; 1526 change = 1;
1525 hpi_handle_error(hpi_volume_set_gain(ss, h_control, an_gain_mB)); 1527 hpi_handle_error(hpi_volume_set_gain(h_control, an_gain_mB));
1526 return change; 1528 return change;
1527} 1529}
1528 1530
@@ -1534,7 +1536,7 @@ static int __devinit snd_asihpi_volume_add(struct snd_card_asihpi *asihpi,
1534 struct snd_card *card = asihpi->card; 1536 struct snd_card *card = asihpi->card;
1535 struct snd_kcontrol_new snd_control; 1537 struct snd_kcontrol_new snd_control;
1536 1538
1537 asihpi_ctl_init(&snd_control, hpi_ctl, "volume"); 1539 asihpi_ctl_init(&snd_control, hpi_ctl, "Volume");
1538 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | 1540 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
1539 SNDRV_CTL_ELEM_ACCESS_TLV_READ; 1541 SNDRV_CTL_ELEM_ACCESS_TLV_READ;
1540 snd_control.info = snd_asihpi_volume_info; 1542 snd_control.info = snd_asihpi_volume_info;
@@ -1558,7 +1560,7 @@ static int snd_asihpi_level_info(struct snd_kcontrol *kcontrol,
1558 short step_gain_mB; 1560 short step_gain_mB;
1559 1561
1560 err = 1562 err =
1561 hpi_level_query_range(ss, h_control, &min_gain_mB, 1563 hpi_level_query_range(h_control, &min_gain_mB,
1562 &max_gain_mB, &step_gain_mB); 1564 &max_gain_mB, &step_gain_mB);
1563 if (err) { 1565 if (err) {
1564 max_gain_mB = 2400; 1566 max_gain_mB = 2400;
@@ -1580,7 +1582,7 @@ static int snd_asihpi_level_get(struct snd_kcontrol *kcontrol,
1580 u32 h_control = kcontrol->private_value; 1582 u32 h_control = kcontrol->private_value;
1581 short an_gain_mB[HPI_MAX_CHANNELS]; 1583 short an_gain_mB[HPI_MAX_CHANNELS];
1582 1584
1583 hpi_handle_error(hpi_level_get_gain(ss, h_control, an_gain_mB)); 1585 hpi_handle_error(hpi_level_get_gain(h_control, an_gain_mB));
1584 ucontrol->value.integer.value[0] = 1586 ucontrol->value.integer.value[0] =
1585 an_gain_mB[0] / HPI_UNITS_PER_dB; 1587 an_gain_mB[0] / HPI_UNITS_PER_dB;
1586 ucontrol->value.integer.value[1] = 1588 ucontrol->value.integer.value[1] =
@@ -1604,7 +1606,7 @@ static int snd_asihpi_level_put(struct snd_kcontrol *kcontrol,
1604 asihpi->mixer_level[addr][1] != right; 1606 asihpi->mixer_level[addr][1] != right;
1605 */ 1607 */
1606 change = 1; 1608 change = 1;
1607 hpi_handle_error(hpi_level_set_gain(ss, h_control, an_gain_mB)); 1609 hpi_handle_error(hpi_level_set_gain(h_control, an_gain_mB));
1608 return change; 1610 return change;
1609} 1611}
1610 1612
@@ -1617,7 +1619,7 @@ static int __devinit snd_asihpi_level_add(struct snd_card_asihpi *asihpi,
1617 struct snd_kcontrol_new snd_control; 1619 struct snd_kcontrol_new snd_control;
1618 1620
1619 /* can't use 'volume' cos some nodes have volume as well */ 1621 /* can't use 'volume' cos some nodes have volume as well */
1620 asihpi_ctl_init(&snd_control, hpi_ctl, "level"); 1622 asihpi_ctl_init(&snd_control, hpi_ctl, "Level");
1621 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | 1623 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
1622 SNDRV_CTL_ELEM_ACCESS_TLV_READ; 1624 SNDRV_CTL_ELEM_ACCESS_TLV_READ;
1623 snd_control.info = snd_asihpi_level_info; 1625 snd_control.info = snd_asihpi_level_info;
@@ -1633,12 +1635,8 @@ static int __devinit snd_asihpi_level_add(struct snd_card_asihpi *asihpi,
1633 ------------------------------------------------------------*/ 1635 ------------------------------------------------------------*/
1634 1636
1635/* AESEBU format */ 1637/* AESEBU format */
1636static char *asihpi_aesebu_format_names[] = 1638static const char * const asihpi_aesebu_format_names[] = {
1637{ 1639 "N/A", "S/PDIF", "AES/EBU" };
1638 "N/A",
1639 "S/PDIF",
1640 "AES/EBU",
1641};
1642 1640
1643static int snd_asihpi_aesebu_format_info(struct snd_kcontrol *kcontrol, 1641static int snd_asihpi_aesebu_format_info(struct snd_kcontrol *kcontrol,
1644 struct snd_ctl_elem_info *uinfo) 1642 struct snd_ctl_elem_info *uinfo)
@@ -1659,12 +1657,12 @@ static int snd_asihpi_aesebu_format_info(struct snd_kcontrol *kcontrol,
1659 1657
1660static int snd_asihpi_aesebu_format_get(struct snd_kcontrol *kcontrol, 1658static int snd_asihpi_aesebu_format_get(struct snd_kcontrol *kcontrol,
1661 struct snd_ctl_elem_value *ucontrol, 1659 struct snd_ctl_elem_value *ucontrol,
1662 u16 (*func)(const struct hpi_hsubsys *, u32, u16 *)) 1660 u16 (*func)(u32, u16 *))
1663{ 1661{
1664 u32 h_control = kcontrol->private_value; 1662 u32 h_control = kcontrol->private_value;
1665 u16 source, err; 1663 u16 source, err;
1666 1664
1667 err = func(ss, h_control, &source); 1665 err = func(h_control, &source);
1668 1666
1669 /* default to N/A */ 1667 /* default to N/A */
1670 ucontrol->value.enumerated.item[0] = 0; 1668 ucontrol->value.enumerated.item[0] = 0;
@@ -1681,7 +1679,7 @@ static int snd_asihpi_aesebu_format_get(struct snd_kcontrol *kcontrol,
1681 1679
1682static int snd_asihpi_aesebu_format_put(struct snd_kcontrol *kcontrol, 1680static int snd_asihpi_aesebu_format_put(struct snd_kcontrol *kcontrol,
1683 struct snd_ctl_elem_value *ucontrol, 1681 struct snd_ctl_elem_value *ucontrol,
1684 u16 (*func)(const struct hpi_hsubsys *, u32, u16)) 1682 u16 (*func)(u32, u16))
1685{ 1683{
1686 u32 h_control = kcontrol->private_value; 1684 u32 h_control = kcontrol->private_value;
1687 1685
@@ -1693,7 +1691,7 @@ static int snd_asihpi_aesebu_format_put(struct snd_kcontrol *kcontrol,
1693 if (ucontrol->value.enumerated.item[0] == 2) 1691 if (ucontrol->value.enumerated.item[0] == 2)
1694 source = HPI_AESEBU_FORMAT_AESEBU; 1692 source = HPI_AESEBU_FORMAT_AESEBU;
1695 1693
1696 if (func(ss, h_control, source) != 0) 1694 if (func(h_control, source) != 0)
1697 return -EINVAL; 1695 return -EINVAL;
1698 1696
1699 return 1; 1697 return 1;
@@ -1702,13 +1700,13 @@ static int snd_asihpi_aesebu_format_put(struct snd_kcontrol *kcontrol,
1702static int snd_asihpi_aesebu_rx_format_get(struct snd_kcontrol *kcontrol, 1700static int snd_asihpi_aesebu_rx_format_get(struct snd_kcontrol *kcontrol,
1703 struct snd_ctl_elem_value *ucontrol) { 1701 struct snd_ctl_elem_value *ucontrol) {
1704 return snd_asihpi_aesebu_format_get(kcontrol, ucontrol, 1702 return snd_asihpi_aesebu_format_get(kcontrol, ucontrol,
1705 HPI_AESEBU__receiver_get_format); 1703 hpi_aesebu_receiver_get_format);
1706} 1704}
1707 1705
1708static int snd_asihpi_aesebu_rx_format_put(struct snd_kcontrol *kcontrol, 1706static int snd_asihpi_aesebu_rx_format_put(struct snd_kcontrol *kcontrol,
1709 struct snd_ctl_elem_value *ucontrol) { 1707 struct snd_ctl_elem_value *ucontrol) {
1710 return snd_asihpi_aesebu_format_put(kcontrol, ucontrol, 1708 return snd_asihpi_aesebu_format_put(kcontrol, ucontrol,
1711 HPI_AESEBU__receiver_set_format); 1709 hpi_aesebu_receiver_set_format);
1712} 1710}
1713 1711
1714static int snd_asihpi_aesebu_rxstatus_info(struct snd_kcontrol *kcontrol, 1712static int snd_asihpi_aesebu_rxstatus_info(struct snd_kcontrol *kcontrol,
@@ -1730,8 +1728,8 @@ static int snd_asihpi_aesebu_rxstatus_get(struct snd_kcontrol *kcontrol,
1730 u32 h_control = kcontrol->private_value; 1728 u32 h_control = kcontrol->private_value;
1731 u16 status; 1729 u16 status;
1732 1730
1733 hpi_handle_error(HPI_AESEBU__receiver_get_error_status( 1731 hpi_handle_error(hpi_aesebu_receiver_get_error_status(
1734 ss, h_control, &status)); 1732 h_control, &status));
1735 ucontrol->value.integer.value[0] = status; 1733 ucontrol->value.integer.value[0] = status;
1736 return 0; 1734 return 0;
1737} 1735}
@@ -1742,7 +1740,7 @@ static int __devinit snd_asihpi_aesebu_rx_add(struct snd_card_asihpi *asihpi,
1742 struct snd_card *card = asihpi->card; 1740 struct snd_card *card = asihpi->card;
1743 struct snd_kcontrol_new snd_control; 1741 struct snd_kcontrol_new snd_control;
1744 1742
1745 asihpi_ctl_init(&snd_control, hpi_ctl, "format"); 1743 asihpi_ctl_init(&snd_control, hpi_ctl, "Format");
1746 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE; 1744 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
1747 snd_control.info = snd_asihpi_aesebu_format_info; 1745 snd_control.info = snd_asihpi_aesebu_format_info;
1748 snd_control.get = snd_asihpi_aesebu_rx_format_get; 1746 snd_control.get = snd_asihpi_aesebu_rx_format_get;
@@ -1752,7 +1750,7 @@ static int __devinit snd_asihpi_aesebu_rx_add(struct snd_card_asihpi *asihpi,
1752 if (ctl_add(card, &snd_control, asihpi) < 0) 1750 if (ctl_add(card, &snd_control, asihpi) < 0)
1753 return -EINVAL; 1751 return -EINVAL;
1754 1752
1755 asihpi_ctl_init(&snd_control, hpi_ctl, "status"); 1753 asihpi_ctl_init(&snd_control, hpi_ctl, "Status");
1756 snd_control.access = 1754 snd_control.access =
1757 SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ; 1755 SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ;
1758 snd_control.info = snd_asihpi_aesebu_rxstatus_info; 1756 snd_control.info = snd_asihpi_aesebu_rxstatus_info;
@@ -1764,13 +1762,13 @@ static int __devinit snd_asihpi_aesebu_rx_add(struct snd_card_asihpi *asihpi,
1764static int snd_asihpi_aesebu_tx_format_get(struct snd_kcontrol *kcontrol, 1762static int snd_asihpi_aesebu_tx_format_get(struct snd_kcontrol *kcontrol,
1765 struct snd_ctl_elem_value *ucontrol) { 1763 struct snd_ctl_elem_value *ucontrol) {
1766 return snd_asihpi_aesebu_format_get(kcontrol, ucontrol, 1764 return snd_asihpi_aesebu_format_get(kcontrol, ucontrol,
1767 HPI_AESEBU__transmitter_get_format); 1765 hpi_aesebu_transmitter_get_format);
1768} 1766}
1769 1767
1770static int snd_asihpi_aesebu_tx_format_put(struct snd_kcontrol *kcontrol, 1768static int snd_asihpi_aesebu_tx_format_put(struct snd_kcontrol *kcontrol,
1771 struct snd_ctl_elem_value *ucontrol) { 1769 struct snd_ctl_elem_value *ucontrol) {
1772 return snd_asihpi_aesebu_format_put(kcontrol, ucontrol, 1770 return snd_asihpi_aesebu_format_put(kcontrol, ucontrol,
1773 HPI_AESEBU__transmitter_set_format); 1771 hpi_aesebu_transmitter_set_format);
1774} 1772}
1775 1773
1776 1774
@@ -1780,7 +1778,7 @@ static int __devinit snd_asihpi_aesebu_tx_add(struct snd_card_asihpi *asihpi,
1780 struct snd_card *card = asihpi->card; 1778 struct snd_card *card = asihpi->card;
1781 struct snd_kcontrol_new snd_control; 1779 struct snd_kcontrol_new snd_control;
1782 1780
1783 asihpi_ctl_init(&snd_control, hpi_ctl, "format"); 1781 asihpi_ctl_init(&snd_control, hpi_ctl, "Format");
1784 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE; 1782 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
1785 snd_control.info = snd_asihpi_aesebu_format_info; 1783 snd_control.info = snd_asihpi_aesebu_format_info;
1786 snd_control.get = snd_asihpi_aesebu_tx_format_get; 1784 snd_control.get = snd_asihpi_aesebu_tx_format_get;
@@ -1804,7 +1802,7 @@ static int snd_asihpi_tuner_gain_info(struct snd_kcontrol *kcontrol,
1804 u16 gain_range[3]; 1802 u16 gain_range[3];
1805 1803
1806 for (idx = 0; idx < 3; idx++) { 1804 for (idx = 0; idx < 3; idx++) {
1807 err = hpi_tuner_query_gain(ss, h_control, 1805 err = hpi_tuner_query_gain(h_control,
1808 idx, &gain_range[idx]); 1806 idx, &gain_range[idx]);
1809 if (err != 0) 1807 if (err != 0)
1810 return err; 1808 return err;
@@ -1827,7 +1825,7 @@ static int snd_asihpi_tuner_gain_get(struct snd_kcontrol *kcontrol,
1827 u32 h_control = kcontrol->private_value; 1825 u32 h_control = kcontrol->private_value;
1828 short gain; 1826 short gain;
1829 1827
1830 hpi_handle_error(hpi_tuner_get_gain(ss, h_control, &gain)); 1828 hpi_handle_error(hpi_tuner_get_gain(h_control, &gain));
1831 ucontrol->value.integer.value[0] = gain / HPI_UNITS_PER_dB; 1829 ucontrol->value.integer.value[0] = gain / HPI_UNITS_PER_dB;
1832 1830
1833 return 0; 1831 return 0;
@@ -1843,7 +1841,7 @@ static int snd_asihpi_tuner_gain_put(struct snd_kcontrol *kcontrol,
1843 short gain; 1841 short gain;
1844 1842
1845 gain = (ucontrol->value.integer.value[0]) * HPI_UNITS_PER_dB; 1843 gain = (ucontrol->value.integer.value[0]) * HPI_UNITS_PER_dB;
1846 hpi_handle_error(hpi_tuner_set_gain(ss, h_control, gain)); 1844 hpi_handle_error(hpi_tuner_set_gain(h_control, gain));
1847 1845
1848 return 1; 1846 return 1;
1849} 1847}
@@ -1857,7 +1855,7 @@ static int asihpi_tuner_band_query(struct snd_kcontrol *kcontrol,
1857 u32 i; 1855 u32 i;
1858 1856
1859 for (i = 0; i < len; i++) { 1857 for (i = 0; i < len; i++) {
1860 err = hpi_tuner_query_band(ss, 1858 err = hpi_tuner_query_band(
1861 h_control, i, &band_list[i]); 1859 h_control, i, &band_list[i]);
1862 if (err != 0) 1860 if (err != 0)
1863 break; 1861 break;
@@ -1913,7 +1911,7 @@ static int snd_asihpi_tuner_band_get(struct snd_kcontrol *kcontrol,
1913 num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands, 1911 num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1914 HPI_TUNER_BAND_LAST); 1912 HPI_TUNER_BAND_LAST);
1915 1913
1916 hpi_handle_error(hpi_tuner_get_band(ss, h_control, &band)); 1914 hpi_handle_error(hpi_tuner_get_band(h_control, &band));
1917 1915
1918 ucontrol->value.enumerated.item[0] = -1; 1916 ucontrol->value.enumerated.item[0] = -1;
1919 for (idx = 0; idx < HPI_TUNER_BAND_LAST; idx++) 1917 for (idx = 0; idx < HPI_TUNER_BAND_LAST; idx++)
@@ -1940,7 +1938,7 @@ static int snd_asihpi_tuner_band_put(struct snd_kcontrol *kcontrol,
1940 HPI_TUNER_BAND_LAST); 1938 HPI_TUNER_BAND_LAST);
1941 1939
1942 band = tuner_bands[ucontrol->value.enumerated.item[0]]; 1940 band = tuner_bands[ucontrol->value.enumerated.item[0]];
1943 hpi_handle_error(hpi_tuner_set_band(ss, h_control, band)); 1941 hpi_handle_error(hpi_tuner_set_band(h_control, band));
1944 1942
1945 return 1; 1943 return 1;
1946} 1944}
@@ -1965,7 +1963,7 @@ static int snd_asihpi_tuner_freq_info(struct snd_kcontrol *kcontrol,
1965 1963
1966 for (band_iter = 0; band_iter < num_bands; band_iter++) { 1964 for (band_iter = 0; band_iter < num_bands; band_iter++) {
1967 for (idx = 0; idx < 3; idx++) { 1965 for (idx = 0; idx < 3; idx++) {
1968 err = hpi_tuner_query_frequency(ss, h_control, 1966 err = hpi_tuner_query_frequency(h_control,
1969 idx, tuner_bands[band_iter], 1967 idx, tuner_bands[band_iter],
1970 &temp_freq_range[idx]); 1968 &temp_freq_range[idx]);
1971 if (err != 0) 1969 if (err != 0)
@@ -1998,7 +1996,7 @@ static int snd_asihpi_tuner_freq_get(struct snd_kcontrol *kcontrol,
1998 u32 h_control = kcontrol->private_value; 1996 u32 h_control = kcontrol->private_value;
1999 u32 freq; 1997 u32 freq;
2000 1998
2001 hpi_handle_error(hpi_tuner_get_frequency(ss, h_control, &freq)); 1999 hpi_handle_error(hpi_tuner_get_frequency(h_control, &freq));
2002 ucontrol->value.integer.value[0] = freq; 2000 ucontrol->value.integer.value[0] = freq;
2003 2001
2004 return 0; 2002 return 0;
@@ -2011,7 +2009,7 @@ static int snd_asihpi_tuner_freq_put(struct snd_kcontrol *kcontrol,
2011 u32 freq; 2009 u32 freq;
2012 2010
2013 freq = ucontrol->value.integer.value[0]; 2011 freq = ucontrol->value.integer.value[0];
2014 hpi_handle_error(hpi_tuner_set_frequency(ss, h_control, freq)); 2012 hpi_handle_error(hpi_tuner_set_frequency(h_control, freq));
2015 2013
2016 return 1; 2014 return 1;
2017} 2015}
@@ -2026,8 +2024,8 @@ static int __devinit snd_asihpi_tuner_add(struct snd_card_asihpi *asihpi,
2026 snd_control.private_value = hpi_ctl->h_control; 2024 snd_control.private_value = hpi_ctl->h_control;
2027 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE; 2025 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
2028 2026
2029 if (!hpi_tuner_get_gain(ss, hpi_ctl->h_control, NULL)) { 2027 if (!hpi_tuner_get_gain(hpi_ctl->h_control, NULL)) {
2030 asihpi_ctl_init(&snd_control, hpi_ctl, "gain"); 2028 asihpi_ctl_init(&snd_control, hpi_ctl, "Gain");
2031 snd_control.info = snd_asihpi_tuner_gain_info; 2029 snd_control.info = snd_asihpi_tuner_gain_info;
2032 snd_control.get = snd_asihpi_tuner_gain_get; 2030 snd_control.get = snd_asihpi_tuner_gain_get;
2033 snd_control.put = snd_asihpi_tuner_gain_put; 2031 snd_control.put = snd_asihpi_tuner_gain_put;
@@ -2036,7 +2034,7 @@ static int __devinit snd_asihpi_tuner_add(struct snd_card_asihpi *asihpi,
2036 return -EINVAL; 2034 return -EINVAL;
2037 } 2035 }
2038 2036
2039 asihpi_ctl_init(&snd_control, hpi_ctl, "band"); 2037 asihpi_ctl_init(&snd_control, hpi_ctl, "Band");
2040 snd_control.info = snd_asihpi_tuner_band_info; 2038 snd_control.info = snd_asihpi_tuner_band_info;
2041 snd_control.get = snd_asihpi_tuner_band_get; 2039 snd_control.get = snd_asihpi_tuner_band_get;
2042 snd_control.put = snd_asihpi_tuner_band_put; 2040 snd_control.put = snd_asihpi_tuner_band_put;
@@ -2044,7 +2042,7 @@ static int __devinit snd_asihpi_tuner_add(struct snd_card_asihpi *asihpi,
2044 if (ctl_add(card, &snd_control, asihpi) < 0) 2042 if (ctl_add(card, &snd_control, asihpi) < 0)
2045 return -EINVAL; 2043 return -EINVAL;
2046 2044
2047 asihpi_ctl_init(&snd_control, hpi_ctl, "freq"); 2045 asihpi_ctl_init(&snd_control, hpi_ctl, "Freq");
2048 snd_control.info = snd_asihpi_tuner_freq_info; 2046 snd_control.info = snd_asihpi_tuner_freq_info;
2049 snd_control.get = snd_asihpi_tuner_freq_get; 2047 snd_control.get = snd_asihpi_tuner_freq_get;
2050 snd_control.put = snd_asihpi_tuner_freq_put; 2048 snd_control.put = snd_asihpi_tuner_freq_put;
@@ -2095,7 +2093,7 @@ static int snd_asihpi_meter_get(struct snd_kcontrol *kcontrol,
2095 short an_gain_mB[HPI_MAX_CHANNELS], i; 2093 short an_gain_mB[HPI_MAX_CHANNELS], i;
2096 u16 err; 2094 u16 err;
2097 2095
2098 err = hpi_meter_get_peak(ss, h_control, an_gain_mB); 2096 err = hpi_meter_get_peak(h_control, an_gain_mB);
2099 2097
2100 for (i = 0; i < HPI_MAX_CHANNELS; i++) { 2098 for (i = 0; i < HPI_MAX_CHANNELS; i++) {
2101 if (err) { 2099 if (err) {
@@ -2120,7 +2118,7 @@ static int __devinit snd_asihpi_meter_add(struct snd_card_asihpi *asihpi,
2120 struct snd_card *card = asihpi->card; 2118 struct snd_card *card = asihpi->card;
2121 struct snd_kcontrol_new snd_control; 2119 struct snd_kcontrol_new snd_control;
2122 2120
2123 asihpi_ctl_init(&snd_control, hpi_ctl, "meter"); 2121 asihpi_ctl_init(&snd_control, hpi_ctl, "Meter");
2124 snd_control.access = 2122 snd_control.access =
2125 SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ; 2123 SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ;
2126 snd_control.info = snd_asihpi_meter_info; 2124 snd_control.info = snd_asihpi_meter_info;
@@ -2140,7 +2138,7 @@ static int snd_card_asihpi_mux_count_sources(struct snd_kcontrol *snd_control)
2140 struct hpi_control hpi_ctl; 2138 struct hpi_control hpi_ctl;
2141 int s, err; 2139 int s, err;
2142 for (s = 0; s < 32; s++) { 2140 for (s = 0; s < 32; s++) {
2143 err = hpi_multiplexer_query_source(ss, h_control, s, 2141 err = hpi_multiplexer_query_source(h_control, s,
2144 &hpi_ctl. 2142 &hpi_ctl.
2145 src_node_type, 2143 src_node_type,
2146 &hpi_ctl. 2144 &hpi_ctl.
@@ -2168,7 +2166,7 @@ static int snd_asihpi_mux_info(struct snd_kcontrol *kcontrol,
2168 uinfo->value.enumerated.items - 1; 2166 uinfo->value.enumerated.items - 1;
2169 2167
2170 err = 2168 err =
2171 hpi_multiplexer_query_source(ss, h_control, 2169 hpi_multiplexer_query_source(h_control,
2172 uinfo->value.enumerated.item, 2170 uinfo->value.enumerated.item,
2173 &src_node_type, &src_node_index); 2171 &src_node_type, &src_node_index);
2174 2172
@@ -2186,11 +2184,11 @@ static int snd_asihpi_mux_get(struct snd_kcontrol *kcontrol,
2186 u16 src_node_type, src_node_index; 2184 u16 src_node_type, src_node_index;
2187 int s; 2185 int s;
2188 2186
2189 hpi_handle_error(hpi_multiplexer_get_source(ss, h_control, 2187 hpi_handle_error(hpi_multiplexer_get_source(h_control,
2190 &source_type, &source_index)); 2188 &source_type, &source_index));
2191 /* Should cache this search result! */ 2189 /* Should cache this search result! */
2192 for (s = 0; s < 256; s++) { 2190 for (s = 0; s < 256; s++) {
2193 if (hpi_multiplexer_query_source(ss, h_control, s, 2191 if (hpi_multiplexer_query_source(h_control, s,
2194 &src_node_type, &src_node_index)) 2192 &src_node_type, &src_node_index))
2195 break; 2193 break;
2196 2194
@@ -2201,7 +2199,7 @@ static int snd_asihpi_mux_get(struct snd_kcontrol *kcontrol,
2201 } 2199 }
2202 } 2200 }
2203 snd_printd(KERN_WARNING 2201 snd_printd(KERN_WARNING
2204 "control %x failed to match mux source %hu %hu\n", 2202 "Control %x failed to match mux source %hu %hu\n",
2205 h_control, source_type, source_index); 2203 h_control, source_type, source_index);
2206 ucontrol->value.enumerated.item[0] = 0; 2204 ucontrol->value.enumerated.item[0] = 0;
2207 return 0; 2205 return 0;
@@ -2217,12 +2215,12 @@ static int snd_asihpi_mux_put(struct snd_kcontrol *kcontrol,
2217 2215
2218 change = 1; 2216 change = 1;
2219 2217
2220 e = hpi_multiplexer_query_source(ss, h_control, 2218 e = hpi_multiplexer_query_source(h_control,
2221 ucontrol->value.enumerated.item[0], 2219 ucontrol->value.enumerated.item[0],
2222 &source_type, &source_index); 2220 &source_type, &source_index);
2223 if (!e) 2221 if (!e)
2224 hpi_handle_error( 2222 hpi_handle_error(
2225 hpi_multiplexer_set_source(ss, h_control, 2223 hpi_multiplexer_set_source(h_control,
2226 source_type, source_index)); 2224 source_type, source_index));
2227 return change; 2225 return change;
2228} 2226}
@@ -2234,11 +2232,7 @@ static int __devinit snd_asihpi_mux_add(struct snd_card_asihpi *asihpi,
2234 struct snd_card *card = asihpi->card; 2232 struct snd_card *card = asihpi->card;
2235 struct snd_kcontrol_new snd_control; 2233 struct snd_kcontrol_new snd_control;
2236 2234
2237#if ASI_STYLE_NAMES 2235 asihpi_ctl_init(&snd_control, hpi_ctl, "Route");
2238 asihpi_ctl_init(&snd_control, hpi_ctl, "multiplexer");
2239#else
2240 asihpi_ctl_init(&snd_control, hpi_ctl, "route");
2241#endif
2242 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE; 2236 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
2243 snd_control.info = snd_asihpi_mux_info; 2237 snd_control.info = snd_asihpi_mux_info;
2244 snd_control.get = snd_asihpi_mux_get; 2238 snd_control.get = snd_asihpi_mux_get;
@@ -2254,33 +2248,38 @@ static int __devinit snd_asihpi_mux_add(struct snd_card_asihpi *asihpi,
2254static int snd_asihpi_cmode_info(struct snd_kcontrol *kcontrol, 2248static int snd_asihpi_cmode_info(struct snd_kcontrol *kcontrol,
2255 struct snd_ctl_elem_info *uinfo) 2249 struct snd_ctl_elem_info *uinfo)
2256{ 2250{
2257 static char *mode_names[HPI_CHANNEL_MODE_LAST] = { 2251 static const char * const mode_names[HPI_CHANNEL_MODE_LAST + 1] = {
2258 "normal", "swap", 2252 "invalid",
2259 "from_left", "from_right", 2253 "Normal", "Swap",
2260 "to_left", "to_right" 2254 "From Left", "From Right",
2255 "To Left", "To Right"
2261 }; 2256 };
2262 2257
2263 u32 h_control = kcontrol->private_value; 2258 u32 h_control = kcontrol->private_value;
2264 u16 mode; 2259 u16 mode;
2265 int i; 2260 int i;
2261 u16 mode_map[6];
2262 int valid_modes = 0;
2266 2263
2267 /* HPI channel mode values can be from 1 to 6 2264 /* HPI channel mode values can be from 1 to 6
2268 Some adapters only support a contiguous subset 2265 Some adapters only support a contiguous subset
2269 */ 2266 */
2270 for (i = 0; i < HPI_CHANNEL_MODE_LAST; i++) 2267 for (i = 0; i < HPI_CHANNEL_MODE_LAST; i++)
2271 if (hpi_channel_mode_query_mode( 2268 if (!hpi_channel_mode_query_mode(
2272 ss, h_control, i, &mode)) 2269 h_control, i, &mode)) {
2273 break; 2270 mode_map[valid_modes] = mode;
2271 valid_modes++;
2272 }
2274 2273
2275 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 2274 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2276 uinfo->count = 1; 2275 uinfo->count = 1;
2277 uinfo->value.enumerated.items = i; 2276 uinfo->value.enumerated.items = valid_modes;
2278 2277
2279 if (uinfo->value.enumerated.item >= i) 2278 if (uinfo->value.enumerated.item >= valid_modes)
2280 uinfo->value.enumerated.item = i - 1; 2279 uinfo->value.enumerated.item = valid_modes - 1;
2281 2280
2282 strcpy(uinfo->value.enumerated.name, 2281 strcpy(uinfo->value.enumerated.name,
2283 mode_names[uinfo->value.enumerated.item]); 2282 mode_names[mode_map[uinfo->value.enumerated.item]]);
2284 2283
2285 return 0; 2284 return 0;
2286} 2285}
@@ -2291,7 +2290,7 @@ static int snd_asihpi_cmode_get(struct snd_kcontrol *kcontrol,
2291 u32 h_control = kcontrol->private_value; 2290 u32 h_control = kcontrol->private_value;
2292 u16 mode; 2291 u16 mode;
2293 2292
2294 if (hpi_channel_mode_get(ss, h_control, &mode)) 2293 if (hpi_channel_mode_get(h_control, &mode))
2295 mode = 1; 2294 mode = 1;
2296 2295
2297 ucontrol->value.enumerated.item[0] = mode - 1; 2296 ucontrol->value.enumerated.item[0] = mode - 1;
@@ -2307,7 +2306,7 @@ static int snd_asihpi_cmode_put(struct snd_kcontrol *kcontrol,
2307 2306
2308 change = 1; 2307 change = 1;
2309 2308
2310 hpi_handle_error(hpi_channel_mode_set(ss, h_control, 2309 hpi_handle_error(hpi_channel_mode_set(h_control,
2311 ucontrol->value.enumerated.item[0] + 1)); 2310 ucontrol->value.enumerated.item[0] + 1));
2312 return change; 2311 return change;
2313} 2312}
@@ -2319,7 +2318,7 @@ static int __devinit snd_asihpi_cmode_add(struct snd_card_asihpi *asihpi,
2319 struct snd_card *card = asihpi->card; 2318 struct snd_card *card = asihpi->card;
2320 struct snd_kcontrol_new snd_control; 2319 struct snd_kcontrol_new snd_control;
2321 2320
2322 asihpi_ctl_init(&snd_control, hpi_ctl, "channel mode"); 2321 asihpi_ctl_init(&snd_control, hpi_ctl, "Mode");
2323 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE; 2322 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
2324 snd_control.info = snd_asihpi_cmode_info; 2323 snd_control.info = snd_asihpi_cmode_info;
2325 snd_control.get = snd_asihpi_cmode_get; 2324 snd_control.get = snd_asihpi_cmode_get;
@@ -2331,15 +2330,12 @@ static int __devinit snd_asihpi_cmode_add(struct snd_card_asihpi *asihpi,
2331/*------------------------------------------------------------ 2330/*------------------------------------------------------------
2332 Sampleclock source controls 2331 Sampleclock source controls
2333 ------------------------------------------------------------*/ 2332 ------------------------------------------------------------*/
2334 2333static char *sampleclock_sources[MAX_CLOCKSOURCES] = {
2335static char *sampleclock_sources[MAX_CLOCKSOURCES] = 2334 "N/A", "Local PLL", "Digital Sync", "Word External", "Word Header",
2336 { "N/A", "local PLL", "AES/EBU sync", "word external", "word header", 2335 "SMPTE", "Digital1", "Auto", "Network", "Invalid",
2337 "SMPTE", "AES/EBU in1", "auto", "network", "invalid", 2336 "Prev Module",
2338 "prev module", 2337 "Digital2", "Digital3", "Digital4", "Digital5",
2339 "AES/EBU in2", "AES/EBU in3", "AES/EBU in4", "AES/EBU in5", 2338 "Digital6", "Digital7", "Digital8"};
2340 "AES/EBU in6", "AES/EBU in7", "AES/EBU in8"};
2341
2342
2343 2339
2344static int snd_asihpi_clksrc_info(struct snd_kcontrol *kcontrol, 2340static int snd_asihpi_clksrc_info(struct snd_kcontrol *kcontrol,
2345 struct snd_ctl_elem_info *uinfo) 2341 struct snd_ctl_elem_info *uinfo)
@@ -2371,11 +2367,11 @@ static int snd_asihpi_clksrc_get(struct snd_kcontrol *kcontrol,
2371 int i; 2367 int i;
2372 2368
2373 ucontrol->value.enumerated.item[0] = 0; 2369 ucontrol->value.enumerated.item[0] = 0;
2374 if (hpi_sample_clock_get_source(ss, h_control, &source)) 2370 if (hpi_sample_clock_get_source(h_control, &source))
2375 source = 0; 2371 source = 0;
2376 2372
2377 if (source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT) 2373 if (source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT)
2378 if (hpi_sample_clock_get_source_index(ss, h_control, &srcindex)) 2374 if (hpi_sample_clock_get_source_index(h_control, &srcindex))
2379 srcindex = 0; 2375 srcindex = 0;
2380 2376
2381 for (i = 0; i < clkcache->count; i++) 2377 for (i = 0; i < clkcache->count; i++)
@@ -2402,11 +2398,11 @@ static int snd_asihpi_clksrc_put(struct snd_kcontrol *kcontrol,
2402 if (item >= clkcache->count) 2398 if (item >= clkcache->count)
2403 item = clkcache->count-1; 2399 item = clkcache->count-1;
2404 2400
2405 hpi_handle_error(hpi_sample_clock_set_source(ss, 2401 hpi_handle_error(hpi_sample_clock_set_source(
2406 h_control, clkcache->s[item].source)); 2402 h_control, clkcache->s[item].source));
2407 2403
2408 if (clkcache->s[item].source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT) 2404 if (clkcache->s[item].source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT)
2409 hpi_handle_error(hpi_sample_clock_set_source_index(ss, 2405 hpi_handle_error(hpi_sample_clock_set_source_index(
2410 h_control, clkcache->s[item].index)); 2406 h_control, clkcache->s[item].index));
2411 return change; 2407 return change;
2412} 2408}
@@ -2434,7 +2430,7 @@ static int snd_asihpi_clklocal_get(struct snd_kcontrol *kcontrol,
2434 u32 rate; 2430 u32 rate;
2435 u16 e; 2431 u16 e;
2436 2432
2437 e = hpi_sample_clock_get_local_rate(ss, h_control, &rate); 2433 e = hpi_sample_clock_get_local_rate(h_control, &rate);
2438 if (!e) 2434 if (!e)
2439 ucontrol->value.integer.value[0] = rate; 2435 ucontrol->value.integer.value[0] = rate;
2440 else 2436 else
@@ -2452,7 +2448,7 @@ static int snd_asihpi_clklocal_put(struct snd_kcontrol *kcontrol,
2452 asihpi->mixer_clkrate[addr][1] != right; 2448 asihpi->mixer_clkrate[addr][1] != right;
2453 */ 2449 */
2454 change = 1; 2450 change = 1;
2455 hpi_handle_error(hpi_sample_clock_set_local_rate(ss, h_control, 2451 hpi_handle_error(hpi_sample_clock_set_local_rate(h_control,
2456 ucontrol->value.integer.value[0])); 2452 ucontrol->value.integer.value[0]));
2457 return change; 2453 return change;
2458} 2454}
@@ -2476,7 +2472,7 @@ static int snd_asihpi_clkrate_get(struct snd_kcontrol *kcontrol,
2476 u32 rate; 2472 u32 rate;
2477 u16 e; 2473 u16 e;
2478 2474
2479 e = hpi_sample_clock_get_sample_rate(ss, h_control, &rate); 2475 e = hpi_sample_clock_get_sample_rate(h_control, &rate);
2480 if (!e) 2476 if (!e)
2481 ucontrol->value.integer.value[0] = rate; 2477 ucontrol->value.integer.value[0] = rate;
2482 else 2478 else
@@ -2501,7 +2497,7 @@ static int __devinit snd_asihpi_sampleclock_add(struct snd_card_asihpi *asihpi,
2501 clkcache->has_local = 0; 2497 clkcache->has_local = 0;
2502 2498
2503 for (i = 0; i <= HPI_SAMPLECLOCK_SOURCE_LAST; i++) { 2499 for (i = 0; i <= HPI_SAMPLECLOCK_SOURCE_LAST; i++) {
2504 if (hpi_sample_clock_query_source(ss, hSC, 2500 if (hpi_sample_clock_query_source(hSC,
2505 i, &source)) 2501 i, &source))
2506 break; 2502 break;
2507 clkcache->s[i].source = source; 2503 clkcache->s[i].source = source;
@@ -2515,7 +2511,7 @@ static int __devinit snd_asihpi_sampleclock_add(struct snd_card_asihpi *asihpi,
2515 if (has_aes_in) 2511 if (has_aes_in)
2516 /* already will have picked up index 0 above */ 2512 /* already will have picked up index 0 above */
2517 for (j = 1; j < 8; j++) { 2513 for (j = 1; j < 8; j++) {
2518 if (hpi_sample_clock_query_source_index(ss, hSC, 2514 if (hpi_sample_clock_query_source_index(hSC,
2519 j, HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT, 2515 j, HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT,
2520 &source)) 2516 &source))
2521 break; 2517 break;
@@ -2528,7 +2524,7 @@ static int __devinit snd_asihpi_sampleclock_add(struct snd_card_asihpi *asihpi,
2528 } 2524 }
2529 clkcache->count = i; 2525 clkcache->count = i;
2530 2526
2531 asihpi_ctl_init(&snd_control, hpi_ctl, "source"); 2527 asihpi_ctl_init(&snd_control, hpi_ctl, "Source");
2532 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE ; 2528 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE ;
2533 snd_control.info = snd_asihpi_clksrc_info; 2529 snd_control.info = snd_asihpi_clksrc_info;
2534 snd_control.get = snd_asihpi_clksrc_get; 2530 snd_control.get = snd_asihpi_clksrc_get;
@@ -2538,7 +2534,7 @@ static int __devinit snd_asihpi_sampleclock_add(struct snd_card_asihpi *asihpi,
2538 2534
2539 2535
2540 if (clkcache->has_local) { 2536 if (clkcache->has_local) {
2541 asihpi_ctl_init(&snd_control, hpi_ctl, "local_rate"); 2537 asihpi_ctl_init(&snd_control, hpi_ctl, "Localrate");
2542 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE ; 2538 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE ;
2543 snd_control.info = snd_asihpi_clklocal_info; 2539 snd_control.info = snd_asihpi_clklocal_info;
2544 snd_control.get = snd_asihpi_clklocal_get; 2540 snd_control.get = snd_asihpi_clklocal_get;
@@ -2549,7 +2545,7 @@ static int __devinit snd_asihpi_sampleclock_add(struct snd_card_asihpi *asihpi,
2549 return -EINVAL; 2545 return -EINVAL;
2550 } 2546 }
2551 2547
2552 asihpi_ctl_init(&snd_control, hpi_ctl, "rate"); 2548 asihpi_ctl_init(&snd_control, hpi_ctl, "Rate");
2553 snd_control.access = 2549 snd_control.access =
2554 SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ; 2550 SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ;
2555 snd_control.info = snd_asihpi_clkrate_info; 2551 snd_control.info = snd_asihpi_clkrate_info;
@@ -2571,10 +2567,10 @@ static int __devinit snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi)
2571 2567
2572 if (snd_BUG_ON(!asihpi)) 2568 if (snd_BUG_ON(!asihpi))
2573 return -EINVAL; 2569 return -EINVAL;
2574 strcpy(card->mixername, "asihpi mixer"); 2570 strcpy(card->mixername, "Asihpi Mixer");
2575 2571
2576 err = 2572 err =
2577 hpi_mixer_open(ss, asihpi->adapter_index, 2573 hpi_mixer_open(asihpi->adapter_index,
2578 &asihpi->h_mixer); 2574 &asihpi->h_mixer);
2579 hpi_handle_error(err); 2575 hpi_handle_error(err);
2580 if (err) 2576 if (err)
@@ -2585,7 +2581,7 @@ static int __devinit snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi)
2585 2581
2586 for (idx = 0; idx < 2000; idx++) { 2582 for (idx = 0; idx < 2000; idx++) {
2587 err = hpi_mixer_get_control_by_index( 2583 err = hpi_mixer_get_control_by_index(
2588 ss, asihpi->h_mixer, 2584 asihpi->h_mixer,
2589 idx, 2585 idx,
2590 &hpi_ctl.src_node_type, 2586 &hpi_ctl.src_node_type,
2591 &hpi_ctl.src_node_index, 2587 &hpi_ctl.src_node_index,
@@ -2597,7 +2593,7 @@ static int __devinit snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi)
2597 if (err == HPI_ERROR_CONTROL_DISABLED) { 2593 if (err == HPI_ERROR_CONTROL_DISABLED) {
2598 if (mixer_dump) 2594 if (mixer_dump)
2599 snd_printk(KERN_INFO 2595 snd_printk(KERN_INFO
2600 "disabled HPI control(%d)\n", 2596 "Disabled HPI Control(%d)\n",
2601 idx); 2597 idx);
2602 continue; 2598 continue;
2603 } else 2599 } else
@@ -2662,7 +2658,7 @@ static int __devinit snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi)
2662 default: 2658 default:
2663 if (mixer_dump) 2659 if (mixer_dump)
2664 snd_printk(KERN_INFO 2660 snd_printk(KERN_INFO
2665 "untranslated HPI control" 2661 "Untranslated HPI Control"
2666 "(%d) %d %d %d %d %d\n", 2662 "(%d) %d %d %d %d %d\n",
2667 idx, 2663 idx,
2668 hpi_ctl.control_type, 2664 hpi_ctl.control_type,
@@ -2712,14 +2708,14 @@ snd_asihpi_proc_read(struct snd_info_entry *entry,
2712 version & 0x7, 2708 version & 0x7,
2713 ((version >> 13) * 100) + ((version >> 7) & 0x3f)); 2709 ((version >> 13) * 100) + ((version >> 7) & 0x3f));
2714 2710
2715 err = hpi_mixer_get_control(ss, asihpi->h_mixer, 2711 err = hpi_mixer_get_control(asihpi->h_mixer,
2716 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0, 2712 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
2717 HPI_CONTROL_SAMPLECLOCK, &h_control); 2713 HPI_CONTROL_SAMPLECLOCK, &h_control);
2718 2714
2719 if (!err) { 2715 if (!err) {
2720 err = hpi_sample_clock_get_sample_rate(ss, 2716 err = hpi_sample_clock_get_sample_rate(
2721 h_control, &rate); 2717 h_control, &rate);
2722 err += hpi_sample_clock_get_source(ss, h_control, &source); 2718 err += hpi_sample_clock_get_source(h_control, &source);
2723 2719
2724 if (!err) 2720 if (!err)
2725 snd_iprintf(buffer, "sample_clock=%d_hz, source %s\n", 2721 snd_iprintf(buffer, "sample_clock=%d_hz, source %s\n",
@@ -2841,15 +2837,17 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev,
2841 if (err < 0) 2837 if (err < 0)
2842 return err; 2838 return err;
2843 snd_printk(KERN_WARNING 2839 snd_printk(KERN_WARNING
2844 "**** WARNING **** adapter index %d->ALSA index %d\n", 2840 "**** WARNING **** Adapter index %d->ALSA index %d\n",
2845 hpi_card->index, card->number); 2841 hpi_card->index, card->number);
2846 } 2842 }
2847 2843
2844 snd_card_set_dev(card, &pci_dev->dev);
2845
2848 asihpi = (struct snd_card_asihpi *) card->private_data; 2846 asihpi = (struct snd_card_asihpi *) card->private_data;
2849 asihpi->card = card; 2847 asihpi->card = card;
2850 asihpi->pci = hpi_card->pci; 2848 asihpi->pci = pci_dev;
2851 asihpi->adapter_index = hpi_card->index; 2849 asihpi->adapter_index = hpi_card->index;
2852 hpi_handle_error(hpi_adapter_get_info(ss, 2850 hpi_handle_error(hpi_adapter_get_info(
2853 asihpi->adapter_index, 2851 asihpi->adapter_index,
2854 &asihpi->num_outstreams, 2852 &asihpi->num_outstreams,
2855 &asihpi->num_instreams, 2853 &asihpi->num_instreams,
@@ -2859,7 +2857,7 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev,
2859 version = asihpi->version; 2857 version = asihpi->version;
2860 snd_printk(KERN_INFO "adapter ID=%4X index=%d num_outstreams=%d " 2858 snd_printk(KERN_INFO "adapter ID=%4X index=%d num_outstreams=%d "
2861 "num_instreams=%d S/N=%d\n" 2859 "num_instreams=%d S/N=%d\n"
2862 "hw version %c%d DSP code version %03d\n", 2860 "Hw Version %c%d DSP code version %03d\n",
2863 asihpi->type, asihpi->adapter_index, 2861 asihpi->type, asihpi->adapter_index,
2864 asihpi->num_outstreams, 2862 asihpi->num_outstreams,
2865 asihpi->num_instreams, asihpi->serial_number, 2863 asihpi->num_instreams, asihpi->serial_number,
@@ -2871,33 +2869,33 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev,
2871 if (pcm_substreams < asihpi->num_instreams) 2869 if (pcm_substreams < asihpi->num_instreams)
2872 pcm_substreams = asihpi->num_instreams; 2870 pcm_substreams = asihpi->num_instreams;
2873 2871
2874 err = hpi_adapter_get_property(ss, asihpi->adapter_index, 2872 err = hpi_adapter_get_property(asihpi->adapter_index,
2875 HPI_ADAPTER_PROPERTY_CAPS1, 2873 HPI_ADAPTER_PROPERTY_CAPS1,
2876 NULL, &asihpi->support_grouping); 2874 NULL, &asihpi->support_grouping);
2877 if (err) 2875 if (err)
2878 asihpi->support_grouping = 0; 2876 asihpi->support_grouping = 0;
2879 2877
2880 err = hpi_adapter_get_property(ss, asihpi->adapter_index, 2878 err = hpi_adapter_get_property(asihpi->adapter_index,
2881 HPI_ADAPTER_PROPERTY_CAPS2, 2879 HPI_ADAPTER_PROPERTY_CAPS2,
2882 &asihpi->support_mrx, NULL); 2880 &asihpi->support_mrx, NULL);
2883 if (err) 2881 if (err)
2884 asihpi->support_mrx = 0; 2882 asihpi->support_mrx = 0;
2885 2883
2886 err = hpi_adapter_get_property(ss, asihpi->adapter_index, 2884 err = hpi_adapter_get_property(asihpi->adapter_index,
2887 HPI_ADAPTER_PROPERTY_INTERVAL, 2885 HPI_ADAPTER_PROPERTY_INTERVAL,
2888 NULL, &asihpi->update_interval_frames); 2886 NULL, &asihpi->update_interval_frames);
2889 if (err) 2887 if (err)
2890 asihpi->update_interval_frames = 512; 2888 asihpi->update_interval_frames = 512;
2891 2889
2892 hpi_handle_error(hpi_instream_open(ss, asihpi->adapter_index, 2890 hpi_handle_error(hpi_instream_open(asihpi->adapter_index,
2893 0, &h_stream)); 2891 0, &h_stream));
2894 2892
2895 err = hpi_instream_host_buffer_free(ss, h_stream); 2893 err = hpi_instream_host_buffer_free(h_stream);
2896 asihpi->support_mmap = (!err); 2894 asihpi->support_mmap = (!err);
2897 2895
2898 hpi_handle_error(hpi_instream_close(ss, h_stream)); 2896 hpi_handle_error(hpi_instream_close(h_stream));
2899 2897
2900 err = hpi_adapter_get_property(ss, asihpi->adapter_index, 2898 err = hpi_adapter_get_property(asihpi->adapter_index,
2901 HPI_ADAPTER_PROPERTY_CURCHANNELS, 2899 HPI_ADAPTER_PROPERTY_CURCHANNELS,
2902 &asihpi->in_max_chans, &asihpi->out_max_chans); 2900 &asihpi->in_max_chans, &asihpi->out_max_chans);
2903 if (err) { 2901 if (err) {
@@ -2923,13 +2921,13 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev,
2923 goto __nodev; 2921 goto __nodev;
2924 } 2922 }
2925 2923
2926 err = hpi_mixer_get_control(ss, asihpi->h_mixer, 2924 err = hpi_mixer_get_control(asihpi->h_mixer,
2927 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0, 2925 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
2928 HPI_CONTROL_SAMPLECLOCK, &h_control); 2926 HPI_CONTROL_SAMPLECLOCK, &h_control);
2929 2927
2930 if (!err) 2928 if (!err)
2931 err = hpi_sample_clock_set_local_rate( 2929 err = hpi_sample_clock_set_local_rate(
2932 ss, h_control, adapter_fs); 2930 h_control, adapter_fs);
2933 2931
2934 snd_asihpi_proc_init(asihpi); 2932 snd_asihpi_proc_init(asihpi);
2935 2933
diff --git a/sound/pci/asihpi/hpi.h b/sound/pci/asihpi/hpi.h
index 23399d02f666..6fc025c448de 100644
--- a/sound/pci/asihpi/hpi.h
+++ b/sound/pci/asihpi/hpi.h
@@ -24,17 +24,10 @@
24 24
25 The HPI is a low-level hardware abstraction layer to all 25 The HPI is a low-level hardware abstraction layer to all
26 AudioScience digital audio adapters 26 AudioScience digital audio adapters
27*/
28/*
29 You must define one operating system that the HPI is to be compiled under
30 HPI_OS_WIN32_USER 32bit Windows
31 HPI_OS_DSP_C6000 DSP TI C6000 (automatically set)
32 HPI_OS_WDM Windows WDM kernel driver
33 HPI_OS_LINUX Linux userspace
34 HPI_OS_LINUX_KERNEL Linux kernel (automatically set)
35 27
36(C) Copyright AudioScience Inc. 1998-2010 28(C) Copyright AudioScience Inc. 1998-2010
37******************************************************************************/ 29*/
30
38#ifndef _HPI_H_ 31#ifndef _HPI_H_
39#define _HPI_H_ 32#define _HPI_H_
40/* HPI Version 33/* HPI Version
@@ -50,20 +43,20 @@ i.e 3.05.02 is a development version
50#define HPI_VER_RELEASE(v) ((int)(v & 0xFF)) 43#define HPI_VER_RELEASE(v) ((int)(v & 0xFF))
51 44
52/* Use single digits for versions less that 10 to avoid octal. */ 45/* Use single digits for versions less that 10 to avoid octal. */
53#define HPI_VER HPI_VERSION_CONSTRUCTOR(4L, 4, 1) 46#define HPI_VER HPI_VERSION_CONSTRUCTOR(4L, 6, 0)
54#define HPI_VER_STRING "4.04.01" 47#define HPI_VER_STRING "4.06.00"
55 48
56/* Library version as documented in hpi-api-versions.txt */ 49/* Library version as documented in hpi-api-versions.txt */
57#define HPI_LIB_VER HPI_VERSION_CONSTRUCTOR(9, 0, 0) 50#define HPI_LIB_VER HPI_VERSION_CONSTRUCTOR(9, 0, 0)
58 51
59#include <linux/types.h> 52#include <linux/types.h>
60#define HPI_EXCLUDE_DEPRECATED 53#define HPI_BUILD_EXCLUDE_DEPRECATED
54#define HPI_BUILD_KERNEL_MODE
61 55
62/******************************************************************************/ 56/******************************************************************************/
63/******************************************************************************/
64/******** HPI API DEFINITIONS *****/ 57/******** HPI API DEFINITIONS *****/
65/******************************************************************************/ 58/******************************************************************************/
66/******************************************************************************/ 59
67/*******************************************/ 60/*******************************************/
68/** Audio format types 61/** Audio format types
69\ingroup stream 62\ingroup stream
@@ -174,7 +167,6 @@ The range is +1.0 to -1.0, which corresponds to digital fullscale.
174 HPI_FORMAT_UNDEFINED = 0xffff 167 HPI_FORMAT_UNDEFINED = 0xffff
175}; 168};
176 169
177/******************************************* in/out Stream states */
178/*******************************************/ 170/*******************************************/
179/** Stream States 171/** Stream States
180\ingroup stream 172\ingroup stream
@@ -194,7 +186,7 @@ enum HPI_STREAM_STATES {
194 cards to be ready. */ 186 cards to be ready. */
195 HPI_STATE_WAIT = 6 187 HPI_STATE_WAIT = 6
196}; 188};
197/******************************************* mixer source node types */ 189/*******************************************/
198/** Source node types 190/** Source node types
199\ingroup mixer 191\ingroup mixer
200*/ 192*/
@@ -224,7 +216,7 @@ enum HPI_SOURCENODES {
224 /* AX6 max sourcenode types = 15 */ 216 /* AX6 max sourcenode types = 15 */
225}; 217};
226 218
227/******************************************* mixer dest node types */ 219/*******************************************/
228/** Destination node types 220/** Destination node types
229\ingroup mixer 221\ingroup mixer
230*/ 222*/
@@ -262,11 +254,11 @@ enum HPI_CONTROLS {
262 HPI_CONTROL_MUTE = 4, /*mute control - not used at present. */ 254 HPI_CONTROL_MUTE = 4, /*mute control - not used at present. */
263 HPI_CONTROL_MULTIPLEXER = 5, /**< multiplexer control. */ 255 HPI_CONTROL_MULTIPLEXER = 5, /**< multiplexer control. */
264 256
265 HPI_CONTROL_AESEBU_TRANSMITTER = 6, /**< AES/EBU transmitter control. */ 257 HPI_CONTROL_AESEBU_TRANSMITTER = 6, /**< AES/EBU transmitter control */
266 HPI_CONTROL_AESEBUTX = HPI_CONTROL_AESEBU_TRANSMITTER, 258 HPI_CONTROL_AESEBUTX = 6, /* HPI_CONTROL_AESEBU_TRANSMITTER */
267 259
268 HPI_CONTROL_AESEBU_RECEIVER = 7, /**< AES/EBU receiver control. */ 260 HPI_CONTROL_AESEBU_RECEIVER = 7, /**< AES/EBU receiver control. */
269 HPI_CONTROL_AESEBURX = HPI_CONTROL_AESEBU_RECEIVER, 261 HPI_CONTROL_AESEBURX = 7, /* HPI_CONTROL_AESEBU_RECEIVER */
270 262
271 HPI_CONTROL_LEVEL = 8, /**< level/trim control - works in d_bu. */ 263 HPI_CONTROL_LEVEL = 8, /**< level/trim control - works in d_bu. */
272 HPI_CONTROL_TUNER = 9, /**< tuner control. */ 264 HPI_CONTROL_TUNER = 9, /**< tuner control. */
@@ -281,7 +273,7 @@ enum HPI_CONTROLS {
281 HPI_CONTROL_SAMPLECLOCK = 17, /**< sample clock control. */ 273 HPI_CONTROL_SAMPLECLOCK = 17, /**< sample clock control. */
282 HPI_CONTROL_MICROPHONE = 18, /**< microphone control. */ 274 HPI_CONTROL_MICROPHONE = 18, /**< microphone control. */
283 HPI_CONTROL_PARAMETRIC_EQ = 19, /**< parametric EQ control. */ 275 HPI_CONTROL_PARAMETRIC_EQ = 19, /**< parametric EQ control. */
284 HPI_CONTROL_EQUALIZER = HPI_CONTROL_PARAMETRIC_EQ, 276 HPI_CONTROL_EQUALIZER = 19, /*HPI_CONTROL_PARAMETRIC_EQ */
285 277
286 HPI_CONTROL_COMPANDER = 20, /**< compander control. */ 278 HPI_CONTROL_COMPANDER = 20, /**< compander control. */
287 HPI_CONTROL_COBRANET = 21, /**< cobranet control. */ 279 HPI_CONTROL_COBRANET = 21, /**< cobranet control. */
@@ -296,10 +288,7 @@ enum HPI_CONTROLS {
296/* WARNING types 256 or greater impact bit packing in all AX6 DSP code */ 288/* WARNING types 256 or greater impact bit packing in all AX6 DSP code */
297}; 289};
298 290
299/* Shorthand names that match attribute names */ 291/*******************************************/
300
301/******************************************* ADAPTER ATTRIBUTES ****/
302
303/** Adapter properties 292/** Adapter properties
304These are used in HPI_AdapterSetProperty() and HPI_AdapterGetProperty() 293These are used in HPI_AdapterSetProperty() and HPI_AdapterGetProperty()
305\ingroup adapter 294\ingroup adapter
@@ -330,12 +319,21 @@ by the driver and is not passed on to the DSP at all.
330Indicates the state of the adapter's SSX2 setting. This setting is stored in 319Indicates the state of the adapter's SSX2 setting. This setting is stored in
331non-volatile memory on the adapter. A typical call sequence would be to use 320non-volatile memory on the adapter. A typical call sequence would be to use
332HPI_ADAPTER_PROPERTY_SSX2_SETTING to set SSX2 on the adapter and then to reload 321HPI_ADAPTER_PROPERTY_SSX2_SETTING to set SSX2 on the adapter and then to reload
333the driver. The driver would query HPI_ADAPTER_PROPERTY_SSX2_SETTING during startup 322the driver. The driver would query HPI_ADAPTER_PROPERTY_SSX2_SETTING during
334and if SSX2 is set, it would then call HPI_ADAPTER_PROPERTY_ENABLE_SSX2 to enable 323startup and if SSX2 is set, it would then call HPI_ADAPTER_PROPERTY_ENABLE_SSX2
335SSX2 stream mapping within the kernel level of the driver. 324to enable SSX2 stream mapping within the kernel level of the driver.
336*/ 325*/
337 HPI_ADAPTER_PROPERTY_SSX2_SETTING = 4, 326 HPI_ADAPTER_PROPERTY_SSX2_SETTING = 4,
338 327
328/** Enables/disables PCI(e) IRQ.
329A setting of 0 indicates that no interrupts are being generated. A DSP boot
330this property is set to 0. Setting to a non-zero value specifies the number
331of frames of audio that should be processed between interrupts. This property
332should be set to multiple of the mixer interval as read back from the
333HPI_ADAPTER_PROPERTY_INTERVAL property.
334*/
335 HPI_ADAPTER_PROPERTY_IRQ_RATE = 5,
336
339/** Base number for readonly properties */ 337/** Base number for readonly properties */
340 HPI_ADAPTER_PROPERTY_READONLYBASE = 256, 338 HPI_ADAPTER_PROPERTY_READONLYBASE = 256,
341 339
@@ -440,21 +438,30 @@ return value is true (1) or false (0). If the current adapter
440mode is MONO SSX2 is disabled, even though this property will 438mode is MONO SSX2 is disabled, even though this property will
441return true. 439return true.
442*/ 440*/
443 HPI_ADAPTER_PROPERTY_SUPPORTS_SSX2 = 271 441 HPI_ADAPTER_PROPERTY_SUPPORTS_SSX2 = 271,
442/** Readonly supports PCI(e) IRQ.
443Indicates that the adapter in it's current mode supports interrupts
444across the host bus. Note, this does not imply that interrupts are
445enabled. Instead it indicates that they can be enabled.
446*/
447 HPI_ADAPTER_PROPERTY_SUPPORTS_IRQ = 272
444}; 448};
445 449
446/** Adapter mode commands 450/** Adapter mode commands
447 451
448Used in wQueryOrSet field of HPI_AdapterSetModeEx(). 452Used in wQueryOrSet parameter of HPI_AdapterSetModeEx().
449\ingroup adapter 453\ingroup adapter
450*/ 454*/
451enum HPI_ADAPTER_MODE_CMDS { 455enum HPI_ADAPTER_MODE_CMDS {
456 /** Set the mode to the given parameter */
452 HPI_ADAPTER_MODE_SET = 0, 457 HPI_ADAPTER_MODE_SET = 0,
458 /** Return 0 or error depending whether mode is valid,
459 but don't set the mode */
453 HPI_ADAPTER_MODE_QUERY = 1 460 HPI_ADAPTER_MODE_QUERY = 1
454}; 461};
455 462
456/** Adapter Modes 463/** Adapter Modes
457 These are used by HPI_AdapterSetModeEx() 464 These are used by HPI_AdapterSetModeEx()
458 465
459\warning - more than 16 possible modes breaks 466\warning - more than 16 possible modes breaks
460a bitmask in the Windows WAVE DLL 467a bitmask in the Windows WAVE DLL
@@ -629,10 +636,13 @@ enum HPI_MIXER_STORE_COMMAND {
629 HPI_MIXER_STORE_SAVE_SINGLE = 6 636 HPI_MIXER_STORE_SAVE_SINGLE = 6
630}; 637};
631 638
632/************************************* CONTROL ATTRIBUTE VALUES ****/ 639/****************************/
640/* CONTROL ATTRIBUTE VALUES */
641/****************************/
642
633/** Used by mixer plugin enable functions 643/** Used by mixer plugin enable functions
634 644
635E.g. HPI_ParametricEQ_SetState() 645E.g. HPI_ParametricEq_SetState()
636\ingroup mixer 646\ingroup mixer
637*/ 647*/
638enum HPI_SWITCH_STATES { 648enum HPI_SWITCH_STATES {
@@ -641,6 +651,7 @@ enum HPI_SWITCH_STATES {
641}; 651};
642 652
643/* Volume control special gain values */ 653/* Volume control special gain values */
654
644/** volumes units are 100ths of a dB 655/** volumes units are 100ths of a dB
645\ingroup volume 656\ingroup volume
646*/ 657*/
@@ -650,6 +661,11 @@ enum HPI_SWITCH_STATES {
650*/ 661*/
651#define HPI_GAIN_OFF (-100 * HPI_UNITS_PER_dB) 662#define HPI_GAIN_OFF (-100 * HPI_UNITS_PER_dB)
652 663
664/** channel mask specifying all channels
665\ingroup volume
666*/
667#define HPI_BITMASK_ALL_CHANNELS (0xFFFFFFFF)
668
653/** value returned for no signal 669/** value returned for no signal
654\ingroup meter 670\ingroup meter
655*/ 671*/
@@ -667,7 +683,7 @@ enum HPI_VOLUME_AUTOFADES {
667 683
668/** The physical encoding format of the AESEBU I/O. 684/** The physical encoding format of the AESEBU I/O.
669 685
670Used in HPI_AESEBU_Transmitter_SetFormat(), HPI_AESEBU_Receiver_SetFormat() 686Used in HPI_Aesebu_Transmitter_SetFormat(), HPI_Aesebu_Receiver_SetFormat()
671along with related Get and Query functions 687along with related Get and Query functions
672\ingroup aestx 688\ingroup aestx
673*/ 689*/
@@ -680,7 +696,7 @@ enum HPI_AESEBU_FORMATS {
680 696
681/** AES/EBU error status bits 697/** AES/EBU error status bits
682 698
683Returned by HPI_AESEBU_Receiver_GetErrorStatus() 699Returned by HPI_Aesebu_Receiver_GetErrorStatus()
684\ingroup aesrx 700\ingroup aesrx
685*/ 701*/
686enum HPI_AESEBU_ERRORS { 702enum HPI_AESEBU_ERRORS {
@@ -767,14 +783,6 @@ enum HPI_TUNER_MODE_VALUES {
767 HPI_TUNER_MODE_RDS_RBDS = 2 /**< RDS - RBDS mode */ 783 HPI_TUNER_MODE_RDS_RBDS = 2 /**< RDS - RBDS mode */
768}; 784};
769 785
770/** Tuner Level settings
771\ingroup tuner
772*/
773enum HPI_TUNER_LEVEL {
774 HPI_TUNER_LEVEL_AVERAGE = 0,
775 HPI_TUNER_LEVEL_RAW = 1
776};
777
778/** Tuner Status Bits 786/** Tuner Status Bits
779 787
780These bitfield values are returned by a call to HPI_Tuner_GetStatus(). 788These bitfield values are returned by a call to HPI_Tuner_GetStatus().
@@ -783,13 +791,13 @@ Multiple fields are returned from a single call.
783*/ 791*/
784enum HPI_TUNER_STATUS_BITS { 792enum HPI_TUNER_STATUS_BITS {
785 HPI_TUNER_VIDEO_COLOR_PRESENT = 0x0001, /**< video color is present. */ 793 HPI_TUNER_VIDEO_COLOR_PRESENT = 0x0001, /**< video color is present. */
786 HPI_TUNER_VIDEO_IS_60HZ = 0x0020, /**< 60 hz video detected. */ 794 HPI_TUNER_VIDEO_IS_60HZ = 0x0020, /**< 60 hz video detected. */
787 HPI_TUNER_VIDEO_HORZ_SYNC_MISSING = 0x0040, /**< video HSYNC is missing. */ 795 HPI_TUNER_VIDEO_HORZ_SYNC_MISSING = 0x0040, /**< video HSYNC is missing. */
788 HPI_TUNER_VIDEO_STATUS_VALID = 0x0100, /**< video status is valid. */ 796 HPI_TUNER_VIDEO_STATUS_VALID = 0x0100, /**< video status is valid. */
789 HPI_TUNER_PLL_LOCKED = 0x1000, /**< the tuner's PLL is locked. */ 797 HPI_TUNER_DIGITAL = 0x0200, /**< tuner reports digital programming. */
790 HPI_TUNER_FM_STEREO = 0x2000, /**< tuner reports back FM stereo. */ 798 HPI_TUNER_MULTIPROGRAM = 0x0400, /**< tuner reports multiple programs. */
791 HPI_TUNER_DIGITAL = 0x0200, /**< tuner reports digital programming. */ 799 HPI_TUNER_PLL_LOCKED = 0x1000, /**< the tuner's PLL is locked. */
792 HPI_TUNER_MULTIPROGRAM = 0x0400 /**< tuner reports multiple programs. */ 800 HPI_TUNER_FM_STEREO = 0x2000 /**< tuner reports back FM stereo. */
793}; 801};
794 802
795/** Channel Modes 803/** Channel Modes
@@ -839,7 +847,7 @@ enum HPI_SAMPLECLOCK_SOURCES {
839 HPI_SAMPLECLOCK_SOURCE_LAST = 10 847 HPI_SAMPLECLOCK_SOURCE_LAST = 10
840}; 848};
841 849
842/** Equalizer filter types. Used by HPI_ParametricEQ_SetBand() 850/** Equalizer filter types. Used by HPI_ParametricEq_SetBand()
843\ingroup parmeq 851\ingroup parmeq
844*/ 852*/
845enum HPI_FILTER_TYPE { 853enum HPI_FILTER_TYPE {
@@ -882,7 +890,7 @@ enum HPI_ERROR_CODES {
882 HPI_ERROR_INVALID_OBJ = 101, 890 HPI_ERROR_INVALID_OBJ = 101,
883 /** Function does not exist. */ 891 /** Function does not exist. */
884 HPI_ERROR_INVALID_FUNC = 102, 892 HPI_ERROR_INVALID_FUNC = 102,
885 /** The specified object (adapter/Stream) does not exist. */ 893 /** The specified object does not exist. */
886 HPI_ERROR_INVALID_OBJ_INDEX = 103, 894 HPI_ERROR_INVALID_OBJ_INDEX = 103,
887 /** Trying to access an object that has not been opened yet. */ 895 /** Trying to access an object that has not been opened yet. */
888 HPI_ERROR_OBJ_NOT_OPEN = 104, 896 HPI_ERROR_OBJ_NOT_OPEN = 104,
@@ -890,8 +898,7 @@ enum HPI_ERROR_CODES {
890 HPI_ERROR_OBJ_ALREADY_OPEN = 105, 898 HPI_ERROR_OBJ_ALREADY_OPEN = 105,
891 /** PCI, ISA resource not valid. */ 899 /** PCI, ISA resource not valid. */
892 HPI_ERROR_INVALID_RESOURCE = 106, 900 HPI_ERROR_INVALID_RESOURCE = 106,
893 /** GetInfo call from SubSysFindAdapters failed. */ 901 /* HPI_ERROR_SUBSYSFINDADAPTERS_GETINFO= 107 */
894 HPI_ERROR_SUBSYSFINDADAPTERS_GETINFO = 107,
895 /** Default response was never updated with actual error code. */ 902 /** Default response was never updated with actual error code. */
896 HPI_ERROR_INVALID_RESPONSE = 108, 903 HPI_ERROR_INVALID_RESPONSE = 108,
897 /** wSize field of response was not updated, 904 /** wSize field of response was not updated,
@@ -899,38 +906,44 @@ enum HPI_ERROR_CODES {
899 HPI_ERROR_PROCESSING_MESSAGE = 109, 906 HPI_ERROR_PROCESSING_MESSAGE = 109,
900 /** The network did not respond in a timely manner. */ 907 /** The network did not respond in a timely manner. */
901 HPI_ERROR_NETWORK_TIMEOUT = 110, 908 HPI_ERROR_NETWORK_TIMEOUT = 110,
902 /** An HPI handle is invalid (uninitialised?). */ 909 /* An HPI handle is invalid (uninitialised?). */
903 HPI_ERROR_INVALID_HANDLE = 111, 910 HPI_ERROR_INVALID_HANDLE = 111,
904 /** A function or attribute has not been implemented yet. */ 911 /** A function or attribute has not been implemented yet. */
905 HPI_ERROR_UNIMPLEMENTED = 112, 912 HPI_ERROR_UNIMPLEMENTED = 112,
906 /** There are too many clients attempting to access a network resource. */ 913 /** There are too many clients attempting
914 to access a network resource. */
907 HPI_ERROR_NETWORK_TOO_MANY_CLIENTS = 113, 915 HPI_ERROR_NETWORK_TOO_MANY_CLIENTS = 113,
908 /** Response buffer passed to HPI_Message was smaller than returned response */ 916 /** Response buffer passed to HPI_Message
917 was smaller than returned response.
918 wSpecificError field of hpi response contains the required size.
919 */
909 HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL = 114, 920 HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL = 114,
910 /** The returned response did not match the sent message */ 921 /** The returned response did not match the sent message */
911 HPI_ERROR_RESPONSE_MISMATCH = 115, 922 HPI_ERROR_RESPONSE_MISMATCH = 115,
923 /** A control setting that should have been cached was not. */
924 HPI_ERROR_CONTROL_CACHING = 116,
925 /** A message buffer in the path to the adapter was smaller
926 than the message size.
927 wSpecificError field of hpi response contains the actual size.
928 */
929 HPI_ERROR_MESSAGE_BUFFER_TOO_SMALL = 117,
912 930
913 /** Too many adapters.*/ 931 /* HPI_ERROR_TOO_MANY_ADAPTERS= 200 */
914 HPI_ERROR_TOO_MANY_ADAPTERS = 200,
915 /** Bad adpater. */ 932 /** Bad adpater. */
916 HPI_ERROR_BAD_ADAPTER = 201, 933 HPI_ERROR_BAD_ADAPTER = 201,
917 /** Adapter number out of range or not set properly. */ 934 /** Adapter number out of range or not set properly. */
918 HPI_ERROR_BAD_ADAPTER_NUMBER = 202, 935 HPI_ERROR_BAD_ADAPTER_NUMBER = 202,
919 /** 2 adapters with the same adapter number. */ 936 /** 2 adapters with the same adapter number. */
920 HPI_DUPLICATE_ADAPTER_NUMBER = 203, 937 HPI_ERROR_DUPLICATE_ADAPTER_NUMBER = 203,
921 /** DSP code failed to bootload. */ 938 /** DSP code failed to bootload. (unused?) */
922 HPI_ERROR_DSP_BOOTLOAD = 204, 939 HPI_ERROR_DSP_BOOTLOAD = 204,
923 /** Adapter failed DSP code self test. */
924 HPI_ERROR_DSP_SELFTEST = 205,
925 /** Couldn't find or open the DSP code file. */ 940 /** Couldn't find or open the DSP code file. */
926 HPI_ERROR_DSP_FILE_NOT_FOUND = 206, 941 HPI_ERROR_DSP_FILE_NOT_FOUND = 206,
927 /** Internal DSP hardware error. */ 942 /** Internal DSP hardware error. */
928 HPI_ERROR_DSP_HARDWARE = 207, 943 HPI_ERROR_DSP_HARDWARE = 207,
929 /** Could not allocate memory in DOS. */
930 HPI_ERROR_DOS_MEMORY_ALLOC = 208,
931 /** Could not allocate memory */ 944 /** Could not allocate memory */
932 HPI_ERROR_MEMORY_ALLOC = 208, 945 HPI_ERROR_MEMORY_ALLOC = 208,
933 /** Failed to correctly load/config PLD .*/ 946 /** Failed to correctly load/config PLD. (unused) */
934 HPI_ERROR_PLD_LOAD = 209, 947 HPI_ERROR_PLD_LOAD = 209,
935 /** Unexpected end of file, block length too big etc. */ 948 /** Unexpected end of file, block length too big etc. */
936 HPI_ERROR_DSP_FILE_FORMAT = 210, 949 HPI_ERROR_DSP_FILE_FORMAT = 210,
@@ -939,8 +952,7 @@ enum HPI_ERROR_CODES {
939 HPI_ERROR_DSP_FILE_ACCESS_DENIED = 211, 952 HPI_ERROR_DSP_FILE_ACCESS_DENIED = 211,
940 /** First DSP code section header not found in DSP file. */ 953 /** First DSP code section header not found in DSP file. */
941 HPI_ERROR_DSP_FILE_NO_HEADER = 212, 954 HPI_ERROR_DSP_FILE_NO_HEADER = 212,
942 /** File read operation on DSP code file failed. */ 955 /* HPI_ERROR_DSP_FILE_READ_ERROR= 213, */
943 HPI_ERROR_DSP_FILE_READ_ERROR = 213,
944 /** DSP code for adapter family not found. */ 956 /** DSP code for adapter family not found. */
945 HPI_ERROR_DSP_SECTION_NOT_FOUND = 214, 957 HPI_ERROR_DSP_SECTION_NOT_FOUND = 214,
946 /** Other OS specific error opening DSP file. */ 958 /** Other OS specific error opening DSP file. */
@@ -950,23 +962,21 @@ enum HPI_ERROR_CODES {
950 /** DSP code section header had size == 0. */ 962 /** DSP code section header had size == 0. */
951 HPI_ERROR_DSP_FILE_NULL_HEADER = 217, 963 HPI_ERROR_DSP_FILE_NULL_HEADER = 217,
952 964
953 /** Base number for flash errors. */ 965 /* HPI_ERROR_FLASH = 220, */
954 HPI_ERROR_FLASH = 220,
955 966
956 /** Flash has bad checksum */ 967 /** Flash has bad checksum */
957 HPI_ERROR_BAD_CHECKSUM = (HPI_ERROR_FLASH + 1), 968 HPI_ERROR_BAD_CHECKSUM = 221,
958 HPI_ERROR_BAD_SEQUENCE = (HPI_ERROR_FLASH + 2), 969 HPI_ERROR_BAD_SEQUENCE = 222,
959 HPI_ERROR_FLASH_ERASE = (HPI_ERROR_FLASH + 3), 970 HPI_ERROR_FLASH_ERASE = 223,
960 HPI_ERROR_FLASH_PROGRAM = (HPI_ERROR_FLASH + 4), 971 HPI_ERROR_FLASH_PROGRAM = 224,
961 HPI_ERROR_FLASH_VERIFY = (HPI_ERROR_FLASH + 5), 972 HPI_ERROR_FLASH_VERIFY = 225,
962 HPI_ERROR_FLASH_TYPE = (HPI_ERROR_FLASH + 6), 973 HPI_ERROR_FLASH_TYPE = 226,
963 HPI_ERROR_FLASH_START = (HPI_ERROR_FLASH + 7), 974 HPI_ERROR_FLASH_START = 227,
964 975
965 /** Reserved for OEMs. */ 976 /** Reserved for OEMs. */
966 HPI_ERROR_RESERVED_1 = 290, 977 HPI_ERROR_RESERVED_1 = 290,
967 978
968 /** Stream does not exist. */ 979 /* HPI_ERROR_INVALID_STREAM = 300 use HPI_ERROR_INVALID_OBJ_INDEX */
969 HPI_ERROR_INVALID_STREAM = 300,
970 /** Invalid compression format. */ 980 /** Invalid compression format. */
971 HPI_ERROR_INVALID_FORMAT = 301, 981 HPI_ERROR_INVALID_FORMAT = 301,
972 /** Invalid format samplerate */ 982 /** Invalid format samplerate */
@@ -977,21 +987,19 @@ enum HPI_ERROR_CODES {
977 HPI_ERROR_INVALID_BITRATE = 304, 987 HPI_ERROR_INVALID_BITRATE = 304,
978 /** Invalid datasize used for stream read/write. */ 988 /** Invalid datasize used for stream read/write. */
979 HPI_ERROR_INVALID_DATASIZE = 305, 989 HPI_ERROR_INVALID_DATASIZE = 305,
980 /** Stream buffer is full during stream write. */ 990 /* HPI_ERROR_BUFFER_FULL = 306 use HPI_ERROR_INVALID_DATASIZE */
981 HPI_ERROR_BUFFER_FULL = 306, 991 /* HPI_ERROR_BUFFER_EMPTY = 307 use HPI_ERROR_INVALID_DATASIZE */
982 /** Stream buffer is empty during stream read. */ 992 /** Null data pointer used for stream read/write. */
983 HPI_ERROR_BUFFER_EMPTY = 307, 993 HPI_ERROR_INVALID_DATA_POINTER = 308,
984 /** Invalid datasize used for stream read/write. */
985 HPI_ERROR_INVALID_DATA_TRANSFER = 308,
986 /** Packet ordering error for stream read/write. */ 994 /** Packet ordering error for stream read/write. */
987 HPI_ERROR_INVALID_PACKET_ORDER = 309, 995 HPI_ERROR_INVALID_PACKET_ORDER = 309,
988 996
989 /** Object can't do requested operation in its current 997 /** Object can't do requested operation in its current
990 state, eg set format, change rec mux state while recording.*/ 998 state, eg set format, change rec mux state while recording.*/
991 HPI_ERROR_INVALID_OPERATION = 310, 999 HPI_ERROR_INVALID_OPERATION = 310,
992 1000
993 /** Where an SRG is shared amongst streams, an incompatible samplerate is one 1001 /** Where a SRG is shared amongst streams, an incompatible samplerate
994 that is different to any currently playing or recording stream. */ 1002 is one that is different to any currently active stream. */
995 HPI_ERROR_INCOMPATIBLE_SAMPLERATE = 311, 1003 HPI_ERROR_INCOMPATIBLE_SAMPLERATE = 311,
996 /** Adapter mode is illegal.*/ 1004 /** Adapter mode is illegal.*/
997 HPI_ERROR_BAD_ADAPTER_MODE = 312, 1005 HPI_ERROR_BAD_ADAPTER_MODE = 312,
@@ -1004,6 +1012,8 @@ enum HPI_ERROR_CODES {
1004 HPI_ERROR_NO_INTERADAPTER_GROUPS = 314, 1012 HPI_ERROR_NO_INTERADAPTER_GROUPS = 314,
1005 /** Streams on different DSPs cannot be grouped. */ 1013 /** Streams on different DSPs cannot be grouped. */
1006 HPI_ERROR_NO_INTERDSP_GROUPS = 315, 1014 HPI_ERROR_NO_INTERDSP_GROUPS = 315,
1015 /** Stream wait cancelled before threshold reached. */
1016 HPI_ERROR_WAIT_CANCELLED = 316,
1007 1017
1008 /** Invalid mixer node for this adapter. */ 1018 /** Invalid mixer node for this adapter. */
1009 HPI_ERROR_INVALID_NODE = 400, 1019 HPI_ERROR_INVALID_NODE = 400,
@@ -1017,6 +1027,7 @@ enum HPI_ERROR_CODES {
1017 HPI_ERROR_CONTROL_DISABLED = 404, 1027 HPI_ERROR_CONTROL_DISABLED = 404,
1018 /** I2C transaction failed due to a missing ACK. */ 1028 /** I2C transaction failed due to a missing ACK. */
1019 HPI_ERROR_CONTROL_I2C_MISSING_ACK = 405, 1029 HPI_ERROR_CONTROL_I2C_MISSING_ACK = 405,
1030 HPI_ERROR_I2C_MISSING_ACK = 405,
1020 /** Control is busy, or coming out of 1031 /** Control is busy, or coming out of
1021 reset and cannot be accessed at this time. */ 1032 reset and cannot be accessed at this time. */
1022 HPI_ERROR_CONTROL_NOT_READY = 407, 1033 HPI_ERROR_CONTROL_NOT_READY = 407,
@@ -1027,7 +1038,6 @@ enum HPI_ERROR_CODES {
1027 HPI_ERROR_NVMEM_FAIL = 452, 1038 HPI_ERROR_NVMEM_FAIL = 452,
1028 1039
1029 /** I2C */ 1040 /** I2C */
1030 HPI_ERROR_I2C_MISSING_ACK = HPI_ERROR_CONTROL_I2C_MISSING_ACK,
1031 HPI_ERROR_I2C_BAD_ADR = 460, 1041 HPI_ERROR_I2C_BAD_ADR = 460,
1032 1042
1033 /** Entity errors */ 1043 /** Entity errors */
@@ -1035,6 +1045,7 @@ enum HPI_ERROR_CODES {
1035 HPI_ERROR_ENTITY_ITEM_COUNT = 471, 1045 HPI_ERROR_ENTITY_ITEM_COUNT = 471,
1036 HPI_ERROR_ENTITY_TYPE_INVALID = 472, 1046 HPI_ERROR_ENTITY_TYPE_INVALID = 472,
1037 HPI_ERROR_ENTITY_ROLE_INVALID = 473, 1047 HPI_ERROR_ENTITY_ROLE_INVALID = 473,
1048 HPI_ERROR_ENTITY_SIZE_MISMATCH = 474,
1038 1049
1039 /* AES18 specific errors were 500..507 */ 1050 /* AES18 specific errors were 500..507 */
1040 1051
@@ -1044,11 +1055,18 @@ enum HPI_ERROR_CODES {
1044 /** hpioct32.c can't obtain mutex */ 1055 /** hpioct32.c can't obtain mutex */
1045 HPI_ERROR_MUTEX_TIMEOUT = 700, 1056 HPI_ERROR_MUTEX_TIMEOUT = 700,
1046 1057
1047 /** errors from HPI backends have values >= this */ 1058 /** Backend errors used to be greater than this.
1059 \deprecated Now, all backends return only errors defined here in hpi.h
1060 */
1048 HPI_ERROR_BACKEND_BASE = 900, 1061 HPI_ERROR_BACKEND_BASE = 900,
1049 1062
1050 /** indicates a cached u16 value is invalid. */ 1063 /** Communication with DSP failed */
1051 HPI_ERROR_ILLEGAL_CACHE_VALUE = 0xffff 1064 HPI_ERROR_DSP_COMMUNICATION = 900
1065 /* Note that the dsp communication error is set to this value so that
1066 it remains compatible with any software that expects such errors
1067 to be backend errors i.e. >= 900.
1068 Do not define any new error codes with values > 900.
1069 */
1052}; 1070};
1053 1071
1054/** \defgroup maximums HPI maximum values 1072/** \defgroup maximums HPI maximum values
@@ -1075,7 +1093,7 @@ enum HPI_ERROR_CODES {
1075 1093
1076/**\}*/ 1094/**\}*/
1077 1095
1078/* ////////////////////////////////////////////////////////////////////// */ 1096/**************/
1079/* STRUCTURES */ 1097/* STRUCTURES */
1080#ifndef DISABLE_PRAGMA_PACK1 1098#ifndef DISABLE_PRAGMA_PACK1
1081#pragma pack(push, 1) 1099#pragma pack(push, 1)
@@ -1092,7 +1110,7 @@ struct hpi_format {
1092 /**< Stereo/JointStereo/Mono */ 1110 /**< Stereo/JointStereo/Mono */
1093 u16 mode_legacy; 1111 u16 mode_legacy;
1094 /**< Legacy ancillary mode or idle bit */ 1112 /**< Legacy ancillary mode or idle bit */
1095 u16 unused; /**< unused */ 1113 u16 unused; /**< Unused */
1096 u16 channels; /**< 1,2..., (or ancillary mode or idle bit */ 1114 u16 channels; /**< 1,2..., (or ancillary mode or idle bit */
1097 u16 format; /**< HPI_FORMAT_PCM16, _MPEG etc. see #HPI_FORMATS. */ 1115 u16 format; /**< HPI_FORMAT_PCM16, _MPEG etc. see #HPI_FORMATS. */
1098}; 1116};
@@ -1106,930 +1124,594 @@ struct hpi_anc_frame {
1106*/ 1124*/
1107struct hpi_async_event { 1125struct hpi_async_event {
1108 u16 event_type; /**< type of event. \sa async_event */ 1126 u16 event_type; /**< type of event. \sa async_event */
1109 u16 sequence; /**< sequence number, allows lost event detection */ 1127 u16 sequence; /**< Sequence number, allows lost event detection */
1110 u32 state; /**< new state */ 1128 u32 state; /**< New state */
1111 u32 h_object; /**< handle to the object returning the event. */ 1129 u32 h_object; /**< handle to the object returning the event. */
1112 union { 1130 union {
1113 struct { 1131 struct {
1114 u16 index; /**< GPIO bit index. */ 1132 u16 index; /**< GPIO bit index. */
1115 } gpio; 1133 } gpio;
1116 struct { 1134 struct {
1117 u16 node_index; /**< what node is the control on ? */ 1135 u16 node_index; /**< what node is the control on ? */
1118 u16 node_type; /**< what type of node is the control on ? */ 1136 u16 node_type; /**< what type of node is the control on ? */
1119 } control; 1137 } control;
1120 } u; 1138 } u;
1121}; 1139};
1122 1140
1123/*/////////////////////////////////////////////////////////////////////////// */
1124/* Public HPI Entity related definitions */
1125
1126struct hpi_entity;
1127
1128enum e_entity_type {
1129 entity_type_null,
1130 entity_type_sequence, /* sequence of potentially heterogeneous TLV entities */
1131
1132 entity_type_reference, /* refers to a TLV entity or NULL */
1133
1134 entity_type_int, /* 32 bit */
1135 entity_type_float, /* ieee754 binary 32 bit encoding */
1136 entity_type_double,
1137
1138 entity_type_cstring,
1139 entity_type_octet,
1140 entity_type_ip4_address,
1141 entity_type_ip6_address,
1142 entity_type_mac_address,
1143
1144 LAST_ENTITY_TYPE
1145};
1146
1147enum e_entity_role {
1148 entity_role_null,
1149 entity_role_value,
1150 entity_role_classname,
1151
1152 entity_role_units,
1153 entity_role_flags,
1154 entity_role_range,
1155
1156 entity_role_mapping,
1157 entity_role_enum,
1158
1159 entity_role_instance_of,
1160 entity_role_depends_on,
1161 entity_role_member_of_group,
1162 entity_role_value_constraint,
1163 entity_role_parameter_port,
1164
1165 entity_role_block,
1166 entity_role_node_group,
1167 entity_role_audio_port,
1168 entity_role_clock_port,
1169 LAST_ENTITY_ROLE
1170};
1171
1172/* skip host side function declarations for 1141/* skip host side function declarations for
1173 DSP compile and documentation extraction */ 1142 DSP compile and documentation extraction */
1174 1143
1175struct hpi_hsubsys {
1176 int not_really_used;
1177};
1178
1179#ifndef DISABLE_PRAGMA_PACK1 1144#ifndef DISABLE_PRAGMA_PACK1
1180#pragma pack(pop) 1145#pragma pack(pop)
1181#endif 1146#endif
1182 1147
1183/*////////////////////////////////////////////////////////////////////////// */ 1148/*****************/
1184/* HPI FUNCTIONS */ 1149/* HPI FUNCTIONS */
1150/*****************/
1185 1151
1186/*/////////////////////////// */ 1152/* Stream */
1187/* DATA and FORMAT and STREAM */
1188
1189u16 hpi_stream_estimate_buffer_size(struct hpi_format *pF, 1153u16 hpi_stream_estimate_buffer_size(struct hpi_format *pF,
1190 u32 host_polling_rate_in_milli_seconds, u32 *recommended_buffer_size); 1154 u32 host_polling_rate_in_milli_seconds, u32 *recommended_buffer_size);
1191 1155
1192/*/////////// */ 1156/*************/
1193/* SUB SYSTEM */ 1157/* SubSystem */
1194struct hpi_hsubsys *hpi_subsys_create(void 1158/*************/
1195 );
1196
1197void hpi_subsys_free(const struct hpi_hsubsys *ph_subsys);
1198
1199u16 hpi_subsys_get_version(const struct hpi_hsubsys *ph_subsys,
1200 u32 *pversion);
1201
1202u16 hpi_subsys_get_version_ex(const struct hpi_hsubsys *ph_subsys,
1203 u32 *pversion_ex);
1204
1205u16 hpi_subsys_get_info(const struct hpi_hsubsys *ph_subsys, u32 *pversion,
1206 u16 *pw_num_adapters, u16 aw_adapter_list[], u16 list_length);
1207
1208u16 hpi_subsys_find_adapters(const struct hpi_hsubsys *ph_subsys,
1209 u16 *pw_num_adapters, u16 aw_adapter_list[], u16 list_length);
1210
1211u16 hpi_subsys_get_num_adapters(const struct hpi_hsubsys *ph_subsys,
1212 int *pn_num_adapters);
1213
1214u16 hpi_subsys_get_adapter(const struct hpi_hsubsys *ph_subsys, int iterator,
1215 u32 *padapter_index, u16 *pw_adapter_type);
1216
1217u16 hpi_subsys_ssx2_bypass(const struct hpi_hsubsys *ph_subsys, u16 bypass);
1218 1159
1219u16 hpi_subsys_set_host_network_interface(const struct hpi_hsubsys *ph_subsys, 1160u16 hpi_subsys_get_version_ex(u32 *pversion_ex);
1220 const char *sz_interface);
1221 1161
1222/*///////// */ 1162u16 hpi_subsys_get_num_adapters(int *pn_num_adapters);
1223/* ADAPTER */
1224 1163
1225u16 hpi_adapter_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index); 1164u16 hpi_subsys_get_adapter(int iterator, u32 *padapter_index,
1165 u16 *pw_adapter_type);
1226 1166
1227u16 hpi_adapter_close(const struct hpi_hsubsys *ph_subsys, u16 adapter_index); 1167/***********/
1168/* Adapter */
1169/***********/
1228 1170
1229u16 hpi_adapter_get_info(const struct hpi_hsubsys *ph_subsys, 1171u16 hpi_adapter_open(u16 adapter_index);
1230 u16 adapter_index, u16 *pw_num_outstreams, u16 *pw_num_instreams,
1231 u16 *pw_version, u32 *pserial_number, u16 *pw_adapter_type);
1232 1172
1233u16 hpi_adapter_get_module_by_index(const struct hpi_hsubsys *ph_subsys, 1173u16 hpi_adapter_close(u16 adapter_index);
1234 u16 adapter_index, u16 module_index, u16 *pw_num_outputs,
1235 u16 *pw_num_inputs, u16 *pw_version, u32 *pserial_number,
1236 u16 *pw_module_type, u32 *ph_module);
1237 1174
1238u16 hpi_adapter_set_mode(const struct hpi_hsubsys *ph_subsys, 1175u16 hpi_adapter_get_info(u16 adapter_index, u16 *pw_num_outstreams,
1239 u16 adapter_index, u32 adapter_mode); 1176 u16 *pw_num_instreams, u16 *pw_version, u32 *pserial_number,
1177 u16 *pw_adapter_type);
1240 1178
1241u16 hpi_adapter_set_mode_ex(const struct hpi_hsubsys *ph_subsys, 1179u16 hpi_adapter_get_module_by_index(u16 adapter_index, u16 module_index,
1242 u16 adapter_index, u32 adapter_mode, u16 query_or_set); 1180 u16 *pw_num_outputs, u16 *pw_num_inputs, u16 *pw_version,
1243 1181 u32 *pserial_number, u16 *pw_module_type, u32 *ph_module);
1244u16 hpi_adapter_get_mode(const struct hpi_hsubsys *ph_subsys,
1245 u16 adapter_index, u32 *padapter_mode);
1246
1247u16 hpi_adapter_get_assert(const struct hpi_hsubsys *ph_subsys,
1248 u16 adapter_index, u16 *assert_present, char *psz_assert,
1249 u16 *pw_line_number);
1250
1251u16 hpi_adapter_get_assert_ex(const struct hpi_hsubsys *ph_subsys,
1252 u16 adapter_index, u16 *assert_present, char *psz_assert,
1253 u32 *pline_number, u16 *pw_assert_on_dsp);
1254
1255u16 hpi_adapter_test_assert(const struct hpi_hsubsys *ph_subsys,
1256 u16 adapter_index, u16 assert_id);
1257
1258u16 hpi_adapter_enable_capability(const struct hpi_hsubsys *ph_subsys,
1259 u16 adapter_index, u16 capability, u32 key);
1260
1261u16 hpi_adapter_self_test(const struct hpi_hsubsys *ph_subsys,
1262 u16 adapter_index);
1263
1264u16 hpi_adapter_debug_read(const struct hpi_hsubsys *ph_subsys,
1265 u16 adapter_index, u32 dsp_address, char *p_bytes, int *count_bytes);
1266
1267u16 hpi_adapter_set_property(const struct hpi_hsubsys *ph_subsys,
1268 u16 adapter_index, u16 property, u16 paramter1, u16 paramter2);
1269
1270u16 hpi_adapter_get_property(const struct hpi_hsubsys *ph_subsys,
1271 u16 adapter_index, u16 property, u16 *pw_paramter1,
1272 u16 *pw_paramter2);
1273
1274u16 hpi_adapter_enumerate_property(const struct hpi_hsubsys *ph_subsys,
1275 u16 adapter_index, u16 index, u16 what_to_enumerate,
1276 u16 property_index, u32 *psetting);
1277
1278/*////////////// */
1279/* NonVol Memory */
1280u16 hpi_nv_memory_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
1281 u32 *ph_nv_memory, u16 *pw_size_in_bytes);
1282
1283u16 hpi_nv_memory_read_byte(const struct hpi_hsubsys *ph_subsys,
1284 u32 h_nv_memory, u16 index, u16 *pw_data);
1285
1286u16 hpi_nv_memory_write_byte(const struct hpi_hsubsys *ph_subsys,
1287 u32 h_nv_memory, u16 index, u16 data);
1288
1289/*////////////// */
1290/* Digital I/O */
1291u16 hpi_gpio_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
1292 u32 *ph_gpio, u16 *pw_number_input_bits, u16 *pw_number_output_bits);
1293
1294u16 hpi_gpio_read_bit(const struct hpi_hsubsys *ph_subsys, u32 h_gpio,
1295 u16 bit_index, u16 *pw_bit_data);
1296
1297u16 hpi_gpio_read_all_bits(const struct hpi_hsubsys *ph_subsys, u32 h_gpio,
1298 u16 aw_all_bit_data[4]
1299 );
1300 1182
1301u16 hpi_gpio_write_bit(const struct hpi_hsubsys *ph_subsys, u32 h_gpio, 1183u16 hpi_adapter_set_mode(u16 adapter_index, u32 adapter_mode);
1302 u16 bit_index, u16 bit_data);
1303 1184
1304u16 hpi_gpio_write_status(const struct hpi_hsubsys *ph_subsys, u32 h_gpio, 1185u16 hpi_adapter_set_mode_ex(u16 adapter_index, u32 adapter_mode,
1305 u16 aw_all_bit_data[4] 1186 u16 query_or_set);
1306 );
1307 1187
1308/**********************/ 1188u16 hpi_adapter_get_mode(u16 adapter_index, u32 *padapter_mode);
1309/* Async Event Object */
1310/**********************/
1311u16 hpi_async_event_open(const struct hpi_hsubsys *ph_subsys,
1312 u16 adapter_index, u32 *ph_async);
1313 1189
1314u16 hpi_async_event_close(const struct hpi_hsubsys *ph_subsys, u32 h_async); 1190u16 hpi_adapter_get_assert2(u16 adapter_index, u16 *p_assert_count,
1191 char *psz_assert, u32 *p_param1, u32 *p_param2,
1192 u32 *p_dsp_string_addr, u16 *p_processor_id);
1315 1193
1316u16 hpi_async_event_wait(const struct hpi_hsubsys *ph_subsys, u32 h_async, 1194u16 hpi_adapter_test_assert(u16 adapter_index, u16 assert_id);
1317 u16 maximum_events, struct hpi_async_event *p_events,
1318 u16 *pw_number_returned);
1319 1195
1320u16 hpi_async_event_get_count(const struct hpi_hsubsys *ph_subsys, 1196u16 hpi_adapter_enable_capability(u16 adapter_index, u16 capability, u32 key);
1321 u32 h_async, u16 *pw_count);
1322 1197
1323u16 hpi_async_event_get(const struct hpi_hsubsys *ph_subsys, u32 h_async, 1198u16 hpi_adapter_self_test(u16 adapter_index);
1324 u16 maximum_events, struct hpi_async_event *p_events,
1325 u16 *pw_number_returned);
1326 1199
1327/*/////////// */ 1200u16 hpi_adapter_debug_read(u16 adapter_index, u32 dsp_address, char *p_bytes,
1328/* WATCH-DOG */ 1201 int *count_bytes);
1329u16 hpi_watchdog_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
1330 u32 *ph_watchdog);
1331 1202
1332u16 hpi_watchdog_set_time(const struct hpi_hsubsys *ph_subsys, u32 h_watchdog, 1203u16 hpi_adapter_set_property(u16 adapter_index, u16 property, u16 paramter1,
1333 u32 time_millisec); 1204 u16 paramter2);
1334 1205
1335u16 hpi_watchdog_ping(const struct hpi_hsubsys *ph_subsys, u32 h_watchdog); 1206u16 hpi_adapter_get_property(u16 adapter_index, u16 property,
1207 u16 *pw_paramter1, u16 *pw_paramter2);
1336 1208
1337/**************/ 1209u16 hpi_adapter_enumerate_property(u16 adapter_index, u16 index,
1338/* OUT STREAM */ 1210 u16 what_to_enumerate, u16 property_index, u32 *psetting);
1339/**************/ 1211/*************/
1340u16 hpi_outstream_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index, 1212/* OutStream */
1341 u16 outstream_index, u32 *ph_outstream); 1213/*************/
1214u16 hpi_outstream_open(u16 adapter_index, u16 outstream_index,
1215 u32 *ph_outstream);
1342 1216
1343u16 hpi_outstream_close(const struct hpi_hsubsys *ph_subsys, u32 h_outstream); 1217u16 hpi_outstream_close(u32 h_outstream);
1344 1218
1345u16 hpi_outstream_get_info_ex(const struct hpi_hsubsys *ph_subsys, 1219u16 hpi_outstream_get_info_ex(u32 h_outstream, u16 *pw_state,
1346 u32 h_outstream, u16 *pw_state, u32 *pbuffer_size, u32 *pdata_to_play, 1220 u32 *pbuffer_size, u32 *pdata_to_play, u32 *psamples_played,
1347 u32 *psamples_played, u32 *pauxiliary_data_to_play); 1221 u32 *pauxiliary_data_to_play);
1348 1222
1349u16 hpi_outstream_write_buf(const struct hpi_hsubsys *ph_subsys, 1223u16 hpi_outstream_write_buf(u32 h_outstream, const u8 *pb_write_buf,
1350 u32 h_outstream, const u8 *pb_write_buf, u32 bytes_to_write, 1224 u32 bytes_to_write, const struct hpi_format *p_format);
1351 const struct hpi_format *p_format);
1352 1225
1353u16 hpi_outstream_start(const struct hpi_hsubsys *ph_subsys, u32 h_outstream); 1226u16 hpi_outstream_start(u32 h_outstream);
1354 1227
1355u16 hpi_outstream_wait_start(const struct hpi_hsubsys *ph_subsys, 1228u16 hpi_outstream_wait_start(u32 h_outstream);
1356 u32 h_outstream);
1357 1229
1358u16 hpi_outstream_stop(const struct hpi_hsubsys *ph_subsys, u32 h_outstream); 1230u16 hpi_outstream_stop(u32 h_outstream);
1359 1231
1360u16 hpi_outstream_sinegen(const struct hpi_hsubsys *ph_subsys, 1232u16 hpi_outstream_sinegen(u32 h_outstream);
1361 u32 h_outstream);
1362 1233
1363u16 hpi_outstream_reset(const struct hpi_hsubsys *ph_subsys, u32 h_outstream); 1234u16 hpi_outstream_reset(u32 h_outstream);
1364 1235
1365u16 hpi_outstream_query_format(const struct hpi_hsubsys *ph_subsys, 1236u16 hpi_outstream_query_format(u32 h_outstream, struct hpi_format *p_format);
1366 u32 h_outstream, struct hpi_format *p_format);
1367 1237
1368u16 hpi_outstream_set_format(const struct hpi_hsubsys *ph_subsys, 1238u16 hpi_outstream_set_format(u32 h_outstream, struct hpi_format *p_format);
1369 u32 h_outstream, struct hpi_format *p_format);
1370 1239
1371u16 hpi_outstream_set_punch_in_out(const struct hpi_hsubsys *ph_subsys, 1240u16 hpi_outstream_set_punch_in_out(u32 h_outstream, u32 punch_in_sample,
1372 u32 h_outstream, u32 punch_in_sample, u32 punch_out_sample); 1241 u32 punch_out_sample);
1373 1242
1374u16 hpi_outstream_set_velocity(const struct hpi_hsubsys *ph_subsys, 1243u16 hpi_outstream_set_velocity(u32 h_outstream, short velocity);
1375 u32 h_outstream, short velocity);
1376 1244
1377u16 hpi_outstream_ancillary_reset(const struct hpi_hsubsys *ph_subsys, 1245u16 hpi_outstream_ancillary_reset(u32 h_outstream, u16 mode);
1378 u32 h_outstream, u16 mode);
1379 1246
1380u16 hpi_outstream_ancillary_get_info(const struct hpi_hsubsys *ph_subsys, 1247u16 hpi_outstream_ancillary_get_info(u32 h_outstream, u32 *pframes_available);
1381 u32 h_outstream, u32 *pframes_available);
1382 1248
1383u16 hpi_outstream_ancillary_read(const struct hpi_hsubsys *ph_subsys, 1249u16 hpi_outstream_ancillary_read(u32 h_outstream,
1384 u32 h_outstream, struct hpi_anc_frame *p_anc_frame_buffer, 1250 struct hpi_anc_frame *p_anc_frame_buffer,
1385 u32 anc_frame_buffer_size_in_bytes, 1251 u32 anc_frame_buffer_size_in_bytes,
1386 u32 number_of_ancillary_frames_to_read); 1252 u32 number_of_ancillary_frames_to_read);
1387 1253
1388u16 hpi_outstream_set_time_scale(const struct hpi_hsubsys *ph_subsys, 1254u16 hpi_outstream_set_time_scale(u32 h_outstream, u32 time_scaleX10000);
1389 u32 h_outstream, u32 time_scaleX10000);
1390 1255
1391u16 hpi_outstream_host_buffer_allocate(const struct hpi_hsubsys *ph_subsys, 1256u16 hpi_outstream_host_buffer_allocate(u32 h_outstream, u32 size_in_bytes);
1392 u32 h_outstream, u32 size_in_bytes);
1393 1257
1394u16 hpi_outstream_host_buffer_free(const struct hpi_hsubsys *ph_subsys, 1258u16 hpi_outstream_host_buffer_free(u32 h_outstream);
1395 u32 h_outstream);
1396 1259
1397u16 hpi_outstream_group_add(const struct hpi_hsubsys *ph_subsys, 1260u16 hpi_outstream_group_add(u32 h_outstream, u32 h_stream);
1398 u32 h_outstream, u32 h_stream);
1399 1261
1400u16 hpi_outstream_group_get_map(const struct hpi_hsubsys *ph_subsys, 1262u16 hpi_outstream_group_get_map(u32 h_outstream, u32 *poutstream_map,
1401 u32 h_outstream, u32 *poutstream_map, u32 *pinstream_map); 1263 u32 *pinstream_map);
1402 1264
1403u16 hpi_outstream_group_reset(const struct hpi_hsubsys *ph_subsys, 1265u16 hpi_outstream_group_reset(u32 h_outstream);
1404 u32 h_outstream);
1405 1266
1406/*////////// */ 1267/************/
1407/* IN_STREAM */ 1268/* InStream */
1408u16 hpi_instream_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index, 1269/************/
1409 u16 instream_index, u32 *ph_instream); 1270u16 hpi_instream_open(u16 adapter_index, u16 instream_index,
1271 u32 *ph_instream);
1410 1272
1411u16 hpi_instream_close(const struct hpi_hsubsys *ph_subsys, u32 h_instream); 1273u16 hpi_instream_close(u32 h_instream);
1412 1274
1413u16 hpi_instream_query_format(const struct hpi_hsubsys *ph_subsys, 1275u16 hpi_instream_query_format(u32 h_instream,
1414 u32 h_instream, const struct hpi_format *p_format); 1276 const struct hpi_format *p_format);
1415 1277
1416u16 hpi_instream_set_format(const struct hpi_hsubsys *ph_subsys, 1278u16 hpi_instream_set_format(u32 h_instream,
1417 u32 h_instream, const struct hpi_format *p_format); 1279 const struct hpi_format *p_format);
1418 1280
1419u16 hpi_instream_read_buf(const struct hpi_hsubsys *ph_subsys, u32 h_instream, 1281u16 hpi_instream_read_buf(u32 h_instream, u8 *pb_read_buf, u32 bytes_to_read);
1420 u8 *pb_read_buf, u32 bytes_to_read);
1421 1282
1422u16 hpi_instream_start(const struct hpi_hsubsys *ph_subsys, u32 h_instream); 1283u16 hpi_instream_start(u32 h_instream);
1423 1284
1424u16 hpi_instream_wait_start(const struct hpi_hsubsys *ph_subsys, 1285u16 hpi_instream_wait_start(u32 h_instream);
1425 u32 h_instream);
1426 1286
1427u16 hpi_instream_stop(const struct hpi_hsubsys *ph_subsys, u32 h_instream); 1287u16 hpi_instream_stop(u32 h_instream);
1428 1288
1429u16 hpi_instream_reset(const struct hpi_hsubsys *ph_subsys, u32 h_instream); 1289u16 hpi_instream_reset(u32 h_instream);
1430 1290
1431u16 hpi_instream_get_info_ex(const struct hpi_hsubsys *ph_subsys, 1291u16 hpi_instream_get_info_ex(u32 h_instream, u16 *pw_state, u32 *pbuffer_size,
1432 u32 h_instream, u16 *pw_state, u32 *pbuffer_size, u32 *pdata_recorded, 1292 u32 *pdata_recorded, u32 *psamples_recorded,
1433 u32 *psamples_recorded, u32 *pauxiliary_data_recorded); 1293 u32 *pauxiliary_data_recorded);
1434 1294
1435u16 hpi_instream_ancillary_reset(const struct hpi_hsubsys *ph_subsys, 1295u16 hpi_instream_ancillary_reset(u32 h_instream, u16 bytes_per_frame,
1436 u32 h_instream, u16 bytes_per_frame, u16 mode, u16 alignment, 1296 u16 mode, u16 alignment, u16 idle_bit);
1437 u16 idle_bit);
1438 1297
1439u16 hpi_instream_ancillary_get_info(const struct hpi_hsubsys *ph_subsys, 1298u16 hpi_instream_ancillary_get_info(u32 h_instream, u32 *pframe_space);
1440 u32 h_instream, u32 *pframe_space);
1441 1299
1442u16 hpi_instream_ancillary_write(const struct hpi_hsubsys *ph_subsys, 1300u16 hpi_instream_ancillary_write(u32 h_instream,
1443 u32 h_instream, const struct hpi_anc_frame *p_anc_frame_buffer, 1301 const struct hpi_anc_frame *p_anc_frame_buffer,
1444 u32 anc_frame_buffer_size_in_bytes, 1302 u32 anc_frame_buffer_size_in_bytes,
1445 u32 number_of_ancillary_frames_to_write); 1303 u32 number_of_ancillary_frames_to_write);
1446 1304
1447u16 hpi_instream_host_buffer_allocate(const struct hpi_hsubsys *ph_subsys, 1305u16 hpi_instream_host_buffer_allocate(u32 h_instream, u32 size_in_bytes);
1448 u32 h_instream, u32 size_in_bytes);
1449 1306
1450u16 hpi_instream_host_buffer_free(const struct hpi_hsubsys *ph_subsys, 1307u16 hpi_instream_host_buffer_free(u32 h_instream);
1451 u32 h_instream);
1452 1308
1453u16 hpi_instream_group_add(const struct hpi_hsubsys *ph_subsys, 1309u16 hpi_instream_group_add(u32 h_instream, u32 h_stream);
1454 u32 h_instream, u32 h_stream);
1455 1310
1456u16 hpi_instream_group_get_map(const struct hpi_hsubsys *ph_subsys, 1311u16 hpi_instream_group_get_map(u32 h_instream, u32 *poutstream_map,
1457 u32 h_instream, u32 *poutstream_map, u32 *pinstream_map); 1312 u32 *pinstream_map);
1458 1313
1459u16 hpi_instream_group_reset(const struct hpi_hsubsys *ph_subsys, 1314u16 hpi_instream_group_reset(u32 h_instream);
1460 u32 h_instream);
1461 1315
1462/*********/ 1316/*********/
1463/* MIXER */ 1317/* Mixer */
1464/*********/ 1318/*********/
1465u16 hpi_mixer_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index, 1319u16 hpi_mixer_open(u16 adapter_index, u32 *ph_mixer);
1466 u32 *ph_mixer); 1320
1467 1321u16 hpi_mixer_close(u32 h_mixer);
1468u16 hpi_mixer_close(const struct hpi_hsubsys *ph_subsys, u32 h_mixer); 1322
1469 1323u16 hpi_mixer_get_control(u32 h_mixer, u16 src_node_type,
1470u16 hpi_mixer_get_control(const struct hpi_hsubsys *ph_subsys, u32 h_mixer, 1324 u16 src_node_type_index, u16 dst_node_type, u16 dst_node_type_index,
1471 u16 src_node_type, u16 src_node_type_index, u16 dst_node_type, 1325 u16 control_type, u32 *ph_control);
1472 u16 dst_node_type_index, u16 control_type, u32 *ph_control); 1326
1473 1327u16 hpi_mixer_get_control_by_index(u32 h_mixer, u16 control_index,
1474u16 hpi_mixer_get_control_by_index(const struct hpi_hsubsys *ph_subsys, 1328 u16 *pw_src_node_type, u16 *pw_src_node_index, u16 *pw_dst_node_type,
1475 u32 h_mixer, u16 control_index, u16 *pw_src_node_type, 1329 u16 *pw_dst_node_index, u16 *pw_control_type, u32 *ph_control);
1476 u16 *pw_src_node_index, u16 *pw_dst_node_type, u16 *pw_dst_node_index, 1330
1477 u16 *pw_control_type, u32 *ph_control); 1331u16 hpi_mixer_store(u32 h_mixer, enum HPI_MIXER_STORE_COMMAND command,
1478 1332 u16 index);
1479u16 hpi_mixer_store(const struct hpi_hsubsys *ph_subsys, u32 h_mixer, 1333/************/
1480 enum HPI_MIXER_STORE_COMMAND command, u16 index); 1334/* Controls */
1481/*************************/ 1335/************/
1482/* mixer CONTROLS */ 1336/******************/
1483/*************************/ 1337/* Volume control */
1484/*************************/ 1338/******************/
1485/* volume control */ 1339u16 hpi_volume_set_gain(u32 h_control, short an_gain0_01dB[HPI_MAX_CHANNELS]
1486/*************************/
1487u16 hpi_volume_set_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1488 short an_gain0_01dB[HPI_MAX_CHANNELS]
1489 ); 1340 );
1490 1341
1491u16 hpi_volume_get_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1342u16 hpi_volume_get_gain(u32 h_control,
1492 short an_gain0_01dB_out[HPI_MAX_CHANNELS] 1343 short an_gain0_01dB_out[HPI_MAX_CHANNELS]
1493 ); 1344 );
1494 1345
1346u16 hpi_volume_set_mute(u32 h_control, u32 mute);
1347
1348u16 hpi_volume_get_mute(u32 h_control, u32 *mute);
1349
1495#define hpi_volume_get_range hpi_volume_query_range 1350#define hpi_volume_get_range hpi_volume_query_range
1496u16 hpi_volume_query_range(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1351u16 hpi_volume_query_range(u32 h_control, short *min_gain_01dB,
1497 short *min_gain_01dB, short *max_gain_01dB, short *step_gain_01dB); 1352 short *max_gain_01dB, short *step_gain_01dB);
1498 1353
1499u16 hpi_volume_query_channels(const struct hpi_hsubsys *ph_subsys, 1354u16 hpi_volume_query_channels(const u32 h_volume, u32 *p_channels);
1500 const u32 h_volume, u32 *p_channels);
1501 1355
1502u16 hpi_volume_auto_fade(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1356u16 hpi_volume_auto_fade(u32 h_control,
1503 short an_stop_gain0_01dB[HPI_MAX_CHANNELS], u32 duration_ms); 1357 short an_stop_gain0_01dB[HPI_MAX_CHANNELS], u32 duration_ms);
1504 1358
1505u16 hpi_volume_auto_fade_profile(const struct hpi_hsubsys *ph_subsys, 1359u16 hpi_volume_auto_fade_profile(u32 h_control,
1506 u32 h_control, short an_stop_gain0_01dB[HPI_MAX_CHANNELS], 1360 short an_stop_gain0_01dB[HPI_MAX_CHANNELS], u32 duration_ms,
1507 u32 duration_ms, u16 profile); 1361 u16 profile);
1508 1362
1509/*************************/ 1363/*****************/
1510/* level control */ 1364/* Level control */
1511/*************************/ 1365/*****************/
1512u16 hpi_level_query_range(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1366u16 hpi_level_query_range(u32 h_control, short *min_gain_01dB,
1513 short *min_gain_01dB, short *max_gain_01dB, short *step_gain_01dB); 1367 short *max_gain_01dB, short *step_gain_01dB);
1514 1368
1515u16 hpi_level_set_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1369u16 hpi_level_set_gain(u32 h_control, short an_gain0_01dB[HPI_MAX_CHANNELS]
1516 short an_gain0_01dB[HPI_MAX_CHANNELS]
1517 ); 1370 );
1518 1371
1519u16 hpi_level_get_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1372u16 hpi_level_get_gain(u32 h_control,
1520 short an_gain0_01dB_out[HPI_MAX_CHANNELS] 1373 short an_gain0_01dB_out[HPI_MAX_CHANNELS]
1521 ); 1374 );
1522 1375
1523/*************************/ 1376/*****************/
1524/* meter control */ 1377/* Meter control */
1525/*************************/ 1378/*****************/
1526u16 hpi_meter_query_channels(const struct hpi_hsubsys *ph_subsys, 1379u16 hpi_meter_query_channels(const u32 h_meter, u32 *p_channels);
1527 const u32 h_meter, u32 *p_channels);
1528 1380
1529u16 hpi_meter_get_peak(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1381u16 hpi_meter_get_peak(u32 h_control,
1530 short an_peak0_01dB_out[HPI_MAX_CHANNELS] 1382 short an_peak0_01dB_out[HPI_MAX_CHANNELS]
1531 ); 1383 );
1532 1384
1533u16 hpi_meter_get_rms(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1385u16 hpi_meter_get_rms(u32 h_control, short an_peak0_01dB_out[HPI_MAX_CHANNELS]
1534 short an_peak0_01dB_out[HPI_MAX_CHANNELS]
1535 ); 1386 );
1536 1387
1537u16 hpi_meter_set_peak_ballistics(const struct hpi_hsubsys *ph_subsys, 1388u16 hpi_meter_set_peak_ballistics(u32 h_control, u16 attack, u16 decay);
1538 u32 h_control, u16 attack, u16 decay);
1539 1389
1540u16 hpi_meter_set_rms_ballistics(const struct hpi_hsubsys *ph_subsys, 1390u16 hpi_meter_set_rms_ballistics(u32 h_control, u16 attack, u16 decay);
1541 u32 h_control, u16 attack, u16 decay);
1542 1391
1543u16 hpi_meter_get_peak_ballistics(const struct hpi_hsubsys *ph_subsys, 1392u16 hpi_meter_get_peak_ballistics(u32 h_control, u16 *attack, u16 *decay);
1544 u32 h_control, u16 *attack, u16 *decay);
1545 1393
1546u16 hpi_meter_get_rms_ballistics(const struct hpi_hsubsys *ph_subsys, 1394u16 hpi_meter_get_rms_ballistics(u32 h_control, u16 *attack, u16 *decay);
1547 u32 h_control, u16 *attack, u16 *decay);
1548 1395
1549/*************************/ 1396/************************/
1550/* channel mode control */ 1397/* ChannelMode control */
1551/*************************/ 1398/************************/
1552u16 hpi_channel_mode_query_mode(const struct hpi_hsubsys *ph_subsys, 1399u16 hpi_channel_mode_query_mode(const u32 h_mode, const u32 index,
1553 const u32 h_mode, const u32 index, u16 *pw_mode); 1400 u16 *pw_mode);
1554 1401
1555u16 hpi_channel_mode_set(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1402u16 hpi_channel_mode_set(u32 h_control, u16 mode);
1556 u16 mode);
1557 1403
1558u16 hpi_channel_mode_get(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1404u16 hpi_channel_mode_get(u32 h_control, u16 *mode);
1559 u16 *mode);
1560 1405
1561/*************************/ 1406/*****************/
1562/* Tuner control */ 1407/* Tuner control */
1563/*************************/ 1408/*****************/
1564u16 hpi_tuner_query_band(const struct hpi_hsubsys *ph_subsys, 1409u16 hpi_tuner_query_band(const u32 h_tuner, const u32 index, u16 *pw_band);
1565 const u32 h_tuner, const u32 index, u16 *pw_band);
1566 1410
1567u16 hpi_tuner_set_band(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1411u16 hpi_tuner_set_band(u32 h_control, u16 band);
1568 u16 band);
1569 1412
1570u16 hpi_tuner_get_band(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1413u16 hpi_tuner_get_band(u32 h_control, u16 *pw_band);
1571 u16 *pw_band);
1572 1414
1573u16 hpi_tuner_query_frequency(const struct hpi_hsubsys *ph_subsys, 1415u16 hpi_tuner_query_frequency(const u32 h_tuner, const u32 index,
1574 const u32 h_tuner, const u32 index, const u16 band, u32 *pfreq); 1416 const u16 band, u32 *pfreq);
1575 1417
1576u16 hpi_tuner_set_frequency(const struct hpi_hsubsys *ph_subsys, 1418u16 hpi_tuner_set_frequency(u32 h_control, u32 freq_ink_hz);
1577 u32 h_control, u32 freq_ink_hz);
1578 1419
1579u16 hpi_tuner_get_frequency(const struct hpi_hsubsys *ph_subsys, 1420u16 hpi_tuner_get_frequency(u32 h_control, u32 *pw_freq_ink_hz);
1580 u32 h_control, u32 *pw_freq_ink_hz);
1581 1421
1582u16 hpi_tuner_getRF_level(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1422u16 hpi_tuner_get_rf_level(u32 h_control, short *pw_level);
1583 short *pw_level);
1584 1423
1585u16 hpi_tuner_get_rawRF_level(const struct hpi_hsubsys *ph_subsys, 1424u16 hpi_tuner_get_raw_rf_level(u32 h_control, short *pw_level);
1586 u32 h_control, short *pw_level);
1587 1425
1588u16 hpi_tuner_query_gain(const struct hpi_hsubsys *ph_subsys, 1426u16 hpi_tuner_query_gain(const u32 h_tuner, const u32 index, u16 *pw_gain);
1589 const u32 h_tuner, const u32 index, u16 *pw_gain);
1590 1427
1591u16 hpi_tuner_set_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1428u16 hpi_tuner_set_gain(u32 h_control, short gain);
1592 short gain);
1593 1429
1594u16 hpi_tuner_get_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1430u16 hpi_tuner_get_gain(u32 h_control, short *pn_gain);
1595 short *pn_gain);
1596 1431
1597u16 hpi_tuner_get_status(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1432u16 hpi_tuner_get_status(u32 h_control, u16 *pw_status_mask, u16 *pw_status);
1598 u16 *pw_status_mask, u16 *pw_status);
1599 1433
1600u16 hpi_tuner_set_mode(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1434u16 hpi_tuner_set_mode(u32 h_control, u32 mode, u32 value);
1601 u32 mode, u32 value);
1602 1435
1603u16 hpi_tuner_get_mode(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1436u16 hpi_tuner_get_mode(u32 h_control, u32 mode, u32 *pn_value);
1604 u32 mode, u32 *pn_value);
1605 1437
1606u16 hpi_tuner_getRDS(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1438u16 hpi_tuner_get_rds(u32 h_control, char *p_rds_data);
1607 char *p_rds_data);
1608 1439
1609u16 hpi_tuner_query_deemphasis(const struct hpi_hsubsys *ph_subsys, 1440u16 hpi_tuner_query_deemphasis(const u32 h_tuner, const u32 index,
1610 const u32 h_tuner, const u32 index, const u16 band, u32 *pdeemphasis); 1441 const u16 band, u32 *pdeemphasis);
1611 1442
1612u16 hpi_tuner_set_deemphasis(const struct hpi_hsubsys *ph_subsys, 1443u16 hpi_tuner_set_deemphasis(u32 h_control, u32 deemphasis);
1613 u32 h_control, u32 deemphasis); 1444u16 hpi_tuner_get_deemphasis(u32 h_control, u32 *pdeemphasis);
1614u16 hpi_tuner_get_deemphasis(const struct hpi_hsubsys *ph_subsys,
1615 u32 h_control, u32 *pdeemphasis);
1616 1445
1617u16 hpi_tuner_query_program(const struct hpi_hsubsys *ph_subsys, 1446u16 hpi_tuner_query_program(const u32 h_tuner, u32 *pbitmap_program);
1618 const u32 h_tuner, u32 *pbitmap_program);
1619 1447
1620u16 hpi_tuner_set_program(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1448u16 hpi_tuner_set_program(u32 h_control, u32 program);
1621 u32 program);
1622 1449
1623u16 hpi_tuner_get_program(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1450u16 hpi_tuner_get_program(u32 h_control, u32 *pprogram);
1624 u32 *pprogram);
1625 1451
1626u16 hpi_tuner_get_hd_radio_dsp_version(const struct hpi_hsubsys *ph_subsys, 1452u16 hpi_tuner_get_hd_radio_dsp_version(u32 h_control, char *psz_dsp_version,
1627 u32 h_control, char *psz_dsp_version, const u32 string_size); 1453 const u32 string_size);
1628 1454
1629u16 hpi_tuner_get_hd_radio_sdk_version(const struct hpi_hsubsys *ph_subsys, 1455u16 hpi_tuner_get_hd_radio_sdk_version(u32 h_control, char *psz_sdk_version,
1630 u32 h_control, char *psz_sdk_version, const u32 string_size); 1456 const u32 string_size);
1631 1457
1632u16 hpi_tuner_get_hd_radio_signal_quality(const struct hpi_hsubsys *ph_subsys, 1458u16 hpi_tuner_get_hd_radio_signal_quality(u32 h_control, u32 *pquality);
1633 u32 h_control, u32 *pquality);
1634 1459
1635u16 hpi_tuner_get_hd_radio_signal_blend(const struct hpi_hsubsys *ph_subsys, 1460u16 hpi_tuner_get_hd_radio_signal_blend(u32 h_control, u32 *pblend);
1636 u32 h_control, u32 *pblend);
1637 1461
1638u16 hpi_tuner_set_hd_radio_signal_blend(const struct hpi_hsubsys *ph_subsys, 1462u16 hpi_tuner_set_hd_radio_signal_blend(u32 h_control, const u32 blend);
1639 u32 h_control, const u32 blend);
1640 1463
1641/****************************/ 1464/***************/
1642/* PADs control */ 1465/* PAD control */
1643/****************************/ 1466/***************/
1644 1467
1645u16 HPI_PAD__get_channel_name(const struct hpi_hsubsys *ph_subsys, 1468u16 hpi_pad_get_channel_name(u32 h_control, char *psz_string,
1646 u32 h_control, char *psz_string, const u32 string_length); 1469 const u32 string_length);
1647 1470
1648u16 HPI_PAD__get_artist(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1471u16 hpi_pad_get_artist(u32 h_control, char *psz_string,
1649 char *psz_string, const u32 string_length); 1472 const u32 string_length);
1650 1473
1651u16 HPI_PAD__get_title(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1474u16 hpi_pad_get_title(u32 h_control, char *psz_string,
1652 char *psz_string, const u32 string_length); 1475 const u32 string_length);
1653 1476
1654u16 HPI_PAD__get_comment(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1477u16 hpi_pad_get_comment(u32 h_control, char *psz_string,
1655 char *psz_string, const u32 string_length); 1478 const u32 string_length);
1656 1479
1657u16 HPI_PAD__get_program_type(const struct hpi_hsubsys *ph_subsys, 1480u16 hpi_pad_get_program_type(u32 h_control, u32 *ppTY);
1658 u32 h_control, u32 *ppTY);
1659 1481
1660u16 HPI_PAD__get_rdsPI(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1482u16 hpi_pad_get_rdsPI(u32 h_control, u32 *ppI);
1661 u32 *ppI);
1662 1483
1663u16 HPI_PAD__get_program_type_string(const struct hpi_hsubsys *ph_subsys, 1484u16 hpi_pad_get_program_type_string(u32 h_control, const u32 data_type,
1664 u32 h_control, const u32 data_type, const u32 pTY, char *psz_string, 1485 const u32 pTY, char *psz_string, const u32 string_length);
1665 const u32 string_length);
1666 1486
1667/****************************/ 1487/****************************/
1668/* AES/EBU Receiver control */ 1488/* AES/EBU Receiver control */
1669/****************************/ 1489/****************************/
1670u16 HPI_AESEBU__receiver_query_format(const struct hpi_hsubsys *ph_subsys, 1490u16 hpi_aesebu_receiver_query_format(const u32 h_aes_rx, const u32 index,
1671 const u32 h_aes_rx, const u32 index, u16 *pw_format); 1491 u16 *pw_format);
1672 1492
1673u16 HPI_AESEBU__receiver_set_format(const struct hpi_hsubsys *ph_subsys, 1493u16 hpi_aesebu_receiver_set_format(u32 h_control, u16 source);
1674 u32 h_control, u16 source);
1675 1494
1676u16 HPI_AESEBU__receiver_get_format(const struct hpi_hsubsys *ph_subsys, 1495u16 hpi_aesebu_receiver_get_format(u32 h_control, u16 *pw_source);
1677 u32 h_control, u16 *pw_source);
1678 1496
1679u16 HPI_AESEBU__receiver_get_sample_rate(const struct hpi_hsubsys *ph_subsys, 1497u16 hpi_aesebu_receiver_get_sample_rate(u32 h_control, u32 *psample_rate);
1680 u32 h_control, u32 *psample_rate);
1681 1498
1682u16 HPI_AESEBU__receiver_get_user_data(const struct hpi_hsubsys *ph_subsys, 1499u16 hpi_aesebu_receiver_get_user_data(u32 h_control, u16 index, u16 *pw_data);
1683 u32 h_control, u16 index, u16 *pw_data);
1684 1500
1685u16 HPI_AESEBU__receiver_get_channel_status(const struct hpi_hsubsys 1501u16 hpi_aesebu_receiver_get_channel_status(u32 h_control, u16 index,
1686 *ph_subsys, u32 h_control, u16 index, u16 *pw_data); 1502 u16 *pw_data);
1687 1503
1688u16 HPI_AESEBU__receiver_get_error_status(const struct hpi_hsubsys *ph_subsys, 1504u16 hpi_aesebu_receiver_get_error_status(u32 h_control, u16 *pw_error_data);
1689 u32 h_control, u16 *pw_error_data);
1690 1505
1691/*******************************/ 1506/*******************************/
1692/* AES/EBU Transmitter control */ 1507/* AES/EBU Transmitter control */
1693/*******************************/ 1508/*******************************/
1694u16 HPI_AESEBU__transmitter_set_sample_rate(const struct hpi_hsubsys 1509u16 hpi_aesebu_transmitter_set_sample_rate(u32 h_control, u32 sample_rate);
1695 *ph_subsys, u32 h_control, u32 sample_rate);
1696 1510
1697u16 HPI_AESEBU__transmitter_set_user_data(const struct hpi_hsubsys *ph_subsys, 1511u16 hpi_aesebu_transmitter_set_user_data(u32 h_control, u16 index, u16 data);
1698 u32 h_control, u16 index, u16 data);
1699 1512
1700u16 HPI_AESEBU__transmitter_set_channel_status(const struct hpi_hsubsys 1513u16 hpi_aesebu_transmitter_set_channel_status(u32 h_control, u16 index,
1701 *ph_subsys, u32 h_control, u16 index, u16 data); 1514 u16 data);
1702 1515
1703u16 HPI_AESEBU__transmitter_get_channel_status(const struct hpi_hsubsys 1516u16 hpi_aesebu_transmitter_get_channel_status(u32 h_control, u16 index,
1704 *ph_subsys, u32 h_control, u16 index, u16 *pw_data); 1517 u16 *pw_data);
1705 1518
1706u16 HPI_AESEBU__transmitter_query_format(const struct hpi_hsubsys *ph_subsys, 1519u16 hpi_aesebu_transmitter_query_format(const u32 h_aes_tx, const u32 index,
1707 const u32 h_aes_tx, const u32 index, u16 *pw_format); 1520 u16 *pw_format);
1708 1521
1709u16 HPI_AESEBU__transmitter_set_format(const struct hpi_hsubsys *ph_subsys, 1522u16 hpi_aesebu_transmitter_set_format(u32 h_control, u16 output_format);
1710 u32 h_control, u16 output_format);
1711 1523
1712u16 HPI_AESEBU__transmitter_get_format(const struct hpi_hsubsys *ph_subsys, 1524u16 hpi_aesebu_transmitter_get_format(u32 h_control, u16 *pw_output_format);
1713 u32 h_control, u16 *pw_output_format);
1714 1525
1715/***********************/ 1526/***********************/
1716/* multiplexer control */ 1527/* Multiplexer control */
1717/***********************/ 1528/***********************/
1718u16 hpi_multiplexer_set_source(const struct hpi_hsubsys *ph_subsys, 1529u16 hpi_multiplexer_set_source(u32 h_control, u16 source_node_type,
1719 u32 h_control, u16 source_node_type, u16 source_node_index); 1530 u16 source_node_index);
1720
1721u16 hpi_multiplexer_get_source(const struct hpi_hsubsys *ph_subsys,
1722 u32 h_control, u16 *source_node_type, u16 *source_node_index);
1723 1531
1724u16 hpi_multiplexer_query_source(const struct hpi_hsubsys *ph_subsys, 1532u16 hpi_multiplexer_get_source(u32 h_control, u16 *source_node_type,
1725 u32 h_control, u16 index, u16 *source_node_type,
1726 u16 *source_node_index); 1533 u16 *source_node_index);
1727 1534
1535u16 hpi_multiplexer_query_source(u32 h_control, u16 index,
1536 u16 *source_node_type, u16 *source_node_index);
1537
1728/***************/ 1538/***************/
1729/* VOX control */ 1539/* Vox control */
1730/***************/ 1540/***************/
1731u16 hpi_vox_set_threshold(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1541u16 hpi_vox_set_threshold(u32 h_control, short an_gain0_01dB);
1732 short an_gain0_01dB);
1733 1542
1734u16 hpi_vox_get_threshold(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1543u16 hpi_vox_get_threshold(u32 h_control, short *an_gain0_01dB);
1735 short *an_gain0_01dB);
1736 1544
1737/*********************/ 1545/*********************/
1738/* Bitstream control */ 1546/* Bitstream control */
1739/*********************/ 1547/*********************/
1740u16 hpi_bitstream_set_clock_edge(const struct hpi_hsubsys *ph_subsys, 1548u16 hpi_bitstream_set_clock_edge(u32 h_control, u16 edge_type);
1741 u32 h_control, u16 edge_type);
1742 1549
1743u16 hpi_bitstream_set_data_polarity(const struct hpi_hsubsys *ph_subsys, 1550u16 hpi_bitstream_set_data_polarity(u32 h_control, u16 polarity);
1744 u32 h_control, u16 polarity);
1745 1551
1746u16 hpi_bitstream_get_activity(const struct hpi_hsubsys *ph_subsys, 1552u16 hpi_bitstream_get_activity(u32 h_control, u16 *pw_clk_activity,
1747 u32 h_control, u16 *pw_clk_activity, u16 *pw_data_activity); 1553 u16 *pw_data_activity);
1748 1554
1749/***********************/ 1555/***********************/
1750/* SampleClock control */ 1556/* SampleClock control */
1751/***********************/ 1557/***********************/
1752 1558
1753u16 hpi_sample_clock_query_source(const struct hpi_hsubsys *ph_subsys, 1559u16 hpi_sample_clock_query_source(const u32 h_clock, const u32 index,
1754 const u32 h_clock, const u32 index, u16 *pw_source); 1560 u16 *pw_source);
1755 1561
1756u16 hpi_sample_clock_set_source(const struct hpi_hsubsys *ph_subsys, 1562u16 hpi_sample_clock_set_source(u32 h_control, u16 source);
1757 u32 h_control, u16 source);
1758 1563
1759u16 hpi_sample_clock_get_source(const struct hpi_hsubsys *ph_subsys, 1564u16 hpi_sample_clock_get_source(u32 h_control, u16 *pw_source);
1760 u32 h_control, u16 *pw_source);
1761 1565
1762u16 hpi_sample_clock_query_source_index(const struct hpi_hsubsys *ph_subsys, 1566u16 hpi_sample_clock_query_source_index(const u32 h_clock, const u32 index,
1763 const u32 h_clock, const u32 index, const u32 source, 1567 const u32 source, u16 *pw_source_index);
1764 u16 *pw_source_index);
1765 1568
1766u16 hpi_sample_clock_set_source_index(const struct hpi_hsubsys *ph_subsys, 1569u16 hpi_sample_clock_set_source_index(u32 h_control, u16 source_index);
1767 u32 h_control, u16 source_index);
1768 1570
1769u16 hpi_sample_clock_get_source_index(const struct hpi_hsubsys *ph_subsys, 1571u16 hpi_sample_clock_get_source_index(u32 h_control, u16 *pw_source_index);
1770 u32 h_control, u16 *pw_source_index);
1771 1572
1772u16 hpi_sample_clock_get_sample_rate(const struct hpi_hsubsys *ph_subsys, 1573u16 hpi_sample_clock_get_sample_rate(u32 h_control, u32 *psample_rate);
1773 u32 h_control, u32 *psample_rate);
1774 1574
1775u16 hpi_sample_clock_query_local_rate(const struct hpi_hsubsys *ph_subsys, 1575u16 hpi_sample_clock_query_local_rate(const u32 h_clock, const u32 index,
1776 const u32 h_clock, const u32 index, u32 *psource); 1576 u32 *psource);
1777 1577
1778u16 hpi_sample_clock_set_local_rate(const struct hpi_hsubsys *ph_subsys, 1578u16 hpi_sample_clock_set_local_rate(u32 h_control, u32 sample_rate);
1779 u32 h_control, u32 sample_rate);
1780 1579
1781u16 hpi_sample_clock_get_local_rate(const struct hpi_hsubsys *ph_subsys, 1580u16 hpi_sample_clock_get_local_rate(u32 h_control, u32 *psample_rate);
1782 u32 h_control, u32 *psample_rate);
1783 1581
1784u16 hpi_sample_clock_set_auto(const struct hpi_hsubsys *ph_subsys, 1582u16 hpi_sample_clock_set_auto(u32 h_control, u32 enable);
1785 u32 h_control, u32 enable);
1786 1583
1787u16 hpi_sample_clock_get_auto(const struct hpi_hsubsys *ph_subsys, 1584u16 hpi_sample_clock_get_auto(u32 h_control, u32 *penable);
1788 u32 h_control, u32 *penable);
1789 1585
1790u16 hpi_sample_clock_set_local_rate_lock(const struct hpi_hsubsys *ph_subsys, 1586u16 hpi_sample_clock_set_local_rate_lock(u32 h_control, u32 lock);
1791 u32 h_control, u32 lock);
1792 1587
1793u16 hpi_sample_clock_get_local_rate_lock(const struct hpi_hsubsys *ph_subsys, 1588u16 hpi_sample_clock_get_local_rate_lock(u32 h_control, u32 *plock);
1794 u32 h_control, u32 *plock);
1795 1589
1796/***********************/ 1590/***********************/
1797/* Microphone control */ 1591/* Microphone control */
1798/***********************/ 1592/***********************/
1799u16 hpi_microphone_set_phantom_power(const struct hpi_hsubsys *ph_subsys, 1593u16 hpi_microphone_set_phantom_power(u32 h_control, u16 on_off);
1800 u32 h_control, u16 on_off);
1801 1594
1802u16 hpi_microphone_get_phantom_power(const struct hpi_hsubsys *ph_subsys, 1595u16 hpi_microphone_get_phantom_power(u32 h_control, u16 *pw_on_off);
1803 u32 h_control, u16 *pw_on_off);
1804 1596
1805/******************************* 1597/********************************/
1806 Parametric Equalizer control 1598/* Parametric Equalizer control */
1807*******************************/ 1599/********************************/
1808u16 hpi_parametricEQ__get_info(const struct hpi_hsubsys *ph_subsys, 1600u16 hpi_parametric_eq_get_info(u32 h_control, u16 *pw_number_of_bands,
1809 u32 h_control, u16 *pw_number_of_bands, u16 *pw_enabled); 1601 u16 *pw_enabled);
1810 1602
1811u16 hpi_parametricEQ__set_state(const struct hpi_hsubsys *ph_subsys, 1603u16 hpi_parametric_eq_set_state(u32 h_control, u16 on_off);
1812 u32 h_control, u16 on_off);
1813 1604
1814u16 hpi_parametricEQ__set_band(const struct hpi_hsubsys *ph_subsys, 1605u16 hpi_parametric_eq_set_band(u32 h_control, u16 index, u16 type,
1815 u32 h_control, u16 index, u16 type, u32 frequency_hz, short q100, 1606 u32 frequency_hz, short q100, short gain0_01dB);
1816 short gain0_01dB);
1817 1607
1818u16 hpi_parametricEQ__get_band(const struct hpi_hsubsys *ph_subsys, 1608u16 hpi_parametric_eq_get_band(u32 h_control, u16 index, u16 *pn_type,
1819 u32 h_control, u16 index, u16 *pn_type, u32 *pfrequency_hz, 1609 u32 *pfrequency_hz, short *pnQ100, short *pn_gain0_01dB);
1820 short *pnQ100, short *pn_gain0_01dB);
1821 1610
1822u16 hpi_parametricEQ__get_coeffs(const struct hpi_hsubsys *ph_subsys, 1611u16 hpi_parametric_eq_get_coeffs(u32 h_control, u16 index, short coeffs[5]
1823 u32 h_control, u16 index, short coeffs[5]
1824 ); 1612 );
1825 1613
1826/******************************* 1614/*******************************/
1827 Compressor Expander control 1615/* Compressor Expander control */
1828*******************************/ 1616/*******************************/
1829
1830u16 hpi_compander_set_enable(const struct hpi_hsubsys *ph_subsys,
1831 u32 h_control, u32 on);
1832
1833u16 hpi_compander_get_enable(const struct hpi_hsubsys *ph_subsys,
1834 u32 h_control, u32 *pon);
1835
1836u16 hpi_compander_set_makeup_gain(const struct hpi_hsubsys *ph_subsys,
1837 u32 h_control, short makeup_gain0_01dB);
1838
1839u16 hpi_compander_get_makeup_gain(const struct hpi_hsubsys *ph_subsys,
1840 u32 h_control, short *pn_makeup_gain0_01dB);
1841
1842u16 hpi_compander_set_attack_time_constant(const struct hpi_hsubsys
1843 *ph_subsys, u32 h_control, u32 index, u32 attack);
1844
1845u16 hpi_compander_get_attack_time_constant(const struct hpi_hsubsys
1846 *ph_subsys, u32 h_control, u32 index, u32 *pw_attack);
1847
1848u16 hpi_compander_set_decay_time_constant(const struct hpi_hsubsys *ph_subsys,
1849 u32 h_control, u32 index, u32 decay);
1850
1851u16 hpi_compander_get_decay_time_constant(const struct hpi_hsubsys *ph_subsys,
1852 u32 h_control, u32 index, u32 *pw_decay);
1853
1854u16 hpi_compander_set_threshold(const struct hpi_hsubsys *ph_subsys,
1855 u32 h_control, u32 index, short threshold0_01dB);
1856
1857u16 hpi_compander_get_threshold(const struct hpi_hsubsys *ph_subsys,
1858 u32 h_control, u32 index, short *pn_threshold0_01dB);
1859
1860u16 hpi_compander_set_ratio(const struct hpi_hsubsys *ph_subsys,
1861 u32 h_control, u32 index, u32 ratio100);
1862
1863u16 hpi_compander_get_ratio(const struct hpi_hsubsys *ph_subsys,
1864 u32 h_control, u32 index, u32 *pw_ratio100);
1865
1866/*******************************
1867 Cobranet HMI control
1868*******************************/
1869u16 hpi_cobranet_hmi_write(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1870 u32 hmi_address, u32 byte_count, u8 *pb_data);
1871
1872u16 hpi_cobranet_hmi_read(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1873 u32 hmi_address, u32 max_byte_count, u32 *pbyte_count, u8 *pb_data);
1874
1875u16 hpi_cobranet_hmi_get_status(const struct hpi_hsubsys *ph_subsys,
1876 u32 h_control, u32 *pstatus, u32 *preadable_size,
1877 u32 *pwriteable_size);
1878
1879/*Read the current IP address
1880*/
1881u16 hpi_cobranet_getI_paddress(const struct hpi_hsubsys *ph_subsys,
1882 u32 h_control, u32 *pi_paddress);
1883
1884/* Write the current IP address
1885*/
1886u16 hpi_cobranet_setI_paddress(const struct hpi_hsubsys *ph_subsys,
1887 u32 h_control, u32 i_paddress);
1888
1889/* Read the static IP address
1890*/
1891u16 hpi_cobranet_get_staticI_paddress(const struct hpi_hsubsys *ph_subsys,
1892 u32 h_control, u32 *pi_paddress);
1893 1617
1894/* Write the static IP address 1618u16 hpi_compander_set_enable(u32 h_control, u32 on);
1895*/
1896u16 hpi_cobranet_set_staticI_paddress(const struct hpi_hsubsys *ph_subsys,
1897 u32 h_control, u32 i_paddress);
1898 1619
1899/* Read the MAC address 1620u16 hpi_compander_get_enable(u32 h_control, u32 *pon);
1900*/
1901u16 hpi_cobranet_getMA_caddress(const struct hpi_hsubsys *ph_subsys,
1902 u32 h_control, u32 *pmAC_MS_bs, u32 *pmAC_LS_bs);
1903 1621
1904/******************************* 1622u16 hpi_compander_set_makeup_gain(u32 h_control, short makeup_gain0_01dB);
1905 Tone Detector control
1906*******************************/
1907u16 hpi_tone_detector_get_state(const struct hpi_hsubsys *ph_subsys, u32 hC,
1908 u32 *state);
1909 1623
1910u16 hpi_tone_detector_set_enable(const struct hpi_hsubsys *ph_subsys, u32 hC, 1624u16 hpi_compander_get_makeup_gain(u32 h_control, short *pn_makeup_gain0_01dB);
1911 u32 enable);
1912 1625
1913u16 hpi_tone_detector_get_enable(const struct hpi_hsubsys *ph_subsys, u32 hC, 1626u16 hpi_compander_set_attack_time_constant(u32 h_control, u32 index,
1914 u32 *enable); 1627 u32 attack);
1915 1628
1916u16 hpi_tone_detector_set_event_enable(const struct hpi_hsubsys *ph_subsys, 1629u16 hpi_compander_get_attack_time_constant(u32 h_control, u32 index,
1917 u32 hC, u32 event_enable); 1630 u32 *pw_attack);
1918 1631
1919u16 hpi_tone_detector_get_event_enable(const struct hpi_hsubsys *ph_subsys, 1632u16 hpi_compander_set_decay_time_constant(u32 h_control, u32 index,
1920 u32 hC, u32 *event_enable); 1633 u32 decay);
1921 1634
1922u16 hpi_tone_detector_set_threshold(const struct hpi_hsubsys *ph_subsys, 1635u16 hpi_compander_get_decay_time_constant(u32 h_control, u32 index,
1923 u32 hC, int threshold); 1636 u32 *pw_decay);
1924 1637
1925u16 hpi_tone_detector_get_threshold(const struct hpi_hsubsys *ph_subsys, 1638u16 hpi_compander_set_threshold(u32 h_control, u32 index,
1926 u32 hC, int *threshold); 1639 short threshold0_01dB);
1927 1640
1928u16 hpi_tone_detector_get_frequency(const struct hpi_hsubsys *ph_subsys, 1641u16 hpi_compander_get_threshold(u32 h_control, u32 index,
1929 u32 hC, u32 index, u32 *frequency); 1642 short *pn_threshold0_01dB);
1930 1643
1931/******************************* 1644u16 hpi_compander_set_ratio(u32 h_control, u32 index, u32 ratio100);
1932 Silence Detector control
1933*******************************/
1934u16 hpi_silence_detector_get_state(const struct hpi_hsubsys *ph_subsys,
1935 u32 hC, u32 *state);
1936 1645
1937u16 hpi_silence_detector_set_enable(const struct hpi_hsubsys *ph_subsys, 1646u16 hpi_compander_get_ratio(u32 h_control, u32 index, u32 *pw_ratio100);
1938 u32 hC, u32 enable);
1939 1647
1940u16 hpi_silence_detector_get_enable(const struct hpi_hsubsys *ph_subsys, 1648/********************/
1941 u32 hC, u32 *enable); 1649/* Cobranet control */
1650/********************/
1651u16 hpi_cobranet_hmi_write(u32 h_control, u32 hmi_address, u32 byte_count,
1652 u8 *pb_data);
1942 1653
1943u16 hpi_silence_detector_set_event_enable(const struct hpi_hsubsys *ph_subsys, 1654u16 hpi_cobranet_hmi_read(u32 h_control, u32 hmi_address, u32 max_byte_count,
1944 u32 hC, u32 event_enable); 1655 u32 *pbyte_count, u8 *pb_data);
1945 1656
1946u16 hpi_silence_detector_get_event_enable(const struct hpi_hsubsys *ph_subsys, 1657u16 hpi_cobranet_hmi_get_status(u32 h_control, u32 *pstatus,
1947 u32 hC, u32 *event_enable); 1658 u32 *preadable_size, u32 *pwriteable_size);
1948 1659
1949u16 hpi_silence_detector_set_delay(const struct hpi_hsubsys *ph_subsys, 1660u16 hpi_cobranet_get_ip_address(u32 h_control, u32 *pdw_ip_address);
1950 u32 hC, u32 delay);
1951 1661
1952u16 hpi_silence_detector_get_delay(const struct hpi_hsubsys *ph_subsys, 1662u16 hpi_cobranet_set_ip_address(u32 h_control, u32 dw_ip_address);
1953 u32 hC, u32 *delay);
1954 1663
1955u16 hpi_silence_detector_set_threshold(const struct hpi_hsubsys *ph_subsys, 1664u16 hpi_cobranet_get_static_ip_address(u32 h_control, u32 *pdw_ip_address);
1956 u32 hC, int threshold);
1957 1665
1958u16 hpi_silence_detector_get_threshold(const struct hpi_hsubsys *ph_subsys, 1666u16 hpi_cobranet_set_static_ip_address(u32 h_control, u32 dw_ip_address);
1959 u32 hC, int *threshold);
1960 1667
1961/******************************* 1668u16 hpi_cobranet_get_macaddress(u32 h_control, u32 *p_mac_msbs,
1962 Universal control 1669 u32 *p_mac_lsbs);
1963*******************************/
1964u16 hpi_entity_find_next(struct hpi_entity *container_entity,
1965 enum e_entity_type type, enum e_entity_role role, int recursive_flag,
1966 struct hpi_entity **current_match);
1967 1670
1968u16 hpi_entity_copy_value_from(struct hpi_entity *entity, 1671/*************************/
1969 enum e_entity_type type, size_t item_count, void *value_dst_p); 1672/* Tone Detector control */
1673/*************************/
1674u16 hpi_tone_detector_get_state(u32 hC, u32 *state);
1970 1675
1971u16 hpi_entity_unpack(struct hpi_entity *entity, enum e_entity_type *type, 1676u16 hpi_tone_detector_set_enable(u32 hC, u32 enable);
1972 size_t *items, enum e_entity_role *role, void **value);
1973 1677
1974u16 hpi_entity_alloc_and_pack(const enum e_entity_type type, 1678u16 hpi_tone_detector_get_enable(u32 hC, u32 *enable);
1975 const size_t item_count, const enum e_entity_role role, void *value,
1976 struct hpi_entity **entity);
1977 1679
1978void hpi_entity_free(struct hpi_entity *entity); 1680u16 hpi_tone_detector_set_event_enable(u32 hC, u32 event_enable);
1979 1681
1980u16 hpi_universal_info(const struct hpi_hsubsys *ph_subsys, u32 hC, 1682u16 hpi_tone_detector_get_event_enable(u32 hC, u32 *event_enable);
1981 struct hpi_entity **info);
1982 1683
1983u16 hpi_universal_get(const struct hpi_hsubsys *ph_subsys, u32 hC, 1684u16 hpi_tone_detector_set_threshold(u32 hC, int threshold);
1984 struct hpi_entity **value);
1985 1685
1986u16 hpi_universal_set(const struct hpi_hsubsys *ph_subsys, u32 hC, 1686u16 hpi_tone_detector_get_threshold(u32 hC, int *threshold);
1987 struct hpi_entity *value);
1988 1687
1989/*/////////// */ 1688u16 hpi_tone_detector_get_frequency(u32 hC, u32 index, u32 *frequency);
1990/* DSP CLOCK */
1991/*/////////// */
1992u16 hpi_clock_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
1993 u32 *ph_dsp_clock);
1994 1689
1995u16 hpi_clock_set_time(const struct hpi_hsubsys *ph_subsys, u32 h_clock, 1690/****************************/
1996 u16 hour, u16 minute, u16 second, u16 milli_second); 1691/* Silence Detector control */
1692/****************************/
1693u16 hpi_silence_detector_get_state(u32 hC, u32 *state);
1997 1694
1998u16 hpi_clock_get_time(const struct hpi_hsubsys *ph_subsys, u32 h_clock, 1695u16 hpi_silence_detector_set_enable(u32 hC, u32 enable);
1999 u16 *pw_hour, u16 *pw_minute, u16 *pw_second, u16 *pw_milli_second);
2000 1696
2001/*/////////// */ 1697u16 hpi_silence_detector_get_enable(u32 hC, u32 *enable);
2002/* PROFILE */
2003/*/////////// */
2004u16 hpi_profile_open_all(const struct hpi_hsubsys *ph_subsys,
2005 u16 adapter_index, u16 profile_index, u32 *ph_profile,
2006 u16 *pw_max_profiles);
2007 1698
2008u16 hpi_profile_get(const struct hpi_hsubsys *ph_subsys, u32 h_profile, 1699u16 hpi_silence_detector_set_event_enable(u32 hC, u32 event_enable);
2009 u16 index, u16 *pw_seconds, u32 *pmicro_seconds, u32 *pcall_count,
2010 u32 *pmax_micro_seconds, u32 *pmin_micro_seconds);
2011 1700
2012u16 hpi_profile_start_all(const struct hpi_hsubsys *ph_subsys, u32 h_profile); 1701u16 hpi_silence_detector_get_event_enable(u32 hC, u32 *event_enable);
2013 1702
2014u16 hpi_profile_stop_all(const struct hpi_hsubsys *ph_subsys, u32 h_profile); 1703u16 hpi_silence_detector_set_delay(u32 hC, u32 delay);
2015 1704
2016u16 hpi_profile_get_name(const struct hpi_hsubsys *ph_subsys, u32 h_profile, 1705u16 hpi_silence_detector_get_delay(u32 hC, u32 *delay);
2017 u16 index, char *sz_profile_name, u16 profile_name_length);
2018 1706
2019u16 hpi_profile_get_utilization(const struct hpi_hsubsys *ph_subsys, 1707u16 hpi_silence_detector_set_threshold(u32 hC, int threshold);
2020 u32 h_profile, u32 *putilization);
2021 1708
2022/*//////////////////// */ 1709u16 hpi_silence_detector_get_threshold(u32 hC, int *threshold);
2023/* UTILITY functions */ 1710/*********************/
1711/* Utility functions */
1712/*********************/
2024 1713
2025u16 hpi_format_create(struct hpi_format *p_format, u16 channels, u16 format, 1714u16 hpi_format_create(struct hpi_format *p_format, u16 channels, u16 format,
2026 u32 sample_rate, u32 bit_rate, u32 attributes); 1715 u32 sample_rate, u32 bit_rate, u32 attributes);
2027 1716
2028/* Until it's verified, this function is for Windows OSs only */ 1717#endif /*_HPI_H_ */
2029
2030#endif /*_H_HPI_ */
2031/*
2032///////////////////////////////////////////////////////////////////////////////
2033// See CVS for history. Last complete set in rev 1.146
2034////////////////////////////////////////////////////////////////////////////////
2035*/
diff --git a/sound/pci/asihpi/hpi6000.c b/sound/pci/asihpi/hpi6000.c
index 1b9bf9395cfe..3e3c2ef6efd8 100644
--- a/sound/pci/asihpi/hpi6000.c
+++ b/sound/pci/asihpi/hpi6000.c
@@ -43,16 +43,17 @@
43#define HPI_HIF_ERROR_MASK 0x4000 43#define HPI_HIF_ERROR_MASK 0x4000
44 44
45/* HPI6000 specific error codes */ 45/* HPI6000 specific error codes */
46#define HPI6000_ERROR_BASE 900 /* not actually used anywhere */
46 47
47#define HPI6000_ERROR_BASE 900 48/* operational/messaging errors */
48#define HPI6000_ERROR_MSG_RESP_IDLE_TIMEOUT 901 49#define HPI6000_ERROR_MSG_RESP_IDLE_TIMEOUT 901
49#define HPI6000_ERROR_MSG_RESP_SEND_MSG_ACK 902 50
50#define HPI6000_ERROR_MSG_RESP_GET_RESP_ACK 903 51#define HPI6000_ERROR_MSG_RESP_GET_RESP_ACK 903
51#define HPI6000_ERROR_MSG_GET_ADR 904 52#define HPI6000_ERROR_MSG_GET_ADR 904
52#define HPI6000_ERROR_RESP_GET_ADR 905 53#define HPI6000_ERROR_RESP_GET_ADR 905
53#define HPI6000_ERROR_MSG_RESP_BLOCKWRITE32 906 54#define HPI6000_ERROR_MSG_RESP_BLOCKWRITE32 906
54#define HPI6000_ERROR_MSG_RESP_BLOCKREAD32 907 55#define HPI6000_ERROR_MSG_RESP_BLOCKREAD32 907
55#define HPI6000_ERROR_MSG_INVALID_DSP_INDEX 908 56
56#define HPI6000_ERROR_CONTROL_CACHE_PARAMS 909 57#define HPI6000_ERROR_CONTROL_CACHE_PARAMS 909
57 58
58#define HPI6000_ERROR_SEND_DATA_IDLE_TIMEOUT 911 59#define HPI6000_ERROR_SEND_DATA_IDLE_TIMEOUT 911
@@ -62,7 +63,6 @@
62#define HPI6000_ERROR_SEND_DATA_CMD 915 63#define HPI6000_ERROR_SEND_DATA_CMD 915
63#define HPI6000_ERROR_SEND_DATA_WRITE 916 64#define HPI6000_ERROR_SEND_DATA_WRITE 916
64#define HPI6000_ERROR_SEND_DATA_IDLECMD 917 65#define HPI6000_ERROR_SEND_DATA_IDLECMD 917
65#define HPI6000_ERROR_SEND_DATA_VERIFY 918
66 66
67#define HPI6000_ERROR_GET_DATA_IDLE_TIMEOUT 921 67#define HPI6000_ERROR_GET_DATA_IDLE_TIMEOUT 921
68#define HPI6000_ERROR_GET_DATA_ACK 922 68#define HPI6000_ERROR_GET_DATA_ACK 922
@@ -76,9 +76,8 @@
76 76
77#define HPI6000_ERROR_MSG_RESP_GETRESPCMD 961 77#define HPI6000_ERROR_MSG_RESP_GETRESPCMD 961
78#define HPI6000_ERROR_MSG_RESP_IDLECMD 962 78#define HPI6000_ERROR_MSG_RESP_IDLECMD 962
79#define HPI6000_ERROR_MSG_RESP_BLOCKVERIFY32 963
80 79
81/* adapter init errors */ 80/* Initialisation/bootload errors */
82#define HPI6000_ERROR_UNHANDLED_SUBSYS_ID 930 81#define HPI6000_ERROR_UNHANDLED_SUBSYS_ID 930
83 82
84/* can't access PCI2040 */ 83/* can't access PCI2040 */
@@ -210,6 +209,8 @@ static void adapter_get_asserts(struct hpi_adapter_obj *pao,
210static short create_adapter_obj(struct hpi_adapter_obj *pao, 209static short create_adapter_obj(struct hpi_adapter_obj *pao,
211 u32 *pos_error_code); 210 u32 *pos_error_code);
212 211
212static void delete_adapter_obj(struct hpi_adapter_obj *pao);
213
213/* local globals */ 214/* local globals */
214 215
215static u16 gw_pci_read_asserts; /* used to count PCI2040 errors */ 216static u16 gw_pci_read_asserts; /* used to count PCI2040 errors */
@@ -217,17 +218,7 @@ static u16 gw_pci_write_asserts; /* used to count PCI2040 errors */
217 218
218static void subsys_message(struct hpi_message *phm, struct hpi_response *phr) 219static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
219{ 220{
220
221 switch (phm->function) { 221 switch (phm->function) {
222 case HPI_SUBSYS_OPEN:
223 case HPI_SUBSYS_CLOSE:
224 case HPI_SUBSYS_GET_INFO:
225 case HPI_SUBSYS_DRIVER_UNLOAD:
226 case HPI_SUBSYS_DRIVER_LOAD:
227 case HPI_SUBSYS_FIND_ADAPTERS:
228 /* messages that should not get here */
229 phr->error = HPI_ERROR_UNIMPLEMENTED;
230 break;
231 case HPI_SUBSYS_CREATE_ADAPTER: 222 case HPI_SUBSYS_CREATE_ADAPTER:
232 subsys_create_adapter(phm, phr); 223 subsys_create_adapter(phm, phr);
233 break; 224 break;
@@ -243,7 +234,6 @@ static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
243static void control_message(struct hpi_adapter_obj *pao, 234static void control_message(struct hpi_adapter_obj *pao,
244 struct hpi_message *phm, struct hpi_response *phr) 235 struct hpi_message *phm, struct hpi_response *phr)
245{ 236{
246
247 switch (phm->function) { 237 switch (phm->function) {
248 case HPI_CONTROL_GET_STATE: 238 case HPI_CONTROL_GET_STATE:
249 if (pao->has_control_cache) { 239 if (pao->has_control_cache) {
@@ -251,7 +241,13 @@ static void control_message(struct hpi_adapter_obj *pao,
251 err = hpi6000_update_control_cache(pao, phm); 241 err = hpi6000_update_control_cache(pao, phm);
252 242
253 if (err) { 243 if (err) {
254 phr->error = err; 244 if (err >= HPI_ERROR_BACKEND_BASE) {
245 phr->error =
246 HPI_ERROR_CONTROL_CACHING;
247 phr->specific_error = err;
248 } else {
249 phr->error = err;
250 }
255 break; 251 break;
256 } 252 }
257 253
@@ -262,16 +258,15 @@ static void control_message(struct hpi_adapter_obj *pao,
262 } 258 }
263 hw_message(pao, phm, phr); 259 hw_message(pao, phm, phr);
264 break; 260 break;
265 case HPI_CONTROL_GET_INFO:
266 hw_message(pao, phm, phr);
267 break;
268 case HPI_CONTROL_SET_STATE: 261 case HPI_CONTROL_SET_STATE:
269 hw_message(pao, phm, phr); 262 hw_message(pao, phm, phr);
270 hpi_sync_control_cache(((struct hpi_hw_obj *)pao->priv)-> 263 hpi_cmn_control_cache_sync_to_msg(((struct hpi_hw_obj *)pao->
271 p_cache, phm, phr); 264 priv)->p_cache, phm, phr);
272 break; 265 break;
266
267 case HPI_CONTROL_GET_INFO:
273 default: 268 default:
274 phr->error = HPI_ERROR_INVALID_FUNC; 269 hw_message(pao, phm, phr);
275 break; 270 break;
276 } 271 }
277} 272}
@@ -280,26 +275,12 @@ static void adapter_message(struct hpi_adapter_obj *pao,
280 struct hpi_message *phm, struct hpi_response *phr) 275 struct hpi_message *phm, struct hpi_response *phr)
281{ 276{
282 switch (phm->function) { 277 switch (phm->function) {
283 case HPI_ADAPTER_GET_INFO:
284 hw_message(pao, phm, phr);
285 break;
286 case HPI_ADAPTER_GET_ASSERT: 278 case HPI_ADAPTER_GET_ASSERT:
287 adapter_get_asserts(pao, phm, phr); 279 adapter_get_asserts(pao, phm, phr);
288 break; 280 break;
289 case HPI_ADAPTER_OPEN: 281
290 case HPI_ADAPTER_CLOSE:
291 case HPI_ADAPTER_TEST_ASSERT:
292 case HPI_ADAPTER_SELFTEST:
293 case HPI_ADAPTER_GET_MODE:
294 case HPI_ADAPTER_SET_MODE:
295 case HPI_ADAPTER_FIND_OBJECT:
296 case HPI_ADAPTER_GET_PROPERTY:
297 case HPI_ADAPTER_SET_PROPERTY:
298 case HPI_ADAPTER_ENUM_PROPERTY:
299 hw_message(pao, phm, phr);
300 break;
301 default: 282 default:
302 phr->error = HPI_ERROR_INVALID_FUNC; 283 hw_message(pao, phm, phr);
303 break; 284 break;
304 } 285 }
305} 286}
@@ -311,7 +292,7 @@ static void outstream_message(struct hpi_adapter_obj *pao,
311 case HPI_OSTREAM_HOSTBUFFER_ALLOC: 292 case HPI_OSTREAM_HOSTBUFFER_ALLOC:
312 case HPI_OSTREAM_HOSTBUFFER_FREE: 293 case HPI_OSTREAM_HOSTBUFFER_FREE:
313 /* Don't let these messages go to the HW function because 294 /* Don't let these messages go to the HW function because
314 * they're called without allocating the spinlock. 295 * they're called without locking the spinlock.
315 * For the HPI6000 adapters the HW would return 296 * For the HPI6000 adapters the HW would return
316 * HPI_ERROR_INVALID_FUNC anyway. 297 * HPI_ERROR_INVALID_FUNC anyway.
317 */ 298 */
@@ -331,7 +312,7 @@ static void instream_message(struct hpi_adapter_obj *pao,
331 case HPI_ISTREAM_HOSTBUFFER_ALLOC: 312 case HPI_ISTREAM_HOSTBUFFER_ALLOC:
332 case HPI_ISTREAM_HOSTBUFFER_FREE: 313 case HPI_ISTREAM_HOSTBUFFER_FREE:
333 /* Don't let these messages go to the HW function because 314 /* Don't let these messages go to the HW function because
334 * they're called without allocating the spinlock. 315 * they're called without locking the spinlock.
335 * For the HPI6000 adapters the HW would return 316 * For the HPI6000 adapters the HW would return
336 * HPI_ERROR_INVALID_FUNC anyway. 317 * HPI_ERROR_INVALID_FUNC anyway.
337 */ 318 */
@@ -355,7 +336,7 @@ void HPI_6000(struct hpi_message *phm, struct hpi_response *phr)
355 /* subsytem messages get executed by every HPI. */ 336 /* subsytem messages get executed by every HPI. */
356 /* All other messages are ignored unless the adapter index matches */ 337 /* All other messages are ignored unless the adapter index matches */
357 /* an adapter in the HPI */ 338 /* an adapter in the HPI */
358 HPI_DEBUG_LOG(DEBUG, "O %d,F %x\n", phm->object, phm->function); 339 /*HPI_DEBUG_LOG(DEBUG, "O %d,F %x\n", phm->wObject, phm->wFunction); */
359 340
360 /* if Dsp has crashed then do not communicate with it any more */ 341 /* if Dsp has crashed then do not communicate with it any more */
361 if (phm->object != HPI_OBJ_SUBSYSTEM) { 342 if (phm->object != HPI_OBJ_SUBSYSTEM) {
@@ -433,21 +414,13 @@ static void subsys_create_adapter(struct hpi_message *phm,
433 struct hpi_adapter_obj ao; 414 struct hpi_adapter_obj ao;
434 struct hpi_adapter_obj *pao; 415 struct hpi_adapter_obj *pao;
435 u32 os_error_code; 416 u32 os_error_code;
436 short error = 0; 417 u16 err = 0;
437 u32 dsp_index = 0; 418 u32 dsp_index = 0;
438 419
439 HPI_DEBUG_LOG(VERBOSE, "subsys_create_adapter\n"); 420 HPI_DEBUG_LOG(VERBOSE, "subsys_create_adapter\n");
440 421
441 memset(&ao, 0, sizeof(ao)); 422 memset(&ao, 0, sizeof(ao));
442 423
443 /* this HPI only creates adapters for TI/PCI2040 based devices */
444 if (phm->u.s.resource.bus_type != HPI_BUS_PCI)
445 return;
446 if (phm->u.s.resource.r.pci->vendor_id != HPI_PCI_VENDOR_ID_TI)
447 return;
448 if (phm->u.s.resource.r.pci->device_id != HPI_PCI_DEV_ID_PCI2040)
449 return;
450
451 ao.priv = kzalloc(sizeof(struct hpi_hw_obj), GFP_KERNEL); 424 ao.priv = kzalloc(sizeof(struct hpi_hw_obj), GFP_KERNEL);
452 if (!ao.priv) { 425 if (!ao.priv) {
453 HPI_DEBUG_LOG(ERROR, "cant get mem for adapter object\n"); 426 HPI_DEBUG_LOG(ERROR, "cant get mem for adapter object\n");
@@ -456,16 +429,19 @@ static void subsys_create_adapter(struct hpi_message *phm,
456 } 429 }
457 430
458 /* create the adapter object based on the resource information */ 431 /* create the adapter object based on the resource information */
459 /*? memcpy(&ao.Pci,&phm->u.s.Resource.r.Pci,sizeof(ao.Pci)); */
460 ao.pci = *phm->u.s.resource.r.pci; 432 ao.pci = *phm->u.s.resource.r.pci;
461 433
462 error = create_adapter_obj(&ao, &os_error_code); 434 err = create_adapter_obj(&ao, &os_error_code);
463 if (!error) 435 if (err) {
464 error = hpi_add_adapter(&ao); 436 delete_adapter_obj(&ao);
465 if (error) { 437 if (err >= HPI_ERROR_BACKEND_BASE) {
438 phr->error = HPI_ERROR_DSP_BOOTLOAD;
439 phr->specific_error = err;
440 } else {
441 phr->error = err;
442 }
443
466 phr->u.s.data = os_error_code; 444 phr->u.s.data = os_error_code;
467 kfree(ao.priv);
468 phr->error = error;
469 return; 445 return;
470 } 446 }
471 /* need to update paParentAdapter */ 447 /* need to update paParentAdapter */
@@ -473,7 +449,7 @@ static void subsys_create_adapter(struct hpi_message *phm,
473 if (!pao) { 449 if (!pao) {
474 /* We just added this adapter, why can't we find it!? */ 450 /* We just added this adapter, why can't we find it!? */
475 HPI_DEBUG_LOG(ERROR, "lost adapter after boot\n"); 451 HPI_DEBUG_LOG(ERROR, "lost adapter after boot\n");
476 phr->error = 950; 452 phr->error = HPI_ERROR_BAD_ADAPTER;
477 return; 453 return;
478 } 454 }
479 455
@@ -482,9 +458,8 @@ static void subsys_create_adapter(struct hpi_message *phm,
482 phw->ado[dsp_index].pa_parent_adapter = pao; 458 phw->ado[dsp_index].pa_parent_adapter = pao;
483 } 459 }
484 460
485 phr->u.s.aw_adapter_list[ao.index] = ao.adapter_type; 461 phr->u.s.adapter_type = ao.adapter_type;
486 phr->u.s.adapter_index = ao.index; 462 phr->u.s.adapter_index = ao.index;
487 phr->u.s.num_adapters++;
488 phr->error = 0; 463 phr->error = 0;
489} 464}
490 465
@@ -492,20 +467,13 @@ static void subsys_delete_adapter(struct hpi_message *phm,
492 struct hpi_response *phr) 467 struct hpi_response *phr)
493{ 468{
494 struct hpi_adapter_obj *pao = NULL; 469 struct hpi_adapter_obj *pao = NULL;
495 struct hpi_hw_obj *phw;
496 470
497 pao = hpi_find_adapter(phm->adapter_index); 471 pao = hpi_find_adapter(phm->obj_index);
498 if (!pao) 472 if (!pao)
499 return; 473 return;
500 474
501 phw = (struct hpi_hw_obj *)pao->priv; 475 delete_adapter_obj(pao);
502
503 if (pao->has_control_cache)
504 hpi_free_control_cache(phw->p_cache);
505
506 hpi_delete_adapter(pao); 476 hpi_delete_adapter(pao);
507 kfree(phw);
508
509 phr->error = 0; 477 phr->error = 0;
510} 478}
511 479
@@ -519,9 +487,6 @@ static short create_adapter_obj(struct hpi_adapter_obj *pao,
519 u32 control_cache_count = 0; 487 u32 control_cache_count = 0;
520 struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv; 488 struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv;
521 489
522 /* init error reporting */
523 pao->dsp_crashed = 0;
524
525 /* The PCI2040 has the following address map */ 490 /* The PCI2040 has the following address map */
526 /* BAR0 - 4K = HPI control and status registers on PCI2040 (HPI CSR) */ 491 /* BAR0 - 4K = HPI control and status registers on PCI2040 (HPI CSR) */
527 /* BAR1 - 32K = HPI registers on DSP */ 492 /* BAR1 - 32K = HPI registers on DSP */
@@ -575,36 +540,36 @@ static short create_adapter_obj(struct hpi_adapter_obj *pao,
575 /* get info about the adapter by asking the adapter */ 540 /* get info about the adapter by asking the adapter */
576 /* send a HPI_ADAPTER_GET_INFO message */ 541 /* send a HPI_ADAPTER_GET_INFO message */
577 { 542 {
578 struct hpi_message hM; 543 struct hpi_message hm;
579 struct hpi_response hR0; /* response from DSP 0 */ 544 struct hpi_response hr0; /* response from DSP 0 */
580 struct hpi_response hR1; /* response from DSP 1 */ 545 struct hpi_response hr1; /* response from DSP 1 */
581 u16 error = 0; 546 u16 error = 0;
582 547
583 HPI_DEBUG_LOG(VERBOSE, "send ADAPTER_GET_INFO\n"); 548 HPI_DEBUG_LOG(VERBOSE, "send ADAPTER_GET_INFO\n");
584 memset(&hM, 0, sizeof(hM)); 549 memset(&hm, 0, sizeof(hm));
585 hM.type = HPI_TYPE_MESSAGE; 550 hm.type = HPI_TYPE_MESSAGE;
586 hM.size = sizeof(struct hpi_message); 551 hm.size = sizeof(struct hpi_message);
587 hM.object = HPI_OBJ_ADAPTER; 552 hm.object = HPI_OBJ_ADAPTER;
588 hM.function = HPI_ADAPTER_GET_INFO; 553 hm.function = HPI_ADAPTER_GET_INFO;
589 hM.adapter_index = 0; 554 hm.adapter_index = 0;
590 memset(&hR0, 0, sizeof(hR0)); 555 memset(&hr0, 0, sizeof(hr0));
591 memset(&hR1, 0, sizeof(hR1)); 556 memset(&hr1, 0, sizeof(hr1));
592 hR0.size = sizeof(hR0); 557 hr0.size = sizeof(hr0);
593 hR1.size = sizeof(hR1); 558 hr1.size = sizeof(hr1);
594 559
595 error = hpi6000_message_response_sequence(pao, 0, &hM, &hR0); 560 error = hpi6000_message_response_sequence(pao, 0, &hm, &hr0);
596 if (hR0.error) { 561 if (hr0.error) {
597 HPI_DEBUG_LOG(DEBUG, "message error %d\n", hR0.error); 562 HPI_DEBUG_LOG(DEBUG, "message error %d\n", hr0.error);
598 return hR0.error; 563 return hr0.error;
599 } 564 }
600 if (phw->num_dsp == 2) { 565 if (phw->num_dsp == 2) {
601 error = hpi6000_message_response_sequence(pao, 1, &hM, 566 error = hpi6000_message_response_sequence(pao, 1, &hm,
602 &hR1); 567 &hr1);
603 if (error) 568 if (error)
604 return error; 569 return error;
605 } 570 }
606 pao->adapter_type = hR0.u.a.adapter_type; 571 pao->adapter_type = hr0.u.ax.info.adapter_type;
607 pao->index = hR0.u.a.adapter_index; 572 pao->index = hr0.u.ax.info.adapter_index;
608 } 573 }
609 574
610 memset(&phw->control_cache[0], 0, 575 memset(&phw->control_cache[0], 0,
@@ -618,22 +583,37 @@ static short create_adapter_obj(struct hpi_adapter_obj *pao,
618 control_cache_count = 583 control_cache_count =
619 hpi_read_word(&phw->ado[0], 584 hpi_read_word(&phw->ado[0],
620 HPI_HIF_ADDR(control_cache_count)); 585 HPI_HIF_ADDR(control_cache_count));
621 pao->has_control_cache = 1;
622 586
623 phw->p_cache = 587 phw->p_cache =
624 hpi_alloc_control_cache(control_cache_count, 588 hpi_alloc_control_cache(control_cache_count,
625 control_cache_size, (struct hpi_control_cache_info *) 589 control_cache_size, (unsigned char *)
626 &phw->control_cache[0] 590 &phw->control_cache[0]
627 ); 591 );
628 if (!phw->p_cache) 592 if (phw->p_cache)
629 pao->has_control_cache = 0; 593 pao->has_control_cache = 1;
630 } else 594 }
631 pao->has_control_cache = 0;
632 595
633 HPI_DEBUG_LOG(DEBUG, "get adapter info ASI%04X index %d\n", 596 HPI_DEBUG_LOG(DEBUG, "get adapter info ASI%04X index %d\n",
634 pao->adapter_type, pao->index); 597 pao->adapter_type, pao->index);
635 pao->open = 0; /* upon creation the adapter is closed */ 598 pao->open = 0; /* upon creation the adapter is closed */
636 return 0; 599
600 if (phw->p_cache)
601 phw->p_cache->adap_idx = pao->index;
602
603 return hpi_add_adapter(pao);
604}
605
606static void delete_adapter_obj(struct hpi_adapter_obj *pao)
607{
608 struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv;
609
610 if (pao->has_control_cache)
611 hpi_free_control_cache(phw->p_cache);
612
613 /* reset DSPs on adapter */
614 iowrite32(0x0003000F, phw->dw2040_HPICSR + HPI_RESET);
615
616 kfree(phw);
637} 617}
638 618
639/************************************************************************/ 619/************************************************************************/
@@ -645,11 +625,13 @@ static void adapter_get_asserts(struct hpi_adapter_obj *pao,
645#ifndef HIDE_PCI_ASSERTS 625#ifndef HIDE_PCI_ASSERTS
646 /* if we have PCI2040 asserts then collect them */ 626 /* if we have PCI2040 asserts then collect them */
647 if ((gw_pci_read_asserts > 0) || (gw_pci_write_asserts > 0)) { 627 if ((gw_pci_read_asserts > 0) || (gw_pci_write_asserts > 0)) {
648 phr->u.a.serial_number = 628 phr->u.ax.assert.p1 =
649 gw_pci_read_asserts * 100 + gw_pci_write_asserts; 629 gw_pci_read_asserts * 100 + gw_pci_write_asserts;
650 phr->u.a.adapter_index = 1; /* assert count */ 630 phr->u.ax.assert.p2 = 0;
651 phr->u.a.adapter_type = -1; /* "dsp index" */ 631 phr->u.ax.assert.count = 1; /* assert count */
652 strcpy(phr->u.a.sz_adapter_assert, "PCI2040 error"); 632 phr->u.ax.assert.dsp_index = -1; /* "dsp index" */
633 strcpy(phr->u.ax.assert.sz_message, "PCI2040 error");
634 phr->u.ax.assert.dsp_msg_addr = 0;
653 gw_pci_read_asserts = 0; 635 gw_pci_read_asserts = 0;
654 gw_pci_write_asserts = 0; 636 gw_pci_write_asserts = 0;
655 phr->error = 0; 637 phr->error = 0;
@@ -686,10 +668,10 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
686 668
687 /* NOTE don't use wAdapterType in this routine. It is not setup yet */ 669 /* NOTE don't use wAdapterType in this routine. It is not setup yet */
688 670
689 switch (pao->pci.subsys_device_id) { 671 switch (pao->pci.pci_dev->subsystem_device) {
690 case 0x5100: 672 case 0x5100:
691 case 0x5110: /* ASI5100 revB or higher with C6711D */ 673 case 0x5110: /* ASI5100 revB or higher with C6711D */
692 case 0x5200: /* ASI5200 PC_ie version of ASI5100 */ 674 case 0x5200: /* ASI5200 PCIe version of ASI5100 */
693 case 0x6100: 675 case 0x6100:
694 case 0x6200: 676 case 0x6200:
695 boot_load_family = HPI_ADAPTER_FAMILY_ASI(0x6200); 677 boot_load_family = HPI_ADAPTER_FAMILY_ASI(0x6200);
@@ -709,8 +691,9 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
709 * note that bits 4..15 are read-only and so should always return zero, 691 * note that bits 4..15 are read-only and so should always return zero,
710 * even though we wrote 1 to them 692 * even though we wrote 1 to them
711 */ 693 */
712 for (i = 0; i < 1000; i++) 694 hpios_delay_micro_seconds(1000);
713 delay = ioread32(phw->dw2040_HPICSR + HPI_RESET); 695 delay = ioread32(phw->dw2040_HPICSR + HPI_RESET);
696
714 if (delay != dw2040_reset) { 697 if (delay != dw2040_reset) {
715 HPI_DEBUG_LOG(ERROR, "INIT_PCI2040 %x %x\n", dw2040_reset, 698 HPI_DEBUG_LOG(ERROR, "INIT_PCI2040 %x %x\n", dw2040_reset,
716 delay); 699 delay);
@@ -743,8 +726,7 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
743 dw2040_reset = dw2040_reset & (~0x00000008); 726 dw2040_reset = dw2040_reset & (~0x00000008);
744 iowrite32(dw2040_reset, phw->dw2040_HPICSR + HPI_RESET); 727 iowrite32(dw2040_reset, phw->dw2040_HPICSR + HPI_RESET);
745 /*delay to allow DSP to get going */ 728 /*delay to allow DSP to get going */
746 for (i = 0; i < 100; i++) 729 hpios_delay_micro_seconds(100);
747 delay = ioread32(phw->dw2040_HPICSR + HPI_RESET);
748 730
749 /* loop through all DSPs, downloading DSP code */ 731 /* loop through all DSPs, downloading DSP code */
750 for (dsp_index = 0; dsp_index < phw->num_dsp; dsp_index++) { 732 for (dsp_index = 0; dsp_index < phw->num_dsp; dsp_index++) {
@@ -783,27 +765,27 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
783 */ 765 */
784 /* bypass PLL */ 766 /* bypass PLL */
785 hpi_write_word(pdo, 0x01B7C100, 0x0000); 767 hpi_write_word(pdo, 0x01B7C100, 0x0000);
786 for (i = 0; i < 100; i++) 768 hpios_delay_micro_seconds(100);
787 delay = ioread32(phw->dw2040_HPICSR +
788 HPI_RESET);
789 769
790 /* ** use default of PLL x7 ** */ 770 /* ** use default of PLL x7 ** */
791 /* EMIF = 225/3=75MHz */ 771 /* EMIF = 225/3=75MHz */
792 hpi_write_word(pdo, 0x01B7C120, 0x8002); 772 hpi_write_word(pdo, 0x01B7C120, 0x8002);
773 hpios_delay_micro_seconds(100);
774
793 /* peri = 225/2 */ 775 /* peri = 225/2 */
794 hpi_write_word(pdo, 0x01B7C11C, 0x8001); 776 hpi_write_word(pdo, 0x01B7C11C, 0x8001);
777 hpios_delay_micro_seconds(100);
778
795 /* cpu = 225/1 */ 779 /* cpu = 225/1 */
796 hpi_write_word(pdo, 0x01B7C118, 0x8000); 780 hpi_write_word(pdo, 0x01B7C118, 0x8000);
797 /* ~200us delay */ 781
798 for (i = 0; i < 2000; i++) 782 /* ~2ms delay */
799 delay = ioread32(phw->dw2040_HPICSR + 783 hpios_delay_micro_seconds(2000);
800 HPI_RESET); 784
801 /* PLL not bypassed */ 785 /* PLL not bypassed */
802 hpi_write_word(pdo, 0x01B7C100, 0x0001); 786 hpi_write_word(pdo, 0x01B7C100, 0x0001);
803 /* ~200us delay */ 787 /* ~2ms delay */
804 for (i = 0; i < 2000; i++) 788 hpios_delay_micro_seconds(2000);
805 delay = ioread32(phw->dw2040_HPICSR +
806 HPI_RESET);
807 } 789 }
808 790
809 /* test r/w to internal DSP memory 791 /* test r/w to internal DSP memory
@@ -927,9 +909,7 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
927 } 909 }
928 910
929 /* delay a little to allow SDRAM and DSP to "get going" */ 911 /* delay a little to allow SDRAM and DSP to "get going" */
930 912 hpios_delay_micro_seconds(1000);
931 for (i = 0; i < 1000; i++)
932 delay = ioread32(phw->dw2040_HPICSR + HPI_RESET);
933 913
934 /* test access to SDRAM */ 914 /* test access to SDRAM */
935 { 915 {
@@ -976,7 +956,7 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
976 956
977 /* write the DSP code down into the DSPs memory */ 957 /* write the DSP code down into the DSPs memory */
978 /*HpiDspCode_Open(nBootLoadFamily,&DspCode,pdwOsErrorCode); */ 958 /*HpiDspCode_Open(nBootLoadFamily,&DspCode,pdwOsErrorCode); */
979 dsp_code.ps_dev = pao->pci.p_os_data; 959 dsp_code.ps_dev = pao->pci.pci_dev;
980 960
981 error = hpi_dsp_code_open(boot_load_family, &dsp_code, 961 error = hpi_dsp_code_open(boot_load_family, &dsp_code,
982 pos_error_code); 962 pos_error_code);
@@ -1073,8 +1053,7 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
1073 1053
1074 /* step 3. Start code by sending interrupt */ 1054 /* step 3. Start code by sending interrupt */
1075 iowrite32(0x00030003, pdo->prHPI_control); 1055 iowrite32(0x00030003, pdo->prHPI_control);
1076 for (i = 0; i < 10000; i++) 1056 hpios_delay_micro_seconds(10000);
1077 delay = ioread32(phw->dw2040_HPICSR + HPI_RESET);
1078 1057
1079 /* wait for a non-zero value in hostcmd - 1058 /* wait for a non-zero value in hostcmd -
1080 * indicating initialization is complete 1059 * indicating initialization is complete
@@ -1101,7 +1080,7 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
1101 * locks up with a bluescreen (NOT GPF or pagefault). 1080 * locks up with a bluescreen (NOT GPF or pagefault).
1102 */ 1081 */
1103 else 1082 else
1104 hpios_delay_micro_seconds(1000); 1083 hpios_delay_micro_seconds(10000);
1105 } 1084 }
1106 if (timeout == 0) 1085 if (timeout == 0)
1107 return HPI6000_ERROR_INIT_NOACK; 1086 return HPI6000_ERROR_INIT_NOACK;
@@ -1132,14 +1111,14 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
1132 mask = 0xFFFFFF00L; 1111 mask = 0xFFFFFF00L;
1133 /* ASI5100 uses AX6 code, */ 1112 /* ASI5100 uses AX6 code, */
1134 /* but has no PLD r/w register to test */ 1113 /* but has no PLD r/w register to test */
1135 if (HPI_ADAPTER_FAMILY_ASI(pao->pci. 1114 if (HPI_ADAPTER_FAMILY_ASI(pao->pci.pci_dev->
1136 subsys_device_id) == 1115 subsystem_device) ==
1137 HPI_ADAPTER_FAMILY_ASI(0x5100)) 1116 HPI_ADAPTER_FAMILY_ASI(0x5100))
1138 mask = 0x00000000L; 1117 mask = 0x00000000L;
1139 /* ASI5200 uses AX6 code, */ 1118 /* ASI5200 uses AX6 code, */
1140 /* but has no PLD r/w register to test */ 1119 /* but has no PLD r/w register to test */
1141 if (HPI_ADAPTER_FAMILY_ASI(pao->pci. 1120 if (HPI_ADAPTER_FAMILY_ASI(pao->pci.pci_dev->
1142 subsys_device_id) == 1121 subsystem_device) ==
1143 HPI_ADAPTER_FAMILY_ASI(0x5200)) 1122 HPI_ADAPTER_FAMILY_ASI(0x5200))
1144 mask = 0x00000000L; 1123 mask = 0x00000000L;
1145 break; 1124 break;
@@ -1204,7 +1183,7 @@ static u32 hpi_read_word(struct dsp_obj *pdo, u32 address)
1204 u32 data = 0; 1183 u32 data = 0;
1205 1184
1206 if (hpi_set_address(pdo, address)) 1185 if (hpi_set_address(pdo, address))
1207 return 0; /*? no way to return error */ 1186 return 0; /*? No way to return error */
1208 1187
1209 /* take care of errata in revB DSP (2.0.1) */ 1188 /* take care of errata in revB DSP (2.0.1) */
1210 data = ioread32(pdo->prHPI_data); 1189 data = ioread32(pdo->prHPI_data);
@@ -1340,10 +1319,6 @@ static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao,
1340 u32 *p_data; 1319 u32 *p_data;
1341 u16 error = 0; 1320 u16 error = 0;
1342 1321
1343 /* does the DSP we are referencing exist? */
1344 if (dsp_index >= phw->num_dsp)
1345 return HPI6000_ERROR_MSG_INVALID_DSP_INDEX;
1346
1347 ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_IDLE); 1322 ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_IDLE);
1348 if (ack & HPI_HIF_ERROR_MASK) { 1323 if (ack & HPI_HIF_ERROR_MASK) {
1349 pao->dsp_crashed++; 1324 pao->dsp_crashed++;
@@ -1351,9 +1326,7 @@ static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao,
1351 } 1326 }
1352 pao->dsp_crashed = 0; 1327 pao->dsp_crashed = 0;
1353 1328
1354 /* send the message */ 1329 /* get the message address and size */
1355
1356 /* get the address and size */
1357 if (phw->message_buffer_address_on_dsp == 0) { 1330 if (phw->message_buffer_address_on_dsp == 0) {
1358 timeout = TIMEOUT; 1331 timeout = TIMEOUT;
1359 do { 1332 do {
@@ -1368,10 +1341,9 @@ static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao,
1368 } else 1341 } else
1369 address = phw->message_buffer_address_on_dsp; 1342 address = phw->message_buffer_address_on_dsp;
1370 1343
1371 /* dwLength = sizeof(struct hpi_message); */
1372 length = phm->size; 1344 length = phm->size;
1373 1345
1374 /* send it */ 1346 /* send the message */
1375 p_data = (u32 *)phm; 1347 p_data = (u32 *)phm;
1376 if (hpi6000_dsp_block_write32(pao, dsp_index, address, p_data, 1348 if (hpi6000_dsp_block_write32(pao, dsp_index, address, p_data,
1377 (u16)length / 4)) 1349 (u16)length / 4))
@@ -1385,7 +1357,7 @@ static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao,
1385 if (ack & HPI_HIF_ERROR_MASK) 1357 if (ack & HPI_HIF_ERROR_MASK)
1386 return HPI6000_ERROR_MSG_RESP_GET_RESP_ACK; 1358 return HPI6000_ERROR_MSG_RESP_GET_RESP_ACK;
1387 1359
1388 /* get the address and size */ 1360 /* get the response address */
1389 if (phw->response_buffer_address_on_dsp == 0) { 1361 if (phw->response_buffer_address_on_dsp == 0) {
1390 timeout = TIMEOUT; 1362 timeout = TIMEOUT;
1391 do { 1363 do {
@@ -1409,7 +1381,7 @@ static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao,
1409 if (!timeout) 1381 if (!timeout)
1410 length = sizeof(struct hpi_response); 1382 length = sizeof(struct hpi_response);
1411 1383
1412 /* get it */ 1384 /* get the response */
1413 p_data = (u32 *)phr; 1385 p_data = (u32 *)phr;
1414 if (hpi6000_dsp_block_read32(pao, dsp_index, address, p_data, 1386 if (hpi6000_dsp_block_read32(pao, dsp_index, address, p_data,
1415 (u16)length / 4)) 1387 (u16)length / 4))
@@ -1805,17 +1777,11 @@ static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
1805 hpios_dsplock_lock(pao); 1777 hpios_dsplock_lock(pao);
1806 error = hpi6000_message_response_sequence(pao, dsp_index, phm, phr); 1778 error = hpi6000_message_response_sequence(pao, dsp_index, phm, phr);
1807 1779
1808 /* maybe an error response */ 1780 if (error) /* something failed in the HPI/DSP interface */
1809 if (error) {
1810 /* something failed in the HPI/DSP interface */
1811 phr->error = error;
1812 /* just the header of the response is valid */
1813 phr->size = sizeof(struct hpi_response_header);
1814 goto err; 1781 goto err;
1815 }
1816 1782
1817 if (phr->error != 0) /* something failed in the DSP */ 1783 if (phr->error) /* something failed in the DSP */
1818 goto err; 1784 goto out;
1819 1785
1820 switch (phm->function) { 1786 switch (phm->function) {
1821 case HPI_OSTREAM_WRITE: 1787 case HPI_OSTREAM_WRITE:
@@ -1827,21 +1793,30 @@ static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
1827 error = hpi6000_get_data(pao, dsp_index, phm, phr); 1793 error = hpi6000_get_data(pao, dsp_index, phm, phr);
1828 break; 1794 break;
1829 case HPI_ADAPTER_GET_ASSERT: 1795 case HPI_ADAPTER_GET_ASSERT:
1830 phr->u.a.adapter_index = 0; /* dsp 0 default */ 1796 phr->u.ax.assert.dsp_index = 0; /* dsp 0 default */
1831 if (num_dsp == 2) { 1797 if (num_dsp == 2) {
1832 if (!phr->u.a.adapter_type) { 1798 if (!phr->u.ax.assert.count) {
1833 /* no assert from dsp 0, check dsp 1 */ 1799 /* no assert from dsp 0, check dsp 1 */
1834 error = hpi6000_message_response_sequence(pao, 1800 error = hpi6000_message_response_sequence(pao,
1835 1, phm, phr); 1801 1, phm, phr);
1836 phr->u.a.adapter_index = 1; 1802 phr->u.ax.assert.dsp_index = 1;
1837 } 1803 }
1838 } 1804 }
1839 } 1805 }
1840 1806
1841 if (error)
1842 phr->error = error;
1843
1844err: 1807err:
1808 if (error) {
1809 if (error >= HPI_ERROR_BACKEND_BASE) {
1810 phr->error = HPI_ERROR_DSP_COMMUNICATION;
1811 phr->specific_error = error;
1812 } else {
1813 phr->error = error;
1814 }
1815
1816 /* just the header of the response is valid */
1817 phr->size = sizeof(struct hpi_response_header);
1818 }
1819out:
1845 hpios_dsplock_unlock(pao); 1820 hpios_dsplock_unlock(pao);
1846 return; 1821 return;
1847} 1822}
diff --git a/sound/pci/asihpi/hpi6205.c b/sound/pci/asihpi/hpi6205.c
index 2672f6591ceb..620525bdac59 100644
--- a/sound/pci/asihpi/hpi6205.c
+++ b/sound/pci/asihpi/hpi6205.c
@@ -38,27 +38,26 @@
38 38
39/*****************************************************************************/ 39/*****************************************************************************/
40/* HPI6205 specific error codes */ 40/* HPI6205 specific error codes */
41#define HPI6205_ERROR_BASE 1000 41#define HPI6205_ERROR_BASE 1000 /* not actually used anywhere */
42/*#define HPI6205_ERROR_MEM_ALLOC 1001 */ 42
43/* operational/messaging errors */
44#define HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT 1015
45#define HPI6205_ERROR_MSG_RESP_TIMEOUT 1016
46
47/* initialization/bootload errors */
43#define HPI6205_ERROR_6205_NO_IRQ 1002 48#define HPI6205_ERROR_6205_NO_IRQ 1002
44#define HPI6205_ERROR_6205_INIT_FAILED 1003 49#define HPI6205_ERROR_6205_INIT_FAILED 1003
45/*#define HPI6205_ERROR_MISSING_DSPCODE 1004 */
46#define HPI6205_ERROR_UNKNOWN_PCI_DEVICE 1005
47#define HPI6205_ERROR_6205_REG 1006 50#define HPI6205_ERROR_6205_REG 1006
48#define HPI6205_ERROR_6205_DSPPAGE 1007 51#define HPI6205_ERROR_6205_DSPPAGE 1007
49#define HPI6205_ERROR_BAD_DSPINDEX 1008
50#define HPI6205_ERROR_C6713_HPIC 1009 52#define HPI6205_ERROR_C6713_HPIC 1009
51#define HPI6205_ERROR_C6713_HPIA 1010 53#define HPI6205_ERROR_C6713_HPIA 1010
52#define HPI6205_ERROR_C6713_PLL 1011 54#define HPI6205_ERROR_C6713_PLL 1011
53#define HPI6205_ERROR_DSP_INTMEM 1012 55#define HPI6205_ERROR_DSP_INTMEM 1012
54#define HPI6205_ERROR_DSP_EXTMEM 1013 56#define HPI6205_ERROR_DSP_EXTMEM 1013
55#define HPI6205_ERROR_DSP_PLD 1014 57#define HPI6205_ERROR_DSP_PLD 1014
56#define HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT 1015
57#define HPI6205_ERROR_MSG_RESP_TIMEOUT 1016
58#define HPI6205_ERROR_6205_EEPROM 1017 58#define HPI6205_ERROR_6205_EEPROM 1017
59#define HPI6205_ERROR_DSP_EMIF 1018 59#define HPI6205_ERROR_DSP_EMIF 1018
60 60
61#define hpi6205_error(dsp_index, err) (err)
62/*****************************************************************************/ 61/*****************************************************************************/
63/* for C6205 PCI i/f */ 62/* for C6205 PCI i/f */
64/* Host Status Register (HSR) bitfields */ 63/* Host Status Register (HSR) bitfields */
@@ -128,9 +127,6 @@ struct hpi_hw_obj {
128 u32 outstream_host_buffer_size[HPI_MAX_STREAMS]; 127 u32 outstream_host_buffer_size[HPI_MAX_STREAMS];
129 128
130 struct consistent_dma_area h_control_cache; 129 struct consistent_dma_area h_control_cache;
131 struct consistent_dma_area h_async_event_buffer;
132/* struct hpi_control_cache_single *pControlCache; */
133 struct hpi_async_event *p_async_event_buffer;
134 struct hpi_control_cache *p_cache; 130 struct hpi_control_cache *p_cache;
135}; 131};
136 132
@@ -208,8 +204,8 @@ static void instream_start(struct hpi_adapter_obj *pao,
208static u32 boot_loader_read_mem32(struct hpi_adapter_obj *pao, int dsp_index, 204static u32 boot_loader_read_mem32(struct hpi_adapter_obj *pao, int dsp_index,
209 u32 address); 205 u32 address);
210 206
211static u16 boot_loader_write_mem32(struct hpi_adapter_obj *pao, int dsp_index, 207static void boot_loader_write_mem32(struct hpi_adapter_obj *pao,
212 u32 address, u32 data); 208 int dsp_index, u32 address, u32 data);
213 209
214static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, 210static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao,
215 int dsp_index); 211 int dsp_index);
@@ -229,17 +225,7 @@ static u16 boot_loader_test_pld(struct hpi_adapter_obj *pao, int dsp_index);
229 225
230static void subsys_message(struct hpi_message *phm, struct hpi_response *phr) 226static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
231{ 227{
232
233 switch (phm->function) { 228 switch (phm->function) {
234 case HPI_SUBSYS_OPEN:
235 case HPI_SUBSYS_CLOSE:
236 case HPI_SUBSYS_GET_INFO:
237 case HPI_SUBSYS_DRIVER_UNLOAD:
238 case HPI_SUBSYS_DRIVER_LOAD:
239 case HPI_SUBSYS_FIND_ADAPTERS:
240 /* messages that should not get here */
241 phr->error = HPI_ERROR_UNIMPLEMENTED;
242 break;
243 case HPI_SUBSYS_CREATE_ADAPTER: 229 case HPI_SUBSYS_CREATE_ADAPTER:
244 subsys_create_adapter(phm, phr); 230 subsys_create_adapter(phm, phr);
245 break; 231 break;
@@ -257,15 +243,22 @@ static void control_message(struct hpi_adapter_obj *pao,
257{ 243{
258 244
259 struct hpi_hw_obj *phw = pao->priv; 245 struct hpi_hw_obj *phw = pao->priv;
246 u16 pending_cache_error = 0;
260 247
261 switch (phm->function) { 248 switch (phm->function) {
262 case HPI_CONTROL_GET_STATE: 249 case HPI_CONTROL_GET_STATE:
263 if (pao->has_control_cache) { 250 if (pao->has_control_cache) {
264 rmb(); /* make sure we see updates DM_aed from DSP */ 251 rmb(); /* make sure we see updates DMAed from DSP */
265 if (hpi_check_control_cache(phw->p_cache, phm, phr)) 252 if (hpi_check_control_cache(phw->p_cache, phm, phr)) {
266 break; 253 break;
254 } else if (phm->u.c.attribute == HPI_METER_PEAK) {
255 pending_cache_error =
256 HPI_ERROR_CONTROL_CACHING;
257 }
267 } 258 }
268 hw_message(pao, phm, phr); 259 hw_message(pao, phm, phr);
260 if (pending_cache_error && !phr->error)
261 phr->error = pending_cache_error;
269 break; 262 break;
270 case HPI_CONTROL_GET_INFO: 263 case HPI_CONTROL_GET_INFO:
271 hw_message(pao, phm, phr); 264 hw_message(pao, phm, phr);
@@ -273,7 +266,8 @@ static void control_message(struct hpi_adapter_obj *pao,
273 case HPI_CONTROL_SET_STATE: 266 case HPI_CONTROL_SET_STATE:
274 hw_message(pao, phm, phr); 267 hw_message(pao, phm, phr);
275 if (pao->has_control_cache) 268 if (pao->has_control_cache)
276 hpi_sync_control_cache(phw->p_cache, phm, phr); 269 hpi_cmn_control_cache_sync_to_msg(phw->p_cache, phm,
270 phr);
277 break; 271 break;
278 default: 272 default:
279 phr->error = HPI_ERROR_INVALID_FUNC; 273 phr->error = HPI_ERROR_INVALID_FUNC;
@@ -296,9 +290,9 @@ static void outstream_message(struct hpi_adapter_obj *pao,
296{ 290{
297 291
298 if (phm->obj_index >= HPI_MAX_STREAMS) { 292 if (phm->obj_index >= HPI_MAX_STREAMS) {
299 phr->error = HPI_ERROR_INVALID_STREAM; 293 phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
300 HPI_DEBUG_LOG(WARNING, 294 HPI_DEBUG_LOG(WARNING,
301 "message referencing invalid stream %d " 295 "Message referencing invalid stream %d "
302 "on adapter index %d\n", phm->obj_index, 296 "on adapter index %d\n", phm->obj_index,
303 phm->adapter_index); 297 phm->adapter_index);
304 return; 298 return;
@@ -340,9 +334,9 @@ static void instream_message(struct hpi_adapter_obj *pao,
340{ 334{
341 335
342 if (phm->obj_index >= HPI_MAX_STREAMS) { 336 if (phm->obj_index >= HPI_MAX_STREAMS) {
343 phr->error = HPI_ERROR_INVALID_STREAM; 337 phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
344 HPI_DEBUG_LOG(WARNING, 338 HPI_DEBUG_LOG(WARNING,
345 "message referencing invalid stream %d " 339 "Message referencing invalid stream %d "
346 "on adapter index %d\n", phm->obj_index, 340 "on adapter index %d\n", phm->obj_index,
347 phm->adapter_index); 341 phm->adapter_index);
348 return; 342 return;
@@ -385,8 +379,8 @@ void HPI_6205(struct hpi_message *phm, struct hpi_response *phr)
385 * All other messages are ignored unless the adapter index matches 379 * All other messages are ignored unless the adapter index matches
386 * an adapter in the HPI 380 * an adapter in the HPI
387 */ 381 */
388 HPI_DEBUG_LOG(DEBUG, "HPI obj=%d, func=%d\n", phm->object, 382 /* HPI_DEBUG_LOG(DEBUG, "HPI Obj=%d, Func=%d\n", phm->wObject,
389 phm->function); 383 phm->wFunction); */
390 384
391 /* if Dsp has crashed then do not communicate with it any more */ 385 /* if Dsp has crashed then do not communicate with it any more */
392 if (phm->object != HPI_OBJ_SUBSYSTEM) { 386 if (phm->object != HPI_OBJ_SUBSYSTEM) {
@@ -411,8 +405,7 @@ void HPI_6205(struct hpi_message *phm, struct hpi_response *phr)
411 405
412 /* Init default response */ 406 /* Init default response */
413 if (phm->function != HPI_SUBSYS_CREATE_ADAPTER) 407 if (phm->function != HPI_SUBSYS_CREATE_ADAPTER)
414 hpi_init_response(phr, phm->object, phm->function, 408 phr->error = HPI_ERROR_PROCESSING_MESSAGE;
415 HPI_ERROR_PROCESSING_MESSAGE);
416 409
417 HPI_DEBUG_LOG(VERBOSE, "start of switch\n"); 410 HPI_DEBUG_LOG(VERBOSE, "start of switch\n");
418 switch (phm->type) { 411 switch (phm->type) {
@@ -423,9 +416,6 @@ void HPI_6205(struct hpi_message *phm, struct hpi_response *phr)
423 break; 416 break;
424 417
425 case HPI_OBJ_ADAPTER: 418 case HPI_OBJ_ADAPTER:
426 phr->size =
427 sizeof(struct hpi_response_header) +
428 sizeof(struct hpi_adapter_res);
429 adapter_message(pao, phm, phr); 419 adapter_message(pao, phm, phr);
430 break; 420 break;
431 421
@@ -474,14 +464,6 @@ static void subsys_create_adapter(struct hpi_message *phm,
474 464
475 memset(&ao, 0, sizeof(ao)); 465 memset(&ao, 0, sizeof(ao));
476 466
477 /* this HPI only creates adapters for TI/PCI devices */
478 if (phm->u.s.resource.bus_type != HPI_BUS_PCI)
479 return;
480 if (phm->u.s.resource.r.pci->vendor_id != HPI_PCI_VENDOR_ID_TI)
481 return;
482 if (phm->u.s.resource.r.pci->device_id != HPI_PCI_DEV_ID_DSP6205)
483 return;
484
485 ao.priv = kzalloc(sizeof(struct hpi_hw_obj), GFP_KERNEL); 467 ao.priv = kzalloc(sizeof(struct hpi_hw_obj), GFP_KERNEL);
486 if (!ao.priv) { 468 if (!ao.priv) {
487 HPI_DEBUG_LOG(ERROR, "cant get mem for adapter object\n"); 469 HPI_DEBUG_LOG(ERROR, "cant get mem for adapter object\n");
@@ -491,18 +473,20 @@ static void subsys_create_adapter(struct hpi_message *phm,
491 473
492 ao.pci = *phm->u.s.resource.r.pci; 474 ao.pci = *phm->u.s.resource.r.pci;
493 err = create_adapter_obj(&ao, &os_error_code); 475 err = create_adapter_obj(&ao, &os_error_code);
494 if (!err)
495 err = hpi_add_adapter(&ao);
496 if (err) { 476 if (err) {
497 phr->u.s.data = os_error_code;
498 delete_adapter_obj(&ao); 477 delete_adapter_obj(&ao);
499 phr->error = err; 478 if (err >= HPI_ERROR_BACKEND_BASE) {
479 phr->error = HPI_ERROR_DSP_BOOTLOAD;
480 phr->specific_error = err;
481 } else {
482 phr->error = err;
483 }
484 phr->u.s.data = os_error_code;
500 return; 485 return;
501 } 486 }
502 487
503 phr->u.s.aw_adapter_list[ao.index] = ao.adapter_type; 488 phr->u.s.adapter_type = ao.adapter_type;
504 phr->u.s.adapter_index = ao.index; 489 phr->u.s.adapter_index = ao.index;
505 phr->u.s.num_adapters++;
506 phr->error = 0; 490 phr->error = 0;
507} 491}
508 492
@@ -513,7 +497,7 @@ static void subsys_delete_adapter(struct hpi_message *phm,
513 struct hpi_adapter_obj *pao; 497 struct hpi_adapter_obj *pao;
514 struct hpi_hw_obj *phw; 498 struct hpi_hw_obj *phw;
515 499
516 pao = hpi_find_adapter(phm->adapter_index); 500 pao = hpi_find_adapter(phm->obj_index);
517 if (!pao) { 501 if (!pao) {
518 phr->error = HPI_ERROR_INVALID_OBJ_INDEX; 502 phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
519 return; 503 return;
@@ -526,6 +510,7 @@ static void subsys_delete_adapter(struct hpi_message *phm,
526 iowrite32(C6205_HDCR_WARMRESET, phw->prHDCR); 510 iowrite32(C6205_HDCR_WARMRESET, phw->prHDCR);
527 511
528 delete_adapter_obj(pao); 512 delete_adapter_obj(pao);
513 hpi_delete_adapter(pao);
529 phr->error = 0; 514 phr->error = 0;
530} 515}
531 516
@@ -538,10 +523,6 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
538 struct hpi_hw_obj *phw = pao->priv; 523 struct hpi_hw_obj *phw = pao->priv;
539 struct bus_master_interface *interface; 524 struct bus_master_interface *interface;
540 u32 phys_addr; 525 u32 phys_addr;
541#ifndef HPI6205_NO_HSR_POLL
542 u32 time_out = HPI6205_TIMEOUT;
543 u32 temp1;
544#endif
545 int i; 526 int i;
546 u16 err; 527 u16 err;
547 528
@@ -566,7 +547,7 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
566 547
567 if (hpios_locked_mem_alloc(&phw->h_locked_mem, 548 if (hpios_locked_mem_alloc(&phw->h_locked_mem,
568 sizeof(struct bus_master_interface), 549 sizeof(struct bus_master_interface),
569 pao->pci.p_os_data)) 550 pao->pci.pci_dev))
570 phw->p_interface_buffer = NULL; 551 phw->p_interface_buffer = NULL;
571 else if (hpios_locked_mem_get_virt_addr(&phw->h_locked_mem, 552 else if (hpios_locked_mem_get_virt_addr(&phw->h_locked_mem,
572 (void *)&phw->p_interface_buffer)) 553 (void *)&phw->p_interface_buffer))
@@ -591,49 +572,29 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
591 572
592 /* allow boot load even if mem alloc wont work */ 573 /* allow boot load even if mem alloc wont work */
593 if (!phw->p_interface_buffer) 574 if (!phw->p_interface_buffer)
594 return hpi6205_error(0, HPI_ERROR_MEMORY_ALLOC); 575 return HPI_ERROR_MEMORY_ALLOC;
595 576
596 interface = phw->p_interface_buffer; 577 interface = phw->p_interface_buffer;
597 578
598#ifndef HPI6205_NO_HSR_POLL
599 /* wait for first interrupt indicating the DSP init is done */
600 time_out = HPI6205_TIMEOUT * 10;
601 temp1 = 0;
602 while (((temp1 & C6205_HSR_INTSRC) == 0) && --time_out)
603 temp1 = ioread32(phw->prHSR);
604
605 if (temp1 & C6205_HSR_INTSRC)
606 HPI_DEBUG_LOG(INFO,
607 "interrupt confirming DSP code running OK\n");
608 else {
609 HPI_DEBUG_LOG(ERROR,
610 "timed out waiting for interrupt "
611 "confirming DSP code running\n");
612 return hpi6205_error(0, HPI6205_ERROR_6205_NO_IRQ);
613 }
614
615 /* reset the interrupt */
616 iowrite32(C6205_HSR_INTSRC, phw->prHSR);
617#endif
618
619 /* make sure the DSP has started ok */ 579 /* make sure the DSP has started ok */
620 if (!wait_dsp_ack(phw, H620_HIF_RESET, HPI6205_TIMEOUT * 10)) { 580 if (!wait_dsp_ack(phw, H620_HIF_RESET, HPI6205_TIMEOUT * 10)) {
621 HPI_DEBUG_LOG(ERROR, "timed out waiting reset state \n"); 581 HPI_DEBUG_LOG(ERROR, "timed out waiting reset state \n");
622 return hpi6205_error(0, HPI6205_ERROR_6205_INIT_FAILED); 582 return HPI6205_ERROR_6205_INIT_FAILED;
623 } 583 }
624 /* Note that *pao, *phw are zeroed after allocation, 584 /* Note that *pao, *phw are zeroed after allocation,
625 * so pointers and flags are NULL by default. 585 * so pointers and flags are NULL by default.
626 * Allocate bus mastering control cache buffer and tell the DSP about it 586 * Allocate bus mastering control cache buffer and tell the DSP about it
627 */ 587 */
628 if (interface->control_cache.number_of_controls) { 588 if (interface->control_cache.number_of_controls) {
629 void *p_control_cache_virtual; 589 u8 *p_control_cache_virtual;
630 590
631 err = hpios_locked_mem_alloc(&phw->h_control_cache, 591 err = hpios_locked_mem_alloc(&phw->h_control_cache,
632 interface->control_cache.size_in_bytes, 592 interface->control_cache.size_in_bytes,
633 pao->pci.p_os_data); 593 pao->pci.pci_dev);
634 if (!err) 594 if (!err)
635 err = hpios_locked_mem_get_virt_addr(&phw-> 595 err = hpios_locked_mem_get_virt_addr(&phw->
636 h_control_cache, &p_control_cache_virtual); 596 h_control_cache,
597 (void *)&p_control_cache_virtual);
637 if (!err) { 598 if (!err) {
638 memset(p_control_cache_virtual, 0, 599 memset(p_control_cache_virtual, 0,
639 interface->control_cache.size_in_bytes); 600 interface->control_cache.size_in_bytes);
@@ -642,7 +603,6 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
642 hpi_alloc_control_cache(interface-> 603 hpi_alloc_control_cache(interface->
643 control_cache.number_of_controls, 604 control_cache.number_of_controls,
644 interface->control_cache.size_in_bytes, 605 interface->control_cache.size_in_bytes,
645 (struct hpi_control_cache_info *)
646 p_control_cache_virtual); 606 p_control_cache_virtual);
647 if (!phw->p_cache) 607 if (!phw->p_cache)
648 err = HPI_ERROR_MEMORY_ALLOC; 608 err = HPI_ERROR_MEMORY_ALLOC;
@@ -662,78 +622,56 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
662 pao->has_control_cache = 0; 622 pao->has_control_cache = 0;
663 } 623 }
664 } 624 }
665 /* allocate bus mastering async buffer and tell the DSP about it */
666 if (interface->async_buffer.b.size) {
667 err = hpios_locked_mem_alloc(&phw->h_async_event_buffer,
668 interface->async_buffer.b.size *
669 sizeof(struct hpi_async_event), pao->pci.p_os_data);
670 if (!err)
671 err = hpios_locked_mem_get_virt_addr
672 (&phw->h_async_event_buffer, (void *)
673 &phw->p_async_event_buffer);
674 if (!err)
675 memset((void *)phw->p_async_event_buffer, 0,
676 interface->async_buffer.b.size *
677 sizeof(struct hpi_async_event));
678 if (!err) {
679 err = hpios_locked_mem_get_phys_addr
680 (&phw->h_async_event_buffer, &phys_addr);
681 interface->async_buffer.physical_address32 =
682 phys_addr;
683 }
684 if (err) {
685 if (hpios_locked_mem_valid(&phw->
686 h_async_event_buffer)) {
687 hpios_locked_mem_free
688 (&phw->h_async_event_buffer);
689 phw->p_async_event_buffer = NULL;
690 }
691 }
692 }
693 send_dsp_command(phw, H620_HIF_IDLE); 625 send_dsp_command(phw, H620_HIF_IDLE);
694 626
695 { 627 {
696 struct hpi_message hM; 628 struct hpi_message hm;
697 struct hpi_response hR; 629 struct hpi_response hr;
698 u32 max_streams; 630 u32 max_streams;
699 631
700 HPI_DEBUG_LOG(VERBOSE, "init ADAPTER_GET_INFO\n"); 632 HPI_DEBUG_LOG(VERBOSE, "init ADAPTER_GET_INFO\n");
701 memset(&hM, 0, sizeof(hM)); 633 memset(&hm, 0, sizeof(hm));
702 hM.type = HPI_TYPE_MESSAGE; 634 hm.type = HPI_TYPE_MESSAGE;
703 hM.size = sizeof(hM); 635 hm.size = sizeof(hm);
704 hM.object = HPI_OBJ_ADAPTER; 636 hm.object = HPI_OBJ_ADAPTER;
705 hM.function = HPI_ADAPTER_GET_INFO; 637 hm.function = HPI_ADAPTER_GET_INFO;
706 hM.adapter_index = 0; 638 hm.adapter_index = 0;
707 memset(&hR, 0, sizeof(hR)); 639 memset(&hr, 0, sizeof(hr));
708 hR.size = sizeof(hR); 640 hr.size = sizeof(hr);
709 641
710 err = message_response_sequence(pao, &hM, &hR); 642 err = message_response_sequence(pao, &hm, &hr);
711 if (err) { 643 if (err) {
712 HPI_DEBUG_LOG(ERROR, "message transport error %d\n", 644 HPI_DEBUG_LOG(ERROR, "message transport error %d\n",
713 err); 645 err);
714 return err; 646 return err;
715 } 647 }
716 if (hR.error) 648 if (hr.error)
717 return hR.error; 649 return hr.error;
718 650
719 pao->adapter_type = hR.u.a.adapter_type; 651 pao->adapter_type = hr.u.ax.info.adapter_type;
720 pao->index = hR.u.a.adapter_index; 652 pao->index = hr.u.ax.info.adapter_index;
721 653
722 max_streams = hR.u.a.num_outstreams + hR.u.a.num_instreams; 654 max_streams =
655 hr.u.ax.info.num_outstreams +
656 hr.u.ax.info.num_instreams;
723 657
724 hpios_locked_mem_prepare((max_streams * 6) / 10, max_streams, 658 hpios_locked_mem_prepare((max_streams * 6) / 10, max_streams,
725 65536, pao->pci.p_os_data); 659 65536, pao->pci.pci_dev);
726 660
727 HPI_DEBUG_LOG(VERBOSE, 661 HPI_DEBUG_LOG(VERBOSE,
728 "got adapter info type %x index %d serial %d\n", 662 "got adapter info type %x index %d serial %d\n",
729 hR.u.a.adapter_type, hR.u.a.adapter_index, 663 hr.u.ax.info.adapter_type, hr.u.ax.info.adapter_index,
730 hR.u.a.serial_number); 664 hr.u.ax.info.serial_number);
731 } 665 }
732 666
733 pao->open = 0; /* upon creation the adapter is closed */ 667 pao->open = 0; /* upon creation the adapter is closed */
734 668
669 if (phw->p_cache)
670 phw->p_cache->adap_idx = pao->index;
671
735 HPI_DEBUG_LOG(INFO, "bootload DSP OK\n"); 672 HPI_DEBUG_LOG(INFO, "bootload DSP OK\n");
736 return 0; 673
674 return hpi_add_adapter(pao);
737} 675}
738 676
739/** Free memory areas allocated by adapter 677/** Free memory areas allocated by adapter
@@ -747,11 +685,6 @@ static void delete_adapter_obj(struct hpi_adapter_obj *pao)
747 685
748 phw = pao->priv; 686 phw = pao->priv;
749 687
750 if (hpios_locked_mem_valid(&phw->h_async_event_buffer)) {
751 hpios_locked_mem_free(&phw->h_async_event_buffer);
752 phw->p_async_event_buffer = NULL;
753 }
754
755 if (hpios_locked_mem_valid(&phw->h_control_cache)) { 688 if (hpios_locked_mem_valid(&phw->h_control_cache)) {
756 hpios_locked_mem_free(&phw->h_control_cache); 689 hpios_locked_mem_free(&phw->h_control_cache);
757 hpi_free_control_cache(phw->p_cache); 690 hpi_free_control_cache(phw->p_cache);
@@ -776,13 +709,15 @@ static void delete_adapter_obj(struct hpi_adapter_obj *pao)
776 phw->outstream_host_buffer_size[i] = 0; 709 phw->outstream_host_buffer_size[i] = 0;
777 } 710 }
778 711
779 hpios_locked_mem_unprepare(pao->pci.p_os_data); 712 hpios_locked_mem_unprepare(pao->pci.pci_dev);
780 713
781 hpi_delete_adapter(pao);
782 kfree(phw); 714 kfree(phw);
783} 715}
784 716
785/*****************************************************************************/ 717/*****************************************************************************/
718/* Adapter functions */
719
720/*****************************************************************************/
786/* OutStream Host buffer functions */ 721/* OutStream Host buffer functions */
787 722
788/** Allocate or attach buffer for busmastering 723/** Allocate or attach buffer for busmastering
@@ -824,7 +759,7 @@ static void outstream_host_buffer_allocate(struct hpi_adapter_obj *pao,
824 759
825 err = hpios_locked_mem_alloc(&phw->outstream_host_buffers 760 err = hpios_locked_mem_alloc(&phw->outstream_host_buffers
826 [phm->obj_index], phm->u.d.u.buffer.buffer_size, 761 [phm->obj_index], phm->u.d.u.buffer.buffer_size,
827 pao->pci.p_os_data); 762 pao->pci.pci_dev);
828 763
829 if (err) { 764 if (err) {
830 phr->error = HPI_ERROR_INVALID_DATASIZE; 765 phr->error = HPI_ERROR_INVALID_DATASIZE;
@@ -861,7 +796,7 @@ static void outstream_host_buffer_allocate(struct hpi_adapter_obj *pao,
861 if (phm->u.d.u.buffer.buffer_size & (phm->u.d.u.buffer. 796 if (phm->u.d.u.buffer.buffer_size & (phm->u.d.u.buffer.
862 buffer_size - 1)) { 797 buffer_size - 1)) {
863 HPI_DEBUG_LOG(ERROR, 798 HPI_DEBUG_LOG(ERROR,
864 "buffer size must be 2^N not %d\n", 799 "Buffer size must be 2^N not %d\n",
865 phm->u.d.u.buffer.buffer_size); 800 phm->u.d.u.buffer.buffer_size);
866 phr->error = HPI_ERROR_INVALID_DATASIZE; 801 phr->error = HPI_ERROR_INVALID_DATASIZE;
867 return; 802 return;
@@ -875,6 +810,7 @@ static void outstream_host_buffer_allocate(struct hpi_adapter_obj *pao,
875 status->dSP_index = 0; 810 status->dSP_index = 0;
876 status->host_index = status->dSP_index; 811 status->host_index = status->dSP_index;
877 status->size_in_bytes = phm->u.d.u.buffer.buffer_size; 812 status->size_in_bytes = phm->u.d.u.buffer.buffer_size;
813 status->auxiliary_data_available = 0;
878 814
879 hw_message(pao, phm, phr); 815 hw_message(pao, phm, phr);
880 816
@@ -966,51 +902,6 @@ static void outstream_write(struct hpi_adapter_obj *pao,
966 hpi_init_response(phr, phm->object, phm->function, 0); 902 hpi_init_response(phr, phm->object, phm->function, 0);
967 status = &interface->outstream_host_buffer_status[phm->obj_index]; 903 status = &interface->outstream_host_buffer_status[phm->obj_index];
968 904
969 if (phw->flag_outstream_just_reset[phm->obj_index]) {
970 /* First OutStremWrite() call following reset will write data to the
971 adapter's buffers, reducing delay before stream can start. The DSP
972 takes care of setting the stream data format using format information
973 embedded in phm.
974 */
975 int partial_write = 0;
976 unsigned int original_size = 0;
977
978 phw->flag_outstream_just_reset[phm->obj_index] = 0;
979
980 /* Send the first buffer to the DSP the old way. */
981 /* Limit size of first transfer - */
982 /* expect that this will not usually be triggered. */
983 if (phm->u.d.u.data.data_size > HPI6205_SIZEOF_DATA) {
984 partial_write = 1;
985 original_size = phm->u.d.u.data.data_size;
986 phm->u.d.u.data.data_size = HPI6205_SIZEOF_DATA;
987 }
988 /* write it */
989 phm->function = HPI_OSTREAM_WRITE;
990 hw_message(pao, phm, phr);
991
992 if (phr->error)
993 return;
994
995 /* update status information that the DSP would typically
996 * update (and will update next time the DSP
997 * buffer update task reads data from the host BBM buffer)
998 */
999 status->auxiliary_data_available = phm->u.d.u.data.data_size;
1000 status->host_index += phm->u.d.u.data.data_size;
1001 status->dSP_index += phm->u.d.u.data.data_size;
1002
1003 /* if we did a full write, we can return from here. */
1004 if (!partial_write)
1005 return;
1006
1007 /* tweak buffer parameters and let the rest of the */
1008 /* buffer land in internal BBM buffer */
1009 phm->u.d.u.data.data_size =
1010 original_size - HPI6205_SIZEOF_DATA;
1011 phm->u.d.u.data.pb_data += HPI6205_SIZEOF_DATA;
1012 }
1013
1014 space_available = outstream_get_space_available(status); 905 space_available = outstream_get_space_available(status);
1015 if (space_available < phm->u.d.u.data.data_size) { 906 if (space_available < phm->u.d.u.data.data_size) {
1016 phr->error = HPI_ERROR_INVALID_DATASIZE; 907 phr->error = HPI_ERROR_INVALID_DATASIZE;
@@ -1047,6 +938,24 @@ static void outstream_write(struct hpi_adapter_obj *pao,
1047 memcpy(p_bbm_data, p_app_data + l_first_write, 938 memcpy(p_bbm_data, p_app_data + l_first_write,
1048 phm->u.d.u.data.data_size - l_first_write); 939 phm->u.d.u.data.data_size - l_first_write);
1049 } 940 }
941
942 /*
943 * This version relies on the DSP code triggering an OStream buffer
944 * update immediately following a SET_FORMAT call. The host has
945 * already written data into the BBM buffer, but the DSP won't know
946 * about it until dwHostIndex is adjusted.
947 */
948 if (phw->flag_outstream_just_reset[phm->obj_index]) {
949 /* Format can only change after reset. Must tell DSP. */
950 u16 function = phm->function;
951 phw->flag_outstream_just_reset[phm->obj_index] = 0;
952 phm->function = HPI_OSTREAM_SET_FORMAT;
953 hw_message(pao, phm, phr); /* send the format to the DSP */
954 phm->function = function;
955 if (phr->error)
956 return;
957 }
958
1050 status->host_index += phm->u.d.u.data.data_size; 959 status->host_index += phm->u.d.u.data.data_size;
1051} 960}
1052 961
@@ -1132,7 +1041,7 @@ static void instream_host_buffer_allocate(struct hpi_adapter_obj *pao,
1132 1041
1133 err = hpios_locked_mem_alloc(&phw->instream_host_buffers[phm-> 1042 err = hpios_locked_mem_alloc(&phw->instream_host_buffers[phm->
1134 obj_index], phm->u.d.u.buffer.buffer_size, 1043 obj_index], phm->u.d.u.buffer.buffer_size,
1135 pao->pci.p_os_data); 1044 pao->pci.pci_dev);
1136 1045
1137 if (err) { 1046 if (err) {
1138 phr->error = HPI_ERROR_INVALID_DATASIZE; 1047 phr->error = HPI_ERROR_INVALID_DATASIZE;
@@ -1163,7 +1072,7 @@ static void instream_host_buffer_allocate(struct hpi_adapter_obj *pao,
1163 if (phm->u.d.u.buffer.buffer_size & (phm->u.d.u.buffer. 1072 if (phm->u.d.u.buffer.buffer_size & (phm->u.d.u.buffer.
1164 buffer_size - 1)) { 1073 buffer_size - 1)) {
1165 HPI_DEBUG_LOG(ERROR, 1074 HPI_DEBUG_LOG(ERROR,
1166 "buffer size must be 2^N not %d\n", 1075 "Buffer size must be 2^N not %d\n",
1167 phm->u.d.u.buffer.buffer_size); 1076 phm->u.d.u.buffer.buffer_size);
1168 phr->error = HPI_ERROR_INVALID_DATASIZE; 1077 phr->error = HPI_ERROR_INVALID_DATASIZE;
1169 return; 1078 return;
@@ -1178,8 +1087,10 @@ static void instream_host_buffer_allocate(struct hpi_adapter_obj *pao,
1178 status->dSP_index = 0; 1087 status->dSP_index = 0;
1179 status->host_index = status->dSP_index; 1088 status->host_index = status->dSP_index;
1180 status->size_in_bytes = phm->u.d.u.buffer.buffer_size; 1089 status->size_in_bytes = phm->u.d.u.buffer.buffer_size;
1090 status->auxiliary_data_available = 0;
1181 1091
1182 hw_message(pao, phm, phr); 1092 hw_message(pao, phm, phr);
1093
1183 if (phr->error 1094 if (phr->error
1184 && hpios_locked_mem_valid(&phw-> 1095 && hpios_locked_mem_valid(&phw->
1185 instream_host_buffers[phm->obj_index])) { 1096 instream_host_buffers[phm->obj_index])) {
@@ -1344,33 +1255,36 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
1344 struct hpi_hw_obj *phw = pao->priv; 1255 struct hpi_hw_obj *phw = pao->priv;
1345 struct dsp_code dsp_code; 1256 struct dsp_code dsp_code;
1346 u16 boot_code_id[HPI6205_MAX_FILES_TO_LOAD]; 1257 u16 boot_code_id[HPI6205_MAX_FILES_TO_LOAD];
1347 u16 firmware_id = pao->pci.subsys_device_id;
1348 u32 temp; 1258 u32 temp;
1349 int dsp = 0, i = 0; 1259 int dsp = 0, i = 0;
1350 u16 err = 0; 1260 u16 err = 0;
1351 1261
1352 boot_code_id[0] = HPI_ADAPTER_ASI(0x6205); 1262 boot_code_id[0] = HPI_ADAPTER_ASI(0x6205);
1353 1263
1354 /* special cases where firmware_id != subsys ID */ 1264 boot_code_id[1] = pao->pci.pci_dev->subsystem_device;
1355 switch (firmware_id) { 1265 boot_code_id[1] = HPI_ADAPTER_FAMILY_ASI(boot_code_id[1]);
1266
1267 /* fix up cases where bootcode id[1] != subsys id */
1268 switch (boot_code_id[1]) {
1356 case HPI_ADAPTER_FAMILY_ASI(0x5000): 1269 case HPI_ADAPTER_FAMILY_ASI(0x5000):
1357 boot_code_id[0] = firmware_id; 1270 boot_code_id[0] = boot_code_id[1];
1358 firmware_id = 0; 1271 boot_code_id[1] = 0;
1359 break; 1272 break;
1360 case HPI_ADAPTER_FAMILY_ASI(0x5300): 1273 case HPI_ADAPTER_FAMILY_ASI(0x5300):
1361 case HPI_ADAPTER_FAMILY_ASI(0x5400): 1274 case HPI_ADAPTER_FAMILY_ASI(0x5400):
1362 case HPI_ADAPTER_FAMILY_ASI(0x6300): 1275 case HPI_ADAPTER_FAMILY_ASI(0x6300):
1363 firmware_id = HPI_ADAPTER_FAMILY_ASI(0x6400); 1276 boot_code_id[1] = HPI_ADAPTER_FAMILY_ASI(0x6400);
1364 break; 1277 break;
1365 case HPI_ADAPTER_FAMILY_ASI(0x5600): 1278 case HPI_ADAPTER_FAMILY_ASI(0x5600):
1366 case HPI_ADAPTER_FAMILY_ASI(0x6500): 1279 case HPI_ADAPTER_FAMILY_ASI(0x6500):
1367 firmware_id = HPI_ADAPTER_FAMILY_ASI(0x6600); 1280 boot_code_id[1] = HPI_ADAPTER_FAMILY_ASI(0x6600);
1368 break; 1281 break;
1369 case HPI_ADAPTER_FAMILY_ASI(0x8800): 1282 case HPI_ADAPTER_FAMILY_ASI(0x8800):
1370 firmware_id = HPI_ADAPTER_FAMILY_ASI(0x8900); 1283 boot_code_id[1] = HPI_ADAPTER_FAMILY_ASI(0x8900);
1284 break;
1285 default:
1371 break; 1286 break;
1372 } 1287 }
1373 boot_code_id[1] = firmware_id;
1374 1288
1375 /* reset DSP by writing a 1 to the WARMRESET bit */ 1289 /* reset DSP by writing a 1 to the WARMRESET bit */
1376 temp = C6205_HDCR_WARMRESET; 1290 temp = C6205_HDCR_WARMRESET;
@@ -1381,7 +1295,7 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
1381 temp = ioread32(phw->prHSR); 1295 temp = ioread32(phw->prHSR);
1382 if ((temp & (C6205_HSR_CFGERR | C6205_HSR_EEREAD)) != 1296 if ((temp & (C6205_HSR_CFGERR | C6205_HSR_EEREAD)) !=
1383 C6205_HSR_EEREAD) 1297 C6205_HSR_EEREAD)
1384 return hpi6205_error(0, HPI6205_ERROR_6205_EEPROM); 1298 return HPI6205_ERROR_6205_EEPROM;
1385 temp |= 0x04; 1299 temp |= 0x04;
1386 /* disable PINTA interrupt */ 1300 /* disable PINTA interrupt */
1387 iowrite32(temp, phw->prHSR); 1301 iowrite32(temp, phw->prHSR);
@@ -1389,27 +1303,27 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
1389 /* check control register reports PCI boot mode */ 1303 /* check control register reports PCI boot mode */
1390 temp = ioread32(phw->prHDCR); 1304 temp = ioread32(phw->prHDCR);
1391 if (!(temp & C6205_HDCR_PCIBOOT)) 1305 if (!(temp & C6205_HDCR_PCIBOOT))
1392 return hpi6205_error(0, HPI6205_ERROR_6205_REG); 1306 return HPI6205_ERROR_6205_REG;
1393 1307
1394 /* try writing a couple of numbers to the DSP page register */ 1308 /* try writing a few numbers to the DSP page register */
1395 /* and reading them back. */ 1309 /* and reading them back. */
1396 temp = 1; 1310 temp = 3;
1397 iowrite32(temp, phw->prDSPP); 1311 iowrite32(temp, phw->prDSPP);
1398 if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP)) 1312 if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
1399 return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE); 1313 return HPI6205_ERROR_6205_DSPPAGE;
1400 temp = 2; 1314 temp = 2;
1401 iowrite32(temp, phw->prDSPP); 1315 iowrite32(temp, phw->prDSPP);
1402 if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP)) 1316 if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
1403 return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE); 1317 return HPI6205_ERROR_6205_DSPPAGE;
1404 temp = 3; 1318 temp = 1;
1405 iowrite32(temp, phw->prDSPP); 1319 iowrite32(temp, phw->prDSPP);
1406 if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP)) 1320 if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
1407 return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE); 1321 return HPI6205_ERROR_6205_DSPPAGE;
1408 /* reset DSP page to the correct number */ 1322 /* reset DSP page to the correct number */
1409 temp = 0; 1323 temp = 0;
1410 iowrite32(temp, phw->prDSPP); 1324 iowrite32(temp, phw->prDSPP);
1411 if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP)) 1325 if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
1412 return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE); 1326 return HPI6205_ERROR_6205_DSPPAGE;
1413 phw->dsp_page = 0; 1327 phw->dsp_page = 0;
1414 1328
1415 /* release 6713 from reset before 6205 is bootloaded. 1329 /* release 6713 from reset before 6205 is bootloaded.
@@ -1455,7 +1369,7 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
1455 return err; 1369 return err;
1456 1370
1457 /* write the DSP code down into the DSPs memory */ 1371 /* write the DSP code down into the DSPs memory */
1458 dsp_code.ps_dev = pao->pci.p_os_data; 1372 dsp_code.ps_dev = pao->pci.pci_dev;
1459 err = hpi_dsp_code_open(boot_code_id[dsp], &dsp_code, 1373 err = hpi_dsp_code_open(boot_code_id[dsp], &dsp_code,
1460 pos_error_code); 1374 pos_error_code);
1461 if (err) 1375 if (err)
@@ -1484,10 +1398,8 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
1484 if (err) 1398 if (err)
1485 break; 1399 break;
1486 for (i = 0; i < (int)length; i++) { 1400 for (i = 0; i < (int)length; i++) {
1487 err = boot_loader_write_mem32(pao, dsp, 1401 boot_loader_write_mem32(pao, dsp, address,
1488 address, *pcode); 1402 *pcode);
1489 if (err)
1490 break;
1491 /* dummy read every 4 words */ 1403 /* dummy read every 4 words */
1492 /* for 6205 advisory 1.4.4 */ 1404 /* for 6205 advisory 1.4.4 */
1493 if (i % 4 == 0) 1405 if (i % 4 == 0)
@@ -1561,7 +1473,7 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
1561 host_mailbox_address_on_dsp = 0x80000000; 1473 host_mailbox_address_on_dsp = 0x80000000;
1562 while ((physicalPC_iaddress != physicalPC_iaddress_verify) 1474 while ((physicalPC_iaddress != physicalPC_iaddress_verify)
1563 && time_out--) { 1475 && time_out--) {
1564 err = boot_loader_write_mem32(pao, 0, 1476 boot_loader_write_mem32(pao, 0,
1565 host_mailbox_address_on_dsp, 1477 host_mailbox_address_on_dsp,
1566 physicalPC_iaddress); 1478 physicalPC_iaddress);
1567 physicalPC_iaddress_verify = 1479 physicalPC_iaddress_verify =
@@ -1631,11 +1543,10 @@ static u32 boot_loader_read_mem32(struct hpi_adapter_obj *pao, int dsp_index,
1631 return data; 1543 return data;
1632} 1544}
1633 1545
1634static u16 boot_loader_write_mem32(struct hpi_adapter_obj *pao, int dsp_index, 1546static void boot_loader_write_mem32(struct hpi_adapter_obj *pao,
1635 u32 address, u32 data) 1547 int dsp_index, u32 address, u32 data)
1636{ 1548{
1637 struct hpi_hw_obj *phw = pao->priv; 1549 struct hpi_hw_obj *phw = pao->priv;
1638 u16 err = 0;
1639 __iomem u32 *p_data; 1550 __iomem u32 *p_data;
1640 /* u32 dwVerifyData=0; */ 1551 /* u32 dwVerifyData=0; */
1641 1552
@@ -1675,15 +1586,11 @@ static u16 boot_loader_write_mem32(struct hpi_adapter_obj *pao, int dsp_index,
1675 1586
1676 /* dummy read every 4 words for 6205 advisory 1.4.4 */ 1587 /* dummy read every 4 words for 6205 advisory 1.4.4 */
1677 boot_loader_read_mem32(pao, 0, 0); 1588 boot_loader_read_mem32(pao, 0, 0);
1678 } else 1589 }
1679 err = hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX);
1680 return err;
1681} 1590}
1682 1591
1683static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index) 1592static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index)
1684{ 1593{
1685 u16 err = 0;
1686
1687 if (dsp_index == 0) { 1594 if (dsp_index == 0) {
1688 u32 setting; 1595 u32 setting;
1689 1596
@@ -1711,8 +1618,7 @@ static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index)
1711 boot_loader_write_mem32(pao, dsp_index, 0x01800008, setting); 1618 boot_loader_write_mem32(pao, dsp_index, 0x01800008, setting);
1712 if (setting != boot_loader_read_mem32(pao, dsp_index, 1619 if (setting != boot_loader_read_mem32(pao, dsp_index,
1713 0x01800008)) 1620 0x01800008))
1714 return hpi6205_error(dsp_index, 1621 return HPI6205_ERROR_DSP_EMIF;
1715 HPI6205_ERROR_DSP_EMIF);
1716 1622
1717 /* EMIF CE1 setup - 32 bit async. This is 6713 #1 HPI, */ 1623 /* EMIF CE1 setup - 32 bit async. This is 6713 #1 HPI, */
1718 /* which occupies D15..0. 6713 starts at 27MHz, so need */ 1624 /* which occupies D15..0. 6713 starts at 27MHz, so need */
@@ -1725,8 +1631,7 @@ static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index)
1725 boot_loader_write_mem32(pao, dsp_index, 0x01800004, setting); 1631 boot_loader_write_mem32(pao, dsp_index, 0x01800004, setting);
1726 if (setting != boot_loader_read_mem32(pao, dsp_index, 1632 if (setting != boot_loader_read_mem32(pao, dsp_index,
1727 0x01800004)) 1633 0x01800004))
1728 return hpi6205_error(dsp_index, 1634 return HPI6205_ERROR_DSP_EMIF;
1729 HPI6205_ERROR_DSP_EMIF);
1730 1635
1731 /* EMIF CE2 setup - 32 bit async. This is 6713 #2 HPI, */ 1636 /* EMIF CE2 setup - 32 bit async. This is 6713 #2 HPI, */
1732 /* which occupies D15..0. 6713 starts at 27MHz, so need */ 1637 /* which occupies D15..0. 6713 starts at 27MHz, so need */
@@ -1738,8 +1643,7 @@ static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index)
1738 boot_loader_write_mem32(pao, dsp_index, 0x01800010, setting); 1643 boot_loader_write_mem32(pao, dsp_index, 0x01800010, setting);
1739 if (setting != boot_loader_read_mem32(pao, dsp_index, 1644 if (setting != boot_loader_read_mem32(pao, dsp_index,
1740 0x01800010)) 1645 0x01800010))
1741 return hpi6205_error(dsp_index, 1646 return HPI6205_ERROR_DSP_EMIF;
1742 HPI6205_ERROR_DSP_EMIF);
1743 1647
1744 /* EMIF CE3 setup - 32 bit async. */ 1648 /* EMIF CE3 setup - 32 bit async. */
1745 /* This is the PLD on the ASI5000 cards only */ 1649 /* This is the PLD on the ASI5000 cards only */
@@ -1750,8 +1654,7 @@ static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index)
1750 boot_loader_write_mem32(pao, dsp_index, 0x01800014, setting); 1654 boot_loader_write_mem32(pao, dsp_index, 0x01800014, setting);
1751 if (setting != boot_loader_read_mem32(pao, dsp_index, 1655 if (setting != boot_loader_read_mem32(pao, dsp_index,
1752 0x01800014)) 1656 0x01800014))
1753 return hpi6205_error(dsp_index, 1657 return HPI6205_ERROR_DSP_EMIF;
1754 HPI6205_ERROR_DSP_EMIF);
1755 1658
1756 /* set EMIF SDRAM control for 2Mx32 SDRAM (512x32x4 bank) */ 1659 /* set EMIF SDRAM control for 2Mx32 SDRAM (512x32x4 bank) */
1757 /* need to use this else DSP code crashes? */ 1660 /* need to use this else DSP code crashes? */
@@ -1775,12 +1678,9 @@ static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index)
1775 read_data = 1678 read_data =
1776 0xFFF7 & boot_loader_read_mem32(pao, 0, HPICL_ADDR); 1679 0xFFF7 & boot_loader_read_mem32(pao, 0, HPICL_ADDR);
1777 if (write_data != read_data) { 1680 if (write_data != read_data) {
1778 err = hpi6205_error(dsp_index,
1779 HPI6205_ERROR_C6713_HPIC);
1780 HPI_DEBUG_LOG(ERROR, "HPICL %x %x\n", write_data, 1681 HPI_DEBUG_LOG(ERROR, "HPICL %x %x\n", write_data,
1781 read_data); 1682 read_data);
1782 1683 return HPI6205_ERROR_C6713_HPIC;
1783 return err;
1784 } 1684 }
1785 /* HPIA - walking ones test */ 1685 /* HPIA - walking ones test */
1786 write_data = 1; 1686 write_data = 1;
@@ -1798,11 +1698,9 @@ static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index)
1798 HPIAH_ADDR)) 1698 HPIAH_ADDR))
1799 << 16); 1699 << 16);
1800 if (read_data != write_data) { 1700 if (read_data != write_data) {
1801 err = hpi6205_error(dsp_index,
1802 HPI6205_ERROR_C6713_HPIA);
1803 HPI_DEBUG_LOG(ERROR, "HPIA %x %x\n", 1701 HPI_DEBUG_LOG(ERROR, "HPIA %x %x\n",
1804 write_data, read_data); 1702 write_data, read_data);
1805 return err; 1703 return HPI6205_ERROR_C6713_HPIA;
1806 } 1704 }
1807 write_data = write_data << 1; 1705 write_data = write_data << 1;
1808 } 1706 }
@@ -1847,30 +1745,81 @@ static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index)
1847 /* PLL should not be bypassed! */ 1745 /* PLL should not be bypassed! */
1848 if ((boot_loader_read_mem32(pao, dsp_index, 0x01B7C100) & 0xF) 1746 if ((boot_loader_read_mem32(pao, dsp_index, 0x01B7C100) & 0xF)
1849 != 0x0001) { 1747 != 0x0001) {
1850 err = hpi6205_error(dsp_index, 1748 return HPI6205_ERROR_C6713_PLL;
1851 HPI6205_ERROR_C6713_PLL);
1852 return err;
1853 } 1749 }
1854 /* setup C67x EMIF (note this is the only use of 1750 /* setup C67x EMIF (note this is the only use of
1855 BAR1 via BootLoader_WriteMem32) */ 1751 BAR1 via BootLoader_WriteMem32) */
1856 boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_GCTL, 1752 boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_GCTL,
1857 0x000034A8); 1753 0x000034A8);
1754
1755 /* EMIF CE0 setup - 2Mx32 Sync DRAM
1756 31..28 Wr setup
1757 27..22 Wr strobe
1758 21..20 Wr hold
1759 19..16 Rd setup
1760 15..14 -
1761 13..8 Rd strobe
1762 7..4 MTYPE 0011 Sync DRAM 32bits
1763 3 Wr hold MSB
1764 2..0 Rd hold
1765 */
1858 boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_CE0, 1766 boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_CE0,
1859 0x00000030); 1767 0x00000030);
1768
1769 /* EMIF SDRAM Extension
1770 0x00
1771 31-21 0000b 0000b 000b
1772 20 WR2RD = 2cycles-1 = 1b
1773
1774 19-18 WR2DEAC = 3cycle-1 = 10b
1775 17 WR2WR = 2cycle-1 = 1b
1776 16-15 R2WDQM = 4cycle-1 = 11b
1777 14-12 RD2WR = 6cycles-1 = 101b
1778
1779 11-10 RD2DEAC = 4cycle-1 = 11b
1780 9 RD2RD = 2cycle-1 = 1b
1781 8-7 THZP = 3cycle-1 = 10b
1782 6-5 TWR = 2cycle-1 = 01b (tWR = 17ns)
1783 4 TRRD = 2cycle = 0b (tRRD = 14ns)
1784 3-1 TRAS = 5cycle-1 = 100b (Tras=42ns)
1785 1 CAS latency = 3cyc = 1b
1786 (for Micron 2M32-7 operating at 100MHz)
1787 */
1860 boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_SDRAMEXT, 1788 boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_SDRAMEXT,
1861 0x001BDF29); 1789 0x001BDF29);
1790
1791 /* EMIF SDRAM control - set up for a 2Mx32 SDRAM (512x32x4 bank)
1792 31 - 0b -
1793 30 SDBSZ 1b 4 bank
1794 29..28 SDRSZ 00b 11 row address pins
1795
1796 27..26 SDCSZ 01b 8 column address pins
1797 25 RFEN 1b refersh enabled
1798 24 INIT 1b init SDRAM!
1799
1800 23..20 TRCD 0001b (Trcd/Tcyc)-1 = (20/10)-1 = 1
1801
1802 19..16 TRP 0001b (Trp/Tcyc)-1 = (20/10)-1 = 1
1803
1804 15..12 TRC 0110b (Trc/Tcyc)-1 = (70/10)-1 = 6
1805
1806 11..0 - 0000b 0000b 0000b
1807 */
1862 boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_SDRAMCTL, 1808 boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_SDRAMCTL,
1863 0x47117000); 1809 0x47116000);
1810
1811 /* SDRAM refresh timing
1812 Need 4,096 refresh cycles every 64ms = 15.625us = 1562cycles of 100MHz = 0x61A
1813 */
1864 boot_loader_write_mem32(pao, dsp_index, 1814 boot_loader_write_mem32(pao, dsp_index,
1865 C6713_EMIF_SDRAMTIMING, 0x00000410); 1815 C6713_EMIF_SDRAMTIMING, 0x00000410);
1866 1816
1867 hpios_delay_micro_seconds(1000); 1817 hpios_delay_micro_seconds(1000);
1868 } else if (dsp_index == 2) { 1818 } else if (dsp_index == 2) {
1869 /* DSP 2 is a C6713 */ 1819 /* DSP 2 is a C6713 */
1820 }
1870 1821
1871 } else 1822 return 0;
1872 err = hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX);
1873 return err;
1874} 1823}
1875 1824
1876static u16 boot_loader_test_memory(struct hpi_adapter_obj *pao, int dsp_index, 1825static u16 boot_loader_test_memory(struct hpi_adapter_obj *pao, int dsp_index,
@@ -1896,7 +1845,7 @@ static u16 boot_loader_test_memory(struct hpi_adapter_obj *pao, int dsp_index,
1896 test_addr); 1845 test_addr);
1897 if (data != test_data) { 1846 if (data != test_data) {
1898 HPI_DEBUG_LOG(VERBOSE, 1847 HPI_DEBUG_LOG(VERBOSE,
1899 "memtest error details " 1848 "Memtest error details "
1900 "%08x %08x %08x %i\n", test_addr, 1849 "%08x %08x %08x %i\n", test_addr,
1901 test_data, data, dsp_index); 1850 test_data, data, dsp_index);
1902 return 1; /* error */ 1851 return 1; /* error */
@@ -1916,7 +1865,7 @@ static u16 boot_loader_test_memory(struct hpi_adapter_obj *pao, int dsp_index,
1916 data = boot_loader_read_mem32(pao, dsp_index, test_addr); 1865 data = boot_loader_read_mem32(pao, dsp_index, test_addr);
1917 if (data != test_data) { 1866 if (data != test_data) {
1918 HPI_DEBUG_LOG(VERBOSE, 1867 HPI_DEBUG_LOG(VERBOSE,
1919 "memtest error details " 1868 "Memtest error details "
1920 "%08x %08x %08x %i\n", test_addr, test_data, 1869 "%08x %08x %08x %i\n", test_addr, test_data,
1921 data, dsp_index); 1870 data, dsp_index);
1922 return 1; /* error */ 1871 return 1; /* error */
@@ -1946,8 +1895,8 @@ static u16 boot_loader_test_internal_memory(struct hpi_adapter_obj *pao,
1946 /* 64K data mem */ 1895 /* 64K data mem */
1947 err = boot_loader_test_memory(pao, dsp_index, 1896 err = boot_loader_test_memory(pao, dsp_index,
1948 0x80000000, 0x10000); 1897 0x80000000, 0x10000);
1949 } else if ((dsp_index == 1) || (dsp_index == 2)) { 1898 } else if (dsp_index == 1) {
1950 /* DSP 1&2 are a C6713 */ 1899 /* DSP 1 is a C6713 */
1951 /* 192K internal mem */ 1900 /* 192K internal mem */
1952 err = boot_loader_test_memory(pao, dsp_index, 0x00000000, 1901 err = boot_loader_test_memory(pao, dsp_index, 0x00000000,
1953 0x30000); 1902 0x30000);
@@ -1955,11 +1904,10 @@ static u16 boot_loader_test_internal_memory(struct hpi_adapter_obj *pao,
1955 /* 64K internal mem / L2 cache */ 1904 /* 64K internal mem / L2 cache */
1956 err = boot_loader_test_memory(pao, dsp_index, 1905 err = boot_loader_test_memory(pao, dsp_index,
1957 0x00030000, 0x10000); 1906 0x00030000, 0x10000);
1958 } else 1907 }
1959 return hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX);
1960 1908
1961 if (err) 1909 if (err)
1962 return hpi6205_error(dsp_index, HPI6205_ERROR_DSP_INTMEM); 1910 return HPI6205_ERROR_DSP_INTMEM;
1963 else 1911 else
1964 return 0; 1912 return 0;
1965} 1913}
@@ -1972,24 +1920,23 @@ static u16 boot_loader_test_external_memory(struct hpi_adapter_obj *pao,
1972 1920
1973 if (dsp_index == 0) { 1921 if (dsp_index == 0) {
1974 /* only test for SDRAM if an ASI5000 card */ 1922 /* only test for SDRAM if an ASI5000 card */
1975 if (pao->pci.subsys_device_id == 0x5000) { 1923 if (pao->pci.pci_dev->subsystem_device == 0x5000) {
1976 /* DSP 0 is always C6205 */ 1924 /* DSP 0 is always C6205 */
1977 dRAM_start_address = 0x00400000; 1925 dRAM_start_address = 0x00400000;
1978 dRAM_size = 0x200000; 1926 dRAM_size = 0x200000;
1979 /*dwDRAMinc=1024; */ 1927 /*dwDRAMinc=1024; */
1980 } else 1928 } else
1981 return 0; 1929 return 0;
1982 } else if ((dsp_index == 1) || (dsp_index == 2)) { 1930 } else if (dsp_index == 1) {
1983 /* DSP 1 is a C6713 */ 1931 /* DSP 1 is a C6713 */
1984 dRAM_start_address = 0x80000000; 1932 dRAM_start_address = 0x80000000;
1985 dRAM_size = 0x200000; 1933 dRAM_size = 0x200000;
1986 /*dwDRAMinc=1024; */ 1934 /*dwDRAMinc=1024; */
1987 } else 1935 }
1988 return hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX);
1989 1936
1990 if (boot_loader_test_memory(pao, dsp_index, dRAM_start_address, 1937 if (boot_loader_test_memory(pao, dsp_index, dRAM_start_address,
1991 dRAM_size)) 1938 dRAM_size))
1992 return hpi6205_error(dsp_index, HPI6205_ERROR_DSP_EXTMEM); 1939 return HPI6205_ERROR_DSP_EXTMEM;
1993 return 0; 1940 return 0;
1994} 1941}
1995 1942
@@ -1998,28 +1945,25 @@ static u16 boot_loader_test_pld(struct hpi_adapter_obj *pao, int dsp_index)
1998 u32 data = 0; 1945 u32 data = 0;
1999 if (dsp_index == 0) { 1946 if (dsp_index == 0) {
2000 /* only test for DSP0 PLD on ASI5000 card */ 1947 /* only test for DSP0 PLD on ASI5000 card */
2001 if (pao->pci.subsys_device_id == 0x5000) { 1948 if (pao->pci.pci_dev->subsystem_device == 0x5000) {
2002 /* PLD is located at CE3=0x03000000 */ 1949 /* PLD is located at CE3=0x03000000 */
2003 data = boot_loader_read_mem32(pao, dsp_index, 1950 data = boot_loader_read_mem32(pao, dsp_index,
2004 0x03000008); 1951 0x03000008);
2005 if ((data & 0xF) != 0x5) 1952 if ((data & 0xF) != 0x5)
2006 return hpi6205_error(dsp_index, 1953 return HPI6205_ERROR_DSP_PLD;
2007 HPI6205_ERROR_DSP_PLD);
2008 data = boot_loader_read_mem32(pao, dsp_index, 1954 data = boot_loader_read_mem32(pao, dsp_index,
2009 0x0300000C); 1955 0x0300000C);
2010 if ((data & 0xF) != 0xA) 1956 if ((data & 0xF) != 0xA)
2011 return hpi6205_error(dsp_index, 1957 return HPI6205_ERROR_DSP_PLD;
2012 HPI6205_ERROR_DSP_PLD);
2013 } 1958 }
2014 } else if (dsp_index == 1) { 1959 } else if (dsp_index == 1) {
2015 /* DSP 1 is a C6713 */ 1960 /* DSP 1 is a C6713 */
2016 if (pao->pci.subsys_device_id == 0x8700) { 1961 if (pao->pci.pci_dev->subsystem_device == 0x8700) {
2017 /* PLD is located at CE1=0x90000000 */ 1962 /* PLD is located at CE1=0x90000000 */
2018 data = boot_loader_read_mem32(pao, dsp_index, 1963 data = boot_loader_read_mem32(pao, dsp_index,
2019 0x90000010); 1964 0x90000010);
2020 if ((data & 0xFF) != 0xAA) 1965 if ((data & 0xFF) != 0xAA)
2021 return hpi6205_error(dsp_index, 1966 return HPI6205_ERROR_DSP_PLD;
2022 HPI6205_ERROR_DSP_PLD);
2023 /* 8713 - LED on */ 1967 /* 8713 - LED on */
2024 boot_loader_write_mem32(pao, dsp_index, 0x90000000, 1968 boot_loader_write_mem32(pao, dsp_index, 0x90000000,
2025 0x02); 1969 0x02);
@@ -2037,14 +1981,11 @@ static short hpi6205_transfer_data(struct hpi_adapter_obj *pao, u8 *p_data,
2037 struct hpi_hw_obj *phw = pao->priv; 1981 struct hpi_hw_obj *phw = pao->priv;
2038 u32 data_transferred = 0; 1982 u32 data_transferred = 0;
2039 u16 err = 0; 1983 u16 err = 0;
2040#ifndef HPI6205_NO_HSR_POLL
2041 u32 time_out;
2042#endif
2043 u32 temp2; 1984 u32 temp2;
2044 struct bus_master_interface *interface = phw->p_interface_buffer; 1985 struct bus_master_interface *interface = phw->p_interface_buffer;
2045 1986
2046 if (!p_data) 1987 if (!p_data)
2047 return HPI_ERROR_INVALID_DATA_TRANSFER; 1988 return HPI_ERROR_INVALID_DATA_POINTER;
2048 1989
2049 data_size &= ~3L; /* round data_size down to nearest 4 bytes */ 1990 data_size &= ~3L; /* round data_size down to nearest 4 bytes */
2050 1991
@@ -2064,14 +2005,10 @@ static short hpi6205_transfer_data(struct hpi_adapter_obj *pao, u8 *p_data,
2064 2005
2065 interface->transfer_size_in_bytes = this_copy; 2006 interface->transfer_size_in_bytes = this_copy;
2066 2007
2067#ifdef HPI6205_NO_HSR_POLL
2068 /* DSP must change this back to nOperation */ 2008 /* DSP must change this back to nOperation */
2069 interface->dsp_ack = H620_HIF_IDLE; 2009 interface->dsp_ack = H620_HIF_IDLE;
2070#endif
2071
2072 send_dsp_command(phw, operation); 2010 send_dsp_command(phw, operation);
2073 2011
2074#ifdef HPI6205_NO_HSR_POLL
2075 temp2 = wait_dsp_ack(phw, operation, HPI6205_TIMEOUT); 2012 temp2 = wait_dsp_ack(phw, operation, HPI6205_TIMEOUT);
2076 HPI_DEBUG_LOG(DEBUG, "spun %d times for data xfer of %d\n", 2013 HPI_DEBUG_LOG(DEBUG, "spun %d times for data xfer of %d\n",
2077 HPI6205_TIMEOUT - temp2, this_copy); 2014 HPI6205_TIMEOUT - temp2, this_copy);
@@ -2079,45 +2016,11 @@ static short hpi6205_transfer_data(struct hpi_adapter_obj *pao, u8 *p_data,
2079 if (!temp2) { 2016 if (!temp2) {
2080 /* timed out */ 2017 /* timed out */
2081 HPI_DEBUG_LOG(ERROR, 2018 HPI_DEBUG_LOG(ERROR,
2082 "timed out waiting for " "state %d got %d\n", 2019 "Timed out waiting for " "state %d got %d\n",
2083 operation, interface->dsp_ack); 2020 operation, interface->dsp_ack);
2084 2021
2085 break; 2022 break;
2086 } 2023 }
2087#else
2088 /* spin waiting on the result */
2089 time_out = HPI6205_TIMEOUT;
2090 temp2 = 0;
2091 while ((temp2 == 0) && time_out--) {
2092 /* give 16k bus mastering transfer time to happen */
2093 /*(16k / 132Mbytes/s = 122usec) */
2094 hpios_delay_micro_seconds(20);
2095 temp2 = ioread32(phw->prHSR);
2096 temp2 &= C6205_HSR_INTSRC;
2097 }
2098 HPI_DEBUG_LOG(DEBUG, "spun %d times for data xfer of %d\n",
2099 HPI6205_TIMEOUT - time_out, this_copy);
2100 if (temp2 == C6205_HSR_INTSRC) {
2101 HPI_DEBUG_LOG(VERBOSE,
2102 "interrupt from HIF <data> OK\n");
2103 /*
2104 if(interface->dwDspAck != nOperation) {
2105 HPI_DEBUG_LOG(DEBUG("interface->dwDspAck=%d,
2106 expected %d \n",
2107 interface->dwDspAck,nOperation);
2108 }
2109 */
2110 }
2111/* need to handle this differently... */
2112 else {
2113 HPI_DEBUG_LOG(ERROR,
2114 "interrupt from HIF <data> BAD\n");
2115 err = HPI_ERROR_DSP_HARDWARE;
2116 }
2117
2118 /* reset the interrupt from the DSP */
2119 iowrite32(C6205_HSR_INTSRC, phw->prHSR);
2120#endif
2121 if (operation == H620_HIF_GET_DATA) 2024 if (operation == H620_HIF_GET_DATA)
2122 memcpy(&p_data[data_transferred], 2025 memcpy(&p_data[data_transferred],
2123 (void *)&interface->u.b_data[0], this_copy); 2026 (void *)&interface->u.b_data[0], this_copy);
@@ -2174,31 +2077,39 @@ static unsigned int message_count;
2174static u16 message_response_sequence(struct hpi_adapter_obj *pao, 2077static u16 message_response_sequence(struct hpi_adapter_obj *pao,
2175 struct hpi_message *phm, struct hpi_response *phr) 2078 struct hpi_message *phm, struct hpi_response *phr)
2176{ 2079{
2177#ifndef HPI6205_NO_HSR_POLL
2178 u32 temp2;
2179#endif
2180 u32 time_out, time_out2; 2080 u32 time_out, time_out2;
2181 struct hpi_hw_obj *phw = pao->priv; 2081 struct hpi_hw_obj *phw = pao->priv;
2182 struct bus_master_interface *interface = phw->p_interface_buffer; 2082 struct bus_master_interface *interface = phw->p_interface_buffer;
2183 u16 err = 0; 2083 u16 err = 0;
2184 2084
2185 message_count++; 2085 message_count++;
2086 if (phm->size > sizeof(interface->u)) {
2087 phr->error = HPI_ERROR_MESSAGE_BUFFER_TOO_SMALL;
2088 phr->specific_error = sizeof(interface->u);
2089 phr->size = sizeof(struct hpi_response_header);
2090 HPI_DEBUG_LOG(ERROR,
2091 "message len %d too big for buffer %zd \n", phm->size,
2092 sizeof(interface->u));
2093 return 0;
2094 }
2095
2186 /* Assume buffer of type struct bus_master_interface 2096 /* Assume buffer of type struct bus_master_interface
2187 is allocated "noncacheable" */ 2097 is allocated "noncacheable" */
2188 2098
2189 if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT)) { 2099 if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT)) {
2190 HPI_DEBUG_LOG(DEBUG, "timeout waiting for idle\n"); 2100 HPI_DEBUG_LOG(DEBUG, "timeout waiting for idle\n");
2191 return hpi6205_error(0, HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT); 2101 return HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT;
2192 } 2102 }
2193 interface->u.message_buffer = *phm; 2103
2104 memcpy(&interface->u.message_buffer, phm, phm->size);
2194 /* signal we want a response */ 2105 /* signal we want a response */
2195 send_dsp_command(phw, H620_HIF_GET_RESP); 2106 send_dsp_command(phw, H620_HIF_GET_RESP);
2196 2107
2197 time_out2 = wait_dsp_ack(phw, H620_HIF_GET_RESP, HPI6205_TIMEOUT); 2108 time_out2 = wait_dsp_ack(phw, H620_HIF_GET_RESP, HPI6205_TIMEOUT);
2198 2109
2199 if (time_out2 == 0) { 2110 if (!time_out2) {
2200 HPI_DEBUG_LOG(ERROR, 2111 HPI_DEBUG_LOG(ERROR,
2201 "(%u) timed out waiting for " "GET_RESP state [%x]\n", 2112 "(%u) Timed out waiting for " "GET_RESP state [%x]\n",
2202 message_count, interface->dsp_ack); 2113 message_count, interface->dsp_ack);
2203 } else { 2114 } else {
2204 HPI_DEBUG_LOG(VERBOSE, 2115 HPI_DEBUG_LOG(VERBOSE,
@@ -2208,58 +2119,38 @@ static u16 message_response_sequence(struct hpi_adapter_obj *pao,
2208 /* spin waiting on HIF interrupt flag (end of msg process) */ 2119 /* spin waiting on HIF interrupt flag (end of msg process) */
2209 time_out = HPI6205_TIMEOUT; 2120 time_out = HPI6205_TIMEOUT;
2210 2121
2211#ifndef HPI6205_NO_HSR_POLL 2122 /* read the result */
2212 temp2 = 0; 2123 if (time_out) {
2213 while ((temp2 == 0) && --time_out) { 2124 if (interface->u.response_buffer.size <= phr->size)
2214 temp2 = ioread32(phw->prHSR); 2125 memcpy(phr, &interface->u.response_buffer,
2215 temp2 &= C6205_HSR_INTSRC; 2126 interface->u.response_buffer.size);
2216 hpios_delay_micro_seconds(1); 2127 else {
2217 } 2128 HPI_DEBUG_LOG(ERROR,
2218 if (temp2 == C6205_HSR_INTSRC) { 2129 "response len %d too big for buffer %d\n",
2219 rmb(); /* ensure we see latest value for dsp_ack */ 2130 interface->u.response_buffer.size, phr->size);
2220 if ((interface->dsp_ack != H620_HIF_GET_RESP)) { 2131 memcpy(phr, &interface->u.response_buffer,
2221 HPI_DEBUG_LOG(DEBUG, 2132 sizeof(struct hpi_response_header));
2222 "(%u)interface->dsp_ack(0x%x) != " 2133 phr->error = HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL;
2223 "H620_HIF_GET_RESP, t=%u\n", message_count, 2134 phr->specific_error =
2224 interface->dsp_ack, 2135 interface->u.response_buffer.size;
2225 HPI6205_TIMEOUT - time_out); 2136 phr->size = sizeof(struct hpi_response_header);
2226 } else {
2227 HPI_DEBUG_LOG(VERBOSE,
2228 "(%u)int with GET_RESP after %u\n",
2229 message_count, HPI6205_TIMEOUT - time_out);
2230 } 2137 }
2231
2232 } else {
2233 /* can we do anything else in response to the error ? */
2234 HPI_DEBUG_LOG(ERROR,
2235 "interrupt from HIF module BAD (function %x)\n",
2236 phm->function);
2237 } 2138 }
2238
2239 /* reset the interrupt from the DSP */
2240 iowrite32(C6205_HSR_INTSRC, phw->prHSR);
2241#endif
2242
2243 /* read the result */
2244 if (time_out != 0)
2245 *phr = interface->u.response_buffer;
2246
2247 /* set interface back to idle */ 2139 /* set interface back to idle */
2248 send_dsp_command(phw, H620_HIF_IDLE); 2140 send_dsp_command(phw, H620_HIF_IDLE);
2249 2141
2250 if ((time_out == 0) || (time_out2 == 0)) { 2142 if (!time_out || !time_out2) {
2251 HPI_DEBUG_LOG(DEBUG, "something timed out!\n"); 2143 HPI_DEBUG_LOG(DEBUG, "something timed out!\n");
2252 return hpi6205_error(0, HPI6205_ERROR_MSG_RESP_TIMEOUT); 2144 return HPI6205_ERROR_MSG_RESP_TIMEOUT;
2253 } 2145 }
2254 /* special case for adapter close - */ 2146 /* special case for adapter close - */
2255 /* wait for the DSP to indicate it is idle */ 2147 /* wait for the DSP to indicate it is idle */
2256 if (phm->function == HPI_ADAPTER_CLOSE) { 2148 if (phm->function == HPI_ADAPTER_CLOSE) {
2257 if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT)) { 2149 if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT)) {
2258 HPI_DEBUG_LOG(DEBUG, 2150 HPI_DEBUG_LOG(DEBUG,
2259 "timeout waiting for idle " 2151 "Timeout waiting for idle "
2260 "(on adapter_close)\n"); 2152 "(on adapter_close)\n");
2261 return hpi6205_error(0, 2153 return HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT;
2262 HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT);
2263 } 2154 }
2264 } 2155 }
2265 err = hpi_validate_response(phm, phr); 2156 err = hpi_validate_response(phm, phr);
@@ -2279,7 +2170,13 @@ static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
2279 /* maybe an error response */ 2170 /* maybe an error response */
2280 if (err) { 2171 if (err) {
2281 /* something failed in the HPI/DSP interface */ 2172 /* something failed in the HPI/DSP interface */
2282 phr->error = err; 2173 if (err >= HPI_ERROR_BACKEND_BASE) {
2174 phr->error = HPI_ERROR_DSP_COMMUNICATION;
2175 phr->specific_error = err;
2176 } else {
2177 phr->error = err;
2178 }
2179
2283 pao->dsp_crashed++; 2180 pao->dsp_crashed++;
2284 2181
2285 /* just the header of the response is valid */ 2182 /* just the header of the response is valid */
diff --git a/sound/pci/asihpi/hpi6205.h b/sound/pci/asihpi/hpi6205.h
index 1adae0857cda..df2f02c0c7b4 100644
--- a/sound/pci/asihpi/hpi6205.h
+++ b/sound/pci/asihpi/hpi6205.h
@@ -25,9 +25,6 @@ Copyright AudioScience, Inc., 2003
25#ifndef _HPI6205_H_ 25#ifndef _HPI6205_H_
26#define _HPI6205_H_ 26#define _HPI6205_H_
27 27
28/* transitional conditional compile shared between host and DSP */
29/* #define HPI6205_NO_HSR_POLL */
30
31#include "hpi_internal.h" 28#include "hpi_internal.h"
32 29
33/*********************************************************** 30/***********************************************************
@@ -78,8 +75,8 @@ struct bus_master_interface {
78 u32 dsp_ack; 75 u32 dsp_ack;
79 u32 transfer_size_in_bytes; 76 u32 transfer_size_in_bytes;
80 union { 77 union {
81 struct hpi_message message_buffer; 78 struct hpi_message_header message_buffer;
82 struct hpi_response response_buffer; 79 struct hpi_response_header response_buffer;
83 u8 b_data[HPI6205_SIZEOF_DATA]; 80 u8 b_data[HPI6205_SIZEOF_DATA];
84 } u; 81 } u;
85 struct controlcache_6205 control_cache; 82 struct controlcache_6205 control_cache;
diff --git a/sound/pci/asihpi/hpi_internal.h b/sound/pci/asihpi/hpi_internal.h
index 16f502d459de..af678be0aa15 100644
--- a/sound/pci/asihpi/hpi_internal.h
+++ b/sound/pci/asihpi/hpi_internal.h
@@ -28,7 +28,7 @@ HPI internal definitions
28/** maximum number of memory regions mapped to an adapter */ 28/** maximum number of memory regions mapped to an adapter */
29#define HPI_MAX_ADAPTER_MEM_SPACES (2) 29#define HPI_MAX_ADAPTER_MEM_SPACES (2)
30 30
31/* Each OS needs its own hpios.h, or specific define as above */ 31/* Each OS needs its own hpios.h */
32#include "hpios.h" 32#include "hpios.h"
33 33
34/* physical memory allocation */ 34/* physical memory allocation */
@@ -49,7 +49,7 @@ HpiOs_LockedMem_GetPyhsAddr() will always succed on the returned handle.
49*/ 49*/
50u16 hpios_locked_mem_alloc(struct consistent_dma_area *p_locked_mem_handle, 50u16 hpios_locked_mem_alloc(struct consistent_dma_area *p_locked_mem_handle,
51 /**< memory handle */ 51 /**< memory handle */
52 u32 size, /**< size in bytes to allocate */ 52 u32 size, /**< Size in bytes to allocate */
53 struct pci_dev *p_os_reference 53 struct pci_dev *p_os_reference
54 /**< OS specific data required for memory allocation */ 54 /**< OS specific data required for memory allocation */
55 ); 55 );
@@ -96,41 +96,6 @@ typedef void hpi_handler_func(struct hpi_message *, struct hpi_response *);
96#define compile_time_assert(cond, msg) \ 96#define compile_time_assert(cond, msg) \
97 typedef char ASSERT_##msg[(cond) ? 1 : -1] 97 typedef char ASSERT_##msg[(cond) ? 1 : -1]
98 98
99/*/////////////////////////////////////////////////////////////////////////// */
100/* Private HPI Entity related definitions */
101
102#define STR_SIZE_FIELD_MAX 65535U
103#define STR_TYPE_FIELD_MAX 255U
104#define STR_ROLE_FIELD_MAX 255U
105
106struct hpi_entity_str {
107 u16 size;
108 u8 type;
109 u8 role;
110};
111
112#if defined(_MSC_VER)
113#pragma warning(push)
114#pragma warning(disable : 4200)
115#endif
116
117struct hpi_entity {
118 struct hpi_entity_str header;
119#if ! defined(HPI_OS_DSP_C6000) || (defined(HPI_OS_DSP_C6000) && (__TI_COMPILER_VERSION__ > 6000008))
120 /* DSP C6000 compiler v6.0.8 and lower
121 do not support flexible array member */
122 u8 value[];
123#else
124 /* NOTE! Using sizeof(struct hpi_entity) will give erroneous results */
125#define HPI_INTERNAL_WARN_ABOUT_ENTITY_VALUE
126 u8 value[1];
127#endif
128};
129
130#if defined(_MSC_VER)
131#pragma warning(pop)
132#endif
133
134/******************************************* bus types */ 99/******************************************* bus types */
135enum HPI_BUSES { 100enum HPI_BUSES {
136 HPI_BUS_ISAPNP = 1, 101 HPI_BUS_ISAPNP = 1,
@@ -139,206 +104,155 @@ enum HPI_BUSES {
139 HPI_BUS_NET = 4 104 HPI_BUS_NET = 4
140}; 105};
141 106
107enum HPI_SUBSYS_OPTIONS {
108 /* 0, 256 are invalid, 1..255 reserved for global options */
109 HPI_SUBSYS_OPT_NET_ENABLE = 257,
110 HPI_SUBSYS_OPT_NET_BROADCAST = 258,
111 HPI_SUBSYS_OPT_NET_UNICAST = 259,
112 HPI_SUBSYS_OPT_NET_ADDR = 260,
113 HPI_SUBSYS_OPT_NET_MASK = 261,
114 HPI_SUBSYS_OPT_NET_ADAPTER_ADDRESS_ADD = 262
115};
116
117/** Volume flags
118*/
119enum HPI_VOLUME_FLAGS {
120 /** Set if the volume control is muted */
121 HPI_VOLUME_FLAG_MUTED = (1 << 0),
122 /** Set if the volume control has a mute function */
123 HPI_VOLUME_FLAG_HAS_MUTE = (1 << 1),
124 /** Set if volume control can do autofading */
125 HPI_VOLUME_FLAG_HAS_AUTOFADE = (1 << 2)
126 /* Note Flags >= (1<<8) are for DSP internal use only */
127};
128
142/******************************************* CONTROL ATTRIBUTES ****/ 129/******************************************* CONTROL ATTRIBUTES ****/
143/* (in order of control type ID */ 130/* (in order of control type ID */
144 131
145/* This allows for 255 control types, 256 unique attributes each */ 132/* This allows for 255 control types, 256 unique attributes each */
146#define HPI_CTL_ATTR(ctl, ai) (HPI_CONTROL_##ctl * 0x100 + ai) 133#define HPI_CTL_ATTR(ctl, ai) ((HPI_CONTROL_##ctl << 8) + ai)
147 134
148/* Get the sub-index of the attribute for a control type */ 135/* Get the sub-index of the attribute for a control type */
149#define HPI_CTL_ATTR_INDEX(i) (i&0xff) 136#define HPI_CTL_ATTR_INDEX(i) (i & 0xff)
150 137
151/* Extract the control from the control attribute */ 138/* Extract the control from the control attribute */
152#define HPI_CTL_ATTR_CONTROL(i) (i>>8) 139#define HPI_CTL_ATTR_CONTROL(i) (i >> 8)
153
154/* Generic control attributes. */
155
156/** Enable a control.
1570=disable, 1=enable
158\note generic to all mixer plugins?
159*/
160#define HPI_GENERIC_ENABLE HPI_CTL_ATTR(GENERIC, 1)
161 140
162/** Enable event generation for a control. 141/** Enable event generation for a control.
1630=disable, 1=enable 1420=disable, 1=enable
164\note generic to all controls that can generate events 143\note generic to all controls that can generate events
165*/ 144*/
166#define HPI_GENERIC_EVENT_ENABLE HPI_CTL_ATTR(GENERIC, 2) 145
167 146/** Unique identifiers for every control attribute
168/* Volume Control attributes */
169#define HPI_VOLUME_GAIN HPI_CTL_ATTR(VOLUME, 1)
170#define HPI_VOLUME_AUTOFADE HPI_CTL_ATTR(VOLUME, 2)
171
172/** For HPI_ControlQuery() to get the number of channels of a volume control*/
173#define HPI_VOLUME_NUM_CHANNELS HPI_CTL_ATTR(VOLUME, 6)
174#define HPI_VOLUME_RANGE HPI_CTL_ATTR(VOLUME, 10)
175
176/** Level Control attributes */
177#define HPI_LEVEL_GAIN HPI_CTL_ATTR(LEVEL, 1)
178#define HPI_LEVEL_RANGE HPI_CTL_ATTR(LEVEL, 10)
179
180/* Meter Control attributes */
181/** return RMS signal level */
182#define HPI_METER_RMS HPI_CTL_ATTR(METER, 1)
183/** return peak signal level */
184#define HPI_METER_PEAK HPI_CTL_ATTR(METER, 2)
185/** ballistics for ALL rms meters on adapter */
186#define HPI_METER_RMS_BALLISTICS HPI_CTL_ATTR(METER, 3)
187/** ballistics for ALL peak meters on adapter */
188#define HPI_METER_PEAK_BALLISTICS HPI_CTL_ATTR(METER, 4)
189
190/** For HPI_ControlQuery() to get the number of channels of a meter control*/
191#define HPI_METER_NUM_CHANNELS HPI_CTL_ATTR(METER, 5)
192
193/* Multiplexer control attributes */
194#define HPI_MULTIPLEXER_SOURCE HPI_CTL_ATTR(MULTIPLEXER, 1)
195#define HPI_MULTIPLEXER_QUERYSOURCE HPI_CTL_ATTR(MULTIPLEXER, 2)
196
197/** AES/EBU transmitter control attributes */
198/** AESEBU or SPDIF */
199#define HPI_AESEBUTX_FORMAT HPI_CTL_ATTR(AESEBUTX, 1)
200#define HPI_AESEBUTX_SAMPLERATE HPI_CTL_ATTR(AESEBUTX, 3)
201#define HPI_AESEBUTX_CHANNELSTATUS HPI_CTL_ATTR(AESEBUTX, 4)
202#define HPI_AESEBUTX_USERDATA HPI_CTL_ATTR(AESEBUTX, 5)
203
204/** AES/EBU receiver control attributes */
205#define HPI_AESEBURX_FORMAT HPI_CTL_ATTR(AESEBURX, 1)
206#define HPI_AESEBURX_ERRORSTATUS HPI_CTL_ATTR(AESEBURX, 2)
207#define HPI_AESEBURX_SAMPLERATE HPI_CTL_ATTR(AESEBURX, 3)
208#define HPI_AESEBURX_CHANNELSTATUS HPI_CTL_ATTR(AESEBURX, 4)
209#define HPI_AESEBURX_USERDATA HPI_CTL_ATTR(AESEBURX, 5)
210
211/** \defgroup tuner_defs Tuners
212\{
213*/
214/** \defgroup tuner_attrs Tuner control attributes
215\{
216*/
217#define HPI_TUNER_BAND HPI_CTL_ATTR(TUNER, 1)
218#define HPI_TUNER_FREQ HPI_CTL_ATTR(TUNER, 2)
219#define HPI_TUNER_LEVEL HPI_CTL_ATTR(TUNER, 3)
220#define HPI_TUNER_AUDIOMUTE HPI_CTL_ATTR(TUNER, 4)
221/* use TUNER_STATUS instead */
222#define HPI_TUNER_VIDEO_STATUS HPI_CTL_ATTR(TUNER, 5)
223#define HPI_TUNER_GAIN HPI_CTL_ATTR(TUNER, 6)
224#define HPI_TUNER_STATUS HPI_CTL_ATTR(TUNER, 7)
225#define HPI_TUNER_MODE HPI_CTL_ATTR(TUNER, 8)
226/** RDS data. */
227#define HPI_TUNER_RDS HPI_CTL_ATTR(TUNER, 9)
228/** Audio pre-emphasis. */
229#define HPI_TUNER_DEEMPHASIS HPI_CTL_ATTR(TUNER, 10)
230/** HD Radio tuner program control. */
231#define HPI_TUNER_PROGRAM HPI_CTL_ATTR(TUNER, 11)
232/** HD Radio tuner digital signal quality. */
233#define HPI_TUNER_HDRADIO_SIGNAL_QUALITY HPI_CTL_ATTR(TUNER, 12)
234/** HD Radio SDK firmware version. */
235#define HPI_TUNER_HDRADIO_SDK_VERSION HPI_CTL_ATTR(TUNER, 13)
236/** HD Radio DSP firmware version. */
237#define HPI_TUNER_HDRADIO_DSP_VERSION HPI_CTL_ATTR(TUNER, 14)
238/** HD Radio signal blend (force analog, or automatic). */
239#define HPI_TUNER_HDRADIO_BLEND HPI_CTL_ATTR(TUNER, 15)
240
241/** \} */
242
243/** \defgroup pads_attrs Tuner PADs control attributes
244\{
245*/
246/** The text string containing the station/channel combination. */
247#define HPI_PAD_CHANNEL_NAME HPI_CTL_ATTR(PAD, 1)
248/** The text string containing the artist. */
249#define HPI_PAD_ARTIST HPI_CTL_ATTR(PAD, 2)
250/** The text string containing the title. */
251#define HPI_PAD_TITLE HPI_CTL_ATTR(PAD, 3)
252/** The text string containing the comment. */
253#define HPI_PAD_COMMENT HPI_CTL_ATTR(PAD, 4)
254/** The integer containing the PTY code. */
255#define HPI_PAD_PROGRAM_TYPE HPI_CTL_ATTR(PAD, 5)
256/** The integer containing the program identification. */
257#define HPI_PAD_PROGRAM_ID HPI_CTL_ATTR(PAD, 6)
258/** The integer containing whether traffic information is supported.
259Contains either 1 or 0. */
260#define HPI_PAD_TA_SUPPORT HPI_CTL_ATTR(PAD, 7)
261/** The integer containing whether traffic announcement is in progress.
262Contains either 1 or 0. */
263#define HPI_PAD_TA_ACTIVE HPI_CTL_ATTR(PAD, 8)
264/** \} */
265/** \} */
266
267/* VOX control attributes */
268#define HPI_VOX_THRESHOLD HPI_CTL_ATTR(VOX, 1)
269
270/*?? channel mode used hpi_multiplexer_source attribute == 1 */
271#define HPI_CHANNEL_MODE_MODE HPI_CTL_ATTR(CHANNEL_MODE, 1)
272
273/** \defgroup channel_modes Channel Modes
274Used for HPI_ChannelModeSet/Get()
275\{
276*/ 147*/
277/** Left channel out = left channel in, Right channel out = right channel in. */ 148enum HPI_CONTROL_ATTRIBUTES {
278#define HPI_CHANNEL_MODE_NORMAL 1 149 HPI_GENERIC_ENABLE = HPI_CTL_ATTR(GENERIC, 1),
279/** Left channel out = right channel in, Right channel out = left channel in. */ 150 HPI_GENERIC_EVENT_ENABLE = HPI_CTL_ATTR(GENERIC, 2),
280#define HPI_CHANNEL_MODE_SWAP 2 151
281/** Left channel out = left channel in, Right channel out = left channel in. */ 152 HPI_VOLUME_GAIN = HPI_CTL_ATTR(VOLUME, 1),
282#define HPI_CHANNEL_MODE_LEFT_TO_STEREO 3 153 HPI_VOLUME_AUTOFADE = HPI_CTL_ATTR(VOLUME, 2),
283/** Left channel out = right channel in, Right channel out = right channel in.*/ 154 HPI_VOLUME_MUTE = HPI_CTL_ATTR(VOLUME, 3),
284#define HPI_CHANNEL_MODE_RIGHT_TO_STEREO 4 155 HPI_VOLUME_GAIN_AND_FLAGS = HPI_CTL_ATTR(VOLUME, 4),
285/** Left channel out = (left channel in + right channel in)/2, 156 HPI_VOLUME_NUM_CHANNELS = HPI_CTL_ATTR(VOLUME, 6),
286 Right channel out = mute. */ 157 HPI_VOLUME_RANGE = HPI_CTL_ATTR(VOLUME, 10),
287#define HPI_CHANNEL_MODE_STEREO_TO_LEFT 5 158
288/** Left channel out = mute, 159 HPI_METER_RMS = HPI_CTL_ATTR(METER, 1),
289 Right channel out = (right channel in + left channel in)/2. */ 160 HPI_METER_PEAK = HPI_CTL_ATTR(METER, 2),
290#define HPI_CHANNEL_MODE_STEREO_TO_RIGHT 6 161 HPI_METER_RMS_BALLISTICS = HPI_CTL_ATTR(METER, 3),
291#define HPI_CHANNEL_MODE_LAST 6 162 HPI_METER_PEAK_BALLISTICS = HPI_CTL_ATTR(METER, 4),
292/** \} */ 163 HPI_METER_NUM_CHANNELS = HPI_CTL_ATTR(METER, 5),
293 164
294/* Bitstream control set attributes */ 165 HPI_MULTIPLEXER_SOURCE = HPI_CTL_ATTR(MULTIPLEXER, 1),
295#define HPI_BITSTREAM_DATA_POLARITY HPI_CTL_ATTR(BITSTREAM, 1) 166 HPI_MULTIPLEXER_QUERYSOURCE = HPI_CTL_ATTR(MULTIPLEXER, 2),
296#define HPI_BITSTREAM_CLOCK_EDGE HPI_CTL_ATTR(BITSTREAM, 2) 167
297#define HPI_BITSTREAM_CLOCK_SOURCE HPI_CTL_ATTR(BITSTREAM, 3) 168 HPI_AESEBUTX_FORMAT = HPI_CTL_ATTR(AESEBUTX, 1),
169 HPI_AESEBUTX_SAMPLERATE = HPI_CTL_ATTR(AESEBUTX, 3),
170 HPI_AESEBUTX_CHANNELSTATUS = HPI_CTL_ATTR(AESEBUTX, 4),
171 HPI_AESEBUTX_USERDATA = HPI_CTL_ATTR(AESEBUTX, 5),
172
173 HPI_AESEBURX_FORMAT = HPI_CTL_ATTR(AESEBURX, 1),
174 HPI_AESEBURX_ERRORSTATUS = HPI_CTL_ATTR(AESEBURX, 2),
175 HPI_AESEBURX_SAMPLERATE = HPI_CTL_ATTR(AESEBURX, 3),
176 HPI_AESEBURX_CHANNELSTATUS = HPI_CTL_ATTR(AESEBURX, 4),
177 HPI_AESEBURX_USERDATA = HPI_CTL_ATTR(AESEBURX, 5),
178
179 HPI_LEVEL_GAIN = HPI_CTL_ATTR(LEVEL, 1),
180 HPI_LEVEL_RANGE = HPI_CTL_ATTR(LEVEL, 10),
181
182 HPI_TUNER_BAND = HPI_CTL_ATTR(TUNER, 1),
183 HPI_TUNER_FREQ = HPI_CTL_ATTR(TUNER, 2),
184 HPI_TUNER_LEVEL_AVG = HPI_CTL_ATTR(TUNER, 3),
185 HPI_TUNER_LEVEL_RAW = HPI_CTL_ATTR(TUNER, 4),
186 HPI_TUNER_SNR = HPI_CTL_ATTR(TUNER, 5),
187 HPI_TUNER_GAIN = HPI_CTL_ATTR(TUNER, 6),
188 HPI_TUNER_STATUS = HPI_CTL_ATTR(TUNER, 7),
189 HPI_TUNER_MODE = HPI_CTL_ATTR(TUNER, 8),
190 HPI_TUNER_RDS = HPI_CTL_ATTR(TUNER, 9),
191 HPI_TUNER_DEEMPHASIS = HPI_CTL_ATTR(TUNER, 10),
192 HPI_TUNER_PROGRAM = HPI_CTL_ATTR(TUNER, 11),
193 HPI_TUNER_HDRADIO_SIGNAL_QUALITY = HPI_CTL_ATTR(TUNER, 12),
194 HPI_TUNER_HDRADIO_SDK_VERSION = HPI_CTL_ATTR(TUNER, 13),
195 HPI_TUNER_HDRADIO_DSP_VERSION = HPI_CTL_ATTR(TUNER, 14),
196 HPI_TUNER_HDRADIO_BLEND = HPI_CTL_ATTR(TUNER, 15),
197
198 HPI_VOX_THRESHOLD = HPI_CTL_ATTR(VOX, 1),
199
200 HPI_CHANNEL_MODE_MODE = HPI_CTL_ATTR(CHANNEL_MODE, 1),
201
202 HPI_BITSTREAM_DATA_POLARITY = HPI_CTL_ATTR(BITSTREAM, 1),
203 HPI_BITSTREAM_CLOCK_EDGE = HPI_CTL_ATTR(BITSTREAM, 2),
204 HPI_BITSTREAM_CLOCK_SOURCE = HPI_CTL_ATTR(BITSTREAM, 3),
205 HPI_BITSTREAM_ACTIVITY = HPI_CTL_ATTR(BITSTREAM, 4),
206
207 HPI_SAMPLECLOCK_SOURCE = HPI_CTL_ATTR(SAMPLECLOCK, 1),
208 HPI_SAMPLECLOCK_SAMPLERATE = HPI_CTL_ATTR(SAMPLECLOCK, 2),
209 HPI_SAMPLECLOCK_SOURCE_INDEX = HPI_CTL_ATTR(SAMPLECLOCK, 3),
210 HPI_SAMPLECLOCK_LOCAL_SAMPLERATE = HPI_CTL_ATTR(SAMPLECLOCK, 4),
211 HPI_SAMPLECLOCK_AUTO = HPI_CTL_ATTR(SAMPLECLOCK, 5),
212 HPI_SAMPLECLOCK_LOCAL_LOCK = HPI_CTL_ATTR(SAMPLECLOCK, 6),
213
214 HPI_MICROPHONE_PHANTOM_POWER = HPI_CTL_ATTR(MICROPHONE, 1),
215
216 HPI_EQUALIZER_NUM_FILTERS = HPI_CTL_ATTR(EQUALIZER, 1),
217 HPI_EQUALIZER_FILTER = HPI_CTL_ATTR(EQUALIZER, 2),
218 HPI_EQUALIZER_COEFFICIENTS = HPI_CTL_ATTR(EQUALIZER, 3),
219
220 HPI_COMPANDER_PARAMS = HPI_CTL_ATTR(COMPANDER, 1),
221 HPI_COMPANDER_MAKEUPGAIN = HPI_CTL_ATTR(COMPANDER, 2),
222 HPI_COMPANDER_THRESHOLD = HPI_CTL_ATTR(COMPANDER, 3),
223 HPI_COMPANDER_RATIO = HPI_CTL_ATTR(COMPANDER, 4),
224 HPI_COMPANDER_ATTACK = HPI_CTL_ATTR(COMPANDER, 5),
225 HPI_COMPANDER_DECAY = HPI_CTL_ATTR(COMPANDER, 6),
226
227 HPI_COBRANET_SET = HPI_CTL_ATTR(COBRANET, 1),
228 HPI_COBRANET_GET = HPI_CTL_ATTR(COBRANET, 2),
229 HPI_COBRANET_SET_DATA = HPI_CTL_ATTR(COBRANET, 3),
230 HPI_COBRANET_GET_DATA = HPI_CTL_ATTR(COBRANET, 4),
231 HPI_COBRANET_GET_STATUS = HPI_CTL_ATTR(COBRANET, 5),
232 HPI_COBRANET_SEND_PACKET = HPI_CTL_ATTR(COBRANET, 6),
233 HPI_COBRANET_GET_PACKET = HPI_CTL_ATTR(COBRANET, 7),
234
235 HPI_TONEDETECTOR_THRESHOLD = HPI_CTL_ATTR(TONEDETECTOR, 1),
236 HPI_TONEDETECTOR_STATE = HPI_CTL_ATTR(TONEDETECTOR, 2),
237 HPI_TONEDETECTOR_FREQUENCY = HPI_CTL_ATTR(TONEDETECTOR, 3),
238
239 HPI_SILENCEDETECTOR_THRESHOLD = HPI_CTL_ATTR(SILENCEDETECTOR, 1),
240 HPI_SILENCEDETECTOR_STATE = HPI_CTL_ATTR(SILENCEDETECTOR, 2),
241 HPI_SILENCEDETECTOR_DELAY = HPI_CTL_ATTR(SILENCEDETECTOR, 3),
242
243 HPI_PAD_CHANNEL_NAME = HPI_CTL_ATTR(PAD, 1),
244 HPI_PAD_ARTIST = HPI_CTL_ATTR(PAD, 2),
245 HPI_PAD_TITLE = HPI_CTL_ATTR(PAD, 3),
246 HPI_PAD_COMMENT = HPI_CTL_ATTR(PAD, 4),
247 HPI_PAD_PROGRAM_TYPE = HPI_CTL_ATTR(PAD, 5),
248 HPI_PAD_PROGRAM_ID = HPI_CTL_ATTR(PAD, 6),
249 HPI_PAD_TA_SUPPORT = HPI_CTL_ATTR(PAD, 7),
250 HPI_PAD_TA_ACTIVE = HPI_CTL_ATTR(PAD, 8)
251};
298 252
299#define HPI_POLARITY_POSITIVE 0 253#define HPI_POLARITY_POSITIVE 0
300#define HPI_POLARITY_NEGATIVE 1 254#define HPI_POLARITY_NEGATIVE 1
301 255
302/* Bitstream control get attributes */
303#define HPI_BITSTREAM_ACTIVITY 1
304
305/* SampleClock control attributes */
306#define HPI_SAMPLECLOCK_SOURCE HPI_CTL_ATTR(SAMPLECLOCK, 1)
307#define HPI_SAMPLECLOCK_SAMPLERATE HPI_CTL_ATTR(SAMPLECLOCK, 2)
308#define HPI_SAMPLECLOCK_SOURCE_INDEX HPI_CTL_ATTR(SAMPLECLOCK, 3)
309#define HPI_SAMPLECLOCK_LOCAL_SAMPLERATE\
310 HPI_CTL_ATTR(SAMPLECLOCK, 4)
311#define HPI_SAMPLECLOCK_AUTO HPI_CTL_ATTR(SAMPLECLOCK, 5)
312#define HPI_SAMPLECLOCK_LOCAL_LOCK HPI_CTL_ATTR(SAMPLECLOCK, 6)
313
314/* Microphone control attributes */
315#define HPI_MICROPHONE_PHANTOM_POWER HPI_CTL_ATTR(MICROPHONE, 1)
316
317/** Equalizer control attributes */
318/** Used to get number of filters in an EQ. (Can't set) */
319#define HPI_EQUALIZER_NUM_FILTERS HPI_CTL_ATTR(EQUALIZER, 1)
320/** Set/get the filter by type, freq, Q, gain */
321#define HPI_EQUALIZER_FILTER HPI_CTL_ATTR(EQUALIZER, 2)
322/** Get the biquad coefficients */
323#define HPI_EQUALIZER_COEFFICIENTS HPI_CTL_ATTR(EQUALIZER, 3)
324
325/* Note compander also uses HPI_GENERIC_ENABLE */
326#define HPI_COMPANDER_PARAMS HPI_CTL_ATTR(COMPANDER, 1)
327#define HPI_COMPANDER_MAKEUPGAIN HPI_CTL_ATTR(COMPANDER, 2)
328#define HPI_COMPANDER_THRESHOLD HPI_CTL_ATTR(COMPANDER, 3)
329#define HPI_COMPANDER_RATIO HPI_CTL_ATTR(COMPANDER, 4)
330#define HPI_COMPANDER_ATTACK HPI_CTL_ATTR(COMPANDER, 5)
331#define HPI_COMPANDER_DECAY HPI_CTL_ATTR(COMPANDER, 6)
332
333/* Cobranet control attributes. */
334#define HPI_COBRANET_SET HPI_CTL_ATTR(COBRANET, 1)
335#define HPI_COBRANET_GET HPI_CTL_ATTR(COBRANET, 2)
336#define HPI_COBRANET_SET_DATA HPI_CTL_ATTR(COBRANET, 3)
337#define HPI_COBRANET_GET_DATA HPI_CTL_ATTR(COBRANET, 4)
338#define HPI_COBRANET_GET_STATUS HPI_CTL_ATTR(COBRANET, 5)
339#define HPI_COBRANET_SEND_PACKET HPI_CTL_ATTR(COBRANET, 6)
340#define HPI_COBRANET_GET_PACKET HPI_CTL_ATTR(COBRANET, 7)
341
342/*------------------------------------------------------------ 256/*------------------------------------------------------------
343 Cobranet Chip Bridge - copied from HMI.H 257 Cobranet Chip Bridge - copied from HMI.H
344------------------------------------------------------------*/ 258------------------------------------------------------------*/
@@ -395,69 +309,22 @@ Used for HPI_ChannelModeSet/Get()
395 309
396#define HPI_ETHERNET_UDP_PORT (44600) /*!< UDP messaging port */ 310#define HPI_ETHERNET_UDP_PORT (44600) /*!< UDP messaging port */
397 311
398/** Base network time out is set to 100 milli-seconds. */ 312/** Default network timeout in milli-seconds. */
399#define HPI_ETHERNET_TIMEOUT_MS (100) 313#define HPI_ETHERNET_TIMEOUT_MS 500
400
401/** \defgroup tonedet_attr Tonedetector attributes
402\{
403Used by HPI_ToneDetector_Set() and HPI_ToneDetector_Get()
404*/
405
406/** Set the threshold level of a tonedetector,
407Threshold is a -ve number in units of dB/100,
408*/
409#define HPI_TONEDETECTOR_THRESHOLD HPI_CTL_ATTR(TONEDETECTOR, 1)
410
411/** Get the current state of tonedetection
412The result is a bitmap of detected tones. pairs of bits represent the left
413and right channels, with left channel in LSB.
414The lowest frequency detector state is in the LSB
415*/
416#define HPI_TONEDETECTOR_STATE HPI_CTL_ATTR(TONEDETECTOR, 2)
417
418/** Get the frequency of a tonedetector band.
419*/
420#define HPI_TONEDETECTOR_FREQUENCY HPI_CTL_ATTR(TONEDETECTOR, 3)
421
422/**\}*/
423 314
424/** \defgroup silencedet_attr SilenceDetector attributes 315/** Locked memory buffer alloc/free phases */
425\{ 316enum HPI_BUFFER_CMDS {
426*/ 317 /** use one message to allocate or free physical memory */
427 318 HPI_BUFFER_CMD_EXTERNAL = 0,
428/** Get the current state of tonedetection 319 /** alloc physical memory */
429The result is a bitmap with 1s for silent channels. Left channel is in LSB 320 HPI_BUFFER_CMD_INTERNAL_ALLOC = 1,
430*/ 321 /** send physical memory address to adapter */
431#define HPI_SILENCEDETECTOR_STATE \ 322 HPI_BUFFER_CMD_INTERNAL_GRANTADAPTER = 2,
432 HPI_CTL_ATTR(SILENCEDETECTOR, 2) 323 /** notify adapter to stop using physical buffer */
433 324 HPI_BUFFER_CMD_INTERNAL_REVOKEADAPTER = 3,
434/** Set the threshold level of a SilenceDetector, 325 /** free physical buffer */
435Threshold is a -ve number in units of dB/100, 326 HPI_BUFFER_CMD_INTERNAL_FREE = 4
436*/ 327};
437#define HPI_SILENCEDETECTOR_THRESHOLD \
438 HPI_CTL_ATTR(SILENCEDETECTOR, 1)
439
440/** get/set the silence time before the detector triggers
441*/
442#define HPI_SILENCEDETECTOR_DELAY \
443 HPI_CTL_ATTR(SILENCEDETECTOR, 3)
444
445/**\}*/
446
447/* Locked memory buffer alloc/free phases */
448/** use one message to allocate or free physical memory */
449#define HPI_BUFFER_CMD_EXTERNAL 0
450/** alloc physical memory */
451#define HPI_BUFFER_CMD_INTERNAL_ALLOC 1
452/** send physical memory address to adapter */
453#define HPI_BUFFER_CMD_INTERNAL_GRANTADAPTER 2
454/** notify adapter to stop using physical buffer */
455#define HPI_BUFFER_CMD_INTERNAL_REVOKEADAPTER 3
456/** free physical buffer */
457#define HPI_BUFFER_CMD_INTERNAL_FREE 4
458
459/******************************************* CONTROLX ATTRIBUTES ****/
460/* NOTE: All controlx attributes must be unique, unlike control attributes */
461 328
462/*****************************************************************************/ 329/*****************************************************************************/
463/*****************************************************************************/ 330/*****************************************************************************/
@@ -482,6 +349,12 @@ Threshold is a -ve number in units of dB/100,
482#define HPI_USB_W2K_TAG 0x57495341 /* "ASIW" */ 349#define HPI_USB_W2K_TAG 0x57495341 /* "ASIW" */
483#define HPI_USB_LINUX_TAG 0x4C495341 /* "ASIL" */ 350#define HPI_USB_LINUX_TAG 0x4C495341 /* "ASIL" */
484 351
352/** Invalid Adapter index
353Used in HPI messages that are not addressed to a specific adapter
354Used in DLL to indicate device not present
355*/
356#define HPI_ADAPTER_INDEX_INVALID 0xFFFF
357
485/** First 2 hex digits define the adapter family */ 358/** First 2 hex digits define the adapter family */
486#define HPI_ADAPTER_FAMILY_MASK 0xff00 359#define HPI_ADAPTER_FAMILY_MASK 0xff00
487#define HPI_MODULE_FAMILY_MASK 0xfff0 360#define HPI_MODULE_FAMILY_MASK 0xfff0
@@ -490,178 +363,185 @@ Threshold is a -ve number in units of dB/100,
490#define HPI_MODULE_FAMILY_ASI(f) (f & HPI_MODULE_FAMILY_MASK) 363#define HPI_MODULE_FAMILY_ASI(f) (f & HPI_MODULE_FAMILY_MASK)
491#define HPI_ADAPTER_ASI(f) (f) 364#define HPI_ADAPTER_ASI(f) (f)
492 365
493/******************************************* message types */ 366enum HPI_MESSAGE_TYPES {
494#define HPI_TYPE_MESSAGE 1 367 HPI_TYPE_MESSAGE = 1,
495#define HPI_TYPE_RESPONSE 2 368 HPI_TYPE_RESPONSE = 2,
496#define HPI_TYPE_DATA 3 369 HPI_TYPE_DATA = 3,
497#define HPI_TYPE_SSX2BYPASS_MESSAGE 4 370 HPI_TYPE_SSX2BYPASS_MESSAGE = 4
498 371};
499/******************************************* object types */ 372
500#define HPI_OBJ_SUBSYSTEM 1 373enum HPI_OBJECT_TYPES {
501#define HPI_OBJ_ADAPTER 2 374 HPI_OBJ_SUBSYSTEM = 1,
502#define HPI_OBJ_OSTREAM 3 375 HPI_OBJ_ADAPTER = 2,
503#define HPI_OBJ_ISTREAM 4 376 HPI_OBJ_OSTREAM = 3,
504#define HPI_OBJ_MIXER 5 377 HPI_OBJ_ISTREAM = 4,
505#define HPI_OBJ_NODE 6 378 HPI_OBJ_MIXER = 5,
506#define HPI_OBJ_CONTROL 7 379 HPI_OBJ_NODE = 6,
507#define HPI_OBJ_NVMEMORY 8 380 HPI_OBJ_CONTROL = 7,
508#define HPI_OBJ_GPIO 9 381 HPI_OBJ_NVMEMORY = 8,
509#define HPI_OBJ_WATCHDOG 10 382 HPI_OBJ_GPIO = 9,
510#define HPI_OBJ_CLOCK 11 383 HPI_OBJ_WATCHDOG = 10,
511#define HPI_OBJ_PROFILE 12 384 HPI_OBJ_CLOCK = 11,
512#define HPI_OBJ_CONTROLEX 13 385 HPI_OBJ_PROFILE = 12,
513#define HPI_OBJ_ASYNCEVENT 14 386 HPI_OBJ_CONTROLEX = 13,
514 387 HPI_OBJ_ASYNCEVENT = 14
515#define HPI_OBJ_MAXINDEX 14 388#define HPI_OBJ_MAXINDEX 14
516 389};
517/******************************************* methods/functions */ 390
518 391#define HPI_OBJ_FUNCTION_SPACING 0x100
519#define HPI_OBJ_FUNCTION_SPACING 0x100 392#define HPI_FUNC_ID(obj, i) (HPI_OBJ_##obj * HPI_OBJ_FUNCTION_SPACING + i)
520#define HPI_MAKE_INDEX(obj, index) (obj * HPI_OBJ_FUNCTION_SPACING + index) 393
521#define HPI_EXTRACT_INDEX(fn) (fn & 0xff) 394#define HPI_EXTRACT_INDEX(fn) (fn & 0xff)
522 395
523/* SUB-SYSTEM */ 396enum HPI_FUNCTION_IDS {
524#define HPI_SUBSYS_OPEN HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 1) 397 HPI_SUBSYS_OPEN = HPI_FUNC_ID(SUBSYSTEM, 1),
525#define HPI_SUBSYS_GET_VERSION HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 2) 398 HPI_SUBSYS_GET_VERSION = HPI_FUNC_ID(SUBSYSTEM, 2),
526#define HPI_SUBSYS_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 3) 399 HPI_SUBSYS_GET_INFO = HPI_FUNC_ID(SUBSYSTEM, 3),
527#define HPI_SUBSYS_FIND_ADAPTERS HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 4) 400 HPI_SUBSYS_FIND_ADAPTERS = HPI_FUNC_ID(SUBSYSTEM, 4),
528#define HPI_SUBSYS_CREATE_ADAPTER HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 5) 401 HPI_SUBSYS_CREATE_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 5),
529#define HPI_SUBSYS_CLOSE HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 6) 402 HPI_SUBSYS_CLOSE = HPI_FUNC_ID(SUBSYSTEM, 6),
530#define HPI_SUBSYS_DELETE_ADAPTER HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 7) 403 HPI_SUBSYS_DELETE_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 7),
531#define HPI_SUBSYS_DRIVER_LOAD HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 8) 404 HPI_SUBSYS_DRIVER_LOAD = HPI_FUNC_ID(SUBSYSTEM, 8),
532#define HPI_SUBSYS_DRIVER_UNLOAD HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 9) 405 HPI_SUBSYS_DRIVER_UNLOAD = HPI_FUNC_ID(SUBSYSTEM, 9),
533#define HPI_SUBSYS_READ_PORT_8 HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 10) 406 HPI_SUBSYS_READ_PORT_8 = HPI_FUNC_ID(SUBSYSTEM, 10),
534#define HPI_SUBSYS_WRITE_PORT_8 HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 11) 407 HPI_SUBSYS_WRITE_PORT_8 = HPI_FUNC_ID(SUBSYSTEM, 11),
535#define HPI_SUBSYS_GET_NUM_ADAPTERS HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 12) 408 HPI_SUBSYS_GET_NUM_ADAPTERS = HPI_FUNC_ID(SUBSYSTEM, 12),
536#define HPI_SUBSYS_GET_ADAPTER HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 13) 409 HPI_SUBSYS_GET_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 13),
537#define HPI_SUBSYS_SET_NETWORK_INTERFACE HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 14) 410 HPI_SUBSYS_SET_NETWORK_INTERFACE = HPI_FUNC_ID(SUBSYSTEM, 14),
538#define HPI_SUBSYS_FUNCTION_COUNT 14 411 HPI_SUBSYS_OPTION_INFO = HPI_FUNC_ID(SUBSYSTEM, 15),
539/* ADAPTER */ 412 HPI_SUBSYS_OPTION_GET = HPI_FUNC_ID(SUBSYSTEM, 16),
540#define HPI_ADAPTER_OPEN HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 1) 413 HPI_SUBSYS_OPTION_SET = HPI_FUNC_ID(SUBSYSTEM, 17),
541#define HPI_ADAPTER_CLOSE HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 2) 414#define HPI_SUBSYS_FUNCTION_COUNT 17
542#define HPI_ADAPTER_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 3) 415
543#define HPI_ADAPTER_GET_ASSERT HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 4) 416 HPI_ADAPTER_OPEN = HPI_FUNC_ID(ADAPTER, 1),
544#define HPI_ADAPTER_TEST_ASSERT HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 5) 417 HPI_ADAPTER_CLOSE = HPI_FUNC_ID(ADAPTER, 2),
545#define HPI_ADAPTER_SET_MODE HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 6) 418 HPI_ADAPTER_GET_INFO = HPI_FUNC_ID(ADAPTER, 3),
546#define HPI_ADAPTER_GET_MODE HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 7) 419 HPI_ADAPTER_GET_ASSERT = HPI_FUNC_ID(ADAPTER, 4),
547#define HPI_ADAPTER_ENABLE_CAPABILITY HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 8) 420 HPI_ADAPTER_TEST_ASSERT = HPI_FUNC_ID(ADAPTER, 5),
548#define HPI_ADAPTER_SELFTEST HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 9) 421 HPI_ADAPTER_SET_MODE = HPI_FUNC_ID(ADAPTER, 6),
549#define HPI_ADAPTER_FIND_OBJECT HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 10) 422 HPI_ADAPTER_GET_MODE = HPI_FUNC_ID(ADAPTER, 7),
550#define HPI_ADAPTER_QUERY_FLASH HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 11) 423 HPI_ADAPTER_ENABLE_CAPABILITY = HPI_FUNC_ID(ADAPTER, 8),
551#define HPI_ADAPTER_START_FLASH HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 12) 424 HPI_ADAPTER_SELFTEST = HPI_FUNC_ID(ADAPTER, 9),
552#define HPI_ADAPTER_PROGRAM_FLASH HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 13) 425 HPI_ADAPTER_FIND_OBJECT = HPI_FUNC_ID(ADAPTER, 10),
553#define HPI_ADAPTER_SET_PROPERTY HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 14) 426 HPI_ADAPTER_QUERY_FLASH = HPI_FUNC_ID(ADAPTER, 11),
554#define HPI_ADAPTER_GET_PROPERTY HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 15) 427 HPI_ADAPTER_START_FLASH = HPI_FUNC_ID(ADAPTER, 12),
555#define HPI_ADAPTER_ENUM_PROPERTY HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 16) 428 HPI_ADAPTER_PROGRAM_FLASH = HPI_FUNC_ID(ADAPTER, 13),
556#define HPI_ADAPTER_MODULE_INFO HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 17) 429 HPI_ADAPTER_SET_PROPERTY = HPI_FUNC_ID(ADAPTER, 14),
557#define HPI_ADAPTER_DEBUG_READ HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 18) 430 HPI_ADAPTER_GET_PROPERTY = HPI_FUNC_ID(ADAPTER, 15),
558#define HPI_ADAPTER_FUNCTION_COUNT 18 431 HPI_ADAPTER_ENUM_PROPERTY = HPI_FUNC_ID(ADAPTER, 16),
559/* OUTPUT STREAM */ 432 HPI_ADAPTER_MODULE_INFO = HPI_FUNC_ID(ADAPTER, 17),
560#define HPI_OSTREAM_OPEN HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 1) 433 HPI_ADAPTER_DEBUG_READ = HPI_FUNC_ID(ADAPTER, 18),
561#define HPI_OSTREAM_CLOSE HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 2) 434 HPI_ADAPTER_IRQ_QUERY_AND_CLEAR = HPI_FUNC_ID(ADAPTER, 19),
562#define HPI_OSTREAM_WRITE HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 3) 435 HPI_ADAPTER_IRQ_CALLBACK = HPI_FUNC_ID(ADAPTER, 20),
563#define HPI_OSTREAM_START HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 4) 436#define HPI_ADAPTER_FUNCTION_COUNT 20
564#define HPI_OSTREAM_STOP HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 5) 437
565#define HPI_OSTREAM_RESET HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 6) 438 HPI_OSTREAM_OPEN = HPI_FUNC_ID(OSTREAM, 1),
566#define HPI_OSTREAM_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 7) 439 HPI_OSTREAM_CLOSE = HPI_FUNC_ID(OSTREAM, 2),
567#define HPI_OSTREAM_QUERY_FORMAT HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 8) 440 HPI_OSTREAM_WRITE = HPI_FUNC_ID(OSTREAM, 3),
568#define HPI_OSTREAM_DATA HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 9) 441 HPI_OSTREAM_START = HPI_FUNC_ID(OSTREAM, 4),
569#define HPI_OSTREAM_SET_VELOCITY HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 10) 442 HPI_OSTREAM_STOP = HPI_FUNC_ID(OSTREAM, 5),
570#define HPI_OSTREAM_SET_PUNCHINOUT HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 11) 443 HPI_OSTREAM_RESET = HPI_FUNC_ID(OSTREAM, 6),
571#define HPI_OSTREAM_SINEGEN HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 12) 444 HPI_OSTREAM_GET_INFO = HPI_FUNC_ID(OSTREAM, 7),
572#define HPI_OSTREAM_ANC_RESET HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 13) 445 HPI_OSTREAM_QUERY_FORMAT = HPI_FUNC_ID(OSTREAM, 8),
573#define HPI_OSTREAM_ANC_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 14) 446 HPI_OSTREAM_DATA = HPI_FUNC_ID(OSTREAM, 9),
574#define HPI_OSTREAM_ANC_READ HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 15) 447 HPI_OSTREAM_SET_VELOCITY = HPI_FUNC_ID(OSTREAM, 10),
575#define HPI_OSTREAM_SET_TIMESCALE HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 16) 448 HPI_OSTREAM_SET_PUNCHINOUT = HPI_FUNC_ID(OSTREAM, 11),
576#define HPI_OSTREAM_SET_FORMAT HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 17) 449 HPI_OSTREAM_SINEGEN = HPI_FUNC_ID(OSTREAM, 12),
577#define HPI_OSTREAM_HOSTBUFFER_ALLOC HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 18) 450 HPI_OSTREAM_ANC_RESET = HPI_FUNC_ID(OSTREAM, 13),
578#define HPI_OSTREAM_HOSTBUFFER_FREE HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 19) 451 HPI_OSTREAM_ANC_GET_INFO = HPI_FUNC_ID(OSTREAM, 14),
579#define HPI_OSTREAM_GROUP_ADD HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 20) 452 HPI_OSTREAM_ANC_READ = HPI_FUNC_ID(OSTREAM, 15),
580#define HPI_OSTREAM_GROUP_GETMAP HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 21) 453 HPI_OSTREAM_SET_TIMESCALE = HPI_FUNC_ID(OSTREAM, 16),
581#define HPI_OSTREAM_GROUP_RESET HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 22) 454 HPI_OSTREAM_SET_FORMAT = HPI_FUNC_ID(OSTREAM, 17),
582#define HPI_OSTREAM_HOSTBUFFER_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 23) 455 HPI_OSTREAM_HOSTBUFFER_ALLOC = HPI_FUNC_ID(OSTREAM, 18),
583#define HPI_OSTREAM_WAIT_START HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 24) 456 HPI_OSTREAM_HOSTBUFFER_FREE = HPI_FUNC_ID(OSTREAM, 19),
584#define HPI_OSTREAM_FUNCTION_COUNT 24 457 HPI_OSTREAM_GROUP_ADD = HPI_FUNC_ID(OSTREAM, 20),
585/* INPUT STREAM */ 458 HPI_OSTREAM_GROUP_GETMAP = HPI_FUNC_ID(OSTREAM, 21),
586#define HPI_ISTREAM_OPEN HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 1) 459 HPI_OSTREAM_GROUP_RESET = HPI_FUNC_ID(OSTREAM, 22),
587#define HPI_ISTREAM_CLOSE HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 2) 460 HPI_OSTREAM_HOSTBUFFER_GET_INFO = HPI_FUNC_ID(OSTREAM, 23),
588#define HPI_ISTREAM_SET_FORMAT HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 3) 461 HPI_OSTREAM_WAIT_START = HPI_FUNC_ID(OSTREAM, 24),
589#define HPI_ISTREAM_READ HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 4) 462 HPI_OSTREAM_WAIT = HPI_FUNC_ID(OSTREAM, 25),
590#define HPI_ISTREAM_START HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 5) 463#define HPI_OSTREAM_FUNCTION_COUNT 25
591#define HPI_ISTREAM_STOP HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 6) 464
592#define HPI_ISTREAM_RESET HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 7) 465 HPI_ISTREAM_OPEN = HPI_FUNC_ID(ISTREAM, 1),
593#define HPI_ISTREAM_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 8) 466 HPI_ISTREAM_CLOSE = HPI_FUNC_ID(ISTREAM, 2),
594#define HPI_ISTREAM_QUERY_FORMAT HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 9) 467 HPI_ISTREAM_SET_FORMAT = HPI_FUNC_ID(ISTREAM, 3),
595#define HPI_ISTREAM_ANC_RESET HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 10) 468 HPI_ISTREAM_READ = HPI_FUNC_ID(ISTREAM, 4),
596#define HPI_ISTREAM_ANC_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 11) 469 HPI_ISTREAM_START = HPI_FUNC_ID(ISTREAM, 5),
597#define HPI_ISTREAM_ANC_WRITE HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 12) 470 HPI_ISTREAM_STOP = HPI_FUNC_ID(ISTREAM, 6),
598#define HPI_ISTREAM_HOSTBUFFER_ALLOC HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 13) 471 HPI_ISTREAM_RESET = HPI_FUNC_ID(ISTREAM, 7),
599#define HPI_ISTREAM_HOSTBUFFER_FREE HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 14) 472 HPI_ISTREAM_GET_INFO = HPI_FUNC_ID(ISTREAM, 8),
600#define HPI_ISTREAM_GROUP_ADD HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 15) 473 HPI_ISTREAM_QUERY_FORMAT = HPI_FUNC_ID(ISTREAM, 9),
601#define HPI_ISTREAM_GROUP_GETMAP HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 16) 474 HPI_ISTREAM_ANC_RESET = HPI_FUNC_ID(ISTREAM, 10),
602#define HPI_ISTREAM_GROUP_RESET HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 17) 475 HPI_ISTREAM_ANC_GET_INFO = HPI_FUNC_ID(ISTREAM, 11),
603#define HPI_ISTREAM_HOSTBUFFER_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 18) 476 HPI_ISTREAM_ANC_WRITE = HPI_FUNC_ID(ISTREAM, 12),
604#define HPI_ISTREAM_WAIT_START HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 19) 477 HPI_ISTREAM_HOSTBUFFER_ALLOC = HPI_FUNC_ID(ISTREAM, 13),
605#define HPI_ISTREAM_FUNCTION_COUNT 19 478 HPI_ISTREAM_HOSTBUFFER_FREE = HPI_FUNC_ID(ISTREAM, 14),
606/* MIXER */ 479 HPI_ISTREAM_GROUP_ADD = HPI_FUNC_ID(ISTREAM, 15),
480 HPI_ISTREAM_GROUP_GETMAP = HPI_FUNC_ID(ISTREAM, 16),
481 HPI_ISTREAM_GROUP_RESET = HPI_FUNC_ID(ISTREAM, 17),
482 HPI_ISTREAM_HOSTBUFFER_GET_INFO = HPI_FUNC_ID(ISTREAM, 18),
483 HPI_ISTREAM_WAIT_START = HPI_FUNC_ID(ISTREAM, 19),
484 HPI_ISTREAM_WAIT = HPI_FUNC_ID(ISTREAM, 20),
485#define HPI_ISTREAM_FUNCTION_COUNT 20
486
607/* NOTE: 487/* NOTE:
608 GET_NODE_INFO, SET_CONNECTION, GET_CONNECTIONS are not currently used */ 488 GET_NODE_INFO, SET_CONNECTION, GET_CONNECTIONS are not currently used */
609#define HPI_MIXER_OPEN HPI_MAKE_INDEX(HPI_OBJ_MIXER, 1) 489 HPI_MIXER_OPEN = HPI_FUNC_ID(MIXER, 1),
610#define HPI_MIXER_CLOSE HPI_MAKE_INDEX(HPI_OBJ_MIXER, 2) 490 HPI_MIXER_CLOSE = HPI_FUNC_ID(MIXER, 2),
611#define HPI_MIXER_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_MIXER, 3) 491 HPI_MIXER_GET_INFO = HPI_FUNC_ID(MIXER, 3),
612#define HPI_MIXER_GET_NODE_INFO HPI_MAKE_INDEX(HPI_OBJ_MIXER, 4) 492 HPI_MIXER_GET_NODE_INFO = HPI_FUNC_ID(MIXER, 4),
613#define HPI_MIXER_GET_CONTROL HPI_MAKE_INDEX(HPI_OBJ_MIXER, 5) 493 HPI_MIXER_GET_CONTROL = HPI_FUNC_ID(MIXER, 5),
614#define HPI_MIXER_SET_CONNECTION HPI_MAKE_INDEX(HPI_OBJ_MIXER, 6) 494 HPI_MIXER_SET_CONNECTION = HPI_FUNC_ID(MIXER, 6),
615#define HPI_MIXER_GET_CONNECTIONS HPI_MAKE_INDEX(HPI_OBJ_MIXER, 7) 495 HPI_MIXER_GET_CONNECTIONS = HPI_FUNC_ID(MIXER, 7),
616#define HPI_MIXER_GET_CONTROL_BY_INDEX HPI_MAKE_INDEX(HPI_OBJ_MIXER, 8) 496 HPI_MIXER_GET_CONTROL_BY_INDEX = HPI_FUNC_ID(MIXER, 8),
617#define HPI_MIXER_GET_CONTROL_ARRAY_BY_INDEX HPI_MAKE_INDEX(HPI_OBJ_MIXER, 9) 497 HPI_MIXER_GET_CONTROL_ARRAY_BY_INDEX = HPI_FUNC_ID(MIXER, 9),
618#define HPI_MIXER_GET_CONTROL_MULTIPLE_VALUES HPI_MAKE_INDEX(HPI_OBJ_MIXER, 10) 498 HPI_MIXER_GET_CONTROL_MULTIPLE_VALUES = HPI_FUNC_ID(MIXER, 10),
619#define HPI_MIXER_STORE HPI_MAKE_INDEX(HPI_OBJ_MIXER, 11) 499 HPI_MIXER_STORE = HPI_FUNC_ID(MIXER, 11),
620#define HPI_MIXER_FUNCTION_COUNT 11 500 HPI_MIXER_GET_CACHE_INFO = HPI_FUNC_ID(MIXER, 12),
621/* MIXER CONTROLS */ 501#define HPI_MIXER_FUNCTION_COUNT 12
622#define HPI_CONTROL_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_CONTROL, 1) 502
623#define HPI_CONTROL_GET_STATE HPI_MAKE_INDEX(HPI_OBJ_CONTROL, 2) 503 HPI_CONTROL_GET_INFO = HPI_FUNC_ID(CONTROL, 1),
624#define HPI_CONTROL_SET_STATE HPI_MAKE_INDEX(HPI_OBJ_CONTROL, 3) 504 HPI_CONTROL_GET_STATE = HPI_FUNC_ID(CONTROL, 2),
505 HPI_CONTROL_SET_STATE = HPI_FUNC_ID(CONTROL, 3),
625#define HPI_CONTROL_FUNCTION_COUNT 3 506#define HPI_CONTROL_FUNCTION_COUNT 3
626/* NONVOL MEMORY */ 507
627#define HPI_NVMEMORY_OPEN HPI_MAKE_INDEX(HPI_OBJ_NVMEMORY, 1) 508 HPI_NVMEMORY_OPEN = HPI_FUNC_ID(NVMEMORY, 1),
628#define HPI_NVMEMORY_READ_BYTE HPI_MAKE_INDEX(HPI_OBJ_NVMEMORY, 2) 509 HPI_NVMEMORY_READ_BYTE = HPI_FUNC_ID(NVMEMORY, 2),
629#define HPI_NVMEMORY_WRITE_BYTE HPI_MAKE_INDEX(HPI_OBJ_NVMEMORY, 3) 510 HPI_NVMEMORY_WRITE_BYTE = HPI_FUNC_ID(NVMEMORY, 3),
630#define HPI_NVMEMORY_FUNCTION_COUNT 3 511#define HPI_NVMEMORY_FUNCTION_COUNT 3
631/* GPIO */ 512
632#define HPI_GPIO_OPEN HPI_MAKE_INDEX(HPI_OBJ_GPIO, 1) 513 HPI_GPIO_OPEN = HPI_FUNC_ID(GPIO, 1),
633#define HPI_GPIO_READ_BIT HPI_MAKE_INDEX(HPI_OBJ_GPIO, 2) 514 HPI_GPIO_READ_BIT = HPI_FUNC_ID(GPIO, 2),
634#define HPI_GPIO_WRITE_BIT HPI_MAKE_INDEX(HPI_OBJ_GPIO, 3) 515 HPI_GPIO_WRITE_BIT = HPI_FUNC_ID(GPIO, 3),
635#define HPI_GPIO_READ_ALL HPI_MAKE_INDEX(HPI_OBJ_GPIO, 4) 516 HPI_GPIO_READ_ALL = HPI_FUNC_ID(GPIO, 4),
636#define HPI_GPIO_WRITE_STATUS HPI_MAKE_INDEX(HPI_OBJ_GPIO, 5) 517 HPI_GPIO_WRITE_STATUS = HPI_FUNC_ID(GPIO, 5),
637#define HPI_GPIO_FUNCTION_COUNT 5 518#define HPI_GPIO_FUNCTION_COUNT 5
638/* ASYNC EVENT */ 519
639#define HPI_ASYNCEVENT_OPEN HPI_MAKE_INDEX(HPI_OBJ_ASYNCEVENT, 1) 520 HPI_ASYNCEVENT_OPEN = HPI_FUNC_ID(ASYNCEVENT, 1),
640#define HPI_ASYNCEVENT_CLOSE HPI_MAKE_INDEX(HPI_OBJ_ASYNCEVENT, 2) 521 HPI_ASYNCEVENT_CLOSE = HPI_FUNC_ID(ASYNCEVENT, 2),
641#define HPI_ASYNCEVENT_WAIT HPI_MAKE_INDEX(HPI_OBJ_ASYNCEVENT, 3) 522 HPI_ASYNCEVENT_WAIT = HPI_FUNC_ID(ASYNCEVENT, 3),
642#define HPI_ASYNCEVENT_GETCOUNT HPI_MAKE_INDEX(HPI_OBJ_ASYNCEVENT, 4) 523 HPI_ASYNCEVENT_GETCOUNT = HPI_FUNC_ID(ASYNCEVENT, 4),
643#define HPI_ASYNCEVENT_GET HPI_MAKE_INDEX(HPI_OBJ_ASYNCEVENT, 5) 524 HPI_ASYNCEVENT_GET = HPI_FUNC_ID(ASYNCEVENT, 5),
644#define HPI_ASYNCEVENT_SENDEVENTS HPI_MAKE_INDEX(HPI_OBJ_ASYNCEVENT, 6) 525 HPI_ASYNCEVENT_SENDEVENTS = HPI_FUNC_ID(ASYNCEVENT, 6),
645#define HPI_ASYNCEVENT_FUNCTION_COUNT 6 526#define HPI_ASYNCEVENT_FUNCTION_COUNT 6
646/* WATCH-DOG */ 527
647#define HPI_WATCHDOG_OPEN HPI_MAKE_INDEX(HPI_OBJ_WATCHDOG, 1) 528 HPI_WATCHDOG_OPEN = HPI_FUNC_ID(WATCHDOG, 1),
648#define HPI_WATCHDOG_SET_TIME HPI_MAKE_INDEX(HPI_OBJ_WATCHDOG, 2) 529 HPI_WATCHDOG_SET_TIME = HPI_FUNC_ID(WATCHDOG, 2),
649#define HPI_WATCHDOG_PING HPI_MAKE_INDEX(HPI_OBJ_WATCHDOG, 3) 530 HPI_WATCHDOG_PING = HPI_FUNC_ID(WATCHDOG, 3),
650/* CLOCK */ 531
651#define HPI_CLOCK_OPEN HPI_MAKE_INDEX(HPI_OBJ_CLOCK, 1) 532 HPI_CLOCK_OPEN = HPI_FUNC_ID(CLOCK, 1),
652#define HPI_CLOCK_SET_TIME HPI_MAKE_INDEX(HPI_OBJ_CLOCK, 2) 533 HPI_CLOCK_SET_TIME = HPI_FUNC_ID(CLOCK, 2),
653#define HPI_CLOCK_GET_TIME HPI_MAKE_INDEX(HPI_OBJ_CLOCK, 3) 534 HPI_CLOCK_GET_TIME = HPI_FUNC_ID(CLOCK, 3),
654/* PROFILE */ 535
655#define HPI_PROFILE_OPEN_ALL HPI_MAKE_INDEX(HPI_OBJ_PROFILE, 1) 536 HPI_PROFILE_OPEN_ALL = HPI_FUNC_ID(PROFILE, 1),
656#define HPI_PROFILE_START_ALL HPI_MAKE_INDEX(HPI_OBJ_PROFILE, 2) 537 HPI_PROFILE_START_ALL = HPI_FUNC_ID(PROFILE, 2),
657#define HPI_PROFILE_STOP_ALL HPI_MAKE_INDEX(HPI_OBJ_PROFILE, 3) 538 HPI_PROFILE_STOP_ALL = HPI_FUNC_ID(PROFILE, 3),
658#define HPI_PROFILE_GET HPI_MAKE_INDEX(HPI_OBJ_PROFILE, 4) 539 HPI_PROFILE_GET = HPI_FUNC_ID(PROFILE, 4),
659#define HPI_PROFILE_GET_IDLECOUNT HPI_MAKE_INDEX(HPI_OBJ_PROFILE, 5) 540 HPI_PROFILE_GET_IDLECOUNT = HPI_FUNC_ID(PROFILE, 5),
660#define HPI_PROFILE_GET_NAME HPI_MAKE_INDEX(HPI_OBJ_PROFILE, 6) 541 HPI_PROFILE_GET_NAME = HPI_FUNC_ID(PROFILE, 6),
661#define HPI_PROFILE_GET_UTILIZATION HPI_MAKE_INDEX(HPI_OBJ_PROFILE, 7) 542 HPI_PROFILE_GET_UTILIZATION = HPI_FUNC_ID(PROFILE, 7)
662#define HPI_PROFILE_FUNCTION_COUNT 7 543#define HPI_PROFILE_FUNCTION_COUNT 7
663/* ////////////////////////////////////////////////////////////////////// */ 544};
664/* PRIVATE ATTRIBUTES */
665 545
666/* ////////////////////////////////////////////////////////////////////// */ 546/* ////////////////////////////////////////////////////////////////////// */
667/* STRUCTURES */ 547/* STRUCTURES */
@@ -672,18 +552,7 @@ Threshold is a -ve number in units of dB/100,
672/** PCI bus resource */ 552/** PCI bus resource */
673struct hpi_pci { 553struct hpi_pci {
674 u32 __iomem *ap_mem_base[HPI_MAX_ADAPTER_MEM_SPACES]; 554 u32 __iomem *ap_mem_base[HPI_MAX_ADAPTER_MEM_SPACES];
675 struct pci_dev *p_os_data; 555 struct pci_dev *pci_dev;
676
677#ifndef HPI64BIT /* keep structure size constant */
678 u32 padding[HPI_MAX_ADAPTER_MEM_SPACES + 1];
679#endif
680 u16 vendor_id;
681 u16 device_id;
682 u16 subsys_vendor_id;
683 u16 subsys_device_id;
684 u16 bus_number;
685 u16 device_number;
686 u32 interrupt;
687}; 556};
688 557
689struct hpi_resource { 558struct hpi_resource {
@@ -702,12 +571,10 @@ struct hpi_resource {
702/** Format info used inside struct hpi_message 571/** Format info used inside struct hpi_message
703 Not the same as public API struct hpi_format */ 572 Not the same as public API struct hpi_format */
704struct hpi_msg_format { 573struct hpi_msg_format {
705 u32 sample_rate; 574 u32 sample_rate; /**< 11025, 32000, 44100 etc. */
706 /**< 11025, 32000, 44100 ... */ 575 u32 bit_rate; /**< for MPEG */
707 u32 bit_rate; /**< for MPEG */ 576 u32 attributes; /**< stereo/joint_stereo/mono */
708 u32 attributes; 577 u16 channels; /**< 1,2..., (or ancillary mode or idle bit */
709 /**< Stereo/JointStereo/Mono */
710 u16 channels; /**< 1,2..., (or ancillary mode or idle bit */
711 u16 format; /**< HPI_FORMAT_PCM16, _MPEG etc. see \ref HPI_FORMATS. */ 578 u16 format; /**< HPI_FORMAT_PCM16, _MPEG etc. see \ref HPI_FORMATS. */
712}; 579};
713 580
@@ -742,7 +609,7 @@ struct hpi_data_compat32 {
742struct hpi_buffer { 609struct hpi_buffer {
743 /** placehoder for backward compatability (see dwBufferSize) */ 610 /** placehoder for backward compatability (see dwBufferSize) */
744 struct hpi_msg_format reserved; 611 struct hpi_msg_format reserved;
745 u32 command; /**< HPI_BUFFER_CMD_xxx*/ 612 u32 command; /**< HPI_BUFFER_CMD_xxx*/
746 u32 pci_address; /**< PCI physical address of buffer for DSP DMA */ 613 u32 pci_address; /**< PCI physical address of buffer for DSP DMA */
747 u32 buffer_size; /**< must line up with data_size of HPI_DATA*/ 614 u32 buffer_size; /**< must line up with data_size of HPI_DATA*/
748}; 615};
@@ -777,30 +644,25 @@ struct hpi_subsys_msg {
777 644
778struct hpi_subsys_res { 645struct hpi_subsys_res {
779 u32 version; 646 u32 version;
780 u32 data; /* used to return extended version */ 647 u32 data; /* extended version */
781 u16 num_adapters; /* number of adapters */ 648 u16 num_adapters;
782 u16 adapter_index; 649 u16 adapter_index;
783 u16 aw_adapter_list[HPI_MAX_ADAPTERS]; 650 u16 adapter_type;
784}; 651 u16 pad16;
785
786struct hpi_adapter_msg {
787 u32 adapter_mode; /* adapter mode */
788 u16 assert_id; /* assert number for "test assert" call
789 object_index for find object call
790 query_or_set for hpi_adapter_set_mode_ex() */
791 u16 object_type; /* for adapter find object call */
792}; 652};
793 653
794union hpi_adapterx_msg { 654union hpi_adapterx_msg {
795 struct hpi_adapter_msg adapter;
796 struct { 655 struct {
797 u32 offset; 656 u32 dsp_address;
798 } query_flash; 657 u32 count_bytes;
658 } debug_read;
799 struct { 659 struct {
800 u32 offset; 660 u32 adapter_mode;
801 u32 length; 661 u16 query_or_set;
802 u32 key; 662 } mode;
803 } start_flash; 663 struct {
664 u16 index;
665 } module_info;
804 struct { 666 struct {
805 u32 checksum; 667 u32 checksum;
806 u16 sequence; 668 u16 sequence;
@@ -809,28 +671,41 @@ union hpi_adapterx_msg {
809 u16 unused; 671 u16 unused;
810 } program_flash; 672 } program_flash;
811 struct { 673 struct {
674 u16 index;
675 u16 what;
676 u16 property_index;
677 } property_enum;
678 struct {
812 u16 property; 679 u16 property;
813 u16 parameter1; 680 u16 parameter1;
814 u16 parameter2; 681 u16 parameter2;
815 } property_set; 682 } property_set;
816 struct { 683 struct {
817 u16 index; 684 u32 offset;
818 u16 what; 685 } query_flash;
819 u16 property_index;
820 } property_enum;
821 struct { 686 struct {
822 u16 index; 687 u32 pad32;
823 } module_info; 688 u16 key1;
689 u16 key2;
690 } restart;
824 struct { 691 struct {
825 u32 dsp_address; 692 u32 offset;
826 u32 count_bytes; 693 u32 length;
827 } debug_read; 694 u32 key;
695 } start_flash;
696 struct {
697 u32 pad32;
698 u16 value;
699 } test_assert;
700 struct {
701 u32 yes;
702 } irq_query;
828}; 703};
829 704
830struct hpi_adapter_res { 705struct hpi_adapter_res {
831 u32 serial_number; 706 u32 serial_number;
832 u16 adapter_type; 707 u16 adapter_type;
833 u16 adapter_index; /* is this needed? also used for dsp_index */ 708 u16 adapter_index;
834 u16 num_instreams; 709 u16 num_instreams;
835 u16 num_outstreams; 710 u16 num_outstreams;
836 u16 num_mixers; 711 u16 num_mixers;
@@ -839,12 +714,18 @@ struct hpi_adapter_res {
839}; 714};
840 715
841union hpi_adapterx_res { 716union hpi_adapterx_res {
842 struct hpi_adapter_res adapter; 717 struct hpi_adapter_res info;
843 struct { 718 struct {
844 u32 checksum; 719 u32 p1;
845 u32 length; 720 u16 count;
846 u32 version; 721 u16 dsp_index;
847 } query_flash; 722 u32 p2;
723 u32 dsp_msg_addr;
724 char sz_message[HPI_STRING_LEN];
725 } assert;
726 struct {
727 u32 adapter_mode;
728 } mode;
848 struct { 729 struct {
849 u16 sequence; 730 u16 sequence;
850 } program_flash; 731 } program_flash;
@@ -852,6 +733,14 @@ union hpi_adapterx_res {
852 u16 parameter1; 733 u16 parameter1;
853 u16 parameter2; 734 u16 parameter2;
854 } property_get; 735 } property_get;
736 struct {
737 u32 checksum;
738 u32 length;
739 u32 version;
740 } query_flash;
741 struct {
742 u32 yes;
743 } irq_query;
855}; 744};
856 745
857struct hpi_stream_msg { 746struct hpi_stream_msg {
@@ -863,6 +752,7 @@ struct hpi_stream_msg {
863 u32 time_scale; 752 u32 time_scale;
864 struct hpi_buffer buffer; 753 struct hpi_buffer buffer;
865 struct hpi_streamid stream; 754 struct hpi_streamid stream;
755 u32 threshold_bytes;
866 } u; 756 } u;
867}; 757};
868 758
@@ -911,7 +801,7 @@ struct hpi_stream_res {
911struct hpi_mixer_msg { 801struct hpi_mixer_msg {
912 u16 control_index; 802 u16 control_index;
913 u16 control_type; /* = HPI_CONTROL_METER _VOLUME etc */ 803 u16 control_type; /* = HPI_CONTROL_METER _VOLUME etc */
914 u16 padding1; /* maintain alignment of subsequent fields */ 804 u16 padding1; /* Maintain alignment of subsequent fields */
915 u16 node_type1; /* = HPI_SOURCENODE_LINEIN etc */ 805 u16 node_type1; /* = HPI_SOURCENODE_LINEIN etc */
916 u16 node_index1; /* = 0..N */ 806 u16 node_index1; /* = 0..N */
917 u16 node_type2; 807 u16 node_type2;
@@ -949,6 +839,11 @@ union hpi_mixerx_res {
949 u32 p_data; /* pointer to data array */ 839 u32 p_data; /* pointer to data array */
950 u16 more_to_do; /* indicates if there is more to do */ 840 u16 more_to_do; /* indicates if there is more to do */
951 } gcabi; 841 } gcabi;
842 struct {
843 u32 total_controls; /* count of controls in the mixer */
844 u32 cache_controls; /* count of controls in the cac */
845 u32 cache_bytes; /* size of cache */
846 } cache_info;
952}; 847};
953 848
954struct hpi_control_msg { 849struct hpi_control_msg {
@@ -1000,12 +895,16 @@ union hpi_control_union_res {
1000 u32 band; 895 u32 band;
1001 u32 frequency; 896 u32 frequency;
1002 u32 gain; 897 u32 gain;
1003 u32 level;
1004 u32 deemphasis; 898 u32 deemphasis;
1005 struct { 899 struct {
1006 u32 data[2]; 900 u32 data[2];
1007 u32 bLER; 901 u32 bLER;
1008 } rds; 902 } rds;
903 short s_level;
904 struct {
905 u16 value;
906 u16 mask;
907 } status;
1009 } tuner; 908 } tuner;
1010 struct { 909 struct {
1011 char sz_data[8]; 910 char sz_data[8];
@@ -1178,11 +1077,11 @@ struct hpi_profile_res_open {
1178}; 1077};
1179 1078
1180struct hpi_profile_res_time { 1079struct hpi_profile_res_time {
1181 u32 micro_seconds; 1080 u32 total_tick_count;
1182 u32 call_count; 1081 u32 call_count;
1183 u32 max_micro_seconds; 1082 u32 max_tick_count;
1184 u32 min_micro_seconds; 1083 u32 ticks_per_millisecond;
1185 u16 seconds; 1084 u16 profile_interval;
1186}; 1085};
1187 1086
1188struct hpi_profile_res_name { 1087struct hpi_profile_res_name {
@@ -1218,7 +1117,6 @@ struct hpi_message {
1218 u16 obj_index; /* */ 1117 u16 obj_index; /* */
1219 union { 1118 union {
1220 struct hpi_subsys_msg s; 1119 struct hpi_subsys_msg s;
1221 struct hpi_adapter_msg a;
1222 union hpi_adapterx_msg ax; 1120 union hpi_adapterx_msg ax;
1223 struct hpi_stream_msg d; 1121 struct hpi_stream_msg d;
1224 struct hpi_mixer_msg m; 1122 struct hpi_mixer_msg m;
@@ -1239,7 +1137,7 @@ struct hpi_message {
1239}; 1137};
1240 1138
1241#define HPI_MESSAGE_SIZE_BY_OBJECT { \ 1139#define HPI_MESSAGE_SIZE_BY_OBJECT { \
1242 sizeof(struct hpi_message_header) , /* default, no object type 0 */ \ 1140 sizeof(struct hpi_message_header) , /* Default, no object type 0 */ \
1243 sizeof(struct hpi_message_header) + sizeof(struct hpi_subsys_msg),\ 1141 sizeof(struct hpi_message_header) + sizeof(struct hpi_subsys_msg),\
1244 sizeof(struct hpi_message_header) + sizeof(union hpi_adapterx_msg),\ 1142 sizeof(struct hpi_message_header) + sizeof(union hpi_adapterx_msg),\
1245 sizeof(struct hpi_message_header) + sizeof(struct hpi_stream_msg),\ 1143 sizeof(struct hpi_message_header) + sizeof(struct hpi_stream_msg),\
@@ -1256,6 +1154,11 @@ struct hpi_message {
1256 sizeof(struct hpi_message_header) + sizeof(struct hpi_async_msg) \ 1154 sizeof(struct hpi_message_header) + sizeof(struct hpi_async_msg) \
1257} 1155}
1258 1156
1157/*
1158Note that the wSpecificError error field should be inspected and potentially
1159reported whenever HPI_ERROR_DSP_COMMUNICATION or HPI_ERROR_DSP_BOOTLOAD is
1160returned in wError.
1161*/
1259struct hpi_response_header { 1162struct hpi_response_header {
1260 u16 size; 1163 u16 size;
1261 u8 type; /* HPI_TYPE_RESPONSE */ 1164 u8 type; /* HPI_TYPE_RESPONSE */
@@ -1277,7 +1180,6 @@ struct hpi_response {
1277 u16 specific_error; /* adapter specific error */ 1180 u16 specific_error; /* adapter specific error */
1278 union { 1181 union {
1279 struct hpi_subsys_res s; 1182 struct hpi_subsys_res s;
1280 struct hpi_adapter_res a;
1281 union hpi_adapterx_res ax; 1183 union hpi_adapterx_res ax;
1282 struct hpi_stream_res d; 1184 struct hpi_stream_res d;
1283 struct hpi_mixer_res m; 1185 struct hpi_mixer_res m;
@@ -1297,7 +1199,7 @@ struct hpi_response {
1297}; 1199};
1298 1200
1299#define HPI_RESPONSE_SIZE_BY_OBJECT { \ 1201#define HPI_RESPONSE_SIZE_BY_OBJECT { \
1300 sizeof(struct hpi_response_header) ,/* default, no object type 0 */ \ 1202 sizeof(struct hpi_response_header) ,/* Default, no object type 0 */ \
1301 sizeof(struct hpi_response_header) + sizeof(struct hpi_subsys_res),\ 1203 sizeof(struct hpi_response_header) + sizeof(struct hpi_subsys_res),\
1302 sizeof(struct hpi_response_header) + sizeof(union hpi_adapterx_res),\ 1204 sizeof(struct hpi_response_header) + sizeof(union hpi_adapterx_res),\
1303 sizeof(struct hpi_response_header) + sizeof(struct hpi_stream_res),\ 1205 sizeof(struct hpi_response_header) + sizeof(struct hpi_stream_res),\
@@ -1314,7 +1216,7 @@ struct hpi_response {
1314 sizeof(struct hpi_response_header) + sizeof(struct hpi_async_res) \ 1216 sizeof(struct hpi_response_header) + sizeof(struct hpi_async_res) \
1315} 1217}
1316 1218
1317/*********************** version 1 message/response *****************************/ 1219/*********************** version 1 message/response **************************/
1318#define HPINET_ETHERNET_DATA_SIZE (1500) 1220#define HPINET_ETHERNET_DATA_SIZE (1500)
1319#define HPINET_IP_HDR_SIZE (20) 1221#define HPINET_IP_HDR_SIZE (20)
1320#define HPINET_IP_DATA_SIZE (HPINET_ETHERNET_DATA_SIZE - HPINET_IP_HDR_SIZE) 1222#define HPINET_IP_DATA_SIZE (HPINET_ETHERNET_DATA_SIZE - HPINET_IP_HDR_SIZE)
@@ -1394,6 +1296,17 @@ struct hpi_res_adapter_program_flash {
1394 sizeof(struct hpi_response_header) - sizeof(u16)]; 1296 sizeof(struct hpi_response_header) - sizeof(u16)];
1395}; 1297};
1396 1298
1299struct hpi_msg_adapter_debug_read {
1300 struct hpi_message_header h;
1301 u32 dsp_address;
1302 u32 count_bytes;
1303};
1304
1305struct hpi_res_adapter_debug_read {
1306 struct hpi_response_header h;
1307 u8 bytes[256];
1308};
1309
1397#if 1 1310#if 1
1398#define hpi_message_header_v1 hpi_message_header 1311#define hpi_message_header_v1 hpi_message_header
1399#define hpi_response_header_v1 hpi_response_header 1312#define hpi_response_header_v1 hpi_response_header
@@ -1414,23 +1327,10 @@ struct hpi_response_header_v1 {
1414}; 1327};
1415#endif 1328#endif
1416 1329
1417/* STRV HPI Packet */
1418struct hpi_msg_strv {
1419 struct hpi_message_header h;
1420 struct hpi_entity strv;
1421};
1422
1423struct hpi_res_strv {
1424 struct hpi_response_header h;
1425 struct hpi_entity strv;
1426};
1427#define MIN_STRV_PACKET_SIZE sizeof(struct hpi_res_strv)
1428
1429struct hpi_msg_payload_v0 { 1330struct hpi_msg_payload_v0 {
1430 struct hpi_message_header h; 1331 struct hpi_message_header h;
1431 union { 1332 union {
1432 struct hpi_subsys_msg s; 1333 struct hpi_subsys_msg s;
1433 struct hpi_adapter_msg a;
1434 union hpi_adapterx_msg ax; 1334 union hpi_adapterx_msg ax;
1435 struct hpi_stream_msg d; 1335 struct hpi_stream_msg d;
1436 struct hpi_mixer_msg m; 1336 struct hpi_mixer_msg m;
@@ -1451,7 +1351,6 @@ struct hpi_res_payload_v0 {
1451 struct hpi_response_header h; 1351 struct hpi_response_header h;
1452 union { 1352 union {
1453 struct hpi_subsys_res s; 1353 struct hpi_subsys_res s;
1454 struct hpi_adapter_res a;
1455 union hpi_adapterx_res ax; 1354 union hpi_adapterx_res ax;
1456 struct hpi_stream_res d; 1355 struct hpi_stream_res d;
1457 struct hpi_mixer_res m; 1356 struct hpi_mixer_res m;
@@ -1471,13 +1370,13 @@ struct hpi_res_payload_v0 {
1471union hpi_message_buffer_v1 { 1370union hpi_message_buffer_v1 {
1472 struct hpi_message m0; /* version 0 */ 1371 struct hpi_message m0; /* version 0 */
1473 struct hpi_message_header_v1 h; 1372 struct hpi_message_header_v1 h;
1474 unsigned char buf[HPI_MAX_PAYLOAD_SIZE]; 1373 u8 buf[HPI_MAX_PAYLOAD_SIZE];
1475}; 1374};
1476 1375
1477union hpi_response_buffer_v1 { 1376union hpi_response_buffer_v1 {
1478 struct hpi_response r0; /* version 0 */ 1377 struct hpi_response r0; /* version 0 */
1479 struct hpi_response_header_v1 h; 1378 struct hpi_response_header_v1 h;
1480 unsigned char buf[HPI_MAX_PAYLOAD_SIZE]; 1379 u8 buf[HPI_MAX_PAYLOAD_SIZE];
1481}; 1380};
1482 1381
1483compile_time_assert((sizeof(union hpi_message_buffer_v1) <= 1382compile_time_assert((sizeof(union hpi_message_buffer_v1) <=
@@ -1499,6 +1398,11 @@ struct hpi_control_defn {
1499/*////////////////////////////////////////////////////////////////////////// */ 1398/*////////////////////////////////////////////////////////////////////////// */
1500/* declarations for control caching (internal to HPI<->DSP interaction) */ 1399/* declarations for control caching (internal to HPI<->DSP interaction) */
1501 1400
1401/** indicates a cached u16 value is invalid. */
1402#define HPI_CACHE_INVALID_UINT16 0xFFFF
1403/** indicates a cached short value is invalid. */
1404#define HPI_CACHE_INVALID_SHORT -32768
1405
1502/** A compact representation of (part of) a controls state. 1406/** A compact representation of (part of) a controls state.
1503Used for efficient transfer of the control state 1407Used for efficient transfer of the control state
1504between DSP and host or across a network 1408between DSP and host or across a network
@@ -1512,58 +1416,104 @@ struct hpi_control_cache_info {
1512 u16 control_index; 1416 u16 control_index;
1513}; 1417};
1514 1418
1515struct hpi_control_cache_single { 1419struct hpi_control_cache_vol {
1420 struct hpi_control_cache_info i;
1421 short an_log[2];
1422 unsigned short flags;
1423 char padding[2];
1424};
1425
1426struct hpi_control_cache_meter {
1427 struct hpi_control_cache_info i;
1428 short an_log_peak[2];
1429 short an_logRMS[2];
1430};
1431
1432struct hpi_control_cache_channelmode {
1433 struct hpi_control_cache_info i;
1434 u16 mode;
1435 char temp_padding[6];
1436};
1437
1438struct hpi_control_cache_mux {
1439 struct hpi_control_cache_info i;
1440 u16 source_node_type;
1441 u16 source_node_index;
1442 char temp_padding[4];
1443};
1444
1445struct hpi_control_cache_level {
1516 struct hpi_control_cache_info i; 1446 struct hpi_control_cache_info i;
1447 short an_log[2];
1448 char temp_padding[4];
1449};
1450
1451struct hpi_control_cache_tuner {
1452 struct hpi_control_cache_info i;
1453 u32 freq_ink_hz;
1454 u16 band;
1455 short s_level_avg;
1456};
1457
1458struct hpi_control_cache_aes3rx {
1459 struct hpi_control_cache_info i;
1460 u32 error_status;
1461 u32 format;
1462};
1463
1464struct hpi_control_cache_aes3tx {
1465 struct hpi_control_cache_info i;
1466 u32 format;
1467 char temp_padding[4];
1468};
1469
1470struct hpi_control_cache_tonedetector {
1471 struct hpi_control_cache_info i;
1472 u16 state;
1473 char temp_padding[6];
1474};
1475
1476struct hpi_control_cache_silencedetector {
1477 struct hpi_control_cache_info i;
1478 u32 state;
1479 char temp_padding[4];
1480};
1481
1482struct hpi_control_cache_sampleclock {
1483 struct hpi_control_cache_info i;
1484 u16 source;
1485 u16 source_index;
1486 u32 sample_rate;
1487};
1488
1489struct hpi_control_cache_microphone {
1490 struct hpi_control_cache_info i;
1491 u16 phantom_state;
1492 char temp_padding[6];
1493};
1494
1495struct hpi_control_cache_generic {
1496 struct hpi_control_cache_info i;
1497 u32 dw1;
1498 u32 dw2;
1499};
1500
1501struct hpi_control_cache_single {
1517 union { 1502 union {
1518 struct { /* volume */ 1503 struct hpi_control_cache_info i;
1519 short an_log[2]; 1504 struct hpi_control_cache_vol vol;
1520 } v; 1505 struct hpi_control_cache_meter meter;
1521 struct { /* peak meter */ 1506 struct hpi_control_cache_channelmode mode;
1522 short an_log_peak[2]; 1507 struct hpi_control_cache_mux mux;
1523 short an_logRMS[2]; 1508 struct hpi_control_cache_level level;
1524 } p; 1509 struct hpi_control_cache_tuner tuner;
1525 struct { /* channel mode */ 1510 struct hpi_control_cache_aes3rx aes3rx;
1526 u16 mode; 1511 struct hpi_control_cache_aes3tx aes3tx;
1527 } m; 1512 struct hpi_control_cache_tonedetector tone;
1528 struct { /* multiplexer */ 1513 struct hpi_control_cache_silencedetector silence;
1529 u16 source_node_type; 1514 struct hpi_control_cache_sampleclock clk;
1530 u16 source_node_index; 1515 struct hpi_control_cache_microphone microphone;
1531 } x; 1516 struct hpi_control_cache_generic generic;
1532 struct { /* level/trim */
1533 short an_log[2];
1534 } l;
1535 struct { /* tuner - partial caching.
1536 some attributes go to the DSP. */
1537 u32 freq_ink_hz;
1538 u16 band;
1539 u16 level;
1540 } t;
1541 struct { /* AESEBU rx status */
1542 u32 error_status;
1543 u32 source;
1544 } aes3rx;
1545 struct { /* AESEBU tx */
1546 u32 format;
1547 } aes3tx;
1548 struct { /* tone detector */
1549 u16 state;
1550 } tone;
1551 struct { /* silence detector */
1552 u32 state;
1553 u32 count;
1554 } silence;
1555 struct { /* sample clock */
1556 u16 source;
1557 u16 source_index;
1558 u32 sample_rate;
1559 } clk;
1560 struct { /* microphone control */
1561 u16 state;
1562 } phantom_power;
1563 struct { /* generic control */
1564 u32 dw1;
1565 u32 dw2;
1566 } g;
1567 } u; 1517 } u;
1568}; 1518};
1569 1519
@@ -1580,8 +1530,7 @@ struct hpi_control_cache_pad {
1580 u32 traffic_anouncement; 1530 u32 traffic_anouncement;
1581}; 1531};
1582 1532
1583/*/////////////////////////////////////////////////////////////////////////// */ 1533/* 2^N sized FIFO buffer (internal to HPI<->DSP interaction) */
1584/* declarations for 2^N sized FIFO buffer (internal to HPI<->DSP interaction) */
1585struct hpi_fifo_buffer { 1534struct hpi_fifo_buffer {
1586 u32 size; 1535 u32 size;
1587 u32 dSP_index; 1536 u32 dSP_index;
@@ -1606,25 +1555,18 @@ u32 hpi_indexes_to_handle(const char c_object, const u16 adapter_index,
1606/*////////////////////////////////////////////////////////////////////////// */ 1555/*////////////////////////////////////////////////////////////////////////// */
1607 1556
1608/* main HPI entry point */ 1557/* main HPI entry point */
1609hpi_handler_func hpi_send_recv; 1558void hpi_send_recv(struct hpi_message *phm, struct hpi_response *phr);
1610
1611/* UDP message */
1612void hpi_send_recvUDP(struct hpi_message *phm, struct hpi_response *phr,
1613 const unsigned int timeout);
1614 1559
1615/* used in PnP OS/driver */ 1560/* used in PnP OS/driver */
1616u16 hpi_subsys_create_adapter(const struct hpi_hsubsys *ph_subsys, 1561u16 hpi_subsys_create_adapter(const struct hpi_resource *p_resource,
1617 const struct hpi_resource *p_resource, u16 *pw_adapter_index); 1562 u16 *pw_adapter_index);
1618 1563
1619u16 hpi_subsys_delete_adapter(const struct hpi_hsubsys *ph_subsys, 1564u16 hpi_subsys_delete_adapter(u16 adapter_index);
1620 u16 adapter_index);
1621 1565
1622u16 hpi_outstream_host_buffer_get_info(const struct hpi_hsubsys *ph_subsys, 1566u16 hpi_outstream_host_buffer_get_info(u32 h_outstream, u8 **pp_buffer,
1623 u32 h_outstream, u8 **pp_buffer,
1624 struct hpi_hostbuffer_status **pp_status); 1567 struct hpi_hostbuffer_status **pp_status);
1625 1568
1626u16 hpi_instream_host_buffer_get_info(const struct hpi_hsubsys *ph_subsys, 1569u16 hpi_instream_host_buffer_get_info(u32 h_instream, u8 **pp_buffer,
1627 u32 h_instream, u8 **pp_buffer,
1628 struct hpi_hostbuffer_status **pp_status); 1570 struct hpi_hostbuffer_status **pp_status);
1629 1571
1630u16 hpi_adapter_restart(u16 adapter_index); 1572u16 hpi_adapter_restart(u16 adapter_index);
diff --git a/sound/pci/asihpi/hpicmn.c b/sound/pci/asihpi/hpicmn.c
index d67f4d3db911..3e9c5c289764 100644
--- a/sound/pci/asihpi/hpicmn.c
+++ b/sound/pci/asihpi/hpicmn.c
@@ -26,6 +26,8 @@
26 26
27#include "hpi_internal.h" 27#include "hpi_internal.h"
28#include "hpidebug.h" 28#include "hpidebug.h"
29#include "hpimsginit.h"
30
29#include "hpicmn.h" 31#include "hpicmn.h"
30 32
31struct hpi_adapters_list { 33struct hpi_adapters_list {
@@ -43,14 +45,24 @@ static struct hpi_adapters_list adapters;
43**/ 45**/
44u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr) 46u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr)
45{ 47{
46 u16 error = 0; 48 if (phr->type != HPI_TYPE_RESPONSE) {
49 HPI_DEBUG_LOG(ERROR, "header type %d invalid\n", phr->type);
50 return HPI_ERROR_INVALID_RESPONSE;
51 }
47 52
48 if ((phr->type != HPI_TYPE_RESPONSE) 53 if (phr->object != phm->object) {
49 || (phr->object != phm->object) 54 HPI_DEBUG_LOG(ERROR, "header object %d invalid\n",
50 || (phr->function != phm->function)) 55 phr->object);
51 error = HPI_ERROR_INVALID_RESPONSE; 56 return HPI_ERROR_INVALID_RESPONSE;
57 }
58
59 if (phr->function != phm->function) {
60 HPI_DEBUG_LOG(ERROR, "header type %d invalid\n",
61 phr->function);
62 return HPI_ERROR_INVALID_RESPONSE;
63 }
52 64
53 return error; 65 return 0;
54} 66}
55 67
56u16 hpi_add_adapter(struct hpi_adapter_obj *pao) 68u16 hpi_add_adapter(struct hpi_adapter_obj *pao)
@@ -66,8 +78,18 @@ u16 hpi_add_adapter(struct hpi_adapter_obj *pao)
66 } 78 }
67 79
68 if (adapters.adapter[pao->index].adapter_type) { 80 if (adapters.adapter[pao->index].adapter_type) {
69 { 81 int a;
70 retval = HPI_DUPLICATE_ADAPTER_NUMBER; 82 for (a = HPI_MAX_ADAPTERS - 1; a >= 0; a--) {
83 if (!adapters.adapter[a].adapter_type) {
84 HPI_DEBUG_LOG(WARNING,
85 "ASI%X duplicate index %d moved to %d\n",
86 pao->adapter_type, pao->index, a);
87 pao->index = a;
88 break;
89 }
90 }
91 if (a < 0) {
92 retval = HPI_ERROR_DUPLICATE_ADAPTER_NUMBER;
71 goto unlock; 93 goto unlock;
72 } 94 }
73 } 95 }
@@ -76,17 +98,22 @@ u16 hpi_add_adapter(struct hpi_adapter_obj *pao)
76 adapters.gw_num_adapters++; 98 adapters.gw_num_adapters++;
77 99
78unlock: 100unlock:
79 hpios_alistlock_un_lock(&adapters); 101 hpios_alistlock_unlock(&adapters);
80 return retval; 102 return retval;
81} 103}
82 104
83void hpi_delete_adapter(struct hpi_adapter_obj *pao) 105void hpi_delete_adapter(struct hpi_adapter_obj *pao)
84{ 106{
85 memset(pao, 0, sizeof(struct hpi_adapter_obj)); 107 if (!pao->adapter_type) {
108 HPI_DEBUG_LOG(ERROR, "removing null adapter?\n");
109 return;
110 }
86 111
87 hpios_alistlock_lock(&adapters); 112 hpios_alistlock_lock(&adapters);
88 adapters.gw_num_adapters--; /* dec the number of adapters */ 113 if (adapters.adapter[pao->index].adapter_type)
89 hpios_alistlock_un_lock(&adapters); 114 adapters.gw_num_adapters--;
115 memset(&adapters.adapter[pao->index], 0, sizeof(adapters.adapter[0]));
116 hpios_alistlock_unlock(&adapters);
90} 117}
91 118
92/** 119/**
@@ -99,7 +126,7 @@ struct hpi_adapter_obj *hpi_find_adapter(u16 adapter_index)
99 struct hpi_adapter_obj *pao = NULL; 126 struct hpi_adapter_obj *pao = NULL;
100 127
101 if (adapter_index >= HPI_MAX_ADAPTERS) { 128 if (adapter_index >= HPI_MAX_ADAPTERS) {
102 HPI_DEBUG_LOG(VERBOSE, "find_adapter invalid index %d ", 129 HPI_DEBUG_LOG(VERBOSE, "find_adapter invalid index %d\n",
103 adapter_index); 130 adapter_index);
104 return NULL; 131 return NULL;
105 } 132 }
@@ -125,51 +152,34 @@ struct hpi_adapter_obj *hpi_find_adapter(u16 adapter_index)
125* wipe an HPI_ADAPTERS_LIST structure. 152* wipe an HPI_ADAPTERS_LIST structure.
126* 153*
127**/ 154**/
128static void wipe_adapter_list(void 155static void wipe_adapter_list(void)
129 )
130{ 156{
131 memset(&adapters, 0, sizeof(adapters)); 157 memset(&adapters, 0, sizeof(adapters));
132} 158}
133 159
134/** 160static void subsys_get_adapter(struct hpi_message *phm,
135* SubSysGetAdapters fills awAdapterList in an struct hpi_response structure 161 struct hpi_response *phr)
136* with all adapters in the given HPI_ADAPTERS_LIST.
137*
138*/
139static void subsys_get_adapters(struct hpi_response *phr)
140{ 162{
141 /* fill in the response adapter array with the position */ 163 int count = phm->obj_index;
142 /* identified by the adapter number/index of the adapters in */ 164 u16 index = 0;
143 /* this HPI */
144 /* i.e. if we have an A120 with it's jumper set to */
145 /* Adapter Number 2 then put an Adapter type A120 in the */
146 /* array in position 1 */
147 /* NOTE: AdapterNumber is 1..N, Index is 0..N-1 */
148
149 /* input: NONE */
150 /* output: wNumAdapters */
151 /* awAdapter[] */
152 /* */
153
154 short i;
155 struct hpi_adapter_obj *pao = NULL;
156 165
157 HPI_DEBUG_LOG(VERBOSE, "subsys_get_adapters\n"); 166 /* find the nCount'th nonzero adapter in array */
158 167 for (index = 0; index < HPI_MAX_ADAPTERS; index++) {
159 /* for each adapter, place it's type in the position of the array */ 168 if (adapters.adapter[index].adapter_type) {
160 /* corresponding to it's adapter number */ 169 if (!count)
161 for (i = 0; i < adapters.gw_num_adapters; i++) { 170 break;
162 pao = &adapters.adapter[i]; 171 count--;
163 if (phr->u.s.aw_adapter_list[pao->index] != 0) {
164 phr->error = HPI_DUPLICATE_ADAPTER_NUMBER;
165 phr->specific_error = pao->index;
166 return;
167 } 172 }
168 phr->u.s.aw_adapter_list[pao->index] = pao->adapter_type;
169 } 173 }
170 174
171 phr->u.s.num_adapters = adapters.gw_num_adapters; 175 if (index < HPI_MAX_ADAPTERS) {
172 phr->error = 0; /* the function completed OK; */ 176 phr->u.s.adapter_index = adapters.adapter[index].index;
177 phr->u.s.adapter_type = adapters.adapter[index].adapter_type;
178 } else {
179 phr->u.s.adapter_index = 0;
180 phr->u.s.adapter_type = 0;
181 phr->error = HPI_ERROR_BAD_ADAPTER_NUMBER;
182 }
173} 183}
174 184
175static unsigned int control_cache_alloc_check(struct hpi_control_cache *pC) 185static unsigned int control_cache_alloc_check(struct hpi_control_cache *pC)
@@ -178,67 +188,98 @@ static unsigned int control_cache_alloc_check(struct hpi_control_cache *pC)
178 int cached = 0; 188 int cached = 0;
179 if (!pC) 189 if (!pC)
180 return 0; 190 return 0;
181 if ((!pC->init) && (pC->p_cache != NULL) && (pC->control_count) 191
182 && (pC->cache_size_in_bytes) 192 if (pC->init)
183 ) { 193 return pC->init;
184 u32 *p_master_cache; 194
185 pC->init = 1; 195 if (!pC->p_cache)
186 196 return 0;
187 p_master_cache = (u32 *)pC->p_cache; 197
188 HPI_DEBUG_LOG(VERBOSE, "check %d controls\n", 198 if (pC->control_count && pC->cache_size_in_bytes) {
199 char *p_master_cache;
200 unsigned int byte_count = 0;
201
202 p_master_cache = (char *)pC->p_cache;
203 HPI_DEBUG_LOG(DEBUG, "check %d controls\n",
189 pC->control_count); 204 pC->control_count);
190 for (i = 0; i < pC->control_count; i++) { 205 for (i = 0; i < pC->control_count; i++) {
191 struct hpi_control_cache_info *info = 206 struct hpi_control_cache_info *info =
192 (struct hpi_control_cache_info *) 207 (struct hpi_control_cache_info *)
193 p_master_cache; 208 &p_master_cache[byte_count];
209
210 if (!info->size_in32bit_words) {
211 if (!i) {
212 HPI_DEBUG_LOG(INFO,
213 "adap %d cache not ready?\n",
214 pC->adap_idx);
215 return 0;
216 }
217 /* The cache is invalid.
218 * Minimum valid entry size is
219 * sizeof(struct hpi_control_cache_info)
220 */
221 HPI_DEBUG_LOG(ERROR,
222 "adap %d zero size cache entry %d\n",
223 pC->adap_idx, i);
224 break;
225 }
194 226
195 if (info->control_type) { 227 if (info->control_type) {
196 pC->p_info[i] = info; 228 pC->p_info[info->control_index] = info;
197 cached++; 229 cached++;
198 } else 230 } else /* dummy cache entry */
199 pC->p_info[i] = NULL; 231 pC->p_info[info->control_index] = NULL;
200 232
201 if (info->size_in32bit_words) 233 byte_count += info->size_in32bit_words * 4;
202 p_master_cache += info->size_in32bit_words;
203 else
204 p_master_cache +=
205 sizeof(struct
206 hpi_control_cache_single) /
207 sizeof(u32);
208 234
209 HPI_DEBUG_LOG(VERBOSE, 235 HPI_DEBUG_LOG(VERBOSE,
210 "cached %d, pinfo %p index %d type %d\n", 236 "cached %d, pinfo %p index %d type %d size %d\n",
211 cached, pC->p_info[i], info->control_index, 237 cached, pC->p_info[info->control_index],
212 info->control_type); 238 info->control_index, info->control_type,
239 info->size_in32bit_words);
240
241 /* quit loop early if whole cache has been scanned.
242 * dwControlCount is the maximum possible entries
243 * but some may be absent from the cache
244 */
245 if (byte_count >= pC->cache_size_in_bytes)
246 break;
247 /* have seen last control index */
248 if (info->control_index == pC->control_count - 1)
249 break;
213 } 250 }
214 /* 251
215 We didn't find anything to cache, so try again later ! 252 if (byte_count != pC->cache_size_in_bytes)
216 */ 253 HPI_DEBUG_LOG(WARNING,
217 if (!cached) 254 "adap %d bytecount %d != cache size %d\n",
218 pC->init = 0; 255 pC->adap_idx, byte_count,
256 pC->cache_size_in_bytes);
257 else
258 HPI_DEBUG_LOG(DEBUG,
259 "adap %d cache good, bytecount == cache size = %d\n",
260 pC->adap_idx, byte_count);
261
262 pC->init = (u16)cached;
219 } 263 }
220 return pC->init; 264 return pC->init;
221} 265}
222 266
223/** Find a control. 267/** Find a control.
224*/ 268*/
225static short find_control(struct hpi_message *phm, 269static short find_control(u16 control_index,
226 struct hpi_control_cache *p_cache, struct hpi_control_cache_info **pI, 270 struct hpi_control_cache *p_cache, struct hpi_control_cache_info **pI)
227 u16 *pw_control_index)
228{ 271{
229 *pw_control_index = phm->obj_index;
230
231 if (!control_cache_alloc_check(p_cache)) { 272 if (!control_cache_alloc_check(p_cache)) {
232 HPI_DEBUG_LOG(VERBOSE, 273 HPI_DEBUG_LOG(VERBOSE,
233 "control_cache_alloc_check() failed. adap%d ci%d\n", 274 "control_cache_alloc_check() failed %d\n",
234 phm->adapter_index, *pw_control_index); 275 control_index);
235 return 0; 276 return 0;
236 } 277 }
237 278
238 *pI = p_cache->p_info[*pw_control_index]; 279 *pI = p_cache->p_info[control_index];
239 if (!*pI) { 280 if (!*pI) {
240 HPI_DEBUG_LOG(VERBOSE, "uncached adap %d, control %d\n", 281 HPI_DEBUG_LOG(VERBOSE, "Uncached Control %d\n",
241 phm->adapter_index, *pw_control_index); 282 control_index);
242 return 0; 283 return 0;
243 } else { 284 } else {
244 HPI_DEBUG_LOG(VERBOSE, "find_control() type %d\n", 285 HPI_DEBUG_LOG(VERBOSE, "find_control() type %d\n",
@@ -247,25 +288,6 @@ static short find_control(struct hpi_message *phm,
247 return 1; 288 return 1;
248} 289}
249 290
250/** Used by the kernel driver to figure out if a buffer needs mapping.
251 */
252short hpi_check_buffer_mapping(struct hpi_control_cache *p_cache,
253 struct hpi_message *phm, void **p, unsigned int *pN)
254{
255 *pN = 0;
256 *p = NULL;
257 if ((phm->function == HPI_CONTROL_GET_STATE)
258 && (phm->object == HPI_OBJ_CONTROLEX)
259 ) {
260 u16 control_index;
261 struct hpi_control_cache_info *pI;
262
263 if (!find_control(phm, p_cache, &pI, &control_index))
264 return 0;
265 }
266 return 0;
267}
268
269/* allow unified treatment of several string fields within struct */ 291/* allow unified treatment of several string fields within struct */
270#define HPICMN_PAD_OFS_AND_SIZE(m) {\ 292#define HPICMN_PAD_OFS_AND_SIZE(m) {\
271 offsetof(struct hpi_control_cache_pad, m), \ 293 offsetof(struct hpi_control_cache_pad, m), \
@@ -290,13 +312,16 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
290 struct hpi_message *phm, struct hpi_response *phr) 312 struct hpi_message *phm, struct hpi_response *phr)
291{ 313{
292 short found = 1; 314 short found = 1;
293 u16 control_index;
294 struct hpi_control_cache_info *pI; 315 struct hpi_control_cache_info *pI;
295 struct hpi_control_cache_single *pC; 316 struct hpi_control_cache_single *pC;
296 struct hpi_control_cache_pad *p_pad; 317 struct hpi_control_cache_pad *p_pad;
297 318
298 if (!find_control(phm, p_cache, &pI, &control_index)) 319 if (!find_control(phm->obj_index, p_cache, &pI)) {
320 HPI_DEBUG_LOG(VERBOSE,
321 "HPICMN find_control() failed for adap %d\n",
322 phm->adapter_index);
299 return 0; 323 return 0;
324 }
300 325
301 phr->error = 0; 326 phr->error = 0;
302 327
@@ -310,55 +335,79 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
310 335
311 case HPI_CONTROL_METER: 336 case HPI_CONTROL_METER:
312 if (phm->u.c.attribute == HPI_METER_PEAK) { 337 if (phm->u.c.attribute == HPI_METER_PEAK) {
313 phr->u.c.an_log_value[0] = pC->u.p.an_log_peak[0]; 338 phr->u.c.an_log_value[0] = pC->u.meter.an_log_peak[0];
314 phr->u.c.an_log_value[1] = pC->u.p.an_log_peak[1]; 339 phr->u.c.an_log_value[1] = pC->u.meter.an_log_peak[1];
315 } else if (phm->u.c.attribute == HPI_METER_RMS) { 340 } else if (phm->u.c.attribute == HPI_METER_RMS) {
316 phr->u.c.an_log_value[0] = pC->u.p.an_logRMS[0]; 341 if (pC->u.meter.an_logRMS[0] ==
317 phr->u.c.an_log_value[1] = pC->u.p.an_logRMS[1]; 342 HPI_CACHE_INVALID_SHORT) {
343 phr->error =
344 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
345 phr->u.c.an_log_value[0] = HPI_METER_MINIMUM;
346 phr->u.c.an_log_value[1] = HPI_METER_MINIMUM;
347 } else {
348 phr->u.c.an_log_value[0] =
349 pC->u.meter.an_logRMS[0];
350 phr->u.c.an_log_value[1] =
351 pC->u.meter.an_logRMS[1];
352 }
318 } else 353 } else
319 found = 0; 354 found = 0;
320 break; 355 break;
321 case HPI_CONTROL_VOLUME: 356 case HPI_CONTROL_VOLUME:
322 if (phm->u.c.attribute == HPI_VOLUME_GAIN) { 357 if (phm->u.c.attribute == HPI_VOLUME_GAIN) {
323 phr->u.c.an_log_value[0] = pC->u.v.an_log[0]; 358 phr->u.c.an_log_value[0] = pC->u.vol.an_log[0];
324 phr->u.c.an_log_value[1] = pC->u.v.an_log[1]; 359 phr->u.c.an_log_value[1] = pC->u.vol.an_log[1];
325 } else 360 } else if (phm->u.c.attribute == HPI_VOLUME_MUTE) {
361 if (pC->u.vol.flags & HPI_VOLUME_FLAG_HAS_MUTE) {
362 if (pC->u.vol.flags & HPI_VOLUME_FLAG_MUTED)
363 phr->u.c.param1 =
364 HPI_BITMASK_ALL_CHANNELS;
365 else
366 phr->u.c.param1 = 0;
367 } else {
368 phr->error =
369 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
370 phr->u.c.param1 = 0;
371 }
372 } else {
326 found = 0; 373 found = 0;
374 }
327 break; 375 break;
328 case HPI_CONTROL_MULTIPLEXER: 376 case HPI_CONTROL_MULTIPLEXER:
329 if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) { 377 if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) {
330 phr->u.c.param1 = pC->u.x.source_node_type; 378 phr->u.c.param1 = pC->u.mux.source_node_type;
331 phr->u.c.param2 = pC->u.x.source_node_index; 379 phr->u.c.param2 = pC->u.mux.source_node_index;
332 } else { 380 } else {
333 found = 0; 381 found = 0;
334 } 382 }
335 break; 383 break;
336 case HPI_CONTROL_CHANNEL_MODE: 384 case HPI_CONTROL_CHANNEL_MODE:
337 if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE) 385 if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE)
338 phr->u.c.param1 = pC->u.m.mode; 386 phr->u.c.param1 = pC->u.mode.mode;
339 else 387 else
340 found = 0; 388 found = 0;
341 break; 389 break;
342 case HPI_CONTROL_LEVEL: 390 case HPI_CONTROL_LEVEL:
343 if (phm->u.c.attribute == HPI_LEVEL_GAIN) { 391 if (phm->u.c.attribute == HPI_LEVEL_GAIN) {
344 phr->u.c.an_log_value[0] = pC->u.l.an_log[0]; 392 phr->u.c.an_log_value[0] = pC->u.level.an_log[0];
345 phr->u.c.an_log_value[1] = pC->u.l.an_log[1]; 393 phr->u.c.an_log_value[1] = pC->u.level.an_log[1];
346 } else 394 } else
347 found = 0; 395 found = 0;
348 break; 396 break;
349 case HPI_CONTROL_TUNER: 397 case HPI_CONTROL_TUNER:
350 if (phm->u.c.attribute == HPI_TUNER_FREQ) 398 if (phm->u.c.attribute == HPI_TUNER_FREQ)
351 phr->u.c.param1 = pC->u.t.freq_ink_hz; 399 phr->u.c.param1 = pC->u.tuner.freq_ink_hz;
352 else if (phm->u.c.attribute == HPI_TUNER_BAND) 400 else if (phm->u.c.attribute == HPI_TUNER_BAND)
353 phr->u.c.param1 = pC->u.t.band; 401 phr->u.c.param1 = pC->u.tuner.band;
354 else if ((phm->u.c.attribute == HPI_TUNER_LEVEL) 402 else if (phm->u.c.attribute == HPI_TUNER_LEVEL_AVG)
355 && (phm->u.c.param1 == HPI_TUNER_LEVEL_AVERAGE)) 403 if (pC->u.tuner.s_level_avg ==
356 if (pC->u.t.level == HPI_ERROR_ILLEGAL_CACHE_VALUE) { 404 HPI_CACHE_INVALID_SHORT) {
357 phr->u.c.param1 = 0; 405 phr->u.cu.tuner.s_level = 0;
358 phr->error = 406 phr->error =
359 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE; 407 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
360 } else 408 } else
361 phr->u.c.param1 = pC->u.t.level; 409 phr->u.cu.tuner.s_level =
410 pC->u.tuner.s_level_avg;
362 else 411 else
363 found = 0; 412 found = 0;
364 break; 413 break;
@@ -366,7 +415,7 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
366 if (phm->u.c.attribute == HPI_AESEBURX_ERRORSTATUS) 415 if (phm->u.c.attribute == HPI_AESEBURX_ERRORSTATUS)
367 phr->u.c.param1 = pC->u.aes3rx.error_status; 416 phr->u.c.param1 = pC->u.aes3rx.error_status;
368 else if (phm->u.c.attribute == HPI_AESEBURX_FORMAT) 417 else if (phm->u.c.attribute == HPI_AESEBURX_FORMAT)
369 phr->u.c.param1 = pC->u.aes3rx.source; 418 phr->u.c.param1 = pC->u.aes3rx.format;
370 else 419 else
371 found = 0; 420 found = 0;
372 break; 421 break;
@@ -385,13 +434,12 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
385 case HPI_CONTROL_SILENCEDETECTOR: 434 case HPI_CONTROL_SILENCEDETECTOR:
386 if (phm->u.c.attribute == HPI_SILENCEDETECTOR_STATE) { 435 if (phm->u.c.attribute == HPI_SILENCEDETECTOR_STATE) {
387 phr->u.c.param1 = pC->u.silence.state; 436 phr->u.c.param1 = pC->u.silence.state;
388 phr->u.c.param2 = pC->u.silence.count;
389 } else 437 } else
390 found = 0; 438 found = 0;
391 break; 439 break;
392 case HPI_CONTROL_MICROPHONE: 440 case HPI_CONTROL_MICROPHONE:
393 if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER) 441 if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER)
394 phr->u.c.param1 = pC->u.phantom_power.state; 442 phr->u.c.param1 = pC->u.microphone.phantom_state;
395 else 443 else
396 found = 0; 444 found = 0;
397 break; 445 break;
@@ -400,7 +448,7 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
400 phr->u.c.param1 = pC->u.clk.source; 448 phr->u.c.param1 = pC->u.clk.source;
401 else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE_INDEX) { 449 else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE_INDEX) {
402 if (pC->u.clk.source_index == 450 if (pC->u.clk.source_index ==
403 HPI_ERROR_ILLEGAL_CACHE_VALUE) { 451 HPI_CACHE_INVALID_UINT16) {
404 phr->u.c.param1 = 0; 452 phr->u.c.param1 = 0;
405 phr->error = 453 phr->error =
406 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE; 454 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
@@ -411,60 +459,63 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
411 else 459 else
412 found = 0; 460 found = 0;
413 break; 461 break;
414 case HPI_CONTROL_PAD: 462 case HPI_CONTROL_PAD:{
463 struct hpi_control_cache_pad *p_pad;
464 p_pad = (struct hpi_control_cache_pad *)pI;
415 465
416 if (!(p_pad->field_valid_flags & (1 << 466 if (!(p_pad->field_valid_flags & (1 <<
417 HPI_CTL_ATTR_INDEX(phm->u.c. 467 HPI_CTL_ATTR_INDEX(phm->u.c.
418 attribute)))) { 468 attribute)))) {
419 phr->error = HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
420 break;
421 }
422
423 if (phm->u.c.attribute == HPI_PAD_PROGRAM_ID)
424 phr->u.c.param1 = p_pad->pI;
425 else if (phm->u.c.attribute == HPI_PAD_PROGRAM_TYPE)
426 phr->u.c.param1 = p_pad->pTY;
427 else {
428 unsigned int index =
429 HPI_CTL_ATTR_INDEX(phm->u.c.attribute) - 1;
430 unsigned int offset = phm->u.c.param1;
431 unsigned int pad_string_len, field_size;
432 char *pad_string;
433 unsigned int tocopy;
434
435 HPI_DEBUG_LOG(VERBOSE, "PADS HPI_PADS_ %d\n",
436 phm->u.c.attribute);
437
438 if (index > ARRAY_SIZE(pad_desc) - 1) {
439 phr->error = 469 phr->error =
440 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE; 470 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
441 break; 471 break;
442 } 472 }
443 473
444 pad_string = ((char *)p_pad) + pad_desc[index].offset; 474 if (phm->u.c.attribute == HPI_PAD_PROGRAM_ID)
445 field_size = pad_desc[index].field_size; 475 phr->u.c.param1 = p_pad->pI;
446 /* Ensure null terminator */ 476 else if (phm->u.c.attribute == HPI_PAD_PROGRAM_TYPE)
447 pad_string[field_size - 1] = 0; 477 phr->u.c.param1 = p_pad->pTY;
448 478 else {
449 pad_string_len = strlen(pad_string) + 1; 479 unsigned int index =
450 480 HPI_CTL_ATTR_INDEX(phm->u.c.
451 if (offset > pad_string_len) { 481 attribute) - 1;
452 phr->error = HPI_ERROR_INVALID_CONTROL_VALUE; 482 unsigned int offset = phm->u.c.param1;
453 break; 483 unsigned int pad_string_len, field_size;
484 char *pad_string;
485 unsigned int tocopy;
486
487 if (index > ARRAY_SIZE(pad_desc) - 1) {
488 phr->error =
489 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
490 break;
491 }
492
493 pad_string =
494 ((char *)p_pad) +
495 pad_desc[index].offset;
496 field_size = pad_desc[index].field_size;
497 /* Ensure null terminator */
498 pad_string[field_size - 1] = 0;
499
500 pad_string_len = strlen(pad_string) + 1;
501
502 if (offset > pad_string_len) {
503 phr->error =
504 HPI_ERROR_INVALID_CONTROL_VALUE;
505 break;
506 }
507
508 tocopy = pad_string_len - offset;
509 if (tocopy > sizeof(phr->u.cu.chars8.sz_data))
510 tocopy = sizeof(phr->u.cu.chars8.
511 sz_data);
512
513 memcpy(phr->u.cu.chars8.sz_data,
514 &pad_string[offset], tocopy);
515
516 phr->u.cu.chars8.remaining_chars =
517 pad_string_len - offset - tocopy;
454 } 518 }
455
456 tocopy = pad_string_len - offset;
457 if (tocopy > sizeof(phr->u.cu.chars8.sz_data))
458 tocopy = sizeof(phr->u.cu.chars8.sz_data);
459
460 HPI_DEBUG_LOG(VERBOSE,
461 "PADS memcpy(%d), offset %d \n", tocopy,
462 offset);
463 memcpy(phr->u.cu.chars8.sz_data, &pad_string[offset],
464 tocopy);
465
466 phr->u.cu.chars8.remaining_chars =
467 pad_string_len - offset - tocopy;
468 } 519 }
469 break; 520 break;
470 default: 521 default:
@@ -472,16 +523,9 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
472 break; 523 break;
473 } 524 }
474 525
475 if (found) 526 HPI_DEBUG_LOG(VERBOSE, "%s Adap %d, Ctl %d, Type %d, Attr %d\n",
476 HPI_DEBUG_LOG(VERBOSE, 527 found ? "Cached" : "Uncached", phm->adapter_index,
477 "cached adap %d, ctl %d, type %d, attr %d\n", 528 pI->control_index, pI->control_type, phm->u.c.attribute);
478 phm->adapter_index, pI->control_index,
479 pI->control_type, phm->u.c.attribute);
480 else
481 HPI_DEBUG_LOG(VERBOSE,
482 "uncached adap %d, ctl %d, ctl type %d\n",
483 phm->adapter_index, pI->control_index,
484 pI->control_type);
485 529
486 if (found) 530 if (found)
487 phr->size = 531 phr->size =
@@ -497,18 +541,21 @@ Only update if no error.
497Volume and Level return the limited values in the response, so use these 541Volume and Level return the limited values in the response, so use these
498Multiplexer does so use sent values 542Multiplexer does so use sent values
499*/ 543*/
500void hpi_sync_control_cache(struct hpi_control_cache *p_cache, 544void hpi_cmn_control_cache_sync_to_msg(struct hpi_control_cache *p_cache,
501 struct hpi_message *phm, struct hpi_response *phr) 545 struct hpi_message *phm, struct hpi_response *phr)
502{ 546{
503 u16 control_index;
504 struct hpi_control_cache_single *pC; 547 struct hpi_control_cache_single *pC;
505 struct hpi_control_cache_info *pI; 548 struct hpi_control_cache_info *pI;
506 549
507 if (phr->error) 550 if (phr->error)
508 return; 551 return;
509 552
510 if (!find_control(phm, p_cache, &pI, &control_index)) 553 if (!find_control(phm->obj_index, p_cache, &pI)) {
554 HPI_DEBUG_LOG(VERBOSE,
555 "HPICMN find_control() failed for adap %d\n",
556 phm->adapter_index);
511 return; 557 return;
558 }
512 559
513 /* pC is the default cached control strucure. 560 /* pC is the default cached control strucure.
514 May be cast to something else in the following switch statement. 561 May be cast to something else in the following switch statement.
@@ -518,31 +565,36 @@ void hpi_sync_control_cache(struct hpi_control_cache *p_cache,
518 switch (pI->control_type) { 565 switch (pI->control_type) {
519 case HPI_CONTROL_VOLUME: 566 case HPI_CONTROL_VOLUME:
520 if (phm->u.c.attribute == HPI_VOLUME_GAIN) { 567 if (phm->u.c.attribute == HPI_VOLUME_GAIN) {
521 pC->u.v.an_log[0] = phr->u.c.an_log_value[0]; 568 pC->u.vol.an_log[0] = phr->u.c.an_log_value[0];
522 pC->u.v.an_log[1] = phr->u.c.an_log_value[1]; 569 pC->u.vol.an_log[1] = phr->u.c.an_log_value[1];
570 } else if (phm->u.c.attribute == HPI_VOLUME_MUTE) {
571 if (phm->u.c.param1)
572 pC->u.vol.flags |= HPI_VOLUME_FLAG_MUTED;
573 else
574 pC->u.vol.flags &= ~HPI_VOLUME_FLAG_MUTED;
523 } 575 }
524 break; 576 break;
525 case HPI_CONTROL_MULTIPLEXER: 577 case HPI_CONTROL_MULTIPLEXER:
526 /* mux does not return its setting on Set command. */ 578 /* mux does not return its setting on Set command. */
527 if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) { 579 if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) {
528 pC->u.x.source_node_type = (u16)phm->u.c.param1; 580 pC->u.mux.source_node_type = (u16)phm->u.c.param1;
529 pC->u.x.source_node_index = (u16)phm->u.c.param2; 581 pC->u.mux.source_node_index = (u16)phm->u.c.param2;
530 } 582 }
531 break; 583 break;
532 case HPI_CONTROL_CHANNEL_MODE: 584 case HPI_CONTROL_CHANNEL_MODE:
533 /* mode does not return its setting on Set command. */ 585 /* mode does not return its setting on Set command. */
534 if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE) 586 if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE)
535 pC->u.m.mode = (u16)phm->u.c.param1; 587 pC->u.mode.mode = (u16)phm->u.c.param1;
536 break; 588 break;
537 case HPI_CONTROL_LEVEL: 589 case HPI_CONTROL_LEVEL:
538 if (phm->u.c.attribute == HPI_LEVEL_GAIN) { 590 if (phm->u.c.attribute == HPI_LEVEL_GAIN) {
539 pC->u.v.an_log[0] = phr->u.c.an_log_value[0]; 591 pC->u.vol.an_log[0] = phr->u.c.an_log_value[0];
540 pC->u.v.an_log[1] = phr->u.c.an_log_value[1]; 592 pC->u.vol.an_log[1] = phr->u.c.an_log_value[1];
541 } 593 }
542 break; 594 break;
543 case HPI_CONTROL_MICROPHONE: 595 case HPI_CONTROL_MICROPHONE:
544 if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER) 596 if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER)
545 pC->u.phantom_power.state = (u16)phm->u.c.param1; 597 pC->u.microphone.phantom_state = (u16)phm->u.c.param1;
546 break; 598 break;
547 case HPI_CONTROL_AESEBU_TRANSMITTER: 599 case HPI_CONTROL_AESEBU_TRANSMITTER:
548 if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT) 600 if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT)
@@ -550,7 +602,7 @@ void hpi_sync_control_cache(struct hpi_control_cache *p_cache,
550 break; 602 break;
551 case HPI_CONTROL_AESEBU_RECEIVER: 603 case HPI_CONTROL_AESEBU_RECEIVER:
552 if (phm->u.c.attribute == HPI_AESEBURX_FORMAT) 604 if (phm->u.c.attribute == HPI_AESEBURX_FORMAT)
553 pC->u.aes3rx.source = phm->u.c.param1; 605 pC->u.aes3rx.format = phm->u.c.param1;
554 break; 606 break;
555 case HPI_CONTROL_SAMPLECLOCK: 607 case HPI_CONTROL_SAMPLECLOCK:
556 if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE) 608 if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE)
@@ -565,59 +617,57 @@ void hpi_sync_control_cache(struct hpi_control_cache *p_cache,
565 } 617 }
566} 618}
567 619
568struct hpi_control_cache *hpi_alloc_control_cache(const u32 620struct hpi_control_cache *hpi_alloc_control_cache(const u32 control_count,
569 number_of_controls, const u32 size_in_bytes, 621 const u32 size_in_bytes, u8 *p_dsp_control_buffer)
570 struct hpi_control_cache_info *pDSP_control_buffer)
571{ 622{
572 struct hpi_control_cache *p_cache = 623 struct hpi_control_cache *p_cache =
573 kmalloc(sizeof(*p_cache), GFP_KERNEL); 624 kmalloc(sizeof(*p_cache), GFP_KERNEL);
574 if (!p_cache) 625 if (!p_cache)
575 return NULL; 626 return NULL;
627
576 p_cache->p_info = 628 p_cache->p_info =
577 kmalloc(sizeof(*p_cache->p_info) * number_of_controls, 629 kmalloc(sizeof(*p_cache->p_info) * control_count, GFP_KERNEL);
578 GFP_KERNEL);
579 if (!p_cache->p_info) { 630 if (!p_cache->p_info) {
580 kfree(p_cache); 631 kfree(p_cache);
581 return NULL; 632 return NULL;
582 } 633 }
634 memset(p_cache->p_info, 0, sizeof(*p_cache->p_info) * control_count);
583 p_cache->cache_size_in_bytes = size_in_bytes; 635 p_cache->cache_size_in_bytes = size_in_bytes;
584 p_cache->control_count = number_of_controls; 636 p_cache->control_count = control_count;
585 p_cache->p_cache = 637 p_cache->p_cache = p_dsp_control_buffer;
586 (struct hpi_control_cache_single *)pDSP_control_buffer;
587 p_cache->init = 0; 638 p_cache->init = 0;
588 return p_cache; 639 return p_cache;
589} 640}
590 641
591void hpi_free_control_cache(struct hpi_control_cache *p_cache) 642void hpi_free_control_cache(struct hpi_control_cache *p_cache)
592{ 643{
593 if (p_cache->init) { 644 if (p_cache) {
594 kfree(p_cache->p_info); 645 kfree(p_cache->p_info);
595 p_cache->p_info = NULL;
596 p_cache->init = 0;
597 kfree(p_cache); 646 kfree(p_cache);
598 } 647 }
599} 648}
600 649
601static void subsys_message(struct hpi_message *phm, struct hpi_response *phr) 650static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
602{ 651{
652 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, phm->function, 0);
603 653
604 switch (phm->function) { 654 switch (phm->function) {
605 case HPI_SUBSYS_OPEN: 655 case HPI_SUBSYS_OPEN:
606 case HPI_SUBSYS_CLOSE: 656 case HPI_SUBSYS_CLOSE:
607 case HPI_SUBSYS_DRIVER_UNLOAD: 657 case HPI_SUBSYS_DRIVER_UNLOAD:
608 phr->error = 0;
609 break; 658 break;
610 case HPI_SUBSYS_DRIVER_LOAD: 659 case HPI_SUBSYS_DRIVER_LOAD:
611 wipe_adapter_list(); 660 wipe_adapter_list();
612 hpios_alistlock_init(&adapters); 661 hpios_alistlock_init(&adapters);
613 phr->error = 0;
614 break; 662 break;
615 case HPI_SUBSYS_GET_INFO: 663 case HPI_SUBSYS_GET_ADAPTER:
616 subsys_get_adapters(phr); 664 subsys_get_adapter(phm, phr);
665 break;
666 case HPI_SUBSYS_GET_NUM_ADAPTERS:
667 phr->u.s.num_adapters = adapters.gw_num_adapters;
617 break; 668 break;
618 case HPI_SUBSYS_CREATE_ADAPTER: 669 case HPI_SUBSYS_CREATE_ADAPTER:
619 case HPI_SUBSYS_DELETE_ADAPTER: 670 case HPI_SUBSYS_DELETE_ADAPTER:
620 phr->error = 0;
621 break; 671 break;
622 default: 672 default:
623 phr->error = HPI_ERROR_INVALID_FUNC; 673 phr->error = HPI_ERROR_INVALID_FUNC;
diff --git a/sound/pci/asihpi/hpicmn.h b/sound/pci/asihpi/hpicmn.h
index 6229022f56cb..590f0b69e655 100644
--- a/sound/pci/asihpi/hpicmn.h
+++ b/sound/pci/asihpi/hpicmn.h
@@ -33,18 +33,19 @@ struct hpi_adapter_obj {
33}; 33};
34 34
35struct hpi_control_cache { 35struct hpi_control_cache {
36 u32 init; /**< indicates whether the 36 /** indicates whether the structures are initialized */
37 structures are initialized */ 37 u16 init;
38 u16 adap_idx;
38 u32 control_count; 39 u32 control_count;
39 u32 cache_size_in_bytes; 40 u32 cache_size_in_bytes;
40 struct hpi_control_cache_info 41 /** pointer to allocated memory of lookup pointers. */
41 **p_info; /**< pointer to allocated memory of 42 struct hpi_control_cache_info **p_info;
42 lookup pointers. */ 43 /** pointer to DSP's control cache. */
43 struct hpi_control_cache_single 44 u8 *p_cache;
44 *p_cache; /**< pointer to DSP's control cache. */
45}; 45};
46 46
47struct hpi_adapter_obj *hpi_find_adapter(u16 adapter_index); 47struct hpi_adapter_obj *hpi_find_adapter(u16 adapter_index);
48
48u16 hpi_add_adapter(struct hpi_adapter_obj *pao); 49u16 hpi_add_adapter(struct hpi_adapter_obj *pao);
49 50
50void hpi_delete_adapter(struct hpi_adapter_obj *pao); 51void hpi_delete_adapter(struct hpi_adapter_obj *pao);
@@ -52,13 +53,10 @@ void hpi_delete_adapter(struct hpi_adapter_obj *pao);
52short hpi_check_control_cache(struct hpi_control_cache *pC, 53short hpi_check_control_cache(struct hpi_control_cache *pC,
53 struct hpi_message *phm, struct hpi_response *phr); 54 struct hpi_message *phm, struct hpi_response *phr);
54struct hpi_control_cache *hpi_alloc_control_cache(const u32 55struct hpi_control_cache *hpi_alloc_control_cache(const u32
55 number_of_controls, const u32 size_in_bytes, 56 number_of_controls, const u32 size_in_bytes, u8 *pDSP_control_buffer);
56 struct hpi_control_cache_info
57 *pDSP_control_buffer);
58void hpi_free_control_cache(struct hpi_control_cache *p_cache); 57void hpi_free_control_cache(struct hpi_control_cache *p_cache);
59 58
60void hpi_sync_control_cache(struct hpi_control_cache *pC, 59void hpi_cmn_control_cache_sync_to_msg(struct hpi_control_cache *pC,
61 struct hpi_message *phm, struct hpi_response *phr); 60 struct hpi_message *phm, struct hpi_response *phr);
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);
63short hpi_check_buffer_mapping(struct hpi_control_cache *p_cache,
64 struct hpi_message *phm, void **p, unsigned int *pN);
diff --git a/sound/pci/asihpi/hpidebug.c b/sound/pci/asihpi/hpidebug.c
index 949836ec913a..b52baf62791e 100644
--- a/sound/pci/asihpi/hpidebug.c
+++ b/sound/pci/asihpi/hpidebug.c
@@ -45,161 +45,14 @@ int hpi_debug_level_get(void)
45 return hpi_debug_level; 45 return hpi_debug_level;
46} 46}
47 47
48#ifdef HPIOS_DEBUG_PRINT
49/* implies OS has no printf-like function */
50#include <stdarg.h>
51
52void hpi_debug_printf(char *fmt, ...)
53{
54 va_list arglist;
55 char buffer[128];
56
57 va_start(arglist, fmt);
58
59 if (buffer[0])
60 HPIOS_DEBUG_PRINT(buffer);
61 va_end(arglist);
62}
63#endif
64
65struct treenode {
66 void *array;
67 unsigned int num_elements;
68};
69
70#define make_treenode_from_array(nodename, array) \
71static void *tmp_strarray_##nodename[] = array; \
72static struct treenode nodename = { \
73 &tmp_strarray_##nodename, \
74 ARRAY_SIZE(tmp_strarray_##nodename) \
75};
76
77#define get_treenode_elem(node_ptr, idx, type) \
78 (&(*((type *)(node_ptr)->array)[idx]))
79
80make_treenode_from_array(hpi_control_type_strings, HPI_CONTROL_TYPE_STRINGS)
81
82 make_treenode_from_array(hpi_subsys_strings, HPI_SUBSYS_STRINGS)
83 make_treenode_from_array(hpi_adapter_strings, HPI_ADAPTER_STRINGS)
84 make_treenode_from_array(hpi_istream_strings, HPI_ISTREAM_STRINGS)
85 make_treenode_from_array(hpi_ostream_strings, HPI_OSTREAM_STRINGS)
86 make_treenode_from_array(hpi_mixer_strings, HPI_MIXER_STRINGS)
87 make_treenode_from_array(hpi_node_strings,
88 {
89 "NODE is invalid object"})
90
91 make_treenode_from_array(hpi_control_strings, HPI_CONTROL_STRINGS)
92 make_treenode_from_array(hpi_nvmemory_strings, HPI_OBJ_STRINGS)
93 make_treenode_from_array(hpi_digitalio_strings, HPI_DIGITALIO_STRINGS)
94 make_treenode_from_array(hpi_watchdog_strings, HPI_WATCHDOG_STRINGS)
95 make_treenode_from_array(hpi_clock_strings, HPI_CLOCK_STRINGS)
96 make_treenode_from_array(hpi_profile_strings, HPI_PROFILE_STRINGS)
97 make_treenode_from_array(hpi_asyncevent_strings, HPI_ASYNCEVENT_STRINGS)
98#define HPI_FUNCTION_STRINGS \
99{ \
100 &hpi_subsys_strings,\
101 &hpi_adapter_strings,\
102 &hpi_ostream_strings,\
103 &hpi_istream_strings,\
104 &hpi_mixer_strings,\
105 &hpi_node_strings,\
106 &hpi_control_strings,\
107 &hpi_nvmemory_strings,\
108 &hpi_digitalio_strings,\
109 &hpi_watchdog_strings,\
110 &hpi_clock_strings,\
111 &hpi_profile_strings,\
112 &hpi_control_strings, \
113 &hpi_asyncevent_strings \
114}
115 make_treenode_from_array(hpi_function_strings, HPI_FUNCTION_STRINGS)
116
117 compile_time_assert(HPI_OBJ_MAXINDEX == 14, obj_list_doesnt_match);
118
119static char *hpi_function_string(unsigned int function)
120{
121 unsigned int object;
122 struct treenode *tmp;
123
124 object = function / HPI_OBJ_FUNCTION_SPACING;
125 function = function - object * HPI_OBJ_FUNCTION_SPACING;
126
127 if (object == 0 || object == HPI_OBJ_NODE
128 || object > hpi_function_strings.num_elements)
129 return "invalid object";
130
131 tmp = get_treenode_elem(&hpi_function_strings, object - 1,
132 struct treenode *);
133
134 if (function == 0 || function > tmp->num_elements)
135 return "invalid function";
136
137 return get_treenode_elem(tmp, function - 1, char *);
138}
139
140void hpi_debug_message(struct hpi_message *phm, char *sz_fileline) 48void hpi_debug_message(struct hpi_message *phm, char *sz_fileline)
141{ 49{
142 if (phm) { 50 if (phm) {
143 if ((phm->object <= HPI_OBJ_MAXINDEX) && phm->object) { 51 printk(KERN_DEBUG "HPI_MSG%d,%d,%d,%d,%d\n", phm->version,
144 u16 index = 0; 52 phm->adapter_index, phm->obj_index, phm->function,
145 u16 attrib = 0; 53 phm->u.c.attribute);
146 int is_control = 0; 54 }
147 55
148 index = phm->obj_index;
149 switch (phm->object) {
150 case HPI_OBJ_ADAPTER:
151 case HPI_OBJ_PROFILE:
152 break;
153 case HPI_OBJ_MIXER:
154 if (phm->function ==
155 HPI_MIXER_GET_CONTROL_BY_INDEX)
156 index = phm->u.m.control_index;
157 break;
158 case HPI_OBJ_OSTREAM:
159 case HPI_OBJ_ISTREAM:
160 break;
161
162 case HPI_OBJ_CONTROLEX:
163 case HPI_OBJ_CONTROL:
164 if (phm->version == 1)
165 attrib = HPI_CTL_ATTR(UNIVERSAL, 1);
166 else
167 attrib = phm->u.c.attribute;
168 is_control = 1;
169 break;
170 default:
171 break;
172 }
173
174 if (is_control && (attrib & 0xFF00)) {
175 int control_type = (attrib & 0xFF00) >> 8;
176 int attr_index = HPI_CTL_ATTR_INDEX(attrib);
177 /* note the KERN facility level
178 is in szFileline already */
179 printk("%s adapter %d %s "
180 "ctrl_index x%04x %s %d\n",
181 sz_fileline, phm->adapter_index,
182 hpi_function_string(phm->function),
183 index,
184 get_treenode_elem
185 (&hpi_control_type_strings,
186 control_type, char *),
187 attr_index);
188
189 } else
190 printk("%s adapter %d %s "
191 "idx x%04x attr x%04x \n",
192 sz_fileline, phm->adapter_index,
193 hpi_function_string(phm->function),
194 index, attrib);
195 } else {
196 printk("adap=%d, invalid obj=%d, func=0x%x\n",
197 phm->adapter_index, phm->object,
198 phm->function);
199 }
200 } else
201 printk(KERN_ERR
202 "NULL message pointer to hpi_debug_message!\n");
203} 56}
204 57
205void hpi_debug_data(u16 *pdata, u32 len) 58void hpi_debug_data(u16 *pdata, u32 len)
diff --git a/sound/pci/asihpi/hpidebug.h b/sound/pci/asihpi/hpidebug.h
index a2f0952a99f0..940f54c3c538 100644
--- a/sound/pci/asihpi/hpidebug.h
+++ b/sound/pci/asihpi/hpidebug.h
@@ -37,7 +37,7 @@ enum { HPI_DEBUG_LEVEL_ERROR = 0, /* always log errors */
37#define HPI_DEBUG_LEVEL_DEFAULT HPI_DEBUG_LEVEL_NOTICE 37#define HPI_DEBUG_LEVEL_DEFAULT HPI_DEBUG_LEVEL_NOTICE
38 38
39/* an OS can define an extra flag string that is appended to 39/* an OS can define an extra flag string that is appended to
40 the start of each message, eg see hpios_linux.h */ 40 the start of each message, eg see linux kernel hpios.h */
41 41
42#ifdef SOURCEFILE_NAME 42#ifdef SOURCEFILE_NAME
43#define FILE_LINE SOURCEFILE_NAME ":" __stringify(__LINE__) " " 43#define FILE_LINE SOURCEFILE_NAME ":" __stringify(__LINE__) " "
@@ -45,18 +45,11 @@ enum { HPI_DEBUG_LEVEL_ERROR = 0, /* always log errors */
45#define FILE_LINE __FILE__ ":" __stringify(__LINE__) " " 45#define FILE_LINE __FILE__ ":" __stringify(__LINE__) " "
46#endif 46#endif
47 47
48#if defined(HPI_DEBUG) && defined(_WINDOWS)
49#define HPI_DEBUGBREAK() debug_break()
50#else
51#define HPI_DEBUGBREAK()
52#endif
53
54#define HPI_DEBUG_ASSERT(expression) \ 48#define HPI_DEBUG_ASSERT(expression) \
55 do { \ 49 do { \
56 if (!(expression)) {\ 50 if (!(expression)) { \
57 printk(KERN_ERR FILE_LINE\ 51 printk(KERN_ERR FILE_LINE \
58 "ASSERT " __stringify(expression));\ 52 "ASSERT " __stringify(expression)); \
59 HPI_DEBUGBREAK();\
60 } \ 53 } \
61 } while (0) 54 } while (0)
62 55
@@ -78,28 +71,27 @@ void hpi_debug_message(struct hpi_message *phm, char *sz_fileline);
78 71
79void hpi_debug_data(u16 *pdata, u32 len); 72void hpi_debug_data(u16 *pdata, u32 len);
80 73
81#define HPI_DEBUG_DATA(pdata, len) \ 74#define HPI_DEBUG_DATA(pdata, len) \
82 do { \ 75 do { \
83 if (hpi_debug_level >= HPI_DEBUG_LEVEL_VERBOSE) \ 76 if (hpi_debug_level >= HPI_DEBUG_LEVEL_VERBOSE) \
84 hpi_debug_data(pdata, len); \ 77 hpi_debug_data(pdata, len); \
85 } while (0) 78 } while (0)
86 79
87#define HPI_DEBUG_MESSAGE(level, phm) \ 80#define HPI_DEBUG_MESSAGE(level, phm) \
88 do { \ 81 do { \
89 if (hpi_debug_level >= HPI_DEBUG_LEVEL_##level) { \ 82 if (hpi_debug_level >= HPI_DEBUG_LEVEL_##level) { \
90 hpi_debug_message(phm,HPI_DEBUG_FLAG_##level \ 83 hpi_debug_message(phm, HPI_DEBUG_FLAG_##level \
91 FILE_LINE __stringify(level));\ 84 FILE_LINE __stringify(level)); \
92 } \ 85 } \
93 } while (0) 86 } while (0)
94 87
95#define HPI_DEBUG_RESPONSE(phr) \ 88#define HPI_DEBUG_RESPONSE(phr) \
96 do { \ 89 do { \
97 if ((hpi_debug_level >= HPI_DEBUG_LEVEL_DEBUG) && (phr->error))\ 90 if (((hpi_debug_level >= HPI_DEBUG_LEVEL_DEBUG) && \
98 HPI_DEBUG_LOG(ERROR, \ 91 (phr->error)) ||\
99 "HPI response - error# %d\n", \ 92 (hpi_debug_level >= HPI_DEBUG_LEVEL_VERBOSE)) \
100 phr->error); \ 93 printk(KERN_DEBUG "HPI_RES%d,%d,%d\n", \
101 else if (hpi_debug_level >= HPI_DEBUG_LEVEL_VERBOSE) \ 94 phr->version, phr->error, phr->specific_error); \
102 HPI_DEBUG_LOG(VERBOSE, "HPI response OK\n");\
103 } while (0) 95 } while (0)
104 96
105#ifndef compile_time_assert 97#ifndef compile_time_assert
@@ -107,279 +99,4 @@ void hpi_debug_data(u16 *pdata, u32 len);
107 typedef char msg[(cond) ? 1 : -1] 99 typedef char msg[(cond) ? 1 : -1]
108#endif 100#endif
109 101
110 /* check that size is exactly some number */ 102#endif /* _HPIDEBUG_H_ */
111#define function_count_check(sym, size) \
112 compile_time_assert((sym##_FUNCTION_COUNT) == (size),\
113 strings_match_defs_##sym)
114
115/* These strings should be generated using a macro which defines
116 the corresponding symbol values. */
117#define HPI_OBJ_STRINGS \
118{ \
119 "HPI_OBJ_SUBSYSTEM", \
120 "HPI_OBJ_ADAPTER", \
121 "HPI_OBJ_OSTREAM", \
122 "HPI_OBJ_ISTREAM", \
123 "HPI_OBJ_MIXER", \
124 "HPI_OBJ_NODE", \
125 "HPI_OBJ_CONTROL", \
126 "HPI_OBJ_NVMEMORY", \
127 "HPI_OBJ_DIGITALIO", \
128 "HPI_OBJ_WATCHDOG", \
129 "HPI_OBJ_CLOCK", \
130 "HPI_OBJ_PROFILE", \
131 "HPI_OBJ_CONTROLEX" \
132}
133
134#define HPI_SUBSYS_STRINGS \
135{ \
136 "HPI_SUBSYS_OPEN", \
137 "HPI_SUBSYS_GET_VERSION", \
138 "HPI_SUBSYS_GET_INFO", \
139 "HPI_SUBSYS_FIND_ADAPTERS", \
140 "HPI_SUBSYS_CREATE_ADAPTER",\
141 "HPI_SUBSYS_CLOSE", \
142 "HPI_SUBSYS_DELETE_ADAPTER", \
143 "HPI_SUBSYS_DRIVER_LOAD", \
144 "HPI_SUBSYS_DRIVER_UNLOAD", \
145 "HPI_SUBSYS_READ_PORT_8", \
146 "HPI_SUBSYS_WRITE_PORT_8", \
147 "HPI_SUBSYS_GET_NUM_ADAPTERS",\
148 "HPI_SUBSYS_GET_ADAPTER", \
149 "HPI_SUBSYS_SET_NETWORK_INTERFACE"\
150}
151function_count_check(HPI_SUBSYS, 14);
152
153#define HPI_ADAPTER_STRINGS \
154{ \
155 "HPI_ADAPTER_OPEN", \
156 "HPI_ADAPTER_CLOSE", \
157 "HPI_ADAPTER_GET_INFO", \
158 "HPI_ADAPTER_GET_ASSERT", \
159 "HPI_ADAPTER_TEST_ASSERT", \
160 "HPI_ADAPTER_SET_MODE", \
161 "HPI_ADAPTER_GET_MODE", \
162 "HPI_ADAPTER_ENABLE_CAPABILITY",\
163 "HPI_ADAPTER_SELFTEST", \
164 "HPI_ADAPTER_FIND_OBJECT", \
165 "HPI_ADAPTER_QUERY_FLASH", \
166 "HPI_ADAPTER_START_FLASH", \
167 "HPI_ADAPTER_PROGRAM_FLASH", \
168 "HPI_ADAPTER_SET_PROPERTY", \
169 "HPI_ADAPTER_GET_PROPERTY", \
170 "HPI_ADAPTER_ENUM_PROPERTY", \
171 "HPI_ADAPTER_MODULE_INFO", \
172 "HPI_ADAPTER_DEBUG_READ" \
173}
174
175function_count_check(HPI_ADAPTER, 18);
176
177#define HPI_OSTREAM_STRINGS \
178{ \
179 "HPI_OSTREAM_OPEN", \
180 "HPI_OSTREAM_CLOSE", \
181 "HPI_OSTREAM_WRITE", \
182 "HPI_OSTREAM_START", \
183 "HPI_OSTREAM_STOP", \
184 "HPI_OSTREAM_RESET", \
185 "HPI_OSTREAM_GET_INFO", \
186 "HPI_OSTREAM_QUERY_FORMAT", \
187 "HPI_OSTREAM_DATA", \
188 "HPI_OSTREAM_SET_VELOCITY", \
189 "HPI_OSTREAM_SET_PUNCHINOUT", \
190 "HPI_OSTREAM_SINEGEN", \
191 "HPI_OSTREAM_ANC_RESET", \
192 "HPI_OSTREAM_ANC_GET_INFO", \
193 "HPI_OSTREAM_ANC_READ", \
194 "HPI_OSTREAM_SET_TIMESCALE",\
195 "HPI_OSTREAM_SET_FORMAT", \
196 "HPI_OSTREAM_HOSTBUFFER_ALLOC", \
197 "HPI_OSTREAM_HOSTBUFFER_FREE", \
198 "HPI_OSTREAM_GROUP_ADD",\
199 "HPI_OSTREAM_GROUP_GETMAP", \
200 "HPI_OSTREAM_GROUP_RESET", \
201 "HPI_OSTREAM_HOSTBUFFER_GET_INFO", \
202 "HPI_OSTREAM_WAIT_START", \
203}
204function_count_check(HPI_OSTREAM, 24);
205
206#define HPI_ISTREAM_STRINGS \
207{ \
208 "HPI_ISTREAM_OPEN", \
209 "HPI_ISTREAM_CLOSE", \
210 "HPI_ISTREAM_SET_FORMAT", \
211 "HPI_ISTREAM_READ", \
212 "HPI_ISTREAM_START", \
213 "HPI_ISTREAM_STOP", \
214 "HPI_ISTREAM_RESET", \
215 "HPI_ISTREAM_GET_INFO", \
216 "HPI_ISTREAM_QUERY_FORMAT", \
217 "HPI_ISTREAM_ANC_RESET", \
218 "HPI_ISTREAM_ANC_GET_INFO", \
219 "HPI_ISTREAM_ANC_WRITE", \
220 "HPI_ISTREAM_HOSTBUFFER_ALLOC",\
221 "HPI_ISTREAM_HOSTBUFFER_FREE", \
222 "HPI_ISTREAM_GROUP_ADD", \
223 "HPI_ISTREAM_GROUP_GETMAP", \
224 "HPI_ISTREAM_GROUP_RESET", \
225 "HPI_ISTREAM_HOSTBUFFER_GET_INFO", \
226 "HPI_ISTREAM_WAIT_START", \
227}
228function_count_check(HPI_ISTREAM, 19);
229
230#define HPI_MIXER_STRINGS \
231{ \
232 "HPI_MIXER_OPEN", \
233 "HPI_MIXER_CLOSE", \
234 "HPI_MIXER_GET_INFO", \
235 "HPI_MIXER_GET_NODE_INFO", \
236 "HPI_MIXER_GET_CONTROL", \
237 "HPI_MIXER_SET_CONNECTION", \
238 "HPI_MIXER_GET_CONNECTIONS", \
239 "HPI_MIXER_GET_CONTROL_BY_INDEX", \
240 "HPI_MIXER_GET_CONTROL_ARRAY_BY_INDEX", \
241 "HPI_MIXER_GET_CONTROL_MULTIPLE_VALUES", \
242 "HPI_MIXER_STORE", \
243}
244function_count_check(HPI_MIXER, 11);
245
246#define HPI_CONTROL_STRINGS \
247{ \
248 "HPI_CONTROL_GET_INFO", \
249 "HPI_CONTROL_GET_STATE", \
250 "HPI_CONTROL_SET_STATE" \
251}
252function_count_check(HPI_CONTROL, 3);
253
254#define HPI_NVMEMORY_STRINGS \
255{ \
256 "HPI_NVMEMORY_OPEN", \
257 "HPI_NVMEMORY_READ_BYTE", \
258 "HPI_NVMEMORY_WRITE_BYTE" \
259}
260function_count_check(HPI_NVMEMORY, 3);
261
262#define HPI_DIGITALIO_STRINGS \
263{ \
264 "HPI_GPIO_OPEN", \
265 "HPI_GPIO_READ_BIT", \
266 "HPI_GPIO_WRITE_BIT", \
267 "HPI_GPIO_READ_ALL", \
268 "HPI_GPIO_WRITE_STATUS"\
269}
270function_count_check(HPI_GPIO, 5);
271
272#define HPI_WATCHDOG_STRINGS \
273{ \
274 "HPI_WATCHDOG_OPEN", \
275 "HPI_WATCHDOG_SET_TIME", \
276 "HPI_WATCHDOG_PING" \
277}
278
279#define HPI_CLOCK_STRINGS \
280{ \
281 "HPI_CLOCK_OPEN", \
282 "HPI_CLOCK_SET_TIME", \
283 "HPI_CLOCK_GET_TIME" \
284}
285
286#define HPI_PROFILE_STRINGS \
287{ \
288 "HPI_PROFILE_OPEN_ALL", \
289 "HPI_PROFILE_START_ALL", \
290 "HPI_PROFILE_STOP_ALL", \
291 "HPI_PROFILE_GET", \
292 "HPI_PROFILE_GET_IDLECOUNT", \
293 "HPI_PROFILE_GET_NAME", \
294 "HPI_PROFILE_GET_UTILIZATION" \
295}
296function_count_check(HPI_PROFILE, 7);
297
298#define HPI_ASYNCEVENT_STRINGS \
299{ \
300 "HPI_ASYNCEVENT_OPEN",\
301 "HPI_ASYNCEVENT_CLOSE ",\
302 "HPI_ASYNCEVENT_WAIT",\
303 "HPI_ASYNCEVENT_GETCOUNT",\
304 "HPI_ASYNCEVENT_GET",\
305 "HPI_ASYNCEVENT_SENDEVENTS"\
306}
307function_count_check(HPI_ASYNCEVENT, 6);
308
309#define HPI_CONTROL_TYPE_STRINGS \
310{ \
311 "null control", \
312 "HPI_CONTROL_CONNECTION", \
313 "HPI_CONTROL_VOLUME", \
314 "HPI_CONTROL_METER", \
315 "HPI_CONTROL_MUTE", \
316 "HPI_CONTROL_MULTIPLEXER", \
317 "HPI_CONTROL_AESEBU_TRANSMITTER", \
318 "HPI_CONTROL_AESEBU_RECEIVER", \
319 "HPI_CONTROL_LEVEL", \
320 "HPI_CONTROL_TUNER", \
321 "HPI_CONTROL_ONOFFSWITCH", \
322 "HPI_CONTROL_VOX", \
323 "HPI_CONTROL_AES18_TRANSMITTER", \
324 "HPI_CONTROL_AES18_RECEIVER", \
325 "HPI_CONTROL_AES18_BLOCKGENERATOR", \
326 "HPI_CONTROL_CHANNEL_MODE", \
327 "HPI_CONTROL_BITSTREAM", \
328 "HPI_CONTROL_SAMPLECLOCK", \
329 "HPI_CONTROL_MICROPHONE", \
330 "HPI_CONTROL_PARAMETRIC_EQ", \
331 "HPI_CONTROL_COMPANDER", \
332 "HPI_CONTROL_COBRANET", \
333 "HPI_CONTROL_TONE_DETECT", \
334 "HPI_CONTROL_SILENCE_DETECT", \
335 "HPI_CONTROL_PAD", \
336 "HPI_CONTROL_SRC" ,\
337 "HPI_CONTROL_UNIVERSAL" \
338}
339
340compile_time_assert((HPI_CONTROL_LAST_INDEX + 1 == 27),
341 controltype_strings_match_defs);
342
343#define HPI_SOURCENODE_STRINGS \
344{ \
345 "no source", \
346 "HPI_SOURCENODE_OSTREAM", \
347 "HPI_SOURCENODE_LINEIN", \
348 "HPI_SOURCENODE_AESEBU_IN", \
349 "HPI_SOURCENODE_TUNER", \
350 "HPI_SOURCENODE_RF", \
351 "HPI_SOURCENODE_CLOCK_SOURCE", \
352 "HPI_SOURCENODE_RAW_BITSTREAM", \
353 "HPI_SOURCENODE_MICROPHONE", \
354 "HPI_SOURCENODE_COBRANET", \
355 "HPI_SOURCENODE_ANALOG", \
356 "HPI_SOURCENODE_ADAPTER" \
357}
358
359compile_time_assert((HPI_SOURCENODE_LAST_INDEX - HPI_SOURCENODE_NONE + 1) ==
360 (12), sourcenode_strings_match_defs);
361
362#define HPI_DESTNODE_STRINGS \
363{ \
364 "no destination", \
365 "HPI_DESTNODE_ISTREAM", \
366 "HPI_DESTNODE_LINEOUT", \
367 "HPI_DESTNODE_AESEBU_OUT", \
368 "HPI_DESTNODE_RF", \
369 "HPI_DESTNODE_SPEAKER", \
370 "HPI_DESTNODE_COBRANET", \
371 "HPI_DESTNODE_ANALOG" \
372}
373compile_time_assert((HPI_DESTNODE_LAST_INDEX - HPI_DESTNODE_NONE + 1) == (8),
374 destnode_strings_match_defs);
375
376#define HPI_CONTROL_CHANNEL_MODE_STRINGS \
377{ \
378 "XXX HPI_CHANNEL_MODE_ERROR XXX", \
379 "HPI_CHANNEL_MODE_NORMAL", \
380 "HPI_CHANNEL_MODE_SWAP", \
381 "HPI_CHANNEL_MODE_LEFT_ONLY", \
382 "HPI_CHANNEL_MODE_RIGHT_ONLY" \
383}
384
385#endif /* _HPIDEBUG_H */
diff --git a/sound/pci/asihpi/hpidspcd.c b/sound/pci/asihpi/hpidspcd.c
index 9b10d9a5c255..fb311d8c05bf 100644
--- a/sound/pci/asihpi/hpidspcd.c
+++ b/sound/pci/asihpi/hpidspcd.c
@@ -71,47 +71,50 @@ short hpi_dsp_code_open(u32 adapter, struct dsp_code *ps_dsp_code,
71 int err; 71 int err;
72 72
73 sprintf(fw_name, "asihpi/dsp%04x.bin", adapter); 73 sprintf(fw_name, "asihpi/dsp%04x.bin", adapter);
74 HPI_DEBUG_LOG(INFO, "requesting firmware for %s\n", fw_name);
75 74
76 err = request_firmware(&ps_firmware, fw_name, 75 err = request_firmware(&ps_firmware, fw_name,
77 &ps_dsp_code->ps_dev->dev); 76 &ps_dsp_code->ps_dev->dev);
77
78 if (err != 0) { 78 if (err != 0) {
79 HPI_DEBUG_LOG(ERROR, "%d, request_firmware failed for %s\n", 79 dev_printk(KERN_ERR, &ps_dsp_code->ps_dev->dev,
80 err, fw_name); 80 "%d, request_firmware failed for %s\n", err,
81 fw_name);
81 goto error1; 82 goto error1;
82 } 83 }
83 if (ps_firmware->size < sizeof(header)) { 84 if (ps_firmware->size < sizeof(header)) {
84 HPI_DEBUG_LOG(ERROR, "header size too small %s\n", fw_name); 85 dev_printk(KERN_ERR, &ps_dsp_code->ps_dev->dev,
86 "Header size too small %s\n", fw_name);
85 goto error2; 87 goto error2;
86 } 88 }
87 memcpy(&header, ps_firmware->data, sizeof(header)); 89 memcpy(&header, ps_firmware->data, sizeof(header));
88 if (header.adapter != adapter) { 90 if (header.adapter != adapter) {
89 HPI_DEBUG_LOG(ERROR, "adapter type incorrect %4x != %4x\n", 91 dev_printk(KERN_ERR, &ps_dsp_code->ps_dev->dev,
90 header.adapter, adapter); 92 "Adapter type incorrect %4x != %4x\n", header.adapter,
93 adapter);
91 goto error2; 94 goto error2;
92 } 95 }
93 if (header.size != ps_firmware->size) { 96 if (header.size != ps_firmware->size) {
94 HPI_DEBUG_LOG(ERROR, "code size wrong %d != %ld\n", 97 dev_printk(KERN_ERR, &ps_dsp_code->ps_dev->dev,
95 header.size, (unsigned long)ps_firmware->size); 98 "Code size wrong %d != %ld\n", header.size,
99 (unsigned long)ps_firmware->size);
96 goto error2; 100 goto error2;
97 } 101 }
98 102
99 if (header.version / 10000 != HPI_VER_DECIMAL / 10000) { 103 if (header.version / 100 != HPI_VER_DECIMAL / 100) {
100 HPI_DEBUG_LOG(ERROR, 104 dev_printk(KERN_ERR, &ps_dsp_code->ps_dev->dev,
101 "firmware major version mismatch " 105 "Incompatible firmware version "
102 "DSP image %d != driver %d\n", header.version, 106 "DSP image %d != Driver %d\n", header.version,
103 HPI_VER_DECIMAL); 107 HPI_VER_DECIMAL);
104 goto error2; 108 goto error2;
105 } 109 }
106 110
107 if (header.version != HPI_VER_DECIMAL) { 111 if (header.version != HPI_VER_DECIMAL) {
108 HPI_DEBUG_LOG(WARNING, 112 dev_printk(KERN_WARNING, &ps_dsp_code->ps_dev->dev,
109 "version mismatch DSP image %d != driver %d\n", 113 "Firmware: release version mismatch DSP image %d != Driver %d\n",
110 header.version, HPI_VER_DECIMAL); 114 header.version, HPI_VER_DECIMAL);
111 /* goto error2; still allow driver to load */
112 } 115 }
113 116
114 HPI_DEBUG_LOG(INFO, "dsp code %s opened\n", fw_name); 117 HPI_DEBUG_LOG(DEBUG, "dsp code %s opened\n", fw_name);
115 ps_dsp_code->ps_firmware = ps_firmware; 118 ps_dsp_code->ps_firmware = ps_firmware;
116 ps_dsp_code->block_length = header.size / sizeof(u32); 119 ps_dsp_code->block_length = header.size / sizeof(u32);
117 ps_dsp_code->word_count = sizeof(header) / sizeof(u32); 120 ps_dsp_code->word_count = sizeof(header) / sizeof(u32);
@@ -148,7 +151,7 @@ void hpi_dsp_code_rewind(struct dsp_code *ps_dsp_code)
148short hpi_dsp_code_read_word(struct dsp_code *ps_dsp_code, u32 *pword) 151short hpi_dsp_code_read_word(struct dsp_code *ps_dsp_code, u32 *pword)
149{ 152{
150 if (ps_dsp_code->word_count + 1 > ps_dsp_code->block_length) 153 if (ps_dsp_code->word_count + 1 > ps_dsp_code->block_length)
151 return (HPI_ERROR_DSP_FILE_FORMAT); 154 return HPI_ERROR_DSP_FILE_FORMAT;
152 155
153 *pword = ((u32 *)(ps_dsp_code->ps_firmware->data))[ps_dsp_code-> 156 *pword = ((u32 *)(ps_dsp_code->ps_firmware->data))[ps_dsp_code->
154 word_count]; 157 word_count];
diff --git a/sound/pci/asihpi/hpidspcd.h b/sound/pci/asihpi/hpidspcd.h
index d7c240398225..65f0ca732704 100644
--- a/sound/pci/asihpi/hpidspcd.h
+++ b/sound/pci/asihpi/hpidspcd.h
@@ -87,7 +87,7 @@ void hpi_dsp_code_rewind(struct dsp_code *ps_dsp_code);
87*/ 87*/
88short hpi_dsp_code_read_word(struct dsp_code *ps_dsp_code, 88short hpi_dsp_code_read_word(struct dsp_code *ps_dsp_code,
89 /**< DSP code descriptor */ 89 /**< DSP code descriptor */
90 u32 *pword /**< where to store the read word */ 90 u32 *pword /**< Where to store the read word */
91 ); 91 );
92 92
93/** Get a block of dsp code into an internal buffer, and provide a pointer to 93/** Get a block of dsp code into an internal buffer, and provide a pointer to
diff --git a/sound/pci/asihpi/hpifunc.c b/sound/pci/asihpi/hpifunc.c
index 1e92eb6dd509..c38fc9487560 100644
--- a/sound/pci/asihpi/hpifunc.c
+++ b/sound/pci/asihpi/hpifunc.c
@@ -30,16 +30,25 @@ u32 hpi_indexes_to_handle(const char c_object, const u16 adapter_index,
30 return handle.w; 30 return handle.w;
31} 31}
32 32
33void hpi_handle_to_indexes(const u32 handle, u16 *pw_adapter_index, 33static u16 hpi_handle_indexes(const u32 h, u16 *p1, u16 *p2)
34 u16 *pw_object_index)
35{ 34{
36 union handle_word uhandle; 35 union handle_word uhandle;
37 uhandle.w = handle; 36 if (!h)
37 return HPI_ERROR_INVALID_HANDLE;
38
39 uhandle.w = h;
40
41 *p1 = (u16)uhandle.h.adapter_index;
42 if (p2)
43 *p2 = (u16)uhandle.h.obj_index;
38 44
39 if (pw_adapter_index) 45 return 0;
40 *pw_adapter_index = (u16)uhandle.h.adapter_index; 46}
41 if (pw_object_index) 47
42 *pw_object_index = (u16)uhandle.h.obj_index; 48void hpi_handle_to_indexes(const u32 handle, u16 *pw_adapter_index,
49 u16 *pw_object_index)
50{
51 hpi_handle_indexes(handle, pw_adapter_index, pw_object_index);
43} 52}
44 53
45char hpi_handle_object(const u32 handle) 54char hpi_handle_object(const u32 handle)
@@ -49,22 +58,6 @@ char hpi_handle_object(const u32 handle)
49 return (char)uhandle.h.obj_type; 58 return (char)uhandle.h.obj_type;
50} 59}
51 60
52#define u32TOINDEX(h, i1) \
53do {\
54 if (h == 0) \
55 return HPI_ERROR_INVALID_OBJ; \
56 else \
57 hpi_handle_to_indexes(h, i1, NULL); \
58} while (0)
59
60#define u32TOINDEXES(h, i1, i2) \
61do {\
62 if (h == 0) \
63 return HPI_ERROR_INVALID_OBJ; \
64 else \
65 hpi_handle_to_indexes(h, i1, i2);\
66} while (0)
67
68void hpi_format_to_msg(struct hpi_msg_format *pMF, 61void hpi_format_to_msg(struct hpi_msg_format *pMF,
69 const struct hpi_format *pF) 62 const struct hpi_format *pF)
70{ 63{
@@ -94,52 +87,13 @@ void hpi_stream_response_to_legacy(struct hpi_stream_res *pSR)
94 pSR->u.legacy_stream_info.state = pSR->u.stream_info.state; 87 pSR->u.legacy_stream_info.state = pSR->u.stream_info.state;
95} 88}
96 89
97static struct hpi_hsubsys gh_subsys; 90static inline void hpi_send_recvV1(struct hpi_message_header *m,
98 91 struct hpi_response_header *r)
99struct hpi_hsubsys *hpi_subsys_create(void)
100{ 92{
101 struct hpi_message hm; 93 hpi_send_recv((struct hpi_message *)m, (struct hpi_response *)r);
102 struct hpi_response hr;
103
104 memset(&gh_subsys, 0, sizeof(struct hpi_hsubsys));
105
106 {
107 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
108 HPI_SUBSYS_OPEN);
109 hpi_send_recv(&hm, &hr);
110
111 if (hr.error == 0)
112 return &gh_subsys;
113
114 }
115 return NULL;
116}
117
118void hpi_subsys_free(const struct hpi_hsubsys *ph_subsys)
119{
120 struct hpi_message hm;
121 struct hpi_response hr;
122
123 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
124 HPI_SUBSYS_CLOSE);
125 hpi_send_recv(&hm, &hr);
126
127} 94}
128 95
129u16 hpi_subsys_get_version(const struct hpi_hsubsys *ph_subsys, u32 *pversion) 96u16 hpi_subsys_get_version_ex(u32 *pversion_ex)
130{
131 struct hpi_message hm;
132 struct hpi_response hr;
133
134 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
135 HPI_SUBSYS_GET_VERSION);
136 hpi_send_recv(&hm, &hr);
137 *pversion = hr.u.s.version;
138 return hr.error;
139}
140
141u16 hpi_subsys_get_version_ex(const struct hpi_hsubsys *ph_subsys,
142 u32 *pversion_ex)
143{ 97{
144 struct hpi_message hm; 98 struct hpi_message hm;
145 struct hpi_response hr; 99 struct hpi_response hr;
@@ -151,51 +105,8 @@ u16 hpi_subsys_get_version_ex(const struct hpi_hsubsys *ph_subsys,
151 return hr.error; 105 return hr.error;
152} 106}
153 107
154u16 hpi_subsys_get_info(const struct hpi_hsubsys *ph_subsys, u32 *pversion, 108u16 hpi_subsys_create_adapter(const struct hpi_resource *p_resource,
155 u16 *pw_num_adapters, u16 aw_adapter_list[], u16 list_length) 109 u16 *pw_adapter_index)
156{
157 struct hpi_message hm;
158 struct hpi_response hr;
159 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
160 HPI_SUBSYS_GET_INFO);
161
162 hpi_send_recv(&hm, &hr);
163
164 *pversion = hr.u.s.version;
165 if (list_length > HPI_MAX_ADAPTERS)
166 memcpy(aw_adapter_list, &hr.u.s.aw_adapter_list,
167 HPI_MAX_ADAPTERS);
168 else
169 memcpy(aw_adapter_list, &hr.u.s.aw_adapter_list, list_length);
170 *pw_num_adapters = hr.u.s.num_adapters;
171 return hr.error;
172}
173
174u16 hpi_subsys_find_adapters(const struct hpi_hsubsys *ph_subsys,
175 u16 *pw_num_adapters, u16 aw_adapter_list[], u16 list_length)
176{
177 struct hpi_message hm;
178 struct hpi_response hr;
179 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
180 HPI_SUBSYS_FIND_ADAPTERS);
181
182 hpi_send_recv(&hm, &hr);
183
184 if (list_length > HPI_MAX_ADAPTERS) {
185 memcpy(aw_adapter_list, &hr.u.s.aw_adapter_list,
186 HPI_MAX_ADAPTERS * sizeof(u16));
187 memset(&aw_adapter_list[HPI_MAX_ADAPTERS], 0,
188 (list_length - HPI_MAX_ADAPTERS) * sizeof(u16));
189 } else
190 memcpy(aw_adapter_list, &hr.u.s.aw_adapter_list,
191 list_length * sizeof(u16));
192 *pw_num_adapters = hr.u.s.num_adapters;
193
194 return hr.error;
195}
196
197u16 hpi_subsys_create_adapter(const struct hpi_hsubsys *ph_subsys,
198 const struct hpi_resource *p_resource, u16 *pw_adapter_index)
199{ 110{
200 struct hpi_message hm; 111 struct hpi_message hm;
201 struct hpi_response hr; 112 struct hpi_response hr;
@@ -210,20 +121,18 @@ u16 hpi_subsys_create_adapter(const struct hpi_hsubsys *ph_subsys,
210 return hr.error; 121 return hr.error;
211} 122}
212 123
213u16 hpi_subsys_delete_adapter(const struct hpi_hsubsys *ph_subsys, 124u16 hpi_subsys_delete_adapter(u16 adapter_index)
214 u16 adapter_index)
215{ 125{
216 struct hpi_message hm; 126 struct hpi_message hm;
217 struct hpi_response hr; 127 struct hpi_response hr;
218 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM, 128 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
219 HPI_SUBSYS_DELETE_ADAPTER); 129 HPI_SUBSYS_DELETE_ADAPTER);
220 hm.adapter_index = adapter_index; 130 hm.obj_index = adapter_index;
221 hpi_send_recv(&hm, &hr); 131 hpi_send_recv(&hm, &hr);
222 return hr.error; 132 return hr.error;
223} 133}
224 134
225u16 hpi_subsys_get_num_adapters(const struct hpi_hsubsys *ph_subsys, 135u16 hpi_subsys_get_num_adapters(int *pn_num_adapters)
226 int *pn_num_adapters)
227{ 136{
228 struct hpi_message hm; 137 struct hpi_message hm;
229 struct hpi_response hr; 138 struct hpi_response hr;
@@ -234,35 +143,22 @@ u16 hpi_subsys_get_num_adapters(const struct hpi_hsubsys *ph_subsys,
234 return hr.error; 143 return hr.error;
235} 144}
236 145
237u16 hpi_subsys_get_adapter(const struct hpi_hsubsys *ph_subsys, int iterator, 146u16 hpi_subsys_get_adapter(int iterator, u32 *padapter_index,
238 u32 *padapter_index, u16 *pw_adapter_type) 147 u16 *pw_adapter_type)
239{ 148{
240 struct hpi_message hm; 149 struct hpi_message hm;
241 struct hpi_response hr; 150 struct hpi_response hr;
242 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM, 151 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
243 HPI_SUBSYS_GET_ADAPTER); 152 HPI_SUBSYS_GET_ADAPTER);
244 hm.adapter_index = (u16)iterator; 153 hm.obj_index = (u16)iterator;
245 hpi_send_recv(&hm, &hr); 154 hpi_send_recv(&hm, &hr);
246 *padapter_index = (int)hr.u.s.adapter_index; 155 *padapter_index = (int)hr.u.s.adapter_index;
247 *pw_adapter_type = hr.u.s.aw_adapter_list[0]; 156 *pw_adapter_type = hr.u.s.adapter_type;
248 return hr.error;
249}
250 157
251u16 hpi_subsys_set_host_network_interface(const struct hpi_hsubsys *ph_subsys,
252 const char *sz_interface)
253{
254 struct hpi_message hm;
255 struct hpi_response hr;
256 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
257 HPI_SUBSYS_SET_NETWORK_INTERFACE);
258 if (sz_interface == NULL)
259 return HPI_ERROR_INVALID_RESOURCE;
260 hm.u.s.resource.r.net_if = sz_interface;
261 hpi_send_recv(&hm, &hr);
262 return hr.error; 158 return hr.error;
263} 159}
264 160
265u16 hpi_adapter_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index) 161u16 hpi_adapter_open(u16 adapter_index)
266{ 162{
267 struct hpi_message hm; 163 struct hpi_message hm;
268 struct hpi_response hr; 164 struct hpi_response hr;
@@ -276,7 +172,7 @@ u16 hpi_adapter_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index)
276 172
277} 173}
278 174
279u16 hpi_adapter_close(const struct hpi_hsubsys *ph_subsys, u16 adapter_index) 175u16 hpi_adapter_close(u16 adapter_index)
280{ 176{
281 struct hpi_message hm; 177 struct hpi_message hm;
282 struct hpi_response hr; 178 struct hpi_response hr;
@@ -289,15 +185,14 @@ u16 hpi_adapter_close(const struct hpi_hsubsys *ph_subsys, u16 adapter_index)
289 return hr.error; 185 return hr.error;
290} 186}
291 187
292u16 hpi_adapter_set_mode(const struct hpi_hsubsys *ph_subsys, 188u16 hpi_adapter_set_mode(u16 adapter_index, u32 adapter_mode)
293 u16 adapter_index, u32 adapter_mode)
294{ 189{
295 return hpi_adapter_set_mode_ex(ph_subsys, adapter_index, adapter_mode, 190 return hpi_adapter_set_mode_ex(adapter_index, adapter_mode,
296 HPI_ADAPTER_MODE_SET); 191 HPI_ADAPTER_MODE_SET);
297} 192}
298 193
299u16 hpi_adapter_set_mode_ex(const struct hpi_hsubsys *ph_subsys, 194u16 hpi_adapter_set_mode_ex(u16 adapter_index, u32 adapter_mode,
300 u16 adapter_index, u32 adapter_mode, u16 query_or_set) 195 u16 query_or_set)
301{ 196{
302 struct hpi_message hm; 197 struct hpi_message hm;
303 struct hpi_response hr; 198 struct hpi_response hr;
@@ -305,14 +200,13 @@ u16 hpi_adapter_set_mode_ex(const struct hpi_hsubsys *ph_subsys,
305 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER, 200 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
306 HPI_ADAPTER_SET_MODE); 201 HPI_ADAPTER_SET_MODE);
307 hm.adapter_index = adapter_index; 202 hm.adapter_index = adapter_index;
308 hm.u.a.adapter_mode = adapter_mode; 203 hm.u.ax.mode.adapter_mode = adapter_mode;
309 hm.u.a.assert_id = query_or_set; 204 hm.u.ax.mode.query_or_set = query_or_set;
310 hpi_send_recv(&hm, &hr); 205 hpi_send_recv(&hm, &hr);
311 return hr.error; 206 return hr.error;
312} 207}
313 208
314u16 hpi_adapter_get_mode(const struct hpi_hsubsys *ph_subsys, 209u16 hpi_adapter_get_mode(u16 adapter_index, u32 *padapter_mode)
315 u16 adapter_index, u32 *padapter_mode)
316{ 210{
317 struct hpi_message hm; 211 struct hpi_message hm;
318 struct hpi_response hr; 212 struct hpi_response hr;
@@ -321,13 +215,13 @@ u16 hpi_adapter_get_mode(const struct hpi_hsubsys *ph_subsys,
321 hm.adapter_index = adapter_index; 215 hm.adapter_index = adapter_index;
322 hpi_send_recv(&hm, &hr); 216 hpi_send_recv(&hm, &hr);
323 if (padapter_mode) 217 if (padapter_mode)
324 *padapter_mode = hr.u.a.serial_number; 218 *padapter_mode = hr.u.ax.mode.adapter_mode;
325 return hr.error; 219 return hr.error;
326} 220}
327 221
328u16 hpi_adapter_get_info(const struct hpi_hsubsys *ph_subsys, 222u16 hpi_adapter_get_info(u16 adapter_index, u16 *pw_num_outstreams,
329 u16 adapter_index, u16 *pw_num_outstreams, u16 *pw_num_instreams, 223 u16 *pw_num_instreams, u16 *pw_version, u32 *pserial_number,
330 u16 *pw_version, u32 *pserial_number, u16 *pw_adapter_type) 224 u16 *pw_adapter_type)
331{ 225{
332 struct hpi_message hm; 226 struct hpi_message hm;
333 struct hpi_response hr; 227 struct hpi_response hr;
@@ -337,18 +231,17 @@ u16 hpi_adapter_get_info(const struct hpi_hsubsys *ph_subsys,
337 231
338 hpi_send_recv(&hm, &hr); 232 hpi_send_recv(&hm, &hr);
339 233
340 *pw_adapter_type = hr.u.a.adapter_type; 234 *pw_adapter_type = hr.u.ax.info.adapter_type;
341 *pw_num_outstreams = hr.u.a.num_outstreams; 235 *pw_num_outstreams = hr.u.ax.info.num_outstreams;
342 *pw_num_instreams = hr.u.a.num_instreams; 236 *pw_num_instreams = hr.u.ax.info.num_instreams;
343 *pw_version = hr.u.a.version; 237 *pw_version = hr.u.ax.info.version;
344 *pserial_number = hr.u.a.serial_number; 238 *pserial_number = hr.u.ax.info.serial_number;
345 return hr.error; 239 return hr.error;
346} 240}
347 241
348u16 hpi_adapter_get_module_by_index(const struct hpi_hsubsys *ph_subsys, 242u16 hpi_adapter_get_module_by_index(u16 adapter_index, u16 module_index,
349 u16 adapter_index, u16 module_index, u16 *pw_num_outputs, 243 u16 *pw_num_outputs, u16 *pw_num_inputs, u16 *pw_version,
350 u16 *pw_num_inputs, u16 *pw_version, u32 *pserial_number, 244 u32 *pserial_number, u16 *pw_module_type, u32 *ph_module)
351 u16 *pw_module_type, u32 *ph_module)
352{ 245{
353 struct hpi_message hm; 246 struct hpi_message hm;
354 struct hpi_response hr; 247 struct hpi_response hr;
@@ -360,173 +253,18 @@ u16 hpi_adapter_get_module_by_index(const struct hpi_hsubsys *ph_subsys,
360 253
361 hpi_send_recv(&hm, &hr); 254 hpi_send_recv(&hm, &hr);
362 255
363 *pw_module_type = hr.u.a.adapter_type; 256 *pw_module_type = hr.u.ax.info.adapter_type;
364 *pw_num_outputs = hr.u.a.num_outstreams; 257 *pw_num_outputs = hr.u.ax.info.num_outstreams;
365 *pw_num_inputs = hr.u.a.num_instreams; 258 *pw_num_inputs = hr.u.ax.info.num_instreams;
366 *pw_version = hr.u.a.version; 259 *pw_version = hr.u.ax.info.version;
367 *pserial_number = hr.u.a.serial_number; 260 *pserial_number = hr.u.ax.info.serial_number;
368 *ph_module = 0; 261 *ph_module = 0;
369 262
370 return hr.error; 263 return hr.error;
371} 264}
372 265
373u16 hpi_adapter_get_assert(const struct hpi_hsubsys *ph_subsys, 266u16 hpi_adapter_set_property(u16 adapter_index, u16 property, u16 parameter1,
374 u16 adapter_index, u16 *assert_present, char *psz_assert, 267 u16 parameter2)
375 u16 *pw_line_number)
376{
377 struct hpi_message hm;
378 struct hpi_response hr;
379 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
380 HPI_ADAPTER_GET_ASSERT);
381 hm.adapter_index = adapter_index;
382 hpi_send_recv(&hm, &hr);
383
384 *assert_present = 0;
385
386 if (!hr.error) {
387
388 *pw_line_number = (u16)hr.u.a.serial_number;
389 if (*pw_line_number) {
390
391 int i;
392 char *src = (char *)hr.u.a.sz_adapter_assert;
393 char *dst = psz_assert;
394
395 *assert_present = 1;
396
397 for (i = 0; i < HPI_STRING_LEN; i++) {
398 char c;
399 c = *src++;
400 *dst++ = c;
401 if (c == 0)
402 break;
403 }
404
405 }
406 }
407 return hr.error;
408}
409
410u16 hpi_adapter_get_assert_ex(const struct hpi_hsubsys *ph_subsys,
411 u16 adapter_index, u16 *assert_present, char *psz_assert,
412 u32 *pline_number, u16 *pw_assert_on_dsp)
413{
414 struct hpi_message hm;
415 struct hpi_response hr;
416 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
417 HPI_ADAPTER_GET_ASSERT);
418 hm.adapter_index = adapter_index;
419
420 hpi_send_recv(&hm, &hr);
421
422 *assert_present = 0;
423
424 if (!hr.error) {
425
426 *pline_number = hr.u.a.serial_number;
427
428 *assert_present = hr.u.a.adapter_type;
429
430 *pw_assert_on_dsp = hr.u.a.adapter_index;
431
432 if (!*assert_present && *pline_number)
433
434 *assert_present = 1;
435
436 if (*assert_present) {
437
438 int i;
439 char *src = (char *)hr.u.a.sz_adapter_assert;
440 char *dst = psz_assert;
441
442 for (i = 0; i < HPI_STRING_LEN; i++) {
443 char c;
444 c = *src++;
445 *dst++ = c;
446 if (c == 0)
447 break;
448 }
449
450 } else {
451 *psz_assert = 0;
452 }
453 }
454 return hr.error;
455}
456
457u16 hpi_adapter_test_assert(const struct hpi_hsubsys *ph_subsys,
458 u16 adapter_index, u16 assert_id)
459{
460 struct hpi_message hm;
461 struct hpi_response hr;
462 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
463 HPI_ADAPTER_TEST_ASSERT);
464 hm.adapter_index = adapter_index;
465 hm.u.a.assert_id = assert_id;
466
467 hpi_send_recv(&hm, &hr);
468
469 return hr.error;
470}
471
472u16 hpi_adapter_enable_capability(const struct hpi_hsubsys *ph_subsys,
473 u16 adapter_index, u16 capability, u32 key)
474{
475 struct hpi_message hm;
476 struct hpi_response hr;
477 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
478 HPI_ADAPTER_ENABLE_CAPABILITY);
479 hm.adapter_index = adapter_index;
480 hm.u.a.assert_id = capability;
481 hm.u.a.adapter_mode = key;
482
483 hpi_send_recv(&hm, &hr);
484
485 return hr.error;
486}
487
488u16 hpi_adapter_self_test(const struct hpi_hsubsys *ph_subsys,
489 u16 adapter_index)
490{
491 struct hpi_message hm;
492 struct hpi_response hr;
493 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
494 HPI_ADAPTER_SELFTEST);
495 hm.adapter_index = adapter_index;
496 hpi_send_recv(&hm, &hr);
497 return hr.error;
498}
499
500u16 hpi_adapter_debug_read(const struct hpi_hsubsys *ph_subsys,
501 u16 adapter_index, u32 dsp_address, char *p_buffer, int *count_bytes)
502{
503 struct hpi_message hm;
504 struct hpi_response hr;
505 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
506 HPI_ADAPTER_DEBUG_READ);
507
508 hr.size = sizeof(hr);
509
510 hm.adapter_index = adapter_index;
511 hm.u.ax.debug_read.dsp_address = dsp_address;
512
513 if (*count_bytes > (int)sizeof(hr.u.bytes))
514 *count_bytes = sizeof(hr.u.bytes);
515
516 hm.u.ax.debug_read.count_bytes = *count_bytes;
517
518 hpi_send_recv(&hm, &hr);
519
520 if (!hr.error) {
521 *count_bytes = hr.size - 12;
522 memcpy(p_buffer, &hr.u.bytes, *count_bytes);
523 } else
524 *count_bytes = 0;
525 return hr.error;
526}
527
528u16 hpi_adapter_set_property(const struct hpi_hsubsys *ph_subsys,
529 u16 adapter_index, u16 property, u16 parameter1, u16 parameter2)
530{ 268{
531 struct hpi_message hm; 269 struct hpi_message hm;
532 struct hpi_response hr; 270 struct hpi_response hr;
@@ -542,9 +280,8 @@ u16 hpi_adapter_set_property(const struct hpi_hsubsys *ph_subsys,
542 return hr.error; 280 return hr.error;
543} 281}
544 282
545u16 hpi_adapter_get_property(const struct hpi_hsubsys *ph_subsys, 283u16 hpi_adapter_get_property(u16 adapter_index, u16 property,
546 u16 adapter_index, u16 property, u16 *pw_parameter1, 284 u16 *pw_parameter1, u16 *pw_parameter2)
547 u16 *pw_parameter2)
548{ 285{
549 struct hpi_message hm; 286 struct hpi_message hm;
550 struct hpi_response hr; 287 struct hpi_response hr;
@@ -564,9 +301,8 @@ u16 hpi_adapter_get_property(const struct hpi_hsubsys *ph_subsys,
564 return hr.error; 301 return hr.error;
565} 302}
566 303
567u16 hpi_adapter_enumerate_property(const struct hpi_hsubsys *ph_subsys, 304u16 hpi_adapter_enumerate_property(u16 adapter_index, u16 index,
568 u16 adapter_index, u16 index, u16 what_to_enumerate, 305 u16 what_to_enumerate, u16 property_index, u32 *psetting)
569 u16 property_index, u32 *psetting)
570{ 306{
571 return 0; 307 return 0;
572} 308}
@@ -574,7 +310,7 @@ u16 hpi_adapter_enumerate_property(const struct hpi_hsubsys *ph_subsys,
574u16 hpi_format_create(struct hpi_format *p_format, u16 channels, u16 format, 310u16 hpi_format_create(struct hpi_format *p_format, u16 channels, u16 format,
575 u32 sample_rate, u32 bit_rate, u32 attributes) 311 u32 sample_rate, u32 bit_rate, u32 attributes)
576{ 312{
577 u16 error = 0; 313 u16 err = 0;
578 struct hpi_msg_format fmt; 314 struct hpi_msg_format fmt;
579 315
580 switch (channels) { 316 switch (channels) {
@@ -586,8 +322,8 @@ u16 hpi_format_create(struct hpi_format *p_format, u16 channels, u16 format,
586 case 16: 322 case 16:
587 break; 323 break;
588 default: 324 default:
589 error = HPI_ERROR_INVALID_CHANNELS; 325 err = HPI_ERROR_INVALID_CHANNELS;
590 return error; 326 return err;
591 } 327 }
592 fmt.channels = channels; 328 fmt.channels = channels;
593 329
@@ -610,17 +346,17 @@ u16 hpi_format_create(struct hpi_format *p_format, u16 channels, u16 format,
610 case HPI_FORMAT_OEM2: 346 case HPI_FORMAT_OEM2:
611 break; 347 break;
612 default: 348 default:
613 error = HPI_ERROR_INVALID_FORMAT; 349 err = HPI_ERROR_INVALID_FORMAT;
614 return error; 350 return err;
615 } 351 }
616 fmt.format = format; 352 fmt.format = format;
617 353
618 if (sample_rate < 8000L) { 354 if (sample_rate < 8000L) {
619 error = HPI_ERROR_INCOMPATIBLE_SAMPLERATE; 355 err = HPI_ERROR_INCOMPATIBLE_SAMPLERATE;
620 sample_rate = 8000L; 356 sample_rate = 8000L;
621 } 357 }
622 if (sample_rate > 200000L) { 358 if (sample_rate > 200000L) {
623 error = HPI_ERROR_INCOMPATIBLE_SAMPLERATE; 359 err = HPI_ERROR_INCOMPATIBLE_SAMPLERATE;
624 sample_rate = 200000L; 360 sample_rate = 200000L;
625 } 361 }
626 fmt.sample_rate = sample_rate; 362 fmt.sample_rate = sample_rate;
@@ -651,10 +387,10 @@ u16 hpi_format_create(struct hpi_format *p_format, u16 channels, u16 format,
651 if ((channels == 1) 387 if ((channels == 1)
652 && (attributes != HPI_MPEG_MODE_DEFAULT)) { 388 && (attributes != HPI_MPEG_MODE_DEFAULT)) {
653 attributes = HPI_MPEG_MODE_DEFAULT; 389 attributes = HPI_MPEG_MODE_DEFAULT;
654 error = HPI_ERROR_INVALID_FORMAT; 390 err = HPI_ERROR_INVALID_FORMAT;
655 } else if (attributes > HPI_MPEG_MODE_DUALCHANNEL) { 391 } else if (attributes > HPI_MPEG_MODE_DUALCHANNEL) {
656 attributes = HPI_MPEG_MODE_DEFAULT; 392 attributes = HPI_MPEG_MODE_DEFAULT;
657 error = HPI_ERROR_INVALID_FORMAT; 393 err = HPI_ERROR_INVALID_FORMAT;
658 } 394 }
659 fmt.attributes = attributes; 395 fmt.attributes = attributes;
660 break; 396 break;
@@ -663,7 +399,7 @@ u16 hpi_format_create(struct hpi_format *p_format, u16 channels, u16 format,
663 } 399 }
664 400
665 hpi_msg_to_format(p_format, &fmt); 401 hpi_msg_to_format(p_format, &fmt);
666 return error; 402 return err;
667} 403}
668 404
669u16 hpi_stream_estimate_buffer_size(struct hpi_format *p_format, 405u16 hpi_stream_estimate_buffer_size(struct hpi_format *p_format,
@@ -712,8 +448,8 @@ u16 hpi_stream_estimate_buffer_size(struct hpi_format *p_format,
712 return 0; 448 return 0;
713} 449}
714 450
715u16 hpi_outstream_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index, 451u16 hpi_outstream_open(u16 adapter_index, u16 outstream_index,
716 u16 outstream_index, u32 *ph_outstream) 452 u32 *ph_outstream)
717{ 453{
718 struct hpi_message hm; 454 struct hpi_message hm;
719 struct hpi_response hr; 455 struct hpi_response hr;
@@ -733,38 +469,41 @@ u16 hpi_outstream_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
733 return hr.error; 469 return hr.error;
734} 470}
735 471
736u16 hpi_outstream_close(const struct hpi_hsubsys *ph_subsys, u32 h_outstream) 472u16 hpi_outstream_close(u32 h_outstream)
737{ 473{
738 struct hpi_message hm; 474 struct hpi_message hm;
739 struct hpi_response hr; 475 struct hpi_response hr;
740 476
741 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 477 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
742 HPI_OSTREAM_HOSTBUFFER_FREE); 478 HPI_OSTREAM_HOSTBUFFER_FREE);
743 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); 479 if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
480 return HPI_ERROR_INVALID_HANDLE;
481
744 hpi_send_recv(&hm, &hr); 482 hpi_send_recv(&hm, &hr);
745 483
746 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 484 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
747 HPI_OSTREAM_GROUP_RESET); 485 HPI_OSTREAM_GROUP_RESET);
748 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); 486 hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index);
749 hpi_send_recv(&hm, &hr); 487 hpi_send_recv(&hm, &hr);
750 488
751 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 489 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
752 HPI_OSTREAM_CLOSE); 490 HPI_OSTREAM_CLOSE);
753 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); 491 hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index);
754 hpi_send_recv(&hm, &hr); 492 hpi_send_recv(&hm, &hr);
755 493
756 return hr.error; 494 return hr.error;
757} 495}
758 496
759u16 hpi_outstream_get_info_ex(const struct hpi_hsubsys *ph_subsys, 497u16 hpi_outstream_get_info_ex(u32 h_outstream, u16 *pw_state,
760 u32 h_outstream, u16 *pw_state, u32 *pbuffer_size, u32 *pdata_to_play, 498 u32 *pbuffer_size, u32 *pdata_to_play, u32 *psamples_played,
761 u32 *psamples_played, u32 *pauxiliary_data_to_play) 499 u32 *pauxiliary_data_to_play)
762{ 500{
763 struct hpi_message hm; 501 struct hpi_message hm;
764 struct hpi_response hr; 502 struct hpi_response hr;
765 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 503 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
766 HPI_OSTREAM_GET_INFO); 504 HPI_OSTREAM_GET_INFO);
767 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); 505 if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
506 return HPI_ERROR_INVALID_HANDLE;
768 507
769 hpi_send_recv(&hm, &hr); 508 hpi_send_recv(&hm, &hr);
770 509
@@ -782,15 +521,15 @@ u16 hpi_outstream_get_info_ex(const struct hpi_hsubsys *ph_subsys,
782 return hr.error; 521 return hr.error;
783} 522}
784 523
785u16 hpi_outstream_write_buf(const struct hpi_hsubsys *ph_subsys, 524u16 hpi_outstream_write_buf(u32 h_outstream, const u8 *pb_data,
786 u32 h_outstream, const u8 *pb_data, u32 bytes_to_write, 525 u32 bytes_to_write, const struct hpi_format *p_format)
787 const struct hpi_format *p_format)
788{ 526{
789 struct hpi_message hm; 527 struct hpi_message hm;
790 struct hpi_response hr; 528 struct hpi_response hr;
791 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 529 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
792 HPI_OSTREAM_WRITE); 530 HPI_OSTREAM_WRITE);
793 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); 531 if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
532 return HPI_ERROR_INVALID_HANDLE;
794 hm.u.d.u.data.pb_data = (u8 *)pb_data; 533 hm.u.d.u.data.pb_data = (u8 *)pb_data;
795 hm.u.d.u.data.data_size = bytes_to_write; 534 hm.u.d.u.data.data_size = bytes_to_write;
796 535
@@ -801,82 +540,85 @@ u16 hpi_outstream_write_buf(const struct hpi_hsubsys *ph_subsys,
801 return hr.error; 540 return hr.error;
802} 541}
803 542
804u16 hpi_outstream_start(const struct hpi_hsubsys *ph_subsys, u32 h_outstream) 543u16 hpi_outstream_start(u32 h_outstream)
805{ 544{
806 struct hpi_message hm; 545 struct hpi_message hm;
807 struct hpi_response hr; 546 struct hpi_response hr;
808 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 547 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
809 HPI_OSTREAM_START); 548 HPI_OSTREAM_START);
810 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); 549 if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
550 return HPI_ERROR_INVALID_HANDLE;
811 551
812 hpi_send_recv(&hm, &hr); 552 hpi_send_recv(&hm, &hr);
813 553
814 return hr.error; 554 return hr.error;
815} 555}
816 556
817u16 hpi_outstream_wait_start(const struct hpi_hsubsys *ph_subsys, 557u16 hpi_outstream_wait_start(u32 h_outstream)
818 u32 h_outstream)
819{ 558{
820 struct hpi_message hm; 559 struct hpi_message hm;
821 struct hpi_response hr; 560 struct hpi_response hr;
822 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 561 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
823 HPI_OSTREAM_WAIT_START); 562 HPI_OSTREAM_WAIT_START);
824 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); 563 if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
564 return HPI_ERROR_INVALID_HANDLE;
825 565
826 hpi_send_recv(&hm, &hr); 566 hpi_send_recv(&hm, &hr);
827 567
828 return hr.error; 568 return hr.error;
829} 569}
830 570
831u16 hpi_outstream_stop(const struct hpi_hsubsys *ph_subsys, u32 h_outstream) 571u16 hpi_outstream_stop(u32 h_outstream)
832{ 572{
833 struct hpi_message hm; 573 struct hpi_message hm;
834 struct hpi_response hr; 574 struct hpi_response hr;
835 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 575 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
836 HPI_OSTREAM_STOP); 576 HPI_OSTREAM_STOP);
837 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); 577 if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
578 return HPI_ERROR_INVALID_HANDLE;
838 579
839 hpi_send_recv(&hm, &hr); 580 hpi_send_recv(&hm, &hr);
840 581
841 return hr.error; 582 return hr.error;
842} 583}
843 584
844u16 hpi_outstream_sinegen(const struct hpi_hsubsys *ph_subsys, 585u16 hpi_outstream_sinegen(u32 h_outstream)
845 u32 h_outstream)
846{ 586{
847 struct hpi_message hm; 587 struct hpi_message hm;
848 struct hpi_response hr; 588 struct hpi_response hr;
849 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 589 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
850 HPI_OSTREAM_SINEGEN); 590 HPI_OSTREAM_SINEGEN);
851 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); 591 if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
592 return HPI_ERROR_INVALID_HANDLE;
852 593
853 hpi_send_recv(&hm, &hr); 594 hpi_send_recv(&hm, &hr);
854 595
855 return hr.error; 596 return hr.error;
856} 597}
857 598
858u16 hpi_outstream_reset(const struct hpi_hsubsys *ph_subsys, u32 h_outstream) 599u16 hpi_outstream_reset(u32 h_outstream)
859{ 600{
860 struct hpi_message hm; 601 struct hpi_message hm;
861 struct hpi_response hr; 602 struct hpi_response hr;
862 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 603 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
863 HPI_OSTREAM_RESET); 604 HPI_OSTREAM_RESET);
864 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); 605 if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
606 return HPI_ERROR_INVALID_HANDLE;
865 607
866 hpi_send_recv(&hm, &hr); 608 hpi_send_recv(&hm, &hr);
867 609
868 return hr.error; 610 return hr.error;
869} 611}
870 612
871u16 hpi_outstream_query_format(const struct hpi_hsubsys *ph_subsys, 613u16 hpi_outstream_query_format(u32 h_outstream, struct hpi_format *p_format)
872 u32 h_outstream, struct hpi_format *p_format)
873{ 614{
874 struct hpi_message hm; 615 struct hpi_message hm;
875 struct hpi_response hr; 616 struct hpi_response hr;
876 617
877 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 618 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
878 HPI_OSTREAM_QUERY_FORMAT); 619 HPI_OSTREAM_QUERY_FORMAT);
879 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); 620 if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
621 return HPI_ERROR_INVALID_HANDLE;
880 622
881 hpi_format_to_msg(&hm.u.d.u.data.format, p_format); 623 hpi_format_to_msg(&hm.u.d.u.data.format, p_format);
882 624
@@ -885,15 +627,15 @@ u16 hpi_outstream_query_format(const struct hpi_hsubsys *ph_subsys,
885 return hr.error; 627 return hr.error;
886} 628}
887 629
888u16 hpi_outstream_set_format(const struct hpi_hsubsys *ph_subsys, 630u16 hpi_outstream_set_format(u32 h_outstream, struct hpi_format *p_format)
889 u32 h_outstream, struct hpi_format *p_format)
890{ 631{
891 struct hpi_message hm; 632 struct hpi_message hm;
892 struct hpi_response hr; 633 struct hpi_response hr;
893 634
894 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 635 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
895 HPI_OSTREAM_SET_FORMAT); 636 HPI_OSTREAM_SET_FORMAT);
896 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); 637 if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
638 return HPI_ERROR_INVALID_HANDLE;
897 639
898 hpi_format_to_msg(&hm.u.d.u.data.format, p_format); 640 hpi_format_to_msg(&hm.u.d.u.data.format, p_format);
899 641
@@ -902,15 +644,15 @@ u16 hpi_outstream_set_format(const struct hpi_hsubsys *ph_subsys,
902 return hr.error; 644 return hr.error;
903} 645}
904 646
905u16 hpi_outstream_set_velocity(const struct hpi_hsubsys *ph_subsys, 647u16 hpi_outstream_set_velocity(u32 h_outstream, short velocity)
906 u32 h_outstream, short velocity)
907{ 648{
908 struct hpi_message hm; 649 struct hpi_message hm;
909 struct hpi_response hr; 650 struct hpi_response hr;
910 651
911 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 652 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
912 HPI_OSTREAM_SET_VELOCITY); 653 HPI_OSTREAM_SET_VELOCITY);
913 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); 654 if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
655 return HPI_ERROR_INVALID_HANDLE;
914 hm.u.d.u.velocity = velocity; 656 hm.u.d.u.velocity = velocity;
915 657
916 hpi_send_recv(&hm, &hr); 658 hpi_send_recv(&hm, &hr);
@@ -918,15 +660,16 @@ u16 hpi_outstream_set_velocity(const struct hpi_hsubsys *ph_subsys,
918 return hr.error; 660 return hr.error;
919} 661}
920 662
921u16 hpi_outstream_set_punch_in_out(const struct hpi_hsubsys *ph_subsys, 663u16 hpi_outstream_set_punch_in_out(u32 h_outstream, u32 punch_in_sample,
922 u32 h_outstream, u32 punch_in_sample, u32 punch_out_sample) 664 u32 punch_out_sample)
923{ 665{
924 struct hpi_message hm; 666 struct hpi_message hm;
925 struct hpi_response hr; 667 struct hpi_response hr;
926 668
927 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 669 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
928 HPI_OSTREAM_SET_PUNCHINOUT); 670 HPI_OSTREAM_SET_PUNCHINOUT);
929 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); 671 if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
672 return HPI_ERROR_INVALID_HANDLE;
930 673
931 hm.u.d.u.pio.punch_in_sample = punch_in_sample; 674 hm.u.d.u.pio.punch_in_sample = punch_in_sample;
932 hm.u.d.u.pio.punch_out_sample = punch_out_sample; 675 hm.u.d.u.pio.punch_out_sample = punch_out_sample;
@@ -936,29 +679,29 @@ u16 hpi_outstream_set_punch_in_out(const struct hpi_hsubsys *ph_subsys,
936 return hr.error; 679 return hr.error;
937} 680}
938 681
939u16 hpi_outstream_ancillary_reset(const struct hpi_hsubsys *ph_subsys, 682u16 hpi_outstream_ancillary_reset(u32 h_outstream, u16 mode)
940 u32 h_outstream, u16 mode)
941{ 683{
942 struct hpi_message hm; 684 struct hpi_message hm;
943 struct hpi_response hr; 685 struct hpi_response hr;
944 686
945 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 687 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
946 HPI_OSTREAM_ANC_RESET); 688 HPI_OSTREAM_ANC_RESET);
947 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); 689 if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
690 return HPI_ERROR_INVALID_HANDLE;
948 hm.u.d.u.data.format.channels = mode; 691 hm.u.d.u.data.format.channels = mode;
949 hpi_send_recv(&hm, &hr); 692 hpi_send_recv(&hm, &hr);
950 return hr.error; 693 return hr.error;
951} 694}
952 695
953u16 hpi_outstream_ancillary_get_info(const struct hpi_hsubsys *ph_subsys, 696u16 hpi_outstream_ancillary_get_info(u32 h_outstream, u32 *pframes_available)
954 u32 h_outstream, u32 *pframes_available)
955{ 697{
956 struct hpi_message hm; 698 struct hpi_message hm;
957 struct hpi_response hr; 699 struct hpi_response hr;
958 700
959 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 701 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
960 HPI_OSTREAM_ANC_GET_INFO); 702 HPI_OSTREAM_ANC_GET_INFO);
961 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); 703 if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
704 return HPI_ERROR_INVALID_HANDLE;
962 hpi_send_recv(&hm, &hr); 705 hpi_send_recv(&hm, &hr);
963 if (hr.error == 0) { 706 if (hr.error == 0) {
964 if (pframes_available) 707 if (pframes_available)
@@ -969,8 +712,8 @@ u16 hpi_outstream_ancillary_get_info(const struct hpi_hsubsys *ph_subsys,
969 return hr.error; 712 return hr.error;
970} 713}
971 714
972u16 hpi_outstream_ancillary_read(const struct hpi_hsubsys *ph_subsys, 715u16 hpi_outstream_ancillary_read(u32 h_outstream,
973 u32 h_outstream, struct hpi_anc_frame *p_anc_frame_buffer, 716 struct hpi_anc_frame *p_anc_frame_buffer,
974 u32 anc_frame_buffer_size_in_bytes, 717 u32 anc_frame_buffer_size_in_bytes,
975 u32 number_of_ancillary_frames_to_read) 718 u32 number_of_ancillary_frames_to_read)
976{ 719{
@@ -979,7 +722,8 @@ u16 hpi_outstream_ancillary_read(const struct hpi_hsubsys *ph_subsys,
979 722
980 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 723 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
981 HPI_OSTREAM_ANC_READ); 724 HPI_OSTREAM_ANC_READ);
982 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); 725 if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
726 return HPI_ERROR_INVALID_HANDLE;
983 hm.u.d.u.data.pb_data = (u8 *)p_anc_frame_buffer; 727 hm.u.d.u.data.pb_data = (u8 *)p_anc_frame_buffer;
984 hm.u.d.u.data.data_size = 728 hm.u.d.u.data.data_size =
985 number_of_ancillary_frames_to_read * 729 number_of_ancillary_frames_to_read *
@@ -987,19 +731,19 @@ u16 hpi_outstream_ancillary_read(const struct hpi_hsubsys *ph_subsys,
987 if (hm.u.d.u.data.data_size <= anc_frame_buffer_size_in_bytes) 731 if (hm.u.d.u.data.data_size <= anc_frame_buffer_size_in_bytes)
988 hpi_send_recv(&hm, &hr); 732 hpi_send_recv(&hm, &hr);
989 else 733 else
990 hr.error = HPI_ERROR_INVALID_DATA_TRANSFER; 734 hr.error = HPI_ERROR_INVALID_DATASIZE;
991 return hr.error; 735 return hr.error;
992} 736}
993 737
994u16 hpi_outstream_set_time_scale(const struct hpi_hsubsys *ph_subsys, 738u16 hpi_outstream_set_time_scale(u32 h_outstream, u32 time_scale)
995 u32 h_outstream, u32 time_scale)
996{ 739{
997 struct hpi_message hm; 740 struct hpi_message hm;
998 struct hpi_response hr; 741 struct hpi_response hr;
999 742
1000 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 743 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
1001 HPI_OSTREAM_SET_TIMESCALE); 744 HPI_OSTREAM_SET_TIMESCALE);
1002 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); 745 if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
746 return HPI_ERROR_INVALID_HANDLE;
1003 747
1004 hm.u.d.u.time_scale = time_scale; 748 hm.u.d.u.time_scale = time_scale;
1005 749
@@ -1008,22 +752,21 @@ u16 hpi_outstream_set_time_scale(const struct hpi_hsubsys *ph_subsys,
1008 return hr.error; 752 return hr.error;
1009} 753}
1010 754
1011u16 hpi_outstream_host_buffer_allocate(const struct hpi_hsubsys *ph_subsys, 755u16 hpi_outstream_host_buffer_allocate(u32 h_outstream, u32 size_in_bytes)
1012 u32 h_outstream, u32 size_in_bytes)
1013{ 756{
1014 struct hpi_message hm; 757 struct hpi_message hm;
1015 struct hpi_response hr; 758 struct hpi_response hr;
1016 759
1017 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 760 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
1018 HPI_OSTREAM_HOSTBUFFER_ALLOC); 761 HPI_OSTREAM_HOSTBUFFER_ALLOC);
1019 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); 762 if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
763 return HPI_ERROR_INVALID_HANDLE;
1020 hm.u.d.u.data.data_size = size_in_bytes; 764 hm.u.d.u.data.data_size = size_in_bytes;
1021 hpi_send_recv(&hm, &hr); 765 hpi_send_recv(&hm, &hr);
1022 return hr.error; 766 return hr.error;
1023} 767}
1024 768
1025u16 hpi_outstream_host_buffer_get_info(const struct hpi_hsubsys *ph_subsys, 769u16 hpi_outstream_host_buffer_get_info(u32 h_outstream, u8 **pp_buffer,
1026 u32 h_outstream, u8 **pp_buffer,
1027 struct hpi_hostbuffer_status **pp_status) 770 struct hpi_hostbuffer_status **pp_status)
1028{ 771{
1029 struct hpi_message hm; 772 struct hpi_message hm;
@@ -1031,7 +774,8 @@ u16 hpi_outstream_host_buffer_get_info(const struct hpi_hsubsys *ph_subsys,
1031 774
1032 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 775 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
1033 HPI_OSTREAM_HOSTBUFFER_GET_INFO); 776 HPI_OSTREAM_HOSTBUFFER_GET_INFO);
1034 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); 777 if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
778 return HPI_ERROR_INVALID_HANDLE;
1035 hpi_send_recv(&hm, &hr); 779 hpi_send_recv(&hm, &hr);
1036 780
1037 if (hr.error == 0) { 781 if (hr.error == 0) {
@@ -1043,21 +787,20 @@ u16 hpi_outstream_host_buffer_get_info(const struct hpi_hsubsys *ph_subsys,
1043 return hr.error; 787 return hr.error;
1044} 788}
1045 789
1046u16 hpi_outstream_host_buffer_free(const struct hpi_hsubsys *ph_subsys, 790u16 hpi_outstream_host_buffer_free(u32 h_outstream)
1047 u32 h_outstream)
1048{ 791{
1049 struct hpi_message hm; 792 struct hpi_message hm;
1050 struct hpi_response hr; 793 struct hpi_response hr;
1051 794
1052 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 795 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
1053 HPI_OSTREAM_HOSTBUFFER_FREE); 796 HPI_OSTREAM_HOSTBUFFER_FREE);
1054 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); 797 if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
798 return HPI_ERROR_INVALID_HANDLE;
1055 hpi_send_recv(&hm, &hr); 799 hpi_send_recv(&hm, &hr);
1056 return hr.error; 800 return hr.error;
1057} 801}
1058 802
1059u16 hpi_outstream_group_add(const struct hpi_hsubsys *ph_subsys, 803u16 hpi_outstream_group_add(u32 h_outstream, u32 h_stream)
1060 u32 h_outstream, u32 h_stream)
1061{ 804{
1062 struct hpi_message hm; 805 struct hpi_message hm;
1063 struct hpi_response hr; 806 struct hpi_response hr;
@@ -1066,22 +809,22 @@ u16 hpi_outstream_group_add(const struct hpi_hsubsys *ph_subsys,
1066 809
1067 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 810 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
1068 HPI_OSTREAM_GROUP_ADD); 811 HPI_OSTREAM_GROUP_ADD);
1069 hr.error = 0; 812
1070 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); 813 if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
814 return HPI_ERROR_INVALID_HANDLE;
815
816 if (hpi_handle_indexes(h_stream, &adapter,
817 &hm.u.d.u.stream.stream_index))
818 return HPI_ERROR_INVALID_HANDLE;
819
1071 c_obj_type = hpi_handle_object(h_stream); 820 c_obj_type = hpi_handle_object(h_stream);
1072 switch (c_obj_type) { 821 switch (c_obj_type) {
1073 case HPI_OBJ_OSTREAM: 822 case HPI_OBJ_OSTREAM:
1074 hm.u.d.u.stream.object_type = HPI_OBJ_OSTREAM;
1075 u32TOINDEXES(h_stream, &adapter,
1076 &hm.u.d.u.stream.stream_index);
1077 break;
1078 case HPI_OBJ_ISTREAM: 823 case HPI_OBJ_ISTREAM:
1079 hm.u.d.u.stream.object_type = HPI_OBJ_ISTREAM; 824 hm.u.d.u.stream.object_type = c_obj_type;
1080 u32TOINDEXES(h_stream, &adapter,
1081 &hm.u.d.u.stream.stream_index);
1082 break; 825 break;
1083 default: 826 default:
1084 return HPI_ERROR_INVALID_STREAM; 827 return HPI_ERROR_INVALID_OBJ;
1085 } 828 }
1086 if (adapter != hm.adapter_index) 829 if (adapter != hm.adapter_index)
1087 return HPI_ERROR_NO_INTERADAPTER_GROUPS; 830 return HPI_ERROR_NO_INTERADAPTER_GROUPS;
@@ -1090,15 +833,16 @@ u16 hpi_outstream_group_add(const struct hpi_hsubsys *ph_subsys,
1090 return hr.error; 833 return hr.error;
1091} 834}
1092 835
1093u16 hpi_outstream_group_get_map(const struct hpi_hsubsys *ph_subsys, 836u16 hpi_outstream_group_get_map(u32 h_outstream, u32 *poutstream_map,
1094 u32 h_outstream, u32 *poutstream_map, u32 *pinstream_map) 837 u32 *pinstream_map)
1095{ 838{
1096 struct hpi_message hm; 839 struct hpi_message hm;
1097 struct hpi_response hr; 840 struct hpi_response hr;
1098 841
1099 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 842 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
1100 HPI_OSTREAM_GROUP_GETMAP); 843 HPI_OSTREAM_GROUP_GETMAP);
1101 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); 844 if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
845 return HPI_ERROR_INVALID_HANDLE;
1102 hpi_send_recv(&hm, &hr); 846 hpi_send_recv(&hm, &hr);
1103 847
1104 if (poutstream_map) 848 if (poutstream_map)
@@ -1109,21 +853,20 @@ u16 hpi_outstream_group_get_map(const struct hpi_hsubsys *ph_subsys,
1109 return hr.error; 853 return hr.error;
1110} 854}
1111 855
1112u16 hpi_outstream_group_reset(const struct hpi_hsubsys *ph_subsys, 856u16 hpi_outstream_group_reset(u32 h_outstream)
1113 u32 h_outstream)
1114{ 857{
1115 struct hpi_message hm; 858 struct hpi_message hm;
1116 struct hpi_response hr; 859 struct hpi_response hr;
1117 860
1118 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 861 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
1119 HPI_OSTREAM_GROUP_RESET); 862 HPI_OSTREAM_GROUP_RESET);
1120 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); 863 if (hpi_handle_indexes(h_outstream, &hm.adapter_index, &hm.obj_index))
864 return HPI_ERROR_INVALID_HANDLE;
1121 hpi_send_recv(&hm, &hr); 865 hpi_send_recv(&hm, &hr);
1122 return hr.error; 866 return hr.error;
1123} 867}
1124 868
1125u16 hpi_instream_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index, 869u16 hpi_instream_open(u16 adapter_index, u16 instream_index, u32 *ph_instream)
1126 u16 instream_index, u32 *ph_instream)
1127{ 870{
1128 struct hpi_message hm; 871 struct hpi_message hm;
1129 struct hpi_response hr; 872 struct hpi_response hr;
@@ -1145,38 +888,40 @@ u16 hpi_instream_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
1145 return hr.error; 888 return hr.error;
1146} 889}
1147 890
1148u16 hpi_instream_close(const struct hpi_hsubsys *ph_subsys, u32 h_instream) 891u16 hpi_instream_close(u32 h_instream)
1149{ 892{
1150 struct hpi_message hm; 893 struct hpi_message hm;
1151 struct hpi_response hr; 894 struct hpi_response hr;
1152 895
1153 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 896 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1154 HPI_ISTREAM_HOSTBUFFER_FREE); 897 HPI_ISTREAM_HOSTBUFFER_FREE);
1155 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index); 898 if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
899 return HPI_ERROR_INVALID_HANDLE;
1156 hpi_send_recv(&hm, &hr); 900 hpi_send_recv(&hm, &hr);
1157 901
1158 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 902 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1159 HPI_ISTREAM_GROUP_RESET); 903 HPI_ISTREAM_GROUP_RESET);
1160 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index); 904 hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index);
1161 hpi_send_recv(&hm, &hr); 905 hpi_send_recv(&hm, &hr);
1162 906
1163 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 907 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1164 HPI_ISTREAM_CLOSE); 908 HPI_ISTREAM_CLOSE);
1165 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index); 909 hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index);
1166 hpi_send_recv(&hm, &hr); 910 hpi_send_recv(&hm, &hr);
1167 911
1168 return hr.error; 912 return hr.error;
1169} 913}
1170 914
1171u16 hpi_instream_query_format(const struct hpi_hsubsys *ph_subsys, 915u16 hpi_instream_query_format(u32 h_instream,
1172 u32 h_instream, const struct hpi_format *p_format) 916 const struct hpi_format *p_format)
1173{ 917{
1174 struct hpi_message hm; 918 struct hpi_message hm;
1175 struct hpi_response hr; 919 struct hpi_response hr;
1176 920
1177 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 921 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1178 HPI_ISTREAM_QUERY_FORMAT); 922 HPI_ISTREAM_QUERY_FORMAT);
1179 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index); 923 if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
924 return HPI_ERROR_INVALID_HANDLE;
1180 hpi_format_to_msg(&hm.u.d.u.data.format, p_format); 925 hpi_format_to_msg(&hm.u.d.u.data.format, p_format);
1181 926
1182 hpi_send_recv(&hm, &hr); 927 hpi_send_recv(&hm, &hr);
@@ -1184,15 +929,15 @@ u16 hpi_instream_query_format(const struct hpi_hsubsys *ph_subsys,
1184 return hr.error; 929 return hr.error;
1185} 930}
1186 931
1187u16 hpi_instream_set_format(const struct hpi_hsubsys *ph_subsys, 932u16 hpi_instream_set_format(u32 h_instream, const struct hpi_format *p_format)
1188 u32 h_instream, const struct hpi_format *p_format)
1189{ 933{
1190 struct hpi_message hm; 934 struct hpi_message hm;
1191 struct hpi_response hr; 935 struct hpi_response hr;
1192 936
1193 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 937 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1194 HPI_ISTREAM_SET_FORMAT); 938 HPI_ISTREAM_SET_FORMAT);
1195 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index); 939 if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
940 return HPI_ERROR_INVALID_HANDLE;
1196 hpi_format_to_msg(&hm.u.d.u.data.format, p_format); 941 hpi_format_to_msg(&hm.u.d.u.data.format, p_format);
1197 942
1198 hpi_send_recv(&hm, &hr); 943 hpi_send_recv(&hm, &hr);
@@ -1200,15 +945,15 @@ u16 hpi_instream_set_format(const struct hpi_hsubsys *ph_subsys,
1200 return hr.error; 945 return hr.error;
1201} 946}
1202 947
1203u16 hpi_instream_read_buf(const struct hpi_hsubsys *ph_subsys, u32 h_instream, 948u16 hpi_instream_read_buf(u32 h_instream, u8 *pb_data, u32 bytes_to_read)
1204 u8 *pb_data, u32 bytes_to_read)
1205{ 949{
1206 struct hpi_message hm; 950 struct hpi_message hm;
1207 struct hpi_response hr; 951 struct hpi_response hr;
1208 952
1209 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 953 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1210 HPI_ISTREAM_READ); 954 HPI_ISTREAM_READ);
1211 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index); 955 if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
956 return HPI_ERROR_INVALID_HANDLE;
1212 hm.u.d.u.data.data_size = bytes_to_read; 957 hm.u.d.u.data.data_size = bytes_to_read;
1213 hm.u.d.u.data.pb_data = pb_data; 958 hm.u.d.u.data.pb_data = pb_data;
1214 959
@@ -1217,72 +962,76 @@ u16 hpi_instream_read_buf(const struct hpi_hsubsys *ph_subsys, u32 h_instream,
1217 return hr.error; 962 return hr.error;
1218} 963}
1219 964
1220u16 hpi_instream_start(const struct hpi_hsubsys *ph_subsys, u32 h_instream) 965u16 hpi_instream_start(u32 h_instream)
1221{ 966{
1222 struct hpi_message hm; 967 struct hpi_message hm;
1223 struct hpi_response hr; 968 struct hpi_response hr;
1224 969
1225 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 970 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1226 HPI_ISTREAM_START); 971 HPI_ISTREAM_START);
1227 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index); 972 if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
973 return HPI_ERROR_INVALID_HANDLE;
1228 974
1229 hpi_send_recv(&hm, &hr); 975 hpi_send_recv(&hm, &hr);
1230 976
1231 return hr.error; 977 return hr.error;
1232} 978}
1233 979
1234u16 hpi_instream_wait_start(const struct hpi_hsubsys *ph_subsys, 980u16 hpi_instream_wait_start(u32 h_instream)
1235 u32 h_instream)
1236{ 981{
1237 struct hpi_message hm; 982 struct hpi_message hm;
1238 struct hpi_response hr; 983 struct hpi_response hr;
1239 984
1240 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 985 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1241 HPI_ISTREAM_WAIT_START); 986 HPI_ISTREAM_WAIT_START);
1242 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index); 987 if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
988 return HPI_ERROR_INVALID_HANDLE;
1243 989
1244 hpi_send_recv(&hm, &hr); 990 hpi_send_recv(&hm, &hr);
1245 991
1246 return hr.error; 992 return hr.error;
1247} 993}
1248 994
1249u16 hpi_instream_stop(const struct hpi_hsubsys *ph_subsys, u32 h_instream) 995u16 hpi_instream_stop(u32 h_instream)
1250{ 996{
1251 struct hpi_message hm; 997 struct hpi_message hm;
1252 struct hpi_response hr; 998 struct hpi_response hr;
1253 999
1254 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 1000 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1255 HPI_ISTREAM_STOP); 1001 HPI_ISTREAM_STOP);
1256 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index); 1002 if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
1003 return HPI_ERROR_INVALID_HANDLE;
1257 1004
1258 hpi_send_recv(&hm, &hr); 1005 hpi_send_recv(&hm, &hr);
1259 1006
1260 return hr.error; 1007 return hr.error;
1261} 1008}
1262 1009
1263u16 hpi_instream_reset(const struct hpi_hsubsys *ph_subsys, u32 h_instream) 1010u16 hpi_instream_reset(u32 h_instream)
1264{ 1011{
1265 struct hpi_message hm; 1012 struct hpi_message hm;
1266 struct hpi_response hr; 1013 struct hpi_response hr;
1267 1014
1268 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 1015 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1269 HPI_ISTREAM_RESET); 1016 HPI_ISTREAM_RESET);
1270 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index); 1017 if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
1018 return HPI_ERROR_INVALID_HANDLE;
1271 1019
1272 hpi_send_recv(&hm, &hr); 1020 hpi_send_recv(&hm, &hr);
1273 1021
1274 return hr.error; 1022 return hr.error;
1275} 1023}
1276 1024
1277u16 hpi_instream_get_info_ex(const struct hpi_hsubsys *ph_subsys, 1025u16 hpi_instream_get_info_ex(u32 h_instream, u16 *pw_state, u32 *pbuffer_size,
1278 u32 h_instream, u16 *pw_state, u32 *pbuffer_size, u32 *pdata_recorded, 1026 u32 *pdata_recorded, u32 *psamples_recorded,
1279 u32 *psamples_recorded, u32 *pauxiliary_data_recorded) 1027 u32 *pauxiliary_data_recorded)
1280{ 1028{
1281 struct hpi_message hm; 1029 struct hpi_message hm;
1282 struct hpi_response hr; 1030 struct hpi_response hr;
1283 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 1031 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1284 HPI_ISTREAM_GET_INFO); 1032 HPI_ISTREAM_GET_INFO);
1285 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index); 1033 if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
1034 return HPI_ERROR_INVALID_HANDLE;
1286 1035
1287 hpi_send_recv(&hm, &hr); 1036 hpi_send_recv(&hm, &hr);
1288 1037
@@ -1300,15 +1049,15 @@ u16 hpi_instream_get_info_ex(const struct hpi_hsubsys *ph_subsys,
1300 return hr.error; 1049 return hr.error;
1301} 1050}
1302 1051
1303u16 hpi_instream_ancillary_reset(const struct hpi_hsubsys *ph_subsys, 1052u16 hpi_instream_ancillary_reset(u32 h_instream, u16 bytes_per_frame,
1304 u32 h_instream, u16 bytes_per_frame, u16 mode, u16 alignment, 1053 u16 mode, u16 alignment, u16 idle_bit)
1305 u16 idle_bit)
1306{ 1054{
1307 struct hpi_message hm; 1055 struct hpi_message hm;
1308 struct hpi_response hr; 1056 struct hpi_response hr;
1309 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 1057 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1310 HPI_ISTREAM_ANC_RESET); 1058 HPI_ISTREAM_ANC_RESET);
1311 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index); 1059 if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
1060 return HPI_ERROR_INVALID_HANDLE;
1312 hm.u.d.u.data.format.attributes = bytes_per_frame; 1061 hm.u.d.u.data.format.attributes = bytes_per_frame;
1313 hm.u.d.u.data.format.format = (mode << 8) | (alignment & 0xff); 1062 hm.u.d.u.data.format.format = (mode << 8) | (alignment & 0xff);
1314 hm.u.d.u.data.format.channels = idle_bit; 1063 hm.u.d.u.data.format.channels = idle_bit;
@@ -1316,14 +1065,14 @@ u16 hpi_instream_ancillary_reset(const struct hpi_hsubsys *ph_subsys,
1316 return hr.error; 1065 return hr.error;
1317} 1066}
1318 1067
1319u16 hpi_instream_ancillary_get_info(const struct hpi_hsubsys *ph_subsys, 1068u16 hpi_instream_ancillary_get_info(u32 h_instream, u32 *pframe_space)
1320 u32 h_instream, u32 *pframe_space)
1321{ 1069{
1322 struct hpi_message hm; 1070 struct hpi_message hm;
1323 struct hpi_response hr; 1071 struct hpi_response hr;
1324 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 1072 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1325 HPI_ISTREAM_ANC_GET_INFO); 1073 HPI_ISTREAM_ANC_GET_INFO);
1326 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index); 1074 if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
1075 return HPI_ERROR_INVALID_HANDLE;
1327 hpi_send_recv(&hm, &hr); 1076 hpi_send_recv(&hm, &hr);
1328 if (pframe_space) 1077 if (pframe_space)
1329 *pframe_space = 1078 *pframe_space =
@@ -1333,8 +1082,8 @@ u16 hpi_instream_ancillary_get_info(const struct hpi_hsubsys *ph_subsys,
1333 return hr.error; 1082 return hr.error;
1334} 1083}
1335 1084
1336u16 hpi_instream_ancillary_write(const struct hpi_hsubsys *ph_subsys, 1085u16 hpi_instream_ancillary_write(u32 h_instream,
1337 u32 h_instream, const struct hpi_anc_frame *p_anc_frame_buffer, 1086 const struct hpi_anc_frame *p_anc_frame_buffer,
1338 u32 anc_frame_buffer_size_in_bytes, 1087 u32 anc_frame_buffer_size_in_bytes,
1339 u32 number_of_ancillary_frames_to_write) 1088 u32 number_of_ancillary_frames_to_write)
1340{ 1089{
@@ -1343,7 +1092,8 @@ u16 hpi_instream_ancillary_write(const struct hpi_hsubsys *ph_subsys,
1343 1092
1344 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 1093 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1345 HPI_ISTREAM_ANC_WRITE); 1094 HPI_ISTREAM_ANC_WRITE);
1346 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index); 1095 if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
1096 return HPI_ERROR_INVALID_HANDLE;
1347 hm.u.d.u.data.pb_data = (u8 *)p_anc_frame_buffer; 1097 hm.u.d.u.data.pb_data = (u8 *)p_anc_frame_buffer;
1348 hm.u.d.u.data.data_size = 1098 hm.u.d.u.data.data_size =
1349 number_of_ancillary_frames_to_write * 1099 number_of_ancillary_frames_to_write *
@@ -1351,12 +1101,11 @@ u16 hpi_instream_ancillary_write(const struct hpi_hsubsys *ph_subsys,
1351 if (hm.u.d.u.data.data_size <= anc_frame_buffer_size_in_bytes) 1101 if (hm.u.d.u.data.data_size <= anc_frame_buffer_size_in_bytes)
1352 hpi_send_recv(&hm, &hr); 1102 hpi_send_recv(&hm, &hr);
1353 else 1103 else
1354 hr.error = HPI_ERROR_INVALID_DATA_TRANSFER; 1104 hr.error = HPI_ERROR_INVALID_DATASIZE;
1355 return hr.error; 1105 return hr.error;
1356} 1106}
1357 1107
1358u16 hpi_instream_host_buffer_allocate(const struct hpi_hsubsys *ph_subsys, 1108u16 hpi_instream_host_buffer_allocate(u32 h_instream, u32 size_in_bytes)
1359 u32 h_instream, u32 size_in_bytes)
1360{ 1109{
1361 1110
1362 struct hpi_message hm; 1111 struct hpi_message hm;
@@ -1364,14 +1113,14 @@ u16 hpi_instream_host_buffer_allocate(const struct hpi_hsubsys *ph_subsys,
1364 1113
1365 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 1114 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1366 HPI_ISTREAM_HOSTBUFFER_ALLOC); 1115 HPI_ISTREAM_HOSTBUFFER_ALLOC);
1367 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index); 1116 if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
1117 return HPI_ERROR_INVALID_HANDLE;
1368 hm.u.d.u.data.data_size = size_in_bytes; 1118 hm.u.d.u.data.data_size = size_in_bytes;
1369 hpi_send_recv(&hm, &hr); 1119 hpi_send_recv(&hm, &hr);
1370 return hr.error; 1120 return hr.error;
1371} 1121}
1372 1122
1373u16 hpi_instream_host_buffer_get_info(const struct hpi_hsubsys *ph_subsys, 1123u16 hpi_instream_host_buffer_get_info(u32 h_instream, u8 **pp_buffer,
1374 u32 h_instream, u8 **pp_buffer,
1375 struct hpi_hostbuffer_status **pp_status) 1124 struct hpi_hostbuffer_status **pp_status)
1376{ 1125{
1377 struct hpi_message hm; 1126 struct hpi_message hm;
@@ -1379,7 +1128,8 @@ u16 hpi_instream_host_buffer_get_info(const struct hpi_hsubsys *ph_subsys,
1379 1128
1380 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 1129 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1381 HPI_ISTREAM_HOSTBUFFER_GET_INFO); 1130 HPI_ISTREAM_HOSTBUFFER_GET_INFO);
1382 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index); 1131 if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
1132 return HPI_ERROR_INVALID_HANDLE;
1383 hpi_send_recv(&hm, &hr); 1133 hpi_send_recv(&hm, &hr);
1384 1134
1385 if (hr.error == 0) { 1135 if (hr.error == 0) {
@@ -1391,8 +1141,7 @@ u16 hpi_instream_host_buffer_get_info(const struct hpi_hsubsys *ph_subsys,
1391 return hr.error; 1141 return hr.error;
1392} 1142}
1393 1143
1394u16 hpi_instream_host_buffer_free(const struct hpi_hsubsys *ph_subsys, 1144u16 hpi_instream_host_buffer_free(u32 h_instream)
1395 u32 h_instream)
1396{ 1145{
1397 1146
1398 struct hpi_message hm; 1147 struct hpi_message hm;
@@ -1400,13 +1149,13 @@ u16 hpi_instream_host_buffer_free(const struct hpi_hsubsys *ph_subsys,
1400 1149
1401 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 1150 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1402 HPI_ISTREAM_HOSTBUFFER_FREE); 1151 HPI_ISTREAM_HOSTBUFFER_FREE);
1403 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index); 1152 if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
1153 return HPI_ERROR_INVALID_HANDLE;
1404 hpi_send_recv(&hm, &hr); 1154 hpi_send_recv(&hm, &hr);
1405 return hr.error; 1155 return hr.error;
1406} 1156}
1407 1157
1408u16 hpi_instream_group_add(const struct hpi_hsubsys *ph_subsys, 1158u16 hpi_instream_group_add(u32 h_instream, u32 h_stream)
1409 u32 h_instream, u32 h_stream)
1410{ 1159{
1411 struct hpi_message hm; 1160 struct hpi_message hm;
1412 struct hpi_response hr; 1161 struct hpi_response hr;
@@ -1416,22 +1165,23 @@ u16 hpi_instream_group_add(const struct hpi_hsubsys *ph_subsys,
1416 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 1165 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1417 HPI_ISTREAM_GROUP_ADD); 1166 HPI_ISTREAM_GROUP_ADD);
1418 hr.error = 0; 1167 hr.error = 0;
1419 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index); 1168
1169 if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
1170 return HPI_ERROR_INVALID_HANDLE;
1171
1172 if (hpi_handle_indexes(h_stream, &adapter,
1173 &hm.u.d.u.stream.stream_index))
1174 return HPI_ERROR_INVALID_HANDLE;
1175
1420 c_obj_type = hpi_handle_object(h_stream); 1176 c_obj_type = hpi_handle_object(h_stream);
1421 1177
1422 switch (c_obj_type) { 1178 switch (c_obj_type) {
1423 case HPI_OBJ_OSTREAM: 1179 case HPI_OBJ_OSTREAM:
1424 hm.u.d.u.stream.object_type = HPI_OBJ_OSTREAM;
1425 u32TOINDEXES(h_stream, &adapter,
1426 &hm.u.d.u.stream.stream_index);
1427 break;
1428 case HPI_OBJ_ISTREAM: 1180 case HPI_OBJ_ISTREAM:
1429 hm.u.d.u.stream.object_type = HPI_OBJ_ISTREAM; 1181 hm.u.d.u.stream.object_type = c_obj_type;
1430 u32TOINDEXES(h_stream, &adapter,
1431 &hm.u.d.u.stream.stream_index);
1432 break; 1182 break;
1433 default: 1183 default:
1434 return HPI_ERROR_INVALID_STREAM; 1184 return HPI_ERROR_INVALID_OBJ;
1435 } 1185 }
1436 1186
1437 if (adapter != hm.adapter_index) 1187 if (adapter != hm.adapter_index)
@@ -1441,15 +1191,16 @@ u16 hpi_instream_group_add(const struct hpi_hsubsys *ph_subsys,
1441 return hr.error; 1191 return hr.error;
1442} 1192}
1443 1193
1444u16 hpi_instream_group_get_map(const struct hpi_hsubsys *ph_subsys, 1194u16 hpi_instream_group_get_map(u32 h_instream, u32 *poutstream_map,
1445 u32 h_instream, u32 *poutstream_map, u32 *pinstream_map) 1195 u32 *pinstream_map)
1446{ 1196{
1447 struct hpi_message hm; 1197 struct hpi_message hm;
1448 struct hpi_response hr; 1198 struct hpi_response hr;
1449 1199
1450 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 1200 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1451 HPI_ISTREAM_HOSTBUFFER_FREE); 1201 HPI_ISTREAM_HOSTBUFFER_FREE);
1452 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index); 1202 if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
1203 return HPI_ERROR_INVALID_HANDLE;
1453 hpi_send_recv(&hm, &hr); 1204 hpi_send_recv(&hm, &hr);
1454 1205
1455 if (poutstream_map) 1206 if (poutstream_map)
@@ -1460,21 +1211,20 @@ u16 hpi_instream_group_get_map(const struct hpi_hsubsys *ph_subsys,
1460 return hr.error; 1211 return hr.error;
1461} 1212}
1462 1213
1463u16 hpi_instream_group_reset(const struct hpi_hsubsys *ph_subsys, 1214u16 hpi_instream_group_reset(u32 h_instream)
1464 u32 h_instream)
1465{ 1215{
1466 struct hpi_message hm; 1216 struct hpi_message hm;
1467 struct hpi_response hr; 1217 struct hpi_response hr;
1468 1218
1469 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 1219 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1470 HPI_ISTREAM_GROUP_RESET); 1220 HPI_ISTREAM_GROUP_RESET);
1471 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index); 1221 if (hpi_handle_indexes(h_instream, &hm.adapter_index, &hm.obj_index))
1222 return HPI_ERROR_INVALID_HANDLE;
1472 hpi_send_recv(&hm, &hr); 1223 hpi_send_recv(&hm, &hr);
1473 return hr.error; 1224 return hr.error;
1474} 1225}
1475 1226
1476u16 hpi_mixer_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index, 1227u16 hpi_mixer_open(u16 adapter_index, u32 *ph_mixer)
1477 u32 *ph_mixer)
1478{ 1228{
1479 struct hpi_message hm; 1229 struct hpi_message hm;
1480 struct hpi_response hr; 1230 struct hpi_response hr;
@@ -1492,25 +1242,29 @@ u16 hpi_mixer_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
1492 return hr.error; 1242 return hr.error;
1493} 1243}
1494 1244
1495u16 hpi_mixer_close(const struct hpi_hsubsys *ph_subsys, u32 h_mixer) 1245u16 hpi_mixer_close(u32 h_mixer)
1496{ 1246{
1497 struct hpi_message hm; 1247 struct hpi_message hm;
1498 struct hpi_response hr; 1248 struct hpi_response hr;
1249
1499 hpi_init_message_response(&hm, &hr, HPI_OBJ_MIXER, HPI_MIXER_CLOSE); 1250 hpi_init_message_response(&hm, &hr, HPI_OBJ_MIXER, HPI_MIXER_CLOSE);
1500 u32TOINDEX(h_mixer, &hm.adapter_index); 1251 if (hpi_handle_indexes(h_mixer, &hm.adapter_index, NULL))
1252 return HPI_ERROR_INVALID_HANDLE;
1253
1501 hpi_send_recv(&hm, &hr); 1254 hpi_send_recv(&hm, &hr);
1502 return hr.error; 1255 return hr.error;
1503} 1256}
1504 1257
1505u16 hpi_mixer_get_control(const struct hpi_hsubsys *ph_subsys, u32 h_mixer, 1258u16 hpi_mixer_get_control(u32 h_mixer, u16 src_node_type,
1506 u16 src_node_type, u16 src_node_type_index, u16 dst_node_type, 1259 u16 src_node_type_index, u16 dst_node_type, u16 dst_node_type_index,
1507 u16 dst_node_type_index, u16 control_type, u32 *ph_control) 1260 u16 control_type, u32 *ph_control)
1508{ 1261{
1509 struct hpi_message hm; 1262 struct hpi_message hm;
1510 struct hpi_response hr; 1263 struct hpi_response hr;
1511 hpi_init_message_response(&hm, &hr, HPI_OBJ_MIXER, 1264 hpi_init_message_response(&hm, &hr, HPI_OBJ_MIXER,
1512 HPI_MIXER_GET_CONTROL); 1265 HPI_MIXER_GET_CONTROL);
1513 u32TOINDEX(h_mixer, &hm.adapter_index); 1266 if (hpi_handle_indexes(h_mixer, &hm.adapter_index, NULL))
1267 return HPI_ERROR_INVALID_HANDLE;
1514 hm.u.m.node_type1 = src_node_type; 1268 hm.u.m.node_type1 = src_node_type;
1515 hm.u.m.node_index1 = src_node_type_index; 1269 hm.u.m.node_index1 = src_node_type_index;
1516 hm.u.m.node_type2 = dst_node_type; 1270 hm.u.m.node_type2 = dst_node_type;
@@ -1528,16 +1282,16 @@ u16 hpi_mixer_get_control(const struct hpi_hsubsys *ph_subsys, u32 h_mixer,
1528 return hr.error; 1282 return hr.error;
1529} 1283}
1530 1284
1531u16 hpi_mixer_get_control_by_index(const struct hpi_hsubsys *ph_subsys, 1285u16 hpi_mixer_get_control_by_index(u32 h_mixer, u16 control_index,
1532 u32 h_mixer, u16 control_index, u16 *pw_src_node_type, 1286 u16 *pw_src_node_type, u16 *pw_src_node_index, u16 *pw_dst_node_type,
1533 u16 *pw_src_node_index, u16 *pw_dst_node_type, u16 *pw_dst_node_index, 1287 u16 *pw_dst_node_index, u16 *pw_control_type, u32 *ph_control)
1534 u16 *pw_control_type, u32 *ph_control)
1535{ 1288{
1536 struct hpi_message hm; 1289 struct hpi_message hm;
1537 struct hpi_response hr; 1290 struct hpi_response hr;
1538 hpi_init_message_response(&hm, &hr, HPI_OBJ_MIXER, 1291 hpi_init_message_response(&hm, &hr, HPI_OBJ_MIXER,
1539 HPI_MIXER_GET_CONTROL_BY_INDEX); 1292 HPI_MIXER_GET_CONTROL_BY_INDEX);
1540 u32TOINDEX(h_mixer, &hm.adapter_index); 1293 if (hpi_handle_indexes(h_mixer, &hm.adapter_index, NULL))
1294 return HPI_ERROR_INVALID_HANDLE;
1541 hm.u.m.control_index = control_index; 1295 hm.u.m.control_index = control_index;
1542 hpi_send_recv(&hm, &hr); 1296 hpi_send_recv(&hm, &hr);
1543 1297
@@ -1562,13 +1316,14 @@ u16 hpi_mixer_get_control_by_index(const struct hpi_hsubsys *ph_subsys,
1562 return hr.error; 1316 return hr.error;
1563} 1317}
1564 1318
1565u16 hpi_mixer_store(const struct hpi_hsubsys *ph_subsys, u32 h_mixer, 1319u16 hpi_mixer_store(u32 h_mixer, enum HPI_MIXER_STORE_COMMAND command,
1566 enum HPI_MIXER_STORE_COMMAND command, u16 index) 1320 u16 index)
1567{ 1321{
1568 struct hpi_message hm; 1322 struct hpi_message hm;
1569 struct hpi_response hr; 1323 struct hpi_response hr;
1570 hpi_init_message_response(&hm, &hr, HPI_OBJ_MIXER, HPI_MIXER_STORE); 1324 hpi_init_message_response(&hm, &hr, HPI_OBJ_MIXER, HPI_MIXER_STORE);
1571 u32TOINDEX(h_mixer, &hm.adapter_index); 1325 if (hpi_handle_indexes(h_mixer, &hm.adapter_index, NULL))
1326 return HPI_ERROR_INVALID_HANDLE;
1572 hm.u.mx.store.command = command; 1327 hm.u.mx.store.command = command;
1573 hm.u.mx.store.index = index; 1328 hm.u.mx.store.index = index;
1574 hpi_send_recv(&hm, &hr); 1329 hpi_send_recv(&hm, &hr);
@@ -1576,16 +1331,16 @@ u16 hpi_mixer_store(const struct hpi_hsubsys *ph_subsys, u32 h_mixer,
1576} 1331}
1577 1332
1578static 1333static
1579u16 hpi_control_param_set(const struct hpi_hsubsys *ph_subsys, 1334u16 hpi_control_param_set(const u32 h_control, const u16 attrib,
1580 const u32 h_control, const u16 attrib, const u32 param1, 1335 const u32 param1, const u32 param2)
1581 const u32 param2)
1582{ 1336{
1583 struct hpi_message hm; 1337 struct hpi_message hm;
1584 struct hpi_response hr; 1338 struct hpi_response hr;
1585 1339
1586 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 1340 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
1587 HPI_CONTROL_SET_STATE); 1341 HPI_CONTROL_SET_STATE);
1588 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 1342 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
1343 return HPI_ERROR_INVALID_HANDLE;
1589 hm.u.c.attribute = attrib; 1344 hm.u.c.attribute = attrib;
1590 hm.u.c.param1 = param1; 1345 hm.u.c.param1 = param1;
1591 hm.u.c.param2 = param2; 1346 hm.u.c.param2 = param2;
@@ -1601,7 +1356,8 @@ static u16 hpi_control_log_set2(u32 h_control, u16 attrib, short sv0,
1601 1356
1602 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 1357 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
1603 HPI_CONTROL_SET_STATE); 1358 HPI_CONTROL_SET_STATE);
1604 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 1359 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
1360 return HPI_ERROR_INVALID_HANDLE;
1605 hm.u.c.attribute = attrib; 1361 hm.u.c.attribute = attrib;
1606 hm.u.c.an_log_value[0] = sv0; 1362 hm.u.c.an_log_value[0] = sv0;
1607 hm.u.c.an_log_value[1] = sv1; 1363 hm.u.c.an_log_value[1] = sv1;
@@ -1610,16 +1366,16 @@ static u16 hpi_control_log_set2(u32 h_control, u16 attrib, short sv0,
1610} 1366}
1611 1367
1612static 1368static
1613u16 hpi_control_param_get(const struct hpi_hsubsys *ph_subsys, 1369u16 hpi_control_param_get(const u32 h_control, const u16 attrib, u32 param1,
1614 const u32 h_control, const u16 attrib, u32 param1, u32 param2, 1370 u32 param2, u32 *pparam1, u32 *pparam2)
1615 u32 *pparam1, u32 *pparam2)
1616{ 1371{
1617 struct hpi_message hm; 1372 struct hpi_message hm;
1618 struct hpi_response hr; 1373 struct hpi_response hr;
1619 1374
1620 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 1375 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
1621 HPI_CONTROL_GET_STATE); 1376 HPI_CONTROL_GET_STATE);
1622 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 1377 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
1378 return HPI_ERROR_INVALID_HANDLE;
1623 hm.u.c.attribute = attrib; 1379 hm.u.c.attribute = attrib;
1624 hm.u.c.param1 = param1; 1380 hm.u.c.param1 = param1;
1625 hm.u.c.param2 = param2; 1381 hm.u.c.param2 = param2;
@@ -1632,19 +1388,20 @@ u16 hpi_control_param_get(const struct hpi_hsubsys *ph_subsys,
1632 return hr.error; 1388 return hr.error;
1633} 1389}
1634 1390
1635#define hpi_control_param1_get(s, h, a, p1) \ 1391#define hpi_control_param1_get(h, a, p1) \
1636 hpi_control_param_get(s, h, a, 0, 0, p1, NULL) 1392 hpi_control_param_get(h, a, 0, 0, p1, NULL)
1637#define hpi_control_param2_get(s, h, a, p1, p2) \ 1393#define hpi_control_param2_get(h, a, p1, p2) \
1638 hpi_control_param_get(s, h, a, 0, 0, p1, p2) 1394 hpi_control_param_get(h, a, 0, 0, p1, p2)
1639 1395
1640static u16 hpi_control_log_get2(const struct hpi_hsubsys *ph_subsys, 1396static u16 hpi_control_log_get2(u32 h_control, u16 attrib, short *sv0,
1641 u32 h_control, u16 attrib, short *sv0, short *sv1) 1397 short *sv1)
1642{ 1398{
1643 struct hpi_message hm; 1399 struct hpi_message hm;
1644 struct hpi_response hr; 1400 struct hpi_response hr;
1645 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 1401 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
1646 HPI_CONTROL_GET_STATE); 1402 HPI_CONTROL_GET_STATE);
1647 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 1403 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
1404 return HPI_ERROR_INVALID_HANDLE;
1648 hm.u.c.attribute = attrib; 1405 hm.u.c.attribute = attrib;
1649 1406
1650 hpi_send_recv(&hm, &hr); 1407 hpi_send_recv(&hm, &hr);
@@ -1655,8 +1412,7 @@ static u16 hpi_control_log_get2(const struct hpi_hsubsys *ph_subsys,
1655} 1412}
1656 1413
1657static 1414static
1658u16 hpi_control_query(const struct hpi_hsubsys *ph_subsys, 1415u16 hpi_control_query(const u32 h_control, const u16 attrib, const u32 index,
1659 const u32 h_control, const u16 attrib, const u32 index,
1660 const u32 param, u32 *psetting) 1416 const u32 param, u32 *psetting)
1661{ 1417{
1662 struct hpi_message hm; 1418 struct hpi_message hm;
@@ -1664,7 +1420,8 @@ u16 hpi_control_query(const struct hpi_hsubsys *ph_subsys,
1664 1420
1665 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 1421 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
1666 HPI_CONTROL_GET_INFO); 1422 HPI_CONTROL_GET_INFO);
1667 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 1423 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
1424 return HPI_ERROR_INVALID_HANDLE;
1668 1425
1669 hm.u.c.attribute = attrib; 1426 hm.u.c.attribute = attrib;
1670 hm.u.c.param1 = index; 1427 hm.u.c.param1 = index;
@@ -1682,7 +1439,7 @@ static u16 hpi_control_get_string(const u32 h_control, const u16 attribute,
1682 unsigned int sub_string_index = 0, j = 0; 1439 unsigned int sub_string_index = 0, j = 0;
1683 char c = 0; 1440 char c = 0;
1684 unsigned int n = 0; 1441 unsigned int n = 0;
1685 u16 hE = 0; 1442 u16 err = 0;
1686 1443
1687 if ((string_length < 1) || (string_length > 256)) 1444 if ((string_length < 1) || (string_length > 256))
1688 return HPI_ERROR_INVALID_CONTROL_VALUE; 1445 return HPI_ERROR_INVALID_CONTROL_VALUE;
@@ -1693,7 +1450,9 @@ static u16 hpi_control_get_string(const u32 h_control, const u16 attribute,
1693 1450
1694 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 1451 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
1695 HPI_CONTROL_GET_STATE); 1452 HPI_CONTROL_GET_STATE);
1696 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 1453 if (hpi_handle_indexes(h_control, &hm.adapter_index,
1454 &hm.obj_index))
1455 return HPI_ERROR_INVALID_HANDLE;
1697 hm.u.c.attribute = attribute; 1456 hm.u.c.attribute = attribute;
1698 hm.u.c.param1 = sub_string_index; 1457 hm.u.c.param1 = sub_string_index;
1699 hm.u.c.param2 = 0; 1458 hm.u.c.param2 = 0;
@@ -1705,7 +1464,7 @@ static u16 hpi_control_get_string(const u32 h_control, const u16 attribute,
1705 return HPI_ERROR_INVALID_CONTROL_VALUE; 1464 return HPI_ERROR_INVALID_CONTROL_VALUE;
1706 1465
1707 if (hr.error) { 1466 if (hr.error) {
1708 hE = hr.error; 1467 err = hr.error;
1709 break; 1468 break;
1710 } 1469 }
1711 for (j = 0; j < 8; j++) { 1470 for (j = 0; j < 8; j++) {
@@ -1714,7 +1473,7 @@ static u16 hpi_control_get_string(const u32 h_control, const u16 attribute,
1714 n++; 1473 n++;
1715 if (n >= string_length) { 1474 if (n >= string_length) {
1716 psz_string[string_length - 1] = 0; 1475 psz_string[string_length - 1] = 0;
1717 hE = HPI_ERROR_INVALID_CONTROL_VALUE; 1476 err = HPI_ERROR_INVALID_CONTROL_VALUE;
1718 break; 1477 break;
1719 } 1478 }
1720 if (c == 0) 1479 if (c == 0)
@@ -1730,57 +1489,52 @@ static u16 hpi_control_get_string(const u32 h_control, const u16 attribute,
1730 if (c == 0) 1489 if (c == 0)
1731 break; 1490 break;
1732 } 1491 }
1733 return hE; 1492 return err;
1734} 1493}
1735 1494
1736u16 HPI_AESEBU__receiver_query_format(const struct hpi_hsubsys *ph_subsys, 1495u16 hpi_aesebu_receiver_query_format(const u32 h_aes_rx, const u32 index,
1737 const u32 h_aes_rx, const u32 index, u16 *pw_format) 1496 u16 *pw_format)
1738{ 1497{
1739 u32 qr; 1498 u32 qr;
1740 u16 err; 1499 u16 err;
1741 1500
1742 err = hpi_control_query(ph_subsys, h_aes_rx, HPI_AESEBURX_FORMAT, 1501 err = hpi_control_query(h_aes_rx, HPI_AESEBURX_FORMAT, index, 0, &qr);
1743 index, 0, &qr);
1744 *pw_format = (u16)qr; 1502 *pw_format = (u16)qr;
1745 return err; 1503 return err;
1746} 1504}
1747 1505
1748u16 HPI_AESEBU__receiver_set_format(const struct hpi_hsubsys *ph_subsys, 1506u16 hpi_aesebu_receiver_set_format(u32 h_control, u16 format)
1749 u32 h_control, u16 format)
1750{ 1507{
1751 return hpi_control_param_set(ph_subsys, h_control, 1508 return hpi_control_param_set(h_control, HPI_AESEBURX_FORMAT, format,
1752 HPI_AESEBURX_FORMAT, format, 0); 1509 0);
1753} 1510}
1754 1511
1755u16 HPI_AESEBU__receiver_get_format(const struct hpi_hsubsys *ph_subsys, 1512u16 hpi_aesebu_receiver_get_format(u32 h_control, u16 *pw_format)
1756 u32 h_control, u16 *pw_format)
1757{ 1513{
1758 u16 err; 1514 u16 err;
1759 u32 param; 1515 u32 param;
1760 1516
1761 err = hpi_control_param1_get(ph_subsys, h_control, 1517 err = hpi_control_param1_get(h_control, HPI_AESEBURX_FORMAT, &param);
1762 HPI_AESEBURX_FORMAT, &param);
1763 if (!err && pw_format) 1518 if (!err && pw_format)
1764 *pw_format = (u16)param; 1519 *pw_format = (u16)param;
1765 1520
1766 return err; 1521 return err;
1767} 1522}
1768 1523
1769u16 HPI_AESEBU__receiver_get_sample_rate(const struct hpi_hsubsys *ph_subsys, 1524u16 hpi_aesebu_receiver_get_sample_rate(u32 h_control, u32 *psample_rate)
1770 u32 h_control, u32 *psample_rate)
1771{ 1525{
1772 return hpi_control_param1_get(ph_subsys, h_control, 1526 return hpi_control_param1_get(h_control, HPI_AESEBURX_SAMPLERATE,
1773 HPI_AESEBURX_SAMPLERATE, psample_rate); 1527 psample_rate);
1774} 1528}
1775 1529
1776u16 HPI_AESEBU__receiver_get_user_data(const struct hpi_hsubsys *ph_subsys, 1530u16 hpi_aesebu_receiver_get_user_data(u32 h_control, u16 index, u16 *pw_data)
1777 u32 h_control, u16 index, u16 *pw_data)
1778{ 1531{
1779 struct hpi_message hm; 1532 struct hpi_message hm;
1780 struct hpi_response hr; 1533 struct hpi_response hr;
1781 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 1534 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
1782 HPI_CONTROL_GET_STATE); 1535 HPI_CONTROL_GET_STATE);
1783 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 1536 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
1537 return HPI_ERROR_INVALID_HANDLE;
1784 hm.u.c.attribute = HPI_AESEBURX_USERDATA; 1538 hm.u.c.attribute = HPI_AESEBURX_USERDATA;
1785 hm.u.c.param1 = index; 1539 hm.u.c.param1 = index;
1786 1540
@@ -1791,14 +1545,15 @@ u16 HPI_AESEBU__receiver_get_user_data(const struct hpi_hsubsys *ph_subsys,
1791 return hr.error; 1545 return hr.error;
1792} 1546}
1793 1547
1794u16 HPI_AESEBU__receiver_get_channel_status(const struct hpi_hsubsys 1548u16 hpi_aesebu_receiver_get_channel_status(u32 h_control, u16 index,
1795 *ph_subsys, u32 h_control, u16 index, u16 *pw_data) 1549 u16 *pw_data)
1796{ 1550{
1797 struct hpi_message hm; 1551 struct hpi_message hm;
1798 struct hpi_response hr; 1552 struct hpi_response hr;
1799 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 1553 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
1800 HPI_CONTROL_GET_STATE); 1554 HPI_CONTROL_GET_STATE);
1801 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 1555 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
1556 return HPI_ERROR_INVALID_HANDLE;
1802 hm.u.c.attribute = HPI_AESEBURX_CHANNELSTATUS; 1557 hm.u.c.attribute = HPI_AESEBURX_CHANNELSTATUS;
1803 hm.u.c.param1 = index; 1558 hm.u.c.param1 = index;
1804 1559
@@ -1809,101 +1564,93 @@ u16 HPI_AESEBU__receiver_get_channel_status(const struct hpi_hsubsys
1809 return hr.error; 1564 return hr.error;
1810} 1565}
1811 1566
1812u16 HPI_AESEBU__receiver_get_error_status(const struct hpi_hsubsys *ph_subsys, 1567u16 hpi_aesebu_receiver_get_error_status(u32 h_control, u16 *pw_error_data)
1813 u32 h_control, u16 *pw_error_data)
1814{ 1568{
1815 u32 error_data = 0; 1569 u32 error_data = 0;
1816 u16 error = 0; 1570 u16 err = 0;
1817 1571
1818 error = hpi_control_param1_get(ph_subsys, h_control, 1572 err = hpi_control_param1_get(h_control, HPI_AESEBURX_ERRORSTATUS,
1819 HPI_AESEBURX_ERRORSTATUS, &error_data); 1573 &error_data);
1820 if (pw_error_data) 1574 if (pw_error_data)
1821 *pw_error_data = (u16)error_data; 1575 *pw_error_data = (u16)error_data;
1822 return error; 1576 return err;
1823} 1577}
1824 1578
1825u16 HPI_AESEBU__transmitter_set_sample_rate(const struct hpi_hsubsys 1579u16 hpi_aesebu_transmitter_set_sample_rate(u32 h_control, u32 sample_rate)
1826 *ph_subsys, u32 h_control, u32 sample_rate)
1827{ 1580{
1828 return hpi_control_param_set(ph_subsys, h_control, 1581 return hpi_control_param_set(h_control, HPI_AESEBUTX_SAMPLERATE,
1829 HPI_AESEBUTX_SAMPLERATE, sample_rate, 0); 1582 sample_rate, 0);
1830} 1583}
1831 1584
1832u16 HPI_AESEBU__transmitter_set_user_data(const struct hpi_hsubsys *ph_subsys, 1585u16 hpi_aesebu_transmitter_set_user_data(u32 h_control, u16 index, u16 data)
1833 u32 h_control, u16 index, u16 data)
1834{ 1586{
1835 return hpi_control_param_set(ph_subsys, h_control, 1587 return hpi_control_param_set(h_control, HPI_AESEBUTX_USERDATA, index,
1836 HPI_AESEBUTX_USERDATA, index, data); 1588 data);
1837} 1589}
1838 1590
1839u16 HPI_AESEBU__transmitter_set_channel_status(const struct hpi_hsubsys 1591u16 hpi_aesebu_transmitter_set_channel_status(u32 h_control, u16 index,
1840 *ph_subsys, u32 h_control, u16 index, u16 data) 1592 u16 data)
1841{ 1593{
1842 return hpi_control_param_set(ph_subsys, h_control, 1594 return hpi_control_param_set(h_control, HPI_AESEBUTX_CHANNELSTATUS,
1843 HPI_AESEBUTX_CHANNELSTATUS, index, data); 1595 index, data);
1844} 1596}
1845 1597
1846u16 HPI_AESEBU__transmitter_get_channel_status(const struct hpi_hsubsys 1598u16 hpi_aesebu_transmitter_get_channel_status(u32 h_control, u16 index,
1847 *ph_subsys, u32 h_control, u16 index, u16 *pw_data) 1599 u16 *pw_data)
1848{ 1600{
1849 return HPI_ERROR_INVALID_OPERATION; 1601 return HPI_ERROR_INVALID_OPERATION;
1850} 1602}
1851 1603
1852u16 HPI_AESEBU__transmitter_query_format(const struct hpi_hsubsys *ph_subsys, 1604u16 hpi_aesebu_transmitter_query_format(const u32 h_aes_tx, const u32 index,
1853 const u32 h_aes_tx, const u32 index, u16 *pw_format) 1605 u16 *pw_format)
1854{ 1606{
1855 u32 qr; 1607 u32 qr;
1856 u16 err; 1608 u16 err;
1857 1609
1858 err = hpi_control_query(ph_subsys, h_aes_tx, HPI_AESEBUTX_FORMAT, 1610 err = hpi_control_query(h_aes_tx, HPI_AESEBUTX_FORMAT, index, 0, &qr);
1859 index, 0, &qr);
1860 *pw_format = (u16)qr; 1611 *pw_format = (u16)qr;
1861 return err; 1612 return err;
1862} 1613}
1863 1614
1864u16 HPI_AESEBU__transmitter_set_format(const struct hpi_hsubsys *ph_subsys, 1615u16 hpi_aesebu_transmitter_set_format(u32 h_control, u16 output_format)
1865 u32 h_control, u16 output_format)
1866{ 1616{
1867 return hpi_control_param_set(ph_subsys, h_control, 1617 return hpi_control_param_set(h_control, HPI_AESEBUTX_FORMAT,
1868 HPI_AESEBUTX_FORMAT, output_format, 0); 1618 output_format, 0);
1869} 1619}
1870 1620
1871u16 HPI_AESEBU__transmitter_get_format(const struct hpi_hsubsys *ph_subsys, 1621u16 hpi_aesebu_transmitter_get_format(u32 h_control, u16 *pw_output_format)
1872 u32 h_control, u16 *pw_output_format)
1873{ 1622{
1874 u16 err; 1623 u16 err;
1875 u32 param; 1624 u32 param;
1876 1625
1877 err = hpi_control_param1_get(ph_subsys, h_control, 1626 err = hpi_control_param1_get(h_control, HPI_AESEBUTX_FORMAT, &param);
1878 HPI_AESEBUTX_FORMAT, &param);
1879 if (!err && pw_output_format) 1627 if (!err && pw_output_format)
1880 *pw_output_format = (u16)param; 1628 *pw_output_format = (u16)param;
1881 1629
1882 return err; 1630 return err;
1883} 1631}
1884 1632
1885u16 hpi_bitstream_set_clock_edge(const struct hpi_hsubsys *ph_subsys, 1633u16 hpi_bitstream_set_clock_edge(u32 h_control, u16 edge_type)
1886 u32 h_control, u16 edge_type)
1887{ 1634{
1888 return hpi_control_param_set(ph_subsys, h_control, 1635 return hpi_control_param_set(h_control, HPI_BITSTREAM_CLOCK_EDGE,
1889 HPI_BITSTREAM_CLOCK_EDGE, edge_type, 0); 1636 edge_type, 0);
1890} 1637}
1891 1638
1892u16 hpi_bitstream_set_data_polarity(const struct hpi_hsubsys *ph_subsys, 1639u16 hpi_bitstream_set_data_polarity(u32 h_control, u16 polarity)
1893 u32 h_control, u16 polarity)
1894{ 1640{
1895 return hpi_control_param_set(ph_subsys, h_control, 1641 return hpi_control_param_set(h_control, HPI_BITSTREAM_DATA_POLARITY,
1896 HPI_BITSTREAM_DATA_POLARITY, polarity, 0); 1642 polarity, 0);
1897} 1643}
1898 1644
1899u16 hpi_bitstream_get_activity(const struct hpi_hsubsys *ph_subsys, 1645u16 hpi_bitstream_get_activity(u32 h_control, u16 *pw_clk_activity,
1900 u32 h_control, u16 *pw_clk_activity, u16 *pw_data_activity) 1646 u16 *pw_data_activity)
1901{ 1647{
1902 struct hpi_message hm; 1648 struct hpi_message hm;
1903 struct hpi_response hr; 1649 struct hpi_response hr;
1904 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 1650 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
1905 HPI_CONTROL_GET_STATE); 1651 HPI_CONTROL_GET_STATE);
1906 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 1652 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
1653 return HPI_ERROR_INVALID_HANDLE;
1907 hm.u.c.attribute = HPI_BITSTREAM_ACTIVITY; 1654 hm.u.c.attribute = HPI_BITSTREAM_ACTIVITY;
1908 hpi_send_recv(&hm, &hr); 1655 hpi_send_recv(&hm, &hr);
1909 if (pw_clk_activity) 1656 if (pw_clk_activity)
@@ -1913,45 +1660,43 @@ u16 hpi_bitstream_get_activity(const struct hpi_hsubsys *ph_subsys,
1913 return hr.error; 1660 return hr.error;
1914} 1661}
1915 1662
1916u16 hpi_channel_mode_query_mode(const struct hpi_hsubsys *ph_subsys, 1663u16 hpi_channel_mode_query_mode(const u32 h_mode, const u32 index,
1917 const u32 h_mode, const u32 index, u16 *pw_mode) 1664 u16 *pw_mode)
1918{ 1665{
1919 u32 qr; 1666 u32 qr;
1920 u16 err; 1667 u16 err;
1921 1668
1922 err = hpi_control_query(ph_subsys, h_mode, HPI_CHANNEL_MODE_MODE, 1669 err = hpi_control_query(h_mode, HPI_CHANNEL_MODE_MODE, index, 0, &qr);
1923 index, 0, &qr);
1924 *pw_mode = (u16)qr; 1670 *pw_mode = (u16)qr;
1925 return err; 1671 return err;
1926} 1672}
1927 1673
1928u16 hpi_channel_mode_set(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1674u16 hpi_channel_mode_set(u32 h_control, u16 mode)
1929 u16 mode)
1930{ 1675{
1931 return hpi_control_param_set(ph_subsys, h_control, 1676 return hpi_control_param_set(h_control, HPI_CHANNEL_MODE_MODE, mode,
1932 HPI_CHANNEL_MODE_MODE, mode, 0); 1677 0);
1933} 1678}
1934 1679
1935u16 hpi_channel_mode_get(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1680u16 hpi_channel_mode_get(u32 h_control, u16 *mode)
1936 u16 *mode)
1937{ 1681{
1938 u32 mode32 = 0; 1682 u32 mode32 = 0;
1939 u16 error = hpi_control_param1_get(ph_subsys, h_control, 1683 u16 err = hpi_control_param1_get(h_control,
1940 HPI_CHANNEL_MODE_MODE, &mode32); 1684 HPI_CHANNEL_MODE_MODE, &mode32);
1941 if (mode) 1685 if (mode)
1942 *mode = (u16)mode32; 1686 *mode = (u16)mode32;
1943 return error; 1687 return err;
1944} 1688}
1945 1689
1946u16 hpi_cobranet_hmi_write(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1690u16 hpi_cobranet_hmi_write(u32 h_control, u32 hmi_address, u32 byte_count,
1947 u32 hmi_address, u32 byte_count, u8 *pb_data) 1691 u8 *pb_data)
1948{ 1692{
1949 struct hpi_message hm; 1693 struct hpi_message hm;
1950 struct hpi_response hr; 1694 struct hpi_response hr;
1951 1695
1952 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX, 1696 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX,
1953 HPI_CONTROL_SET_STATE); 1697 HPI_CONTROL_SET_STATE);
1954 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 1698 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
1699 return HPI_ERROR_INVALID_HANDLE;
1955 1700
1956 hm.u.cx.u.cobranet_data.byte_count = byte_count; 1701 hm.u.cx.u.cobranet_data.byte_count = byte_count;
1957 hm.u.cx.u.cobranet_data.hmi_address = hmi_address; 1702 hm.u.cx.u.cobranet_data.hmi_address = hmi_address;
@@ -1969,15 +1714,16 @@ u16 hpi_cobranet_hmi_write(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1969 return hr.error; 1714 return hr.error;
1970} 1715}
1971 1716
1972u16 hpi_cobranet_hmi_read(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1717u16 hpi_cobranet_hmi_read(u32 h_control, u32 hmi_address, u32 max_byte_count,
1973 u32 hmi_address, u32 max_byte_count, u32 *pbyte_count, u8 *pb_data) 1718 u32 *pbyte_count, u8 *pb_data)
1974{ 1719{
1975 struct hpi_message hm; 1720 struct hpi_message hm;
1976 struct hpi_response hr; 1721 struct hpi_response hr;
1977 1722
1978 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX, 1723 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX,
1979 HPI_CONTROL_GET_STATE); 1724 HPI_CONTROL_GET_STATE);
1980 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 1725 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
1726 return HPI_ERROR_INVALID_HANDLE;
1981 1727
1982 hm.u.cx.u.cobranet_data.byte_count = max_byte_count; 1728 hm.u.cx.u.cobranet_data.byte_count = max_byte_count;
1983 hm.u.cx.u.cobranet_data.hmi_address = hmi_address; 1729 hm.u.cx.u.cobranet_data.hmi_address = hmi_address;
@@ -2008,16 +1754,16 @@ u16 hpi_cobranet_hmi_read(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2008 return hr.error; 1754 return hr.error;
2009} 1755}
2010 1756
2011u16 hpi_cobranet_hmi_get_status(const struct hpi_hsubsys *ph_subsys, 1757u16 hpi_cobranet_hmi_get_status(u32 h_control, u32 *pstatus,
2012 u32 h_control, u32 *pstatus, u32 *preadable_size, 1758 u32 *preadable_size, u32 *pwriteable_size)
2013 u32 *pwriteable_size)
2014{ 1759{
2015 struct hpi_message hm; 1760 struct hpi_message hm;
2016 struct hpi_response hr; 1761 struct hpi_response hr;
2017 1762
2018 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX, 1763 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX,
2019 HPI_CONTROL_GET_STATE); 1764 HPI_CONTROL_GET_STATE);
2020 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 1765 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
1766 return HPI_ERROR_INVALID_HANDLE;
2021 1767
2022 hm.u.cx.attribute = HPI_COBRANET_GET_STATUS; 1768 hm.u.cx.attribute = HPI_COBRANET_GET_STATUS;
2023 1769
@@ -2035,177 +1781,176 @@ u16 hpi_cobranet_hmi_get_status(const struct hpi_hsubsys *ph_subsys,
2035 return hr.error; 1781 return hr.error;
2036} 1782}
2037 1783
2038u16 hpi_cobranet_getI_paddress(const struct hpi_hsubsys *ph_subsys, 1784u16 hpi_cobranet_get_ip_address(u32 h_control, u32 *pdw_ip_address)
2039 u32 h_control, u32 *pi_paddress)
2040{ 1785{
2041 u32 byte_count; 1786 u32 byte_count;
2042 u32 iP; 1787 u32 iP;
2043 u16 error; 1788 u16 err;
2044 1789
2045 error = hpi_cobranet_hmi_read(ph_subsys, h_control, 1790 err = hpi_cobranet_hmi_read(h_control,
2046 HPI_COBRANET_HMI_cobra_ip_mon_currentIP, 4, &byte_count, 1791 HPI_COBRANET_HMI_cobra_ip_mon_currentIP, 4, &byte_count,
2047 (u8 *)&iP); 1792 (u8 *)&iP);
2048 1793
2049 *pi_paddress = 1794 *pdw_ip_address =
2050 ((iP & 0xff000000) >> 8) | ((iP & 0x00ff0000) << 8) | ((iP & 1795 ((iP & 0xff000000) >> 8) | ((iP & 0x00ff0000) << 8) | ((iP &
2051 0x0000ff00) >> 8) | ((iP & 0x000000ff) << 8); 1796 0x0000ff00) >> 8) | ((iP & 0x000000ff) << 8);
2052 1797
2053 if (error) 1798 if (err)
2054 *pi_paddress = 0; 1799 *pdw_ip_address = 0;
2055 1800
2056 return error; 1801 return err;
2057 1802
2058} 1803}
2059 1804
2060u16 hpi_cobranet_setI_paddress(const struct hpi_hsubsys *ph_subsys, 1805u16 hpi_cobranet_set_ip_address(u32 h_control, u32 dw_ip_address)
2061 u32 h_control, u32 i_paddress)
2062{ 1806{
2063 u32 iP; 1807 u32 iP;
2064 u16 error; 1808 u16 err;
2065 1809
2066 iP = ((i_paddress & 0xff000000) >> 8) | ((i_paddress & 0x00ff0000) << 1810 iP = ((dw_ip_address & 0xff000000) >> 8) | ((dw_ip_address &
2067 8) | ((i_paddress & 0x0000ff00) >> 8) | ((i_paddress & 1811 0x00ff0000) << 8) | ((dw_ip_address & 0x0000ff00) >>
2068 0x000000ff) << 8); 1812 8) | ((dw_ip_address & 0x000000ff) << 8);
2069 1813
2070 error = hpi_cobranet_hmi_write(ph_subsys, h_control, 1814 err = hpi_cobranet_hmi_write(h_control,
2071 HPI_COBRANET_HMI_cobra_ip_mon_currentIP, 4, (u8 *)&iP); 1815 HPI_COBRANET_HMI_cobra_ip_mon_currentIP, 4, (u8 *)&iP);
2072 1816
2073 return error; 1817 return err;
2074 1818
2075} 1819}
2076 1820
2077u16 hpi_cobranet_get_staticI_paddress(const struct hpi_hsubsys *ph_subsys, 1821u16 hpi_cobranet_get_static_ip_address(u32 h_control, u32 *pdw_ip_address)
2078 u32 h_control, u32 *pi_paddress)
2079{ 1822{
2080 u32 byte_count; 1823 u32 byte_count;
2081 u32 iP; 1824 u32 iP;
2082 u16 error; 1825 u16 err;
2083 error = hpi_cobranet_hmi_read(ph_subsys, h_control, 1826 err = hpi_cobranet_hmi_read(h_control,
2084 HPI_COBRANET_HMI_cobra_ip_mon_staticIP, 4, &byte_count, 1827 HPI_COBRANET_HMI_cobra_ip_mon_staticIP, 4, &byte_count,
2085 (u8 *)&iP); 1828 (u8 *)&iP);
2086 1829
2087 *pi_paddress = 1830 *pdw_ip_address =
2088 ((iP & 0xff000000) >> 8) | ((iP & 0x00ff0000) << 8) | ((iP & 1831 ((iP & 0xff000000) >> 8) | ((iP & 0x00ff0000) << 8) | ((iP &
2089 0x0000ff00) >> 8) | ((iP & 0x000000ff) << 8); 1832 0x0000ff00) >> 8) | ((iP & 0x000000ff) << 8);
2090 1833
2091 if (error) 1834 if (err)
2092 *pi_paddress = 0; 1835 *pdw_ip_address = 0;
2093 1836
2094 return error; 1837 return err;
2095 1838
2096} 1839}
2097 1840
2098u16 hpi_cobranet_set_staticI_paddress(const struct hpi_hsubsys *ph_subsys, 1841u16 hpi_cobranet_set_static_ip_address(u32 h_control, u32 dw_ip_address)
2099 u32 h_control, u32 i_paddress)
2100{ 1842{
2101 u32 iP; 1843 u32 iP;
2102 u16 error; 1844 u16 err;
2103 1845
2104 iP = ((i_paddress & 0xff000000) >> 8) | ((i_paddress & 0x00ff0000) << 1846 iP = ((dw_ip_address & 0xff000000) >> 8) | ((dw_ip_address &
2105 8) | ((i_paddress & 0x0000ff00) >> 8) | ((i_paddress & 1847 0x00ff0000) << 8) | ((dw_ip_address & 0x0000ff00) >>
2106 0x000000ff) << 8); 1848 8) | ((dw_ip_address & 0x000000ff) << 8);
2107 1849
2108 error = hpi_cobranet_hmi_write(ph_subsys, h_control, 1850 err = hpi_cobranet_hmi_write(h_control,
2109 HPI_COBRANET_HMI_cobra_ip_mon_staticIP, 4, (u8 *)&iP); 1851 HPI_COBRANET_HMI_cobra_ip_mon_staticIP, 4, (u8 *)&iP);
2110 1852
2111 return error; 1853 return err;
2112 1854
2113} 1855}
2114 1856
2115u16 hpi_cobranet_getMA_caddress(const struct hpi_hsubsys *ph_subsys, 1857u16 hpi_cobranet_get_macaddress(u32 h_control, u32 *p_mac_msbs,
2116 u32 h_control, u32 *pmAC_MS_bs, u32 *pmAC_LS_bs) 1858 u32 *p_mac_lsbs)
2117{ 1859{
2118 u32 byte_count; 1860 u32 byte_count;
2119 u16 error; 1861 u16 err;
2120 u32 mAC; 1862 u32 mac;
2121 1863
2122 error = hpi_cobranet_hmi_read(ph_subsys, h_control, 1864 err = hpi_cobranet_hmi_read(h_control,
2123 HPI_COBRANET_HMI_cobra_if_phy_address, 4, &byte_count, 1865 HPI_COBRANET_HMI_cobra_if_phy_address, 4, &byte_count,
2124 (u8 *)&mAC); 1866 (u8 *)&mac);
2125 *pmAC_MS_bs = 1867
2126 ((mAC & 0xff000000) >> 8) | ((mAC & 0x00ff0000) << 8) | ((mAC 1868 if (!err) {
2127 & 0x0000ff00) >> 8) | ((mAC & 0x000000ff) << 8); 1869 *p_mac_msbs =
2128 error += hpi_cobranet_hmi_read(ph_subsys, h_control, 1870 ((mac & 0xff000000) >> 8) | ((mac & 0x00ff0000) << 8)
2129 HPI_COBRANET_HMI_cobra_if_phy_address + 1, 4, &byte_count, 1871 | ((mac & 0x0000ff00) >> 8) | ((mac & 0x000000ff) <<
2130 (u8 *)&mAC); 1872 8);
2131 *pmAC_LS_bs = 1873
2132 ((mAC & 0xff000000) >> 8) | ((mAC & 0x00ff0000) << 8) | ((mAC 1874 err = hpi_cobranet_hmi_read(h_control,
2133 & 0x0000ff00) >> 8) | ((mAC & 0x000000ff) << 8); 1875 HPI_COBRANET_HMI_cobra_if_phy_address + 1, 4,
2134 1876 &byte_count, (u8 *)&mac);
2135 if (error) {
2136 *pmAC_MS_bs = 0;
2137 *pmAC_LS_bs = 0;
2138 } 1877 }
2139 1878
2140 return error; 1879 if (!err) {
1880 *p_mac_lsbs =
1881 ((mac & 0xff000000) >> 8) | ((mac & 0x00ff0000) << 8)
1882 | ((mac & 0x0000ff00) >> 8) | ((mac & 0x000000ff) <<
1883 8);
1884 } else {
1885 *p_mac_msbs = 0;
1886 *p_mac_lsbs = 0;
1887 }
1888
1889 return err;
2141} 1890}
2142 1891
2143u16 hpi_compander_set_enable(const struct hpi_hsubsys *ph_subsys, 1892u16 hpi_compander_set_enable(u32 h_control, u32 enable)
2144 u32 h_control, u32 enable)
2145{ 1893{
2146 return hpi_control_param_set(ph_subsys, h_control, HPI_GENERIC_ENABLE, 1894 return hpi_control_param_set(h_control, HPI_GENERIC_ENABLE, enable,
2147 enable, 0); 1895 0);
2148} 1896}
2149 1897
2150u16 hpi_compander_get_enable(const struct hpi_hsubsys *ph_subsys, 1898u16 hpi_compander_get_enable(u32 h_control, u32 *enable)
2151 u32 h_control, u32 *enable)
2152{ 1899{
2153 return hpi_control_param1_get(ph_subsys, h_control, 1900 return hpi_control_param1_get(h_control, HPI_GENERIC_ENABLE, enable);
2154 HPI_GENERIC_ENABLE, enable);
2155} 1901}
2156 1902
2157u16 hpi_compander_set_makeup_gain(const struct hpi_hsubsys *ph_subsys, 1903u16 hpi_compander_set_makeup_gain(u32 h_control, short makeup_gain0_01dB)
2158 u32 h_control, short makeup_gain0_01dB)
2159{ 1904{
2160 return hpi_control_log_set2(h_control, HPI_COMPANDER_MAKEUPGAIN, 1905 return hpi_control_log_set2(h_control, HPI_COMPANDER_MAKEUPGAIN,
2161 makeup_gain0_01dB, 0); 1906 makeup_gain0_01dB, 0);
2162} 1907}
2163 1908
2164u16 hpi_compander_get_makeup_gain(const struct hpi_hsubsys *ph_subsys, 1909u16 hpi_compander_get_makeup_gain(u32 h_control, short *makeup_gain0_01dB)
2165 u32 h_control, short *makeup_gain0_01dB)
2166{ 1910{
2167 return hpi_control_log_get2(ph_subsys, h_control, 1911 return hpi_control_log_get2(h_control, HPI_COMPANDER_MAKEUPGAIN,
2168 HPI_COMPANDER_MAKEUPGAIN, makeup_gain0_01dB, NULL); 1912 makeup_gain0_01dB, NULL);
2169} 1913}
2170 1914
2171u16 hpi_compander_set_attack_time_constant(const struct hpi_hsubsys 1915u16 hpi_compander_set_attack_time_constant(u32 h_control, unsigned int index,
2172 *ph_subsys, u32 h_control, unsigned int index, u32 attack) 1916 u32 attack)
2173{ 1917{
2174 return hpi_control_param_set(ph_subsys, h_control, 1918 return hpi_control_param_set(h_control, HPI_COMPANDER_ATTACK, attack,
2175 HPI_COMPANDER_ATTACK, attack, index); 1919 index);
2176} 1920}
2177 1921
2178u16 hpi_compander_get_attack_time_constant(const struct hpi_hsubsys 1922u16 hpi_compander_get_attack_time_constant(u32 h_control, unsigned int index,
2179 *ph_subsys, u32 h_control, unsigned int index, u32 *attack) 1923 u32 *attack)
2180{ 1924{
2181 return hpi_control_param_get(ph_subsys, h_control, 1925 return hpi_control_param_get(h_control, HPI_COMPANDER_ATTACK, 0,
2182 HPI_COMPANDER_ATTACK, 0, index, attack, NULL); 1926 index, attack, NULL);
2183} 1927}
2184 1928
2185u16 hpi_compander_set_decay_time_constant(const struct hpi_hsubsys *ph_subsys, 1929u16 hpi_compander_set_decay_time_constant(u32 h_control, unsigned int index,
2186 u32 h_control, unsigned int index, u32 decay) 1930 u32 decay)
2187{ 1931{
2188 return hpi_control_param_set(ph_subsys, h_control, 1932 return hpi_control_param_set(h_control, HPI_COMPANDER_DECAY, decay,
2189 HPI_COMPANDER_DECAY, decay, index); 1933 index);
2190} 1934}
2191 1935
2192u16 hpi_compander_get_decay_time_constant(const struct hpi_hsubsys *ph_subsys, 1936u16 hpi_compander_get_decay_time_constant(u32 h_control, unsigned int index,
2193 u32 h_control, unsigned int index, u32 *decay) 1937 u32 *decay)
2194{ 1938{
2195 return hpi_control_param_get(ph_subsys, h_control, 1939 return hpi_control_param_get(h_control, HPI_COMPANDER_DECAY, 0, index,
2196 HPI_COMPANDER_DECAY, 0, index, decay, NULL); 1940 decay, NULL);
2197 1941
2198} 1942}
2199 1943
2200u16 hpi_compander_set_threshold(const struct hpi_hsubsys *ph_subsys, 1944u16 hpi_compander_set_threshold(u32 h_control, unsigned int index,
2201 u32 h_control, unsigned int index, short threshold0_01dB) 1945 short threshold0_01dB)
2202{ 1946{
2203 struct hpi_message hm; 1947 struct hpi_message hm;
2204 struct hpi_response hr; 1948 struct hpi_response hr;
2205 1949
2206 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 1950 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2207 HPI_CONTROL_SET_STATE); 1951 HPI_CONTROL_SET_STATE);
2208 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 1952 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
1953 return HPI_ERROR_INVALID_HANDLE;
2209 hm.u.c.attribute = HPI_COMPANDER_THRESHOLD; 1954 hm.u.c.attribute = HPI_COMPANDER_THRESHOLD;
2210 hm.u.c.param2 = index; 1955 hm.u.c.param2 = index;
2211 hm.u.c.an_log_value[0] = threshold0_01dB; 1956 hm.u.c.an_log_value[0] = threshold0_01dB;
@@ -2215,15 +1960,16 @@ u16 hpi_compander_set_threshold(const struct hpi_hsubsys *ph_subsys,
2215 return hr.error; 1960 return hr.error;
2216} 1961}
2217 1962
2218u16 hpi_compander_get_threshold(const struct hpi_hsubsys *ph_subsys, 1963u16 hpi_compander_get_threshold(u32 h_control, unsigned int index,
2219 u32 h_control, unsigned int index, short *threshold0_01dB) 1964 short *threshold0_01dB)
2220{ 1965{
2221 struct hpi_message hm; 1966 struct hpi_message hm;
2222 struct hpi_response hr; 1967 struct hpi_response hr;
2223 1968
2224 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 1969 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2225 HPI_CONTROL_GET_STATE); 1970 HPI_CONTROL_GET_STATE);
2226 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 1971 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
1972 return HPI_ERROR_INVALID_HANDLE;
2227 hm.u.c.attribute = HPI_COMPANDER_THRESHOLD; 1973 hm.u.c.attribute = HPI_COMPANDER_THRESHOLD;
2228 hm.u.c.param2 = index; 1974 hm.u.c.param2 = index;
2229 1975
@@ -2233,29 +1979,28 @@ u16 hpi_compander_get_threshold(const struct hpi_hsubsys *ph_subsys,
2233 return hr.error; 1979 return hr.error;
2234} 1980}
2235 1981
2236u16 hpi_compander_set_ratio(const struct hpi_hsubsys *ph_subsys, 1982u16 hpi_compander_set_ratio(u32 h_control, u32 index, u32 ratio100)
2237 u32 h_control, u32 index, u32 ratio100)
2238{ 1983{
2239 return hpi_control_param_set(ph_subsys, h_control, 1984 return hpi_control_param_set(h_control, HPI_COMPANDER_RATIO, ratio100,
2240 HPI_COMPANDER_RATIO, ratio100, index); 1985 index);
2241} 1986}
2242 1987
2243u16 hpi_compander_get_ratio(const struct hpi_hsubsys *ph_subsys, 1988u16 hpi_compander_get_ratio(u32 h_control, u32 index, u32 *ratio100)
2244 u32 h_control, u32 index, u32 *ratio100)
2245{ 1989{
2246 return hpi_control_param_get(ph_subsys, h_control, 1990 return hpi_control_param_get(h_control, HPI_COMPANDER_RATIO, 0, index,
2247 HPI_COMPANDER_RATIO, 0, index, ratio100, NULL); 1991 ratio100, NULL);
2248} 1992}
2249 1993
2250u16 hpi_level_query_range(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1994u16 hpi_level_query_range(u32 h_control, short *min_gain_01dB,
2251 short *min_gain_01dB, short *max_gain_01dB, short *step_gain_01dB) 1995 short *max_gain_01dB, short *step_gain_01dB)
2252{ 1996{
2253 struct hpi_message hm; 1997 struct hpi_message hm;
2254 struct hpi_response hr; 1998 struct hpi_response hr;
2255 1999
2256 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 2000 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2257 HPI_CONTROL_GET_STATE); 2001 HPI_CONTROL_GET_STATE);
2258 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 2002 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
2003 return HPI_ERROR_INVALID_HANDLE;
2259 hm.u.c.attribute = HPI_LEVEL_RANGE; 2004 hm.u.c.attribute = HPI_LEVEL_RANGE;
2260 2005
2261 hpi_send_recv(&hm, &hr); 2006 hpi_send_recv(&hm, &hr);
@@ -2273,31 +2018,27 @@ u16 hpi_level_query_range(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2273 return hr.error; 2018 return hr.error;
2274} 2019}
2275 2020
2276u16 hpi_level_set_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2021u16 hpi_level_set_gain(u32 h_control, short an_gain0_01dB[HPI_MAX_CHANNELS]
2277 short an_gain0_01dB[HPI_MAX_CHANNELS]
2278 ) 2022 )
2279{ 2023{
2280 return hpi_control_log_set2(h_control, HPI_LEVEL_GAIN, 2024 return hpi_control_log_set2(h_control, HPI_LEVEL_GAIN,
2281 an_gain0_01dB[0], an_gain0_01dB[1]); 2025 an_gain0_01dB[0], an_gain0_01dB[1]);
2282} 2026}
2283 2027
2284u16 hpi_level_get_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2028u16 hpi_level_get_gain(u32 h_control, short an_gain0_01dB[HPI_MAX_CHANNELS]
2285 short an_gain0_01dB[HPI_MAX_CHANNELS]
2286 ) 2029 )
2287{ 2030{
2288 return hpi_control_log_get2(ph_subsys, h_control, HPI_LEVEL_GAIN, 2031 return hpi_control_log_get2(h_control, HPI_LEVEL_GAIN,
2289 &an_gain0_01dB[0], &an_gain0_01dB[1]); 2032 &an_gain0_01dB[0], &an_gain0_01dB[1]);
2290} 2033}
2291 2034
2292u16 hpi_meter_query_channels(const struct hpi_hsubsys *ph_subsys, 2035u16 hpi_meter_query_channels(const u32 h_meter, u32 *p_channels)
2293 const u32 h_meter, u32 *p_channels)
2294{ 2036{
2295 return hpi_control_query(ph_subsys, h_meter, HPI_METER_NUM_CHANNELS, 2037 return hpi_control_query(h_meter, HPI_METER_NUM_CHANNELS, 0, 0,
2296 0, 0, p_channels); 2038 p_channels);
2297} 2039}
2298 2040
2299u16 hpi_meter_get_peak(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2041u16 hpi_meter_get_peak(u32 h_control, short an_peakdB[HPI_MAX_CHANNELS]
2300 short an_peakdB[HPI_MAX_CHANNELS]
2301 ) 2042 )
2302{ 2043{
2303 short i = 0; 2044 short i = 0;
@@ -2307,7 +2048,8 @@ u16 hpi_meter_get_peak(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2307 2048
2308 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 2049 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2309 HPI_CONTROL_GET_STATE); 2050 HPI_CONTROL_GET_STATE);
2310 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 2051 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
2052 return HPI_ERROR_INVALID_HANDLE;
2311 hm.obj_index = hm.obj_index; 2053 hm.obj_index = hm.obj_index;
2312 hm.u.c.attribute = HPI_METER_PEAK; 2054 hm.u.c.attribute = HPI_METER_PEAK;
2313 2055
@@ -2322,8 +2064,7 @@ u16 hpi_meter_get_peak(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2322 return hr.error; 2064 return hr.error;
2323} 2065}
2324 2066
2325u16 hpi_meter_get_rms(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2067u16 hpi_meter_get_rms(u32 h_control, short an_rmsdB[HPI_MAX_CHANNELS]
2326 short an_rmsdB[HPI_MAX_CHANNELS]
2327 ) 2068 )
2328{ 2069{
2329 short i = 0; 2070 short i = 0;
@@ -2333,7 +2074,8 @@ u16 hpi_meter_get_rms(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2333 2074
2334 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 2075 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2335 HPI_CONTROL_GET_STATE); 2076 HPI_CONTROL_GET_STATE);
2336 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 2077 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
2078 return HPI_ERROR_INVALID_HANDLE;
2337 hm.u.c.attribute = HPI_METER_RMS; 2079 hm.u.c.attribute = HPI_METER_RMS;
2338 2080
2339 hpi_send_recv(&hm, &hr); 2081 hpi_send_recv(&hm, &hr);
@@ -2348,22 +2090,20 @@ u16 hpi_meter_get_rms(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2348 return hr.error; 2090 return hr.error;
2349} 2091}
2350 2092
2351u16 hpi_meter_set_rms_ballistics(const struct hpi_hsubsys *ph_subsys, 2093u16 hpi_meter_set_rms_ballistics(u32 h_control, u16 attack, u16 decay)
2352 u32 h_control, u16 attack, u16 decay)
2353{ 2094{
2354 return hpi_control_param_set(ph_subsys, h_control, 2095 return hpi_control_param_set(h_control, HPI_METER_RMS_BALLISTICS,
2355 HPI_METER_RMS_BALLISTICS, attack, decay); 2096 attack, decay);
2356} 2097}
2357 2098
2358u16 hpi_meter_get_rms_ballistics(const struct hpi_hsubsys *ph_subsys, 2099u16 hpi_meter_get_rms_ballistics(u32 h_control, u16 *pn_attack, u16 *pn_decay)
2359 u32 h_control, u16 *pn_attack, u16 *pn_decay)
2360{ 2100{
2361 u32 attack; 2101 u32 attack;
2362 u32 decay; 2102 u32 decay;
2363 u16 error; 2103 u16 error;
2364 2104
2365 error = hpi_control_param2_get(ph_subsys, h_control, 2105 error = hpi_control_param2_get(h_control, HPI_METER_RMS_BALLISTICS,
2366 HPI_METER_RMS_BALLISTICS, &attack, &decay); 2106 &attack, &decay);
2367 2107
2368 if (pn_attack) 2108 if (pn_attack)
2369 *pn_attack = (unsigned short)attack; 2109 *pn_attack = (unsigned short)attack;
@@ -2373,22 +2113,21 @@ u16 hpi_meter_get_rms_ballistics(const struct hpi_hsubsys *ph_subsys,
2373 return error; 2113 return error;
2374} 2114}
2375 2115
2376u16 hpi_meter_set_peak_ballistics(const struct hpi_hsubsys *ph_subsys, 2116u16 hpi_meter_set_peak_ballistics(u32 h_control, u16 attack, u16 decay)
2377 u32 h_control, u16 attack, u16 decay)
2378{ 2117{
2379 return hpi_control_param_set(ph_subsys, h_control, 2118 return hpi_control_param_set(h_control, HPI_METER_PEAK_BALLISTICS,
2380 HPI_METER_PEAK_BALLISTICS, attack, decay); 2119 attack, decay);
2381} 2120}
2382 2121
2383u16 hpi_meter_get_peak_ballistics(const struct hpi_hsubsys *ph_subsys, 2122u16 hpi_meter_get_peak_ballistics(u32 h_control, u16 *pn_attack,
2384 u32 h_control, u16 *pn_attack, u16 *pn_decay) 2123 u16 *pn_decay)
2385{ 2124{
2386 u32 attack; 2125 u32 attack;
2387 u32 decay; 2126 u32 decay;
2388 u16 error; 2127 u16 error;
2389 2128
2390 error = hpi_control_param2_get(ph_subsys, h_control, 2129 error = hpi_control_param2_get(h_control, HPI_METER_PEAK_BALLISTICS,
2391 HPI_METER_PEAK_BALLISTICS, &attack, &decay); 2130 &attack, &decay);
2392 2131
2393 if (pn_attack) 2132 if (pn_attack)
2394 *pn_attack = (short)attack; 2133 *pn_attack = (short)attack;
@@ -2398,55 +2137,53 @@ u16 hpi_meter_get_peak_ballistics(const struct hpi_hsubsys *ph_subsys,
2398 return error; 2137 return error;
2399} 2138}
2400 2139
2401u16 hpi_microphone_set_phantom_power(const struct hpi_hsubsys *ph_subsys, 2140u16 hpi_microphone_set_phantom_power(u32 h_control, u16 on_off)
2402 u32 h_control, u16 on_off)
2403{ 2141{
2404 return hpi_control_param_set(ph_subsys, h_control, 2142 return hpi_control_param_set(h_control, HPI_MICROPHONE_PHANTOM_POWER,
2405 HPI_MICROPHONE_PHANTOM_POWER, (u32)on_off, 0); 2143 (u32)on_off, 0);
2406} 2144}
2407 2145
2408u16 hpi_microphone_get_phantom_power(const struct hpi_hsubsys *ph_subsys, 2146u16 hpi_microphone_get_phantom_power(u32 h_control, u16 *pw_on_off)
2409 u32 h_control, u16 *pw_on_off)
2410{ 2147{
2411 u16 error = 0; 2148 u16 error = 0;
2412 u32 on_off = 0; 2149 u32 on_off = 0;
2413 error = hpi_control_param1_get(ph_subsys, h_control, 2150 error = hpi_control_param1_get(h_control,
2414 HPI_MICROPHONE_PHANTOM_POWER, &on_off); 2151 HPI_MICROPHONE_PHANTOM_POWER, &on_off);
2415 if (pw_on_off) 2152 if (pw_on_off)
2416 *pw_on_off = (u16)on_off; 2153 *pw_on_off = (u16)on_off;
2417 return error; 2154 return error;
2418} 2155}
2419 2156
2420u16 hpi_multiplexer_set_source(const struct hpi_hsubsys *ph_subsys, 2157u16 hpi_multiplexer_set_source(u32 h_control, u16 source_node_type,
2421 u32 h_control, u16 source_node_type, u16 source_node_index) 2158 u16 source_node_index)
2422{ 2159{
2423 return hpi_control_param_set(ph_subsys, h_control, 2160 return hpi_control_param_set(h_control, HPI_MULTIPLEXER_SOURCE,
2424 HPI_MULTIPLEXER_SOURCE, source_node_type, source_node_index); 2161 source_node_type, source_node_index);
2425} 2162}
2426 2163
2427u16 hpi_multiplexer_get_source(const struct hpi_hsubsys *ph_subsys, 2164u16 hpi_multiplexer_get_source(u32 h_control, u16 *source_node_type,
2428 u32 h_control, u16 *source_node_type, u16 *source_node_index) 2165 u16 *source_node_index)
2429{ 2166{
2430 u32 node, index; 2167 u32 node, index;
2431 u16 error = hpi_control_param2_get(ph_subsys, h_control, 2168 u16 err = hpi_control_param2_get(h_control,
2432 HPI_MULTIPLEXER_SOURCE, &node, 2169 HPI_MULTIPLEXER_SOURCE, &node,
2433 &index); 2170 &index);
2434 if (source_node_type) 2171 if (source_node_type)
2435 *source_node_type = (u16)node; 2172 *source_node_type = (u16)node;
2436 if (source_node_index) 2173 if (source_node_index)
2437 *source_node_index = (u16)index; 2174 *source_node_index = (u16)index;
2438 return error; 2175 return err;
2439} 2176}
2440 2177
2441u16 hpi_multiplexer_query_source(const struct hpi_hsubsys *ph_subsys, 2178u16 hpi_multiplexer_query_source(u32 h_control, u16 index,
2442 u32 h_control, u16 index, u16 *source_node_type, 2179 u16 *source_node_type, u16 *source_node_index)
2443 u16 *source_node_index)
2444{ 2180{
2445 struct hpi_message hm; 2181 struct hpi_message hm;
2446 struct hpi_response hr; 2182 struct hpi_response hr;
2447 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 2183 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2448 HPI_CONTROL_GET_STATE); 2184 HPI_CONTROL_GET_STATE);
2449 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 2185 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
2186 return HPI_ERROR_INVALID_HANDLE;
2450 hm.u.c.attribute = HPI_MULTIPLEXER_QUERYSOURCE; 2187 hm.u.c.attribute = HPI_MULTIPLEXER_QUERYSOURCE;
2451 hm.u.c.param1 = index; 2188 hm.u.c.param1 = index;
2452 2189
@@ -2459,15 +2196,15 @@ u16 hpi_multiplexer_query_source(const struct hpi_hsubsys *ph_subsys,
2459 return hr.error; 2196 return hr.error;
2460} 2197}
2461 2198
2462u16 hpi_parametricEQ__get_info(const struct hpi_hsubsys *ph_subsys, 2199u16 hpi_parametric_eq_get_info(u32 h_control, u16 *pw_number_of_bands,
2463 u32 h_control, u16 *pw_number_of_bands, u16 *pw_on_off) 2200 u16 *pw_on_off)
2464{ 2201{
2465 u32 oB = 0; 2202 u32 oB = 0;
2466 u32 oO = 0; 2203 u32 oO = 0;
2467 u16 error = 0; 2204 u16 error = 0;
2468 2205
2469 error = hpi_control_param2_get(ph_subsys, h_control, 2206 error = hpi_control_param2_get(h_control, HPI_EQUALIZER_NUM_FILTERS,
2470 HPI_EQUALIZER_NUM_FILTERS, &oO, &oB); 2207 &oO, &oB);
2471 if (pw_number_of_bands) 2208 if (pw_number_of_bands)
2472 *pw_number_of_bands = (u16)oB; 2209 *pw_number_of_bands = (u16)oB;
2473 if (pw_on_off) 2210 if (pw_on_off)
@@ -2475,23 +2212,22 @@ u16 hpi_parametricEQ__get_info(const struct hpi_hsubsys *ph_subsys,
2475 return error; 2212 return error;
2476} 2213}
2477 2214
2478u16 hpi_parametricEQ__set_state(const struct hpi_hsubsys *ph_subsys, 2215u16 hpi_parametric_eq_set_state(u32 h_control, u16 on_off)
2479 u32 h_control, u16 on_off)
2480{ 2216{
2481 return hpi_control_param_set(ph_subsys, h_control, 2217 return hpi_control_param_set(h_control, HPI_EQUALIZER_NUM_FILTERS,
2482 HPI_EQUALIZER_NUM_FILTERS, on_off, 0); 2218 on_off, 0);
2483} 2219}
2484 2220
2485u16 hpi_parametricEQ__get_band(const struct hpi_hsubsys *ph_subsys, 2221u16 hpi_parametric_eq_get_band(u32 h_control, u16 index, u16 *pn_type,
2486 u32 h_control, u16 index, u16 *pn_type, u32 *pfrequency_hz, 2222 u32 *pfrequency_hz, short *pnQ100, short *pn_gain0_01dB)
2487 short *pnQ100, short *pn_gain0_01dB)
2488{ 2223{
2489 struct hpi_message hm; 2224 struct hpi_message hm;
2490 struct hpi_response hr; 2225 struct hpi_response hr;
2491 2226
2492 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 2227 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2493 HPI_CONTROL_GET_STATE); 2228 HPI_CONTROL_GET_STATE);
2494 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 2229 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
2230 return HPI_ERROR_INVALID_HANDLE;
2495 hm.u.c.attribute = HPI_EQUALIZER_FILTER; 2231 hm.u.c.attribute = HPI_EQUALIZER_FILTER;
2496 hm.u.c.param2 = index; 2232 hm.u.c.param2 = index;
2497 2233
@@ -2509,16 +2245,16 @@ u16 hpi_parametricEQ__get_band(const struct hpi_hsubsys *ph_subsys,
2509 return hr.error; 2245 return hr.error;
2510} 2246}
2511 2247
2512u16 hpi_parametricEQ__set_band(const struct hpi_hsubsys *ph_subsys, 2248u16 hpi_parametric_eq_set_band(u32 h_control, u16 index, u16 type,
2513 u32 h_control, u16 index, u16 type, u32 frequency_hz, short q100, 2249 u32 frequency_hz, short q100, short gain0_01dB)
2514 short gain0_01dB)
2515{ 2250{
2516 struct hpi_message hm; 2251 struct hpi_message hm;
2517 struct hpi_response hr; 2252 struct hpi_response hr;
2518 2253
2519 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 2254 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2520 HPI_CONTROL_SET_STATE); 2255 HPI_CONTROL_SET_STATE);
2521 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 2256 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
2257 return HPI_ERROR_INVALID_HANDLE;
2522 2258
2523 hm.u.c.param1 = frequency_hz; 2259 hm.u.c.param1 = frequency_hz;
2524 hm.u.c.param2 = (index & 0xFFFFL) + ((u32)type << 16); 2260 hm.u.c.param2 = (index & 0xFFFFL) + ((u32)type << 16);
@@ -2531,8 +2267,7 @@ u16 hpi_parametricEQ__set_band(const struct hpi_hsubsys *ph_subsys,
2531 return hr.error; 2267 return hr.error;
2532} 2268}
2533 2269
2534u16 hpi_parametricEQ__get_coeffs(const struct hpi_hsubsys *ph_subsys, 2270u16 hpi_parametric_eq_get_coeffs(u32 h_control, u16 index, short coeffs[5]
2535 u32 h_control, u16 index, short coeffs[5]
2536 ) 2271 )
2537{ 2272{
2538 struct hpi_message hm; 2273 struct hpi_message hm;
@@ -2540,7 +2275,8 @@ u16 hpi_parametricEQ__get_coeffs(const struct hpi_hsubsys *ph_subsys,
2540 2275
2541 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 2276 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2542 HPI_CONTROL_GET_STATE); 2277 HPI_CONTROL_GET_STATE);
2543 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 2278 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
2279 return HPI_ERROR_INVALID_HANDLE;
2544 hm.u.c.attribute = HPI_EQUALIZER_COEFFICIENTS; 2280 hm.u.c.attribute = HPI_EQUALIZER_COEFFICIENTS;
2545 hm.u.c.param2 = index; 2281 hm.u.c.param2 = index;
2546 2282
@@ -2555,444 +2291,388 @@ u16 hpi_parametricEQ__get_coeffs(const struct hpi_hsubsys *ph_subsys,
2555 return hr.error; 2291 return hr.error;
2556} 2292}
2557 2293
2558u16 hpi_sample_clock_query_source(const struct hpi_hsubsys *ph_subsys, 2294u16 hpi_sample_clock_query_source(const u32 h_clock, const u32 index,
2559 const u32 h_clock, const u32 index, u16 *pw_source) 2295 u16 *pw_source)
2560{ 2296{
2561 u32 qr; 2297 u32 qr;
2562 u16 err; 2298 u16 err;
2563 2299
2564 err = hpi_control_query(ph_subsys, h_clock, HPI_SAMPLECLOCK_SOURCE, 2300 err = hpi_control_query(h_clock, HPI_SAMPLECLOCK_SOURCE, index, 0,
2565 index, 0, &qr); 2301 &qr);
2566 *pw_source = (u16)qr; 2302 *pw_source = (u16)qr;
2567 return err; 2303 return err;
2568} 2304}
2569 2305
2570u16 hpi_sample_clock_set_source(const struct hpi_hsubsys *ph_subsys, 2306u16 hpi_sample_clock_set_source(u32 h_control, u16 source)
2571 u32 h_control, u16 source)
2572{ 2307{
2573 return hpi_control_param_set(ph_subsys, h_control, 2308 return hpi_control_param_set(h_control, HPI_SAMPLECLOCK_SOURCE,
2574 HPI_SAMPLECLOCK_SOURCE, source, 0); 2309 source, 0);
2575} 2310}
2576 2311
2577u16 hpi_sample_clock_get_source(const struct hpi_hsubsys *ph_subsys, 2312u16 hpi_sample_clock_get_source(u32 h_control, u16 *pw_source)
2578 u32 h_control, u16 *pw_source)
2579{ 2313{
2580 u16 error = 0; 2314 u16 err = 0;
2581 u32 source = 0; 2315 u32 source = 0;
2582 error = hpi_control_param1_get(ph_subsys, h_control, 2316 err = hpi_control_param1_get(h_control, HPI_SAMPLECLOCK_SOURCE,
2583 HPI_SAMPLECLOCK_SOURCE, &source); 2317 &source);
2584 if (!error) 2318 if (!err)
2585 if (pw_source) 2319 if (pw_source)
2586 *pw_source = (u16)source; 2320 *pw_source = (u16)source;
2587 return error; 2321 return err;
2588} 2322}
2589 2323
2590u16 hpi_sample_clock_query_source_index(const struct hpi_hsubsys *ph_subsys, 2324u16 hpi_sample_clock_query_source_index(const u32 h_clock, const u32 index,
2591 const u32 h_clock, const u32 index, const u32 source, 2325 const u32 source, u16 *pw_source_index)
2592 u16 *pw_source_index)
2593{ 2326{
2594 u32 qr; 2327 u32 qr;
2595 u16 err; 2328 u16 err;
2596 2329
2597 err = hpi_control_query(ph_subsys, h_clock, 2330 err = hpi_control_query(h_clock, HPI_SAMPLECLOCK_SOURCE_INDEX, index,
2598 HPI_SAMPLECLOCK_SOURCE_INDEX, index, source, &qr); 2331 source, &qr);
2599 *pw_source_index = (u16)qr; 2332 *pw_source_index = (u16)qr;
2600 return err; 2333 return err;
2601} 2334}
2602 2335
2603u16 hpi_sample_clock_set_source_index(const struct hpi_hsubsys *ph_subsys, 2336u16 hpi_sample_clock_set_source_index(u32 h_control, u16 source_index)
2604 u32 h_control, u16 source_index)
2605{ 2337{
2606 return hpi_control_param_set(ph_subsys, h_control, 2338 return hpi_control_param_set(h_control, HPI_SAMPLECLOCK_SOURCE_INDEX,
2607 HPI_SAMPLECLOCK_SOURCE_INDEX, source_index, 0); 2339 source_index, 0);
2608} 2340}
2609 2341
2610u16 hpi_sample_clock_get_source_index(const struct hpi_hsubsys *ph_subsys, 2342u16 hpi_sample_clock_get_source_index(u32 h_control, u16 *pw_source_index)
2611 u32 h_control, u16 *pw_source_index)
2612{ 2343{
2613 u16 error = 0; 2344 u16 err = 0;
2614 u32 source_index = 0; 2345 u32 source_index = 0;
2615 error = hpi_control_param1_get(ph_subsys, h_control, 2346 err = hpi_control_param1_get(h_control, HPI_SAMPLECLOCK_SOURCE_INDEX,
2616 HPI_SAMPLECLOCK_SOURCE_INDEX, &source_index); 2347 &source_index);
2617 if (!error) 2348 if (!err)
2618 if (pw_source_index) 2349 if (pw_source_index)
2619 *pw_source_index = (u16)source_index; 2350 *pw_source_index = (u16)source_index;
2620 return error; 2351 return err;
2621} 2352}
2622 2353
2623u16 hpi_sample_clock_query_local_rate(const struct hpi_hsubsys *ph_subsys, 2354u16 hpi_sample_clock_query_local_rate(const u32 h_clock, const u32 index,
2624 const u32 h_clock, const u32 index, u32 *prate) 2355 u32 *prate)
2625{ 2356{
2626 u16 err; 2357 u16 err;
2627 err = hpi_control_query(ph_subsys, h_clock, 2358 err = hpi_control_query(h_clock, HPI_SAMPLECLOCK_LOCAL_SAMPLERATE,
2628 HPI_SAMPLECLOCK_LOCAL_SAMPLERATE, index, 0, prate); 2359 index, 0, prate);
2629 2360
2630 return err; 2361 return err;
2631} 2362}
2632 2363
2633u16 hpi_sample_clock_set_local_rate(const struct hpi_hsubsys *ph_subsys, 2364u16 hpi_sample_clock_set_local_rate(u32 h_control, u32 sample_rate)
2634 u32 h_control, u32 sample_rate)
2635{ 2365{
2636 return hpi_control_param_set(ph_subsys, h_control, 2366 return hpi_control_param_set(h_control,
2637 HPI_SAMPLECLOCK_LOCAL_SAMPLERATE, sample_rate, 0); 2367 HPI_SAMPLECLOCK_LOCAL_SAMPLERATE, sample_rate, 0);
2638} 2368}
2639 2369
2640u16 hpi_sample_clock_get_local_rate(const struct hpi_hsubsys *ph_subsys, 2370u16 hpi_sample_clock_get_local_rate(u32 h_control, u32 *psample_rate)
2641 u32 h_control, u32 *psample_rate)
2642{ 2371{
2643 u16 error = 0; 2372 u16 err = 0;
2644 u32 sample_rate = 0; 2373 u32 sample_rate = 0;
2645 error = hpi_control_param1_get(ph_subsys, h_control, 2374 err = hpi_control_param1_get(h_control,
2646 HPI_SAMPLECLOCK_LOCAL_SAMPLERATE, &sample_rate); 2375 HPI_SAMPLECLOCK_LOCAL_SAMPLERATE, &sample_rate);
2647 if (!error) 2376 if (!err)
2648 if (psample_rate) 2377 if (psample_rate)
2649 *psample_rate = sample_rate; 2378 *psample_rate = sample_rate;
2650 return error; 2379 return err;
2651} 2380}
2652 2381
2653u16 hpi_sample_clock_get_sample_rate(const struct hpi_hsubsys *ph_subsys, 2382u16 hpi_sample_clock_get_sample_rate(u32 h_control, u32 *psample_rate)
2654 u32 h_control, u32 *psample_rate)
2655{ 2383{
2656 u16 error = 0; 2384 u16 err = 0;
2657 u32 sample_rate = 0; 2385 u32 sample_rate = 0;
2658 error = hpi_control_param1_get(ph_subsys, h_control, 2386 err = hpi_control_param1_get(h_control, HPI_SAMPLECLOCK_SAMPLERATE,
2659 HPI_SAMPLECLOCK_SAMPLERATE, &sample_rate); 2387 &sample_rate);
2660 if (!error) 2388 if (!err)
2661 if (psample_rate) 2389 if (psample_rate)
2662 *psample_rate = sample_rate; 2390 *psample_rate = sample_rate;
2663 return error; 2391 return err;
2664} 2392}
2665 2393
2666u16 hpi_sample_clock_set_auto(const struct hpi_hsubsys *ph_subsys, 2394u16 hpi_sample_clock_set_auto(u32 h_control, u32 enable)
2667 u32 h_control, u32 enable)
2668{ 2395{
2669 return hpi_control_param_set(ph_subsys, h_control, 2396 return hpi_control_param_set(h_control, HPI_SAMPLECLOCK_AUTO, enable,
2670 HPI_SAMPLECLOCK_AUTO, enable, 0); 2397 0);
2671} 2398}
2672 2399
2673u16 hpi_sample_clock_get_auto(const struct hpi_hsubsys *ph_subsys, 2400u16 hpi_sample_clock_get_auto(u32 h_control, u32 *penable)
2674 u32 h_control, u32 *penable)
2675{ 2401{
2676 return hpi_control_param1_get(ph_subsys, h_control, 2402 return hpi_control_param1_get(h_control, HPI_SAMPLECLOCK_AUTO,
2677 HPI_SAMPLECLOCK_AUTO, penable); 2403 penable);
2678} 2404}
2679 2405
2680u16 hpi_sample_clock_set_local_rate_lock(const struct hpi_hsubsys *ph_subsys, 2406u16 hpi_sample_clock_set_local_rate_lock(u32 h_control, u32 lock)
2681 u32 h_control, u32 lock)
2682{ 2407{
2683 return hpi_control_param_set(ph_subsys, h_control, 2408 return hpi_control_param_set(h_control, HPI_SAMPLECLOCK_LOCAL_LOCK,
2684 HPI_SAMPLECLOCK_LOCAL_LOCK, lock, 0); 2409 lock, 0);
2685} 2410}
2686 2411
2687u16 hpi_sample_clock_get_local_rate_lock(const struct hpi_hsubsys *ph_subsys, 2412u16 hpi_sample_clock_get_local_rate_lock(u32 h_control, u32 *plock)
2688 u32 h_control, u32 *plock)
2689{ 2413{
2690 return hpi_control_param1_get(ph_subsys, h_control, 2414 return hpi_control_param1_get(h_control, HPI_SAMPLECLOCK_LOCAL_LOCK,
2691 HPI_SAMPLECLOCK_LOCAL_LOCK, plock); 2415 plock);
2692} 2416}
2693 2417
2694u16 hpi_tone_detector_get_frequency(const struct hpi_hsubsys *ph_subsys, 2418u16 hpi_tone_detector_get_frequency(u32 h_control, u32 index, u32 *frequency)
2695 u32 h_control, u32 index, u32 *frequency)
2696{ 2419{
2697 return hpi_control_param_get(ph_subsys, h_control, 2420 return hpi_control_param_get(h_control, HPI_TONEDETECTOR_FREQUENCY,
2698 HPI_TONEDETECTOR_FREQUENCY, index, 0, frequency, NULL); 2421 index, 0, frequency, NULL);
2699} 2422}
2700 2423
2701u16 hpi_tone_detector_get_state(const struct hpi_hsubsys *ph_subsys, 2424u16 hpi_tone_detector_get_state(u32 h_control, u32 *state)
2702 u32 h_control, u32 *state)
2703{ 2425{
2704 return hpi_control_param1_get(ph_subsys, h_control, 2426 return hpi_control_param1_get(h_control, HPI_TONEDETECTOR_STATE,
2705 HPI_TONEDETECTOR_STATE, state); 2427 state);
2706} 2428}
2707 2429
2708u16 hpi_tone_detector_set_enable(const struct hpi_hsubsys *ph_subsys, 2430u16 hpi_tone_detector_set_enable(u32 h_control, u32 enable)
2709 u32 h_control, u32 enable)
2710{ 2431{
2711 return hpi_control_param_set(ph_subsys, h_control, HPI_GENERIC_ENABLE, 2432 return hpi_control_param_set(h_control, HPI_GENERIC_ENABLE, enable,
2712 (u32)enable, 0); 2433 0);
2713} 2434}
2714 2435
2715u16 hpi_tone_detector_get_enable(const struct hpi_hsubsys *ph_subsys, 2436u16 hpi_tone_detector_get_enable(u32 h_control, u32 *enable)
2716 u32 h_control, u32 *enable)
2717{ 2437{
2718 return hpi_control_param1_get(ph_subsys, h_control, 2438 return hpi_control_param1_get(h_control, HPI_GENERIC_ENABLE, enable);
2719 HPI_GENERIC_ENABLE, enable);
2720} 2439}
2721 2440
2722u16 hpi_tone_detector_set_event_enable(const struct hpi_hsubsys *ph_subsys, 2441u16 hpi_tone_detector_set_event_enable(u32 h_control, u32 event_enable)
2723 u32 h_control, u32 event_enable)
2724{ 2442{
2725 return hpi_control_param_set(ph_subsys, h_control, 2443 return hpi_control_param_set(h_control, HPI_GENERIC_EVENT_ENABLE,
2726 HPI_GENERIC_EVENT_ENABLE, (u32)event_enable, 0); 2444 (u32)event_enable, 0);
2727} 2445}
2728 2446
2729u16 hpi_tone_detector_get_event_enable(const struct hpi_hsubsys *ph_subsys, 2447u16 hpi_tone_detector_get_event_enable(u32 h_control, u32 *event_enable)
2730 u32 h_control, u32 *event_enable)
2731{ 2448{
2732 return hpi_control_param1_get(ph_subsys, h_control, 2449 return hpi_control_param1_get(h_control, HPI_GENERIC_EVENT_ENABLE,
2733 HPI_GENERIC_EVENT_ENABLE, event_enable); 2450 event_enable);
2734} 2451}
2735 2452
2736u16 hpi_tone_detector_set_threshold(const struct hpi_hsubsys *ph_subsys, 2453u16 hpi_tone_detector_set_threshold(u32 h_control, int threshold)
2737 u32 h_control, int threshold)
2738{ 2454{
2739 return hpi_control_param_set(ph_subsys, h_control, 2455 return hpi_control_param_set(h_control, HPI_TONEDETECTOR_THRESHOLD,
2740 HPI_TONEDETECTOR_THRESHOLD, (u32)threshold, 0); 2456 (u32)threshold, 0);
2741} 2457}
2742 2458
2743u16 hpi_tone_detector_get_threshold(const struct hpi_hsubsys *ph_subsys, 2459u16 hpi_tone_detector_get_threshold(u32 h_control, int *threshold)
2744 u32 h_control, int *threshold)
2745{ 2460{
2746 return hpi_control_param1_get(ph_subsys, h_control, 2461 return hpi_control_param1_get(h_control, HPI_TONEDETECTOR_THRESHOLD,
2747 HPI_TONEDETECTOR_THRESHOLD, (u32 *)threshold); 2462 (u32 *)threshold);
2748} 2463}
2749 2464
2750u16 hpi_silence_detector_get_state(const struct hpi_hsubsys *ph_subsys, 2465u16 hpi_silence_detector_get_state(u32 h_control, u32 *state)
2751 u32 h_control, u32 *state)
2752{ 2466{
2753 return hpi_control_param1_get(ph_subsys, h_control, 2467 return hpi_control_param1_get(h_control, HPI_SILENCEDETECTOR_STATE,
2754 HPI_SILENCEDETECTOR_STATE, state); 2468 state);
2755} 2469}
2756 2470
2757u16 hpi_silence_detector_set_enable(const struct hpi_hsubsys *ph_subsys, 2471u16 hpi_silence_detector_set_enable(u32 h_control, u32 enable)
2758 u32 h_control, u32 enable)
2759{ 2472{
2760 return hpi_control_param_set(ph_subsys, h_control, HPI_GENERIC_ENABLE, 2473 return hpi_control_param_set(h_control, HPI_GENERIC_ENABLE, enable,
2761 (u32)enable, 0); 2474 0);
2762} 2475}
2763 2476
2764u16 hpi_silence_detector_get_enable(const struct hpi_hsubsys *ph_subsys, 2477u16 hpi_silence_detector_get_enable(u32 h_control, u32 *enable)
2765 u32 h_control, u32 *enable)
2766{ 2478{
2767 return hpi_control_param1_get(ph_subsys, h_control, 2479 return hpi_control_param1_get(h_control, HPI_GENERIC_ENABLE, enable);
2768 HPI_GENERIC_ENABLE, enable);
2769} 2480}
2770 2481
2771u16 hpi_silence_detector_set_event_enable(const struct hpi_hsubsys *ph_subsys, 2482u16 hpi_silence_detector_set_event_enable(u32 h_control, u32 event_enable)
2772 u32 h_control, u32 event_enable)
2773{ 2483{
2774 return hpi_control_param_set(ph_subsys, h_control, 2484 return hpi_control_param_set(h_control, HPI_GENERIC_EVENT_ENABLE,
2775 HPI_GENERIC_EVENT_ENABLE, event_enable, 0); 2485 event_enable, 0);
2776} 2486}
2777 2487
2778u16 hpi_silence_detector_get_event_enable(const struct hpi_hsubsys *ph_subsys, 2488u16 hpi_silence_detector_get_event_enable(u32 h_control, u32 *event_enable)
2779 u32 h_control, u32 *event_enable)
2780{ 2489{
2781 return hpi_control_param1_get(ph_subsys, h_control, 2490 return hpi_control_param1_get(h_control, HPI_GENERIC_EVENT_ENABLE,
2782 HPI_GENERIC_EVENT_ENABLE, event_enable); 2491 event_enable);
2783} 2492}
2784 2493
2785u16 hpi_silence_detector_set_delay(const struct hpi_hsubsys *ph_subsys, 2494u16 hpi_silence_detector_set_delay(u32 h_control, u32 delay)
2786 u32 h_control, u32 delay)
2787{ 2495{
2788 return hpi_control_param_set(ph_subsys, h_control, 2496 return hpi_control_param_set(h_control, HPI_SILENCEDETECTOR_DELAY,
2789 HPI_SILENCEDETECTOR_DELAY, delay, 0); 2497 delay, 0);
2790} 2498}
2791 2499
2792u16 hpi_silence_detector_get_delay(const struct hpi_hsubsys *ph_subsys, 2500u16 hpi_silence_detector_get_delay(u32 h_control, u32 *delay)
2793 u32 h_control, u32 *delay)
2794{ 2501{
2795 return hpi_control_param1_get(ph_subsys, h_control, 2502 return hpi_control_param1_get(h_control, HPI_SILENCEDETECTOR_DELAY,
2796 HPI_SILENCEDETECTOR_DELAY, delay); 2503 delay);
2797} 2504}
2798 2505
2799u16 hpi_silence_detector_set_threshold(const struct hpi_hsubsys *ph_subsys, 2506u16 hpi_silence_detector_set_threshold(u32 h_control, int threshold)
2800 u32 h_control, int threshold)
2801{ 2507{
2802 return hpi_control_param_set(ph_subsys, h_control, 2508 return hpi_control_param_set(h_control, HPI_SILENCEDETECTOR_THRESHOLD,
2803 HPI_SILENCEDETECTOR_THRESHOLD, threshold, 0); 2509 threshold, 0);
2804} 2510}
2805 2511
2806u16 hpi_silence_detector_get_threshold(const struct hpi_hsubsys *ph_subsys, 2512u16 hpi_silence_detector_get_threshold(u32 h_control, int *threshold)
2807 u32 h_control, int *threshold)
2808{ 2513{
2809 return hpi_control_param1_get(ph_subsys, h_control, 2514 return hpi_control_param1_get(h_control,
2810 HPI_SILENCEDETECTOR_THRESHOLD, (u32 *)threshold); 2515 HPI_SILENCEDETECTOR_THRESHOLD, (u32 *)threshold);
2811} 2516}
2812 2517
2813u16 hpi_tuner_query_band(const struct hpi_hsubsys *ph_subsys, 2518u16 hpi_tuner_query_band(const u32 h_tuner, const u32 index, u16 *pw_band)
2814 const u32 h_tuner, const u32 index, u16 *pw_band)
2815{ 2519{
2816 u32 qr; 2520 u32 qr;
2817 u16 err; 2521 u16 err;
2818 2522
2819 err = hpi_control_query(ph_subsys, h_tuner, HPI_TUNER_BAND, index, 0, 2523 err = hpi_control_query(h_tuner, HPI_TUNER_BAND, index, 0, &qr);
2820 &qr);
2821 *pw_band = (u16)qr; 2524 *pw_band = (u16)qr;
2822 return err; 2525 return err;
2823} 2526}
2824 2527
2825u16 hpi_tuner_set_band(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2528u16 hpi_tuner_set_band(u32 h_control, u16 band)
2826 u16 band)
2827{ 2529{
2828 return hpi_control_param_set(ph_subsys, h_control, HPI_TUNER_BAND, 2530 return hpi_control_param_set(h_control, HPI_TUNER_BAND, band, 0);
2829 band, 0);
2830} 2531}
2831 2532
2832u16 hpi_tuner_get_band(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2533u16 hpi_tuner_get_band(u32 h_control, u16 *pw_band)
2833 u16 *pw_band)
2834{ 2534{
2835 u32 band = 0; 2535 u32 band = 0;
2836 u16 error = 0; 2536 u16 error = 0;
2837 2537
2838 error = hpi_control_param1_get(ph_subsys, h_control, HPI_TUNER_BAND, 2538 error = hpi_control_param1_get(h_control, HPI_TUNER_BAND, &band);
2839 &band);
2840 if (pw_band) 2539 if (pw_band)
2841 *pw_band = (u16)band; 2540 *pw_band = (u16)band;
2842 return error; 2541 return error;
2843} 2542}
2844 2543
2845u16 hpi_tuner_query_frequency(const struct hpi_hsubsys *ph_subsys, 2544u16 hpi_tuner_query_frequency(const u32 h_tuner, const u32 index,
2846 const u32 h_tuner, const u32 index, const u16 band, u32 *pfreq) 2545 const u16 band, u32 *pfreq)
2847{ 2546{
2848 return hpi_control_query(ph_subsys, h_tuner, HPI_TUNER_FREQ, index, 2547 return hpi_control_query(h_tuner, HPI_TUNER_FREQ, index, band, pfreq);
2849 band, pfreq);
2850} 2548}
2851 2549
2852u16 hpi_tuner_set_frequency(const struct hpi_hsubsys *ph_subsys, 2550u16 hpi_tuner_set_frequency(u32 h_control, u32 freq_ink_hz)
2853 u32 h_control, u32 freq_ink_hz)
2854{ 2551{
2855 return hpi_control_param_set(ph_subsys, h_control, HPI_TUNER_FREQ, 2552 return hpi_control_param_set(h_control, HPI_TUNER_FREQ, freq_ink_hz,
2856 freq_ink_hz, 0); 2553 0);
2857} 2554}
2858 2555
2859u16 hpi_tuner_get_frequency(const struct hpi_hsubsys *ph_subsys, 2556u16 hpi_tuner_get_frequency(u32 h_control, u32 *pw_freq_ink_hz)
2860 u32 h_control, u32 *pw_freq_ink_hz)
2861{ 2557{
2862 return hpi_control_param1_get(ph_subsys, h_control, HPI_TUNER_FREQ, 2558 return hpi_control_param1_get(h_control, HPI_TUNER_FREQ,
2863 pw_freq_ink_hz); 2559 pw_freq_ink_hz);
2864} 2560}
2865 2561
2866u16 hpi_tuner_query_gain(const struct hpi_hsubsys *ph_subsys, 2562u16 hpi_tuner_query_gain(const u32 h_tuner, const u32 index, u16 *pw_gain)
2867 const u32 h_tuner, const u32 index, u16 *pw_gain)
2868{ 2563{
2869 u32 qr; 2564 u32 qr;
2870 u16 err; 2565 u16 err;
2871 2566
2872 err = hpi_control_query(ph_subsys, h_tuner, HPI_TUNER_BAND, index, 0, 2567 err = hpi_control_query(h_tuner, HPI_TUNER_BAND, index, 0, &qr);
2873 &qr);
2874 *pw_gain = (u16)qr; 2568 *pw_gain = (u16)qr;
2875 return err; 2569 return err;
2876} 2570}
2877 2571
2878u16 hpi_tuner_set_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2572u16 hpi_tuner_set_gain(u32 h_control, short gain)
2879 short gain)
2880{ 2573{
2881 return hpi_control_param_set(ph_subsys, h_control, HPI_TUNER_GAIN, 2574 return hpi_control_param_set(h_control, HPI_TUNER_GAIN, gain, 0);
2882 gain, 0);
2883} 2575}
2884 2576
2885u16 hpi_tuner_get_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2577u16 hpi_tuner_get_gain(u32 h_control, short *pn_gain)
2886 short *pn_gain)
2887{ 2578{
2888 u32 gain = 0; 2579 u32 gain = 0;
2889 u16 error = 0; 2580 u16 error = 0;
2890 2581
2891 error = hpi_control_param1_get(ph_subsys, h_control, HPI_TUNER_GAIN, 2582 error = hpi_control_param1_get(h_control, HPI_TUNER_GAIN, &gain);
2892 &gain);
2893 if (pn_gain) 2583 if (pn_gain)
2894 *pn_gain = (u16)gain; 2584 *pn_gain = (u16)gain;
2895 return error; 2585 return error;
2896} 2586}
2897 2587
2898u16 hpi_tuner_getRF_level(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2588u16 hpi_tuner_get_rf_level(u32 h_control, short *pw_level)
2899 short *pw_level)
2900{ 2589{
2901 struct hpi_message hm; 2590 struct hpi_message hm;
2902 struct hpi_response hr; 2591 struct hpi_response hr;
2903 2592
2904 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 2593 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2905 HPI_CONTROL_GET_STATE); 2594 HPI_CONTROL_GET_STATE);
2906 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 2595 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
2907 hm.u.c.attribute = HPI_TUNER_LEVEL; 2596 return HPI_ERROR_INVALID_HANDLE;
2908 hm.u.c.param1 = HPI_TUNER_LEVEL_AVERAGE; 2597 hm.u.cu.attribute = HPI_TUNER_LEVEL_AVG;
2909 hpi_send_recv(&hm, &hr); 2598 hpi_send_recv(&hm, &hr);
2910 if (pw_level) 2599 if (pw_level)
2911 *pw_level = (short)hr.u.c.param1; 2600 *pw_level = hr.u.cu.tuner.s_level;
2912 return hr.error; 2601 return hr.error;
2913} 2602}
2914 2603
2915u16 hpi_tuner_get_rawRF_level(const struct hpi_hsubsys *ph_subsys, 2604u16 hpi_tuner_get_raw_rf_level(u32 h_control, short *pw_level)
2916 u32 h_control, short *pw_level)
2917{ 2605{
2918 struct hpi_message hm; 2606 struct hpi_message hm;
2919 struct hpi_response hr; 2607 struct hpi_response hr;
2920 2608
2921 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 2609 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2922 HPI_CONTROL_GET_STATE); 2610 HPI_CONTROL_GET_STATE);
2923 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 2611 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
2924 hm.u.c.attribute = HPI_TUNER_LEVEL; 2612 return HPI_ERROR_INVALID_HANDLE;
2925 hm.u.c.param1 = HPI_TUNER_LEVEL_RAW; 2613 hm.u.cu.attribute = HPI_TUNER_LEVEL_RAW;
2926 hpi_send_recv(&hm, &hr); 2614 hpi_send_recv(&hm, &hr);
2927 if (pw_level) 2615 if (pw_level)
2928 *pw_level = (short)hr.u.c.param1; 2616 *pw_level = hr.u.cu.tuner.s_level;
2929 return hr.error; 2617 return hr.error;
2930} 2618}
2931 2619
2932u16 hpi_tuner_query_deemphasis(const struct hpi_hsubsys *ph_subsys, 2620u16 hpi_tuner_query_deemphasis(const u32 h_tuner, const u32 index,
2933 const u32 h_tuner, const u32 index, const u16 band, u32 *pdeemphasis) 2621 const u16 band, u32 *pdeemphasis)
2934{ 2622{
2935 return hpi_control_query(ph_subsys, h_tuner, HPI_TUNER_DEEMPHASIS, 2623 return hpi_control_query(h_tuner, HPI_TUNER_DEEMPHASIS, index, band,
2936 index, band, pdeemphasis); 2624 pdeemphasis);
2937} 2625}
2938 2626
2939u16 hpi_tuner_set_deemphasis(const struct hpi_hsubsys *ph_subsys, 2627u16 hpi_tuner_set_deemphasis(u32 h_control, u32 deemphasis)
2940 u32 h_control, u32 deemphasis)
2941{ 2628{
2942 return hpi_control_param_set(ph_subsys, h_control, 2629 return hpi_control_param_set(h_control, HPI_TUNER_DEEMPHASIS,
2943 HPI_TUNER_DEEMPHASIS, deemphasis, 0); 2630 deemphasis, 0);
2944} 2631}
2945 2632
2946u16 hpi_tuner_get_deemphasis(const struct hpi_hsubsys *ph_subsys, 2633u16 hpi_tuner_get_deemphasis(u32 h_control, u32 *pdeemphasis)
2947 u32 h_control, u32 *pdeemphasis)
2948{ 2634{
2949 return hpi_control_param1_get(ph_subsys, h_control, 2635 return hpi_control_param1_get(h_control, HPI_TUNER_DEEMPHASIS,
2950 HPI_TUNER_DEEMPHASIS, pdeemphasis); 2636 pdeemphasis);
2951} 2637}
2952 2638
2953u16 hpi_tuner_query_program(const struct hpi_hsubsys *ph_subsys, 2639u16 hpi_tuner_query_program(const u32 h_tuner, u32 *pbitmap_program)
2954 const u32 h_tuner, u32 *pbitmap_program)
2955{ 2640{
2956 return hpi_control_query(ph_subsys, h_tuner, HPI_TUNER_PROGRAM, 0, 0, 2641 return hpi_control_query(h_tuner, HPI_TUNER_PROGRAM, 0, 0,
2957 pbitmap_program); 2642 pbitmap_program);
2958} 2643}
2959 2644
2960u16 hpi_tuner_set_program(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2645u16 hpi_tuner_set_program(u32 h_control, u32 program)
2961 u32 program)
2962{ 2646{
2963 return hpi_control_param_set(ph_subsys, h_control, HPI_TUNER_PROGRAM, 2647 return hpi_control_param_set(h_control, HPI_TUNER_PROGRAM, program,
2964 program, 0); 2648 0);
2965} 2649}
2966 2650
2967u16 hpi_tuner_get_program(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2651u16 hpi_tuner_get_program(u32 h_control, u32 *pprogram)
2968 u32 *pprogram)
2969{ 2652{
2970 return hpi_control_param1_get(ph_subsys, h_control, HPI_TUNER_PROGRAM, 2653 return hpi_control_param1_get(h_control, HPI_TUNER_PROGRAM, pprogram);
2971 pprogram);
2972} 2654}
2973 2655
2974u16 hpi_tuner_get_hd_radio_dsp_version(const struct hpi_hsubsys *ph_subsys, 2656u16 hpi_tuner_get_hd_radio_dsp_version(u32 h_control, char *psz_dsp_version,
2975 u32 h_control, char *psz_dsp_version, const u32 string_size) 2657 const u32 string_size)
2976{ 2658{
2977 return hpi_control_get_string(h_control, 2659 return hpi_control_get_string(h_control,
2978 HPI_TUNER_HDRADIO_DSP_VERSION, psz_dsp_version, string_size); 2660 HPI_TUNER_HDRADIO_DSP_VERSION, psz_dsp_version, string_size);
2979} 2661}
2980 2662
2981u16 hpi_tuner_get_hd_radio_sdk_version(const struct hpi_hsubsys *ph_subsys, 2663u16 hpi_tuner_get_hd_radio_sdk_version(u32 h_control, char *psz_sdk_version,
2982 u32 h_control, char *psz_sdk_version, const u32 string_size) 2664 const u32 string_size)
2983{ 2665{
2984 return hpi_control_get_string(h_control, 2666 return hpi_control_get_string(h_control,
2985 HPI_TUNER_HDRADIO_SDK_VERSION, psz_sdk_version, string_size); 2667 HPI_TUNER_HDRADIO_SDK_VERSION, psz_sdk_version, string_size);
2986} 2668}
2987 2669
2988u16 hpi_tuner_get_status(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2670u16 hpi_tuner_get_status(u32 h_control, u16 *pw_status_mask, u16 *pw_status)
2989 u16 *pw_status_mask, u16 *pw_status)
2990{ 2671{
2991 u32 status = 0; 2672 u32 status = 0;
2992 u16 error = 0; 2673 u16 error = 0;
2993 2674
2994 error = hpi_control_param1_get(ph_subsys, h_control, HPI_TUNER_STATUS, 2675 error = hpi_control_param1_get(h_control, HPI_TUNER_STATUS, &status);
2995 &status);
2996 if (pw_status) { 2676 if (pw_status) {
2997 if (!error) { 2677 if (!error) {
2998 *pw_status_mask = (u16)(status >> 16); 2678 *pw_status_mask = (u16)(status >> 16);
@@ -3005,50 +2685,44 @@ u16 hpi_tuner_get_status(const struct hpi_hsubsys *ph_subsys, u32 h_control,
3005 return error; 2685 return error;
3006} 2686}
3007 2687
3008u16 hpi_tuner_set_mode(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2688u16 hpi_tuner_set_mode(u32 h_control, u32 mode, u32 value)
3009 u32 mode, u32 value)
3010{ 2689{
3011 return hpi_control_param_set(ph_subsys, h_control, HPI_TUNER_MODE, 2690 return hpi_control_param_set(h_control, HPI_TUNER_MODE, mode, value);
3012 mode, value);
3013} 2691}
3014 2692
3015u16 hpi_tuner_get_mode(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2693u16 hpi_tuner_get_mode(u32 h_control, u32 mode, u32 *pn_value)
3016 u32 mode, u32 *pn_value)
3017{ 2694{
3018 return hpi_control_param_get(ph_subsys, h_control, HPI_TUNER_MODE, 2695 return hpi_control_param_get(h_control, HPI_TUNER_MODE, mode, 0,
3019 mode, 0, pn_value, NULL); 2696 pn_value, NULL);
3020} 2697}
3021 2698
3022u16 hpi_tuner_get_hd_radio_signal_quality(const struct hpi_hsubsys *ph_subsys, 2699u16 hpi_tuner_get_hd_radio_signal_quality(u32 h_control, u32 *pquality)
3023 u32 h_control, u32 *pquality)
3024{ 2700{
3025 return hpi_control_param1_get(ph_subsys, h_control, 2701 return hpi_control_param1_get(h_control,
3026 HPI_TUNER_HDRADIO_SIGNAL_QUALITY, pquality); 2702 HPI_TUNER_HDRADIO_SIGNAL_QUALITY, pquality);
3027} 2703}
3028 2704
3029u16 hpi_tuner_get_hd_radio_signal_blend(const struct hpi_hsubsys *ph_subsys, 2705u16 hpi_tuner_get_hd_radio_signal_blend(u32 h_control, u32 *pblend)
3030 u32 h_control, u32 *pblend)
3031{ 2706{
3032 return hpi_control_param1_get(ph_subsys, h_control, 2707 return hpi_control_param1_get(h_control, HPI_TUNER_HDRADIO_BLEND,
3033 HPI_TUNER_HDRADIO_BLEND, pblend); 2708 pblend);
3034} 2709}
3035 2710
3036u16 hpi_tuner_set_hd_radio_signal_blend(const struct hpi_hsubsys *ph_subsys, 2711u16 hpi_tuner_set_hd_radio_signal_blend(u32 h_control, const u32 blend)
3037 u32 h_control, const u32 blend)
3038{ 2712{
3039 return hpi_control_param_set(ph_subsys, h_control, 2713 return hpi_control_param_set(h_control, HPI_TUNER_HDRADIO_BLEND,
3040 HPI_TUNER_HDRADIO_BLEND, blend, 0); 2714 blend, 0);
3041} 2715}
3042 2716
3043u16 hpi_tuner_getRDS(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2717u16 hpi_tuner_get_rds(u32 h_control, char *p_data)
3044 char *p_data)
3045{ 2718{
3046 struct hpi_message hm; 2719 struct hpi_message hm;
3047 struct hpi_response hr; 2720 struct hpi_response hr;
3048 2721
3049 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 2722 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
3050 HPI_CONTROL_GET_STATE); 2723 HPI_CONTROL_GET_STATE);
3051 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 2724 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
2725 return HPI_ERROR_INVALID_HANDLE;
3052 hm.u.c.attribute = HPI_TUNER_RDS; 2726 hm.u.c.attribute = HPI_TUNER_RDS;
3053 hpi_send_recv(&hm, &hr); 2727 hpi_send_recv(&hm, &hr);
3054 if (p_data) { 2728 if (p_data) {
@@ -3059,80 +2733,82 @@ u16 hpi_tuner_getRDS(const struct hpi_hsubsys *ph_subsys, u32 h_control,
3059 return hr.error; 2733 return hr.error;
3060} 2734}
3061 2735
3062u16 HPI_PAD__get_channel_name(const struct hpi_hsubsys *ph_subsys, 2736u16 hpi_pad_get_channel_name(u32 h_control, char *psz_string,
3063 u32 h_control, char *psz_string, const u32 data_length) 2737 const u32 data_length)
3064{ 2738{
3065 return hpi_control_get_string(h_control, HPI_PAD_CHANNEL_NAME, 2739 return hpi_control_get_string(h_control, HPI_PAD_CHANNEL_NAME,
3066 psz_string, data_length); 2740 psz_string, data_length);
3067} 2741}
3068 2742
3069u16 HPI_PAD__get_artist(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2743u16 hpi_pad_get_artist(u32 h_control, char *psz_string, const u32 data_length)
3070 char *psz_string, const u32 data_length)
3071{ 2744{
3072 return hpi_control_get_string(h_control, HPI_PAD_ARTIST, psz_string, 2745 return hpi_control_get_string(h_control, HPI_PAD_ARTIST, psz_string,
3073 data_length); 2746 data_length);
3074} 2747}
3075 2748
3076u16 HPI_PAD__get_title(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2749u16 hpi_pad_get_title(u32 h_control, char *psz_string, const u32 data_length)
3077 char *psz_string, const u32 data_length)
3078{ 2750{
3079 return hpi_control_get_string(h_control, HPI_PAD_TITLE, psz_string, 2751 return hpi_control_get_string(h_control, HPI_PAD_TITLE, psz_string,
3080 data_length); 2752 data_length);
3081} 2753}
3082 2754
3083u16 HPI_PAD__get_comment(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2755u16 hpi_pad_get_comment(u32 h_control, char *psz_string,
3084 char *psz_string, const u32 data_length) 2756 const u32 data_length)
3085{ 2757{
3086 return hpi_control_get_string(h_control, HPI_PAD_COMMENT, psz_string, 2758 return hpi_control_get_string(h_control, HPI_PAD_COMMENT, psz_string,
3087 data_length); 2759 data_length);
3088} 2760}
3089 2761
3090u16 HPI_PAD__get_program_type(const struct hpi_hsubsys *ph_subsys, 2762u16 hpi_pad_get_program_type(u32 h_control, u32 *ppTY)
3091 u32 h_control, u32 *ppTY)
3092{ 2763{
3093 return hpi_control_param1_get(ph_subsys, h_control, 2764 return hpi_control_param1_get(h_control, HPI_PAD_PROGRAM_TYPE, ppTY);
3094 HPI_PAD_PROGRAM_TYPE, ppTY);
3095} 2765}
3096 2766
3097u16 HPI_PAD__get_rdsPI(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2767u16 hpi_pad_get_rdsPI(u32 h_control, u32 *ppI)
3098 u32 *ppI)
3099{ 2768{
3100 return hpi_control_param1_get(ph_subsys, h_control, 2769 return hpi_control_param1_get(h_control, HPI_PAD_PROGRAM_ID, ppI);
3101 HPI_PAD_PROGRAM_ID, ppI);
3102} 2770}
3103 2771
3104u16 hpi_volume_query_channels(const struct hpi_hsubsys *ph_subsys, 2772u16 hpi_volume_query_channels(const u32 h_volume, u32 *p_channels)
3105 const u32 h_volume, u32 *p_channels)
3106{ 2773{
3107 return hpi_control_query(ph_subsys, h_volume, HPI_VOLUME_NUM_CHANNELS, 2774 return hpi_control_query(h_volume, HPI_VOLUME_NUM_CHANNELS, 0, 0,
3108 0, 0, p_channels); 2775 p_channels);
3109} 2776}
3110 2777
3111u16 hpi_volume_set_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2778u16 hpi_volume_set_gain(u32 h_control, short an_log_gain[HPI_MAX_CHANNELS]
3112 short an_log_gain[HPI_MAX_CHANNELS]
3113 ) 2779 )
3114{ 2780{
3115 return hpi_control_log_set2(h_control, HPI_VOLUME_GAIN, 2781 return hpi_control_log_set2(h_control, HPI_VOLUME_GAIN,
3116 an_log_gain[0], an_log_gain[1]); 2782 an_log_gain[0], an_log_gain[1]);
3117} 2783}
3118 2784
3119u16 hpi_volume_get_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2785u16 hpi_volume_get_gain(u32 h_control, short an_log_gain[HPI_MAX_CHANNELS]
3120 short an_log_gain[HPI_MAX_CHANNELS]
3121 ) 2786 )
3122{ 2787{
3123 return hpi_control_log_get2(ph_subsys, h_control, HPI_VOLUME_GAIN, 2788 return hpi_control_log_get2(h_control, HPI_VOLUME_GAIN,
3124 &an_log_gain[0], &an_log_gain[1]); 2789 &an_log_gain[0], &an_log_gain[1]);
3125} 2790}
3126 2791
3127u16 hpi_volume_query_range(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2792u16 hpi_volume_set_mute(u32 h_control, u32 mute)
3128 short *min_gain_01dB, short *max_gain_01dB, short *step_gain_01dB) 2793{
2794 return hpi_control_param_set(h_control, HPI_VOLUME_MUTE, mute, 0);
2795}
2796
2797u16 hpi_volume_get_mute(u32 h_control, u32 *mute)
2798{
2799 return hpi_control_param1_get(h_control, HPI_VOLUME_MUTE, mute);
2800}
2801
2802u16 hpi_volume_query_range(u32 h_control, short *min_gain_01dB,
2803 short *max_gain_01dB, short *step_gain_01dB)
3129{ 2804{
3130 struct hpi_message hm; 2805 struct hpi_message hm;
3131 struct hpi_response hr; 2806 struct hpi_response hr;
3132 2807
3133 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 2808 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
3134 HPI_CONTROL_GET_STATE); 2809 HPI_CONTROL_GET_STATE);
3135 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 2810 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
2811 return HPI_ERROR_INVALID_HANDLE;
3136 hm.u.c.attribute = HPI_VOLUME_RANGE; 2812 hm.u.c.attribute = HPI_VOLUME_RANGE;
3137 2813
3138 hpi_send_recv(&hm, &hr); 2814 hpi_send_recv(&hm, &hr);
@@ -3150,16 +2826,17 @@ u16 hpi_volume_query_range(const struct hpi_hsubsys *ph_subsys, u32 h_control,
3150 return hr.error; 2826 return hr.error;
3151} 2827}
3152 2828
3153u16 hpi_volume_auto_fade_profile(const struct hpi_hsubsys *ph_subsys, 2829u16 hpi_volume_auto_fade_profile(u32 h_control,
3154 u32 h_control, short an_stop_gain0_01dB[HPI_MAX_CHANNELS], 2830 short an_stop_gain0_01dB[HPI_MAX_CHANNELS], u32 duration_ms,
3155 u32 duration_ms, u16 profile) 2831 u16 profile)
3156{ 2832{
3157 struct hpi_message hm; 2833 struct hpi_message hm;
3158 struct hpi_response hr; 2834 struct hpi_response hr;
3159 2835
3160 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 2836 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
3161 HPI_CONTROL_SET_STATE); 2837 HPI_CONTROL_SET_STATE);
3162 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 2838 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
2839 return HPI_ERROR_INVALID_HANDLE;
3163 2840
3164 memcpy(hm.u.c.an_log_value, an_stop_gain0_01dB, 2841 memcpy(hm.u.c.an_log_value, an_stop_gain0_01dB,
3165 sizeof(short) * HPI_MAX_CHANNELS); 2842 sizeof(short) * HPI_MAX_CHANNELS);
@@ -3173,21 +2850,21 @@ u16 hpi_volume_auto_fade_profile(const struct hpi_hsubsys *ph_subsys,
3173 return hr.error; 2850 return hr.error;
3174} 2851}
3175 2852
3176u16 hpi_volume_auto_fade(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2853u16 hpi_volume_auto_fade(u32 h_control,
3177 short an_stop_gain0_01dB[HPI_MAX_CHANNELS], u32 duration_ms) 2854 short an_stop_gain0_01dB[HPI_MAX_CHANNELS], u32 duration_ms)
3178{ 2855{
3179 return hpi_volume_auto_fade_profile(ph_subsys, h_control, 2856 return hpi_volume_auto_fade_profile(h_control, an_stop_gain0_01dB,
3180 an_stop_gain0_01dB, duration_ms, HPI_VOLUME_AUTOFADE_LOG); 2857 duration_ms, HPI_VOLUME_AUTOFADE_LOG);
3181} 2858}
3182 2859
3183u16 hpi_vox_set_threshold(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2860u16 hpi_vox_set_threshold(u32 h_control, short an_gain0_01dB)
3184 short an_gain0_01dB)
3185{ 2861{
3186 struct hpi_message hm; 2862 struct hpi_message hm;
3187 struct hpi_response hr; 2863 struct hpi_response hr;
3188 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 2864 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
3189 HPI_CONTROL_SET_STATE); 2865 HPI_CONTROL_SET_STATE);
3190 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 2866 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
2867 return HPI_ERROR_INVALID_HANDLE;
3191 hm.u.c.attribute = HPI_VOX_THRESHOLD; 2868 hm.u.c.attribute = HPI_VOX_THRESHOLD;
3192 2869
3193 hm.u.c.an_log_value[0] = an_gain0_01dB; 2870 hm.u.c.an_log_value[0] = an_gain0_01dB;
@@ -3197,14 +2874,14 @@ u16 hpi_vox_set_threshold(const struct hpi_hsubsys *ph_subsys, u32 h_control,
3197 return hr.error; 2874 return hr.error;
3198} 2875}
3199 2876
3200u16 hpi_vox_get_threshold(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2877u16 hpi_vox_get_threshold(u32 h_control, short *an_gain0_01dB)
3201 short *an_gain0_01dB)
3202{ 2878{
3203 struct hpi_message hm; 2879 struct hpi_message hm;
3204 struct hpi_response hr; 2880 struct hpi_response hr;
3205 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 2881 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
3206 HPI_CONTROL_GET_STATE); 2882 HPI_CONTROL_GET_STATE);
3207 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 2883 if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
2884 return HPI_ERROR_INVALID_HANDLE;
3208 hm.u.c.attribute = HPI_VOX_THRESHOLD; 2885 hm.u.c.attribute = HPI_VOX_THRESHOLD;
3209 2886
3210 hpi_send_recv(&hm, &hr); 2887 hpi_send_recv(&hm, &hr);
@@ -3213,728 +2890,3 @@ u16 hpi_vox_get_threshold(const struct hpi_hsubsys *ph_subsys, u32 h_control,
3213 2890
3214 return hr.error; 2891 return hr.error;
3215} 2892}
3216
3217static size_t strv_packet_size = MIN_STRV_PACKET_SIZE;
3218
3219static size_t entity_type_to_size[LAST_ENTITY_TYPE] = {
3220 0,
3221 sizeof(struct hpi_entity),
3222 sizeof(void *),
3223
3224 sizeof(int),
3225 sizeof(float),
3226 sizeof(double),
3227
3228 sizeof(char),
3229 sizeof(char),
3230
3231 4 * sizeof(char),
3232 16 * sizeof(char),
3233 6 * sizeof(char),
3234};
3235
3236static inline size_t hpi_entity_size(struct hpi_entity *entity_ptr)
3237{
3238 return entity_ptr->header.size;
3239}
3240
3241static inline size_t hpi_entity_header_size(struct hpi_entity *entity_ptr)
3242{
3243 return sizeof(entity_ptr->header);
3244}
3245
3246static inline size_t hpi_entity_value_size(struct hpi_entity *entity_ptr)
3247{
3248 return hpi_entity_size(entity_ptr) -
3249 hpi_entity_header_size(entity_ptr);
3250}
3251
3252static inline size_t hpi_entity_item_count(struct hpi_entity *entity_ptr)
3253{
3254 return hpi_entity_value_size(entity_ptr) /
3255 entity_type_to_size[entity_ptr->header.type];
3256}
3257
3258static inline struct hpi_entity *hpi_entity_ptr_to_next(struct hpi_entity
3259 *entity_ptr)
3260{
3261 return (void *)(((u8 *)entity_ptr) + hpi_entity_size(entity_ptr));
3262}
3263
3264static inline u16 hpi_entity_check_type(const enum e_entity_type t)
3265{
3266 if (t >= 0 && t < STR_TYPE_FIELD_MAX)
3267 return 0;
3268 return HPI_ERROR_ENTITY_TYPE_INVALID;
3269}
3270
3271static inline u16 hpi_entity_check_role(const enum e_entity_role r)
3272{
3273 if (r >= 0 && r < STR_ROLE_FIELD_MAX)
3274 return 0;
3275 return HPI_ERROR_ENTITY_ROLE_INVALID;
3276}
3277
3278static u16 hpi_entity_get_next(struct hpi_entity *entity, int recursive_flag,
3279 void *guard_p, struct hpi_entity **next)
3280{
3281 HPI_DEBUG_ASSERT(entity != NULL);
3282 HPI_DEBUG_ASSERT(next != NULL);
3283 HPI_DEBUG_ASSERT(hpi_entity_size(entity) != 0);
3284
3285 if (guard_p <= (void *)entity) {
3286 *next = NULL;
3287 return 0;
3288 }
3289
3290 if (recursive_flag && entity->header.type == entity_type_sequence)
3291 *next = (struct hpi_entity *)entity->value;
3292 else
3293 *next = (struct hpi_entity *)hpi_entity_ptr_to_next(entity);
3294
3295 if (guard_p <= (void *)*next) {
3296 *next = NULL;
3297 return 0;
3298 }
3299
3300 HPI_DEBUG_ASSERT(guard_p >= (void *)hpi_entity_ptr_to_next(*next));
3301 return 0;
3302}
3303
3304u16 hpi_entity_find_next(struct hpi_entity *container_entity,
3305 enum e_entity_type type, enum e_entity_role role, int recursive_flag,
3306 struct hpi_entity **current_match)
3307{
3308 struct hpi_entity *tmp = NULL;
3309 void *guard_p = NULL;
3310
3311 HPI_DEBUG_ASSERT(container_entity != NULL);
3312 guard_p = hpi_entity_ptr_to_next(container_entity);
3313
3314 if (*current_match != NULL)
3315 hpi_entity_get_next(*current_match, recursive_flag, guard_p,
3316 &tmp);
3317 else
3318 hpi_entity_get_next(container_entity, 1, guard_p, &tmp);
3319
3320 while (tmp) {
3321 u16 err;
3322
3323 HPI_DEBUG_ASSERT((void *)tmp >= (void *)container_entity);
3324
3325 if ((!type || tmp->header.type == type) && (!role
3326 || tmp->header.role == role)) {
3327 *current_match = tmp;
3328 return 0;
3329 }
3330
3331 err = hpi_entity_get_next(tmp, recursive_flag, guard_p,
3332 current_match);
3333 if (err)
3334 return err;
3335
3336 tmp = *current_match;
3337 }
3338
3339 *current_match = NULL;
3340 return 0;
3341}
3342
3343void hpi_entity_free(struct hpi_entity *entity)
3344{
3345 kfree(entity);
3346}
3347
3348static u16 hpi_entity_alloc_and_copy(struct hpi_entity *src,
3349 struct hpi_entity **dst)
3350{
3351 size_t buf_size;
3352 HPI_DEBUG_ASSERT(dst != NULL);
3353 HPI_DEBUG_ASSERT(src != NULL);
3354
3355 buf_size = hpi_entity_size(src);
3356 *dst = kmalloc(buf_size, GFP_KERNEL);
3357 if (*dst == NULL)
3358 return HPI_ERROR_MEMORY_ALLOC;
3359 memcpy(*dst, src, buf_size);
3360 return 0;
3361}
3362
3363u16 hpi_universal_info(const struct hpi_hsubsys *ph_subsys, u32 hC,
3364 struct hpi_entity **info)
3365{
3366 struct hpi_msg_strv hm;
3367 struct hpi_res_strv *phr;
3368 u16 hpi_err;
3369 int remaining_attempts = 2;
3370 size_t resp_packet_size = 1024;
3371
3372 *info = NULL;
3373
3374 while (remaining_attempts--) {
3375 phr = kmalloc(resp_packet_size, GFP_KERNEL);
3376 HPI_DEBUG_ASSERT(phr != NULL);
3377
3378 hpi_init_message_responseV1(&hm.h, (u16)sizeof(hm), &phr->h,
3379 (u16)resp_packet_size, HPI_OBJ_CONTROL,
3380 HPI_CONTROL_GET_INFO);
3381 u32TOINDEXES(hC, &hm.h.adapter_index, &hm.h.obj_index);
3382
3383 hm.strv.header.size = sizeof(hm.strv);
3384 phr->strv.header.size = resp_packet_size - sizeof(phr->h);
3385
3386 hpi_send_recv((struct hpi_message *)&hm.h,
3387 (struct hpi_response *)&phr->h);
3388 if (phr->h.error == HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL) {
3389
3390 HPI_DEBUG_ASSERT(phr->h.specific_error >
3391 MIN_STRV_PACKET_SIZE
3392 && phr->h.specific_error < 1500);
3393 resp_packet_size = phr->h.specific_error;
3394 } else {
3395 remaining_attempts = 0;
3396 if (!phr->h.error)
3397 hpi_entity_alloc_and_copy(&phr->strv, info);
3398 }
3399
3400 hpi_err = phr->h.error;
3401 kfree(phr);
3402 }
3403
3404 return hpi_err;
3405}
3406
3407u16 hpi_universal_get(const struct hpi_hsubsys *ph_subsys, u32 hC,
3408 struct hpi_entity **value)
3409{
3410 struct hpi_msg_strv hm;
3411 struct hpi_res_strv *phr;
3412 u16 hpi_err;
3413 int remaining_attempts = 2;
3414
3415 *value = NULL;
3416
3417 while (remaining_attempts--) {
3418 phr = kmalloc(strv_packet_size, GFP_KERNEL);
3419 if (!phr)
3420 return HPI_ERROR_MEMORY_ALLOC;
3421
3422 hpi_init_message_responseV1(&hm.h, (u16)sizeof(hm), &phr->h,
3423 (u16)strv_packet_size, HPI_OBJ_CONTROL,
3424 HPI_CONTROL_GET_STATE);
3425 u32TOINDEXES(hC, &hm.h.adapter_index, &hm.h.obj_index);
3426
3427 hm.strv.header.size = sizeof(hm.strv);
3428 phr->strv.header.size = strv_packet_size - sizeof(phr->h);
3429
3430 hpi_send_recv((struct hpi_message *)&hm.h,
3431 (struct hpi_response *)&phr->h);
3432 if (phr->h.error == HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL) {
3433
3434 HPI_DEBUG_ASSERT(phr->h.specific_error >
3435 MIN_STRV_PACKET_SIZE
3436 && phr->h.specific_error < 1000);
3437 strv_packet_size = phr->h.specific_error;
3438 } else {
3439 remaining_attempts = 0;
3440 if (!phr->h.error)
3441 hpi_entity_alloc_and_copy(&phr->strv, value);
3442 }
3443
3444 hpi_err = phr->h.error;
3445 kfree(phr);
3446 }
3447
3448 return hpi_err;
3449}
3450
3451u16 hpi_universal_set(const struct hpi_hsubsys *ph_subsys, u32 hC,
3452 struct hpi_entity *value)
3453{
3454 struct hpi_msg_strv *phm;
3455 struct hpi_res_strv hr;
3456
3457 phm = kmalloc(sizeof(phm->h) + value->header.size, GFP_KERNEL);
3458 HPI_DEBUG_ASSERT(phm != NULL);
3459
3460 hpi_init_message_responseV1(&phm->h,
3461 sizeof(phm->h) + value->header.size, &hr.h, sizeof(hr),
3462 HPI_OBJ_CONTROL, HPI_CONTROL_SET_STATE);
3463 u32TOINDEXES(hC, &phm->h.adapter_index, &phm->h.obj_index);
3464 hr.strv.header.size = sizeof(hr.strv);
3465
3466 memcpy(&phm->strv, value, value->header.size);
3467 hpi_send_recv((struct hpi_message *)&phm->h,
3468 (struct hpi_response *)&hr.h);
3469
3470 return hr.h.error;
3471}
3472
3473u16 hpi_entity_alloc_and_pack(const enum e_entity_type type,
3474 const size_t item_count, const enum e_entity_role role, void *value,
3475 struct hpi_entity **entity)
3476{
3477 size_t bytes_to_copy, total_size;
3478 u16 hE = 0;
3479 *entity = NULL;
3480
3481 hE = hpi_entity_check_type(type);
3482 if (hE)
3483 return hE;
3484
3485 HPI_DEBUG_ASSERT(role > entity_role_null && type < LAST_ENTITY_TYPE);
3486
3487 bytes_to_copy = entity_type_to_size[type] * item_count;
3488 total_size = hpi_entity_header_size(*entity) + bytes_to_copy;
3489
3490 HPI_DEBUG_ASSERT(total_size >= hpi_entity_header_size(*entity)
3491 && total_size < STR_SIZE_FIELD_MAX);
3492
3493 *entity = kmalloc(total_size, GFP_KERNEL);
3494 if (*entity == NULL)
3495 return HPI_ERROR_MEMORY_ALLOC;
3496 memcpy((*entity)->value, value, bytes_to_copy);
3497 (*entity)->header.size =
3498 hpi_entity_header_size(*entity) + bytes_to_copy;
3499 (*entity)->header.type = type;
3500 (*entity)->header.role = role;
3501 return 0;
3502}
3503
3504u16 hpi_entity_copy_value_from(struct hpi_entity *entity,
3505 enum e_entity_type type, size_t item_count, void *value_dst_p)
3506{
3507 size_t bytes_to_copy;
3508
3509 if (entity->header.type != type)
3510 return HPI_ERROR_ENTITY_TYPE_MISMATCH;
3511
3512 if (hpi_entity_item_count(entity) != item_count)
3513 return HPI_ERROR_ENTITY_ITEM_COUNT;
3514
3515 bytes_to_copy = entity_type_to_size[type] * item_count;
3516 memcpy(value_dst_p, entity->value, bytes_to_copy);
3517 return 0;
3518}
3519
3520u16 hpi_entity_unpack(struct hpi_entity *entity, enum e_entity_type *type,
3521 size_t *item_count, enum e_entity_role *role, void **value)
3522{
3523 u16 err = 0;
3524 HPI_DEBUG_ASSERT(entity != NULL);
3525
3526 if (type)
3527 *type = entity->header.type;
3528
3529 if (role)
3530 *role = entity->header.role;
3531
3532 if (value)
3533 *value = entity->value;
3534
3535 if (item_count != NULL) {
3536 if (entity->header.type == entity_type_sequence) {
3537 void *guard_p = hpi_entity_ptr_to_next(entity);
3538 struct hpi_entity *next = NULL;
3539 void *contents = entity->value;
3540
3541 *item_count = 0;
3542 while (contents < guard_p) {
3543 (*item_count)++;
3544 err = hpi_entity_get_next(contents, 0,
3545 guard_p, &next);
3546 if (next == NULL || err)
3547 break;
3548 contents = next;
3549 }
3550 } else {
3551 *item_count = hpi_entity_item_count(entity);
3552 }
3553 }
3554 return err;
3555}
3556
3557u16 hpi_gpio_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
3558 u32 *ph_gpio, u16 *pw_number_input_bits, u16 *pw_number_output_bits)
3559{
3560 struct hpi_message hm;
3561 struct hpi_response hr;
3562 hpi_init_message_response(&hm, &hr, HPI_OBJ_GPIO, HPI_GPIO_OPEN);
3563 hm.adapter_index = adapter_index;
3564
3565 hpi_send_recv(&hm, &hr);
3566
3567 if (hr.error == 0) {
3568 *ph_gpio =
3569 hpi_indexes_to_handle(HPI_OBJ_GPIO, adapter_index, 0);
3570 if (pw_number_input_bits)
3571 *pw_number_input_bits = hr.u.l.number_input_bits;
3572 if (pw_number_output_bits)
3573 *pw_number_output_bits = hr.u.l.number_output_bits;
3574 } else
3575 *ph_gpio = 0;
3576 return hr.error;
3577}
3578
3579u16 hpi_gpio_read_bit(const struct hpi_hsubsys *ph_subsys, u32 h_gpio,
3580 u16 bit_index, u16 *pw_bit_data)
3581{
3582 struct hpi_message hm;
3583 struct hpi_response hr;
3584 hpi_init_message_response(&hm, &hr, HPI_OBJ_GPIO, HPI_GPIO_READ_BIT);
3585 u32TOINDEX(h_gpio, &hm.adapter_index);
3586 hm.u.l.bit_index = bit_index;
3587
3588 hpi_send_recv(&hm, &hr);
3589
3590 *pw_bit_data = hr.u.l.bit_data[0];
3591 return hr.error;
3592}
3593
3594u16 hpi_gpio_read_all_bits(const struct hpi_hsubsys *ph_subsys, u32 h_gpio,
3595 u16 aw_all_bit_data[4]
3596 )
3597{
3598 struct hpi_message hm;
3599 struct hpi_response hr;
3600 hpi_init_message_response(&hm, &hr, HPI_OBJ_GPIO, HPI_GPIO_READ_ALL);
3601 u32TOINDEX(h_gpio, &hm.adapter_index);
3602
3603 hpi_send_recv(&hm, &hr);
3604
3605 if (aw_all_bit_data) {
3606 aw_all_bit_data[0] = hr.u.l.bit_data[0];
3607 aw_all_bit_data[1] = hr.u.l.bit_data[1];
3608 aw_all_bit_data[2] = hr.u.l.bit_data[2];
3609 aw_all_bit_data[3] = hr.u.l.bit_data[3];
3610 }
3611 return hr.error;
3612}
3613
3614u16 hpi_gpio_write_bit(const struct hpi_hsubsys *ph_subsys, u32 h_gpio,
3615 u16 bit_index, u16 bit_data)
3616{
3617 struct hpi_message hm;
3618 struct hpi_response hr;
3619 hpi_init_message_response(&hm, &hr, HPI_OBJ_GPIO, HPI_GPIO_WRITE_BIT);
3620 u32TOINDEX(h_gpio, &hm.adapter_index);
3621 hm.u.l.bit_index = bit_index;
3622 hm.u.l.bit_data = bit_data;
3623
3624 hpi_send_recv(&hm, &hr);
3625
3626 return hr.error;
3627}
3628
3629u16 hpi_gpio_write_status(const struct hpi_hsubsys *ph_subsys, u32 h_gpio,
3630 u16 aw_all_bit_data[4]
3631 )
3632{
3633 struct hpi_message hm;
3634 struct hpi_response hr;
3635 hpi_init_message_response(&hm, &hr, HPI_OBJ_GPIO,
3636 HPI_GPIO_WRITE_STATUS);
3637 u32TOINDEX(h_gpio, &hm.adapter_index);
3638
3639 hpi_send_recv(&hm, &hr);
3640
3641 if (aw_all_bit_data) {
3642 aw_all_bit_data[0] = hr.u.l.bit_data[0];
3643 aw_all_bit_data[1] = hr.u.l.bit_data[1];
3644 aw_all_bit_data[2] = hr.u.l.bit_data[2];
3645 aw_all_bit_data[3] = hr.u.l.bit_data[3];
3646 }
3647 return hr.error;
3648}
3649
3650u16 hpi_async_event_open(const struct hpi_hsubsys *ph_subsys,
3651 u16 adapter_index, u32 *ph_async)
3652{
3653 struct hpi_message hm;
3654 struct hpi_response hr;
3655 hpi_init_message_response(&hm, &hr, HPI_OBJ_ASYNCEVENT,
3656 HPI_ASYNCEVENT_OPEN);
3657 hm.adapter_index = adapter_index;
3658
3659 hpi_send_recv(&hm, &hr);
3660
3661 if (hr.error == 0)
3662
3663 *ph_async =
3664 hpi_indexes_to_handle(HPI_OBJ_ASYNCEVENT,
3665 adapter_index, 0);
3666 else
3667 *ph_async = 0;
3668 return hr.error;
3669
3670}
3671
3672u16 hpi_async_event_close(const struct hpi_hsubsys *ph_subsys, u32 h_async)
3673{
3674 struct hpi_message hm;
3675 struct hpi_response hr;
3676 hpi_init_message_response(&hm, &hr, HPI_OBJ_ASYNCEVENT,
3677 HPI_ASYNCEVENT_OPEN);
3678 u32TOINDEX(h_async, &hm.adapter_index);
3679
3680 hpi_send_recv(&hm, &hr);
3681
3682 return hr.error;
3683}
3684
3685u16 hpi_async_event_wait(const struct hpi_hsubsys *ph_subsys, u32 h_async,
3686 u16 maximum_events, struct hpi_async_event *p_events,
3687 u16 *pw_number_returned)
3688{
3689
3690 return 0;
3691}
3692
3693u16 hpi_async_event_get_count(const struct hpi_hsubsys *ph_subsys,
3694 u32 h_async, u16 *pw_count)
3695{
3696 struct hpi_message hm;
3697 struct hpi_response hr;
3698 hpi_init_message_response(&hm, &hr, HPI_OBJ_ASYNCEVENT,
3699 HPI_ASYNCEVENT_GETCOUNT);
3700 u32TOINDEX(h_async, &hm.adapter_index);
3701
3702 hpi_send_recv(&hm, &hr);
3703
3704 if (hr.error == 0)
3705 if (pw_count)
3706 *pw_count = hr.u.as.u.count.count;
3707
3708 return hr.error;
3709}
3710
3711u16 hpi_async_event_get(const struct hpi_hsubsys *ph_subsys, u32 h_async,
3712 u16 maximum_events, struct hpi_async_event *p_events,
3713 u16 *pw_number_returned)
3714{
3715 struct hpi_message hm;
3716 struct hpi_response hr;
3717 hpi_init_message_response(&hm, &hr, HPI_OBJ_ASYNCEVENT,
3718 HPI_ASYNCEVENT_GET);
3719 u32TOINDEX(h_async, &hm.adapter_index);
3720
3721 hpi_send_recv(&hm, &hr);
3722 if (!hr.error) {
3723 memcpy(p_events, &hr.u.as.u.event,
3724 sizeof(struct hpi_async_event));
3725 *pw_number_returned = 1;
3726 }
3727
3728 return hr.error;
3729}
3730
3731u16 hpi_nv_memory_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
3732 u32 *ph_nv_memory, u16 *pw_size_in_bytes)
3733{
3734 struct hpi_message hm;
3735 struct hpi_response hr;
3736 hpi_init_message_response(&hm, &hr, HPI_OBJ_NVMEMORY,
3737 HPI_NVMEMORY_OPEN);
3738 hm.adapter_index = adapter_index;
3739
3740 hpi_send_recv(&hm, &hr);
3741
3742 if (hr.error == 0) {
3743 *ph_nv_memory =
3744 hpi_indexes_to_handle(HPI_OBJ_NVMEMORY, adapter_index,
3745 0);
3746 if (pw_size_in_bytes)
3747 *pw_size_in_bytes = hr.u.n.size_in_bytes;
3748 } else
3749 *ph_nv_memory = 0;
3750 return hr.error;
3751}
3752
3753u16 hpi_nv_memory_read_byte(const struct hpi_hsubsys *ph_subsys,
3754 u32 h_nv_memory, u16 index, u16 *pw_data)
3755{
3756 struct hpi_message hm;
3757 struct hpi_response hr;
3758 hpi_init_message_response(&hm, &hr, HPI_OBJ_NVMEMORY,
3759 HPI_NVMEMORY_READ_BYTE);
3760 u32TOINDEX(h_nv_memory, &hm.adapter_index);
3761 hm.u.n.address = index;
3762
3763 hpi_send_recv(&hm, &hr);
3764
3765 *pw_data = hr.u.n.data;
3766 return hr.error;
3767}
3768
3769u16 hpi_nv_memory_write_byte(const struct hpi_hsubsys *ph_subsys,
3770 u32 h_nv_memory, u16 index, u16 data)
3771{
3772 struct hpi_message hm;
3773 struct hpi_response hr;
3774 hpi_init_message_response(&hm, &hr, HPI_OBJ_NVMEMORY,
3775 HPI_NVMEMORY_WRITE_BYTE);
3776 u32TOINDEX(h_nv_memory, &hm.adapter_index);
3777 hm.u.n.address = index;
3778 hm.u.n.data = data;
3779
3780 hpi_send_recv(&hm, &hr);
3781
3782 return hr.error;
3783}
3784
3785u16 hpi_profile_open_all(const struct hpi_hsubsys *ph_subsys,
3786 u16 adapter_index, u16 profile_index, u32 *ph_profile,
3787 u16 *pw_max_profiles)
3788{
3789 struct hpi_message hm;
3790 struct hpi_response hr;
3791 hpi_init_message_response(&hm, &hr, HPI_OBJ_PROFILE,
3792 HPI_PROFILE_OPEN_ALL);
3793 hm.adapter_index = adapter_index;
3794 hm.obj_index = profile_index;
3795 hpi_send_recv(&hm, &hr);
3796
3797 *pw_max_profiles = hr.u.p.u.o.max_profiles;
3798 if (hr.error == 0)
3799 *ph_profile =
3800 hpi_indexes_to_handle(HPI_OBJ_PROFILE, adapter_index,
3801 profile_index);
3802 else
3803 *ph_profile = 0;
3804 return hr.error;
3805}
3806
3807u16 hpi_profile_get(const struct hpi_hsubsys *ph_subsys, u32 h_profile,
3808 u16 bin_index, u16 *pw_seconds, u32 *pmicro_seconds, u32 *pcall_count,
3809 u32 *pmax_micro_seconds, u32 *pmin_micro_seconds)
3810{
3811 struct hpi_message hm;
3812 struct hpi_response hr;
3813 hpi_init_message_response(&hm, &hr, HPI_OBJ_PROFILE, HPI_PROFILE_GET);
3814 u32TOINDEXES(h_profile, &hm.adapter_index, &hm.obj_index);
3815 hm.u.p.bin_index = bin_index;
3816 hpi_send_recv(&hm, &hr);
3817 if (pw_seconds)
3818 *pw_seconds = hr.u.p.u.t.seconds;
3819 if (pmicro_seconds)
3820 *pmicro_seconds = hr.u.p.u.t.micro_seconds;
3821 if (pcall_count)
3822 *pcall_count = hr.u.p.u.t.call_count;
3823 if (pmax_micro_seconds)
3824 *pmax_micro_seconds = hr.u.p.u.t.max_micro_seconds;
3825 if (pmin_micro_seconds)
3826 *pmin_micro_seconds = hr.u.p.u.t.min_micro_seconds;
3827 return hr.error;
3828}
3829
3830u16 hpi_profile_get_utilization(const struct hpi_hsubsys *ph_subsys,
3831 u32 h_profile, u32 *putilization)
3832{
3833 struct hpi_message hm;
3834 struct hpi_response hr;
3835 hpi_init_message_response(&hm, &hr, HPI_OBJ_PROFILE,
3836 HPI_PROFILE_GET_UTILIZATION);
3837 u32TOINDEXES(h_profile, &hm.adapter_index, &hm.obj_index);
3838 hpi_send_recv(&hm, &hr);
3839 if (hr.error) {
3840 if (putilization)
3841 *putilization = 0;
3842 } else {
3843 if (putilization)
3844 *putilization = hr.u.p.u.t.call_count;
3845 }
3846 return hr.error;
3847}
3848
3849u16 hpi_profile_get_name(const struct hpi_hsubsys *ph_subsys, u32 h_profile,
3850 u16 bin_index, char *sz_name, u16 name_length)
3851{
3852 struct hpi_message hm;
3853 struct hpi_response hr;
3854 hpi_init_message_response(&hm, &hr, HPI_OBJ_PROFILE,
3855 HPI_PROFILE_GET_NAME);
3856 u32TOINDEXES(h_profile, &hm.adapter_index, &hm.obj_index);
3857 hm.u.p.bin_index = bin_index;
3858 hpi_send_recv(&hm, &hr);
3859 if (hr.error) {
3860 if (sz_name)
3861 strcpy(sz_name, "??");
3862 } else {
3863 if (sz_name)
3864 memcpy(sz_name, (char *)hr.u.p.u.n.sz_name,
3865 name_length);
3866 }
3867 return hr.error;
3868}
3869
3870u16 hpi_profile_start_all(const struct hpi_hsubsys *ph_subsys, u32 h_profile)
3871{
3872 struct hpi_message hm;
3873 struct hpi_response hr;
3874 hpi_init_message_response(&hm, &hr, HPI_OBJ_PROFILE,
3875 HPI_PROFILE_START_ALL);
3876 u32TOINDEXES(h_profile, &hm.adapter_index, &hm.obj_index);
3877 hpi_send_recv(&hm, &hr);
3878
3879 return hr.error;
3880}
3881
3882u16 hpi_profile_stop_all(const struct hpi_hsubsys *ph_subsys, u32 h_profile)
3883{
3884 struct hpi_message hm;
3885 struct hpi_response hr;
3886 hpi_init_message_response(&hm, &hr, HPI_OBJ_PROFILE,
3887 HPI_PROFILE_STOP_ALL);
3888 u32TOINDEXES(h_profile, &hm.adapter_index, &hm.obj_index);
3889 hpi_send_recv(&hm, &hr);
3890
3891 return hr.error;
3892}
3893
3894u16 hpi_watchdog_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
3895 u32 *ph_watchdog)
3896{
3897 struct hpi_message hm;
3898 struct hpi_response hr;
3899 hpi_init_message_response(&hm, &hr, HPI_OBJ_WATCHDOG,
3900 HPI_WATCHDOG_OPEN);
3901 hm.adapter_index = adapter_index;
3902
3903 hpi_send_recv(&hm, &hr);
3904
3905 if (hr.error == 0)
3906 *ph_watchdog =
3907 hpi_indexes_to_handle(HPI_OBJ_WATCHDOG, adapter_index,
3908 0);
3909 else
3910 *ph_watchdog = 0;
3911 return hr.error;
3912}
3913
3914u16 hpi_watchdog_set_time(const struct hpi_hsubsys *ph_subsys, u32 h_watchdog,
3915 u32 time_millisec)
3916{
3917 struct hpi_message hm;
3918 struct hpi_response hr;
3919 hpi_init_message_response(&hm, &hr, HPI_OBJ_WATCHDOG,
3920 HPI_WATCHDOG_SET_TIME);
3921 u32TOINDEX(h_watchdog, &hm.adapter_index);
3922 hm.u.w.time_ms = time_millisec;
3923
3924 hpi_send_recv(&hm, &hr);
3925
3926 return hr.error;
3927}
3928
3929u16 hpi_watchdog_ping(const struct hpi_hsubsys *ph_subsys, u32 h_watchdog)
3930{
3931 struct hpi_message hm;
3932 struct hpi_response hr;
3933 hpi_init_message_response(&hm, &hr, HPI_OBJ_WATCHDOG,
3934 HPI_WATCHDOG_PING);
3935 u32TOINDEX(h_watchdog, &hm.adapter_index);
3936
3937 hpi_send_recv(&hm, &hr);
3938
3939 return hr.error;
3940}
diff --git a/sound/pci/asihpi/hpimsginit.c b/sound/pci/asihpi/hpimsginit.c
index 8e1d099ed7e4..628376ce4a49 100644
--- a/sound/pci/asihpi/hpimsginit.c
+++ b/sound/pci/asihpi/hpimsginit.c
@@ -32,21 +32,6 @@ static u16 res_size[HPI_OBJ_MAXINDEX + 1] = HPI_RESPONSE_SIZE_BY_OBJECT;
32static u16 gwSSX2_bypass; 32static u16 gwSSX2_bypass;
33 33
34/** \internal 34/** \internal
35 * Used by ASIO driver to disable SSX2 for a single process
36 * \param phSubSys Pointer to HPI subsystem handle.
37 * \param wBypass New bypass setting 0 = off, nonzero = on
38 * \return Previous bypass setting.
39 */
40u16 hpi_subsys_ssx2_bypass(const struct hpi_hsubsys *ph_subsys, u16 bypass)
41{
42 u16 old_value = gwSSX2_bypass;
43
44 gwSSX2_bypass = bypass;
45
46 return old_value;
47}
48
49/** \internal
50 * initialize the HPI message structure 35 * initialize the HPI message structure
51 */ 36 */
52static void hpi_init_message(struct hpi_message *phm, u16 object, 37static void hpi_init_message(struct hpi_message *phm, u16 object,
@@ -65,7 +50,8 @@ static void hpi_init_message(struct hpi_message *phm, u16 object,
65 phm->object = object; 50 phm->object = object;
66 phm->function = function; 51 phm->function = function;
67 phm->version = 0; 52 phm->version = 0;
68 /* Expect adapter index to be set by caller */ 53 phm->adapter_index = HPI_ADAPTER_INDEX_INVALID;
54 /* Expect actual adapter index to be set by caller */
69} 55}
70 56
71/** \internal 57/** \internal
diff --git a/sound/pci/asihpi/hpimsginit.h b/sound/pci/asihpi/hpimsginit.h
index 864ad020c9b3..bfd330d78b58 100644
--- a/sound/pci/asihpi/hpimsginit.h
+++ b/sound/pci/asihpi/hpimsginit.h
@@ -21,11 +21,15 @@
21 (C) Copyright AudioScience Inc. 2007 21 (C) Copyright AudioScience Inc. 2007
22*******************************************************************************/ 22*******************************************************************************/
23/* Initialise response headers, or msg/response pairs. 23/* Initialise response headers, or msg/response pairs.
24Note that it is valid to just init a response e.g. when a lower level is preparing 24Note that it is valid to just init a response e.g. when a lower level is
25a response to a message. 25preparing a response to a message.
26However, when sending a message, a matching response buffer always must be prepared 26However, when sending a message, a matching response buffer must always be
27prepared.
27*/ 28*/
28 29
30#ifndef _HPIMSGINIT_H_
31#define _HPIMSGINIT_H_
32
29void hpi_init_response(struct hpi_response *phr, u16 object, u16 function, 33void hpi_init_response(struct hpi_response *phr, u16 object, u16 function,
30 u16 error); 34 u16 error);
31 35
@@ -38,3 +42,5 @@ void hpi_init_responseV1(struct hpi_response_header *phr, u16 size,
38void hpi_init_message_responseV1(struct hpi_message_header *phm, u16 msg_size, 42void hpi_init_message_responseV1(struct hpi_message_header *phm, u16 msg_size,
39 struct hpi_response_header *phr, u16 res_size, u16 object, 43 struct hpi_response_header *phr, u16 res_size, u16 object,
40 u16 function); 44 u16 function);
45
46#endif /* _HPIMSGINIT_H_ */
diff --git a/sound/pci/asihpi/hpimsgx.c b/sound/pci/asihpi/hpimsgx.c
index f01ab964f602..bcbdf30a6aa0 100644
--- a/sound/pci/asihpi/hpimsgx.c
+++ b/sound/pci/asihpi/hpimsgx.c
@@ -23,6 +23,7 @@ Extended Message Function With Response Cacheing
23#define SOURCEFILE_NAME "hpimsgx.c" 23#define SOURCEFILE_NAME "hpimsgx.c"
24#include "hpi_internal.h" 24#include "hpi_internal.h"
25#include "hpimsginit.h" 25#include "hpimsginit.h"
26#include "hpicmn.h"
26#include "hpimsgx.h" 27#include "hpimsgx.h"
27#include "hpidebug.h" 28#include "hpidebug.h"
28 29
@@ -42,22 +43,24 @@ static hpi_handler_func *hpi_lookup_entry_point_function(const struct hpi_pci
42 43
43 for (i = 0; asihpi_pci_tbl[i].vendor != 0; i++) { 44 for (i = 0; asihpi_pci_tbl[i].vendor != 0; i++) {
44 if (asihpi_pci_tbl[i].vendor != PCI_ANY_ID 45 if (asihpi_pci_tbl[i].vendor != PCI_ANY_ID
45 && asihpi_pci_tbl[i].vendor != pci_info->vendor_id) 46 && asihpi_pci_tbl[i].vendor !=
47 pci_info->pci_dev->vendor)
46 continue; 48 continue;
47 if (asihpi_pci_tbl[i].device != PCI_ANY_ID 49 if (asihpi_pci_tbl[i].device != PCI_ANY_ID
48 && asihpi_pci_tbl[i].device != pci_info->device_id) 50 && asihpi_pci_tbl[i].device !=
51 pci_info->pci_dev->device)
49 continue; 52 continue;
50 if (asihpi_pci_tbl[i].subvendor != PCI_ANY_ID 53 if (asihpi_pci_tbl[i].subvendor != PCI_ANY_ID
51 && asihpi_pci_tbl[i].subvendor != 54 && asihpi_pci_tbl[i].subvendor !=
52 pci_info->subsys_vendor_id) 55 pci_info->pci_dev->subsystem_vendor)
53 continue; 56 continue;
54 if (asihpi_pci_tbl[i].subdevice != PCI_ANY_ID 57 if (asihpi_pci_tbl[i].subdevice != PCI_ANY_ID
55 && asihpi_pci_tbl[i].subdevice != 58 && asihpi_pci_tbl[i].subdevice !=
56 pci_info->subsys_device_id) 59 pci_info->pci_dev->subsystem_device)
57 continue; 60 continue;
58 61
59 HPI_DEBUG_LOG(DEBUG, " %x,%lu\n", i, 62 /* HPI_DEBUG_LOG(DEBUG, " %x,%lx\n", i,
60 asihpi_pci_tbl[i].driver_data); 63 asihpi_pci_tbl[i].driver_data); */
61 return (hpi_handler_func *) asihpi_pci_tbl[i].driver_data; 64 return (hpi_handler_func *) asihpi_pci_tbl[i].driver_data;
62 } 65 }
63 66
@@ -67,21 +70,12 @@ static hpi_handler_func *hpi_lookup_entry_point_function(const struct hpi_pci
67static inline void hw_entry_point(struct hpi_message *phm, 70static inline void hw_entry_point(struct hpi_message *phm,
68 struct hpi_response *phr) 71 struct hpi_response *phr)
69{ 72{
70 73 if ((phm->adapter_index < HPI_MAX_ADAPTERS)
71 hpi_handler_func *ep; 74 && hpi_entry_points[phm->adapter_index])
72 75 hpi_entry_points[phm->adapter_index] (phm, phr);
73 if (phm->adapter_index < HPI_MAX_ADAPTERS) { 76 else
74 ep = (hpi_handler_func *) hpi_entry_points[phm-> 77 hpi_init_response(phr, phm->object, phm->function,
75 adapter_index]; 78 HPI_ERROR_PROCESSING_MESSAGE);
76 if (ep) {
77 HPI_DEBUG_MESSAGE(DEBUG, phm);
78 ep(phm, phr);
79 HPI_DEBUG_RESPONSE(phr);
80 return;
81 }
82 }
83 hpi_init_response(phr, phm->object, phm->function,
84 HPI_ERROR_PROCESSING_MESSAGE);
85} 79}
86 80
87static void adapter_open(struct hpi_message *phm, struct hpi_response *phr); 81static void adapter_open(struct hpi_message *phm, struct hpi_response *phr);
@@ -100,6 +94,7 @@ static void instream_close(struct hpi_message *phm, struct hpi_response *phr,
100 void *h_owner); 94 void *h_owner);
101 95
102static void HPIMSGX__reset(u16 adapter_index); 96static void HPIMSGX__reset(u16 adapter_index);
97
103static u16 HPIMSGX__init(struct hpi_message *phm, struct hpi_response *phr); 98static u16 HPIMSGX__init(struct hpi_message *phm, struct hpi_response *phr);
104static void HPIMSGX__cleanup(u16 adapter_index, void *h_owner); 99static void HPIMSGX__cleanup(u16 adapter_index, void *h_owner);
105 100
@@ -153,8 +148,6 @@ static struct hpi_stream_response
153 148
154static struct hpi_mixer_response rESP_HPI_MIXER_OPEN[HPI_MAX_ADAPTERS]; 149static struct hpi_mixer_response rESP_HPI_MIXER_OPEN[HPI_MAX_ADAPTERS];
155 150
156static struct hpi_subsys_response gRESP_HPI_SUBSYS_FIND_ADAPTERS;
157
158static struct adapter_info aDAPTER_INFO[HPI_MAX_ADAPTERS]; 151static struct adapter_info aDAPTER_INFO[HPI_MAX_ADAPTERS];
159 152
160/* use these to keep track of opens from user mode apps/DLLs */ 153/* use these to keep track of opens from user mode apps/DLLs */
@@ -167,6 +160,11 @@ static struct asi_open_state
167static void subsys_message(struct hpi_message *phm, struct hpi_response *phr, 160static void subsys_message(struct hpi_message *phm, struct hpi_response *phr,
168 void *h_owner) 161 void *h_owner)
169{ 162{
163 if (phm->adapter_index != HPI_ADAPTER_INDEX_INVALID)
164 HPI_DEBUG_LOG(WARNING,
165 "suspicious adapter index %d in subsys message 0x%x.\n",
166 phm->adapter_index, phm->function);
167
170 switch (phm->function) { 168 switch (phm->function) {
171 case HPI_SUBSYS_GET_VERSION: 169 case HPI_SUBSYS_GET_VERSION:
172 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, 170 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM,
@@ -204,85 +202,37 @@ static void subsys_message(struct hpi_message *phm, struct hpi_response *phr,
204 HPI_SUBSYS_DRIVER_UNLOAD, 0); 202 HPI_SUBSYS_DRIVER_UNLOAD, 0);
205 return; 203 return;
206 204
207 case HPI_SUBSYS_GET_INFO:
208 HPI_COMMON(phm, phr);
209 break;
210
211 case HPI_SUBSYS_FIND_ADAPTERS:
212 memcpy(phr, &gRESP_HPI_SUBSYS_FIND_ADAPTERS,
213 sizeof(gRESP_HPI_SUBSYS_FIND_ADAPTERS));
214 break;
215 case HPI_SUBSYS_GET_NUM_ADAPTERS: 205 case HPI_SUBSYS_GET_NUM_ADAPTERS:
216 memcpy(phr, &gRESP_HPI_SUBSYS_FIND_ADAPTERS,
217 sizeof(gRESP_HPI_SUBSYS_FIND_ADAPTERS));
218 phr->function = HPI_SUBSYS_GET_NUM_ADAPTERS;
219 break;
220 case HPI_SUBSYS_GET_ADAPTER: 206 case HPI_SUBSYS_GET_ADAPTER:
221 { 207 HPI_COMMON(phm, phr);
222 int count = phm->adapter_index; 208 break;
223 int index = 0;
224 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM,
225 HPI_SUBSYS_GET_ADAPTER, 0);
226
227 /* This is complicated by the fact that we want to
228 * "skip" 0's in the adapter list.
229 * First, make sure we are pointing to a
230 * non-zero adapter type.
231 */
232 while (gRESP_HPI_SUBSYS_FIND_ADAPTERS.
233 s.aw_adapter_list[index] == 0) {
234 index++;
235 if (index >= HPI_MAX_ADAPTERS)
236 break;
237 }
238 while (count) {
239 /* move on to the next adapter */
240 index++;
241 if (index >= HPI_MAX_ADAPTERS)
242 break;
243 while (gRESP_HPI_SUBSYS_FIND_ADAPTERS.
244 s.aw_adapter_list[index] == 0) {
245 index++;
246 if (index >= HPI_MAX_ADAPTERS)
247 break;
248 }
249 count--;
250 }
251 209
252 if (index < HPI_MAX_ADAPTERS) {
253 phr->u.s.adapter_index = (u16)index;
254 phr->u.s.aw_adapter_list[0] =
255 gRESP_HPI_SUBSYS_FIND_ADAPTERS.
256 s.aw_adapter_list[index];
257 } else {
258 phr->u.s.adapter_index = 0;
259 phr->u.s.aw_adapter_list[0] = 0;
260 phr->error = HPI_ERROR_BAD_ADAPTER_NUMBER;
261 }
262 break;
263 }
264 case HPI_SUBSYS_CREATE_ADAPTER: 210 case HPI_SUBSYS_CREATE_ADAPTER:
265 HPIMSGX__init(phm, phr); 211 HPIMSGX__init(phm, phr);
266 break; 212 break;
213
267 case HPI_SUBSYS_DELETE_ADAPTER: 214 case HPI_SUBSYS_DELETE_ADAPTER:
268 HPIMSGX__cleanup(phm->adapter_index, h_owner); 215 HPIMSGX__cleanup(phm->obj_index, h_owner);
269 { 216 {
270 struct hpi_message hm; 217 struct hpi_message hm;
271 struct hpi_response hr; 218 struct hpi_response hr;
272 /* call to HPI_ADAPTER_CLOSE */
273 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER, 219 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
274 HPI_ADAPTER_CLOSE); 220 HPI_ADAPTER_CLOSE);
275 hm.adapter_index = phm->adapter_index; 221 hm.adapter_index = phm->obj_index;
276 hw_entry_point(&hm, &hr); 222 hw_entry_point(&hm, &hr);
277 } 223 }
278 hw_entry_point(phm, phr); 224 if ((phm->obj_index < HPI_MAX_ADAPTERS)
279 gRESP_HPI_SUBSYS_FIND_ADAPTERS.s. 225 && hpi_entry_points[phm->obj_index]) {
280 aw_adapter_list[phm->adapter_index] 226 hpi_entry_points[phm->obj_index] (phm, phr);
281 = 0; 227 hpi_entry_points[phm->obj_index] = NULL;
282 hpi_entry_points[phm->adapter_index] = NULL; 228 } else
229 phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
230
283 break; 231 break;
284 default: 232 default:
285 hw_entry_point(phm, phr); 233 /* Must explicitly handle every subsys message in this switch */
234 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, phm->function,
235 HPI_ERROR_INVALID_FUNC);
286 break; 236 break;
287 } 237 }
288} 238}
@@ -409,33 +359,7 @@ void hpi_send_recv_ex(struct hpi_message *phm, struct hpi_response *phr,
409 break; 359 break;
410 } 360 }
411 HPI_DEBUG_RESPONSE(phr); 361 HPI_DEBUG_RESPONSE(phr);
412#if 1 362
413 if (phr->error >= HPI_ERROR_BACKEND_BASE) {
414 void *ep = NULL;
415 char *ep_name;
416
417 HPI_DEBUG_MESSAGE(ERROR, phm);
418
419 if (phm->adapter_index < HPI_MAX_ADAPTERS)
420 ep = hpi_entry_points[phm->adapter_index];
421
422 /* Don't need this? Have adapter index in debug info
423 Know at driver load time index->backend mapping */
424 if (ep == HPI_6000)
425 ep_name = "HPI_6000";
426 else if (ep == HPI_6205)
427 ep_name = "HPI_6205";
428 else
429 ep_name = "unknown";
430
431 HPI_DEBUG_LOG(ERROR, "HPI %s response - error# %d\n", ep_name,
432 phr->error);
433
434 if (hpi_debug_level >= HPI_DEBUG_LEVEL_VERBOSE)
435 hpi_debug_data((u16 *)phm,
436 sizeof(*phm) / sizeof(u16));
437 }
438#endif
439} 363}
440 364
441static void adapter_open(struct hpi_message *phm, struct hpi_response *phr) 365static void adapter_open(struct hpi_message *phm, struct hpi_response *phr)
@@ -484,7 +408,7 @@ static void instream_open(struct hpi_message *phm, struct hpi_response *phr,
484 else { 408 else {
485 instream_user_open[phm->adapter_index][phm-> 409 instream_user_open[phm->adapter_index][phm->
486 obj_index].open_flag = 1; 410 obj_index].open_flag = 1;
487 hpios_msgxlock_un_lock(&msgx_lock); 411 hpios_msgxlock_unlock(&msgx_lock);
488 412
489 /* issue a reset */ 413 /* issue a reset */
490 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 414 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
@@ -509,7 +433,7 @@ static void instream_open(struct hpi_message *phm, struct hpi_response *phr,
509 sizeof(rESP_HPI_ISTREAM_OPEN[0][0])); 433 sizeof(rESP_HPI_ISTREAM_OPEN[0][0]));
510 } 434 }
511 } 435 }
512 hpios_msgxlock_un_lock(&msgx_lock); 436 hpios_msgxlock_unlock(&msgx_lock);
513} 437}
514 438
515static void instream_close(struct hpi_message *phm, struct hpi_response *phr, 439static void instream_close(struct hpi_message *phm, struct hpi_response *phr,
@@ -530,7 +454,7 @@ static void instream_close(struct hpi_message *phm, struct hpi_response *phr,
530 phm->wAdapterIndex, phm->wObjIndex, hOwner); */ 454 phm->wAdapterIndex, phm->wObjIndex, hOwner); */
531 instream_user_open[phm->adapter_index][phm-> 455 instream_user_open[phm->adapter_index][phm->
532 obj_index].h_owner = NULL; 456 obj_index].h_owner = NULL;
533 hpios_msgxlock_un_lock(&msgx_lock); 457 hpios_msgxlock_unlock(&msgx_lock);
534 /* issue a reset */ 458 /* issue a reset */
535 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM, 459 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
536 HPI_ISTREAM_RESET); 460 HPI_ISTREAM_RESET);
@@ -556,7 +480,7 @@ static void instream_close(struct hpi_message *phm, struct hpi_response *phr,
556 obj_index].h_owner); 480 obj_index].h_owner);
557 phr->error = HPI_ERROR_OBJ_NOT_OPEN; 481 phr->error = HPI_ERROR_OBJ_NOT_OPEN;
558 } 482 }
559 hpios_msgxlock_un_lock(&msgx_lock); 483 hpios_msgxlock_unlock(&msgx_lock);
560} 484}
561 485
562static void outstream_open(struct hpi_message *phm, struct hpi_response *phr, 486static void outstream_open(struct hpi_message *phm, struct hpi_response *phr,
@@ -581,7 +505,7 @@ static void outstream_open(struct hpi_message *phm, struct hpi_response *phr,
581 else { 505 else {
582 outstream_user_open[phm->adapter_index][phm-> 506 outstream_user_open[phm->adapter_index][phm->
583 obj_index].open_flag = 1; 507 obj_index].open_flag = 1;
584 hpios_msgxlock_un_lock(&msgx_lock); 508 hpios_msgxlock_unlock(&msgx_lock);
585 509
586 /* issue a reset */ 510 /* issue a reset */
587 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 511 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
@@ -606,7 +530,7 @@ static void outstream_open(struct hpi_message *phm, struct hpi_response *phr,
606 sizeof(rESP_HPI_OSTREAM_OPEN[0][0])); 530 sizeof(rESP_HPI_OSTREAM_OPEN[0][0]));
607 } 531 }
608 } 532 }
609 hpios_msgxlock_un_lock(&msgx_lock); 533 hpios_msgxlock_unlock(&msgx_lock);
610} 534}
611 535
612static void outstream_close(struct hpi_message *phm, struct hpi_response *phr, 536static void outstream_close(struct hpi_message *phm, struct hpi_response *phr,
@@ -628,7 +552,7 @@ static void outstream_close(struct hpi_message *phm, struct hpi_response *phr,
628 phm->wAdapterIndex, phm->wObjIndex, hOwner); */ 552 phm->wAdapterIndex, phm->wObjIndex, hOwner); */
629 outstream_user_open[phm->adapter_index][phm-> 553 outstream_user_open[phm->adapter_index][phm->
630 obj_index].h_owner = NULL; 554 obj_index].h_owner = NULL;
631 hpios_msgxlock_un_lock(&msgx_lock); 555 hpios_msgxlock_unlock(&msgx_lock);
632 /* issue a reset */ 556 /* issue a reset */
633 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 557 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
634 HPI_OSTREAM_RESET); 558 HPI_OSTREAM_RESET);
@@ -654,7 +578,7 @@ static void outstream_close(struct hpi_message *phm, struct hpi_response *phr,
654 obj_index].h_owner); 578 obj_index].h_owner);
655 phr->error = HPI_ERROR_OBJ_NOT_OPEN; 579 phr->error = HPI_ERROR_OBJ_NOT_OPEN;
656 } 580 }
657 hpios_msgxlock_un_lock(&msgx_lock); 581 hpios_msgxlock_unlock(&msgx_lock);
658} 582}
659 583
660static u16 adapter_prepare(u16 adapter) 584static u16 adapter_prepare(u16 adapter)
@@ -683,16 +607,9 @@ static u16 adapter_prepare(u16 adapter)
683 if (hr.error) 607 if (hr.error)
684 return hr.error; 608 return hr.error;
685 609
686 aDAPTER_INFO[adapter].num_outstreams = hr.u.a.num_outstreams; 610 aDAPTER_INFO[adapter].num_outstreams = hr.u.ax.info.num_outstreams;
687 aDAPTER_INFO[adapter].num_instreams = hr.u.a.num_instreams; 611 aDAPTER_INFO[adapter].num_instreams = hr.u.ax.info.num_instreams;
688 aDAPTER_INFO[adapter].type = hr.u.a.adapter_type; 612 aDAPTER_INFO[adapter].type = hr.u.ax.info.adapter_type;
689
690 gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.aw_adapter_list[adapter] =
691 hr.u.a.adapter_type;
692 gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.num_adapters++;
693 if (gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.num_adapters > HPI_MAX_ADAPTERS)
694 gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.num_adapters =
695 HPI_MAX_ADAPTERS;
696 613
697 /* call to HPI_OSTREAM_OPEN */ 614 /* call to HPI_OSTREAM_OPEN */
698 for (i = 0; i < aDAPTER_INFO[adapter].num_outstreams; i++) { 615 for (i = 0; i < aDAPTER_INFO[adapter].num_outstreams; i++) {
@@ -727,7 +644,7 @@ static u16 adapter_prepare(u16 adapter)
727 memcpy(&rESP_HPI_MIXER_OPEN[adapter], &hr, 644 memcpy(&rESP_HPI_MIXER_OPEN[adapter], &hr,
728 sizeof(rESP_HPI_MIXER_OPEN[0])); 645 sizeof(rESP_HPI_MIXER_OPEN[0]));
729 646
730 return gRESP_HPI_SUBSYS_FIND_ADAPTERS.h.error; 647 return 0;
731} 648}
732 649
733static void HPIMSGX__reset(u16 adapter_index) 650static void HPIMSGX__reset(u16 adapter_index)
@@ -737,12 +654,6 @@ static void HPIMSGX__reset(u16 adapter_index)
737 struct hpi_response hr; 654 struct hpi_response hr;
738 655
739 if (adapter_index == HPIMSGX_ALLADAPTERS) { 656 if (adapter_index == HPIMSGX_ALLADAPTERS) {
740 /* reset all responses to contain errors */
741 hpi_init_response(&hr, HPI_OBJ_SUBSYSTEM,
742 HPI_SUBSYS_FIND_ADAPTERS, 0);
743 memcpy(&gRESP_HPI_SUBSYS_FIND_ADAPTERS, &hr,
744 sizeof(gRESP_HPI_SUBSYS_FIND_ADAPTERS));
745
746 for (adapter = 0; adapter < HPI_MAX_ADAPTERS; adapter++) { 657 for (adapter = 0; adapter < HPI_MAX_ADAPTERS; adapter++) {
747 658
748 hpi_init_response(&hr, HPI_OBJ_ADAPTER, 659 hpi_init_response(&hr, HPI_OBJ_ADAPTER,
@@ -783,12 +694,6 @@ static void HPIMSGX__reset(u16 adapter_index)
783 rESP_HPI_ISTREAM_OPEN[adapter_index][i].h.error = 694 rESP_HPI_ISTREAM_OPEN[adapter_index][i].h.error =
784 HPI_ERROR_INVALID_OBJ; 695 HPI_ERROR_INVALID_OBJ;
785 } 696 }
786 if (gRESP_HPI_SUBSYS_FIND_ADAPTERS.
787 s.aw_adapter_list[adapter_index]) {
788 gRESP_HPI_SUBSYS_FIND_ADAPTERS.
789 s.aw_adapter_list[adapter_index] = 0;
790 gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.num_adapters--;
791 }
792 } 697 }
793} 698}
794 699
@@ -802,15 +707,9 @@ static u16 HPIMSGX__init(struct hpi_message *phm,
802 hpi_handler_func *entry_point_func; 707 hpi_handler_func *entry_point_func;
803 struct hpi_response hr; 708 struct hpi_response hr;
804 709
805 if (gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.num_adapters >= HPI_MAX_ADAPTERS)
806 return HPI_ERROR_BAD_ADAPTER_NUMBER;
807
808 /* Init response here so we can pass in previous adapter list */ 710 /* Init response here so we can pass in previous adapter list */
809 hpi_init_response(&hr, phm->object, phm->function, 711 hpi_init_response(&hr, phm->object, phm->function,
810 HPI_ERROR_INVALID_OBJ); 712 HPI_ERROR_INVALID_OBJ);
811 memcpy(hr.u.s.aw_adapter_list,
812 gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.aw_adapter_list,
813 sizeof(gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.aw_adapter_list));
814 713
815 entry_point_func = 714 entry_point_func =
816 hpi_lookup_entry_point_function(phm->u.s.resource.r.pci); 715 hpi_lookup_entry_point_function(phm->u.s.resource.r.pci);
@@ -860,7 +759,7 @@ static void HPIMSGX__cleanup(u16 adapter_index, void *h_owner)
860 struct hpi_response hr; 759 struct hpi_response hr;
861 760
862 HPI_DEBUG_LOG(DEBUG, 761 HPI_DEBUG_LOG(DEBUG,
863 "close adapter %d ostream %d\n", 762 "Close adapter %d ostream %d\n",
864 adapter, i); 763 adapter, i);
865 764
866 hpi_init_message_response(&hm, &hr, 765 hpi_init_message_response(&hm, &hr,
@@ -884,7 +783,7 @@ static void HPIMSGX__cleanup(u16 adapter_index, void *h_owner)
884 struct hpi_response hr; 783 struct hpi_response hr;
885 784
886 HPI_DEBUG_LOG(DEBUG, 785 HPI_DEBUG_LOG(DEBUG,
887 "close adapter %d istream %d\n", 786 "Close adapter %d istream %d\n",
888 adapter, i); 787 adapter, i);
889 788
890 hpi_init_message_response(&hm, &hr, 789 hpi_init_message_response(&hm, &hr,
diff --git a/sound/pci/asihpi/hpioctl.c b/sound/pci/asihpi/hpioctl.c
index 22dbd91811a4..cd624f13ff8e 100644
--- a/sound/pci/asihpi/hpioctl.c
+++ b/sound/pci/asihpi/hpioctl.c
@@ -30,6 +30,7 @@ Common Linux HPI ioctl and module probe/remove functions
30#include <linux/slab.h> 30#include <linux/slab.h>
31#include <linux/moduleparam.h> 31#include <linux/moduleparam.h>
32#include <asm/uaccess.h> 32#include <asm/uaccess.h>
33#include <linux/pci.h>
33#include <linux/stringify.h> 34#include <linux/stringify.h>
34 35
35#ifdef MODULE_FIRMWARE 36#ifdef MODULE_FIRMWARE
@@ -45,7 +46,7 @@ MODULE_FIRMWARE("asihpi/dsp8900.bin");
45static int prealloc_stream_buf; 46static int prealloc_stream_buf;
46module_param(prealloc_stream_buf, int, S_IRUGO); 47module_param(prealloc_stream_buf, int, S_IRUGO);
47MODULE_PARM_DESC(prealloc_stream_buf, 48MODULE_PARM_DESC(prealloc_stream_buf,
48 "preallocate size for per-adapter stream buffer"); 49 "Preallocate size for per-adapter stream buffer");
49 50
50/* Allow the debug level to be changed after module load. 51/* Allow the debug level to be changed after module load.
51 E.g. echo 2 > /sys/module/asihpi/parameters/hpiDebugLevel 52 E.g. echo 2 > /sys/module/asihpi/parameters/hpiDebugLevel
@@ -121,8 +122,8 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
121 phpi_ioctl_data = (struct hpi_ioctl_linux __user *)arg; 122 phpi_ioctl_data = (struct hpi_ioctl_linux __user *)arg;
122 123
123 /* Read the message and response pointers from user space. */ 124 /* Read the message and response pointers from user space. */
124 if (get_user(puhm, &phpi_ioctl_data->phm) || 125 if (get_user(puhm, &phpi_ioctl_data->phm)
125 get_user(puhr, &phpi_ioctl_data->phr)) { 126 || get_user(puhr, &phpi_ioctl_data->phr)) {
126 err = -EFAULT; 127 err = -EFAULT;
127 goto out; 128 goto out;
128 } 129 }
@@ -135,7 +136,7 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
135 if (hm->h.size > sizeof(*hm)) 136 if (hm->h.size > sizeof(*hm))
136 hm->h.size = sizeof(*hm); 137 hm->h.size = sizeof(*hm);
137 138
138 /*printk(KERN_INFO "message size %d\n", hm->h.wSize); */ 139 /* printk(KERN_INFO "message size %d\n", hm->h.wSize); */
139 140
140 uncopied_bytes = copy_from_user(hm, puhm, hm->h.size); 141 uncopied_bytes = copy_from_user(hm, puhm, hm->h.size);
141 if (uncopied_bytes) { 142 if (uncopied_bytes) {
@@ -155,8 +156,13 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
155 goto out; 156 goto out;
156 } 157 }
157 158
159 if (hm->h.adapter_index >= HPI_MAX_ADAPTERS) {
160 err = -EINVAL;
161 goto out;
162 }
163
158 pa = &adapters[hm->h.adapter_index]; 164 pa = &adapters[hm->h.adapter_index];
159 hr->h.size = 0; 165 hr->h.size = res_max_size;
160 if (hm->h.object == HPI_OBJ_SUBSYSTEM) { 166 if (hm->h.object == HPI_OBJ_SUBSYSTEM) {
161 switch (hm->h.function) { 167 switch (hm->h.function) {
162 case HPI_SUBSYS_CREATE_ADAPTER: 168 case HPI_SUBSYS_CREATE_ADAPTER:
@@ -216,7 +222,7 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
216 */ 222 */
217 if (pa->buffer_size < size) { 223 if (pa->buffer_size < size) {
218 HPI_DEBUG_LOG(DEBUG, 224 HPI_DEBUG_LOG(DEBUG,
219 "realloc adapter %d stream " 225 "Realloc adapter %d stream "
220 "buffer from %zd to %d\n", 226 "buffer from %zd to %d\n",
221 hm->h.adapter_index, 227 hm->h.adapter_index,
222 pa->buffer_size, size); 228 pa->buffer_size, size);
@@ -259,7 +265,7 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
259 copy_from_user(pa->p_buffer, ptr, size); 265 copy_from_user(pa->p_buffer, ptr, size);
260 if (uncopied_bytes) 266 if (uncopied_bytes)
261 HPI_DEBUG_LOG(WARNING, 267 HPI_DEBUG_LOG(WARNING,
262 "missed %d of %d " 268 "Missed %d of %d "
263 "bytes from user\n", uncopied_bytes, 269 "bytes from user\n", uncopied_bytes,
264 size); 270 size);
265 } 271 }
@@ -271,7 +277,7 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
271 copy_to_user(ptr, pa->p_buffer, size); 277 copy_to_user(ptr, pa->p_buffer, size);
272 if (uncopied_bytes) 278 if (uncopied_bytes)
273 HPI_DEBUG_LOG(WARNING, 279 HPI_DEBUG_LOG(WARNING,
274 "missed %d of %d " "bytes to user\n", 280 "Missed %d of %d " "bytes to user\n",
275 uncopied_bytes, size); 281 uncopied_bytes, size);
276 } 282 }
277 283
@@ -290,9 +296,9 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
290 if (hr->h.size > res_max_size) { 296 if (hr->h.size > res_max_size) {
291 HPI_DEBUG_LOG(ERROR, "response too big %d %d\n", hr->h.size, 297 HPI_DEBUG_LOG(ERROR, "response too big %d %d\n", hr->h.size,
292 res_max_size); 298 res_max_size);
293 /*HPI_DEBUG_MESSAGE(ERROR, hm); */ 299 hr->h.error = HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL;
294 err = -EFAULT; 300 hr->h.specific_error = hr->h.size;
295 goto out; 301 hr->h.size = sizeof(hr->h);
296 } 302 }
297 303
298 uncopied_bytes = copy_to_user(puhr, hr, hr->h.size); 304 uncopied_bytes = copy_to_user(puhr, hr, hr->h.size);
@@ -320,18 +326,26 @@ int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev,
320 326
321 memset(&adapter, 0, sizeof(adapter)); 327 memset(&adapter, 0, sizeof(adapter));
322 328
323 printk(KERN_DEBUG "probe PCI device (%04x:%04x,%04x:%04x,%04x)\n", 329 dev_printk(KERN_DEBUG, &pci_dev->dev,
324 pci_dev->vendor, pci_dev->device, pci_dev->subsystem_vendor, 330 "probe %04x:%04x,%04x:%04x,%04x\n", pci_dev->vendor,
331 pci_dev->device, pci_dev->subsystem_vendor,
325 pci_dev->subsystem_device, pci_dev->devfn); 332 pci_dev->subsystem_device, pci_dev->devfn);
326 333
334 if (pci_enable_device(pci_dev) < 0) {
335 dev_printk(KERN_ERR, &pci_dev->dev,
336 "pci_enable_device failed, disabling device\n");
337 return -EIO;
338 }
339
340 pci_set_master(pci_dev); /* also sets latency timer if < 16 */
341
327 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM, 342 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
328 HPI_SUBSYS_CREATE_ADAPTER); 343 HPI_SUBSYS_CREATE_ADAPTER);
329 hpi_init_response(&hr, HPI_OBJ_SUBSYSTEM, HPI_SUBSYS_CREATE_ADAPTER, 344 hpi_init_response(&hr, HPI_OBJ_SUBSYSTEM, HPI_SUBSYS_CREATE_ADAPTER,
330 HPI_ERROR_PROCESSING_MESSAGE); 345 HPI_ERROR_PROCESSING_MESSAGE);
331 346
332 hm.adapter_index = -1; /* an invalid index */ 347 hm.adapter_index = HPI_ADAPTER_INDEX_INVALID;
333 348
334 /* fill in HPI_PCI information from kernel provided information */
335 adapter.pci = pci_dev; 349 adapter.pci = pci_dev;
336 350
337 nm = HPI_MAX_ADAPTER_MEM_SPACES; 351 nm = HPI_MAX_ADAPTER_MEM_SPACES;
@@ -359,19 +373,7 @@ int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev,
359 pci.ap_mem_base[idx] = adapter.ap_remapped_mem_base[idx]; 373 pci.ap_mem_base[idx] = adapter.ap_remapped_mem_base[idx];
360 } 374 }
361 375
362 /* could replace Pci with direct pointer to pci_dev for linux 376 pci.pci_dev = pci_dev;
363 Instead wrap accessor functions for IDs etc.
364 Would it work for windows?
365 */
366 pci.bus_number = pci_dev->bus->number;
367 pci.vendor_id = (u16)pci_dev->vendor;
368 pci.device_id = (u16)pci_dev->device;
369 pci.subsys_vendor_id = (u16)(pci_dev->subsystem_vendor & 0xffff);
370 pci.subsys_device_id = (u16)(pci_dev->subsystem_device & 0xffff);
371 pci.device_number = pci_dev->devfn;
372 pci.interrupt = pci_dev->irq;
373 pci.p_os_data = pci_dev;
374
375 hm.u.s.resource.bus_type = HPI_BUS_PCI; 377 hm.u.s.resource.bus_type = HPI_BUS_PCI;
376 hm.u.s.resource.r.pci = &pci; 378 hm.u.s.resource.r.pci = &pci;
377 379
@@ -392,10 +394,10 @@ int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev,
392 } 394 }
393 395
394 adapter.index = hr.u.s.adapter_index; 396 adapter.index = hr.u.s.adapter_index;
395 adapter.type = hr.u.s.aw_adapter_list[adapter.index]; 397 adapter.type = hr.u.s.adapter_type;
396 hm.adapter_index = adapter.index; 398 hm.adapter_index = adapter.index;
397 399
398 err = hpi_adapter_open(NULL, adapter.index); 400 err = hpi_adapter_open(adapter.index);
399 if (err) 401 if (err)
400 goto err; 402 goto err;
401 403
@@ -407,8 +409,9 @@ int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev,
407 mutex_init(&adapters[adapter.index].mutex); 409 mutex_init(&adapters[adapter.index].mutex);
408 pci_set_drvdata(pci_dev, &adapters[adapter.index]); 410 pci_set_drvdata(pci_dev, &adapters[adapter.index]);
409 411
410 printk(KERN_INFO "probe found adapter ASI%04X HPI index #%d.\n", 412 dev_printk(KERN_INFO, &pci_dev->dev,
411 adapter.type, adapter.index); 413 "probe succeeded for ASI%04X HPI index %d\n", adapter.type,
414 adapter.index);
412 415
413 return 0; 416 return 0;
414 417
@@ -439,7 +442,8 @@ void __devexit asihpi_adapter_remove(struct pci_dev *pci_dev)
439 442
440 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM, 443 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
441 HPI_SUBSYS_DELETE_ADAPTER); 444 HPI_SUBSYS_DELETE_ADAPTER);
442 hm.adapter_index = pa->index; 445 hm.obj_index = pa->index;
446 hm.adapter_index = HPI_ADAPTER_INDEX_INVALID;
443 hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL); 447 hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL);
444 448
445 /* unmap PCI memory space, mapped during device init. */ 449 /* unmap PCI memory space, mapped during device init. */
@@ -450,20 +454,18 @@ void __devexit asihpi_adapter_remove(struct pci_dev *pci_dev)
450 } 454 }
451 } 455 }
452 456
453 if (pa->p_buffer) { 457 if (pa->p_buffer)
454 pa->buffer_size = 0;
455 vfree(pa->p_buffer); 458 vfree(pa->p_buffer);
456 }
457 459
458 pci_set_drvdata(pci_dev, NULL); 460 pci_set_drvdata(pci_dev, NULL);
459 /* 461 if (1)
460 printk(KERN_INFO "PCI device (%04x:%04x,%04x:%04x,%04x)," 462 dev_printk(KERN_INFO, &pci_dev->dev,
461 " HPI index # %d, removed.\n", 463 "remove %04x:%04x,%04x:%04x,%04x," " HPI index %d.\n",
462 pci_dev->vendor, pci_dev->device, 464 pci_dev->vendor, pci_dev->device,
463 pci_dev->subsystem_vendor, 465 pci_dev->subsystem_vendor, pci_dev->subsystem_device,
464 pci_dev->subsystem_device, pci_dev->devfn, 466 pci_dev->devfn, pa->index);
465 pa->index); 467
466 */ 468 memset(pa, 0, sizeof(*pa));
467} 469}
468 470
469void __init asihpi_init(void) 471void __init asihpi_init(void)
diff --git a/sound/pci/asihpi/hpios.h b/sound/pci/asihpi/hpios.h
index 370f39b43f85..03273e729f99 100644
--- a/sound/pci/asihpi/hpios.h
+++ b/sound/pci/asihpi/hpios.h
@@ -27,9 +27,7 @@ HPI Operating System Specific macros for Linux Kernel driver
27#define HPI_OS_LINUX_KERNEL 27#define HPI_OS_LINUX_KERNEL
28 28
29#define HPI_OS_DEFINED 29#define HPI_OS_DEFINED
30#define HPI_KERNEL_MODE 30#define HPI_BUILD_KERNEL_MODE
31
32#define HPI_REASSIGN_DUPLICATE_ADAPTER_IDX
33 31
34#include <linux/io.h> 32#include <linux/io.h>
35#include <asm/system.h> 33#include <asm/system.h>
@@ -135,20 +133,20 @@ static inline void cond_unlock(struct hpios_spinlock *l)
135 133
136#define hpios_msgxlock_init(obj) spin_lock_init(&(obj)->lock) 134#define hpios_msgxlock_init(obj) spin_lock_init(&(obj)->lock)
137#define hpios_msgxlock_lock(obj) cond_lock(obj) 135#define hpios_msgxlock_lock(obj) cond_lock(obj)
138#define hpios_msgxlock_un_lock(obj) cond_unlock(obj) 136#define hpios_msgxlock_unlock(obj) cond_unlock(obj)
139 137
140#define hpios_dsplock_init(obj) spin_lock_init(&(obj)->dsp_lock.lock) 138#define hpios_dsplock_init(obj) spin_lock_init(&(obj)->dsp_lock.lock)
141#define hpios_dsplock_lock(obj) cond_lock(&(obj)->dsp_lock) 139#define hpios_dsplock_lock(obj) cond_lock(&(obj)->dsp_lock)
142#define hpios_dsplock_unlock(obj) cond_unlock(&(obj)->dsp_lock) 140#define hpios_dsplock_unlock(obj) cond_unlock(&(obj)->dsp_lock)
143 141
144#ifdef CONFIG_SND_DEBUG 142#ifdef CONFIG_SND_DEBUG
145#define HPI_DEBUG 143#define HPI_BUILD_DEBUG
146#endif 144#endif
147 145
148#define HPI_ALIST_LOCKING 146#define HPI_ALIST_LOCKING
149#define hpios_alistlock_init(obj) spin_lock_init(&((obj)->list_lock.lock)) 147#define hpios_alistlock_init(obj) spin_lock_init(&((obj)->list_lock.lock))
150#define hpios_alistlock_lock(obj) spin_lock(&((obj)->list_lock.lock)) 148#define hpios_alistlock_lock(obj) spin_lock(&((obj)->list_lock.lock))
151#define hpios_alistlock_un_lock(obj) spin_unlock(&((obj)->list_lock.lock)) 149#define hpios_alistlock_unlock(obj) spin_unlock(&((obj)->list_lock.lock))
152 150
153struct hpi_adapter { 151struct hpi_adapter {
154 /* mutex prevents contention for one card 152 /* mutex prevents contention for one card
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c
index 49d572a7b235..3119cd97a217 100644
--- a/sound/pci/atiixp.c
+++ b/sound/pci/atiixp.c
@@ -522,7 +522,7 @@ static int snd_atiixp_aclink_reset(struct atiixp *chip)
522 atiixp_read(chip, CMD); 522 atiixp_read(chip, CMD);
523 mdelay(1); 523 mdelay(1);
524 atiixp_update(chip, CMD, ATI_REG_CMD_AC_RESET, ATI_REG_CMD_AC_RESET); 524 atiixp_update(chip, CMD, ATI_REG_CMD_AC_RESET, ATI_REG_CMD_AC_RESET);
525 if (--timeout) { 525 if (!--timeout) {
526 snd_printk(KERN_ERR "atiixp: codec reset timeout\n"); 526 snd_printk(KERN_ERR "atiixp: codec reset timeout\n");
527 break; 527 break;
528 } 528 }
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c
index 91d7036b6411..2f74c2fdf1ea 100644
--- a/sound/pci/atiixp_modem.c
+++ b/sound/pci/atiixp_modem.c
@@ -498,7 +498,7 @@ static int snd_atiixp_aclink_reset(struct atiixp_modem *chip)
498 atiixp_read(chip, CMD); 498 atiixp_read(chip, CMD);
499 msleep(1); 499 msleep(1);
500 atiixp_update(chip, CMD, ATI_REG_CMD_AC_RESET, ATI_REG_CMD_AC_RESET); 500 atiixp_update(chip, CMD, ATI_REG_CMD_AC_RESET, ATI_REG_CMD_AC_RESET);
501 if (--timeout) { 501 if (!--timeout) {
502 snd_printk(KERN_ERR "atiixp-modem: codec reset timeout\n"); 502 snd_printk(KERN_ERR "atiixp-modem: codec reset timeout\n");
503 break; 503 break;
504 } 504 }
diff --git a/sound/pci/au88x0/au88x0_eq.c b/sound/pci/au88x0/au88x0_eq.c
index 38602b85874d..278ed8189fca 100644
--- a/sound/pci/au88x0/au88x0_eq.c
+++ b/sound/pci/au88x0/au88x0_eq.c
@@ -896,7 +896,8 @@ static int __devinit vortex_eq_init(vortex_t * vortex)
896 if ((kcontrol = 896 if ((kcontrol =
897 snd_ctl_new1(&vortex_eq_kcontrol, vortex)) == NULL) 897 snd_ctl_new1(&vortex_eq_kcontrol, vortex)) == NULL)
898 return -ENOMEM; 898 return -ENOMEM;
899 strcpy(kcontrol->id.name, EqBandLabels[i]); 899 snprintf(kcontrol->id.name, sizeof(kcontrol->id.name),
900 "%s Playback Volume", EqBandLabels[i]);
900 kcontrol->private_value = i; 901 kcontrol->private_value = i;
901 if ((err = snd_ctl_add(vortex->card, kcontrol)) < 0) 902 if ((err = snd_ctl_add(vortex->card, kcontrol)) < 0)
902 return err; 903 return err;
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index 573594bf3225..5715c4d05573 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -1,6 +1,5 @@
1/* 1/* azt3328.c - driver for Aztech AZF3328 based soundcards (e.g. PCI168).
2 * azt3328.c - driver for Aztech AZF3328 based soundcards (e.g. PCI168). 2 * Copyright (C) 2002, 2005 - 2011 by Andreas Mohr <andi AT lisas.de>
3 * Copyright (C) 2002, 2005 - 2010 by Andreas Mohr <andi AT lisas.de>
4 * 3 *
5 * Framework borrowed from Bart Hartgers's als4000.c. 4 * Framework borrowed from Bart Hartgers's als4000.c.
6 * Driver developed on PCI168 AP(W) version (PCI rev. 10, subsystem ID 1801), 5 * Driver developed on PCI168 AP(W) version (PCI rev. 10, subsystem ID 1801),
@@ -66,6 +65,13 @@
66 * addresses illegally. So far unfortunately it looks like the very flexible 65 * addresses illegally. So far unfortunately it looks like the very flexible
67 * ALSA AC97 support is still not enough to easily compensate for such a 66 * ALSA AC97 support is still not enough to easily compensate for such a
68 * grave layout violation despite all tweaks and quirks mechanisms it offers. 67 * grave layout violation despite all tweaks and quirks mechanisms it offers.
68 * Well, not quite: now ac97 layer is much improved (bus-specific ops!),
69 * thus I was able to implement support - it's actually working quite well.
70 * An interesting item might be Aztech AMR 2800-W, since it's an AC97
71 * modem card which might reveal the Aztech-specific codec ID which
72 * we might want to pretend, too. Dito PCI168's brother, PCI368,
73 * where the advertising datasheet says it's AC97-based and has a
74 * Digital Enhanced Game Port.
69 * - builtin genuine OPL3 - verified to work fine, 20080506 75 * - builtin genuine OPL3 - verified to work fine, 20080506
70 * - full duplex 16bit playback/record at independent sampling rate 76 * - full duplex 16bit playback/record at independent sampling rate
71 * - MPU401 (+ legacy address support, claimed by one official spec sheet) 77 * - MPU401 (+ legacy address support, claimed by one official spec sheet)
@@ -189,6 +195,16 @@
189#include <sound/mpu401.h> 195#include <sound/mpu401.h>
190#include <sound/opl3.h> 196#include <sound/opl3.h>
191#include <sound/initval.h> 197#include <sound/initval.h>
198/*
199 * Config switch, to use ALSA's AC97 layer instead of old custom mixer crap.
200 * If the AC97 compatibility parts we needed to implement locally turn out
201 * to work nicely, then remove the old implementation eventually.
202 */
203#define AZF_USE_AC97_LAYER 1
204
205#ifdef AZF_USE_AC97_LAYER
206#include <sound/ac97_codec.h>
207#endif
192#include "azt3328.h" 208#include "azt3328.h"
193 209
194MODULE_AUTHOR("Andreas Mohr <andi AT lisas.de>"); 210MODULE_AUTHOR("Andreas Mohr <andi AT lisas.de>");
@@ -328,6 +344,10 @@ struct snd_azf3328 {
328 /* playback, recording and I2S out codecs */ 344 /* playback, recording and I2S out codecs */
329 struct snd_azf3328_codec_data codecs[3]; 345 struct snd_azf3328_codec_data codecs[3];
330 346
347#ifdef AZF_USE_AC97_LAYER
348 struct snd_ac97 *ac97;
349#endif
350
331 struct snd_card *card; 351 struct snd_card *card;
332 struct snd_rawmidi *rmidi; 352 struct snd_rawmidi *rmidi;
333 353
@@ -506,7 +526,7 @@ snd_azf3328_mixer_inw(const struct snd_azf3328 *chip, unsigned reg)
506#define AZF_MUTE_BIT 0x80 526#define AZF_MUTE_BIT 0x80
507 527
508static bool 528static bool
509snd_azf3328_mixer_set_mute(const struct snd_azf3328 *chip, 529snd_azf3328_mixer_mute_control(const struct snd_azf3328 *chip,
510 unsigned reg, bool do_mute 530 unsigned reg, bool do_mute
511) 531)
512{ 532{
@@ -521,6 +541,323 @@ snd_azf3328_mixer_set_mute(const struct snd_azf3328 *chip,
521 return (do_mute) ? !updated : updated; 541 return (do_mute) ? !updated : updated;
522} 542}
523 543
544static inline bool
545snd_azf3328_mixer_mute_control_master(const struct snd_azf3328 *chip,
546 bool do_mute
547)
548{
549 return snd_azf3328_mixer_mute_control(
550 chip,
551 IDX_MIXER_PLAY_MASTER,
552 do_mute
553 );
554}
555
556static inline bool
557snd_azf3328_mixer_mute_control_pcm(const struct snd_azf3328 *chip,
558 bool do_mute
559)
560{
561 return snd_azf3328_mixer_mute_control(
562 chip,
563 IDX_MIXER_WAVEOUT,
564 do_mute
565 );
566}
567
568static inline void
569snd_azf3328_mixer_reset(const struct snd_azf3328 *chip)
570{
571 /* reset (close) mixer:
572 * first mute master volume, then reset
573 */
574 snd_azf3328_mixer_mute_control_master(chip, 1);
575 snd_azf3328_mixer_outw(chip, IDX_MIXER_RESET, 0x0000);
576}
577
578#ifdef AZF_USE_AC97_LAYER
579
580static inline void
581snd_azf3328_mixer_ac97_map_unsupported(unsigned short reg, const char *mode)
582{
583 /* need to add some more or less clever emulation? */
584 printk(KERN_WARNING
585 "azt3328: missing %s emulation for AC97 register 0x%02x!\n",
586 mode, reg);
587}
588
589/*
590 * Need to have _special_ AC97 mixer hardware register index mapper,
591 * to compensate for the issue of a rather AC97-incompatible hardware layout.
592 */
593#define AZF_REG_MASK 0x3f
594#define AZF_AC97_REG_UNSUPPORTED 0x8000
595#define AZF_AC97_REG_REAL_IO_READ 0x4000
596#define AZF_AC97_REG_REAL_IO_WRITE 0x2000
597#define AZF_AC97_REG_REAL_IO_RW \
598 (AZF_AC97_REG_REAL_IO_READ | AZF_AC97_REG_REAL_IO_WRITE)
599#define AZF_AC97_REG_EMU_IO_READ 0x0400
600#define AZF_AC97_REG_EMU_IO_WRITE 0x0200
601#define AZF_AC97_REG_EMU_IO_RW \
602 (AZF_AC97_REG_EMU_IO_READ | AZF_AC97_REG_EMU_IO_WRITE)
603static unsigned short
604snd_azf3328_mixer_ac97_map_reg_idx(unsigned short reg)
605{
606 static const struct {
607 unsigned short azf_reg;
608 } azf_reg_mapper[] = {
609 /* Especially when taking into consideration
610 * mono/stereo-based sequence of azf vs. AC97 control series,
611 * it's quite obvious that azf simply got rid
612 * of the AC97_HEADPHONE control at its intended offset,
613 * thus shifted _all_ controls by one,
614 * and _then_ simply added it as an FMSYNTH control at the end,
615 * to make up for the offset.
616 * This means we'll have to translate indices here as
617 * needed and then do some tiny AC97 patch action
618 * (snd_ac97_rename_vol_ctl() etc.) - that's it.
619 */
620 { /* AC97_RESET */ IDX_MIXER_RESET
621 | AZF_AC97_REG_REAL_IO_WRITE
622 | AZF_AC97_REG_EMU_IO_READ },
623 { /* AC97_MASTER */ IDX_MIXER_PLAY_MASTER },
624 /* note large shift: AC97_HEADPHONE to IDX_MIXER_FMSYNTH! */
625 { /* AC97_HEADPHONE */ IDX_MIXER_FMSYNTH },
626 { /* AC97_MASTER_MONO */ IDX_MIXER_MODEMOUT },
627 { /* AC97_MASTER_TONE */ IDX_MIXER_BASSTREBLE },
628 { /* AC97_PC_BEEP */ IDX_MIXER_PCBEEP },
629 { /* AC97_PHONE */ IDX_MIXER_MODEMIN },
630 { /* AC97_MIC */ IDX_MIXER_MIC },
631 { /* AC97_LINE */ IDX_MIXER_LINEIN },
632 { /* AC97_CD */ IDX_MIXER_CDAUDIO },
633 { /* AC97_VIDEO */ IDX_MIXER_VIDEO },
634 { /* AC97_AUX */ IDX_MIXER_AUX },
635 { /* AC97_PCM */ IDX_MIXER_WAVEOUT },
636 { /* AC97_REC_SEL */ IDX_MIXER_REC_SELECT },
637 { /* AC97_REC_GAIN */ IDX_MIXER_REC_VOLUME },
638 { /* AC97_REC_GAIN_MIC */ AZF_AC97_REG_EMU_IO_RW },
639 { /* AC97_GENERAL_PURPOSE */ IDX_MIXER_ADVCTL2 },
640 { /* AC97_3D_CONTROL */ IDX_MIXER_ADVCTL1 },
641 };
642
643 unsigned short reg_azf = AZF_AC97_REG_UNSUPPORTED;
644
645 /* azf3328 supports the low-numbered and low-spec:ed range
646 of AC97 regs only */
647 if (reg <= AC97_3D_CONTROL) {
648 unsigned short reg_idx = reg / 2;
649 reg_azf = azf_reg_mapper[reg_idx].azf_reg;
650 /* a translation-only entry means it's real read/write: */
651 if (!(reg_azf & ~AZF_REG_MASK))
652 reg_azf |= AZF_AC97_REG_REAL_IO_RW;
653 } else {
654 switch (reg) {
655 case AC97_POWERDOWN:
656 reg_azf = AZF_AC97_REG_EMU_IO_RW;
657 break;
658 case AC97_EXTENDED_ID:
659 reg_azf = AZF_AC97_REG_EMU_IO_READ;
660 break;
661 case AC97_EXTENDED_STATUS:
662 /* I don't know what the h*ll AC97 layer
663 * would consult this _extended_ register for
664 * given a base-AC97-advertised card,
665 * but let's just emulate it anyway :-P
666 */
667 reg_azf = AZF_AC97_REG_EMU_IO_RW;
668 break;
669 case AC97_VENDOR_ID1:
670 case AC97_VENDOR_ID2:
671 reg_azf = AZF_AC97_REG_EMU_IO_READ;
672 break;
673 }
674 }
675 return reg_azf;
676}
677
678static const unsigned short
679azf_emulated_ac97_caps =
680 AC97_BC_DEDICATED_MIC |
681 AC97_BC_BASS_TREBLE |
682 /* Headphone is an FM Synth control here */
683 AC97_BC_HEADPHONE |
684 /* no AC97_BC_LOUDNESS! */
685 /* mask 0x7c00 is
686 vendor-specific 3D enhancement
687 vendor indicator.
688 Since there actually _is_ an
689 entry for Aztech Labs
690 (13), make damn sure
691 to indicate it. */
692 (13 << 10);
693
694static const unsigned short
695azf_emulated_ac97_powerdown =
696 /* pretend everything to be active */
697 AC97_PD_ADC_STATUS |
698 AC97_PD_DAC_STATUS |
699 AC97_PD_MIXER_STATUS |
700 AC97_PD_VREF_STATUS;
701
702/*
703 * Emulated, _inofficial_ vendor ID
704 * (there might be some devices such as the MR 2800-W
705 * which could reveal the real Aztech AC97 ID).
706 * We choose to use "AZT" prefix, and then use 1 to indicate PCI168
707 * (better don't use 0x68 since there's a PCI368 as well).
708 */
709static const unsigned int
710azf_emulated_ac97_vendor_id = 0x415a5401;
711
712static unsigned short
713snd_azf3328_mixer_ac97_read(struct snd_ac97 *ac97, unsigned short reg_ac97)
714{
715 const struct snd_azf3328 *chip = ac97->private_data;
716 unsigned short reg_azf = snd_azf3328_mixer_ac97_map_reg_idx(reg_ac97);
717 unsigned short reg_val = 0;
718 bool unsupported = 0;
719
720 snd_azf3328_dbgmixer(
721 "snd_azf3328_mixer_ac97_read reg_ac97 %u\n",
722 reg_ac97
723 );
724 if (reg_azf & AZF_AC97_REG_UNSUPPORTED)
725 unsupported = 1;
726 else {
727 if (reg_azf & AZF_AC97_REG_REAL_IO_READ)
728 reg_val = snd_azf3328_mixer_inw(chip,
729 reg_azf & AZF_REG_MASK);
730 else {
731 /*
732 * Proceed with dummy I/O read,
733 * to ensure compatible timing where this may matter.
734 * (ALSA AC97 layer usually doesn't call I/O functions
735 * due to intelligent I/O caching anyway)
736 * Choose a mixer register that's thoroughly unrelated
737 * to common audio (try to minimize distortion).
738 */
739 snd_azf3328_mixer_inw(chip, IDX_MIXER_SOMETHING30H);
740 }
741
742 if (reg_azf & AZF_AC97_REG_EMU_IO_READ) {
743 switch (reg_ac97) {
744 case AC97_RESET:
745 reg_val |= azf_emulated_ac97_caps;
746 break;
747 case AC97_POWERDOWN:
748 reg_val |= azf_emulated_ac97_powerdown;
749 break;
750 case AC97_EXTENDED_ID:
751 case AC97_EXTENDED_STATUS:
752 /* AFAICS we simply can't support anything: */
753 reg_val |= 0;
754 break;
755 case AC97_VENDOR_ID1:
756 reg_val = azf_emulated_ac97_vendor_id >> 16;
757 break;
758 case AC97_VENDOR_ID2:
759 reg_val = azf_emulated_ac97_vendor_id & 0xffff;
760 break;
761 default:
762 unsupported = 1;
763 break;
764 }
765 }
766 }
767 if (unsupported)
768 snd_azf3328_mixer_ac97_map_unsupported(reg_ac97, "read");
769
770 return reg_val;
771}
772
773static void
774snd_azf3328_mixer_ac97_write(struct snd_ac97 *ac97,
775 unsigned short reg_ac97, unsigned short val)
776{
777 const struct snd_azf3328 *chip = ac97->private_data;
778 unsigned short reg_azf = snd_azf3328_mixer_ac97_map_reg_idx(reg_ac97);
779 bool unsupported = 0;
780
781 snd_azf3328_dbgmixer(
782 "snd_azf3328_mixer_ac97_write reg_ac97 %u val %u\n",
783 reg_ac97, val
784 );
785 if (reg_azf & AZF_AC97_REG_UNSUPPORTED)
786 unsupported = 1;
787 else {
788 if (reg_azf & AZF_AC97_REG_REAL_IO_WRITE)
789 snd_azf3328_mixer_outw(
790 chip,
791 reg_azf & AZF_REG_MASK,
792 val
793 );
794 else
795 if (reg_azf & AZF_AC97_REG_EMU_IO_WRITE) {
796 switch (reg_ac97) {
797 case AC97_REC_GAIN_MIC:
798 case AC97_POWERDOWN:
799 case AC97_EXTENDED_STATUS:
800 /*
801 * Silently swallow these writes.
802 * Since for most registers our card doesn't
803 * actually support a comparable feature,
804 * this is exactly what we should do here.
805 * The AC97 layer's I/O caching probably
806 * automatically takes care of all the rest...
807 * (remembers written values etc.)
808 */
809 break;
810 default:
811 unsupported = 1;
812 break;
813 }
814 }
815 }
816 if (unsupported)
817 snd_azf3328_mixer_ac97_map_unsupported(reg_ac97, "write");
818}
819
820static int __devinit
821snd_azf3328_mixer_new(struct snd_azf3328 *chip)
822{
823 struct snd_ac97_bus *bus;
824 struct snd_ac97_template ac97;
825 static struct snd_ac97_bus_ops ops = {
826 .write = snd_azf3328_mixer_ac97_write,
827 .read = snd_azf3328_mixer_ac97_read,
828 };
829 int rc;
830
831 memset(&ac97, 0, sizeof(ac97));
832 ac97.scaps = AC97_SCAP_SKIP_MODEM
833 | AC97_SCAP_AUDIO /* we support audio! */
834 | AC97_SCAP_NO_SPDIF;
835 ac97.private_data = chip;
836 ac97.pci = chip->pci;
837
838 /*
839 * ALSA's AC97 layer has terrible init crackling issues,
840 * unfortunately, and since it makes use of AC97_RESET,
841 * there's no use trying to mute Master Playback proactively.
842 */
843
844 rc = snd_ac97_bus(chip->card, 0, &ops, NULL, &bus);
845 if (!rc)
846 rc = snd_ac97_mixer(bus, &ac97, &chip->ac97);
847 /*
848 * Make sure to complain loudly in case of AC97 init failure,
849 * since failure may happen quite often,
850 * due to this card being a very quirky AC97 "lookalike".
851 */
852 if (rc)
853 printk(KERN_ERR "azt3328: AC97 init failed, err %d!\n", rc);
854
855 /* If we return an error here, then snd_card_free() should
856 * free up any ac97 codecs that got created, as well as the bus.
857 */
858 return rc;
859}
860#else /* AZF_USE_AC97_LAYER */
524static void 861static void
525snd_azf3328_mixer_write_volume_gradually(const struct snd_azf3328 *chip, 862snd_azf3328_mixer_write_volume_gradually(const struct snd_azf3328 *chip,
526 unsigned reg, 863 unsigned reg,
@@ -945,6 +1282,7 @@ snd_azf3328_mixer_new(struct snd_azf3328 *chip)
945 snd_azf3328_dbgcallleave(); 1282 snd_azf3328_dbgcallleave();
946 return 0; 1283 return 0;
947} 1284}
1285#endif /* AZF_USE_AC97_LAYER */
948 1286
949static int 1287static int
950snd_azf3328_hw_params(struct snd_pcm_substream *substream, 1288snd_azf3328_hw_params(struct snd_pcm_substream *substream,
@@ -1233,8 +1571,8 @@ snd_azf3328_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
1233 if (is_main_mixer_playback_codec) { 1571 if (is_main_mixer_playback_codec) {
1234 /* mute WaveOut (avoid clicking during setup) */ 1572 /* mute WaveOut (avoid clicking during setup) */
1235 previously_muted = 1573 previously_muted =
1236 snd_azf3328_mixer_set_mute( 1574 snd_azf3328_mixer_mute_control_pcm(
1237 chip, IDX_MIXER_WAVEOUT, 1 1575 chip, 1
1238 ); 1576 );
1239 } 1577 }
1240 1578
@@ -1290,8 +1628,8 @@ snd_azf3328_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
1290 if (is_main_mixer_playback_codec) { 1628 if (is_main_mixer_playback_codec) {
1291 /* now unmute WaveOut */ 1629 /* now unmute WaveOut */
1292 if (!previously_muted) 1630 if (!previously_muted)
1293 snd_azf3328_mixer_set_mute( 1631 snd_azf3328_mixer_mute_control_pcm(
1294 chip, IDX_MIXER_WAVEOUT, 0 1632 chip, 0
1295 ); 1633 );
1296 } 1634 }
1297 1635
@@ -1315,8 +1653,8 @@ snd_azf3328_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
1315 if (is_main_mixer_playback_codec) { 1653 if (is_main_mixer_playback_codec) {
1316 /* mute WaveOut (avoid clicking during setup) */ 1654 /* mute WaveOut (avoid clicking during setup) */
1317 previously_muted = 1655 previously_muted =
1318 snd_azf3328_mixer_set_mute( 1656 snd_azf3328_mixer_mute_control_pcm(
1319 chip, IDX_MIXER_WAVEOUT, 1 1657 chip, 1
1320 ); 1658 );
1321 } 1659 }
1322 1660
@@ -1341,8 +1679,8 @@ snd_azf3328_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
1341 if (is_main_mixer_playback_codec) { 1679 if (is_main_mixer_playback_codec) {
1342 /* now unmute WaveOut */ 1680 /* now unmute WaveOut */
1343 if (!previously_muted) 1681 if (!previously_muted)
1344 snd_azf3328_mixer_set_mute( 1682 snd_azf3328_mixer_mute_control_pcm(
1345 chip, IDX_MIXER_WAVEOUT, 0 1683 chip, 0
1346 ); 1684 );
1347 } 1685 }
1348 1686
@@ -2050,11 +2388,7 @@ snd_azf3328_free(struct snd_azf3328 *chip)
2050 if (chip->irq < 0) 2388 if (chip->irq < 0)
2051 goto __end_hw; 2389 goto __end_hw;
2052 2390
2053 /* reset (close) mixer: 2391 snd_azf3328_mixer_reset(chip);
2054 * first mute master volume, then reset
2055 */
2056 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_PLAY_MASTER, 1);
2057 snd_azf3328_mixer_outw(chip, IDX_MIXER_RESET, 0x0000);
2058 2392
2059 snd_azf3328_timer_stop(chip->timer); 2393 snd_azf3328_timer_stop(chip->timer);
2060 snd_azf3328_gameport_free(chip); 2394 snd_azf3328_gameport_free(chip);
@@ -2407,6 +2741,55 @@ snd_azf3328_suspend_regs(unsigned long io_addr, unsigned count, u32 *saved_regs)
2407 } 2741 }
2408} 2742}
2409 2743
2744static inline void
2745snd_azf3328_resume_regs(const u32 *saved_regs,
2746 unsigned long io_addr,
2747 unsigned count
2748)
2749{
2750 unsigned reg;
2751
2752 for (reg = 0; reg < count; ++reg) {
2753 outl(*saved_regs, io_addr);
2754 snd_azf3328_dbgpm("resume: io 0x%04lx: 0x%08x --> 0x%08x\n",
2755 io_addr, *saved_regs, inl(io_addr));
2756 ++saved_regs;
2757 io_addr += sizeof(*saved_regs);
2758 }
2759}
2760
2761static inline void
2762snd_azf3328_suspend_ac97(struct snd_azf3328 *chip)
2763{
2764#ifdef AZF_USE_AC97_LAYER
2765 snd_ac97_suspend(chip->ac97);
2766#else
2767 snd_azf3328_suspend_regs(chip->mixer_io,
2768 ARRAY_SIZE(chip->saved_regs_mixer), chip->saved_regs_mixer);
2769
2770 /* make sure to disable master volume etc. to prevent looping sound */
2771 snd_azf3328_mixer_mute_control_master(chip, 1);
2772 snd_azf3328_mixer_mute_control_pcm(chip, 1);
2773#endif /* AZF_USE_AC97_LAYER */
2774}
2775
2776static inline void
2777snd_azf3328_resume_ac97(const struct snd_azf3328 *chip)
2778{
2779#ifdef AZF_USE_AC97_LAYER
2780 snd_ac97_resume(chip->ac97);
2781#else
2782 snd_azf3328_resume_regs(chip->saved_regs_mixer, chip->mixer_io,
2783 ARRAY_SIZE(chip->saved_regs_mixer));
2784
2785 /* unfortunately with 32bit transfers, IDX_MIXER_PLAY_MASTER (0x02)
2786 and IDX_MIXER_RESET (offset 0x00) get touched at the same time,
2787 resulting in a mixer reset condition persisting until _after_
2788 master vol was restored. Thus master vol needs an extra restore. */
2789 outw(((u16 *)chip->saved_regs_mixer)[1], chip->mixer_io + 2);
2790#endif /* AZF_USE_AC97_LAYER */
2791}
2792
2410static int 2793static int
2411snd_azf3328_suspend(struct pci_dev *pci, pm_message_t state) 2794snd_azf3328_suspend(struct pci_dev *pci, pm_message_t state)
2412{ 2795{
@@ -2420,12 +2803,7 @@ snd_azf3328_suspend(struct pci_dev *pci, pm_message_t state)
2420 snd_pcm_suspend_all(chip->pcm[AZF_CODEC_PLAYBACK]); 2803 snd_pcm_suspend_all(chip->pcm[AZF_CODEC_PLAYBACK]);
2421 snd_pcm_suspend_all(chip->pcm[AZF_CODEC_I2S_OUT]); 2804 snd_pcm_suspend_all(chip->pcm[AZF_CODEC_I2S_OUT]);
2422 2805
2423 snd_azf3328_suspend_regs(chip->mixer_io, 2806 snd_azf3328_suspend_ac97(chip);
2424 ARRAY_SIZE(chip->saved_regs_mixer), chip->saved_regs_mixer);
2425
2426 /* make sure to disable master volume etc. to prevent looping sound */
2427 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_PLAY_MASTER, 1);
2428 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1);
2429 2807
2430 snd_azf3328_suspend_regs(chip->ctrl_io, 2808 snd_azf3328_suspend_regs(chip->ctrl_io,
2431 ARRAY_SIZE(chip->saved_regs_ctrl), chip->saved_regs_ctrl); 2809 ARRAY_SIZE(chip->saved_regs_ctrl), chip->saved_regs_ctrl);
@@ -2447,23 +2825,6 @@ snd_azf3328_suspend(struct pci_dev *pci, pm_message_t state)
2447 return 0; 2825 return 0;
2448} 2826}
2449 2827
2450static inline void
2451snd_azf3328_resume_regs(const u32 *saved_regs,
2452 unsigned long io_addr,
2453 unsigned count
2454)
2455{
2456 unsigned reg;
2457
2458 for (reg = 0; reg < count; ++reg) {
2459 outl(*saved_regs, io_addr);
2460 snd_azf3328_dbgpm("resume: io 0x%04lx: 0x%08x --> 0x%08x\n",
2461 io_addr, *saved_regs, inl(io_addr));
2462 ++saved_regs;
2463 io_addr += sizeof(*saved_regs);
2464 }
2465}
2466
2467static int 2828static int
2468snd_azf3328_resume(struct pci_dev *pci) 2829snd_azf3328_resume(struct pci_dev *pci)
2469{ 2830{
@@ -2487,14 +2848,7 @@ snd_azf3328_resume(struct pci_dev *pci)
2487 snd_azf3328_resume_regs(chip->saved_regs_opl3, chip->opl3_io, 2848 snd_azf3328_resume_regs(chip->saved_regs_opl3, chip->opl3_io,
2488 ARRAY_SIZE(chip->saved_regs_opl3)); 2849 ARRAY_SIZE(chip->saved_regs_opl3));
2489 2850
2490 snd_azf3328_resume_regs(chip->saved_regs_mixer, chip->mixer_io, 2851 snd_azf3328_resume_ac97(chip);
2491 ARRAY_SIZE(chip->saved_regs_mixer));
2492
2493 /* unfortunately with 32bit transfers, IDX_MIXER_PLAY_MASTER (0x02)
2494 and IDX_MIXER_RESET (offset 0x00) get touched at the same time,
2495 resulting in a mixer reset condition persisting until _after_
2496 master vol was restored. Thus master vol needs an extra restore. */
2497 outw(((u16 *)chip->saved_regs_mixer)[1], chip->mixer_io + 2);
2498 2852
2499 snd_azf3328_resume_regs(chip->saved_regs_ctrl, chip->ctrl_io, 2853 snd_azf3328_resume_regs(chip->saved_regs_ctrl, chip->ctrl_io,
2500 ARRAY_SIZE(chip->saved_regs_ctrl)); 2854 ARRAY_SIZE(chip->saved_regs_ctrl));
diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c
index 1bff80cde0a2..b9321544c31c 100644
--- a/sound/pci/ctxfi/ctatc.c
+++ b/sound/pci/ctxfi/ctatc.c
@@ -869,7 +869,7 @@ spdif_passthru_playback_setup(struct ct_atc *atc, struct ct_atc_pcm *apcm)
869 mutex_lock(&atc->atc_mutex); 869 mutex_lock(&atc->atc_mutex);
870 dao->ops->get_spos(dao, &status); 870 dao->ops->get_spos(dao, &status);
871 if (((status >> 24) & IEC958_AES3_CON_FS) != iec958_con_fs) { 871 if (((status >> 24) & IEC958_AES3_CON_FS) != iec958_con_fs) {
872 status &= ((~IEC958_AES3_CON_FS) << 24); 872 status &= ~(IEC958_AES3_CON_FS << 24);
873 status |= (iec958_con_fs << 24); 873 status |= (iec958_con_fs << 24);
874 dao->ops->set_spos(dao, status); 874 dao->ops->set_spos(dao, status);
875 dao->ops->commit_write(dao); 875 dao->ops->commit_write(dao);
diff --git a/sound/pci/ctxfi/ctdaio.c b/sound/pci/ctxfi/ctdaio.c
index af56eb949bde..47d9ea97de02 100644
--- a/sound/pci/ctxfi/ctdaio.c
+++ b/sound/pci/ctxfi/ctdaio.c
@@ -176,6 +176,7 @@ static int dao_set_left_input(struct dao *dao, struct rsc *input)
176 if (!entry) 176 if (!entry)
177 return -ENOMEM; 177 return -ENOMEM;
178 178
179 dao->ops->clear_left_input(dao);
179 /* Program master and conjugate resources */ 180 /* Program master and conjugate resources */
180 input->ops->master(input); 181 input->ops->master(input);
181 daio->rscl.ops->master(&daio->rscl); 182 daio->rscl.ops->master(&daio->rscl);
@@ -204,6 +205,7 @@ static int dao_set_right_input(struct dao *dao, struct rsc *input)
204 if (!entry) 205 if (!entry)
205 return -ENOMEM; 206 return -ENOMEM;
206 207
208 dao->ops->clear_right_input(dao);
207 /* Program master and conjugate resources */ 209 /* Program master and conjugate resources */
208 input->ops->master(input); 210 input->ops->master(input);
209 daio->rscr.ops->master(&daio->rscr); 211 daio->rscr.ops->master(&daio->rscr);
diff --git a/sound/pci/ctxfi/cthw20k2.c b/sound/pci/ctxfi/cthw20k2.c
index b6b11bfe7574..5364164674e4 100644
--- a/sound/pci/ctxfi/cthw20k2.c
+++ b/sound/pci/ctxfi/cthw20k2.c
@@ -1307,10 +1307,10 @@ static int hw_pll_init(struct hw *hw, unsigned int rsr)
1307 set_field(&pllctl, PLLCTL_B, 0); 1307 set_field(&pllctl, PLLCTL_B, 0);
1308 if (48000 == rsr) { 1308 if (48000 == rsr) {
1309 set_field(&pllctl, PLLCTL_FD, 16 - 2); 1309 set_field(&pllctl, PLLCTL_FD, 16 - 2);
1310 set_field(&pllctl, PLLCTL_RD, 1 - 1); 1310 set_field(&pllctl, PLLCTL_RD, 1 - 1); /* 3000*16/1 = 48000 */
1311 } else { /* 44100 */ 1311 } else { /* 44100 */
1312 set_field(&pllctl, PLLCTL_FD, 147 - 2); 1312 set_field(&pllctl, PLLCTL_FD, 147 - 2);
1313 set_field(&pllctl, PLLCTL_RD, 10 - 1); 1313 set_field(&pllctl, PLLCTL_RD, 10 - 1); /* 3000*147/10 = 44100 */
1314 } 1314 }
1315 hw_write_20kx(hw, PLL_CTL, pllctl); 1315 hw_write_20kx(hw, PLL_CTL, pllctl);
1316 mdelay(40); 1316 mdelay(40);
@@ -1740,6 +1740,10 @@ static int hw_is_adc_input_selected(struct hw *hw, enum ADCSRC type)
1740 return data; 1740 return data;
1741} 1741}
1742 1742
1743#define MIC_BOOST_0DB 0xCF
1744#define MIC_BOOST_STEPS_PER_DB 2
1745#define MIC_BOOST_20DB (MIC_BOOST_0DB + 20 * MIC_BOOST_STEPS_PER_DB)
1746
1743static int hw_adc_input_select(struct hw *hw, enum ADCSRC type) 1747static int hw_adc_input_select(struct hw *hw, enum ADCSRC type)
1744{ 1748{
1745 u32 data; 1749 u32 data;
@@ -1751,10 +1755,12 @@ static int hw_adc_input_select(struct hw *hw, enum ADCSRC type)
1751 hw_write_20kx(hw, GPIO_DATA, data); 1755 hw_write_20kx(hw, GPIO_DATA, data);
1752 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_ADCMC, 0x101), 1756 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_ADCMC, 0x101),
1753 MAKE_WM8775_DATA(0x101)); /* Mic-in */ 1757 MAKE_WM8775_DATA(0x101)); /* Mic-in */
1754 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCL, 0xE7), 1758 hw20k2_i2c_write(hw,
1755 MAKE_WM8775_DATA(0xE7)); /* +12dB boost */ 1759 MAKE_WM8775_ADDR(WM8775_AADCL, MIC_BOOST_20DB),
1756 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCR, 0xE7), 1760 MAKE_WM8775_DATA(MIC_BOOST_20DB)); /* +20dB */
1757 MAKE_WM8775_DATA(0xE7)); /* +12dB boost */ 1761 hw20k2_i2c_write(hw,
1762 MAKE_WM8775_ADDR(WM8775_AADCR, MIC_BOOST_20DB),
1763 MAKE_WM8775_DATA(MIC_BOOST_20DB)); /* +20dB */
1758 break; 1764 break;
1759 case ADC_LINEIN: 1765 case ADC_LINEIN:
1760 data &= ~(0x1 << 14); 1766 data &= ~(0x1 << 14);
@@ -1827,10 +1833,12 @@ static int hw_adc_init(struct hw *hw, const struct adc_conf *info)
1827 1833
1828 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_ADCMC, 0x101), 1834 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_ADCMC, 0x101),
1829 MAKE_WM8775_DATA(0x101)); /* Mic-in */ 1835 MAKE_WM8775_DATA(0x101)); /* Mic-in */
1830 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCL, 0xE7), 1836 hw20k2_i2c_write(hw,
1831 MAKE_WM8775_DATA(0xE7)); /* +12dB boost */ 1837 MAKE_WM8775_ADDR(WM8775_AADCL, MIC_BOOST_20DB),
1832 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCR, 0xE7), 1838 MAKE_WM8775_DATA(MIC_BOOST_20DB)); /* +20dB */
1833 MAKE_WM8775_DATA(0xE7)); /* +12dB boost */ 1839 hw20k2_i2c_write(hw,
1840 MAKE_WM8775_ADDR(WM8775_AADCR, MIC_BOOST_20DB),
1841 MAKE_WM8775_DATA(MIC_BOOST_20DB)); /* +20dB */
1834 } else if (mux == 2) { 1842 } else if (mux == 2) {
1835 /* Configures GPIO data to select Line-in */ 1843 /* Configures GPIO data to select Line-in */
1836 data &= ~(0x1 << 14); 1844 data &= ~(0x1 << 14);
diff --git a/sound/pci/ctxfi/ctmixer.c b/sound/pci/ctxfi/ctmixer.c
index 15c1e7271ea8..c3519ff42fbb 100644
--- a/sound/pci/ctxfi/ctmixer.c
+++ b/sound/pci/ctxfi/ctmixer.c
@@ -566,19 +566,6 @@ static int ct_spdif_get_mask(struct snd_kcontrol *kcontrol,
566 return 0; 566 return 0;
567} 567}
568 568
569static int ct_spdif_default_get(struct snd_kcontrol *kcontrol,
570 struct snd_ctl_elem_value *ucontrol)
571{
572 unsigned int status = SNDRV_PCM_DEFAULT_CON_SPDIF;
573
574 ucontrol->value.iec958.status[0] = (status >> 0) & 0xff;
575 ucontrol->value.iec958.status[1] = (status >> 8) & 0xff;
576 ucontrol->value.iec958.status[2] = (status >> 16) & 0xff;
577 ucontrol->value.iec958.status[3] = (status >> 24) & 0xff;
578
579 return 0;
580}
581
582static int ct_spdif_get(struct snd_kcontrol *kcontrol, 569static int ct_spdif_get(struct snd_kcontrol *kcontrol,
583 struct snd_ctl_elem_value *ucontrol) 570 struct snd_ctl_elem_value *ucontrol)
584{ 571{
@@ -586,6 +573,10 @@ static int ct_spdif_get(struct snd_kcontrol *kcontrol,
586 unsigned int status; 573 unsigned int status;
587 574
588 atc->spdif_out_get_status(atc, &status); 575 atc->spdif_out_get_status(atc, &status);
576
577 if (status == 0)
578 status = SNDRV_PCM_DEFAULT_CON_SPDIF;
579
589 ucontrol->value.iec958.status[0] = (status >> 0) & 0xff; 580 ucontrol->value.iec958.status[0] = (status >> 0) & 0xff;
590 ucontrol->value.iec958.status[1] = (status >> 8) & 0xff; 581 ucontrol->value.iec958.status[1] = (status >> 8) & 0xff;
591 ucontrol->value.iec958.status[2] = (status >> 16) & 0xff; 582 ucontrol->value.iec958.status[2] = (status >> 16) & 0xff;
@@ -629,7 +620,7 @@ static struct snd_kcontrol_new iec958_default_ctl = {
629 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT), 620 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
630 .count = 1, 621 .count = 1,
631 .info = ct_spdif_info, 622 .info = ct_spdif_info,
632 .get = ct_spdif_default_get, 623 .get = ct_spdif_get,
633 .put = ct_spdif_put, 624 .put = ct_spdif_put,
634 .private_value = MIXER_IEC958_DEFAULT 625 .private_value = MIXER_IEC958_DEFAULT
635}; 626};
diff --git a/sound/pci/ctxfi/ctvmem.c b/sound/pci/ctxfi/ctvmem.c
index 65da6e466f80..b78f3fc3c33c 100644
--- a/sound/pci/ctxfi/ctvmem.c
+++ b/sound/pci/ctxfi/ctvmem.c
@@ -52,8 +52,7 @@ get_vm_block(struct ct_vm *vm, unsigned int size)
52 52
53 if (entry->size == size) { 53 if (entry->size == size) {
54 /* Move the vm node from unused list to used list directly */ 54 /* Move the vm node from unused list to used list directly */
55 list_del(&entry->list); 55 list_move(&entry->list, &vm->used);
56 list_add(&entry->list, &vm->used);
57 vm->size -= size; 56 vm->size -= size;
58 block = entry; 57 block = entry;
59 goto out; 58 goto out;
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
index 66c7fb3ced3e..5e619a84da06 100644
--- a/sound/pci/emu10k1/emu10k1_main.c
+++ b/sound/pci/emu10k1/emu10k1_main.c
@@ -926,7 +926,7 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu)
926 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_IN, 0x19); 926 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_IN, 0x19);
927 /* Unknown. */ 927 /* Unknown. */
928 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_OUT, 0x0c); 928 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_OUT, 0x0c);
929 /* IRQ Enable: Alll on */ 929 /* IRQ Enable: All on */
930 /* snd_emu1010_fpga_write(emu, 0x09, 0x0f ); */ 930 /* snd_emu1010_fpga_write(emu, 0x09, 0x0f ); */
931 /* IRQ Enable: All off */ 931 /* IRQ Enable: All off */
932 snd_emu1010_fpga_write(emu, EMU_HANA_IRQ_ENABLE, 0x00); 932 snd_emu1010_fpga_write(emu, EMU_HANA_IRQ_ENABLE, 0x00);
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index ae5c5d5e4b7c..2c79e96d0324 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -29,6 +29,7 @@
29#include <sound/asoundef.h> 29#include <sound/asoundef.h>
30#include <sound/tlv.h> 30#include <sound/tlv.h>
31#include <sound/initval.h> 31#include <sound/initval.h>
32#include <sound/jack.h>
32#include "hda_local.h" 33#include "hda_local.h"
33#include "hda_beep.h" 34#include "hda_beep.h"
34#include <sound/hda_hwdep.h> 35#include <sound/hda_hwdep.h>
@@ -4959,5 +4960,109 @@ void snd_print_pcm_bits(int pcm, char *buf, int buflen)
4959} 4960}
4960EXPORT_SYMBOL_HDA(snd_print_pcm_bits); 4961EXPORT_SYMBOL_HDA(snd_print_pcm_bits);
4961 4962
4963#ifdef CONFIG_SND_HDA_INPUT_JACK
4964/*
4965 * Input-jack notification support
4966 */
4967struct hda_jack_item {
4968 hda_nid_t nid;
4969 int type;
4970 struct snd_jack *jack;
4971};
4972
4973static const char *get_jack_default_name(struct hda_codec *codec, hda_nid_t nid,
4974 int type)
4975{
4976 switch (type) {
4977 case SND_JACK_HEADPHONE:
4978 return "Headphone";
4979 case SND_JACK_MICROPHONE:
4980 return "Mic";
4981 case SND_JACK_LINEOUT:
4982 return "Line-out";
4983 case SND_JACK_HEADSET:
4984 return "Headset";
4985 default:
4986 return "Misc";
4987 }
4988}
4989
4990static void hda_free_jack_priv(struct snd_jack *jack)
4991{
4992 struct hda_jack_item *jacks = jack->private_data;
4993 jacks->nid = 0;
4994 jacks->jack = NULL;
4995}
4996
4997int snd_hda_input_jack_add(struct hda_codec *codec, hda_nid_t nid, int type,
4998 const char *name)
4999{
5000 struct hda_jack_item *jack;
5001 int err;
5002
5003 snd_array_init(&codec->jacks, sizeof(*jack), 32);
5004 jack = snd_array_new(&codec->jacks);
5005 if (!jack)
5006 return -ENOMEM;
5007
5008 jack->nid = nid;
5009 jack->type = type;
5010 if (!name)
5011 name = get_jack_default_name(codec, nid, type);
5012 err = snd_jack_new(codec->bus->card, name, type, &jack->jack);
5013 if (err < 0) {
5014 jack->nid = 0;
5015 return err;
5016 }
5017 jack->jack->private_data = jack;
5018 jack->jack->private_free = hda_free_jack_priv;
5019 return 0;
5020}
5021EXPORT_SYMBOL_HDA(snd_hda_input_jack_add);
5022
5023void snd_hda_input_jack_report(struct hda_codec *codec, hda_nid_t nid)
5024{
5025 struct hda_jack_item *jacks = codec->jacks.list;
5026 int i;
5027
5028 if (!jacks)
5029 return;
5030
5031 for (i = 0; i < codec->jacks.used; i++, jacks++) {
5032 unsigned int pin_ctl;
5033 unsigned int present;
5034 int type;
5035
5036 if (jacks->nid != nid)
5037 continue;
5038 present = snd_hda_jack_detect(codec, nid);
5039 type = jacks->type;
5040 if (type == (SND_JACK_HEADPHONE | SND_JACK_LINEOUT)) {
5041 pin_ctl = snd_hda_codec_read(codec, nid, 0,
5042 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
5043 type = (pin_ctl & AC_PINCTL_HP_EN) ?
5044 SND_JACK_HEADPHONE : SND_JACK_LINEOUT;
5045 }
5046 snd_jack_report(jacks->jack, present ? type : 0);
5047 }
5048}
5049EXPORT_SYMBOL_HDA(snd_hda_input_jack_report);
5050
5051/* free jack instances manually when clearing/reconfiguring */
5052void snd_hda_input_jack_free(struct hda_codec *codec)
5053{
5054 if (!codec->bus->shutdown && codec->jacks.list) {
5055 struct hda_jack_item *jacks = codec->jacks.list;
5056 int i;
5057 for (i = 0; i < codec->jacks.used; i++, jacks++) {
5058 if (jacks->jack)
5059 snd_device_free(codec->bus->card, jacks->jack);
5060 }
5061 }
5062 snd_array_free(&codec->jacks);
5063}
5064EXPORT_SYMBOL_HDA(snd_hda_input_jack_free);
5065#endif /* CONFIG_SND_HDA_INPUT_JACK */
5066
4962MODULE_DESCRIPTION("HDA codec core"); 5067MODULE_DESCRIPTION("HDA codec core");
4963MODULE_LICENSE("GPL"); 5068MODULE_LICENSE("GPL");
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index fdf8d44f8b6b..e46d5420a9f2 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -866,6 +866,11 @@ struct hda_codec {
866 /* codec-specific additional proc output */ 866 /* codec-specific additional proc output */
867 void (*proc_widget_hook)(struct snd_info_buffer *buffer, 867 void (*proc_widget_hook)(struct snd_info_buffer *buffer,
868 struct hda_codec *codec, hda_nid_t nid); 868 struct hda_codec *codec, hda_nid_t nid);
869
870#ifdef CONFIG_SND_HDA_INPUT_JACK
871 /* jack detection */
872 struct snd_array jacks;
873#endif
869}; 874};
870 875
871/* direction */ 876/* direction */
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index fcedad9a5fef..70a9d32f0e96 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -1052,9 +1052,12 @@ static void azx_init_pci(struct azx *chip)
1052 /* Clear bits 0-2 of PCI register TCSEL (at offset 0x44) 1052 /* Clear bits 0-2 of PCI register TCSEL (at offset 0x44)
1053 * TCSEL == Traffic Class Select Register, which sets PCI express QOS 1053 * TCSEL == Traffic Class Select Register, which sets PCI express QOS
1054 * Ensuring these bits are 0 clears playback static on some HD Audio 1054 * Ensuring these bits are 0 clears playback static on some HD Audio
1055 * codecs 1055 * codecs.
1056 * The PCI register TCSEL is defined in the Intel manuals.
1056 */ 1057 */
1057 update_pci_byte(chip->pci, ICH6_PCIREG_TCSEL, 0x07, 0); 1058 if (chip->driver_type != AZX_DRIVER_ATI &&
1059 chip->driver_type != AZX_DRIVER_ATIHDMI)
1060 update_pci_byte(chip->pci, ICH6_PCIREG_TCSEL, 0x07, 0);
1058 1061
1059 switch (chip->driver_type) { 1062 switch (chip->driver_type) {
1060 case AZX_DRIVER_ATI: 1063 case AZX_DRIVER_ATI:
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 3ab5e7a303db..ff5e2ac2239a 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -656,4 +656,28 @@ static inline void snd_hda_eld_proc_free(struct hda_codec *codec,
656#define SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE 80 656#define SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE 80
657void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen); 657void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen);
658 658
659/*
660 * Input-jack notification support
661 */
662#ifdef CONFIG_SND_HDA_INPUT_JACK
663int snd_hda_input_jack_add(struct hda_codec *codec, hda_nid_t nid, int type,
664 const char *name);
665void snd_hda_input_jack_report(struct hda_codec *codec, hda_nid_t nid);
666void snd_hda_input_jack_free(struct hda_codec *codec);
667#else /* CONFIG_SND_HDA_INPUT_JACK */
668static inline int snd_hda_input_jack_add(struct hda_codec *codec,
669 hda_nid_t nid, int type,
670 const char *name)
671{
672 return 0;
673}
674static inline void snd_hda_input_jack_report(struct hda_codec *codec,
675 hda_nid_t nid)
676{
677}
678static inline void snd_hda_input_jack_free(struct hda_codec *codec)
679{
680}
681#endif /* CONFIG_SND_HDA_INPUT_JACK */
682
659#endif /* __SOUND_HDA_LOCAL_H */ 683#endif /* __SOUND_HDA_LOCAL_H */
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 8dabab798689..734c6ee55d8a 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -30,10 +30,10 @@
30#include "hda_beep.h" 30#include "hda_beep.h"
31 31
32struct ad198x_spec { 32struct ad198x_spec {
33 struct snd_kcontrol_new *mixers[5]; 33 struct snd_kcontrol_new *mixers[6];
34 int num_mixers; 34 int num_mixers;
35 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */ 35 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
36 const struct hda_verb *init_verbs[5]; /* initialization verbs 36 const struct hda_verb *init_verbs[6]; /* initialization verbs
37 * don't forget NULL termination! 37 * don't forget NULL termination!
38 */ 38 */
39 unsigned int num_init_verbs; 39 unsigned int num_init_verbs;
@@ -331,36 +331,11 @@ static int ad198x_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
331 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); 331 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
332} 332}
333 333
334static int ad198x_alt_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
335 struct hda_codec *codec,
336 unsigned int stream_tag,
337 unsigned int format,
338 struct snd_pcm_substream *substream)
339{
340 struct ad198x_spec *spec = codec->spec;
341 snd_hda_codec_setup_stream(codec, spec->alt_dac_nid[0], stream_tag,
342 0, format);
343 return 0;
344}
345
346static int ad198x_alt_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
347 struct hda_codec *codec,
348 struct snd_pcm_substream *substream)
349{
350 struct ad198x_spec *spec = codec->spec;
351 snd_hda_codec_cleanup_stream(codec, spec->alt_dac_nid[0]);
352 return 0;
353}
354
355static struct hda_pcm_stream ad198x_pcm_analog_alt_playback = { 334static struct hda_pcm_stream ad198x_pcm_analog_alt_playback = {
356 .substreams = 1, 335 .substreams = 1,
357 .channels_min = 2, 336 .channels_min = 2,
358 .channels_max = 2, 337 .channels_max = 2,
359 /* NID is set in ad198x_build_pcms */ 338 /* NID is set in ad198x_build_pcms */
360 .ops = {
361 .prepare = ad198x_alt_playback_pcm_prepare,
362 .cleanup = ad198x_alt_playback_pcm_cleanup
363 },
364}; 339};
365 340
366/* 341/*
@@ -2239,29 +2214,6 @@ static struct snd_kcontrol_new ad1988_6stack_mixers2[] = {
2239static struct snd_kcontrol_new ad1988_6stack_fp_mixers[] = { 2214static struct snd_kcontrol_new ad1988_6stack_fp_mixers[] = {
2240 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 2215 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
2241 2216
2242 HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT),
2243 HDA_BIND_MUTE("Surround Playback Switch", 0x2a, 2, HDA_INPUT),
2244 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x27, 1, 2, HDA_INPUT),
2245 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x27, 2, 2, HDA_INPUT),
2246 HDA_BIND_MUTE("Side Playback Switch", 0x28, 2, HDA_INPUT),
2247 HDA_BIND_MUTE("Headphone Playback Switch", 0x22, 2, HDA_INPUT),
2248 HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
2249
2250 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT),
2251 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT),
2252 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x0, HDA_INPUT),
2253 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x0, HDA_INPUT),
2254 HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT),
2255 HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT),
2256 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x4, HDA_INPUT),
2257 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x4, HDA_INPUT),
2258
2259 HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
2260 HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
2261
2262 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT),
2263 HDA_CODEC_VOLUME("Mic Boost Volume", 0x3c, 0x0, HDA_OUTPUT),
2264
2265 { } /* end */ 2217 { } /* end */
2266}; 2218};
2267 2219
@@ -2545,11 +2497,6 @@ static struct hda_verb ad1988_6stack_init_verbs[] = {
2545}; 2497};
2546 2498
2547static struct hda_verb ad1988_6stack_fp_init_verbs[] = { 2499static struct hda_verb ad1988_6stack_fp_init_verbs[] = {
2548 /* Front, Surround, CLFE, side DAC; unmute as default */
2549 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2550 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2551 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2552 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2553 /* Headphone; unmute as default */ 2500 /* Headphone; unmute as default */
2554 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2501 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2555 /* Port-A front headphon path */ 2502 /* Port-A front headphon path */
@@ -2558,50 +2505,6 @@ static struct hda_verb ad1988_6stack_fp_init_verbs[] = {
2558 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2505 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2559 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2506 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2560 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2507 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2561 /* Port-D line-out path */
2562 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2563 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2564 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2565 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2566 /* Port-F surround path */
2567 {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2568 {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2569 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2570 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2571 /* Port-G CLFE path */
2572 {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2573 {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2574 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2575 {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2576 /* Port-H side path */
2577 {0x28, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2578 {0x28, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2579 {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2580 {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2581 /* Mono out path */
2582 {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
2583 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2584 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2585 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2586 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
2587 /* Port-B front mic-in path */
2588 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2589 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2590 {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2591 /* Port-C line-in path */
2592 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2593 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2594 {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2595 {0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
2596 /* Port-E mic-in path */
2597 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2598 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2599 {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2600 {0x34, AC_VERB_SET_CONNECT_SEL, 0x0},
2601 /* Analog CD Input */
2602 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2603 /* Analog Mix output amp */
2604 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
2605 2508
2606 { } 2509 { }
2607}; 2510};
@@ -3316,20 +3219,20 @@ static int patch_ad1988(struct hda_codec *codec)
3316 spec->mixers[0] = ad1988_6stack_mixers1_rev2; 3219 spec->mixers[0] = ad1988_6stack_mixers1_rev2;
3317 else 3220 else
3318 spec->mixers[0] = ad1988_6stack_mixers1; 3221 spec->mixers[0] = ad1988_6stack_mixers1;
3222 spec->mixers[1] = ad1988_6stack_mixers2;
3223 spec->num_init_verbs = 1;
3224 spec->init_verbs[0] = ad1988_6stack_init_verbs;
3319 if (board_config == AD1988_6STACK_DIG_FP) { 3225 if (board_config == AD1988_6STACK_DIG_FP) {
3320 spec->mixers[1] = ad1988_6stack_fp_mixers; 3226 spec->num_mixers++;
3227 spec->mixers[2] = ad1988_6stack_fp_mixers;
3228 spec->num_init_verbs++;
3229 spec->init_verbs[1] = ad1988_6stack_fp_init_verbs;
3321 spec->slave_vols = ad1988_6stack_fp_slave_vols; 3230 spec->slave_vols = ad1988_6stack_fp_slave_vols;
3322 spec->slave_sws = ad1988_6stack_fp_slave_sws; 3231 spec->slave_sws = ad1988_6stack_fp_slave_sws;
3323 spec->alt_dac_nid = ad1988_alt_dac_nid; 3232 spec->alt_dac_nid = ad1988_alt_dac_nid;
3324 spec->stream_analog_alt_playback = 3233 spec->stream_analog_alt_playback =
3325 &ad198x_pcm_analog_alt_playback; 3234 &ad198x_pcm_analog_alt_playback;
3326 } else 3235 }
3327 spec->mixers[1] = ad1988_6stack_mixers2;
3328 spec->num_init_verbs = 1;
3329 if (board_config == AD1988_6STACK_DIG_FP)
3330 spec->init_verbs[0] = ad1988_6stack_fp_init_verbs;
3331 else
3332 spec->init_verbs[0] = ad1988_6stack_init_verbs;
3333 if ((board_config == AD1988_6STACK_DIG) || 3236 if ((board_config == AD1988_6STACK_DIG) ||
3334 (board_config == AD1988_6STACK_DIG_FP)) { 3237 (board_config == AD1988_6STACK_DIG_FP)) {
3335 spec->multiout.dig_out_nid = AD1988_SPDIF_OUT; 3238 spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 4d5004e693f0..d08cf31596f3 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -49,14 +49,6 @@
49#define AUTO_MIC_PORTB (1 << 1) 49#define AUTO_MIC_PORTB (1 << 1)
50#define AUTO_MIC_PORTC (1 << 2) 50#define AUTO_MIC_PORTC (1 << 2)
51 51
52struct conexant_jack {
53
54 hda_nid_t nid;
55 int type;
56 struct snd_jack *jack;
57
58};
59
60struct pin_dac_pair { 52struct pin_dac_pair {
61 hda_nid_t pin; 53 hda_nid_t pin;
62 hda_nid_t dac; 54 hda_nid_t dac;
@@ -111,9 +103,6 @@ struct conexant_spec {
111 103
112 unsigned int spdif_route; 104 unsigned int spdif_route;
113 105
114 /* jack detection */
115 struct snd_array jacks;
116
117 /* dynamic controls, init_verbs and input_mux */ 106 /* dynamic controls, init_verbs and input_mux */
118 struct auto_pin_cfg autocfg; 107 struct auto_pin_cfg autocfg;
119 struct hda_input_mux private_imux; 108 struct hda_input_mux private_imux;
@@ -393,71 +382,9 @@ static int conexant_mux_enum_put(struct snd_kcontrol *kcontrol,
393 &spec->cur_mux[adc_idx]); 382 &spec->cur_mux[adc_idx]);
394} 383}
395 384
396#ifdef CONFIG_SND_HDA_INPUT_JACK
397static void conexant_free_jack_priv(struct snd_jack *jack)
398{
399 struct conexant_jack *jacks = jack->private_data;
400 jacks->nid = 0;
401 jacks->jack = NULL;
402}
403
404static int conexant_add_jack(struct hda_codec *codec,
405 hda_nid_t nid, int type)
406{
407 struct conexant_spec *spec;
408 struct conexant_jack *jack;
409 const char *name;
410 int i, err;
411
412 spec = codec->spec;
413 snd_array_init(&spec->jacks, sizeof(*jack), 32);
414
415 jack = spec->jacks.list;
416 for (i = 0; i < spec->jacks.used; i++, jack++)
417 if (jack->nid == nid)
418 return 0 ; /* already present */
419
420 jack = snd_array_new(&spec->jacks);
421 name = (type == SND_JACK_HEADPHONE) ? "Headphone" : "Mic" ;
422
423 if (!jack)
424 return -ENOMEM;
425
426 jack->nid = nid;
427 jack->type = type;
428
429 err = snd_jack_new(codec->bus->card, name, type, &jack->jack);
430 if (err < 0)
431 return err;
432 jack->jack->private_data = jack;
433 jack->jack->private_free = conexant_free_jack_priv;
434 return 0;
435}
436
437static void conexant_report_jack(struct hda_codec *codec, hda_nid_t nid)
438{
439 struct conexant_spec *spec = codec->spec;
440 struct conexant_jack *jacks = spec->jacks.list;
441
442 if (jacks) {
443 int i;
444 for (i = 0; i < spec->jacks.used; i++) {
445 if (jacks->nid == nid) {
446 unsigned int present;
447 present = snd_hda_jack_detect(codec, nid);
448
449 present = (present) ? jacks->type : 0 ;
450
451 snd_jack_report(jacks->jack,
452 present);
453 }
454 jacks++;
455 }
456 }
457}
458
459static int conexant_init_jacks(struct hda_codec *codec) 385static int conexant_init_jacks(struct hda_codec *codec)
460{ 386{
387#ifdef CONFIG_SND_HDA_INPUT_JACK
461 struct conexant_spec *spec = codec->spec; 388 struct conexant_spec *spec = codec->spec;
462 int i; 389 int i;
463 390
@@ -469,15 +396,15 @@ static int conexant_init_jacks(struct hda_codec *codec)
469 int err = 0; 396 int err = 0;
470 switch (hv->param ^ AC_USRSP_EN) { 397 switch (hv->param ^ AC_USRSP_EN) {
471 case CONEXANT_HP_EVENT: 398 case CONEXANT_HP_EVENT:
472 err = conexant_add_jack(codec, hv->nid, 399 err = snd_hda_input_jack_add(codec, hv->nid,
473 SND_JACK_HEADPHONE); 400 SND_JACK_HEADPHONE, NULL);
474 conexant_report_jack(codec, hv->nid); 401 snd_hda_input_jack_report(codec, hv->nid);
475 break; 402 break;
476 case CXT5051_PORTC_EVENT: 403 case CXT5051_PORTC_EVENT:
477 case CONEXANT_MIC_EVENT: 404 case CONEXANT_MIC_EVENT:
478 err = conexant_add_jack(codec, hv->nid, 405 err = snd_hda_input_jack_add(codec, hv->nid,
479 SND_JACK_MICROPHONE); 406 SND_JACK_MICROPHONE, NULL);
480 conexant_report_jack(codec, hv->nid); 407 snd_hda_input_jack_report(codec, hv->nid);
481 break; 408 break;
482 } 409 }
483 if (err < 0) 410 if (err < 0)
@@ -485,19 +412,9 @@ static int conexant_init_jacks(struct hda_codec *codec)
485 ++hv; 412 ++hv;
486 } 413 }
487 } 414 }
488 return 0; 415#endif /* CONFIG_SND_HDA_INPUT_JACK */
489
490}
491#else
492static inline void conexant_report_jack(struct hda_codec *codec, hda_nid_t nid)
493{
494}
495
496static inline int conexant_init_jacks(struct hda_codec *codec)
497{
498 return 0; 416 return 0;
499} 417}
500#endif
501 418
502static int conexant_init(struct hda_codec *codec) 419static int conexant_init(struct hda_codec *codec)
503{ 420{
@@ -511,18 +428,7 @@ static int conexant_init(struct hda_codec *codec)
511 428
512static void conexant_free(struct hda_codec *codec) 429static void conexant_free(struct hda_codec *codec)
513{ 430{
514#ifdef CONFIG_SND_HDA_INPUT_JACK 431 snd_hda_input_jack_free(codec);
515 struct conexant_spec *spec = codec->spec;
516 if (spec->jacks.list) {
517 struct conexant_jack *jacks = spec->jacks.list;
518 int i;
519 for (i = 0; i < spec->jacks.used; i++, jacks++) {
520 if (jacks->jack)
521 snd_device_free(codec->bus->card, jacks->jack);
522 }
523 snd_array_free(&spec->jacks);
524 }
525#endif
526 snd_hda_detach_beep_device(codec); 432 snd_hda_detach_beep_device(codec);
527 kfree(codec->spec); 433 kfree(codec->spec);
528} 434}
@@ -1787,7 +1693,7 @@ static void cxt5051_hp_unsol_event(struct hda_codec *codec,
1787 cxt5051_portc_automic(codec); 1693 cxt5051_portc_automic(codec);
1788 break; 1694 break;
1789 } 1695 }
1790 conexant_report_jack(codec, nid); 1696 snd_hda_input_jack_report(codec, nid);
1791} 1697}
1792 1698
1793static struct snd_kcontrol_new cxt5051_playback_mixers[] = { 1699static struct snd_kcontrol_new cxt5051_playback_mixers[] = {
@@ -1959,10 +1865,8 @@ static void cxt5051_init_mic_port(struct hda_codec *codec, hda_nid_t nid,
1959 snd_hda_codec_write(codec, nid, 0, 1865 snd_hda_codec_write(codec, nid, 0,
1960 AC_VERB_SET_UNSOLICITED_ENABLE, 1866 AC_VERB_SET_UNSOLICITED_ENABLE,
1961 AC_USRSP_EN | event); 1867 AC_USRSP_EN | event);
1962#ifdef CONFIG_SND_HDA_INPUT_JACK 1868 snd_hda_input_jack_add(codec, nid, SND_JACK_MICROPHONE, NULL);
1963 conexant_add_jack(codec, nid, SND_JACK_MICROPHONE); 1869 snd_hda_input_jack_report(codec, nid);
1964 conexant_report_jack(codec, nid);
1965#endif
1966} 1870}
1967 1871
1968static struct hda_verb cxt5051_ideapad_init_verbs[] = { 1872static struct hda_verb cxt5051_ideapad_init_verbs[] = {
@@ -3477,11 +3381,11 @@ static void cx_auto_unsol_event(struct hda_codec *codec, unsigned int res)
3477 switch (res >> 26) { 3381 switch (res >> 26) {
3478 case CONEXANT_HP_EVENT: 3382 case CONEXANT_HP_EVENT:
3479 cx_auto_hp_automute(codec); 3383 cx_auto_hp_automute(codec);
3480 conexant_report_jack(codec, nid); 3384 snd_hda_input_jack_report(codec, nid);
3481 break; 3385 break;
3482 case CONEXANT_MIC_EVENT: 3386 case CONEXANT_MIC_EVENT:
3483 cx_auto_automic(codec); 3387 cx_auto_automic(codec);
3484 conexant_report_jack(codec, nid); 3388 snd_hda_input_jack_report(codec, nid);
3485 break; 3389 break;
3486 } 3390 }
3487} 3391}
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index ec0fa2dd0a27..251773e45f61 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -110,6 +110,12 @@ struct dp_audio_infoframe {
110 u8 LFEPBL01_LSV36_DM_INH7; 110 u8 LFEPBL01_LSV36_DM_INH7;
111}; 111};
112 112
113union audio_infoframe {
114 struct hdmi_audio_infoframe hdmi;
115 struct dp_audio_infoframe dp;
116 u8 bytes[0];
117};
118
113/* 119/*
114 * CEA speaker placement: 120 * CEA speaker placement:
115 * 121 *
@@ -620,8 +626,7 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid,
620 int channels = substream->runtime->channels; 626 int channels = substream->runtime->channels;
621 int ca; 627 int ca;
622 int i; 628 int i;
623 u8 ai[max(sizeof(struct hdmi_audio_infoframe), 629 union audio_infoframe ai;
624 sizeof(struct dp_audio_infoframe))];
625 630
626 ca = hdmi_channel_allocation(codec, nid, channels); 631 ca = hdmi_channel_allocation(codec, nid, channels);
627 632
@@ -633,11 +638,10 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid,
633 638
634 pin_nid = spec->pin[i]; 639 pin_nid = spec->pin[i];
635 640
636 memset(ai, 0, sizeof(ai)); 641 memset(&ai, 0, sizeof(ai));
637 if (spec->sink_eld[i].conn_type == 0) { /* HDMI */ 642 if (spec->sink_eld[i].conn_type == 0) { /* HDMI */
638 struct hdmi_audio_infoframe *hdmi_ai; 643 struct hdmi_audio_infoframe *hdmi_ai = &ai.hdmi;
639 644
640 hdmi_ai = (struct hdmi_audio_infoframe *)ai;
641 hdmi_ai->type = 0x84; 645 hdmi_ai->type = 0x84;
642 hdmi_ai->ver = 0x01; 646 hdmi_ai->ver = 0x01;
643 hdmi_ai->len = 0x0a; 647 hdmi_ai->len = 0x0a;
@@ -645,9 +649,8 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid,
645 hdmi_ai->CA = ca; 649 hdmi_ai->CA = ca;
646 hdmi_checksum_audio_infoframe(hdmi_ai); 650 hdmi_checksum_audio_infoframe(hdmi_ai);
647 } else if (spec->sink_eld[i].conn_type == 1) { /* DisplayPort */ 651 } else if (spec->sink_eld[i].conn_type == 1) { /* DisplayPort */
648 struct dp_audio_infoframe *dp_ai; 652 struct dp_audio_infoframe *dp_ai = &ai.dp;
649 653
650 dp_ai = (struct dp_audio_infoframe *)ai;
651 dp_ai->type = 0x84; 654 dp_ai->type = 0x84;
652 dp_ai->len = 0x1b; 655 dp_ai->len = 0x1b;
653 dp_ai->ver = 0x11 << 2; 656 dp_ai->ver = 0x11 << 2;
@@ -664,7 +667,8 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid,
664 * sizeof(*dp_ai) to avoid partial match/update problems when 667 * sizeof(*dp_ai) to avoid partial match/update problems when
665 * the user switches between HDMI/DP monitors. 668 * the user switches between HDMI/DP monitors.
666 */ 669 */
667 if (!hdmi_infoframe_uptodate(codec, pin_nid, ai, sizeof(ai))) { 670 if (!hdmi_infoframe_uptodate(codec, pin_nid, ai.bytes,
671 sizeof(ai))) {
668 snd_printdd("hdmi_setup_audio_infoframe: " 672 snd_printdd("hdmi_setup_audio_infoframe: "
669 "cvt=%d pin=%d channels=%d\n", 673 "cvt=%d pin=%d channels=%d\n",
670 nid, pin_nid, 674 nid, pin_nid,
@@ -672,7 +676,7 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid,
672 hdmi_setup_channel_mapping(codec, pin_nid, ca); 676 hdmi_setup_channel_mapping(codec, pin_nid, ca);
673 hdmi_stop_infoframe_trans(codec, pin_nid); 677 hdmi_stop_infoframe_trans(codec, pin_nid);
674 hdmi_fill_audio_infoframe(codec, pin_nid, 678 hdmi_fill_audio_infoframe(codec, pin_nid,
675 ai, sizeof(ai)); 679 ai.bytes, sizeof(ai));
676 hdmi_start_infoframe_trans(codec, pin_nid); 680 hdmi_start_infoframe_trans(codec, pin_nid);
677 } 681 }
678 } 682 }
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 4261bb8eec1d..f1a03f223495 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -282,12 +282,6 @@ struct alc_mic_route {
282 unsigned char amix_idx; 282 unsigned char amix_idx;
283}; 283};
284 284
285struct alc_jack {
286 hda_nid_t nid;
287 int type;
288 struct snd_jack *jack;
289};
290
291#define MUX_IDX_UNDEF ((unsigned char)-1) 285#define MUX_IDX_UNDEF ((unsigned char)-1)
292 286
293struct alc_customize_define { 287struct alc_customize_define {
@@ -366,9 +360,6 @@ struct alc_spec {
366 /* PCM information */ 360 /* PCM information */
367 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */ 361 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
368 362
369 /* jack detection */
370 struct snd_array jacks;
371
372 /* dynamic controls, init_verbs and input_mux */ 363 /* dynamic controls, init_verbs and input_mux */
373 struct auto_pin_cfg autocfg; 364 struct auto_pin_cfg autocfg;
374 struct alc_customize_define cdefine; 365 struct alc_customize_define cdefine;
@@ -394,6 +385,7 @@ struct alc_spec {
394 /* other flags */ 385 /* other flags */
395 unsigned int no_analog :1; /* digital I/O only */ 386 unsigned int no_analog :1; /* digital I/O only */
396 unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */ 387 unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */
388 unsigned int single_input_src:1;
397 int init_amp; 389 int init_amp;
398 int codec_variant; /* flag for other variants */ 390 int codec_variant; /* flag for other variants */
399 391
@@ -1032,94 +1024,32 @@ static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
1032 alc_fix_pll(codec); 1024 alc_fix_pll(codec);
1033} 1025}
1034 1026
1035#ifdef CONFIG_SND_HDA_INPUT_JACK
1036static void alc_free_jack_priv(struct snd_jack *jack)
1037{
1038 struct alc_jack *jacks = jack->private_data;
1039 jacks->nid = 0;
1040 jacks->jack = NULL;
1041}
1042
1043static int alc_add_jack(struct hda_codec *codec,
1044 hda_nid_t nid, int type)
1045{
1046 struct alc_spec *spec;
1047 struct alc_jack *jack;
1048 const char *name;
1049 int err;
1050
1051 spec = codec->spec;
1052 snd_array_init(&spec->jacks, sizeof(*jack), 32);
1053 jack = snd_array_new(&spec->jacks);
1054 if (!jack)
1055 return -ENOMEM;
1056
1057 jack->nid = nid;
1058 jack->type = type;
1059 name = (type == SND_JACK_HEADPHONE) ? "Headphone" : "Mic" ;
1060
1061 err = snd_jack_new(codec->bus->card, name, type, &jack->jack);
1062 if (err < 0)
1063 return err;
1064 jack->jack->private_data = jack;
1065 jack->jack->private_free = alc_free_jack_priv;
1066 return 0;
1067}
1068
1069static void alc_report_jack(struct hda_codec *codec, hda_nid_t nid)
1070{
1071 struct alc_spec *spec = codec->spec;
1072 struct alc_jack *jacks = spec->jacks.list;
1073
1074 if (jacks) {
1075 int i;
1076 for (i = 0; i < spec->jacks.used; i++) {
1077 if (jacks->nid == nid) {
1078 unsigned int present;
1079 present = snd_hda_jack_detect(codec, nid);
1080
1081 present = (present) ? jacks->type : 0;
1082
1083 snd_jack_report(jacks->jack, present);
1084 }
1085 jacks++;
1086 }
1087 }
1088}
1089
1090static int alc_init_jacks(struct hda_codec *codec) 1027static int alc_init_jacks(struct hda_codec *codec)
1091{ 1028{
1029#ifdef CONFIG_SND_HDA_INPUT_JACK
1092 struct alc_spec *spec = codec->spec; 1030 struct alc_spec *spec = codec->spec;
1093 int err; 1031 int err;
1094 unsigned int hp_nid = spec->autocfg.hp_pins[0]; 1032 unsigned int hp_nid = spec->autocfg.hp_pins[0];
1095 unsigned int mic_nid = spec->ext_mic.pin; 1033 unsigned int mic_nid = spec->ext_mic.pin;
1096 1034
1097 if (hp_nid) { 1035 if (hp_nid) {
1098 err = alc_add_jack(codec, hp_nid, SND_JACK_HEADPHONE); 1036 err = snd_hda_input_jack_add(codec, hp_nid,
1037 SND_JACK_HEADPHONE, NULL);
1099 if (err < 0) 1038 if (err < 0)
1100 return err; 1039 return err;
1101 alc_report_jack(codec, hp_nid); 1040 snd_hda_input_jack_report(codec, hp_nid);
1102 } 1041 }
1103 1042
1104 if (mic_nid) { 1043 if (mic_nid) {
1105 err = alc_add_jack(codec, mic_nid, SND_JACK_MICROPHONE); 1044 err = snd_hda_input_jack_add(codec, mic_nid,
1045 SND_JACK_MICROPHONE, NULL);
1106 if (err < 0) 1046 if (err < 0)
1107 return err; 1047 return err;
1108 alc_report_jack(codec, mic_nid); 1048 snd_hda_input_jack_report(codec, mic_nid);
1109 } 1049 }
1110 1050#endif /* CONFIG_SND_HDA_INPUT_JACK */
1111 return 0;
1112}
1113#else
1114static inline void alc_report_jack(struct hda_codec *codec, hda_nid_t nid)
1115{
1116}
1117
1118static inline int alc_init_jacks(struct hda_codec *codec)
1119{
1120 return 0; 1051 return 0;
1121} 1052}
1122#endif
1123 1053
1124static void alc_automute_speaker(struct hda_codec *codec, int pinctl) 1054static void alc_automute_speaker(struct hda_codec *codec, int pinctl)
1125{ 1055{
@@ -1133,7 +1063,7 @@ static void alc_automute_speaker(struct hda_codec *codec, int pinctl)
1133 nid = spec->autocfg.hp_pins[i]; 1063 nid = spec->autocfg.hp_pins[i];
1134 if (!nid) 1064 if (!nid)
1135 break; 1065 break;
1136 alc_report_jack(codec, nid); 1066 snd_hda_input_jack_report(codec, nid);
1137 spec->jack_present |= snd_hda_jack_detect(codec, nid); 1067 spec->jack_present |= snd_hda_jack_detect(codec, nid);
1138 } 1068 }
1139 1069
@@ -1240,7 +1170,7 @@ static void alc_mic_automute(struct hda_codec *codec)
1240 AC_VERB_SET_CONNECT_SEL, 1170 AC_VERB_SET_CONNECT_SEL,
1241 alive->mux_idx); 1171 alive->mux_idx);
1242 } 1172 }
1243 alc_report_jack(codec, spec->ext_mic.pin); 1173 snd_hda_input_jack_report(codec, spec->ext_mic.pin);
1244 1174
1245 /* FIXME: analog mixer */ 1175 /* FIXME: analog mixer */
1246} 1176}
@@ -2292,13 +2222,13 @@ static struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = {
2292 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2222 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2293 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2223 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2294 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 2224 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2295 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0f, 2, 0x0, 2225 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2296 HDA_OUTPUT), 2226 HDA_OUTPUT),
2297 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0f, 2, 2, HDA_INPUT), 2227 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2298 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0f, 1, 0x0, HDA_OUTPUT), 2228 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2299 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0f, 1, 2, HDA_INPUT), 2229 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2300 HDA_CODEC_VOLUME("Side Playback Volume", 0x0e, 0x0, HDA_OUTPUT), 2230 HDA_CODEC_VOLUME_MONO("Internal LFE Playback Volume", 0x0f, 1, 0x0, HDA_OUTPUT),
2301 HDA_BIND_MUTE("Side Playback Switch", 0x0e, 2, HDA_INPUT), 2231 HDA_BIND_MUTE_MONO("Internal LFE Playback Switch", 0x0f, 1, 2, HDA_INPUT),
2302 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2232 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2303 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2233 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2304 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 2234 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
@@ -2309,7 +2239,6 @@ static struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = {
2309 { } /* end */ 2239 { } /* end */
2310}; 2240};
2311 2241
2312
2313static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = { 2242static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
2314 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2243 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2315 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2244 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
@@ -3919,6 +3848,8 @@ static struct hda_amp_list alc880_lg_loopbacks[] = {
3919 * Common callbacks 3848 * Common callbacks
3920 */ 3849 */
3921 3850
3851static void alc_init_special_input_src(struct hda_codec *codec);
3852
3922static int alc_init(struct hda_codec *codec) 3853static int alc_init(struct hda_codec *codec)
3923{ 3854{
3924 struct alc_spec *spec = codec->spec; 3855 struct alc_spec *spec = codec->spec;
@@ -3929,6 +3860,7 @@ static int alc_init(struct hda_codec *codec)
3929 3860
3930 for (i = 0; i < spec->num_init_verbs; i++) 3861 for (i = 0; i < spec->num_init_verbs; i++)
3931 snd_hda_sequence_write(codec, spec->init_verbs[i]); 3862 snd_hda_sequence_write(codec, spec->init_verbs[i]);
3863 alc_init_special_input_src(codec);
3932 3864
3933 if (spec->init_hook) 3865 if (spec->init_hook)
3934 spec->init_hook(codec); 3866 spec->init_hook(codec);
@@ -4284,6 +4216,7 @@ static void alc_free(struct hda_codec *codec)
4284 return; 4216 return;
4285 4217
4286 alc_shutup(codec); 4218 alc_shutup(codec);
4219 snd_hda_input_jack_free(codec);
4287 alc_free_kctls(codec); 4220 alc_free_kctls(codec);
4288 kfree(spec); 4221 kfree(spec);
4289 snd_hda_detach_beep_device(codec); 4222 snd_hda_detach_beep_device(codec);
@@ -4702,7 +4635,7 @@ static struct snd_pci_quirk alc880_cfg_tbl[] = {
4702 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2), 4635 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
4703 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG), 4636 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
4704 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG), 4637 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
4705 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734), 4638 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_F1734),
4706 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL), 4639 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
4707 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53), 4640 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
4708 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810), 4641 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
@@ -5151,7 +5084,9 @@ static const char *alc_get_line_out_pfx(const struct auto_pin_cfg *cfg,
5151 5084
5152 switch (cfg->line_out_type) { 5085 switch (cfg->line_out_type) {
5153 case AUTO_PIN_SPEAKER_OUT: 5086 case AUTO_PIN_SPEAKER_OUT:
5154 return "Speaker"; 5087 if (cfg->line_outs == 1)
5088 return "Speaker";
5089 break;
5155 case AUTO_PIN_HP_OUT: 5090 case AUTO_PIN_HP_OUT:
5156 return "Headphone"; 5091 return "Headphone";
5157 default: 5092 default:
@@ -5205,16 +5140,19 @@ static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
5205 return err; 5140 return err;
5206 } else { 5141 } else {
5207 const char *name = pfx; 5142 const char *name = pfx;
5208 if (!name) 5143 int index = i;
5144 if (!name) {
5209 name = chname[i]; 5145 name = chname[i];
5146 index = 0;
5147 }
5210 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, 5148 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5211 name, i, 5149 name, index,
5212 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 5150 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
5213 HDA_OUTPUT)); 5151 HDA_OUTPUT));
5214 if (err < 0) 5152 if (err < 0)
5215 return err; 5153 return err;
5216 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, 5154 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5217 name, i, 5155 name, index,
5218 HDA_COMPOSE_AMP_VAL(nid, 3, 2, 5156 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
5219 HDA_INPUT)); 5157 HDA_INPUT));
5220 if (err < 0) 5158 if (err < 0)
@@ -5585,6 +5523,7 @@ static void fixup_single_adc(struct hda_codec *codec)
5585 spec->capsrc_nids += i; 5523 spec->capsrc_nids += i;
5586 spec->adc_nids += i; 5524 spec->adc_nids += i;
5587 spec->num_adc_nids = 1; 5525 spec->num_adc_nids = 1;
5526 spec->single_input_src = 1;
5588 } 5527 }
5589} 5528}
5590 5529
@@ -5596,6 +5535,16 @@ static void fixup_dual_adc_switch(struct hda_codec *codec)
5596 init_capsrc_for_pin(codec, spec->int_mic.pin); 5535 init_capsrc_for_pin(codec, spec->int_mic.pin);
5597} 5536}
5598 5537
5538/* initialize some special cases for input sources */
5539static void alc_init_special_input_src(struct hda_codec *codec)
5540{
5541 struct alc_spec *spec = codec->spec;
5542 if (spec->dual_adc_switch)
5543 fixup_dual_adc_switch(codec);
5544 else if (spec->single_input_src)
5545 init_capsrc_for_pin(codec, spec->autocfg.inputs[0].pin);
5546}
5547
5599static void set_capture_mixer(struct hda_codec *codec) 5548static void set_capture_mixer(struct hda_codec *codec)
5600{ 5549{
5601 struct alc_spec *spec = codec->spec; 5550 struct alc_spec *spec = codec->spec;
@@ -5611,7 +5560,7 @@ static void set_capture_mixer(struct hda_codec *codec)
5611 int mux = 0; 5560 int mux = 0;
5612 int num_adcs = spec->num_adc_nids; 5561 int num_adcs = spec->num_adc_nids;
5613 if (spec->dual_adc_switch) 5562 if (spec->dual_adc_switch)
5614 fixup_dual_adc_switch(codec); 5563 num_adcs = 1;
5615 else if (spec->auto_mic) 5564 else if (spec->auto_mic)
5616 fixup_automic_adc(codec); 5565 fixup_automic_adc(codec);
5617 else if (spec->input_mux) { 5566 else if (spec->input_mux) {
@@ -5620,8 +5569,6 @@ static void set_capture_mixer(struct hda_codec *codec)
5620 else if (spec->input_mux->num_items == 1) 5569 else if (spec->input_mux->num_items == 1)
5621 fixup_single_adc(codec); 5570 fixup_single_adc(codec);
5622 } 5571 }
5623 if (spec->dual_adc_switch)
5624 num_adcs = 1;
5625 spec->cap_mixer = caps[mux][num_adcs - 1]; 5572 spec->cap_mixer = caps[mux][num_adcs - 1];
5626 } 5573 }
5627} 5574}
@@ -10748,6 +10695,7 @@ static struct alc_config_preset alc882_presets[] = {
10748 */ 10695 */
10749enum { 10696enum {
10750 PINFIX_ABIT_AW9D_MAX, 10697 PINFIX_ABIT_AW9D_MAX,
10698 PINFIX_LENOVO_Y530,
10751 PINFIX_PB_M5210, 10699 PINFIX_PB_M5210,
10752 PINFIX_ACER_ASPIRE_7736, 10700 PINFIX_ACER_ASPIRE_7736,
10753}; 10701};
@@ -10762,6 +10710,14 @@ static const struct alc_fixup alc882_fixups[] = {
10762 { } 10710 { }
10763 } 10711 }
10764 }, 10712 },
10713 [PINFIX_LENOVO_Y530] = {
10714 .type = ALC_FIXUP_PINS,
10715 .v.pins = (const struct alc_pincfg[]) {
10716 { 0x15, 0x99130112 }, /* rear int speakers */
10717 { 0x16, 0x99130111 }, /* subwoofer */
10718 { }
10719 }
10720 },
10765 [PINFIX_PB_M5210] = { 10721 [PINFIX_PB_M5210] = {
10766 .type = ALC_FIXUP_VERBS, 10722 .type = ALC_FIXUP_VERBS,
10767 .v.verbs = (const struct hda_verb[]) { 10723 .v.verbs = (const struct hda_verb[]) {
@@ -10777,6 +10733,7 @@ static const struct alc_fixup alc882_fixups[] = {
10777 10733
10778static struct snd_pci_quirk alc882_fixup_tbl[] = { 10734static struct snd_pci_quirk alc882_fixup_tbl[] = {
10779 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210), 10735 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210),
10736 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", PINFIX_LENOVO_Y530),
10780 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX), 10737 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
10781 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736), 10738 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736),
10782 {} 10739 {}
@@ -10829,23 +10786,28 @@ static void alc882_auto_init_hp_out(struct hda_codec *codec)
10829 hda_nid_t pin, dac; 10786 hda_nid_t pin, dac;
10830 int i; 10787 int i;
10831 10788
10832 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) { 10789 if (spec->autocfg.line_out_type != AUTO_PIN_HP_OUT) {
10833 pin = spec->autocfg.hp_pins[i]; 10790 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
10834 if (!pin) 10791 pin = spec->autocfg.hp_pins[i];
10835 break; 10792 if (!pin)
10836 dac = spec->multiout.hp_nid; 10793 break;
10837 if (!dac) 10794 dac = spec->multiout.hp_nid;
10838 dac = spec->multiout.dac_nids[0]; /* to front */ 10795 if (!dac)
10839 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac); 10796 dac = spec->multiout.dac_nids[0]; /* to front */
10797 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
10798 }
10840 } 10799 }
10841 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) { 10800
10842 pin = spec->autocfg.speaker_pins[i]; 10801 if (spec->autocfg.line_out_type != AUTO_PIN_SPEAKER_OUT) {
10843 if (!pin) 10802 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
10844 break; 10803 pin = spec->autocfg.speaker_pins[i];
10845 dac = spec->multiout.extra_out_nid[0]; 10804 if (!pin)
10846 if (!dac) 10805 break;
10847 dac = spec->multiout.dac_nids[0]; /* to front */ 10806 dac = spec->multiout.extra_out_nid[0];
10848 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac); 10807 if (!dac)
10808 dac = spec->multiout.dac_nids[0]; /* to front */
10809 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
10810 }
10849 } 10811 }
10850} 10812}
10851 10813
@@ -13796,6 +13758,7 @@ static int alc268_parse_auto_config(struct hda_codec *codec)
13796} 13758}
13797 13759
13798#define alc268_auto_init_analog_input alc882_auto_init_analog_input 13760#define alc268_auto_init_analog_input alc882_auto_init_analog_input
13761#define alc268_auto_init_input_src alc882_auto_init_input_src
13799 13762
13800/* init callback for auto-configuration model -- overriding the default init */ 13763/* init callback for auto-configuration model -- overriding the default init */
13801static void alc268_auto_init(struct hda_codec *codec) 13764static void alc268_auto_init(struct hda_codec *codec)
@@ -13805,6 +13768,7 @@ static void alc268_auto_init(struct hda_codec *codec)
13805 alc268_auto_init_hp_out(codec); 13768 alc268_auto_init_hp_out(codec);
13806 alc268_auto_init_mono_speaker_out(codec); 13769 alc268_auto_init_mono_speaker_out(codec);
13807 alc268_auto_init_analog_input(codec); 13770 alc268_auto_init_analog_input(codec);
13771 alc268_auto_init_input_src(codec);
13808 alc_auto_init_digital(codec); 13772 alc_auto_init_digital(codec);
13809 if (spec->unsol_event) 13773 if (spec->unsol_event)
13810 alc_inithook(codec); 13774 alc_inithook(codec);
@@ -14092,7 +14056,6 @@ static int patch_alc268(struct hda_codec *codec)
14092 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) { 14056 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
14093 /* check whether NID 0x07 is valid */ 14057 /* check whether NID 0x07 is valid */
14094 unsigned int wcap = get_wcaps(codec, 0x07); 14058 unsigned int wcap = get_wcaps(codec, 0x07);
14095 int i;
14096 14059
14097 spec->capsrc_nids = alc268_capsrc_nids; 14060 spec->capsrc_nids = alc268_capsrc_nids;
14098 /* get type */ 14061 /* get type */
@@ -14112,13 +14075,6 @@ static int patch_alc268(struct hda_codec *codec)
14112 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids); 14075 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
14113 add_mixer(spec, alc268_capture_mixer); 14076 add_mixer(spec, alc268_capture_mixer);
14114 } 14077 }
14115 /* set default input source */
14116 for (i = 0; i < spec->num_adc_nids; i++)
14117 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
14118 0, AC_VERB_SET_CONNECT_SEL,
14119 i < spec->num_mux_defs ?
14120 spec->input_mux[i].items[0].index :
14121 spec->input_mux->items[0].index);
14122 } 14078 }
14123 14079
14124 spec->vmaster_nid = 0x02; 14080 spec->vmaster_nid = 0x02;
@@ -14495,7 +14451,7 @@ static void alc269_speaker_automute(struct hda_codec *codec)
14495 HDA_AMP_MUTE, bits); 14451 HDA_AMP_MUTE, bits);
14496 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 14452 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
14497 HDA_AMP_MUTE, bits); 14453 HDA_AMP_MUTE, bits);
14498 alc_report_jack(codec, nid); 14454 snd_hda_input_jack_report(codec, nid);
14499} 14455}
14500 14456
14501/* unsolicited event for HP jack sensing */ 14457/* unsolicited event for HP jack sensing */
@@ -14807,11 +14763,6 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
14807 fillup_priv_adc_nids(codec, alc269_adc_candidates, 14763 fillup_priv_adc_nids(codec, alc269_adc_candidates,
14808 sizeof(alc269_adc_candidates)); 14764 sizeof(alc269_adc_candidates));
14809 14765
14810 /* set default input source */
14811 if (!spec->dual_adc_switch)
14812 select_or_unmute_capsrc(codec, spec->capsrc_nids[0],
14813 spec->input_mux->items[0].index);
14814
14815 err = alc_auto_add_mic_boost(codec); 14766 err = alc_auto_add_mic_boost(codec);
14816 if (err < 0) 14767 if (err < 0)
14817 return err; 14768 return err;
@@ -14825,6 +14776,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
14825#define alc269_auto_init_multi_out alc268_auto_init_multi_out 14776#define alc269_auto_init_multi_out alc268_auto_init_multi_out
14826#define alc269_auto_init_hp_out alc268_auto_init_hp_out 14777#define alc269_auto_init_hp_out alc268_auto_init_hp_out
14827#define alc269_auto_init_analog_input alc882_auto_init_analog_input 14778#define alc269_auto_init_analog_input alc882_auto_init_analog_input
14779#define alc269_auto_init_input_src alc882_auto_init_input_src
14828 14780
14829 14781
14830/* init callback for auto-configuration model -- overriding the default init */ 14782/* init callback for auto-configuration model -- overriding the default init */
@@ -14834,6 +14786,8 @@ static void alc269_auto_init(struct hda_codec *codec)
14834 alc269_auto_init_multi_out(codec); 14786 alc269_auto_init_multi_out(codec);
14835 alc269_auto_init_hp_out(codec); 14787 alc269_auto_init_hp_out(codec);
14836 alc269_auto_init_analog_input(codec); 14788 alc269_auto_init_analog_input(codec);
14789 if (!spec->dual_adc_switch)
14790 alc269_auto_init_input_src(codec);
14837 alc_auto_init_digital(codec); 14791 alc_auto_init_digital(codec);
14838 if (spec->unsol_event) 14792 if (spec->unsol_event)
14839 alc_inithook(codec); 14793 alc_inithook(codec);
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index bd7b123f6440..05fcd60cc46f 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -180,18 +180,16 @@ struct sigmatel_event {
180 int data; 180 int data;
181}; 181};
182 182
183struct sigmatel_jack {
184 hda_nid_t nid;
185 int type;
186 struct snd_jack *jack;
187};
188
189struct sigmatel_mic_route { 183struct sigmatel_mic_route {
190 hda_nid_t pin; 184 hda_nid_t pin;
191 signed char mux_idx; 185 signed char mux_idx;
192 signed char dmux_idx; 186 signed char dmux_idx;
193}; 187};
194 188
189#define MAX_PINS_NUM 16
190#define MAX_ADCS_NUM 4
191#define MAX_DMICS_NUM 4
192
195struct sigmatel_spec { 193struct sigmatel_spec {
196 struct snd_kcontrol_new *mixers[4]; 194 struct snd_kcontrol_new *mixers[4];
197 unsigned int num_mixers; 195 unsigned int num_mixers;
@@ -229,9 +227,6 @@ struct sigmatel_spec {
229 hda_nid_t *pwr_nids; 227 hda_nid_t *pwr_nids;
230 hda_nid_t *dac_list; 228 hda_nid_t *dac_list;
231 229
232 /* jack detection */
233 struct snd_array jacks;
234
235 /* events */ 230 /* events */
236 struct snd_array events; 231 struct snd_array events;
237 232
@@ -309,6 +304,17 @@ struct sigmatel_spec {
309 struct hda_input_mux private_imux; 304 struct hda_input_mux private_imux;
310 struct hda_input_mux private_smux; 305 struct hda_input_mux private_smux;
311 struct hda_input_mux private_mono_mux; 306 struct hda_input_mux private_mono_mux;
307
308 /* auto spec */
309 unsigned auto_pin_cnt;
310 hda_nid_t auto_pin_nids[MAX_PINS_NUM];
311 unsigned auto_adc_cnt;
312 hda_nid_t auto_adc_nids[MAX_ADCS_NUM];
313 hda_nid_t auto_mux_nids[MAX_ADCS_NUM];
314 hda_nid_t auto_dmux_nids[MAX_ADCS_NUM];
315 unsigned long auto_capvols[MAX_ADCS_NUM];
316 unsigned auto_dmic_cnt;
317 hda_nid_t auto_dmic_nids[MAX_DMICS_NUM];
312}; 318};
313 319
314static hda_nid_t stac9200_adc_nids[1] = { 320static hda_nid_t stac9200_adc_nids[1] = {
@@ -364,14 +370,6 @@ static unsigned long stac92hd73xx_capvols[] = {
364 370
365#define STAC92HD83_DAC_COUNT 3 371#define STAC92HD83_DAC_COUNT 3
366 372
367static hda_nid_t stac92hd83xxx_mux_nids[2] = {
368 0x17, 0x18,
369};
370
371static hda_nid_t stac92hd83xxx_adc_nids[2] = {
372 0x15, 0x16,
373};
374
375static hda_nid_t stac92hd83xxx_pwr_nids[4] = { 373static hda_nid_t stac92hd83xxx_pwr_nids[4] = {
376 0xa, 0xb, 0xd, 0xe, 374 0xa, 0xb, 0xd, 0xe,
377}; 375};
@@ -384,25 +382,9 @@ static unsigned int stac92hd83xxx_pwr_mapping[4] = {
384 0x03, 0x0c, 0x20, 0x40, 382 0x03, 0x0c, 0x20, 0x40,
385}; 383};
386 384
387#define STAC92HD83XXX_NUM_DMICS 2 385static hda_nid_t stac92hd83xxx_dmic_nids[] = {
388static hda_nid_t stac92hd83xxx_dmic_nids[STAC92HD83XXX_NUM_DMICS + 1] = { 386 0x11, 0x20,
389 0x11, 0x20, 0
390};
391
392#define STAC92HD88XXX_NUM_DMICS STAC92HD83XXX_NUM_DMICS
393#define stac92hd88xxx_dmic_nids stac92hd83xxx_dmic_nids
394
395#define STAC92HD87B_NUM_DMICS 1
396static hda_nid_t stac92hd87b_dmic_nids[STAC92HD87B_NUM_DMICS + 1] = {
397 0x11, 0
398};
399
400#define STAC92HD83XXX_NUM_CAPS 2
401static unsigned long stac92hd83xxx_capvols[] = {
402 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
403 HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_OUTPUT),
404}; 387};
405#define stac92hd83xxx_capsws stac92hd83xxx_capvols
406 388
407static hda_nid_t stac92hd71bxx_pwr_nids[3] = { 389static hda_nid_t stac92hd71bxx_pwr_nids[3] = {
408 0x0a, 0x0d, 0x0f 390 0x0a, 0x0d, 0x0f
@@ -581,21 +563,6 @@ static hda_nid_t stac92hd73xx_pin_nids[13] = {
581 0x14, 0x22, 0x23 563 0x14, 0x22, 0x23
582}; 564};
583 565
584static hda_nid_t stac92hd83xxx_pin_nids[10] = {
585 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
586 0x0f, 0x10, 0x11, 0x1f, 0x20,
587};
588
589static hda_nid_t stac92hd87xxx_pin_nids[6] = {
590 0x0a, 0x0b, 0x0c, 0x0d,
591 0x0f, 0x11,
592};
593
594static hda_nid_t stac92hd88xxx_pin_nids[8] = {
595 0x0a, 0x0b, 0x0c, 0x0d,
596 0x0f, 0x11, 0x1f, 0x20,
597};
598
599#define STAC92HD71BXX_NUM_PINS 13 566#define STAC92HD71BXX_NUM_PINS 13
600static hda_nid_t stac92hd71bxx_pin_nids_4port[STAC92HD71BXX_NUM_PINS] = { 567static hda_nid_t stac92hd71bxx_pin_nids_4port[STAC92HD71BXX_NUM_PINS] = {
601 0x0a, 0x0b, 0x0c, 0x0d, 0x00, 568 0x0a, 0x0b, 0x0c, 0x0d, 0x00,
@@ -757,7 +724,7 @@ static int stac92xx_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
757 struct sigmatel_spec *spec = codec->spec; 724 struct sigmatel_spec *spec = codec->spec;
758 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 725 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
759 const struct hda_input_mux *imux = spec->input_mux; 726 const struct hda_input_mux *imux = spec->input_mux;
760 unsigned int idx, prev_idx; 727 unsigned int idx, prev_idx, didx;
761 728
762 idx = ucontrol->value.enumerated.item[0]; 729 idx = ucontrol->value.enumerated.item[0];
763 if (idx >= imux->num_items) 730 if (idx >= imux->num_items)
@@ -769,7 +736,8 @@ static int stac92xx_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
769 snd_hda_codec_write_cache(codec, spec->mux_nids[adc_idx], 0, 736 snd_hda_codec_write_cache(codec, spec->mux_nids[adc_idx], 0,
770 AC_VERB_SET_CONNECT_SEL, 737 AC_VERB_SET_CONNECT_SEL,
771 imux->items[idx].index); 738 imux->items[idx].index);
772 if (prev_idx >= spec->num_analog_muxes) { 739 if (prev_idx >= spec->num_analog_muxes &&
740 spec->mux_nids[adc_idx] != spec->dmux_nids[adc_idx]) {
773 imux = spec->dinput_mux; 741 imux = spec->dinput_mux;
774 /* 0 = analog */ 742 /* 0 = analog */
775 snd_hda_codec_write_cache(codec, 743 snd_hda_codec_write_cache(codec,
@@ -779,9 +747,13 @@ static int stac92xx_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
779 } 747 }
780 } else { 748 } else {
781 imux = spec->dinput_mux; 749 imux = spec->dinput_mux;
750 /* first dimux item is hardcoded to select analog imux,
751 * so lets skip it
752 */
753 didx = idx - spec->num_analog_muxes + 1;
782 snd_hda_codec_write_cache(codec, spec->dmux_nids[adc_idx], 0, 754 snd_hda_codec_write_cache(codec, spec->dmux_nids[adc_idx], 0,
783 AC_VERB_SET_CONNECT_SEL, 755 AC_VERB_SET_CONNECT_SEL,
784 imux->items[idx - 1].index); 756 imux->items[didx].index);
785 } 757 }
786 spec->cur_mux[adc_idx] = idx; 758 spec->cur_mux[adc_idx] = idx;
787 return 1; 759 return 1;
@@ -3419,6 +3391,17 @@ static const char * const stac92xx_dmic_labels[5] = {
3419 "Digital Mic 3", "Digital Mic 4" 3391 "Digital Mic 3", "Digital Mic 4"
3420}; 3392};
3421 3393
3394static hda_nid_t get_connected_node(struct hda_codec *codec, hda_nid_t mux,
3395 int idx)
3396{
3397 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
3398 int nums;
3399 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
3400 if (idx >= 0 && idx < nums)
3401 return conn[idx];
3402 return 0;
3403}
3404
3422static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, 3405static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
3423 hda_nid_t nid) 3406 hda_nid_t nid)
3424{ 3407{
@@ -3429,6 +3412,15 @@ static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
3429 for (i = 0; i < nums; i++) 3412 for (i = 0; i < nums; i++)
3430 if (conn[i] == nid) 3413 if (conn[i] == nid)
3431 return i; 3414 return i;
3415
3416 for (i = 0; i < nums; i++) {
3417 unsigned int wid_caps = get_wcaps(codec, conn[i]);
3418 unsigned int wid_type = get_wcaps_type(wid_caps);
3419
3420 if (wid_type != AC_WID_PIN && wid_type != AC_WID_AUD_MIX)
3421 if (get_connection_index(codec, conn[i], nid) >= 0)
3422 return i;
3423 }
3432 return -1; 3424 return -1;
3433} 3425}
3434 3426
@@ -3501,6 +3493,16 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,
3501 type_idx, HDA_OUTPUT); 3493 type_idx, HDA_OUTPUT);
3502 if (err < 0) 3494 if (err < 0)
3503 return err; 3495 return err;
3496 if (!err) {
3497 nid = get_connected_node(codec,
3498 spec->dmux_nids[0], index);
3499 if (nid)
3500 err = create_elem_capture_vol(codec,
3501 nid, label,
3502 type_idx, HDA_INPUT);
3503 if (err < 0)
3504 return err;
3505 }
3504 } 3506 }
3505 } 3507 }
3506 3508
@@ -4054,21 +4056,10 @@ static void stac_gpio_set(struct hda_codec *codec, unsigned int mask,
4054 AC_VERB_SET_GPIO_DATA, gpiostate); /* sync */ 4056 AC_VERB_SET_GPIO_DATA, gpiostate); /* sync */
4055} 4057}
4056 4058
4057#ifdef CONFIG_SND_HDA_INPUT_JACK
4058static void stac92xx_free_jack_priv(struct snd_jack *jack)
4059{
4060 struct sigmatel_jack *jacks = jack->private_data;
4061 jacks->nid = 0;
4062 jacks->jack = NULL;
4063}
4064#endif
4065
4066static int stac92xx_add_jack(struct hda_codec *codec, 4059static int stac92xx_add_jack(struct hda_codec *codec,
4067 hda_nid_t nid, int type) 4060 hda_nid_t nid, int type)
4068{ 4061{
4069#ifdef CONFIG_SND_HDA_INPUT_JACK 4062#ifdef CONFIG_SND_HDA_INPUT_JACK
4070 struct sigmatel_spec *spec = codec->spec;
4071 struct sigmatel_jack *jack;
4072 int def_conf = snd_hda_codec_get_pincfg(codec, nid); 4063 int def_conf = snd_hda_codec_get_pincfg(codec, nid);
4073 int connectivity = get_defcfg_connect(def_conf); 4064 int connectivity = get_defcfg_connect(def_conf);
4074 char name[32]; 4065 char name[32];
@@ -4077,26 +4068,15 @@ static int stac92xx_add_jack(struct hda_codec *codec,
4077 if (connectivity && connectivity != AC_JACK_PORT_FIXED) 4068 if (connectivity && connectivity != AC_JACK_PORT_FIXED)
4078 return 0; 4069 return 0;
4079 4070
4080 snd_array_init(&spec->jacks, sizeof(*jack), 32);
4081 jack = snd_array_new(&spec->jacks);
4082 if (!jack)
4083 return -ENOMEM;
4084 jack->nid = nid;
4085 jack->type = type;
4086
4087 snprintf(name, sizeof(name), "%s at %s %s Jack", 4071 snprintf(name, sizeof(name), "%s at %s %s Jack",
4088 snd_hda_get_jack_type(def_conf), 4072 snd_hda_get_jack_type(def_conf),
4089 snd_hda_get_jack_connectivity(def_conf), 4073 snd_hda_get_jack_connectivity(def_conf),
4090 snd_hda_get_jack_location(def_conf)); 4074 snd_hda_get_jack_location(def_conf));
4091 4075
4092 err = snd_jack_new(codec->bus->card, name, type, &jack->jack); 4076 err = snd_hda_input_jack_add(codec, nid, type, name);
4093 if (err < 0) { 4077 if (err < 0)
4094 jack->nid = 0;
4095 return err; 4078 return err;
4096 } 4079#endif /* CONFIG_SND_HDA_INPUT_JACK */
4097 jack->jack->private_data = jack;
4098 jack->jack->private_free = stac92xx_free_jack_priv;
4099#endif
4100 return 0; 4080 return 0;
4101} 4081}
4102 4082
@@ -4399,23 +4379,6 @@ static int stac92xx_init(struct hda_codec *codec)
4399 return 0; 4379 return 0;
4400} 4380}
4401 4381
4402static void stac92xx_free_jacks(struct hda_codec *codec)
4403{
4404#ifdef CONFIG_SND_HDA_INPUT_JACK
4405 /* free jack instances manually when clearing/reconfiguring */
4406 struct sigmatel_spec *spec = codec->spec;
4407 if (!codec->bus->shutdown && spec->jacks.list) {
4408 struct sigmatel_jack *jacks = spec->jacks.list;
4409 int i;
4410 for (i = 0; i < spec->jacks.used; i++, jacks++) {
4411 if (jacks->jack)
4412 snd_device_free(codec->bus->card, jacks->jack);
4413 }
4414 }
4415 snd_array_free(&spec->jacks);
4416#endif
4417}
4418
4419static void stac92xx_free_kctls(struct hda_codec *codec) 4382static void stac92xx_free_kctls(struct hda_codec *codec)
4420{ 4383{
4421 struct sigmatel_spec *spec = codec->spec; 4384 struct sigmatel_spec *spec = codec->spec;
@@ -4449,7 +4412,7 @@ static void stac92xx_free(struct hda_codec *codec)
4449 return; 4412 return;
4450 4413
4451 stac92xx_shutup(codec); 4414 stac92xx_shutup(codec);
4452 stac92xx_free_jacks(codec); 4415 snd_hda_input_jack_free(codec);
4453 snd_array_free(&spec->events); 4416 snd_array_free(&spec->events);
4454 4417
4455 kfree(spec); 4418 kfree(spec);
@@ -4667,33 +4630,6 @@ static void stac92xx_pin_sense(struct hda_codec *codec, hda_nid_t nid)
4667 stac_toggle_power_map(codec, nid, get_pin_presence(codec, nid)); 4630 stac_toggle_power_map(codec, nid, get_pin_presence(codec, nid));
4668} 4631}
4669 4632
4670static void stac92xx_report_jack(struct hda_codec *codec, hda_nid_t nid)
4671{
4672 struct sigmatel_spec *spec = codec->spec;
4673 struct sigmatel_jack *jacks = spec->jacks.list;
4674
4675 if (jacks) {
4676 int i;
4677 for (i = 0; i < spec->jacks.used; i++) {
4678 if (jacks->nid == nid) {
4679 unsigned int pin_ctl =
4680 snd_hda_codec_read(codec, nid,
4681 0, AC_VERB_GET_PIN_WIDGET_CONTROL,
4682 0x00);
4683 int type = jacks->type;
4684 if (type == (SND_JACK_LINEOUT
4685 | SND_JACK_HEADPHONE))
4686 type = (pin_ctl & AC_PINCTL_HP_EN)
4687 ? SND_JACK_HEADPHONE : SND_JACK_LINEOUT;
4688 snd_jack_report(jacks->jack,
4689 get_pin_presence(codec, nid)
4690 ? type : 0);
4691 }
4692 jacks++;
4693 }
4694 }
4695}
4696
4697/* get the pin connection (fixed, none, etc) */ 4633/* get the pin connection (fixed, none, etc) */
4698static unsigned int stac_get_defcfg_connect(struct hda_codec *codec, int idx) 4634static unsigned int stac_get_defcfg_connect(struct hda_codec *codec, int idx)
4699{ 4635{
@@ -4782,7 +4718,7 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
4782 case STAC_PWR_EVENT: 4718 case STAC_PWR_EVENT:
4783 if (spec->num_pwrs > 0) 4719 if (spec->num_pwrs > 0)
4784 stac92xx_pin_sense(codec, event->nid); 4720 stac92xx_pin_sense(codec, event->nid);
4785 stac92xx_report_jack(codec, event->nid); 4721 snd_hda_input_jack_report(codec, event->nid);
4786 4722
4787 switch (codec->subsystem_id) { 4723 switch (codec->subsystem_id) {
4788 case 0x103c308f: 4724 case 0x103c308f:
@@ -5378,6 +5314,105 @@ static int hp_bnb2011_with_dock(struct hda_codec *codec)
5378 return 0; 5314 return 0;
5379} 5315}
5380 5316
5317static void stac92hd8x_add_pin(struct hda_codec *codec, hda_nid_t nid)
5318{
5319 struct sigmatel_spec *spec = codec->spec;
5320 unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid);
5321 int i;
5322
5323 spec->auto_pin_nids[spec->auto_pin_cnt] = nid;
5324 spec->auto_pin_cnt++;
5325
5326 if (get_defcfg_device(def_conf) == AC_JACK_MIC_IN &&
5327 get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE) {
5328 for (i = 0; i < ARRAY_SIZE(stac92hd83xxx_dmic_nids); i++) {
5329 if (nid == stac92hd83xxx_dmic_nids[i]) {
5330 spec->auto_dmic_nids[spec->auto_dmic_cnt] = nid;
5331 spec->auto_dmic_cnt++;
5332 }
5333 }
5334 }
5335}
5336
5337static void stac92hd8x_add_adc(struct hda_codec *codec, hda_nid_t nid)
5338{
5339 struct sigmatel_spec *spec = codec->spec;
5340
5341 spec->auto_adc_nids[spec->auto_adc_cnt] = nid;
5342 spec->auto_adc_cnt++;
5343}
5344
5345static void stac92hd8x_add_mux(struct hda_codec *codec, hda_nid_t nid)
5346{
5347 int i, j;
5348 struct sigmatel_spec *spec = codec->spec;
5349
5350 for (i = 0; i < spec->auto_adc_cnt; i++) {
5351 if (get_connection_index(codec,
5352 spec->auto_adc_nids[i], nid) >= 0) {
5353 /* mux and volume for adc_nids[i] */
5354 if (!spec->auto_mux_nids[i]) {
5355 spec->auto_mux_nids[i] = nid;
5356 /* 92hd codecs capture volume is in mux */
5357 spec->auto_capvols[i] = HDA_COMPOSE_AMP_VAL(nid,
5358 3, 0, HDA_OUTPUT);
5359 }
5360 for (j = 0; j < spec->auto_dmic_cnt; j++) {
5361 if (get_connection_index(codec, nid,
5362 spec->auto_dmic_nids[j]) >= 0) {
5363 /* dmux for adc_nids[i] */
5364 if (!spec->auto_dmux_nids[i])
5365 spec->auto_dmux_nids[i] = nid;
5366 break;
5367 }
5368 }
5369 break;
5370 }
5371 }
5372}
5373
5374static void stac92hd8x_fill_auto_spec(struct hda_codec *codec)
5375{
5376 hda_nid_t nid, end_nid;
5377 unsigned int wid_caps, wid_type;
5378 struct sigmatel_spec *spec = codec->spec;
5379
5380 end_nid = codec->start_nid + codec->num_nodes;
5381
5382 for (nid = codec->start_nid; nid < end_nid; nid++) {
5383 wid_caps = get_wcaps(codec, nid);
5384 wid_type = get_wcaps_type(wid_caps);
5385
5386 if (wid_type == AC_WID_PIN)
5387 stac92hd8x_add_pin(codec, nid);
5388
5389 if (wid_type == AC_WID_AUD_IN && !(wid_caps & AC_WCAP_DIGITAL))
5390 stac92hd8x_add_adc(codec, nid);
5391 }
5392
5393 for (nid = codec->start_nid; nid < end_nid; nid++) {
5394 wid_caps = get_wcaps(codec, nid);
5395 wid_type = get_wcaps_type(wid_caps);
5396
5397 if (wid_type == AC_WID_AUD_SEL)
5398 stac92hd8x_add_mux(codec, nid);
5399 }
5400
5401 spec->pin_nids = spec->auto_pin_nids;
5402 spec->num_pins = spec->auto_pin_cnt;
5403 spec->adc_nids = spec->auto_adc_nids;
5404 spec->num_adcs = spec->auto_adc_cnt;
5405 spec->capvols = spec->auto_capvols;
5406 spec->capsws = spec->auto_capvols;
5407 spec->num_caps = spec->auto_adc_cnt;
5408 spec->mux_nids = spec->auto_mux_nids;
5409 spec->num_muxes = spec->auto_adc_cnt;
5410 spec->dmux_nids = spec->auto_dmux_nids;
5411 spec->num_dmuxes = spec->auto_adc_cnt;
5412 spec->dmic_nids = spec->auto_dmic_nids;
5413 spec->num_dmics = spec->auto_dmic_cnt;
5414}
5415
5381static int patch_stac92hd83xxx(struct hda_codec *codec) 5416static int patch_stac92hd83xxx(struct hda_codec *codec)
5382{ 5417{
5383 struct sigmatel_spec *spec; 5418 struct sigmatel_spec *spec;
@@ -5399,26 +5434,17 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)
5399 snd_hda_codec_write_cache(codec, codec->afg, 0, 0x7ED, 0); 5434 snd_hda_codec_write_cache(codec, codec->afg, 0, 0x7ED, 0);
5400 codec->no_trigger_sense = 1; 5435 codec->no_trigger_sense = 1;
5401 codec->spec = spec; 5436 codec->spec = spec;
5437
5438 stac92hd8x_fill_auto_spec(codec);
5439
5402 spec->linear_tone_beep = 0; 5440 spec->linear_tone_beep = 0;
5403 codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs; 5441 codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs;
5404 spec->digbeep_nid = 0x21; 5442 spec->digbeep_nid = 0x21;
5405 spec->dmic_nids = stac92hd83xxx_dmic_nids;
5406 spec->dmux_nids = stac92hd83xxx_mux_nids;
5407 spec->mux_nids = stac92hd83xxx_mux_nids;
5408 spec->num_muxes = ARRAY_SIZE(stac92hd83xxx_mux_nids);
5409 spec->adc_nids = stac92hd83xxx_adc_nids;
5410 spec->num_adcs = ARRAY_SIZE(stac92hd83xxx_adc_nids);
5411 spec->pwr_nids = stac92hd83xxx_pwr_nids; 5443 spec->pwr_nids = stac92hd83xxx_pwr_nids;
5412 spec->pwr_mapping = stac92hd83xxx_pwr_mapping; 5444 spec->pwr_mapping = stac92hd83xxx_pwr_mapping;
5413 spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids); 5445 spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids);
5414 spec->multiout.dac_nids = spec->dac_nids; 5446 spec->multiout.dac_nids = spec->dac_nids;
5415
5416 spec->init = stac92hd83xxx_core_init; 5447 spec->init = stac92hd83xxx_core_init;
5417 spec->num_pins = ARRAY_SIZE(stac92hd83xxx_pin_nids);
5418 spec->pin_nids = stac92hd83xxx_pin_nids;
5419 spec->num_caps = STAC92HD83XXX_NUM_CAPS;
5420 spec->capvols = stac92hd83xxx_capvols;
5421 spec->capsws = stac92hd83xxx_capsws;
5422 5448
5423 spec->board_config = snd_hda_check_board_config(codec, 5449 spec->board_config = snd_hda_check_board_config(codec,
5424 STAC_92HD83XXX_MODELS, 5450 STAC_92HD83XXX_MODELS,
@@ -5436,28 +5462,11 @@ again:
5436 case 0x111d76d1: 5462 case 0x111d76d1:
5437 case 0x111d76d9: 5463 case 0x111d76d9:
5438 case 0x111d76e5: 5464 case 0x111d76e5:
5439 spec->dmic_nids = stac92hd87b_dmic_nids;
5440 spec->num_dmics = stac92xx_connected_ports(codec,
5441 stac92hd87b_dmic_nids,
5442 STAC92HD87B_NUM_DMICS);
5443 spec->num_pins = ARRAY_SIZE(stac92hd87xxx_pin_nids);
5444 spec->pin_nids = stac92hd87xxx_pin_nids;
5445 spec->mono_nid = 0;
5446 spec->num_pwrs = 0;
5447 break;
5448 case 0x111d7666: 5465 case 0x111d7666:
5449 case 0x111d7667: 5466 case 0x111d7667:
5450 case 0x111d7668: 5467 case 0x111d7668:
5451 case 0x111d7669: 5468 case 0x111d7669:
5452 case 0x111d76e3: 5469 case 0x111d76e3:
5453 spec->num_dmics = stac92xx_connected_ports(codec,
5454 stac92hd88xxx_dmic_nids,
5455 STAC92HD88XXX_NUM_DMICS);
5456 spec->num_pins = ARRAY_SIZE(stac92hd88xxx_pin_nids);
5457 spec->pin_nids = stac92hd88xxx_pin_nids;
5458 spec->mono_nid = 0;
5459 spec->num_pwrs = 0;
5460 break;
5461 case 0x111d7604: 5470 case 0x111d7604:
5462 case 0x111d76d4: 5471 case 0x111d76d4:
5463 case 0x111d7605: 5472 case 0x111d7605:
@@ -5466,9 +5475,6 @@ again:
5466 if (spec->board_config == STAC_92HD83XXX_PWR_REF) 5475 if (spec->board_config == STAC_92HD83XXX_PWR_REF)
5467 break; 5476 break;
5468 spec->num_pwrs = 0; 5477 spec->num_pwrs = 0;
5469 spec->num_dmics = stac92xx_connected_ports(codec,
5470 stac92hd83xxx_dmic_nids,
5471 STAC92HD83XXX_NUM_DMICS);
5472 break; 5478 break;
5473 } 5479 }
5474 5480
diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c
index 13cec1e5ced9..2ae8d29500a8 100644
--- a/sound/pci/intel8x0m.c
+++ b/sound/pci/intel8x0m.c
@@ -341,9 +341,9 @@ static int snd_intel8x0m_codec_semaphore(struct intel8x0m *chip, unsigned int co
341 return -EBUSY; 341 return -EBUSY;
342} 342}
343 343
344static void snd_intel8x0_codec_write(struct snd_ac97 *ac97, 344static void snd_intel8x0m_codec_write(struct snd_ac97 *ac97,
345 unsigned short reg, 345 unsigned short reg,
346 unsigned short val) 346 unsigned short val)
347{ 347{
348 struct intel8x0m *chip = ac97->private_data; 348 struct intel8x0m *chip = ac97->private_data;
349 349
@@ -354,8 +354,8 @@ static void snd_intel8x0_codec_write(struct snd_ac97 *ac97,
354 iaputword(chip, reg + ac97->num * 0x80, val); 354 iaputword(chip, reg + ac97->num * 0x80, val);
355} 355}
356 356
357static unsigned short snd_intel8x0_codec_read(struct snd_ac97 *ac97, 357static unsigned short snd_intel8x0m_codec_read(struct snd_ac97 *ac97,
358 unsigned short reg) 358 unsigned short reg)
359{ 359{
360 struct intel8x0m *chip = ac97->private_data; 360 struct intel8x0m *chip = ac97->private_data;
361 unsigned short res; 361 unsigned short res;
@@ -385,7 +385,7 @@ static unsigned short snd_intel8x0_codec_read(struct snd_ac97 *ac97,
385/* 385/*
386 * DMA I/O 386 * DMA I/O
387 */ 387 */
388static void snd_intel8x0_setup_periods(struct intel8x0m *chip, struct ichdev *ichdev) 388static void snd_intel8x0m_setup_periods(struct intel8x0m *chip, struct ichdev *ichdev)
389{ 389{
390 int idx; 390 int idx;
391 u32 *bdbar = ichdev->bdbar; 391 u32 *bdbar = ichdev->bdbar;
@@ -437,7 +437,7 @@ static void snd_intel8x0_setup_periods(struct intel8x0m *chip, struct ichdev *ic
437 * Interrupt handler 437 * Interrupt handler
438 */ 438 */
439 439
440static inline void snd_intel8x0_update(struct intel8x0m *chip, struct ichdev *ichdev) 440static inline void snd_intel8x0m_update(struct intel8x0m *chip, struct ichdev *ichdev)
441{ 441{
442 unsigned long port = ichdev->reg_offset; 442 unsigned long port = ichdev->reg_offset;
443 int civ, i, step; 443 int civ, i, step;
@@ -489,7 +489,7 @@ static inline void snd_intel8x0_update(struct intel8x0m *chip, struct ichdev *ic
489 iputbyte(chip, port + ichdev->roff_sr, ICH_FIFOE | ICH_BCIS | ICH_LVBCI); 489 iputbyte(chip, port + ichdev->roff_sr, ICH_FIFOE | ICH_BCIS | ICH_LVBCI);
490} 490}
491 491
492static irqreturn_t snd_intel8x0_interrupt(int irq, void *dev_id) 492static irqreturn_t snd_intel8x0m_interrupt(int irq, void *dev_id)
493{ 493{
494 struct intel8x0m *chip = dev_id; 494 struct intel8x0m *chip = dev_id;
495 struct ichdev *ichdev; 495 struct ichdev *ichdev;
@@ -512,7 +512,7 @@ static irqreturn_t snd_intel8x0_interrupt(int irq, void *dev_id)
512 for (i = 0; i < chip->bdbars_count; i++) { 512 for (i = 0; i < chip->bdbars_count; i++) {
513 ichdev = &chip->ichd[i]; 513 ichdev = &chip->ichd[i];
514 if (status & ichdev->int_sta_mask) 514 if (status & ichdev->int_sta_mask)
515 snd_intel8x0_update(chip, ichdev); 515 snd_intel8x0m_update(chip, ichdev);
516 } 516 }
517 517
518 /* ack them */ 518 /* ack them */
@@ -526,7 +526,7 @@ static irqreturn_t snd_intel8x0_interrupt(int irq, void *dev_id)
526 * PCM part 526 * PCM part
527 */ 527 */
528 528
529static int snd_intel8x0_pcm_trigger(struct snd_pcm_substream *substream, int cmd) 529static int snd_intel8x0m_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
530{ 530{
531 struct intel8x0m *chip = snd_pcm_substream_chip(substream); 531 struct intel8x0m *chip = snd_pcm_substream_chip(substream);
532 struct ichdev *ichdev = get_ichdev(substream); 532 struct ichdev *ichdev = get_ichdev(substream);
@@ -561,18 +561,18 @@ static int snd_intel8x0_pcm_trigger(struct snd_pcm_substream *substream, int cmd
561 return 0; 561 return 0;
562} 562}
563 563
564static int snd_intel8x0_hw_params(struct snd_pcm_substream *substream, 564static int snd_intel8x0m_hw_params(struct snd_pcm_substream *substream,
565 struct snd_pcm_hw_params *hw_params) 565 struct snd_pcm_hw_params *hw_params)
566{ 566{
567 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); 567 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
568} 568}
569 569
570static int snd_intel8x0_hw_free(struct snd_pcm_substream *substream) 570static int snd_intel8x0m_hw_free(struct snd_pcm_substream *substream)
571{ 571{
572 return snd_pcm_lib_free_pages(substream); 572 return snd_pcm_lib_free_pages(substream);
573} 573}
574 574
575static snd_pcm_uframes_t snd_intel8x0_pcm_pointer(struct snd_pcm_substream *substream) 575static snd_pcm_uframes_t snd_intel8x0m_pcm_pointer(struct snd_pcm_substream *substream)
576{ 576{
577 struct intel8x0m *chip = snd_pcm_substream_chip(substream); 577 struct intel8x0m *chip = snd_pcm_substream_chip(substream);
578 struct ichdev *ichdev = get_ichdev(substream); 578 struct ichdev *ichdev = get_ichdev(substream);
@@ -600,7 +600,7 @@ static int snd_intel8x0m_pcm_prepare(struct snd_pcm_substream *substream)
600 ichdev->fragsize = snd_pcm_lib_period_bytes(substream); 600 ichdev->fragsize = snd_pcm_lib_period_bytes(substream);
601 snd_ac97_write(ichdev->ac97, AC97_LINE1_RATE, runtime->rate); 601 snd_ac97_write(ichdev->ac97, AC97_LINE1_RATE, runtime->rate);
602 snd_ac97_write(ichdev->ac97, AC97_LINE1_LEVEL, 0); 602 snd_ac97_write(ichdev->ac97, AC97_LINE1_LEVEL, 0);
603 snd_intel8x0_setup_periods(chip, ichdev); 603 snd_intel8x0m_setup_periods(chip, ichdev);
604 return 0; 604 return 0;
605} 605}
606 606
@@ -682,22 +682,22 @@ static struct snd_pcm_ops snd_intel8x0m_playback_ops = {
682 .open = snd_intel8x0m_playback_open, 682 .open = snd_intel8x0m_playback_open,
683 .close = snd_intel8x0m_playback_close, 683 .close = snd_intel8x0m_playback_close,
684 .ioctl = snd_pcm_lib_ioctl, 684 .ioctl = snd_pcm_lib_ioctl,
685 .hw_params = snd_intel8x0_hw_params, 685 .hw_params = snd_intel8x0m_hw_params,
686 .hw_free = snd_intel8x0_hw_free, 686 .hw_free = snd_intel8x0m_hw_free,
687 .prepare = snd_intel8x0m_pcm_prepare, 687 .prepare = snd_intel8x0m_pcm_prepare,
688 .trigger = snd_intel8x0_pcm_trigger, 688 .trigger = snd_intel8x0m_pcm_trigger,
689 .pointer = snd_intel8x0_pcm_pointer, 689 .pointer = snd_intel8x0m_pcm_pointer,
690}; 690};
691 691
692static struct snd_pcm_ops snd_intel8x0m_capture_ops = { 692static struct snd_pcm_ops snd_intel8x0m_capture_ops = {
693 .open = snd_intel8x0m_capture_open, 693 .open = snd_intel8x0m_capture_open,
694 .close = snd_intel8x0m_capture_close, 694 .close = snd_intel8x0m_capture_close,
695 .ioctl = snd_pcm_lib_ioctl, 695 .ioctl = snd_pcm_lib_ioctl,
696 .hw_params = snd_intel8x0_hw_params, 696 .hw_params = snd_intel8x0m_hw_params,
697 .hw_free = snd_intel8x0_hw_free, 697 .hw_free = snd_intel8x0m_hw_free,
698 .prepare = snd_intel8x0m_pcm_prepare, 698 .prepare = snd_intel8x0m_pcm_prepare,
699 .trigger = snd_intel8x0_pcm_trigger, 699 .trigger = snd_intel8x0m_pcm_trigger,
700 .pointer = snd_intel8x0_pcm_pointer, 700 .pointer = snd_intel8x0m_pcm_pointer,
701}; 701};
702 702
703 703
@@ -710,7 +710,7 @@ struct ich_pcm_table {
710 int ac97_idx; 710 int ac97_idx;
711}; 711};
712 712
713static int __devinit snd_intel8x0_pcm1(struct intel8x0m *chip, int device, 713static int __devinit snd_intel8x0m_pcm1(struct intel8x0m *chip, int device,
714 struct ich_pcm_table *rec) 714 struct ich_pcm_table *rec)
715{ 715{
716 struct snd_pcm *pcm; 716 struct snd_pcm *pcm;
@@ -759,7 +759,7 @@ static struct ich_pcm_table intel_pcms[] __devinitdata = {
759 }, 759 },
760}; 760};
761 761
762static int __devinit snd_intel8x0_pcm(struct intel8x0m *chip) 762static int __devinit snd_intel8x0m_pcm(struct intel8x0m *chip)
763{ 763{
764 int i, tblsize, device, err; 764 int i, tblsize, device, err;
765 struct ich_pcm_table *tbl, *rec; 765 struct ich_pcm_table *tbl, *rec;
@@ -791,7 +791,7 @@ static int __devinit snd_intel8x0_pcm(struct intel8x0m *chip)
791 if (! chip->ichd[rec->ac97_idx].ac97) 791 if (! chip->ichd[rec->ac97_idx].ac97)
792 continue; 792 continue;
793 } 793 }
794 err = snd_intel8x0_pcm1(chip, device, rec); 794 err = snd_intel8x0m_pcm1(chip, device, rec);
795 if (err < 0) 795 if (err < 0)
796 return err; 796 return err;
797 device++; 797 device++;
@@ -806,20 +806,20 @@ static int __devinit snd_intel8x0_pcm(struct intel8x0m *chip)
806 * Mixer part 806 * Mixer part
807 */ 807 */
808 808
809static void snd_intel8x0_mixer_free_ac97_bus(struct snd_ac97_bus *bus) 809static void snd_intel8x0m_mixer_free_ac97_bus(struct snd_ac97_bus *bus)
810{ 810{
811 struct intel8x0m *chip = bus->private_data; 811 struct intel8x0m *chip = bus->private_data;
812 chip->ac97_bus = NULL; 812 chip->ac97_bus = NULL;
813} 813}
814 814
815static void snd_intel8x0_mixer_free_ac97(struct snd_ac97 *ac97) 815static void snd_intel8x0m_mixer_free_ac97(struct snd_ac97 *ac97)
816{ 816{
817 struct intel8x0m *chip = ac97->private_data; 817 struct intel8x0m *chip = ac97->private_data;
818 chip->ac97 = NULL; 818 chip->ac97 = NULL;
819} 819}
820 820
821 821
822static int __devinit snd_intel8x0_mixer(struct intel8x0m *chip, int ac97_clock) 822static int __devinit snd_intel8x0m_mixer(struct intel8x0m *chip, int ac97_clock)
823{ 823{
824 struct snd_ac97_bus *pbus; 824 struct snd_ac97_bus *pbus;
825 struct snd_ac97_template ac97; 825 struct snd_ac97_template ac97;
@@ -827,22 +827,22 @@ static int __devinit snd_intel8x0_mixer(struct intel8x0m *chip, int ac97_clock)
827 int err; 827 int err;
828 unsigned int glob_sta = 0; 828 unsigned int glob_sta = 0;
829 static struct snd_ac97_bus_ops ops = { 829 static struct snd_ac97_bus_ops ops = {
830 .write = snd_intel8x0_codec_write, 830 .write = snd_intel8x0m_codec_write,
831 .read = snd_intel8x0_codec_read, 831 .read = snd_intel8x0m_codec_read,
832 }; 832 };
833 833
834 chip->in_ac97_init = 1; 834 chip->in_ac97_init = 1;
835 835
836 memset(&ac97, 0, sizeof(ac97)); 836 memset(&ac97, 0, sizeof(ac97));
837 ac97.private_data = chip; 837 ac97.private_data = chip;
838 ac97.private_free = snd_intel8x0_mixer_free_ac97; 838 ac97.private_free = snd_intel8x0m_mixer_free_ac97;
839 ac97.scaps = AC97_SCAP_SKIP_AUDIO | AC97_SCAP_POWER_SAVE; 839 ac97.scaps = AC97_SCAP_SKIP_AUDIO | AC97_SCAP_POWER_SAVE;
840 840
841 glob_sta = igetdword(chip, ICHREG(GLOB_STA)); 841 glob_sta = igetdword(chip, ICHREG(GLOB_STA));
842 842
843 if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &pbus)) < 0) 843 if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &pbus)) < 0)
844 goto __err; 844 goto __err;
845 pbus->private_free = snd_intel8x0_mixer_free_ac97_bus; 845 pbus->private_free = snd_intel8x0m_mixer_free_ac97_bus;
846 if (ac97_clock >= 8000 && ac97_clock <= 48000) 846 if (ac97_clock >= 8000 && ac97_clock <= 48000)
847 pbus->clock = ac97_clock; 847 pbus->clock = ac97_clock;
848 chip->ac97_bus = pbus; 848 chip->ac97_bus = pbus;
@@ -894,7 +894,8 @@ static int snd_intel8x0m_ich_chip_init(struct intel8x0m *chip, int probing)
894 /* finish cold or do warm reset */ 894 /* finish cold or do warm reset */
895 cnt |= (cnt & ICH_AC97COLD) == 0 ? ICH_AC97COLD : ICH_AC97WARM; 895 cnt |= (cnt & ICH_AC97COLD) == 0 ? ICH_AC97COLD : ICH_AC97WARM;
896 iputdword(chip, ICHREG(GLOB_CNT), cnt); 896 iputdword(chip, ICHREG(GLOB_CNT), cnt);
897 end_time = (jiffies + (HZ / 4)) + 1; 897 usleep_range(500, 1000); /* give warm reset some time */
898 end_time = jiffies + HZ / 4;
898 do { 899 do {
899 if ((igetdword(chip, ICHREG(GLOB_CNT)) & ICH_AC97WARM) == 0) 900 if ((igetdword(chip, ICHREG(GLOB_CNT)) & ICH_AC97WARM) == 0)
900 goto __ok; 901 goto __ok;
@@ -959,7 +960,7 @@ static int snd_intel8x0m_ich_chip_init(struct intel8x0m *chip, int probing)
959 return 0; 960 return 0;
960} 961}
961 962
962static int snd_intel8x0_chip_init(struct intel8x0m *chip, int probing) 963static int snd_intel8x0m_chip_init(struct intel8x0m *chip, int probing)
963{ 964{
964 unsigned int i; 965 unsigned int i;
965 int err; 966 int err;
@@ -980,7 +981,7 @@ static int snd_intel8x0_chip_init(struct intel8x0m *chip, int probing)
980 return 0; 981 return 0;
981} 982}
982 983
983static int snd_intel8x0_free(struct intel8x0m *chip) 984static int snd_intel8x0m_free(struct intel8x0m *chip)
984{ 985{
985 unsigned int i; 986 unsigned int i;
986 987
@@ -1045,7 +1046,7 @@ static int intel8x0m_resume(struct pci_dev *pci)
1045 return -EIO; 1046 return -EIO;
1046 } 1047 }
1047 pci_set_master(pci); 1048 pci_set_master(pci);
1048 if (request_irq(pci->irq, snd_intel8x0_interrupt, 1049 if (request_irq(pci->irq, snd_intel8x0m_interrupt,
1049 IRQF_SHARED, card->shortname, chip)) { 1050 IRQF_SHARED, card->shortname, chip)) {
1050 printk(KERN_ERR "intel8x0m: unable to grab IRQ %d, " 1051 printk(KERN_ERR "intel8x0m: unable to grab IRQ %d, "
1051 "disabling device\n", pci->irq); 1052 "disabling device\n", pci->irq);
@@ -1053,7 +1054,7 @@ static int intel8x0m_resume(struct pci_dev *pci)
1053 return -EIO; 1054 return -EIO;
1054 } 1055 }
1055 chip->irq = pci->irq; 1056 chip->irq = pci->irq;
1056 snd_intel8x0_chip_init(chip, 0); 1057 snd_intel8x0m_chip_init(chip, 0);
1057 snd_ac97_resume(chip->ac97); 1058 snd_ac97_resume(chip->ac97);
1058 1059
1059 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 1060 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
@@ -1094,10 +1095,10 @@ static void __devinit snd_intel8x0m_proc_init(struct intel8x0m * chip)
1094#endif /* CONFIG_PROC_FS */ 1095#endif /* CONFIG_PROC_FS */
1095 1096
1096 1097
1097static int snd_intel8x0_dev_free(struct snd_device *device) 1098static int snd_intel8x0m_dev_free(struct snd_device *device)
1098{ 1099{
1099 struct intel8x0m *chip = device->device_data; 1100 struct intel8x0m *chip = device->device_data;
1100 return snd_intel8x0_free(chip); 1101 return snd_intel8x0m_free(chip);
1101} 1102}
1102 1103
1103struct ich_reg_info { 1104struct ich_reg_info {
@@ -1108,7 +1109,7 @@ struct ich_reg_info {
1108static int __devinit snd_intel8x0m_create(struct snd_card *card, 1109static int __devinit snd_intel8x0m_create(struct snd_card *card,
1109 struct pci_dev *pci, 1110 struct pci_dev *pci,
1110 unsigned long device_type, 1111 unsigned long device_type,
1111 struct intel8x0m ** r_intel8x0) 1112 struct intel8x0m **r_intel8x0m)
1112{ 1113{
1113 struct intel8x0m *chip; 1114 struct intel8x0m *chip;
1114 int err; 1115 int err;
@@ -1116,7 +1117,7 @@ static int __devinit snd_intel8x0m_create(struct snd_card *card,
1116 unsigned int int_sta_masks; 1117 unsigned int int_sta_masks;
1117 struct ichdev *ichdev; 1118 struct ichdev *ichdev;
1118 static struct snd_device_ops ops = { 1119 static struct snd_device_ops ops = {
1119 .dev_free = snd_intel8x0_dev_free, 1120 .dev_free = snd_intel8x0m_dev_free,
1120 }; 1121 };
1121 static struct ich_reg_info intel_regs[2] = { 1122 static struct ich_reg_info intel_regs[2] = {
1122 { ICH_MIINT, 0 }, 1123 { ICH_MIINT, 0 },
@@ -1124,7 +1125,7 @@ static int __devinit snd_intel8x0m_create(struct snd_card *card,
1124 }; 1125 };
1125 struct ich_reg_info *tbl; 1126 struct ich_reg_info *tbl;
1126 1127
1127 *r_intel8x0 = NULL; 1128 *r_intel8x0m = NULL;
1128 1129
1129 if ((err = pci_enable_device(pci)) < 0) 1130 if ((err = pci_enable_device(pci)) < 0)
1130 return err; 1131 return err;
@@ -1158,7 +1159,7 @@ static int __devinit snd_intel8x0m_create(struct snd_card *card,
1158 chip->addr = pci_iomap(pci, 0, 0); 1159 chip->addr = pci_iomap(pci, 0, 0);
1159 if (!chip->addr) { 1160 if (!chip->addr) {
1160 snd_printk(KERN_ERR "AC'97 space ioremap problem\n"); 1161 snd_printk(KERN_ERR "AC'97 space ioremap problem\n");
1161 snd_intel8x0_free(chip); 1162 snd_intel8x0m_free(chip);
1162 return -EIO; 1163 return -EIO;
1163 } 1164 }
1164 if (pci_resource_flags(pci, 3) & IORESOURCE_MEM) /* ICH4 */ 1165 if (pci_resource_flags(pci, 3) & IORESOURCE_MEM) /* ICH4 */
@@ -1167,15 +1168,15 @@ static int __devinit snd_intel8x0m_create(struct snd_card *card,
1167 chip->bmaddr = pci_iomap(pci, 1, 0); 1168 chip->bmaddr = pci_iomap(pci, 1, 0);
1168 if (!chip->bmaddr) { 1169 if (!chip->bmaddr) {
1169 snd_printk(KERN_ERR "Controller space ioremap problem\n"); 1170 snd_printk(KERN_ERR "Controller space ioremap problem\n");
1170 snd_intel8x0_free(chip); 1171 snd_intel8x0m_free(chip);
1171 return -EIO; 1172 return -EIO;
1172 } 1173 }
1173 1174
1174 port_inited: 1175 port_inited:
1175 if (request_irq(pci->irq, snd_intel8x0_interrupt, IRQF_SHARED, 1176 if (request_irq(pci->irq, snd_intel8x0m_interrupt, IRQF_SHARED,
1176 card->shortname, chip)) { 1177 card->shortname, chip)) {
1177 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); 1178 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
1178 snd_intel8x0_free(chip); 1179 snd_intel8x0m_free(chip);
1179 return -EBUSY; 1180 return -EBUSY;
1180 } 1181 }
1181 chip->irq = pci->irq; 1182 chip->irq = pci->irq;
@@ -1210,7 +1211,7 @@ static int __devinit snd_intel8x0m_create(struct snd_card *card,
1210 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), 1211 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
1211 chip->bdbars_count * sizeof(u32) * ICH_MAX_FRAGS * 2, 1212 chip->bdbars_count * sizeof(u32) * ICH_MAX_FRAGS * 2,
1212 &chip->bdbars) < 0) { 1213 &chip->bdbars) < 0) {
1213 snd_intel8x0_free(chip); 1214 snd_intel8x0m_free(chip);
1214 return -ENOMEM; 1215 return -ENOMEM;
1215 } 1216 }
1216 /* tables must be aligned to 8 bytes here, but the kernel pages 1217 /* tables must be aligned to 8 bytes here, but the kernel pages
@@ -1225,19 +1226,19 @@ static int __devinit snd_intel8x0m_create(struct snd_card *card,
1225 chip->int_sta_reg = ICH_REG_GLOB_STA; 1226 chip->int_sta_reg = ICH_REG_GLOB_STA;
1226 chip->int_sta_mask = int_sta_masks; 1227 chip->int_sta_mask = int_sta_masks;
1227 1228
1228 if ((err = snd_intel8x0_chip_init(chip, 1)) < 0) { 1229 if ((err = snd_intel8x0m_chip_init(chip, 1)) < 0) {
1229 snd_intel8x0_free(chip); 1230 snd_intel8x0m_free(chip);
1230 return err; 1231 return err;
1231 } 1232 }
1232 1233
1233 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { 1234 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
1234 snd_intel8x0_free(chip); 1235 snd_intel8x0m_free(chip);
1235 return err; 1236 return err;
1236 } 1237 }
1237 1238
1238 snd_card_set_dev(card, &pci->dev); 1239 snd_card_set_dev(card, &pci->dev);
1239 1240
1240 *r_intel8x0 = chip; 1241 *r_intel8x0m = chip;
1241 return 0; 1242 return 0;
1242} 1243}
1243 1244
@@ -1295,11 +1296,11 @@ static int __devinit snd_intel8x0m_probe(struct pci_dev *pci,
1295 } 1296 }
1296 card->private_data = chip; 1297 card->private_data = chip;
1297 1298
1298 if ((err = snd_intel8x0_mixer(chip, ac97_clock)) < 0) { 1299 if ((err = snd_intel8x0m_mixer(chip, ac97_clock)) < 0) {
1299 snd_card_free(card); 1300 snd_card_free(card);
1300 return err; 1301 return err;
1301 } 1302 }
1302 if ((err = snd_intel8x0_pcm(chip)) < 0) { 1303 if ((err = snd_intel8x0m_pcm(chip)) < 0) {
1303 snd_card_free(card); 1304 snd_card_free(card);
1304 return err; 1305 return err;
1305 } 1306 }
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index f5eadfc0672a..a323eafb9e03 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -8,6 +8,21 @@
8 * Modified 2006-06-01 for AES32 support by Remy Bruno 8 * Modified 2006-06-01 for AES32 support by Remy Bruno
9 * <remy.bruno@trinnov.com> 9 * <remy.bruno@trinnov.com>
10 * 10 *
11 * Modified 2009-04-13 for proper metering by Florian Faber
12 * <faber@faberman.de>
13 *
14 * Modified 2009-04-14 for native float support by Florian Faber
15 * <faber@faberman.de>
16 *
17 * Modified 2009-04-26 fixed bug in rms metering by Florian Faber
18 * <faber@faberman.de>
19 *
20 * Modified 2009-04-30 added hw serial number support by Florian Faber
21 *
22 * Modified 2011-01-14 added S/PDIF input on RayDATs by Adrian Knoth
23 *
24 * Modified 2011-01-25 variable period sizes on RayDAT/AIO by Adrian Knoth
25 *
11 * This program is free software; you can redistribute it and/or modify 26 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by 27 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or 28 * the Free Software Foundation; either version 2 of the License, or
@@ -35,6 +50,7 @@
35#include <sound/core.h> 50#include <sound/core.h>
36#include <sound/control.h> 51#include <sound/control.h>
37#include <sound/pcm.h> 52#include <sound/pcm.h>
53#include <sound/pcm_params.h>
38#include <sound/info.h> 54#include <sound/info.h>
39#include <sound/asoundef.h> 55#include <sound/asoundef.h>
40#include <sound/rawmidi.h> 56#include <sound/rawmidi.h>
@@ -47,15 +63,6 @@ static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
47static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ 63static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
48static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */ 64static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */
49 65
50/* Disable precise pointer at start */
51static int precise_ptr[SNDRV_CARDS];
52
53/* Send all playback to line outs */
54static int line_outs_monitor[SNDRV_CARDS];
55
56/* Enable Analog Outs on Channel 63/64 by default */
57static int enable_monitor[SNDRV_CARDS];
58
59module_param_array(index, int, NULL, 0444); 66module_param_array(index, int, NULL, 0444);
60MODULE_PARM_DESC(index, "Index value for RME HDSPM interface."); 67MODULE_PARM_DESC(index, "Index value for RME HDSPM interface.");
61 68
@@ -65,42 +72,39 @@ MODULE_PARM_DESC(id, "ID string for RME HDSPM interface.");
65module_param_array(enable, bool, NULL, 0444); 72module_param_array(enable, bool, NULL, 0444);
66MODULE_PARM_DESC(enable, "Enable/disable specific HDSPM soundcards."); 73MODULE_PARM_DESC(enable, "Enable/disable specific HDSPM soundcards.");
67 74
68module_param_array(precise_ptr, bool, NULL, 0444);
69MODULE_PARM_DESC(precise_ptr, "Enable or disable precise pointer.");
70
71module_param_array(line_outs_monitor, bool, NULL, 0444);
72MODULE_PARM_DESC(line_outs_monitor,
73 "Send playback streams to analog outs by default.");
74
75module_param_array(enable_monitor, bool, NULL, 0444);
76MODULE_PARM_DESC(enable_monitor,
77 "Enable Analog Out on Channel 63/64 by default.");
78 75
79MODULE_AUTHOR 76MODULE_AUTHOR
80 ("Winfried Ritsch <ritsch_AT_iem.at>, " 77(
81 "Paul Davis <paul@linuxaudiosystems.com>, " 78 "Winfried Ritsch <ritsch_AT_iem.at>, "
82 "Marcus Andersson, Thomas Charbonnel <thomas@undata.org>, " 79 "Paul Davis <paul@linuxaudiosystems.com>, "
83 "Remy Bruno <remy.bruno@trinnov.com>"); 80 "Marcus Andersson, Thomas Charbonnel <thomas@undata.org>, "
81 "Remy Bruno <remy.bruno@trinnov.com>, "
82 "Florian Faber <faberman@linuxproaudio.org>, "
83 "Adrian Knoth <adi@drcomp.erfurt.thur.de>"
84);
84MODULE_DESCRIPTION("RME HDSPM"); 85MODULE_DESCRIPTION("RME HDSPM");
85MODULE_LICENSE("GPL"); 86MODULE_LICENSE("GPL");
86MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); 87MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
87 88
88/* --- Write registers. --- 89/* --- Write registers. ---
89 These are defined as byte-offsets from the iobase value. */ 90 These are defined as byte-offsets from the iobase value. */
90 91
92#define HDSPM_WR_SETTINGS 0
93#define HDSPM_outputBufferAddress 32
94#define HDSPM_inputBufferAddress 36
91#define HDSPM_controlRegister 64 95#define HDSPM_controlRegister 64
92#define HDSPM_interruptConfirmation 96 96#define HDSPM_interruptConfirmation 96
93#define HDSPM_control2Reg 256 /* not in specs ???????? */ 97#define HDSPM_control2Reg 256 /* not in specs ???????? */
94#define HDSPM_freqReg 256 /* for AES32 */ 98#define HDSPM_freqReg 256 /* for AES32 */
95#define HDSPM_midiDataOut0 352 /* just believe in old code */ 99#define HDSPM_midiDataOut0 352 /* just believe in old code */
96#define HDSPM_midiDataOut1 356 100#define HDSPM_midiDataOut1 356
97#define HDSPM_eeprom_wr 384 /* for AES32 */ 101#define HDSPM_eeprom_wr 384 /* for AES32 */
98 102
99/* DMA enable for 64 channels, only Bit 0 is relevant */ 103/* DMA enable for 64 channels, only Bit 0 is relevant */
100#define HDSPM_outputEnableBase 512 /* 512-767 input DMA */ 104#define HDSPM_outputEnableBase 512 /* 512-767 input DMA */
101#define HDSPM_inputEnableBase 768 /* 768-1023 output DMA */ 105#define HDSPM_inputEnableBase 768 /* 768-1023 output DMA */
102 106
103/* 16 page addresses for each of the 64 channels DMA buffer in and out 107/* 16 page addresses for each of the 64 channels DMA buffer in and out
104 (each 64k=16*4k) Buffer must be 4k aligned (which is default i386 ????) */ 108 (each 64k=16*4k) Buffer must be 4k aligned (which is default i386 ????) */
105#define HDSPM_pageAddressBufferOut 8192 109#define HDSPM_pageAddressBufferOut 8192
106#define HDSPM_pageAddressBufferIn (HDSPM_pageAddressBufferOut+64*16*4) 110#define HDSPM_pageAddressBufferIn (HDSPM_pageAddressBufferOut+64*16*4)
@@ -119,22 +123,84 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
119#define HDSPM_statusRegister2 192 123#define HDSPM_statusRegister2 192
120#define HDSPM_timecodeRegister 128 124#define HDSPM_timecodeRegister 128
121 125
126/* AIO, RayDAT */
127#define HDSPM_RD_STATUS_0 0
128#define HDSPM_RD_STATUS_1 64
129#define HDSPM_RD_STATUS_2 128
130#define HDSPM_RD_STATUS_3 192
131
132#define HDSPM_RD_TCO 256
133#define HDSPM_RD_PLL_FREQ 512
134#define HDSPM_WR_TCO 128
135
136#define HDSPM_TCO1_TCO_lock 0x00000001
137#define HDSPM_TCO1_WCK_Input_Range_LSB 0x00000002
138#define HDSPM_TCO1_WCK_Input_Range_MSB 0x00000004
139#define HDSPM_TCO1_LTC_Input_valid 0x00000008
140#define HDSPM_TCO1_WCK_Input_valid 0x00000010
141#define HDSPM_TCO1_Video_Input_Format_NTSC 0x00000020
142#define HDSPM_TCO1_Video_Input_Format_PAL 0x00000040
143
144#define HDSPM_TCO1_set_TC 0x00000100
145#define HDSPM_TCO1_set_drop_frame_flag 0x00000200
146#define HDSPM_TCO1_LTC_Format_LSB 0x00000400
147#define HDSPM_TCO1_LTC_Format_MSB 0x00000800
148
149#define HDSPM_TCO2_TC_run 0x00010000
150#define HDSPM_TCO2_WCK_IO_ratio_LSB 0x00020000
151#define HDSPM_TCO2_WCK_IO_ratio_MSB 0x00040000
152#define HDSPM_TCO2_set_num_drop_frames_LSB 0x00080000
153#define HDSPM_TCO2_set_num_drop_frames_MSB 0x00100000
154#define HDSPM_TCO2_set_jam_sync 0x00200000
155#define HDSPM_TCO2_set_flywheel 0x00400000
156
157#define HDSPM_TCO2_set_01_4 0x01000000
158#define HDSPM_TCO2_set_pull_down 0x02000000
159#define HDSPM_TCO2_set_pull_up 0x04000000
160#define HDSPM_TCO2_set_freq 0x08000000
161#define HDSPM_TCO2_set_term_75R 0x10000000
162#define HDSPM_TCO2_set_input_LSB 0x20000000
163#define HDSPM_TCO2_set_input_MSB 0x40000000
164#define HDSPM_TCO2_set_freq_from_app 0x80000000
165
166
167#define HDSPM_midiDataOut0 352
168#define HDSPM_midiDataOut1 356
169#define HDSPM_midiDataOut2 368
170
122#define HDSPM_midiDataIn0 360 171#define HDSPM_midiDataIn0 360
123#define HDSPM_midiDataIn1 364 172#define HDSPM_midiDataIn1 364
173#define HDSPM_midiDataIn2 372
174#define HDSPM_midiDataIn3 376
124 175
125/* status is data bytes in MIDI-FIFO (0-128) */ 176/* status is data bytes in MIDI-FIFO (0-128) */
126#define HDSPM_midiStatusOut0 384 177#define HDSPM_midiStatusOut0 384
127#define HDSPM_midiStatusOut1 388 178#define HDSPM_midiStatusOut1 388
128#define HDSPM_midiStatusIn0 392 179#define HDSPM_midiStatusOut2 400
129#define HDSPM_midiStatusIn1 396 180
181#define HDSPM_midiStatusIn0 392
182#define HDSPM_midiStatusIn1 396
183#define HDSPM_midiStatusIn2 404
184#define HDSPM_midiStatusIn3 408
130 185
131 186
132/* the meters are regular i/o-mapped registers, but offset 187/* the meters are regular i/o-mapped registers, but offset
133 considerably from the rest. the peak registers are reset 188 considerably from the rest. the peak registers are reset
134 when read; the least-significant 4 bits are full-scale counters; 189 when read; the least-significant 4 bits are full-scale counters;
135 the actual peak value is in the most-significant 24 bits. 190 the actual peak value is in the most-significant 24 bits.
136*/ 191*/
137#define HDSPM_MADI_peakrmsbase 4096 /* 4096-8191 2x64x32Bit Meters */ 192
193#define HDSPM_MADI_INPUT_PEAK 4096
194#define HDSPM_MADI_PLAYBACK_PEAK 4352
195#define HDSPM_MADI_OUTPUT_PEAK 4608
196
197#define HDSPM_MADI_INPUT_RMS_L 6144
198#define HDSPM_MADI_PLAYBACK_RMS_L 6400
199#define HDSPM_MADI_OUTPUT_RMS_L 6656
200
201#define HDSPM_MADI_INPUT_RMS_H 7168
202#define HDSPM_MADI_PLAYBACK_RMS_H 7424
203#define HDSPM_MADI_OUTPUT_RMS_H 7680
138 204
139/* --- Control Register bits --------- */ 205/* --- Control Register bits --------- */
140#define HDSPM_Start (1<<0) /* start engine */ 206#define HDSPM_Start (1<<0) /* start engine */
@@ -143,7 +209,9 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
143#define HDSPM_Latency1 (1<<2) /* where n is defined */ 209#define HDSPM_Latency1 (1<<2) /* where n is defined */
144#define HDSPM_Latency2 (1<<3) /* by Latency{2,1,0} */ 210#define HDSPM_Latency2 (1<<3) /* by Latency{2,1,0} */
145 211
146#define HDSPM_ClockModeMaster (1<<4) /* 1=Master, 0=Slave/Autosync */ 212#define HDSPM_ClockModeMaster (1<<4) /* 1=Master, 0=Autosync */
213#define HDSPM_c0Master 0x1 /* Master clock bit in settings
214 register [RayDAT, AIO] */
147 215
148#define HDSPM_AudioInterruptEnable (1<<5) /* what do you think ? */ 216#define HDSPM_AudioInterruptEnable (1<<5) /* what do you think ? */
149 217
@@ -157,7 +225,7 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
157 56channelMODE=0 */ /* MADI ONLY*/ 225 56channelMODE=0 */ /* MADI ONLY*/
158#define HDSPM_Emphasis (1<<10) /* Emphasis */ /* AES32 ONLY */ 226#define HDSPM_Emphasis (1<<10) /* Emphasis */ /* AES32 ONLY */
159 227
160#define HDSPM_AutoInp (1<<11) /* Auto Input (takeover) == Safe Mode, 228#define HDSPM_AutoInp (1<<11) /* Auto Input (takeover) == Safe Mode,
161 0=off, 1=on */ /* MADI ONLY */ 229 0=off, 1=on */ /* MADI ONLY */
162#define HDSPM_Dolby (1<<11) /* Dolby = "NonAudio" ?? */ /* AES32 ONLY */ 230#define HDSPM_Dolby (1<<11) /* Dolby = "NonAudio" ?? */ /* AES32 ONLY */
163 231
@@ -166,22 +234,23 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
166 */ 234 */
167#define HDSPM_InputSelect1 (1<<15) /* should be 0 */ 235#define HDSPM_InputSelect1 (1<<15) /* should be 0 */
168 236
169#define HDSPM_SyncRef0 (1<<16) /* 0=WOrd, 1=MADI */
170#define HDSPM_SyncRef1 (1<<17) /* for AES32: SyncRefN codes the AES # */
171#define HDSPM_SyncRef2 (1<<13) 237#define HDSPM_SyncRef2 (1<<13)
172#define HDSPM_SyncRef3 (1<<25) 238#define HDSPM_SyncRef3 (1<<25)
173 239
174#define HDSPM_SMUX (1<<18) /* Frame ??? */ /* MADI ONY */ 240#define HDSPM_SMUX (1<<18) /* Frame ??? */ /* MADI ONY */
175#define HDSPM_clr_tms (1<<19) /* clear track marker, do not use 241#define HDSPM_clr_tms (1<<19) /* clear track marker, do not use
176 AES additional bits in 242 AES additional bits in
177 lower 5 Audiodatabits ??? */ 243 lower 5 Audiodatabits ??? */
178#define HDSPM_taxi_reset (1<<20) /* ??? */ /* MADI ONLY ? */ 244#define HDSPM_taxi_reset (1<<20) /* ??? */ /* MADI ONLY ? */
179#define HDSPM_WCK48 (1<<20) /* Frame ??? = HDSPM_SMUX */ /* AES32 ONLY */ 245#define HDSPM_WCK48 (1<<20) /* Frame ??? = HDSPM_SMUX */ /* AES32 ONLY */
180 246
181#define HDSPM_Midi0InterruptEnable (1<<22) 247#define HDSPM_Midi0InterruptEnable 0x0400000
182#define HDSPM_Midi1InterruptEnable (1<<23) 248#define HDSPM_Midi1InterruptEnable 0x0800000
249#define HDSPM_Midi2InterruptEnable 0x0200000
250#define HDSPM_Midi3InterruptEnable 0x4000000
183 251
184#define HDSPM_LineOut (1<<24) /* Analog Out on channel 63/64 on=1, mute=0 */ 252#define HDSPM_LineOut (1<<24) /* Analog Out on channel 63/64 on=1, mute=0 */
253#define HDSPe_FLOAT_FORMAT 0x2000000
185 254
186#define HDSPM_DS_DoubleWire (1<<26) /* AES32 ONLY */ 255#define HDSPM_DS_DoubleWire (1<<26) /* AES32 ONLY */
187#define HDSPM_QS_DoubleWire (1<<27) /* AES32 ONLY */ 256#define HDSPM_QS_DoubleWire (1<<27) /* AES32 ONLY */
@@ -198,11 +267,18 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
198#define HDSPM_InputCoaxial (HDSPM_InputSelect0) 267#define HDSPM_InputCoaxial (HDSPM_InputSelect0)
199#define HDSPM_SyncRefMask (HDSPM_SyncRef0|HDSPM_SyncRef1|\ 268#define HDSPM_SyncRefMask (HDSPM_SyncRef0|HDSPM_SyncRef1|\
200 HDSPM_SyncRef2|HDSPM_SyncRef3) 269 HDSPM_SyncRef2|HDSPM_SyncRef3)
201#define HDSPM_SyncRef_Word 0
202#define HDSPM_SyncRef_MADI (HDSPM_SyncRef0)
203 270
204#define HDSPM_SYNC_FROM_WORD 0 /* Preferred sync reference */ 271#define HDSPM_c0_SyncRef0 0x2
205#define HDSPM_SYNC_FROM_MADI 1 /* choices - used by "pref_sync_ref" */ 272#define HDSPM_c0_SyncRef1 0x4
273#define HDSPM_c0_SyncRef2 0x8
274#define HDSPM_c0_SyncRef3 0x10
275#define HDSPM_c0_SyncRefMask (HDSPM_c0_SyncRef0 | HDSPM_c0_SyncRef1 |\
276 HDSPM_c0_SyncRef2 | HDSPM_c0_SyncRef3)
277
278#define HDSPM_SYNC_FROM_WORD 0 /* Preferred sync reference */
279#define HDSPM_SYNC_FROM_MADI 1 /* choices - used by "pref_sync_ref" */
280#define HDSPM_SYNC_FROM_TCO 2
281#define HDSPM_SYNC_FROM_SYNC_IN 3
206 282
207#define HDSPM_Frequency32KHz HDSPM_Frequency0 283#define HDSPM_Frequency32KHz HDSPM_Frequency0
208#define HDSPM_Frequency44_1KHz HDSPM_Frequency1 284#define HDSPM_Frequency44_1KHz HDSPM_Frequency1
@@ -216,17 +292,6 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
216#define HDSPM_Frequency192KHz (HDSPM_QuadSpeed|HDSPM_Frequency1|\ 292#define HDSPM_Frequency192KHz (HDSPM_QuadSpeed|HDSPM_Frequency1|\
217 HDSPM_Frequency0) 293 HDSPM_Frequency0)
218 294
219/* --- for internal discrimination */
220#define HDSPM_CLOCK_SOURCE_AUTOSYNC 0 /* Sample Clock Sources */
221#define HDSPM_CLOCK_SOURCE_INTERNAL_32KHZ 1
222#define HDSPM_CLOCK_SOURCE_INTERNAL_44_1KHZ 2
223#define HDSPM_CLOCK_SOURCE_INTERNAL_48KHZ 3
224#define HDSPM_CLOCK_SOURCE_INTERNAL_64KHZ 4
225#define HDSPM_CLOCK_SOURCE_INTERNAL_88_2KHZ 5
226#define HDSPM_CLOCK_SOURCE_INTERNAL_96KHZ 6
227#define HDSPM_CLOCK_SOURCE_INTERNAL_128KHZ 7
228#define HDSPM_CLOCK_SOURCE_INTERNAL_176_4KHZ 8
229#define HDSPM_CLOCK_SOURCE_INTERNAL_192KHZ 9
230 295
231/* Synccheck Status */ 296/* Synccheck Status */
232#define HDSPM_SYNC_CHECK_NO_LOCK 0 297#define HDSPM_SYNC_CHECK_NO_LOCK 0
@@ -236,14 +301,16 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
236/* AutoSync References - used by "autosync_ref" control switch */ 301/* AutoSync References - used by "autosync_ref" control switch */
237#define HDSPM_AUTOSYNC_FROM_WORD 0 302#define HDSPM_AUTOSYNC_FROM_WORD 0
238#define HDSPM_AUTOSYNC_FROM_MADI 1 303#define HDSPM_AUTOSYNC_FROM_MADI 1
239#define HDSPM_AUTOSYNC_FROM_NONE 2 304#define HDSPM_AUTOSYNC_FROM_TCO 2
305#define HDSPM_AUTOSYNC_FROM_SYNC_IN 3
306#define HDSPM_AUTOSYNC_FROM_NONE 4
240 307
241/* Possible sources of MADI input */ 308/* Possible sources of MADI input */
242#define HDSPM_OPTICAL 0 /* optical */ 309#define HDSPM_OPTICAL 0 /* optical */
243#define HDSPM_COAXIAL 1 /* BNC */ 310#define HDSPM_COAXIAL 1 /* BNC */
244 311
245#define hdspm_encode_latency(x) (((x)<<1) & HDSPM_LatencyMask) 312#define hdspm_encode_latency(x) (((x)<<1) & HDSPM_LatencyMask)
246#define hdspm_decode_latency(x) (((x) & HDSPM_LatencyMask)>>1) 313#define hdspm_decode_latency(x) ((((x) & HDSPM_LatencyMask)>>1))
247 314
248#define hdspm_encode_in(x) (((x)&0x3)<<14) 315#define hdspm_encode_in(x) (((x)&0x3)<<14)
249#define hdspm_decode_in(x) (((x)>>14)&0x3) 316#define hdspm_decode_in(x) (((x)>>14)&0x3)
@@ -270,13 +337,21 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
270#define HDSPM_AB_int (1<<2) /* InputChannel Opt=0, Coax=1 337#define HDSPM_AB_int (1<<2) /* InputChannel Opt=0, Coax=1
271 * (like inp0) 338 * (like inp0)
272 */ 339 */
340
273#define HDSPM_madiLock (1<<3) /* MADI Locked =1, no=0 */ 341#define HDSPM_madiLock (1<<3) /* MADI Locked =1, no=0 */
342#define HDSPM_madiSync (1<<18) /* MADI is in sync */
343
344#define HDSPM_tcoLock 0x00000020 /* Optional TCO locked status FOR HDSPe MADI! */
345#define HDSPM_tcoSync 0x10000000 /* Optional TCO sync status */
346
347#define HDSPM_syncInLock 0x00010000 /* Sync In lock status FOR HDSPe MADI! */
348#define HDSPM_syncInSync 0x00020000 /* Sync In sync status FOR HDSPe MADI! */
274 349
275#define HDSPM_BufferPositionMask 0x000FFC0 /* Bit 6..15 : h/w buffer pointer */ 350#define HDSPM_BufferPositionMask 0x000FFC0 /* Bit 6..15 : h/w buffer pointer */
276 /* since 64byte accurate last 6 bits 351 /* since 64byte accurate, last 6 bits are not used */
277 are not used */ 352
353
278 354
279#define HDSPM_madiSync (1<<18) /* MADI is in sync */
280#define HDSPM_DoubleSpeedStatus (1<<19) /* (input) card in double speed */ 355#define HDSPM_DoubleSpeedStatus (1<<19) /* (input) card in double speed */
281 356
282#define HDSPM_madiFreq0 (1<<22) /* system freq 0=error */ 357#define HDSPM_madiFreq0 (1<<22) /* system freq 0=error */
@@ -287,8 +362,19 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
287#define HDSPM_BufferID (1<<26) /* (Double)Buffer ID toggles with 362#define HDSPM_BufferID (1<<26) /* (Double)Buffer ID toggles with
288 * Interrupt 363 * Interrupt
289 */ 364 */
290#define HDSPM_midi0IRQPending (1<<30) /* MIDI IRQ is pending */ 365#define HDSPM_tco_detect 0x08000000
291#define HDSPM_midi1IRQPending (1<<31) /* and aktiv */ 366#define HDSPM_tco_lock 0x20000000
367
368#define HDSPM_s2_tco_detect 0x00000040
369#define HDSPM_s2_AEBO_D 0x00000080
370#define HDSPM_s2_AEBI_D 0x00000100
371
372
373#define HDSPM_midi0IRQPending 0x40000000
374#define HDSPM_midi1IRQPending 0x80000000
375#define HDSPM_midi2IRQPending 0x20000000
376#define HDSPM_midi2IRQPendingAES 0x00000020
377#define HDSPM_midi3IRQPending 0x00200000
292 378
293/* --- status bit helpers */ 379/* --- status bit helpers */
294#define HDSPM_madiFreqMask (HDSPM_madiFreq0|HDSPM_madiFreq1|\ 380#define HDSPM_madiFreqMask (HDSPM_madiFreq0|HDSPM_madiFreq1|\
@@ -317,7 +403,10 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
317#define HDSPM_wc_freq2 (1<<7) /* 100=64, 101=88.2, 110=96, */ 403#define HDSPM_wc_freq2 (1<<7) /* 100=64, 101=88.2, 110=96, */
318/* missing Bit for 111=128, 1000=176.4, 1001=192 */ 404/* missing Bit for 111=128, 1000=176.4, 1001=192 */
319 405
320#define HDSPM_SelSyncRef0 (1<<8) /* Sync Source in slave mode */ 406#define HDSPM_SyncRef0 0x10000 /* Sync Reference */
407#define HDSPM_SyncRef1 0x20000
408
409#define HDSPM_SelSyncRef0 (1<<8) /* AutoSync Source */
321#define HDSPM_SelSyncRef1 (1<<9) /* 000=word, 001=MADI, */ 410#define HDSPM_SelSyncRef1 (1<<9) /* 000=word, 001=MADI, */
322#define HDSPM_SelSyncRef2 (1<<10) /* 111=no valid signal */ 411#define HDSPM_SelSyncRef2 (1<<10) /* 111=no valid signal */
323 412
@@ -331,11 +420,19 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
331#define HDSPM_wcFreq88_2 (HDSPM_wc_freq0|HDSPM_wc_freq2) 420#define HDSPM_wcFreq88_2 (HDSPM_wc_freq0|HDSPM_wc_freq2)
332#define HDSPM_wcFreq96 (HDSPM_wc_freq1|HDSPM_wc_freq2) 421#define HDSPM_wcFreq96 (HDSPM_wc_freq1|HDSPM_wc_freq2)
333 422
423#define HDSPM_status1_F_0 0x0400000
424#define HDSPM_status1_F_1 0x0800000
425#define HDSPM_status1_F_2 0x1000000
426#define HDSPM_status1_F_3 0x2000000
427#define HDSPM_status1_freqMask (HDSPM_status1_F_0|HDSPM_status1_F_1|HDSPM_status1_F_2|HDSPM_status1_F_3)
428
334 429
335#define HDSPM_SelSyncRefMask (HDSPM_SelSyncRef0|HDSPM_SelSyncRef1|\ 430#define HDSPM_SelSyncRefMask (HDSPM_SelSyncRef0|HDSPM_SelSyncRef1|\
336 HDSPM_SelSyncRef2) 431 HDSPM_SelSyncRef2)
337#define HDSPM_SelSyncRef_WORD 0 432#define HDSPM_SelSyncRef_WORD 0
338#define HDSPM_SelSyncRef_MADI (HDSPM_SelSyncRef0) 433#define HDSPM_SelSyncRef_MADI (HDSPM_SelSyncRef0)
434#define HDSPM_SelSyncRef_TCO (HDSPM_SelSyncRef1)
435#define HDSPM_SelSyncRef_SyncIn (HDSPM_SelSyncRef0|HDSPM_SelSyncRef1)
339#define HDSPM_SelSyncRef_NVALID (HDSPM_SelSyncRef0|HDSPM_SelSyncRef1|\ 436#define HDSPM_SelSyncRef_NVALID (HDSPM_SelSyncRef0|HDSPM_SelSyncRef1|\
340 HDSPM_SelSyncRef2) 437 HDSPM_SelSyncRef2)
341 438
@@ -345,7 +442,7 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
345/* status */ 442/* status */
346#define HDSPM_AES32_wcLock 0x0200000 443#define HDSPM_AES32_wcLock 0x0200000
347#define HDSPM_AES32_wcFreq_bit 22 444#define HDSPM_AES32_wcFreq_bit 22
348/* (status >> HDSPM_AES32_wcFreq_bit) & 0xF gives WC frequency (cf function 445/* (status >> HDSPM_AES32_wcFreq_bit) & 0xF gives WC frequency (cf function
349 HDSPM_bit2freq */ 446 HDSPM_bit2freq */
350#define HDSPM_AES32_syncref_bit 16 447#define HDSPM_AES32_syncref_bit 16
351/* (status >> HDSPM_AES32_syncref_bit) & 0xF gives sync source */ 448/* (status >> HDSPM_AES32_syncref_bit) & 0xF gives sync source */
@@ -398,28 +495,348 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
398#define MADI_DS_CHANNELS 32 495#define MADI_DS_CHANNELS 32
399#define MADI_QS_CHANNELS 16 496#define MADI_QS_CHANNELS 16
400 497
498#define RAYDAT_SS_CHANNELS 36
499#define RAYDAT_DS_CHANNELS 20
500#define RAYDAT_QS_CHANNELS 12
501
502#define AIO_IN_SS_CHANNELS 14
503#define AIO_IN_DS_CHANNELS 10
504#define AIO_IN_QS_CHANNELS 8
505#define AIO_OUT_SS_CHANNELS 16
506#define AIO_OUT_DS_CHANNELS 12
507#define AIO_OUT_QS_CHANNELS 10
508
509#define AES32_CHANNELS 16
510
401/* the size of a substream (1 mono data stream) */ 511/* the size of a substream (1 mono data stream) */
402#define HDSPM_CHANNEL_BUFFER_SAMPLES (16*1024) 512#define HDSPM_CHANNEL_BUFFER_SAMPLES (16*1024)
403#define HDSPM_CHANNEL_BUFFER_BYTES (4*HDSPM_CHANNEL_BUFFER_SAMPLES) 513#define HDSPM_CHANNEL_BUFFER_BYTES (4*HDSPM_CHANNEL_BUFFER_SAMPLES)
404 514
405/* the size of the area we need to allocate for DMA transfers. the 515/* the size of the area we need to allocate for DMA transfers. the
406 size is the same regardless of the number of channels, and 516 size is the same regardless of the number of channels, and
407 also the latency to use. 517 also the latency to use.
408 for one direction !!! 518 for one direction !!!
409*/ 519*/
410#define HDSPM_DMA_AREA_BYTES (HDSPM_MAX_CHANNELS * HDSPM_CHANNEL_BUFFER_BYTES) 520#define HDSPM_DMA_AREA_BYTES (HDSPM_MAX_CHANNELS * HDSPM_CHANNEL_BUFFER_BYTES)
411#define HDSPM_DMA_AREA_KILOBYTES (HDSPM_DMA_AREA_BYTES/1024) 521#define HDSPM_DMA_AREA_KILOBYTES (HDSPM_DMA_AREA_BYTES/1024)
412 522
413/* revisions >= 230 indicate AES32 card */ 523/* revisions >= 230 indicate AES32 card */
414#define HDSPM_AESREVISION 230 524#define HDSPM_MADI_REV 210
525#define HDSPM_RAYDAT_REV 211
526#define HDSPM_AIO_REV 212
527#define HDSPM_MADIFACE_REV 213
528#define HDSPM_AES_REV 240
529#define HDSPM_AES32_REV 234
530#define HDSPM_AES32_OLD_REV 233
415 531
416/* speed factor modes */ 532/* speed factor modes */
417#define HDSPM_SPEED_SINGLE 0 533#define HDSPM_SPEED_SINGLE 0
418#define HDSPM_SPEED_DOUBLE 1 534#define HDSPM_SPEED_DOUBLE 1
419#define HDSPM_SPEED_QUAD 2 535#define HDSPM_SPEED_QUAD 2
536
420/* names for speed modes */ 537/* names for speed modes */
421static char *hdspm_speed_names[] = { "single", "double", "quad" }; 538static char *hdspm_speed_names[] = { "single", "double", "quad" };
422 539
540static char *texts_autosync_aes_tco[] = { "Word Clock",
541 "AES1", "AES2", "AES3", "AES4",
542 "AES5", "AES6", "AES7", "AES8",
543 "TCO" };
544static char *texts_autosync_aes[] = { "Word Clock",
545 "AES1", "AES2", "AES3", "AES4",
546 "AES5", "AES6", "AES7", "AES8" };
547static char *texts_autosync_madi_tco[] = { "Word Clock",
548 "MADI", "TCO", "Sync In" };
549static char *texts_autosync_madi[] = { "Word Clock",
550 "MADI", "Sync In" };
551
552static char *texts_autosync_raydat_tco[] = {
553 "Word Clock",
554 "ADAT 1", "ADAT 2", "ADAT 3", "ADAT 4",
555 "AES", "SPDIF", "TCO", "Sync In"
556};
557static char *texts_autosync_raydat[] = {
558 "Word Clock",
559 "ADAT 1", "ADAT 2", "ADAT 3", "ADAT 4",
560 "AES", "SPDIF", "Sync In"
561};
562static char *texts_autosync_aio_tco[] = {
563 "Word Clock",
564 "ADAT", "AES", "SPDIF", "TCO", "Sync In"
565};
566static char *texts_autosync_aio[] = { "Word Clock",
567 "ADAT", "AES", "SPDIF", "Sync In" };
568
569static char *texts_freq[] = {
570 "No Lock",
571 "32 kHz",
572 "44.1 kHz",
573 "48 kHz",
574 "64 kHz",
575 "88.2 kHz",
576 "96 kHz",
577 "128 kHz",
578 "176.4 kHz",
579 "192 kHz"
580};
581
582static char *texts_ports_madi[] = {
583 "MADI.1", "MADI.2", "MADI.3", "MADI.4", "MADI.5", "MADI.6",
584 "MADI.7", "MADI.8", "MADI.9", "MADI.10", "MADI.11", "MADI.12",
585 "MADI.13", "MADI.14", "MADI.15", "MADI.16", "MADI.17", "MADI.18",
586 "MADI.19", "MADI.20", "MADI.21", "MADI.22", "MADI.23", "MADI.24",
587 "MADI.25", "MADI.26", "MADI.27", "MADI.28", "MADI.29", "MADI.30",
588 "MADI.31", "MADI.32", "MADI.33", "MADI.34", "MADI.35", "MADI.36",
589 "MADI.37", "MADI.38", "MADI.39", "MADI.40", "MADI.41", "MADI.42",
590 "MADI.43", "MADI.44", "MADI.45", "MADI.46", "MADI.47", "MADI.48",
591 "MADI.49", "MADI.50", "MADI.51", "MADI.52", "MADI.53", "MADI.54",
592 "MADI.55", "MADI.56", "MADI.57", "MADI.58", "MADI.59", "MADI.60",
593 "MADI.61", "MADI.62", "MADI.63", "MADI.64",
594};
595
596
597static char *texts_ports_raydat_ss[] = {
598 "ADAT1.1", "ADAT1.2", "ADAT1.3", "ADAT1.4", "ADAT1.5", "ADAT1.6",
599 "ADAT1.7", "ADAT1.8", "ADAT2.1", "ADAT2.2", "ADAT2.3", "ADAT2.4",
600 "ADAT2.5", "ADAT2.6", "ADAT2.7", "ADAT2.8", "ADAT3.1", "ADAT3.2",
601 "ADAT3.3", "ADAT3.4", "ADAT3.5", "ADAT3.6", "ADAT3.7", "ADAT3.8",
602 "ADAT4.1", "ADAT4.2", "ADAT4.3", "ADAT4.4", "ADAT4.5", "ADAT4.6",
603 "ADAT4.7", "ADAT4.8",
604 "AES.L", "AES.R",
605 "SPDIF.L", "SPDIF.R"
606};
607
608static char *texts_ports_raydat_ds[] = {
609 "ADAT1.1", "ADAT1.2", "ADAT1.3", "ADAT1.4",
610 "ADAT2.1", "ADAT2.2", "ADAT2.3", "ADAT2.4",
611 "ADAT3.1", "ADAT3.2", "ADAT3.3", "ADAT3.4",
612 "ADAT4.1", "ADAT4.2", "ADAT4.3", "ADAT4.4",
613 "AES.L", "AES.R",
614 "SPDIF.L", "SPDIF.R"
615};
616
617static char *texts_ports_raydat_qs[] = {
618 "ADAT1.1", "ADAT1.2",
619 "ADAT2.1", "ADAT2.2",
620 "ADAT3.1", "ADAT3.2",
621 "ADAT4.1", "ADAT4.2",
622 "AES.L", "AES.R",
623 "SPDIF.L", "SPDIF.R"
624};
625
626
627static char *texts_ports_aio_in_ss[] = {
628 "Analogue.L", "Analogue.R",
629 "AES.L", "AES.R",
630 "SPDIF.L", "SPDIF.R",
631 "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4", "ADAT.5", "ADAT.6",
632 "ADAT.7", "ADAT.8"
633};
634
635static char *texts_ports_aio_out_ss[] = {
636 "Analogue.L", "Analogue.R",
637 "AES.L", "AES.R",
638 "SPDIF.L", "SPDIF.R",
639 "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4", "ADAT.5", "ADAT.6",
640 "ADAT.7", "ADAT.8",
641 "Phone.L", "Phone.R"
642};
643
644static char *texts_ports_aio_in_ds[] = {
645 "Analogue.L", "Analogue.R",
646 "AES.L", "AES.R",
647 "SPDIF.L", "SPDIF.R",
648 "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4"
649};
650
651static char *texts_ports_aio_out_ds[] = {
652 "Analogue.L", "Analogue.R",
653 "AES.L", "AES.R",
654 "SPDIF.L", "SPDIF.R",
655 "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4",
656 "Phone.L", "Phone.R"
657};
658
659static char *texts_ports_aio_in_qs[] = {
660 "Analogue.L", "Analogue.R",
661 "AES.L", "AES.R",
662 "SPDIF.L", "SPDIF.R",
663 "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4"
664};
665
666static char *texts_ports_aio_out_qs[] = {
667 "Analogue.L", "Analogue.R",
668 "AES.L", "AES.R",
669 "SPDIF.L", "SPDIF.R",
670 "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4",
671 "Phone.L", "Phone.R"
672};
673
674static char *texts_ports_aes32[] = {
675 "AES.1", "AES.2", "AES.3", "AES.4", "AES.5", "AES.6", "AES.7",
676 "AES.8", "AES.9.", "AES.10", "AES.11", "AES.12", "AES.13", "AES.14",
677 "AES.15", "AES.16"
678};
679
680/* These tables map the ALSA channels 1..N to the channels that we
681 need to use in order to find the relevant channel buffer. RME
682 refers to this kind of mapping as between "the ADAT channel and
683 the DMA channel." We index it using the logical audio channel,
684 and the value is the DMA channel (i.e. channel buffer number)
685 where the data for that channel can be read/written from/to.
686*/
687
688static char channel_map_unity_ss[HDSPM_MAX_CHANNELS] = {
689 0, 1, 2, 3, 4, 5, 6, 7,
690 8, 9, 10, 11, 12, 13, 14, 15,
691 16, 17, 18, 19, 20, 21, 22, 23,
692 24, 25, 26, 27, 28, 29, 30, 31,
693 32, 33, 34, 35, 36, 37, 38, 39,
694 40, 41, 42, 43, 44, 45, 46, 47,
695 48, 49, 50, 51, 52, 53, 54, 55,
696 56, 57, 58, 59, 60, 61, 62, 63
697};
698
699static char channel_map_raydat_ss[HDSPM_MAX_CHANNELS] = {
700 4, 5, 6, 7, 8, 9, 10, 11, /* ADAT 1 */
701 12, 13, 14, 15, 16, 17, 18, 19, /* ADAT 2 */
702 20, 21, 22, 23, 24, 25, 26, 27, /* ADAT 3 */
703 28, 29, 30, 31, 32, 33, 34, 35, /* ADAT 4 */
704 0, 1, /* AES */
705 2, 3, /* SPDIF */
706 -1, -1, -1, -1,
707 -1, -1, -1, -1, -1, -1, -1, -1,
708 -1, -1, -1, -1, -1, -1, -1, -1,
709 -1, -1, -1, -1, -1, -1, -1, -1,
710};
711
712static char channel_map_raydat_ds[HDSPM_MAX_CHANNELS] = {
713 4, 5, 6, 7, /* ADAT 1 */
714 8, 9, 10, 11, /* ADAT 2 */
715 12, 13, 14, 15, /* ADAT 3 */
716 16, 17, 18, 19, /* ADAT 4 */
717 0, 1, /* AES */
718 2, 3, /* SPDIF */
719 -1, -1, -1, -1,
720 -1, -1, -1, -1, -1, -1, -1, -1,
721 -1, -1, -1, -1, -1, -1, -1, -1,
722 -1, -1, -1, -1, -1, -1, -1, -1,
723 -1, -1, -1, -1, -1, -1, -1, -1,
724 -1, -1, -1, -1, -1, -1, -1, -1,
725};
726
727static char channel_map_raydat_qs[HDSPM_MAX_CHANNELS] = {
728 4, 5, /* ADAT 1 */
729 6, 7, /* ADAT 2 */
730 8, 9, /* ADAT 3 */
731 10, 11, /* ADAT 4 */
732 0, 1, /* AES */
733 2, 3, /* SPDIF */
734 -1, -1, -1, -1,
735 -1, -1, -1, -1, -1, -1, -1, -1,
736 -1, -1, -1, -1, -1, -1, -1, -1,
737 -1, -1, -1, -1, -1, -1, -1, -1,
738 -1, -1, -1, -1, -1, -1, -1, -1,
739 -1, -1, -1, -1, -1, -1, -1, -1,
740 -1, -1, -1, -1, -1, -1, -1, -1,
741};
742
743static char channel_map_aio_in_ss[HDSPM_MAX_CHANNELS] = {
744 0, 1, /* line in */
745 8, 9, /* aes in, */
746 10, 11, /* spdif in */
747 12, 13, 14, 15, 16, 17, 18, 19, /* ADAT in */
748 -1, -1,
749 -1, -1, -1, -1, -1, -1, -1, -1,
750 -1, -1, -1, -1, -1, -1, -1, -1,
751 -1, -1, -1, -1, -1, -1, -1, -1,
752 -1, -1, -1, -1, -1, -1, -1, -1,
753 -1, -1, -1, -1, -1, -1, -1, -1,
754 -1, -1, -1, -1, -1, -1, -1, -1,
755};
756
757static char channel_map_aio_out_ss[HDSPM_MAX_CHANNELS] = {
758 0, 1, /* line out */
759 8, 9, /* aes out */
760 10, 11, /* spdif out */
761 12, 13, 14, 15, 16, 17, 18, 19, /* ADAT out */
762 6, 7, /* phone out */
763 -1, -1, -1, -1, -1, -1, -1, -1,
764 -1, -1, -1, -1, -1, -1, -1, -1,
765 -1, -1, -1, -1, -1, -1, -1, -1,
766 -1, -1, -1, -1, -1, -1, -1, -1,
767 -1, -1, -1, -1, -1, -1, -1, -1,
768 -1, -1, -1, -1, -1, -1, -1, -1,
769};
770
771static char channel_map_aio_in_ds[HDSPM_MAX_CHANNELS] = {
772 0, 1, /* line in */
773 8, 9, /* aes in */
774 10, 11, /* spdif in */
775 12, 14, 16, 18, /* adat in */
776 -1, -1, -1, -1, -1, -1,
777 -1, -1, -1, -1, -1, -1, -1, -1,
778 -1, -1, -1, -1, -1, -1, -1, -1,
779 -1, -1, -1, -1, -1, -1, -1, -1,
780 -1, -1, -1, -1, -1, -1, -1, -1,
781 -1, -1, -1, -1, -1, -1, -1, -1,
782 -1, -1, -1, -1, -1, -1, -1, -1
783};
784
785static char channel_map_aio_out_ds[HDSPM_MAX_CHANNELS] = {
786 0, 1, /* line out */
787 8, 9, /* aes out */
788 10, 11, /* spdif out */
789 12, 14, 16, 18, /* adat out */
790 6, 7, /* phone out */
791 -1, -1, -1, -1,
792 -1, -1, -1, -1, -1, -1, -1, -1,
793 -1, -1, -1, -1, -1, -1, -1, -1,
794 -1, -1, -1, -1, -1, -1, -1, -1,
795 -1, -1, -1, -1, -1, -1, -1, -1,
796 -1, -1, -1, -1, -1, -1, -1, -1,
797 -1, -1, -1, -1, -1, -1, -1, -1
798};
799
800static char channel_map_aio_in_qs[HDSPM_MAX_CHANNELS] = {
801 0, 1, /* line in */
802 8, 9, /* aes in */
803 10, 11, /* spdif in */
804 12, 16, /* adat in */
805 -1, -1, -1, -1, -1, -1, -1, -1,
806 -1, -1, -1, -1, -1, -1, -1, -1,
807 -1, -1, -1, -1, -1, -1, -1, -1,
808 -1, -1, -1, -1, -1, -1, -1, -1,
809 -1, -1, -1, -1, -1, -1, -1, -1,
810 -1, -1, -1, -1, -1, -1, -1, -1,
811 -1, -1, -1, -1, -1, -1, -1, -1
812};
813
814static char channel_map_aio_out_qs[HDSPM_MAX_CHANNELS] = {
815 0, 1, /* line out */
816 8, 9, /* aes out */
817 10, 11, /* spdif out */
818 12, 16, /* adat out */
819 6, 7, /* phone out */
820 -1, -1, -1, -1, -1, -1,
821 -1, -1, -1, -1, -1, -1, -1, -1,
822 -1, -1, -1, -1, -1, -1, -1, -1,
823 -1, -1, -1, -1, -1, -1, -1, -1,
824 -1, -1, -1, -1, -1, -1, -1, -1,
825 -1, -1, -1, -1, -1, -1, -1, -1,
826 -1, -1, -1, -1, -1, -1, -1, -1
827};
828
829static char channel_map_aes32[HDSPM_MAX_CHANNELS] = {
830 0, 1, 2, 3, 4, 5, 6, 7,
831 8, 9, 10, 11, 12, 13, 14, 15,
832 -1, -1, -1, -1, -1, -1, -1, -1,
833 -1, -1, -1, -1, -1, -1, -1, -1,
834 -1, -1, -1, -1, -1, -1, -1, -1,
835 -1, -1, -1, -1, -1, -1, -1, -1,
836 -1, -1, -1, -1, -1, -1, -1, -1,
837 -1, -1, -1, -1, -1, -1, -1, -1
838};
839
423struct hdspm_midi { 840struct hdspm_midi {
424 struct hdspm *hdspm; 841 struct hdspm *hdspm;
425 int id; 842 int id;
@@ -430,6 +847,21 @@ struct hdspm_midi {
430 struct timer_list timer; 847 struct timer_list timer;
431 spinlock_t lock; 848 spinlock_t lock;
432 int pending; 849 int pending;
850 int dataIn;
851 int statusIn;
852 int dataOut;
853 int statusOut;
854 int ie;
855 int irq;
856};
857
858struct hdspm_tco {
859 int input;
860 int framerate;
861 int wordclock;
862 int samplerate;
863 int pull;
864 int term; /* 0 = off, 1 = on */
433}; 865};
434 866
435struct hdspm { 867struct hdspm {
@@ -441,21 +873,39 @@ struct hdspm {
441 char *card_name; /* for procinfo */ 873 char *card_name; /* for procinfo */
442 unsigned short firmware_rev; /* dont know if relevant (yes if AES32)*/ 874 unsigned short firmware_rev; /* dont know if relevant (yes if AES32)*/
443 875
444 unsigned char is_aes32; /* indicates if card is AES32 */ 876 uint8_t io_type;
445 877
446 int precise_ptr; /* use precise pointers, to be tested */
447 int monitor_outs; /* set up monitoring outs init flag */ 878 int monitor_outs; /* set up monitoring outs init flag */
448 879
449 u32 control_register; /* cached value */ 880 u32 control_register; /* cached value */
450 u32 control2_register; /* cached value */ 881 u32 control2_register; /* cached value */
882 u32 settings_register;
451 883
452 struct hdspm_midi midi[2]; 884 struct hdspm_midi midi[4];
453 struct tasklet_struct midi_tasklet; 885 struct tasklet_struct midi_tasklet;
454 886
455 size_t period_bytes; 887 size_t period_bytes;
456 unsigned char ss_channels; /* channels of card in single speed */ 888 unsigned char ss_in_channels;
457 unsigned char ds_channels; /* Double Speed */ 889 unsigned char ds_in_channels;
458 unsigned char qs_channels; /* Quad Speed */ 890 unsigned char qs_in_channels;
891 unsigned char ss_out_channels;
892 unsigned char ds_out_channels;
893 unsigned char qs_out_channels;
894
895 unsigned char max_channels_in;
896 unsigned char max_channels_out;
897
898 char *channel_map_in;
899 char *channel_map_out;
900
901 char *channel_map_in_ss, *channel_map_in_ds, *channel_map_in_qs;
902 char *channel_map_out_ss, *channel_map_out_ds, *channel_map_out_qs;
903
904 char **port_names_in;
905 char **port_names_out;
906
907 char **port_names_in_ss, **port_names_in_ds, **port_names_in_qs;
908 char **port_names_out_ss, **port_names_out_ds, **port_names_out_qs;
459 909
460 unsigned char *playback_buffer; /* suitably aligned address */ 910 unsigned char *playback_buffer; /* suitably aligned address */
461 unsigned char *capture_buffer; /* suitably aligned address */ 911 unsigned char *capture_buffer; /* suitably aligned address */
@@ -468,14 +918,13 @@ struct hdspm {
468 int last_internal_sample_rate; 918 int last_internal_sample_rate;
469 int system_sample_rate; 919 int system_sample_rate;
470 920
471 char *channel_map; /* channel map for DS and Quadspeed */
472
473 int dev; /* Hardware vars... */ 921 int dev; /* Hardware vars... */
474 int irq; 922 int irq;
475 unsigned long port; 923 unsigned long port;
476 void __iomem *iobase; 924 void __iomem *iobase;
477 925
478 int irq_count; /* for debug */ 926 int irq_count; /* for debug */
927 int midiPorts;
479 928
480 struct snd_card *card; /* one card */ 929 struct snd_card *card; /* one card */
481 struct snd_pcm *pcm; /* has one pcm */ 930 struct snd_pcm *pcm; /* has one pcm */
@@ -487,28 +936,17 @@ struct hdspm {
487 struct snd_kcontrol *playback_mixer_ctls[HDSPM_MAX_CHANNELS]; 936 struct snd_kcontrol *playback_mixer_ctls[HDSPM_MAX_CHANNELS];
488 /* but input to much, so not used */ 937 /* but input to much, so not used */
489 struct snd_kcontrol *input_mixer_ctls[HDSPM_MAX_CHANNELS]; 938 struct snd_kcontrol *input_mixer_ctls[HDSPM_MAX_CHANNELS];
490 /* full mixer accessible over mixer ioctl or hwdep-device */ 939 /* full mixer accessable over mixer ioctl or hwdep-device */
491 struct hdspm_mixer *mixer; 940 struct hdspm_mixer *mixer;
492 941
493}; 942 struct hdspm_tco *tco; /* NULL if no TCO detected */
494 943
495/* These tables map the ALSA channels 1..N to the channels that we 944 char **texts_autosync;
496 need to use in order to find the relevant channel buffer. RME 945 int texts_autosync_items;
497 refer to this kind of mapping as between "the ADAT channel and 946
498 the DMA channel." We index it using the logical audio channel, 947 cycles_t last_interrupt;
499 and the value is the DMA channel (i.e. channel buffer number)
500 where the data for that channel can be read/written from/to.
501*/
502 948
503static char channel_map_madi_ss[HDSPM_MAX_CHANNELS] = { 949 struct hdspm_peak_rms peak_rms;
504 0, 1, 2, 3, 4, 5, 6, 7,
505 8, 9, 10, 11, 12, 13, 14, 15,
506 16, 17, 18, 19, 20, 21, 22, 23,
507 24, 25, 26, 27, 28, 29, 30, 31,
508 32, 33, 34, 35, 36, 37, 38, 39,
509 40, 41, 42, 43, 44, 45, 46, 47,
510 48, 49, 50, 51, 52, 53, 54, 55,
511 56, 57, 58, 59, 60, 61, 62, 63
512}; 950};
513 951
514 952
@@ -532,11 +970,11 @@ static int __devinit snd_hdspm_create_alsa_devices(struct snd_card *card,
532static int __devinit snd_hdspm_create_pcm(struct snd_card *card, 970static int __devinit snd_hdspm_create_pcm(struct snd_card *card,
533 struct hdspm * hdspm); 971 struct hdspm * hdspm);
534 972
535static inline void snd_hdspm_initialize_midi_flush(struct hdspm * hdspm); 973static inline void snd_hdspm_initialize_midi_flush(struct hdspm *hdspm);
536static int hdspm_update_simple_mixer_controls(struct hdspm * hdspm); 974static int hdspm_update_simple_mixer_controls(struct hdspm *hdspm);
537static int hdspm_autosync_ref(struct hdspm * hdspm); 975static int hdspm_autosync_ref(struct hdspm *hdspm);
538static int snd_hdspm_set_defaults(struct hdspm * hdspm); 976static int snd_hdspm_set_defaults(struct hdspm *hdspm);
539static void hdspm_set_sgbuf(struct hdspm * hdspm, 977static void hdspm_set_sgbuf(struct hdspm *hdspm,
540 struct snd_pcm_substream *substream, 978 struct snd_pcm_substream *substream,
541 unsigned int reg, int channels); 979 unsigned int reg, int channels);
542 980
@@ -550,7 +988,7 @@ static inline int HDSPM_bit2freq(int n)
550 return bit2freq_tab[n]; 988 return bit2freq_tab[n];
551} 989}
552 990
553/* Write/read to/from HDSPM with Addresses in Bytes 991/* Write/read to/from HDSPM with Adresses in Bytes
554 not words but only 32Bit writes are allowed */ 992 not words but only 32Bit writes are allowed */
555 993
556static inline void hdspm_write(struct hdspm * hdspm, unsigned int reg, 994static inline void hdspm_write(struct hdspm * hdspm, unsigned int reg,
@@ -564,8 +1002,8 @@ static inline unsigned int hdspm_read(struct hdspm * hdspm, unsigned int reg)
564 return readl(hdspm->iobase + reg); 1002 return readl(hdspm->iobase + reg);
565} 1003}
566 1004
567/* for each output channel (chan) I have an Input (in) and Playback (pb) Fader 1005/* for each output channel (chan) I have an Input (in) and Playback (pb) Fader
568 mixer is write only on hardware so we have to cache him for read 1006 mixer is write only on hardware so we have to cache him for read
569 each fader is a u32, but uses only the first 16 bit */ 1007 each fader is a u32, but uses only the first 16 bit */
570 1008
571static inline int hdspm_read_in_gain(struct hdspm * hdspm, unsigned int chan, 1009static inline int hdspm_read_in_gain(struct hdspm * hdspm, unsigned int chan,
@@ -641,30 +1079,67 @@ static int snd_hdspm_use_is_exclusive(struct hdspm *hdspm)
641/* check for external sample rate */ 1079/* check for external sample rate */
642static int hdspm_external_sample_rate(struct hdspm *hdspm) 1080static int hdspm_external_sample_rate(struct hdspm *hdspm)
643{ 1081{
644 if (hdspm->is_aes32) { 1082 unsigned int status, status2, timecode;
645 unsigned int status2 = hdspm_read(hdspm, HDSPM_statusRegister2); 1083 int syncref, rate = 0, rate_bits;
646 unsigned int status = hdspm_read(hdspm, HDSPM_statusRegister);
647 unsigned int timecode =
648 hdspm_read(hdspm, HDSPM_timecodeRegister);
649 1084
650 int syncref = hdspm_autosync_ref(hdspm); 1085 switch (hdspm->io_type) {
1086 case AES32:
1087 status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
1088 status = hdspm_read(hdspm, HDSPM_statusRegister);
1089 timecode = hdspm_read(hdspm, HDSPM_timecodeRegister);
1090
1091 syncref = hdspm_autosync_ref(hdspm);
651 1092
652 if (syncref == HDSPM_AES32_AUTOSYNC_FROM_WORD && 1093 if (syncref == HDSPM_AES32_AUTOSYNC_FROM_WORD &&
653 status & HDSPM_AES32_wcLock) 1094 status & HDSPM_AES32_wcLock)
654 return HDSPM_bit2freq((status >> HDSPM_AES32_wcFreq_bit) 1095 return HDSPM_bit2freq((status >> HDSPM_AES32_wcFreq_bit) & 0xF);
655 & 0xF); 1096
656 if (syncref >= HDSPM_AES32_AUTOSYNC_FROM_AES1 && 1097 if (syncref >= HDSPM_AES32_AUTOSYNC_FROM_AES1 &&
657 syncref <= HDSPM_AES32_AUTOSYNC_FROM_AES8 && 1098 syncref <= HDSPM_AES32_AUTOSYNC_FROM_AES8 &&
658 status2 & (HDSPM_LockAES >> 1099 status2 & (HDSPM_LockAES >>
659 (syncref - HDSPM_AES32_AUTOSYNC_FROM_AES1))) 1100 (syncref - HDSPM_AES32_AUTOSYNC_FROM_AES1)))
660 return HDSPM_bit2freq((timecode >> 1101 return HDSPM_bit2freq((timecode >> (4*(syncref-HDSPM_AES32_AUTOSYNC_FROM_AES1))) & 0xF);
661 (4*(syncref-HDSPM_AES32_AUTOSYNC_FROM_AES1))) & 0xF);
662 return 0; 1102 return 0;
663 } else { 1103 break;
664 unsigned int status2 = hdspm_read(hdspm, HDSPM_statusRegister2); 1104
665 unsigned int status = hdspm_read(hdspm, HDSPM_statusRegister); 1105 case MADIface:
666 unsigned int rate_bits; 1106 status = hdspm_read(hdspm, HDSPM_statusRegister);
667 int rate = 0; 1107
1108 if (!(status & HDSPM_madiLock)) {
1109 rate = 0; /* no lock */
1110 } else {
1111 switch (status & (HDSPM_status1_freqMask)) {
1112 case HDSPM_status1_F_0*1:
1113 rate = 32000; break;
1114 case HDSPM_status1_F_0*2:
1115 rate = 44100; break;
1116 case HDSPM_status1_F_0*3:
1117 rate = 48000; break;
1118 case HDSPM_status1_F_0*4:
1119 rate = 64000; break;
1120 case HDSPM_status1_F_0*5:
1121 rate = 88200; break;
1122 case HDSPM_status1_F_0*6:
1123 rate = 96000; break;
1124 case HDSPM_status1_F_0*7:
1125 rate = 128000; break;
1126 case HDSPM_status1_F_0*8:
1127 rate = 176400; break;
1128 case HDSPM_status1_F_0*9:
1129 rate = 192000; break;
1130 default:
1131 rate = 0; break;
1132 }
1133 }
1134
1135 break;
1136
1137 case MADI:
1138 case AIO:
1139 case RayDAT:
1140 status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
1141 status = hdspm_read(hdspm, HDSPM_statusRegister);
1142 rate = 0;
668 1143
669 /* if wordclock has synced freq and wordclock is valid */ 1144 /* if wordclock has synced freq and wordclock is valid */
670 if ((status2 & HDSPM_wcLock) != 0 && 1145 if ((status2 & HDSPM_wcLock) != 0 &&
@@ -672,6 +1147,7 @@ static int hdspm_external_sample_rate(struct hdspm *hdspm)
672 1147
673 rate_bits = status2 & HDSPM_wcFreqMask; 1148 rate_bits = status2 & HDSPM_wcFreqMask;
674 1149
1150
675 switch (rate_bits) { 1151 switch (rate_bits) {
676 case HDSPM_wcFreq32: 1152 case HDSPM_wcFreq32:
677 rate = 32000; 1153 rate = 32000;
@@ -691,7 +1167,6 @@ static int hdspm_external_sample_rate(struct hdspm *hdspm)
691 case HDSPM_wcFreq96: 1167 case HDSPM_wcFreq96:
692 rate = 96000; 1168 rate = 96000;
693 break; 1169 break;
694 /* Quadspeed Bit missing ???? */
695 default: 1170 default:
696 rate = 0; 1171 rate = 0;
697 break; 1172 break;
@@ -702,10 +1177,10 @@ static int hdspm_external_sample_rate(struct hdspm *hdspm)
702 * word has priority to MADI 1177 * word has priority to MADI
703 */ 1178 */
704 if (rate != 0 && 1179 if (rate != 0 &&
705 (status2 & HDSPM_SelSyncRefMask) == HDSPM_SelSyncRef_WORD) 1180 (status2 & HDSPM_SelSyncRefMask) == HDSPM_SelSyncRef_WORD)
706 return rate; 1181 return rate;
707 1182
708 /* maby a madi input (which is taken if sel sync is madi) */ 1183 /* maybe a madi input (which is taken if sel sync is madi) */
709 if (status & HDSPM_madiLock) { 1184 if (status & HDSPM_madiLock) {
710 rate_bits = status & HDSPM_madiFreqMask; 1185 rate_bits = status & HDSPM_madiFreqMask;
711 1186
@@ -742,36 +1217,35 @@ static int hdspm_external_sample_rate(struct hdspm *hdspm)
742 break; 1217 break;
743 } 1218 }
744 } 1219 }
745 return rate; 1220 break;
746 } 1221 }
1222
1223 return rate;
747} 1224}
748 1225
749/* Latency function */ 1226/* Latency function */
750static inline void hdspm_compute_period_size(struct hdspm * hdspm) 1227static inline void hdspm_compute_period_size(struct hdspm *hdspm)
751{ 1228{
752 hdspm->period_bytes = 1229 hdspm->period_bytes = 1 << ((hdspm_decode_latency(hdspm->control_register) + 8));
753 1 << ((hdspm_decode_latency(hdspm->control_register) + 8));
754} 1230}
755 1231
756static snd_pcm_uframes_t hdspm_hw_pointer(struct hdspm * hdspm) 1232
1233static snd_pcm_uframes_t hdspm_hw_pointer(struct hdspm *hdspm)
757{ 1234{
758 int position; 1235 int position;
759 1236
760 position = hdspm_read(hdspm, HDSPM_statusRegister); 1237 position = hdspm_read(hdspm, HDSPM_statusRegister);
761 1238
762 if (!hdspm->precise_ptr) 1239 switch (hdspm->io_type) {
763 return (position & HDSPM_BufferID) ? 1240 case RayDAT:
1241 case AIO:
1242 position &= HDSPM_BufferPositionMask;
1243 position /= 4; /* Bytes per sample */
1244 break;
1245 default:
1246 position = (position & HDSPM_BufferID) ?
764 (hdspm->period_bytes / 4) : 0; 1247 (hdspm->period_bytes / 4) : 0;
765 1248 }
766 /* hwpointer comes in bytes and is 64Bytes accurate (by docu since
767 PCI Burst)
768 i have experimented that it is at most 64 Byte to much for playing
769 so substraction of 64 byte should be ok for ALSA, but use it only
770 for application where you know what you do since if you come to
771 near with record pointer it can be a disaster */
772
773 position &= HDSPM_BufferPositionMask;
774 position = ((position - 64) % (2 * hdspm->period_bytes)) / 4;
775 1249
776 return position; 1250 return position;
777} 1251}
@@ -805,7 +1279,7 @@ static void hdspm_silence_playback(struct hdspm *hdspm)
805 } 1279 }
806} 1280}
807 1281
808static int hdspm_set_interrupt_interval(struct hdspm * s, unsigned int frames) 1282static int hdspm_set_interrupt_interval(struct hdspm *s, unsigned int frames)
809{ 1283{
810 int n; 1284 int n;
811 1285
@@ -829,21 +1303,53 @@ static int hdspm_set_interrupt_interval(struct hdspm * s, unsigned int frames)
829 return 0; 1303 return 0;
830} 1304}
831 1305
1306static u64 hdspm_calc_dds_value(struct hdspm *hdspm, u64 period)
1307{
1308 u64 freq_const;
1309
1310 if (period == 0)
1311 return 0;
1312
1313 switch (hdspm->io_type) {
1314 case MADI:
1315 case AES32:
1316 freq_const = 110069313433624ULL;
1317 break;
1318 case RayDAT:
1319 case AIO:
1320 freq_const = 104857600000000ULL;
1321 break;
1322 case MADIface:
1323 freq_const = 131072000000000ULL;
1324 }
1325
1326 return div_u64(freq_const, period);
1327}
1328
1329
832static void hdspm_set_dds_value(struct hdspm *hdspm, int rate) 1330static void hdspm_set_dds_value(struct hdspm *hdspm, int rate)
833{ 1331{
834 u64 n; 1332 u64 n;
835 1333
836 if (rate >= 112000) 1334 if (rate >= 112000)
837 rate /= 4; 1335 rate /= 4;
838 else if (rate >= 56000) 1336 else if (rate >= 56000)
839 rate /= 2; 1337 rate /= 2;
840 1338
841 /* RME says n = 104857600000000, but in the windows MADI driver, I see: 1339 switch (hdspm->io_type) {
842// return 104857600000000 / rate; // 100 MHz 1340 case MADIface:
843 return 110100480000000 / rate; // 105 MHz 1341 n = 131072000000000ULL; /* 125 MHz */
844 */ 1342 break;
845 /* n = 104857600000000ULL; */ /* = 2^20 * 10^8 */ 1343 case MADI:
846 n = 110100480000000ULL; /* Value checked for AES32 and MADI */ 1344 case AES32:
1345 n = 110069313433624ULL; /* 105 MHz */
1346 break;
1347 case RayDAT:
1348 case AIO:
1349 n = 104857600000000ULL; /* 100 MHz */
1350 break;
1351 }
1352
847 n = div_u64(n, rate); 1353 n = div_u64(n, rate);
848 /* n should be less than 2^32 for being written to FREQ register */ 1354 /* n should be less than 2^32 for being written to FREQ register */
849 snd_BUG_ON(n >> 32); 1355 snd_BUG_ON(n >> 32);
@@ -864,13 +1370,13 @@ static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally)
864 1370
865 if (!(hdspm->control_register & HDSPM_ClockModeMaster)) { 1371 if (!(hdspm->control_register & HDSPM_ClockModeMaster)) {
866 1372
867 /* SLAVE --- */ 1373 /* SLAVE --- */
868 if (called_internally) { 1374 if (called_internally) {
869 1375
870 /* request from ctl or card initialization 1376 /* request from ctl or card initialization
871 just make a warning an remember setting 1377 just make a warning an remember setting
872 for future master mode switching */ 1378 for future master mode switching */
873 1379
874 snd_printk(KERN_WARNING "HDSPM: " 1380 snd_printk(KERN_WARNING "HDSPM: "
875 "Warning: device is not running " 1381 "Warning: device is not running "
876 "as a clock master.\n"); 1382 "as a clock master.\n");
@@ -907,7 +1413,7 @@ static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally)
907 1413
908 Note that a similar but essentially insoluble problem exists for 1414 Note that a similar but essentially insoluble problem exists for
909 externally-driven rate changes. All we can do is to flag rate 1415 externally-driven rate changes. All we can do is to flag rate
910 changes in the read/write routines. 1416 changes in the read/write routines.
911 */ 1417 */
912 1418
913 if (current_rate <= 48000) 1419 if (current_rate <= 48000)
@@ -975,16 +1481,35 @@ static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally)
975 /* For AES32, need to set DDS value in FREQ register 1481 /* For AES32, need to set DDS value in FREQ register
976 For MADI, also apparently */ 1482 For MADI, also apparently */
977 hdspm_set_dds_value(hdspm, rate); 1483 hdspm_set_dds_value(hdspm, rate);
978 1484
979 if (hdspm->is_aes32 && rate != current_rate) 1485 if (AES32 == hdspm->io_type && rate != current_rate)
980 hdspm_write(hdspm, HDSPM_eeprom_wr, 0); 1486 hdspm_write(hdspm, HDSPM_eeprom_wr, 0);
981
982 /* For AES32 and for MADI (at least rev 204), channel_map needs to
983 * always be channel_map_madi_ss, whatever the sample rate */
984 hdspm->channel_map = channel_map_madi_ss;
985 1487
986 hdspm->system_sample_rate = rate; 1488 hdspm->system_sample_rate = rate;
987 1489
1490 if (rate <= 48000) {
1491 hdspm->channel_map_in = hdspm->channel_map_in_ss;
1492 hdspm->channel_map_out = hdspm->channel_map_out_ss;
1493 hdspm->max_channels_in = hdspm->ss_in_channels;
1494 hdspm->max_channels_out = hdspm->ss_out_channels;
1495 hdspm->port_names_in = hdspm->port_names_in_ss;
1496 hdspm->port_names_out = hdspm->port_names_out_ss;
1497 } else if (rate <= 96000) {
1498 hdspm->channel_map_in = hdspm->channel_map_in_ds;
1499 hdspm->channel_map_out = hdspm->channel_map_out_ds;
1500 hdspm->max_channels_in = hdspm->ds_in_channels;
1501 hdspm->max_channels_out = hdspm->ds_out_channels;
1502 hdspm->port_names_in = hdspm->port_names_in_ds;
1503 hdspm->port_names_out = hdspm->port_names_out_ds;
1504 } else {
1505 hdspm->channel_map_in = hdspm->channel_map_in_qs;
1506 hdspm->channel_map_out = hdspm->channel_map_out_qs;
1507 hdspm->max_channels_in = hdspm->qs_in_channels;
1508 hdspm->max_channels_out = hdspm->qs_out_channels;
1509 hdspm->port_names_in = hdspm->port_names_in_qs;
1510 hdspm->port_names_out = hdspm->port_names_out_qs;
1511 }
1512
988 if (not_set != 0) 1513 if (not_set != 0)
989 return -1; 1514 return -1;
990 1515
@@ -1019,39 +1544,26 @@ static inline unsigned char snd_hdspm_midi_read_byte (struct hdspm *hdspm,
1019 int id) 1544 int id)
1020{ 1545{
1021 /* the hardware already does the relevant bit-mask with 0xff */ 1546 /* the hardware already does the relevant bit-mask with 0xff */
1022 if (id) 1547 return hdspm_read(hdspm, hdspm->midi[id].dataIn);
1023 return hdspm_read(hdspm, HDSPM_midiDataIn1);
1024 else
1025 return hdspm_read(hdspm, HDSPM_midiDataIn0);
1026} 1548}
1027 1549
1028static inline void snd_hdspm_midi_write_byte (struct hdspm *hdspm, int id, 1550static inline void snd_hdspm_midi_write_byte (struct hdspm *hdspm, int id,
1029 int val) 1551 int val)
1030{ 1552{
1031 /* the hardware already does the relevant bit-mask with 0xff */ 1553 /* the hardware already does the relevant bit-mask with 0xff */
1032 if (id) 1554 return hdspm_write(hdspm, hdspm->midi[id].dataOut, val);
1033 hdspm_write(hdspm, HDSPM_midiDataOut1, val);
1034 else
1035 hdspm_write(hdspm, HDSPM_midiDataOut0, val);
1036} 1555}
1037 1556
1038static inline int snd_hdspm_midi_input_available (struct hdspm *hdspm, int id) 1557static inline int snd_hdspm_midi_input_available (struct hdspm *hdspm, int id)
1039{ 1558{
1040 if (id) 1559 return hdspm_read(hdspm, hdspm->midi[id].statusIn) & 0xFF;
1041 return (hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xff);
1042 else
1043 return (hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xff);
1044} 1560}
1045 1561
1046static inline int snd_hdspm_midi_output_possible (struct hdspm *hdspm, int id) 1562static inline int snd_hdspm_midi_output_possible (struct hdspm *hdspm, int id)
1047{ 1563{
1048 int fifo_bytes_used; 1564 int fifo_bytes_used;
1049 1565
1050 if (id) 1566 fifo_bytes_used = hdspm_read(hdspm, hdspm->midi[id].statusOut) & 0xFF;
1051 fifo_bytes_used = hdspm_read(hdspm, HDSPM_midiStatusOut1);
1052 else
1053 fifo_bytes_used = hdspm_read(hdspm, HDSPM_midiStatusOut0);
1054 fifo_bytes_used &= 0xff;
1055 1567
1056 if (fifo_bytes_used < 128) 1568 if (fifo_bytes_used < 128)
1057 return 128 - fifo_bytes_used; 1569 return 128 - fifo_bytes_used;
@@ -1074,7 +1586,7 @@ static int snd_hdspm_midi_output_write (struct hdspm_midi *hmidi)
1074 unsigned char buf[128]; 1586 unsigned char buf[128];
1075 1587
1076 /* Output is not interrupt driven */ 1588 /* Output is not interrupt driven */
1077 1589
1078 spin_lock_irqsave (&hmidi->lock, flags); 1590 spin_lock_irqsave (&hmidi->lock, flags);
1079 if (hmidi->output && 1591 if (hmidi->output &&
1080 !snd_rawmidi_transmit_empty (hmidi->output)) { 1592 !snd_rawmidi_transmit_empty (hmidi->output)) {
@@ -1083,11 +1595,11 @@ static int snd_hdspm_midi_output_write (struct hdspm_midi *hmidi)
1083 if (n_pending > 0) { 1595 if (n_pending > 0) {
1084 if (n_pending > (int)sizeof (buf)) 1596 if (n_pending > (int)sizeof (buf))
1085 n_pending = sizeof (buf); 1597 n_pending = sizeof (buf);
1086 1598
1087 to_write = snd_rawmidi_transmit (hmidi->output, buf, 1599 to_write = snd_rawmidi_transmit (hmidi->output, buf,
1088 n_pending); 1600 n_pending);
1089 if (to_write > 0) { 1601 if (to_write > 0) {
1090 for (i = 0; i < to_write; ++i) 1602 for (i = 0; i < to_write; ++i)
1091 snd_hdspm_midi_write_byte (hmidi->hdspm, 1603 snd_hdspm_midi_write_byte (hmidi->hdspm,
1092 hmidi->id, 1604 hmidi->id,
1093 buf[i]); 1605 buf[i]);
@@ -1127,12 +1639,11 @@ static int snd_hdspm_midi_input_read (struct hdspm_midi *hmidi)
1127 } 1639 }
1128 } 1640 }
1129 hmidi->pending = 0; 1641 hmidi->pending = 0;
1130 if (hmidi->id) 1642
1131 hmidi->hdspm->control_register |= HDSPM_Midi1InterruptEnable; 1643 hmidi->hdspm->control_register |= hmidi->ie;
1132 else
1133 hmidi->hdspm->control_register |= HDSPM_Midi0InterruptEnable;
1134 hdspm_write(hmidi->hdspm, HDSPM_controlRegister, 1644 hdspm_write(hmidi->hdspm, HDSPM_controlRegister,
1135 hmidi->hdspm->control_register); 1645 hmidi->hdspm->control_register);
1646
1136 spin_unlock_irqrestore (&hmidi->lock, flags); 1647 spin_unlock_irqrestore (&hmidi->lock, flags);
1137 return snd_hdspm_midi_output_write (hmidi); 1648 return snd_hdspm_midi_output_write (hmidi);
1138} 1649}
@@ -1143,20 +1654,18 @@ snd_hdspm_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
1143 struct hdspm *hdspm; 1654 struct hdspm *hdspm;
1144 struct hdspm_midi *hmidi; 1655 struct hdspm_midi *hmidi;
1145 unsigned long flags; 1656 unsigned long flags;
1146 u32 ie;
1147 1657
1148 hmidi = substream->rmidi->private_data; 1658 hmidi = substream->rmidi->private_data;
1149 hdspm = hmidi->hdspm; 1659 hdspm = hmidi->hdspm;
1150 ie = hmidi->id ? 1660
1151 HDSPM_Midi1InterruptEnable : HDSPM_Midi0InterruptEnable;
1152 spin_lock_irqsave (&hdspm->lock, flags); 1661 spin_lock_irqsave (&hdspm->lock, flags);
1153 if (up) { 1662 if (up) {
1154 if (!(hdspm->control_register & ie)) { 1663 if (!(hdspm->control_register & hmidi->ie)) {
1155 snd_hdspm_flush_midi_input (hdspm, hmidi->id); 1664 snd_hdspm_flush_midi_input (hdspm, hmidi->id);
1156 hdspm->control_register |= ie; 1665 hdspm->control_register |= hmidi->ie;
1157 } 1666 }
1158 } else { 1667 } else {
1159 hdspm->control_register &= ~ie; 1668 hdspm->control_register &= ~hmidi->ie;
1160 } 1669 }
1161 1670
1162 hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register); 1671 hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
@@ -1167,14 +1676,14 @@ static void snd_hdspm_midi_output_timer(unsigned long data)
1167{ 1676{
1168 struct hdspm_midi *hmidi = (struct hdspm_midi *) data; 1677 struct hdspm_midi *hmidi = (struct hdspm_midi *) data;
1169 unsigned long flags; 1678 unsigned long flags;
1170 1679
1171 snd_hdspm_midi_output_write(hmidi); 1680 snd_hdspm_midi_output_write(hmidi);
1172 spin_lock_irqsave (&hmidi->lock, flags); 1681 spin_lock_irqsave (&hmidi->lock, flags);
1173 1682
1174 /* this does not bump hmidi->istimer, because the 1683 /* this does not bump hmidi->istimer, because the
1175 kernel automatically removed the timer when it 1684 kernel automatically removed the timer when it
1176 expired, and we are now adding it back, thus 1685 expired, and we are now adding it back, thus
1177 leaving istimer wherever it was set before. 1686 leaving istimer wherever it was set before.
1178 */ 1687 */
1179 1688
1180 if (hmidi->istimer) { 1689 if (hmidi->istimer) {
@@ -1288,22 +1797,103 @@ static int __devinit snd_hdspm_create_midi (struct snd_card *card,
1288 hdspm->midi[id].hdspm = hdspm; 1797 hdspm->midi[id].hdspm = hdspm;
1289 spin_lock_init (&hdspm->midi[id].lock); 1798 spin_lock_init (&hdspm->midi[id].lock);
1290 1799
1291 sprintf (buf, "%s MIDI %d", card->shortname, id+1); 1800 if (0 == id) {
1292 err = snd_rawmidi_new (card, buf, id, 1, 1, &hdspm->midi[id].rmidi); 1801 if (MADIface == hdspm->io_type) {
1293 if (err < 0) 1802 /* MIDI-over-MADI on HDSPe MADIface */
1294 return err; 1803 hdspm->midi[0].dataIn = HDSPM_midiDataIn2;
1804 hdspm->midi[0].statusIn = HDSPM_midiStatusIn2;
1805 hdspm->midi[0].dataOut = HDSPM_midiDataOut2;
1806 hdspm->midi[0].statusOut = HDSPM_midiStatusOut2;
1807 hdspm->midi[0].ie = HDSPM_Midi2InterruptEnable;
1808 hdspm->midi[0].irq = HDSPM_midi2IRQPending;
1809 } else {
1810 hdspm->midi[0].dataIn = HDSPM_midiDataIn0;
1811 hdspm->midi[0].statusIn = HDSPM_midiStatusIn0;
1812 hdspm->midi[0].dataOut = HDSPM_midiDataOut0;
1813 hdspm->midi[0].statusOut = HDSPM_midiStatusOut0;
1814 hdspm->midi[0].ie = HDSPM_Midi0InterruptEnable;
1815 hdspm->midi[0].irq = HDSPM_midi0IRQPending;
1816 }
1817 } else if (1 == id) {
1818 hdspm->midi[1].dataIn = HDSPM_midiDataIn1;
1819 hdspm->midi[1].statusIn = HDSPM_midiStatusIn1;
1820 hdspm->midi[1].dataOut = HDSPM_midiDataOut1;
1821 hdspm->midi[1].statusOut = HDSPM_midiStatusOut1;
1822 hdspm->midi[1].ie = HDSPM_Midi1InterruptEnable;
1823 hdspm->midi[1].irq = HDSPM_midi1IRQPending;
1824 } else if ((2 == id) && (MADI == hdspm->io_type)) {
1825 /* MIDI-over-MADI on HDSPe MADI */
1826 hdspm->midi[2].dataIn = HDSPM_midiDataIn2;
1827 hdspm->midi[2].statusIn = HDSPM_midiStatusIn2;
1828 hdspm->midi[2].dataOut = HDSPM_midiDataOut2;
1829 hdspm->midi[2].statusOut = HDSPM_midiStatusOut2;
1830 hdspm->midi[2].ie = HDSPM_Midi2InterruptEnable;
1831 hdspm->midi[2].irq = HDSPM_midi2IRQPending;
1832 } else if (2 == id) {
1833 /* TCO MTC, read only */
1834 hdspm->midi[2].dataIn = HDSPM_midiDataIn2;
1835 hdspm->midi[2].statusIn = HDSPM_midiStatusIn2;
1836 hdspm->midi[2].dataOut = -1;
1837 hdspm->midi[2].statusOut = -1;
1838 hdspm->midi[2].ie = HDSPM_Midi2InterruptEnable;
1839 hdspm->midi[2].irq = HDSPM_midi2IRQPendingAES;
1840 } else if (3 == id) {
1841 /* TCO MTC on HDSPe MADI */
1842 hdspm->midi[3].dataIn = HDSPM_midiDataIn3;
1843 hdspm->midi[3].statusIn = HDSPM_midiStatusIn3;
1844 hdspm->midi[3].dataOut = -1;
1845 hdspm->midi[3].statusOut = -1;
1846 hdspm->midi[3].ie = HDSPM_Midi3InterruptEnable;
1847 hdspm->midi[3].irq = HDSPM_midi3IRQPending;
1848 }
1295 1849
1296 sprintf(hdspm->midi[id].rmidi->name, "HDSPM MIDI %d", id+1); 1850 if ((id < 2) || ((2 == id) && ((MADI == hdspm->io_type) ||
1297 hdspm->midi[id].rmidi->private_data = &hdspm->midi[id]; 1851 (MADIface == hdspm->io_type)))) {
1852 if ((id == 0) && (MADIface == hdspm->io_type)) {
1853 sprintf(buf, "%s MIDIoverMADI", card->shortname);
1854 } else if ((id == 2) && (MADI == hdspm->io_type)) {
1855 sprintf(buf, "%s MIDIoverMADI", card->shortname);
1856 } else {
1857 sprintf(buf, "%s MIDI %d", card->shortname, id+1);
1858 }
1859 err = snd_rawmidi_new(card, buf, id, 1, 1,
1860 &hdspm->midi[id].rmidi);
1861 if (err < 0)
1862 return err;
1298 1863
1299 snd_rawmidi_set_ops(hdspm->midi[id].rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, 1864 sprintf(hdspm->midi[id].rmidi->name, "%s MIDI %d",
1300 &snd_hdspm_midi_output); 1865 card->id, id+1);
1301 snd_rawmidi_set_ops(hdspm->midi[id].rmidi, SNDRV_RAWMIDI_STREAM_INPUT, 1866 hdspm->midi[id].rmidi->private_data = &hdspm->midi[id];
1302 &snd_hdspm_midi_input); 1867
1868 snd_rawmidi_set_ops(hdspm->midi[id].rmidi,
1869 SNDRV_RAWMIDI_STREAM_OUTPUT,
1870 &snd_hdspm_midi_output);
1871 snd_rawmidi_set_ops(hdspm->midi[id].rmidi,
1872 SNDRV_RAWMIDI_STREAM_INPUT,
1873 &snd_hdspm_midi_input);
1874
1875 hdspm->midi[id].rmidi->info_flags |=
1876 SNDRV_RAWMIDI_INFO_OUTPUT |
1877 SNDRV_RAWMIDI_INFO_INPUT |
1878 SNDRV_RAWMIDI_INFO_DUPLEX;
1879 } else {
1880 /* TCO MTC, read only */
1881 sprintf(buf, "%s MTC %d", card->shortname, id+1);
1882 err = snd_rawmidi_new(card, buf, id, 1, 1,
1883 &hdspm->midi[id].rmidi);
1884 if (err < 0)
1885 return err;
1303 1886
1304 hdspm->midi[id].rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | 1887 sprintf(hdspm->midi[id].rmidi->name,
1305 SNDRV_RAWMIDI_INFO_INPUT | 1888 "%s MTC %d", card->id, id+1);
1306 SNDRV_RAWMIDI_INFO_DUPLEX; 1889 hdspm->midi[id].rmidi->private_data = &hdspm->midi[id];
1890
1891 snd_rawmidi_set_ops(hdspm->midi[id].rmidi,
1892 SNDRV_RAWMIDI_STREAM_INPUT,
1893 &snd_hdspm_midi_input);
1894
1895 hdspm->midi[id].rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT;
1896 }
1307 1897
1308 return 0; 1898 return 0;
1309} 1899}
@@ -1312,12 +1902,15 @@ static int __devinit snd_hdspm_create_midi (struct snd_card *card,
1312static void hdspm_midi_tasklet(unsigned long arg) 1902static void hdspm_midi_tasklet(unsigned long arg)
1313{ 1903{
1314 struct hdspm *hdspm = (struct hdspm *)arg; 1904 struct hdspm *hdspm = (struct hdspm *)arg;
1315 1905 int i = 0;
1316 if (hdspm->midi[0].pending) 1906
1317 snd_hdspm_midi_input_read (&hdspm->midi[0]); 1907 while (i < hdspm->midiPorts) {
1318 if (hdspm->midi[1].pending) 1908 if (hdspm->midi[i].pending)
1319 snd_hdspm_midi_input_read (&hdspm->midi[1]); 1909 snd_hdspm_midi_input_read(&hdspm->midi[i]);
1320} 1910
1911 i++;
1912 }
1913}
1321 1914
1322 1915
1323/*----------------------------------------------------------------------------- 1916/*-----------------------------------------------------------------------------
@@ -1326,6 +1919,22 @@ static void hdspm_midi_tasklet(unsigned long arg)
1326 1919
1327/* get the system sample rate which is set */ 1920/* get the system sample rate which is set */
1328 1921
1922
1923/**
1924 * Calculate the real sample rate from the
1925 * current DDS value.
1926 **/
1927static int hdspm_get_system_sample_rate(struct hdspm *hdspm)
1928{
1929 unsigned int period, rate;
1930
1931 period = hdspm_read(hdspm, HDSPM_RD_PLL_FREQ);
1932 rate = hdspm_calc_dds_value(hdspm, period);
1933
1934 return rate;
1935}
1936
1937
1329#define HDSPM_SYSTEM_SAMPLE_RATE(xname, xindex) \ 1938#define HDSPM_SYSTEM_SAMPLE_RATE(xname, xindex) \
1330{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 1939{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1331 .name = xname, \ 1940 .name = xname, \
@@ -1340,112 +1949,274 @@ static int snd_hdspm_info_system_sample_rate(struct snd_kcontrol *kcontrol,
1340{ 1949{
1341 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 1950 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1342 uinfo->count = 1; 1951 uinfo->count = 1;
1952 uinfo->value.integer.min = 27000;
1953 uinfo->value.integer.max = 207000;
1954 uinfo->value.integer.step = 1;
1343 return 0; 1955 return 0;
1344} 1956}
1345 1957
1958
1346static int snd_hdspm_get_system_sample_rate(struct snd_kcontrol *kcontrol, 1959static int snd_hdspm_get_system_sample_rate(struct snd_kcontrol *kcontrol,
1347 struct snd_ctl_elem_value * 1960 struct snd_ctl_elem_value *
1348 ucontrol) 1961 ucontrol)
1349{ 1962{
1350 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); 1963 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
1351 1964
1352 ucontrol->value.enumerated.item[0] = hdspm->system_sample_rate; 1965 ucontrol->value.integer.value[0] = hdspm_get_system_sample_rate(hdspm);
1966 return 0;
1967}
1968
1969
1970/**
1971 * Returns the WordClock sample rate class for the given card.
1972 **/
1973static int hdspm_get_wc_sample_rate(struct hdspm *hdspm)
1974{
1975 int status;
1976
1977 switch (hdspm->io_type) {
1978 case RayDAT:
1979 case AIO:
1980 status = hdspm_read(hdspm, HDSPM_RD_STATUS_1);
1981 return (status >> 16) & 0xF;
1982 break;
1983 default:
1984 break;
1985 }
1986
1987
1988 return 0;
1989}
1990
1991
1992/**
1993 * Returns the TCO sample rate class for the given card.
1994 **/
1995static int hdspm_get_tco_sample_rate(struct hdspm *hdspm)
1996{
1997 int status;
1998
1999 if (hdspm->tco) {
2000 switch (hdspm->io_type) {
2001 case RayDAT:
2002 case AIO:
2003 status = hdspm_read(hdspm, HDSPM_RD_STATUS_1);
2004 return (status >> 20) & 0xF;
2005 break;
2006 default:
2007 break;
2008 }
2009 }
2010
2011 return 0;
2012}
2013
2014
2015/**
2016 * Returns the SYNC_IN sample rate class for the given card.
2017 **/
2018static int hdspm_get_sync_in_sample_rate(struct hdspm *hdspm)
2019{
2020 int status;
2021
2022 if (hdspm->tco) {
2023 switch (hdspm->io_type) {
2024 case RayDAT:
2025 case AIO:
2026 status = hdspm_read(hdspm, HDSPM_RD_STATUS_2);
2027 return (status >> 12) & 0xF;
2028 break;
2029 default:
2030 break;
2031 }
2032 }
2033
1353 return 0; 2034 return 0;
1354} 2035}
1355 2036
2037
2038/**
2039 * Returns the sample rate class for input source <idx> for
2040 * 'new style' cards like the AIO and RayDAT.
2041 **/
2042static int hdspm_get_s1_sample_rate(struct hdspm *hdspm, unsigned int idx)
2043{
2044 int status = hdspm_read(hdspm, HDSPM_RD_STATUS_2);
2045
2046 return (status >> (idx*4)) & 0xF;
2047}
2048
2049
2050
1356#define HDSPM_AUTOSYNC_SAMPLE_RATE(xname, xindex) \ 2051#define HDSPM_AUTOSYNC_SAMPLE_RATE(xname, xindex) \
1357{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2052{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1358 .name = xname, \ 2053 .name = xname, \
1359 .index = xindex, \ 2054 .private_value = xindex, \
1360 .access = SNDRV_CTL_ELEM_ACCESS_READ, \ 2055 .access = SNDRV_CTL_ELEM_ACCESS_READ, \
1361 .info = snd_hdspm_info_autosync_sample_rate, \ 2056 .info = snd_hdspm_info_autosync_sample_rate, \
1362 .get = snd_hdspm_get_autosync_sample_rate \ 2057 .get = snd_hdspm_get_autosync_sample_rate \
1363} 2058}
1364 2059
2060
1365static int snd_hdspm_info_autosync_sample_rate(struct snd_kcontrol *kcontrol, 2061static int snd_hdspm_info_autosync_sample_rate(struct snd_kcontrol *kcontrol,
1366 struct snd_ctl_elem_info *uinfo) 2062 struct snd_ctl_elem_info *uinfo)
1367{ 2063{
1368 static char *texts[] = { "32000", "44100", "48000",
1369 "64000", "88200", "96000",
1370 "128000", "176400", "192000",
1371 "None"
1372 };
1373 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 2064 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1374 uinfo->count = 1; 2065 uinfo->count = 1;
1375 uinfo->value.enumerated.items = 10; 2066 uinfo->value.enumerated.items = 10;
2067
1376 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) 2068 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1377 uinfo->value.enumerated.item = 2069 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1378 uinfo->value.enumerated.items - 1;
1379 strcpy(uinfo->value.enumerated.name, 2070 strcpy(uinfo->value.enumerated.name,
1380 texts[uinfo->value.enumerated.item]); 2071 texts_freq[uinfo->value.enumerated.item]);
1381 return 0; 2072 return 0;
1382} 2073}
1383 2074
2075
1384static int snd_hdspm_get_autosync_sample_rate(struct snd_kcontrol *kcontrol, 2076static int snd_hdspm_get_autosync_sample_rate(struct snd_kcontrol *kcontrol,
1385 struct snd_ctl_elem_value * 2077 struct snd_ctl_elem_value *
1386 ucontrol) 2078 ucontrol)
1387{ 2079{
1388 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); 2080 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
1389 2081
1390 switch (hdspm_external_sample_rate(hdspm)) { 2082 switch (hdspm->io_type) {
1391 case 32000: 2083 case RayDAT:
1392 ucontrol->value.enumerated.item[0] = 0; 2084 switch (kcontrol->private_value) {
1393 break; 2085 case 0:
1394 case 44100: 2086 ucontrol->value.enumerated.item[0] =
1395 ucontrol->value.enumerated.item[0] = 1; 2087 hdspm_get_wc_sample_rate(hdspm);
1396 break; 2088 break;
1397 case 48000: 2089 case 7:
1398 ucontrol->value.enumerated.item[0] = 2; 2090 ucontrol->value.enumerated.item[0] =
1399 break; 2091 hdspm_get_tco_sample_rate(hdspm);
1400 case 64000: 2092 break;
1401 ucontrol->value.enumerated.item[0] = 3; 2093 case 8:
1402 break; 2094 ucontrol->value.enumerated.item[0] =
1403 case 88200: 2095 hdspm_get_sync_in_sample_rate(hdspm);
1404 ucontrol->value.enumerated.item[0] = 4; 2096 break;
1405 break; 2097 default:
1406 case 96000: 2098 ucontrol->value.enumerated.item[0] =
1407 ucontrol->value.enumerated.item[0] = 5; 2099 hdspm_get_s1_sample_rate(hdspm,
1408 break; 2100 kcontrol->private_value-1);
1409 case 128000: 2101 }
1410 ucontrol->value.enumerated.item[0] = 6; 2102
1411 break; 2103 case AIO:
1412 case 176400: 2104 switch (kcontrol->private_value) {
1413 ucontrol->value.enumerated.item[0] = 7; 2105 case 0: /* WC */
1414 break; 2106 ucontrol->value.enumerated.item[0] =
1415 case 192000: 2107 hdspm_get_wc_sample_rate(hdspm);
1416 ucontrol->value.enumerated.item[0] = 8; 2108 break;
1417 break; 2109 case 4: /* TCO */
2110 ucontrol->value.enumerated.item[0] =
2111 hdspm_get_tco_sample_rate(hdspm);
2112 break;
2113 case 5: /* SYNC_IN */
2114 ucontrol->value.enumerated.item[0] =
2115 hdspm_get_sync_in_sample_rate(hdspm);
2116 break;
2117 default:
2118 ucontrol->value.enumerated.item[0] =
2119 hdspm_get_s1_sample_rate(hdspm,
2120 ucontrol->id.index-1);
2121 }
2122
2123 case AES32:
1418 2124
2125 switch (kcontrol->private_value) {
2126 case 0: /* WC */
2127 ucontrol->value.enumerated.item[0] =
2128 hdspm_get_wc_sample_rate(hdspm);
2129 break;
2130 case 9: /* TCO */
2131 ucontrol->value.enumerated.item[0] =
2132 hdspm_get_tco_sample_rate(hdspm);
2133 break;
2134 case 10: /* SYNC_IN */
2135 ucontrol->value.enumerated.item[0] =
2136 hdspm_get_sync_in_sample_rate(hdspm);
2137 break;
2138 default: /* AES1 to AES8 */
2139 ucontrol->value.enumerated.item[0] =
2140 hdspm_get_s1_sample_rate(hdspm,
2141 kcontrol->private_value-1);
2142 break;
2143
2144 }
1419 default: 2145 default:
1420 ucontrol->value.enumerated.item[0] = 9; 2146 break;
1421 } 2147 }
2148
1422 return 0; 2149 return 0;
1423} 2150}
1424 2151
2152
1425#define HDSPM_SYSTEM_CLOCK_MODE(xname, xindex) \ 2153#define HDSPM_SYSTEM_CLOCK_MODE(xname, xindex) \
1426{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2154{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1427 .name = xname, \ 2155 .name = xname, \
1428 .index = xindex, \ 2156 .index = xindex, \
1429 .access = SNDRV_CTL_ELEM_ACCESS_READ, \ 2157 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
1430 .info = snd_hdspm_info_system_clock_mode, \ 2158 SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
1431 .get = snd_hdspm_get_system_clock_mode, \ 2159 .info = snd_hdspm_info_system_clock_mode, \
1432} 2160 .get = snd_hdspm_get_system_clock_mode, \
2161 .put = snd_hdspm_put_system_clock_mode, \
2162}
2163
2164
2165/**
2166 * Returns the system clock mode for the given card.
2167 * @returns 0 - master, 1 - slave
2168 **/
2169static int hdspm_system_clock_mode(struct hdspm *hdspm)
2170{
2171 switch (hdspm->io_type) {
2172 case AIO:
2173 case RayDAT:
2174 if (hdspm->settings_register & HDSPM_c0Master)
2175 return 0;
2176 break;
2177
2178 default:
2179 if (hdspm->control_register & HDSPM_ClockModeMaster)
2180 return 0;
2181 }
1433 2182
2183 return 1;
2184}
1434 2185
1435 2186
1436static int hdspm_system_clock_mode(struct hdspm * hdspm) 2187/**
2188 * Sets the system clock mode.
2189 * @param mode 0 - master, 1 - slave
2190 **/
2191static void hdspm_set_system_clock_mode(struct hdspm *hdspm, int mode)
1437{ 2192{
1438 /* Always reflect the hardware info, rme is never wrong !!!! */ 2193 switch (hdspm->io_type) {
2194 case AIO:
2195 case RayDAT:
2196 if (0 == mode)
2197 hdspm->settings_register |= HDSPM_c0Master;
2198 else
2199 hdspm->settings_register &= ~HDSPM_c0Master;
1439 2200
1440 if (hdspm->control_register & HDSPM_ClockModeMaster) 2201 hdspm_write(hdspm, HDSPM_WR_SETTINGS, hdspm->settings_register);
1441 return 0; 2202 break;
1442 return 1; 2203
2204 default:
2205 if (0 == mode)
2206 hdspm->control_register |= HDSPM_ClockModeMaster;
2207 else
2208 hdspm->control_register &= ~HDSPM_ClockModeMaster;
2209
2210 hdspm_write(hdspm, HDSPM_controlRegister,
2211 hdspm->control_register);
2212 }
1443} 2213}
1444 2214
2215
1445static int snd_hdspm_info_system_clock_mode(struct snd_kcontrol *kcontrol, 2216static int snd_hdspm_info_system_clock_mode(struct snd_kcontrol *kcontrol,
1446 struct snd_ctl_elem_info *uinfo) 2217 struct snd_ctl_elem_info *uinfo)
1447{ 2218{
1448 static char *texts[] = { "Master", "Slave" }; 2219 static char *texts[] = { "Master", "AutoSync" };
1449 2220
1450 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 2221 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1451 uinfo->count = 1; 2222 uinfo->count = 1;
@@ -1463,96 +2234,83 @@ static int snd_hdspm_get_system_clock_mode(struct snd_kcontrol *kcontrol,
1463{ 2234{
1464 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); 2235 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
1465 2236
1466 ucontrol->value.enumerated.item[0] = 2237 ucontrol->value.enumerated.item[0] = hdspm_system_clock_mode(hdspm);
1467 hdspm_system_clock_mode(hdspm);
1468 return 0; 2238 return 0;
1469} 2239}
1470 2240
1471#define HDSPM_CLOCK_SOURCE(xname, xindex) \ 2241static int snd_hdspm_put_system_clock_mode(struct snd_kcontrol *kcontrol,
1472{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2242 struct snd_ctl_elem_value *ucontrol)
1473 .name = xname, \ 2243{
1474 .index = xindex, \ 2244 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
1475 .info = snd_hdspm_info_clock_source, \ 2245 int val;
1476 .get = snd_hdspm_get_clock_source, \ 2246
1477 .put = snd_hdspm_put_clock_source \ 2247 if (!snd_hdspm_use_is_exclusive(hdspm))
2248 return -EBUSY;
2249
2250 val = ucontrol->value.enumerated.item[0];
2251 if (val < 0)
2252 val = 0;
2253 else if (val > 1)
2254 val = 1;
2255
2256 hdspm_set_system_clock_mode(hdspm, val);
2257
2258 return 0;
1478} 2259}
1479 2260
2261
2262#define HDSPM_INTERNAL_CLOCK(xname, xindex) \
2263{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2264 .name = xname, \
2265 .index = xindex, \
2266 .info = snd_hdspm_info_clock_source, \
2267 .get = snd_hdspm_get_clock_source, \
2268 .put = snd_hdspm_put_clock_source \
2269}
2270
2271
1480static int hdspm_clock_source(struct hdspm * hdspm) 2272static int hdspm_clock_source(struct hdspm * hdspm)
1481{ 2273{
1482 if (hdspm->control_register & HDSPM_ClockModeMaster) { 2274 switch (hdspm->system_sample_rate) {
1483 switch (hdspm->system_sample_rate) { 2275 case 32000: return 0;
1484 case 32000: 2276 case 44100: return 1;
1485 return 1; 2277 case 48000: return 2;
1486 case 44100: 2278 case 64000: return 3;
1487 return 2; 2279 case 88200: return 4;
1488 case 48000: 2280 case 96000: return 5;
1489 return 3; 2281 case 128000: return 6;
1490 case 64000: 2282 case 176400: return 7;
1491 return 4; 2283 case 192000: return 8;
1492 case 88200:
1493 return 5;
1494 case 96000:
1495 return 6;
1496 case 128000:
1497 return 7;
1498 case 176400:
1499 return 8;
1500 case 192000:
1501 return 9;
1502 default:
1503 return 3;
1504 }
1505 } else {
1506 return 0;
1507 } 2284 }
2285
2286 return -1;
1508} 2287}
1509 2288
1510static int hdspm_set_clock_source(struct hdspm * hdspm, int mode) 2289static int hdspm_set_clock_source(struct hdspm * hdspm, int mode)
1511{ 2290{
1512 int rate; 2291 int rate;
1513 switch (mode) { 2292 switch (mode) {
1514 2293 case 0:
1515 case HDSPM_CLOCK_SOURCE_AUTOSYNC: 2294 rate = 32000; break;
1516 if (hdspm_external_sample_rate(hdspm) != 0) { 2295 case 1:
1517 hdspm->control_register &= ~HDSPM_ClockModeMaster; 2296 rate = 44100; break;
1518 hdspm_write(hdspm, HDSPM_controlRegister, 2297 case 2:
1519 hdspm->control_register); 2298 rate = 48000; break;
1520 return 0; 2299 case 3:
1521 } 2300 rate = 64000; break;
1522 return -1; 2301 case 4:
1523 case HDSPM_CLOCK_SOURCE_INTERNAL_32KHZ: 2302 rate = 88200; break;
1524 rate = 32000; 2303 case 5:
1525 break; 2304 rate = 96000; break;
1526 case HDSPM_CLOCK_SOURCE_INTERNAL_44_1KHZ: 2305 case 6:
1527 rate = 44100; 2306 rate = 128000; break;
1528 break; 2307 case 7:
1529 case HDSPM_CLOCK_SOURCE_INTERNAL_48KHZ: 2308 rate = 176400; break;
1530 rate = 48000; 2309 case 8:
1531 break; 2310 rate = 192000; break;
1532 case HDSPM_CLOCK_SOURCE_INTERNAL_64KHZ:
1533 rate = 64000;
1534 break;
1535 case HDSPM_CLOCK_SOURCE_INTERNAL_88_2KHZ:
1536 rate = 88200;
1537 break;
1538 case HDSPM_CLOCK_SOURCE_INTERNAL_96KHZ:
1539 rate = 96000;
1540 break;
1541 case HDSPM_CLOCK_SOURCE_INTERNAL_128KHZ:
1542 rate = 128000;
1543 break;
1544 case HDSPM_CLOCK_SOURCE_INTERNAL_176_4KHZ:
1545 rate = 176400;
1546 break;
1547 case HDSPM_CLOCK_SOURCE_INTERNAL_192KHZ:
1548 rate = 192000;
1549 break;
1550
1551 default: 2311 default:
1552 rate = 44100; 2312 rate = 48000;
1553 } 2313 }
1554 hdspm->control_register |= HDSPM_ClockModeMaster;
1555 hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
1556 hdspm_set_rate(hdspm, rate, 1); 2314 hdspm_set_rate(hdspm, rate, 1);
1557 return 0; 2315 return 0;
1558} 2316}
@@ -1560,25 +2318,16 @@ static int hdspm_set_clock_source(struct hdspm * hdspm, int mode)
1560static int snd_hdspm_info_clock_source(struct snd_kcontrol *kcontrol, 2318static int snd_hdspm_info_clock_source(struct snd_kcontrol *kcontrol,
1561 struct snd_ctl_elem_info *uinfo) 2319 struct snd_ctl_elem_info *uinfo)
1562{ 2320{
1563 static char *texts[] = { "AutoSync",
1564 "Internal 32.0 kHz", "Internal 44.1 kHz",
1565 "Internal 48.0 kHz",
1566 "Internal 64.0 kHz", "Internal 88.2 kHz",
1567 "Internal 96.0 kHz",
1568 "Internal 128.0 kHz", "Internal 176.4 kHz",
1569 "Internal 192.0 kHz"
1570 };
1571
1572 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 2321 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1573 uinfo->count = 1; 2322 uinfo->count = 1;
1574 uinfo->value.enumerated.items = 10; 2323 uinfo->value.enumerated.items = 9;
1575 2324
1576 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) 2325 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1577 uinfo->value.enumerated.item = 2326 uinfo->value.enumerated.item =
1578 uinfo->value.enumerated.items - 1; 2327 uinfo->value.enumerated.items - 1;
1579 2328
1580 strcpy(uinfo->value.enumerated.name, 2329 strcpy(uinfo->value.enumerated.name,
1581 texts[uinfo->value.enumerated.item]); 2330 texts_freq[uinfo->value.enumerated.item+1]);
1582 2331
1583 return 0; 2332 return 0;
1584} 2333}
@@ -1615,134 +2364,301 @@ static int snd_hdspm_put_clock_source(struct snd_kcontrol *kcontrol,
1615 return change; 2364 return change;
1616} 2365}
1617 2366
1618#define HDSPM_PREF_SYNC_REF(xname, xindex) \
1619{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1620 .name = xname, \
1621 .index = xindex, \
1622 .info = snd_hdspm_info_pref_sync_ref, \
1623 .get = snd_hdspm_get_pref_sync_ref, \
1624 .put = snd_hdspm_put_pref_sync_ref \
1625}
1626 2367
2368#define HDSPM_PREF_SYNC_REF(xname, xindex) \
2369{.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2370 .name = xname, \
2371 .index = xindex, \
2372 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
2373 SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
2374 .info = snd_hdspm_info_pref_sync_ref, \
2375 .get = snd_hdspm_get_pref_sync_ref, \
2376 .put = snd_hdspm_put_pref_sync_ref \
2377}
2378
2379
2380/**
2381 * Returns the current preferred sync reference setting.
2382 * The semantics of the return value are depending on the
2383 * card, please see the comments for clarification.
2384 **/
1627static int hdspm_pref_sync_ref(struct hdspm * hdspm) 2385static int hdspm_pref_sync_ref(struct hdspm * hdspm)
1628{ 2386{
1629 /* Notice that this looks at the requested sync source, 2387 switch (hdspm->io_type) {
1630 not the one actually in use. 2388 case AES32:
1631 */
1632 if (hdspm->is_aes32) {
1633 switch (hdspm->control_register & HDSPM_SyncRefMask) { 2389 switch (hdspm->control_register & HDSPM_SyncRefMask) {
1634 /* number gives AES index, except for 0 which 2390 case 0: return 0; /* WC */
1635 corresponds to WordClock */ 2391 case HDSPM_SyncRef0: return 1; /* AES 1 */
1636 case 0: return 0; 2392 case HDSPM_SyncRef1: return 2; /* AES 2 */
1637 case HDSPM_SyncRef0: return 1; 2393 case HDSPM_SyncRef1+HDSPM_SyncRef0: return 3; /* AES 3 */
1638 case HDSPM_SyncRef1: return 2; 2394 case HDSPM_SyncRef2: return 4; /* AES 4 */
1639 case HDSPM_SyncRef1+HDSPM_SyncRef0: return 3; 2395 case HDSPM_SyncRef2+HDSPM_SyncRef0: return 5; /* AES 5 */
1640 case HDSPM_SyncRef2: return 4; 2396 case HDSPM_SyncRef2+HDSPM_SyncRef1: return 6; /* AES 6 */
1641 case HDSPM_SyncRef2+HDSPM_SyncRef0: return 5; 2397 case HDSPM_SyncRef2+HDSPM_SyncRef1+HDSPM_SyncRef0:
1642 case HDSPM_SyncRef2+HDSPM_SyncRef1: return 6; 2398 return 7; /* AES 7 */
1643 case HDSPM_SyncRef2+HDSPM_SyncRef1+HDSPM_SyncRef0: return 7; 2399 case HDSPM_SyncRef3: return 8; /* AES 8 */
1644 case HDSPM_SyncRef3: return 8; 2400 case HDSPM_SyncRef3+HDSPM_SyncRef0: return 9; /* TCO */
1645 } 2401 }
1646 } else { 2402 break;
1647 switch (hdspm->control_register & HDSPM_SyncRefMask) { 2403
1648 case HDSPM_SyncRef_Word: 2404 case MADI:
1649 return HDSPM_SYNC_FROM_WORD; 2405 case MADIface:
1650 case HDSPM_SyncRef_MADI: 2406 if (hdspm->tco) {
1651 return HDSPM_SYNC_FROM_MADI; 2407 switch (hdspm->control_register & HDSPM_SyncRefMask) {
2408 case 0: return 0; /* WC */
2409 case HDSPM_SyncRef0: return 1; /* MADI */
2410 case HDSPM_SyncRef1: return 2; /* TCO */
2411 case HDSPM_SyncRef1+HDSPM_SyncRef0:
2412 return 3; /* SYNC_IN */
2413 }
2414 } else {
2415 switch (hdspm->control_register & HDSPM_SyncRefMask) {
2416 case 0: return 0; /* WC */
2417 case HDSPM_SyncRef0: return 1; /* MADI */
2418 case HDSPM_SyncRef1+HDSPM_SyncRef0:
2419 return 2; /* SYNC_IN */
2420 }
2421 }
2422 break;
2423
2424 case RayDAT:
2425 if (hdspm->tco) {
2426 switch ((hdspm->settings_register &
2427 HDSPM_c0_SyncRefMask) / HDSPM_c0_SyncRef0) {
2428 case 0: return 0; /* WC */
2429 case 3: return 1; /* ADAT 1 */
2430 case 4: return 2; /* ADAT 2 */
2431 case 5: return 3; /* ADAT 3 */
2432 case 6: return 4; /* ADAT 4 */
2433 case 1: return 5; /* AES */
2434 case 2: return 6; /* SPDIF */
2435 case 9: return 7; /* TCO */
2436 case 10: return 8; /* SYNC_IN */
2437 }
2438 } else {
2439 switch ((hdspm->settings_register &
2440 HDSPM_c0_SyncRefMask) / HDSPM_c0_SyncRef0) {
2441 case 0: return 0; /* WC */
2442 case 3: return 1; /* ADAT 1 */
2443 case 4: return 2; /* ADAT 2 */
2444 case 5: return 3; /* ADAT 3 */
2445 case 6: return 4; /* ADAT 4 */
2446 case 1: return 5; /* AES */
2447 case 2: return 6; /* SPDIF */
2448 case 10: return 7; /* SYNC_IN */
2449 }
1652 } 2450 }
2451
2452 break;
2453
2454 case AIO:
2455 if (hdspm->tco) {
2456 switch ((hdspm->settings_register &
2457 HDSPM_c0_SyncRefMask) / HDSPM_c0_SyncRef0) {
2458 case 0: return 0; /* WC */
2459 case 3: return 1; /* ADAT */
2460 case 1: return 2; /* AES */
2461 case 2: return 3; /* SPDIF */
2462 case 9: return 4; /* TCO */
2463 case 10: return 5; /* SYNC_IN */
2464 }
2465 } else {
2466 switch ((hdspm->settings_register &
2467 HDSPM_c0_SyncRefMask) / HDSPM_c0_SyncRef0) {
2468 case 0: return 0; /* WC */
2469 case 3: return 1; /* ADAT */
2470 case 1: return 2; /* AES */
2471 case 2: return 3; /* SPDIF */
2472 case 10: return 4; /* SYNC_IN */
2473 }
2474 }
2475
2476 break;
1653 } 2477 }
1654 2478
1655 return HDSPM_SYNC_FROM_WORD; 2479 return -1;
1656} 2480}
1657 2481
2482
2483/**
2484 * Set the preferred sync reference to <pref>. The semantics
2485 * of <pref> are depending on the card type, see the comments
2486 * for clarification.
2487 **/
1658static int hdspm_set_pref_sync_ref(struct hdspm * hdspm, int pref) 2488static int hdspm_set_pref_sync_ref(struct hdspm * hdspm, int pref)
1659{ 2489{
1660 hdspm->control_register &= ~HDSPM_SyncRefMask; 2490 int p = 0;
1661 2491
1662 if (hdspm->is_aes32) { 2492 switch (hdspm->io_type) {
1663 switch (pref) { 2493 case AES32:
1664 case 0: 2494 hdspm->control_register &= ~HDSPM_SyncRefMask;
1665 hdspm->control_register |= 0;
1666 break;
1667 case 1:
1668 hdspm->control_register |= HDSPM_SyncRef0;
1669 break;
1670 case 2:
1671 hdspm->control_register |= HDSPM_SyncRef1;
1672 break;
1673 case 3:
1674 hdspm->control_register |= HDSPM_SyncRef1+HDSPM_SyncRef0;
1675 break;
1676 case 4:
1677 hdspm->control_register |= HDSPM_SyncRef2;
1678 break;
1679 case 5:
1680 hdspm->control_register |= HDSPM_SyncRef2+HDSPM_SyncRef0;
1681 break;
1682 case 6:
1683 hdspm->control_register |= HDSPM_SyncRef2+HDSPM_SyncRef1;
1684 break;
1685 case 7:
1686 hdspm->control_register |=
1687 HDSPM_SyncRef2+HDSPM_SyncRef1+HDSPM_SyncRef0;
1688 break;
1689 case 8:
1690 hdspm->control_register |= HDSPM_SyncRef3;
1691 break;
1692 default:
1693 return -1;
1694 }
1695 } else {
1696 switch (pref) { 2495 switch (pref) {
1697 case HDSPM_SYNC_FROM_MADI: 2496 case 0: /* WC */
1698 hdspm->control_register |= HDSPM_SyncRef_MADI; 2497 break;
2498 case 1: /* AES 1 */
2499 hdspm->control_register |= HDSPM_SyncRef0;
2500 break;
2501 case 2: /* AES 2 */
2502 hdspm->control_register |= HDSPM_SyncRef1;
2503 break;
2504 case 3: /* AES 3 */
2505 hdspm->control_register |=
2506 HDSPM_SyncRef1+HDSPM_SyncRef0;
2507 break;
2508 case 4: /* AES 4 */
2509 hdspm->control_register |= HDSPM_SyncRef2;
2510 break;
2511 case 5: /* AES 5 */
2512 hdspm->control_register |=
2513 HDSPM_SyncRef2+HDSPM_SyncRef0;
1699 break; 2514 break;
1700 case HDSPM_SYNC_FROM_WORD: 2515 case 6: /* AES 6 */
1701 hdspm->control_register |= HDSPM_SyncRef_Word; 2516 hdspm->control_register |=
2517 HDSPM_SyncRef2+HDSPM_SyncRef1;
2518 break;
2519 case 7: /* AES 7 */
2520 hdspm->control_register |=
2521 HDSPM_SyncRef2+HDSPM_SyncRef1+HDSPM_SyncRef0;
2522 break;
2523 case 8: /* AES 8 */
2524 hdspm->control_register |= HDSPM_SyncRef3;
2525 break;
2526 case 9: /* TCO */
2527 hdspm->control_register |=
2528 HDSPM_SyncRef3+HDSPM_SyncRef0;
1702 break; 2529 break;
1703 default: 2530 default:
1704 return -1; 2531 return -1;
1705 } 2532 }
2533
2534 break;
2535
2536 case MADI:
2537 case MADIface:
2538 hdspm->control_register &= ~HDSPM_SyncRefMask;
2539 if (hdspm->tco) {
2540 switch (pref) {
2541 case 0: /* WC */
2542 break;
2543 case 1: /* MADI */
2544 hdspm->control_register |= HDSPM_SyncRef0;
2545 break;
2546 case 2: /* TCO */
2547 hdspm->control_register |= HDSPM_SyncRef1;
2548 break;
2549 case 3: /* SYNC_IN */
2550 hdspm->control_register |=
2551 HDSPM_SyncRef0+HDSPM_SyncRef1;
2552 break;
2553 default:
2554 return -1;
2555 }
2556 } else {
2557 switch (pref) {
2558 case 0: /* WC */
2559 break;
2560 case 1: /* MADI */
2561 hdspm->control_register |= HDSPM_SyncRef0;
2562 break;
2563 case 2: /* SYNC_IN */
2564 hdspm->control_register |=
2565 HDSPM_SyncRef0+HDSPM_SyncRef1;
2566 break;
2567 default:
2568 return -1;
2569 }
2570 }
2571
2572 break;
2573
2574 case RayDAT:
2575 if (hdspm->tco) {
2576 switch (pref) {
2577 case 0: p = 0; break; /* WC */
2578 case 1: p = 3; break; /* ADAT 1 */
2579 case 2: p = 4; break; /* ADAT 2 */
2580 case 3: p = 5; break; /* ADAT 3 */
2581 case 4: p = 6; break; /* ADAT 4 */
2582 case 5: p = 1; break; /* AES */
2583 case 6: p = 2; break; /* SPDIF */
2584 case 7: p = 9; break; /* TCO */
2585 case 8: p = 10; break; /* SYNC_IN */
2586 default: return -1;
2587 }
2588 } else {
2589 switch (pref) {
2590 case 0: p = 0; break; /* WC */
2591 case 1: p = 3; break; /* ADAT 1 */
2592 case 2: p = 4; break; /* ADAT 2 */
2593 case 3: p = 5; break; /* ADAT 3 */
2594 case 4: p = 6; break; /* ADAT 4 */
2595 case 5: p = 1; break; /* AES */
2596 case 6: p = 2; break; /* SPDIF */
2597 case 7: p = 10; break; /* SYNC_IN */
2598 default: return -1;
2599 }
2600 }
2601 break;
2602
2603 case AIO:
2604 if (hdspm->tco) {
2605 switch (pref) {
2606 case 0: p = 0; break; /* WC */
2607 case 1: p = 3; break; /* ADAT */
2608 case 2: p = 1; break; /* AES */
2609 case 3: p = 2; break; /* SPDIF */
2610 case 4: p = 9; break; /* TCO */
2611 case 5: p = 10; break; /* SYNC_IN */
2612 default: return -1;
2613 }
2614 } else {
2615 switch (pref) {
2616 case 0: p = 0; break; /* WC */
2617 case 1: p = 3; break; /* ADAT */
2618 case 2: p = 1; break; /* AES */
2619 case 3: p = 2; break; /* SPDIF */
2620 case 4: p = 10; break; /* SYNC_IN */
2621 default: return -1;
2622 }
2623 }
2624 break;
1706 } 2625 }
1707 hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register); 2626
2627 switch (hdspm->io_type) {
2628 case RayDAT:
2629 case AIO:
2630 hdspm->settings_register &= ~HDSPM_c0_SyncRefMask;
2631 hdspm->settings_register |= HDSPM_c0_SyncRef0 * p;
2632 hdspm_write(hdspm, HDSPM_WR_SETTINGS, hdspm->settings_register);
2633 break;
2634
2635 case MADI:
2636 case MADIface:
2637 case AES32:
2638 hdspm_write(hdspm, HDSPM_controlRegister,
2639 hdspm->control_register);
2640 }
2641
1708 return 0; 2642 return 0;
1709} 2643}
1710 2644
2645
1711static int snd_hdspm_info_pref_sync_ref(struct snd_kcontrol *kcontrol, 2646static int snd_hdspm_info_pref_sync_ref(struct snd_kcontrol *kcontrol,
1712 struct snd_ctl_elem_info *uinfo) 2647 struct snd_ctl_elem_info *uinfo)
1713{ 2648{
1714 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); 2649 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
1715 2650
1716 if (hdspm->is_aes32) { 2651 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1717 static char *texts[] = { "Word", "AES1", "AES2", "AES3", 2652 uinfo->count = 1;
1718 "AES4", "AES5", "AES6", "AES7", "AES8" }; 2653 uinfo->value.enumerated.items = hdspm->texts_autosync_items;
1719
1720 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1721 uinfo->count = 1;
1722
1723 uinfo->value.enumerated.items = 9;
1724
1725 if (uinfo->value.enumerated.item >=
1726 uinfo->value.enumerated.items)
1727 uinfo->value.enumerated.item =
1728 uinfo->value.enumerated.items - 1;
1729 strcpy(uinfo->value.enumerated.name,
1730 texts[uinfo->value.enumerated.item]);
1731 } else {
1732 static char *texts[] = { "Word", "MADI" };
1733 2654
1734 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 2655 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1735 uinfo->count = 1; 2656 uinfo->value.enumerated.item =
2657 uinfo->value.enumerated.items - 1;
1736 2658
1737 uinfo->value.enumerated.items = 2; 2659 strcpy(uinfo->value.enumerated.name,
2660 hdspm->texts_autosync[uinfo->value.enumerated.item]);
1738 2661
1739 if (uinfo->value.enumerated.item >=
1740 uinfo->value.enumerated.items)
1741 uinfo->value.enumerated.item =
1742 uinfo->value.enumerated.items - 1;
1743 strcpy(uinfo->value.enumerated.name,
1744 texts[uinfo->value.enumerated.item]);
1745 }
1746 return 0; 2662 return 0;
1747} 2663}
1748 2664
@@ -1750,32 +2666,41 @@ static int snd_hdspm_get_pref_sync_ref(struct snd_kcontrol *kcontrol,
1750 struct snd_ctl_elem_value *ucontrol) 2666 struct snd_ctl_elem_value *ucontrol)
1751{ 2667{
1752 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); 2668 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
2669 int psf = hdspm_pref_sync_ref(hdspm);
1753 2670
1754 ucontrol->value.enumerated.item[0] = hdspm_pref_sync_ref(hdspm); 2671 if (psf >= 0) {
1755 return 0; 2672 ucontrol->value.enumerated.item[0] = psf;
2673 return 0;
2674 }
2675
2676 return -1;
1756} 2677}
1757 2678
1758static int snd_hdspm_put_pref_sync_ref(struct snd_kcontrol *kcontrol, 2679static int snd_hdspm_put_pref_sync_ref(struct snd_kcontrol *kcontrol,
1759 struct snd_ctl_elem_value *ucontrol) 2680 struct snd_ctl_elem_value *ucontrol)
1760{ 2681{
1761 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); 2682 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
1762 int change, max; 2683 int val, change = 0;
1763 unsigned int val;
1764
1765 max = hdspm->is_aes32 ? 9 : 2;
1766 2684
1767 if (!snd_hdspm_use_is_exclusive(hdspm)) 2685 if (!snd_hdspm_use_is_exclusive(hdspm))
1768 return -EBUSY; 2686 return -EBUSY;
1769 2687
1770 val = ucontrol->value.enumerated.item[0] % max; 2688 val = ucontrol->value.enumerated.item[0];
2689
2690 if (val < 0)
2691 val = 0;
2692 else if (val >= hdspm->texts_autosync_items)
2693 val = hdspm->texts_autosync_items-1;
1771 2694
1772 spin_lock_irq(&hdspm->lock); 2695 spin_lock_irq(&hdspm->lock);
1773 change = (int) val != hdspm_pref_sync_ref(hdspm); 2696 if (val != hdspm_pref_sync_ref(hdspm))
1774 hdspm_set_pref_sync_ref(hdspm, val); 2697 change = (0 == hdspm_set_pref_sync_ref(hdspm, val)) ? 1 : 0;
2698
1775 spin_unlock_irq(&hdspm->lock); 2699 spin_unlock_irq(&hdspm->lock);
1776 return change; 2700 return change;
1777} 2701}
1778 2702
2703
1779#define HDSPM_AUTOSYNC_REF(xname, xindex) \ 2704#define HDSPM_AUTOSYNC_REF(xname, xindex) \
1780{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2705{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1781 .name = xname, \ 2706 .name = xname, \
@@ -1785,18 +2710,18 @@ static int snd_hdspm_put_pref_sync_ref(struct snd_kcontrol *kcontrol,
1785 .get = snd_hdspm_get_autosync_ref, \ 2710 .get = snd_hdspm_get_autosync_ref, \
1786} 2711}
1787 2712
1788static int hdspm_autosync_ref(struct hdspm * hdspm) 2713static int hdspm_autosync_ref(struct hdspm *hdspm)
1789{ 2714{
1790 if (hdspm->is_aes32) { 2715 if (AES32 == hdspm->io_type) {
1791 unsigned int status = hdspm_read(hdspm, HDSPM_statusRegister); 2716 unsigned int status = hdspm_read(hdspm, HDSPM_statusRegister);
1792 unsigned int syncref = (status >> HDSPM_AES32_syncref_bit) & 2717 unsigned int syncref =
1793 0xF; 2718 (status >> HDSPM_AES32_syncref_bit) & 0xF;
1794 if (syncref == 0) 2719 if (syncref == 0)
1795 return HDSPM_AES32_AUTOSYNC_FROM_WORD; 2720 return HDSPM_AES32_AUTOSYNC_FROM_WORD;
1796 if (syncref <= 8) 2721 if (syncref <= 8)
1797 return syncref; 2722 return syncref;
1798 return HDSPM_AES32_AUTOSYNC_FROM_NONE; 2723 return HDSPM_AES32_AUTOSYNC_FROM_NONE;
1799 } else { 2724 } else if (MADI == hdspm->io_type) {
1800 /* This looks at the autosync selected sync reference */ 2725 /* This looks at the autosync selected sync reference */
1801 unsigned int status2 = hdspm_read(hdspm, HDSPM_statusRegister2); 2726 unsigned int status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
1802 2727
@@ -1805,22 +2730,27 @@ static int hdspm_autosync_ref(struct hdspm * hdspm)
1805 return HDSPM_AUTOSYNC_FROM_WORD; 2730 return HDSPM_AUTOSYNC_FROM_WORD;
1806 case HDSPM_SelSyncRef_MADI: 2731 case HDSPM_SelSyncRef_MADI:
1807 return HDSPM_AUTOSYNC_FROM_MADI; 2732 return HDSPM_AUTOSYNC_FROM_MADI;
2733 case HDSPM_SelSyncRef_TCO:
2734 return HDSPM_AUTOSYNC_FROM_TCO;
2735 case HDSPM_SelSyncRef_SyncIn:
2736 return HDSPM_AUTOSYNC_FROM_SYNC_IN;
1808 case HDSPM_SelSyncRef_NVALID: 2737 case HDSPM_SelSyncRef_NVALID:
1809 return HDSPM_AUTOSYNC_FROM_NONE; 2738 return HDSPM_AUTOSYNC_FROM_NONE;
1810 default: 2739 default:
1811 return 0; 2740 return 0;
1812 } 2741 }
1813 2742
1814 return 0;
1815 } 2743 }
2744 return 0;
1816} 2745}
1817 2746
2747
1818static int snd_hdspm_info_autosync_ref(struct snd_kcontrol *kcontrol, 2748static int snd_hdspm_info_autosync_ref(struct snd_kcontrol *kcontrol,
1819 struct snd_ctl_elem_info *uinfo) 2749 struct snd_ctl_elem_info *uinfo)
1820{ 2750{
1821 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); 2751 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
1822 2752
1823 if (hdspm->is_aes32) { 2753 if (AES32 == hdspm->io_type) {
1824 static char *texts[] = { "WordClock", "AES1", "AES2", "AES3", 2754 static char *texts[] = { "WordClock", "AES1", "AES2", "AES3",
1825 "AES4", "AES5", "AES6", "AES7", "AES8", "None"}; 2755 "AES4", "AES5", "AES6", "AES7", "AES8", "None"};
1826 2756
@@ -1833,14 +2763,15 @@ static int snd_hdspm_info_autosync_ref(struct snd_kcontrol *kcontrol,
1833 uinfo->value.enumerated.items - 1; 2763 uinfo->value.enumerated.items - 1;
1834 strcpy(uinfo->value.enumerated.name, 2764 strcpy(uinfo->value.enumerated.name,
1835 texts[uinfo->value.enumerated.item]); 2765 texts[uinfo->value.enumerated.item]);
1836 } else { 2766 } else if (MADI == hdspm->io_type) {
1837 static char *texts[] = { "WordClock", "MADI", "None" }; 2767 static char *texts[] = {"Word Clock", "MADI", "TCO",
2768 "Sync In", "None" };
1838 2769
1839 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 2770 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1840 uinfo->count = 1; 2771 uinfo->count = 1;
1841 uinfo->value.enumerated.items = 3; 2772 uinfo->value.enumerated.items = 5;
1842 if (uinfo->value.enumerated.item >= 2773 if (uinfo->value.enumerated.item >=
1843 uinfo->value.enumerated.items) 2774 uinfo->value.enumerated.items)
1844 uinfo->value.enumerated.item = 2775 uinfo->value.enumerated.item =
1845 uinfo->value.enumerated.items - 1; 2776 uinfo->value.enumerated.items - 1;
1846 strcpy(uinfo->value.enumerated.name, 2777 strcpy(uinfo->value.enumerated.name,
@@ -1858,6 +2789,7 @@ static int snd_hdspm_get_autosync_ref(struct snd_kcontrol *kcontrol,
1858 return 0; 2789 return 0;
1859} 2790}
1860 2791
2792
1861#define HDSPM_LINE_OUT(xname, xindex) \ 2793#define HDSPM_LINE_OUT(xname, xindex) \
1862{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2794{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1863 .name = xname, \ 2795 .name = xname, \
@@ -1914,6 +2846,7 @@ static int snd_hdspm_put_line_out(struct snd_kcontrol *kcontrol,
1914 return change; 2846 return change;
1915} 2847}
1916 2848
2849
1917#define HDSPM_TX_64(xname, xindex) \ 2850#define HDSPM_TX_64(xname, xindex) \
1918{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2851{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1919 .name = xname, \ 2852 .name = xname, \
@@ -1969,6 +2902,7 @@ static int snd_hdspm_put_tx_64(struct snd_kcontrol *kcontrol,
1969 return change; 2902 return change;
1970} 2903}
1971 2904
2905
1972#define HDSPM_C_TMS(xname, xindex) \ 2906#define HDSPM_C_TMS(xname, xindex) \
1973{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2907{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1974 .name = xname, \ 2908 .name = xname, \
@@ -2024,6 +2958,7 @@ static int snd_hdspm_put_c_tms(struct snd_kcontrol *kcontrol,
2024 return change; 2958 return change;
2025} 2959}
2026 2960
2961
2027#define HDSPM_SAFE_MODE(xname, xindex) \ 2962#define HDSPM_SAFE_MODE(xname, xindex) \
2028{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2963{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2029 .name = xname, \ 2964 .name = xname, \
@@ -2079,6 +3014,7 @@ static int snd_hdspm_put_safe_mode(struct snd_kcontrol *kcontrol,
2079 return change; 3014 return change;
2080} 3015}
2081 3016
3017
2082#define HDSPM_EMPHASIS(xname, xindex) \ 3018#define HDSPM_EMPHASIS(xname, xindex) \
2083{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 3019{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2084 .name = xname, \ 3020 .name = xname, \
@@ -2134,6 +3070,7 @@ static int snd_hdspm_put_emphasis(struct snd_kcontrol *kcontrol,
2134 return change; 3070 return change;
2135} 3071}
2136 3072
3073
2137#define HDSPM_DOLBY(xname, xindex) \ 3074#define HDSPM_DOLBY(xname, xindex) \
2138{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 3075{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2139 .name = xname, \ 3076 .name = xname, \
@@ -2189,6 +3126,7 @@ static int snd_hdspm_put_dolby(struct snd_kcontrol *kcontrol,
2189 return change; 3126 return change;
2190} 3127}
2191 3128
3129
2192#define HDSPM_PROFESSIONAL(xname, xindex) \ 3130#define HDSPM_PROFESSIONAL(xname, xindex) \
2193{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 3131{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2194 .name = xname, \ 3132 .name = xname, \
@@ -2315,6 +3253,7 @@ static int snd_hdspm_put_input_select(struct snd_kcontrol *kcontrol,
2315 return change; 3253 return change;
2316} 3254}
2317 3255
3256
2318#define HDSPM_DS_WIRE(xname, xindex) \ 3257#define HDSPM_DS_WIRE(xname, xindex) \
2319{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 3258{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2320 .name = xname, \ 3259 .name = xname, \
@@ -2386,6 +3325,7 @@ static int snd_hdspm_put_ds_wire(struct snd_kcontrol *kcontrol,
2386 return change; 3325 return change;
2387} 3326}
2388 3327
3328
2389#define HDSPM_QS_WIRE(xname, xindex) \ 3329#define HDSPM_QS_WIRE(xname, xindex) \
2390{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 3330{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2391 .name = xname, \ 3331 .name = xname, \
@@ -2472,15 +3412,6 @@ static int snd_hdspm_put_qs_wire(struct snd_kcontrol *kcontrol,
2472 return change; 3412 return change;
2473} 3413}
2474 3414
2475/* Simple Mixer
2476 deprecated since to much faders ???
2477 MIXER interface says output (source, destination, value)
2478 where source > MAX_channels are playback channels
2479 on MADICARD
2480 - playback mixer matrix: [channelout+64] [output] [value]
2481 - input(thru) mixer matrix: [channelin] [output] [value]
2482 (better do 2 kontrols for separation ?)
2483*/
2484 3415
2485#define HDSPM_MIXER(xname, xindex) \ 3416#define HDSPM_MIXER(xname, xindex) \
2486{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ 3417{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \
@@ -2586,7 +3517,7 @@ static int snd_hdspm_put_mixer(struct snd_kcontrol *kcontrol,
2586 3517
2587/* The simple mixer control(s) provide gain control for the 3518/* The simple mixer control(s) provide gain control for the
2588 basic 1:1 mappings of playback streams to output 3519 basic 1:1 mappings of playback streams to output
2589 streams. 3520 streams.
2590*/ 3521*/
2591 3522
2592#define HDSPM_PLAYBACK_MIXER \ 3523#define HDSPM_PLAYBACK_MIXER \
@@ -2604,7 +3535,7 @@ static int snd_hdspm_info_playback_mixer(struct snd_kcontrol *kcontrol,
2604 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 3535 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2605 uinfo->count = 1; 3536 uinfo->count = 1;
2606 uinfo->value.integer.min = 0; 3537 uinfo->value.integer.min = 0;
2607 uinfo->value.integer.max = 65536; 3538 uinfo->value.integer.max = 64;
2608 uinfo->value.integer.step = 1; 3539 uinfo->value.integer.step = 1;
2609 return 0; 3540 return 0;
2610} 3541}
@@ -2614,28 +3545,17 @@ static int snd_hdspm_get_playback_mixer(struct snd_kcontrol *kcontrol,
2614{ 3545{
2615 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); 3546 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
2616 int channel; 3547 int channel;
2617 int mapped_channel;
2618 3548
2619 channel = ucontrol->id.index - 1; 3549 channel = ucontrol->id.index - 1;
2620 3550
2621 if (snd_BUG_ON(channel < 0 || channel >= HDSPM_MAX_CHANNELS)) 3551 if (snd_BUG_ON(channel < 0 || channel >= HDSPM_MAX_CHANNELS))
2622 return -EINVAL; 3552 return -EINVAL;
2623 3553
2624 mapped_channel = hdspm->channel_map[channel];
2625 if (mapped_channel < 0)
2626 return -EINVAL;
2627
2628 spin_lock_irq(&hdspm->lock); 3554 spin_lock_irq(&hdspm->lock);
2629 ucontrol->value.integer.value[0] = 3555 ucontrol->value.integer.value[0] =
2630 hdspm_read_pb_gain(hdspm, mapped_channel, mapped_channel); 3556 (hdspm_read_pb_gain(hdspm, channel, channel)*64)/UNITY_GAIN;
2631 spin_unlock_irq(&hdspm->lock); 3557 spin_unlock_irq(&hdspm->lock);
2632 3558
2633 /*
2634 snd_printdd("get pb mixer index %d, channel %d, mapped_channel %d, "
2635 "value %d\n",
2636 ucontrol->id.index, channel, mapped_channel,
2637 ucontrol->value.integer.value[0]);
2638 */
2639 return 0; 3559 return 0;
2640} 3560}
2641 3561
@@ -2645,7 +3565,6 @@ static int snd_hdspm_put_playback_mixer(struct snd_kcontrol *kcontrol,
2645 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); 3565 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
2646 int change; 3566 int change;
2647 int channel; 3567 int channel;
2648 int mapped_channel;
2649 int gain; 3568 int gain;
2650 3569
2651 if (!snd_hdspm_use_is_exclusive(hdspm)) 3570 if (!snd_hdspm_use_is_exclusive(hdspm))
@@ -2656,59 +3575,60 @@ static int snd_hdspm_put_playback_mixer(struct snd_kcontrol *kcontrol,
2656 if (snd_BUG_ON(channel < 0 || channel >= HDSPM_MAX_CHANNELS)) 3575 if (snd_BUG_ON(channel < 0 || channel >= HDSPM_MAX_CHANNELS))
2657 return -EINVAL; 3576 return -EINVAL;
2658 3577
2659 mapped_channel = hdspm->channel_map[channel]; 3578 gain = ucontrol->value.integer.value[0]*UNITY_GAIN/64;
2660 if (mapped_channel < 0)
2661 return -EINVAL;
2662
2663 gain = ucontrol->value.integer.value[0];
2664 3579
2665 spin_lock_irq(&hdspm->lock); 3580 spin_lock_irq(&hdspm->lock);
2666 change = 3581 change =
2667 gain != hdspm_read_pb_gain(hdspm, mapped_channel, 3582 gain != hdspm_read_pb_gain(hdspm, channel,
2668 mapped_channel); 3583 channel);
2669 if (change) 3584 if (change)
2670 hdspm_write_pb_gain(hdspm, mapped_channel, mapped_channel, 3585 hdspm_write_pb_gain(hdspm, channel, channel,
2671 gain); 3586 gain);
2672 spin_unlock_irq(&hdspm->lock); 3587 spin_unlock_irq(&hdspm->lock);
2673 return change; 3588 return change;
2674} 3589}
2675 3590
2676#define HDSPM_WC_SYNC_CHECK(xname, xindex) \ 3591#define HDSPM_SYNC_CHECK(xname, xindex) \
2677{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 3592{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2678 .name = xname, \ 3593 .name = xname, \
2679 .index = xindex, \ 3594 .private_value = xindex, \
2680 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ 3595 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
2681 .info = snd_hdspm_info_sync_check, \ 3596 .info = snd_hdspm_info_sync_check, \
2682 .get = snd_hdspm_get_wc_sync_check \ 3597 .get = snd_hdspm_get_sync_check \
2683} 3598}
2684 3599
3600
2685static int snd_hdspm_info_sync_check(struct snd_kcontrol *kcontrol, 3601static int snd_hdspm_info_sync_check(struct snd_kcontrol *kcontrol,
2686 struct snd_ctl_elem_info *uinfo) 3602 struct snd_ctl_elem_info *uinfo)
2687{ 3603{
2688 static char *texts[] = { "No Lock", "Lock", "Sync" }; 3604 static char *texts[] = { "No Lock", "Lock", "Sync", "N/A" };
2689 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 3605 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2690 uinfo->count = 1; 3606 uinfo->count = 1;
2691 uinfo->value.enumerated.items = 3; 3607 uinfo->value.enumerated.items = 4;
2692 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) 3608 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2693 uinfo->value.enumerated.item = 3609 uinfo->value.enumerated.item =
2694 uinfo->value.enumerated.items - 1; 3610 uinfo->value.enumerated.items - 1;
2695 strcpy(uinfo->value.enumerated.name, 3611 strcpy(uinfo->value.enumerated.name,
2696 texts[uinfo->value.enumerated.item]); 3612 texts[uinfo->value.enumerated.item]);
2697 return 0; 3613 return 0;
2698} 3614}
2699 3615
2700static int hdspm_wc_sync_check(struct hdspm * hdspm) 3616static int hdspm_wc_sync_check(struct hdspm *hdspm)
2701{ 3617{
2702 if (hdspm->is_aes32) { 3618 int status, status2;
2703 int status = hdspm_read(hdspm, HDSPM_statusRegister); 3619
2704 if (status & HDSPM_AES32_wcLock) { 3620 switch (hdspm->io_type) {
2705 /* I don't know how to differenciate sync from lock. 3621 case AES32:
2706 Doing as if sync for now */ 3622 status = hdspm_read(hdspm, HDSPM_statusRegister);
3623 if (status & HDSPM_wcSync)
2707 return 2; 3624 return 2;
2708 } 3625 else if (status & HDSPM_wcLock)
3626 return 1;
2709 return 0; 3627 return 0;
2710 } else { 3628 break;
2711 int status2 = hdspm_read(hdspm, HDSPM_statusRegister2); 3629
3630 case MADI:
3631 status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
2712 if (status2 & HDSPM_wcLock) { 3632 if (status2 & HDSPM_wcLock) {
2713 if (status2 & HDSPM_wcSync) 3633 if (status2 & HDSPM_wcSync)
2714 return 2; 3634 return 2;
@@ -2716,29 +3636,30 @@ static int hdspm_wc_sync_check(struct hdspm * hdspm)
2716 return 1; 3636 return 1;
2717 } 3637 }
2718 return 0; 3638 return 0;
2719 } 3639 break;
2720}
2721 3640
2722static int snd_hdspm_get_wc_sync_check(struct snd_kcontrol *kcontrol, 3641 case RayDAT:
2723 struct snd_ctl_elem_value *ucontrol) 3642 case AIO:
2724{ 3643 status = hdspm_read(hdspm, HDSPM_statusRegister);
2725 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
2726 3644
2727 ucontrol->value.enumerated.item[0] = hdspm_wc_sync_check(hdspm); 3645 if (status & 0x2000000)
2728 return 0; 3646 return 2;
2729} 3647 else if (status & 0x1000000)
3648 return 1;
3649 return 0;
2730 3650
3651 break;
2731 3652
2732#define HDSPM_MADI_SYNC_CHECK(xname, xindex) \ 3653 case MADIface:
2733{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 3654 break;
2734 .name = xname, \ 3655 }
2735 .index = xindex, \ 3656
2736 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ 3657
2737 .info = snd_hdspm_info_sync_check, \ 3658 return 3;
2738 .get = snd_hdspm_get_madisync_sync_check \
2739} 3659}
2740 3660
2741static int hdspm_madisync_sync_check(struct hdspm * hdspm) 3661
3662static int hdspm_madi_sync_check(struct hdspm *hdspm)
2742{ 3663{
2743 int status = hdspm_read(hdspm, HDSPM_statusRegister); 3664 int status = hdspm_read(hdspm, HDSPM_statusRegister);
2744 if (status & HDSPM_madiLock) { 3665 if (status & HDSPM_madiLock) {
@@ -2750,89 +3671,726 @@ static int hdspm_madisync_sync_check(struct hdspm * hdspm)
2750 return 0; 3671 return 0;
2751} 3672}
2752 3673
2753static int snd_hdspm_get_madisync_sync_check(struct snd_kcontrol *kcontrol, 3674
2754 struct snd_ctl_elem_value * 3675static int hdspm_s1_sync_check(struct hdspm *hdspm, int idx)
2755 ucontrol)
2756{ 3676{
2757 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); 3677 int status, lock, sync;
3678
3679 status = hdspm_read(hdspm, HDSPM_RD_STATUS_1);
3680
3681 lock = (status & (0x1<<idx)) ? 1 : 0;
3682 sync = (status & (0x100<<idx)) ? 1 : 0;
2758 3683
2759 ucontrol->value.enumerated.item[0] = 3684 if (lock && sync)
2760 hdspm_madisync_sync_check(hdspm); 3685 return 2;
3686 else if (lock)
3687 return 1;
2761 return 0; 3688 return 0;
2762} 3689}
2763 3690
2764 3691
2765#define HDSPM_AES_SYNC_CHECK(xname, xindex) \ 3692static int hdspm_sync_in_sync_check(struct hdspm *hdspm)
2766{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 3693{
2767 .name = xname, \ 3694 int status, lock = 0, sync = 0;
2768 .index = xindex, \ 3695
2769 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ 3696 switch (hdspm->io_type) {
2770 .info = snd_hdspm_info_sync_check, \ 3697 case RayDAT:
2771 .get = snd_hdspm_get_aes_sync_check \ 3698 case AIO:
3699 status = hdspm_read(hdspm, HDSPM_RD_STATUS_3);
3700 lock = (status & 0x400) ? 1 : 0;
3701 sync = (status & 0x800) ? 1 : 0;
3702 break;
3703
3704 case MADI:
3705 case AES32:
3706 status = hdspm_read(hdspm, HDSPM_statusRegister2);
3707 lock = (status & HDSPM_syncInLock) ? 1 : 0;
3708 sync = (status & HDSPM_syncInSync) ? 1 : 0;
3709 break;
3710
3711 case MADIface:
3712 break;
3713 }
3714
3715 if (lock && sync)
3716 return 2;
3717 else if (lock)
3718 return 1;
3719
3720 return 0;
2772} 3721}
2773 3722
2774static int hdspm_aes_sync_check(struct hdspm * hdspm, int idx) 3723static int hdspm_aes_sync_check(struct hdspm *hdspm, int idx)
2775{ 3724{
2776 int status2 = hdspm_read(hdspm, HDSPM_statusRegister2); 3725 int status2, lock, sync;
2777 if (status2 & (HDSPM_LockAES >> idx)) { 3726 status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
2778 /* I don't know how to differenciate sync from lock. 3727
2779 Doing as if sync for now */ 3728 lock = (status2 & (0x0080 >> idx)) ? 1 : 0;
3729 sync = (status2 & (0x8000 >> idx)) ? 1 : 0;
3730
3731 if (sync)
2780 return 2; 3732 return 2;
3733 else if (lock)
3734 return 1;
3735 return 0;
3736}
3737
3738
3739static int hdspm_tco_sync_check(struct hdspm *hdspm)
3740{
3741 int status;
3742
3743 if (hdspm->tco) {
3744 switch (hdspm->io_type) {
3745 case MADI:
3746 case AES32:
3747 status = hdspm_read(hdspm, HDSPM_statusRegister);
3748 if (status & HDSPM_tcoLock) {
3749 if (status & HDSPM_tcoSync)
3750 return 2;
3751 else
3752 return 1;
3753 }
3754 return 0;
3755
3756 break;
3757
3758 case RayDAT:
3759 case AIO:
3760 status = hdspm_read(hdspm, HDSPM_RD_STATUS_1);
3761
3762 if (status & 0x8000000)
3763 return 2; /* Sync */
3764 if (status & 0x4000000)
3765 return 1; /* Lock */
3766 return 0; /* No signal */
3767 break;
3768
3769 default:
3770 break;
3771 }
3772 }
3773
3774 return 3; /* N/A */
3775}
3776
3777
3778static int snd_hdspm_get_sync_check(struct snd_kcontrol *kcontrol,
3779 struct snd_ctl_elem_value *ucontrol)
3780{
3781 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
3782 int val = -1;
3783
3784 switch (hdspm->io_type) {
3785 case RayDAT:
3786 switch (kcontrol->private_value) {
3787 case 0: /* WC */
3788 val = hdspm_wc_sync_check(hdspm); break;
3789 case 7: /* TCO */
3790 val = hdspm_tco_sync_check(hdspm); break;
3791 case 8: /* SYNC IN */
3792 val = hdspm_sync_in_sync_check(hdspm); break;
3793 default:
3794 val = hdspm_s1_sync_check(hdspm, ucontrol->id.index-1);
3795 }
3796
3797 case AIO:
3798 switch (kcontrol->private_value) {
3799 case 0: /* WC */
3800 val = hdspm_wc_sync_check(hdspm); break;
3801 case 4: /* TCO */
3802 val = hdspm_tco_sync_check(hdspm); break;
3803 case 5: /* SYNC IN */
3804 val = hdspm_sync_in_sync_check(hdspm); break;
3805 default:
3806 val = hdspm_s1_sync_check(hdspm, ucontrol->id.index-1);
3807 }
3808
3809 case MADI:
3810 switch (kcontrol->private_value) {
3811 case 0: /* WC */
3812 val = hdspm_wc_sync_check(hdspm); break;
3813 case 1: /* MADI */
3814 val = hdspm_madi_sync_check(hdspm); break;
3815 case 2: /* TCO */
3816 val = hdspm_tco_sync_check(hdspm); break;
3817 case 3: /* SYNC_IN */
3818 val = hdspm_sync_in_sync_check(hdspm); break;
3819 }
3820
3821 case MADIface:
3822 val = hdspm_madi_sync_check(hdspm); /* MADI */
3823 break;
3824
3825 case AES32:
3826 switch (kcontrol->private_value) {
3827 case 0: /* WC */
3828 val = hdspm_wc_sync_check(hdspm); break;
3829 case 9: /* TCO */
3830 val = hdspm_tco_sync_check(hdspm); break;
3831 case 10 /* SYNC IN */:
3832 val = hdspm_sync_in_sync_check(hdspm); break;
3833 default: /* AES1 to AES8 */
3834 val = hdspm_aes_sync_check(hdspm,
3835 kcontrol->private_value-1);
3836 }
3837
2781 } 3838 }
3839
3840 if (-1 == val)
3841 val = 3;
3842
3843 ucontrol->value.enumerated.item[0] = val;
2782 return 0; 3844 return 0;
2783} 3845}
2784 3846
2785static int snd_hdspm_get_aes_sync_check(struct snd_kcontrol *kcontrol, 3847
3848
3849/**
3850 * TCO controls
3851 **/
3852static void hdspm_tco_write(struct hdspm *hdspm)
3853{
3854 unsigned int tc[4] = { 0, 0, 0, 0};
3855
3856 switch (hdspm->tco->input) {
3857 case 0:
3858 tc[2] |= HDSPM_TCO2_set_input_MSB;
3859 break;
3860 case 1:
3861 tc[2] |= HDSPM_TCO2_set_input_LSB;
3862 break;
3863 default:
3864 break;
3865 }
3866
3867 switch (hdspm->tco->framerate) {
3868 case 1:
3869 tc[1] |= HDSPM_TCO1_LTC_Format_LSB;
3870 break;
3871 case 2:
3872 tc[1] |= HDSPM_TCO1_LTC_Format_MSB;
3873 break;
3874 case 3:
3875 tc[1] |= HDSPM_TCO1_LTC_Format_MSB +
3876 HDSPM_TCO1_set_drop_frame_flag;
3877 break;
3878 case 4:
3879 tc[1] |= HDSPM_TCO1_LTC_Format_LSB +
3880 HDSPM_TCO1_LTC_Format_MSB;
3881 break;
3882 case 5:
3883 tc[1] |= HDSPM_TCO1_LTC_Format_LSB +
3884 HDSPM_TCO1_LTC_Format_MSB +
3885 HDSPM_TCO1_set_drop_frame_flag;
3886 break;
3887 default:
3888 break;
3889 }
3890
3891 switch (hdspm->tco->wordclock) {
3892 case 1:
3893 tc[2] |= HDSPM_TCO2_WCK_IO_ratio_LSB;
3894 break;
3895 case 2:
3896 tc[2] |= HDSPM_TCO2_WCK_IO_ratio_MSB;
3897 break;
3898 default:
3899 break;
3900 }
3901
3902 switch (hdspm->tco->samplerate) {
3903 case 1:
3904 tc[2] |= HDSPM_TCO2_set_freq;
3905 break;
3906 case 2:
3907 tc[2] |= HDSPM_TCO2_set_freq_from_app;
3908 break;
3909 default:
3910 break;
3911 }
3912
3913 switch (hdspm->tco->pull) {
3914 case 1:
3915 tc[2] |= HDSPM_TCO2_set_pull_up;
3916 break;
3917 case 2:
3918 tc[2] |= HDSPM_TCO2_set_pull_down;
3919 break;
3920 case 3:
3921 tc[2] |= HDSPM_TCO2_set_pull_up + HDSPM_TCO2_set_01_4;
3922 break;
3923 case 4:
3924 tc[2] |= HDSPM_TCO2_set_pull_down + HDSPM_TCO2_set_01_4;
3925 break;
3926 default:
3927 break;
3928 }
3929
3930 if (1 == hdspm->tco->term) {
3931 tc[2] |= HDSPM_TCO2_set_term_75R;
3932 }
3933
3934 hdspm_write(hdspm, HDSPM_WR_TCO, tc[0]);
3935 hdspm_write(hdspm, HDSPM_WR_TCO+4, tc[1]);
3936 hdspm_write(hdspm, HDSPM_WR_TCO+8, tc[2]);
3937 hdspm_write(hdspm, HDSPM_WR_TCO+12, tc[3]);
3938}
3939
3940
3941#define HDSPM_TCO_SAMPLE_RATE(xname, xindex) \
3942{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3943 .name = xname, \
3944 .index = xindex, \
3945 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
3946 SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
3947 .info = snd_hdspm_info_tco_sample_rate, \
3948 .get = snd_hdspm_get_tco_sample_rate, \
3949 .put = snd_hdspm_put_tco_sample_rate \
3950}
3951
3952static int snd_hdspm_info_tco_sample_rate(struct snd_kcontrol *kcontrol,
3953 struct snd_ctl_elem_info *uinfo)
3954{
3955 static char *texts[] = { "44.1 kHz", "48 kHz" };
3956 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3957 uinfo->count = 1;
3958 uinfo->value.enumerated.items = 2;
3959
3960 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
3961 uinfo->value.enumerated.item =
3962 uinfo->value.enumerated.items - 1;
3963
3964 strcpy(uinfo->value.enumerated.name,
3965 texts[uinfo->value.enumerated.item]);
3966
3967 return 0;
3968}
3969
3970static int snd_hdspm_get_tco_sample_rate(struct snd_kcontrol *kcontrol,
3971 struct snd_ctl_elem_value *ucontrol)
3972{
3973 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
3974
3975 ucontrol->value.enumerated.item[0] = hdspm->tco->samplerate;
3976
3977 return 0;
3978}
3979
3980static int snd_hdspm_put_tco_sample_rate(struct snd_kcontrol *kcontrol,
3981 struct snd_ctl_elem_value *ucontrol)
3982{
3983 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
3984
3985 if (hdspm->tco->samplerate != ucontrol->value.enumerated.item[0]) {
3986 hdspm->tco->samplerate = ucontrol->value.enumerated.item[0];
3987
3988 hdspm_tco_write(hdspm);
3989
3990 return 1;
3991 }
3992
3993 return 0;
3994}
3995
3996
3997#define HDSPM_TCO_PULL(xname, xindex) \
3998{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3999 .name = xname, \
4000 .index = xindex, \
4001 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
4002 SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
4003 .info = snd_hdspm_info_tco_pull, \
4004 .get = snd_hdspm_get_tco_pull, \
4005 .put = snd_hdspm_put_tco_pull \
4006}
4007
4008static int snd_hdspm_info_tco_pull(struct snd_kcontrol *kcontrol,
4009 struct snd_ctl_elem_info *uinfo)
4010{
4011 static char *texts[] = { "0", "+ 0.1 %", "- 0.1 %", "+ 4 %", "- 4 %" };
4012 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4013 uinfo->count = 1;
4014 uinfo->value.enumerated.items = 5;
4015
4016 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
4017 uinfo->value.enumerated.item =
4018 uinfo->value.enumerated.items - 1;
4019
4020 strcpy(uinfo->value.enumerated.name,
4021 texts[uinfo->value.enumerated.item]);
4022
4023 return 0;
4024}
4025
4026static int snd_hdspm_get_tco_pull(struct snd_kcontrol *kcontrol,
4027 struct snd_ctl_elem_value *ucontrol)
4028{
4029 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
4030
4031 ucontrol->value.enumerated.item[0] = hdspm->tco->pull;
4032
4033 return 0;
4034}
4035
4036static int snd_hdspm_put_tco_pull(struct snd_kcontrol *kcontrol,
4037 struct snd_ctl_elem_value *ucontrol)
4038{
4039 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
4040
4041 if (hdspm->tco->pull != ucontrol->value.enumerated.item[0]) {
4042 hdspm->tco->pull = ucontrol->value.enumerated.item[0];
4043
4044 hdspm_tco_write(hdspm);
4045
4046 return 1;
4047 }
4048
4049 return 0;
4050}
4051
4052#define HDSPM_TCO_WCK_CONVERSION(xname, xindex) \
4053{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4054 .name = xname, \
4055 .index = xindex, \
4056 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
4057 SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
4058 .info = snd_hdspm_info_tco_wck_conversion, \
4059 .get = snd_hdspm_get_tco_wck_conversion, \
4060 .put = snd_hdspm_put_tco_wck_conversion \
4061}
4062
4063static int snd_hdspm_info_tco_wck_conversion(struct snd_kcontrol *kcontrol,
4064 struct snd_ctl_elem_info *uinfo)
4065{
4066 static char *texts[] = { "1:1", "44.1 -> 48", "48 -> 44.1" };
4067 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4068 uinfo->count = 1;
4069 uinfo->value.enumerated.items = 3;
4070
4071 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
4072 uinfo->value.enumerated.item =
4073 uinfo->value.enumerated.items - 1;
4074
4075 strcpy(uinfo->value.enumerated.name,
4076 texts[uinfo->value.enumerated.item]);
4077
4078 return 0;
4079}
4080
4081static int snd_hdspm_get_tco_wck_conversion(struct snd_kcontrol *kcontrol,
4082 struct snd_ctl_elem_value *ucontrol)
4083{
4084 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
4085
4086 ucontrol->value.enumerated.item[0] = hdspm->tco->wordclock;
4087
4088 return 0;
4089}
4090
4091static int snd_hdspm_put_tco_wck_conversion(struct snd_kcontrol *kcontrol,
4092 struct snd_ctl_elem_value *ucontrol)
4093{
4094 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
4095
4096 if (hdspm->tco->wordclock != ucontrol->value.enumerated.item[0]) {
4097 hdspm->tco->wordclock = ucontrol->value.enumerated.item[0];
4098
4099 hdspm_tco_write(hdspm);
4100
4101 return 1;
4102 }
4103
4104 return 0;
4105}
4106
4107
4108#define HDSPM_TCO_FRAME_RATE(xname, xindex) \
4109{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4110 .name = xname, \
4111 .index = xindex, \
4112 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
4113 SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
4114 .info = snd_hdspm_info_tco_frame_rate, \
4115 .get = snd_hdspm_get_tco_frame_rate, \
4116 .put = snd_hdspm_put_tco_frame_rate \
4117}
4118
4119static int snd_hdspm_info_tco_frame_rate(struct snd_kcontrol *kcontrol,
4120 struct snd_ctl_elem_info *uinfo)
4121{
4122 static char *texts[] = { "24 fps", "25 fps", "29.97fps",
4123 "29.97 dfps", "30 fps", "30 dfps" };
4124 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4125 uinfo->count = 1;
4126 uinfo->value.enumerated.items = 6;
4127
4128 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
4129 uinfo->value.enumerated.item =
4130 uinfo->value.enumerated.items - 1;
4131
4132 strcpy(uinfo->value.enumerated.name,
4133 texts[uinfo->value.enumerated.item]);
4134
4135 return 0;
4136}
4137
4138static int snd_hdspm_get_tco_frame_rate(struct snd_kcontrol *kcontrol,
2786 struct snd_ctl_elem_value *ucontrol) 4139 struct snd_ctl_elem_value *ucontrol)
2787{ 4140{
2788 int offset;
2789 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); 4141 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
2790 4142
2791 offset = ucontrol->id.index - 1; 4143 ucontrol->value.enumerated.item[0] = hdspm->tco->framerate;
2792 if (offset < 0 || offset >= 8)
2793 return -EINVAL;
2794 4144
2795 ucontrol->value.enumerated.item[0] =
2796 hdspm_aes_sync_check(hdspm, offset);
2797 return 0; 4145 return 0;
2798} 4146}
2799 4147
4148static int snd_hdspm_put_tco_frame_rate(struct snd_kcontrol *kcontrol,
4149 struct snd_ctl_elem_value *ucontrol)
4150{
4151 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
4152
4153 if (hdspm->tco->framerate != ucontrol->value.enumerated.item[0]) {
4154 hdspm->tco->framerate = ucontrol->value.enumerated.item[0];
2800 4155
2801static struct snd_kcontrol_new snd_hdspm_controls_madi[] = { 4156 hdspm_tco_write(hdspm);
4157
4158 return 1;
4159 }
4160
4161 return 0;
4162}
2802 4163
2803 HDSPM_MIXER("Mixer", 0),
2804/* 'Sample Clock Source' complies with the alsa control naming scheme */
2805 HDSPM_CLOCK_SOURCE("Sample Clock Source", 0),
2806 4164
4165#define HDSPM_TCO_SYNC_SOURCE(xname, xindex) \
4166{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4167 .name = xname, \
4168 .index = xindex, \
4169 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
4170 SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
4171 .info = snd_hdspm_info_tco_sync_source, \
4172 .get = snd_hdspm_get_tco_sync_source, \
4173 .put = snd_hdspm_put_tco_sync_source \
4174}
4175
4176static int snd_hdspm_info_tco_sync_source(struct snd_kcontrol *kcontrol,
4177 struct snd_ctl_elem_info *uinfo)
4178{
4179 static char *texts[] = { "LTC", "Video", "WCK" };
4180 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4181 uinfo->count = 1;
4182 uinfo->value.enumerated.items = 3;
4183
4184 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
4185 uinfo->value.enumerated.item =
4186 uinfo->value.enumerated.items - 1;
4187
4188 strcpy(uinfo->value.enumerated.name,
4189 texts[uinfo->value.enumerated.item]);
4190
4191 return 0;
4192}
4193
4194static int snd_hdspm_get_tco_sync_source(struct snd_kcontrol *kcontrol,
4195 struct snd_ctl_elem_value *ucontrol)
4196{
4197 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
4198
4199 ucontrol->value.enumerated.item[0] = hdspm->tco->input;
4200
4201 return 0;
4202}
4203
4204static int snd_hdspm_put_tco_sync_source(struct snd_kcontrol *kcontrol,
4205 struct snd_ctl_elem_value *ucontrol)
4206{
4207 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
4208
4209 if (hdspm->tco->input != ucontrol->value.enumerated.item[0]) {
4210 hdspm->tco->input = ucontrol->value.enumerated.item[0];
4211
4212 hdspm_tco_write(hdspm);
4213
4214 return 1;
4215 }
4216
4217 return 0;
4218}
4219
4220
4221#define HDSPM_TCO_WORD_TERM(xname, xindex) \
4222{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4223 .name = xname, \
4224 .index = xindex, \
4225 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
4226 SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
4227 .info = snd_hdspm_info_tco_word_term, \
4228 .get = snd_hdspm_get_tco_word_term, \
4229 .put = snd_hdspm_put_tco_word_term \
4230}
4231
4232static int snd_hdspm_info_tco_word_term(struct snd_kcontrol *kcontrol,
4233 struct snd_ctl_elem_info *uinfo)
4234{
4235 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
4236 uinfo->count = 1;
4237 uinfo->value.integer.min = 0;
4238 uinfo->value.integer.max = 1;
4239
4240 return 0;
4241}
4242
4243
4244static int snd_hdspm_get_tco_word_term(struct snd_kcontrol *kcontrol,
4245 struct snd_ctl_elem_value *ucontrol)
4246{
4247 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
4248
4249 ucontrol->value.enumerated.item[0] = hdspm->tco->term;
4250
4251 return 0;
4252}
4253
4254
4255static int snd_hdspm_put_tco_word_term(struct snd_kcontrol *kcontrol,
4256 struct snd_ctl_elem_value *ucontrol)
4257{
4258 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
4259
4260 if (hdspm->tco->term != ucontrol->value.enumerated.item[0]) {
4261 hdspm->tco->term = ucontrol->value.enumerated.item[0];
4262
4263 hdspm_tco_write(hdspm);
4264
4265 return 1;
4266 }
4267
4268 return 0;
4269}
4270
4271
4272
4273
4274static struct snd_kcontrol_new snd_hdspm_controls_madi[] = {
4275 HDSPM_MIXER("Mixer", 0),
4276 HDSPM_INTERNAL_CLOCK("Internal Clock", 0),
2807 HDSPM_SYSTEM_CLOCK_MODE("System Clock Mode", 0), 4277 HDSPM_SYSTEM_CLOCK_MODE("System Clock Mode", 0),
2808 HDSPM_PREF_SYNC_REF("Preferred Sync Reference", 0), 4278 HDSPM_PREF_SYNC_REF("Preferred Sync Reference", 0),
2809 HDSPM_AUTOSYNC_REF("AutoSync Reference", 0), 4279 HDSPM_AUTOSYNC_REF("AutoSync Reference", 0),
2810 HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0), 4280 HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0),
2811/* 'External Rate' complies with the alsa control naming scheme */ 4281 HDSPM_SYNC_CHECK("WC SyncCheck", 0),
2812 HDSPM_AUTOSYNC_SAMPLE_RATE("External Rate", 0), 4282 HDSPM_SYNC_CHECK("MADI SyncCheck", 1),
2813 HDSPM_WC_SYNC_CHECK("Word Clock Lock Status", 0), 4283 HDSPM_SYNC_CHECK("TCO SyncCHeck", 2),
2814 HDSPM_MADI_SYNC_CHECK("MADI Sync Lock Status", 0), 4284 HDSPM_SYNC_CHECK("SYNC IN SyncCheck", 3),
2815 HDSPM_LINE_OUT("Line Out", 0), 4285 HDSPM_LINE_OUT("Line Out", 0),
2816 HDSPM_TX_64("TX 64 channels mode", 0), 4286 HDSPM_TX_64("TX 64 channels mode", 0),
2817 HDSPM_C_TMS("Clear Track Marker", 0), 4287 HDSPM_C_TMS("Clear Track Marker", 0),
2818 HDSPM_SAFE_MODE("Safe Mode", 0), 4288 HDSPM_SAFE_MODE("Safe Mode", 0),
2819 HDSPM_INPUT_SELECT("Input Select", 0), 4289 HDSPM_INPUT_SELECT("Input Select", 0)
2820}; 4290};
2821 4291
2822static struct snd_kcontrol_new snd_hdspm_controls_aes32[] = {
2823 4292
4293static struct snd_kcontrol_new snd_hdspm_controls_madiface[] = {
2824 HDSPM_MIXER("Mixer", 0), 4294 HDSPM_MIXER("Mixer", 0),
2825/* 'Sample Clock Source' complies with the alsa control naming scheme */ 4295 HDSPM_INTERNAL_CLOCK("Internal Clock", 0),
2826 HDSPM_CLOCK_SOURCE("Sample Clock Source", 0), 4296 HDSPM_SYSTEM_CLOCK_MODE("System Clock Mode", 0),
4297 HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0),
4298 HDSPM_AUTOSYNC_SAMPLE_RATE("External Rate", 0),
4299 HDSPM_SYNC_CHECK("MADI SyncCheck", 0),
4300 HDSPM_TX_64("TX 64 channels mode", 0),
4301 HDSPM_C_TMS("Clear Track Marker", 0),
4302 HDSPM_SAFE_MODE("Safe Mode", 0)
4303};
2827 4304
4305static struct snd_kcontrol_new snd_hdspm_controls_aio[] = {
4306 HDSPM_MIXER("Mixer", 0),
4307 HDSPM_INTERNAL_CLOCK("Internal Clock", 0),
2828 HDSPM_SYSTEM_CLOCK_MODE("System Clock Mode", 0), 4308 HDSPM_SYSTEM_CLOCK_MODE("System Clock Mode", 0),
2829 HDSPM_PREF_SYNC_REF("Preferred Sync Reference", 0), 4309 HDSPM_PREF_SYNC_REF("Preferred Sync Reference", 0),
2830 HDSPM_AUTOSYNC_REF("AutoSync Reference", 0), 4310 HDSPM_AUTOSYNC_REF("AutoSync Reference", 0),
2831 HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0), 4311 HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0),
2832/* 'External Rate' complies with the alsa control naming scheme */
2833 HDSPM_AUTOSYNC_SAMPLE_RATE("External Rate", 0), 4312 HDSPM_AUTOSYNC_SAMPLE_RATE("External Rate", 0),
2834 HDSPM_WC_SYNC_CHECK("Word Clock Lock Status", 0), 4313 HDSPM_SYNC_CHECK("WC SyncCheck", 0),
2835/* HDSPM_AES_SYNC_CHECK("AES Lock Status", 0),*/ /* created in snd_hdspm_create_controls() */ 4314 HDSPM_SYNC_CHECK("AES SyncCheck", 1),
4315 HDSPM_SYNC_CHECK("SPDIF SyncCheck", 2),
4316 HDSPM_SYNC_CHECK("ADAT SyncCheck", 3),
4317 HDSPM_SYNC_CHECK("TCO SyncCheck", 4),
4318 HDSPM_SYNC_CHECK("SYNC IN SyncCheck", 5),
4319 HDSPM_AUTOSYNC_SAMPLE_RATE("WC Frequency", 0),
4320 HDSPM_AUTOSYNC_SAMPLE_RATE("AES Frequency", 1),
4321 HDSPM_AUTOSYNC_SAMPLE_RATE("SPDIF Frequency", 2),
4322 HDSPM_AUTOSYNC_SAMPLE_RATE("ADAT Frequency", 3),
4323 HDSPM_AUTOSYNC_SAMPLE_RATE("TCO Frequency", 4),
4324 HDSPM_AUTOSYNC_SAMPLE_RATE("SYNC IN Frequency", 5)
4325
4326 /*
4327 HDSPM_INPUT_SELECT("Input Select", 0),
4328 HDSPM_SPDIF_OPTICAL("SPDIF Out Optical", 0),
4329 HDSPM_PROFESSIONAL("SPDIF Out Professional", 0);
4330 HDSPM_SPDIF_IN("SPDIF In", 0);
4331 HDSPM_BREAKOUT_CABLE("Breakout Cable", 0);
4332 HDSPM_INPUT_LEVEL("Input Level", 0);
4333 HDSPM_OUTPUT_LEVEL("Output Level", 0);
4334 HDSPM_PHONES("Phones", 0);
4335 */
4336};
4337
4338static struct snd_kcontrol_new snd_hdspm_controls_raydat[] = {
4339 HDSPM_MIXER("Mixer", 0),
4340 HDSPM_INTERNAL_CLOCK("Internal Clock", 0),
4341 HDSPM_SYSTEM_CLOCK_MODE("Clock Mode", 0),
4342 HDSPM_PREF_SYNC_REF("Pref Sync Ref", 0),
4343 HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0),
4344 HDSPM_SYNC_CHECK("WC SyncCheck", 0),
4345 HDSPM_SYNC_CHECK("AES SyncCheck", 1),
4346 HDSPM_SYNC_CHECK("SPDIF SyncCheck", 2),
4347 HDSPM_SYNC_CHECK("ADAT1 SyncCheck", 3),
4348 HDSPM_SYNC_CHECK("ADAT2 SyncCheck", 4),
4349 HDSPM_SYNC_CHECK("ADAT3 SyncCheck", 5),
4350 HDSPM_SYNC_CHECK("ADAT4 SyncCheck", 6),
4351 HDSPM_SYNC_CHECK("TCO SyncCheck", 7),
4352 HDSPM_SYNC_CHECK("SYNC IN SyncCheck", 8),
4353 HDSPM_AUTOSYNC_SAMPLE_RATE("WC Frequency", 0),
4354 HDSPM_AUTOSYNC_SAMPLE_RATE("AES Frequency", 1),
4355 HDSPM_AUTOSYNC_SAMPLE_RATE("SPDIF Frequency", 2),
4356 HDSPM_AUTOSYNC_SAMPLE_RATE("ADAT1 Frequency", 3),
4357 HDSPM_AUTOSYNC_SAMPLE_RATE("ADAT2 Frequency", 4),
4358 HDSPM_AUTOSYNC_SAMPLE_RATE("ADAT3 Frequency", 5),
4359 HDSPM_AUTOSYNC_SAMPLE_RATE("ADAT4 Frequency", 6),
4360 HDSPM_AUTOSYNC_SAMPLE_RATE("TCO Frequency", 7),
4361 HDSPM_AUTOSYNC_SAMPLE_RATE("SYNC IN Frequency", 8)
4362};
4363
4364static struct snd_kcontrol_new snd_hdspm_controls_aes32[] = {
4365 HDSPM_MIXER("Mixer", 0),
4366 HDSPM_INTERNAL_CLOCK("Internal Clock", 0),
4367 HDSPM_SYSTEM_CLOCK_MODE("System Clock Mode", 0),
4368 HDSPM_PREF_SYNC_REF("Preferred Sync Reference", 0),
4369 HDSPM_AUTOSYNC_REF("AutoSync Reference", 0),
4370 HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0),
4371 HDSPM_AUTOSYNC_SAMPLE_RATE("External Rate", 0),
4372 HDSPM_SYNC_CHECK("WC Sync Check", 0),
4373 HDSPM_SYNC_CHECK("AES1 Sync Check", 1),
4374 HDSPM_SYNC_CHECK("AES2 Sync Check", 2),
4375 HDSPM_SYNC_CHECK("AES3 Sync Check", 3),
4376 HDSPM_SYNC_CHECK("AES4 Sync Check", 4),
4377 HDSPM_SYNC_CHECK("AES5 Sync Check", 5),
4378 HDSPM_SYNC_CHECK("AES6 Sync Check", 6),
4379 HDSPM_SYNC_CHECK("AES7 Sync Check", 7),
4380 HDSPM_SYNC_CHECK("AES8 Sync Check", 8),
4381 HDSPM_SYNC_CHECK("TCO Sync Check", 9),
4382 HDSPM_SYNC_CHECK("SYNC IN Sync Check", 10),
4383 HDSPM_AUTOSYNC_SAMPLE_RATE("WC Frequency", 0),
4384 HDSPM_AUTOSYNC_SAMPLE_RATE("AES1 Frequency", 1),
4385 HDSPM_AUTOSYNC_SAMPLE_RATE("AES2 Frequency", 2),
4386 HDSPM_AUTOSYNC_SAMPLE_RATE("AES3 Frequency", 3),
4387 HDSPM_AUTOSYNC_SAMPLE_RATE("AES4 Frequency", 4),
4388 HDSPM_AUTOSYNC_SAMPLE_RATE("AES5 Frequency", 5),
4389 HDSPM_AUTOSYNC_SAMPLE_RATE("AES6 Frequency", 6),
4390 HDSPM_AUTOSYNC_SAMPLE_RATE("AES7 Frequency", 7),
4391 HDSPM_AUTOSYNC_SAMPLE_RATE("AES8 Frequency", 8),
4392 HDSPM_AUTOSYNC_SAMPLE_RATE("TCO Frequency", 9),
4393 HDSPM_AUTOSYNC_SAMPLE_RATE("SYNC IN Frequency", 10),
2836 HDSPM_LINE_OUT("Line Out", 0), 4394 HDSPM_LINE_OUT("Line Out", 0),
2837 HDSPM_EMPHASIS("Emphasis", 0), 4395 HDSPM_EMPHASIS("Emphasis", 0),
2838 HDSPM_DOLBY("Non Audio", 0), 4396 HDSPM_DOLBY("Non Audio", 0),
@@ -2842,6 +4400,19 @@ static struct snd_kcontrol_new snd_hdspm_controls_aes32[] = {
2842 HDSPM_QS_WIRE("Quad Speed Wire Mode", 0), 4400 HDSPM_QS_WIRE("Quad Speed Wire Mode", 0),
2843}; 4401};
2844 4402
4403
4404
4405/* Control elements for the optional TCO module */
4406static struct snd_kcontrol_new snd_hdspm_controls_tco[] = {
4407 HDSPM_TCO_SAMPLE_RATE("TCO Sample Rate", 0),
4408 HDSPM_TCO_PULL("TCO Pull", 0),
4409 HDSPM_TCO_WCK_CONVERSION("TCO WCK Conversion", 0),
4410 HDSPM_TCO_FRAME_RATE("TCO Frame Rate", 0),
4411 HDSPM_TCO_SYNC_SOURCE("TCO Sync Source", 0),
4412 HDSPM_TCO_WORD_TERM("TCO Word Term", 0)
4413};
4414
4415
2845static struct snd_kcontrol_new snd_hdspm_playback_mixer = HDSPM_PLAYBACK_MIXER; 4416static struct snd_kcontrol_new snd_hdspm_playback_mixer = HDSPM_PLAYBACK_MIXER;
2846 4417
2847 4418
@@ -2849,78 +4420,76 @@ static int hdspm_update_simple_mixer_controls(struct hdspm * hdspm)
2849{ 4420{
2850 int i; 4421 int i;
2851 4422
2852 for (i = hdspm->ds_channels; i < hdspm->ss_channels; ++i) { 4423 for (i = hdspm->ds_out_channels; i < hdspm->ss_out_channels; ++i) {
2853 if (hdspm->system_sample_rate > 48000) { 4424 if (hdspm->system_sample_rate > 48000) {
2854 hdspm->playback_mixer_ctls[i]->vd[0].access = 4425 hdspm->playback_mixer_ctls[i]->vd[0].access =
2855 SNDRV_CTL_ELEM_ACCESS_INACTIVE | 4426 SNDRV_CTL_ELEM_ACCESS_INACTIVE |
2856 SNDRV_CTL_ELEM_ACCESS_READ | 4427 SNDRV_CTL_ELEM_ACCESS_READ |
2857 SNDRV_CTL_ELEM_ACCESS_VOLATILE; 4428 SNDRV_CTL_ELEM_ACCESS_VOLATILE;
2858 } else { 4429 } else {
2859 hdspm->playback_mixer_ctls[i]->vd[0].access = 4430 hdspm->playback_mixer_ctls[i]->vd[0].access =
2860 SNDRV_CTL_ELEM_ACCESS_READWRITE | 4431 SNDRV_CTL_ELEM_ACCESS_READWRITE |
2861 SNDRV_CTL_ELEM_ACCESS_VOLATILE; 4432 SNDRV_CTL_ELEM_ACCESS_VOLATILE;
2862 } 4433 }
2863 snd_ctl_notify(hdspm->card, SNDRV_CTL_EVENT_MASK_VALUE | 4434 snd_ctl_notify(hdspm->card, SNDRV_CTL_EVENT_MASK_VALUE |
2864 SNDRV_CTL_EVENT_MASK_INFO, 4435 SNDRV_CTL_EVENT_MASK_INFO,
2865 &hdspm->playback_mixer_ctls[i]->id); 4436 &hdspm->playback_mixer_ctls[i]->id);
2866 } 4437 }
2867 4438
2868 return 0; 4439 return 0;
2869} 4440}
2870 4441
2871 4442
2872static int snd_hdspm_create_controls(struct snd_card *card, struct hdspm * hdspm) 4443static int snd_hdspm_create_controls(struct snd_card *card,
4444 struct hdspm *hdspm)
2873{ 4445{
2874 unsigned int idx, limit; 4446 unsigned int idx, limit;
2875 int err; 4447 int err;
2876 struct snd_kcontrol *kctl; 4448 struct snd_kcontrol *kctl;
4449 struct snd_kcontrol_new *list = NULL;
2877 4450
2878 /* add control list first */ 4451 switch (hdspm->io_type) {
2879 if (hdspm->is_aes32) { 4452 case MADI:
2880 struct snd_kcontrol_new aes_sync_ctl = 4453 list = snd_hdspm_controls_madi;
2881 HDSPM_AES_SYNC_CHECK("AES Lock Status", 0); 4454 limit = ARRAY_SIZE(snd_hdspm_controls_madi);
4455 break;
4456 case MADIface:
4457 list = snd_hdspm_controls_madiface;
4458 limit = ARRAY_SIZE(snd_hdspm_controls_madiface);
4459 break;
4460 case AIO:
4461 list = snd_hdspm_controls_aio;
4462 limit = ARRAY_SIZE(snd_hdspm_controls_aio);
4463 break;
4464 case RayDAT:
4465 list = snd_hdspm_controls_raydat;
4466 limit = ARRAY_SIZE(snd_hdspm_controls_raydat);
4467 break;
4468 case AES32:
4469 list = snd_hdspm_controls_aes32;
4470 limit = ARRAY_SIZE(snd_hdspm_controls_aes32);
4471 break;
4472 }
2882 4473
2883 for (idx = 0; idx < ARRAY_SIZE(snd_hdspm_controls_aes32); 4474 if (NULL != list) {
2884 idx++) { 4475 for (idx = 0; idx < limit; idx++) {
2885 err = snd_ctl_add(card,
2886 snd_ctl_new1(&snd_hdspm_controls_aes32[idx],
2887 hdspm));
2888 if (err < 0)
2889 return err;
2890 }
2891 for (idx = 1; idx <= 8; idx++) {
2892 aes_sync_ctl.index = idx;
2893 err = snd_ctl_add(card,
2894 snd_ctl_new1(&aes_sync_ctl, hdspm));
2895 if (err < 0)
2896 return err;
2897 }
2898 } else {
2899 for (idx = 0; idx < ARRAY_SIZE(snd_hdspm_controls_madi);
2900 idx++) {
2901 err = snd_ctl_add(card, 4476 err = snd_ctl_add(card,
2902 snd_ctl_new1(&snd_hdspm_controls_madi[idx], 4477 snd_ctl_new1(&list[idx], hdspm));
2903 hdspm));
2904 if (err < 0) 4478 if (err < 0)
2905 return err; 4479 return err;
2906 } 4480 }
2907 } 4481 }
2908 4482
2909 /* Channel playback mixer as default control
2910 Note: the whole matrix would be 128*HDSPM_MIXER_CHANNELS Faders,
2911 thats too * big for any alsamixer they are accessible via special
2912 IOCTL on hwdep and the mixer 2dimensional mixer control
2913 */
2914 4483
4484 /* create simple 1:1 playback mixer controls */
2915 snd_hdspm_playback_mixer.name = "Chn"; 4485 snd_hdspm_playback_mixer.name = "Chn";
2916 limit = HDSPM_MAX_CHANNELS; 4486 if (hdspm->system_sample_rate >= 128000) {
2917 4487 limit = hdspm->qs_out_channels;
2918 /* The index values are one greater than the channel ID so that 4488 } else if (hdspm->system_sample_rate >= 64000) {
2919 * alsamixer will display them correctly. We want to use the index 4489 limit = hdspm->ds_out_channels;
2920 * for fast lookup of the relevant channel, but if we use it at all, 4490 } else {
2921 * most ALSA software does the wrong thing with it ... 4491 limit = hdspm->ss_out_channels;
2922 */ 4492 }
2923
2924 for (idx = 0; idx < limit; ++idx) { 4493 for (idx = 0; idx < limit; ++idx) {
2925 snd_hdspm_playback_mixer.index = idx + 1; 4494 snd_hdspm_playback_mixer.index = idx + 1;
2926 kctl = snd_ctl_new1(&snd_hdspm_playback_mixer, hdspm); 4495 kctl = snd_ctl_new1(&snd_hdspm_playback_mixer, hdspm);
@@ -2930,11 +4499,24 @@ static int snd_hdspm_create_controls(struct snd_card *card, struct hdspm * hdspm
2930 hdspm->playback_mixer_ctls[idx] = kctl; 4499 hdspm->playback_mixer_ctls[idx] = kctl;
2931 } 4500 }
2932 4501
4502
4503 if (hdspm->tco) {
4504 /* add tco control elements */
4505 list = snd_hdspm_controls_tco;
4506 limit = ARRAY_SIZE(snd_hdspm_controls_tco);
4507 for (idx = 0; idx < limit; idx++) {
4508 err = snd_ctl_add(card,
4509 snd_ctl_new1(&list[idx], hdspm));
4510 if (err < 0)
4511 return err;
4512 }
4513 }
4514
2933 return 0; 4515 return 0;
2934} 4516}
2935 4517
2936/*------------------------------------------------------------ 4518/*------------------------------------------------------------
2937 /proc interface 4519 /proc interface
2938 ------------------------------------------------------------*/ 4520 ------------------------------------------------------------*/
2939 4521
2940static void 4522static void
@@ -2942,72 +4524,178 @@ snd_hdspm_proc_read_madi(struct snd_info_entry * entry,
2942 struct snd_info_buffer *buffer) 4524 struct snd_info_buffer *buffer)
2943{ 4525{
2944 struct hdspm *hdspm = entry->private_data; 4526 struct hdspm *hdspm = entry->private_data;
2945 unsigned int status; 4527 unsigned int status, status2, control, freq;
2946 unsigned int status2; 4528
2947 char *pref_sync_ref; 4529 char *pref_sync_ref;
2948 char *autosync_ref; 4530 char *autosync_ref;
2949 char *system_clock_mode; 4531 char *system_clock_mode;
2950 char *clock_source;
2951 char *insel; 4532 char *insel;
2952 char *syncref;
2953 int x, x2; 4533 int x, x2;
2954 4534
4535 /* TCO stuff */
4536 int a, ltc, frames, seconds, minutes, hours;
4537 unsigned int period;
4538 u64 freq_const = 0;
4539 u32 rate;
4540
2955 status = hdspm_read(hdspm, HDSPM_statusRegister); 4541 status = hdspm_read(hdspm, HDSPM_statusRegister);
2956 status2 = hdspm_read(hdspm, HDSPM_statusRegister2); 4542 status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
4543 control = hdspm->control_register;
4544 freq = hdspm_read(hdspm, HDSPM_timecodeRegister);
2957 4545
2958 snd_iprintf(buffer, "%s (Card #%d) Rev.%x Status2first3bits: %x\n", 4546 snd_iprintf(buffer, "%s (Card #%d) Rev.%x Status2first3bits: %x\n",
2959 hdspm->card_name, hdspm->card->number + 1, 4547 hdspm->card_name, hdspm->card->number + 1,
2960 hdspm->firmware_rev, 4548 hdspm->firmware_rev,
2961 (status2 & HDSPM_version0) | 4549 (status2 & HDSPM_version0) |
2962 (status2 & HDSPM_version1) | (status2 & 4550 (status2 & HDSPM_version1) | (status2 &
2963 HDSPM_version2)); 4551 HDSPM_version2));
4552
4553 snd_iprintf(buffer, "HW Serial: 0x%06x%06x\n",
4554 (hdspm_read(hdspm, HDSPM_midiStatusIn1)>>8) & 0xFFFFFF,
4555 (hdspm_read(hdspm, HDSPM_midiStatusIn0)>>8) & 0xFFFFFF);
2964 4556
2965 snd_iprintf(buffer, "IRQ: %d Registers bus: 0x%lx VM: 0x%lx\n", 4557 snd_iprintf(buffer, "IRQ: %d Registers bus: 0x%lx VM: 0x%lx\n",
2966 hdspm->irq, hdspm->port, (unsigned long)hdspm->iobase); 4558 hdspm->irq, hdspm->port, (unsigned long)hdspm->iobase);
2967 4559
2968 snd_iprintf(buffer, "--- System ---\n"); 4560 snd_iprintf(buffer, "--- System ---\n");
2969 4561
2970 snd_iprintf(buffer, 4562 snd_iprintf(buffer,
2971 "IRQ Pending: Audio=%d, MIDI0=%d, MIDI1=%d, IRQcount=%d\n", 4563 "IRQ Pending: Audio=%d, MIDI0=%d, MIDI1=%d, IRQcount=%d\n",
2972 status & HDSPM_audioIRQPending, 4564 status & HDSPM_audioIRQPending,
2973 (status & HDSPM_midi0IRQPending) ? 1 : 0, 4565 (status & HDSPM_midi0IRQPending) ? 1 : 0,
2974 (status & HDSPM_midi1IRQPending) ? 1 : 0, 4566 (status & HDSPM_midi1IRQPending) ? 1 : 0,
2975 hdspm->irq_count); 4567 hdspm->irq_count);
2976 snd_iprintf(buffer, 4568 snd_iprintf(buffer,
2977 "HW pointer: id = %d, rawptr = %d (%d->%d) " 4569 "HW pointer: id = %d, rawptr = %d (%d->%d) "
2978 "estimated= %ld (bytes)\n", 4570 "estimated= %ld (bytes)\n",
2979 ((status & HDSPM_BufferID) ? 1 : 0), 4571 ((status & HDSPM_BufferID) ? 1 : 0),
2980 (status & HDSPM_BufferPositionMask), 4572 (status & HDSPM_BufferPositionMask),
2981 (status & HDSPM_BufferPositionMask) % 4573 (status & HDSPM_BufferPositionMask) %
2982 (2 * (int)hdspm->period_bytes), 4574 (2 * (int)hdspm->period_bytes),
2983 ((status & HDSPM_BufferPositionMask) - 64) % 4575 ((status & HDSPM_BufferPositionMask) - 64) %
2984 (2 * (int)hdspm->period_bytes), 4576 (2 * (int)hdspm->period_bytes),
2985 (long) hdspm_hw_pointer(hdspm) * 4); 4577 (long) hdspm_hw_pointer(hdspm) * 4);
2986 4578
2987 snd_iprintf(buffer, 4579 snd_iprintf(buffer,
2988 "MIDI FIFO: Out1=0x%x, Out2=0x%x, In1=0x%x, In2=0x%x \n", 4580 "MIDI FIFO: Out1=0x%x, Out2=0x%x, In1=0x%x, In2=0x%x \n",
2989 hdspm_read(hdspm, HDSPM_midiStatusOut0) & 0xFF, 4581 hdspm_read(hdspm, HDSPM_midiStatusOut0) & 0xFF,
2990 hdspm_read(hdspm, HDSPM_midiStatusOut1) & 0xFF, 4582 hdspm_read(hdspm, HDSPM_midiStatusOut1) & 0xFF,
2991 hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xFF, 4583 hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xFF,
2992 hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xFF); 4584 hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xFF);
2993 snd_iprintf(buffer, 4585 snd_iprintf(buffer,
2994 "Register: ctrl1=0x%x, ctrl2=0x%x, status1=0x%x, " 4586 "MIDIoverMADI FIFO: In=0x%x, Out=0x%x \n",
2995 "status2=0x%x\n", 4587 hdspm_read(hdspm, HDSPM_midiStatusIn2) & 0xFF,
2996 hdspm->control_register, hdspm->control2_register, 4588 hdspm_read(hdspm, HDSPM_midiStatusOut2) & 0xFF);
2997 status, status2); 4589 snd_iprintf(buffer,
4590 "Register: ctrl1=0x%x, ctrl2=0x%x, status1=0x%x, "
4591 "status2=0x%x\n",
4592 hdspm->control_register, hdspm->control2_register,
4593 status, status2);
4594 if (status & HDSPM_tco_detect) {
4595 snd_iprintf(buffer, "TCO module detected.\n");
4596 a = hdspm_read(hdspm, HDSPM_RD_TCO+4);
4597 if (a & HDSPM_TCO1_LTC_Input_valid) {
4598 snd_iprintf(buffer, " LTC valid, ");
4599 switch (a & (HDSPM_TCO1_LTC_Format_LSB |
4600 HDSPM_TCO1_LTC_Format_MSB)) {
4601 case 0:
4602 snd_iprintf(buffer, "24 fps, ");
4603 break;
4604 case HDSPM_TCO1_LTC_Format_LSB:
4605 snd_iprintf(buffer, "25 fps, ");
4606 break;
4607 case HDSPM_TCO1_LTC_Format_MSB:
4608 snd_iprintf(buffer, "29.97 fps, ");
4609 break;
4610 default:
4611 snd_iprintf(buffer, "30 fps, ");
4612 break;
4613 }
4614 if (a & HDSPM_TCO1_set_drop_frame_flag) {
4615 snd_iprintf(buffer, "drop frame\n");
4616 } else {
4617 snd_iprintf(buffer, "full frame\n");
4618 }
4619 } else {
4620 snd_iprintf(buffer, " no LTC\n");
4621 }
4622 if (a & HDSPM_TCO1_Video_Input_Format_NTSC) {
4623 snd_iprintf(buffer, " Video: NTSC\n");
4624 } else if (a & HDSPM_TCO1_Video_Input_Format_PAL) {
4625 snd_iprintf(buffer, " Video: PAL\n");
4626 } else {
4627 snd_iprintf(buffer, " No video\n");
4628 }
4629 if (a & HDSPM_TCO1_TCO_lock) {
4630 snd_iprintf(buffer, " Sync: lock\n");
4631 } else {
4632 snd_iprintf(buffer, " Sync: no lock\n");
4633 }
4634
4635 switch (hdspm->io_type) {
4636 case MADI:
4637 case AES32:
4638 freq_const = 110069313433624ULL;
4639 break;
4640 case RayDAT:
4641 case AIO:
4642 freq_const = 104857600000000ULL;
4643 break;
4644 case MADIface:
4645 break; /* no TCO possible */
4646 }
4647
4648 period = hdspm_read(hdspm, HDSPM_RD_PLL_FREQ);
4649 snd_iprintf(buffer, " period: %u\n", period);
4650
4651
4652 /* rate = freq_const/period; */
4653 rate = div_u64(freq_const, period);
4654
4655 if (control & HDSPM_QuadSpeed) {
4656 rate *= 4;
4657 } else if (control & HDSPM_DoubleSpeed) {
4658 rate *= 2;
4659 }
4660
4661 snd_iprintf(buffer, " Frequency: %u Hz\n",
4662 (unsigned int) rate);
4663
4664 ltc = hdspm_read(hdspm, HDSPM_RD_TCO);
4665 frames = ltc & 0xF;
4666 ltc >>= 4;
4667 frames += (ltc & 0x3) * 10;
4668 ltc >>= 4;
4669 seconds = ltc & 0xF;
4670 ltc >>= 4;
4671 seconds += (ltc & 0x7) * 10;
4672 ltc >>= 4;
4673 minutes = ltc & 0xF;
4674 ltc >>= 4;
4675 minutes += (ltc & 0x7) * 10;
4676 ltc >>= 4;
4677 hours = ltc & 0xF;
4678 ltc >>= 4;
4679 hours += (ltc & 0x3) * 10;
4680 snd_iprintf(buffer,
4681 " LTC In: %02d:%02d:%02d:%02d\n",
4682 hours, minutes, seconds, frames);
4683
4684 } else {
4685 snd_iprintf(buffer, "No TCO module detected.\n");
4686 }
2998 4687
2999 snd_iprintf(buffer, "--- Settings ---\n"); 4688 snd_iprintf(buffer, "--- Settings ---\n");
3000 4689
3001 x = 1 << (6 + hdspm_decode_latency(hdspm->control_register & 4690 x = 1 << (6 + hdspm_decode_latency(hdspm->control_register &
3002 HDSPM_LatencyMask)); 4691 HDSPM_LatencyMask));
3003 4692
3004 snd_iprintf(buffer, 4693 snd_iprintf(buffer,
3005 "Size (Latency): %d samples (2 periods of %lu bytes)\n", 4694 "Size (Latency): %d samples (2 periods of %lu bytes)\n",
3006 x, (unsigned long) hdspm->period_bytes); 4695 x, (unsigned long) hdspm->period_bytes);
3007 4696
3008 snd_iprintf(buffer, "Line out: %s, Precise Pointer: %s\n", 4697 snd_iprintf(buffer, "Line out: %s\n",
3009 (hdspm->control_register & HDSPM_LineOut) ? "on " : "off", 4698 (hdspm->control_register & HDSPM_LineOut) ? "on " : "off");
3010 (hdspm->precise_ptr) ? "on" : "off");
3011 4699
3012 switch (hdspm->control_register & HDSPM_InputMask) { 4700 switch (hdspm->control_register & HDSPM_InputMask) {
3013 case HDSPM_InputOptical: 4701 case HDSPM_InputOptical:
@@ -3017,63 +4705,22 @@ snd_hdspm_proc_read_madi(struct snd_info_entry * entry,
3017 insel = "Coaxial"; 4705 insel = "Coaxial";
3018 break; 4706 break;
3019 default: 4707 default:
3020 insel = "Unknown"; 4708 insel = "Unkown";
3021 }
3022
3023 switch (hdspm->control_register & HDSPM_SyncRefMask) {
3024 case HDSPM_SyncRef_Word:
3025 syncref = "WordClock";
3026 break;
3027 case HDSPM_SyncRef_MADI:
3028 syncref = "MADI";
3029 break;
3030 default:
3031 syncref = "Unknown";
3032 } 4709 }
3033 snd_iprintf(buffer, "Inputsel = %s, SyncRef = %s\n", insel,
3034 syncref);
3035 4710
3036 snd_iprintf(buffer, 4711 snd_iprintf(buffer,
3037 "ClearTrackMarker = %s, Transmit in %s Channel Mode, " 4712 "ClearTrackMarker = %s, Transmit in %s Channel Mode, "
3038 "Auto Input %s\n", 4713 "Auto Input %s\n",
3039 (hdspm-> 4714 (hdspm->control_register & HDSPM_clr_tms) ? "on" : "off",
3040 control_register & HDSPM_clr_tms) ? "on" : "off", 4715 (hdspm->control_register & HDSPM_TX_64ch) ? "64" : "56",
3041 (hdspm-> 4716 (hdspm->control_register & HDSPM_AutoInp) ? "on" : "off");
3042 control_register & HDSPM_TX_64ch) ? "64" : "56", 4717
3043 (hdspm->
3044 control_register & HDSPM_AutoInp) ? "on" : "off");
3045 4718
3046 switch (hdspm_clock_source(hdspm)) {
3047 case HDSPM_CLOCK_SOURCE_AUTOSYNC:
3048 clock_source = "AutoSync";
3049 break;
3050 case HDSPM_CLOCK_SOURCE_INTERNAL_32KHZ:
3051 clock_source = "Internal 32 kHz";
3052 break;
3053 case HDSPM_CLOCK_SOURCE_INTERNAL_44_1KHZ:
3054 clock_source = "Internal 44.1 kHz";
3055 break;
3056 case HDSPM_CLOCK_SOURCE_INTERNAL_48KHZ:
3057 clock_source = "Internal 48 kHz";
3058 break;
3059 case HDSPM_CLOCK_SOURCE_INTERNAL_64KHZ:
3060 clock_source = "Internal 64 kHz";
3061 break;
3062 case HDSPM_CLOCK_SOURCE_INTERNAL_88_2KHZ:
3063 clock_source = "Internal 88.2 kHz";
3064 break;
3065 case HDSPM_CLOCK_SOURCE_INTERNAL_96KHZ:
3066 clock_source = "Internal 96 kHz";
3067 break;
3068 default:
3069 clock_source = "Error";
3070 }
3071 snd_iprintf(buffer, "Sample Clock Source: %s\n", clock_source);
3072 if (!(hdspm->control_register & HDSPM_ClockModeMaster)) 4719 if (!(hdspm->control_register & HDSPM_ClockModeMaster))
3073 system_clock_mode = "Slave"; 4720 system_clock_mode = "AutoSync";
3074 else 4721 else
3075 system_clock_mode = "Master"; 4722 system_clock_mode = "Master";
3076 snd_iprintf(buffer, "System Clock Mode: %s\n", system_clock_mode); 4723 snd_iprintf(buffer, "AutoSync Reference: %s\n", system_clock_mode);
3077 4724
3078 switch (hdspm_pref_sync_ref(hdspm)) { 4725 switch (hdspm_pref_sync_ref(hdspm)) {
3079 case HDSPM_SYNC_FROM_WORD: 4726 case HDSPM_SYNC_FROM_WORD:
@@ -3082,15 +4729,21 @@ snd_hdspm_proc_read_madi(struct snd_info_entry * entry,
3082 case HDSPM_SYNC_FROM_MADI: 4729 case HDSPM_SYNC_FROM_MADI:
3083 pref_sync_ref = "MADI Sync"; 4730 pref_sync_ref = "MADI Sync";
3084 break; 4731 break;
4732 case HDSPM_SYNC_FROM_TCO:
4733 pref_sync_ref = "TCO";
4734 break;
4735 case HDSPM_SYNC_FROM_SYNC_IN:
4736 pref_sync_ref = "Sync In";
4737 break;
3085 default: 4738 default:
3086 pref_sync_ref = "XXXX Clock"; 4739 pref_sync_ref = "XXXX Clock";
3087 break; 4740 break;
3088 } 4741 }
3089 snd_iprintf(buffer, "Preferred Sync Reference: %s\n", 4742 snd_iprintf(buffer, "Preferred Sync Reference: %s\n",
3090 pref_sync_ref); 4743 pref_sync_ref);
3091 4744
3092 snd_iprintf(buffer, "System Clock Frequency: %d\n", 4745 snd_iprintf(buffer, "System Clock Frequency: %d\n",
3093 hdspm->system_sample_rate); 4746 hdspm->system_sample_rate);
3094 4747
3095 4748
3096 snd_iprintf(buffer, "--- Status:\n"); 4749 snd_iprintf(buffer, "--- Status:\n");
@@ -3099,12 +4752,18 @@ snd_hdspm_proc_read_madi(struct snd_info_entry * entry,
3099 x2 = status2 & HDSPM_wcSync; 4752 x2 = status2 & HDSPM_wcSync;
3100 4753
3101 snd_iprintf(buffer, "Inputs MADI=%s, WordClock=%s\n", 4754 snd_iprintf(buffer, "Inputs MADI=%s, WordClock=%s\n",
3102 (status & HDSPM_madiLock) ? (x ? "Sync" : "Lock") : 4755 (status & HDSPM_madiLock) ? (x ? "Sync" : "Lock") :
3103 "NoLock", 4756 "NoLock",
3104 (status2 & HDSPM_wcLock) ? (x2 ? "Sync" : "Lock") : 4757 (status2 & HDSPM_wcLock) ? (x2 ? "Sync" : "Lock") :
3105 "NoLock"); 4758 "NoLock");
3106 4759
3107 switch (hdspm_autosync_ref(hdspm)) { 4760 switch (hdspm_autosync_ref(hdspm)) {
4761 case HDSPM_AUTOSYNC_FROM_SYNC_IN:
4762 autosync_ref = "Sync In";
4763 break;
4764 case HDSPM_AUTOSYNC_FROM_TCO:
4765 autosync_ref = "TCO";
4766 break;
3108 case HDSPM_AUTOSYNC_FROM_WORD: 4767 case HDSPM_AUTOSYNC_FROM_WORD:
3109 autosync_ref = "Word Clock"; 4768 autosync_ref = "Word Clock";
3110 break; 4769 break;
@@ -3119,15 +4778,15 @@ snd_hdspm_proc_read_madi(struct snd_info_entry * entry,
3119 break; 4778 break;
3120 } 4779 }
3121 snd_iprintf(buffer, 4780 snd_iprintf(buffer,
3122 "AutoSync: Reference= %s, Freq=%d (MADI = %d, Word = %d)\n", 4781 "AutoSync: Reference= %s, Freq=%d (MADI = %d, Word = %d)\n",
3123 autosync_ref, hdspm_external_sample_rate(hdspm), 4782 autosync_ref, hdspm_external_sample_rate(hdspm),
3124 (status & HDSPM_madiFreqMask) >> 22, 4783 (status & HDSPM_madiFreqMask) >> 22,
3125 (status2 & HDSPM_wcFreqMask) >> 5); 4784 (status2 & HDSPM_wcFreqMask) >> 5);
3126 4785
3127 snd_iprintf(buffer, "Input: %s, Mode=%s\n", 4786 snd_iprintf(buffer, "Input: %s, Mode=%s\n",
3128 (status & HDSPM_AB_int) ? "Coax" : "Optical", 4787 (status & HDSPM_AB_int) ? "Coax" : "Optical",
3129 (status & HDSPM_RX_64ch) ? "64 channels" : 4788 (status & HDSPM_RX_64ch) ? "64 channels" :
3130 "56 channels"); 4789 "56 channels");
3131 4790
3132 snd_iprintf(buffer, "\n"); 4791 snd_iprintf(buffer, "\n");
3133} 4792}
@@ -3142,8 +4801,6 @@ snd_hdspm_proc_read_aes32(struct snd_info_entry * entry,
3142 unsigned int timecode; 4801 unsigned int timecode;
3143 int pref_syncref; 4802 int pref_syncref;
3144 char *autosync_ref; 4803 char *autosync_ref;
3145 char *system_clock_mode;
3146 char *clock_source;
3147 int x; 4804 int x;
3148 4805
3149 status = hdspm_read(hdspm, HDSPM_statusRegister); 4806 status = hdspm_read(hdspm, HDSPM_statusRegister);
@@ -3183,24 +4840,27 @@ snd_hdspm_proc_read_aes32(struct snd_info_entry * entry,
3183 hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xFF, 4840 hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xFF,
3184 hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xFF); 4841 hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xFF);
3185 snd_iprintf(buffer, 4842 snd_iprintf(buffer,
3186 "Register: ctrl1=0x%x, status1=0x%x, status2=0x%x, " 4843 "MIDIoverMADI FIFO: In=0x%x, Out=0x%x \n",
3187 "timecode=0x%x\n", 4844 hdspm_read(hdspm, HDSPM_midiStatusIn2) & 0xFF,
3188 hdspm->control_register, 4845 hdspm_read(hdspm, HDSPM_midiStatusOut2) & 0xFF);
3189 status, status2, timecode); 4846 snd_iprintf(buffer,
4847 "Register: ctrl1=0x%x, ctrl2=0x%x, status1=0x%x, "
4848 "status2=0x%x\n",
4849 hdspm->control_register, hdspm->control2_register,
4850 status, status2);
3190 4851
3191 snd_iprintf(buffer, "--- Settings ---\n"); 4852 snd_iprintf(buffer, "--- Settings ---\n");
3192 4853
3193 x = 1 << (6 + hdspm_decode_latency(hdspm->control_register & 4854 x = 1 << (6 + hdspm_decode_latency(hdspm->control_register &
3194 HDSPM_LatencyMask)); 4855 HDSPM_LatencyMask));
3195 4856
3196 snd_iprintf(buffer, 4857 snd_iprintf(buffer,
3197 "Size (Latency): %d samples (2 periods of %lu bytes)\n", 4858 "Size (Latency): %d samples (2 periods of %lu bytes)\n",
3198 x, (unsigned long) hdspm->period_bytes); 4859 x, (unsigned long) hdspm->period_bytes);
3199 4860
3200 snd_iprintf(buffer, "Line out: %s, Precise Pointer: %s\n", 4861 snd_iprintf(buffer, "Line out: %s\n",
3201 (hdspm-> 4862 (hdspm->
3202 control_register & HDSPM_LineOut) ? "on " : "off", 4863 control_register & HDSPM_LineOut) ? "on " : "off");
3203 (hdspm->precise_ptr) ? "on" : "off");
3204 4864
3205 snd_iprintf(buffer, 4865 snd_iprintf(buffer,
3206 "ClearTrackMarker %s, Emphasis %s, Dolby %s\n", 4866 "ClearTrackMarker %s, Emphasis %s, Dolby %s\n",
@@ -3211,46 +4871,6 @@ snd_hdspm_proc_read_aes32(struct snd_info_entry * entry,
3211 (hdspm-> 4871 (hdspm->
3212 control_register & HDSPM_Dolby) ? "on" : "off"); 4872 control_register & HDSPM_Dolby) ? "on" : "off");
3213 4873
3214 switch (hdspm_clock_source(hdspm)) {
3215 case HDSPM_CLOCK_SOURCE_AUTOSYNC:
3216 clock_source = "AutoSync";
3217 break;
3218 case HDSPM_CLOCK_SOURCE_INTERNAL_32KHZ:
3219 clock_source = "Internal 32 kHz";
3220 break;
3221 case HDSPM_CLOCK_SOURCE_INTERNAL_44_1KHZ:
3222 clock_source = "Internal 44.1 kHz";
3223 break;
3224 case HDSPM_CLOCK_SOURCE_INTERNAL_48KHZ:
3225 clock_source = "Internal 48 kHz";
3226 break;
3227 case HDSPM_CLOCK_SOURCE_INTERNAL_64KHZ:
3228 clock_source = "Internal 64 kHz";
3229 break;
3230 case HDSPM_CLOCK_SOURCE_INTERNAL_88_2KHZ:
3231 clock_source = "Internal 88.2 kHz";
3232 break;
3233 case HDSPM_CLOCK_SOURCE_INTERNAL_96KHZ:
3234 clock_source = "Internal 96 kHz";
3235 break;
3236 case HDSPM_CLOCK_SOURCE_INTERNAL_128KHZ:
3237 clock_source = "Internal 128 kHz";
3238 break;
3239 case HDSPM_CLOCK_SOURCE_INTERNAL_176_4KHZ:
3240 clock_source = "Internal 176.4 kHz";
3241 break;
3242 case HDSPM_CLOCK_SOURCE_INTERNAL_192KHZ:
3243 clock_source = "Internal 192 kHz";
3244 break;
3245 default:
3246 clock_source = "Error";
3247 }
3248 snd_iprintf(buffer, "Sample Clock Source: %s\n", clock_source);
3249 if (!(hdspm->control_register & HDSPM_ClockModeMaster))
3250 system_clock_mode = "Slave";
3251 else
3252 system_clock_mode = "Master";
3253 snd_iprintf(buffer, "System Clock Mode: %s\n", system_clock_mode);
3254 4874
3255 pref_syncref = hdspm_pref_sync_ref(hdspm); 4875 pref_syncref = hdspm_pref_sync_ref(hdspm);
3256 if (pref_syncref == 0) 4876 if (pref_syncref == 0)
@@ -3274,38 +4894,108 @@ snd_hdspm_proc_read_aes32(struct snd_info_entry * entry,
3274 snd_iprintf(buffer, "--- Status:\n"); 4894 snd_iprintf(buffer, "--- Status:\n");
3275 4895
3276 snd_iprintf(buffer, "Word: %s Frequency: %d\n", 4896 snd_iprintf(buffer, "Word: %s Frequency: %d\n",
3277 (status & HDSPM_AES32_wcLock)? "Sync " : "No Lock", 4897 (status & HDSPM_AES32_wcLock) ? "Sync " : "No Lock",
3278 HDSPM_bit2freq((status >> HDSPM_AES32_wcFreq_bit) & 0xF)); 4898 HDSPM_bit2freq((status >> HDSPM_AES32_wcFreq_bit) & 0xF));
3279 4899
3280 for (x = 0; x < 8; x++) { 4900 for (x = 0; x < 8; x++) {
3281 snd_iprintf(buffer, "AES%d: %s Frequency: %d\n", 4901 snd_iprintf(buffer, "AES%d: %s Frequency: %d\n",
3282 x+1, 4902 x+1,
3283 (status2 & (HDSPM_LockAES >> x)) ? 4903 (status2 & (HDSPM_LockAES >> x)) ?
3284 "Sync ": "No Lock", 4904 "Sync " : "No Lock",
3285 HDSPM_bit2freq((timecode >> (4*x)) & 0xF)); 4905 HDSPM_bit2freq((timecode >> (4*x)) & 0xF));
3286 } 4906 }
3287 4907
3288 switch (hdspm_autosync_ref(hdspm)) { 4908 switch (hdspm_autosync_ref(hdspm)) {
3289 case HDSPM_AES32_AUTOSYNC_FROM_NONE: autosync_ref="None"; break; 4909 case HDSPM_AES32_AUTOSYNC_FROM_NONE:
3290 case HDSPM_AES32_AUTOSYNC_FROM_WORD: autosync_ref="Word Clock"; break; 4910 autosync_ref = "None"; break;
3291 case HDSPM_AES32_AUTOSYNC_FROM_AES1: autosync_ref="AES1"; break; 4911 case HDSPM_AES32_AUTOSYNC_FROM_WORD:
3292 case HDSPM_AES32_AUTOSYNC_FROM_AES2: autosync_ref="AES2"; break; 4912 autosync_ref = "Word Clock"; break;
3293 case HDSPM_AES32_AUTOSYNC_FROM_AES3: autosync_ref="AES3"; break; 4913 case HDSPM_AES32_AUTOSYNC_FROM_AES1:
3294 case HDSPM_AES32_AUTOSYNC_FROM_AES4: autosync_ref="AES4"; break; 4914 autosync_ref = "AES1"; break;
3295 case HDSPM_AES32_AUTOSYNC_FROM_AES5: autosync_ref="AES5"; break; 4915 case HDSPM_AES32_AUTOSYNC_FROM_AES2:
3296 case HDSPM_AES32_AUTOSYNC_FROM_AES6: autosync_ref="AES6"; break; 4916 autosync_ref = "AES2"; break;
3297 case HDSPM_AES32_AUTOSYNC_FROM_AES7: autosync_ref="AES7"; break; 4917 case HDSPM_AES32_AUTOSYNC_FROM_AES3:
3298 case HDSPM_AES32_AUTOSYNC_FROM_AES8: autosync_ref="AES8"; break; 4918 autosync_ref = "AES3"; break;
3299 default: autosync_ref = "---"; break; 4919 case HDSPM_AES32_AUTOSYNC_FROM_AES4:
4920 autosync_ref = "AES4"; break;
4921 case HDSPM_AES32_AUTOSYNC_FROM_AES5:
4922 autosync_ref = "AES5"; break;
4923 case HDSPM_AES32_AUTOSYNC_FROM_AES6:
4924 autosync_ref = "AES6"; break;
4925 case HDSPM_AES32_AUTOSYNC_FROM_AES7:
4926 autosync_ref = "AES7"; break;
4927 case HDSPM_AES32_AUTOSYNC_FROM_AES8:
4928 autosync_ref = "AES8"; break;
4929 default:
4930 autosync_ref = "---"; break;
3300 } 4931 }
3301 snd_iprintf(buffer, "AutoSync ref = %s\n", autosync_ref); 4932 snd_iprintf(buffer, "AutoSync ref = %s\n", autosync_ref);
3302 4933
3303 snd_iprintf(buffer, "\n"); 4934 snd_iprintf(buffer, "\n");
3304} 4935}
3305 4936
4937static void
4938snd_hdspm_proc_read_raydat(struct snd_info_entry *entry,
4939 struct snd_info_buffer *buffer)
4940{
4941 struct hdspm *hdspm = entry->private_data;
4942 unsigned int status1, status2, status3, control, i;
4943 unsigned int lock, sync;
4944
4945 status1 = hdspm_read(hdspm, HDSPM_RD_STATUS_1); /* s1 */
4946 status2 = hdspm_read(hdspm, HDSPM_RD_STATUS_2); /* freq */
4947 status3 = hdspm_read(hdspm, HDSPM_RD_STATUS_3); /* s2 */
4948
4949 control = hdspm->control_register;
4950
4951 snd_iprintf(buffer, "STATUS1: 0x%08x\n", status1);
4952 snd_iprintf(buffer, "STATUS2: 0x%08x\n", status2);
4953 snd_iprintf(buffer, "STATUS3: 0x%08x\n", status3);
4954
4955
4956 snd_iprintf(buffer, "\n*** CLOCK MODE\n\n");
4957
4958 snd_iprintf(buffer, "Clock mode : %s\n",
4959 (hdspm_system_clock_mode(hdspm) == 0) ? "master" : "slave");
4960 snd_iprintf(buffer, "System frequency: %d Hz\n",
4961 hdspm_get_system_sample_rate(hdspm));
4962
4963 snd_iprintf(buffer, "\n*** INPUT STATUS\n\n");
4964
4965 lock = 0x1;
4966 sync = 0x100;
4967
4968 for (i = 0; i < 8; i++) {
4969 snd_iprintf(buffer, "s1_input %d: Lock %d, Sync %d, Freq %s\n",
4970 i,
4971 (status1 & lock) ? 1 : 0,
4972 (status1 & sync) ? 1 : 0,
4973 texts_freq[(status2 >> (i * 4)) & 0xF]);
4974
4975 lock = lock<<1;
4976 sync = sync<<1;
4977 }
4978
4979 snd_iprintf(buffer, "WC input: Lock %d, Sync %d, Freq %s\n",
4980 (status1 & 0x1000000) ? 1 : 0,
4981 (status1 & 0x2000000) ? 1 : 0,
4982 texts_freq[(status1 >> 16) & 0xF]);
4983
4984 snd_iprintf(buffer, "TCO input: Lock %d, Sync %d, Freq %s\n",
4985 (status1 & 0x4000000) ? 1 : 0,
4986 (status1 & 0x8000000) ? 1 : 0,
4987 texts_freq[(status1 >> 20) & 0xF]);
4988
4989 snd_iprintf(buffer, "SYNC IN: Lock %d, Sync %d, Freq %s\n",
4990 (status3 & 0x400) ? 1 : 0,
4991 (status3 & 0x800) ? 1 : 0,
4992 texts_freq[(status2 >> 12) & 0xF]);
4993
4994}
4995
3306#ifdef CONFIG_SND_DEBUG 4996#ifdef CONFIG_SND_DEBUG
3307static void 4997static void
3308snd_hdspm_proc_read_debug(struct snd_info_entry * entry, 4998snd_hdspm_proc_read_debug(struct snd_info_entry *entry,
3309 struct snd_info_buffer *buffer) 4999 struct snd_info_buffer *buffer)
3310{ 5000{
3311 struct hdspm *hdspm = entry->private_data; 5001 struct hdspm *hdspm = entry->private_data;
@@ -3322,16 +5012,68 @@ snd_hdspm_proc_read_debug(struct snd_info_entry * entry,
3322#endif 5012#endif
3323 5013
3324 5014
5015static void snd_hdspm_proc_ports_in(struct snd_info_entry *entry,
5016 struct snd_info_buffer *buffer)
5017{
5018 struct hdspm *hdspm = entry->private_data;
5019 int i;
5020
5021 snd_iprintf(buffer, "# generated by hdspm\n");
5022
5023 for (i = 0; i < hdspm->max_channels_in; i++) {
5024 snd_iprintf(buffer, "%d=%s\n", i+1, hdspm->port_names_in[i]);
5025 }
5026}
3325 5027
3326static void __devinit snd_hdspm_proc_init(struct hdspm * hdspm) 5028static void snd_hdspm_proc_ports_out(struct snd_info_entry *entry,
5029 struct snd_info_buffer *buffer)
5030{
5031 struct hdspm *hdspm = entry->private_data;
5032 int i;
5033
5034 snd_iprintf(buffer, "# generated by hdspm\n");
5035
5036 for (i = 0; i < hdspm->max_channels_out; i++) {
5037 snd_iprintf(buffer, "%d=%s\n", i+1, hdspm->port_names_out[i]);
5038 }
5039}
5040
5041
5042static void __devinit snd_hdspm_proc_init(struct hdspm *hdspm)
3327{ 5043{
3328 struct snd_info_entry *entry; 5044 struct snd_info_entry *entry;
3329 5045
3330 if (!snd_card_proc_new(hdspm->card, "hdspm", &entry)) 5046 if (!snd_card_proc_new(hdspm->card, "hdspm", &entry)) {
3331 snd_info_set_text_ops(entry, hdspm, 5047 switch (hdspm->io_type) {
3332 hdspm->is_aes32 ? 5048 case AES32:
3333 snd_hdspm_proc_read_aes32 : 5049 snd_info_set_text_ops(entry, hdspm,
3334 snd_hdspm_proc_read_madi); 5050 snd_hdspm_proc_read_aes32);
5051 break;
5052 case MADI:
5053 snd_info_set_text_ops(entry, hdspm,
5054 snd_hdspm_proc_read_madi);
5055 break;
5056 case MADIface:
5057 /* snd_info_set_text_ops(entry, hdspm,
5058 snd_hdspm_proc_read_madiface); */
5059 break;
5060 case RayDAT:
5061 snd_info_set_text_ops(entry, hdspm,
5062 snd_hdspm_proc_read_raydat);
5063 break;
5064 case AIO:
5065 break;
5066 }
5067 }
5068
5069 if (!snd_card_proc_new(hdspm->card, "ports.in", &entry)) {
5070 snd_info_set_text_ops(entry, hdspm, snd_hdspm_proc_ports_in);
5071 }
5072
5073 if (!snd_card_proc_new(hdspm->card, "ports.out", &entry)) {
5074 snd_info_set_text_ops(entry, hdspm, snd_hdspm_proc_ports_out);
5075 }
5076
3335#ifdef CONFIG_SND_DEBUG 5077#ifdef CONFIG_SND_DEBUG
3336 /* debug file to read all hdspm registers */ 5078 /* debug file to read all hdspm registers */
3337 if (!snd_card_proc_new(hdspm->card, "debug", &entry)) 5079 if (!snd_card_proc_new(hdspm->card, "debug", &entry))
@@ -3341,47 +5083,48 @@ static void __devinit snd_hdspm_proc_init(struct hdspm * hdspm)
3341} 5083}
3342 5084
3343/*------------------------------------------------------------ 5085/*------------------------------------------------------------
3344 hdspm intitialize 5086 hdspm intitialize
3345 ------------------------------------------------------------*/ 5087 ------------------------------------------------------------*/
3346 5088
3347static int snd_hdspm_set_defaults(struct hdspm * hdspm) 5089static int snd_hdspm_set_defaults(struct hdspm * hdspm)
3348{ 5090{
3349 unsigned int i;
3350
3351 /* ASSUMPTION: hdspm->lock is either held, or there is no need to 5091 /* ASSUMPTION: hdspm->lock is either held, or there is no need to
3352 hold it (e.g. during module initialization). 5092 hold it (e.g. during module initialization).
3353 */ 5093 */
3354 5094
3355 /* set defaults: */ 5095 /* set defaults: */
3356 5096
3357 if (hdspm->is_aes32) 5097 hdspm->settings_register = 0;
5098
5099 switch (hdspm->io_type) {
5100 case MADI:
5101 case MADIface:
5102 hdspm->control_register =
5103 0x2 + 0x8 + 0x10 + 0x80 + 0x400 + 0x4000 + 0x1000000;
5104 break;
5105
5106 case RayDAT:
5107 case AIO:
5108 hdspm->settings_register = 0x1 + 0x1000;
5109 /* Magic values are: LAT_0, LAT_2, Master, freq1, tx64ch, inp_0,
5110 * line_out */
5111 hdspm->control_register =
5112 0x2 + 0x8 + 0x10 + 0x80 + 0x400 + 0x4000 + 0x1000000;
5113 break;
5114
5115 case AES32:
3358 hdspm->control_register = 5116 hdspm->control_register =
3359 HDSPM_ClockModeMaster | /* Master Cloack Mode on */ 5117 HDSPM_ClockModeMaster | /* Master Cloack Mode on */
3360 hdspm_encode_latency(7) | /* latency maximum = 5118 hdspm_encode_latency(7) | /* latency max=8192samples */
3361 * 8192 samples
3362 */
3363 HDSPM_SyncRef0 | /* AES1 is syncclock */ 5119 HDSPM_SyncRef0 | /* AES1 is syncclock */
3364 HDSPM_LineOut | /* Analog output in */ 5120 HDSPM_LineOut | /* Analog output in */
3365 HDSPM_Professional; /* Professional mode */ 5121 HDSPM_Professional; /* Professional mode */
3366 else 5122 break;
3367 hdspm->control_register = 5123 }
3368 HDSPM_ClockModeMaster | /* Master Cloack Mode on */
3369 hdspm_encode_latency(7) | /* latency maximum =
3370 * 8192 samples
3371 */
3372 HDSPM_InputCoaxial | /* Input Coax not Optical */
3373 HDSPM_SyncRef_MADI | /* Madi is syncclock */
3374 HDSPM_LineOut | /* Analog output in */
3375 HDSPM_TX_64ch | /* transmit in 64ch mode */
3376 HDSPM_AutoInp; /* AutoInput chossing (takeover) */
3377
3378 /* ! HDSPM_Frequency0|HDSPM_Frequency1 = 44.1khz */
3379 /* ! HDSPM_DoubleSpeed HDSPM_QuadSpeed = normal speed */
3380 /* ! HDSPM_clr_tms = do not clear bits in track marks */
3381 5124
3382 hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register); 5125 hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
3383 5126
3384 if (!hdspm->is_aes32) { 5127 if (AES32 == hdspm->io_type) {
3385 /* No control2 register for AES32 */ 5128 /* No control2 register for AES32 */
3386#ifdef SNDRV_BIG_ENDIAN 5129#ifdef SNDRV_BIG_ENDIAN
3387 hdspm->control2_register = HDSPM_BIGENDIAN_MODE; 5130 hdspm->control2_register = HDSPM_BIGENDIAN_MODE;
@@ -3397,57 +5140,59 @@ static int snd_hdspm_set_defaults(struct hdspm * hdspm)
3397 5140
3398 all_in_all_mixer(hdspm, 0 * UNITY_GAIN); 5141 all_in_all_mixer(hdspm, 0 * UNITY_GAIN);
3399 5142
3400 if (line_outs_monitor[hdspm->dev]) { 5143 if (hdspm->io_type == AIO || hdspm->io_type == RayDAT) {
3401 5144 hdspm_write(hdspm, HDSPM_WR_SETTINGS, hdspm->settings_register);
3402 snd_printk(KERN_INFO "HDSPM: "
3403 "sending all playback streams to line outs.\n");
3404
3405 for (i = 0; i < HDSPM_MIXER_CHANNELS; i++) {
3406 if (hdspm_write_pb_gain(hdspm, i, i, UNITY_GAIN))
3407 return -EIO;
3408 }
3409 } 5145 }
3410 5146
3411 /* set a default rate so that the channel map is set up. */ 5147 /* set a default rate so that the channel map is set up. */
3412 hdspm->channel_map = channel_map_madi_ss; 5148 hdspm_set_rate(hdspm, 48000, 1);
3413 hdspm_set_rate(hdspm, 44100, 1);
3414 5149
3415 return 0; 5150 return 0;
3416} 5151}
3417 5152
3418 5153
3419/*------------------------------------------------------------ 5154/*------------------------------------------------------------
3420 interrupt 5155 interrupt
3421 ------------------------------------------------------------*/ 5156 ------------------------------------------------------------*/
3422 5157
3423static irqreturn_t snd_hdspm_interrupt(int irq, void *dev_id) 5158static irqreturn_t snd_hdspm_interrupt(int irq, void *dev_id)
3424{ 5159{
3425 struct hdspm *hdspm = (struct hdspm *) dev_id; 5160 struct hdspm *hdspm = (struct hdspm *) dev_id;
3426 unsigned int status; 5161 unsigned int status;
3427 int audio; 5162 int i, audio, midi, schedule = 0;
3428 int midi0; 5163 /* cycles_t now; */
3429 int midi1;
3430 unsigned int midi0status;
3431 unsigned int midi1status;
3432 int schedule = 0;
3433 5164
3434 status = hdspm_read(hdspm, HDSPM_statusRegister); 5165 status = hdspm_read(hdspm, HDSPM_statusRegister);
3435 5166
3436 audio = status & HDSPM_audioIRQPending; 5167 audio = status & HDSPM_audioIRQPending;
3437 midi0 = status & HDSPM_midi0IRQPending; 5168 midi = status & (HDSPM_midi0IRQPending | HDSPM_midi1IRQPending |
3438 midi1 = status & HDSPM_midi1IRQPending; 5169 HDSPM_midi2IRQPending | HDSPM_midi3IRQPending);
5170
5171 /* now = get_cycles(); */
5172 /**
5173 * LAT_2..LAT_0 period counter (win) counter (mac)
5174 * 6 4096 ~256053425 ~514672358
5175 * 5 2048 ~128024983 ~257373821
5176 * 4 1024 ~64023706 ~128718089
5177 * 3 512 ~32005945 ~64385999
5178 * 2 256 ~16003039 ~32260176
5179 * 1 128 ~7998738 ~16194507
5180 * 0 64 ~3998231 ~8191558
5181 **/
5182 /*
5183 snd_printk(KERN_INFO "snd_hdspm_interrupt %llu @ %llx\n",
5184 now-hdspm->last_interrupt, status & 0xFFC0);
5185 hdspm->last_interrupt = now;
5186 */
3439 5187
3440 if (!audio && !midi0 && !midi1) 5188 if (!audio && !midi)
3441 return IRQ_NONE; 5189 return IRQ_NONE;
3442 5190
3443 hdspm_write(hdspm, HDSPM_interruptConfirmation, 0); 5191 hdspm_write(hdspm, HDSPM_interruptConfirmation, 0);
3444 hdspm->irq_count++; 5192 hdspm->irq_count++;
3445 5193
3446 midi0status = hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xff;
3447 midi1status = hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xff;
3448 5194
3449 if (audio) { 5195 if (audio) {
3450
3451 if (hdspm->capture_substream) 5196 if (hdspm->capture_substream)
3452 snd_pcm_period_elapsed(hdspm->capture_substream); 5197 snd_pcm_period_elapsed(hdspm->capture_substream);
3453 5198
@@ -3455,118 +5200,44 @@ static irqreturn_t snd_hdspm_interrupt(int irq, void *dev_id)
3455 snd_pcm_period_elapsed(hdspm->playback_substream); 5200 snd_pcm_period_elapsed(hdspm->playback_substream);
3456 } 5201 }
3457 5202
3458 if (midi0 && midi0status) { 5203 if (midi) {
3459 /* we disable interrupts for this input until processing 5204 i = 0;
3460 * is done 5205 while (i < hdspm->midiPorts) {
3461 */ 5206 if ((hdspm_read(hdspm,
3462 hdspm->control_register &= ~HDSPM_Midi0InterruptEnable; 5207 hdspm->midi[i].statusIn) & 0xff) &&
3463 hdspm_write(hdspm, HDSPM_controlRegister, 5208 (status & hdspm->midi[i].irq)) {
3464 hdspm->control_register); 5209 /* we disable interrupts for this input until
3465 hdspm->midi[0].pending = 1; 5210 * processing is done
3466 schedule = 1; 5211 */
3467 } 5212 hdspm->control_register &= ~hdspm->midi[i].ie;
3468 if (midi1 && midi1status) { 5213 hdspm_write(hdspm, HDSPM_controlRegister,
3469 /* we disable interrupts for this input until processing 5214 hdspm->control_register);
3470 * is done 5215 hdspm->midi[i].pending = 1;
3471 */ 5216 schedule = 1;
3472 hdspm->control_register &= ~HDSPM_Midi1InterruptEnable; 5217 }
3473 hdspm_write(hdspm, HDSPM_controlRegister, 5218
3474 hdspm->control_register); 5219 i++;
3475 hdspm->midi[1].pending = 1; 5220 }
3476 schedule = 1; 5221
5222 if (schedule)
5223 tasklet_hi_schedule(&hdspm->midi_tasklet);
3477 } 5224 }
3478 if (schedule) 5225
3479 tasklet_schedule(&hdspm->midi_tasklet);
3480 return IRQ_HANDLED; 5226 return IRQ_HANDLED;
3481} 5227}
3482 5228
3483/*------------------------------------------------------------ 5229/*------------------------------------------------------------
3484 pcm interface 5230 pcm interface
3485 ------------------------------------------------------------*/ 5231 ------------------------------------------------------------*/
3486 5232
3487 5233
3488static snd_pcm_uframes_t snd_hdspm_hw_pointer(struct snd_pcm_substream * 5234static snd_pcm_uframes_t snd_hdspm_hw_pointer(struct snd_pcm_substream
3489 substream) 5235 *substream)
3490{ 5236{
3491 struct hdspm *hdspm = snd_pcm_substream_chip(substream); 5237 struct hdspm *hdspm = snd_pcm_substream_chip(substream);
3492 return hdspm_hw_pointer(hdspm); 5238 return hdspm_hw_pointer(hdspm);
3493} 5239}
3494 5240
3495static char *hdspm_channel_buffer_location(struct hdspm * hdspm,
3496 int stream, int channel)
3497{
3498 int mapped_channel;
3499
3500 if (snd_BUG_ON(channel < 0 || channel >= HDSPM_MAX_CHANNELS))
3501 return NULL;
3502
3503 mapped_channel = hdspm->channel_map[channel];
3504 if (mapped_channel < 0)
3505 return NULL;
3506
3507 if (stream == SNDRV_PCM_STREAM_CAPTURE)
3508 return hdspm->capture_buffer +
3509 mapped_channel * HDSPM_CHANNEL_BUFFER_BYTES;
3510 else
3511 return hdspm->playback_buffer +
3512 mapped_channel * HDSPM_CHANNEL_BUFFER_BYTES;
3513}
3514
3515
3516/* dont know why need it ??? */
3517static int snd_hdspm_playback_copy(struct snd_pcm_substream *substream,
3518 int channel, snd_pcm_uframes_t pos,
3519 void __user *src, snd_pcm_uframes_t count)
3520{
3521 struct hdspm *hdspm = snd_pcm_substream_chip(substream);
3522 char *channel_buf;
3523
3524 if (snd_BUG_ON(pos + count > HDSPM_CHANNEL_BUFFER_BYTES / 4))
3525 return -EINVAL;
3526
3527 channel_buf =
3528 hdspm_channel_buffer_location(hdspm, substream->pstr->stream,
3529 channel);
3530
3531 if (snd_BUG_ON(!channel_buf))
3532 return -EIO;
3533
3534 return copy_from_user(channel_buf + pos * 4, src, count * 4);
3535}
3536
3537static int snd_hdspm_capture_copy(struct snd_pcm_substream *substream,
3538 int channel, snd_pcm_uframes_t pos,
3539 void __user *dst, snd_pcm_uframes_t count)
3540{
3541 struct hdspm *hdspm = snd_pcm_substream_chip(substream);
3542 char *channel_buf;
3543
3544 if (snd_BUG_ON(pos + count > HDSPM_CHANNEL_BUFFER_BYTES / 4))
3545 return -EINVAL;
3546
3547 channel_buf =
3548 hdspm_channel_buffer_location(hdspm, substream->pstr->stream,
3549 channel);
3550 if (snd_BUG_ON(!channel_buf))
3551 return -EIO;
3552 return copy_to_user(dst, channel_buf + pos * 4, count * 4);
3553}
3554
3555static int snd_hdspm_hw_silence(struct snd_pcm_substream *substream,
3556 int channel, snd_pcm_uframes_t pos,
3557 snd_pcm_uframes_t count)
3558{
3559 struct hdspm *hdspm = snd_pcm_substream_chip(substream);
3560 char *channel_buf;
3561
3562 channel_buf =
3563 hdspm_channel_buffer_location(hdspm, substream->pstr->stream,
3564 channel);
3565 if (snd_BUG_ON(!channel_buf))
3566 return -EIO;
3567 memset(channel_buf + pos * 4, 0, count * 4);
3568 return 0;
3569}
3570 5241
3571static int snd_hdspm_reset(struct snd_pcm_substream *substream) 5242static int snd_hdspm_reset(struct snd_pcm_substream *substream)
3572{ 5243{
@@ -3589,7 +5260,7 @@ static int snd_hdspm_reset(struct snd_pcm_substream *substream)
3589 snd_pcm_group_for_each_entry(s, substream) { 5260 snd_pcm_group_for_each_entry(s, substream) {
3590 if (s == other) { 5261 if (s == other) {
3591 oruntime->status->hw_ptr = 5262 oruntime->status->hw_ptr =
3592 runtime->status->hw_ptr; 5263 runtime->status->hw_ptr;
3593 break; 5264 break;
3594 } 5265 }
3595 } 5266 }
@@ -3621,19 +5292,19 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream,
3621 /* The other stream is open, and not by the same 5292 /* The other stream is open, and not by the same
3622 task as this one. Make sure that the parameters 5293 task as this one. Make sure that the parameters
3623 that matter are the same. 5294 that matter are the same.
3624 */ 5295 */
3625 5296
3626 if (params_rate(params) != hdspm->system_sample_rate) { 5297 if (params_rate(params) != hdspm->system_sample_rate) {
3627 spin_unlock_irq(&hdspm->lock); 5298 spin_unlock_irq(&hdspm->lock);
3628 _snd_pcm_hw_param_setempty(params, 5299 _snd_pcm_hw_param_setempty(params,
3629 SNDRV_PCM_HW_PARAM_RATE); 5300 SNDRV_PCM_HW_PARAM_RATE);
3630 return -EBUSY; 5301 return -EBUSY;
3631 } 5302 }
3632 5303
3633 if (params_period_size(params) != hdspm->period_bytes / 4) { 5304 if (params_period_size(params) != hdspm->period_bytes / 4) {
3634 spin_unlock_irq(&hdspm->lock); 5305 spin_unlock_irq(&hdspm->lock);
3635 _snd_pcm_hw_param_setempty(params, 5306 _snd_pcm_hw_param_setempty(params,
3636 SNDRV_PCM_HW_PARAM_PERIOD_SIZE); 5307 SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
3637 return -EBUSY; 5308 return -EBUSY;
3638 } 5309 }
3639 5310
@@ -3646,18 +5317,20 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream,
3646 spin_lock_irq(&hdspm->lock); 5317 spin_lock_irq(&hdspm->lock);
3647 err = hdspm_set_rate(hdspm, params_rate(params), 0); 5318 err = hdspm_set_rate(hdspm, params_rate(params), 0);
3648 if (err < 0) { 5319 if (err < 0) {
5320 snd_printk(KERN_INFO "err on hdspm_set_rate: %d\n", err);
3649 spin_unlock_irq(&hdspm->lock); 5321 spin_unlock_irq(&hdspm->lock);
3650 _snd_pcm_hw_param_setempty(params, 5322 _snd_pcm_hw_param_setempty(params,
3651 SNDRV_PCM_HW_PARAM_RATE); 5323 SNDRV_PCM_HW_PARAM_RATE);
3652 return err; 5324 return err;
3653 } 5325 }
3654 spin_unlock_irq(&hdspm->lock); 5326 spin_unlock_irq(&hdspm->lock);
3655 5327
3656 err = hdspm_set_interrupt_interval(hdspm, 5328 err = hdspm_set_interrupt_interval(hdspm,
3657 params_period_size(params)); 5329 params_period_size(params));
3658 if (err < 0) { 5330 if (err < 0) {
5331 snd_printk(KERN_INFO "err on hdspm_set_interrupt_interval: %d\n", err);
3659 _snd_pcm_hw_param_setempty(params, 5332 _snd_pcm_hw_param_setempty(params,
3660 SNDRV_PCM_HW_PARAM_PERIOD_SIZE); 5333 SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
3661 return err; 5334 return err;
3662 } 5335 }
3663 5336
@@ -3667,10 +5340,13 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream,
3667 /* malloc all buffer even if not enabled to get sure */ 5340 /* malloc all buffer even if not enabled to get sure */
3668 /* Update for MADI rev 204: we need to allocate for all channels, 5341 /* Update for MADI rev 204: we need to allocate for all channels,
3669 * otherwise it doesn't work at 96kHz */ 5342 * otherwise it doesn't work at 96kHz */
5343
3670 err = 5344 err =
3671 snd_pcm_lib_malloc_pages(substream, HDSPM_DMA_AREA_BYTES); 5345 snd_pcm_lib_malloc_pages(substream, HDSPM_DMA_AREA_BYTES);
3672 if (err < 0) 5346 if (err < 0) {
5347 snd_printk(KERN_INFO "err on snd_pcm_lib_malloc_pages: %d\n", err);
3673 return err; 5348 return err;
5349 }
3674 5350
3675 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 5351 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
3676 5352
@@ -3681,7 +5357,7 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream,
3681 snd_hdspm_enable_out(hdspm, i, 1); 5357 snd_hdspm_enable_out(hdspm, i, 1);
3682 5358
3683 hdspm->playback_buffer = 5359 hdspm->playback_buffer =
3684 (unsigned char *) substream->runtime->dma_area; 5360 (unsigned char *) substream->runtime->dma_area;
3685 snd_printdd("Allocated sample buffer for playback at %p\n", 5361 snd_printdd("Allocated sample buffer for playback at %p\n",
3686 hdspm->playback_buffer); 5362 hdspm->playback_buffer);
3687 } else { 5363 } else {
@@ -3692,23 +5368,40 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream,
3692 snd_hdspm_enable_in(hdspm, i, 1); 5368 snd_hdspm_enable_in(hdspm, i, 1);
3693 5369
3694 hdspm->capture_buffer = 5370 hdspm->capture_buffer =
3695 (unsigned char *) substream->runtime->dma_area; 5371 (unsigned char *) substream->runtime->dma_area;
3696 snd_printdd("Allocated sample buffer for capture at %p\n", 5372 snd_printdd("Allocated sample buffer for capture at %p\n",
3697 hdspm->capture_buffer); 5373 hdspm->capture_buffer);
3698 } 5374 }
5375
3699 /* 5376 /*
3700 snd_printdd("Allocated sample buffer for %s at 0x%08X\n", 5377 snd_printdd("Allocated sample buffer for %s at 0x%08X\n",
3701 substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 5378 substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
3702 "playback" : "capture", 5379 "playback" : "capture",
3703 snd_pcm_sgbuf_get_addr(substream, 0)); 5380 snd_pcm_sgbuf_get_addr(substream, 0));
3704 */ 5381 */
3705 /* 5382 /*
3706 snd_printdd("set_hwparams: %s %d Hz, %d channels, bs = %d\n", 5383 snd_printdd("set_hwparams: %s %d Hz, %d channels, bs = %d\n",
3707 substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 5384 substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
3708 "playback" : "capture", 5385 "playback" : "capture",
3709 params_rate(params), params_channels(params), 5386 params_rate(params), params_channels(params),
3710 params_buffer_size(params)); 5387 params_buffer_size(params));
3711 */ 5388 */
5389
5390
5391 /* Switch to native float format if requested */
5392 if (SNDRV_PCM_FORMAT_FLOAT_LE == params_format(params)) {
5393 if (!(hdspm->control_register & HDSPe_FLOAT_FORMAT))
5394 snd_printk(KERN_INFO "hdspm: Switching to native 32bit LE float format.\n");
5395
5396 hdspm->control_register |= HDSPe_FLOAT_FORMAT;
5397 } else if (SNDRV_PCM_FORMAT_S32_LE == params_format(params)) {
5398 if (hdspm->control_register & HDSPe_FLOAT_FORMAT)
5399 snd_printk(KERN_INFO "hdspm: Switching to native 32bit LE integer format.\n");
5400
5401 hdspm->control_register &= ~HDSPe_FLOAT_FORMAT;
5402 }
5403 hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
5404
3712 return 0; 5405 return 0;
3713} 5406}
3714 5407
@@ -3719,14 +5412,14 @@ static int snd_hdspm_hw_free(struct snd_pcm_substream *substream)
3719 5412
3720 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 5413 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
3721 5414
3722 /* params_channels(params) should be enough, 5415 /* params_channels(params) should be enough,
3723 but to get sure in case of error */ 5416 but to get sure in case of error */
3724 for (i = 0; i < HDSPM_MAX_CHANNELS; ++i) 5417 for (i = 0; i < hdspm->max_channels_out; ++i)
3725 snd_hdspm_enable_out(hdspm, i, 0); 5418 snd_hdspm_enable_out(hdspm, i, 0);
3726 5419
3727 hdspm->playback_buffer = NULL; 5420 hdspm->playback_buffer = NULL;
3728 } else { 5421 } else {
3729 for (i = 0; i < HDSPM_MAX_CHANNELS; ++i) 5422 for (i = 0; i < hdspm->max_channels_in; ++i)
3730 snd_hdspm_enable_in(hdspm, i, 0); 5423 snd_hdspm_enable_in(hdspm, i, 0);
3731 5424
3732 hdspm->capture_buffer = NULL; 5425 hdspm->capture_buffer = NULL;
@@ -3738,37 +5431,58 @@ static int snd_hdspm_hw_free(struct snd_pcm_substream *substream)
3738 return 0; 5431 return 0;
3739} 5432}
3740 5433
5434
3741static int snd_hdspm_channel_info(struct snd_pcm_substream *substream, 5435static int snd_hdspm_channel_info(struct snd_pcm_substream *substream,
3742 struct snd_pcm_channel_info * info) 5436 struct snd_pcm_channel_info *info)
3743{ 5437{
3744 struct hdspm *hdspm = snd_pcm_substream_chip(substream); 5438 struct hdspm *hdspm = snd_pcm_substream_chip(substream);
3745 int mapped_channel;
3746 5439
3747 if (snd_BUG_ON(info->channel >= HDSPM_MAX_CHANNELS)) 5440 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
3748 return -EINVAL; 5441 if (snd_BUG_ON(info->channel >= hdspm->max_channels_out)) {
5442 snd_printk(KERN_INFO "snd_hdspm_channel_info: output channel out of range (%d)\n", info->channel);
5443 return -EINVAL;
5444 }
3749 5445
3750 mapped_channel = hdspm->channel_map[info->channel]; 5446 if (hdspm->channel_map_out[info->channel] < 0) {
3751 if (mapped_channel < 0) 5447 snd_printk(KERN_INFO "snd_hdspm_channel_info: output channel %d mapped out\n", info->channel);
3752 return -EINVAL; 5448 return -EINVAL;
5449 }
5450
5451 info->offset = hdspm->channel_map_out[info->channel] *
5452 HDSPM_CHANNEL_BUFFER_BYTES;
5453 } else {
5454 if (snd_BUG_ON(info->channel >= hdspm->max_channels_in)) {
5455 snd_printk(KERN_INFO "snd_hdspm_channel_info: input channel out of range (%d)\n", info->channel);
5456 return -EINVAL;
5457 }
5458
5459 if (hdspm->channel_map_in[info->channel] < 0) {
5460 snd_printk(KERN_INFO "snd_hdspm_channel_info: input channel %d mapped out\n", info->channel);
5461 return -EINVAL;
5462 }
5463
5464 info->offset = hdspm->channel_map_in[info->channel] *
5465 HDSPM_CHANNEL_BUFFER_BYTES;
5466 }
3753 5467
3754 info->offset = mapped_channel * HDSPM_CHANNEL_BUFFER_BYTES;
3755 info->first = 0; 5468 info->first = 0;
3756 info->step = 32; 5469 info->step = 32;
3757 return 0; 5470 return 0;
3758} 5471}
3759 5472
5473
3760static int snd_hdspm_ioctl(struct snd_pcm_substream *substream, 5474static int snd_hdspm_ioctl(struct snd_pcm_substream *substream,
3761 unsigned int cmd, void *arg) 5475 unsigned int cmd, void *arg)
3762{ 5476{
3763 switch (cmd) { 5477 switch (cmd) {
3764 case SNDRV_PCM_IOCTL1_RESET: 5478 case SNDRV_PCM_IOCTL1_RESET:
3765 return snd_hdspm_reset(substream); 5479 return snd_hdspm_reset(substream);
3766 5480
3767 case SNDRV_PCM_IOCTL1_CHANNEL_INFO: 5481 case SNDRV_PCM_IOCTL1_CHANNEL_INFO:
3768 { 5482 {
3769 struct snd_pcm_channel_info *info = arg; 5483 struct snd_pcm_channel_info *info = arg;
3770 return snd_hdspm_channel_info(substream, info); 5484 return snd_hdspm_channel_info(substream, info);
3771 } 5485 }
3772 default: 5486 default:
3773 break; 5487 break;
3774 } 5488 }
@@ -3815,19 +5529,19 @@ static int snd_hdspm_trigger(struct snd_pcm_substream *substream, int cmd)
3815 } 5529 }
3816 if (cmd == SNDRV_PCM_TRIGGER_START) { 5530 if (cmd == SNDRV_PCM_TRIGGER_START) {
3817 if (!(running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) 5531 if (!(running & (1 << SNDRV_PCM_STREAM_PLAYBACK))
3818 && substream->stream == 5532 && substream->stream ==
3819 SNDRV_PCM_STREAM_CAPTURE) 5533 SNDRV_PCM_STREAM_CAPTURE)
3820 hdspm_silence_playback(hdspm); 5534 hdspm_silence_playback(hdspm);
3821 } else { 5535 } else {
3822 if (running && 5536 if (running &&
3823 substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 5537 substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
3824 hdspm_silence_playback(hdspm); 5538 hdspm_silence_playback(hdspm);
3825 } 5539 }
3826 } else { 5540 } else {
3827 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) 5541 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
3828 hdspm_silence_playback(hdspm); 5542 hdspm_silence_playback(hdspm);
3829 } 5543 }
3830 _ok: 5544_ok:
3831 snd_pcm_trigger_done(substream, substream); 5545 snd_pcm_trigger_done(substream, substream);
3832 if (!hdspm->running && running) 5546 if (!hdspm->running && running)
3833 hdspm_start_audio(hdspm); 5547 hdspm_start_audio(hdspm);
@@ -3844,8 +5558,18 @@ static int snd_hdspm_prepare(struct snd_pcm_substream *substream)
3844 return 0; 5558 return 0;
3845} 5559}
3846 5560
3847static unsigned int period_sizes[] = 5561static unsigned int period_sizes_old[] = {
3848 { 64, 128, 256, 512, 1024, 2048, 4096, 8192 }; 5562 64, 128, 256, 512, 1024, 2048, 4096
5563};
5564
5565static unsigned int period_sizes_new[] = {
5566 32, 64, 128, 256, 512, 1024, 2048, 4096
5567};
5568
5569/* RayDAT and AIO always have a buffer of 16384 samples per channel */
5570static unsigned int raydat_aio_buffer_sizes[] = {
5571 16384
5572};
3849 5573
3850static struct snd_pcm_hardware snd_hdspm_playback_subinfo = { 5574static struct snd_pcm_hardware snd_hdspm_playback_subinfo = {
3851 .info = (SNDRV_PCM_INFO_MMAP | 5575 .info = (SNDRV_PCM_INFO_MMAP |
@@ -3866,9 +5590,9 @@ static struct snd_pcm_hardware snd_hdspm_playback_subinfo = {
3866 .buffer_bytes_max = 5590 .buffer_bytes_max =
3867 HDSPM_CHANNEL_BUFFER_BYTES * HDSPM_MAX_CHANNELS, 5591 HDSPM_CHANNEL_BUFFER_BYTES * HDSPM_MAX_CHANNELS,
3868 .period_bytes_min = (64 * 4), 5592 .period_bytes_min = (64 * 4),
3869 .period_bytes_max = (8192 * 4) * HDSPM_MAX_CHANNELS, 5593 .period_bytes_max = (4096 * 4) * HDSPM_MAX_CHANNELS,
3870 .periods_min = 2, 5594 .periods_min = 2,
3871 .periods_max = 2, 5595 .periods_max = 512,
3872 .fifo_size = 0 5596 .fifo_size = 0
3873}; 5597};
3874 5598
@@ -3891,20 +5615,66 @@ static struct snd_pcm_hardware snd_hdspm_capture_subinfo = {
3891 .buffer_bytes_max = 5615 .buffer_bytes_max =
3892 HDSPM_CHANNEL_BUFFER_BYTES * HDSPM_MAX_CHANNELS, 5616 HDSPM_CHANNEL_BUFFER_BYTES * HDSPM_MAX_CHANNELS,
3893 .period_bytes_min = (64 * 4), 5617 .period_bytes_min = (64 * 4),
3894 .period_bytes_max = (8192 * 4) * HDSPM_MAX_CHANNELS, 5618 .period_bytes_max = (4096 * 4) * HDSPM_MAX_CHANNELS,
3895 .periods_min = 2, 5619 .periods_min = 2,
3896 .periods_max = 2, 5620 .periods_max = 512,
3897 .fifo_size = 0 5621 .fifo_size = 0
3898}; 5622};
3899 5623
3900static struct snd_pcm_hw_constraint_list hw_constraints_period_sizes = { 5624static struct snd_pcm_hw_constraint_list hw_constraints_period_sizes_old = {
3901 .count = ARRAY_SIZE(period_sizes), 5625 .count = ARRAY_SIZE(period_sizes_old),
3902 .list = period_sizes, 5626 .list = period_sizes_old,
3903 .mask = 0 5627 .mask = 0
3904}; 5628};
3905 5629
5630static struct snd_pcm_hw_constraint_list hw_constraints_period_sizes_new = {
5631 .count = ARRAY_SIZE(period_sizes_new),
5632 .list = period_sizes_new,
5633 .mask = 0
5634};
3906 5635
3907static int snd_hdspm_hw_rule_channels_rate(struct snd_pcm_hw_params *params, 5636static struct snd_pcm_hw_constraint_list hw_constraints_raydat_io_buffer = {
5637 .count = ARRAY_SIZE(raydat_aio_buffer_sizes),
5638 .list = raydat_aio_buffer_sizes,
5639 .mask = 0
5640};
5641
5642static int snd_hdspm_hw_rule_in_channels_rate(struct snd_pcm_hw_params *params,
5643 struct snd_pcm_hw_rule *rule)
5644{
5645 struct hdspm *hdspm = rule->private;
5646 struct snd_interval *c =
5647 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
5648 struct snd_interval *r =
5649 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
5650
5651 if (r->min > 96000 && r->max <= 192000) {
5652 struct snd_interval t = {
5653 .min = hdspm->qs_in_channels,
5654 .max = hdspm->qs_in_channels,
5655 .integer = 1,
5656 };
5657 return snd_interval_refine(c, &t);
5658 } else if (r->min > 48000 && r->max <= 96000) {
5659 struct snd_interval t = {
5660 .min = hdspm->ds_in_channels,
5661 .max = hdspm->ds_in_channels,
5662 .integer = 1,
5663 };
5664 return snd_interval_refine(c, &t);
5665 } else if (r->max < 64000) {
5666 struct snd_interval t = {
5667 .min = hdspm->ss_in_channels,
5668 .max = hdspm->ss_in_channels,
5669 .integer = 1,
5670 };
5671 return snd_interval_refine(c, &t);
5672 }
5673
5674 return 0;
5675}
5676
5677static int snd_hdspm_hw_rule_out_channels_rate(struct snd_pcm_hw_params *params,
3908 struct snd_pcm_hw_rule * rule) 5678 struct snd_pcm_hw_rule * rule)
3909{ 5679{
3910 struct hdspm *hdspm = rule->private; 5680 struct hdspm *hdspm = rule->private;
@@ -3913,25 +5683,33 @@ static int snd_hdspm_hw_rule_channels_rate(struct snd_pcm_hw_params *params,
3913 struct snd_interval *r = 5683 struct snd_interval *r =
3914 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); 5684 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
3915 5685
3916 if (r->min > 48000 && r->max <= 96000) { 5686 if (r->min > 96000 && r->max <= 192000) {
3917 struct snd_interval t = { 5687 struct snd_interval t = {
3918 .min = hdspm->ds_channels, 5688 .min = hdspm->qs_out_channels,
3919 .max = hdspm->ds_channels, 5689 .max = hdspm->qs_out_channels,
5690 .integer = 1,
5691 };
5692 return snd_interval_refine(c, &t);
5693 } else if (r->min > 48000 && r->max <= 96000) {
5694 struct snd_interval t = {
5695 .min = hdspm->ds_out_channels,
5696 .max = hdspm->ds_out_channels,
3920 .integer = 1, 5697 .integer = 1,
3921 }; 5698 };
3922 return snd_interval_refine(c, &t); 5699 return snd_interval_refine(c, &t);
3923 } else if (r->max < 64000) { 5700 } else if (r->max < 64000) {
3924 struct snd_interval t = { 5701 struct snd_interval t = {
3925 .min = hdspm->ss_channels, 5702 .min = hdspm->ss_out_channels,
3926 .max = hdspm->ss_channels, 5703 .max = hdspm->ss_out_channels,
3927 .integer = 1, 5704 .integer = 1,
3928 }; 5705 };
3929 return snd_interval_refine(c, &t); 5706 return snd_interval_refine(c, &t);
5707 } else {
3930 } 5708 }
3931 return 0; 5709 return 0;
3932} 5710}
3933 5711
3934static int snd_hdspm_hw_rule_rate_channels(struct snd_pcm_hw_params *params, 5712static int snd_hdspm_hw_rule_rate_in_channels(struct snd_pcm_hw_params *params,
3935 struct snd_pcm_hw_rule * rule) 5713 struct snd_pcm_hw_rule * rule)
3936{ 5714{
3937 struct hdspm *hdspm = rule->private; 5715 struct hdspm *hdspm = rule->private;
@@ -3940,42 +5718,92 @@ static int snd_hdspm_hw_rule_rate_channels(struct snd_pcm_hw_params *params,
3940 struct snd_interval *r = 5718 struct snd_interval *r =
3941 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); 5719 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
3942 5720
3943 if (c->min >= hdspm->ss_channels) { 5721 if (c->min >= hdspm->ss_in_channels) {
3944 struct snd_interval t = { 5722 struct snd_interval t = {
3945 .min = 32000, 5723 .min = 32000,
3946 .max = 48000, 5724 .max = 48000,
3947 .integer = 1, 5725 .integer = 1,
3948 }; 5726 };
3949 return snd_interval_refine(r, &t); 5727 return snd_interval_refine(r, &t);
3950 } else if (c->max <= hdspm->ds_channels) { 5728 } else if (c->max <= hdspm->qs_in_channels) {
5729 struct snd_interval t = {
5730 .min = 128000,
5731 .max = 192000,
5732 .integer = 1,
5733 };
5734 return snd_interval_refine(r, &t);
5735 } else if (c->max <= hdspm->ds_in_channels) {
3951 struct snd_interval t = { 5736 struct snd_interval t = {
3952 .min = 64000, 5737 .min = 64000,
3953 .max = 96000, 5738 .max = 96000,
3954 .integer = 1, 5739 .integer = 1,
3955 }; 5740 };
5741 return snd_interval_refine(r, &t);
5742 }
3956 5743
5744 return 0;
5745}
5746static int snd_hdspm_hw_rule_rate_out_channels(struct snd_pcm_hw_params *params,
5747 struct snd_pcm_hw_rule *rule)
5748{
5749 struct hdspm *hdspm = rule->private;
5750 struct snd_interval *c =
5751 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
5752 struct snd_interval *r =
5753 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
5754
5755 if (c->min >= hdspm->ss_out_channels) {
5756 struct snd_interval t = {
5757 .min = 32000,
5758 .max = 48000,
5759 .integer = 1,
5760 };
5761 return snd_interval_refine(r, &t);
5762 } else if (c->max <= hdspm->qs_out_channels) {
5763 struct snd_interval t = {
5764 .min = 128000,
5765 .max = 192000,
5766 .integer = 1,
5767 };
5768 return snd_interval_refine(r, &t);
5769 } else if (c->max <= hdspm->ds_out_channels) {
5770 struct snd_interval t = {
5771 .min = 64000,
5772 .max = 96000,
5773 .integer = 1,
5774 };
3957 return snd_interval_refine(r, &t); 5775 return snd_interval_refine(r, &t);
3958 } 5776 }
5777
3959 return 0; 5778 return 0;
3960} 5779}
3961 5780
3962static int snd_hdspm_hw_rule_channels(struct snd_pcm_hw_params *params, 5781static int snd_hdspm_hw_rule_in_channels(struct snd_pcm_hw_params *params,
3963 struct snd_pcm_hw_rule *rule) 5782 struct snd_pcm_hw_rule *rule)
3964{ 5783{
3965 unsigned int list[3]; 5784 unsigned int list[3];
3966 struct hdspm *hdspm = rule->private; 5785 struct hdspm *hdspm = rule->private;
3967 struct snd_interval *c = hw_param_interval(params, 5786 struct snd_interval *c = hw_param_interval(params,
3968 SNDRV_PCM_HW_PARAM_CHANNELS); 5787 SNDRV_PCM_HW_PARAM_CHANNELS);
3969 if (hdspm->is_aes32) { 5788
3970 list[0] = hdspm->qs_channels; 5789 list[0] = hdspm->qs_in_channels;
3971 list[1] = hdspm->ds_channels; 5790 list[1] = hdspm->ds_in_channels;
3972 list[2] = hdspm->ss_channels; 5791 list[2] = hdspm->ss_in_channels;
3973 return snd_interval_list(c, 3, list, 0); 5792 return snd_interval_list(c, 3, list, 0);
3974 } else { 5793}
3975 list[0] = hdspm->ds_channels; 5794
3976 list[1] = hdspm->ss_channels; 5795static int snd_hdspm_hw_rule_out_channels(struct snd_pcm_hw_params *params,
3977 return snd_interval_list(c, 2, list, 0); 5796 struct snd_pcm_hw_rule *rule)
3978 } 5797{
5798 unsigned int list[3];
5799 struct hdspm *hdspm = rule->private;
5800 struct snd_interval *c = hw_param_interval(params,
5801 SNDRV_PCM_HW_PARAM_CHANNELS);
5802
5803 list[0] = hdspm->qs_out_channels;
5804 list[1] = hdspm->ds_out_channels;
5805 list[2] = hdspm->ss_out_channels;
5806 return snd_interval_list(c, 3, list, 0);
3979} 5807}
3980 5808
3981 5809
@@ -3999,6 +5827,7 @@ static int snd_hdspm_playback_open(struct snd_pcm_substream *substream)
3999 5827
4000 snd_pcm_set_sync(substream); 5828 snd_pcm_set_sync(substream);
4001 5829
5830
4002 runtime->hw = snd_hdspm_playback_subinfo; 5831 runtime->hw = snd_hdspm_playback_subinfo;
4003 5832
4004 if (hdspm->capture_substream == NULL) 5833 if (hdspm->capture_substream == NULL)
@@ -4011,25 +5840,41 @@ static int snd_hdspm_playback_open(struct snd_pcm_substream *substream)
4011 5840
4012 snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); 5841 snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
4013 5842
4014 snd_pcm_hw_constraint_list(runtime, 0, 5843 switch (hdspm->io_type) {
4015 SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 5844 case AIO:
4016 &hw_constraints_period_sizes); 5845 case RayDAT:
5846 snd_pcm_hw_constraint_list(runtime, 0,
5847 SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
5848 &hw_constraints_period_sizes_new);
5849 snd_pcm_hw_constraint_list(runtime, 0,
5850 SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
5851 &hw_constraints_raydat_io_buffer);
4017 5852
4018 if (hdspm->is_aes32) { 5853 break;
5854
5855 default:
5856 snd_pcm_hw_constraint_list(runtime, 0,
5857 SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
5858 &hw_constraints_period_sizes_old);
5859 }
5860
5861 if (AES32 == hdspm->io_type) {
4019 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 5862 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
4020 &hdspm_hw_constraints_aes32_sample_rates); 5863 &hdspm_hw_constraints_aes32_sample_rates);
4021 } else { 5864 } else {
4022 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
4023 snd_hdspm_hw_rule_channels, hdspm,
4024 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
4025 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
4026 snd_hdspm_hw_rule_channels_rate, hdspm,
4027 SNDRV_PCM_HW_PARAM_RATE, -1);
4028
4029 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 5865 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
4030 snd_hdspm_hw_rule_rate_channels, hdspm, 5866 snd_hdspm_hw_rule_rate_out_channels, hdspm,
4031 SNDRV_PCM_HW_PARAM_CHANNELS, -1); 5867 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
4032 } 5868 }
5869
5870 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
5871 snd_hdspm_hw_rule_out_channels, hdspm,
5872 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
5873
5874 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
5875 snd_hdspm_hw_rule_out_channels_rate, hdspm,
5876 SNDRV_PCM_HW_PARAM_RATE, -1);
5877
4033 return 0; 5878 return 0;
4034} 5879}
4035 5880
@@ -4066,24 +5911,40 @@ static int snd_hdspm_capture_open(struct snd_pcm_substream *substream)
4066 spin_unlock_irq(&hdspm->lock); 5911 spin_unlock_irq(&hdspm->lock);
4067 5912
4068 snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); 5913 snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
4069 snd_pcm_hw_constraint_list(runtime, 0, 5914 switch (hdspm->io_type) {
4070 SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 5915 case AIO:
4071 &hw_constraints_period_sizes); 5916 case RayDAT:
4072 if (hdspm->is_aes32) { 5917 snd_pcm_hw_constraint_list(runtime, 0,
5918 SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
5919 &hw_constraints_period_sizes_new);
5920 snd_pcm_hw_constraint_list(runtime, 0,
5921 SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
5922 &hw_constraints_raydat_io_buffer);
5923 break;
5924
5925 default:
5926 snd_pcm_hw_constraint_list(runtime, 0,
5927 SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
5928 &hw_constraints_period_sizes_old);
5929 }
5930
5931 if (AES32 == hdspm->io_type) {
4073 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 5932 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
4074 &hdspm_hw_constraints_aes32_sample_rates); 5933 &hdspm_hw_constraints_aes32_sample_rates);
4075 } else { 5934 } else {
4076 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
4077 snd_hdspm_hw_rule_channels, hdspm,
4078 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
4079 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
4080 snd_hdspm_hw_rule_channels_rate, hdspm,
4081 SNDRV_PCM_HW_PARAM_RATE, -1);
4082
4083 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 5935 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
4084 snd_hdspm_hw_rule_rate_channels, hdspm, 5936 snd_hdspm_hw_rule_rate_in_channels, hdspm,
4085 SNDRV_PCM_HW_PARAM_CHANNELS, -1); 5937 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
4086 } 5938 }
5939
5940 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
5941 snd_hdspm_hw_rule_in_channels, hdspm,
5942 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
5943
5944 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
5945 snd_hdspm_hw_rule_in_channels_rate, hdspm,
5946 SNDRV_PCM_HW_PARAM_RATE, -1);
5947
4087 return 0; 5948 return 0;
4088} 5949}
4089 5950
@@ -4100,32 +5961,129 @@ static int snd_hdspm_capture_release(struct snd_pcm_substream *substream)
4100 return 0; 5961 return 0;
4101} 5962}
4102 5963
4103static int snd_hdspm_hwdep_ioctl(struct snd_hwdep * hw, struct file *file, 5964static int snd_hdspm_hwdep_dummy_op(struct snd_hwdep *hw, struct file *file)
4104 unsigned int cmd, unsigned long arg)
4105{ 5965{
5966 /* we have nothing to initialize but the call is required */
5967 return 0;
5968}
5969
5970static inline int copy_u32_le(void __user *dest, void __iomem *src)
5971{
5972 u32 val = readl(src);
5973 return copy_to_user(dest, &val, 4);
5974}
5975
5976static int snd_hdspm_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
5977 unsigned int cmd, unsigned long __user arg)
5978{
5979 void __user *argp = (void __user *)arg;
4106 struct hdspm *hdspm = hw->private_data; 5980 struct hdspm *hdspm = hw->private_data;
4107 struct hdspm_mixer_ioctl mixer; 5981 struct hdspm_mixer_ioctl mixer;
4108 struct hdspm_config_info info; 5982 struct hdspm_config info;
5983 struct hdspm_status status;
4109 struct hdspm_version hdspm_version; 5984 struct hdspm_version hdspm_version;
4110 struct hdspm_peak_rms_ioctl rms; 5985 struct hdspm_peak_rms *levels;
5986 struct hdspm_ltc ltc;
5987 unsigned int statusregister;
5988 long unsigned int s;
5989 int i = 0;
4111 5990
4112 switch (cmd) { 5991 switch (cmd) {
4113 5992
4114 case SNDRV_HDSPM_IOCTL_GET_PEAK_RMS: 5993 case SNDRV_HDSPM_IOCTL_GET_PEAK_RMS:
4115 if (copy_from_user(&rms, (void __user *)arg, sizeof(rms))) 5994 levels = &hdspm->peak_rms;
5995 for (i = 0; i < HDSPM_MAX_CHANNELS; i++) {
5996 levels->input_peaks[i] =
5997 readl(hdspm->iobase +
5998 HDSPM_MADI_INPUT_PEAK + i*4);
5999 levels->playback_peaks[i] =
6000 readl(hdspm->iobase +
6001 HDSPM_MADI_PLAYBACK_PEAK + i*4);
6002 levels->output_peaks[i] =
6003 readl(hdspm->iobase +
6004 HDSPM_MADI_OUTPUT_PEAK + i*4);
6005
6006 levels->input_rms[i] =
6007 ((uint64_t) readl(hdspm->iobase +
6008 HDSPM_MADI_INPUT_RMS_H + i*4) << 32) |
6009 (uint64_t) readl(hdspm->iobase +
6010 HDSPM_MADI_INPUT_RMS_L + i*4);
6011 levels->playback_rms[i] =
6012 ((uint64_t)readl(hdspm->iobase +
6013 HDSPM_MADI_PLAYBACK_RMS_H+i*4) << 32) |
6014 (uint64_t)readl(hdspm->iobase +
6015 HDSPM_MADI_PLAYBACK_RMS_L + i*4);
6016 levels->output_rms[i] =
6017 ((uint64_t)readl(hdspm->iobase +
6018 HDSPM_MADI_OUTPUT_RMS_H + i*4) << 32) |
6019 (uint64_t)readl(hdspm->iobase +
6020 HDSPM_MADI_OUTPUT_RMS_L + i*4);
6021 }
6022
6023 if (hdspm->system_sample_rate > 96000) {
6024 levels->speed = qs;
6025 } else if (hdspm->system_sample_rate > 48000) {
6026 levels->speed = ds;
6027 } else {
6028 levels->speed = ss;
6029 }
6030 levels->status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
6031
6032 s = copy_to_user(argp, levels, sizeof(struct hdspm_peak_rms));
6033 if (0 != s) {
6034 /* snd_printk(KERN_ERR "copy_to_user(.., .., %lu): %lu
6035 [Levels]\n", sizeof(struct hdspm_peak_rms), s);
6036 */
4116 return -EFAULT; 6037 return -EFAULT;
4117 /* maybe there is a chance to memorymap in future 6038 }
4118 * so dont touch just copy 6039 break;
4119 */ 6040
4120 if(copy_to_user_fromio((void __user *)rms.peak, 6041 case SNDRV_HDSPM_IOCTL_GET_LTC:
4121 hdspm->iobase+HDSPM_MADI_peakrmsbase, 6042 ltc.ltc = hdspm_read(hdspm, HDSPM_RD_TCO);
4122 sizeof(struct hdspm_peak_rms)) != 0 ) 6043 i = hdspm_read(hdspm, HDSPM_RD_TCO + 4);
6044 if (i & HDSPM_TCO1_LTC_Input_valid) {
6045 switch (i & (HDSPM_TCO1_LTC_Format_LSB |
6046 HDSPM_TCO1_LTC_Format_MSB)) {
6047 case 0:
6048 ltc.format = fps_24;
6049 break;
6050 case HDSPM_TCO1_LTC_Format_LSB:
6051 ltc.format = fps_25;
6052 break;
6053 case HDSPM_TCO1_LTC_Format_MSB:
6054 ltc.format = fps_2997;
6055 break;
6056 default:
6057 ltc.format = 30;
6058 break;
6059 }
6060 if (i & HDSPM_TCO1_set_drop_frame_flag) {
6061 ltc.frame = drop_frame;
6062 } else {
6063 ltc.frame = full_frame;
6064 }
6065 } else {
6066 ltc.format = format_invalid;
6067 ltc.frame = frame_invalid;
6068 }
6069 if (i & HDSPM_TCO1_Video_Input_Format_NTSC) {
6070 ltc.input_format = ntsc;
6071 } else if (i & HDSPM_TCO1_Video_Input_Format_PAL) {
6072 ltc.input_format = pal;
6073 } else {
6074 ltc.input_format = no_video;
6075 }
6076
6077 s = copy_to_user(argp, &ltc, sizeof(struct hdspm_ltc));
6078 if (0 != s) {
6079 /*
6080 snd_printk(KERN_ERR "copy_to_user(.., .., %lu): %lu [LTC]\n", sizeof(struct hdspm_ltc), s); */
4123 return -EFAULT; 6081 return -EFAULT;
6082 }
4124 6083
4125 break; 6084 break;
4126
4127 6085
4128 case SNDRV_HDSPM_IOCTL_GET_CONFIG_INFO: 6086 case SNDRV_HDSPM_IOCTL_GET_CONFIG:
4129 6087
4130 memset(&info, 0, sizeof(info)); 6088 memset(&info, 0, sizeof(info));
4131 spin_lock_irq(&hdspm->lock); 6089 spin_lock_irq(&hdspm->lock);
@@ -4134,7 +6092,7 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep * hw, struct file *file,
4134 6092
4135 info.system_sample_rate = hdspm->system_sample_rate; 6093 info.system_sample_rate = hdspm->system_sample_rate;
4136 info.autosync_sample_rate = 6094 info.autosync_sample_rate =
4137 hdspm_external_sample_rate(hdspm); 6095 hdspm_external_sample_rate(hdspm);
4138 info.system_clock_mode = hdspm_system_clock_mode(hdspm); 6096 info.system_clock_mode = hdspm_system_clock_mode(hdspm);
4139 info.clock_source = hdspm_clock_source(hdspm); 6097 info.clock_source = hdspm_clock_source(hdspm);
4140 info.autosync_ref = hdspm_autosync_ref(hdspm); 6098 info.autosync_ref = hdspm_autosync_ref(hdspm);
@@ -4145,10 +6103,58 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep * hw, struct file *file,
4145 return -EFAULT; 6103 return -EFAULT;
4146 break; 6104 break;
4147 6105
6106 case SNDRV_HDSPM_IOCTL_GET_STATUS:
6107 status.card_type = hdspm->io_type;
6108
6109 status.autosync_source = hdspm_autosync_ref(hdspm);
6110
6111 status.card_clock = 110069313433624ULL;
6112 status.master_period = hdspm_read(hdspm, HDSPM_RD_PLL_FREQ);
6113
6114 switch (hdspm->io_type) {
6115 case MADI:
6116 case MADIface:
6117 status.card_specific.madi.sync_wc =
6118 hdspm_wc_sync_check(hdspm);
6119 status.card_specific.madi.sync_madi =
6120 hdspm_madi_sync_check(hdspm);
6121 status.card_specific.madi.sync_tco =
6122 hdspm_tco_sync_check(hdspm);
6123 status.card_specific.madi.sync_in =
6124 hdspm_sync_in_sync_check(hdspm);
6125
6126 statusregister =
6127 hdspm_read(hdspm, HDSPM_statusRegister);
6128 status.card_specific.madi.madi_input =
6129 (statusregister & HDSPM_AB_int) ? 1 : 0;
6130 status.card_specific.madi.channel_format =
6131 (statusregister & HDSPM_TX_64ch) ? 1 : 0;
6132 /* TODO: Mac driver sets it when f_s>48kHz */
6133 status.card_specific.madi.frame_format = 0;
6134
6135 default:
6136 break;
6137 }
6138
6139 if (copy_to_user((void __user *) arg, &status, sizeof(status)))
6140 return -EFAULT;
6141
6142
6143 break;
6144
4148 case SNDRV_HDSPM_IOCTL_GET_VERSION: 6145 case SNDRV_HDSPM_IOCTL_GET_VERSION:
6146 hdspm_version.card_type = hdspm->io_type;
6147 strncpy(hdspm_version.cardname, hdspm->card_name,
6148 sizeof(hdspm_version.cardname));
6149 hdspm_version.serial = (hdspm_read(hdspm,
6150 HDSPM_midiStatusIn0)>>8) & 0xFFFFFF;
4149 hdspm_version.firmware_rev = hdspm->firmware_rev; 6151 hdspm_version.firmware_rev = hdspm->firmware_rev;
6152 hdspm_version.addons = 0;
6153 if (hdspm->tco)
6154 hdspm_version.addons |= HDSPM_ADDON_TCO;
6155
4150 if (copy_to_user((void __user *) arg, &hdspm_version, 6156 if (copy_to_user((void __user *) arg, &hdspm_version,
4151 sizeof(hdspm_version))) 6157 sizeof(hdspm_version)))
4152 return -EFAULT; 6158 return -EFAULT;
4153 break; 6159 break;
4154 6160
@@ -4156,7 +6162,7 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep * hw, struct file *file,
4156 if (copy_from_user(&mixer, (void __user *)arg, sizeof(mixer))) 6162 if (copy_from_user(&mixer, (void __user *)arg, sizeof(mixer)))
4157 return -EFAULT; 6163 return -EFAULT;
4158 if (copy_to_user((void __user *)mixer.mixer, hdspm->mixer, 6164 if (copy_to_user((void __user *)mixer.mixer, hdspm->mixer,
4159 sizeof(struct hdspm_mixer))) 6165 sizeof(struct hdspm_mixer)))
4160 return -EFAULT; 6166 return -EFAULT;
4161 break; 6167 break;
4162 6168
@@ -4175,8 +6181,6 @@ static struct snd_pcm_ops snd_hdspm_playback_ops = {
4175 .prepare = snd_hdspm_prepare, 6181 .prepare = snd_hdspm_prepare,
4176 .trigger = snd_hdspm_trigger, 6182 .trigger = snd_hdspm_trigger,
4177 .pointer = snd_hdspm_hw_pointer, 6183 .pointer = snd_hdspm_hw_pointer,
4178 .copy = snd_hdspm_playback_copy,
4179 .silence = snd_hdspm_hw_silence,
4180 .page = snd_pcm_sgbuf_ops_page, 6184 .page = snd_pcm_sgbuf_ops_page,
4181}; 6185};
4182 6186
@@ -4189,7 +6193,6 @@ static struct snd_pcm_ops snd_hdspm_capture_ops = {
4189 .prepare = snd_hdspm_prepare, 6193 .prepare = snd_hdspm_prepare,
4190 .trigger = snd_hdspm_trigger, 6194 .trigger = snd_hdspm_trigger,
4191 .pointer = snd_hdspm_hw_pointer, 6195 .pointer = snd_hdspm_hw_pointer,
4192 .copy = snd_hdspm_capture_copy,
4193 .page = snd_pcm_sgbuf_ops_page, 6196 .page = snd_pcm_sgbuf_ops_page,
4194}; 6197};
4195 6198
@@ -4207,16 +6210,18 @@ static int __devinit snd_hdspm_create_hwdep(struct snd_card *card,
4207 hw->private_data = hdspm; 6210 hw->private_data = hdspm;
4208 strcpy(hw->name, "HDSPM hwdep interface"); 6211 strcpy(hw->name, "HDSPM hwdep interface");
4209 6212
6213 hw->ops.open = snd_hdspm_hwdep_dummy_op;
4210 hw->ops.ioctl = snd_hdspm_hwdep_ioctl; 6214 hw->ops.ioctl = snd_hdspm_hwdep_ioctl;
6215 hw->ops.release = snd_hdspm_hwdep_dummy_op;
4211 6216
4212 return 0; 6217 return 0;
4213} 6218}
4214 6219
4215 6220
4216/*------------------------------------------------------------ 6221/*------------------------------------------------------------
4217 memory interface 6222 memory interface
4218 ------------------------------------------------------------*/ 6223 ------------------------------------------------------------*/
4219static int __devinit snd_hdspm_preallocate_memory(struct hdspm * hdspm) 6224static int __devinit snd_hdspm_preallocate_memory(struct hdspm *hdspm)
4220{ 6225{
4221 int err; 6226 int err;
4222 struct snd_pcm *pcm; 6227 struct snd_pcm *pcm;
@@ -4228,7 +6233,7 @@ static int __devinit snd_hdspm_preallocate_memory(struct hdspm * hdspm)
4228 6233
4229 err = 6234 err =
4230 snd_pcm_lib_preallocate_pages_for_all(pcm, 6235 snd_pcm_lib_preallocate_pages_for_all(pcm,
4231 SNDRV_DMA_TYPE_DEV_SG, 6236 SNDRV_DMA_TYPE_DEV_SG,
4232 snd_dma_pci_data(hdspm->pci), 6237 snd_dma_pci_data(hdspm->pci),
4233 wanted, 6238 wanted,
4234 wanted); 6239 wanted);
@@ -4242,19 +6247,23 @@ static int __devinit snd_hdspm_preallocate_memory(struct hdspm * hdspm)
4242 return 0; 6247 return 0;
4243} 6248}
4244 6249
4245static void hdspm_set_sgbuf(struct hdspm * hdspm, 6250
6251static void hdspm_set_sgbuf(struct hdspm *hdspm,
4246 struct snd_pcm_substream *substream, 6252 struct snd_pcm_substream *substream,
4247 unsigned int reg, int channels) 6253 unsigned int reg, int channels)
4248{ 6254{
4249 int i; 6255 int i;
6256
6257 /* continuous memory segment */
4250 for (i = 0; i < (channels * 16); i++) 6258 for (i = 0; i < (channels * 16); i++)
4251 hdspm_write(hdspm, reg + 4 * i, 6259 hdspm_write(hdspm, reg + 4 * i,
4252 snd_pcm_sgbuf_get_addr(substream, 4096 * i)); 6260 snd_pcm_sgbuf_get_addr(substream, 4096 * i));
4253} 6261}
4254 6262
6263
4255/* ------------- ALSA Devices ---------------------------- */ 6264/* ------------- ALSA Devices ---------------------------- */
4256static int __devinit snd_hdspm_create_pcm(struct snd_card *card, 6265static int __devinit snd_hdspm_create_pcm(struct snd_card *card,
4257 struct hdspm * hdspm) 6266 struct hdspm *hdspm)
4258{ 6267{
4259 struct snd_pcm *pcm; 6268 struct snd_pcm *pcm;
4260 int err; 6269 int err;
@@ -4283,27 +6292,30 @@ static int __devinit snd_hdspm_create_pcm(struct snd_card *card,
4283 6292
4284static inline void snd_hdspm_initialize_midi_flush(struct hdspm * hdspm) 6293static inline void snd_hdspm_initialize_midi_flush(struct hdspm * hdspm)
4285{ 6294{
4286 snd_hdspm_flush_midi_input(hdspm, 0); 6295 int i;
4287 snd_hdspm_flush_midi_input(hdspm, 1); 6296
6297 for (i = 0; i < hdspm->midiPorts; i++)
6298 snd_hdspm_flush_midi_input(hdspm, i);
4288} 6299}
4289 6300
4290static int __devinit snd_hdspm_create_alsa_devices(struct snd_card *card, 6301static int __devinit snd_hdspm_create_alsa_devices(struct snd_card *card,
4291 struct hdspm * hdspm) 6302 struct hdspm * hdspm)
4292{ 6303{
4293 int err; 6304 int err, i;
4294 6305
4295 snd_printdd("Create card...\n"); 6306 snd_printdd("Create card...\n");
4296 err = snd_hdspm_create_pcm(card, hdspm); 6307 err = snd_hdspm_create_pcm(card, hdspm);
4297 if (err < 0) 6308 if (err < 0)
4298 return err; 6309 return err;
4299 6310
4300 err = snd_hdspm_create_midi(card, hdspm, 0); 6311 i = 0;
4301 if (err < 0) 6312 while (i < hdspm->midiPorts) {
4302 return err; 6313 err = snd_hdspm_create_midi(card, hdspm, i);
4303 6314 if (err < 0) {
4304 err = snd_hdspm_create_midi(card, hdspm, 1); 6315 return err;
4305 if (err < 0) 6316 }
4306 return err; 6317 i++;
6318 }
4307 6319
4308 err = snd_hdspm_create_controls(card, hdspm); 6320 err = snd_hdspm_create_controls(card, hdspm);
4309 if (err < 0) 6321 if (err < 0)
@@ -4346,37 +6358,55 @@ static int __devinit snd_hdspm_create_alsa_devices(struct snd_card *card,
4346} 6358}
4347 6359
4348static int __devinit snd_hdspm_create(struct snd_card *card, 6360static int __devinit snd_hdspm_create(struct snd_card *card,
4349 struct hdspm *hdspm, 6361 struct hdspm *hdspm) {
4350 int precise_ptr, int enable_monitor) 6362
4351{
4352 struct pci_dev *pci = hdspm->pci; 6363 struct pci_dev *pci = hdspm->pci;
4353 int err; 6364 int err;
4354 unsigned long io_extent; 6365 unsigned long io_extent;
4355 6366
4356 hdspm->irq = -1; 6367 hdspm->irq = -1;
4357
4358 spin_lock_init(&hdspm->midi[0].lock);
4359 spin_lock_init(&hdspm->midi[1].lock);
4360
4361 hdspm->card = card; 6368 hdspm->card = card;
4362 6369
4363 spin_lock_init(&hdspm->lock); 6370 spin_lock_init(&hdspm->lock);
4364 6371
4365 tasklet_init(&hdspm->midi_tasklet,
4366 hdspm_midi_tasklet, (unsigned long) hdspm);
4367
4368 pci_read_config_word(hdspm->pci, 6372 pci_read_config_word(hdspm->pci,
4369 PCI_CLASS_REVISION, &hdspm->firmware_rev); 6373 PCI_CLASS_REVISION, &hdspm->firmware_rev);
4370
4371 hdspm->is_aes32 = (hdspm->firmware_rev >= HDSPM_AESREVISION);
4372 6374
4373 strcpy(card->mixername, "Xilinx FPGA"); 6375 strcpy(card->mixername, "Xilinx FPGA");
4374 if (hdspm->is_aes32) { 6376 strcpy(card->driver, "HDSPM");
4375 strcpy(card->driver, "HDSPAES32"); 6377
4376 hdspm->card_name = "RME HDSPM AES32"; 6378 switch (hdspm->firmware_rev) {
4377 } else { 6379 case HDSPM_MADI_REV:
4378 strcpy(card->driver, "HDSPM"); 6380 hdspm->io_type = MADI;
4379 hdspm->card_name = "RME HDSPM MADI"; 6381 hdspm->card_name = "RME MADI";
6382 hdspm->midiPorts = 3;
6383 break;
6384 case HDSPM_RAYDAT_REV:
6385 hdspm->io_type = RayDAT;
6386 hdspm->card_name = "RME RayDAT";
6387 hdspm->midiPorts = 2;
6388 break;
6389 case HDSPM_AIO_REV:
6390 hdspm->io_type = AIO;
6391 hdspm->card_name = "RME AIO";
6392 hdspm->midiPorts = 1;
6393 break;
6394 case HDSPM_MADIFACE_REV:
6395 hdspm->io_type = MADIface;
6396 hdspm->card_name = "RME MADIface";
6397 hdspm->midiPorts = 1;
6398 break;
6399 case HDSPM_AES_REV:
6400 case HDSPM_AES32_REV:
6401 case HDSPM_AES32_OLD_REV:
6402 hdspm->io_type = AES32;
6403 hdspm->card_name = "RME AES32";
6404 hdspm->midiPorts = 2;
6405 break;
6406 default:
6407 snd_printk(KERN_ERR "HDSPM: unknown firmware revision %x\n",
6408 hdspm->firmware_rev);
6409 return -ENODEV;
4380 } 6410 }
4381 6411
4382 err = pci_enable_device(pci); 6412 err = pci_enable_device(pci);
@@ -4393,22 +6423,21 @@ static int __devinit snd_hdspm_create(struct snd_card *card,
4393 io_extent = pci_resource_len(pci, 0); 6423 io_extent = pci_resource_len(pci, 0);
4394 6424
4395 snd_printdd("grabbed memory region 0x%lx-0x%lx\n", 6425 snd_printdd("grabbed memory region 0x%lx-0x%lx\n",
4396 hdspm->port, hdspm->port + io_extent - 1); 6426 hdspm->port, hdspm->port + io_extent - 1);
4397
4398 6427
4399 hdspm->iobase = ioremap_nocache(hdspm->port, io_extent); 6428 hdspm->iobase = ioremap_nocache(hdspm->port, io_extent);
4400 if (!hdspm->iobase) { 6429 if (!hdspm->iobase) {
4401 snd_printk(KERN_ERR "HDSPM: " 6430 snd_printk(KERN_ERR "HDSPM: "
4402 "unable to remap region 0x%lx-0x%lx\n", 6431 "unable to remap region 0x%lx-0x%lx\n",
4403 hdspm->port, hdspm->port + io_extent - 1); 6432 hdspm->port, hdspm->port + io_extent - 1);
4404 return -EBUSY; 6433 return -EBUSY;
4405 } 6434 }
4406 snd_printdd("remapped region (0x%lx) 0x%lx-0x%lx\n", 6435 snd_printdd("remapped region (0x%lx) 0x%lx-0x%lx\n",
4407 (unsigned long)hdspm->iobase, hdspm->port, 6436 (unsigned long)hdspm->iobase, hdspm->port,
4408 hdspm->port + io_extent - 1); 6437 hdspm->port + io_extent - 1);
4409 6438
4410 if (request_irq(pci->irq, snd_hdspm_interrupt, 6439 if (request_irq(pci->irq, snd_hdspm_interrupt,
4411 IRQF_SHARED, "hdspm", hdspm)) { 6440 IRQF_SHARED, "hdspm", hdspm)) {
4412 snd_printk(KERN_ERR "HDSPM: unable to use IRQ %d\n", pci->irq); 6441 snd_printk(KERN_ERR "HDSPM: unable to use IRQ %d\n", pci->irq);
4413 return -EBUSY; 6442 return -EBUSY;
4414 } 6443 }
@@ -4416,23 +6445,219 @@ static int __devinit snd_hdspm_create(struct snd_card *card,
4416 snd_printdd("use IRQ %d\n", pci->irq); 6445 snd_printdd("use IRQ %d\n", pci->irq);
4417 6446
4418 hdspm->irq = pci->irq; 6447 hdspm->irq = pci->irq;
4419 hdspm->precise_ptr = precise_ptr;
4420
4421 hdspm->monitor_outs = enable_monitor;
4422 6448
4423 snd_printdd("kmalloc Mixer memory of %zd Bytes\n", 6449 snd_printdd("kmalloc Mixer memory of %zd Bytes\n",
4424 sizeof(struct hdspm_mixer)); 6450 sizeof(struct hdspm_mixer));
4425 hdspm->mixer = kzalloc(sizeof(struct hdspm_mixer), GFP_KERNEL); 6451 hdspm->mixer = kzalloc(sizeof(struct hdspm_mixer), GFP_KERNEL);
4426 if (!hdspm->mixer) { 6452 if (!hdspm->mixer) {
4427 snd_printk(KERN_ERR "HDSPM: " 6453 snd_printk(KERN_ERR "HDSPM: "
4428 "unable to kmalloc Mixer memory of %d Bytes\n", 6454 "unable to kmalloc Mixer memory of %d Bytes\n",
4429 (int)sizeof(struct hdspm_mixer)); 6455 (int)sizeof(struct hdspm_mixer));
4430 return err; 6456 return err;
4431 } 6457 }
4432 6458
4433 hdspm->ss_channels = MADI_SS_CHANNELS; 6459 hdspm->port_names_in = NULL;
4434 hdspm->ds_channels = MADI_DS_CHANNELS; 6460 hdspm->port_names_out = NULL;
4435 hdspm->qs_channels = MADI_QS_CHANNELS; 6461
6462 switch (hdspm->io_type) {
6463 case AES32:
6464 hdspm->ss_in_channels = hdspm->ss_out_channels = AES32_CHANNELS;
6465 hdspm->ds_in_channels = hdspm->ds_out_channels = AES32_CHANNELS;
6466 hdspm->qs_in_channels = hdspm->qs_out_channels = AES32_CHANNELS;
6467
6468 hdspm->channel_map_in_ss = hdspm->channel_map_out_ss =
6469 channel_map_aes32;
6470 hdspm->channel_map_in_ds = hdspm->channel_map_out_ds =
6471 channel_map_aes32;
6472 hdspm->channel_map_in_qs = hdspm->channel_map_out_qs =
6473 channel_map_aes32;
6474 hdspm->port_names_in_ss = hdspm->port_names_out_ss =
6475 texts_ports_aes32;
6476 hdspm->port_names_in_ds = hdspm->port_names_out_ds =
6477 texts_ports_aes32;
6478 hdspm->port_names_in_qs = hdspm->port_names_out_qs =
6479 texts_ports_aes32;
6480
6481 hdspm->max_channels_out = hdspm->max_channels_in =
6482 AES32_CHANNELS;
6483 hdspm->port_names_in = hdspm->port_names_out =
6484 texts_ports_aes32;
6485 hdspm->channel_map_in = hdspm->channel_map_out =
6486 channel_map_aes32;
6487
6488 break;
6489
6490 case MADI:
6491 case MADIface:
6492 hdspm->ss_in_channels = hdspm->ss_out_channels =
6493 MADI_SS_CHANNELS;
6494 hdspm->ds_in_channels = hdspm->ds_out_channels =
6495 MADI_DS_CHANNELS;
6496 hdspm->qs_in_channels = hdspm->qs_out_channels =
6497 MADI_QS_CHANNELS;
6498
6499 hdspm->channel_map_in_ss = hdspm->channel_map_out_ss =
6500 channel_map_unity_ss;
6501 hdspm->channel_map_in_ds = hdspm->channel_map_out_ds =
6502 channel_map_unity_ss;
6503 hdspm->channel_map_in_qs = hdspm->channel_map_out_qs =
6504 channel_map_unity_ss;
6505
6506 hdspm->port_names_in_ss = hdspm->port_names_out_ss =
6507 texts_ports_madi;
6508 hdspm->port_names_in_ds = hdspm->port_names_out_ds =
6509 texts_ports_madi;
6510 hdspm->port_names_in_qs = hdspm->port_names_out_qs =
6511 texts_ports_madi;
6512 break;
6513
6514 case AIO:
6515 if (0 == (hdspm_read(hdspm, HDSPM_statusRegister2) & HDSPM_s2_AEBI_D)) {
6516 snd_printk(KERN_INFO "HDSPM: AEB input board found, but not supported\n");
6517 }
6518
6519 hdspm->ss_in_channels = AIO_IN_SS_CHANNELS;
6520 hdspm->ds_in_channels = AIO_IN_DS_CHANNELS;
6521 hdspm->qs_in_channels = AIO_IN_QS_CHANNELS;
6522 hdspm->ss_out_channels = AIO_OUT_SS_CHANNELS;
6523 hdspm->ds_out_channels = AIO_OUT_DS_CHANNELS;
6524 hdspm->qs_out_channels = AIO_OUT_QS_CHANNELS;
6525
6526 hdspm->channel_map_out_ss = channel_map_aio_out_ss;
6527 hdspm->channel_map_out_ds = channel_map_aio_out_ds;
6528 hdspm->channel_map_out_qs = channel_map_aio_out_qs;
6529
6530 hdspm->channel_map_in_ss = channel_map_aio_in_ss;
6531 hdspm->channel_map_in_ds = channel_map_aio_in_ds;
6532 hdspm->channel_map_in_qs = channel_map_aio_in_qs;
6533
6534 hdspm->port_names_in_ss = texts_ports_aio_in_ss;
6535 hdspm->port_names_out_ss = texts_ports_aio_out_ss;
6536 hdspm->port_names_in_ds = texts_ports_aio_in_ds;
6537 hdspm->port_names_out_ds = texts_ports_aio_out_ds;
6538 hdspm->port_names_in_qs = texts_ports_aio_in_qs;
6539 hdspm->port_names_out_qs = texts_ports_aio_out_qs;
6540
6541 break;
6542
6543 case RayDAT:
6544 hdspm->ss_in_channels = hdspm->ss_out_channels =
6545 RAYDAT_SS_CHANNELS;
6546 hdspm->ds_in_channels = hdspm->ds_out_channels =
6547 RAYDAT_DS_CHANNELS;
6548 hdspm->qs_in_channels = hdspm->qs_out_channels =
6549 RAYDAT_QS_CHANNELS;
6550
6551 hdspm->max_channels_in = RAYDAT_SS_CHANNELS;
6552 hdspm->max_channels_out = RAYDAT_SS_CHANNELS;
6553
6554 hdspm->channel_map_in_ss = hdspm->channel_map_out_ss =
6555 channel_map_raydat_ss;
6556 hdspm->channel_map_in_ds = hdspm->channel_map_out_ds =
6557 channel_map_raydat_ds;
6558 hdspm->channel_map_in_qs = hdspm->channel_map_out_qs =
6559 channel_map_raydat_qs;
6560 hdspm->channel_map_in = hdspm->channel_map_out =
6561 channel_map_raydat_ss;
6562
6563 hdspm->port_names_in_ss = hdspm->port_names_out_ss =
6564 texts_ports_raydat_ss;
6565 hdspm->port_names_in_ds = hdspm->port_names_out_ds =
6566 texts_ports_raydat_ds;
6567 hdspm->port_names_in_qs = hdspm->port_names_out_qs =
6568 texts_ports_raydat_qs;
6569
6570
6571 break;
6572
6573 }
6574
6575 /* TCO detection */
6576 switch (hdspm->io_type) {
6577 case AIO:
6578 case RayDAT:
6579 if (hdspm_read(hdspm, HDSPM_statusRegister2) &
6580 HDSPM_s2_tco_detect) {
6581 hdspm->midiPorts++;
6582 hdspm->tco = kzalloc(sizeof(struct hdspm_tco),
6583 GFP_KERNEL);
6584 if (NULL != hdspm->tco) {
6585 hdspm_tco_write(hdspm);
6586 }
6587 snd_printk(KERN_INFO "HDSPM: AIO/RayDAT TCO module found\n");
6588 } else {
6589 hdspm->tco = NULL;
6590 }
6591 break;
6592
6593 case MADI:
6594 if (hdspm_read(hdspm, HDSPM_statusRegister) & HDSPM_tco_detect) {
6595 hdspm->midiPorts++;
6596 hdspm->tco = kzalloc(sizeof(struct hdspm_tco),
6597 GFP_KERNEL);
6598 if (NULL != hdspm->tco) {
6599 hdspm_tco_write(hdspm);
6600 }
6601 snd_printk(KERN_INFO "HDSPM: MADI TCO module found\n");
6602 } else {
6603 hdspm->tco = NULL;
6604 }
6605 break;
6606
6607 default:
6608 hdspm->tco = NULL;
6609 }
6610
6611 /* texts */
6612 switch (hdspm->io_type) {
6613 case AES32:
6614 if (hdspm->tco) {
6615 hdspm->texts_autosync = texts_autosync_aes_tco;
6616 hdspm->texts_autosync_items = 10;
6617 } else {
6618 hdspm->texts_autosync = texts_autosync_aes;
6619 hdspm->texts_autosync_items = 9;
6620 }
6621 break;
6622
6623 case MADI:
6624 if (hdspm->tco) {
6625 hdspm->texts_autosync = texts_autosync_madi_tco;
6626 hdspm->texts_autosync_items = 4;
6627 } else {
6628 hdspm->texts_autosync = texts_autosync_madi;
6629 hdspm->texts_autosync_items = 3;
6630 }
6631 break;
6632
6633 case MADIface:
6634
6635 break;
6636
6637 case RayDAT:
6638 if (hdspm->tco) {
6639 hdspm->texts_autosync = texts_autosync_raydat_tco;
6640 hdspm->texts_autosync_items = 9;
6641 } else {
6642 hdspm->texts_autosync = texts_autosync_raydat;
6643 hdspm->texts_autosync_items = 8;
6644 }
6645 break;
6646
6647 case AIO:
6648 if (hdspm->tco) {
6649 hdspm->texts_autosync = texts_autosync_aio_tco;
6650 hdspm->texts_autosync_items = 6;
6651 } else {
6652 hdspm->texts_autosync = texts_autosync_aio;
6653 hdspm->texts_autosync_items = 5;
6654 }
6655 break;
6656
6657 }
6658
6659 tasklet_init(&hdspm->midi_tasklet,
6660 hdspm_midi_tasklet, (unsigned long) hdspm);
4436 6661
4437 snd_printdd("create alsa devices.\n"); 6662 snd_printdd("create alsa devices.\n");
4438 err = snd_hdspm_create_alsa_devices(card, hdspm); 6663 err = snd_hdspm_create_alsa_devices(card, hdspm);
@@ -4444,6 +6669,7 @@ static int __devinit snd_hdspm_create(struct snd_card *card,
4444 return 0; 6669 return 0;
4445} 6670}
4446 6671
6672
4447static int snd_hdspm_free(struct hdspm * hdspm) 6673static int snd_hdspm_free(struct hdspm * hdspm)
4448{ 6674{
4449 6675
@@ -4452,7 +6678,8 @@ static int snd_hdspm_free(struct hdspm * hdspm)
4452 /* stop th audio, and cancel all interrupts */ 6678 /* stop th audio, and cancel all interrupts */
4453 hdspm->control_register &= 6679 hdspm->control_register &=
4454 ~(HDSPM_Start | HDSPM_AudioInterruptEnable | 6680 ~(HDSPM_Start | HDSPM_AudioInterruptEnable |
4455 HDSPM_Midi0InterruptEnable | HDSPM_Midi1InterruptEnable); 6681 HDSPM_Midi0InterruptEnable | HDSPM_Midi1InterruptEnable |
6682 HDSPM_Midi2InterruptEnable | HDSPM_Midi3InterruptEnable);
4456 hdspm_write(hdspm, HDSPM_controlRegister, 6683 hdspm_write(hdspm, HDSPM_controlRegister,
4457 hdspm->control_register); 6684 hdspm->control_register);
4458 } 6685 }
@@ -4472,6 +6699,7 @@ static int snd_hdspm_free(struct hdspm * hdspm)
4472 return 0; 6699 return 0;
4473} 6700}
4474 6701
6702
4475static void snd_hdspm_card_free(struct snd_card *card) 6703static void snd_hdspm_card_free(struct snd_card *card)
4476{ 6704{
4477 struct hdspm *hdspm = card->private_data; 6705 struct hdspm *hdspm = card->private_data;
@@ -4480,6 +6708,7 @@ static void snd_hdspm_card_free(struct snd_card *card)
4480 snd_hdspm_free(hdspm); 6708 snd_hdspm_free(hdspm);
4481} 6709}
4482 6710
6711
4483static int __devinit snd_hdspm_probe(struct pci_dev *pci, 6712static int __devinit snd_hdspm_probe(struct pci_dev *pci,
4484 const struct pci_device_id *pci_id) 6713 const struct pci_device_id *pci_id)
4485{ 6714{
@@ -4496,7 +6725,7 @@ static int __devinit snd_hdspm_probe(struct pci_dev *pci,
4496 } 6725 }
4497 6726
4498 err = snd_card_create(index[dev], id[dev], 6727 err = snd_card_create(index[dev], id[dev],
4499 THIS_MODULE, sizeof(struct hdspm), &card); 6728 THIS_MODULE, sizeof(struct hdspm), &card);
4500 if (err < 0) 6729 if (err < 0)
4501 return err; 6730 return err;
4502 6731
@@ -4507,16 +6736,25 @@ static int __devinit snd_hdspm_probe(struct pci_dev *pci,
4507 6736
4508 snd_card_set_dev(card, &pci->dev); 6737 snd_card_set_dev(card, &pci->dev);
4509 6738
4510 err = snd_hdspm_create(card, hdspm, precise_ptr[dev], 6739 err = snd_hdspm_create(card, hdspm);
4511 enable_monitor[dev]);
4512 if (err < 0) { 6740 if (err < 0) {
4513 snd_card_free(card); 6741 snd_card_free(card);
4514 return err; 6742 return err;
4515 } 6743 }
4516 6744
4517 strcpy(card->shortname, "HDSPM MADI"); 6745 if (hdspm->io_type != MADIface) {
4518 sprintf(card->longname, "%s at 0x%lx, irq %d", hdspm->card_name, 6746 sprintf(card->shortname, "%s_%x",
4519 hdspm->port, hdspm->irq); 6747 hdspm->card_name,
6748 (hdspm_read(hdspm, HDSPM_midiStatusIn0)>>8) & 0xFFFFFF);
6749 sprintf(card->longname, "%s S/N 0x%x at 0x%lx, irq %d",
6750 hdspm->card_name,
6751 (hdspm_read(hdspm, HDSPM_midiStatusIn0)>>8) & 0xFFFFFF,
6752 hdspm->port, hdspm->irq);
6753 } else {
6754 sprintf(card->shortname, "%s", hdspm->card_name);
6755 sprintf(card->longname, "%s at 0x%lx, irq %d",
6756 hdspm->card_name, hdspm->port, hdspm->irq);
6757 }
4520 6758
4521 err = snd_card_register(card); 6759 err = snd_card_register(card);
4522 if (err < 0) { 6760 if (err < 0) {
diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c
index b47cfd45b3b9..3ecbd67f88c9 100644
--- a/sound/ppc/pmac.c
+++ b/sound/ppc/pmac.c
@@ -1034,7 +1034,11 @@ static int __devinit snd_pmac_detect(struct snd_pmac *chip)
1034 if (of_device_is_compatible(sound, "tumbler")) { 1034 if (of_device_is_compatible(sound, "tumbler")) {
1035 chip->model = PMAC_TUMBLER; 1035 chip->model = PMAC_TUMBLER;
1036 chip->can_capture = of_machine_is_compatible("PowerMac4,2") 1036 chip->can_capture = of_machine_is_compatible("PowerMac4,2")
1037 || of_machine_is_compatible("PowerBook4,1"); 1037 || of_machine_is_compatible("PowerBook3,2")
1038 || of_machine_is_compatible("PowerBook3,3")
1039 || of_machine_is_compatible("PowerBook4,1")
1040 || of_machine_is_compatible("PowerBook4,2")
1041 || of_machine_is_compatible("PowerBook4,3");
1038 chip->can_duplex = 0; 1042 chip->can_duplex = 0;
1039 // chip->can_byte_swap = 0; /* FIXME: check this */ 1043 // chip->can_byte_swap = 0; /* FIXME: check this */
1040 chip->num_freqs = ARRAY_SIZE(tumbler_freqs); 1044 chip->num_freqs = ARRAY_SIZE(tumbler_freqs);
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index a3efc52a34da..8224db5f0434 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -50,10 +50,12 @@ source "sound/soc/jz4740/Kconfig"
50source "sound/soc/nuc900/Kconfig" 50source "sound/soc/nuc900/Kconfig"
51source "sound/soc/omap/Kconfig" 51source "sound/soc/omap/Kconfig"
52source "sound/soc/kirkwood/Kconfig" 52source "sound/soc/kirkwood/Kconfig"
53source "sound/soc/mid-x86/Kconfig"
53source "sound/soc/pxa/Kconfig" 54source "sound/soc/pxa/Kconfig"
54source "sound/soc/samsung/Kconfig" 55source "sound/soc/samsung/Kconfig"
55source "sound/soc/s6000/Kconfig" 56source "sound/soc/s6000/Kconfig"
56source "sound/soc/sh/Kconfig" 57source "sound/soc/sh/Kconfig"
58source "sound/soc/tegra/Kconfig"
57source "sound/soc/txx9/Kconfig" 59source "sound/soc/txx9/Kconfig"
58 60
59# Supported codecs 61# Supported codecs
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index ce913bf5213c..1ed61c5df2c5 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_SND_SOC) += ep93xx/
10obj-$(CONFIG_SND_SOC) += fsl/ 10obj-$(CONFIG_SND_SOC) += fsl/
11obj-$(CONFIG_SND_SOC) += imx/ 11obj-$(CONFIG_SND_SOC) += imx/
12obj-$(CONFIG_SND_SOC) += jz4740/ 12obj-$(CONFIG_SND_SOC) += jz4740/
13obj-$(CONFIG_SND_SOC) += mid-x86/
13obj-$(CONFIG_SND_SOC) += nuc900/ 14obj-$(CONFIG_SND_SOC) += nuc900/
14obj-$(CONFIG_SND_SOC) += omap/ 15obj-$(CONFIG_SND_SOC) += omap/
15obj-$(CONFIG_SND_SOC) += kirkwood/ 16obj-$(CONFIG_SND_SOC) += kirkwood/
@@ -17,4 +18,5 @@ obj-$(CONFIG_SND_SOC) += pxa/
17obj-$(CONFIG_SND_SOC) += samsung/ 18obj-$(CONFIG_SND_SOC) += samsung/
18obj-$(CONFIG_SND_SOC) += s6000/ 19obj-$(CONFIG_SND_SOC) += s6000/
19obj-$(CONFIG_SND_SOC) += sh/ 20obj-$(CONFIG_SND_SOC) += sh/
21obj-$(CONFIG_SND_SOC) += tegra/
20obj-$(CONFIG_SND_SOC) += txx9/ 22obj-$(CONFIG_SND_SOC) += txx9/
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index c48b23c1d4fc..d63c1754e05f 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -26,17 +26,24 @@ config SND_SOC_ALL_CODECS
26 select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC 26 select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC
27 select SND_SOC_CS42L51 if I2C 27 select SND_SOC_CS42L51 if I2C
28 select SND_SOC_CS4270 if I2C 28 select SND_SOC_CS4270 if I2C
29 select SND_SOC_CS4271 if SND_SOC_I2C_AND_SPI
29 select SND_SOC_CX20442 30 select SND_SOC_CX20442
30 select SND_SOC_DA7210 if I2C 31 select SND_SOC_DA7210 if I2C
32 select SND_SOC_DFBMCS320
31 select SND_SOC_JZ4740_CODEC if SOC_JZ4740 33 select SND_SOC_JZ4740_CODEC if SOC_JZ4740
34 select SND_SOC_LM4857 if I2C
32 select SND_SOC_MAX98088 if I2C 35 select SND_SOC_MAX98088 if I2C
36 select SND_SOC_MAX9850 if I2C
33 select SND_SOC_MAX9877 if I2C 37 select SND_SOC_MAX9877 if I2C
34 select SND_SOC_PCM3008 38 select SND_SOC_PCM3008
39 select SND_SOC_SGTL5000 if I2C
40 select SND_SOC_SN95031 if INTEL_SCU_IPC
35 select SND_SOC_SPDIF 41 select SND_SOC_SPDIF
36 select SND_SOC_SSM2602 if I2C 42 select SND_SOC_SSM2602 if I2C
37 select SND_SOC_STAC9766 if SND_SOC_AC97_BUS 43 select SND_SOC_STAC9766 if SND_SOC_AC97_BUS
38 select SND_SOC_TLV320AIC23 if I2C 44 select SND_SOC_TLV320AIC23 if I2C
39 select SND_SOC_TLV320AIC26 if SPI_MASTER 45 select SND_SOC_TLV320AIC26 if SPI_MASTER
46 select SND_SOC_TVL320AIC32X4 if I2C
40 select SND_SOC_TLV320AIC3X if I2C 47 select SND_SOC_TLV320AIC3X if I2C
41 select SND_SOC_TPA6130A2 if I2C 48 select SND_SOC_TPA6130A2 if I2C
42 select SND_SOC_TLV320DAC33 if I2C 49 select SND_SOC_TLV320DAC33 if I2C
@@ -76,6 +83,7 @@ config SND_SOC_ALL_CODECS
76 select SND_SOC_WM8985 if SND_SOC_I2C_AND_SPI 83 select SND_SOC_WM8985 if SND_SOC_I2C_AND_SPI
77 select SND_SOC_WM8988 if SND_SOC_I2C_AND_SPI 84 select SND_SOC_WM8988 if SND_SOC_I2C_AND_SPI
78 select SND_SOC_WM8990 if I2C 85 select SND_SOC_WM8990 if I2C
86 select SND_SOC_WM8991 if I2C
79 select SND_SOC_WM8993 if I2C 87 select SND_SOC_WM8993 if I2C
80 select SND_SOC_WM8994 if MFD_WM8994 88 select SND_SOC_WM8994 if MFD_WM8994
81 select SND_SOC_WM8995 if SND_SOC_I2C_AND_SPI 89 select SND_SOC_WM8995 if SND_SOC_I2C_AND_SPI
@@ -155,6 +163,9 @@ config SND_SOC_CS4270_VD33_ERRATA
155 bool 163 bool
156 depends on SND_SOC_CS4270 164 depends on SND_SOC_CS4270
157 165
166config SND_SOC_CS4271
167 tristate
168
158config SND_SOC_CX20442 169config SND_SOC_CX20442
159 tristate 170 tristate
160 171
@@ -167,15 +178,28 @@ config SND_SOC_L3
167config SND_SOC_DA7210 178config SND_SOC_DA7210
168 tristate 179 tristate
169 180
181config SND_SOC_DFBMCS320
182 tristate
183
170config SND_SOC_DMIC 184config SND_SOC_DMIC
171 tristate 185 tristate
172 186
173config SND_SOC_MAX98088 187config SND_SOC_MAX98088
174 tristate 188 tristate
175 189
190config SND_SOC_MAX9850
191 tristate
192
176config SND_SOC_PCM3008 193config SND_SOC_PCM3008
177 tristate 194 tristate
178 195
196#Freescale sgtl5000 codec
197config SND_SOC_SGTL5000
198 tristate
199
200config SND_SOC_SN95031
201 tristate
202
179config SND_SOC_SPDIF 203config SND_SOC_SPDIF
180 tristate 204 tristate
181 205
@@ -192,6 +216,9 @@ config SND_SOC_TLV320AIC26
192 tristate "TI TLV320AIC26 Codec support" if SND_SOC_OF_SIMPLE 216 tristate "TI TLV320AIC26 Codec support" if SND_SOC_OF_SIMPLE
193 depends on SPI 217 depends on SPI
194 218
219config SND_SOC_TVL320AIC32X4
220 tristate
221
195config SND_SOC_TLV320AIC3X 222config SND_SOC_TLV320AIC3X
196 tristate 223 tristate
197 224
@@ -304,6 +331,9 @@ config SND_SOC_WM8988
304config SND_SOC_WM8990 331config SND_SOC_WM8990
305 tristate 332 tristate
306 333
334config SND_SOC_WM8991
335 tristate
336
307config SND_SOC_WM8993 337config SND_SOC_WM8993
308 tristate 338 tristate
309 339
@@ -326,6 +356,9 @@ config SND_SOC_WM9713
326 tristate 356 tristate
327 357
328# Amp 358# Amp
359config SND_SOC_LM4857
360 tristate
361
329config SND_SOC_MAX9877 362config SND_SOC_MAX9877
330 tristate 363 tristate
331 364
@@ -337,4 +370,3 @@ config SND_SOC_WM2000
337 370
338config SND_SOC_WM9090 371config SND_SOC_WM9090
339 tristate 372 tristate
340
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 579af9c4f128..379bc55f0723 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -12,19 +12,25 @@ snd-soc-ak4671-objs := ak4671.o
12snd-soc-cq93vc-objs := cq93vc.o 12snd-soc-cq93vc-objs := cq93vc.o
13snd-soc-cs42l51-objs := cs42l51.o 13snd-soc-cs42l51-objs := cs42l51.o
14snd-soc-cs4270-objs := cs4270.o 14snd-soc-cs4270-objs := cs4270.o
15snd-soc-cs4271-objs := cs4271.o
15snd-soc-cx20442-objs := cx20442.o 16snd-soc-cx20442-objs := cx20442.o
16snd-soc-da7210-objs := da7210.o 17snd-soc-da7210-objs := da7210.o
18snd-soc-dfbmcs320-objs := dfbmcs320.o
17snd-soc-dmic-objs := dmic.o 19snd-soc-dmic-objs := dmic.o
18snd-soc-l3-objs := l3.o 20snd-soc-l3-objs := l3.o
19snd-soc-max98088-objs := max98088.o 21snd-soc-max98088-objs := max98088.o
22snd-soc-max9850-objs := max9850.o
20snd-soc-pcm3008-objs := pcm3008.o 23snd-soc-pcm3008-objs := pcm3008.o
24snd-soc-sgtl5000-objs := sgtl5000.o
21snd-soc-alc5623-objs := alc5623.o 25snd-soc-alc5623-objs := alc5623.o
26snd-soc-sn95031-objs := sn95031.o
22snd-soc-spdif-objs := spdif_transciever.o 27snd-soc-spdif-objs := spdif_transciever.o
23snd-soc-ssm2602-objs := ssm2602.o 28snd-soc-ssm2602-objs := ssm2602.o
24snd-soc-stac9766-objs := stac9766.o 29snd-soc-stac9766-objs := stac9766.o
25snd-soc-tlv320aic23-objs := tlv320aic23.o 30snd-soc-tlv320aic23-objs := tlv320aic23.o
26snd-soc-tlv320aic26-objs := tlv320aic26.o 31snd-soc-tlv320aic26-objs := tlv320aic26.o
27snd-soc-tlv320aic3x-objs := tlv320aic3x.o 32snd-soc-tlv320aic3x-objs := tlv320aic3x.o
33snd-soc-tlv320aic32x4-objs := tlv320aic32x4.o
28snd-soc-tlv320dac33-objs := tlv320dac33.o 34snd-soc-tlv320dac33-objs := tlv320dac33.o
29snd-soc-twl4030-objs := twl4030.o 35snd-soc-twl4030-objs := twl4030.o
30snd-soc-twl6040-objs := twl6040.o 36snd-soc-twl6040-objs := twl6040.o
@@ -61,6 +67,7 @@ snd-soc-wm8978-objs := wm8978.o
61snd-soc-wm8985-objs := wm8985.o 67snd-soc-wm8985-objs := wm8985.o
62snd-soc-wm8988-objs := wm8988.o 68snd-soc-wm8988-objs := wm8988.o
63snd-soc-wm8990-objs := wm8990.o 69snd-soc-wm8990-objs := wm8990.o
70snd-soc-wm8991-objs := wm8991.o
64snd-soc-wm8993-objs := wm8993.o 71snd-soc-wm8993-objs := wm8993.o
65snd-soc-wm8994-objs := wm8994.o wm8994-tables.o 72snd-soc-wm8994-objs := wm8994.o wm8994-tables.o
66snd-soc-wm8995-objs := wm8995.o 73snd-soc-wm8995-objs := wm8995.o
@@ -72,6 +79,7 @@ snd-soc-wm-hubs-objs := wm_hubs.o
72snd-soc-jz4740-codec-objs := jz4740.o 79snd-soc-jz4740-codec-objs := jz4740.o
73 80
74# Amp 81# Amp
82snd-soc-lm4857-objs := lm4857.o
75snd-soc-max9877-objs := max9877.o 83snd-soc-max9877-objs := max9877.o
76snd-soc-tpa6130a2-objs := tpa6130a2.o 84snd-soc-tpa6130a2-objs := tpa6130a2.o
77snd-soc-wm2000-objs := wm2000.o 85snd-soc-wm2000-objs := wm2000.o
@@ -88,23 +96,29 @@ obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o
88obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o 96obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o
89obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o 97obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o
90obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o 98obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o
99obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o
91obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o 100obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o
92obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o 101obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o
93obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o 102obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
103obj-$(CONFIG_SND_SOC_CS4271) += snd-soc-cs4271.o
94obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o 104obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o
95obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o 105obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o
106obj-$(CONFIG_SND_SOC_DFBMCS320) += snd-soc-dfbmcs320.o
96obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o 107obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o
97obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o 108obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o
98obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o 109obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o
99obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o 110obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o
111obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o
100obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o 112obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o
101obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o 113obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o
114obj-$(CONFIG_SND_SOC_SN95031) +=snd-soc-sn95031.o
102obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o 115obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o
103obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o 116obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o
104obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o 117obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o
105obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o 118obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o
106obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o 119obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o
107obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o 120obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o
121obj-$(CONFIG_SND_SOC_TVL320AIC32X4) += snd-soc-tlv320aic32x4.o
108obj-$(CONFIG_SND_SOC_TLV320DAC33) += snd-soc-tlv320dac33.o 122obj-$(CONFIG_SND_SOC_TLV320DAC33) += snd-soc-tlv320dac33.o
109obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o 123obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o
110obj-$(CONFIG_SND_SOC_TWL6040) += snd-soc-twl6040.o 124obj-$(CONFIG_SND_SOC_TWL6040) += snd-soc-twl6040.o
@@ -141,6 +155,7 @@ obj-$(CONFIG_SND_SOC_WM8978) += snd-soc-wm8978.o
141obj-$(CONFIG_SND_SOC_WM8985) += snd-soc-wm8985.o 155obj-$(CONFIG_SND_SOC_WM8985) += snd-soc-wm8985.o
142obj-$(CONFIG_SND_SOC_WM8988) += snd-soc-wm8988.o 156obj-$(CONFIG_SND_SOC_WM8988) += snd-soc-wm8988.o
143obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o 157obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o
158obj-$(CONFIG_SND_SOC_WM8991) += snd-soc-wm8991.o
144obj-$(CONFIG_SND_SOC_WM8993) += snd-soc-wm8993.o 159obj-$(CONFIG_SND_SOC_WM8993) += snd-soc-wm8993.o
145obj-$(CONFIG_SND_SOC_WM8994) += snd-soc-wm8994.o 160obj-$(CONFIG_SND_SOC_WM8994) += snd-soc-wm8994.o
146obj-$(CONFIG_SND_SOC_WM8995) += snd-soc-wm8995.o 161obj-$(CONFIG_SND_SOC_WM8995) += snd-soc-wm8995.o
@@ -151,6 +166,7 @@ obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o
151obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o 166obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o
152 167
153# Amp 168# Amp
169obj-$(CONFIG_SND_SOC_LM4857) += snd-soc-lm4857.o
154obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o 170obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o
155obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o 171obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o
156obj-$(CONFIG_SND_SOC_WM2000) += snd-soc-wm2000.o 172obj-$(CONFIG_SND_SOC_WM2000) += snd-soc-wm2000.o
diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c
index c27f8f59dc66..cbf0b6d400b8 100644
--- a/sound/soc/codecs/ak4104.c
+++ b/sound/soc/codecs/ak4104.c
@@ -294,7 +294,6 @@ static struct spi_driver ak4104_spi_driver = {
294 294
295static int __init ak4104_init(void) 295static int __init ak4104_init(void)
296{ 296{
297 pr_info("Asahi Kasei AK4104 ALSA SoC Codec Driver\n");
298 return spi_register_driver(&ak4104_spi_driver); 297 return spi_register_driver(&ak4104_spi_driver);
299} 298}
300module_init(ak4104_init); 299module_init(ak4104_init);
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
index f00eba313dfd..4be0570e3f1f 100644
--- a/sound/soc/codecs/ak4642.c
+++ b/sound/soc/codecs/ak4642.c
@@ -116,6 +116,12 @@
116#define BCKO_MASK (1 << 3) 116#define BCKO_MASK (1 << 3)
117#define BCKO_64 BCKO_MASK 117#define BCKO_64 BCKO_MASK
118 118
119#define DIF_MASK (3 << 0)
120#define DSP (0 << 0)
121#define RIGHT_J (1 << 0)
122#define LEFT_J (2 << 0)
123#define I2S (3 << 0)
124
119/* MD_CTL2 */ 125/* MD_CTL2 */
120#define FS0 (1 << 0) 126#define FS0 (1 << 0)
121#define FS1 (1 << 1) 127#define FS1 (1 << 1)
@@ -354,6 +360,24 @@ static int ak4642_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
354 snd_soc_update_bits(codec, PW_MGMT2, MS, data); 360 snd_soc_update_bits(codec, PW_MGMT2, MS, data);
355 snd_soc_update_bits(codec, MD_CTL1, BCKO_MASK, bcko); 361 snd_soc_update_bits(codec, MD_CTL1, BCKO_MASK, bcko);
356 362
363 /* format type */
364 data = 0;
365 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
366 case SND_SOC_DAIFMT_LEFT_J:
367 data = LEFT_J;
368 break;
369 case SND_SOC_DAIFMT_I2S:
370 data = I2S;
371 break;
372 /* FIXME
373 * Please add RIGHT_J / DSP support here
374 */
375 default:
376 return -EINVAL;
377 break;
378 }
379 snd_soc_update_bits(codec, MD_CTL1, DIF_MASK, data);
380
357 return 0; 381 return 0;
358} 382}
359 383
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index 8b51245f2318..0206a17d7283 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -193,12 +193,12 @@ static struct cs4270_mode_ratios cs4270_mode_ratios[] = {
193/* The number of MCLK/LRCK ratios supported by the CS4270 */ 193/* The number of MCLK/LRCK ratios supported by the CS4270 */
194#define NUM_MCLK_RATIOS ARRAY_SIZE(cs4270_mode_ratios) 194#define NUM_MCLK_RATIOS ARRAY_SIZE(cs4270_mode_ratios)
195 195
196static int cs4270_reg_is_readable(unsigned int reg) 196static int cs4270_reg_is_readable(struct snd_soc_codec *codec, unsigned int reg)
197{ 197{
198 return (reg >= CS4270_FIRSTREG) && (reg <= CS4270_LASTREG); 198 return (reg >= CS4270_FIRSTREG) && (reg <= CS4270_LASTREG);
199} 199}
200 200
201static int cs4270_reg_is_volatile(unsigned int reg) 201static int cs4270_reg_is_volatile(struct snd_soc_codec *codec, unsigned int reg)
202{ 202{
203 /* Unreadable registers are considered volatile */ 203 /* Unreadable registers are considered volatile */
204 if ((reg < CS4270_FIRSTREG) || (reg > CS4270_LASTREG)) 204 if ((reg < CS4270_FIRSTREG) || (reg > CS4270_LASTREG))
@@ -719,7 +719,7 @@ static int cs4270_i2c_remove(struct i2c_client *i2c_client)
719/* 719/*
720 * cs4270_id - I2C device IDs supported by this driver 720 * cs4270_id - I2C device IDs supported by this driver
721 */ 721 */
722static struct i2c_device_id cs4270_id[] = { 722static const struct i2c_device_id cs4270_id[] = {
723 {"cs4270", 0}, 723 {"cs4270", 0},
724 {} 724 {}
725}; 725};
@@ -743,8 +743,6 @@ static struct i2c_driver cs4270_i2c_driver = {
743 743
744static int __init cs4270_init(void) 744static int __init cs4270_init(void)
745{ 745{
746 pr_info("Cirrus Logic CS4270 ALSA SoC Codec Driver\n");
747
748 return i2c_add_driver(&cs4270_i2c_driver); 746 return i2c_add_driver(&cs4270_i2c_driver);
749} 747}
750module_init(cs4270_init); 748module_init(cs4270_init);
diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c
new file mode 100644
index 000000000000..083aab96ca80
--- /dev/null
+++ b/sound/soc/codecs/cs4271.c
@@ -0,0 +1,667 @@
1/*
2 * CS4271 ASoC codec driver
3 *
4 * Copyright (c) 2010 Alexander Sverdlin <subaparts@yandex.ru>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * This driver support CS4271 codec being master or slave, working
17 * in control port mode, connected either via SPI or I2C.
18 * The data format accepted is I2S or left-justified.
19 * DAPM support not implemented.
20 */
21
22#include <linux/module.h>
23#include <linux/slab.h>
24#include <linux/delay.h>
25#include <sound/pcm.h>
26#include <sound/soc.h>
27#include <sound/tlv.h>
28#include <linux/gpio.h>
29#include <linux/i2c.h>
30#include <linux/spi/spi.h>
31#include <sound/cs4271.h>
32
33#define CS4271_PCM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
34 SNDRV_PCM_FMTBIT_S24_LE | \
35 SNDRV_PCM_FMTBIT_S32_LE)
36#define CS4271_PCM_RATES SNDRV_PCM_RATE_8000_192000
37
38/*
39 * CS4271 registers
40 * High byte represents SPI chip address (0x10) + write command (0)
41 * Low byte - codec register address
42 */
43#define CS4271_MODE1 0x2001 /* Mode Control 1 */
44#define CS4271_DACCTL 0x2002 /* DAC Control */
45#define CS4271_DACVOL 0x2003 /* DAC Volume & Mixing Control */
46#define CS4271_VOLA 0x2004 /* DAC Channel A Volume Control */
47#define CS4271_VOLB 0x2005 /* DAC Channel B Volume Control */
48#define CS4271_ADCCTL 0x2006 /* ADC Control */
49#define CS4271_MODE2 0x2007 /* Mode Control 2 */
50#define CS4271_CHIPID 0x2008 /* Chip ID */
51
52#define CS4271_FIRSTREG CS4271_MODE1
53#define CS4271_LASTREG CS4271_MODE2
54#define CS4271_NR_REGS ((CS4271_LASTREG & 0xFF) + 1)
55
56/* Bit masks for the CS4271 registers */
57#define CS4271_MODE1_MODE_MASK 0xC0
58#define CS4271_MODE1_MODE_1X 0x00
59#define CS4271_MODE1_MODE_2X 0x80
60#define CS4271_MODE1_MODE_4X 0xC0
61
62#define CS4271_MODE1_DIV_MASK 0x30
63#define CS4271_MODE1_DIV_1 0x00
64#define CS4271_MODE1_DIV_15 0x10
65#define CS4271_MODE1_DIV_2 0x20
66#define CS4271_MODE1_DIV_3 0x30
67
68#define CS4271_MODE1_MASTER 0x08
69
70#define CS4271_MODE1_DAC_DIF_MASK 0x07
71#define CS4271_MODE1_DAC_DIF_LJ 0x00
72#define CS4271_MODE1_DAC_DIF_I2S 0x01
73#define CS4271_MODE1_DAC_DIF_RJ16 0x02
74#define CS4271_MODE1_DAC_DIF_RJ24 0x03
75#define CS4271_MODE1_DAC_DIF_RJ20 0x04
76#define CS4271_MODE1_DAC_DIF_RJ18 0x05
77
78#define CS4271_DACCTL_AMUTE 0x80
79#define CS4271_DACCTL_IF_SLOW 0x40
80
81#define CS4271_DACCTL_DEM_MASK 0x30
82#define CS4271_DACCTL_DEM_DIS 0x00
83#define CS4271_DACCTL_DEM_441 0x10
84#define CS4271_DACCTL_DEM_48 0x20
85#define CS4271_DACCTL_DEM_32 0x30
86
87#define CS4271_DACCTL_SVRU 0x08
88#define CS4271_DACCTL_SRD 0x04
89#define CS4271_DACCTL_INVA 0x02
90#define CS4271_DACCTL_INVB 0x01
91
92#define CS4271_DACVOL_BEQUA 0x40
93#define CS4271_DACVOL_SOFT 0x20
94#define CS4271_DACVOL_ZEROC 0x10
95
96#define CS4271_DACVOL_ATAPI_MASK 0x0F
97#define CS4271_DACVOL_ATAPI_M_M 0x00
98#define CS4271_DACVOL_ATAPI_M_BR 0x01
99#define CS4271_DACVOL_ATAPI_M_BL 0x02
100#define CS4271_DACVOL_ATAPI_M_BLR2 0x03
101#define CS4271_DACVOL_ATAPI_AR_M 0x04
102#define CS4271_DACVOL_ATAPI_AR_BR 0x05
103#define CS4271_DACVOL_ATAPI_AR_BL 0x06
104#define CS4271_DACVOL_ATAPI_AR_BLR2 0x07
105#define CS4271_DACVOL_ATAPI_AL_M 0x08
106#define CS4271_DACVOL_ATAPI_AL_BR 0x09
107#define CS4271_DACVOL_ATAPI_AL_BL 0x0A
108#define CS4271_DACVOL_ATAPI_AL_BLR2 0x0B
109#define CS4271_DACVOL_ATAPI_ALR2_M 0x0C
110#define CS4271_DACVOL_ATAPI_ALR2_BR 0x0D
111#define CS4271_DACVOL_ATAPI_ALR2_BL 0x0E
112#define CS4271_DACVOL_ATAPI_ALR2_BLR2 0x0F
113
114#define CS4271_VOLA_MUTE 0x80
115#define CS4271_VOLA_VOL_MASK 0x7F
116#define CS4271_VOLB_MUTE 0x80
117#define CS4271_VOLB_VOL_MASK 0x7F
118
119#define CS4271_ADCCTL_DITHER16 0x20
120
121#define CS4271_ADCCTL_ADC_DIF_MASK 0x10
122#define CS4271_ADCCTL_ADC_DIF_LJ 0x00
123#define CS4271_ADCCTL_ADC_DIF_I2S 0x10
124
125#define CS4271_ADCCTL_MUTEA 0x08
126#define CS4271_ADCCTL_MUTEB 0x04
127#define CS4271_ADCCTL_HPFDA 0x02
128#define CS4271_ADCCTL_HPFDB 0x01
129
130#define CS4271_MODE2_LOOP 0x10
131#define CS4271_MODE2_MUTECAEQUB 0x08
132#define CS4271_MODE2_FREEZE 0x04
133#define CS4271_MODE2_CPEN 0x02
134#define CS4271_MODE2_PDN 0x01
135
136#define CS4271_CHIPID_PART_MASK 0xF0
137#define CS4271_CHIPID_REV_MASK 0x0F
138
139/*
140 * Default CS4271 power-up configuration
141 * Array contains non-existing in hw register at address 0
142 * Array do not include Chip ID, as codec driver does not use
143 * registers read operations at all
144 */
145static const u8 cs4271_dflt_reg[CS4271_NR_REGS] = {
146 0,
147 0,
148 CS4271_DACCTL_AMUTE,
149 CS4271_DACVOL_SOFT | CS4271_DACVOL_ATAPI_AL_BR,
150 0,
151 0,
152 0,
153 0,
154};
155
156struct cs4271_private {
157 /* SND_SOC_I2C or SND_SOC_SPI */
158 enum snd_soc_control_type bus_type;
159 void *control_data;
160 unsigned int mclk;
161 bool master;
162 bool deemph;
163 /* Current sample rate for de-emphasis control */
164 int rate;
165 /* GPIO driving Reset pin, if any */
166 int gpio_nreset;
167 /* GPIO that disable serial bus, if any */
168 int gpio_disable;
169};
170
171/*
172 * @freq is the desired MCLK rate
173 * MCLK rate should (c) be the sample rate, multiplied by one of the
174 * ratios listed in cs4271_mclk_fs_ratios table
175 */
176static int cs4271_set_dai_sysclk(struct snd_soc_dai *codec_dai,
177 int clk_id, unsigned int freq, int dir)
178{
179 struct snd_soc_codec *codec = codec_dai->codec;
180 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
181
182 cs4271->mclk = freq;
183 return 0;
184}
185
186static int cs4271_set_dai_fmt(struct snd_soc_dai *codec_dai,
187 unsigned int format)
188{
189 struct snd_soc_codec *codec = codec_dai->codec;
190 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
191 unsigned int val = 0;
192 int ret;
193
194 switch (format & SND_SOC_DAIFMT_MASTER_MASK) {
195 case SND_SOC_DAIFMT_CBS_CFS:
196 cs4271->master = 0;
197 break;
198 case SND_SOC_DAIFMT_CBM_CFM:
199 cs4271->master = 1;
200 val |= CS4271_MODE1_MASTER;
201 break;
202 default:
203 dev_err(codec->dev, "Invalid DAI format\n");
204 return -EINVAL;
205 }
206
207 switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
208 case SND_SOC_DAIFMT_LEFT_J:
209 val |= CS4271_MODE1_DAC_DIF_LJ;
210 ret = snd_soc_update_bits(codec, CS4271_ADCCTL,
211 CS4271_ADCCTL_ADC_DIF_MASK, CS4271_ADCCTL_ADC_DIF_LJ);
212 if (ret < 0)
213 return ret;
214 break;
215 case SND_SOC_DAIFMT_I2S:
216 val |= CS4271_MODE1_DAC_DIF_I2S;
217 ret = snd_soc_update_bits(codec, CS4271_ADCCTL,
218 CS4271_ADCCTL_ADC_DIF_MASK, CS4271_ADCCTL_ADC_DIF_I2S);
219 if (ret < 0)
220 return ret;
221 break;
222 default:
223 dev_err(codec->dev, "Invalid DAI format\n");
224 return -EINVAL;
225 }
226
227 ret = snd_soc_update_bits(codec, CS4271_MODE1,
228 CS4271_MODE1_DAC_DIF_MASK | CS4271_MODE1_MASTER, val);
229 if (ret < 0)
230 return ret;
231 return 0;
232}
233
234static int cs4271_deemph[] = {0, 44100, 48000, 32000};
235
236static int cs4271_set_deemph(struct snd_soc_codec *codec)
237{
238 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
239 int i, ret;
240 int val = CS4271_DACCTL_DEM_DIS;
241
242 if (cs4271->deemph) {
243 /* Find closest de-emphasis freq */
244 val = 1;
245 for (i = 2; i < ARRAY_SIZE(cs4271_deemph); i++)
246 if (abs(cs4271_deemph[i] - cs4271->rate) <
247 abs(cs4271_deemph[val] - cs4271->rate))
248 val = i;
249 val <<= 4;
250 }
251
252 ret = snd_soc_update_bits(codec, CS4271_DACCTL,
253 CS4271_DACCTL_DEM_MASK, val);
254 if (ret < 0)
255 return ret;
256 return 0;
257}
258
259static int cs4271_get_deemph(struct snd_kcontrol *kcontrol,
260 struct snd_ctl_elem_value *ucontrol)
261{
262 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
263 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
264
265 ucontrol->value.enumerated.item[0] = cs4271->deemph;
266 return 0;
267}
268
269static int cs4271_put_deemph(struct snd_kcontrol *kcontrol,
270 struct snd_ctl_elem_value *ucontrol)
271{
272 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
273 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
274
275 cs4271->deemph = ucontrol->value.enumerated.item[0];
276 return cs4271_set_deemph(codec);
277}
278
279struct cs4271_clk_cfg {
280 bool master; /* codec mode */
281 u8 speed_mode; /* codec speed mode: 1x, 2x, 4x */
282 unsigned short ratio; /* MCLK / sample rate */
283 u8 ratio_mask; /* ratio bit mask for Master mode */
284};
285
286static struct cs4271_clk_cfg cs4271_clk_tab[] = {
287 {1, CS4271_MODE1_MODE_1X, 256, CS4271_MODE1_DIV_1},
288 {1, CS4271_MODE1_MODE_1X, 384, CS4271_MODE1_DIV_15},
289 {1, CS4271_MODE1_MODE_1X, 512, CS4271_MODE1_DIV_2},
290 {1, CS4271_MODE1_MODE_1X, 768, CS4271_MODE1_DIV_3},
291 {1, CS4271_MODE1_MODE_2X, 128, CS4271_MODE1_DIV_1},
292 {1, CS4271_MODE1_MODE_2X, 192, CS4271_MODE1_DIV_15},
293 {1, CS4271_MODE1_MODE_2X, 256, CS4271_MODE1_DIV_2},
294 {1, CS4271_MODE1_MODE_2X, 384, CS4271_MODE1_DIV_3},
295 {1, CS4271_MODE1_MODE_4X, 64, CS4271_MODE1_DIV_1},
296 {1, CS4271_MODE1_MODE_4X, 96, CS4271_MODE1_DIV_15},
297 {1, CS4271_MODE1_MODE_4X, 128, CS4271_MODE1_DIV_2},
298 {1, CS4271_MODE1_MODE_4X, 192, CS4271_MODE1_DIV_3},
299 {0, CS4271_MODE1_MODE_1X, 256, CS4271_MODE1_DIV_1},
300 {0, CS4271_MODE1_MODE_1X, 384, CS4271_MODE1_DIV_1},
301 {0, CS4271_MODE1_MODE_1X, 512, CS4271_MODE1_DIV_1},
302 {0, CS4271_MODE1_MODE_1X, 768, CS4271_MODE1_DIV_2},
303 {0, CS4271_MODE1_MODE_1X, 1024, CS4271_MODE1_DIV_2},
304 {0, CS4271_MODE1_MODE_2X, 128, CS4271_MODE1_DIV_1},
305 {0, CS4271_MODE1_MODE_2X, 192, CS4271_MODE1_DIV_1},
306 {0, CS4271_MODE1_MODE_2X, 256, CS4271_MODE1_DIV_1},
307 {0, CS4271_MODE1_MODE_2X, 384, CS4271_MODE1_DIV_2},
308 {0, CS4271_MODE1_MODE_2X, 512, CS4271_MODE1_DIV_2},
309 {0, CS4271_MODE1_MODE_4X, 64, CS4271_MODE1_DIV_1},
310 {0, CS4271_MODE1_MODE_4X, 96, CS4271_MODE1_DIV_1},
311 {0, CS4271_MODE1_MODE_4X, 128, CS4271_MODE1_DIV_1},
312 {0, CS4271_MODE1_MODE_4X, 192, CS4271_MODE1_DIV_2},
313 {0, CS4271_MODE1_MODE_4X, 256, CS4271_MODE1_DIV_2},
314};
315
316#define CS4171_NR_RATIOS ARRAY_SIZE(cs4271_clk_tab)
317
318static int cs4271_hw_params(struct snd_pcm_substream *substream,
319 struct snd_pcm_hw_params *params,
320 struct snd_soc_dai *dai)
321{
322 struct snd_soc_pcm_runtime *rtd = substream->private_data;
323 struct snd_soc_codec *codec = rtd->codec;
324 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
325 int i, ret;
326 unsigned int ratio, val;
327
328 cs4271->rate = params_rate(params);
329
330 /* Configure DAC */
331 if (cs4271->rate < 50000)
332 val = CS4271_MODE1_MODE_1X;
333 else if (cs4271->rate < 100000)
334 val = CS4271_MODE1_MODE_2X;
335 else
336 val = CS4271_MODE1_MODE_4X;
337
338 ratio = cs4271->mclk / cs4271->rate;
339 for (i = 0; i < CS4171_NR_RATIOS; i++)
340 if ((cs4271_clk_tab[i].master == cs4271->master) &&
341 (cs4271_clk_tab[i].speed_mode == val) &&
342 (cs4271_clk_tab[i].ratio == ratio))
343 break;
344
345 if (i == CS4171_NR_RATIOS) {
346 dev_err(codec->dev, "Invalid sample rate\n");
347 return -EINVAL;
348 }
349
350 val |= cs4271_clk_tab[i].ratio_mask;
351
352 ret = snd_soc_update_bits(codec, CS4271_MODE1,
353 CS4271_MODE1_MODE_MASK | CS4271_MODE1_DIV_MASK, val);
354 if (ret < 0)
355 return ret;
356
357 return cs4271_set_deemph(codec);
358}
359
360static int cs4271_digital_mute(struct snd_soc_dai *dai, int mute)
361{
362 struct snd_soc_codec *codec = dai->codec;
363 int ret;
364 int val_a = 0;
365 int val_b = 0;
366
367 if (mute) {
368 val_a = CS4271_VOLA_MUTE;
369 val_b = CS4271_VOLB_MUTE;
370 }
371
372 ret = snd_soc_update_bits(codec, CS4271_VOLA, CS4271_VOLA_MUTE, val_a);
373 if (ret < 0)
374 return ret;
375 ret = snd_soc_update_bits(codec, CS4271_VOLB, CS4271_VOLB_MUTE, val_b);
376 if (ret < 0)
377 return ret;
378
379 return 0;
380}
381
382/* CS4271 controls */
383static DECLARE_TLV_DB_SCALE(cs4271_dac_tlv, -12700, 100, 0);
384
385static const struct snd_kcontrol_new cs4271_snd_controls[] = {
386 SOC_DOUBLE_R_TLV("Master Playback Volume", CS4271_VOLA, CS4271_VOLB,
387 0, 0x7F, 1, cs4271_dac_tlv),
388 SOC_SINGLE("Digital Loopback Switch", CS4271_MODE2, 4, 1, 0),
389 SOC_SINGLE("Soft Ramp Switch", CS4271_DACVOL, 5, 1, 0),
390 SOC_SINGLE("Zero Cross Switch", CS4271_DACVOL, 4, 1, 0),
391 SOC_SINGLE_BOOL_EXT("De-emphasis Switch", 0,
392 cs4271_get_deemph, cs4271_put_deemph),
393 SOC_SINGLE("Auto-Mute Switch", CS4271_DACCTL, 7, 1, 0),
394 SOC_SINGLE("Slow Roll Off Filter Switch", CS4271_DACCTL, 6, 1, 0),
395 SOC_SINGLE("Soft Volume Ramp-Up Switch", CS4271_DACCTL, 3, 1, 0),
396 SOC_SINGLE("Soft Ramp-Down Switch", CS4271_DACCTL, 2, 1, 0),
397 SOC_SINGLE("Left Channel Inversion Switch", CS4271_DACCTL, 1, 1, 0),
398 SOC_SINGLE("Right Channel Inversion Switch", CS4271_DACCTL, 0, 1, 0),
399 SOC_DOUBLE("Master Capture Switch", CS4271_ADCCTL, 3, 2, 1, 1),
400 SOC_SINGLE("Dither 16-Bit Data Switch", CS4271_ADCCTL, 5, 1, 0),
401 SOC_DOUBLE("High Pass Filter Switch", CS4271_ADCCTL, 1, 0, 1, 1),
402 SOC_DOUBLE_R("Master Playback Switch", CS4271_VOLA, CS4271_VOLB,
403 7, 1, 1),
404};
405
406static struct snd_soc_dai_ops cs4271_dai_ops = {
407 .hw_params = cs4271_hw_params,
408 .set_sysclk = cs4271_set_dai_sysclk,
409 .set_fmt = cs4271_set_dai_fmt,
410 .digital_mute = cs4271_digital_mute,
411};
412
413static struct snd_soc_dai_driver cs4271_dai = {
414 .name = "cs4271-hifi",
415 .playback = {
416 .stream_name = "Playback",
417 .channels_min = 2,
418 .channels_max = 2,
419 .rates = CS4271_PCM_RATES,
420 .formats = CS4271_PCM_FORMATS,
421 },
422 .capture = {
423 .stream_name = "Capture",
424 .channels_min = 2,
425 .channels_max = 2,
426 .rates = CS4271_PCM_RATES,
427 .formats = CS4271_PCM_FORMATS,
428 },
429 .ops = &cs4271_dai_ops,
430 .symmetric_rates = 1,
431};
432
433#ifdef CONFIG_PM
434static int cs4271_soc_suspend(struct snd_soc_codec *codec, pm_message_t mesg)
435{
436 int ret;
437 /* Set power-down bit */
438 ret = snd_soc_update_bits(codec, CS4271_MODE2, 0, CS4271_MODE2_PDN);
439 if (ret < 0)
440 return ret;
441 return 0;
442}
443
444static int cs4271_soc_resume(struct snd_soc_codec *codec)
445{
446 int ret;
447 /* Restore codec state */
448 ret = snd_soc_cache_sync(codec);
449 if (ret < 0)
450 return ret;
451 /* then disable the power-down bit */
452 ret = snd_soc_update_bits(codec, CS4271_MODE2, CS4271_MODE2_PDN, 0);
453 if (ret < 0)
454 return ret;
455 return 0;
456}
457#else
458#define cs4271_soc_suspend NULL
459#define cs4271_soc_resume NULL
460#endif /* CONFIG_PM */
461
462static int cs4271_probe(struct snd_soc_codec *codec)
463{
464 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
465 struct cs4271_platform_data *cs4271plat = codec->dev->platform_data;
466 int ret;
467 int gpio_nreset = -EINVAL;
468
469 codec->control_data = cs4271->control_data;
470
471 if (cs4271plat && gpio_is_valid(cs4271plat->gpio_nreset))
472 gpio_nreset = cs4271plat->gpio_nreset;
473
474 if (gpio_nreset >= 0)
475 if (gpio_request(gpio_nreset, "CS4271 Reset"))
476 gpio_nreset = -EINVAL;
477 if (gpio_nreset >= 0) {
478 /* Reset codec */
479 gpio_direction_output(gpio_nreset, 0);
480 udelay(1);
481 gpio_set_value(gpio_nreset, 1);
482 /* Give the codec time to wake up */
483 udelay(1);
484 }
485
486 cs4271->gpio_nreset = gpio_nreset;
487
488 /*
489 * In case of I2C, chip address specified in board data.
490 * So cache IO operations use 8 bit codec register address.
491 * In case of SPI, chip address and register address
492 * passed together as 16 bit value.
493 * Anyway, register address is masked with 0xFF inside
494 * soc-cache code.
495 */
496 if (cs4271->bus_type == SND_SOC_SPI)
497 ret = snd_soc_codec_set_cache_io(codec, 16, 8,
498 cs4271->bus_type);
499 else
500 ret = snd_soc_codec_set_cache_io(codec, 8, 8,
501 cs4271->bus_type);
502 if (ret) {
503 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
504 return ret;
505 }
506
507 ret = snd_soc_update_bits(codec, CS4271_MODE2, 0,
508 CS4271_MODE2_PDN | CS4271_MODE2_CPEN);
509 if (ret < 0)
510 return ret;
511 ret = snd_soc_update_bits(codec, CS4271_MODE2, CS4271_MODE2_PDN, 0);
512 if (ret < 0)
513 return ret;
514 /* Power-up sequence requires 85 uS */
515 udelay(85);
516
517 return snd_soc_add_controls(codec, cs4271_snd_controls,
518 ARRAY_SIZE(cs4271_snd_controls));
519}
520
521static int cs4271_remove(struct snd_soc_codec *codec)
522{
523 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
524 int gpio_nreset;
525
526 gpio_nreset = cs4271->gpio_nreset;
527
528 if (gpio_is_valid(gpio_nreset)) {
529 /* Set codec to the reset state */
530 gpio_set_value(gpio_nreset, 0);
531 gpio_free(gpio_nreset);
532 }
533
534 return 0;
535};
536
537static struct snd_soc_codec_driver soc_codec_dev_cs4271 = {
538 .probe = cs4271_probe,
539 .remove = cs4271_remove,
540 .suspend = cs4271_soc_suspend,
541 .resume = cs4271_soc_resume,
542 .reg_cache_default = cs4271_dflt_reg,
543 .reg_cache_size = ARRAY_SIZE(cs4271_dflt_reg),
544 .reg_word_size = sizeof(cs4271_dflt_reg[0]),
545 .compress_type = SND_SOC_FLAT_COMPRESSION,
546};
547
548#if defined(CONFIG_SPI_MASTER)
549static int __devinit cs4271_spi_probe(struct spi_device *spi)
550{
551 struct cs4271_private *cs4271;
552
553 cs4271 = devm_kzalloc(&spi->dev, sizeof(*cs4271), GFP_KERNEL);
554 if (!cs4271)
555 return -ENOMEM;
556
557 spi_set_drvdata(spi, cs4271);
558 cs4271->control_data = spi;
559 cs4271->bus_type = SND_SOC_SPI;
560
561 return snd_soc_register_codec(&spi->dev, &soc_codec_dev_cs4271,
562 &cs4271_dai, 1);
563}
564
565static int __devexit cs4271_spi_remove(struct spi_device *spi)
566{
567 snd_soc_unregister_codec(&spi->dev);
568 return 0;
569}
570
571static struct spi_driver cs4271_spi_driver = {
572 .driver = {
573 .name = "cs4271",
574 .owner = THIS_MODULE,
575 },
576 .probe = cs4271_spi_probe,
577 .remove = __devexit_p(cs4271_spi_remove),
578};
579#endif /* defined(CONFIG_SPI_MASTER) */
580
581#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
582static const struct i2c_device_id cs4271_i2c_id[] = {
583 {"cs4271", 0},
584 {}
585};
586MODULE_DEVICE_TABLE(i2c, cs4271_i2c_id);
587
588static int __devinit cs4271_i2c_probe(struct i2c_client *client,
589 const struct i2c_device_id *id)
590{
591 struct cs4271_private *cs4271;
592
593 cs4271 = devm_kzalloc(&client->dev, sizeof(*cs4271), GFP_KERNEL);
594 if (!cs4271)
595 return -ENOMEM;
596
597 i2c_set_clientdata(client, cs4271);
598 cs4271->control_data = client;
599 cs4271->bus_type = SND_SOC_I2C;
600
601 return snd_soc_register_codec(&client->dev, &soc_codec_dev_cs4271,
602 &cs4271_dai, 1);
603}
604
605static int __devexit cs4271_i2c_remove(struct i2c_client *client)
606{
607 snd_soc_unregister_codec(&client->dev);
608 return 0;
609}
610
611static struct i2c_driver cs4271_i2c_driver = {
612 .driver = {
613 .name = "cs4271",
614 .owner = THIS_MODULE,
615 },
616 .id_table = cs4271_i2c_id,
617 .probe = cs4271_i2c_probe,
618 .remove = __devexit_p(cs4271_i2c_remove),
619};
620#endif /* defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) */
621
622/*
623 * We only register our serial bus driver here without
624 * assignment to particular chip. So if any of the below
625 * fails, there is some problem with I2C or SPI subsystem.
626 * In most cases this module will be compiled with support
627 * of only one serial bus.
628 */
629static int __init cs4271_modinit(void)
630{
631 int ret;
632
633#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
634 ret = i2c_add_driver(&cs4271_i2c_driver);
635 if (ret) {
636 pr_err("Failed to register CS4271 I2C driver: %d\n", ret);
637 return ret;
638 }
639#endif
640
641#if defined(CONFIG_SPI_MASTER)
642 ret = spi_register_driver(&cs4271_spi_driver);
643 if (ret) {
644 pr_err("Failed to register CS4271 SPI driver: %d\n", ret);
645 return ret;
646 }
647#endif
648
649 return 0;
650}
651module_init(cs4271_modinit);
652
653static void __exit cs4271_modexit(void)
654{
655#if defined(CONFIG_SPI_MASTER)
656 spi_unregister_driver(&cs4271_spi_driver);
657#endif
658
659#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
660 i2c_del_driver(&cs4271_i2c_driver);
661#endif
662}
663module_exit(cs4271_modexit);
664
665MODULE_AUTHOR("Alexander Sverdlin <subaparts@yandex.ru>");
666MODULE_DESCRIPTION("Cirrus Logic CS4271 ALSA SoC Codec Driver");
667MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/dfbmcs320.c b/sound/soc/codecs/dfbmcs320.c
new file mode 100644
index 000000000000..704bbde65737
--- /dev/null
+++ b/sound/soc/codecs/dfbmcs320.c
@@ -0,0 +1,72 @@
1/*
2 * Driver for the DFBM-CS320 bluetooth module
3 * Copyright 2011 Lars-Peter Clausen <lars@metafoo.de>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 */
11
12#include <linux/init.h>
13#include <linux/module.h>
14#include <linux/platform_device.h>
15
16#include <sound/soc.h>
17
18static struct snd_soc_dai_driver dfbmcs320_dai = {
19 .name = "dfbmcs320-pcm",
20 .playback = {
21 .channels_min = 1,
22 .channels_max = 1,
23 .rates = SNDRV_PCM_RATE_8000,
24 .formats = SNDRV_PCM_FMTBIT_S16_LE,
25 },
26 .capture = {
27 .channels_min = 1,
28 .channels_max = 1,
29 .rates = SNDRV_PCM_RATE_8000,
30 .formats = SNDRV_PCM_FMTBIT_S16_LE,
31 },
32};
33
34static struct snd_soc_codec_driver soc_codec_dev_dfbmcs320;
35
36static int __devinit dfbmcs320_probe(struct platform_device *pdev)
37{
38 return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_dfbmcs320,
39 &dfbmcs320_dai, 1);
40}
41
42static int __devexit dfbmcs320_remove(struct platform_device *pdev)
43{
44 snd_soc_unregister_codec(&pdev->dev);
45
46 return 0;
47}
48
49static struct platform_driver dfmcs320_driver = {
50 .driver = {
51 .name = "dfbmcs320",
52 .owner = THIS_MODULE,
53 },
54 .probe = dfbmcs320_probe,
55 .remove = __devexit_p(dfbmcs320_remove),
56};
57
58static int __init dfbmcs320_init(void)
59{
60 return platform_driver_register(&dfmcs320_driver);
61}
62module_init(dfbmcs320_init);
63
64static void __exit dfbmcs320_exit(void)
65{
66 platform_driver_unregister(&dfmcs320_driver);
67}
68module_exit(dfbmcs320_exit);
69
70MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
71MODULE_DESCRIPTION("ASoC DFBM-CS320 bluethooth module driver");
72MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/lm4857.c b/sound/soc/codecs/lm4857.c
new file mode 100644
index 000000000000..72de47e5d040
--- /dev/null
+++ b/sound/soc/codecs/lm4857.c
@@ -0,0 +1,276 @@
1/*
2 * LM4857 AMP driver
3 *
4 * Copyright 2007 Wolfson Microelectronics PLC.
5 * Author: Graeme Gregory
6 * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
7 * Copyright 2011 Lars-Peter Clausen <lars@metafoo.de>
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 *
14 */
15
16#include <linux/init.h>
17#include <linux/module.h>
18#include <linux/i2c.h>
19#include <linux/slab.h>
20
21#include <sound/core.h>
22#include <sound/soc.h>
23#include <sound/tlv.h>
24
25struct lm4857 {
26 struct i2c_client *i2c;
27 uint8_t mode;
28};
29
30static const uint8_t lm4857_default_regs[] = {
31 0x00, 0x00, 0x00, 0x00,
32};
33
34/* The register offsets in the cache array */
35#define LM4857_MVOL 0
36#define LM4857_LVOL 1
37#define LM4857_RVOL 2
38#define LM4857_CTRL 3
39
40/* the shifts required to set these bits */
41#define LM4857_3D 5
42#define LM4857_WAKEUP 5
43#define LM4857_EPGAIN 4
44
45static int lm4857_write(struct snd_soc_codec *codec, unsigned int reg,
46 unsigned int value)
47{
48 uint8_t data;
49 int ret;
50
51 ret = snd_soc_cache_write(codec, reg, value);
52 if (ret < 0)
53 return ret;
54
55 data = (reg << 6) | value;
56 ret = i2c_master_send(codec->control_data, &data, 1);
57 if (ret != 1) {
58 dev_err(codec->dev, "Failed to write register: %d\n", ret);
59 return ret;
60 }
61
62 return 0;
63}
64
65static unsigned int lm4857_read(struct snd_soc_codec *codec,
66 unsigned int reg)
67{
68 unsigned int val;
69 int ret;
70
71 ret = snd_soc_cache_read(codec, reg, &val);
72 if (ret)
73 return -1;
74
75 return val;
76}
77
78static int lm4857_get_mode(struct snd_kcontrol *kcontrol,
79 struct snd_ctl_elem_value *ucontrol)
80{
81 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
82 struct lm4857 *lm4857 = snd_soc_codec_get_drvdata(codec);
83
84 ucontrol->value.integer.value[0] = lm4857->mode;
85
86 return 0;
87}
88
89static int lm4857_set_mode(struct snd_kcontrol *kcontrol,
90 struct snd_ctl_elem_value *ucontrol)
91{
92 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
93 struct lm4857 *lm4857 = snd_soc_codec_get_drvdata(codec);
94 uint8_t value = ucontrol->value.integer.value[0];
95
96 lm4857->mode = value;
97
98 if (codec->dapm.bias_level == SND_SOC_BIAS_ON)
99 snd_soc_update_bits(codec, LM4857_CTRL, 0x0F, value + 6);
100
101 return 1;
102}
103
104static int lm4857_set_bias_level(struct snd_soc_codec *codec,
105 enum snd_soc_bias_level level)
106{
107 struct lm4857 *lm4857 = snd_soc_codec_get_drvdata(codec);
108
109 switch (level) {
110 case SND_SOC_BIAS_ON:
111 snd_soc_update_bits(codec, LM4857_CTRL, 0x0F, lm4857->mode + 6);
112 break;
113 case SND_SOC_BIAS_STANDBY:
114 snd_soc_update_bits(codec, LM4857_CTRL, 0x0F, 0);
115 break;
116 default:
117 break;
118 }
119
120 codec->dapm.bias_level = level;
121
122 return 0;
123}
124
125static const char *lm4857_mode[] = {
126 "Earpiece",
127 "Loudspeaker",
128 "Loudspeaker + Headphone",
129 "Headphone",
130};
131
132static const struct soc_enum lm4857_mode_enum =
133 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(lm4857_mode), lm4857_mode);
134
135static const struct snd_soc_dapm_widget lm4857_dapm_widgets[] = {
136 SND_SOC_DAPM_INPUT("IN"),
137
138 SND_SOC_DAPM_OUTPUT("LS"),
139 SND_SOC_DAPM_OUTPUT("HP"),
140 SND_SOC_DAPM_OUTPUT("EP"),
141};
142
143static const DECLARE_TLV_DB_SCALE(stereo_tlv, -4050, 150, 0);
144static const DECLARE_TLV_DB_SCALE(mono_tlv, -3450, 150, 0);
145
146static const struct snd_kcontrol_new lm4857_controls[] = {
147 SOC_SINGLE_TLV("Left Playback Volume", LM4857_LVOL, 0, 31, 0,
148 stereo_tlv),
149 SOC_SINGLE_TLV("Right Playback Volume", LM4857_RVOL, 0, 31, 0,
150 stereo_tlv),
151 SOC_SINGLE_TLV("Mono Playback Volume", LM4857_MVOL, 0, 31, 0,
152 mono_tlv),
153 SOC_SINGLE("Spk 3D Playback Switch", LM4857_LVOL, LM4857_3D, 1, 0),
154 SOC_SINGLE("HP 3D Playback Switch", LM4857_RVOL, LM4857_3D, 1, 0),
155 SOC_SINGLE("Fast Wakeup Playback Switch", LM4857_CTRL,
156 LM4857_WAKEUP, 1, 0),
157 SOC_SINGLE("Earpiece 6dB Playback Switch", LM4857_CTRL,
158 LM4857_EPGAIN, 1, 0),
159
160 SOC_ENUM_EXT("Mode", lm4857_mode_enum,
161 lm4857_get_mode, lm4857_set_mode),
162};
163
164/* There is a demux inbetween the the input signal and the output signals.
165 * Currently there is no easy way to model it in ASoC and since it does not make
166 * much of a difference in practice simply connect the input direclty to the
167 * outputs. */
168static const struct snd_soc_dapm_route lm4857_routes[] = {
169 {"LS", NULL, "IN"},
170 {"HP", NULL, "IN"},
171 {"EP", NULL, "IN"},
172};
173
174static int lm4857_probe(struct snd_soc_codec *codec)
175{
176 struct lm4857 *lm4857 = snd_soc_codec_get_drvdata(codec);
177 struct snd_soc_dapm_context *dapm = &codec->dapm;
178 int ret;
179
180 codec->control_data = lm4857->i2c;
181
182 ret = snd_soc_add_controls(codec, lm4857_controls,
183 ARRAY_SIZE(lm4857_controls));
184 if (ret)
185 return ret;
186
187 ret = snd_soc_dapm_new_controls(dapm, lm4857_dapm_widgets,
188 ARRAY_SIZE(lm4857_dapm_widgets));
189 if (ret)
190 return ret;
191
192 ret = snd_soc_dapm_add_routes(dapm, lm4857_routes,
193 ARRAY_SIZE(lm4857_routes));
194 if (ret)
195 return ret;
196
197 snd_soc_dapm_new_widgets(dapm);
198
199 return 0;
200}
201
202static struct snd_soc_codec_driver soc_codec_dev_lm4857 = {
203 .write = lm4857_write,
204 .read = lm4857_read,
205 .probe = lm4857_probe,
206 .reg_cache_size = ARRAY_SIZE(lm4857_default_regs),
207 .reg_word_size = sizeof(uint8_t),
208 .reg_cache_default = lm4857_default_regs,
209 .set_bias_level = lm4857_set_bias_level,
210};
211
212static int __devinit lm4857_i2c_probe(struct i2c_client *i2c,
213 const struct i2c_device_id *id)
214{
215 struct lm4857 *lm4857;
216 int ret;
217
218 lm4857 = kzalloc(sizeof(*lm4857), GFP_KERNEL);
219 if (!lm4857)
220 return -ENOMEM;
221
222 i2c_set_clientdata(i2c, lm4857);
223
224 lm4857->i2c = i2c;
225
226 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_lm4857, NULL, 0);
227
228 if (ret) {
229 kfree(lm4857);
230 return ret;
231 }
232
233 return 0;
234}
235
236static int __devexit lm4857_i2c_remove(struct i2c_client *i2c)
237{
238 struct lm4857 *lm4857 = i2c_get_clientdata(i2c);
239
240 snd_soc_unregister_codec(&i2c->dev);
241 kfree(lm4857);
242
243 return 0;
244}
245
246static const struct i2c_device_id lm4857_i2c_id[] = {
247 { "lm4857", 0 },
248 { }
249};
250MODULE_DEVICE_TABLE(i2c, lm4857_i2c_id);
251
252static struct i2c_driver lm4857_i2c_driver = {
253 .driver = {
254 .name = "lm4857",
255 .owner = THIS_MODULE,
256 },
257 .probe = lm4857_i2c_probe,
258 .remove = __devexit_p(lm4857_i2c_remove),
259 .id_table = lm4857_i2c_id,
260};
261
262static int __init lm4857_init(void)
263{
264 return i2c_add_driver(&lm4857_i2c_driver);
265}
266module_init(lm4857_init);
267
268static void __exit lm4857_exit(void)
269{
270 i2c_del_driver(&lm4857_i2c_driver);
271}
272module_exit(lm4857_exit);
273
274MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
275MODULE_DESCRIPTION("LM4857 amplifier driver");
276MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c
index 89498f9ad2e5..bd0517cb7980 100644
--- a/sound/soc/codecs/max98088.c
+++ b/sound/soc/codecs/max98088.c
@@ -608,7 +608,7 @@ static struct {
608 { 0xFF, 0x00, 1 }, /* FF */ 608 { 0xFF, 0x00, 1 }, /* FF */
609}; 609};
610 610
611static int max98088_volatile_register(unsigned int reg) 611static int max98088_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
612{ 612{
613 return max98088_access[reg].vol; 613 return max98088_access[reg].vol;
614} 614}
diff --git a/sound/soc/codecs/max9850.c b/sound/soc/codecs/max9850.c
new file mode 100644
index 000000000000..208d2ee61855
--- /dev/null
+++ b/sound/soc/codecs/max9850.c
@@ -0,0 +1,389 @@
1/*
2 * max9850.c -- codec driver for max9850
3 *
4 * Copyright (C) 2011 taskit GmbH
5 *
6 * Author: Christian Glindkamp <christian.glindkamp@taskit.de>
7 *
8 * Initial development of this code was funded by
9 * MICRONIC Computer Systeme GmbH, http://www.mcsberlin.de/
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 *
16 */
17
18#include <linux/module.h>
19#include <linux/init.h>
20#include <linux/i2c.h>
21#include <linux/slab.h>
22#include <sound/pcm.h>
23#include <sound/pcm_params.h>
24#include <sound/soc.h>
25#include <sound/tlv.h>
26
27#include "max9850.h"
28
29struct max9850_priv {
30 unsigned int sysclk;
31};
32
33/* max9850 register cache */
34static const u8 max9850_reg[MAX9850_CACHEREGNUM] = {
35 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
36};
37
38/* these registers are not used at the moment but provided for the sake of
39 * completeness */
40static int max9850_volatile_register(struct snd_soc_codec *codec,
41 unsigned int reg)
42{
43 switch (reg) {
44 case MAX9850_STATUSA:
45 case MAX9850_STATUSB:
46 return 1;
47 default:
48 return 0;
49 }
50}
51
52static const unsigned int max9850_tlv[] = {
53 TLV_DB_RANGE_HEAD(4),
54 0x18, 0x1f, TLV_DB_SCALE_ITEM(-7450, 400, 0),
55 0x20, 0x33, TLV_DB_SCALE_ITEM(-4150, 200, 0),
56 0x34, 0x37, TLV_DB_SCALE_ITEM(-150, 100, 0),
57 0x38, 0x3f, TLV_DB_SCALE_ITEM(250, 50, 0),
58};
59
60static const struct snd_kcontrol_new max9850_controls[] = {
61SOC_SINGLE_TLV("Headphone Volume", MAX9850_VOLUME, 0, 0x3f, 1, max9850_tlv),
62SOC_SINGLE("Headphone Switch", MAX9850_VOLUME, 7, 1, 1),
63SOC_SINGLE("Mono Switch", MAX9850_GENERAL_PURPOSE, 2, 1, 0),
64};
65
66static const struct snd_kcontrol_new max9850_mixer_controls[] = {
67 SOC_DAPM_SINGLE("Line In Switch", MAX9850_ENABLE, 1, 1, 0),
68};
69
70static const struct snd_soc_dapm_widget max9850_dapm_widgets[] = {
71SND_SOC_DAPM_SUPPLY("Charge Pump 1", MAX9850_ENABLE, 4, 0, NULL, 0),
72SND_SOC_DAPM_SUPPLY("Charge Pump 2", MAX9850_ENABLE, 5, 0, NULL, 0),
73SND_SOC_DAPM_SUPPLY("MCLK", MAX9850_ENABLE, 6, 0, NULL, 0),
74SND_SOC_DAPM_SUPPLY("SHDN", MAX9850_ENABLE, 7, 0, NULL, 0),
75SND_SOC_DAPM_MIXER_NAMED_CTL("Output Mixer", MAX9850_ENABLE, 2, 0,
76 &max9850_mixer_controls[0],
77 ARRAY_SIZE(max9850_mixer_controls)),
78SND_SOC_DAPM_PGA("Headphone Output", MAX9850_ENABLE, 3, 0, NULL, 0),
79SND_SOC_DAPM_DAC("DAC", "HiFi Playback", MAX9850_ENABLE, 0, 0),
80SND_SOC_DAPM_OUTPUT("OUTL"),
81SND_SOC_DAPM_OUTPUT("HPL"),
82SND_SOC_DAPM_OUTPUT("OUTR"),
83SND_SOC_DAPM_OUTPUT("HPR"),
84SND_SOC_DAPM_MIXER("Line Input", SND_SOC_NOPM, 0, 0, NULL, 0),
85SND_SOC_DAPM_INPUT("INL"),
86SND_SOC_DAPM_INPUT("INR"),
87};
88
89static const struct snd_soc_dapm_route intercon[] = {
90 /* output mixer */
91 {"Output Mixer", NULL, "DAC"},
92 {"Output Mixer", "Line In Switch", "Line Input"},
93
94 /* outputs */
95 {"Headphone Output", NULL, "Output Mixer"},
96 {"HPL", NULL, "Headphone Output"},
97 {"HPR", NULL, "Headphone Output"},
98 {"OUTL", NULL, "Output Mixer"},
99 {"OUTR", NULL, "Output Mixer"},
100
101 /* inputs */
102 {"Line Input", NULL, "INL"},
103 {"Line Input", NULL, "INR"},
104
105 /* supplies */
106 {"Output Mixer", NULL, "Charge Pump 1"},
107 {"Output Mixer", NULL, "Charge Pump 2"},
108 {"Output Mixer", NULL, "SHDN"},
109 {"DAC", NULL, "MCLK"},
110};
111
112static int max9850_hw_params(struct snd_pcm_substream *substream,
113 struct snd_pcm_hw_params *params,
114 struct snd_soc_dai *dai)
115{
116 struct snd_soc_codec *codec = dai->codec;
117 struct max9850_priv *max9850 = snd_soc_codec_get_drvdata(codec);
118 u64 lrclk_div;
119 u8 sf, da;
120
121 if (!max9850->sysclk)
122 return -EINVAL;
123
124 /* lrclk_div = 2^22 * rate / iclk with iclk = mclk / sf */
125 sf = (snd_soc_read(codec, MAX9850_CLOCK) >> 2) + 1;
126 lrclk_div = (1 << 22);
127 lrclk_div *= params_rate(params);
128 lrclk_div *= sf;
129 do_div(lrclk_div, max9850->sysclk);
130
131 snd_soc_write(codec, MAX9850_LRCLK_MSB, (lrclk_div >> 8) & 0x7f);
132 snd_soc_write(codec, MAX9850_LRCLK_LSB, lrclk_div & 0xff);
133
134 switch (params_format(params)) {
135 case SNDRV_PCM_FORMAT_S16_LE:
136 da = 0;
137 break;
138 case SNDRV_PCM_FORMAT_S20_3LE:
139 da = 0x2;
140 break;
141 case SNDRV_PCM_FORMAT_S24_LE:
142 da = 0x3;
143 break;
144 default:
145 return -EINVAL;
146 }
147 snd_soc_update_bits(codec, MAX9850_DIGITAL_AUDIO, 0x3, da);
148
149 return 0;
150}
151
152static int max9850_set_dai_sysclk(struct snd_soc_dai *codec_dai,
153 int clk_id, unsigned int freq, int dir)
154{
155 struct snd_soc_codec *codec = codec_dai->codec;
156 struct max9850_priv *max9850 = snd_soc_codec_get_drvdata(codec);
157
158 /* calculate mclk -> iclk divider */
159 if (freq <= 13000000)
160 snd_soc_write(codec, MAX9850_CLOCK, 0x0);
161 else if (freq <= 26000000)
162 snd_soc_write(codec, MAX9850_CLOCK, 0x4);
163 else if (freq <= 40000000)
164 snd_soc_write(codec, MAX9850_CLOCK, 0x8);
165 else
166 return -EINVAL;
167
168 max9850->sysclk = freq;
169 return 0;
170}
171
172static int max9850_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
173{
174 struct snd_soc_codec *codec = codec_dai->codec;
175 u8 da = 0;
176
177 /* set master/slave audio interface */
178 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
179 case SND_SOC_DAIFMT_CBM_CFM:
180 da |= MAX9850_MASTER;
181 break;
182 case SND_SOC_DAIFMT_CBS_CFS:
183 break;
184 default:
185 return -EINVAL;
186 }
187
188 /* interface format */
189 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
190 case SND_SOC_DAIFMT_I2S:
191 da |= MAX9850_DLY;
192 break;
193 case SND_SOC_DAIFMT_RIGHT_J:
194 da |= MAX9850_RTJ;
195 break;
196 case SND_SOC_DAIFMT_LEFT_J:
197 break;
198 default:
199 return -EINVAL;
200 }
201
202 /* clock inversion */
203 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
204 case SND_SOC_DAIFMT_NB_NF:
205 break;
206 case SND_SOC_DAIFMT_IB_IF:
207 da |= MAX9850_BCINV | MAX9850_INV;
208 break;
209 case SND_SOC_DAIFMT_IB_NF:
210 da |= MAX9850_BCINV;
211 break;
212 case SND_SOC_DAIFMT_NB_IF:
213 da |= MAX9850_INV;
214 break;
215 default:
216 return -EINVAL;
217 }
218
219 /* set da */
220 snd_soc_write(codec, MAX9850_DIGITAL_AUDIO, da);
221
222 return 0;
223}
224
225static int max9850_set_bias_level(struct snd_soc_codec *codec,
226 enum snd_soc_bias_level level)
227{
228 int ret;
229
230 switch (level) {
231 case SND_SOC_BIAS_ON:
232 break;
233 case SND_SOC_BIAS_PREPARE:
234 break;
235 case SND_SOC_BIAS_STANDBY:
236 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
237 ret = snd_soc_cache_sync(codec);
238 if (ret) {
239 dev_err(codec->dev,
240 "Failed to sync cache: %d\n", ret);
241 return ret;
242 }
243 }
244 break;
245 case SND_SOC_BIAS_OFF:
246 break;
247 }
248 codec->dapm.bias_level = level;
249 return 0;
250}
251
252#define MAX9850_RATES SNDRV_PCM_RATE_8000_48000
253
254#define MAX9850_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
255 SNDRV_PCM_FMTBIT_S24_LE)
256
257static struct snd_soc_dai_ops max9850_dai_ops = {
258 .hw_params = max9850_hw_params,
259 .set_sysclk = max9850_set_dai_sysclk,
260 .set_fmt = max9850_set_dai_fmt,
261};
262
263static struct snd_soc_dai_driver max9850_dai = {
264 .name = "max9850-hifi",
265 .playback = {
266 .stream_name = "Playback",
267 .channels_min = 1,
268 .channels_max = 2,
269 .rates = MAX9850_RATES,
270 .formats = MAX9850_FORMATS
271 },
272 .ops = &max9850_dai_ops,
273};
274
275#ifdef CONFIG_PM
276static int max9850_suspend(struct snd_soc_codec *codec, pm_message_t state)
277{
278 max9850_set_bias_level(codec, SND_SOC_BIAS_OFF);
279
280 return 0;
281}
282
283static int max9850_resume(struct snd_soc_codec *codec)
284{
285 max9850_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
286
287 return 0;
288}
289#else
290#define max9850_suspend NULL
291#define max9850_resume NULL
292#endif
293
294static int max9850_probe(struct snd_soc_codec *codec)
295{
296 struct snd_soc_dapm_context *dapm = &codec->dapm;
297 int ret;
298
299 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
300 if (ret < 0) {
301 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
302 return ret;
303 }
304
305 /* enable zero-detect */
306 snd_soc_update_bits(codec, MAX9850_GENERAL_PURPOSE, 1, 1);
307 /* enable slew-rate control */
308 snd_soc_update_bits(codec, MAX9850_VOLUME, 0x40, 0x40);
309 /* set slew-rate 125ms */
310 snd_soc_update_bits(codec, MAX9850_CHARGE_PUMP, 0xff, 0xc0);
311
312 snd_soc_dapm_new_controls(dapm, max9850_dapm_widgets,
313 ARRAY_SIZE(max9850_dapm_widgets));
314 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
315
316 snd_soc_add_controls(codec, max9850_controls,
317 ARRAY_SIZE(max9850_controls));
318
319 return 0;
320}
321
322static struct snd_soc_codec_driver soc_codec_dev_max9850 = {
323 .probe = max9850_probe,
324 .suspend = max9850_suspend,
325 .resume = max9850_resume,
326 .set_bias_level = max9850_set_bias_level,
327 .reg_cache_size = ARRAY_SIZE(max9850_reg),
328 .reg_word_size = sizeof(u8),
329 .reg_cache_default = max9850_reg,
330 .volatile_register = max9850_volatile_register,
331};
332
333static int __devinit max9850_i2c_probe(struct i2c_client *i2c,
334 const struct i2c_device_id *id)
335{
336 struct max9850_priv *max9850;
337 int ret;
338
339 max9850 = kzalloc(sizeof(struct max9850_priv), GFP_KERNEL);
340 if (max9850 == NULL)
341 return -ENOMEM;
342
343 i2c_set_clientdata(i2c, max9850);
344
345 ret = snd_soc_register_codec(&i2c->dev,
346 &soc_codec_dev_max9850, &max9850_dai, 1);
347 if (ret < 0)
348 kfree(max9850);
349 return ret;
350}
351
352static __devexit int max9850_i2c_remove(struct i2c_client *client)
353{
354 snd_soc_unregister_codec(&client->dev);
355 kfree(i2c_get_clientdata(client));
356 return 0;
357}
358
359static const struct i2c_device_id max9850_i2c_id[] = {
360 { "max9850", 0 },
361 { }
362};
363MODULE_DEVICE_TABLE(i2c, max9850_i2c_id);
364
365static struct i2c_driver max9850_i2c_driver = {
366 .driver = {
367 .name = "max9850",
368 .owner = THIS_MODULE,
369 },
370 .probe = max9850_i2c_probe,
371 .remove = __devexit_p(max9850_i2c_remove),
372 .id_table = max9850_i2c_id,
373};
374
375static int __init max9850_init(void)
376{
377 return i2c_add_driver(&max9850_i2c_driver);
378}
379module_init(max9850_init);
380
381static void __exit max9850_exit(void)
382{
383 i2c_del_driver(&max9850_i2c_driver);
384}
385module_exit(max9850_exit);
386
387MODULE_AUTHOR("Christian Glindkamp <christian.glindkamp@taskit.de>");
388MODULE_DESCRIPTION("ASoC MAX9850 codec driver");
389MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/max9850.h b/sound/soc/codecs/max9850.h
new file mode 100644
index 000000000000..72b1ddb04b0d
--- /dev/null
+++ b/sound/soc/codecs/max9850.h
@@ -0,0 +1,38 @@
1/*
2 * max9850.h -- codec driver for max9850
3 *
4 * Copyright (C) 2011 taskit GmbH
5 * Author: Christian Glindkamp <christian.glindkamp@taskit.de>
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
14#ifndef _MAX9850_H
15#define _MAX9850_H
16
17#define MAX9850_STATUSA 0x00
18#define MAX9850_STATUSB 0x01
19#define MAX9850_VOLUME 0x02
20#define MAX9850_GENERAL_PURPOSE 0x03
21#define MAX9850_INTERRUPT 0x04
22#define MAX9850_ENABLE 0x05
23#define MAX9850_CLOCK 0x06
24#define MAX9850_CHARGE_PUMP 0x07
25#define MAX9850_LRCLK_MSB 0x08
26#define MAX9850_LRCLK_LSB 0x09
27#define MAX9850_DIGITAL_AUDIO 0x0a
28
29#define MAX9850_CACHEREGNUM 11
30
31/* MAX9850_DIGITAL_AUDIO */
32#define MAX9850_MASTER (1<<7)
33#define MAX9850_INV (1<<6)
34#define MAX9850_BCINV (1<<5)
35#define MAX9850_DLY (1<<3)
36#define MAX9850_RTJ (1<<2)
37
38#endif
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c
new file mode 100644
index 000000000000..1f7217f703ee
--- /dev/null
+++ b/sound/soc/codecs/sgtl5000.c
@@ -0,0 +1,1513 @@
1/*
2 * sgtl5000.c -- SGTL5000 ALSA SoC Audio driver
3 *
4 * Copyright 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved.
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/init.h>
14#include <linux/delay.h>
15#include <linux/slab.h>
16#include <linux/pm.h>
17#include <linux/i2c.h>
18#include <linux/clk.h>
19#include <linux/platform_device.h>
20#include <linux/regulator/driver.h>
21#include <linux/regulator/machine.h>
22#include <linux/regulator/consumer.h>
23#include <sound/core.h>
24#include <sound/tlv.h>
25#include <sound/pcm.h>
26#include <sound/pcm_params.h>
27#include <sound/soc.h>
28#include <sound/soc-dapm.h>
29#include <sound/initval.h>
30
31#include "sgtl5000.h"
32
33#define SGTL5000_DAP_REG_OFFSET 0x0100
34#define SGTL5000_MAX_REG_OFFSET 0x013A
35
36/* default value of sgtl5000 registers except DAP */
37static const u16 sgtl5000_regs[SGTL5000_MAX_REG_OFFSET >> 1] = {
38 0xa011, /* 0x0000, CHIP_ID. 11 stand for revison 17 */
39 0x0000, /* 0x0002, CHIP_DIG_POWER. */
40 0x0008, /* 0x0004, CHIP_CKL_CTRL */
41 0x0010, /* 0x0006, CHIP_I2S_CTRL */
42 0x0000, /* 0x0008, reserved */
43 0x0008, /* 0x000A, CHIP_SSS_CTRL */
44 0x0000, /* 0x000C, reserved */
45 0x020c, /* 0x000E, CHIP_ADCDAC_CTRL */
46 0x3c3c, /* 0x0010, CHIP_DAC_VOL */
47 0x0000, /* 0x0012, reserved */
48 0x015f, /* 0x0014, CHIP_PAD_STRENGTH */
49 0x0000, /* 0x0016, reserved */
50 0x0000, /* 0x0018, reserved */
51 0x0000, /* 0x001A, reserved */
52 0x0000, /* 0x001E, reserved */
53 0x0000, /* 0x0020, CHIP_ANA_ADC_CTRL */
54 0x1818, /* 0x0022, CHIP_ANA_HP_CTRL */
55 0x0111, /* 0x0024, CHIP_ANN_CTRL */
56 0x0000, /* 0x0026, CHIP_LINREG_CTRL */
57 0x0000, /* 0x0028, CHIP_REF_CTRL */
58 0x0000, /* 0x002A, CHIP_MIC_CTRL */
59 0x0000, /* 0x002C, CHIP_LINE_OUT_CTRL */
60 0x0404, /* 0x002E, CHIP_LINE_OUT_VOL */
61 0x7060, /* 0x0030, CHIP_ANA_POWER */
62 0x5000, /* 0x0032, CHIP_PLL_CTRL */
63 0x0000, /* 0x0034, CHIP_CLK_TOP_CTRL */
64 0x0000, /* 0x0036, CHIP_ANA_STATUS */
65 0x0000, /* 0x0038, reserved */
66 0x0000, /* 0x003A, CHIP_ANA_TEST2 */
67 0x0000, /* 0x003C, CHIP_SHORT_CTRL */
68 0x0000, /* reserved */
69};
70
71/* default value of dap registers */
72static const u16 sgtl5000_dap_regs[] = {
73 0x0000, /* 0x0100, DAP_CONTROL */
74 0x0000, /* 0x0102, DAP_PEQ */
75 0x0040, /* 0x0104, DAP_BASS_ENHANCE */
76 0x051f, /* 0x0106, DAP_BASS_ENHANCE_CTRL */
77 0x0000, /* 0x0108, DAP_AUDIO_EQ */
78 0x0040, /* 0x010A, DAP_SGTL_SURROUND */
79 0x0000, /* 0x010C, DAP_FILTER_COEF_ACCESS */
80 0x0000, /* 0x010E, DAP_COEF_WR_B0_MSB */
81 0x0000, /* 0x0110, DAP_COEF_WR_B0_LSB */
82 0x0000, /* 0x0112, reserved */
83 0x0000, /* 0x0114, reserved */
84 0x002f, /* 0x0116, DAP_AUDIO_EQ_BASS_BAND0 */
85 0x002f, /* 0x0118, DAP_AUDIO_EQ_BAND0 */
86 0x002f, /* 0x011A, DAP_AUDIO_EQ_BAND2 */
87 0x002f, /* 0x011C, DAP_AUDIO_EQ_BAND3 */
88 0x002f, /* 0x011E, DAP_AUDIO_EQ_TREBLE_BAND4 */
89 0x8000, /* 0x0120, DAP_MAIN_CHAN */
90 0x0000, /* 0x0122, DAP_MIX_CHAN */
91 0x0510, /* 0x0124, DAP_AVC_CTRL */
92 0x1473, /* 0x0126, DAP_AVC_THRESHOLD */
93 0x0028, /* 0x0128, DAP_AVC_ATTACK */
94 0x0050, /* 0x012A, DAP_AVC_DECAY */
95 0x0000, /* 0x012C, DAP_COEF_WR_B1_MSB */
96 0x0000, /* 0x012E, DAP_COEF_WR_B1_LSB */
97 0x0000, /* 0x0130, DAP_COEF_WR_B2_MSB */
98 0x0000, /* 0x0132, DAP_COEF_WR_B2_LSB */
99 0x0000, /* 0x0134, DAP_COEF_WR_A1_MSB */
100 0x0000, /* 0x0136, DAP_COEF_WR_A1_LSB */
101 0x0000, /* 0x0138, DAP_COEF_WR_A2_MSB */
102 0x0000, /* 0x013A, DAP_COEF_WR_A2_LSB */
103};
104
105/* regulator supplies for sgtl5000, VDDD is an optional external supply */
106enum sgtl5000_regulator_supplies {
107 VDDA,
108 VDDIO,
109 VDDD,
110 SGTL5000_SUPPLY_NUM
111};
112
113/* vddd is optional supply */
114static const char *supply_names[SGTL5000_SUPPLY_NUM] = {
115 "VDDA",
116 "VDDIO",
117 "VDDD"
118};
119
120#define LDO_CONSUMER_NAME "VDDD_LDO"
121#define LDO_VOLTAGE 1200000
122
123static struct regulator_consumer_supply ldo_consumer[] = {
124 REGULATOR_SUPPLY(LDO_CONSUMER_NAME, NULL),
125};
126
127static struct regulator_init_data ldo_init_data = {
128 .constraints = {
129 .min_uV = 850000,
130 .max_uV = 1600000,
131 .valid_modes_mask = REGULATOR_MODE_NORMAL,
132 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
133 },
134 .num_consumer_supplies = 1,
135 .consumer_supplies = &ldo_consumer[0],
136};
137
138/*
139 * sgtl5000 internal ldo regulator,
140 * enabled when VDDD not provided
141 */
142struct ldo_regulator {
143 struct regulator_desc desc;
144 struct regulator_dev *dev;
145 int voltage;
146 void *codec_data;
147 bool enabled;
148};
149
150/* sgtl5000 private structure in codec */
151struct sgtl5000_priv {
152 int sysclk; /* sysclk rate */
153 int master; /* i2s master or not */
154 int fmt; /* i2s data format */
155 struct regulator_bulk_data supplies[SGTL5000_SUPPLY_NUM];
156 struct ldo_regulator *ldo;
157};
158
159/*
160 * mic_bias power on/off share the same register bits with
161 * output impedance of mic bias, when power on mic bias, we
162 * need reclaim it to impedance value.
163 * 0x0 = Powered off
164 * 0x1 = 2Kohm
165 * 0x2 = 4Kohm
166 * 0x3 = 8Kohm
167 */
168static int mic_bias_event(struct snd_soc_dapm_widget *w,
169 struct snd_kcontrol *kcontrol, int event)
170{
171 switch (event) {
172 case SND_SOC_DAPM_POST_PMU:
173 /* change mic bias resistor to 4Kohm */
174 snd_soc_update_bits(w->codec, SGTL5000_CHIP_MIC_CTRL,
175 SGTL5000_BIAS_R_4k, SGTL5000_BIAS_R_4k);
176 break;
177
178 case SND_SOC_DAPM_PRE_PMD:
179 /*
180 * SGTL5000_BIAS_R_8k as mask to clean the two bits
181 * of mic bias and output impedance
182 */
183 snd_soc_update_bits(w->codec, SGTL5000_CHIP_MIC_CTRL,
184 SGTL5000_BIAS_R_8k, 0);
185 break;
186 }
187 return 0;
188}
189
190/*
191 * using codec assist to small pop, hp_powerup or lineout_powerup
192 * should stay setting until vag_powerup is fully ramped down,
193 * vag fully ramped down require 400ms.
194 */
195static int small_pop_event(struct snd_soc_dapm_widget *w,
196 struct snd_kcontrol *kcontrol, int event)
197{
198 switch (event) {
199 case SND_SOC_DAPM_PRE_PMU:
200 snd_soc_update_bits(w->codec, SGTL5000_CHIP_ANA_POWER,
201 SGTL5000_VAG_POWERUP, SGTL5000_VAG_POWERUP);
202 break;
203
204 case SND_SOC_DAPM_PRE_PMD:
205 snd_soc_update_bits(w->codec, SGTL5000_CHIP_ANA_POWER,
206 SGTL5000_VAG_POWERUP, 0);
207 msleep(400);
208 break;
209 default:
210 break;
211 }
212
213 return 0;
214}
215
216/* input sources for ADC */
217static const char *adc_mux_text[] = {
218 "MIC_IN", "LINE_IN"
219};
220
221static const struct soc_enum adc_enum =
222SOC_ENUM_SINGLE(SGTL5000_CHIP_ANA_CTRL, 2, 2, adc_mux_text);
223
224static const struct snd_kcontrol_new adc_mux =
225SOC_DAPM_ENUM("Capture Mux", adc_enum);
226
227/* input sources for DAC */
228static const char *dac_mux_text[] = {
229 "DAC", "LINE_IN"
230};
231
232static const struct soc_enum dac_enum =
233SOC_ENUM_SINGLE(SGTL5000_CHIP_ANA_CTRL, 6, 2, dac_mux_text);
234
235static const struct snd_kcontrol_new dac_mux =
236SOC_DAPM_ENUM("Headphone Mux", dac_enum);
237
238static const struct snd_soc_dapm_widget sgtl5000_dapm_widgets[] = {
239 SND_SOC_DAPM_INPUT("LINE_IN"),
240 SND_SOC_DAPM_INPUT("MIC_IN"),
241
242 SND_SOC_DAPM_OUTPUT("HP_OUT"),
243 SND_SOC_DAPM_OUTPUT("LINE_OUT"),
244
245 SND_SOC_DAPM_MICBIAS_E("Mic Bias", SGTL5000_CHIP_MIC_CTRL, 8, 0,
246 mic_bias_event,
247 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
248
249 SND_SOC_DAPM_PGA_E("HP", SGTL5000_CHIP_ANA_POWER, 4, 0, NULL, 0,
250 small_pop_event,
251 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
252 SND_SOC_DAPM_PGA_E("LO", SGTL5000_CHIP_ANA_POWER, 0, 0, NULL, 0,
253 small_pop_event,
254 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
255
256 SND_SOC_DAPM_MUX("Capture Mux", SND_SOC_NOPM, 0, 0, &adc_mux),
257 SND_SOC_DAPM_MUX("Headphone Mux", SND_SOC_NOPM, 0, 0, &dac_mux),
258
259 /* aif for i2s input */
260 SND_SOC_DAPM_AIF_IN("AIFIN", "Playback",
261 0, SGTL5000_CHIP_DIG_POWER,
262 0, 0),
263
264 /* aif for i2s output */
265 SND_SOC_DAPM_AIF_OUT("AIFOUT", "Capture",
266 0, SGTL5000_CHIP_DIG_POWER,
267 1, 0),
268
269 SND_SOC_DAPM_ADC("ADC", "Capture", SGTL5000_CHIP_ANA_POWER, 1, 0),
270
271 SND_SOC_DAPM_DAC("DAC", "Playback", SGTL5000_CHIP_ANA_POWER, 3, 0),
272};
273
274/* routes for sgtl5000 */
275static const struct snd_soc_dapm_route audio_map[] = {
276 {"Capture Mux", "LINE_IN", "LINE_IN"}, /* line_in --> adc_mux */
277 {"Capture Mux", "MIC_IN", "MIC_IN"}, /* mic_in --> adc_mux */
278
279 {"ADC", NULL, "Capture Mux"}, /* adc_mux --> adc */
280 {"AIFOUT", NULL, "ADC"}, /* adc --> i2s_out */
281
282 {"DAC", NULL, "AIFIN"}, /* i2s-->dac,skip audio mux */
283 {"Headphone Mux", "DAC", "DAC"}, /* dac --> hp_mux */
284 {"LO", NULL, "DAC"}, /* dac --> line_out */
285
286 {"Headphone Mux", "LINE_IN", "LINE_IN"},/* line_in --> hp_mux */
287 {"HP", NULL, "Headphone Mux"}, /* hp_mux --> hp */
288
289 {"LINE_OUT", NULL, "LO"},
290 {"HP_OUT", NULL, "HP"},
291};
292
293/* custom function to fetch info of PCM playback volume */
294static int dac_info_volsw(struct snd_kcontrol *kcontrol,
295 struct snd_ctl_elem_info *uinfo)
296{
297 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
298 uinfo->count = 2;
299 uinfo->value.integer.min = 0;
300 uinfo->value.integer.max = 0xfc - 0x3c;
301 return 0;
302}
303
304/*
305 * custom function to get of PCM playback volume
306 *
307 * dac volume register
308 * 15-------------8-7--------------0
309 * | R channel vol | L channel vol |
310 * -------------------------------
311 *
312 * PCM volume with 0.5017 dB steps from 0 to -90 dB
313 *
314 * register values map to dB
315 * 0x3B and less = Reserved
316 * 0x3C = 0 dB
317 * 0x3D = -0.5 dB
318 * 0xF0 = -90 dB
319 * 0xFC and greater = Muted
320 *
321 * register value map to userspace value
322 *
323 * register value 0x3c(0dB) 0xf0(-90dB)0xfc
324 * ------------------------------
325 * userspace value 0xc0 0
326 */
327static int dac_get_volsw(struct snd_kcontrol *kcontrol,
328 struct snd_ctl_elem_value *ucontrol)
329{
330 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
331 int reg;
332 int l;
333 int r;
334
335 reg = snd_soc_read(codec, SGTL5000_CHIP_DAC_VOL);
336
337 /* get left channel volume */
338 l = (reg & SGTL5000_DAC_VOL_LEFT_MASK) >> SGTL5000_DAC_VOL_LEFT_SHIFT;
339
340 /* get right channel volume */
341 r = (reg & SGTL5000_DAC_VOL_RIGHT_MASK) >> SGTL5000_DAC_VOL_RIGHT_SHIFT;
342
343 /* make sure value fall in (0x3c,0xfc) */
344 l = clamp(l, 0x3c, 0xfc);
345 r = clamp(r, 0x3c, 0xfc);
346
347 /* invert it and map to userspace value */
348 l = 0xfc - l;
349 r = 0xfc - r;
350
351 ucontrol->value.integer.value[0] = l;
352 ucontrol->value.integer.value[1] = r;
353
354 return 0;
355}
356
357/*
358 * custom function to put of PCM playback volume
359 *
360 * dac volume register
361 * 15-------------8-7--------------0
362 * | R channel vol | L channel vol |
363 * -------------------------------
364 *
365 * PCM volume with 0.5017 dB steps from 0 to -90 dB
366 *
367 * register values map to dB
368 * 0x3B and less = Reserved
369 * 0x3C = 0 dB
370 * 0x3D = -0.5 dB
371 * 0xF0 = -90 dB
372 * 0xFC and greater = Muted
373 *
374 * userspace value map to register value
375 *
376 * userspace value 0xc0 0
377 * ------------------------------
378 * register value 0x3c(0dB) 0xf0(-90dB)0xfc
379 */
380static int dac_put_volsw(struct snd_kcontrol *kcontrol,
381 struct snd_ctl_elem_value *ucontrol)
382{
383 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
384 int reg;
385 int l;
386 int r;
387
388 l = ucontrol->value.integer.value[0];
389 r = ucontrol->value.integer.value[1];
390
391 /* make sure userspace volume fall in (0, 0xfc-0x3c) */
392 l = clamp(l, 0, 0xfc - 0x3c);
393 r = clamp(r, 0, 0xfc - 0x3c);
394
395 /* invert it, get the value can be set to register */
396 l = 0xfc - l;
397 r = 0xfc - r;
398
399 /* shift to get the register value */
400 reg = l << SGTL5000_DAC_VOL_LEFT_SHIFT |
401 r << SGTL5000_DAC_VOL_RIGHT_SHIFT;
402
403 snd_soc_write(codec, SGTL5000_CHIP_DAC_VOL, reg);
404
405 return 0;
406}
407
408static const DECLARE_TLV_DB_SCALE(capture_6db_attenuate, -600, 600, 0);
409
410/* tlv for mic gain, 0db 20db 30db 40db */
411static const unsigned int mic_gain_tlv[] = {
412 TLV_DB_RANGE_HEAD(4),
413 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
414 1, 3, TLV_DB_SCALE_ITEM(2000, 1000, 0),
415};
416
417/* tlv for hp volume, -51.5db to 12.0db, step .5db */
418static const DECLARE_TLV_DB_SCALE(headphone_volume, -5150, 50, 0);
419
420static const struct snd_kcontrol_new sgtl5000_snd_controls[] = {
421 /* SOC_DOUBLE_S8_TLV with invert */
422 {
423 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
424 .name = "PCM Playback Volume",
425 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |
426 SNDRV_CTL_ELEM_ACCESS_READWRITE,
427 .info = dac_info_volsw,
428 .get = dac_get_volsw,
429 .put = dac_put_volsw,
430 },
431
432 SOC_DOUBLE("Capture Volume", SGTL5000_CHIP_ANA_ADC_CTRL, 0, 4, 0xf, 0),
433 SOC_SINGLE_TLV("Capture Attenuate Switch (-6dB)",
434 SGTL5000_CHIP_ANA_ADC_CTRL,
435 8, 2, 0, capture_6db_attenuate),
436 SOC_SINGLE("Capture ZC Switch", SGTL5000_CHIP_ANA_CTRL, 1, 1, 0),
437
438 SOC_DOUBLE_TLV("Headphone Playback Volume",
439 SGTL5000_CHIP_ANA_HP_CTRL,
440 0, 8,
441 0x7f, 1,
442 headphone_volume),
443 SOC_SINGLE("Headphone Playback ZC Switch", SGTL5000_CHIP_ANA_CTRL,
444 5, 1, 0),
445
446 SOC_SINGLE_TLV("Mic Volume", SGTL5000_CHIP_MIC_CTRL,
447 0, 4, 0, mic_gain_tlv),
448};
449
450/* mute the codec used by alsa core */
451static int sgtl5000_digital_mute(struct snd_soc_dai *codec_dai, int mute)
452{
453 struct snd_soc_codec *codec = codec_dai->codec;
454 u16 adcdac_ctrl = SGTL5000_DAC_MUTE_LEFT | SGTL5000_DAC_MUTE_RIGHT;
455
456 snd_soc_update_bits(codec, SGTL5000_CHIP_ADCDAC_CTRL,
457 adcdac_ctrl, mute ? adcdac_ctrl : 0);
458
459 return 0;
460}
461
462/* set codec format */
463static int sgtl5000_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
464{
465 struct snd_soc_codec *codec = codec_dai->codec;
466 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
467 u16 i2sctl = 0;
468
469 sgtl5000->master = 0;
470 /*
471 * i2s clock and frame master setting.
472 * ONLY support:
473 * - clock and frame slave,
474 * - clock and frame master
475 */
476 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
477 case SND_SOC_DAIFMT_CBS_CFS:
478 break;
479 case SND_SOC_DAIFMT_CBM_CFM:
480 i2sctl |= SGTL5000_I2S_MASTER;
481 sgtl5000->master = 1;
482 break;
483 default:
484 return -EINVAL;
485 }
486
487 /* setting i2s data format */
488 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
489 case SND_SOC_DAIFMT_DSP_A:
490 i2sctl |= SGTL5000_I2S_MODE_PCM;
491 break;
492 case SND_SOC_DAIFMT_DSP_B:
493 i2sctl |= SGTL5000_I2S_MODE_PCM;
494 i2sctl |= SGTL5000_I2S_LRALIGN;
495 break;
496 case SND_SOC_DAIFMT_I2S:
497 i2sctl |= SGTL5000_I2S_MODE_I2S_LJ;
498 break;
499 case SND_SOC_DAIFMT_RIGHT_J:
500 i2sctl |= SGTL5000_I2S_MODE_RJ;
501 i2sctl |= SGTL5000_I2S_LRPOL;
502 break;
503 case SND_SOC_DAIFMT_LEFT_J:
504 i2sctl |= SGTL5000_I2S_MODE_I2S_LJ;
505 i2sctl |= SGTL5000_I2S_LRALIGN;
506 break;
507 default:
508 return -EINVAL;
509 }
510
511 sgtl5000->fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
512
513 /* Clock inversion */
514 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
515 case SND_SOC_DAIFMT_NB_NF:
516 break;
517 case SND_SOC_DAIFMT_IB_NF:
518 i2sctl |= SGTL5000_I2S_SCLK_INV;
519 break;
520 default:
521 return -EINVAL;
522 }
523
524 snd_soc_write(codec, SGTL5000_CHIP_I2S_CTRL, i2sctl);
525
526 return 0;
527}
528
529/* set codec sysclk */
530static int sgtl5000_set_dai_sysclk(struct snd_soc_dai *codec_dai,
531 int clk_id, unsigned int freq, int dir)
532{
533 struct snd_soc_codec *codec = codec_dai->codec;
534 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
535
536 switch (clk_id) {
537 case SGTL5000_SYSCLK:
538 sgtl5000->sysclk = freq;
539 break;
540 default:
541 return -EINVAL;
542 }
543
544 return 0;
545}
546
547/*
548 * set clock according to i2s frame clock,
549 * sgtl5000 provide 2 clock sources.
550 * 1. sys_mclk. sample freq can only configure to
551 * 1/256, 1/384, 1/512 of sys_mclk.
552 * 2. pll. can derive any audio clocks.
553 *
554 * clock setting rules:
555 * 1. in slave mode, only sys_mclk can use.
556 * 2. as constraint by sys_mclk, sample freq should
557 * set to 32k, 44.1k and above.
558 * 3. using sys_mclk prefer to pll to save power.
559 */
560static int sgtl5000_set_clock(struct snd_soc_codec *codec, int frame_rate)
561{
562 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
563 int clk_ctl = 0;
564 int sys_fs; /* sample freq */
565
566 /*
567 * sample freq should be divided by frame clock,
568 * if frame clock lower than 44.1khz, sample feq should set to
569 * 32khz or 44.1khz.
570 */
571 switch (frame_rate) {
572 case 8000:
573 case 16000:
574 sys_fs = 32000;
575 break;
576 case 11025:
577 case 22050:
578 sys_fs = 44100;
579 break;
580 default:
581 sys_fs = frame_rate;
582 break;
583 }
584
585 /* set divided factor of frame clock */
586 switch (sys_fs / frame_rate) {
587 case 4:
588 clk_ctl |= SGTL5000_RATE_MODE_DIV_4 << SGTL5000_RATE_MODE_SHIFT;
589 break;
590 case 2:
591 clk_ctl |= SGTL5000_RATE_MODE_DIV_2 << SGTL5000_RATE_MODE_SHIFT;
592 break;
593 case 1:
594 clk_ctl |= SGTL5000_RATE_MODE_DIV_1 << SGTL5000_RATE_MODE_SHIFT;
595 break;
596 default:
597 return -EINVAL;
598 }
599
600 /* set the sys_fs according to frame rate */
601 switch (sys_fs) {
602 case 32000:
603 clk_ctl |= SGTL5000_SYS_FS_32k << SGTL5000_SYS_FS_SHIFT;
604 break;
605 case 44100:
606 clk_ctl |= SGTL5000_SYS_FS_44_1k << SGTL5000_SYS_FS_SHIFT;
607 break;
608 case 48000:
609 clk_ctl |= SGTL5000_SYS_FS_48k << SGTL5000_SYS_FS_SHIFT;
610 break;
611 case 96000:
612 clk_ctl |= SGTL5000_SYS_FS_96k << SGTL5000_SYS_FS_SHIFT;
613 break;
614 default:
615 dev_err(codec->dev, "frame rate %d not supported\n",
616 frame_rate);
617 return -EINVAL;
618 }
619
620 /*
621 * calculate the divider of mclk/sample_freq,
622 * factor of freq =96k can only be 256, since mclk in range (12m,27m)
623 */
624 switch (sgtl5000->sysclk / sys_fs) {
625 case 256:
626 clk_ctl |= SGTL5000_MCLK_FREQ_256FS <<
627 SGTL5000_MCLK_FREQ_SHIFT;
628 break;
629 case 384:
630 clk_ctl |= SGTL5000_MCLK_FREQ_384FS <<
631 SGTL5000_MCLK_FREQ_SHIFT;
632 break;
633 case 512:
634 clk_ctl |= SGTL5000_MCLK_FREQ_512FS <<
635 SGTL5000_MCLK_FREQ_SHIFT;
636 break;
637 default:
638 /* if mclk not satisify the divider, use pll */
639 if (sgtl5000->master) {
640 clk_ctl |= SGTL5000_MCLK_FREQ_PLL <<
641 SGTL5000_MCLK_FREQ_SHIFT;
642 } else {
643 dev_err(codec->dev,
644 "PLL not supported in slave mode\n");
645 return -EINVAL;
646 }
647 }
648
649 /* if using pll, please check manual 6.4.2 for detail */
650 if ((clk_ctl & SGTL5000_MCLK_FREQ_MASK) == SGTL5000_MCLK_FREQ_PLL) {
651 u64 out, t;
652 int div2;
653 int pll_ctl;
654 unsigned int in, int_div, frac_div;
655
656 if (sgtl5000->sysclk > 17000000) {
657 div2 = 1;
658 in = sgtl5000->sysclk / 2;
659 } else {
660 div2 = 0;
661 in = sgtl5000->sysclk;
662 }
663 if (sys_fs == 44100)
664 out = 180633600;
665 else
666 out = 196608000;
667 t = do_div(out, in);
668 int_div = out;
669 t *= 2048;
670 do_div(t, in);
671 frac_div = t;
672 pll_ctl = int_div << SGTL5000_PLL_INT_DIV_SHIFT |
673 frac_div << SGTL5000_PLL_FRAC_DIV_SHIFT;
674
675 snd_soc_write(codec, SGTL5000_CHIP_PLL_CTRL, pll_ctl);
676 if (div2)
677 snd_soc_update_bits(codec,
678 SGTL5000_CHIP_CLK_TOP_CTRL,
679 SGTL5000_INPUT_FREQ_DIV2,
680 SGTL5000_INPUT_FREQ_DIV2);
681 else
682 snd_soc_update_bits(codec,
683 SGTL5000_CHIP_CLK_TOP_CTRL,
684 SGTL5000_INPUT_FREQ_DIV2,
685 0);
686
687 /* power up pll */
688 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
689 SGTL5000_PLL_POWERUP | SGTL5000_VCOAMP_POWERUP,
690 SGTL5000_PLL_POWERUP | SGTL5000_VCOAMP_POWERUP);
691 } else {
692 /* power down pll */
693 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
694 SGTL5000_PLL_POWERUP | SGTL5000_VCOAMP_POWERUP,
695 0);
696 }
697
698 /* if using pll, clk_ctrl must be set after pll power up */
699 snd_soc_write(codec, SGTL5000_CHIP_CLK_CTRL, clk_ctl);
700
701 return 0;
702}
703
704/*
705 * Set PCM DAI bit size and sample rate.
706 * input: params_rate, params_fmt
707 */
708static int sgtl5000_pcm_hw_params(struct snd_pcm_substream *substream,
709 struct snd_pcm_hw_params *params,
710 struct snd_soc_dai *dai)
711{
712 struct snd_soc_pcm_runtime *rtd = substream->private_data;
713 struct snd_soc_codec *codec = rtd->codec;
714 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
715 int channels = params_channels(params);
716 int i2s_ctl = 0;
717 int stereo;
718 int ret;
719
720 /* sysclk should already set */
721 if (!sgtl5000->sysclk) {
722 dev_err(codec->dev, "%s: set sysclk first!\n", __func__);
723 return -EFAULT;
724 }
725
726 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
727 stereo = SGTL5000_DAC_STEREO;
728 else
729 stereo = SGTL5000_ADC_STEREO;
730
731 /* set mono to save power */
732 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER, stereo,
733 channels == 1 ? 0 : stereo);
734
735 /* set codec clock base on lrclk */
736 ret = sgtl5000_set_clock(codec, params_rate(params));
737 if (ret)
738 return ret;
739
740 /* set i2s data format */
741 switch (params_format(params)) {
742 case SNDRV_PCM_FORMAT_S16_LE:
743 if (sgtl5000->fmt == SND_SOC_DAIFMT_RIGHT_J)
744 return -EINVAL;
745 i2s_ctl |= SGTL5000_I2S_DLEN_16 << SGTL5000_I2S_DLEN_SHIFT;
746 i2s_ctl |= SGTL5000_I2S_SCLKFREQ_32FS <<
747 SGTL5000_I2S_SCLKFREQ_SHIFT;
748 break;
749 case SNDRV_PCM_FORMAT_S20_3LE:
750 i2s_ctl |= SGTL5000_I2S_DLEN_20 << SGTL5000_I2S_DLEN_SHIFT;
751 i2s_ctl |= SGTL5000_I2S_SCLKFREQ_64FS <<
752 SGTL5000_I2S_SCLKFREQ_SHIFT;
753 break;
754 case SNDRV_PCM_FORMAT_S24_LE:
755 i2s_ctl |= SGTL5000_I2S_DLEN_24 << SGTL5000_I2S_DLEN_SHIFT;
756 i2s_ctl |= SGTL5000_I2S_SCLKFREQ_64FS <<
757 SGTL5000_I2S_SCLKFREQ_SHIFT;
758 break;
759 case SNDRV_PCM_FORMAT_S32_LE:
760 if (sgtl5000->fmt == SND_SOC_DAIFMT_RIGHT_J)
761 return -EINVAL;
762 i2s_ctl |= SGTL5000_I2S_DLEN_32 << SGTL5000_I2S_DLEN_SHIFT;
763 i2s_ctl |= SGTL5000_I2S_SCLKFREQ_64FS <<
764 SGTL5000_I2S_SCLKFREQ_SHIFT;
765 break;
766 default:
767 return -EINVAL;
768 }
769
770 snd_soc_update_bits(codec, SGTL5000_CHIP_I2S_CTRL, i2s_ctl, i2s_ctl);
771
772 return 0;
773}
774
775static int ldo_regulator_is_enabled(struct regulator_dev *dev)
776{
777 struct ldo_regulator *ldo = rdev_get_drvdata(dev);
778
779 return ldo->enabled;
780}
781
782static int ldo_regulator_enable(struct regulator_dev *dev)
783{
784 struct ldo_regulator *ldo = rdev_get_drvdata(dev);
785 struct snd_soc_codec *codec = (struct snd_soc_codec *)ldo->codec_data;
786 int reg;
787
788 if (ldo_regulator_is_enabled(dev))
789 return 0;
790
791 /* set regulator value firstly */
792 reg = (1600 - ldo->voltage / 1000) / 50;
793 reg = clamp(reg, 0x0, 0xf);
794
795 /* amend the voltage value, unit: uV */
796 ldo->voltage = (1600 - reg * 50) * 1000;
797
798 /* set voltage to register */
799 snd_soc_update_bits(codec, SGTL5000_CHIP_LINREG_CTRL,
800 (0x1 << 4) - 1, reg);
801
802 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
803 SGTL5000_LINEREG_D_POWERUP,
804 SGTL5000_LINEREG_D_POWERUP);
805
806 /* when internal ldo enabled, simple digital power can be disabled */
807 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
808 SGTL5000_LINREG_SIMPLE_POWERUP,
809 0);
810
811 ldo->enabled = 1;
812 return 0;
813}
814
815static int ldo_regulator_disable(struct regulator_dev *dev)
816{
817 struct ldo_regulator *ldo = rdev_get_drvdata(dev);
818 struct snd_soc_codec *codec = (struct snd_soc_codec *)ldo->codec_data;
819
820 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
821 SGTL5000_LINEREG_D_POWERUP,
822 0);
823
824 /* clear voltage info */
825 snd_soc_update_bits(codec, SGTL5000_CHIP_LINREG_CTRL,
826 (0x1 << 4) - 1, 0);
827
828 ldo->enabled = 0;
829
830 return 0;
831}
832
833static int ldo_regulator_get_voltage(struct regulator_dev *dev)
834{
835 struct ldo_regulator *ldo = rdev_get_drvdata(dev);
836
837 return ldo->voltage;
838}
839
840static struct regulator_ops ldo_regulator_ops = {
841 .is_enabled = ldo_regulator_is_enabled,
842 .enable = ldo_regulator_enable,
843 .disable = ldo_regulator_disable,
844 .get_voltage = ldo_regulator_get_voltage,
845};
846
847static int ldo_regulator_register(struct snd_soc_codec *codec,
848 struct regulator_init_data *init_data,
849 int voltage)
850{
851 struct ldo_regulator *ldo;
852
853 ldo = kzalloc(sizeof(struct ldo_regulator), GFP_KERNEL);
854
855 if (!ldo) {
856 dev_err(codec->dev, "failed to allocate ldo_regulator\n");
857 return -ENOMEM;
858 }
859
860 ldo->desc.name = kstrdup(dev_name(codec->dev), GFP_KERNEL);
861 if (!ldo->desc.name) {
862 kfree(ldo);
863 dev_err(codec->dev, "failed to allocate decs name memory\n");
864 return -ENOMEM;
865 }
866
867 ldo->desc.type = REGULATOR_VOLTAGE;
868 ldo->desc.owner = THIS_MODULE;
869 ldo->desc.ops = &ldo_regulator_ops;
870 ldo->desc.n_voltages = 1;
871
872 ldo->codec_data = codec;
873 ldo->voltage = voltage;
874
875 ldo->dev = regulator_register(&ldo->desc, codec->dev,
876 init_data, ldo);
877 if (IS_ERR(ldo->dev)) {
878 int ret = PTR_ERR(ldo->dev);
879
880 dev_err(codec->dev, "failed to register regulator\n");
881 kfree(ldo->desc.name);
882 kfree(ldo);
883
884 return ret;
885 }
886
887 return 0;
888}
889
890static int ldo_regulator_remove(struct snd_soc_codec *codec)
891{
892 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
893 struct ldo_regulator *ldo = sgtl5000->ldo;
894
895 if (!ldo)
896 return 0;
897
898 regulator_unregister(ldo->dev);
899 kfree(ldo->desc.name);
900 kfree(ldo);
901
902 return 0;
903}
904
905/*
906 * set dac bias
907 * common state changes:
908 * startup:
909 * off --> standby --> prepare --> on
910 * standby --> prepare --> on
911 *
912 * stop:
913 * on --> prepare --> standby
914 */
915static int sgtl5000_set_bias_level(struct snd_soc_codec *codec,
916 enum snd_soc_bias_level level)
917{
918 int ret;
919 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
920
921 switch (level) {
922 case SND_SOC_BIAS_ON:
923 case SND_SOC_BIAS_PREPARE:
924 break;
925 case SND_SOC_BIAS_STANDBY:
926 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
927 ret = regulator_bulk_enable(
928 ARRAY_SIZE(sgtl5000->supplies),
929 sgtl5000->supplies);
930 if (ret)
931 return ret;
932 udelay(10);
933 }
934
935 break;
936 case SND_SOC_BIAS_OFF:
937 regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies),
938 sgtl5000->supplies);
939 break;
940 }
941
942 codec->dapm.bias_level = level;
943 return 0;
944}
945
946#define SGTL5000_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
947 SNDRV_PCM_FMTBIT_S20_3LE |\
948 SNDRV_PCM_FMTBIT_S24_LE |\
949 SNDRV_PCM_FMTBIT_S32_LE)
950
951static struct snd_soc_dai_ops sgtl5000_ops = {
952 .hw_params = sgtl5000_pcm_hw_params,
953 .digital_mute = sgtl5000_digital_mute,
954 .set_fmt = sgtl5000_set_dai_fmt,
955 .set_sysclk = sgtl5000_set_dai_sysclk,
956};
957
958static struct snd_soc_dai_driver sgtl5000_dai = {
959 .name = "sgtl5000",
960 .playback = {
961 .stream_name = "Playback",
962 .channels_min = 1,
963 .channels_max = 2,
964 /*
965 * only support 8~48K + 96K,
966 * TODO modify hw_param to support more
967 */
968 .rates = SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_96000,
969 .formats = SGTL5000_FORMATS,
970 },
971 .capture = {
972 .stream_name = "Capture",
973 .channels_min = 1,
974 .channels_max = 2,
975 .rates = SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_96000,
976 .formats = SGTL5000_FORMATS,
977 },
978 .ops = &sgtl5000_ops,
979 .symmetric_rates = 1,
980};
981
982static int sgtl5000_volatile_register(struct snd_soc_codec *codec,
983 unsigned int reg)
984{
985 switch (reg) {
986 case SGTL5000_CHIP_ID:
987 case SGTL5000_CHIP_ADCDAC_CTRL:
988 case SGTL5000_CHIP_ANA_STATUS:
989 return 1;
990 }
991
992 return 0;
993}
994
995#ifdef CONFIG_SUSPEND
996static int sgtl5000_suspend(struct snd_soc_codec *codec, pm_message_t state)
997{
998 sgtl5000_set_bias_level(codec, SND_SOC_BIAS_OFF);
999
1000 return 0;
1001}
1002
1003/*
1004 * restore all sgtl5000 registers,
1005 * since a big hole between dap and regular registers,
1006 * we will restore them respectively.
1007 */
1008static int sgtl5000_restore_regs(struct snd_soc_codec *codec)
1009{
1010 u16 *cache = codec->reg_cache;
1011 int i;
1012 int regular_regs = SGTL5000_CHIP_SHORT_CTRL >> 1;
1013
1014 /* restore regular registers */
1015 for (i = 0; i < regular_regs; i++) {
1016 int reg = i << 1;
1017
1018 /* this regs depends on the others */
1019 if (reg == SGTL5000_CHIP_ANA_POWER ||
1020 reg == SGTL5000_CHIP_CLK_CTRL ||
1021 reg == SGTL5000_CHIP_LINREG_CTRL ||
1022 reg == SGTL5000_CHIP_LINE_OUT_CTRL ||
1023 reg == SGTL5000_CHIP_CLK_CTRL)
1024 continue;
1025
1026 snd_soc_write(codec, reg, cache[i]);
1027 }
1028
1029 /* restore dap registers */
1030 for (i = SGTL5000_DAP_REG_OFFSET >> 1;
1031 i < SGTL5000_MAX_REG_OFFSET >> 1; i++) {
1032 int reg = i << 1;
1033
1034 snd_soc_write(codec, reg, cache[i]);
1035 }
1036
1037 /*
1038 * restore power and other regs according
1039 * to set_power() and set_clock()
1040 */
1041 snd_soc_write(codec, SGTL5000_CHIP_LINREG_CTRL,
1042 cache[SGTL5000_CHIP_LINREG_CTRL >> 1]);
1043
1044 snd_soc_write(codec, SGTL5000_CHIP_ANA_POWER,
1045 cache[SGTL5000_CHIP_ANA_POWER >> 1]);
1046
1047 snd_soc_write(codec, SGTL5000_CHIP_CLK_CTRL,
1048 cache[SGTL5000_CHIP_CLK_CTRL >> 1]);
1049
1050 snd_soc_write(codec, SGTL5000_CHIP_REF_CTRL,
1051 cache[SGTL5000_CHIP_REF_CTRL >> 1]);
1052
1053 snd_soc_write(codec, SGTL5000_CHIP_LINE_OUT_CTRL,
1054 cache[SGTL5000_CHIP_LINE_OUT_CTRL >> 1]);
1055 return 0;
1056}
1057
1058static int sgtl5000_resume(struct snd_soc_codec *codec)
1059{
1060 /* Bring the codec back up to standby to enable regulators */
1061 sgtl5000_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1062
1063 /* Restore registers by cached in memory */
1064 sgtl5000_restore_regs(codec);
1065 return 0;
1066}
1067#else
1068#define sgtl5000_suspend NULL
1069#define sgtl5000_resume NULL
1070#endif /* CONFIG_SUSPEND */
1071
1072/*
1073 * sgtl5000 has 3 internal power supplies:
1074 * 1. VAG, normally set to vdda/2
1075 * 2. chargepump, set to different value
1076 * according to voltage of vdda and vddio
1077 * 3. line out VAG, normally set to vddio/2
1078 *
1079 * and should be set according to:
1080 * 1. vddd provided by external or not
1081 * 2. vdda and vddio voltage value. > 3.1v or not
1082 * 3. chip revision >=0x11 or not. If >=0x11, not use external vddd.
1083 */
1084static int sgtl5000_set_power_regs(struct snd_soc_codec *codec)
1085{
1086 int vddd;
1087 int vdda;
1088 int vddio;
1089 u16 ana_pwr;
1090 u16 lreg_ctrl;
1091 int vag;
1092 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
1093
1094 vdda = regulator_get_voltage(sgtl5000->supplies[VDDA].consumer);
1095 vddio = regulator_get_voltage(sgtl5000->supplies[VDDIO].consumer);
1096 vddd = regulator_get_voltage(sgtl5000->supplies[VDDD].consumer);
1097
1098 vdda = vdda / 1000;
1099 vddio = vddio / 1000;
1100 vddd = vddd / 1000;
1101
1102 if (vdda <= 0 || vddio <= 0 || vddd < 0) {
1103 dev_err(codec->dev, "regulator voltage not set correctly\n");
1104
1105 return -EINVAL;
1106 }
1107
1108 /* according to datasheet, maximum voltage of supplies */
1109 if (vdda > 3600 || vddio > 3600 || vddd > 1980) {
1110 dev_err(codec->dev,
1111 "exceed max voltage vdda %dmv vddio %dma vddd %dma\n",
1112 vdda, vddio, vddd);
1113
1114 return -EINVAL;
1115 }
1116
1117 /* reset value */
1118 ana_pwr = snd_soc_read(codec, SGTL5000_CHIP_ANA_POWER);
1119 ana_pwr |= SGTL5000_DAC_STEREO |
1120 SGTL5000_ADC_STEREO |
1121 SGTL5000_REFTOP_POWERUP;
1122 lreg_ctrl = snd_soc_read(codec, SGTL5000_CHIP_LINREG_CTRL);
1123
1124 if (vddio < 3100 && vdda < 3100) {
1125 /* enable internal oscillator used for charge pump */
1126 snd_soc_update_bits(codec, SGTL5000_CHIP_CLK_TOP_CTRL,
1127 SGTL5000_INT_OSC_EN,
1128 SGTL5000_INT_OSC_EN);
1129 /* Enable VDDC charge pump */
1130 ana_pwr |= SGTL5000_VDDC_CHRGPMP_POWERUP;
1131 } else if (vddio >= 3100 && vdda >= 3100) {
1132 /*
1133 * if vddio and vddd > 3.1v,
1134 * charge pump should be clean before set ana_pwr
1135 */
1136 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
1137 SGTL5000_VDDC_CHRGPMP_POWERUP, 0);
1138
1139 /* VDDC use VDDIO rail */
1140 lreg_ctrl |= SGTL5000_VDDC_ASSN_OVRD;
1141 lreg_ctrl |= SGTL5000_VDDC_MAN_ASSN_VDDIO <<
1142 SGTL5000_VDDC_MAN_ASSN_SHIFT;
1143 }
1144
1145 snd_soc_write(codec, SGTL5000_CHIP_LINREG_CTRL, lreg_ctrl);
1146
1147 snd_soc_write(codec, SGTL5000_CHIP_ANA_POWER, ana_pwr);
1148
1149 /* set voltage to register */
1150 snd_soc_update_bits(codec, SGTL5000_CHIP_LINREG_CTRL,
1151 (0x1 << 4) - 1, 0x8);
1152
1153 /*
1154 * if vddd linear reg has been enabled,
1155 * simple digital supply should be clear to get
1156 * proper VDDD voltage.
1157 */
1158 if (ana_pwr & SGTL5000_LINEREG_D_POWERUP)
1159 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
1160 SGTL5000_LINREG_SIMPLE_POWERUP,
1161 0);
1162 else
1163 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
1164 SGTL5000_LINREG_SIMPLE_POWERUP |
1165 SGTL5000_STARTUP_POWERUP,
1166 0);
1167
1168 /*
1169 * set ADC/DAC VAG to vdda / 2,
1170 * should stay in range (0.8v, 1.575v)
1171 */
1172 vag = vdda / 2;
1173 if (vag <= SGTL5000_ANA_GND_BASE)
1174 vag = 0;
1175 else if (vag >= SGTL5000_ANA_GND_BASE + SGTL5000_ANA_GND_STP *
1176 (SGTL5000_ANA_GND_MASK >> SGTL5000_ANA_GND_SHIFT))
1177 vag = SGTL5000_ANA_GND_MASK >> SGTL5000_ANA_GND_SHIFT;
1178 else
1179 vag = (vag - SGTL5000_ANA_GND_BASE) / SGTL5000_ANA_GND_STP;
1180
1181 snd_soc_update_bits(codec, SGTL5000_CHIP_REF_CTRL,
1182 vag << SGTL5000_ANA_GND_SHIFT,
1183 vag << SGTL5000_ANA_GND_SHIFT);
1184
1185 /* set line out VAG to vddio / 2, in range (0.8v, 1.675v) */
1186 vag = vddio / 2;
1187 if (vag <= SGTL5000_LINE_OUT_GND_BASE)
1188 vag = 0;
1189 else if (vag >= SGTL5000_LINE_OUT_GND_BASE +
1190 SGTL5000_LINE_OUT_GND_STP * SGTL5000_LINE_OUT_GND_MAX)
1191 vag = SGTL5000_LINE_OUT_GND_MAX;
1192 else
1193 vag = (vag - SGTL5000_LINE_OUT_GND_BASE) /
1194 SGTL5000_LINE_OUT_GND_STP;
1195
1196 snd_soc_update_bits(codec, SGTL5000_CHIP_LINE_OUT_CTRL,
1197 vag << SGTL5000_LINE_OUT_GND_SHIFT |
1198 SGTL5000_LINE_OUT_CURRENT_360u <<
1199 SGTL5000_LINE_OUT_CURRENT_SHIFT,
1200 vag << SGTL5000_LINE_OUT_GND_SHIFT |
1201 SGTL5000_LINE_OUT_CURRENT_360u <<
1202 SGTL5000_LINE_OUT_CURRENT_SHIFT);
1203
1204 return 0;
1205}
1206
1207static int sgtl5000_enable_regulators(struct snd_soc_codec *codec)
1208{
1209 u16 reg;
1210 int ret;
1211 int rev;
1212 int i;
1213 int external_vddd = 0;
1214 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
1215
1216 for (i = 0; i < ARRAY_SIZE(sgtl5000->supplies); i++)
1217 sgtl5000->supplies[i].supply = supply_names[i];
1218
1219 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(sgtl5000->supplies),
1220 sgtl5000->supplies);
1221 if (!ret)
1222 external_vddd = 1;
1223 else {
1224 /* set internal ldo to 1.2v */
1225 int voltage = LDO_VOLTAGE;
1226
1227 ret = ldo_regulator_register(codec, &ldo_init_data, voltage);
1228 if (ret) {
1229 dev_err(codec->dev,
1230 "Failed to register vddd internal supplies: %d\n",
1231 ret);
1232 return ret;
1233 }
1234
1235 sgtl5000->supplies[VDDD].supply = LDO_CONSUMER_NAME;
1236
1237 ret = regulator_bulk_get(codec->dev,
1238 ARRAY_SIZE(sgtl5000->supplies),
1239 sgtl5000->supplies);
1240
1241 if (ret) {
1242 ldo_regulator_remove(codec);
1243 dev_err(codec->dev,
1244 "Failed to request supplies: %d\n", ret);
1245
1246 return ret;
1247 }
1248 }
1249
1250 ret = regulator_bulk_enable(ARRAY_SIZE(sgtl5000->supplies),
1251 sgtl5000->supplies);
1252 if (ret)
1253 goto err_regulator_free;
1254
1255 /* wait for all power rails bring up */
1256 udelay(10);
1257
1258 /* read chip information */
1259 reg = snd_soc_read(codec, SGTL5000_CHIP_ID);
1260 if (((reg & SGTL5000_PARTID_MASK) >> SGTL5000_PARTID_SHIFT) !=
1261 SGTL5000_PARTID_PART_ID) {
1262 dev_err(codec->dev,
1263 "Device with ID register %x is not a sgtl5000\n", reg);
1264 ret = -ENODEV;
1265 goto err_regulator_disable;
1266 }
1267
1268 rev = (reg & SGTL5000_REVID_MASK) >> SGTL5000_REVID_SHIFT;
1269 dev_info(codec->dev, "sgtl5000 revision %d\n", rev);
1270
1271 /*
1272 * workaround for revision 0x11 and later,
1273 * roll back to use internal LDO
1274 */
1275 if (external_vddd && rev >= 0x11) {
1276 int voltage = LDO_VOLTAGE;
1277 /* disable all regulator first */
1278 regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies),
1279 sgtl5000->supplies);
1280 /* free VDDD regulator */
1281 regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies),
1282 sgtl5000->supplies);
1283
1284 ret = ldo_regulator_register(codec, &ldo_init_data, voltage);
1285 if (ret)
1286 return ret;
1287
1288 sgtl5000->supplies[VDDD].supply = LDO_CONSUMER_NAME;
1289
1290 ret = regulator_bulk_get(codec->dev,
1291 ARRAY_SIZE(sgtl5000->supplies),
1292 sgtl5000->supplies);
1293 if (ret) {
1294 ldo_regulator_remove(codec);
1295 dev_err(codec->dev,
1296 "Failed to request supplies: %d\n", ret);
1297
1298 return ret;
1299 }
1300
1301 ret = regulator_bulk_enable(ARRAY_SIZE(sgtl5000->supplies),
1302 sgtl5000->supplies);
1303 if (ret)
1304 goto err_regulator_free;
1305
1306 /* wait for all power rails bring up */
1307 udelay(10);
1308 }
1309
1310 return 0;
1311
1312err_regulator_disable:
1313 regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies),
1314 sgtl5000->supplies);
1315err_regulator_free:
1316 regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies),
1317 sgtl5000->supplies);
1318 if (external_vddd)
1319 ldo_regulator_remove(codec);
1320 return ret;
1321
1322}
1323
1324static int sgtl5000_probe(struct snd_soc_codec *codec)
1325{
1326 int ret;
1327 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
1328
1329 /* setup i2c data ops */
1330 ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C);
1331 if (ret < 0) {
1332 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1333 return ret;
1334 }
1335
1336 ret = sgtl5000_enable_regulators(codec);
1337 if (ret)
1338 return ret;
1339
1340 /* power up sgtl5000 */
1341 ret = sgtl5000_set_power_regs(codec);
1342 if (ret)
1343 goto err;
1344
1345 /* enable small pop, introduce 400ms delay in turning off */
1346 snd_soc_update_bits(codec, SGTL5000_CHIP_REF_CTRL,
1347 SGTL5000_SMALL_POP,
1348 SGTL5000_SMALL_POP);
1349
1350 /* disable short cut detector */
1351 snd_soc_write(codec, SGTL5000_CHIP_SHORT_CTRL, 0);
1352
1353 /*
1354 * set i2s as default input of sound switch
1355 * TODO: add sound switch to control and dapm widge.
1356 */
1357 snd_soc_write(codec, SGTL5000_CHIP_SSS_CTRL,
1358 SGTL5000_DAC_SEL_I2S_IN << SGTL5000_DAC_SEL_SHIFT);
1359 snd_soc_write(codec, SGTL5000_CHIP_DIG_POWER,
1360 SGTL5000_ADC_EN | SGTL5000_DAC_EN);
1361
1362 /* enable dac volume ramp by default */
1363 snd_soc_write(codec, SGTL5000_CHIP_ADCDAC_CTRL,
1364 SGTL5000_DAC_VOL_RAMP_EN |
1365 SGTL5000_DAC_MUTE_RIGHT |
1366 SGTL5000_DAC_MUTE_LEFT);
1367
1368 snd_soc_write(codec, SGTL5000_CHIP_PAD_STRENGTH, 0x015f);
1369
1370 snd_soc_write(codec, SGTL5000_CHIP_ANA_CTRL,
1371 SGTL5000_HP_ZCD_EN |
1372 SGTL5000_ADC_ZCD_EN);
1373
1374 snd_soc_write(codec, SGTL5000_CHIP_MIC_CTRL, 0);
1375
1376 /*
1377 * disable DAP
1378 * TODO:
1379 * Enable DAP in kcontrol and dapm.
1380 */
1381 snd_soc_write(codec, SGTL5000_DAP_CTRL, 0);
1382
1383 /* leading to standby state */
1384 ret = sgtl5000_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1385 if (ret)
1386 goto err;
1387
1388 snd_soc_add_controls(codec, sgtl5000_snd_controls,
1389 ARRAY_SIZE(sgtl5000_snd_controls));
1390
1391 snd_soc_dapm_new_controls(&codec->dapm, sgtl5000_dapm_widgets,
1392 ARRAY_SIZE(sgtl5000_dapm_widgets));
1393
1394 snd_soc_dapm_add_routes(&codec->dapm, audio_map,
1395 ARRAY_SIZE(audio_map));
1396
1397 snd_soc_dapm_new_widgets(&codec->dapm);
1398
1399 return 0;
1400
1401err:
1402 regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies),
1403 sgtl5000->supplies);
1404 regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies),
1405 sgtl5000->supplies);
1406 ldo_regulator_remove(codec);
1407
1408 return ret;
1409}
1410
1411static int sgtl5000_remove(struct snd_soc_codec *codec)
1412{
1413 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
1414
1415 sgtl5000_set_bias_level(codec, SND_SOC_BIAS_OFF);
1416
1417 regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies),
1418 sgtl5000->supplies);
1419 regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies),
1420 sgtl5000->supplies);
1421 ldo_regulator_remove(codec);
1422
1423 return 0;
1424}
1425
1426static struct snd_soc_codec_driver sgtl5000_driver = {
1427 .probe = sgtl5000_probe,
1428 .remove = sgtl5000_remove,
1429 .suspend = sgtl5000_suspend,
1430 .resume = sgtl5000_resume,
1431 .set_bias_level = sgtl5000_set_bias_level,
1432 .reg_cache_size = ARRAY_SIZE(sgtl5000_regs),
1433 .reg_word_size = sizeof(u16),
1434 .reg_cache_step = 2,
1435 .reg_cache_default = sgtl5000_regs,
1436 .volatile_register = sgtl5000_volatile_register,
1437};
1438
1439static __devinit int sgtl5000_i2c_probe(struct i2c_client *client,
1440 const struct i2c_device_id *id)
1441{
1442 struct sgtl5000_priv *sgtl5000;
1443 int ret;
1444
1445 sgtl5000 = kzalloc(sizeof(struct sgtl5000_priv), GFP_KERNEL);
1446 if (!sgtl5000)
1447 return -ENOMEM;
1448
1449 /*
1450 * copy DAP default values to default value array.
1451 * sgtl5000 register space has a big hole, merge it
1452 * at init phase makes life easy.
1453 * FIXME: should we drop 'const' of sgtl5000_regs?
1454 */
1455 memcpy((void *)(&sgtl5000_regs[0] + (SGTL5000_DAP_REG_OFFSET >> 1)),
1456 sgtl5000_dap_regs,
1457 SGTL5000_MAX_REG_OFFSET - SGTL5000_DAP_REG_OFFSET);
1458
1459 i2c_set_clientdata(client, sgtl5000);
1460
1461 ret = snd_soc_register_codec(&client->dev,
1462 &sgtl5000_driver, &sgtl5000_dai, 1);
1463 if (ret) {
1464 dev_err(&client->dev, "Failed to register codec: %d\n", ret);
1465 kfree(sgtl5000);
1466 return ret;
1467 }
1468
1469 return 0;
1470}
1471
1472static __devexit int sgtl5000_i2c_remove(struct i2c_client *client)
1473{
1474 struct sgtl5000_priv *sgtl5000 = i2c_get_clientdata(client);
1475
1476 snd_soc_unregister_codec(&client->dev);
1477
1478 kfree(sgtl5000);
1479 return 0;
1480}
1481
1482static const struct i2c_device_id sgtl5000_id[] = {
1483 {"sgtl5000", 0},
1484 {},
1485};
1486
1487MODULE_DEVICE_TABLE(i2c, sgtl5000_id);
1488
1489static struct i2c_driver sgtl5000_i2c_driver = {
1490 .driver = {
1491 .name = "sgtl5000",
1492 .owner = THIS_MODULE,
1493 },
1494 .probe = sgtl5000_i2c_probe,
1495 .remove = __devexit_p(sgtl5000_i2c_remove),
1496 .id_table = sgtl5000_id,
1497};
1498
1499static int __init sgtl5000_modinit(void)
1500{
1501 return i2c_add_driver(&sgtl5000_i2c_driver);
1502}
1503module_init(sgtl5000_modinit);
1504
1505static void __exit sgtl5000_exit(void)
1506{
1507 i2c_del_driver(&sgtl5000_i2c_driver);
1508}
1509module_exit(sgtl5000_exit);
1510
1511MODULE_DESCRIPTION("Freescale SGTL5000 ALSA SoC Codec Driver");
1512MODULE_AUTHOR("Zeng Zhaoming <zhaoming.zeng@freescale.com>");
1513MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/sgtl5000.h b/sound/soc/codecs/sgtl5000.h
new file mode 100644
index 000000000000..eec3ab368f39
--- /dev/null
+++ b/sound/soc/codecs/sgtl5000.h
@@ -0,0 +1,400 @@
1/*
2 * sgtl5000.h - SGTL5000 audio codec interface
3 *
4 * Copyright 2010-2011 Freescale Semiconductor, Inc.
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 _SGTL5000_H
12#define _SGTL5000_H
13
14/*
15 * Register values.
16 */
17#define SGTL5000_CHIP_ID 0x0000
18#define SGTL5000_CHIP_DIG_POWER 0x0002
19#define SGTL5000_CHIP_CLK_CTRL 0x0004
20#define SGTL5000_CHIP_I2S_CTRL 0x0006
21#define SGTL5000_CHIP_SSS_CTRL 0x000a
22#define SGTL5000_CHIP_ADCDAC_CTRL 0x000e
23#define SGTL5000_CHIP_DAC_VOL 0x0010
24#define SGTL5000_CHIP_PAD_STRENGTH 0x0014
25#define SGTL5000_CHIP_ANA_ADC_CTRL 0x0020
26#define SGTL5000_CHIP_ANA_HP_CTRL 0x0022
27#define SGTL5000_CHIP_ANA_CTRL 0x0024
28#define SGTL5000_CHIP_LINREG_CTRL 0x0026
29#define SGTL5000_CHIP_REF_CTRL 0x0028
30#define SGTL5000_CHIP_MIC_CTRL 0x002a
31#define SGTL5000_CHIP_LINE_OUT_CTRL 0x002c
32#define SGTL5000_CHIP_LINE_OUT_VOL 0x002e
33#define SGTL5000_CHIP_ANA_POWER 0x0030
34#define SGTL5000_CHIP_PLL_CTRL 0x0032
35#define SGTL5000_CHIP_CLK_TOP_CTRL 0x0034
36#define SGTL5000_CHIP_ANA_STATUS 0x0036
37#define SGTL5000_CHIP_SHORT_CTRL 0x003c
38#define SGTL5000_CHIP_ANA_TEST2 0x003a
39#define SGTL5000_DAP_CTRL 0x0100
40#define SGTL5000_DAP_PEQ 0x0102
41#define SGTL5000_DAP_BASS_ENHANCE 0x0104
42#define SGTL5000_DAP_BASS_ENHANCE_CTRL 0x0106
43#define SGTL5000_DAP_AUDIO_EQ 0x0108
44#define SGTL5000_DAP_SURROUND 0x010a
45#define SGTL5000_DAP_FLT_COEF_ACCESS 0x010c
46#define SGTL5000_DAP_COEF_WR_B0_MSB 0x010e
47#define SGTL5000_DAP_COEF_WR_B0_LSB 0x0110
48#define SGTL5000_DAP_EQ_BASS_BAND0 0x0116
49#define SGTL5000_DAP_EQ_BASS_BAND1 0x0118
50#define SGTL5000_DAP_EQ_BASS_BAND2 0x011a
51#define SGTL5000_DAP_EQ_BASS_BAND3 0x011c
52#define SGTL5000_DAP_EQ_BASS_BAND4 0x011e
53#define SGTL5000_DAP_MAIN_CHAN 0x0120
54#define SGTL5000_DAP_MIX_CHAN 0x0122
55#define SGTL5000_DAP_AVC_CTRL 0x0124
56#define SGTL5000_DAP_AVC_THRESHOLD 0x0126
57#define SGTL5000_DAP_AVC_ATTACK 0x0128
58#define SGTL5000_DAP_AVC_DECAY 0x012a
59#define SGTL5000_DAP_COEF_WR_B1_MSB 0x012c
60#define SGTL5000_DAP_COEF_WR_B1_LSB 0x012e
61#define SGTL5000_DAP_COEF_WR_B2_MSB 0x0130
62#define SGTL5000_DAP_COEF_WR_B2_LSB 0x0132
63#define SGTL5000_DAP_COEF_WR_A1_MSB 0x0134
64#define SGTL5000_DAP_COEF_WR_A1_LSB 0x0136
65#define SGTL5000_DAP_COEF_WR_A2_MSB 0x0138
66#define SGTL5000_DAP_COEF_WR_A2_LSB 0x013a
67
68/*
69 * Field Definitions.
70 */
71
72/*
73 * SGTL5000_CHIP_ID
74 */
75#define SGTL5000_PARTID_MASK 0xff00
76#define SGTL5000_PARTID_SHIFT 8
77#define SGTL5000_PARTID_WIDTH 8
78#define SGTL5000_PARTID_PART_ID 0xa0
79#define SGTL5000_REVID_MASK 0x00ff
80#define SGTL5000_REVID_SHIFT 0
81#define SGTL5000_REVID_WIDTH 8
82
83/*
84 * SGTL5000_CHIP_DIG_POWER
85 */
86#define SGTL5000_ADC_EN 0x0040
87#define SGTL5000_DAC_EN 0x0020
88#define SGTL5000_DAP_POWERUP 0x0010
89#define SGTL5000_I2S_OUT_POWERUP 0x0002
90#define SGTL5000_I2S_IN_POWERUP 0x0001
91
92/*
93 * SGTL5000_CHIP_CLK_CTRL
94 */
95#define SGTL5000_RATE_MODE_MASK 0x0030
96#define SGTL5000_RATE_MODE_SHIFT 4
97#define SGTL5000_RATE_MODE_WIDTH 2
98#define SGTL5000_RATE_MODE_DIV_1 0
99#define SGTL5000_RATE_MODE_DIV_2 1
100#define SGTL5000_RATE_MODE_DIV_4 2
101#define SGTL5000_RATE_MODE_DIV_6 3
102#define SGTL5000_SYS_FS_MASK 0x000c
103#define SGTL5000_SYS_FS_SHIFT 2
104#define SGTL5000_SYS_FS_WIDTH 2
105#define SGTL5000_SYS_FS_32k 0x0
106#define SGTL5000_SYS_FS_44_1k 0x1
107#define SGTL5000_SYS_FS_48k 0x2
108#define SGTL5000_SYS_FS_96k 0x3
109#define SGTL5000_MCLK_FREQ_MASK 0x0003
110#define SGTL5000_MCLK_FREQ_SHIFT 0
111#define SGTL5000_MCLK_FREQ_WIDTH 2
112#define SGTL5000_MCLK_FREQ_256FS 0x0
113#define SGTL5000_MCLK_FREQ_384FS 0x1
114#define SGTL5000_MCLK_FREQ_512FS 0x2
115#define SGTL5000_MCLK_FREQ_PLL 0x3
116
117/*
118 * SGTL5000_CHIP_I2S_CTRL
119 */
120#define SGTL5000_I2S_SCLKFREQ_MASK 0x0100
121#define SGTL5000_I2S_SCLKFREQ_SHIFT 8
122#define SGTL5000_I2S_SCLKFREQ_WIDTH 1
123#define SGTL5000_I2S_SCLKFREQ_64FS 0x0
124#define SGTL5000_I2S_SCLKFREQ_32FS 0x1 /* Not for RJ mode */
125#define SGTL5000_I2S_MASTER 0x0080
126#define SGTL5000_I2S_SCLK_INV 0x0040
127#define SGTL5000_I2S_DLEN_MASK 0x0030
128#define SGTL5000_I2S_DLEN_SHIFT 4
129#define SGTL5000_I2S_DLEN_WIDTH 2
130#define SGTL5000_I2S_DLEN_32 0x0
131#define SGTL5000_I2S_DLEN_24 0x1
132#define SGTL5000_I2S_DLEN_20 0x2
133#define SGTL5000_I2S_DLEN_16 0x3
134#define SGTL5000_I2S_MODE_MASK 0x000c
135#define SGTL5000_I2S_MODE_SHIFT 2
136#define SGTL5000_I2S_MODE_WIDTH 2
137#define SGTL5000_I2S_MODE_I2S_LJ 0x0
138#define SGTL5000_I2S_MODE_RJ 0x1
139#define SGTL5000_I2S_MODE_PCM 0x2
140#define SGTL5000_I2S_LRALIGN 0x0002
141#define SGTL5000_I2S_LRPOL 0x0001 /* set for which mode */
142
143/*
144 * SGTL5000_CHIP_SSS_CTRL
145 */
146#define SGTL5000_DAP_MIX_LRSWAP 0x4000
147#define SGTL5000_DAP_LRSWAP 0x2000
148#define SGTL5000_DAC_LRSWAP 0x1000
149#define SGTL5000_I2S_OUT_LRSWAP 0x0400
150#define SGTL5000_DAP_MIX_SEL_MASK 0x0300
151#define SGTL5000_DAP_MIX_SEL_SHIFT 8
152#define SGTL5000_DAP_MIX_SEL_WIDTH 2
153#define SGTL5000_DAP_MIX_SEL_ADC 0x0
154#define SGTL5000_DAP_MIX_SEL_I2S_IN 0x1
155#define SGTL5000_DAP_SEL_MASK 0x00c0
156#define SGTL5000_DAP_SEL_SHIFT 6
157#define SGTL5000_DAP_SEL_WIDTH 2
158#define SGTL5000_DAP_SEL_ADC 0x0
159#define SGTL5000_DAP_SEL_I2S_IN 0x1
160#define SGTL5000_DAC_SEL_MASK 0x0030
161#define SGTL5000_DAC_SEL_SHIFT 4
162#define SGTL5000_DAC_SEL_WIDTH 2
163#define SGTL5000_DAC_SEL_ADC 0x0
164#define SGTL5000_DAC_SEL_I2S_IN 0x1
165#define SGTL5000_DAC_SEL_DAP 0x3
166#define SGTL5000_I2S_OUT_SEL_MASK 0x0003
167#define SGTL5000_I2S_OUT_SEL_SHIFT 0
168#define SGTL5000_I2S_OUT_SEL_WIDTH 2
169#define SGTL5000_I2S_OUT_SEL_ADC 0x0
170#define SGTL5000_I2S_OUT_SEL_I2S_IN 0x1
171#define SGTL5000_I2S_OUT_SEL_DAP 0x3
172
173/*
174 * SGTL5000_CHIP_ADCDAC_CTRL
175 */
176#define SGTL5000_VOL_BUSY_DAC_RIGHT 0x2000
177#define SGTL5000_VOL_BUSY_DAC_LEFT 0x1000
178#define SGTL5000_DAC_VOL_RAMP_EN 0x0200
179#define SGTL5000_DAC_VOL_RAMP_EXPO 0x0100
180#define SGTL5000_DAC_MUTE_RIGHT 0x0008
181#define SGTL5000_DAC_MUTE_LEFT 0x0004
182#define SGTL5000_ADC_HPF_FREEZE 0x0002
183#define SGTL5000_ADC_HPF_BYPASS 0x0001
184
185/*
186 * SGTL5000_CHIP_DAC_VOL
187 */
188#define SGTL5000_DAC_VOL_RIGHT_MASK 0xff00
189#define SGTL5000_DAC_VOL_RIGHT_SHIFT 8
190#define SGTL5000_DAC_VOL_RIGHT_WIDTH 8
191#define SGTL5000_DAC_VOL_LEFT_MASK 0x00ff
192#define SGTL5000_DAC_VOL_LEFT_SHIFT 0
193#define SGTL5000_DAC_VOL_LEFT_WIDTH 8
194
195/*
196 * SGTL5000_CHIP_PAD_STRENGTH
197 */
198#define SGTL5000_PAD_I2S_LRCLK_MASK 0x0300
199#define SGTL5000_PAD_I2S_LRCLK_SHIFT 8
200#define SGTL5000_PAD_I2S_LRCLK_WIDTH 2
201#define SGTL5000_PAD_I2S_SCLK_MASK 0x00c0
202#define SGTL5000_PAD_I2S_SCLK_SHIFT 6
203#define SGTL5000_PAD_I2S_SCLK_WIDTH 2
204#define SGTL5000_PAD_I2S_DOUT_MASK 0x0030
205#define SGTL5000_PAD_I2S_DOUT_SHIFT 4
206#define SGTL5000_PAD_I2S_DOUT_WIDTH 2
207#define SGTL5000_PAD_I2C_SDA_MASK 0x000c
208#define SGTL5000_PAD_I2C_SDA_SHIFT 2
209#define SGTL5000_PAD_I2C_SDA_WIDTH 2
210#define SGTL5000_PAD_I2C_SCL_MASK 0x0003
211#define SGTL5000_PAD_I2C_SCL_SHIFT 0
212#define SGTL5000_PAD_I2C_SCL_WIDTH 2
213
214/*
215 * SGTL5000_CHIP_ANA_ADC_CTRL
216 */
217#define SGTL5000_ADC_VOL_M6DB 0x0100
218#define SGTL5000_ADC_VOL_RIGHT_MASK 0x00f0
219#define SGTL5000_ADC_VOL_RIGHT_SHIFT 4
220#define SGTL5000_ADC_VOL_RIGHT_WIDTH 4
221#define SGTL5000_ADC_VOL_LEFT_MASK 0x000f
222#define SGTL5000_ADC_VOL_LEFT_SHIFT 0
223#define SGTL5000_ADC_VOL_LEFT_WIDTH 4
224
225/*
226 * SGTL5000_CHIP_ANA_HP_CTRL
227 */
228#define SGTL5000_HP_VOL_RIGHT_MASK 0x7f00
229#define SGTL5000_HP_VOL_RIGHT_SHIFT 8
230#define SGTL5000_HP_VOL_RIGHT_WIDTH 7
231#define SGTL5000_HP_VOL_LEFT_MASK 0x007f
232#define SGTL5000_HP_VOL_LEFT_SHIFT 0
233#define SGTL5000_HP_VOL_LEFT_WIDTH 7
234
235/*
236 * SGTL5000_CHIP_ANA_CTRL
237 */
238#define SGTL5000_LINE_OUT_MUTE 0x0100
239#define SGTL5000_HP_SEL_MASK 0x0040
240#define SGTL5000_HP_SEL_SHIFT 6
241#define SGTL5000_HP_SEL_WIDTH 1
242#define SGTL5000_HP_SEL_DAC 0x0
243#define SGTL5000_HP_SEL_LINE_IN 0x1
244#define SGTL5000_HP_ZCD_EN 0x0020
245#define SGTL5000_HP_MUTE 0x0010
246#define SGTL5000_ADC_SEL_MASK 0x0004
247#define SGTL5000_ADC_SEL_SHIFT 2
248#define SGTL5000_ADC_SEL_WIDTH 1
249#define SGTL5000_ADC_SEL_MIC 0x0
250#define SGTL5000_ADC_SEL_LINE_IN 0x1
251#define SGTL5000_ADC_ZCD_EN 0x0002
252#define SGTL5000_ADC_MUTE 0x0001
253
254/*
255 * SGTL5000_CHIP_LINREG_CTRL
256 */
257#define SGTL5000_VDDC_MAN_ASSN_MASK 0x0040
258#define SGTL5000_VDDC_MAN_ASSN_SHIFT 6
259#define SGTL5000_VDDC_MAN_ASSN_WIDTH 1
260#define SGTL5000_VDDC_MAN_ASSN_VDDA 0x0
261#define SGTL5000_VDDC_MAN_ASSN_VDDIO 0x1
262#define SGTL5000_VDDC_ASSN_OVRD 0x0020
263#define SGTL5000_LINREG_VDDD_MASK 0x000f
264#define SGTL5000_LINREG_VDDD_SHIFT 0
265#define SGTL5000_LINREG_VDDD_WIDTH 4
266
267/*
268 * SGTL5000_CHIP_REF_CTRL
269 */
270#define SGTL5000_ANA_GND_MASK 0x01f0
271#define SGTL5000_ANA_GND_SHIFT 4
272#define SGTL5000_ANA_GND_WIDTH 5
273#define SGTL5000_ANA_GND_BASE 800 /* mv */
274#define SGTL5000_ANA_GND_STP 25 /*mv */
275#define SGTL5000_BIAS_CTRL_MASK 0x000e
276#define SGTL5000_BIAS_CTRL_SHIFT 1
277#define SGTL5000_BIAS_CTRL_WIDTH 3
278#define SGTL5000_SMALL_POP 0x0001
279
280/*
281 * SGTL5000_CHIP_MIC_CTRL
282 */
283#define SGTL5000_BIAS_R_MASK 0x0200
284#define SGTL5000_BIAS_R_SHIFT 8
285#define SGTL5000_BIAS_R_WIDTH 2
286#define SGTL5000_BIAS_R_off 0x0
287#define SGTL5000_BIAS_R_2K 0x1
288#define SGTL5000_BIAS_R_4k 0x2
289#define SGTL5000_BIAS_R_8k 0x3
290#define SGTL5000_BIAS_VOLT_MASK 0x0070
291#define SGTL5000_BIAS_VOLT_SHIFT 4
292#define SGTL5000_BIAS_VOLT_WIDTH 3
293#define SGTL5000_MIC_GAIN_MASK 0x0003
294#define SGTL5000_MIC_GAIN_SHIFT 0
295#define SGTL5000_MIC_GAIN_WIDTH 2
296
297/*
298 * SGTL5000_CHIP_LINE_OUT_CTRL
299 */
300#define SGTL5000_LINE_OUT_CURRENT_MASK 0x0f00
301#define SGTL5000_LINE_OUT_CURRENT_SHIFT 8
302#define SGTL5000_LINE_OUT_CURRENT_WIDTH 4
303#define SGTL5000_LINE_OUT_CURRENT_180u 0x0
304#define SGTL5000_LINE_OUT_CURRENT_270u 0x1
305#define SGTL5000_LINE_OUT_CURRENT_360u 0x3
306#define SGTL5000_LINE_OUT_CURRENT_450u 0x7
307#define SGTL5000_LINE_OUT_CURRENT_540u 0xf
308#define SGTL5000_LINE_OUT_GND_MASK 0x003f
309#define SGTL5000_LINE_OUT_GND_SHIFT 0
310#define SGTL5000_LINE_OUT_GND_WIDTH 6
311#define SGTL5000_LINE_OUT_GND_BASE 800 /* mv */
312#define SGTL5000_LINE_OUT_GND_STP 25
313#define SGTL5000_LINE_OUT_GND_MAX 0x23
314
315/*
316 * SGTL5000_CHIP_LINE_OUT_VOL
317 */
318#define SGTL5000_LINE_OUT_VOL_RIGHT_MASK 0x1f00
319#define SGTL5000_LINE_OUT_VOL_RIGHT_SHIFT 8
320#define SGTL5000_LINE_OUT_VOL_RIGHT_WIDTH 5
321#define SGTL5000_LINE_OUT_VOL_LEFT_MASK 0x001f
322#define SGTL5000_LINE_OUT_VOL_LEFT_SHIFT 0
323#define SGTL5000_LINE_OUT_VOL_LEFT_WIDTH 5
324
325/*
326 * SGTL5000_CHIP_ANA_POWER
327 */
328#define SGTL5000_DAC_STEREO 0x4000
329#define SGTL5000_LINREG_SIMPLE_POWERUP 0x2000
330#define SGTL5000_STARTUP_POWERUP 0x1000
331#define SGTL5000_VDDC_CHRGPMP_POWERUP 0x0800
332#define SGTL5000_PLL_POWERUP 0x0400
333#define SGTL5000_LINEREG_D_POWERUP 0x0200
334#define SGTL5000_VCOAMP_POWERUP 0x0100
335#define SGTL5000_VAG_POWERUP 0x0080
336#define SGTL5000_ADC_STEREO 0x0040
337#define SGTL5000_REFTOP_POWERUP 0x0020
338#define SGTL5000_HP_POWERUP 0x0010
339#define SGTL5000_DAC_POWERUP 0x0008
340#define SGTL5000_CAPLESS_HP_POWERUP 0x0004
341#define SGTL5000_ADC_POWERUP 0x0002
342#define SGTL5000_LINE_OUT_POWERUP 0x0001
343
344/*
345 * SGTL5000_CHIP_PLL_CTRL
346 */
347#define SGTL5000_PLL_INT_DIV_MASK 0xf800
348#define SGTL5000_PLL_INT_DIV_SHIFT 11
349#define SGTL5000_PLL_INT_DIV_WIDTH 5
350#define SGTL5000_PLL_FRAC_DIV_MASK 0x0700
351#define SGTL5000_PLL_FRAC_DIV_SHIFT 0
352#define SGTL5000_PLL_FRAC_DIV_WIDTH 11
353
354/*
355 * SGTL5000_CHIP_CLK_TOP_CTRL
356 */
357#define SGTL5000_INT_OSC_EN 0x0800
358#define SGTL5000_INPUT_FREQ_DIV2 0x0008
359
360/*
361 * SGTL5000_CHIP_ANA_STATUS
362 */
363#define SGTL5000_HP_LRSHORT 0x0200
364#define SGTL5000_CAPLESS_SHORT 0x0100
365#define SGTL5000_PLL_LOCKED 0x0010
366
367/*
368 * SGTL5000_CHIP_SHORT_CTRL
369 */
370#define SGTL5000_LVLADJR_MASK 0x7000
371#define SGTL5000_LVLADJR_SHIFT 12
372#define SGTL5000_LVLADJR_WIDTH 3
373#define SGTL5000_LVLADJL_MASK 0x0700
374#define SGTL5000_LVLADJL_SHIFT 8
375#define SGTL5000_LVLADJL_WIDTH 3
376#define SGTL5000_LVLADJC_MASK 0x0070
377#define SGTL5000_LVLADJC_SHIFT 4
378#define SGTL5000_LVLADJC_WIDTH 3
379#define SGTL5000_LR_SHORT_MOD_MASK 0x000c
380#define SGTL5000_LR_SHORT_MOD_SHIFT 2
381#define SGTL5000_LR_SHORT_MOD_WIDTH 2
382#define SGTL5000_CM_SHORT_MOD_MASK 0x0003
383#define SGTL5000_CM_SHORT_MOD_SHIFT 0
384#define SGTL5000_CM_SHORT_MOD_WIDTH 2
385
386/*
387 *SGTL5000_CHIP_ANA_TEST2
388 */
389#define SGTL5000_MONO_DAC 0x1000
390
391/*
392 * SGTL5000_DAP_CTRL
393 */
394#define SGTL5000_DAP_MIX_EN 0x0010
395#define SGTL5000_DAP_EN 0x0001
396
397#define SGTL5000_SYSCLK 0x00
398#define SGTL5000_LRCLK 0x01
399
400#endif
diff --git a/sound/soc/codecs/sn95031.c b/sound/soc/codecs/sn95031.c
new file mode 100644
index 000000000000..2a30eae1881c
--- /dev/null
+++ b/sound/soc/codecs/sn95031.c
@@ -0,0 +1,949 @@
1/*
2 * sn95031.c - TI sn95031 Codec driver
3 *
4 * Copyright (C) 2010 Intel Corp
5 * Author: Vinod Koul <vinod.koul@intel.com>
6 * Author: Harsha Priya <priya.harsha@intel.com>
7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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 as published by
11 * the Free Software Foundation; version 2 of the License.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21 *
22 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
23 *
24 *
25 */
26#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
27
28#include <linux/platform_device.h>
29#include <linux/slab.h>
30#include <asm/intel_scu_ipc.h>
31#include <sound/pcm.h>
32#include <sound/pcm_params.h>
33#include <sound/soc.h>
34#include <sound/soc-dapm.h>
35#include <sound/initval.h>
36#include <sound/tlv.h>
37#include <sound/jack.h>
38#include "sn95031.h"
39
40#define SN95031_RATES (SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_44100)
41#define SN95031_FORMATS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE)
42
43/* adc helper functions */
44
45/* enables mic bias voltage */
46static void sn95031_enable_mic_bias(struct snd_soc_codec *codec)
47{
48 snd_soc_write(codec, SN95031_VAUD, BIT(2)|BIT(1)|BIT(0));
49 snd_soc_update_bits(codec, SN95031_MICBIAS, BIT(2), BIT(2));
50}
51
52/* Enable/Disable the ADC depending on the argument */
53static void configure_adc(struct snd_soc_codec *sn95031_codec, int val)
54{
55 int value = snd_soc_read(sn95031_codec, SN95031_ADC1CNTL1);
56
57 if (val) {
58 /* Enable and start the ADC */
59 value |= (SN95031_ADC_ENBL | SN95031_ADC_START);
60 value &= (~SN95031_ADC_NO_LOOP);
61 } else {
62 /* Just stop the ADC */
63 value &= (~SN95031_ADC_START);
64 }
65 snd_soc_write(sn95031_codec, SN95031_ADC1CNTL1, value);
66}
67
68/*
69 * finds an empty channel for conversion
70 * If the ADC is not enabled then start using 0th channel
71 * itself. Otherwise find an empty channel by looking for a
72 * channel in which the stopbit is set to 1. returns the index
73 * of the first free channel if succeeds or an error code.
74 *
75 * Context: can sleep
76 *
77 */
78static int find_free_channel(struct snd_soc_codec *sn95031_codec)
79{
80 int ret = 0, i, value;
81
82 /* check whether ADC is enabled */
83 value = snd_soc_read(sn95031_codec, SN95031_ADC1CNTL1);
84
85 if ((value & SN95031_ADC_ENBL) == 0)
86 return 0;
87
88 /* ADC is already enabled; Looking for an empty channel */
89 for (i = 0; i < SN95031_ADC_CHANLS_MAX; i++) {
90 value = snd_soc_read(sn95031_codec,
91 SN95031_ADC_CHNL_START_ADDR + i);
92 if (value & SN95031_STOPBIT_MASK) {
93 ret = i;
94 break;
95 }
96 }
97 return (ret > SN95031_ADC_LOOP_MAX) ? (-EINVAL) : ret;
98}
99
100/* Initialize the ADC for reading micbias values. Can sleep. */
101static int sn95031_initialize_adc(struct snd_soc_codec *sn95031_codec)
102{
103 int base_addr, chnl_addr;
104 int value;
105 static int channel_index;
106
107 /* Index of the first channel in which the stop bit is set */
108 channel_index = find_free_channel(sn95031_codec);
109 if (channel_index < 0) {
110 pr_err("No free ADC channels");
111 return channel_index;
112 }
113
114 base_addr = SN95031_ADC_CHNL_START_ADDR + channel_index;
115
116 if (!(channel_index == 0 || channel_index == SN95031_ADC_LOOP_MAX)) {
117 /* Reset stop bit for channels other than 0 and 12 */
118 value = snd_soc_read(sn95031_codec, base_addr);
119 /* Set the stop bit to zero */
120 snd_soc_write(sn95031_codec, base_addr, value & 0xEF);
121 /* Index of the first free channel */
122 base_addr++;
123 channel_index++;
124 }
125
126 /* Since this is the last channel, set the stop bit
127 to 1 by ORing the DIE_SENSOR_CODE with 0x10 */
128 snd_soc_write(sn95031_codec, base_addr,
129 SN95031_AUDIO_DETECT_CODE | 0x10);
130
131 chnl_addr = SN95031_ADC_DATA_START_ADDR + 2 * channel_index;
132 pr_debug("mid_initialize : %x", chnl_addr);
133 configure_adc(sn95031_codec, 1);
134 return chnl_addr;
135}
136
137
138/* reads the ADC registers and gets the mic bias value in mV. */
139static unsigned int sn95031_get_mic_bias(struct snd_soc_codec *codec)
140{
141 u16 adc_adr = sn95031_initialize_adc(codec);
142 u16 adc_val1, adc_val2;
143 unsigned int mic_bias;
144
145 sn95031_enable_mic_bias(codec);
146
147 /* Enable the sound card for conversion before reading */
148 snd_soc_write(codec, SN95031_ADC1CNTL3, 0x05);
149 /* Re-toggle the RRDATARD bit */
150 snd_soc_write(codec, SN95031_ADC1CNTL3, 0x04);
151
152 /* Read the higher bits of data */
153 msleep(1000);
154 adc_val1 = snd_soc_read(codec, adc_adr);
155 adc_adr++;
156 adc_val2 = snd_soc_read(codec, adc_adr);
157
158 /* Adding lower two bits to the higher bits */
159 mic_bias = (adc_val1 << 2) + (adc_val2 & 3);
160 mic_bias = (mic_bias * SN95031_ADC_ONE_LSB_MULTIPLIER) / 1000;
161 pr_debug("mic bias = %dmV\n", mic_bias);
162 return mic_bias;
163}
164EXPORT_SYMBOL_GPL(sn95031_get_mic_bias);
165/*end - adc helper functions */
166
167static inline unsigned int sn95031_read(struct snd_soc_codec *codec,
168 unsigned int reg)
169{
170 u8 value = 0;
171 int ret;
172
173 ret = intel_scu_ipc_ioread8(reg, &value);
174 if (ret)
175 pr_err("read of %x failed, err %d\n", reg, ret);
176 return value;
177
178}
179
180static inline int sn95031_write(struct snd_soc_codec *codec,
181 unsigned int reg, unsigned int value)
182{
183 int ret;
184
185 ret = intel_scu_ipc_iowrite8(reg, value);
186 if (ret)
187 pr_err("write of %x failed, err %d\n", reg, ret);
188 return ret;
189}
190
191static int sn95031_set_vaud_bias(struct snd_soc_codec *codec,
192 enum snd_soc_bias_level level)
193{
194 switch (level) {
195 case SND_SOC_BIAS_ON:
196 break;
197
198 case SND_SOC_BIAS_PREPARE:
199 if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) {
200 pr_debug("vaud_bias powering up pll\n");
201 /* power up the pll */
202 snd_soc_write(codec, SN95031_AUDPLLCTRL, BIT(5));
203 /* enable pcm 2 */
204 snd_soc_update_bits(codec, SN95031_PCM2C2,
205 BIT(0), BIT(0));
206 }
207 break;
208
209 case SND_SOC_BIAS_STANDBY:
210 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
211 pr_debug("vaud_bias power up rail\n");
212 /* power up the rail */
213 snd_soc_write(codec, SN95031_VAUD,
214 BIT(2)|BIT(1)|BIT(0));
215 msleep(1);
216 } else if (codec->dapm.bias_level == SND_SOC_BIAS_PREPARE) {
217 /* turn off pcm */
218 pr_debug("vaud_bias power dn pcm\n");
219 snd_soc_update_bits(codec, SN95031_PCM2C2, BIT(0), 0);
220 snd_soc_write(codec, SN95031_AUDPLLCTRL, 0);
221 }
222 break;
223
224
225 case SND_SOC_BIAS_OFF:
226 pr_debug("vaud_bias _OFF doing rail shutdown\n");
227 snd_soc_write(codec, SN95031_VAUD, BIT(3));
228 break;
229 }
230
231 codec->dapm.bias_level = level;
232 return 0;
233}
234
235static int sn95031_vhs_event(struct snd_soc_dapm_widget *w,
236 struct snd_kcontrol *kcontrol, int event)
237{
238 if (SND_SOC_DAPM_EVENT_ON(event)) {
239 pr_debug("VHS SND_SOC_DAPM_EVENT_ON doing rail startup now\n");
240 /* power up the rail */
241 snd_soc_write(w->codec, SN95031_VHSP, 0x3D);
242 snd_soc_write(w->codec, SN95031_VHSN, 0x3F);
243 msleep(1);
244 } else if (SND_SOC_DAPM_EVENT_OFF(event)) {
245 pr_debug("VHS SND_SOC_DAPM_EVENT_OFF doing rail shutdown\n");
246 snd_soc_write(w->codec, SN95031_VHSP, 0xC4);
247 snd_soc_write(w->codec, SN95031_VHSN, 0x04);
248 }
249 return 0;
250}
251
252static int sn95031_vihf_event(struct snd_soc_dapm_widget *w,
253 struct snd_kcontrol *kcontrol, int event)
254{
255 if (SND_SOC_DAPM_EVENT_ON(event)) {
256 pr_debug("VIHF SND_SOC_DAPM_EVENT_ON doing rail startup now\n");
257 /* power up the rail */
258 snd_soc_write(w->codec, SN95031_VIHF, 0x27);
259 msleep(1);
260 } else if (SND_SOC_DAPM_EVENT_OFF(event)) {
261 pr_debug("VIHF SND_SOC_DAPM_EVENT_OFF doing rail shutdown\n");
262 snd_soc_write(w->codec, SN95031_VIHF, 0x24);
263 }
264 return 0;
265}
266
267static int sn95031_dmic12_event(struct snd_soc_dapm_widget *w,
268 struct snd_kcontrol *k, int event)
269{
270 unsigned int ldo = 0, clk_dir = 0, data_dir = 0;
271
272 if (SND_SOC_DAPM_EVENT_ON(event)) {
273 ldo = BIT(5)|BIT(4);
274 clk_dir = BIT(0);
275 data_dir = BIT(7);
276 }
277 /* program DMIC LDO, clock and set clock */
278 snd_soc_update_bits(w->codec, SN95031_MICBIAS, BIT(5)|BIT(4), ldo);
279 snd_soc_update_bits(w->codec, SN95031_DMICBUF0123, BIT(0), clk_dir);
280 snd_soc_update_bits(w->codec, SN95031_DMICBUF0123, BIT(7), data_dir);
281 return 0;
282}
283
284static int sn95031_dmic34_event(struct snd_soc_dapm_widget *w,
285 struct snd_kcontrol *k, int event)
286{
287 unsigned int ldo = 0, clk_dir = 0, data_dir = 0;
288
289 if (SND_SOC_DAPM_EVENT_ON(event)) {
290 ldo = BIT(5)|BIT(4);
291 clk_dir = BIT(2);
292 data_dir = BIT(1);
293 }
294 /* program DMIC LDO, clock and set clock */
295 snd_soc_update_bits(w->codec, SN95031_MICBIAS, BIT(5)|BIT(4), ldo);
296 snd_soc_update_bits(w->codec, SN95031_DMICBUF0123, BIT(2), clk_dir);
297 snd_soc_update_bits(w->codec, SN95031_DMICBUF45, BIT(1), data_dir);
298 return 0;
299}
300
301static int sn95031_dmic56_event(struct snd_soc_dapm_widget *w,
302 struct snd_kcontrol *k, int event)
303{
304 unsigned int ldo = 0;
305
306 if (SND_SOC_DAPM_EVENT_ON(event))
307 ldo = BIT(7)|BIT(6);
308
309 /* program DMIC LDO */
310 snd_soc_update_bits(w->codec, SN95031_MICBIAS, BIT(7)|BIT(6), ldo);
311 return 0;
312}
313
314/* mux controls */
315static const char *sn95031_mic_texts[] = { "AMIC", "LineIn" };
316
317static const struct soc_enum sn95031_micl_enum =
318 SOC_ENUM_SINGLE(SN95031_ADCCONFIG, 1, 2, sn95031_mic_texts);
319
320static const struct snd_kcontrol_new sn95031_micl_mux_control =
321 SOC_DAPM_ENUM("Route", sn95031_micl_enum);
322
323static const struct soc_enum sn95031_micr_enum =
324 SOC_ENUM_SINGLE(SN95031_ADCCONFIG, 3, 2, sn95031_mic_texts);
325
326static const struct snd_kcontrol_new sn95031_micr_mux_control =
327 SOC_DAPM_ENUM("Route", sn95031_micr_enum);
328
329static const char *sn95031_input_texts[] = { "DMIC1", "DMIC2", "DMIC3",
330 "DMIC4", "DMIC5", "DMIC6",
331 "ADC Left", "ADC Right" };
332
333static const struct soc_enum sn95031_input1_enum =
334 SOC_ENUM_SINGLE(SN95031_AUDIOMUX12, 0, 8, sn95031_input_texts);
335
336static const struct snd_kcontrol_new sn95031_input1_mux_control =
337 SOC_DAPM_ENUM("Route", sn95031_input1_enum);
338
339static const struct soc_enum sn95031_input2_enum =
340 SOC_ENUM_SINGLE(SN95031_AUDIOMUX12, 4, 8, sn95031_input_texts);
341
342static const struct snd_kcontrol_new sn95031_input2_mux_control =
343 SOC_DAPM_ENUM("Route", sn95031_input2_enum);
344
345static const struct soc_enum sn95031_input3_enum =
346 SOC_ENUM_SINGLE(SN95031_AUDIOMUX34, 0, 8, sn95031_input_texts);
347
348static const struct snd_kcontrol_new sn95031_input3_mux_control =
349 SOC_DAPM_ENUM("Route", sn95031_input3_enum);
350
351static const struct soc_enum sn95031_input4_enum =
352 SOC_ENUM_SINGLE(SN95031_AUDIOMUX34, 4, 8, sn95031_input_texts);
353
354static const struct snd_kcontrol_new sn95031_input4_mux_control =
355 SOC_DAPM_ENUM("Route", sn95031_input4_enum);
356
357/* capture path controls */
358
359static const char *sn95031_micmode_text[] = {"Single Ended", "Differential"};
360
361/* 0dB to 30dB in 10dB steps */
362static const DECLARE_TLV_DB_SCALE(mic_tlv, 0, 10, 0);
363
364static const struct soc_enum sn95031_micmode1_enum =
365 SOC_ENUM_SINGLE(SN95031_MICAMP1, 1, 2, sn95031_micmode_text);
366static const struct soc_enum sn95031_micmode2_enum =
367 SOC_ENUM_SINGLE(SN95031_MICAMP2, 1, 2, sn95031_micmode_text);
368
369static const char *sn95031_dmic_cfg_text[] = {"GPO", "DMIC"};
370
371static const struct soc_enum sn95031_dmic12_cfg_enum =
372 SOC_ENUM_SINGLE(SN95031_DMICMUX, 0, 2, sn95031_dmic_cfg_text);
373static const struct soc_enum sn95031_dmic34_cfg_enum =
374 SOC_ENUM_SINGLE(SN95031_DMICMUX, 1, 2, sn95031_dmic_cfg_text);
375static const struct soc_enum sn95031_dmic56_cfg_enum =
376 SOC_ENUM_SINGLE(SN95031_DMICMUX, 2, 2, sn95031_dmic_cfg_text);
377
378static const struct snd_kcontrol_new sn95031_snd_controls[] = {
379 SOC_ENUM("Mic1Mode Capture Route", sn95031_micmode1_enum),
380 SOC_ENUM("Mic2Mode Capture Route", sn95031_micmode2_enum),
381 SOC_ENUM("DMIC12 Capture Route", sn95031_dmic12_cfg_enum),
382 SOC_ENUM("DMIC34 Capture Route", sn95031_dmic34_cfg_enum),
383 SOC_ENUM("DMIC56 Capture Route", sn95031_dmic56_cfg_enum),
384 SOC_SINGLE_TLV("Mic1 Capture Volume", SN95031_MICAMP1,
385 2, 4, 0, mic_tlv),
386 SOC_SINGLE_TLV("Mic2 Capture Volume", SN95031_MICAMP2,
387 2, 4, 0, mic_tlv),
388};
389
390/* DAPM widgets */
391static const struct snd_soc_dapm_widget sn95031_dapm_widgets[] = {
392
393 /* all end points mic, hs etc */
394 SND_SOC_DAPM_OUTPUT("HPOUTL"),
395 SND_SOC_DAPM_OUTPUT("HPOUTR"),
396 SND_SOC_DAPM_OUTPUT("EPOUT"),
397 SND_SOC_DAPM_OUTPUT("IHFOUTL"),
398 SND_SOC_DAPM_OUTPUT("IHFOUTR"),
399 SND_SOC_DAPM_OUTPUT("LINEOUTL"),
400 SND_SOC_DAPM_OUTPUT("LINEOUTR"),
401 SND_SOC_DAPM_OUTPUT("VIB1OUT"),
402 SND_SOC_DAPM_OUTPUT("VIB2OUT"),
403
404 SND_SOC_DAPM_INPUT("AMIC1"), /* headset mic */
405 SND_SOC_DAPM_INPUT("AMIC2"),
406 SND_SOC_DAPM_INPUT("DMIC1"),
407 SND_SOC_DAPM_INPUT("DMIC2"),
408 SND_SOC_DAPM_INPUT("DMIC3"),
409 SND_SOC_DAPM_INPUT("DMIC4"),
410 SND_SOC_DAPM_INPUT("DMIC5"),
411 SND_SOC_DAPM_INPUT("DMIC6"),
412 SND_SOC_DAPM_INPUT("LINEINL"),
413 SND_SOC_DAPM_INPUT("LINEINR"),
414
415 SND_SOC_DAPM_MICBIAS("AMIC1Bias", SN95031_MICBIAS, 2, 0),
416 SND_SOC_DAPM_MICBIAS("AMIC2Bias", SN95031_MICBIAS, 3, 0),
417 SND_SOC_DAPM_MICBIAS("DMIC12Bias", SN95031_DMICMUX, 3, 0),
418 SND_SOC_DAPM_MICBIAS("DMIC34Bias", SN95031_DMICMUX, 4, 0),
419 SND_SOC_DAPM_MICBIAS("DMIC56Bias", SN95031_DMICMUX, 5, 0),
420
421 SND_SOC_DAPM_SUPPLY("DMIC12supply", SN95031_DMICLK, 0, 0,
422 sn95031_dmic12_event,
423 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
424 SND_SOC_DAPM_SUPPLY("DMIC34supply", SN95031_DMICLK, 1, 0,
425 sn95031_dmic34_event,
426 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
427 SND_SOC_DAPM_SUPPLY("DMIC56supply", SN95031_DMICLK, 2, 0,
428 sn95031_dmic56_event,
429 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
430
431 SND_SOC_DAPM_AIF_OUT("PCM_Out", "Capture", 0,
432 SND_SOC_NOPM, 0, 0),
433
434 SND_SOC_DAPM_SUPPLY("Headset Rail", SND_SOC_NOPM, 0, 0,
435 sn95031_vhs_event,
436 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
437 SND_SOC_DAPM_SUPPLY("Speaker Rail", SND_SOC_NOPM, 0, 0,
438 sn95031_vihf_event,
439 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
440
441 /* playback path driver enables */
442 SND_SOC_DAPM_PGA("Headset Left Playback",
443 SN95031_DRIVEREN, 0, 0, NULL, 0),
444 SND_SOC_DAPM_PGA("Headset Right Playback",
445 SN95031_DRIVEREN, 1, 0, NULL, 0),
446 SND_SOC_DAPM_PGA("Speaker Left Playback",
447 SN95031_DRIVEREN, 2, 0, NULL, 0),
448 SND_SOC_DAPM_PGA("Speaker Right Playback",
449 SN95031_DRIVEREN, 3, 0, NULL, 0),
450 SND_SOC_DAPM_PGA("Vibra1 Playback",
451 SN95031_DRIVEREN, 4, 0, NULL, 0),
452 SND_SOC_DAPM_PGA("Vibra2 Playback",
453 SN95031_DRIVEREN, 5, 0, NULL, 0),
454 SND_SOC_DAPM_PGA("Earpiece Playback",
455 SN95031_DRIVEREN, 6, 0, NULL, 0),
456 SND_SOC_DAPM_PGA("Lineout Left Playback",
457 SN95031_LOCTL, 0, 0, NULL, 0),
458 SND_SOC_DAPM_PGA("Lineout Right Playback",
459 SN95031_LOCTL, 4, 0, NULL, 0),
460
461 /* playback path filter enable */
462 SND_SOC_DAPM_PGA("Headset Left Filter",
463 SN95031_HSEPRXCTRL, 4, 0, NULL, 0),
464 SND_SOC_DAPM_PGA("Headset Right Filter",
465 SN95031_HSEPRXCTRL, 5, 0, NULL, 0),
466 SND_SOC_DAPM_PGA("Speaker Left Filter",
467 SN95031_IHFRXCTRL, 0, 0, NULL, 0),
468 SND_SOC_DAPM_PGA("Speaker Right Filter",
469 SN95031_IHFRXCTRL, 1, 0, NULL, 0),
470
471 /* DACs */
472 SND_SOC_DAPM_DAC("HSDAC Left", "Headset",
473 SN95031_DACCONFIG, 0, 0),
474 SND_SOC_DAPM_DAC("HSDAC Right", "Headset",
475 SN95031_DACCONFIG, 1, 0),
476 SND_SOC_DAPM_DAC("IHFDAC Left", "Speaker",
477 SN95031_DACCONFIG, 2, 0),
478 SND_SOC_DAPM_DAC("IHFDAC Right", "Speaker",
479 SN95031_DACCONFIG, 3, 0),
480 SND_SOC_DAPM_DAC("Vibra1 DAC", "Vibra1",
481 SN95031_VIB1C5, 1, 0),
482 SND_SOC_DAPM_DAC("Vibra2 DAC", "Vibra2",
483 SN95031_VIB2C5, 1, 0),
484
485 /* capture widgets */
486 SND_SOC_DAPM_PGA("LineIn Enable Left", SN95031_MICAMP1,
487 7, 0, NULL, 0),
488 SND_SOC_DAPM_PGA("LineIn Enable Right", SN95031_MICAMP2,
489 7, 0, NULL, 0),
490
491 SND_SOC_DAPM_PGA("MIC1 Enable", SN95031_MICAMP1, 0, 0, NULL, 0),
492 SND_SOC_DAPM_PGA("MIC2 Enable", SN95031_MICAMP2, 0, 0, NULL, 0),
493 SND_SOC_DAPM_PGA("TX1 Enable", SN95031_AUDIOTXEN, 2, 0, NULL, 0),
494 SND_SOC_DAPM_PGA("TX2 Enable", SN95031_AUDIOTXEN, 3, 0, NULL, 0),
495 SND_SOC_DAPM_PGA("TX3 Enable", SN95031_AUDIOTXEN, 4, 0, NULL, 0),
496 SND_SOC_DAPM_PGA("TX4 Enable", SN95031_AUDIOTXEN, 5, 0, NULL, 0),
497
498 /* ADC have null stream as they will be turned ON by TX path */
499 SND_SOC_DAPM_ADC("ADC Left", NULL,
500 SN95031_ADCCONFIG, 0, 0),
501 SND_SOC_DAPM_ADC("ADC Right", NULL,
502 SN95031_ADCCONFIG, 2, 0),
503
504 SND_SOC_DAPM_MUX("Mic_InputL Capture Route",
505 SND_SOC_NOPM, 0, 0, &sn95031_micl_mux_control),
506 SND_SOC_DAPM_MUX("Mic_InputR Capture Route",
507 SND_SOC_NOPM, 0, 0, &sn95031_micr_mux_control),
508
509 SND_SOC_DAPM_MUX("Txpath1 Capture Route",
510 SND_SOC_NOPM, 0, 0, &sn95031_input1_mux_control),
511 SND_SOC_DAPM_MUX("Txpath2 Capture Route",
512 SND_SOC_NOPM, 0, 0, &sn95031_input2_mux_control),
513 SND_SOC_DAPM_MUX("Txpath3 Capture Route",
514 SND_SOC_NOPM, 0, 0, &sn95031_input3_mux_control),
515 SND_SOC_DAPM_MUX("Txpath4 Capture Route",
516 SND_SOC_NOPM, 0, 0, &sn95031_input4_mux_control),
517
518};
519
520static const struct snd_soc_dapm_route sn95031_audio_map[] = {
521 /* headset and earpiece map */
522 { "HPOUTL", NULL, "Headset Rail"},
523 { "HPOUTR", NULL, "Headset Rail"},
524 { "HPOUTL", NULL, "Headset Left Playback" },
525 { "HPOUTR", NULL, "Headset Right Playback" },
526 { "EPOUT", NULL, "Earpiece Playback" },
527 { "Headset Left Playback", NULL, "Headset Left Filter"},
528 { "Headset Right Playback", NULL, "Headset Right Filter"},
529 { "Earpiece Playback", NULL, "Headset Left Filter"},
530 { "Headset Left Filter", NULL, "HSDAC Left"},
531 { "Headset Right Filter", NULL, "HSDAC Right"},
532
533 /* speaker map */
534 { "IHFOUTL", NULL, "Speaker Rail"},
535 { "IHFOUTR", NULL, "Speaker Rail"},
536 { "IHFOUTL", "NULL", "Speaker Left Playback"},
537 { "IHFOUTR", "NULL", "Speaker Right Playback"},
538 { "Speaker Left Playback", NULL, "Speaker Left Filter"},
539 { "Speaker Right Playback", NULL, "Speaker Right Filter"},
540 { "Speaker Left Filter", NULL, "IHFDAC Left"},
541 { "Speaker Right Filter", NULL, "IHFDAC Right"},
542
543 /* vibra map */
544 { "VIB1OUT", NULL, "Vibra1 Playback"},
545 { "Vibra1 Playback", NULL, "Vibra1 DAC"},
546
547 { "VIB2OUT", NULL, "Vibra2 Playback"},
548 { "Vibra2 Playback", NULL, "Vibra2 DAC"},
549
550 /* lineout */
551 { "LINEOUTL", NULL, "Lineout Left Playback"},
552 { "LINEOUTR", NULL, "Lineout Right Playback"},
553 { "Lineout Left Playback", NULL, "Headset Left Filter"},
554 { "Lineout Left Playback", NULL, "Speaker Left Filter"},
555 { "Lineout Left Playback", NULL, "Vibra1 DAC"},
556 { "Lineout Right Playback", NULL, "Headset Right Filter"},
557 { "Lineout Right Playback", NULL, "Speaker Right Filter"},
558 { "Lineout Right Playback", NULL, "Vibra2 DAC"},
559
560 /* Headset (AMIC1) mic */
561 { "AMIC1Bias", NULL, "AMIC1"},
562 { "MIC1 Enable", NULL, "AMIC1Bias"},
563 { "Mic_InputL Capture Route", "AMIC", "MIC1 Enable"},
564
565 /* AMIC2 */
566 { "AMIC2Bias", NULL, "AMIC2"},
567 { "MIC2 Enable", NULL, "AMIC2Bias"},
568 { "Mic_InputR Capture Route", "AMIC", "MIC2 Enable"},
569
570
571 /* Linein */
572 { "LineIn Enable Left", NULL, "LINEINL"},
573 { "LineIn Enable Right", NULL, "LINEINR"},
574 { "Mic_InputL Capture Route", "LineIn", "LineIn Enable Left"},
575 { "Mic_InputR Capture Route", "LineIn", "LineIn Enable Right"},
576
577 /* ADC connection */
578 { "ADC Left", NULL, "Mic_InputL Capture Route"},
579 { "ADC Right", NULL, "Mic_InputR Capture Route"},
580
581 /*DMIC connections */
582 { "DMIC1", NULL, "DMIC12supply"},
583 { "DMIC2", NULL, "DMIC12supply"},
584 { "DMIC3", NULL, "DMIC34supply"},
585 { "DMIC4", NULL, "DMIC34supply"},
586 { "DMIC5", NULL, "DMIC56supply"},
587 { "DMIC6", NULL, "DMIC56supply"},
588
589 { "DMIC12Bias", NULL, "DMIC1"},
590 { "DMIC12Bias", NULL, "DMIC2"},
591 { "DMIC34Bias", NULL, "DMIC3"},
592 { "DMIC34Bias", NULL, "DMIC4"},
593 { "DMIC56Bias", NULL, "DMIC5"},
594 { "DMIC56Bias", NULL, "DMIC6"},
595
596 /*TX path inputs*/
597 { "Txpath1 Capture Route", "ADC Left", "ADC Left"},
598 { "Txpath2 Capture Route", "ADC Left", "ADC Left"},
599 { "Txpath3 Capture Route", "ADC Left", "ADC Left"},
600 { "Txpath4 Capture Route", "ADC Left", "ADC Left"},
601 { "Txpath1 Capture Route", "ADC Right", "ADC Right"},
602 { "Txpath2 Capture Route", "ADC Right", "ADC Right"},
603 { "Txpath3 Capture Route", "ADC Right", "ADC Right"},
604 { "Txpath4 Capture Route", "ADC Right", "ADC Right"},
605 { "Txpath1 Capture Route", "DMIC1", "DMIC1"},
606 { "Txpath2 Capture Route", "DMIC1", "DMIC1"},
607 { "Txpath3 Capture Route", "DMIC1", "DMIC1"},
608 { "Txpath4 Capture Route", "DMIC1", "DMIC1"},
609 { "Txpath1 Capture Route", "DMIC2", "DMIC2"},
610 { "Txpath2 Capture Route", "DMIC2", "DMIC2"},
611 { "Txpath3 Capture Route", "DMIC2", "DMIC2"},
612 { "Txpath4 Capture Route", "DMIC2", "DMIC2"},
613 { "Txpath1 Capture Route", "DMIC3", "DMIC3"},
614 { "Txpath2 Capture Route", "DMIC3", "DMIC3"},
615 { "Txpath3 Capture Route", "DMIC3", "DMIC3"},
616 { "Txpath4 Capture Route", "DMIC3", "DMIC3"},
617 { "Txpath1 Capture Route", "DMIC4", "DMIC4"},
618 { "Txpath2 Capture Route", "DMIC4", "DMIC4"},
619 { "Txpath3 Capture Route", "DMIC4", "DMIC4"},
620 { "Txpath4 Capture Route", "DMIC4", "DMIC4"},
621 { "Txpath1 Capture Route", "DMIC5", "DMIC5"},
622 { "Txpath2 Capture Route", "DMIC5", "DMIC5"},
623 { "Txpath3 Capture Route", "DMIC5", "DMIC5"},
624 { "Txpath4 Capture Route", "DMIC5", "DMIC5"},
625 { "Txpath1 Capture Route", "DMIC6", "DMIC6"},
626 { "Txpath2 Capture Route", "DMIC6", "DMIC6"},
627 { "Txpath3 Capture Route", "DMIC6", "DMIC6"},
628 { "Txpath4 Capture Route", "DMIC6", "DMIC6"},
629
630 /* tx path */
631 { "TX1 Enable", NULL, "Txpath1 Capture Route"},
632 { "TX2 Enable", NULL, "Txpath2 Capture Route"},
633 { "TX3 Enable", NULL, "Txpath3 Capture Route"},
634 { "TX4 Enable", NULL, "Txpath4 Capture Route"},
635 { "PCM_Out", NULL, "TX1 Enable"},
636 { "PCM_Out", NULL, "TX2 Enable"},
637 { "PCM_Out", NULL, "TX3 Enable"},
638 { "PCM_Out", NULL, "TX4 Enable"},
639
640};
641
642/* speaker and headset mutes, for audio pops and clicks */
643static int sn95031_pcm_hs_mute(struct snd_soc_dai *dai, int mute)
644{
645 snd_soc_update_bits(dai->codec,
646 SN95031_HSLVOLCTRL, BIT(7), (!mute << 7));
647 snd_soc_update_bits(dai->codec,
648 SN95031_HSRVOLCTRL, BIT(7), (!mute << 7));
649 return 0;
650}
651
652static int sn95031_pcm_spkr_mute(struct snd_soc_dai *dai, int mute)
653{
654 snd_soc_update_bits(dai->codec,
655 SN95031_IHFLVOLCTRL, BIT(7), (!mute << 7));
656 snd_soc_update_bits(dai->codec,
657 SN95031_IHFRVOLCTRL, BIT(7), (!mute << 7));
658 return 0;
659}
660
661int sn95031_pcm_hw_params(struct snd_pcm_substream *substream,
662 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
663{
664 unsigned int format, rate;
665
666 switch (params_format(params)) {
667 case SNDRV_PCM_FORMAT_S16_LE:
668 format = BIT(4)|BIT(5);
669 break;
670
671 case SNDRV_PCM_FORMAT_S24_LE:
672 format = 0;
673 break;
674 default:
675 return -EINVAL;
676 }
677 snd_soc_update_bits(dai->codec, SN95031_PCM2C2,
678 BIT(4)|BIT(5), format);
679
680 switch (params_rate(params)) {
681 case 48000:
682 pr_debug("RATE_48000\n");
683 rate = 0;
684 break;
685
686 case 44100:
687 pr_debug("RATE_44100\n");
688 rate = BIT(7);
689 break;
690
691 default:
692 pr_err("ERR rate %d\n", params_rate(params));
693 return -EINVAL;
694 }
695 snd_soc_update_bits(dai->codec, SN95031_PCM1C1, BIT(7), rate);
696
697 return 0;
698}
699
700/* Codec DAI section */
701static struct snd_soc_dai_ops sn95031_headset_dai_ops = {
702 .digital_mute = sn95031_pcm_hs_mute,
703 .hw_params = sn95031_pcm_hw_params,
704};
705
706static struct snd_soc_dai_ops sn95031_speaker_dai_ops = {
707 .digital_mute = sn95031_pcm_spkr_mute,
708 .hw_params = sn95031_pcm_hw_params,
709};
710
711static struct snd_soc_dai_ops sn95031_vib1_dai_ops = {
712 .hw_params = sn95031_pcm_hw_params,
713};
714
715static struct snd_soc_dai_ops sn95031_vib2_dai_ops = {
716 .hw_params = sn95031_pcm_hw_params,
717};
718
719struct snd_soc_dai_driver sn95031_dais[] = {
720{
721 .name = "SN95031 Headset",
722 .playback = {
723 .stream_name = "Headset",
724 .channels_min = 2,
725 .channels_max = 2,
726 .rates = SN95031_RATES,
727 .formats = SN95031_FORMATS,
728 },
729 .capture = {
730 .stream_name = "Capture",
731 .channels_min = 1,
732 .channels_max = 5,
733 .rates = SN95031_RATES,
734 .formats = SN95031_FORMATS,
735 },
736 .ops = &sn95031_headset_dai_ops,
737},
738{ .name = "SN95031 Speaker",
739 .playback = {
740 .stream_name = "Speaker",
741 .channels_min = 2,
742 .channels_max = 2,
743 .rates = SN95031_RATES,
744 .formats = SN95031_FORMATS,
745 },
746 .ops = &sn95031_speaker_dai_ops,
747},
748{ .name = "SN95031 Vibra1",
749 .playback = {
750 .stream_name = "Vibra1",
751 .channels_min = 1,
752 .channels_max = 1,
753 .rates = SN95031_RATES,
754 .formats = SN95031_FORMATS,
755 },
756 .ops = &sn95031_vib1_dai_ops,
757},
758{ .name = "SN95031 Vibra2",
759 .playback = {
760 .stream_name = "Vibra2",
761 .channels_min = 1,
762 .channels_max = 1,
763 .rates = SN95031_RATES,
764 .formats = SN95031_FORMATS,
765 },
766 .ops = &sn95031_vib2_dai_ops,
767},
768};
769
770static inline void sn95031_disable_jack_btn(struct snd_soc_codec *codec)
771{
772 snd_soc_write(codec, SN95031_BTNCTRL2, 0x00);
773}
774
775static inline void sn95031_enable_jack_btn(struct snd_soc_codec *codec)
776{
777 snd_soc_write(codec, SN95031_BTNCTRL1, 0x77);
778 snd_soc_write(codec, SN95031_BTNCTRL2, 0x01);
779}
780
781static int sn95031_get_headset_state(struct snd_soc_jack *mfld_jack)
782{
783 int micbias = sn95031_get_mic_bias(mfld_jack->codec);
784
785 int jack_type = snd_soc_jack_get_type(mfld_jack, micbias);
786
787 pr_debug("jack type detected = %d\n", jack_type);
788 if (jack_type == SND_JACK_HEADSET)
789 sn95031_enable_jack_btn(mfld_jack->codec);
790 return jack_type;
791}
792
793void sn95031_jack_detection(struct mfld_jack_data *jack_data)
794{
795 unsigned int status;
796 unsigned int mask = SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_HEADSET;
797
798 pr_debug("interrupt id read in sram = 0x%x\n", jack_data->intr_id);
799 if (jack_data->intr_id & 0x1) {
800 pr_debug("short_push detected\n");
801 status = SND_JACK_HEADSET | SND_JACK_BTN_0;
802 } else if (jack_data->intr_id & 0x2) {
803 pr_debug("long_push detected\n");
804 status = SND_JACK_HEADSET | SND_JACK_BTN_1;
805 } else if (jack_data->intr_id & 0x4) {
806 pr_debug("headset or headphones inserted\n");
807 status = sn95031_get_headset_state(jack_data->mfld_jack);
808 } else if (jack_data->intr_id & 0x8) {
809 pr_debug("headset or headphones removed\n");
810 status = 0;
811 sn95031_disable_jack_btn(jack_data->mfld_jack->codec);
812 } else {
813 pr_err("unidentified interrupt\n");
814 return;
815 }
816
817 snd_soc_jack_report(jack_data->mfld_jack, status, mask);
818 /*button pressed and released so we send explicit button release */
819 if ((status & SND_JACK_BTN_0) | (status & SND_JACK_BTN_1))
820 snd_soc_jack_report(jack_data->mfld_jack,
821 SND_JACK_HEADSET, mask);
822}
823EXPORT_SYMBOL_GPL(sn95031_jack_detection);
824
825/* codec registration */
826static int sn95031_codec_probe(struct snd_soc_codec *codec)
827{
828 int ret;
829
830 pr_debug("codec_probe called\n");
831
832 codec->dapm.bias_level = SND_SOC_BIAS_OFF;
833 codec->dapm.idle_bias_off = 1;
834
835 /* PCM interface config
836 * This sets the pcm rx slot conguration to max 6 slots
837 * for max 4 dais (2 stereo and 2 mono)
838 */
839 snd_soc_write(codec, SN95031_PCM2RXSLOT01, 0x10);
840 snd_soc_write(codec, SN95031_PCM2RXSLOT23, 0x32);
841 snd_soc_write(codec, SN95031_PCM2RXSLOT45, 0x54);
842 snd_soc_write(codec, SN95031_PCM2TXSLOT01, 0x10);
843 snd_soc_write(codec, SN95031_PCM2TXSLOT23, 0x32);
844 /* pcm port setting
845 * This sets the pcm port to slave and clock at 19.2Mhz which
846 * can support 6slots, sampling rate set per stream in hw-params
847 */
848 snd_soc_write(codec, SN95031_PCM1C1, 0x00);
849 snd_soc_write(codec, SN95031_PCM2C1, 0x01);
850 snd_soc_write(codec, SN95031_PCM2C2, 0x0A);
851 snd_soc_write(codec, SN95031_HSMIXER, BIT(0)|BIT(4));
852 /* vendor vibra workround, the vibras are muted by
853 * custom register so unmute them
854 */
855 snd_soc_write(codec, SN95031_SSR5, 0x80);
856 snd_soc_write(codec, SN95031_SSR6, 0x80);
857 snd_soc_write(codec, SN95031_VIB1C5, 0x00);
858 snd_soc_write(codec, SN95031_VIB2C5, 0x00);
859 /* configure vibras for pcm port */
860 snd_soc_write(codec, SN95031_VIB1C3, 0x00);
861 snd_soc_write(codec, SN95031_VIB2C3, 0x00);
862
863 /* soft mute ramp time */
864 snd_soc_write(codec, SN95031_SOFTMUTE, 0x3);
865 /* fix the initial volume at 1dB,
866 * default in +9dB,
867 * 1dB give optimal swing on DAC, amps
868 */
869 snd_soc_write(codec, SN95031_HSLVOLCTRL, 0x08);
870 snd_soc_write(codec, SN95031_HSRVOLCTRL, 0x08);
871 snd_soc_write(codec, SN95031_IHFLVOLCTRL, 0x08);
872 snd_soc_write(codec, SN95031_IHFRVOLCTRL, 0x08);
873 /* dac mode and lineout workaround */
874 snd_soc_write(codec, SN95031_SSR2, 0x10);
875 snd_soc_write(codec, SN95031_SSR3, 0x40);
876
877 snd_soc_add_controls(codec, sn95031_snd_controls,
878 ARRAY_SIZE(sn95031_snd_controls));
879
880 ret = snd_soc_dapm_new_controls(&codec->dapm, sn95031_dapm_widgets,
881 ARRAY_SIZE(sn95031_dapm_widgets));
882 if (ret)
883 pr_err("soc_dapm_new_control failed %d", ret);
884 ret = snd_soc_dapm_add_routes(&codec->dapm, sn95031_audio_map,
885 ARRAY_SIZE(sn95031_audio_map));
886 if (ret)
887 pr_err("soc_dapm_add_routes failed %d", ret);
888
889 return ret;
890}
891
892static int sn95031_codec_remove(struct snd_soc_codec *codec)
893{
894 pr_debug("codec_remove called\n");
895 sn95031_set_vaud_bias(codec, SND_SOC_BIAS_OFF);
896
897 return 0;
898}
899
900struct snd_soc_codec_driver sn95031_codec = {
901 .probe = sn95031_codec_probe,
902 .remove = sn95031_codec_remove,
903 .read = sn95031_read,
904 .write = sn95031_write,
905 .set_bias_level = sn95031_set_vaud_bias,
906};
907
908static int __devinit sn95031_device_probe(struct platform_device *pdev)
909{
910 pr_debug("codec device probe called for %s\n", dev_name(&pdev->dev));
911 return snd_soc_register_codec(&pdev->dev, &sn95031_codec,
912 sn95031_dais, ARRAY_SIZE(sn95031_dais));
913}
914
915static int __devexit sn95031_device_remove(struct platform_device *pdev)
916{
917 pr_debug("codec device remove called\n");
918 snd_soc_unregister_codec(&pdev->dev);
919 return 0;
920}
921
922static struct platform_driver sn95031_codec_driver = {
923 .driver = {
924 .name = "sn95031",
925 .owner = THIS_MODULE,
926 },
927 .probe = sn95031_device_probe,
928 .remove = sn95031_device_remove,
929};
930
931static int __init sn95031_init(void)
932{
933 pr_debug("driver init called\n");
934 return platform_driver_register(&sn95031_codec_driver);
935}
936module_init(sn95031_init);
937
938static void __exit sn95031_exit(void)
939{
940 pr_debug("driver exit called\n");
941 platform_driver_unregister(&sn95031_codec_driver);
942}
943module_exit(sn95031_exit);
944
945MODULE_DESCRIPTION("ASoC TI SN95031 codec driver");
946MODULE_AUTHOR("Vinod Koul <vinod.koul@intel.com>");
947MODULE_AUTHOR("Harsha Priya <priya.harsha@intel.com>");
948MODULE_LICENSE("GPL v2");
949MODULE_ALIAS("platform:sn95031");
diff --git a/sound/soc/codecs/sn95031.h b/sound/soc/codecs/sn95031.h
new file mode 100644
index 000000000000..20376d234fb8
--- /dev/null
+++ b/sound/soc/codecs/sn95031.h
@@ -0,0 +1,132 @@
1/*
2 * sn95031.h - TI sn95031 Codec driver
3 *
4 * Copyright (C) 2010 Intel Corp
5 * Author: Vinod Koul <vinod.koul@intel.com>
6 * Author: Harsha Priya <priya.harsha@intel.com>
7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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 as published by
11 * the Free Software Foundation; version 2 of the License.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21 *
22 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
23 *
24 *
25 */
26#ifndef _SN95031_H
27#define _SN95031_H
28
29/*register map*/
30#define SN95031_VAUD 0xDB
31#define SN95031_VHSP 0xDC
32#define SN95031_VHSN 0xDD
33#define SN95031_VIHF 0xC9
34
35#define SN95031_AUDPLLCTRL 0x240
36#define SN95031_DMICBUF0123 0x241
37#define SN95031_DMICBUF45 0x242
38#define SN95031_DMICGPO 0x244
39#define SN95031_DMICMUX 0x245
40#define SN95031_DMICLK 0x246
41#define SN95031_MICBIAS 0x247
42#define SN95031_ADCCONFIG 0x248
43#define SN95031_MICAMP1 0x249
44#define SN95031_MICAMP2 0x24A
45#define SN95031_NOISEMUX 0x24B
46#define SN95031_AUDIOMUX12 0x24C
47#define SN95031_AUDIOMUX34 0x24D
48#define SN95031_AUDIOSINC 0x24E
49#define SN95031_AUDIOTXEN 0x24F
50#define SN95031_HSEPRXCTRL 0x250
51#define SN95031_IHFRXCTRL 0x251
52#define SN95031_HSMIXER 0x256
53#define SN95031_DACCONFIG 0x257
54#define SN95031_SOFTMUTE 0x258
55#define SN95031_HSLVOLCTRL 0x259
56#define SN95031_HSRVOLCTRL 0x25A
57#define SN95031_IHFLVOLCTRL 0x25B
58#define SN95031_IHFRVOLCTRL 0x25C
59#define SN95031_DRIVEREN 0x25D
60#define SN95031_LOCTL 0x25E
61#define SN95031_VIB1C1 0x25F
62#define SN95031_VIB1C2 0x260
63#define SN95031_VIB1C3 0x261
64#define SN95031_VIB1SPIPCM1 0x262
65#define SN95031_VIB1SPIPCM2 0x263
66#define SN95031_VIB1C5 0x264
67#define SN95031_VIB2C1 0x265
68#define SN95031_VIB2C2 0x266
69#define SN95031_VIB2C3 0x267
70#define SN95031_VIB2SPIPCM1 0x268
71#define SN95031_VIB2SPIPCM2 0x269
72#define SN95031_VIB2C5 0x26A
73#define SN95031_BTNCTRL1 0x26B
74#define SN95031_BTNCTRL2 0x26C
75#define SN95031_PCM1TXSLOT01 0x26D
76#define SN95031_PCM1TXSLOT23 0x26E
77#define SN95031_PCM1TXSLOT45 0x26F
78#define SN95031_PCM1RXSLOT0_3 0x270
79#define SN95031_PCM1RXSLOT45 0x271
80#define SN95031_PCM2TXSLOT01 0x272
81#define SN95031_PCM2TXSLOT23 0x273
82#define SN95031_PCM2TXSLOT45 0x274
83#define SN95031_PCM2RXSLOT01 0x275
84#define SN95031_PCM2RXSLOT23 0x276
85#define SN95031_PCM2RXSLOT45 0x277
86#define SN95031_PCM1C1 0x278
87#define SN95031_PCM1C2 0x279
88#define SN95031_PCM1C3 0x27A
89#define SN95031_PCM2C1 0x27B
90#define SN95031_PCM2C2 0x27C
91/*end codec register defn*/
92
93/*vendor defn these are not part of avp*/
94#define SN95031_SSR2 0x381
95#define SN95031_SSR3 0x382
96#define SN95031_SSR5 0x384
97#define SN95031_SSR6 0x385
98
99/* ADC registers */
100
101#define SN95031_ADC1CNTL1 0x1C0
102#define SN95031_ADC_ENBL 0x10
103#define SN95031_ADC_START 0x08
104#define SN95031_ADC1CNTL3 0x1C2
105#define SN95031_ADCTHERM_ENBL 0x04
106#define SN95031_ADCRRDATA_ENBL 0x05
107#define SN95031_STOPBIT_MASK 16
108#define SN95031_ADCTHERM_MASK 4
109#define SN95031_ADC_CHANLS_MAX 15 /* Number of ADC channels */
110#define SN95031_ADC_LOOP_MAX (SN95031_ADC_CHANLS_MAX - 1)
111#define SN95031_ADC_NO_LOOP 0x07
112#define SN95031_AUDIO_GPIO_CTRL 0x070
113
114/* ADC channel code values */
115#define SN95031_AUDIO_DETECT_CODE 0x06
116
117/* ADC base addresses */
118#define SN95031_ADC_CHNL_START_ADDR 0x1C5 /* increments by 1 */
119#define SN95031_ADC_DATA_START_ADDR 0x1D4 /* increments by 2 */
120/* multipier to convert to mV */
121#define SN95031_ADC_ONE_LSB_MULTIPLIER 2346
122
123
124struct mfld_jack_data {
125 int intr_id;
126 int micbias_vol;
127 struct snd_soc_jack *mfld_jack;
128};
129
130extern void sn95031_jack_detection(struct mfld_jack_data *jack_data);
131
132#endif
diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c
new file mode 100644
index 000000000000..e93b9d1ae1dd
--- /dev/null
+++ b/sound/soc/codecs/tlv320aic32x4.c
@@ -0,0 +1,794 @@
1/*
2 * linux/sound/soc/codecs/tlv320aic32x4.c
3 *
4 * Copyright 2011 Vista Silicon S.L.
5 *
6 * Author: Javier Martin <javier.martin@vista-silicon.com>
7 *
8 * Based on sound/soc/codecs/wm8974 and TI driver for kernel 2.6.27.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU 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 Street, Fifth Floor, Boston,
23 * MA 02110-1301, USA.
24 */
25
26#include <linux/module.h>
27#include <linux/moduleparam.h>
28#include <linux/init.h>
29#include <linux/delay.h>
30#include <linux/pm.h>
31#include <linux/i2c.h>
32#include <linux/platform_device.h>
33#include <linux/cdev.h>
34#include <linux/slab.h>
35
36#include <sound/tlv320aic32x4.h>
37#include <sound/core.h>
38#include <sound/pcm.h>
39#include <sound/pcm_params.h>
40#include <sound/soc.h>
41#include <sound/soc-dapm.h>
42#include <sound/initval.h>
43#include <sound/tlv.h>
44
45#include "tlv320aic32x4.h"
46
47struct aic32x4_rate_divs {
48 u32 mclk;
49 u32 rate;
50 u8 p_val;
51 u8 pll_j;
52 u16 pll_d;
53 u16 dosr;
54 u8 ndac;
55 u8 mdac;
56 u8 aosr;
57 u8 nadc;
58 u8 madc;
59 u8 blck_N;
60};
61
62struct aic32x4_priv {
63 u32 sysclk;
64 s32 master;
65 u8 page_no;
66 void *control_data;
67 u32 power_cfg;
68 u32 micpga_routing;
69 bool swapdacs;
70};
71
72/* 0dB min, 1dB steps */
73static DECLARE_TLV_DB_SCALE(tlv_step_1, 0, 100, 0);
74/* 0dB min, 0.5dB steps */
75static DECLARE_TLV_DB_SCALE(tlv_step_0_5, 0, 50, 0);
76
77static const struct snd_kcontrol_new aic32x4_snd_controls[] = {
78 SOC_DOUBLE_R_TLV("PCM Playback Volume", AIC32X4_LDACVOL,
79 AIC32X4_RDACVOL, 0, 0x30, 0, tlv_step_0_5),
80 SOC_DOUBLE_R_TLV("HP Driver Gain Volume", AIC32X4_HPLGAIN,
81 AIC32X4_HPRGAIN, 0, 0x1D, 0, tlv_step_1),
82 SOC_DOUBLE_R_TLV("LO Driver Gain Volume", AIC32X4_LOLGAIN,
83 AIC32X4_LORGAIN, 0, 0x1D, 0, tlv_step_1),
84 SOC_DOUBLE_R("HP DAC Playback Switch", AIC32X4_HPLGAIN,
85 AIC32X4_HPRGAIN, 6, 0x01, 1),
86 SOC_DOUBLE_R("LO DAC Playback Switch", AIC32X4_LOLGAIN,
87 AIC32X4_LORGAIN, 6, 0x01, 1),
88 SOC_DOUBLE_R("Mic PGA Switch", AIC32X4_LMICPGAVOL,
89 AIC32X4_RMICPGAVOL, 7, 0x01, 1),
90
91 SOC_SINGLE("ADCFGA Left Mute Switch", AIC32X4_ADCFGA, 7, 1, 0),
92 SOC_SINGLE("ADCFGA Right Mute Switch", AIC32X4_ADCFGA, 3, 1, 0),
93
94 SOC_DOUBLE_R_TLV("ADC Level Volume", AIC32X4_LADCVOL,
95 AIC32X4_RADCVOL, 0, 0x28, 0, tlv_step_0_5),
96 SOC_DOUBLE_R_TLV("PGA Level Volume", AIC32X4_LMICPGAVOL,
97 AIC32X4_RMICPGAVOL, 0, 0x5f, 0, tlv_step_0_5),
98
99 SOC_SINGLE("Auto-mute Switch", AIC32X4_DACMUTE, 4, 7, 0),
100
101 SOC_SINGLE("AGC Left Switch", AIC32X4_LAGC1, 7, 1, 0),
102 SOC_SINGLE("AGC Right Switch", AIC32X4_RAGC1, 7, 1, 0),
103 SOC_DOUBLE_R("AGC Target Level", AIC32X4_LAGC1, AIC32X4_RAGC1,
104 4, 0x07, 0),
105 SOC_DOUBLE_R("AGC Gain Hysteresis", AIC32X4_LAGC1, AIC32X4_RAGC1,
106 0, 0x03, 0),
107 SOC_DOUBLE_R("AGC Hysteresis", AIC32X4_LAGC2, AIC32X4_RAGC2,
108 6, 0x03, 0),
109 SOC_DOUBLE_R("AGC Noise Threshold", AIC32X4_LAGC2, AIC32X4_RAGC2,
110 1, 0x1F, 0),
111 SOC_DOUBLE_R("AGC Max PGA", AIC32X4_LAGC3, AIC32X4_RAGC3,
112 0, 0x7F, 0),
113 SOC_DOUBLE_R("AGC Attack Time", AIC32X4_LAGC4, AIC32X4_RAGC4,
114 3, 0x1F, 0),
115 SOC_DOUBLE_R("AGC Decay Time", AIC32X4_LAGC5, AIC32X4_RAGC5,
116 3, 0x1F, 0),
117 SOC_DOUBLE_R("AGC Noise Debounce", AIC32X4_LAGC6, AIC32X4_RAGC6,
118 0, 0x1F, 0),
119 SOC_DOUBLE_R("AGC Signal Debounce", AIC32X4_LAGC7, AIC32X4_RAGC7,
120 0, 0x0F, 0),
121};
122
123static const struct aic32x4_rate_divs aic32x4_divs[] = {
124 /* 8k rate */
125 {AIC32X4_FREQ_12000000, 8000, 1, 7, 6800, 768, 5, 3, 128, 5, 18, 24},
126 {AIC32X4_FREQ_24000000, 8000, 2, 7, 6800, 768, 15, 1, 64, 45, 4, 24},
127 {AIC32X4_FREQ_25000000, 8000, 2, 7, 3728, 768, 15, 1, 64, 45, 4, 24},
128 /* 11.025k rate */
129 {AIC32X4_FREQ_12000000, 11025, 1, 7, 5264, 512, 8, 2, 128, 8, 8, 16},
130 {AIC32X4_FREQ_24000000, 11025, 2, 7, 5264, 512, 16, 1, 64, 32, 4, 16},
131 /* 16k rate */
132 {AIC32X4_FREQ_12000000, 16000, 1, 7, 6800, 384, 5, 3, 128, 5, 9, 12},
133 {AIC32X4_FREQ_24000000, 16000, 2, 7, 6800, 384, 15, 1, 64, 18, 5, 12},
134 {AIC32X4_FREQ_25000000, 16000, 2, 7, 3728, 384, 15, 1, 64, 18, 5, 12},
135 /* 22.05k rate */
136 {AIC32X4_FREQ_12000000, 22050, 1, 7, 5264, 256, 4, 4, 128, 4, 8, 8},
137 {AIC32X4_FREQ_24000000, 22050, 2, 7, 5264, 256, 16, 1, 64, 16, 4, 8},
138 {AIC32X4_FREQ_25000000, 22050, 2, 7, 2253, 256, 16, 1, 64, 16, 4, 8},
139 /* 32k rate */
140 {AIC32X4_FREQ_12000000, 32000, 1, 7, 1680, 192, 2, 7, 64, 2, 21, 6},
141 {AIC32X4_FREQ_24000000, 32000, 2, 7, 1680, 192, 7, 2, 64, 7, 6, 6},
142 /* 44.1k rate */
143 {AIC32X4_FREQ_12000000, 44100, 1, 7, 5264, 128, 2, 8, 128, 2, 8, 4},
144 {AIC32X4_FREQ_24000000, 44100, 2, 7, 5264, 128, 8, 2, 64, 8, 4, 4},
145 {AIC32X4_FREQ_25000000, 44100, 2, 7, 2253, 128, 8, 2, 64, 8, 4, 4},
146 /* 48k rate */
147 {AIC32X4_FREQ_12000000, 48000, 1, 8, 1920, 128, 2, 8, 128, 2, 8, 4},
148 {AIC32X4_FREQ_24000000, 48000, 2, 8, 1920, 128, 8, 2, 64, 8, 4, 4},
149 {AIC32X4_FREQ_25000000, 48000, 2, 7, 8643, 128, 8, 2, 64, 8, 4, 4}
150};
151
152static const struct snd_kcontrol_new hpl_output_mixer_controls[] = {
153 SOC_DAPM_SINGLE("L_DAC Switch", AIC32X4_HPLROUTE, 3, 1, 0),
154 SOC_DAPM_SINGLE("IN1_L Switch", AIC32X4_HPLROUTE, 2, 1, 0),
155};
156
157static const struct snd_kcontrol_new hpr_output_mixer_controls[] = {
158 SOC_DAPM_SINGLE("R_DAC Switch", AIC32X4_HPRROUTE, 3, 1, 0),
159 SOC_DAPM_SINGLE("IN1_R Switch", AIC32X4_HPRROUTE, 2, 1, 0),
160};
161
162static const struct snd_kcontrol_new lol_output_mixer_controls[] = {
163 SOC_DAPM_SINGLE("L_DAC Switch", AIC32X4_LOLROUTE, 3, 1, 0),
164};
165
166static const struct snd_kcontrol_new lor_output_mixer_controls[] = {
167 SOC_DAPM_SINGLE("R_DAC Switch", AIC32X4_LORROUTE, 3, 1, 0),
168};
169
170static const struct snd_kcontrol_new left_input_mixer_controls[] = {
171 SOC_DAPM_SINGLE("IN1_L P Switch", AIC32X4_LMICPGAPIN, 6, 1, 0),
172 SOC_DAPM_SINGLE("IN2_L P Switch", AIC32X4_LMICPGAPIN, 4, 1, 0),
173 SOC_DAPM_SINGLE("IN3_L P Switch", AIC32X4_LMICPGAPIN, 2, 1, 0),
174};
175
176static const struct snd_kcontrol_new right_input_mixer_controls[] = {
177 SOC_DAPM_SINGLE("IN1_R P Switch", AIC32X4_RMICPGAPIN, 6, 1, 0),
178 SOC_DAPM_SINGLE("IN2_R P Switch", AIC32X4_RMICPGAPIN, 4, 1, 0),
179 SOC_DAPM_SINGLE("IN3_R P Switch", AIC32X4_RMICPGAPIN, 2, 1, 0),
180};
181
182static const struct snd_soc_dapm_widget aic32x4_dapm_widgets[] = {
183 SND_SOC_DAPM_DAC("Left DAC", "Left Playback", AIC32X4_DACSETUP, 7, 0),
184 SND_SOC_DAPM_MIXER("HPL Output Mixer", SND_SOC_NOPM, 0, 0,
185 &hpl_output_mixer_controls[0],
186 ARRAY_SIZE(hpl_output_mixer_controls)),
187 SND_SOC_DAPM_PGA("HPL Power", AIC32X4_OUTPWRCTL, 5, 0, NULL, 0),
188
189 SND_SOC_DAPM_MIXER("LOL Output Mixer", SND_SOC_NOPM, 0, 0,
190 &lol_output_mixer_controls[0],
191 ARRAY_SIZE(lol_output_mixer_controls)),
192 SND_SOC_DAPM_PGA("LOL Power", AIC32X4_OUTPWRCTL, 3, 0, NULL, 0),
193
194 SND_SOC_DAPM_DAC("Right DAC", "Right Playback", AIC32X4_DACSETUP, 6, 0),
195 SND_SOC_DAPM_MIXER("HPR Output Mixer", SND_SOC_NOPM, 0, 0,
196 &hpr_output_mixer_controls[0],
197 ARRAY_SIZE(hpr_output_mixer_controls)),
198 SND_SOC_DAPM_PGA("HPR Power", AIC32X4_OUTPWRCTL, 4, 0, NULL, 0),
199 SND_SOC_DAPM_MIXER("LOR Output Mixer", SND_SOC_NOPM, 0, 0,
200 &lor_output_mixer_controls[0],
201 ARRAY_SIZE(lor_output_mixer_controls)),
202 SND_SOC_DAPM_PGA("LOR Power", AIC32X4_OUTPWRCTL, 2, 0, NULL, 0),
203 SND_SOC_DAPM_MIXER("Left Input Mixer", SND_SOC_NOPM, 0, 0,
204 &left_input_mixer_controls[0],
205 ARRAY_SIZE(left_input_mixer_controls)),
206 SND_SOC_DAPM_MIXER("Right Input Mixer", SND_SOC_NOPM, 0, 0,
207 &right_input_mixer_controls[0],
208 ARRAY_SIZE(right_input_mixer_controls)),
209 SND_SOC_DAPM_ADC("Left ADC", "Left Capture", AIC32X4_ADCSETUP, 7, 0),
210 SND_SOC_DAPM_ADC("Right ADC", "Right Capture", AIC32X4_ADCSETUP, 6, 0),
211 SND_SOC_DAPM_MICBIAS("Mic Bias", AIC32X4_MICBIAS, 6, 0),
212
213 SND_SOC_DAPM_OUTPUT("HPL"),
214 SND_SOC_DAPM_OUTPUT("HPR"),
215 SND_SOC_DAPM_OUTPUT("LOL"),
216 SND_SOC_DAPM_OUTPUT("LOR"),
217 SND_SOC_DAPM_INPUT("IN1_L"),
218 SND_SOC_DAPM_INPUT("IN1_R"),
219 SND_SOC_DAPM_INPUT("IN2_L"),
220 SND_SOC_DAPM_INPUT("IN2_R"),
221 SND_SOC_DAPM_INPUT("IN3_L"),
222 SND_SOC_DAPM_INPUT("IN3_R"),
223};
224
225static const struct snd_soc_dapm_route aic32x4_dapm_routes[] = {
226 /* Left Output */
227 {"HPL Output Mixer", "L_DAC Switch", "Left DAC"},
228 {"HPL Output Mixer", "IN1_L Switch", "IN1_L"},
229
230 {"HPL Power", NULL, "HPL Output Mixer"},
231 {"HPL", NULL, "HPL Power"},
232
233 {"LOL Output Mixer", "L_DAC Switch", "Left DAC"},
234
235 {"LOL Power", NULL, "LOL Output Mixer"},
236 {"LOL", NULL, "LOL Power"},
237
238 /* Right Output */
239 {"HPR Output Mixer", "R_DAC Switch", "Right DAC"},
240 {"HPR Output Mixer", "IN1_R Switch", "IN1_R"},
241
242 {"HPR Power", NULL, "HPR Output Mixer"},
243 {"HPR", NULL, "HPR Power"},
244
245 {"LOR Output Mixer", "R_DAC Switch", "Right DAC"},
246
247 {"LOR Power", NULL, "LOR Output Mixer"},
248 {"LOR", NULL, "LOR Power"},
249
250 /* Left input */
251 {"Left Input Mixer", "IN1_L P Switch", "IN1_L"},
252 {"Left Input Mixer", "IN2_L P Switch", "IN2_L"},
253 {"Left Input Mixer", "IN3_L P Switch", "IN3_L"},
254
255 {"Left ADC", NULL, "Left Input Mixer"},
256
257 /* Right Input */
258 {"Right Input Mixer", "IN1_R P Switch", "IN1_R"},
259 {"Right Input Mixer", "IN2_R P Switch", "IN2_R"},
260 {"Right Input Mixer", "IN3_R P Switch", "IN3_R"},
261
262 {"Right ADC", NULL, "Right Input Mixer"},
263};
264
265static inline int aic32x4_change_page(struct snd_soc_codec *codec,
266 unsigned int new_page)
267{
268 struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
269 u8 data[2];
270 int ret;
271
272 data[0] = 0x00;
273 data[1] = new_page & 0xff;
274
275 ret = codec->hw_write(codec->control_data, data, 2);
276 if (ret == 2) {
277 aic32x4->page_no = new_page;
278 return 0;
279 } else {
280 return ret;
281 }
282}
283
284static int aic32x4_write(struct snd_soc_codec *codec, unsigned int reg,
285 unsigned int val)
286{
287 struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
288 unsigned int page = reg / 128;
289 unsigned int fixed_reg = reg % 128;
290 u8 data[2];
291 int ret;
292
293 /* A write to AIC32X4_PSEL is really a non-explicit page change */
294 if (reg == AIC32X4_PSEL)
295 return aic32x4_change_page(codec, val);
296
297 if (aic32x4->page_no != page) {
298 ret = aic32x4_change_page(codec, page);
299 if (ret != 0)
300 return ret;
301 }
302
303 data[0] = fixed_reg & 0xff;
304 data[1] = val & 0xff;
305
306 if (codec->hw_write(codec->control_data, data, 2) == 2)
307 return 0;
308 else
309 return -EIO;
310}
311
312static unsigned int aic32x4_read(struct snd_soc_codec *codec, unsigned int reg)
313{
314 struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
315 unsigned int page = reg / 128;
316 unsigned int fixed_reg = reg % 128;
317 int ret;
318
319 if (aic32x4->page_no != page) {
320 ret = aic32x4_change_page(codec, page);
321 if (ret != 0)
322 return ret;
323 }
324 return i2c_smbus_read_byte_data(codec->control_data, fixed_reg & 0xff);
325}
326
327static inline int aic32x4_get_divs(int mclk, int rate)
328{
329 int i;
330
331 for (i = 0; i < ARRAY_SIZE(aic32x4_divs); i++) {
332 if ((aic32x4_divs[i].rate == rate)
333 && (aic32x4_divs[i].mclk == mclk)) {
334 return i;
335 }
336 }
337 printk(KERN_ERR "aic32x4: master clock and sample rate is not supported\n");
338 return -EINVAL;
339}
340
341static int aic32x4_add_widgets(struct snd_soc_codec *codec)
342{
343 snd_soc_dapm_new_controls(&codec->dapm, aic32x4_dapm_widgets,
344 ARRAY_SIZE(aic32x4_dapm_widgets));
345
346 snd_soc_dapm_add_routes(&codec->dapm, aic32x4_dapm_routes,
347 ARRAY_SIZE(aic32x4_dapm_routes));
348
349 snd_soc_dapm_new_widgets(&codec->dapm);
350 return 0;
351}
352
353static int aic32x4_set_dai_sysclk(struct snd_soc_dai *codec_dai,
354 int clk_id, unsigned int freq, int dir)
355{
356 struct snd_soc_codec *codec = codec_dai->codec;
357 struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
358
359 switch (freq) {
360 case AIC32X4_FREQ_12000000:
361 case AIC32X4_FREQ_24000000:
362 case AIC32X4_FREQ_25000000:
363 aic32x4->sysclk = freq;
364 return 0;
365 }
366 printk(KERN_ERR "aic32x4: invalid frequency to set DAI system clock\n");
367 return -EINVAL;
368}
369
370static int aic32x4_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
371{
372 struct snd_soc_codec *codec = codec_dai->codec;
373 struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
374 u8 iface_reg_1;
375 u8 iface_reg_2;
376 u8 iface_reg_3;
377
378 iface_reg_1 = snd_soc_read(codec, AIC32X4_IFACE1);
379 iface_reg_1 = iface_reg_1 & ~(3 << 6 | 3 << 2);
380 iface_reg_2 = snd_soc_read(codec, AIC32X4_IFACE2);
381 iface_reg_2 = 0;
382 iface_reg_3 = snd_soc_read(codec, AIC32X4_IFACE3);
383 iface_reg_3 = iface_reg_3 & ~(1 << 3);
384
385 /* set master/slave audio interface */
386 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
387 case SND_SOC_DAIFMT_CBM_CFM:
388 aic32x4->master = 1;
389 iface_reg_1 |= AIC32X4_BCLKMASTER | AIC32X4_WCLKMASTER;
390 break;
391 case SND_SOC_DAIFMT_CBS_CFS:
392 aic32x4->master = 0;
393 break;
394 default:
395 printk(KERN_ERR "aic32x4: invalid DAI master/slave interface\n");
396 return -EINVAL;
397 }
398
399 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
400 case SND_SOC_DAIFMT_I2S:
401 break;
402 case SND_SOC_DAIFMT_DSP_A:
403 iface_reg_1 |= (AIC32X4_DSP_MODE << AIC32X4_PLLJ_SHIFT);
404 iface_reg_3 |= (1 << 3); /* invert bit clock */
405 iface_reg_2 = 0x01; /* add offset 1 */
406 break;
407 case SND_SOC_DAIFMT_DSP_B:
408 iface_reg_1 |= (AIC32X4_DSP_MODE << AIC32X4_PLLJ_SHIFT);
409 iface_reg_3 |= (1 << 3); /* invert bit clock */
410 break;
411 case SND_SOC_DAIFMT_RIGHT_J:
412 iface_reg_1 |=
413 (AIC32X4_RIGHT_JUSTIFIED_MODE << AIC32X4_PLLJ_SHIFT);
414 break;
415 case SND_SOC_DAIFMT_LEFT_J:
416 iface_reg_1 |=
417 (AIC32X4_LEFT_JUSTIFIED_MODE << AIC32X4_PLLJ_SHIFT);
418 break;
419 default:
420 printk(KERN_ERR "aic32x4: invalid DAI interface format\n");
421 return -EINVAL;
422 }
423
424 snd_soc_write(codec, AIC32X4_IFACE1, iface_reg_1);
425 snd_soc_write(codec, AIC32X4_IFACE2, iface_reg_2);
426 snd_soc_write(codec, AIC32X4_IFACE3, iface_reg_3);
427 return 0;
428}
429
430static int aic32x4_hw_params(struct snd_pcm_substream *substream,
431 struct snd_pcm_hw_params *params,
432 struct snd_soc_dai *dai)
433{
434 struct snd_soc_codec *codec = dai->codec;
435 struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
436 u8 data;
437 int i;
438
439 i = aic32x4_get_divs(aic32x4->sysclk, params_rate(params));
440 if (i < 0) {
441 printk(KERN_ERR "aic32x4: sampling rate not supported\n");
442 return i;
443 }
444
445 /* Use PLL as CODEC_CLKIN and DAC_MOD_CLK as BDIV_CLKIN */
446 snd_soc_write(codec, AIC32X4_CLKMUX, AIC32X4_PLLCLKIN);
447 snd_soc_write(codec, AIC32X4_IFACE3, AIC32X4_DACMOD2BCLK);
448
449 /* We will fix R value to 1 and will make P & J=K.D as varialble */
450 data = snd_soc_read(codec, AIC32X4_PLLPR);
451 data &= ~(7 << 4);
452 snd_soc_write(codec, AIC32X4_PLLPR,
453 (data | (aic32x4_divs[i].p_val << 4) | 0x01));
454
455 snd_soc_write(codec, AIC32X4_PLLJ, aic32x4_divs[i].pll_j);
456
457 snd_soc_write(codec, AIC32X4_PLLDMSB, (aic32x4_divs[i].pll_d >> 8));
458 snd_soc_write(codec, AIC32X4_PLLDLSB,
459 (aic32x4_divs[i].pll_d & 0xff));
460
461 /* NDAC divider value */
462 data = snd_soc_read(codec, AIC32X4_NDAC);
463 data &= ~(0x7f);
464 snd_soc_write(codec, AIC32X4_NDAC, data | aic32x4_divs[i].ndac);
465
466 /* MDAC divider value */
467 data = snd_soc_read(codec, AIC32X4_MDAC);
468 data &= ~(0x7f);
469 snd_soc_write(codec, AIC32X4_MDAC, data | aic32x4_divs[i].mdac);
470
471 /* DOSR MSB & LSB values */
472 snd_soc_write(codec, AIC32X4_DOSRMSB, aic32x4_divs[i].dosr >> 8);
473 snd_soc_write(codec, AIC32X4_DOSRLSB,
474 (aic32x4_divs[i].dosr & 0xff));
475
476 /* NADC divider value */
477 data = snd_soc_read(codec, AIC32X4_NADC);
478 data &= ~(0x7f);
479 snd_soc_write(codec, AIC32X4_NADC, data | aic32x4_divs[i].nadc);
480
481 /* MADC divider value */
482 data = snd_soc_read(codec, AIC32X4_MADC);
483 data &= ~(0x7f);
484 snd_soc_write(codec, AIC32X4_MADC, data | aic32x4_divs[i].madc);
485
486 /* AOSR value */
487 snd_soc_write(codec, AIC32X4_AOSR, aic32x4_divs[i].aosr);
488
489 /* BCLK N divider */
490 data = snd_soc_read(codec, AIC32X4_BCLKN);
491 data &= ~(0x7f);
492 snd_soc_write(codec, AIC32X4_BCLKN, data | aic32x4_divs[i].blck_N);
493
494 data = snd_soc_read(codec, AIC32X4_IFACE1);
495 data = data & ~(3 << 4);
496 switch (params_format(params)) {
497 case SNDRV_PCM_FORMAT_S16_LE:
498 break;
499 case SNDRV_PCM_FORMAT_S20_3LE:
500 data |= (AIC32X4_WORD_LEN_20BITS << AIC32X4_DOSRMSB_SHIFT);
501 break;
502 case SNDRV_PCM_FORMAT_S24_LE:
503 data |= (AIC32X4_WORD_LEN_24BITS << AIC32X4_DOSRMSB_SHIFT);
504 break;
505 case SNDRV_PCM_FORMAT_S32_LE:
506 data |= (AIC32X4_WORD_LEN_32BITS << AIC32X4_DOSRMSB_SHIFT);
507 break;
508 }
509 snd_soc_write(codec, AIC32X4_IFACE1, data);
510
511 return 0;
512}
513
514static int aic32x4_mute(struct snd_soc_dai *dai, int mute)
515{
516 struct snd_soc_codec *codec = dai->codec;
517 u8 dac_reg;
518
519 dac_reg = snd_soc_read(codec, AIC32X4_DACMUTE) & ~AIC32X4_MUTEON;
520 if (mute)
521 snd_soc_write(codec, AIC32X4_DACMUTE, dac_reg | AIC32X4_MUTEON);
522 else
523 snd_soc_write(codec, AIC32X4_DACMUTE, dac_reg);
524 return 0;
525}
526
527static int aic32x4_set_bias_level(struct snd_soc_codec *codec,
528 enum snd_soc_bias_level level)
529{
530 struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
531 u8 value;
532
533 switch (level) {
534 case SND_SOC_BIAS_ON:
535 if (aic32x4->master) {
536 /* Switch on PLL */
537 value = snd_soc_read(codec, AIC32X4_PLLPR);
538 snd_soc_write(codec, AIC32X4_PLLPR,
539 (value | AIC32X4_PLLEN));
540
541 /* Switch on NDAC Divider */
542 value = snd_soc_read(codec, AIC32X4_NDAC);
543 snd_soc_write(codec, AIC32X4_NDAC,
544 value | AIC32X4_NDACEN);
545
546 /* Switch on MDAC Divider */
547 value = snd_soc_read(codec, AIC32X4_MDAC);
548 snd_soc_write(codec, AIC32X4_MDAC,
549 value | AIC32X4_MDACEN);
550
551 /* Switch on NADC Divider */
552 value = snd_soc_read(codec, AIC32X4_NADC);
553 snd_soc_write(codec, AIC32X4_NADC,
554 value | AIC32X4_MDACEN);
555
556 /* Switch on MADC Divider */
557 value = snd_soc_read(codec, AIC32X4_MADC);
558 snd_soc_write(codec, AIC32X4_MADC,
559 value | AIC32X4_MDACEN);
560
561 /* Switch on BCLK_N Divider */
562 value = snd_soc_read(codec, AIC32X4_BCLKN);
563 snd_soc_write(codec, AIC32X4_BCLKN,
564 value | AIC32X4_BCLKEN);
565 }
566 break;
567 case SND_SOC_BIAS_PREPARE:
568 break;
569 case SND_SOC_BIAS_STANDBY:
570 if (aic32x4->master) {
571 /* Switch off PLL */
572 value = snd_soc_read(codec, AIC32X4_PLLPR);
573 snd_soc_write(codec, AIC32X4_PLLPR,
574 (value & ~AIC32X4_PLLEN));
575
576 /* Switch off NDAC Divider */
577 value = snd_soc_read(codec, AIC32X4_NDAC);
578 snd_soc_write(codec, AIC32X4_NDAC,
579 value & ~AIC32X4_NDACEN);
580
581 /* Switch off MDAC Divider */
582 value = snd_soc_read(codec, AIC32X4_MDAC);
583 snd_soc_write(codec, AIC32X4_MDAC,
584 value & ~AIC32X4_MDACEN);
585
586 /* Switch off NADC Divider */
587 value = snd_soc_read(codec, AIC32X4_NADC);
588 snd_soc_write(codec, AIC32X4_NADC,
589 value & ~AIC32X4_NDACEN);
590
591 /* Switch off MADC Divider */
592 value = snd_soc_read(codec, AIC32X4_MADC);
593 snd_soc_write(codec, AIC32X4_MADC,
594 value & ~AIC32X4_MDACEN);
595 value = snd_soc_read(codec, AIC32X4_BCLKN);
596
597 /* Switch off BCLK_N Divider */
598 snd_soc_write(codec, AIC32X4_BCLKN,
599 value & ~AIC32X4_BCLKEN);
600 }
601 break;
602 case SND_SOC_BIAS_OFF:
603 break;
604 }
605 codec->dapm.bias_level = level;
606 return 0;
607}
608
609#define AIC32X4_RATES SNDRV_PCM_RATE_8000_48000
610#define AIC32X4_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE \
611 | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
612
613static struct snd_soc_dai_ops aic32x4_ops = {
614 .hw_params = aic32x4_hw_params,
615 .digital_mute = aic32x4_mute,
616 .set_fmt = aic32x4_set_dai_fmt,
617 .set_sysclk = aic32x4_set_dai_sysclk,
618};
619
620static struct snd_soc_dai_driver aic32x4_dai = {
621 .name = "tlv320aic32x4-hifi",
622 .playback = {
623 .stream_name = "Playback",
624 .channels_min = 1,
625 .channels_max = 2,
626 .rates = AIC32X4_RATES,
627 .formats = AIC32X4_FORMATS,},
628 .capture = {
629 .stream_name = "Capture",
630 .channels_min = 1,
631 .channels_max = 2,
632 .rates = AIC32X4_RATES,
633 .formats = AIC32X4_FORMATS,},
634 .ops = &aic32x4_ops,
635 .symmetric_rates = 1,
636};
637
638static int aic32x4_suspend(struct snd_soc_codec *codec, pm_message_t state)
639{
640 aic32x4_set_bias_level(codec, SND_SOC_BIAS_OFF);
641 return 0;
642}
643
644static int aic32x4_resume(struct snd_soc_codec *codec)
645{
646 aic32x4_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
647 return 0;
648}
649
650static int aic32x4_probe(struct snd_soc_codec *codec)
651{
652 struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
653 u32 tmp_reg;
654
655 codec->hw_write = (hw_write_t) i2c_master_send;
656 codec->control_data = aic32x4->control_data;
657
658 snd_soc_write(codec, AIC32X4_RESET, 0x01);
659
660 /* Power platform configuration */
661 if (aic32x4->power_cfg & AIC32X4_PWR_MICBIAS_2075_LDOIN) {
662 snd_soc_write(codec, AIC32X4_MICBIAS, AIC32X4_MICBIAS_LDOIN |
663 AIC32X4_MICBIAS_2075V);
664 }
665 if (aic32x4->power_cfg & AIC32X4_PWR_AVDD_DVDD_WEAK_DISABLE) {
666 snd_soc_write(codec, AIC32X4_PWRCFG, AIC32X4_AVDDWEAKDISABLE);
667 }
668 if (aic32x4->power_cfg & AIC32X4_PWR_AIC32X4_LDO_ENABLE) {
669 snd_soc_write(codec, AIC32X4_LDOCTL, AIC32X4_LDOCTLEN);
670 }
671 tmp_reg = snd_soc_read(codec, AIC32X4_CMMODE);
672 if (aic32x4->power_cfg & AIC32X4_PWR_CMMODE_LDOIN_RANGE_18_36) {
673 tmp_reg |= AIC32X4_LDOIN_18_36;
674 }
675 if (aic32x4->power_cfg & AIC32X4_PWR_CMMODE_HP_LDOIN_POWERED) {
676 tmp_reg |= AIC32X4_LDOIN2HP;
677 }
678 snd_soc_write(codec, AIC32X4_CMMODE, tmp_reg);
679
680 /* Do DACs need to be swapped? */
681 if (aic32x4->swapdacs) {
682 snd_soc_write(codec, AIC32X4_DACSETUP, AIC32X4_LDAC2RCHN | AIC32X4_RDAC2LCHN);
683 } else {
684 snd_soc_write(codec, AIC32X4_DACSETUP, AIC32X4_LDAC2LCHN | AIC32X4_RDAC2RCHN);
685 }
686
687 /* Mic PGA routing */
688 if (aic32x4->micpga_routing | AIC32X4_MICPGA_ROUTE_LMIC_IN2R_10K) {
689 snd_soc_write(codec, AIC32X4_LMICPGANIN, AIC32X4_LMICPGANIN_IN2R_10K);
690 }
691 if (aic32x4->micpga_routing | AIC32X4_MICPGA_ROUTE_RMIC_IN1L_10K) {
692 snd_soc_write(codec, AIC32X4_RMICPGANIN, AIC32X4_RMICPGANIN_IN1L_10K);
693 }
694
695 aic32x4_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
696 snd_soc_add_controls(codec, aic32x4_snd_controls,
697 ARRAY_SIZE(aic32x4_snd_controls));
698 aic32x4_add_widgets(codec);
699
700 return 0;
701}
702
703static int aic32x4_remove(struct snd_soc_codec *codec)
704{
705 aic32x4_set_bias_level(codec, SND_SOC_BIAS_OFF);
706 return 0;
707}
708
709static struct snd_soc_codec_driver soc_codec_dev_aic32x4 = {
710 .read = aic32x4_read,
711 .write = aic32x4_write,
712 .probe = aic32x4_probe,
713 .remove = aic32x4_remove,
714 .suspend = aic32x4_suspend,
715 .resume = aic32x4_resume,
716 .set_bias_level = aic32x4_set_bias_level,
717};
718
719static __devinit int aic32x4_i2c_probe(struct i2c_client *i2c,
720 const struct i2c_device_id *id)
721{
722 struct aic32x4_pdata *pdata = i2c->dev.platform_data;
723 struct aic32x4_priv *aic32x4;
724 int ret;
725
726 aic32x4 = kzalloc(sizeof(struct aic32x4_priv), GFP_KERNEL);
727 if (aic32x4 == NULL)
728 return -ENOMEM;
729
730 aic32x4->control_data = i2c;
731 i2c_set_clientdata(i2c, aic32x4);
732
733 if (pdata) {
734 aic32x4->power_cfg = pdata->power_cfg;
735 aic32x4->swapdacs = pdata->swapdacs;
736 aic32x4->micpga_routing = pdata->micpga_routing;
737 } else {
738 aic32x4->power_cfg = 0;
739 aic32x4->swapdacs = false;
740 aic32x4->micpga_routing = 0;
741 }
742
743 ret = snd_soc_register_codec(&i2c->dev,
744 &soc_codec_dev_aic32x4, &aic32x4_dai, 1);
745 if (ret < 0)
746 kfree(aic32x4);
747 return ret;
748}
749
750static __devexit int aic32x4_i2c_remove(struct i2c_client *client)
751{
752 snd_soc_unregister_codec(&client->dev);
753 kfree(i2c_get_clientdata(client));
754 return 0;
755}
756
757static const struct i2c_device_id aic32x4_i2c_id[] = {
758 { "tlv320aic32x4", 0 },
759 { }
760};
761MODULE_DEVICE_TABLE(i2c, aic32x4_i2c_id);
762
763static struct i2c_driver aic32x4_i2c_driver = {
764 .driver = {
765 .name = "tlv320aic32x4",
766 .owner = THIS_MODULE,
767 },
768 .probe = aic32x4_i2c_probe,
769 .remove = __devexit_p(aic32x4_i2c_remove),
770 .id_table = aic32x4_i2c_id,
771};
772
773static int __init aic32x4_modinit(void)
774{
775 int ret = 0;
776
777 ret = i2c_add_driver(&aic32x4_i2c_driver);
778 if (ret != 0) {
779 printk(KERN_ERR "Failed to register aic32x4 I2C driver: %d\n",
780 ret);
781 }
782 return ret;
783}
784module_init(aic32x4_modinit);
785
786static void __exit aic32x4_exit(void)
787{
788 i2c_del_driver(&aic32x4_i2c_driver);
789}
790module_exit(aic32x4_exit);
791
792MODULE_DESCRIPTION("ASoC tlv320aic32x4 codec driver");
793MODULE_AUTHOR("Javier Martin <javier.martin@vista-silicon.com>");
794MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/tlv320aic32x4.h b/sound/soc/codecs/tlv320aic32x4.h
new file mode 100644
index 000000000000..aae2b2440398
--- /dev/null
+++ b/sound/soc/codecs/tlv320aic32x4.h
@@ -0,0 +1,143 @@
1/*
2 * tlv320aic32x4.h
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9
10#ifndef _TLV320AIC32X4_H
11#define _TLV320AIC32X4_H
12
13/* tlv320aic32x4 register space (in decimal to match datasheet) */
14
15#define AIC32X4_PAGE1 128
16
17#define AIC32X4_PSEL 0
18#define AIC32X4_RESET 1
19#define AIC32X4_CLKMUX 4
20#define AIC32X4_PLLPR 5
21#define AIC32X4_PLLJ 6
22#define AIC32X4_PLLDMSB 7
23#define AIC32X4_PLLDLSB 8
24#define AIC32X4_NDAC 11
25#define AIC32X4_MDAC 12
26#define AIC32X4_DOSRMSB 13
27#define AIC32X4_DOSRLSB 14
28#define AIC32X4_NADC 18
29#define AIC32X4_MADC 19
30#define AIC32X4_AOSR 20
31#define AIC32X4_CLKMUX2 25
32#define AIC32X4_CLKOUTM 26
33#define AIC32X4_IFACE1 27
34#define AIC32X4_IFACE2 28
35#define AIC32X4_IFACE3 29
36#define AIC32X4_BCLKN 30
37#define AIC32X4_IFACE4 31
38#define AIC32X4_IFACE5 32
39#define AIC32X4_IFACE6 33
40#define AIC32X4_DOUTCTL 53
41#define AIC32X4_DINCTL 54
42#define AIC32X4_DACSPB 60
43#define AIC32X4_ADCSPB 61
44#define AIC32X4_DACSETUP 63
45#define AIC32X4_DACMUTE 64
46#define AIC32X4_LDACVOL 65
47#define AIC32X4_RDACVOL 66
48#define AIC32X4_ADCSETUP 81
49#define AIC32X4_ADCFGA 82
50#define AIC32X4_LADCVOL 83
51#define AIC32X4_RADCVOL 84
52#define AIC32X4_LAGC1 86
53#define AIC32X4_LAGC2 87
54#define AIC32X4_LAGC3 88
55#define AIC32X4_LAGC4 89
56#define AIC32X4_LAGC5 90
57#define AIC32X4_LAGC6 91
58#define AIC32X4_LAGC7 92
59#define AIC32X4_RAGC1 94
60#define AIC32X4_RAGC2 95
61#define AIC32X4_RAGC3 96
62#define AIC32X4_RAGC4 97
63#define AIC32X4_RAGC5 98
64#define AIC32X4_RAGC6 99
65#define AIC32X4_RAGC7 100
66#define AIC32X4_PWRCFG (AIC32X4_PAGE1 + 1)
67#define AIC32X4_LDOCTL (AIC32X4_PAGE1 + 2)
68#define AIC32X4_OUTPWRCTL (AIC32X4_PAGE1 + 9)
69#define AIC32X4_CMMODE (AIC32X4_PAGE1 + 10)
70#define AIC32X4_HPLROUTE (AIC32X4_PAGE1 + 12)
71#define AIC32X4_HPRROUTE (AIC32X4_PAGE1 + 13)
72#define AIC32X4_LOLROUTE (AIC32X4_PAGE1 + 14)
73#define AIC32X4_LORROUTE (AIC32X4_PAGE1 + 15)
74#define AIC32X4_HPLGAIN (AIC32X4_PAGE1 + 16)
75#define AIC32X4_HPRGAIN (AIC32X4_PAGE1 + 17)
76#define AIC32X4_LOLGAIN (AIC32X4_PAGE1 + 18)
77#define AIC32X4_LORGAIN (AIC32X4_PAGE1 + 19)
78#define AIC32X4_HEADSTART (AIC32X4_PAGE1 + 20)
79#define AIC32X4_MICBIAS (AIC32X4_PAGE1 + 51)
80#define AIC32X4_LMICPGAPIN (AIC32X4_PAGE1 + 52)
81#define AIC32X4_LMICPGANIN (AIC32X4_PAGE1 + 54)
82#define AIC32X4_RMICPGAPIN (AIC32X4_PAGE1 + 55)
83#define AIC32X4_RMICPGANIN (AIC32X4_PAGE1 + 57)
84#define AIC32X4_FLOATINGINPUT (AIC32X4_PAGE1 + 58)
85#define AIC32X4_LMICPGAVOL (AIC32X4_PAGE1 + 59)
86#define AIC32X4_RMICPGAVOL (AIC32X4_PAGE1 + 60)
87
88#define AIC32X4_FREQ_12000000 12000000
89#define AIC32X4_FREQ_24000000 24000000
90#define AIC32X4_FREQ_25000000 25000000
91
92#define AIC32X4_WORD_LEN_16BITS 0x00
93#define AIC32X4_WORD_LEN_20BITS 0x01
94#define AIC32X4_WORD_LEN_24BITS 0x02
95#define AIC32X4_WORD_LEN_32BITS 0x03
96
97#define AIC32X4_I2S_MODE 0x00
98#define AIC32X4_DSP_MODE 0x01
99#define AIC32X4_RIGHT_JUSTIFIED_MODE 0x02
100#define AIC32X4_LEFT_JUSTIFIED_MODE 0x03
101
102#define AIC32X4_AVDDWEAKDISABLE 0x08
103#define AIC32X4_LDOCTLEN 0x01
104
105#define AIC32X4_LDOIN_18_36 0x01
106#define AIC32X4_LDOIN2HP 0x02
107
108#define AIC32X4_DACSPBLOCK_MASK 0x1f
109#define AIC32X4_ADCSPBLOCK_MASK 0x1f
110
111#define AIC32X4_PLLJ_SHIFT 6
112#define AIC32X4_DOSRMSB_SHIFT 4
113
114#define AIC32X4_PLLCLKIN 0x03
115
116#define AIC32X4_MICBIAS_LDOIN 0x08
117#define AIC32X4_MICBIAS_2075V 0x60
118
119#define AIC32X4_LMICPGANIN_IN2R_10K 0x10
120#define AIC32X4_RMICPGANIN_IN1L_10K 0x10
121
122#define AIC32X4_LMICPGAVOL_NOGAIN 0x80
123#define AIC32X4_RMICPGAVOL_NOGAIN 0x80
124
125#define AIC32X4_BCLKMASTER 0x08
126#define AIC32X4_WCLKMASTER 0x04
127#define AIC32X4_PLLEN (0x01 << 7)
128#define AIC32X4_NDACEN (0x01 << 7)
129#define AIC32X4_MDACEN (0x01 << 7)
130#define AIC32X4_NADCEN (0x01 << 7)
131#define AIC32X4_MADCEN (0x01 << 7)
132#define AIC32X4_BCLKEN (0x01 << 7)
133#define AIC32X4_DACEN (0x03 << 6)
134#define AIC32X4_RDAC2LCHN (0x02 << 2)
135#define AIC32X4_LDAC2RCHN (0x02 << 4)
136#define AIC32X4_LDAC2LCHN (0x01 << 4)
137#define AIC32X4_RDAC2RCHN (0x01 << 2)
138
139#define AIC32X4_SSTEP2WCLK 0x01
140#define AIC32X4_MUTEON 0x0C
141#define AIC32X4_DACMOD2BCLK 0x01
142
143#endif /* _TLV320AIC32X4_H */
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
index 71d7be8ac488..00b6d87e7bdb 100644
--- a/sound/soc/codecs/tlv320dac33.c
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -1615,6 +1615,7 @@ static const struct i2c_device_id tlv320dac33_i2c_id[] = {
1615 }, 1615 },
1616 { }, 1616 { },
1617}; 1617};
1618MODULE_DEVICE_TABLE(i2c, tlv320dac33_i2c_id);
1618 1619
1619static struct i2c_driver tlv320dac33_i2c_driver = { 1620static struct i2c_driver tlv320dac33_i2c_driver = {
1620 .driver = { 1621 .driver = {
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
index 4bbf1b15a493..482fcdb59bfa 100644
--- a/sound/soc/codecs/twl6040.c
+++ b/sound/soc/codecs/twl6040.c
@@ -724,8 +724,8 @@ static int twl6040_power_mode_event(struct snd_soc_dapm_widget *w,
724 return 0; 724 return 0;
725} 725}
726 726
727void twl6040_hs_jack_report(struct snd_soc_codec *codec, 727static void twl6040_hs_jack_report(struct snd_soc_codec *codec,
728 struct snd_soc_jack *jack, int report) 728 struct snd_soc_jack *jack, int report)
729{ 729{
730 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); 730 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
731 int status; 731 int status;
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c
index 80ddf4fd23db..a3b9cbb20ee9 100644
--- a/sound/soc/codecs/wm2000.c
+++ b/sound/soc/codecs/wm2000.c
@@ -836,24 +836,25 @@ static void wm2000_i2c_shutdown(struct i2c_client *i2c)
836} 836}
837 837
838#ifdef CONFIG_PM 838#ifdef CONFIG_PM
839static int wm2000_i2c_suspend(struct i2c_client *i2c, pm_message_t mesg) 839static int wm2000_i2c_suspend(struct device *dev)
840{ 840{
841 struct i2c_client *i2c = to_i2c_client(dev);
841 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev); 842 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
842 843
843 return wm2000_anc_transition(wm2000, ANC_OFF); 844 return wm2000_anc_transition(wm2000, ANC_OFF);
844} 845}
845 846
846static int wm2000_i2c_resume(struct i2c_client *i2c) 847static int wm2000_i2c_resume(struct device *dev)
847{ 848{
849 struct i2c_client *i2c = to_i2c_client(dev);
848 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev); 850 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
849 851
850 return wm2000_anc_set_mode(wm2000); 852 return wm2000_anc_set_mode(wm2000);
851} 853}
852#else
853#define wm2000_i2c_suspend NULL
854#define wm2000_i2c_resume NULL
855#endif 854#endif
856 855
856static SIMPLE_DEV_PM_OPS(wm2000_pm, wm2000_i2c_suspend, wm2000_i2c_resume);
857
857static const struct i2c_device_id wm2000_i2c_id[] = { 858static const struct i2c_device_id wm2000_i2c_id[] = {
858 { "wm2000", 0 }, 859 { "wm2000", 0 },
859 { } 860 { }
@@ -864,11 +865,10 @@ static struct i2c_driver wm2000_i2c_driver = {
864 .driver = { 865 .driver = {
865 .name = "wm2000", 866 .name = "wm2000",
866 .owner = THIS_MODULE, 867 .owner = THIS_MODULE,
868 .pm = &wm2000_pm,
867 }, 869 },
868 .probe = wm2000_i2c_probe, 870 .probe = wm2000_i2c_probe,
869 .remove = __devexit_p(wm2000_i2c_remove), 871 .remove = __devexit_p(wm2000_i2c_remove),
870 .suspend = wm2000_i2c_suspend,
871 .resume = wm2000_i2c_resume,
872 .shutdown = wm2000_i2c_shutdown, 872 .shutdown = wm2000_i2c_shutdown,
873 .id_table = wm2000_i2c_id, 873 .id_table = wm2000_i2c_id,
874}; 874};
diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c
index 5eb2f501ce32..4fd4d8dca0fc 100644
--- a/sound/soc/codecs/wm8523.c
+++ b/sound/soc/codecs/wm8523.c
@@ -58,7 +58,7 @@ static const u16 wm8523_reg[WM8523_REGISTER_COUNT] = {
58 0x0000, /* R8 - ZERO_DETECT */ 58 0x0000, /* R8 - ZERO_DETECT */
59}; 59};
60 60
61static int wm8523_volatile_register(unsigned int reg) 61static int wm8523_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
62{ 62{
63 switch (reg) { 63 switch (reg) {
64 case WM8523_DEVICE_ID: 64 case WM8523_DEVICE_ID:
@@ -414,7 +414,6 @@ static int wm8523_resume(struct snd_soc_codec *codec)
414static int wm8523_probe(struct snd_soc_codec *codec) 414static int wm8523_probe(struct snd_soc_codec *codec)
415{ 415{
416 struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec); 416 struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
417 u16 *reg_cache = codec->reg_cache;
418 int ret, i; 417 int ret, i;
419 418
420 codec->hw_write = (hw_write_t)i2c_master_send; 419 codec->hw_write = (hw_write_t)i2c_master_send;
@@ -471,8 +470,9 @@ static int wm8523_probe(struct snd_soc_codec *codec)
471 } 470 }
472 471
473 /* Change some default settings - latch VU and enable ZC */ 472 /* Change some default settings - latch VU and enable ZC */
474 reg_cache[WM8523_DAC_GAINR] |= WM8523_DACR_VU; 473 snd_soc_update_bits(codec, WM8523_DAC_GAINR,
475 reg_cache[WM8523_DAC_CTRL3] |= WM8523_ZC; 474 WM8523_DACR_VU, WM8523_DACR_VU);
475 snd_soc_update_bits(codec, WM8523_DAC_CTRL3, WM8523_ZC, WM8523_ZC);
476 476
477 wm8523_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 477 wm8523_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
478 478
diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c
index 494f2d31d75b..25af901fe813 100644
--- a/sound/soc/codecs/wm8741.c
+++ b/sound/soc/codecs/wm8741.c
@@ -421,7 +421,6 @@ static int wm8741_resume(struct snd_soc_codec *codec)
421static int wm8741_probe(struct snd_soc_codec *codec) 421static int wm8741_probe(struct snd_soc_codec *codec)
422{ 422{
423 struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec); 423 struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
424 u16 *reg_cache = codec->reg_cache;
425 int ret = 0; 424 int ret = 0;
426 425
427 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8741->control_type); 426 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8741->control_type);
@@ -437,10 +436,14 @@ static int wm8741_probe(struct snd_soc_codec *codec)
437 } 436 }
438 437
439 /* Change some default settings - latch VU */ 438 /* Change some default settings - latch VU */
440 reg_cache[WM8741_DACLLSB_ATTENUATION] |= WM8741_UPDATELL; 439 snd_soc_update_bits(codec, WM8741_DACLLSB_ATTENUATION,
441 reg_cache[WM8741_DACLMSB_ATTENUATION] |= WM8741_UPDATELM; 440 WM8741_UPDATELL, WM8741_UPDATELL);
442 reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERL; 441 snd_soc_update_bits(codec, WM8741_DACLMSB_ATTENUATION,
443 reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERM; 442 WM8741_UPDATELM, WM8741_UPDATELM);
443 snd_soc_update_bits(codec, WM8741_DACRLSB_ATTENUATION,
444 WM8741_UPDATERL, WM8741_UPDATERL);
445 snd_soc_update_bits(codec, WM8741_DACRLSB_ATTENUATION,
446 WM8741_UPDATERM, WM8741_UPDATERM);
444 447
445 snd_soc_add_controls(codec, wm8741_snd_controls, 448 snd_soc_add_controls(codec, wm8741_snd_controls,
446 ARRAY_SIZE(wm8741_snd_controls)); 449 ARRAY_SIZE(wm8741_snd_controls));
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index 79b02ae125c5..3f09deea8d9d 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -55,8 +55,10 @@ static int caps_charge = 2000;
55module_param(caps_charge, int, 0); 55module_param(caps_charge, int, 0);
56MODULE_PARM_DESC(caps_charge, "WM8753 cap charge time (msecs)"); 56MODULE_PARM_DESC(caps_charge, "WM8753 cap charge time (msecs)");
57 57
58static void wm8753_set_dai_mode(struct snd_soc_codec *codec, 58static int wm8753_hifi_write_dai_fmt(struct snd_soc_codec *codec,
59 struct snd_soc_dai *dai, unsigned int hifi); 59 unsigned int fmt);
60static int wm8753_voice_write_dai_fmt(struct snd_soc_codec *codec,
61 unsigned int fmt);
60 62
61/* 63/*
62 * wm8753 register cache 64 * wm8753 register cache
@@ -87,6 +89,10 @@ struct wm8753_priv {
87 enum snd_soc_control_type control_type; 89 enum snd_soc_control_type control_type;
88 unsigned int sysclk; 90 unsigned int sysclk;
89 unsigned int pcmclk; 91 unsigned int pcmclk;
92
93 unsigned int voice_fmt;
94 unsigned int hifi_fmt;
95
90 int dai_func; 96 int dai_func;
91}; 97};
92 98
@@ -170,9 +176,9 @@ static int wm8753_get_dai(struct snd_kcontrol *kcontrol,
170 struct snd_ctl_elem_value *ucontrol) 176 struct snd_ctl_elem_value *ucontrol)
171{ 177{
172 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 178 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
173 int mode = snd_soc_read(codec, WM8753_IOCTL); 179 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
174 180
175 ucontrol->value.integer.value[0] = (mode & 0xc) >> 2; 181 ucontrol->value.integer.value[0] = wm8753->dai_func;
176 return 0; 182 return 0;
177} 183}
178 184
@@ -180,16 +186,26 @@ static int wm8753_set_dai(struct snd_kcontrol *kcontrol,
180 struct snd_ctl_elem_value *ucontrol) 186 struct snd_ctl_elem_value *ucontrol)
181{ 187{
182 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 188 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
183 int mode = snd_soc_read(codec, WM8753_IOCTL);
184 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); 189 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
190 u16 ioctl;
191
192 if (codec->active)
193 return -EBUSY;
194
195 ioctl = snd_soc_read(codec, WM8753_IOCTL);
196
197 wm8753->dai_func = ucontrol->value.integer.value[0];
198
199 if (((ioctl >> 2) & 0x3) == wm8753->dai_func)
200 return 1;
201
202 ioctl = (ioctl & 0x1f3) | (wm8753->dai_func << 2);
203 snd_soc_write(codec, WM8753_IOCTL, ioctl);
185 204
186 if (((mode & 0xc) >> 2) == ucontrol->value.integer.value[0])
187 return 0;
188 205
189 mode &= 0xfff3; 206 wm8753_hifi_write_dai_fmt(codec, wm8753->hifi_fmt);
190 mode |= (ucontrol->value.integer.value[0] << 2); 207 wm8753_voice_write_dai_fmt(codec, wm8753->voice_fmt);
191 208
192 wm8753->dai_func = ucontrol->value.integer.value[0];
193 return 1; 209 return 1;
194} 210}
195 211
@@ -828,10 +844,9 @@ static int wm8753_set_dai_sysclk(struct snd_soc_dai *codec_dai,
828/* 844/*
829 * Set's ADC and Voice DAC format. 845 * Set's ADC and Voice DAC format.
830 */ 846 */
831static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_dai *codec_dai, 847static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_codec *codec,
832 unsigned int fmt) 848 unsigned int fmt)
833{ 849{
834 struct snd_soc_codec *codec = codec_dai->codec;
835 u16 voice = snd_soc_read(codec, WM8753_PCM) & 0x01ec; 850 u16 voice = snd_soc_read(codec, WM8753_PCM) & 0x01ec;
836 851
837 /* interface format */ 852 /* interface format */
@@ -858,13 +873,6 @@ static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_dai *codec_dai,
858 return 0; 873 return 0;
859} 874}
860 875
861static int wm8753_pcm_startup(struct snd_pcm_substream *substream,
862 struct snd_soc_dai *dai)
863{
864 wm8753_set_dai_mode(dai->codec, dai, 0);
865 return 0;
866}
867
868/* 876/*
869 * Set PCM DAI bit size and sample rate. 877 * Set PCM DAI bit size and sample rate.
870 */ 878 */
@@ -905,10 +913,9 @@ static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream,
905/* 913/*
906 * Set's PCM dai fmt and BCLK. 914 * Set's PCM dai fmt and BCLK.
907 */ 915 */
908static int wm8753_pcm_set_dai_fmt(struct snd_soc_dai *codec_dai, 916static int wm8753_pcm_set_dai_fmt(struct snd_soc_codec *codec,
909 unsigned int fmt) 917 unsigned int fmt)
910{ 918{
911 struct snd_soc_codec *codec = codec_dai->codec;
912 u16 voice, ioctl; 919 u16 voice, ioctl;
913 920
914 voice = snd_soc_read(codec, WM8753_PCM) & 0x011f; 921 voice = snd_soc_read(codec, WM8753_PCM) & 0x011f;
@@ -999,10 +1006,9 @@ static int wm8753_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
999/* 1006/*
1000 * Set's HiFi DAC format. 1007 * Set's HiFi DAC format.
1001 */ 1008 */
1002static int wm8753_hdac_set_dai_fmt(struct snd_soc_dai *codec_dai, 1009static int wm8753_hdac_set_dai_fmt(struct snd_soc_codec *codec,
1003 unsigned int fmt) 1010 unsigned int fmt)
1004{ 1011{
1005 struct snd_soc_codec *codec = codec_dai->codec;
1006 u16 hifi = snd_soc_read(codec, WM8753_HIFI) & 0x01e0; 1012 u16 hifi = snd_soc_read(codec, WM8753_HIFI) & 0x01e0;
1007 1013
1008 /* interface format */ 1014 /* interface format */
@@ -1032,10 +1038,9 @@ static int wm8753_hdac_set_dai_fmt(struct snd_soc_dai *codec_dai,
1032/* 1038/*
1033 * Set's I2S DAI format. 1039 * Set's I2S DAI format.
1034 */ 1040 */
1035static int wm8753_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai, 1041static int wm8753_i2s_set_dai_fmt(struct snd_soc_codec *codec,
1036 unsigned int fmt) 1042 unsigned int fmt)
1037{ 1043{
1038 struct snd_soc_codec *codec = codec_dai->codec;
1039 u16 ioctl, hifi; 1044 u16 ioctl, hifi;
1040 1045
1041 hifi = snd_soc_read(codec, WM8753_HIFI) & 0x011f; 1046 hifi = snd_soc_read(codec, WM8753_HIFI) & 0x011f;
@@ -1098,13 +1103,6 @@ static int wm8753_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai,
1098 return 0; 1103 return 0;
1099} 1104}
1100 1105
1101static int wm8753_i2s_startup(struct snd_pcm_substream *substream,
1102 struct snd_soc_dai *dai)
1103{
1104 wm8753_set_dai_mode(dai->codec, dai, 1);
1105 return 0;
1106}
1107
1108/* 1106/*
1109 * Set PCM DAI bit size and sample rate. 1107 * Set PCM DAI bit size and sample rate.
1110 */ 1108 */
@@ -1147,61 +1145,117 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream,
1147 return 0; 1145 return 0;
1148} 1146}
1149 1147
1150static int wm8753_mode1v_set_dai_fmt(struct snd_soc_dai *codec_dai, 1148static int wm8753_mode1v_set_dai_fmt(struct snd_soc_codec *codec,
1151 unsigned int fmt) 1149 unsigned int fmt)
1152{ 1150{
1153 struct snd_soc_codec *codec = codec_dai->codec;
1154 u16 clock; 1151 u16 clock;
1155 1152
1156 /* set clk source as pcmclk */ 1153 /* set clk source as pcmclk */
1157 clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb; 1154 clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb;
1158 snd_soc_write(codec, WM8753_CLOCK, clock); 1155 snd_soc_write(codec, WM8753_CLOCK, clock);
1159 1156
1160 if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0) 1157 return wm8753_vdac_adc_set_dai_fmt(codec, fmt);
1161 return -EINVAL;
1162 return wm8753_pcm_set_dai_fmt(codec_dai, fmt);
1163} 1158}
1164 1159
1165static int wm8753_mode1h_set_dai_fmt(struct snd_soc_dai *codec_dai, 1160static int wm8753_mode1h_set_dai_fmt(struct snd_soc_codec *codec,
1166 unsigned int fmt) 1161 unsigned int fmt)
1167{ 1162{
1168 if (wm8753_hdac_set_dai_fmt(codec_dai, fmt) < 0) 1163 return wm8753_hdac_set_dai_fmt(codec, fmt);
1169 return -EINVAL;
1170 return wm8753_i2s_set_dai_fmt(codec_dai, fmt);
1171} 1164}
1172 1165
1173static int wm8753_mode2_set_dai_fmt(struct snd_soc_dai *codec_dai, 1166static int wm8753_mode2_set_dai_fmt(struct snd_soc_codec *codec,
1174 unsigned int fmt) 1167 unsigned int fmt)
1175{ 1168{
1176 struct snd_soc_codec *codec = codec_dai->codec;
1177 u16 clock; 1169 u16 clock;
1178 1170
1179 /* set clk source as pcmclk */ 1171 /* set clk source as pcmclk */
1180 clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb; 1172 clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb;
1181 snd_soc_write(codec, WM8753_CLOCK, clock); 1173 snd_soc_write(codec, WM8753_CLOCK, clock);
1182 1174
1183 if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0) 1175 return wm8753_vdac_adc_set_dai_fmt(codec, fmt);
1184 return -EINVAL;
1185 return wm8753_i2s_set_dai_fmt(codec_dai, fmt);
1186} 1176}
1187 1177
1188static int wm8753_mode3_4_set_dai_fmt(struct snd_soc_dai *codec_dai, 1178static int wm8753_mode3_4_set_dai_fmt(struct snd_soc_codec *codec,
1189 unsigned int fmt) 1179 unsigned int fmt)
1190{ 1180{
1191 struct snd_soc_codec *codec = codec_dai->codec;
1192 u16 clock; 1181 u16 clock;
1193 1182
1194 /* set clk source as mclk */ 1183 /* set clk source as mclk */
1195 clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb; 1184 clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb;
1196 snd_soc_write(codec, WM8753_CLOCK, clock | 0x4); 1185 snd_soc_write(codec, WM8753_CLOCK, clock | 0x4);
1197 1186
1198 if (wm8753_hdac_set_dai_fmt(codec_dai, fmt) < 0) 1187 if (wm8753_hdac_set_dai_fmt(codec, fmt) < 0)
1199 return -EINVAL; 1188 return -EINVAL;
1200 if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0) 1189 return wm8753_vdac_adc_set_dai_fmt(codec, fmt);
1201 return -EINVAL;
1202 return wm8753_i2s_set_dai_fmt(codec_dai, fmt);
1203} 1190}
1204 1191
1192static int wm8753_hifi_write_dai_fmt(struct snd_soc_codec *codec,
1193 unsigned int fmt)
1194{
1195 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1196 int ret = 0;
1197
1198 switch (wm8753->dai_func) {
1199 case 0:
1200 ret = wm8753_mode1h_set_dai_fmt(codec, fmt);
1201 break;
1202 case 1:
1203 ret = wm8753_mode2_set_dai_fmt(codec, fmt);
1204 break;
1205 case 2:
1206 case 3:
1207 ret = wm8753_mode3_4_set_dai_fmt(codec, fmt);
1208 break;
1209 default:
1210 break;
1211 }
1212 if (ret)
1213 return ret;
1214
1215 return wm8753_i2s_set_dai_fmt(codec, fmt);
1216}
1217
1218static int wm8753_hifi_set_dai_fmt(struct snd_soc_dai *codec_dai,
1219 unsigned int fmt)
1220{
1221 struct snd_soc_codec *codec = codec_dai->codec;
1222 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1223
1224 wm8753->hifi_fmt = fmt;
1225
1226 return wm8753_hifi_write_dai_fmt(codec, fmt);
1227};
1228
1229static int wm8753_voice_write_dai_fmt(struct snd_soc_codec *codec,
1230 unsigned int fmt)
1231{
1232 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1233 int ret = 0;
1234
1235 if (wm8753->dai_func != 0)
1236 return 0;
1237
1238 ret = wm8753_mode1v_set_dai_fmt(codec, fmt);
1239 if (ret)
1240 return ret;
1241 ret = wm8753_pcm_set_dai_fmt(codec, fmt);
1242 if (ret)
1243 return ret;
1244
1245 return 0;
1246};
1247
1248static int wm8753_voice_set_dai_fmt(struct snd_soc_dai *codec_dai,
1249 unsigned int fmt)
1250{
1251 struct snd_soc_codec *codec = codec_dai->codec;
1252 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1253
1254 wm8753->voice_fmt = fmt;
1255
1256 return wm8753_voice_write_dai_fmt(codec, fmt);
1257};
1258
1205static int wm8753_mute(struct snd_soc_dai *dai, int mute) 1259static int wm8753_mute(struct snd_soc_dai *dai, int mute)
1206{ 1260{
1207 struct snd_soc_codec *codec = dai->codec; 1261 struct snd_soc_codec *codec = dai->codec;
@@ -1268,57 +1322,25 @@ static int wm8753_set_bias_level(struct snd_soc_codec *codec,
1268 * 3. Voice disabled - HIFI over HIFI 1322 * 3. Voice disabled - HIFI over HIFI
1269 * 4. Voice disabled - HIFI over HIFI, uses voice DAI LRC for capture 1323 * 4. Voice disabled - HIFI over HIFI, uses voice DAI LRC for capture
1270 */ 1324 */
1271static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode1 = { 1325static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode = {
1272 .startup = wm8753_i2s_startup,
1273 .hw_params = wm8753_i2s_hw_params, 1326 .hw_params = wm8753_i2s_hw_params,
1274 .digital_mute = wm8753_mute, 1327 .digital_mute = wm8753_mute,
1275 .set_fmt = wm8753_mode1h_set_dai_fmt, 1328 .set_fmt = wm8753_hifi_set_dai_fmt,
1276 .set_clkdiv = wm8753_set_dai_clkdiv,
1277 .set_pll = wm8753_set_dai_pll,
1278 .set_sysclk = wm8753_set_dai_sysclk,
1279};
1280
1281static struct snd_soc_dai_ops wm8753_dai_ops_voice_mode1 = {
1282 .startup = wm8753_pcm_startup,
1283 .hw_params = wm8753_pcm_hw_params,
1284 .digital_mute = wm8753_mute,
1285 .set_fmt = wm8753_mode1v_set_dai_fmt,
1286 .set_clkdiv = wm8753_set_dai_clkdiv, 1329 .set_clkdiv = wm8753_set_dai_clkdiv,
1287 .set_pll = wm8753_set_dai_pll, 1330 .set_pll = wm8753_set_dai_pll,
1288 .set_sysclk = wm8753_set_dai_sysclk, 1331 .set_sysclk = wm8753_set_dai_sysclk,
1289}; 1332};
1290 1333
1291static struct snd_soc_dai_ops wm8753_dai_ops_voice_mode2 = { 1334static struct snd_soc_dai_ops wm8753_dai_ops_voice_mode = {
1292 .startup = wm8753_pcm_startup,
1293 .hw_params = wm8753_pcm_hw_params, 1335 .hw_params = wm8753_pcm_hw_params,
1294 .digital_mute = wm8753_mute, 1336 .digital_mute = wm8753_mute,
1295 .set_fmt = wm8753_mode2_set_dai_fmt, 1337 .set_fmt = wm8753_voice_set_dai_fmt,
1296 .set_clkdiv = wm8753_set_dai_clkdiv,
1297 .set_pll = wm8753_set_dai_pll,
1298 .set_sysclk = wm8753_set_dai_sysclk,
1299};
1300
1301static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode3 = {
1302 .startup = wm8753_i2s_startup,
1303 .hw_params = wm8753_i2s_hw_params,
1304 .digital_mute = wm8753_mute,
1305 .set_fmt = wm8753_mode3_4_set_dai_fmt,
1306 .set_clkdiv = wm8753_set_dai_clkdiv,
1307 .set_pll = wm8753_set_dai_pll,
1308 .set_sysclk = wm8753_set_dai_sysclk,
1309};
1310
1311static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode4 = {
1312 .startup = wm8753_i2s_startup,
1313 .hw_params = wm8753_i2s_hw_params,
1314 .digital_mute = wm8753_mute,
1315 .set_fmt = wm8753_mode3_4_set_dai_fmt,
1316 .set_clkdiv = wm8753_set_dai_clkdiv, 1338 .set_clkdiv = wm8753_set_dai_clkdiv,
1317 .set_pll = wm8753_set_dai_pll, 1339 .set_pll = wm8753_set_dai_pll,
1318 .set_sysclk = wm8753_set_dai_sysclk, 1340 .set_sysclk = wm8753_set_dai_sysclk,
1319}; 1341};
1320 1342
1321static struct snd_soc_dai_driver wm8753_all_dai[] = { 1343static struct snd_soc_dai_driver wm8753_dai[] = {
1322/* DAI HiFi mode 1 */ 1344/* DAI HiFi mode 1 */
1323{ .name = "wm8753-hifi", 1345{ .name = "wm8753-hifi",
1324 .playback = { 1346 .playback = {
@@ -1326,14 +1348,16 @@ static struct snd_soc_dai_driver wm8753_all_dai[] = {
1326 .channels_min = 1, 1348 .channels_min = 1,
1327 .channels_max = 2, 1349 .channels_max = 2,
1328 .rates = WM8753_RATES, 1350 .rates = WM8753_RATES,
1329 .formats = WM8753_FORMATS}, 1351 .formats = WM8753_FORMATS
1352 },
1330 .capture = { /* dummy for fast DAI switching */ 1353 .capture = { /* dummy for fast DAI switching */
1331 .stream_name = "Capture", 1354 .stream_name = "Capture",
1332 .channels_min = 1, 1355 .channels_min = 1,
1333 .channels_max = 2, 1356 .channels_max = 2,
1334 .rates = WM8753_RATES, 1357 .rates = WM8753_RATES,
1335 .formats = WM8753_FORMATS}, 1358 .formats = WM8753_FORMATS
1336 .ops = &wm8753_dai_ops_hifi_mode1, 1359 },
1360 .ops = &wm8753_dai_ops_hifi_mode,
1337}, 1361},
1338/* DAI Voice mode 1 */ 1362/* DAI Voice mode 1 */
1339{ .name = "wm8753-voice", 1363{ .name = "wm8753-voice",
@@ -1342,97 +1366,19 @@ static struct snd_soc_dai_driver wm8753_all_dai[] = {
1342 .channels_min = 1, 1366 .channels_min = 1,
1343 .channels_max = 1, 1367 .channels_max = 1,
1344 .rates = WM8753_RATES, 1368 .rates = WM8753_RATES,
1345 .formats = WM8753_FORMATS,}, 1369 .formats = WM8753_FORMATS,
1346 .capture = { 1370 },
1347 .stream_name = "Capture",
1348 .channels_min = 1,
1349 .channels_max = 2,
1350 .rates = WM8753_RATES,
1351 .formats = WM8753_FORMATS,},
1352 .ops = &wm8753_dai_ops_voice_mode1,
1353},
1354/* DAI HiFi mode 2 - dummy */
1355{ .name = "wm8753-hifi",
1356},
1357/* DAI Voice mode 2 */
1358{ .name = "wm8753-voice",
1359 .playback = {
1360 .stream_name = "Voice Playback",
1361 .channels_min = 1,
1362 .channels_max = 1,
1363 .rates = WM8753_RATES,
1364 .formats = WM8753_FORMATS,},
1365 .capture = {
1366 .stream_name = "Capture",
1367 .channels_min = 1,
1368 .channels_max = 2,
1369 .rates = WM8753_RATES,
1370 .formats = WM8753_FORMATS,},
1371 .ops = &wm8753_dai_ops_voice_mode2,
1372},
1373/* DAI HiFi mode 3 */
1374{ .name = "wm8753-hifi",
1375 .playback = {
1376 .stream_name = "HiFi Playback",
1377 .channels_min = 1,
1378 .channels_max = 2,
1379 .rates = WM8753_RATES,
1380 .formats = WM8753_FORMATS,},
1381 .capture = {
1382 .stream_name = "Capture",
1383 .channels_min = 1,
1384 .channels_max = 2,
1385 .rates = WM8753_RATES,
1386 .formats = WM8753_FORMATS,},
1387 .ops = &wm8753_dai_ops_hifi_mode3,
1388},
1389/* DAI Voice mode 3 - dummy */
1390{ .name = "wm8753-voice",
1391},
1392/* DAI HiFi mode 4 */
1393{ .name = "wm8753-hifi",
1394 .playback = {
1395 .stream_name = "HiFi Playback",
1396 .channels_min = 1,
1397 .channels_max = 2,
1398 .rates = WM8753_RATES,
1399 .formats = WM8753_FORMATS,},
1400 .capture = { 1371 .capture = {
1401 .stream_name = "Capture", 1372 .stream_name = "Capture",
1402 .channels_min = 1, 1373 .channels_min = 1,
1403 .channels_max = 2, 1374 .channels_max = 2,
1404 .rates = WM8753_RATES, 1375 .rates = WM8753_RATES,
1405 .formats = WM8753_FORMATS,}, 1376 .formats = WM8753_FORMATS,
1406 .ops = &wm8753_dai_ops_hifi_mode4,
1407},
1408/* DAI Voice mode 4 - dummy */
1409{ .name = "wm8753-voice",
1410},
1411};
1412
1413static struct snd_soc_dai_driver wm8753_dai[] = {
1414 {
1415 .name = "wm8753-aif0",
1416 },
1417 {
1418 .name = "wm8753-aif1",
1419 }, 1377 },
1378 .ops = &wm8753_dai_ops_voice_mode,
1379},
1420}; 1380};
1421 1381
1422static void wm8753_set_dai_mode(struct snd_soc_codec *codec,
1423 struct snd_soc_dai *dai, unsigned int hifi)
1424{
1425 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1426
1427 if (wm8753->dai_func < 4) {
1428 if (hifi)
1429 dai->driver = &wm8753_all_dai[wm8753->dai_func << 1];
1430 else
1431 dai->driver = &wm8753_all_dai[(wm8753->dai_func << 1) + 1];
1432 }
1433 snd_soc_write(codec, WM8753_IOCTL, wm8753->dai_func);
1434}
1435
1436static void wm8753_work(struct work_struct *work) 1382static void wm8753_work(struct work_struct *work)
1437{ 1383{
1438 struct snd_soc_dapm_context *dapm = 1384 struct snd_soc_dapm_context *dapm =
diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c
index 6dae1b40c9f7..6785688f8806 100644
--- a/sound/soc/codecs/wm8804.c
+++ b/sound/soc/codecs/wm8804.c
@@ -175,7 +175,7 @@ static int txsrc_put(struct snd_kcontrol *kcontrol,
175 return 0; 175 return 0;
176} 176}
177 177
178static int wm8804_volatile(unsigned int reg) 178static int wm8804_volatile(struct snd_soc_codec *codec, unsigned int reg)
179{ 179{
180 switch (reg) { 180 switch (reg) {
181 case WM8804_RST_DEVID1: 181 case WM8804_RST_DEVID1:
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c
index cd0959926d12..449ea09a193d 100644
--- a/sound/soc/codecs/wm8900.c
+++ b/sound/soc/codecs/wm8900.c
@@ -180,7 +180,7 @@ static const u16 wm8900_reg_defaults[WM8900_MAXREG] = {
180 /* Remaining registers all zero */ 180 /* Remaining registers all zero */
181}; 181};
182 182
183static int wm8900_volatile_register(unsigned int reg) 183static int wm8900_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
184{ 184{
185 switch (reg) { 185 switch (reg) {
186 case WM8900_REG_ID: 186 case WM8900_REG_ID:
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index 017d99ceb42e..ae1cadfae84c 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -2,6 +2,7 @@
2 * wm8903.c -- WM8903 ALSA SoC Audio driver 2 * wm8903.c -- WM8903 ALSA SoC Audio driver
3 * 3 *
4 * Copyright 2008 Wolfson Microelectronics 4 * Copyright 2008 Wolfson Microelectronics
5 * Copyright 2011 NVIDIA, Inc.
5 * 6 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 7 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 * 8 *
@@ -19,6 +20,7 @@
19#include <linux/init.h> 20#include <linux/init.h>
20#include <linux/completion.h> 21#include <linux/completion.h>
21#include <linux/delay.h> 22#include <linux/delay.h>
23#include <linux/gpio.h>
22#include <linux/pm.h> 24#include <linux/pm.h>
23#include <linux/i2c.h> 25#include <linux/i2c.h>
24#include <linux/platform_device.h> 26#include <linux/platform_device.h>
@@ -213,6 +215,7 @@ static u16 wm8903_reg_defaults[] = {
213}; 215};
214 216
215struct wm8903_priv { 217struct wm8903_priv {
218 struct snd_soc_codec *codec;
216 219
217 int sysclk; 220 int sysclk;
218 int irq; 221 int irq;
@@ -220,25 +223,36 @@ struct wm8903_priv {
220 int fs; 223 int fs;
221 int deemph; 224 int deemph;
222 225
226 int dcs_pending;
227 int dcs_cache[4];
228
223 /* Reference count */ 229 /* Reference count */
224 int class_w_users; 230 int class_w_users;
225 231
226 struct completion wseq;
227
228 struct snd_soc_jack *mic_jack; 232 struct snd_soc_jack *mic_jack;
229 int mic_det; 233 int mic_det;
230 int mic_short; 234 int mic_short;
231 int mic_last_report; 235 int mic_last_report;
232 int mic_delay; 236 int mic_delay;
237
238#ifdef CONFIG_GPIOLIB
239 struct gpio_chip gpio_chip;
240#endif
233}; 241};
234 242
235static int wm8903_volatile_register(unsigned int reg) 243static int wm8903_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
236{ 244{
237 switch (reg) { 245 switch (reg) {
238 case WM8903_SW_RESET_AND_ID: 246 case WM8903_SW_RESET_AND_ID:
239 case WM8903_REVISION_NUMBER: 247 case WM8903_REVISION_NUMBER:
240 case WM8903_INTERRUPT_STATUS_1: 248 case WM8903_INTERRUPT_STATUS_1:
241 case WM8903_WRITE_SEQUENCER_4: 249 case WM8903_WRITE_SEQUENCER_4:
250 case WM8903_POWER_MANAGEMENT_3:
251 case WM8903_POWER_MANAGEMENT_2:
252 case WM8903_DC_SERVO_READBACK_1:
253 case WM8903_DC_SERVO_READBACK_2:
254 case WM8903_DC_SERVO_READBACK_3:
255 case WM8903_DC_SERVO_READBACK_4:
242 return 1; 256 return 1;
243 257
244 default: 258 default:
@@ -246,50 +260,6 @@ static int wm8903_volatile_register(unsigned int reg)
246 } 260 }
247} 261}
248 262
249static int wm8903_run_sequence(struct snd_soc_codec *codec, unsigned int start)
250{
251 u16 reg[5];
252 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
253
254 BUG_ON(start > 48);
255
256 /* Enable the sequencer if it's not already on */
257 reg[0] = snd_soc_read(codec, WM8903_WRITE_SEQUENCER_0);
258 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0,
259 reg[0] | WM8903_WSEQ_ENA);
260
261 dev_dbg(codec->dev, "Starting sequence at %d\n", start);
262
263 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_3,
264 start | WM8903_WSEQ_START);
265
266 /* Wait for it to complete. If we have the interrupt wired up then
267 * that will break us out of the poll early.
268 */
269 do {
270 wait_for_completion_timeout(&wm8903->wseq,
271 msecs_to_jiffies(10));
272
273 reg[4] = snd_soc_read(codec, WM8903_WRITE_SEQUENCER_4);
274 } while (reg[4] & WM8903_WSEQ_BUSY);
275
276 dev_dbg(codec->dev, "Sequence complete\n");
277
278 /* Disable the sequencer again if we enabled it */
279 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0, reg[0]);
280
281 return 0;
282}
283
284static void wm8903_sync_reg_cache(struct snd_soc_codec *codec, u16 *cache)
285{
286 int i;
287
288 /* There really ought to be something better we can do here :/ */
289 for (i = 0; i < ARRAY_SIZE(wm8903_reg_defaults); i++)
290 cache[i] = codec->hw_read(codec, i);
291}
292
293static void wm8903_reset(struct snd_soc_codec *codec) 263static void wm8903_reset(struct snd_soc_codec *codec)
294{ 264{
295 snd_soc_write(codec, WM8903_SW_RESET_AND_ID, 0); 265 snd_soc_write(codec, WM8903_SW_RESET_AND_ID, 0);
@@ -297,11 +267,6 @@ static void wm8903_reset(struct snd_soc_codec *codec)
297 sizeof(wm8903_reg_defaults)); 267 sizeof(wm8903_reg_defaults));
298} 268}
299 269
300#define WM8903_OUTPUT_SHORT 0x8
301#define WM8903_OUTPUT_OUT 0x4
302#define WM8903_OUTPUT_INT 0x2
303#define WM8903_OUTPUT_IN 0x1
304
305static int wm8903_cp_event(struct snd_soc_dapm_widget *w, 270static int wm8903_cp_event(struct snd_soc_dapm_widget *w,
306 struct snd_kcontrol *kcontrol, int event) 271 struct snd_kcontrol *kcontrol, int event)
307{ 272{
@@ -311,97 +276,101 @@ static int wm8903_cp_event(struct snd_soc_dapm_widget *w,
311 return 0; 276 return 0;
312} 277}
313 278
314/* 279static int wm8903_dcs_event(struct snd_soc_dapm_widget *w,
315 * Event for headphone and line out amplifier power changes. Special 280 struct snd_kcontrol *kcontrol, int event)
316 * power up/down sequences are required in order to maximise pop/click
317 * performance.
318 */
319static int wm8903_output_event(struct snd_soc_dapm_widget *w,
320 struct snd_kcontrol *kcontrol, int event)
321{ 281{
322 struct snd_soc_codec *codec = w->codec; 282 struct snd_soc_codec *codec = w->codec;
323 u16 val; 283 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
324 u16 reg;
325 u16 dcs_reg;
326 u16 dcs_bit;
327 int shift;
328 284
329 switch (w->reg) { 285 switch (event) {
330 case WM8903_POWER_MANAGEMENT_2: 286 case SND_SOC_DAPM_POST_PMU:
331 reg = WM8903_ANALOGUE_HP_0; 287 wm8903->dcs_pending |= 1 << w->shift;
332 dcs_bit = 0 + w->shift;
333 break; 288 break;
334 case WM8903_POWER_MANAGEMENT_3: 289 case SND_SOC_DAPM_PRE_PMD:
335 reg = WM8903_ANALOGUE_LINEOUT_0; 290 snd_soc_update_bits(codec, WM8903_DC_SERVO_0,
336 dcs_bit = 2 + w->shift; 291 1 << w->shift, 0);
337 break; 292 break;
338 default:
339 BUG();
340 return -EINVAL; /* Spurious warning from some compilers */
341 } 293 }
342 294
343 switch (w->shift) { 295 return 0;
344 case 0: 296}
345 shift = 0;
346 break;
347 case 1:
348 shift = 4;
349 break;
350 default:
351 BUG();
352 return -EINVAL; /* Spurious warning from some compilers */
353 }
354 297
355 if (event & SND_SOC_DAPM_PRE_PMU) { 298#define WM8903_DCS_MODE_WRITE_STOP 0
356 val = snd_soc_read(codec, reg); 299#define WM8903_DCS_MODE_START_STOP 2
357 300
358 /* Short the output */ 301static void wm8903_seq_notifier(struct snd_soc_dapm_context *dapm,
359 val &= ~(WM8903_OUTPUT_SHORT << shift); 302 enum snd_soc_dapm_type event, int subseq)
360 snd_soc_write(codec, reg, val); 303{
361 } 304 struct snd_soc_codec *codec = container_of(dapm,
305 struct snd_soc_codec, dapm);
306 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
307 int dcs_mode = WM8903_DCS_MODE_WRITE_STOP;
308 int i, val;
362 309
363 if (event & SND_SOC_DAPM_POST_PMU) { 310 /* Complete any pending DC servo starts */
364 val = snd_soc_read(codec, reg); 311 if (wm8903->dcs_pending) {
312 dev_dbg(codec->dev, "Starting DC servo for %x\n",
313 wm8903->dcs_pending);
365 314
366 val |= (WM8903_OUTPUT_IN << shift); 315 /* If we've no cached values then we need to do startup */
367 snd_soc_write(codec, reg, val); 316 for (i = 0; i < ARRAY_SIZE(wm8903->dcs_cache); i++) {
317 if (!(wm8903->dcs_pending & (1 << i)))
318 continue;
368 319
369 val |= (WM8903_OUTPUT_INT << shift); 320 if (wm8903->dcs_cache[i]) {
370 snd_soc_write(codec, reg, val); 321 dev_dbg(codec->dev,
322 "Restore DC servo %d value %x\n",
323 3 - i, wm8903->dcs_cache[i]);
324
325 snd_soc_write(codec, WM8903_DC_SERVO_4 + i,
326 wm8903->dcs_cache[i] & 0xff);
327 } else {
328 dev_dbg(codec->dev,
329 "Calibrate DC servo %d\n", 3 - i);
330 dcs_mode = WM8903_DCS_MODE_START_STOP;
331 }
332 }
371 333
372 /* Turn on the output ENA_OUTP */ 334 /* Don't trust the cache for analogue */
373 val |= (WM8903_OUTPUT_OUT << shift); 335 if (wm8903->class_w_users)
374 snd_soc_write(codec, reg, val); 336 dcs_mode = WM8903_DCS_MODE_START_STOP;
375 337
376 /* Enable the DC servo */ 338 snd_soc_update_bits(codec, WM8903_DC_SERVO_2,
377 dcs_reg = snd_soc_read(codec, WM8903_DC_SERVO_0); 339 WM8903_DCS_MODE_MASK, dcs_mode);
378 dcs_reg |= dcs_bit;
379 snd_soc_write(codec, WM8903_DC_SERVO_0, dcs_reg);
380 340
381 /* Remove the short */ 341 snd_soc_update_bits(codec, WM8903_DC_SERVO_0,
382 val |= (WM8903_OUTPUT_SHORT << shift); 342 WM8903_DCS_ENA_MASK, wm8903->dcs_pending);
383 snd_soc_write(codec, reg, val);
384 }
385 343
386 if (event & SND_SOC_DAPM_PRE_PMD) { 344 switch (dcs_mode) {
387 val = snd_soc_read(codec, reg); 345 case WM8903_DCS_MODE_WRITE_STOP:
346 break;
388 347
389 /* Short the output */ 348 case WM8903_DCS_MODE_START_STOP:
390 val &= ~(WM8903_OUTPUT_SHORT << shift); 349 msleep(270);
391 snd_soc_write(codec, reg, val);
392 350
393 /* Disable the DC servo */ 351 /* Cache the measured offsets for digital */
394 dcs_reg = snd_soc_read(codec, WM8903_DC_SERVO_0); 352 if (wm8903->class_w_users)
395 dcs_reg &= ~dcs_bit; 353 break;
396 snd_soc_write(codec, WM8903_DC_SERVO_0, dcs_reg);
397 354
398 /* Then disable the intermediate and output stages */ 355 for (i = 0; i < ARRAY_SIZE(wm8903->dcs_cache); i++) {
399 val &= ~((WM8903_OUTPUT_OUT | WM8903_OUTPUT_INT | 356 if (!(wm8903->dcs_pending & (1 << i)))
400 WM8903_OUTPUT_IN) << shift); 357 continue;
401 snd_soc_write(codec, reg, val);
402 }
403 358
404 return 0; 359 val = snd_soc_read(codec,
360 WM8903_DC_SERVO_READBACK_1 + i);
361 dev_dbg(codec->dev, "DC servo %d: %x\n",
362 3 - i, val);
363 wm8903->dcs_cache[i] = val;
364 }
365 break;
366
367 default:
368 pr_warn("DCS mode %d delay not set\n", dcs_mode);
369 break;
370 }
371
372 wm8903->dcs_pending = 0;
373 }
405} 374}
406 375
407/* 376/*
@@ -667,6 +636,22 @@ static const struct soc_enum lsidetone_enum =
667static const struct soc_enum rsidetone_enum = 636static const struct soc_enum rsidetone_enum =
668 SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_0, 0, 3, sidetone_text); 637 SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_0, 0, 3, sidetone_text);
669 638
639static const char *aif_text[] = {
640 "Left", "Right"
641};
642
643static const struct soc_enum lcapture_enum =
644 SOC_ENUM_SINGLE(WM8903_AUDIO_INTERFACE_0, 7, 2, aif_text);
645
646static const struct soc_enum rcapture_enum =
647 SOC_ENUM_SINGLE(WM8903_AUDIO_INTERFACE_0, 6, 2, aif_text);
648
649static const struct soc_enum lplay_enum =
650 SOC_ENUM_SINGLE(WM8903_AUDIO_INTERFACE_0, 5, 2, aif_text);
651
652static const struct soc_enum rplay_enum =
653 SOC_ENUM_SINGLE(WM8903_AUDIO_INTERFACE_0, 4, 2, aif_text);
654
670static const struct snd_kcontrol_new wm8903_snd_controls[] = { 655static const struct snd_kcontrol_new wm8903_snd_controls[] = {
671 656
672/* Input PGAs - No TLV since the scale depends on PGA mode */ 657/* Input PGAs - No TLV since the scale depends on PGA mode */
@@ -784,6 +769,18 @@ static const struct snd_kcontrol_new lsidetone_mux =
784static const struct snd_kcontrol_new rsidetone_mux = 769static const struct snd_kcontrol_new rsidetone_mux =
785 SOC_DAPM_ENUM("DACR Sidetone Mux", rsidetone_enum); 770 SOC_DAPM_ENUM("DACR Sidetone Mux", rsidetone_enum);
786 771
772static const struct snd_kcontrol_new lcapture_mux =
773 SOC_DAPM_ENUM("Left Capture Mux", lcapture_enum);
774
775static const struct snd_kcontrol_new rcapture_mux =
776 SOC_DAPM_ENUM("Right Capture Mux", rcapture_enum);
777
778static const struct snd_kcontrol_new lplay_mux =
779 SOC_DAPM_ENUM("Left Playback Mux", lplay_enum);
780
781static const struct snd_kcontrol_new rplay_mux =
782 SOC_DAPM_ENUM("Right Playback Mux", rplay_enum);
783
787static const struct snd_kcontrol_new left_output_mixer[] = { 784static const struct snd_kcontrol_new left_output_mixer[] = {
788SOC_DAPM_SINGLE("DACL Switch", WM8903_ANALOGUE_LEFT_MIX_0, 3, 1, 0), 785SOC_DAPM_SINGLE("DACL Switch", WM8903_ANALOGUE_LEFT_MIX_0, 3, 1, 0),
789SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_LEFT_MIX_0, 2, 1, 0), 786SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_LEFT_MIX_0, 2, 1, 0),
@@ -847,14 +844,26 @@ SND_SOC_DAPM_MUX("Right Input Mode Mux", SND_SOC_NOPM, 0, 0, &rinput_mode_mux),
847SND_SOC_DAPM_PGA("Left Input PGA", WM8903_POWER_MANAGEMENT_0, 1, 0, NULL, 0), 844SND_SOC_DAPM_PGA("Left Input PGA", WM8903_POWER_MANAGEMENT_0, 1, 0, NULL, 0),
848SND_SOC_DAPM_PGA("Right Input PGA", WM8903_POWER_MANAGEMENT_0, 0, 0, NULL, 0), 845SND_SOC_DAPM_PGA("Right Input PGA", WM8903_POWER_MANAGEMENT_0, 0, 0, NULL, 0),
849 846
850SND_SOC_DAPM_ADC("ADCL", "Left HiFi Capture", WM8903_POWER_MANAGEMENT_6, 1, 0), 847SND_SOC_DAPM_ADC("ADCL", NULL, WM8903_POWER_MANAGEMENT_6, 1, 0),
851SND_SOC_DAPM_ADC("ADCR", "Right HiFi Capture", WM8903_POWER_MANAGEMENT_6, 0, 0), 848SND_SOC_DAPM_ADC("ADCR", NULL, WM8903_POWER_MANAGEMENT_6, 0, 0),
849
850SND_SOC_DAPM_MUX("Left Capture Mux", SND_SOC_NOPM, 0, 0, &lcapture_mux),
851SND_SOC_DAPM_MUX("Right Capture Mux", SND_SOC_NOPM, 0, 0, &rcapture_mux),
852
853SND_SOC_DAPM_AIF_OUT("AIFTXL", "Left HiFi Capture", 0, SND_SOC_NOPM, 0, 0),
854SND_SOC_DAPM_AIF_OUT("AIFTXR", "Right HiFi Capture", 0, SND_SOC_NOPM, 0, 0),
852 855
853SND_SOC_DAPM_MUX("DACL Sidetone", SND_SOC_NOPM, 0, 0, &lsidetone_mux), 856SND_SOC_DAPM_MUX("DACL Sidetone", SND_SOC_NOPM, 0, 0, &lsidetone_mux),
854SND_SOC_DAPM_MUX("DACR Sidetone", SND_SOC_NOPM, 0, 0, &rsidetone_mux), 857SND_SOC_DAPM_MUX("DACR Sidetone", SND_SOC_NOPM, 0, 0, &rsidetone_mux),
855 858
856SND_SOC_DAPM_DAC("DACL", "Left Playback", WM8903_POWER_MANAGEMENT_6, 3, 0), 859SND_SOC_DAPM_AIF_IN("AIFRXL", "Left Playback", 0, SND_SOC_NOPM, 0, 0),
857SND_SOC_DAPM_DAC("DACR", "Right Playback", WM8903_POWER_MANAGEMENT_6, 2, 0), 860SND_SOC_DAPM_AIF_IN("AIFRXR", "Right Playback", 0, SND_SOC_NOPM, 0, 0),
861
862SND_SOC_DAPM_MUX("Left Playback Mux", SND_SOC_NOPM, 0, 0, &lplay_mux),
863SND_SOC_DAPM_MUX("Right Playback Mux", SND_SOC_NOPM, 0, 0, &rplay_mux),
864
865SND_SOC_DAPM_DAC("DACL", NULL, WM8903_POWER_MANAGEMENT_6, 3, 0),
866SND_SOC_DAPM_DAC("DACR", NULL, WM8903_POWER_MANAGEMENT_6, 2, 0),
858 867
859SND_SOC_DAPM_MIXER("Left Output Mixer", WM8903_POWER_MANAGEMENT_1, 1, 0, 868SND_SOC_DAPM_MIXER("Left Output Mixer", WM8903_POWER_MANAGEMENT_1, 1, 0,
860 left_output_mixer, ARRAY_SIZE(left_output_mixer)), 869 left_output_mixer, ARRAY_SIZE(left_output_mixer)),
@@ -866,23 +875,45 @@ SND_SOC_DAPM_MIXER("Left Speaker Mixer", WM8903_POWER_MANAGEMENT_4, 1, 0,
866SND_SOC_DAPM_MIXER("Right Speaker Mixer", WM8903_POWER_MANAGEMENT_4, 0, 0, 875SND_SOC_DAPM_MIXER("Right Speaker Mixer", WM8903_POWER_MANAGEMENT_4, 0, 0,
867 right_speaker_mixer, ARRAY_SIZE(right_speaker_mixer)), 876 right_speaker_mixer, ARRAY_SIZE(right_speaker_mixer)),
868 877
869SND_SOC_DAPM_PGA_E("Left Headphone Output PGA", WM8903_POWER_MANAGEMENT_2, 878SND_SOC_DAPM_PGA_S("Left Headphone Output PGA", 0, WM8903_ANALOGUE_HP_0,
870 1, 0, NULL, 0, wm8903_output_event, 879 4, 0, NULL, 0),
871 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 880SND_SOC_DAPM_PGA_S("Right Headphone Output PGA", 0, WM8903_ANALOGUE_HP_0,
872 SND_SOC_DAPM_PRE_PMD), 881 0, 0, NULL, 0),
873SND_SOC_DAPM_PGA_E("Right Headphone Output PGA", WM8903_POWER_MANAGEMENT_2, 882
874 0, 0, NULL, 0, wm8903_output_event, 883SND_SOC_DAPM_PGA_S("Left Line Output PGA", 0, WM8903_ANALOGUE_LINEOUT_0, 4, 0,
875 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 884 NULL, 0),
876 SND_SOC_DAPM_PRE_PMD), 885SND_SOC_DAPM_PGA_S("Right Line Output PGA", 0, WM8903_ANALOGUE_LINEOUT_0, 0, 0,
877 886 NULL, 0),
878SND_SOC_DAPM_PGA_E("Left Line Output PGA", WM8903_POWER_MANAGEMENT_3, 1, 0, 887
879 NULL, 0, wm8903_output_event, 888SND_SOC_DAPM_PGA_S("HPL_RMV_SHORT", 4, WM8903_ANALOGUE_HP_0, 7, 0, NULL, 0),
880 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 889SND_SOC_DAPM_PGA_S("HPL_ENA_OUTP", 3, WM8903_ANALOGUE_HP_0, 6, 0, NULL, 0),
881 SND_SOC_DAPM_PRE_PMD), 890SND_SOC_DAPM_PGA_S("HPL_ENA_DLY", 1, WM8903_ANALOGUE_HP_0, 5, 0, NULL, 0),
882SND_SOC_DAPM_PGA_E("Right Line Output PGA", WM8903_POWER_MANAGEMENT_3, 0, 0, 891SND_SOC_DAPM_PGA_S("HPR_RMV_SHORT", 4, WM8903_ANALOGUE_HP_0, 3, 0, NULL, 0),
883 NULL, 0, wm8903_output_event, 892SND_SOC_DAPM_PGA_S("HPR_ENA_OUTP", 3, WM8903_ANALOGUE_HP_0, 2, 0, NULL, 0),
884 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 893SND_SOC_DAPM_PGA_S("HPR_ENA_DLY", 1, WM8903_ANALOGUE_HP_0, 1, 0, NULL, 0),
885 SND_SOC_DAPM_PRE_PMD), 894
895SND_SOC_DAPM_PGA_S("LINEOUTL_RMV_SHORT", 4, WM8903_ANALOGUE_LINEOUT_0, 7, 0,
896 NULL, 0),
897SND_SOC_DAPM_PGA_S("LINEOUTL_ENA_OUTP", 3, WM8903_ANALOGUE_LINEOUT_0, 6, 0,
898 NULL, 0),
899SND_SOC_DAPM_PGA_S("LINEOUTL_ENA_DLY", 1, WM8903_ANALOGUE_LINEOUT_0, 5, 0,
900 NULL, 0),
901SND_SOC_DAPM_PGA_S("LINEOUTR_RMV_SHORT", 4, WM8903_ANALOGUE_LINEOUT_0, 3, 0,
902 NULL, 0),
903SND_SOC_DAPM_PGA_S("LINEOUTR_ENA_OUTP", 3, WM8903_ANALOGUE_LINEOUT_0, 2, 0,
904 NULL, 0),
905SND_SOC_DAPM_PGA_S("LINEOUTR_ENA_DLY", 1, WM8903_ANALOGUE_LINEOUT_0, 1, 0,
906 NULL, 0),
907
908SND_SOC_DAPM_SUPPLY("DCS Master", WM8903_DC_SERVO_0, 4, 0, NULL, 0),
909SND_SOC_DAPM_PGA_S("HPL_DCS", 3, SND_SOC_NOPM, 3, 0, wm8903_dcs_event,
910 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
911SND_SOC_DAPM_PGA_S("HPR_DCS", 3, SND_SOC_NOPM, 2, 0, wm8903_dcs_event,
912 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
913SND_SOC_DAPM_PGA_S("LINEOUTL_DCS", 3, SND_SOC_NOPM, 1, 0, wm8903_dcs_event,
914 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
915SND_SOC_DAPM_PGA_S("LINEOUTR_DCS", 3, SND_SOC_NOPM, 0, 0, wm8903_dcs_event,
916 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
886 917
887SND_SOC_DAPM_PGA("Left Speaker PGA", WM8903_POWER_MANAGEMENT_5, 1, 0, 918SND_SOC_DAPM_PGA("Left Speaker PGA", WM8903_POWER_MANAGEMENT_5, 1, 0,
888 NULL, 0), 919 NULL, 0),
@@ -892,10 +923,18 @@ SND_SOC_DAPM_PGA("Right Speaker PGA", WM8903_POWER_MANAGEMENT_5, 0, 0,
892SND_SOC_DAPM_SUPPLY("Charge Pump", WM8903_CHARGE_PUMP_0, 0, 0, 923SND_SOC_DAPM_SUPPLY("Charge Pump", WM8903_CHARGE_PUMP_0, 0, 0,
893 wm8903_cp_event, SND_SOC_DAPM_POST_PMU), 924 wm8903_cp_event, SND_SOC_DAPM_POST_PMU),
894SND_SOC_DAPM_SUPPLY("CLK_DSP", WM8903_CLOCK_RATES_2, 1, 0, NULL, 0), 925SND_SOC_DAPM_SUPPLY("CLK_DSP", WM8903_CLOCK_RATES_2, 1, 0, NULL, 0),
926SND_SOC_DAPM_SUPPLY("CLK_SYS", WM8903_CLOCK_RATES_2, 2, 0, NULL, 0),
895}; 927};
896 928
897static const struct snd_soc_dapm_route intercon[] = { 929static const struct snd_soc_dapm_route intercon[] = {
898 930
931 { "CLK_DSP", NULL, "CLK_SYS" },
932 { "Mic Bias", NULL, "CLK_SYS" },
933 { "HPL_DCS", NULL, "CLK_SYS" },
934 { "HPR_DCS", NULL, "CLK_SYS" },
935 { "LINEOUTL_DCS", NULL, "CLK_SYS" },
936 { "LINEOUTR_DCS", NULL, "CLK_SYS" },
937
899 { "Left Input Mux", "IN1L", "IN1L" }, 938 { "Left Input Mux", "IN1L", "IN1L" },
900 { "Left Input Mux", "IN2L", "IN2L" }, 939 { "Left Input Mux", "IN2L", "IN2L" },
901 { "Left Input Mux", "IN3L", "IN3L" }, 940 { "Left Input Mux", "IN3L", "IN3L" },
@@ -936,18 +975,36 @@ static const struct snd_soc_dapm_route intercon[] = {
936 { "Left Input PGA", NULL, "Left Input Mode Mux" }, 975 { "Left Input PGA", NULL, "Left Input Mode Mux" },
937 { "Right Input PGA", NULL, "Right Input Mode Mux" }, 976 { "Right Input PGA", NULL, "Right Input Mode Mux" },
938 977
978 { "Left Capture Mux", "Left", "ADCL" },
979 { "Left Capture Mux", "Right", "ADCR" },
980
981 { "Right Capture Mux", "Left", "ADCL" },
982 { "Right Capture Mux", "Right", "ADCR" },
983
984 { "AIFTXL", NULL, "Left Capture Mux" },
985 { "AIFTXR", NULL, "Right Capture Mux" },
986
939 { "ADCL", NULL, "Left Input PGA" }, 987 { "ADCL", NULL, "Left Input PGA" },
940 { "ADCL", NULL, "CLK_DSP" }, 988 { "ADCL", NULL, "CLK_DSP" },
941 { "ADCR", NULL, "Right Input PGA" }, 989 { "ADCR", NULL, "Right Input PGA" },
942 { "ADCR", NULL, "CLK_DSP" }, 990 { "ADCR", NULL, "CLK_DSP" },
943 991
992 { "Left Playback Mux", "Left", "AIFRXL" },
993 { "Left Playback Mux", "Right", "AIFRXR" },
994
995 { "Right Playback Mux", "Left", "AIFRXL" },
996 { "Right Playback Mux", "Right", "AIFRXR" },
997
944 { "DACL Sidetone", "Left", "ADCL" }, 998 { "DACL Sidetone", "Left", "ADCL" },
945 { "DACL Sidetone", "Right", "ADCR" }, 999 { "DACL Sidetone", "Right", "ADCR" },
946 { "DACR Sidetone", "Left", "ADCL" }, 1000 { "DACR Sidetone", "Left", "ADCL" },
947 { "DACR Sidetone", "Right", "ADCR" }, 1001 { "DACR Sidetone", "Right", "ADCR" },
948 1002
1003 { "DACL", NULL, "Left Playback Mux" },
949 { "DACL", NULL, "DACL Sidetone" }, 1004 { "DACL", NULL, "DACL Sidetone" },
950 { "DACL", NULL, "CLK_DSP" }, 1005 { "DACL", NULL, "CLK_DSP" },
1006
1007 { "DACR", NULL, "Right Playback Mux" },
951 { "DACR", NULL, "DACR Sidetone" }, 1008 { "DACR", NULL, "DACR Sidetone" },
952 { "DACR", NULL, "CLK_DSP" }, 1009 { "DACR", NULL, "CLK_DSP" },
953 1010
@@ -980,11 +1037,35 @@ static const struct snd_soc_dapm_route intercon[] = {
980 { "Left Speaker PGA", NULL, "Left Speaker Mixer" }, 1037 { "Left Speaker PGA", NULL, "Left Speaker Mixer" },
981 { "Right Speaker PGA", NULL, "Right Speaker Mixer" }, 1038 { "Right Speaker PGA", NULL, "Right Speaker Mixer" },
982 1039
983 { "HPOUTL", NULL, "Left Headphone Output PGA" }, 1040 { "HPL_ENA_DLY", NULL, "Left Headphone Output PGA" },
984 { "HPOUTR", NULL, "Right Headphone Output PGA" }, 1041 { "HPR_ENA_DLY", NULL, "Right Headphone Output PGA" },
1042 { "LINEOUTL_ENA_DLY", NULL, "Left Line Output PGA" },
1043 { "LINEOUTR_ENA_DLY", NULL, "Right Line Output PGA" },
1044
1045 { "HPL_DCS", NULL, "DCS Master" },
1046 { "HPR_DCS", NULL, "DCS Master" },
1047 { "LINEOUTL_DCS", NULL, "DCS Master" },
1048 { "LINEOUTR_DCS", NULL, "DCS Master" },
1049
1050 { "HPL_DCS", NULL, "HPL_ENA_DLY" },
1051 { "HPR_DCS", NULL, "HPR_ENA_DLY" },
1052 { "LINEOUTL_DCS", NULL, "LINEOUTL_ENA_DLY" },
1053 { "LINEOUTR_DCS", NULL, "LINEOUTR_ENA_DLY" },
985 1054
986 { "LINEOUTL", NULL, "Left Line Output PGA" }, 1055 { "HPL_ENA_OUTP", NULL, "HPL_DCS" },
987 { "LINEOUTR", NULL, "Right Line Output PGA" }, 1056 { "HPR_ENA_OUTP", NULL, "HPR_DCS" },
1057 { "LINEOUTL_ENA_OUTP", NULL, "LINEOUTL_DCS" },
1058 { "LINEOUTR_ENA_OUTP", NULL, "LINEOUTR_DCS" },
1059
1060 { "HPL_RMV_SHORT", NULL, "HPL_ENA_OUTP" },
1061 { "HPR_RMV_SHORT", NULL, "HPR_ENA_OUTP" },
1062 { "LINEOUTL_RMV_SHORT", NULL, "LINEOUTL_ENA_OUTP" },
1063 { "LINEOUTR_RMV_SHORT", NULL, "LINEOUTR_ENA_OUTP" },
1064
1065 { "HPOUTL", NULL, "HPL_RMV_SHORT" },
1066 { "HPOUTR", NULL, "HPR_RMV_SHORT" },
1067 { "LINEOUTL", NULL, "LINEOUTL_RMV_SHORT" },
1068 { "LINEOUTR", NULL, "LINEOUTR_RMV_SHORT" },
988 1069
989 { "LOP", NULL, "Left Speaker PGA" }, 1070 { "LOP", NULL, "Left Speaker PGA" },
990 { "LON", NULL, "Left Speaker PGA" }, 1071 { "LON", NULL, "Left Speaker PGA" },
@@ -1012,29 +1093,71 @@ static int wm8903_add_widgets(struct snd_soc_codec *codec)
1012static int wm8903_set_bias_level(struct snd_soc_codec *codec, 1093static int wm8903_set_bias_level(struct snd_soc_codec *codec,
1013 enum snd_soc_bias_level level) 1094 enum snd_soc_bias_level level)
1014{ 1095{
1015 u16 reg;
1016
1017 switch (level) { 1096 switch (level) {
1018 case SND_SOC_BIAS_ON: 1097 case SND_SOC_BIAS_ON:
1098 break;
1099
1019 case SND_SOC_BIAS_PREPARE: 1100 case SND_SOC_BIAS_PREPARE:
1020 reg = snd_soc_read(codec, WM8903_VMID_CONTROL_0); 1101 snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0,
1021 reg &= ~(WM8903_VMID_RES_MASK); 1102 WM8903_VMID_RES_MASK,
1022 reg |= WM8903_VMID_RES_50K; 1103 WM8903_VMID_RES_50K);
1023 snd_soc_write(codec, WM8903_VMID_CONTROL_0, reg);
1024 break; 1104 break;
1025 1105
1026 case SND_SOC_BIAS_STANDBY: 1106 case SND_SOC_BIAS_STANDBY:
1027 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { 1107 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1028 snd_soc_write(codec, WM8903_CLOCK_RATES_2, 1108 snd_soc_update_bits(codec, WM8903_BIAS_CONTROL_0,
1029 WM8903_CLK_SYS_ENA); 1109 WM8903_POBCTRL | WM8903_ISEL_MASK |
1030 1110 WM8903_STARTUP_BIAS_ENA |
1031 /* Change DC servo dither level in startup sequence */ 1111 WM8903_BIAS_ENA,
1032 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0, 0x11); 1112 WM8903_POBCTRL |
1033 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_1, 0x1257); 1113 (2 << WM8903_ISEL_SHIFT) |
1034 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_2, 0x2); 1114 WM8903_STARTUP_BIAS_ENA);
1035 1115
1036 wm8903_run_sequence(codec, 0); 1116 snd_soc_update_bits(codec,
1037 wm8903_sync_reg_cache(codec, codec->reg_cache); 1117 WM8903_ANALOGUE_SPK_OUTPUT_CONTROL_0,
1118 WM8903_SPK_DISCHARGE,
1119 WM8903_SPK_DISCHARGE);
1120
1121 msleep(33);
1122
1123 snd_soc_update_bits(codec, WM8903_POWER_MANAGEMENT_5,
1124 WM8903_SPKL_ENA | WM8903_SPKR_ENA,
1125 WM8903_SPKL_ENA | WM8903_SPKR_ENA);
1126
1127 snd_soc_update_bits(codec,
1128 WM8903_ANALOGUE_SPK_OUTPUT_CONTROL_0,
1129 WM8903_SPK_DISCHARGE, 0);
1130
1131 snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0,
1132 WM8903_VMID_TIE_ENA |
1133 WM8903_BUFIO_ENA |
1134 WM8903_VMID_IO_ENA |
1135 WM8903_VMID_SOFT_MASK |
1136 WM8903_VMID_RES_MASK |
1137 WM8903_VMID_BUF_ENA,
1138 WM8903_VMID_TIE_ENA |
1139 WM8903_BUFIO_ENA |
1140 WM8903_VMID_IO_ENA |
1141 (2 << WM8903_VMID_SOFT_SHIFT) |
1142 WM8903_VMID_RES_250K |
1143 WM8903_VMID_BUF_ENA);
1144
1145 msleep(129);
1146
1147 snd_soc_update_bits(codec, WM8903_POWER_MANAGEMENT_5,
1148 WM8903_SPKL_ENA | WM8903_SPKR_ENA,
1149 0);
1150
1151 snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0,
1152 WM8903_VMID_SOFT_MASK, 0);
1153
1154 snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0,
1155 WM8903_VMID_RES_MASK,
1156 WM8903_VMID_RES_50K);
1157
1158 snd_soc_update_bits(codec, WM8903_BIAS_CONTROL_0,
1159 WM8903_BIAS_ENA | WM8903_POBCTRL,
1160 WM8903_BIAS_ENA);
1038 1161
1039 /* By default no bypass paths are enabled so 1162 /* By default no bypass paths are enabled so
1040 * enable Class W support. 1163 * enable Class W support.
@@ -1047,17 +1170,32 @@ static int wm8903_set_bias_level(struct snd_soc_codec *codec,
1047 WM8903_CP_DYN_V); 1170 WM8903_CP_DYN_V);
1048 } 1171 }
1049 1172
1050 reg = snd_soc_read(codec, WM8903_VMID_CONTROL_0); 1173 snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0,
1051 reg &= ~(WM8903_VMID_RES_MASK); 1174 WM8903_VMID_RES_MASK,
1052 reg |= WM8903_VMID_RES_250K; 1175 WM8903_VMID_RES_250K);
1053 snd_soc_write(codec, WM8903_VMID_CONTROL_0, reg);
1054 break; 1176 break;
1055 1177
1056 case SND_SOC_BIAS_OFF: 1178 case SND_SOC_BIAS_OFF:
1057 wm8903_run_sequence(codec, 32); 1179 snd_soc_update_bits(codec, WM8903_BIAS_CONTROL_0,
1058 reg = snd_soc_read(codec, WM8903_CLOCK_RATES_2); 1180 WM8903_BIAS_ENA, 0);
1059 reg &= ~WM8903_CLK_SYS_ENA; 1181
1060 snd_soc_write(codec, WM8903_CLOCK_RATES_2, reg); 1182 snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0,
1183 WM8903_VMID_SOFT_MASK,
1184 2 << WM8903_VMID_SOFT_SHIFT);
1185
1186 snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0,
1187 WM8903_VMID_BUF_ENA, 0);
1188
1189 msleep(290);
1190
1191 snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0,
1192 WM8903_VMID_TIE_ENA | WM8903_BUFIO_ENA |
1193 WM8903_VMID_IO_ENA | WM8903_VMID_RES_MASK |
1194 WM8903_VMID_SOFT_MASK |
1195 WM8903_VMID_BUF_ENA, 0);
1196
1197 snd_soc_update_bits(codec, WM8903_BIAS_CONTROL_0,
1198 WM8903_STARTUP_BIAS_ENA, 0);
1061 break; 1199 break;
1062 } 1200 }
1063 1201
@@ -1510,8 +1648,7 @@ static irqreturn_t wm8903_irq(int irq, void *data)
1510 int_val = snd_soc_read(codec, WM8903_INTERRUPT_STATUS_1) & mask; 1648 int_val = snd_soc_read(codec, WM8903_INTERRUPT_STATUS_1) & mask;
1511 1649
1512 if (int_val & WM8903_WSEQ_BUSY_EINT) { 1650 if (int_val & WM8903_WSEQ_BUSY_EINT) {
1513 dev_dbg(codec->dev, "Write sequencer done\n"); 1651 dev_warn(codec->dev, "Write sequencer done\n");
1514 complete(&wm8903->wseq);
1515 } 1652 }
1516 1653
1517 /* 1654 /*
@@ -1635,6 +1772,120 @@ static int wm8903_resume(struct snd_soc_codec *codec)
1635 return 0; 1772 return 0;
1636} 1773}
1637 1774
1775#ifdef CONFIG_GPIOLIB
1776static inline struct wm8903_priv *gpio_to_wm8903(struct gpio_chip *chip)
1777{
1778 return container_of(chip, struct wm8903_priv, gpio_chip);
1779}
1780
1781static int wm8903_gpio_request(struct gpio_chip *chip, unsigned offset)
1782{
1783 if (offset >= WM8903_NUM_GPIO)
1784 return -EINVAL;
1785
1786 return 0;
1787}
1788
1789static int wm8903_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
1790{
1791 struct wm8903_priv *wm8903 = gpio_to_wm8903(chip);
1792 struct snd_soc_codec *codec = wm8903->codec;
1793 unsigned int mask, val;
1794
1795 mask = WM8903_GP1_FN_MASK | WM8903_GP1_DIR_MASK;
1796 val = (WM8903_GPn_FN_GPIO_INPUT << WM8903_GP1_FN_SHIFT) |
1797 WM8903_GP1_DIR;
1798
1799 return snd_soc_update_bits(codec, WM8903_GPIO_CONTROL_1 + offset,
1800 mask, val);
1801}
1802
1803static int wm8903_gpio_get(struct gpio_chip *chip, unsigned offset)
1804{
1805 struct wm8903_priv *wm8903 = gpio_to_wm8903(chip);
1806 struct snd_soc_codec *codec = wm8903->codec;
1807 int reg;
1808
1809 reg = snd_soc_read(codec, WM8903_GPIO_CONTROL_1 + offset);
1810
1811 return (reg & WM8903_GP1_LVL_MASK) >> WM8903_GP1_LVL_SHIFT;
1812}
1813
1814static int wm8903_gpio_direction_out(struct gpio_chip *chip,
1815 unsigned offset, int value)
1816{
1817 struct wm8903_priv *wm8903 = gpio_to_wm8903(chip);
1818 struct snd_soc_codec *codec = wm8903->codec;
1819 unsigned int mask, val;
1820
1821 mask = WM8903_GP1_FN_MASK | WM8903_GP1_DIR_MASK | WM8903_GP1_LVL_MASK;
1822 val = (WM8903_GPn_FN_GPIO_OUTPUT << WM8903_GP1_FN_SHIFT) |
1823 (value << WM8903_GP2_LVL_SHIFT);
1824
1825 return snd_soc_update_bits(codec, WM8903_GPIO_CONTROL_1 + offset,
1826 mask, val);
1827}
1828
1829static void wm8903_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
1830{
1831 struct wm8903_priv *wm8903 = gpio_to_wm8903(chip);
1832 struct snd_soc_codec *codec = wm8903->codec;
1833
1834 snd_soc_update_bits(codec, WM8903_GPIO_CONTROL_1 + offset,
1835 WM8903_GP1_LVL_MASK,
1836 !!value << WM8903_GP1_LVL_SHIFT);
1837}
1838
1839static struct gpio_chip wm8903_template_chip = {
1840 .label = "wm8903",
1841 .owner = THIS_MODULE,
1842 .request = wm8903_gpio_request,
1843 .direction_input = wm8903_gpio_direction_in,
1844 .get = wm8903_gpio_get,
1845 .direction_output = wm8903_gpio_direction_out,
1846 .set = wm8903_gpio_set,
1847 .can_sleep = 1,
1848};
1849
1850static void wm8903_init_gpio(struct snd_soc_codec *codec)
1851{
1852 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1853 struct wm8903_platform_data *pdata = dev_get_platdata(codec->dev);
1854 int ret;
1855
1856 wm8903->gpio_chip = wm8903_template_chip;
1857 wm8903->gpio_chip.ngpio = WM8903_NUM_GPIO;
1858 wm8903->gpio_chip.dev = codec->dev;
1859
1860 if (pdata && pdata->gpio_base)
1861 wm8903->gpio_chip.base = pdata->gpio_base;
1862 else
1863 wm8903->gpio_chip.base = -1;
1864
1865 ret = gpiochip_add(&wm8903->gpio_chip);
1866 if (ret != 0)
1867 dev_err(codec->dev, "Failed to add GPIOs: %d\n", ret);
1868}
1869
1870static void wm8903_free_gpio(struct snd_soc_codec *codec)
1871{
1872 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1873 int ret;
1874
1875 ret = gpiochip_remove(&wm8903->gpio_chip);
1876 if (ret != 0)
1877 dev_err(codec->dev, "Failed to remove GPIOs: %d\n", ret);
1878}
1879#else
1880static void wm8903_init_gpio(struct snd_soc_codec *codec)
1881{
1882}
1883
1884static void wm8903_free_gpio(struct snd_soc_codec *codec)
1885{
1886}
1887#endif
1888
1638static int wm8903_probe(struct snd_soc_codec *codec) 1889static int wm8903_probe(struct snd_soc_codec *codec)
1639{ 1890{
1640 struct wm8903_platform_data *pdata = dev_get_platdata(codec->dev); 1891 struct wm8903_platform_data *pdata = dev_get_platdata(codec->dev);
@@ -1643,7 +1894,7 @@ static int wm8903_probe(struct snd_soc_codec *codec)
1643 int trigger, irq_pol; 1894 int trigger, irq_pol;
1644 u16 val; 1895 u16 val;
1645 1896
1646 init_completion(&wm8903->wseq); 1897 wm8903->codec = codec;
1647 1898
1648 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); 1899 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
1649 if (ret != 0) { 1900 if (ret != 0) {
@@ -1659,19 +1910,33 @@ static int wm8903_probe(struct snd_soc_codec *codec)
1659 } 1910 }
1660 1911
1661 val = snd_soc_read(codec, WM8903_REVISION_NUMBER); 1912 val = snd_soc_read(codec, WM8903_REVISION_NUMBER);
1662 dev_info(codec->dev, "WM8903 revision %d\n", 1913 dev_info(codec->dev, "WM8903 revision %c\n",
1663 val & WM8903_CHIP_REV_MASK); 1914 (val & WM8903_CHIP_REV_MASK) + 'A');
1664 1915
1665 wm8903_reset(codec); 1916 wm8903_reset(codec);
1666 1917
1667 /* Set up GPIOs and microphone detection */ 1918 /* Set up GPIOs and microphone detection */
1668 if (pdata) { 1919 if (pdata) {
1920 bool mic_gpio = false;
1921
1669 for (i = 0; i < ARRAY_SIZE(pdata->gpio_cfg); i++) { 1922 for (i = 0; i < ARRAY_SIZE(pdata->gpio_cfg); i++) {
1670 if (!pdata->gpio_cfg[i]) 1923 if (pdata->gpio_cfg[i] == WM8903_GPIO_NO_CONFIG)
1671 continue; 1924 continue;
1672 1925
1673 snd_soc_write(codec, WM8903_GPIO_CONTROL_1 + i, 1926 snd_soc_write(codec, WM8903_GPIO_CONTROL_1 + i,
1674 pdata->gpio_cfg[i] & 0xffff); 1927 pdata->gpio_cfg[i] & 0xffff);
1928
1929 val = (pdata->gpio_cfg[i] & WM8903_GP1_FN_MASK)
1930 >> WM8903_GP1_FN_SHIFT;
1931
1932 switch (val) {
1933 case WM8903_GPn_FN_MICBIAS_CURRENT_DETECT:
1934 case WM8903_GPn_FN_MICBIAS_SHORT_DETECT:
1935 mic_gpio = true;
1936 break;
1937 default:
1938 break;
1939 }
1675 } 1940 }
1676 1941
1677 snd_soc_write(codec, WM8903_MIC_BIAS_CONTROL_0, 1942 snd_soc_write(codec, WM8903_MIC_BIAS_CONTROL_0,
@@ -1682,6 +1947,14 @@ static int wm8903_probe(struct snd_soc_codec *codec)
1682 snd_soc_update_bits(codec, WM8903_WRITE_SEQUENCER_0, 1947 snd_soc_update_bits(codec, WM8903_WRITE_SEQUENCER_0,
1683 WM8903_WSEQ_ENA, WM8903_WSEQ_ENA); 1948 WM8903_WSEQ_ENA, WM8903_WSEQ_ENA);
1684 1949
1950 /* If microphone detection is enabled by pdata but
1951 * detected via IRQ then interrupts can be lost before
1952 * the machine driver has set up microphone detection
1953 * IRQs as the IRQs are clear on read. The detection
1954 * will be enabled when the machine driver configures.
1955 */
1956 WARN_ON(!mic_gpio && (pdata->micdet_cfg & WM8903_MICDET_ENA));
1957
1685 wm8903->mic_delay = pdata->micdet_delay; 1958 wm8903->mic_delay = pdata->micdet_delay;
1686 } 1959 }
1687 1960
@@ -1741,20 +2014,23 @@ static int wm8903_probe(struct snd_soc_codec *codec)
1741 snd_soc_write(codec, WM8903_ANALOGUE_OUT3_RIGHT, val); 2014 snd_soc_write(codec, WM8903_ANALOGUE_OUT3_RIGHT, val);
1742 2015
1743 /* Enable DAC soft mute by default */ 2016 /* Enable DAC soft mute by default */
1744 val = snd_soc_read(codec, WM8903_DAC_DIGITAL_1); 2017 snd_soc_update_bits(codec, WM8903_DAC_DIGITAL_1,
1745 val |= WM8903_DAC_MUTEMODE; 2018 WM8903_DAC_MUTEMODE | WM8903_DAC_MUTE,
1746 snd_soc_write(codec, WM8903_DAC_DIGITAL_1, val); 2019 WM8903_DAC_MUTEMODE | WM8903_DAC_MUTE);
1747 2020
1748 snd_soc_add_controls(codec, wm8903_snd_controls, 2021 snd_soc_add_controls(codec, wm8903_snd_controls,
1749 ARRAY_SIZE(wm8903_snd_controls)); 2022 ARRAY_SIZE(wm8903_snd_controls));
1750 wm8903_add_widgets(codec); 2023 wm8903_add_widgets(codec);
1751 2024
2025 wm8903_init_gpio(codec);
2026
1752 return ret; 2027 return ret;
1753} 2028}
1754 2029
1755/* power down chip */ 2030/* power down chip */
1756static int wm8903_remove(struct snd_soc_codec *codec) 2031static int wm8903_remove(struct snd_soc_codec *codec)
1757{ 2032{
2033 wm8903_free_gpio(codec);
1758 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF); 2034 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF);
1759 return 0; 2035 return 0;
1760} 2036}
@@ -1769,6 +2045,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8903 = {
1769 .reg_word_size = sizeof(u16), 2045 .reg_word_size = sizeof(u16),
1770 .reg_cache_default = wm8903_reg_defaults, 2046 .reg_cache_default = wm8903_reg_defaults,
1771 .volatile_register = wm8903_volatile_register, 2047 .volatile_register = wm8903_volatile_register,
2048 .seq_notifier = wm8903_seq_notifier,
1772}; 2049};
1773 2050
1774#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 2051#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
@@ -1807,7 +2084,7 @@ MODULE_DEVICE_TABLE(i2c, wm8903_i2c_id);
1807 2084
1808static struct i2c_driver wm8903_i2c_driver = { 2085static struct i2c_driver wm8903_i2c_driver = {
1809 .driver = { 2086 .driver = {
1810 .name = "wm8903-codec", 2087 .name = "wm8903",
1811 .owner = THIS_MODULE, 2088 .owner = THIS_MODULE,
1812 }, 2089 },
1813 .probe = wm8903_i2c_probe, 2090 .probe = wm8903_i2c_probe,
diff --git a/sound/soc/codecs/wm8903.h b/sound/soc/codecs/wm8903.h
index e3ec2433b215..db949311c0f2 100644
--- a/sound/soc/codecs/wm8903.h
+++ b/sound/soc/codecs/wm8903.h
@@ -75,6 +75,14 @@ extern int wm8903_mic_detect(struct snd_soc_codec *codec,
75#define WM8903_ANALOGUE_SPK_OUTPUT_CONTROL_0 0x41 75#define WM8903_ANALOGUE_SPK_OUTPUT_CONTROL_0 0x41
76#define WM8903_DC_SERVO_0 0x43 76#define WM8903_DC_SERVO_0 0x43
77#define WM8903_DC_SERVO_2 0x45 77#define WM8903_DC_SERVO_2 0x45
78#define WM8903_DC_SERVO_4 0x47
79#define WM8903_DC_SERVO_5 0x48
80#define WM8903_DC_SERVO_6 0x49
81#define WM8903_DC_SERVO_7 0x4A
82#define WM8903_DC_SERVO_READBACK_1 0x51
83#define WM8903_DC_SERVO_READBACK_2 0x52
84#define WM8903_DC_SERVO_READBACK_3 0x53
85#define WM8903_DC_SERVO_READBACK_4 0x54
78#define WM8903_ANALOGUE_HP_0 0x5A 86#define WM8903_ANALOGUE_HP_0 0x5A
79#define WM8903_ANALOGUE_LINEOUT_0 0x5E 87#define WM8903_ANALOGUE_LINEOUT_0 0x5E
80#define WM8903_CHARGE_PUMP_0 0x62 88#define WM8903_CHARGE_PUMP_0 0x62
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index 9de44a4c05c0..443ae580445c 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -596,7 +596,7 @@ static struct {
596 { 0x003F, 0x003F, 0 }, /* R248 - FLL NCO Test 1 */ 596 { 0x003F, 0x003F, 0 }, /* R248 - FLL NCO Test 1 */
597}; 597};
598 598
599static int wm8904_volatile_register(unsigned int reg) 599static int wm8904_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
600{ 600{
601 return wm8904_access[reg].vol; 601 return wm8904_access[reg].vol;
602} 602}
@@ -2436,19 +2436,28 @@ static int wm8904_probe(struct snd_soc_codec *codec)
2436 } 2436 }
2437 2437
2438 /* Change some default settings - latch VU and enable ZC */ 2438 /* Change some default settings - latch VU and enable ZC */
2439 reg_cache[WM8904_ADC_DIGITAL_VOLUME_LEFT] |= WM8904_ADC_VU; 2439 snd_soc_update_bits(codec, WM8904_ADC_DIGITAL_VOLUME_LEFT,
2440 reg_cache[WM8904_ADC_DIGITAL_VOLUME_RIGHT] |= WM8904_ADC_VU; 2440 WM8904_ADC_VU, WM8904_ADC_VU);
2441 reg_cache[WM8904_DAC_DIGITAL_VOLUME_LEFT] |= WM8904_DAC_VU; 2441 snd_soc_update_bits(codec, WM8904_ADC_DIGITAL_VOLUME_RIGHT,
2442 reg_cache[WM8904_DAC_DIGITAL_VOLUME_RIGHT] |= WM8904_DAC_VU; 2442 WM8904_ADC_VU, WM8904_ADC_VU);
2443 reg_cache[WM8904_ANALOGUE_OUT1_LEFT] |= WM8904_HPOUT_VU | 2443 snd_soc_update_bits(codec, WM8904_DAC_DIGITAL_VOLUME_LEFT,
2444 WM8904_HPOUTLZC; 2444 WM8904_DAC_VU, WM8904_DAC_VU);
2445 reg_cache[WM8904_ANALOGUE_OUT1_RIGHT] |= WM8904_HPOUT_VU | 2445 snd_soc_update_bits(codec, WM8904_DAC_DIGITAL_VOLUME_RIGHT,
2446 WM8904_HPOUTRZC; 2446 WM8904_DAC_VU, WM8904_DAC_VU);
2447 reg_cache[WM8904_ANALOGUE_OUT2_LEFT] |= WM8904_LINEOUT_VU | 2447 snd_soc_update_bits(codec, WM8904_ANALOGUE_OUT1_LEFT,
2448 WM8904_LINEOUTLZC; 2448 WM8904_HPOUT_VU | WM8904_HPOUTLZC,
2449 reg_cache[WM8904_ANALOGUE_OUT2_RIGHT] |= WM8904_LINEOUT_VU | 2449 WM8904_HPOUT_VU | WM8904_HPOUTLZC);
2450 WM8904_LINEOUTRZC; 2450 snd_soc_update_bits(codec, WM8904_ANALOGUE_OUT1_RIGHT,
2451 reg_cache[WM8904_CLOCK_RATES_0] &= ~WM8904_SR_MODE; 2451 WM8904_HPOUT_VU | WM8904_HPOUTRZC,
2452 WM8904_HPOUT_VU | WM8904_HPOUTRZC);
2453 snd_soc_update_bits(codec, WM8904_ANALOGUE_OUT2_LEFT,
2454 WM8904_LINEOUT_VU | WM8904_LINEOUTLZC,
2455 WM8904_LINEOUT_VU | WM8904_LINEOUTLZC);
2456 snd_soc_update_bits(codec, WM8904_ANALOGUE_OUT2_RIGHT,
2457 WM8904_LINEOUT_VU | WM8904_LINEOUTRZC,
2458 WM8904_LINEOUT_VU | WM8904_LINEOUTRZC);
2459 snd_soc_update_bits(codec, WM8904_CLOCK_RATES_0,
2460 WM8904_SR_MODE, 0);
2452 2461
2453 /* Apply configuration from the platform data. */ 2462 /* Apply configuration from the platform data. */
2454 if (wm8904->pdata) { 2463 if (wm8904->pdata) {
@@ -2469,10 +2478,12 @@ static int wm8904_probe(struct snd_soc_codec *codec)
2469 /* Set Class W by default - this will be managed by the Class 2478 /* Set Class W by default - this will be managed by the Class
2470 * G widget at runtime where bypass paths are available. 2479 * G widget at runtime where bypass paths are available.
2471 */ 2480 */
2472 reg_cache[WM8904_CLASS_W_0] |= WM8904_CP_DYN_PWR; 2481 snd_soc_update_bits(codec, WM8904_CLASS_W_0,
2482 WM8904_CP_DYN_PWR, WM8904_CP_DYN_PWR);
2473 2483
2474 /* Use normal bias source */ 2484 /* Use normal bias source */
2475 reg_cache[WM8904_BIAS_CONTROL_0] &= ~WM8904_POBCTRL; 2485 snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0,
2486 WM8904_POBCTRL, 0);
2476 2487
2477 wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 2488 wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2478 2489
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c
index 7167dfc96aa7..5e0214d6293e 100644
--- a/sound/soc/codecs/wm8955.c
+++ b/sound/soc/codecs/wm8955.c
@@ -934,16 +934,27 @@ static int wm8955_probe(struct snd_soc_codec *codec)
934 } 934 }
935 935
936 /* Change some default settings - latch VU and enable ZC */ 936 /* Change some default settings - latch VU and enable ZC */
937 reg_cache[WM8955_LEFT_DAC_VOLUME] |= WM8955_LDVU; 937 snd_soc_update_bits(codec, WM8955_LEFT_DAC_VOLUME,
938 reg_cache[WM8955_RIGHT_DAC_VOLUME] |= WM8955_RDVU; 938 WM8955_LDVU, WM8955_LDVU);
939 reg_cache[WM8955_LOUT1_VOLUME] |= WM8955_LO1VU | WM8955_LO1ZC; 939 snd_soc_update_bits(codec, WM8955_RIGHT_DAC_VOLUME,
940 reg_cache[WM8955_ROUT1_VOLUME] |= WM8955_RO1VU | WM8955_RO1ZC; 940 WM8955_RDVU, WM8955_RDVU);
941 reg_cache[WM8955_LOUT2_VOLUME] |= WM8955_LO2VU | WM8955_LO2ZC; 941 snd_soc_update_bits(codec, WM8955_LOUT1_VOLUME,
942 reg_cache[WM8955_ROUT2_VOLUME] |= WM8955_RO2VU | WM8955_RO2ZC; 942 WM8955_LO1VU | WM8955_LO1ZC,
943 reg_cache[WM8955_MONOOUT_VOLUME] |= WM8955_MOZC; 943 WM8955_LO1VU | WM8955_LO1ZC);
944 snd_soc_update_bits(codec, WM8955_ROUT1_VOLUME,
945 WM8955_RO1VU | WM8955_RO1ZC,
946 WM8955_RO1VU | WM8955_RO1ZC);
947 snd_soc_update_bits(codec, WM8955_LOUT2_VOLUME,
948 WM8955_LO2VU | WM8955_LO2ZC,
949 WM8955_LO2VU | WM8955_LO2ZC);
950 snd_soc_update_bits(codec, WM8955_ROUT2_VOLUME,
951 WM8955_RO2VU | WM8955_RO2ZC,
952 WM8955_RO2VU | WM8955_RO2ZC);
953 snd_soc_update_bits(codec, WM8955_MONOOUT_VOLUME,
954 WM8955_MOZC, WM8955_MOZC);
944 955
945 /* Also enable adaptive bass boost by default */ 956 /* Also enable adaptive bass boost by default */
946 reg_cache[WM8955_BASS_CONTROL] |= WM8955_BB; 957 snd_soc_update_bits(codec, WM8955_BASS_CONTROL, WM8955_BB, WM8955_BB);
947 958
948 /* Set platform data values */ 959 /* Set platform data values */
949 if (pdata) { 960 if (pdata) {
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c
index 55252e7d02c9..cdee8103d09b 100644
--- a/sound/soc/codecs/wm8961.c
+++ b/sound/soc/codecs/wm8961.c
@@ -291,7 +291,7 @@ struct wm8961_priv {
291 int sysclk; 291 int sysclk;
292}; 292};
293 293
294static int wm8961_volatile_register(unsigned int reg) 294static int wm8961_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
295{ 295{
296 switch (reg) { 296 switch (reg) {
297 case WM8961_SOFTWARE_RESET: 297 case WM8961_SOFTWARE_RESET:
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index b9cb1fcf8c92..3b71dd65c966 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -1938,7 +1938,7 @@ static const struct wm8962_reg_access {
1938 [21139] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21139 - VSS_XTS32_0 */ 1938 [21139] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21139 - VSS_XTS32_0 */
1939}; 1939};
1940 1940
1941static int wm8962_volatile_register(unsigned int reg) 1941static int wm8962_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
1942{ 1942{
1943 if (wm8962_reg_access[reg].vol) 1943 if (wm8962_reg_access[reg].vol)
1944 return 1; 1944 return 1;
@@ -1946,7 +1946,7 @@ static int wm8962_volatile_register(unsigned int reg)
1946 return 0; 1946 return 0;
1947} 1947}
1948 1948
1949static int wm8962_readable_register(unsigned int reg) 1949static int wm8962_readable_register(struct snd_soc_codec *codec, unsigned int reg)
1950{ 1950{
1951 if (wm8962_reg_access[reg].read) 1951 if (wm8962_reg_access[reg].read)
1952 return 1; 1952 return 1;
@@ -3635,7 +3635,7 @@ static void wm8962_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
3635 struct snd_soc_codec *codec = wm8962->codec; 3635 struct snd_soc_codec *codec = wm8962->codec;
3636 3636
3637 snd_soc_update_bits(codec, WM8962_GPIO_BASE + offset, 3637 snd_soc_update_bits(codec, WM8962_GPIO_BASE + offset,
3638 WM8962_GP2_LVL, value << WM8962_GP2_LVL_SHIFT); 3638 WM8962_GP2_LVL, !!value << WM8962_GP2_LVL_SHIFT);
3639} 3639}
3640 3640
3641static int wm8962_gpio_direction_out(struct gpio_chip *chip, 3641static int wm8962_gpio_direction_out(struct gpio_chip *chip,
@@ -3822,16 +3822,26 @@ static int wm8962_probe(struct snd_soc_codec *codec)
3822 } 3822 }
3823 3823
3824 /* Latch volume update bits */ 3824 /* Latch volume update bits */
3825 reg_cache[WM8962_LEFT_INPUT_VOLUME] |= WM8962_IN_VU; 3825 snd_soc_update_bits(codec, WM8962_LEFT_INPUT_VOLUME,
3826 reg_cache[WM8962_RIGHT_INPUT_VOLUME] |= WM8962_IN_VU; 3826 WM8962_IN_VU, WM8962_IN_VU);
3827 reg_cache[WM8962_LEFT_ADC_VOLUME] |= WM8962_ADC_VU; 3827 snd_soc_update_bits(codec, WM8962_RIGHT_INPUT_VOLUME,
3828 reg_cache[WM8962_RIGHT_ADC_VOLUME] |= WM8962_ADC_VU; 3828 WM8962_IN_VU, WM8962_IN_VU);
3829 reg_cache[WM8962_LEFT_DAC_VOLUME] |= WM8962_DAC_VU; 3829 snd_soc_update_bits(codec, WM8962_LEFT_ADC_VOLUME,
3830 reg_cache[WM8962_RIGHT_DAC_VOLUME] |= WM8962_DAC_VU; 3830 WM8962_ADC_VU, WM8962_ADC_VU);
3831 reg_cache[WM8962_SPKOUTL_VOLUME] |= WM8962_SPKOUT_VU; 3831 snd_soc_update_bits(codec, WM8962_RIGHT_ADC_VOLUME,
3832 reg_cache[WM8962_SPKOUTR_VOLUME] |= WM8962_SPKOUT_VU; 3832 WM8962_ADC_VU, WM8962_ADC_VU);
3833 reg_cache[WM8962_HPOUTL_VOLUME] |= WM8962_HPOUT_VU; 3833 snd_soc_update_bits(codec, WM8962_LEFT_DAC_VOLUME,
3834 reg_cache[WM8962_HPOUTR_VOLUME] |= WM8962_HPOUT_VU; 3834 WM8962_DAC_VU, WM8962_DAC_VU);
3835 snd_soc_update_bits(codec, WM8962_RIGHT_DAC_VOLUME,
3836 WM8962_DAC_VU, WM8962_DAC_VU);
3837 snd_soc_update_bits(codec, WM8962_SPKOUTL_VOLUME,
3838 WM8962_SPKOUT_VU, WM8962_SPKOUT_VU);
3839 snd_soc_update_bits(codec, WM8962_SPKOUTR_VOLUME,
3840 WM8962_SPKOUT_VU, WM8962_SPKOUT_VU);
3841 snd_soc_update_bits(codec, WM8962_HPOUTL_VOLUME,
3842 WM8962_HPOUT_VU, WM8962_HPOUT_VU);
3843 snd_soc_update_bits(codec, WM8962_HPOUTR_VOLUME,
3844 WM8962_HPOUT_VU, WM8962_HPOUT_VU);
3835 3845
3836 wm8962_add_widgets(codec); 3846 wm8962_add_widgets(codec);
3837 3847
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c
index 8dfb0a0da673..85e3e630e763 100644
--- a/sound/soc/codecs/wm8978.c
+++ b/sound/soc/codecs/wm8978.c
@@ -93,6 +93,7 @@ static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
93static const DECLARE_TLV_DB_SCALE(inpga_tlv, -1200, 75, 0); 93static const DECLARE_TLV_DB_SCALE(inpga_tlv, -1200, 75, 0);
94static const DECLARE_TLV_DB_SCALE(spk_tlv, -5700, 100, 0); 94static const DECLARE_TLV_DB_SCALE(spk_tlv, -5700, 100, 0);
95static const DECLARE_TLV_DB_SCALE(boost_tlv, -1500, 300, 1); 95static const DECLARE_TLV_DB_SCALE(boost_tlv, -1500, 300, 1);
96static const DECLARE_TLV_DB_SCALE(limiter_tlv, 0, 100, 0);
96 97
97static const struct snd_kcontrol_new wm8978_snd_controls[] = { 98static const struct snd_kcontrol_new wm8978_snd_controls[] = {
98 99
@@ -144,8 +145,8 @@ static const struct snd_kcontrol_new wm8978_snd_controls[] = {
144 145
145 SOC_SINGLE("DAC Playback Limiter Threshold", 146 SOC_SINGLE("DAC Playback Limiter Threshold",
146 WM8978_DAC_LIMITER_2, 4, 7, 0), 147 WM8978_DAC_LIMITER_2, 4, 7, 0),
147 SOC_SINGLE("DAC Playback Limiter Boost", 148 SOC_SINGLE_TLV("DAC Playback Limiter Volume",
148 WM8978_DAC_LIMITER_2, 0, 12, 0), 149 WM8978_DAC_LIMITER_2, 0, 12, 0, limiter_tlv),
149 150
150 SOC_ENUM("ALC Enable Switch", alc1), 151 SOC_ENUM("ALC Enable Switch", alc1),
151 SOC_SINGLE("ALC Capture Min Gain", WM8978_ALC_CONTROL_1, 0, 7, 0), 152 SOC_SINGLE("ALC Capture Min Gain", WM8978_ALC_CONTROL_1, 0, 7, 0),
@@ -967,7 +968,7 @@ static int wm8978_probe(struct snd_soc_codec *codec)
967 * written. 968 * written.
968 */ 969 */
969 for (i = 0; i < ARRAY_SIZE(update_reg); i++) 970 for (i = 0; i < ARRAY_SIZE(update_reg); i++)
970 ((u16 *)codec->reg_cache)[update_reg[i]] |= 0x100; 971 snd_soc_update_bits(codec, update_reg[i], 0x100, 0x100);
971 972
972 /* Reset the codec */ 973 /* Reset the codec */
973 ret = snd_soc_write(codec, WM8978_RESET, 0); 974 ret = snd_soc_write(codec, WM8978_RESET, 0);
diff --git a/sound/soc/codecs/wm8991.c b/sound/soc/codecs/wm8991.c
new file mode 100644
index 000000000000..28fdfd66661d
--- /dev/null
+++ b/sound/soc/codecs/wm8991.c
@@ -0,0 +1,1427 @@
1/*
2 * wm8991.c -- WM8991 ALSA Soc Audio driver
3 *
4 * Copyright 2007-2010 Wolfson Microelectronics PLC.
5 * Author: Graeme Gregory
6 * linux@wolfsonmicro.com
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#include <linux/module.h>
15#include <linux/moduleparam.h>
16#include <linux/version.h>
17#include <linux/kernel.h>
18#include <linux/init.h>
19#include <linux/delay.h>
20#include <linux/pm.h>
21#include <linux/i2c.h>
22#include <linux/platform_device.h>
23#include <linux/slab.h>
24#include <sound/core.h>
25#include <sound/pcm.h>
26#include <sound/pcm_params.h>
27#include <sound/soc.h>
28#include <sound/soc-dapm.h>
29#include <sound/initval.h>
30#include <sound/tlv.h>
31#include <asm/div64.h>
32
33#include "wm8991.h"
34
35struct wm8991_priv {
36 enum snd_soc_control_type control_type;
37 unsigned int pcmclk;
38};
39
40static const u16 wm8991_reg_defs[] = {
41 0x8991, /* R0 - Reset */
42 0x0000, /* R1 - Power Management (1) */
43 0x6000, /* R2 - Power Management (2) */
44 0x0000, /* R3 - Power Management (3) */
45 0x4050, /* R4 - Audio Interface (1) */
46 0x4000, /* R5 - Audio Interface (2) */
47 0x01C8, /* R6 - Clocking (1) */
48 0x0000, /* R7 - Clocking (2) */
49 0x0040, /* R8 - Audio Interface (3) */
50 0x0040, /* R9 - Audio Interface (4) */
51 0x0004, /* R10 - DAC CTRL */
52 0x00C0, /* R11 - Left DAC Digital Volume */
53 0x00C0, /* R12 - Right DAC Digital Volume */
54 0x0000, /* R13 - Digital Side Tone */
55 0x0100, /* R14 - ADC CTRL */
56 0x00C0, /* R15 - Left ADC Digital Volume */
57 0x00C0, /* R16 - Right ADC Digital Volume */
58 0x0000, /* R17 */
59 0x0000, /* R18 - GPIO CTRL 1 */
60 0x1000, /* R19 - GPIO1 & GPIO2 */
61 0x1010, /* R20 - GPIO3 & GPIO4 */
62 0x1010, /* R21 - GPIO5 & GPIO6 */
63 0x8000, /* R22 - GPIOCTRL 2 */
64 0x0800, /* R23 - GPIO_POL */
65 0x008B, /* R24 - Left Line Input 1&2 Volume */
66 0x008B, /* R25 - Left Line Input 3&4 Volume */
67 0x008B, /* R26 - Right Line Input 1&2 Volume */
68 0x008B, /* R27 - Right Line Input 3&4 Volume */
69 0x0000, /* R28 - Left Output Volume */
70 0x0000, /* R29 - Right Output Volume */
71 0x0066, /* R30 - Line Outputs Volume */
72 0x0022, /* R31 - Out3/4 Volume */
73 0x0079, /* R32 - Left OPGA Volume */
74 0x0079, /* R33 - Right OPGA Volume */
75 0x0003, /* R34 - Speaker Volume */
76 0x0003, /* R35 - ClassD1 */
77 0x0000, /* R36 */
78 0x0100, /* R37 - ClassD3 */
79 0x0000, /* R38 */
80 0x0000, /* R39 - Input Mixer1 */
81 0x0000, /* R40 - Input Mixer2 */
82 0x0000, /* R41 - Input Mixer3 */
83 0x0000, /* R42 - Input Mixer4 */
84 0x0000, /* R43 - Input Mixer5 */
85 0x0000, /* R44 - Input Mixer6 */
86 0x0000, /* R45 - Output Mixer1 */
87 0x0000, /* R46 - Output Mixer2 */
88 0x0000, /* R47 - Output Mixer3 */
89 0x0000, /* R48 - Output Mixer4 */
90 0x0000, /* R49 - Output Mixer5 */
91 0x0000, /* R50 - Output Mixer6 */
92 0x0180, /* R51 - Out3/4 Mixer */
93 0x0000, /* R52 - Line Mixer1 */
94 0x0000, /* R53 - Line Mixer2 */
95 0x0000, /* R54 - Speaker Mixer */
96 0x0000, /* R55 - Additional Control */
97 0x0000, /* R56 - AntiPOP1 */
98 0x0000, /* R57 - AntiPOP2 */
99 0x0000, /* R58 - MICBIAS */
100 0x0000, /* R59 */
101 0x0008, /* R60 - PLL1 */
102 0x0031, /* R61 - PLL2 */
103 0x0026, /* R62 - PLL3 */
104};
105
106#define wm8991_reset(c) snd_soc_write(c, WM8991_RESET, 0)
107
108static const unsigned int rec_mix_tlv[] = {
109 TLV_DB_RANGE_HEAD(1),
110 0, 7, TLV_DB_LINEAR_ITEM(-1500, 600),
111};
112
113static const unsigned int in_pga_tlv[] = {
114 TLV_DB_RANGE_HEAD(1),
115 0, 0x1F, TLV_DB_LINEAR_ITEM(-1650, 3000),
116};
117
118static const unsigned int out_mix_tlv[] = {
119 TLV_DB_RANGE_HEAD(1),
120 0, 7, TLV_DB_LINEAR_ITEM(0, -2100),
121};
122
123static const unsigned int out_pga_tlv[] = {
124 TLV_DB_RANGE_HEAD(1),
125 0, 127, TLV_DB_LINEAR_ITEM(-7300, 600),
126};
127
128static const unsigned int out_omix_tlv[] = {
129 TLV_DB_RANGE_HEAD(1),
130 0, 7, TLV_DB_LINEAR_ITEM(-600, 0),
131};
132
133static const unsigned int out_dac_tlv[] = {
134 TLV_DB_RANGE_HEAD(1),
135 0, 255, TLV_DB_LINEAR_ITEM(-7163, 0),
136};
137
138static const unsigned int in_adc_tlv[] = {
139 TLV_DB_RANGE_HEAD(1),
140 0, 255, TLV_DB_LINEAR_ITEM(-7163, 1763),
141};
142
143static const unsigned int out_sidetone_tlv[] = {
144 TLV_DB_RANGE_HEAD(1),
145 0, 31, TLV_DB_LINEAR_ITEM(-3600, 0),
146};
147
148static int wm899x_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol,
149 struct snd_ctl_elem_value *ucontrol)
150{
151 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
152 int reg = kcontrol->private_value & 0xff;
153 int ret;
154 u16 val;
155
156 ret = snd_soc_put_volsw(kcontrol, ucontrol);
157 if (ret < 0)
158 return ret;
159
160 /* now hit the volume update bits (always bit 8) */
161 val = snd_soc_read(codec, reg);
162 return snd_soc_write(codec, reg, val | 0x0100);
163}
164
165static const char *wm8991_digital_sidetone[] =
166{"None", "Left ADC", "Right ADC", "Reserved"};
167
168static const struct soc_enum wm8991_left_digital_sidetone_enum =
169 SOC_ENUM_SINGLE(WM8991_DIGITAL_SIDE_TONE,
170 WM8991_ADC_TO_DACL_SHIFT,
171 WM8991_ADC_TO_DACL_MASK,
172 wm8991_digital_sidetone);
173
174static const struct soc_enum wm8991_right_digital_sidetone_enum =
175 SOC_ENUM_SINGLE(WM8991_DIGITAL_SIDE_TONE,
176 WM8991_ADC_TO_DACR_SHIFT,
177 WM8991_ADC_TO_DACR_MASK,
178 wm8991_digital_sidetone);
179
180static const char *wm8991_adcmode[] =
181{"Hi-fi mode", "Voice mode 1", "Voice mode 2", "Voice mode 3"};
182
183static const struct soc_enum wm8991_right_adcmode_enum =
184 SOC_ENUM_SINGLE(WM8991_ADC_CTRL,
185 WM8991_ADC_HPF_CUT_SHIFT,
186 WM8991_ADC_HPF_CUT_MASK,
187 wm8991_adcmode);
188
189static const struct snd_kcontrol_new wm8991_snd_controls[] = {
190 /* INMIXL */
191 SOC_SINGLE("LIN12 PGA Boost", WM8991_INPUT_MIXER3, WM8991_L12MNBST_BIT, 1, 0),
192 SOC_SINGLE("LIN34 PGA Boost", WM8991_INPUT_MIXER3, WM8991_L34MNBST_BIT, 1, 0),
193 /* INMIXR */
194 SOC_SINGLE("RIN12 PGA Boost", WM8991_INPUT_MIXER3, WM8991_R12MNBST_BIT, 1, 0),
195 SOC_SINGLE("RIN34 PGA Boost", WM8991_INPUT_MIXER3, WM8991_R34MNBST_BIT, 1, 0),
196
197 /* LOMIX */
198 SOC_SINGLE_TLV("LOMIX LIN3 Bypass Volume", WM8991_OUTPUT_MIXER3,
199 WM8991_LLI3LOVOL_SHIFT, WM8991_LLI3LOVOL_MASK, 1, out_mix_tlv),
200 SOC_SINGLE_TLV("LOMIX RIN12 PGA Bypass Volume", WM8991_OUTPUT_MIXER3,
201 WM8991_LR12LOVOL_SHIFT, WM8991_LR12LOVOL_MASK, 1, out_mix_tlv),
202 SOC_SINGLE_TLV("LOMIX LIN12 PGA Bypass Volume", WM8991_OUTPUT_MIXER3,
203 WM8991_LL12LOVOL_SHIFT, WM8991_LL12LOVOL_MASK, 1, out_mix_tlv),
204 SOC_SINGLE_TLV("LOMIX RIN3 Bypass Volume", WM8991_OUTPUT_MIXER5,
205 WM8991_LRI3LOVOL_SHIFT, WM8991_LRI3LOVOL_MASK, 1, out_mix_tlv),
206 SOC_SINGLE_TLV("LOMIX AINRMUX Bypass Volume", WM8991_OUTPUT_MIXER5,
207 WM8991_LRBLOVOL_SHIFT, WM8991_LRBLOVOL_MASK, 1, out_mix_tlv),
208 SOC_SINGLE_TLV("LOMIX AINLMUX Bypass Volume", WM8991_OUTPUT_MIXER5,
209 WM8991_LRBLOVOL_SHIFT, WM8991_LRBLOVOL_MASK, 1, out_mix_tlv),
210
211 /* ROMIX */
212 SOC_SINGLE_TLV("ROMIX RIN3 Bypass Volume", WM8991_OUTPUT_MIXER4,
213 WM8991_RRI3ROVOL_SHIFT, WM8991_RRI3ROVOL_MASK, 1, out_mix_tlv),
214 SOC_SINGLE_TLV("ROMIX LIN12 PGA Bypass Volume", WM8991_OUTPUT_MIXER4,
215 WM8991_RL12ROVOL_SHIFT, WM8991_RL12ROVOL_MASK, 1, out_mix_tlv),
216 SOC_SINGLE_TLV("ROMIX RIN12 PGA Bypass Volume", WM8991_OUTPUT_MIXER4,
217 WM8991_RR12ROVOL_SHIFT, WM8991_RR12ROVOL_MASK, 1, out_mix_tlv),
218 SOC_SINGLE_TLV("ROMIX LIN3 Bypass Volume", WM8991_OUTPUT_MIXER6,
219 WM8991_RLI3ROVOL_SHIFT, WM8991_RLI3ROVOL_MASK, 1, out_mix_tlv),
220 SOC_SINGLE_TLV("ROMIX AINLMUX Bypass Volume", WM8991_OUTPUT_MIXER6,
221 WM8991_RLBROVOL_SHIFT, WM8991_RLBROVOL_MASK, 1, out_mix_tlv),
222 SOC_SINGLE_TLV("ROMIX AINRMUX Bypass Volume", WM8991_OUTPUT_MIXER6,
223 WM8991_RRBROVOL_SHIFT, WM8991_RRBROVOL_MASK, 1, out_mix_tlv),
224
225 /* LOUT */
226 SOC_WM899X_OUTPGA_SINGLE_R_TLV("LOUT Volume", WM8991_LEFT_OUTPUT_VOLUME,
227 WM8991_LOUTVOL_SHIFT, WM8991_LOUTVOL_MASK, 0, out_pga_tlv),
228 SOC_SINGLE("LOUT ZC", WM8991_LEFT_OUTPUT_VOLUME, WM8991_LOZC_BIT, 1, 0),
229
230 /* ROUT */
231 SOC_WM899X_OUTPGA_SINGLE_R_TLV("ROUT Volume", WM8991_RIGHT_OUTPUT_VOLUME,
232 WM8991_ROUTVOL_SHIFT, WM8991_ROUTVOL_MASK, 0, out_pga_tlv),
233 SOC_SINGLE("ROUT ZC", WM8991_RIGHT_OUTPUT_VOLUME, WM8991_ROZC_BIT, 1, 0),
234
235 /* LOPGA */
236 SOC_WM899X_OUTPGA_SINGLE_R_TLV("LOPGA Volume", WM8991_LEFT_OPGA_VOLUME,
237 WM8991_LOPGAVOL_SHIFT, WM8991_LOPGAVOL_MASK, 0, out_pga_tlv),
238 SOC_SINGLE("LOPGA ZC Switch", WM8991_LEFT_OPGA_VOLUME,
239 WM8991_LOPGAZC_BIT, 1, 0),
240
241 /* ROPGA */
242 SOC_WM899X_OUTPGA_SINGLE_R_TLV("ROPGA Volume", WM8991_RIGHT_OPGA_VOLUME,
243 WM8991_ROPGAVOL_SHIFT, WM8991_ROPGAVOL_MASK, 0, out_pga_tlv),
244 SOC_SINGLE("ROPGA ZC Switch", WM8991_RIGHT_OPGA_VOLUME,
245 WM8991_ROPGAZC_BIT, 1, 0),
246
247 SOC_SINGLE("LON Mute Switch", WM8991_LINE_OUTPUTS_VOLUME,
248 WM8991_LONMUTE_BIT, 1, 0),
249 SOC_SINGLE("LOP Mute Switch", WM8991_LINE_OUTPUTS_VOLUME,
250 WM8991_LOPMUTE_BIT, 1, 0),
251 SOC_SINGLE("LOP Attenuation Switch", WM8991_LINE_OUTPUTS_VOLUME,
252 WM8991_LOATTN_BIT, 1, 0),
253 SOC_SINGLE("RON Mute Switch", WM8991_LINE_OUTPUTS_VOLUME,
254 WM8991_RONMUTE_BIT, 1, 0),
255 SOC_SINGLE("ROP Mute Switch", WM8991_LINE_OUTPUTS_VOLUME,
256 WM8991_ROPMUTE_BIT, 1, 0),
257 SOC_SINGLE("ROP Attenuation Switch", WM8991_LINE_OUTPUTS_VOLUME,
258 WM8991_ROATTN_BIT, 1, 0),
259
260 SOC_SINGLE("OUT3 Mute Switch", WM8991_OUT3_4_VOLUME,
261 WM8991_OUT3MUTE_BIT, 1, 0),
262 SOC_SINGLE("OUT3 Attenuation Switch", WM8991_OUT3_4_VOLUME,
263 WM8991_OUT3ATTN_BIT, 1, 0),
264
265 SOC_SINGLE("OUT4 Mute Switch", WM8991_OUT3_4_VOLUME,
266 WM8991_OUT4MUTE_BIT, 1, 0),
267 SOC_SINGLE("OUT4 Attenuation Switch", WM8991_OUT3_4_VOLUME,
268 WM8991_OUT4ATTN_BIT, 1, 0),
269
270 SOC_SINGLE("Speaker Mode Switch", WM8991_CLASSD1,
271 WM8991_CDMODE_BIT, 1, 0),
272
273 SOC_SINGLE("Speaker Output Attenuation Volume", WM8991_SPEAKER_VOLUME,
274 WM8991_SPKVOL_SHIFT, WM8991_SPKVOL_MASK, 0),
275 SOC_SINGLE("Speaker DC Boost Volume", WM8991_CLASSD3,
276 WM8991_DCGAIN_SHIFT, WM8991_DCGAIN_MASK, 0),
277 SOC_SINGLE("Speaker AC Boost Volume", WM8991_CLASSD3,
278 WM8991_ACGAIN_SHIFT, WM8991_ACGAIN_MASK, 0),
279
280 SOC_WM899X_OUTPGA_SINGLE_R_TLV("Left DAC Digital Volume",
281 WM8991_LEFT_DAC_DIGITAL_VOLUME,
282 WM8991_DACL_VOL_SHIFT,
283 WM8991_DACL_VOL_MASK,
284 0,
285 out_dac_tlv),
286
287 SOC_WM899X_OUTPGA_SINGLE_R_TLV("Right DAC Digital Volume",
288 WM8991_RIGHT_DAC_DIGITAL_VOLUME,
289 WM8991_DACR_VOL_SHIFT,
290 WM8991_DACR_VOL_MASK,
291 0,
292 out_dac_tlv),
293
294 SOC_ENUM("Left Digital Sidetone", wm8991_left_digital_sidetone_enum),
295 SOC_ENUM("Right Digital Sidetone", wm8991_right_digital_sidetone_enum),
296
297 SOC_SINGLE_TLV("Left Digital Sidetone Volume", WM8991_DIGITAL_SIDE_TONE,
298 WM8991_ADCL_DAC_SVOL_SHIFT, WM8991_ADCL_DAC_SVOL_MASK, 0,
299 out_sidetone_tlv),
300 SOC_SINGLE_TLV("Right Digital Sidetone Volume", WM8991_DIGITAL_SIDE_TONE,
301 WM8991_ADCR_DAC_SVOL_SHIFT, WM8991_ADCR_DAC_SVOL_MASK, 0,
302 out_sidetone_tlv),
303
304 SOC_SINGLE("ADC Digital High Pass Filter Switch", WM8991_ADC_CTRL,
305 WM8991_ADC_HPF_ENA_BIT, 1, 0),
306
307 SOC_ENUM("ADC HPF Mode", wm8991_right_adcmode_enum),
308
309 SOC_WM899X_OUTPGA_SINGLE_R_TLV("Left ADC Digital Volume",
310 WM8991_LEFT_ADC_DIGITAL_VOLUME,
311 WM8991_ADCL_VOL_SHIFT,
312 WM8991_ADCL_VOL_MASK,
313 0,
314 in_adc_tlv),
315
316 SOC_WM899X_OUTPGA_SINGLE_R_TLV("Right ADC Digital Volume",
317 WM8991_RIGHT_ADC_DIGITAL_VOLUME,
318 WM8991_ADCR_VOL_SHIFT,
319 WM8991_ADCR_VOL_MASK,
320 0,
321 in_adc_tlv),
322
323 SOC_WM899X_OUTPGA_SINGLE_R_TLV("LIN12 Volume",
324 WM8991_LEFT_LINE_INPUT_1_2_VOLUME,
325 WM8991_LIN12VOL_SHIFT,
326 WM8991_LIN12VOL_MASK,
327 0,
328 in_pga_tlv),
329
330 SOC_SINGLE("LIN12 ZC Switch", WM8991_LEFT_LINE_INPUT_1_2_VOLUME,
331 WM8991_LI12ZC_BIT, 1, 0),
332
333 SOC_SINGLE("LIN12 Mute Switch", WM8991_LEFT_LINE_INPUT_1_2_VOLUME,
334 WM8991_LI12MUTE_BIT, 1, 0),
335
336 SOC_WM899X_OUTPGA_SINGLE_R_TLV("LIN34 Volume",
337 WM8991_LEFT_LINE_INPUT_3_4_VOLUME,
338 WM8991_LIN34VOL_SHIFT,
339 WM8991_LIN34VOL_MASK,
340 0,
341 in_pga_tlv),
342
343 SOC_SINGLE("LIN34 ZC Switch", WM8991_LEFT_LINE_INPUT_3_4_VOLUME,
344 WM8991_LI34ZC_BIT, 1, 0),
345
346 SOC_SINGLE("LIN34 Mute Switch", WM8991_LEFT_LINE_INPUT_3_4_VOLUME,
347 WM8991_LI34MUTE_BIT, 1, 0),
348
349 SOC_WM899X_OUTPGA_SINGLE_R_TLV("RIN12 Volume",
350 WM8991_RIGHT_LINE_INPUT_1_2_VOLUME,
351 WM8991_RIN12VOL_SHIFT,
352 WM8991_RIN12VOL_MASK,
353 0,
354 in_pga_tlv),
355
356 SOC_SINGLE("RIN12 ZC Switch", WM8991_RIGHT_LINE_INPUT_1_2_VOLUME,
357 WM8991_RI12ZC_BIT, 1, 0),
358
359 SOC_SINGLE("RIN12 Mute Switch", WM8991_RIGHT_LINE_INPUT_1_2_VOLUME,
360 WM8991_RI12MUTE_BIT, 1, 0),
361
362 SOC_WM899X_OUTPGA_SINGLE_R_TLV("RIN34 Volume",
363 WM8991_RIGHT_LINE_INPUT_3_4_VOLUME,
364 WM8991_RIN34VOL_SHIFT,
365 WM8991_RIN34VOL_MASK,
366 0,
367 in_pga_tlv),
368
369 SOC_SINGLE("RIN34 ZC Switch", WM8991_RIGHT_LINE_INPUT_3_4_VOLUME,
370 WM8991_RI34ZC_BIT, 1, 0),
371
372 SOC_SINGLE("RIN34 Mute Switch", WM8991_RIGHT_LINE_INPUT_3_4_VOLUME,
373 WM8991_RI34MUTE_BIT, 1, 0),
374};
375
376/*
377 * _DAPM_ Controls
378 */
379static int inmixer_event(struct snd_soc_dapm_widget *w,
380 struct snd_kcontrol *kcontrol, int event)
381{
382 u16 reg, fakepower;
383
384 reg = snd_soc_read(w->codec, WM8991_POWER_MANAGEMENT_2);
385 fakepower = snd_soc_read(w->codec, WM8991_INTDRIVBITS);
386
387 if (fakepower & ((1 << WM8991_INMIXL_PWR_BIT) |
388 (1 << WM8991_AINLMUX_PWR_BIT)))
389 reg |= WM8991_AINL_ENA;
390 else
391 reg &= ~WM8991_AINL_ENA;
392
393 if (fakepower & ((1 << WM8991_INMIXR_PWR_BIT) |
394 (1 << WM8991_AINRMUX_PWR_BIT)))
395 reg |= WM8991_AINR_ENA;
396 else
397 reg &= ~WM8991_AINL_ENA;
398
399 snd_soc_write(w->codec, WM8991_POWER_MANAGEMENT_2, reg);
400 return 0;
401}
402
403static int outmixer_event(struct snd_soc_dapm_widget *w,
404 struct snd_kcontrol *kcontrol, int event)
405{
406 u32 reg_shift = kcontrol->private_value & 0xfff;
407 int ret = 0;
408 u16 reg;
409
410 switch (reg_shift) {
411 case WM8991_SPEAKER_MIXER | (WM8991_LDSPK_BIT << 8):
412 reg = snd_soc_read(w->codec, WM8991_OUTPUT_MIXER1);
413 if (reg & WM8991_LDLO) {
414 printk(KERN_WARNING
415 "Cannot set as Output Mixer 1 LDLO Set\n");
416 ret = -1;
417 }
418 break;
419
420 case WM8991_SPEAKER_MIXER | (WM8991_RDSPK_BIT << 8):
421 reg = snd_soc_read(w->codec, WM8991_OUTPUT_MIXER2);
422 if (reg & WM8991_RDRO) {
423 printk(KERN_WARNING
424 "Cannot set as Output Mixer 2 RDRO Set\n");
425 ret = -1;
426 }
427 break;
428
429 case WM8991_OUTPUT_MIXER1 | (WM8991_LDLO_BIT << 8):
430 reg = snd_soc_read(w->codec, WM8991_SPEAKER_MIXER);
431 if (reg & WM8991_LDSPK) {
432 printk(KERN_WARNING
433 "Cannot set as Speaker Mixer LDSPK Set\n");
434 ret = -1;
435 }
436 break;
437
438 case WM8991_OUTPUT_MIXER2 | (WM8991_RDRO_BIT << 8):
439 reg = snd_soc_read(w->codec, WM8991_SPEAKER_MIXER);
440 if (reg & WM8991_RDSPK) {
441 printk(KERN_WARNING
442 "Cannot set as Speaker Mixer RDSPK Set\n");
443 ret = -1;
444 }
445 break;
446 }
447
448 return ret;
449}
450
451/* INMIX dB values */
452static const unsigned int in_mix_tlv[] = {
453 TLV_DB_RANGE_HEAD(1),
454 0, 7, TLV_DB_LINEAR_ITEM(-1200, 600),
455};
456
457/* Left In PGA Connections */
458static const struct snd_kcontrol_new wm8991_dapm_lin12_pga_controls[] = {
459 SOC_DAPM_SINGLE("LIN1 Switch", WM8991_INPUT_MIXER2, WM8991_LMN1_BIT, 1, 0),
460 SOC_DAPM_SINGLE("LIN2 Switch", WM8991_INPUT_MIXER2, WM8991_LMP2_BIT, 1, 0),
461};
462
463static const struct snd_kcontrol_new wm8991_dapm_lin34_pga_controls[] = {
464 SOC_DAPM_SINGLE("LIN3 Switch", WM8991_INPUT_MIXER2, WM8991_LMN3_BIT, 1, 0),
465 SOC_DAPM_SINGLE("LIN4 Switch", WM8991_INPUT_MIXER2, WM8991_LMP4_BIT, 1, 0),
466};
467
468/* Right In PGA Connections */
469static const struct snd_kcontrol_new wm8991_dapm_rin12_pga_controls[] = {
470 SOC_DAPM_SINGLE("RIN1 Switch", WM8991_INPUT_MIXER2, WM8991_RMN1_BIT, 1, 0),
471 SOC_DAPM_SINGLE("RIN2 Switch", WM8991_INPUT_MIXER2, WM8991_RMP2_BIT, 1, 0),
472};
473
474static const struct snd_kcontrol_new wm8991_dapm_rin34_pga_controls[] = {
475 SOC_DAPM_SINGLE("RIN3 Switch", WM8991_INPUT_MIXER2, WM8991_RMN3_BIT, 1, 0),
476 SOC_DAPM_SINGLE("RIN4 Switch", WM8991_INPUT_MIXER2, WM8991_RMP4_BIT, 1, 0),
477};
478
479/* INMIXL */
480static const struct snd_kcontrol_new wm8991_dapm_inmixl_controls[] = {
481 SOC_DAPM_SINGLE_TLV("Record Left Volume", WM8991_INPUT_MIXER3,
482 WM8991_LDBVOL_SHIFT, WM8991_LDBVOL_MASK, 0, in_mix_tlv),
483 SOC_DAPM_SINGLE_TLV("LIN2 Volume", WM8991_INPUT_MIXER5, WM8991_LI2BVOL_SHIFT,
484 7, 0, in_mix_tlv),
485 SOC_DAPM_SINGLE("LINPGA12 Switch", WM8991_INPUT_MIXER3, WM8991_L12MNB_BIT,
486 1, 0),
487 SOC_DAPM_SINGLE("LINPGA34 Switch", WM8991_INPUT_MIXER3, WM8991_L34MNB_BIT,
488 1, 0),
489};
490
491/* INMIXR */
492static const struct snd_kcontrol_new wm8991_dapm_inmixr_controls[] = {
493 SOC_DAPM_SINGLE_TLV("Record Right Volume", WM8991_INPUT_MIXER4,
494 WM8991_RDBVOL_SHIFT, WM8991_RDBVOL_MASK, 0, in_mix_tlv),
495 SOC_DAPM_SINGLE_TLV("RIN2 Volume", WM8991_INPUT_MIXER6, WM8991_RI2BVOL_SHIFT,
496 7, 0, in_mix_tlv),
497 SOC_DAPM_SINGLE("RINPGA12 Switch", WM8991_INPUT_MIXER3, WM8991_L12MNB_BIT,
498 1, 0),
499 SOC_DAPM_SINGLE("RINPGA34 Switch", WM8991_INPUT_MIXER3, WM8991_L34MNB_BIT,
500 1, 0),
501};
502
503/* AINLMUX */
504static const char *wm8991_ainlmux[] =
505{"INMIXL Mix", "RXVOICE Mix", "DIFFINL Mix"};
506
507static const struct soc_enum wm8991_ainlmux_enum =
508 SOC_ENUM_SINGLE(WM8991_INPUT_MIXER1, WM8991_AINLMODE_SHIFT,
509 ARRAY_SIZE(wm8991_ainlmux), wm8991_ainlmux);
510
511static const struct snd_kcontrol_new wm8991_dapm_ainlmux_controls =
512 SOC_DAPM_ENUM("Route", wm8991_ainlmux_enum);
513
514/* DIFFINL */
515
516/* AINRMUX */
517static const char *wm8991_ainrmux[] =
518{"INMIXR Mix", "RXVOICE Mix", "DIFFINR Mix"};
519
520static const struct soc_enum wm8991_ainrmux_enum =
521 SOC_ENUM_SINGLE(WM8991_INPUT_MIXER1, WM8991_AINRMODE_SHIFT,
522 ARRAY_SIZE(wm8991_ainrmux), wm8991_ainrmux);
523
524static const struct snd_kcontrol_new wm8991_dapm_ainrmux_controls =
525 SOC_DAPM_ENUM("Route", wm8991_ainrmux_enum);
526
527/* RXVOICE */
528static const struct snd_kcontrol_new wm8991_dapm_rxvoice_controls[] = {
529 SOC_DAPM_SINGLE_TLV("LIN4RXN", WM8991_INPUT_MIXER5, WM8991_LR4BVOL_SHIFT,
530 WM8991_LR4BVOL_MASK, 0, in_mix_tlv),
531 SOC_DAPM_SINGLE_TLV("RIN4RXP", WM8991_INPUT_MIXER6, WM8991_RL4BVOL_SHIFT,
532 WM8991_RL4BVOL_MASK, 0, in_mix_tlv),
533};
534
535/* LOMIX */
536static const struct snd_kcontrol_new wm8991_dapm_lomix_controls[] = {
537 SOC_DAPM_SINGLE("LOMIX Right ADC Bypass Switch", WM8991_OUTPUT_MIXER1,
538 WM8991_LRBLO_BIT, 1, 0),
539 SOC_DAPM_SINGLE("LOMIX Left ADC Bypass Switch", WM8991_OUTPUT_MIXER1,
540 WM8991_LLBLO_BIT, 1, 0),
541 SOC_DAPM_SINGLE("LOMIX RIN3 Bypass Switch", WM8991_OUTPUT_MIXER1,
542 WM8991_LRI3LO_BIT, 1, 0),
543 SOC_DAPM_SINGLE("LOMIX LIN3 Bypass Switch", WM8991_OUTPUT_MIXER1,
544 WM8991_LLI3LO_BIT, 1, 0),
545 SOC_DAPM_SINGLE("LOMIX RIN12 PGA Bypass Switch", WM8991_OUTPUT_MIXER1,
546 WM8991_LR12LO_BIT, 1, 0),
547 SOC_DAPM_SINGLE("LOMIX LIN12 PGA Bypass Switch", WM8991_OUTPUT_MIXER1,
548 WM8991_LL12LO_BIT, 1, 0),
549 SOC_DAPM_SINGLE("LOMIX Left DAC Switch", WM8991_OUTPUT_MIXER1,
550 WM8991_LDLO_BIT, 1, 0),
551};
552
553/* ROMIX */
554static const struct snd_kcontrol_new wm8991_dapm_romix_controls[] = {
555 SOC_DAPM_SINGLE("ROMIX Left ADC Bypass Switch", WM8991_OUTPUT_MIXER2,
556 WM8991_RLBRO_BIT, 1, 0),
557 SOC_DAPM_SINGLE("ROMIX Right ADC Bypass Switch", WM8991_OUTPUT_MIXER2,
558 WM8991_RRBRO_BIT, 1, 0),
559 SOC_DAPM_SINGLE("ROMIX LIN3 Bypass Switch", WM8991_OUTPUT_MIXER2,
560 WM8991_RLI3RO_BIT, 1, 0),
561 SOC_DAPM_SINGLE("ROMIX RIN3 Bypass Switch", WM8991_OUTPUT_MIXER2,
562 WM8991_RRI3RO_BIT, 1, 0),
563 SOC_DAPM_SINGLE("ROMIX LIN12 PGA Bypass Switch", WM8991_OUTPUT_MIXER2,
564 WM8991_RL12RO_BIT, 1, 0),
565 SOC_DAPM_SINGLE("ROMIX RIN12 PGA Bypass Switch", WM8991_OUTPUT_MIXER2,
566 WM8991_RR12RO_BIT, 1, 0),
567 SOC_DAPM_SINGLE("ROMIX Right DAC Switch", WM8991_OUTPUT_MIXER2,
568 WM8991_RDRO_BIT, 1, 0),
569};
570
571/* LONMIX */
572static const struct snd_kcontrol_new wm8991_dapm_lonmix_controls[] = {
573 SOC_DAPM_SINGLE("LONMIX Left Mixer PGA Switch", WM8991_LINE_MIXER1,
574 WM8991_LLOPGALON_BIT, 1, 0),
575 SOC_DAPM_SINGLE("LONMIX Right Mixer PGA Switch", WM8991_LINE_MIXER1,
576 WM8991_LROPGALON_BIT, 1, 0),
577 SOC_DAPM_SINGLE("LONMIX Inverted LOP Switch", WM8991_LINE_MIXER1,
578 WM8991_LOPLON_BIT, 1, 0),
579};
580
581/* LOPMIX */
582static const struct snd_kcontrol_new wm8991_dapm_lopmix_controls[] = {
583 SOC_DAPM_SINGLE("LOPMIX Right Mic Bypass Switch", WM8991_LINE_MIXER1,
584 WM8991_LR12LOP_BIT, 1, 0),
585 SOC_DAPM_SINGLE("LOPMIX Left Mic Bypass Switch", WM8991_LINE_MIXER1,
586 WM8991_LL12LOP_BIT, 1, 0),
587 SOC_DAPM_SINGLE("LOPMIX Left Mixer PGA Switch", WM8991_LINE_MIXER1,
588 WM8991_LLOPGALOP_BIT, 1, 0),
589};
590
591/* RONMIX */
592static const struct snd_kcontrol_new wm8991_dapm_ronmix_controls[] = {
593 SOC_DAPM_SINGLE("RONMIX Right Mixer PGA Switch", WM8991_LINE_MIXER2,
594 WM8991_RROPGARON_BIT, 1, 0),
595 SOC_DAPM_SINGLE("RONMIX Left Mixer PGA Switch", WM8991_LINE_MIXER2,
596 WM8991_RLOPGARON_BIT, 1, 0),
597 SOC_DAPM_SINGLE("RONMIX Inverted ROP Switch", WM8991_LINE_MIXER2,
598 WM8991_ROPRON_BIT, 1, 0),
599};
600
601/* ROPMIX */
602static const struct snd_kcontrol_new wm8991_dapm_ropmix_controls[] = {
603 SOC_DAPM_SINGLE("ROPMIX Left Mic Bypass Switch", WM8991_LINE_MIXER2,
604 WM8991_RL12ROP_BIT, 1, 0),
605 SOC_DAPM_SINGLE("ROPMIX Right Mic Bypass Switch", WM8991_LINE_MIXER2,
606 WM8991_RR12ROP_BIT, 1, 0),
607 SOC_DAPM_SINGLE("ROPMIX Right Mixer PGA Switch", WM8991_LINE_MIXER2,
608 WM8991_RROPGAROP_BIT, 1, 0),
609};
610
611/* OUT3MIX */
612static const struct snd_kcontrol_new wm8991_dapm_out3mix_controls[] = {
613 SOC_DAPM_SINGLE("OUT3MIX LIN4RXN Bypass Switch", WM8991_OUT3_4_MIXER,
614 WM8991_LI4O3_BIT, 1, 0),
615 SOC_DAPM_SINGLE("OUT3MIX Left Out PGA Switch", WM8991_OUT3_4_MIXER,
616 WM8991_LPGAO3_BIT, 1, 0),
617};
618
619/* OUT4MIX */
620static const struct snd_kcontrol_new wm8991_dapm_out4mix_controls[] = {
621 SOC_DAPM_SINGLE("OUT4MIX Right Out PGA Switch", WM8991_OUT3_4_MIXER,
622 WM8991_RPGAO4_BIT, 1, 0),
623 SOC_DAPM_SINGLE("OUT4MIX RIN4RXP Bypass Switch", WM8991_OUT3_4_MIXER,
624 WM8991_RI4O4_BIT, 1, 0),
625};
626
627/* SPKMIX */
628static const struct snd_kcontrol_new wm8991_dapm_spkmix_controls[] = {
629 SOC_DAPM_SINGLE("SPKMIX LIN2 Bypass Switch", WM8991_SPEAKER_MIXER,
630 WM8991_LI2SPK_BIT, 1, 0),
631 SOC_DAPM_SINGLE("SPKMIX LADC Bypass Switch", WM8991_SPEAKER_MIXER,
632 WM8991_LB2SPK_BIT, 1, 0),
633 SOC_DAPM_SINGLE("SPKMIX Left Mixer PGA Switch", WM8991_SPEAKER_MIXER,
634 WM8991_LOPGASPK_BIT, 1, 0),
635 SOC_DAPM_SINGLE("SPKMIX Left DAC Switch", WM8991_SPEAKER_MIXER,
636 WM8991_LDSPK_BIT, 1, 0),
637 SOC_DAPM_SINGLE("SPKMIX Right DAC Switch", WM8991_SPEAKER_MIXER,
638 WM8991_RDSPK_BIT, 1, 0),
639 SOC_DAPM_SINGLE("SPKMIX Right Mixer PGA Switch", WM8991_SPEAKER_MIXER,
640 WM8991_ROPGASPK_BIT, 1, 0),
641 SOC_DAPM_SINGLE("SPKMIX RADC Bypass Switch", WM8991_SPEAKER_MIXER,
642 WM8991_RL12ROP_BIT, 1, 0),
643 SOC_DAPM_SINGLE("SPKMIX RIN2 Bypass Switch", WM8991_SPEAKER_MIXER,
644 WM8991_RI2SPK_BIT, 1, 0),
645};
646
647static const struct snd_soc_dapm_widget wm8991_dapm_widgets[] = {
648 /* Input Side */
649 /* Input Lines */
650 SND_SOC_DAPM_INPUT("LIN1"),
651 SND_SOC_DAPM_INPUT("LIN2"),
652 SND_SOC_DAPM_INPUT("LIN3"),
653 SND_SOC_DAPM_INPUT("LIN4RXN"),
654 SND_SOC_DAPM_INPUT("RIN3"),
655 SND_SOC_DAPM_INPUT("RIN4RXP"),
656 SND_SOC_DAPM_INPUT("RIN1"),
657 SND_SOC_DAPM_INPUT("RIN2"),
658 SND_SOC_DAPM_INPUT("Internal ADC Source"),
659
660 /* DACs */
661 SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8991_POWER_MANAGEMENT_2,
662 WM8991_ADCL_ENA_BIT, 0),
663 SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8991_POWER_MANAGEMENT_2,
664 WM8991_ADCR_ENA_BIT, 0),
665
666 /* Input PGAs */
667 SND_SOC_DAPM_MIXER("LIN12 PGA", WM8991_POWER_MANAGEMENT_2, WM8991_LIN12_ENA_BIT,
668 0, &wm8991_dapm_lin12_pga_controls[0],
669 ARRAY_SIZE(wm8991_dapm_lin12_pga_controls)),
670 SND_SOC_DAPM_MIXER("LIN34 PGA", WM8991_POWER_MANAGEMENT_2, WM8991_LIN34_ENA_BIT,
671 0, &wm8991_dapm_lin34_pga_controls[0],
672 ARRAY_SIZE(wm8991_dapm_lin34_pga_controls)),
673 SND_SOC_DAPM_MIXER("RIN12 PGA", WM8991_POWER_MANAGEMENT_2, WM8991_RIN12_ENA_BIT,
674 0, &wm8991_dapm_rin12_pga_controls[0],
675 ARRAY_SIZE(wm8991_dapm_rin12_pga_controls)),
676 SND_SOC_DAPM_MIXER("RIN34 PGA", WM8991_POWER_MANAGEMENT_2, WM8991_RIN34_ENA_BIT,
677 0, &wm8991_dapm_rin34_pga_controls[0],
678 ARRAY_SIZE(wm8991_dapm_rin34_pga_controls)),
679
680 /* INMIXL */
681 SND_SOC_DAPM_MIXER_E("INMIXL", WM8991_INTDRIVBITS, WM8991_INMIXL_PWR_BIT, 0,
682 &wm8991_dapm_inmixl_controls[0],
683 ARRAY_SIZE(wm8991_dapm_inmixl_controls),
684 inmixer_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
685
686 /* AINLMUX */
687 SND_SOC_DAPM_MUX_E("AINLMUX", WM8991_INTDRIVBITS, WM8991_AINLMUX_PWR_BIT, 0,
688 &wm8991_dapm_ainlmux_controls, inmixer_event,
689 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
690
691 /* INMIXR */
692 SND_SOC_DAPM_MIXER_E("INMIXR", WM8991_INTDRIVBITS, WM8991_INMIXR_PWR_BIT, 0,
693 &wm8991_dapm_inmixr_controls[0],
694 ARRAY_SIZE(wm8991_dapm_inmixr_controls),
695 inmixer_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
696
697 /* AINRMUX */
698 SND_SOC_DAPM_MUX_E("AINRMUX", WM8991_INTDRIVBITS, WM8991_AINRMUX_PWR_BIT, 0,
699 &wm8991_dapm_ainrmux_controls, inmixer_event,
700 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
701
702 /* Output Side */
703 /* DACs */
704 SND_SOC_DAPM_DAC("Left DAC", "Left Playback", WM8991_POWER_MANAGEMENT_3,
705 WM8991_DACL_ENA_BIT, 0),
706 SND_SOC_DAPM_DAC("Right DAC", "Right Playback", WM8991_POWER_MANAGEMENT_3,
707 WM8991_DACR_ENA_BIT, 0),
708
709 /* LOMIX */
710 SND_SOC_DAPM_MIXER_E("LOMIX", WM8991_POWER_MANAGEMENT_3, WM8991_LOMIX_ENA_BIT,
711 0, &wm8991_dapm_lomix_controls[0],
712 ARRAY_SIZE(wm8991_dapm_lomix_controls),
713 outmixer_event, SND_SOC_DAPM_PRE_REG),
714
715 /* LONMIX */
716 SND_SOC_DAPM_MIXER("LONMIX", WM8991_POWER_MANAGEMENT_3, WM8991_LON_ENA_BIT, 0,
717 &wm8991_dapm_lonmix_controls[0],
718 ARRAY_SIZE(wm8991_dapm_lonmix_controls)),
719
720 /* LOPMIX */
721 SND_SOC_DAPM_MIXER("LOPMIX", WM8991_POWER_MANAGEMENT_3, WM8991_LOP_ENA_BIT, 0,
722 &wm8991_dapm_lopmix_controls[0],
723 ARRAY_SIZE(wm8991_dapm_lopmix_controls)),
724
725 /* OUT3MIX */
726 SND_SOC_DAPM_MIXER("OUT3MIX", WM8991_POWER_MANAGEMENT_1, WM8991_OUT3_ENA_BIT, 0,
727 &wm8991_dapm_out3mix_controls[0],
728 ARRAY_SIZE(wm8991_dapm_out3mix_controls)),
729
730 /* SPKMIX */
731 SND_SOC_DAPM_MIXER_E("SPKMIX", WM8991_POWER_MANAGEMENT_1, WM8991_SPK_ENA_BIT, 0,
732 &wm8991_dapm_spkmix_controls[0],
733 ARRAY_SIZE(wm8991_dapm_spkmix_controls), outmixer_event,
734 SND_SOC_DAPM_PRE_REG),
735
736 /* OUT4MIX */
737 SND_SOC_DAPM_MIXER("OUT4MIX", WM8991_POWER_MANAGEMENT_1, WM8991_OUT4_ENA_BIT, 0,
738 &wm8991_dapm_out4mix_controls[0],
739 ARRAY_SIZE(wm8991_dapm_out4mix_controls)),
740
741 /* ROPMIX */
742 SND_SOC_DAPM_MIXER("ROPMIX", WM8991_POWER_MANAGEMENT_3, WM8991_ROP_ENA_BIT, 0,
743 &wm8991_dapm_ropmix_controls[0],
744 ARRAY_SIZE(wm8991_dapm_ropmix_controls)),
745
746 /* RONMIX */
747 SND_SOC_DAPM_MIXER("RONMIX", WM8991_POWER_MANAGEMENT_3, WM8991_RON_ENA_BIT, 0,
748 &wm8991_dapm_ronmix_controls[0],
749 ARRAY_SIZE(wm8991_dapm_ronmix_controls)),
750
751 /* ROMIX */
752 SND_SOC_DAPM_MIXER_E("ROMIX", WM8991_POWER_MANAGEMENT_3, WM8991_ROMIX_ENA_BIT,
753 0, &wm8991_dapm_romix_controls[0],
754 ARRAY_SIZE(wm8991_dapm_romix_controls),
755 outmixer_event, SND_SOC_DAPM_PRE_REG),
756
757 /* LOUT PGA */
758 SND_SOC_DAPM_PGA("LOUT PGA", WM8991_POWER_MANAGEMENT_1, WM8991_LOUT_ENA_BIT, 0,
759 NULL, 0),
760
761 /* ROUT PGA */
762 SND_SOC_DAPM_PGA("ROUT PGA", WM8991_POWER_MANAGEMENT_1, WM8991_ROUT_ENA_BIT, 0,
763 NULL, 0),
764
765 /* LOPGA */
766 SND_SOC_DAPM_PGA("LOPGA", WM8991_POWER_MANAGEMENT_3, WM8991_LOPGA_ENA_BIT, 0,
767 NULL, 0),
768
769 /* ROPGA */
770 SND_SOC_DAPM_PGA("ROPGA", WM8991_POWER_MANAGEMENT_3, WM8991_ROPGA_ENA_BIT, 0,
771 NULL, 0),
772
773 /* MICBIAS */
774 SND_SOC_DAPM_MICBIAS("MICBIAS", WM8991_POWER_MANAGEMENT_1,
775 WM8991_MICBIAS_ENA_BIT, 0),
776
777 SND_SOC_DAPM_OUTPUT("LON"),
778 SND_SOC_DAPM_OUTPUT("LOP"),
779 SND_SOC_DAPM_OUTPUT("OUT3"),
780 SND_SOC_DAPM_OUTPUT("LOUT"),
781 SND_SOC_DAPM_OUTPUT("SPKN"),
782 SND_SOC_DAPM_OUTPUT("SPKP"),
783 SND_SOC_DAPM_OUTPUT("ROUT"),
784 SND_SOC_DAPM_OUTPUT("OUT4"),
785 SND_SOC_DAPM_OUTPUT("ROP"),
786 SND_SOC_DAPM_OUTPUT("RON"),
787 SND_SOC_DAPM_OUTPUT("OUT"),
788
789 SND_SOC_DAPM_OUTPUT("Internal DAC Sink"),
790};
791
792static const struct snd_soc_dapm_route audio_map[] = {
793 /* Make DACs turn on when playing even if not mixed into any outputs */
794 {"Internal DAC Sink", NULL, "Left DAC"},
795 {"Internal DAC Sink", NULL, "Right DAC"},
796
797 /* Make ADCs turn on when recording even if not mixed from any inputs */
798 {"Left ADC", NULL, "Internal ADC Source"},
799 {"Right ADC", NULL, "Internal ADC Source"},
800
801 /* Input Side */
802 /* LIN12 PGA */
803 {"LIN12 PGA", "LIN1 Switch", "LIN1"},
804 {"LIN12 PGA", "LIN2 Switch", "LIN2"},
805 /* LIN34 PGA */
806 {"LIN34 PGA", "LIN3 Switch", "LIN3"},
807 {"LIN34 PGA", "LIN4 Switch", "LIN4RXN"},
808 /* INMIXL */
809 {"INMIXL", "Record Left Volume", "LOMIX"},
810 {"INMIXL", "LIN2 Volume", "LIN2"},
811 {"INMIXL", "LINPGA12 Switch", "LIN12 PGA"},
812 {"INMIXL", "LINPGA34 Switch", "LIN34 PGA"},
813 /* AINLMUX */
814 {"AINLMUX", "INMIXL Mix", "INMIXL"},
815 {"AINLMUX", "DIFFINL Mix", "LIN12 PGA"},
816 {"AINLMUX", "DIFFINL Mix", "LIN34 PGA"},
817 {"AINLMUX", "RXVOICE Mix", "LIN4RXN"},
818 {"AINLMUX", "RXVOICE Mix", "RIN4RXP"},
819 /* ADC */
820 {"Left ADC", NULL, "AINLMUX"},
821
822 /* RIN12 PGA */
823 {"RIN12 PGA", "RIN1 Switch", "RIN1"},
824 {"RIN12 PGA", "RIN2 Switch", "RIN2"},
825 /* RIN34 PGA */
826 {"RIN34 PGA", "RIN3 Switch", "RIN3"},
827 {"RIN34 PGA", "RIN4 Switch", "RIN4RXP"},
828 /* INMIXL */
829 {"INMIXR", "Record Right Volume", "ROMIX"},
830 {"INMIXR", "RIN2 Volume", "RIN2"},
831 {"INMIXR", "RINPGA12 Switch", "RIN12 PGA"},
832 {"INMIXR", "RINPGA34 Switch", "RIN34 PGA"},
833 /* AINRMUX */
834 {"AINRMUX", "INMIXR Mix", "INMIXR"},
835 {"AINRMUX", "DIFFINR Mix", "RIN12 PGA"},
836 {"AINRMUX", "DIFFINR Mix", "RIN34 PGA"},
837 {"AINRMUX", "RXVOICE Mix", "LIN4RXN"},
838 {"AINRMUX", "RXVOICE Mix", "RIN4RXP"},
839 /* ADC */
840 {"Right ADC", NULL, "AINRMUX"},
841
842 /* LOMIX */
843 {"LOMIX", "LOMIX RIN3 Bypass Switch", "RIN3"},
844 {"LOMIX", "LOMIX LIN3 Bypass Switch", "LIN3"},
845 {"LOMIX", "LOMIX LIN12 PGA Bypass Switch", "LIN12 PGA"},
846 {"LOMIX", "LOMIX RIN12 PGA Bypass Switch", "RIN12 PGA"},
847 {"LOMIX", "LOMIX Right ADC Bypass Switch", "AINRMUX"},
848 {"LOMIX", "LOMIX Left ADC Bypass Switch", "AINLMUX"},
849 {"LOMIX", "LOMIX Left DAC Switch", "Left DAC"},
850
851 /* ROMIX */
852 {"ROMIX", "ROMIX RIN3 Bypass Switch", "RIN3"},
853 {"ROMIX", "ROMIX LIN3 Bypass Switch", "LIN3"},
854 {"ROMIX", "ROMIX LIN12 PGA Bypass Switch", "LIN12 PGA"},
855 {"ROMIX", "ROMIX RIN12 PGA Bypass Switch", "RIN12 PGA"},
856 {"ROMIX", "ROMIX Right ADC Bypass Switch", "AINRMUX"},
857 {"ROMIX", "ROMIX Left ADC Bypass Switch", "AINLMUX"},
858 {"ROMIX", "ROMIX Right DAC Switch", "Right DAC"},
859
860 /* SPKMIX */
861 {"SPKMIX", "SPKMIX LIN2 Bypass Switch", "LIN2"},
862 {"SPKMIX", "SPKMIX RIN2 Bypass Switch", "RIN2"},
863 {"SPKMIX", "SPKMIX LADC Bypass Switch", "AINLMUX"},
864 {"SPKMIX", "SPKMIX RADC Bypass Switch", "AINRMUX"},
865 {"SPKMIX", "SPKMIX Left Mixer PGA Switch", "LOPGA"},
866 {"SPKMIX", "SPKMIX Right Mixer PGA Switch", "ROPGA"},
867 {"SPKMIX", "SPKMIX Right DAC Switch", "Right DAC"},
868 {"SPKMIX", "SPKMIX Left DAC Switch", "Right DAC"},
869
870 /* LONMIX */
871 {"LONMIX", "LONMIX Left Mixer PGA Switch", "LOPGA"},
872 {"LONMIX", "LONMIX Right Mixer PGA Switch", "ROPGA"},
873 {"LONMIX", "LONMIX Inverted LOP Switch", "LOPMIX"},
874
875 /* LOPMIX */
876 {"LOPMIX", "LOPMIX Right Mic Bypass Switch", "RIN12 PGA"},
877 {"LOPMIX", "LOPMIX Left Mic Bypass Switch", "LIN12 PGA"},
878 {"LOPMIX", "LOPMIX Left Mixer PGA Switch", "LOPGA"},
879
880 /* OUT3MIX */
881 {"OUT3MIX", "OUT3MIX LIN4RXN Bypass Switch", "LIN4RXN"},
882 {"OUT3MIX", "OUT3MIX Left Out PGA Switch", "LOPGA"},
883
884 /* OUT4MIX */
885 {"OUT4MIX", "OUT4MIX Right Out PGA Switch", "ROPGA"},
886 {"OUT4MIX", "OUT4MIX RIN4RXP Bypass Switch", "RIN4RXP"},
887
888 /* RONMIX */
889 {"RONMIX", "RONMIX Right Mixer PGA Switch", "ROPGA"},
890 {"RONMIX", "RONMIX Left Mixer PGA Switch", "LOPGA"},
891 {"RONMIX", "RONMIX Inverted ROP Switch", "ROPMIX"},
892
893 /* ROPMIX */
894 {"ROPMIX", "ROPMIX Left Mic Bypass Switch", "LIN12 PGA"},
895 {"ROPMIX", "ROPMIX Right Mic Bypass Switch", "RIN12 PGA"},
896 {"ROPMIX", "ROPMIX Right Mixer PGA Switch", "ROPGA"},
897
898 /* Out Mixer PGAs */
899 {"LOPGA", NULL, "LOMIX"},
900 {"ROPGA", NULL, "ROMIX"},
901
902 {"LOUT PGA", NULL, "LOMIX"},
903 {"ROUT PGA", NULL, "ROMIX"},
904
905 /* Output Pins */
906 {"LON", NULL, "LONMIX"},
907 {"LOP", NULL, "LOPMIX"},
908 {"OUT", NULL, "OUT3MIX"},
909 {"LOUT", NULL, "LOUT PGA"},
910 {"SPKN", NULL, "SPKMIX"},
911 {"ROUT", NULL, "ROUT PGA"},
912 {"OUT4", NULL, "OUT4MIX"},
913 {"ROP", NULL, "ROPMIX"},
914 {"RON", NULL, "RONMIX"},
915};
916
917/* PLL divisors */
918struct _pll_div {
919 u32 div2;
920 u32 n;
921 u32 k;
922};
923
924/* The size in bits of the pll divide multiplied by 10
925 * to allow rounding later */
926#define FIXED_PLL_SIZE ((1 << 16) * 10)
927
928static void pll_factors(struct _pll_div *pll_div, unsigned int target,
929 unsigned int source)
930{
931 u64 Kpart;
932 unsigned int K, Ndiv, Nmod;
933
934
935 Ndiv = target / source;
936 if (Ndiv < 6) {
937 source >>= 1;
938 pll_div->div2 = 1;
939 Ndiv = target / source;
940 } else
941 pll_div->div2 = 0;
942
943 if ((Ndiv < 6) || (Ndiv > 12))
944 printk(KERN_WARNING
945 "WM8991 N value outwith recommended range! N = %d\n", Ndiv);
946
947 pll_div->n = Ndiv;
948 Nmod = target % source;
949 Kpart = FIXED_PLL_SIZE * (long long)Nmod;
950
951 do_div(Kpart, source);
952
953 K = Kpart & 0xFFFFFFFF;
954
955 /* Check if we need to round */
956 if ((K % 10) >= 5)
957 K += 5;
958
959 /* Move down to proper range now rounding is done */
960 K /= 10;
961
962 pll_div->k = K;
963}
964
965static int wm8991_set_dai_pll(struct snd_soc_dai *codec_dai,
966 int pll_id, int src, unsigned int freq_in, unsigned int freq_out)
967{
968 u16 reg;
969 struct snd_soc_codec *codec = codec_dai->codec;
970 struct _pll_div pll_div;
971
972 if (freq_in && freq_out) {
973 pll_factors(&pll_div, freq_out * 4, freq_in);
974
975 /* Turn on PLL */
976 reg = snd_soc_read(codec, WM8991_POWER_MANAGEMENT_2);
977 reg |= WM8991_PLL_ENA;
978 snd_soc_write(codec, WM8991_POWER_MANAGEMENT_2, reg);
979
980 /* sysclk comes from PLL */
981 reg = snd_soc_read(codec, WM8991_CLOCKING_2);
982 snd_soc_write(codec, WM8991_CLOCKING_2, reg | WM8991_SYSCLK_SRC);
983
984 /* set up N , fractional mode and pre-divisor if neccessary */
985 snd_soc_write(codec, WM8991_PLL1, pll_div.n | WM8991_SDM |
986 (pll_div.div2 ? WM8991_PRESCALE : 0));
987 snd_soc_write(codec, WM8991_PLL2, (u8)(pll_div.k>>8));
988 snd_soc_write(codec, WM8991_PLL3, (u8)(pll_div.k & 0xFF));
989 } else {
990 /* Turn on PLL */
991 reg = snd_soc_read(codec, WM8991_POWER_MANAGEMENT_2);
992 reg &= ~WM8991_PLL_ENA;
993 snd_soc_write(codec, WM8991_POWER_MANAGEMENT_2, reg);
994 }
995 return 0;
996}
997
998/*
999 * Set's ADC and Voice DAC format.
1000 */
1001static int wm8991_set_dai_fmt(struct snd_soc_dai *codec_dai,
1002 unsigned int fmt)
1003{
1004 struct snd_soc_codec *codec = codec_dai->codec;
1005 u16 audio1, audio3;
1006
1007 audio1 = snd_soc_read(codec, WM8991_AUDIO_INTERFACE_1);
1008 audio3 = snd_soc_read(codec, WM8991_AUDIO_INTERFACE_3);
1009
1010 /* set master/slave audio interface */
1011 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1012 case SND_SOC_DAIFMT_CBS_CFS:
1013 audio3 &= ~WM8991_AIF_MSTR1;
1014 break;
1015 case SND_SOC_DAIFMT_CBM_CFM:
1016 audio3 |= WM8991_AIF_MSTR1;
1017 break;
1018 default:
1019 return -EINVAL;
1020 }
1021
1022 audio1 &= ~WM8991_AIF_FMT_MASK;
1023
1024 /* interface format */
1025 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1026 case SND_SOC_DAIFMT_I2S:
1027 audio1 |= WM8991_AIF_TMF_I2S;
1028 audio1 &= ~WM8991_AIF_LRCLK_INV;
1029 break;
1030 case SND_SOC_DAIFMT_RIGHT_J:
1031 audio1 |= WM8991_AIF_TMF_RIGHTJ;
1032 audio1 &= ~WM8991_AIF_LRCLK_INV;
1033 break;
1034 case SND_SOC_DAIFMT_LEFT_J:
1035 audio1 |= WM8991_AIF_TMF_LEFTJ;
1036 audio1 &= ~WM8991_AIF_LRCLK_INV;
1037 break;
1038 case SND_SOC_DAIFMT_DSP_A:
1039 audio1 |= WM8991_AIF_TMF_DSP;
1040 audio1 &= ~WM8991_AIF_LRCLK_INV;
1041 break;
1042 case SND_SOC_DAIFMT_DSP_B:
1043 audio1 |= WM8991_AIF_TMF_DSP | WM8991_AIF_LRCLK_INV;
1044 break;
1045 default:
1046 return -EINVAL;
1047 }
1048
1049 snd_soc_write(codec, WM8991_AUDIO_INTERFACE_1, audio1);
1050 snd_soc_write(codec, WM8991_AUDIO_INTERFACE_3, audio3);
1051 return 0;
1052}
1053
1054static int wm8991_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
1055 int div_id, int div)
1056{
1057 struct snd_soc_codec *codec = codec_dai->codec;
1058 u16 reg;
1059
1060 switch (div_id) {
1061 case WM8991_MCLK_DIV:
1062 reg = snd_soc_read(codec, WM8991_CLOCKING_2) &
1063 ~WM8991_MCLK_DIV_MASK;
1064 snd_soc_write(codec, WM8991_CLOCKING_2, reg | div);
1065 break;
1066 case WM8991_DACCLK_DIV:
1067 reg = snd_soc_read(codec, WM8991_CLOCKING_2) &
1068 ~WM8991_DAC_CLKDIV_MASK;
1069 snd_soc_write(codec, WM8991_CLOCKING_2, reg | div);
1070 break;
1071 case WM8991_ADCCLK_DIV:
1072 reg = snd_soc_read(codec, WM8991_CLOCKING_2) &
1073 ~WM8991_ADC_CLKDIV_MASK;
1074 snd_soc_write(codec, WM8991_CLOCKING_2, reg | div);
1075 break;
1076 case WM8991_BCLK_DIV:
1077 reg = snd_soc_read(codec, WM8991_CLOCKING_1) &
1078 ~WM8991_BCLK_DIV_MASK;
1079 snd_soc_write(codec, WM8991_CLOCKING_1, reg | div);
1080 break;
1081 default:
1082 return -EINVAL;
1083 }
1084
1085 return 0;
1086}
1087
1088/*
1089 * Set PCM DAI bit size and sample rate.
1090 */
1091static int wm8991_hw_params(struct snd_pcm_substream *substream,
1092 struct snd_pcm_hw_params *params,
1093 struct snd_soc_dai *dai)
1094{
1095 struct snd_soc_codec *codec = dai->codec;
1096 u16 audio1 = snd_soc_read(codec, WM8991_AUDIO_INTERFACE_1);
1097
1098 audio1 &= ~WM8991_AIF_WL_MASK;
1099 /* bit size */
1100 switch (params_format(params)) {
1101 case SNDRV_PCM_FORMAT_S16_LE:
1102 break;
1103 case SNDRV_PCM_FORMAT_S20_3LE:
1104 audio1 |= WM8991_AIF_WL_20BITS;
1105 break;
1106 case SNDRV_PCM_FORMAT_S24_LE:
1107 audio1 |= WM8991_AIF_WL_24BITS;
1108 break;
1109 case SNDRV_PCM_FORMAT_S32_LE:
1110 audio1 |= WM8991_AIF_WL_32BITS;
1111 break;
1112 }
1113
1114 snd_soc_write(codec, WM8991_AUDIO_INTERFACE_1, audio1);
1115 return 0;
1116}
1117
1118static int wm8991_mute(struct snd_soc_dai *dai, int mute)
1119{
1120 struct snd_soc_codec *codec = dai->codec;
1121 u16 val;
1122
1123 val = snd_soc_read(codec, WM8991_DAC_CTRL) & ~WM8991_DAC_MUTE;
1124 if (mute)
1125 snd_soc_write(codec, WM8991_DAC_CTRL, val | WM8991_DAC_MUTE);
1126 else
1127 snd_soc_write(codec, WM8991_DAC_CTRL, val);
1128 return 0;
1129}
1130
1131static int wm8991_set_bias_level(struct snd_soc_codec *codec,
1132 enum snd_soc_bias_level level)
1133{
1134 u16 val;
1135
1136 switch (level) {
1137 case SND_SOC_BIAS_ON:
1138 break;
1139
1140 case SND_SOC_BIAS_PREPARE:
1141 /* VMID=2*50k */
1142 val = snd_soc_read(codec, WM8991_POWER_MANAGEMENT_1) &
1143 ~WM8991_VMID_MODE_MASK;
1144 snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, val | 0x2);
1145 break;
1146
1147 case SND_SOC_BIAS_STANDBY:
1148 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1149 snd_soc_cache_sync(codec);
1150 /* Enable all output discharge bits */
1151 snd_soc_write(codec, WM8991_ANTIPOP1, WM8991_DIS_LLINE |
1152 WM8991_DIS_RLINE | WM8991_DIS_OUT3 |
1153 WM8991_DIS_OUT4 | WM8991_DIS_LOUT |
1154 WM8991_DIS_ROUT);
1155
1156 /* Enable POBCTRL, SOFT_ST, VMIDTOG and BUFDCOPEN */
1157 snd_soc_write(codec, WM8991_ANTIPOP2, WM8991_SOFTST |
1158 WM8991_BUFDCOPEN | WM8991_POBCTRL |
1159 WM8991_VMIDTOG);
1160
1161 /* Delay to allow output caps to discharge */
1162 msleep(300);
1163
1164 /* Disable VMIDTOG */
1165 snd_soc_write(codec, WM8991_ANTIPOP2, WM8991_SOFTST |
1166 WM8991_BUFDCOPEN | WM8991_POBCTRL);
1167
1168 /* disable all output discharge bits */
1169 snd_soc_write(codec, WM8991_ANTIPOP1, 0);
1170
1171 /* Enable outputs */
1172 snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, 0x1b00);
1173
1174 msleep(50);
1175
1176 /* Enable VMID at 2x50k */
1177 snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, 0x1f02);
1178
1179 msleep(100);
1180
1181 /* Enable VREF */
1182 snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, 0x1f03);
1183
1184 msleep(600);
1185
1186 /* Enable BUFIOEN */
1187 snd_soc_write(codec, WM8991_ANTIPOP2, WM8991_SOFTST |
1188 WM8991_BUFDCOPEN | WM8991_POBCTRL |
1189 WM8991_BUFIOEN);
1190
1191 /* Disable outputs */
1192 snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, 0x3);
1193
1194 /* disable POBCTRL, SOFT_ST and BUFDCOPEN */
1195 snd_soc_write(codec, WM8991_ANTIPOP2, WM8991_BUFIOEN);
1196 }
1197
1198 /* VMID=2*250k */
1199 val = snd_soc_read(codec, WM8991_POWER_MANAGEMENT_1) &
1200 ~WM8991_VMID_MODE_MASK;
1201 snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, val | 0x4);
1202 break;
1203
1204 case SND_SOC_BIAS_OFF:
1205 /* Enable POBCTRL and SOFT_ST */
1206 snd_soc_write(codec, WM8991_ANTIPOP2, WM8991_SOFTST |
1207 WM8991_POBCTRL | WM8991_BUFIOEN);
1208
1209 /* Enable POBCTRL, SOFT_ST and BUFDCOPEN */
1210 snd_soc_write(codec, WM8991_ANTIPOP2, WM8991_SOFTST |
1211 WM8991_BUFDCOPEN | WM8991_POBCTRL |
1212 WM8991_BUFIOEN);
1213
1214 /* mute DAC */
1215 val = snd_soc_read(codec, WM8991_DAC_CTRL);
1216 snd_soc_write(codec, WM8991_DAC_CTRL, val | WM8991_DAC_MUTE);
1217
1218 /* Enable any disabled outputs */
1219 snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, 0x1f03);
1220
1221 /* Disable VMID */
1222 snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, 0x1f01);
1223
1224 msleep(300);
1225
1226 /* Enable all output discharge bits */
1227 snd_soc_write(codec, WM8991_ANTIPOP1, WM8991_DIS_LLINE |
1228 WM8991_DIS_RLINE | WM8991_DIS_OUT3 |
1229 WM8991_DIS_OUT4 | WM8991_DIS_LOUT |
1230 WM8991_DIS_ROUT);
1231
1232 /* Disable VREF */
1233 snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, 0x0);
1234
1235 /* disable POBCTRL, SOFT_ST and BUFDCOPEN */
1236 snd_soc_write(codec, WM8991_ANTIPOP2, 0x0);
1237 codec->cache_sync = 1;
1238 break;
1239 }
1240
1241 codec->dapm.bias_level = level;
1242 return 0;
1243}
1244
1245static int wm8991_suspend(struct snd_soc_codec *codec, pm_message_t state)
1246{
1247 wm8991_set_bias_level(codec, SND_SOC_BIAS_OFF);
1248 return 0;
1249}
1250
1251static int wm8991_resume(struct snd_soc_codec *codec)
1252{
1253 wm8991_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1254 return 0;
1255}
1256
1257/* power down chip */
1258static int wm8991_remove(struct snd_soc_codec *codec)
1259{
1260 wm8991_set_bias_level(codec, SND_SOC_BIAS_OFF);
1261 return 0;
1262}
1263
1264static int wm8991_probe(struct snd_soc_codec *codec)
1265{
1266 struct wm8991_priv *wm8991;
1267 int ret;
1268 unsigned int reg;
1269
1270 wm8991 = snd_soc_codec_get_drvdata(codec);
1271
1272 ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm8991->control_type);
1273 if (ret < 0) {
1274 dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret);
1275 return ret;
1276 }
1277
1278 ret = wm8991_reset(codec);
1279 if (ret < 0) {
1280 dev_err(codec->dev, "Failed to issue reset\n");
1281 return ret;
1282 }
1283
1284 wm8991_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1285
1286 reg = snd_soc_read(codec, WM8991_AUDIO_INTERFACE_4);
1287 snd_soc_write(codec, WM8991_AUDIO_INTERFACE_4, reg | WM8991_ALRCGPIO1);
1288
1289 reg = snd_soc_read(codec, WM8991_GPIO1_GPIO2) &
1290 ~WM8991_GPIO1_SEL_MASK;
1291 snd_soc_write(codec, WM8991_GPIO1_GPIO2, reg | 1);
1292
1293 reg = snd_soc_read(codec, WM8991_POWER_MANAGEMENT_1);
1294 snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, reg | WM8991_VREF_ENA|
1295 WM8991_VMID_MODE_MASK);
1296
1297 reg = snd_soc_read(codec, WM8991_POWER_MANAGEMENT_2);
1298 snd_soc_write(codec, WM8991_POWER_MANAGEMENT_2, reg | WM8991_OPCLK_ENA);
1299
1300 snd_soc_write(codec, WM8991_DAC_CTRL, 0);
1301 snd_soc_write(codec, WM8991_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8));
1302 snd_soc_write(codec, WM8991_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8));
1303
1304 snd_soc_add_controls(codec, wm8991_snd_controls,
1305 ARRAY_SIZE(wm8991_snd_controls));
1306
1307 snd_soc_dapm_new_controls(&codec->dapm, wm8991_dapm_widgets,
1308 ARRAY_SIZE(wm8991_dapm_widgets));
1309 snd_soc_dapm_add_routes(&codec->dapm, audio_map,
1310 ARRAY_SIZE(audio_map));
1311 return 0;
1312}
1313
1314#define WM8991_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
1315 SNDRV_PCM_FMTBIT_S24_LE)
1316
1317static struct snd_soc_dai_ops wm8991_ops = {
1318 .hw_params = wm8991_hw_params,
1319 .digital_mute = wm8991_mute,
1320 .set_fmt = wm8991_set_dai_fmt,
1321 .set_clkdiv = wm8991_set_dai_clkdiv,
1322 .set_pll = wm8991_set_dai_pll
1323};
1324
1325/*
1326 * The WM8991 supports 2 different and mutually exclusive DAI
1327 * configurations.
1328 *
1329 * 1. ADC/DAC on Primary Interface
1330 * 2. ADC on Primary Interface/DAC on secondary
1331 */
1332static struct snd_soc_dai_driver wm8991_dai = {
1333 /* ADC/DAC on primary */
1334 .name = "wm8991",
1335 .id = 1,
1336 .playback = {
1337 .stream_name = "Playback",
1338 .channels_min = 1,
1339 .channels_max = 2,
1340 .rates = SNDRV_PCM_RATE_8000_96000,
1341 .formats = WM8991_FORMATS
1342 },
1343 .capture = {
1344 .stream_name = "Capture",
1345 .channels_min = 1,
1346 .channels_max = 2,
1347 .rates = SNDRV_PCM_RATE_8000_96000,
1348 .formats = WM8991_FORMATS
1349 },
1350 .ops = &wm8991_ops
1351};
1352
1353static struct snd_soc_codec_driver soc_codec_dev_wm8991 = {
1354 .probe = wm8991_probe,
1355 .remove = wm8991_remove,
1356 .suspend = wm8991_suspend,
1357 .resume = wm8991_resume,
1358 .set_bias_level = wm8991_set_bias_level,
1359 .reg_cache_size = WM8991_MAX_REGISTER + 1,
1360 .reg_word_size = sizeof(u16),
1361 .reg_cache_default = wm8991_reg_defs
1362};
1363
1364static __devinit int wm8991_i2c_probe(struct i2c_client *i2c,
1365 const struct i2c_device_id *id)
1366{
1367 struct wm8991_priv *wm8991;
1368 int ret;
1369
1370 wm8991 = kzalloc(sizeof *wm8991, GFP_KERNEL);
1371 if (!wm8991)
1372 return -ENOMEM;
1373
1374 wm8991->control_type = SND_SOC_I2C;
1375 i2c_set_clientdata(i2c, wm8991);
1376
1377 ret = snd_soc_register_codec(&i2c->dev,
1378 &soc_codec_dev_wm8991, &wm8991_dai, 1);
1379 if (ret < 0)
1380 kfree(wm8991);
1381 return ret;
1382}
1383
1384static __devexit int wm8991_i2c_remove(struct i2c_client *client)
1385{
1386 snd_soc_unregister_codec(&client->dev);
1387 kfree(i2c_get_clientdata(client));
1388 return 0;
1389}
1390
1391static const struct i2c_device_id wm8991_i2c_id[] = {
1392 { "wm8991", 0 },
1393 { }
1394};
1395MODULE_DEVICE_TABLE(i2c, wm8991_i2c_id);
1396
1397static struct i2c_driver wm8991_i2c_driver = {
1398 .driver = {
1399 .name = "wm8991",
1400 .owner = THIS_MODULE,
1401 },
1402 .probe = wm8991_i2c_probe,
1403 .remove = __devexit_p(wm8991_i2c_remove),
1404 .id_table = wm8991_i2c_id,
1405};
1406
1407static int __init wm8991_modinit(void)
1408{
1409 int ret;
1410 ret = i2c_add_driver(&wm8991_i2c_driver);
1411 if (ret != 0) {
1412 printk(KERN_ERR "Failed to register WM8991 I2C driver: %d\n",
1413 ret);
1414 }
1415 return 0;
1416}
1417module_init(wm8991_modinit);
1418
1419static void __exit wm8991_exit(void)
1420{
1421 i2c_del_driver(&wm8991_i2c_driver);
1422}
1423module_exit(wm8991_exit);
1424
1425MODULE_DESCRIPTION("ASoC WM8991 driver");
1426MODULE_AUTHOR("Graeme Gregory");
1427MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8991.h b/sound/soc/codecs/wm8991.h
new file mode 100644
index 000000000000..8a942efd18a5
--- /dev/null
+++ b/sound/soc/codecs/wm8991.h
@@ -0,0 +1,833 @@
1/*
2 * wm8991.h -- audio driver for WM8991
3 *
4 * Copyright 2007 Wolfson Microelectronics PLC.
5 * Author: Graeme Gregory
6 * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#ifndef _WM8991_H
15#define _WM8991_H
16
17/*
18 * Register values.
19 */
20#define WM8991_RESET 0x00
21#define WM8991_POWER_MANAGEMENT_1 0x01
22#define WM8991_POWER_MANAGEMENT_2 0x02
23#define WM8991_POWER_MANAGEMENT_3 0x03
24#define WM8991_AUDIO_INTERFACE_1 0x04
25#define WM8991_AUDIO_INTERFACE_2 0x05
26#define WM8991_CLOCKING_1 0x06
27#define WM8991_CLOCKING_2 0x07
28#define WM8991_AUDIO_INTERFACE_3 0x08
29#define WM8991_AUDIO_INTERFACE_4 0x09
30#define WM8991_DAC_CTRL 0x0A
31#define WM8991_LEFT_DAC_DIGITAL_VOLUME 0x0B
32#define WM8991_RIGHT_DAC_DIGITAL_VOLUME 0x0C
33#define WM8991_DIGITAL_SIDE_TONE 0x0D
34#define WM8991_ADC_CTRL 0x0E
35#define WM8991_LEFT_ADC_DIGITAL_VOLUME 0x0F
36#define WM8991_RIGHT_ADC_DIGITAL_VOLUME 0x10
37#define WM8991_GPIO_CTRL_1 0x12
38#define WM8991_GPIO1_GPIO2 0x13
39#define WM8991_GPIO3_GPIO4 0x14
40#define WM8991_GPIO5_GPIO6 0x15
41#define WM8991_GPIOCTRL_2 0x16
42#define WM8991_GPIO_POL 0x17
43#define WM8991_LEFT_LINE_INPUT_1_2_VOLUME 0x18
44#define WM8991_LEFT_LINE_INPUT_3_4_VOLUME 0x19
45#define WM8991_RIGHT_LINE_INPUT_1_2_VOLUME 0x1A
46#define WM8991_RIGHT_LINE_INPUT_3_4_VOLUME 0x1B
47#define WM8991_LEFT_OUTPUT_VOLUME 0x1C
48#define WM8991_RIGHT_OUTPUT_VOLUME 0x1D
49#define WM8991_LINE_OUTPUTS_VOLUME 0x1E
50#define WM8991_OUT3_4_VOLUME 0x1F
51#define WM8991_LEFT_OPGA_VOLUME 0x20
52#define WM8991_RIGHT_OPGA_VOLUME 0x21
53#define WM8991_SPEAKER_VOLUME 0x22
54#define WM8991_CLASSD1 0x23
55#define WM8991_CLASSD3 0x25
56#define WM8991_INPUT_MIXER1 0x27
57#define WM8991_INPUT_MIXER2 0x28
58#define WM8991_INPUT_MIXER3 0x29
59#define WM8991_INPUT_MIXER4 0x2A
60#define WM8991_INPUT_MIXER5 0x2B
61#define WM8991_INPUT_MIXER6 0x2C
62#define WM8991_OUTPUT_MIXER1 0x2D
63#define WM8991_OUTPUT_MIXER2 0x2E
64#define WM8991_OUTPUT_MIXER3 0x2F
65#define WM8991_OUTPUT_MIXER4 0x30
66#define WM8991_OUTPUT_MIXER5 0x31
67#define WM8991_OUTPUT_MIXER6 0x32
68#define WM8991_OUT3_4_MIXER 0x33
69#define WM8991_LINE_MIXER1 0x34
70#define WM8991_LINE_MIXER2 0x35
71#define WM8991_SPEAKER_MIXER 0x36
72#define WM8991_ADDITIONAL_CONTROL 0x37
73#define WM8991_ANTIPOP1 0x38
74#define WM8991_ANTIPOP2 0x39
75#define WM8991_MICBIAS 0x3A
76#define WM8991_PLL1 0x3C
77#define WM8991_PLL2 0x3D
78#define WM8991_PLL3 0x3E
79#define WM8991_INTDRIVBITS 0x3F
80
81#define WM8991_REGISTER_COUNT 60
82#define WM8991_MAX_REGISTER 0x3F
83
84/*
85 * Field Definitions.
86 */
87
88/*
89 * R0 (0x00) - Reset
90 */
91#define WM8991_SW_RESET_CHIP_ID_MASK 0xFFFF /* SW_RESET_CHIP_ID - [15:0] */
92
93/*
94 * R1 (0x01) - Power Management (1)
95 */
96#define WM8991_SPK_ENA 0x1000 /* SPK_ENA */
97#define WM8991_SPK_ENA_BIT 12
98#define WM8991_OUT3_ENA 0x0800 /* OUT3_ENA */
99#define WM8991_OUT3_ENA_BIT 11
100#define WM8991_OUT4_ENA 0x0400 /* OUT4_ENA */
101#define WM8991_OUT4_ENA_BIT 10
102#define WM8991_LOUT_ENA 0x0200 /* LOUT_ENA */
103#define WM8991_LOUT_ENA_BIT 9
104#define WM8991_ROUT_ENA 0x0100 /* ROUT_ENA */
105#define WM8991_ROUT_ENA_BIT 8
106#define WM8991_MICBIAS_ENA 0x0010 /* MICBIAS_ENA */
107#define WM8991_MICBIAS_ENA_BIT 4
108#define WM8991_VMID_MODE_MASK 0x0006 /* VMID_MODE - [2:1] */
109#define WM8991_VREF_ENA 0x0001 /* VREF_ENA */
110#define WM8991_VREF_ENA_BIT 0
111
112/*
113 * R2 (0x02) - Power Management (2)
114 */
115#define WM8991_PLL_ENA 0x8000 /* PLL_ENA */
116#define WM8991_PLL_ENA_BIT 15
117#define WM8991_TSHUT_ENA 0x4000 /* TSHUT_ENA */
118#define WM8991_TSHUT_ENA_BIT 14
119#define WM8991_TSHUT_OPDIS 0x2000 /* TSHUT_OPDIS */
120#define WM8991_TSHUT_OPDIS_BIT 13
121#define WM8991_OPCLK_ENA 0x0800 /* OPCLK_ENA */
122#define WM8991_OPCLK_ENA_BIT 11
123#define WM8991_AINL_ENA 0x0200 /* AINL_ENA */
124#define WM8991_AINL_ENA_BIT 9
125#define WM8991_AINR_ENA 0x0100 /* AINR_ENA */
126#define WM8991_AINR_ENA_BIT 8
127#define WM8991_LIN34_ENA 0x0080 /* LIN34_ENA */
128#define WM8991_LIN34_ENA_BIT 7
129#define WM8991_LIN12_ENA 0x0040 /* LIN12_ENA */
130#define WM8991_LIN12_ENA_BIT 6
131#define WM8991_RIN34_ENA 0x0020 /* RIN34_ENA */
132#define WM8991_RIN34_ENA_BIT 5
133#define WM8991_RIN12_ENA 0x0010 /* RIN12_ENA */
134#define WM8991_RIN12_ENA_BIT 4
135#define WM8991_ADCL_ENA 0x0002 /* ADCL_ENA */
136#define WM8991_ADCL_ENA_BIT 1
137#define WM8991_ADCR_ENA 0x0001 /* ADCR_ENA */
138#define WM8991_ADCR_ENA_BIT 0
139
140/*
141 * R3 (0x03) - Power Management (3)
142 */
143#define WM8991_LON_ENA 0x2000 /* LON_ENA */
144#define WM8991_LON_ENA_BIT 13
145#define WM8991_LOP_ENA 0x1000 /* LOP_ENA */
146#define WM8991_LOP_ENA_BIT 12
147#define WM8991_RON_ENA 0x0800 /* RON_ENA */
148#define WM8991_RON_ENA_BIT 11
149#define WM8991_ROP_ENA 0x0400 /* ROP_ENA */
150#define WM8991_ROP_ENA_BIT 10
151#define WM8991_LOPGA_ENA 0x0080 /* LOPGA_ENA */
152#define WM8991_LOPGA_ENA_BIT 7
153#define WM8991_ROPGA_ENA 0x0040 /* ROPGA_ENA */
154#define WM8991_ROPGA_ENA_BIT 6
155#define WM8991_LOMIX_ENA 0x0020 /* LOMIX_ENA */
156#define WM8991_LOMIX_ENA_BIT 5
157#define WM8991_ROMIX_ENA 0x0010 /* ROMIX_ENA */
158#define WM8991_ROMIX_ENA_BIT 4
159#define WM8991_DACL_ENA 0x0002 /* DACL_ENA */
160#define WM8991_DACL_ENA_BIT 1
161#define WM8991_DACR_ENA 0x0001 /* DACR_ENA */
162#define WM8991_DACR_ENA_BIT 0
163
164/*
165 * R4 (0x04) - Audio Interface (1)
166 */
167#define WM8991_AIFADCL_SRC 0x8000 /* AIFADCL_SRC */
168#define WM8991_AIFADCR_SRC 0x4000 /* AIFADCR_SRC */
169#define WM8991_AIFADC_TDM 0x2000 /* AIFADC_TDM */
170#define WM8991_AIFADC_TDM_CHAN 0x1000 /* AIFADC_TDM_CHAN */
171#define WM8991_AIF_BCLK_INV 0x0100 /* AIF_BCLK_INV */
172#define WM8991_AIF_LRCLK_INV 0x0080 /* AIF_LRCLK_INV */
173#define WM8991_AIF_WL_MASK 0x0060 /* AIF_WL - [6:5] */
174#define WM8991_AIF_WL_16BITS (0 << 5)
175#define WM8991_AIF_WL_20BITS (1 << 5)
176#define WM8991_AIF_WL_24BITS (2 << 5)
177#define WM8991_AIF_WL_32BITS (3 << 5)
178#define WM8991_AIF_FMT_MASK 0x0018 /* AIF_FMT - [4:3] */
179#define WM8991_AIF_TMF_RIGHTJ (0 << 3)
180#define WM8991_AIF_TMF_LEFTJ (1 << 3)
181#define WM8991_AIF_TMF_I2S (2 << 3)
182#define WM8991_AIF_TMF_DSP (3 << 3)
183
184/*
185 * R5 (0x05) - Audio Interface (2)
186 */
187#define WM8991_DACL_SRC 0x8000 /* DACL_SRC */
188#define WM8991_DACR_SRC 0x4000 /* DACR_SRC */
189#define WM8991_AIFDAC_TDM 0x2000 /* AIFDAC_TDM */
190#define WM8991_AIFDAC_TDM_CHAN 0x1000 /* AIFDAC_TDM_CHAN */
191#define WM8991_DAC_BOOST_MASK 0x0C00 /* DAC_BOOST - [11:10] */
192#define WM8991_DAC_COMP 0x0010 /* DAC_COMP */
193#define WM8991_DAC_COMPMODE 0x0008 /* DAC_COMPMODE */
194#define WM8991_ADC_COMP 0x0004 /* ADC_COMP */
195#define WM8991_ADC_COMPMODE 0x0002 /* ADC_COMPMODE */
196#define WM8991_LOOPBACK 0x0001 /* LOOPBACK */
197
198/*
199 * R6 (0x06) - Clocking (1)
200 */
201#define WM8991_TOCLK_RATE 0x8000 /* TOCLK_RATE */
202#define WM8991_TOCLK_ENA 0x4000 /* TOCLK_ENA */
203#define WM8991_OPCLKDIV_MASK 0x1E00 /* OPCLKDIV - [12:9] */
204#define WM8991_DCLKDIV_MASK 0x01C0 /* DCLKDIV - [8:6] */
205#define WM8991_BCLK_DIV_MASK 0x001E /* BCLK_DIV - [4:1] */
206#define WM8991_BCLK_DIV_1 (0x0 << 1)
207#define WM8991_BCLK_DIV_1_5 (0x1 << 1)
208#define WM8991_BCLK_DIV_2 (0x2 << 1)
209#define WM8991_BCLK_DIV_3 (0x3 << 1)
210#define WM8991_BCLK_DIV_4 (0x4 << 1)
211#define WM8991_BCLK_DIV_5_5 (0x5 << 1)
212#define WM8991_BCLK_DIV_6 (0x6 << 1)
213#define WM8991_BCLK_DIV_8 (0x7 << 1)
214#define WM8991_BCLK_DIV_11 (0x8 << 1)
215#define WM8991_BCLK_DIV_12 (0x9 << 1)
216#define WM8991_BCLK_DIV_16 (0xA << 1)
217#define WM8991_BCLK_DIV_22 (0xB << 1)
218#define WM8991_BCLK_DIV_24 (0xC << 1)
219#define WM8991_BCLK_DIV_32 (0xD << 1)
220#define WM8991_BCLK_DIV_44 (0xE << 1)
221#define WM8991_BCLK_DIV_48 (0xF << 1)
222
223/*
224 * R7 (0x07) - Clocking (2)
225 */
226#define WM8991_MCLK_SRC 0x8000 /* MCLK_SRC */
227#define WM8991_SYSCLK_SRC 0x4000 /* SYSCLK_SRC */
228#define WM8991_CLK_FORCE 0x2000 /* CLK_FORCE */
229#define WM8991_MCLK_DIV_MASK 0x1800 /* MCLK_DIV - [12:11] */
230#define WM8991_MCLK_DIV_1 (0 << 11)
231#define WM8991_MCLK_DIV_2 ( 2 << 11)
232#define WM8991_MCLK_INV 0x0400 /* MCLK_INV */
233#define WM8991_ADC_CLKDIV_MASK 0x00E0 /* ADC_CLKDIV - [7:5] */
234#define WM8991_ADC_CLKDIV_1 (0 << 5)
235#define WM8991_ADC_CLKDIV_1_5 (1 << 5)
236#define WM8991_ADC_CLKDIV_2 (2 << 5)
237#define WM8991_ADC_CLKDIV_3 (3 << 5)
238#define WM8991_ADC_CLKDIV_4 (4 << 5)
239#define WM8991_ADC_CLKDIV_5_5 (5 << 5)
240#define WM8991_ADC_CLKDIV_6 (6 << 5)
241#define WM8991_DAC_CLKDIV_MASK 0x001C /* DAC_CLKDIV - [4:2] */
242#define WM8991_DAC_CLKDIV_1 (0 << 2)
243#define WM8991_DAC_CLKDIV_1_5 (1 << 2)
244#define WM8991_DAC_CLKDIV_2 (2 << 2)
245#define WM8991_DAC_CLKDIV_3 (3 << 2)
246#define WM8991_DAC_CLKDIV_4 (4 << 2)
247#define WM8991_DAC_CLKDIV_5_5 (5 << 2)
248#define WM8991_DAC_CLKDIV_6 (6 << 2)
249
250/*
251 * R8 (0x08) - Audio Interface (3)
252 */
253#define WM8991_AIF_MSTR1 0x8000 /* AIF_MSTR1 */
254#define WM8991_AIF_MSTR2 0x4000 /* AIF_MSTR2 */
255#define WM8991_AIF_SEL 0x2000 /* AIF_SEL */
256#define WM8991_ADCLRC_DIR 0x0800 /* ADCLRC_DIR */
257#define WM8991_ADCLRC_RATE_MASK 0x07FF /* ADCLRC_RATE - [10:0] */
258
259/*
260 * R9 (0x09) - Audio Interface (4)
261 */
262#define WM8991_ALRCGPIO1 0x8000 /* ALRCGPIO1 */
263#define WM8991_ALRCBGPIO6 0x4000 /* ALRCBGPIO6 */
264#define WM8991_AIF_TRIS 0x2000 /* AIF_TRIS */
265#define WM8991_DACLRC_DIR 0x0800 /* DACLRC_DIR */
266#define WM8991_DACLRC_RATE_MASK 0x07FF /* DACLRC_RATE - [10:0] */
267
268/*
269 * R10 (0x0A) - DAC CTRL
270 */
271#define WM8991_AIF_LRCLKRATE 0x0400 /* AIF_LRCLKRATE */
272#define WM8991_DAC_MONO 0x0200 /* DAC_MONO */
273#define WM8991_DAC_SB_FILT 0x0100 /* DAC_SB_FILT */
274#define WM8991_DAC_MUTERATE 0x0080 /* DAC_MUTERATE */
275#define WM8991_DAC_MUTEMODE 0x0040 /* DAC_MUTEMODE */
276#define WM8991_DEEMP_MASK 0x0030 /* DEEMP - [5:4] */
277#define WM8991_DAC_MUTE 0x0004 /* DAC_MUTE */
278#define WM8991_DACL_DATINV 0x0002 /* DACL_DATINV */
279#define WM8991_DACR_DATINV 0x0001 /* DACR_DATINV */
280
281/*
282 * R11 (0x0B) - Left DAC Digital Volume
283 */
284#define WM8991_DAC_VU 0x0100 /* DAC_VU */
285#define WM8991_DACL_VOL_MASK 0x00FF /* DACL_VOL - [7:0] */
286#define WM8991_DACL_VOL_SHIFT 0
287/*
288 * R12 (0x0C) - Right DAC Digital Volume
289 */
290#define WM8991_DAC_VU 0x0100 /* DAC_VU */
291#define WM8991_DACR_VOL_MASK 0x00FF /* DACR_VOL - [7:0] */
292#define WM8991_DACR_VOL_SHIFT 0
293/*
294 * R13 (0x0D) - Digital Side Tone
295 */
296#define WM8991_ADCL_DAC_SVOL_MASK 0x0F /* ADCL_DAC_SVOL - [12:9] */
297#define WM8991_ADCL_DAC_SVOL_SHIFT 9
298#define WM8991_ADCR_DAC_SVOL_MASK 0x0F /* ADCR_DAC_SVOL - [8:5] */
299#define WM8991_ADCR_DAC_SVOL_SHIFT 5
300#define WM8991_ADC_TO_DACL_MASK 0x03 /* ADC_TO_DACL - [3:2] */
301#define WM8991_ADC_TO_DACL_SHIFT 2
302#define WM8991_ADC_TO_DACR_MASK 0x03 /* ADC_TO_DACR - [1:0] */
303#define WM8991_ADC_TO_DACR_SHIFT 0
304
305/*
306 * R14 (0x0E) - ADC CTRL
307 */
308#define WM8991_ADC_HPF_ENA 0x0100 /* ADC_HPF_ENA */
309#define WM8991_ADC_HPF_ENA_BIT 8
310#define WM8991_ADC_HPF_CUT_MASK 0x03 /* ADC_HPF_CUT - [6:5] */
311#define WM8991_ADC_HPF_CUT_SHIFT 5
312#define WM8991_ADCL_DATINV 0x0002 /* ADCL_DATINV */
313#define WM8991_ADCL_DATINV_BIT 1
314#define WM8991_ADCR_DATINV 0x0001 /* ADCR_DATINV */
315#define WM8991_ADCR_DATINV_BIT 0
316
317/*
318 * R15 (0x0F) - Left ADC Digital Volume
319 */
320#define WM8991_ADC_VU 0x0100 /* ADC_VU */
321#define WM8991_ADCL_VOL_MASK 0x00FF /* ADCL_VOL - [7:0] */
322#define WM8991_ADCL_VOL_SHIFT 0
323
324/*
325 * R16 (0x10) - Right ADC Digital Volume
326 */
327#define WM8991_ADC_VU 0x0100 /* ADC_VU */
328#define WM8991_ADCR_VOL_MASK 0x00FF /* ADCR_VOL - [7:0] */
329#define WM8991_ADCR_VOL_SHIFT 0
330
331/*
332 * R18 (0x12) - GPIO CTRL 1
333 */
334#define WM8991_IRQ 0x1000 /* IRQ */
335#define WM8991_TEMPOK 0x0800 /* TEMPOK */
336#define WM8991_MICSHRT 0x0400 /* MICSHRT */
337#define WM8991_MICDET 0x0200 /* MICDET */
338#define WM8991_PLL_LCK 0x0100 /* PLL_LCK */
339#define WM8991_GPI8_STATUS 0x0080 /* GPI8_STATUS */
340#define WM8991_GPI7_STATUS 0x0040 /* GPI7_STATUS */
341#define WM8991_GPIO6_STATUS 0x0020 /* GPIO6_STATUS */
342#define WM8991_GPIO5_STATUS 0x0010 /* GPIO5_STATUS */
343#define WM8991_GPIO4_STATUS 0x0008 /* GPIO4_STATUS */
344#define WM8991_GPIO3_STATUS 0x0004 /* GPIO3_STATUS */
345#define WM8991_GPIO2_STATUS 0x0002 /* GPIO2_STATUS */
346#define WM8991_GPIO1_STATUS 0x0001 /* GPIO1_STATUS */
347
348/*
349 * R19 (0x13) - GPIO1 & GPIO2
350 */
351#define WM8991_GPIO2_DEB_ENA 0x8000 /* GPIO2_DEB_ENA */
352#define WM8991_GPIO2_IRQ_ENA 0x4000 /* GPIO2_IRQ_ENA */
353#define WM8991_GPIO2_PU 0x2000 /* GPIO2_PU */
354#define WM8991_GPIO2_PD 0x1000 /* GPIO2_PD */
355#define WM8991_GPIO2_SEL_MASK 0x0F00 /* GPIO2_SEL - [11:8] */
356#define WM8991_GPIO1_DEB_ENA 0x0080 /* GPIO1_DEB_ENA */
357#define WM8991_GPIO1_IRQ_ENA 0x0040 /* GPIO1_IRQ_ENA */
358#define WM8991_GPIO1_PU 0x0020 /* GPIO1_PU */
359#define WM8991_GPIO1_PD 0x0010 /* GPIO1_PD */
360#define WM8991_GPIO1_SEL_MASK 0x000F /* GPIO1_SEL - [3:0] */
361
362/*
363 * R20 (0x14) - GPIO3 & GPIO4
364 */
365#define WM8991_GPIO4_DEB_ENA 0x8000 /* GPIO4_DEB_ENA */
366#define WM8991_GPIO4_IRQ_ENA 0x4000 /* GPIO4_IRQ_ENA */
367#define WM8991_GPIO4_PU 0x2000 /* GPIO4_PU */
368#define WM8991_GPIO4_PD 0x1000 /* GPIO4_PD */
369#define WM8991_GPIO4_SEL_MASK 0x0F00 /* GPIO4_SEL - [11:8] */
370#define WM8991_GPIO3_DEB_ENA 0x0080 /* GPIO3_DEB_ENA */
371#define WM8991_GPIO3_IRQ_ENA 0x0040 /* GPIO3_IRQ_ENA */
372#define WM8991_GPIO3_PU 0x0020 /* GPIO3_PU */
373#define WM8991_GPIO3_PD 0x0010 /* GPIO3_PD */
374#define WM8991_GPIO3_SEL_MASK 0x000F /* GPIO3_SEL - [3:0] */
375
376/*
377 * R21 (0x15) - GPIO5 & GPIO6
378 */
379#define WM8991_GPIO6_DEB_ENA 0x8000 /* GPIO6_DEB_ENA */
380#define WM8991_GPIO6_IRQ_ENA 0x4000 /* GPIO6_IRQ_ENA */
381#define WM8991_GPIO6_PU 0x2000 /* GPIO6_PU */
382#define WM8991_GPIO6_PD 0x1000 /* GPIO6_PD */
383#define WM8991_GPIO6_SEL_MASK 0x0F00 /* GPIO6_SEL - [11:8] */
384#define WM8991_GPIO5_DEB_ENA 0x0080 /* GPIO5_DEB_ENA */
385#define WM8991_GPIO5_IRQ_ENA 0x0040 /* GPIO5_IRQ_ENA */
386#define WM8991_GPIO5_PU 0x0020 /* GPIO5_PU */
387#define WM8991_GPIO5_PD 0x0010 /* GPIO5_PD */
388#define WM8991_GPIO5_SEL_MASK 0x000F /* GPIO5_SEL - [3:0] */
389
390/*
391 * R22 (0x16) - GPIOCTRL 2
392 */
393#define WM8991_RD_3W_ENA 0x8000 /* RD_3W_ENA */
394#define WM8991_MODE_3W4W 0x4000 /* MODE_3W4W */
395#define WM8991_TEMPOK_IRQ_ENA 0x0800 /* TEMPOK_IRQ_ENA */
396#define WM8991_MICSHRT_IRQ_ENA 0x0400 /* MICSHRT_IRQ_ENA */
397#define WM8991_MICDET_IRQ_ENA 0x0200 /* MICDET_IRQ_ENA */
398#define WM8991_PLL_LCK_IRQ_ENA 0x0100 /* PLL_LCK_IRQ_ENA */
399#define WM8991_GPI8_DEB_ENA 0x0080 /* GPI8_DEB_ENA */
400#define WM8991_GPI8_IRQ_ENA 0x0040 /* GPI8_IRQ_ENA */
401#define WM8991_GPI8_ENA 0x0010 /* GPI8_ENA */
402#define WM8991_GPI7_DEB_ENA 0x0008 /* GPI7_DEB_ENA */
403#define WM8991_GPI7_IRQ_ENA 0x0004 /* GPI7_IRQ_ENA */
404#define WM8991_GPI7_ENA 0x0001 /* GPI7_ENA */
405
406/*
407 * R23 (0x17) - GPIO_POL
408 */
409#define WM8991_IRQ_INV 0x1000 /* IRQ_INV */
410#define WM8991_TEMPOK_POL 0x0800 /* TEMPOK_POL */
411#define WM8991_MICSHRT_POL 0x0400 /* MICSHRT_POL */
412#define WM8991_MICDET_POL 0x0200 /* MICDET_POL */
413#define WM8991_PLL_LCK_POL 0x0100 /* PLL_LCK_POL */
414#define WM8991_GPI8_POL 0x0080 /* GPI8_POL */
415#define WM8991_GPI7_POL 0x0040 /* GPI7_POL */
416#define WM8991_GPIO6_POL 0x0020 /* GPIO6_POL */
417#define WM8991_GPIO5_POL 0x0010 /* GPIO5_POL */
418#define WM8991_GPIO4_POL 0x0008 /* GPIO4_POL */
419#define WM8991_GPIO3_POL 0x0004 /* GPIO3_POL */
420#define WM8991_GPIO2_POL 0x0002 /* GPIO2_POL */
421#define WM8991_GPIO1_POL 0x0001 /* GPIO1_POL */
422
423/*
424 * R24 (0x18) - Left Line Input 1&2 Volume
425 */
426#define WM8991_IPVU 0x0100 /* IPVU */
427#define WM8991_LI12MUTE 0x0080 /* LI12MUTE */
428#define WM8991_LI12MUTE_BIT 7
429#define WM8991_LI12ZC 0x0040 /* LI12ZC */
430#define WM8991_LI12ZC_BIT 6
431#define WM8991_LIN12VOL_MASK 0x001F /* LIN12VOL - [4:0] */
432#define WM8991_LIN12VOL_SHIFT 0
433/*
434 * R25 (0x19) - Left Line Input 3&4 Volume
435 */
436#define WM8991_IPVU 0x0100 /* IPVU */
437#define WM8991_LI34MUTE 0x0080 /* LI34MUTE */
438#define WM8991_LI34MUTE_BIT 7
439#define WM8991_LI34ZC 0x0040 /* LI34ZC */
440#define WM8991_LI34ZC_BIT 6
441#define WM8991_LIN34VOL_MASK 0x001F /* LIN34VOL - [4:0] */
442#define WM8991_LIN34VOL_SHIFT 0
443
444/*
445 * R26 (0x1A) - Right Line Input 1&2 Volume
446 */
447#define WM8991_IPVU 0x0100 /* IPVU */
448#define WM8991_RI12MUTE 0x0080 /* RI12MUTE */
449#define WM8991_RI12MUTE_BIT 7
450#define WM8991_RI12ZC 0x0040 /* RI12ZC */
451#define WM8991_RI12ZC_BIT 6
452#define WM8991_RIN12VOL_MASK 0x001F /* RIN12VOL - [4:0] */
453#define WM8991_RIN12VOL_SHIFT 0
454
455/*
456 * R27 (0x1B) - Right Line Input 3&4 Volume
457 */
458#define WM8991_IPVU 0x0100 /* IPVU */
459#define WM8991_RI34MUTE 0x0080 /* RI34MUTE */
460#define WM8991_RI34MUTE_BIT 7
461#define WM8991_RI34ZC 0x0040 /* RI34ZC */
462#define WM8991_RI34ZC_BIT 6
463#define WM8991_RIN34VOL_MASK 0x001F /* RIN34VOL - [4:0] */
464#define WM8991_RIN34VOL_SHIFT 0
465
466/*
467 * R28 (0x1C) - Left Output Volume
468 */
469#define WM8991_OPVU 0x0100 /* OPVU */
470#define WM8991_LOZC 0x0080 /* LOZC */
471#define WM8991_LOZC_BIT 7
472#define WM8991_LOUTVOL_MASK 0x007F /* LOUTVOL - [6:0] */
473#define WM8991_LOUTVOL_SHIFT 0
474/*
475 * R29 (0x1D) - Right Output Volume
476 */
477#define WM8991_OPVU 0x0100 /* OPVU */
478#define WM8991_ROZC 0x0080 /* ROZC */
479#define WM8991_ROZC_BIT 7
480#define WM8991_ROUTVOL_MASK 0x007F /* ROUTVOL - [6:0] */
481#define WM8991_ROUTVOL_SHIFT 0
482/*
483 * R30 (0x1E) - Line Outputs Volume
484 */
485#define WM8991_LONMUTE 0x0040 /* LONMUTE */
486#define WM8991_LONMUTE_BIT 6
487#define WM8991_LOPMUTE 0x0020 /* LOPMUTE */
488#define WM8991_LOPMUTE_BIT 5
489#define WM8991_LOATTN 0x0010 /* LOATTN */
490#define WM8991_LOATTN_BIT 4
491#define WM8991_RONMUTE 0x0004 /* RONMUTE */
492#define WM8991_RONMUTE_BIT 2
493#define WM8991_ROPMUTE 0x0002 /* ROPMUTE */
494#define WM8991_ROPMUTE_BIT 1
495#define WM8991_ROATTN 0x0001 /* ROATTN */
496#define WM8991_ROATTN_BIT 0
497
498/*
499 * R31 (0x1F) - Out3/4 Volume
500 */
501#define WM8991_OUT3MUTE 0x0020 /* OUT3MUTE */
502#define WM8991_OUT3MUTE_BIT 5
503#define WM8991_OUT3ATTN 0x0010 /* OUT3ATTN */
504#define WM8991_OUT3ATTN_BIT 4
505#define WM8991_OUT4MUTE 0x0002 /* OUT4MUTE */
506#define WM8991_OUT4MUTE_BIT 1
507#define WM8991_OUT4ATTN 0x0001 /* OUT4ATTN */
508#define WM8991_OUT4ATTN_BIT 0
509
510/*
511 * R32 (0x20) - Left OPGA Volume
512 */
513#define WM8991_OPVU 0x0100 /* OPVU */
514#define WM8991_LOPGAZC 0x0080 /* LOPGAZC */
515#define WM8991_LOPGAZC_BIT 7
516#define WM8991_LOPGAVOL_MASK 0x007F /* LOPGAVOL - [6:0] */
517#define WM8991_LOPGAVOL_SHIFT 0
518
519/*
520 * R33 (0x21) - Right OPGA Volume
521 */
522#define WM8991_OPVU 0x0100 /* OPVU */
523#define WM8991_ROPGAZC 0x0080 /* ROPGAZC */
524#define WM8991_ROPGAZC_BIT 7
525#define WM8991_ROPGAVOL_MASK 0x007F /* ROPGAVOL - [6:0] */
526#define WM8991_ROPGAVOL_SHIFT 0
527/*
528 * R34 (0x22) - Speaker Volume
529 */
530#define WM8991_SPKVOL_MASK 0x0003 /* SPKVOL - [1:0] */
531#define WM8991_SPKVOL_SHIFT 0
532
533/*
534 * R35 (0x23) - ClassD1
535 */
536#define WM8991_CDMODE 0x0100 /* CDMODE */
537#define WM8991_CDMODE_BIT 8
538
539/*
540 * R37 (0x25) - ClassD3
541 */
542#define WM8991_DCGAIN_MASK 0x0007 /* DCGAIN - [5:3] */
543#define WM8991_DCGAIN_SHIFT 3
544#define WM8991_ACGAIN_MASK 0x0007 /* ACGAIN - [2:0] */
545#define WM8991_ACGAIN_SHIFT 0
546/*
547 * R39 (0x27) - Input Mixer1
548 */
549#define WM8991_AINLMODE_MASK 0x000C /* AINLMODE - [3:2] */
550#define WM8991_AINLMODE_SHIFT 2
551#define WM8991_AINRMODE_MASK 0x0003 /* AINRMODE - [1:0] */
552#define WM8991_AINRMODE_SHIFT 0
553
554/*
555 * R40 (0x28) - Input Mixer2
556 */
557#define WM8991_LMP4 0x0080 /* LMP4 */
558#define WM8991_LMP4_BIT 7 /* LMP4 */
559#define WM8991_LMN3 0x0040 /* LMN3 */
560#define WM8991_LMN3_BIT 6 /* LMN3 */
561#define WM8991_LMP2 0x0020 /* LMP2 */
562#define WM8991_LMP2_BIT 5 /* LMP2 */
563#define WM8991_LMN1 0x0010 /* LMN1 */
564#define WM8991_LMN1_BIT 4 /* LMN1 */
565#define WM8991_RMP4 0x0008 /* RMP4 */
566#define WM8991_RMP4_BIT 3 /* RMP4 */
567#define WM8991_RMN3 0x0004 /* RMN3 */
568#define WM8991_RMN3_BIT 2 /* RMN3 */
569#define WM8991_RMP2 0x0002 /* RMP2 */
570#define WM8991_RMP2_BIT 1 /* RMP2 */
571#define WM8991_RMN1 0x0001 /* RMN1 */
572#define WM8991_RMN1_BIT 0 /* RMN1 */
573
574/*
575 * R41 (0x29) - Input Mixer3
576 */
577#define WM8991_L34MNB 0x0100 /* L34MNB */
578#define WM8991_L34MNB_BIT 8
579#define WM8991_L34MNBST 0x0080 /* L34MNBST */
580#define WM8991_L34MNBST_BIT 7
581#define WM8991_L12MNB 0x0020 /* L12MNB */
582#define WM8991_L12MNB_BIT 5
583#define WM8991_L12MNBST 0x0010 /* L12MNBST */
584#define WM8991_L12MNBST_BIT 4
585#define WM8991_LDBVOL_MASK 0x0007 /* LDBVOL - [2:0] */
586#define WM8991_LDBVOL_SHIFT 0
587
588/*
589 * R42 (0x2A) - Input Mixer4
590 */
591#define WM8991_R34MNB 0x0100 /* R34MNB */
592#define WM8991_R34MNB_BIT 8
593#define WM8991_R34MNBST 0x0080 /* R34MNBST */
594#define WM8991_R34MNBST_BIT 7
595#define WM8991_R12MNB 0x0020 /* R12MNB */
596#define WM8991_R12MNB_BIT 5
597#define WM8991_R12MNBST 0x0010 /* R12MNBST */
598#define WM8991_R12MNBST_BIT 4
599#define WM8991_RDBVOL_MASK 0x0007 /* RDBVOL - [2:0] */
600#define WM8991_RDBVOL_SHIFT 0
601
602/*
603 * R43 (0x2B) - Input Mixer5
604 */
605#define WM8991_LI2BVOL_MASK 0x07 /* LI2BVOL - [8:6] */
606#define WM8991_LI2BVOL_SHIFT 6
607#define WM8991_LR4BVOL_MASK 0x07 /* LR4BVOL - [5:3] */
608#define WM8991_LR4BVOL_SHIFT 3
609#define WM8991_LL4BVOL_MASK 0x07 /* LL4BVOL - [2:0] */
610#define WM8991_LL4BVOL_SHIFT 0
611
612/*
613 * R44 (0x2C) - Input Mixer6
614 */
615#define WM8991_RI2BVOL_MASK 0x07 /* RI2BVOL - [8:6] */
616#define WM8991_RI2BVOL_SHIFT 6
617#define WM8991_RL4BVOL_MASK 0x07 /* RL4BVOL - [5:3] */
618#define WM8991_RL4BVOL_SHIFT 3
619#define WM8991_RR4BVOL_MASK 0x07 /* RR4BVOL - [2:0] */
620#define WM8991_RR4BVOL_SHIFT 0
621
622/*
623 * R45 (0x2D) - Output Mixer1
624 */
625#define WM8991_LRBLO 0x0080 /* LRBLO */
626#define WM8991_LRBLO_BIT 7
627#define WM8991_LLBLO 0x0040 /* LLBLO */
628#define WM8991_LLBLO_BIT 6
629#define WM8991_LRI3LO 0x0020 /* LRI3LO */
630#define WM8991_LRI3LO_BIT 5
631#define WM8991_LLI3LO 0x0010 /* LLI3LO */
632#define WM8991_LLI3LO_BIT 4
633#define WM8991_LR12LO 0x0008 /* LR12LO */
634#define WM8991_LR12LO_BIT 3
635#define WM8991_LL12LO 0x0004 /* LL12LO */
636#define WM8991_LL12LO_BIT 2
637#define WM8991_LDLO 0x0001 /* LDLO */
638#define WM8991_LDLO_BIT 0
639
640/*
641 * R46 (0x2E) - Output Mixer2
642 */
643#define WM8991_RLBRO 0x0080 /* RLBRO */
644#define WM8991_RLBRO_BIT 7
645#define WM8991_RRBRO 0x0040 /* RRBRO */
646#define WM8991_RRBRO_BIT 6
647#define WM8991_RLI3RO 0x0020 /* RLI3RO */
648#define WM8991_RLI3RO_BIT 5
649#define WM8991_RRI3RO 0x0010 /* RRI3RO */
650#define WM8991_RRI3RO_BIT 4
651#define WM8991_RL12RO 0x0008 /* RL12RO */
652#define WM8991_RL12RO_BIT 3
653#define WM8991_RR12RO 0x0004 /* RR12RO */
654#define WM8991_RR12RO_BIT 2
655#define WM8991_RDRO 0x0001 /* RDRO */
656#define WM8991_RDRO_BIT 0
657
658/*
659 * R47 (0x2F) - Output Mixer3
660 */
661#define WM8991_LLI3LOVOL_MASK 0x07 /* LLI3LOVOL - [8:6] */
662#define WM8991_LLI3LOVOL_SHIFT 6
663#define WM8991_LR12LOVOL_MASK 0x07 /* LR12LOVOL - [5:3] */
664#define WM8991_LR12LOVOL_SHIFT 3
665#define WM8991_LL12LOVOL_MASK 0x07 /* LL12LOVOL - [2:0] */
666#define WM8991_LL12LOVOL_SHIFT 0
667
668/*
669 * R48 (0x30) - Output Mixer4
670 */
671#define WM8991_RRI3ROVOL_MASK 0x07 /* RRI3ROVOL - [8:6] */
672#define WM8991_RRI3ROVOL_SHIFT 6
673#define WM8991_RL12ROVOL_MASK 0x07 /* RL12ROVOL - [5:3] */
674#define WM8991_RL12ROVOL_SHIFT 3
675#define WM8991_RR12ROVOL_MASK 0x07 /* RR12ROVOL - [2:0] */
676#define WM8991_RR12ROVOL_SHIFT 0
677
678/*
679 * R49 (0x31) - Output Mixer5
680 */
681#define WM8991_LRI3LOVOL_MASK 0x07 /* LRI3LOVOL - [8:6] */
682#define WM8991_LRI3LOVOL_SHIFT 6
683#define WM8991_LRBLOVOL_MASK 0x07 /* LRBLOVOL - [5:3] */
684#define WM8991_LRBLOVOL_SHIFT 3
685#define WM8991_LLBLOVOL_MASK 0x07 /* LLBLOVOL - [2:0] */
686#define WM8991_LLBLOVOL_SHIFT 0
687
688/*
689 * R50 (0x32) - Output Mixer6
690 */
691#define WM8991_RLI3ROVOL_MASK 0x07 /* RLI3ROVOL - [8:6] */
692#define WM8991_RLI3ROVOL_SHIFT 6
693#define WM8991_RLBROVOL_MASK 0x07 /* RLBROVOL - [5:3] */
694#define WM8991_RLBROVOL_SHIFT 3
695#define WM8991_RRBROVOL_MASK 0x07 /* RRBROVOL - [2:0] */
696#define WM8991_RRBROVOL_SHIFT 0
697
698/*
699 * R51 (0x33) - Out3/4 Mixer
700 */
701#define WM8991_VSEL_MASK 0x0180 /* VSEL - [8:7] */
702#define WM8991_LI4O3 0x0020 /* LI4O3 */
703#define WM8991_LI4O3_BIT 5
704#define WM8991_LPGAO3 0x0010 /* LPGAO3 */
705#define WM8991_LPGAO3_BIT 4
706#define WM8991_RI4O4 0x0002 /* RI4O4 */
707#define WM8991_RI4O4_BIT 1
708#define WM8991_RPGAO4 0x0001 /* RPGAO4 */
709#define WM8991_RPGAO4_BIT 0
710/*
711 * R52 (0x34) - Line Mixer1
712 */
713#define WM8991_LLOPGALON 0x0040 /* LLOPGALON */
714#define WM8991_LLOPGALON_BIT 6
715#define WM8991_LROPGALON 0x0020 /* LROPGALON */
716#define WM8991_LROPGALON_BIT 5
717#define WM8991_LOPLON 0x0010 /* LOPLON */
718#define WM8991_LOPLON_BIT 4
719#define WM8991_LR12LOP 0x0004 /* LR12LOP */
720#define WM8991_LR12LOP_BIT 2
721#define WM8991_LL12LOP 0x0002 /* LL12LOP */
722#define WM8991_LL12LOP_BIT 1
723#define WM8991_LLOPGALOP 0x0001 /* LLOPGALOP */
724#define WM8991_LLOPGALOP_BIT 0
725/*
726 * R53 (0x35) - Line Mixer2
727 */
728#define WM8991_RROPGARON 0x0040 /* RROPGARON */
729#define WM8991_RROPGARON_BIT 6
730#define WM8991_RLOPGARON 0x0020 /* RLOPGARON */
731#define WM8991_RLOPGARON_BIT 5
732#define WM8991_ROPRON 0x0010 /* ROPRON */
733#define WM8991_ROPRON_BIT 4
734#define WM8991_RL12ROP 0x0004 /* RL12ROP */
735#define WM8991_RL12ROP_BIT 2
736#define WM8991_RR12ROP 0x0002 /* RR12ROP */
737#define WM8991_RR12ROP_BIT 1
738#define WM8991_RROPGAROP 0x0001 /* RROPGAROP */
739#define WM8991_RROPGAROP_BIT 0
740
741/*
742 * R54 (0x36) - Speaker Mixer
743 */
744#define WM8991_LB2SPK 0x0080 /* LB2SPK */
745#define WM8991_LB2SPK_BIT 7
746#define WM8991_RB2SPK 0x0040 /* RB2SPK */
747#define WM8991_RB2SPK_BIT 6
748#define WM8991_LI2SPK 0x0020 /* LI2SPK */
749#define WM8991_LI2SPK_BIT 5
750#define WM8991_RI2SPK 0x0010 /* RI2SPK */
751#define WM8991_RI2SPK_BIT 4
752#define WM8991_LOPGASPK 0x0008 /* LOPGASPK */
753#define WM8991_LOPGASPK_BIT 3
754#define WM8991_ROPGASPK 0x0004 /* ROPGASPK */
755#define WM8991_ROPGASPK_BIT 2
756#define WM8991_LDSPK 0x0002 /* LDSPK */
757#define WM8991_LDSPK_BIT 1
758#define WM8991_RDSPK 0x0001 /* RDSPK */
759#define WM8991_RDSPK_BIT 0
760
761/*
762 * R55 (0x37) - Additional Control
763 */
764#define WM8991_VROI 0x0001 /* VROI */
765
766/*
767 * R56 (0x38) - AntiPOP1
768 */
769#define WM8991_DIS_LLINE 0x0020 /* DIS_LLINE */
770#define WM8991_DIS_RLINE 0x0010 /* DIS_RLINE */
771#define WM8991_DIS_OUT3 0x0008 /* DIS_OUT3 */
772#define WM8991_DIS_OUT4 0x0004 /* DIS_OUT4 */
773#define WM8991_DIS_LOUT 0x0002 /* DIS_LOUT */
774#define WM8991_DIS_ROUT 0x0001 /* DIS_ROUT */
775
776/*
777 * R57 (0x39) - AntiPOP2
778 */
779#define WM8991_SOFTST 0x0040 /* SOFTST */
780#define WM8991_BUFIOEN 0x0008 /* BUFIOEN */
781#define WM8991_BUFDCOPEN 0x0004 /* BUFDCOPEN */
782#define WM8991_POBCTRL 0x0002 /* POBCTRL */
783#define WM8991_VMIDTOG 0x0001 /* VMIDTOG */
784
785/*
786 * R58 (0x3A) - MICBIAS
787 */
788#define WM8991_MCDSCTH_MASK 0x00C0 /* MCDSCTH - [7:6] */
789#define WM8991_MCDTHR_MASK 0x0038 /* MCDTHR - [5:3] */
790#define WM8991_MCD 0x0004 /* MCD */
791#define WM8991_MBSEL 0x0001 /* MBSEL */
792
793/*
794 * R60 (0x3C) - PLL1
795 */
796#define WM8991_SDM 0x0080 /* SDM */
797#define WM8991_PRESCALE 0x0040 /* PRESCALE */
798#define WM8991_PLLN_MASK 0x000F /* PLLN - [3:0] */
799
800/*
801 * R61 (0x3D) - PLL2
802 */
803#define WM8991_PLLK1_MASK 0x00FF /* PLLK1 - [7:0] */
804
805/*
806 * R62 (0x3E) - PLL3
807 */
808#define WM8991_PLLK2_MASK 0x00FF /* PLLK2 - [7:0] */
809
810/*
811 * R63 (0x3F) - Internal Driver Bits
812 */
813#define WM8991_INMIXL_PWR_BIT 0
814#define WM8991_AINLMUX_PWR_BIT 1
815#define WM8991_INMIXR_PWR_BIT 2
816#define WM8991_AINRMUX_PWR_BIT 3
817
818#define WM8991_MCLK_DIV 0
819#define WM8991_DACCLK_DIV 1
820#define WM8991_ADCCLK_DIV 2
821#define WM8991_BCLK_DIV 3
822
823#define SOC_WM899X_OUTPGA_SINGLE_R_TLV(xname, reg, shift, max, invert,\
824 tlv_array) \
825{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
826 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
827 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
828 .tlv.p = (tlv_array), \
829 .info = snd_soc_info_volsw, \
830 .get = snd_soc_get_volsw, .put = wm899x_outpga_put_volsw_vu, \
831 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
832
833#endif /* _WM8991_H */
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c
index 18c0d9ce7c32..379fa22c5b6c 100644
--- a/sound/soc/codecs/wm8993.c
+++ b/sound/soc/codecs/wm8993.c
@@ -242,7 +242,7 @@ struct wm8993_priv {
242 int fll_src; 242 int fll_src;
243}; 243};
244 244
245static int wm8993_volatile(unsigned int reg) 245static int wm8993_volatile(struct snd_soc_codec *codec, unsigned int reg)
246{ 246{
247 switch (reg) { 247 switch (reg) {
248 case WM8993_SOFTWARE_RESET: 248 case WM8993_SOFTWARE_RESET:
diff --git a/sound/soc/codecs/wm8994-tables.c b/sound/soc/codecs/wm8994-tables.c
index 68e9b024dd48..a87adbd05ee1 100644
--- a/sound/soc/codecs/wm8994-tables.c
+++ b/sound/soc/codecs/wm8994-tables.c
@@ -62,8 +62,8 @@ const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE] = {
62 { 0x00FF, 0x00FF }, /* R58 - MICBIAS */ 62 { 0x00FF, 0x00FF }, /* R58 - MICBIAS */
63 { 0x000F, 0x000F }, /* R59 - LDO 1 */ 63 { 0x000F, 0x000F }, /* R59 - LDO 1 */
64 { 0x0007, 0x0007 }, /* R60 - LDO 2 */ 64 { 0x0007, 0x0007 }, /* R60 - LDO 2 */
65 { 0x0000, 0x0000 }, /* R61 */ 65 { 0xFFFF, 0xFFFF }, /* R61 */
66 { 0x0000, 0x0000 }, /* R62 */ 66 { 0xFFFF, 0xFFFF }, /* R62 */
67 { 0x0000, 0x0000 }, /* R63 */ 67 { 0x0000, 0x0000 }, /* R63 */
68 { 0x0000, 0x0000 }, /* R64 */ 68 { 0x0000, 0x0000 }, /* R64 */
69 { 0x0000, 0x0000 }, /* R65 */ 69 { 0x0000, 0x0000 }, /* R65 */
@@ -209,9 +209,9 @@ const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE] = {
209 { 0x0000, 0x0000 }, /* R205 */ 209 { 0x0000, 0x0000 }, /* R205 */
210 { 0x0000, 0x0000 }, /* R206 */ 210 { 0x0000, 0x0000 }, /* R206 */
211 { 0x0000, 0x0000 }, /* R207 */ 211 { 0x0000, 0x0000 }, /* R207 */
212 { 0x0000, 0x0000 }, /* R208 */ 212 { 0xFFFF, 0xFFFF }, /* R208 */
213 { 0x0000, 0x0000 }, /* R209 */ 213 { 0xFFFF, 0xFFFF }, /* R209 */
214 { 0x0000, 0x0000 }, /* R210 */ 214 { 0xFFFF, 0xFFFF }, /* R210 */
215 { 0x0000, 0x0000 }, /* R211 */ 215 { 0x0000, 0x0000 }, /* R211 */
216 { 0x0000, 0x0000 }, /* R212 */ 216 { 0x0000, 0x0000 }, /* R212 */
217 { 0x0000, 0x0000 }, /* R213 */ 217 { 0x0000, 0x0000 }, /* R213 */
@@ -1573,7 +1573,7 @@ const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE] = {
1573 { 0x03C3, 0x03C3 }, /* R1569 - Sidetone */ 1573 { 0x03C3, 0x03C3 }, /* R1569 - Sidetone */
1574}; 1574};
1575 1575
1576const __devinitdata u16 wm8994_reg_defaults[WM8994_CACHE_SIZE] = { 1576const u16 wm8994_reg_defaults[WM8994_CACHE_SIZE] = {
1577 0x8994, /* R0 - Software Reset */ 1577 0x8994, /* R0 - Software Reset */
1578 0x0000, /* R1 - Power Management (1) */ 1578 0x0000, /* R1 - Power Management (1) */
1579 0x6000, /* R2 - Power Management (2) */ 1579 0x6000, /* R2 - Power Management (2) */
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index c6c958ee5d59..3dc64c8b6a5c 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -102,8 +102,7 @@ struct wm8994_priv {
102 102
103 wm8958_micdet_cb jack_cb; 103 wm8958_micdet_cb jack_cb;
104 void *jack_cb_data; 104 void *jack_cb_data;
105 bool jack_is_mic; 105 int micdet_irq;
106 bool jack_is_video;
107 106
108 int revision; 107 int revision;
109 struct wm8994_pdata *pdata; 108 struct wm8994_pdata *pdata;
@@ -115,7 +114,7 @@ struct wm8994_priv {
115 unsigned int aif2clk_disable:1; 114 unsigned int aif2clk_disable:1;
116}; 115};
117 116
118static int wm8994_readable(unsigned int reg) 117static int wm8994_readable(struct snd_soc_codec *codec, unsigned int reg)
119{ 118{
120 switch (reg) { 119 switch (reg) {
121 case WM8994_GPIO_1: 120 case WM8994_GPIO_1:
@@ -142,7 +141,7 @@ static int wm8994_readable(unsigned int reg)
142 return wm8994_access_masks[reg].readable != 0; 141 return wm8994_access_masks[reg].readable != 0;
143} 142}
144 143
145static int wm8994_volatile(unsigned int reg) 144static int wm8994_volatile(struct snd_soc_codec *codec, unsigned int reg)
146{ 145{
147 if (reg >= WM8994_CACHE_SIZE) 146 if (reg >= WM8994_CACHE_SIZE)
148 return 1; 147 return 1;
@@ -170,7 +169,7 @@ static int wm8994_write(struct snd_soc_codec *codec, unsigned int reg,
170 169
171 BUG_ON(reg > WM8994_MAX_REGISTER); 170 BUG_ON(reg > WM8994_MAX_REGISTER);
172 171
173 if (!wm8994_volatile(reg)) { 172 if (!wm8994_volatile(codec, reg)) {
174 ret = snd_soc_cache_write(codec, reg, value); 173 ret = snd_soc_cache_write(codec, reg, value);
175 if (ret != 0) 174 if (ret != 0)
176 dev_err(codec->dev, "Cache write to %x failed: %d\n", 175 dev_err(codec->dev, "Cache write to %x failed: %d\n",
@@ -188,7 +187,7 @@ static unsigned int wm8994_read(struct snd_soc_codec *codec,
188 187
189 BUG_ON(reg > WM8994_MAX_REGISTER); 188 BUG_ON(reg > WM8994_MAX_REGISTER);
190 189
191 if (!wm8994_volatile(reg) && wm8994_readable(reg) && 190 if (!wm8994_volatile(codec, reg) && wm8994_readable(codec, reg) &&
192 reg < codec->driver->reg_cache_size) { 191 reg < codec->driver->reg_cache_size) {
193 ret = snd_soc_cache_read(codec, reg, &val); 192 ret = snd_soc_cache_read(codec, reg, &val);
194 if (ret >= 0) 193 if (ret >= 0)
@@ -529,7 +528,7 @@ static int wm8994_get_retune_mobile_enum(struct snd_kcontrol *kcontrol,
529 struct snd_ctl_elem_value *ucontrol) 528 struct snd_ctl_elem_value *ucontrol)
530{ 529{
531 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 530 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
532 struct wm8994_priv *wm8994 =snd_soc_codec_get_drvdata(codec); 531 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
533 int block = wm8994_get_retune_mobile_block(kcontrol->id.name); 532 int block = wm8994_get_retune_mobile_block(kcontrol->id.name);
534 533
535 ucontrol->value.enumerated.item[0] = wm8994->retune_mobile_cfg[block]; 534 ucontrol->value.enumerated.item[0] = wm8994->retune_mobile_cfg[block];
@@ -1103,6 +1102,13 @@ static int adc_mux_ev(struct snd_soc_dapm_widget *w,
1103 return 0; 1102 return 0;
1104} 1103}
1105 1104
1105static int micbias_ev(struct snd_soc_dapm_widget *w,
1106 struct snd_kcontrol *kcontrol, int event)
1107{
1108 late_enable_ev(w, kcontrol, event);
1109 return 0;
1110}
1111
1106static int dac_ev(struct snd_soc_dapm_widget *w, 1112static int dac_ev(struct snd_soc_dapm_widget *w,
1107 struct snd_kcontrol *kcontrol, int event) 1113 struct snd_kcontrol *kcontrol, int event)
1108{ 1114{
@@ -1440,6 +1446,10 @@ SND_SOC_DAPM_INPUT("DMIC1DAT"),
1440SND_SOC_DAPM_INPUT("DMIC2DAT"), 1446SND_SOC_DAPM_INPUT("DMIC2DAT"),
1441SND_SOC_DAPM_INPUT("Clock"), 1447SND_SOC_DAPM_INPUT("Clock"),
1442 1448
1449SND_SOC_DAPM_MICBIAS("MICBIAS", WM8994_MICBIAS, 2, 0),
1450SND_SOC_DAPM_SUPPLY_S("MICBIAS Supply", 1, SND_SOC_NOPM, 0, 0, micbias_ev,
1451 SND_SOC_DAPM_PRE_PMU),
1452
1443SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event, 1453SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event,
1444 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 1454 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1445 1455
@@ -1755,6 +1765,8 @@ static const struct snd_soc_dapm_route wm8994_revd_intercon[] = {
1755 { "AIF2DACDAT", NULL, "AIF1DACDAT" }, 1765 { "AIF2DACDAT", NULL, "AIF1DACDAT" },
1756 { "AIF1ADCDAT", NULL, "AIF2ADCDAT" }, 1766 { "AIF1ADCDAT", NULL, "AIF2ADCDAT" },
1757 { "AIF2ADCDAT", NULL, "AIF1ADCDAT" }, 1767 { "AIF2ADCDAT", NULL, "AIF1ADCDAT" },
1768 { "MICBIAS", NULL, "CLK_SYS" },
1769 { "MICBIAS", NULL, "MICBIAS Supply" },
1758}; 1770};
1759 1771
1760static const struct snd_soc_dapm_route wm8994_intercon[] = { 1772static const struct snd_soc_dapm_route wm8994_intercon[] = {
@@ -2883,6 +2895,13 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
2883 else 2895 else
2884 snd_soc_add_controls(wm8994->codec, wm8994_eq_controls, 2896 snd_soc_add_controls(wm8994->codec, wm8994_eq_controls,
2885 ARRAY_SIZE(wm8994_eq_controls)); 2897 ARRAY_SIZE(wm8994_eq_controls));
2898
2899 for (i = 0; i < ARRAY_SIZE(pdata->micbias); i++) {
2900 if (pdata->micbias[i]) {
2901 snd_soc_write(codec, WM8958_MICBIAS1 + i,
2902 pdata->micbias[i] & 0xffff);
2903 }
2904 }
2886} 2905}
2887 2906
2888/** 2907/**
@@ -2993,46 +3012,18 @@ static void wm8958_default_micdet(u16 status, void *data)
2993 int report = 0; 3012 int report = 0;
2994 3013
2995 /* If nothing present then clear our statuses */ 3014 /* If nothing present then clear our statuses */
2996 if (!(status & WM8958_MICD_STS)) { 3015 if (!(status & WM8958_MICD_STS))
2997 wm8994->jack_is_video = false;
2998 wm8994->jack_is_mic = false;
2999 goto done; 3016 goto done;
3000 }
3001 3017
3002 /* Assume anything over 475 ohms is a microphone and remember 3018 report = SND_JACK_MICROPHONE;
3003 * that we've seen one (since buttons override it) */
3004 if (status & 0x600)
3005 wm8994->jack_is_mic = true;
3006 if (wm8994->jack_is_mic)
3007 report |= SND_JACK_MICROPHONE;
3008
3009 /* Video has an impedence of approximately 75 ohms; assume
3010 * this isn't used as a button and remember it since buttons
3011 * override it. */
3012 if (status & 0x40)
3013 wm8994->jack_is_video = true;
3014 if (wm8994->jack_is_video)
3015 report |= SND_JACK_VIDEOOUT;
3016 3019
3017 /* Everything else is buttons; just assign slots */ 3020 /* Everything else is buttons; just assign slots */
3018 if (status & 0x4) 3021 if (status & 0x1c0)
3019 report |= SND_JACK_BTN_0; 3022 report |= SND_JACK_BTN_0;
3020 if (status & 0x8)
3021 report |= SND_JACK_BTN_1;
3022 if (status & 0x10)
3023 report |= SND_JACK_BTN_2;
3024 if (status & 0x20)
3025 report |= SND_JACK_BTN_3;
3026 if (status & 0x80)
3027 report |= SND_JACK_BTN_4;
3028 if (status & 0x100)
3029 report |= SND_JACK_BTN_5;
3030 3023
3031done: 3024done:
3032 snd_soc_jack_report(wm8994->micdet[0].jack, report, 3025 snd_soc_jack_report(wm8994->micdet[0].jack, report,
3033 SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2 | 3026 SND_JACK_BTN_0 | SND_JACK_MICROPHONE);
3034 SND_JACK_BTN_3 | SND_JACK_BTN_4 | SND_JACK_BTN_5 |
3035 SND_JACK_MICROPHONE | SND_JACK_VIDEOOUT);
3036} 3027}
3037 3028
3038/** 3029/**
@@ -3131,13 +3122,19 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3131 wm8994->pdata = dev_get_platdata(codec->dev->parent); 3122 wm8994->pdata = dev_get_platdata(codec->dev->parent);
3132 wm8994->codec = codec; 3123 wm8994->codec = codec;
3133 3124
3125 if (wm8994->pdata && wm8994->pdata->micdet_irq)
3126 wm8994->micdet_irq = wm8994->pdata->micdet_irq;
3127 else if (wm8994->pdata && wm8994->pdata->irq_base)
3128 wm8994->micdet_irq = wm8994->pdata->irq_base +
3129 WM8994_IRQ_MIC1_DET;
3130
3134 pm_runtime_enable(codec->dev); 3131 pm_runtime_enable(codec->dev);
3135 pm_runtime_resume(codec->dev); 3132 pm_runtime_resume(codec->dev);
3136 3133
3137 /* Read our current status back from the chip - we don't want to 3134 /* Read our current status back from the chip - we don't want to
3138 * reset as this may interfere with the GPIO or LDO operation. */ 3135 * reset as this may interfere with the GPIO or LDO operation. */
3139 for (i = 0; i < WM8994_CACHE_SIZE; i++) { 3136 for (i = 0; i < WM8994_CACHE_SIZE; i++) {
3140 if (!wm8994_readable(i) || wm8994_volatile(i)) 3137 if (!wm8994_readable(codec, i) || wm8994_volatile(codec, i))
3141 continue; 3138 continue;
3142 3139
3143 ret = wm8994_reg_read(codec->control_data, i); 3140 ret = wm8994_reg_read(codec->control_data, i);
@@ -3179,14 +3176,17 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3179 3176
3180 switch (control->type) { 3177 switch (control->type) {
3181 case WM8994: 3178 case WM8994:
3182 ret = wm8994_request_irq(codec->control_data, 3179 if (wm8994->micdet_irq) {
3183 WM8994_IRQ_MIC1_DET, 3180 ret = request_threaded_irq(wm8994->micdet_irq, NULL,
3184 wm8994_mic_irq, "Mic 1 detect", 3181 wm8994_mic_irq,
3185 wm8994); 3182 IRQF_TRIGGER_RISING,
3186 if (ret != 0) 3183 "Mic1 detect",
3187 dev_warn(codec->dev, 3184 wm8994);
3188 "Failed to request Mic1 detect IRQ: %d\n", 3185 if (ret != 0)
3189 ret); 3186 dev_warn(codec->dev,
3187 "Failed to request Mic1 detect IRQ: %d\n",
3188 ret);
3189 }
3190 3190
3191 ret = wm8994_request_irq(codec->control_data, 3191 ret = wm8994_request_irq(codec->control_data,
3192 WM8994_IRQ_MIC1_SHRT, 3192 WM8994_IRQ_MIC1_SHRT,
@@ -3217,15 +3217,17 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3217 break; 3217 break;
3218 3218
3219 case WM8958: 3219 case WM8958:
3220 ret = wm8994_request_irq(codec->control_data, 3220 if (wm8994->micdet_irq) {
3221 WM8994_IRQ_MIC1_DET, 3221 ret = request_threaded_irq(wm8994->micdet_irq, NULL,
3222 wm8958_mic_irq, "Mic detect", 3222 wm8958_mic_irq,
3223 wm8994); 3223 IRQF_TRIGGER_RISING,
3224 if (ret != 0) 3224 "Mic detect",
3225 dev_warn(codec->dev, 3225 wm8994);
3226 "Failed to request Mic detect IRQ: %d\n", 3226 if (ret != 0)
3227 ret); 3227 dev_warn(codec->dev,
3228 break; 3228 "Failed to request Mic detect IRQ: %d\n",
3229 ret);
3230 }
3229 } 3231 }
3230 3232
3231 /* Remember if AIFnLRCLK is configured as a GPIO. This should be 3233 /* Remember if AIFnLRCLK is configured as a GPIO. This should be
@@ -3369,7 +3371,8 @@ err_irq:
3369 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, wm8994); 3371 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, wm8994);
3370 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET, wm8994); 3372 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET, wm8994);
3371 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, wm8994); 3373 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, wm8994);
3372 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_DET, wm8994); 3374 if (wm8994->micdet_irq)
3375 free_irq(wm8994->micdet_irq, wm8994);
3373err: 3376err:
3374 kfree(wm8994); 3377 kfree(wm8994);
3375 return ret; 3378 return ret;
@@ -3386,8 +3389,8 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec)
3386 3389
3387 switch (control->type) { 3390 switch (control->type) {
3388 case WM8994: 3391 case WM8994:
3389 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, 3392 if (wm8994->micdet_irq)
3390 wm8994); 3393 free_irq(wm8994->micdet_irq, wm8994);
3391 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET, 3394 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET,
3392 wm8994); 3395 wm8994);
3393 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, 3396 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT,
@@ -3397,8 +3400,8 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec)
3397 break; 3400 break;
3398 3401
3399 case WM8958: 3402 case WM8958:
3400 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_DET, 3403 if (wm8994->micdet_irq)
3401 wm8994); 3404 free_irq(wm8994->micdet_irq, wm8994);
3402 break; 3405 break;
3403 } 3406 }
3404 kfree(wm8994->retune_mobile_texts); 3407 kfree(wm8994->retune_mobile_texts);
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h
index 0c355bfc88f1..999b8851226b 100644
--- a/sound/soc/codecs/wm8994.h
+++ b/sound/soc/codecs/wm8994.h
@@ -43,6 +43,6 @@ struct wm8994_access_mask {
43}; 43};
44 44
45extern const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE]; 45extern const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE];
46extern const __devinitdata u16 wm8994_reg_defaults[WM8994_CACHE_SIZE]; 46extern const u16 wm8994_reg_defaults[WM8994_CACHE_SIZE];
47 47
48#endif 48#endif
diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c
index 608c84c5aa8e..67eaaecbb42e 100644
--- a/sound/soc/codecs/wm8995.c
+++ b/sound/soc/codecs/wm8995.c
@@ -19,6 +19,7 @@
19#include <linux/pm.h> 19#include <linux/pm.h>
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include <linux/spi/spi.h> 21#include <linux/spi/spi.h>
22#include <linux/regulator/consumer.h>
22#include <linux/slab.h> 23#include <linux/slab.h>
23#include <sound/core.h> 24#include <sound/core.h>
24#include <sound/pcm.h> 25#include <sound/pcm.h>
@@ -30,6 +31,18 @@
30 31
31#include "wm8995.h" 32#include "wm8995.h"
32 33
34#define WM8995_NUM_SUPPLIES 8
35static const char *wm8995_supply_names[WM8995_NUM_SUPPLIES] = {
36 "DCVDD",
37 "DBVDD1",
38 "DBVDD2",
39 "DBVDD3",
40 "AVDD1",
41 "AVDD2",
42 "CPVDD",
43 "MICVDD"
44};
45
33static const u16 wm8995_reg_defs[WM8995_MAX_REGISTER + 1] = { 46static const u16 wm8995_reg_defs[WM8995_MAX_REGISTER + 1] = {
34 [0] = 0x8995, [5] = 0x0100, [16] = 0x000b, [17] = 0x000b, 47 [0] = 0x8995, [5] = 0x0100, [16] = 0x000b, [17] = 0x000b,
35 [24] = 0x02c0, [25] = 0x02c0, [26] = 0x02c0, [27] = 0x02c0, 48 [24] = 0x02c0, [25] = 0x02c0, [26] = 0x02c0, [27] = 0x02c0,
@@ -126,8 +139,37 @@ struct wm8995_priv {
126 int mclk[2]; 139 int mclk[2];
127 int aifclk[2]; 140 int aifclk[2];
128 struct fll_config fll[2], fll_suspend[2]; 141 struct fll_config fll[2], fll_suspend[2];
142 struct regulator_bulk_data supplies[WM8995_NUM_SUPPLIES];
143 struct notifier_block disable_nb[WM8995_NUM_SUPPLIES];
144 struct snd_soc_codec *codec;
129}; 145};
130 146
147/*
148 * We can't use the same notifier block for more than one supply and
149 * there's no way I can see to get from a callback to the caller
150 * except container_of().
151 */
152#define WM8995_REGULATOR_EVENT(n) \
153static int wm8995_regulator_event_##n(struct notifier_block *nb, \
154 unsigned long event, void *data) \
155{ \
156 struct wm8995_priv *wm8995 = container_of(nb, struct wm8995_priv, \
157 disable_nb[n]); \
158 if (event & REGULATOR_EVENT_DISABLE) { \
159 wm8995->codec->cache_sync = 1; \
160 } \
161 return 0; \
162}
163
164WM8995_REGULATOR_EVENT(0)
165WM8995_REGULATOR_EVENT(1)
166WM8995_REGULATOR_EVENT(2)
167WM8995_REGULATOR_EVENT(3)
168WM8995_REGULATOR_EVENT(4)
169WM8995_REGULATOR_EVENT(5)
170WM8995_REGULATOR_EVENT(6)
171WM8995_REGULATOR_EVENT(7)
172
131static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1); 173static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
132static const DECLARE_TLV_DB_SCALE(in1lr_pga_tlv, -1650, 150, 0); 174static const DECLARE_TLV_DB_SCALE(in1lr_pga_tlv, -1650, 150, 0);
133static const DECLARE_TLV_DB_SCALE(in1l_boost_tlv, 0, 600, 0); 175static const DECLARE_TLV_DB_SCALE(in1l_boost_tlv, 0, 600, 0);
@@ -909,7 +951,7 @@ static const struct snd_soc_dapm_route wm8995_intercon[] = {
909 { "SPK2R", NULL, "SPK2R Driver" } 951 { "SPK2R", NULL, "SPK2R Driver" }
910}; 952};
911 953
912static int wm8995_volatile(unsigned int reg) 954static int wm8995_volatile(struct snd_soc_codec *codec, unsigned int reg)
913{ 955{
914 /* out of bounds registers are generally considered 956 /* out of bounds registers are generally considered
915 * volatile to support register banks that are partially 957 * volatile to support register banks that are partially
@@ -1483,6 +1525,11 @@ static int wm8995_set_bias_level(struct snd_soc_codec *codec,
1483 break; 1525 break;
1484 case SND_SOC_BIAS_STANDBY: 1526 case SND_SOC_BIAS_STANDBY:
1485 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { 1527 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1528 ret = regulator_bulk_enable(ARRAY_SIZE(wm8995->supplies),
1529 wm8995->supplies);
1530 if (ret)
1531 return ret;
1532
1486 ret = snd_soc_cache_sync(codec); 1533 ret = snd_soc_cache_sync(codec);
1487 if (ret) { 1534 if (ret) {
1488 dev_err(codec->dev, 1535 dev_err(codec->dev,
@@ -1492,12 +1539,13 @@ static int wm8995_set_bias_level(struct snd_soc_codec *codec,
1492 1539
1493 snd_soc_update_bits(codec, WM8995_POWER_MANAGEMENT_1, 1540 snd_soc_update_bits(codec, WM8995_POWER_MANAGEMENT_1,
1494 WM8995_BG_ENA_MASK, WM8995_BG_ENA); 1541 WM8995_BG_ENA_MASK, WM8995_BG_ENA);
1495
1496 } 1542 }
1497 break; 1543 break;
1498 case SND_SOC_BIAS_OFF: 1544 case SND_SOC_BIAS_OFF:
1499 snd_soc_update_bits(codec, WM8995_POWER_MANAGEMENT_1, 1545 snd_soc_update_bits(codec, WM8995_POWER_MANAGEMENT_1,
1500 WM8995_BG_ENA_MASK, 0); 1546 WM8995_BG_ENA_MASK, 0);
1547 regulator_bulk_disable(ARRAY_SIZE(wm8995->supplies),
1548 wm8995->supplies);
1501 break; 1549 break;
1502 } 1550 }
1503 1551
@@ -1536,10 +1584,12 @@ static int wm8995_remove(struct snd_soc_codec *codec)
1536static int wm8995_probe(struct snd_soc_codec *codec) 1584static int wm8995_probe(struct snd_soc_codec *codec)
1537{ 1585{
1538 struct wm8995_priv *wm8995; 1586 struct wm8995_priv *wm8995;
1587 int i;
1539 int ret; 1588 int ret;
1540 1589
1541 codec->dapm.idle_bias_off = 1; 1590 codec->dapm.idle_bias_off = 1;
1542 wm8995 = snd_soc_codec_get_drvdata(codec); 1591 wm8995 = snd_soc_codec_get_drvdata(codec);
1592 wm8995->codec = codec;
1543 1593
1544 ret = snd_soc_codec_set_cache_io(codec, 16, 16, wm8995->control_type); 1594 ret = snd_soc_codec_set_cache_io(codec, 16, 16, wm8995->control_type);
1545 if (ret < 0) { 1595 if (ret < 0) {
@@ -1547,21 +1597,58 @@ static int wm8995_probe(struct snd_soc_codec *codec)
1547 return ret; 1597 return ret;
1548 } 1598 }
1549 1599
1600 for (i = 0; i < ARRAY_SIZE(wm8995->supplies); i++)
1601 wm8995->supplies[i].supply = wm8995_supply_names[i];
1602
1603 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8995->supplies),
1604 wm8995->supplies);
1605 if (ret) {
1606 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
1607 return ret;
1608 }
1609
1610 wm8995->disable_nb[0].notifier_call = wm8995_regulator_event_0;
1611 wm8995->disable_nb[1].notifier_call = wm8995_regulator_event_1;
1612 wm8995->disable_nb[2].notifier_call = wm8995_regulator_event_2;
1613 wm8995->disable_nb[3].notifier_call = wm8995_regulator_event_3;
1614 wm8995->disable_nb[4].notifier_call = wm8995_regulator_event_4;
1615 wm8995->disable_nb[5].notifier_call = wm8995_regulator_event_5;
1616 wm8995->disable_nb[6].notifier_call = wm8995_regulator_event_6;
1617 wm8995->disable_nb[7].notifier_call = wm8995_regulator_event_7;
1618
1619 /* This should really be moved into the regulator core */
1620 for (i = 0; i < ARRAY_SIZE(wm8995->supplies); i++) {
1621 ret = regulator_register_notifier(wm8995->supplies[i].consumer,
1622 &wm8995->disable_nb[i]);
1623 if (ret) {
1624 dev_err(codec->dev,
1625 "Failed to register regulator notifier: %d\n",
1626 ret);
1627 }
1628 }
1629
1630 ret = regulator_bulk_enable(ARRAY_SIZE(wm8995->supplies),
1631 wm8995->supplies);
1632 if (ret) {
1633 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
1634 goto err_reg_get;
1635 }
1636
1550 ret = snd_soc_read(codec, WM8995_SOFTWARE_RESET); 1637 ret = snd_soc_read(codec, WM8995_SOFTWARE_RESET);
1551 if (ret < 0) { 1638 if (ret < 0) {
1552 dev_err(codec->dev, "Failed to read device ID: %d\n", ret); 1639 dev_err(codec->dev, "Failed to read device ID: %d\n", ret);
1553 return ret; 1640 goto err_reg_enable;
1554 } 1641 }
1555 1642
1556 if (ret != 0x8995) { 1643 if (ret != 0x8995) {
1557 dev_err(codec->dev, "Invalid device ID: %#x\n", ret); 1644 dev_err(codec->dev, "Invalid device ID: %#x\n", ret);
1558 return -EINVAL; 1645 goto err_reg_enable;
1559 } 1646 }
1560 1647
1561 ret = snd_soc_write(codec, WM8995_SOFTWARE_RESET, 0); 1648 ret = snd_soc_write(codec, WM8995_SOFTWARE_RESET, 0);
1562 if (ret < 0) { 1649 if (ret < 0) {
1563 dev_err(codec->dev, "Failed to issue reset: %d\n", ret); 1650 dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
1564 return ret; 1651 goto err_reg_enable;
1565 } 1652 }
1566 1653
1567 wm8995_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1654 wm8995_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
@@ -1596,6 +1683,12 @@ static int wm8995_probe(struct snd_soc_codec *codec)
1596 ARRAY_SIZE(wm8995_intercon)); 1683 ARRAY_SIZE(wm8995_intercon));
1597 1684
1598 return 0; 1685 return 0;
1686
1687err_reg_enable:
1688 regulator_bulk_disable(ARRAY_SIZE(wm8995->supplies), wm8995->supplies);
1689err_reg_get:
1690 regulator_bulk_free(ARRAY_SIZE(wm8995->supplies), wm8995->supplies);
1691 return ret;
1599} 1692}
1600 1693
1601#define WM8995_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 1694#define WM8995_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c
index cce704c275c6..55cdf2982020 100644
--- a/sound/soc/codecs/wm9081.c
+++ b/sound/soc/codecs/wm9081.c
@@ -167,10 +167,10 @@ struct wm9081_priv {
167 int fll_fref; 167 int fll_fref;
168 int fll_fout; 168 int fll_fout;
169 int tdm_width; 169 int tdm_width;
170 struct wm9081_retune_mobile_config *retune; 170 struct wm9081_pdata pdata;
171}; 171};
172 172
173static int wm9081_volatile_register(unsigned int reg) 173static int wm9081_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
174{ 174{
175 switch (reg) { 175 switch (reg) {
176 case WM9081_SOFTWARE_RESET: 176 case WM9081_SOFTWARE_RESET:
@@ -389,27 +389,6 @@ SOC_DAPM_SINGLE("IN2 Switch", WM9081_ANALOGUE_MIXER, 2, 1, 0),
389SOC_DAPM_SINGLE("Playback Switch", WM9081_ANALOGUE_MIXER, 4, 1, 0), 389SOC_DAPM_SINGLE("Playback Switch", WM9081_ANALOGUE_MIXER, 4, 1, 0),
390}; 390};
391 391
392static int speaker_event(struct snd_soc_dapm_widget *w,
393 struct snd_kcontrol *kcontrol, int event)
394{
395 struct snd_soc_codec *codec = w->codec;
396 unsigned int reg = snd_soc_read(codec, WM9081_POWER_MANAGEMENT);
397
398 switch (event) {
399 case SND_SOC_DAPM_POST_PMU:
400 reg |= WM9081_SPK_ENA;
401 break;
402
403 case SND_SOC_DAPM_PRE_PMD:
404 reg &= ~WM9081_SPK_ENA;
405 break;
406 }
407
408 snd_soc_write(codec, WM9081_POWER_MANAGEMENT, reg);
409
410 return 0;
411}
412
413struct _fll_div { 392struct _fll_div {
414 u16 fll_fratio; 393 u16 fll_fratio;
415 u16 fll_outdiv; 394 u16 fll_outdiv;
@@ -747,9 +726,8 @@ SND_SOC_DAPM_MIXER_NAMED_CTL("Mixer", SND_SOC_NOPM, 0, 0,
747 726
748SND_SOC_DAPM_PGA("LINEOUT PGA", WM9081_POWER_MANAGEMENT, 4, 0, NULL, 0), 727SND_SOC_DAPM_PGA("LINEOUT PGA", WM9081_POWER_MANAGEMENT, 4, 0, NULL, 0),
749 728
750SND_SOC_DAPM_PGA_E("Speaker PGA", WM9081_POWER_MANAGEMENT, 2, 0, NULL, 0, 729SND_SOC_DAPM_PGA("Speaker PGA", WM9081_POWER_MANAGEMENT, 2, 0, NULL, 0),
751 speaker_event, 730SND_SOC_DAPM_PGA("Speaker", WM9081_POWER_MANAGEMENT, 1, 0, NULL, 0),
752 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
753 731
754SND_SOC_DAPM_OUTPUT("LINEOUT"), 732SND_SOC_DAPM_OUTPUT("LINEOUT"),
755SND_SOC_DAPM_OUTPUT("SPKN"), 733SND_SOC_DAPM_OUTPUT("SPKN"),
@@ -762,7 +740,7 @@ SND_SOC_DAPM_SUPPLY("TOCLK", WM9081_CLOCK_CONTROL_3, 2, 0, NULL, 0),
762}; 740};
763 741
764 742
765static const struct snd_soc_dapm_route audio_paths[] = { 743static const struct snd_soc_dapm_route wm9081_audio_paths[] = {
766 { "DAC", NULL, "CLK_SYS" }, 744 { "DAC", NULL, "CLK_SYS" },
767 { "DAC", NULL, "CLK_DSP" }, 745 { "DAC", NULL, "CLK_DSP" },
768 746
@@ -780,8 +758,10 @@ static const struct snd_soc_dapm_route audio_paths[] = {
780 { "Speaker PGA", NULL, "TOCLK" }, 758 { "Speaker PGA", NULL, "TOCLK" },
781 { "Speaker PGA", NULL, "CLK_SYS" }, 759 { "Speaker PGA", NULL, "CLK_SYS" },
782 760
783 { "SPKN", NULL, "Speaker PGA" }, 761 { "Speaker", NULL, "Speaker PGA" },
784 { "SPKP", NULL, "Speaker PGA" }, 762
763 { "SPKN", NULL, "Speaker" },
764 { "SPKP", NULL, "Speaker" },
785}; 765};
786 766
787static int wm9081_set_bias_level(struct snd_soc_codec *codec, 767static int wm9081_set_bias_level(struct snd_soc_codec *codec,
@@ -1082,21 +1062,22 @@ static int wm9081_hw_params(struct snd_pcm_substream *substream,
1082 aif4 |= wm9081->bclk / wm9081->fs; 1062 aif4 |= wm9081->bclk / wm9081->fs;
1083 1063
1084 /* Apply a ReTune Mobile configuration if it's in use */ 1064 /* Apply a ReTune Mobile configuration if it's in use */
1085 if (wm9081->retune) { 1065 if (wm9081->pdata.num_retune_configs) {
1086 struct wm9081_retune_mobile_config *retune = wm9081->retune; 1066 struct wm9081_pdata *pdata = &wm9081->pdata;
1087 struct wm9081_retune_mobile_setting *s; 1067 struct wm9081_retune_mobile_setting *s;
1088 int eq1; 1068 int eq1;
1089 1069
1090 best = 0; 1070 best = 0;
1091 best_val = abs(retune->configs[0].rate - wm9081->fs); 1071 best_val = abs(pdata->retune_configs[0].rate - wm9081->fs);
1092 for (i = 0; i < retune->num_configs; i++) { 1072 for (i = 0; i < pdata->num_retune_configs; i++) {
1093 cur_val = abs(retune->configs[i].rate - wm9081->fs); 1073 cur_val = abs(pdata->retune_configs[i].rate -
1074 wm9081->fs);
1094 if (cur_val < best_val) { 1075 if (cur_val < best_val) {
1095 best_val = cur_val; 1076 best_val = cur_val;
1096 best = i; 1077 best = i;
1097 } 1078 }
1098 } 1079 }
1099 s = &retune->configs[best]; 1080 s = &pdata->retune_configs[best];
1100 1081
1101 dev_dbg(codec->dev, "ReTune Mobile %s tuned for %dHz\n", 1082 dev_dbg(codec->dev, "ReTune Mobile %s tuned for %dHz\n",
1102 s->name, s->rate); 1083 s->name, s->rate);
@@ -1139,10 +1120,9 @@ static int wm9081_digital_mute(struct snd_soc_dai *codec_dai, int mute)
1139 return 0; 1120 return 0;
1140} 1121}
1141 1122
1142static int wm9081_set_sysclk(struct snd_soc_dai *codec_dai, 1123static int wm9081_set_sysclk(struct snd_soc_codec *codec,
1143 int clk_id, unsigned int freq, int dir) 1124 int clk_id, unsigned int freq, int dir)
1144{ 1125{
1145 struct snd_soc_codec *codec = codec_dai->codec;
1146 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec); 1126 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
1147 1127
1148 switch (clk_id) { 1128 switch (clk_id) {
@@ -1207,7 +1187,6 @@ static int wm9081_set_tdm_slot(struct snd_soc_dai *dai,
1207 1187
1208static struct snd_soc_dai_ops wm9081_dai_ops = { 1188static struct snd_soc_dai_ops wm9081_dai_ops = {
1209 .hw_params = wm9081_hw_params, 1189 .hw_params = wm9081_hw_params,
1210 .set_sysclk = wm9081_set_sysclk,
1211 .set_fmt = wm9081_set_dai_fmt, 1190 .set_fmt = wm9081_set_dai_fmt,
1212 .digital_mute = wm9081_digital_mute, 1191 .digital_mute = wm9081_digital_mute,
1213 .set_tdm_slot = wm9081_set_tdm_slot, 1192 .set_tdm_slot = wm9081_set_tdm_slot,
@@ -1231,7 +1210,6 @@ static struct snd_soc_dai_driver wm9081_dai = {
1231static int wm9081_probe(struct snd_soc_codec *codec) 1210static int wm9081_probe(struct snd_soc_codec *codec)
1232{ 1211{
1233 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec); 1212 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
1234 struct snd_soc_dapm_context *dapm = &codec->dapm;
1235 int ret; 1213 int ret;
1236 u16 reg; 1214 u16 reg;
1237 1215
@@ -1255,6 +1233,14 @@ static int wm9081_probe(struct snd_soc_codec *codec)
1255 return ret; 1233 return ret;
1256 } 1234 }
1257 1235
1236 reg = 0;
1237 if (wm9081->pdata.irq_high)
1238 reg |= WM9081_IRQ_POL;
1239 if (!wm9081->pdata.irq_cmos)
1240 reg |= WM9081_IRQ_OP_CTRL;
1241 snd_soc_update_bits(codec, WM9081_INTERRUPT_CONTROL,
1242 WM9081_IRQ_POL | WM9081_IRQ_OP_CTRL, reg);
1243
1258 wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1244 wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1259 1245
1260 /* Enable zero cross by default */ 1246 /* Enable zero cross by default */
@@ -1266,17 +1252,13 @@ static int wm9081_probe(struct snd_soc_codec *codec)
1266 1252
1267 snd_soc_add_controls(codec, wm9081_snd_controls, 1253 snd_soc_add_controls(codec, wm9081_snd_controls,
1268 ARRAY_SIZE(wm9081_snd_controls)); 1254 ARRAY_SIZE(wm9081_snd_controls));
1269 if (!wm9081->retune) { 1255 if (!wm9081->pdata.num_retune_configs) {
1270 dev_dbg(codec->dev, 1256 dev_dbg(codec->dev,
1271 "No ReTune Mobile data, using normal EQ\n"); 1257 "No ReTune Mobile data, using normal EQ\n");
1272 snd_soc_add_controls(codec, wm9081_eq_controls, 1258 snd_soc_add_controls(codec, wm9081_eq_controls,
1273 ARRAY_SIZE(wm9081_eq_controls)); 1259 ARRAY_SIZE(wm9081_eq_controls));
1274 } 1260 }
1275 1261
1276 snd_soc_dapm_new_controls(dapm, wm9081_dapm_widgets,
1277 ARRAY_SIZE(wm9081_dapm_widgets));
1278 snd_soc_dapm_add_routes(dapm, audio_paths, ARRAY_SIZE(audio_paths));
1279
1280 return ret; 1262 return ret;
1281} 1263}
1282 1264
@@ -1320,11 +1302,19 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9081 = {
1320 .remove = wm9081_remove, 1302 .remove = wm9081_remove,
1321 .suspend = wm9081_suspend, 1303 .suspend = wm9081_suspend,
1322 .resume = wm9081_resume, 1304 .resume = wm9081_resume,
1305
1306 .set_sysclk = wm9081_set_sysclk,
1323 .set_bias_level = wm9081_set_bias_level, 1307 .set_bias_level = wm9081_set_bias_level,
1308
1324 .reg_cache_size = ARRAY_SIZE(wm9081_reg_defaults), 1309 .reg_cache_size = ARRAY_SIZE(wm9081_reg_defaults),
1325 .reg_word_size = sizeof(u16), 1310 .reg_word_size = sizeof(u16),
1326 .reg_cache_default = wm9081_reg_defaults, 1311 .reg_cache_default = wm9081_reg_defaults,
1327 .volatile_register = wm9081_volatile_register, 1312 .volatile_register = wm9081_volatile_register,
1313
1314 .dapm_widgets = wm9081_dapm_widgets,
1315 .num_dapm_widgets = ARRAY_SIZE(wm9081_dapm_widgets),
1316 .dapm_routes = wm9081_audio_paths,
1317 .num_dapm_routes = ARRAY_SIZE(wm9081_audio_paths),
1328}; 1318};
1329 1319
1330#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1320#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
@@ -1343,8 +1333,8 @@ static __devinit int wm9081_i2c_probe(struct i2c_client *i2c,
1343 wm9081->control_data = i2c; 1333 wm9081->control_data = i2c;
1344 1334
1345 if (dev_get_platdata(&i2c->dev)) 1335 if (dev_get_platdata(&i2c->dev))
1346 memcpy(&wm9081->retune, dev_get_platdata(&i2c->dev), 1336 memcpy(&wm9081->pdata, dev_get_platdata(&i2c->dev),
1347 sizeof(wm9081->retune)); 1337 sizeof(wm9081->pdata));
1348 1338
1349 ret = snd_soc_register_codec(&i2c->dev, 1339 ret = snd_soc_register_codec(&i2c->dev,
1350 &soc_codec_dev_wm9081, &wm9081_dai, 1); 1340 &soc_codec_dev_wm9081, &wm9081_dai, 1);
@@ -1368,7 +1358,7 @@ MODULE_DEVICE_TABLE(i2c, wm9081_i2c_id);
1368 1358
1369static struct i2c_driver wm9081_i2c_driver = { 1359static struct i2c_driver wm9081_i2c_driver = {
1370 .driver = { 1360 .driver = {
1371 .name = "wm9081-codec", 1361 .name = "wm9081",
1372 .owner = THIS_MODULE, 1362 .owner = THIS_MODULE,
1373 }, 1363 },
1374 .probe = wm9081_i2c_probe, 1364 .probe = wm9081_i2c_probe,
diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c
index a788c4297046..4de12203e611 100644
--- a/sound/soc/codecs/wm9090.c
+++ b/sound/soc/codecs/wm9090.c
@@ -144,7 +144,7 @@ struct wm9090_priv {
144 void *control_data; 144 void *control_data;
145}; 145};
146 146
147static int wm9090_volatile(unsigned int reg) 147static int wm9090_volatile(struct snd_soc_codec *codec, unsigned int reg)
148{ 148{
149 switch (reg) { 149 switch (reg) {
150 case WM9090_SOFTWARE_RESET: 150 case WM9090_SOFTWARE_RESET:
@@ -518,7 +518,7 @@ static int wm9090_set_bias_level(struct snd_soc_codec *codec,
518 for (i = 1; i < codec->driver->reg_cache_size; i++) { 518 for (i = 1; i < codec->driver->reg_cache_size; i++) {
519 if (reg_cache[i] == wm9090_reg_defaults[i]) 519 if (reg_cache[i] == wm9090_reg_defaults[i])
520 continue; 520 continue;
521 if (wm9090_volatile(i)) 521 if (wm9090_volatile(codec, i))
522 continue; 522 continue;
523 523
524 ret = snd_soc_write(codec, i, reg_cache[i]); 524 ret = snd_soc_write(codec, i, reg_cache[i]);
@@ -551,7 +551,6 @@ static int wm9090_set_bias_level(struct snd_soc_codec *codec,
551static int wm9090_probe(struct snd_soc_codec *codec) 551static int wm9090_probe(struct snd_soc_codec *codec)
552{ 552{
553 struct wm9090_priv *wm9090 = snd_soc_codec_get_drvdata(codec); 553 struct wm9090_priv *wm9090 = snd_soc_codec_get_drvdata(codec);
554 u16 *reg_cache = codec->reg_cache;
555 int ret; 554 int ret;
556 555
557 codec->control_data = wm9090->control_data; 556 codec->control_data = wm9090->control_data;
@@ -576,22 +575,30 @@ static int wm9090_probe(struct snd_soc_codec *codec)
576 /* Configure some defaults; they will be written out when we 575 /* Configure some defaults; they will be written out when we
577 * bring the bias up. 576 * bring the bias up.
578 */ 577 */
579 reg_cache[WM9090_IN1_LINE_INPUT_A_VOLUME] |= WM9090_IN1_VU 578 snd_soc_update_bits(codec, WM9090_IN1_LINE_INPUT_A_VOLUME,
580 | WM9090_IN1A_ZC; 579 WM9090_IN1_VU | WM9090_IN1A_ZC,
581 reg_cache[WM9090_IN1_LINE_INPUT_B_VOLUME] |= WM9090_IN1_VU 580 WM9090_IN1_VU | WM9090_IN1A_ZC);
582 | WM9090_IN1B_ZC; 581 snd_soc_update_bits(codec, WM9090_IN1_LINE_INPUT_B_VOLUME,
583 reg_cache[WM9090_IN2_LINE_INPUT_A_VOLUME] |= WM9090_IN2_VU 582 WM9090_IN1_VU | WM9090_IN1B_ZC,
584 | WM9090_IN2A_ZC; 583 WM9090_IN1_VU | WM9090_IN1B_ZC);
585 reg_cache[WM9090_IN2_LINE_INPUT_B_VOLUME] |= WM9090_IN2_VU 584 snd_soc_update_bits(codec, WM9090_IN2_LINE_INPUT_A_VOLUME,
586 | WM9090_IN2B_ZC; 585 WM9090_IN2_VU | WM9090_IN2A_ZC,
587 reg_cache[WM9090_SPEAKER_VOLUME_LEFT] |= 586 WM9090_IN2_VU | WM9090_IN2A_ZC);
588 WM9090_SPKOUT_VU | WM9090_SPKOUTL_ZC; 587 snd_soc_update_bits(codec, WM9090_IN2_LINE_INPUT_B_VOLUME,
589 reg_cache[WM9090_LEFT_OUTPUT_VOLUME] |= 588 WM9090_IN2_VU | WM9090_IN2B_ZC,
590 WM9090_HPOUT1_VU | WM9090_HPOUT1L_ZC; 589 WM9090_IN2_VU | WM9090_IN2B_ZC);
591 reg_cache[WM9090_RIGHT_OUTPUT_VOLUME] |= 590 snd_soc_update_bits(codec, WM9090_SPEAKER_VOLUME_LEFT,
592 WM9090_HPOUT1_VU | WM9090_HPOUT1R_ZC; 591 WM9090_SPKOUT_VU | WM9090_SPKOUTL_ZC,
593 592 WM9090_SPKOUT_VU | WM9090_SPKOUTL_ZC);
594 reg_cache[WM9090_CLOCKING_1] |= WM9090_TOCLK_ENA; 593 snd_soc_update_bits(codec, WM9090_LEFT_OUTPUT_VOLUME,
594 WM9090_HPOUT1_VU | WM9090_HPOUT1L_ZC,
595 WM9090_HPOUT1_VU | WM9090_HPOUT1L_ZC);
596 snd_soc_update_bits(codec, WM9090_RIGHT_OUTPUT_VOLUME,
597 WM9090_HPOUT1_VU | WM9090_HPOUT1R_ZC,
598 WM9090_HPOUT1_VU | WM9090_HPOUT1R_ZC);
599
600 snd_soc_update_bits(codec, WM9090_CLOCKING_1,
601 WM9090_TOCLK_ENA, WM9090_TOCLK_ENA);
595 602
596 wm9090_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 603 wm9090_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
597 604
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index 516892706063..7b6b3c18e299 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -82,7 +82,8 @@ static void wait_for_dc_servo(struct snd_soc_codec *codec, unsigned int op)
82 } while (reg & op && count < 400); 82 } while (reg & op && count < 400);
83 83
84 if (reg & op) 84 if (reg & op)
85 dev_err(codec->dev, "Timed out waiting for DC Servo\n"); 85 dev_err(codec->dev, "Timed out waiting for DC Servo %x\n",
86 op);
86} 87}
87 88
88/* 89/*
diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c
index 9e0e565e6ed9..d0d60b8a54d4 100644
--- a/sound/soc/davinci/davinci-i2s.c
+++ b/sound/soc/davinci/davinci-i2s.c
@@ -658,7 +658,7 @@ static int davinci_i2s_probe(struct platform_device *pdev)
658 return -ENODEV; 658 return -ENODEV;
659 } 659 }
660 660
661 ioarea = request_mem_region(mem->start, (mem->end - mem->start) + 1, 661 ioarea = request_mem_region(mem->start, resource_size(mem),
662 pdev->name); 662 pdev->name);
663 if (!ioarea) { 663 if (!ioarea) {
664 dev_err(&pdev->dev, "McBSP region already claimed\n"); 664 dev_err(&pdev->dev, "McBSP region already claimed\n");
@@ -694,20 +694,25 @@ static int davinci_i2s_probe(struct platform_device *pdev)
694 } 694 }
695 clk_enable(dev->clk); 695 clk_enable(dev->clk);
696 696
697 dev->base = (void __iomem *)IO_ADDRESS(mem->start); 697 dev->base = ioremap(mem->start, resource_size(mem));
698 if (!dev->base) {
699 dev_err(&pdev->dev, "ioremap failed\n");
700 ret = -ENOMEM;
701 goto err_release_clk;
702 }
698 703
699 dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].dma_addr = 704 dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].dma_addr =
700 (dma_addr_t)(io_v2p(dev->base) + DAVINCI_MCBSP_DXR_REG); 705 (dma_addr_t)(mem->start + DAVINCI_MCBSP_DXR_REG);
701 706
702 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].dma_addr = 707 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].dma_addr =
703 (dma_addr_t)(io_v2p(dev->base) + DAVINCI_MCBSP_DRR_REG); 708 (dma_addr_t)(mem->start + DAVINCI_MCBSP_DRR_REG);
704 709
705 /* first TX, then RX */ 710 /* first TX, then RX */
706 res = platform_get_resource(pdev, IORESOURCE_DMA, 0); 711 res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
707 if (!res) { 712 if (!res) {
708 dev_err(&pdev->dev, "no DMA resource\n"); 713 dev_err(&pdev->dev, "no DMA resource\n");
709 ret = -ENXIO; 714 ret = -ENXIO;
710 goto err_free_mem; 715 goto err_iounmap;
711 } 716 }
712 dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].channel = res->start; 717 dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].channel = res->start;
713 718
@@ -715,7 +720,7 @@ static int davinci_i2s_probe(struct platform_device *pdev)
715 if (!res) { 720 if (!res) {
716 dev_err(&pdev->dev, "no DMA resource\n"); 721 dev_err(&pdev->dev, "no DMA resource\n");
717 ret = -ENXIO; 722 ret = -ENXIO;
718 goto err_free_mem; 723 goto err_iounmap;
719 } 724 }
720 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].channel = res->start; 725 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].channel = res->start;
721 dev->dev = &pdev->dev; 726 dev->dev = &pdev->dev;
@@ -724,14 +729,19 @@ static int davinci_i2s_probe(struct platform_device *pdev)
724 729
725 ret = snd_soc_register_dai(&pdev->dev, &davinci_i2s_dai); 730 ret = snd_soc_register_dai(&pdev->dev, &davinci_i2s_dai);
726 if (ret != 0) 731 if (ret != 0)
727 goto err_free_mem; 732 goto err_iounmap;
728 733
729 return 0; 734 return 0;
730 735
736err_iounmap:
737 iounmap(dev->base);
738err_release_clk:
739 clk_disable(dev->clk);
740 clk_put(dev->clk);
731err_free_mem: 741err_free_mem:
732 kfree(dev); 742 kfree(dev);
733err_release_region: 743err_release_region:
734 release_mem_region(mem->start, (mem->end - mem->start) + 1); 744 release_mem_region(mem->start, resource_size(mem));
735 745
736 return ret; 746 return ret;
737} 747}
@@ -747,7 +757,7 @@ static int davinci_i2s_remove(struct platform_device *pdev)
747 dev->clk = NULL; 757 dev->clk = NULL;
748 kfree(dev); 758 kfree(dev);
749 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 759 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
750 release_mem_region(mem->start, (mem->end - mem->start) + 1); 760 release_mem_region(mem->start, resource_size(mem));
751 761
752 return 0; 762 return 0;
753} 763}
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index fb55d2c5d704..a5af834c8ef5 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -868,7 +868,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
868 } 868 }
869 869
870 ioarea = request_mem_region(mem->start, 870 ioarea = request_mem_region(mem->start,
871 (mem->end - mem->start) + 1, pdev->name); 871 resource_size(mem), pdev->name);
872 if (!ioarea) { 872 if (!ioarea) {
873 dev_err(&pdev->dev, "Audio region already claimed\n"); 873 dev_err(&pdev->dev, "Audio region already claimed\n");
874 ret = -EBUSY; 874 ret = -EBUSY;
@@ -885,7 +885,13 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
885 clk_enable(dev->clk); 885 clk_enable(dev->clk);
886 dev->clk_active = 1; 886 dev->clk_active = 1;
887 887
888 dev->base = (void __iomem *)IO_ADDRESS(mem->start); 888 dev->base = ioremap(mem->start, resource_size(mem));
889 if (!dev->base) {
890 dev_err(&pdev->dev, "ioremap failed\n");
891 ret = -ENOMEM;
892 goto err_release_clk;
893 }
894
889 dev->op_mode = pdata->op_mode; 895 dev->op_mode = pdata->op_mode;
890 dev->tdm_slots = pdata->tdm_slots; 896 dev->tdm_slots = pdata->tdm_slots;
891 dev->num_serializer = pdata->num_serializer; 897 dev->num_serializer = pdata->num_serializer;
@@ -899,14 +905,14 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
899 dma_data->asp_chan_q = pdata->asp_chan_q; 905 dma_data->asp_chan_q = pdata->asp_chan_q;
900 dma_data->ram_chan_q = pdata->ram_chan_q; 906 dma_data->ram_chan_q = pdata->ram_chan_q;
901 dma_data->dma_addr = (dma_addr_t) (pdata->tx_dma_offset + 907 dma_data->dma_addr = (dma_addr_t) (pdata->tx_dma_offset +
902 io_v2p(dev->base)); 908 mem->start);
903 909
904 /* first TX, then RX */ 910 /* first TX, then RX */
905 res = platform_get_resource(pdev, IORESOURCE_DMA, 0); 911 res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
906 if (!res) { 912 if (!res) {
907 dev_err(&pdev->dev, "no DMA resource\n"); 913 dev_err(&pdev->dev, "no DMA resource\n");
908 ret = -ENODEV; 914 ret = -ENODEV;
909 goto err_release_region; 915 goto err_iounmap;
910 } 916 }
911 917
912 dma_data->channel = res->start; 918 dma_data->channel = res->start;
@@ -915,13 +921,13 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
915 dma_data->asp_chan_q = pdata->asp_chan_q; 921 dma_data->asp_chan_q = pdata->asp_chan_q;
916 dma_data->ram_chan_q = pdata->ram_chan_q; 922 dma_data->ram_chan_q = pdata->ram_chan_q;
917 dma_data->dma_addr = (dma_addr_t)(pdata->rx_dma_offset + 923 dma_data->dma_addr = (dma_addr_t)(pdata->rx_dma_offset +
918 io_v2p(dev->base)); 924 mem->start);
919 925
920 res = platform_get_resource(pdev, IORESOURCE_DMA, 1); 926 res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
921 if (!res) { 927 if (!res) {
922 dev_err(&pdev->dev, "no DMA resource\n"); 928 dev_err(&pdev->dev, "no DMA resource\n");
923 ret = -ENODEV; 929 ret = -ENODEV;
924 goto err_release_region; 930 goto err_iounmap;
925 } 931 }
926 932
927 dma_data->channel = res->start; 933 dma_data->channel = res->start;
@@ -929,11 +935,16 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
929 ret = snd_soc_register_dai(&pdev->dev, &davinci_mcasp_dai[pdata->op_mode]); 935 ret = snd_soc_register_dai(&pdev->dev, &davinci_mcasp_dai[pdata->op_mode]);
930 936
931 if (ret != 0) 937 if (ret != 0)
932 goto err_release_region; 938 goto err_iounmap;
933 return 0; 939 return 0;
934 940
941err_iounmap:
942 iounmap(dev->base);
943err_release_clk:
944 clk_disable(dev->clk);
945 clk_put(dev->clk);
935err_release_region: 946err_release_region:
936 release_mem_region(mem->start, (mem->end - mem->start) + 1); 947 release_mem_region(mem->start, resource_size(mem));
937err_release_data: 948err_release_data:
938 kfree(dev); 949 kfree(dev);
939 950
@@ -951,7 +962,7 @@ static int davinci_mcasp_remove(struct platform_device *pdev)
951 dev->clk = NULL; 962 dev->clk = NULL;
952 963
953 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 964 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
954 release_mem_region(mem->start, (mem->end - mem->start) + 1); 965 release_mem_region(mem->start, resource_size(mem));
955 966
956 kfree(dev); 967 kfree(dev);
957 968
diff --git a/sound/soc/ep93xx/Kconfig b/sound/soc/ep93xx/Kconfig
index 57429041189c..91a28de94109 100644
--- a/sound/soc/ep93xx/Kconfig
+++ b/sound/soc/ep93xx/Kconfig
@@ -30,3 +30,12 @@ config SND_EP93XX_SOC_SIMONE
30 help 30 help
31 Say Y or M here if you want to add support for AC97 audio on the 31 Say Y or M here if you want to add support for AC97 audio on the
32 Simplemachines Sim.One board. 32 Simplemachines Sim.One board.
33
34config SND_EP93XX_SOC_EDB93XX
35 tristate "SoC Audio support for Cirrus Logic EDB93xx boards"
36 depends on SND_EP93XX_SOC && (MACH_EDB9301 || MACH_EDB9302 || MACH_EDB9302A || MACH_EDB9307A || MACH_EDB9315A)
37 select SND_EP93XX_SOC_I2S
38 select SND_SOC_CS4271
39 help
40 Say Y or M here if you want to add support for I2S audio on the
41 Cirrus Logic EDB93xx boards.
diff --git a/sound/soc/ep93xx/Makefile b/sound/soc/ep93xx/Makefile
index 8e7977fb6b7d..5514146cbdf0 100644
--- a/sound/soc/ep93xx/Makefile
+++ b/sound/soc/ep93xx/Makefile
@@ -10,6 +10,8 @@ obj-$(CONFIG_SND_EP93XX_SOC_AC97) += snd-soc-ep93xx-ac97.o
10# EP93XX Machine Support 10# EP93XX Machine Support
11snd-soc-snappercl15-objs := snappercl15.o 11snd-soc-snappercl15-objs := snappercl15.o
12snd-soc-simone-objs := simone.o 12snd-soc-simone-objs := simone.o
13snd-soc-edb93xx-objs := edb93xx.o
13 14
14obj-$(CONFIG_SND_EP93XX_SOC_SNAPPERCL15) += snd-soc-snappercl15.o 15obj-$(CONFIG_SND_EP93XX_SOC_SNAPPERCL15) += snd-soc-snappercl15.o
15obj-$(CONFIG_SND_EP93XX_SOC_SIMONE) += snd-soc-simone.o 16obj-$(CONFIG_SND_EP93XX_SOC_SIMONE) += snd-soc-simone.o
17obj-$(CONFIG_SND_EP93XX_SOC_EDB93XX) += snd-soc-edb93xx.o
diff --git a/sound/soc/ep93xx/edb93xx.c b/sound/soc/ep93xx/edb93xx.c
new file mode 100644
index 000000000000..d3aa15119d26
--- /dev/null
+++ b/sound/soc/ep93xx/edb93xx.c
@@ -0,0 +1,142 @@
1/*
2 * SoC audio for EDB93xx
3 *
4 * Copyright (c) 2010 Alexander Sverdlin <subaparts@yandex.ru>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * This driver support CS4271 codec being master or slave, working
17 * in control port mode, connected either via SPI or I2C.
18 * The data format accepted is I2S or left-justified.
19 * DAPM support not implemented.
20 */
21
22#include <linux/platform_device.h>
23#include <linux/gpio.h>
24#include <sound/core.h>
25#include <sound/pcm.h>
26#include <sound/soc.h>
27#include <asm/mach-types.h>
28#include <mach/hardware.h>
29#include "ep93xx-pcm.h"
30
31#define edb93xx_has_audio() (machine_is_edb9301() || \
32 machine_is_edb9302() || \
33 machine_is_edb9302a() || \
34 machine_is_edb9307a() || \
35 machine_is_edb9315a())
36
37static int edb93xx_hw_params(struct snd_pcm_substream *substream,
38 struct snd_pcm_hw_params *params)
39{
40 struct snd_soc_pcm_runtime *rtd = substream->private_data;
41 struct snd_soc_dai *codec_dai = rtd->codec_dai;
42 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
43 int err;
44 unsigned int mclk_rate;
45 unsigned int rate = params_rate(params);
46
47 /*
48 * According to CS4271 datasheet we use MCLK/LRCK=256 for
49 * rates below 50kHz and 128 for higher sample rates
50 */
51 if (rate < 50000)
52 mclk_rate = rate * 64 * 4;
53 else
54 mclk_rate = rate * 64 * 2;
55
56 err = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
57 SND_SOC_DAIFMT_NB_IF |
58 SND_SOC_DAIFMT_CBS_CFS);
59 if (err)
60 return err;
61
62 err = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
63 SND_SOC_DAIFMT_NB_IF |
64 SND_SOC_DAIFMT_CBS_CFS);
65 if (err)
66 return err;
67
68 err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk_rate,
69 SND_SOC_CLOCK_IN);
70 if (err)
71 return err;
72
73 return snd_soc_dai_set_sysclk(cpu_dai, 0, mclk_rate,
74 SND_SOC_CLOCK_OUT);
75}
76
77static struct snd_soc_ops edb93xx_ops = {
78 .hw_params = edb93xx_hw_params,
79};
80
81static struct snd_soc_dai_link edb93xx_dai = {
82 .name = "CS4271",
83 .stream_name = "CS4271 HiFi",
84 .platform_name = "ep93xx-pcm-audio",
85 .cpu_dai_name = "ep93xx-i2s",
86 .codec_name = "spi0.0",
87 .codec_dai_name = "cs4271-hifi",
88 .ops = &edb93xx_ops,
89};
90
91static struct snd_soc_card snd_soc_edb93xx = {
92 .name = "EDB93XX",
93 .dai_link = &edb93xx_dai,
94 .num_links = 1,
95};
96
97static struct platform_device *edb93xx_snd_device;
98
99static int __init edb93xx_init(void)
100{
101 int ret;
102
103 if (!edb93xx_has_audio())
104 return -ENODEV;
105
106 ret = ep93xx_i2s_acquire(EP93XX_SYSCON_DEVCFG_I2SONAC97,
107 EP93XX_SYSCON_I2SCLKDIV_ORIDE |
108 EP93XX_SYSCON_I2SCLKDIV_SPOL);
109 if (ret)
110 return ret;
111
112 edb93xx_snd_device = platform_device_alloc("soc-audio", -1);
113 if (!edb93xx_snd_device) {
114 ret = -ENOMEM;
115 goto free_i2s;
116 }
117
118 platform_set_drvdata(edb93xx_snd_device, &snd_soc_edb93xx);
119 ret = platform_device_add(edb93xx_snd_device);
120 if (ret)
121 goto device_put;
122
123 return 0;
124
125device_put:
126 platform_device_put(edb93xx_snd_device);
127free_i2s:
128 ep93xx_i2s_release();
129 return ret;
130}
131module_init(edb93xx_init);
132
133static void __exit edb93xx_exit(void)
134{
135 platform_device_unregister(edb93xx_snd_device);
136 ep93xx_i2s_release();
137}
138module_exit(edb93xx_exit);
139
140MODULE_AUTHOR("Alexander Sverdlin <subaparts@yandex.ru>");
141MODULE_DESCRIPTION("ALSA SoC EDB93xx");
142MODULE_LICENSE("GPL");
diff --git a/sound/soc/ep93xx/ep93xx-ac97.c b/sound/soc/ep93xx/ep93xx-ac97.c
index 68a0bae1208a..104e95cda0ad 100644
--- a/sound/soc/ep93xx/ep93xx-ac97.c
+++ b/sound/soc/ep93xx/ep93xx-ac97.c
@@ -253,7 +253,6 @@ static int ep93xx_ac97_trigger(struct snd_pcm_substream *substream,
253 struct ep93xx_ac97_info *info = snd_soc_dai_get_drvdata(dai); 253 struct ep93xx_ac97_info *info = snd_soc_dai_get_drvdata(dai);
254 unsigned v = 0; 254 unsigned v = 0;
255 255
256
257 switch (cmd) { 256 switch (cmd) {
258 case SNDRV_PCM_TRIGGER_START: 257 case SNDRV_PCM_TRIGGER_START:
259 case SNDRV_PCM_TRIGGER_RESUME: 258 case SNDRV_PCM_TRIGGER_RESUME:
diff --git a/sound/soc/ep93xx/ep93xx-i2s.c b/sound/soc/ep93xx/ep93xx-i2s.c
index fff579a1c134..042f4e93746f 100644
--- a/sound/soc/ep93xx/ep93xx-i2s.c
+++ b/sound/soc/ep93xx/ep93xx-i2s.c
@@ -242,7 +242,7 @@ static int ep93xx_i2s_hw_params(struct snd_pcm_substream *substream,
242{ 242{
243 struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai); 243 struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai);
244 unsigned word_len, div, sdiv, lrdiv; 244 unsigned word_len, div, sdiv, lrdiv;
245 int found = 0, err; 245 int err;
246 246
247 switch (params_format(params)) { 247 switch (params_format(params)) {
248 case SNDRV_PCM_FORMAT_S16_LE: 248 case SNDRV_PCM_FORMAT_S16_LE:
@@ -275,15 +275,14 @@ static int ep93xx_i2s_hw_params(struct snd_pcm_substream *substream,
275 * the codec uses. 275 * the codec uses.
276 */ 276 */
277 div = clk_get_rate(info->mclk) / params_rate(params); 277 div = clk_get_rate(info->mclk) / params_rate(params);
278 for (sdiv = 2; sdiv <= 4; sdiv += 2) 278 sdiv = 4;
279 for (lrdiv = 64; lrdiv <= 128; lrdiv <<= 1) 279 if (div > (256 + 512) / 2) {
280 if (sdiv * lrdiv == div) { 280 lrdiv = 128;
281 found = 1; 281 } else {
282 goto out; 282 lrdiv = 64;
283 } 283 if (div < (128 + 256) / 2)
284out: 284 sdiv = 2;
285 if (!found) 285 }
286 return -EINVAL;
287 286
288 err = clk_set_rate(info->sclk, clk_get_rate(info->mclk) / sdiv); 287 err = clk_set_rate(info->sclk, clk_get_rate(info->mclk) / sdiv);
289 if (err) 288 if (err)
@@ -314,10 +313,12 @@ static int ep93xx_i2s_suspend(struct snd_soc_dai *dai)
314 struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai); 313 struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai);
315 314
316 if (!dai->active) 315 if (!dai->active)
317 return; 316 return 0;
318 317
319 ep93xx_i2s_disable(info, SNDRV_PCM_STREAM_PLAYBACK); 318 ep93xx_i2s_disable(info, SNDRV_PCM_STREAM_PLAYBACK);
320 ep93xx_i2s_disable(info, SNDRV_PCM_STREAM_CAPTURE); 319 ep93xx_i2s_disable(info, SNDRV_PCM_STREAM_CAPTURE);
320
321 return 0;
321} 322}
322 323
323static int ep93xx_i2s_resume(struct snd_soc_dai *dai) 324static int ep93xx_i2s_resume(struct snd_soc_dai *dai)
@@ -325,10 +326,12 @@ static int ep93xx_i2s_resume(struct snd_soc_dai *dai)
325 struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai); 326 struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai);
326 327
327 if (!dai->active) 328 if (!dai->active)
328 return; 329 return 0;
329 330
330 ep93xx_i2s_enable(info, SNDRV_PCM_STREAM_PLAYBACK); 331 ep93xx_i2s_enable(info, SNDRV_PCM_STREAM_PLAYBACK);
331 ep93xx_i2s_enable(info, SNDRV_PCM_STREAM_CAPTURE); 332 ep93xx_i2s_enable(info, SNDRV_PCM_STREAM_CAPTURE);
333
334 return 0;
332} 335}
333#else 336#else
334#define ep93xx_i2s_suspend NULL 337#define ep93xx_i2s_suspend NULL
@@ -352,13 +355,13 @@ static struct snd_soc_dai_driver ep93xx_i2s_dai = {
352 .playback = { 355 .playback = {
353 .channels_min = 2, 356 .channels_min = 2,
354 .channels_max = 2, 357 .channels_max = 2,
355 .rates = SNDRV_PCM_RATE_8000_96000, 358 .rates = SNDRV_PCM_RATE_8000_192000,
356 .formats = EP93XX_I2S_FORMATS, 359 .formats = EP93XX_I2S_FORMATS,
357 }, 360 },
358 .capture = { 361 .capture = {
359 .channels_min = 2, 362 .channels_min = 2,
360 .channels_max = 2, 363 .channels_max = 2,
361 .rates = SNDRV_PCM_RATE_8000_96000, 364 .rates = SNDRV_PCM_RATE_8000_192000,
362 .formats = EP93XX_I2S_FORMATS, 365 .formats = EP93XX_I2S_FORMATS,
363 }, 366 },
364 .ops = &ep93xx_i2s_dai_ops, 367 .ops = &ep93xx_i2s_dai_ops,
diff --git a/sound/soc/ep93xx/ep93xx-pcm.c b/sound/soc/ep93xx/ep93xx-pcm.c
index 06670776f649..a456e491155f 100644
--- a/sound/soc/ep93xx/ep93xx-pcm.c
+++ b/sound/soc/ep93xx/ep93xx-pcm.c
@@ -35,9 +35,9 @@ static const struct snd_pcm_hardware ep93xx_pcm_hardware = {
35 SNDRV_PCM_INFO_INTERLEAVED | 35 SNDRV_PCM_INFO_INTERLEAVED |
36 SNDRV_PCM_INFO_BLOCK_TRANSFER), 36 SNDRV_PCM_INFO_BLOCK_TRANSFER),
37 37
38 .rates = SNDRV_PCM_RATE_8000_96000, 38 .rates = SNDRV_PCM_RATE_8000_192000,
39 .rate_min = SNDRV_PCM_RATE_8000, 39 .rate_min = SNDRV_PCM_RATE_8000,
40 .rate_max = SNDRV_PCM_RATE_96000, 40 .rate_max = SNDRV_PCM_RATE_192000,
41 41
42 .formats = (SNDRV_PCM_FMTBIT_S16_LE | 42 .formats = (SNDRV_PCM_FMTBIT_S16_LE |
43 SNDRV_PCM_FMTBIT_S24_LE | 43 SNDRV_PCM_FMTBIT_S24_LE |
diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c
index 7d7847a1e66b..c16c6b2eff95 100644
--- a/sound/soc/fsl/mpc8610_hpcd.c
+++ b/sound/soc/fsl/mpc8610_hpcd.c
@@ -53,9 +53,8 @@ struct mpc8610_hpcd_data {
53 * 53 *
54 * Here we program the DMACR and PMUXCR registers. 54 * Here we program the DMACR and PMUXCR registers.
55 */ 55 */
56static int mpc8610_hpcd_machine_probe(struct platform_device *sound_device) 56static int mpc8610_hpcd_machine_probe(struct snd_soc_card *card)
57{ 57{
58 struct snd_soc_card *card = platform_get_drvdata(sound_device);
59 struct mpc8610_hpcd_data *machine_data = 58 struct mpc8610_hpcd_data *machine_data =
60 container_of(card, struct mpc8610_hpcd_data, card); 59 container_of(card, struct mpc8610_hpcd_data, card);
61 struct ccsr_guts_86xx __iomem *guts; 60 struct ccsr_guts_86xx __iomem *guts;
@@ -138,9 +137,8 @@ static int mpc8610_hpcd_startup(struct snd_pcm_substream *substream)
138 * This function is called to remove the sound device for one SSI. We 137 * This function is called to remove the sound device for one SSI. We
139 * de-program the DMACR and PMUXCR register. 138 * de-program the DMACR and PMUXCR register.
140 */ 139 */
141static int mpc8610_hpcd_machine_remove(struct platform_device *sound_device) 140static int mpc8610_hpcd_machine_remove(struct snd_soc_card *card)
142{ 141{
143 struct snd_soc_card *card = platform_get_drvdata(sound_device);
144 struct mpc8610_hpcd_data *machine_data = 142 struct mpc8610_hpcd_data *machine_data =
145 container_of(card, struct mpc8610_hpcd_data, card); 143 container_of(card, struct mpc8610_hpcd_data, card);
146 struct ccsr_guts_86xx __iomem *guts; 144 struct ccsr_guts_86xx __iomem *guts;
diff --git a/sound/soc/fsl/p1022_ds.c b/sound/soc/fsl/p1022_ds.c
index 026b756961e0..66e0b68af147 100644
--- a/sound/soc/fsl/p1022_ds.c
+++ b/sound/soc/fsl/p1022_ds.c
@@ -85,9 +85,8 @@ struct machine_data {
85 * 85 *
86 * Here we program the DMACR and PMUXCR registers. 86 * Here we program the DMACR and PMUXCR registers.
87 */ 87 */
88static int p1022_ds_machine_probe(struct platform_device *sound_device) 88static int p1022_ds_machine_probe(struct snd_soc_card *card)
89{ 89{
90 struct snd_soc_card *card = platform_get_drvdata(sound_device);
91 struct machine_data *mdata = 90 struct machine_data *mdata =
92 container_of(card, struct machine_data, card); 91 container_of(card, struct machine_data, card);
93 struct ccsr_guts_85xx __iomem *guts; 92 struct ccsr_guts_85xx __iomem *guts;
@@ -160,9 +159,8 @@ static int p1022_ds_startup(struct snd_pcm_substream *substream)
160 * This function is called to remove the sound device for one SSI. We 159 * This function is called to remove the sound device for one SSI. We
161 * de-program the DMACR and PMUXCR register. 160 * de-program the DMACR and PMUXCR register.
162 */ 161 */
163static int p1022_ds_machine_remove(struct platform_device *sound_device) 162static int p1022_ds_machine_remove(struct snd_soc_card *card)
164{ 163{
165 struct snd_soc_card *card = platform_get_drvdata(sound_device);
166 struct machine_data *mdata = 164 struct machine_data *mdata =
167 container_of(card, struct machine_data, card); 165 container_of(card, struct machine_data, card);
168 struct ccsr_guts_85xx __iomem *guts; 166 struct ccsr_guts_85xx __iomem *guts;
diff --git a/sound/soc/imx/Kconfig b/sound/soc/imx/Kconfig
index 9eeb8f0d67e9..d8f130d39dd9 100644
--- a/sound/soc/imx/Kconfig
+++ b/sound/soc/imx/Kconfig
@@ -30,6 +30,16 @@ config SND_MXC_SOC_WM1133_EV1
30 Enable support for audio on the i.MX31ADS with the WM1133-EV1 30 Enable support for audio on the i.MX31ADS with the WM1133-EV1
31 PMIC board with WM8835x fitted. 31 PMIC board with WM8835x fitted.
32 32
33config SND_SOC_MX27VIS_AIC32X4
34 tristate "SoC audio support for Visstrim M10 boards"
35 depends on MACH_IMX27_VISSTRIM_M10
36 select SND_SOC_TVL320AIC32X4
37 select SND_MXC_SOC_SSI
38 select SND_MXC_SOC_MX2
39 help
40 Say Y if you want to add support for SoC audio on Visstrim SM10
41 board with TLV320AIC32X4 codec.
42
33config SND_SOC_PHYCORE_AC97 43config SND_SOC_PHYCORE_AC97
34 tristate "SoC Audio support for Phytec phyCORE (and phyCARD) boards" 44 tristate "SoC Audio support for Phytec phyCORE (and phyCARD) boards"
35 depends on MACH_PCM043 || MACH_PCA100 45 depends on MACH_PCM043 || MACH_PCA100
diff --git a/sound/soc/imx/Makefile b/sound/soc/imx/Makefile
index b67fc02a4ecc..d6d609ba7e24 100644
--- a/sound/soc/imx/Makefile
+++ b/sound/soc/imx/Makefile
@@ -10,8 +10,10 @@ obj-$(CONFIG_SND_MXC_SOC_MX2) += snd-soc-imx-mx2.o
10# i.MX Machine Support 10# i.MX Machine Support
11snd-soc-eukrea-tlv320-objs := eukrea-tlv320.o 11snd-soc-eukrea-tlv320-objs := eukrea-tlv320.o
12snd-soc-phycore-ac97-objs := phycore-ac97.o 12snd-soc-phycore-ac97-objs := phycore-ac97.o
13snd-soc-mx27vis-aic32x4-objs := mx27vis-aic32x4.o
13snd-soc-wm1133-ev1-objs := wm1133-ev1.o 14snd-soc-wm1133-ev1-objs := wm1133-ev1.o
14 15
15obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o 16obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o
16obj-$(CONFIG_SND_SOC_PHYCORE_AC97) += snd-soc-phycore-ac97.o 17obj-$(CONFIG_SND_SOC_PHYCORE_AC97) += snd-soc-phycore-ac97.o
18obj-$(CONFIG_SND_SOC_MX27VIS_AIC32X4) += snd-soc-mx27vis-aic32x4.o
17obj-$(CONFIG_SND_MXC_SOC_WM1133_EV1) += snd-soc-wm1133-ev1.o 19obj-$(CONFIG_SND_MXC_SOC_WM1133_EV1) += snd-soc-wm1133-ev1.o
diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c
index 30894ea7f333..bc92ec620004 100644
--- a/sound/soc/imx/imx-ssi.c
+++ b/sound/soc/imx/imx-ssi.c
@@ -108,7 +108,7 @@ static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
108 break; 108 break;
109 case SND_SOC_DAIFMT_DSP_B: 109 case SND_SOC_DAIFMT_DSP_B:
110 /* data on rising edge of bclk, frame high with data */ 110 /* data on rising edge of bclk, frame high with data */
111 strcr |= SSI_STCR_TFSL; 111 strcr |= SSI_STCR_TFSL | SSI_STCR_TXBIT0;
112 break; 112 break;
113 case SND_SOC_DAIFMT_DSP_A: 113 case SND_SOC_DAIFMT_DSP_A:
114 /* data on rising edge of bclk, frame high 1clk before data */ 114 /* data on rising edge of bclk, frame high 1clk before data */
@@ -656,6 +656,9 @@ static int imx_ssi_probe(struct platform_device *pdev)
656 ssi->dma_params_rx.dma_addr = res->start + SSI_SRX0; 656 ssi->dma_params_rx.dma_addr = res->start + SSI_SRX0;
657 ssi->dma_params_tx.dma_addr = res->start + SSI_STX0; 657 ssi->dma_params_tx.dma_addr = res->start + SSI_STX0;
658 658
659 ssi->dma_params_tx.burstsize = 4;
660 ssi->dma_params_rx.burstsize = 4;
661
659 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx0"); 662 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx0");
660 if (res) 663 if (res)
661 ssi->dma_params_tx.dma = res->start; 664 ssi->dma_params_tx.dma = res->start;
diff --git a/sound/soc/imx/mx27vis-aic32x4.c b/sound/soc/imx/mx27vis-aic32x4.c
new file mode 100644
index 000000000000..054110b91d42
--- /dev/null
+++ b/sound/soc/imx/mx27vis-aic32x4.c
@@ -0,0 +1,137 @@
1/*
2 * mx27vis-aic32x4.c
3 *
4 * Copyright 2011 Vista Silicon S.L.
5 *
6 * Author: Javier Martin <javier.martin@vista-silicon.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 * 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., 51 Franklin Street, Fifth Floor, Boston,
21 * MA 02110-1301, USA.
22 */
23
24#include <linux/module.h>
25#include <linux/moduleparam.h>
26#include <linux/device.h>
27#include <linux/i2c.h>
28#include <sound/core.h>
29#include <sound/pcm.h>
30#include <sound/soc.h>
31#include <sound/soc-dapm.h>
32#include <asm/mach-types.h>
33#include <mach/audmux.h>
34
35#include "../codecs/tlv320aic32x4.h"
36#include "imx-ssi.h"
37
38static int mx27vis_aic32x4_hw_params(struct snd_pcm_substream *substream,
39 struct snd_pcm_hw_params *params)
40{
41 struct snd_soc_pcm_runtime *rtd = substream->private_data;
42 struct snd_soc_dai *codec_dai = rtd->codec_dai;
43 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
44 int ret;
45 u32 dai_format;
46
47 dai_format = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF |
48 SND_SOC_DAIFMT_CBM_CFM;
49
50 /* set codec DAI configuration */
51 snd_soc_dai_set_fmt(codec_dai, dai_format);
52
53 /* set cpu DAI configuration */
54 snd_soc_dai_set_fmt(cpu_dai, dai_format);
55
56 ret = snd_soc_dai_set_sysclk(codec_dai, 0,
57 25000000, SND_SOC_CLOCK_OUT);
58 if (ret) {
59 pr_err("%s: failed setting codec sysclk\n", __func__);
60 return ret;
61 }
62
63 ret = snd_soc_dai_set_sysclk(cpu_dai, IMX_SSP_SYS_CLK, 0,
64 SND_SOC_CLOCK_IN);
65 if (ret) {
66 pr_err("can't set CPU system clock IMX_SSP_SYS_CLK\n");
67 return ret;
68 }
69
70 return 0;
71}
72
73static struct snd_soc_ops mx27vis_aic32x4_snd_ops = {
74 .hw_params = mx27vis_aic32x4_hw_params,
75};
76
77static struct snd_soc_dai_link mx27vis_aic32x4_dai = {
78 .name = "tlv320aic32x4",
79 .stream_name = "TLV320AIC32X4",
80 .codec_dai_name = "tlv320aic32x4-hifi",
81 .platform_name = "imx-pcm-audio.0",
82 .codec_name = "tlv320aic32x4.0-0018",
83 .cpu_dai_name = "imx-ssi.0",
84 .ops = &mx27vis_aic32x4_snd_ops,
85};
86
87static struct snd_soc_card mx27vis_aic32x4 = {
88 .name = "visstrim_m10-audio",
89 .dai_link = &mx27vis_aic32x4_dai,
90 .num_links = 1,
91};
92
93static struct platform_device *mx27vis_aic32x4_snd_device;
94
95static int __init mx27vis_aic32x4_init(void)
96{
97 int ret;
98
99 mx27vis_aic32x4_snd_device = platform_device_alloc("soc-audio", -1);
100 if (!mx27vis_aic32x4_snd_device)
101 return -ENOMEM;
102
103 platform_set_drvdata(mx27vis_aic32x4_snd_device, &mx27vis_aic32x4);
104 ret = platform_device_add(mx27vis_aic32x4_snd_device);
105
106 if (ret) {
107 printk(KERN_ERR "ASoC: Platform device allocation failed\n");
108 platform_device_put(mx27vis_aic32x4_snd_device);
109 }
110
111 /* Connect SSI0 as clock slave to SSI1 external pins */
112 mxc_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0,
113 MXC_AUDMUX_V1_PCR_SYN |
114 MXC_AUDMUX_V1_PCR_TFSDIR |
115 MXC_AUDMUX_V1_PCR_TCLKDIR |
116 MXC_AUDMUX_V1_PCR_TFCSEL(MX27_AUDMUX_PPCR1_SSI_PINS_1) |
117 MXC_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_PPCR1_SSI_PINS_1)
118 );
119 mxc_audmux_v1_configure_port(MX27_AUDMUX_PPCR1_SSI_PINS_1,
120 MXC_AUDMUX_V1_PCR_SYN |
121 MXC_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR1_SSI0)
122 );
123
124 return ret;
125}
126
127static void __exit mx27vis_aic32x4_exit(void)
128{
129 platform_device_unregister(mx27vis_aic32x4_snd_device);
130}
131
132module_init(mx27vis_aic32x4_init);
133module_exit(mx27vis_aic32x4_exit);
134
135MODULE_AUTHOR("Javier Martin <javier.martin@vista-silicon.com>");
136MODULE_DESCRIPTION("ALSA SoC AIC32X4 mx27 visstrim");
137MODULE_LICENSE("GPL");
diff --git a/sound/soc/mid-x86/Kconfig b/sound/soc/mid-x86/Kconfig
new file mode 100644
index 000000000000..29350428f1c2
--- /dev/null
+++ b/sound/soc/mid-x86/Kconfig
@@ -0,0 +1,14 @@
1config SND_MFLD_MACHINE
2 tristate "SOC Machine Audio driver for Intel Medfield MID platform"
3 depends on INTEL_SCU_IPC
4 depends on SND_INTEL_SST
5 select SND_SOC_SN95031
6 select SND_SST_PLATFORM
7 help
8 This adds support for ASoC machine driver for Intel(R) MID Medfield platform
9 used as alsa device in audio substem in Intel(R) MID devices
10 Say Y if you have such a device
11 If unsure select "N".
12
13config SND_SST_PLATFORM
14 tristate
diff --git a/sound/soc/mid-x86/Makefile b/sound/soc/mid-x86/Makefile
new file mode 100644
index 000000000000..639883339465
--- /dev/null
+++ b/sound/soc/mid-x86/Makefile
@@ -0,0 +1,5 @@
1snd-soc-sst-platform-objs := sst_platform.o
2snd-soc-mfld-machine-objs := mfld_machine.o
3
4obj-$(CONFIG_SND_SST_PLATFORM) += snd-soc-sst-platform.o
5obj-$(CONFIG_SND_MFLD_MACHINE) += snd-soc-mfld-machine.o
diff --git a/sound/soc/mid-x86/mfld_machine.c b/sound/soc/mid-x86/mfld_machine.c
new file mode 100644
index 000000000000..429aa1be2cff
--- /dev/null
+++ b/sound/soc/mid-x86/mfld_machine.c
@@ -0,0 +1,452 @@
1/*
2 * mfld_machine.c - ASoc Machine driver for Intel Medfield MID platform
3 *
4 * Copyright (C) 2010 Intel Corp
5 * Author: Vinod Koul <vinod.koul@intel.com>
6 * Author: Harsha Priya <priya.harsha@intel.com>
7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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 as published by
11 * the Free Software Foundation; version 2 of the License.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21 *
22 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
23 */
24
25#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
26
27#include <linux/init.h>
28#include <linux/device.h>
29#include <linux/slab.h>
30#include <linux/io.h>
31#include <sound/pcm.h>
32#include <sound/pcm_params.h>
33#include <sound/soc.h>
34#include <sound/jack.h>
35#include "../codecs/sn95031.h"
36
37#define MID_MONO 1
38#define MID_STEREO 2
39#define MID_MAX_CAP 5
40#define MFLD_JACK_INSERT 0x04
41
42enum soc_mic_bias_zones {
43 MFLD_MV_START = 0,
44 /* mic bias volutage range for Headphones*/
45 MFLD_MV_HP = 400,
46 /* mic bias volutage range for American Headset*/
47 MFLD_MV_AM_HS = 650,
48 /* mic bias volutage range for Headset*/
49 MFLD_MV_HS = 2000,
50 MFLD_MV_UNDEFINED,
51};
52
53static unsigned int hs_switch;
54static unsigned int lo_dac;
55
56struct mfld_mc_private {
57 struct platform_device *socdev;
58 void __iomem *int_base;
59 struct snd_soc_codec *codec;
60 u8 interrupt_status;
61};
62
63struct snd_soc_jack mfld_jack;
64
65/*Headset jack detection DAPM pins */
66static struct snd_soc_jack_pin mfld_jack_pins[] = {
67 {
68 .pin = "Headphones",
69 .mask = SND_JACK_HEADPHONE,
70 },
71 {
72 .pin = "AMIC1",
73 .mask = SND_JACK_MICROPHONE,
74 },
75};
76
77/* jack detection voltage zones */
78static struct snd_soc_jack_zone mfld_zones[] = {
79 {MFLD_MV_START, MFLD_MV_AM_HS, SND_JACK_HEADPHONE},
80 {MFLD_MV_AM_HS, MFLD_MV_HS, SND_JACK_HEADSET},
81};
82
83/* sound card controls */
84static const char *headset_switch_text[] = {"Earpiece", "Headset"};
85
86static const char *lo_text[] = {"Vibra", "Headset", "IHF", "None"};
87
88static const struct soc_enum headset_enum =
89 SOC_ENUM_SINGLE_EXT(2, headset_switch_text);
90
91static const struct soc_enum lo_enum =
92 SOC_ENUM_SINGLE_EXT(4, lo_text);
93
94static int headset_get_switch(struct snd_kcontrol *kcontrol,
95 struct snd_ctl_elem_value *ucontrol)
96{
97 ucontrol->value.integer.value[0] = hs_switch;
98 return 0;
99}
100
101static int headset_set_switch(struct snd_kcontrol *kcontrol,
102 struct snd_ctl_elem_value *ucontrol)
103{
104 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
105
106 if (ucontrol->value.integer.value[0] == hs_switch)
107 return 0;
108
109 if (ucontrol->value.integer.value[0]) {
110 pr_debug("hs_set HS path\n");
111 snd_soc_dapm_enable_pin(&codec->dapm, "Headphones");
112 snd_soc_dapm_disable_pin(&codec->dapm, "EPOUT");
113 } else {
114 pr_debug("hs_set EP path\n");
115 snd_soc_dapm_disable_pin(&codec->dapm, "Headphones");
116 snd_soc_dapm_enable_pin(&codec->dapm, "EPOUT");
117 }
118 snd_soc_dapm_sync(&codec->dapm);
119 hs_switch = ucontrol->value.integer.value[0];
120
121 return 0;
122}
123
124static void lo_enable_out_pins(struct snd_soc_codec *codec)
125{
126 snd_soc_dapm_enable_pin(&codec->dapm, "IHFOUTL");
127 snd_soc_dapm_enable_pin(&codec->dapm, "IHFOUTR");
128 snd_soc_dapm_enable_pin(&codec->dapm, "LINEOUTL");
129 snd_soc_dapm_enable_pin(&codec->dapm, "LINEOUTR");
130 snd_soc_dapm_enable_pin(&codec->dapm, "VIB1OUT");
131 snd_soc_dapm_enable_pin(&codec->dapm, "VIB2OUT");
132 if (hs_switch) {
133 snd_soc_dapm_enable_pin(&codec->dapm, "Headphones");
134 snd_soc_dapm_disable_pin(&codec->dapm, "EPOUT");
135 } else {
136 snd_soc_dapm_disable_pin(&codec->dapm, "Headphones");
137 snd_soc_dapm_enable_pin(&codec->dapm, "EPOUT");
138 }
139}
140
141static int lo_get_switch(struct snd_kcontrol *kcontrol,
142 struct snd_ctl_elem_value *ucontrol)
143{
144 ucontrol->value.integer.value[0] = lo_dac;
145 return 0;
146}
147
148static int lo_set_switch(struct snd_kcontrol *kcontrol,
149 struct snd_ctl_elem_value *ucontrol)
150{
151 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
152
153 if (ucontrol->value.integer.value[0] == lo_dac)
154 return 0;
155
156 /* we dont want to work with last state of lineout so just enable all
157 * pins and then disable pins not required
158 */
159 lo_enable_out_pins(codec);
160 switch (ucontrol->value.integer.value[0]) {
161 case 0:
162 pr_debug("set vibra path\n");
163 snd_soc_dapm_disable_pin(&codec->dapm, "VIB1OUT");
164 snd_soc_dapm_disable_pin(&codec->dapm, "VIB2OUT");
165 snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0);
166 break;
167
168 case 1:
169 pr_debug("set hs path\n");
170 snd_soc_dapm_disable_pin(&codec->dapm, "Headphones");
171 snd_soc_dapm_disable_pin(&codec->dapm, "EPOUT");
172 snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0x22);
173 break;
174
175 case 2:
176 pr_debug("set spkr path\n");
177 snd_soc_dapm_disable_pin(&codec->dapm, "IHFOUTL");
178 snd_soc_dapm_disable_pin(&codec->dapm, "IHFOUTR");
179 snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0x44);
180 break;
181
182 case 3:
183 pr_debug("set null path\n");
184 snd_soc_dapm_disable_pin(&codec->dapm, "LINEOUTL");
185 snd_soc_dapm_disable_pin(&codec->dapm, "LINEOUTR");
186 snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0x66);
187 break;
188 }
189 snd_soc_dapm_sync(&codec->dapm);
190 lo_dac = ucontrol->value.integer.value[0];
191 return 0;
192}
193
194static const struct snd_kcontrol_new mfld_snd_controls[] = {
195 SOC_ENUM_EXT("Playback Switch", headset_enum,
196 headset_get_switch, headset_set_switch),
197 SOC_ENUM_EXT("Lineout Mux", lo_enum,
198 lo_get_switch, lo_set_switch),
199};
200
201static const struct snd_soc_dapm_widget mfld_widgets[] = {
202 SND_SOC_DAPM_HP("Headphones", NULL),
203 SND_SOC_DAPM_MIC("Mic", NULL),
204};
205
206static const struct snd_soc_dapm_route mfld_map[] = {
207 {"Headphones", NULL, "HPOUTR"},
208 {"Headphones", NULL, "HPOUTL"},
209 {"Mic", NULL, "AMIC1"},
210};
211
212static void mfld_jack_check(unsigned int intr_status)
213{
214 struct mfld_jack_data jack_data;
215
216 jack_data.mfld_jack = &mfld_jack;
217 jack_data.intr_id = intr_status;
218
219 sn95031_jack_detection(&jack_data);
220 /* TODO: add american headset detection post gpiolib support */
221}
222
223static int mfld_init(struct snd_soc_pcm_runtime *runtime)
224{
225 struct snd_soc_codec *codec = runtime->codec;
226 struct snd_soc_dapm_context *dapm = &codec->dapm;
227 int ret_val;
228
229 /* Add jack sense widgets */
230 snd_soc_dapm_new_controls(dapm, mfld_widgets, ARRAY_SIZE(mfld_widgets));
231
232 /* Set up the map */
233 snd_soc_dapm_add_routes(dapm, mfld_map, ARRAY_SIZE(mfld_map));
234
235 /* always connected */
236 snd_soc_dapm_enable_pin(dapm, "Headphones");
237 snd_soc_dapm_enable_pin(dapm, "Mic");
238 snd_soc_dapm_sync(dapm);
239
240 ret_val = snd_soc_add_controls(codec, mfld_snd_controls,
241 ARRAY_SIZE(mfld_snd_controls));
242 if (ret_val) {
243 pr_err("soc_add_controls failed %d", ret_val);
244 return ret_val;
245 }
246 /* default is earpiece pin, userspace sets it explcitly */
247 snd_soc_dapm_disable_pin(dapm, "Headphones");
248 /* default is lineout NC, userspace sets it explcitly */
249 snd_soc_dapm_disable_pin(dapm, "LINEOUTL");
250 snd_soc_dapm_disable_pin(dapm, "LINEOUTR");
251 lo_dac = 3;
252 hs_switch = 0;
253 /* we dont use linein in this so set to NC */
254 snd_soc_dapm_disable_pin(dapm, "LINEINL");
255 snd_soc_dapm_disable_pin(dapm, "LINEINR");
256 snd_soc_dapm_sync(dapm);
257
258 /* Headset and button jack detection */
259 ret_val = snd_soc_jack_new(codec, "Intel(R) MID Audio Jack",
260 SND_JACK_HEADSET | SND_JACK_BTN_0 |
261 SND_JACK_BTN_1, &mfld_jack);
262 if (ret_val) {
263 pr_err("jack creation failed\n");
264 return ret_val;
265 }
266
267 ret_val = snd_soc_jack_add_pins(&mfld_jack,
268 ARRAY_SIZE(mfld_jack_pins), mfld_jack_pins);
269 if (ret_val) {
270 pr_err("adding jack pins failed\n");
271 return ret_val;
272 }
273 ret_val = snd_soc_jack_add_zones(&mfld_jack,
274 ARRAY_SIZE(mfld_zones), mfld_zones);
275 if (ret_val) {
276 pr_err("adding jack zones failed\n");
277 return ret_val;
278 }
279
280 /* we want to check if anything is inserted at boot,
281 * so send a fake event to codec and it will read adc
282 * to find if anything is there or not */
283 mfld_jack_check(MFLD_JACK_INSERT);
284 return ret_val;
285}
286
287struct snd_soc_dai_link mfld_msic_dailink[] = {
288 {
289 .name = "Medfield Headset",
290 .stream_name = "Headset",
291 .cpu_dai_name = "Headset-cpu-dai",
292 .codec_dai_name = "SN95031 Headset",
293 .codec_name = "sn95031",
294 .platform_name = "sst-platform",
295 .init = mfld_init,
296 },
297 {
298 .name = "Medfield Speaker",
299 .stream_name = "Speaker",
300 .cpu_dai_name = "Speaker-cpu-dai",
301 .codec_dai_name = "SN95031 Speaker",
302 .codec_name = "sn95031",
303 .platform_name = "sst-platform",
304 .init = NULL,
305 },
306 {
307 .name = "Medfield Vibra",
308 .stream_name = "Vibra1",
309 .cpu_dai_name = "Vibra1-cpu-dai",
310 .codec_dai_name = "SN95031 Vibra1",
311 .codec_name = "sn95031",
312 .platform_name = "sst-platform",
313 .init = NULL,
314 },
315 {
316 .name = "Medfield Haptics",
317 .stream_name = "Vibra2",
318 .cpu_dai_name = "Vibra2-cpu-dai",
319 .codec_dai_name = "SN95031 Vibra2",
320 .codec_name = "sn95031",
321 .platform_name = "sst-platform",
322 .init = NULL,
323 },
324};
325
326/* SoC card */
327static struct snd_soc_card snd_soc_card_mfld = {
328 .name = "medfield_audio",
329 .dai_link = mfld_msic_dailink,
330 .num_links = ARRAY_SIZE(mfld_msic_dailink),
331};
332
333static irqreturn_t snd_mfld_jack_intr_handler(int irq, void *dev)
334{
335 struct mfld_mc_private *mc_private = (struct mfld_mc_private *) dev;
336
337 memcpy_fromio(&mc_private->interrupt_status,
338 ((void *)(mc_private->int_base)),
339 sizeof(u8));
340 return IRQ_WAKE_THREAD;
341}
342
343static irqreturn_t snd_mfld_jack_detection(int irq, void *data)
344{
345 struct mfld_mc_private *mc_drv_ctx = (struct mfld_mc_private *) data;
346
347 if (mfld_jack.codec == NULL)
348 return IRQ_HANDLED;
349 mfld_jack_check(mc_drv_ctx->interrupt_status);
350
351 return IRQ_HANDLED;
352}
353
354static int __devinit snd_mfld_mc_probe(struct platform_device *pdev)
355{
356 int ret_val = 0, irq;
357 struct mfld_mc_private *mc_drv_ctx;
358 struct resource *irq_mem;
359
360 pr_debug("snd_mfld_mc_probe called\n");
361
362 /* retrive the irq number */
363 irq = platform_get_irq(pdev, 0);
364
365 /* audio interrupt base of SRAM location where
366 * interrupts are stored by System FW */
367 mc_drv_ctx = kzalloc(sizeof(*mc_drv_ctx), GFP_ATOMIC);
368 if (!mc_drv_ctx) {
369 pr_err("allocation failed\n");
370 return -ENOMEM;
371 }
372
373 irq_mem = platform_get_resource_byname(
374 pdev, IORESOURCE_MEM, "IRQ_BASE");
375 if (!irq_mem) {
376 pr_err("no mem resource given\n");
377 ret_val = -ENODEV;
378 goto unalloc;
379 }
380 mc_drv_ctx->int_base = ioremap_nocache(irq_mem->start,
381 resource_size(irq_mem));
382 if (!mc_drv_ctx->int_base) {
383 pr_err("Mapping of cache failed\n");
384 ret_val = -ENOMEM;
385 goto unalloc;
386 }
387 /* register for interrupt */
388 ret_val = request_threaded_irq(irq, snd_mfld_jack_intr_handler,
389 snd_mfld_jack_detection,
390 IRQF_SHARED, pdev->dev.driver->name, mc_drv_ctx);
391 if (ret_val) {
392 pr_err("cannot register IRQ\n");
393 goto unalloc;
394 }
395 /* register the soc card */
396 snd_soc_card_mfld.dev = &pdev->dev;
397 ret_val = snd_soc_register_card(&snd_soc_card_mfld);
398 if (ret_val) {
399 pr_debug("snd_soc_register_card failed %d\n", ret_val);
400 goto freeirq;
401 }
402 platform_set_drvdata(pdev, mc_drv_ctx);
403 pr_debug("successfully exited probe\n");
404 return ret_val;
405
406freeirq:
407 free_irq(irq, mc_drv_ctx);
408unalloc:
409 kfree(mc_drv_ctx);
410 return ret_val;
411}
412
413static int __devexit snd_mfld_mc_remove(struct platform_device *pdev)
414{
415 struct mfld_mc_private *mc_drv_ctx = platform_get_drvdata(pdev);
416
417 pr_debug("snd_mfld_mc_remove called\n");
418 free_irq(platform_get_irq(pdev, 0), mc_drv_ctx);
419 snd_soc_unregister_card(&snd_soc_card_mfld);
420 kfree(mc_drv_ctx);
421 platform_set_drvdata(pdev, NULL);
422 return 0;
423}
424
425static struct platform_driver snd_mfld_mc_driver = {
426 .driver = {
427 .owner = THIS_MODULE,
428 .name = "msic_audio",
429 },
430 .probe = snd_mfld_mc_probe,
431 .remove = __devexit_p(snd_mfld_mc_remove),
432};
433
434static int __init snd_mfld_driver_init(void)
435{
436 pr_debug("snd_mfld_driver_init called\n");
437 return platform_driver_register(&snd_mfld_mc_driver);
438}
439module_init(snd_mfld_driver_init);
440
441static void __exit snd_mfld_driver_exit(void)
442{
443 pr_debug("snd_mfld_driver_exit called\n");
444 platform_driver_unregister(&snd_mfld_mc_driver);
445}
446module_exit(snd_mfld_driver_exit);
447
448MODULE_DESCRIPTION("ASoC Intel(R) MID Machine driver");
449MODULE_AUTHOR("Vinod Koul <vinod.koul@intel.com>");
450MODULE_AUTHOR("Harsha Priya <priya.harsha@intel.com>");
451MODULE_LICENSE("GPL v2");
452MODULE_ALIAS("platform:msic-audio");
diff --git a/sound/soc/mid-x86/sst_platform.c b/sound/soc/mid-x86/sst_platform.c
new file mode 100644
index 000000000000..ee2c22475a76
--- /dev/null
+++ b/sound/soc/mid-x86/sst_platform.c
@@ -0,0 +1,474 @@
1/*
2 * sst_platform.c - Intel MID Platform driver
3 *
4 * Copyright (C) 2010 Intel Corp
5 * Author: Vinod Koul <vinod.koul@intel.com>
6 * Author: Harsha Priya <priya.harsha@intel.com>
7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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 as published by
11 * the Free Software Foundation; version 2 of the License.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21 *
22 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
23 *
24 *
25 */
26#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
27
28#include <linux/slab.h>
29#include <linux/io.h>
30#include <sound/core.h>
31#include <sound/pcm.h>
32#include <sound/pcm_params.h>
33#include <sound/soc.h>
34#include "../../../drivers/staging/intel_sst/intel_sst_ioctl.h"
35#include "../../../drivers/staging/intel_sst/intel_sst.h"
36#include "sst_platform.h"
37
38static struct snd_pcm_hardware sst_platform_pcm_hw = {
39 .info = (SNDRV_PCM_INFO_INTERLEAVED |
40 SNDRV_PCM_INFO_DOUBLE |
41 SNDRV_PCM_INFO_PAUSE |
42 SNDRV_PCM_INFO_RESUME |
43 SNDRV_PCM_INFO_MMAP|
44 SNDRV_PCM_INFO_MMAP_VALID |
45 SNDRV_PCM_INFO_BLOCK_TRANSFER |
46 SNDRV_PCM_INFO_SYNC_START),
47 .formats = (SNDRV_PCM_FMTBIT_S16 | SNDRV_PCM_FMTBIT_U16 |
48 SNDRV_PCM_FMTBIT_S24 | SNDRV_PCM_FMTBIT_U24 |
49 SNDRV_PCM_FMTBIT_S32 | SNDRV_PCM_FMTBIT_U32),
50 .rates = (SNDRV_PCM_RATE_8000|
51 SNDRV_PCM_RATE_44100 |
52 SNDRV_PCM_RATE_48000),
53 .rate_min = SST_MIN_RATE,
54 .rate_max = SST_MAX_RATE,
55 .channels_min = SST_MIN_CHANNEL,
56 .channels_max = SST_MAX_CHANNEL,
57 .buffer_bytes_max = SST_MAX_BUFFER,
58 .period_bytes_min = SST_MIN_PERIOD_BYTES,
59 .period_bytes_max = SST_MAX_PERIOD_BYTES,
60 .periods_min = SST_MIN_PERIODS,
61 .periods_max = SST_MAX_PERIODS,
62 .fifo_size = SST_FIFO_SIZE,
63};
64
65/* MFLD - MSIC */
66struct snd_soc_dai_driver sst_platform_dai[] = {
67{
68 .name = "Headset-cpu-dai",
69 .id = 0,
70 .playback = {
71 .channels_min = SST_STEREO,
72 .channels_max = SST_STEREO,
73 .rates = SNDRV_PCM_RATE_48000,
74 .formats = SNDRV_PCM_FMTBIT_S24_LE,
75 },
76 .capture = {
77 .channels_min = 1,
78 .channels_max = 5,
79 .rates = SNDRV_PCM_RATE_48000,
80 .formats = SNDRV_PCM_FMTBIT_S24_LE,
81 },
82},
83{
84 .name = "Speaker-cpu-dai",
85 .id = 1,
86 .playback = {
87 .channels_min = SST_MONO,
88 .channels_max = SST_STEREO,
89 .rates = SNDRV_PCM_RATE_48000,
90 .formats = SNDRV_PCM_FMTBIT_S24_LE,
91 },
92},
93{
94 .name = "Vibra1-cpu-dai",
95 .id = 2,
96 .playback = {
97 .channels_min = SST_MONO,
98 .channels_max = SST_MONO,
99 .rates = SNDRV_PCM_RATE_48000,
100 .formats = SNDRV_PCM_FMTBIT_S24_LE,
101 },
102},
103{
104 .name = "Vibra2-cpu-dai",
105 .id = 3,
106 .playback = {
107 .channels_min = SST_MONO,
108 .channels_max = SST_STEREO,
109 .rates = SNDRV_PCM_RATE_48000,
110 .formats = SNDRV_PCM_FMTBIT_S24_LE,
111 },
112},
113};
114
115/* helper functions */
116static inline void sst_set_stream_status(struct sst_runtime_stream *stream,
117 int state)
118{
119 spin_lock(&stream->status_lock);
120 stream->stream_status = state;
121 spin_unlock(&stream->status_lock);
122}
123
124static inline int sst_get_stream_status(struct sst_runtime_stream *stream)
125{
126 int state;
127
128 spin_lock(&stream->status_lock);
129 state = stream->stream_status;
130 spin_unlock(&stream->status_lock);
131 return state;
132}
133
134static void sst_fill_pcm_params(struct snd_pcm_substream *substream,
135 struct snd_sst_stream_params *param)
136{
137
138 param->uc.pcm_params.codec = SST_CODEC_TYPE_PCM;
139 param->uc.pcm_params.num_chan = (u8) substream->runtime->channels;
140 param->uc.pcm_params.pcm_wd_sz = substream->runtime->sample_bits;
141 param->uc.pcm_params.reserved = 0;
142 param->uc.pcm_params.sfreq = substream->runtime->rate;
143 param->uc.pcm_params.ring_buffer_size =
144 snd_pcm_lib_buffer_bytes(substream);
145 param->uc.pcm_params.period_count = substream->runtime->period_size;
146 param->uc.pcm_params.ring_buffer_addr =
147 virt_to_phys(substream->dma_buffer.area);
148 pr_debug("period_cnt = %d\n", param->uc.pcm_params.period_count);
149 pr_debug("sfreq= %d, wd_sz = %d\n",
150 param->uc.pcm_params.sfreq, param->uc.pcm_params.pcm_wd_sz);
151}
152
153static int sst_platform_alloc_stream(struct snd_pcm_substream *substream)
154{
155 struct sst_runtime_stream *stream =
156 substream->runtime->private_data;
157 struct snd_sst_stream_params param = {{{0,},},};
158 struct snd_sst_params str_params = {0};
159 int ret_val;
160
161 /* set codec params and inform SST driver the same */
162 sst_fill_pcm_params(substream, &param);
163 substream->runtime->dma_area = substream->dma_buffer.area;
164 str_params.sparams = param;
165 str_params.codec = param.uc.pcm_params.codec;
166 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
167 str_params.ops = STREAM_OPS_PLAYBACK;
168 str_params.device_type = substream->pcm->device + 1;
169 pr_debug("Playbck stream,Device %d\n",
170 substream->pcm->device);
171 } else {
172 str_params.ops = STREAM_OPS_CAPTURE;
173 str_params.device_type = SND_SST_DEVICE_CAPTURE;
174 pr_debug("Capture stream,Device %d\n",
175 substream->pcm->device);
176 }
177 ret_val = stream->sstdrv_ops->pcm_control->open(&str_params);
178 pr_debug("SST_SND_PLAY/CAPTURE ret_val = %x\n", ret_val);
179 if (ret_val < 0)
180 return ret_val;
181
182 stream->stream_info.str_id = ret_val;
183 pr_debug("str id : %d\n", stream->stream_info.str_id);
184 return ret_val;
185}
186
187static void sst_period_elapsed(void *mad_substream)
188{
189 struct snd_pcm_substream *substream = mad_substream;
190 struct sst_runtime_stream *stream;
191 int status;
192
193 if (!substream || !substream->runtime)
194 return;
195 stream = substream->runtime->private_data;
196 if (!stream)
197 return;
198 status = sst_get_stream_status(stream);
199 if (status != SST_PLATFORM_RUNNING)
200 return;
201 snd_pcm_period_elapsed(substream);
202}
203
204static int sst_platform_init_stream(struct snd_pcm_substream *substream)
205{
206 struct sst_runtime_stream *stream =
207 substream->runtime->private_data;
208 int ret_val;
209
210 pr_debug("setting buffer ptr param\n");
211 sst_set_stream_status(stream, SST_PLATFORM_INIT);
212 stream->stream_info.period_elapsed = sst_period_elapsed;
213 stream->stream_info.mad_substream = substream;
214 stream->stream_info.buffer_ptr = 0;
215 stream->stream_info.sfreq = substream->runtime->rate;
216 ret_val = stream->sstdrv_ops->pcm_control->device_control(
217 SST_SND_STREAM_INIT, &stream->stream_info);
218 if (ret_val)
219 pr_err("control_set ret error %d\n", ret_val);
220 return ret_val;
221
222}
223/* end -- helper functions */
224
225static int sst_platform_open(struct snd_pcm_substream *substream)
226{
227 struct snd_pcm_runtime *runtime;
228 struct sst_runtime_stream *stream;
229 int ret_val = 0;
230
231 pr_debug("sst_platform_open called\n");
232 runtime = substream->runtime;
233 runtime->hw = sst_platform_pcm_hw;
234 stream = kzalloc(sizeof(*stream), GFP_KERNEL);
235 if (!stream)
236 return -ENOMEM;
237 spin_lock_init(&stream->status_lock);
238 stream->stream_info.str_id = 0;
239 sst_set_stream_status(stream, SST_PLATFORM_INIT);
240 stream->stream_info.mad_substream = substream;
241 /* allocate memory for SST API set */
242 stream->sstdrv_ops = kzalloc(sizeof(*stream->sstdrv_ops),
243 GFP_KERNEL);
244 if (!stream->sstdrv_ops) {
245 pr_err("sst: mem allocation for ops fail\n");
246 kfree(stream);
247 return -ENOMEM;
248 }
249 stream->sstdrv_ops->vendor_id = MSIC_VENDOR_ID;
250 /* registering with SST driver to get access to SST APIs to use */
251 ret_val = register_sst_card(stream->sstdrv_ops);
252 if (ret_val) {
253 pr_err("sst: sst card registration failed\n");
254 return ret_val;
255 }
256 runtime->private_data = stream;
257 return snd_pcm_hw_constraint_integer(runtime,
258 SNDRV_PCM_HW_PARAM_PERIODS);
259}
260
261static int sst_platform_close(struct snd_pcm_substream *substream)
262{
263 struct sst_runtime_stream *stream;
264 int ret_val = 0, str_id;
265
266 pr_debug("sst_platform_close called\n");
267 stream = substream->runtime->private_data;
268 str_id = stream->stream_info.str_id;
269 if (str_id)
270 ret_val = stream->sstdrv_ops->pcm_control->close(str_id);
271 kfree(stream->sstdrv_ops);
272 kfree(stream);
273 return ret_val;
274}
275
276static int sst_platform_pcm_prepare(struct snd_pcm_substream *substream)
277{
278 struct sst_runtime_stream *stream;
279 int ret_val = 0, str_id;
280
281 pr_debug("sst_platform_pcm_prepare called\n");
282 stream = substream->runtime->private_data;
283 str_id = stream->stream_info.str_id;
284 if (stream->stream_info.str_id) {
285 ret_val = stream->sstdrv_ops->pcm_control->device_control(
286 SST_SND_DROP, &str_id);
287 return ret_val;
288 }
289
290 ret_val = sst_platform_alloc_stream(substream);
291 if (ret_val < 0)
292 return ret_val;
293 snprintf(substream->pcm->id, sizeof(substream->pcm->id),
294 "%d", stream->stream_info.str_id);
295
296 ret_val = sst_platform_init_stream(substream);
297 if (ret_val)
298 return ret_val;
299 substream->runtime->hw.info = SNDRV_PCM_INFO_BLOCK_TRANSFER;
300 return ret_val;
301}
302
303static int sst_platform_pcm_trigger(struct snd_pcm_substream *substream,
304 int cmd)
305{
306 int ret_val = 0, str_id;
307 struct sst_runtime_stream *stream;
308 int str_cmd, status;
309
310 pr_debug("sst_platform_pcm_trigger called\n");
311 stream = substream->runtime->private_data;
312 str_id = stream->stream_info.str_id;
313 switch (cmd) {
314 case SNDRV_PCM_TRIGGER_START:
315 pr_debug("sst: Trigger Start\n");
316 str_cmd = SST_SND_START;
317 status = SST_PLATFORM_RUNNING;
318 stream->stream_info.mad_substream = substream;
319 break;
320 case SNDRV_PCM_TRIGGER_STOP:
321 pr_debug("sst: in stop\n");
322 str_cmd = SST_SND_DROP;
323 status = SST_PLATFORM_DROPPED;
324 break;
325 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
326 pr_debug("sst: in pause\n");
327 str_cmd = SST_SND_PAUSE;
328 status = SST_PLATFORM_PAUSED;
329 break;
330 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
331 pr_debug("sst: in pause release\n");
332 str_cmd = SST_SND_RESUME;
333 status = SST_PLATFORM_RUNNING;
334 break;
335 default:
336 return -EINVAL;
337 }
338 ret_val = stream->sstdrv_ops->pcm_control->device_control(str_cmd,
339 &str_id);
340 if (!ret_val)
341 sst_set_stream_status(stream, status);
342
343 return ret_val;
344}
345
346
347static snd_pcm_uframes_t sst_platform_pcm_pointer
348 (struct snd_pcm_substream *substream)
349{
350 struct sst_runtime_stream *stream;
351 int ret_val, status;
352 struct pcm_stream_info *str_info;
353
354 stream = substream->runtime->private_data;
355 status = sst_get_stream_status(stream);
356 if (status == SST_PLATFORM_INIT)
357 return 0;
358 str_info = &stream->stream_info;
359 ret_val = stream->sstdrv_ops->pcm_control->device_control(
360 SST_SND_BUFFER_POINTER, str_info);
361 if (ret_val) {
362 pr_err("sst: error code = %d\n", ret_val);
363 return ret_val;
364 }
365 return stream->stream_info.buffer_ptr;
366}
367
368static int sst_platform_pcm_hw_params(struct snd_pcm_substream *substream,
369 struct snd_pcm_hw_params *params)
370{
371 snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
372 memset(substream->runtime->dma_area, 0, params_buffer_bytes(params));
373
374 return 0;
375}
376
377static struct snd_pcm_ops sst_platform_ops = {
378 .open = sst_platform_open,
379 .close = sst_platform_close,
380 .ioctl = snd_pcm_lib_ioctl,
381 .prepare = sst_platform_pcm_prepare,
382 .trigger = sst_platform_pcm_trigger,
383 .pointer = sst_platform_pcm_pointer,
384 .hw_params = sst_platform_pcm_hw_params,
385};
386
387static void sst_pcm_free(struct snd_pcm *pcm)
388{
389 pr_debug("sst_pcm_free called\n");
390 snd_pcm_lib_preallocate_free_for_all(pcm);
391}
392
393int sst_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
394 struct snd_pcm *pcm)
395{
396 int retval = 0;
397
398 pr_debug("sst_pcm_new called\n");
399 if (dai->driver->playback.channels_min ||
400 dai->driver->capture.channels_min) {
401 retval = snd_pcm_lib_preallocate_pages_for_all(pcm,
402 SNDRV_DMA_TYPE_CONTINUOUS,
403 snd_dma_continuous_data(GFP_KERNEL),
404 SST_MIN_BUFFER, SST_MAX_BUFFER);
405 if (retval) {
406 pr_err("dma buffer allocationf fail\n");
407 return retval;
408 }
409 }
410 return retval;
411}
412struct snd_soc_platform_driver sst_soc_platform_drv = {
413 .ops = &sst_platform_ops,
414 .pcm_new = sst_pcm_new,
415 .pcm_free = sst_pcm_free,
416};
417
418static int sst_platform_probe(struct platform_device *pdev)
419{
420 int ret;
421
422 pr_debug("sst_platform_probe called\n");
423 ret = snd_soc_register_platform(&pdev->dev, &sst_soc_platform_drv);
424 if (ret) {
425 pr_err("registering soc platform failed\n");
426 return ret;
427 }
428
429 ret = snd_soc_register_dais(&pdev->dev,
430 sst_platform_dai, ARRAY_SIZE(sst_platform_dai));
431 if (ret) {
432 pr_err("registering cpu dais failed\n");
433 snd_soc_unregister_platform(&pdev->dev);
434 }
435 return ret;
436}
437
438static int sst_platform_remove(struct platform_device *pdev)
439{
440
441 snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(sst_platform_dai));
442 snd_soc_unregister_platform(&pdev->dev);
443 pr_debug("sst_platform_remove sucess\n");
444 return 0;
445}
446
447static struct platform_driver sst_platform_driver = {
448 .driver = {
449 .name = "sst-platform",
450 .owner = THIS_MODULE,
451 },
452 .probe = sst_platform_probe,
453 .remove = sst_platform_remove,
454};
455
456static int __init sst_soc_platform_init(void)
457{
458 pr_debug("sst_soc_platform_init called\n");
459 return platform_driver_register(&sst_platform_driver);
460}
461module_init(sst_soc_platform_init);
462
463static void __exit sst_soc_platform_exit(void)
464{
465 platform_driver_unregister(&sst_platform_driver);
466 pr_debug("sst_soc_platform_exit sucess\n");
467}
468module_exit(sst_soc_platform_exit);
469
470MODULE_DESCRIPTION("ASoC Intel(R) MID Platform driver");
471MODULE_AUTHOR("Vinod Koul <vinod.koul@intel.com>");
472MODULE_AUTHOR("Harsha Priya <priya.harsha@intel.com>");
473MODULE_LICENSE("GPL v2");
474MODULE_ALIAS("platform:sst-platform");
diff --git a/sound/soc/mid-x86/sst_platform.h b/sound/soc/mid-x86/sst_platform.h
new file mode 100644
index 000000000000..df370286694f
--- /dev/null
+++ b/sound/soc/mid-x86/sst_platform.h
@@ -0,0 +1,63 @@
1/*
2 * sst_platform.h - Intel MID Platform driver header file
3 *
4 * Copyright (C) 2010 Intel Corp
5 * Author: Vinod Koul <vinod.koul@intel.com>
6 * Author: Harsha Priya <priya.harsha@intel.com>
7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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 as published by
11 * the Free Software Foundation; version 2 of the License.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21 *
22 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
23 *
24 *
25 */
26
27#ifndef __SST_PLATFORMDRV_H__
28#define __SST_PLATFORMDRV_H__
29
30#define SST_MONO 1
31#define SST_STEREO 2
32#define SST_MAX_CAP 5
33
34#define SST_MIN_RATE 8000
35#define SST_MAX_RATE 48000
36#define SST_MIN_CHANNEL 1
37#define SST_MAX_CHANNEL 5
38#define SST_MAX_BUFFER (800*1024)
39#define SST_MIN_BUFFER (800*1024)
40#define SST_MIN_PERIOD_BYTES 32
41#define SST_MAX_PERIOD_BYTES SST_MAX_BUFFER
42#define SST_MIN_PERIODS 2
43#define SST_MAX_PERIODS (1024*2)
44#define SST_FIFO_SIZE 0
45#define SST_CARD_NAMES "intel_mid_card"
46#define MSIC_VENDOR_ID 3
47
48struct sst_runtime_stream {
49 int stream_status;
50 struct pcm_stream_info stream_info;
51 struct intel_sst_card_ops *sstdrv_ops;
52 spinlock_t status_lock;
53};
54
55enum sst_drv_status {
56 SST_PLATFORM_INIT = 1,
57 SST_PLATFORM_STARTED,
58 SST_PLATFORM_RUNNING,
59 SST_PLATFORM_PAUSED,
60 SST_PLATFORM_DROPPED,
61};
62
63#endif
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
index a088db6d5091..b5922984eac6 100644
--- a/sound/soc/omap/Kconfig
+++ b/sound/soc/omap/Kconfig
@@ -24,6 +24,7 @@ config SND_OMAP_SOC_RX51
24 select OMAP_MCBSP 24 select OMAP_MCBSP
25 select SND_OMAP_SOC_MCBSP 25 select SND_OMAP_SOC_MCBSP
26 select SND_SOC_TLV320AIC3X 26 select SND_SOC_TLV320AIC3X
27 select SND_SOC_TPA6130A2
27 help 28 help
28 Say Y if you want to add support for SoC audio on Nokia RX-51 29 Say Y if you want to add support for SoC audio on Nokia RX-51
29 hardware. This is also known as Nokia N900 product. 30 hardware. This is also known as Nokia N900 product.
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c
index 09fb0df8d416..d0986220eff9 100644
--- a/sound/soc/omap/rx51.c
+++ b/sound/soc/omap/rx51.c
@@ -31,6 +31,7 @@
31#include <sound/pcm.h> 31#include <sound/pcm.h>
32#include <sound/soc.h> 32#include <sound/soc.h>
33#include <plat/mcbsp.h> 33#include <plat/mcbsp.h>
34#include "../codecs/tpa6130a2.h"
34 35
35#include <asm/mach-types.h> 36#include <asm/mach-types.h>
36 37
@@ -39,6 +40,7 @@
39 40
40#define RX51_TVOUT_SEL_GPIO 40 41#define RX51_TVOUT_SEL_GPIO 40
41#define RX51_JACK_DETECT_GPIO 177 42#define RX51_JACK_DETECT_GPIO 177
43#define RX51_ECI_SW_GPIO 182
42/* 44/*
43 * REVISIT: TWL4030 GPIO base in RX-51. Now statically defined to 192. This 45 * REVISIT: TWL4030 GPIO base in RX-51. Now statically defined to 192. This
44 * gpio is reserved in arch/arm/mach-omap2/board-rx51-peripherals.c 46 * gpio is reserved in arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -47,7 +49,9 @@
47 49
48enum { 50enum {
49 RX51_JACK_DISABLED, 51 RX51_JACK_DISABLED,
50 RX51_JACK_TVOUT, /* tv-out */ 52 RX51_JACK_TVOUT, /* tv-out with stereo output */
53 RX51_JACK_HP, /* headphone: stereo output, no mic */
54 RX51_JACK_HS, /* headset: stereo output with mic */
51}; 55};
52 56
53static int rx51_spk_func; 57static int rx51_spk_func;
@@ -57,6 +61,19 @@ static int rx51_jack_func;
57static void rx51_ext_control(struct snd_soc_codec *codec) 61static void rx51_ext_control(struct snd_soc_codec *codec)
58{ 62{
59 struct snd_soc_dapm_context *dapm = &codec->dapm; 63 struct snd_soc_dapm_context *dapm = &codec->dapm;
64 int hp = 0, hs = 0, tvout = 0;
65
66 switch (rx51_jack_func) {
67 case RX51_JACK_TVOUT:
68 tvout = 1;
69 hp = 1;
70 break;
71 case RX51_JACK_HS:
72 hs = 1;
73 case RX51_JACK_HP:
74 hp = 1;
75 break;
76 }
60 77
61 if (rx51_spk_func) 78 if (rx51_spk_func)
62 snd_soc_dapm_enable_pin(dapm, "Ext Spk"); 79 snd_soc_dapm_enable_pin(dapm, "Ext Spk");
@@ -66,9 +83,16 @@ static void rx51_ext_control(struct snd_soc_codec *codec)
66 snd_soc_dapm_enable_pin(dapm, "DMic"); 83 snd_soc_dapm_enable_pin(dapm, "DMic");
67 else 84 else
68 snd_soc_dapm_disable_pin(dapm, "DMic"); 85 snd_soc_dapm_disable_pin(dapm, "DMic");
86 if (hp)
87 snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
88 else
89 snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
90 if (hs)
91 snd_soc_dapm_enable_pin(dapm, "HS Mic");
92 else
93 snd_soc_dapm_disable_pin(dapm, "HS Mic");
69 94
70 gpio_set_value(RX51_TVOUT_SEL_GPIO, 95 gpio_set_value(RX51_TVOUT_SEL_GPIO, tvout);
71 rx51_jack_func == RX51_JACK_TVOUT);
72 96
73 snd_soc_dapm_sync(dapm); 97 snd_soc_dapm_sync(dapm);
74} 98}
@@ -153,6 +177,19 @@ static int rx51_spk_event(struct snd_soc_dapm_widget *w,
153 return 0; 177 return 0;
154} 178}
155 179
180static int rx51_hp_event(struct snd_soc_dapm_widget *w,
181 struct snd_kcontrol *k, int event)
182{
183 struct snd_soc_codec *codec = w->dapm->codec;
184
185 if (SND_SOC_DAPM_EVENT_ON(event))
186 tpa6130a2_stereo_enable(codec, 1);
187 else
188 tpa6130a2_stereo_enable(codec, 0);
189
190 return 0;
191}
192
156static int rx51_get_input(struct snd_kcontrol *kcontrol, 193static int rx51_get_input(struct snd_kcontrol *kcontrol,
157 struct snd_ctl_elem_value *ucontrol) 194 struct snd_ctl_elem_value *ucontrol)
158{ 195{
@@ -203,7 +240,7 @@ static struct snd_soc_jack_gpio rx51_av_jack_gpios[] = {
203 { 240 {
204 .gpio = RX51_JACK_DETECT_GPIO, 241 .gpio = RX51_JACK_DETECT_GPIO,
205 .name = "avdet-gpio", 242 .name = "avdet-gpio",
206 .report = SND_JACK_VIDEOOUT, 243 .report = SND_JACK_HEADSET,
207 .invert = 1, 244 .invert = 1,
208 .debounce_time = 200, 245 .debounce_time = 200,
209 }, 246 },
@@ -212,19 +249,38 @@ static struct snd_soc_jack_gpio rx51_av_jack_gpios[] = {
212static const struct snd_soc_dapm_widget aic34_dapm_widgets[] = { 249static const struct snd_soc_dapm_widget aic34_dapm_widgets[] = {
213 SND_SOC_DAPM_SPK("Ext Spk", rx51_spk_event), 250 SND_SOC_DAPM_SPK("Ext Spk", rx51_spk_event),
214 SND_SOC_DAPM_MIC("DMic", NULL), 251 SND_SOC_DAPM_MIC("DMic", NULL),
252 SND_SOC_DAPM_HP("Headphone Jack", rx51_hp_event),
253 SND_SOC_DAPM_MIC("HS Mic", NULL),
254 SND_SOC_DAPM_LINE("FM Transmitter", NULL),
255};
256
257static const struct snd_soc_dapm_widget aic34_dapm_widgetsb[] = {
258 SND_SOC_DAPM_SPK("Earphone", NULL),
215}; 259};
216 260
217static const struct snd_soc_dapm_route audio_map[] = { 261static const struct snd_soc_dapm_route audio_map[] = {
218 {"Ext Spk", NULL, "HPLOUT"}, 262 {"Ext Spk", NULL, "HPLOUT"},
219 {"Ext Spk", NULL, "HPROUT"}, 263 {"Ext Spk", NULL, "HPROUT"},
264 {"Headphone Jack", NULL, "LLOUT"},
265 {"Headphone Jack", NULL, "RLOUT"},
266 {"FM Transmitter", NULL, "LLOUT"},
267 {"FM Transmitter", NULL, "RLOUT"},
220 268
221 {"DMic Rate 64", NULL, "Mic Bias 2V"}, 269 {"DMic Rate 64", NULL, "Mic Bias 2V"},
222 {"Mic Bias 2V", NULL, "DMic"}, 270 {"Mic Bias 2V", NULL, "DMic"},
223}; 271};
224 272
273static const struct snd_soc_dapm_route audio_mapb[] = {
274 {"b LINE2R", NULL, "MONO_LOUT"},
275 {"Earphone", NULL, "b HPLOUT"},
276
277 {"LINE1L", NULL, "b Mic Bias 2.5V"},
278 {"b Mic Bias 2.5V", NULL, "HS Mic"}
279};
280
225static const char *spk_function[] = {"Off", "On"}; 281static const char *spk_function[] = {"Off", "On"};
226static const char *input_function[] = {"ADC", "Digital Mic"}; 282static const char *input_function[] = {"ADC", "Digital Mic"};
227static const char *jack_function[] = {"Off", "TV-OUT"}; 283static const char *jack_function[] = {"Off", "TV-OUT", "Headphone", "Headset"};
228 284
229static const struct soc_enum rx51_enum[] = { 285static const struct soc_enum rx51_enum[] = {
230 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spk_function), spk_function), 286 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spk_function), spk_function),
@@ -239,6 +295,11 @@ static const struct snd_kcontrol_new aic34_rx51_controls[] = {
239 rx51_get_input, rx51_set_input), 295 rx51_get_input, rx51_set_input),
240 SOC_ENUM_EXT("Jack Function", rx51_enum[2], 296 SOC_ENUM_EXT("Jack Function", rx51_enum[2],
241 rx51_get_jack, rx51_set_jack), 297 rx51_get_jack, rx51_set_jack),
298 SOC_DAPM_PIN_SWITCH("FM Transmitter"),
299};
300
301static const struct snd_kcontrol_new aic34_rx51_controlsb[] = {
302 SOC_DAPM_PIN_SWITCH("Earphone"),
242}; 303};
243 304
244static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd) 305static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd)
@@ -265,11 +326,21 @@ static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd)
265 /* Set up RX-51 specific audio path audio_map */ 326 /* Set up RX-51 specific audio path audio_map */
266 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); 327 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
267 328
329 err = tpa6130a2_add_controls(codec);
330 if (err < 0)
331 return err;
332 snd_soc_limit_volume(codec, "TPA6130A2 Headphone Playback Volume", 42);
333
334 err = omap_mcbsp_st_add_controls(codec, 1);
335 if (err < 0)
336 return err;
337
268 snd_soc_dapm_sync(dapm); 338 snd_soc_dapm_sync(dapm);
269 339
270 /* AV jack detection */ 340 /* AV jack detection */
271 err = snd_soc_jack_new(codec, "AV Jack", 341 err = snd_soc_jack_new(codec, "AV Jack",
272 SND_JACK_VIDEOOUT, &rx51_av_jack); 342 SND_JACK_HEADSET | SND_JACK_VIDEOOUT,
343 &rx51_av_jack);
273 if (err) 344 if (err)
274 return err; 345 return err;
275 err = snd_soc_jack_add_gpios(&rx51_av_jack, 346 err = snd_soc_jack_add_gpios(&rx51_av_jack,
@@ -279,6 +350,24 @@ static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd)
279 return err; 350 return err;
280} 351}
281 352
353static int rx51_aic34b_init(struct snd_soc_dapm_context *dapm)
354{
355 int err;
356
357 err = snd_soc_add_controls(dapm->codec, aic34_rx51_controlsb,
358 ARRAY_SIZE(aic34_rx51_controlsb));
359 if (err < 0)
360 return err;
361
362 err = snd_soc_dapm_new_controls(dapm, aic34_dapm_widgetsb,
363 ARRAY_SIZE(aic34_dapm_widgetsb));
364 if (err < 0)
365 return 0;
366
367 return snd_soc_dapm_add_routes(dapm, audio_mapb,
368 ARRAY_SIZE(audio_mapb));
369}
370
282/* Digital audio interface glue - connects codec <--> CPU */ 371/* Digital audio interface glue - connects codec <--> CPU */
283static struct snd_soc_dai_link rx51_dai[] = { 372static struct snd_soc_dai_link rx51_dai[] = {
284 { 373 {
@@ -293,11 +382,30 @@ static struct snd_soc_dai_link rx51_dai[] = {
293 }, 382 },
294}; 383};
295 384
385struct snd_soc_aux_dev rx51_aux_dev[] = {
386 {
387 .name = "TLV320AIC34b",
388 .codec_name = "tlv320aic3x-codec.2-0019",
389 .init = rx51_aic34b_init,
390 },
391};
392
393static struct snd_soc_codec_conf rx51_codec_conf[] = {
394 {
395 .dev_name = "tlv320aic3x-codec.2-0019",
396 .name_prefix = "b",
397 },
398};
399
296/* Audio card */ 400/* Audio card */
297static struct snd_soc_card rx51_sound_card = { 401static struct snd_soc_card rx51_sound_card = {
298 .name = "RX-51", 402 .name = "RX-51",
299 .dai_link = rx51_dai, 403 .dai_link = rx51_dai,
300 .num_links = ARRAY_SIZE(rx51_dai), 404 .num_links = ARRAY_SIZE(rx51_dai),
405 .aux_dev = rx51_aux_dev,
406 .num_aux_devs = ARRAY_SIZE(rx51_aux_dev),
407 .codec_conf = rx51_codec_conf,
408 .num_configs = ARRAY_SIZE(rx51_codec_conf),
301}; 409};
302 410
303static struct platform_device *rx51_snd_device; 411static struct platform_device *rx51_snd_device;
@@ -309,10 +417,14 @@ static int __init rx51_soc_init(void)
309 if (!machine_is_nokia_rx51()) 417 if (!machine_is_nokia_rx51())
310 return -ENODEV; 418 return -ENODEV;
311 419
312 err = gpio_request(RX51_TVOUT_SEL_GPIO, "tvout_sel"); 420 err = gpio_request_one(RX51_TVOUT_SEL_GPIO,
421 GPIOF_DIR_OUT | GPIOF_INIT_LOW, "tvout_sel");
313 if (err) 422 if (err)
314 goto err_gpio_tvout_sel; 423 goto err_gpio_tvout_sel;
315 gpio_direction_output(RX51_TVOUT_SEL_GPIO, 0); 424 err = gpio_request_one(RX51_ECI_SW_GPIO,
425 GPIOF_DIR_OUT | GPIOF_INIT_HIGH, "eci_sw");
426 if (err)
427 goto err_gpio_eci_sw;
316 428
317 rx51_snd_device = platform_device_alloc("soc-audio", -1); 429 rx51_snd_device = platform_device_alloc("soc-audio", -1);
318 if (!rx51_snd_device) { 430 if (!rx51_snd_device) {
@@ -330,6 +442,8 @@ static int __init rx51_soc_init(void)
330err2: 442err2:
331 platform_device_put(rx51_snd_device); 443 platform_device_put(rx51_snd_device);
332err1: 444err1:
445 gpio_free(RX51_ECI_SW_GPIO);
446err_gpio_eci_sw:
333 gpio_free(RX51_TVOUT_SEL_GPIO); 447 gpio_free(RX51_TVOUT_SEL_GPIO);
334err_gpio_tvout_sel: 448err_gpio_tvout_sel:
335 449
@@ -342,6 +456,7 @@ static void __exit rx51_soc_exit(void)
342 rx51_av_jack_gpios); 456 rx51_av_jack_gpios);
343 457
344 platform_device_unregister(rx51_snd_device); 458 platform_device_unregister(rx51_snd_device);
459 gpio_free(RX51_ECI_SW_GPIO);
345 gpio_free(RX51_TVOUT_SEL_GPIO); 460 gpio_free(RX51_TVOUT_SEL_GPIO);
346} 461}
347 462
diff --git a/sound/soc/pxa/raumfeld.c b/sound/soc/pxa/raumfeld.c
index 0fd60f423036..2afabaf59491 100644
--- a/sound/soc/pxa/raumfeld.c
+++ b/sound/soc/pxa/raumfeld.c
@@ -151,13 +151,13 @@ static struct snd_soc_ops raumfeld_cs4270_ops = {
151 .hw_params = raumfeld_cs4270_hw_params, 151 .hw_params = raumfeld_cs4270_hw_params,
152}; 152};
153 153
154static int raumfeld_line_suspend(struct platform_device *pdev, pm_message_t state) 154static int raumfeld_line_suspend(struct snd_soc_card *card)
155{ 155{
156 raumfeld_enable_audio(false); 156 raumfeld_enable_audio(false);
157 return 0; 157 return 0;
158} 158}
159 159
160static int raumfeld_line_resume(struct platform_device *pdev) 160static int raumfeld_line_resume(struct snd_soc_card *card)
161{ 161{
162 raumfeld_enable_audio(true); 162 raumfeld_enable_audio(true);
163 return 0; 163 return 0;
@@ -229,19 +229,19 @@ static struct snd_soc_dai_link raumfeld_dai[] = {
229{ 229{
230 .name = "ak4104", 230 .name = "ak4104",
231 .stream_name = "Playback", 231 .stream_name = "Playback",
232 .cpu_dai_name = "pxa-ssp-dai.1", 232 .cpu_dai_name = "pxa-ssp-dai.1",
233 .codec_dai_name = "ak4104-hifi", 233 .codec_dai_name = "ak4104-hifi",
234 .platform_name = "pxa-pcm-audio", 234 .platform_name = "pxa-pcm-audio",
235 .ops = &raumfeld_ak4104_ops, 235 .ops = &raumfeld_ak4104_ops,
236 .codec_name = "ak4104-codec.0", 236 .codec_name = "ak4104-codec.0",
237}, 237},
238{ 238{
239 .name = "CS4270", 239 .name = "CS4270",
240 .stream_name = "CS4270", 240 .stream_name = "CS4270",
241 .cpu_dai_name = "pxa-ssp-dai.0", 241 .cpu_dai_name = "pxa-ssp-dai.0",
242 .platform_name = "pxa-pcm-audio", 242 .platform_name = "pxa-pcm-audio",
243 .codec_dai_name = "cs4270-hifi", 243 .codec_dai_name = "cs4270-hifi",
244 .codec_name = "cs4270-codec.0-0048", 244 .codec_name = "cs4270-codec.0-0048",
245 .ops = &raumfeld_cs4270_ops, 245 .ops = &raumfeld_cs4270_ops,
246},}; 246},};
247 247
diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c
index 4b6e5d608b42..9a2351366957 100644
--- a/sound/soc/pxa/tosa.c
+++ b/sound/soc/pxa/tosa.c
@@ -237,7 +237,7 @@ static struct snd_soc_dai_link tosa_dai[] = {
237}, 237},
238}; 238};
239 239
240static int tosa_probe(struct platform_device *dev) 240static int tosa_probe(struct snd_soc_card *card)
241{ 241{
242 int ret; 242 int ret;
243 243
@@ -251,7 +251,7 @@ static int tosa_probe(struct platform_device *dev)
251 return ret; 251 return ret;
252} 252}
253 253
254static int tosa_remove(struct platform_device *dev) 254static int tosa_remove(struct snd_soc_card *card)
255{ 255{
256 gpio_free(TOSA_GPIO_L_MUTE); 256 gpio_free(TOSA_GPIO_L_MUTE);
257 return 0; 257 return 0;
diff --git a/sound/soc/pxa/z2.c b/sound/soc/pxa/z2.c
index 3ceaef68e01d..d69d9fc32233 100644
--- a/sound/soc/pxa/z2.c
+++ b/sound/soc/pxa/z2.c
@@ -95,6 +95,11 @@ static struct snd_soc_jack_pin hs_jack_pins[] = {
95 .pin = "Headphone Jack", 95 .pin = "Headphone Jack",
96 .mask = SND_JACK_HEADPHONE, 96 .mask = SND_JACK_HEADPHONE,
97 }, 97 },
98 {
99 .pin = "Ext Spk",
100 .mask = SND_JACK_HEADPHONE,
101 .invert = 1
102 },
98}; 103};
99 104
100/* Headset jack detection gpios */ 105/* Headset jack detection gpios */
@@ -147,7 +152,7 @@ static int z2_wm8750_init(struct snd_soc_pcm_runtime *rtd)
147 snd_soc_dapm_disable_pin(dapm, "LINPUT3"); 152 snd_soc_dapm_disable_pin(dapm, "LINPUT3");
148 snd_soc_dapm_disable_pin(dapm, "RINPUT3"); 153 snd_soc_dapm_disable_pin(dapm, "RINPUT3");
149 snd_soc_dapm_disable_pin(dapm, "OUT3"); 154 snd_soc_dapm_disable_pin(dapm, "OUT3");
150 snd_soc_dapm_disable_pin(dapm, "MONO"); 155 snd_soc_dapm_disable_pin(dapm, "MONO1");
151 156
152 /* Add z2 specific widgets */ 157 /* Add z2 specific widgets */
153 snd_soc_dapm_new_controls(dapm, wm8750_dapm_widgets, 158 snd_soc_dapm_new_controls(dapm, wm8750_dapm_widgets,
diff --git a/sound/soc/pxa/zylonite.c b/sound/soc/pxa/zylonite.c
index 25bba108fea3..ac577263b3e3 100644
--- a/sound/soc/pxa/zylonite.c
+++ b/sound/soc/pxa/zylonite.c
@@ -189,7 +189,7 @@ static struct snd_soc_dai_link zylonite_dai[] = {
189}, 189},
190}; 190};
191 191
192static int zylonite_probe(struct platform_device *pdev) 192static int zylonite_probe(struct snd_soc_card *card)
193{ 193{
194 int ret; 194 int ret;
195 195
@@ -216,7 +216,7 @@ static int zylonite_probe(struct platform_device *pdev)
216 return 0; 216 return 0;
217} 217}
218 218
219static int zylonite_remove(struct platform_device *pdev) 219static int zylonite_remove(struct snd_soc_card *card)
220{ 220{
221 if (clk_pout) { 221 if (clk_pout) {
222 clk_disable(pout); 222 clk_disable(pout);
@@ -226,8 +226,7 @@ static int zylonite_remove(struct platform_device *pdev)
226 return 0; 226 return 0;
227} 227}
228 228
229static int zylonite_suspend_post(struct platform_device *pdev, 229static int zylonite_suspend_post(struct snd_soc_card *card)
230 pm_message_t state)
231{ 230{
232 if (clk_pout) 231 if (clk_pout)
233 clk_disable(pout); 232 clk_disable(pout);
@@ -235,7 +234,7 @@ static int zylonite_suspend_post(struct platform_device *pdev,
235 return 0; 234 return 0;
236} 235}
237 236
238static int zylonite_resume_pre(struct platform_device *pdev) 237static int zylonite_resume_pre(struct snd_soc_card *card)
239{ 238{
240 int ret = 0; 239 int ret = 0;
241 240
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig
index d6713d5a90e7..a3fdfb631469 100644
--- a/sound/soc/samsung/Kconfig
+++ b/sound/soc/samsung/Kconfig
@@ -35,23 +35,16 @@ config SND_SAMSUNG_I2S
35 tristate 35 tristate
36 36
37config SND_SOC_SAMSUNG_NEO1973_WM8753 37config SND_SOC_SAMSUNG_NEO1973_WM8753
38 tristate "SoC I2S Audio support for NEO1973 - WM8753" 38 tristate "Audio support for Openmoko Neo1973 Smartphones (GTA01/GTA02)"
39 depends on SND_SOC_SAMSUNG && MACH_NEO1973_GTA01 39 depends on SND_SOC_SAMSUNG && (MACH_NEO1973_GTA01 || MACH_NEO1973_GTA02)
40 select SND_S3C24XX_I2S 40 select SND_S3C24XX_I2S
41 select SND_SOC_WM8753 41 select SND_SOC_WM8753
42 select SND_SOC_LM4857 if MACH_NEO1973_GTA01
43 select SND_SOC_DFBMCS320
42 help 44 help
43 Say Y if you want to add support for SoC audio on smdk2440 45 Say Y here to enable audio support for the Openmoko Neo1973
44 with the WM8753. 46 Smartphones.
45 47
46config SND_SOC_SAMSUNG_NEO1973_GTA02_WM8753
47 tristate "Audio support for the Openmoko Neo FreeRunner (GTA02)"
48 depends on SND_SOC_SAMSUNG && MACH_NEO1973_GTA02
49 select SND_S3C24XX_I2S
50 select SND_SOC_WM8753
51 help
52 This driver provides audio support for the Openmoko Neo FreeRunner
53 smartphone.
54
55config SND_SOC_SAMSUNG_JIVE_WM8750 48config SND_SOC_SAMSUNG_JIVE_WM8750
56 tristate "SoC I2S Audio support for Jive" 49 tristate "SoC I2S Audio support for Jive"
57 depends on SND_SOC_SAMSUNG && MACH_JIVE 50 depends on SND_SOC_SAMSUNG && MACH_JIVE
diff --git a/sound/soc/samsung/Makefile b/sound/soc/samsung/Makefile
index 705d4e8a6724..294dec05c26d 100644
--- a/sound/soc/samsung/Makefile
+++ b/sound/soc/samsung/Makefile
@@ -20,7 +20,6 @@ obj-$(CONFIG_SND_SAMSUNG_I2S) += snd-soc-i2s.o
20# S3C24XX Machine Support 20# S3C24XX Machine Support
21snd-soc-jive-wm8750-objs := jive_wm8750.o 21snd-soc-jive-wm8750-objs := jive_wm8750.o
22snd-soc-neo1973-wm8753-objs := neo1973_wm8753.o 22snd-soc-neo1973-wm8753-objs := neo1973_wm8753.o
23snd-soc-neo1973-gta02-wm8753-objs := neo1973_gta02_wm8753.o
24snd-soc-smdk2443-wm9710-objs := smdk2443_wm9710.o 23snd-soc-smdk2443-wm9710-objs := smdk2443_wm9710.o
25snd-soc-ln2440sbc-alc650-objs := ln2440sbc_alc650.o 24snd-soc-ln2440sbc-alc650-objs := ln2440sbc_alc650.o
26snd-soc-s3c24xx-uda134x-objs := s3c24xx_uda134x.o 25snd-soc-s3c24xx-uda134x-objs := s3c24xx_uda134x.o
@@ -38,7 +37,6 @@ snd-soc-smdk-spdif-objs := smdk_spdif.o
38 37
39obj-$(CONFIG_SND_SOC_SAMSUNG_JIVE_WM8750) += snd-soc-jive-wm8750.o 38obj-$(CONFIG_SND_SOC_SAMSUNG_JIVE_WM8750) += snd-soc-jive-wm8750.o
40obj-$(CONFIG_SND_SOC_SAMSUNG_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o 39obj-$(CONFIG_SND_SOC_SAMSUNG_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o
41obj-$(CONFIG_SND_SOC_SAMSUNG_NEO1973_GTA02_WM8753) += snd-soc-neo1973-gta02-wm8753.o
42obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK2443_WM9710) += snd-soc-smdk2443-wm9710.o 40obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK2443_WM9710) += snd-soc-smdk2443-wm9710.o
43obj-$(CONFIG_SND_SOC_SAMSUNG_LN2440SBC_ALC650) += snd-soc-ln2440sbc-alc650.o 41obj-$(CONFIG_SND_SOC_SAMSUNG_LN2440SBC_ALC650) += snd-soc-ln2440sbc-alc650.o
44obj-$(CONFIG_SND_SOC_SAMSUNG_S3C24XX_UDA134X) += snd-soc-s3c24xx-uda134x.o 42obj-$(CONFIG_SND_SOC_SAMSUNG_S3C24XX_UDA134X) += snd-soc-s3c24xx-uda134x.o
diff --git a/sound/soc/samsung/ac97.c b/sound/soc/samsung/ac97.c
index 4770a9550341..f97110e72e85 100644
--- a/sound/soc/samsung/ac97.c
+++ b/sound/soc/samsung/ac97.c
@@ -12,24 +12,24 @@
12 * published by the Free Software Foundation. 12 * published by the Free Software Foundation.
13 */ 13 */
14 14
15#include <linux/init.h>
16#include <linux/module.h>
17#include <linux/io.h> 15#include <linux/io.h>
18#include <linux/delay.h> 16#include <linux/delay.h>
19#include <linux/clk.h> 17#include <linux/clk.h>
20 18
21#include <sound/soc.h> 19#include <sound/soc.h>
22 20
23#include <plat/regs-ac97.h>
24#include <mach/dma.h> 21#include <mach/dma.h>
22#include <plat/regs-ac97.h>
25#include <plat/audio.h> 23#include <plat/audio.h>
26 24
27#include "dma.h" 25#include "dma.h"
28#include "ac97.h"
29 26
30#define AC_CMD_ADDR(x) (x << 16) 27#define AC_CMD_ADDR(x) (x << 16)
31#define AC_CMD_DATA(x) (x & 0xffff) 28#define AC_CMD_DATA(x) (x & 0xffff)
32 29
30#define S3C_AC97_DAI_PCM 0
31#define S3C_AC97_DAI_MIC 1
32
33struct s3c_ac97_info { 33struct s3c_ac97_info {
34 struct clk *ac97_clk; 34 struct clk *ac97_clk;
35 void __iomem *regs; 35 void __iomem *regs;
diff --git a/sound/soc/samsung/ac97.h b/sound/soc/samsung/ac97.h
deleted file mode 100644
index 0d0e1b511457..000000000000
--- a/sound/soc/samsung/ac97.h
+++ /dev/null
@@ -1,21 +0,0 @@
1/* sound/soc/samsung/ac97.h
2 *
3 * ALSA SoC Audio Layer - S3C AC97 Controller driver
4 * Evolved from s3c2443-ac97.h
5 *
6 * Copyright (c) 2010 Samsung Electronics Co. Ltd
7 * Author: Jaswinder Singh <jassi.brar@samsung.com>
8 * Credits: Graeme Gregory, Sean Choi
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#ifndef __S3C_AC97_H_
16#define __S3C_AC97_H_
17
18#define S3C_AC97_DAI_PCM 0
19#define S3C_AC97_DAI_MIC 1
20
21#endif /* __S3C_AC97_H_ */
diff --git a/sound/soc/samsung/dma.c b/sound/soc/samsung/dma.c
index 21240198c5d6..5cb3b880f0d5 100644
--- a/sound/soc/samsung/dma.c
+++ b/sound/soc/samsung/dma.c
@@ -14,17 +14,11 @@
14 * option) any later version. 14 * option) any later version.
15 */ 15 */
16 16
17#include <linux/module.h>
18#include <linux/init.h>
19#include <linux/io.h>
20#include <linux/platform_device.h>
21#include <linux/slab.h> 17#include <linux/slab.h>
22#include <linux/dma-mapping.h> 18#include <linux/dma-mapping.h>
23 19
24#include <sound/core.h>
25#include <sound/pcm.h>
26#include <sound/pcm_params.h>
27#include <sound/soc.h> 20#include <sound/soc.h>
21#include <sound/pcm_params.h>
28 22
29#include <asm/dma.h> 23#include <asm/dma.h>
30#include <mach/hardware.h> 24#include <mach/hardware.h>
@@ -32,6 +26,9 @@
32 26
33#include "dma.h" 27#include "dma.h"
34 28
29#define ST_RUNNING (1<<0)
30#define ST_OPENED (1<<1)
31
35static const struct snd_pcm_hardware dma_hardware = { 32static const struct snd_pcm_hardware dma_hardware = {
36 .info = SNDRV_PCM_INFO_INTERLEAVED | 33 .info = SNDRV_PCM_INFO_INTERLEAVED |
37 SNDRV_PCM_INFO_BLOCK_TRANSFER | 34 SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -313,7 +310,7 @@ dma_pointer(struct snd_pcm_substream *substream)
313 /* we seem to be getting the odd error from the pcm library due 310 /* we seem to be getting the odd error from the pcm library due
314 * to out-of-bounds pointers. this is maybe due to the dma engine 311 * to out-of-bounds pointers. this is maybe due to the dma engine
315 * not having loaded the new values for the channel before being 312 * not having loaded the new values for the channel before being
316 * callled... (todo - fix ) 313 * called... (todo - fix )
317 */ 314 */
318 315
319 if (res >= snd_pcm_lib_buffer_bytes(substream)) { 316 if (res >= snd_pcm_lib_buffer_bytes(substream)) {
diff --git a/sound/soc/samsung/dma.h b/sound/soc/samsung/dma.h
index f8cd2b4223af..c50659269a40 100644
--- a/sound/soc/samsung/dma.h
+++ b/sound/soc/samsung/dma.h
@@ -12,9 +12,6 @@
12#ifndef _S3C_AUDIO_H 12#ifndef _S3C_AUDIO_H
13#define _S3C_AUDIO_H 13#define _S3C_AUDIO_H
14 14
15#define ST_RUNNING (1<<0)
16#define ST_OPENED (1<<1)
17
18struct s3c_dma_params { 15struct s3c_dma_params {
19 struct s3c2410_dma_client *client; /* stream identifier */ 16 struct s3c2410_dma_client *client; /* stream identifier */
20 int channel; /* Channel ID */ 17 int channel; /* Channel ID */
@@ -22,9 +19,4 @@ struct s3c_dma_params {
22 int dma_size; /* Size of the DMA transfer */ 19 int dma_size; /* Size of the DMA transfer */
23}; 20};
24 21
25#define S3C24XX_DAI_I2S 0
26
27/* platform data */
28extern struct snd_ac97_bus_ops s3c24xx_ac97_ops;
29
30#endif 22#endif
diff --git a/sound/soc/samsung/goni_wm8994.c b/sound/soc/samsung/goni_wm8994.c
index 34dd9ef1b9c0..f6b3a3ce5919 100644
--- a/sound/soc/samsung/goni_wm8994.c
+++ b/sound/soc/samsung/goni_wm8994.c
@@ -11,21 +11,13 @@
11 * 11 *
12 */ 12 */
13 13
14#include <linux/module.h>
15#include <linux/moduleparam.h>
16#include <linux/io.h>
17#include <linux/platform_device.h>
18#include <sound/soc.h> 14#include <sound/soc.h>
19#include <sound/jack.h> 15#include <sound/jack.h>
16
20#include <asm/mach-types.h> 17#include <asm/mach-types.h>
21#include <mach/gpio.h> 18#include <mach/gpio.h>
22#include <mach/regs-clock.h>
23 19
24#include <linux/mfd/wm8994/core.h>
25#include <linux/mfd/wm8994/registers.h>
26#include "../codecs/wm8994.h" 20#include "../codecs/wm8994.h"
27#include "dma.h"
28#include "i2s.h"
29 21
30#define MACHINE_NAME 0 22#define MACHINE_NAME 0
31#define CPU_VOICE_DAI 1 23#define CPU_VOICE_DAI 1
diff --git a/sound/soc/samsung/h1940_uda1380.c b/sound/soc/samsung/h1940_uda1380.c
index c45f7ce14d61..241f55d00660 100644
--- a/sound/soc/samsung/h1940_uda1380.c
+++ b/sound/soc/samsung/h1940_uda1380.c
@@ -13,25 +13,16 @@
13 * 13 *
14 */ 14 */
15 15
16#include <linux/module.h>
17#include <linux/moduleparam.h>
18#include <linux/platform_device.h>
19#include <linux/i2c.h>
20#include <linux/gpio.h> 16#include <linux/gpio.h>
21 17
22#include <sound/soc.h> 18#include <sound/soc.h>
23#include <sound/uda1380.h>
24#include <sound/jack.h> 19#include <sound/jack.h>
25 20
26#include <plat/regs-iis.h> 21#include <plat/regs-iis.h>
27
28#include <mach/h1940-latch.h> 22#include <mach/h1940-latch.h>
29
30#include <asm/mach-types.h> 23#include <asm/mach-types.h>
31 24
32#include "dma.h"
33#include "s3c24xx-i2s.h" 25#include "s3c24xx-i2s.h"
34#include "../codecs/uda1380.h"
35 26
36static unsigned int rates[] = { 27static unsigned int rates[] = {
37 11025, 28 11025,
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index d00ac3a7102c..ffa09b3b2caa 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -15,9 +15,8 @@
15#include <linux/clk.h> 15#include <linux/clk.h>
16#include <linux/io.h> 16#include <linux/io.h>
17 17
18#include <sound/pcm.h>
19#include <sound/pcm_params.h>
20#include <sound/soc.h> 18#include <sound/soc.h>
19#include <sound/pcm_params.h>
21 20
22#include <plat/audio.h> 21#include <plat/audio.h>
23 22
diff --git a/sound/soc/samsung/jive_wm8750.c b/sound/soc/samsung/jive_wm8750.c
index 08802520e014..3b53ad54bc33 100644
--- a/sound/soc/samsung/jive_wm8750.c
+++ b/sound/soc/samsung/jive_wm8750.c
@@ -11,22 +11,11 @@
11 * published by the Free Software Foundation. 11 * published by the Free Software Foundation.
12*/ 12*/
13 13
14#include <linux/module.h>
15#include <linux/moduleparam.h>
16#include <linux/timer.h>
17#include <linux/interrupt.h>
18#include <linux/platform_device.h>
19#include <linux/clk.h>
20
21#include <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/soc.h> 14#include <sound/soc.h>
24 15
25#include <asm/mach-types.h> 16#include <asm/mach-types.h>
26 17
27#include "dma.h"
28#include "s3c2412-i2s.h" 18#include "s3c2412-i2s.h"
29
30#include "../codecs/wm8750.h" 19#include "../codecs/wm8750.h"
31 20
32static const struct snd_soc_dapm_route audio_map[] = { 21static const struct snd_soc_dapm_route audio_map[] = {
diff --git a/sound/soc/samsung/lm4857.h b/sound/soc/samsung/lm4857.h
deleted file mode 100644
index 0cf5b7011d6f..000000000000
--- a/sound/soc/samsung/lm4857.h
+++ /dev/null
@@ -1,32 +0,0 @@
1/*
2 * lm4857.h -- ALSA Soc Audio Layer
3 *
4 * Copyright 2007 Wolfson Microelectronics PLC.
5 * Author: Graeme Gregory
6 * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 * Revision history
14 * 18th Jun 2007 Initial version.
15 */
16
17#ifndef LM4857_H_
18#define LM4857_H_
19
20/* The register offsets in the cache array */
21#define LM4857_MVOL 0
22#define LM4857_LVOL 1
23#define LM4857_RVOL 2
24#define LM4857_CTRL 3
25
26/* the shifts required to set these bits */
27#define LM4857_3D 5
28#define LM4857_WAKEUP 5
29#define LM4857_EPGAIN 4
30
31#endif /*LM4857_H_*/
32
diff --git a/sound/soc/samsung/ln2440sbc_alc650.c b/sound/soc/samsung/ln2440sbc_alc650.c
index a2bb34def740..bd91c19a6c08 100644
--- a/sound/soc/samsung/ln2440sbc_alc650.c
+++ b/sound/soc/samsung/ln2440sbc_alc650.c
@@ -16,15 +16,8 @@
16 * 16 *
17 */ 17 */
18 18
19#include <linux/module.h>
20#include <linux/device.h>
21#include <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/soc.h> 19#include <sound/soc.h>
24 20
25#include "dma.h"
26#include "ac97.h"
27
28static struct snd_soc_card ln2440sbc; 21static struct snd_soc_card ln2440sbc;
29 22
30static struct snd_soc_dai_link ln2440sbc_dai[] = { 23static struct snd_soc_dai_link ln2440sbc_dai[] = {
diff --git a/sound/soc/samsung/neo1973_gta02_wm8753.c b/sound/soc/samsung/neo1973_gta02_wm8753.c
deleted file mode 100644
index 0d0ae2b9eef6..000000000000
--- a/sound/soc/samsung/neo1973_gta02_wm8753.c
+++ /dev/null
@@ -1,504 +0,0 @@
1/*
2 * neo1973_gta02_wm8753.c -- SoC audio for Openmoko Freerunner(GTA02)
3 *
4 * Copyright 2007 Openmoko Inc
5 * Author: Graeme Gregory <graeme@openmoko.org>
6 * Copyright 2007 Wolfson Microelectronics PLC.
7 * Author: Graeme Gregory <linux@wolfsonmicro.com>
8 * Copyright 2009 Wolfson Microelectronics
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 */
15
16#include <linux/module.h>
17#include <linux/moduleparam.h>
18#include <linux/timer.h>
19#include <linux/interrupt.h>
20#include <linux/platform_device.h>
21#include <linux/gpio.h>
22#include <sound/core.h>
23#include <sound/pcm.h>
24#include <sound/soc.h>
25
26#include <asm/mach-types.h>
27
28#include <plat/regs-iis.h>
29
30#include <mach/regs-clock.h>
31#include <asm/io.h>
32#include <mach/gta02.h>
33#include "../codecs/wm8753.h"
34#include "dma.h"
35#include "s3c24xx-i2s.h"
36
37static struct snd_soc_card neo1973_gta02;
38
39static int neo1973_gta02_hifi_hw_params(struct snd_pcm_substream *substream,
40 struct snd_pcm_hw_params *params)
41{
42 struct snd_soc_pcm_runtime *rtd = substream->private_data;
43 struct snd_soc_dai *codec_dai = rtd->codec_dai;
44 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
45 unsigned int pll_out = 0, bclk = 0;
46 int ret = 0;
47 unsigned long iis_clkrate;
48
49 iis_clkrate = s3c24xx_i2s_get_clockrate();
50
51 switch (params_rate(params)) {
52 case 8000:
53 case 16000:
54 pll_out = 12288000;
55 break;
56 case 48000:
57 bclk = WM8753_BCLK_DIV_4;
58 pll_out = 12288000;
59 break;
60 case 96000:
61 bclk = WM8753_BCLK_DIV_2;
62 pll_out = 12288000;
63 break;
64 case 11025:
65 bclk = WM8753_BCLK_DIV_16;
66 pll_out = 11289600;
67 break;
68 case 22050:
69 bclk = WM8753_BCLK_DIV_8;
70 pll_out = 11289600;
71 break;
72 case 44100:
73 bclk = WM8753_BCLK_DIV_4;
74 pll_out = 11289600;
75 break;
76 case 88200:
77 bclk = WM8753_BCLK_DIV_2;
78 pll_out = 11289600;
79 break;
80 }
81
82 /* set codec DAI configuration */
83 ret = snd_soc_dai_set_fmt(codec_dai,
84 SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
85 SND_SOC_DAIFMT_CBM_CFM);
86 if (ret < 0)
87 return ret;
88
89 /* set cpu DAI configuration */
90 ret = snd_soc_dai_set_fmt(cpu_dai,
91 SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
92 SND_SOC_DAIFMT_CBM_CFM);
93 if (ret < 0)
94 return ret;
95
96 /* set the codec system clock for DAC and ADC */
97 ret = snd_soc_dai_set_sysclk(codec_dai, WM8753_MCLK, pll_out,
98 SND_SOC_CLOCK_IN);
99 if (ret < 0)
100 return ret;
101
102 /* set MCLK division for sample rate */
103 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK,
104 S3C2410_IISMOD_32FS);
105 if (ret < 0)
106 return ret;
107
108 /* set codec BCLK division for sample rate */
109 ret = snd_soc_dai_set_clkdiv(codec_dai,
110 WM8753_BCLKDIV, bclk);
111 if (ret < 0)
112 return ret;
113
114 /* set prescaler division for sample rate */
115 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER,
116 S3C24XX_PRESCALE(4, 4));
117 if (ret < 0)
118 return ret;
119
120 /* codec PLL input is PCLK/4 */
121 ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0,
122 iis_clkrate / 4, pll_out);
123 if (ret < 0)
124 return ret;
125
126 return 0;
127}
128
129static int neo1973_gta02_hifi_hw_free(struct snd_pcm_substream *substream)
130{
131 struct snd_soc_pcm_runtime *rtd = substream->private_data;
132 struct snd_soc_dai *codec_dai = rtd->codec_dai;
133
134 /* disable the PLL */
135 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, 0, 0);
136}
137
138/*
139 * Neo1973 WM8753 HiFi DAI opserations.
140 */
141static struct snd_soc_ops neo1973_gta02_hifi_ops = {
142 .hw_params = neo1973_gta02_hifi_hw_params,
143 .hw_free = neo1973_gta02_hifi_hw_free,
144};
145
146static int neo1973_gta02_voice_hw_params(
147 struct snd_pcm_substream *substream,
148 struct snd_pcm_hw_params *params)
149{
150 struct snd_soc_pcm_runtime *rtd = substream->private_data;
151 struct snd_soc_dai *codec_dai = rtd->codec_dai;
152 unsigned int pcmdiv = 0;
153 int ret = 0;
154 unsigned long iis_clkrate;
155
156 iis_clkrate = s3c24xx_i2s_get_clockrate();
157
158 if (params_rate(params) != 8000)
159 return -EINVAL;
160 if (params_channels(params) != 1)
161 return -EINVAL;
162
163 pcmdiv = WM8753_PCM_DIV_6; /* 2.048 MHz */
164
165 /* todo: gg check mode (DSP_B) against CSR datasheet */
166 /* set codec DAI configuration */
167 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_B |
168 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
169 if (ret < 0)
170 return ret;
171
172 /* set the codec system clock for DAC and ADC */
173 ret = snd_soc_dai_set_sysclk(codec_dai, WM8753_PCMCLK,
174 12288000, SND_SOC_CLOCK_IN);
175 if (ret < 0)
176 return ret;
177
178 /* set codec PCM division for sample rate */
179 ret = snd_soc_dai_set_clkdiv(codec_dai, WM8753_PCMDIV,
180 pcmdiv);
181 if (ret < 0)
182 return ret;
183
184 /* configure and enable PLL for 12.288MHz output */
185 ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0,
186 iis_clkrate / 4, 12288000);
187 if (ret < 0)
188 return ret;
189
190 return 0;
191}
192
193static int neo1973_gta02_voice_hw_free(struct snd_pcm_substream *substream)
194{
195 struct snd_soc_pcm_runtime *rtd = substream->private_data;
196 struct snd_soc_dai *codec_dai = rtd->codec_dai;
197
198 /* disable the PLL */
199 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 0, 0);
200}
201
202static struct snd_soc_ops neo1973_gta02_voice_ops = {
203 .hw_params = neo1973_gta02_voice_hw_params,
204 .hw_free = neo1973_gta02_voice_hw_free,
205};
206
207#define LM4853_AMP 1
208#define LM4853_SPK 2
209
210static u8 lm4853_state;
211
212/* This has no effect, it exists only to maintain compatibility with
213 * existing ALSA state files.
214 */
215static int lm4853_set_state(struct snd_kcontrol *kcontrol,
216 struct snd_ctl_elem_value *ucontrol)
217{
218 int val = ucontrol->value.integer.value[0];
219
220 if (val)
221 lm4853_state |= LM4853_AMP;
222 else
223 lm4853_state &= ~LM4853_AMP;
224
225 return 0;
226}
227
228static int lm4853_get_state(struct snd_kcontrol *kcontrol,
229 struct snd_ctl_elem_value *ucontrol)
230{
231 ucontrol->value.integer.value[0] = lm4853_state & LM4853_AMP;
232
233 return 0;
234}
235
236static int lm4853_set_spk(struct snd_kcontrol *kcontrol,
237 struct snd_ctl_elem_value *ucontrol)
238{
239 int val = ucontrol->value.integer.value[0];
240
241 if (val) {
242 lm4853_state |= LM4853_SPK;
243 gpio_set_value(GTA02_GPIO_HP_IN, 0);
244 } else {
245 lm4853_state &= ~LM4853_SPK;
246 gpio_set_value(GTA02_GPIO_HP_IN, 1);
247 }
248
249 return 0;
250}
251
252static int lm4853_get_spk(struct snd_kcontrol *kcontrol,
253 struct snd_ctl_elem_value *ucontrol)
254{
255 ucontrol->value.integer.value[0] = (lm4853_state & LM4853_SPK) >> 1;
256
257 return 0;
258}
259
260static int lm4853_event(struct snd_soc_dapm_widget *w,
261 struct snd_kcontrol *k,
262 int event)
263{
264 gpio_set_value(GTA02_GPIO_AMP_SHUT, SND_SOC_DAPM_EVENT_OFF(event));
265
266 return 0;
267}
268
269static const struct snd_soc_dapm_widget wm8753_dapm_widgets[] = {
270 SND_SOC_DAPM_SPK("Stereo Out", lm4853_event),
271 SND_SOC_DAPM_LINE("GSM Line Out", NULL),
272 SND_SOC_DAPM_LINE("GSM Line In", NULL),
273 SND_SOC_DAPM_MIC("Headset Mic", NULL),
274 SND_SOC_DAPM_MIC("Handset Mic", NULL),
275 SND_SOC_DAPM_SPK("Handset Spk", NULL),
276};
277
278
279/* example machine audio_mapnections */
280static const struct snd_soc_dapm_route audio_map[] = {
281
282 /* Connections to the lm4853 amp */
283 {"Stereo Out", NULL, "LOUT1"},
284 {"Stereo Out", NULL, "ROUT1"},
285
286 /* Connections to the GSM Module */
287 {"GSM Line Out", NULL, "MONO1"},
288 {"GSM Line Out", NULL, "MONO2"},
289 {"RXP", NULL, "GSM Line In"},
290 {"RXN", NULL, "GSM Line In"},
291
292 /* Connections to Headset */
293 {"MIC1", NULL, "Mic Bias"},
294 {"Mic Bias", NULL, "Headset Mic"},
295
296 /* Call Mic */
297 {"MIC2", NULL, "Mic Bias"},
298 {"MIC2N", NULL, "Mic Bias"},
299 {"Mic Bias", NULL, "Handset Mic"},
300
301 /* Call Speaker */
302 {"Handset Spk", NULL, "LOUT2"},
303 {"Handset Spk", NULL, "ROUT2"},
304
305 /* Connect the ALC pins */
306 {"ACIN", NULL, "ACOP"},
307};
308
309static const struct snd_kcontrol_new wm8753_neo1973_gta02_controls[] = {
310 SOC_DAPM_PIN_SWITCH("Stereo Out"),
311 SOC_DAPM_PIN_SWITCH("GSM Line Out"),
312 SOC_DAPM_PIN_SWITCH("GSM Line In"),
313 SOC_DAPM_PIN_SWITCH("Headset Mic"),
314 SOC_DAPM_PIN_SWITCH("Handset Mic"),
315 SOC_DAPM_PIN_SWITCH("Handset Spk"),
316
317 /* This has no effect, it exists only to maintain compatibility with
318 * existing ALSA state files.
319 */
320 SOC_SINGLE_EXT("Amp State Switch", 6, 0, 1, 0,
321 lm4853_get_state,
322 lm4853_set_state),
323 SOC_SINGLE_EXT("Amp Spk Switch", 7, 0, 1, 0,
324 lm4853_get_spk,
325 lm4853_set_spk),
326};
327
328/*
329 * This is an example machine initialisation for a wm8753 connected to a
330 * neo1973 GTA02.
331 */
332static int neo1973_gta02_wm8753_init(struct snd_soc_pcm_runtime *rtd)
333{
334 struct snd_soc_codec *codec = rtd->codec;
335 struct snd_soc_dapm_context *dapm = &codec->dapm;
336 int err;
337
338 /* set up NC codec pins */
339 snd_soc_dapm_nc_pin(dapm, "OUT3");
340 snd_soc_dapm_nc_pin(dapm, "OUT4");
341 snd_soc_dapm_nc_pin(dapm, "LINE1");
342 snd_soc_dapm_nc_pin(dapm, "LINE2");
343
344 /* Add neo1973 gta02 specific widgets */
345 snd_soc_dapm_new_controls(dapm, wm8753_dapm_widgets,
346 ARRAY_SIZE(wm8753_dapm_widgets));
347
348 /* add neo1973 gta02 specific controls */
349 err = snd_soc_add_controls(codec, wm8753_neo1973_gta02_controls,
350 ARRAY_SIZE(wm8753_neo1973_gta02_controls));
351
352 if (err < 0)
353 return err;
354
355 /* set up neo1973 gta02 specific audio path audio_map */
356 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
357
358 /* set endpoints to default off mode */
359 snd_soc_dapm_disable_pin(dapm, "Stereo Out");
360 snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
361 snd_soc_dapm_disable_pin(dapm, "GSM Line In");
362 snd_soc_dapm_disable_pin(dapm, "Headset Mic");
363 snd_soc_dapm_disable_pin(dapm, "Handset Mic");
364 snd_soc_dapm_disable_pin(dapm, "Handset Spk");
365
366 /* allow audio paths from the GSM modem to run during suspend */
367 snd_soc_dapm_ignore_suspend(dapm, "Stereo Out");
368 snd_soc_dapm_ignore_suspend(dapm, "GSM Line Out");
369 snd_soc_dapm_ignore_suspend(dapm, "GSM Line In");
370 snd_soc_dapm_ignore_suspend(dapm, "Headset Mic");
371 snd_soc_dapm_ignore_suspend(dapm, "Handset Mic");
372 snd_soc_dapm_ignore_suspend(dapm, "Handset Spk");
373
374 snd_soc_dapm_sync(dapm);
375
376 return 0;
377}
378
379/*
380 * BT Codec DAI
381 */
382static struct snd_soc_dai_driver bt_dai = {
383 .name = "bluetooth-dai",
384 .playback = {
385 .channels_min = 1,
386 .channels_max = 1,
387 .rates = SNDRV_PCM_RATE_8000,
388 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
389 .capture = {
390 .channels_min = 1,
391 .channels_max = 1,
392 .rates = SNDRV_PCM_RATE_8000,
393 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
394};
395
396static struct snd_soc_dai_link neo1973_gta02_dai[] = {
397{ /* Hifi Playback - for similatious use with voice below */
398 .name = "WM8753",
399 .stream_name = "WM8753 HiFi",
400 .cpu_dai_name = "s3c24xx-iis",
401 .codec_dai_name = "wm8753-hifi",
402 .init = neo1973_gta02_wm8753_init,
403 .platform_name = "samsung-audio",
404 .codec_name = "wm8753-codec.0-001a",
405 .ops = &neo1973_gta02_hifi_ops,
406},
407{ /* Voice via BT */
408 .name = "Bluetooth",
409 .stream_name = "Voice",
410 .cpu_dai_name = "bluetooth-dai",
411 .codec_dai_name = "wm8753-voice",
412 .ops = &neo1973_gta02_voice_ops,
413 .codec_name = "wm8753-codec.0-001a",
414 .platform_name = "samsung-audio",
415},
416};
417
418static struct snd_soc_card neo1973_gta02 = {
419 .name = "neo1973-gta02",
420 .dai_link = neo1973_gta02_dai,
421 .num_links = ARRAY_SIZE(neo1973_gta02_dai),
422};
423
424static struct platform_device *neo1973_gta02_snd_device;
425
426static int __init neo1973_gta02_init(void)
427{
428 int ret;
429
430 if (!machine_is_neo1973_gta02()) {
431 printk(KERN_INFO
432 "Only GTA02 is supported by this ASoC driver\n");
433 return -ENODEV;
434 }
435
436 neo1973_gta02_snd_device = platform_device_alloc("soc-audio", -1);
437 if (!neo1973_gta02_snd_device)
438 return -ENOMEM;
439
440 /* register bluetooth DAI here */
441 ret = snd_soc_register_dai(&neo1973_gta02_snd_device->dev, &bt_dai);
442 if (ret)
443 goto err_put_device;
444
445 platform_set_drvdata(neo1973_gta02_snd_device, &neo1973_gta02);
446 ret = platform_device_add(neo1973_gta02_snd_device);
447
448 if (ret)
449 goto err_unregister_dai;
450
451 /* Initialise GPIOs used by amp */
452 ret = gpio_request(GTA02_GPIO_HP_IN, "GTA02_HP_IN");
453 if (ret) {
454 pr_err("gta02_wm8753: Failed to register GPIO %d\n", GTA02_GPIO_HP_IN);
455 goto err_del_device;
456 }
457
458 ret = gpio_direction_output(GTA02_GPIO_HP_IN, 1);
459 if (ret) {
460 pr_err("gta02_wm8753: Failed to configure GPIO %d\n", GTA02_GPIO_HP_IN);
461 goto err_free_gpio_hp_in;
462 }
463
464 ret = gpio_request(GTA02_GPIO_AMP_SHUT, "GTA02_AMP_SHUT");
465 if (ret) {
466 pr_err("gta02_wm8753: Failed to register GPIO %d\n", GTA02_GPIO_AMP_SHUT);
467 goto err_free_gpio_hp_in;
468 }
469
470 ret = gpio_direction_output(GTA02_GPIO_AMP_SHUT, 1);
471 if (ret) {
472 pr_err("gta02_wm8753: Failed to configure GPIO %d\n", GTA02_GPIO_AMP_SHUT);
473 goto err_free_gpio_amp_shut;
474 }
475
476 return 0;
477
478err_free_gpio_amp_shut:
479 gpio_free(GTA02_GPIO_AMP_SHUT);
480err_free_gpio_hp_in:
481 gpio_free(GTA02_GPIO_HP_IN);
482err_del_device:
483 platform_device_del(neo1973_gta02_snd_device);
484err_unregister_dai:
485 snd_soc_unregister_dai(&neo1973_gta02_snd_device->dev);
486err_put_device:
487 platform_device_put(neo1973_gta02_snd_device);
488 return ret;
489}
490module_init(neo1973_gta02_init);
491
492static void __exit neo1973_gta02_exit(void)
493{
494 snd_soc_unregister_dai(&neo1973_gta02_snd_device->dev);
495 platform_device_unregister(neo1973_gta02_snd_device);
496 gpio_free(GTA02_GPIO_HP_IN);
497 gpio_free(GTA02_GPIO_AMP_SHUT);
498}
499module_exit(neo1973_gta02_exit);
500
501/* Module information */
502MODULE_AUTHOR("Graeme Gregory, graeme@openmoko.org");
503MODULE_DESCRIPTION("ALSA SoC WM8753 Neo1973 GTA02");
504MODULE_LICENSE("GPL");
diff --git a/sound/soc/samsung/neo1973_wm8753.c b/sound/soc/samsung/neo1973_wm8753.c
index d20815d5ab2e..78bfdb3f5d7e 100644
--- a/sound/soc/samsung/neo1973_wm8753.c
+++ b/sound/soc/samsung/neo1973_wm8753.c
@@ -1,57 +1,32 @@
1/* 1/*
2 * neo1973_wm8753.c -- SoC audio for Neo1973 2 * neo1973_wm8753.c -- SoC audio for Openmoko Neo1973 and Freerunner devices
3 * 3 *
4 * Copyright 2007 Openmoko Inc
5 * Author: Graeme Gregory <graeme@openmoko.org>
4 * Copyright 2007 Wolfson Microelectronics PLC. 6 * Copyright 2007 Wolfson Microelectronics PLC.
5 * Author: Graeme Gregory 7 * Author: Graeme Gregory
6 * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com 8 * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
9 * Copyright 2009 Wolfson Microelectronics
7 * 10 *
8 * This program is free software; you can redistribute it and/or modify it 11 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the 12 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your 13 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. 14 * option) any later version.
12 *
13 */ 15 */
14 16
15#include <linux/module.h> 17#include <linux/module.h>
16#include <linux/moduleparam.h>
17#include <linux/timer.h>
18#include <linux/interrupt.h>
19#include <linux/platform_device.h> 18#include <linux/platform_device.h>
20#include <linux/i2c.h> 19#include <linux/gpio.h>
21#include <sound/core.h> 20
22#include <sound/pcm.h>
23#include <sound/soc.h> 21#include <sound/soc.h>
24#include <sound/tlv.h>
25 22
26#include <asm/mach-types.h> 23#include <asm/mach-types.h>
27#include <asm/hardware/scoop.h>
28#include <mach/regs-clock.h>
29#include <mach/regs-gpio.h>
30#include <mach/hardware.h>
31#include <linux/io.h>
32#include <mach/spi-gpio.h>
33
34#include <plat/regs-iis.h> 24#include <plat/regs-iis.h>
25#include <mach/gta02.h>
35 26
36#include "../codecs/wm8753.h" 27#include "../codecs/wm8753.h"
37#include "lm4857.h"
38#include "dma.h"
39#include "s3c24xx-i2s.h" 28#include "s3c24xx-i2s.h"
40 29
41/* define the scenarios */
42#define NEO_AUDIO_OFF 0
43#define NEO_GSM_CALL_AUDIO_HANDSET 1
44#define NEO_GSM_CALL_AUDIO_HEADSET 2
45#define NEO_GSM_CALL_AUDIO_BLUETOOTH 3
46#define NEO_STEREO_TO_SPEAKERS 4
47#define NEO_STEREO_TO_HEADPHONES 5
48#define NEO_CAPTURE_HANDSET 6
49#define NEO_CAPTURE_HEADSET 7
50#define NEO_CAPTURE_BLUETOOTH 8
51
52static struct snd_soc_card neo1973;
53static struct i2c_client *i2c;
54
55static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream, 30static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream,
56 struct snd_pcm_hw_params *params) 31 struct snd_pcm_hw_params *params)
57{ 32{
@@ -62,8 +37,6 @@ static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream,
62 int ret = 0; 37 int ret = 0;
63 unsigned long iis_clkrate; 38 unsigned long iis_clkrate;
64 39
65 pr_debug("Entered %s\n", __func__);
66
67 iis_clkrate = s3c24xx_i2s_get_clockrate(); 40 iis_clkrate = s3c24xx_i2s_get_clockrate();
68 41
69 switch (params_rate(params)) { 42 switch (params_rate(params)) {
@@ -148,8 +121,6 @@ static int neo1973_hifi_hw_free(struct snd_pcm_substream *substream)
148 struct snd_soc_pcm_runtime *rtd = substream->private_data; 121 struct snd_soc_pcm_runtime *rtd = substream->private_data;
149 struct snd_soc_dai *codec_dai = rtd->codec_dai; 122 struct snd_soc_dai *codec_dai = rtd->codec_dai;
150 123
151 pr_debug("Entered %s\n", __func__);
152
153 /* disable the PLL */ 124 /* disable the PLL */
154 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, 0, 0); 125 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, 0, 0);
155} 126}
@@ -171,8 +142,6 @@ static int neo1973_voice_hw_params(struct snd_pcm_substream *substream,
171 int ret = 0; 142 int ret = 0;
172 unsigned long iis_clkrate; 143 unsigned long iis_clkrate;
173 144
174 pr_debug("Entered %s\n", __func__);
175
176 iis_clkrate = s3c24xx_i2s_get_clockrate(); 145 iis_clkrate = s3c24xx_i2s_get_clockrate();
177 146
178 if (params_rate(params) != 8000) 147 if (params_rate(params) != 8000)
@@ -214,8 +183,6 @@ static int neo1973_voice_hw_free(struct snd_pcm_substream *substream)
214 struct snd_soc_pcm_runtime *rtd = substream->private_data; 183 struct snd_soc_pcm_runtime *rtd = substream->private_data;
215 struct snd_soc_dai *codec_dai = rtd->codec_dai; 184 struct snd_soc_dai *codec_dai = rtd->codec_dai;
216 185
217 pr_debug("Entered %s\n", __func__);
218
219 /* disable the PLL */ 186 /* disable the PLL */
220 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 0, 0); 187 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 0, 0);
221} 188}
@@ -225,335 +192,232 @@ static struct snd_soc_ops neo1973_voice_ops = {
225 .hw_free = neo1973_voice_hw_free, 192 .hw_free = neo1973_voice_hw_free,
226}; 193};
227 194
228static int neo1973_scenario; 195/* Shared routes and controls */
229
230static int neo1973_get_scenario(struct snd_kcontrol *kcontrol,
231 struct snd_ctl_elem_value *ucontrol)
232{
233 ucontrol->value.integer.value[0] = neo1973_scenario;
234 return 0;
235}
236
237static int set_scenario_endpoints(struct snd_soc_codec *codec, int scenario)
238{
239 struct snd_soc_dapm_context *dapm = &codec->dapm;
240
241 pr_debug("Entered %s\n", __func__);
242
243 switch (neo1973_scenario) {
244 case NEO_AUDIO_OFF:
245 snd_soc_dapm_disable_pin(dapm, "Audio Out");
246 snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
247 snd_soc_dapm_disable_pin(dapm, "GSM Line In");
248 snd_soc_dapm_disable_pin(dapm, "Headset Mic");
249 snd_soc_dapm_disable_pin(dapm, "Call Mic");
250 break;
251 case NEO_GSM_CALL_AUDIO_HANDSET:
252 snd_soc_dapm_enable_pin(dapm, "Audio Out");
253 snd_soc_dapm_enable_pin(dapm, "GSM Line Out");
254 snd_soc_dapm_enable_pin(dapm, "GSM Line In");
255 snd_soc_dapm_disable_pin(dapm, "Headset Mic");
256 snd_soc_dapm_enable_pin(dapm, "Call Mic");
257 break;
258 case NEO_GSM_CALL_AUDIO_HEADSET:
259 snd_soc_dapm_enable_pin(dapm, "Audio Out");
260 snd_soc_dapm_enable_pin(dapm, "GSM Line Out");
261 snd_soc_dapm_enable_pin(dapm, "GSM Line In");
262 snd_soc_dapm_enable_pin(dapm, "Headset Mic");
263 snd_soc_dapm_disable_pin(dapm, "Call Mic");
264 break;
265 case NEO_GSM_CALL_AUDIO_BLUETOOTH:
266 snd_soc_dapm_disable_pin(dapm, "Audio Out");
267 snd_soc_dapm_enable_pin(dapm, "GSM Line Out");
268 snd_soc_dapm_enable_pin(dapm, "GSM Line In");
269 snd_soc_dapm_disable_pin(dapm, "Headset Mic");
270 snd_soc_dapm_disable_pin(dapm, "Call Mic");
271 break;
272 case NEO_STEREO_TO_SPEAKERS:
273 snd_soc_dapm_enable_pin(dapm, "Audio Out");
274 snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
275 snd_soc_dapm_disable_pin(dapm, "GSM Line In");
276 snd_soc_dapm_disable_pin(dapm, "Headset Mic");
277 snd_soc_dapm_disable_pin(dapm, "Call Mic");
278 break;
279 case NEO_STEREO_TO_HEADPHONES:
280 snd_soc_dapm_enable_pin(dapm, "Audio Out");
281 snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
282 snd_soc_dapm_disable_pin(dapm, "GSM Line In");
283 snd_soc_dapm_disable_pin(dapm, "Headset Mic");
284 snd_soc_dapm_disable_pin(dapm, "Call Mic");
285 break;
286 case NEO_CAPTURE_HANDSET:
287 snd_soc_dapm_disable_pin(dapm, "Audio Out");
288 snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
289 snd_soc_dapm_disable_pin(dapm, "GSM Line In");
290 snd_soc_dapm_disable_pin(dapm, "Headset Mic");
291 snd_soc_dapm_enable_pin(dapm, "Call Mic");
292 break;
293 case NEO_CAPTURE_HEADSET:
294 snd_soc_dapm_disable_pin(dapm, "Audio Out");
295 snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
296 snd_soc_dapm_disable_pin(dapm, "GSM Line In");
297 snd_soc_dapm_enable_pin(dapm, "Headset Mic");
298 snd_soc_dapm_disable_pin(dapm, "Call Mic");
299 break;
300 case NEO_CAPTURE_BLUETOOTH:
301 snd_soc_dapm_disable_pin(dapm, "Audio Out");
302 snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
303 snd_soc_dapm_disable_pin(dapm, "GSM Line In");
304 snd_soc_dapm_disable_pin(dapm, "Headset Mic");
305 snd_soc_dapm_disable_pin(dapm, "Call Mic");
306 break;
307 default:
308 snd_soc_dapm_disable_pin(dapm, "Audio Out");
309 snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
310 snd_soc_dapm_disable_pin(dapm, "GSM Line In");
311 snd_soc_dapm_disable_pin(dapm, "Headset Mic");
312 snd_soc_dapm_disable_pin(dapm, "Call Mic");
313 }
314 196
315 snd_soc_dapm_sync(dapm); 197static const struct snd_soc_dapm_widget neo1973_wm8753_dapm_widgets[] = {
198 SND_SOC_DAPM_LINE("GSM Line Out", NULL),
199 SND_SOC_DAPM_LINE("GSM Line In", NULL),
200 SND_SOC_DAPM_MIC("Headset Mic", NULL),
201 SND_SOC_DAPM_MIC("Handset Mic", NULL),
202};
316 203
317 return 0; 204static const struct snd_soc_dapm_route neo1973_wm8753_routes[] = {
318} 205 /* Connections to the GSM Module */
206 {"GSM Line Out", NULL, "MONO1"},
207 {"GSM Line Out", NULL, "MONO2"},
208 {"RXP", NULL, "GSM Line In"},
209 {"RXN", NULL, "GSM Line In"},
319 210
320static int neo1973_set_scenario(struct snd_kcontrol *kcontrol, 211 /* Connections to Headset */
321 struct snd_ctl_elem_value *ucontrol) 212 {"MIC1", NULL, "Mic Bias"},
322{ 213 {"Mic Bias", NULL, "Headset Mic"},
323 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
324 214
325 pr_debug("Entered %s\n", __func__); 215 /* Call Mic */
216 {"MIC2", NULL, "Mic Bias"},
217 {"MIC2N", NULL, "Mic Bias"},
218 {"Mic Bias", NULL, "Handset Mic"},
326 219
327 if (neo1973_scenario == ucontrol->value.integer.value[0]) 220 /* Connect the ALC pins */
328 return 0; 221 {"ACIN", NULL, "ACOP"},
222};
329 223
330 neo1973_scenario = ucontrol->value.integer.value[0]; 224static const struct snd_kcontrol_new neo1973_wm8753_controls[] = {
331 set_scenario_endpoints(codec, neo1973_scenario); 225 SOC_DAPM_PIN_SWITCH("GSM Line Out"),
332 return 1; 226 SOC_DAPM_PIN_SWITCH("GSM Line In"),
333} 227 SOC_DAPM_PIN_SWITCH("Headset Mic"),
228 SOC_DAPM_PIN_SWITCH("Handset Mic"),
229};
334 230
335static u8 lm4857_regs[4] = {0x00, 0x40, 0x80, 0xC0}; 231/* GTA02 specific routes and controlls */
336 232
337static void lm4857_write_regs(void) 233#ifdef CONFIG_MACH_NEO1973_GTA02
338{
339 pr_debug("Entered %s\n", __func__);
340 234
341 if (i2c_master_send(i2c, lm4857_regs, 4) != 4) 235static int gta02_speaker_enabled;
342 printk(KERN_ERR "lm4857: i2c write failed\n");
343}
344 236
345static int lm4857_get_reg(struct snd_kcontrol *kcontrol, 237static int lm4853_set_spk(struct snd_kcontrol *kcontrol,
346 struct snd_ctl_elem_value *ucontrol) 238 struct snd_ctl_elem_value *ucontrol)
347{ 239{
348 struct soc_mixer_control *mc = 240 gta02_speaker_enabled = ucontrol->value.integer.value[0];
349 (struct soc_mixer_control *)kcontrol->private_value;
350 int reg = mc->reg;
351 int shift = mc->shift;
352 int mask = mc->max;
353 241
354 pr_debug("Entered %s\n", __func__); 242 gpio_set_value(GTA02_GPIO_HP_IN, !gta02_speaker_enabled);
355 243
356 ucontrol->value.integer.value[0] = (lm4857_regs[reg] >> shift) & mask;
357 return 0; 244 return 0;
358} 245}
359 246
360static int lm4857_set_reg(struct snd_kcontrol *kcontrol, 247static int lm4853_get_spk(struct snd_kcontrol *kcontrol,
361 struct snd_ctl_elem_value *ucontrol) 248 struct snd_ctl_elem_value *ucontrol)
362{ 249{
363 struct soc_mixer_control *mc = 250 ucontrol->value.integer.value[0] = gta02_speaker_enabled;
364 (struct soc_mixer_control *)kcontrol->private_value; 251 return 0;
365 int reg = mc->reg;
366 int shift = mc->shift;
367 int mask = mc->max;
368
369 if (((lm4857_regs[reg] >> shift) & mask) ==
370 ucontrol->value.integer.value[0])
371 return 0;
372
373 lm4857_regs[reg] &= ~(mask << shift);
374 lm4857_regs[reg] |= ucontrol->value.integer.value[0] << shift;
375 lm4857_write_regs();
376 return 1;
377} 252}
378 253
379static int lm4857_get_mode(struct snd_kcontrol *kcontrol, 254static int lm4853_event(struct snd_soc_dapm_widget *w,
380 struct snd_ctl_elem_value *ucontrol) 255 struct snd_kcontrol *k, int event)
381{ 256{
382 u8 value = lm4857_regs[LM4857_CTRL] & 0x0F; 257 gpio_set_value(GTA02_GPIO_AMP_SHUT, SND_SOC_DAPM_EVENT_OFF(event));
383
384 pr_debug("Entered %s\n", __func__);
385
386 if (value)
387 value -= 5;
388 258
389 ucontrol->value.integer.value[0] = value;
390 return 0; 259 return 0;
391} 260}
392 261
393static int lm4857_set_mode(struct snd_kcontrol *kcontrol, 262static const struct snd_soc_dapm_route neo1973_gta02_routes[] = {
394 struct snd_ctl_elem_value *ucontrol) 263 /* Connections to the amp */
395{ 264 {"Stereo Out", NULL, "LOUT1"},
396 u8 value = ucontrol->value.integer.value[0]; 265 {"Stereo Out", NULL, "ROUT1"},
397
398 pr_debug("Entered %s\n", __func__);
399
400 if (value)
401 value += 5;
402
403 if ((lm4857_regs[LM4857_CTRL] & 0x0F) == value)
404 return 0;
405
406 lm4857_regs[LM4857_CTRL] &= 0xF0;
407 lm4857_regs[LM4857_CTRL] |= value;
408 lm4857_write_regs();
409 return 1;
410}
411 266
412static const struct snd_soc_dapm_widget wm8753_dapm_widgets[] = { 267 /* Call Speaker */
413 SND_SOC_DAPM_LINE("Audio Out", NULL), 268 {"Handset Spk", NULL, "LOUT2"},
414 SND_SOC_DAPM_LINE("GSM Line Out", NULL), 269 {"Handset Spk", NULL, "ROUT2"},
415 SND_SOC_DAPM_LINE("GSM Line In", NULL),
416 SND_SOC_DAPM_MIC("Headset Mic", NULL),
417 SND_SOC_DAPM_MIC("Call Mic", NULL),
418}; 270};
419 271
272static const struct snd_kcontrol_new neo1973_gta02_wm8753_controls[] = {
273 SOC_DAPM_PIN_SWITCH("Handset Spk"),
274 SOC_DAPM_PIN_SWITCH("Stereo Out"),
420 275
421static const struct snd_soc_dapm_route dapm_routes[] = { 276 SOC_SINGLE_BOOL_EXT("Amp Spk Switch", 0,
422 277 lm4853_get_spk,
423 /* Connections to the lm4857 amp */ 278 lm4853_set_spk),
424 {"Audio Out", NULL, "LOUT1"}, 279};
425 {"Audio Out", NULL, "ROUT1"},
426
427 /* Connections to the GSM Module */
428 {"GSM Line Out", NULL, "MONO1"},
429 {"GSM Line Out", NULL, "MONO2"},
430 {"RXP", NULL, "GSM Line In"},
431 {"RXN", NULL, "GSM Line In"},
432 280
433 /* Connections to Headset */ 281static const struct snd_soc_dapm_widget neo1973_gta02_wm8753_dapm_widgets[] = {
434 {"MIC1", NULL, "Mic Bias"}, 282 SND_SOC_DAPM_SPK("Handset Spk", NULL),
435 {"Mic Bias", NULL, "Headset Mic"}, 283 SND_SOC_DAPM_SPK("Stereo Out", lm4853_event),
284};
436 285
437 /* Call Mic */ 286static int neo1973_gta02_wm8753_init(struct snd_soc_codec *codec)
438 {"MIC2", NULL, "Mic Bias"}, 287{
439 {"MIC2N", NULL, "Mic Bias"}, 288 struct snd_soc_dapm_context *dapm = &codec->dapm;
440 {"Mic Bias", NULL, "Call Mic"}, 289 int ret;
441 290
442 /* Connect the ALC pins */ 291 ret = snd_soc_dapm_new_controls(dapm, neo1973_gta02_wm8753_dapm_widgets,
443 {"ACIN", NULL, "ACOP"}, 292 ARRAY_SIZE(neo1973_gta02_wm8753_dapm_widgets));
444}; 293 if (ret)
294 return ret;
445 295
446static const char *lm4857_mode[] = { 296 ret = snd_soc_dapm_add_routes(dapm, neo1973_gta02_routes,
447 "Off", 297 ARRAY_SIZE(neo1973_gta02_routes));
448 "Call Speaker", 298 if (ret)
449 "Stereo Speakers", 299 return ret;
450 "Stereo Speakers + Headphones",
451 "Headphones"
452};
453 300
454static const struct soc_enum lm4857_mode_enum[] = { 301 ret = snd_soc_add_controls(codec, neo1973_gta02_wm8753_controls,
455 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(lm4857_mode), lm4857_mode), 302 ARRAY_SIZE(neo1973_gta02_wm8753_controls));
456}; 303 if (ret)
304 return ret;
457 305
458static const char *neo_scenarios[] = { 306 snd_soc_dapm_disable_pin(dapm, "Stereo Out");
459 "Off", 307 snd_soc_dapm_disable_pin(dapm, "Handset Spk");
460 "GSM Handset", 308 snd_soc_dapm_ignore_suspend(dapm, "Stereo Out");
461 "GSM Headset", 309 snd_soc_dapm_ignore_suspend(dapm, "Handset Spk");
462 "GSM Bluetooth",
463 "Speakers",
464 "Headphones",
465 "Capture Handset",
466 "Capture Headset",
467 "Capture Bluetooth"
468};
469 310
470static const struct soc_enum neo_scenario_enum[] = { 311 return 0;
471 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(neo_scenarios), neo_scenarios), 312}
472};
473 313
474static const DECLARE_TLV_DB_SCALE(stereo_tlv, -4050, 150, 0); 314#else
475static const DECLARE_TLV_DB_SCALE(mono_tlv, -3450, 150, 0); 315static int neo1973_gta02_wm8753_init(struct snd_soc_code *codec) { return 0; }
476 316#endif
477static const struct snd_kcontrol_new wm8753_neo1973_controls[] = {
478 SOC_SINGLE_EXT_TLV("Amp Left Playback Volume", LM4857_LVOL, 0, 31, 0,
479 lm4857_get_reg, lm4857_set_reg, stereo_tlv),
480 SOC_SINGLE_EXT_TLV("Amp Right Playback Volume", LM4857_RVOL, 0, 31, 0,
481 lm4857_get_reg, lm4857_set_reg, stereo_tlv),
482 SOC_SINGLE_EXT_TLV("Amp Mono Playback Volume", LM4857_MVOL, 0, 31, 0,
483 lm4857_get_reg, lm4857_set_reg, mono_tlv),
484 SOC_ENUM_EXT("Amp Mode", lm4857_mode_enum[0],
485 lm4857_get_mode, lm4857_set_mode),
486 SOC_ENUM_EXT("Neo Mode", neo_scenario_enum[0],
487 neo1973_get_scenario, neo1973_set_scenario),
488 SOC_SINGLE_EXT("Amp Spk 3D Playback Switch", LM4857_LVOL, 5, 1, 0,
489 lm4857_get_reg, lm4857_set_reg),
490 SOC_SINGLE_EXT("Amp HP 3d Playback Switch", LM4857_RVOL, 5, 1, 0,
491 lm4857_get_reg, lm4857_set_reg),
492 SOC_SINGLE_EXT("Amp Fast Wakeup Playback Switch", LM4857_CTRL, 5, 1, 0,
493 lm4857_get_reg, lm4857_set_reg),
494 SOC_SINGLE_EXT("Amp Earpiece 6dB Playback Switch", LM4857_CTRL, 4, 1, 0,
495 lm4857_get_reg, lm4857_set_reg),
496};
497 317
498/*
499 * This is an example machine initialisation for a wm8753 connected to a
500 * neo1973 II. It is missing logic to detect hp/mic insertions and logic
501 * to re-route the audio in such an event.
502 */
503static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd) 318static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd)
504{ 319{
505 struct snd_soc_codec *codec = rtd->codec; 320 struct snd_soc_codec *codec = rtd->codec;
506 struct snd_soc_dapm_context *dapm = &codec->dapm; 321 struct snd_soc_dapm_context *dapm = &codec->dapm;
507 int err; 322 int ret;
508
509 pr_debug("Entered %s\n", __func__);
510 323
511 /* set up NC codec pins */ 324 /* set up NC codec pins */
512 snd_soc_dapm_nc_pin(dapm, "LOUT2"); 325 if (machine_is_neo1973_gta01()) {
513 snd_soc_dapm_nc_pin(dapm, "ROUT2"); 326 snd_soc_dapm_nc_pin(dapm, "LOUT2");
327 snd_soc_dapm_nc_pin(dapm, "ROUT2");
328 }
514 snd_soc_dapm_nc_pin(dapm, "OUT3"); 329 snd_soc_dapm_nc_pin(dapm, "OUT3");
515 snd_soc_dapm_nc_pin(dapm, "OUT4"); 330 snd_soc_dapm_nc_pin(dapm, "OUT4");
516 snd_soc_dapm_nc_pin(dapm, "LINE1"); 331 snd_soc_dapm_nc_pin(dapm, "LINE1");
517 snd_soc_dapm_nc_pin(dapm, "LINE2"); 332 snd_soc_dapm_nc_pin(dapm, "LINE2");
518 333
519 /* Add neo1973 specific widgets */ 334 /* Add neo1973 specific widgets */
520 snd_soc_dapm_new_controls(dapm, wm8753_dapm_widgets, 335 ret = snd_soc_dapm_new_controls(dapm, neo1973_wm8753_dapm_widgets,
521 ARRAY_SIZE(wm8753_dapm_widgets)); 336 ARRAY_SIZE(neo1973_wm8753_dapm_widgets));
522 337 if (ret)
523 /* set endpoints to default mode */ 338 return ret;
524 set_scenario_endpoints(codec, NEO_AUDIO_OFF);
525 339
526 /* add neo1973 specific controls */ 340 /* add neo1973 specific controls */
527 err = snd_soc_add_controls(codec, wm8753_neo1973_controls, 341 ret = snd_soc_add_controls(codec, neo1973_wm8753_controls,
528 ARRAY_SIZE(8753_neo1973_controls)); 342 ARRAY_SIZE(neo1973_wm8753_controls));
529 if (err < 0) 343 if (ret)
530 return err; 344 return ret;
531 345
532 /* set up neo1973 specific audio routes */ 346 /* set up neo1973 specific audio routes */
533 err = snd_soc_dapm_add_routes(dapm, dapm_routes, 347 ret = snd_soc_dapm_add_routes(dapm, neo1973_wm8753_routes,
534 ARRAY_SIZE(dapm_routes)); 348 ARRAY_SIZE(neo1973_wm8753_routes));
349 if (ret)
350 return ret;
351
352 /* set endpoints to default off mode */
353 snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
354 snd_soc_dapm_disable_pin(dapm, "GSM Line In");
355 snd_soc_dapm_disable_pin(dapm, "Headset Mic");
356 snd_soc_dapm_disable_pin(dapm, "Handset Mic");
357
358 /* allow audio paths from the GSM modem to run during suspend */
359 snd_soc_dapm_ignore_suspend(dapm, "GSM Line Out");
360 snd_soc_dapm_ignore_suspend(dapm, "GSM Line In");
361 snd_soc_dapm_ignore_suspend(dapm, "Headset Mic");
362 snd_soc_dapm_ignore_suspend(dapm, "Handset Mic");
363
364 if (machine_is_neo1973_gta02()) {
365 ret = neo1973_gta02_wm8753_init(codec);
366 if (ret)
367 return ret;
368 }
535 369
536 snd_soc_dapm_sync(dapm); 370 snd_soc_dapm_sync(dapm);
371
537 return 0; 372 return 0;
538} 373}
539 374
540/* 375/* GTA01 specific controlls */
541 * BT Codec DAI 376
542 */ 377#ifdef CONFIG_MACH_NEO1973_GTA01
543static struct snd_soc_dai bt_dai = { 378
544 .name = "bluetooth-dai", 379static const struct snd_soc_dapm_route neo1973_lm4857_routes[] = {
545 .playback = { 380 {"Amp IN", NULL, "ROUT1"},
546 .channels_min = 1, 381 {"Amp IN", NULL, "LOUT1"},
547 .channels_max = 1, 382
548 .rates = SNDRV_PCM_RATE_8000, 383 {"Handset Spk", NULL, "Amp EP"},
549 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 384 {"Stereo Out", NULL, "Amp LS"},
550 .capture = { 385 {"Headphone", NULL, "Amp HP"},
551 .channels_min = 1, 386};
552 .channels_max = 1, 387
553 .rates = SNDRV_PCM_RATE_8000, 388static const struct snd_soc_dapm_widget neo1973_lm4857_dapm_widgets[] = {
554 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 389 SND_SOC_DAPM_SPK("Handset Spk", NULL),
390 SND_SOC_DAPM_SPK("Stereo Out", NULL),
391 SND_SOC_DAPM_HP("Headphone", NULL),
555}; 392};
556 393
394static int neo1973_lm4857_init(struct snd_soc_dapm_context *dapm)
395{
396 int ret;
397
398 ret = snd_soc_dapm_new_controls(dapm, neo1973_lm4857_dapm_widgets,
399 ARRAY_SIZE(neo1973_lm4857_dapm_widgets));
400 if (ret)
401 return ret;
402
403 ret = snd_soc_dapm_add_routes(dapm, neo1973_lm4857_routes,
404 ARRAY_SIZE(neo1973_lm4857_routes));
405 if (ret)
406 return ret;
407
408 snd_soc_dapm_ignore_suspend(dapm, "Stereo Out");
409 snd_soc_dapm_ignore_suspend(dapm, "Handset Spk");
410 snd_soc_dapm_ignore_suspend(dapm, "Headphone");
411
412 snd_soc_dapm_sync(dapm);
413
414 return 0;
415}
416
417#else
418static int neo1973_lm4857_init(struct snd_soc_dapm_context *dapm) { return 0; };
419#endif
420
557static struct snd_soc_dai_link neo1973_dai[] = { 421static struct snd_soc_dai_link neo1973_dai[] = {
558{ /* Hifi Playback - for similatious use with voice below */ 422{ /* Hifi Playback - for similatious use with voice below */
559 .name = "WM8753", 423 .name = "WM8753",
@@ -569,90 +433,49 @@ static struct snd_soc_dai_link neo1973_dai[] = {
569 .name = "Bluetooth", 433 .name = "Bluetooth",
570 .stream_name = "Voice", 434 .stream_name = "Voice",
571 .platform_name = "samsung-audio", 435 .platform_name = "samsung-audio",
572 .cpu_dai_name = "bluetooth-dai", 436 .cpu_dai_name = "dfbmcs320-pcm",
573 .codec_dai_name = "wm8753-voice", 437 .codec_dai_name = "wm8753-voice",
574 .codec_name = "wm8753-codec.0-001a", 438 .codec_name = "wm8753-codec.0-001a",
575 .ops = &neo1973_voice_ops, 439 .ops = &neo1973_voice_ops,
576}, 440},
577}; 441};
578 442
579static struct snd_soc_card neo1973 = { 443static struct snd_soc_aux_dev neo1973_aux_devs[] = {
580 .name = "neo1973", 444 {
581 .dai_link = neo1973_dai, 445 .name = "dfbmcs320",
582 .num_links = ARRAY_SIZE(neo1973_dai), 446 .codec_name = "dfbmcs320.0",
447 },
448 {
449 .name = "lm4857",
450 .codec_name = "lm4857.0-007c",
451 .init = neo1973_lm4857_init,
452 },
583}; 453};
584 454
585static int lm4857_i2c_probe(struct i2c_client *client, 455static struct snd_soc_codec_conf neo1973_codec_conf[] = {
586 const struct i2c_device_id *id) 456 {
587{ 457 .dev_name = "lm4857.0-007c",
588 pr_debug("Entered %s\n", __func__); 458 .name_prefix = "Amp",
589 459 },
590 i2c = client; 460};
591
592 lm4857_write_regs();
593 return 0;
594}
595
596static int lm4857_i2c_remove(struct i2c_client *client)
597{
598 pr_debug("Entered %s\n", __func__);
599
600 i2c = NULL;
601
602 return 0;
603}
604
605static u8 lm4857_state;
606
607static int lm4857_suspend(struct i2c_client *dev, pm_message_t state)
608{
609 pr_debug("Entered %s\n", __func__);
610
611 dev_dbg(&dev->dev, "lm4857_suspend\n");
612 lm4857_state = lm4857_regs[LM4857_CTRL] & 0xf;
613 if (lm4857_state) {
614 lm4857_regs[LM4857_CTRL] &= 0xf0;
615 lm4857_write_regs();
616 }
617 return 0;
618}
619
620static int lm4857_resume(struct i2c_client *dev)
621{
622 pr_debug("Entered %s\n", __func__);
623
624 if (lm4857_state) {
625 lm4857_regs[LM4857_CTRL] |= (lm4857_state & 0x0f);
626 lm4857_write_regs();
627 }
628 return 0;
629}
630
631static void lm4857_shutdown(struct i2c_client *dev)
632{
633 pr_debug("Entered %s\n", __func__);
634
635 dev_dbg(&dev->dev, "lm4857_shutdown\n");
636 lm4857_regs[LM4857_CTRL] &= 0xf0;
637 lm4857_write_regs();
638}
639 461
640static const struct i2c_device_id lm4857_i2c_id[] = { 462#ifdef CONFIG_MACH_NEO1973_GTA02
641 { "neo1973_lm4857", 0 }, 463static const struct gpio neo1973_gta02_gpios[] = {
642 { } 464 { GTA02_GPIO_HP_IN, GPIOF_OUT_INIT_HIGH, "GTA02_HP_IN" },
465 { GTA02_GPIO_AMP_SHUT, GPIOF_OUT_INIT_HIGH, "GTA02_AMP_SHUT" },
643}; 466};
467#else
468static const struct gpio neo1973_gta02_gpios[] = {};
469#endif
644 470
645static struct i2c_driver lm4857_i2c_driver = { 471static struct snd_soc_card neo1973 = {
646 .driver = { 472 .name = "neo1973",
647 .name = "LM4857 I2C Amp", 473 .dai_link = neo1973_dai,
648 .owner = THIS_MODULE, 474 .num_links = ARRAY_SIZE(neo1973_dai),
649 }, 475 .aux_dev = neo1973_aux_devs,
650 .suspend = lm4857_suspend, 476 .num_aux_devs = ARRAY_SIZE(neo1973_aux_devs),
651 .resume = lm4857_resume, 477 .codec_conf = neo1973_codec_conf,
652 .shutdown = lm4857_shutdown, 478 .num_configs = ARRAY_SIZE(neo1973_codec_conf),
653 .probe = lm4857_i2c_probe,
654 .remove = lm4857_i2c_remove,
655 .id_table = lm4857_i2c_id,
656}; 479};
657 480
658static struct platform_device *neo1973_snd_device; 481static struct platform_device *neo1973_snd_device;
@@ -661,46 +484,56 @@ static int __init neo1973_init(void)
661{ 484{
662 int ret; 485 int ret;
663 486
664 pr_debug("Entered %s\n", __func__); 487 if (!machine_is_neo1973_gta01() && !machine_is_neo1973_gta02())
665
666 if (!machine_is_neo1973_gta01()) {
667 printk(KERN_INFO
668 "Only GTA01 hardware supported by ASoC driver\n");
669 return -ENODEV; 488 return -ENODEV;
489
490 if (machine_is_neo1973_gta02()) {
491 neo1973.name = "neo1973gta02";
492 neo1973.num_aux_devs = 1;
493
494 ret = gpio_request_array(neo1973_gta02_gpios,
495 ARRAY_SIZE(neo1973_gta02_gpios));
496 if (ret)
497 return ret;
670 } 498 }
671 499
672 neo1973_snd_device = platform_device_alloc("soc-audio", -1); 500 neo1973_snd_device = platform_device_alloc("soc-audio", -1);
673 if (!neo1973_snd_device) 501 if (!neo1973_snd_device) {
674 return -ENOMEM; 502 ret = -ENOMEM;
503 goto err_gpio_free;
504 }
675 505
676 platform_set_drvdata(neo1973_snd_device, &neo1973); 506 platform_set_drvdata(neo1973_snd_device, &neo1973);
677 ret = platform_device_add(neo1973_snd_device); 507 ret = platform_device_add(neo1973_snd_device);
678 508
679 if (ret) { 509 if (ret)
680 platform_device_put(neo1973_snd_device); 510 goto err_put_device;
681 return ret;
682 }
683
684 ret = i2c_add_driver(&lm4857_i2c_driver);
685 511
686 if (ret != 0) 512 return 0;
687 platform_device_unregister(neo1973_snd_device);
688 513
514err_put_device:
515 platform_device_put(neo1973_snd_device);
516err_gpio_free:
517 if (machine_is_neo1973_gta02()) {
518 gpio_free_array(neo1973_gta02_gpios,
519 ARRAY_SIZE(neo1973_gta02_gpios));
520 }
689 return ret; 521 return ret;
690} 522}
523module_init(neo1973_init);
691 524
692static void __exit neo1973_exit(void) 525static void __exit neo1973_exit(void)
693{ 526{
694 pr_debug("Entered %s\n", __func__);
695
696 i2c_del_driver(&lm4857_i2c_driver);
697 platform_device_unregister(neo1973_snd_device); 527 platform_device_unregister(neo1973_snd_device);
698}
699 528
700module_init(neo1973_init); 529 if (machine_is_neo1973_gta02()) {
530 gpio_free_array(neo1973_gta02_gpios,
531 ARRAY_SIZE(neo1973_gta02_gpios));
532 }
533}
701module_exit(neo1973_exit); 534module_exit(neo1973_exit);
702 535
703/* Module information */ 536/* Module information */
704MODULE_AUTHOR("Graeme Gregory, graeme@openmoko.org, www.openmoko.org"); 537MODULE_AUTHOR("Graeme Gregory, graeme@openmoko.org, www.openmoko.org");
705MODULE_DESCRIPTION("ALSA SoC WM8753 Neo1973"); 538MODULE_DESCRIPTION("ALSA SoC WM8753 Neo1973 and Frerunner");
706MODULE_LICENSE("GPL"); 539MODULE_LICENSE("GPL");
diff --git a/sound/soc/samsung/pcm.c b/sound/soc/samsung/pcm.c
index 48d0b750406b..38aac7d57a59 100644
--- a/sound/soc/samsung/pcm.c
+++ b/sound/soc/samsung/pcm.c
@@ -11,20 +11,11 @@
11 * published by the Free Software Foundation. 11 * published by the Free Software Foundation.
12 */ 12 */
13 13
14#include <linux/init.h>
15#include <linux/module.h>
16#include <linux/device.h>
17#include <linux/delay.h>
18#include <linux/clk.h> 14#include <linux/clk.h>
19#include <linux/kernel.h>
20#include <linux/gpio.h>
21#include <linux/io.h> 15#include <linux/io.h>
22 16
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26#include <sound/initval.h>
27#include <sound/soc.h> 17#include <sound/soc.h>
18#include <sound/pcm_params.h>
28 19
29#include <plat/audio.h> 20#include <plat/audio.h>
30#include <plat/dma.h> 21#include <plat/dma.h>
@@ -32,6 +23,113 @@
32#include "dma.h" 23#include "dma.h"
33#include "pcm.h" 24#include "pcm.h"
34 25
26/*Register Offsets */
27#define S3C_PCM_CTL 0x00
28#define S3C_PCM_CLKCTL 0x04
29#define S3C_PCM_TXFIFO 0x08
30#define S3C_PCM_RXFIFO 0x0C
31#define S3C_PCM_IRQCTL 0x10
32#define S3C_PCM_IRQSTAT 0x14
33#define S3C_PCM_FIFOSTAT 0x18
34#define S3C_PCM_CLRINT 0x20
35
36/* PCM_CTL Bit-Fields */
37#define S3C_PCM_CTL_TXDIPSTICK_MASK 0x3f
38#define S3C_PCM_CTL_TXDIPSTICK_SHIFT 13
39#define S3C_PCM_CTL_RXDIPSTICK_MASK 0x3f
40#define S3C_PCM_CTL_RXDIPSTICK_SHIFT 7
41#define S3C_PCM_CTL_TXDMA_EN (0x1 << 6)
42#define S3C_PCM_CTL_RXDMA_EN (0x1 << 5)
43#define S3C_PCM_CTL_TXMSB_AFTER_FSYNC (0x1 << 4)
44#define S3C_PCM_CTL_RXMSB_AFTER_FSYNC (0x1 << 3)
45#define S3C_PCM_CTL_TXFIFO_EN (0x1 << 2)
46#define S3C_PCM_CTL_RXFIFO_EN (0x1 << 1)
47#define S3C_PCM_CTL_ENABLE (0x1 << 0)
48
49/* PCM_CLKCTL Bit-Fields */
50#define S3C_PCM_CLKCTL_SERCLK_EN (0x1 << 19)
51#define S3C_PCM_CLKCTL_SERCLKSEL_PCLK (0x1 << 18)
52#define S3C_PCM_CLKCTL_SCLKDIV_MASK 0x1ff
53#define S3C_PCM_CLKCTL_SYNCDIV_MASK 0x1ff
54#define S3C_PCM_CLKCTL_SCLKDIV_SHIFT 9
55#define S3C_PCM_CLKCTL_SYNCDIV_SHIFT 0
56
57/* PCM_TXFIFO Bit-Fields */
58#define S3C_PCM_TXFIFO_DVALID (0x1 << 16)
59#define S3C_PCM_TXFIFO_DATA_MSK (0xffff << 0)
60
61/* PCM_RXFIFO Bit-Fields */
62#define S3C_PCM_RXFIFO_DVALID (0x1 << 16)
63#define S3C_PCM_RXFIFO_DATA_MSK (0xffff << 0)
64
65/* PCM_IRQCTL Bit-Fields */
66#define S3C_PCM_IRQCTL_IRQEN (0x1 << 14)
67#define S3C_PCM_IRQCTL_WRDEN (0x1 << 12)
68#define S3C_PCM_IRQCTL_TXEMPTYEN (0x1 << 11)
69#define S3C_PCM_IRQCTL_TXALMSTEMPTYEN (0x1 << 10)
70#define S3C_PCM_IRQCTL_TXFULLEN (0x1 << 9)
71#define S3C_PCM_IRQCTL_TXALMSTFULLEN (0x1 << 8)
72#define S3C_PCM_IRQCTL_TXSTARVEN (0x1 << 7)
73#define S3C_PCM_IRQCTL_TXERROVRFLEN (0x1 << 6)
74#define S3C_PCM_IRQCTL_RXEMPTEN (0x1 << 5)
75#define S3C_PCM_IRQCTL_RXALMSTEMPTEN (0x1 << 4)
76#define S3C_PCM_IRQCTL_RXFULLEN (0x1 << 3)
77#define S3C_PCM_IRQCTL_RXALMSTFULLEN (0x1 << 2)
78#define S3C_PCM_IRQCTL_RXSTARVEN (0x1 << 1)
79#define S3C_PCM_IRQCTL_RXERROVRFLEN (0x1 << 0)
80
81/* PCM_IRQSTAT Bit-Fields */
82#define S3C_PCM_IRQSTAT_IRQPND (0x1 << 13)
83#define S3C_PCM_IRQSTAT_WRD_XFER (0x1 << 12)
84#define S3C_PCM_IRQSTAT_TXEMPTY (0x1 << 11)
85#define S3C_PCM_IRQSTAT_TXALMSTEMPTY (0x1 << 10)
86#define S3C_PCM_IRQSTAT_TXFULL (0x1 << 9)
87#define S3C_PCM_IRQSTAT_TXALMSTFULL (0x1 << 8)
88#define S3C_PCM_IRQSTAT_TXSTARV (0x1 << 7)
89#define S3C_PCM_IRQSTAT_TXERROVRFL (0x1 << 6)
90#define S3C_PCM_IRQSTAT_RXEMPT (0x1 << 5)
91#define S3C_PCM_IRQSTAT_RXALMSTEMPT (0x1 << 4)
92#define S3C_PCM_IRQSTAT_RXFULL (0x1 << 3)
93#define S3C_PCM_IRQSTAT_RXALMSTFULL (0x1 << 2)
94#define S3C_PCM_IRQSTAT_RXSTARV (0x1 << 1)
95#define S3C_PCM_IRQSTAT_RXERROVRFL (0x1 << 0)
96
97/* PCM_FIFOSTAT Bit-Fields */
98#define S3C_PCM_FIFOSTAT_TXCNT_MSK (0x3f << 14)
99#define S3C_PCM_FIFOSTAT_TXFIFOEMPTY (0x1 << 13)
100#define S3C_PCM_FIFOSTAT_TXFIFOALMSTEMPTY (0x1 << 12)
101#define S3C_PCM_FIFOSTAT_TXFIFOFULL (0x1 << 11)
102#define S3C_PCM_FIFOSTAT_TXFIFOALMSTFULL (0x1 << 10)
103#define S3C_PCM_FIFOSTAT_RXCNT_MSK (0x3f << 4)
104#define S3C_PCM_FIFOSTAT_RXFIFOEMPTY (0x1 << 3)
105#define S3C_PCM_FIFOSTAT_RXFIFOALMSTEMPTY (0x1 << 2)
106#define S3C_PCM_FIFOSTAT_RXFIFOFULL (0x1 << 1)
107#define S3C_PCM_FIFOSTAT_RXFIFOALMSTFULL (0x1 << 0)
108
109/**
110 * struct s3c_pcm_info - S3C PCM Controller information
111 * @dev: The parent device passed to use from the probe.
112 * @regs: The pointer to the device register block.
113 * @dma_playback: DMA information for playback channel.
114 * @dma_capture: DMA information for capture channel.
115 */
116struct s3c_pcm_info {
117 spinlock_t lock;
118 struct device *dev;
119 void __iomem *regs;
120
121 unsigned int sclk_per_fs;
122
123 /* Whether to keep PCMSCLK enabled even when idle(no active xfer) */
124 unsigned int idleclk;
125
126 struct clk *pclk;
127 struct clk *cclk;
128
129 struct s3c_dma_params *dma_playback;
130 struct s3c_dma_params *dma_capture;
131};
132
35static struct s3c2410_dma_client s3c_pcm_dma_client_out = { 133static struct s3c2410_dma_client s3c_pcm_dma_client_out = {
36 .name = "PCM Stereo out" 134 .name = "PCM Stereo out"
37}; 135};
diff --git a/sound/soc/samsung/pcm.h b/sound/soc/samsung/pcm.h
index 03393dcf852d..726baf814613 100644
--- a/sound/soc/samsung/pcm.h
+++ b/sound/soc/samsung/pcm.h
@@ -9,116 +9,9 @@
9#ifndef __S3C_PCM_H 9#ifndef __S3C_PCM_H
10#define __S3C_PCM_H __FILE__ 10#define __S3C_PCM_H __FILE__
11 11
12/*Register Offsets */
13#define S3C_PCM_CTL (0x00)
14#define S3C_PCM_CLKCTL (0x04)
15#define S3C_PCM_TXFIFO (0x08)
16#define S3C_PCM_RXFIFO (0x0C)
17#define S3C_PCM_IRQCTL (0x10)
18#define S3C_PCM_IRQSTAT (0x14)
19#define S3C_PCM_FIFOSTAT (0x18)
20#define S3C_PCM_CLRINT (0x20)
21
22/* PCM_CTL Bit-Fields */
23#define S3C_PCM_CTL_TXDIPSTICK_MASK (0x3f)
24#define S3C_PCM_CTL_TXDIPSTICK_SHIFT (13)
25#define S3C_PCM_CTL_RXDIPSTICK_MASK (0x3f)
26#define S3C_PCM_CTL_RXDIPSTICK_SHIFT (7)
27#define S3C_PCM_CTL_TXDMA_EN (0x1<<6)
28#define S3C_PCM_CTL_RXDMA_EN (0x1<<5)
29#define S3C_PCM_CTL_TXMSB_AFTER_FSYNC (0x1<<4)
30#define S3C_PCM_CTL_RXMSB_AFTER_FSYNC (0x1<<3)
31#define S3C_PCM_CTL_TXFIFO_EN (0x1<<2)
32#define S3C_PCM_CTL_RXFIFO_EN (0x1<<1)
33#define S3C_PCM_CTL_ENABLE (0x1<<0)
34
35/* PCM_CLKCTL Bit-Fields */
36#define S3C_PCM_CLKCTL_SERCLK_EN (0x1<<19)
37#define S3C_PCM_CLKCTL_SERCLKSEL_PCLK (0x1<<18)
38#define S3C_PCM_CLKCTL_SCLKDIV_MASK (0x1ff)
39#define S3C_PCM_CLKCTL_SYNCDIV_MASK (0x1ff)
40#define S3C_PCM_CLKCTL_SCLKDIV_SHIFT (9)
41#define S3C_PCM_CLKCTL_SYNCDIV_SHIFT (0)
42
43/* PCM_TXFIFO Bit-Fields */
44#define S3C_PCM_TXFIFO_DVALID (0x1<<16)
45#define S3C_PCM_TXFIFO_DATA_MSK (0xffff<<0)
46
47/* PCM_RXFIFO Bit-Fields */
48#define S3C_PCM_RXFIFO_DVALID (0x1<<16)
49#define S3C_PCM_RXFIFO_DATA_MSK (0xffff<<0)
50
51/* PCM_IRQCTL Bit-Fields */
52#define S3C_PCM_IRQCTL_IRQEN (0x1<<14)
53#define S3C_PCM_IRQCTL_WRDEN (0x1<<12)
54#define S3C_PCM_IRQCTL_TXEMPTYEN (0x1<<11)
55#define S3C_PCM_IRQCTL_TXALMSTEMPTYEN (0x1<<10)
56#define S3C_PCM_IRQCTL_TXFULLEN (0x1<<9)
57#define S3C_PCM_IRQCTL_TXALMSTFULLEN (0x1<<8)
58#define S3C_PCM_IRQCTL_TXSTARVEN (0x1<<7)
59#define S3C_PCM_IRQCTL_TXERROVRFLEN (0x1<<6)
60#define S3C_PCM_IRQCTL_RXEMPTEN (0x1<<5)
61#define S3C_PCM_IRQCTL_RXALMSTEMPTEN (0x1<<4)
62#define S3C_PCM_IRQCTL_RXFULLEN (0x1<<3)
63#define S3C_PCM_IRQCTL_RXALMSTFULLEN (0x1<<2)
64#define S3C_PCM_IRQCTL_RXSTARVEN (0x1<<1)
65#define S3C_PCM_IRQCTL_RXERROVRFLEN (0x1<<0)
66
67/* PCM_IRQSTAT Bit-Fields */
68#define S3C_PCM_IRQSTAT_IRQPND (0x1<<13)
69#define S3C_PCM_IRQSTAT_WRD_XFER (0x1<<12)
70#define S3C_PCM_IRQSTAT_TXEMPTY (0x1<<11)
71#define S3C_PCM_IRQSTAT_TXALMSTEMPTY (0x1<<10)
72#define S3C_PCM_IRQSTAT_TXFULL (0x1<<9)
73#define S3C_PCM_IRQSTAT_TXALMSTFULL (0x1<<8)
74#define S3C_PCM_IRQSTAT_TXSTARV (0x1<<7)
75#define S3C_PCM_IRQSTAT_TXERROVRFL (0x1<<6)
76#define S3C_PCM_IRQSTAT_RXEMPT (0x1<<5)
77#define S3C_PCM_IRQSTAT_RXALMSTEMPT (0x1<<4)
78#define S3C_PCM_IRQSTAT_RXFULL (0x1<<3)
79#define S3C_PCM_IRQSTAT_RXALMSTFULL (0x1<<2)
80#define S3C_PCM_IRQSTAT_RXSTARV (0x1<<1)
81#define S3C_PCM_IRQSTAT_RXERROVRFL (0x1<<0)
82
83/* PCM_FIFOSTAT Bit-Fields */
84#define S3C_PCM_FIFOSTAT_TXCNT_MSK (0x3f<<14)
85#define S3C_PCM_FIFOSTAT_TXFIFOEMPTY (0x1<<13)
86#define S3C_PCM_FIFOSTAT_TXFIFOALMSTEMPTY (0x1<<12)
87#define S3C_PCM_FIFOSTAT_TXFIFOFULL (0x1<<11)
88#define S3C_PCM_FIFOSTAT_TXFIFOALMSTFULL (0x1<<10)
89#define S3C_PCM_FIFOSTAT_RXCNT_MSK (0x3f<<4)
90#define S3C_PCM_FIFOSTAT_RXFIFOEMPTY (0x1<<3)
91#define S3C_PCM_FIFOSTAT_RXFIFOALMSTEMPTY (0x1<<2)
92#define S3C_PCM_FIFOSTAT_RXFIFOFULL (0x1<<1)
93#define S3C_PCM_FIFOSTAT_RXFIFOALMSTFULL (0x1<<0)
94
95#define S3C_PCM_CLKSRC_PCLK 0 12#define S3C_PCM_CLKSRC_PCLK 0
96#define S3C_PCM_CLKSRC_MUX 1 13#define S3C_PCM_CLKSRC_MUX 1
97 14
98#define S3C_PCM_SCLK_PER_FS 0 15#define S3C_PCM_SCLK_PER_FS 0
99 16
100/**
101 * struct s3c_pcm_info - S3C PCM Controller information
102 * @dev: The parent device passed to use from the probe.
103 * @regs: The pointer to the device register block.
104 * @dma_playback: DMA information for playback channel.
105 * @dma_capture: DMA information for capture channel.
106 */
107struct s3c_pcm_info {
108 spinlock_t lock;
109 struct device *dev;
110 void __iomem *regs;
111
112 unsigned int sclk_per_fs;
113
114 /* Whether to keep PCMSCLK enabled even when idle(no active xfer) */
115 unsigned int idleclk;
116
117 struct clk *pclk;
118 struct clk *cclk;
119
120 struct s3c_dma_params *dma_playback;
121 struct s3c_dma_params *dma_capture;
122};
123
124#endif /* __S3C_PCM_H */ 17#endif /* __S3C_PCM_H */
diff --git a/sound/soc/samsung/rx1950_uda1380.c b/sound/soc/samsung/rx1950_uda1380.c
index f40027445dda..1e574a5d440d 100644
--- a/sound/soc/samsung/rx1950_uda1380.c
+++ b/sound/soc/samsung/rx1950_uda1380.c
@@ -17,26 +17,15 @@
17 * 17 *
18 */ 18 */
19 19
20#include <linux/module.h>
21#include <linux/moduleparam.h>
22#include <linux/platform_device.h>
23#include <linux/i2c.h>
24#include <linux/gpio.h> 20#include <linux/gpio.h>
25#include <linux/clk.h>
26 21
27#include <sound/soc.h> 22#include <sound/soc.h>
28#include <sound/uda1380.h>
29#include <sound/jack.h> 23#include <sound/jack.h>
30 24
31#include <plat/regs-iis.h> 25#include <plat/regs-iis.h>
32
33#include <mach/regs-clock.h>
34
35#include <asm/mach-types.h> 26#include <asm/mach-types.h>
36 27
37#include "dma.h"
38#include "s3c24xx-i2s.h" 28#include "s3c24xx-i2s.h"
39#include "../codecs/uda1380.h"
40 29
41static int rx1950_uda1380_init(struct snd_soc_pcm_runtime *rtd); 30static int rx1950_uda1380_init(struct snd_soc_pcm_runtime *rtd);
42static int rx1950_startup(struct snd_pcm_substream *substream); 31static int rx1950_startup(struct snd_pcm_substream *substream);
diff --git a/sound/soc/samsung/s3c-i2s-v2.c b/sound/soc/samsung/s3c-i2s-v2.c
index 094f36e41e83..52074a2b0696 100644
--- a/sound/soc/samsung/s3c-i2s-v2.c
+++ b/sound/soc/samsung/s3c-i2s-v2.c
@@ -20,9 +20,8 @@
20#include <linux/clk.h> 20#include <linux/clk.h>
21#include <linux/io.h> 21#include <linux/io.h>
22 22
23#include <sound/pcm.h>
24#include <sound/pcm_params.h>
25#include <sound/soc.h> 23#include <sound/soc.h>
24#include <sound/pcm_params.h>
26 25
27#include <mach/dma.h> 26#include <mach/dma.h>
28 27
diff --git a/sound/soc/samsung/s3c2412-i2s.c b/sound/soc/samsung/s3c2412-i2s.c
index 7ea837867124..841ab14c1100 100644
--- a/sound/soc/samsung/s3c2412-i2s.c
+++ b/sound/soc/samsung/s3c2412-i2s.c
@@ -16,21 +16,13 @@
16 * option) any later version. 16 * option) any later version.
17 */ 17 */
18 18
19#include <linux/init.h>
20#include <linux/module.h>
21#include <linux/device.h>
22#include <linux/delay.h> 19#include <linux/delay.h>
23#include <linux/gpio.h> 20#include <linux/gpio.h>
24#include <linux/clk.h> 21#include <linux/clk.h>
25#include <linux/kernel.h>
26#include <linux/io.h> 22#include <linux/io.h>
27 23
28#include <sound/core.h>
29#include <sound/pcm.h>
30#include <sound/pcm_params.h>
31#include <sound/initval.h>
32#include <sound/soc.h> 24#include <sound/soc.h>
33#include <mach/hardware.h> 25#include <sound/pcm_params.h>
34 26
35#include <mach/regs-gpio.h> 27#include <mach/regs-gpio.h>
36#include <mach/dma.h> 28#include <mach/dma.h>
@@ -39,8 +31,6 @@
39#include "regs-i2s-v2.h" 31#include "regs-i2s-v2.h"
40#include "s3c2412-i2s.h" 32#include "s3c2412-i2s.h"
41 33
42#define S3C2412_I2S_DEBUG 0
43
44static struct s3c2410_dma_client s3c2412_dma_client_out = { 34static struct s3c2410_dma_client s3c2412_dma_client_out = {
45 .name = "I2S PCM Stereo out" 35 .name = "I2S PCM Stereo out"
46}; 36};
diff --git a/sound/soc/samsung/s3c24xx-i2s.c b/sound/soc/samsung/s3c24xx-i2s.c
index 13e41ed8e22b..63d8849d80bd 100644
--- a/sound/soc/samsung/s3c24xx-i2s.c
+++ b/sound/soc/samsung/s3c24xx-i2s.c
@@ -14,28 +14,16 @@
14 * option) any later version. 14 * option) any later version.
15 */ 15 */
16 16
17#include <linux/init.h>
18#include <linux/module.h>
19#include <linux/device.h>
20#include <linux/delay.h> 17#include <linux/delay.h>
21#include <linux/clk.h> 18#include <linux/clk.h>
22#include <linux/jiffies.h>
23#include <linux/io.h> 19#include <linux/io.h>
24#include <linux/gpio.h> 20#include <linux/gpio.h>
25 21
26#include <sound/core.h>
27#include <sound/pcm.h>
28#include <sound/pcm_params.h>
29#include <sound/initval.h>
30#include <sound/soc.h> 22#include <sound/soc.h>
23#include <sound/pcm_params.h>
31 24
32#include <mach/hardware.h>
33#include <mach/regs-gpio.h> 25#include <mach/regs-gpio.h>
34#include <mach/regs-clock.h>
35
36#include <asm/dma.h>
37#include <mach/dma.h> 26#include <mach/dma.h>
38
39#include <plat/regs-iis.h> 27#include <plat/regs-iis.h>
40 28
41#include "dma.h" 29#include "dma.h"
diff --git a/sound/soc/samsung/s3c24xx_simtec.c b/sound/soc/samsung/s3c24xx_simtec.c
index a434032d1832..349566f0686b 100644
--- a/sound/soc/samsung/s3c24xx_simtec.c
+++ b/sound/soc/samsung/s3c24xx_simtec.c
@@ -7,20 +7,13 @@
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8*/ 8*/
9 9
10#include <linux/module.h>
11#include <linux/moduleparam.h>
12#include <linux/platform_device.h>
13#include <linux/gpio.h> 10#include <linux/gpio.h>
14#include <linux/clk.h> 11#include <linux/clk.h>
15#include <linux/i2c.h>
16 12
17#include <sound/core.h>
18#include <sound/pcm.h>
19#include <sound/soc.h> 13#include <sound/soc.h>
20 14
21#include <plat/audio-simtec.h> 15#include <plat/audio-simtec.h>
22 16
23#include "dma.h"
24#include "s3c24xx-i2s.h" 17#include "s3c24xx-i2s.h"
25#include "s3c24xx_simtec.h" 18#include "s3c24xx_simtec.h"
26 19
diff --git a/sound/soc/samsung/s3c24xx_simtec_hermes.c b/sound/soc/samsung/s3c24xx_simtec_hermes.c
index 08fcaaa66907..ce6aef604179 100644
--- a/sound/soc/samsung/s3c24xx_simtec_hermes.c
+++ b/sound/soc/samsung/s3c24xx_simtec_hermes.c
@@ -7,18 +7,8 @@
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8*/ 8*/
9 9
10#include <linux/module.h>
11#include <linux/clk.h>
12#include <linux/platform_device.h>
13
14#include <sound/core.h>
15#include <sound/pcm.h>
16#include <sound/soc.h> 10#include <sound/soc.h>
17 11
18#include <plat/audio-simtec.h>
19
20#include "dma.h"
21#include "s3c24xx-i2s.h"
22#include "s3c24xx_simtec.h" 12#include "s3c24xx_simtec.h"
23 13
24static const struct snd_soc_dapm_widget dapm_widgets[] = { 14static const struct snd_soc_dapm_widget dapm_widgets[] = {
diff --git a/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c b/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c
index 116e3e670167..a7ef7db54687 100644
--- a/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c
+++ b/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c
@@ -7,22 +7,10 @@
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8*/ 8*/
9 9
10#include <linux/module.h>
11#include <linux/clk.h>
12#include <linux/platform_device.h>
13
14#include <sound/core.h>
15#include <sound/pcm.h>
16#include <sound/soc.h> 10#include <sound/soc.h>
17 11
18#include <plat/audio-simtec.h>
19
20#include "dma.h"
21#include "s3c24xx-i2s.h"
22#include "s3c24xx_simtec.h" 12#include "s3c24xx_simtec.h"
23 13
24#include "../codecs/tlv320aic23.h"
25
26/* supported machines: 14/* supported machines:
27 * 15 *
28 * Machine Connections AMP 16 * Machine Connections AMP
diff --git a/sound/soc/samsung/s3c24xx_uda134x.c b/sound/soc/samsung/s3c24xx_uda134x.c
index 2c09e93dd566..3cb700751078 100644
--- a/sound/soc/samsung/s3c24xx_uda134x.c
+++ b/sound/soc/samsung/s3c24xx_uda134x.c
@@ -11,22 +11,15 @@
11 * published by the Free Software Foundation. 11 * published by the Free Software Foundation.
12 */ 12 */
13 13
14#include <linux/module.h>
15#include <linux/clk.h> 14#include <linux/clk.h>
16#include <linux/mutex.h>
17#include <linux/gpio.h> 15#include <linux/gpio.h>
18#include <sound/pcm.h> 16
19#include <sound/pcm_params.h>
20#include <sound/soc.h> 17#include <sound/soc.h>
21#include <sound/s3c24xx_uda134x.h> 18#include <sound/s3c24xx_uda134x.h>
22#include <sound/uda134x.h>
23 19
24#include <plat/regs-iis.h> 20#include <plat/regs-iis.h>
25 21
26#include "dma.h"
27#include "s3c24xx-i2s.h" 22#include "s3c24xx-i2s.h"
28#include "../codecs/uda134x.h"
29
30 23
31/* #define ENFORCE_RATES 1 */ 24/* #define ENFORCE_RATES 1 */
32/* 25/*
diff --git a/sound/soc/samsung/smartq_wm8987.c b/sound/soc/samsung/smartq_wm8987.c
index 61e2b5219d42..0a2c4f223038 100644
--- a/sound/soc/samsung/smartq_wm8987.c
+++ b/sound/soc/samsung/smartq_wm8987.c
@@ -13,20 +13,14 @@
13 * 13 *
14 */ 14 */
15 15
16#include <linux/module.h>
17#include <linux/platform_device.h>
18#include <linux/gpio.h> 16#include <linux/gpio.h>
19 17
20#include <sound/pcm.h>
21#include <sound/pcm_params.h>
22#include <sound/soc.h> 18#include <sound/soc.h>
23#include <sound/jack.h> 19#include <sound/jack.h>
24 20
25#include <asm/mach-types.h> 21#include <asm/mach-types.h>
26 22
27#include "dma.h"
28#include "i2s.h" 23#include "i2s.h"
29
30#include "../codecs/wm8750.h" 24#include "../codecs/wm8750.h"
31 25
32/* 26/*
diff --git a/sound/soc/samsung/smdk2443_wm9710.c b/sound/soc/samsung/smdk2443_wm9710.c
index 3be7e7e92d6e..3a0dbfc793f0 100644
--- a/sound/soc/samsung/smdk2443_wm9710.c
+++ b/sound/soc/samsung/smdk2443_wm9710.c
@@ -12,15 +12,8 @@
12 * 12 *
13 */ 13 */
14 14
15#include <linux/module.h>
16#include <linux/device.h>
17#include <sound/core.h>
18#include <sound/pcm.h>
19#include <sound/soc.h> 15#include <sound/soc.h>
20 16
21#include "dma.h"
22#include "ac97.h"
23
24static struct snd_soc_card smdk2443; 17static struct snd_soc_card smdk2443;
25 18
26static struct snd_soc_dai_link smdk2443_dai[] = { 19static struct snd_soc_dai_link smdk2443_dai[] = {
diff --git a/sound/soc/samsung/smdk_spdif.c b/sound/soc/samsung/smdk_spdif.c
index b5c3fad01bb8..e8ac961c6ba1 100644
--- a/sound/soc/samsung/smdk_spdif.c
+++ b/sound/soc/samsung/smdk_spdif.c
@@ -10,15 +10,10 @@
10 * 10 *
11 */ 11 */
12 12
13#include <linux/module.h>
14#include <linux/device.h>
15#include <linux/clk.h> 13#include <linux/clk.h>
16 14
17#include <plat/devs.h>
18
19#include <sound/soc.h> 15#include <sound/soc.h>
20 16
21#include "dma.h"
22#include "spdif.h" 17#include "spdif.h"
23 18
24/* Audio clock settings are belonged to board specific part. Every 19/* Audio clock settings are belonged to board specific part. Every
diff --git a/sound/soc/samsung/smdk_wm8580.c b/sound/soc/samsung/smdk_wm8580.c
index b2cff1a44aed..8aacf23d6f3a 100644
--- a/sound/soc/samsung/smdk_wm8580.c
+++ b/sound/soc/samsung/smdk_wm8580.c
@@ -10,17 +10,12 @@
10 * option) any later version. 10 * option) any later version.
11 */ 11 */
12 12
13#include <linux/platform_device.h>
14#include <linux/clk.h>
15#include <sound/core.h>
16#include <sound/pcm.h>
17#include <sound/pcm_params.h>
18#include <sound/soc.h> 13#include <sound/soc.h>
14#include <sound/pcm_params.h>
19 15
20#include <asm/mach-types.h> 16#include <asm/mach-types.h>
21 17
22#include "../codecs/wm8580.h" 18#include "../codecs/wm8580.h"
23#include "dma.h"
24#include "i2s.h" 19#include "i2s.h"
25 20
26/* 21/*
diff --git a/sound/soc/samsung/smdk_wm9713.c b/sound/soc/samsung/smdk_wm9713.c
index ae5fed6f772f..fffe3c1dd1bd 100644
--- a/sound/soc/samsung/smdk_wm9713.c
+++ b/sound/soc/samsung/smdk_wm9713.c
@@ -11,13 +11,8 @@
11 * 11 *
12 */ 12 */
13 13
14#include <linux/module.h>
15#include <linux/device.h>
16#include <sound/soc.h> 14#include <sound/soc.h>
17 15
18#include "dma.h"
19#include "ac97.h"
20
21static struct snd_soc_card smdk; 16static struct snd_soc_card smdk;
22 17
23/* 18/*
diff --git a/sound/soc/samsung/spdif.c b/sound/soc/samsung/spdif.c
index f0816404ea3e..28c491dacf7a 100644
--- a/sound/soc/samsung/spdif.c
+++ b/sound/soc/samsung/spdif.c
@@ -13,9 +13,8 @@
13#include <linux/clk.h> 13#include <linux/clk.h>
14#include <linux/io.h> 14#include <linux/io.h>
15 15
16#include <sound/pcm.h>
17#include <sound/pcm_params.h>
18#include <sound/soc.h> 16#include <sound/soc.h>
17#include <sound/pcm_params.h>
19 18
20#include <plat/audio.h> 19#include <plat/audio.h>
21#include <mach/dma.h> 20#include <mach/dma.h>
diff --git a/sound/soc/sh/fsi-ak4642.c b/sound/soc/sh/fsi-ak4642.c
index a14820ac9665..d6f4703b3c07 100644
--- a/sound/soc/sh/fsi-ak4642.c
+++ b/sound/soc/sh/fsi-ak4642.c
@@ -18,18 +18,26 @@ struct fsi_ak4642_data {
18 const char *cpu_dai; 18 const char *cpu_dai;
19 const char *codec; 19 const char *codec;
20 const char *platform; 20 const char *platform;
21 int id;
21}; 22};
22 23
23static int fsi_ak4642_dai_init(struct snd_soc_pcm_runtime *rtd) 24static int fsi_ak4642_dai_init(struct snd_soc_pcm_runtime *rtd)
24{ 25{
25 struct snd_soc_dai *dai = rtd->codec_dai; 26 struct snd_soc_dai *codec = rtd->codec_dai;
27 struct snd_soc_dai *cpu = rtd->cpu_dai;
26 int ret; 28 int ret;
27 29
28 ret = snd_soc_dai_set_fmt(dai, SND_SOC_DAIFMT_CBM_CFM); 30 ret = snd_soc_dai_set_fmt(codec, SND_SOC_DAIFMT_LEFT_J |
31 SND_SOC_DAIFMT_CBM_CFM);
29 if (ret < 0) 32 if (ret < 0)
30 return ret; 33 return ret;
31 34
32 ret = snd_soc_dai_set_sysclk(dai, 0, 11289600, 0); 35 ret = snd_soc_dai_set_sysclk(codec, 0, 11289600, 0);
36 if (ret < 0)
37 return ret;
38
39 ret = snd_soc_dai_set_fmt(cpu, SND_SOC_DAIFMT_LEFT_J |
40 SND_SOC_DAIFMT_CBS_CFS);
33 41
34 return ret; 42 return ret;
35} 43}
@@ -60,7 +68,7 @@ static int fsi_ak4642_probe(struct platform_device *pdev)
60 68
61 pdata = (struct fsi_ak4642_data *)id_entry->driver_data; 69 pdata = (struct fsi_ak4642_data *)id_entry->driver_data;
62 70
63 fsi_snd_device = platform_device_alloc("soc-audio", FSI_PORT_A); 71 fsi_snd_device = platform_device_alloc("soc-audio", pdata->id);
64 if (!fsi_snd_device) 72 if (!fsi_snd_device)
65 goto out; 73 goto out;
66 74
@@ -93,6 +101,7 @@ static struct fsi_ak4642_data fsi_a_ak4642 = {
93 .cpu_dai = "fsia-dai", 101 .cpu_dai = "fsia-dai",
94 .codec = "ak4642-codec.0-0012", 102 .codec = "ak4642-codec.0-0012",
95 .platform = "sh_fsi.0", 103 .platform = "sh_fsi.0",
104 .id = FSI_PORT_A,
96}; 105};
97 106
98static struct fsi_ak4642_data fsi_b_ak4642 = { 107static struct fsi_ak4642_data fsi_b_ak4642 = {
@@ -101,6 +110,7 @@ static struct fsi_ak4642_data fsi_b_ak4642 = {
101 .cpu_dai = "fsib-dai", 110 .cpu_dai = "fsib-dai",
102 .codec = "ak4642-codec.0-0012", 111 .codec = "ak4642-codec.0-0012",
103 .platform = "sh_fsi.0", 112 .platform = "sh_fsi.0",
113 .id = FSI_PORT_B,
104}; 114};
105 115
106static struct fsi_ak4642_data fsi_a_ak4643 = { 116static struct fsi_ak4642_data fsi_a_ak4643 = {
@@ -109,6 +119,7 @@ static struct fsi_ak4642_data fsi_a_ak4643 = {
109 .cpu_dai = "fsia-dai", 119 .cpu_dai = "fsia-dai",
110 .codec = "ak4642-codec.0-0013", 120 .codec = "ak4642-codec.0-0013",
111 .platform = "sh_fsi.0", 121 .platform = "sh_fsi.0",
122 .id = FSI_PORT_A,
112}; 123};
113 124
114static struct fsi_ak4642_data fsi_b_ak4643 = { 125static struct fsi_ak4642_data fsi_b_ak4643 = {
@@ -117,6 +128,7 @@ static struct fsi_ak4642_data fsi_b_ak4643 = {
117 .cpu_dai = "fsib-dai", 128 .cpu_dai = "fsib-dai",
118 .codec = "ak4642-codec.0-0013", 129 .codec = "ak4642-codec.0-0013",
119 .platform = "sh_fsi.0", 130 .platform = "sh_fsi.0",
131 .id = FSI_PORT_B,
120}; 132};
121 133
122static struct fsi_ak4642_data fsi2_a_ak4642 = { 134static struct fsi_ak4642_data fsi2_a_ak4642 = {
@@ -125,6 +137,7 @@ static struct fsi_ak4642_data fsi2_a_ak4642 = {
125 .cpu_dai = "fsia-dai", 137 .cpu_dai = "fsia-dai",
126 .codec = "ak4642-codec.0-0012", 138 .codec = "ak4642-codec.0-0012",
127 .platform = "sh_fsi2", 139 .platform = "sh_fsi2",
140 .id = FSI_PORT_A,
128}; 141};
129 142
130static struct fsi_ak4642_data fsi2_b_ak4642 = { 143static struct fsi_ak4642_data fsi2_b_ak4642 = {
@@ -133,6 +146,7 @@ static struct fsi_ak4642_data fsi2_b_ak4642 = {
133 .cpu_dai = "fsib-dai", 146 .cpu_dai = "fsib-dai",
134 .codec = "ak4642-codec.0-0012", 147 .codec = "ak4642-codec.0-0012",
135 .platform = "sh_fsi2", 148 .platform = "sh_fsi2",
149 .id = FSI_PORT_B,
136}; 150};
137 151
138static struct fsi_ak4642_data fsi2_a_ak4643 = { 152static struct fsi_ak4642_data fsi2_a_ak4643 = {
@@ -141,6 +155,7 @@ static struct fsi_ak4642_data fsi2_a_ak4643 = {
141 .cpu_dai = "fsia-dai", 155 .cpu_dai = "fsia-dai",
142 .codec = "ak4642-codec.0-0013", 156 .codec = "ak4642-codec.0-0013",
143 .platform = "sh_fsi2", 157 .platform = "sh_fsi2",
158 .id = FSI_PORT_A,
144}; 159};
145 160
146static struct fsi_ak4642_data fsi2_b_ak4643 = { 161static struct fsi_ak4642_data fsi2_b_ak4643 = {
@@ -149,6 +164,7 @@ static struct fsi_ak4642_data fsi2_b_ak4643 = {
149 .cpu_dai = "fsib-dai", 164 .cpu_dai = "fsib-dai",
150 .codec = "ak4642-codec.0-0013", 165 .codec = "ak4642-codec.0-0013",
151 .platform = "sh_fsi2", 166 .platform = "sh_fsi2",
167 .id = FSI_PORT_B,
152}; 168};
153 169
154static struct platform_device_id fsi_id_table[] = { 170static struct platform_device_id fsi_id_table[] = {
diff --git a/sound/soc/sh/fsi-da7210.c b/sound/soc/sh/fsi-da7210.c
index e8df9da92f71..dbafd7ac5590 100644
--- a/sound/soc/sh/fsi-da7210.c
+++ b/sound/soc/sh/fsi-da7210.c
@@ -15,11 +15,20 @@
15 15
16static int fsi_da7210_init(struct snd_soc_pcm_runtime *rtd) 16static int fsi_da7210_init(struct snd_soc_pcm_runtime *rtd)
17{ 17{
18 struct snd_soc_dai *dai = rtd->codec_dai; 18 struct snd_soc_dai *codec = rtd->codec_dai;
19 struct snd_soc_dai *cpu = rtd->cpu_dai;
20 int ret;
19 21
20 return snd_soc_dai_set_fmt(dai, 22 ret = snd_soc_dai_set_fmt(codec,
21 SND_SOC_DAIFMT_I2S | 23 SND_SOC_DAIFMT_I2S |
22 SND_SOC_DAIFMT_CBM_CFM); 24 SND_SOC_DAIFMT_CBM_CFM);
25 if (ret < 0)
26 return ret;
27
28 ret = snd_soc_dai_set_fmt(cpu, SND_SOC_DAIFMT_I2S |
29 SND_SOC_DAIFMT_CBS_CFS);
30
31 return ret;
23} 32}
24 33
25static struct snd_soc_dai_link fsi_da7210_dai = { 34static struct snd_soc_dai_link fsi_da7210_dai = {
diff --git a/sound/soc/sh/fsi-hdmi.c b/sound/soc/sh/fsi-hdmi.c
index a52dd8ec71d3..9719985eb82d 100644
--- a/sound/soc/sh/fsi-hdmi.c
+++ b/sound/soc/sh/fsi-hdmi.c
@@ -12,31 +12,59 @@
12#include <linux/platform_device.h> 12#include <linux/platform_device.h>
13#include <sound/sh_fsi.h> 13#include <sound/sh_fsi.h>
14 14
15struct fsi_hdmi_data {
16 const char *cpu_dai;
17 const char *card;
18 int id;
19};
20
21static int fsi_hdmi_dai_init(struct snd_soc_pcm_runtime *rtd)
22{
23 struct snd_soc_dai *cpu = rtd->cpu_dai;
24 int ret;
25
26 ret = snd_soc_dai_set_fmt(cpu, SND_SOC_DAIFMT_CBM_CFM);
27
28 return ret;
29}
30
15static struct snd_soc_dai_link fsi_dai_link = { 31static struct snd_soc_dai_link fsi_dai_link = {
16 .name = "HDMI", 32 .name = "HDMI",
17 .stream_name = "HDMI", 33 .stream_name = "HDMI",
18 .cpu_dai_name = "fsib-dai", /* fsi B */
19 .codec_dai_name = "sh_mobile_hdmi-hifi", 34 .codec_dai_name = "sh_mobile_hdmi-hifi",
20 .platform_name = "sh_fsi2", 35 .platform_name = "sh_fsi2",
21 .codec_name = "sh-mobile-hdmi", 36 .codec_name = "sh-mobile-hdmi",
37 .init = fsi_hdmi_dai_init,
22}; 38};
23 39
24static struct snd_soc_card fsi_soc_card = { 40static struct snd_soc_card fsi_soc_card = {
25 .name = "FSI (SH MOBILE HDMI)",
26 .dai_link = &fsi_dai_link, 41 .dai_link = &fsi_dai_link,
27 .num_links = 1, 42 .num_links = 1,
28}; 43};
29 44
30static struct platform_device *fsi_snd_device; 45static struct platform_device *fsi_snd_device;
31 46
32static int __init fsi_hdmi_init(void) 47static int fsi_hdmi_probe(struct platform_device *pdev)
33{ 48{
34 int ret = -ENOMEM; 49 int ret = -ENOMEM;
50 const struct platform_device_id *id_entry;
51 struct fsi_hdmi_data *pdata;
52
53 id_entry = pdev->id_entry;
54 if (!id_entry) {
55 dev_err(&pdev->dev, "unknown fsi hdmi\n");
56 return -ENODEV;
57 }
35 58
36 fsi_snd_device = platform_device_alloc("soc-audio", FSI_PORT_B); 59 pdata = (struct fsi_hdmi_data *)id_entry->driver_data;
60
61 fsi_snd_device = platform_device_alloc("soc-audio", pdata->id);
37 if (!fsi_snd_device) 62 if (!fsi_snd_device)
38 goto out; 63 goto out;
39 64
65 fsi_dai_link.cpu_dai_name = pdata->cpu_dai;
66 fsi_soc_card.name = pdata->card;
67
40 platform_set_drvdata(fsi_snd_device, &fsi_soc_card); 68 platform_set_drvdata(fsi_snd_device, &fsi_soc_card);
41 ret = platform_device_add(fsi_snd_device); 69 ret = platform_device_add(fsi_snd_device);
42 70
@@ -47,9 +75,48 @@ out:
47 return ret; 75 return ret;
48} 76}
49 77
50static void __exit fsi_hdmi_exit(void) 78static int fsi_hdmi_remove(struct platform_device *pdev)
51{ 79{
52 platform_device_unregister(fsi_snd_device); 80 platform_device_unregister(fsi_snd_device);
81 return 0;
82}
83
84static struct fsi_hdmi_data fsi2_a_hdmi = {
85 .cpu_dai = "fsia-dai",
86 .card = "FSI2A (SH MOBILE HDMI)",
87 .id = FSI_PORT_A,
88};
89
90static struct fsi_hdmi_data fsi2_b_hdmi = {
91 .cpu_dai = "fsib-dai",
92 .card = "FSI2B (SH MOBILE HDMI)",
93 .id = FSI_PORT_B,
94};
95
96static struct platform_device_id fsi_id_table[] = {
97 /* FSI 2 */
98 { "sh_fsi2_a_hdmi", (kernel_ulong_t)&fsi2_a_hdmi },
99 { "sh_fsi2_b_hdmi", (kernel_ulong_t)&fsi2_b_hdmi },
100 {},
101};
102
103static struct platform_driver fsi_hdmi = {
104 .driver = {
105 .name = "fsi-hdmi-audio",
106 },
107 .probe = fsi_hdmi_probe,
108 .remove = fsi_hdmi_remove,
109 .id_table = fsi_id_table,
110};
111
112static int __init fsi_hdmi_init(void)
113{
114 return platform_driver_register(&fsi_hdmi);
115}
116
117static void __exit fsi_hdmi_exit(void)
118{
119 platform_driver_unregister(&fsi_hdmi);
53} 120}
54 121
55module_init(fsi_hdmi_init); 122module_init(fsi_hdmi_init);
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 2b06402801ef..0c9997e2d8c0 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -78,6 +78,8 @@
78/* CKG1 */ 78/* CKG1 */
79#define ACKMD_MASK 0x00007000 79#define ACKMD_MASK 0x00007000
80#define BPFMD_MASK 0x00000700 80#define BPFMD_MASK 0x00000700
81#define DIMD (1 << 4)
82#define DOMD (1 << 0)
81 83
82/* A/B MST_CTLR */ 84/* A/B MST_CTLR */
83#define BP (1 << 4) /* Fix the signal of Biphase output */ 85#define BP (1 << 4) /* Fix the signal of Biphase output */
@@ -111,6 +113,8 @@
111 113
112#define FSI_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE) 114#define FSI_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE)
113 115
116typedef int (*set_rate_func)(struct device *dev, int is_porta, int rate, int enable);
117
114/* 118/*
115 * FSI driver use below type name for variable 119 * FSI driver use below type name for variable
116 * 120 *
@@ -128,7 +132,6 @@ struct fsi_stream {
128 struct snd_pcm_substream *substream; 132 struct snd_pcm_substream *substream;
129 133
130 int fifo_max_num; 134 int fifo_max_num;
131 int chan_num;
132 135
133 int buff_offset; 136 int buff_offset;
134 int buff_len; 137 int buff_len;
@@ -143,6 +146,7 @@ struct fsi_priv {
143 void __iomem *base; 146 void __iomem *base;
144 struct fsi_master *master; 147 struct fsi_master *master;
145 148
149 int chan_num;
146 struct fsi_stream playback; 150 struct fsi_stream playback;
147 struct fsi_stream capture; 151 struct fsi_stream capture;
148 152
@@ -252,9 +256,8 @@ static struct snd_soc_dai *fsi_get_dai(struct snd_pcm_substream *substream)
252 return rtd->cpu_dai; 256 return rtd->cpu_dai;
253} 257}
254 258
255static struct fsi_priv *fsi_get_priv(struct snd_pcm_substream *substream) 259static struct fsi_priv *fsi_get_priv_frm_dai(struct snd_soc_dai *dai)
256{ 260{
257 struct snd_soc_dai *dai = fsi_get_dai(substream);
258 struct fsi_master *master = snd_soc_dai_get_drvdata(dai); 261 struct fsi_master *master = snd_soc_dai_get_drvdata(dai);
259 262
260 if (dai->id == 0) 263 if (dai->id == 0)
@@ -263,11 +266,27 @@ static struct fsi_priv *fsi_get_priv(struct snd_pcm_substream *substream)
263 return &master->fsib; 266 return &master->fsib;
264} 267}
265 268
269static struct fsi_priv *fsi_get_priv(struct snd_pcm_substream *substream)
270{
271 return fsi_get_priv_frm_dai(fsi_get_dai(substream));
272}
273
274static set_rate_func fsi_get_info_set_rate(struct fsi_master *master)
275{
276 if (!master->info)
277 return NULL;
278
279 return master->info->set_rate;
280}
281
266static u32 fsi_get_info_flags(struct fsi_priv *fsi) 282static u32 fsi_get_info_flags(struct fsi_priv *fsi)
267{ 283{
268 int is_porta = fsi_is_port_a(fsi); 284 int is_porta = fsi_is_port_a(fsi);
269 struct fsi_master *master = fsi_get_master(fsi); 285 struct fsi_master *master = fsi_get_master(fsi);
270 286
287 if (!master->info)
288 return 0;
289
271 return is_porta ? master->info->porta_flags : 290 return is_porta ? master->info->porta_flags :
272 master->info->portb_flags; 291 master->info->portb_flags;
273} 292}
@@ -288,21 +307,6 @@ static inline struct fsi_stream *fsi_get_stream(struct fsi_priv *fsi,
288 return is_play ? &fsi->playback : &fsi->capture; 307 return is_play ? &fsi->playback : &fsi->capture;
289} 308}
290 309
291static int fsi_is_master_mode(struct fsi_priv *fsi, int is_play)
292{
293 u32 mode;
294 u32 flags = fsi_get_info_flags(fsi);
295
296 mode = is_play ? SH_FSI_OUT_SLAVE_MODE : SH_FSI_IN_SLAVE_MODE;
297
298 /* return
299 * 1 : master mode
300 * 0 : slave mode
301 */
302
303 return (mode & flags) != mode;
304}
305
306static u32 fsi_get_port_shift(struct fsi_priv *fsi, int is_play) 310static u32 fsi_get_port_shift(struct fsi_priv *fsi, int is_play)
307{ 311{
308 int is_porta = fsi_is_port_a(fsi); 312 int is_porta = fsi_is_port_a(fsi);
@@ -357,7 +361,6 @@ static void fsi_stream_pop(struct fsi_priv *fsi, int is_play)
357static int fsi_get_fifo_data_num(struct fsi_priv *fsi, int is_play) 361static int fsi_get_fifo_data_num(struct fsi_priv *fsi, int is_play)
358{ 362{
359 u32 status; 363 u32 status;
360 struct fsi_stream *io = fsi_get_stream(fsi, is_play);
361 int data_num; 364 int data_num;
362 365
363 status = is_play ? 366 status = is_play ?
@@ -365,7 +368,7 @@ static int fsi_get_fifo_data_num(struct fsi_priv *fsi, int is_play)
365 fsi_reg_read(fsi, DIFF_ST); 368 fsi_reg_read(fsi, DIFF_ST);
366 369
367 data_num = 0x1ff & (status >> 8); 370 data_num = 0x1ff & (status >> 8);
368 data_num *= io->chan_num; 371 data_num *= fsi->chan_num;
369 372
370 return data_num; 373 return data_num;
371} 374}
@@ -387,7 +390,7 @@ static int fsi_get_frame_width(struct fsi_priv *fsi, int is_play)
387 struct snd_pcm_substream *substream = io->substream; 390 struct snd_pcm_substream *substream = io->substream;
388 struct snd_pcm_runtime *runtime = substream->runtime; 391 struct snd_pcm_runtime *runtime = substream->runtime;
389 392
390 return frames_to_bytes(runtime, 1) / io->chan_num; 393 return frames_to_bytes(runtime, 1) / fsi->chan_num;
391} 394}
392 395
393static void fsi_count_fifo_err(struct fsi_priv *fsi) 396static void fsi_count_fifo_err(struct fsi_priv *fsi)
@@ -580,10 +583,10 @@ static void fsi_fifo_init(struct fsi_priv *fsi,
580 * 7 channels: 32 ( 32 x 7 = 224) 583 * 7 channels: 32 ( 32 x 7 = 224)
581 * 8 channels: 32 ( 32 x 8 = 256) 584 * 8 channels: 32 ( 32 x 8 = 256)
582 */ 585 */
583 for (i = 1; i < io->chan_num; i <<= 1) 586 for (i = 1; i < fsi->chan_num; i <<= 1)
584 io->fifo_max_num >>= 1; 587 io->fifo_max_num >>= 1;
585 dev_dbg(dai->dev, "%d channel %d store\n", 588 dev_dbg(dai->dev, "%d channel %d store\n",
586 io->chan_num, io->fifo_max_num); 589 fsi->chan_num, io->fifo_max_num);
587 590
588 /* 591 /*
589 * set interrupt generation factor 592 * set interrupt generation factor
@@ -659,7 +662,7 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream)
659 * data_num_max : number of FSI fifo free space 662 * data_num_max : number of FSI fifo free space
660 * data_num : number of ALSA residue data 663 * data_num : number of ALSA residue data
661 */ 664 */
662 data_num_max = io->fifo_max_num * io->chan_num; 665 data_num_max = io->fifo_max_num * fsi->chan_num;
663 data_num_max -= fsi_get_fifo_data_num(fsi, is_play); 666 data_num_max -= fsi_get_fifo_data_num(fsi, is_play);
664 667
665 data_num = data_residue_num; 668 data_num = data_residue_num;
@@ -754,25 +757,12 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
754 struct snd_soc_dai *dai) 757 struct snd_soc_dai *dai)
755{ 758{
756 struct fsi_priv *fsi = fsi_get_priv(substream); 759 struct fsi_priv *fsi = fsi_get_priv(substream);
757 struct fsi_master *master = fsi_get_master(fsi);
758 struct fsi_stream *io;
759 u32 flags = fsi_get_info_flags(fsi); 760 u32 flags = fsi_get_info_flags(fsi);
760 u32 fmt;
761 u32 data; 761 u32 data;
762 int is_play = fsi_is_play(substream); 762 int is_play = fsi_is_play(substream);
763 int is_master;
764
765 io = fsi_get_stream(fsi, is_play);
766 763
767 pm_runtime_get_sync(dai->dev); 764 pm_runtime_get_sync(dai->dev);
768 765
769 /* CKG1 */
770 data = is_play ? (1 << 0) : (1 << 4);
771 is_master = fsi_is_master_mode(fsi, is_play);
772 if (is_master)
773 fsi_reg_mask_set(fsi, CKG1, data, data);
774 else
775 fsi_reg_mask_set(fsi, CKG1, data, 0);
776 766
777 /* clock inversion (CKG2) */ 767 /* clock inversion (CKG2) */
778 data = 0; 768 data = 0;
@@ -787,54 +777,6 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
787 777
788 fsi_reg_write(fsi, CKG2, data); 778 fsi_reg_write(fsi, CKG2, data);
789 779
790 /* do fmt, di fmt */
791 data = 0;
792 fmt = is_play ? SH_FSI_GET_OFMT(flags) : SH_FSI_GET_IFMT(flags);
793 switch (fmt) {
794 case SH_FSI_FMT_MONO:
795 data = CR_MONO;
796 io->chan_num = 1;
797 break;
798 case SH_FSI_FMT_MONO_DELAY:
799 data = CR_MONO_D;
800 io->chan_num = 1;
801 break;
802 case SH_FSI_FMT_PCM:
803 data = CR_PCM;
804 io->chan_num = 2;
805 break;
806 case SH_FSI_FMT_I2S:
807 data = CR_I2S;
808 io->chan_num = 2;
809 break;
810 case SH_FSI_FMT_TDM:
811 io->chan_num = is_play ?
812 SH_FSI_GET_CH_O(flags) : SH_FSI_GET_CH_I(flags);
813 data = CR_TDM | (io->chan_num - 1);
814 break;
815 case SH_FSI_FMT_TDM_DELAY:
816 io->chan_num = is_play ?
817 SH_FSI_GET_CH_O(flags) : SH_FSI_GET_CH_I(flags);
818 data = CR_TDM_D | (io->chan_num - 1);
819 break;
820 case SH_FSI_FMT_SPDIF:
821 if (master->core->ver < 2) {
822 dev_err(dai->dev, "This FSI can not use SPDIF\n");
823 return -EINVAL;
824 }
825 data = CR_BWS_16 | CR_DTMD_SPDIF_PCM | CR_PCM;
826 io->chan_num = 2;
827 fsi_spdif_clk_ctrl(fsi, 1);
828 fsi_reg_mask_set(fsi, OUT_SEL, DMMD, DMMD);
829 break;
830 default:
831 dev_err(dai->dev, "unknown format.\n");
832 return -EINVAL;
833 }
834 is_play ?
835 fsi_reg_write(fsi, DO_FMT, data) :
836 fsi_reg_write(fsi, DI_FMT, data);
837
838 /* irq clear */ 780 /* irq clear */
839 fsi_irq_disable(fsi, is_play); 781 fsi_irq_disable(fsi, is_play);
840 fsi_irq_clear_status(fsi); 782 fsi_irq_clear_status(fsi);
@@ -851,12 +793,12 @@ static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
851 struct fsi_priv *fsi = fsi_get_priv(substream); 793 struct fsi_priv *fsi = fsi_get_priv(substream);
852 int is_play = fsi_is_play(substream); 794 int is_play = fsi_is_play(substream);
853 struct fsi_master *master = fsi_get_master(fsi); 795 struct fsi_master *master = fsi_get_master(fsi);
854 int (*set_rate)(struct device *dev, int is_porta, int rate, int enable); 796 set_rate_func set_rate;
855 797
856 fsi_irq_disable(fsi, is_play); 798 fsi_irq_disable(fsi, is_play);
857 fsi_clk_ctrl(fsi, 0); 799 fsi_clk_ctrl(fsi, 0);
858 800
859 set_rate = master->info->set_rate; 801 set_rate = fsi_get_info_set_rate(master);
860 if (set_rate && fsi->rate) 802 if (set_rate && fsi->rate)
861 set_rate(dai->dev, fsi_is_port_a(fsi), fsi->rate, 0); 803 set_rate(dai->dev, fsi_is_port_a(fsi), fsi->rate, 0);
862 fsi->rate = 0; 804 fsi->rate = 0;
@@ -889,18 +831,100 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
889 return ret; 831 return ret;
890} 832}
891 833
834static int fsi_set_fmt_dai(struct fsi_priv *fsi, unsigned int fmt)
835{
836 u32 data = 0;
837
838 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
839 case SND_SOC_DAIFMT_I2S:
840 data = CR_I2S;
841 fsi->chan_num = 2;
842 break;
843 case SND_SOC_DAIFMT_LEFT_J:
844 data = CR_PCM;
845 fsi->chan_num = 2;
846 break;
847 default:
848 return -EINVAL;
849 }
850
851 fsi_reg_write(fsi, DO_FMT, data);
852 fsi_reg_write(fsi, DI_FMT, data);
853
854 return 0;
855}
856
857static int fsi_set_fmt_spdif(struct fsi_priv *fsi)
858{
859 struct fsi_master *master = fsi_get_master(fsi);
860 u32 data = 0;
861
862 if (master->core->ver < 2)
863 return -EINVAL;
864
865 data = CR_BWS_16 | CR_DTMD_SPDIF_PCM | CR_PCM;
866 fsi->chan_num = 2;
867 fsi_spdif_clk_ctrl(fsi, 1);
868 fsi_reg_mask_set(fsi, OUT_SEL, DMMD, DMMD);
869
870 fsi_reg_write(fsi, DO_FMT, data);
871 fsi_reg_write(fsi, DI_FMT, data);
872
873 return 0;
874}
875
876static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
877{
878 struct fsi_priv *fsi = fsi_get_priv_frm_dai(dai);
879 u32 flags = fsi_get_info_flags(fsi);
880 u32 data = 0;
881 int ret;
882
883 pm_runtime_get_sync(dai->dev);
884
885 /* set master/slave audio interface */
886 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
887 case SND_SOC_DAIFMT_CBM_CFM:
888 data = DIMD | DOMD;
889 break;
890 case SND_SOC_DAIFMT_CBS_CFS:
891 break;
892 default:
893 ret = -EINVAL;
894 goto set_fmt_exit;
895 }
896 fsi_reg_mask_set(fsi, CKG1, (DIMD | DOMD), data);
897
898 /* set format */
899 switch (flags & SH_FSI_FMT_MASK) {
900 case SH_FSI_FMT_DAI:
901 ret = fsi_set_fmt_dai(fsi, fmt & SND_SOC_DAIFMT_FORMAT_MASK);
902 break;
903 case SH_FSI_FMT_SPDIF:
904 ret = fsi_set_fmt_spdif(fsi);
905 break;
906 default:
907 ret = -EINVAL;
908 }
909
910set_fmt_exit:
911 pm_runtime_put_sync(dai->dev);
912
913 return ret;
914}
915
892static int fsi_dai_hw_params(struct snd_pcm_substream *substream, 916static int fsi_dai_hw_params(struct snd_pcm_substream *substream,
893 struct snd_pcm_hw_params *params, 917 struct snd_pcm_hw_params *params,
894 struct snd_soc_dai *dai) 918 struct snd_soc_dai *dai)
895{ 919{
896 struct fsi_priv *fsi = fsi_get_priv(substream); 920 struct fsi_priv *fsi = fsi_get_priv(substream);
897 struct fsi_master *master = fsi_get_master(fsi); 921 struct fsi_master *master = fsi_get_master(fsi);
898 int (*set_rate)(struct device *dev, int is_porta, int rate, int enable); 922 set_rate_func set_rate;
899 int fsi_ver = master->core->ver; 923 int fsi_ver = master->core->ver;
900 long rate = params_rate(params); 924 long rate = params_rate(params);
901 int ret; 925 int ret;
902 926
903 set_rate = master->info->set_rate; 927 set_rate = fsi_get_info_set_rate(master);
904 if (!set_rate) 928 if (!set_rate)
905 return 0; 929 return 0;
906 930
@@ -975,6 +999,7 @@ static struct snd_soc_dai_ops fsi_dai_ops = {
975 .startup = fsi_dai_startup, 999 .startup = fsi_dai_startup,
976 .shutdown = fsi_dai_shutdown, 1000 .shutdown = fsi_dai_shutdown,
977 .trigger = fsi_dai_trigger, 1001 .trigger = fsi_dai_trigger,
1002 .set_fmt = fsi_dai_set_fmt,
978 .hw_params = fsi_dai_hw_params, 1003 .hw_params = fsi_dai_hw_params,
979}; 1004};
980 1005
diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c
index 8c2a21a978ac..5d76da43b14c 100644
--- a/sound/soc/soc-cache.c
+++ b/sound/soc/soc-cache.c
@@ -18,6 +18,8 @@
18#include <linux/bitmap.h> 18#include <linux/bitmap.h>
19#include <linux/rbtree.h> 19#include <linux/rbtree.h>
20 20
21#include <trace/events/asoc.h>
22
21static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec, 23static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec,
22 unsigned int reg) 24 unsigned int reg)
23{ 25{
@@ -25,7 +27,8 @@ static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec,
25 unsigned int val; 27 unsigned int val;
26 28
27 if (reg >= codec->driver->reg_cache_size || 29 if (reg >= codec->driver->reg_cache_size ||
28 snd_soc_codec_volatile_register(codec, reg)) { 30 snd_soc_codec_volatile_register(codec, reg) ||
31 codec->cache_bypass) {
29 if (codec->cache_only) 32 if (codec->cache_only)
30 return -1; 33 return -1;
31 34
@@ -49,7 +52,8 @@ static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg,
49 data[1] = value & 0x00ff; 52 data[1] = value & 0x00ff;
50 53
51 if (!snd_soc_codec_volatile_register(codec, reg) && 54 if (!snd_soc_codec_volatile_register(codec, reg) &&
52 reg < codec->driver->reg_cache_size) { 55 reg < codec->driver->reg_cache_size &&
56 !codec->cache_bypass) {
53 ret = snd_soc_cache_write(codec, reg, value); 57 ret = snd_soc_cache_write(codec, reg, value);
54 if (ret < 0) 58 if (ret < 0)
55 return -1; 59 return -1;
@@ -106,7 +110,8 @@ static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec,
106 unsigned int val; 110 unsigned int val;
107 111
108 if (reg >= codec->driver->reg_cache_size || 112 if (reg >= codec->driver->reg_cache_size ||
109 snd_soc_codec_volatile_register(codec, reg)) { 113 snd_soc_codec_volatile_register(codec, reg) ||
114 codec->cache_bypass) {
110 if (codec->cache_only) 115 if (codec->cache_only)
111 return -1; 116 return -1;
112 117
@@ -130,7 +135,8 @@ static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg,
130 data[1] = value & 0x00ff; 135 data[1] = value & 0x00ff;
131 136
132 if (!snd_soc_codec_volatile_register(codec, reg) && 137 if (!snd_soc_codec_volatile_register(codec, reg) &&
133 reg < codec->driver->reg_cache_size) { 138 reg < codec->driver->reg_cache_size &&
139 !codec->cache_bypass) {
134 ret = snd_soc_cache_write(codec, reg, value); 140 ret = snd_soc_cache_write(codec, reg, value);
135 if (ret < 0) 141 if (ret < 0)
136 return -1; 142 return -1;
@@ -191,7 +197,8 @@ static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg,
191 data[1] = value & 0xff; 197 data[1] = value & 0xff;
192 198
193 if (!snd_soc_codec_volatile_register(codec, reg) && 199 if (!snd_soc_codec_volatile_register(codec, reg) &&
194 reg < codec->driver->reg_cache_size) { 200 reg < codec->driver->reg_cache_size &&
201 !codec->cache_bypass) {
195 ret = snd_soc_cache_write(codec, reg, value); 202 ret = snd_soc_cache_write(codec, reg, value);
196 if (ret < 0) 203 if (ret < 0)
197 return -1; 204 return -1;
@@ -216,7 +223,8 @@ static unsigned int snd_soc_8_8_read(struct snd_soc_codec *codec,
216 223
217 reg &= 0xff; 224 reg &= 0xff;
218 if (reg >= codec->driver->reg_cache_size || 225 if (reg >= codec->driver->reg_cache_size ||
219 snd_soc_codec_volatile_register(codec, reg)) { 226 snd_soc_codec_volatile_register(codec, reg) ||
227 codec->cache_bypass) {
220 if (codec->cache_only) 228 if (codec->cache_only)
221 return -1; 229 return -1;
222 230
@@ -271,7 +279,8 @@ static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg,
271 data[2] = value & 0xff; 279 data[2] = value & 0xff;
272 280
273 if (!snd_soc_codec_volatile_register(codec, reg) && 281 if (!snd_soc_codec_volatile_register(codec, reg) &&
274 reg < codec->driver->reg_cache_size) { 282 reg < codec->driver->reg_cache_size &&
283 !codec->cache_bypass) {
275 ret = snd_soc_cache_write(codec, reg, value); 284 ret = snd_soc_cache_write(codec, reg, value);
276 if (ret < 0) 285 if (ret < 0)
277 return -1; 286 return -1;
@@ -295,7 +304,8 @@ static unsigned int snd_soc_8_16_read(struct snd_soc_codec *codec,
295 unsigned int val; 304 unsigned int val;
296 305
297 if (reg >= codec->driver->reg_cache_size || 306 if (reg >= codec->driver->reg_cache_size ||
298 snd_soc_codec_volatile_register(codec, reg)) { 307 snd_soc_codec_volatile_register(codec, reg) ||
308 codec->cache_bypass) {
299 if (codec->cache_only) 309 if (codec->cache_only)
300 return -1; 310 return -1;
301 311
@@ -450,7 +460,8 @@ static unsigned int snd_soc_16_8_read(struct snd_soc_codec *codec,
450 460
451 reg &= 0xff; 461 reg &= 0xff;
452 if (reg >= codec->driver->reg_cache_size || 462 if (reg >= codec->driver->reg_cache_size ||
453 snd_soc_codec_volatile_register(codec, reg)) { 463 snd_soc_codec_volatile_register(codec, reg) ||
464 codec->cache_bypass) {
454 if (codec->cache_only) 465 if (codec->cache_only)
455 return -1; 466 return -1;
456 467
@@ -476,7 +487,8 @@ static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg,
476 487
477 reg &= 0xff; 488 reg &= 0xff;
478 if (!snd_soc_codec_volatile_register(codec, reg) && 489 if (!snd_soc_codec_volatile_register(codec, reg) &&
479 reg < codec->driver->reg_cache_size) { 490 reg < codec->driver->reg_cache_size &&
491 !codec->cache_bypass) {
480 ret = snd_soc_cache_write(codec, reg, value); 492 ret = snd_soc_cache_write(codec, reg, value);
481 if (ret < 0) 493 if (ret < 0)
482 return -1; 494 return -1;
@@ -568,7 +580,8 @@ static unsigned int snd_soc_16_16_read(struct snd_soc_codec *codec,
568 unsigned int val; 580 unsigned int val;
569 581
570 if (reg >= codec->driver->reg_cache_size || 582 if (reg >= codec->driver->reg_cache_size ||
571 snd_soc_codec_volatile_register(codec, reg)) { 583 snd_soc_codec_volatile_register(codec, reg) ||
584 codec->cache_bypass) {
572 if (codec->cache_only) 585 if (codec->cache_only)
573 return -1; 586 return -1;
574 587
@@ -595,7 +608,8 @@ static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg,
595 data[3] = value & 0xff; 608 data[3] = value & 0xff;
596 609
597 if (!snd_soc_codec_volatile_register(codec, reg) && 610 if (!snd_soc_codec_volatile_register(codec, reg) &&
598 reg < codec->driver->reg_cache_size) { 611 reg < codec->driver->reg_cache_size &&
612 !codec->cache_bypass) {
599 ret = snd_soc_cache_write(codec, reg, value); 613 ret = snd_soc_cache_write(codec, reg, value);
600 if (ret < 0) 614 if (ret < 0)
601 return -1; 615 return -1;
@@ -761,6 +775,49 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
761} 775}
762EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io); 776EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io);
763 777
778static bool snd_soc_set_cache_val(void *base, unsigned int idx,
779 unsigned int val, unsigned int word_size)
780{
781 switch (word_size) {
782 case 1: {
783 u8 *cache = base;
784 if (cache[idx] == val)
785 return true;
786 cache[idx] = val;
787 break;
788 }
789 case 2: {
790 u16 *cache = base;
791 if (cache[idx] == val)
792 return true;
793 cache[idx] = val;
794 break;
795 }
796 default:
797 BUG();
798 }
799 return false;
800}
801
802static unsigned int snd_soc_get_cache_val(const void *base, unsigned int idx,
803 unsigned int word_size)
804{
805 switch (word_size) {
806 case 1: {
807 const u8 *cache = base;
808 return cache[idx];
809 }
810 case 2: {
811 const u16 *cache = base;
812 return cache[idx];
813 }
814 default:
815 BUG();
816 }
817 /* unreachable */
818 return -1;
819}
820
764struct snd_soc_rbtree_node { 821struct snd_soc_rbtree_node {
765 struct rb_node node; 822 struct rb_node node;
766 unsigned int reg; 823 unsigned int reg;
@@ -835,7 +892,9 @@ static int snd_soc_rbtree_cache_sync(struct snd_soc_codec *codec)
835 ret = snd_soc_cache_read(codec, rbnode->reg, &val); 892 ret = snd_soc_cache_read(codec, rbnode->reg, &val);
836 if (ret) 893 if (ret)
837 return ret; 894 return ret;
895 codec->cache_bypass = 1;
838 ret = snd_soc_write(codec, rbnode->reg, val); 896 ret = snd_soc_write(codec, rbnode->reg, val);
897 codec->cache_bypass = 0;
839 if (ret) 898 if (ret)
840 return ret; 899 return ret;
841 dev_dbg(codec->dev, "Synced register %#x, value = %#x\n", 900 dev_dbg(codec->dev, "Synced register %#x, value = %#x\n",
@@ -924,7 +983,12 @@ static int snd_soc_rbtree_cache_exit(struct snd_soc_codec *codec)
924 983
925static int snd_soc_rbtree_cache_init(struct snd_soc_codec *codec) 984static int snd_soc_rbtree_cache_init(struct snd_soc_codec *codec)
926{ 985{
986 struct snd_soc_rbtree_node *rbtree_node;
927 struct snd_soc_rbtree_ctx *rbtree_ctx; 987 struct snd_soc_rbtree_ctx *rbtree_ctx;
988 unsigned int val;
989 unsigned int word_size;
990 int i;
991 int ret;
928 992
929 codec->reg_cache = kmalloc(sizeof *rbtree_ctx, GFP_KERNEL); 993 codec->reg_cache = kmalloc(sizeof *rbtree_ctx, GFP_KERNEL);
930 if (!codec->reg_cache) 994 if (!codec->reg_cache)
@@ -936,53 +1000,25 @@ static int snd_soc_rbtree_cache_init(struct snd_soc_codec *codec)
936 if (!codec->reg_def_copy) 1000 if (!codec->reg_def_copy)
937 return 0; 1001 return 0;
938 1002
939/* 1003 /*
940 * populate the rbtree with the initialized registers. All other 1004 * populate the rbtree with the initialized registers. All other
941 * registers will be inserted into the tree when they are first written. 1005 * registers will be inserted when they are first modified.
942 * 1006 */
943 * The reasoning behind this, is that we need to step through and 1007 word_size = codec->driver->reg_word_size;
944 * dereference the cache in u8/u16 increments without sacrificing 1008 for (i = 0; i < codec->driver->reg_cache_size; ++i) {
945 * portability. This could also be done using memcpy() but that would 1009 val = snd_soc_get_cache_val(codec->reg_def_copy, i, word_size);
946 * be slightly more cryptic. 1010 if (!val)
947 */ 1011 continue;
948#define snd_soc_rbtree_populate(cache) \ 1012 rbtree_node = kzalloc(sizeof *rbtree_node, GFP_KERNEL);
949({ \ 1013 if (!rbtree_node) {
950 int ret, i; \ 1014 ret = -ENOMEM;
951 struct snd_soc_rbtree_node *rbtree_node; \ 1015 snd_soc_cache_exit(codec);
952 \ 1016 break;
953 ret = 0; \ 1017 }
954 cache = codec->reg_def_copy; \ 1018 rbtree_node->reg = i;
955 for (i = 0; i < codec->driver->reg_cache_size; ++i) { \ 1019 rbtree_node->value = val;
956 if (!cache[i]) \ 1020 rbtree_node->defval = val;
957 continue; \ 1021 snd_soc_rbtree_insert(&rbtree_ctx->root, rbtree_node);
958 rbtree_node = kzalloc(sizeof *rbtree_node, GFP_KERNEL); \
959 if (!rbtree_node) { \
960 ret = -ENOMEM; \
961 snd_soc_cache_exit(codec); \
962 break; \
963 } \
964 rbtree_node->reg = i; \
965 rbtree_node->value = cache[i]; \
966 rbtree_node->defval = cache[i]; \
967 snd_soc_rbtree_insert(&rbtree_ctx->root, \
968 rbtree_node); \
969 } \
970 ret; \
971})
972
973 switch (codec->driver->reg_word_size) {
974 case 1: {
975 const u8 *cache;
976
977 return snd_soc_rbtree_populate(cache);
978 }
979 case 2: {
980 const u16 *cache;
981
982 return snd_soc_rbtree_populate(cache);
983 }
984 default:
985 BUG();
986 } 1022 }
987 1023
988 return 0; 1024 return 0;
@@ -1080,34 +1116,28 @@ static inline int snd_soc_lzo_get_blkindex(struct snd_soc_codec *codec,
1080 unsigned int reg) 1116 unsigned int reg)
1081{ 1117{
1082 const struct snd_soc_codec_driver *codec_drv; 1118 const struct snd_soc_codec_driver *codec_drv;
1083 size_t reg_size;
1084 1119
1085 codec_drv = codec->driver; 1120 codec_drv = codec->driver;
1086 reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size;
1087 return (reg * codec_drv->reg_word_size) / 1121 return (reg * codec_drv->reg_word_size) /
1088 DIV_ROUND_UP(reg_size, snd_soc_lzo_block_count()); 1122 DIV_ROUND_UP(codec->reg_size, snd_soc_lzo_block_count());
1089} 1123}
1090 1124
1091static inline int snd_soc_lzo_get_blkpos(struct snd_soc_codec *codec, 1125static inline int snd_soc_lzo_get_blkpos(struct snd_soc_codec *codec,
1092 unsigned int reg) 1126 unsigned int reg)
1093{ 1127{
1094 const struct snd_soc_codec_driver *codec_drv; 1128 const struct snd_soc_codec_driver *codec_drv;
1095 size_t reg_size;
1096 1129
1097 codec_drv = codec->driver; 1130 codec_drv = codec->driver;
1098 reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size; 1131 return reg % (DIV_ROUND_UP(codec->reg_size, snd_soc_lzo_block_count()) /
1099 return reg % (DIV_ROUND_UP(reg_size, snd_soc_lzo_block_count()) /
1100 codec_drv->reg_word_size); 1132 codec_drv->reg_word_size);
1101} 1133}
1102 1134
1103static inline int snd_soc_lzo_get_blksize(struct snd_soc_codec *codec) 1135static inline int snd_soc_lzo_get_blksize(struct snd_soc_codec *codec)
1104{ 1136{
1105 const struct snd_soc_codec_driver *codec_drv; 1137 const struct snd_soc_codec_driver *codec_drv;
1106 size_t reg_size;
1107 1138
1108 codec_drv = codec->driver; 1139 codec_drv = codec->driver;
1109 reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size; 1140 return DIV_ROUND_UP(codec->reg_size, snd_soc_lzo_block_count());
1110 return DIV_ROUND_UP(reg_size, snd_soc_lzo_block_count());
1111} 1141}
1112 1142
1113static int snd_soc_lzo_cache_sync(struct snd_soc_codec *codec) 1143static int snd_soc_lzo_cache_sync(struct snd_soc_codec *codec)
@@ -1122,7 +1152,9 @@ static int snd_soc_lzo_cache_sync(struct snd_soc_codec *codec)
1122 ret = snd_soc_cache_read(codec, i, &val); 1152 ret = snd_soc_cache_read(codec, i, &val);
1123 if (ret) 1153 if (ret)
1124 return ret; 1154 return ret;
1155 codec->cache_bypass = 1;
1125 ret = snd_soc_write(codec, i, val); 1156 ret = snd_soc_write(codec, i, val);
1157 codec->cache_bypass = 0;
1126 if (ret) 1158 if (ret)
1127 return ret; 1159 return ret;
1128 dev_dbg(codec->dev, "Synced register %#x, value = %#x\n", 1160 dev_dbg(codec->dev, "Synced register %#x, value = %#x\n",
@@ -1165,29 +1197,10 @@ static int snd_soc_lzo_cache_write(struct snd_soc_codec *codec,
1165 } 1197 }
1166 1198
1167 /* write the new value to the cache */ 1199 /* write the new value to the cache */
1168 switch (codec->driver->reg_word_size) { 1200 if (snd_soc_set_cache_val(lzo_block->dst, blkpos, value,
1169 case 1: { 1201 codec->driver->reg_word_size)) {
1170 u8 *cache; 1202 kfree(lzo_block->dst);
1171 cache = lzo_block->dst; 1203 goto out;
1172 if (cache[blkpos] == value) {
1173 kfree(lzo_block->dst);
1174 goto out;
1175 }
1176 cache[blkpos] = value;
1177 }
1178 break;
1179 case 2: {
1180 u16 *cache;
1181 cache = lzo_block->dst;
1182 if (cache[blkpos] == value) {
1183 kfree(lzo_block->dst);
1184 goto out;
1185 }
1186 cache[blkpos] = value;
1187 }
1188 break;
1189 default:
1190 BUG();
1191 } 1204 }
1192 1205
1193 /* prepare the source to be the decompressed block */ 1206 /* prepare the source to be the decompressed block */
@@ -1241,25 +1254,10 @@ static int snd_soc_lzo_cache_read(struct snd_soc_codec *codec,
1241 1254
1242 /* decompress the block */ 1255 /* decompress the block */
1243 ret = snd_soc_lzo_decompress_cache_block(codec, lzo_block); 1256 ret = snd_soc_lzo_decompress_cache_block(codec, lzo_block);
1244 if (ret >= 0) { 1257 if (ret >= 0)
1245 /* fetch the value from the cache */ 1258 /* fetch the value from the cache */
1246 switch (codec->driver->reg_word_size) { 1259 *value = snd_soc_get_cache_val(lzo_block->dst, blkpos,
1247 case 1: { 1260 codec->driver->reg_word_size);
1248 u8 *cache;
1249 cache = lzo_block->dst;
1250 *value = cache[blkpos];
1251 }
1252 break;
1253 case 2: {
1254 u16 *cache;
1255 cache = lzo_block->dst;
1256 *value = cache[blkpos];
1257 }
1258 break;
1259 default:
1260 BUG();
1261 }
1262 }
1263 1261
1264 kfree(lzo_block->dst); 1262 kfree(lzo_block->dst);
1265 /* restore the pointer and length of the compressed block */ 1263 /* restore the pointer and length of the compressed block */
@@ -1301,7 +1299,7 @@ static int snd_soc_lzo_cache_exit(struct snd_soc_codec *codec)
1301static int snd_soc_lzo_cache_init(struct snd_soc_codec *codec) 1299static int snd_soc_lzo_cache_init(struct snd_soc_codec *codec)
1302{ 1300{
1303 struct snd_soc_lzo_ctx **lzo_blocks; 1301 struct snd_soc_lzo_ctx **lzo_blocks;
1304 size_t reg_size, bmp_size; 1302 size_t bmp_size;
1305 const struct snd_soc_codec_driver *codec_drv; 1303 const struct snd_soc_codec_driver *codec_drv;
1306 int ret, tofree, i, blksize, blkcount; 1304 int ret, tofree, i, blksize, blkcount;
1307 const char *p, *end; 1305 const char *p, *end;
@@ -1309,7 +1307,6 @@ static int snd_soc_lzo_cache_init(struct snd_soc_codec *codec)
1309 1307
1310 ret = 0; 1308 ret = 0;
1311 codec_drv = codec->driver; 1309 codec_drv = codec->driver;
1312 reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size;
1313 1310
1314 /* 1311 /*
1315 * If we have not been given a default register cache 1312 * If we have not been given a default register cache
@@ -1321,8 +1318,7 @@ static int snd_soc_lzo_cache_init(struct snd_soc_codec *codec)
1321 tofree = 1; 1318 tofree = 1;
1322 1319
1323 if (!codec->reg_def_copy) { 1320 if (!codec->reg_def_copy) {
1324 codec->reg_def_copy = kzalloc(reg_size, 1321 codec->reg_def_copy = kzalloc(codec->reg_size, GFP_KERNEL);
1325 GFP_KERNEL);
1326 if (!codec->reg_def_copy) 1322 if (!codec->reg_def_copy)
1327 return -ENOMEM; 1323 return -ENOMEM;
1328 } 1324 }
@@ -1370,7 +1366,7 @@ static int snd_soc_lzo_cache_init(struct snd_soc_codec *codec)
1370 1366
1371 blksize = snd_soc_lzo_get_blksize(codec); 1367 blksize = snd_soc_lzo_get_blksize(codec);
1372 p = codec->reg_def_copy; 1368 p = codec->reg_def_copy;
1373 end = codec->reg_def_copy + reg_size; 1369 end = codec->reg_def_copy + codec->reg_size;
1374 /* compress the register map and fill the lzo blocks */ 1370 /* compress the register map and fill the lzo blocks */
1375 for (i = 0; i < blkcount; ++i, p += blksize) { 1371 for (i = 0; i < blkcount; ++i, p += blksize) {
1376 lzo_blocks[i]->src = p; 1372 lzo_blocks[i]->src = p;
@@ -1414,28 +1410,10 @@ static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec)
1414 ret = snd_soc_cache_read(codec, i, &val); 1410 ret = snd_soc_cache_read(codec, i, &val);
1415 if (ret) 1411 if (ret)
1416 return ret; 1412 return ret;
1417 if (codec_drv->reg_cache_default) { 1413 if (codec->reg_def_copy)
1418 switch (codec_drv->reg_word_size) { 1414 if (snd_soc_get_cache_val(codec->reg_def_copy,
1419 case 1: { 1415 i, codec_drv->reg_word_size) == val)
1420 const u8 *cache; 1416 continue;
1421
1422 cache = codec_drv->reg_cache_default;
1423 if (cache[i] == val)
1424 continue;
1425 }
1426 break;
1427 case 2: {
1428 const u16 *cache;
1429
1430 cache = codec_drv->reg_cache_default;
1431 if (cache[i] == val)
1432 continue;
1433 }
1434 break;
1435 default:
1436 BUG();
1437 }
1438 }
1439 ret = snd_soc_write(codec, i, val); 1417 ret = snd_soc_write(codec, i, val);
1440 if (ret) 1418 if (ret)
1441 return ret; 1419 return ret;
@@ -1448,50 +1426,16 @@ static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec)
1448static int snd_soc_flat_cache_write(struct snd_soc_codec *codec, 1426static int snd_soc_flat_cache_write(struct snd_soc_codec *codec,
1449 unsigned int reg, unsigned int value) 1427 unsigned int reg, unsigned int value)
1450{ 1428{
1451 switch (codec->driver->reg_word_size) { 1429 snd_soc_set_cache_val(codec->reg_cache, reg, value,
1452 case 1: { 1430 codec->driver->reg_word_size);
1453 u8 *cache;
1454
1455 cache = codec->reg_cache;
1456 cache[reg] = value;
1457 }
1458 break;
1459 case 2: {
1460 u16 *cache;
1461
1462 cache = codec->reg_cache;
1463 cache[reg] = value;
1464 }
1465 break;
1466 default:
1467 BUG();
1468 }
1469
1470 return 0; 1431 return 0;
1471} 1432}
1472 1433
1473static int snd_soc_flat_cache_read(struct snd_soc_codec *codec, 1434static int snd_soc_flat_cache_read(struct snd_soc_codec *codec,
1474 unsigned int reg, unsigned int *value) 1435 unsigned int reg, unsigned int *value)
1475{ 1436{
1476 switch (codec->driver->reg_word_size) { 1437 *value = snd_soc_get_cache_val(codec->reg_cache, reg,
1477 case 1: { 1438 codec->driver->reg_word_size);
1478 u8 *cache;
1479
1480 cache = codec->reg_cache;
1481 *value = cache[reg];
1482 }
1483 break;
1484 case 2: {
1485 u16 *cache;
1486
1487 cache = codec->reg_cache;
1488 *value = cache[reg];
1489 }
1490 break;
1491 default:
1492 BUG();
1493 }
1494
1495 return 0; 1439 return 0;
1496} 1440}
1497 1441
@@ -1507,24 +1451,14 @@ static int snd_soc_flat_cache_exit(struct snd_soc_codec *codec)
1507static int snd_soc_flat_cache_init(struct snd_soc_codec *codec) 1451static int snd_soc_flat_cache_init(struct snd_soc_codec *codec)
1508{ 1452{
1509 const struct snd_soc_codec_driver *codec_drv; 1453 const struct snd_soc_codec_driver *codec_drv;
1510 size_t reg_size;
1511 1454
1512 codec_drv = codec->driver; 1455 codec_drv = codec->driver;
1513 reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size;
1514 1456
1515 /* 1457 if (codec->reg_def_copy)
1516 * for flat compression, we don't need to keep a copy of the 1458 codec->reg_cache = kmemdup(codec->reg_def_copy,
1517 * original defaults register cache as it will definitely not 1459 codec->reg_size, GFP_KERNEL);
1518 * be marked as __devinitconst
1519 */
1520 kfree(codec->reg_def_copy);
1521 codec->reg_def_copy = NULL;
1522
1523 if (codec_drv->reg_cache_default)
1524 codec->reg_cache = kmemdup(codec_drv->reg_cache_default,
1525 reg_size, GFP_KERNEL);
1526 else 1460 else
1527 codec->reg_cache = kzalloc(reg_size, GFP_KERNEL); 1461 codec->reg_cache = kzalloc(codec->reg_size, GFP_KERNEL);
1528 if (!codec->reg_cache) 1462 if (!codec->reg_cache)
1529 return -ENOMEM; 1463 return -ENOMEM;
1530 1464
@@ -1669,21 +1603,77 @@ EXPORT_SYMBOL_GPL(snd_soc_cache_write);
1669int snd_soc_cache_sync(struct snd_soc_codec *codec) 1603int snd_soc_cache_sync(struct snd_soc_codec *codec)
1670{ 1604{
1671 int ret; 1605 int ret;
1606 const char *name;
1672 1607
1673 if (!codec->cache_sync) { 1608 if (!codec->cache_sync) {
1674 return 0; 1609 return 0;
1675 } 1610 }
1676 1611
1677 if (codec->cache_ops && codec->cache_ops->sync) { 1612 if (!codec->cache_ops || !codec->cache_ops->sync)
1678 if (codec->cache_ops->name) 1613 return -EINVAL;
1679 dev_dbg(codec->dev, "Syncing %s cache for %s codec\n",
1680 codec->cache_ops->name, codec->name);
1681 ret = codec->cache_ops->sync(codec);
1682 if (!ret)
1683 codec->cache_sync = 0;
1684 return ret;
1685 }
1686 1614
1687 return -EINVAL; 1615 if (codec->cache_ops->name)
1616 name = codec->cache_ops->name;
1617 else
1618 name = "unknown";
1619
1620 if (codec->cache_ops->name)
1621 dev_dbg(codec->dev, "Syncing %s cache for %s codec\n",
1622 codec->cache_ops->name, codec->name);
1623 trace_snd_soc_cache_sync(codec, name, "start");
1624 ret = codec->cache_ops->sync(codec);
1625 if (!ret)
1626 codec->cache_sync = 0;
1627 trace_snd_soc_cache_sync(codec, name, "end");
1628 return ret;
1688} 1629}
1689EXPORT_SYMBOL_GPL(snd_soc_cache_sync); 1630EXPORT_SYMBOL_GPL(snd_soc_cache_sync);
1631
1632static int snd_soc_get_reg_access_index(struct snd_soc_codec *codec,
1633 unsigned int reg)
1634{
1635 const struct snd_soc_codec_driver *codec_drv;
1636 unsigned int min, max, index;
1637
1638 codec_drv = codec->driver;
1639 min = 0;
1640 max = codec_drv->reg_access_size - 1;
1641 do {
1642 index = (min + max) / 2;
1643 if (codec_drv->reg_access_default[index].reg == reg)
1644 return index;
1645 if (codec_drv->reg_access_default[index].reg < reg)
1646 min = index + 1;
1647 else
1648 max = index;
1649 } while (min <= max);
1650 return -1;
1651}
1652
1653int snd_soc_default_volatile_register(struct snd_soc_codec *codec,
1654 unsigned int reg)
1655{
1656 int index;
1657
1658 if (reg >= codec->driver->reg_cache_size)
1659 return 1;
1660 index = snd_soc_get_reg_access_index(codec, reg);
1661 if (index < 0)
1662 return 0;
1663 return codec->driver->reg_access_default[index].vol;
1664}
1665EXPORT_SYMBOL_GPL(snd_soc_default_volatile_register);
1666
1667int snd_soc_default_readable_register(struct snd_soc_codec *codec,
1668 unsigned int reg)
1669{
1670 int index;
1671
1672 if (reg >= codec->driver->reg_cache_size)
1673 return 1;
1674 index = snd_soc_get_reg_access_index(codec, reg);
1675 if (index < 0)
1676 return 0;
1677 return codec->driver->reg_access_default[index].read;
1678}
1679EXPORT_SYMBOL_GPL(snd_soc_default_readable_register);
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index c3f6f1e72790..17efacdb248a 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -48,7 +48,8 @@ static DEFINE_MUTEX(pcm_mutex);
48static DECLARE_WAIT_QUEUE_HEAD(soc_pm_waitq); 48static DECLARE_WAIT_QUEUE_HEAD(soc_pm_waitq);
49 49
50#ifdef CONFIG_DEBUG_FS 50#ifdef CONFIG_DEBUG_FS
51static struct dentry *debugfs_root; 51struct dentry *snd_soc_debugfs_root;
52EXPORT_SYMBOL_GPL(snd_soc_debugfs_root);
52#endif 53#endif
53 54
54static DEFINE_MUTEX(client_mutex); 55static DEFINE_MUTEX(client_mutex);
@@ -57,8 +58,6 @@ static LIST_HEAD(dai_list);
57static LIST_HEAD(platform_list); 58static LIST_HEAD(platform_list);
58static LIST_HEAD(codec_list); 59static LIST_HEAD(codec_list);
59 60
60static int snd_soc_register_card(struct snd_soc_card *card);
61static int snd_soc_unregister_card(struct snd_soc_card *card);
62static int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num); 61static int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num);
63 62
64/* 63/*
@@ -70,10 +69,73 @@ static int pmdown_time = 5000;
70module_param(pmdown_time, int, 0); 69module_param(pmdown_time, int, 0);
71MODULE_PARM_DESC(pmdown_time, "DAPM stream powerdown time (msecs)"); 70MODULE_PARM_DESC(pmdown_time, "DAPM stream powerdown time (msecs)");
72 71
72/* returns the minimum number of bytes needed to represent
73 * a particular given value */
74static int min_bytes_needed(unsigned long val)
75{
76 int c = 0;
77 int i;
78
79 for (i = (sizeof val * 8) - 1; i >= 0; --i, ++c)
80 if (val & (1UL << i))
81 break;
82 c = (sizeof val * 8) - c;
83 if (!c || (c % 8))
84 c = (c + 8) / 8;
85 else
86 c /= 8;
87 return c;
88}
89
90/* fill buf which is 'len' bytes with a formatted
91 * string of the form 'reg: value\n' */
92static int format_register_str(struct snd_soc_codec *codec,
93 unsigned int reg, char *buf, size_t len)
94{
95 int wordsize = codec->driver->reg_word_size * 2;
96 int regsize = min_bytes_needed(codec->driver->reg_cache_size) * 2;
97 int ret;
98 char tmpbuf[len + 1];
99 char regbuf[regsize + 1];
100
101 /* since tmpbuf is allocated on the stack, warn the callers if they
102 * try to abuse this function */
103 WARN_ON(len > 63);
104
105 /* +2 for ': ' and + 1 for '\n' */
106 if (wordsize + regsize + 2 + 1 != len)
107 return -EINVAL;
108
109 ret = snd_soc_read(codec , reg);
110 if (ret < 0) {
111 memset(regbuf, 'X', regsize);
112 regbuf[regsize] = '\0';
113 } else {
114 snprintf(regbuf, regsize + 1, "%.*x", regsize, ret);
115 }
116
117 /* prepare the buffer */
118 snprintf(tmpbuf, len + 1, "%.*x: %s\n", wordsize, reg, regbuf);
119 /* copy it back to the caller without the '\0' */
120 memcpy(buf, tmpbuf, len);
121
122 return 0;
123}
124
73/* codec register dump */ 125/* codec register dump */
74static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf) 126static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf,
127 size_t count, loff_t pos)
75{ 128{
76 int ret, i, step = 1, count = 0; 129 int i, step = 1;
130 int wordsize, regsize;
131 int len;
132 size_t total = 0;
133 loff_t p = 0;
134
135 wordsize = codec->driver->reg_word_size * 2;
136 regsize = min_bytes_needed(codec->driver->reg_cache_size) * 2;
137
138 len = wordsize + regsize + 2 + 1;
77 139
78 if (!codec->driver->reg_cache_size) 140 if (!codec->driver->reg_cache_size)
79 return 0; 141 return 0;
@@ -81,55 +143,37 @@ static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf)
81 if (codec->driver->reg_cache_step) 143 if (codec->driver->reg_cache_step)
82 step = codec->driver->reg_cache_step; 144 step = codec->driver->reg_cache_step;
83 145
84 count += sprintf(buf, "%s registers\n", codec->name);
85 for (i = 0; i < codec->driver->reg_cache_size; i += step) { 146 for (i = 0; i < codec->driver->reg_cache_size; i += step) {
86 if (codec->driver->readable_register && !codec->driver->readable_register(i)) 147 if (codec->readable_register && !codec->readable_register(codec, i))
87 continue; 148 continue;
88
89 count += sprintf(buf + count, "%2x: ", i);
90 if (count >= PAGE_SIZE - 1)
91 break;
92
93 if (codec->driver->display_register) { 149 if (codec->driver->display_register) {
94 count += codec->driver->display_register(codec, buf + count, 150 count += codec->driver->display_register(codec, buf + count,
95 PAGE_SIZE - count, i); 151 PAGE_SIZE - count, i);
96 } else { 152 } else {
97 /* If the read fails it's almost certainly due to 153 /* only support larger than PAGE_SIZE bytes debugfs
98 * the register being volatile and the device being 154 * entries for the default case */
99 * powered off. 155 if (p >= pos) {
100 */ 156 if (total + len >= count - 1)
101 ret = snd_soc_read(codec, i); 157 break;
102 if (ret >= 0) 158 format_register_str(codec, i, buf + total, len);
103 count += snprintf(buf + count, 159 total += len;
104 PAGE_SIZE - count, 160 }
105 "%4x", ret); 161 p += len;
106 else
107 count += snprintf(buf + count,
108 PAGE_SIZE - count,
109 "<no data: %d>", ret);
110 } 162 }
111
112 if (count >= PAGE_SIZE - 1)
113 break;
114
115 count += snprintf(buf + count, PAGE_SIZE - count, "\n");
116 if (count >= PAGE_SIZE - 1)
117 break;
118 } 163 }
119 164
120 /* Truncate count; min() would cause a warning */ 165 total = min(total, count - 1);
121 if (count >= PAGE_SIZE)
122 count = PAGE_SIZE - 1;
123 166
124 return count; 167 return total;
125} 168}
169
126static ssize_t codec_reg_show(struct device *dev, 170static ssize_t codec_reg_show(struct device *dev,
127 struct device_attribute *attr, char *buf) 171 struct device_attribute *attr, char *buf)
128{ 172{
129 struct snd_soc_pcm_runtime *rtd = 173 struct snd_soc_pcm_runtime *rtd =
130 container_of(dev, struct snd_soc_pcm_runtime, dev); 174 container_of(dev, struct snd_soc_pcm_runtime, dev);
131 175
132 return soc_codec_reg_show(rtd->codec, buf); 176 return soc_codec_reg_show(rtd->codec, buf, PAGE_SIZE, 0);
133} 177}
134 178
135static DEVICE_ATTR(codec_reg, 0444, codec_reg_show, NULL); 179static DEVICE_ATTR(codec_reg, 0444, codec_reg_show, NULL);
@@ -168,16 +212,28 @@ static int codec_reg_open_file(struct inode *inode, struct file *file)
168} 212}
169 213
170static ssize_t codec_reg_read_file(struct file *file, char __user *user_buf, 214static ssize_t codec_reg_read_file(struct file *file, char __user *user_buf,
171 size_t count, loff_t *ppos) 215 size_t count, loff_t *ppos)
172{ 216{
173 ssize_t ret; 217 ssize_t ret;
174 struct snd_soc_codec *codec = file->private_data; 218 struct snd_soc_codec *codec = file->private_data;
175 char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL); 219 char *buf;
220
221 if (*ppos < 0 || !count)
222 return -EINVAL;
223
224 buf = kmalloc(count, GFP_KERNEL);
176 if (!buf) 225 if (!buf)
177 return -ENOMEM; 226 return -ENOMEM;
178 ret = soc_codec_reg_show(codec, buf); 227
179 if (ret >= 0) 228 ret = soc_codec_reg_show(codec, buf, count, *ppos);
180 ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret); 229 if (ret >= 0) {
230 if (copy_to_user(user_buf, buf, ret)) {
231 kfree(buf);
232 return -EFAULT;
233 }
234 *ppos += ret;
235 }
236
181 kfree(buf); 237 kfree(buf);
182 return ret; 238 return ret;
183} 239}
@@ -209,6 +265,10 @@ static ssize_t codec_reg_write_file(struct file *file,
209 start++; 265 start++;
210 if (strict_strtoul(start, 16, &value)) 266 if (strict_strtoul(start, 16, &value))
211 return -EINVAL; 267 return -EINVAL;
268
269 /* Userspace has been fiddling around behind the kernel's back */
270 add_taint(TAINT_USER);
271
212 snd_soc_write(codec, reg, value); 272 snd_soc_write(codec, reg, value);
213 return buf_size; 273 return buf_size;
214} 274}
@@ -232,6 +292,11 @@ static void soc_init_codec_debugfs(struct snd_soc_codec *codec)
232 return; 292 return;
233 } 293 }
234 294
295 debugfs_create_bool("cache_sync", 0444, codec->debugfs_codec_root,
296 &codec->cache_sync);
297 debugfs_create_bool("cache_only", 0444, codec->debugfs_codec_root,
298 &codec->cache_only);
299
235 codec->debugfs_reg = debugfs_create_file("codec_reg", 0644, 300 codec->debugfs_reg = debugfs_create_file("codec_reg", 0644,
236 codec->debugfs_codec_root, 301 codec->debugfs_codec_root,
237 codec, &codec_reg_fops); 302 codec, &codec_reg_fops);
@@ -356,7 +421,7 @@ static const struct file_operations platform_list_fops = {
356static void soc_init_card_debugfs(struct snd_soc_card *card) 421static void soc_init_card_debugfs(struct snd_soc_card *card)
357{ 422{
358 card->debugfs_card_root = debugfs_create_dir(card->name, 423 card->debugfs_card_root = debugfs_create_dir(card->name,
359 debugfs_root); 424 snd_soc_debugfs_root);
360 if (!card->debugfs_card_root) { 425 if (!card->debugfs_card_root) {
361 dev_warn(card->dev, 426 dev_warn(card->dev,
362 "ASoC: Failed to create codec debugfs directory\n"); 427 "ASoC: Failed to create codec debugfs directory\n");
@@ -435,20 +500,30 @@ static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream)
435 struct snd_soc_dai *codec_dai = rtd->codec_dai; 500 struct snd_soc_dai *codec_dai = rtd->codec_dai;
436 int ret; 501 int ret;
437 502
438 if (codec_dai->driver->symmetric_rates || cpu_dai->driver->symmetric_rates || 503 if (!codec_dai->driver->symmetric_rates &&
439 rtd->dai_link->symmetric_rates) { 504 !cpu_dai->driver->symmetric_rates &&
440 dev_dbg(&rtd->dev, "Symmetry forces %dHz rate\n", 505 !rtd->dai_link->symmetric_rates)
441 rtd->rate); 506 return 0;
442 507
443 ret = snd_pcm_hw_constraint_minmax(substream->runtime, 508 /* This can happen if multiple streams are starting simultaneously -
444 SNDRV_PCM_HW_PARAM_RATE, 509 * the second can need to get its constraints before the first has
445 rtd->rate, 510 * picked a rate. Complain and allow the application to carry on.
446 rtd->rate); 511 */
447 if (ret < 0) { 512 if (!rtd->rate) {
448 dev_err(&rtd->dev, 513 dev_warn(&rtd->dev,
449 "Unable to apply rate symmetry constraint: %d\n", ret); 514 "Not enforcing symmetric_rates due to race\n");
450 return ret; 515 return 0;
451 } 516 }
517
518 dev_dbg(&rtd->dev, "Symmetry forces %dHz rate\n", rtd->rate);
519
520 ret = snd_pcm_hw_constraint_minmax(substream->runtime,
521 SNDRV_PCM_HW_PARAM_RATE,
522 rtd->rate, rtd->rate);
523 if (ret < 0) {
524 dev_err(&rtd->dev,
525 "Unable to apply rate symmetry constraint: %d\n", ret);
526 return ret;
452 } 527 }
453 528
454 return 0; 529 return 0;
@@ -962,12 +1037,11 @@ static struct snd_pcm_ops soc_pcm_ops = {
962 .pointer = soc_pcm_pointer, 1037 .pointer = soc_pcm_pointer,
963}; 1038};
964 1039
965#ifdef CONFIG_PM 1040#ifdef CONFIG_PM_SLEEP
966/* powers down audio subsystem for suspend */ 1041/* powers down audio subsystem for suspend */
967static int soc_suspend(struct device *dev) 1042int snd_soc_suspend(struct device *dev)
968{ 1043{
969 struct platform_device *pdev = to_platform_device(dev); 1044 struct snd_soc_card *card = dev_get_drvdata(dev);
970 struct snd_soc_card *card = platform_get_drvdata(pdev);
971 struct snd_soc_codec *codec; 1045 struct snd_soc_codec *codec;
972 int i; 1046 int i;
973 1047
@@ -1008,7 +1082,7 @@ static int soc_suspend(struct device *dev)
1008 } 1082 }
1009 1083
1010 if (card->suspend_pre) 1084 if (card->suspend_pre)
1011 card->suspend_pre(pdev, PMSG_SUSPEND); 1085 card->suspend_pre(card);
1012 1086
1013 for (i = 0; i < card->num_rtd; i++) { 1087 for (i = 0; i < card->num_rtd; i++) {
1014 struct snd_soc_dai *cpu_dai = card->rtd[i].cpu_dai; 1088 struct snd_soc_dai *cpu_dai = card->rtd[i].cpu_dai;
@@ -1075,10 +1149,11 @@ static int soc_suspend(struct device *dev)
1075 } 1149 }
1076 1150
1077 if (card->suspend_post) 1151 if (card->suspend_post)
1078 card->suspend_post(pdev, PMSG_SUSPEND); 1152 card->suspend_post(card);
1079 1153
1080 return 0; 1154 return 0;
1081} 1155}
1156EXPORT_SYMBOL_GPL(snd_soc_suspend);
1082 1157
1083/* deferred resume work, so resume can complete before we finished 1158/* deferred resume work, so resume can complete before we finished
1084 * setting our codec back up, which can be very slow on I2C 1159 * setting our codec back up, which can be very slow on I2C
@@ -1087,7 +1162,6 @@ static void soc_resume_deferred(struct work_struct *work)
1087{ 1162{
1088 struct snd_soc_card *card = 1163 struct snd_soc_card *card =
1089 container_of(work, struct snd_soc_card, deferred_resume_work); 1164 container_of(work, struct snd_soc_card, deferred_resume_work);
1090 struct platform_device *pdev = to_platform_device(card->dev);
1091 struct snd_soc_codec *codec; 1165 struct snd_soc_codec *codec;
1092 int i; 1166 int i;
1093 1167
@@ -1101,7 +1175,7 @@ static void soc_resume_deferred(struct work_struct *work)
1101 snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D2); 1175 snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D2);
1102 1176
1103 if (card->resume_pre) 1177 if (card->resume_pre)
1104 card->resume_pre(pdev); 1178 card->resume_pre(card);
1105 1179
1106 /* resume AC97 DAIs */ 1180 /* resume AC97 DAIs */
1107 for (i = 0; i < card->num_rtd; i++) { 1181 for (i = 0; i < card->num_rtd; i++) {
@@ -1176,7 +1250,7 @@ static void soc_resume_deferred(struct work_struct *work)
1176 } 1250 }
1177 1251
1178 if (card->resume_post) 1252 if (card->resume_post)
1179 card->resume_post(pdev); 1253 card->resume_post(card);
1180 1254
1181 dev_dbg(card->dev, "resume work completed\n"); 1255 dev_dbg(card->dev, "resume work completed\n");
1182 1256
@@ -1185,10 +1259,9 @@ static void soc_resume_deferred(struct work_struct *work)
1185} 1259}
1186 1260
1187/* powers up audio subsystem after a suspend */ 1261/* powers up audio subsystem after a suspend */
1188static int soc_resume(struct device *dev) 1262int snd_soc_resume(struct device *dev)
1189{ 1263{
1190 struct platform_device *pdev = to_platform_device(dev); 1264 struct snd_soc_card *card = dev_get_drvdata(dev);
1191 struct snd_soc_card *card = platform_get_drvdata(pdev);
1192 int i; 1265 int i;
1193 1266
1194 /* AC97 devices might have other drivers hanging off them so 1267 /* AC97 devices might have other drivers hanging off them so
@@ -1210,9 +1283,10 @@ static int soc_resume(struct device *dev)
1210 1283
1211 return 0; 1284 return 0;
1212} 1285}
1286EXPORT_SYMBOL_GPL(snd_soc_resume);
1213#else 1287#else
1214#define soc_suspend NULL 1288#define snd_soc_suspend NULL
1215#define soc_resume NULL 1289#define snd_soc_resume NULL
1216#endif 1290#endif
1217 1291
1218static struct snd_soc_dai_ops null_dai_ops = { 1292static struct snd_soc_dai_ops null_dai_ops = {
@@ -1400,31 +1474,44 @@ static int soc_probe_codec(struct snd_soc_card *card,
1400 struct snd_soc_codec *codec) 1474 struct snd_soc_codec *codec)
1401{ 1475{
1402 int ret = 0; 1476 int ret = 0;
1477 const struct snd_soc_codec_driver *driver = codec->driver;
1403 1478
1404 codec->card = card; 1479 codec->card = card;
1405 codec->dapm.card = card; 1480 codec->dapm.card = card;
1406 soc_set_name_prefix(card, codec); 1481 soc_set_name_prefix(card, codec);
1407 1482
1408 if (codec->driver->probe) { 1483 if (!try_module_get(codec->dev->driver->owner))
1409 ret = codec->driver->probe(codec); 1484 return -ENODEV;
1485
1486 if (driver->probe) {
1487 ret = driver->probe(codec);
1410 if (ret < 0) { 1488 if (ret < 0) {
1411 dev_err(codec->dev, 1489 dev_err(codec->dev,
1412 "asoc: failed to probe CODEC %s: %d\n", 1490 "asoc: failed to probe CODEC %s: %d\n",
1413 codec->name, ret); 1491 codec->name, ret);
1414 return ret; 1492 goto err_probe;
1415 } 1493 }
1416 } 1494 }
1417 1495
1496 if (driver->dapm_widgets)
1497 snd_soc_dapm_new_controls(&codec->dapm, driver->dapm_widgets,
1498 driver->num_dapm_widgets);
1499 if (driver->dapm_routes)
1500 snd_soc_dapm_add_routes(&codec->dapm, driver->dapm_routes,
1501 driver->num_dapm_routes);
1502
1418 soc_init_codec_debugfs(codec); 1503 soc_init_codec_debugfs(codec);
1419 1504
1420 /* mark codec as probed and add to card codec list */ 1505 /* mark codec as probed and add to card codec list */
1421 if (!try_module_get(codec->dev->driver->owner))
1422 return -ENODEV;
1423
1424 codec->probed = 1; 1506 codec->probed = 1;
1425 list_add(&codec->card_list, &card->codec_dev_list); 1507 list_add(&codec->card_list, &card->codec_dev_list);
1426 list_add(&codec->dapm.list, &card->dapm_list); 1508 list_add(&codec->dapm.list, &card->dapm_list);
1427 1509
1510 return 0;
1511
1512err_probe:
1513 module_put(codec->dev->driver->owner);
1514
1428 return ret; 1515 return ret;
1429} 1516}
1430 1517
@@ -1468,7 +1555,6 @@ static int soc_post_component_init(struct snd_soc_card *card,
1468 1555
1469 /* Make sure all DAPM widgets are instantiated */ 1556 /* Make sure all DAPM widgets are instantiated */
1470 snd_soc_dapm_new_widgets(&codec->dapm); 1557 snd_soc_dapm_new_widgets(&codec->dapm);
1471 snd_soc_dapm_sync(&codec->dapm);
1472 1558
1473 /* register the rtd device */ 1559 /* register the rtd device */
1474 rtd->codec = codec; 1560 rtd->codec = codec;
@@ -1543,19 +1629,19 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num)
1543 1629
1544 /* probe the platform */ 1630 /* probe the platform */
1545 if (!platform->probed) { 1631 if (!platform->probed) {
1632 if (!try_module_get(platform->dev->driver->owner))
1633 return -ENODEV;
1634
1546 if (platform->driver->probe) { 1635 if (platform->driver->probe) {
1547 ret = platform->driver->probe(platform); 1636 ret = platform->driver->probe(platform);
1548 if (ret < 0) { 1637 if (ret < 0) {
1549 printk(KERN_ERR "asoc: failed to probe platform %s\n", 1638 printk(KERN_ERR "asoc: failed to probe platform %s\n",
1550 platform->name); 1639 platform->name);
1640 module_put(platform->dev->driver->owner);
1551 return ret; 1641 return ret;
1552 } 1642 }
1553 } 1643 }
1554 /* mark platform as probed and add to card platform list */ 1644 /* mark platform as probed and add to card platform list */
1555
1556 if (!try_module_get(platform->dev->driver->owner))
1557 return -ENODEV;
1558
1559 platform->probed = 1; 1645 platform->probed = 1;
1560 list_add(&platform->card_list, &card->platform_dev_list); 1646 list_add(&platform->card_list, &card->platform_dev_list);
1561 } 1647 }
@@ -1713,7 +1799,6 @@ static int snd_soc_init_codec_cache(struct snd_soc_codec *codec,
1713 1799
1714static void snd_soc_instantiate_card(struct snd_soc_card *card) 1800static void snd_soc_instantiate_card(struct snd_soc_card *card)
1715{ 1801{
1716 struct platform_device *pdev = to_platform_device(card->dev);
1717 struct snd_soc_codec *codec; 1802 struct snd_soc_codec *codec;
1718 struct snd_soc_codec_conf *codec_conf; 1803 struct snd_soc_codec_conf *codec_conf;
1719 enum snd_soc_compress_type compress_type; 1804 enum snd_soc_compress_type compress_type;
@@ -1740,6 +1825,8 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1740 list_for_each_entry(codec, &codec_list, list) { 1825 list_for_each_entry(codec, &codec_list, list) {
1741 if (codec->cache_init) 1826 if (codec->cache_init)
1742 continue; 1827 continue;
1828 /* by default we don't override the compress_type */
1829 compress_type = 0;
1743 /* check to see if we need to override the compress_type */ 1830 /* check to see if we need to override the compress_type */
1744 for (i = 0; i < card->num_configs; ++i) { 1831 for (i = 0; i < card->num_configs; ++i) {
1745 codec_conf = &card->codec_conf[i]; 1832 codec_conf = &card->codec_conf[i];
@@ -1750,18 +1837,6 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1750 break; 1837 break;
1751 } 1838 }
1752 } 1839 }
1753 if (i == card->num_configs) {
1754 /* no need to override the compress_type so
1755 * go ahead and do the standard thing */
1756 ret = snd_soc_init_codec_cache(codec, 0);
1757 if (ret < 0) {
1758 mutex_unlock(&card->mutex);
1759 return;
1760 }
1761 continue;
1762 }
1763 /* override the compress_type with the one supplied in
1764 * the machine driver */
1765 ret = snd_soc_init_codec_cache(codec, compress_type); 1840 ret = snd_soc_init_codec_cache(codec, compress_type);
1766 if (ret < 0) { 1841 if (ret < 0) {
1767 mutex_unlock(&card->mutex); 1842 mutex_unlock(&card->mutex);
@@ -1780,14 +1855,19 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1780 } 1855 }
1781 card->snd_card->dev = card->dev; 1856 card->snd_card->dev = card->dev;
1782 1857
1783#ifdef CONFIG_PM 1858 card->dapm.bias_level = SND_SOC_BIAS_OFF;
1859 card->dapm.dev = card->dev;
1860 card->dapm.card = card;
1861 list_add(&card->dapm.list, &card->dapm_list);
1862
1863#ifdef CONFIG_PM_SLEEP
1784 /* deferred resume work */ 1864 /* deferred resume work */
1785 INIT_WORK(&card->deferred_resume_work, soc_resume_deferred); 1865 INIT_WORK(&card->deferred_resume_work, soc_resume_deferred);
1786#endif 1866#endif
1787 1867
1788 /* initialise the sound card only once */ 1868 /* initialise the sound card only once */
1789 if (card->probe) { 1869 if (card->probe) {
1790 ret = card->probe(pdev); 1870 ret = card->probe(card);
1791 if (ret < 0) 1871 if (ret < 0)
1792 goto card_probe_error; 1872 goto card_probe_error;
1793 } 1873 }
@@ -1810,11 +1890,37 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1810 } 1890 }
1811 } 1891 }
1812 1892
1893 if (card->dapm_widgets)
1894 snd_soc_dapm_new_controls(&card->dapm, card->dapm_widgets,
1895 card->num_dapm_widgets);
1896 if (card->dapm_routes)
1897 snd_soc_dapm_add_routes(&card->dapm, card->dapm_routes,
1898 card->num_dapm_routes);
1899
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
1813 snprintf(card->snd_card->shortname, sizeof(card->snd_card->shortname), 1910 snprintf(card->snd_card->shortname, sizeof(card->snd_card->shortname),
1814 "%s", card->name); 1911 "%s", card->name);
1815 snprintf(card->snd_card->longname, sizeof(card->snd_card->longname), 1912 snprintf(card->snd_card->longname, sizeof(card->snd_card->longname),
1816 "%s", card->name); 1913 "%s", card->name);
1817 1914
1915 if (card->late_probe) {
1916 ret = card->late_probe(card);
1917 if (ret < 0) {
1918 dev_err(card->dev, "%s late_probe() failed: %d\n",
1919 card->name, ret);
1920 goto probe_aux_dev_err;
1921 }
1922 }
1923
1818 ret = snd_card_register(card->snd_card); 1924 ret = snd_card_register(card->snd_card);
1819 if (ret < 0) { 1925 if (ret < 0) {
1820 printk(KERN_ERR "asoc: failed to register soundcard for %s\n", card->name); 1926 printk(KERN_ERR "asoc: failed to register soundcard for %s\n", card->name);
@@ -1848,7 +1954,7 @@ probe_dai_err:
1848 1954
1849card_probe_error: 1955card_probe_error:
1850 if (card->remove) 1956 if (card->remove)
1851 card->remove(pdev); 1957 card->remove(card);
1852 1958
1853 snd_card_free(card->snd_card); 1959 snd_card_free(card->snd_card);
1854 1960
@@ -1872,16 +1978,15 @@ static int soc_probe(struct platform_device *pdev)
1872 struct snd_soc_card *card = platform_get_drvdata(pdev); 1978 struct snd_soc_card *card = platform_get_drvdata(pdev);
1873 int ret = 0; 1979 int ret = 0;
1874 1980
1981 /*
1982 * no card, so machine driver should be registering card
1983 * we should not be here in that case so ret error
1984 */
1985 if (!card)
1986 return -EINVAL;
1987
1875 /* Bodge while we unpick instantiation */ 1988 /* Bodge while we unpick instantiation */
1876 card->dev = &pdev->dev; 1989 card->dev = &pdev->dev;
1877 INIT_LIST_HEAD(&card->dai_dev_list);
1878 INIT_LIST_HEAD(&card->codec_dev_list);
1879 INIT_LIST_HEAD(&card->platform_dev_list);
1880 INIT_LIST_HEAD(&card->widgets);
1881 INIT_LIST_HEAD(&card->paths);
1882 INIT_LIST_HEAD(&card->dapm_list);
1883
1884 soc_init_card_debugfs(card);
1885 1990
1886 ret = snd_soc_register_card(card); 1991 ret = snd_soc_register_card(card);
1887 if (ret != 0) { 1992 if (ret != 0) {
@@ -1892,45 +1997,48 @@ static int soc_probe(struct platform_device *pdev)
1892 return 0; 1997 return 0;
1893} 1998}
1894 1999
1895/* removes a socdev */ 2000static int soc_cleanup_card_resources(struct snd_soc_card *card)
1896static int soc_remove(struct platform_device *pdev)
1897{ 2001{
1898 struct snd_soc_card *card = platform_get_drvdata(pdev);
1899 int i; 2002 int i;
1900 2003
1901 if (card->instantiated) { 2004 /* make sure any delayed work runs */
2005 for (i = 0; i < card->num_rtd; i++) {
2006 struct snd_soc_pcm_runtime *rtd = &card->rtd[i];
2007 flush_delayed_work_sync(&rtd->delayed_work);
2008 }
1902 2009
1903 /* make sure any delayed work runs */ 2010 /* remove auxiliary devices */
1904 for (i = 0; i < card->num_rtd; i++) { 2011 for (i = 0; i < card->num_aux_devs; i++)
1905 struct snd_soc_pcm_runtime *rtd = &card->rtd[i]; 2012 soc_remove_aux_dev(card, i);
1906 flush_delayed_work_sync(&rtd->delayed_work);
1907 }
1908 2013
1909 /* remove auxiliary devices */ 2014 /* remove and free each DAI */
1910 for (i = 0; i < card->num_aux_devs; i++) 2015 for (i = 0; i < card->num_rtd; i++)
1911 soc_remove_aux_dev(card, i); 2016 soc_remove_dai_link(card, i);
1912 2017
1913 /* remove and free each DAI */ 2018 soc_cleanup_card_debugfs(card);
1914 for (i = 0; i < card->num_rtd; i++)
1915 soc_remove_dai_link(card, i);
1916 2019
1917 soc_cleanup_card_debugfs(card); 2020 /* remove the card */
2021 if (card->remove)
2022 card->remove(card);
2023
2024 kfree(card->rtd);
2025 snd_card_free(card->snd_card);
2026 return 0;
1918 2027
1919 /* remove the card */ 2028}
1920 if (card->remove) 2029
1921 card->remove(pdev); 2030/* removes a socdev */
2031static int soc_remove(struct platform_device *pdev)
2032{
2033 struct snd_soc_card *card = platform_get_drvdata(pdev);
1922 2034
1923 kfree(card->rtd);
1924 snd_card_free(card->snd_card);
1925 }
1926 snd_soc_unregister_card(card); 2035 snd_soc_unregister_card(card);
1927 return 0; 2036 return 0;
1928} 2037}
1929 2038
1930static int soc_poweroff(struct device *dev) 2039int snd_soc_poweroff(struct device *dev)
1931{ 2040{
1932 struct platform_device *pdev = to_platform_device(dev); 2041 struct snd_soc_card *card = dev_get_drvdata(dev);
1933 struct snd_soc_card *card = platform_get_drvdata(pdev);
1934 int i; 2042 int i;
1935 2043
1936 if (!card->instantiated) 2044 if (!card->instantiated)
@@ -1947,11 +2055,12 @@ static int soc_poweroff(struct device *dev)
1947 2055
1948 return 0; 2056 return 0;
1949} 2057}
2058EXPORT_SYMBOL_GPL(snd_soc_poweroff);
1950 2059
1951static const struct dev_pm_ops soc_pm_ops = { 2060const struct dev_pm_ops snd_soc_pm_ops = {
1952 .suspend = soc_suspend, 2061 .suspend = snd_soc_suspend,
1953 .resume = soc_resume, 2062 .resume = snd_soc_resume,
1954 .poweroff = soc_poweroff, 2063 .poweroff = snd_soc_poweroff,
1955}; 2064};
1956 2065
1957/* ASoC platform driver */ 2066/* ASoC platform driver */
@@ -1959,7 +2068,7 @@ static struct platform_driver soc_driver = {
1959 .driver = { 2068 .driver = {
1960 .name = "soc-audio", 2069 .name = "soc-audio",
1961 .owner = THIS_MODULE, 2070 .owner = THIS_MODULE,
1962 .pm = &soc_pm_ops, 2071 .pm = &snd_soc_pm_ops,
1963 }, 2072 },
1964 .probe = soc_probe, 2073 .probe = soc_probe,
1965 .remove = soc_remove, 2074 .remove = soc_remove,
@@ -2029,10 +2138,11 @@ static int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
2029 * 2138 *
2030 * Boolean function indiciating if a CODEC register is volatile. 2139 * Boolean function indiciating if a CODEC register is volatile.
2031 */ 2140 */
2032int snd_soc_codec_volatile_register(struct snd_soc_codec *codec, int reg) 2141int snd_soc_codec_volatile_register(struct snd_soc_codec *codec,
2142 unsigned int reg)
2033{ 2143{
2034 if (codec->driver->volatile_register) 2144 if (codec->volatile_register)
2035 return codec->driver->volatile_register(reg); 2145 return codec->volatile_register(codec, reg);
2036 else 2146 else
2037 return 0; 2147 return 0;
2038} 2148}
@@ -2129,19 +2239,27 @@ EXPORT_SYMBOL_GPL(snd_soc_write);
2129 * 2239 *
2130 * Writes new register value. 2240 * Writes new register value.
2131 * 2241 *
2132 * Returns 1 for change else 0. 2242 * Returns 1 for change, 0 for no change, or negative error code.
2133 */ 2243 */
2134int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg, 2244int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg,
2135 unsigned int mask, unsigned int value) 2245 unsigned int mask, unsigned int value)
2136{ 2246{
2137 int change; 2247 int change;
2138 unsigned int old, new; 2248 unsigned int old, new;
2249 int ret;
2139 2250
2140 old = snd_soc_read(codec, reg); 2251 ret = snd_soc_read(codec, reg);
2252 if (ret < 0)
2253 return ret;
2254
2255 old = ret;
2141 new = (old & ~mask) | value; 2256 new = (old & ~mask) | value;
2142 change = old != new; 2257 change = old != new;
2143 if (change) 2258 if (change) {
2144 snd_soc_write(codec, reg, new); 2259 ret = snd_soc_write(codec, reg, new);
2260 if (ret < 0)
2261 return ret;
2262 }
2145 2263
2146 return change; 2264 return change;
2147} 2265}
@@ -2226,22 +2344,45 @@ EXPORT_SYMBOL_GPL(snd_soc_set_runtime_hwparams);
2226 * @_template: control template 2344 * @_template: control template
2227 * @data: control private data 2345 * @data: control private data
2228 * @long_name: control long name 2346 * @long_name: control long name
2347 * @prefix: control name prefix
2229 * 2348 *
2230 * Create a new mixer control from a template control. 2349 * Create a new mixer control from a template control.
2231 * 2350 *
2232 * Returns 0 for success, else error. 2351 * Returns 0 for success, else error.
2233 */ 2352 */
2234struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template, 2353struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template,
2235 void *data, char *long_name) 2354 void *data, char *long_name,
2355 const char *prefix)
2236{ 2356{
2237 struct snd_kcontrol_new template; 2357 struct snd_kcontrol_new template;
2358 struct snd_kcontrol *kcontrol;
2359 char *name = NULL;
2360 int name_len;
2238 2361
2239 memcpy(&template, _template, sizeof(template)); 2362 memcpy(&template, _template, sizeof(template));
2240 if (long_name)
2241 template.name = long_name;
2242 template.index = 0; 2363 template.index = 0;
2243 2364
2244 return snd_ctl_new1(&template, data); 2365 if (!long_name)
2366 long_name = template.name;
2367
2368 if (prefix) {
2369 name_len = strlen(long_name) + strlen(prefix) + 2;
2370 name = kmalloc(name_len, GFP_ATOMIC);
2371 if (!name)
2372 return NULL;
2373
2374 snprintf(name, name_len, "%s %s", prefix, long_name);
2375
2376 template.name = name;
2377 } else {
2378 template.name = long_name;
2379 }
2380
2381 kcontrol = snd_ctl_new1(&template, data);
2382
2383 kfree(name);
2384
2385 return kcontrol;
2245} 2386}
2246EXPORT_SYMBOL_GPL(snd_soc_cnew); 2387EXPORT_SYMBOL_GPL(snd_soc_cnew);
2247 2388
@@ -2260,22 +2401,16 @@ int snd_soc_add_controls(struct snd_soc_codec *codec,
2260 const struct snd_kcontrol_new *controls, int num_controls) 2401 const struct snd_kcontrol_new *controls, int num_controls)
2261{ 2402{
2262 struct snd_card *card = codec->card->snd_card; 2403 struct snd_card *card = codec->card->snd_card;
2263 char prefixed_name[44], *name;
2264 int err, i; 2404 int err, i;
2265 2405
2266 for (i = 0; i < num_controls; i++) { 2406 for (i = 0; i < num_controls; i++) {
2267 const struct snd_kcontrol_new *control = &controls[i]; 2407 const struct snd_kcontrol_new *control = &controls[i];
2268 if (codec->name_prefix) { 2408 err = snd_ctl_add(card, snd_soc_cnew(control, codec,
2269 snprintf(prefixed_name, sizeof(prefixed_name), "%s %s", 2409 control->name,
2270 codec->name_prefix, control->name); 2410 codec->name_prefix));
2271 name = prefixed_name;
2272 } else {
2273 name = control->name;
2274 }
2275 err = snd_ctl_add(card, snd_soc_cnew(control, codec, name));
2276 if (err < 0) { 2411 if (err < 0) {
2277 dev_err(codec->dev, "%s: Failed to add %s: %d\n", 2412 dev_err(codec->dev, "%s: Failed to add %s: %d\n",
2278 codec->name, name, err); 2413 codec->name, control->name, err);
2279 return err; 2414 return err;
2280 } 2415 }
2281 } 2416 }
@@ -2956,12 +3091,34 @@ int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
2956{ 3091{
2957 if (dai->driver && dai->driver->ops->set_sysclk) 3092 if (dai->driver && dai->driver->ops->set_sysclk)
2958 return dai->driver->ops->set_sysclk(dai, clk_id, freq, dir); 3093 return dai->driver->ops->set_sysclk(dai, clk_id, freq, dir);
3094 else if (dai->codec && dai->codec->driver->set_sysclk)
3095 return dai->codec->driver->set_sysclk(dai->codec, clk_id,
3096 freq, dir);
2959 else 3097 else
2960 return -EINVAL; 3098 return -EINVAL;
2961} 3099}
2962EXPORT_SYMBOL_GPL(snd_soc_dai_set_sysclk); 3100EXPORT_SYMBOL_GPL(snd_soc_dai_set_sysclk);
2963 3101
2964/** 3102/**
3103 * snd_soc_codec_set_sysclk - configure CODEC system or master clock.
3104 * @codec: CODEC
3105 * @clk_id: DAI specific clock ID
3106 * @freq: new clock frequency in Hz
3107 * @dir: new clock direction - input/output.
3108 *
3109 * Configures the CODEC master (MCLK) or system (SYSCLK) clocking.
3110 */
3111int snd_soc_codec_set_sysclk(struct snd_soc_codec *codec, int clk_id,
3112 unsigned int freq, int dir)
3113{
3114 if (codec->driver->set_sysclk)
3115 return codec->driver->set_sysclk(codec, clk_id, freq, dir);
3116 else
3117 return -EINVAL;
3118}
3119EXPORT_SYMBOL_GPL(snd_soc_codec_set_sysclk);
3120
3121/**
2965 * snd_soc_dai_set_clkdiv - configure DAI clock dividers. 3122 * snd_soc_dai_set_clkdiv - configure DAI clock dividers.
2966 * @dai: DAI 3123 * @dai: DAI
2967 * @div_id: DAI specific clock divider ID 3124 * @div_id: DAI specific clock divider ID
@@ -2997,11 +3154,35 @@ int snd_soc_dai_set_pll(struct snd_soc_dai *dai, int pll_id, int source,
2997 if (dai->driver && dai->driver->ops->set_pll) 3154 if (dai->driver && dai->driver->ops->set_pll)
2998 return dai->driver->ops->set_pll(dai, pll_id, source, 3155 return dai->driver->ops->set_pll(dai, pll_id, source,
2999 freq_in, freq_out); 3156 freq_in, freq_out);
3157 else if (dai->codec && dai->codec->driver->set_pll)
3158 return dai->codec->driver->set_pll(dai->codec, pll_id, source,
3159 freq_in, freq_out);
3000 else 3160 else
3001 return -EINVAL; 3161 return -EINVAL;
3002} 3162}
3003EXPORT_SYMBOL_GPL(snd_soc_dai_set_pll); 3163EXPORT_SYMBOL_GPL(snd_soc_dai_set_pll);
3004 3164
3165/*
3166 * snd_soc_codec_set_pll - configure codec PLL.
3167 * @codec: CODEC
3168 * @pll_id: DAI specific PLL ID
3169 * @source: DAI specific source for the PLL
3170 * @freq_in: PLL input clock frequency in Hz
3171 * @freq_out: requested PLL output clock frequency in Hz
3172 *
3173 * Configures and enables PLL to generate output clock based on input clock.
3174 */
3175int snd_soc_codec_set_pll(struct snd_soc_codec *codec, int pll_id, int source,
3176 unsigned int freq_in, unsigned int freq_out)
3177{
3178 if (codec->driver->set_pll)
3179 return codec->driver->set_pll(codec, pll_id, source,
3180 freq_in, freq_out);
3181 else
3182 return -EINVAL;
3183}
3184EXPORT_SYMBOL_GPL(snd_soc_codec_set_pll);
3185
3005/** 3186/**
3006 * snd_soc_dai_set_fmt - configure DAI hardware audio format. 3187 * snd_soc_dai_set_fmt - configure DAI hardware audio format.
3007 * @dai: DAI 3188 * @dai: DAI
@@ -3101,17 +3282,18 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_digital_mute);
3101 * 3282 *
3102 * @card: Card to register 3283 * @card: Card to register
3103 * 3284 *
3104 * Note that currently this is an internal only function: it will be
3105 * exposed to machine drivers after further backporting of ASoC v2
3106 * registration APIs.
3107 */ 3285 */
3108static int snd_soc_register_card(struct snd_soc_card *card) 3286int snd_soc_register_card(struct snd_soc_card *card)
3109{ 3287{
3110 int i; 3288 int i;
3111 3289
3112 if (!card->name || !card->dev) 3290 if (!card->name || !card->dev)
3113 return -EINVAL; 3291 return -EINVAL;
3114 3292
3293 snd_soc_initialize_card_lists(card);
3294
3295 soc_init_card_debugfs(card);
3296
3115 card->rtd = kzalloc(sizeof(struct snd_soc_pcm_runtime) * 3297 card->rtd = kzalloc(sizeof(struct snd_soc_pcm_runtime) *
3116 (card->num_links + card->num_aux_devs), 3298 (card->num_links + card->num_aux_devs),
3117 GFP_KERNEL); 3299 GFP_KERNEL);
@@ -3135,18 +3317,18 @@ static int snd_soc_register_card(struct snd_soc_card *card)
3135 3317
3136 return 0; 3318 return 0;
3137} 3319}
3320EXPORT_SYMBOL_GPL(snd_soc_register_card);
3138 3321
3139/** 3322/**
3140 * snd_soc_unregister_card - Unregister a card with the ASoC core 3323 * snd_soc_unregister_card - Unregister a card with the ASoC core
3141 * 3324 *
3142 * @card: Card to unregister 3325 * @card: Card to unregister
3143 * 3326 *
3144 * Note that currently this is an internal only function: it will be
3145 * exposed to machine drivers after further backporting of ASoC v2
3146 * registration APIs.
3147 */ 3327 */
3148static int snd_soc_unregister_card(struct snd_soc_card *card) 3328int snd_soc_unregister_card(struct snd_soc_card *card)
3149{ 3329{
3330 if (card->instantiated)
3331 soc_cleanup_card_resources(card);
3150 mutex_lock(&client_mutex); 3332 mutex_lock(&client_mutex);
3151 list_del(&card->list); 3333 list_del(&card->list);
3152 mutex_unlock(&client_mutex); 3334 mutex_unlock(&client_mutex);
@@ -3154,6 +3336,7 @@ static int snd_soc_unregister_card(struct snd_soc_card *card)
3154 3336
3155 return 0; 3337 return 0;
3156} 3338}
3339EXPORT_SYMBOL_GPL(snd_soc_unregister_card);
3157 3340
3158/* 3341/*
3159 * Simplify DAI link configuration by removing ".-1" from device names 3342 * Simplify DAI link configuration by removing ".-1" from device names
@@ -3483,9 +3666,12 @@ int snd_soc_register_codec(struct device *dev,
3483 3666
3484 codec->write = codec_drv->write; 3667 codec->write = codec_drv->write;
3485 codec->read = codec_drv->read; 3668 codec->read = codec_drv->read;
3669 codec->volatile_register = codec_drv->volatile_register;
3670 codec->readable_register = codec_drv->readable_register;
3486 codec->dapm.bias_level = SND_SOC_BIAS_OFF; 3671 codec->dapm.bias_level = SND_SOC_BIAS_OFF;
3487 codec->dapm.dev = dev; 3672 codec->dapm.dev = dev;
3488 codec->dapm.codec = codec; 3673 codec->dapm.codec = codec;
3674 codec->dapm.seq_notifier = codec_drv->seq_notifier;
3489 codec->dev = dev; 3675 codec->dev = dev;
3490 codec->driver = codec_drv; 3676 codec->driver = codec_drv;
3491 codec->num_dai = num_dai; 3677 codec->num_dai = num_dai;
@@ -3494,20 +3680,30 @@ int snd_soc_register_codec(struct device *dev,
3494 /* allocate CODEC register cache */ 3680 /* allocate CODEC register cache */
3495 if (codec_drv->reg_cache_size && codec_drv->reg_word_size) { 3681 if (codec_drv->reg_cache_size && codec_drv->reg_word_size) {
3496 reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size; 3682 reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size;
3683 codec->reg_size = reg_size;
3497 /* it is necessary to make a copy of the default register cache 3684 /* it is necessary to make a copy of the default register cache
3498 * because in the case of using a compression type that requires 3685 * because in the case of using a compression type that requires
3499 * the default register cache to be marked as __devinitconst the 3686 * the default register cache to be marked as __devinitconst the
3500 * kernel might have freed the array by the time we initialize 3687 * kernel might have freed the array by the time we initialize
3501 * the cache. 3688 * the cache.
3502 */ 3689 */
3503 codec->reg_def_copy = kmemdup(codec_drv->reg_cache_default, 3690 if (codec_drv->reg_cache_default) {
3504 reg_size, GFP_KERNEL); 3691 codec->reg_def_copy = kmemdup(codec_drv->reg_cache_default,
3505 if (!codec->reg_def_copy) { 3692 reg_size, GFP_KERNEL);
3506 ret = -ENOMEM; 3693 if (!codec->reg_def_copy) {
3507 goto fail; 3694 ret = -ENOMEM;
3695 goto fail;
3696 }
3508 } 3697 }
3509 } 3698 }
3510 3699
3700 if (codec_drv->reg_access_size && codec_drv->reg_access_default) {
3701 if (!codec->volatile_register)
3702 codec->volatile_register = snd_soc_default_volatile_register;
3703 if (!codec->readable_register)
3704 codec->readable_register = snd_soc_default_readable_register;
3705 }
3706
3511 for (i = 0; i < num_dai; i++) { 3707 for (i = 0; i < num_dai; i++) {
3512 fixup_codec_formats(&dai_drv[i].playback); 3708 fixup_codec_formats(&dai_drv[i].playback);
3513 fixup_codec_formats(&dai_drv[i].capture); 3709 fixup_codec_formats(&dai_drv[i].capture);
@@ -3574,22 +3770,22 @@ EXPORT_SYMBOL_GPL(snd_soc_unregister_codec);
3574static int __init snd_soc_init(void) 3770static int __init snd_soc_init(void)
3575{ 3771{
3576#ifdef CONFIG_DEBUG_FS 3772#ifdef CONFIG_DEBUG_FS
3577 debugfs_root = debugfs_create_dir("asoc", NULL); 3773 snd_soc_debugfs_root = debugfs_create_dir("asoc", NULL);
3578 if (IS_ERR(debugfs_root) || !debugfs_root) { 3774 if (IS_ERR(snd_soc_debugfs_root) || !snd_soc_debugfs_root) {
3579 printk(KERN_WARNING 3775 printk(KERN_WARNING
3580 "ASoC: Failed to create debugfs directory\n"); 3776 "ASoC: Failed to create debugfs directory\n");
3581 debugfs_root = NULL; 3777 snd_soc_debugfs_root = NULL;
3582 } 3778 }
3583 3779
3584 if (!debugfs_create_file("codecs", 0444, debugfs_root, NULL, 3780 if (!debugfs_create_file("codecs", 0444, snd_soc_debugfs_root, NULL,
3585 &codec_list_fops)) 3781 &codec_list_fops))
3586 pr_warn("ASoC: Failed to create CODEC list debugfs file\n"); 3782 pr_warn("ASoC: Failed to create CODEC list debugfs file\n");
3587 3783
3588 if (!debugfs_create_file("dais", 0444, debugfs_root, NULL, 3784 if (!debugfs_create_file("dais", 0444, snd_soc_debugfs_root, NULL,
3589 &dai_list_fops)) 3785 &dai_list_fops))
3590 pr_warn("ASoC: Failed to create DAI list debugfs file\n"); 3786 pr_warn("ASoC: Failed to create DAI list debugfs file\n");
3591 3787
3592 if (!debugfs_create_file("platforms", 0444, debugfs_root, NULL, 3788 if (!debugfs_create_file("platforms", 0444, snd_soc_debugfs_root, NULL,
3593 &platform_list_fops)) 3789 &platform_list_fops))
3594 pr_warn("ASoC: Failed to create platform list debugfs file\n"); 3790 pr_warn("ASoC: Failed to create platform list debugfs file\n");
3595#endif 3791#endif
@@ -3601,7 +3797,7 @@ module_init(snd_soc_init);
3601static void __exit snd_soc_exit(void) 3797static void __exit snd_soc_exit(void)
3602{ 3798{
3603#ifdef CONFIG_DEBUG_FS 3799#ifdef CONFIG_DEBUG_FS
3604 debugfs_remove_recursive(debugfs_root); 3800 debugfs_remove_recursive(snd_soc_debugfs_root);
3605#endif 3801#endif
3606 platform_driver_unregister(&soc_driver); 3802 platform_driver_unregister(&soc_driver);
3607} 3803}
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 1790f83ee665..81c4052c127c 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -32,6 +32,7 @@
32#include <linux/module.h> 32#include <linux/module.h>
33#include <linux/moduleparam.h> 33#include <linux/moduleparam.h>
34#include <linux/init.h> 34#include <linux/init.h>
35#include <linux/async.h>
35#include <linux/delay.h> 36#include <linux/delay.h>
36#include <linux/pm.h> 37#include <linux/pm.h>
37#include <linux/bitops.h> 38#include <linux/bitops.h>
@@ -125,17 +126,17 @@ static inline struct snd_soc_dapm_widget *dapm_cnew_widget(
125 126
126/** 127/**
127 * snd_soc_dapm_set_bias_level - set the bias level for the system 128 * snd_soc_dapm_set_bias_level - set the bias level for the system
128 * @card: audio device 129 * @dapm: DAPM context
129 * @level: level to configure 130 * @level: level to configure
130 * 131 *
131 * Configure the bias (power) levels for the SoC audio device. 132 * Configure the bias (power) levels for the SoC audio device.
132 * 133 *
133 * Returns 0 for success else error. 134 * Returns 0 for success else error.
134 */ 135 */
135static int snd_soc_dapm_set_bias_level(struct snd_soc_card *card, 136static int snd_soc_dapm_set_bias_level(struct snd_soc_dapm_context *dapm,
136 struct snd_soc_dapm_context *dapm,
137 enum snd_soc_bias_level level) 137 enum snd_soc_bias_level level)
138{ 138{
139 struct snd_soc_card *card = dapm->card;
139 int ret = 0; 140 int ret = 0;
140 141
141 switch (level) { 142 switch (level) {
@@ -365,9 +366,20 @@ static int dapm_new_mixer(struct snd_soc_dapm_context *dapm,
365 struct snd_soc_dapm_widget *w) 366 struct snd_soc_dapm_widget *w)
366{ 367{
367 int i, ret = 0; 368 int i, ret = 0;
368 size_t name_len; 369 size_t name_len, prefix_len;
369 struct snd_soc_dapm_path *path; 370 struct snd_soc_dapm_path *path;
370 struct snd_card *card = dapm->codec->card->snd_card; 371 struct snd_card *card = dapm->card->snd_card;
372 const char *prefix;
373
374 if (dapm->codec)
375 prefix = dapm->codec->name_prefix;
376 else
377 prefix = NULL;
378
379 if (prefix)
380 prefix_len = strlen(prefix) + 1;
381 else
382 prefix_len = 0;
371 383
372 /* add kcontrol */ 384 /* add kcontrol */
373 for (i = 0; i < w->num_kcontrols; i++) { 385 for (i = 0; i < w->num_kcontrols; i++) {
@@ -396,8 +408,15 @@ static int dapm_new_mixer(struct snd_soc_dapm_context *dapm,
396 408
397 switch (w->id) { 409 switch (w->id) {
398 default: 410 default:
411 /* The control will get a prefix from
412 * the control creation process but
413 * we're also using the same prefix
414 * for widgets so cut the prefix off
415 * the front of the widget name.
416 */
399 snprintf(path->long_name, name_len, "%s %s", 417 snprintf(path->long_name, name_len, "%s %s",
400 w->name, w->kcontrols[i].name); 418 w->name + prefix_len,
419 w->kcontrols[i].name);
401 break; 420 break;
402 case snd_soc_dapm_mixer_named_ctl: 421 case snd_soc_dapm_mixer_named_ctl:
403 snprintf(path->long_name, name_len, "%s", 422 snprintf(path->long_name, name_len, "%s",
@@ -408,7 +427,7 @@ static int dapm_new_mixer(struct snd_soc_dapm_context *dapm,
408 path->long_name[name_len - 1] = '\0'; 427 path->long_name[name_len - 1] = '\0';
409 428
410 path->kcontrol = snd_soc_cnew(&w->kcontrols[i], w, 429 path->kcontrol = snd_soc_cnew(&w->kcontrols[i], w,
411 path->long_name); 430 path->long_name, prefix);
412 ret = snd_ctl_add(card, path->kcontrol); 431 ret = snd_ctl_add(card, path->kcontrol);
413 if (ret < 0) { 432 if (ret < 0) {
414 dev_err(dapm->dev, 433 dev_err(dapm->dev,
@@ -429,7 +448,9 @@ static int dapm_new_mux(struct snd_soc_dapm_context *dapm,
429{ 448{
430 struct snd_soc_dapm_path *path = NULL; 449 struct snd_soc_dapm_path *path = NULL;
431 struct snd_kcontrol *kcontrol; 450 struct snd_kcontrol *kcontrol;
432 struct snd_card *card = dapm->codec->card->snd_card; 451 struct snd_card *card = dapm->card->snd_card;
452 const char *prefix;
453 size_t prefix_len;
433 int ret = 0; 454 int ret = 0;
434 455
435 if (!w->num_kcontrols) { 456 if (!w->num_kcontrols) {
@@ -437,7 +458,22 @@ static int dapm_new_mux(struct snd_soc_dapm_context *dapm,
437 return -EINVAL; 458 return -EINVAL;
438 } 459 }
439 460
440 kcontrol = snd_soc_cnew(&w->kcontrols[0], w, w->name); 461 if (dapm->codec)
462 prefix = dapm->codec->name_prefix;
463 else
464 prefix = NULL;
465
466 if (prefix)
467 prefix_len = strlen(prefix) + 1;
468 else
469 prefix_len = 0;
470
471 /* The control will get a prefix from the control creation
472 * process but we're also using the same prefix for widgets so
473 * cut the prefix off the front of the widget name.
474 */
475 kcontrol = snd_soc_cnew(&w->kcontrols[0], w, w->name + prefix_len,
476 prefix);
441 ret = snd_ctl_add(card, kcontrol); 477 ret = snd_ctl_add(card, kcontrol);
442 478
443 if (ret < 0) 479 if (ret < 0)
@@ -479,7 +515,7 @@ static inline void dapm_clear_walk(struct snd_soc_dapm_context *dapm)
479 */ 515 */
480static int snd_soc_dapm_suspend_check(struct snd_soc_dapm_widget *widget) 516static int snd_soc_dapm_suspend_check(struct snd_soc_dapm_widget *widget)
481{ 517{
482 int level = snd_power_get_state(widget->dapm->codec->card->snd_card); 518 int level = snd_power_get_state(widget->dapm->card->snd_card);
483 519
484 switch (level) { 520 switch (level) {
485 case SNDRV_CTL_POWER_D3hot: 521 case SNDRV_CTL_POWER_D3hot:
@@ -734,10 +770,23 @@ static int dapm_supply_check_power(struct snd_soc_dapm_widget *w)
734 770
735static int dapm_seq_compare(struct snd_soc_dapm_widget *a, 771static int dapm_seq_compare(struct snd_soc_dapm_widget *a,
736 struct snd_soc_dapm_widget *b, 772 struct snd_soc_dapm_widget *b,
737 int sort[]) 773 bool power_up)
738{ 774{
775 int *sort;
776
777 if (power_up)
778 sort = dapm_up_seq;
779 else
780 sort = dapm_down_seq;
781
739 if (sort[a->id] != sort[b->id]) 782 if (sort[a->id] != sort[b->id])
740 return sort[a->id] - sort[b->id]; 783 return sort[a->id] - sort[b->id];
784 if (a->subseq != b->subseq) {
785 if (power_up)
786 return a->subseq - b->subseq;
787 else
788 return b->subseq - a->subseq;
789 }
741 if (a->reg != b->reg) 790 if (a->reg != b->reg)
742 return a->reg - b->reg; 791 return a->reg - b->reg;
743 if (a->dapm != b->dapm) 792 if (a->dapm != b->dapm)
@@ -749,12 +798,12 @@ static int dapm_seq_compare(struct snd_soc_dapm_widget *a,
749/* Insert a widget in order into a DAPM power sequence. */ 798/* Insert a widget in order into a DAPM power sequence. */
750static void dapm_seq_insert(struct snd_soc_dapm_widget *new_widget, 799static void dapm_seq_insert(struct snd_soc_dapm_widget *new_widget,
751 struct list_head *list, 800 struct list_head *list,
752 int sort[]) 801 bool power_up)
753{ 802{
754 struct snd_soc_dapm_widget *w; 803 struct snd_soc_dapm_widget *w;
755 804
756 list_for_each_entry(w, list, power_list) 805 list_for_each_entry(w, list, power_list)
757 if (dapm_seq_compare(new_widget, w, sort) < 0) { 806 if (dapm_seq_compare(new_widget, w, power_up) < 0) {
758 list_add_tail(&new_widget->power_list, &w->power_list); 807 list_add_tail(&new_widget->power_list, &w->power_list);
759 return; 808 return;
760 } 809 }
@@ -865,26 +914,42 @@ static void dapm_seq_run_coalesced(struct snd_soc_dapm_context *dapm,
865 * handled. 914 * handled.
866 */ 915 */
867static void dapm_seq_run(struct snd_soc_dapm_context *dapm, 916static void dapm_seq_run(struct snd_soc_dapm_context *dapm,
868 struct list_head *list, int event, int sort[]) 917 struct list_head *list, int event, bool power_up)
869{ 918{
870 struct snd_soc_dapm_widget *w, *n; 919 struct snd_soc_dapm_widget *w, *n;
871 LIST_HEAD(pending); 920 LIST_HEAD(pending);
872 int cur_sort = -1; 921 int cur_sort = -1;
922 int cur_subseq = -1;
873 int cur_reg = SND_SOC_NOPM; 923 int cur_reg = SND_SOC_NOPM;
874 struct snd_soc_dapm_context *cur_dapm = NULL; 924 struct snd_soc_dapm_context *cur_dapm = NULL;
875 int ret; 925 int ret, i;
926 int *sort;
927
928 if (power_up)
929 sort = dapm_up_seq;
930 else
931 sort = dapm_down_seq;
876 932
877 list_for_each_entry_safe(w, n, list, power_list) { 933 list_for_each_entry_safe(w, n, list, power_list) {
878 ret = 0; 934 ret = 0;
879 935
880 /* Do we need to apply any queued changes? */ 936 /* Do we need to apply any queued changes? */
881 if (sort[w->id] != cur_sort || w->reg != cur_reg || 937 if (sort[w->id] != cur_sort || w->reg != cur_reg ||
882 w->dapm != cur_dapm) { 938 w->dapm != cur_dapm || w->subseq != cur_subseq) {
883 if (!list_empty(&pending)) 939 if (!list_empty(&pending))
884 dapm_seq_run_coalesced(cur_dapm, &pending); 940 dapm_seq_run_coalesced(cur_dapm, &pending);
885 941
942 if (cur_dapm && cur_dapm->seq_notifier) {
943 for (i = 0; i < ARRAY_SIZE(dapm_up_seq); i++)
944 if (sort[i] == cur_sort)
945 cur_dapm->seq_notifier(cur_dapm,
946 i,
947 cur_subseq);
948 }
949
886 INIT_LIST_HEAD(&pending); 950 INIT_LIST_HEAD(&pending);
887 cur_sort = -1; 951 cur_sort = -1;
952 cur_subseq = -1;
888 cur_reg = SND_SOC_NOPM; 953 cur_reg = SND_SOC_NOPM;
889 cur_dapm = NULL; 954 cur_dapm = NULL;
890 } 955 }
@@ -929,6 +994,7 @@ static void dapm_seq_run(struct snd_soc_dapm_context *dapm,
929 default: 994 default:
930 /* Queue it up for application */ 995 /* Queue it up for application */
931 cur_sort = sort[w->id]; 996 cur_sort = sort[w->id];
997 cur_subseq = w->subseq;
932 cur_reg = w->reg; 998 cur_reg = w->reg;
933 cur_dapm = w->dapm; 999 cur_dapm = w->dapm;
934 list_move(&w->power_list, &pending); 1000 list_move(&w->power_list, &pending);
@@ -942,6 +1008,13 @@ static void dapm_seq_run(struct snd_soc_dapm_context *dapm,
942 1008
943 if (!list_empty(&pending)) 1009 if (!list_empty(&pending))
944 dapm_seq_run_coalesced(cur_dapm, &pending); 1010 dapm_seq_run_coalesced(cur_dapm, &pending);
1011
1012 if (cur_dapm && cur_dapm->seq_notifier) {
1013 for (i = 0; i < ARRAY_SIZE(dapm_up_seq); i++)
1014 if (sort[i] == cur_sort)
1015 cur_dapm->seq_notifier(cur_dapm,
1016 i, cur_subseq);
1017 }
945} 1018}
946 1019
947static void dapm_widget_update(struct snd_soc_dapm_context *dapm) 1020static void dapm_widget_update(struct snd_soc_dapm_context *dapm)
@@ -977,7 +1050,62 @@ static void dapm_widget_update(struct snd_soc_dapm_context *dapm)
977 } 1050 }
978} 1051}
979 1052
1053/* Async callback run prior to DAPM sequences - brings to _PREPARE if
1054 * they're changing state.
1055 */
1056static void dapm_pre_sequence_async(void *data, async_cookie_t cookie)
1057{
1058 struct snd_soc_dapm_context *d = data;
1059 int ret;
980 1060
1061 if (d->dev_power && d->bias_level == SND_SOC_BIAS_OFF) {
1062 ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_STANDBY);
1063 if (ret != 0)
1064 dev_err(d->dev,
1065 "Failed to turn on bias: %d\n", ret);
1066 }
1067
1068 /* If we're changing to all on or all off then prepare */
1069 if ((d->dev_power && d->bias_level == SND_SOC_BIAS_STANDBY) ||
1070 (!d->dev_power && d->bias_level == SND_SOC_BIAS_ON)) {
1071 ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_PREPARE);
1072 if (ret != 0)
1073 dev_err(d->dev,
1074 "Failed to prepare bias: %d\n", ret);
1075 }
1076}
1077
1078/* Async callback run prior to DAPM sequences - brings to their final
1079 * state.
1080 */
1081static void dapm_post_sequence_async(void *data, async_cookie_t cookie)
1082{
1083 struct snd_soc_dapm_context *d = data;
1084 int ret;
1085
1086 /* If we just powered the last thing off drop to standby bias */
1087 if (d->bias_level == SND_SOC_BIAS_PREPARE && !d->dev_power) {
1088 ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_STANDBY);
1089 if (ret != 0)
1090 dev_err(d->dev, "Failed to apply standby bias: %d\n",
1091 ret);
1092 }
1093
1094 /* If we're in standby and can support bias off then do that */
1095 if (d->bias_level == SND_SOC_BIAS_STANDBY && d->idle_bias_off) {
1096 ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_OFF);
1097 if (ret != 0)
1098 dev_err(d->dev, "Failed to turn off bias: %d\n", ret);
1099 }
1100
1101 /* If we just powered up then move to active bias */
1102 if (d->bias_level == SND_SOC_BIAS_PREPARE && d->dev_power) {
1103 ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_ON);
1104 if (ret != 0)
1105 dev_err(d->dev, "Failed to apply active bias: %d\n",
1106 ret);
1107 }
1108}
981 1109
982/* 1110/*
983 * Scan each dapm widget for complete audio path. 1111 * Scan each dapm widget for complete audio path.
@@ -990,12 +1118,12 @@ static void dapm_widget_update(struct snd_soc_dapm_context *dapm)
990 */ 1118 */
991static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event) 1119static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
992{ 1120{
993 struct snd_soc_card *card = dapm->codec->card; 1121 struct snd_soc_card *card = dapm->card;
994 struct snd_soc_dapm_widget *w; 1122 struct snd_soc_dapm_widget *w;
995 struct snd_soc_dapm_context *d; 1123 struct snd_soc_dapm_context *d;
996 LIST_HEAD(up_list); 1124 LIST_HEAD(up_list);
997 LIST_HEAD(down_list); 1125 LIST_HEAD(down_list);
998 int ret = 0; 1126 LIST_HEAD(async_domain);
999 int power; 1127 int power;
1000 1128
1001 trace_snd_soc_dapm_start(card); 1129 trace_snd_soc_dapm_start(card);
@@ -1010,10 +1138,10 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1010 list_for_each_entry(w, &card->widgets, list) { 1138 list_for_each_entry(w, &card->widgets, list) {
1011 switch (w->id) { 1139 switch (w->id) {
1012 case snd_soc_dapm_pre: 1140 case snd_soc_dapm_pre:
1013 dapm_seq_insert(w, &down_list, dapm_down_seq); 1141 dapm_seq_insert(w, &down_list, false);
1014 break; 1142 break;
1015 case snd_soc_dapm_post: 1143 case snd_soc_dapm_post:
1016 dapm_seq_insert(w, &up_list, dapm_up_seq); 1144 dapm_seq_insert(w, &up_list, true);
1017 break; 1145 break;
1018 1146
1019 default: 1147 default:
@@ -1033,9 +1161,9 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1033 trace_snd_soc_dapm_widget_power(w, power); 1161 trace_snd_soc_dapm_widget_power(w, power);
1034 1162
1035 if (power) 1163 if (power)
1036 dapm_seq_insert(w, &up_list, dapm_up_seq); 1164 dapm_seq_insert(w, &up_list, true);
1037 else 1165 else
1038 dapm_seq_insert(w, &down_list, dapm_down_seq); 1166 dapm_seq_insert(w, &down_list, false);
1039 1167
1040 w->power = power; 1168 w->power = power;
1041 break; 1169 break;
@@ -1073,65 +1201,25 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1073 } 1201 }
1074 } 1202 }
1075 1203
1076 list_for_each_entry(d, &dapm->card->dapm_list, list) { 1204 /* Run all the bias changes in parallel */
1077 if (d->dev_power && d->bias_level == SND_SOC_BIAS_OFF) { 1205 list_for_each_entry(d, &dapm->card->dapm_list, list)
1078 ret = snd_soc_dapm_set_bias_level(card, d, 1206 async_schedule_domain(dapm_pre_sequence_async, d,
1079 SND_SOC_BIAS_STANDBY); 1207 &async_domain);
1080 if (ret != 0) 1208 async_synchronize_full_domain(&async_domain);
1081 dev_err(d->dev,
1082 "Failed to turn on bias: %d\n", ret);
1083 }
1084
1085 /* If we're changing to all on or all off then prepare */
1086 if ((d->dev_power && d->bias_level == SND_SOC_BIAS_STANDBY) ||
1087 (!d->dev_power && d->bias_level == SND_SOC_BIAS_ON)) {
1088 ret = snd_soc_dapm_set_bias_level(card, d,
1089 SND_SOC_BIAS_PREPARE);
1090 if (ret != 0)
1091 dev_err(d->dev,
1092 "Failed to prepare bias: %d\n", ret);
1093 }
1094 }
1095 1209
1096 /* Power down widgets first; try to avoid amplifying pops. */ 1210 /* Power down widgets first; try to avoid amplifying pops. */
1097 dapm_seq_run(dapm, &down_list, event, dapm_down_seq); 1211 dapm_seq_run(dapm, &down_list, event, false);
1098 1212
1099 dapm_widget_update(dapm); 1213 dapm_widget_update(dapm);
1100 1214
1101 /* Now power up. */ 1215 /* Now power up. */
1102 dapm_seq_run(dapm, &up_list, event, dapm_up_seq); 1216 dapm_seq_run(dapm, &up_list, event, true);
1103
1104 list_for_each_entry(d, &dapm->card->dapm_list, list) {
1105 /* If we just powered the last thing off drop to standby bias */
1106 if (d->bias_level == SND_SOC_BIAS_PREPARE && !d->dev_power) {
1107 ret = snd_soc_dapm_set_bias_level(card, d,
1108 SND_SOC_BIAS_STANDBY);
1109 if (ret != 0)
1110 dev_err(d->dev,
1111 "Failed to apply standby bias: %d\n",
1112 ret);
1113 }
1114 1217
1115 /* If we're in standby and can support bias off then do that */ 1218 /* Run all the bias changes in parallel */
1116 if (d->bias_level == SND_SOC_BIAS_STANDBY && 1219 list_for_each_entry(d, &dapm->card->dapm_list, list)
1117 d->idle_bias_off) { 1220 async_schedule_domain(dapm_post_sequence_async, d,
1118 ret = snd_soc_dapm_set_bias_level(card, d, 1221 &async_domain);
1119 SND_SOC_BIAS_OFF); 1222 async_synchronize_full_domain(&async_domain);
1120 if (ret != 0)
1121 dev_err(d->dev,
1122 "Failed to turn off bias: %d\n", ret);
1123 }
1124
1125 /* If we just powered up then move to active bias */
1126 if (d->bias_level == SND_SOC_BIAS_PREPARE && d->dev_power) {
1127 ret = snd_soc_dapm_set_bias_level(card, d,
1128 SND_SOC_BIAS_ON);
1129 if (ret != 0)
1130 dev_err(d->dev,
1131 "Failed to apply active bias: %d\n",
1132 ret);
1133 }
1134 }
1135 1223
1136 pop_dbg(dapm->dev, card->pop_time, 1224 pop_dbg(dapm->dev, card->pop_time,
1137 "DAPM sequencing finished, waiting %dms\n", card->pop_time); 1225 "DAPM sequencing finished, waiting %dms\n", card->pop_time);
@@ -1189,7 +1277,7 @@ static ssize_t dapm_widget_power_read_file(struct file *file,
1189 1277
1190 if (p->connect) 1278 if (p->connect)
1191 ret += snprintf(buf + ret, PAGE_SIZE - ret, 1279 ret += snprintf(buf + ret, PAGE_SIZE - ret,
1192 " in %s %s\n", 1280 " in \"%s\" \"%s\"\n",
1193 p->name ? p->name : "static", 1281 p->name ? p->name : "static",
1194 p->source->name); 1282 p->source->name);
1195 } 1283 }
@@ -1199,7 +1287,7 @@ static ssize_t dapm_widget_power_read_file(struct file *file,
1199 1287
1200 if (p->connect) 1288 if (p->connect)
1201 ret += snprintf(buf + ret, PAGE_SIZE - ret, 1289 ret += snprintf(buf + ret, PAGE_SIZE - ret,
1202 " out %s %s\n", 1290 " out \"%s\" \"%s\"\n",
1203 p->name ? p->name : "static", 1291 p->name ? p->name : "static",
1204 p->sink->name); 1292 p->sink->name);
1205 } 1293 }
@@ -1464,7 +1552,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm,
1464 char prefixed_source[80]; 1552 char prefixed_source[80];
1465 int ret = 0; 1553 int ret = 0;
1466 1554
1467 if (dapm->codec->name_prefix) { 1555 if (dapm->codec && dapm->codec->name_prefix) {
1468 snprintf(prefixed_sink, sizeof(prefixed_sink), "%s %s", 1556 snprintf(prefixed_sink, sizeof(prefixed_sink), "%s %s",
1469 dapm->codec->name_prefix, route->sink); 1557 dapm->codec->name_prefix, route->sink);
1470 sink = prefixed_sink; 1558 sink = prefixed_sink;
@@ -2114,14 +2202,14 @@ int snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
2114 return -ENOMEM; 2202 return -ENOMEM;
2115 2203
2116 name_len = strlen(widget->name) + 1; 2204 name_len = strlen(widget->name) + 1;
2117 if (dapm->codec->name_prefix) 2205 if (dapm->codec && dapm->codec->name_prefix)
2118 name_len += 1 + strlen(dapm->codec->name_prefix); 2206 name_len += 1 + strlen(dapm->codec->name_prefix);
2119 w->name = kmalloc(name_len, GFP_KERNEL); 2207 w->name = kmalloc(name_len, GFP_KERNEL);
2120 if (w->name == NULL) { 2208 if (w->name == NULL) {
2121 kfree(w); 2209 kfree(w);
2122 return -ENOMEM; 2210 return -ENOMEM;
2123 } 2211 }
2124 if (dapm->codec->name_prefix) 2212 if (dapm->codec && dapm->codec->name_prefix)
2125 snprintf(w->name, name_len, "%s %s", 2213 snprintf(w->name, name_len, "%s %s",
2126 dapm->codec->name_prefix, widget->name); 2214 dapm->codec->name_prefix, widget->name);
2127 else 2215 else
@@ -2226,7 +2314,6 @@ int snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd,
2226 mutex_unlock(&codec->mutex); 2314 mutex_unlock(&codec->mutex);
2227 return 0; 2315 return 0;
2228} 2316}
2229EXPORT_SYMBOL_GPL(snd_soc_dapm_stream_event);
2230 2317
2231/** 2318/**
2232 * snd_soc_dapm_enable_pin - enable pin. 2319 * snd_soc_dapm_enable_pin - enable pin.
@@ -2393,7 +2480,7 @@ static void soc_dapm_shutdown_codec(struct snd_soc_dapm_context *dapm)
2393 if (w->dapm != dapm) 2480 if (w->dapm != dapm)
2394 continue; 2481 continue;
2395 if (w->power) { 2482 if (w->power) {
2396 dapm_seq_insert(w, &down_list, dapm_down_seq); 2483 dapm_seq_insert(w, &down_list, false);
2397 w->power = 0; 2484 w->power = 0;
2398 powerdown = 1; 2485 powerdown = 1;
2399 } 2486 }
@@ -2403,9 +2490,9 @@ static void soc_dapm_shutdown_codec(struct snd_soc_dapm_context *dapm)
2403 * standby. 2490 * standby.
2404 */ 2491 */
2405 if (powerdown) { 2492 if (powerdown) {
2406 snd_soc_dapm_set_bias_level(NULL, dapm, SND_SOC_BIAS_PREPARE); 2493 snd_soc_dapm_set_bias_level(dapm, SND_SOC_BIAS_PREPARE);
2407 dapm_seq_run(dapm, &down_list, 0, dapm_down_seq); 2494 dapm_seq_run(dapm, &down_list, 0, false);
2408 snd_soc_dapm_set_bias_level(NULL, dapm, SND_SOC_BIAS_STANDBY); 2495 snd_soc_dapm_set_bias_level(dapm, SND_SOC_BIAS_STANDBY);
2409 } 2496 }
2410} 2497}
2411 2498
@@ -2418,7 +2505,7 @@ void snd_soc_dapm_shutdown(struct snd_soc_card *card)
2418 2505
2419 list_for_each_entry(codec, &card->codec_dev_list, list) { 2506 list_for_each_entry(codec, &card->codec_dev_list, list) {
2420 soc_dapm_shutdown_codec(&codec->dapm); 2507 soc_dapm_shutdown_codec(&codec->dapm);
2421 snd_soc_dapm_set_bias_level(card, &codec->dapm, SND_SOC_BIAS_OFF); 2508 snd_soc_dapm_set_bias_level(&codec->dapm, SND_SOC_BIAS_OFF);
2422 } 2509 }
2423} 2510}
2424 2511
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c
index ac5a5bc7375a..fcab80b36a37 100644
--- a/sound/soc/soc-jack.c
+++ b/sound/soc/soc-jack.c
@@ -37,6 +37,7 @@ int snd_soc_jack_new(struct snd_soc_codec *codec, const char *id, int type,
37{ 37{
38 jack->codec = codec; 38 jack->codec = codec;
39 INIT_LIST_HEAD(&jack->pins); 39 INIT_LIST_HEAD(&jack->pins);
40 INIT_LIST_HEAD(&jack->jack_zones);
40 BLOCKING_INIT_NOTIFIER_HEAD(&jack->notifier); 41 BLOCKING_INIT_NOTIFIER_HEAD(&jack->notifier);
41 42
42 return snd_jack_new(codec->card->snd_card, id, type, &jack->jack); 43 return snd_jack_new(codec->card->snd_card, id, type, &jack->jack);
@@ -100,7 +101,7 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
100 } 101 }
101 102
102 /* Report before the DAPM sync to help users updating micbias status */ 103 /* Report before the DAPM sync to help users updating micbias status */
103 blocking_notifier_call_chain(&jack->notifier, status, NULL); 104 blocking_notifier_call_chain(&jack->notifier, status, jack);
104 105
105 snd_soc_dapm_sync(dapm); 106 snd_soc_dapm_sync(dapm);
106 107
@@ -112,6 +113,51 @@ out:
112EXPORT_SYMBOL_GPL(snd_soc_jack_report); 113EXPORT_SYMBOL_GPL(snd_soc_jack_report);
113 114
114/** 115/**
116 * snd_soc_jack_add_zones - Associate voltage zones with jack
117 *
118 * @jack: ASoC jack
119 * @count: Number of zones
120 * @zone: Array of zones
121 *
122 * After this function has been called the zones specified in the
123 * array will be associated with the jack.
124 */
125int snd_soc_jack_add_zones(struct snd_soc_jack *jack, int count,
126 struct snd_soc_jack_zone *zones)
127{
128 int i;
129
130 for (i = 0; i < count; i++) {
131 INIT_LIST_HEAD(&zones[i].list);
132 list_add(&(zones[i].list), &jack->jack_zones);
133 }
134 return 0;
135}
136EXPORT_SYMBOL_GPL(snd_soc_jack_add_zones);
137
138/**
139 * snd_soc_jack_get_type - Based on the mic bias value, this function returns
140 * the type of jack from the zones delcared in the jack type
141 *
142 * @micbias_voltage: mic bias voltage at adc channel when jack is plugged in
143 *
144 * Based on the mic bias value passed, this function helps identify
145 * the type of jack from the already delcared jack zones
146 */
147int snd_soc_jack_get_type(struct snd_soc_jack *jack, int micbias_voltage)
148{
149 struct snd_soc_jack_zone *zone;
150
151 list_for_each_entry(zone, &jack->jack_zones, list) {
152 if (micbias_voltage >= zone->min_mv &&
153 micbias_voltage < zone->max_mv)
154 return zone->jack_type;
155 }
156 return 0;
157}
158EXPORT_SYMBOL_GPL(snd_soc_jack_get_type);
159
160/**
115 * snd_soc_jack_add_pins - Associate DAPM pins with an ASoC jack 161 * snd_soc_jack_add_pins - Associate DAPM pins with an ASoC jack
116 * 162 *
117 * @jack: ASoC jack 163 * @jack: ASoC jack
@@ -194,7 +240,7 @@ static void snd_soc_jack_gpio_detect(struct snd_soc_jack_gpio *gpio)
194 int enable; 240 int enable;
195 int report; 241 int report;
196 242
197 enable = gpio_get_value(gpio->gpio); 243 enable = gpio_get_value_cansleep(gpio->gpio);
198 if (gpio->invert) 244 if (gpio->invert)
199 enable = !enable; 245 enable = !enable;
200 246
@@ -284,6 +330,14 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count,
284 if (ret) 330 if (ret)
285 goto err; 331 goto err;
286 332
333 if (gpios[i].wake) {
334 ret = set_irq_wake(gpio_to_irq(gpios[i].gpio), 1);
335 if (ret != 0)
336 printk(KERN_ERR
337 "Failed to mark GPIO %d as wake source: %d\n",
338 gpios[i].gpio, ret);
339 }
340
287#ifdef CONFIG_GPIO_SYSFS 341#ifdef CONFIG_GPIO_SYSFS
288 /* Expose GPIO value over sysfs for diagnostic purposes */ 342 /* Expose GPIO value over sysfs for diagnostic purposes */
289 gpio_export(gpios[i].gpio, false); 343 gpio_export(gpios[i].gpio, false);
diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c
index 1d07b931f3d8..3f45e6a439bf 100644
--- a/sound/soc/soc-utils.c
+++ b/sound/soc/soc-utils.c
@@ -28,26 +28,9 @@ int snd_soc_params_to_frame_size(struct snd_pcm_hw_params *params)
28{ 28{
29 int sample_size; 29 int sample_size;
30 30
31 switch (params_format(params)) { 31 sample_size = snd_pcm_format_width(params_format(params));
32 case SNDRV_PCM_FORMAT_S16_LE: 32 if (sample_size < 0)
33 case SNDRV_PCM_FORMAT_S16_BE: 33 return sample_size;
34 sample_size = 16;
35 break;
36 case SNDRV_PCM_FORMAT_S20_3LE:
37 case SNDRV_PCM_FORMAT_S20_3BE:
38 sample_size = 20;
39 break;
40 case SNDRV_PCM_FORMAT_S24_LE:
41 case SNDRV_PCM_FORMAT_S24_BE:
42 sample_size = 24;
43 break;
44 case SNDRV_PCM_FORMAT_S32_LE:
45 case SNDRV_PCM_FORMAT_S32_BE:
46 sample_size = 32;
47 break;
48 default:
49 return -ENOTSUPP;
50 }
51 34
52 return snd_soc_calc_frame_size(sample_size, params_channels(params), 35 return snd_soc_calc_frame_size(sample_size, params_channels(params),
53 1); 36 1);
diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig
new file mode 100644
index 000000000000..66b504f06c23
--- /dev/null
+++ b/sound/soc/tegra/Kconfig
@@ -0,0 +1,26 @@
1config SND_TEGRA_SOC
2 tristate "SoC Audio for the Tegra System-on-Chip"
3 depends on ARCH_TEGRA && TEGRA_SYSTEM_DMA
4 default m
5 help
6 Say Y or M here if you want support for SoC audio on Tegra.
7
8config SND_TEGRA_SOC_I2S
9 tristate
10 depends on SND_TEGRA_SOC
11 default m
12 help
13 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
15 machine drivers to support below.
16
17config SND_TEGRA_SOC_HARMONY
18 tristate "SoC Audio support for Tegra Harmony reference board"
19 depends on SND_TEGRA_SOC && MACH_HARMONY && I2C
20 default m
21 select SND_TEGRA_SOC_I2S
22 select SND_SOC_WM8903
23 help
24 Say Y or M here if you want to add support for SoC audio on the
25 Tegra Harmony reference board.
26
diff --git a/sound/soc/tegra/Makefile b/sound/soc/tegra/Makefile
new file mode 100644
index 000000000000..fd183d3ab4f1
--- /dev/null
+++ b/sound/soc/tegra/Makefile
@@ -0,0 +1,15 @@
1# Tegra platform Support
2snd-soc-tegra-das-objs := tegra_das.o
3snd-soc-tegra-pcm-objs := tegra_pcm.o
4snd-soc-tegra-i2s-objs := tegra_i2s.o
5snd-soc-tegra-utils-objs += tegra_asoc_utils.o
6
7obj-$(CONFIG_SND_TEGRA_SOC) += snd-soc-tegra-utils.o
8obj-$(CONFIG_SND_TEGRA_SOC) += snd-soc-tegra-das.o
9obj-$(CONFIG_SND_TEGRA_SOC) += snd-soc-tegra-pcm.o
10obj-$(CONFIG_SND_TEGRA_SOC_I2S) += snd-soc-tegra-i2s.o
11
12# Tegra machine Support
13snd-soc-tegra-harmony-objs := harmony.o
14
15obj-$(CONFIG_SND_TEGRA_SOC_HARMONY) += snd-soc-tegra-harmony.o
diff --git a/sound/soc/tegra/harmony.c b/sound/soc/tegra/harmony.c
new file mode 100644
index 000000000000..8585957477eb
--- /dev/null
+++ b/sound/soc/tegra/harmony.c
@@ -0,0 +1,393 @@
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 },
374 .probe = tegra_snd_harmony_probe,
375 .remove = __devexit_p(tegra_snd_harmony_remove),
376};
377
378static int __init snd_tegra_harmony_init(void)
379{
380 return platform_driver_register(&tegra_snd_harmony_driver);
381}
382module_init(snd_tegra_harmony_init);
383
384static void __exit snd_tegra_harmony_exit(void)
385{
386 platform_driver_unregister(&tegra_snd_harmony_driver);
387}
388module_exit(snd_tegra_harmony_exit);
389
390MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
391MODULE_DESCRIPTION("Harmony machine ASoC driver");
392MODULE_LICENSE("GPL");
393MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/tegra/tegra_asoc_utils.c b/sound/soc/tegra/tegra_asoc_utils.c
new file mode 100644
index 000000000000..52f0a3f9ce40
--- /dev/null
+++ b/sound/soc/tegra/tegra_asoc_utils.c
@@ -0,0 +1,155 @@
1/*
2 * tegra_asoc_utils.c - Harmony machine ASoC driver
3 *
4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010 - NVIDIA, Inc.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19 * 02110-1301 USA
20 *
21 */
22
23#include <linux/clk.h>
24#include <linux/device.h>
25#include <linux/err.h>
26#include <linux/kernel.h>
27
28#include "tegra_asoc_utils.h"
29
30int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate,
31 int mclk, int *mclk_change)
32{
33 int new_baseclock;
34 int err;
35
36 switch (srate) {
37 case 11025:
38 case 22050:
39 case 44100:
40 case 88200:
41 new_baseclock = 56448000;
42 break;
43 case 8000:
44 case 16000:
45 case 32000:
46 case 48000:
47 case 64000:
48 case 96000:
49 new_baseclock = 73728000;
50 break;
51 default:
52 return -EINVAL;
53 }
54
55 *mclk_change = ((new_baseclock != data->set_baseclock) ||
56 (mclk != data->set_mclk));
57 if (!*mclk_change)
58 return 0;
59
60 data->set_baseclock = 0;
61 data->set_mclk = 0;
62
63 clk_disable(data->clk_cdev1);
64 clk_disable(data->clk_pll_a_out0);
65 clk_disable(data->clk_pll_a);
66
67 err = clk_set_rate(data->clk_pll_a, new_baseclock);
68 if (err) {
69 dev_err(data->dev, "Can't set pll_a rate: %d\n", err);
70 return err;
71 }
72
73 err = clk_set_rate(data->clk_pll_a_out0, mclk);
74 if (err) {
75 dev_err(data->dev, "Can't set pll_a_out0 rate: %d\n", err);
76 return err;
77 }
78
79 /* Don't set cdev1 rate; its locked to pll_a_out0 */
80
81 err = clk_enable(data->clk_pll_a);
82 if (err) {
83 dev_err(data->dev, "Can't enable pll_a: %d\n", err);
84 return err;
85 }
86
87 err = clk_enable(data->clk_pll_a_out0);
88 if (err) {
89 dev_err(data->dev, "Can't enable pll_a_out0: %d\n", err);
90 return err;
91 }
92
93 err = clk_enable(data->clk_cdev1);
94 if (err) {
95 dev_err(data->dev, "Can't enable cdev1: %d\n", err);
96 return err;
97 }
98
99 data->set_baseclock = new_baseclock;
100 data->set_mclk = mclk;
101
102 return 0;
103}
104EXPORT_SYMBOL_GPL(tegra_asoc_utils_set_rate);
105
106int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data,
107 struct device *dev)
108{
109 int ret;
110
111 data->dev = dev;
112
113 data->clk_pll_a = clk_get_sys(NULL, "pll_a");
114 if (IS_ERR(data->clk_pll_a)) {
115 dev_err(data->dev, "Can't retrieve clk pll_a\n");
116 ret = PTR_ERR(data->clk_pll_a);
117 goto err;
118 }
119
120 data->clk_pll_a_out0 = clk_get_sys(NULL, "pll_a_out0");
121 if (IS_ERR(data->clk_pll_a_out0)) {
122 dev_err(data->dev, "Can't retrieve clk pll_a_out0\n");
123 ret = PTR_ERR(data->clk_pll_a_out0);
124 goto err_put_pll_a;
125 }
126
127 data->clk_cdev1 = clk_get_sys(NULL, "cdev1");
128 if (IS_ERR(data->clk_cdev1)) {
129 dev_err(data->dev, "Can't retrieve clk cdev1\n");
130 ret = PTR_ERR(data->clk_cdev1);
131 goto err_put_pll_a_out0;
132 }
133
134 return 0;
135
136err_put_pll_a_out0:
137 clk_put(data->clk_pll_a_out0);
138err_put_pll_a:
139 clk_put(data->clk_pll_a);
140err:
141 return ret;
142}
143EXPORT_SYMBOL_GPL(tegra_asoc_utils_init);
144
145void tegra_asoc_utils_fini(struct tegra_asoc_utils_data *data)
146{
147 clk_put(data->clk_cdev1);
148 clk_put(data->clk_pll_a_out0);
149 clk_put(data->clk_pll_a);
150}
151EXPORT_SYMBOL_GPL(tegra_asoc_utils_fini);
152
153MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
154MODULE_DESCRIPTION("Tegra ASoC utility code");
155MODULE_LICENSE("GPL");
diff --git a/sound/soc/tegra/tegra_asoc_utils.h b/sound/soc/tegra/tegra_asoc_utils.h
new file mode 100644
index 000000000000..bbba7afdfc2c
--- /dev/null
+++ b/sound/soc/tegra/tegra_asoc_utils.h
@@ -0,0 +1,45 @@
1/*
2 * tegra_asoc_utils.h - Definitions for Tegra DAS driver
3 *
4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010 - NVIDIA, Inc.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19 * 02110-1301 USA
20 *
21 */
22
23#ifndef __TEGRA_ASOC_UTILS_H__
24#define __TEGRA_ASOC_UTILS_H_
25
26struct clk;
27struct device;
28
29struct tegra_asoc_utils_data {
30 struct device *dev;
31 struct clk *clk_pll_a;
32 struct clk *clk_pll_a_out0;
33 struct clk *clk_cdev1;
34 int set_baseclock;
35 int set_mclk;
36};
37
38int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate,
39 int mclk, int *mclk_change);
40int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data,
41 struct device *dev);
42void tegra_asoc_utils_fini(struct tegra_asoc_utils_data *data);
43
44#endif
45
diff --git a/sound/soc/tegra/tegra_das.c b/sound/soc/tegra/tegra_das.c
new file mode 100644
index 000000000000..9f24ef73f2cb
--- /dev/null
+++ b/sound/soc/tegra/tegra_das.c
@@ -0,0 +1,265 @@
1/*
2 * tegra_das.c - Tegra DAS driver
3 *
4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010 - NVIDIA, Inc.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19 * 02110-1301 USA
20 *
21 */
22
23#include <linux/module.h>
24#include <linux/debugfs.h>
25#include <linux/device.h>
26#include <linux/platform_device.h>
27#include <linux/seq_file.h>
28#include <linux/slab.h>
29#include <linux/io.h>
30#include <mach/iomap.h>
31#include <sound/soc.h>
32#include "tegra_das.h"
33
34#define DRV_NAME "tegra-das"
35
36static struct tegra_das *das;
37
38static inline void tegra_das_write(u32 reg, u32 val)
39{
40 __raw_writel(val, das->regs + reg);
41}
42
43static inline u32 tegra_das_read(u32 reg)
44{
45 return __raw_readl(das->regs + reg);
46}
47
48int tegra_das_connect_dap_to_dac(int dap, int dac)
49{
50 u32 addr;
51 u32 reg;
52
53 if (!das)
54 return -ENODEV;
55
56 addr = TEGRA_DAS_DAP_CTRL_SEL +
57 (dap * TEGRA_DAS_DAP_CTRL_SEL_STRIDE);
58 reg = dac << TEGRA_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL_P;
59
60 tegra_das_write(addr, reg);
61
62 return 0;
63}
64EXPORT_SYMBOL_GPL(tegra_das_connect_dap_to_dac);
65
66int tegra_das_connect_dap_to_dap(int dap, int otherdap, int master,
67 int sdata1rx, int sdata2rx)
68{
69 u32 addr;
70 u32 reg;
71
72 if (!das)
73 return -ENODEV;
74
75 addr = TEGRA_DAS_DAP_CTRL_SEL +
76 (dap * TEGRA_DAS_DAP_CTRL_SEL_STRIDE);
77 reg = otherdap << TEGRA_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL_P |
78 !!sdata2rx << TEGRA_DAS_DAP_CTRL_SEL_DAP_SDATA2_TX_RX_P |
79 !!sdata1rx << TEGRA_DAS_DAP_CTRL_SEL_DAP_SDATA1_TX_RX_P |
80 !!master << TEGRA_DAS_DAP_CTRL_SEL_DAP_MS_SEL_P;
81
82 tegra_das_write(addr, reg);
83
84 return 0;
85}
86EXPORT_SYMBOL_GPL(tegra_das_connect_dap_to_dap);
87
88int tegra_das_connect_dac_to_dap(int dac, int dap)
89{
90 u32 addr;
91 u32 reg;
92
93 if (!das)
94 return -ENODEV;
95
96 addr = TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL +
97 (dac * TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_STRIDE);
98 reg = dap << TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_CLK_SEL_P |
99 dap << TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA1_SEL_P |
100 dap << TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA2_SEL_P;
101
102 tegra_das_write(addr, reg);
103
104 return 0;
105}
106EXPORT_SYMBOL_GPL(tegra_das_connect_dac_to_dap);
107
108#ifdef CONFIG_DEBUG_FS
109static int tegra_das_show(struct seq_file *s, void *unused)
110{
111 int i;
112 u32 addr;
113 u32 reg;
114
115 for (i = 0; i < TEGRA_DAS_DAP_CTRL_SEL_COUNT; i++) {
116 addr = TEGRA_DAS_DAP_CTRL_SEL +
117 (i * TEGRA_DAS_DAP_CTRL_SEL_STRIDE);
118 reg = tegra_das_read(addr);
119 seq_printf(s, "TEGRA_DAS_DAP_CTRL_SEL[%d] = %08x\n", i, reg);
120 }
121
122 for (i = 0; i < TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_COUNT; i++) {
123 addr = TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL +
124 (i * TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_STRIDE);
125 reg = tegra_das_read(addr);
126 seq_printf(s, "TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL[%d] = %08x\n",
127 i, reg);
128 }
129
130 return 0;
131}
132
133static int tegra_das_debug_open(struct inode *inode, struct file *file)
134{
135 return single_open(file, tegra_das_show, inode->i_private);
136}
137
138static const struct file_operations tegra_das_debug_fops = {
139 .open = tegra_das_debug_open,
140 .read = seq_read,
141 .llseek = seq_lseek,
142 .release = single_release,
143};
144
145static void tegra_das_debug_add(struct tegra_das *das)
146{
147 das->debug = debugfs_create_file(DRV_NAME, S_IRUGO,
148 snd_soc_debugfs_root, das,
149 &tegra_das_debug_fops);
150}
151
152static void tegra_das_debug_remove(struct tegra_das *das)
153{
154 if (das->debug)
155 debugfs_remove(das->debug);
156}
157#else
158static inline void tegra_das_debug_add(struct tegra_das *das)
159{
160}
161
162static inline void tegra_das_debug_remove(struct tegra_das *das)
163{
164}
165#endif
166
167static int __devinit tegra_das_probe(struct platform_device *pdev)
168{
169 struct resource *res, *region;
170 int ret = 0;
171
172 if (das)
173 return -ENODEV;
174
175 das = kzalloc(sizeof(struct tegra_das), GFP_KERNEL);
176 if (!das) {
177 dev_err(&pdev->dev, "Can't allocate tegra_das\n");
178 ret = -ENOMEM;
179 goto exit;
180 }
181 das->dev = &pdev->dev;
182
183 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
184 if (!res) {
185 dev_err(&pdev->dev, "No memory resource\n");
186 ret = -ENODEV;
187 goto err_free;
188 }
189
190 region = request_mem_region(res->start, resource_size(res),
191 pdev->name);
192 if (!region) {
193 dev_err(&pdev->dev, "Memory region already claimed\n");
194 ret = -EBUSY;
195 goto err_free;
196 }
197
198 das->regs = ioremap(res->start, resource_size(res));
199 if (!das->regs) {
200 dev_err(&pdev->dev, "ioremap failed\n");
201 ret = -ENOMEM;
202 goto err_release;
203 }
204
205 tegra_das_debug_add(das);
206
207 platform_set_drvdata(pdev, das);
208
209 return 0;
210
211err_release:
212 release_mem_region(res->start, resource_size(res));
213err_free:
214 kfree(das);
215 das = 0;
216exit:
217 return ret;
218}
219
220static int __devexit tegra_das_remove(struct platform_device *pdev)
221{
222 struct resource *res;
223
224 if (!das)
225 return -ENODEV;
226
227 platform_set_drvdata(pdev, NULL);
228
229 tegra_das_debug_remove(das);
230
231 iounmap(das->regs);
232
233 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
234 release_mem_region(res->start, resource_size(res));
235
236 kfree(das);
237 das = 0;
238
239 return 0;
240}
241
242static struct platform_driver tegra_das_driver = {
243 .probe = tegra_das_probe,
244 .remove = __devexit_p(tegra_das_remove),
245 .driver = {
246 .name = DRV_NAME,
247 },
248};
249
250static int __init tegra_das_modinit(void)
251{
252 return platform_driver_register(&tegra_das_driver);
253}
254module_init(tegra_das_modinit);
255
256static void __exit tegra_das_modexit(void)
257{
258 platform_driver_unregister(&tegra_das_driver);
259}
260module_exit(tegra_das_modexit);
261
262MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
263MODULE_DESCRIPTION("Tegra DAS driver");
264MODULE_LICENSE("GPL");
265MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/tegra/tegra_das.h b/sound/soc/tegra/tegra_das.h
new file mode 100644
index 000000000000..2c96c7b3c459
--- /dev/null
+++ b/sound/soc/tegra/tegra_das.h
@@ -0,0 +1,135 @@
1/*
2 * tegra_das.h - Definitions for Tegra DAS driver
3 *
4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010 - NVIDIA, Inc.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19 * 02110-1301 USA
20 *
21 */
22
23#ifndef __TEGRA_DAS_H__
24#define __TEGRA_DAS_H__
25
26/* Register TEGRA_DAS_DAP_CTRL_SEL */
27#define TEGRA_DAS_DAP_CTRL_SEL 0x00
28#define TEGRA_DAS_DAP_CTRL_SEL_COUNT 5
29#define TEGRA_DAS_DAP_CTRL_SEL_STRIDE 4
30#define TEGRA_DAS_DAP_CTRL_SEL_DAP_MS_SEL_P 31
31#define TEGRA_DAS_DAP_CTRL_SEL_DAP_MS_SEL_S 1
32#define TEGRA_DAS_DAP_CTRL_SEL_DAP_SDATA1_TX_RX_P 30
33#define TEGRA_DAS_DAP_CTRL_SEL_DAP_SDATA1_TX_RX_S 1
34#define TEGRA_DAS_DAP_CTRL_SEL_DAP_SDATA2_TX_RX_P 29
35#define TEGRA_DAS_DAP_CTRL_SEL_DAP_SDATA2_TX_RX_S 1
36#define TEGRA_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL_P 0
37#define TEGRA_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL_S 5
38
39/* Values for field TEGRA_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL */
40#define TEGRA_DAS_DAP_SEL_DAC1 0
41#define TEGRA_DAS_DAP_SEL_DAC2 1
42#define TEGRA_DAS_DAP_SEL_DAC3 2
43#define TEGRA_DAS_DAP_SEL_DAP1 16
44#define TEGRA_DAS_DAP_SEL_DAP2 17
45#define TEGRA_DAS_DAP_SEL_DAP3 18
46#define TEGRA_DAS_DAP_SEL_DAP4 19
47#define TEGRA_DAS_DAP_SEL_DAP5 20
48
49/* Register TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL */
50#define TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL 0x40
51#define TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_COUNT 3
52#define TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_STRIDE 4
53#define TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA2_SEL_P 28
54#define TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA2_SEL_S 4
55#define TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA1_SEL_P 24
56#define TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA1_SEL_S 4
57#define TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_CLK_SEL_P 0
58#define TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_CLK_SEL_S 4
59
60/*
61 * Values for:
62 * TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA2_SEL
63 * TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA1_SEL
64 * TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_CLK_SEL
65 */
66#define TEGRA_DAS_DAC_SEL_DAP1 0
67#define TEGRA_DAS_DAC_SEL_DAP2 1
68#define TEGRA_DAS_DAC_SEL_DAP3 2
69#define TEGRA_DAS_DAC_SEL_DAP4 3
70#define TEGRA_DAS_DAC_SEL_DAP5 4
71
72/*
73 * Names/IDs of the DACs/DAPs.
74 */
75
76#define TEGRA_DAS_DAP_ID_1 0
77#define TEGRA_DAS_DAP_ID_2 1
78#define TEGRA_DAS_DAP_ID_3 2
79#define TEGRA_DAS_DAP_ID_4 3
80#define TEGRA_DAS_DAP_ID_5 4
81
82#define TEGRA_DAS_DAC_ID_1 0
83#define TEGRA_DAS_DAC_ID_2 1
84#define TEGRA_DAS_DAC_ID_3 2
85
86struct tegra_das {
87 struct device *dev;
88 void __iomem *regs;
89 struct dentry *debug;
90};
91
92/*
93 * Terminology:
94 * DAS: Digital audio switch (HW module controlled by this driver)
95 * DAP: Digital audio port (port/pins on Tegra device)
96 * DAC: Digital audio controller (e.g. I2S or AC97 controller elsewhere)
97 *
98 * The Tegra DAS is a mux/cross-bar which can connect each DAP to a specific
99 * DAC, or another DAP. When DAPs are connected, one must be the master and
100 * one the slave. Each DAC allows selection of a specific DAP for input, to
101 * cater for the case where N DAPs are connected to 1 DAC for broadcast
102 * output.
103 *
104 * This driver is dumb; no attempt is made to ensure that a valid routing
105 * configuration is programmed.
106 */
107
108/*
109 * Connect a DAP to to a DAC
110 * dap_id: DAP to connect: TEGRA_DAS_DAP_ID_*
111 * dac_sel: DAC to connect to: TEGRA_DAS_DAP_SEL_DAC*
112 */
113extern int tegra_das_connect_dap_to_dac(int dap_id, int dac_sel);
114
115/*
116 * Connect a DAP to to another DAP
117 * dap_id: DAP to connect: TEGRA_DAS_DAP_ID_*
118 * other_dap_sel: DAP to connect to: TEGRA_DAS_DAP_SEL_DAP*
119 * master: Is this DAP the master (1) or slave (0)
120 * sdata1rx: Is this DAP's SDATA1 pin RX (1) or TX (0)
121 * sdata2rx: Is this DAP's SDATA2 pin RX (1) or TX (0)
122 */
123extern int tegra_das_connect_dap_to_dap(int dap_id, int other_dap_sel,
124 int master, int sdata1rx,
125 int sdata2rx);
126
127/*
128 * Connect a DAC's input to a DAP
129 * (DAC outputs are selected by the DAP)
130 * dac_id: DAC ID to connect: TEGRA_DAS_DAC_ID_*
131 * dap_sel: DAP to receive input from: TEGRA_DAS_DAC_SEL_DAP*
132 */
133extern int tegra_das_connect_dac_to_dap(int dac_id, int dap_sel);
134
135#endif
diff --git a/sound/soc/tegra/tegra_i2s.c b/sound/soc/tegra/tegra_i2s.c
new file mode 100644
index 000000000000..4f5e2c90b020
--- /dev/null
+++ b/sound/soc/tegra/tegra_i2s.c
@@ -0,0 +1,503 @@
1/*
2 * tegra_i2s.c - Tegra I2S driver
3 *
4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010 - NVIDIA, Inc.
6 *
7 * Based on code copyright/by:
8 *
9 * Copyright (c) 2009-2010, NVIDIA Corporation.
10 * Scott Peterson <speterson@nvidia.com>
11 *
12 * Copyright (C) 2010 Google, Inc.
13 * Iliyan Malchev <malchev@google.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 <linux/clk.h>
32#include <linux/module.h>
33#include <linux/debugfs.h>
34#include <linux/device.h>
35#include <linux/platform_device.h>
36#include <linux/seq_file.h>
37#include <linux/slab.h>
38#include <linux/io.h>
39#include <mach/iomap.h>
40#include <sound/core.h>
41#include <sound/pcm.h>
42#include <sound/pcm_params.h>
43#include <sound/soc.h>
44
45#include "tegra_das.h"
46#include "tegra_i2s.h"
47
48#define DRV_NAME "tegra-i2s"
49
50static inline void tegra_i2s_write(struct tegra_i2s *i2s, u32 reg, u32 val)
51{
52 __raw_writel(val, i2s->regs + reg);
53}
54
55static inline u32 tegra_i2s_read(struct tegra_i2s *i2s, u32 reg)
56{
57 return __raw_readl(i2s->regs + reg);
58}
59
60#ifdef CONFIG_DEBUG_FS
61static int tegra_i2s_show(struct seq_file *s, void *unused)
62{
63#define REG(r) { r, #r }
64 static const struct {
65 int offset;
66 const char *name;
67 } regs[] = {
68 REG(TEGRA_I2S_CTRL),
69 REG(TEGRA_I2S_STATUS),
70 REG(TEGRA_I2S_TIMING),
71 REG(TEGRA_I2S_FIFO_SCR),
72 REG(TEGRA_I2S_PCM_CTRL),
73 REG(TEGRA_I2S_NW_CTRL),
74 REG(TEGRA_I2S_TDM_CTRL),
75 REG(TEGRA_I2S_TDM_TX_RX_CTRL),
76 };
77#undef REG
78
79 struct tegra_i2s *i2s = s->private;
80 int i;
81
82 for (i = 0; i < ARRAY_SIZE(regs); i++) {
83 u32 val = tegra_i2s_read(i2s, regs[i].offset);
84 seq_printf(s, "%s = %08x\n", regs[i].name, val);
85 }
86
87 return 0;
88}
89
90static int tegra_i2s_debug_open(struct inode *inode, struct file *file)
91{
92 return single_open(file, tegra_i2s_show, inode->i_private);
93}
94
95static const struct file_operations tegra_i2s_debug_fops = {
96 .open = tegra_i2s_debug_open,
97 .read = seq_read,
98 .llseek = seq_lseek,
99 .release = single_release,
100};
101
102static void tegra_i2s_debug_add(struct tegra_i2s *i2s, int id)
103{
104 char name[] = DRV_NAME ".0";
105
106 snprintf(name, sizeof(name), DRV_NAME".%1d", id);
107 i2s->debug = debugfs_create_file(name, S_IRUGO, snd_soc_debugfs_root,
108 i2s, &tegra_i2s_debug_fops);
109}
110
111static void tegra_i2s_debug_remove(struct tegra_i2s *i2s)
112{
113 if (i2s->debug)
114 debugfs_remove(i2s->debug);
115}
116#else
117static inline void tegra_i2s_debug_add(struct tegra_i2s *i2s)
118{
119}
120
121static inline void tegra_i2s_debug_remove(struct tegra_i2s *i2s)
122{
123}
124#endif
125
126static int tegra_i2s_set_fmt(struct snd_soc_dai *dai,
127 unsigned int fmt)
128{
129 struct tegra_i2s *i2s = snd_soc_dai_get_drvdata(dai);
130
131 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
132 case SND_SOC_DAIFMT_NB_NF:
133 break;
134 default:
135 return -EINVAL;
136 }
137
138 i2s->reg_ctrl &= ~TEGRA_I2S_CTRL_MASTER_ENABLE;
139 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
140 case SND_SOC_DAIFMT_CBS_CFS:
141 i2s->reg_ctrl |= TEGRA_I2S_CTRL_MASTER_ENABLE;
142 break;
143 case SND_SOC_DAIFMT_CBM_CFM:
144 break;
145 default:
146 return -EINVAL;
147 }
148
149 i2s->reg_ctrl &= ~(TEGRA_I2S_CTRL_BIT_FORMAT_MASK |
150 TEGRA_I2S_CTRL_LRCK_MASK);
151 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
152 case SND_SOC_DAIFMT_DSP_A:
153 i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_FORMAT_DSP;
154 i2s->reg_ctrl |= TEGRA_I2S_CTRL_LRCK_L_LOW;
155 break;
156 case SND_SOC_DAIFMT_DSP_B:
157 i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_FORMAT_DSP;
158 i2s->reg_ctrl |= TEGRA_I2S_CTRL_LRCK_R_LOW;
159 break;
160 case SND_SOC_DAIFMT_I2S:
161 i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_FORMAT_I2S;
162 i2s->reg_ctrl |= TEGRA_I2S_CTRL_LRCK_L_LOW;
163 break;
164 case SND_SOC_DAIFMT_RIGHT_J:
165 i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_FORMAT_RJM;
166 i2s->reg_ctrl |= TEGRA_I2S_CTRL_LRCK_L_LOW;
167 break;
168 case SND_SOC_DAIFMT_LEFT_J:
169 i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_FORMAT_LJM;
170 i2s->reg_ctrl |= TEGRA_I2S_CTRL_LRCK_L_LOW;
171 break;
172 default:
173 return -EINVAL;
174 }
175
176 return 0;
177}
178
179static int tegra_i2s_hw_params(struct snd_pcm_substream *substream,
180 struct snd_pcm_hw_params *params,
181 struct snd_soc_dai *dai)
182{
183 struct device *dev = substream->pcm->card->dev;
184 struct tegra_i2s *i2s = snd_soc_dai_get_drvdata(dai);
185 u32 reg;
186 int ret, sample_size, srate, i2sclock, bitcnt;
187
188 i2s->reg_ctrl &= ~TEGRA_I2S_CTRL_BIT_SIZE_MASK;
189 switch (params_format(params)) {
190 case SNDRV_PCM_FORMAT_S16_LE:
191 i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_SIZE_16;
192 sample_size = 16;
193 break;
194 case SNDRV_PCM_FORMAT_S24_LE:
195 i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_SIZE_24;
196 sample_size = 24;
197 break;
198 case SNDRV_PCM_FORMAT_S32_LE:
199 i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_SIZE_32;
200 sample_size = 32;
201 break;
202 default:
203 return -EINVAL;
204 }
205
206 srate = params_rate(params);
207
208 /* Final "* 2" required by Tegra hardware */
209 i2sclock = srate * params_channels(params) * sample_size * 2;
210
211 ret = clk_set_rate(i2s->clk_i2s, i2sclock);
212 if (ret) {
213 dev_err(dev, "Can't set I2S clock rate: %d\n", ret);
214 return ret;
215 }
216
217 bitcnt = (i2sclock / (2 * srate)) - 1;
218 if (bitcnt < 0 || bitcnt > TEGRA_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US)
219 return -EINVAL;
220 reg = bitcnt << TEGRA_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT;
221
222 if (i2sclock % (2 * srate))
223 reg |= TEGRA_I2S_TIMING_NON_SYM_ENABLE;
224
225 tegra_i2s_write(i2s, TEGRA_I2S_TIMING, reg);
226
227 tegra_i2s_write(i2s, TEGRA_I2S_FIFO_SCR,
228 TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_FOUR_SLOTS |
229 TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_FOUR_SLOTS);
230
231 return 0;
232}
233
234static void tegra_i2s_start_playback(struct tegra_i2s *i2s)
235{
236 i2s->reg_ctrl |= TEGRA_I2S_CTRL_FIFO1_ENABLE;
237 tegra_i2s_write(i2s, TEGRA_I2S_CTRL, i2s->reg_ctrl);
238}
239
240static void tegra_i2s_stop_playback(struct tegra_i2s *i2s)
241{
242 i2s->reg_ctrl &= ~TEGRA_I2S_CTRL_FIFO1_ENABLE;
243 tegra_i2s_write(i2s, TEGRA_I2S_CTRL, i2s->reg_ctrl);
244}
245
246static void tegra_i2s_start_capture(struct tegra_i2s *i2s)
247{
248 i2s->reg_ctrl |= TEGRA_I2S_CTRL_FIFO2_ENABLE;
249 tegra_i2s_write(i2s, TEGRA_I2S_CTRL, i2s->reg_ctrl);
250}
251
252static void tegra_i2s_stop_capture(struct tegra_i2s *i2s)
253{
254 i2s->reg_ctrl &= ~TEGRA_I2S_CTRL_FIFO2_ENABLE;
255 tegra_i2s_write(i2s, TEGRA_I2S_CTRL, i2s->reg_ctrl);
256}
257
258static int tegra_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
259 struct snd_soc_dai *dai)
260{
261 struct tegra_i2s *i2s = snd_soc_dai_get_drvdata(dai);
262
263 switch (cmd) {
264 case SNDRV_PCM_TRIGGER_START:
265 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
266 case SNDRV_PCM_TRIGGER_RESUME:
267 if (!i2s->clk_refs)
268 clk_enable(i2s->clk_i2s);
269 i2s->clk_refs++;
270 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
271 tegra_i2s_start_playback(i2s);
272 else
273 tegra_i2s_start_capture(i2s);
274 break;
275 case SNDRV_PCM_TRIGGER_STOP:
276 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
277 case SNDRV_PCM_TRIGGER_SUSPEND:
278 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
279 tegra_i2s_stop_playback(i2s);
280 else
281 tegra_i2s_stop_capture(i2s);
282 i2s->clk_refs--;
283 if (!i2s->clk_refs)
284 clk_disable(i2s->clk_i2s);
285 break;
286 default:
287 return -EINVAL;
288 }
289
290 return 0;
291}
292
293static int tegra_i2s_probe(struct snd_soc_dai *dai)
294{
295 struct tegra_i2s * i2s = snd_soc_dai_get_drvdata(dai);
296
297 dai->capture_dma_data = &i2s->capture_dma_data;
298 dai->playback_dma_data = &i2s->playback_dma_data;
299
300 return 0;
301}
302
303static struct snd_soc_dai_ops tegra_i2s_dai_ops = {
304 .set_fmt = tegra_i2s_set_fmt,
305 .hw_params = tegra_i2s_hw_params,
306 .trigger = tegra_i2s_trigger,
307};
308
309struct snd_soc_dai_driver tegra_i2s_dai[] = {
310 {
311 .name = DRV_NAME ".0",
312 .probe = tegra_i2s_probe,
313 .playback = {
314 .channels_min = 2,
315 .channels_max = 2,
316 .rates = SNDRV_PCM_RATE_8000_96000,
317 .formats = SNDRV_PCM_FMTBIT_S16_LE,
318 },
319 .capture = {
320 .channels_min = 2,
321 .channels_max = 2,
322 .rates = SNDRV_PCM_RATE_8000_96000,
323 .formats = SNDRV_PCM_FMTBIT_S16_LE,
324 },
325 .ops = &tegra_i2s_dai_ops,
326 .symmetric_rates = 1,
327 },
328 {
329 .name = DRV_NAME ".1",
330 .probe = tegra_i2s_probe,
331 .playback = {
332 .channels_min = 2,
333 .channels_max = 2,
334 .rates = SNDRV_PCM_RATE_8000_96000,
335 .formats = SNDRV_PCM_FMTBIT_S16_LE,
336 },
337 .capture = {
338 .channels_min = 2,
339 .channels_max = 2,
340 .rates = SNDRV_PCM_RATE_8000_96000,
341 .formats = SNDRV_PCM_FMTBIT_S16_LE,
342 },
343 .ops = &tegra_i2s_dai_ops,
344 .symmetric_rates = 1,
345 },
346};
347
348static __devinit int tegra_i2s_platform_probe(struct platform_device *pdev)
349{
350 struct tegra_i2s * i2s;
351 char clk_name[12]; /* tegra-i2s.0 */
352 struct resource *mem, *memregion, *dmareq;
353 int ret;
354
355 if ((pdev->id < 0) ||
356 (pdev->id >= ARRAY_SIZE(tegra_i2s_dai))) {
357 dev_err(&pdev->dev, "ID %d out of range\n", pdev->id);
358 return -EINVAL;
359 }
360
361 /*
362 * FIXME: Until a codec driver exists for the tegra DAS, hard-code a
363 * 1:1 mapping between audio controllers and audio ports.
364 */
365 ret = tegra_das_connect_dap_to_dac(TEGRA_DAS_DAP_ID_1 + pdev->id,
366 TEGRA_DAS_DAP_SEL_DAC1 + pdev->id);
367 if (ret) {
368 dev_err(&pdev->dev, "Can't set up DAP connection\n");
369 return ret;
370 }
371 ret = tegra_das_connect_dac_to_dap(TEGRA_DAS_DAC_ID_1 + pdev->id,
372 TEGRA_DAS_DAC_SEL_DAP1 + pdev->id);
373 if (ret) {
374 dev_err(&pdev->dev, "Can't set up DAC connection\n");
375 return ret;
376 }
377
378 i2s = kzalloc(sizeof(struct tegra_i2s), GFP_KERNEL);
379 if (!i2s) {
380 dev_err(&pdev->dev, "Can't allocate tegra_i2s\n");
381 ret = -ENOMEM;
382 goto exit;
383 }
384 dev_set_drvdata(&pdev->dev, i2s);
385
386 snprintf(clk_name, sizeof(clk_name), DRV_NAME ".%d", pdev->id);
387 i2s->clk_i2s = clk_get_sys(clk_name, NULL);
388 if (IS_ERR(i2s->clk_i2s)) {
389 dev_err(&pdev->dev, "Can't retrieve i2s clock\n");
390 ret = PTR_ERR(i2s->clk_i2s);
391 goto err_free;
392 }
393
394 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
395 if (!mem) {
396 dev_err(&pdev->dev, "No memory resource\n");
397 ret = -ENODEV;
398 goto err_clk_put;
399 }
400
401 dmareq = platform_get_resource(pdev, IORESOURCE_DMA, 0);
402 if (!dmareq) {
403 dev_err(&pdev->dev, "No DMA resource\n");
404 ret = -ENODEV;
405 goto err_clk_put;
406 }
407
408 memregion = request_mem_region(mem->start, resource_size(mem),
409 DRV_NAME);
410 if (!memregion) {
411 dev_err(&pdev->dev, "Memory region already claimed\n");
412 ret = -EBUSY;
413 goto err_clk_put;
414 }
415
416 i2s->regs = ioremap(mem->start, resource_size(mem));
417 if (!i2s->regs) {
418 dev_err(&pdev->dev, "ioremap failed\n");
419 ret = -ENOMEM;
420 goto err_release;
421 }
422
423 i2s->capture_dma_data.addr = mem->start + TEGRA_I2S_FIFO2;
424 i2s->capture_dma_data.wrap = 4;
425 i2s->capture_dma_data.width = 32;
426 i2s->capture_dma_data.req_sel = dmareq->start;
427
428 i2s->playback_dma_data.addr = mem->start + TEGRA_I2S_FIFO1;
429 i2s->playback_dma_data.wrap = 4;
430 i2s->playback_dma_data.width = 32;
431 i2s->playback_dma_data.req_sel = dmareq->start;
432
433 i2s->reg_ctrl = TEGRA_I2S_CTRL_FIFO_FORMAT_PACKED;
434
435 ret = snd_soc_register_dai(&pdev->dev, &tegra_i2s_dai[pdev->id]);
436 if (ret) {
437 dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
438 ret = -ENOMEM;
439 goto err_unmap;
440 }
441
442 tegra_i2s_debug_add(i2s, pdev->id);
443
444 return 0;
445
446err_unmap:
447 iounmap(i2s->regs);
448err_release:
449 release_mem_region(mem->start, resource_size(mem));
450err_clk_put:
451 clk_put(i2s->clk_i2s);
452err_free:
453 kfree(i2s);
454exit:
455 return ret;
456}
457
458static int __devexit tegra_i2s_platform_remove(struct platform_device *pdev)
459{
460 struct tegra_i2s *i2s = dev_get_drvdata(&pdev->dev);
461 struct resource *res;
462
463 snd_soc_unregister_dai(&pdev->dev);
464
465 tegra_i2s_debug_remove(i2s);
466
467 iounmap(i2s->regs);
468
469 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
470 release_mem_region(res->start, resource_size(res));
471
472 clk_put(i2s->clk_i2s);
473
474 kfree(i2s);
475
476 return 0;
477}
478
479static struct platform_driver tegra_i2s_driver = {
480 .driver = {
481 .name = DRV_NAME,
482 .owner = THIS_MODULE,
483 },
484 .probe = tegra_i2s_platform_probe,
485 .remove = __devexit_p(tegra_i2s_platform_remove),
486};
487
488static int __init snd_tegra_i2s_init(void)
489{
490 return platform_driver_register(&tegra_i2s_driver);
491}
492module_init(snd_tegra_i2s_init);
493
494static void __exit snd_tegra_i2s_exit(void)
495{
496 platform_driver_unregister(&tegra_i2s_driver);
497}
498module_exit(snd_tegra_i2s_exit);
499
500MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
501MODULE_DESCRIPTION("Tegra I2S ASoC driver");
502MODULE_LICENSE("GPL");
503MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/tegra/tegra_i2s.h b/sound/soc/tegra/tegra_i2s.h
new file mode 100644
index 000000000000..2b38a096f46c
--- /dev/null
+++ b/sound/soc/tegra/tegra_i2s.h
@@ -0,0 +1,165 @@
1/*
2 * tegra_i2s.h - Definitions for Tegra I2S driver
3 *
4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010 - NVIDIA, Inc.
6 *
7 * Based on code copyright/by:
8 *
9 * Copyright (c) 2009-2010, NVIDIA Corporation.
10 * Scott Peterson <speterson@nvidia.com>
11 *
12 * Copyright (C) 2010 Google, Inc.
13 * Iliyan Malchev <malchev@google.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#ifndef __TEGRA_I2S_H__
32#define __TEGRA_I2S_H__
33
34#include "tegra_pcm.h"
35
36/* Register offsets from TEGRA_I2S1_BASE and TEGRA_I2S2_BASE */
37
38#define TEGRA_I2S_CTRL 0x00
39#define TEGRA_I2S_STATUS 0x04
40#define TEGRA_I2S_TIMING 0x08
41#define TEGRA_I2S_FIFO_SCR 0x0c
42#define TEGRA_I2S_PCM_CTRL 0x10
43#define TEGRA_I2S_NW_CTRL 0x14
44#define TEGRA_I2S_TDM_CTRL 0x20
45#define TEGRA_I2S_TDM_TX_RX_CTRL 0x24
46#define TEGRA_I2S_FIFO1 0x40
47#define TEGRA_I2S_FIFO2 0x80
48
49/* Fields in TEGRA_I2S_CTRL */
50
51#define TEGRA_I2S_CTRL_FIFO2_TX_ENABLE (1 << 30)
52#define TEGRA_I2S_CTRL_FIFO1_ENABLE (1 << 29)
53#define TEGRA_I2S_CTRL_FIFO2_ENABLE (1 << 28)
54#define TEGRA_I2S_CTRL_FIFO1_RX_ENABLE (1 << 27)
55#define TEGRA_I2S_CTRL_FIFO_LPBK_ENABLE (1 << 26)
56#define TEGRA_I2S_CTRL_MASTER_ENABLE (1 << 25)
57
58#define TEGRA_I2S_LRCK_LEFT_LOW 0
59#define TEGRA_I2S_LRCK_RIGHT_LOW 1
60
61#define TEGRA_I2S_CTRL_LRCK_SHIFT 24
62#define TEGRA_I2S_CTRL_LRCK_MASK (1 << TEGRA_I2S_CTRL_LRCK_SHIFT)
63#define TEGRA_I2S_CTRL_LRCK_L_LOW (TEGRA_I2S_LRCK_LEFT_LOW << TEGRA_I2S_CTRL_LRCK_SHIFT)
64#define TEGRA_I2S_CTRL_LRCK_R_LOW (TEGRA_I2S_LRCK_RIGHT_LOW << TEGRA_I2S_CTRL_LRCK_SHIFT)
65
66#define TEGRA_I2S_BIT_FORMAT_I2S 0
67#define TEGRA_I2S_BIT_FORMAT_RJM 1
68#define TEGRA_I2S_BIT_FORMAT_LJM 2
69#define TEGRA_I2S_BIT_FORMAT_DSP 3
70
71#define TEGRA_I2S_CTRL_BIT_FORMAT_SHIFT 10
72#define TEGRA_I2S_CTRL_BIT_FORMAT_MASK (3 << TEGRA_I2S_CTRL_BIT_FORMAT_SHIFT)
73#define TEGRA_I2S_CTRL_BIT_FORMAT_I2S (TEGRA_I2S_BIT_FORMAT_I2S << TEGRA_I2S_CTRL_BIT_FORMAT_SHIFT)
74#define TEGRA_I2S_CTRL_BIT_FORMAT_RJM (TEGRA_I2S_BIT_FORMAT_RJM << TEGRA_I2S_CTRL_BIT_FORMAT_SHIFT)
75#define TEGRA_I2S_CTRL_BIT_FORMAT_LJM (TEGRA_I2S_BIT_FORMAT_LJM << TEGRA_I2S_CTRL_BIT_FORMAT_SHIFT)
76#define TEGRA_I2S_CTRL_BIT_FORMAT_DSP (TEGRA_I2S_BIT_FORMAT_DSP << TEGRA_I2S_CTRL_BIT_FORMAT_SHIFT)
77
78#define TEGRA_I2S_BIT_SIZE_16 0
79#define TEGRA_I2S_BIT_SIZE_20 1
80#define TEGRA_I2S_BIT_SIZE_24 2
81#define TEGRA_I2S_BIT_SIZE_32 3
82
83#define TEGRA_I2S_CTRL_BIT_SIZE_SHIFT 8
84#define TEGRA_I2S_CTRL_BIT_SIZE_MASK (3 << TEGRA_I2S_CTRL_BIT_SIZE_SHIFT)
85#define TEGRA_I2S_CTRL_BIT_SIZE_16 (TEGRA_I2S_BIT_SIZE_16 << TEGRA_I2S_CTRL_BIT_SIZE_SHIFT)
86#define TEGRA_I2S_CTRL_BIT_SIZE_20 (TEGRA_I2S_BIT_SIZE_20 << TEGRA_I2S_CTRL_BIT_SIZE_SHIFT)
87#define TEGRA_I2S_CTRL_BIT_SIZE_24 (TEGRA_I2S_BIT_SIZE_24 << TEGRA_I2S_CTRL_BIT_SIZE_SHIFT)
88#define TEGRA_I2S_CTRL_BIT_SIZE_32 (TEGRA_I2S_BIT_SIZE_32 << TEGRA_I2S_CTRL_BIT_SIZE_SHIFT)
89
90#define TEGRA_I2S_FIFO_16_LSB 0
91#define TEGRA_I2S_FIFO_20_LSB 1
92#define TEGRA_I2S_FIFO_24_LSB 2
93#define TEGRA_I2S_FIFO_32 3
94#define TEGRA_I2S_FIFO_PACKED 7
95
96#define TEGRA_I2S_CTRL_FIFO_FORMAT_SHIFT 4
97#define TEGRA_I2S_CTRL_FIFO_FORMAT_MASK (7 << TEGRA_I2S_CTRL_FIFO_FORMAT_SHIFT)
98#define TEGRA_I2S_CTRL_FIFO_FORMAT_16_LSB (TEGRA_I2S_FIFO_16_LSB << TEGRA_I2S_CTRL_FIFO_FORMAT_SHIFT)
99#define TEGRA_I2S_CTRL_FIFO_FORMAT_20_LSB (TEGRA_I2S_FIFO_20_LSB << TEGRA_I2S_CTRL_FIFO_FORMAT_SHIFT)
100#define TEGRA_I2S_CTRL_FIFO_FORMAT_24_LSB (TEGRA_I2S_FIFO_24_LSB << TEGRA_I2S_CTRL_FIFO_FORMAT_SHIFT)
101#define TEGRA_I2S_CTRL_FIFO_FORMAT_32 (TEGRA_I2S_FIFO_32 << TEGRA_I2S_CTRL_FIFO_FORMAT_SHIFT)
102#define TEGRA_I2S_CTRL_FIFO_FORMAT_PACKED (TEGRA_I2S_FIFO_PACKED << TEGRA_I2S_CTRL_FIFO_FORMAT_SHIFT)
103
104#define TEGRA_I2S_CTRL_IE_FIFO1_ERR (1 << 3)
105#define TEGRA_I2S_CTRL_IE_FIFO2_ERR (1 << 2)
106#define TEGRA_I2S_CTRL_QE_FIFO1 (1 << 1)
107#define TEGRA_I2S_CTRL_QE_FIFO2 (1 << 0)
108
109/* Fields in TEGRA_I2S_STATUS */
110
111#define TEGRA_I2S_STATUS_FIFO1_RDY (1 << 31)
112#define TEGRA_I2S_STATUS_FIFO2_RDY (1 << 30)
113#define TEGRA_I2S_STATUS_FIFO1_BSY (1 << 29)
114#define TEGRA_I2S_STATUS_FIFO2_BSY (1 << 28)
115#define TEGRA_I2S_STATUS_FIFO1_ERR (1 << 3)
116#define TEGRA_I2S_STATUS_FIFO2_ERR (1 << 2)
117#define TEGRA_I2S_STATUS_QS_FIFO1 (1 << 1)
118#define TEGRA_I2S_STATUS_QS_FIFO2 (1 << 0)
119
120/* Fields in TEGRA_I2S_TIMING */
121
122#define TEGRA_I2S_TIMING_NON_SYM_ENABLE (1 << 12)
123#define TEGRA_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT 0
124#define TEGRA_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US 0x7fff
125#define TEGRA_I2S_TIMING_CHANNEL_BIT_COUNT_MASK (TEGRA_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US << TEGRA_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT)
126
127/* Fields in TEGRA_I2S_FIFO_SCR */
128
129#define TEGRA_I2S_FIFO_SCR_FIFO2_FULL_EMPTY_COUNT_SHIFT 24
130#define TEGRA_I2S_FIFO_SCR_FIFO1_FULL_EMPTY_COUNT_SHIFT 16
131#define TEGRA_I2S_FIFO_SCR_FIFO_FULL_EMPTY_COUNT_MASK 0x3f
132
133#define TEGRA_I2S_FIFO_SCR_FIFO2_CLR (1 << 12)
134#define TEGRA_I2S_FIFO_SCR_FIFO1_CLR (1 << 8)
135
136#define TEGRA_I2S_FIFO_ATN_LVL_ONE_SLOT 0
137#define TEGRA_I2S_FIFO_ATN_LVL_FOUR_SLOTS 1
138#define TEGRA_I2S_FIFO_ATN_LVL_EIGHT_SLOTS 2
139#define TEGRA_I2S_FIFO_ATN_LVL_TWELVE_SLOTS 3
140
141#define TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_SHIFT 4
142#define TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_MASK (3 << TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_SHIFT)
143#define TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_ONE_SLOT (TEGRA_I2S_FIFO_ATN_LVL_ONE_SLOT << TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_SHIFT)
144#define TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_FOUR_SLOTS (TEGRA_I2S_FIFO_ATN_LVL_FOUR_SLOTS << TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_SHIFT)
145#define TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_EIGHT_SLOTS (TEGRA_I2S_FIFO_ATN_LVL_EIGHT_SLOTS << TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_SHIFT)
146#define TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_TWELVE_SLOTS (TEGRA_I2S_FIFO_ATN_LVL_TWELVE_SLOTS << TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_SHIFT)
147
148#define TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT 0
149#define TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_MASK (3 << TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT)
150#define TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_ONE_SLOT (TEGRA_I2S_FIFO_ATN_LVL_ONE_SLOT << TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT)
151#define TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_FOUR_SLOTS (TEGRA_I2S_FIFO_ATN_LVL_FOUR_SLOTS << TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT)
152#define TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_EIGHT_SLOTS (TEGRA_I2S_FIFO_ATN_LVL_EIGHT_SLOTS << TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT)
153#define TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_TWELVE_SLOTS (TEGRA_I2S_FIFO_ATN_LVL_TWELVE_SLOTS << TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT)
154
155struct tegra_i2s {
156 struct clk *clk_i2s;
157 int clk_refs;
158 struct tegra_pcm_dma_params capture_dma_data;
159 struct tegra_pcm_dma_params playback_dma_data;
160 void __iomem *regs;
161 struct dentry *debug;
162 u32 reg_ctrl;
163};
164
165#endif
diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c
new file mode 100644
index 000000000000..3c271f953582
--- /dev/null
+++ b/sound/soc/tegra/tegra_pcm.c
@@ -0,0 +1,404 @@
1/*
2 * tegra_pcm.c - Tegra PCM driver
3 *
4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010 - NVIDIA, Inc.
6 *
7 * Based on code copyright/by:
8 *
9 * Copyright (c) 2009-2010, NVIDIA Corporation.
10 * Scott Peterson <speterson@nvidia.com>
11 * Vijay Mali <vmali@nvidia.com>
12 *
13 * Copyright (C) 2010 Google, Inc.
14 * Iliyan Malchev <malchev@google.com>
15 *
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * version 2 as published by the Free Software Foundation.
19 *
20 * This program is distributed in the hope that it will be useful, but
21 * WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 * General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
28 * 02110-1301 USA
29 *
30 */
31
32#include <linux/module.h>
33#include <linux/dma-mapping.h>
34#include <linux/slab.h>
35#include <sound/core.h>
36#include <sound/pcm.h>
37#include <sound/pcm_params.h>
38#include <sound/soc.h>
39
40#include "tegra_pcm.h"
41
42#define DRV_NAME "tegra-pcm-audio"
43
44static const struct snd_pcm_hardware tegra_pcm_hardware = {
45 .info = SNDRV_PCM_INFO_MMAP |
46 SNDRV_PCM_INFO_MMAP_VALID |
47 SNDRV_PCM_INFO_PAUSE |
48 SNDRV_PCM_INFO_RESUME |
49 SNDRV_PCM_INFO_INTERLEAVED,
50 .formats = SNDRV_PCM_FMTBIT_S16_LE,
51 .channels_min = 2,
52 .channels_max = 2,
53 .period_bytes_min = 1024,
54 .period_bytes_max = PAGE_SIZE,
55 .periods_min = 2,
56 .periods_max = 8,
57 .buffer_bytes_max = PAGE_SIZE * 8,
58 .fifo_size = 4,
59};
60
61static void tegra_pcm_queue_dma(struct tegra_runtime_data *prtd)
62{
63 struct snd_pcm_substream *substream = prtd->substream;
64 struct snd_dma_buffer *buf = &substream->dma_buffer;
65 struct tegra_dma_req *dma_req;
66 unsigned long addr;
67
68 dma_req = &prtd->dma_req[prtd->dma_req_idx];
69 prtd->dma_req_idx = 1 - prtd->dma_req_idx;
70
71 addr = buf->addr + prtd->dma_pos;
72 prtd->dma_pos += dma_req->size;
73 if (prtd->dma_pos >= prtd->dma_pos_end)
74 prtd->dma_pos = 0;
75
76 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
77 dma_req->source_addr = addr;
78 else
79 dma_req->dest_addr = addr;
80
81 tegra_dma_enqueue_req(prtd->dma_chan, dma_req);
82}
83
84static void dma_complete_callback(struct tegra_dma_req *req)
85{
86 struct tegra_runtime_data *prtd = (struct tegra_runtime_data *)req->dev;
87 struct snd_pcm_substream *substream = prtd->substream;
88 struct snd_pcm_runtime *runtime = substream->runtime;
89
90 spin_lock(&prtd->lock);
91
92 if (!prtd->running) {
93 spin_unlock(&prtd->lock);
94 return;
95 }
96
97 if (++prtd->period_index >= runtime->periods)
98 prtd->period_index = 0;
99
100 tegra_pcm_queue_dma(prtd);
101
102 spin_unlock(&prtd->lock);
103
104 snd_pcm_period_elapsed(substream);
105}
106
107static void setup_dma_tx_request(struct tegra_dma_req *req,
108 struct tegra_pcm_dma_params * dmap)
109{
110 req->complete = dma_complete_callback;
111 req->to_memory = false;
112 req->dest_addr = dmap->addr;
113 req->dest_wrap = dmap->wrap;
114 req->source_bus_width = 32;
115 req->source_wrap = 0;
116 req->dest_bus_width = dmap->width;
117 req->req_sel = dmap->req_sel;
118}
119
120static void setup_dma_rx_request(struct tegra_dma_req *req,
121 struct tegra_pcm_dma_params * dmap)
122{
123 req->complete = dma_complete_callback;
124 req->to_memory = true;
125 req->source_addr = dmap->addr;
126 req->dest_wrap = 0;
127 req->source_bus_width = dmap->width;
128 req->source_wrap = dmap->wrap;
129 req->dest_bus_width = 32;
130 req->req_sel = dmap->req_sel;
131}
132
133static int tegra_pcm_open(struct snd_pcm_substream *substream)
134{
135 struct snd_pcm_runtime *runtime = substream->runtime;
136 struct tegra_runtime_data *prtd;
137 struct snd_soc_pcm_runtime *rtd = substream->private_data;
138 struct tegra_pcm_dma_params * dmap;
139 int ret = 0;
140
141 prtd = kzalloc(sizeof(struct tegra_runtime_data), GFP_KERNEL);
142 if (prtd == NULL)
143 return -ENOMEM;
144
145 runtime->private_data = prtd;
146 prtd->substream = substream;
147
148 spin_lock_init(&prtd->lock);
149
150 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
151 dmap = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
152 setup_dma_tx_request(&prtd->dma_req[0], dmap);
153 setup_dma_tx_request(&prtd->dma_req[1], dmap);
154 } else {
155 dmap = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
156 setup_dma_rx_request(&prtd->dma_req[0], dmap);
157 setup_dma_rx_request(&prtd->dma_req[1], dmap);
158 }
159
160 prtd->dma_req[0].dev = prtd;
161 prtd->dma_req[1].dev = prtd;
162
163 prtd->dma_chan = tegra_dma_allocate_channel(TEGRA_DMA_MODE_ONESHOT);
164 if (prtd->dma_chan == NULL) {
165 ret = -ENOMEM;
166 goto err;
167 }
168
169 /* Set HW params now that initialization is complete */
170 snd_soc_set_runtime_hwparams(substream, &tegra_pcm_hardware);
171
172 /* Ensure that buffer size is a multiple of period size */
173 ret = snd_pcm_hw_constraint_integer(runtime,
174 SNDRV_PCM_HW_PARAM_PERIODS);
175 if (ret < 0)
176 goto err;
177
178 return 0;
179
180err:
181 if (prtd->dma_chan) {
182 tegra_dma_free_channel(prtd->dma_chan);
183 }
184
185 kfree(prtd);
186
187 return ret;
188}
189
190static int tegra_pcm_close(struct snd_pcm_substream *substream)
191{
192 struct snd_pcm_runtime *runtime = substream->runtime;
193 struct tegra_runtime_data *prtd = runtime->private_data;
194
195 tegra_dma_free_channel(prtd->dma_chan);
196
197 kfree(prtd);
198
199 return 0;
200}
201
202static int tegra_pcm_hw_params(struct snd_pcm_substream *substream,
203 struct snd_pcm_hw_params *params)
204{
205 struct snd_pcm_runtime *runtime = substream->runtime;
206 struct tegra_runtime_data *prtd = runtime->private_data;
207
208 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
209
210 prtd->dma_req[0].size = params_period_bytes(params);
211 prtd->dma_req[1].size = prtd->dma_req[0].size;
212
213 return 0;
214}
215
216static int tegra_pcm_hw_free(struct snd_pcm_substream *substream)
217{
218 snd_pcm_set_runtime_buffer(substream, NULL);
219
220 return 0;
221}
222
223static int tegra_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
224{
225 struct snd_pcm_runtime *runtime = substream->runtime;
226 struct tegra_runtime_data *prtd = runtime->private_data;
227 unsigned long flags;
228
229 switch (cmd) {
230 case SNDRV_PCM_TRIGGER_START:
231 prtd->dma_pos = 0;
232 prtd->dma_pos_end = frames_to_bytes(runtime, runtime->periods * runtime->period_size);
233 prtd->period_index = 0;
234 prtd->dma_req_idx = 0;
235 /* Fall-through */
236 case SNDRV_PCM_TRIGGER_RESUME:
237 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
238 spin_lock_irqsave(&prtd->lock, flags);
239 prtd->running = 1;
240 spin_unlock_irqrestore(&prtd->lock, flags);
241 tegra_pcm_queue_dma(prtd);
242 tegra_pcm_queue_dma(prtd);
243 break;
244 case SNDRV_PCM_TRIGGER_STOP:
245 case SNDRV_PCM_TRIGGER_SUSPEND:
246 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
247 spin_lock_irqsave(&prtd->lock, flags);
248 prtd->running = 0;
249 spin_unlock_irqrestore(&prtd->lock, flags);
250 tegra_dma_dequeue_req(prtd->dma_chan, &prtd->dma_req[0]);
251 tegra_dma_dequeue_req(prtd->dma_chan, &prtd->dma_req[1]);
252 break;
253 default:
254 return -EINVAL;
255 }
256
257 return 0;
258}
259
260static snd_pcm_uframes_t tegra_pcm_pointer(struct snd_pcm_substream *substream)
261{
262 struct snd_pcm_runtime *runtime = substream->runtime;
263 struct tegra_runtime_data *prtd = runtime->private_data;
264
265 return prtd->period_index * runtime->period_size;
266}
267
268
269static int tegra_pcm_mmap(struct snd_pcm_substream *substream,
270 struct vm_area_struct *vma)
271{
272 struct snd_pcm_runtime *runtime = substream->runtime;
273
274 return dma_mmap_writecombine(substream->pcm->card->dev, vma,
275 runtime->dma_area,
276 runtime->dma_addr,
277 runtime->dma_bytes);
278}
279
280static struct snd_pcm_ops tegra_pcm_ops = {
281 .open = tegra_pcm_open,
282 .close = tegra_pcm_close,
283 .ioctl = snd_pcm_lib_ioctl,
284 .hw_params = tegra_pcm_hw_params,
285 .hw_free = tegra_pcm_hw_free,
286 .trigger = tegra_pcm_trigger,
287 .pointer = tegra_pcm_pointer,
288 .mmap = tegra_pcm_mmap,
289};
290
291static int tegra_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
292{
293 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
294 struct snd_dma_buffer *buf = &substream->dma_buffer;
295 size_t size = tegra_pcm_hardware.buffer_bytes_max;
296
297 buf->area = dma_alloc_writecombine(pcm->card->dev, size,
298 &buf->addr, GFP_KERNEL);
299 if (!buf->area)
300 return -ENOMEM;
301
302 buf->dev.type = SNDRV_DMA_TYPE_DEV;
303 buf->dev.dev = pcm->card->dev;
304 buf->private_data = NULL;
305 buf->bytes = size;
306
307 return 0;
308}
309
310static void tegra_pcm_deallocate_dma_buffer(struct snd_pcm *pcm, int stream)
311{
312 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
313 struct snd_dma_buffer *buf = &substream->dma_buffer;
314
315 if (!buf->area)
316 return;
317
318 dma_free_writecombine(pcm->card->dev, buf->bytes,
319 buf->area, buf->addr);
320 buf->area = NULL;
321}
322
323static u64 tegra_dma_mask = DMA_BIT_MASK(32);
324
325static int tegra_pcm_new(struct snd_card *card,
326 struct snd_soc_dai *dai, struct snd_pcm *pcm)
327{
328 int ret = 0;
329
330 if (!card->dev->dma_mask)
331 card->dev->dma_mask = &tegra_dma_mask;
332 if (!card->dev->coherent_dma_mask)
333 card->dev->coherent_dma_mask = 0xffffffff;
334
335 if (dai->driver->playback.channels_min) {
336 ret = tegra_pcm_preallocate_dma_buffer(pcm,
337 SNDRV_PCM_STREAM_PLAYBACK);
338 if (ret)
339 goto err;
340 }
341
342 if (dai->driver->capture.channels_min) {
343 ret = tegra_pcm_preallocate_dma_buffer(pcm,
344 SNDRV_PCM_STREAM_CAPTURE);
345 if (ret)
346 goto err_free_play;
347 }
348
349 return 0;
350
351err_free_play:
352 tegra_pcm_deallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_PLAYBACK);
353err:
354 return ret;
355}
356
357static void tegra_pcm_free(struct snd_pcm *pcm)
358{
359 tegra_pcm_deallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_CAPTURE);
360 tegra_pcm_deallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_PLAYBACK);
361}
362
363struct snd_soc_platform_driver tegra_pcm_platform = {
364 .ops = &tegra_pcm_ops,
365 .pcm_new = tegra_pcm_new,
366 .pcm_free = tegra_pcm_free,
367};
368
369static int __devinit tegra_pcm_platform_probe(struct platform_device *pdev)
370{
371 return snd_soc_register_platform(&pdev->dev, &tegra_pcm_platform);
372}
373
374static int __devexit tegra_pcm_platform_remove(struct platform_device *pdev)
375{
376 snd_soc_unregister_platform(&pdev->dev);
377 return 0;
378}
379
380static struct platform_driver tegra_pcm_driver = {
381 .driver = {
382 .name = DRV_NAME,
383 .owner = THIS_MODULE,
384 },
385 .probe = tegra_pcm_platform_probe,
386 .remove = __devexit_p(tegra_pcm_platform_remove),
387};
388
389static int __init snd_tegra_pcm_init(void)
390{
391 return platform_driver_register(&tegra_pcm_driver);
392}
393module_init(snd_tegra_pcm_init);
394
395static void __exit snd_tegra_pcm_exit(void)
396{
397 platform_driver_unregister(&tegra_pcm_driver);
398}
399module_exit(snd_tegra_pcm_exit);
400
401MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
402MODULE_DESCRIPTION("Tegra PCM ASoC driver");
403MODULE_LICENSE("GPL");
404MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/tegra/tegra_pcm.h b/sound/soc/tegra/tegra_pcm.h
new file mode 100644
index 000000000000..dbb90339fe0d
--- /dev/null
+++ b/sound/soc/tegra/tegra_pcm.h
@@ -0,0 +1,55 @@
1/*
2 * tegra_pcm.h - Definitions for Tegra PCM driver
3 *
4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010 - NVIDIA, Inc.
6 *
7 * Based on code copyright/by:
8 *
9 * Copyright (c) 2009-2010, NVIDIA Corporation.
10 * Scott Peterson <speterson@nvidia.com>
11 *
12 * Copyright (C) 2010 Google, Inc.
13 * Iliyan Malchev <malchev@google.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#ifndef __TEGRA_PCM_H__
32#define __TEGRA_PCM_H__
33
34#include <mach/dma.h>
35
36struct tegra_pcm_dma_params {
37 unsigned long addr;
38 unsigned long wrap;
39 unsigned long width;
40 unsigned long req_sel;
41};
42
43struct tegra_runtime_data {
44 struct snd_pcm_substream *substream;
45 spinlock_t lock;
46 int running;
47 int dma_pos;
48 int dma_pos_end;
49 int period_index;
50 int dma_req_idx;
51 struct tegra_dma_req dma_req[2];
52 struct tegra_dma_channel *dma_chan;
53};
54
55#endif
diff --git a/sound/sound_core.c b/sound/sound_core.c
index 5580aced8730..6ce277860fd7 100644
--- a/sound/sound_core.c
+++ b/sound/sound_core.c
@@ -384,6 +384,9 @@ int register_sound_special_device(const struct file_operations *fops, int unit,
384 case 4: 384 case 4:
385 name = "audio"; 385 name = "audio";
386 break; 386 break;
387 case 5:
388 name = "dspW";
389 break;
387 case 8: 390 case 8:
388 name = "sequencer2"; 391 name = "sequencer2";
389 if (unit >= SOUND_STEP) 392 if (unit >= SOUND_STEP)
diff --git a/sound/usb/6fire/Makefile b/sound/usb/6fire/Makefile
new file mode 100644
index 000000000000..dfce6ec53513
--- /dev/null
+++ b/sound/usb/6fire/Makefile
@@ -0,0 +1,3 @@
1snd-usb-6fire-objs += chip.o comm.o midi.o control.o firmware.o pcm.o
2obj-$(CONFIG_SND_USB_6FIRE) += snd-usb-6fire.o
3
diff --git a/sound/usb/6fire/chip.c b/sound/usb/6fire/chip.c
new file mode 100644
index 000000000000..c7dca7b0b9fe
--- /dev/null
+++ b/sound/usb/6fire/chip.c
@@ -0,0 +1,232 @@
1/*
2 * Linux driver for TerraTec DMX 6Fire USB
3 *
4 * Main routines and module definitions.
5 *
6 * Author: Torsten Schenk <torsten.schenk@zoho.com>
7 * Created: Jan 01, 2011
8 * Version: 0.3.0
9 * Copyright: (C) Torsten Schenk
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 */
16
17#include "chip.h"
18#include "firmware.h"
19#include "pcm.h"
20#include "control.h"
21#include "comm.h"
22#include "midi.h"
23
24#include <linux/moduleparam.h>
25#include <linux/interrupt.h>
26#include <linux/module.h>
27#include <linux/init.h>
28#include <linux/gfp.h>
29#include <sound/initval.h>
30
31MODULE_AUTHOR("Torsten Schenk <torsten.schenk@zoho.com>");
32MODULE_DESCRIPTION("TerraTec DMX 6Fire USB audio driver, version 0.3.0");
33MODULE_LICENSE("GPL v2");
34MODULE_SUPPORTED_DEVICE("{{TerraTec, DMX 6Fire USB}}");
35
36static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */
37static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for card */
38static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable card */
39static struct sfire_chip *chips[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
40static struct usb_device *devices[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
41
42module_param_array(index, int, NULL, 0444);
43MODULE_PARM_DESC(index, "Index value for the 6fire sound device");
44module_param_array(id, charp, NULL, 0444);
45MODULE_PARM_DESC(id, "ID string for the 6fire sound device.");
46module_param_array(enable, bool, NULL, 0444);
47MODULE_PARM_DESC(enable, "Enable the 6fire sound device.");
48
49static DEFINE_MUTEX(register_mutex);
50
51static void usb6fire_chip_abort(struct sfire_chip *chip)
52{
53 if (chip) {
54 if (chip->pcm)
55 usb6fire_pcm_abort(chip);
56 if (chip->midi)
57 usb6fire_midi_abort(chip);
58 if (chip->comm)
59 usb6fire_comm_abort(chip);
60 if (chip->control)
61 usb6fire_control_abort(chip);
62 if (chip->card) {
63 snd_card_disconnect(chip->card);
64 snd_card_free_when_closed(chip->card);
65 chip->card = NULL;
66 }
67 }
68}
69
70static void usb6fire_chip_destroy(struct sfire_chip *chip)
71{
72 if (chip) {
73 if (chip->pcm)
74 usb6fire_pcm_destroy(chip);
75 if (chip->midi)
76 usb6fire_midi_destroy(chip);
77 if (chip->comm)
78 usb6fire_comm_destroy(chip);
79 if (chip->control)
80 usb6fire_control_destroy(chip);
81 if (chip->card)
82 snd_card_free(chip->card);
83 }
84}
85
86static int __devinit usb6fire_chip_probe(struct usb_interface *intf,
87 const struct usb_device_id *usb_id)
88{
89 int ret;
90 int i;
91 struct sfire_chip *chip = NULL;
92 struct usb_device *device = interface_to_usbdev(intf);
93 int regidx = -1; /* index in module parameter array */
94 struct snd_card *card = NULL;
95
96 /* look if we already serve this card and return if so */
97 mutex_lock(&register_mutex);
98 for (i = 0; i < SNDRV_CARDS; i++) {
99 if (devices[i] == device) {
100 if (chips[i])
101 chips[i]->intf_count++;
102 usb_set_intfdata(intf, chips[i]);
103 mutex_unlock(&register_mutex);
104 return 0;
105 } else if (regidx < 0)
106 regidx = i;
107 }
108 if (regidx < 0) {
109 mutex_unlock(&register_mutex);
110 snd_printk(KERN_ERR PREFIX "too many cards registered.\n");
111 return -ENODEV;
112 }
113 devices[regidx] = device;
114 mutex_unlock(&register_mutex);
115
116 /* check, if firmware is present on device, upload it if not */
117 ret = usb6fire_fw_init(intf);
118 if (ret < 0)
119 return ret;
120 else if (ret == FW_NOT_READY) /* firmware update performed */
121 return 0;
122
123 /* if we are here, card can be registered in alsa. */
124 if (usb_set_interface(device, 0, 0) != 0) {
125 snd_printk(KERN_ERR PREFIX "can't set first interface.\n");
126 return -EIO;
127 }
128 ret = snd_card_create(index[regidx], id[regidx], THIS_MODULE,
129 sizeof(struct sfire_chip), &card);
130 if (ret < 0) {
131 snd_printk(KERN_ERR PREFIX "cannot create alsa card.\n");
132 return ret;
133 }
134 strcpy(card->driver, "6FireUSB");
135 strcpy(card->shortname, "TerraTec DMX6FireUSB");
136 sprintf(card->longname, "%s at %d:%d", card->shortname,
137 device->bus->busnum, device->devnum);
138 snd_card_set_dev(card, &intf->dev);
139
140 chip = card->private_data;
141 chips[regidx] = chip;
142 chip->dev = device;
143 chip->regidx = regidx;
144 chip->intf_count = 1;
145 chip->card = card;
146
147 ret = usb6fire_comm_init(chip);
148 if (ret < 0) {
149 usb6fire_chip_destroy(chip);
150 return ret;
151 }
152
153 ret = usb6fire_midi_init(chip);
154 if (ret < 0) {
155 usb6fire_chip_destroy(chip);
156 return ret;
157 }
158
159 ret = usb6fire_pcm_init(chip);
160 if (ret < 0) {
161 usb6fire_chip_destroy(chip);
162 return ret;
163 }
164
165 ret = usb6fire_control_init(chip);
166 if (ret < 0) {
167 usb6fire_chip_destroy(chip);
168 return ret;
169 }
170
171 ret = snd_card_register(card);
172 if (ret < 0) {
173 snd_printk(KERN_ERR PREFIX "cannot register card.");
174 usb6fire_chip_destroy(chip);
175 return ret;
176 }
177 usb_set_intfdata(intf, chip);
178 return 0;
179}
180
181static void usb6fire_chip_disconnect(struct usb_interface *intf)
182{
183 struct sfire_chip *chip;
184 struct snd_card *card;
185
186 chip = usb_get_intfdata(intf);
187 if (chip) { /* if !chip, fw upload has been performed */
188 card = chip->card;
189 chip->intf_count--;
190 if (!chip->intf_count) {
191 mutex_lock(&register_mutex);
192 devices[chip->regidx] = NULL;
193 chips[chip->regidx] = NULL;
194 mutex_unlock(&register_mutex);
195
196 chip->shutdown = true;
197 usb6fire_chip_abort(chip);
198 usb6fire_chip_destroy(chip);
199 }
200 }
201}
202
203static struct usb_device_id device_table[] = {
204 {
205 .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
206 .idVendor = 0x0ccd,
207 .idProduct = 0x0080
208 },
209 {}
210};
211
212MODULE_DEVICE_TABLE(usb, device_table);
213
214static struct usb_driver driver = {
215 .name = "snd-usb-6fire",
216 .probe = usb6fire_chip_probe,
217 .disconnect = usb6fire_chip_disconnect,
218 .id_table = device_table,
219};
220
221static int __init usb6fire_chip_init(void)
222{
223 return usb_register(&driver);
224}
225
226static void __exit usb6fire_chip_cleanup(void)
227{
228 usb_deregister(&driver);
229}
230
231module_init(usb6fire_chip_init);
232module_exit(usb6fire_chip_cleanup);
diff --git a/sound/usb/6fire/chip.h b/sound/usb/6fire/chip.h
new file mode 100644
index 000000000000..d11e5cb520f0
--- /dev/null
+++ b/sound/usb/6fire/chip.h
@@ -0,0 +1,32 @@
1/*
2 * Linux driver for TerraTec DMX 6Fire USB
3 *
4 * Author: Torsten Schenk <torsten.schenk@zoho.com>
5 * Created: Jan 01, 2011
6 * Version: 0.3.0
7 * Copyright: (C) Torsten Schenk
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 as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 */
14#ifndef USB6FIRE_CHIP_H
15#define USB6FIRE_CHIP_H
16
17#include "common.h"
18
19struct sfire_chip {
20 struct usb_device *dev;
21 struct snd_card *card;
22 int intf_count; /* number of registered interfaces */
23 int regidx; /* index in module parameter arrays */
24 bool shutdown;
25
26 struct midi_runtime *midi;
27 struct pcm_runtime *pcm;
28 struct control_runtime *control;
29 struct comm_runtime *comm;
30};
31#endif /* USB6FIRE_CHIP_H */
32
diff --git a/sound/usb/6fire/comm.c b/sound/usb/6fire/comm.c
new file mode 100644
index 000000000000..c994daa57af2
--- /dev/null
+++ b/sound/usb/6fire/comm.c
@@ -0,0 +1,176 @@
1/*
2 * Linux driver for TerraTec DMX 6Fire USB
3 *
4 * Device communications
5 *
6 * Author: Torsten Schenk <torsten.schenk@zoho.com>
7 * Created: Jan 01, 2011
8 * Version: 0.3.0
9 * Copyright: (C) Torsten Schenk
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 */
16
17#include "comm.h"
18#include "chip.h"
19#include "midi.h"
20
21enum {
22 COMM_EP = 1,
23 COMM_FPGA_EP = 2
24};
25
26static void usb6fire_comm_init_urb(struct comm_runtime *rt, struct urb *urb,
27 u8 *buffer, void *context, void(*handler)(struct urb *urb))
28{
29 usb_init_urb(urb);
30 urb->transfer_buffer = buffer;
31 urb->pipe = usb_sndintpipe(rt->chip->dev, COMM_EP);
32 urb->complete = handler;
33 urb->context = context;
34 urb->interval = 1;
35 urb->dev = rt->chip->dev;
36}
37
38static void usb6fire_comm_receiver_handler(struct urb *urb)
39{
40 struct comm_runtime *rt = urb->context;
41 struct midi_runtime *midi_rt = rt->chip->midi;
42
43 if (!urb->status) {
44 if (rt->receiver_buffer[0] == 0x10) /* midi in event */
45 if (midi_rt)
46 midi_rt->in_received(midi_rt,
47 rt->receiver_buffer + 2,
48 rt->receiver_buffer[1]);
49 }
50
51 if (!rt->chip->shutdown) {
52 urb->status = 0;
53 urb->actual_length = 0;
54 if (usb_submit_urb(urb, GFP_ATOMIC) < 0)
55 snd_printk(KERN_WARNING PREFIX
56 "comm data receiver aborted.\n");
57 }
58}
59
60static void usb6fire_comm_init_buffer(u8 *buffer, u8 id, u8 request,
61 u8 reg, u8 vl, u8 vh)
62{
63 buffer[0] = 0x01;
64 buffer[2] = request;
65 buffer[3] = id;
66 switch (request) {
67 case 0x02:
68 buffer[1] = 0x05; /* length (starting at buffer[2]) */
69 buffer[4] = reg;
70 buffer[5] = vl;
71 buffer[6] = vh;
72 break;
73
74 case 0x12:
75 buffer[1] = 0x0b; /* length (starting at buffer[2]) */
76 buffer[4] = 0x00;
77 buffer[5] = 0x18;
78 buffer[6] = 0x05;
79 buffer[7] = 0x00;
80 buffer[8] = 0x01;
81 buffer[9] = 0x00;
82 buffer[10] = 0x9e;
83 buffer[11] = reg;
84 buffer[12] = vl;
85 break;
86
87 case 0x20:
88 case 0x21:
89 case 0x22:
90 buffer[1] = 0x04;
91 buffer[4] = reg;
92 buffer[5] = vl;
93 break;
94 }
95}
96
97static int usb6fire_comm_send_buffer(u8 *buffer, struct usb_device *dev)
98{
99 int ret;
100 int actual_len;
101
102 ret = usb_interrupt_msg(dev, usb_sndintpipe(dev, COMM_EP),
103 buffer, buffer[1] + 2, &actual_len, HZ);
104 if (ret < 0)
105 return ret;
106 else if (actual_len != buffer[1] + 2)
107 return -EIO;
108 return 0;
109}
110
111static int usb6fire_comm_write8(struct comm_runtime *rt, u8 request,
112 u8 reg, u8 value)
113{
114 u8 buffer[13]; /* 13: maximum length of message */
115
116 usb6fire_comm_init_buffer(buffer, 0x00, request, reg, value, 0x00);
117 return usb6fire_comm_send_buffer(buffer, rt->chip->dev);
118}
119
120static int usb6fire_comm_write16(struct comm_runtime *rt, u8 request,
121 u8 reg, u8 vl, u8 vh)
122{
123 u8 buffer[13]; /* 13: maximum length of message */
124
125 usb6fire_comm_init_buffer(buffer, 0x00, request, reg, vl, vh);
126 return usb6fire_comm_send_buffer(buffer, rt->chip->dev);
127}
128
129int __devinit usb6fire_comm_init(struct sfire_chip *chip)
130{
131 struct comm_runtime *rt = kzalloc(sizeof(struct comm_runtime),
132 GFP_KERNEL);
133 struct urb *urb = &rt->receiver;
134 int ret;
135
136 if (!rt)
137 return -ENOMEM;
138
139 rt->serial = 1;
140 rt->chip = chip;
141 usb_init_urb(urb);
142 rt->init_urb = usb6fire_comm_init_urb;
143 rt->write8 = usb6fire_comm_write8;
144 rt->write16 = usb6fire_comm_write16;
145
146 /* submit an urb that receives communication data from device */
147 urb->transfer_buffer = rt->receiver_buffer;
148 urb->transfer_buffer_length = COMM_RECEIVER_BUFSIZE;
149 urb->pipe = usb_rcvintpipe(chip->dev, COMM_EP);
150 urb->dev = chip->dev;
151 urb->complete = usb6fire_comm_receiver_handler;
152 urb->context = rt;
153 urb->interval = 1;
154 ret = usb_submit_urb(urb, GFP_KERNEL);
155 if (ret < 0) {
156 kfree(rt);
157 snd_printk(KERN_ERR PREFIX "cannot create comm data receiver.");
158 return ret;
159 }
160 chip->comm = rt;
161 return 0;
162}
163
164void usb6fire_comm_abort(struct sfire_chip *chip)
165{
166 struct comm_runtime *rt = chip->comm;
167
168 if (rt)
169 usb_poison_urb(&rt->receiver);
170}
171
172void usb6fire_comm_destroy(struct sfire_chip *chip)
173{
174 kfree(chip->comm);
175 chip->comm = NULL;
176}
diff --git a/sound/usb/6fire/comm.h b/sound/usb/6fire/comm.h
new file mode 100644
index 000000000000..edc5dc84b888
--- /dev/null
+++ b/sound/usb/6fire/comm.h
@@ -0,0 +1,44 @@
1/*
2 * Linux driver for TerraTec DMX 6Fire USB
3 *
4 * Author: Torsten Schenk <torsten.schenk@zoho.com>
5 * Created: Jan 01, 2011
6 * Version: 0.3.0
7 * Copyright: (C) Torsten Schenk
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 as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 */
14#ifndef USB6FIRE_COMM_H
15#define USB6FIRE_COMM_H
16
17#include "common.h"
18
19enum /* settings for comm */
20{
21 COMM_RECEIVER_BUFSIZE = 64,
22};
23
24struct comm_runtime {
25 struct sfire_chip *chip;
26
27 struct urb receiver;
28 u8 receiver_buffer[COMM_RECEIVER_BUFSIZE];
29
30 u8 serial; /* urb serial */
31
32 void (*init_urb)(struct comm_runtime *rt, struct urb *urb, u8 *buffer,
33 void *context, void(*handler)(struct urb *urb));
34 /* writes control data to the device */
35 int (*write8)(struct comm_runtime *rt, u8 request, u8 reg, u8 value);
36 int (*write16)(struct comm_runtime *rt, u8 request, u8 reg,
37 u8 vh, u8 vl);
38};
39
40int __devinit usb6fire_comm_init(struct sfire_chip *chip);
41void usb6fire_comm_abort(struct sfire_chip *chip);
42void usb6fire_comm_destroy(struct sfire_chip *chip);
43#endif /* USB6FIRE_COMM_H */
44
diff --git a/sound/usb/6fire/common.h b/sound/usb/6fire/common.h
new file mode 100644
index 000000000000..7dbeb4a37831
--- /dev/null
+++ b/sound/usb/6fire/common.h
@@ -0,0 +1,30 @@
1/*
2 * Linux driver for TerraTec DMX 6Fire USB
3 *
4 * Author: Torsten Schenk <torsten.schenk@zoho.com>
5 * Created: Jan 01, 2011
6 * Version: 0.3.0
7 * Copyright: (C) Torsten Schenk
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 as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 */
14
15#ifndef USB6FIRE_COMMON_H
16#define USB6FIRE_COMMON_H
17
18#include <linux/slab.h>
19#include <linux/usb.h>
20#include <sound/core.h>
21
22#define PREFIX "6fire: "
23
24struct sfire_chip;
25struct midi_runtime;
26struct pcm_runtime;
27struct control_runtime;
28struct comm_runtime;
29#endif /* USB6FIRE_COMMON_H */
30
diff --git a/sound/usb/6fire/control.c b/sound/usb/6fire/control.c
new file mode 100644
index 000000000000..248463511186
--- /dev/null
+++ b/sound/usb/6fire/control.c
@@ -0,0 +1,275 @@
1/*
2 * Linux driver for TerraTec DMX 6Fire USB
3 *
4 * Mixer control
5 *
6 * Author: Torsten Schenk <torsten.schenk@zoho.com>
7 * Created: Jan 01, 2011
8 * Version: 0.3.0
9 * Copyright: (C) Torsten Schenk
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 */
16
17#include <linux/interrupt.h>
18#include <sound/control.h>
19
20#include "control.h"
21#include "comm.h"
22#include "chip.h"
23
24static char *opt_coax_texts[2] = { "Optical", "Coax" };
25static char *line_phono_texts[2] = { "Line", "Phono" };
26
27/*
28 * calculated with $value\[i\] = 128 \cdot sqrt[3]{\frac{i}{128}}$
29 * this is done because the linear values cause rapid degredation
30 * of volume in the uppermost region.
31 */
32static const u8 log_volume_table[128] = {
33 0x00, 0x19, 0x20, 0x24, 0x28, 0x2b, 0x2e, 0x30, 0x32, 0x34,
34 0x36, 0x38, 0x3a, 0x3b, 0x3d, 0x3e, 0x40, 0x41, 0x42, 0x43,
35 0x44, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e,
36 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x53, 0x54, 0x55, 0x56,
37 0x56, 0x57, 0x58, 0x58, 0x59, 0x5a, 0x5b, 0x5b, 0x5c, 0x5c,
38 0x5d, 0x5e, 0x5e, 0x5f, 0x60, 0x60, 0x61, 0x61, 0x62, 0x62,
39 0x63, 0x63, 0x64, 0x65, 0x65, 0x66, 0x66, 0x67, 0x67, 0x68,
40 0x68, 0x69, 0x69, 0x6a, 0x6a, 0x6b, 0x6b, 0x6c, 0x6c, 0x6c,
41 0x6d, 0x6d, 0x6e, 0x6e, 0x6f, 0x6f, 0x70, 0x70, 0x70, 0x71,
42 0x71, 0x72, 0x72, 0x73, 0x73, 0x73, 0x74, 0x74, 0x75, 0x75,
43 0x75, 0x76, 0x76, 0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x79,
44 0x79, 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c,
45 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7f, 0x7f };
46
47/*
48 * data that needs to be sent to device. sets up card internal stuff.
49 * values dumped from windows driver and filtered by trial'n'error.
50 */
51static const struct {
52 u8 type;
53 u8 reg;
54 u8 value;
55}
56init_data[] = {
57 { 0x22, 0x00, 0x00 }, { 0x20, 0x00, 0x08 }, { 0x22, 0x01, 0x01 },
58 { 0x20, 0x01, 0x08 }, { 0x22, 0x02, 0x00 }, { 0x20, 0x02, 0x08 },
59 { 0x22, 0x03, 0x00 }, { 0x20, 0x03, 0x08 }, { 0x22, 0x04, 0x00 },
60 { 0x20, 0x04, 0x08 }, { 0x22, 0x05, 0x01 }, { 0x20, 0x05, 0x08 },
61 { 0x22, 0x04, 0x01 }, { 0x12, 0x04, 0x00 }, { 0x12, 0x05, 0x00 },
62 { 0x12, 0x0d, 0x78 }, { 0x12, 0x21, 0x82 }, { 0x12, 0x22, 0x80 },
63 { 0x12, 0x23, 0x00 }, { 0x12, 0x06, 0x02 }, { 0x12, 0x03, 0x00 },
64 { 0x12, 0x02, 0x00 }, { 0x22, 0x03, 0x01 },
65 { 0 } /* TERMINATING ENTRY */
66};
67
68static void usb6fire_control_master_vol_update(struct control_runtime *rt)
69{
70 struct comm_runtime *comm_rt = rt->chip->comm;
71 if (comm_rt) {
72 /* set volume */
73 comm_rt->write8(comm_rt, 0x12, 0x0f, 0x7f -
74 log_volume_table[rt->master_vol]);
75 /* unmute */
76 comm_rt->write8(comm_rt, 0x12, 0x0e, 0x00);
77 }
78}
79
80static void usb6fire_control_line_phono_update(struct control_runtime *rt)
81{
82 struct comm_runtime *comm_rt = rt->chip->comm;
83 if (comm_rt) {
84 comm_rt->write8(comm_rt, 0x22, 0x02, rt->line_phono_switch);
85 comm_rt->write8(comm_rt, 0x21, 0x02, rt->line_phono_switch);
86 }
87}
88
89static void usb6fire_control_opt_coax_update(struct control_runtime *rt)
90{
91 struct comm_runtime *comm_rt = rt->chip->comm;
92 if (comm_rt) {
93 comm_rt->write8(comm_rt, 0x22, 0x00, rt->opt_coax_switch);
94 comm_rt->write8(comm_rt, 0x21, 0x00, rt->opt_coax_switch);
95 }
96}
97
98static int usb6fire_control_master_vol_info(struct snd_kcontrol *kcontrol,
99 struct snd_ctl_elem_info *uinfo)
100{
101 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
102 uinfo->count = 1;
103 uinfo->value.integer.min = 0;
104 uinfo->value.integer.max = 127;
105 return 0;
106}
107
108static int usb6fire_control_master_vol_put(struct snd_kcontrol *kcontrol,
109 struct snd_ctl_elem_value *ucontrol)
110{
111 struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
112 int changed = 0;
113 if (rt->master_vol != ucontrol->value.integer.value[0]) {
114 rt->master_vol = ucontrol->value.integer.value[0];
115 usb6fire_control_master_vol_update(rt);
116 changed = 1;
117 }
118 return changed;
119}
120
121static int usb6fire_control_master_vol_get(struct snd_kcontrol *kcontrol,
122 struct snd_ctl_elem_value *ucontrol)
123{
124 struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
125 ucontrol->value.integer.value[0] = rt->master_vol;
126 return 0;
127}
128
129static int usb6fire_control_line_phono_info(struct snd_kcontrol *kcontrol,
130 struct snd_ctl_elem_info *uinfo)
131{
132 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
133 uinfo->count = 1;
134 uinfo->value.enumerated.items = 2;
135 if (uinfo->value.enumerated.item > 1)
136 uinfo->value.enumerated.item = 1;
137 strcpy(uinfo->value.enumerated.name,
138 line_phono_texts[uinfo->value.enumerated.item]);
139 return 0;
140}
141
142static int usb6fire_control_line_phono_put(struct snd_kcontrol *kcontrol,
143 struct snd_ctl_elem_value *ucontrol)
144{
145 struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
146 int changed = 0;
147 if (rt->line_phono_switch != ucontrol->value.integer.value[0]) {
148 rt->line_phono_switch = ucontrol->value.integer.value[0];
149 usb6fire_control_line_phono_update(rt);
150 changed = 1;
151 }
152 return changed;
153}
154
155static int usb6fire_control_line_phono_get(struct snd_kcontrol *kcontrol,
156 struct snd_ctl_elem_value *ucontrol)
157{
158 struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
159 ucontrol->value.integer.value[0] = rt->line_phono_switch;
160 return 0;
161}
162
163static int usb6fire_control_opt_coax_info(struct snd_kcontrol *kcontrol,
164 struct snd_ctl_elem_info *uinfo)
165{
166 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
167 uinfo->count = 1;
168 uinfo->value.enumerated.items = 2;
169 if (uinfo->value.enumerated.item > 1)
170 uinfo->value.enumerated.item = 1;
171 strcpy(uinfo->value.enumerated.name,
172 opt_coax_texts[uinfo->value.enumerated.item]);
173 return 0;
174}
175
176static int usb6fire_control_opt_coax_put(struct snd_kcontrol *kcontrol,
177 struct snd_ctl_elem_value *ucontrol)
178{
179 struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
180 int changed = 0;
181
182 if (rt->opt_coax_switch != ucontrol->value.enumerated.item[0]) {
183 rt->opt_coax_switch = ucontrol->value.enumerated.item[0];
184 usb6fire_control_opt_coax_update(rt);
185 changed = 1;
186 }
187 return changed;
188}
189
190static int usb6fire_control_opt_coax_get(struct snd_kcontrol *kcontrol,
191 struct snd_ctl_elem_value *ucontrol)
192{
193 struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
194 ucontrol->value.enumerated.item[0] = rt->opt_coax_switch;
195 return 0;
196}
197
198static struct __devinitdata snd_kcontrol_new elements[] = {
199 {
200 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
201 .name = "Master Playback Volume",
202 .index = 0,
203 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
204 .info = usb6fire_control_master_vol_info,
205 .get = usb6fire_control_master_vol_get,
206 .put = usb6fire_control_master_vol_put
207 },
208 {
209 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
210 .name = "Line/Phono Capture Route",
211 .index = 0,
212 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
213 .info = usb6fire_control_line_phono_info,
214 .get = usb6fire_control_line_phono_get,
215 .put = usb6fire_control_line_phono_put
216 },
217 {
218 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
219 .name = "Opt/Coax Capture Route",
220 .index = 0,
221 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
222 .info = usb6fire_control_opt_coax_info,
223 .get = usb6fire_control_opt_coax_get,
224 .put = usb6fire_control_opt_coax_put
225 },
226 {}
227};
228
229int __devinit usb6fire_control_init(struct sfire_chip *chip)
230{
231 int i;
232 int ret;
233 struct control_runtime *rt = kzalloc(sizeof(struct control_runtime),
234 GFP_KERNEL);
235 struct comm_runtime *comm_rt = chip->comm;
236
237 if (!rt)
238 return -ENOMEM;
239
240 rt->chip = chip;
241
242 i = 0;
243 while (init_data[i].type) {
244 comm_rt->write8(comm_rt, init_data[i].type, init_data[i].reg,
245 init_data[i].value);
246 i++;
247 }
248
249 usb6fire_control_opt_coax_update(rt);
250 usb6fire_control_line_phono_update(rt);
251 usb6fire_control_master_vol_update(rt);
252
253 i = 0;
254 while (elements[i].name) {
255 ret = snd_ctl_add(chip->card, snd_ctl_new1(&elements[i], rt));
256 if (ret < 0) {
257 kfree(rt);
258 snd_printk(KERN_ERR PREFIX "cannot add control.\n");
259 return ret;
260 }
261 i++;
262 }
263
264 chip->control = rt;
265 return 0;
266}
267
268void usb6fire_control_abort(struct sfire_chip *chip)
269{}
270
271void usb6fire_control_destroy(struct sfire_chip *chip)
272{
273 kfree(chip->control);
274 chip->control = NULL;
275}
diff --git a/sound/usb/6fire/control.h b/sound/usb/6fire/control.h
new file mode 100644
index 000000000000..b534c777ab02
--- /dev/null
+++ b/sound/usb/6fire/control.h
@@ -0,0 +1,37 @@
1/*
2 * Linux driver for TerraTec DMX 6Fire USB
3 *
4 * Author: Torsten Schenk <torsten.schenk@zoho.com>
5 * Created: Jan 01, 2011
6 * Version: 0.3.0
7 * Copyright: (C) Torsten Schenk
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 as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 */
14
15#ifndef USB6FIRE_CONTROL_H
16#define USB6FIRE_CONTROL_H
17
18#include "common.h"
19
20enum {
21 CONTROL_MAX_ELEMENTS = 32
22};
23
24struct control_runtime {
25 struct sfire_chip *chip;
26
27 struct snd_kcontrol *element[CONTROL_MAX_ELEMENTS];
28 bool opt_coax_switch;
29 bool line_phono_switch;
30 u8 master_vol;
31};
32
33int __devinit usb6fire_control_init(struct sfire_chip *chip);
34void usb6fire_control_abort(struct sfire_chip *chip);
35void usb6fire_control_destroy(struct sfire_chip *chip);
36#endif /* USB6FIRE_CONTROL_H */
37
diff --git a/sound/usb/6fire/firmware.c b/sound/usb/6fire/firmware.c
new file mode 100644
index 000000000000..9081a54a9c6c
--- /dev/null
+++ b/sound/usb/6fire/firmware.c
@@ -0,0 +1,426 @@
1/*
2 * Linux driver for TerraTec DMX 6Fire USB
3 *
4 * Firmware loader
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>
13 * Created: Jan 01, 2011
14 * Version: 0.3.0
15 * Copyright: (C) Torsten Schenk
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
21 */
22
23#include <linux/firmware.h>
24
25#include "firmware.h"
26#include "chip.h"
27
28MODULE_FIRMWARE("6fire/dmx6firel2.ihx");
29MODULE_FIRMWARE("6fire/dmx6fireap.ihx");
30MODULE_FIRMWARE("6fire/dmx6firecf.bin");
31
32enum {
33 FPGA_BUFSIZE = 512, FPGA_EP = 2
34};
35
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/*
63 * wMaxPacketSize of pcm endpoints.
64 * keep synced with rates_in_packet_size and rates_out_packet_size in pcm.c
65 * fpp: frames per isopacket
66 *
67 * CAUTION: keep sizeof <= buffer[] in usb6fire_fw_init
68 */
69static const u8 ep_w_max_packet_size[] = {
70 0xe4, 0x00, 0xe4, 0x00, /* alt 1: 228 EP2 and EP6 (7 fpp) */
71 0xa4, 0x01, 0xa4, 0x01, /* alt 2: 420 EP2 and EP6 (13 fpp)*/
72 0x94, 0x01, 0x5c, 0x02 /* alt 3: 404 EP2 and 604 EP6 (25 fpp) */
73};
74
75struct ihex_record {
76 u16 address;
77 u8 len;
78 u8 data[256];
79 char error; /* true if an error occured parsing this record */
80
81 u8 max_len; /* maximum record length in whole ihex */
82
83 /* private */
84 const char *txt_data;
85 unsigned int txt_length;
86 unsigned int txt_offset; /* current position in txt_data */
87};
88
89static u8 usb6fire_fw_ihex_nibble(const u8 n)
90{
91 if (n >= '0' && n <= '9')
92 return n - '0';
93 else if (n >= 'A' && n <= 'F')
94 return n - ('A' - 10);
95 else if (n >= 'a' && n <= 'f')
96 return n - ('a' - 10);
97 return 0;
98}
99
100static u8 usb6fire_fw_ihex_hex(const u8 *data, u8 *crc)
101{
102 u8 val = (usb6fire_fw_ihex_nibble(data[0]) << 4) |
103 usb6fire_fw_ihex_nibble(data[1]);
104 *crc += val;
105 return val;
106}
107
108/*
109 * returns true if record is available, false otherwise.
110 * iff an error occured, false will be returned and record->error will be true.
111 */
112static bool usb6fire_fw_ihex_next_record(struct ihex_record *record)
113{
114 u8 crc = 0;
115 u8 type;
116 int i;
117
118 record->error = false;
119
120 /* find begin of record (marked by a colon) */
121 while (record->txt_offset < record->txt_length
122 && record->txt_data[record->txt_offset] != ':')
123 record->txt_offset++;
124 if (record->txt_offset == record->txt_length)
125 return false;
126
127 /* number of characters needed for len, addr and type entries */
128 record->txt_offset++;
129 if (record->txt_offset + 8 > record->txt_length) {
130 record->error = true;
131 return false;
132 }
133
134 record->len = usb6fire_fw_ihex_hex(record->txt_data +
135 record->txt_offset, &crc);
136 record->txt_offset += 2;
137 record->address = usb6fire_fw_ihex_hex(record->txt_data +
138 record->txt_offset, &crc) << 8;
139 record->txt_offset += 2;
140 record->address |= usb6fire_fw_ihex_hex(record->txt_data +
141 record->txt_offset, &crc);
142 record->txt_offset += 2;
143 type = usb6fire_fw_ihex_hex(record->txt_data +
144 record->txt_offset, &crc);
145 record->txt_offset += 2;
146
147 /* number of characters needed for data and crc entries */
148 if (record->txt_offset + 2 * (record->len + 1) > record->txt_length) {
149 record->error = true;
150 return false;
151 }
152 for (i = 0; i < record->len; i++) {
153 record->data[i] = usb6fire_fw_ihex_hex(record->txt_data
154 + record->txt_offset, &crc);
155 record->txt_offset += 2;
156 }
157 usb6fire_fw_ihex_hex(record->txt_data + record->txt_offset, &crc);
158 if (crc) {
159 record->error = true;
160 return false;
161 }
162
163 if (type == 1 || !record->len) /* eof */
164 return false;
165 else if (type == 0)
166 return true;
167 else {
168 record->error = true;
169 return false;
170 }
171}
172
173static int usb6fire_fw_ihex_init(const struct firmware *fw,
174 struct ihex_record *record)
175{
176 record->txt_data = fw->data;
177 record->txt_length = fw->size;
178 record->txt_offset = 0;
179 record->max_len = 0;
180 /* read all records, if loop ends, record->error indicates,
181 * whether ihex is valid. */
182 while (usb6fire_fw_ihex_next_record(record))
183 record->max_len = max(record->len, record->max_len);
184 if (record->error)
185 return -EINVAL;
186 record->txt_offset = 0;
187 return 0;
188}
189
190static int usb6fire_fw_ezusb_write(struct usb_device *device,
191 int type, int value, char *data, int len)
192{
193 int ret;
194
195 ret = usb_control_msg(device, usb_sndctrlpipe(device, 0), type,
196 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
197 value, 0, data, len, HZ);
198 if (ret < 0)
199 return ret;
200 else if (ret != len)
201 return -EIO;
202 return 0;
203}
204
205static int usb6fire_fw_ezusb_read(struct usb_device *device,
206 int type, int value, char *data, int len)
207{
208 int ret = usb_control_msg(device, usb_rcvctrlpipe(device, 0), type,
209 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, value,
210 0, data, len, HZ);
211 if (ret < 0)
212 return ret;
213 else if (ret != len)
214 return -EIO;
215 return 0;
216}
217
218static int usb6fire_fw_fpga_write(struct usb_device *device,
219 char *data, int len)
220{
221 int actual_len;
222 int ret;
223
224 ret = usb_bulk_msg(device, usb_sndbulkpipe(device, FPGA_EP), data, len,
225 &actual_len, HZ);
226 if (ret < 0)
227 return ret;
228 else if (actual_len != len)
229 return -EIO;
230 return 0;
231}
232
233static int usb6fire_fw_ezusb_upload(
234 struct usb_interface *intf, const char *fwname,
235 unsigned int postaddr, u8 *postdata, unsigned int postlen)
236{
237 int ret;
238 u8 data;
239 struct usb_device *device = interface_to_usbdev(intf);
240 const struct firmware *fw = 0;
241 struct ihex_record *rec = kmalloc(sizeof(struct ihex_record),
242 GFP_KERNEL);
243
244 if (!rec)
245 return -ENOMEM;
246
247 ret = request_firmware(&fw, fwname, &device->dev);
248 if (ret < 0) {
249 kfree(rec);
250 snd_printk(KERN_ERR PREFIX "error requesting ezusb "
251 "firmware %s.\n", fwname);
252 return ret;
253 }
254 ret = usb6fire_fw_ihex_init(fw, rec);
255 if (ret < 0) {
256 kfree(rec);
257 snd_printk(KERN_ERR PREFIX "error validating ezusb "
258 "firmware %s.\n", fwname);
259 return ret;
260 }
261 /* upload firmware image */
262 data = 0x01; /* stop ezusb cpu */
263 ret = usb6fire_fw_ezusb_write(device, 0xa0, 0xe600, &data, 1);
264 if (ret < 0) {
265 kfree(rec);
266 release_firmware(fw);
267 snd_printk(KERN_ERR PREFIX "unable to upload ezusb "
268 "firmware %s: begin message.\n", fwname);
269 return ret;
270 }
271
272 while (usb6fire_fw_ihex_next_record(rec)) { /* write firmware */
273 ret = usb6fire_fw_ezusb_write(device, 0xa0, rec->address,
274 rec->data, rec->len);
275 if (ret < 0) {
276 kfree(rec);
277 release_firmware(fw);
278 snd_printk(KERN_ERR PREFIX "unable to upload ezusb "
279 "firmware %s: data urb.\n", fwname);
280 return ret;
281 }
282 }
283
284 release_firmware(fw);
285 kfree(rec);
286 if (postdata) { /* write data after firmware has been uploaded */
287 ret = usb6fire_fw_ezusb_write(device, 0xa0, postaddr,
288 postdata, postlen);
289 if (ret < 0) {
290 snd_printk(KERN_ERR PREFIX "unable to upload ezusb "
291 "firmware %s: post urb.\n", fwname);
292 return ret;
293 }
294 }
295
296 data = 0x00; /* resume ezusb cpu */
297 ret = usb6fire_fw_ezusb_write(device, 0xa0, 0xe600, &data, 1);
298 if (ret < 0) {
299 release_firmware(fw);
300 snd_printk(KERN_ERR PREFIX "unable to upload ezusb "
301 "firmware %s: end message.\n", fwname);
302 return ret;
303 }
304 return 0;
305}
306
307static int usb6fire_fw_fpga_upload(
308 struct usb_interface *intf, const char *fwname)
309{
310 int ret;
311 int i;
312 struct usb_device *device = interface_to_usbdev(intf);
313 u8 *buffer = kmalloc(FPGA_BUFSIZE, GFP_KERNEL);
314 const char *c;
315 const char *end;
316 const struct firmware *fw;
317
318 if (!buffer)
319 return -ENOMEM;
320
321 ret = request_firmware(&fw, fwname, &device->dev);
322 if (ret < 0) {
323 snd_printk(KERN_ERR PREFIX "unable to get fpga firmware %s.\n",
324 fwname);
325 kfree(buffer);
326 return -EIO;
327 }
328
329 c = fw->data;
330 end = fw->data + fw->size;
331
332 ret = usb6fire_fw_ezusb_write(device, 8, 0, NULL, 0);
333 if (ret < 0) {
334 kfree(buffer);
335 release_firmware(fw);
336 snd_printk(KERN_ERR PREFIX "unable to upload fpga firmware: "
337 "begin urb.\n");
338 return ret;
339 }
340
341 while (c != end) {
342 for (i = 0; c != end && i < FPGA_BUFSIZE; i++, c++)
343 buffer[i] = BIT_REVERSE_TABLE[(u8) *c];
344
345 ret = usb6fire_fw_fpga_write(device, buffer, i);
346 if (ret < 0) {
347 release_firmware(fw);
348 kfree(buffer);
349 snd_printk(KERN_ERR PREFIX "unable to upload fpga "
350 "firmware: fw urb.\n");
351 return ret;
352 }
353 }
354 release_firmware(fw);
355 kfree(buffer);
356
357 ret = usb6fire_fw_ezusb_write(device, 9, 0, NULL, 0);
358 if (ret < 0) {
359 snd_printk(KERN_ERR PREFIX "unable to upload fpga firmware: "
360 "end urb.\n");
361 return ret;
362 }
363 return 0;
364}
365
366int usb6fire_fw_init(struct usb_interface *intf)
367{
368 int i;
369 int ret;
370 struct usb_device *device = interface_to_usbdev(intf);
371 /* buffer: 8 receiving bytes from device and
372 * sizeof(EP_W_MAX_PACKET_SIZE) bytes for non-const copy */
373 u8 buffer[12];
374
375 ret = usb6fire_fw_ezusb_read(device, 1, 0, buffer, 8);
376 if (ret < 0) {
377 snd_printk(KERN_ERR PREFIX "unable to receive device "
378 "firmware state.\n");
379 return ret;
380 }
381 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 "
385 "received from device: ");
386 for (i = 0; i < 8; i++)
387 snd_printk("%02x ", buffer[i]);
388 snd_printk("\n");
389 return -EIO;
390 }
391 /* do we need fpga loader ezusb firmware? */
392 if (buffer[3] == 0x01 && buffer[6] == 0x19) {
393 ret = usb6fire_fw_ezusb_upload(intf,
394 "6fire/dmx6firel2.ihx", 0, NULL, 0);
395 if (ret < 0)
396 return ret;
397 return FW_NOT_READY;
398 }
399 /* do we need fpga firmware and application ezusb firmware? */
400 else if (buffer[3] == 0x02 && buffer[6] == 0x0b) {
401 ret = usb6fire_fw_fpga_upload(intf, "6fire/dmx6firecf.bin");
402 if (ret < 0)
403 return ret;
404 memcpy(buffer, ep_w_max_packet_size,
405 sizeof(ep_w_max_packet_size));
406 ret = usb6fire_fw_ezusb_upload(intf, "6fire/dmx6fireap.ihx",
407 0x0003, buffer, sizeof(ep_w_max_packet_size));
408 if (ret < 0)
409 return ret;
410 return FW_NOT_READY;
411 }
412 /* all fw loaded? */
413 else if (buffer[3] == 0x03 && buffer[6] == 0x0b)
414 return 0;
415 /* unknown data? */
416 else {
417 snd_printk(KERN_ERR PREFIX "unknown device firmware state "
418 "received from device: ");
419 for (i = 0; i < 8; i++)
420 snd_printk("%02x ", buffer[i]);
421 snd_printk("\n");
422 return -EIO;
423 }
424 return 0;
425}
426
diff --git a/sound/usb/6fire/firmware.h b/sound/usb/6fire/firmware.h
new file mode 100644
index 000000000000..008569895381
--- /dev/null
+++ b/sound/usb/6fire/firmware.h
@@ -0,0 +1,27 @@
1/*
2 * Linux driver for TerraTec DMX 6Fire USB
3 *
4 * Author: Torsten Schenk
5 * Created: Jan 01, 2011
6 * Copyright: (C) Torsten Schenk
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
14#ifndef USB6FIRE_FIRMWARE_H
15#define USB6FIRE_FIRMWARE_H
16
17#include "common.h"
18
19enum /* firmware state of device */
20{
21 FW_READY = 0,
22 FW_NOT_READY = 1
23};
24
25int __devinit usb6fire_fw_init(struct usb_interface *intf);
26#endif /* USB6FIRE_FIRMWARE_H */
27
diff --git a/sound/usb/6fire/midi.c b/sound/usb/6fire/midi.c
new file mode 100644
index 000000000000..13f4509dce2b
--- /dev/null
+++ b/sound/usb/6fire/midi.c
@@ -0,0 +1,203 @@
1/*
2 * Linux driver for TerraTec DMX 6Fire USB
3 *
4 * Rawmidi driver
5 *
6 * Author: Torsten Schenk <torsten.schenk@zoho.com>
7 * Created: Jan 01, 2011
8 * Version: 0.3.0
9 * Copyright: (C) Torsten Schenk
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 */
16
17#include <sound/rawmidi.h>
18
19#include "midi.h"
20#include "chip.h"
21#include "comm.h"
22
23static void usb6fire_midi_out_handler(struct urb *urb)
24{
25 struct midi_runtime *rt = urb->context;
26 int ret;
27 unsigned long flags;
28
29 spin_lock_irqsave(&rt->out_lock, flags);
30
31 if (rt->out) {
32 ret = snd_rawmidi_transmit(rt->out, rt->out_buffer + 4,
33 MIDI_BUFSIZE - 4);
34 if (ret > 0) { /* more data available, send next packet */
35 rt->out_buffer[1] = ret + 2;
36 rt->out_buffer[3] = rt->out_serial++;
37 urb->transfer_buffer_length = ret + 4;
38
39 ret = usb_submit_urb(urb, GFP_ATOMIC);
40 if (ret < 0)
41 snd_printk(KERN_ERR PREFIX "midi out urb "
42 "submit failed: %d\n", ret);
43 } else /* no more data to transmit */
44 rt->out = NULL;
45 }
46 spin_unlock_irqrestore(&rt->out_lock, flags);
47}
48
49static void usb6fire_midi_in_received(
50 struct midi_runtime *rt, u8 *data, int length)
51{
52 unsigned long flags;
53
54 spin_lock_irqsave(&rt->in_lock, flags);
55 if (rt->in)
56 snd_rawmidi_receive(rt->in, data, length);
57 spin_unlock_irqrestore(&rt->in_lock, flags);
58}
59
60static int usb6fire_midi_out_open(struct snd_rawmidi_substream *alsa_sub)
61{
62 return 0;
63}
64
65static int usb6fire_midi_out_close(struct snd_rawmidi_substream *alsa_sub)
66{
67 return 0;
68}
69
70static void usb6fire_midi_out_trigger(
71 struct snd_rawmidi_substream *alsa_sub, int up)
72{
73 struct midi_runtime *rt = alsa_sub->rmidi->private_data;
74 struct urb *urb = &rt->out_urb;
75 __s8 ret;
76 unsigned long flags;
77
78 spin_lock_irqsave(&rt->out_lock, flags);
79 if (up) { /* start transfer */
80 if (rt->out) { /* we are already transmitting so just return */
81 spin_unlock_irqrestore(&rt->out_lock, flags);
82 return;
83 }
84
85 ret = snd_rawmidi_transmit(alsa_sub, rt->out_buffer + 4,
86 MIDI_BUFSIZE - 4);
87 if (ret > 0) {
88 rt->out_buffer[1] = ret + 2;
89 rt->out_buffer[3] = rt->out_serial++;
90 urb->transfer_buffer_length = ret + 4;
91
92 ret = usb_submit_urb(urb, GFP_ATOMIC);
93 if (ret < 0)
94 snd_printk(KERN_ERR PREFIX "midi out urb "
95 "submit failed: %d\n", ret);
96 else
97 rt->out = alsa_sub;
98 }
99 } else if (rt->out == alsa_sub)
100 rt->out = NULL;
101 spin_unlock_irqrestore(&rt->out_lock, flags);
102}
103
104static void usb6fire_midi_out_drain(struct snd_rawmidi_substream *alsa_sub)
105{
106 struct midi_runtime *rt = alsa_sub->rmidi->private_data;
107 int retry = 0;
108
109 while (rt->out && retry++ < 100)
110 msleep(10);
111}
112
113static int usb6fire_midi_in_open(struct snd_rawmidi_substream *alsa_sub)
114{
115 return 0;
116}
117
118static int usb6fire_midi_in_close(struct snd_rawmidi_substream *alsa_sub)
119{
120 return 0;
121}
122
123static void usb6fire_midi_in_trigger(
124 struct snd_rawmidi_substream *alsa_sub, int up)
125{
126 struct midi_runtime *rt = alsa_sub->rmidi->private_data;
127 unsigned long flags;
128
129 spin_lock_irqsave(&rt->in_lock, flags);
130 if (up)
131 rt->in = alsa_sub;
132 else
133 rt->in = NULL;
134 spin_unlock_irqrestore(&rt->in_lock, flags);
135}
136
137static struct snd_rawmidi_ops out_ops = {
138 .open = usb6fire_midi_out_open,
139 .close = usb6fire_midi_out_close,
140 .trigger = usb6fire_midi_out_trigger,
141 .drain = usb6fire_midi_out_drain
142};
143
144static struct snd_rawmidi_ops in_ops = {
145 .open = usb6fire_midi_in_open,
146 .close = usb6fire_midi_in_close,
147 .trigger = usb6fire_midi_in_trigger
148};
149
150int __devinit usb6fire_midi_init(struct sfire_chip *chip)
151{
152 int ret;
153 struct midi_runtime *rt = kzalloc(sizeof(struct midi_runtime),
154 GFP_KERNEL);
155 struct comm_runtime *comm_rt = chip->comm;
156
157 if (!rt)
158 return -ENOMEM;
159
160 rt->chip = chip;
161 rt->in_received = usb6fire_midi_in_received;
162 rt->out_buffer[0] = 0x80; /* 'send midi' command */
163 rt->out_buffer[1] = 0x00; /* size of data */
164 rt->out_buffer[2] = 0x00; /* always 0 */
165 spin_lock_init(&rt->in_lock);
166 spin_lock_init(&rt->out_lock);
167
168 comm_rt->init_urb(comm_rt, &rt->out_urb, rt->out_buffer, rt,
169 usb6fire_midi_out_handler);
170
171 ret = snd_rawmidi_new(chip->card, "6FireUSB", 0, 1, 1, &rt->instance);
172 if (ret < 0) {
173 kfree(rt);
174 snd_printk(KERN_ERR PREFIX "unable to create midi.\n");
175 return ret;
176 }
177 rt->instance->private_data = rt;
178 strcpy(rt->instance->name, "DMX6FireUSB MIDI");
179 rt->instance->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT |
180 SNDRV_RAWMIDI_INFO_INPUT |
181 SNDRV_RAWMIDI_INFO_DUPLEX;
182 snd_rawmidi_set_ops(rt->instance, SNDRV_RAWMIDI_STREAM_OUTPUT,
183 &out_ops);
184 snd_rawmidi_set_ops(rt->instance, SNDRV_RAWMIDI_STREAM_INPUT,
185 &in_ops);
186
187 chip->midi = rt;
188 return 0;
189}
190
191void usb6fire_midi_abort(struct sfire_chip *chip)
192{
193 struct midi_runtime *rt = chip->midi;
194
195 if (rt)
196 usb_poison_urb(&rt->out_urb);
197}
198
199void usb6fire_midi_destroy(struct sfire_chip *chip)
200{
201 kfree(chip->midi);
202 chip->midi = NULL;
203}
diff --git a/sound/usb/6fire/midi.h b/sound/usb/6fire/midi.h
new file mode 100644
index 000000000000..97a7bf669135
--- /dev/null
+++ b/sound/usb/6fire/midi.h
@@ -0,0 +1,46 @@
1/*
2 * Linux driver for TerraTec DMX 6Fire USB
3 *
4 * Author: Torsten Schenk <torsten.schenk@zoho.com>
5 * Created: Jan 01, 2011
6 * Version: 0.3.0
7 * Copyright: (C) Torsten Schenk
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 as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 */
14
15#ifndef USB6FIRE_MIDI_H
16#define USB6FIRE_MIDI_H
17
18#include "common.h"
19
20enum {
21 MIDI_BUFSIZE = 64
22};
23
24struct midi_runtime {
25 struct sfire_chip *chip;
26 struct snd_rawmidi *instance;
27
28 struct snd_rawmidi_substream *in;
29 char in_active;
30
31 spinlock_t in_lock;
32 spinlock_t out_lock;
33 struct snd_rawmidi_substream *out;
34 struct urb out_urb;
35 u8 out_serial; /* serial number of out packet */
36 u8 out_buffer[MIDI_BUFSIZE];
37 int buffer_offset;
38
39 void (*in_received)(struct midi_runtime *rt, u8 *data, int length);
40};
41
42int __devinit usb6fire_midi_init(struct sfire_chip *chip);
43void usb6fire_midi_abort(struct sfire_chip *chip);
44void usb6fire_midi_destroy(struct sfire_chip *chip);
45#endif /* USB6FIRE_MIDI_H */
46
diff --git a/sound/usb/6fire/pcm.c b/sound/usb/6fire/pcm.c
new file mode 100644
index 000000000000..ba62c7468ba8
--- /dev/null
+++ b/sound/usb/6fire/pcm.c
@@ -0,0 +1,688 @@
1/*
2 * Linux driver for TerraTec DMX 6Fire USB
3 *
4 * PCM driver
5 *
6 * Author: Torsten Schenk <torsten.schenk@zoho.com>
7 * Created: Jan 01, 2011
8 * Version: 0.3.0
9 * Copyright: (C) Torsten Schenk
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 */
16
17#include "pcm.h"
18#include "chip.h"
19#include "comm.h"
20
21enum {
22 OUT_N_CHANNELS = 6, IN_N_CHANNELS = 4
23};
24
25/* keep next two synced with
26 * FW_EP_W_MAX_PACKET_SIZE[] and RATES_MAX_PACKET_SIZE */
27static 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 };
29static 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[] = {
32 SNDRV_PCM_RATE_44100, SNDRV_PCM_RATE_48000,
33 SNDRV_PCM_RATE_88200, SNDRV_PCM_RATE_96000,
34 SNDRV_PCM_RATE_176400, SNDRV_PCM_RATE_192000 };
35
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 */
41 OUT_EP = 6, IN_EP = 2, MAX_BUFSIZE = 128 * 1024
42};
43
44enum { /* pcm streaming states */
45 STREAM_DISABLED, /* no pcm streaming */
46 STREAM_STARTING, /* pcm streaming requested, waiting to become ready */
47 STREAM_RUNNING, /* pcm streaming running */
48 STREAM_STOPPING
49};
50
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 = {
61 .info = SNDRV_PCM_INFO_MMAP |
62 SNDRV_PCM_INFO_INTERLEAVED |
63 SNDRV_PCM_INFO_BLOCK_TRANSFER |
64 SNDRV_PCM_INFO_MMAP_VALID |
65 SNDRV_PCM_INFO_BATCH,
66
67 .formats = SNDRV_PCM_FMTBIT_S24_LE,
68
69 .rates = SNDRV_PCM_RATE_44100 |
70 SNDRV_PCM_RATE_48000 |
71 SNDRV_PCM_RATE_88200 |
72 SNDRV_PCM_RATE_96000 |
73 SNDRV_PCM_RATE_176400 |
74 SNDRV_PCM_RATE_192000,
75
76 .rate_min = 44100,
77 .rate_max = 192000,
78 .channels_min = 1,
79 .channels_max = 0, /* set in pcm_open, depending on capture/playback */
80 .buffer_bytes_max = MAX_BUFSIZE,
81 .period_bytes_min = PCM_N_PACKETS_PER_URB * (PCM_MAX_PACKET_SIZE - 4),
82 .period_bytes_max = MAX_BUFSIZE,
83 .periods_min = 2,
84 .periods_max = 1024
85};
86
87static int usb6fire_pcm_set_rate(struct pcm_runtime *rt)
88{
89 int ret;
90 struct usb_device *device = rt->chip->dev;
91 struct comm_runtime *comm_rt = rt->chip->comm;
92
93 if (rt->rate >= ARRAY_SIZE(rates))
94 return -EINVAL;
95 /* disable streaming */
96 ret = comm_rt->write16(comm_rt, 0x02, 0x00, 0x00, 0x00);
97 if (ret < 0) {
98 snd_printk(KERN_ERR PREFIX "error stopping streaming while "
99 "setting samplerate %d.\n", rates[rt->rate]);
100 return ret;
101 }
102
103 ret = usb_set_interface(device, 1, rates_altsetting[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) {
115 snd_printk(KERN_ERR PREFIX "error setting samplerate %d.\n",
116 rates[rt->rate]);
117 return ret;
118 }
119
120 /* enable analog inputs and outputs
121 * (one bit per stereo-channel) */
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) {
126 snd_printk(KERN_ERR PREFIX "error initializing analog channels "
127 "while setting samplerate %d.\n",
128 rates[rt->rate]);
129 return ret;
130 }
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
140 ret = comm_rt->write16(comm_rt, 0x02, 0x00, 0x00, 0x01);
141 if (ret < 0) {
142 snd_printk(KERN_ERR PREFIX "error starting streaming while "
143 "setting samplerate %d.\n", rates[rt->rate]);
144 return ret;
145 }
146
147 rt->in_n_analog = IN_N_CHANNELS;
148 rt->out_n_analog = OUT_N_CHANNELS;
149 rt->in_packet_size = rates_in_packet_size[rt->rate];
150 rt->out_packet_size = rates_out_packet_size[rt->rate];
151 return 0;
152}
153
154static struct pcm_substream *usb6fire_pcm_get_substream(
155 struct snd_pcm_substream *alsa_sub)
156{
157 struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
158
159 if (alsa_sub->stream == SNDRV_PCM_STREAM_PLAYBACK)
160 return &rt->playback;
161 else if (alsa_sub->stream == SNDRV_PCM_STREAM_CAPTURE)
162 return &rt->capture;
163 snd_printk(KERN_ERR PREFIX "error getting pcm substream slot.\n");
164 return NULL;
165}
166
167/* call with stream_mutex locked */
168static void usb6fire_pcm_stream_stop(struct pcm_runtime *rt)
169{
170 int i;
171
172 if (rt->stream_state != STREAM_DISABLED) {
173 for (i = 0; i < PCM_N_URBS; i++) {
174 usb_kill_urb(&rt->in_urbs[i].instance);
175 usb_kill_urb(&rt->out_urbs[i].instance);
176 }
177 rt->stream_state = STREAM_DISABLED;
178 }
179}
180
181/* call with stream_mutex locked */
182static int usb6fire_pcm_stream_start(struct pcm_runtime *rt)
183{
184 int ret;
185 int i;
186 int k;
187 struct usb_iso_packet_descriptor *packet;
188
189 if (rt->stream_state == STREAM_DISABLED) {
190 /* submit our in urbs */
191 rt->stream_wait_cond = false;
192 rt->stream_state = STREAM_STARTING;
193 for (i = 0; i < PCM_N_URBS; i++) {
194 for (k = 0; k < PCM_N_PACKETS_PER_URB; k++) {
195 packet = &rt->in_urbs[i].packets[k];
196 packet->offset = k * rt->in_packet_size;
197 packet->length = rt->in_packet_size;
198 packet->actual_length = 0;
199 packet->status = 0;
200 }
201 ret = usb_submit_urb(&rt->in_urbs[i].instance,
202 GFP_ATOMIC);
203 if (ret) {
204 usb6fire_pcm_stream_stop(rt);
205 return ret;
206 }
207 }
208
209 /* wait for first out urb to return (sent in in urb handler) */
210 wait_event_timeout(rt->stream_wait_queue, rt->stream_wait_cond,
211 HZ);
212 if (rt->stream_wait_cond)
213 rt->stream_state = STREAM_RUNNING;
214 else {
215 usb6fire_pcm_stream_stop(rt);
216 return -EIO;
217 }
218 }
219 return 0;
220}
221
222/* call with substream locked */
223static void usb6fire_pcm_capture(struct pcm_substream *sub, struct pcm_urb *urb)
224{
225 int i;
226 int frame;
227 int frame_count;
228 unsigned int total_length = 0;
229 struct pcm_runtime *rt = snd_pcm_substream_chip(sub->instance);
230 struct snd_pcm_runtime *alsa_rt = sub->instance->runtime;
231 u32 *src = (u32 *) urb->buffer;
232 u32 *dest = (u32 *) (alsa_rt->dma_area + sub->dma_off
233 * (alsa_rt->frame_bits >> 3));
234 u32 *dest_end = (u32 *) (alsa_rt->dma_area + alsa_rt->buffer_size
235 * (alsa_rt->frame_bits >> 3));
236 int bytes_per_frame = alsa_rt->channels << 2;
237
238 for (i = 0; i < PCM_N_PACKETS_PER_URB; i++) {
239 /* at least 4 header bytes for valid packet.
240 * after that: 32 bits per sample for analog channels */
241 if (urb->packets[i].actual_length > 4)
242 frame_count = (urb->packets[i].actual_length - 4)
243 / (rt->in_n_analog << 2);
244 else
245 frame_count = 0;
246
247 src = (u32 *) (urb->buffer + total_length);
248 src++; /* skip leading 4 bytes of every packet */
249 total_length += urb->packets[i].length;
250 for (frame = 0; frame < frame_count; frame++) {
251 memcpy(dest, src, bytes_per_frame);
252 dest += alsa_rt->channels;
253 src += rt->in_n_analog;
254 sub->dma_off++;
255 sub->period_off++;
256 if (dest == dest_end) {
257 sub->dma_off = 0;
258 dest = (u32 *) alsa_rt->dma_area;
259 }
260 }
261 }
262}
263
264/* call with substream locked */
265static void usb6fire_pcm_playback(struct pcm_substream *sub,
266 struct pcm_urb *urb)
267{
268 int i;
269 int frame;
270 int frame_count;
271 struct pcm_runtime *rt = snd_pcm_substream_chip(sub->instance);
272 struct snd_pcm_runtime *alsa_rt = sub->instance->runtime;
273 u32 *src = (u32 *) (alsa_rt->dma_area + sub->dma_off
274 * (alsa_rt->frame_bits >> 3));
275 u32 *src_end = (u32 *) (alsa_rt->dma_area + alsa_rt->buffer_size
276 * (alsa_rt->frame_bits >> 3));
277 u32 *dest = (u32 *) urb->buffer;
278 int bytes_per_frame = alsa_rt->channels << 2;
279
280 for (i = 0; i < PCM_N_PACKETS_PER_URB; i++) {
281 /* at least 4 header bytes for valid packet.
282 * after that: 32 bits per sample for analog channels */
283 if (urb->packets[i].length > 4)
284 frame_count = (urb->packets[i].length - 4)
285 / (rt->out_n_analog << 2);
286 else
287 frame_count = 0;
288 dest++; /* skip leading 4 bytes of every frame */
289 for (frame = 0; frame < frame_count; frame++) {
290 memcpy(dest, src, bytes_per_frame);
291 src += alsa_rt->channels;
292 dest += rt->out_n_analog;
293 sub->dma_off++;
294 sub->period_off++;
295 if (src == src_end) {
296 src = (u32 *) alsa_rt->dma_area;
297 sub->dma_off = 0;
298 }
299 }
300 }
301}
302
303static void usb6fire_pcm_in_urb_handler(struct urb *usb_urb)
304{
305 struct pcm_urb *in_urb = usb_urb->context;
306 struct pcm_urb *out_urb = in_urb->peer;
307 struct pcm_runtime *rt = in_urb->chip->pcm;
308 struct pcm_substream *sub;
309 unsigned long flags;
310 int total_length = 0;
311 int frame_count;
312 int frame;
313 int channel;
314 int i;
315 u8 *dest;
316
317 if (usb_urb->status || rt->panic || rt->stream_state == STREAM_STOPPING)
318 return;
319 for (i = 0; i < PCM_N_PACKETS_PER_URB; i++)
320 if (in_urb->packets[i].status) {
321 rt->panic = true;
322 return;
323 }
324
325 if (rt->stream_state == STREAM_DISABLED) {
326 snd_printk(KERN_ERR PREFIX "internal error: "
327 "stream disabled in in-urb handler.\n");
328 return;
329 }
330
331 /* receive our capture data */
332 sub = &rt->capture;
333 spin_lock_irqsave(&sub->lock, flags);
334 if (sub->active) {
335 usb6fire_pcm_capture(sub, in_urb);
336 if (sub->period_off >= sub->instance->runtime->period_size) {
337 sub->period_off %= sub->instance->runtime->period_size;
338 spin_unlock_irqrestore(&sub->lock, flags);
339 snd_pcm_period_elapsed(sub->instance);
340 } else
341 spin_unlock_irqrestore(&sub->lock, flags);
342 } else
343 spin_unlock_irqrestore(&sub->lock, flags);
344
345 /* setup out urb structure */
346 for (i = 0; i < PCM_N_PACKETS_PER_URB; i++) {
347 out_urb->packets[i].offset = total_length;
348 out_urb->packets[i].length = (in_urb->packets[i].actual_length
349 - 4) / (rt->in_n_analog << 2)
350 * (rt->out_n_analog << 2) + 4;
351 out_urb->packets[i].status = 0;
352 total_length += out_urb->packets[i].length;
353 }
354 memset(out_urb->buffer, 0, total_length);
355
356 /* now send our playback data (if a free out urb was found) */
357 sub = &rt->playback;
358 spin_lock_irqsave(&sub->lock, flags);
359 if (sub->active) {
360 usb6fire_pcm_playback(sub, out_urb);
361 if (sub->period_off >= sub->instance->runtime->period_size) {
362 sub->period_off %= sub->instance->runtime->period_size;
363 spin_unlock_irqrestore(&sub->lock, flags);
364 snd_pcm_period_elapsed(sub->instance);
365 } else
366 spin_unlock_irqrestore(&sub->lock, flags);
367 } else
368 spin_unlock_irqrestore(&sub->lock, flags);
369
370 /* setup the 4th byte of each sample (0x40 for analog channels) */
371 dest = out_urb->buffer;
372 for (i = 0; i < PCM_N_PACKETS_PER_URB; i++)
373 if (out_urb->packets[i].length >= 4) {
374 frame_count = (out_urb->packets[i].length - 4)
375 / (rt->out_n_analog << 2);
376 *(dest++) = 0xaa;
377 *(dest++) = 0xaa;
378 *(dest++) = frame_count;
379 *(dest++) = 0x00;
380 for (frame = 0; frame < frame_count; frame++)
381 for (channel = 0;
382 channel < rt->out_n_analog;
383 channel++) {
384 dest += 3; /* skip sample data */
385 *(dest++) = 0x40;
386 }
387 }
388 usb_submit_urb(&out_urb->instance, GFP_ATOMIC);
389 usb_submit_urb(&in_urb->instance, GFP_ATOMIC);
390}
391
392static void usb6fire_pcm_out_urb_handler(struct urb *usb_urb)
393{
394 struct pcm_urb *urb = usb_urb->context;
395 struct pcm_runtime *rt = urb->chip->pcm;
396
397 if (rt->stream_state == STREAM_STARTING) {
398 rt->stream_wait_cond = true;
399 wake_up(&rt->stream_wait_queue);
400 }
401}
402
403static int usb6fire_pcm_open(struct snd_pcm_substream *alsa_sub)
404{
405 struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
406 struct pcm_substream *sub = NULL;
407 struct snd_pcm_runtime *alsa_rt = alsa_sub->runtime;
408
409 if (rt->panic)
410 return -EPIPE;
411
412 mutex_lock(&rt->stream_mutex);
413 alsa_rt->hw = pcm_hw;
414
415 if (alsa_sub->stream == SNDRV_PCM_STREAM_PLAYBACK) {
416 if (rt->rate >= 0)
417 alsa_rt->hw.rates = rates_alsaid[rt->rate];
418 alsa_rt->hw.channels_max = OUT_N_CHANNELS;
419 sub = &rt->playback;
420 } else if (alsa_sub->stream == SNDRV_PCM_STREAM_CAPTURE) {
421 if (rt->rate >= 0)
422 alsa_rt->hw.rates = rates_alsaid[rt->rate];
423 alsa_rt->hw.channels_max = IN_N_CHANNELS;
424 sub = &rt->capture;
425 }
426
427 if (!sub) {
428 mutex_unlock(&rt->stream_mutex);
429 snd_printk(KERN_ERR PREFIX "invalid stream type.\n");
430 return -EINVAL;
431 }
432
433 sub->instance = alsa_sub;
434 sub->active = false;
435 mutex_unlock(&rt->stream_mutex);
436 return 0;
437}
438
439static int usb6fire_pcm_close(struct snd_pcm_substream *alsa_sub)
440{
441 struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
442 struct pcm_substream *sub = usb6fire_pcm_get_substream(alsa_sub);
443 unsigned long flags;
444
445 if (rt->panic)
446 return 0;
447
448 mutex_lock(&rt->stream_mutex);
449 if (sub) {
450 /* deactivate substream */
451 spin_lock_irqsave(&sub->lock, flags);
452 sub->instance = NULL;
453 sub->active = false;
454 spin_unlock_irqrestore(&sub->lock, flags);
455
456 /* all substreams closed? if so, stop streaming */
457 if (!rt->playback.instance && !rt->capture.instance) {
458 usb6fire_pcm_stream_stop(rt);
459 rt->rate = -1;
460 }
461 }
462 mutex_unlock(&rt->stream_mutex);
463 return 0;
464}
465
466static int usb6fire_pcm_hw_params(struct snd_pcm_substream *alsa_sub,
467 struct snd_pcm_hw_params *hw_params)
468{
469 return snd_pcm_lib_malloc_pages(alsa_sub,
470 params_buffer_bytes(hw_params));
471}
472
473static int usb6fire_pcm_hw_free(struct snd_pcm_substream *alsa_sub)
474{
475 return snd_pcm_lib_free_pages(alsa_sub);
476}
477
478static int usb6fire_pcm_prepare(struct snd_pcm_substream *alsa_sub)
479{
480 struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
481 struct pcm_substream *sub = usb6fire_pcm_get_substream(alsa_sub);
482 struct snd_pcm_runtime *alsa_rt = alsa_sub->runtime;
483 int i;
484 int ret;
485
486 if (rt->panic)
487 return -EPIPE;
488 if (!sub)
489 return -ENODEV;
490
491 mutex_lock(&rt->stream_mutex);
492 sub->dma_off = 0;
493 sub->period_off = 0;
494
495 if (rt->stream_state == STREAM_DISABLED) {
496 for (i = 0; i < ARRAY_SIZE(rates); i++)
497 if (alsa_rt->rate == rates[i]) {
498 rt->rate = i;
499 break;
500 }
501 if (i == ARRAY_SIZE(rates)) {
502 mutex_unlock(&rt->stream_mutex);
503 snd_printk("invalid rate %d in prepare.\n",
504 alsa_rt->rate);
505 return -EINVAL;
506 }
507
508 ret = usb6fire_pcm_set_rate(rt);
509 if (ret) {
510 mutex_unlock(&rt->stream_mutex);
511 return ret;
512 }
513 ret = usb6fire_pcm_stream_start(rt);
514 if (ret) {
515 mutex_unlock(&rt->stream_mutex);
516 snd_printk(KERN_ERR PREFIX
517 "could not start pcm stream.\n");
518 return ret;
519 }
520 }
521 mutex_unlock(&rt->stream_mutex);
522 return 0;
523}
524
525static int usb6fire_pcm_trigger(struct snd_pcm_substream *alsa_sub, int cmd)
526{
527 struct pcm_substream *sub = usb6fire_pcm_get_substream(alsa_sub);
528 struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
529 unsigned long flags;
530
531 if (rt->panic)
532 return -EPIPE;
533 if (!sub)
534 return -ENODEV;
535
536 switch (cmd) {
537 case SNDRV_PCM_TRIGGER_START:
538 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
539 spin_lock_irqsave(&sub->lock, flags);
540 sub->active = true;
541 spin_unlock_irqrestore(&sub->lock, flags);
542 return 0;
543
544 case SNDRV_PCM_TRIGGER_STOP:
545 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
546 spin_lock_irqsave(&sub->lock, flags);
547 sub->active = false;
548 spin_unlock_irqrestore(&sub->lock, flags);
549 return 0;
550
551 default:
552 return -EINVAL;
553 }
554}
555
556static snd_pcm_uframes_t usb6fire_pcm_pointer(
557 struct snd_pcm_substream *alsa_sub)
558{
559 struct pcm_substream *sub = usb6fire_pcm_get_substream(alsa_sub);
560 struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
561 unsigned long flags;
562 snd_pcm_uframes_t ret;
563
564 if (rt->panic || !sub)
565 return SNDRV_PCM_STATE_XRUN;
566
567 spin_lock_irqsave(&sub->lock, flags);
568 ret = sub->dma_off;
569 spin_unlock_irqrestore(&sub->lock, flags);
570 return ret;
571}
572
573static struct snd_pcm_ops pcm_ops = {
574 .open = usb6fire_pcm_open,
575 .close = usb6fire_pcm_close,
576 .ioctl = snd_pcm_lib_ioctl,
577 .hw_params = usb6fire_pcm_hw_params,
578 .hw_free = usb6fire_pcm_hw_free,
579 .prepare = usb6fire_pcm_prepare,
580 .trigger = usb6fire_pcm_trigger,
581 .pointer = usb6fire_pcm_pointer,
582};
583
584static void __devinit usb6fire_pcm_init_urb(struct pcm_urb *urb,
585 struct sfire_chip *chip, bool in, int ep,
586 void (*handler)(struct urb *))
587{
588 urb->chip = chip;
589 usb_init_urb(&urb->instance);
590 urb->instance.transfer_buffer = urb->buffer;
591 urb->instance.transfer_buffer_length =
592 PCM_N_PACKETS_PER_URB * PCM_MAX_PACKET_SIZE;
593 urb->instance.dev = chip->dev;
594 urb->instance.pipe = in ? usb_rcvisocpipe(chip->dev, ep)
595 : usb_sndisocpipe(chip->dev, ep);
596 urb->instance.interval = 1;
597 urb->instance.transfer_flags = URB_ISO_ASAP;
598 urb->instance.complete = handler;
599 urb->instance.context = urb;
600 urb->instance.number_of_packets = PCM_N_PACKETS_PER_URB;
601}
602
603int __devinit usb6fire_pcm_init(struct sfire_chip *chip)
604{
605 int i;
606 int ret;
607 struct snd_pcm *pcm;
608 struct pcm_runtime *rt =
609 kzalloc(sizeof(struct pcm_runtime), GFP_KERNEL);
610
611 if (!rt)
612 return -ENOMEM;
613
614 rt->chip = chip;
615 rt->stream_state = STREAM_DISABLED;
616 rt->rate = -1;
617 init_waitqueue_head(&rt->stream_wait_queue);
618 mutex_init(&rt->stream_mutex);
619
620 spin_lock_init(&rt->playback.lock);
621 spin_lock_init(&rt->capture.lock);
622
623 for (i = 0; i < PCM_N_URBS; i++) {
624 usb6fire_pcm_init_urb(&rt->in_urbs[i], chip, true, IN_EP,
625 usb6fire_pcm_in_urb_handler);
626 usb6fire_pcm_init_urb(&rt->out_urbs[i], chip, false, OUT_EP,
627 usb6fire_pcm_out_urb_handler);
628
629 rt->in_urbs[i].peer = &rt->out_urbs[i];
630 rt->out_urbs[i].peer = &rt->in_urbs[i];
631 }
632
633 ret = snd_pcm_new(chip->card, "DMX6FireUSB", 0, 1, 1, &pcm);
634 if (ret < 0) {
635 kfree(rt);
636 snd_printk(KERN_ERR PREFIX "cannot create pcm instance.\n");
637 return ret;
638 }
639
640 pcm->private_data = rt;
641 strcpy(pcm->name, "DMX 6Fire USB");
642 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &pcm_ops);
643 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &pcm_ops);
644
645 ret = snd_pcm_lib_preallocate_pages_for_all(pcm,
646 SNDRV_DMA_TYPE_CONTINUOUS,
647 snd_dma_continuous_data(GFP_KERNEL),
648 MAX_BUFSIZE, MAX_BUFSIZE);
649 if (ret) {
650 kfree(rt);
651 snd_printk(KERN_ERR PREFIX
652 "error preallocating pcm buffers.\n");
653 return ret;
654 }
655 rt->instance = pcm;
656
657 chip->pcm = rt;
658 return 0;
659}
660
661void usb6fire_pcm_abort(struct sfire_chip *chip)
662{
663 struct pcm_runtime *rt = chip->pcm;
664 int i;
665
666 if (rt) {
667 rt->panic = true;
668
669 if (rt->playback.instance)
670 snd_pcm_stop(rt->playback.instance,
671 SNDRV_PCM_STATE_XRUN);
672 if (rt->capture.instance)
673 snd_pcm_stop(rt->capture.instance,
674 SNDRV_PCM_STATE_XRUN);
675
676 for (i = 0; i < PCM_N_URBS; i++) {
677 usb_poison_urb(&rt->in_urbs[i].instance);
678 usb_poison_urb(&rt->out_urbs[i].instance);
679 }
680
681 }
682}
683
684void usb6fire_pcm_destroy(struct sfire_chip *chip)
685{
686 kfree(chip->pcm);
687 chip->pcm = NULL;
688}
diff --git a/sound/usb/6fire/pcm.h b/sound/usb/6fire/pcm.h
new file mode 100644
index 000000000000..2bee81374002
--- /dev/null
+++ b/sound/usb/6fire/pcm.h
@@ -0,0 +1,76 @@
1/*
2 * Linux driver for TerraTec DMX 6Fire USB
3 *
4 * Author: Torsten Schenk <torsten.schenk@zoho.com>
5 * Created: Jan 01, 2011
6 * Version: 0.3.0
7 * Copyright: (C) Torsten Schenk
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 as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 */
14
15#ifndef USB6FIRE_PCM_H
16#define USB6FIRE_PCM_H
17
18#include <sound/pcm.h>
19#include <linux/mutex.h>
20
21#include "common.h"
22
23enum /* settings for pcm */
24{
25 /* maximum of EP_W_MAX_PACKET_SIZE[] (see firmware.c) */
26 PCM_N_URBS = 16, PCM_N_PACKETS_PER_URB = 8, PCM_MAX_PACKET_SIZE = 604
27};
28
29struct pcm_urb {
30 struct sfire_chip *chip;
31
32 /* BEGIN DO NOT SEPARATE */
33 struct urb instance;
34 struct usb_iso_packet_descriptor packets[PCM_N_PACKETS_PER_URB];
35 /* END DO NOT SEPARATE */
36 u8 buffer[PCM_N_PACKETS_PER_URB * PCM_MAX_PACKET_SIZE];
37
38 struct pcm_urb *peer;
39};
40
41struct pcm_substream {
42 spinlock_t lock;
43 struct snd_pcm_substream *instance;
44
45 bool active;
46
47 snd_pcm_uframes_t dma_off; /* current position in alsa dma_area */
48 snd_pcm_uframes_t period_off; /* current position in current period */
49};
50
51struct pcm_runtime {
52 struct sfire_chip *chip;
53 struct snd_pcm *instance;
54
55 struct pcm_substream playback;
56 struct pcm_substream capture;
57 bool panic; /* if set driver won't do anymore pcm on device */
58
59 struct pcm_urb in_urbs[PCM_N_URBS];
60 struct pcm_urb out_urbs[PCM_N_URBS];
61 int in_packet_size;
62 int out_packet_size;
63 int in_n_analog; /* number of analog channels soundcard sends */
64 int out_n_analog; /* number of analog channels soundcard receives */
65
66 struct mutex stream_mutex;
67 u8 stream_state; /* one of STREAM_XXX (pcm.c) */
68 u8 rate; /* one of PCM_RATE_XXX */
69 wait_queue_head_t stream_wait_queue;
70 bool stream_wait_cond;
71};
72
73int __devinit usb6fire_pcm_init(struct sfire_chip *chip);
74void usb6fire_pcm_abort(struct sfire_chip *chip);
75void usb6fire_pcm_destroy(struct sfire_chip *chip);
76#endif /* USB6FIRE_PCM_H */
diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig
index 112984f4080f..97724d8fa9f6 100644
--- a/sound/usb/Kconfig
+++ b/sound/usb/Kconfig
@@ -62,6 +62,7 @@ config SND_USB_CAIAQ
62 * Native Instruments Audio 2 DJ 62 * Native Instruments Audio 2 DJ
63 * Native Instruments Audio 4 DJ 63 * Native Instruments Audio 4 DJ
64 * Native Instruments Audio 8 DJ 64 * Native Instruments Audio 8 DJ
65 * Native Instruments Traktor Audio 2
65 * Native Instruments Guitar Rig Session I/O 66 * Native Instruments Guitar Rig Session I/O
66 * Native Instruments Guitar Rig mobile 67 * Native Instruments Guitar Rig mobile
67 * Native Instruments Traktor Kontrol X1 68 * Native Instruments Traktor Kontrol X1
@@ -97,5 +98,21 @@ config SND_USB_US122L
97 To compile this driver as a module, choose M here: the module 98 To compile this driver as a module, choose M here: the module
98 will be called snd-usb-us122l. 99 will be called snd-usb-us122l.
99 100
101config SND_USB_6FIRE
102 tristate "TerraTec DMX 6Fire USB"
103 depends on EXPERIMENTAL
104 select FW_LOADER
105 select SND_RAWMIDI
106 select SND_PCM
107 help
108 Say Y here to include support for TerraTec 6fire DMX USB interface.
109
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
112 firmware loading for all devices. If you own such a device,
113 you could start windows and let the windows driver upload
114 the firmware. As long as you do not unplug your device from power,
115 it should be usable.
116
100endif # SND_USB 117endif # SND_USB
101 118
diff --git a/sound/usb/Makefile b/sound/usb/Makefile
index 1e362bf8834f..cf9ed66445fa 100644
--- a/sound/usb/Makefile
+++ b/sound/usb/Makefile
@@ -23,4 +23,4 @@ obj-$(CONFIG_SND_USB_UA101) += snd-usbmidi-lib.o
23obj-$(CONFIG_SND_USB_USX2Y) += snd-usbmidi-lib.o 23obj-$(CONFIG_SND_USB_USX2Y) += snd-usbmidi-lib.o
24obj-$(CONFIG_SND_USB_US122L) += snd-usbmidi-lib.o 24obj-$(CONFIG_SND_USB_US122L) += snd-usbmidi-lib.o
25 25
26obj-$(CONFIG_SND) += misc/ usx2y/ caiaq/ 26obj-$(CONFIG_SND) += misc/ usx2y/ caiaq/ 6fire/
diff --git a/sound/usb/caiaq/audio.c b/sound/usb/caiaq/audio.c
index 66eabafb1c24..d0d493ca28ae 100644
--- a/sound/usb/caiaq/audio.c
+++ b/sound/usb/caiaq/audio.c
@@ -805,6 +805,7 @@ int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *dev)
805 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO2DJ): 805 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO2DJ):
806 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ): 806 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ):
807 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ): 807 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ):
808 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORAUDIO2):
808 dev->samplerates |= SNDRV_PCM_RATE_88200; 809 dev->samplerates |= SNDRV_PCM_RATE_88200;
809 break; 810 break;
810 } 811 }
diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c
index 6480c3283c05..45bc4a2dc6f0 100644
--- a/sound/usb/caiaq/device.c
+++ b/sound/usb/caiaq/device.c
@@ -46,6 +46,7 @@ MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2},"
46 "{Native Instruments, Audio 2 DJ}," 46 "{Native Instruments, Audio 2 DJ},"
47 "{Native Instruments, Audio 4 DJ}," 47 "{Native Instruments, Audio 4 DJ},"
48 "{Native Instruments, Audio 8 DJ}," 48 "{Native Instruments, Audio 8 DJ},"
49 "{Native Instruments, Traktor Audio 2},"
49 "{Native Instruments, Session I/O}," 50 "{Native Instruments, Session I/O},"
50 "{Native Instruments, GuitarRig mobile}" 51 "{Native Instruments, GuitarRig mobile}"
51 "{Native Instruments, Traktor Kontrol X1}" 52 "{Native Instruments, Traktor Kontrol X1}"
@@ -140,6 +141,11 @@ static struct usb_device_id snd_usb_id_table[] = {
140 .idVendor = USB_VID_NATIVEINSTRUMENTS, 141 .idVendor = USB_VID_NATIVEINSTRUMENTS,
141 .idProduct = USB_PID_TRAKTORKONTROLS4 142 .idProduct = USB_PID_TRAKTORKONTROLS4
142 }, 143 },
144 {
145 .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
146 .idVendor = USB_VID_NATIVEINSTRUMENTS,
147 .idProduct = USB_PID_TRAKTORAUDIO2
148 },
143 { /* terminator */ } 149 { /* terminator */ }
144}; 150};
145 151
diff --git a/sound/usb/caiaq/device.h b/sound/usb/caiaq/device.h
index e3d8a3efb35b..b2b310194ffa 100644
--- a/sound/usb/caiaq/device.h
+++ b/sound/usb/caiaq/device.h
@@ -17,6 +17,7 @@
17#define USB_PID_GUITARRIGMOBILE 0x0d8d 17#define USB_PID_GUITARRIGMOBILE 0x0d8d
18#define USB_PID_TRAKTORKONTROLX1 0x2305 18#define USB_PID_TRAKTORKONTROLX1 0x2305
19#define USB_PID_TRAKTORKONTROLS4 0xbaff 19#define USB_PID_TRAKTORKONTROLS4 0xbaff
20#define USB_PID_TRAKTORAUDIO2 0x041d
20 21
21#define EP1_BUFSIZE 64 22#define EP1_BUFSIZE 64
22#define EP4_BUFSIZE 512 23#define EP4_BUFSIZE 512
diff --git a/sound/usb/card.c b/sound/usb/card.c
index c0f8270bc199..40722f8711ad 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -65,6 +65,7 @@
65#include "pcm.h" 65#include "pcm.h"
66#include "urb.h" 66#include "urb.h"
67#include "format.h" 67#include "format.h"
68#include "power.h"
68 69
69MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>"); 70MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
70MODULE_DESCRIPTION("USB Audio"); 71MODULE_DESCRIPTION("USB Audio");
@@ -330,6 +331,7 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx,
330 chip->setup = device_setup[idx]; 331 chip->setup = device_setup[idx];
331 chip->nrpacks = nrpacks; 332 chip->nrpacks = nrpacks;
332 chip->async_unlink = async_unlink; 333 chip->async_unlink = async_unlink;
334 chip->probing = 1;
333 335
334 chip->usb_id = USB_ID(le16_to_cpu(dev->descriptor.idVendor), 336 chip->usb_id = USB_ID(le16_to_cpu(dev->descriptor.idVendor),
335 le16_to_cpu(dev->descriptor.idProduct)); 337 le16_to_cpu(dev->descriptor.idProduct));
@@ -451,6 +453,7 @@ static void *snd_usb_audio_probe(struct usb_device *dev,
451 goto __error; 453 goto __error;
452 } 454 }
453 chip = usb_chip[i]; 455 chip = usb_chip[i];
456 chip->probing = 1;
454 break; 457 break;
455 } 458 }
456 } 459 }
@@ -466,6 +469,7 @@ static void *snd_usb_audio_probe(struct usb_device *dev,
466 goto __error; 469 goto __error;
467 } 470 }
468 snd_card_set_dev(chip->card, &intf->dev); 471 snd_card_set_dev(chip->card, &intf->dev);
472 chip->pm_intf = intf;
469 break; 473 break;
470 } 474 }
471 if (!chip) { 475 if (!chip) {
@@ -505,6 +509,7 @@ static void *snd_usb_audio_probe(struct usb_device *dev,
505 509
506 usb_chip[chip->index] = chip; 510 usb_chip[chip->index] = chip;
507 chip->num_interfaces++; 511 chip->num_interfaces++;
512 chip->probing = 0;
508 mutex_unlock(&register_mutex); 513 mutex_unlock(&register_mutex);
509 return chip; 514 return chip;
510 515
@@ -581,29 +586,61 @@ static void usb_audio_disconnect(struct usb_interface *intf)
581} 586}
582 587
583#ifdef CONFIG_PM 588#ifdef CONFIG_PM
589
590int snd_usb_autoresume(struct snd_usb_audio *chip)
591{
592 int err = -ENODEV;
593
594 if (!chip->shutdown && !chip->probing)
595 err = usb_autopm_get_interface(chip->pm_intf);
596
597 return err;
598}
599
600void snd_usb_autosuspend(struct snd_usb_audio *chip)
601{
602 if (!chip->shutdown && !chip->probing)
603 usb_autopm_put_interface(chip->pm_intf);
604}
605
584static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message) 606static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message)
585{ 607{
586 struct snd_usb_audio *chip = usb_get_intfdata(intf); 608 struct snd_usb_audio *chip = usb_get_intfdata(intf);
587 struct list_head *p; 609 struct list_head *p;
588 struct snd_usb_stream *as; 610 struct snd_usb_stream *as;
611 struct usb_mixer_interface *mixer;
589 612
590 if (chip == (void *)-1L) 613 if (chip == (void *)-1L)
591 return 0; 614 return 0;
592 615
593 snd_power_change_state(chip->card, SNDRV_CTL_POWER_D3hot); 616 if (!(message.event & PM_EVENT_AUTO)) {
594 if (!chip->num_suspended_intf++) { 617 snd_power_change_state(chip->card, SNDRV_CTL_POWER_D3hot);
595 list_for_each(p, &chip->pcm_list) { 618 if (!chip->num_suspended_intf++) {
596 as = list_entry(p, struct snd_usb_stream, list); 619 list_for_each(p, &chip->pcm_list) {
597 snd_pcm_suspend_all(as->pcm); 620 as = list_entry(p, struct snd_usb_stream, list);
598 } 621 snd_pcm_suspend_all(as->pcm);
622 }
623 }
624 } else {
625 /*
626 * otherwise we keep the rest of the system in the dark
627 * to keep this transparent
628 */
629 if (!chip->num_suspended_intf++)
630 chip->autosuspended = 1;
599 } 631 }
600 632
633 list_for_each_entry(mixer, &chip->mixer_list, list)
634 snd_usb_mixer_inactivate(mixer);
635
601 return 0; 636 return 0;
602} 637}
603 638
604static int usb_audio_resume(struct usb_interface *intf) 639static int usb_audio_resume(struct usb_interface *intf)
605{ 640{
606 struct snd_usb_audio *chip = usb_get_intfdata(intf); 641 struct snd_usb_audio *chip = usb_get_intfdata(intf);
642 struct usb_mixer_interface *mixer;
643 int err = 0;
607 644
608 if (chip == (void *)-1L) 645 if (chip == (void *)-1L)
609 return 0; 646 return 0;
@@ -611,12 +648,20 @@ static int usb_audio_resume(struct usb_interface *intf)
611 return 0; 648 return 0;
612 /* 649 /*
613 * ALSA leaves material resumption to user space 650 * ALSA leaves material resumption to user space
614 * we just notify 651 * we just notify and restart the mixers
615 */ 652 */
653 list_for_each_entry(mixer, &chip->mixer_list, list) {
654 err = snd_usb_mixer_activate(mixer);
655 if (err < 0)
656 goto err_out;
657 }
616 658
617 snd_power_change_state(chip->card, SNDRV_CTL_POWER_D0); 659 if (!chip->autosuspended)
660 snd_power_change_state(chip->card, SNDRV_CTL_POWER_D0);
661 chip->autosuspended = 0;
618 662
619 return 0; 663err_out:
664 return err;
620} 665}
621#else 666#else
622#define usb_audio_suspend NULL 667#define usb_audio_suspend NULL
@@ -644,6 +689,7 @@ static struct usb_driver usb_audio_driver = {
644 .suspend = usb_audio_suspend, 689 .suspend = usb_audio_suspend,
645 .resume = usb_audio_resume, 690 .resume = usb_audio_resume,
646 .id_table = usb_audio_ids, 691 .id_table = usb_audio_ids,
692 .supports_autosuspend = 1,
647}; 693};
648 694
649static int __init snd_usb_audio_init(void) 695static int __init snd_usb_audio_init(void)
diff --git a/sound/usb/midi.c b/sound/usb/midi.c
index db2dc5ffe6dd..b4b39c0b6c9e 100644
--- a/sound/usb/midi.c
+++ b/sound/usb/midi.c
@@ -54,6 +54,7 @@
54#include <sound/asequencer.h> 54#include <sound/asequencer.h>
55#include "usbaudio.h" 55#include "usbaudio.h"
56#include "midi.h" 56#include "midi.h"
57#include "power.h"
57#include "helper.h" 58#include "helper.h"
58 59
59/* 60/*
@@ -1044,6 +1045,7 @@ static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream)
1044 struct snd_usb_midi* umidi = substream->rmidi->private_data; 1045 struct snd_usb_midi* umidi = substream->rmidi->private_data;
1045 struct usbmidi_out_port* port = NULL; 1046 struct usbmidi_out_port* port = NULL;
1046 int i, j; 1047 int i, j;
1048 int err;
1047 1049
1048 for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) 1050 for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i)
1049 if (umidi->endpoints[i].out) 1051 if (umidi->endpoints[i].out)
@@ -1056,6 +1058,9 @@ static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream)
1056 snd_BUG(); 1058 snd_BUG();
1057 return -ENXIO; 1059 return -ENXIO;
1058 } 1060 }
1061 err = usb_autopm_get_interface(umidi->iface);
1062 if (err < 0)
1063 return -EIO;
1059 substream->runtime->private_data = port; 1064 substream->runtime->private_data = port;
1060 port->state = STATE_UNKNOWN; 1065 port->state = STATE_UNKNOWN;
1061 substream_open(substream, 1); 1066 substream_open(substream, 1);
@@ -1064,7 +1069,10 @@ static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream)
1064 1069
1065static int snd_usbmidi_output_close(struct snd_rawmidi_substream *substream) 1070static int snd_usbmidi_output_close(struct snd_rawmidi_substream *substream)
1066{ 1071{
1072 struct snd_usb_midi* umidi = substream->rmidi->private_data;
1073
1067 substream_open(substream, 0); 1074 substream_open(substream, 0);
1075 usb_autopm_put_interface(umidi->iface);
1068 return 0; 1076 return 0;
1069} 1077}
1070 1078
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index 85af6051b52d..5e4775716607 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -61,6 +61,7 @@
61#include "mixer.h" 61#include "mixer.h"
62#include "helper.h" 62#include "helper.h"
63#include "mixer_quirks.h" 63#include "mixer_quirks.h"
64#include "power.h"
64 65
65#define MAX_ID_ELEMS 256 66#define MAX_ID_ELEMS 256
66 67
@@ -295,16 +296,22 @@ static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, int v
295 unsigned char buf[2]; 296 unsigned char buf[2];
296 int val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1; 297 int val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1;
297 int timeout = 10; 298 int timeout = 10;
299 int err;
298 300
301 err = snd_usb_autoresume(cval->mixer->chip);
302 if (err < 0)
303 return -EIO;
299 while (timeout-- > 0) { 304 while (timeout-- > 0) {
300 if (snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), request, 305 if (snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), request,
301 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, 306 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
302 validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), 307 validx, snd_usb_ctrl_intf(chip) | (cval->id << 8),
303 buf, val_len, 100) >= val_len) { 308 buf, val_len, 100) >= val_len) {
304 *value_ret = convert_signed_value(cval, snd_usb_combine_bytes(buf, val_len)); 309 *value_ret = convert_signed_value(cval, snd_usb_combine_bytes(buf, val_len));
310 snd_usb_autosuspend(cval->mixer->chip);
305 return 0; 311 return 0;
306 } 312 }
307 } 313 }
314 snd_usb_autosuspend(cval->mixer->chip);
308 snd_printdd(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n", 315 snd_printdd(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n",
309 request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type); 316 request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type);
310 return -EINVAL; 317 return -EINVAL;
@@ -328,12 +335,18 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int v
328 335
329 memset(buf, 0, sizeof(buf)); 336 memset(buf, 0, sizeof(buf));
330 337
338 ret = snd_usb_autoresume(chip) ? -EIO : 0;
339 if (ret)
340 goto error;
341
331 ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest, 342 ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest,
332 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, 343 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
333 validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), 344 validx, snd_usb_ctrl_intf(chip) | (cval->id << 8),
334 buf, size, 1000); 345 buf, size, 1000);
346 snd_usb_autosuspend(chip);
335 347
336 if (ret < 0) { 348 if (ret < 0) {
349error:
337 snd_printk(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n", 350 snd_printk(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n",
338 request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type); 351 request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type);
339 return ret; 352 return ret;
@@ -413,7 +426,7 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
413{ 426{
414 struct snd_usb_audio *chip = cval->mixer->chip; 427 struct snd_usb_audio *chip = cval->mixer->chip;
415 unsigned char buf[2]; 428 unsigned char buf[2];
416 int val_len, timeout = 10; 429 int val_len, err, timeout = 10;
417 430
418 if (cval->mixer->protocol == UAC_VERSION_1) { 431 if (cval->mixer->protocol == UAC_VERSION_1) {
419 val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1; 432 val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1;
@@ -433,13 +446,19 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
433 value_set = convert_bytes_value(cval, value_set); 446 value_set = convert_bytes_value(cval, value_set);
434 buf[0] = value_set & 0xff; 447 buf[0] = value_set & 0xff;
435 buf[1] = (value_set >> 8) & 0xff; 448 buf[1] = (value_set >> 8) & 0xff;
449 err = snd_usb_autoresume(chip);
450 if (err < 0)
451 return -EIO;
436 while (timeout-- > 0) 452 while (timeout-- > 0)
437 if (snd_usb_ctl_msg(chip->dev, 453 if (snd_usb_ctl_msg(chip->dev,
438 usb_sndctrlpipe(chip->dev, 0), request, 454 usb_sndctrlpipe(chip->dev, 0), request,
439 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, 455 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
440 validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), 456 validx, snd_usb_ctrl_intf(chip) | (cval->id << 8),
441 buf, val_len, 100) >= 0) 457 buf, val_len, 100) >= 0) {
458 snd_usb_autosuspend(chip);
442 return 0; 459 return 0;
460 }
461 snd_usb_autosuspend(chip);
443 snd_printdd(KERN_ERR "cannot set ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d, data = %#x/%#x\n", 462 snd_printdd(KERN_ERR "cannot set ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d, data = %#x/%#x\n",
444 request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type, buf[0], buf[1]); 463 request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type, buf[0], buf[1]);
445 return -EINVAL; 464 return -EINVAL;
@@ -987,6 +1006,7 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
987 struct snd_kcontrol *kctl; 1006 struct snd_kcontrol *kctl;
988 struct usb_mixer_elem_info *cval; 1007 struct usb_mixer_elem_info *cval;
989 const struct usbmix_name_map *map; 1008 const struct usbmix_name_map *map;
1009 unsigned int range;
990 1010
991 control++; /* change from zero-based to 1-based value */ 1011 control++; /* change from zero-based to 1-based value */
992 1012
@@ -1121,6 +1141,7 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
1121 } 1141 }
1122 break; 1142 break;
1123 1143
1144 case USB_ID(0x046d, 0x0808):
1124 case USB_ID(0x046d, 0x0809): 1145 case USB_ID(0x046d, 0x0809):
1125 case USB_ID(0x046d, 0x0991): 1146 case USB_ID(0x046d, 0x0991):
1126 /* Most audio usb devices lie about volume resolution. 1147 /* Most audio usb devices lie about volume resolution.
@@ -1136,6 +1157,21 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
1136 1157
1137 } 1158 }
1138 1159
1160 range = (cval->max - cval->min) / cval->res;
1161 /* Are there devices with volume range more than 255? I use a bit more
1162 * to be sure. 384 is a resolution magic number found on Logitech
1163 * devices. It will definitively catch all buggy Logitech devices.
1164 */
1165 if (range > 384) {
1166 snd_printk(KERN_WARNING "usb_audio: Warning! Unlikely big "
1167 "volume range (=%u), cval->res is probably wrong.",
1168 range);
1169 snd_printk(KERN_WARNING "usb_audio: [%d] FU [%s] ch = %d, "
1170 "val = %d/%d/%d", cval->id,
1171 kctl->id.name, cval->channels,
1172 cval->min, cval->max, cval->res);
1173 }
1174
1139 snd_printdd(KERN_INFO "[%d] FU [%s] ch = %d, val = %d/%d/%d\n", 1175 snd_printdd(KERN_INFO "[%d] FU [%s] ch = %d, val = %d/%d/%d\n",
1140 cval->id, kctl->id.name, cval->channels, cval->min, cval->max, cval->res); 1176 cval->id, kctl->id.name, cval->channels, cval->min, cval->max, cval->res);
1141 add_control_to_empty(state, kctl); 1177 add_control_to_empty(state, kctl);
@@ -2058,8 +2094,9 @@ static void snd_usb_mixer_interrupt(struct urb *urb)
2058{ 2094{
2059 struct usb_mixer_interface *mixer = urb->context; 2095 struct usb_mixer_interface *mixer = urb->context;
2060 int len = urb->actual_length; 2096 int len = urb->actual_length;
2097 int ustatus = urb->status;
2061 2098
2062 if (urb->status != 0) 2099 if (ustatus != 0)
2063 goto requeue; 2100 goto requeue;
2064 2101
2065 if (mixer->protocol == UAC_VERSION_1) { 2102 if (mixer->protocol == UAC_VERSION_1) {
@@ -2100,12 +2137,32 @@ static void snd_usb_mixer_interrupt(struct urb *urb)
2100 } 2137 }
2101 2138
2102requeue: 2139requeue:
2103 if (urb->status != -ENOENT && urb->status != -ECONNRESET) { 2140 if (ustatus != -ENOENT && ustatus != -ECONNRESET && ustatus != -ESHUTDOWN) {
2104 urb->dev = mixer->chip->dev; 2141 urb->dev = mixer->chip->dev;
2105 usb_submit_urb(urb, GFP_ATOMIC); 2142 usb_submit_urb(urb, GFP_ATOMIC);
2106 } 2143 }
2107} 2144}
2108 2145
2146/* stop any bus activity of a mixer */
2147void snd_usb_mixer_inactivate(struct usb_mixer_interface *mixer)
2148{
2149 usb_kill_urb(mixer->urb);
2150 usb_kill_urb(mixer->rc_urb);
2151}
2152
2153int snd_usb_mixer_activate(struct usb_mixer_interface *mixer)
2154{
2155 int err;
2156
2157 if (mixer->urb) {
2158 err = usb_submit_urb(mixer->urb, GFP_NOIO);
2159 if (err < 0)
2160 return err;
2161 }
2162
2163 return 0;
2164}
2165
2109/* create the handler for the optional status interrupt endpoint */ 2166/* create the handler for the optional status interrupt endpoint */
2110static int snd_usb_mixer_status_create(struct usb_mixer_interface *mixer) 2167static int snd_usb_mixer_status_create(struct usb_mixer_interface *mixer)
2111{ 2168{
diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h
index 26c636c5c93a..b4a2c8165e4b 100644
--- a/sound/usb/mixer.h
+++ b/sound/usb/mixer.h
@@ -52,5 +52,7 @@ void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer, int unitid);
52 52
53int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval, 53int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
54 int request, int validx, int value_set); 54 int request, int validx, int value_set);
55void snd_usb_mixer_inactivate(struct usb_mixer_interface *mixer);
56int snd_usb_mixer_activate(struct usb_mixer_interface *mixer);
55 57
56#endif /* __USBMIXER_H */ 58#endif /* __USBMIXER_H */
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
index 782f741cd00a..73dcc8256bc0 100644
--- a/sound/usb/mixer_quirks.c
+++ b/sound/usb/mixer_quirks.c
@@ -346,6 +346,141 @@ static int snd_xonar_u1_controls_create(struct usb_mixer_interface *mixer)
346 return 0; 346 return 0;
347} 347}
348 348
349/* Native Instruments device quirks */
350
351#define _MAKE_NI_CONTROL(bRequest,wIndex) ((bRequest) << 16 | (wIndex))
352
353static int snd_nativeinstruments_control_get(struct snd_kcontrol *kcontrol,
354 struct snd_ctl_elem_value *ucontrol)
355{
356 struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
357 struct usb_device *dev = mixer->chip->dev;
358 u8 bRequest = (kcontrol->private_value >> 16) & 0xff;
359 u16 wIndex = kcontrol->private_value & 0xffff;
360 u8 tmp;
361
362 int ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), bRequest,
363 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
364 0, cpu_to_le16(wIndex),
365 &tmp, sizeof(tmp), 1000);
366
367 if (ret < 0) {
368 snd_printk(KERN_ERR
369 "unable to issue vendor read request (ret = %d)", ret);
370 return ret;
371 }
372
373 ucontrol->value.integer.value[0] = tmp;
374
375 return 0;
376}
377
378static int snd_nativeinstruments_control_put(struct snd_kcontrol *kcontrol,
379 struct snd_ctl_elem_value *ucontrol)
380{
381 struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
382 struct usb_device *dev = mixer->chip->dev;
383 u8 bRequest = (kcontrol->private_value >> 16) & 0xff;
384 u16 wIndex = kcontrol->private_value & 0xffff;
385 u16 wValue = ucontrol->value.integer.value[0];
386
387 int ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), bRequest,
388 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
389 cpu_to_le16(wValue), cpu_to_le16(wIndex),
390 NULL, 0, 1000);
391
392 if (ret < 0) {
393 snd_printk(KERN_ERR
394 "unable to issue vendor write request (ret = %d)", ret);
395 return ret;
396 }
397
398 return 0;
399}
400
401static struct snd_kcontrol_new snd_nativeinstruments_ta6_mixers[] = {
402 {
403 .name = "Direct Thru Channel A",
404 .private_value = _MAKE_NI_CONTROL(0x01, 0x03),
405 },
406 {
407 .name = "Direct Thru Channel B",
408 .private_value = _MAKE_NI_CONTROL(0x01, 0x05),
409 },
410 {
411 .name = "Phono Input Channel A",
412 .private_value = _MAKE_NI_CONTROL(0x02, 0x03),
413 },
414 {
415 .name = "Phono Input Channel B",
416 .private_value = _MAKE_NI_CONTROL(0x02, 0x05),
417 },
418};
419
420static struct snd_kcontrol_new snd_nativeinstruments_ta10_mixers[] = {
421 {
422 .name = "Direct Thru Channel A",
423 .private_value = _MAKE_NI_CONTROL(0x01, 0x03),
424 },
425 {
426 .name = "Direct Thru Channel B",
427 .private_value = _MAKE_NI_CONTROL(0x01, 0x05),
428 },
429 {
430 .name = "Direct Thru Channel C",
431 .private_value = _MAKE_NI_CONTROL(0x01, 0x07),
432 },
433 {
434 .name = "Direct Thru Channel D",
435 .private_value = _MAKE_NI_CONTROL(0x01, 0x09),
436 },
437 {
438 .name = "Phono Input Channel A",
439 .private_value = _MAKE_NI_CONTROL(0x02, 0x03),
440 },
441 {
442 .name = "Phono Input Channel B",
443 .private_value = _MAKE_NI_CONTROL(0x02, 0x05),
444 },
445 {
446 .name = "Phono Input Channel C",
447 .private_value = _MAKE_NI_CONTROL(0x02, 0x07),
448 },
449 {
450 .name = "Phono Input Channel D",
451 .private_value = _MAKE_NI_CONTROL(0x02, 0x09),
452 },
453};
454
455static int snd_nativeinstruments_create_mixer(struct usb_mixer_interface *mixer,
456 const struct snd_kcontrol_new *kc,
457 unsigned int count)
458{
459 int i, err = 0;
460 struct snd_kcontrol_new template = {
461 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
462 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
463 .get = snd_nativeinstruments_control_get,
464 .put = snd_nativeinstruments_control_put,
465 .info = snd_ctl_boolean_mono_info,
466 };
467
468 for (i = 0; i < count; i++) {
469 struct snd_kcontrol *c;
470
471 template.name = kc[i].name;
472 template.private_value = kc[i].private_value;
473
474 c = snd_ctl_new1(&template, mixer);
475 err = snd_ctl_add(mixer->chip->card, c);
476
477 if (err < 0)
478 break;
479 }
480
481 return err;
482}
483
349void snd_emuusb_set_samplerate(struct snd_usb_audio *chip, 484void snd_emuusb_set_samplerate(struct snd_usb_audio *chip,
350 unsigned char samplerate_id) 485 unsigned char samplerate_id)
351{ 486{
@@ -367,31 +502,44 @@ void snd_emuusb_set_samplerate(struct snd_usb_audio *chip,
367 502
368int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) 503int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
369{ 504{
370 int err; 505 int err = 0;
371 struct snd_info_entry *entry; 506 struct snd_info_entry *entry;
372 507
373 if ((err = snd_usb_soundblaster_remote_init(mixer)) < 0) 508 if ((err = snd_usb_soundblaster_remote_init(mixer)) < 0)
374 return err; 509 return err;
375 510
376 if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020) || 511 switch (mixer->chip->usb_id) {
377 mixer->chip->usb_id == USB_ID(0x041e, 0x3040) || 512 case USB_ID(0x041e, 0x3020):
378 mixer->chip->usb_id == USB_ID(0x041e, 0x3042) || 513 case USB_ID(0x041e, 0x3040):
379 mixer->chip->usb_id == USB_ID(0x041e, 0x3048)) { 514 case USB_ID(0x041e, 0x3042):
380 if ((err = snd_audigy2nx_controls_create(mixer)) < 0) 515 case USB_ID(0x041e, 0x3048):
381 return err; 516 err = snd_audigy2nx_controls_create(mixer);
517 if (err < 0)
518 break;
382 if (!snd_card_proc_new(mixer->chip->card, "audigy2nx", &entry)) 519 if (!snd_card_proc_new(mixer->chip->card, "audigy2nx", &entry))
383 snd_info_set_text_ops(entry, mixer, 520 snd_info_set_text_ops(entry, mixer,
384 snd_audigy2nx_proc_read); 521 snd_audigy2nx_proc_read);
385 } 522 break;
386 523
387 if (mixer->chip->usb_id == USB_ID(0x0b05, 0x1739) || 524 case USB_ID(0x0b05, 0x1739):
388 mixer->chip->usb_id == USB_ID(0x0b05, 0x1743)) { 525 case USB_ID(0x0b05, 0x1743):
389 err = snd_xonar_u1_controls_create(mixer); 526 err = snd_xonar_u1_controls_create(mixer);
390 if (err < 0) 527 break;
391 return err; 528
529 case USB_ID(0x17cc, 0x1011): /* Traktor Audio 6 */
530 err = snd_nativeinstruments_create_mixer(mixer,
531 snd_nativeinstruments_ta6_mixers,
532 ARRAY_SIZE(snd_nativeinstruments_ta6_mixers));
533 break;
534
535 case USB_ID(0x17cc, 0x1021): /* Traktor Audio 10 */
536 err = snd_nativeinstruments_create_mixer(mixer,
537 snd_nativeinstruments_ta10_mixers,
538 ARRAY_SIZE(snd_nativeinstruments_ta10_mixers));
539 break;
392 } 540 }
393 541
394 return 0; 542 return err;
395} 543}
396 544
397void snd_usb_mixer_rc_memory_change(struct usb_mixer_interface *mixer, 545void snd_usb_mixer_rc_memory_change(struct usb_mixer_interface *mixer,
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index e3f680526cb5..b8dcbf407bbb 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -32,6 +32,7 @@
32#include "helper.h" 32#include "helper.h"
33#include "pcm.h" 33#include "pcm.h"
34#include "clock.h" 34#include "clock.h"
35#include "power.h"
35 36
36/* 37/*
37 * return the current pcm pointer. just based on the hwptr_done value. 38 * return the current pcm pointer. just based on the hwptr_done value.
@@ -739,6 +740,9 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre
739 pt = 125 * (1 << fp->datainterval); 740 pt = 125 * (1 << fp->datainterval);
740 ptmin = min(ptmin, pt); 741 ptmin = min(ptmin, pt);
741 } 742 }
743 err = snd_usb_autoresume(subs->stream->chip);
744 if (err < 0)
745 return err;
742 746
743 param_period_time_if_needed = SNDRV_PCM_HW_PARAM_PERIOD_TIME; 747 param_period_time_if_needed = SNDRV_PCM_HW_PARAM_PERIOD_TIME;
744 if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) 748 if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL)
@@ -756,21 +760,21 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre
756 SNDRV_PCM_HW_PARAM_CHANNELS, 760 SNDRV_PCM_HW_PARAM_CHANNELS,
757 param_period_time_if_needed, 761 param_period_time_if_needed,
758 -1)) < 0) 762 -1)) < 0)
759 return err; 763 goto rep_err;
760 if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 764 if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
761 hw_rule_channels, subs, 765 hw_rule_channels, subs,
762 SNDRV_PCM_HW_PARAM_FORMAT, 766 SNDRV_PCM_HW_PARAM_FORMAT,
763 SNDRV_PCM_HW_PARAM_RATE, 767 SNDRV_PCM_HW_PARAM_RATE,
764 param_period_time_if_needed, 768 param_period_time_if_needed,
765 -1)) < 0) 769 -1)) < 0)
766 return err; 770 goto rep_err;
767 if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT, 771 if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT,
768 hw_rule_format, subs, 772 hw_rule_format, subs,
769 SNDRV_PCM_HW_PARAM_RATE, 773 SNDRV_PCM_HW_PARAM_RATE,
770 SNDRV_PCM_HW_PARAM_CHANNELS, 774 SNDRV_PCM_HW_PARAM_CHANNELS,
771 param_period_time_if_needed, 775 param_period_time_if_needed,
772 -1)) < 0) 776 -1)) < 0)
773 return err; 777 goto rep_err;
774 if (param_period_time_if_needed >= 0) { 778 if (param_period_time_if_needed >= 0) {
775 err = snd_pcm_hw_rule_add(runtime, 0, 779 err = snd_pcm_hw_rule_add(runtime, 0,
776 SNDRV_PCM_HW_PARAM_PERIOD_TIME, 780 SNDRV_PCM_HW_PARAM_PERIOD_TIME,
@@ -780,11 +784,15 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre
780 SNDRV_PCM_HW_PARAM_RATE, 784 SNDRV_PCM_HW_PARAM_RATE,
781 -1); 785 -1);
782 if (err < 0) 786 if (err < 0)
783 return err; 787 goto rep_err;
784 } 788 }
785 if ((err = snd_usb_pcm_check_knot(runtime, subs)) < 0) 789 if ((err = snd_usb_pcm_check_knot(runtime, subs)) < 0)
786 return err; 790 goto rep_err;
787 return 0; 791 return 0;
792
793rep_err:
794 snd_usb_autosuspend(subs->stream->chip);
795 return err;
788} 796}
789 797
790static int snd_usb_pcm_open(struct snd_pcm_substream *substream, int direction) 798static int snd_usb_pcm_open(struct snd_pcm_substream *substream, int direction)
@@ -798,6 +806,7 @@ static int snd_usb_pcm_open(struct snd_pcm_substream *substream, int direction)
798 runtime->hw = snd_usb_hardware; 806 runtime->hw = snd_usb_hardware;
799 runtime->private_data = subs; 807 runtime->private_data = subs;
800 subs->pcm_substream = substream; 808 subs->pcm_substream = substream;
809 /* runtime PM is also done there */
801 return setup_hw_info(runtime, subs); 810 return setup_hw_info(runtime, subs);
802} 811}
803 812
@@ -811,6 +820,7 @@ static int snd_usb_pcm_close(struct snd_pcm_substream *substream, int direction)
811 subs->interface = -1; 820 subs->interface = -1;
812 } 821 }
813 subs->pcm_substream = NULL; 822 subs->pcm_substream = NULL;
823 snd_usb_autosuspend(subs->stream->chip);
814 return 0; 824 return 0;
815} 825}
816 826
diff --git a/sound/usb/power.h b/sound/usb/power.h
new file mode 100644
index 000000000000..48ee51dcb71e
--- /dev/null
+++ b/sound/usb/power.h
@@ -0,0 +1,17 @@
1#ifndef __USBAUDIO_POWER_H
2#define __USBAUDIO_POWER_H
3
4#ifdef CONFIG_PM
5int snd_usb_autoresume(struct snd_usb_audio *chip);
6void snd_usb_autosuspend(struct snd_usb_audio *chip);
7#else
8static inline int snd_usb_autoresume(struct snd_usb_audio *chip)
9{
10 return 0;
11}
12static inline void snd_usb_autosuspend(struct snd_usb_audio *chip)
13{
14}
15#endif
16
17#endif /* __USBAUDIO_POWER_H */
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
index 921a86fd9884..c0dcfca9b5b5 100644
--- a/sound/usb/quirks-table.h
+++ b/sound/usb/quirks-table.h
@@ -2290,6 +2290,20 @@ YAMAHA_DEVICE(0x7010, "UB99"),
2290 } 2290 }
2291}, 2291},
2292 2292
2293/* Native Instruments MK2 series */
2294{
2295 /* Traktor Audio 6 */
2296 .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
2297 .idVendor = 0x17cc,
2298 .idProduct = 0x1010,
2299},
2300{
2301 /* Traktor Audio 10 */
2302 .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
2303 .idVendor = 0x17cc,
2304 .idProduct = 0x1020,
2305},
2306
2293/* Miditech devices */ 2307/* Miditech devices */
2294{ 2308{
2295 USB_DEVICE(0x4752, 0x0011), 2309 USB_DEVICE(0x4752, 0x0011),
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index e314cdb85003..355759bad581 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -425,6 +425,34 @@ static int snd_usb_accessmusic_boot_quirk(struct usb_device *dev)
425} 425}
426 426
427/* 427/*
428 * Some sound cards from Native Instruments are in fact compliant to the USB
429 * audio standard of version 2 and other approved USB standards, even though
430 * they come up as vendor-specific device when first connected.
431 *
432 * However, they can be told to come up with a new set of descriptors
433 * upon their next enumeration, and the interfaces announced by the new
434 * descriptors will then be handled by the kernel's class drivers. As the
435 * product ID will also change, no further checks are required.
436 */
437
438static int snd_usb_nativeinstruments_boot_quirk(struct usb_device *dev)
439{
440 int ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
441 0xaf, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
442 cpu_to_le16(1), 0, NULL, 0, 1000);
443
444 if (ret < 0)
445 return ret;
446
447 usb_reset_device(dev);
448
449 /* return -EAGAIN, so the creation of an audio interface for this
450 * temporary device is aborted. The device will reconnect with a
451 * new product ID */
452 return -EAGAIN;
453}
454
455/*
428 * Setup quirks 456 * Setup quirks
429 */ 457 */
430#define AUDIOPHILE_SET 0x01 /* if set, parse device_setup */ 458#define AUDIOPHILE_SET 0x01 /* if set, parse device_setup */
@@ -489,27 +517,33 @@ int snd_usb_apply_boot_quirk(struct usb_device *dev,
489 u32 id = USB_ID(le16_to_cpu(dev->descriptor.idVendor), 517 u32 id = USB_ID(le16_to_cpu(dev->descriptor.idVendor),
490 le16_to_cpu(dev->descriptor.idProduct)); 518 le16_to_cpu(dev->descriptor.idProduct));
491 519
492 /* SB Extigy needs special boot-up sequence */ 520 switch (id) {
493 /* if more models come, this will go to the quirk list. */ 521 case USB_ID(0x041e, 0x3000):
494 if (id == USB_ID(0x041e, 0x3000)) 522 /* SB Extigy needs special boot-up sequence */
523 /* if more models come, this will go to the quirk list. */
495 return snd_usb_extigy_boot_quirk(dev, intf); 524 return snd_usb_extigy_boot_quirk(dev, intf);
496 525
497 /* SB Audigy 2 NX needs its own boot-up magic, too */ 526 case USB_ID(0x041e, 0x3020):
498 if (id == USB_ID(0x041e, 0x3020)) 527 /* SB Audigy 2 NX needs its own boot-up magic, too */
499 return snd_usb_audigy2nx_boot_quirk(dev); 528 return snd_usb_audigy2nx_boot_quirk(dev);
500 529
501 /* C-Media CM106 / Turtle Beach Audio Advantage Roadie */ 530 case USB_ID(0x10f5, 0x0200):
502 if (id == USB_ID(0x10f5, 0x0200)) 531 /* C-Media CM106 / Turtle Beach Audio Advantage Roadie */
503 return snd_usb_cm106_boot_quirk(dev); 532 return snd_usb_cm106_boot_quirk(dev);
504 533
505 /* C-Media CM6206 / CM106-Like Sound Device */ 534 case USB_ID(0x0d8c, 0x0102):
506 if (id == USB_ID(0x0d8c, 0x0102)) 535 /* C-Media CM6206 / CM106-Like Sound Device */
507 return snd_usb_cm6206_boot_quirk(dev); 536 return snd_usb_cm6206_boot_quirk(dev);
508 537
509 /* Access Music VirusTI Desktop */ 538 case USB_ID(0x133e, 0x0815):
510 if (id == USB_ID(0x133e, 0x0815)) 539 /* Access Music VirusTI Desktop */
511 return snd_usb_accessmusic_boot_quirk(dev); 540 return snd_usb_accessmusic_boot_quirk(dev);
512 541
542 case USB_ID(0x17cc, 0x1010): /* Traktor Audio 6 */
543 case USB_ID(0x17cc, 0x1020): /* Traktor Audio 10 */
544 return snd_usb_nativeinstruments_boot_quirk(dev);
545 }
546
513 return 0; 547 return 0;
514} 548}
515 549
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
index 6e66fffe87f5..32f2a97f2f14 100644
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -34,10 +34,14 @@ struct snd_usb_audio {
34 int index; 34 int index;
35 struct usb_device *dev; 35 struct usb_device *dev;
36 struct snd_card *card; 36 struct snd_card *card;
37 struct usb_interface *pm_intf;
37 u32 usb_id; 38 u32 usb_id;
38 int shutdown;
39 struct mutex shutdown_mutex; 39 struct mutex shutdown_mutex;
40 unsigned int shutdown:1;
41 unsigned int probing:1;
42 unsigned int autosuspended:1;
40 unsigned int txfr_quirk:1; /* Subframe boundaries on transfers */ 43 unsigned int txfr_quirk:1; /* Subframe boundaries on transfers */
44
41 int num_interfaces; 45 int num_interfaces;
42 int num_suspended_intf; 46 int num_suspended_intf;
43 47