aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2010-03-08 15:21:04 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2010-03-08 15:21:04 -0500
commit988addf82e4c03739375279de73929580a2d4a6a (patch)
tree989ae1cd4e264bbad80c65f04480486246e7b9f3 /sound
parent004c1c7096659d352b83047a7593e91d8a30e3c5 (diff)
parent25cf84cf377c0aae5dbcf937ea89bc7893db5176 (diff)
Merge branch 'origin' into devel-stable
Conflicts: arch/arm/mach-mx2/devices.c arch/arm/mach-mx2/devices.h sound/soc/pxa/pxa-ssp.c
Diffstat (limited to 'sound')
-rw-r--r--sound/aoa/fabrics/layout.c2
-rw-r--r--sound/core/control.c7
-rw-r--r--sound/core/misc.c32
-rw-r--r--sound/core/oss/pcm_oss.c31
-rw-r--r--sound/core/pcm.c5
-rw-r--r--sound/core/pcm_lib.c445
-rw-r--r--sound/core/pcm_memory.c55
-rw-r--r--sound/core/pcm_native.c67
-rw-r--r--sound/core/seq/seq_clientmgr.c2
-rw-r--r--sound/core/seq/seq_timer.c27
-rw-r--r--sound/drivers/dummy.c290
-rw-r--r--sound/drivers/vx/vx_pcm.c61
-rw-r--r--sound/isa/Kconfig37
-rw-r--r--sound/isa/Makefile2
-rw-r--r--sound/isa/als100.c121
-rw-r--r--sound/isa/dt019x.c321
-rw-r--r--sound/isa/opti9xx/opti92x-ad1848.c93
-rw-r--r--sound/isa/sb/Makefile2
-rw-r--r--sound/isa/sb/jazz16.c404
-rw-r--r--sound/isa/sb/sb8_main.c118
-rw-r--r--sound/isa/sb/sb_common.c3
-rw-r--r--sound/isa/sb/sb_mixer.c333
-rw-r--r--sound/isa/wss/wss_lib.c80
-rw-r--r--sound/mips/sgio2audio.c34
-rw-r--r--sound/oss/au1550_ac97.c16
-rw-r--r--sound/oss/kahlua.c2
-rw-r--r--sound/oss/soundcard.c35
-rw-r--r--sound/pci/Kconfig1
-rw-r--r--sound/pci/ac97/ac97_patch.c17
-rw-r--r--sound/pci/ad1889.c2
-rw-r--r--sound/pci/ali5451/ali5451.c2
-rw-r--r--sound/pci/als300.c2
-rw-r--r--sound/pci/als4000.c2
-rw-r--r--sound/pci/atiixp.c2
-rw-r--r--sound/pci/atiixp_modem.c2
-rw-r--r--sound/pci/au88x0/au8810.c2
-rw-r--r--sound/pci/au88x0/au8820.c2
-rw-r--r--sound/pci/au88x0/au8830.c2
-rw-r--r--sound/pci/aw2/aw2-alsa.c2
-rw-r--r--sound/pci/azt3328.c2
-rw-r--r--sound/pci/bt87x.c4
-rw-r--r--sound/pci/ca0106/ca0106_main.c2
-rw-r--r--sound/pci/cmipci.c4
-rw-r--r--sound/pci/cs4281.c2
-rw-r--r--sound/pci/cs46xx/cs46xx.c2
-rw-r--r--sound/pci/cs46xx/cs46xx_lib.c22
-rw-r--r--sound/pci/cs46xx/dsp_spos.c42
-rw-r--r--sound/pci/cs46xx/dsp_spos.h4
-rw-r--r--sound/pci/cs46xx/dsp_spos_scb_lib.c33
-rw-r--r--sound/pci/cs5530.c2
-rw-r--r--sound/pci/cs5535audio/cs5535audio.c2
-rw-r--r--sound/pci/ctxfi/ctatc.c23
-rw-r--r--sound/pci/ctxfi/ctatc.h2
-rw-r--r--sound/pci/ctxfi/xfi.c7
-rw-r--r--sound/pci/echoaudio/darla20.c2
-rw-r--r--sound/pci/echoaudio/darla20_dsp.c12
-rw-r--r--sound/pci/echoaudio/darla24.c2
-rw-r--r--sound/pci/echoaudio/darla24_dsp.c12
-rw-r--r--sound/pci/echoaudio/echo3g.c2
-rw-r--r--sound/pci/echoaudio/echo3g_dsp.c28
-rw-r--r--sound/pci/echoaudio/echoaudio.c205
-rw-r--r--sound/pci/echoaudio/echoaudio.h11
-rw-r--r--sound/pci/echoaudio/echoaudio_3g.c5
-rw-r--r--sound/pci/echoaudio/echoaudio_dsp.c157
-rw-r--r--sound/pci/echoaudio/gina20.c2
-rw-r--r--sound/pci/echoaudio/gina20_dsp.c15
-rw-r--r--sound/pci/echoaudio/gina24.c2
-rw-r--r--sound/pci/echoaudio/gina24_dsp.c38
-rw-r--r--sound/pci/echoaudio/indigo.c2
-rw-r--r--sound/pci/echoaudio/indigo_dsp.c12
-rw-r--r--sound/pci/echoaudio/indigo_express_dsp.c1
-rw-r--r--sound/pci/echoaudio/indigodj.c2
-rw-r--r--sound/pci/echoaudio/indigodj_dsp.c12
-rw-r--r--sound/pci/echoaudio/indigodjx.c2
-rw-r--r--sound/pci/echoaudio/indigodjx_dsp.c13
-rw-r--r--sound/pci/echoaudio/indigoio.c2
-rw-r--r--sound/pci/echoaudio/indigoio_dsp.c12
-rw-r--r--sound/pci/echoaudio/indigoiox.c2
-rw-r--r--sound/pci/echoaudio/indigoiox_dsp.c13
-rw-r--r--sound/pci/echoaudio/layla20.c2
-rw-r--r--sound/pci/echoaudio/layla20_dsp.c20
-rw-r--r--sound/pci/echoaudio/layla24.c2
-rw-r--r--sound/pci/echoaudio/layla24_dsp.c37
-rw-r--r--sound/pci/echoaudio/mia.c2
-rw-r--r--sound/pci/echoaudio/mia_dsp.c12
-rw-r--r--sound/pci/echoaudio/mona.c2
-rw-r--r--sound/pci/echoaudio/mona_dsp.c61
-rw-r--r--sound/pci/emu10k1/emu10k1.c2
-rw-r--r--sound/pci/emu10k1/emu10k1x.c2
-rw-r--r--sound/pci/ens1370.c2
-rw-r--r--sound/pci/es1938.c2
-rw-r--r--sound/pci/es1968.c2
-rw-r--r--sound/pci/fm801.c2
-rw-r--r--sound/pci/hda/hda_codec.c81
-rw-r--r--sound/pci/hda/hda_codec.h5
-rw-r--r--sound/pci/hda/hda_generic.c3
-rw-r--r--sound/pci/hda/hda_hwdep.c60
-rw-r--r--sound/pci/hda/hda_intel.c60
-rw-r--r--sound/pci/hda/hda_local.h14
-rw-r--r--sound/pci/hda/hda_proc.c31
-rw-r--r--sound/pci/hda/patch_analog.c117
-rw-r--r--sound/pci/hda/patch_cirrus.c14
-rw-r--r--sound/pci/hda/patch_cmedia.c11
-rw-r--r--sound/pci/hda/patch_conexant.c592
-rw-r--r--sound/pci/hda/patch_realtek.c1006
-rw-r--r--sound/pci/hda/patch_si3054.c1
-rw-r--r--sound/pci/hda/patch_sigmatel.c271
-rw-r--r--sound/pci/hda/patch_via.c274
-rw-r--r--sound/pci/ice1712/ice1712.c11
-rw-r--r--sound/pci/ice1712/ice1724.c2
-rw-r--r--sound/pci/intel8x0.c2
-rw-r--r--sound/pci/intel8x0m.c2
-rw-r--r--sound/pci/korg1212/korg1212.c2
-rw-r--r--sound/pci/lx6464es/lx6464es.c2
-rw-r--r--sound/pci/maestro3.c2
-rw-r--r--sound/pci/mixart/mixart.c2
-rw-r--r--sound/pci/nm256/nm256.c2
-rw-r--r--sound/pci/oxygen/Makefile2
-rw-r--r--sound/pci/oxygen/hifier.c2
-rw-r--r--sound/pci/oxygen/oxygen.c2
-rw-r--r--sound/pci/oxygen/virtuoso.c5
-rw-r--r--sound/pci/oxygen/wm8766.h73
-rw-r--r--sound/pci/oxygen/wm8776.h177
-rw-r--r--sound/pci/oxygen/xonar.h2
-rw-r--r--sound/pci/oxygen/xonar_wm87x6.c1021
-rw-r--r--sound/pci/pcxhr/pcxhr.c2
-rw-r--r--sound/pci/riptide/riptide.c4
-rw-r--r--sound/pci/rme32.c2
-rw-r--r--sound/pci/rme96.c2
-rw-r--r--sound/pci/rme9652/hdsp.c2
-rw-r--r--sound/pci/rme9652/hdspm.c2
-rw-r--r--sound/pci/rme9652/rme9652.c2
-rw-r--r--sound/pci/sis7019.c2
-rw-r--r--sound/pci/sonicvibes.c2
-rw-r--r--sound/pci/trident/trident.c2
-rw-r--r--sound/pci/via82xx.c8
-rw-r--r--sound/pci/via82xx_modem.c2
-rw-r--r--sound/pci/vx222/vx222.c2
-rw-r--r--sound/pci/ymfpci/ymfpci.c2
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c52
-rw-r--r--sound/ppc/awacs.c24
-rw-r--r--sound/ppc/burgundy.c4
-rw-r--r--sound/ppc/pmac.c18
-rw-r--r--sound/soc/au1x/Kconfig10
-rw-r--r--sound/soc/au1x/Makefile4
-rw-r--r--sound/soc/au1x/db1200.c141
-rw-r--r--sound/soc/au1x/dbdma2.c14
-rw-r--r--sound/soc/au1x/sample-ac97.c144
-rw-r--r--sound/soc/blackfin/bf5xx-ac97-pcm.c8
-rw-r--r--sound/soc/blackfin/bf5xx-i2s-pcm.c3
-rw-r--r--sound/soc/blackfin/bf5xx-tdm-pcm.c3
-rw-r--r--sound/soc/codecs/Kconfig24
-rw-r--r--sound/soc/codecs/Makefile16
-rw-r--r--sound/soc/codecs/ad1836.c96
-rw-r--r--sound/soc/codecs/ad1836.h1
-rw-r--r--sound/soc/codecs/ad1938.c228
-rw-r--r--sound/soc/codecs/ak4104.c4
-rw-r--r--sound/soc/codecs/cs4270.c91
-rw-r--r--sound/soc/codecs/da7210.c589
-rw-r--r--sound/soc/codecs/da7210.h24
-rw-r--r--sound/soc/codecs/tlv320aic3x.c75
-rw-r--r--sound/soc/codecs/tlv320dac33.c311
-rw-r--r--sound/soc/codecs/tpa6130a2.c115
-rw-r--r--sound/soc/codecs/twl4030.c33
-rw-r--r--sound/soc/codecs/twl4030.h2
-rw-r--r--sound/soc/codecs/uda1380.c2
-rw-r--r--sound/soc/codecs/wm2000.c888
-rw-r--r--sound/soc/codecs/wm2000.h79
-rw-r--r--sound/soc/codecs/wm8350.c8
-rw-r--r--sound/soc/codecs/wm8727.c66
-rw-r--r--sound/soc/codecs/wm8731.c3
-rw-r--r--sound/soc/codecs/wm8753.c8
-rw-r--r--sound/soc/codecs/wm8776.c2
-rw-r--r--sound/soc/codecs/wm8904.c2656
-rw-r--r--sound/soc/codecs/wm8904.h1681
-rw-r--r--sound/soc/codecs/wm8955.c1151
-rw-r--r--sound/soc/codecs/wm8955.h489
-rw-r--r--sound/soc/codecs/wm8961.c3
-rw-r--r--sound/soc/codecs/wm8974.c12
-rw-r--r--sound/soc/codecs/wm8974.h12
-rw-r--r--sound/soc/codecs/wm8978.c1149
-rw-r--r--sound/soc/codecs/wm8978.h86
-rw-r--r--sound/soc/codecs/wm8990.c8
-rw-r--r--sound/soc/codecs/wm8993.c307
-rw-r--r--sound/soc/codecs/wm8994.c3867
-rw-r--r--sound/soc/codecs/wm8994.h26
-rw-r--r--sound/soc/codecs/wm9713.c64
-rw-r--r--sound/soc/codecs/wm_hubs.c148
-rw-r--r--sound/soc/codecs/wm_hubs.h6
-rw-r--r--sound/soc/davinci/davinci-mcasp.c17
-rw-r--r--sound/soc/davinci/davinci-mcasp.h1
-rw-r--r--sound/soc/davinci/davinci-pcm.c2
-rw-r--r--sound/soc/fsl/efika-audio-fabric.c2
-rw-r--r--sound/soc/fsl/pcm030-audio-fabric.c2
-rw-r--r--sound/soc/imx/Kconfig20
-rw-r--r--sound/soc/imx/Makefile14
-rw-r--r--sound/soc/imx/imx-pcm-dma-mx2.c313
-rw-r--r--sound/soc/imx/imx-pcm-fiq.c297
-rw-r--r--sound/soc/imx/imx-ssi.c758
-rw-r--r--sound/soc/imx/imx-ssi.h237
-rw-r--r--sound/soc/imx/mx1_mx2-pcm.c488
-rw-r--r--sound/soc/imx/mx1_mx2-pcm.h26
-rw-r--r--sound/soc/imx/mx27vis_wm8974.c318
-rw-r--r--sound/soc/imx/mxc-ssi.c860
-rw-r--r--sound/soc/imx/mxc-ssi.h238
-rw-r--r--sound/soc/imx/phycore-ac97.c90
-rw-r--r--sound/soc/omap/Kconfig11
-rw-r--r--sound/soc/omap/Makefile2
-rw-r--r--sound/soc/omap/mcpdm.c484
-rw-r--r--sound/soc/omap/mcpdm.h151
-rw-r--r--sound/soc/omap/omap-mcbsp.c146
-rw-r--r--sound/soc/omap/omap-mcbsp.h4
-rw-r--r--sound/soc/omap/omap-mcpdm.c251
-rw-r--r--sound/soc/omap/omap-mcpdm.h29
-rw-r--r--sound/soc/omap/omap-pcm.c15
-rw-r--r--sound/soc/omap/omap-pcm.h4
-rw-r--r--sound/soc/omap/omap3beagle.c6
-rw-r--r--sound/soc/omap/omap3pandora.c42
-rw-r--r--sound/soc/pxa/pxa-ssp.c13
-rw-r--r--sound/soc/pxa/raumfeld.c61
-rw-r--r--sound/soc/s3c24xx/Kconfig22
-rw-r--r--sound/soc/s3c24xx/Makefile7
-rw-r--r--sound/soc/s3c24xx/ln2440sbc_alc650.c4
-rw-r--r--sound/soc/s3c24xx/s3c-ac97.c518
-rw-r--r--sound/soc/s3c24xx/s3c-ac97.h23
-rw-r--r--sound/soc/s3c24xx/s3c-pcm.c3
-rw-r--r--sound/soc/s3c24xx/s3c2443-ac97.c432
-rw-r--r--sound/soc/s3c24xx/s3c24xx-ac97.h25
-rw-r--r--sound/soc/s3c24xx/s3c64xx-i2s.c120
-rw-r--r--sound/soc/s3c24xx/smdk2443_wm9710.c4
-rw-r--r--sound/soc/s3c24xx/smdk_wm9713.c94
-rw-r--r--sound/soc/sh/Kconfig23
-rw-r--r--sound/soc/sh/Makefile6
-rw-r--r--sound/soc/sh/fsi-da7210.c83
-rw-r--r--sound/soc/sh/fsi.c227
-rw-r--r--sound/soc/sh/migor.c218
-rw-r--r--sound/soc/sh/siu.h193
-rw-r--r--sound/soc/sh/siu_dai.c847
-rw-r--r--sound/soc/sh/siu_pcm.c616
-rw-r--r--sound/soc/soc-cache.c213
-rw-r--r--sound/soc/soc-core.c49
-rw-r--r--sound/soc/soc-dapm.c142
-rw-r--r--sound/usb/Kconfig12
-rw-r--r--sound/usb/Makefile2
-rw-r--r--sound/usb/ua101.c1421
-rw-r--r--sound/usb/usbaudio.c841
-rw-r--r--sound/usb/usbaudio.h106
-rw-r--r--sound/usb/usbmidi.c34
-rw-r--r--sound/usb/usbmixer.c371
-rw-r--r--sound/usb/usbmixer_maps.c23
-rw-r--r--sound/usb/usbquirks.h233
-rw-r--r--sound/usb/usx2y/us122l.c6
252 files changed, 27689 insertions, 6305 deletions
diff --git a/sound/aoa/fabrics/layout.c b/sound/aoa/fabrics/layout.c
index 586965f9605f..7a437da05646 100644
--- a/sound/aoa/fabrics/layout.c
+++ b/sound/aoa/fabrics/layout.c
@@ -768,7 +768,7 @@ static int check_codec(struct aoa_codec *codec,
768 "required property %s not present\n", propname); 768 "required property %s not present\n", propname);
769 return -ENODEV; 769 return -ENODEV;
770 } 770 }
771 if (*ref != codec->node->linux_phandle) { 771 if (*ref != codec->node->phandle) {
772 printk(KERN_INFO "snd-aoa-fabric-layout: " 772 printk(KERN_INFO "snd-aoa-fabric-layout: "
773 "%s doesn't match!\n", propname); 773 "%s doesn't match!\n", propname);
774 return -ENODEV; 774 return -ENODEV;
diff --git a/sound/core/control.c b/sound/core/control.c
index 268ab7471224..439ce64f9d82 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -237,8 +237,9 @@ struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new *ncontrol,
237 access = ncontrol->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE : 237 access = ncontrol->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE :
238 (ncontrol->access & (SNDRV_CTL_ELEM_ACCESS_READWRITE| 238 (ncontrol->access & (SNDRV_CTL_ELEM_ACCESS_READWRITE|
239 SNDRV_CTL_ELEM_ACCESS_INACTIVE| 239 SNDRV_CTL_ELEM_ACCESS_INACTIVE|
240 SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE| 240 SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE|
241 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK)); 241 SNDRV_CTL_ELEM_ACCESS_TLV_COMMAND|
242 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK));
242 kctl.info = ncontrol->info; 243 kctl.info = ncontrol->info;
243 kctl.get = ncontrol->get; 244 kctl.get = ncontrol->get;
244 kctl.put = ncontrol->put; 245 kctl.put = ncontrol->put;
@@ -1099,7 +1100,7 @@ static int snd_ctl_tlv_ioctl(struct snd_ctl_file *file,
1099 1100
1100 if (copy_from_user(&tlv, _tlv, sizeof(tlv))) 1101 if (copy_from_user(&tlv, _tlv, sizeof(tlv)))
1101 return -EFAULT; 1102 return -EFAULT;
1102 if (tlv.length < sizeof(unsigned int) * 3) 1103 if (tlv.length < sizeof(unsigned int) * 2)
1103 return -EINVAL; 1104 return -EINVAL;
1104 down_read(&card->controls_rwsem); 1105 down_read(&card->controls_rwsem);
1105 kctl = snd_ctl_find_numid(card, tlv.numid); 1106 kctl = snd_ctl_find_numid(card, tlv.numid);
diff --git a/sound/core/misc.c b/sound/core/misc.c
index 23a032c6d487..3da4f92427d8 100644
--- a/sound/core/misc.c
+++ b/sound/core/misc.c
@@ -101,8 +101,9 @@ EXPORT_SYMBOL_GPL(__snd_printk);
101#ifdef CONFIG_PCI 101#ifdef CONFIG_PCI
102#include <linux/pci.h> 102#include <linux/pci.h>
103/** 103/**
104 * snd_pci_quirk_lookup - look up a PCI SSID quirk list 104 * snd_pci_quirk_lookup_id - look up a PCI SSID quirk list
105 * @pci: pci_dev handle 105 * @vendor: PCI SSV id
106 * @device: PCI SSD id
106 * @list: quirk list, terminated by a null entry 107 * @list: quirk list, terminated by a null entry
107 * 108 *
108 * Look through the given quirk list and finds a matching entry 109 * Look through the given quirk list and finds a matching entry
@@ -112,18 +113,39 @@ EXPORT_SYMBOL_GPL(__snd_printk);
112 * Returns the matched entry pointer, or NULL if nothing matched. 113 * Returns the matched entry pointer, or NULL if nothing matched.
113 */ 114 */
114const struct snd_pci_quirk * 115const struct snd_pci_quirk *
115snd_pci_quirk_lookup(struct pci_dev *pci, const struct snd_pci_quirk *list) 116snd_pci_quirk_lookup_id(u16 vendor, u16 device,
117 const struct snd_pci_quirk *list)
116{ 118{
117 const struct snd_pci_quirk *q; 119 const struct snd_pci_quirk *q;
118 120
119 for (q = list; q->subvendor; q++) { 121 for (q = list; q->subvendor; q++) {
120 if (q->subvendor != pci->subsystem_vendor) 122 if (q->subvendor != vendor)
121 continue; 123 continue;
122 if (!q->subdevice || 124 if (!q->subdevice ||
123 (pci->subsystem_device & q->subdevice_mask) == q->subdevice) 125 (device & q->subdevice_mask) == q->subdevice)
124 return q; 126 return q;
125 } 127 }
126 return NULL; 128 return NULL;
127} 129}
130EXPORT_SYMBOL(snd_pci_quirk_lookup_id);
131
132/**
133 * snd_pci_quirk_lookup - look up a PCI SSID quirk list
134 * @pci: pci_dev handle
135 * @list: quirk list, terminated by a null entry
136 *
137 * Look through the given quirk list and finds a matching entry
138 * with the same PCI SSID. When subdevice is 0, all subdevice
139 * values may match.
140 *
141 * Returns the matched entry pointer, or NULL if nothing matched.
142 */
143const struct snd_pci_quirk *
144snd_pci_quirk_lookup(struct pci_dev *pci, const struct snd_pci_quirk *list)
145{
146 return snd_pci_quirk_lookup_id(pci->subsystem_vendor,
147 pci->subsystem_device,
148 list);
149}
128EXPORT_SYMBOL(snd_pci_quirk_lookup); 150EXPORT_SYMBOL(snd_pci_quirk_lookup);
129#endif 151#endif
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index d9c96353121a..82d4e3329b3d 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -632,6 +632,12 @@ static long snd_pcm_alsa_frames(struct snd_pcm_substream *substream, long bytes)
632 return bytes_to_frames(runtime, (buffer_size * bytes) / runtime->oss.buffer_bytes); 632 return bytes_to_frames(runtime, (buffer_size * bytes) / runtime->oss.buffer_bytes);
633} 633}
634 634
635static inline
636snd_pcm_uframes_t get_hw_ptr_period(struct snd_pcm_runtime *runtime)
637{
638 return runtime->hw_ptr_interrupt;
639}
640
635/* define extended formats in the recent OSS versions (if any) */ 641/* define extended formats in the recent OSS versions (if any) */
636/* linear formats */ 642/* linear formats */
637#define AFMT_S32_LE 0x00001000 643#define AFMT_S32_LE 0x00001000
@@ -1102,7 +1108,7 @@ static int snd_pcm_oss_prepare(struct snd_pcm_substream *substream)
1102 return err; 1108 return err;
1103 } 1109 }
1104 runtime->oss.prepare = 0; 1110 runtime->oss.prepare = 0;
1105 runtime->oss.prev_hw_ptr_interrupt = 0; 1111 runtime->oss.prev_hw_ptr_period = 0;
1106 runtime->oss.period_ptr = 0; 1112 runtime->oss.period_ptr = 0;
1107 runtime->oss.buffer_used = 0; 1113 runtime->oss.buffer_used = 0;
1108 1114
@@ -1950,7 +1956,8 @@ static int snd_pcm_oss_get_caps(struct snd_pcm_oss_file *pcm_oss_file)
1950 return result; 1956 return result;
1951} 1957}
1952 1958
1953static void snd_pcm_oss_simulate_fill(struct snd_pcm_substream *substream, snd_pcm_uframes_t hw_ptr) 1959static void snd_pcm_oss_simulate_fill(struct snd_pcm_substream *substream,
1960 snd_pcm_uframes_t hw_ptr)
1954{ 1961{
1955 struct snd_pcm_runtime *runtime = substream->runtime; 1962 struct snd_pcm_runtime *runtime = substream->runtime;
1956 snd_pcm_uframes_t appl_ptr; 1963 snd_pcm_uframes_t appl_ptr;
@@ -1986,7 +1993,8 @@ static int snd_pcm_oss_set_trigger(struct snd_pcm_oss_file *pcm_oss_file, int tr
1986 if (runtime->oss.trigger) 1993 if (runtime->oss.trigger)
1987 goto _skip1; 1994 goto _skip1;
1988 if (atomic_read(&psubstream->mmap_count)) 1995 if (atomic_read(&psubstream->mmap_count))
1989 snd_pcm_oss_simulate_fill(psubstream, runtime->hw_ptr_interrupt); 1996 snd_pcm_oss_simulate_fill(psubstream,
1997 get_hw_ptr_period(runtime));
1990 runtime->oss.trigger = 1; 1998 runtime->oss.trigger = 1;
1991 runtime->start_threshold = 1; 1999 runtime->start_threshold = 1;
1992 cmd = SNDRV_PCM_IOCTL_START; 2000 cmd = SNDRV_PCM_IOCTL_START;
@@ -2105,11 +2113,12 @@ static int snd_pcm_oss_get_ptr(struct snd_pcm_oss_file *pcm_oss_file, int stream
2105 info.ptr = snd_pcm_oss_bytes(substream, runtime->status->hw_ptr % runtime->buffer_size); 2113 info.ptr = snd_pcm_oss_bytes(substream, runtime->status->hw_ptr % runtime->buffer_size);
2106 if (atomic_read(&substream->mmap_count)) { 2114 if (atomic_read(&substream->mmap_count)) {
2107 snd_pcm_sframes_t n; 2115 snd_pcm_sframes_t n;
2108 n = (delay = runtime->hw_ptr_interrupt) - runtime->oss.prev_hw_ptr_interrupt; 2116 delay = get_hw_ptr_period(runtime);
2117 n = delay - runtime->oss.prev_hw_ptr_period;
2109 if (n < 0) 2118 if (n < 0)
2110 n += runtime->boundary; 2119 n += runtime->boundary;
2111 info.blocks = n / runtime->period_size; 2120 info.blocks = n / runtime->period_size;
2112 runtime->oss.prev_hw_ptr_interrupt = delay; 2121 runtime->oss.prev_hw_ptr_period = delay;
2113 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 2122 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
2114 snd_pcm_oss_simulate_fill(substream, delay); 2123 snd_pcm_oss_simulate_fill(substream, delay);
2115 info.bytes = snd_pcm_oss_bytes(substream, runtime->status->hw_ptr) & INT_MAX; 2124 info.bytes = snd_pcm_oss_bytes(substream, runtime->status->hw_ptr) & INT_MAX;
@@ -2673,18 +2682,22 @@ static int snd_pcm_oss_playback_ready(struct snd_pcm_substream *substream)
2673{ 2682{
2674 struct snd_pcm_runtime *runtime = substream->runtime; 2683 struct snd_pcm_runtime *runtime = substream->runtime;
2675 if (atomic_read(&substream->mmap_count)) 2684 if (atomic_read(&substream->mmap_count))
2676 return runtime->oss.prev_hw_ptr_interrupt != runtime->hw_ptr_interrupt; 2685 return runtime->oss.prev_hw_ptr_period !=
2686 get_hw_ptr_period(runtime);
2677 else 2687 else
2678 return snd_pcm_playback_avail(runtime) >= runtime->oss.period_frames; 2688 return snd_pcm_playback_avail(runtime) >=
2689 runtime->oss.period_frames;
2679} 2690}
2680 2691
2681static int snd_pcm_oss_capture_ready(struct snd_pcm_substream *substream) 2692static int snd_pcm_oss_capture_ready(struct snd_pcm_substream *substream)
2682{ 2693{
2683 struct snd_pcm_runtime *runtime = substream->runtime; 2694 struct snd_pcm_runtime *runtime = substream->runtime;
2684 if (atomic_read(&substream->mmap_count)) 2695 if (atomic_read(&substream->mmap_count))
2685 return runtime->oss.prev_hw_ptr_interrupt != runtime->hw_ptr_interrupt; 2696 return runtime->oss.prev_hw_ptr_period !=
2697 get_hw_ptr_period(runtime);
2686 else 2698 else
2687 return snd_pcm_capture_avail(runtime) >= runtime->oss.period_frames; 2699 return snd_pcm_capture_avail(runtime) >=
2700 runtime->oss.period_frames;
2688} 2701}
2689 2702
2690static unsigned int snd_pcm_oss_poll(struct file *file, poll_table * wait) 2703static unsigned int snd_pcm_oss_poll(struct file *file, poll_table * wait)
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 6884ae031f6f..0d428d0896db 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -894,6 +894,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
894 memset((void*)runtime->control, 0, size); 894 memset((void*)runtime->control, 0, size);
895 895
896 init_waitqueue_head(&runtime->sleep); 896 init_waitqueue_head(&runtime->sleep);
897 init_waitqueue_head(&runtime->tsleep);
897 898
898 runtime->status->state = SNDRV_PCM_STATE_OPEN; 899 runtime->status->state = SNDRV_PCM_STATE_OPEN;
899 900
@@ -921,6 +922,10 @@ void snd_pcm_detach_substream(struct snd_pcm_substream *substream)
921 snd_free_pages((void*)runtime->control, 922 snd_free_pages((void*)runtime->control,
922 PAGE_ALIGN(sizeof(struct snd_pcm_mmap_control))); 923 PAGE_ALIGN(sizeof(struct snd_pcm_mmap_control)));
923 kfree(runtime->hw_constraints.rules); 924 kfree(runtime->hw_constraints.rules);
925#ifdef CONFIG_SND_PCM_XRUN_DEBUG
926 if (runtime->hwptr_log)
927 kfree(runtime->hwptr_log);
928#endif
924 kfree(runtime); 929 kfree(runtime);
925 substream->runtime = NULL; 930 substream->runtime = NULL;
926 put_pid(substream->pid); 931 put_pid(substream->pid);
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index a27545b23ee9..b546ac2660f9 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -126,17 +126,6 @@ void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_ufram
126 } 126 }
127} 127}
128 128
129#ifdef CONFIG_SND_PCM_XRUN_DEBUG
130#define xrun_debug(substream, mask) ((substream)->pstr->xrun_debug & (mask))
131#else
132#define xrun_debug(substream, mask) 0
133#endif
134
135#define dump_stack_on_xrun(substream) do { \
136 if (xrun_debug(substream, 2)) \
137 dump_stack(); \
138 } while (0)
139
140static void pcm_debug_name(struct snd_pcm_substream *substream, 129static void pcm_debug_name(struct snd_pcm_substream *substream,
141 char *name, size_t len) 130 char *name, size_t len)
142{ 131{
@@ -147,6 +136,24 @@ static void pcm_debug_name(struct snd_pcm_substream *substream,
147 substream->number); 136 substream->number);
148} 137}
149 138
139#define XRUN_DEBUG_BASIC (1<<0)
140#define XRUN_DEBUG_STACK (1<<1) /* dump also stack */
141#define XRUN_DEBUG_JIFFIESCHECK (1<<2) /* do jiffies check */
142#define XRUN_DEBUG_PERIODUPDATE (1<<3) /* full period update info */
143#define XRUN_DEBUG_HWPTRUPDATE (1<<4) /* full hwptr update info */
144#define XRUN_DEBUG_LOG (1<<5) /* show last 10 positions on err */
145#define XRUN_DEBUG_LOGONCE (1<<6) /* do above only once */
146
147#ifdef CONFIG_SND_PCM_XRUN_DEBUG
148
149#define xrun_debug(substream, mask) \
150 ((substream)->pstr->xrun_debug & (mask))
151
152#define dump_stack_on_xrun(substream) do { \
153 if (xrun_debug(substream, XRUN_DEBUG_STACK)) \
154 dump_stack(); \
155 } while (0)
156
150static void xrun(struct snd_pcm_substream *substream) 157static void xrun(struct snd_pcm_substream *substream)
151{ 158{
152 struct snd_pcm_runtime *runtime = substream->runtime; 159 struct snd_pcm_runtime *runtime = substream->runtime;
@@ -154,7 +161,7 @@ static void xrun(struct snd_pcm_substream *substream)
154 if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE) 161 if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE)
155 snd_pcm_gettime(runtime, (struct timespec *)&runtime->status->tstamp); 162 snd_pcm_gettime(runtime, (struct timespec *)&runtime->status->tstamp);
156 snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); 163 snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
157 if (xrun_debug(substream, 1)) { 164 if (xrun_debug(substream, XRUN_DEBUG_BASIC)) {
158 char name[16]; 165 char name[16];
159 pcm_debug_name(substream, name, sizeof(name)); 166 pcm_debug_name(substream, name, sizeof(name));
160 snd_printd(KERN_DEBUG "XRUN: %s\n", name); 167 snd_printd(KERN_DEBUG "XRUN: %s\n", name);
@@ -162,32 +169,102 @@ static void xrun(struct snd_pcm_substream *substream)
162 } 169 }
163} 170}
164 171
165static snd_pcm_uframes_t 172#define hw_ptr_error(substream, fmt, args...) \
166snd_pcm_update_hw_ptr_pos(struct snd_pcm_substream *substream, 173 do { \
167 struct snd_pcm_runtime *runtime) 174 if (xrun_debug(substream, XRUN_DEBUG_BASIC)) { \
168{ 175 xrun_log_show(substream); \
176 if (printk_ratelimit()) { \
177 snd_printd("PCM: " fmt, ##args); \
178 } \
179 dump_stack_on_xrun(substream); \
180 } \
181 } while (0)
182
183#define XRUN_LOG_CNT 10
184
185struct hwptr_log_entry {
186 unsigned long jiffies;
169 snd_pcm_uframes_t pos; 187 snd_pcm_uframes_t pos;
188 snd_pcm_uframes_t period_size;
189 snd_pcm_uframes_t buffer_size;
190 snd_pcm_uframes_t old_hw_ptr;
191 snd_pcm_uframes_t hw_ptr_base;
192};
170 193
171 pos = substream->ops->pointer(substream); 194struct snd_pcm_hwptr_log {
172 if (pos == SNDRV_PCM_POS_XRUN) 195 unsigned int idx;
173 return pos; /* XRUN */ 196 unsigned int hit: 1;
174 if (pos >= runtime->buffer_size) { 197 struct hwptr_log_entry entries[XRUN_LOG_CNT];
175 if (printk_ratelimit()) { 198};
176 char name[16]; 199
177 pcm_debug_name(substream, name, sizeof(name)); 200static void xrun_log(struct snd_pcm_substream *substream,
178 snd_printd(KERN_ERR "BUG: %s, pos = 0x%lx, " 201 snd_pcm_uframes_t pos)
179 "buffer size = 0x%lx, period size = 0x%lx\n", 202{
180 name, pos, runtime->buffer_size, 203 struct snd_pcm_runtime *runtime = substream->runtime;
181 runtime->period_size); 204 struct snd_pcm_hwptr_log *log = runtime->hwptr_log;
182 } 205 struct hwptr_log_entry *entry;
183 pos = 0; 206
207 if (log == NULL) {
208 log = kzalloc(sizeof(*log), GFP_ATOMIC);
209 if (log == NULL)
210 return;
211 runtime->hwptr_log = log;
212 } else {
213 if (xrun_debug(substream, XRUN_DEBUG_LOGONCE) && log->hit)
214 return;
184 } 215 }
185 pos -= pos % runtime->min_align; 216 entry = &log->entries[log->idx];
186 return pos; 217 entry->jiffies = jiffies;
218 entry->pos = pos;
219 entry->period_size = runtime->period_size;
220 entry->buffer_size = runtime->buffer_size;;
221 entry->old_hw_ptr = runtime->status->hw_ptr;
222 entry->hw_ptr_base = runtime->hw_ptr_base;
223 log->idx = (log->idx + 1) % XRUN_LOG_CNT;
224}
225
226static void xrun_log_show(struct snd_pcm_substream *substream)
227{
228 struct snd_pcm_hwptr_log *log = substream->runtime->hwptr_log;
229 struct hwptr_log_entry *entry;
230 char name[16];
231 unsigned int idx;
232 int cnt;
233
234 if (log == NULL)
235 return;
236 if (xrun_debug(substream, XRUN_DEBUG_LOGONCE) && log->hit)
237 return;
238 pcm_debug_name(substream, name, sizeof(name));
239 for (cnt = 0, idx = log->idx; cnt < XRUN_LOG_CNT; cnt++) {
240 entry = &log->entries[idx];
241 if (entry->period_size == 0)
242 break;
243 snd_printd("hwptr log: %s: j=%lu, pos=%ld/%ld/%ld, "
244 "hwptr=%ld/%ld\n",
245 name, entry->jiffies, (unsigned long)entry->pos,
246 (unsigned long)entry->period_size,
247 (unsigned long)entry->buffer_size,
248 (unsigned long)entry->old_hw_ptr,
249 (unsigned long)entry->hw_ptr_base);
250 idx++;
251 idx %= XRUN_LOG_CNT;
252 }
253 log->hit = 1;
187} 254}
188 255
189static int snd_pcm_update_hw_ptr_post(struct snd_pcm_substream *substream, 256#else /* ! CONFIG_SND_PCM_XRUN_DEBUG */
190 struct snd_pcm_runtime *runtime) 257
258#define xrun_debug(substream, mask) 0
259#define xrun(substream) do { } while (0)
260#define hw_ptr_error(substream, fmt, args...) do { } while (0)
261#define xrun_log(substream, pos) do { } while (0)
262#define xrun_log_show(substream) do { } while (0)
263
264#endif
265
266int snd_pcm_update_state(struct snd_pcm_substream *substream,
267 struct snd_pcm_runtime *runtime)
191{ 268{
192 snd_pcm_uframes_t avail; 269 snd_pcm_uframes_t avail;
193 270
@@ -209,88 +286,94 @@ static int snd_pcm_update_hw_ptr_post(struct snd_pcm_substream *substream,
209 } 286 }
210 } 287 }
211 if (avail >= runtime->control->avail_min) 288 if (avail >= runtime->control->avail_min)
212 wake_up(&runtime->sleep); 289 wake_up(runtime->twake ? &runtime->tsleep : &runtime->sleep);
213 return 0; 290 return 0;
214} 291}
215 292
216#define hw_ptr_error(substream, fmt, args...) \ 293static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
217 do { \ 294 unsigned int in_interrupt)
218 if (xrun_debug(substream, 1)) { \
219 if (printk_ratelimit()) { \
220 snd_printd("PCM: " fmt, ##args); \
221 } \
222 dump_stack_on_xrun(substream); \
223 } \
224 } while (0)
225
226static int snd_pcm_update_hw_ptr_interrupt(struct snd_pcm_substream *substream)
227{ 295{
228 struct snd_pcm_runtime *runtime = substream->runtime; 296 struct snd_pcm_runtime *runtime = substream->runtime;
229 snd_pcm_uframes_t pos; 297 snd_pcm_uframes_t pos;
230 snd_pcm_uframes_t old_hw_ptr, new_hw_ptr, hw_ptr_interrupt, hw_base; 298 snd_pcm_uframes_t old_hw_ptr, new_hw_ptr, hw_base;
231 snd_pcm_sframes_t hdelta, delta; 299 snd_pcm_sframes_t hdelta, delta;
232 unsigned long jdelta; 300 unsigned long jdelta;
233 301
234 old_hw_ptr = runtime->status->hw_ptr; 302 old_hw_ptr = runtime->status->hw_ptr;
235 pos = snd_pcm_update_hw_ptr_pos(substream, runtime); 303 pos = substream->ops->pointer(substream);
236 if (pos == SNDRV_PCM_POS_XRUN) { 304 if (pos == SNDRV_PCM_POS_XRUN) {
237 xrun(substream); 305 xrun(substream);
238 return -EPIPE; 306 return -EPIPE;
239 } 307 }
240 if (xrun_debug(substream, 8)) { 308 if (pos >= runtime->buffer_size) {
241 char name[16]; 309 if (printk_ratelimit()) {
242 pcm_debug_name(substream, name, sizeof(name)); 310 char name[16];
243 snd_printd("period_update: %s: pos=0x%x/0x%x/0x%x, " 311 pcm_debug_name(substream, name, sizeof(name));
244 "hwptr=0x%lx, hw_base=0x%lx, hw_intr=0x%lx\n", 312 xrun_log_show(substream);
245 name, (unsigned int)pos, 313 snd_printd(KERN_ERR "BUG: %s, pos = %ld, "
246 (unsigned int)runtime->period_size, 314 "buffer size = %ld, period size = %ld\n",
247 (unsigned int)runtime->buffer_size, 315 name, pos, runtime->buffer_size,
248 (unsigned long)old_hw_ptr, 316 runtime->period_size);
249 (unsigned long)runtime->hw_ptr_base, 317 }
250 (unsigned long)runtime->hw_ptr_interrupt); 318 pos = 0;
251 } 319 }
320 pos -= pos % runtime->min_align;
321 if (xrun_debug(substream, XRUN_DEBUG_LOG))
322 xrun_log(substream, pos);
252 hw_base = runtime->hw_ptr_base; 323 hw_base = runtime->hw_ptr_base;
253 new_hw_ptr = hw_base + pos; 324 new_hw_ptr = hw_base + pos;
254 hw_ptr_interrupt = runtime->hw_ptr_interrupt + runtime->period_size; 325 if (in_interrupt) {
255 delta = new_hw_ptr - hw_ptr_interrupt; 326 /* we know that one period was processed */
256 if (hw_ptr_interrupt >= runtime->boundary) { 327 /* delta = "expected next hw_ptr" for in_interrupt != 0 */
257 hw_ptr_interrupt -= runtime->boundary; 328 delta = runtime->hw_ptr_interrupt + runtime->period_size;
258 if (hw_base < runtime->boundary / 2) 329 if (delta > new_hw_ptr) {
259 /* hw_base was already lapped; recalc delta */
260 delta = new_hw_ptr - hw_ptr_interrupt;
261 }
262 if (delta < 0) {
263 if (runtime->periods == 1 || new_hw_ptr < old_hw_ptr)
264 delta += runtime->buffer_size;
265 if (delta < 0) {
266 hw_ptr_error(substream,
267 "Unexpected hw_pointer value "
268 "(stream=%i, pos=%ld, intr_ptr=%ld)\n",
269 substream->stream, (long)pos,
270 (long)hw_ptr_interrupt);
271#if 1
272 /* simply skipping the hwptr update seems more
273 * robust in some cases, e.g. on VMware with
274 * inaccurate timer source
275 */
276 return 0; /* skip this update */
277#else
278 /* rebase to interrupt position */
279 hw_base = new_hw_ptr = hw_ptr_interrupt;
280 /* align hw_base to buffer_size */
281 hw_base -= hw_base % runtime->buffer_size;
282 delta = 0;
283#endif
284 } else {
285 hw_base += runtime->buffer_size; 330 hw_base += runtime->buffer_size;
286 if (hw_base >= runtime->boundary) 331 if (hw_base >= runtime->boundary)
287 hw_base = 0; 332 hw_base = 0;
288 new_hw_ptr = hw_base + pos; 333 new_hw_ptr = hw_base + pos;
334 goto __delta;
289 } 335 }
290 } 336 }
337 /* new_hw_ptr might be lower than old_hw_ptr in case when */
338 /* pointer crosses the end of the ring buffer */
339 if (new_hw_ptr < old_hw_ptr) {
340 hw_base += runtime->buffer_size;
341 if (hw_base >= runtime->boundary)
342 hw_base = 0;
343 new_hw_ptr = hw_base + pos;
344 }
345 __delta:
346 delta = (new_hw_ptr - old_hw_ptr) % runtime->boundary;
347 if (xrun_debug(substream, in_interrupt ?
348 XRUN_DEBUG_PERIODUPDATE : XRUN_DEBUG_HWPTRUPDATE)) {
349 char name[16];
350 pcm_debug_name(substream, name, sizeof(name));
351 snd_printd("%s_update: %s: pos=%u/%u/%u, "
352 "hwptr=%ld/%ld/%ld/%ld\n",
353 in_interrupt ? "period" : "hwptr",
354 name,
355 (unsigned int)pos,
356 (unsigned int)runtime->period_size,
357 (unsigned int)runtime->buffer_size,
358 (unsigned long)delta,
359 (unsigned long)old_hw_ptr,
360 (unsigned long)new_hw_ptr,
361 (unsigned long)runtime->hw_ptr_base);
362 }
363 /* something must be really wrong */
364 if (delta >= runtime->buffer_size + runtime->period_size) {
365 hw_ptr_error(substream,
366 "Unexpected hw_pointer value %s"
367 "(stream=%i, pos=%ld, new_hw_ptr=%ld, "
368 "old_hw_ptr=%ld)\n",
369 in_interrupt ? "[Q] " : "[P]",
370 substream->stream, (long)pos,
371 (long)new_hw_ptr, (long)old_hw_ptr);
372 return 0;
373 }
291 374
292 /* Do jiffies check only in xrun_debug mode */ 375 /* Do jiffies check only in xrun_debug mode */
293 if (!xrun_debug(substream, 4)) 376 if (!xrun_debug(substream, XRUN_DEBUG_JIFFIESCHECK))
294 goto no_jiffies_check; 377 goto no_jiffies_check;
295 378
296 /* Skip the jiffies check for hardwares with BATCH flag. 379 /* Skip the jiffies check for hardwares with BATCH flag.
@@ -299,7 +382,7 @@ static int snd_pcm_update_hw_ptr_interrupt(struct snd_pcm_substream *substream)
299 */ 382 */
300 if (runtime->hw.info & SNDRV_PCM_INFO_BATCH) 383 if (runtime->hw.info & SNDRV_PCM_INFO_BATCH)
301 goto no_jiffies_check; 384 goto no_jiffies_check;
302 hdelta = new_hw_ptr - old_hw_ptr; 385 hdelta = delta;
303 if (hdelta < runtime->delay) 386 if (hdelta < runtime->delay)
304 goto no_jiffies_check; 387 goto no_jiffies_check;
305 hdelta -= runtime->delay; 388 hdelta -= runtime->delay;
@@ -308,130 +391,68 @@ static int snd_pcm_update_hw_ptr_interrupt(struct snd_pcm_substream *substream)
308 delta = jdelta / 391 delta = jdelta /
309 (((runtime->period_size * HZ) / runtime->rate) 392 (((runtime->period_size * HZ) / runtime->rate)
310 + HZ/100); 393 + HZ/100);
394 /* move new_hw_ptr according jiffies not pos variable */
395 new_hw_ptr = old_hw_ptr;
396 hw_base = delta;
397 /* use loop to avoid checks for delta overflows */
398 /* the delta value is small or zero in most cases */
399 while (delta > 0) {
400 new_hw_ptr += runtime->period_size;
401 if (new_hw_ptr >= runtime->boundary)
402 new_hw_ptr -= runtime->boundary;
403 delta--;
404 }
405 /* align hw_base to buffer_size */
311 hw_ptr_error(substream, 406 hw_ptr_error(substream,
312 "hw_ptr skipping! [Q] " 407 "hw_ptr skipping! %s"
313 "(pos=%ld, delta=%ld, period=%ld, " 408 "(pos=%ld, delta=%ld, period=%ld, "
314 "jdelta=%lu/%lu/%lu)\n", 409 "jdelta=%lu/%lu/%lu, hw_ptr=%ld/%ld)\n",
410 in_interrupt ? "[Q] " : "",
315 (long)pos, (long)hdelta, 411 (long)pos, (long)hdelta,
316 (long)runtime->period_size, jdelta, 412 (long)runtime->period_size, jdelta,
317 ((hdelta * HZ) / runtime->rate), delta); 413 ((hdelta * HZ) / runtime->rate), hw_base,
318 hw_ptr_interrupt = runtime->hw_ptr_interrupt + 414 (unsigned long)old_hw_ptr,
319 runtime->period_size * delta; 415 (unsigned long)new_hw_ptr);
320 if (hw_ptr_interrupt >= runtime->boundary) 416 /* reset values to proper state */
321 hw_ptr_interrupt -= runtime->boundary;
322 /* rebase to interrupt position */
323 hw_base = new_hw_ptr = hw_ptr_interrupt;
324 /* align hw_base to buffer_size */
325 hw_base -= hw_base % runtime->buffer_size;
326 delta = 0; 417 delta = 0;
418 hw_base = new_hw_ptr - (new_hw_ptr % runtime->buffer_size);
327 } 419 }
328 no_jiffies_check: 420 no_jiffies_check:
329 if (delta > runtime->period_size + runtime->period_size / 2) { 421 if (delta > runtime->period_size + runtime->period_size / 2) {
330 hw_ptr_error(substream, 422 hw_ptr_error(substream,
331 "Lost interrupts? " 423 "Lost interrupts? %s"
332 "(stream=%i, delta=%ld, intr_ptr=%ld)\n", 424 "(stream=%i, delta=%ld, new_hw_ptr=%ld, "
425 "old_hw_ptr=%ld)\n",
426 in_interrupt ? "[Q] " : "",
333 substream->stream, (long)delta, 427 substream->stream, (long)delta,
334 (long)hw_ptr_interrupt); 428 (long)new_hw_ptr,
335 /* rebase hw_ptr_interrupt */ 429 (long)old_hw_ptr);
336 hw_ptr_interrupt =
337 new_hw_ptr - new_hw_ptr % runtime->period_size;
338 } 430 }
339 runtime->hw_ptr_interrupt = hw_ptr_interrupt; 431
432 if (runtime->status->hw_ptr == new_hw_ptr)
433 return 0;
340 434
341 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && 435 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
342 runtime->silence_size > 0) 436 runtime->silence_size > 0)
343 snd_pcm_playback_silence(substream, new_hw_ptr); 437 snd_pcm_playback_silence(substream, new_hw_ptr);
344 438
345 if (runtime->status->hw_ptr == new_hw_ptr) 439 if (in_interrupt) {
346 return 0; 440 runtime->hw_ptr_interrupt = new_hw_ptr -
347 441 (new_hw_ptr % runtime->period_size);
442 }
348 runtime->hw_ptr_base = hw_base; 443 runtime->hw_ptr_base = hw_base;
349 runtime->status->hw_ptr = new_hw_ptr; 444 runtime->status->hw_ptr = new_hw_ptr;
350 runtime->hw_ptr_jiffies = jiffies; 445 runtime->hw_ptr_jiffies = jiffies;
351 if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE) 446 if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE)
352 snd_pcm_gettime(runtime, (struct timespec *)&runtime->status->tstamp); 447 snd_pcm_gettime(runtime, (struct timespec *)&runtime->status->tstamp);
353 448
354 return snd_pcm_update_hw_ptr_post(substream, runtime); 449 return snd_pcm_update_state(substream, runtime);
355} 450}
356 451
357/* CAUTION: call it with irq disabled */ 452/* CAUTION: call it with irq disabled */
358int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream) 453int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream)
359{ 454{
360 struct snd_pcm_runtime *runtime = substream->runtime; 455 return snd_pcm_update_hw_ptr0(substream, 0);
361 snd_pcm_uframes_t pos;
362 snd_pcm_uframes_t old_hw_ptr, new_hw_ptr, hw_base;
363 snd_pcm_sframes_t delta;
364 unsigned long jdelta;
365
366 old_hw_ptr = runtime->status->hw_ptr;
367 pos = snd_pcm_update_hw_ptr_pos(substream, runtime);
368 if (pos == SNDRV_PCM_POS_XRUN) {
369 xrun(substream);
370 return -EPIPE;
371 }
372 if (xrun_debug(substream, 16)) {
373 char name[16];
374 pcm_debug_name(substream, name, sizeof(name));
375 snd_printd("hw_update: %s: pos=0x%x/0x%x/0x%x, "
376 "hwptr=0x%lx, hw_base=0x%lx, hw_intr=0x%lx\n",
377 name, (unsigned int)pos,
378 (unsigned int)runtime->period_size,
379 (unsigned int)runtime->buffer_size,
380 (unsigned long)old_hw_ptr,
381 (unsigned long)runtime->hw_ptr_base,
382 (unsigned long)runtime->hw_ptr_interrupt);
383 }
384
385 hw_base = runtime->hw_ptr_base;
386 new_hw_ptr = hw_base + pos;
387
388 delta = new_hw_ptr - old_hw_ptr;
389 jdelta = jiffies - runtime->hw_ptr_jiffies;
390 if (delta < 0) {
391 delta += runtime->buffer_size;
392 if (delta < 0) {
393 hw_ptr_error(substream,
394 "Unexpected hw_pointer value [2] "
395 "(stream=%i, pos=%ld, old_ptr=%ld, jdelta=%li)\n",
396 substream->stream, (long)pos,
397 (long)old_hw_ptr, jdelta);
398 return 0;
399 }
400 hw_base += runtime->buffer_size;
401 if (hw_base >= runtime->boundary)
402 hw_base = 0;
403 new_hw_ptr = hw_base + pos;
404 }
405 /* Do jiffies check only in xrun_debug mode */
406 if (!xrun_debug(substream, 4))
407 goto no_jiffies_check;
408 if (delta < runtime->delay)
409 goto no_jiffies_check;
410 delta -= runtime->delay;
411 if (((delta * HZ) / runtime->rate) > jdelta + HZ/100) {
412 hw_ptr_error(substream,
413 "hw_ptr skipping! "
414 "(pos=%ld, delta=%ld, period=%ld, jdelta=%lu/%lu)\n",
415 (long)pos, (long)delta,
416 (long)runtime->period_size, jdelta,
417 ((delta * HZ) / runtime->rate));
418 return 0;
419 }
420 no_jiffies_check:
421 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
422 runtime->silence_size > 0)
423 snd_pcm_playback_silence(substream, new_hw_ptr);
424
425 if (runtime->status->hw_ptr == new_hw_ptr)
426 return 0;
427
428 runtime->hw_ptr_base = hw_base;
429 runtime->status->hw_ptr = new_hw_ptr;
430 runtime->hw_ptr_jiffies = jiffies;
431 if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE)
432 snd_pcm_gettime(runtime, (struct timespec *)&runtime->status->tstamp);
433
434 return snd_pcm_update_hw_ptr_post(substream, runtime);
435} 456}
436 457
437/** 458/**
@@ -745,10 +766,13 @@ int snd_interval_ratnum(struct snd_interval *i,
745 unsigned int rats_count, struct snd_ratnum *rats, 766 unsigned int rats_count, struct snd_ratnum *rats,
746 unsigned int *nump, unsigned int *denp) 767 unsigned int *nump, unsigned int *denp)
747{ 768{
748 unsigned int best_num, best_diff, best_den; 769 unsigned int best_num, best_den;
770 int best_diff;
749 unsigned int k; 771 unsigned int k;
750 struct snd_interval t; 772 struct snd_interval t;
751 int err; 773 int err;
774 unsigned int result_num, result_den;
775 int result_diff;
752 776
753 best_num = best_den = best_diff = 0; 777 best_num = best_den = best_diff = 0;
754 for (k = 0; k < rats_count; ++k) { 778 for (k = 0; k < rats_count; ++k) {
@@ -770,6 +794,8 @@ int snd_interval_ratnum(struct snd_interval *i,
770 den -= r; 794 den -= r;
771 } 795 }
772 diff = num - q * den; 796 diff = num - q * den;
797 if (diff < 0)
798 diff = -diff;
773 if (best_num == 0 || 799 if (best_num == 0 ||
774 diff * best_den < best_diff * den) { 800 diff * best_den < best_diff * den) {
775 best_diff = diff; 801 best_diff = diff;
@@ -784,6 +810,9 @@ int snd_interval_ratnum(struct snd_interval *i,
784 t.min = div_down(best_num, best_den); 810 t.min = div_down(best_num, best_den);
785 t.openmin = !!(best_num % best_den); 811 t.openmin = !!(best_num % best_den);
786 812
813 result_num = best_num;
814 result_diff = best_diff;
815 result_den = best_den;
787 best_num = best_den = best_diff = 0; 816 best_num = best_den = best_diff = 0;
788 for (k = 0; k < rats_count; ++k) { 817 for (k = 0; k < rats_count; ++k) {
789 unsigned int num = rats[k].num; 818 unsigned int num = rats[k].num;
@@ -806,6 +835,8 @@ int snd_interval_ratnum(struct snd_interval *i,
806 den += rats[k].den_step - r; 835 den += rats[k].den_step - r;
807 } 836 }
808 diff = q * den - num; 837 diff = q * den - num;
838 if (diff < 0)
839 diff = -diff;
809 if (best_num == 0 || 840 if (best_num == 0 ||
810 diff * best_den < best_diff * den) { 841 diff * best_den < best_diff * den) {
811 best_diff = diff; 842 best_diff = diff;
@@ -825,10 +856,14 @@ int snd_interval_ratnum(struct snd_interval *i,
825 return err; 856 return err;
826 857
827 if (snd_interval_single(i)) { 858 if (snd_interval_single(i)) {
859 if (best_diff * result_den < result_diff * best_den) {
860 result_num = best_num;
861 result_den = best_den;
862 }
828 if (nump) 863 if (nump)
829 *nump = best_num; 864 *nump = result_num;
830 if (denp) 865 if (denp)
831 *denp = best_den; 866 *denp = result_den;
832 } 867 }
833 return err; 868 return err;
834} 869}
@@ -1643,7 +1678,7 @@ void snd_pcm_period_elapsed(struct snd_pcm_substream *substream)
1643 1678
1644 snd_pcm_stream_lock_irqsave(substream, flags); 1679 snd_pcm_stream_lock_irqsave(substream, flags);
1645 if (!snd_pcm_running(substream) || 1680 if (!snd_pcm_running(substream) ||
1646 snd_pcm_update_hw_ptr_interrupt(substream) < 0) 1681 snd_pcm_update_hw_ptr0(substream, 1) < 0)
1647 goto _end; 1682 goto _end;
1648 1683
1649 if (substream->timer_running) 1684 if (substream->timer_running)
@@ -1674,7 +1709,7 @@ static int wait_for_avail_min(struct snd_pcm_substream *substream,
1674 long tout; 1709 long tout;
1675 1710
1676 init_waitqueue_entry(&wait, current); 1711 init_waitqueue_entry(&wait, current);
1677 add_wait_queue(&runtime->sleep, &wait); 1712 add_wait_queue(&runtime->tsleep, &wait);
1678 for (;;) { 1713 for (;;) {
1679 if (signal_pending(current)) { 1714 if (signal_pending(current)) {
1680 err = -ERESTARTSYS; 1715 err = -ERESTARTSYS;
@@ -1717,7 +1752,7 @@ static int wait_for_avail_min(struct snd_pcm_substream *substream,
1717 break; 1752 break;
1718 } 1753 }
1719 _endloop: 1754 _endloop:
1720 remove_wait_queue(&runtime->sleep, &wait); 1755 remove_wait_queue(&runtime->tsleep, &wait);
1721 *availp = avail; 1756 *availp = avail;
1722 return err; 1757 return err;
1723} 1758}
@@ -1776,6 +1811,7 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream,
1776 goto _end_unlock; 1811 goto _end_unlock;
1777 } 1812 }
1778 1813
1814 runtime->twake = 1;
1779 while (size > 0) { 1815 while (size > 0) {
1780 snd_pcm_uframes_t frames, appl_ptr, appl_ofs; 1816 snd_pcm_uframes_t frames, appl_ptr, appl_ofs;
1781 snd_pcm_uframes_t avail; 1817 snd_pcm_uframes_t avail;
@@ -1797,15 +1833,17 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream,
1797 if (frames > cont) 1833 if (frames > cont)
1798 frames = cont; 1834 frames = cont;
1799 if (snd_BUG_ON(!frames)) { 1835 if (snd_BUG_ON(!frames)) {
1836 runtime->twake = 0;
1800 snd_pcm_stream_unlock_irq(substream); 1837 snd_pcm_stream_unlock_irq(substream);
1801 return -EINVAL; 1838 return -EINVAL;
1802 } 1839 }
1803 appl_ptr = runtime->control->appl_ptr; 1840 appl_ptr = runtime->control->appl_ptr;
1804 appl_ofs = appl_ptr % runtime->buffer_size; 1841 appl_ofs = appl_ptr % runtime->buffer_size;
1805 snd_pcm_stream_unlock_irq(substream); 1842 snd_pcm_stream_unlock_irq(substream);
1806 if ((err = transfer(substream, appl_ofs, data, offset, frames)) < 0) 1843 err = transfer(substream, appl_ofs, data, offset, frames);
1807 goto _end;
1808 snd_pcm_stream_lock_irq(substream); 1844 snd_pcm_stream_lock_irq(substream);
1845 if (err < 0)
1846 goto _end_unlock;
1809 switch (runtime->status->state) { 1847 switch (runtime->status->state) {
1810 case SNDRV_PCM_STATE_XRUN: 1848 case SNDRV_PCM_STATE_XRUN:
1811 err = -EPIPE; 1849 err = -EPIPE;
@@ -1834,8 +1872,10 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream,
1834 } 1872 }
1835 } 1873 }
1836 _end_unlock: 1874 _end_unlock:
1875 runtime->twake = 0;
1876 if (xfer > 0 && err >= 0)
1877 snd_pcm_update_state(substream, runtime);
1837 snd_pcm_stream_unlock_irq(substream); 1878 snd_pcm_stream_unlock_irq(substream);
1838 _end:
1839 return xfer > 0 ? (snd_pcm_sframes_t)xfer : err; 1879 return xfer > 0 ? (snd_pcm_sframes_t)xfer : err;
1840} 1880}
1841 1881
@@ -1993,6 +2033,7 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream,
1993 goto _end_unlock; 2033 goto _end_unlock;
1994 } 2034 }
1995 2035
2036 runtime->twake = 1;
1996 while (size > 0) { 2037 while (size > 0) {
1997 snd_pcm_uframes_t frames, appl_ptr, appl_ofs; 2038 snd_pcm_uframes_t frames, appl_ptr, appl_ofs;
1998 snd_pcm_uframes_t avail; 2039 snd_pcm_uframes_t avail;
@@ -2021,15 +2062,17 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream,
2021 if (frames > cont) 2062 if (frames > cont)
2022 frames = cont; 2063 frames = cont;
2023 if (snd_BUG_ON(!frames)) { 2064 if (snd_BUG_ON(!frames)) {
2065 runtime->twake = 0;
2024 snd_pcm_stream_unlock_irq(substream); 2066 snd_pcm_stream_unlock_irq(substream);
2025 return -EINVAL; 2067 return -EINVAL;
2026 } 2068 }
2027 appl_ptr = runtime->control->appl_ptr; 2069 appl_ptr = runtime->control->appl_ptr;
2028 appl_ofs = appl_ptr % runtime->buffer_size; 2070 appl_ofs = appl_ptr % runtime->buffer_size;
2029 snd_pcm_stream_unlock_irq(substream); 2071 snd_pcm_stream_unlock_irq(substream);
2030 if ((err = transfer(substream, appl_ofs, data, offset, frames)) < 0) 2072 err = transfer(substream, appl_ofs, data, offset, frames);
2031 goto _end;
2032 snd_pcm_stream_lock_irq(substream); 2073 snd_pcm_stream_lock_irq(substream);
2074 if (err < 0)
2075 goto _end_unlock;
2033 switch (runtime->status->state) { 2076 switch (runtime->status->state) {
2034 case SNDRV_PCM_STATE_XRUN: 2077 case SNDRV_PCM_STATE_XRUN:
2035 err = -EPIPE; 2078 err = -EPIPE;
@@ -2052,8 +2095,10 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream,
2052 xfer += frames; 2095 xfer += frames;
2053 } 2096 }
2054 _end_unlock: 2097 _end_unlock:
2098 runtime->twake = 0;
2099 if (xfer > 0 && err >= 0)
2100 snd_pcm_update_state(substream, runtime);
2055 snd_pcm_stream_unlock_irq(substream); 2101 snd_pcm_stream_unlock_irq(substream);
2056 _end:
2057 return xfer > 0 ? (snd_pcm_sframes_t)xfer : err; 2102 return xfer > 0 ? (snd_pcm_sframes_t)xfer : err;
2058} 2103}
2059 2104
diff --git a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c
index caa7796bc2f5..d6d49d6651f9 100644
--- a/sound/core/pcm_memory.c
+++ b/sound/core/pcm_memory.c
@@ -23,6 +23,7 @@
23#include <linux/time.h> 23#include <linux/time.h>
24#include <linux/init.h> 24#include <linux/init.h>
25#include <linux/moduleparam.h> 25#include <linux/moduleparam.h>
26#include <linux/vmalloc.h>
26#include <sound/core.h> 27#include <sound/core.h>
27#include <sound/pcm.h> 28#include <sound/pcm.h>
28#include <sound/info.h> 29#include <sound/info.h>
@@ -434,3 +435,57 @@ int snd_pcm_lib_free_pages(struct snd_pcm_substream *substream)
434} 435}
435 436
436EXPORT_SYMBOL(snd_pcm_lib_free_pages); 437EXPORT_SYMBOL(snd_pcm_lib_free_pages);
438
439int _snd_pcm_lib_alloc_vmalloc_buffer(struct snd_pcm_substream *substream,
440 size_t size, gfp_t gfp_flags)
441{
442 struct snd_pcm_runtime *runtime;
443
444 if (PCM_RUNTIME_CHECK(substream))
445 return -EINVAL;
446 runtime = substream->runtime;
447 if (runtime->dma_area) {
448 if (runtime->dma_bytes >= size)
449 return 0; /* already large enough */
450 vfree(runtime->dma_area);
451 }
452 runtime->dma_area = __vmalloc(size, gfp_flags, PAGE_KERNEL);
453 if (!runtime->dma_area)
454 return -ENOMEM;
455 runtime->dma_bytes = size;
456 return 1;
457}
458EXPORT_SYMBOL(_snd_pcm_lib_alloc_vmalloc_buffer);
459
460/**
461 * snd_pcm_lib_free_vmalloc_buffer - free vmalloc buffer
462 * @substream: the substream with a buffer allocated by
463 * snd_pcm_lib_alloc_vmalloc_buffer()
464 */
465int snd_pcm_lib_free_vmalloc_buffer(struct snd_pcm_substream *substream)
466{
467 struct snd_pcm_runtime *runtime;
468
469 if (PCM_RUNTIME_CHECK(substream))
470 return -EINVAL;
471 runtime = substream->runtime;
472 vfree(runtime->dma_area);
473 runtime->dma_area = NULL;
474 return 0;
475}
476EXPORT_SYMBOL(snd_pcm_lib_free_vmalloc_buffer);
477
478/**
479 * snd_pcm_lib_get_vmalloc_page - map vmalloc buffer offset to page struct
480 * @substream: the substream with a buffer allocated by
481 * snd_pcm_lib_alloc_vmalloc_buffer()
482 * @offset: offset in the buffer
483 *
484 * This function is to be used as the page callback in the PCM ops.
485 */
486struct page *snd_pcm_lib_get_vmalloc_page(struct snd_pcm_substream *substream,
487 unsigned long offset)
488{
489 return vmalloc_to_page(substream->runtime->dma_area + offset);
490}
491EXPORT_SYMBOL(snd_pcm_lib_get_vmalloc_page);
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 25b0641e6b8c..872887624030 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -27,6 +27,7 @@
27#include <linux/pm_qos_params.h> 27#include <linux/pm_qos_params.h>
28#include <linux/uio.h> 28#include <linux/uio.h>
29#include <linux/dma-mapping.h> 29#include <linux/dma-mapping.h>
30#include <linux/math64.h>
30#include <sound/core.h> 31#include <sound/core.h>
31#include <sound/control.h> 32#include <sound/control.h>
32#include <sound/info.h> 33#include <sound/info.h>
@@ -315,10 +316,10 @@ int snd_pcm_hw_refine(struct snd_pcm_substream *substream,
315 if (!params->info) 316 if (!params->info)
316 params->info = hw->info & ~SNDRV_PCM_INFO_FIFO_IN_FRAMES; 317 params->info = hw->info & ~SNDRV_PCM_INFO_FIFO_IN_FRAMES;
317 if (!params->fifo_size) { 318 if (!params->fifo_size) {
318 if (snd_mask_min(&params->masks[SNDRV_PCM_HW_PARAM_FORMAT]) == 319 m = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
319 snd_mask_max(&params->masks[SNDRV_PCM_HW_PARAM_FORMAT]) && 320 i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
320 snd_mask_min(&params->masks[SNDRV_PCM_HW_PARAM_CHANNELS]) == 321 if (snd_mask_min(m) == snd_mask_max(m) &&
321 snd_mask_max(&params->masks[SNDRV_PCM_HW_PARAM_CHANNELS])) { 322 snd_interval_min(i) == snd_interval_max(i)) {
322 changed = substream->ops->ioctl(substream, 323 changed = substream->ops->ioctl(substream,
323 SNDRV_PCM_IOCTL1_FIFO_SIZE, params); 324 SNDRV_PCM_IOCTL1_FIFO_SIZE, params);
324 if (changed < 0) 325 if (changed < 0)
@@ -366,6 +367,38 @@ static int period_to_usecs(struct snd_pcm_runtime *runtime)
366 return usecs; 367 return usecs;
367} 368}
368 369
370static int calc_boundary(struct snd_pcm_runtime *runtime)
371{
372 u_int64_t boundary;
373
374 boundary = (u_int64_t)runtime->buffer_size *
375 (u_int64_t)runtime->period_size;
376#if BITS_PER_LONG < 64
377 /* try to find lowest common multiple for buffer and period */
378 if (boundary > LONG_MAX - runtime->buffer_size) {
379 u_int32_t remainder = -1;
380 u_int32_t divident = runtime->buffer_size;
381 u_int32_t divisor = runtime->period_size;
382 while (remainder) {
383 remainder = divident % divisor;
384 if (remainder) {
385 divident = divisor;
386 divisor = remainder;
387 }
388 }
389 boundary = div_u64(boundary, divisor);
390 if (boundary > LONG_MAX - runtime->buffer_size)
391 return -ERANGE;
392 }
393#endif
394 if (boundary == 0)
395 return -ERANGE;
396 runtime->boundary = boundary;
397 while (runtime->boundary * 2 <= LONG_MAX - runtime->buffer_size)
398 runtime->boundary *= 2;
399 return 0;
400}
401
369static int snd_pcm_hw_params(struct snd_pcm_substream *substream, 402static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
370 struct snd_pcm_hw_params *params) 403 struct snd_pcm_hw_params *params)
371{ 404{
@@ -441,9 +474,9 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
441 runtime->stop_threshold = runtime->buffer_size; 474 runtime->stop_threshold = runtime->buffer_size;
442 runtime->silence_threshold = 0; 475 runtime->silence_threshold = 0;
443 runtime->silence_size = 0; 476 runtime->silence_size = 0;
444 runtime->boundary = runtime->buffer_size; 477 err = calc_boundary(runtime);
445 while (runtime->boundary * 2 <= LONG_MAX - runtime->buffer_size) 478 if (err < 0)
446 runtime->boundary *= 2; 479 goto _error;
447 480
448 snd_pcm_timer_resolution_change(substream); 481 snd_pcm_timer_resolution_change(substream);
449 runtime->status->state = SNDRV_PCM_STATE_SETUP; 482 runtime->status->state = SNDRV_PCM_STATE_SETUP;
@@ -516,6 +549,7 @@ static int snd_pcm_sw_params(struct snd_pcm_substream *substream,
516 struct snd_pcm_sw_params *params) 549 struct snd_pcm_sw_params *params)
517{ 550{
518 struct snd_pcm_runtime *runtime; 551 struct snd_pcm_runtime *runtime;
552 int err;
519 553
520 if (PCM_RUNTIME_CHECK(substream)) 554 if (PCM_RUNTIME_CHECK(substream))
521 return -ENXIO; 555 return -ENXIO;
@@ -540,6 +574,7 @@ static int snd_pcm_sw_params(struct snd_pcm_substream *substream,
540 if (params->silence_threshold > runtime->buffer_size) 574 if (params->silence_threshold > runtime->buffer_size)
541 return -EINVAL; 575 return -EINVAL;
542 } 576 }
577 err = 0;
543 snd_pcm_stream_lock_irq(substream); 578 snd_pcm_stream_lock_irq(substream);
544 runtime->tstamp_mode = params->tstamp_mode; 579 runtime->tstamp_mode = params->tstamp_mode;
545 runtime->period_step = params->period_step; 580 runtime->period_step = params->period_step;
@@ -553,10 +588,10 @@ static int snd_pcm_sw_params(struct snd_pcm_substream *substream,
553 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && 588 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
554 runtime->silence_size > 0) 589 runtime->silence_size > 0)
555 snd_pcm_playback_silence(substream, ULONG_MAX); 590 snd_pcm_playback_silence(substream, ULONG_MAX);
556 wake_up(&runtime->sleep); 591 err = snd_pcm_update_state(substream, runtime);
557 } 592 }
558 snd_pcm_stream_unlock_irq(substream); 593 snd_pcm_stream_unlock_irq(substream);
559 return 0; 594 return err;
560} 595}
561 596
562static int snd_pcm_sw_params_user(struct snd_pcm_substream *substream, 597static int snd_pcm_sw_params_user(struct snd_pcm_substream *substream,
@@ -917,6 +952,7 @@ static void snd_pcm_post_stop(struct snd_pcm_substream *substream, int state)
917 runtime->status->state = state; 952 runtime->status->state = state;
918 } 953 }
919 wake_up(&runtime->sleep); 954 wake_up(&runtime->sleep);
955 wake_up(&runtime->tsleep);
920} 956}
921 957
922static struct action_ops snd_pcm_action_stop = { 958static struct action_ops snd_pcm_action_stop = {
@@ -1002,6 +1038,7 @@ static void snd_pcm_post_pause(struct snd_pcm_substream *substream, int push)
1002 SNDRV_TIMER_EVENT_MPAUSE, 1038 SNDRV_TIMER_EVENT_MPAUSE,
1003 &runtime->trigger_tstamp); 1039 &runtime->trigger_tstamp);
1004 wake_up(&runtime->sleep); 1040 wake_up(&runtime->sleep);
1041 wake_up(&runtime->tsleep);
1005 } else { 1042 } else {
1006 runtime->status->state = SNDRV_PCM_STATE_RUNNING; 1043 runtime->status->state = SNDRV_PCM_STATE_RUNNING;
1007 if (substream->timer) 1044 if (substream->timer)
@@ -1059,6 +1096,7 @@ static void snd_pcm_post_suspend(struct snd_pcm_substream *substream, int state)
1059 runtime->status->suspended_state = runtime->status->state; 1096 runtime->status->suspended_state = runtime->status->state;
1060 runtime->status->state = SNDRV_PCM_STATE_SUSPENDED; 1097 runtime->status->state = SNDRV_PCM_STATE_SUSPENDED;
1061 wake_up(&runtime->sleep); 1098 wake_up(&runtime->sleep);
1099 wake_up(&runtime->tsleep);
1062} 1100}
1063 1101
1064static struct action_ops snd_pcm_action_suspend = { 1102static struct action_ops snd_pcm_action_suspend = {
@@ -3162,9 +3200,7 @@ int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream,
3162 long size; 3200 long size;
3163 unsigned long offset; 3201 unsigned long offset;
3164 3202
3165#ifdef pgprot_noncached
3166 area->vm_page_prot = pgprot_noncached(area->vm_page_prot); 3203 area->vm_page_prot = pgprot_noncached(area->vm_page_prot);
3167#endif
3168 area->vm_flags |= VM_IO; 3204 area->vm_flags |= VM_IO;
3169 size = area->vm_end - area->vm_start; 3205 size = area->vm_end - area->vm_start;
3170 offset = area->vm_pgoff << PAGE_SHIFT; 3206 offset = area->vm_pgoff << PAGE_SHIFT;
@@ -3178,6 +3214,15 @@ int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream,
3178EXPORT_SYMBOL(snd_pcm_lib_mmap_iomem); 3214EXPORT_SYMBOL(snd_pcm_lib_mmap_iomem);
3179#endif /* SNDRV_PCM_INFO_MMAP */ 3215#endif /* SNDRV_PCM_INFO_MMAP */
3180 3216
3217/* mmap callback with pgprot_noncached */
3218int snd_pcm_lib_mmap_noncached(struct snd_pcm_substream *substream,
3219 struct vm_area_struct *area)
3220{
3221 area->vm_page_prot = pgprot_noncached(area->vm_page_prot);
3222 return snd_pcm_default_mmap(substream, area);
3223}
3224EXPORT_SYMBOL(snd_pcm_lib_mmap_noncached);
3225
3181/* 3226/*
3182 * mmap DMA buffer 3227 * mmap DMA buffer
3183 */ 3228 */
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
index 8ca2be339f3b..48eca9ff9ee7 100644
--- a/sound/core/seq/seq_clientmgr.c
+++ b/sound/core/seq/seq_clientmgr.c
@@ -2190,7 +2190,7 @@ static int snd_seq_do_ioctl(struct snd_seq_client *client, unsigned int cmd,
2190 if (p->cmd == cmd) 2190 if (p->cmd == cmd)
2191 return p->func(client, arg); 2191 return p->func(client, arg);
2192 } 2192 }
2193 snd_printd("seq unknown ioctl() 0x%x (type='%c', number=0x%2x)\n", 2193 snd_printd("seq unknown ioctl() 0x%x (type='%c', number=0x%02x)\n",
2194 cmd, _IOC_TYPE(cmd), _IOC_NR(cmd)); 2194 cmd, _IOC_TYPE(cmd), _IOC_NR(cmd));
2195 return -ENOTTY; 2195 return -ENOTTY;
2196} 2196}
diff --git a/sound/core/seq/seq_timer.c b/sound/core/seq/seq_timer.c
index f745c317d6af..160b1bd0cd62 100644
--- a/sound/core/seq/seq_timer.c
+++ b/sound/core/seq/seq_timer.c
@@ -33,22 +33,21 @@
33 33
34#define SKEW_BASE 0x10000 /* 16bit shift */ 34#define SKEW_BASE 0x10000 /* 16bit shift */
35 35
36static void snd_seq_timer_set_tick_resolution(struct snd_seq_timer_tick *tick, 36static void snd_seq_timer_set_tick_resolution(struct snd_seq_timer *tmr)
37 int tempo, int ppq)
38{ 37{
39 if (tempo < 1000000) 38 if (tmr->tempo < 1000000)
40 tick->resolution = (tempo * 1000) / ppq; 39 tmr->tick.resolution = (tmr->tempo * 1000) / tmr->ppq;
41 else { 40 else {
42 /* might overflow.. */ 41 /* might overflow.. */
43 unsigned int s; 42 unsigned int s;
44 s = tempo % ppq; 43 s = tmr->tempo % tmr->ppq;
45 s = (s * 1000) / ppq; 44 s = (s * 1000) / tmr->ppq;
46 tick->resolution = (tempo / ppq) * 1000; 45 tmr->tick.resolution = (tmr->tempo / tmr->ppq) * 1000;
47 tick->resolution += s; 46 tmr->tick.resolution += s;
48 } 47 }
49 if (tick->resolution <= 0) 48 if (tmr->tick.resolution <= 0)
50 tick->resolution = 1; 49 tmr->tick.resolution = 1;
51 snd_seq_timer_update_tick(tick, 0); 50 snd_seq_timer_update_tick(&tmr->tick, 0);
52} 51}
53 52
54/* create new timer (constructor) */ 53/* create new timer (constructor) */
@@ -96,7 +95,7 @@ void snd_seq_timer_defaults(struct snd_seq_timer * tmr)
96 /* setup defaults */ 95 /* setup defaults */
97 tmr->ppq = 96; /* 96 PPQ */ 96 tmr->ppq = 96; /* 96 PPQ */
98 tmr->tempo = 500000; /* 120 BPM */ 97 tmr->tempo = 500000; /* 120 BPM */
99 snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq); 98 snd_seq_timer_set_tick_resolution(tmr);
100 tmr->running = 0; 99 tmr->running = 0;
101 100
102 tmr->type = SNDRV_SEQ_TIMER_ALSA; 101 tmr->type = SNDRV_SEQ_TIMER_ALSA;
@@ -180,7 +179,7 @@ int snd_seq_timer_set_tempo(struct snd_seq_timer * tmr, int tempo)
180 spin_lock_irqsave(&tmr->lock, flags); 179 spin_lock_irqsave(&tmr->lock, flags);
181 if ((unsigned int)tempo != tmr->tempo) { 180 if ((unsigned int)tempo != tmr->tempo) {
182 tmr->tempo = tempo; 181 tmr->tempo = tempo;
183 snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq); 182 snd_seq_timer_set_tick_resolution(tmr);
184 } 183 }
185 spin_unlock_irqrestore(&tmr->lock, flags); 184 spin_unlock_irqrestore(&tmr->lock, flags);
186 return 0; 185 return 0;
@@ -205,7 +204,7 @@ int snd_seq_timer_set_ppq(struct snd_seq_timer * tmr, int ppq)
205 } 204 }
206 205
207 tmr->ppq = ppq; 206 tmr->ppq = ppq;
208 snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq); 207 snd_seq_timer_set_tick_resolution(tmr);
209 spin_unlock_irqrestore(&tmr->lock, flags); 208 spin_unlock_irqrestore(&tmr->lock, flags);
210 return 0; 209 return 0;
211} 210}
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c
index 252e04ce602f..7f41990ed68b 100644
--- a/sound/drivers/dummy.c
+++ b/sound/drivers/dummy.c
@@ -45,109 +45,23 @@ MODULE_SUPPORTED_DEVICE("{{ALSA,Dummy soundcard}}");
45#define MAX_PCM_SUBSTREAMS 128 45#define MAX_PCM_SUBSTREAMS 128
46#define MAX_MIDI_DEVICES 2 46#define MAX_MIDI_DEVICES 2
47 47
48#if 0 /* emu10k1 emulation */
49#define MAX_BUFFER_SIZE (128 * 1024)
50static int emu10k1_playback_constraints(struct snd_pcm_runtime *runtime)
51{
52 int err;
53 err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
54 if (err < 0)
55 return err;
56 err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 256, UINT_MAX);
57 if (err < 0)
58 return err;
59 return 0;
60}
61#define add_playback_constraints emu10k1_playback_constraints
62#endif
63
64#if 0 /* RME9652 emulation */
65#define MAX_BUFFER_SIZE (26 * 64 * 1024)
66#define USE_FORMATS SNDRV_PCM_FMTBIT_S32_LE
67#define USE_CHANNELS_MIN 26
68#define USE_CHANNELS_MAX 26
69#define USE_PERIODS_MIN 2
70#define USE_PERIODS_MAX 2
71#endif
72
73#if 0 /* ICE1712 emulation */
74#define MAX_BUFFER_SIZE (256 * 1024)
75#define USE_FORMATS SNDRV_PCM_FMTBIT_S32_LE
76#define USE_CHANNELS_MIN 10
77#define USE_CHANNELS_MAX 10
78#define USE_PERIODS_MIN 1
79#define USE_PERIODS_MAX 1024
80#endif
81
82#if 0 /* UDA1341 emulation */
83#define MAX_BUFFER_SIZE (16380)
84#define USE_FORMATS SNDRV_PCM_FMTBIT_S16_LE
85#define USE_CHANNELS_MIN 2
86#define USE_CHANNELS_MAX 2
87#define USE_PERIODS_MIN 2
88#define USE_PERIODS_MAX 255
89#endif
90
91#if 0 /* simple AC97 bridge (intel8x0) with 48kHz AC97 only codec */
92#define USE_FORMATS SNDRV_PCM_FMTBIT_S16_LE
93#define USE_CHANNELS_MIN 2
94#define USE_CHANNELS_MAX 2
95#define USE_RATE SNDRV_PCM_RATE_48000
96#define USE_RATE_MIN 48000
97#define USE_RATE_MAX 48000
98#endif
99
100#if 0 /* CA0106 */
101#define USE_FORMATS SNDRV_PCM_FMTBIT_S16_LE
102#define USE_CHANNELS_MIN 2
103#define USE_CHANNELS_MAX 2
104#define USE_RATE (SNDRV_PCM_RATE_48000|SNDRV_PCM_RATE_96000|SNDRV_PCM_RATE_192000)
105#define USE_RATE_MIN 48000
106#define USE_RATE_MAX 192000
107#define MAX_BUFFER_SIZE ((65536-64)*8)
108#define MAX_PERIOD_SIZE (65536-64)
109#define USE_PERIODS_MIN 2
110#define USE_PERIODS_MAX 8
111#endif
112
113
114/* defaults */ 48/* defaults */
115#ifndef MAX_BUFFER_SIZE
116#define MAX_BUFFER_SIZE (64*1024) 49#define MAX_BUFFER_SIZE (64*1024)
117#endif 50#define MIN_PERIOD_SIZE 64
118#ifndef MAX_PERIOD_SIZE
119#define MAX_PERIOD_SIZE MAX_BUFFER_SIZE 51#define MAX_PERIOD_SIZE MAX_BUFFER_SIZE
120#endif
121#ifndef USE_FORMATS
122#define USE_FORMATS (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE) 52#define USE_FORMATS (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE)
123#endif
124#ifndef USE_RATE
125#define USE_RATE SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000 53#define USE_RATE SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000
126#define USE_RATE_MIN 5500 54#define USE_RATE_MIN 5500
127#define USE_RATE_MAX 48000 55#define USE_RATE_MAX 48000
128#endif
129#ifndef USE_CHANNELS_MIN
130#define USE_CHANNELS_MIN 1 56#define USE_CHANNELS_MIN 1
131#endif
132#ifndef USE_CHANNELS_MAX
133#define USE_CHANNELS_MAX 2 57#define USE_CHANNELS_MAX 2
134#endif
135#ifndef USE_PERIODS_MIN
136#define USE_PERIODS_MIN 1 58#define USE_PERIODS_MIN 1
137#endif
138#ifndef USE_PERIODS_MAX
139#define USE_PERIODS_MAX 1024 59#define USE_PERIODS_MAX 1024
140#endif
141#ifndef add_playback_constraints
142#define add_playback_constraints(x) 0
143#endif
144#ifndef add_capture_constraints
145#define add_capture_constraints(x) 0
146#endif
147 60
148static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ 61static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
149static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ 62static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
150static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0}; 63static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0};
64static char *model[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = NULL};
151static int pcm_devs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; 65static int pcm_devs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
152static int pcm_substreams[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 8}; 66static int pcm_substreams[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 8};
153//static int midi_devs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2}; 67//static int midi_devs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
@@ -162,6 +76,8 @@ module_param_array(id, charp, NULL, 0444);
162MODULE_PARM_DESC(id, "ID string for dummy soundcard."); 76MODULE_PARM_DESC(id, "ID string for dummy soundcard.");
163module_param_array(enable, bool, NULL, 0444); 77module_param_array(enable, bool, NULL, 0444);
164MODULE_PARM_DESC(enable, "Enable this dummy soundcard."); 78MODULE_PARM_DESC(enable, "Enable this dummy soundcard.");
79module_param_array(model, charp, NULL, 0444);
80MODULE_PARM_DESC(model, "Soundcard model.");
165module_param_array(pcm_devs, int, NULL, 0444); 81module_param_array(pcm_devs, int, NULL, 0444);
166MODULE_PARM_DESC(pcm_devs, "PCM devices # (0-4) for dummy driver."); 82MODULE_PARM_DESC(pcm_devs, "PCM devices # (0-4) for dummy driver.");
167module_param_array(pcm_substreams, int, NULL, 0444); 83module_param_array(pcm_substreams, int, NULL, 0444);
@@ -193,9 +109,28 @@ struct dummy_timer_ops {
193 snd_pcm_uframes_t (*pointer)(struct snd_pcm_substream *); 109 snd_pcm_uframes_t (*pointer)(struct snd_pcm_substream *);
194}; 110};
195 111
112struct dummy_model {
113 const char *name;
114 int (*playback_constraints)(struct snd_pcm_runtime *runtime);
115 int (*capture_constraints)(struct snd_pcm_runtime *runtime);
116 u64 formats;
117 size_t buffer_bytes_max;
118 size_t period_bytes_min;
119 size_t period_bytes_max;
120 unsigned int periods_min;
121 unsigned int periods_max;
122 unsigned int rates;
123 unsigned int rate_min;
124 unsigned int rate_max;
125 unsigned int channels_min;
126 unsigned int channels_max;
127};
128
196struct snd_dummy { 129struct snd_dummy {
197 struct snd_card *card; 130 struct snd_card *card;
131 struct dummy_model *model;
198 struct snd_pcm *pcm; 132 struct snd_pcm *pcm;
133 struct snd_pcm_hardware pcm_hw;
199 spinlock_t mixer_lock; 134 spinlock_t mixer_lock;
200 int mixer_volume[MIXER_ADDR_LAST+1][2]; 135 int mixer_volume[MIXER_ADDR_LAST+1][2];
201 int capture_source[MIXER_ADDR_LAST+1][2]; 136 int capture_source[MIXER_ADDR_LAST+1][2];
@@ -203,6 +138,92 @@ struct snd_dummy {
203}; 138};
204 139
205/* 140/*
141 * card models
142 */
143
144static int emu10k1_playback_constraints(struct snd_pcm_runtime *runtime)
145{
146 int err;
147 err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
148 if (err < 0)
149 return err;
150 err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 256, UINT_MAX);
151 if (err < 0)
152 return err;
153 return 0;
154}
155
156struct dummy_model model_emu10k1 = {
157 .name = "emu10k1",
158 .playback_constraints = emu10k1_playback_constraints,
159 .buffer_bytes_max = 128 * 1024,
160};
161
162struct dummy_model model_rme9652 = {
163 .name = "rme9652",
164 .buffer_bytes_max = 26 * 64 * 1024,
165 .formats = SNDRV_PCM_FMTBIT_S32_LE,
166 .channels_min = 26,
167 .channels_max = 26,
168 .periods_min = 2,
169 .periods_max = 2,
170};
171
172struct dummy_model model_ice1712 = {
173 .name = "ice1712",
174 .buffer_bytes_max = 256 * 1024,
175 .formats = SNDRV_PCM_FMTBIT_S32_LE,
176 .channels_min = 10,
177 .channels_max = 10,
178 .periods_min = 1,
179 .periods_max = 1024,
180};
181
182struct dummy_model model_uda1341 = {
183 .name = "uda1341",
184 .buffer_bytes_max = 16380,
185 .formats = SNDRV_PCM_FMTBIT_S16_LE,
186 .channels_min = 2,
187 .channels_max = 2,
188 .periods_min = 2,
189 .periods_max = 255,
190};
191
192struct dummy_model model_ac97 = {
193 .name = "ac97",
194 .formats = SNDRV_PCM_FMTBIT_S16_LE,
195 .channels_min = 2,
196 .channels_max = 2,
197 .rates = SNDRV_PCM_RATE_48000,
198 .rate_min = 48000,
199 .rate_max = 48000,
200};
201
202struct dummy_model model_ca0106 = {
203 .name = "ca0106",
204 .formats = SNDRV_PCM_FMTBIT_S16_LE,
205 .buffer_bytes_max = ((65536-64)*8),
206 .period_bytes_max = (65536-64),
207 .periods_min = 2,
208 .periods_max = 8,
209 .channels_min = 2,
210 .channels_max = 2,
211 .rates = SNDRV_PCM_RATE_48000|SNDRV_PCM_RATE_96000|SNDRV_PCM_RATE_192000,
212 .rate_min = 48000,
213 .rate_max = 192000,
214};
215
216struct dummy_model *dummy_models[] = {
217 &model_emu10k1,
218 &model_rme9652,
219 &model_ice1712,
220 &model_uda1341,
221 &model_ac97,
222 &model_ca0106,
223 NULL
224};
225
226/*
206 * system timer interface 227 * system timer interface
207 */ 228 */
208 229
@@ -509,7 +530,7 @@ static struct snd_pcm_hardware dummy_pcm_hardware = {
509 .channels_min = USE_CHANNELS_MIN, 530 .channels_min = USE_CHANNELS_MIN,
510 .channels_max = USE_CHANNELS_MAX, 531 .channels_max = USE_CHANNELS_MAX,
511 .buffer_bytes_max = MAX_BUFFER_SIZE, 532 .buffer_bytes_max = MAX_BUFFER_SIZE,
512 .period_bytes_min = 64, 533 .period_bytes_min = MIN_PERIOD_SIZE,
513 .period_bytes_max = MAX_PERIOD_SIZE, 534 .period_bytes_max = MAX_PERIOD_SIZE,
514 .periods_min = USE_PERIODS_MIN, 535 .periods_min = USE_PERIODS_MIN,
515 .periods_max = USE_PERIODS_MAX, 536 .periods_max = USE_PERIODS_MAX,
@@ -538,6 +559,7 @@ static int dummy_pcm_hw_free(struct snd_pcm_substream *substream)
538static int dummy_pcm_open(struct snd_pcm_substream *substream) 559static int dummy_pcm_open(struct snd_pcm_substream *substream)
539{ 560{
540 struct snd_dummy *dummy = snd_pcm_substream_chip(substream); 561 struct snd_dummy *dummy = snd_pcm_substream_chip(substream);
562 struct dummy_model *model = dummy->model;
541 struct snd_pcm_runtime *runtime = substream->runtime; 563 struct snd_pcm_runtime *runtime = substream->runtime;
542 int err; 564 int err;
543 565
@@ -551,7 +573,7 @@ static int dummy_pcm_open(struct snd_pcm_substream *substream)
551 if (err < 0) 573 if (err < 0)
552 return err; 574 return err;
553 575
554 runtime->hw = dummy_pcm_hardware; 576 runtime->hw = dummy->pcm_hw;
555 if (substream->pcm->device & 1) { 577 if (substream->pcm->device & 1) {
556 runtime->hw.info &= ~SNDRV_PCM_INFO_INTERLEAVED; 578 runtime->hw.info &= ~SNDRV_PCM_INFO_INTERLEAVED;
557 runtime->hw.info |= SNDRV_PCM_INFO_NONINTERLEAVED; 579 runtime->hw.info |= SNDRV_PCM_INFO_NONINTERLEAVED;
@@ -560,10 +582,16 @@ static int dummy_pcm_open(struct snd_pcm_substream *substream)
560 runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP | 582 runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP |
561 SNDRV_PCM_INFO_MMAP_VALID); 583 SNDRV_PCM_INFO_MMAP_VALID);
562 584
563 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 585 if (model == NULL)
564 err = add_playback_constraints(substream->runtime); 586 return 0;
565 else 587
566 err = add_capture_constraints(substream->runtime); 588 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
589 if (model->playback_constraints)
590 err = model->playback_constraints(substream->runtime);
591 } else {
592 if (model->capture_constraints)
593 err = model->capture_constraints(substream->runtime);
594 }
567 if (err < 0) { 595 if (err < 0) {
568 dummy->timer_ops->free(substream); 596 dummy->timer_ops->free(substream);
569 return err; 597 return err;
@@ -823,17 +851,19 @@ static int __devinit snd_card_dummy_new_mixer(struct snd_dummy *dummy)
823/* 851/*
824 * proc interface 852 * proc interface
825 */ 853 */
826static void print_formats(struct snd_info_buffer *buffer) 854static void print_formats(struct snd_dummy *dummy,
855 struct snd_info_buffer *buffer)
827{ 856{
828 int i; 857 int i;
829 858
830 for (i = 0; i < SNDRV_PCM_FORMAT_LAST; i++) { 859 for (i = 0; i < SNDRV_PCM_FORMAT_LAST; i++) {
831 if (dummy_pcm_hardware.formats & (1ULL << i)) 860 if (dummy->pcm_hw.formats & (1ULL << i))
832 snd_iprintf(buffer, " %s", snd_pcm_format_name(i)); 861 snd_iprintf(buffer, " %s", snd_pcm_format_name(i));
833 } 862 }
834} 863}
835 864
836static void print_rates(struct snd_info_buffer *buffer) 865static void print_rates(struct snd_dummy *dummy,
866 struct snd_info_buffer *buffer)
837{ 867{
838 static int rates[] = { 868 static int rates[] = {
839 5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000, 869 5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000,
@@ -841,19 +871,19 @@ static void print_rates(struct snd_info_buffer *buffer)
841 }; 871 };
842 int i; 872 int i;
843 873
844 if (dummy_pcm_hardware.rates & SNDRV_PCM_RATE_CONTINUOUS) 874 if (dummy->pcm_hw.rates & SNDRV_PCM_RATE_CONTINUOUS)
845 snd_iprintf(buffer, " continuous"); 875 snd_iprintf(buffer, " continuous");
846 if (dummy_pcm_hardware.rates & SNDRV_PCM_RATE_KNOT) 876 if (dummy->pcm_hw.rates & SNDRV_PCM_RATE_KNOT)
847 snd_iprintf(buffer, " knot"); 877 snd_iprintf(buffer, " knot");
848 for (i = 0; i < ARRAY_SIZE(rates); i++) 878 for (i = 0; i < ARRAY_SIZE(rates); i++)
849 if (dummy_pcm_hardware.rates & (1 << i)) 879 if (dummy->pcm_hw.rates & (1 << i))
850 snd_iprintf(buffer, " %d", rates[i]); 880 snd_iprintf(buffer, " %d", rates[i]);
851} 881}
852 882
853#define get_dummy_int_ptr(ofs) \ 883#define get_dummy_int_ptr(dummy, ofs) \
854 (unsigned int *)((char *)&dummy_pcm_hardware + (ofs)) 884 (unsigned int *)((char *)&((dummy)->pcm_hw) + (ofs))
855#define get_dummy_ll_ptr(ofs) \ 885#define get_dummy_ll_ptr(dummy, ofs) \
856 (unsigned long long *)((char *)&dummy_pcm_hardware + (ofs)) 886 (unsigned long long *)((char *)&((dummy)->pcm_hw) + (ofs))
857 887
858struct dummy_hw_field { 888struct dummy_hw_field {
859 const char *name; 889 const char *name;
@@ -884,20 +914,21 @@ static struct dummy_hw_field fields[] = {
884static void dummy_proc_read(struct snd_info_entry *entry, 914static void dummy_proc_read(struct snd_info_entry *entry,
885 struct snd_info_buffer *buffer) 915 struct snd_info_buffer *buffer)
886{ 916{
917 struct snd_dummy *dummy = entry->private_data;
887 int i; 918 int i;
888 919
889 for (i = 0; i < ARRAY_SIZE(fields); i++) { 920 for (i = 0; i < ARRAY_SIZE(fields); i++) {
890 snd_iprintf(buffer, "%s ", fields[i].name); 921 snd_iprintf(buffer, "%s ", fields[i].name);
891 if (fields[i].size == sizeof(int)) 922 if (fields[i].size == sizeof(int))
892 snd_iprintf(buffer, fields[i].format, 923 snd_iprintf(buffer, fields[i].format,
893 *get_dummy_int_ptr(fields[i].offset)); 924 *get_dummy_int_ptr(dummy, fields[i].offset));
894 else 925 else
895 snd_iprintf(buffer, fields[i].format, 926 snd_iprintf(buffer, fields[i].format,
896 *get_dummy_ll_ptr(fields[i].offset)); 927 *get_dummy_ll_ptr(dummy, fields[i].offset));
897 if (!strcmp(fields[i].name, "formats")) 928 if (!strcmp(fields[i].name, "formats"))
898 print_formats(buffer); 929 print_formats(dummy, buffer);
899 else if (!strcmp(fields[i].name, "rates")) 930 else if (!strcmp(fields[i].name, "rates"))
900 print_rates(buffer); 931 print_rates(dummy, buffer);
901 snd_iprintf(buffer, "\n"); 932 snd_iprintf(buffer, "\n");
902 } 933 }
903} 934}
@@ -905,6 +936,7 @@ static void dummy_proc_read(struct snd_info_entry *entry,
905static void dummy_proc_write(struct snd_info_entry *entry, 936static void dummy_proc_write(struct snd_info_entry *entry,
906 struct snd_info_buffer *buffer) 937 struct snd_info_buffer *buffer)
907{ 938{
939 struct snd_dummy *dummy = entry->private_data;
908 char line[64]; 940 char line[64];
909 941
910 while (!snd_info_get_line(buffer, line, sizeof(line))) { 942 while (!snd_info_get_line(buffer, line, sizeof(line))) {
@@ -924,9 +956,9 @@ static void dummy_proc_write(struct snd_info_entry *entry,
924 if (strict_strtoull(item, 0, &val)) 956 if (strict_strtoull(item, 0, &val))
925 continue; 957 continue;
926 if (fields[i].size == sizeof(int)) 958 if (fields[i].size == sizeof(int))
927 *get_dummy_int_ptr(fields[i].offset) = val; 959 *get_dummy_int_ptr(dummy, fields[i].offset) = val;
928 else 960 else
929 *get_dummy_ll_ptr(fields[i].offset) = val; 961 *get_dummy_ll_ptr(dummy, fields[i].offset) = val;
930 } 962 }
931} 963}
932 964
@@ -938,6 +970,7 @@ static void __devinit dummy_proc_init(struct snd_dummy *chip)
938 snd_info_set_text_ops(entry, chip, dummy_proc_read); 970 snd_info_set_text_ops(entry, chip, dummy_proc_read);
939 entry->c.text.write = dummy_proc_write; 971 entry->c.text.write = dummy_proc_write;
940 entry->mode |= S_IWUSR; 972 entry->mode |= S_IWUSR;
973 entry->private_data = chip;
941 } 974 }
942} 975}
943#else 976#else
@@ -948,6 +981,7 @@ static int __devinit snd_dummy_probe(struct platform_device *devptr)
948{ 981{
949 struct snd_card *card; 982 struct snd_card *card;
950 struct snd_dummy *dummy; 983 struct snd_dummy *dummy;
984 struct dummy_model *m = NULL, **mdl;
951 int idx, err; 985 int idx, err;
952 int dev = devptr->id; 986 int dev = devptr->id;
953 987
@@ -957,6 +991,15 @@ static int __devinit snd_dummy_probe(struct platform_device *devptr)
957 return err; 991 return err;
958 dummy = card->private_data; 992 dummy = card->private_data;
959 dummy->card = card; 993 dummy->card = card;
994 for (mdl = dummy_models; *mdl && model[dev]; mdl++) {
995 if (strcmp(model[dev], (*mdl)->name) == 0) {
996 printk(KERN_INFO
997 "snd-dummy: Using model '%s' for card %i\n",
998 (*mdl)->name, card->number);
999 m = dummy->model = *mdl;
1000 break;
1001 }
1002 }
960 for (idx = 0; idx < MAX_PCM_DEVICES && idx < pcm_devs[dev]; idx++) { 1003 for (idx = 0; idx < MAX_PCM_DEVICES && idx < pcm_devs[dev]; idx++) {
961 if (pcm_substreams[dev] < 1) 1004 if (pcm_substreams[dev] < 1)
962 pcm_substreams[dev] = 1; 1005 pcm_substreams[dev] = 1;
@@ -966,6 +1009,33 @@ static int __devinit snd_dummy_probe(struct platform_device *devptr)
966 if (err < 0) 1009 if (err < 0)
967 goto __nodev; 1010 goto __nodev;
968 } 1011 }
1012
1013 dummy->pcm_hw = dummy_pcm_hardware;
1014 if (m) {
1015 if (m->formats)
1016 dummy->pcm_hw.formats = m->formats;
1017 if (m->buffer_bytes_max)
1018 dummy->pcm_hw.buffer_bytes_max = m->buffer_bytes_max;
1019 if (m->period_bytes_min)
1020 dummy->pcm_hw.period_bytes_min = m->period_bytes_min;
1021 if (m->period_bytes_max)
1022 dummy->pcm_hw.period_bytes_max = m->period_bytes_max;
1023 if (m->periods_min)
1024 dummy->pcm_hw.periods_min = m->periods_min;
1025 if (m->periods_max)
1026 dummy->pcm_hw.periods_max = m->periods_max;
1027 if (m->rates)
1028 dummy->pcm_hw.rates = m->rates;
1029 if (m->rate_min)
1030 dummy->pcm_hw.rate_min = m->rate_min;
1031 if (m->rate_max)
1032 dummy->pcm_hw.rate_max = m->rate_max;
1033 if (m->channels_min)
1034 dummy->pcm_hw.channels_min = m->channels_min;
1035 if (m->channels_max)
1036 dummy->pcm_hw.channels_max = m->channels_max;
1037 }
1038
969 err = snd_card_dummy_new_mixer(dummy); 1039 err = snd_card_dummy_new_mixer(dummy);
970 if (err < 0) 1040 if (err < 0)
971 goto __nodev; 1041 goto __nodev;
diff --git a/sound/drivers/vx/vx_pcm.c b/sound/drivers/vx/vx_pcm.c
index 6644d0034fba..35a2f71a6af5 100644
--- a/sound/drivers/vx/vx_pcm.c
+++ b/sound/drivers/vx/vx_pcm.c
@@ -46,7 +46,6 @@
46 */ 46 */
47 47
48#include <linux/slab.h> 48#include <linux/slab.h>
49#include <linux/vmalloc.h>
50#include <linux/delay.h> 49#include <linux/delay.h>
51#include <sound/core.h> 50#include <sound/core.h>
52#include <sound/asoundef.h> 51#include <sound/asoundef.h>
@@ -56,55 +55,6 @@
56 55
57 56
58/* 57/*
59 * we use a vmalloc'ed (sg-)buffer
60 */
61
62/* get the physical page pointer on the given offset */
63static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs,
64 unsigned long offset)
65{
66 void *pageptr = subs->runtime->dma_area + offset;
67 return vmalloc_to_page(pageptr);
68}
69
70/*
71 * allocate a buffer via vmalloc_32().
72 * called from hw_params
73 * NOTE: this may be called not only once per pcm open!
74 */
75static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, size_t size)
76{
77 struct snd_pcm_runtime *runtime = subs->runtime;
78 if (runtime->dma_area) {
79 /* already allocated */
80 if (runtime->dma_bytes >= size)
81 return 0; /* already enough large */
82 vfree(runtime->dma_area);
83 }
84 runtime->dma_area = vmalloc_32(size);
85 if (! runtime->dma_area)
86 return -ENOMEM;
87 memset(runtime->dma_area, 0, size);
88 runtime->dma_bytes = size;
89 return 1; /* changed */
90}
91
92/*
93 * free the buffer.
94 * called from hw_free callback
95 * NOTE: this may be called not only once per pcm open!
96 */
97static int snd_pcm_free_vmalloc_buffer(struct snd_pcm_substream *subs)
98{
99 struct snd_pcm_runtime *runtime = subs->runtime;
100
101 vfree(runtime->dma_area);
102 runtime->dma_area = NULL;
103 return 0;
104}
105
106
107/*
108 * read three pending pcm bytes via inb() 58 * read three pending pcm bytes via inb()
109 */ 59 */
110static void vx_pcm_read_per_bytes(struct vx_core *chip, struct snd_pcm_runtime *runtime, 60static void vx_pcm_read_per_bytes(struct vx_core *chip, struct snd_pcm_runtime *runtime,
@@ -865,7 +815,8 @@ static snd_pcm_uframes_t vx_pcm_playback_pointer(struct snd_pcm_substream *subs)
865static int vx_pcm_hw_params(struct snd_pcm_substream *subs, 815static int vx_pcm_hw_params(struct snd_pcm_substream *subs,
866 struct snd_pcm_hw_params *hw_params) 816 struct snd_pcm_hw_params *hw_params)
867{ 817{
868 return snd_pcm_alloc_vmalloc_buffer(subs, params_buffer_bytes(hw_params)); 818 return snd_pcm_lib_alloc_vmalloc_32_buffer
819 (subs, params_buffer_bytes(hw_params));
869} 820}
870 821
871/* 822/*
@@ -873,7 +824,7 @@ static int vx_pcm_hw_params(struct snd_pcm_substream *subs,
873 */ 824 */
874static int vx_pcm_hw_free(struct snd_pcm_substream *subs) 825static int vx_pcm_hw_free(struct snd_pcm_substream *subs)
875{ 826{
876 return snd_pcm_free_vmalloc_buffer(subs); 827 return snd_pcm_lib_free_vmalloc_buffer(subs);
877} 828}
878 829
879/* 830/*
@@ -953,7 +904,8 @@ static struct snd_pcm_ops vx_pcm_playback_ops = {
953 .prepare = vx_pcm_prepare, 904 .prepare = vx_pcm_prepare,
954 .trigger = vx_pcm_trigger, 905 .trigger = vx_pcm_trigger,
955 .pointer = vx_pcm_playback_pointer, 906 .pointer = vx_pcm_playback_pointer,
956 .page = snd_pcm_get_vmalloc_page, 907 .page = snd_pcm_lib_get_vmalloc_page,
908 .mmap = snd_pcm_lib_mmap_vmalloc,
957}; 909};
958 910
959 911
@@ -1173,7 +1125,8 @@ static struct snd_pcm_ops vx_pcm_capture_ops = {
1173 .prepare = vx_pcm_prepare, 1125 .prepare = vx_pcm_prepare,
1174 .trigger = vx_pcm_trigger, 1126 .trigger = vx_pcm_trigger,
1175 .pointer = vx_pcm_capture_pointer, 1127 .pointer = vx_pcm_capture_pointer,
1176 .page = snd_pcm_get_vmalloc_page, 1128 .page = snd_pcm_lib_get_vmalloc_page,
1129 .mmap = snd_pcm_lib_mmap_vmalloc,
1177}; 1130};
1178 1131
1179 1132
diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig
index 02fe81ca88fd..755a0a5f0e3f 100644
--- a/sound/isa/Kconfig
+++ b/sound/isa/Kconfig
@@ -63,15 +63,16 @@ config SND_AD1848
63 will be called snd-ad1848. 63 will be called snd-ad1848.
64 64
65config SND_ALS100 65config SND_ALS100
66 tristate "Avance Logic ALS100/ALS120" 66 tristate "Diamond Tech. DT-019x and Avance Logic ALSxxx"
67 depends on PNP 67 depends on PNP
68 select ISAPNP 68 select ISAPNP
69 select SND_OPL3_LIB 69 select SND_OPL3_LIB
70 select SND_MPU401_UART 70 select SND_MPU401_UART
71 select SND_SB16_DSP 71 select SND_SB16_DSP
72 help 72 help
73 Say Y here to include support for soundcards based on Avance 73 Say Y here to include support for soundcards based on the
74 Logic ALS100, ALS110, ALS120 and ALS200 chips. 74 Diamond Technologies DT-019X or Avance Logic chips: ALS007,
75 ALS100, ALS110, ALS120 and ALS200 chips.
75 76
76 To compile this driver as a module, choose M here: the module 77 To compile this driver as a module, choose M here: the module
77 will be called snd-als100. 78 will be called snd-als100.
@@ -127,20 +128,6 @@ config SND_CS4236
127 To compile this driver as a module, choose M here: the module 128 To compile this driver as a module, choose M here: the module
128 will be called snd-cs4236. 129 will be called snd-cs4236.
129 130
130config SND_DT019X
131 tristate "Diamond Technologies DT-019X, Avance Logic ALS-007"
132 depends on PNP
133 select ISAPNP
134 select SND_OPL3_LIB
135 select SND_MPU401_UART
136 select SND_SB16_DSP
137 help
138 Say Y here to include support for soundcards based on the
139 Diamond Technologies DT-019X or Avance Logic ALS-007 chips.
140
141 To compile this driver as a module, choose M here: the module
142 will be called snd-dt019x.
143
144config SND_ES968 131config SND_ES968
145 tristate "Generic ESS ES968 driver" 132 tristate "Generic ESS ES968 driver"
146 depends on PNP 133 depends on PNP
@@ -252,6 +239,22 @@ config SND_INTERWAVE_STB
252 To compile this driver as a module, choose M here: the module 239 To compile this driver as a module, choose M here: the module
253 will be called snd-interwave-stb. 240 will be called snd-interwave-stb.
254 241
242config SND_JAZZ16
243 tristate "Media Vision Jazz16 card and compatibles"
244 select SND_OPL3_LIB
245 select SND_MPU401_UART
246 select SND_SB8_DSP
247 help
248 Say Y here to include support for soundcards based on the
249 Media Vision Jazz16 chipset: digital chip MVD1216 (Jazz16),
250 codec MVA416 (CS4216) and mixer MVA514 (ICS2514).
251 Media Vision's Jazz16 cards were sold under names Pro Sonic 16,
252 Premium 3-D and Pro 3-D. There were also OEMs cards with the
253 Jazz16 chipset.
254
255 To compile this driver as a module, choose M here: the module
256 will be called snd-jazz16.
257
255config SND_OPL3SA2 258config SND_OPL3SA2
256 tristate "Yamaha OPL3-SA2/SA3" 259 tristate "Yamaha OPL3-SA2/SA3"
257 select SND_OPL3_LIB 260 select SND_OPL3_LIB
diff --git a/sound/isa/Makefile b/sound/isa/Makefile
index b906b9a1a81e..c73d30c4f462 100644
--- a/sound/isa/Makefile
+++ b/sound/isa/Makefile
@@ -7,7 +7,6 @@ snd-adlib-objs := adlib.o
7snd-als100-objs := als100.o 7snd-als100-objs := als100.o
8snd-azt2320-objs := azt2320.o 8snd-azt2320-objs := azt2320.o
9snd-cmi8330-objs := cmi8330.o 9snd-cmi8330-objs := cmi8330.o
10snd-dt019x-objs := dt019x.o
11snd-es18xx-objs := es18xx.o 10snd-es18xx-objs := es18xx.o
12snd-opl3sa2-objs := opl3sa2.o 11snd-opl3sa2-objs := opl3sa2.o
13snd-sc6000-objs := sc6000.o 12snd-sc6000-objs := sc6000.o
@@ -19,7 +18,6 @@ obj-$(CONFIG_SND_ADLIB) += snd-adlib.o
19obj-$(CONFIG_SND_ALS100) += snd-als100.o 18obj-$(CONFIG_SND_ALS100) += snd-als100.o
20obj-$(CONFIG_SND_AZT2320) += snd-azt2320.o 19obj-$(CONFIG_SND_AZT2320) += snd-azt2320.o
21obj-$(CONFIG_SND_CMI8330) += snd-cmi8330.o 20obj-$(CONFIG_SND_CMI8330) += snd-cmi8330.o
22obj-$(CONFIG_SND_DT019X) += snd-dt019x.o
23obj-$(CONFIG_SND_ES18XX) += snd-es18xx.o 21obj-$(CONFIG_SND_ES18XX) += snd-es18xx.o
24obj-$(CONFIG_SND_OPL3SA2) += snd-opl3sa2.o 22obj-$(CONFIG_SND_OPL3SA2) += snd-opl3sa2.o
25obj-$(CONFIG_SND_SC6000) += snd-sc6000.o 23obj-$(CONFIG_SND_SC6000) += snd-sc6000.o
diff --git a/sound/isa/als100.c b/sound/isa/als100.c
index 5fd52e4d7079..20becc89f6f6 100644
--- a/sound/isa/als100.c
+++ b/sound/isa/als100.c
@@ -2,9 +2,13 @@
2/* 2/*
3 card-als100.c - driver for Avance Logic ALS100 based soundcards. 3 card-als100.c - driver for Avance Logic ALS100 based soundcards.
4 Copyright (C) 1999-2000 by Massimo Piccioni <dafastidio@libero.it> 4 Copyright (C) 1999-2000 by Massimo Piccioni <dafastidio@libero.it>
5 Copyright (C) 1999-2002 by Massimo Piccioni <dafastidio@libero.it>
5 6
6 Thanks to Pierfrancesco 'qM2' Passerini. 7 Thanks to Pierfrancesco 'qM2' Passerini.
7 8
9 Generalised for soundcards based on DT-0196 and ALS-007 chips
10 by Jonathan Woithe <jwoithe@physics.adelaide.edu.au>: June 2002.
11
8 This program is free software; you can redistribute it and/or modify 12 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 13 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 14 the Free Software Foundation; either version 2 of the License, or
@@ -33,10 +37,10 @@
33 37
34#define PFX "als100: " 38#define PFX "als100: "
35 39
36MODULE_AUTHOR("Massimo Piccioni <dafastidio@libero.it>"); 40MODULE_DESCRIPTION("Avance Logic ALS007/ALS1X0");
37MODULE_DESCRIPTION("Avance Logic ALS1X0"); 41MODULE_SUPPORTED_DEVICE("{{Diamond Technologies DT-019X},"
38MODULE_LICENSE("GPL"); 42 "{Avance Logic ALS-007}}"
39MODULE_SUPPORTED_DEVICE("{{Avance Logic,ALS100 - PRO16PNP}," 43 "{{Avance Logic,ALS100 - PRO16PNP},"
40 "{Avance Logic,ALS110}," 44 "{Avance Logic,ALS110},"
41 "{Avance Logic,ALS120}," 45 "{Avance Logic,ALS120},"
42 "{Avance Logic,ALS200}," 46 "{Avance Logic,ALS200},"
@@ -45,9 +49,12 @@ MODULE_SUPPORTED_DEVICE("{{Avance Logic,ALS100 - PRO16PNP},"
45 "{Avance Logic,ALS120}," 49 "{Avance Logic,ALS120},"
46 "{RTL,RTL3000}}"); 50 "{RTL,RTL3000}}");
47 51
52MODULE_AUTHOR("Massimo Piccioni <dafastidio@libero.it>");
53MODULE_LICENSE("GPL");
54
48static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ 55static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
49static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ 56static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
50static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */ 57static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
51static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */ 58static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
52static long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */ 59static long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
53static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */ 60static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
@@ -57,14 +64,15 @@ static int dma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* PnP setup */
57static int dma16[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* PnP setup */ 64static int dma16[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* PnP setup */
58 65
59module_param_array(index, int, NULL, 0444); 66module_param_array(index, int, NULL, 0444);
60MODULE_PARM_DESC(index, "Index value for als100 based soundcard."); 67MODULE_PARM_DESC(index, "Index value for Avance Logic based soundcard.");
61module_param_array(id, charp, NULL, 0444); 68module_param_array(id, charp, NULL, 0444);
62MODULE_PARM_DESC(id, "ID string for als100 based soundcard."); 69MODULE_PARM_DESC(id, "ID string for Avance Logic based soundcard.");
63module_param_array(enable, bool, NULL, 0444); 70module_param_array(enable, bool, NULL, 0444);
64MODULE_PARM_DESC(enable, "Enable als100 based soundcard."); 71MODULE_PARM_DESC(enable, "Enable Avance Logic based soundcard.");
72
73MODULE_ALIAS("snd-dt019x");
65 74
66struct snd_card_als100 { 75struct snd_card_als100 {
67 int dev_no;
68 struct pnp_dev *dev; 76 struct pnp_dev *dev;
69 struct pnp_dev *devmpu; 77 struct pnp_dev *devmpu;
70 struct pnp_dev *devopl; 78 struct pnp_dev *devopl;
@@ -72,25 +80,43 @@ struct snd_card_als100 {
72}; 80};
73 81
74static struct pnp_card_device_id snd_als100_pnpids[] = { 82static struct pnp_card_device_id snd_als100_pnpids[] = {
83 /* DT197A30 */
84 { .id = "RWB1688",
85 .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" } },
86 .driver_data = SB_HW_DT019X },
87 /* DT0196 / ALS-007 */
88 { .id = "ALS0007",
89 .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" } },
90 .driver_data = SB_HW_DT019X },
75 /* ALS100 - PRO16PNP */ 91 /* ALS100 - PRO16PNP */
76 { .id = "ALS0001", .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" } } }, 92 { .id = "ALS0001",
93 .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" } },
94 .driver_data = SB_HW_ALS100 },
77 /* ALS110 - MF1000 - Digimate 3D Sound */ 95 /* ALS110 - MF1000 - Digimate 3D Sound */
78 { .id = "ALS0110", .devs = { { "@@@1001" }, { "@X@1001" }, { "@H@1001" } } }, 96 { .id = "ALS0110",
97 .devs = { { "@@@1001" }, { "@X@1001" }, { "@H@1001" } },
98 .driver_data = SB_HW_ALS100 },
79 /* ALS120 */ 99 /* ALS120 */
80 { .id = "ALS0120", .devs = { { "@@@2001" }, { "@X@2001" }, { "@H@2001" } } }, 100 { .id = "ALS0120",
101 .devs = { { "@@@2001" }, { "@X@2001" }, { "@H@2001" } },
102 .driver_data = SB_HW_ALS100 },
81 /* ALS200 */ 103 /* ALS200 */
82 { .id = "ALS0200", .devs = { { "@@@0020" }, { "@X@0020" }, { "@H@0001" } } }, 104 { .id = "ALS0200",
105 .devs = { { "@@@0020" }, { "@X@0020" }, { "@H@0001" } },
106 .driver_data = SB_HW_ALS100 },
83 /* ALS200 OEM */ 107 /* ALS200 OEM */
84 { .id = "ALS0200", .devs = { { "@@@0020" }, { "@X@0020" }, { "@H@0020" } } }, 108 { .id = "ALS0200",
109 .devs = { { "@@@0020" }, { "@X@0020" }, { "@H@0020" } },
110 .driver_data = SB_HW_ALS100 },
85 /* RTL3000 */ 111 /* RTL3000 */
86 { .id = "RTL3000", .devs = { { "@@@2001" }, { "@X@2001" }, { "@H@2001" } } }, 112 { .id = "RTL3000",
87 { .id = "", } /* end */ 113 .devs = { { "@@@2001" }, { "@X@2001" }, { "@H@2001" } },
114 .driver_data = SB_HW_ALS100 },
115 { .id = "" } /* end */
88}; 116};
89 117
90MODULE_DEVICE_TABLE(pnp_card, snd_als100_pnpids); 118MODULE_DEVICE_TABLE(pnp_card, snd_als100_pnpids);
91 119
92#define DRIVER_NAME "snd-card-als100"
93
94static int __devinit snd_card_als100_pnp(int dev, struct snd_card_als100 *acard, 120static int __devinit snd_card_als100_pnp(int dev, struct snd_card_als100 *acard,
95 struct pnp_card_link *card, 121 struct pnp_card_link *card,
96 const struct pnp_card_device_id *id) 122 const struct pnp_card_device_id *id)
@@ -113,8 +139,12 @@ static int __devinit snd_card_als100_pnp(int dev, struct snd_card_als100 *acard,
113 return err; 139 return err;
114 } 140 }
115 port[dev] = pnp_port_start(pdev, 0); 141 port[dev] = pnp_port_start(pdev, 0);
116 dma8[dev] = pnp_dma(pdev, 1); 142 if (id->driver_data == SB_HW_DT019X)
117 dma16[dev] = pnp_dma(pdev, 0); 143 dma8[dev] = pnp_dma(pdev, 0);
144 else {
145 dma8[dev] = pnp_dma(pdev, 1);
146 dma16[dev] = pnp_dma(pdev, 0);
147 }
118 irq[dev] = pnp_irq(pdev, 0); 148 irq[dev] = pnp_irq(pdev, 0);
119 149
120 pdev = acard->devmpu; 150 pdev = acard->devmpu;
@@ -175,22 +205,33 @@ static int __devinit snd_card_als100_probe(int dev,
175 } 205 }
176 snd_card_set_dev(card, &pcard->card->dev); 206 snd_card_set_dev(card, &pcard->card->dev);
177 207
178 if ((error = snd_sbdsp_create(card, port[dev], 208 if (pid->driver_data == SB_HW_DT019X)
179 irq[dev], 209 dma16[dev] = -1;
180 snd_sb16dsp_interrupt, 210
181 dma8[dev], 211 error = snd_sbdsp_create(card, port[dev], irq[dev],
182 dma16[dev], 212 snd_sb16dsp_interrupt,
183 SB_HW_ALS100, &chip)) < 0) { 213 dma8[dev], dma16[dev],
214 pid->driver_data,
215 &chip);
216 if (error < 0) {
184 snd_card_free(card); 217 snd_card_free(card);
185 return error; 218 return error;
186 } 219 }
187 acard->chip = chip; 220 acard->chip = chip;
188 221
189 strcpy(card->driver, "ALS100"); 222 if (pid->driver_data == SB_HW_DT019X) {
190 strcpy(card->shortname, "Avance Logic ALS100"); 223 strcpy(card->driver, "DT-019X");
191 sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d&%d", 224 strcpy(card->shortname, "Diamond Tech. DT-019X");
192 card->shortname, chip->name, chip->port, 225 sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d",
193 irq[dev], dma8[dev], dma16[dev]); 226 card->shortname, chip->name, chip->port,
227 irq[dev], dma8[dev]);
228 } else {
229 strcpy(card->driver, "ALS100");
230 strcpy(card->shortname, "Avance Logic ALS100");
231 sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d&%d",
232 card->shortname, chip->name, chip->port,
233 irq[dev], dma8[dev], dma16[dev]);
234 }
194 235
195 if ((error = snd_sb16dsp_pcm(chip, 0, NULL)) < 0) { 236 if ((error = snd_sb16dsp_pcm(chip, 0, NULL)) < 0) {
196 snd_card_free(card); 237 snd_card_free(card);
@@ -203,9 +244,19 @@ static int __devinit snd_card_als100_probe(int dev,
203 } 244 }
204 245
205 if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) { 246 if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) {
206 if (snd_mpu401_uart_new(card, 0, MPU401_HW_ALS100, 247 int mpu_type = MPU401_HW_ALS100;
248
249 if (mpu_irq[dev] == SNDRV_AUTO_IRQ)
250 mpu_irq[dev] = -1;
251
252 if (pid->driver_data == SB_HW_DT019X)
253 mpu_type = MPU401_HW_MPU401;
254
255 if (snd_mpu401_uart_new(card, 0,
256 mpu_type,
207 mpu_port[dev], 0, 257 mpu_port[dev], 0,
208 mpu_irq[dev], IRQF_DISABLED, 258 mpu_irq[dev],
259 mpu_irq[dev] >= 0 ? IRQF_DISABLED : 0,
209 NULL) < 0) 260 NULL) < 0)
210 snd_printk(KERN_ERR PFX "no MPU-401 device at 0x%lx\n", mpu_port[dev]); 261 snd_printk(KERN_ERR PFX "no MPU-401 device at 0x%lx\n", mpu_port[dev]);
211 } 262 }
@@ -291,7 +342,7 @@ static int snd_als100_pnp_resume(struct pnp_card_link *pcard)
291 342
292static struct pnp_card_driver als100_pnpc_driver = { 343static struct pnp_card_driver als100_pnpc_driver = {
293 .flags = PNP_DRIVER_RES_DISABLE, 344 .flags = PNP_DRIVER_RES_DISABLE,
294 .name = "als100", 345 .name = "als100",
295 .id_table = snd_als100_pnpids, 346 .id_table = snd_als100_pnpids,
296 .probe = snd_als100_pnp_detect, 347 .probe = snd_als100_pnp_detect,
297 .remove = __devexit_p(snd_als100_pnp_remove), 348 .remove = __devexit_p(snd_als100_pnp_remove),
@@ -312,7 +363,7 @@ static int __init alsa_card_als100_init(void)
312 if (!als100_devices) { 363 if (!als100_devices) {
313 pnp_unregister_card_driver(&als100_pnpc_driver); 364 pnp_unregister_card_driver(&als100_pnpc_driver);
314#ifdef MODULE 365#ifdef MODULE
315 snd_printk(KERN_ERR "no ALS100 based soundcards found\n"); 366 snd_printk(KERN_ERR "no Avance Logic based soundcards found\n");
316#endif 367#endif
317 return -ENODEV; 368 return -ENODEV;
318 } 369 }
diff --git a/sound/isa/dt019x.c b/sound/isa/dt019x.c
deleted file mode 100644
index 80f5b1af9be8..000000000000
--- a/sound/isa/dt019x.c
+++ /dev/null
@@ -1,321 +0,0 @@
1
2/*
3 dt019x.c - driver for Diamond Technologies DT-0197H based soundcards.
4 Copyright (C) 1999, 2002 by Massimo Piccioni <dafastidio@libero.it>
5
6 Generalised for soundcards based on DT-0196 and ALS-007 chips
7 by Jonathan Woithe <jwoithe@physics.adelaide.edu.au>: June 2002.
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 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22*/
23
24#include <linux/init.h>
25#include <linux/wait.h>
26#include <linux/pnp.h>
27#include <linux/moduleparam.h>
28#include <sound/core.h>
29#include <sound/initval.h>
30#include <sound/mpu401.h>
31#include <sound/opl3.h>
32#include <sound/sb.h>
33
34#define PFX "dt019x: "
35
36MODULE_AUTHOR("Massimo Piccioni <dafastidio@libero.it>");
37MODULE_DESCRIPTION("Diamond Technologies DT-019X / Avance Logic ALS-007");
38MODULE_LICENSE("GPL");
39MODULE_SUPPORTED_DEVICE("{{Diamond Technologies DT-019X},"
40 "{Avance Logic ALS-007}}");
41
42static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
43static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
44static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
45static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
46static long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
47static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
48static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* PnP setup */
49static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* PnP setup */
50static int dma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* PnP setup */
51
52module_param_array(index, int, NULL, 0444);
53MODULE_PARM_DESC(index, "Index value for DT-019X based soundcard.");
54module_param_array(id, charp, NULL, 0444);
55MODULE_PARM_DESC(id, "ID string for DT-019X based soundcard.");
56module_param_array(enable, bool, NULL, 0444);
57MODULE_PARM_DESC(enable, "Enable DT-019X based soundcard.");
58
59struct snd_card_dt019x {
60 struct pnp_dev *dev;
61 struct pnp_dev *devmpu;
62 struct pnp_dev *devopl;
63 struct snd_sb *chip;
64};
65
66static struct pnp_card_device_id snd_dt019x_pnpids[] = {
67 /* DT197A30 */
68 { .id = "RWB1688", .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" }, } },
69 /* DT0196 / ALS-007 */
70 { .id = "ALS0007", .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" }, } },
71 { .id = "", }
72};
73
74MODULE_DEVICE_TABLE(pnp_card, snd_dt019x_pnpids);
75
76
77#define DRIVER_NAME "snd-card-dt019x"
78
79
80static int __devinit snd_card_dt019x_pnp(int dev, struct snd_card_dt019x *acard,
81 struct pnp_card_link *card,
82 const struct pnp_card_device_id *pid)
83{
84 struct pnp_dev *pdev;
85 int err;
86
87 acard->dev = pnp_request_card_device(card, pid->devs[0].id, NULL);
88 if (acard->dev == NULL)
89 return -ENODEV;
90
91 acard->devmpu = pnp_request_card_device(card, pid->devs[1].id, NULL);
92 acard->devopl = pnp_request_card_device(card, pid->devs[2].id, NULL);
93
94 pdev = acard->dev;
95
96 err = pnp_activate_dev(pdev);
97 if (err < 0) {
98 snd_printk(KERN_ERR PFX "DT-019X AUDIO pnp configure failure\n");
99 return err;
100 }
101
102 port[dev] = pnp_port_start(pdev, 0);
103 dma8[dev] = pnp_dma(pdev, 0);
104 irq[dev] = pnp_irq(pdev, 0);
105 snd_printdd("dt019x: found audio interface: port=0x%lx, irq=0x%x, dma=0x%x\n",
106 port[dev],irq[dev],dma8[dev]);
107
108 pdev = acard->devmpu;
109 if (pdev != NULL) {
110 err = pnp_activate_dev(pdev);
111 if (err < 0) {
112 pnp_release_card_device(pdev);
113 snd_printk(KERN_ERR PFX "DT-019X MPU401 pnp configure failure, skipping\n");
114 goto __mpu_error;
115 }
116 mpu_port[dev] = pnp_port_start(pdev, 0);
117 mpu_irq[dev] = pnp_irq(pdev, 0);
118 snd_printdd("dt019x: found MPU-401: port=0x%lx, irq=0x%x\n",
119 mpu_port[dev],mpu_irq[dev]);
120 } else {
121 __mpu_error:
122 acard->devmpu = NULL;
123 mpu_port[dev] = -1;
124 }
125
126 pdev = acard->devopl;
127 if (pdev != NULL) {
128 err = pnp_activate_dev(pdev);
129 if (err < 0) {
130 pnp_release_card_device(pdev);
131 snd_printk(KERN_ERR PFX "DT-019X OPL3 pnp configure failure, skipping\n");
132 goto __fm_error;
133 }
134 fm_port[dev] = pnp_port_start(pdev, 0);
135 snd_printdd("dt019x: found OPL3 synth: port=0x%lx\n",fm_port[dev]);
136 } else {
137 __fm_error:
138 acard->devopl = NULL;
139 fm_port[dev] = -1;
140 }
141
142 return 0;
143}
144
145static int __devinit snd_card_dt019x_probe(int dev, struct pnp_card_link *pcard, const struct pnp_card_device_id *pid)
146{
147 int error;
148 struct snd_sb *chip;
149 struct snd_card *card;
150 struct snd_card_dt019x *acard;
151 struct snd_opl3 *opl3;
152
153 error = snd_card_create(index[dev], id[dev], THIS_MODULE,
154 sizeof(struct snd_card_dt019x), &card);
155 if (error < 0)
156 return error;
157 acard = card->private_data;
158
159 snd_card_set_dev(card, &pcard->card->dev);
160 if ((error = snd_card_dt019x_pnp(dev, acard, pcard, pid))) {
161 snd_card_free(card);
162 return error;
163 }
164
165 if ((error = snd_sbdsp_create(card, port[dev],
166 irq[dev],
167 snd_sb16dsp_interrupt,
168 dma8[dev],
169 -1,
170 SB_HW_DT019X,
171 &chip)) < 0) {
172 snd_card_free(card);
173 return error;
174 }
175 acard->chip = chip;
176
177 strcpy(card->driver, "DT-019X");
178 strcpy(card->shortname, "Diamond Tech. DT-019X");
179 sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d",
180 card->shortname, chip->name, chip->port,
181 irq[dev], dma8[dev]);
182
183 if ((error = snd_sb16dsp_pcm(chip, 0, NULL)) < 0) {
184 snd_card_free(card);
185 return error;
186 }
187 if ((error = snd_sbmixer_new(chip)) < 0) {
188 snd_card_free(card);
189 return error;
190 }
191
192 if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) {
193 if (mpu_irq[dev] == SNDRV_AUTO_IRQ)
194 mpu_irq[dev] = -1;
195 if (snd_mpu401_uart_new(card, 0,
196/* MPU401_HW_SB,*/
197 MPU401_HW_MPU401,
198 mpu_port[dev], 0,
199 mpu_irq[dev],
200 mpu_irq[dev] >= 0 ? IRQF_DISABLED : 0,
201 NULL) < 0)
202 snd_printk(KERN_ERR PFX "no MPU-401 device at 0x%lx ?\n", mpu_port[dev]);
203 }
204
205 if (fm_port[dev] > 0 && fm_port[dev] != SNDRV_AUTO_PORT) {
206 if (snd_opl3_create(card,
207 fm_port[dev],
208 fm_port[dev] + 2,
209 OPL3_HW_AUTO, 0, &opl3) < 0) {
210 snd_printk(KERN_ERR PFX "no OPL device at 0x%lx-0x%lx ?\n",
211 fm_port[dev], fm_port[dev] + 2);
212 } else {
213 if ((error = snd_opl3_timer_new(opl3, 0, 1)) < 0) {
214 snd_card_free(card);
215 return error;
216 }
217 if ((error = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
218 snd_card_free(card);
219 return error;
220 }
221 }
222 }
223
224 if ((error = snd_card_register(card)) < 0) {
225 snd_card_free(card);
226 return error;
227 }
228 pnp_set_card_drvdata(pcard, card);
229 return 0;
230}
231
232static unsigned int __devinitdata dt019x_devices;
233
234static int __devinit snd_dt019x_pnp_probe(struct pnp_card_link *card,
235 const struct pnp_card_device_id *pid)
236{
237 static int dev;
238 int res;
239
240 for ( ; dev < SNDRV_CARDS; dev++) {
241 if (!enable[dev])
242 continue;
243 res = snd_card_dt019x_probe(dev, card, pid);
244 if (res < 0)
245 return res;
246 dev++;
247 dt019x_devices++;
248 return 0;
249 }
250 return -ENODEV;
251}
252
253static void __devexit snd_dt019x_pnp_remove(struct pnp_card_link * pcard)
254{
255 snd_card_free(pnp_get_card_drvdata(pcard));
256 pnp_set_card_drvdata(pcard, NULL);
257}
258
259#ifdef CONFIG_PM
260static int snd_dt019x_pnp_suspend(struct pnp_card_link *pcard, pm_message_t state)
261{
262 struct snd_card *card = pnp_get_card_drvdata(pcard);
263 struct snd_card_dt019x *acard = card->private_data;
264 struct snd_sb *chip = acard->chip;
265
266 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
267 snd_pcm_suspend_all(chip->pcm);
268 snd_sbmixer_suspend(chip);
269 return 0;
270}
271
272static int snd_dt019x_pnp_resume(struct pnp_card_link *pcard)
273{
274 struct snd_card *card = pnp_get_card_drvdata(pcard);
275 struct snd_card_dt019x *acard = card->private_data;
276 struct snd_sb *chip = acard->chip;
277
278 snd_sbdsp_reset(chip);
279 snd_sbmixer_resume(chip);
280 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
281 return 0;
282}
283#endif
284
285static struct pnp_card_driver dt019x_pnpc_driver = {
286 .flags = PNP_DRIVER_RES_DISABLE,
287 .name = "dt019x",
288 .id_table = snd_dt019x_pnpids,
289 .probe = snd_dt019x_pnp_probe,
290 .remove = __devexit_p(snd_dt019x_pnp_remove),
291#ifdef CONFIG_PM
292 .suspend = snd_dt019x_pnp_suspend,
293 .resume = snd_dt019x_pnp_resume,
294#endif
295};
296
297static int __init alsa_card_dt019x_init(void)
298{
299 int err;
300
301 err = pnp_register_card_driver(&dt019x_pnpc_driver);
302 if (err)
303 return err;
304
305 if (!dt019x_devices) {
306 pnp_unregister_card_driver(&dt019x_pnpc_driver);
307#ifdef MODULE
308 snd_printk(KERN_ERR "no DT-019X / ALS-007 based soundcards found\n");
309#endif
310 return -ENODEV;
311 }
312 return 0;
313}
314
315static void __exit alsa_card_dt019x_exit(void)
316{
317 pnp_unregister_card_driver(&dt019x_pnpc_driver);
318}
319
320module_init(alsa_card_dt019x_init)
321module_exit(alsa_card_dt019x_exit)
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c
index c8a8da0d4036..a4af53b5c1cf 100644
--- a/sound/isa/opti9xx/opti92x-ad1848.c
+++ b/sound/isa/opti9xx/opti92x-ad1848.c
@@ -33,6 +33,7 @@
33#include <asm/io.h> 33#include <asm/io.h>
34#include <asm/dma.h> 34#include <asm/dma.h>
35#include <sound/core.h> 35#include <sound/core.h>
36#include <sound/tlv.h>
36#include <sound/wss.h> 37#include <sound/wss.h>
37#include <sound/mpu401.h> 38#include <sound/mpu401.h>
38#include <sound/opl3.h> 39#include <sound/opl3.h>
@@ -546,6 +547,93 @@ __skip_mpu:
546 547
547#ifdef OPTi93X 548#ifdef OPTi93X
548 549
550static const DECLARE_TLV_DB_SCALE(db_scale_5bit_3db_step, -9300, 300, 0);
551static const DECLARE_TLV_DB_SCALE(db_scale_5bit, -4650, 150, 0);
552static const DECLARE_TLV_DB_SCALE(db_scale_4bit_12db_max, -3300, 300, 0);
553
554static struct snd_kcontrol_new snd_opti93x_controls[] = {
555WSS_DOUBLE("Master Playback Switch", 0,
556 OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 7, 7, 1, 1),
557WSS_DOUBLE_TLV("Master Playback Volume", 0,
558 OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 1, 1, 31, 1,
559 db_scale_5bit_3db_step),
560WSS_DOUBLE_TLV("PCM Playback Volume", 0,
561 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 31, 1,
562 db_scale_5bit),
563WSS_DOUBLE_TLV("FM Playback Volume", 0,
564 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 1, 1, 15, 1,
565 db_scale_4bit_12db_max),
566WSS_DOUBLE("Line Playback Switch", 0,
567 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1),
568WSS_DOUBLE_TLV("Line Playback Volume", 0,
569 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 15, 1,
570 db_scale_4bit_12db_max),
571WSS_DOUBLE("Mic Playback Switch", 0,
572 OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 7, 7, 1, 1),
573WSS_DOUBLE_TLV("Mic Playback Volume", 0,
574 OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 1, 1, 15, 1,
575 db_scale_4bit_12db_max),
576WSS_DOUBLE_TLV("CD Playback Volume", 0,
577 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 1, 1, 15, 1,
578 db_scale_4bit_12db_max),
579WSS_DOUBLE("Aux Playback Switch", 0,
580 OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 7, 7, 1, 1),
581WSS_DOUBLE_TLV("Aux Playback Volume", 0,
582 OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 1, 1, 15, 1,
583 db_scale_4bit_12db_max),
584};
585
586static int __devinit snd_opti93x_mixer(struct snd_wss *chip)
587{
588 struct snd_card *card;
589 unsigned int idx;
590 struct snd_ctl_elem_id id1, id2;
591 int err;
592
593 if (snd_BUG_ON(!chip || !chip->pcm))
594 return -EINVAL;
595
596 card = chip->card;
597
598 strcpy(card->mixername, chip->pcm->name);
599
600 memset(&id1, 0, sizeof(id1));
601 memset(&id2, 0, sizeof(id2));
602 id1.iface = id2.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
603 /* reassign AUX0 switch to CD */
604 strcpy(id1.name, "Aux Playback Switch");
605 strcpy(id2.name, "CD Playback Switch");
606 err = snd_ctl_rename_id(card, &id1, &id2);
607 if (err < 0) {
608 snd_printk(KERN_ERR "Cannot rename opti93x control\n");
609 return err;
610 }
611 /* reassign AUX1 switch to FM */
612 strcpy(id1.name, "Aux Playback Switch"); id1.index = 1;
613 strcpy(id2.name, "FM Playback Switch");
614 err = snd_ctl_rename_id(card, &id1, &id2);
615 if (err < 0) {
616 snd_printk(KERN_ERR "Cannot rename opti93x control\n");
617 return err;
618 }
619 /* remove AUX1 volume */
620 strcpy(id1.name, "Aux Playback Volume"); id1.index = 1;
621 snd_ctl_remove_id(card, &id1);
622
623 /* Replace WSS volume controls with OPTi93x volume controls */
624 id1.index = 0;
625 for (idx = 0; idx < ARRAY_SIZE(snd_opti93x_controls); idx++) {
626 strcpy(id1.name, snd_opti93x_controls[idx].name);
627 snd_ctl_remove_id(card, &id1);
628
629 err = snd_ctl_add(card,
630 snd_ctl_new1(&snd_opti93x_controls[idx], chip));
631 if (err < 0)
632 return err;
633 }
634 return 0;
635}
636
549static irqreturn_t snd_opti93x_interrupt(int irq, void *dev_id) 637static irqreturn_t snd_opti93x_interrupt(int irq, void *dev_id)
550{ 638{
551 struct snd_opti9xx *chip = dev_id; 639 struct snd_opti9xx *chip = dev_id;
@@ -754,6 +842,11 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card)
754 error = snd_wss_mixer(codec); 842 error = snd_wss_mixer(codec);
755 if (error < 0) 843 if (error < 0)
756 return error; 844 return error;
845#ifdef OPTi93X
846 error = snd_opti93x_mixer(codec);
847 if (error < 0)
848 return error;
849#endif
757#ifdef CS4231 850#ifdef CS4231
758 error = snd_wss_timer(codec, 0, &timer); 851 error = snd_wss_timer(codec, 0, &timer);
759 if (error < 0) 852 if (error < 0)
diff --git a/sound/isa/sb/Makefile b/sound/isa/sb/Makefile
index faeffceb01b7..af3669681788 100644
--- a/sound/isa/sb/Makefile
+++ b/sound/isa/sb/Makefile
@@ -12,6 +12,7 @@ snd-sb16-objs := sb16.o
12snd-sbawe-objs := sbawe.o emu8000.o 12snd-sbawe-objs := sbawe.o emu8000.o
13snd-emu8000-synth-objs := emu8000_synth.o emu8000_callback.o emu8000_patch.o emu8000_pcm.o 13snd-emu8000-synth-objs := emu8000_synth.o emu8000_callback.o emu8000_patch.o emu8000_pcm.o
14snd-es968-objs := es968.o 14snd-es968-objs := es968.o
15snd-jazz16-objs := jazz16.o
15 16
16# Toplevel Module Dependency 17# Toplevel Module Dependency
17obj-$(CONFIG_SND_SB_COMMON) += snd-sb-common.o 18obj-$(CONFIG_SND_SB_COMMON) += snd-sb-common.o
@@ -21,6 +22,7 @@ obj-$(CONFIG_SND_SB8) += snd-sb8.o
21obj-$(CONFIG_SND_SB16) += snd-sb16.o 22obj-$(CONFIG_SND_SB16) += snd-sb16.o
22obj-$(CONFIG_SND_SBAWE) += snd-sbawe.o 23obj-$(CONFIG_SND_SBAWE) += snd-sbawe.o
23obj-$(CONFIG_SND_ES968) += snd-es968.o 24obj-$(CONFIG_SND_ES968) += snd-es968.o
25obj-$(CONFIG_SND_JAZZ16) += snd-jazz16.o
24ifeq ($(CONFIG_SND_SB16_CSP),y) 26ifeq ($(CONFIG_SND_SB16_CSP),y)
25 obj-$(CONFIG_SND_SB16) += snd-sb16-csp.o 27 obj-$(CONFIG_SND_SB16) += snd-sb16-csp.o
26 obj-$(CONFIG_SND_SBAWE) += snd-sb16-csp.o 28 obj-$(CONFIG_SND_SBAWE) += snd-sb16-csp.o
diff --git a/sound/isa/sb/jazz16.c b/sound/isa/sb/jazz16.c
new file mode 100644
index 000000000000..8d21a3feda3a
--- /dev/null
+++ b/sound/isa/sb/jazz16.c
@@ -0,0 +1,404 @@
1
2/*
3 * jazz16.c - driver for Media Vision Jazz16 based soundcards.
4 * Copyright (C) 2009 Krzysztof Helt <krzysztof.h1@wp.pl>
5 * Based on patches posted by Rask Ingemann Lambertsen and Rene Herman.
6 * Based on OSS Sound Blaster driver.
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file COPYING in the main directory of this archive for
10 * more details.
11 *
12 */
13
14#include <linux/init.h>
15#include <linux/module.h>
16#include <linux/io.h>
17#include <asm/dma.h>
18#include <linux/isa.h>
19#include <sound/core.h>
20#include <sound/mpu401.h>
21#include <sound/opl3.h>
22#include <sound/sb.h>
23#define SNDRV_LEGACY_FIND_FREE_IRQ
24#define SNDRV_LEGACY_FIND_FREE_DMA
25#include <sound/initval.h>
26
27#define PFX "jazz16: "
28
29MODULE_DESCRIPTION("Media Vision Jazz16");
30MODULE_SUPPORTED_DEVICE("{{Media Vision ??? },"
31 "{RTL,RTL3000}}");
32
33MODULE_AUTHOR("Krzysztof Helt <krzysztof.h1@wp.pl>");
34MODULE_LICENSE("GPL");
35
36static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
37static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
38static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
39static unsigned long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
40static unsigned long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
41static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
42static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
43static int dma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;
44static int dma16[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;
45
46module_param_array(index, int, NULL, 0444);
47MODULE_PARM_DESC(index, "Index value for Media Vision Jazz16 based soundcard.");
48module_param_array(id, charp, NULL, 0444);
49MODULE_PARM_DESC(id, "ID string for Media Vision Jazz16 based soundcard.");
50module_param_array(enable, bool, NULL, 0444);
51MODULE_PARM_DESC(enable, "Enable Media Vision Jazz16 based soundcard.");
52module_param_array(port, long, NULL, 0444);
53MODULE_PARM_DESC(port, "Port # for jazz16 driver.");
54module_param_array(mpu_port, long, NULL, 0444);
55MODULE_PARM_DESC(mpu_port, "MPU-401 port # for jazz16 driver.");
56module_param_array(irq, int, NULL, 0444);
57MODULE_PARM_DESC(irq, "IRQ # for jazz16 driver.");
58module_param_array(mpu_irq, int, NULL, 0444);
59MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for jazz16 driver.");
60module_param_array(dma8, int, NULL, 0444);
61MODULE_PARM_DESC(dma8, "DMA8 # for jazz16 driver.");
62module_param_array(dma16, int, NULL, 0444);
63MODULE_PARM_DESC(dma16, "DMA16 # for jazz16 driver.");
64
65#define SB_JAZZ16_WAKEUP 0xaf
66#define SB_JAZZ16_SET_PORTS 0x50
67#define SB_DSP_GET_JAZZ_BRD_REV 0xfa
68#define SB_JAZZ16_SET_DMAINTR 0xfb
69#define SB_DSP_GET_JAZZ_MODEL 0xfe
70
71struct snd_card_jazz16 {
72 struct snd_sb *chip;
73};
74
75static irqreturn_t jazz16_interrupt(int irq, void *chip)
76{
77 return snd_sb8dsp_interrupt(chip);
78}
79
80static int __devinit jazz16_configure_ports(unsigned long port,
81 unsigned long mpu_port, int idx)
82{
83 unsigned char val;
84
85 if (!request_region(0x201, 1, "jazz16 config")) {
86 snd_printk(KERN_ERR "config port region is already in use.\n");
87 return -EBUSY;
88 }
89 outb(SB_JAZZ16_WAKEUP - idx, 0x201);
90 udelay(100);
91 outb(SB_JAZZ16_SET_PORTS + idx, 0x201);
92 udelay(100);
93 val = port & 0x70;
94 val |= (mpu_port & 0x30) >> 4;
95 outb(val, 0x201);
96
97 release_region(0x201, 1);
98 return 0;
99}
100
101static int __devinit jazz16_detect_board(unsigned long port,
102 unsigned long mpu_port)
103{
104 int err;
105 int val;
106 struct snd_sb chip;
107
108 if (!request_region(port, 0x10, "jazz16")) {
109 snd_printk(KERN_ERR "I/O port region is already in use.\n");
110 return -EBUSY;
111 }
112 /* just to call snd_sbdsp_command/reset/get_byte() */
113 chip.port = port;
114
115 err = snd_sbdsp_reset(&chip);
116 if (err < 0)
117 for (val = 0; val < 4; val++) {
118 err = jazz16_configure_ports(port, mpu_port, val);
119 if (err < 0)
120 break;
121
122 err = snd_sbdsp_reset(&chip);
123 if (!err)
124 break;
125 }
126 if (err < 0) {
127 err = -ENODEV;
128 goto err_unmap;
129 }
130 if (!snd_sbdsp_command(&chip, SB_DSP_GET_JAZZ_BRD_REV)) {
131 err = -EBUSY;
132 goto err_unmap;
133 }
134 val = snd_sbdsp_get_byte(&chip);
135 if (val >= 0x30)
136 snd_sbdsp_get_byte(&chip);
137
138 if ((val & 0xf0) != 0x10) {
139 err = -ENODEV;
140 goto err_unmap;
141 }
142 if (!snd_sbdsp_command(&chip, SB_DSP_GET_JAZZ_MODEL)) {
143 err = -EBUSY;
144 goto err_unmap;
145 }
146 snd_sbdsp_get_byte(&chip);
147 err = snd_sbdsp_get_byte(&chip);
148 snd_printd("Media Vision Jazz16 board detected: rev 0x%x, model 0x%x\n",
149 val, err);
150
151 err = 0;
152
153err_unmap:
154 release_region(port, 0x10);
155 return err;
156}
157
158static int __devinit jazz16_configure_board(struct snd_sb *chip, int mpu_irq)
159{
160 static unsigned char jazz_irq_bits[] = { 0, 0, 2, 3, 0, 1, 0, 4,
161 0, 2, 5, 0, 0, 0, 0, 6 };
162 static unsigned char jazz_dma_bits[] = { 0, 1, 0, 2, 0, 3, 0, 4 };
163
164 if (jazz_dma_bits[chip->dma8] == 0 ||
165 jazz_dma_bits[chip->dma16] == 0 ||
166 jazz_irq_bits[chip->irq] == 0)
167 return -EINVAL;
168
169 if (!snd_sbdsp_command(chip, SB_JAZZ16_SET_DMAINTR))
170 return -EBUSY;
171
172 if (!snd_sbdsp_command(chip,
173 jazz_dma_bits[chip->dma8] |
174 (jazz_dma_bits[chip->dma16] << 4)))
175 return -EBUSY;
176
177 if (!snd_sbdsp_command(chip,
178 jazz_irq_bits[chip->irq] |
179 (jazz_irq_bits[mpu_irq] << 4)))
180 return -EBUSY;
181
182 return 0;
183}
184
185static int __devinit snd_jazz16_match(struct device *devptr, unsigned int dev)
186{
187 if (!enable[dev])
188 return 0;
189 if (port[dev] == SNDRV_AUTO_PORT) {
190 snd_printk(KERN_ERR "please specify port\n");
191 return 0;
192 } else if (port[dev] == 0x200 || (port[dev] & ~0x270)) {
193 snd_printk(KERN_ERR "incorrect port specified\n");
194 return 0;
195 }
196 if (dma8[dev] != SNDRV_AUTO_DMA &&
197 dma8[dev] != 1 && dma8[dev] != 3) {
198 snd_printk(KERN_ERR "dma8 must be 1 or 3\n");
199 return 0;
200 }
201 if (dma16[dev] != SNDRV_AUTO_DMA &&
202 dma16[dev] != 5 && dma16[dev] != 7) {
203 snd_printk(KERN_ERR "dma16 must be 5 or 7\n");
204 return 0;
205 }
206 if (mpu_port[dev] != SNDRV_AUTO_PORT &&
207 (mpu_port[dev] & ~0x030) != 0x300) {
208 snd_printk(KERN_ERR "incorrect mpu_port specified\n");
209 return 0;
210 }
211 if (mpu_irq[dev] != SNDRV_AUTO_DMA &&
212 mpu_irq[dev] != 2 && mpu_irq[dev] != 3 &&
213 mpu_irq[dev] != 5 && mpu_irq[dev] != 7) {
214 snd_printk(KERN_ERR "mpu_irq must be 2, 3, 5 or 7\n");
215 return 0;
216 }
217 return 1;
218}
219
220static int __devinit snd_jazz16_probe(struct device *devptr, unsigned int dev)
221{
222 struct snd_card *card;
223 struct snd_card_jazz16 *jazz16;
224 struct snd_sb *chip;
225 struct snd_opl3 *opl3;
226 static int possible_irqs[] = {2, 3, 5, 7, 9, 10, 15, -1};
227 static int possible_dmas8[] = {1, 3, -1};
228 static int possible_dmas16[] = {5, 7, -1};
229 int err, xirq, xdma8, xdma16, xmpu_port, xmpu_irq;
230
231 err = snd_card_create(index[dev], id[dev], THIS_MODULE,
232 sizeof(struct snd_card_jazz16), &card);
233 if (err < 0)
234 return err;
235
236 jazz16 = card->private_data;
237
238 xirq = irq[dev];
239 if (xirq == SNDRV_AUTO_IRQ) {
240 xirq = snd_legacy_find_free_irq(possible_irqs);
241 if (xirq < 0) {
242 snd_printk(KERN_ERR "unable to find a free IRQ\n");
243 err = -EBUSY;
244 goto err_free;
245 }
246 }
247 xdma8 = dma8[dev];
248 if (xdma8 == SNDRV_AUTO_DMA) {
249 xdma8 = snd_legacy_find_free_dma(possible_dmas8);
250 if (xdma8 < 0) {
251 snd_printk(KERN_ERR "unable to find a free DMA8\n");
252 err = -EBUSY;
253 goto err_free;
254 }
255 }
256 xdma16 = dma16[dev];
257 if (xdma16 == SNDRV_AUTO_DMA) {
258 xdma16 = snd_legacy_find_free_dma(possible_dmas16);
259 if (xdma16 < 0) {
260 snd_printk(KERN_ERR "unable to find a free DMA16\n");
261 err = -EBUSY;
262 goto err_free;
263 }
264 }
265
266 xmpu_port = mpu_port[dev];
267 if (xmpu_port == SNDRV_AUTO_PORT)
268 xmpu_port = 0;
269 err = jazz16_detect_board(port[dev], xmpu_port);
270 if (err < 0) {
271 printk(KERN_ERR "Media Vision Jazz16 board not detected\n");
272 goto err_free;
273 }
274 err = snd_sbdsp_create(card, port[dev], irq[dev],
275 jazz16_interrupt,
276 dma8[dev], dma16[dev],
277 SB_HW_JAZZ16,
278 &chip);
279 if (err < 0)
280 goto err_free;
281
282 xmpu_irq = mpu_irq[dev];
283 if (xmpu_irq == SNDRV_AUTO_IRQ || mpu_port[dev] == SNDRV_AUTO_PORT)
284 xmpu_irq = 0;
285 err = jazz16_configure_board(chip, xmpu_irq);
286 if (err < 0) {
287 printk(KERN_ERR "Media Vision Jazz16 configuration failed\n");
288 goto err_free;
289 }
290
291 jazz16->chip = chip;
292
293 strcpy(card->driver, "jazz16");
294 strcpy(card->shortname, "Media Vision Jazz16");
295 sprintf(card->longname,
296 "Media Vision Jazz16 at 0x%lx, irq %d, dma8 %d, dma16 %d",
297 port[dev], xirq, xdma8, xdma16);
298
299 err = snd_sb8dsp_pcm(chip, 0, NULL);
300 if (err < 0)
301 goto err_free;
302 err = snd_sbmixer_new(chip);
303 if (err < 0)
304 goto err_free;
305
306 err = snd_opl3_create(card, chip->port, chip->port + 2,
307 OPL3_HW_AUTO, 1, &opl3);
308 if (err < 0)
309 snd_printk(KERN_WARNING "no OPL device at 0x%lx-0x%lx\n",
310 chip->port, chip->port + 2);
311 else {
312 err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
313 if (err < 0)
314 goto err_free;
315 }
316 if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) {
317 if (mpu_irq[dev] == SNDRV_AUTO_IRQ)
318 mpu_irq[dev] = -1;
319
320 if (snd_mpu401_uart_new(card, 0,
321 MPU401_HW_MPU401,
322 mpu_port[dev], 0,
323 mpu_irq[dev],
324 mpu_irq[dev] >= 0 ? IRQF_DISABLED : 0,
325 NULL) < 0)
326 snd_printk(KERN_ERR "no MPU-401 device at 0x%lx\n",
327 mpu_port[dev]);
328 }
329
330 snd_card_set_dev(card, devptr);
331
332 err = snd_card_register(card);
333 if (err < 0)
334 goto err_free;
335
336 dev_set_drvdata(devptr, card);
337 return 0;
338
339err_free:
340 snd_card_free(card);
341 return err;
342}
343
344static int __devexit snd_jazz16_remove(struct device *devptr, unsigned int dev)
345{
346 struct snd_card *card = dev_get_drvdata(devptr);
347
348 dev_set_drvdata(devptr, NULL);
349 snd_card_free(card);
350 return 0;
351}
352
353#ifdef CONFIG_PM
354static int snd_jazz16_suspend(struct device *pdev, unsigned int n,
355 pm_message_t state)
356{
357 struct snd_card *card = dev_get_drvdata(pdev);
358 struct snd_card_jazz16 *acard = card->private_data;
359 struct snd_sb *chip = acard->chip;
360
361 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
362 snd_pcm_suspend_all(chip->pcm);
363 snd_sbmixer_suspend(chip);
364 return 0;
365}
366
367static int snd_jazz16_resume(struct device *pdev, unsigned int n)
368{
369 struct snd_card *card = dev_get_drvdata(pdev);
370 struct snd_card_jazz16 *acard = card->private_data;
371 struct snd_sb *chip = acard->chip;
372
373 snd_sbdsp_reset(chip);
374 snd_sbmixer_resume(chip);
375 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
376 return 0;
377}
378#endif
379
380static struct isa_driver snd_jazz16_driver = {
381 .match = snd_jazz16_match,
382 .probe = snd_jazz16_probe,
383 .remove = __devexit_p(snd_jazz16_remove),
384#ifdef CONFIG_PM
385 .suspend = snd_jazz16_suspend,
386 .resume = snd_jazz16_resume,
387#endif
388 .driver = {
389 .name = "jazz16"
390 },
391};
392
393static int __init alsa_card_jazz16_init(void)
394{
395 return isa_register_driver(&snd_jazz16_driver, SNDRV_CARDS);
396}
397
398static void __exit alsa_card_jazz16_exit(void)
399{
400 isa_unregister_driver(&snd_jazz16_driver);
401}
402
403module_init(alsa_card_jazz16_init)
404module_exit(alsa_card_jazz16_exit)
diff --git a/sound/isa/sb/sb8_main.c b/sound/isa/sb/sb8_main.c
index 658d55769c9c..7d84c9f34dc9 100644
--- a/sound/isa/sb/sb8_main.c
+++ b/sound/isa/sb/sb8_main.c
@@ -106,9 +106,21 @@ static int snd_sb8_playback_prepare(struct snd_pcm_substream *substream)
106 struct snd_sb *chip = snd_pcm_substream_chip(substream); 106 struct snd_sb *chip = snd_pcm_substream_chip(substream);
107 struct snd_pcm_runtime *runtime = substream->runtime; 107 struct snd_pcm_runtime *runtime = substream->runtime;
108 unsigned int mixreg, rate, size, count; 108 unsigned int mixreg, rate, size, count;
109 unsigned char format;
110 unsigned char stereo = runtime->channels > 1;
111 int dma;
109 112
110 rate = runtime->rate; 113 rate = runtime->rate;
111 switch (chip->hardware) { 114 switch (chip->hardware) {
115 case SB_HW_JAZZ16:
116 if (runtime->format == SNDRV_PCM_FORMAT_S16_LE) {
117 if (chip->mode & SB_MODE_CAPTURE_16)
118 return -EBUSY;
119 else
120 chip->mode |= SB_MODE_PLAYBACK_16;
121 }
122 chip->playback_format = SB_DSP_LO_OUTPUT_AUTO;
123 break;
112 case SB_HW_PRO: 124 case SB_HW_PRO:
113 if (runtime->channels > 1) { 125 if (runtime->channels > 1) {
114 if (snd_BUG_ON(rate != SB8_RATE(11025) && 126 if (snd_BUG_ON(rate != SB8_RATE(11025) &&
@@ -133,11 +145,21 @@ static int snd_sb8_playback_prepare(struct snd_pcm_substream *substream)
133 default: 145 default:
134 return -EINVAL; 146 return -EINVAL;
135 } 147 }
148 if (chip->mode & SB_MODE_PLAYBACK_16) {
149 format = stereo ? SB_DSP_STEREO_16BIT : SB_DSP_MONO_16BIT;
150 dma = chip->dma16;
151 } else {
152 format = stereo ? SB_DSP_STEREO_8BIT : SB_DSP_MONO_8BIT;
153 chip->mode |= SB_MODE_PLAYBACK_8;
154 dma = chip->dma8;
155 }
136 size = chip->p_dma_size = snd_pcm_lib_buffer_bytes(substream); 156 size = chip->p_dma_size = snd_pcm_lib_buffer_bytes(substream);
137 count = chip->p_period_size = snd_pcm_lib_period_bytes(substream); 157 count = chip->p_period_size = snd_pcm_lib_period_bytes(substream);
138 spin_lock_irqsave(&chip->reg_lock, flags); 158 spin_lock_irqsave(&chip->reg_lock, flags);
139 snd_sbdsp_command(chip, SB_DSP_SPEAKER_ON); 159 snd_sbdsp_command(chip, SB_DSP_SPEAKER_ON);
140 if (runtime->channels > 1) { 160 if (chip->hardware == SB_HW_JAZZ16)
161 snd_sbdsp_command(chip, format);
162 else if (stereo) {
141 /* set playback stereo mode */ 163 /* set playback stereo mode */
142 spin_lock(&chip->mixer_lock); 164 spin_lock(&chip->mixer_lock);
143 mixreg = snd_sbmixer_read(chip, SB_DSP_STEREO_SW); 165 mixreg = snd_sbmixer_read(chip, SB_DSP_STEREO_SW);
@@ -147,15 +169,14 @@ static int snd_sb8_playback_prepare(struct snd_pcm_substream *substream)
147 /* Soundblaster hardware programming reference guide, 3-23 */ 169 /* Soundblaster hardware programming reference guide, 3-23 */
148 snd_sbdsp_command(chip, SB_DSP_DMA8_EXIT); 170 snd_sbdsp_command(chip, SB_DSP_DMA8_EXIT);
149 runtime->dma_area[0] = 0x80; 171 runtime->dma_area[0] = 0x80;
150 snd_dma_program(chip->dma8, runtime->dma_addr, 1, DMA_MODE_WRITE); 172 snd_dma_program(dma, runtime->dma_addr, 1, DMA_MODE_WRITE);
151 /* force interrupt */ 173 /* force interrupt */
152 chip->mode = SB_MODE_HALT;
153 snd_sbdsp_command(chip, SB_DSP_OUTPUT); 174 snd_sbdsp_command(chip, SB_DSP_OUTPUT);
154 snd_sbdsp_command(chip, 0); 175 snd_sbdsp_command(chip, 0);
155 snd_sbdsp_command(chip, 0); 176 snd_sbdsp_command(chip, 0);
156 } 177 }
157 snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE); 178 snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE);
158 if (runtime->channels > 1) { 179 if (stereo) {
159 snd_sbdsp_command(chip, 256 - runtime->rate_den / 2); 180 snd_sbdsp_command(chip, 256 - runtime->rate_den / 2);
160 spin_lock(&chip->mixer_lock); 181 spin_lock(&chip->mixer_lock);
161 /* save output filter status and turn it off */ 182 /* save output filter status and turn it off */
@@ -168,13 +189,15 @@ static int snd_sb8_playback_prepare(struct snd_pcm_substream *substream)
168 snd_sbdsp_command(chip, 256 - runtime->rate_den); 189 snd_sbdsp_command(chip, 256 - runtime->rate_den);
169 } 190 }
170 if (chip->playback_format != SB_DSP_OUTPUT) { 191 if (chip->playback_format != SB_DSP_OUTPUT) {
192 if (chip->mode & SB_MODE_PLAYBACK_16)
193 count /= 2;
171 count--; 194 count--;
172 snd_sbdsp_command(chip, SB_DSP_BLOCK_SIZE); 195 snd_sbdsp_command(chip, SB_DSP_BLOCK_SIZE);
173 snd_sbdsp_command(chip, count & 0xff); 196 snd_sbdsp_command(chip, count & 0xff);
174 snd_sbdsp_command(chip, count >> 8); 197 snd_sbdsp_command(chip, count >> 8);
175 } 198 }
176 spin_unlock_irqrestore(&chip->reg_lock, flags); 199 spin_unlock_irqrestore(&chip->reg_lock, flags);
177 snd_dma_program(chip->dma8, runtime->dma_addr, 200 snd_dma_program(dma, runtime->dma_addr,
178 size, DMA_MODE_WRITE | DMA_AUTOINIT); 201 size, DMA_MODE_WRITE | DMA_AUTOINIT);
179 return 0; 202 return 0;
180} 203}
@@ -212,7 +235,6 @@ static int snd_sb8_playback_trigger(struct snd_pcm_substream *substream,
212 snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF); 235 snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF);
213 } 236 }
214 spin_unlock_irqrestore(&chip->reg_lock, flags); 237 spin_unlock_irqrestore(&chip->reg_lock, flags);
215 chip->mode = (cmd == SNDRV_PCM_TRIGGER_START) ? SB_MODE_PLAYBACK_8 : SB_MODE_HALT;
216 return 0; 238 return 0;
217} 239}
218 240
@@ -234,9 +256,21 @@ static int snd_sb8_capture_prepare(struct snd_pcm_substream *substream)
234 struct snd_sb *chip = snd_pcm_substream_chip(substream); 256 struct snd_sb *chip = snd_pcm_substream_chip(substream);
235 struct snd_pcm_runtime *runtime = substream->runtime; 257 struct snd_pcm_runtime *runtime = substream->runtime;
236 unsigned int mixreg, rate, size, count; 258 unsigned int mixreg, rate, size, count;
259 unsigned char format;
260 unsigned char stereo = runtime->channels > 1;
261 int dma;
237 262
238 rate = runtime->rate; 263 rate = runtime->rate;
239 switch (chip->hardware) { 264 switch (chip->hardware) {
265 case SB_HW_JAZZ16:
266 if (runtime->format == SNDRV_PCM_FORMAT_S16_LE) {
267 if (chip->mode & SB_MODE_PLAYBACK_16)
268 return -EBUSY;
269 else
270 chip->mode |= SB_MODE_CAPTURE_16;
271 }
272 chip->capture_format = SB_DSP_LO_INPUT_AUTO;
273 break;
240 case SB_HW_PRO: 274 case SB_HW_PRO:
241 if (runtime->channels > 1) { 275 if (runtime->channels > 1) {
242 if (snd_BUG_ON(rate != SB8_RATE(11025) && 276 if (snd_BUG_ON(rate != SB8_RATE(11025) &&
@@ -262,14 +296,24 @@ static int snd_sb8_capture_prepare(struct snd_pcm_substream *substream)
262 default: 296 default:
263 return -EINVAL; 297 return -EINVAL;
264 } 298 }
299 if (chip->mode & SB_MODE_CAPTURE_16) {
300 format = stereo ? SB_DSP_STEREO_16BIT : SB_DSP_MONO_16BIT;
301 dma = chip->dma16;
302 } else {
303 format = stereo ? SB_DSP_STEREO_8BIT : SB_DSP_MONO_8BIT;
304 chip->mode |= SB_MODE_CAPTURE_8;
305 dma = chip->dma8;
306 }
265 size = chip->c_dma_size = snd_pcm_lib_buffer_bytes(substream); 307 size = chip->c_dma_size = snd_pcm_lib_buffer_bytes(substream);
266 count = chip->c_period_size = snd_pcm_lib_period_bytes(substream); 308 count = chip->c_period_size = snd_pcm_lib_period_bytes(substream);
267 spin_lock_irqsave(&chip->reg_lock, flags); 309 spin_lock_irqsave(&chip->reg_lock, flags);
268 snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF); 310 snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF);
269 if (runtime->channels > 1) 311 if (chip->hardware == SB_HW_JAZZ16)
312 snd_sbdsp_command(chip, format);
313 else if (stereo)
270 snd_sbdsp_command(chip, SB_DSP_STEREO_8BIT); 314 snd_sbdsp_command(chip, SB_DSP_STEREO_8BIT);
271 snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE); 315 snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE);
272 if (runtime->channels > 1) { 316 if (stereo) {
273 snd_sbdsp_command(chip, 256 - runtime->rate_den / 2); 317 snd_sbdsp_command(chip, 256 - runtime->rate_den / 2);
274 spin_lock(&chip->mixer_lock); 318 spin_lock(&chip->mixer_lock);
275 /* save input filter status and turn it off */ 319 /* save input filter status and turn it off */
@@ -282,13 +326,15 @@ static int snd_sb8_capture_prepare(struct snd_pcm_substream *substream)
282 snd_sbdsp_command(chip, 256 - runtime->rate_den); 326 snd_sbdsp_command(chip, 256 - runtime->rate_den);
283 } 327 }
284 if (chip->capture_format != SB_DSP_INPUT) { 328 if (chip->capture_format != SB_DSP_INPUT) {
329 if (chip->mode & SB_MODE_PLAYBACK_16)
330 count /= 2;
285 count--; 331 count--;
286 snd_sbdsp_command(chip, SB_DSP_BLOCK_SIZE); 332 snd_sbdsp_command(chip, SB_DSP_BLOCK_SIZE);
287 snd_sbdsp_command(chip, count & 0xff); 333 snd_sbdsp_command(chip, count & 0xff);
288 snd_sbdsp_command(chip, count >> 8); 334 snd_sbdsp_command(chip, count >> 8);
289 } 335 }
290 spin_unlock_irqrestore(&chip->reg_lock, flags); 336 spin_unlock_irqrestore(&chip->reg_lock, flags);
291 snd_dma_program(chip->dma8, runtime->dma_addr, 337 snd_dma_program(dma, runtime->dma_addr,
292 size, DMA_MODE_READ | DMA_AUTOINIT); 338 size, DMA_MODE_READ | DMA_AUTOINIT);
293 return 0; 339 return 0;
294} 340}
@@ -328,7 +374,6 @@ static int snd_sb8_capture_trigger(struct snd_pcm_substream *substream,
328 snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF); 374 snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF);
329 } 375 }
330 spin_unlock_irqrestore(&chip->reg_lock, flags); 376 spin_unlock_irqrestore(&chip->reg_lock, flags);
331 chip->mode = (cmd == SNDRV_PCM_TRIGGER_START) ? SB_MODE_CAPTURE_8 : SB_MODE_HALT;
332 return 0; 377 return 0;
333} 378}
334 379
@@ -339,13 +384,21 @@ irqreturn_t snd_sb8dsp_interrupt(struct snd_sb *chip)
339 384
340 snd_sb_ack_8bit(chip); 385 snd_sb_ack_8bit(chip);
341 switch (chip->mode) { 386 switch (chip->mode) {
342 case SB_MODE_PLAYBACK_8: /* ok.. playback is active */ 387 case SB_MODE_PLAYBACK_16: /* ok.. playback is active */
388 if (chip->hardware != SB_HW_JAZZ16)
389 break;
390 /* fallthru */
391 case SB_MODE_PLAYBACK_8:
343 substream = chip->playback_substream; 392 substream = chip->playback_substream;
344 runtime = substream->runtime; 393 runtime = substream->runtime;
345 if (chip->playback_format == SB_DSP_OUTPUT) 394 if (chip->playback_format == SB_DSP_OUTPUT)
346 snd_sb8_playback_trigger(substream, SNDRV_PCM_TRIGGER_START); 395 snd_sb8_playback_trigger(substream, SNDRV_PCM_TRIGGER_START);
347 snd_pcm_period_elapsed(substream); 396 snd_pcm_period_elapsed(substream);
348 break; 397 break;
398 case SB_MODE_CAPTURE_16:
399 if (chip->hardware != SB_HW_JAZZ16)
400 break;
401 /* fallthru */
349 case SB_MODE_CAPTURE_8: 402 case SB_MODE_CAPTURE_8:
350 substream = chip->capture_substream; 403 substream = chip->capture_substream;
351 runtime = substream->runtime; 404 runtime = substream->runtime;
@@ -361,10 +414,15 @@ static snd_pcm_uframes_t snd_sb8_playback_pointer(struct snd_pcm_substream *subs
361{ 414{
362 struct snd_sb *chip = snd_pcm_substream_chip(substream); 415 struct snd_sb *chip = snd_pcm_substream_chip(substream);
363 size_t ptr; 416 size_t ptr;
417 int dma;
364 418
365 if (chip->mode != SB_MODE_PLAYBACK_8) 419 if (chip->mode & SB_MODE_PLAYBACK_8)
420 dma = chip->dma8;
421 else if (chip->mode & SB_MODE_PLAYBACK_16)
422 dma = chip->dma16;
423 else
366 return 0; 424 return 0;
367 ptr = snd_dma_pointer(chip->dma8, chip->p_dma_size); 425 ptr = snd_dma_pointer(dma, chip->p_dma_size);
368 return bytes_to_frames(substream->runtime, ptr); 426 return bytes_to_frames(substream->runtime, ptr);
369} 427}
370 428
@@ -372,10 +430,15 @@ static snd_pcm_uframes_t snd_sb8_capture_pointer(struct snd_pcm_substream *subst
372{ 430{
373 struct snd_sb *chip = snd_pcm_substream_chip(substream); 431 struct snd_sb *chip = snd_pcm_substream_chip(substream);
374 size_t ptr; 432 size_t ptr;
433 int dma;
375 434
376 if (chip->mode != SB_MODE_CAPTURE_8) 435 if (chip->mode & SB_MODE_CAPTURE_8)
436 dma = chip->dma8;
437 else if (chip->mode & SB_MODE_CAPTURE_16)
438 dma = chip->dma16;
439 else
377 return 0; 440 return 0;
378 ptr = snd_dma_pointer(chip->dma8, chip->c_dma_size); 441 ptr = snd_dma_pointer(dma, chip->c_dma_size);
379 return bytes_to_frames(substream->runtime, ptr); 442 return bytes_to_frames(substream->runtime, ptr);
380} 443}
381 444
@@ -446,6 +509,14 @@ static int snd_sb8_open(struct snd_pcm_substream *substream)
446 runtime->hw = snd_sb8_capture; 509 runtime->hw = snd_sb8_capture;
447 } 510 }
448 switch (chip->hardware) { 511 switch (chip->hardware) {
512 case SB_HW_JAZZ16:
513 if (chip->dma16 == 5 || chip->dma16 == 7)
514 runtime->hw.formats |= SNDRV_PCM_FMTBIT_S16_LE;
515 runtime->hw.rates |= SNDRV_PCM_RATE_8000_48000;
516 runtime->hw.rate_min = 4000;
517 runtime->hw.rate_max = 50000;
518 runtime->hw.channels_max = 2;
519 break;
449 case SB_HW_PRO: 520 case SB_HW_PRO:
450 runtime->hw.rate_max = 44100; 521 runtime->hw.rate_max = 44100;
451 runtime->hw.channels_max = 2; 522 runtime->hw.channels_max = 2;
@@ -468,6 +539,14 @@ static int snd_sb8_open(struct snd_pcm_substream *substream)
468 } 539 }
469 snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 540 snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
470 &hw_constraints_clock); 541 &hw_constraints_clock);
542 if (chip->dma8 > 3 || chip->dma16 >= 0) {
543 snd_pcm_hw_constraint_step(runtime, 0,
544 SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 2);
545 snd_pcm_hw_constraint_step(runtime, 0,
546 SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 2);
547 runtime->hw.buffer_bytes_max = 128 * 1024 * 1024;
548 runtime->hw.period_bytes_max = 128 * 1024 * 1024;
549 }
471 return 0; 550 return 0;
472} 551}
473 552
@@ -480,6 +559,10 @@ static int snd_sb8_close(struct snd_pcm_substream *substream)
480 chip->capture_substream = NULL; 559 chip->capture_substream = NULL;
481 spin_lock_irqsave(&chip->open_lock, flags); 560 spin_lock_irqsave(&chip->open_lock, flags);
482 chip->open &= ~SB_OPEN_PCM; 561 chip->open &= ~SB_OPEN_PCM;
562 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
563 chip->mode &= ~SB_MODE_PLAYBACK;
564 else
565 chip->mode &= ~SB_MODE_CAPTURE;
483 spin_unlock_irqrestore(&chip->open_lock, flags); 566 spin_unlock_irqrestore(&chip->open_lock, flags);
484 return 0; 567 return 0;
485} 568}
@@ -515,6 +598,7 @@ int snd_sb8dsp_pcm(struct snd_sb *chip, int device, struct snd_pcm ** rpcm)
515 struct snd_card *card = chip->card; 598 struct snd_card *card = chip->card;
516 struct snd_pcm *pcm; 599 struct snd_pcm *pcm;
517 int err; 600 int err;
601 size_t max_prealloc = 64 * 1024;
518 602
519 if (rpcm) 603 if (rpcm)
520 *rpcm = NULL; 604 *rpcm = NULL;
@@ -527,9 +611,11 @@ int snd_sb8dsp_pcm(struct snd_sb *chip, int device, struct snd_pcm ** rpcm)
527 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_sb8_playback_ops); 611 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_sb8_playback_ops);
528 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_sb8_capture_ops); 612 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_sb8_capture_ops);
529 613
614 if (chip->dma8 > 3 || chip->dma16 >= 0)
615 max_prealloc = 128 * 1024;
530 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, 616 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
531 snd_dma_isa_data(), 617 snd_dma_isa_data(),
532 64*1024, 64*1024); 618 64*1024, max_prealloc);
533 619
534 if (rpcm) 620 if (rpcm)
535 *rpcm = pcm; 621 *rpcm = pcm;
diff --git a/sound/isa/sb/sb_common.c b/sound/isa/sb/sb_common.c
index 27a651502251..eae6c1c0eff9 100644
--- a/sound/isa/sb/sb_common.c
+++ b/sound/isa/sb/sb_common.c
@@ -170,6 +170,9 @@ static int snd_sbdsp_probe(struct snd_sb * chip)
170 case SB_HW_CS5530: 170 case SB_HW_CS5530:
171 str = "16 (CS5530)"; 171 str = "16 (CS5530)";
172 break; 172 break;
173 case SB_HW_JAZZ16:
174 str = "Pro (Jazz16)";
175 break;
173 default: 176 default:
174 return -ENODEV; 177 return -ENODEV;
175 } 178 }
diff --git a/sound/isa/sb/sb_mixer.c b/sound/isa/sb/sb_mixer.c
index 318ff0c823e7..6496822c1808 100644
--- a/sound/isa/sb/sb_mixer.c
+++ b/sound/isa/sb/sb_mixer.c
@@ -528,20 +528,11 @@ int snd_sbmixer_add_ctl(struct snd_sb *chip, const char *name, int index, int ty
528 * SB 2.0 specific mixer elements 528 * SB 2.0 specific mixer elements
529 */ 529 */
530 530
531static struct sbmix_elem snd_sb20_ctl_master_play_vol = 531static struct sbmix_elem snd_sb20_controls[] = {
532 SB_SINGLE("Master Playback Volume", SB_DSP20_MASTER_DEV, 1, 7); 532 SB_SINGLE("Master Playback Volume", SB_DSP20_MASTER_DEV, 1, 7),
533static struct sbmix_elem snd_sb20_ctl_pcm_play_vol = 533 SB_SINGLE("PCM Playback Volume", SB_DSP20_PCM_DEV, 1, 3),
534 SB_SINGLE("PCM Playback Volume", SB_DSP20_PCM_DEV, 1, 3); 534 SB_SINGLE("Synth Playback Volume", SB_DSP20_FM_DEV, 1, 7),
535static struct sbmix_elem snd_sb20_ctl_synth_play_vol = 535 SB_SINGLE("CD Playback Volume", SB_DSP20_CD_DEV, 1, 7)
536 SB_SINGLE("Synth Playback Volume", SB_DSP20_FM_DEV, 1, 7);
537static struct sbmix_elem snd_sb20_ctl_cd_play_vol =
538 SB_SINGLE("CD Playback Volume", SB_DSP20_CD_DEV, 1, 7);
539
540static struct sbmix_elem *snd_sb20_controls[] = {
541 &snd_sb20_ctl_master_play_vol,
542 &snd_sb20_ctl_pcm_play_vol,
543 &snd_sb20_ctl_synth_play_vol,
544 &snd_sb20_ctl_cd_play_vol
545}; 536};
546 537
547static unsigned char snd_sb20_init_values[][2] = { 538static unsigned char snd_sb20_init_values[][2] = {
@@ -552,41 +543,24 @@ static unsigned char snd_sb20_init_values[][2] = {
552/* 543/*
553 * SB Pro specific mixer elements 544 * SB Pro specific mixer elements
554 */ 545 */
555static struct sbmix_elem snd_sbpro_ctl_master_play_vol = 546static struct sbmix_elem snd_sbpro_controls[] = {
556 SB_DOUBLE("Master Playback Volume", SB_DSP_MASTER_DEV, SB_DSP_MASTER_DEV, 5, 1, 7); 547 SB_DOUBLE("Master Playback Volume",
557static struct sbmix_elem snd_sbpro_ctl_pcm_play_vol = 548 SB_DSP_MASTER_DEV, SB_DSP_MASTER_DEV, 5, 1, 7),
558 SB_DOUBLE("PCM Playback Volume", SB_DSP_PCM_DEV, SB_DSP_PCM_DEV, 5, 1, 7); 549 SB_DOUBLE("PCM Playback Volume",
559static struct sbmix_elem snd_sbpro_ctl_pcm_play_filter = 550 SB_DSP_PCM_DEV, SB_DSP_PCM_DEV, 5, 1, 7),
560 SB_SINGLE("PCM Playback Filter", SB_DSP_PLAYBACK_FILT, 5, 1); 551 SB_SINGLE("PCM Playback Filter", SB_DSP_PLAYBACK_FILT, 5, 1),
561static struct sbmix_elem snd_sbpro_ctl_synth_play_vol = 552 SB_DOUBLE("Synth Playback Volume",
562 SB_DOUBLE("Synth Playback Volume", SB_DSP_FM_DEV, SB_DSP_FM_DEV, 5, 1, 7); 553 SB_DSP_FM_DEV, SB_DSP_FM_DEV, 5, 1, 7),
563static struct sbmix_elem snd_sbpro_ctl_cd_play_vol = 554 SB_DOUBLE("CD Playback Volume", SB_DSP_CD_DEV, SB_DSP_CD_DEV, 5, 1, 7),
564 SB_DOUBLE("CD Playback Volume", SB_DSP_CD_DEV, SB_DSP_CD_DEV, 5, 1, 7); 555 SB_DOUBLE("Line Playback Volume",
565static struct sbmix_elem snd_sbpro_ctl_line_play_vol = 556 SB_DSP_LINE_DEV, SB_DSP_LINE_DEV, 5, 1, 7),
566 SB_DOUBLE("Line Playback Volume", SB_DSP_LINE_DEV, SB_DSP_LINE_DEV, 5, 1, 7); 557 SB_SINGLE("Mic Playback Volume", SB_DSP_MIC_DEV, 1, 3),
567static struct sbmix_elem snd_sbpro_ctl_mic_play_vol =
568 SB_SINGLE("Mic Playback Volume", SB_DSP_MIC_DEV, 1, 3);
569static struct sbmix_elem snd_sbpro_ctl_capture_source =
570 { 558 {
571 .name = "Capture Source", 559 .name = "Capture Source",
572 .type = SB_MIX_CAPTURE_PRO 560 .type = SB_MIX_CAPTURE_PRO
573 }; 561 },
574static struct sbmix_elem snd_sbpro_ctl_capture_filter = 562 SB_SINGLE("Capture Filter", SB_DSP_CAPTURE_FILT, 5, 1),
575 SB_SINGLE("Capture Filter", SB_DSP_CAPTURE_FILT, 5, 1); 563 SB_SINGLE("Capture Low-Pass Filter", SB_DSP_CAPTURE_FILT, 3, 1)
576static struct sbmix_elem snd_sbpro_ctl_capture_low_filter =
577 SB_SINGLE("Capture Low-Pass Filter", SB_DSP_CAPTURE_FILT, 3, 1);
578
579static struct sbmix_elem *snd_sbpro_controls[] = {
580 &snd_sbpro_ctl_master_play_vol,
581 &snd_sbpro_ctl_pcm_play_vol,
582 &snd_sbpro_ctl_pcm_play_filter,
583 &snd_sbpro_ctl_synth_play_vol,
584 &snd_sbpro_ctl_cd_play_vol,
585 &snd_sbpro_ctl_line_play_vol,
586 &snd_sbpro_ctl_mic_play_vol,
587 &snd_sbpro_ctl_capture_source,
588 &snd_sbpro_ctl_capture_filter,
589 &snd_sbpro_ctl_capture_low_filter
590}; 564};
591 565
592static unsigned char snd_sbpro_init_values[][2] = { 566static unsigned char snd_sbpro_init_values[][2] = {
@@ -598,68 +572,42 @@ static unsigned char snd_sbpro_init_values[][2] = {
598/* 572/*
599 * SB16 specific mixer elements 573 * SB16 specific mixer elements
600 */ 574 */
601static struct sbmix_elem snd_sb16_ctl_master_play_vol = 575static struct sbmix_elem snd_sb16_controls[] = {
602 SB_DOUBLE("Master Playback Volume", SB_DSP4_MASTER_DEV, (SB_DSP4_MASTER_DEV + 1), 3, 3, 31); 576 SB_DOUBLE("Master Playback Volume",
603static struct sbmix_elem snd_sb16_ctl_3d_enhance_switch = 577 SB_DSP4_MASTER_DEV, (SB_DSP4_MASTER_DEV + 1), 3, 3, 31),
604 SB_SINGLE("3D Enhancement Switch", SB_DSP4_3DSE, 0, 1); 578 SB_DOUBLE("PCM Playback Volume",
605static struct sbmix_elem snd_sb16_ctl_tone_bass = 579 SB_DSP4_PCM_DEV, (SB_DSP4_PCM_DEV + 1), 3, 3, 31),
606 SB_DOUBLE("Tone Control - Bass", SB_DSP4_BASS_DEV, (SB_DSP4_BASS_DEV + 1), 4, 4, 15); 580 SB16_INPUT_SW("Synth Capture Route",
607static struct sbmix_elem snd_sb16_ctl_tone_treble = 581 SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 6, 5),
608 SB_DOUBLE("Tone Control - Treble", SB_DSP4_TREBLE_DEV, (SB_DSP4_TREBLE_DEV + 1), 4, 4, 15); 582 SB_DOUBLE("Synth Playback Volume",
609static struct sbmix_elem snd_sb16_ctl_pcm_play_vol = 583 SB_DSP4_SYNTH_DEV, (SB_DSP4_SYNTH_DEV + 1), 3, 3, 31),
610 SB_DOUBLE("PCM Playback Volume", SB_DSP4_PCM_DEV, (SB_DSP4_PCM_DEV + 1), 3, 3, 31); 584 SB16_INPUT_SW("CD Capture Route",
611static struct sbmix_elem snd_sb16_ctl_synth_capture_route = 585 SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 2, 1),
612 SB16_INPUT_SW("Synth Capture Route", SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 6, 5); 586 SB_DOUBLE("CD Playback Switch",
613static struct sbmix_elem snd_sb16_ctl_synth_play_vol = 587 SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 2, 1, 1),
614 SB_DOUBLE("Synth Playback Volume", SB_DSP4_SYNTH_DEV, (SB_DSP4_SYNTH_DEV + 1), 3, 3, 31); 588 SB_DOUBLE("CD Playback Volume",
615static struct sbmix_elem snd_sb16_ctl_cd_capture_route = 589 SB_DSP4_CD_DEV, (SB_DSP4_CD_DEV + 1), 3, 3, 31),
616 SB16_INPUT_SW("CD Capture Route", SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 2, 1); 590 SB16_INPUT_SW("Mic Capture Route",
617static struct sbmix_elem snd_sb16_ctl_cd_play_switch = 591 SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 0, 0),
618 SB_DOUBLE("CD Playback Switch", SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 2, 1, 1); 592 SB_SINGLE("Mic Playback Switch", SB_DSP4_OUTPUT_SW, 0, 1),
619static struct sbmix_elem snd_sb16_ctl_cd_play_vol = 593 SB_SINGLE("Mic Playback Volume", SB_DSP4_MIC_DEV, 3, 31),
620 SB_DOUBLE("CD Playback Volume", SB_DSP4_CD_DEV, (SB_DSP4_CD_DEV + 1), 3, 3, 31); 594 SB_SINGLE("Beep Volume", SB_DSP4_SPEAKER_DEV, 6, 3),
621static struct sbmix_elem snd_sb16_ctl_line_capture_route = 595 SB_DOUBLE("Capture Volume",
622 SB16_INPUT_SW("Line Capture Route", SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 4, 3); 596 SB_DSP4_IGAIN_DEV, (SB_DSP4_IGAIN_DEV + 1), 6, 6, 3),
623static struct sbmix_elem snd_sb16_ctl_line_play_switch = 597 SB_DOUBLE("Playback Volume",
624 SB_DOUBLE("Line Playback Switch", SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 4, 3, 1); 598 SB_DSP4_OGAIN_DEV, (SB_DSP4_OGAIN_DEV + 1), 6, 6, 3),
625static struct sbmix_elem snd_sb16_ctl_line_play_vol = 599 SB16_INPUT_SW("Line Capture Route",
626 SB_DOUBLE("Line Playback Volume", SB_DSP4_LINE_DEV, (SB_DSP4_LINE_DEV + 1), 3, 3, 31); 600 SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 4, 3),
627static struct sbmix_elem snd_sb16_ctl_mic_capture_route = 601 SB_DOUBLE("Line Playback Switch",
628 SB16_INPUT_SW("Mic Capture Route", SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 0, 0); 602 SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 4, 3, 1),
629static struct sbmix_elem snd_sb16_ctl_mic_play_switch = 603 SB_DOUBLE("Line Playback Volume",
630 SB_SINGLE("Mic Playback Switch", SB_DSP4_OUTPUT_SW, 0, 1); 604 SB_DSP4_LINE_DEV, (SB_DSP4_LINE_DEV + 1), 3, 3, 31),
631static struct sbmix_elem snd_sb16_ctl_mic_play_vol = 605 SB_SINGLE("Mic Auto Gain", SB_DSP4_MIC_AGC, 0, 1),
632 SB_SINGLE("Mic Playback Volume", SB_DSP4_MIC_DEV, 3, 31); 606 SB_SINGLE("3D Enhancement Switch", SB_DSP4_3DSE, 0, 1),
633static struct sbmix_elem snd_sb16_ctl_pc_speaker_vol = 607 SB_DOUBLE("Tone Control - Bass",
634 SB_SINGLE("Beep Volume", SB_DSP4_SPEAKER_DEV, 6, 3); 608 SB_DSP4_BASS_DEV, (SB_DSP4_BASS_DEV + 1), 4, 4, 15),
635static struct sbmix_elem snd_sb16_ctl_capture_vol = 609 SB_DOUBLE("Tone Control - Treble",
636 SB_DOUBLE("Capture Volume", SB_DSP4_IGAIN_DEV, (SB_DSP4_IGAIN_DEV + 1), 6, 6, 3); 610 SB_DSP4_TREBLE_DEV, (SB_DSP4_TREBLE_DEV + 1), 4, 4, 15)
637static struct sbmix_elem snd_sb16_ctl_play_vol =
638 SB_DOUBLE("Playback Volume", SB_DSP4_OGAIN_DEV, (SB_DSP4_OGAIN_DEV + 1), 6, 6, 3);
639static struct sbmix_elem snd_sb16_ctl_auto_mic_gain =
640 SB_SINGLE("Mic Auto Gain", SB_DSP4_MIC_AGC, 0, 1);
641
642static struct sbmix_elem *snd_sb16_controls[] = {
643 &snd_sb16_ctl_master_play_vol,
644 &snd_sb16_ctl_3d_enhance_switch,
645 &snd_sb16_ctl_tone_bass,
646 &snd_sb16_ctl_tone_treble,
647 &snd_sb16_ctl_pcm_play_vol,
648 &snd_sb16_ctl_synth_capture_route,
649 &snd_sb16_ctl_synth_play_vol,
650 &snd_sb16_ctl_cd_capture_route,
651 &snd_sb16_ctl_cd_play_switch,
652 &snd_sb16_ctl_cd_play_vol,
653 &snd_sb16_ctl_line_capture_route,
654 &snd_sb16_ctl_line_play_switch,
655 &snd_sb16_ctl_line_play_vol,
656 &snd_sb16_ctl_mic_capture_route,
657 &snd_sb16_ctl_mic_play_switch,
658 &snd_sb16_ctl_mic_play_vol,
659 &snd_sb16_ctl_pc_speaker_vol,
660 &snd_sb16_ctl_capture_vol,
661 &snd_sb16_ctl_play_vol,
662 &snd_sb16_ctl_auto_mic_gain
663}; 611};
664 612
665static unsigned char snd_sb16_init_values[][2] = { 613static unsigned char snd_sb16_init_values[][2] = {
@@ -678,46 +626,34 @@ static unsigned char snd_sb16_init_values[][2] = {
678/* 626/*
679 * DT019x specific mixer elements 627 * DT019x specific mixer elements
680 */ 628 */
681static struct sbmix_elem snd_dt019x_ctl_master_play_vol = 629static struct sbmix_elem snd_dt019x_controls[] = {
682 SB_DOUBLE("Master Playback Volume", SB_DT019X_MASTER_DEV, SB_DT019X_MASTER_DEV, 4,0, 15); 630 /* ALS4000 below has some parts which we might be lacking,
683static struct sbmix_elem snd_dt019x_ctl_pcm_play_vol = 631 * e.g. snd_als4000_ctl_mono_playback_switch - check it! */
684 SB_DOUBLE("PCM Playback Volume", SB_DT019X_PCM_DEV, SB_DT019X_PCM_DEV, 4,0, 15); 632 SB_DOUBLE("Master Playback Volume",
685static struct sbmix_elem snd_dt019x_ctl_synth_play_vol = 633 SB_DT019X_MASTER_DEV, SB_DT019X_MASTER_DEV, 4, 0, 15),
686 SB_DOUBLE("Synth Playback Volume", SB_DT019X_SYNTH_DEV, SB_DT019X_SYNTH_DEV, 4,0, 15); 634 SB_DOUBLE("PCM Playback Switch",
687static struct sbmix_elem snd_dt019x_ctl_cd_play_vol = 635 SB_DT019X_OUTPUT_SW2, SB_DT019X_OUTPUT_SW2, 2, 1, 1),
688 SB_DOUBLE("CD Playback Volume", SB_DT019X_CD_DEV, SB_DT019X_CD_DEV, 4,0, 15); 636 SB_DOUBLE("PCM Playback Volume",
689static struct sbmix_elem snd_dt019x_ctl_mic_play_vol = 637 SB_DT019X_PCM_DEV, SB_DT019X_PCM_DEV, 4, 0, 15),
690 SB_SINGLE("Mic Playback Volume", SB_DT019X_MIC_DEV, 4, 7); 638 SB_DOUBLE("Synth Playback Switch",
691static struct sbmix_elem snd_dt019x_ctl_pc_speaker_vol = 639 SB_DT019X_OUTPUT_SW2, SB_DT019X_OUTPUT_SW2, 4, 3, 1),
692 SB_SINGLE("Beep Volume", SB_DT019X_SPKR_DEV, 0, 7); 640 SB_DOUBLE("Synth Playback Volume",
693static struct sbmix_elem snd_dt019x_ctl_line_play_vol = 641 SB_DT019X_SYNTH_DEV, SB_DT019X_SYNTH_DEV, 4, 0, 15),
694 SB_DOUBLE("Line Playback Volume", SB_DT019X_LINE_DEV, SB_DT019X_LINE_DEV, 4,0, 15); 642 SB_DOUBLE("CD Playback Switch",
695static struct sbmix_elem snd_dt019x_ctl_pcm_play_switch = 643 SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 2, 1, 1),
696 SB_DOUBLE("PCM Playback Switch", SB_DT019X_OUTPUT_SW2, SB_DT019X_OUTPUT_SW2, 2,1, 1); 644 SB_DOUBLE("CD Playback Volume",
697static struct sbmix_elem snd_dt019x_ctl_synth_play_switch = 645 SB_DT019X_CD_DEV, SB_DT019X_CD_DEV, 4, 0, 15),
698 SB_DOUBLE("Synth Playback Switch", SB_DT019X_OUTPUT_SW2, SB_DT019X_OUTPUT_SW2, 4,3, 1); 646 SB_SINGLE("Mic Playback Switch", SB_DSP4_OUTPUT_SW, 0, 1),
699static struct sbmix_elem snd_dt019x_ctl_capture_source = 647 SB_SINGLE("Mic Playback Volume", SB_DT019X_MIC_DEV, 4, 7),
648 SB_SINGLE("Beep Volume", SB_DT019X_SPKR_DEV, 0, 7),
649 SB_DOUBLE("Line Playback Switch",
650 SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 4, 3, 1),
651 SB_DOUBLE("Line Playback Volume",
652 SB_DT019X_LINE_DEV, SB_DT019X_LINE_DEV, 4, 0, 15),
700 { 653 {
701 .name = "Capture Source", 654 .name = "Capture Source",
702 .type = SB_MIX_CAPTURE_DT019X 655 .type = SB_MIX_CAPTURE_DT019X
703 }; 656 }
704
705static struct sbmix_elem *snd_dt019x_controls[] = {
706 /* ALS4000 below has some parts which we might be lacking,
707 * e.g. snd_als4000_ctl_mono_playback_switch - check it! */
708 &snd_dt019x_ctl_master_play_vol,
709 &snd_dt019x_ctl_pcm_play_vol,
710 &snd_dt019x_ctl_synth_play_vol,
711 &snd_dt019x_ctl_cd_play_vol,
712 &snd_dt019x_ctl_mic_play_vol,
713 &snd_dt019x_ctl_pc_speaker_vol,
714 &snd_dt019x_ctl_line_play_vol,
715 &snd_sb16_ctl_mic_play_switch,
716 &snd_sb16_ctl_cd_play_switch,
717 &snd_sb16_ctl_line_play_switch,
718 &snd_dt019x_ctl_pcm_play_switch,
719 &snd_dt019x_ctl_synth_play_switch,
720 &snd_dt019x_ctl_capture_source
721}; 657};
722 658
723static unsigned char snd_dt019x_init_values[][2] = { 659static unsigned char snd_dt019x_init_values[][2] = {
@@ -735,82 +671,37 @@ static unsigned char snd_dt019x_init_values[][2] = {
735/* 671/*
736 * ALS4000 specific mixer elements 672 * ALS4000 specific mixer elements
737 */ 673 */
738static struct sbmix_elem snd_als4000_ctl_master_mono_playback_switch = 674static struct sbmix_elem snd_als4000_controls[] = {
739 SB_SINGLE("Master Mono Playback Switch", SB_ALS4000_MONO_IO_CTRL, 5, 1); 675 SB_DOUBLE("PCM Playback Switch",
740static struct sbmix_elem snd_als4k_ctl_master_mono_capture_route = { 676 SB_DT019X_OUTPUT_SW2, SB_DT019X_OUTPUT_SW2, 2, 1, 1),
677 SB_DOUBLE("Synth Playback Switch",
678 SB_DT019X_OUTPUT_SW2, SB_DT019X_OUTPUT_SW2, 4, 3, 1),
679 SB_SINGLE("Mic Boost (+20dB)", SB_ALS4000_MIC_IN_GAIN, 0, 0x03),
680 SB_SINGLE("Master Mono Playback Switch", SB_ALS4000_MONO_IO_CTRL, 5, 1),
681 {
741 .name = "Master Mono Capture Route", 682 .name = "Master Mono Capture Route",
742 .type = SB_MIX_MONO_CAPTURE_ALS4K 683 .type = SB_MIX_MONO_CAPTURE_ALS4K
743 }; 684 },
744static struct sbmix_elem snd_als4000_ctl_mono_playback_switch = 685 SB_SINGLE("Mono Playback Switch", SB_DT019X_OUTPUT_SW2, 0, 1),
745 SB_SINGLE("Mono Playback Switch", SB_DT019X_OUTPUT_SW2, 0, 1); 686 SB_SINGLE("Analog Loopback Switch", SB_ALS4000_MIC_IN_GAIN, 7, 0x01),
746static struct sbmix_elem snd_als4000_ctl_mic_20db_boost = 687 SB_SINGLE("3D Control - Switch", SB_ALS4000_3D_SND_FX, 6, 0x01),
747 SB_SINGLE("Mic Boost (+20dB)", SB_ALS4000_MIC_IN_GAIN, 0, 0x03);
748static struct sbmix_elem snd_als4000_ctl_mixer_analog_loopback =
749 SB_SINGLE("Analog Loopback Switch", SB_ALS4000_MIC_IN_GAIN, 7, 0x01);
750static struct sbmix_elem snd_als4000_ctl_mixer_digital_loopback =
751 SB_SINGLE("Digital Loopback Switch", 688 SB_SINGLE("Digital Loopback Switch",
752 SB_ALS4000_CR3_CONFIGURATION, 7, 0x01); 689 SB_ALS4000_CR3_CONFIGURATION, 7, 0x01),
753/* FIXME: functionality of 3D controls might be swapped, I didn't find 690 /* FIXME: functionality of 3D controls might be swapped, I didn't find
754 * a description of how to identify what is supposed to be what */ 691 * a description of how to identify what is supposed to be what */
755static struct sbmix_elem snd_als4000_3d_control_switch = 692 SB_SINGLE("3D Control - Level", SB_ALS4000_3D_SND_FX, 0, 0x07),
756 SB_SINGLE("3D Control - Switch", SB_ALS4000_3D_SND_FX, 6, 0x01);
757static struct sbmix_elem snd_als4000_3d_control_ratio =
758 SB_SINGLE("3D Control - Level", SB_ALS4000_3D_SND_FX, 0, 0x07);
759static struct sbmix_elem snd_als4000_3d_control_freq =
760 /* FIXME: maybe there's actually some standard 3D ctrl name for it?? */ 693 /* FIXME: maybe there's actually some standard 3D ctrl name for it?? */
761 SB_SINGLE("3D Control - Freq", SB_ALS4000_3D_SND_FX, 4, 0x03); 694 SB_SINGLE("3D Control - Freq", SB_ALS4000_3D_SND_FX, 4, 0x03),
762static struct sbmix_elem snd_als4000_3d_control_delay =
763 /* FIXME: ALS4000a.pdf mentions BBD (Bucket Brigade Device) time delay, 695 /* FIXME: ALS4000a.pdf mentions BBD (Bucket Brigade Device) time delay,
764 * but what ALSA 3D attribute is that actually? "Center", "Depth", 696 * but what ALSA 3D attribute is that actually? "Center", "Depth",
765 * "Wide" or "Space" or even "Level"? Assuming "Wide" for now... */ 697 * "Wide" or "Space" or even "Level"? Assuming "Wide" for now... */
766 SB_SINGLE("3D Control - Wide", SB_ALS4000_3D_TIME_DELAY, 0, 0x0f); 698 SB_SINGLE("3D Control - Wide", SB_ALS4000_3D_TIME_DELAY, 0, 0x0f),
767static struct sbmix_elem snd_als4000_3d_control_poweroff_switch = 699 SB_SINGLE("3D PowerOff Switch", SB_ALS4000_3D_TIME_DELAY, 4, 0x01),
768 SB_SINGLE("3D PowerOff Switch", SB_ALS4000_3D_TIME_DELAY, 4, 0x01);
769static struct sbmix_elem snd_als4000_ctl_3db_freq_control_switch =
770 SB_SINGLE("Master Playback 8kHz / 20kHz LPF Switch", 700 SB_SINGLE("Master Playback 8kHz / 20kHz LPF Switch",
771 SB_ALS4000_FMDAC, 5, 0x01); 701 SB_ALS4000_FMDAC, 5, 0x01),
772#ifdef NOT_AVAILABLE 702#ifdef NOT_AVAILABLE
773static struct sbmix_elem snd_als4000_ctl_fmdac = 703 SB_SINGLE("FMDAC Switch (Option ?)", SB_ALS4000_FMDAC, 0, 0x01),
774 SB_SINGLE("FMDAC Switch (Option ?)", SB_ALS4000_FMDAC, 0, 0x01); 704 SB_SINGLE("QSound Mode", SB_ALS4000_QSOUND, 1, 0x1f),
775static struct sbmix_elem snd_als4000_ctl_qsound =
776 SB_SINGLE("QSound Mode", SB_ALS4000_QSOUND, 1, 0x1f);
777#endif
778
779static struct sbmix_elem *snd_als4000_controls[] = {
780 /* ALS4000a.PDF regs page */
781 &snd_sb16_ctl_master_play_vol, /* MX30/31 12 */
782 &snd_dt019x_ctl_pcm_play_switch, /* MX4C 16 */
783 &snd_sb16_ctl_pcm_play_vol, /* MX32/33 12 */
784 &snd_sb16_ctl_synth_capture_route, /* MX3D/3E 14 */
785 &snd_dt019x_ctl_synth_play_switch, /* MX4C 16 */
786 &snd_sb16_ctl_synth_play_vol, /* MX34/35 12/13 */
787 &snd_sb16_ctl_cd_capture_route, /* MX3D/3E 14 */
788 &snd_sb16_ctl_cd_play_switch, /* MX3C 14 */
789 &snd_sb16_ctl_cd_play_vol, /* MX36/37 13 */
790 &snd_sb16_ctl_line_capture_route, /* MX3D/3E 14 */
791 &snd_sb16_ctl_line_play_switch, /* MX3C 14 */
792 &snd_sb16_ctl_line_play_vol, /* MX38/39 13 */
793 &snd_sb16_ctl_mic_capture_route, /* MX3D/3E 14 */
794 &snd_als4000_ctl_mic_20db_boost, /* MX4D 16 */
795 &snd_sb16_ctl_mic_play_switch, /* MX3C 14 */
796 &snd_sb16_ctl_mic_play_vol, /* MX3A 13 */
797 &snd_sb16_ctl_pc_speaker_vol, /* MX3B 14 */
798 &snd_sb16_ctl_capture_vol, /* MX3F/40 15 */
799 &snd_sb16_ctl_play_vol, /* MX41/42 15 */
800 &snd_als4000_ctl_master_mono_playback_switch, /* MX4C 16 */
801 &snd_als4k_ctl_master_mono_capture_route, /* MX4B 16 */
802 &snd_als4000_ctl_mono_playback_switch, /* MX4C 16 */
803 &snd_als4000_ctl_mixer_analog_loopback, /* MX4D 16 */
804 &snd_als4000_ctl_mixer_digital_loopback, /* CR3 21 */
805 &snd_als4000_3d_control_switch, /* MX50 17 */
806 &snd_als4000_3d_control_ratio, /* MX50 17 */
807 &snd_als4000_3d_control_freq, /* MX50 17 */
808 &snd_als4000_3d_control_delay, /* MX51 18 */
809 &snd_als4000_3d_control_poweroff_switch, /* MX51 18 */
810 &snd_als4000_ctl_3db_freq_control_switch, /* MX4F 17 */
811#ifdef NOT_AVAILABLE
812 &snd_als4000_ctl_fmdac,
813 &snd_als4000_ctl_qsound,
814#endif 705#endif
815}; 706};
816 707
@@ -829,11 +720,10 @@ static unsigned char snd_als4000_init_values[][2] = {
829 { SB_ALS4000_MIC_IN_GAIN, 0 }, 720 { SB_ALS4000_MIC_IN_GAIN, 0 },
830}; 721};
831 722
832
833/* 723/*
834 */ 724 */
835static int snd_sbmixer_init(struct snd_sb *chip, 725static int snd_sbmixer_init(struct snd_sb *chip,
836 struct sbmix_elem **controls, 726 struct sbmix_elem *controls,
837 int controls_count, 727 int controls_count,
838 unsigned char map[][2], 728 unsigned char map[][2],
839 int map_count, 729 int map_count,
@@ -856,7 +746,8 @@ static int snd_sbmixer_init(struct snd_sb *chip,
856 } 746 }
857 747
858 for (idx = 0; idx < controls_count; idx++) { 748 for (idx = 0; idx < controls_count; idx++) {
859 if ((err = snd_sbmixer_add_ctl_elem(chip, controls[idx])) < 0) 749 err = snd_sbmixer_add_ctl_elem(chip, &controls[idx]);
750 if (err < 0)
860 return err; 751 return err;
861 } 752 }
862 snd_component_add(card, name); 753 snd_component_add(card, name);
@@ -888,6 +779,7 @@ int snd_sbmixer_new(struct snd_sb *chip)
888 return err; 779 return err;
889 break; 780 break;
890 case SB_HW_PRO: 781 case SB_HW_PRO:
782 case SB_HW_JAZZ16:
891 if ((err = snd_sbmixer_init(chip, 783 if ((err = snd_sbmixer_init(chip,
892 snd_sbpro_controls, 784 snd_sbpro_controls,
893 ARRAY_SIZE(snd_sbpro_controls), 785 ARRAY_SIZE(snd_sbpro_controls),
@@ -908,6 +800,15 @@ int snd_sbmixer_new(struct snd_sb *chip)
908 return err; 800 return err;
909 break; 801 break;
910 case SB_HW_ALS4000: 802 case SB_HW_ALS4000:
803 /* use only the first 16 controls from SB16 */
804 err = snd_sbmixer_init(chip,
805 snd_sb16_controls,
806 16,
807 snd_sb16_init_values,
808 ARRAY_SIZE(snd_sb16_init_values),
809 "ALS4000");
810 if (err < 0)
811 return err;
911 if ((err = snd_sbmixer_init(chip, 812 if ((err = snd_sbmixer_init(chip,
912 snd_als4000_controls, 813 snd_als4000_controls,
913 ARRAY_SIZE(snd_als4000_controls), 814 ARRAY_SIZE(snd_als4000_controls),
@@ -1029,6 +930,7 @@ void snd_sbmixer_suspend(struct snd_sb *chip)
1029 save_mixer(chip, sb20_saved_regs, ARRAY_SIZE(sb20_saved_regs)); 930 save_mixer(chip, sb20_saved_regs, ARRAY_SIZE(sb20_saved_regs));
1030 break; 931 break;
1031 case SB_HW_PRO: 932 case SB_HW_PRO:
933 case SB_HW_JAZZ16:
1032 save_mixer(chip, sbpro_saved_regs, ARRAY_SIZE(sbpro_saved_regs)); 934 save_mixer(chip, sbpro_saved_regs, ARRAY_SIZE(sbpro_saved_regs));
1033 break; 935 break;
1034 case SB_HW_16: 936 case SB_HW_16:
@@ -1055,6 +957,7 @@ void snd_sbmixer_resume(struct snd_sb *chip)
1055 restore_mixer(chip, sb20_saved_regs, ARRAY_SIZE(sb20_saved_regs)); 957 restore_mixer(chip, sb20_saved_regs, ARRAY_SIZE(sb20_saved_regs));
1056 break; 958 break;
1057 case SB_HW_PRO: 959 case SB_HW_PRO:
960 case SB_HW_JAZZ16:
1058 restore_mixer(chip, sbpro_saved_regs, ARRAY_SIZE(sbpro_saved_regs)); 961 restore_mixer(chip, sbpro_saved_regs, ARRAY_SIZE(sbpro_saved_regs));
1059 break; 962 break;
1060 case SB_HW_16: 963 case SB_HW_16:
diff --git a/sound/isa/wss/wss_lib.c b/sound/isa/wss/wss_lib.c
index 5b9d6c18bc45..9191b32d9130 100644
--- a/sound/isa/wss/wss_lib.c
+++ b/sound/isa/wss/wss_lib.c
@@ -2014,6 +2014,7 @@ static int snd_wss_info_mux(struct snd_kcontrol *kcontrol,
2014 case WSS_HW_INTERWAVE: 2014 case WSS_HW_INTERWAVE:
2015 ptexts = gusmax_texts; 2015 ptexts = gusmax_texts;
2016 break; 2016 break;
2017 case WSS_HW_OPTI93X:
2017 case WSS_HW_OPL3SA2: 2018 case WSS_HW_OPL3SA2:
2018 ptexts = opl3sa_texts; 2019 ptexts = opl3sa_texts;
2019 break; 2020 break;
@@ -2246,54 +2247,12 @@ WSS_SINGLE("Beep Bypass Playback Switch", 0,
2246 CS4231_MONO_CTRL, 5, 1, 0), 2247 CS4231_MONO_CTRL, 5, 1, 0),
2247}; 2248};
2248 2249
2249static struct snd_kcontrol_new snd_opti93x_controls[] = {
2250WSS_DOUBLE("Master Playback Switch", 0,
2251 OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 7, 7, 1, 1),
2252WSS_DOUBLE_TLV("Master Playback Volume", 0,
2253 OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 1, 1, 31, 1,
2254 db_scale_6bit),
2255WSS_DOUBLE("PCM Playback Switch", 0,
2256 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1),
2257WSS_DOUBLE("PCM Playback Volume", 0,
2258 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 31, 1),
2259WSS_DOUBLE("FM Playback Switch", 0,
2260 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
2261WSS_DOUBLE("FM Playback Volume", 0,
2262 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 1, 1, 15, 1),
2263WSS_DOUBLE("Line Playback Switch", 0,
2264 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1),
2265WSS_DOUBLE("Line Playback Volume", 0,
2266 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 15, 1),
2267WSS_DOUBLE("Mic Playback Switch", 0,
2268 OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 7, 7, 1, 1),
2269WSS_DOUBLE("Mic Playback Volume", 0,
2270 OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 1, 1, 15, 1),
2271WSS_DOUBLE("Mic Boost", 0,
2272 CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 5, 5, 1, 0),
2273WSS_DOUBLE("CD Playback Switch", 0,
2274 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1),
2275WSS_DOUBLE("CD Playback Volume", 0,
2276 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 1, 1, 15, 1),
2277WSS_DOUBLE("Aux Playback Switch", 0,
2278 OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 7, 7, 1, 1),
2279WSS_DOUBLE("Aux Playback Volume", 0,
2280 OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 1, 1, 15, 1),
2281WSS_DOUBLE("Capture Volume", 0,
2282 CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 0, 0, 15, 0),
2283{
2284 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2285 .name = "Capture Source",
2286 .info = snd_wss_info_mux,
2287 .get = snd_wss_get_mux,
2288 .put = snd_wss_put_mux,
2289}
2290};
2291
2292int snd_wss_mixer(struct snd_wss *chip) 2250int snd_wss_mixer(struct snd_wss *chip)
2293{ 2251{
2294 struct snd_card *card; 2252 struct snd_card *card;
2295 unsigned int idx; 2253 unsigned int idx;
2296 int err; 2254 int err;
2255 int count = ARRAY_SIZE(snd_wss_controls);
2297 2256
2298 if (snd_BUG_ON(!chip || !chip->pcm)) 2257 if (snd_BUG_ON(!chip || !chip->pcm))
2299 return -EINVAL; 2258 return -EINVAL;
@@ -2302,28 +2261,19 @@ int snd_wss_mixer(struct snd_wss *chip)
2302 2261
2303 strcpy(card->mixername, chip->pcm->name); 2262 strcpy(card->mixername, chip->pcm->name);
2304 2263
2305 if (chip->hardware == WSS_HW_OPTI93X) 2264 /* Use only the first 11 entries on AD1848 */
2306 for (idx = 0; idx < ARRAY_SIZE(snd_opti93x_controls); idx++) { 2265 if (chip->hardware & WSS_HW_AD1848_MASK)
2307 err = snd_ctl_add(card, 2266 count = 11;
2308 snd_ctl_new1(&snd_opti93x_controls[idx], 2267 /* There is no loopback on OPTI93X */
2309 chip)); 2268 else if (chip->hardware == WSS_HW_OPTI93X)
2310 if (err < 0) 2269 count = 9;
2311 return err; 2270
2312 } 2271 for (idx = 0; idx < count; idx++) {
2313 else { 2272 err = snd_ctl_add(card,
2314 int count = ARRAY_SIZE(snd_wss_controls); 2273 snd_ctl_new1(&snd_wss_controls[idx],
2315 2274 chip));
2316 /* Use only the first 11 entries on AD1848 */ 2275 if (err < 0)
2317 if (chip->hardware & WSS_HW_AD1848_MASK) 2276 return err;
2318 count = 11;
2319
2320 for (idx = 0; idx < count; idx++) {
2321 err = snd_ctl_add(card,
2322 snd_ctl_new1(&snd_wss_controls[idx],
2323 chip));
2324 if (err < 0)
2325 return err;
2326 }
2327 } 2277 }
2328 return 0; 2278 return 0;
2329} 2279}
diff --git a/sound/mips/sgio2audio.c b/sound/mips/sgio2audio.c
index f1d9d16b5486..6aff217379d9 100644
--- a/sound/mips/sgio2audio.c
+++ b/sound/mips/sgio2audio.c
@@ -26,7 +26,6 @@
26#include <linux/delay.h> 26#include <linux/delay.h>
27#include <linux/spinlock.h> 27#include <linux/spinlock.h>
28#include <linux/gfp.h> 28#include <linux/gfp.h>
29#include <linux/vmalloc.h>
30#include <linux/interrupt.h> 29#include <linux/interrupt.h>
31#include <linux/dma-mapping.h> 30#include <linux/dma-mapping.h>
32#include <linux/platform_device.h> 31#include <linux/platform_device.h>
@@ -603,25 +602,14 @@ static int snd_sgio2audio_pcm_close(struct snd_pcm_substream *substream)
603static int snd_sgio2audio_pcm_hw_params(struct snd_pcm_substream *substream, 602static int snd_sgio2audio_pcm_hw_params(struct snd_pcm_substream *substream,
604 struct snd_pcm_hw_params *hw_params) 603 struct snd_pcm_hw_params *hw_params)
605{ 604{
606 struct snd_pcm_runtime *runtime = substream->runtime; 605 return snd_pcm_lib_alloc_vmalloc_buffer(substream,
607 int size = params_buffer_bytes(hw_params); 606 params_buffer_bytes(hw_params));
608
609 /* alloc virtual 'dma' area */
610 if (runtime->dma_area)
611 vfree(runtime->dma_area);
612 runtime->dma_area = vmalloc_user(size);
613 if (runtime->dma_area == NULL)
614 return -ENOMEM;
615 runtime->dma_bytes = size;
616 return 0;
617} 607}
618 608
619/* hw_free callback */ 609/* hw_free callback */
620static int snd_sgio2audio_pcm_hw_free(struct snd_pcm_substream *substream) 610static int snd_sgio2audio_pcm_hw_free(struct snd_pcm_substream *substream)
621{ 611{
622 vfree(substream->runtime->dma_area); 612 return snd_pcm_lib_free_vmalloc_buffer(substream);
623 substream->runtime->dma_area = NULL;
624 return 0;
625} 613}
626 614
627/* prepare callback */ 615/* prepare callback */
@@ -692,13 +680,6 @@ snd_sgio2audio_pcm_pointer(struct snd_pcm_substream *substream)
692 chip->channel[chan->idx].pos); 680 chip->channel[chan->idx].pos);
693} 681}
694 682
695/* get the physical page pointer on the given offset */
696static struct page *snd_sgio2audio_page(struct snd_pcm_substream *substream,
697 unsigned long offset)
698{
699 return vmalloc_to_page(substream->runtime->dma_area + offset);
700}
701
702/* operators */ 683/* operators */
703static struct snd_pcm_ops snd_sgio2audio_playback1_ops = { 684static struct snd_pcm_ops snd_sgio2audio_playback1_ops = {
704 .open = snd_sgio2audio_playback1_open, 685 .open = snd_sgio2audio_playback1_open,
@@ -709,7 +690,8 @@ static struct snd_pcm_ops snd_sgio2audio_playback1_ops = {
709 .prepare = snd_sgio2audio_pcm_prepare, 690 .prepare = snd_sgio2audio_pcm_prepare,
710 .trigger = snd_sgio2audio_pcm_trigger, 691 .trigger = snd_sgio2audio_pcm_trigger,
711 .pointer = snd_sgio2audio_pcm_pointer, 692 .pointer = snd_sgio2audio_pcm_pointer,
712 .page = snd_sgio2audio_page, 693 .page = snd_pcm_lib_get_vmalloc_page,
694 .mmap = snd_pcm_lib_mmap_vmalloc,
713}; 695};
714 696
715static struct snd_pcm_ops snd_sgio2audio_playback2_ops = { 697static struct snd_pcm_ops snd_sgio2audio_playback2_ops = {
@@ -721,7 +703,8 @@ static struct snd_pcm_ops snd_sgio2audio_playback2_ops = {
721 .prepare = snd_sgio2audio_pcm_prepare, 703 .prepare = snd_sgio2audio_pcm_prepare,
722 .trigger = snd_sgio2audio_pcm_trigger, 704 .trigger = snd_sgio2audio_pcm_trigger,
723 .pointer = snd_sgio2audio_pcm_pointer, 705 .pointer = snd_sgio2audio_pcm_pointer,
724 .page = snd_sgio2audio_page, 706 .page = snd_pcm_lib_get_vmalloc_page,
707 .mmap = snd_pcm_lib_mmap_vmalloc,
725}; 708};
726 709
727static struct snd_pcm_ops snd_sgio2audio_capture_ops = { 710static struct snd_pcm_ops snd_sgio2audio_capture_ops = {
@@ -733,7 +716,8 @@ static struct snd_pcm_ops snd_sgio2audio_capture_ops = {
733 .prepare = snd_sgio2audio_pcm_prepare, 716 .prepare = snd_sgio2audio_pcm_prepare,
734 .trigger = snd_sgio2audio_pcm_trigger, 717 .trigger = snd_sgio2audio_pcm_trigger,
735 .pointer = snd_sgio2audio_pcm_pointer, 718 .pointer = snd_sgio2audio_pcm_pointer,
736 .page = snd_sgio2audio_page, 719 .page = snd_pcm_lib_get_vmalloc_page,
720 .mmap = snd_pcm_lib_mmap_vmalloc,
737}; 721};
738 722
739/* 723/*
diff --git a/sound/oss/au1550_ac97.c b/sound/oss/au1550_ac97.c
index 4191acccbcdb..c1070e33b32f 100644
--- a/sound/oss/au1550_ac97.c
+++ b/sound/oss/au1550_ac97.c
@@ -614,7 +614,8 @@ start_adc(struct au1550_state *s)
614 /* Put two buffers on the ring to get things started. 614 /* Put two buffers on the ring to get things started.
615 */ 615 */
616 for (i=0; i<2; i++) { 616 for (i=0; i<2; i++) {
617 au1xxx_dbdma_put_dest(db->dmanr, db->nextIn, db->dma_fragsize); 617 au1xxx_dbdma_put_dest(db->dmanr, virt_to_phys(db->nextIn),
618 db->dma_fragsize, DDMA_FLAGS_IE);
618 619
619 db->nextIn += db->dma_fragsize; 620 db->nextIn += db->dma_fragsize;
620 if (db->nextIn >= db->rawbuf + db->dmasize) 621 if (db->nextIn >= db->rawbuf + db->dmasize)
@@ -732,8 +733,9 @@ static void dac_dma_interrupt(int irq, void *dev_id)
732 db->dma_qcount--; 733 db->dma_qcount--;
733 734
734 if (db->count >= db->fragsize) { 735 if (db->count >= db->fragsize) {
735 if (au1xxx_dbdma_put_source(db->dmanr, db->nextOut, 736 if (au1xxx_dbdma_put_source(db->dmanr,
736 db->fragsize) == 0) { 737 virt_to_phys(db->nextOut), db->fragsize,
738 DDMA_FLAGS_IE) == 0) {
737 err("qcount < 2 and no ring room!"); 739 err("qcount < 2 and no ring room!");
738 } 740 }
739 db->nextOut += db->fragsize; 741 db->nextOut += db->fragsize;
@@ -777,7 +779,8 @@ static void adc_dma_interrupt(int irq, void *dev_id)
777 779
778 /* Put a new empty buffer on the destination DMA. 780 /* Put a new empty buffer on the destination DMA.
779 */ 781 */
780 au1xxx_dbdma_put_dest(dp->dmanr, dp->nextIn, dp->dma_fragsize); 782 au1xxx_dbdma_put_dest(dp->dmanr, virt_to_phys(dp->nextIn),
783 dp->dma_fragsize, DDMA_FLAGS_IE);
781 784
782 dp->nextIn += dp->dma_fragsize; 785 dp->nextIn += dp->dma_fragsize;
783 if (dp->nextIn >= dp->rawbuf + dp->dmasize) 786 if (dp->nextIn >= dp->rawbuf + dp->dmasize)
@@ -1177,8 +1180,9 @@ au1550_write(struct file *file, const char *buffer, size_t count, loff_t * ppos)
1177 * we know the dma has stopped. 1180 * we know the dma has stopped.
1178 */ 1181 */
1179 while ((db->dma_qcount < 2) && (db->count >= db->fragsize)) { 1182 while ((db->dma_qcount < 2) && (db->count >= db->fragsize)) {
1180 if (au1xxx_dbdma_put_source(db->dmanr, db->nextOut, 1183 if (au1xxx_dbdma_put_source(db->dmanr,
1181 db->fragsize) == 0) { 1184 virt_to_phys(db->nextOut), db->fragsize,
1185 DDMA_FLAGS_IE) == 0) {
1182 err("qcount < 2 and no ring room!"); 1186 err("qcount < 2 and no ring room!");
1183 } 1187 }
1184 db->nextOut += db->fragsize; 1188 db->nextOut += db->fragsize;
diff --git a/sound/oss/kahlua.c b/sound/oss/kahlua.c
index 89466b056be7..24d152ccf80d 100644
--- a/sound/oss/kahlua.c
+++ b/sound/oss/kahlua.c
@@ -198,7 +198,7 @@ MODULE_LICENSE("GPL");
198 * 5530 only. The 5510/5520 decode is different. 198 * 5530 only. The 5510/5520 decode is different.
199 */ 199 */
200 200
201static struct pci_device_id id_tbl[] = { 201static DEFINE_PCI_DEVICE_TABLE(id_tbl) = {
202 { PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5530_AUDIO), 0 }, 202 { PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5530_AUDIO), 0 },
203 { } 203 { }
204}; 204};
diff --git a/sound/oss/soundcard.c b/sound/oss/soundcard.c
index c62530943888..fde7c12fe5da 100644
--- a/sound/oss/soundcard.c
+++ b/sound/oss/soundcard.c
@@ -328,11 +328,11 @@ static int sound_mixer_ioctl(int mixdev, unsigned int cmd, void __user *arg)
328 return mixer_devs[mixdev]->ioctl(mixdev, cmd, arg); 328 return mixer_devs[mixdev]->ioctl(mixdev, cmd, arg);
329} 329}
330 330
331static int sound_ioctl(struct inode *inode, struct file *file, 331static long sound_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
332 unsigned int cmd, unsigned long arg)
333{ 332{
334 int len = 0, dtype; 333 int len = 0, dtype;
335 int dev = iminor(inode); 334 int dev = iminor(file->f_dentry->d_inode);
335 long ret = -EINVAL;
336 void __user *p = (void __user *)arg; 336 void __user *p = (void __user *)arg;
337 337
338 if (_SIOC_DIR(cmd) != _SIOC_NONE && _SIOC_DIR(cmd) != 0) { 338 if (_SIOC_DIR(cmd) != _SIOC_NONE && _SIOC_DIR(cmd) != 0) {
@@ -353,6 +353,7 @@ static int sound_ioctl(struct inode *inode, struct file *file,
353 if (cmd == OSS_GETVERSION) 353 if (cmd == OSS_GETVERSION)
354 return __put_user(SOUND_VERSION, (int __user *)p); 354 return __put_user(SOUND_VERSION, (int __user *)p);
355 355
356 lock_kernel();
356 if (_IOC_TYPE(cmd) == 'M' && num_mixers > 0 && /* Mixer ioctl */ 357 if (_IOC_TYPE(cmd) == 'M' && num_mixers > 0 && /* Mixer ioctl */
357 (dev & 0x0f) != SND_DEV_CTL) { 358 (dev & 0x0f) != SND_DEV_CTL) {
358 dtype = dev & 0x0f; 359 dtype = dev & 0x0f;
@@ -360,24 +361,31 @@ static int sound_ioctl(struct inode *inode, struct file *file,
360 case SND_DEV_DSP: 361 case SND_DEV_DSP:
361 case SND_DEV_DSP16: 362 case SND_DEV_DSP16:
362 case SND_DEV_AUDIO: 363 case SND_DEV_AUDIO:
363 return sound_mixer_ioctl(audio_devs[dev >> 4]->mixer_dev, 364 ret = sound_mixer_ioctl(audio_devs[dev >> 4]->mixer_dev,
364 cmd, p); 365 cmd, p);
365 366 break;
366 default: 367 default:
367 return sound_mixer_ioctl(dev >> 4, cmd, p); 368 ret = sound_mixer_ioctl(dev >> 4, cmd, p);
369 break;
368 } 370 }
371 unlock_kernel();
372 return ret;
369 } 373 }
374
370 switch (dev & 0x0f) { 375 switch (dev & 0x0f) {
371 case SND_DEV_CTL: 376 case SND_DEV_CTL:
372 if (cmd == SOUND_MIXER_GETLEVELS) 377 if (cmd == SOUND_MIXER_GETLEVELS)
373 return get_mixer_levels(p); 378 ret = get_mixer_levels(p);
374 if (cmd == SOUND_MIXER_SETLEVELS) 379 else if (cmd == SOUND_MIXER_SETLEVELS)
375 return set_mixer_levels(p); 380 ret = set_mixer_levels(p);
376 return sound_mixer_ioctl(dev >> 4, cmd, p); 381 else
382 ret = sound_mixer_ioctl(dev >> 4, cmd, p);
383 break;
377 384
378 case SND_DEV_SEQ: 385 case SND_DEV_SEQ:
379 case SND_DEV_SEQ2: 386 case SND_DEV_SEQ2:
380 return sequencer_ioctl(dev, file, cmd, p); 387 ret = sequencer_ioctl(dev, file, cmd, p);
388 break;
381 389
382 case SND_DEV_DSP: 390 case SND_DEV_DSP:
383 case SND_DEV_DSP16: 391 case SND_DEV_DSP16:
@@ -390,7 +398,8 @@ static int sound_ioctl(struct inode *inode, struct file *file,
390 break; 398 break;
391 399
392 } 400 }
393 return -EINVAL; 401 unlock_kernel();
402 return ret;
394} 403}
395 404
396static unsigned int sound_poll(struct file *file, poll_table * wait) 405static unsigned int sound_poll(struct file *file, poll_table * wait)
@@ -490,7 +499,7 @@ const struct file_operations oss_sound_fops = {
490 .read = sound_read, 499 .read = sound_read,
491 .write = sound_write, 500 .write = sound_write,
492 .poll = sound_poll, 501 .poll = sound_poll,
493 .ioctl = sound_ioctl, 502 .unlocked_ioctl = sound_ioctl,
494 .mmap = sound_mmap, 503 .mmap = sound_mmap,
495 .open = sound_open, 504 .open = sound_open,
496 .release = sound_release, 505 .release = sound_release,
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index 351654cf7b09..1298c68d6bf0 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -789,6 +789,7 @@ config SND_VIRTUOSO
789 Say Y here to include support for sound cards based on the 789 Say Y here to include support for sound cards based on the
790 Asus AV100/AV200 chips, i.e., Xonar D1, DX, D2, D2X, 790 Asus AV100/AV200 chips, i.e., Xonar D1, DX, D2, D2X,
791 Essence ST (Deluxe), and Essence STX. 791 Essence ST (Deluxe), and Essence STX.
792 Support for the DS is experimental.
792 Support for the HDAV1.3 (Deluxe) is very experimental. 793 Support for the HDAV1.3 (Deluxe) is very experimental.
793 794
794 To compile this driver as a module, choose M here: the module 795 To compile this driver as a module, choose M here: the module
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
index d9266bae2849..1caf5e3c1f6a 100644
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -544,25 +544,10 @@ static int patch_wolfson04(struct snd_ac97 * ac97)
544 return 0; 544 return 0;
545} 545}
546 546
547static int patch_wolfson_wm9705_specific(struct snd_ac97 * ac97)
548{
549 int err, i;
550 for (i = 0; i < ARRAY_SIZE(wm97xx_snd_ac97_controls); i++) {
551 if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm97xx_snd_ac97_controls[i], ac97))) < 0)
552 return err;
553 }
554 snd_ac97_write_cache(ac97, 0x72, 0x0808);
555 return 0;
556}
557
558static struct snd_ac97_build_ops patch_wolfson_wm9705_ops = {
559 .build_specific = patch_wolfson_wm9705_specific,
560};
561
562static int patch_wolfson05(struct snd_ac97 * ac97) 547static int patch_wolfson05(struct snd_ac97 * ac97)
563{ 548{
564 /* WM9705, WM9710 */ 549 /* WM9705, WM9710 */
565 ac97->build_ops = &patch_wolfson_wm9705_ops; 550 ac97->build_ops = &patch_wolfson_wm9703_ops;
566#ifdef CONFIG_TOUCHSCREEN_WM9705 551#ifdef CONFIG_TOUCHSCREEN_WM9705
567 /* WM9705 touchscreen uses AUX and VIDEO for touch */ 552 /* WM9705 touchscreen uses AUX and VIDEO for touch */
568 ac97->flags |= AC97_HAS_NO_VIDEO | AC97_HAS_NO_AUX; 553 ac97->flags |= AC97_HAS_NO_VIDEO | AC97_HAS_NO_AUX;
diff --git a/sound/pci/ad1889.c b/sound/pci/ad1889.c
index 8f5098f92c37..4382d0fa6b9a 100644
--- a/sound/pci/ad1889.c
+++ b/sound/pci/ad1889.c
@@ -1048,7 +1048,7 @@ snd_ad1889_remove(struct pci_dev *pci)
1048 pci_set_drvdata(pci, NULL); 1048 pci_set_drvdata(pci, NULL);
1049} 1049}
1050 1050
1051static struct pci_device_id snd_ad1889_ids[] = { 1051static DEFINE_PCI_DEVICE_TABLE(snd_ad1889_ids) = {
1052 { PCI_DEVICE(PCI_VENDOR_ID_ANALOG_DEVICES, PCI_DEVICE_ID_AD1889JS) }, 1052 { PCI_DEVICE(PCI_VENDOR_ID_ANALOG_DEVICES, PCI_DEVICE_ID_AD1889JS) },
1053 { 0, }, 1053 { 0, },
1054}; 1054};
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c
index aaf4da68969c..5c6e322a48f0 100644
--- a/sound/pci/ali5451/ali5451.c
+++ b/sound/pci/ali5451/ali5451.c
@@ -275,7 +275,7 @@ struct snd_ali {
275#endif 275#endif
276}; 276};
277 277
278static struct pci_device_id snd_ali_ids[] = { 278static DEFINE_PCI_DEVICE_TABLE(snd_ali_ids) = {
279 {PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5451), 0, 0, 0}, 279 {PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5451), 0, 0, 0},
280 {0, } 280 {0, }
281}; 281};
diff --git a/sound/pci/als300.c b/sound/pci/als300.c
index 3aa35af7ca91..d7653cb7ac60 100644
--- a/sound/pci/als300.c
+++ b/sound/pci/als300.c
@@ -145,7 +145,7 @@ struct snd_als300_substream_data {
145 int block_counter_register; 145 int block_counter_register;
146}; 146};
147 147
148static struct pci_device_id snd_als300_ids[] = { 148static DEFINE_PCI_DEVICE_TABLE(snd_als300_ids) = {
149 { 0x4005, 0x0300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALS300 }, 149 { 0x4005, 0x0300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALS300 },
150 { 0x4005, 0x0308, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALS300_PLUS }, 150 { 0x4005, 0x0308, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALS300_PLUS },
151 { 0, } 151 { 0, }
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c
index 3dbacde1a5af..d75cf7b06426 100644
--- a/sound/pci/als4000.c
+++ b/sound/pci/als4000.c
@@ -117,7 +117,7 @@ struct snd_card_als4000 {
117#endif 117#endif
118}; 118};
119 119
120static struct pci_device_id snd_als4000_ids[] = { 120static DEFINE_PCI_DEVICE_TABLE(snd_als4000_ids) = {
121 { 0x4005, 0x4000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* ALS4000 */ 121 { 0x4005, 0x4000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* ALS4000 */
122 { 0, } 122 { 0, }
123}; 123};
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c
index 42b4fbbd8e2b..49d572a7b235 100644
--- a/sound/pci/atiixp.c
+++ b/sound/pci/atiixp.c
@@ -286,7 +286,7 @@ struct atiixp {
286 286
287/* 287/*
288 */ 288 */
289static struct pci_device_id snd_atiixp_ids[] = { 289static DEFINE_PCI_DEVICE_TABLE(snd_atiixp_ids) = {
290 { PCI_VDEVICE(ATI, 0x4341), 0 }, /* SB200 */ 290 { PCI_VDEVICE(ATI, 0x4341), 0 }, /* SB200 */
291 { PCI_VDEVICE(ATI, 0x4361), 0 }, /* SB300 */ 291 { PCI_VDEVICE(ATI, 0x4361), 0 }, /* SB300 */
292 { PCI_VDEVICE(ATI, 0x4370), 0 }, /* SB400 */ 292 { PCI_VDEVICE(ATI, 0x4370), 0 }, /* SB400 */
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c
index e7e147bf8eb2..91d7036b6411 100644
--- a/sound/pci/atiixp_modem.c
+++ b/sound/pci/atiixp_modem.c
@@ -261,7 +261,7 @@ struct atiixp_modem {
261 261
262/* 262/*
263 */ 263 */
264static struct pci_device_id snd_atiixp_ids[] = { 264static DEFINE_PCI_DEVICE_TABLE(snd_atiixp_ids) = {
265 { PCI_VDEVICE(ATI, 0x434d), 0 }, /* SB200 */ 265 { PCI_VDEVICE(ATI, 0x434d), 0 }, /* SB200 */
266 { PCI_VDEVICE(ATI, 0x4378), 0 }, /* SB400 */ 266 { PCI_VDEVICE(ATI, 0x4378), 0 }, /* SB400 */
267 { 0, } 267 { 0, }
diff --git a/sound/pci/au88x0/au8810.c b/sound/pci/au88x0/au8810.c
index c0e8c6b295cb..aa51cc7771dd 100644
--- a/sound/pci/au88x0/au8810.c
+++ b/sound/pci/au88x0/au8810.c
@@ -1,6 +1,6 @@
1#include "au8810.h" 1#include "au8810.h"
2#include "au88x0.h" 2#include "au88x0.h"
3static struct pci_device_id snd_vortex_ids[] = { 3static DEFINE_PCI_DEVICE_TABLE(snd_vortex_ids) = {
4 {PCI_VDEVICE(AUREAL, PCI_DEVICE_ID_AUREAL_ADVANTAGE), 1,}, 4 {PCI_VDEVICE(AUREAL, PCI_DEVICE_ID_AUREAL_ADVANTAGE), 1,},
5 {0,} 5 {0,}
6}; 6};
diff --git a/sound/pci/au88x0/au8820.c b/sound/pci/au88x0/au8820.c
index a6527330df58..2f321e7306cd 100644
--- a/sound/pci/au88x0/au8820.c
+++ b/sound/pci/au88x0/au8820.c
@@ -1,6 +1,6 @@
1#include "au8820.h" 1#include "au8820.h"
2#include "au88x0.h" 2#include "au88x0.h"
3static struct pci_device_id snd_vortex_ids[] = { 3static DEFINE_PCI_DEVICE_TABLE(snd_vortex_ids) = {
4 {PCI_VDEVICE(AUREAL, PCI_DEVICE_ID_AUREAL_VORTEX_1), 0,}, 4 {PCI_VDEVICE(AUREAL, PCI_DEVICE_ID_AUREAL_VORTEX_1), 0,},
5 {0,} 5 {0,}
6}; 6};
diff --git a/sound/pci/au88x0/au8830.c b/sound/pci/au88x0/au8830.c
index 6c702ad4352a..279b78f06d22 100644
--- a/sound/pci/au88x0/au8830.c
+++ b/sound/pci/au88x0/au8830.c
@@ -1,6 +1,6 @@
1#include "au8830.h" 1#include "au8830.h"
2#include "au88x0.h" 2#include "au88x0.h"
3static struct pci_device_id snd_vortex_ids[] = { 3static DEFINE_PCI_DEVICE_TABLE(snd_vortex_ids) = {
4 {PCI_VDEVICE(AUREAL, PCI_DEVICE_ID_AUREAL_VORTEX_2), 0,}, 4 {PCI_VDEVICE(AUREAL, PCI_DEVICE_ID_AUREAL_VORTEX_2), 0,},
5 {0,} 5 {0,}
6}; 6};
diff --git a/sound/pci/aw2/aw2-alsa.c b/sound/pci/aw2/aw2-alsa.c
index 4d34bb0d99d3..67921f93a41e 100644
--- a/sound/pci/aw2/aw2-alsa.c
+++ b/sound/pci/aw2/aw2-alsa.c
@@ -164,7 +164,7 @@ MODULE_PARM_DESC(id, "ID string for the Audiowerk2 soundcard.");
164module_param_array(enable, bool, NULL, 0444); 164module_param_array(enable, bool, NULL, 0444);
165MODULE_PARM_DESC(enable, "Enable Audiowerk2 soundcard."); 165MODULE_PARM_DESC(enable, "Enable Audiowerk2 soundcard.");
166 166
167static struct pci_device_id snd_aw2_ids[] = { 167static DEFINE_PCI_DEVICE_TABLE(snd_aw2_ids) = {
168 {PCI_VENDOR_ID_SAA7146, PCI_DEVICE_ID_SAA7146, 0, 0, 168 {PCI_VENDOR_ID_SAA7146, PCI_DEVICE_ID_SAA7146, 0, 0,
169 0, 0, 0}, 169 0, 0, 0},
170 {0} 170 {0}
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index 69867ace7860..4679ed83a43b 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -350,7 +350,7 @@ struct snd_azf3328 {
350#endif 350#endif
351}; 351};
352 352
353static const struct pci_device_id snd_azf3328_ids[] = { 353static DEFINE_PCI_DEVICE_TABLE(snd_azf3328_ids) = {
354 { 0x122D, 0x50DC, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* PCI168/3328 */ 354 { 0x122D, 0x50DC, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* PCI168/3328 */
355 { 0x122D, 0x80DA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* 3328 */ 355 { 0x122D, 0x80DA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* 3328 */
356 { 0, } 356 { 0, }
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c
index 4e2b925a94cc..37e1b5df5ab8 100644
--- a/sound/pci/bt87x.c
+++ b/sound/pci/bt87x.c
@@ -795,7 +795,7 @@ fail:
795 .driver_data = SND_BT87X_BOARD_ ## id } 795 .driver_data = SND_BT87X_BOARD_ ## id }
796/* driver_data is the card id for that device */ 796/* driver_data is the card id for that device */
797 797
798static struct pci_device_id snd_bt87x_ids[] = { 798static DEFINE_PCI_DEVICE_TABLE(snd_bt87x_ids) = {
799 /* Hauppauge WinTV series */ 799 /* Hauppauge WinTV series */
800 BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0x13eb, GENERIC), 800 BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0x13eb, GENERIC),
801 /* Hauppauge WinTV series */ 801 /* Hauppauge WinTV series */
@@ -964,7 +964,7 @@ static void __devexit snd_bt87x_remove(struct pci_dev *pci)
964 964
965/* default entries for all Bt87x cards - it's not exported */ 965/* default entries for all Bt87x cards - it's not exported */
966/* driver_data is set to 0 to call detection */ 966/* driver_data is set to 0 to call detection */
967static struct pci_device_id snd_bt87x_default_ids[] __devinitdata = { 967static DEFINE_PCI_DEVICE_TABLE(snd_bt87x_default_ids) = {
968 BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, PCI_ANY_ID, PCI_ANY_ID, UNKNOWN), 968 BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, PCI_ANY_ID, PCI_ANY_ID, UNKNOWN),
969 BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, PCI_ANY_ID, PCI_ANY_ID, UNKNOWN), 969 BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, PCI_ANY_ID, PCI_ANY_ID, UNKNOWN),
970 { } 970 { }
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index 15e4138bce17..0a3d3d6e77b4 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -1875,7 +1875,7 @@ static int snd_ca0106_resume(struct pci_dev *pci)
1875#endif 1875#endif
1876 1876
1877// PCI IDs 1877// PCI IDs
1878static struct pci_device_id snd_ca0106_ids[] = { 1878static DEFINE_PCI_DEVICE_TABLE(snd_ca0106_ids) = {
1879 { PCI_VDEVICE(CREATIVE, 0x0007), 0 }, /* Audigy LS or Live 24bit */ 1879 { PCI_VDEVICE(CREATIVE, 0x0007), 0 }, /* Audigy LS or Live 24bit */
1880 { 0, } 1880 { 0, }
1881}; 1881};
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c
index a312bae08f52..1ded64e05643 100644
--- a/sound/pci/cmipci.c
+++ b/sound/pci/cmipci.c
@@ -2796,7 +2796,7 @@ static inline void snd_cmipci_proc_init(struct cmipci *cm) {}
2796#endif 2796#endif
2797 2797
2798 2798
2799static struct pci_device_id snd_cmipci_ids[] = { 2799static DEFINE_PCI_DEVICE_TABLE(snd_cmipci_ids) = {
2800 {PCI_VDEVICE(CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338A), 0}, 2800 {PCI_VDEVICE(CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338A), 0},
2801 {PCI_VDEVICE(CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338B), 0}, 2801 {PCI_VDEVICE(CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338B), 0},
2802 {PCI_VDEVICE(CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8738), 0}, 2802 {PCI_VDEVICE(CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8738), 0},
@@ -3018,7 +3018,7 @@ static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pc
3018 int integrated_midi = 0; 3018 int integrated_midi = 0;
3019 char modelstr[16]; 3019 char modelstr[16];
3020 int pcm_index, pcm_spdif_index; 3020 int pcm_index, pcm_spdif_index;
3021 static struct pci_device_id intel_82437vx[] = { 3021 static DEFINE_PCI_DEVICE_TABLE(intel_82437vx) = {
3022 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437VX) }, 3022 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437VX) },
3023 { }, 3023 { },
3024 }; 3024 };
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c
index e2e0359bb056..9edc65059e3e 100644
--- a/sound/pci/cs4281.c
+++ b/sound/pci/cs4281.c
@@ -494,7 +494,7 @@ struct cs4281 {
494 494
495static irqreturn_t snd_cs4281_interrupt(int irq, void *dev_id); 495static irqreturn_t snd_cs4281_interrupt(int irq, void *dev_id);
496 496
497static struct pci_device_id snd_cs4281_ids[] = { 497static DEFINE_PCI_DEVICE_TABLE(snd_cs4281_ids) = {
498 { PCI_VDEVICE(CIRRUS, 0x6005), 0, }, /* CS4281 */ 498 { PCI_VDEVICE(CIRRUS, 0x6005), 0, }, /* CS4281 */
499 { 0, } 499 { 0, }
500}; 500};
diff --git a/sound/pci/cs46xx/cs46xx.c b/sound/pci/cs46xx/cs46xx.c
index 033aec430117..767fa7f06cd0 100644
--- a/sound/pci/cs46xx/cs46xx.c
+++ b/sound/pci/cs46xx/cs46xx.c
@@ -64,7 +64,7 @@ MODULE_PARM_DESC(thinkpad, "Force to enable Thinkpad's CLKRUN control.");
64module_param_array(mmap_valid, bool, NULL, 0444); 64module_param_array(mmap_valid, bool, NULL, 0444);
65MODULE_PARM_DESC(mmap_valid, "Support OSS mmap."); 65MODULE_PARM_DESC(mmap_valid, "Support OSS mmap.");
66 66
67static struct pci_device_id snd_cs46xx_ids[] = { 67static DEFINE_PCI_DEVICE_TABLE(snd_cs46xx_ids) = {
68 { PCI_VDEVICE(CIRRUS, 0x6001), 0, }, /* CS4280 */ 68 { PCI_VDEVICE(CIRRUS, 0x6001), 0, }, /* CS4280 */
69 { PCI_VDEVICE(CIRRUS, 0x6003), 0, }, /* CS4612 */ 69 { PCI_VDEVICE(CIRRUS, 0x6003), 0, }, /* CS4612 */
70 { PCI_VDEVICE(CIRRUS, 0x6004), 0, }, /* CS4615 */ 70 { PCI_VDEVICE(CIRRUS, 0x6004), 0, }, /* CS4615 */
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
index 1be96ead4244..3f99a5e8528c 100644
--- a/sound/pci/cs46xx/cs46xx_lib.c
+++ b/sound/pci/cs46xx/cs46xx_lib.c
@@ -2238,11 +2238,11 @@ static void snd_cs46xx_codec_reset (struct snd_ac97 * ac97)
2238 2238
2239 /* set the desired CODEC mode */ 2239 /* set the desired CODEC mode */
2240 if (ac97->num == CS46XX_PRIMARY_CODEC_INDEX) { 2240 if (ac97->num == CS46XX_PRIMARY_CODEC_INDEX) {
2241 snd_printdd("cs46xx: CODOEC1 mode %04x\n",0x0); 2241 snd_printdd("cs46xx: CODEC1 mode %04x\n", 0x0);
2242 snd_cs46xx_ac97_write(ac97,AC97_CSR_ACMODE,0x0); 2242 snd_cs46xx_ac97_write(ac97, AC97_CSR_ACMODE, 0x0);
2243 } else if (ac97->num == CS46XX_SECONDARY_CODEC_INDEX) { 2243 } else if (ac97->num == CS46XX_SECONDARY_CODEC_INDEX) {
2244 snd_printdd("cs46xx: CODOEC2 mode %04x\n",0x3); 2244 snd_printdd("cs46xx: CODEC2 mode %04x\n", 0x3);
2245 snd_cs46xx_ac97_write(ac97,AC97_CSR_ACMODE,0x3); 2245 snd_cs46xx_ac97_write(ac97, AC97_CSR_ACMODE, 0x3);
2246 } else { 2246 } else {
2247 snd_BUG(); /* should never happen ... */ 2247 snd_BUG(); /* should never happen ... */
2248 } 2248 }
@@ -2266,7 +2266,7 @@ static void snd_cs46xx_codec_reset (struct snd_ac97 * ac97)
2266 return; 2266 return;
2267 2267
2268 /* test if we can write to the record gain volume register */ 2268 /* test if we can write to the record gain volume register */
2269 snd_ac97_write_cache(ac97, AC97_REC_GAIN, 0x8a05); 2269 snd_ac97_write(ac97, AC97_REC_GAIN, 0x8a05);
2270 if ((err = snd_ac97_read(ac97, AC97_REC_GAIN)) == 0x8a05) 2270 if ((err = snd_ac97_read(ac97, AC97_REC_GAIN)) == 0x8a05)
2271 return; 2271 return;
2272 2272
@@ -3597,7 +3597,7 @@ static struct cs_card_type __devinitdata cards[] = {
3597#ifdef CONFIG_PM 3597#ifdef CONFIG_PM
3598static unsigned int saved_regs[] = { 3598static unsigned int saved_regs[] = {
3599 BA0_ACOSV, 3599 BA0_ACOSV,
3600 BA0_ASER_FADDR, 3600 /*BA0_ASER_FADDR,*/
3601 BA0_ASER_MASTER, 3601 BA0_ASER_MASTER,
3602 BA1_PVOL, 3602 BA1_PVOL,
3603 BA1_CVOL, 3603 BA1_CVOL,
@@ -3644,6 +3644,7 @@ int snd_cs46xx_resume(struct pci_dev *pci)
3644#ifdef CONFIG_SND_CS46XX_NEW_DSP 3644#ifdef CONFIG_SND_CS46XX_NEW_DSP
3645 int i; 3645 int i;
3646#endif 3646#endif
3647 unsigned int tmp;
3647 3648
3648 pci_set_power_state(pci, PCI_D0); 3649 pci_set_power_state(pci, PCI_D0);
3649 pci_restore_state(pci); 3650 pci_restore_state(pci);
@@ -3685,6 +3686,15 @@ int snd_cs46xx_resume(struct pci_dev *pci)
3685 snd_ac97_resume(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]); 3686 snd_ac97_resume(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]);
3686 snd_ac97_resume(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]); 3687 snd_ac97_resume(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]);
3687 3688
3689 /*
3690 * Stop capture DMA.
3691 */
3692 tmp = snd_cs46xx_peek(chip, BA1_CCTL);
3693 chip->capt.ctl = tmp & 0x0000ffff;
3694 snd_cs46xx_poke(chip, BA1_CCTL, tmp & 0xffff0000);
3695
3696 mdelay(5);
3697
3688 /* reset playback/capture */ 3698 /* reset playback/capture */
3689 snd_cs46xx_set_play_sample_rate(chip, 8000); 3699 snd_cs46xx_set_play_sample_rate(chip, 8000);
3690 snd_cs46xx_set_capture_sample_rate(chip, 8000); 3700 snd_cs46xx_set_capture_sample_rate(chip, 8000);
diff --git a/sound/pci/cs46xx/dsp_spos.c b/sound/pci/cs46xx/dsp_spos.c
index f4f0c8f5dad7..3e5ca8fb519f 100644
--- a/sound/pci/cs46xx/dsp_spos.c
+++ b/sound/pci/cs46xx/dsp_spos.c
@@ -298,6 +298,9 @@ void cs46xx_dsp_spos_destroy (struct snd_cs46xx * chip)
298 if (ins->scbs[i].deleted) continue; 298 if (ins->scbs[i].deleted) continue;
299 299
300 cs46xx_dsp_proc_free_scb_desc ( (ins->scbs + i) ); 300 cs46xx_dsp_proc_free_scb_desc ( (ins->scbs + i) );
301#ifdef CONFIG_PM
302 kfree(ins->scbs[i].data);
303#endif
301 } 304 }
302 305
303 kfree(ins->code.data); 306 kfree(ins->code.data);
@@ -974,13 +977,11 @@ static struct dsp_scb_descriptor * _map_scb (struct snd_cs46xx *chip, char * nam
974 977
975 index = find_free_scb_index (ins); 978 index = find_free_scb_index (ins);
976 979
980 memset(&ins->scbs[index], 0, sizeof(ins->scbs[index]));
977 strcpy(ins->scbs[index].scb_name, name); 981 strcpy(ins->scbs[index].scb_name, name);
978 ins->scbs[index].address = dest; 982 ins->scbs[index].address = dest;
979 ins->scbs[index].index = index; 983 ins->scbs[index].index = index;
980 ins->scbs[index].proc_info = NULL;
981 ins->scbs[index].ref_count = 1; 984 ins->scbs[index].ref_count = 1;
982 ins->scbs[index].deleted = 0;
983 spin_lock_init(&ins->scbs[index].lock);
984 985
985 desc = (ins->scbs + index); 986 desc = (ins->scbs + index);
986 ins->scbs[index].scb_symbol = add_symbol (chip, name, dest, SYMBOL_PARAMETER); 987 ins->scbs[index].scb_symbol = add_symbol (chip, name, dest, SYMBOL_PARAMETER);
@@ -1022,17 +1023,29 @@ _map_task_tree (struct snd_cs46xx *chip, char * name, u32 dest, u32 size)
1022 return desc; 1023 return desc;
1023} 1024}
1024 1025
1026#define SCB_BYTES (0x10 * 4)
1027
1025struct dsp_scb_descriptor * 1028struct dsp_scb_descriptor *
1026cs46xx_dsp_create_scb (struct snd_cs46xx *chip, char * name, u32 * scb_data, u32 dest) 1029cs46xx_dsp_create_scb (struct snd_cs46xx *chip, char * name, u32 * scb_data, u32 dest)
1027{ 1030{
1028 struct dsp_scb_descriptor * desc; 1031 struct dsp_scb_descriptor * desc;
1029 1032
1033#ifdef CONFIG_PM
1034 /* copy the data for resume */
1035 scb_data = kmemdup(scb_data, SCB_BYTES, GFP_KERNEL);
1036 if (!scb_data)
1037 return NULL;
1038#endif
1039
1030 desc = _map_scb (chip,name,dest); 1040 desc = _map_scb (chip,name,dest);
1031 if (desc) { 1041 if (desc) {
1032 desc->data = scb_data; 1042 desc->data = scb_data;
1033 _dsp_create_scb(chip,scb_data,dest); 1043 _dsp_create_scb(chip,scb_data,dest);
1034 } else { 1044 } else {
1035 snd_printk(KERN_ERR "dsp_spos: failed to map SCB\n"); 1045 snd_printk(KERN_ERR "dsp_spos: failed to map SCB\n");
1046#ifdef CONFIG_PM
1047 kfree(scb_data);
1048#endif
1036 } 1049 }
1037 1050
1038 return desc; 1051 return desc;
@@ -1988,7 +2001,28 @@ int cs46xx_dsp_resume(struct snd_cs46xx * chip)
1988 continue; 2001 continue;
1989 _dsp_create_scb(chip, s->data, s->address); 2002 _dsp_create_scb(chip, s->data, s->address);
1990 } 2003 }
1991 2004 for (i = 0; i < ins->nscb; i++) {
2005 struct dsp_scb_descriptor *s = &ins->scbs[i];
2006 if (s->deleted)
2007 continue;
2008 if (s->updated)
2009 cs46xx_dsp_spos_update_scb(chip, s);
2010 if (s->volume_set)
2011 cs46xx_dsp_scb_set_volume(chip, s,
2012 s->volume[0], s->volume[1]);
2013 }
2014 if (ins->spdif_status_out & DSP_SPDIF_STATUS_HW_ENABLED) {
2015 cs46xx_dsp_enable_spdif_hw(chip);
2016 snd_cs46xx_poke(chip, (ins->ref_snoop_scb->address + 2) << 2,
2017 (OUTPUT_SNOOP_BUFFER + 0x10) << 0x10);
2018 if (ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN)
2019 cs46xx_poke_via_dsp(chip, SP_SPDOUT_CSUV,
2020 ins->spdif_csuv_stream);
2021 }
2022 if (chip->dsp_spos_instance->spdif_status_in) {
2023 cs46xx_poke_via_dsp(chip, SP_ASER_COUNTDOWN, 0x80000005);
2024 cs46xx_poke_via_dsp(chip, SP_SPDIN_CONTROL, 0x800003ff);
2025 }
1992 return 0; 2026 return 0;
1993} 2027}
1994#endif 2028#endif
diff --git a/sound/pci/cs46xx/dsp_spos.h b/sound/pci/cs46xx/dsp_spos.h
index f9e169d33c03..ca47a8114c7f 100644
--- a/sound/pci/cs46xx/dsp_spos.h
+++ b/sound/pci/cs46xx/dsp_spos.h
@@ -212,6 +212,7 @@ static inline void cs46xx_dsp_spos_update_scb (struct snd_cs46xx * chip,
212 (scb->address + SCBsubListPtr) << 2, 212 (scb->address + SCBsubListPtr) << 2,
213 (scb->sub_list_ptr->address << 0x10) | 213 (scb->sub_list_ptr->address << 0x10) |
214 (scb->next_scb_ptr->address)); 214 (scb->next_scb_ptr->address));
215 scb->updated = 1;
215} 216}
216 217
217static inline void cs46xx_dsp_scb_set_volume (struct snd_cs46xx * chip, 218static inline void cs46xx_dsp_scb_set_volume (struct snd_cs46xx * chip,
@@ -222,6 +223,9 @@ static inline void cs46xx_dsp_scb_set_volume (struct snd_cs46xx * chip,
222 223
223 snd_cs46xx_poke(chip, (scb->address + SCBVolumeCtrl) << 2, val); 224 snd_cs46xx_poke(chip, (scb->address + SCBVolumeCtrl) << 2, val);
224 snd_cs46xx_poke(chip, (scb->address + SCBVolumeCtrl + 1) << 2, val); 225 snd_cs46xx_poke(chip, (scb->address + SCBVolumeCtrl + 1) << 2, val);
226 scb->volume_set = 1;
227 scb->volume[0] = left;
228 scb->volume[1] = right;
225} 229}
226#endif /* __DSP_SPOS_H__ */ 230#endif /* __DSP_SPOS_H__ */
227#endif /* CONFIG_SND_CS46XX_NEW_DSP */ 231#endif /* CONFIG_SND_CS46XX_NEW_DSP */
diff --git a/sound/pci/cs46xx/dsp_spos_scb_lib.c b/sound/pci/cs46xx/dsp_spos_scb_lib.c
index dd7c41b037b4..00b148a10239 100644
--- a/sound/pci/cs46xx/dsp_spos_scb_lib.c
+++ b/sound/pci/cs46xx/dsp_spos_scb_lib.c
@@ -115,7 +115,6 @@ static void cs46xx_dsp_proc_scb_info_read (struct snd_info_entry *entry,
115static void _dsp_unlink_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor * scb) 115static void _dsp_unlink_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor * scb)
116{ 116{
117 struct dsp_spos_instance * ins = chip->dsp_spos_instance; 117 struct dsp_spos_instance * ins = chip->dsp_spos_instance;
118 unsigned long flags;
119 118
120 if ( scb->parent_scb_ptr ) { 119 if ( scb->parent_scb_ptr ) {
121 /* unlink parent SCB */ 120 /* unlink parent SCB */
@@ -153,8 +152,6 @@ static void _dsp_unlink_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor
153 scb->next_scb_ptr = ins->the_null_scb; 152 scb->next_scb_ptr = ins->the_null_scb;
154 } 153 }
155 154
156 spin_lock_irqsave(&chip->reg_lock, flags);
157
158 /* update parent first entry in DSP RAM */ 155 /* update parent first entry in DSP RAM */
159 cs46xx_dsp_spos_update_scb(chip,scb->parent_scb_ptr); 156 cs46xx_dsp_spos_update_scb(chip,scb->parent_scb_ptr);
160 157
@@ -162,7 +159,6 @@ static void _dsp_unlink_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor
162 cs46xx_dsp_spos_update_scb(chip,scb); 159 cs46xx_dsp_spos_update_scb(chip,scb);
163 160
164 scb->parent_scb_ptr = NULL; 161 scb->parent_scb_ptr = NULL;
165 spin_unlock_irqrestore(&chip->reg_lock, flags);
166 } 162 }
167} 163}
168 164
@@ -197,9 +193,9 @@ void cs46xx_dsp_remove_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor *
197 goto _end; 193 goto _end;
198#endif 194#endif
199 195
200 spin_lock_irqsave(&scb->lock, flags); 196 spin_lock_irqsave(&chip->reg_lock, flags);
201 _dsp_unlink_scb (chip,scb); 197 _dsp_unlink_scb (chip,scb);
202 spin_unlock_irqrestore(&scb->lock, flags); 198 spin_unlock_irqrestore(&chip->reg_lock, flags);
203 199
204 cs46xx_dsp_proc_free_scb_desc(scb); 200 cs46xx_dsp_proc_free_scb_desc(scb);
205 if (snd_BUG_ON(!scb->scb_symbol)) 201 if (snd_BUG_ON(!scb->scb_symbol))
@@ -207,6 +203,10 @@ void cs46xx_dsp_remove_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor *
207 remove_symbol (chip,scb->scb_symbol); 203 remove_symbol (chip,scb->scb_symbol);
208 204
209 ins->scbs[scb->index].deleted = 1; 205 ins->scbs[scb->index].deleted = 1;
206#ifdef CONFIG_PM
207 kfree(ins->scbs[scb->index].data);
208 ins->scbs[scb->index].data = NULL;
209#endif
210 210
211 if (scb->index < ins->scb_highest_frag_index) 211 if (scb->index < ins->scb_highest_frag_index)
212 ins->scb_highest_frag_index = scb->index; 212 ins->scb_highest_frag_index = scb->index;
@@ -1508,20 +1508,17 @@ int cs46xx_dsp_pcm_unlink (struct snd_cs46xx * chip,
1508 chip->dsp_spos_instance->npcm_channels <= 0)) 1508 chip->dsp_spos_instance->npcm_channels <= 0))
1509 return -EIO; 1509 return -EIO;
1510 1510
1511 spin_lock(&pcm_channel->src_scb->lock); 1511 spin_lock_irqsave(&chip->reg_lock, flags);
1512
1513 if (pcm_channel->unlinked) { 1512 if (pcm_channel->unlinked) {
1514 spin_unlock(&pcm_channel->src_scb->lock); 1513 spin_unlock_irqrestore(&chip->reg_lock, flags);
1515 return -EIO; 1514 return -EIO;
1516 } 1515 }
1517 1516
1518 spin_lock_irqsave(&chip->reg_lock, flags);
1519 pcm_channel->unlinked = 1; 1517 pcm_channel->unlinked = 1;
1520 spin_unlock_irqrestore(&chip->reg_lock, flags);
1521 1518
1522 _dsp_unlink_scb (chip,pcm_channel->pcm_reader_scb); 1519 _dsp_unlink_scb (chip,pcm_channel->pcm_reader_scb);
1520 spin_unlock_irqrestore(&chip->reg_lock, flags);
1523 1521
1524 spin_unlock(&pcm_channel->src_scb->lock);
1525 return 0; 1522 return 0;
1526} 1523}
1527 1524
@@ -1533,10 +1530,10 @@ int cs46xx_dsp_pcm_link (struct snd_cs46xx * chip,
1533 struct dsp_scb_descriptor * src_scb = pcm_channel->src_scb; 1530 struct dsp_scb_descriptor * src_scb = pcm_channel->src_scb;
1534 unsigned long flags; 1531 unsigned long flags;
1535 1532
1536 spin_lock(&pcm_channel->src_scb->lock); 1533 spin_lock_irqsave(&chip->reg_lock, flags);
1537 1534
1538 if (pcm_channel->unlinked == 0) { 1535 if (pcm_channel->unlinked == 0) {
1539 spin_unlock(&pcm_channel->src_scb->lock); 1536 spin_unlock_irqrestore(&chip->reg_lock, flags);
1540 return -EIO; 1537 return -EIO;
1541 } 1538 }
1542 1539
@@ -1552,8 +1549,6 @@ int cs46xx_dsp_pcm_link (struct snd_cs46xx * chip,
1552 snd_BUG_ON(pcm_channel->pcm_reader_scb->parent_scb_ptr); 1549 snd_BUG_ON(pcm_channel->pcm_reader_scb->parent_scb_ptr);
1553 pcm_channel->pcm_reader_scb->parent_scb_ptr = parent_scb; 1550 pcm_channel->pcm_reader_scb->parent_scb_ptr = parent_scb;
1554 1551
1555 spin_lock_irqsave(&chip->reg_lock, flags);
1556
1557 /* update SCB entry in DSP RAM */ 1552 /* update SCB entry in DSP RAM */
1558 cs46xx_dsp_spos_update_scb(chip,pcm_channel->pcm_reader_scb); 1553 cs46xx_dsp_spos_update_scb(chip,pcm_channel->pcm_reader_scb);
1559 1554
@@ -1562,8 +1557,6 @@ int cs46xx_dsp_pcm_link (struct snd_cs46xx * chip,
1562 1557
1563 pcm_channel->unlinked = 0; 1558 pcm_channel->unlinked = 0;
1564 spin_unlock_irqrestore(&chip->reg_lock, flags); 1559 spin_unlock_irqrestore(&chip->reg_lock, flags);
1565
1566 spin_unlock(&pcm_channel->src_scb->lock);
1567 return 0; 1560 return 0;
1568} 1561}
1569 1562
@@ -1596,13 +1589,17 @@ cs46xx_add_record_source (struct snd_cs46xx *chip, struct dsp_scb_descriptor * s
1596 1589
1597int cs46xx_src_unlink(struct snd_cs46xx *chip, struct dsp_scb_descriptor * src) 1590int cs46xx_src_unlink(struct snd_cs46xx *chip, struct dsp_scb_descriptor * src)
1598{ 1591{
1592 unsigned long flags;
1593
1599 if (snd_BUG_ON(!src->parent_scb_ptr)) 1594 if (snd_BUG_ON(!src->parent_scb_ptr))
1600 return -EINVAL; 1595 return -EINVAL;
1601 1596
1602 /* mute SCB */ 1597 /* mute SCB */
1603 cs46xx_dsp_scb_set_volume (chip,src,0,0); 1598 cs46xx_dsp_scb_set_volume (chip,src,0,0);
1604 1599
1600 spin_lock_irqsave(&chip->reg_lock, flags);
1605 _dsp_unlink_scb (chip,src); 1601 _dsp_unlink_scb (chip,src);
1602 spin_unlock_irqrestore(&chip->reg_lock, flags);
1606 1603
1607 return 0; 1604 return 0;
1608} 1605}
diff --git a/sound/pci/cs5530.c b/sound/pci/cs5530.c
index dc464321d0f3..207479a641cf 100644
--- a/sound/pci/cs5530.c
+++ b/sound/pci/cs5530.c
@@ -58,7 +58,7 @@ struct snd_cs5530 {
58 unsigned long pci_base; 58 unsigned long pci_base;
59}; 59};
60 60
61static struct pci_device_id snd_cs5530_ids[] = { 61static DEFINE_PCI_DEVICE_TABLE(snd_cs5530_ids) = {
62 {PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_AUDIO, PCI_ANY_ID, 62 {PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_AUDIO, PCI_ANY_ID,
63 PCI_ANY_ID, 0, 0}, 63 PCI_ANY_ID, 0, 0},
64 {0,} 64 {0,}
diff --git a/sound/pci/cs5535audio/cs5535audio.c b/sound/pci/cs5535audio/cs5535audio.c
index 91e7faf69bbb..afb803708416 100644
--- a/sound/pci/cs5535audio/cs5535audio.c
+++ b/sound/pci/cs5535audio/cs5535audio.c
@@ -66,7 +66,7 @@ MODULE_PARM_DESC(id, "ID string for " DRIVER_NAME);
66module_param_array(enable, bool, NULL, 0444); 66module_param_array(enable, bool, NULL, 0444);
67MODULE_PARM_DESC(enable, "Enable " DRIVER_NAME); 67MODULE_PARM_DESC(enable, "Enable " DRIVER_NAME);
68 68
69static struct pci_device_id snd_cs5535audio_ids[] = { 69static DEFINE_PCI_DEVICE_TABLE(snd_cs5535audio_ids) = {
70 { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_AUDIO) }, 70 { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_AUDIO) },
71 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_AUDIO) }, 71 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_AUDIO) },
72 {} 72 {}
diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c
index 459c1f62783b..480cb1e905b6 100644
--- a/sound/pci/ctxfi/ctatc.c
+++ b/sound/pci/ctxfi/ctatc.c
@@ -1214,10 +1214,11 @@ static int atc_dev_free(struct snd_device *dev)
1214 return ct_atc_destroy(atc); 1214 return ct_atc_destroy(atc);
1215} 1215}
1216 1216
1217static int __devinit atc_identify_card(struct ct_atc *atc) 1217static int __devinit atc_identify_card(struct ct_atc *atc, unsigned int ssid)
1218{ 1218{
1219 const struct snd_pci_quirk *p; 1219 const struct snd_pci_quirk *p;
1220 const struct snd_pci_quirk *list; 1220 const struct snd_pci_quirk *list;
1221 u16 vendor_id, device_id;
1221 1222
1222 switch (atc->chip_type) { 1223 switch (atc->chip_type) {
1223 case ATC20K1: 1224 case ATC20K1:
@@ -1231,13 +1232,19 @@ static int __devinit atc_identify_card(struct ct_atc *atc)
1231 default: 1232 default:
1232 return -ENOENT; 1233 return -ENOENT;
1233 } 1234 }
1234 p = snd_pci_quirk_lookup(atc->pci, list); 1235 if (ssid) {
1236 vendor_id = ssid >> 16;
1237 device_id = ssid & 0xffff;
1238 } else {
1239 vendor_id = atc->pci->subsystem_vendor;
1240 device_id = atc->pci->subsystem_device;
1241 }
1242 p = snd_pci_quirk_lookup_id(vendor_id, device_id, list);
1235 if (p) { 1243 if (p) {
1236 if (p->value < 0) { 1244 if (p->value < 0) {
1237 printk(KERN_ERR "ctxfi: " 1245 printk(KERN_ERR "ctxfi: "
1238 "Device %04x:%04x is black-listed\n", 1246 "Device %04x:%04x is black-listed\n",
1239 atc->pci->subsystem_vendor, 1247 vendor_id, device_id);
1240 atc->pci->subsystem_device);
1241 return -ENOENT; 1248 return -ENOENT;
1242 } 1249 }
1243 atc->model = p->value; 1250 atc->model = p->value;
@@ -1250,8 +1257,7 @@ static int __devinit atc_identify_card(struct ct_atc *atc)
1250 atc->model_name = ct_subsys_name[atc->model]; 1257 atc->model_name = ct_subsys_name[atc->model];
1251 snd_printd("ctxfi: chip %s model %s (%04x:%04x) is found\n", 1258 snd_printd("ctxfi: chip %s model %s (%04x:%04x) is found\n",
1252 atc->chip_name, atc->model_name, 1259 atc->chip_name, atc->model_name,
1253 atc->pci->subsystem_vendor, 1260 vendor_id, device_id);
1254 atc->pci->subsystem_device);
1255 return 0; 1261 return 0;
1256} 1262}
1257 1263
@@ -1625,7 +1631,8 @@ static struct ct_atc atc_preset __devinitdata = {
1625 1631
1626int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci, 1632int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci,
1627 unsigned int rsr, unsigned int msr, 1633 unsigned int rsr, unsigned int msr,
1628 int chip_type, struct ct_atc **ratc) 1634 int chip_type, unsigned int ssid,
1635 struct ct_atc **ratc)
1629{ 1636{
1630 struct ct_atc *atc; 1637 struct ct_atc *atc;
1631 static struct snd_device_ops ops = { 1638 static struct snd_device_ops ops = {
@@ -1651,7 +1658,7 @@ int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci,
1651 mutex_init(&atc->atc_mutex); 1658 mutex_init(&atc->atc_mutex);
1652 1659
1653 /* Find card model */ 1660 /* Find card model */
1654 err = atc_identify_card(atc); 1661 err = atc_identify_card(atc, ssid);
1655 if (err < 0) { 1662 if (err < 0) {
1656 printk(KERN_ERR "ctatc: Card not recognised\n"); 1663 printk(KERN_ERR "ctatc: Card not recognised\n");
1657 goto error1; 1664 goto error1;
diff --git a/sound/pci/ctxfi/ctatc.h b/sound/pci/ctxfi/ctatc.h
index 9fd8a5708943..7167c0185d52 100644
--- a/sound/pci/ctxfi/ctatc.h
+++ b/sound/pci/ctxfi/ctatc.h
@@ -148,7 +148,7 @@ struct ct_atc {
148 148
149int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci, 149int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci,
150 unsigned int rsr, unsigned int msr, int chip_type, 150 unsigned int rsr, unsigned int msr, int chip_type,
151 struct ct_atc **ratc); 151 unsigned int subsysid, struct ct_atc **ratc);
152int __devinit ct_atc_create_alsa_devs(struct ct_atc *atc); 152int __devinit ct_atc_create_alsa_devs(struct ct_atc *atc);
153 153
154#endif /* CTATC_H */ 154#endif /* CTATC_H */
diff --git a/sound/pci/ctxfi/xfi.c b/sound/pci/ctxfi/xfi.c
index 76541748e7bc..f42e7e1a1074 100644
--- a/sound/pci/ctxfi/xfi.c
+++ b/sound/pci/ctxfi/xfi.c
@@ -32,6 +32,7 @@ module_param(multiple, uint, S_IRUGO);
32static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; 32static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
33static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; 33static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
34static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; 34static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
35static unsigned int subsystem[SNDRV_CARDS];
35 36
36module_param_array(index, int, NULL, 0444); 37module_param_array(index, int, NULL, 0444);
37MODULE_PARM_DESC(index, "Index value for Creative X-Fi driver"); 38MODULE_PARM_DESC(index, "Index value for Creative X-Fi driver");
@@ -39,8 +40,10 @@ module_param_array(id, charp, NULL, 0444);
39MODULE_PARM_DESC(id, "ID string for Creative X-Fi driver"); 40MODULE_PARM_DESC(id, "ID string for Creative X-Fi driver");
40module_param_array(enable, bool, NULL, 0444); 41module_param_array(enable, bool, NULL, 0444);
41MODULE_PARM_DESC(enable, "Enable Creative X-Fi driver"); 42MODULE_PARM_DESC(enable, "Enable Creative X-Fi driver");
43module_param_array(subsystem, int, NULL, 0444);
44MODULE_PARM_DESC(subsystem, "Override subsystem ID for Creative X-Fi driver");
42 45
43static struct pci_device_id ct_pci_dev_ids[] = { 46static DEFINE_PCI_DEVICE_TABLE(ct_pci_dev_ids) = {
44 /* only X-Fi is supported, so... */ 47 /* only X-Fi is supported, so... */
45 { PCI_DEVICE(PCI_VENDOR_ID_CREATIVE, PCI_DEVICE_ID_CREATIVE_20K1), 48 { PCI_DEVICE(PCI_VENDOR_ID_CREATIVE, PCI_DEVICE_ID_CREATIVE_20K1),
46 .driver_data = ATC20K1, 49 .driver_data = ATC20K1,
@@ -85,7 +88,7 @@ ct_card_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
85 multiple = 2; 88 multiple = 2;
86 } 89 }
87 err = ct_atc_create(card, pci, reference_rate, multiple, 90 err = ct_atc_create(card, pci, reference_rate, multiple,
88 pci_id->driver_data, &atc); 91 pci_id->driver_data, subsystem[dev], &atc);
89 if (err < 0) 92 if (err < 0)
90 goto error; 93 goto error;
91 94
diff --git a/sound/pci/echoaudio/darla20.c b/sound/pci/echoaudio/darla20.c
index 8c6db3aa3c1a..a65bafe0800f 100644
--- a/sound/pci/echoaudio/darla20.c
+++ b/sound/pci/echoaudio/darla20.c
@@ -63,7 +63,7 @@ static const struct firmware card_fw[] = {
63 {0, "darla20_dsp.fw"} 63 {0, "darla20_dsp.fw"}
64}; 64};
65 65
66static struct pci_device_id snd_echo_ids[] = { 66static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
67 {0x1057, 0x1801, 0xECC0, 0x0010, 0, 0, 0}, /* DSP 56301 Darla20 rev.0 */ 67 {0x1057, 0x1801, 0xECC0, 0x0010, 0, 0, 0}, /* DSP 56301 Darla20 rev.0 */
68 {0,} 68 {0,}
69}; 69};
diff --git a/sound/pci/echoaudio/darla20_dsp.c b/sound/pci/echoaudio/darla20_dsp.c
index 29043301ebb8..20c7cbc89bb3 100644
--- a/sound/pci/echoaudio/darla20_dsp.c
+++ b/sound/pci/echoaudio/darla20_dsp.c
@@ -45,7 +45,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
45 chip->device_id = device_id; 45 chip->device_id = device_id;
46 chip->subdevice_id = subdevice_id; 46 chip->subdevice_id = subdevice_id;
47 chip->bad_board = TRUE; 47 chip->bad_board = TRUE;
48 chip->dsp_code_to_load = &card_fw[FW_DARLA20_DSP]; 48 chip->dsp_code_to_load = FW_DARLA20_DSP;
49 chip->spdif_status = GD_SPDIF_STATUS_UNDEF; 49 chip->spdif_status = GD_SPDIF_STATUS_UNDEF;
50 chip->clock_state = GD_CLOCK_UNDEF; 50 chip->clock_state = GD_CLOCK_UNDEF;
51 /* Since this card has no ASIC, mark it as loaded so everything 51 /* Since this card has no ASIC, mark it as loaded so everything
@@ -57,15 +57,19 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
57 return err; 57 return err;
58 chip->bad_board = FALSE; 58 chip->bad_board = FALSE;
59 59
60 if ((err = init_line_levels(chip)) < 0)
61 return err;
62
63 DE_INIT(("init_hw done\n")); 60 DE_INIT(("init_hw done\n"));
64 return err; 61 return err;
65} 62}
66 63
67 64
68 65
66static int set_mixer_defaults(struct echoaudio *chip)
67{
68 return init_line_levels(chip);
69}
70
71
72
69/* The Darla20 has no external clock sources */ 73/* The Darla20 has no external clock sources */
70static u32 detect_input_clocks(const struct echoaudio *chip) 74static u32 detect_input_clocks(const struct echoaudio *chip)
71{ 75{
diff --git a/sound/pci/echoaudio/darla24.c b/sound/pci/echoaudio/darla24.c
index 04cbf3eaf05a..0a6c50bcd758 100644
--- a/sound/pci/echoaudio/darla24.c
+++ b/sound/pci/echoaudio/darla24.c
@@ -67,7 +67,7 @@ static const struct firmware card_fw[] = {
67 {0, "darla24_dsp.fw"} 67 {0, "darla24_dsp.fw"}
68}; 68};
69 69
70static struct pci_device_id snd_echo_ids[] = { 70static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
71 {0x1057, 0x1801, 0xECC0, 0x0040, 0, 0, 0}, /* DSP 56301 Darla24 rev.0 */ 71 {0x1057, 0x1801, 0xECC0, 0x0040, 0, 0, 0}, /* DSP 56301 Darla24 rev.0 */
72 {0x1057, 0x1801, 0xECC0, 0x0041, 0, 0, 0}, /* DSP 56301 Darla24 rev.1 */ 72 {0x1057, 0x1801, 0xECC0, 0x0041, 0, 0, 0}, /* DSP 56301 Darla24 rev.1 */
73 {0,} 73 {0,}
diff --git a/sound/pci/echoaudio/darla24_dsp.c b/sound/pci/echoaudio/darla24_dsp.c
index 60228731841f..6da6663e9176 100644
--- a/sound/pci/echoaudio/darla24_dsp.c
+++ b/sound/pci/echoaudio/darla24_dsp.c
@@ -45,7 +45,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
45 chip->device_id = device_id; 45 chip->device_id = device_id;
46 chip->subdevice_id = subdevice_id; 46 chip->subdevice_id = subdevice_id;
47 chip->bad_board = TRUE; 47 chip->bad_board = TRUE;
48 chip->dsp_code_to_load = &card_fw[FW_DARLA24_DSP]; 48 chip->dsp_code_to_load = FW_DARLA24_DSP;
49 /* Since this card has no ASIC, mark it as loaded so everything 49 /* Since this card has no ASIC, mark it as loaded so everything
50 works OK */ 50 works OK */
51 chip->asic_loaded = TRUE; 51 chip->asic_loaded = TRUE;
@@ -56,15 +56,19 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
56 return err; 56 return err;
57 chip->bad_board = FALSE; 57 chip->bad_board = FALSE;
58 58
59 if ((err = init_line_levels(chip)) < 0)
60 return err;
61
62 DE_INIT(("init_hw done\n")); 59 DE_INIT(("init_hw done\n"));
63 return err; 60 return err;
64} 61}
65 62
66 63
67 64
65static int set_mixer_defaults(struct echoaudio *chip)
66{
67 return init_line_levels(chip);
68}
69
70
71
68static u32 detect_input_clocks(const struct echoaudio *chip) 72static u32 detect_input_clocks(const struct echoaudio *chip)
69{ 73{
70 u32 clocks_from_dsp, clock_bits; 74 u32 clocks_from_dsp, clock_bits;
diff --git a/sound/pci/echoaudio/echo3g.c b/sound/pci/echoaudio/echo3g.c
index 4022e43a0053..f5142796989b 100644
--- a/sound/pci/echoaudio/echo3g.c
+++ b/sound/pci/echoaudio/echo3g.c
@@ -81,7 +81,7 @@ static const struct firmware card_fw[] = {
81 {0, "3g_asic.fw"} 81 {0, "3g_asic.fw"}
82}; 82};
83 83
84static struct pci_device_id snd_echo_ids[] = { 84static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
85 {0x1057, 0x3410, 0xECC0, 0x0100, 0, 0, 0}, /* Echo 3G */ 85 {0x1057, 0x3410, 0xECC0, 0x0100, 0, 0, 0}, /* Echo 3G */
86 {0,} 86 {0,}
87}; 87};
diff --git a/sound/pci/echoaudio/echo3g_dsp.c b/sound/pci/echoaudio/echo3g_dsp.c
index 57967e580571..3cdc2ee2d1dd 100644
--- a/sound/pci/echoaudio/echo3g_dsp.c
+++ b/sound/pci/echoaudio/echo3g_dsp.c
@@ -61,7 +61,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
61 chip->subdevice_id = subdevice_id; 61 chip->subdevice_id = subdevice_id;
62 chip->bad_board = TRUE; 62 chip->bad_board = TRUE;
63 chip->has_midi = TRUE; 63 chip->has_midi = TRUE;
64 chip->dsp_code_to_load = &card_fw[FW_ECHO3G_DSP]; 64 chip->dsp_code_to_load = FW_ECHO3G_DSP;
65 65
66 /* Load the DSP code and the ASIC on the PCI card and get 66 /* Load the DSP code and the ASIC on the PCI card and get
67 what type of external box is attached */ 67 what type of external box is attached */
@@ -97,20 +97,6 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
97 chip->digital_modes = ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA | 97 chip->digital_modes = ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA |
98 ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL | 98 ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL |
99 ECHOCAPS_HAS_DIGITAL_MODE_ADAT; 99 ECHOCAPS_HAS_DIGITAL_MODE_ADAT;
100 chip->digital_mode = DIGITAL_MODE_SPDIF_RCA;
101 chip->professional_spdif = FALSE;
102 chip->non_audio_spdif = FALSE;
103 chip->bad_board = FALSE;
104
105 if ((err = init_line_levels(chip)) < 0)
106 return err;
107 err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA);
108 if (err < 0)
109 return err;
110 err = set_phantom_power(chip, 0);
111 if (err < 0)
112 return err;
113 err = set_professional_spdif(chip, TRUE);
114 100
115 DE_INIT(("init_hw done\n")); 101 DE_INIT(("init_hw done\n"));
116 return err; 102 return err;
@@ -118,6 +104,18 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
118 104
119 105
120 106
107static int set_mixer_defaults(struct echoaudio *chip)
108{
109 chip->digital_mode = DIGITAL_MODE_SPDIF_RCA;
110 chip->professional_spdif = FALSE;
111 chip->non_audio_spdif = FALSE;
112 chip->bad_board = FALSE;
113 chip->phantom_power = FALSE;
114 return init_line_levels(chip);
115}
116
117
118
121static int set_phantom_power(struct echoaudio *chip, char on) 119static int set_phantom_power(struct echoaudio *chip, char on)
122{ 120{
123 u32 control_reg = le32_to_cpu(chip->comm_page->control_register); 121 u32 control_reg = le32_to_cpu(chip->comm_page->control_register);
diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c
index 1305f7ca02c3..8dab82d7d19d 100644
--- a/sound/pci/echoaudio/echoaudio.c
+++ b/sound/pci/echoaudio/echoaudio.c
@@ -36,22 +36,61 @@ MODULE_PARM_DESC(enable, "Enable " ECHOCARD_NAME " soundcard.");
36static unsigned int channels_list[10] = {1, 2, 4, 6, 8, 10, 12, 14, 16, 999999}; 36static unsigned int channels_list[10] = {1, 2, 4, 6, 8, 10, 12, 14, 16, 999999};
37static const DECLARE_TLV_DB_SCALE(db_scale_output_gain, -12800, 100, 1); 37static const DECLARE_TLV_DB_SCALE(db_scale_output_gain, -12800, 100, 1);
38 38
39
40
39static int get_firmware(const struct firmware **fw_entry, 41static int get_firmware(const struct firmware **fw_entry,
40 const struct firmware *frm, struct echoaudio *chip) 42 struct echoaudio *chip, const short fw_index)
41{ 43{
42 int err; 44 int err;
43 char name[30]; 45 char name[30];
44 DE_ACT(("firmware requested: %s\n", frm->data)); 46
45 snprintf(name, sizeof(name), "ea/%s", frm->data); 47#ifdef CONFIG_PM
46 if ((err = request_firmware(fw_entry, name, pci_device(chip))) < 0) 48 if (chip->fw_cache[fw_index]) {
49 DE_ACT(("firmware requested: %s is cached\n", card_fw[fw_index].data));
50 *fw_entry = chip->fw_cache[fw_index];
51 return 0;
52 }
53#endif
54
55 DE_ACT(("firmware requested: %s\n", card_fw[fw_index].data));
56 snprintf(name, sizeof(name), "ea/%s", card_fw[fw_index].data);
57 err = request_firmware(fw_entry, name, pci_device(chip));
58 if (err < 0)
47 snd_printk(KERN_ERR "get_firmware(): Firmware not available (%d)\n", err); 59 snd_printk(KERN_ERR "get_firmware(): Firmware not available (%d)\n", err);
60#ifdef CONFIG_PM
61 else
62 chip->fw_cache[fw_index] = *fw_entry;
63#endif
48 return err; 64 return err;
49} 65}
50 66
67
68
51static void free_firmware(const struct firmware *fw_entry) 69static void free_firmware(const struct firmware *fw_entry)
52{ 70{
71#ifdef CONFIG_PM
72 DE_ACT(("firmware not released (kept in cache)\n"));
73#else
53 release_firmware(fw_entry); 74 release_firmware(fw_entry);
54 DE_ACT(("firmware released\n")); 75 DE_ACT(("firmware released\n"));
76#endif
77}
78
79
80
81static void free_firmware_cache(struct echoaudio *chip)
82{
83#ifdef CONFIG_PM
84 int i;
85
86 for (i = 0; i < 8 ; i++)
87 if (chip->fw_cache[i]) {
88 release_firmware(chip->fw_cache[i]);
89 DE_ACT(("release_firmware(%d)\n", i));
90 }
91
92 DE_ACT(("firmware_cache released\n"));
93#endif
55} 94}
56 95
57 96
@@ -714,6 +753,8 @@ static int pcm_trigger(struct snd_pcm_substream *substream, int cmd)
714 753
715 spin_lock(&chip->lock); 754 spin_lock(&chip->lock);
716 switch (cmd) { 755 switch (cmd) {
756 case SNDRV_PCM_TRIGGER_RESUME:
757 DE_ACT(("pcm_trigger resume\n"));
717 case SNDRV_PCM_TRIGGER_START: 758 case SNDRV_PCM_TRIGGER_START:
718 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 759 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
719 DE_ACT(("pcm_trigger start\n")); 760 DE_ACT(("pcm_trigger start\n"));
@@ -737,6 +778,8 @@ static int pcm_trigger(struct snd_pcm_substream *substream, int cmd)
737 err = start_transport(chip, channelmask, 778 err = start_transport(chip, channelmask,
738 chip->pipe_cyclic_mask); 779 chip->pipe_cyclic_mask);
739 break; 780 break;
781 case SNDRV_PCM_TRIGGER_SUSPEND:
782 DE_ACT(("pcm_trigger suspend\n"));
740 case SNDRV_PCM_TRIGGER_STOP: 783 case SNDRV_PCM_TRIGGER_STOP:
741 DE_ACT(("pcm_trigger stop\n")); 784 DE_ACT(("pcm_trigger stop\n"));
742 for (i = 0; i < DSP_MAXPIPES; i++) { 785 for (i = 0; i < DSP_MAXPIPES; i++) {
@@ -1821,7 +1864,9 @@ static irqreturn_t snd_echo_interrupt(int irq, void *dev_id)
1821 /* The hardware doesn't tell us which substream caused the irq, 1864 /* The hardware doesn't tell us which substream caused the irq,
1822 thus we have to check all running substreams. */ 1865 thus we have to check all running substreams. */
1823 for (ss = 0; ss < DSP_MAXPIPES; ss++) { 1866 for (ss = 0; ss < DSP_MAXPIPES; ss++) {
1824 if ((substream = chip->substream[ss])) { 1867 substream = chip->substream[ss];
1868 if (substream && ((struct audiopipe *)substream->runtime->
1869 private_data)->state == PIPE_STATE_STARTED) {
1825 period = pcm_pointer(substream) / 1870 period = pcm_pointer(substream) /
1826 substream->runtime->period_size; 1871 substream->runtime->period_size;
1827 if (period != chip->last_period[ss]) { 1872 if (period != chip->last_period[ss]) {
@@ -1874,6 +1919,7 @@ static int snd_echo_free(struct echoaudio *chip)
1874 pci_disable_device(chip->pci); 1919 pci_disable_device(chip->pci);
1875 1920
1876 /* release chip data */ 1921 /* release chip data */
1922 free_firmware_cache(chip);
1877 kfree(chip); 1923 kfree(chip);
1878 DE_INIT(("Chip freed.\n")); 1924 DE_INIT(("Chip freed.\n"));
1879 return 0; 1925 return 0;
@@ -1911,18 +1957,27 @@ static __devinit int snd_echo_create(struct snd_card *card,
1911 return err; 1957 return err;
1912 pci_set_master(pci); 1958 pci_set_master(pci);
1913 1959
1914 /* allocate a chip-specific data */ 1960 /* Allocate chip if needed */
1915 chip = kzalloc(sizeof(*chip), GFP_KERNEL); 1961 if (!*rchip) {
1916 if (!chip) { 1962 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
1917 pci_disable_device(pci); 1963 if (!chip) {
1918 return -ENOMEM; 1964 pci_disable_device(pci);
1965 return -ENOMEM;
1966 }
1967 DE_INIT(("chip=%p\n", chip));
1968 spin_lock_init(&chip->lock);
1969 chip->card = card;
1970 chip->pci = pci;
1971 chip->irq = -1;
1972 atomic_set(&chip->opencount, 0);
1973 mutex_init(&chip->mode_mutex);
1974 chip->can_set_rate = 1;
1975 } else {
1976 /* If this was called from the resume function, chip is
1977 * already allocated and it contains current card settings.
1978 */
1979 chip = *rchip;
1919 } 1980 }
1920 DE_INIT(("chip=%p\n", chip));
1921
1922 spin_lock_init(&chip->lock);
1923 chip->card = card;
1924 chip->pci = pci;
1925 chip->irq = -1;
1926 1981
1927 /* PCI resource allocation */ 1982 /* PCI resource allocation */
1928 chip->dsp_registers_phys = pci_resource_start(pci, 0); 1983 chip->dsp_registers_phys = pci_resource_start(pci, 0);
@@ -1962,7 +2017,9 @@ static __devinit int snd_echo_create(struct snd_card *card,
1962 chip->comm_page = (struct comm_page *)chip->commpage_dma_buf.area; 2017 chip->comm_page = (struct comm_page *)chip->commpage_dma_buf.area;
1963 2018
1964 err = init_hw(chip, chip->pci->device, chip->pci->subsystem_device); 2019 err = init_hw(chip, chip->pci->device, chip->pci->subsystem_device);
1965 if (err) { 2020 if (err >= 0)
2021 err = set_mixer_defaults(chip);
2022 if (err < 0) {
1966 DE_INIT(("init_hw err=%d\n", err)); 2023 DE_INIT(("init_hw err=%d\n", err));
1967 snd_echo_free(chip); 2024 snd_echo_free(chip);
1968 return err; 2025 return err;
@@ -1973,9 +2030,6 @@ static __devinit int snd_echo_create(struct snd_card *card,
1973 snd_echo_free(chip); 2030 snd_echo_free(chip);
1974 return err; 2031 return err;
1975 } 2032 }
1976 atomic_set(&chip->opencount, 0);
1977 mutex_init(&chip->mode_mutex);
1978 chip->can_set_rate = 1;
1979 *rchip = chip; 2033 *rchip = chip;
1980 /* Init done ! */ 2034 /* Init done ! */
1981 return 0; 2035 return 0;
@@ -2008,6 +2062,7 @@ static int __devinit snd_echo_probe(struct pci_dev *pci,
2008 2062
2009 snd_card_set_dev(card, &pci->dev); 2063 snd_card_set_dev(card, &pci->dev);
2010 2064
2065 chip = NULL; /* Tells snd_echo_create to allocate chip */
2011 if ((err = snd_echo_create(card, pci, &chip)) < 0) { 2066 if ((err = snd_echo_create(card, pci, &chip)) < 0) {
2012 snd_card_free(card); 2067 snd_card_free(card);
2013 return err; 2068 return err;
@@ -2147,6 +2202,112 @@ ctl_error:
2147 2202
2148 2203
2149 2204
2205#if defined(CONFIG_PM)
2206
2207static int snd_echo_suspend(struct pci_dev *pci, pm_message_t state)
2208{
2209 struct echoaudio *chip = pci_get_drvdata(pci);
2210
2211 DE_INIT(("suspend start\n"));
2212 snd_pcm_suspend_all(chip->analog_pcm);
2213 snd_pcm_suspend_all(chip->digital_pcm);
2214
2215#ifdef ECHOCARD_HAS_MIDI
2216 /* This call can sleep */
2217 if (chip->midi_out)
2218 snd_echo_midi_output_trigger(chip->midi_out, 0);
2219#endif
2220 spin_lock_irq(&chip->lock);
2221 if (wait_handshake(chip)) {
2222 spin_unlock_irq(&chip->lock);
2223 return -EIO;
2224 }
2225 clear_handshake(chip);
2226 if (send_vector(chip, DSP_VC_GO_COMATOSE) < 0) {
2227 spin_unlock_irq(&chip->lock);
2228 return -EIO;
2229 }
2230 spin_unlock_irq(&chip->lock);
2231
2232 chip->dsp_code = NULL;
2233 free_irq(chip->irq, chip);
2234 chip->irq = -1;
2235 pci_save_state(pci);
2236 pci_disable_device(pci);
2237
2238 DE_INIT(("suspend done\n"));
2239 return 0;
2240}
2241
2242
2243
2244static int snd_echo_resume(struct pci_dev *pci)
2245{
2246 struct echoaudio *chip = pci_get_drvdata(pci);
2247 struct comm_page *commpage, *commpage_bak;
2248 u32 pipe_alloc_mask;
2249 int err;
2250
2251 DE_INIT(("resume start\n"));
2252 pci_restore_state(pci);
2253 commpage_bak = kmalloc(sizeof(struct echoaudio), GFP_KERNEL);
2254 commpage = chip->comm_page;
2255 memcpy(commpage_bak, commpage, sizeof(struct comm_page));
2256
2257 err = init_hw(chip, chip->pci->device, chip->pci->subsystem_device);
2258 if (err < 0) {
2259 kfree(commpage_bak);
2260 DE_INIT(("resume init_hw err=%d\n", err));
2261 snd_echo_free(chip);
2262 return err;
2263 }
2264 DE_INIT(("resume init OK\n"));
2265
2266 /* Temporarily set chip->pipe_alloc_mask=0 otherwise
2267 * restore_dsp_settings() fails.
2268 */
2269 pipe_alloc_mask = chip->pipe_alloc_mask;
2270 chip->pipe_alloc_mask = 0;
2271 err = restore_dsp_rettings(chip);
2272 chip->pipe_alloc_mask = pipe_alloc_mask;
2273 if (err < 0) {
2274 kfree(commpage_bak);
2275 return err;
2276 }
2277 DE_INIT(("resume restore OK\n"));
2278
2279 memcpy(&commpage->audio_format, &commpage_bak->audio_format,
2280 sizeof(commpage->audio_format));
2281 memcpy(&commpage->sglist_addr, &commpage_bak->sglist_addr,
2282 sizeof(commpage->sglist_addr));
2283 memcpy(&commpage->midi_output, &commpage_bak->midi_output,
2284 sizeof(commpage->midi_output));
2285 kfree(commpage_bak);
2286
2287 if (request_irq(pci->irq, snd_echo_interrupt, IRQF_SHARED,
2288 ECHOCARD_NAME, chip)) {
2289 snd_echo_free(chip);
2290 snd_printk(KERN_ERR "cannot grab irq\n");
2291 return -EBUSY;
2292 }
2293 chip->irq = pci->irq;
2294 DE_INIT(("resume irq=%d\n", chip->irq));
2295
2296#ifdef ECHOCARD_HAS_MIDI
2297 if (chip->midi_input_enabled)
2298 enable_midi_input(chip, TRUE);
2299 if (chip->midi_out)
2300 snd_echo_midi_output_trigger(chip->midi_out, 1);
2301#endif
2302
2303 DE_INIT(("resume done\n"));
2304 return 0;
2305}
2306
2307#endif /* CONFIG_PM */
2308
2309
2310
2150static void __devexit snd_echo_remove(struct pci_dev *pci) 2311static void __devexit snd_echo_remove(struct pci_dev *pci)
2151{ 2312{
2152 struct echoaudio *chip; 2313 struct echoaudio *chip;
@@ -2169,6 +2330,10 @@ static struct pci_driver driver = {
2169 .id_table = snd_echo_ids, 2330 .id_table = snd_echo_ids,
2170 .probe = snd_echo_probe, 2331 .probe = snd_echo_probe,
2171 .remove = __devexit_p(snd_echo_remove), 2332 .remove = __devexit_p(snd_echo_remove),
2333#ifdef CONFIG_PM
2334 .suspend = snd_echo_suspend,
2335 .resume = snd_echo_resume,
2336#endif /* CONFIG_PM */
2172}; 2337};
2173 2338
2174 2339
diff --git a/sound/pci/echoaudio/echoaudio.h b/sound/pci/echoaudio/echoaudio.h
index f9490ae36c2e..1df974dcb5f4 100644
--- a/sound/pci/echoaudio/echoaudio.h
+++ b/sound/pci/echoaudio/echoaudio.h
@@ -442,13 +442,16 @@ struct echoaudio {
442 u16 device_id, subdevice_id; 442 u16 device_id, subdevice_id;
443 u16 *dsp_code; /* Current DSP code loaded, 443 u16 *dsp_code; /* Current DSP code loaded,
444 * NULL if nothing loaded */ 444 * NULL if nothing loaded */
445 const struct firmware *dsp_code_to_load;/* DSP code to load */ 445 short dsp_code_to_load; /* DSP code to load */
446 const struct firmware *asic_code; /* Current ASIC code */ 446 short asic_code; /* Current ASIC code */
447 u32 comm_page_phys; /* Physical address of the 447 u32 comm_page_phys; /* Physical address of the
448 * memory seen by DSP */ 448 * memory seen by DSP */
449 volatile u32 __iomem *dsp_registers; /* DSP's register base */ 449 volatile u32 __iomem *dsp_registers; /* DSP's register base */
450 u32 active_mask; /* Chs. active mask or 450 u32 active_mask; /* Chs. active mask or
451 * punks out */ 451 * punks out */
452#ifdef CONFIG_PM
453 const struct firmware *fw_cache[8]; /* Cached firmwares */
454#endif
452 455
453#ifdef ECHOCARD_HAS_MIDI 456#ifdef ECHOCARD_HAS_MIDI
454 u16 mtc_state; /* State for MIDI input parsing state machine */ 457 u16 mtc_state; /* State for MIDI input parsing state machine */
@@ -464,11 +467,13 @@ static int load_firmware(struct echoaudio *chip);
464static int wait_handshake(struct echoaudio *chip); 467static int wait_handshake(struct echoaudio *chip);
465static int send_vector(struct echoaudio *chip, u32 command); 468static int send_vector(struct echoaudio *chip, u32 command);
466static int get_firmware(const struct firmware **fw_entry, 469static int get_firmware(const struct firmware **fw_entry,
467 const struct firmware *frm, struct echoaudio *chip); 470 struct echoaudio *chip, const short fw_index);
468static void free_firmware(const struct firmware *fw_entry); 471static void free_firmware(const struct firmware *fw_entry);
469 472
470#ifdef ECHOCARD_HAS_MIDI 473#ifdef ECHOCARD_HAS_MIDI
471static int enable_midi_input(struct echoaudio *chip, char enable); 474static int enable_midi_input(struct echoaudio *chip, char enable);
475static void snd_echo_midi_output_trigger(
476 struct snd_rawmidi_substream *substream, int up);
472static int midi_service_irq(struct echoaudio *chip); 477static int midi_service_irq(struct echoaudio *chip);
473static int __devinit snd_echo_midi_create(struct snd_card *card, 478static int __devinit snd_echo_midi_create(struct snd_card *card,
474 struct echoaudio *chip); 479 struct echoaudio *chip);
diff --git a/sound/pci/echoaudio/echoaudio_3g.c b/sound/pci/echoaudio/echoaudio_3g.c
index e32a74897921..658db44ef746 100644
--- a/sound/pci/echoaudio/echoaudio_3g.c
+++ b/sound/pci/echoaudio/echoaudio_3g.c
@@ -227,12 +227,11 @@ static int load_asic(struct echoaudio *chip)
227 /* Give the DSP a few milliseconds to settle down */ 227 /* Give the DSP a few milliseconds to settle down */
228 mdelay(2); 228 mdelay(2);
229 229
230 err = load_asic_generic(chip, DSP_FNC_LOAD_3G_ASIC, 230 err = load_asic_generic(chip, DSP_FNC_LOAD_3G_ASIC, FW_3G_ASIC);
231 &card_fw[FW_3G_ASIC]);
232 if (err < 0) 231 if (err < 0)
233 return err; 232 return err;
234 233
235 chip->asic_code = &card_fw[FW_3G_ASIC]; 234 chip->asic_code = FW_3G_ASIC;
236 235
237 /* Now give the new ASIC some time to set up */ 236 /* Now give the new ASIC some time to set up */
238 msleep(1000); 237 msleep(1000);
diff --git a/sound/pci/echoaudio/echoaudio_dsp.c b/sound/pci/echoaudio/echoaudio_dsp.c
index 4df51ef5e095..64417a733220 100644
--- a/sound/pci/echoaudio/echoaudio_dsp.c
+++ b/sound/pci/echoaudio/echoaudio_dsp.c
@@ -175,15 +175,15 @@ static inline int check_asic_status(struct echoaudio *chip)
175#ifdef ECHOCARD_HAS_ASIC 175#ifdef ECHOCARD_HAS_ASIC
176 176
177/* Load ASIC code - done after the DSP is loaded */ 177/* Load ASIC code - done after the DSP is loaded */
178static int load_asic_generic(struct echoaudio *chip, u32 cmd, 178static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic)
179 const struct firmware *asic)
180{ 179{
181 const struct firmware *fw; 180 const struct firmware *fw;
182 int err; 181 int err;
183 u32 i, size; 182 u32 i, size;
184 u8 *code; 183 u8 *code;
185 184
186 if ((err = get_firmware(&fw, asic, chip)) < 0) { 185 err = get_firmware(&fw, chip, asic);
186 if (err < 0) {
187 snd_printk(KERN_WARNING "Firmware not found !\n"); 187 snd_printk(KERN_WARNING "Firmware not found !\n");
188 return err; 188 return err;
189 } 189 }
@@ -245,7 +245,8 @@ static int install_resident_loader(struct echoaudio *chip)
245 return 0; 245 return 0;
246 } 246 }
247 247
248 if ((i = get_firmware(&fw, &card_fw[FW_361_LOADER], chip)) < 0) { 248 i = get_firmware(&fw, chip, FW_361_LOADER);
249 if (i < 0) {
249 snd_printk(KERN_WARNING "Firmware not found !\n"); 250 snd_printk(KERN_WARNING "Firmware not found !\n");
250 return i; 251 return i;
251 } 252 }
@@ -485,7 +486,8 @@ static int load_firmware(struct echoaudio *chip)
485 chip->dsp_code = NULL; 486 chip->dsp_code = NULL;
486 } 487 }
487 488
488 if ((err = get_firmware(&fw, chip->dsp_code_to_load, chip)) < 0) 489 err = get_firmware(&fw, chip, chip->dsp_code_to_load);
490 if (err < 0)
489 return err; 491 return err;
490 err = load_dsp(chip, (u16 *)fw->data); 492 err = load_dsp(chip, (u16 *)fw->data);
491 free_firmware(fw); 493 free_firmware(fw);
@@ -495,9 +497,6 @@ static int load_firmware(struct echoaudio *chip)
495 if ((box_type = load_asic(chip)) < 0) 497 if ((box_type = load_asic(chip)) < 0)
496 return box_type; /* error */ 498 return box_type; /* error */
497 499
498 if ((err = restore_dsp_rettings(chip)) < 0)
499 return err;
500
501 return box_type; 500 return box_type;
502} 501}
503 502
@@ -657,51 +656,106 @@ static void get_audio_meters(struct echoaudio *chip, long *meters)
657 656
658static int restore_dsp_rettings(struct echoaudio *chip) 657static int restore_dsp_rettings(struct echoaudio *chip)
659{ 658{
660 int err; 659 int i, o, err;
661 DE_INIT(("restore_dsp_settings\n")); 660 DE_INIT(("restore_dsp_settings\n"));
662 661
663 if ((err = check_asic_status(chip)) < 0) 662 if ((err = check_asic_status(chip)) < 0)
664 return err; 663 return err;
665 664
666 /* @ Gina20/Darla20 only. Should be harmless for other cards. */ 665 /* Gina20/Darla20 only. Should be harmless for other cards. */
667 chip->comm_page->gd_clock_state = GD_CLOCK_UNDEF; 666 chip->comm_page->gd_clock_state = GD_CLOCK_UNDEF;
668 chip->comm_page->gd_spdif_status = GD_SPDIF_STATUS_UNDEF; 667 chip->comm_page->gd_spdif_status = GD_SPDIF_STATUS_UNDEF;
669 chip->comm_page->handshake = 0xffffffff; 668 chip->comm_page->handshake = 0xffffffff;
670 669
671 if ((err = set_sample_rate(chip, chip->sample_rate)) < 0) 670 /* Restore output busses */
671 for (i = 0; i < num_busses_out(chip); i++) {
672 err = set_output_gain(chip, i, chip->output_gain[i]);
673 if (err < 0)
674 return err;
675 }
676
677#ifdef ECHOCARD_HAS_VMIXER
678 for (i = 0; i < num_pipes_out(chip); i++)
679 for (o = 0; o < num_busses_out(chip); o++) {
680 err = set_vmixer_gain(chip, o, i,
681 chip->vmixer_gain[o][i]);
682 if (err < 0)
683 return err;
684 }
685 if (update_vmixer_level(chip) < 0)
686 return -EIO;
687#endif /* ECHOCARD_HAS_VMIXER */
688
689#ifdef ECHOCARD_HAS_MONITOR
690 for (o = 0; o < num_busses_out(chip); o++)
691 for (i = 0; i < num_busses_in(chip); i++) {
692 err = set_monitor_gain(chip, o, i,
693 chip->monitor_gain[o][i]);
694 if (err < 0)
695 return err;
696 }
697#endif /* ECHOCARD_HAS_MONITOR */
698
699#ifdef ECHOCARD_HAS_INPUT_GAIN
700 for (i = 0; i < num_busses_in(chip); i++) {
701 err = set_input_gain(chip, i, chip->input_gain[i]);
702 if (err < 0)
703 return err;
704 }
705#endif /* ECHOCARD_HAS_INPUT_GAIN */
706
707 err = update_output_line_level(chip);
708 if (err < 0)
672 return err; 709 return err;
673 710
674 if (chip->meters_enabled) 711 err = update_input_line_level(chip);
675 if (send_vector(chip, DSP_VC_METERS_ON) < 0) 712 if (err < 0)
676 return -EIO; 713 return err;
677 714
678#ifdef ECHOCARD_HAS_EXTERNAL_CLOCK 715 err = set_sample_rate(chip, chip->sample_rate);
679 if (set_input_clock(chip, chip->input_clock) < 0) 716 if (err < 0)
717 return err;
718
719 if (chip->meters_enabled) {
720 err = send_vector(chip, DSP_VC_METERS_ON);
721 if (err < 0)
722 return err;
723 }
724
725#ifdef ECHOCARD_HAS_DIGITAL_MODE_SWITCH
726 if (set_digital_mode(chip, chip->digital_mode) < 0)
680 return -EIO; 727 return -EIO;
681#endif 728#endif
682 729
683#ifdef ECHOCARD_HAS_OUTPUT_CLOCK_SWITCH 730#ifdef ECHOCARD_HAS_DIGITAL_IO
684 if (set_output_clock(chip, chip->output_clock) < 0) 731 if (set_professional_spdif(chip, chip->professional_spdif) < 0)
685 return -EIO; 732 return -EIO;
686#endif 733#endif
687 734
688 if (update_output_line_level(chip) < 0) 735#ifdef ECHOCARD_HAS_PHANTOM_POWER
736 if (set_phantom_power(chip, chip->phantom_power) < 0)
689 return -EIO; 737 return -EIO;
738#endif
690 739
691 if (update_input_line_level(chip) < 0) 740#ifdef ECHOCARD_HAS_EXTERNAL_CLOCK
741 /* set_input_clock() also restores automute setting */
742 if (set_input_clock(chip, chip->input_clock) < 0)
692 return -EIO; 743 return -EIO;
744#endif
693 745
694#ifdef ECHOCARD_HAS_VMIXER 746#ifdef ECHOCARD_HAS_OUTPUT_CLOCK_SWITCH
695 if (update_vmixer_level(chip) < 0) 747 if (set_output_clock(chip, chip->output_clock) < 0)
696 return -EIO; 748 return -EIO;
697#endif 749#endif
698 750
699 if (wait_handshake(chip) < 0) 751 if (wait_handshake(chip) < 0)
700 return -EIO; 752 return -EIO;
701 clear_handshake(chip); 753 clear_handshake(chip);
754 if (send_vector(chip, DSP_VC_UPDATE_FLAGS) < 0)
755 return -EIO;
702 756
703 DE_INIT(("restore_dsp_rettings done\n")); 757 DE_INIT(("restore_dsp_rettings done\n"));
704 return send_vector(chip, DSP_VC_UPDATE_FLAGS); 758 return 0;
705} 759}
706 760
707 761
@@ -918,9 +972,6 @@ static int init_dsp_comm_page(struct echoaudio *chip)
918 chip->card_name = ECHOCARD_NAME; 972 chip->card_name = ECHOCARD_NAME;
919 chip->bad_board = TRUE; /* Set TRUE until DSP loaded */ 973 chip->bad_board = TRUE; /* Set TRUE until DSP loaded */
920 chip->dsp_code = NULL; /* Current DSP code not loaded */ 974 chip->dsp_code = NULL; /* Current DSP code not loaded */
921 chip->digital_mode = DIGITAL_MODE_NONE;
922 chip->input_clock = ECHO_CLOCK_INTERNAL;
923 chip->output_clock = ECHO_CLOCK_WORD;
924 chip->asic_loaded = FALSE; 975 chip->asic_loaded = FALSE;
925 memset(chip->comm_page, 0, sizeof(struct comm_page)); 976 memset(chip->comm_page, 0, sizeof(struct comm_page));
926 977
@@ -931,7 +982,6 @@ static int init_dsp_comm_page(struct echoaudio *chip)
931 chip->comm_page->midi_out_free_count = 982 chip->comm_page->midi_out_free_count =
932 cpu_to_le32(DSP_MIDI_OUT_FIFO_SIZE); 983 cpu_to_le32(DSP_MIDI_OUT_FIFO_SIZE);
933 chip->comm_page->sample_rate = cpu_to_le32(44100); 984 chip->comm_page->sample_rate = cpu_to_le32(44100);
934 chip->sample_rate = 44100;
935 985
936 /* Set line levels so we don't blast any inputs on startup */ 986 /* Set line levels so we don't blast any inputs on startup */
937 memset(chip->comm_page->monitors, ECHOGAIN_MUTED, MONITOR_ARRAY_SIZE); 987 memset(chip->comm_page->monitors, ECHOGAIN_MUTED, MONITOR_ARRAY_SIZE);
@@ -942,50 +992,21 @@ static int init_dsp_comm_page(struct echoaudio *chip)
942 992
943 993
944 994
945/* This function initializes the several volume controls for busses and pipes. 995/* This function initializes the chip structure with default values, ie. all
946This MUST be called after the DSP is up and running ! */ 996 * muted and internal clock source. Then it copies the settings to the DSP.
997 * This MUST be called after the DSP is up and running !
998 */
947static int init_line_levels(struct echoaudio *chip) 999static int init_line_levels(struct echoaudio *chip)
948{ 1000{
949 int st, i, o;
950
951 DE_INIT(("init_line_levels\n")); 1001 DE_INIT(("init_line_levels\n"));
952 1002 memset(chip->output_gain, ECHOGAIN_MUTED, sizeof(chip->output_gain));
953 /* Mute output busses */ 1003 memset(chip->input_gain, ECHOGAIN_MUTED, sizeof(chip->input_gain));
954 for (i = 0; i < num_busses_out(chip); i++) 1004 memset(chip->monitor_gain, ECHOGAIN_MUTED, sizeof(chip->monitor_gain));
955 if ((st = set_output_gain(chip, i, ECHOGAIN_MUTED))) 1005 memset(chip->vmixer_gain, ECHOGAIN_MUTED, sizeof(chip->vmixer_gain));
956 return st; 1006 chip->input_clock = ECHO_CLOCK_INTERNAL;
957 if ((st = update_output_line_level(chip))) 1007 chip->output_clock = ECHO_CLOCK_WORD;
958 return st; 1008 chip->sample_rate = 44100;
959 1009 return restore_dsp_rettings(chip);
960#ifdef ECHOCARD_HAS_VMIXER
961 /* Mute the Vmixer */
962 for (i = 0; i < num_pipes_out(chip); i++)
963 for (o = 0; o < num_busses_out(chip); o++)
964 if ((st = set_vmixer_gain(chip, o, i, ECHOGAIN_MUTED)))
965 return st;
966 if ((st = update_vmixer_level(chip)))
967 return st;
968#endif /* ECHOCARD_HAS_VMIXER */
969
970#ifdef ECHOCARD_HAS_MONITOR
971 /* Mute the monitor mixer */
972 for (o = 0; o < num_busses_out(chip); o++)
973 for (i = 0; i < num_busses_in(chip); i++)
974 if ((st = set_monitor_gain(chip, o, i, ECHOGAIN_MUTED)))
975 return st;
976 if ((st = update_output_line_level(chip)))
977 return st;
978#endif /* ECHOCARD_HAS_MONITOR */
979
980#ifdef ECHOCARD_HAS_INPUT_GAIN
981 for (i = 0; i < num_busses_in(chip); i++)
982 if ((st = set_input_gain(chip, i, ECHOGAIN_MUTED)))
983 return st;
984 if ((st = update_input_line_level(chip)))
985 return st;
986#endif /* ECHOCARD_HAS_INPUT_GAIN */
987
988 return 0;
989} 1010}
990 1011
991 1012
diff --git a/sound/pci/echoaudio/gina20.c b/sound/pci/echoaudio/gina20.c
index c0e64b8f52a4..2364f8a1bc21 100644
--- a/sound/pci/echoaudio/gina20.c
+++ b/sound/pci/echoaudio/gina20.c
@@ -67,7 +67,7 @@ static const struct firmware card_fw[] = {
67 {0, "gina20_dsp.fw"} 67 {0, "gina20_dsp.fw"}
68}; 68};
69 69
70static struct pci_device_id snd_echo_ids[] = { 70static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
71 {0x1057, 0x1801, 0xECC0, 0x0020, 0, 0, 0}, /* DSP 56301 Gina20 rev.0 */ 71 {0x1057, 0x1801, 0xECC0, 0x0020, 0, 0, 0}, /* DSP 56301 Gina20 rev.0 */
72 {0,} 72 {0,}
73}; 73};
diff --git a/sound/pci/echoaudio/gina20_dsp.c b/sound/pci/echoaudio/gina20_dsp.c
index 3f1e7475faea..d1615a0579d1 100644
--- a/sound/pci/echoaudio/gina20_dsp.c
+++ b/sound/pci/echoaudio/gina20_dsp.c
@@ -49,7 +49,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
49 chip->device_id = device_id; 49 chip->device_id = device_id;
50 chip->subdevice_id = subdevice_id; 50 chip->subdevice_id = subdevice_id;
51 chip->bad_board = TRUE; 51 chip->bad_board = TRUE;
52 chip->dsp_code_to_load = &card_fw[FW_GINA20_DSP]; 52 chip->dsp_code_to_load = FW_GINA20_DSP;
53 chip->spdif_status = GD_SPDIF_STATUS_UNDEF; 53 chip->spdif_status = GD_SPDIF_STATUS_UNDEF;
54 chip->clock_state = GD_CLOCK_UNDEF; 54 chip->clock_state = GD_CLOCK_UNDEF;
55 /* Since this card has no ASIC, mark it as loaded so everything 55 /* Since this card has no ASIC, mark it as loaded so everything
@@ -62,17 +62,20 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
62 return err; 62 return err;
63 chip->bad_board = FALSE; 63 chip->bad_board = FALSE;
64 64
65 if ((err = init_line_levels(chip)) < 0)
66 return err;
67
68 err = set_professional_spdif(chip, TRUE);
69
70 DE_INIT(("init_hw done\n")); 65 DE_INIT(("init_hw done\n"));
71 return err; 66 return err;
72} 67}
73 68
74 69
75 70
71static int set_mixer_defaults(struct echoaudio *chip)
72{
73 chip->professional_spdif = FALSE;
74 return init_line_levels(chip);
75}
76
77
78
76static u32 detect_input_clocks(const struct echoaudio *chip) 79static u32 detect_input_clocks(const struct echoaudio *chip)
77{ 80{
78 u32 clocks_from_dsp, clock_bits; 81 u32 clocks_from_dsp, clock_bits;
diff --git a/sound/pci/echoaudio/gina24.c b/sound/pci/echoaudio/gina24.c
index c36a78dd0b5e..616b55825a19 100644
--- a/sound/pci/echoaudio/gina24.c
+++ b/sound/pci/echoaudio/gina24.c
@@ -85,7 +85,7 @@ static const struct firmware card_fw[] = {
85 {0, "gina24_361_asic.fw"} 85 {0, "gina24_361_asic.fw"}
86}; 86};
87 87
88static struct pci_device_id snd_echo_ids[] = { 88static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
89 {0x1057, 0x1801, 0xECC0, 0x0050, 0, 0, 0}, /* DSP 56301 Gina24 rev.0 */ 89 {0x1057, 0x1801, 0xECC0, 0x0050, 0, 0, 0}, /* DSP 56301 Gina24 rev.0 */
90 {0x1057, 0x1801, 0xECC0, 0x0051, 0, 0, 0}, /* DSP 56301 Gina24 rev.1 */ 90 {0x1057, 0x1801, 0xECC0, 0x0051, 0, 0, 0}, /* DSP 56301 Gina24 rev.1 */
91 {0x1057, 0x3410, 0xECC0, 0x0050, 0, 0, 0}, /* DSP 56361 Gina24 rev.0 */ 91 {0x1057, 0x3410, 0xECC0, 0x0050, 0, 0, 0}, /* DSP 56361 Gina24 rev.0 */
diff --git a/sound/pci/echoaudio/gina24_dsp.c b/sound/pci/echoaudio/gina24_dsp.c
index 2fef37a2a5b9..98f7cfa81b5f 100644
--- a/sound/pci/echoaudio/gina24_dsp.c
+++ b/sound/pci/echoaudio/gina24_dsp.c
@@ -33,8 +33,7 @@ static int write_control_reg(struct echoaudio *chip, u32 value, char force);
33static int set_input_clock(struct echoaudio *chip, u16 clock); 33static int set_input_clock(struct echoaudio *chip, u16 clock);
34static int set_professional_spdif(struct echoaudio *chip, char prof); 34static int set_professional_spdif(struct echoaudio *chip, char prof);
35static int set_digital_mode(struct echoaudio *chip, u8 mode); 35static int set_digital_mode(struct echoaudio *chip, u8 mode);
36static int load_asic_generic(struct echoaudio *chip, u32 cmd, 36static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic);
37 const struct firmware *asic);
38static int check_asic_status(struct echoaudio *chip); 37static int check_asic_status(struct echoaudio *chip);
39 38
40 39
@@ -58,19 +57,16 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
58 ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF | 57 ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF |
59 ECHO_CLOCK_BIT_ESYNC | ECHO_CLOCK_BIT_ESYNC96 | 58 ECHO_CLOCK_BIT_ESYNC | ECHO_CLOCK_BIT_ESYNC96 |
60 ECHO_CLOCK_BIT_ADAT; 59 ECHO_CLOCK_BIT_ADAT;
61 chip->professional_spdif = FALSE;
62 chip->digital_in_automute = TRUE;
63 chip->digital_mode = DIGITAL_MODE_SPDIF_RCA;
64 60
65 /* Gina24 comes in both '301 and '361 flavors */ 61 /* Gina24 comes in both '301 and '361 flavors */
66 if (chip->device_id == DEVICE_ID_56361) { 62 if (chip->device_id == DEVICE_ID_56361) {
67 chip->dsp_code_to_load = &card_fw[FW_GINA24_361_DSP]; 63 chip->dsp_code_to_load = FW_GINA24_361_DSP;
68 chip->digital_modes = 64 chip->digital_modes =
69 ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA | 65 ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA |
70 ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL | 66 ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL |
71 ECHOCAPS_HAS_DIGITAL_MODE_ADAT; 67 ECHOCAPS_HAS_DIGITAL_MODE_ADAT;
72 } else { 68 } else {
73 chip->dsp_code_to_load = &card_fw[FW_GINA24_301_DSP]; 69 chip->dsp_code_to_load = FW_GINA24_301_DSP;
74 chip->digital_modes = 70 chip->digital_modes =
75 ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA | 71 ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA |
76 ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL | 72 ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL |
@@ -82,19 +78,22 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
82 return err; 78 return err;
83 chip->bad_board = FALSE; 79 chip->bad_board = FALSE;
84 80
85 if ((err = init_line_levels(chip)) < 0)
86 return err;
87 err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA);
88 if (err < 0)
89 return err;
90 err = set_professional_spdif(chip, TRUE);
91
92 DE_INIT(("init_hw done\n")); 81 DE_INIT(("init_hw done\n"));
93 return err; 82 return err;
94} 83}
95 84
96 85
97 86
87static int set_mixer_defaults(struct echoaudio *chip)
88{
89 chip->digital_mode = DIGITAL_MODE_SPDIF_RCA;
90 chip->professional_spdif = FALSE;
91 chip->digital_in_automute = TRUE;
92 return init_line_levels(chip);
93}
94
95
96
98static u32 detect_input_clocks(const struct echoaudio *chip) 97static u32 detect_input_clocks(const struct echoaudio *chip)
99{ 98{
100 u32 clocks_from_dsp, clock_bits; 99 u32 clocks_from_dsp, clock_bits;
@@ -125,7 +124,7 @@ static int load_asic(struct echoaudio *chip)
125{ 124{
126 u32 control_reg; 125 u32 control_reg;
127 int err; 126 int err;
128 const struct firmware *fw; 127 short asic;
129 128
130 if (chip->asic_loaded) 129 if (chip->asic_loaded)
131 return 1; 130 return 1;
@@ -135,14 +134,15 @@ static int load_asic(struct echoaudio *chip)
135 134
136 /* Pick the correct ASIC for '301 or '361 Gina24 */ 135 /* Pick the correct ASIC for '301 or '361 Gina24 */
137 if (chip->device_id == DEVICE_ID_56361) 136 if (chip->device_id == DEVICE_ID_56361)
138 fw = &card_fw[FW_GINA24_361_ASIC]; 137 asic = FW_GINA24_361_ASIC;
139 else 138 else
140 fw = &card_fw[FW_GINA24_301_ASIC]; 139 asic = FW_GINA24_301_ASIC;
141 140
142 if ((err = load_asic_generic(chip, DSP_FNC_LOAD_GINA24_ASIC, fw)) < 0) 141 err = load_asic_generic(chip, DSP_FNC_LOAD_GINA24_ASIC, asic);
142 if (err < 0)
143 return err; 143 return err;
144 144
145 chip->asic_code = fw; 145 chip->asic_code = asic;
146 146
147 /* Now give the new ASIC a little time to set up */ 147 /* Now give the new ASIC a little time to set up */
148 mdelay(10); 148 mdelay(10);
diff --git a/sound/pci/echoaudio/indigo.c b/sound/pci/echoaudio/indigo.c
index 0a58a7c1fd7c..776175c0bdad 100644
--- a/sound/pci/echoaudio/indigo.c
+++ b/sound/pci/echoaudio/indigo.c
@@ -68,7 +68,7 @@ static const struct firmware card_fw[] = {
68 {0, "indigo_dsp.fw"} 68 {0, "indigo_dsp.fw"}
69}; 69};
70 70
71static struct pci_device_id snd_echo_ids[] = { 71static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
72 {0x1057, 0x3410, 0xECC0, 0x0090, 0, 0, 0}, /* Indigo */ 72 {0x1057, 0x3410, 0xECC0, 0x0090, 0, 0, 0}, /* Indigo */
73 {0,} 73 {0,}
74}; 74};
diff --git a/sound/pci/echoaudio/indigo_dsp.c b/sound/pci/echoaudio/indigo_dsp.c
index 0b2cd9c86277..5e85f14fe5a8 100644
--- a/sound/pci/echoaudio/indigo_dsp.c
+++ b/sound/pci/echoaudio/indigo_dsp.c
@@ -50,7 +50,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
50 chip->device_id = device_id; 50 chip->device_id = device_id;
51 chip->subdevice_id = subdevice_id; 51 chip->subdevice_id = subdevice_id;
52 chip->bad_board = TRUE; 52 chip->bad_board = TRUE;
53 chip->dsp_code_to_load = &card_fw[FW_INDIGO_DSP]; 53 chip->dsp_code_to_load = FW_INDIGO_DSP;
54 /* Since this card has no ASIC, mark it as loaded so everything 54 /* Since this card has no ASIC, mark it as loaded so everything
55 works OK */ 55 works OK */
56 chip->asic_loaded = TRUE; 56 chip->asic_loaded = TRUE;
@@ -60,15 +60,19 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
60 return err; 60 return err;
61 chip->bad_board = FALSE; 61 chip->bad_board = FALSE;
62 62
63 if ((err = init_line_levels(chip)) < 0)
64 return err;
65
66 DE_INIT(("init_hw done\n")); 63 DE_INIT(("init_hw done\n"));
67 return err; 64 return err;
68} 65}
69 66
70 67
71 68
69static int set_mixer_defaults(struct echoaudio *chip)
70{
71 return init_line_levels(chip);
72}
73
74
75
72static u32 detect_input_clocks(const struct echoaudio *chip) 76static u32 detect_input_clocks(const struct echoaudio *chip)
73{ 77{
74 return ECHO_CLOCK_BIT_INTERNAL; 78 return ECHO_CLOCK_BIT_INTERNAL;
diff --git a/sound/pci/echoaudio/indigo_express_dsp.c b/sound/pci/echoaudio/indigo_express_dsp.c
index 9ab625e15652..2e4ab3e34a74 100644
--- a/sound/pci/echoaudio/indigo_express_dsp.c
+++ b/sound/pci/echoaudio/indigo_express_dsp.c
@@ -61,6 +61,7 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate)
61 61
62 control_reg |= clock; 62 control_reg |= clock;
63 if (control_reg != old_control_reg) { 63 if (control_reg != old_control_reg) {
64 DE_ACT(("set_sample_rate: %d clock %d\n", rate, clock));
64 chip->comm_page->control_register = cpu_to_le32(control_reg); 65 chip->comm_page->control_register = cpu_to_le32(control_reg);
65 chip->sample_rate = rate; 66 chip->sample_rate = rate;
66 clear_handshake(chip); 67 clear_handshake(chip);
diff --git a/sound/pci/echoaudio/indigodj.c b/sound/pci/echoaudio/indigodj.c
index 2db24d29332b..8816b0bd2ba6 100644
--- a/sound/pci/echoaudio/indigodj.c
+++ b/sound/pci/echoaudio/indigodj.c
@@ -68,7 +68,7 @@ static const struct firmware card_fw[] = {
68 {0, "indigo_dj_dsp.fw"} 68 {0, "indigo_dj_dsp.fw"}
69}; 69};
70 70
71static struct pci_device_id snd_echo_ids[] = { 71static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
72 {0x1057, 0x3410, 0xECC0, 0x00B0, 0, 0, 0}, /* Indigo DJ*/ 72 {0x1057, 0x3410, 0xECC0, 0x00B0, 0, 0, 0}, /* Indigo DJ*/
73 {0,} 73 {0,}
74}; 74};
diff --git a/sound/pci/echoaudio/indigodj_dsp.c b/sound/pci/echoaudio/indigodj_dsp.c
index 08392916691e..68f3c8ccc1bf 100644
--- a/sound/pci/echoaudio/indigodj_dsp.c
+++ b/sound/pci/echoaudio/indigodj_dsp.c
@@ -50,7 +50,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
50 chip->device_id = device_id; 50 chip->device_id = device_id;
51 chip->subdevice_id = subdevice_id; 51 chip->subdevice_id = subdevice_id;
52 chip->bad_board = TRUE; 52 chip->bad_board = TRUE;
53 chip->dsp_code_to_load = &card_fw[FW_INDIGO_DJ_DSP]; 53 chip->dsp_code_to_load = FW_INDIGO_DJ_DSP;
54 /* Since this card has no ASIC, mark it as loaded so everything 54 /* Since this card has no ASIC, mark it as loaded so everything
55 works OK */ 55 works OK */
56 chip->asic_loaded = TRUE; 56 chip->asic_loaded = TRUE;
@@ -60,15 +60,19 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
60 return err; 60 return err;
61 chip->bad_board = FALSE; 61 chip->bad_board = FALSE;
62 62
63 if ((err = init_line_levels(chip)) < 0)
64 return err;
65
66 DE_INIT(("init_hw done\n")); 63 DE_INIT(("init_hw done\n"));
67 return err; 64 return err;
68} 65}
69 66
70 67
71 68
69static int set_mixer_defaults(struct echoaudio *chip)
70{
71 return init_line_levels(chip);
72}
73
74
75
72static u32 detect_input_clocks(const struct echoaudio *chip) 76static u32 detect_input_clocks(const struct echoaudio *chip)
73{ 77{
74 return ECHO_CLOCK_BIT_INTERNAL; 78 return ECHO_CLOCK_BIT_INTERNAL;
diff --git a/sound/pci/echoaudio/indigodjx.c b/sound/pci/echoaudio/indigodjx.c
index 2e44316530a2..b1e3652f2f48 100644
--- a/sound/pci/echoaudio/indigodjx.c
+++ b/sound/pci/echoaudio/indigodjx.c
@@ -68,7 +68,7 @@ static const struct firmware card_fw[] = {
68 {0, "indigo_djx_dsp.fw"} 68 {0, "indigo_djx_dsp.fw"}
69}; 69};
70 70
71static struct pci_device_id snd_echo_ids[] = { 71static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
72 {0x1057, 0x3410, 0xECC0, 0x00E0, 0, 0, 0}, /* Indigo DJx*/ 72 {0x1057, 0x3410, 0xECC0, 0x00E0, 0, 0, 0}, /* Indigo DJx*/
73 {0,} 73 {0,}
74}; 74};
diff --git a/sound/pci/echoaudio/indigodjx_dsp.c b/sound/pci/echoaudio/indigodjx_dsp.c
index f591fc2ed960..bb9632c752a9 100644
--- a/sound/pci/echoaudio/indigodjx_dsp.c
+++ b/sound/pci/echoaudio/indigodjx_dsp.c
@@ -48,7 +48,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
48 chip->device_id = device_id; 48 chip->device_id = device_id;
49 chip->subdevice_id = subdevice_id; 49 chip->subdevice_id = subdevice_id;
50 chip->bad_board = TRUE; 50 chip->bad_board = TRUE;
51 chip->dsp_code_to_load = &card_fw[FW_INDIGO_DJX_DSP]; 51 chip->dsp_code_to_load = FW_INDIGO_DJX_DSP;
52 /* Since this card has no ASIC, mark it as loaded so everything 52 /* Since this card has no ASIC, mark it as loaded so everything
53 works OK */ 53 works OK */
54 chip->asic_loaded = TRUE; 54 chip->asic_loaded = TRUE;
@@ -59,10 +59,13 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
59 return err; 59 return err;
60 chip->bad_board = FALSE; 60 chip->bad_board = FALSE;
61 61
62 err = init_line_levels(chip);
63 if (err < 0)
64 return err;
65
66 DE_INIT(("init_hw done\n")); 62 DE_INIT(("init_hw done\n"));
67 return err; 63 return err;
68} 64}
65
66
67
68static int set_mixer_defaults(struct echoaudio *chip)
69{
70 return init_line_levels(chip);
71}
diff --git a/sound/pci/echoaudio/indigoio.c b/sound/pci/echoaudio/indigoio.c
index a60c0a0a89b7..1035125336d6 100644
--- a/sound/pci/echoaudio/indigoio.c
+++ b/sound/pci/echoaudio/indigoio.c
@@ -69,7 +69,7 @@ static const struct firmware card_fw[] = {
69 {0, "indigo_io_dsp.fw"} 69 {0, "indigo_io_dsp.fw"}
70}; 70};
71 71
72static struct pci_device_id snd_echo_ids[] = { 72static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
73 {0x1057, 0x3410, 0xECC0, 0x00A0, 0, 0, 0}, /* Indigo IO*/ 73 {0x1057, 0x3410, 0xECC0, 0x00A0, 0, 0, 0}, /* Indigo IO*/
74 {0,} 74 {0,}
75}; 75};
diff --git a/sound/pci/echoaudio/indigoio_dsp.c b/sound/pci/echoaudio/indigoio_dsp.c
index 0604c8a85223..beb9a5b69892 100644
--- a/sound/pci/echoaudio/indigoio_dsp.c
+++ b/sound/pci/echoaudio/indigoio_dsp.c
@@ -50,7 +50,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
50 chip->device_id = device_id; 50 chip->device_id = device_id;
51 chip->subdevice_id = subdevice_id; 51 chip->subdevice_id = subdevice_id;
52 chip->bad_board = TRUE; 52 chip->bad_board = TRUE;
53 chip->dsp_code_to_load = &card_fw[FW_INDIGO_IO_DSP]; 53 chip->dsp_code_to_load = FW_INDIGO_IO_DSP;
54 /* Since this card has no ASIC, mark it as loaded so everything 54 /* Since this card has no ASIC, mark it as loaded so everything
55 works OK */ 55 works OK */
56 chip->asic_loaded = TRUE; 56 chip->asic_loaded = TRUE;
@@ -60,15 +60,19 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
60 return err; 60 return err;
61 chip->bad_board = FALSE; 61 chip->bad_board = FALSE;
62 62
63 if ((err = init_line_levels(chip)) < 0)
64 return err;
65
66 DE_INIT(("init_hw done\n")); 63 DE_INIT(("init_hw done\n"));
67 return err; 64 return err;
68} 65}
69 66
70 67
71 68
69static int set_mixer_defaults(struct echoaudio *chip)
70{
71 return init_line_levels(chip);
72}
73
74
75
72static u32 detect_input_clocks(const struct echoaudio *chip) 76static u32 detect_input_clocks(const struct echoaudio *chip)
73{ 77{
74 return ECHO_CLOCK_BIT_INTERNAL; 78 return ECHO_CLOCK_BIT_INTERNAL;
diff --git a/sound/pci/echoaudio/indigoiox.c b/sound/pci/echoaudio/indigoiox.c
index eb3819f9654a..60b7cb2753cf 100644
--- a/sound/pci/echoaudio/indigoiox.c
+++ b/sound/pci/echoaudio/indigoiox.c
@@ -69,7 +69,7 @@ static const struct firmware card_fw[] = {
69 {0, "indigo_iox_dsp.fw"} 69 {0, "indigo_iox_dsp.fw"}
70}; 70};
71 71
72static struct pci_device_id snd_echo_ids[] = { 72static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
73 {0x1057, 0x3410, 0xECC0, 0x00D0, 0, 0, 0}, /* Indigo IOx */ 73 {0x1057, 0x3410, 0xECC0, 0x00D0, 0, 0, 0}, /* Indigo IOx */
74 {0,} 74 {0,}
75}; 75};
diff --git a/sound/pci/echoaudio/indigoiox_dsp.c b/sound/pci/echoaudio/indigoiox_dsp.c
index f357521c79e6..394c6e76bcbc 100644
--- a/sound/pci/echoaudio/indigoiox_dsp.c
+++ b/sound/pci/echoaudio/indigoiox_dsp.c
@@ -48,7 +48,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
48 chip->device_id = device_id; 48 chip->device_id = device_id;
49 chip->subdevice_id = subdevice_id; 49 chip->subdevice_id = subdevice_id;
50 chip->bad_board = TRUE; 50 chip->bad_board = TRUE;
51 chip->dsp_code_to_load = &card_fw[FW_INDIGO_IOX_DSP]; 51 chip->dsp_code_to_load = FW_INDIGO_IOX_DSP;
52 /* Since this card has no ASIC, mark it as loaded so everything 52 /* Since this card has no ASIC, mark it as loaded so everything
53 works OK */ 53 works OK */
54 chip->asic_loaded = TRUE; 54 chip->asic_loaded = TRUE;
@@ -59,10 +59,13 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
59 return err; 59 return err;
60 chip->bad_board = FALSE; 60 chip->bad_board = FALSE;
61 61
62 err = init_line_levels(chip);
63 if (err < 0)
64 return err;
65
66 DE_INIT(("init_hw done\n")); 62 DE_INIT(("init_hw done\n"));
67 return err; 63 return err;
68} 64}
65
66
67
68static int set_mixer_defaults(struct echoaudio *chip)
69{
70 return init_line_levels(chip);
71}
diff --git a/sound/pci/echoaudio/layla20.c b/sound/pci/echoaudio/layla20.c
index 506194688995..8c3f5c5b5301 100644
--- a/sound/pci/echoaudio/layla20.c
+++ b/sound/pci/echoaudio/layla20.c
@@ -76,7 +76,7 @@ static const struct firmware card_fw[] = {
76 {0, "layla20_asic.fw"} 76 {0, "layla20_asic.fw"}
77}; 77};
78 78
79static struct pci_device_id snd_echo_ids[] = { 79static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
80 {0x1057, 0x1801, 0xECC0, 0x0030, 0, 0, 0}, /* DSP 56301 Layla20 rev.0 */ 80 {0x1057, 0x1801, 0xECC0, 0x0030, 0, 0, 0}, /* DSP 56301 Layla20 rev.0 */
81 {0x1057, 0x1801, 0xECC0, 0x0031, 0, 0, 0}, /* DSP 56301 Layla20 rev.1 */ 81 {0x1057, 0x1801, 0xECC0, 0x0031, 0, 0, 0}, /* DSP 56301 Layla20 rev.1 */
82 {0,} 82 {0,}
diff --git a/sound/pci/echoaudio/layla20_dsp.c b/sound/pci/echoaudio/layla20_dsp.c
index 83750e9fd7b4..53ce94605044 100644
--- a/sound/pci/echoaudio/layla20_dsp.c
+++ b/sound/pci/echoaudio/layla20_dsp.c
@@ -31,8 +31,7 @@
31 31
32static int read_dsp(struct echoaudio *chip, u32 *data); 32static int read_dsp(struct echoaudio *chip, u32 *data);
33static int set_professional_spdif(struct echoaudio *chip, char prof); 33static int set_professional_spdif(struct echoaudio *chip, char prof);
34static int load_asic_generic(struct echoaudio *chip, u32 cmd, 34static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic);
35 const struct firmware *asic);
36static int check_asic_status(struct echoaudio *chip); 35static int check_asic_status(struct echoaudio *chip);
37static int update_flags(struct echoaudio *chip); 36static int update_flags(struct echoaudio *chip);
38 37
@@ -54,7 +53,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
54 chip->subdevice_id = subdevice_id; 53 chip->subdevice_id = subdevice_id;
55 chip->bad_board = TRUE; 54 chip->bad_board = TRUE;
56 chip->has_midi = TRUE; 55 chip->has_midi = TRUE;
57 chip->dsp_code_to_load = &card_fw[FW_LAYLA20_DSP]; 56 chip->dsp_code_to_load = FW_LAYLA20_DSP;
58 chip->input_clock_types = 57 chip->input_clock_types =
59 ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF | 58 ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF |
60 ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_SUPER; 59 ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_SUPER;
@@ -65,17 +64,20 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
65 return err; 64 return err;
66 chip->bad_board = FALSE; 65 chip->bad_board = FALSE;
67 66
68 if ((err = init_line_levels(chip)) < 0)
69 return err;
70
71 err = set_professional_spdif(chip, TRUE);
72
73 DE_INIT(("init_hw done\n")); 67 DE_INIT(("init_hw done\n"));
74 return err; 68 return err;
75} 69}
76 70
77 71
78 72
73static int set_mixer_defaults(struct echoaudio *chip)
74{
75 chip->professional_spdif = FALSE;
76 return init_line_levels(chip);
77}
78
79
80
79static u32 detect_input_clocks(const struct echoaudio *chip) 81static u32 detect_input_clocks(const struct echoaudio *chip)
80{ 82{
81 u32 clocks_from_dsp, clock_bits; 83 u32 clocks_from_dsp, clock_bits;
@@ -144,7 +146,7 @@ static int load_asic(struct echoaudio *chip)
144 return 0; 146 return 0;
145 147
146 err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA_ASIC, 148 err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA_ASIC,
147 &card_fw[FW_LAYLA20_ASIC]); 149 FW_LAYLA20_ASIC);
148 if (err < 0) 150 if (err < 0)
149 return err; 151 return err;
150 152
diff --git a/sound/pci/echoaudio/layla24.c b/sound/pci/echoaudio/layla24.c
index e09e3ea7781e..ed1cc0abc2b8 100644
--- a/sound/pci/echoaudio/layla24.c
+++ b/sound/pci/echoaudio/layla24.c
@@ -87,7 +87,7 @@ static const struct firmware card_fw[] = {
87 {0, "layla24_2S_asic.fw"} 87 {0, "layla24_2S_asic.fw"}
88}; 88};
89 89
90static struct pci_device_id snd_echo_ids[] = { 90static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
91 {0x1057, 0x3410, 0xECC0, 0x0060, 0, 0, 0}, /* DSP 56361 Layla24 rev.0 */ 91 {0x1057, 0x3410, 0xECC0, 0x0060, 0, 0, 0}, /* DSP 56361 Layla24 rev.0 */
92 {0,} 92 {0,}
93}; 93};
diff --git a/sound/pci/echoaudio/layla24_dsp.c b/sound/pci/echoaudio/layla24_dsp.c
index d61b5cbcccad..8c041647f285 100644
--- a/sound/pci/echoaudio/layla24_dsp.c
+++ b/sound/pci/echoaudio/layla24_dsp.c
@@ -32,8 +32,7 @@ static int write_control_reg(struct echoaudio *chip, u32 value, char force);
32static int set_input_clock(struct echoaudio *chip, u16 clock); 32static int set_input_clock(struct echoaudio *chip, u16 clock);
33static int set_professional_spdif(struct echoaudio *chip, char prof); 33static int set_professional_spdif(struct echoaudio *chip, char prof);
34static int set_digital_mode(struct echoaudio *chip, u8 mode); 34static int set_digital_mode(struct echoaudio *chip, u8 mode);
35static int load_asic_generic(struct echoaudio *chip, u32 cmd, 35static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic);
36 const struct firmware *asic);
37static int check_asic_status(struct echoaudio *chip); 36static int check_asic_status(struct echoaudio *chip);
38 37
39 38
@@ -54,7 +53,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
54 chip->subdevice_id = subdevice_id; 53 chip->subdevice_id = subdevice_id;
55 chip->bad_board = TRUE; 54 chip->bad_board = TRUE;
56 chip->has_midi = TRUE; 55 chip->has_midi = TRUE;
57 chip->dsp_code_to_load = &card_fw[FW_LAYLA24_DSP]; 56 chip->dsp_code_to_load = FW_LAYLA24_DSP;
58 chip->input_clock_types = 57 chip->input_clock_types =
59 ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF | 58 ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF |
60 ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_ADAT; 59 ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_ADAT;
@@ -62,9 +61,6 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
62 ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA | 61 ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA |
63 ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL | 62 ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL |
64 ECHOCAPS_HAS_DIGITAL_MODE_ADAT; 63 ECHOCAPS_HAS_DIGITAL_MODE_ADAT;
65 chip->digital_mode = DIGITAL_MODE_SPDIF_RCA;
66 chip->professional_spdif = FALSE;
67 chip->digital_in_automute = TRUE;
68 64
69 if ((err = load_firmware(chip)) < 0) 65 if ((err = load_firmware(chip)) < 0)
70 return err; 66 return err;
@@ -73,17 +69,22 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
73 if ((err = init_line_levels(chip)) < 0) 69 if ((err = init_line_levels(chip)) < 0)
74 return err; 70 return err;
75 71
76 err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA);
77 if (err < 0)
78 return err;
79 err = set_professional_spdif(chip, TRUE);
80
81 DE_INIT(("init_hw done\n")); 72 DE_INIT(("init_hw done\n"));
82 return err; 73 return err;
83} 74}
84 75
85 76
86 77
78static int set_mixer_defaults(struct echoaudio *chip)
79{
80 chip->digital_mode = DIGITAL_MODE_SPDIF_RCA;
81 chip->professional_spdif = FALSE;
82 chip->digital_in_automute = TRUE;
83 return init_line_levels(chip);
84}
85
86
87
87static u32 detect_input_clocks(const struct echoaudio *chip) 88static u32 detect_input_clocks(const struct echoaudio *chip)
88{ 89{
89 u32 clocks_from_dsp, clock_bits; 90 u32 clocks_from_dsp, clock_bits;
@@ -123,18 +124,18 @@ static int load_asic(struct echoaudio *chip)
123 124
124 /* Load the ASIC for the PCI card */ 125 /* Load the ASIC for the PCI card */
125 err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA24_PCI_CARD_ASIC, 126 err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA24_PCI_CARD_ASIC,
126 &card_fw[FW_LAYLA24_1_ASIC]); 127 FW_LAYLA24_1_ASIC);
127 if (err < 0) 128 if (err < 0)
128 return err; 129 return err;
129 130
130 chip->asic_code = &card_fw[FW_LAYLA24_2S_ASIC]; 131 chip->asic_code = FW_LAYLA24_2S_ASIC;
131 132
132 /* Now give the new ASIC a little time to set up */ 133 /* Now give the new ASIC a little time to set up */
133 mdelay(10); 134 mdelay(10);
134 135
135 /* Do the external one */ 136 /* Do the external one */
136 err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA24_EXTERNAL_ASIC, 137 err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA24_EXTERNAL_ASIC,
137 &card_fw[FW_LAYLA24_2S_ASIC]); 138 FW_LAYLA24_2S_ASIC);
138 if (err < 0) 139 if (err < 0)
139 return FALSE; 140 return FALSE;
140 141
@@ -299,7 +300,7 @@ static int set_input_clock(struct echoaudio *chip, u16 clock)
299/* Depending on what digital mode you want, Layla24 needs different ASICs 300/* Depending on what digital mode you want, Layla24 needs different ASICs
300loaded. This function checks the ASIC needed for the new mode and sees 301loaded. This function checks the ASIC needed for the new mode and sees
301if it matches the one already loaded. */ 302if it matches the one already loaded. */
302static int switch_asic(struct echoaudio *chip, const struct firmware *asic) 303static int switch_asic(struct echoaudio *chip, short asic)
303{ 304{
304 s8 *monitors; 305 s8 *monitors;
305 306
@@ -335,7 +336,7 @@ static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode)
335{ 336{
336 u32 control_reg; 337 u32 control_reg;
337 int err, incompatible_clock; 338 int err, incompatible_clock;
338 const struct firmware *asic; 339 short asic;
339 340
340 /* Set clock to "internal" if it's not compatible with the new mode */ 341 /* Set clock to "internal" if it's not compatible with the new mode */
341 incompatible_clock = FALSE; 342 incompatible_clock = FALSE;
@@ -344,12 +345,12 @@ static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode)
344 case DIGITAL_MODE_SPDIF_RCA: 345 case DIGITAL_MODE_SPDIF_RCA:
345 if (chip->input_clock == ECHO_CLOCK_ADAT) 346 if (chip->input_clock == ECHO_CLOCK_ADAT)
346 incompatible_clock = TRUE; 347 incompatible_clock = TRUE;
347 asic = &card_fw[FW_LAYLA24_2S_ASIC]; 348 asic = FW_LAYLA24_2S_ASIC;
348 break; 349 break;
349 case DIGITAL_MODE_ADAT: 350 case DIGITAL_MODE_ADAT:
350 if (chip->input_clock == ECHO_CLOCK_SPDIF) 351 if (chip->input_clock == ECHO_CLOCK_SPDIF)
351 incompatible_clock = TRUE; 352 incompatible_clock = TRUE;
352 asic = &card_fw[FW_LAYLA24_2A_ASIC]; 353 asic = FW_LAYLA24_2A_ASIC;
353 break; 354 break;
354 default: 355 default:
355 DE_ACT(("Digital mode not supported: %d\n", mode)); 356 DE_ACT(("Digital mode not supported: %d\n", mode));
diff --git a/sound/pci/echoaudio/mia.c b/sound/pci/echoaudio/mia.c
index f05c8c097aa8..cc2bbfc65327 100644
--- a/sound/pci/echoaudio/mia.c
+++ b/sound/pci/echoaudio/mia.c
@@ -77,7 +77,7 @@ static const struct firmware card_fw[] = {
77 {0, "mia_dsp.fw"} 77 {0, "mia_dsp.fw"}
78}; 78};
79 79
80static struct pci_device_id snd_echo_ids[] = { 80static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
81 {0x1057, 0x3410, 0xECC0, 0x0080, 0, 0, 0}, /* DSP 56361 Mia rev.0 */ 81 {0x1057, 0x3410, 0xECC0, 0x0080, 0, 0, 0}, /* DSP 56361 Mia rev.0 */
82 {0x1057, 0x3410, 0xECC0, 0x0081, 0, 0, 0}, /* DSP 56361 Mia rev.1 */ 82 {0x1057, 0x3410, 0xECC0, 0x0081, 0, 0, 0}, /* DSP 56361 Mia rev.1 */
83 {0,} 83 {0,}
diff --git a/sound/pci/echoaudio/mia_dsp.c b/sound/pci/echoaudio/mia_dsp.c
index 551405114cbc..6ebfa6e7ab9e 100644
--- a/sound/pci/echoaudio/mia_dsp.c
+++ b/sound/pci/echoaudio/mia_dsp.c
@@ -53,7 +53,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
53 chip->device_id = device_id; 53 chip->device_id = device_id;
54 chip->subdevice_id = subdevice_id; 54 chip->subdevice_id = subdevice_id;
55 chip->bad_board = TRUE; 55 chip->bad_board = TRUE;
56 chip->dsp_code_to_load = &card_fw[FW_MIA_DSP]; 56 chip->dsp_code_to_load = FW_MIA_DSP;
57 /* Since this card has no ASIC, mark it as loaded so everything 57 /* Since this card has no ASIC, mark it as loaded so everything
58 works OK */ 58 works OK */
59 chip->asic_loaded = TRUE; 59 chip->asic_loaded = TRUE;
@@ -66,15 +66,19 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
66 return err; 66 return err;
67 chip->bad_board = FALSE; 67 chip->bad_board = FALSE;
68 68
69 if ((err = init_line_levels(chip)))
70 return err;
71
72 DE_INIT(("init_hw done\n")); 69 DE_INIT(("init_hw done\n"));
73 return err; 70 return err;
74} 71}
75 72
76 73
77 74
75static int set_mixer_defaults(struct echoaudio *chip)
76{
77 return init_line_levels(chip);
78}
79
80
81
78static u32 detect_input_clocks(const struct echoaudio *chip) 82static u32 detect_input_clocks(const struct echoaudio *chip)
79{ 83{
80 u32 clocks_from_dsp, clock_bits; 84 u32 clocks_from_dsp, clock_bits;
diff --git a/sound/pci/echoaudio/mona.c b/sound/pci/echoaudio/mona.c
index b05bad944901..3e7e01824b40 100644
--- a/sound/pci/echoaudio/mona.c
+++ b/sound/pci/echoaudio/mona.c
@@ -92,7 +92,7 @@ static const struct firmware card_fw[] = {
92 {0, "mona_2_asic.fw"} 92 {0, "mona_2_asic.fw"}
93}; 93};
94 94
95static struct pci_device_id snd_echo_ids[] = { 95static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
96 {0x1057, 0x1801, 0xECC0, 0x0070, 0, 0, 0}, /* DSP 56301 Mona rev.0 */ 96 {0x1057, 0x1801, 0xECC0, 0x0070, 0, 0, 0}, /* DSP 56301 Mona rev.0 */
97 {0x1057, 0x1801, 0xECC0, 0x0071, 0, 0, 0}, /* DSP 56301 Mona rev.1 */ 97 {0x1057, 0x1801, 0xECC0, 0x0071, 0, 0, 0}, /* DSP 56301 Mona rev.1 */
98 {0x1057, 0x1801, 0xECC0, 0x0072, 0, 0, 0}, /* DSP 56301 Mona rev.2 */ 98 {0x1057, 0x1801, 0xECC0, 0x0072, 0, 0, 0}, /* DSP 56301 Mona rev.2 */
diff --git a/sound/pci/echoaudio/mona_dsp.c b/sound/pci/echoaudio/mona_dsp.c
index eaa619bd2a03..6e6a7eb555b8 100644
--- a/sound/pci/echoaudio/mona_dsp.c
+++ b/sound/pci/echoaudio/mona_dsp.c
@@ -33,8 +33,7 @@ static int write_control_reg(struct echoaudio *chip, u32 value, char force);
33static int set_input_clock(struct echoaudio *chip, u16 clock); 33static int set_input_clock(struct echoaudio *chip, u16 clock);
34static int set_professional_spdif(struct echoaudio *chip, char prof); 34static int set_professional_spdif(struct echoaudio *chip, char prof);
35static int set_digital_mode(struct echoaudio *chip, u8 mode); 35static int set_digital_mode(struct echoaudio *chip, u8 mode);
36static int load_asic_generic(struct echoaudio *chip, u32 cmd, 36static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic);
37 const struct firmware *asic);
38static int check_asic_status(struct echoaudio *chip); 37static int check_asic_status(struct echoaudio *chip);
39 38
40 39
@@ -64,32 +63,30 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
64 63
65 /* Mona comes in both '301 and '361 flavors */ 64 /* Mona comes in both '301 and '361 flavors */
66 if (chip->device_id == DEVICE_ID_56361) 65 if (chip->device_id == DEVICE_ID_56361)
67 chip->dsp_code_to_load = &card_fw[FW_MONA_361_DSP]; 66 chip->dsp_code_to_load = FW_MONA_361_DSP;
68 else 67 else
69 chip->dsp_code_to_load = &card_fw[FW_MONA_301_DSP]; 68 chip->dsp_code_to_load = FW_MONA_301_DSP;
70
71 chip->digital_mode = DIGITAL_MODE_SPDIF_RCA;
72 chip->professional_spdif = FALSE;
73 chip->digital_in_automute = TRUE;
74 69
75 if ((err = load_firmware(chip)) < 0) 70 if ((err = load_firmware(chip)) < 0)
76 return err; 71 return err;
77 chip->bad_board = FALSE; 72 chip->bad_board = FALSE;
78 73
79 if ((err = init_line_levels(chip)) < 0)
80 return err;
81
82 err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA);
83 if (err < 0)
84 return err;
85 err = set_professional_spdif(chip, TRUE);
86
87 DE_INIT(("init_hw done\n")); 74 DE_INIT(("init_hw done\n"));
88 return err; 75 return err;
89} 76}
90 77
91 78
92 79
80static int set_mixer_defaults(struct echoaudio *chip)
81{
82 chip->digital_mode = DIGITAL_MODE_SPDIF_RCA;
83 chip->professional_spdif = FALSE;
84 chip->digital_in_automute = TRUE;
85 return init_line_levels(chip);
86}
87
88
89
93static u32 detect_input_clocks(const struct echoaudio *chip) 90static u32 detect_input_clocks(const struct echoaudio *chip)
94{ 91{
95 u32 clocks_from_dsp, clock_bits; 92 u32 clocks_from_dsp, clock_bits;
@@ -120,7 +117,7 @@ static int load_asic(struct echoaudio *chip)
120{ 117{
121 u32 control_reg; 118 u32 control_reg;
122 int err; 119 int err;
123 const struct firmware *asic; 120 short asic;
124 121
125 if (chip->asic_loaded) 122 if (chip->asic_loaded)
126 return 0; 123 return 0;
@@ -128,9 +125,9 @@ static int load_asic(struct echoaudio *chip)
128 mdelay(10); 125 mdelay(10);
129 126
130 if (chip->device_id == DEVICE_ID_56361) 127 if (chip->device_id == DEVICE_ID_56361)
131 asic = &card_fw[FW_MONA_361_1_ASIC48]; 128 asic = FW_MONA_361_1_ASIC48;
132 else 129 else
133 asic = &card_fw[FW_MONA_301_1_ASIC48]; 130 asic = FW_MONA_301_1_ASIC48;
134 131
135 err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_PCI_CARD_ASIC, asic); 132 err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_PCI_CARD_ASIC, asic);
136 if (err < 0) 133 if (err < 0)
@@ -141,7 +138,7 @@ static int load_asic(struct echoaudio *chip)
141 138
142 /* Do the external one */ 139 /* Do the external one */
143 err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_EXTERNAL_ASIC, 140 err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_EXTERNAL_ASIC,
144 &card_fw[FW_MONA_2_ASIC]); 141 FW_MONA_2_ASIC);
145 if (err < 0) 142 if (err < 0)
146 return err; 143 return err;
147 144
@@ -165,22 +162,22 @@ loaded. This function checks the ASIC needed for the new mode and sees
165if it matches the one already loaded. */ 162if it matches the one already loaded. */
166static int switch_asic(struct echoaudio *chip, char double_speed) 163static int switch_asic(struct echoaudio *chip, char double_speed)
167{ 164{
168 const struct firmware *asic;
169 int err; 165 int err;
166 short asic;
170 167
171 /* Check the clock detect bits to see if this is 168 /* Check the clock detect bits to see if this is
172 a single-speed clock or a double-speed clock; load 169 a single-speed clock or a double-speed clock; load
173 a new ASIC if necessary. */ 170 a new ASIC if necessary. */
174 if (chip->device_id == DEVICE_ID_56361) { 171 if (chip->device_id == DEVICE_ID_56361) {
175 if (double_speed) 172 if (double_speed)
176 asic = &card_fw[FW_MONA_361_1_ASIC96]; 173 asic = FW_MONA_361_1_ASIC96;
177 else 174 else
178 asic = &card_fw[FW_MONA_361_1_ASIC48]; 175 asic = FW_MONA_361_1_ASIC48;
179 } else { 176 } else {
180 if (double_speed) 177 if (double_speed)
181 asic = &card_fw[FW_MONA_301_1_ASIC96]; 178 asic = FW_MONA_301_1_ASIC96;
182 else 179 else
183 asic = &card_fw[FW_MONA_301_1_ASIC48]; 180 asic = FW_MONA_301_1_ASIC48;
184 } 181 }
185 182
186 if (asic != chip->asic_code) { 183 if (asic != chip->asic_code) {
@@ -200,7 +197,7 @@ static int switch_asic(struct echoaudio *chip, char double_speed)
200static int set_sample_rate(struct echoaudio *chip, u32 rate) 197static int set_sample_rate(struct echoaudio *chip, u32 rate)
201{ 198{
202 u32 control_reg, clock; 199 u32 control_reg, clock;
203 const struct firmware *asic; 200 short asic;
204 char force_write; 201 char force_write;
205 202
206 /* Only set the clock for internal mode. */ 203 /* Only set the clock for internal mode. */
@@ -218,14 +215,14 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate)
218 if (chip->digital_mode == DIGITAL_MODE_ADAT) 215 if (chip->digital_mode == DIGITAL_MODE_ADAT)
219 return -EINVAL; 216 return -EINVAL;
220 if (chip->device_id == DEVICE_ID_56361) 217 if (chip->device_id == DEVICE_ID_56361)
221 asic = &card_fw[FW_MONA_361_1_ASIC96]; 218 asic = FW_MONA_361_1_ASIC96;
222 else 219 else
223 asic = &card_fw[FW_MONA_301_1_ASIC96]; 220 asic = FW_MONA_301_1_ASIC96;
224 } else { 221 } else {
225 if (chip->device_id == DEVICE_ID_56361) 222 if (chip->device_id == DEVICE_ID_56361)
226 asic = &card_fw[FW_MONA_361_1_ASIC48]; 223 asic = FW_MONA_361_1_ASIC48;
227 else 224 else
228 asic = &card_fw[FW_MONA_301_1_ASIC48]; 225 asic = FW_MONA_301_1_ASIC48;
229 } 226 }
230 227
231 force_write = 0; 228 force_write = 0;
@@ -410,8 +407,8 @@ static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode)
410 case DIGITAL_MODE_ADAT: 407 case DIGITAL_MODE_ADAT:
411 /* If the current ASIC is the 96KHz ASIC, switch the ASIC 408 /* If the current ASIC is the 96KHz ASIC, switch the ASIC
412 and set to 48 KHz */ 409 and set to 48 KHz */
413 if (chip->asic_code == &card_fw[FW_MONA_361_1_ASIC96] || 410 if (chip->asic_code == FW_MONA_361_1_ASIC96 ||
414 chip->asic_code == &card_fw[FW_MONA_301_1_ASIC96]) { 411 chip->asic_code == FW_MONA_301_1_ASIC96) {
415 set_sample_rate(chip, 48000); 412 set_sample_rate(chip, 48000);
416 } 413 }
417 control_reg |= GML_ADAT_MODE; 414 control_reg |= GML_ADAT_MODE;
diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c
index 168af67d938e..4203782d7cb7 100644
--- a/sound/pci/emu10k1/emu10k1.c
+++ b/sound/pci/emu10k1/emu10k1.c
@@ -76,7 +76,7 @@ MODULE_PARM_DESC(subsystem, "Force card subsystem model.");
76/* 76/*
77 * Class 0401: 1102:0008 (rev 00) Subsystem: 1102:1001 -> Audigy2 Value Model:SB0400 77 * Class 0401: 1102:0008 (rev 00) Subsystem: 1102:1001 -> Audigy2 Value Model:SB0400
78 */ 78 */
79static struct pci_device_id snd_emu10k1_ids[] = { 79static DEFINE_PCI_DEVICE_TABLE(snd_emu10k1_ids) = {
80 { PCI_VDEVICE(CREATIVE, 0x0002), 0 }, /* EMU10K1 */ 80 { PCI_VDEVICE(CREATIVE, 0x0002), 0 }, /* EMU10K1 */
81 { PCI_VDEVICE(CREATIVE, 0x0004), 1 }, /* Audigy */ 81 { PCI_VDEVICE(CREATIVE, 0x0004), 1 }, /* Audigy */
82 { PCI_VDEVICE(CREATIVE, 0x0008), 1 }, /* Audigy 2 Value SB0400 */ 82 { PCI_VDEVICE(CREATIVE, 0x0008), 1 }, /* Audigy 2 Value SB0400 */
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c
index 1d369ff73805..df47f738098d 100644
--- a/sound/pci/emu10k1/emu10k1x.c
+++ b/sound/pci/emu10k1/emu10k1x.c
@@ -1605,7 +1605,7 @@ static void __devexit snd_emu10k1x_remove(struct pci_dev *pci)
1605} 1605}
1606 1606
1607// PCI IDs 1607// PCI IDs
1608static struct pci_device_id snd_emu10k1x_ids[] = { 1608static DEFINE_PCI_DEVICE_TABLE(snd_emu10k1x_ids) = {
1609 { PCI_VDEVICE(CREATIVE, 0x0006), 0 }, /* Dell OEM version (EMU10K1) */ 1609 { PCI_VDEVICE(CREATIVE, 0x0006), 0 }, /* Dell OEM version (EMU10K1) */
1610 { 0, } 1610 { 0, }
1611}; 1611};
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c
index 2b82c5c723e1..c7fba5379813 100644
--- a/sound/pci/ens1370.c
+++ b/sound/pci/ens1370.c
@@ -443,7 +443,7 @@ struct ensoniq {
443 443
444static irqreturn_t snd_audiopci_interrupt(int irq, void *dev_id); 444static irqreturn_t snd_audiopci_interrupt(int irq, void *dev_id);
445 445
446static struct pci_device_id snd_audiopci_ids[] = { 446static DEFINE_PCI_DEVICE_TABLE(snd_audiopci_ids) = {
447#ifdef CHIP1370 447#ifdef CHIP1370
448 { PCI_VDEVICE(ENSONIQ, 0x5000), 0, }, /* ES1370 */ 448 { PCI_VDEVICE(ENSONIQ, 0x5000), 0, }, /* ES1370 */
449#endif 449#endif
diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c
index fb83e1ffa5cb..553b75217259 100644
--- a/sound/pci/es1938.c
+++ b/sound/pci/es1938.c
@@ -243,7 +243,7 @@ struct es1938 {
243 243
244static irqreturn_t snd_es1938_interrupt(int irq, void *dev_id); 244static irqreturn_t snd_es1938_interrupt(int irq, void *dev_id);
245 245
246static struct pci_device_id snd_es1938_ids[] = { 246static DEFINE_PCI_DEVICE_TABLE(snd_es1938_ids) = {
247 { PCI_VDEVICE(ESS, 0x1969), 0, }, /* Solo-1 */ 247 { PCI_VDEVICE(ESS, 0x1969), 0, }, /* Solo-1 */
248 { 0, } 248 { 0, }
249}; 249};
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index a11f453a6b6d..ecaea9fb48ec 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -551,7 +551,7 @@ struct es1968 {
551 551
552static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id); 552static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id);
553 553
554static struct pci_device_id snd_es1968_ids[] = { 554static DEFINE_PCI_DEVICE_TABLE(snd_es1968_ids) = {
555 /* Maestro 1 */ 555 /* Maestro 1 */
556 { 0x1285, 0x0100, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, TYPE_MAESTRO }, 556 { 0x1285, 0x0100, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, TYPE_MAESTRO },
557 /* Maestro 2 */ 557 /* Maestro 2 */
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
index 83508b3964fb..e1baad74ea4b 100644
--- a/sound/pci/fm801.c
+++ b/sound/pci/fm801.c
@@ -205,7 +205,7 @@ struct fm801 {
205#endif 205#endif
206}; 206};
207 207
208static struct pci_device_id snd_fm801_ids[] = { 208static DEFINE_PCI_DEVICE_TABLE(snd_fm801_ids) = {
209 { 0x1319, 0x0801, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0, }, /* FM801 */ 209 { 0x1319, 0x0801, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0, }, /* FM801 */
210 { 0x5213, 0x0510, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0, }, /* Gallant Odyssey Sound 4 */ 210 { 0x5213, 0x0510, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0, }, /* Gallant Odyssey Sound 4 */
211 { 0, } 211 { 0, }
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index f98b47cd6cfb..76d3c4c049db 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -824,6 +824,9 @@ int snd_hda_add_pincfg(struct hda_codec *codec, struct snd_array *list,
824 struct hda_pincfg *pin; 824 struct hda_pincfg *pin;
825 unsigned int oldcfg; 825 unsigned int oldcfg;
826 826
827 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
828 return -EINVAL;
829
827 oldcfg = snd_hda_codec_get_pincfg(codec, nid); 830 oldcfg = snd_hda_codec_get_pincfg(codec, nid);
828 pin = look_up_pincfg(codec, list, nid); 831 pin = look_up_pincfg(codec, list, nid);
829 if (!pin) { 832 if (!pin) {
@@ -899,6 +902,25 @@ static void restore_pincfgs(struct hda_codec *codec)
899 } 902 }
900} 903}
901 904
905/**
906 * snd_hda_shutup_pins - Shut up all pins
907 * @codec: the HDA codec
908 *
909 * Clear all pin controls to shup up before suspend for avoiding click noise.
910 * The controls aren't cached so that they can be resumed properly.
911 */
912void snd_hda_shutup_pins(struct hda_codec *codec)
913{
914 int i;
915 for (i = 0; i < codec->init_pins.used; i++) {
916 struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i);
917 /* use read here for syncing after issuing each verb */
918 snd_hda_codec_read(codec, pin->nid, 0,
919 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
920 }
921}
922EXPORT_SYMBOL_HDA(snd_hda_shutup_pins);
923
902static void init_hda_cache(struct hda_cache_rec *cache, 924static void init_hda_cache(struct hda_cache_rec *cache,
903 unsigned int record_size); 925 unsigned int record_size);
904static void free_hda_cache(struct hda_cache_rec *cache); 926static void free_hda_cache(struct hda_cache_rec *cache);
@@ -931,6 +953,7 @@ static void snd_hda_codec_free(struct hda_codec *codec)
931#endif 953#endif
932 list_del(&codec->list); 954 list_del(&codec->list);
933 snd_array_free(&codec->mixers); 955 snd_array_free(&codec->mixers);
956 snd_array_free(&codec->nids);
934 codec->bus->caddr_tbl[codec->addr] = NULL; 957 codec->bus->caddr_tbl[codec->addr] = NULL;
935 if (codec->patch_ops.free) 958 if (codec->patch_ops.free)
936 codec->patch_ops.free(codec); 959 codec->patch_ops.free(codec);
@@ -985,7 +1008,8 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr
985 mutex_init(&codec->control_mutex); 1008 mutex_init(&codec->control_mutex);
986 init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info)); 1009 init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info));
987 init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head)); 1010 init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head));
988 snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 60); 1011 snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 32);
1012 snd_array_init(&codec->nids, sizeof(struct hda_nid_item), 32);
989 snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16); 1013 snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16);
990 snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16); 1014 snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16);
991 if (codec->bus->modelname) { 1015 if (codec->bus->modelname) {
@@ -1708,7 +1732,7 @@ struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec,
1708EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl); 1732EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl);
1709 1733
1710/** 1734/**
1711 * snd_hda_ctl-add - Add a control element and assign to the codec 1735 * snd_hda_ctl_add - Add a control element and assign to the codec
1712 * @codec: HD-audio codec 1736 * @codec: HD-audio codec
1713 * @nid: corresponding NID (optional) 1737 * @nid: corresponding NID (optional)
1714 * @kctl: the control element to assign 1738 * @kctl: the control element to assign
@@ -1723,19 +1747,25 @@ EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl);
1723 * 1747 *
1724 * snd_hda_ctl_add() checks the control subdev id field whether 1748 * snd_hda_ctl_add() checks the control subdev id field whether
1725 * #HDA_SUBDEV_NID_FLAG bit is set. If set (and @nid is zero), the lower 1749 * #HDA_SUBDEV_NID_FLAG bit is set. If set (and @nid is zero), the lower
1726 * bits value is taken as the NID to assign. 1750 * bits value is taken as the NID to assign. The #HDA_NID_ITEM_AMP bit
1751 * specifies if kctl->private_value is a HDA amplifier value.
1727 */ 1752 */
1728int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid, 1753int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid,
1729 struct snd_kcontrol *kctl) 1754 struct snd_kcontrol *kctl)
1730{ 1755{
1731 int err; 1756 int err;
1757 unsigned short flags = 0;
1732 struct hda_nid_item *item; 1758 struct hda_nid_item *item;
1733 1759
1734 if (kctl->id.subdevice & HDA_SUBDEV_NID_FLAG) { 1760 if (kctl->id.subdevice & HDA_SUBDEV_AMP_FLAG) {
1761 flags |= HDA_NID_ITEM_AMP;
1735 if (nid == 0) 1762 if (nid == 0)
1736 nid = kctl->id.subdevice & 0xffff; 1763 nid = get_amp_nid_(kctl->private_value);
1737 kctl->id.subdevice = 0;
1738 } 1764 }
1765 if ((kctl->id.subdevice & HDA_SUBDEV_NID_FLAG) != 0 && nid == 0)
1766 nid = kctl->id.subdevice & 0xffff;
1767 if (kctl->id.subdevice & (HDA_SUBDEV_NID_FLAG|HDA_SUBDEV_AMP_FLAG))
1768 kctl->id.subdevice = 0;
1739 err = snd_ctl_add(codec->bus->card, kctl); 1769 err = snd_ctl_add(codec->bus->card, kctl);
1740 if (err < 0) 1770 if (err < 0)
1741 return err; 1771 return err;
@@ -1744,11 +1774,41 @@ int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid,
1744 return -ENOMEM; 1774 return -ENOMEM;
1745 item->kctl = kctl; 1775 item->kctl = kctl;
1746 item->nid = nid; 1776 item->nid = nid;
1777 item->flags = flags;
1747 return 0; 1778 return 0;
1748} 1779}
1749EXPORT_SYMBOL_HDA(snd_hda_ctl_add); 1780EXPORT_SYMBOL_HDA(snd_hda_ctl_add);
1750 1781
1751/** 1782/**
1783 * snd_hda_add_nid - Assign a NID to a control element
1784 * @codec: HD-audio codec
1785 * @nid: corresponding NID (optional)
1786 * @kctl: the control element to assign
1787 * @index: index to kctl
1788 *
1789 * Add the given control element to an array inside the codec instance.
1790 * This function is used when #snd_hda_ctl_add cannot be used for 1:1
1791 * NID:KCTL mapping - for example "Capture Source" selector.
1792 */
1793int snd_hda_add_nid(struct hda_codec *codec, struct snd_kcontrol *kctl,
1794 unsigned int index, hda_nid_t nid)
1795{
1796 struct hda_nid_item *item;
1797
1798 if (nid > 0) {
1799 item = snd_array_new(&codec->nids);
1800 if (!item)
1801 return -ENOMEM;
1802 item->kctl = kctl;
1803 item->index = index;
1804 item->nid = nid;
1805 return 0;
1806 }
1807 return -EINVAL;
1808}
1809EXPORT_SYMBOL_HDA(snd_hda_add_nid);
1810
1811/**
1752 * snd_hda_ctls_clear - Clear all controls assigned to the given codec 1812 * snd_hda_ctls_clear - Clear all controls assigned to the given codec
1753 * @codec: HD-audio codec 1813 * @codec: HD-audio codec
1754 */ 1814 */
@@ -1759,6 +1819,7 @@ void snd_hda_ctls_clear(struct hda_codec *codec)
1759 for (i = 0; i < codec->mixers.used; i++) 1819 for (i = 0; i < codec->mixers.used; i++)
1760 snd_ctl_remove(codec->bus->card, items[i].kctl); 1820 snd_ctl_remove(codec->bus->card, items[i].kctl);
1761 snd_array_free(&codec->mixers); 1821 snd_array_free(&codec->mixers);
1822 snd_array_free(&codec->nids);
1762} 1823}
1763 1824
1764/* pseudo device locking 1825/* pseudo device locking
@@ -2706,7 +2767,8 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
2706 snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE, 2767 snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE,
2707 power_state); 2768 power_state);
2708 /* partial workaround for "azx_get_response timeout" */ 2769 /* partial workaround for "azx_get_response timeout" */
2709 if (power_state == AC_PWRST_D0) 2770 if (power_state == AC_PWRST_D0 &&
2771 (codec->vendor_id & 0xffff0000) == 0x14f10000)
2710 msleep(10); 2772 msleep(10);
2711 2773
2712 nid = codec->start_nid; 2774 nid = codec->start_nid;
@@ -2740,7 +2802,6 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
2740 if (power_state == AC_PWRST_D0) { 2802 if (power_state == AC_PWRST_D0) {
2741 unsigned long end_time; 2803 unsigned long end_time;
2742 int state; 2804 int state;
2743 msleep(10);
2744 /* wait until the codec reachs to D0 */ 2805 /* wait until the codec reachs to D0 */
2745 end_time = jiffies + msecs_to_jiffies(500); 2806 end_time = jiffies + msecs_to_jiffies(500);
2746 do { 2807 do {
@@ -3214,6 +3275,8 @@ const char *snd_hda_pcm_type_name[HDA_PCM_NTYPES] = {
3214 3275
3215/* 3276/*
3216 * get the empty PCM device number to assign 3277 * get the empty PCM device number to assign
3278 *
3279 * note the max device number is limited by HDA_MAX_PCMS, currently 10
3217 */ 3280 */
3218static int get_empty_pcm_device(struct hda_bus *bus, int type) 3281static int get_empty_pcm_device(struct hda_bus *bus, int type)
3219{ 3282{
@@ -3478,6 +3541,8 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew)
3478 3541
3479 for (; knew->name; knew++) { 3542 for (; knew->name; knew++) {
3480 struct snd_kcontrol *kctl; 3543 struct snd_kcontrol *kctl;
3544 if (knew->iface == -1) /* skip this codec private value */
3545 continue;
3481 kctl = snd_ctl_new1(knew, codec); 3546 kctl = snd_ctl_new1(knew, codec);
3482 if (!kctl) 3547 if (!kctl)
3483 return -ENOMEM; 3548 return -ENOMEM;
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 0a770a28e71f..b75da47571e6 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -527,6 +527,9 @@ enum {
527/* max. codec address */ 527/* max. codec address */
528#define HDA_MAX_CODEC_ADDRESS 0x0f 528#define HDA_MAX_CODEC_ADDRESS 0x0f
529 529
530/* max number of PCM devics per card */
531#define HDA_MAX_PCMS 10
532
530/* 533/*
531 * generic arrays 534 * generic arrays
532 */ 535 */
@@ -789,6 +792,7 @@ struct hda_codec {
789 u32 *wcaps; 792 u32 *wcaps;
790 793
791 struct snd_array mixers; /* list of assigned mixer elements */ 794 struct snd_array mixers; /* list of assigned mixer elements */
795 struct snd_array nids; /* list of mapped mixer elements */
792 796
793 struct hda_cache_rec amp_cache; /* cache for amp access */ 797 struct hda_cache_rec amp_cache; /* cache for amp access */
794 struct hda_cache_rec cmd_cache; /* cache for other commands */ 798 struct hda_cache_rec cmd_cache; /* cache for other commands */
@@ -898,6 +902,7 @@ int snd_hda_codec_set_pincfg(struct hda_codec *codec, hda_nid_t nid,
898 unsigned int cfg); 902 unsigned int cfg);
899int snd_hda_add_pincfg(struct hda_codec *codec, struct snd_array *list, 903int snd_hda_add_pincfg(struct hda_codec *codec, struct snd_array *list,
900 hda_nid_t nid, unsigned int cfg); /* for hwdep */ 904 hda_nid_t nid, unsigned int cfg); /* for hwdep */
905void snd_hda_shutup_pins(struct hda_codec *codec);
901 906
902/* 907/*
903 * Mixer 908 * Mixer
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index 092c6a7c2ff3..5ea21285ee1f 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -861,7 +861,8 @@ static int build_input_controls(struct hda_codec *codec)
861 } 861 }
862 862
863 /* create input MUX if multiple sources are available */ 863 /* create input MUX if multiple sources are available */
864 err = snd_hda_ctl_add(codec, 0, snd_ctl_new1(&cap_sel, codec)); 864 err = snd_hda_ctl_add(codec, spec->adc_node->nid,
865 snd_ctl_new1(&cap_sel, codec));
865 if (err < 0) 866 if (err < 0)
866 return err; 867 return err;
867 868
diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c
index 40ccb419b6e9..a1fc83753cc6 100644
--- a/sound/pci/hda/hda_hwdep.c
+++ b/sound/pci/hda/hda_hwdep.c
@@ -293,8 +293,11 @@ static ssize_t type##_store(struct device *dev, \
293{ \ 293{ \
294 struct snd_hwdep *hwdep = dev_get_drvdata(dev); \ 294 struct snd_hwdep *hwdep = dev_get_drvdata(dev); \
295 struct hda_codec *codec = hwdep->private_data; \ 295 struct hda_codec *codec = hwdep->private_data; \
296 char *after; \ 296 unsigned long val; \
297 codec->type = simple_strtoul(buf, &after, 0); \ 297 int err = strict_strtoul(buf, 0, &val); \
298 if (err < 0) \
299 return err; \
300 codec->type = val; \
298 return count; \ 301 return count; \
299} 302}
300 303
@@ -622,6 +625,10 @@ enum {
622 LINE_MODE_PINCFG, 625 LINE_MODE_PINCFG,
623 LINE_MODE_VERB, 626 LINE_MODE_VERB,
624 LINE_MODE_HINT, 627 LINE_MODE_HINT,
628 LINE_MODE_VENDOR_ID,
629 LINE_MODE_SUBSYSTEM_ID,
630 LINE_MODE_REVISION_ID,
631 LINE_MODE_CHIP_NAME,
625 NUM_LINE_MODES, 632 NUM_LINE_MODES,
626}; 633};
627 634
@@ -651,53 +658,71 @@ static void parse_codec_mode(char *buf, struct hda_bus *bus,
651} 658}
652 659
653/* parse the contents after the other command tags, [pincfg], [verb], 660/* parse the contents after the other command tags, [pincfg], [verb],
654 * [hint] and [model] 661 * [vendor_id], [subsystem_id], [revision_id], [chip_name], [hint] and [model]
655 * just pass to the sysfs helper (only when any codec was specified) 662 * just pass to the sysfs helper (only when any codec was specified)
656 */ 663 */
657static void parse_pincfg_mode(char *buf, struct hda_bus *bus, 664static void parse_pincfg_mode(char *buf, struct hda_bus *bus,
658 struct hda_codec **codecp) 665 struct hda_codec **codecp)
659{ 666{
660 if (!*codecp)
661 return;
662 parse_user_pin_configs(*codecp, buf); 667 parse_user_pin_configs(*codecp, buf);
663} 668}
664 669
665static void parse_verb_mode(char *buf, struct hda_bus *bus, 670static void parse_verb_mode(char *buf, struct hda_bus *bus,
666 struct hda_codec **codecp) 671 struct hda_codec **codecp)
667{ 672{
668 if (!*codecp)
669 return;
670 parse_init_verbs(*codecp, buf); 673 parse_init_verbs(*codecp, buf);
671} 674}
672 675
673static void parse_hint_mode(char *buf, struct hda_bus *bus, 676static void parse_hint_mode(char *buf, struct hda_bus *bus,
674 struct hda_codec **codecp) 677 struct hda_codec **codecp)
675{ 678{
676 if (!*codecp)
677 return;
678 parse_hints(*codecp, buf); 679 parse_hints(*codecp, buf);
679} 680}
680 681
681static void parse_model_mode(char *buf, struct hda_bus *bus, 682static void parse_model_mode(char *buf, struct hda_bus *bus,
682 struct hda_codec **codecp) 683 struct hda_codec **codecp)
683{ 684{
684 if (!*codecp)
685 return;
686 kfree((*codecp)->modelname); 685 kfree((*codecp)->modelname);
687 (*codecp)->modelname = kstrdup(buf, GFP_KERNEL); 686 (*codecp)->modelname = kstrdup(buf, GFP_KERNEL);
688} 687}
689 688
689static void parse_chip_name_mode(char *buf, struct hda_bus *bus,
690 struct hda_codec **codecp)
691{
692 kfree((*codecp)->chip_name);
693 (*codecp)->chip_name = kstrdup(buf, GFP_KERNEL);
694}
695
696#define DEFINE_PARSE_ID_MODE(name) \
697static void parse_##name##_mode(char *buf, struct hda_bus *bus, \
698 struct hda_codec **codecp) \
699{ \
700 unsigned long val; \
701 if (!strict_strtoul(buf, 0, &val)) \
702 (*codecp)->name = val; \
703}
704
705DEFINE_PARSE_ID_MODE(vendor_id);
706DEFINE_PARSE_ID_MODE(subsystem_id);
707DEFINE_PARSE_ID_MODE(revision_id);
708
709
690struct hda_patch_item { 710struct hda_patch_item {
691 const char *tag; 711 const char *tag;
692 void (*parser)(char *buf, struct hda_bus *bus, struct hda_codec **retc); 712 void (*parser)(char *buf, struct hda_bus *bus, struct hda_codec **retc);
713 int need_codec;
693}; 714};
694 715
695static struct hda_patch_item patch_items[NUM_LINE_MODES] = { 716static struct hda_patch_item patch_items[NUM_LINE_MODES] = {
696 [LINE_MODE_CODEC] = { "[codec]", parse_codec_mode }, 717 [LINE_MODE_CODEC] = { "[codec]", parse_codec_mode, 0 },
697 [LINE_MODE_MODEL] = { "[model]", parse_model_mode }, 718 [LINE_MODE_MODEL] = { "[model]", parse_model_mode, 1 },
698 [LINE_MODE_VERB] = { "[verb]", parse_verb_mode }, 719 [LINE_MODE_VERB] = { "[verb]", parse_verb_mode, 1 },
699 [LINE_MODE_PINCFG] = { "[pincfg]", parse_pincfg_mode }, 720 [LINE_MODE_PINCFG] = { "[pincfg]", parse_pincfg_mode, 1 },
700 [LINE_MODE_HINT] = { "[hint]", parse_hint_mode }, 721 [LINE_MODE_HINT] = { "[hint]", parse_hint_mode, 1 },
722 [LINE_MODE_VENDOR_ID] = { "[vendor_id]", parse_vendor_id_mode, 1 },
723 [LINE_MODE_SUBSYSTEM_ID] = { "[subsystem_id]", parse_subsystem_id_mode, 1 },
724 [LINE_MODE_REVISION_ID] = { "[revision_id]", parse_revision_id_mode, 1 },
725 [LINE_MODE_CHIP_NAME] = { "[chip_name]", parse_chip_name_mode, 1 },
701}; 726};
702 727
703/* check the line starting with '[' -- change the parser mode accodingly */ 728/* check the line starting with '[' -- change the parser mode accodingly */
@@ -780,7 +805,8 @@ int snd_hda_load_patch(struct hda_bus *bus, const char *patch)
780 continue; 805 continue;
781 if (*buf == '[') 806 if (*buf == '[')
782 line_mode = parse_line_mode(buf, bus); 807 line_mode = parse_line_mode(buf, bus);
783 else if (patch_items[line_mode].parser) 808 else if (patch_items[line_mode].parser &&
809 (codec || !patch_items[line_mode].need_codec))
784 patch_items[line_mode].parser(buf, bus, &codec); 810 patch_items[line_mode].parser(buf, bus, &codec);
785 } 811 }
786 release_firmware(fw); 812 release_firmware(fw);
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index ff6da6f386d1..d5c93ad852ee 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -125,6 +125,7 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
125 "{Intel, ICH9}," 125 "{Intel, ICH9},"
126 "{Intel, ICH10}," 126 "{Intel, ICH10},"
127 "{Intel, PCH}," 127 "{Intel, PCH},"
128 "{Intel, CPT},"
128 "{Intel, SCH}," 129 "{Intel, SCH},"
129 "{ATI, SB450}," 130 "{ATI, SB450},"
130 "{ATI, SB600}," 131 "{ATI, SB600},"
@@ -259,8 +260,6 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
259#define AZX_MAX_FRAG 32 260#define AZX_MAX_FRAG 32
260/* max buffer size - no h/w limit, you can increase as you like */ 261/* max buffer size - no h/w limit, you can increase as you like */
261#define AZX_MAX_BUF_SIZE (1024*1024*1024) 262#define AZX_MAX_BUF_SIZE (1024*1024*1024)
262/* max number of PCM devics per card */
263#define AZX_MAX_PCMS 8
264 263
265/* RIRB int mask: overrun[2], response[0] */ 264/* RIRB int mask: overrun[2], response[0] */
266#define RIRB_INT_RESPONSE 0x01 265#define RIRB_INT_RESPONSE 0x01
@@ -408,7 +407,7 @@ struct azx {
408 struct azx_dev *azx_dev; 407 struct azx_dev *azx_dev;
409 408
410 /* PCM */ 409 /* PCM */
411 struct snd_pcm *pcm[AZX_MAX_PCMS]; 410 struct snd_pcm *pcm[HDA_MAX_PCMS];
412 411
413 /* HD codec */ 412 /* HD codec */
414 unsigned short codec_mask; 413 unsigned short codec_mask;
@@ -449,6 +448,7 @@ struct azx {
449/* driver types */ 448/* driver types */
450enum { 449enum {
451 AZX_DRIVER_ICH, 450 AZX_DRIVER_ICH,
451 AZX_DRIVER_PCH,
452 AZX_DRIVER_SCH, 452 AZX_DRIVER_SCH,
453 AZX_DRIVER_ATI, 453 AZX_DRIVER_ATI,
454 AZX_DRIVER_ATIHDMI, 454 AZX_DRIVER_ATIHDMI,
@@ -463,6 +463,7 @@ enum {
463 463
464static char *driver_short_names[] __devinitdata = { 464static char *driver_short_names[] __devinitdata = {
465 [AZX_DRIVER_ICH] = "HDA Intel", 465 [AZX_DRIVER_ICH] = "HDA Intel",
466 [AZX_DRIVER_PCH] = "HDA Intel PCH",
466 [AZX_DRIVER_SCH] = "HDA Intel MID", 467 [AZX_DRIVER_SCH] = "HDA Intel MID",
467 [AZX_DRIVER_ATI] = "HDA ATI SB", 468 [AZX_DRIVER_ATI] = "HDA ATI SB",
468 [AZX_DRIVER_ATIHDMI] = "HDA ATI HDMI", 469 [AZX_DRIVER_ATIHDMI] = "HDA ATI HDMI",
@@ -968,8 +969,8 @@ static void azx_stream_start(struct azx *chip, struct azx_dev *azx_dev)
968 azx_dev->insufficient = 1; 969 azx_dev->insufficient = 1;
969 970
970 /* enable SIE */ 971 /* enable SIE */
971 azx_writeb(chip, INTCTL, 972 azx_writel(chip, INTCTL,
972 azx_readb(chip, INTCTL) | (1 << azx_dev->index)); 973 azx_readl(chip, INTCTL) | (1 << azx_dev->index));
973 /* set DMA start and interrupt mask */ 974 /* set DMA start and interrupt mask */
974 azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) | 975 azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) |
975 SD_CTL_DMA_START | SD_INT_MASK); 976 SD_CTL_DMA_START | SD_INT_MASK);
@@ -988,8 +989,8 @@ static void azx_stream_stop(struct azx *chip, struct azx_dev *azx_dev)
988{ 989{
989 azx_stream_clear(chip, azx_dev); 990 azx_stream_clear(chip, azx_dev);
990 /* disable SIE */ 991 /* disable SIE */
991 azx_writeb(chip, INTCTL, 992 azx_writel(chip, INTCTL,
992 azx_readb(chip, INTCTL) & ~(1 << azx_dev->index)); 993 azx_readl(chip, INTCTL) & ~(1 << azx_dev->index));
993} 994}
994 995
995 996
@@ -1065,6 +1066,7 @@ static void azx_init_pci(struct azx *chip)
1065 0x01, NVIDIA_HDA_ENABLE_COHBIT); 1066 0x01, NVIDIA_HDA_ENABLE_COHBIT);
1066 break; 1067 break;
1067 case AZX_DRIVER_SCH: 1068 case AZX_DRIVER_SCH:
1069 case AZX_DRIVER_PCH:
1068 pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop); 1070 pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop);
1069 if (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) { 1071 if (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) {
1070 pci_write_config_word(chip->pci, INTEL_SCH_HDA_DEVC, 1072 pci_write_config_word(chip->pci, INTEL_SCH_HDA_DEVC,
@@ -1350,7 +1352,7 @@ static void azx_bus_reset(struct hda_bus *bus)
1350 if (chip->initialized) { 1352 if (chip->initialized) {
1351 int i; 1353 int i;
1352 1354
1353 for (i = 0; i < AZX_MAX_PCMS; i++) 1355 for (i = 0; i < HDA_MAX_PCMS; i++)
1354 snd_pcm_suspend_all(chip->pcm[i]); 1356 snd_pcm_suspend_all(chip->pcm[i]);
1355 snd_hda_suspend(chip->bus); 1357 snd_hda_suspend(chip->bus);
1356 snd_hda_resume(chip->bus); 1358 snd_hda_resume(chip->bus);
@@ -1412,7 +1414,7 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model)
1412 chip->codec_mask &= ~(1 << c); 1414 chip->codec_mask &= ~(1 << c);
1413 /* More badly, accessing to a non-existing 1415 /* More badly, accessing to a non-existing
1414 * codec often screws up the controller chip, 1416 * codec often screws up the controller chip,
1415 * and distrubs the further communications. 1417 * and disturbs the further communications.
1416 * Thus if an error occurs during probing, 1418 * Thus if an error occurs during probing,
1417 * better to reset the controller chip to 1419 * better to reset the controller chip to
1418 * get back to the sanity state. 1420 * get back to the sanity state.
@@ -1983,7 +1985,7 @@ azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
1983 int pcm_dev = cpcm->device; 1985 int pcm_dev = cpcm->device;
1984 int s, err; 1986 int s, err;
1985 1987
1986 if (pcm_dev >= AZX_MAX_PCMS) { 1988 if (pcm_dev >= HDA_MAX_PCMS) {
1987 snd_printk(KERN_ERR SFX "Invalid PCM device number %d\n", 1989 snd_printk(KERN_ERR SFX "Invalid PCM device number %d\n",
1988 pcm_dev); 1990 pcm_dev);
1989 return -EINVAL; 1991 return -EINVAL;
@@ -2139,7 +2141,7 @@ static int azx_suspend(struct pci_dev *pci, pm_message_t state)
2139 2141
2140 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); 2142 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
2141 azx_clear_irq_pending(chip); 2143 azx_clear_irq_pending(chip);
2142 for (i = 0; i < AZX_MAX_PCMS; i++) 2144 for (i = 0; i < HDA_MAX_PCMS; i++)
2143 snd_pcm_suspend_all(chip->pcm[i]); 2145 snd_pcm_suspend_all(chip->pcm[i]);
2144 if (chip->initialized) 2146 if (chip->initialized)
2145 snd_hda_suspend(chip->bus); 2147 snd_hda_suspend(chip->bus);
@@ -2262,6 +2264,7 @@ static struct snd_pci_quirk position_fix_list[] __devinitdata = {
2262 SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB), 2264 SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB),
2263 SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB), 2265 SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB),
2264 SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB), 2266 SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB),
2267 SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB),
2265 SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB), 2268 SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB),
2266 SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB), 2269 SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB),
2267 {} 2270 {}
@@ -2418,6 +2421,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
2418 if (bdl_pos_adj[dev] < 0) { 2421 if (bdl_pos_adj[dev] < 0) {
2419 switch (chip->driver_type) { 2422 switch (chip->driver_type) {
2420 case AZX_DRIVER_ICH: 2423 case AZX_DRIVER_ICH:
2424 case AZX_DRIVER_PCH:
2421 bdl_pos_adj[dev] = 1; 2425 bdl_pos_adj[dev] = 1;
2422 break; 2426 break;
2423 default: 2427 default:
@@ -2683,7 +2687,7 @@ static void __devexit azx_remove(struct pci_dev *pci)
2683} 2687}
2684 2688
2685/* PCI IDs */ 2689/* PCI IDs */
2686static struct pci_device_id azx_ids[] = { 2690static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
2687 /* ICH 6..10 */ 2691 /* ICH 6..10 */
2688 { PCI_DEVICE(0x8086, 0x2668), .driver_data = AZX_DRIVER_ICH }, 2692 { PCI_DEVICE(0x8086, 0x2668), .driver_data = AZX_DRIVER_ICH },
2689 { PCI_DEVICE(0x8086, 0x27d8), .driver_data = AZX_DRIVER_ICH }, 2693 { PCI_DEVICE(0x8086, 0x27d8), .driver_data = AZX_DRIVER_ICH },
@@ -2696,6 +2700,8 @@ static struct pci_device_id azx_ids[] = {
2696 { PCI_DEVICE(0x8086, 0x3a6e), .driver_data = AZX_DRIVER_ICH }, 2700 { PCI_DEVICE(0x8086, 0x3a6e), .driver_data = AZX_DRIVER_ICH },
2697 /* PCH */ 2701 /* PCH */
2698 { PCI_DEVICE(0x8086, 0x3b56), .driver_data = AZX_DRIVER_ICH }, 2702 { PCI_DEVICE(0x8086, 0x3b56), .driver_data = AZX_DRIVER_ICH },
2703 /* CPT */
2704 { PCI_DEVICE(0x8086, 0x1c20), .driver_data = AZX_DRIVER_PCH },
2699 /* SCH */ 2705 /* SCH */
2700 { PCI_DEVICE(0x8086, 0x811b), .driver_data = AZX_DRIVER_SCH }, 2706 { PCI_DEVICE(0x8086, 0x811b), .driver_data = AZX_DRIVER_SCH },
2701 /* ATI SB 450/600 */ 2707 /* ATI SB 450/600 */
@@ -2723,32 +2729,10 @@ static struct pci_device_id azx_ids[] = {
2723 /* ULI M5461 */ 2729 /* ULI M5461 */
2724 { PCI_DEVICE(0x10b9, 0x5461), .driver_data = AZX_DRIVER_ULI }, 2730 { PCI_DEVICE(0x10b9, 0x5461), .driver_data = AZX_DRIVER_ULI },
2725 /* NVIDIA MCP */ 2731 /* NVIDIA MCP */
2726 { PCI_DEVICE(0x10de, 0x026c), .driver_data = AZX_DRIVER_NVIDIA }, 2732 { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID),
2727 { PCI_DEVICE(0x10de, 0x0371), .driver_data = AZX_DRIVER_NVIDIA }, 2733 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
2728 { PCI_DEVICE(0x10de, 0x03e4), .driver_data = AZX_DRIVER_NVIDIA }, 2734 .class_mask = 0xffffff,
2729 { PCI_DEVICE(0x10de, 0x03f0), .driver_data = AZX_DRIVER_NVIDIA }, 2735 .driver_data = AZX_DRIVER_NVIDIA },
2730 { PCI_DEVICE(0x10de, 0x044a), .driver_data = AZX_DRIVER_NVIDIA },
2731 { PCI_DEVICE(0x10de, 0x044b), .driver_data = AZX_DRIVER_NVIDIA },
2732 { PCI_DEVICE(0x10de, 0x055c), .driver_data = AZX_DRIVER_NVIDIA },
2733 { PCI_DEVICE(0x10de, 0x055d), .driver_data = AZX_DRIVER_NVIDIA },
2734 { PCI_DEVICE(0x10de, 0x0590), .driver_data = AZX_DRIVER_NVIDIA },
2735 { PCI_DEVICE(0x10de, 0x0774), .driver_data = AZX_DRIVER_NVIDIA },
2736 { PCI_DEVICE(0x10de, 0x0775), .driver_data = AZX_DRIVER_NVIDIA },
2737 { PCI_DEVICE(0x10de, 0x0776), .driver_data = AZX_DRIVER_NVIDIA },
2738 { PCI_DEVICE(0x10de, 0x0777), .driver_data = AZX_DRIVER_NVIDIA },
2739 { PCI_DEVICE(0x10de, 0x07fc), .driver_data = AZX_DRIVER_NVIDIA },
2740 { PCI_DEVICE(0x10de, 0x07fd), .driver_data = AZX_DRIVER_NVIDIA },
2741 { PCI_DEVICE(0x10de, 0x0ac0), .driver_data = AZX_DRIVER_NVIDIA },
2742 { PCI_DEVICE(0x10de, 0x0ac1), .driver_data = AZX_DRIVER_NVIDIA },
2743 { PCI_DEVICE(0x10de, 0x0ac2), .driver_data = AZX_DRIVER_NVIDIA },
2744 { PCI_DEVICE(0x10de, 0x0ac3), .driver_data = AZX_DRIVER_NVIDIA },
2745 { PCI_DEVICE(0x10de, 0x0be2), .driver_data = AZX_DRIVER_NVIDIA },
2746 { PCI_DEVICE(0x10de, 0x0be3), .driver_data = AZX_DRIVER_NVIDIA },
2747 { PCI_DEVICE(0x10de, 0x0be4), .driver_data = AZX_DRIVER_NVIDIA },
2748 { PCI_DEVICE(0x10de, 0x0d94), .driver_data = AZX_DRIVER_NVIDIA },
2749 { PCI_DEVICE(0x10de, 0x0d95), .driver_data = AZX_DRIVER_NVIDIA },
2750 { PCI_DEVICE(0x10de, 0x0d96), .driver_data = AZX_DRIVER_NVIDIA },
2751 { PCI_DEVICE(0x10de, 0x0d97), .driver_data = AZX_DRIVER_NVIDIA },
2752 /* Teradici */ 2736 /* Teradici */
2753 { PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA }, 2737 { PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA },
2754 /* Creative X-Fi (CA0110-IBG) */ 2738 /* Creative X-Fi (CA0110-IBG) */
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 5778ae882b83..7cee364976ff 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -31,6 +31,7 @@
31 * in snd_hda_ctl_add(), so that this value won't appear in the outside. 31 * in snd_hda_ctl_add(), so that this value won't appear in the outside.
32 */ 32 */
33#define HDA_SUBDEV_NID_FLAG (1U << 31) 33#define HDA_SUBDEV_NID_FLAG (1U << 31)
34#define HDA_SUBDEV_AMP_FLAG (1U << 30)
34 35
35/* 36/*
36 * for mixer controls 37 * for mixer controls
@@ -42,7 +43,7 @@
42/* mono volume with index (index=0,1,...) (channel=1,2) */ 43/* mono volume with index (index=0,1,...) (channel=1,2) */
43#define HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \ 44#define HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \
44 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ 45 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \
45 .subdevice = HDA_SUBDEV_NID_FLAG | (nid), \ 46 .subdevice = HDA_SUBDEV_AMP_FLAG, \
46 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \ 47 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
47 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ 48 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
48 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, \ 49 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, \
@@ -63,7 +64,7 @@
63/* mono mute switch with index (index=0,1,...) (channel=1,2) */ 64/* mono mute switch with index (index=0,1,...) (channel=1,2) */
64#define HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \ 65#define HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \
65 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ 66 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \
66 .subdevice = HDA_SUBDEV_NID_FLAG | (nid), \ 67 .subdevice = HDA_SUBDEV_AMP_FLAG, \
67 .info = snd_hda_mixer_amp_switch_info, \ 68 .info = snd_hda_mixer_amp_switch_info, \
68 .get = snd_hda_mixer_amp_switch_get, \ 69 .get = snd_hda_mixer_amp_switch_get, \
69 .put = snd_hda_mixer_amp_switch_put, \ 70 .put = snd_hda_mixer_amp_switch_put, \
@@ -81,7 +82,7 @@
81/* special beep mono mute switch with index (index=0,1,...) (channel=1,2) */ 82/* special beep mono mute switch with index (index=0,1,...) (channel=1,2) */
82#define HDA_CODEC_MUTE_BEEP_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \ 83#define HDA_CODEC_MUTE_BEEP_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \
83 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ 84 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \
84 .subdevice = HDA_SUBDEV_NID_FLAG | (nid), \ 85 .subdevice = HDA_SUBDEV_AMP_FLAG, \
85 .info = snd_hda_mixer_amp_switch_info, \ 86 .info = snd_hda_mixer_amp_switch_info, \
86 .get = snd_hda_mixer_amp_switch_get, \ 87 .get = snd_hda_mixer_amp_switch_get, \
87 .put = snd_hda_mixer_amp_switch_put_beep, \ 88 .put = snd_hda_mixer_amp_switch_put_beep, \
@@ -464,13 +465,20 @@ u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid);
464u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid); 465u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid);
465int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid); 466int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid);
466 467
468/* flags for hda_nid_item */
469#define HDA_NID_ITEM_AMP (1<<0)
470
467struct hda_nid_item { 471struct hda_nid_item {
468 struct snd_kcontrol *kctl; 472 struct snd_kcontrol *kctl;
473 unsigned int index;
469 hda_nid_t nid; 474 hda_nid_t nid;
475 unsigned short flags;
470}; 476};
471 477
472int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid, 478int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid,
473 struct snd_kcontrol *kctl); 479 struct snd_kcontrol *kctl);
480int snd_hda_add_nid(struct hda_codec *codec, struct snd_kcontrol *kctl,
481 unsigned int index, hda_nid_t nid);
474void snd_hda_ctls_clear(struct hda_codec *codec); 482void snd_hda_ctls_clear(struct hda_codec *codec);
475 483
476/* 484/*
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
index c9afc04adac8..f97d35de66c4 100644
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -61,18 +61,29 @@ static const char *get_wid_type_name(unsigned int wid_value)
61 return "UNKNOWN Widget"; 61 return "UNKNOWN Widget";
62} 62}
63 63
64static void print_nid_mixers(struct snd_info_buffer *buffer, 64static void print_nid_array(struct snd_info_buffer *buffer,
65 struct hda_codec *codec, hda_nid_t nid) 65 struct hda_codec *codec, hda_nid_t nid,
66 struct snd_array *array)
66{ 67{
67 int i; 68 int i;
68 struct hda_nid_item *items = codec->mixers.list; 69 struct hda_nid_item *items = array->list, *item;
69 struct snd_kcontrol *kctl; 70 struct snd_kcontrol *kctl;
70 for (i = 0; i < codec->mixers.used; i++) { 71 for (i = 0; i < array->used; i++) {
71 if (items[i].nid == nid) { 72 item = &items[i];
72 kctl = items[i].kctl; 73 if (item->nid == nid) {
74 kctl = item->kctl;
73 snd_iprintf(buffer, 75 snd_iprintf(buffer,
74 " Control: name=\"%s\", index=%i, device=%i\n", 76 " Control: name=\"%s\", index=%i, device=%i\n",
75 kctl->id.name, kctl->id.index, kctl->id.device); 77 kctl->id.name, kctl->id.index + item->index,
78 kctl->id.device);
79 if (item->flags & HDA_NID_ITEM_AMP)
80 snd_iprintf(buffer,
81 " ControlAmp: chs=%lu, dir=%s, "
82 "idx=%lu, ofs=%lu\n",
83 get_amp_channels(kctl),
84 get_amp_direction(kctl) ? "Out" : "In",
85 get_amp_index(kctl),
86 get_amp_offset(kctl));
76 } 87 }
77 } 88 }
78} 89}
@@ -528,7 +539,8 @@ static void print_gpio(struct snd_info_buffer *buffer,
528 (data & (1<<i)) ? 1 : 0, 539 (data & (1<<i)) ? 1 : 0,
529 (unsol & (1<<i)) ? 1 : 0); 540 (unsol & (1<<i)) ? 1 : 0);
530 /* FIXME: add GPO and GPI pin information */ 541 /* FIXME: add GPO and GPI pin information */
531 print_nid_mixers(buffer, codec, nid); 542 print_nid_array(buffer, codec, nid, &codec->mixers);
543 print_nid_array(buffer, codec, nid, &codec->nids);
532} 544}
533 545
534static void print_codec_info(struct snd_info_entry *entry, 546static void print_codec_info(struct snd_info_entry *entry,
@@ -608,7 +620,8 @@ static void print_codec_info(struct snd_info_entry *entry,
608 snd_iprintf(buffer, " CP"); 620 snd_iprintf(buffer, " CP");
609 snd_iprintf(buffer, "\n"); 621 snd_iprintf(buffer, "\n");
610 622
611 print_nid_mixers(buffer, codec, nid); 623 print_nid_array(buffer, codec, nid, &codec->mixers);
624 print_nid_array(buffer, codec, nid, &codec->nids);
612 print_nid_pcms(buffer, codec, nid); 625 print_nid_pcms(buffer, codec, nid);
613 626
614 /* volume knob is a special widget that always have connection 627 /* volume knob is a special widget that always have connection
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 69a941c7b158..e6d1bdff1b6e 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -174,6 +174,7 @@ static struct snd_kcontrol_new ad_beep_mixer[] = {
174static int ad198x_build_controls(struct hda_codec *codec) 174static int ad198x_build_controls(struct hda_codec *codec)
175{ 175{
176 struct ad198x_spec *spec = codec->spec; 176 struct ad198x_spec *spec = codec->spec;
177 struct snd_kcontrol *kctl;
177 unsigned int i; 178 unsigned int i;
178 int err; 179 int err;
179 180
@@ -208,9 +209,7 @@ static int ad198x_build_controls(struct hda_codec *codec)
208 if (!kctl) 209 if (!kctl)
209 return -ENOMEM; 210 return -ENOMEM;
210 kctl->private_value = spec->beep_amp; 211 kctl->private_value = spec->beep_amp;
211 err = snd_hda_ctl_add(codec, 212 err = snd_hda_ctl_add(codec, 0, kctl);
212 get_amp_nid_(spec->beep_amp),
213 kctl);
214 if (err < 0) 213 if (err < 0)
215 return err; 214 return err;
216 } 215 }
@@ -239,6 +238,27 @@ static int ad198x_build_controls(struct hda_codec *codec)
239 } 238 }
240 239
241 ad198x_free_kctls(codec); /* no longer needed */ 240 ad198x_free_kctls(codec); /* no longer needed */
241
242 /* assign Capture Source enums to NID */
243 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
244 if (!kctl)
245 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
246 for (i = 0; kctl && i < kctl->count; i++) {
247 err = snd_hda_add_nid(codec, kctl, i, spec->capsrc_nids[i]);
248 if (err < 0)
249 return err;
250 }
251
252 /* assign IEC958 enums to NID */
253 kctl = snd_hda_find_mixer_ctl(codec,
254 SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source");
255 if (kctl) {
256 err = snd_hda_add_nid(codec, kctl, 0,
257 spec->multiout.dig_out_nid);
258 if (err < 0)
259 return err;
260 }
261
242 return 0; 262 return 0;
243} 263}
244 264
@@ -421,6 +441,11 @@ static int ad198x_build_pcms(struct hda_codec *codec)
421 return 0; 441 return 0;
422} 442}
423 443
444static inline void ad198x_shutup(struct hda_codec *codec)
445{
446 snd_hda_shutup_pins(codec);
447}
448
424static void ad198x_free_kctls(struct hda_codec *codec) 449static void ad198x_free_kctls(struct hda_codec *codec)
425{ 450{
426 struct ad198x_spec *spec = codec->spec; 451 struct ad198x_spec *spec = codec->spec;
@@ -434,6 +459,46 @@ static void ad198x_free_kctls(struct hda_codec *codec)
434 snd_array_free(&spec->kctls); 459 snd_array_free(&spec->kctls);
435} 460}
436 461
462static void ad198x_power_eapd_write(struct hda_codec *codec, hda_nid_t front,
463 hda_nid_t hp)
464{
465 struct ad198x_spec *spec = codec->spec;
466 snd_hda_codec_write(codec, front, 0, AC_VERB_SET_EAPD_BTLENABLE,
467 !spec->inv_eapd ? 0x00 : 0x02);
468 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_EAPD_BTLENABLE,
469 !spec->inv_eapd ? 0x00 : 0x02);
470}
471
472static void ad198x_power_eapd(struct hda_codec *codec)
473{
474 /* We currently only handle front, HP */
475 switch (codec->vendor_id) {
476 case 0x11d41882:
477 case 0x11d4882a:
478 case 0x11d41884:
479 case 0x11d41984:
480 case 0x11d41883:
481 case 0x11d4184a:
482 case 0x11d4194a:
483 case 0x11d4194b:
484 ad198x_power_eapd_write(codec, 0x12, 0x11);
485 break;
486 case 0x11d41981:
487 case 0x11d41983:
488 ad198x_power_eapd_write(codec, 0x05, 0x06);
489 break;
490 case 0x11d41986:
491 ad198x_power_eapd_write(codec, 0x1b, 0x1a);
492 break;
493 case 0x11d41988:
494 case 0x11d4198b:
495 case 0x11d4989a:
496 case 0x11d4989b:
497 ad198x_power_eapd_write(codec, 0x29, 0x22);
498 break;
499 }
500}
501
437static void ad198x_free(struct hda_codec *codec) 502static void ad198x_free(struct hda_codec *codec)
438{ 503{
439 struct ad198x_spec *spec = codec->spec; 504 struct ad198x_spec *spec = codec->spec;
@@ -441,11 +506,29 @@ static void ad198x_free(struct hda_codec *codec)
441 if (!spec) 506 if (!spec)
442 return; 507 return;
443 508
509 ad198x_shutup(codec);
444 ad198x_free_kctls(codec); 510 ad198x_free_kctls(codec);
445 kfree(spec); 511 kfree(spec);
446 snd_hda_detach_beep_device(codec); 512 snd_hda_detach_beep_device(codec);
447} 513}
448 514
515#ifdef SND_HDA_NEEDS_RESUME
516static int ad198x_suspend(struct hda_codec *codec, pm_message_t state)
517{
518 ad198x_shutup(codec);
519 ad198x_power_eapd(codec);
520 return 0;
521}
522
523static int ad198x_resume(struct hda_codec *codec)
524{
525 ad198x_init(codec);
526 snd_hda_codec_resume_amp(codec);
527 snd_hda_codec_resume_cache(codec);
528 return 0;
529}
530#endif
531
449static struct hda_codec_ops ad198x_patch_ops = { 532static struct hda_codec_ops ad198x_patch_ops = {
450 .build_controls = ad198x_build_controls, 533 .build_controls = ad198x_build_controls,
451 .build_pcms = ad198x_build_pcms, 534 .build_pcms = ad198x_build_pcms,
@@ -454,6 +537,11 @@ static struct hda_codec_ops ad198x_patch_ops = {
454#ifdef CONFIG_SND_HDA_POWER_SAVE 537#ifdef CONFIG_SND_HDA_POWER_SAVE
455 .check_power_status = ad198x_check_power_status, 538 .check_power_status = ad198x_check_power_status,
456#endif 539#endif
540#ifdef SND_HDA_NEEDS_RESUME
541 .suspend = ad198x_suspend,
542 .resume = ad198x_resume,
543#endif
544 .reboot_notify = ad198x_shutup,
457}; 545};
458 546
459 547
@@ -701,6 +789,7 @@ static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = {
701 { 789 {
702 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 790 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
703 .name = "External Amplifier", 791 .name = "External Amplifier",
792 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
704 .info = ad198x_eapd_info, 793 .info = ad198x_eapd_info,
705 .get = ad198x_eapd_get, 794 .get = ad198x_eapd_get,
706 .put = ad198x_eapd_put, 795 .put = ad198x_eapd_put,
@@ -808,6 +897,7 @@ static struct snd_kcontrol_new ad1986a_automute_master_mixers[] = {
808 { 897 {
809 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 898 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
810 .name = "Master Playback Switch", 899 .name = "Master Playback Switch",
900 .subdevice = HDA_SUBDEV_AMP_FLAG,
811 .info = snd_hda_mixer_amp_switch_info, 901 .info = snd_hda_mixer_amp_switch_info,
812 .get = snd_hda_mixer_amp_switch_get, 902 .get = snd_hda_mixer_amp_switch_get,
813 .put = ad1986a_hp_master_sw_put, 903 .put = ad1986a_hp_master_sw_put,
@@ -1008,7 +1098,7 @@ static struct snd_pci_quirk ad1986a_cfg_tbl[] = {
1008 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS M2N", AD1986A_3STACK), 1098 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS M2N", AD1986A_3STACK),
1009 SND_PCI_QUIRK(0x1043, 0x8234, "ASUS M2N", AD1986A_3STACK), 1099 SND_PCI_QUIRK(0x1043, 0x8234, "ASUS M2N", AD1986A_3STACK),
1010 SND_PCI_QUIRK(0x10de, 0xcb84, "ASUS A8N-VM", AD1986A_3STACK), 1100 SND_PCI_QUIRK(0x10de, 0xcb84, "ASUS A8N-VM", AD1986A_3STACK),
1011 SND_PCI_QUIRK(0x1179, 0xff40, "Toshiba", AD1986A_LAPTOP_EAPD), 1101 SND_PCI_QUIRK(0x1179, 0xff40, "Toshiba Satellite L40-10Q", AD1986A_3STACK),
1012 SND_PCI_QUIRK(0x144d, 0xb03c, "Samsung R55", AD1986A_3STACK), 1102 SND_PCI_QUIRK(0x144d, 0xb03c, "Samsung R55", AD1986A_3STACK),
1013 SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_LAPTOP), 1103 SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_LAPTOP),
1014 SND_PCI_QUIRK(0x144d, 0xc024, "Samsung P50", AD1986A_SAMSUNG_P50), 1104 SND_PCI_QUIRK(0x144d, 0xc024, "Samsung P50", AD1986A_SAMSUNG_P50),
@@ -1612,6 +1702,7 @@ static struct snd_kcontrol_new ad1981_hp_mixers[] = {
1612 HDA_BIND_VOL("Master Playback Volume", &ad1981_hp_bind_master_vol), 1702 HDA_BIND_VOL("Master Playback Volume", &ad1981_hp_bind_master_vol),
1613 { 1703 {
1614 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1704 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1705 .subdevice = HDA_SUBDEV_NID_FLAG | 0x05,
1615 .name = "Master Playback Switch", 1706 .name = "Master Playback Switch",
1616 .info = ad198x_eapd_info, 1707 .info = ad198x_eapd_info,
1617 .get = ad198x_eapd_get, 1708 .get = ad198x_eapd_get,
@@ -2136,6 +2227,7 @@ static struct snd_kcontrol_new ad1988_laptop_mixers[] = {
2136 { 2227 {
2137 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2228 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2138 .name = "External Amplifier", 2229 .name = "External Amplifier",
2230 .subdevice = HDA_SUBDEV_NID_FLAG | 0x12,
2139 .info = ad198x_eapd_info, 2231 .info = ad198x_eapd_info,
2140 .get = ad198x_eapd_get, 2232 .get = ad198x_eapd_get,
2141 .put = ad198x_eapd_put, 2233 .put = ad198x_eapd_put,
@@ -2257,6 +2349,7 @@ static struct snd_kcontrol_new ad1988_spdif_out_mixers[] = {
2257 { 2349 {
2258 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2350 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2259 .name = "IEC958 Playback Source", 2351 .name = "IEC958 Playback Source",
2352 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
2260 .info = ad1988_spdif_playback_source_info, 2353 .info = ad1988_spdif_playback_source_info,
2261 .get = ad1988_spdif_playback_source_get, 2354 .get = ad1988_spdif_playback_source_get,
2262 .put = ad1988_spdif_playback_source_put, 2355 .put = ad1988_spdif_playback_source_put,
@@ -2372,6 +2465,12 @@ static struct hda_verb ad1988_spdif_init_verbs[] = {
2372 { } 2465 { }
2373}; 2466};
2374 2467
2468static struct hda_verb ad1988_spdif_in_init_verbs[] = {
2469 /* unmute SPDIF input pin */
2470 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2471 { }
2472};
2473
2375/* AD1989 has no ADC -> SPDIF route */ 2474/* AD1989 has no ADC -> SPDIF route */
2376static struct hda_verb ad1989_spdif_init_verbs[] = { 2475static struct hda_verb ad1989_spdif_init_verbs[] = {
2377 /* SPDIF-1 out pin */ 2476 /* SPDIF-1 out pin */
@@ -2589,7 +2688,7 @@ static int add_control(struct ad198x_spec *spec, int type, const char *name,
2589 if (! knew->name) 2688 if (! knew->name)
2590 return -ENOMEM; 2689 return -ENOMEM;
2591 if (get_amp_nid_(val)) 2690 if (get_amp_nid_(val))
2592 knew->subdevice = HDA_SUBDEV_NID_FLAG | get_amp_nid_(val); 2691 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
2593 knew->private_value = val; 2692 knew->private_value = val;
2594 return 0; 2693 return 0;
2595} 2694}
@@ -3107,8 +3206,11 @@ static int patch_ad1988(struct hda_codec *codec)
3107 ad1988_spdif_init_verbs; 3206 ad1988_spdif_init_verbs;
3108 } 3207 }
3109 } 3208 }
3110 if (spec->dig_in_nid && codec->vendor_id < 0x11d4989a) 3209 if (spec->dig_in_nid && codec->vendor_id < 0x11d4989a) {
3111 spec->mixers[spec->num_mixers++] = ad1988_spdif_in_mixers; 3210 spec->mixers[spec->num_mixers++] = ad1988_spdif_in_mixers;
3211 spec->init_verbs[spec->num_init_verbs++] =
3212 ad1988_spdif_in_init_verbs;
3213 }
3112 3214
3113 codec->patch_ops = ad198x_patch_ops; 3215 codec->patch_ops = ad198x_patch_ops;
3114 switch (board_config) { 3216 switch (board_config) {
@@ -3747,6 +3849,7 @@ static struct snd_kcontrol_new ad1884a_laptop_mixers[] = {
3747 { 3849 {
3748 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3850 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3749 .name = "Master Playback Switch", 3851 .name = "Master Playback Switch",
3852 .subdevice = HDA_SUBDEV_AMP_FLAG,
3750 .info = snd_hda_mixer_amp_switch_info, 3853 .info = snd_hda_mixer_amp_switch_info,
3751 .get = snd_hda_mixer_amp_switch_get, 3854 .get = snd_hda_mixer_amp_switch_get,
3752 .put = ad1884a_mobile_master_sw_put, 3855 .put = ad1884a_mobile_master_sw_put,
@@ -3775,6 +3878,7 @@ static struct snd_kcontrol_new ad1884a_mobile_mixers[] = {
3775 { 3878 {
3776 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3879 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3777 .name = "Master Playback Switch", 3880 .name = "Master Playback Switch",
3881 .subdevice = HDA_SUBDEV_AMP_FLAG,
3778 .info = snd_hda_mixer_amp_switch_info, 3882 .info = snd_hda_mixer_amp_switch_info,
3779 .get = snd_hda_mixer_amp_switch_get, 3883 .get = snd_hda_mixer_amp_switch_get,
3780 .put = ad1884a_mobile_master_sw_put, 3884 .put = ad1884a_mobile_master_sw_put,
@@ -4116,6 +4220,7 @@ static struct snd_kcontrol_new ad1984a_touchsmart_mixers[] = {
4116/* HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/ 4220/* HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/
4117 { 4221 {
4118 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 4222 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4223 .subdevice = HDA_SUBDEV_AMP_FLAG,
4119 .name = "Master Playback Switch", 4224 .name = "Master Playback Switch",
4120 .info = snd_hda_mixer_amp_switch_info, 4225 .info = snd_hda_mixer_amp_switch_info,
4121 .get = snd_hda_mixer_amp_switch_get, 4226 .get = snd_hda_mixer_amp_switch_get,
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index fe0423c39598..7de782a5b8f4 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -501,7 +501,8 @@ static int add_mute(struct hda_codec *codec, const char *name, int index,
501 knew.private_value = pval; 501 knew.private_value = pval;
502 snprintf(tmp, sizeof(tmp), "%s %s Switch", name, dir_sfx[dir]); 502 snprintf(tmp, sizeof(tmp), "%s %s Switch", name, dir_sfx[dir]);
503 *kctlp = snd_ctl_new1(&knew, codec); 503 *kctlp = snd_ctl_new1(&knew, codec);
504 return snd_hda_ctl_add(codec, get_amp_nid_(pval), *kctlp); 504 (*kctlp)->id.subdevice = HDA_SUBDEV_AMP_FLAG;
505 return snd_hda_ctl_add(codec, 0, *kctlp);
505} 506}
506 507
507static int add_volume(struct hda_codec *codec, const char *name, 508static int add_volume(struct hda_codec *codec, const char *name,
@@ -514,7 +515,8 @@ static int add_volume(struct hda_codec *codec, const char *name,
514 knew.private_value = pval; 515 knew.private_value = pval;
515 snprintf(tmp, sizeof(tmp), "%s %s Volume", name, dir_sfx[dir]); 516 snprintf(tmp, sizeof(tmp), "%s %s Volume", name, dir_sfx[dir]);
516 *kctlp = snd_ctl_new1(&knew, codec); 517 *kctlp = snd_ctl_new1(&knew, codec);
517 return snd_hda_ctl_add(codec, get_amp_nid_(pval), *kctlp); 518 (*kctlp)->id.subdevice = HDA_SUBDEV_AMP_FLAG;
519 return snd_hda_ctl_add(codec, 0, *kctlp);
518} 520}
519 521
520static void fix_volume_caps(struct hda_codec *codec, hda_nid_t dac) 522static void fix_volume_caps(struct hda_codec *codec, hda_nid_t dac)
@@ -751,6 +753,7 @@ static int build_input(struct hda_codec *codec)
751 spec->capture_bind[1] = make_bind_capture(codec, &snd_hda_bind_vol); 753 spec->capture_bind[1] = make_bind_capture(codec, &snd_hda_bind_vol);
752 for (i = 0; i < 2; i++) { 754 for (i = 0; i < 2; i++) {
753 struct snd_kcontrol *kctl; 755 struct snd_kcontrol *kctl;
756 int n;
754 if (!spec->capture_bind[i]) 757 if (!spec->capture_bind[i])
755 return -ENOMEM; 758 return -ENOMEM;
756 kctl = snd_ctl_new1(&cs_capture_ctls[i], codec); 759 kctl = snd_ctl_new1(&cs_capture_ctls[i], codec);
@@ -760,6 +763,13 @@ static int build_input(struct hda_codec *codec)
760 err = snd_hda_ctl_add(codec, 0, kctl); 763 err = snd_hda_ctl_add(codec, 0, kctl);
761 if (err < 0) 764 if (err < 0)
762 return err; 765 return err;
766 for (n = 0; n < AUTO_PIN_LAST; n++) {
767 if (!spec->adc_nid[n])
768 continue;
769 err = snd_hda_add_nid(codec, kctl, 0, spec->adc_nid[i]);
770 if (err < 0)
771 return err;
772 }
763 } 773 }
764 774
765 if (spec->num_inputs > 1 && !spec->mic_detect) { 775 if (spec->num_inputs > 1 && !spec->mic_detect) {
diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c
index a45c1169762b..ff60908f4554 100644
--- a/sound/pci/hda/patch_cmedia.c
+++ b/sound/pci/hda/patch_cmedia.c
@@ -315,7 +315,8 @@ static struct hda_verb cmi9880_allout_init[] = {
315static int cmi9880_build_controls(struct hda_codec *codec) 315static int cmi9880_build_controls(struct hda_codec *codec)
316{ 316{
317 struct cmi_spec *spec = codec->spec; 317 struct cmi_spec *spec = codec->spec;
318 int err; 318 struct snd_kcontrol *kctl;
319 int i, err;
319 320
320 err = snd_hda_add_new_ctls(codec, cmi9880_basic_mixer); 321 err = snd_hda_add_new_ctls(codec, cmi9880_basic_mixer);
321 if (err < 0) 322 if (err < 0)
@@ -340,6 +341,14 @@ static int cmi9880_build_controls(struct hda_codec *codec)
340 if (err < 0) 341 if (err < 0)
341 return err; 342 return err;
342 } 343 }
344
345 /* assign Capture Source enums to NID */
346 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
347 for (i = 0; kctl && i < kctl->count; i++) {
348 err = snd_hda_add_nid(codec, kctl, i, spec->adc_nids[i]);
349 if (err < 0)
350 return err;
351 }
343 return 0; 352 return 0;
344} 353}
345 354
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index c578c28f368e..194a28c54992 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -42,10 +42,12 @@
42 42
43/* Conexant 5051 specific */ 43/* Conexant 5051 specific */
44 44
45#define CXT5051_SPDIF_OUT 0x1C 45#define CXT5051_SPDIF_OUT 0x12
46#define CXT5051_PORTB_EVENT 0x38 46#define CXT5051_PORTB_EVENT 0x38
47#define CXT5051_PORTC_EVENT 0x39 47#define CXT5051_PORTC_EVENT 0x39
48 48
49#define AUTO_MIC_PORTB (1 << 1)
50#define AUTO_MIC_PORTC (1 << 2)
49 51
50struct conexant_jack { 52struct conexant_jack {
51 53
@@ -74,7 +76,7 @@ struct conexant_spec {
74 */ 76 */
75 unsigned int cur_eapd; 77 unsigned int cur_eapd;
76 unsigned int hp_present; 78 unsigned int hp_present;
77 unsigned int no_auto_mic; 79 unsigned int auto_mic;
78 unsigned int need_dac_fix; 80 unsigned int need_dac_fix;
79 81
80 /* capture */ 82 /* capture */
@@ -111,8 +113,23 @@ struct conexant_spec {
111 113
112 unsigned int dell_automute; 114 unsigned int dell_automute;
113 unsigned int port_d_mode; 115 unsigned int port_d_mode;
114 unsigned char ext_mic_bias; 116 unsigned int dell_vostro:1;
115 unsigned int dell_vostro; 117 unsigned int ideapad:1;
118
119 unsigned int ext_mic_present;
120 unsigned int recording;
121 void (*capture_prepare)(struct hda_codec *codec);
122 void (*capture_cleanup)(struct hda_codec *codec);
123
124 /* OLPC XO-1.5 supports DC input mode (e.g. for use with analog sensors)
125 * through the microphone jack.
126 * When the user enables this through a mixer switch, both internal and
127 * external microphones are disabled. Gain is fixed at 0dB. In this mode,
128 * we also allow the bias to be configured through a separate mixer
129 * control. */
130 unsigned int dc_enable;
131 unsigned int dc_input_bias; /* offset into cxt5066_olpc_dc_bias */
132 unsigned int mic_boost; /* offset into cxt5066_analog_mic_boost */
116}; 133};
117 134
118static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo, 135static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo,
@@ -185,6 +202,8 @@ static int conexant_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
185 struct snd_pcm_substream *substream) 202 struct snd_pcm_substream *substream)
186{ 203{
187 struct conexant_spec *spec = codec->spec; 204 struct conexant_spec *spec = codec->spec;
205 if (spec->capture_prepare)
206 spec->capture_prepare(codec);
188 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 207 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
189 stream_tag, 0, format); 208 stream_tag, 0, format);
190 return 0; 209 return 0;
@@ -196,6 +215,8 @@ static int conexant_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
196{ 215{
197 struct conexant_spec *spec = codec->spec; 216 struct conexant_spec *spec = codec->spec;
198 snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]); 217 snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]);
218 if (spec->capture_cleanup)
219 spec->capture_cleanup(codec);
199 return 0; 220 return 0;
200} 221}
201 222
@@ -1585,6 +1606,11 @@ static void cxt5051_update_speaker(struct hda_codec *codec)
1585{ 1606{
1586 struct conexant_spec *spec = codec->spec; 1607 struct conexant_spec *spec = codec->spec;
1587 unsigned int pinctl; 1608 unsigned int pinctl;
1609 /* headphone pin */
1610 pinctl = (spec->hp_present && spec->cur_eapd) ? PIN_HP : 0;
1611 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
1612 pinctl);
1613 /* speaker pin */
1588 pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0; 1614 pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0;
1589 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 1615 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
1590 pinctl); 1616 pinctl);
@@ -1608,7 +1634,7 @@ static void cxt5051_portb_automic(struct hda_codec *codec)
1608 struct conexant_spec *spec = codec->spec; 1634 struct conexant_spec *spec = codec->spec;
1609 unsigned int present; 1635 unsigned int present;
1610 1636
1611 if (spec->no_auto_mic) 1637 if (!(spec->auto_mic & AUTO_MIC_PORTB))
1612 return; 1638 return;
1613 present = snd_hda_jack_detect(codec, 0x17); 1639 present = snd_hda_jack_detect(codec, 0x17);
1614 snd_hda_codec_write(codec, 0x14, 0, 1640 snd_hda_codec_write(codec, 0x14, 0,
@@ -1623,7 +1649,7 @@ static void cxt5051_portc_automic(struct hda_codec *codec)
1623 unsigned int present; 1649 unsigned int present;
1624 hda_nid_t new_adc; 1650 hda_nid_t new_adc;
1625 1651
1626 if (spec->no_auto_mic) 1652 if (!(spec->auto_mic & AUTO_MIC_PORTC))
1627 return; 1653 return;
1628 present = snd_hda_jack_detect(codec, 0x18); 1654 present = snd_hda_jack_detect(codec, 0x18);
1629 if (present) 1655 if (present)
@@ -1669,13 +1695,7 @@ static void cxt5051_hp_unsol_event(struct hda_codec *codec,
1669 conexant_report_jack(codec, nid); 1695 conexant_report_jack(codec, nid);
1670} 1696}
1671 1697
1672static struct snd_kcontrol_new cxt5051_mixers[] = { 1698static struct snd_kcontrol_new cxt5051_playback_mixers[] = {
1673 HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1674 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1675 HDA_CODEC_VOLUME("External Mic Volume", 0x14, 0x01, HDA_INPUT),
1676 HDA_CODEC_MUTE("External Mic Switch", 0x14, 0x01, HDA_INPUT),
1677 HDA_CODEC_VOLUME("Docking Mic Volume", 0x15, 0x00, HDA_INPUT),
1678 HDA_CODEC_MUTE("Docking Mic Switch", 0x15, 0x00, HDA_INPUT),
1679 HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT), 1699 HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT),
1680 { 1700 {
1681 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1701 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -1685,7 +1705,16 @@ static struct snd_kcontrol_new cxt5051_mixers[] = {
1685 .put = cxt5051_hp_master_sw_put, 1705 .put = cxt5051_hp_master_sw_put,
1686 .private_value = 0x1a, 1706 .private_value = 0x1a,
1687 }, 1707 },
1708 {}
1709};
1688 1710
1711static struct snd_kcontrol_new cxt5051_capture_mixers[] = {
1712 HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1713 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1714 HDA_CODEC_VOLUME("External Mic Volume", 0x14, 0x01, HDA_INPUT),
1715 HDA_CODEC_MUTE("External Mic Switch", 0x14, 0x01, HDA_INPUT),
1716 HDA_CODEC_VOLUME("Docking Mic Volume", 0x15, 0x00, HDA_INPUT),
1717 HDA_CODEC_MUTE("Docking Mic Switch", 0x15, 0x00, HDA_INPUT),
1689 {} 1718 {}
1690}; 1719};
1691 1720
@@ -1694,32 +1723,26 @@ static struct snd_kcontrol_new cxt5051_hp_mixers[] = {
1694 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT), 1723 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1695 HDA_CODEC_VOLUME("External Mic Volume", 0x15, 0x00, HDA_INPUT), 1724 HDA_CODEC_VOLUME("External Mic Volume", 0x15, 0x00, HDA_INPUT),
1696 HDA_CODEC_MUTE("External Mic Switch", 0x15, 0x00, HDA_INPUT), 1725 HDA_CODEC_MUTE("External Mic Switch", 0x15, 0x00, HDA_INPUT),
1697 HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT),
1698 {
1699 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1700 .name = "Master Playback Switch",
1701 .info = cxt_eapd_info,
1702 .get = cxt_eapd_get,
1703 .put = cxt5051_hp_master_sw_put,
1704 .private_value = 0x1a,
1705 },
1706
1707 {} 1726 {}
1708}; 1727};
1709 1728
1710static struct snd_kcontrol_new cxt5051_hp_dv6736_mixers[] = { 1729static struct snd_kcontrol_new cxt5051_hp_dv6736_mixers[] = {
1711 HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x00, HDA_INPUT), 1730 HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x00, HDA_INPUT),
1712 HDA_CODEC_MUTE("Mic Switch", 0x14, 0x00, HDA_INPUT), 1731 HDA_CODEC_MUTE("Capture Switch", 0x14, 0x00, HDA_INPUT),
1713 HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT), 1732 {}
1714 { 1733};
1715 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1716 .name = "Master Playback Switch",
1717 .info = cxt_eapd_info,
1718 .get = cxt_eapd_get,
1719 .put = cxt5051_hp_master_sw_put,
1720 .private_value = 0x1a,
1721 },
1722 1734
1735static struct snd_kcontrol_new cxt5051_f700_mixers[] = {
1736 HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x01, HDA_INPUT),
1737 HDA_CODEC_MUTE("Capture Switch", 0x14, 0x01, HDA_INPUT),
1738 {}
1739};
1740
1741static struct snd_kcontrol_new cxt5051_toshiba_mixers[] = {
1742 HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1743 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1744 HDA_CODEC_VOLUME("External Mic Volume", 0x14, 0x01, HDA_INPUT),
1745 HDA_CODEC_MUTE("External Mic Switch", 0x14, 0x01, HDA_INPUT),
1723 {} 1746 {}
1724}; 1747};
1725 1748
@@ -1748,8 +1771,6 @@ static struct hda_verb cxt5051_init_verbs[] = {
1748 /* EAPD */ 1771 /* EAPD */
1749 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ 1772 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
1750 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT}, 1773 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1751 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTB_EVENT},
1752 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTC_EVENT},
1753 { } /* end */ 1774 { } /* end */
1754}; 1775};
1755 1776
@@ -1775,7 +1796,6 @@ static struct hda_verb cxt5051_hp_dv6736_init_verbs[] = {
1775 /* EAPD */ 1796 /* EAPD */
1776 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ 1797 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
1777 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT}, 1798 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1778 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTB_EVENT},
1779 { } /* end */ 1799 { } /* end */
1780}; 1800};
1781 1801
@@ -1807,17 +1827,60 @@ static struct hda_verb cxt5051_lenovo_x200_init_verbs[] = {
1807 /* EAPD */ 1827 /* EAPD */
1808 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ 1828 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
1809 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT}, 1829 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1810 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTB_EVENT},
1811 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTC_EVENT},
1812 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT}, 1830 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1813 { } /* end */ 1831 { } /* end */
1814}; 1832};
1815 1833
1834static struct hda_verb cxt5051_f700_init_verbs[] = {
1835 /* Line in, Mic */
1836 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1837 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1838 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0},
1839 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0},
1840 /* SPK */
1841 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1842 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
1843 /* HP, Amp */
1844 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1845 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
1846 /* DAC1 */
1847 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1848 /* Record selector: Int mic */
1849 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
1850 {0x14, AC_VERB_SET_CONNECT_SEL, 0x1},
1851 /* SPDIF route: PCM */
1852 {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0},
1853 /* EAPD */
1854 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
1855 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1856 { } /* end */
1857};
1858
1859static void cxt5051_init_mic_port(struct hda_codec *codec, hda_nid_t nid,
1860 unsigned int event)
1861{
1862 snd_hda_codec_write(codec, nid, 0,
1863 AC_VERB_SET_UNSOLICITED_ENABLE,
1864 AC_USRSP_EN | event);
1865#ifdef CONFIG_SND_HDA_INPUT_JACK
1866 conexant_add_jack(codec, nid, SND_JACK_MICROPHONE);
1867 conexant_report_jack(codec, nid);
1868#endif
1869}
1870
1816/* initialize jack-sensing, too */ 1871/* initialize jack-sensing, too */
1817static int cxt5051_init(struct hda_codec *codec) 1872static int cxt5051_init(struct hda_codec *codec)
1818{ 1873{
1874 struct conexant_spec *spec = codec->spec;
1875
1819 conexant_init(codec); 1876 conexant_init(codec);
1820 conexant_init_jacks(codec); 1877 conexant_init_jacks(codec);
1878
1879 if (spec->auto_mic & AUTO_MIC_PORTB)
1880 cxt5051_init_mic_port(codec, 0x17, CXT5051_PORTB_EVENT);
1881 if (spec->auto_mic & AUTO_MIC_PORTC)
1882 cxt5051_init_mic_port(codec, 0x18, CXT5051_PORTC_EVENT);
1883
1821 if (codec->patch_ops.unsol_event) { 1884 if (codec->patch_ops.unsol_event) {
1822 cxt5051_hp_automute(codec); 1885 cxt5051_hp_automute(codec);
1823 cxt5051_portb_automic(codec); 1886 cxt5051_portb_automic(codec);
@@ -1832,6 +1895,8 @@ enum {
1832 CXT5051_HP, /* no docking */ 1895 CXT5051_HP, /* no docking */
1833 CXT5051_HP_DV6736, /* HP without mic switch */ 1896 CXT5051_HP_DV6736, /* HP without mic switch */
1834 CXT5051_LENOVO_X200, /* Lenovo X200 laptop */ 1897 CXT5051_LENOVO_X200, /* Lenovo X200 laptop */
1898 CXT5051_F700, /* HP Compaq Presario F700 */
1899 CXT5051_TOSHIBA, /* Toshiba M300 & co */
1835 CXT5051_MODELS 1900 CXT5051_MODELS
1836}; 1901};
1837 1902
@@ -1840,11 +1905,15 @@ static const char *cxt5051_models[CXT5051_MODELS] = {
1840 [CXT5051_HP] = "hp", 1905 [CXT5051_HP] = "hp",
1841 [CXT5051_HP_DV6736] = "hp-dv6736", 1906 [CXT5051_HP_DV6736] = "hp-dv6736",
1842 [CXT5051_LENOVO_X200] = "lenovo-x200", 1907 [CXT5051_LENOVO_X200] = "lenovo-x200",
1908 [CXT5051_F700] = "hp-700",
1909 [CXT5051_TOSHIBA] = "toshiba",
1843}; 1910};
1844 1911
1845static struct snd_pci_quirk cxt5051_cfg_tbl[] = { 1912static struct snd_pci_quirk cxt5051_cfg_tbl[] = {
1846 SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV6736", CXT5051_HP_DV6736), 1913 SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV6736", CXT5051_HP_DV6736),
1847 SND_PCI_QUIRK(0x103c, 0x360b, "Compaq Presario CQ60", CXT5051_HP), 1914 SND_PCI_QUIRK(0x103c, 0x360b, "Compaq Presario CQ60", CXT5051_HP),
1915 SND_PCI_QUIRK(0x103c, 0x30ea, "Compaq Presario F700", CXT5051_F700),
1916 SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba M30x", CXT5051_TOSHIBA),
1848 SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board", 1917 SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board",
1849 CXT5051_LAPTOP), 1918 CXT5051_LAPTOP),
1850 SND_PCI_QUIRK(0x14f1, 0x5051, "HP Spartan 1.1", CXT5051_HP), 1919 SND_PCI_QUIRK(0x14f1, 0x5051, "HP Spartan 1.1", CXT5051_HP),
@@ -1872,8 +1941,9 @@ static int patch_cxt5051(struct hda_codec *codec)
1872 spec->multiout.dig_out_nid = CXT5051_SPDIF_OUT; 1941 spec->multiout.dig_out_nid = CXT5051_SPDIF_OUT;
1873 spec->num_adc_nids = 1; /* not 2; via auto-mic switch */ 1942 spec->num_adc_nids = 1; /* not 2; via auto-mic switch */
1874 spec->adc_nids = cxt5051_adc_nids; 1943 spec->adc_nids = cxt5051_adc_nids;
1875 spec->num_mixers = 1; 1944 spec->num_mixers = 2;
1876 spec->mixers[0] = cxt5051_mixers; 1945 spec->mixers[0] = cxt5051_capture_mixers;
1946 spec->mixers[1] = cxt5051_playback_mixers;
1877 spec->num_init_verbs = 1; 1947 spec->num_init_verbs = 1;
1878 spec->init_verbs[0] = cxt5051_init_verbs; 1948 spec->init_verbs[0] = cxt5051_init_verbs;
1879 spec->spdif_route = 0; 1949 spec->spdif_route = 0;
@@ -1887,6 +1957,7 @@ static int patch_cxt5051(struct hda_codec *codec)
1887 board_config = snd_hda_check_board_config(codec, CXT5051_MODELS, 1957 board_config = snd_hda_check_board_config(codec, CXT5051_MODELS,
1888 cxt5051_models, 1958 cxt5051_models,
1889 cxt5051_cfg_tbl); 1959 cxt5051_cfg_tbl);
1960 spec->auto_mic = AUTO_MIC_PORTB | AUTO_MIC_PORTC;
1890 switch (board_config) { 1961 switch (board_config) {
1891 case CXT5051_HP: 1962 case CXT5051_HP:
1892 spec->mixers[0] = cxt5051_hp_mixers; 1963 spec->mixers[0] = cxt5051_hp_mixers;
@@ -1894,11 +1965,20 @@ static int patch_cxt5051(struct hda_codec *codec)
1894 case CXT5051_HP_DV6736: 1965 case CXT5051_HP_DV6736:
1895 spec->init_verbs[0] = cxt5051_hp_dv6736_init_verbs; 1966 spec->init_verbs[0] = cxt5051_hp_dv6736_init_verbs;
1896 spec->mixers[0] = cxt5051_hp_dv6736_mixers; 1967 spec->mixers[0] = cxt5051_hp_dv6736_mixers;
1897 spec->no_auto_mic = 1; 1968 spec->auto_mic = 0;
1898 break; 1969 break;
1899 case CXT5051_LENOVO_X200: 1970 case CXT5051_LENOVO_X200:
1900 spec->init_verbs[0] = cxt5051_lenovo_x200_init_verbs; 1971 spec->init_verbs[0] = cxt5051_lenovo_x200_init_verbs;
1901 break; 1972 break;
1973 case CXT5051_F700:
1974 spec->init_verbs[0] = cxt5051_f700_init_verbs;
1975 spec->mixers[0] = cxt5051_f700_mixers;
1976 spec->auto_mic = 0;
1977 break;
1978 case CXT5051_TOSHIBA:
1979 spec->mixers[0] = cxt5051_toshiba_mixers;
1980 spec->auto_mic = AUTO_MIC_PORTB;
1981 break;
1902 } 1982 }
1903 1983
1904 return 0; 1984 return 0;
@@ -1966,33 +2046,117 @@ static int cxt5066_hp_master_sw_put(struct snd_kcontrol *kcontrol,
1966 return 1; 2046 return 1;
1967} 2047}
1968 2048
2049static const struct hda_input_mux cxt5066_olpc_dc_bias = {
2050 .num_items = 3,
2051 .items = {
2052 { "Off", PIN_IN },
2053 { "50%", PIN_VREF50 },
2054 { "80%", PIN_VREF80 },
2055 },
2056};
2057
2058static int cxt5066_set_olpc_dc_bias(struct hda_codec *codec)
2059{
2060 struct conexant_spec *spec = codec->spec;
2061 /* Even though port F is the DC input, the bias is controlled on port B.
2062 * we also leave that port as an active input (but unselected) in DC mode
2063 * just in case that is necessary to make the bias setting take effect. */
2064 return snd_hda_codec_write_cache(codec, 0x1a, 0,
2065 AC_VERB_SET_PIN_WIDGET_CONTROL,
2066 cxt5066_olpc_dc_bias.items[spec->dc_input_bias].index);
2067}
2068
2069/* OLPC defers mic widget control until when capture is started because the
2070 * microphone LED comes on as soon as these settings are put in place. if we
2071 * did this before recording, it would give the false indication that recording
2072 * is happening when it is not. */
2073static void cxt5066_olpc_select_mic(struct hda_codec *codec)
2074{
2075 struct conexant_spec *spec = codec->spec;
2076 if (!spec->recording)
2077 return;
2078
2079 if (spec->dc_enable) {
2080 /* in DC mode we ignore presence detection and just use the jack
2081 * through our special DC port */
2082 const struct hda_verb enable_dc_mode[] = {
2083 /* disble internal mic, port C */
2084 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2085
2086 /* enable DC capture, port F */
2087 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2088 {},
2089 };
2090
2091 snd_hda_sequence_write(codec, enable_dc_mode);
2092 /* port B input disabled (and bias set) through the following call */
2093 cxt5066_set_olpc_dc_bias(codec);
2094 return;
2095 }
2096
2097 /* disable DC (port F) */
2098 snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
2099
2100 /* external mic, port B */
2101 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
2102 spec->ext_mic_present ? CXT5066_OLPC_EXT_MIC_BIAS : 0);
2103
2104 /* internal mic, port C */
2105 snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
2106 spec->ext_mic_present ? 0 : PIN_VREF80);
2107}
2108
1969/* toggle input of built-in and mic jack appropriately */ 2109/* toggle input of built-in and mic jack appropriately */
1970static void cxt5066_automic(struct hda_codec *codec) 2110static void cxt5066_olpc_automic(struct hda_codec *codec)
1971{ 2111{
1972 struct conexant_spec *spec = codec->spec; 2112 struct conexant_spec *spec = codec->spec;
2113 unsigned int present;
2114
2115 if (spec->dc_enable) /* don't do presence detection in DC mode */
2116 return;
2117
2118 present = snd_hda_codec_read(codec, 0x1a, 0,
2119 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2120 if (present)
2121 snd_printdd("CXT5066: external microphone detected\n");
2122 else
2123 snd_printdd("CXT5066: external microphone absent\n");
2124
2125 snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_CONNECT_SEL,
2126 present ? 0 : 1);
2127 spec->ext_mic_present = !!present;
2128
2129 cxt5066_olpc_select_mic(codec);
2130}
2131
2132/* toggle input of built-in digital mic and mic jack appropriately */
2133static void cxt5066_vostro_automic(struct hda_codec *codec)
2134{
2135 unsigned int present;
2136
1973 struct hda_verb ext_mic_present[] = { 2137 struct hda_verb ext_mic_present[] = {
1974 /* enable external mic, port B */ 2138 /* enable external mic, port B */
1975 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, spec->ext_mic_bias}, 2139 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1976 2140
1977 /* switch to external mic input */ 2141 /* switch to external mic input */
1978 {0x17, AC_VERB_SET_CONNECT_SEL, 0}, 2142 {0x17, AC_VERB_SET_CONNECT_SEL, 0},
2143 {0x14, AC_VERB_SET_CONNECT_SEL, 0},
1979 2144
1980 /* disable internal mic, port C */ 2145 /* disable internal digital mic */
1981 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2146 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
1982 {} 2147 {}
1983 }; 2148 };
1984 static struct hda_verb ext_mic_absent[] = { 2149 static struct hda_verb ext_mic_absent[] = {
1985 /* enable internal mic, port C */ 2150 /* enable internal mic, port C */
1986 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2151 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1987 2152
1988 /* switch to internal mic input */ 2153 /* switch to internal mic input */
1989 {0x17, AC_VERB_SET_CONNECT_SEL, 1}, 2154 {0x14, AC_VERB_SET_CONNECT_SEL, 2},
1990 2155
1991 /* disable external mic, port B */ 2156 /* disable external mic, port B */
1992 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2157 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
1993 {} 2158 {}
1994 }; 2159 };
1995 unsigned int present;
1996 2160
1997 present = snd_hda_jack_detect(codec, 0x1a); 2161 present = snd_hda_jack_detect(codec, 0x1a);
1998 if (present) { 2162 if (present) {
@@ -2005,36 +2169,24 @@ static void cxt5066_automic(struct hda_codec *codec)
2005} 2169}
2006 2170
2007/* toggle input of built-in digital mic and mic jack appropriately */ 2171/* toggle input of built-in digital mic and mic jack appropriately */
2008static void cxt5066_vostro_automic(struct hda_codec *codec) 2172static void cxt5066_ideapad_automic(struct hda_codec *codec)
2009{ 2173{
2010 struct conexant_spec *spec = codec->spec;
2011 unsigned int present; 2174 unsigned int present;
2012 2175
2013 struct hda_verb ext_mic_present[] = { 2176 struct hda_verb ext_mic_present[] = {
2014 /* enable external mic, port B */
2015 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, spec->ext_mic_bias},
2016
2017 /* switch to external mic input */
2018 {0x17, AC_VERB_SET_CONNECT_SEL, 0},
2019 {0x14, AC_VERB_SET_CONNECT_SEL, 0}, 2177 {0x14, AC_VERB_SET_CONNECT_SEL, 0},
2020 2178 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2021 /* disable internal digital mic */
2022 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2179 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2023 {} 2180 {}
2024 }; 2181 };
2025 static struct hda_verb ext_mic_absent[] = { 2182 static struct hda_verb ext_mic_absent[] = {
2026 /* enable internal mic, port C */
2027 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2028
2029 /* switch to internal mic input */
2030 {0x14, AC_VERB_SET_CONNECT_SEL, 2}, 2183 {0x14, AC_VERB_SET_CONNECT_SEL, 2},
2031 2184 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2032 /* disable external mic, port B */ 2185 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2033 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2034 {} 2186 {}
2035 }; 2187 };
2036 2188
2037 present = snd_hda_jack_detect(codec, 0x1a); 2189 present = snd_hda_jack_detect(codec, 0x1b);
2038 if (present) { 2190 if (present) {
2039 snd_printdd("CXT5066: external microphone detected\n"); 2191 snd_printdd("CXT5066: external microphone detected\n");
2040 snd_hda_sequence_write(codec, ext_mic_present); 2192 snd_hda_sequence_write(codec, ext_mic_present);
@@ -2063,15 +2215,18 @@ static void cxt5066_hp_automute(struct hda_codec *codec)
2063} 2215}
2064 2216
2065/* unsolicited event for jack sensing */ 2217/* unsolicited event for jack sensing */
2066static void cxt5066_unsol_event(struct hda_codec *codec, unsigned int res) 2218static void cxt5066_olpc_unsol_event(struct hda_codec *codec, unsigned int res)
2067{ 2219{
2220 struct conexant_spec *spec = codec->spec;
2068 snd_printdd("CXT5066: unsol event %x (%x)\n", res, res >> 26); 2221 snd_printdd("CXT5066: unsol event %x (%x)\n", res, res >> 26);
2069 switch (res >> 26) { 2222 switch (res >> 26) {
2070 case CONEXANT_HP_EVENT: 2223 case CONEXANT_HP_EVENT:
2071 cxt5066_hp_automute(codec); 2224 cxt5066_hp_automute(codec);
2072 break; 2225 break;
2073 case CONEXANT_MIC_EVENT: 2226 case CONEXANT_MIC_EVENT:
2074 cxt5066_automic(codec); 2227 /* ignore mic events in DC mode; we're always using the jack */
2228 if (!spec->dc_enable)
2229 cxt5066_olpc_automic(codec);
2075 break; 2230 break;
2076 } 2231 }
2077} 2232}
@@ -2090,6 +2245,20 @@ static void cxt5066_vostro_event(struct hda_codec *codec, unsigned int res)
2090 } 2245 }
2091} 2246}
2092 2247
2248/* unsolicited event for jack sensing */
2249static void cxt5066_ideapad_event(struct hda_codec *codec, unsigned int res)
2250{
2251 snd_printdd("CXT5066_ideapad: unsol event %x (%x)\n", res, res >> 26);
2252 switch (res >> 26) {
2253 case CONEXANT_HP_EVENT:
2254 cxt5066_hp_automute(codec);
2255 break;
2256 case CONEXANT_MIC_EVENT:
2257 cxt5066_ideapad_automic(codec);
2258 break;
2259 }
2260}
2261
2093static const struct hda_input_mux cxt5066_analog_mic_boost = { 2262static const struct hda_input_mux cxt5066_analog_mic_boost = {
2094 .num_items = 5, 2263 .num_items = 5,
2095 .items = { 2264 .items = {
@@ -2101,6 +2270,23 @@ static const struct hda_input_mux cxt5066_analog_mic_boost = {
2101 }, 2270 },
2102}; 2271};
2103 2272
2273static void cxt5066_set_mic_boost(struct hda_codec *codec)
2274{
2275 struct conexant_spec *spec = codec->spec;
2276 snd_hda_codec_write_cache(codec, 0x17, 0,
2277 AC_VERB_SET_AMP_GAIN_MUTE,
2278 AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_OUTPUT |
2279 cxt5066_analog_mic_boost.items[spec->mic_boost].index);
2280 if (spec->ideapad) {
2281 /* adjust the internal mic as well...it is not through 0x17 */
2282 snd_hda_codec_write_cache(codec, 0x23, 0,
2283 AC_VERB_SET_AMP_GAIN_MUTE,
2284 AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_INPUT |
2285 cxt5066_analog_mic_boost.
2286 items[spec->mic_boost].index);
2287 }
2288}
2289
2104static int cxt5066_mic_boost_mux_enum_info(struct snd_kcontrol *kcontrol, 2290static int cxt5066_mic_boost_mux_enum_info(struct snd_kcontrol *kcontrol,
2105 struct snd_ctl_elem_info *uinfo) 2291 struct snd_ctl_elem_info *uinfo)
2106{ 2292{
@@ -2111,15 +2297,8 @@ static int cxt5066_mic_boost_mux_enum_get(struct snd_kcontrol *kcontrol,
2111 struct snd_ctl_elem_value *ucontrol) 2297 struct snd_ctl_elem_value *ucontrol)
2112{ 2298{
2113 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2299 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2114 int val; 2300 struct conexant_spec *spec = codec->spec;
2115 hda_nid_t nid = kcontrol->private_value & 0xff; 2301 ucontrol->value.enumerated.item[0] = spec->mic_boost;
2116 int inout = (kcontrol->private_value & 0x100) ?
2117 AC_AMP_GET_INPUT : AC_AMP_GET_OUTPUT;
2118
2119 val = snd_hda_codec_read(codec, nid, 0,
2120 AC_VERB_GET_AMP_GAIN_MUTE, inout);
2121
2122 ucontrol->value.enumerated.item[0] = val & AC_AMP_GAIN;
2123 return 0; 2302 return 0;
2124} 2303}
2125 2304
@@ -2127,26 +2306,132 @@ static int cxt5066_mic_boost_mux_enum_put(struct snd_kcontrol *kcontrol,
2127 struct snd_ctl_elem_value *ucontrol) 2306 struct snd_ctl_elem_value *ucontrol)
2128{ 2307{
2129 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2308 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2309 struct conexant_spec *spec = codec->spec;
2130 const struct hda_input_mux *imux = &cxt5066_analog_mic_boost; 2310 const struct hda_input_mux *imux = &cxt5066_analog_mic_boost;
2131 unsigned int idx; 2311 unsigned int idx;
2132 hda_nid_t nid = kcontrol->private_value & 0xff; 2312 idx = ucontrol->value.enumerated.item[0];
2133 int inout = (kcontrol->private_value & 0x100) ? 2313 if (idx >= imux->num_items)
2134 AC_AMP_SET_INPUT : AC_AMP_SET_OUTPUT; 2314 idx = imux->num_items - 1;
2315
2316 spec->mic_boost = idx;
2317 if (!spec->dc_enable)
2318 cxt5066_set_mic_boost(codec);
2319 return 1;
2320}
2321
2322static void cxt5066_enable_dc(struct hda_codec *codec)
2323{
2324 const struct hda_verb enable_dc_mode[] = {
2325 /* disable gain */
2326 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2327
2328 /* switch to DC input */
2329 {0x17, AC_VERB_SET_CONNECT_SEL, 3},
2330 {}
2331 };
2332
2333 /* configure as input source */
2334 snd_hda_sequence_write(codec, enable_dc_mode);
2335 cxt5066_olpc_select_mic(codec); /* also sets configured bias */
2336}
2337
2338static void cxt5066_disable_dc(struct hda_codec *codec)
2339{
2340 /* reconfigure input source */
2341 cxt5066_set_mic_boost(codec);
2342 /* automic also selects the right mic if we're recording */
2343 cxt5066_olpc_automic(codec);
2344}
2345
2346static int cxt5066_olpc_dc_get(struct snd_kcontrol *kcontrol,
2347 struct snd_ctl_elem_value *ucontrol)
2348{
2349 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2350 struct conexant_spec *spec = codec->spec;
2351 ucontrol->value.integer.value[0] = spec->dc_enable;
2352 return 0;
2353}
2135 2354
2136 if (!imux->num_items) 2355static int cxt5066_olpc_dc_put(struct snd_kcontrol *kcontrol,
2356 struct snd_ctl_elem_value *ucontrol)
2357{
2358 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2359 struct conexant_spec *spec = codec->spec;
2360 int dc_enable = !!ucontrol->value.integer.value[0];
2361
2362 if (dc_enable == spec->dc_enable)
2137 return 0; 2363 return 0;
2364
2365 spec->dc_enable = dc_enable;
2366 if (dc_enable)
2367 cxt5066_enable_dc(codec);
2368 else
2369 cxt5066_disable_dc(codec);
2370
2371 return 1;
2372}
2373
2374static int cxt5066_olpc_dc_bias_enum_info(struct snd_kcontrol *kcontrol,
2375 struct snd_ctl_elem_info *uinfo)
2376{
2377 return snd_hda_input_mux_info(&cxt5066_olpc_dc_bias, uinfo);
2378}
2379
2380static int cxt5066_olpc_dc_bias_enum_get(struct snd_kcontrol *kcontrol,
2381 struct snd_ctl_elem_value *ucontrol)
2382{
2383 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2384 struct conexant_spec *spec = codec->spec;
2385 ucontrol->value.enumerated.item[0] = spec->dc_input_bias;
2386 return 0;
2387}
2388
2389static int cxt5066_olpc_dc_bias_enum_put(struct snd_kcontrol *kcontrol,
2390 struct snd_ctl_elem_value *ucontrol)
2391{
2392 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2393 struct conexant_spec *spec = codec->spec;
2394 const struct hda_input_mux *imux = &cxt5066_analog_mic_boost;
2395 unsigned int idx;
2396
2138 idx = ucontrol->value.enumerated.item[0]; 2397 idx = ucontrol->value.enumerated.item[0];
2139 if (idx >= imux->num_items) 2398 if (idx >= imux->num_items)
2140 idx = imux->num_items - 1; 2399 idx = imux->num_items - 1;
2141 2400
2142 snd_hda_codec_write_cache(codec, nid, 0, 2401 spec->dc_input_bias = idx;
2143 AC_VERB_SET_AMP_GAIN_MUTE, 2402 if (spec->dc_enable)
2144 AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | inout | 2403 cxt5066_set_olpc_dc_bias(codec);
2145 imux->items[idx].index);
2146
2147 return 1; 2404 return 1;
2148} 2405}
2149 2406
2407static void cxt5066_olpc_capture_prepare(struct hda_codec *codec)
2408{
2409 struct conexant_spec *spec = codec->spec;
2410 /* mark as recording and configure the microphone widget so that the
2411 * recording LED comes on. */
2412 spec->recording = 1;
2413 cxt5066_olpc_select_mic(codec);
2414}
2415
2416static void cxt5066_olpc_capture_cleanup(struct hda_codec *codec)
2417{
2418 struct conexant_spec *spec = codec->spec;
2419 const struct hda_verb disable_mics[] = {
2420 /* disable external mic, port B */
2421 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2422
2423 /* disble internal mic, port C */
2424 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2425
2426 /* disable DC capture, port F */
2427 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2428 {},
2429 };
2430
2431 snd_hda_sequence_write(codec, disable_mics);
2432 spec->recording = 0;
2433}
2434
2150static struct hda_input_mux cxt5066_capture_source = { 2435static struct hda_input_mux cxt5066_capture_source = {
2151 .num_items = 4, 2436 .num_items = 4,
2152 .items = { 2437 .items = {
@@ -2187,6 +2472,7 @@ static struct snd_kcontrol_new cxt5066_mixer_master_olpc[] = {
2187 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | 2472 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
2188 SNDRV_CTL_ELEM_ACCESS_TLV_READ | 2473 SNDRV_CTL_ELEM_ACCESS_TLV_READ |
2189 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, 2474 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK,
2475 .subdevice = HDA_SUBDEV_AMP_FLAG,
2190 .info = snd_hda_mixer_amp_volume_info, 2476 .info = snd_hda_mixer_amp_volume_info,
2191 .get = snd_hda_mixer_amp_volume_get, 2477 .get = snd_hda_mixer_amp_volume_get,
2192 .put = snd_hda_mixer_amp_volume_put, 2478 .put = snd_hda_mixer_amp_volume_put,
@@ -2198,6 +2484,24 @@ static struct snd_kcontrol_new cxt5066_mixer_master_olpc[] = {
2198 {} 2484 {}
2199}; 2485};
2200 2486
2487static struct snd_kcontrol_new cxt5066_mixer_olpc_dc[] = {
2488 {
2489 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2490 .name = "DC Mode Enable Switch",
2491 .info = snd_ctl_boolean_mono_info,
2492 .get = cxt5066_olpc_dc_get,
2493 .put = cxt5066_olpc_dc_put,
2494 },
2495 {
2496 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2497 .name = "DC Input Bias Enum",
2498 .info = cxt5066_olpc_dc_bias_enum_info,
2499 .get = cxt5066_olpc_dc_bias_enum_get,
2500 .put = cxt5066_olpc_dc_bias_enum_put,
2501 },
2502 {}
2503};
2504
2201static struct snd_kcontrol_new cxt5066_mixers[] = { 2505static struct snd_kcontrol_new cxt5066_mixers[] = {
2202 { 2506 {
2203 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2507 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -2210,11 +2514,10 @@ static struct snd_kcontrol_new cxt5066_mixers[] = {
2210 2514
2211 { 2515 {
2212 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2516 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2213 .name = "Ext Mic Boost Capture Enum", 2517 .name = "Analog Mic Boost Capture Enum",
2214 .info = cxt5066_mic_boost_mux_enum_info, 2518 .info = cxt5066_mic_boost_mux_enum_info,
2215 .get = cxt5066_mic_boost_mux_enum_get, 2519 .get = cxt5066_mic_boost_mux_enum_get,
2216 .put = cxt5066_mic_boost_mux_enum_put, 2520 .put = cxt5066_mic_boost_mux_enum_put,
2217 .private_value = 0x17,
2218 }, 2521 },
2219 2522
2220 HDA_BIND_VOL("Capture Volume", &cxt5066_bind_capture_vol_others), 2523 HDA_BIND_VOL("Capture Volume", &cxt5066_bind_capture_vol_others),
@@ -2296,10 +2599,10 @@ static struct hda_verb cxt5066_init_verbs_olpc[] = {
2296 {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ 2599 {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2297 2600
2298 /* Port B: external microphone */ 2601 /* Port B: external microphone */
2299 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, CXT5066_OLPC_EXT_MIC_BIAS}, 2602 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2300 2603
2301 /* Port C: internal microphone */ 2604 /* Port C: internal microphone */
2302 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2605 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2303 2606
2304 /* Port D: unused */ 2607 /* Port D: unused */
2305 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2608 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
@@ -2308,7 +2611,7 @@ static struct hda_verb cxt5066_init_verbs_olpc[] = {
2308 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2611 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2309 {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ 2612 {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
2310 2613
2311 /* Port F: unused */ 2614 /* Port F: external DC input through microphone port */
2312 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2615 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2313 2616
2314 /* Port G: internal speakers */ 2617 /* Port G: internal speakers */
@@ -2412,6 +2715,56 @@ static struct hda_verb cxt5066_init_verbs_vostro[] = {
2412 { } /* end */ 2715 { } /* end */
2413}; 2716};
2414 2717
2718static struct hda_verb cxt5066_init_verbs_ideapad[] = {
2719 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */
2720 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */
2721 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */
2722 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port E */
2723
2724 /* Speakers */
2725 {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2726 {0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2727
2728 /* HP, Amp */
2729 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2730 {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2731
2732 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2733 {0x1c, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2734
2735 /* DAC1 */
2736 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2737
2738 /* Node 14 connections: 0x17 0x18 0x23 0x24 0x27 */
2739 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x50},
2740 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2741 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2) | 0x50},
2742 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2743 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2744 {0x14, AC_VERB_SET_CONNECT_SEL, 2}, /* default to internal mic */
2745
2746 /* Audio input selector */
2747 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x2},
2748 {0x17, AC_VERB_SET_CONNECT_SEL, 1}, /* route ext mic */
2749
2750 /* SPDIF route: PCM */
2751 {0x20, AC_VERB_SET_CONNECT_SEL, 0x0},
2752 {0x22, AC_VERB_SET_CONNECT_SEL, 0x0},
2753
2754 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2755 {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2756
2757 /* internal microphone */
2758 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* enable int mic */
2759
2760 /* EAPD */
2761 {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
2762
2763 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
2764 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
2765 { } /* end */
2766};
2767
2415static struct hda_verb cxt5066_init_verbs_portd_lo[] = { 2768static struct hda_verb cxt5066_init_verbs_portd_lo[] = {
2416 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2769 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2417 { } /* end */ 2770 { } /* end */
@@ -2428,8 +2781,24 @@ static int cxt5066_init(struct hda_codec *codec)
2428 cxt5066_hp_automute(codec); 2781 cxt5066_hp_automute(codec);
2429 if (spec->dell_vostro) 2782 if (spec->dell_vostro)
2430 cxt5066_vostro_automic(codec); 2783 cxt5066_vostro_automic(codec);
2431 else 2784 else if (spec->ideapad)
2432 cxt5066_automic(codec); 2785 cxt5066_ideapad_automic(codec);
2786 }
2787 cxt5066_set_mic_boost(codec);
2788 return 0;
2789}
2790
2791static int cxt5066_olpc_init(struct hda_codec *codec)
2792{
2793 struct conexant_spec *spec = codec->spec;
2794 snd_printdd("CXT5066: init\n");
2795 conexant_init(codec);
2796 cxt5066_hp_automute(codec);
2797 if (!spec->dc_enable) {
2798 cxt5066_set_mic_boost(codec);
2799 cxt5066_olpc_automic(codec);
2800 } else {
2801 cxt5066_enable_dc(codec);
2433 } 2802 }
2434 return 0; 2803 return 0;
2435} 2804}
@@ -2439,6 +2808,7 @@ enum {
2439 CXT5066_DELL_LAPTOP, /* Dell Laptop */ 2808 CXT5066_DELL_LAPTOP, /* Dell Laptop */
2440 CXT5066_OLPC_XO_1_5, /* OLPC XO 1.5 */ 2809 CXT5066_OLPC_XO_1_5, /* OLPC XO 1.5 */
2441 CXT5066_DELL_VOSTO, /* Dell Vostro 1015i */ 2810 CXT5066_DELL_VOSTO, /* Dell Vostro 1015i */
2811 CXT5066_IDEAPAD, /* Lenovo IdeaPad U150 */
2442 CXT5066_MODELS 2812 CXT5066_MODELS
2443}; 2813};
2444 2814
@@ -2446,7 +2816,8 @@ static const char *cxt5066_models[CXT5066_MODELS] = {
2446 [CXT5066_LAPTOP] = "laptop", 2816 [CXT5066_LAPTOP] = "laptop",
2447 [CXT5066_DELL_LAPTOP] = "dell-laptop", 2817 [CXT5066_DELL_LAPTOP] = "dell-laptop",
2448 [CXT5066_OLPC_XO_1_5] = "olpc-xo-1_5", 2818 [CXT5066_OLPC_XO_1_5] = "olpc-xo-1_5",
2449 [CXT5066_DELL_VOSTO] = "dell-vostro" 2819 [CXT5066_DELL_VOSTO] = "dell-vostro",
2820 [CXT5066_IDEAPAD] = "ideapad",
2450}; 2821};
2451 2822
2452static struct snd_pci_quirk cxt5066_cfg_tbl[] = { 2823static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
@@ -2456,6 +2827,7 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
2456 CXT5066_DELL_LAPTOP), 2827 CXT5066_DELL_LAPTOP),
2457 SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5), 2828 SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5),
2458 SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTO), 2829 SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTO),
2830 SND_PCI_QUIRK(0x17aa, 0x3a0d, "ideapad", CXT5066_IDEAPAD),
2459 {} 2831 {}
2460}; 2832};
2461 2833
@@ -2470,7 +2842,7 @@ static int patch_cxt5066(struct hda_codec *codec)
2470 codec->spec = spec; 2842 codec->spec = spec;
2471 2843
2472 codec->patch_ops = conexant_patch_ops; 2844 codec->patch_ops = conexant_patch_ops;
2473 codec->patch_ops.init = cxt5066_init; 2845 codec->patch_ops.init = conexant_init;
2474 2846
2475 spec->dell_automute = 0; 2847 spec->dell_automute = 0;
2476 spec->multiout.max_channels = 2; 2848 spec->multiout.max_channels = 2;
@@ -2483,7 +2855,6 @@ static int patch_cxt5066(struct hda_codec *codec)
2483 spec->input_mux = &cxt5066_capture_source; 2855 spec->input_mux = &cxt5066_capture_source;
2484 2856
2485 spec->port_d_mode = PIN_HP; 2857 spec->port_d_mode = PIN_HP;
2486 spec->ext_mic_bias = PIN_VREF80;
2487 2858
2488 spec->num_init_verbs = 1; 2859 spec->num_init_verbs = 1;
2489 spec->init_verbs[0] = cxt5066_init_verbs; 2860 spec->init_verbs[0] = cxt5066_init_verbs;
@@ -2510,20 +2881,28 @@ static int patch_cxt5066(struct hda_codec *codec)
2510 spec->dell_automute = 1; 2881 spec->dell_automute = 1;
2511 break; 2882 break;
2512 case CXT5066_OLPC_XO_1_5: 2883 case CXT5066_OLPC_XO_1_5:
2513 codec->patch_ops.unsol_event = cxt5066_unsol_event; 2884 codec->patch_ops.init = cxt5066_olpc_init;
2885 codec->patch_ops.unsol_event = cxt5066_olpc_unsol_event;
2514 spec->init_verbs[0] = cxt5066_init_verbs_olpc; 2886 spec->init_verbs[0] = cxt5066_init_verbs_olpc;
2515 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc; 2887 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc;
2888 spec->mixers[spec->num_mixers++] = cxt5066_mixer_olpc_dc;
2516 spec->mixers[spec->num_mixers++] = cxt5066_mixers; 2889 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
2517 spec->port_d_mode = 0; 2890 spec->port_d_mode = 0;
2518 spec->ext_mic_bias = CXT5066_OLPC_EXT_MIC_BIAS; 2891 spec->mic_boost = 3; /* default 30dB gain */
2519 2892
2520 /* no S/PDIF out */ 2893 /* no S/PDIF out */
2521 spec->multiout.dig_out_nid = 0; 2894 spec->multiout.dig_out_nid = 0;
2522 2895
2523 /* input source automatically selected */ 2896 /* input source automatically selected */
2524 spec->input_mux = NULL; 2897 spec->input_mux = NULL;
2898
2899 /* our capture hooks which allow us to turn on the microphone LED
2900 * at the right time */
2901 spec->capture_prepare = cxt5066_olpc_capture_prepare;
2902 spec->capture_cleanup = cxt5066_olpc_capture_cleanup;
2525 break; 2903 break;
2526 case CXT5066_DELL_VOSTO: 2904 case CXT5066_DELL_VOSTO:
2905 codec->patch_ops.init = cxt5066_init;
2527 codec->patch_ops.unsol_event = cxt5066_vostro_event; 2906 codec->patch_ops.unsol_event = cxt5066_vostro_event;
2528 spec->init_verbs[0] = cxt5066_init_verbs_vostro; 2907 spec->init_verbs[0] = cxt5066_init_verbs_vostro;
2529 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc; 2908 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc;
@@ -2531,6 +2910,7 @@ static int patch_cxt5066(struct hda_codec *codec)
2531 spec->mixers[spec->num_mixers++] = cxt5066_vostro_mixers; 2910 spec->mixers[spec->num_mixers++] = cxt5066_vostro_mixers;
2532 spec->port_d_mode = 0; 2911 spec->port_d_mode = 0;
2533 spec->dell_vostro = 1; 2912 spec->dell_vostro = 1;
2913 spec->mic_boost = 3; /* default 30dB gain */
2534 snd_hda_attach_beep_device(codec, 0x13); 2914 snd_hda_attach_beep_device(codec, 0x13);
2535 2915
2536 /* no S/PDIF out */ 2916 /* no S/PDIF out */
@@ -2539,6 +2919,22 @@ static int patch_cxt5066(struct hda_codec *codec)
2539 /* input source automatically selected */ 2919 /* input source automatically selected */
2540 spec->input_mux = NULL; 2920 spec->input_mux = NULL;
2541 break; 2921 break;
2922 case CXT5066_IDEAPAD:
2923 codec->patch_ops.init = cxt5066_init;
2924 codec->patch_ops.unsol_event = cxt5066_ideapad_event;
2925 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
2926 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
2927 spec->init_verbs[0] = cxt5066_init_verbs_ideapad;
2928 spec->port_d_mode = 0;
2929 spec->ideapad = 1;
2930 spec->mic_boost = 2; /* default 20dB gain */
2931
2932 /* no S/PDIF out */
2933 spec->multiout.dig_out_nid = 0;
2934
2935 /* input source automatically selected */
2936 spec->input_mux = NULL;
2937 break;
2542 } 2938 }
2543 2939
2544 return 0; 2940 return 0;
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index da34095c707f..e8cbe216e912 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -131,8 +131,10 @@ enum {
131enum { 131enum {
132 ALC269_BASIC, 132 ALC269_BASIC,
133 ALC269_QUANTA_FL1, 133 ALC269_QUANTA_FL1,
134 ALC269_ASUS_AMIC, 134 ALC269_AMIC,
135 ALC269_ASUS_DMIC, 135 ALC269_DMIC,
136 ALC269VB_AMIC,
137 ALC269VB_DMIC,
136 ALC269_FUJITSU, 138 ALC269_FUJITSU,
137 ALC269_LIFEBOOK, 139 ALC269_LIFEBOOK,
138 ALC269_AUTO, 140 ALC269_AUTO,
@@ -207,8 +209,10 @@ enum {
207 ALC882_ASUS_A7J, 209 ALC882_ASUS_A7J,
208 ALC882_ASUS_A7M, 210 ALC882_ASUS_A7M,
209 ALC885_MACPRO, 211 ALC885_MACPRO,
212 ALC885_MBA21,
210 ALC885_MBP3, 213 ALC885_MBP3,
211 ALC885_MB5, 214 ALC885_MB5,
215 ALC885_MACMINI3,
212 ALC885_IMAC24, 216 ALC885_IMAC24,
213 ALC885_IMAC91, 217 ALC885_IMAC91,
214 ALC883_3ST_2ch_DIG, 218 ALC883_3ST_2ch_DIG,
@@ -338,7 +342,7 @@ struct alc_spec {
338 void (*init_hook)(struct hda_codec *codec); 342 void (*init_hook)(struct hda_codec *codec);
339 void (*unsol_event)(struct hda_codec *codec, unsigned int res); 343 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
340#ifdef CONFIG_SND_HDA_POWER_SAVE 344#ifdef CONFIG_SND_HDA_POWER_SAVE
341 void (*power_hook)(struct hda_codec *codec, int power); 345 void (*power_hook)(struct hda_codec *codec);
342#endif 346#endif
343 347
344 /* for pin sensing */ 348 /* for pin sensing */
@@ -391,7 +395,7 @@ struct alc_config_preset {
391 void (*init_hook)(struct hda_codec *); 395 void (*init_hook)(struct hda_codec *);
392#ifdef CONFIG_SND_HDA_POWER_SAVE 396#ifdef CONFIG_SND_HDA_POWER_SAVE
393 struct hda_amp_list *loopbacks; 397 struct hda_amp_list *loopbacks;
394 void (*power_hook)(struct hda_codec *codec, int power); 398 void (*power_hook)(struct hda_codec *codec);
395#endif 399#endif
396}; 400};
397 401
@@ -633,6 +637,7 @@ static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
633 637
634#define ALC_PIN_MODE(xname, nid, dir) \ 638#define ALC_PIN_MODE(xname, nid, dir) \
635 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 639 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
640 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
636 .info = alc_pin_mode_info, \ 641 .info = alc_pin_mode_info, \
637 .get = alc_pin_mode_get, \ 642 .get = alc_pin_mode_get, \
638 .put = alc_pin_mode_put, \ 643 .put = alc_pin_mode_put, \
@@ -684,6 +689,7 @@ static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
684} 689}
685#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \ 690#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
686 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 691 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
692 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
687 .info = alc_gpio_data_info, \ 693 .info = alc_gpio_data_info, \
688 .get = alc_gpio_data_get, \ 694 .get = alc_gpio_data_get, \
689 .put = alc_gpio_data_put, \ 695 .put = alc_gpio_data_put, \
@@ -738,6 +744,7 @@ static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
738} 744}
739#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \ 745#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
740 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 746 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
747 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
741 .info = alc_spdif_ctrl_info, \ 748 .info = alc_spdif_ctrl_info, \
742 .get = alc_spdif_ctrl_get, \ 749 .get = alc_spdif_ctrl_get, \
743 .put = alc_spdif_ctrl_put, \ 750 .put = alc_spdif_ctrl_put, \
@@ -791,6 +798,7 @@ static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
791 798
792#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \ 799#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
793 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 800 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
801 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
794 .info = alc_eapd_ctrl_info, \ 802 .info = alc_eapd_ctrl_info, \
795 .get = alc_eapd_ctrl_get, \ 803 .get = alc_eapd_ctrl_get, \
796 .put = alc_eapd_ctrl_put, \ 804 .put = alc_eapd_ctrl_put, \
@@ -837,27 +845,6 @@ static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
837 spec->init_verbs[spec->num_init_verbs++] = verb; 845 spec->init_verbs[spec->num_init_verbs++] = verb;
838} 846}
839 847
840#ifdef CONFIG_PROC_FS
841/*
842 * hook for proc
843 */
844static void print_realtek_coef(struct snd_info_buffer *buffer,
845 struct hda_codec *codec, hda_nid_t nid)
846{
847 int coeff;
848
849 if (nid != 0x20)
850 return;
851 coeff = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
852 snd_iprintf(buffer, " Processing Coefficient: 0x%02x\n", coeff);
853 coeff = snd_hda_codec_read(codec, nid, 0,
854 AC_VERB_GET_COEF_INDEX, 0);
855 snd_iprintf(buffer, " Coefficient Index: 0x%02x\n", coeff);
856}
857#else
858#define print_realtek_coef NULL
859#endif
860
861/* 848/*
862 * set up from the preset table 849 * set up from the preset table
863 */ 850 */
@@ -1162,6 +1149,7 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type)
1162 case 0x10ec0888: 1149 case 0x10ec0888:
1163 alc888_coef_init(codec); 1150 alc888_coef_init(codec);
1164 break; 1151 break;
1152#if 0 /* XXX: This may cause the silent output on speaker on some machines */
1165 case 0x10ec0267: 1153 case 0x10ec0267:
1166 case 0x10ec0268: 1154 case 0x10ec0268:
1167 snd_hda_codec_write(codec, 0x20, 0, 1155 snd_hda_codec_write(codec, 0x20, 0,
@@ -1174,6 +1162,7 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type)
1174 AC_VERB_SET_PROC_COEF, 1162 AC_VERB_SET_PROC_COEF,
1175 tmp | 0x3000); 1163 tmp | 0x3000);
1176 break; 1164 break;
1165#endif /* XXX */
1177 } 1166 }
1178 break; 1167 break;
1179 } 1168 }
@@ -1265,7 +1254,7 @@ static void alc_init_auto_mic(struct hda_codec *codec)
1265 */ 1254 */
1266static int alc_subsystem_id(struct hda_codec *codec, 1255static int alc_subsystem_id(struct hda_codec *codec,
1267 hda_nid_t porta, hda_nid_t porte, 1256 hda_nid_t porta, hda_nid_t porte,
1268 hda_nid_t portd) 1257 hda_nid_t portd, hda_nid_t porti)
1269{ 1258{
1270 unsigned int ass, tmp, i; 1259 unsigned int ass, tmp, i;
1271 unsigned nid; 1260 unsigned nid;
@@ -1291,7 +1280,7 @@ static int alc_subsystem_id(struct hda_codec *codec,
1291 snd_printd("realtek: No valid SSID, " 1280 snd_printd("realtek: No valid SSID, "
1292 "checking pincfg 0x%08x for NID 0x%x\n", 1281 "checking pincfg 0x%08x for NID 0x%x\n",
1293 ass, nid); 1282 ass, nid);
1294 if (!(ass & 1) && !(ass & 0x100000)) 1283 if (!(ass & 1))
1295 return 0; 1284 return 0;
1296 if ((ass >> 30) != 1) /* no physical connection */ 1285 if ((ass >> 30) != 1) /* no physical connection */
1297 return 0; 1286 return 0;
@@ -1351,6 +1340,8 @@ do_sku:
1351 nid = porte; 1340 nid = porte;
1352 else if (tmp == 2) 1341 else if (tmp == 2)
1353 nid = portd; 1342 nid = portd;
1343 else if (tmp == 3)
1344 nid = porti;
1354 else 1345 else
1355 return 1; 1346 return 1;
1356 for (i = 0; i < spec->autocfg.line_outs; i++) 1347 for (i = 0; i < spec->autocfg.line_outs; i++)
@@ -1365,9 +1356,10 @@ do_sku:
1365} 1356}
1366 1357
1367static void alc_ssid_check(struct hda_codec *codec, 1358static void alc_ssid_check(struct hda_codec *codec,
1368 hda_nid_t porta, hda_nid_t porte, hda_nid_t portd) 1359 hda_nid_t porta, hda_nid_t porte,
1360 hda_nid_t portd, hda_nid_t porti)
1369{ 1361{
1370 if (!alc_subsystem_id(codec, porta, porte, portd)) { 1362 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) {
1371 struct alc_spec *spec = codec->spec; 1363 struct alc_spec *spec = codec->spec;
1372 snd_printd("realtek: " 1364 snd_printd("realtek: "
1373 "Enable default setup for auto mode as fallback\n"); 1365 "Enable default setup for auto mode as fallback\n");
@@ -1840,14 +1832,6 @@ static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
1840 spec->autocfg.speaker_pins[2] = 0x1b; 1832 spec->autocfg.speaker_pins[2] = 0x1b;
1841} 1833}
1842 1834
1843#ifdef CONFIG_SND_HDA_POWER_SAVE
1844static void alc889_power_eapd(struct hda_codec *codec, int power)
1845{
1846 set_eapd(codec, 0x14, power);
1847 set_eapd(codec, 0x15, power);
1848}
1849#endif
1850
1851/* 1835/*
1852 * ALC880 3-stack model 1836 * ALC880 3-stack model
1853 * 1837 *
@@ -2450,6 +2434,15 @@ static const char *alc_slave_sws[] = {
2450 * build control elements 2434 * build control elements
2451 */ 2435 */
2452 2436
2437#define NID_MAPPING (-1)
2438
2439#define SUBDEV_SPEAKER_ (0 << 6)
2440#define SUBDEV_HP_ (1 << 6)
2441#define SUBDEV_LINE_ (2 << 6)
2442#define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f))
2443#define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f))
2444#define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f))
2445
2453static void alc_free_kctls(struct hda_codec *codec); 2446static void alc_free_kctls(struct hda_codec *codec);
2454 2447
2455#ifdef CONFIG_SND_HDA_INPUT_BEEP 2448#ifdef CONFIG_SND_HDA_INPUT_BEEP
@@ -2464,8 +2457,11 @@ static struct snd_kcontrol_new alc_beep_mixer[] = {
2464static int alc_build_controls(struct hda_codec *codec) 2457static int alc_build_controls(struct hda_codec *codec)
2465{ 2458{
2466 struct alc_spec *spec = codec->spec; 2459 struct alc_spec *spec = codec->spec;
2467 int err; 2460 struct snd_kcontrol *kctl;
2468 int i; 2461 struct snd_kcontrol_new *knew;
2462 int i, j, err;
2463 unsigned int u;
2464 hda_nid_t nid;
2469 2465
2470 for (i = 0; i < spec->num_mixers; i++) { 2466 for (i = 0; i < spec->num_mixers; i++) {
2471 err = snd_hda_add_new_ctls(codec, spec->mixers[i]); 2467 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
@@ -2506,8 +2502,7 @@ static int alc_build_controls(struct hda_codec *codec)
2506 if (!kctl) 2502 if (!kctl)
2507 return -ENOMEM; 2503 return -ENOMEM;
2508 kctl->private_value = spec->beep_amp; 2504 kctl->private_value = spec->beep_amp;
2509 err = snd_hda_ctl_add(codec, 2505 err = snd_hda_ctl_add(codec, 0, kctl);
2510 get_amp_nid_(spec->beep_amp), kctl);
2511 if (err < 0) 2506 if (err < 0)
2512 return err; 2507 return err;
2513 } 2508 }
@@ -2534,6 +2529,75 @@ static int alc_build_controls(struct hda_codec *codec)
2534 } 2529 }
2535 2530
2536 alc_free_kctls(codec); /* no longer needed */ 2531 alc_free_kctls(codec); /* no longer needed */
2532
2533 /* assign Capture Source enums to NID */
2534 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
2535 if (!kctl)
2536 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
2537 for (i = 0; kctl && i < kctl->count; i++) {
2538 hda_nid_t *nids = spec->capsrc_nids;
2539 if (!nids)
2540 nids = spec->adc_nids;
2541 err = snd_hda_add_nid(codec, kctl, i, nids[i]);
2542 if (err < 0)
2543 return err;
2544 }
2545 if (spec->cap_mixer) {
2546 const char *kname = kctl ? kctl->id.name : NULL;
2547 for (knew = spec->cap_mixer; knew->name; knew++) {
2548 if (kname && strcmp(knew->name, kname) == 0)
2549 continue;
2550 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
2551 for (i = 0; kctl && i < kctl->count; i++) {
2552 err = snd_hda_add_nid(codec, kctl, i,
2553 spec->adc_nids[i]);
2554 if (err < 0)
2555 return err;
2556 }
2557 }
2558 }
2559
2560 /* other nid->control mapping */
2561 for (i = 0; i < spec->num_mixers; i++) {
2562 for (knew = spec->mixers[i]; knew->name; knew++) {
2563 if (knew->iface != NID_MAPPING)
2564 continue;
2565 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
2566 if (kctl == NULL)
2567 continue;
2568 u = knew->subdevice;
2569 for (j = 0; j < 4; j++, u >>= 8) {
2570 nid = u & 0x3f;
2571 if (nid == 0)
2572 continue;
2573 switch (u & 0xc0) {
2574 case SUBDEV_SPEAKER_:
2575 nid = spec->autocfg.speaker_pins[nid];
2576 break;
2577 case SUBDEV_LINE_:
2578 nid = spec->autocfg.line_out_pins[nid];
2579 break;
2580 case SUBDEV_HP_:
2581 nid = spec->autocfg.hp_pins[nid];
2582 break;
2583 default:
2584 continue;
2585 }
2586 err = snd_hda_add_nid(codec, kctl, 0, nid);
2587 if (err < 0)
2588 return err;
2589 }
2590 u = knew->private_value;
2591 for (j = 0; j < 4; j++, u >>= 8) {
2592 nid = u & 0xff;
2593 if (nid == 0)
2594 continue;
2595 err = snd_hda_add_nid(codec, kctl, 0, nid);
2596 if (err < 0)
2597 return err;
2598 }
2599 }
2600 }
2537 return 0; 2601 return 0;
2538} 2602}
2539 2603
@@ -3616,6 +3680,11 @@ static int alc_build_pcms(struct hda_codec *codec)
3616 return 0; 3680 return 0;
3617} 3681}
3618 3682
3683static inline void alc_shutup(struct hda_codec *codec)
3684{
3685 snd_hda_shutup_pins(codec);
3686}
3687
3619static void alc_free_kctls(struct hda_codec *codec) 3688static void alc_free_kctls(struct hda_codec *codec)
3620{ 3689{
3621 struct alc_spec *spec = codec->spec; 3690 struct alc_spec *spec = codec->spec;
@@ -3636,17 +3705,44 @@ static void alc_free(struct hda_codec *codec)
3636 if (!spec) 3705 if (!spec)
3637 return; 3706 return;
3638 3707
3708 alc_shutup(codec);
3639 alc_free_kctls(codec); 3709 alc_free_kctls(codec);
3640 kfree(spec); 3710 kfree(spec);
3641 snd_hda_detach_beep_device(codec); 3711 snd_hda_detach_beep_device(codec);
3642} 3712}
3643 3713
3644#ifdef CONFIG_SND_HDA_POWER_SAVE 3714#ifdef CONFIG_SND_HDA_POWER_SAVE
3715static void alc_power_eapd(struct hda_codec *codec)
3716{
3717 /* We currently only handle front, HP */
3718 switch (codec->vendor_id) {
3719 case 0x10ec0260:
3720 set_eapd(codec, 0x0f, 0);
3721 set_eapd(codec, 0x10, 0);
3722 break;
3723 case 0x10ec0262:
3724 case 0x10ec0267:
3725 case 0x10ec0268:
3726 case 0x10ec0269:
3727 case 0x10ec0270:
3728 case 0x10ec0272:
3729 case 0x10ec0660:
3730 case 0x10ec0662:
3731 case 0x10ec0663:
3732 case 0x10ec0862:
3733 case 0x10ec0889:
3734 set_eapd(codec, 0x14, 0);
3735 set_eapd(codec, 0x15, 0);
3736 break;
3737 }
3738}
3739
3645static int alc_suspend(struct hda_codec *codec, pm_message_t state) 3740static int alc_suspend(struct hda_codec *codec, pm_message_t state)
3646{ 3741{
3647 struct alc_spec *spec = codec->spec; 3742 struct alc_spec *spec = codec->spec;
3743 alc_shutup(codec);
3648 if (spec && spec->power_hook) 3744 if (spec && spec->power_hook)
3649 spec->power_hook(codec, 0); 3745 spec->power_hook(codec);
3650 return 0; 3746 return 0;
3651} 3747}
3652#endif 3748#endif
@@ -3654,16 +3750,9 @@ static int alc_suspend(struct hda_codec *codec, pm_message_t state)
3654#ifdef SND_HDA_NEEDS_RESUME 3750#ifdef SND_HDA_NEEDS_RESUME
3655static int alc_resume(struct hda_codec *codec) 3751static int alc_resume(struct hda_codec *codec)
3656{ 3752{
3657#ifdef CONFIG_SND_HDA_POWER_SAVE
3658 struct alc_spec *spec = codec->spec;
3659#endif
3660 codec->patch_ops.init(codec); 3753 codec->patch_ops.init(codec);
3661 snd_hda_codec_resume_amp(codec); 3754 snd_hda_codec_resume_amp(codec);
3662 snd_hda_codec_resume_cache(codec); 3755 snd_hda_codec_resume_cache(codec);
3663#ifdef CONFIG_SND_HDA_POWER_SAVE
3664 if (spec && spec->power_hook)
3665 spec->power_hook(codec, 1);
3666#endif
3667 return 0; 3756 return 0;
3668} 3757}
3669#endif 3758#endif
@@ -3683,6 +3772,7 @@ static struct hda_codec_ops alc_patch_ops = {
3683 .suspend = alc_suspend, 3772 .suspend = alc_suspend,
3684 .check_power_status = alc_check_power_status, 3773 .check_power_status = alc_check_power_status,
3685#endif 3774#endif
3775 .reboot_notify = alc_shutup,
3686}; 3776};
3687 3777
3688 3778
@@ -3839,6 +3929,7 @@ static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3839#define PIN_CTL_TEST(xname,nid) { \ 3929#define PIN_CTL_TEST(xname,nid) { \
3840 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 3930 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3841 .name = xname, \ 3931 .name = xname, \
3932 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
3842 .info = alc_test_pin_ctl_info, \ 3933 .info = alc_test_pin_ctl_info, \
3843 .get = alc_test_pin_ctl_get, \ 3934 .get = alc_test_pin_ctl_get, \
3844 .put = alc_test_pin_ctl_put, \ 3935 .put = alc_test_pin_ctl_put, \
@@ -3848,6 +3939,7 @@ static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3848#define PIN_SRC_TEST(xname,nid) { \ 3939#define PIN_SRC_TEST(xname,nid) { \
3849 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 3940 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3850 .name = xname, \ 3941 .name = xname, \
3942 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
3851 .info = alc_test_pin_src_info, \ 3943 .info = alc_test_pin_src_info, \
3852 .get = alc_test_pin_src_get, \ 3944 .get = alc_test_pin_src_get, \
3853 .put = alc_test_pin_src_put, \ 3945 .put = alc_test_pin_src_put, \
@@ -4387,7 +4479,7 @@ static int add_control(struct alc_spec *spec, int type, const char *name,
4387 if (!knew->name) 4479 if (!knew->name)
4388 return -ENOMEM; 4480 return -ENOMEM;
4389 if (get_amp_nid_(val)) 4481 if (get_amp_nid_(val))
4390 knew->subdevice = HDA_SUBDEV_NID_FLAG | get_amp_nid_(val); 4482 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
4391 knew->private_value = val; 4483 knew->private_value = val;
4392 return 0; 4484 return 0;
4393} 4485}
@@ -4770,7 +4862,7 @@ static int alc880_parse_auto_config(struct hda_codec *codec)
4770 spec->num_mux_defs = 1; 4862 spec->num_mux_defs = 1;
4771 spec->input_mux = &spec->private_imux[0]; 4863 spec->input_mux = &spec->private_imux[0];
4772 4864
4773 alc_ssid_check(codec, 0x15, 0x1b, 0x14); 4865 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4774 4866
4775 return 1; 4867 return 1;
4776} 4868}
@@ -4974,7 +5066,6 @@ static int patch_alc880(struct hda_codec *codec)
4974 if (!spec->loopback.amplist) 5066 if (!spec->loopback.amplist)
4975 spec->loopback.amplist = alc880_loopbacks; 5067 spec->loopback.amplist = alc880_loopbacks;
4976#endif 5068#endif
4977 codec->proc_widget_hook = print_realtek_coef;
4978 5069
4979 return 0; 5070 return 0;
4980} 5071}
@@ -5182,6 +5273,7 @@ static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
5182 { 5273 {
5183 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5274 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5184 .name = "Master Playback Switch", 5275 .name = "Master Playback Switch",
5276 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
5185 .info = snd_ctl_boolean_mono_info, 5277 .info = snd_ctl_boolean_mono_info,
5186 .get = alc260_hp_master_sw_get, 5278 .get = alc260_hp_master_sw_get,
5187 .put = alc260_hp_master_sw_put, 5279 .put = alc260_hp_master_sw_put,
@@ -5220,6 +5312,7 @@ static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
5220 { 5312 {
5221 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5313 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5222 .name = "Master Playback Switch", 5314 .name = "Master Playback Switch",
5315 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
5223 .info = snd_ctl_boolean_mono_info, 5316 .info = snd_ctl_boolean_mono_info,
5224 .get = alc260_hp_master_sw_get, 5317 .get = alc260_hp_master_sw_get,
5225 .put = alc260_hp_master_sw_put, 5318 .put = alc260_hp_master_sw_put,
@@ -6303,7 +6396,7 @@ static int alc260_parse_auto_config(struct hda_codec *codec)
6303 spec->num_mux_defs = 1; 6396 spec->num_mux_defs = 1;
6304 spec->input_mux = &spec->private_imux[0]; 6397 spec->input_mux = &spec->private_imux[0];
6305 6398
6306 alc_ssid_check(codec, 0x10, 0x15, 0x0f); 6399 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
6307 6400
6308 return 1; 6401 return 1;
6309} 6402}
@@ -6582,7 +6675,6 @@ static int patch_alc260(struct hda_codec *codec)
6582 if (!spec->loopback.amplist) 6675 if (!spec->loopback.amplist)
6583 spec->loopback.amplist = alc260_loopbacks; 6676 spec->loopback.amplist = alc260_loopbacks;
6584#endif 6677#endif
6585 codec->proc_widget_hook = print_realtek_coef;
6586 6678
6587 return 0; 6679 return 0;
6588} 6680}
@@ -6664,6 +6756,14 @@ static struct hda_input_mux mb5_capture_source = {
6664 }, 6756 },
6665}; 6757};
6666 6758
6759static struct hda_input_mux macmini3_capture_source = {
6760 .num_items = 2,
6761 .items = {
6762 { "Line", 0x2 },
6763 { "CD", 0x4 },
6764 },
6765};
6766
6667static struct hda_input_mux alc883_3stack_6ch_intel = { 6767static struct hda_input_mux alc883_3stack_6ch_intel = {
6668 .num_items = 4, 6768 .num_items = 4,
6669 .items = { 6769 .items = {
@@ -6852,6 +6952,13 @@ static struct hda_channel_mode alc882_sixstack_modes[2] = {
6852 { 8, alc882_sixstack_ch8_init }, 6952 { 8, alc882_sixstack_ch8_init },
6853}; 6953};
6854 6954
6955
6956/* Macbook Air 2,1 */
6957
6958static struct hda_channel_mode alc885_mba21_ch_modes[1] = {
6959 { 2, NULL },
6960};
6961
6855/* 6962/*
6856 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic 6963 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
6857 */ 6964 */
@@ -6912,6 +7019,7 @@ static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
6912 { 6, alc885_mb5_ch6_init }, 7019 { 6, alc885_mb5_ch6_init },
6913}; 7020};
6914 7021
7022#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
6915 7023
6916/* 7024/*
6917 * 2ch mode 7025 * 2ch mode
@@ -7123,6 +7231,15 @@ static struct snd_kcontrol_new alc882_base_mixer[] = {
7123 { } /* end */ 7231 { } /* end */
7124}; 7232};
7125 7233
7234/* Macbook Air 2,1 same control for HP and internal Speaker */
7235
7236static struct snd_kcontrol_new alc885_mba21_mixer[] = {
7237 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7238 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
7239 { }
7240};
7241
7242
7126static struct snd_kcontrol_new alc885_mbp3_mixer[] = { 7243static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
7127 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 7244 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7128 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT), 7245 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
@@ -7156,6 +7273,21 @@ static struct snd_kcontrol_new alc885_mb5_mixer[] = {
7156 { } /* end */ 7273 { } /* end */
7157}; 7274};
7158 7275
7276static struct snd_kcontrol_new alc885_macmini3_mixer[] = {
7277 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7278 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7279 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7280 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7281 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7282 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
7283 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7284 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
7285 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7286 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
7287 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
7288 { } /* end */
7289};
7290
7159static struct snd_kcontrol_new alc885_imac91_mixer[] = { 7291static struct snd_kcontrol_new alc885_imac91_mixer[] = {
7160 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 7292 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7161 HDA_BIND_MUTE ("Line-Out Playback Switch", 0x0c, 0x02, HDA_INPUT), 7293 HDA_BIND_MUTE ("Line-Out Playback Switch", 0x0c, 0x02, HDA_INPUT),
@@ -7247,29 +7379,18 @@ static struct snd_kcontrol_new alc882_chmode_mixer[] = {
7247 7379
7248static struct hda_verb alc882_base_init_verbs[] = { 7380static struct hda_verb alc882_base_init_verbs[] = {
7249 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 7381 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7250 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7251 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7382 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7252 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7383 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7253 /* Rear mixer */ 7384 /* Rear mixer */
7254 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7255 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7385 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7256 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7386 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7257 /* CLFE mixer */ 7387 /* CLFE mixer */
7258 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7259 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7388 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7260 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7389 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7261 /* Side mixer */ 7390 /* Side mixer */
7262 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7263 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7391 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7264 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7392 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7265 7393
7266 /* mute analog input loopbacks */
7267 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7268 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7269 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7270 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7271 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7272
7273 /* Front Pin: output 0 (0x0c) */ 7394 /* Front Pin: output 0 (0x0c) */
7274 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7395 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7275 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7396 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
@@ -7306,14 +7427,8 @@ static struct hda_verb alc882_base_init_verbs[] = {
7306 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 7427 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7307 /* Input mixer2 */ 7428 /* Input mixer2 */
7308 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7429 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7309 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7310 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7311 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7312 /* Input mixer3 */ 7430 /* Input mixer3 */
7313 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7431 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7314 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7315 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7316 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7317 /* ADC2: mute amp left and right */ 7432 /* ADC2: mute amp left and right */
7318 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7433 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7319 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 7434 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
@@ -7357,26 +7472,17 @@ static struct hda_verb alc_hp15_unsol_verbs[] = {
7357 7472
7358static struct hda_verb alc885_init_verbs[] = { 7473static struct hda_verb alc885_init_verbs[] = {
7359 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 7474 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7360 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7475 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7361 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7476 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7362 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7363 /* Rear mixer */ 7477 /* Rear mixer */
7364 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7478 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7365 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7479 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7366 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7367 /* CLFE mixer */ 7480 /* CLFE mixer */
7368 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7481 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7369 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7482 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7370 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7371 /* Side mixer */ 7483 /* Side mixer */
7372 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7484 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7373 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7485 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7374 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7375
7376 /* mute analog input loopbacks */
7377 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7378 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7379 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7380 7486
7381 /* Front HP Pin: output 0 (0x0c) */ 7487 /* Front HP Pin: output 0 (0x0c) */
7382 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7488 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
@@ -7410,17 +7516,11 @@ static struct hda_verb alc885_init_verbs[] = {
7410 7516
7411 /* Mixer elements: 0x18, , 0x1a, 0x1b */ 7517 /* Mixer elements: 0x18, , 0x1a, 0x1b */
7412 /* Input mixer1 */ 7518 /* Input mixer1 */
7413 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 7519 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7414 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7415 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7416 /* Input mixer2 */ 7520 /* Input mixer2 */
7417 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7521 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7418 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7419 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7420 /* Input mixer3 */ 7522 /* Input mixer3 */
7421 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 7523 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7422 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7423 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7424 /* ADC2: mute amp left and right */ 7524 /* ADC2: mute amp left and right */
7425 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7525 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7426 /* ADC3: mute amp left and right */ 7526 /* ADC3: mute amp left and right */
@@ -7562,6 +7662,76 @@ static struct hda_verb alc885_mb5_init_verbs[] = {
7562 { } 7662 { }
7563}; 7663};
7564 7664
7665/* Macmini 3,1 */
7666static struct hda_verb alc885_macmini3_init_verbs[] = {
7667 /* DACs */
7668 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7669 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7670 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7671 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7672 /* Front mixer */
7673 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7674 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7675 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7676 /* Surround mixer */
7677 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7678 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7679 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7680 /* LFE mixer */
7681 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7682 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7683 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7684 /* HP mixer */
7685 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7686 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7687 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7688 /* Front Pin (0x0c) */
7689 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7690 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7691 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7692 /* LFE Pin (0x0e) */
7693 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7694 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7695 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
7696 /* HP Pin (0x0f) */
7697 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7698 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7699 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
7700 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7701 /* Line In pin */
7702 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7703 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7704
7705 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7706 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7707 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7708 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7709 { }
7710};
7711
7712
7713static struct hda_verb alc885_mba21_init_verbs[] = {
7714 /*Internal and HP Speaker Mixer*/
7715 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7716 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7717 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7718 /*Internal Speaker Pin (0x0c)*/
7719 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
7720 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7721 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7722 /* HP Pin: output 0 (0x0e) */
7723 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
7724 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7725 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7726 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
7727 /* Line in (is hp when jack connected)*/
7728 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
7729 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7730
7731 { }
7732 };
7733
7734
7565/* Macbook Pro rev3 */ 7735/* Macbook Pro rev3 */
7566static struct hda_verb alc885_mbp3_init_verbs[] = { 7736static struct hda_verb alc885_mbp3_init_verbs[] = {
7567 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 7737 /* Front mixer: unmute input/output amp left and right (volume = 0) */
@@ -7724,54 +7894,35 @@ static void alc885_imac24_setup(struct hda_codec *codec)
7724 spec->autocfg.speaker_pins[1] = 0x1a; 7894 spec->autocfg.speaker_pins[1] = 0x1a;
7725} 7895}
7726 7896
7727static void alc885_mbp3_setup(struct hda_codec *codec) 7897#define alc885_mb5_setup alc885_imac24_setup
7728{ 7898#define alc885_macmini3_setup alc885_imac24_setup
7729 struct alc_spec *spec = codec->spec;
7730
7731 spec->autocfg.hp_pins[0] = 0x15;
7732 spec->autocfg.speaker_pins[0] = 0x14;
7733}
7734 7899
7735static void alc885_mb5_automute(struct hda_codec *codec) 7900/* Macbook Air 2,1 */
7901static void alc885_mba21_setup(struct hda_codec *codec)
7736{ 7902{
7737 unsigned int present; 7903 struct alc_spec *spec = codec->spec;
7738
7739 present = snd_hda_codec_read(codec, 0x14, 0,
7740 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7741 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
7742 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7743 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
7744 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7745 7904
7905 spec->autocfg.hp_pins[0] = 0x14;
7906 spec->autocfg.speaker_pins[0] = 0x18;
7746} 7907}
7747 7908
7748static void alc885_mb5_unsol_event(struct hda_codec *codec,
7749 unsigned int res)
7750{
7751 /* Headphone insertion or removal. */
7752 if ((res >> 26) == ALC880_HP_EVENT)
7753 alc885_mb5_automute(codec);
7754}
7755 7909
7756static void alc885_imac91_automute(struct hda_codec *codec)
7757{
7758 unsigned int present;
7759 7910
7760 present = snd_hda_codec_read(codec, 0x14, 0, 7911static void alc885_mbp3_setup(struct hda_codec *codec)
7761 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 7912{
7762 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 7913 struct alc_spec *spec = codec->spec;
7763 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7764 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
7765 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7766 7914
7915 spec->autocfg.hp_pins[0] = 0x15;
7916 spec->autocfg.speaker_pins[0] = 0x14;
7767} 7917}
7768 7918
7769static void alc885_imac91_unsol_event(struct hda_codec *codec, 7919static void alc885_imac91_setup(struct hda_codec *codec)
7770 unsigned int res)
7771{ 7920{
7772 /* Headphone insertion or removal. */ 7921 struct alc_spec *spec = codec->spec;
7773 if ((res >> 26) == ALC880_HP_EVENT) 7922
7774 alc885_imac91_automute(codec); 7923 spec->autocfg.hp_pins[0] = 0x14;
7924 spec->autocfg.speaker_pins[0] = 0x15;
7925 spec->autocfg.speaker_pins[1] = 0x1a;
7775} 7926}
7776 7927
7777static struct hda_verb alc882_targa_verbs[] = { 7928static struct hda_verb alc882_targa_verbs[] = {
@@ -7906,18 +8057,6 @@ static struct hda_verb alc883_auto_init_verbs[] = {
7906 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 8057 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7907 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8058 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7908 8059
7909 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7910 * mixer widget
7911 * Note: PASD motherboards uses the Line In 2 as the input for
7912 * front panel mic (mic 2)
7913 */
7914 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7915 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7916 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7917 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7918 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7919 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7920
7921 /* 8060 /*
7922 * Set up output mixers (0x0c - 0x0f) 8061 * Set up output mixers (0x0c - 0x0f)
7923 */ 8062 */
@@ -7942,16 +8081,9 @@ static struct hda_verb alc883_auto_init_verbs[] = {
7942 /* FIXME: use matrix-type input source selection */ 8081 /* FIXME: use matrix-type input source selection */
7943 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 8082 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7944 /* Input mixer2 */ 8083 /* Input mixer2 */
7945 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 8084 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7946 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7947 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7948 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7949 /* Input mixer3 */ 8085 /* Input mixer3 */
7950 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 8086 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7951 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7952 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7953 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7954
7955 { } 8087 { }
7956}; 8088};
7957 8089
@@ -8938,6 +9070,8 @@ static const char *alc882_models[ALC882_MODEL_LAST] = {
8938 [ALC882_ASUS_A7M] = "asus-a7m", 9070 [ALC882_ASUS_A7M] = "asus-a7m",
8939 [ALC885_MACPRO] = "macpro", 9071 [ALC885_MACPRO] = "macpro",
8940 [ALC885_MB5] = "mb5", 9072 [ALC885_MB5] = "mb5",
9073 [ALC885_MACMINI3] = "macmini3",
9074 [ALC885_MBA21] = "mba21",
8941 [ALC885_MBP3] = "mbp3", 9075 [ALC885_MBP3] = "mbp3",
8942 [ALC885_IMAC24] = "imac24", 9076 [ALC885_IMAC24] = "imac24",
8943 [ALC885_IMAC91] = "imac91", 9077 [ALC885_IMAC91] = "imac91",
@@ -9121,6 +9255,7 @@ static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
9121 */ 9255 */
9122 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5), 9256 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
9123 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5), 9257 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
9258 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
9124 {} /* terminator */ 9259 {} /* terminator */
9125}; 9260};
9126 9261
@@ -9172,6 +9307,18 @@ static struct alc_config_preset alc882_presets[] = {
9172 .input_mux = &alc882_capture_source, 9307 .input_mux = &alc882_capture_source,
9173 .dig_out_nid = ALC882_DIGOUT_NID, 9308 .dig_out_nid = ALC882_DIGOUT_NID,
9174 }, 9309 },
9310 [ALC885_MBA21] = {
9311 .mixers = { alc885_mba21_mixer },
9312 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
9313 .num_dacs = 2,
9314 .dac_nids = alc882_dac_nids,
9315 .channel_mode = alc885_mba21_ch_modes,
9316 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
9317 .input_mux = &alc882_capture_source,
9318 .unsol_event = alc_automute_amp_unsol_event,
9319 .setup = alc885_mba21_setup,
9320 .init_hook = alc_automute_amp,
9321 },
9175 [ALC885_MBP3] = { 9322 [ALC885_MBP3] = {
9176 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer }, 9323 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
9177 .init_verbs = { alc885_mbp3_init_verbs, 9324 .init_verbs = { alc885_mbp3_init_verbs,
@@ -9199,8 +9346,24 @@ static struct alc_config_preset alc882_presets[] = {
9199 .input_mux = &mb5_capture_source, 9346 .input_mux = &mb5_capture_source,
9200 .dig_out_nid = ALC882_DIGOUT_NID, 9347 .dig_out_nid = ALC882_DIGOUT_NID,
9201 .dig_in_nid = ALC882_DIGIN_NID, 9348 .dig_in_nid = ALC882_DIGIN_NID,
9202 .unsol_event = alc885_mb5_unsol_event, 9349 .unsol_event = alc_automute_amp_unsol_event,
9203 .init_hook = alc885_mb5_automute, 9350 .setup = alc885_mb5_setup,
9351 .init_hook = alc_automute_amp,
9352 },
9353 [ALC885_MACMINI3] = {
9354 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
9355 .init_verbs = { alc885_macmini3_init_verbs,
9356 alc880_gpio1_init_verbs },
9357 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9358 .dac_nids = alc882_dac_nids,
9359 .channel_mode = alc885_macmini3_6ch_modes,
9360 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
9361 .input_mux = &macmini3_capture_source,
9362 .dig_out_nid = ALC882_DIGOUT_NID,
9363 .dig_in_nid = ALC882_DIGIN_NID,
9364 .unsol_event = alc_automute_amp_unsol_event,
9365 .setup = alc885_macmini3_setup,
9366 .init_hook = alc_automute_amp,
9204 }, 9367 },
9205 [ALC885_MACPRO] = { 9368 [ALC885_MACPRO] = {
9206 .mixers = { alc882_macpro_mixer }, 9369 .mixers = { alc882_macpro_mixer },
@@ -9239,8 +9402,9 @@ static struct alc_config_preset alc882_presets[] = {
9239 .input_mux = &alc882_capture_source, 9402 .input_mux = &alc882_capture_source,
9240 .dig_out_nid = ALC882_DIGOUT_NID, 9403 .dig_out_nid = ALC882_DIGOUT_NID,
9241 .dig_in_nid = ALC882_DIGIN_NID, 9404 .dig_in_nid = ALC882_DIGIN_NID,
9242 .unsol_event = alc885_imac91_unsol_event, 9405 .unsol_event = alc_automute_amp_unsol_event,
9243 .init_hook = alc885_imac91_automute, 9406 .setup = alc885_imac91_setup,
9407 .init_hook = alc_automute_amp,
9244 }, 9408 },
9245 [ALC882_TARGA] = { 9409 [ALC882_TARGA] = {
9246 .mixers = { alc882_targa_mixer, alc882_chmode_mixer }, 9410 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
@@ -9528,7 +9692,7 @@ static struct alc_config_preset alc882_presets[] = {
9528 .setup = alc889_acer_aspire_8930g_setup, 9692 .setup = alc889_acer_aspire_8930g_setup,
9529 .init_hook = alc_automute_amp, 9693 .init_hook = alc_automute_amp,
9530#ifdef CONFIG_SND_HDA_POWER_SAVE 9694#ifdef CONFIG_SND_HDA_POWER_SAVE
9531 .power_hook = alc889_power_eapd, 9695 .power_hook = alc_power_eapd,
9532#endif 9696#endif
9533 }, 9697 },
9534 [ALC888_ACER_ASPIRE_7730G] = { 9698 [ALC888_ACER_ASPIRE_7730G] = {
@@ -10063,7 +10227,7 @@ static int alc882_parse_auto_config(struct hda_codec *codec)
10063 spec->num_mux_defs = 1; 10227 spec->num_mux_defs = 1;
10064 spec->input_mux = &spec->private_imux[0]; 10228 spec->input_mux = &spec->private_imux[0];
10065 10229
10066 alc_ssid_check(codec, 0x15, 0x1b, 0x14); 10230 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
10067 10231
10068 err = alc_auto_add_mic_boost(codec); 10232 err = alc_auto_add_mic_boost(codec);
10069 if (err < 0) 10233 if (err < 0)
@@ -10201,7 +10365,6 @@ static int patch_alc882(struct hda_codec *codec)
10201 if (!spec->loopback.amplist) 10365 if (!spec->loopback.amplist)
10202 spec->loopback.amplist = alc882_loopbacks; 10366 spec->loopback.amplist = alc882_loopbacks;
10203#endif 10367#endif
10204 codec->proc_widget_hook = print_realtek_coef;
10205 10368
10206 return 0; 10369 return 0;
10207} 10370}
@@ -10324,8 +10487,14 @@ static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
10324 .info = snd_ctl_boolean_mono_info, \ 10487 .info = snd_ctl_boolean_mono_info, \
10325 .get = alc262_hp_master_sw_get, \ 10488 .get = alc262_hp_master_sw_get, \
10326 .put = alc262_hp_master_sw_put, \ 10489 .put = alc262_hp_master_sw_put, \
10490 }, \
10491 { \
10492 .iface = NID_MAPPING, \
10493 .name = "Master Playback Switch", \
10494 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
10327 } 10495 }
10328 10496
10497
10329static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { 10498static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
10330 ALC262_HP_MASTER_SWITCH, 10499 ALC262_HP_MASTER_SWITCH,
10331 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 10500 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
@@ -10483,6 +10652,12 @@ static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
10483 .info = snd_ctl_boolean_mono_info, \ 10652 .info = snd_ctl_boolean_mono_info, \
10484 .get = alc262_hippo_master_sw_get, \ 10653 .get = alc262_hippo_master_sw_get, \
10485 .put = alc262_hippo_master_sw_put, \ 10654 .put = alc262_hippo_master_sw_put, \
10655 }, \
10656 { \
10657 .iface = NID_MAPPING, \
10658 .name = "Master Playback Switch", \
10659 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
10660 (SUBDEV_SPEAKER(0) << 16), \
10486 } 10661 }
10487 10662
10488static struct snd_kcontrol_new alc262_hippo_mixer[] = { 10663static struct snd_kcontrol_new alc262_hippo_mixer[] = {
@@ -10963,11 +11138,17 @@ static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
10963 { 11138 {
10964 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11139 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10965 .name = "Master Playback Switch", 11140 .name = "Master Playback Switch",
11141 .subdevice = HDA_SUBDEV_AMP_FLAG,
10966 .info = snd_hda_mixer_amp_switch_info, 11142 .info = snd_hda_mixer_amp_switch_info,
10967 .get = snd_hda_mixer_amp_switch_get, 11143 .get = snd_hda_mixer_amp_switch_get,
10968 .put = alc262_fujitsu_master_sw_put, 11144 .put = alc262_fujitsu_master_sw_put,
10969 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 11145 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10970 }, 11146 },
11147 {
11148 .iface = NID_MAPPING,
11149 .name = "Master Playback Switch",
11150 .private_value = 0x1b,
11151 },
10971 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11152 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10972 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11153 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10973 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11154 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
@@ -10998,6 +11179,7 @@ static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
10998 { 11179 {
10999 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11180 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11000 .name = "Master Playback Switch", 11181 .name = "Master Playback Switch",
11182 .subdevice = HDA_SUBDEV_AMP_FLAG,
11001 .info = snd_hda_mixer_amp_switch_info, 11183 .info = snd_hda_mixer_amp_switch_info,
11002 .get = snd_hda_mixer_amp_switch_get, 11184 .get = snd_hda_mixer_amp_switch_get,
11003 .put = alc262_lenovo_3000_master_sw_put, 11185 .put = alc262_lenovo_3000_master_sw_put,
@@ -11152,6 +11334,11 @@ static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
11152 .get = alc_mux_enum_get, 11334 .get = alc_mux_enum_get,
11153 .put = alc262_ultra_mux_enum_put, 11335 .put = alc262_ultra_mux_enum_put,
11154 }, 11336 },
11337 {
11338 .iface = NID_MAPPING,
11339 .name = "Capture Source",
11340 .private_value = 0x15,
11341 },
11155 { } /* end */ 11342 { } /* end */
11156}; 11343};
11157 11344
@@ -11598,7 +11785,7 @@ static int alc262_parse_auto_config(struct hda_codec *codec)
11598 if (err < 0) 11785 if (err < 0)
11599 return err; 11786 return err;
11600 11787
11601 alc_ssid_check(codec, 0x15, 0x14, 0x1b); 11788 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
11602 11789
11603 return 1; 11790 return 1;
11604} 11791}
@@ -12041,7 +12228,6 @@ static int patch_alc262(struct hda_codec *codec)
12041 if (!spec->loopback.amplist) 12228 if (!spec->loopback.amplist)
12042 spec->loopback.amplist = alc262_loopbacks; 12229 spec->loopback.amplist = alc262_loopbacks;
12043#endif 12230#endif
12044 codec->proc_widget_hook = print_realtek_coef;
12045 12231
12046 return 0; 12232 return 0;
12047} 12233}
@@ -12170,6 +12356,7 @@ static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
12170 { 12356 {
12171 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12357 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12172 .name = "Master Playback Switch", 12358 .name = "Master Playback Switch",
12359 .subdevice = HDA_SUBDEV_AMP_FLAG,
12173 .info = snd_hda_mixer_amp_switch_info, 12360 .info = snd_hda_mixer_amp_switch_info,
12174 .get = snd_hda_mixer_amp_switch_get, 12361 .get = snd_hda_mixer_amp_switch_get,
12175 .put = alc268_acer_master_sw_put, 12362 .put = alc268_acer_master_sw_put,
@@ -12185,6 +12372,7 @@ static struct snd_kcontrol_new alc268_acer_mixer[] = {
12185 { 12372 {
12186 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12373 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12187 .name = "Master Playback Switch", 12374 .name = "Master Playback Switch",
12375 .subdevice = HDA_SUBDEV_AMP_FLAG,
12188 .info = snd_hda_mixer_amp_switch_info, 12376 .info = snd_hda_mixer_amp_switch_info,
12189 .get = snd_hda_mixer_amp_switch_get, 12377 .get = snd_hda_mixer_amp_switch_get,
12190 .put = alc268_acer_master_sw_put, 12378 .put = alc268_acer_master_sw_put,
@@ -12202,6 +12390,7 @@ static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
12202 { 12390 {
12203 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12391 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12204 .name = "Master Playback Switch", 12392 .name = "Master Playback Switch",
12393 .subdevice = HDA_SUBDEV_AMP_FLAG,
12205 .info = snd_hda_mixer_amp_switch_info, 12394 .info = snd_hda_mixer_amp_switch_info,
12206 .get = snd_hda_mixer_amp_switch_get, 12395 .get = snd_hda_mixer_amp_switch_get,
12207 .put = alc268_acer_master_sw_put, 12396 .put = alc268_acer_master_sw_put,
@@ -12547,7 +12736,6 @@ static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
12547 dac = 0x02; 12736 dac = 0x02;
12548 break; 12737 break;
12549 case 0x15: 12738 case 0x15:
12550 case 0x21:
12551 dac = 0x03; 12739 dac = 0x03;
12552 break; 12740 break;
12553 default: 12741 default:
@@ -12768,7 +12956,7 @@ static int alc268_parse_auto_config(struct hda_codec *codec)
12768 if (err < 0) 12956 if (err < 0)
12769 return err; 12957 return err;
12770 12958
12771 alc_ssid_check(codec, 0x15, 0x1b, 0x14); 12959 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
12772 12960
12773 return 1; 12961 return 1;
12774} 12962}
@@ -13105,8 +13293,6 @@ static int patch_alc268(struct hda_codec *codec)
13105 if (board_config == ALC268_AUTO) 13293 if (board_config == ALC268_AUTO)
13106 spec->init_hook = alc268_auto_init; 13294 spec->init_hook = alc268_auto_init;
13107 13295
13108 codec->proc_widget_hook = print_realtek_coef;
13109
13110 return 0; 13296 return 0;
13111} 13297}
13112 13298
@@ -13126,6 +13312,15 @@ static hda_nid_t alc269_capsrc_nids[1] = {
13126 0x23, 13312 0x23,
13127}; 13313};
13128 13314
13315static hda_nid_t alc269vb_adc_nids[1] = {
13316 /* ADC1 */
13317 0x09,
13318};
13319
13320static hda_nid_t alc269vb_capsrc_nids[1] = {
13321 0x22,
13322};
13323
13129/* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24), 13324/* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
13130 * not a mux! 13325 * not a mux!
13131 */ 13326 */
@@ -13155,6 +13350,7 @@ static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
13155 { 13350 {
13156 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13351 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13157 .name = "Master Playback Switch", 13352 .name = "Master Playback Switch",
13353 .subdevice = HDA_SUBDEV_AMP_FLAG,
13158 .info = snd_hda_mixer_amp_switch_info, 13354 .info = snd_hda_mixer_amp_switch_info,
13159 .get = snd_hda_mixer_amp_switch_get, 13355 .get = snd_hda_mixer_amp_switch_get,
13160 .put = alc268_acer_master_sw_put, 13356 .put = alc268_acer_master_sw_put,
@@ -13175,6 +13371,7 @@ static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
13175 { 13371 {
13176 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13372 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13177 .name = "Master Playback Switch", 13373 .name = "Master Playback Switch",
13374 .subdevice = HDA_SUBDEV_AMP_FLAG,
13178 .info = snd_hda_mixer_amp_switch_info, 13375 .info = snd_hda_mixer_amp_switch_info,
13179 .get = snd_hda_mixer_amp_switch_get, 13376 .get = snd_hda_mixer_amp_switch_get,
13180 .put = alc268_acer_master_sw_put, 13377 .put = alc268_acer_master_sw_put,
@@ -13192,7 +13389,7 @@ static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
13192 { } 13389 { }
13193}; 13390};
13194 13391
13195static struct snd_kcontrol_new alc269_eeepc_mixer[] = { 13392static struct snd_kcontrol_new alc269_laptop_mixer[] = {
13196 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 13393 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13197 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 13394 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13198 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 13395 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
@@ -13200,16 +13397,47 @@ static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
13200 { } /* end */ 13397 { } /* end */
13201}; 13398};
13202 13399
13400static struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
13401 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13402 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13403 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
13404 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13405 { } /* end */
13406};
13407
13203/* capture mixer elements */ 13408/* capture mixer elements */
13204static struct snd_kcontrol_new alc269_epc_capture_mixer[] = { 13409static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
13410 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13411 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13412 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13413 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT),
13414 { } /* end */
13415};
13416
13417static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
13205 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 13418 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13206 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 13419 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13207 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 13420 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13208 { } /* end */ 13421 { } /* end */
13209}; 13422};
13210 13423
13424static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
13425 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13426 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13427 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13428 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT),
13429 { } /* end */
13430};
13431
13432static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
13433 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13434 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13435 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13436 { } /* end */
13437};
13438
13211/* FSC amilo */ 13439/* FSC amilo */
13212#define alc269_fujitsu_mixer alc269_eeepc_mixer 13440#define alc269_fujitsu_mixer alc269_laptop_mixer
13213 13441
13214static struct hda_verb alc269_quanta_fl1_verbs[] = { 13442static struct hda_verb alc269_quanta_fl1_verbs[] = {
13215 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 13443 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
@@ -13352,7 +13580,7 @@ static void alc269_lifebook_init_hook(struct hda_codec *codec)
13352 alc269_lifebook_mic_autoswitch(codec); 13580 alc269_lifebook_mic_autoswitch(codec);
13353} 13581}
13354 13582
13355static struct hda_verb alc269_eeepc_dmic_init_verbs[] = { 13583static struct hda_verb alc269_laptop_dmic_init_verbs[] = {
13356 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 13584 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13357 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05}, 13585 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
13358 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 13586 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
@@ -13363,7 +13591,7 @@ static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
13363 {} 13591 {}
13364}; 13592};
13365 13593
13366static struct hda_verb alc269_eeepc_amic_init_verbs[] = { 13594static struct hda_verb alc269_laptop_amic_init_verbs[] = {
13367 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 13595 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13368 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01}, 13596 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
13369 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 13597 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
@@ -13373,6 +13601,28 @@ static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
13373 {} 13601 {}
13374}; 13602};
13375 13603
13604static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
13605 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
13606 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
13607 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13608 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
13609 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13610 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13611 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13612 {}
13613};
13614
13615static struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
13616 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
13617 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
13618 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13619 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
13620 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13621 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13622 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13623 {}
13624};
13625
13376/* toggle speaker-output according to the hp-jack state */ 13626/* toggle speaker-output according to the hp-jack state */
13377static void alc269_speaker_automute(struct hda_codec *codec) 13627static void alc269_speaker_automute(struct hda_codec *codec)
13378{ 13628{
@@ -13390,7 +13640,7 @@ static void alc269_speaker_automute(struct hda_codec *codec)
13390} 13640}
13391 13641
13392/* unsolicited event for HP jack sensing */ 13642/* unsolicited event for HP jack sensing */
13393static void alc269_eeepc_unsol_event(struct hda_codec *codec, 13643static void alc269_laptop_unsol_event(struct hda_codec *codec,
13394 unsigned int res) 13644 unsigned int res)
13395{ 13645{
13396 switch (res >> 26) { 13646 switch (res >> 26) {
@@ -13403,7 +13653,7 @@ static void alc269_eeepc_unsol_event(struct hda_codec *codec,
13403 } 13653 }
13404} 13654}
13405 13655
13406static void alc269_eeepc_dmic_setup(struct hda_codec *codec) 13656static void alc269_laptop_dmic_setup(struct hda_codec *codec)
13407{ 13657{
13408 struct alc_spec *spec = codec->spec; 13658 struct alc_spec *spec = codec->spec;
13409 spec->ext_mic.pin = 0x18; 13659 spec->ext_mic.pin = 0x18;
@@ -13413,7 +13663,17 @@ static void alc269_eeepc_dmic_setup(struct hda_codec *codec)
13413 spec->auto_mic = 1; 13663 spec->auto_mic = 1;
13414} 13664}
13415 13665
13416static void alc269_eeepc_amic_setup(struct hda_codec *codec) 13666static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
13667{
13668 struct alc_spec *spec = codec->spec;
13669 spec->ext_mic.pin = 0x18;
13670 spec->ext_mic.mux_idx = 0;
13671 spec->int_mic.pin = 0x12;
13672 spec->int_mic.mux_idx = 6;
13673 spec->auto_mic = 1;
13674}
13675
13676static void alc269_laptop_amic_setup(struct hda_codec *codec)
13417{ 13677{
13418 struct alc_spec *spec = codec->spec; 13678 struct alc_spec *spec = codec->spec;
13419 spec->ext_mic.pin = 0x18; 13679 spec->ext_mic.pin = 0x18;
@@ -13423,7 +13683,7 @@ static void alc269_eeepc_amic_setup(struct hda_codec *codec)
13423 spec->auto_mic = 1; 13683 spec->auto_mic = 1;
13424} 13684}
13425 13685
13426static void alc269_eeepc_inithook(struct hda_codec *codec) 13686static void alc269_laptop_inithook(struct hda_codec *codec)
13427{ 13687{
13428 alc269_speaker_automute(codec); 13688 alc269_speaker_automute(codec);
13429 alc_mic_automute(codec); 13689 alc_mic_automute(codec);
@@ -13436,22 +13696,10 @@ static struct hda_verb alc269_init_verbs[] = {
13436 /* 13696 /*
13437 * Unmute ADC0 and set the default input to mic-in 13697 * Unmute ADC0 and set the default input to mic-in
13438 */ 13698 */
13439 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13699 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13440
13441 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
13442 * analog-loopback mixer widget
13443 * Note: PASD motherboards uses the Line In 2 as the input for
13444 * front panel mic (mic 2)
13445 */
13446 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
13447 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13448 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13449 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13450 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13451 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13452 13700
13453 /* 13701 /*
13454 * Set up output mixers (0x0c - 0x0e) 13702 * Set up output mixers (0x02 - 0x03)
13455 */ 13703 */
13456 /* set vol=0 to output mixers */ 13704 /* set vol=0 to output mixers */
13457 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 13705 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
@@ -13476,26 +13724,57 @@ static struct hda_verb alc269_init_verbs[] = {
13476 13724
13477 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13725 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13478 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13726 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13479 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13480 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13481 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13482 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13483 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13484 13727
13485 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 13728 /* FIXME: use Mux-type input source selection */
13486 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 13729 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
13730 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
13731 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
13487 13732
13488 /* FIXME: use matrix-type input source selection */ 13733 /* set EAPD */
13734 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13735 { }
13736};
13737
13738static struct hda_verb alc269vb_init_verbs[] = {
13739 /*
13740 * Unmute ADC0 and set the default input to mic-in
13741 */
13742 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13743
13744 /*
13745 * Set up output mixers (0x02 - 0x03)
13746 */
13747 /* set vol=0 to output mixers */
13748 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13749 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13750
13751 /* set up input amps for analog loopback */
13752 /* Amp Indices: DAC = 0, mixer = 1 */
13753 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13754 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13755 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13756 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13757 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13758 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13759
13760 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13761 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13762 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13763 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13764 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13765 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13766 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13767
13768 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13769 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13770
13771 /* FIXME: use Mux-type input source selection */
13489 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */ 13772 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
13490 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 13773 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
13491 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 13774 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
13492 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13493 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13494 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13495 13775
13496 /* set EAPD */ 13776 /* set EAPD */
13497 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 13777 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13498 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13499 { } 13778 { }
13500}; 13779};
13501 13780
@@ -13543,6 +13822,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
13543 struct alc_spec *spec = codec->spec; 13822 struct alc_spec *spec = codec->spec;
13544 int err; 13823 int err;
13545 static hda_nid_t alc269_ignore[] = { 0x1d, 0 }; 13824 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
13825 hda_nid_t real_capsrc_nids;
13546 13826
13547 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 13827 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13548 alc269_ignore); 13828 alc269_ignore);
@@ -13564,11 +13844,20 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
13564 if (spec->kctls.list) 13844 if (spec->kctls.list)
13565 add_mixer(spec, spec->kctls.list); 13845 add_mixer(spec, spec->kctls.list);
13566 13846
13567 add_verb(spec, alc269_init_verbs); 13847 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010) {
13848 add_verb(spec, alc269vb_init_verbs);
13849 real_capsrc_nids = alc269vb_capsrc_nids[0];
13850 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
13851 } else {
13852 add_verb(spec, alc269_init_verbs);
13853 real_capsrc_nids = alc269_capsrc_nids[0];
13854 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
13855 }
13856
13568 spec->num_mux_defs = 1; 13857 spec->num_mux_defs = 1;
13569 spec->input_mux = &spec->private_imux[0]; 13858 spec->input_mux = &spec->private_imux[0];
13570 /* set default input source */ 13859 /* set default input source */
13571 snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0], 13860 snd_hda_codec_write_cache(codec, real_capsrc_nids,
13572 0, AC_VERB_SET_CONNECT_SEL, 13861 0, AC_VERB_SET_CONNECT_SEL,
13573 spec->input_mux->items[0].index); 13862 spec->input_mux->items[0].index);
13574 13863
@@ -13579,8 +13868,6 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
13579 if (!spec->cap_mixer && !spec->no_analog) 13868 if (!spec->cap_mixer && !spec->no_analog)
13580 set_capture_mixer(codec); 13869 set_capture_mixer(codec);
13581 13870
13582 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
13583
13584 return 1; 13871 return 1;
13585} 13872}
13586 13873
@@ -13606,8 +13893,8 @@ static void alc269_auto_init(struct hda_codec *codec)
13606static const char *alc269_models[ALC269_MODEL_LAST] = { 13893static const char *alc269_models[ALC269_MODEL_LAST] = {
13607 [ALC269_BASIC] = "basic", 13894 [ALC269_BASIC] = "basic",
13608 [ALC269_QUANTA_FL1] = "quanta", 13895 [ALC269_QUANTA_FL1] = "quanta",
13609 [ALC269_ASUS_AMIC] = "asus-amic", 13896 [ALC269_AMIC] = "laptop-amic",
13610 [ALC269_ASUS_DMIC] = "asus-dmic", 13897 [ALC269_DMIC] = "laptop-dmic",
13611 [ALC269_FUJITSU] = "fujitsu", 13898 [ALC269_FUJITSU] = "fujitsu",
13612 [ALC269_LIFEBOOK] = "lifebook", 13899 [ALC269_LIFEBOOK] = "lifebook",
13613 [ALC269_AUTO] = "auto", 13900 [ALC269_AUTO] = "auto",
@@ -13616,43 +13903,57 @@ static const char *alc269_models[ALC269_MODEL_LAST] = {
13616static struct snd_pci_quirk alc269_cfg_tbl[] = { 13903static struct snd_pci_quirk alc269_cfg_tbl[] = {
13617 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1), 13904 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
13618 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", 13905 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
13619 ALC269_ASUS_AMIC), 13906 ALC269_AMIC),
13620 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_ASUS_AMIC), 13907 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
13621 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80JT", ALC269_ASUS_AMIC), 13908 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
13622 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_ASUS_AMIC), 13909 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
13623 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82Jv", ALC269_ASUS_AMIC), 13910 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
13624 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_ASUS_AMIC), 13911 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
13625 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_ASUS_AMIC), 13912 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
13626 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_ASUS_AMIC), 13913 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
13627 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_ASUS_AMIC), 13914 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
13628 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_ASUS_AMIC), 13915 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
13629 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_ASUS_AMIC), 13916 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82Jv", ALC269_AMIC),
13630 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_ASUS_AMIC), 13917 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
13631 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_ASUS_AMIC), 13918 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
13632 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_ASUS_AMIC), 13919 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
13633 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_ASUS_AMIC), 13920 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
13634 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_ASUS_AMIC), 13921 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
13635 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_ASUS_AMIC), 13922 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
13636 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_ASUS_AMIC), 13923 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
13637 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_ASUS_AMIC), 13924 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
13638 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_ASUS_AMIC), 13925 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
13639 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_ASUS_AMIC), 13926 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
13640 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_ASUS_AMIC), 13927 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
13641 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_ASUS_AMIC), 13928 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
13642 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_ASUS_AMIC), 13929 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
13643 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_ASUS_DMIC), 13930 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
13644 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_ASUS_AMIC), 13931 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
13645 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_ASUS_AMIC), 13932 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
13646 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_ASUS_AMIC), 13933 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
13647 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_ASUS_AMIC), 13934 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
13935 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
13936 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
13937 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
13938 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
13939 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
13940 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
13941 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
13942 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
13648 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901", 13943 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
13649 ALC269_ASUS_DMIC), 13944 ALC269_DMIC),
13650 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101", 13945 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
13651 ALC269_ASUS_DMIC), 13946 ALC269_DMIC),
13652 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_ASUS_DMIC), 13947 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
13653 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_ASUS_DMIC), 13948 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
13654 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU), 13949 SND_PCI_QUIRK(0x104d, 0x9071, "SONY XTB", ALC269_DMIC),
13655 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK), 13950 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
13951 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
13952 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
13953 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
13954 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
13955 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
13956 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
13656 {} 13957 {}
13657}; 13958};
13658 13959
@@ -13680,47 +13981,75 @@ static struct alc_config_preset alc269_presets[] = {
13680 .setup = alc269_quanta_fl1_setup, 13981 .setup = alc269_quanta_fl1_setup,
13681 .init_hook = alc269_quanta_fl1_init_hook, 13982 .init_hook = alc269_quanta_fl1_init_hook,
13682 }, 13983 },
13683 [ALC269_ASUS_AMIC] = { 13984 [ALC269_AMIC] = {
13684 .mixers = { alc269_eeepc_mixer }, 13985 .mixers = { alc269_laptop_mixer },
13685 .cap_mixer = alc269_epc_capture_mixer, 13986 .cap_mixer = alc269_laptop_analog_capture_mixer,
13686 .init_verbs = { alc269_init_verbs, 13987 .init_verbs = { alc269_init_verbs,
13687 alc269_eeepc_amic_init_verbs }, 13988 alc269_laptop_amic_init_verbs },
13688 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 13989 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13689 .dac_nids = alc269_dac_nids, 13990 .dac_nids = alc269_dac_nids,
13690 .hp_nid = 0x03, 13991 .hp_nid = 0x03,
13691 .num_channel_mode = ARRAY_SIZE(alc269_modes), 13992 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13692 .channel_mode = alc269_modes, 13993 .channel_mode = alc269_modes,
13693 .unsol_event = alc269_eeepc_unsol_event, 13994 .unsol_event = alc269_laptop_unsol_event,
13694 .setup = alc269_eeepc_amic_setup, 13995 .setup = alc269_laptop_amic_setup,
13695 .init_hook = alc269_eeepc_inithook, 13996 .init_hook = alc269_laptop_inithook,
13696 }, 13997 },
13697 [ALC269_ASUS_DMIC] = { 13998 [ALC269_DMIC] = {
13698 .mixers = { alc269_eeepc_mixer }, 13999 .mixers = { alc269_laptop_mixer },
13699 .cap_mixer = alc269_epc_capture_mixer, 14000 .cap_mixer = alc269_laptop_digital_capture_mixer,
13700 .init_verbs = { alc269_init_verbs, 14001 .init_verbs = { alc269_init_verbs,
13701 alc269_eeepc_dmic_init_verbs }, 14002 alc269_laptop_dmic_init_verbs },
14003 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14004 .dac_nids = alc269_dac_nids,
14005 .hp_nid = 0x03,
14006 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14007 .channel_mode = alc269_modes,
14008 .unsol_event = alc269_laptop_unsol_event,
14009 .setup = alc269_laptop_dmic_setup,
14010 .init_hook = alc269_laptop_inithook,
14011 },
14012 [ALC269VB_AMIC] = {
14013 .mixers = { alc269vb_laptop_mixer },
14014 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
14015 .init_verbs = { alc269vb_init_verbs,
14016 alc269vb_laptop_amic_init_verbs },
14017 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14018 .dac_nids = alc269_dac_nids,
14019 .hp_nid = 0x03,
14020 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14021 .channel_mode = alc269_modes,
14022 .unsol_event = alc269_laptop_unsol_event,
14023 .setup = alc269_laptop_amic_setup,
14024 .init_hook = alc269_laptop_inithook,
14025 },
14026 [ALC269VB_DMIC] = {
14027 .mixers = { alc269vb_laptop_mixer },
14028 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
14029 .init_verbs = { alc269vb_init_verbs,
14030 alc269vb_laptop_dmic_init_verbs },
13702 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 14031 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13703 .dac_nids = alc269_dac_nids, 14032 .dac_nids = alc269_dac_nids,
13704 .hp_nid = 0x03, 14033 .hp_nid = 0x03,
13705 .num_channel_mode = ARRAY_SIZE(alc269_modes), 14034 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13706 .channel_mode = alc269_modes, 14035 .channel_mode = alc269_modes,
13707 .unsol_event = alc269_eeepc_unsol_event, 14036 .unsol_event = alc269_laptop_unsol_event,
13708 .setup = alc269_eeepc_dmic_setup, 14037 .setup = alc269vb_laptop_dmic_setup,
13709 .init_hook = alc269_eeepc_inithook, 14038 .init_hook = alc269_laptop_inithook,
13710 }, 14039 },
13711 [ALC269_FUJITSU] = { 14040 [ALC269_FUJITSU] = {
13712 .mixers = { alc269_fujitsu_mixer }, 14041 .mixers = { alc269_fujitsu_mixer },
13713 .cap_mixer = alc269_epc_capture_mixer, 14042 .cap_mixer = alc269_laptop_digital_capture_mixer,
13714 .init_verbs = { alc269_init_verbs, 14043 .init_verbs = { alc269_init_verbs,
13715 alc269_eeepc_dmic_init_verbs }, 14044 alc269_laptop_dmic_init_verbs },
13716 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 14045 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13717 .dac_nids = alc269_dac_nids, 14046 .dac_nids = alc269_dac_nids,
13718 .hp_nid = 0x03, 14047 .hp_nid = 0x03,
13719 .num_channel_mode = ARRAY_SIZE(alc269_modes), 14048 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13720 .channel_mode = alc269_modes, 14049 .channel_mode = alc269_modes,
13721 .unsol_event = alc269_eeepc_unsol_event, 14050 .unsol_event = alc269_laptop_unsol_event,
13722 .setup = alc269_eeepc_dmic_setup, 14051 .setup = alc269_laptop_dmic_setup,
13723 .init_hook = alc269_eeepc_inithook, 14052 .init_hook = alc269_laptop_inithook,
13724 }, 14053 },
13725 [ALC269_LIFEBOOK] = { 14054 [ALC269_LIFEBOOK] = {
13726 .mixers = { alc269_lifebook_mixer }, 14055 .mixers = { alc269_lifebook_mixer },
@@ -13741,6 +14070,7 @@ static int patch_alc269(struct hda_codec *codec)
13741 struct alc_spec *spec; 14070 struct alc_spec *spec;
13742 int board_config; 14071 int board_config;
13743 int err; 14072 int err;
14073 int is_alc269vb = 0;
13744 14074
13745 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 14075 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13746 if (spec == NULL) 14076 if (spec == NULL)
@@ -13757,6 +14087,7 @@ static int patch_alc269(struct hda_codec *codec)
13757 alc_free(codec); 14087 alc_free(codec);
13758 return -ENOMEM; 14088 return -ENOMEM;
13759 } 14089 }
14090 is_alc269vb = 1;
13760 } 14091 }
13761 14092
13762 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST, 14093 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
@@ -13792,7 +14123,7 @@ static int patch_alc269(struct hda_codec *codec)
13792 if (board_config != ALC269_AUTO) 14123 if (board_config != ALC269_AUTO)
13793 setup_preset(codec, &alc269_presets[board_config]); 14124 setup_preset(codec, &alc269_presets[board_config]);
13794 14125
13795 if (codec->subsystem_id == 0x17aa3bf8) { 14126 if (board_config == ALC269_QUANTA_FL1) {
13796 /* Due to a hardware problem on Lenovo Ideadpad, we need to 14127 /* Due to a hardware problem on Lenovo Ideadpad, we need to
13797 * fix the sample rate of analog I/O to 44.1kHz 14128 * fix the sample rate of analog I/O to 44.1kHz
13798 */ 14129 */
@@ -13805,9 +14136,16 @@ static int patch_alc269(struct hda_codec *codec)
13805 spec->stream_digital_playback = &alc269_pcm_digital_playback; 14136 spec->stream_digital_playback = &alc269_pcm_digital_playback;
13806 spec->stream_digital_capture = &alc269_pcm_digital_capture; 14137 spec->stream_digital_capture = &alc269_pcm_digital_capture;
13807 14138
13808 spec->adc_nids = alc269_adc_nids; 14139 if (!is_alc269vb) {
13809 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids); 14140 spec->adc_nids = alc269_adc_nids;
13810 spec->capsrc_nids = alc269_capsrc_nids; 14141 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
14142 spec->capsrc_nids = alc269_capsrc_nids;
14143 } else {
14144 spec->adc_nids = alc269vb_adc_nids;
14145 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
14146 spec->capsrc_nids = alc269vb_capsrc_nids;
14147 }
14148
13811 if (!spec->cap_mixer) 14149 if (!spec->cap_mixer)
13812 set_capture_mixer(codec); 14150 set_capture_mixer(codec);
13813 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); 14151 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
@@ -13821,7 +14159,6 @@ static int patch_alc269(struct hda_codec *codec)
13821 if (!spec->loopback.amplist) 14159 if (!spec->loopback.amplist)
13822 spec->loopback.amplist = alc269_loopbacks; 14160 spec->loopback.amplist = alc269_loopbacks;
13823#endif 14161#endif
13824 codec->proc_widget_hook = print_realtek_coef;
13825 14162
13826 return 0; 14163 return 0;
13827} 14164}
@@ -14684,7 +15021,7 @@ static int alc861_parse_auto_config(struct hda_codec *codec)
14684 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids); 15021 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
14685 set_capture_mixer(codec); 15022 set_capture_mixer(codec);
14686 15023
14687 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b); 15024 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
14688 15025
14689 return 1; 15026 return 1;
14690} 15027}
@@ -14939,13 +15276,16 @@ static int patch_alc861(struct hda_codec *codec)
14939 spec->vmaster_nid = 0x03; 15276 spec->vmaster_nid = 0x03;
14940 15277
14941 codec->patch_ops = alc_patch_ops; 15278 codec->patch_ops = alc_patch_ops;
14942 if (board_config == ALC861_AUTO) 15279 if (board_config == ALC861_AUTO) {
14943 spec->init_hook = alc861_auto_init; 15280 spec->init_hook = alc861_auto_init;
14944#ifdef CONFIG_SND_HDA_POWER_SAVE 15281#ifdef CONFIG_SND_HDA_POWER_SAVE
15282 spec->power_hook = alc_power_eapd;
15283#endif
15284 }
15285#ifdef CONFIG_SND_HDA_POWER_SAVE
14945 if (!spec->loopback.amplist) 15286 if (!spec->loopback.amplist)
14946 spec->loopback.amplist = alc861_loopbacks; 15287 spec->loopback.amplist = alc861_loopbacks;
14947#endif 15288#endif
14948 codec->proc_widget_hook = print_realtek_coef;
14949 15289
14950 return 0; 15290 return 0;
14951} 15291}
@@ -15572,7 +15912,7 @@ static struct alc_config_preset alc861vd_presets[] = {
15572static int alc861vd_auto_create_input_ctls(struct hda_codec *codec, 15912static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
15573 const struct auto_pin_cfg *cfg) 15913 const struct auto_pin_cfg *cfg)
15574{ 15914{
15575 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x22, 0); 15915 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x09, 0);
15576} 15916}
15577 15917
15578 15918
@@ -15808,7 +16148,7 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec)
15808 if (err < 0) 16148 if (err < 0)
15809 return err; 16149 return err;
15810 16150
15811 alc_ssid_check(codec, 0x15, 0x1b, 0x14); 16151 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
15812 16152
15813 return 1; 16153 return 1;
15814} 16154}
@@ -15925,7 +16265,6 @@ static int patch_alc861vd(struct hda_codec *codec)
15925 if (!spec->loopback.amplist) 16265 if (!spec->loopback.amplist)
15926 spec->loopback.amplist = alc861vd_loopbacks; 16266 spec->loopback.amplist = alc861vd_loopbacks;
15927#endif 16267#endif
15928 codec->proc_widget_hook = print_realtek_coef;
15929 16268
15930 return 0; 16269 return 0;
15931} 16270}
@@ -16392,13 +16731,6 @@ static struct hda_verb alc662_init_verbs[] = {
16392 /* ADC: mute amp left and right */ 16731 /* ADC: mute amp left and right */
16393 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16732 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16394 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 16733 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16395 /* Front mixer: unmute input/output amp left and right (volume = 0) */
16396
16397 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16398 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16399 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16400 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16401 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16402 16734
16403 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 16735 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16404 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 16736 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
@@ -16448,6 +16780,28 @@ static struct hda_verb alc662_init_verbs[] = {
16448 { } 16780 { }
16449}; 16781};
16450 16782
16783static struct hda_verb alc663_init_verbs[] = {
16784 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16785 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16786 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16787 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16788 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16789 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16790 { }
16791};
16792
16793static struct hda_verb alc272_init_verbs[] = {
16794 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16795 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16796 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16797 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16798 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16799 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16800 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16801 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16802 { }
16803};
16804
16451static struct hda_verb alc662_sue_init_verbs[] = { 16805static struct hda_verb alc662_sue_init_verbs[] = {
16452 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT}, 16806 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
16453 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, 16807 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
@@ -16467,61 +16821,6 @@ static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
16467 {} 16821 {}
16468}; 16822};
16469 16823
16470/*
16471 * generic initialization of ADC, input mixers and output mixers
16472 */
16473static struct hda_verb alc662_auto_init_verbs[] = {
16474 /*
16475 * Unmute ADC and set the default input to mic-in
16476 */
16477 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16478 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16479
16480 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
16481 * mixer widget
16482 * Note: PASD motherboards uses the Line In 2 as the input for front
16483 * panel mic (mic 2)
16484 */
16485 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
16486 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16487 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16488 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16489 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16490 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16491
16492 /*
16493 * Set up output mixers (0x0c - 0x0f)
16494 */
16495 /* set vol=0 to output mixers */
16496 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16497 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16498 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16499
16500 /* set up input amps for analog loopback */
16501 /* Amp Indices: DAC = 0, mixer = 1 */
16502 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16503 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16504 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16505 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16506 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16507 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16508
16509
16510 /* FIXME: use matrix-type input source selection */
16511 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
16512 /* Input mixer */
16513 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16514 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16515 { }
16516};
16517
16518/* additional verbs for ALC663 */
16519static struct hda_verb alc663_auto_init_verbs[] = {
16520 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16521 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16522 { }
16523};
16524
16525static struct hda_verb alc663_m51va_init_verbs[] = { 16824static struct hda_verb alc663_m51va_init_verbs[] = {
16526 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16825 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16527 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16826 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
@@ -17272,6 +17571,7 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = {
17272 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1), 17571 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
17273 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1), 17572 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
17274 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3), 17573 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
17574 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
17275 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3), 17575 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
17276 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1), 17576 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
17277 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2), 17577 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
@@ -17307,6 +17607,7 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = {
17307 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3), 17607 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
17308 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3), 17608 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
17309 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1), 17609 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
17610 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
17310 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1), 17611 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
17311 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1), 17612 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
17312 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1), 17613 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
@@ -17334,6 +17635,7 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = {
17334 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10), 17635 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
17335 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L", 17636 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
17336 ALC662_3ST_6ch_DIG), 17637 ALC662_3ST_6ch_DIG),
17638 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
17337 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG), 17639 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
17338 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA), 17640 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
17339 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E), 17641 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
@@ -17952,15 +18254,23 @@ static int alc662_parse_auto_config(struct hda_codec *codec)
17952 spec->num_mux_defs = 1; 18254 spec->num_mux_defs = 1;
17953 spec->input_mux = &spec->private_imux[0]; 18255 spec->input_mux = &spec->private_imux[0];
17954 18256
17955 add_verb(spec, alc662_auto_init_verbs); 18257 add_verb(spec, alc662_init_verbs);
17956 if (codec->vendor_id == 0x10ec0663) 18258 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
17957 add_verb(spec, alc663_auto_init_verbs); 18259 codec->vendor_id == 0x10ec0665)
18260 add_verb(spec, alc663_init_verbs);
18261
18262 if (codec->vendor_id == 0x10ec0272)
18263 add_verb(spec, alc272_init_verbs);
17958 18264
17959 err = alc_auto_add_mic_boost(codec); 18265 err = alc_auto_add_mic_boost(codec);
17960 if (err < 0) 18266 if (err < 0)
17961 return err; 18267 return err;
17962 18268
17963 alc_ssid_check(codec, 0x15, 0x1b, 0x14); 18269 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
18270 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
18271 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
18272 else
18273 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
17964 18274
17965 return 1; 18275 return 1;
17966} 18276}
@@ -18046,11 +18356,20 @@ static int patch_alc662(struct hda_codec *codec)
18046 18356
18047 if (!spec->cap_mixer) 18357 if (!spec->cap_mixer)
18048 set_capture_mixer(codec); 18358 set_capture_mixer(codec);
18049 if (codec->vendor_id == 0x10ec0662) 18359
18360 switch (codec->vendor_id) {
18361 case 0x10ec0662:
18050 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 18362 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
18051 else 18363 break;
18364 case 0x10ec0272:
18365 case 0x10ec0663:
18366 case 0x10ec0665:
18052 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); 18367 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
18053 18368 break;
18369 case 0x10ec0273:
18370 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
18371 break;
18372 }
18054 spec->vmaster_nid = 0x02; 18373 spec->vmaster_nid = 0x02;
18055 18374
18056 codec->patch_ops = alc_patch_ops; 18375 codec->patch_ops = alc_patch_ops;
@@ -18060,7 +18379,6 @@ static int patch_alc662(struct hda_codec *codec)
18060 if (!spec->loopback.amplist) 18379 if (!spec->loopback.amplist)
18061 spec->loopback.amplist = alc662_loopbacks; 18380 spec->loopback.amplist = alc662_loopbacks;
18062#endif 18381#endif
18063 codec->proc_widget_hook = print_realtek_coef;
18064 18382
18065 return 0; 18383 return 0;
18066} 18384}
@@ -18101,6 +18419,8 @@ static struct hda_codec_preset snd_hda_preset_realtek[] = {
18101 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1", 18419 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
18102 .patch = patch_alc662 }, 18420 .patch = patch_alc662 },
18103 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, 18421 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
18422 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
18423 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
18104 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, 18424 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
18105 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, 18425 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
18106 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 }, 18426 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
diff --git a/sound/pci/hda/patch_si3054.c b/sound/pci/hda/patch_si3054.c
index 43b436c5d01b..f419ee8d75f0 100644
--- a/sound/pci/hda/patch_si3054.c
+++ b/sound/pci/hda/patch_si3054.c
@@ -122,6 +122,7 @@ static int si3054_switch_put(struct snd_kcontrol *kcontrol,
122#define SI3054_KCONTROL(kname,reg,mask) { \ 122#define SI3054_KCONTROL(kname,reg,mask) { \
123 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 123 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
124 .name = kname, \ 124 .name = kname, \
125 .subdevice = HDA_SUBDEV_NID_FLAG | reg, \
125 .info = si3054_switch_info, \ 126 .info = si3054_switch_info, \
126 .get = si3054_switch_get, \ 127 .get = si3054_switch_get, \
127 .put = si3054_switch_put, \ 128 .put = si3054_switch_put, \
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 799ba2570902..8c416bb18a57 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -568,6 +568,11 @@ static hda_nid_t stac92hd83xxx_pin_nids[10] = {
568 0x0f, 0x10, 0x11, 0x1f, 0x20, 568 0x0f, 0x10, 0x11, 0x1f, 0x20,
569}; 569};
570 570
571static hda_nid_t stac92hd88xxx_pin_nids[10] = {
572 0x0a, 0x0b, 0x0c, 0x0d,
573 0x0f, 0x11, 0x1f, 0x20,
574};
575
571#define STAC92HD71BXX_NUM_PINS 13 576#define STAC92HD71BXX_NUM_PINS 13
572static hda_nid_t stac92hd71bxx_pin_nids_4port[STAC92HD71BXX_NUM_PINS] = { 577static hda_nid_t stac92hd71bxx_pin_nids_4port[STAC92HD71BXX_NUM_PINS] = {
573 0x0a, 0x0b, 0x0c, 0x0d, 0x00, 578 0x0a, 0x0b, 0x0c, 0x0d, 0x00,
@@ -2688,7 +2693,7 @@ static struct snd_kcontrol_new *
2688stac_control_new(struct sigmatel_spec *spec, 2693stac_control_new(struct sigmatel_spec *spec,
2689 struct snd_kcontrol_new *ktemp, 2694 struct snd_kcontrol_new *ktemp,
2690 const char *name, 2695 const char *name,
2691 hda_nid_t nid) 2696 unsigned int subdev)
2692{ 2697{
2693 struct snd_kcontrol_new *knew; 2698 struct snd_kcontrol_new *knew;
2694 2699
@@ -2704,8 +2709,7 @@ stac_control_new(struct sigmatel_spec *spec,
2704 spec->kctls.alloced--; 2709 spec->kctls.alloced--;
2705 return NULL; 2710 return NULL;
2706 } 2711 }
2707 if (nid) 2712 knew->subdevice = subdev;
2708 knew->subdevice = HDA_SUBDEV_NID_FLAG | nid;
2709 return knew; 2713 return knew;
2710} 2714}
2711 2715
@@ -2715,7 +2719,7 @@ static int stac92xx_add_control_temp(struct sigmatel_spec *spec,
2715 unsigned long val) 2719 unsigned long val)
2716{ 2720{
2717 struct snd_kcontrol_new *knew = stac_control_new(spec, ktemp, name, 2721 struct snd_kcontrol_new *knew = stac_control_new(spec, ktemp, name,
2718 get_amp_nid_(val)); 2722 HDA_SUBDEV_AMP_FLAG);
2719 if (!knew) 2723 if (!knew)
2720 return -ENOMEM; 2724 return -ENOMEM;
2721 knew->index = idx; 2725 knew->index = idx;
@@ -2874,6 +2878,13 @@ static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t nid)
2874 2878
2875 conn_len = snd_hda_get_connections(codec, nid, conn, 2879 conn_len = snd_hda_get_connections(codec, nid, conn,
2876 HDA_MAX_CONNECTIONS); 2880 HDA_MAX_CONNECTIONS);
2881 /* 92HD88: trace back up the link of nids to find the DAC */
2882 while (conn_len == 1 && (get_wcaps_type(get_wcaps(codec, conn[0]))
2883 != AC_WID_AUD_OUT)) {
2884 nid = conn[0];
2885 conn_len = snd_hda_get_connections(codec, nid, conn,
2886 HDA_MAX_CONNECTIONS);
2887 }
2877 for (j = 0; j < conn_len; j++) { 2888 for (j = 0; j < conn_len; j++) {
2878 wcaps = get_wcaps(codec, conn[j]); 2889 wcaps = get_wcaps(codec, conn[j]);
2879 wtype = get_wcaps_type(wcaps); 2890 wtype = get_wcaps_type(wcaps);
@@ -4160,34 +4171,52 @@ static void stac92xx_power_down(struct hda_codec *codec)
4160static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid, 4171static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid,
4161 int enable); 4172 int enable);
4162 4173
4174static inline int get_int_hint(struct hda_codec *codec, const char *key,
4175 int *valp)
4176{
4177 const char *p;
4178 p = snd_hda_get_hint(codec, key);
4179 if (p) {
4180 unsigned long val;
4181 if (!strict_strtoul(p, 0, &val)) {
4182 *valp = val;
4183 return 1;
4184 }
4185 }
4186 return 0;
4187}
4188
4163/* override some hints from the hwdep entry */ 4189/* override some hints from the hwdep entry */
4164static void stac_store_hints(struct hda_codec *codec) 4190static void stac_store_hints(struct hda_codec *codec)
4165{ 4191{
4166 struct sigmatel_spec *spec = codec->spec; 4192 struct sigmatel_spec *spec = codec->spec;
4167 const char *p;
4168 int val; 4193 int val;
4169 4194
4170 val = snd_hda_get_bool_hint(codec, "hp_detect"); 4195 val = snd_hda_get_bool_hint(codec, "hp_detect");
4171 if (val >= 0) 4196 if (val >= 0)
4172 spec->hp_detect = val; 4197 spec->hp_detect = val;
4173 p = snd_hda_get_hint(codec, "gpio_mask"); 4198 if (get_int_hint(codec, "gpio_mask", &spec->gpio_mask)) {
4174 if (p) {
4175 spec->gpio_mask = simple_strtoul(p, NULL, 0);
4176 spec->eapd_mask = spec->gpio_dir = spec->gpio_data = 4199 spec->eapd_mask = spec->gpio_dir = spec->gpio_data =
4177 spec->gpio_mask; 4200 spec->gpio_mask;
4178 } 4201 }
4179 p = snd_hda_get_hint(codec, "gpio_dir"); 4202 if (get_int_hint(codec, "gpio_dir", &spec->gpio_dir))
4180 if (p) 4203 spec->gpio_mask &= spec->gpio_mask;
4181 spec->gpio_dir = simple_strtoul(p, NULL, 0) & spec->gpio_mask; 4204 if (get_int_hint(codec, "gpio_data", &spec->gpio_data))
4182 p = snd_hda_get_hint(codec, "gpio_data"); 4205 spec->gpio_dir &= spec->gpio_mask;
4183 if (p) 4206 if (get_int_hint(codec, "eapd_mask", &spec->eapd_mask))
4184 spec->gpio_data = simple_strtoul(p, NULL, 0) & spec->gpio_mask; 4207 spec->eapd_mask &= spec->gpio_mask;
4185 p = snd_hda_get_hint(codec, "eapd_mask"); 4208 if (get_int_hint(codec, "gpio_mute", &spec->gpio_mute))
4186 if (p) 4209 spec->gpio_mute &= spec->gpio_mask;
4187 spec->eapd_mask = simple_strtoul(p, NULL, 0) & spec->gpio_mask;
4188 val = snd_hda_get_bool_hint(codec, "eapd_switch"); 4210 val = snd_hda_get_bool_hint(codec, "eapd_switch");
4189 if (val >= 0) 4211 if (val >= 0)
4190 spec->eapd_switch = val; 4212 spec->eapd_switch = val;
4213 get_int_hint(codec, "gpio_led_polarity", &spec->gpio_led_polarity);
4214 if (get_int_hint(codec, "gpio_led", &spec->gpio_led)) {
4215 spec->gpio_mask |= spec->gpio_led;
4216 spec->gpio_dir |= spec->gpio_led;
4217 if (spec->gpio_led_polarity)
4218 spec->gpio_data |= spec->gpio_led;
4219 }
4191} 4220}
4192 4221
4193static int stac92xx_init(struct hda_codec *codec) 4222static int stac92xx_init(struct hda_codec *codec)
@@ -4334,6 +4363,12 @@ static int stac92xx_init(struct hda_codec *codec)
4334 if (enable_pin_detect(codec, nid, STAC_PWR_EVENT)) 4363 if (enable_pin_detect(codec, nid, STAC_PWR_EVENT))
4335 stac_issue_unsol_event(codec, nid); 4364 stac_issue_unsol_event(codec, nid);
4336 } 4365 }
4366
4367#ifdef CONFIG_SND_HDA_POWER_SAVE
4368 /* sync mute LED */
4369 if (spec->gpio_led && codec->patch_ops.check_power_status)
4370 codec->patch_ops.check_power_status(codec, 0x01);
4371#endif
4337 if (spec->dac_list) 4372 if (spec->dac_list)
4338 stac92xx_power_down(codec); 4373 stac92xx_power_down(codec);
4339 return 0; 4374 return 0;
@@ -4372,18 +4407,8 @@ static void stac92xx_free_kctls(struct hda_codec *codec)
4372static void stac92xx_shutup(struct hda_codec *codec) 4407static void stac92xx_shutup(struct hda_codec *codec)
4373{ 4408{
4374 struct sigmatel_spec *spec = codec->spec; 4409 struct sigmatel_spec *spec = codec->spec;
4375 int i;
4376 hda_nid_t nid;
4377 4410
4378 /* reset each pin before powering down DAC/ADC to avoid click noise */ 4411 snd_hda_shutup_pins(codec);
4379 nid = codec->start_nid;
4380 for (i = 0; i < codec->num_nodes; i++, nid++) {
4381 unsigned int wcaps = get_wcaps(codec, nid);
4382 unsigned int wid_type = get_wcaps_type(wcaps);
4383 if (wid_type == AC_WID_PIN)
4384 snd_hda_codec_read(codec, nid, 0,
4385 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
4386 }
4387 4412
4388 if (spec->eapd_mask) 4413 if (spec->eapd_mask)
4389 stac_gpio_set(codec, spec->gpio_mask, 4414 stac_gpio_set(codec, spec->gpio_mask,
@@ -4735,19 +4760,14 @@ static int hp_blike_system(u32 subsystem_id);
4735static void set_hp_led_gpio(struct hda_codec *codec) 4760static void set_hp_led_gpio(struct hda_codec *codec)
4736{ 4761{
4737 struct sigmatel_spec *spec = codec->spec; 4762 struct sigmatel_spec *spec = codec->spec;
4738 switch (codec->vendor_id) { 4763 unsigned int gpio;
4739 case 0x111d7608: 4764
4740 /* GPIO 0 */ 4765 gpio = snd_hda_param_read(codec, codec->afg, AC_PAR_GPIO_CAP);
4741 spec->gpio_led = 0x01; 4766 gpio &= AC_GPIO_IO_COUNT;
4742 break; 4767 if (gpio > 3)
4743 case 0x111d7600: 4768 spec->gpio_led = 0x08; /* GPIO 3 */
4744 case 0x111d7601: 4769 else
4745 case 0x111d7602: 4770 spec->gpio_led = 0x01; /* GPIO 0 */
4746 case 0x111d7603:
4747 /* GPIO 3 */
4748 spec->gpio_led = 0x08;
4749 break;
4750 }
4751} 4771}
4752 4772
4753/* 4773/*
@@ -4770,7 +4790,7 @@ static void set_hp_led_gpio(struct hda_codec *codec)
4770 * Need more information on whether it is true across the entire series. 4790 * Need more information on whether it is true across the entire series.
4771 * -- kunal 4791 * -- kunal
4772 */ 4792 */
4773static int find_mute_led_gpio(struct hda_codec *codec) 4793static int find_mute_led_gpio(struct hda_codec *codec, int default_polarity)
4774{ 4794{
4775 struct sigmatel_spec *spec = codec->spec; 4795 struct sigmatel_spec *spec = codec->spec;
4776 const struct dmi_device *dev = NULL; 4796 const struct dmi_device *dev = NULL;
@@ -4797,7 +4817,7 @@ static int find_mute_led_gpio(struct hda_codec *codec)
4797 */ 4817 */
4798 if (!hp_blike_system(codec->subsystem_id)) { 4818 if (!hp_blike_system(codec->subsystem_id)) {
4799 set_hp_led_gpio(codec); 4819 set_hp_led_gpio(codec);
4800 spec->gpio_led_polarity = 1; 4820 spec->gpio_led_polarity = default_polarity;
4801 return 1; 4821 return 1;
4802 } 4822 }
4803 } 4823 }
@@ -4895,6 +4915,11 @@ static int stac92xx_resume(struct hda_codec *codec)
4895 stac_issue_unsol_event(codec, 4915 stac_issue_unsol_event(codec,
4896 spec->autocfg.line_out_pins[0]); 4916 spec->autocfg.line_out_pins[0]);
4897 } 4917 }
4918#ifdef CONFIG_SND_HDA_POWER_SAVE
4919 /* sync mute LED */
4920 if (spec->gpio_led && codec->patch_ops.check_power_status)
4921 codec->patch_ops.check_power_status(codec, 0x01);
4922#endif
4898 return 0; 4923 return 0;
4899} 4924}
4900 4925
@@ -4914,43 +4939,29 @@ static int stac92xx_hp_check_power_status(struct hda_codec *codec,
4914 hda_nid_t nid) 4939 hda_nid_t nid)
4915{ 4940{
4916 struct sigmatel_spec *spec = codec->spec; 4941 struct sigmatel_spec *spec = codec->spec;
4942 int i, muted = 1;
4917 4943
4918 if (nid == 0x10) { 4944 for (i = 0; i < spec->multiout.num_dacs; i++) {
4919 if (snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) & 4945 nid = spec->multiout.dac_nids[i];
4920 HDA_AMP_MUTE) 4946 if (!(snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) &
4921 spec->gpio_data &= ~spec->gpio_led; /* orange */ 4947 HDA_AMP_MUTE)) {
4922 else 4948 muted = 0; /* something heard */
4923 spec->gpio_data |= spec->gpio_led; /* white */ 4949 break;
4924
4925 if (!spec->gpio_led_polarity) {
4926 /* LED state is inverted on these systems */
4927 spec->gpio_data ^= spec->gpio_led;
4928 } 4950 }
4929
4930 stac_gpio_set(codec, spec->gpio_mask,
4931 spec->gpio_dir,
4932 spec->gpio_data);
4933 } 4951 }
4952 if (muted)
4953 spec->gpio_data &= ~spec->gpio_led; /* orange */
4954 else
4955 spec->gpio_data |= spec->gpio_led; /* white */
4934 4956
4935 return 0; 4957 if (!spec->gpio_led_polarity) {
4936} 4958 /* LED state is inverted on these systems */
4937 4959 spec->gpio_data ^= spec->gpio_led;
4938static int idt92hd83xxx_hp_check_power_status(struct hda_codec *codec, 4960 }
4939 hda_nid_t nid)
4940{
4941 struct sigmatel_spec *spec = codec->spec;
4942 4961
4943 if (nid != 0x13)
4944 return 0;
4945 if (snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) & HDA_AMP_MUTE)
4946 spec->gpio_data |= spec->gpio_led; /* mute LED on */
4947 else
4948 spec->gpio_data &= ~spec->gpio_led; /* mute LED off */
4949 stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data); 4962 stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data);
4950
4951 return 0; 4963 return 0;
4952} 4964}
4953
4954#endif 4965#endif
4955 4966
4956static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state) 4967static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state)
@@ -5272,7 +5283,6 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)
5272 hda_nid_t conn[STAC92HD83_DAC_COUNT + 1]; 5283 hda_nid_t conn[STAC92HD83_DAC_COUNT + 1];
5273 int err; 5284 int err;
5274 int num_dacs; 5285 int num_dacs;
5275 hda_nid_t nid;
5276 5286
5277 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 5287 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5278 if (spec == NULL) 5288 if (spec == NULL)
@@ -5311,7 +5321,18 @@ again:
5311 stac92hd83xxx_brd_tbl[spec->board_config]); 5321 stac92hd83xxx_brd_tbl[spec->board_config]);
5312 5322
5313 switch (codec->vendor_id) { 5323 switch (codec->vendor_id) {
5324 case 0x111d7666:
5325 case 0x111d7667:
5326 case 0x111d7668:
5327 case 0x111d7669:
5328 spec->num_pins = ARRAY_SIZE(stac92hd88xxx_pin_nids);
5329 spec->pin_nids = stac92hd88xxx_pin_nids;
5330 spec->mono_nid = 0;
5331 spec->digbeep_nid = 0;
5332 spec->num_pwrs = 0;
5333 break;
5314 case 0x111d7604: 5334 case 0x111d7604:
5335 case 0x111d76d4:
5315 case 0x111d7605: 5336 case 0x111d7605:
5316 case 0x111d76d5: 5337 case 0x111d76d5:
5317 if (spec->board_config == STAC_92HD83XXX_PWR_REF) 5338 if (spec->board_config == STAC_92HD83XXX_PWR_REF)
@@ -5322,8 +5343,10 @@ again:
5322 5343
5323 codec->patch_ops = stac92xx_patch_ops; 5344 codec->patch_ops = stac92xx_patch_ops;
5324 5345
5325 if (spec->board_config == STAC_92HD83XXX_HP) 5346 if (find_mute_led_gpio(codec, 0))
5326 spec->gpio_led = 0x01; 5347 snd_printd("mute LED gpio %d polarity %d\n",
5348 spec->gpio_led,
5349 spec->gpio_led_polarity);
5327 5350
5328#ifdef CONFIG_SND_HDA_POWER_SAVE 5351#ifdef CONFIG_SND_HDA_POWER_SAVE
5329 if (spec->gpio_led) { 5352 if (spec->gpio_led) {
@@ -5332,7 +5355,7 @@ again:
5332 spec->gpio_data |= spec->gpio_led; 5355 spec->gpio_data |= spec->gpio_led;
5333 /* register check_power_status callback. */ 5356 /* register check_power_status callback. */
5334 codec->patch_ops.check_power_status = 5357 codec->patch_ops.check_power_status =
5335 idt92hd83xxx_hp_check_power_status; 5358 stac92xx_hp_check_power_status;
5336 } 5359 }
5337#endif 5360#endif
5338 5361
@@ -5352,24 +5375,21 @@ again:
5352 return err; 5375 return err;
5353 } 5376 }
5354 5377
5355 switch (spec->board_config) { 5378 /* docking output support */
5356 case STAC_DELL_S14: 5379 num_dacs = snd_hda_get_connections(codec, 0xF,
5357 nid = 0xf;
5358 break;
5359 default:
5360 nid = 0xe;
5361 break;
5362 }
5363
5364 num_dacs = snd_hda_get_connections(codec, nid,
5365 conn, STAC92HD83_DAC_COUNT + 1) - 1; 5380 conn, STAC92HD83_DAC_COUNT + 1) - 1;
5366 if (num_dacs < 0) 5381 /* skip non-DAC connections */
5367 num_dacs = STAC92HD83_DAC_COUNT; 5382 while (num_dacs >= 0 &&
5368 5383 (get_wcaps_type(get_wcaps(codec, conn[num_dacs]))
5369 /* set port X to select the last DAC 5384 != AC_WID_AUD_OUT))
5370 */ 5385 num_dacs--;
5371 snd_hda_codec_write_cache(codec, nid, 0, 5386 /* set port E and F to select the last DAC */
5387 if (num_dacs >= 0) {
5388 snd_hda_codec_write_cache(codec, 0xE, 0,
5389 AC_VERB_SET_CONNECT_SEL, num_dacs);
5390 snd_hda_codec_write_cache(codec, 0xF, 0,
5372 AC_VERB_SET_CONNECT_SEL, num_dacs); 5391 AC_VERB_SET_CONNECT_SEL, num_dacs);
5392 }
5373 5393
5374 codec->proc_widget_hook = stac92hd_proc_hook; 5394 codec->proc_widget_hook = stac92hd_proc_hook;
5375 5395
@@ -5431,6 +5451,54 @@ static int stac92hd71bxx_connected_smuxes(struct hda_codec *codec,
5431 return 0; 5451 return 0;
5432} 5452}
5433 5453
5454/* HP dv7 bass switch - GPIO5 */
5455#define stac_hp_bass_gpio_info snd_ctl_boolean_mono_info
5456static int stac_hp_bass_gpio_get(struct snd_kcontrol *kcontrol,
5457 struct snd_ctl_elem_value *ucontrol)
5458{
5459 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5460 struct sigmatel_spec *spec = codec->spec;
5461 ucontrol->value.integer.value[0] = !!(spec->gpio_data & 0x20);
5462 return 0;
5463}
5464
5465static int stac_hp_bass_gpio_put(struct snd_kcontrol *kcontrol,
5466 struct snd_ctl_elem_value *ucontrol)
5467{
5468 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5469 struct sigmatel_spec *spec = codec->spec;
5470 unsigned int gpio_data;
5471
5472 gpio_data = (spec->gpio_data & ~0x20) |
5473 (ucontrol->value.integer.value[0] ? 0x20 : 0);
5474 if (gpio_data == spec->gpio_data)
5475 return 0;
5476 spec->gpio_data = gpio_data;
5477 stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data);
5478 return 1;
5479}
5480
5481static struct snd_kcontrol_new stac_hp_bass_sw_ctrl = {
5482 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5483 .info = stac_hp_bass_gpio_info,
5484 .get = stac_hp_bass_gpio_get,
5485 .put = stac_hp_bass_gpio_put,
5486};
5487
5488static int stac_add_hp_bass_switch(struct hda_codec *codec)
5489{
5490 struct sigmatel_spec *spec = codec->spec;
5491
5492 if (!stac_control_new(spec, &stac_hp_bass_sw_ctrl,
5493 "Bass Speaker Playback Switch", 0))
5494 return -ENOMEM;
5495
5496 spec->gpio_mask |= 0x20;
5497 spec->gpio_dir |= 0x20;
5498 spec->gpio_data |= 0x20;
5499 return 0;
5500}
5501
5434static int patch_stac92hd71bxx(struct hda_codec *codec) 5502static int patch_stac92hd71bxx(struct hda_codec *codec)
5435{ 5503{
5436 struct sigmatel_spec *spec; 5504 struct sigmatel_spec *spec;
@@ -5602,7 +5670,6 @@ again:
5602 */ 5670 */
5603 spec->num_smuxes = 1; 5671 spec->num_smuxes = 1;
5604 spec->num_dmuxes = 1; 5672 spec->num_dmuxes = 1;
5605 spec->gpio_led = 0x01;
5606 /* fallthrough */ 5673 /* fallthrough */
5607 case STAC_HP_DV5: 5674 case STAC_HP_DV5:
5608 snd_hda_codec_set_pincfg(codec, 0x0d, 0x90170010); 5675 snd_hda_codec_set_pincfg(codec, 0x0d, 0x90170010);
@@ -5617,8 +5684,6 @@ again:
5617 spec->num_dmics = 1; 5684 spec->num_dmics = 1;
5618 spec->num_dmuxes = 1; 5685 spec->num_dmuxes = 1;
5619 spec->num_smuxes = 1; 5686 spec->num_smuxes = 1;
5620 /* orange/white mute led on GPIO3, orange=0, white=1 */
5621 spec->gpio_led = 0x08;
5622 break; 5687 break;
5623 } 5688 }
5624 5689
@@ -5640,7 +5705,7 @@ again:
5640 } 5705 }
5641 } 5706 }
5642 5707
5643 if (find_mute_led_gpio(codec)) 5708 if (find_mute_led_gpio(codec, 1))
5644 snd_printd("mute LED gpio %d polarity %d\n", 5709 snd_printd("mute LED gpio %d polarity %d\n",
5645 spec->gpio_led, 5710 spec->gpio_led,
5646 spec->gpio_led_polarity); 5711 spec->gpio_led_polarity);
@@ -5674,6 +5739,15 @@ again:
5674 return err; 5739 return err;
5675 } 5740 }
5676 5741
5742 /* enable bass on HP dv7 */
5743 if (spec->board_config == STAC_HP_DV5) {
5744 unsigned int cap;
5745 cap = snd_hda_param_read(codec, 0x1, AC_PAR_GPIO_CAP);
5746 cap &= AC_GPIO_IO_COUNT;
5747 if (cap >= 6)
5748 stac_add_hp_bass_switch(codec);
5749 }
5750
5677 codec->proc_widget_hook = stac92hd7x_proc_hook; 5751 codec->proc_widget_hook = stac92hd7x_proc_hook;
5678 5752
5679 return 0; 5753 return 0;
@@ -6172,8 +6246,13 @@ static struct hda_codec_preset snd_hda_preset_sigmatel[] = {
6172 { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 }, 6246 { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 },
6173 { .id = 0x111d7603, .name = "92HD75B3X5", .patch = patch_stac92hd71bxx}, 6247 { .id = 0x111d7603, .name = "92HD75B3X5", .patch = patch_stac92hd71bxx},
6174 { .id = 0x111d7604, .name = "92HD83C1X5", .patch = patch_stac92hd83xxx}, 6248 { .id = 0x111d7604, .name = "92HD83C1X5", .patch = patch_stac92hd83xxx},
6249 { .id = 0x111d76d4, .name = "92HD83C1C5", .patch = patch_stac92hd83xxx},
6175 { .id = 0x111d7605, .name = "92HD81B1X5", .patch = patch_stac92hd83xxx}, 6250 { .id = 0x111d7605, .name = "92HD81B1X5", .patch = patch_stac92hd83xxx},
6176 { .id = 0x111d76d5, .name = "92HD81B1C5", .patch = patch_stac92hd83xxx}, 6251 { .id = 0x111d76d5, .name = "92HD81B1C5", .patch = patch_stac92hd83xxx},
6252 { .id = 0x111d7666, .name = "92HD88B3", .patch = patch_stac92hd83xxx},
6253 { .id = 0x111d7667, .name = "92HD88B1", .patch = patch_stac92hd83xxx},
6254 { .id = 0x111d7668, .name = "92HD88B2", .patch = patch_stac92hd83xxx},
6255 { .id = 0x111d7669, .name = "92HD88B4", .patch = patch_stac92hd83xxx},
6177 { .id = 0x111d7608, .name = "92HD75B2X5", .patch = patch_stac92hd71bxx}, 6256 { .id = 0x111d7608, .name = "92HD75B2X5", .patch = patch_stac92hd71bxx},
6178 { .id = 0x111d7674, .name = "92HD73D1X5", .patch = patch_stac92hd73xx }, 6257 { .id = 0x111d7674, .name = "92HD73D1X5", .patch = patch_stac92hd73xx },
6179 { .id = 0x111d7675, .name = "92HD73C1X5", .patch = patch_stac92hd73xx }, 6258 { .id = 0x111d7675, .name = "92HD73C1X5", .patch = patch_stac92hd73xx },
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index b70e26ad263f..9ddc37300f6b 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -54,6 +54,8 @@
54#include "hda_codec.h" 54#include "hda_codec.h"
55#include "hda_local.h" 55#include "hda_local.h"
56 56
57#define NID_MAPPING (-1)
58
57/* amp values */ 59/* amp values */
58#define AMP_VAL_IDX_SHIFT 19 60#define AMP_VAL_IDX_SHIFT 19
59#define AMP_VAL_IDX_MASK (0x0f<<19) 61#define AMP_VAL_IDX_MASK (0x0f<<19)
@@ -157,6 +159,19 @@ struct via_spec {
157#endif 159#endif
158}; 160};
159 161
162static struct via_spec * via_new_spec(struct hda_codec *codec)
163{
164 struct via_spec *spec;
165
166 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
167 if (spec == NULL)
168 return NULL;
169
170 codec->spec = spec;
171 spec->codec = codec;
172 return spec;
173}
174
160static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec) 175static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec)
161{ 176{
162 u32 vendor_id = codec->vendor_id; 177 u32 vendor_id = codec->vendor_id;
@@ -443,11 +458,27 @@ static int via_add_control(struct via_spec *spec, int type, const char *name,
443 if (!knew->name) 458 if (!knew->name)
444 return -ENOMEM; 459 return -ENOMEM;
445 if (get_amp_nid_(val)) 460 if (get_amp_nid_(val))
446 knew->subdevice = HDA_SUBDEV_NID_FLAG | get_amp_nid_(val); 461 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
447 knew->private_value = val; 462 knew->private_value = val;
448 return 0; 463 return 0;
449} 464}
450 465
466static struct snd_kcontrol_new *via_clone_control(struct via_spec *spec,
467 struct snd_kcontrol_new *tmpl)
468{
469 struct snd_kcontrol_new *knew;
470
471 snd_array_init(&spec->kctls, sizeof(*knew), 32);
472 knew = snd_array_new(&spec->kctls);
473 if (!knew)
474 return NULL;
475 *knew = *tmpl;
476 knew->name = kstrdup(tmpl->name, GFP_KERNEL);
477 if (!knew->name)
478 return NULL;
479 return 0;
480}
481
451static void via_free_kctls(struct hda_codec *codec) 482static void via_free_kctls(struct hda_codec *codec)
452{ 483{
453 struct via_spec *spec = codec->spec; 484 struct via_spec *spec = codec->spec;
@@ -1088,24 +1119,9 @@ static int via_independent_hp_get(struct snd_kcontrol *kcontrol,
1088 struct snd_ctl_elem_value *ucontrol) 1119 struct snd_ctl_elem_value *ucontrol)
1089{ 1120{
1090 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1121 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1091 struct via_spec *spec = codec->spec; 1122 hda_nid_t nid = kcontrol->private_value;
1092 hda_nid_t nid;
1093 unsigned int pinsel; 1123 unsigned int pinsel;
1094 1124
1095 switch (spec->codec_type) {
1096 case VT1718S:
1097 nid = 0x34;
1098 break;
1099 case VT2002P:
1100 nid = 0x35;
1101 break;
1102 case VT1812:
1103 nid = 0x3d;
1104 break;
1105 default:
1106 nid = spec->autocfg.hp_pins[0];
1107 break;
1108 }
1109 /* use !! to translate conn sel 2 for VT1718S */ 1125 /* use !! to translate conn sel 2 for VT1718S */
1110 pinsel = !!snd_hda_codec_read(codec, nid, 0, 1126 pinsel = !!snd_hda_codec_read(codec, nid, 0,
1111 AC_VERB_GET_CONNECT_SEL, 1127 AC_VERB_GET_CONNECT_SEL,
@@ -1127,29 +1143,24 @@ static void activate_ctl(struct hda_codec *codec, const char *name, int active)
1127 } 1143 }
1128} 1144}
1129 1145
1146static hda_nid_t side_mute_channel(struct via_spec *spec)
1147{
1148 switch (spec->codec_type) {
1149 case VT1708: return 0x1b;
1150 case VT1709_10CH: return 0x29;
1151 case VT1708B_8CH: /* fall thru */
1152 case VT1708S: return 0x27;
1153 default: return 0;
1154 }
1155}
1156
1130static int update_side_mute_status(struct hda_codec *codec) 1157static int update_side_mute_status(struct hda_codec *codec)
1131{ 1158{
1132 /* mute side channel */ 1159 /* mute side channel */
1133 struct via_spec *spec = codec->spec; 1160 struct via_spec *spec = codec->spec;
1134 unsigned int parm = spec->hp_independent_mode 1161 unsigned int parm = spec->hp_independent_mode
1135 ? AMP_OUT_MUTE : AMP_OUT_UNMUTE; 1162 ? AMP_OUT_MUTE : AMP_OUT_UNMUTE;
1136 hda_nid_t sw3; 1163 hda_nid_t sw3 = side_mute_channel(spec);
1137
1138 switch (spec->codec_type) {
1139 case VT1708:
1140 sw3 = 0x1b;
1141 break;
1142 case VT1709_10CH:
1143 sw3 = 0x29;
1144 break;
1145 case VT1708B_8CH:
1146 case VT1708S:
1147 sw3 = 0x27;
1148 break;
1149 default:
1150 sw3 = 0;
1151 break;
1152 }
1153 1164
1154 if (sw3) 1165 if (sw3)
1155 snd_hda_codec_write(codec, sw3, 0, AC_VERB_SET_AMP_GAIN_MUTE, 1166 snd_hda_codec_write(codec, sw3, 0, AC_VERB_SET_AMP_GAIN_MUTE,
@@ -1162,28 +1173,11 @@ static int via_independent_hp_put(struct snd_kcontrol *kcontrol,
1162{ 1173{
1163 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1174 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1164 struct via_spec *spec = codec->spec; 1175 struct via_spec *spec = codec->spec;
1165 hda_nid_t nid = spec->autocfg.hp_pins[0]; 1176 hda_nid_t nid = kcontrol->private_value;
1166 unsigned int pinsel = ucontrol->value.enumerated.item[0]; 1177 unsigned int pinsel = ucontrol->value.enumerated.item[0];
1167 /* Get Independent Mode index of headphone pin widget */ 1178 /* Get Independent Mode index of headphone pin widget */
1168 spec->hp_independent_mode = spec->hp_independent_mode_index == pinsel 1179 spec->hp_independent_mode = spec->hp_independent_mode_index == pinsel
1169 ? 1 : 0; 1180 ? 1 : 0;
1170
1171 switch (spec->codec_type) {
1172 case VT1718S:
1173 nid = 0x34;
1174 pinsel = pinsel ? 2 : 0; /* indep HP use AOW4 (index 2) */
1175 spec->multiout.num_dacs = 4;
1176 break;
1177 case VT2002P:
1178 nid = 0x35;
1179 break;
1180 case VT1812:
1181 nid = 0x3d;
1182 break;
1183 default:
1184 nid = spec->autocfg.hp_pins[0];
1185 break;
1186 }
1187 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, pinsel); 1181 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, pinsel);
1188 1182
1189 if (spec->multiout.hp_nid && spec->multiout.hp_nid 1183 if (spec->multiout.hp_nid && spec->multiout.hp_nid
@@ -1207,18 +1201,55 @@ static int via_independent_hp_put(struct snd_kcontrol *kcontrol,
1207 return 0; 1201 return 0;
1208} 1202}
1209 1203
1210static struct snd_kcontrol_new via_hp_mixer[] = { 1204static struct snd_kcontrol_new via_hp_mixer[2] = {
1211 { 1205 {
1212 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1206 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1213 .name = "Independent HP", 1207 .name = "Independent HP",
1214 .count = 1,
1215 .info = via_independent_hp_info, 1208 .info = via_independent_hp_info,
1216 .get = via_independent_hp_get, 1209 .get = via_independent_hp_get,
1217 .put = via_independent_hp_put, 1210 .put = via_independent_hp_put,
1218 }, 1211 },
1219 { } /* end */ 1212 {
1213 .iface = NID_MAPPING,
1214 .name = "Independent HP",
1215 },
1220}; 1216};
1221 1217
1218static int via_hp_build(struct via_spec *spec)
1219{
1220 struct snd_kcontrol_new *knew;
1221 hda_nid_t nid;
1222
1223 knew = via_clone_control(spec, &via_hp_mixer[0]);
1224 if (knew == NULL)
1225 return -ENOMEM;
1226
1227 switch (spec->codec_type) {
1228 case VT1718S:
1229 nid = 0x34;
1230 break;
1231 case VT2002P:
1232 nid = 0x35;
1233 break;
1234 case VT1812:
1235 nid = 0x3d;
1236 break;
1237 default:
1238 nid = spec->autocfg.hp_pins[0];
1239 break;
1240 }
1241
1242 knew->subdevice = HDA_SUBDEV_NID_FLAG | nid;
1243 knew->private_value = nid;
1244
1245 knew = via_clone_control(spec, &via_hp_mixer[1]);
1246 if (knew == NULL)
1247 return -ENOMEM;
1248 knew->subdevice = side_mute_channel(spec);
1249
1250 return 0;
1251}
1252
1222static void notify_aa_path_ctls(struct hda_codec *codec) 1253static void notify_aa_path_ctls(struct hda_codec *codec)
1223{ 1254{
1224 int i; 1255 int i;
@@ -1376,7 +1407,7 @@ static int via_smart51_put(struct snd_kcontrol *kcontrol,
1376 return 1; 1407 return 1;
1377} 1408}
1378 1409
1379static struct snd_kcontrol_new via_smart51_mixer[] = { 1410static struct snd_kcontrol_new via_smart51_mixer[2] = {
1380 { 1411 {
1381 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1412 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1382 .name = "Smart 5.1", 1413 .name = "Smart 5.1",
@@ -1385,9 +1416,36 @@ static struct snd_kcontrol_new via_smart51_mixer[] = {
1385 .get = via_smart51_get, 1416 .get = via_smart51_get,
1386 .put = via_smart51_put, 1417 .put = via_smart51_put,
1387 }, 1418 },
1388 {} /* end */ 1419 {
1420 .iface = NID_MAPPING,
1421 .name = "Smart 5.1",
1422 }
1389}; 1423};
1390 1424
1425static int via_smart51_build(struct via_spec *spec)
1426{
1427 struct snd_kcontrol_new *knew;
1428 int index[] = { AUTO_PIN_MIC, AUTO_PIN_FRONT_MIC, AUTO_PIN_LINE };
1429 hda_nid_t nid;
1430 int i;
1431
1432 knew = via_clone_control(spec, &via_smart51_mixer[0]);
1433 if (knew == NULL)
1434 return -ENOMEM;
1435
1436 for (i = 0; i < ARRAY_SIZE(index); i++) {
1437 nid = spec->autocfg.input_pins[index[i]];
1438 if (nid) {
1439 knew = via_clone_control(spec, &via_smart51_mixer[1]);
1440 if (knew == NULL)
1441 return -ENOMEM;
1442 knew->subdevice = nid;
1443 }
1444 }
1445
1446 return 0;
1447}
1448
1391/* capture mixer elements */ 1449/* capture mixer elements */
1392static struct snd_kcontrol_new vt1708_capture_mixer[] = { 1450static struct snd_kcontrol_new vt1708_capture_mixer[] = {
1393 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT), 1451 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT),
@@ -1819,8 +1877,9 @@ static struct hda_pcm_stream vt1708_pcm_digital_capture = {
1819static int via_build_controls(struct hda_codec *codec) 1877static int via_build_controls(struct hda_codec *codec)
1820{ 1878{
1821 struct via_spec *spec = codec->spec; 1879 struct via_spec *spec = codec->spec;
1822 int err; 1880 struct snd_kcontrol *kctl;
1823 int i; 1881 struct snd_kcontrol_new *knew;
1882 int err, i;
1824 1883
1825 for (i = 0; i < spec->num_mixers; i++) { 1884 for (i = 0; i < spec->num_mixers; i++) {
1826 err = snd_hda_add_new_ctls(codec, spec->mixers[i]); 1885 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
@@ -1845,6 +1904,27 @@ static int via_build_controls(struct hda_codec *codec)
1845 return err; 1904 return err;
1846 } 1905 }
1847 1906
1907 /* assign Capture Source enums to NID */
1908 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
1909 for (i = 0; kctl && i < kctl->count; i++) {
1910 err = snd_hda_add_nid(codec, kctl, i, spec->mux_nids[i]);
1911 if (err < 0)
1912 return err;
1913 }
1914
1915 /* other nid->control mapping */
1916 for (i = 0; i < spec->num_mixers; i++) {
1917 for (knew = spec->mixers[i]; knew->name; knew++) {
1918 if (knew->iface != NID_MAPPING)
1919 continue;
1920 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
1921 if (kctl == NULL)
1922 continue;
1923 err = snd_hda_add_nid(codec, kctl, 0,
1924 knew->subdevice);
1925 }
1926 }
1927
1848 /* init power states */ 1928 /* init power states */
1849 set_jack_power_state(codec); 1929 set_jack_power_state(codec);
1850 analog_low_current_mode(codec, 1); 1930 analog_low_current_mode(codec, 1);
@@ -2481,9 +2561,9 @@ static int vt1708_parse_auto_config(struct hda_codec *codec)
2481 spec->input_mux = &spec->private_imux[0]; 2561 spec->input_mux = &spec->private_imux[0];
2482 2562
2483 if (spec->hp_mux) 2563 if (spec->hp_mux)
2484 spec->mixers[spec->num_mixers++] = via_hp_mixer; 2564 via_hp_build(spec);
2485 2565
2486 spec->mixers[spec->num_mixers++] = via_smart51_mixer; 2566 via_smart51_build(spec);
2487 return 1; 2567 return 1;
2488} 2568}
2489 2569
@@ -2554,12 +2634,10 @@ static int patch_vt1708(struct hda_codec *codec)
2554 int err; 2634 int err;
2555 2635
2556 /* create a codec specific record */ 2636 /* create a codec specific record */
2557 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 2637 spec = via_new_spec(codec);
2558 if (spec == NULL) 2638 if (spec == NULL)
2559 return -ENOMEM; 2639 return -ENOMEM;
2560 2640
2561 codec->spec = spec;
2562
2563 /* automatic parse from the BIOS config */ 2641 /* automatic parse from the BIOS config */
2564 err = vt1708_parse_auto_config(codec); 2642 err = vt1708_parse_auto_config(codec);
2565 if (err < 0) { 2643 if (err < 0) {
@@ -2597,7 +2675,6 @@ static int patch_vt1708(struct hda_codec *codec)
2597#ifdef CONFIG_SND_HDA_POWER_SAVE 2675#ifdef CONFIG_SND_HDA_POWER_SAVE
2598 spec->loopback.amplist = vt1708_loopbacks; 2676 spec->loopback.amplist = vt1708_loopbacks;
2599#endif 2677#endif
2600 spec->codec = codec;
2601 INIT_DELAYED_WORK(&spec->vt1708_hp_work, vt1708_update_hp_jack_state); 2678 INIT_DELAYED_WORK(&spec->vt1708_hp_work, vt1708_update_hp_jack_state);
2602 return 0; 2679 return 0;
2603} 2680}
@@ -3010,9 +3087,9 @@ static int vt1709_parse_auto_config(struct hda_codec *codec)
3010 spec->input_mux = &spec->private_imux[0]; 3087 spec->input_mux = &spec->private_imux[0];
3011 3088
3012 if (spec->hp_mux) 3089 if (spec->hp_mux)
3013 spec->mixers[spec->num_mixers++] = via_hp_mixer; 3090 via_hp_build(spec);
3014 3091
3015 spec->mixers[spec->num_mixers++] = via_smart51_mixer; 3092 via_smart51_build(spec);
3016 return 1; 3093 return 1;
3017} 3094}
3018 3095
@@ -3032,12 +3109,10 @@ static int patch_vt1709_10ch(struct hda_codec *codec)
3032 int err; 3109 int err;
3033 3110
3034 /* create a codec specific record */ 3111 /* create a codec specific record */
3035 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 3112 spec = via_new_spec(codec);
3036 if (spec == NULL) 3113 if (spec == NULL)
3037 return -ENOMEM; 3114 return -ENOMEM;
3038 3115
3039 codec->spec = spec;
3040
3041 err = vt1709_parse_auto_config(codec); 3116 err = vt1709_parse_auto_config(codec);
3042 if (err < 0) { 3117 if (err < 0) {
3043 via_free(codec); 3118 via_free(codec);
@@ -3126,12 +3201,10 @@ static int patch_vt1709_6ch(struct hda_codec *codec)
3126 int err; 3201 int err;
3127 3202
3128 /* create a codec specific record */ 3203 /* create a codec specific record */
3129 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 3204 spec = via_new_spec(codec);
3130 if (spec == NULL) 3205 if (spec == NULL)
3131 return -ENOMEM; 3206 return -ENOMEM;
3132 3207
3133 codec->spec = spec;
3134
3135 err = vt1709_parse_auto_config(codec); 3208 err = vt1709_parse_auto_config(codec);
3136 if (err < 0) { 3209 if (err < 0) {
3137 via_free(codec); 3210 via_free(codec);
@@ -3581,9 +3654,9 @@ static int vt1708B_parse_auto_config(struct hda_codec *codec)
3581 spec->input_mux = &spec->private_imux[0]; 3654 spec->input_mux = &spec->private_imux[0];
3582 3655
3583 if (spec->hp_mux) 3656 if (spec->hp_mux)
3584 spec->mixers[spec->num_mixers++] = via_hp_mixer; 3657 via_hp_build(spec);
3585 3658
3586 spec->mixers[spec->num_mixers++] = via_smart51_mixer; 3659 via_smart51_build(spec);
3587 return 1; 3660 return 1;
3588} 3661}
3589 3662
@@ -3605,12 +3678,10 @@ static int patch_vt1708B_8ch(struct hda_codec *codec)
3605 if (get_codec_type(codec) == VT1708BCE) 3678 if (get_codec_type(codec) == VT1708BCE)
3606 return patch_vt1708S(codec); 3679 return patch_vt1708S(codec);
3607 /* create a codec specific record */ 3680 /* create a codec specific record */
3608 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 3681 spec = via_new_spec(codec);
3609 if (spec == NULL) 3682 if (spec == NULL)
3610 return -ENOMEM; 3683 return -ENOMEM;
3611 3684
3612 codec->spec = spec;
3613
3614 /* automatic parse from the BIOS config */ 3685 /* automatic parse from the BIOS config */
3615 err = vt1708B_parse_auto_config(codec); 3686 err = vt1708B_parse_auto_config(codec);
3616 if (err < 0) { 3687 if (err < 0) {
@@ -3657,12 +3728,10 @@ static int patch_vt1708B_4ch(struct hda_codec *codec)
3657 int err; 3728 int err;
3658 3729
3659 /* create a codec specific record */ 3730 /* create a codec specific record */
3660 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 3731 spec = via_new_spec(codec);
3661 if (spec == NULL) 3732 if (spec == NULL)
3662 return -ENOMEM; 3733 return -ENOMEM;
3663 3734
3664 codec->spec = spec;
3665
3666 /* automatic parse from the BIOS config */ 3735 /* automatic parse from the BIOS config */
3667 err = vt1708B_parse_auto_config(codec); 3736 err = vt1708B_parse_auto_config(codec);
3668 if (err < 0) { 3737 if (err < 0) {
@@ -4071,9 +4140,9 @@ static int vt1708S_parse_auto_config(struct hda_codec *codec)
4071 spec->input_mux = &spec->private_imux[0]; 4140 spec->input_mux = &spec->private_imux[0];
4072 4141
4073 if (spec->hp_mux) 4142 if (spec->hp_mux)
4074 spec->mixers[spec->num_mixers++] = via_hp_mixer; 4143 via_hp_build(spec);
4075 4144
4076 spec->mixers[spec->num_mixers++] = via_smart51_mixer; 4145 via_smart51_build(spec);
4077 return 1; 4146 return 1;
4078} 4147}
4079 4148
@@ -4103,12 +4172,10 @@ static int patch_vt1708S(struct hda_codec *codec)
4103 int err; 4172 int err;
4104 4173
4105 /* create a codec specific record */ 4174 /* create a codec specific record */
4106 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 4175 spec = via_new_spec(codec);
4107 if (spec == NULL) 4176 if (spec == NULL)
4108 return -ENOMEM; 4177 return -ENOMEM;
4109 4178
4110 codec->spec = spec;
4111
4112 /* automatic parse from the BIOS config */ 4179 /* automatic parse from the BIOS config */
4113 err = vt1708S_parse_auto_config(codec); 4180 err = vt1708S_parse_auto_config(codec);
4114 if (err < 0) { 4181 if (err < 0) {
@@ -4443,7 +4510,7 @@ static int vt1702_parse_auto_config(struct hda_codec *codec)
4443 spec->input_mux = &spec->private_imux[0]; 4510 spec->input_mux = &spec->private_imux[0];
4444 4511
4445 if (spec->hp_mux) 4512 if (spec->hp_mux)
4446 spec->mixers[spec->num_mixers++] = via_hp_mixer; 4513 via_hp_build(spec);
4447 4514
4448 return 1; 4515 return 1;
4449} 4516}
@@ -4464,12 +4531,10 @@ static int patch_vt1702(struct hda_codec *codec)
4464 int err; 4531 int err;
4465 4532
4466 /* create a codec specific record */ 4533 /* create a codec specific record */
4467 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 4534 spec = via_new_spec(codec);
4468 if (spec == NULL) 4535 if (spec == NULL)
4469 return -ENOMEM; 4536 return -ENOMEM;
4470 4537
4471 codec->spec = spec;
4472
4473 /* automatic parse from the BIOS config */ 4538 /* automatic parse from the BIOS config */
4474 err = vt1702_parse_auto_config(codec); 4539 err = vt1702_parse_auto_config(codec);
4475 if (err < 0) { 4540 if (err < 0) {
@@ -4865,9 +4930,9 @@ static int vt1718S_parse_auto_config(struct hda_codec *codec)
4865 spec->input_mux = &spec->private_imux[0]; 4930 spec->input_mux = &spec->private_imux[0];
4866 4931
4867 if (spec->hp_mux) 4932 if (spec->hp_mux)
4868 spec->mixers[spec->num_mixers++] = via_hp_mixer; 4933 via_hp_build(spec);
4869 4934
4870 spec->mixers[spec->num_mixers++] = via_smart51_mixer; 4935 via_smart51_build(spec);
4871 4936
4872 return 1; 4937 return 1;
4873} 4938}
@@ -4888,12 +4953,10 @@ static int patch_vt1718S(struct hda_codec *codec)
4888 int err; 4953 int err;
4889 4954
4890 /* create a codec specific record */ 4955 /* create a codec specific record */
4891 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 4956 spec = via_new_spec(codec);
4892 if (spec == NULL) 4957 if (spec == NULL)
4893 return -ENOMEM; 4958 return -ENOMEM;
4894 4959
4895 codec->spec = spec;
4896
4897 /* automatic parse from the BIOS config */ 4960 /* automatic parse from the BIOS config */
4898 err = vt1718S_parse_auto_config(codec); 4961 err = vt1718S_parse_auto_config(codec);
4899 if (err < 0) { 4962 if (err < 0) {
@@ -5014,6 +5077,7 @@ static struct snd_kcontrol_new vt1716s_dmic_mixer[] = {
5014 { 5077 {
5015 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5078 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5016 .name = "Digital Mic Capture Switch", 5079 .name = "Digital Mic Capture Switch",
5080 .subdevice = HDA_SUBDEV_NID_FLAG | 0x26,
5017 .count = 1, 5081 .count = 1,
5018 .info = vt1716s_dmic_info, 5082 .info = vt1716s_dmic_info,
5019 .get = vt1716s_dmic_get, 5083 .get = vt1716s_dmic_get,
@@ -5361,9 +5425,9 @@ static int vt1716S_parse_auto_config(struct hda_codec *codec)
5361 spec->input_mux = &spec->private_imux[0]; 5425 spec->input_mux = &spec->private_imux[0];
5362 5426
5363 if (spec->hp_mux) 5427 if (spec->hp_mux)
5364 spec->mixers[spec->num_mixers++] = via_hp_mixer; 5428 via_hp_build(spec);
5365 5429
5366 spec->mixers[spec->num_mixers++] = via_smart51_mixer; 5430 via_smart51_build(spec);
5367 5431
5368 return 1; 5432 return 1;
5369} 5433}
@@ -5384,12 +5448,10 @@ static int patch_vt1716S(struct hda_codec *codec)
5384 int err; 5448 int err;
5385 5449
5386 /* create a codec specific record */ 5450 /* create a codec specific record */
5387 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 5451 spec = via_new_spec(codec);
5388 if (spec == NULL) 5452 if (spec == NULL)
5389 return -ENOMEM; 5453 return -ENOMEM;
5390 5454
5391 codec->spec = spec;
5392
5393 /* automatic parse from the BIOS config */ 5455 /* automatic parse from the BIOS config */
5394 err = vt1716S_parse_auto_config(codec); 5456 err = vt1716S_parse_auto_config(codec);
5395 if (err < 0) { 5457 if (err < 0) {
@@ -5719,7 +5781,7 @@ static int vt2002P_parse_auto_config(struct hda_codec *codec)
5719 spec->input_mux = &spec->private_imux[0]; 5781 spec->input_mux = &spec->private_imux[0];
5720 5782
5721 if (spec->hp_mux) 5783 if (spec->hp_mux)
5722 spec->mixers[spec->num_mixers++] = via_hp_mixer; 5784 via_hp_build(spec);
5723 5785
5724 return 1; 5786 return 1;
5725} 5787}
@@ -5741,12 +5803,10 @@ static int patch_vt2002P(struct hda_codec *codec)
5741 int err; 5803 int err;
5742 5804
5743 /* create a codec specific record */ 5805 /* create a codec specific record */
5744 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 5806 spec = via_new_spec(codec);
5745 if (spec == NULL) 5807 if (spec == NULL)
5746 return -ENOMEM; 5808 return -ENOMEM;
5747 5809
5748 codec->spec = spec;
5749
5750 /* automatic parse from the BIOS config */ 5810 /* automatic parse from the BIOS config */
5751 err = vt2002P_parse_auto_config(codec); 5811 err = vt2002P_parse_auto_config(codec);
5752 if (err < 0) { 5812 if (err < 0) {
@@ -6070,7 +6130,7 @@ static int vt1812_parse_auto_config(struct hda_codec *codec)
6070 spec->input_mux = &spec->private_imux[0]; 6130 spec->input_mux = &spec->private_imux[0];
6071 6131
6072 if (spec->hp_mux) 6132 if (spec->hp_mux)
6073 spec->mixers[spec->num_mixers++] = via_hp_mixer; 6133 via_hp_build(spec);
6074 6134
6075 return 1; 6135 return 1;
6076} 6136}
@@ -6092,12 +6152,10 @@ static int patch_vt1812(struct hda_codec *codec)
6092 int err; 6152 int err;
6093 6153
6094 /* create a codec specific record */ 6154 /* create a codec specific record */
6095 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 6155 spec = via_new_spec(codec);
6096 if (spec == NULL) 6156 if (spec == NULL)
6097 return -ENOMEM; 6157 return -ENOMEM;
6098 6158
6099 codec->spec = spec;
6100
6101 /* automatic parse from the BIOS config */ 6159 /* automatic parse from the BIOS config */
6102 err = vt1812_parse_auto_config(codec); 6160 err = vt1812_parse_auto_config(codec);
6103 if (err < 0) { 6161 if (err < 0) {
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
index c7cff6f8168a..4fc6d8bc637e 100644
--- a/sound/pci/ice1712/ice1712.c
+++ b/sound/pci/ice1712/ice1712.c
@@ -106,7 +106,7 @@ module_param_array(dxr_enable, int, NULL, 0444);
106MODULE_PARM_DESC(dxr_enable, "Enable DXR support for Terratec DMX6FIRE."); 106MODULE_PARM_DESC(dxr_enable, "Enable DXR support for Terratec DMX6FIRE.");
107 107
108 108
109static const struct pci_device_id snd_ice1712_ids[] = { 109static DEFINE_PCI_DEVICE_TABLE(snd_ice1712_ids) = {
110 { PCI_VDEVICE(ICE, PCI_DEVICE_ID_ICE_1712), 0 }, /* ICE1712 */ 110 { PCI_VDEVICE(ICE, PCI_DEVICE_ID_ICE_1712), 0 }, /* ICE1712 */
111 { 0, } 111 { 0, }
112}; 112};
@@ -1180,6 +1180,10 @@ static int snd_ice1712_playback_pro_open(struct snd_pcm_substream *substream)
1180 snd_pcm_set_sync(substream); 1180 snd_pcm_set_sync(substream);
1181 snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); 1181 snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
1182 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates); 1182 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);
1183 if (is_pro_rate_locked(ice)) {
1184 runtime->hw.rate_min = PRO_RATE_DEFAULT;
1185 runtime->hw.rate_max = PRO_RATE_DEFAULT;
1186 }
1183 1187
1184 if (ice->spdif.ops.open) 1188 if (ice->spdif.ops.open)
1185 ice->spdif.ops.open(ice, substream); 1189 ice->spdif.ops.open(ice, substream);
@@ -1197,6 +1201,11 @@ static int snd_ice1712_capture_pro_open(struct snd_pcm_substream *substream)
1197 snd_pcm_set_sync(substream); 1201 snd_pcm_set_sync(substream);
1198 snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); 1202 snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
1199 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates); 1203 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);
1204 if (is_pro_rate_locked(ice)) {
1205 runtime->hw.rate_min = PRO_RATE_DEFAULT;
1206 runtime->hw.rate_max = PRO_RATE_DEFAULT;
1207 }
1208
1200 return 0; 1209 return 0;
1201} 1210}
1202 1211
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index ae29073eea93..c1498fa5545f 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -94,7 +94,7 @@ MODULE_PARM_DESC(model, "Use the given board model.");
94 94
95 95
96/* Both VT1720 and VT1724 have the same PCI IDs */ 96/* Both VT1720 and VT1724 have the same PCI IDs */
97static const struct pci_device_id snd_vt1724_ids[] = { 97static DEFINE_PCI_DEVICE_TABLE(snd_vt1724_ids) = {
98 { PCI_VDEVICE(ICE, PCI_DEVICE_ID_VT1724), 0 }, 98 { PCI_VDEVICE(ICE, PCI_DEVICE_ID_VT1724), 0 },
99 { 0, } 99 { 0, }
100}; 100};
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index b990143636f1..6433e65c9507 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -420,7 +420,7 @@ struct intel8x0 {
420 u32 int_sta_mask; /* interrupt status mask */ 420 u32 int_sta_mask; /* interrupt status mask */
421}; 421};
422 422
423static struct pci_device_id snd_intel8x0_ids[] = { 423static DEFINE_PCI_DEVICE_TABLE(snd_intel8x0_ids) = {
424 { PCI_VDEVICE(INTEL, 0x2415), DEVICE_INTEL }, /* 82801AA */ 424 { PCI_VDEVICE(INTEL, 0x2415), DEVICE_INTEL }, /* 82801AA */
425 { PCI_VDEVICE(INTEL, 0x2425), DEVICE_INTEL }, /* 82901AB */ 425 { PCI_VDEVICE(INTEL, 0x2425), DEVICE_INTEL }, /* 82901AB */
426 { PCI_VDEVICE(INTEL, 0x2445), DEVICE_INTEL }, /* 82801BA */ 426 { PCI_VDEVICE(INTEL, 0x2445), DEVICE_INTEL }, /* 82801BA */
diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c
index 9e7d12e7673f..13cec1e5ced9 100644
--- a/sound/pci/intel8x0m.c
+++ b/sound/pci/intel8x0m.c
@@ -219,7 +219,7 @@ struct intel8x0m {
219 unsigned int pcm_pos_shift; 219 unsigned int pcm_pos_shift;
220}; 220};
221 221
222static struct pci_device_id snd_intel8x0m_ids[] = { 222static DEFINE_PCI_DEVICE_TABLE(snd_intel8x0m_ids) = {
223 { PCI_VDEVICE(INTEL, 0x2416), DEVICE_INTEL }, /* 82801AA */ 223 { PCI_VDEVICE(INTEL, 0x2416), DEVICE_INTEL }, /* 82801AA */
224 { PCI_VDEVICE(INTEL, 0x2426), DEVICE_INTEL }, /* 82901AB */ 224 { PCI_VDEVICE(INTEL, 0x2426), DEVICE_INTEL }, /* 82901AB */
225 { PCI_VDEVICE(INTEL, 0x2446), DEVICE_INTEL }, /* 82801BA */ 225 { PCI_VDEVICE(INTEL, 0x2446), DEVICE_INTEL }, /* 82801BA */
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c
index 7cc38a11e997..6d795700be79 100644
--- a/sound/pci/korg1212/korg1212.c
+++ b/sound/pci/korg1212/korg1212.c
@@ -418,7 +418,7 @@ module_param_array(enable, bool, NULL, 0444);
418MODULE_PARM_DESC(enable, "Enable Korg 1212 soundcard."); 418MODULE_PARM_DESC(enable, "Enable Korg 1212 soundcard.");
419MODULE_AUTHOR("Haroldo Gamal <gamal@alternex.com.br>"); 419MODULE_AUTHOR("Haroldo Gamal <gamal@alternex.com.br>");
420 420
421static struct pci_device_id snd_korg1212_ids[] = { 421static DEFINE_PCI_DEVICE_TABLE(snd_korg1212_ids) = {
422 { 422 {
423 .vendor = 0x10b5, 423 .vendor = 0x10b5,
424 .device = 0x906d, 424 .device = 0x906d,
diff --git a/sound/pci/lx6464es/lx6464es.c b/sound/pci/lx6464es/lx6464es.c
index 11b8c6514b3d..0cca56038cd9 100644
--- a/sound/pci/lx6464es/lx6464es.c
+++ b/sound/pci/lx6464es/lx6464es.c
@@ -55,7 +55,7 @@ static const char card_name[] = "LX6464ES";
55 55
56#define PCI_DEVICE_ID_PLX_LX6464ES PCI_DEVICE_ID_PLX_9056 56#define PCI_DEVICE_ID_PLX_LX6464ES PCI_DEVICE_ID_PLX_9056
57 57
58static struct pci_device_id snd_lx6464es_ids[] = { 58static DEFINE_PCI_DEVICE_TABLE(snd_lx6464es_ids) = {
59 { PCI_DEVICE(PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_LX6464ES), 59 { PCI_DEVICE(PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_LX6464ES),
60 .subvendor = PCI_VENDOR_ID_DIGIGRAM, 60 .subvendor = PCI_VENDOR_ID_DIGIGRAM,
61 .subdevice = PCI_SUBDEVICE_ID_DIGIGRAM_LX6464ES_SERIAL_SUBSYSTEM 61 .subdevice = PCI_SUBDEVICE_ID_DIGIGRAM_LX6464ES_SERIAL_SUBSYSTEM
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index 75283fbb4b3f..b64e78139d63 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -861,7 +861,7 @@ struct snd_m3 {
861/* 861/*
862 * pci ids 862 * pci ids
863 */ 863 */
864static struct pci_device_id snd_m3_ids[] = { 864static DEFINE_PCI_DEVICE_TABLE(snd_m3_ids) = {
865 {PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ALLEGRO_1, PCI_ANY_ID, PCI_ANY_ID, 865 {PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ALLEGRO_1, PCI_ANY_ID, PCI_ANY_ID,
866 PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0}, 866 PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0},
867 {PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ALLEGRO, PCI_ANY_ID, PCI_ANY_ID, 867 {PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ALLEGRO, PCI_ANY_ID, PCI_ANY_ID,
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c
index a83d1968a845..7e8e7da592a9 100644
--- a/sound/pci/mixart/mixart.c
+++ b/sound/pci/mixart/mixart.c
@@ -60,7 +60,7 @@ MODULE_PARM_DESC(enable, "Enable Digigram " CARD_NAME " soundcard.");
60/* 60/*
61 */ 61 */
62 62
63static struct pci_device_id snd_mixart_ids[] = { 63static DEFINE_PCI_DEVICE_TABLE(snd_mixart_ids) = {
64 { PCI_VDEVICE(MOTOROLA, 0x0003), 0, }, /* MC8240 */ 64 { PCI_VDEVICE(MOTOROLA, 0x0003), 0, }, /* MC8240 */
65 { 0, } 65 { 0, }
66}; 66};
diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c
index 97a0731331a1..5a60492ac7b3 100644
--- a/sound/pci/nm256/nm256.c
+++ b/sound/pci/nm256/nm256.c
@@ -262,7 +262,7 @@ struct nm256 {
262/* 262/*
263 * PCI ids 263 * PCI ids
264 */ 264 */
265static struct pci_device_id snd_nm256_ids[] = { 265static DEFINE_PCI_DEVICE_TABLE(snd_nm256_ids) = {
266 {PCI_VDEVICE(NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO), 0}, 266 {PCI_VDEVICE(NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO), 0},
267 {PCI_VDEVICE(NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO), 0}, 267 {PCI_VDEVICE(NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO), 0},
268 {PCI_VDEVICE(NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256XL_PLUS_AUDIO), 0}, 268 {PCI_VDEVICE(NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256XL_PLUS_AUDIO), 0},
diff --git a/sound/pci/oxygen/Makefile b/sound/pci/oxygen/Makefile
index 389941cf6100..acd8f15f7bff 100644
--- a/sound/pci/oxygen/Makefile
+++ b/sound/pci/oxygen/Makefile
@@ -2,7 +2,7 @@ snd-oxygen-lib-objs := oxygen_io.o oxygen_lib.o oxygen_mixer.o oxygen_pcm.o
2snd-hifier-objs := hifier.o 2snd-hifier-objs := hifier.o
3snd-oxygen-objs := oxygen.o 3snd-oxygen-objs := oxygen.o
4snd-virtuoso-objs := virtuoso.o xonar_lib.o \ 4snd-virtuoso-objs := virtuoso.o xonar_lib.o \
5 xonar_pcm179x.o xonar_cs43xx.o xonar_hdmi.o 5 xonar_pcm179x.o xonar_cs43xx.o xonar_wm87x6.o xonar_hdmi.o
6 6
7obj-$(CONFIG_SND_OXYGEN_LIB) += snd-oxygen-lib.o 7obj-$(CONFIG_SND_OXYGEN_LIB) += snd-oxygen-lib.o
8obj-$(CONFIG_SND_HIFIER) += snd-hifier.o 8obj-$(CONFIG_SND_HIFIER) += snd-hifier.o
diff --git a/sound/pci/oxygen/hifier.c b/sound/pci/oxygen/hifier.c
index e3c229b63311..5a87d683691f 100644
--- a/sound/pci/oxygen/hifier.c
+++ b/sound/pci/oxygen/hifier.c
@@ -48,7 +48,7 @@ MODULE_PARM_DESC(id, "ID string");
48module_param_array(enable, bool, NULL, 0444); 48module_param_array(enable, bool, NULL, 0444);
49MODULE_PARM_DESC(enable, "enable card"); 49MODULE_PARM_DESC(enable, "enable card");
50 50
51static struct pci_device_id hifier_ids[] __devinitdata = { 51static DEFINE_PCI_DEVICE_TABLE(hifier_ids) = {
52 { OXYGEN_PCI_SUBID(0x14c3, 0x1710) }, 52 { OXYGEN_PCI_SUBID(0x14c3, 0x1710) },
53 { OXYGEN_PCI_SUBID(0x14c3, 0x1711) }, 53 { OXYGEN_PCI_SUBID(0x14c3, 0x1711) },
54 { OXYGEN_PCI_SUBID_BROKEN_EEPROM }, 54 { OXYGEN_PCI_SUBID_BROKEN_EEPROM },
diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c
index acbedebcffd9..289cb4dacfc7 100644
--- a/sound/pci/oxygen/oxygen.c
+++ b/sound/pci/oxygen/oxygen.c
@@ -72,7 +72,7 @@ enum {
72 MODEL_CLARO_HALO, /* HT-Omega Claro halo */ 72 MODEL_CLARO_HALO, /* HT-Omega Claro halo */
73}; 73};
74 74
75static struct pci_device_id oxygen_ids[] __devinitdata = { 75static DEFINE_PCI_DEVICE_TABLE(oxygen_ids) = {
76 { OXYGEN_PCI_SUBID(0x10b0, 0x0216), .driver_data = MODEL_CMEDIA_REF }, 76 { OXYGEN_PCI_SUBID(0x10b0, 0x0216), .driver_data = MODEL_CMEDIA_REF },
77 { OXYGEN_PCI_SUBID(0x10b0, 0x0218), .driver_data = MODEL_CMEDIA_REF }, 77 { OXYGEN_PCI_SUBID(0x10b0, 0x0218), .driver_data = MODEL_CMEDIA_REF },
78 { OXYGEN_PCI_SUBID(0x10b0, 0x0219), .driver_data = MODEL_CMEDIA_REF }, 78 { OXYGEN_PCI_SUBID(0x10b0, 0x0219), .driver_data = MODEL_CMEDIA_REF },
diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c
index 6accaf9580b2..f03a2f2cffee 100644
--- a/sound/pci/oxygen/virtuoso.c
+++ b/sound/pci/oxygen/virtuoso.c
@@ -40,7 +40,7 @@ MODULE_PARM_DESC(id, "ID string");
40module_param_array(enable, bool, NULL, 0444); 40module_param_array(enable, bool, NULL, 0444);
41MODULE_PARM_DESC(enable, "enable card"); 41MODULE_PARM_DESC(enable, "enable card");
42 42
43static struct pci_device_id xonar_ids[] __devinitdata = { 43static DEFINE_PCI_DEVICE_TABLE(xonar_ids) = {
44 { OXYGEN_PCI_SUBID(0x1043, 0x8269) }, 44 { OXYGEN_PCI_SUBID(0x1043, 0x8269) },
45 { OXYGEN_PCI_SUBID(0x1043, 0x8275) }, 45 { OXYGEN_PCI_SUBID(0x1043, 0x8275) },
46 { OXYGEN_PCI_SUBID(0x1043, 0x82b7) }, 46 { OXYGEN_PCI_SUBID(0x1043, 0x82b7) },
@@ -49,6 +49,7 @@ static struct pci_device_id xonar_ids[] __devinitdata = {
49 { OXYGEN_PCI_SUBID(0x1043, 0x834f) }, 49 { OXYGEN_PCI_SUBID(0x1043, 0x834f) },
50 { OXYGEN_PCI_SUBID(0x1043, 0x835c) }, 50 { OXYGEN_PCI_SUBID(0x1043, 0x835c) },
51 { OXYGEN_PCI_SUBID(0x1043, 0x835d) }, 51 { OXYGEN_PCI_SUBID(0x1043, 0x835d) },
52 { OXYGEN_PCI_SUBID(0x1043, 0x838e) },
52 { OXYGEN_PCI_SUBID_BROKEN_EEPROM }, 53 { OXYGEN_PCI_SUBID_BROKEN_EEPROM },
53 { } 54 { }
54}; 55};
@@ -61,6 +62,8 @@ static int __devinit get_xonar_model(struct oxygen *chip,
61 return 0; 62 return 0;
62 if (get_xonar_cs43xx_model(chip, id) >= 0) 63 if (get_xonar_cs43xx_model(chip, id) >= 0)
63 return 0; 64 return 0;
65 if (get_xonar_wm87x6_model(chip, id) >= 0)
66 return 0;
64 return -EINVAL; 67 return -EINVAL;
65} 68}
66 69
diff --git a/sound/pci/oxygen/wm8766.h b/sound/pci/oxygen/wm8766.h
new file mode 100644
index 000000000000..e0e849a7eaeb
--- /dev/null
+++ b/sound/pci/oxygen/wm8766.h
@@ -0,0 +1,73 @@
1#ifndef WM8766_H_INCLUDED
2#define WM8766_H_INCLUDED
3
4#define WM8766_LDA1 0x00
5#define WM8766_RDA1 0x01
6#define WM8766_DAC_CTRL 0x02
7#define WM8766_INT_CTRL 0x03
8#define WM8766_LDA2 0x04
9#define WM8766_RDA2 0x05
10#define WM8766_LDA3 0x06
11#define WM8766_RDA3 0x07
12#define WM8766_MASTDA 0x08
13#define WM8766_DAC_CTRL2 0x09
14#define WM8766_DAC_CTRL3 0x0a
15#define WM8766_MUTE1 0x0c
16#define WM8766_MUTE2 0x0f
17#define WM8766_RESET 0x1f
18
19/* LDAx/RDAx/MASTDA */
20#define WM8766_ATT_MASK 0x0ff
21#define WM8766_UPDATE 0x100
22/* DAC_CTRL */
23#define WM8766_MUTEALL 0x001
24#define WM8766_DEEMPALL 0x002
25#define WM8766_PWDN 0x004
26#define WM8766_ATC 0x008
27#define WM8766_IZD 0x010
28#define WM8766_PL_LEFT_MASK 0x060
29#define WM8766_PL_LEFT_MUTE 0x000
30#define WM8766_PL_LEFT_LEFT 0x020
31#define WM8766_PL_LEFT_RIGHT 0x040
32#define WM8766_PL_LEFT_LRMIX 0x060
33#define WM8766_PL_RIGHT_MASK 0x180
34#define WM8766_PL_RIGHT_MUTE 0x000
35#define WM8766_PL_RIGHT_LEFT 0x080
36#define WM8766_PL_RIGHT_RIGHT 0x100
37#define WM8766_PL_RIGHT_LRMIX 0x180
38/* INT_CTRL */
39#define WM8766_FMT_MASK 0x003
40#define WM8766_FMT_RJUST 0x000
41#define WM8766_FMT_LJUST 0x001
42#define WM8766_FMT_I2S 0x002
43#define WM8766_FMT_DSP 0x003
44#define WM8766_LRP 0x004
45#define WM8766_BCP 0x008
46#define WM8766_IWL_MASK 0x030
47#define WM8766_IWL_16 0x000
48#define WM8766_IWL_20 0x010
49#define WM8766_IWL_24 0x020
50#define WM8766_IWL_32 0x030
51#define WM8766_PHASE_MASK 0x1c0
52/* DAC_CTRL2 */
53#define WM8766_ZCD 0x001
54#define WM8766_DZFM_MASK 0x006
55#define WM8766_DMUTE_MASK 0x038
56#define WM8766_DEEMP_MASK 0x1c0
57/* DAC_CTRL3 */
58#define WM8766_DACPD_MASK 0x00e
59#define WM8766_PWRDNALL 0x010
60#define WM8766_MS 0x020
61#define WM8766_RATE_MASK 0x1c0
62#define WM8766_RATE_128 0x000
63#define WM8766_RATE_192 0x040
64#define WM8766_RATE_256 0x080
65#define WM8766_RATE_384 0x0c0
66#define WM8766_RATE_512 0x100
67#define WM8766_RATE_768 0x140
68/* MUTE1 */
69#define WM8766_MPD1 0x040
70/* MUTE2 */
71#define WM8766_MPD2 0x020
72
73#endif
diff --git a/sound/pci/oxygen/wm8776.h b/sound/pci/oxygen/wm8776.h
new file mode 100644
index 000000000000..1a96f5615727
--- /dev/null
+++ b/sound/pci/oxygen/wm8776.h
@@ -0,0 +1,177 @@
1#ifndef WM8776_H_INCLUDED
2#define WM8776_H_INCLUDED
3
4/*
5 * the following register names are from:
6 * wm8776.h -- WM8776 ASoC driver
7 *
8 * Copyright 2009 Wolfson Microelectronics plc
9 *
10 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 */
16
17#define WM8776_HPLVOL 0x00
18#define WM8776_HPRVOL 0x01
19#define WM8776_HPMASTER 0x02
20#define WM8776_DACLVOL 0x03
21#define WM8776_DACRVOL 0x04
22#define WM8776_DACMASTER 0x05
23#define WM8776_PHASESWAP 0x06
24#define WM8776_DACCTRL1 0x07
25#define WM8776_DACMUTE 0x08
26#define WM8776_DACCTRL2 0x09
27#define WM8776_DACIFCTRL 0x0a
28#define WM8776_ADCIFCTRL 0x0b
29#define WM8776_MSTRCTRL 0x0c
30#define WM8776_PWRDOWN 0x0d
31#define WM8776_ADCLVOL 0x0e
32#define WM8776_ADCRVOL 0x0f
33#define WM8776_ALCCTRL1 0x10
34#define WM8776_ALCCTRL2 0x11
35#define WM8776_ALCCTRL3 0x12
36#define WM8776_NOISEGATE 0x13
37#define WM8776_LIMITER 0x14
38#define WM8776_ADCMUX 0x15
39#define WM8776_OUTMUX 0x16
40#define WM8776_RESET 0x17
41
42
43/* HPLVOL/HPRVOL/HPMASTER */
44#define WM8776_HPATT_MASK 0x07f
45#define WM8776_HPZCEN 0x080
46#define WM8776_UPDATE 0x100
47
48/* DACLVOL/DACRVOL/DACMASTER */
49#define WM8776_DATT_MASK 0x0ff
50/*#define WM8776_UPDATE 0x100*/
51
52/* PHASESWAP */
53#define WM8776_PH_MASK 0x003
54
55/* DACCTRL1 */
56#define WM8776_DZCEN 0x001
57#define WM8776_ATC 0x002
58#define WM8776_IZD 0x004
59#define WM8776_TOD 0x008
60#define WM8776_PL_LEFT_MASK 0x030
61#define WM8776_PL_LEFT_MUTE 0x000
62#define WM8776_PL_LEFT_LEFT 0x010
63#define WM8776_PL_LEFT_RIGHT 0x020
64#define WM8776_PL_LEFT_LRMIX 0x030
65#define WM8776_PL_RIGHT_MASK 0x0c0
66#define WM8776_PL_RIGHT_MUTE 0x000
67#define WM8776_PL_RIGHT_LEFT 0x040
68#define WM8776_PL_RIGHT_RIGHT 0x080
69#define WM8776_PL_RIGHT_LRMIX 0x0c0
70
71/* DACMUTE */
72#define WM8776_DMUTE 0x001
73
74/* DACCTRL2 */
75#define WM8776_DEEMPH 0x001
76#define WM8776_DZFM_MASK 0x006
77#define WM8776_DZFM_NONE 0x000
78#define WM8776_DZFM_LR 0x002
79#define WM8776_DZFM_BOTH 0x004
80#define WM8776_DZFM_EITHER 0x006
81
82/* DACIFCTRL */
83#define WM8776_DACFMT_MASK 0x003
84#define WM8776_DACFMT_RJUST 0x000
85#define WM8776_DACFMT_LJUST 0x001
86#define WM8776_DACFMT_I2S 0x002
87#define WM8776_DACFMT_DSP 0x003
88#define WM8776_DACLRP 0x004
89#define WM8776_DACBCP 0x008
90#define WM8776_DACWL_MASK 0x030
91#define WM8776_DACWL_16 0x000
92#define WM8776_DACWL_20 0x010
93#define WM8776_DACWL_24 0x020
94#define WM8776_DACWL_32 0x030
95
96/* ADCIFCTRL */
97#define WM8776_ADCFMT_MASK 0x003
98#define WM8776_ADCFMT_RJUST 0x000
99#define WM8776_ADCFMT_LJUST 0x001
100#define WM8776_ADCFMT_I2S 0x002
101#define WM8776_ADCFMT_DSP 0x003
102#define WM8776_ADCLRP 0x004
103#define WM8776_ADCBCP 0x008
104#define WM8776_ADCWL_MASK 0x030
105#define WM8776_ADCWL_16 0x000
106#define WM8776_ADCWL_20 0x010
107#define WM8776_ADCWL_24 0x020
108#define WM8776_ADCWL_32 0x030
109#define WM8776_ADCMCLK 0x040
110#define WM8776_ADCHPD 0x100
111
112/* MSTRCTRL */
113#define WM8776_ADCRATE_MASK 0x007
114#define WM8776_ADCRATE_256 0x002
115#define WM8776_ADCRATE_384 0x003
116#define WM8776_ADCRATE_512 0x004
117#define WM8776_ADCRATE_768 0x005
118#define WM8776_ADCOSR 0x008
119#define WM8776_DACRATE_MASK 0x070
120#define WM8776_DACRATE_128 0x000
121#define WM8776_DACRATE_192 0x010
122#define WM8776_DACRATE_256 0x020
123#define WM8776_DACRATE_384 0x030
124#define WM8776_DACRATE_512 0x040
125#define WM8776_DACRATE_768 0x050
126#define WM8776_DACMS 0x080
127#define WM8776_ADCMS 0x100
128
129/* PWRDOWN */
130#define WM8776_PDWN 0x001
131#define WM8776_ADCPD 0x002
132#define WM8776_DACPD 0x004
133#define WM8776_HPPD 0x008
134#define WM8776_AINPD 0x040
135
136/* ADCLVOL/ADCRVOL */
137#define WM8776_AGMASK 0x0ff
138#define WM8776_ZCA 0x100
139
140/* ALCCTRL1 */
141#define WM8776_LCT_MASK 0x00f
142#define WM8776_MAXGAIN_MASK 0x070
143#define WM8776_LCSEL_MASK 0x180
144#define WM8776_LCSEL_LIMITER 0x000
145#define WM8776_LCSEL_ALC_RIGHT 0x080
146#define WM8776_LCSEL_ALC_LEFT 0x100
147#define WM8776_LCSEL_ALC_STEREO 0x180
148
149/* ALCCTRL2 */
150#define WM8776_HLD_MASK 0x00f
151#define WM8776_ALCZC 0x080
152#define WM8776_LCEN 0x100
153
154/* ALCCTRL3 */
155#define WM8776_ATK_MASK 0x00f
156#define WM8776_DCY_MASK 0x0f0
157
158/* NOISEGATE */
159#define WM8776_NGAT 0x001
160#define WM8776_NGTH_MASK 0x01c
161
162/* LIMITER */
163#define WM8776_MAXATTEN_MASK 0x00f
164#define WM8776_TRANWIN_MASK 0x070
165
166/* ADCMUX */
167#define WM8776_AMX_MASK 0x01f
168#define WM8776_MUTERA 0x040
169#define WM8776_MUTELA 0x080
170#define WM8776_LRBOTH 0x100
171
172/* OUTMUX */
173#define WM8776_MX_DAC 0x001
174#define WM8776_MX_AUX 0x002
175#define WM8776_MX_BYPASS 0x004
176
177#endif
diff --git a/sound/pci/oxygen/xonar.h b/sound/pci/oxygen/xonar.h
index 89b3ed814d64..b35343b0a9a5 100644
--- a/sound/pci/oxygen/xonar.h
+++ b/sound/pci/oxygen/xonar.h
@@ -35,6 +35,8 @@ int get_xonar_pcm179x_model(struct oxygen *chip,
35 const struct pci_device_id *id); 35 const struct pci_device_id *id);
36int get_xonar_cs43xx_model(struct oxygen *chip, 36int get_xonar_cs43xx_model(struct oxygen *chip,
37 const struct pci_device_id *id); 37 const struct pci_device_id *id);
38int get_xonar_wm87x6_model(struct oxygen *chip,
39 const struct pci_device_id *id);
38 40
39/* HDMI helper functions */ 41/* HDMI helper functions */
40 42
diff --git a/sound/pci/oxygen/xonar_wm87x6.c b/sound/pci/oxygen/xonar_wm87x6.c
new file mode 100644
index 000000000000..7754db166d9e
--- /dev/null
+++ b/sound/pci/oxygen/xonar_wm87x6.c
@@ -0,0 +1,1021 @@
1/*
2 * card driver for models with WM8776/WM8766 DACs (Xonar DS)
3 *
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5 *
6 *
7 * This driver is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License, version 2.
9 *
10 * This driver is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this driver; if not, see <http://www.gnu.org/licenses/>.
17 */
18
19/*
20 * Xonar DS
21 * --------
22 *
23 * CMI8788:
24 *
25 * SPI 0 -> WM8766 (surround, center/LFE, back)
26 * SPI 1 -> WM8776 (front, input)
27 *
28 * GPIO 4 <- headphone detect
29 * GPIO 6 -> route input jack to input 1/2 (1/0)
30 * GPIO 7 -> enable output to speakers
31 * GPIO 8 -> enable output to speakers
32 */
33
34#include <linux/pci.h>
35#include <linux/delay.h>
36#include <sound/control.h>
37#include <sound/core.h>
38#include <sound/pcm.h>
39#include <sound/pcm_params.h>
40#include <sound/tlv.h>
41#include "xonar.h"
42#include "wm8776.h"
43#include "wm8766.h"
44
45#define GPIO_DS_HP_DETECT 0x0010
46#define GPIO_DS_INPUT_ROUTE 0x0040
47#define GPIO_DS_OUTPUT_ENABLE 0x0180
48
49#define LC_CONTROL_LIMITER 0x40000000
50#define LC_CONTROL_ALC 0x20000000
51
52struct xonar_wm87x6 {
53 struct xonar_generic generic;
54 u16 wm8776_regs[0x17];
55 u16 wm8766_regs[0x10];
56 struct snd_kcontrol *lc_controls[13];
57};
58
59static void wm8776_write(struct oxygen *chip,
60 unsigned int reg, unsigned int value)
61{
62 struct xonar_wm87x6 *data = chip->model_data;
63
64 oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
65 OXYGEN_SPI_DATA_LENGTH_2 |
66 OXYGEN_SPI_CLOCK_160 |
67 (1 << OXYGEN_SPI_CODEC_SHIFT) |
68 OXYGEN_SPI_CEN_LATCH_CLOCK_LO,
69 (reg << 9) | value);
70 if (reg < ARRAY_SIZE(data->wm8776_regs)) {
71 if (reg >= WM8776_HPLVOL || reg <= WM8776_DACMASTER)
72 value &= ~WM8776_UPDATE;
73 data->wm8776_regs[reg] = value;
74 }
75}
76
77static void wm8776_write_cached(struct oxygen *chip,
78 unsigned int reg, unsigned int value)
79{
80 struct xonar_wm87x6 *data = chip->model_data;
81
82 if (reg >= ARRAY_SIZE(data->wm8776_regs) ||
83 value != data->wm8776_regs[reg])
84 wm8776_write(chip, reg, value);
85}
86
87static void wm8766_write(struct oxygen *chip,
88 unsigned int reg, unsigned int value)
89{
90 struct xonar_wm87x6 *data = chip->model_data;
91
92 oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
93 OXYGEN_SPI_DATA_LENGTH_2 |
94 OXYGEN_SPI_CLOCK_160 |
95 (0 << OXYGEN_SPI_CODEC_SHIFT) |
96 OXYGEN_SPI_CEN_LATCH_CLOCK_LO,
97 (reg << 9) | value);
98 if (reg < ARRAY_SIZE(data->wm8766_regs))
99 data->wm8766_regs[reg] = value;
100}
101
102static void wm8766_write_cached(struct oxygen *chip,
103 unsigned int reg, unsigned int value)
104{
105 struct xonar_wm87x6 *data = chip->model_data;
106
107 if (reg >= ARRAY_SIZE(data->wm8766_regs) ||
108 value != data->wm8766_regs[reg]) {
109 if ((reg >= WM8766_LDA1 && reg <= WM8766_RDA1) ||
110 (reg >= WM8766_LDA2 && reg <= WM8766_MASTDA))
111 value &= ~WM8766_UPDATE;
112 wm8766_write(chip, reg, value);
113 }
114}
115
116static void wm8776_registers_init(struct oxygen *chip)
117{
118 struct xonar_wm87x6 *data = chip->model_data;
119
120 wm8776_write(chip, WM8776_RESET, 0);
121 wm8776_write(chip, WM8776_DACCTRL1, WM8776_DZCEN |
122 WM8776_PL_LEFT_LEFT | WM8776_PL_RIGHT_RIGHT);
123 wm8776_write(chip, WM8776_DACMUTE, chip->dac_mute ? WM8776_DMUTE : 0);
124 wm8776_write(chip, WM8776_DACIFCTRL,
125 WM8776_DACFMT_LJUST | WM8776_DACWL_24);
126 wm8776_write(chip, WM8776_ADCIFCTRL,
127 data->wm8776_regs[WM8776_ADCIFCTRL]);
128 wm8776_write(chip, WM8776_MSTRCTRL, data->wm8776_regs[WM8776_MSTRCTRL]);
129 wm8776_write(chip, WM8776_PWRDOWN, data->wm8776_regs[WM8776_PWRDOWN]);
130 wm8776_write(chip, WM8776_HPLVOL, data->wm8776_regs[WM8776_HPLVOL]);
131 wm8776_write(chip, WM8776_HPRVOL, data->wm8776_regs[WM8776_HPRVOL] |
132 WM8776_UPDATE);
133 wm8776_write(chip, WM8776_ADCLVOL, data->wm8776_regs[WM8776_ADCLVOL]);
134 wm8776_write(chip, WM8776_ADCRVOL, data->wm8776_regs[WM8776_ADCRVOL]);
135 wm8776_write(chip, WM8776_ADCMUX, data->wm8776_regs[WM8776_ADCMUX]);
136 wm8776_write(chip, WM8776_DACLVOL, chip->dac_volume[0]);
137 wm8776_write(chip, WM8776_DACRVOL, chip->dac_volume[1] | WM8776_UPDATE);
138}
139
140static void wm8766_registers_init(struct oxygen *chip)
141{
142 wm8766_write(chip, WM8766_RESET, 0);
143 wm8766_write(chip, WM8766_INT_CTRL, WM8766_FMT_LJUST | WM8766_IWL_24);
144 wm8766_write(chip, WM8766_DAC_CTRL2,
145 WM8766_ZCD | (chip->dac_mute ? WM8766_DMUTE_MASK : 0));
146 wm8766_write(chip, WM8766_LDA1, chip->dac_volume[2]);
147 wm8766_write(chip, WM8766_RDA1, chip->dac_volume[3]);
148 wm8766_write(chip, WM8766_LDA2, chip->dac_volume[4]);
149 wm8766_write(chip, WM8766_RDA2, chip->dac_volume[5]);
150 wm8766_write(chip, WM8766_LDA3, chip->dac_volume[6]);
151 wm8766_write(chip, WM8766_RDA3, chip->dac_volume[7] | WM8766_UPDATE);
152}
153
154static void wm8776_init(struct oxygen *chip)
155{
156 struct xonar_wm87x6 *data = chip->model_data;
157
158 data->wm8776_regs[WM8776_HPLVOL] = (0x79 - 60) | WM8776_HPZCEN;
159 data->wm8776_regs[WM8776_HPRVOL] = (0x79 - 60) | WM8776_HPZCEN;
160 data->wm8776_regs[WM8776_ADCIFCTRL] =
161 WM8776_ADCFMT_LJUST | WM8776_ADCWL_24 | WM8776_ADCMCLK;
162 data->wm8776_regs[WM8776_MSTRCTRL] =
163 WM8776_ADCRATE_256 | WM8776_DACRATE_256;
164 data->wm8776_regs[WM8776_PWRDOWN] = WM8776_HPPD;
165 data->wm8776_regs[WM8776_ADCLVOL] = 0xa5 | WM8776_ZCA;
166 data->wm8776_regs[WM8776_ADCRVOL] = 0xa5 | WM8776_ZCA;
167 data->wm8776_regs[WM8776_ADCMUX] = 0x001;
168 wm8776_registers_init(chip);
169}
170
171static void xonar_ds_init(struct oxygen *chip)
172{
173 struct xonar_wm87x6 *data = chip->model_data;
174
175 data->generic.anti_pop_delay = 300;
176 data->generic.output_enable_bit = GPIO_DS_OUTPUT_ENABLE;
177
178 wm8776_init(chip);
179 wm8766_registers_init(chip);
180
181 oxygen_write16_masked(chip, OXYGEN_GPIO_CONTROL, GPIO_DS_INPUT_ROUTE,
182 GPIO_DS_HP_DETECT | GPIO_DS_INPUT_ROUTE);
183 oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, GPIO_DS_INPUT_ROUTE);
184 oxygen_set_bits16(chip, OXYGEN_GPIO_INTERRUPT_MASK, GPIO_DS_HP_DETECT);
185 chip->interrupt_mask |= OXYGEN_INT_GPIO;
186
187 xonar_enable_output(chip);
188
189 snd_component_add(chip->card, "WM8776");
190 snd_component_add(chip->card, "WM8766");
191}
192
193static void xonar_ds_cleanup(struct oxygen *chip)
194{
195 xonar_disable_output(chip);
196}
197
198static void xonar_ds_suspend(struct oxygen *chip)
199{
200 xonar_ds_cleanup(chip);
201}
202
203static void xonar_ds_resume(struct oxygen *chip)
204{
205 wm8776_registers_init(chip);
206 wm8766_registers_init(chip);
207 xonar_enable_output(chip);
208}
209
210static void wm8776_adc_hardware_filter(unsigned int channel,
211 struct snd_pcm_hardware *hardware)
212{
213 if (channel == PCM_A) {
214 hardware->rates = SNDRV_PCM_RATE_32000 |
215 SNDRV_PCM_RATE_44100 |
216 SNDRV_PCM_RATE_48000 |
217 SNDRV_PCM_RATE_64000 |
218 SNDRV_PCM_RATE_88200 |
219 SNDRV_PCM_RATE_96000;
220 hardware->rate_max = 96000;
221 }
222}
223
224static void set_wm87x6_dac_params(struct oxygen *chip,
225 struct snd_pcm_hw_params *params)
226{
227}
228
229static void set_wm8776_adc_params(struct oxygen *chip,
230 struct snd_pcm_hw_params *params)
231{
232 u16 reg;
233
234 reg = WM8776_ADCRATE_256 | WM8776_DACRATE_256;
235 if (params_rate(params) > 48000)
236 reg |= WM8776_ADCOSR;
237 wm8776_write_cached(chip, WM8776_MSTRCTRL, reg);
238}
239
240static void update_wm8776_volume(struct oxygen *chip)
241{
242 struct xonar_wm87x6 *data = chip->model_data;
243 u8 to_change;
244
245 if (chip->dac_volume[0] == chip->dac_volume[1]) {
246 if (chip->dac_volume[0] != data->wm8776_regs[WM8776_DACLVOL] ||
247 chip->dac_volume[1] != data->wm8776_regs[WM8776_DACRVOL]) {
248 wm8776_write(chip, WM8776_DACMASTER,
249 chip->dac_volume[0] | WM8776_UPDATE);
250 data->wm8776_regs[WM8776_DACLVOL] = chip->dac_volume[0];
251 data->wm8776_regs[WM8776_DACRVOL] = chip->dac_volume[0];
252 }
253 } else {
254 to_change = (chip->dac_volume[0] !=
255 data->wm8776_regs[WM8776_DACLVOL]) << 0;
256 to_change |= (chip->dac_volume[1] !=
257 data->wm8776_regs[WM8776_DACLVOL]) << 1;
258 if (to_change & 1)
259 wm8776_write(chip, WM8776_DACLVOL, chip->dac_volume[0] |
260 ((to_change & 2) ? 0 : WM8776_UPDATE));
261 if (to_change & 2)
262 wm8776_write(chip, WM8776_DACRVOL,
263 chip->dac_volume[1] | WM8776_UPDATE);
264 }
265}
266
267static void update_wm87x6_volume(struct oxygen *chip)
268{
269 static const u8 wm8766_regs[6] = {
270 WM8766_LDA1, WM8766_RDA1,
271 WM8766_LDA2, WM8766_RDA2,
272 WM8766_LDA3, WM8766_RDA3,
273 };
274 struct xonar_wm87x6 *data = chip->model_data;
275 unsigned int i;
276 u8 to_change;
277
278 update_wm8776_volume(chip);
279 if (chip->dac_volume[2] == chip->dac_volume[3] &&
280 chip->dac_volume[2] == chip->dac_volume[4] &&
281 chip->dac_volume[2] == chip->dac_volume[5] &&
282 chip->dac_volume[2] == chip->dac_volume[6] &&
283 chip->dac_volume[2] == chip->dac_volume[7]) {
284 to_change = 0;
285 for (i = 0; i < 6; ++i)
286 if (chip->dac_volume[2] !=
287 data->wm8766_regs[wm8766_regs[i]])
288 to_change = 1;
289 if (to_change) {
290 wm8766_write(chip, WM8766_MASTDA,
291 chip->dac_volume[2] | WM8766_UPDATE);
292 for (i = 0; i < 6; ++i)
293 data->wm8766_regs[wm8766_regs[i]] =
294 chip->dac_volume[2];
295 }
296 } else {
297 to_change = 0;
298 for (i = 0; i < 6; ++i)
299 to_change |= (chip->dac_volume[2 + i] !=
300 data->wm8766_regs[wm8766_regs[i]]) << i;
301 for (i = 0; i < 6; ++i)
302 if (to_change & (1 << i))
303 wm8766_write(chip, wm8766_regs[i],
304 chip->dac_volume[2 + i] |
305 ((to_change & (0x3e << i))
306 ? 0 : WM8766_UPDATE));
307 }
308}
309
310static void update_wm8776_mute(struct oxygen *chip)
311{
312 wm8776_write_cached(chip, WM8776_DACMUTE,
313 chip->dac_mute ? WM8776_DMUTE : 0);
314}
315
316static void update_wm87x6_mute(struct oxygen *chip)
317{
318 update_wm8776_mute(chip);
319 wm8766_write_cached(chip, WM8766_DAC_CTRL2, WM8766_ZCD |
320 (chip->dac_mute ? WM8766_DMUTE_MASK : 0));
321}
322
323static void xonar_ds_gpio_changed(struct oxygen *chip)
324{
325 u16 bits;
326
327 bits = oxygen_read16(chip, OXYGEN_GPIO_DATA);
328 snd_printk(KERN_INFO "HP detect: %d\n", !!(bits & GPIO_DS_HP_DETECT));
329}
330
331static int wm8776_bit_switch_get(struct snd_kcontrol *ctl,
332 struct snd_ctl_elem_value *value)
333{
334 struct oxygen *chip = ctl->private_data;
335 struct xonar_wm87x6 *data = chip->model_data;
336 u16 bit = ctl->private_value & 0xffff;
337 unsigned int reg_index = (ctl->private_value >> 16) & 0xff;
338 bool invert = (ctl->private_value >> 24) & 1;
339
340 value->value.integer.value[0] =
341 ((data->wm8776_regs[reg_index] & bit) != 0) ^ invert;
342 return 0;
343}
344
345static int wm8776_bit_switch_put(struct snd_kcontrol *ctl,
346 struct snd_ctl_elem_value *value)
347{
348 struct oxygen *chip = ctl->private_data;
349 struct xonar_wm87x6 *data = chip->model_data;
350 u16 bit = ctl->private_value & 0xffff;
351 u16 reg_value;
352 unsigned int reg_index = (ctl->private_value >> 16) & 0xff;
353 bool invert = (ctl->private_value >> 24) & 1;
354 int changed;
355
356 mutex_lock(&chip->mutex);
357 reg_value = data->wm8776_regs[reg_index] & ~bit;
358 if (value->value.integer.value[0] ^ invert)
359 reg_value |= bit;
360 changed = reg_value != data->wm8776_regs[reg_index];
361 if (changed)
362 wm8776_write(chip, reg_index, reg_value);
363 mutex_unlock(&chip->mutex);
364 return changed;
365}
366
367static int wm8776_field_enum_info(struct snd_kcontrol *ctl,
368 struct snd_ctl_elem_info *info)
369{
370 static const char *const hld[16] = {
371 "0 ms", "2.67 ms", "5.33 ms", "10.6 ms",
372 "21.3 ms", "42.7 ms", "85.3 ms", "171 ms",
373 "341 ms", "683 ms", "1.37 s", "2.73 s",
374 "5.46 s", "10.9 s", "21.8 s", "43.7 s",
375 };
376 static const char *const atk_lim[11] = {
377 "0.25 ms", "0.5 ms", "1 ms", "2 ms",
378 "4 ms", "8 ms", "16 ms", "32 ms",
379 "64 ms", "128 ms", "256 ms",
380 };
381 static const char *const atk_alc[11] = {
382 "8.40 ms", "16.8 ms", "33.6 ms", "67.2 ms",
383 "134 ms", "269 ms", "538 ms", "1.08 s",
384 "2.15 s", "4.3 s", "8.6 s",
385 };
386 static const char *const dcy_lim[11] = {
387 "1.2 ms", "2.4 ms", "4.8 ms", "9.6 ms",
388 "19.2 ms", "38.4 ms", "76.8 ms", "154 ms",
389 "307 ms", "614 ms", "1.23 s",
390 };
391 static const char *const dcy_alc[11] = {
392 "33.5 ms", "67.0 ms", "134 ms", "268 ms",
393 "536 ms", "1.07 s", "2.14 s", "4.29 s",
394 "8.58 s", "17.2 s", "34.3 s",
395 };
396 static const char *const tranwin[8] = {
397 "0 us", "62.5 us", "125 us", "250 us",
398 "500 us", "1 ms", "2 ms", "4 ms",
399 };
400 u8 max;
401 const char *const *names;
402
403 max = (ctl->private_value >> 12) & 0xf;
404 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
405 info->count = 1;
406 info->value.enumerated.items = max + 1;
407 if (info->value.enumerated.item > max)
408 info->value.enumerated.item = max;
409 switch ((ctl->private_value >> 24) & 0x1f) {
410 case WM8776_ALCCTRL2:
411 names = hld;
412 break;
413 case WM8776_ALCCTRL3:
414 if (((ctl->private_value >> 20) & 0xf) == 0) {
415 if (ctl->private_value & LC_CONTROL_LIMITER)
416 names = atk_lim;
417 else
418 names = atk_alc;
419 } else {
420 if (ctl->private_value & LC_CONTROL_LIMITER)
421 names = dcy_lim;
422 else
423 names = dcy_alc;
424 }
425 break;
426 case WM8776_LIMITER:
427 names = tranwin;
428 break;
429 default:
430 return -ENXIO;
431 }
432 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
433 return 0;
434}
435
436static int wm8776_field_volume_info(struct snd_kcontrol *ctl,
437 struct snd_ctl_elem_info *info)
438{
439 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
440 info->count = 1;
441 info->value.integer.min = (ctl->private_value >> 8) & 0xf;
442 info->value.integer.max = (ctl->private_value >> 12) & 0xf;
443 return 0;
444}
445
446static void wm8776_field_set_from_ctl(struct snd_kcontrol *ctl)
447{
448 struct oxygen *chip = ctl->private_data;
449 struct xonar_wm87x6 *data = chip->model_data;
450 unsigned int value, reg_index, mode;
451 u8 min, max, shift;
452 u16 mask, reg_value;
453 bool invert;
454
455 if ((data->wm8776_regs[WM8776_ALCCTRL1] & WM8776_LCSEL_MASK) ==
456 WM8776_LCSEL_LIMITER)
457 mode = LC_CONTROL_LIMITER;
458 else
459 mode = LC_CONTROL_ALC;
460 if (!(ctl->private_value & mode))
461 return;
462
463 value = ctl->private_value & 0xf;
464 min = (ctl->private_value >> 8) & 0xf;
465 max = (ctl->private_value >> 12) & 0xf;
466 mask = (ctl->private_value >> 16) & 0xf;
467 shift = (ctl->private_value >> 20) & 0xf;
468 reg_index = (ctl->private_value >> 24) & 0x1f;
469 invert = (ctl->private_value >> 29) & 0x1;
470
471 if (invert)
472 value = max - (value - min);
473 reg_value = data->wm8776_regs[reg_index];
474 reg_value &= ~(mask << shift);
475 reg_value |= value << shift;
476 wm8776_write_cached(chip, reg_index, reg_value);
477}
478
479static int wm8776_field_set(struct snd_kcontrol *ctl, unsigned int value)
480{
481 struct oxygen *chip = ctl->private_data;
482 u8 min, max;
483 int changed;
484
485 min = (ctl->private_value >> 8) & 0xf;
486 max = (ctl->private_value >> 12) & 0xf;
487 if (value < min || value > max)
488 return -EINVAL;
489 mutex_lock(&chip->mutex);
490 changed = value != (ctl->private_value & 0xf);
491 if (changed) {
492 ctl->private_value = (ctl->private_value & ~0xf) | value;
493 wm8776_field_set_from_ctl(ctl);
494 }
495 mutex_unlock(&chip->mutex);
496 return changed;
497}
498
499static int wm8776_field_enum_get(struct snd_kcontrol *ctl,
500 struct snd_ctl_elem_value *value)
501{
502 value->value.enumerated.item[0] = ctl->private_value & 0xf;
503 return 0;
504}
505
506static int wm8776_field_volume_get(struct snd_kcontrol *ctl,
507 struct snd_ctl_elem_value *value)
508{
509 value->value.integer.value[0] = ctl->private_value & 0xf;
510 return 0;
511}
512
513static int wm8776_field_enum_put(struct snd_kcontrol *ctl,
514 struct snd_ctl_elem_value *value)
515{
516 return wm8776_field_set(ctl, value->value.enumerated.item[0]);
517}
518
519static int wm8776_field_volume_put(struct snd_kcontrol *ctl,
520 struct snd_ctl_elem_value *value)
521{
522 return wm8776_field_set(ctl, value->value.integer.value[0]);
523}
524
525static int wm8776_hp_vol_info(struct snd_kcontrol *ctl,
526 struct snd_ctl_elem_info *info)
527{
528 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
529 info->count = 2;
530 info->value.integer.min = 0x79 - 60;
531 info->value.integer.max = 0x7f;
532 return 0;
533}
534
535static int wm8776_hp_vol_get(struct snd_kcontrol *ctl,
536 struct snd_ctl_elem_value *value)
537{
538 struct oxygen *chip = ctl->private_data;
539 struct xonar_wm87x6 *data = chip->model_data;
540
541 mutex_lock(&chip->mutex);
542 value->value.integer.value[0] =
543 data->wm8776_regs[WM8776_HPLVOL] & WM8776_HPATT_MASK;
544 value->value.integer.value[1] =
545 data->wm8776_regs[WM8776_HPRVOL] & WM8776_HPATT_MASK;
546 mutex_unlock(&chip->mutex);
547 return 0;
548}
549
550static int wm8776_hp_vol_put(struct snd_kcontrol *ctl,
551 struct snd_ctl_elem_value *value)
552{
553 struct oxygen *chip = ctl->private_data;
554 struct xonar_wm87x6 *data = chip->model_data;
555 u8 to_update;
556
557 mutex_lock(&chip->mutex);
558 to_update = (value->value.integer.value[0] !=
559 (data->wm8776_regs[WM8776_HPLVOL] & WM8776_HPATT_MASK))
560 << 0;
561 to_update |= (value->value.integer.value[1] !=
562 (data->wm8776_regs[WM8776_HPRVOL] & WM8776_HPATT_MASK))
563 << 1;
564 if (value->value.integer.value[0] == value->value.integer.value[1]) {
565 if (to_update) {
566 wm8776_write(chip, WM8776_HPMASTER,
567 value->value.integer.value[0] |
568 WM8776_HPZCEN | WM8776_UPDATE);
569 data->wm8776_regs[WM8776_HPLVOL] =
570 value->value.integer.value[0] | WM8776_HPZCEN;
571 data->wm8776_regs[WM8776_HPRVOL] =
572 value->value.integer.value[0] | WM8776_HPZCEN;
573 }
574 } else {
575 if (to_update & 1)
576 wm8776_write(chip, WM8776_HPLVOL,
577 value->value.integer.value[0] |
578 WM8776_HPZCEN |
579 ((to_update & 2) ? 0 : WM8776_UPDATE));
580 if (to_update & 2)
581 wm8776_write(chip, WM8776_HPRVOL,
582 value->value.integer.value[1] |
583 WM8776_HPZCEN | WM8776_UPDATE);
584 }
585 mutex_unlock(&chip->mutex);
586 return to_update != 0;
587}
588
589static int wm8776_input_mux_get(struct snd_kcontrol *ctl,
590 struct snd_ctl_elem_value *value)
591{
592 struct oxygen *chip = ctl->private_data;
593 struct xonar_wm87x6 *data = chip->model_data;
594 unsigned int mux_bit = ctl->private_value;
595
596 value->value.integer.value[0] =
597 !!(data->wm8776_regs[WM8776_ADCMUX] & mux_bit);
598 return 0;
599}
600
601static int wm8776_input_mux_put(struct snd_kcontrol *ctl,
602 struct snd_ctl_elem_value *value)
603{
604 struct oxygen *chip = ctl->private_data;
605 struct xonar_wm87x6 *data = chip->model_data;
606 unsigned int mux_bit = ctl->private_value;
607 u16 reg;
608 int changed;
609
610 mutex_lock(&chip->mutex);
611 reg = data->wm8776_regs[WM8776_ADCMUX];
612 if (value->value.integer.value[0]) {
613 reg &= ~0x003;
614 reg |= mux_bit;
615 } else
616 reg &= ~mux_bit;
617 changed = reg != data->wm8776_regs[WM8776_ADCMUX];
618 if (changed) {
619 oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
620 reg & 1 ? GPIO_DS_INPUT_ROUTE : 0,
621 GPIO_DS_INPUT_ROUTE);
622 wm8776_write(chip, WM8776_ADCMUX, reg);
623 }
624 mutex_unlock(&chip->mutex);
625 return changed;
626}
627
628static int wm8776_input_vol_info(struct snd_kcontrol *ctl,
629 struct snd_ctl_elem_info *info)
630{
631 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
632 info->count = 2;
633 info->value.integer.min = 0xa5;
634 info->value.integer.max = 0xff;
635 return 0;
636}
637
638static int wm8776_input_vol_get(struct snd_kcontrol *ctl,
639 struct snd_ctl_elem_value *value)
640{
641 struct oxygen *chip = ctl->private_data;
642 struct xonar_wm87x6 *data = chip->model_data;
643
644 mutex_lock(&chip->mutex);
645 value->value.integer.value[0] =
646 data->wm8776_regs[WM8776_ADCLVOL] & WM8776_AGMASK;
647 value->value.integer.value[1] =
648 data->wm8776_regs[WM8776_ADCRVOL] & WM8776_AGMASK;
649 mutex_unlock(&chip->mutex);
650 return 0;
651}
652
653static int wm8776_input_vol_put(struct snd_kcontrol *ctl,
654 struct snd_ctl_elem_value *value)
655{
656 struct oxygen *chip = ctl->private_data;
657 struct xonar_wm87x6 *data = chip->model_data;
658 int changed = 0;
659
660 mutex_lock(&chip->mutex);
661 changed = (value->value.integer.value[0] !=
662 (data->wm8776_regs[WM8776_ADCLVOL] & WM8776_AGMASK)) ||
663 (value->value.integer.value[1] !=
664 (data->wm8776_regs[WM8776_ADCRVOL] & WM8776_AGMASK));
665 wm8776_write_cached(chip, WM8776_ADCLVOL,
666 value->value.integer.value[0] | WM8776_ZCA);
667 wm8776_write_cached(chip, WM8776_ADCRVOL,
668 value->value.integer.value[1] | WM8776_ZCA);
669 mutex_unlock(&chip->mutex);
670 return changed;
671}
672
673static int wm8776_level_control_info(struct snd_kcontrol *ctl,
674 struct snd_ctl_elem_info *info)
675{
676 static const char *const names[3] = {
677 "None", "Peak Limiter", "Automatic Level Control"
678 };
679 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
680 info->count = 1;
681 info->value.enumerated.items = 3;
682 if (info->value.enumerated.item >= 3)
683 info->value.enumerated.item = 2;
684 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
685 return 0;
686}
687
688static int wm8776_level_control_get(struct snd_kcontrol *ctl,
689 struct snd_ctl_elem_value *value)
690{
691 struct oxygen *chip = ctl->private_data;
692 struct xonar_wm87x6 *data = chip->model_data;
693
694 if (!(data->wm8776_regs[WM8776_ALCCTRL2] & WM8776_LCEN))
695 value->value.enumerated.item[0] = 0;
696 else if ((data->wm8776_regs[WM8776_ALCCTRL1] & WM8776_LCSEL_MASK) ==
697 WM8776_LCSEL_LIMITER)
698 value->value.enumerated.item[0] = 1;
699 else
700 value->value.enumerated.item[0] = 2;
701 return 0;
702}
703
704static void activate_control(struct oxygen *chip,
705 struct snd_kcontrol *ctl, unsigned int mode)
706{
707 unsigned int access;
708
709 if (ctl->private_value & mode)
710 access = 0;
711 else
712 access = SNDRV_CTL_ELEM_ACCESS_INACTIVE;
713 if ((ctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_INACTIVE) != access) {
714 ctl->vd[0].access ^= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
715 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_INFO, &ctl->id);
716 }
717}
718
719static int wm8776_level_control_put(struct snd_kcontrol *ctl,
720 struct snd_ctl_elem_value *value)
721{
722 struct oxygen *chip = ctl->private_data;
723 struct xonar_wm87x6 *data = chip->model_data;
724 unsigned int mode = 0, i;
725 u16 ctrl1, ctrl2;
726 int changed;
727
728 if (value->value.enumerated.item[0] >= 3)
729 return -EINVAL;
730 mutex_lock(&chip->mutex);
731 changed = value->value.enumerated.item[0] != ctl->private_value;
732 if (changed) {
733 ctl->private_value = value->value.enumerated.item[0];
734 ctrl1 = data->wm8776_regs[WM8776_ALCCTRL1];
735 ctrl2 = data->wm8776_regs[WM8776_ALCCTRL2];
736 switch (value->value.enumerated.item[0]) {
737 default:
738 wm8776_write_cached(chip, WM8776_ALCCTRL2,
739 ctrl2 & ~WM8776_LCEN);
740 break;
741 case 1:
742 wm8776_write_cached(chip, WM8776_ALCCTRL1,
743 (ctrl1 & ~WM8776_LCSEL_MASK) |
744 WM8776_LCSEL_LIMITER);
745 wm8776_write_cached(chip, WM8776_ALCCTRL2,
746 ctrl2 | WM8776_LCEN);
747 mode = LC_CONTROL_LIMITER;
748 break;
749 case 2:
750 wm8776_write_cached(chip, WM8776_ALCCTRL1,
751 (ctrl1 & ~WM8776_LCSEL_MASK) |
752 WM8776_LCSEL_ALC_STEREO);
753 wm8776_write_cached(chip, WM8776_ALCCTRL2,
754 ctrl2 | WM8776_LCEN);
755 mode = LC_CONTROL_ALC;
756 break;
757 }
758 for (i = 0; i < ARRAY_SIZE(data->lc_controls); ++i)
759 activate_control(chip, data->lc_controls[i], mode);
760 }
761 mutex_unlock(&chip->mutex);
762 return changed;
763}
764
765static int hpf_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info)
766{
767 static const char *const names[2] = {
768 "None", "High-pass Filter"
769 };
770
771 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
772 info->count = 1;
773 info->value.enumerated.items = 2;
774 if (info->value.enumerated.item >= 2)
775 info->value.enumerated.item = 1;
776 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
777 return 0;
778}
779
780static int hpf_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
781{
782 struct oxygen *chip = ctl->private_data;
783 struct xonar_wm87x6 *data = chip->model_data;
784
785 value->value.enumerated.item[0] =
786 !(data->wm8776_regs[WM8776_ADCIFCTRL] & WM8776_ADCHPD);
787 return 0;
788}
789
790static int hpf_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
791{
792 struct oxygen *chip = ctl->private_data;
793 struct xonar_wm87x6 *data = chip->model_data;
794 unsigned int reg;
795 int changed;
796
797 mutex_lock(&chip->mutex);
798 reg = data->wm8776_regs[WM8776_ADCIFCTRL] & ~WM8776_ADCHPD;
799 if (!value->value.enumerated.item[0])
800 reg |= WM8776_ADCHPD;
801 changed = reg != data->wm8776_regs[WM8776_ADCIFCTRL];
802 if (changed)
803 wm8776_write(chip, WM8776_ADCIFCTRL, reg);
804 mutex_unlock(&chip->mutex);
805 return changed;
806}
807
808#define WM8776_BIT_SWITCH(xname, reg, bit, invert, flags) { \
809 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
810 .name = xname, \
811 .info = snd_ctl_boolean_mono_info, \
812 .get = wm8776_bit_switch_get, \
813 .put = wm8776_bit_switch_put, \
814 .private_value = ((reg) << 16) | (bit) | ((invert) << 24) | (flags), \
815}
816#define _WM8776_FIELD_CTL(xname, reg, shift, initval, min, max, mask, flags) \
817 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
818 .name = xname, \
819 .private_value = (initval) | ((min) << 8) | ((max) << 12) | \
820 ((mask) << 16) | ((shift) << 20) | ((reg) << 24) | (flags)
821#define WM8776_FIELD_CTL_ENUM(xname, reg, shift, init, min, max, mask, flags) {\
822 _WM8776_FIELD_CTL(xname " Capture Enum", \
823 reg, shift, init, min, max, mask, flags), \
824 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
825 SNDRV_CTL_ELEM_ACCESS_INACTIVE, \
826 .info = wm8776_field_enum_info, \
827 .get = wm8776_field_enum_get, \
828 .put = wm8776_field_enum_put, \
829}
830#define WM8776_FIELD_CTL_VOLUME(a, b, c, d, e, f, g, h, tlv_p) { \
831 _WM8776_FIELD_CTL(a " Capture Volume", b, c, d, e, f, g, h), \
832 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
833 SNDRV_CTL_ELEM_ACCESS_INACTIVE | \
834 SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
835 .info = wm8776_field_volume_info, \
836 .get = wm8776_field_volume_get, \
837 .put = wm8776_field_volume_put, \
838 .tlv = { .p = tlv_p }, \
839}
840
841static const DECLARE_TLV_DB_SCALE(wm87x6_dac_db_scale, -6000, 50, 0);
842static const DECLARE_TLV_DB_SCALE(wm8776_adc_db_scale, -2100, 50, 0);
843static const DECLARE_TLV_DB_SCALE(wm8776_hp_db_scale, -6000, 100, 0);
844static const DECLARE_TLV_DB_SCALE(wm8776_lct_db_scale, -1600, 100, 0);
845static const DECLARE_TLV_DB_SCALE(wm8776_maxgain_db_scale, 0, 400, 0);
846static const DECLARE_TLV_DB_SCALE(wm8776_ngth_db_scale, -7800, 600, 0);
847static const DECLARE_TLV_DB_SCALE(wm8776_maxatten_lim_db_scale, -1200, 100, 0);
848static const DECLARE_TLV_DB_SCALE(wm8776_maxatten_alc_db_scale, -2100, 400, 0);
849
850static const struct snd_kcontrol_new ds_controls[] = {
851 {
852 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
853 .name = "Headphone Playback Volume",
854 .info = wm8776_hp_vol_info,
855 .get = wm8776_hp_vol_get,
856 .put = wm8776_hp_vol_put,
857 .tlv = { .p = wm8776_hp_db_scale },
858 },
859 WM8776_BIT_SWITCH("Headphone Playback Switch",
860 WM8776_PWRDOWN, WM8776_HPPD, 1, 0),
861 {
862 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
863 .name = "Input Capture Volume",
864 .info = wm8776_input_vol_info,
865 .get = wm8776_input_vol_get,
866 .put = wm8776_input_vol_put,
867 .tlv = { .p = wm8776_adc_db_scale },
868 },
869 {
870 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
871 .name = "Line Capture Switch",
872 .info = snd_ctl_boolean_mono_info,
873 .get = wm8776_input_mux_get,
874 .put = wm8776_input_mux_put,
875 .private_value = 1 << 0,
876 },
877 {
878 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
879 .name = "Mic Capture Switch",
880 .info = snd_ctl_boolean_mono_info,
881 .get = wm8776_input_mux_get,
882 .put = wm8776_input_mux_put,
883 .private_value = 1 << 1,
884 },
885 WM8776_BIT_SWITCH("Aux", WM8776_ADCMUX, 1 << 2, 0, 0),
886 {
887 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
888 .name = "ADC Filter Capture Enum",
889 .info = hpf_info,
890 .get = hpf_get,
891 .put = hpf_put,
892 },
893 {
894 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
895 .name = "Level Control Capture Enum",
896 .info = wm8776_level_control_info,
897 .get = wm8776_level_control_get,
898 .put = wm8776_level_control_put,
899 .private_value = 0,
900 },
901};
902static const struct snd_kcontrol_new lc_controls[] = {
903 WM8776_FIELD_CTL_VOLUME("Limiter Threshold",
904 WM8776_ALCCTRL1, 0, 11, 0, 15, 0xf,
905 LC_CONTROL_LIMITER, wm8776_lct_db_scale),
906 WM8776_FIELD_CTL_ENUM("Limiter Attack Time",
907 WM8776_ALCCTRL3, 0, 2, 0, 10, 0xf,
908 LC_CONTROL_LIMITER),
909 WM8776_FIELD_CTL_ENUM("Limiter Decay Time",
910 WM8776_ALCCTRL3, 4, 3, 0, 10, 0xf,
911 LC_CONTROL_LIMITER),
912 WM8776_FIELD_CTL_ENUM("Limiter Transient Window",
913 WM8776_LIMITER, 4, 2, 0, 7, 0x7,
914 LC_CONTROL_LIMITER),
915 WM8776_FIELD_CTL_VOLUME("Limiter Maximum Attenuation",
916 WM8776_LIMITER, 0, 6, 3, 12, 0xf,
917 LC_CONTROL_LIMITER,
918 wm8776_maxatten_lim_db_scale),
919 WM8776_FIELD_CTL_VOLUME("ALC Target Level",
920 WM8776_ALCCTRL1, 0, 11, 0, 15, 0xf,
921 LC_CONTROL_ALC, wm8776_lct_db_scale),
922 WM8776_FIELD_CTL_ENUM("ALC Attack Time",
923 WM8776_ALCCTRL3, 0, 2, 0, 10, 0xf,
924 LC_CONTROL_ALC),
925 WM8776_FIELD_CTL_ENUM("ALC Decay Time",
926 WM8776_ALCCTRL3, 4, 3, 0, 10, 0xf,
927 LC_CONTROL_ALC),
928 WM8776_FIELD_CTL_VOLUME("ALC Maximum Gain",
929 WM8776_ALCCTRL1, 4, 7, 1, 7, 0x7,
930 LC_CONTROL_ALC, wm8776_maxgain_db_scale),
931 WM8776_FIELD_CTL_VOLUME("ALC Maximum Attenuation",
932 WM8776_LIMITER, 0, 10, 10, 15, 0xf,
933 LC_CONTROL_ALC, wm8776_maxatten_alc_db_scale),
934 WM8776_FIELD_CTL_ENUM("ALC Hold Time",
935 WM8776_ALCCTRL2, 0, 0, 0, 15, 0xf,
936 LC_CONTROL_ALC),
937 WM8776_BIT_SWITCH("Noise Gate Capture Switch",
938 WM8776_NOISEGATE, WM8776_NGAT, 0,
939 LC_CONTROL_ALC),
940 WM8776_FIELD_CTL_VOLUME("Noise Gate Threshold",
941 WM8776_NOISEGATE, 2, 0, 0, 7, 0x7,
942 LC_CONTROL_ALC, wm8776_ngth_db_scale),
943};
944
945static int xonar_ds_control_filter(struct snd_kcontrol_new *template)
946{
947 if (!strncmp(template->name, "CD Capture ", 11))
948 return 1; /* no CD input */
949 return 0;
950}
951
952static int xonar_ds_mixer_init(struct oxygen *chip)
953{
954 struct xonar_wm87x6 *data = chip->model_data;
955 unsigned int i;
956 struct snd_kcontrol *ctl;
957 int err;
958
959 for (i = 0; i < ARRAY_SIZE(ds_controls); ++i) {
960 ctl = snd_ctl_new1(&ds_controls[i], chip);
961 if (!ctl)
962 return -ENOMEM;
963 err = snd_ctl_add(chip->card, ctl);
964 if (err < 0)
965 return err;
966 }
967 BUILD_BUG_ON(ARRAY_SIZE(lc_controls) != ARRAY_SIZE(data->lc_controls));
968 for (i = 0; i < ARRAY_SIZE(lc_controls); ++i) {
969 ctl = snd_ctl_new1(&lc_controls[i], chip);
970 if (!ctl)
971 return -ENOMEM;
972 err = snd_ctl_add(chip->card, ctl);
973 if (err < 0)
974 return err;
975 data->lc_controls[i] = ctl;
976 }
977 return 0;
978}
979
980static const struct oxygen_model model_xonar_ds = {
981 .shortname = "Xonar DS",
982 .longname = "Asus Virtuoso 200",
983 .chip = "AV200",
984 .init = xonar_ds_init,
985 .control_filter = xonar_ds_control_filter,
986 .mixer_init = xonar_ds_mixer_init,
987 .cleanup = xonar_ds_cleanup,
988 .suspend = xonar_ds_suspend,
989 .resume = xonar_ds_resume,
990 .pcm_hardware_filter = wm8776_adc_hardware_filter,
991 .get_i2s_mclk = oxygen_default_i2s_mclk,
992 .set_dac_params = set_wm87x6_dac_params,
993 .set_adc_params = set_wm8776_adc_params,
994 .update_dac_volume = update_wm87x6_volume,
995 .update_dac_mute = update_wm87x6_mute,
996 .gpio_changed = xonar_ds_gpio_changed,
997 .dac_tlv = wm87x6_dac_db_scale,
998 .model_data_size = sizeof(struct xonar_wm87x6),
999 .device_config = PLAYBACK_0_TO_I2S |
1000 PLAYBACK_1_TO_SPDIF |
1001 CAPTURE_0_FROM_I2S_1,
1002 .dac_channels = 8,
1003 .dac_volume_min = 255 - 2*60,
1004 .dac_volume_max = 255,
1005 .function_flags = OXYGEN_FUNCTION_SPI,
1006 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1007 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1008};
1009
1010int __devinit get_xonar_wm87x6_model(struct oxygen *chip,
1011 const struct pci_device_id *id)
1012{
1013 switch (id->subdevice) {
1014 case 0x838e:
1015 chip->model = model_xonar_ds;
1016 break;
1017 default:
1018 return -EINVAL;
1019 }
1020 return 0;
1021}
diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c
index 833e9c7b27c7..95cfde27d25c 100644
--- a/sound/pci/pcxhr/pcxhr.c
+++ b/sound/pci/pcxhr/pcxhr.c
@@ -94,7 +94,7 @@ enum {
94 PCI_ID_LAST 94 PCI_ID_LAST
95}; 95};
96 96
97static struct pci_device_id pcxhr_ids[] = { 97static DEFINE_PCI_DEVICE_TABLE(pcxhr_ids) = {
98 { 0x10b5, 0x9656, 0x1369, 0xb001, 0, 0, PCI_ID_VX882HR, }, 98 { 0x10b5, 0x9656, 0x1369, 0xb001, 0, 0, PCI_ID_VX882HR, },
99 { 0x10b5, 0x9656, 0x1369, 0xb101, 0, 0, PCI_ID_PCX882HR, }, 99 { 0x10b5, 0x9656, 0x1369, 0xb101, 0, 0, PCI_ID_PCX882HR, },
100 { 0x10b5, 0x9656, 0x1369, 0xb201, 0, 0, PCI_ID_VX881HR, }, 100 { 0x10b5, 0x9656, 0x1369, 0xb201, 0, 0, PCI_ID_VX881HR, },
diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c
index e66ef2b69b5d..960a227eb653 100644
--- a/sound/pci/riptide/riptide.c
+++ b/sound/pci/riptide/riptide.c
@@ -506,7 +506,7 @@ static int riptide_reset(struct cmdif *cif, struct snd_riptide *chip);
506/* 506/*
507 */ 507 */
508 508
509static struct pci_device_id snd_riptide_ids[] = { 509static DEFINE_PCI_DEVICE_TABLE(snd_riptide_ids) = {
510 { PCI_DEVICE(0x127a, 0x4310) }, 510 { PCI_DEVICE(0x127a, 0x4310) },
511 { PCI_DEVICE(0x127a, 0x4320) }, 511 { PCI_DEVICE(0x127a, 0x4320) },
512 { PCI_DEVICE(0x127a, 0x4330) }, 512 { PCI_DEVICE(0x127a, 0x4330) },
@@ -515,7 +515,7 @@ static struct pci_device_id snd_riptide_ids[] = {
515}; 515};
516 516
517#ifdef SUPPORT_JOYSTICK 517#ifdef SUPPORT_JOYSTICK
518static struct pci_device_id snd_riptide_joystick_ids[] __devinitdata = { 518static DEFINE_PCI_DEVICE_TABLE(snd_riptide_joystick_ids) = {
519 { PCI_DEVICE(0x127a, 0x4312) }, 519 { PCI_DEVICE(0x127a, 0x4312) },
520 { PCI_DEVICE(0x127a, 0x4322) }, 520 { PCI_DEVICE(0x127a, 0x4322) },
521 { PCI_DEVICE(0x127a, 0x4332) }, 521 { PCI_DEVICE(0x127a, 0x4332) },
diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c
index f977dba7cbd0..d5e1c6eb7b7b 100644
--- a/sound/pci/rme32.c
+++ b/sound/pci/rme32.c
@@ -226,7 +226,7 @@ struct rme32 {
226 struct snd_kcontrol *spdif_ctl; 226 struct snd_kcontrol *spdif_ctl;
227}; 227};
228 228
229static struct pci_device_id snd_rme32_ids[] = { 229static DEFINE_PCI_DEVICE_TABLE(snd_rme32_ids) = {
230 {PCI_VDEVICE(XILINX_RME, PCI_DEVICE_ID_RME_DIGI32), 0,}, 230 {PCI_VDEVICE(XILINX_RME, PCI_DEVICE_ID_RME_DIGI32), 0,},
231 {PCI_VDEVICE(XILINX_RME, PCI_DEVICE_ID_RME_DIGI32_8), 0,}, 231 {PCI_VDEVICE(XILINX_RME, PCI_DEVICE_ID_RME_DIGI32_8), 0,},
232 {PCI_VDEVICE(XILINX_RME, PCI_DEVICE_ID_RME_DIGI32_PRO), 0,}, 232 {PCI_VDEVICE(XILINX_RME, PCI_DEVICE_ID_RME_DIGI32_PRO), 0,},
diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c
index 2ba5c0fd55db..9d5252bc870c 100644
--- a/sound/pci/rme96.c
+++ b/sound/pci/rme96.c
@@ -231,7 +231,7 @@ struct rme96 {
231 struct snd_kcontrol *spdif_ctl; 231 struct snd_kcontrol *spdif_ctl;
232}; 232};
233 233
234static struct pci_device_id snd_rme96_ids[] = { 234static DEFINE_PCI_DEVICE_TABLE(snd_rme96_ids) = {
235 { PCI_VDEVICE(XILINX, PCI_DEVICE_ID_RME_DIGI96), 0, }, 235 { PCI_VDEVICE(XILINX, PCI_DEVICE_ID_RME_DIGI96), 0, },
236 { PCI_VDEVICE(XILINX, PCI_DEVICE_ID_RME_DIGI96_8), 0, }, 236 { PCI_VDEVICE(XILINX, PCI_DEVICE_ID_RME_DIGI96_8), 0, },
237 { PCI_VDEVICE(XILINX, PCI_DEVICE_ID_RME_DIGI96_8_PRO), 0, }, 237 { PCI_VDEVICE(XILINX, PCI_DEVICE_ID_RME_DIGI96_8_PRO), 0, },
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 7bb827c7d806..52c6eb57cc3f 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -585,7 +585,7 @@ static void snd_hammerfall_free_buffer(struct snd_dma_buffer *dmab, struct pci_d
585} 585}
586 586
587 587
588static struct pci_device_id snd_hdsp_ids[] = { 588static DEFINE_PCI_DEVICE_TABLE(snd_hdsp_ids) = {
589 { 589 {
590 .vendor = PCI_VENDOR_ID_XILINX, 590 .vendor = PCI_VENDOR_ID_XILINX,
591 .device = PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP, 591 .device = PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP,
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index a1b10d1a384d..3d72c1effeef 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -512,7 +512,7 @@ static char channel_map_madi_ss[HDSPM_MAX_CHANNELS] = {
512}; 512};
513 513
514 514
515static struct pci_device_id snd_hdspm_ids[] __devinitdata = { 515static DEFINE_PCI_DEVICE_TABLE(snd_hdspm_ids) = {
516 { 516 {
517 .vendor = PCI_VENDOR_ID_XILINX, 517 .vendor = PCI_VENDOR_ID_XILINX,
518 .device = PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP_MADI, 518 .device = PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP_MADI,
diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c
index bc539abb2105..44a3e2d8c556 100644
--- a/sound/pci/rme9652/rme9652.c
+++ b/sound/pci/rme9652/rme9652.c
@@ -314,7 +314,7 @@ static void snd_hammerfall_free_buffer(struct snd_dma_buffer *dmab, struct pci_d
314} 314}
315 315
316 316
317static struct pci_device_id snd_rme9652_ids[] = { 317static DEFINE_PCI_DEVICE_TABLE(snd_rme9652_ids) = {
318 { 318 {
319 .vendor = 0x10ee, 319 .vendor = 0x10ee,
320 .device = 0x3fc4, 320 .device = 0x3fc4,
diff --git a/sound/pci/sis7019.c b/sound/pci/sis7019.c
index 1a5ff0611072..7e3e8fbc90fe 100644
--- a/sound/pci/sis7019.c
+++ b/sound/pci/sis7019.c
@@ -48,7 +48,7 @@ MODULE_PARM_DESC(id, "ID string for SiS7019 Audio Accelerator.");
48module_param(enable, bool, 0444); 48module_param(enable, bool, 0444);
49MODULE_PARM_DESC(enable, "Enable SiS7019 Audio Accelerator."); 49MODULE_PARM_DESC(enable, "Enable SiS7019 Audio Accelerator.");
50 50
51static struct pci_device_id snd_sis7019_ids[] = { 51static DEFINE_PCI_DEVICE_TABLE(snd_sis7019_ids) = {
52 { PCI_DEVICE(PCI_VENDOR_ID_SI, 0x7019) }, 52 { PCI_DEVICE(PCI_VENDOR_ID_SI, 0x7019) },
53 { 0, } 53 { 0, }
54}; 54};
diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c
index 1f6406c4534d..337b9facadfd 100644
--- a/sound/pci/sonicvibes.c
+++ b/sound/pci/sonicvibes.c
@@ -242,7 +242,7 @@ struct sonicvibes {
242#endif 242#endif
243}; 243};
244 244
245static struct pci_device_id snd_sonic_ids[] = { 245static DEFINE_PCI_DEVICE_TABLE(snd_sonic_ids) = {
246 { PCI_VDEVICE(S3, 0xca00), 0, }, 246 { PCI_VDEVICE(S3, 0xca00), 0, },
247 { 0, } 247 { 0, }
248}; 248};
diff --git a/sound/pci/trident/trident.c b/sound/pci/trident/trident.c
index 21cef97d478d..6d0581841d7a 100644
--- a/sound/pci/trident/trident.c
+++ b/sound/pci/trident/trident.c
@@ -62,7 +62,7 @@ MODULE_PARM_DESC(pcm_channels, "Number of hardware channels assigned for PCM.");
62module_param_array(wavetable_size, int, NULL, 0444); 62module_param_array(wavetable_size, int, NULL, 0444);
63MODULE_PARM_DESC(wavetable_size, "Maximum memory size in kB for wavetable synth."); 63MODULE_PARM_DESC(wavetable_size, "Maximum memory size in kB for wavetable synth.");
64 64
65static struct pci_device_id snd_trident_ids[] = { 65static DEFINE_PCI_DEVICE_TABLE(snd_trident_ids) = {
66 {PCI_DEVICE(PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_DX), 66 {PCI_DEVICE(PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_DX),
67 PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0}, 67 PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0},
68 {PCI_DEVICE(PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_NX), 68 {PCI_DEVICE(PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_NX),
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index 8a332d2f615c..7e494b6a1d0e 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -401,7 +401,7 @@ struct via82xx {
401#endif 401#endif
402}; 402};
403 403
404static struct pci_device_id snd_via82xx_ids[] = { 404static DEFINE_PCI_DEVICE_TABLE(snd_via82xx_ids) = {
405 /* 0x1106, 0x3058 */ 405 /* 0x1106, 0x3058 */
406 { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C686_5), TYPE_CARD_VIA686, }, /* 686A */ 406 { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C686_5), TYPE_CARD_VIA686, }, /* 686A */
407 /* 0x1106, 0x3059 */ 407 /* 0x1106, 0x3059 */
@@ -1791,6 +1791,12 @@ static struct ac97_quirk ac97_quirks[] = {
1791 .type = AC97_TUNE_HP_ONLY 1791 .type = AC97_TUNE_HP_ONLY
1792 }, 1792 },
1793 { 1793 {
1794 .subvendor = 0x110a,
1795 .subdevice = 0x0079,
1796 .name = "Fujitsu Siemens D1289",
1797 .type = AC97_TUNE_HP_ONLY
1798 },
1799 {
1794 .subvendor = 0x1019, 1800 .subvendor = 0x1019,
1795 .subdevice = 0x0a81, 1801 .subdevice = 0x0a81,
1796 .name = "ECS K7VTA3", 1802 .name = "ECS K7VTA3",
diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c
index 47eb61561dfc..f7e8bbbe3953 100644
--- a/sound/pci/via82xx_modem.c
+++ b/sound/pci/via82xx_modem.c
@@ -260,7 +260,7 @@ struct via82xx_modem {
260 struct snd_info_entry *proc_entry; 260 struct snd_info_entry *proc_entry;
261}; 261};
262 262
263static struct pci_device_id snd_via82xx_modem_ids[] = { 263static DEFINE_PCI_DEVICE_TABLE(snd_via82xx_modem_ids) = {
264 { PCI_VDEVICE(VIA, 0x3068), TYPE_CARD_VIA82XX_MODEM, }, 264 { PCI_VDEVICE(VIA, 0x3068), TYPE_CARD_VIA82XX_MODEM, },
265 { 0, } 265 { 0, }
266}; 266};
diff --git a/sound/pci/vx222/vx222.c b/sound/pci/vx222/vx222.c
index fc9136c3e0d7..99a9a814be0b 100644
--- a/sound/pci/vx222/vx222.c
+++ b/sound/pci/vx222/vx222.c
@@ -60,7 +60,7 @@ enum {
60 VX_PCI_VX222_NEW 60 VX_PCI_VX222_NEW
61}; 61};
62 62
63static struct pci_device_id snd_vx222_ids[] = { 63static DEFINE_PCI_DEVICE_TABLE(snd_vx222_ids) = {
64 { 0x10b5, 0x9050, 0x1369, PCI_ANY_ID, 0, 0, VX_PCI_VX222_OLD, }, /* PLX */ 64 { 0x10b5, 0x9050, 0x1369, PCI_ANY_ID, 0, 0, VX_PCI_VX222_OLD, }, /* PLX */
65 { 0x10b5, 0x9030, 0x1369, PCI_ANY_ID, 0, 0, VX_PCI_VX222_NEW, }, /* PLX */ 65 { 0x10b5, 0x9030, 0x1369, PCI_ANY_ID, 0, 0, VX_PCI_VX222_NEW, }, /* PLX */
66 { 0, } 66 { 0, }
diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c
index e6b18b90d451..80c682113381 100644
--- a/sound/pci/ymfpci/ymfpci.c
+++ b/sound/pci/ymfpci/ymfpci.c
@@ -66,7 +66,7 @@ MODULE_PARM_DESC(joystick_port, "Joystick port address");
66module_param_array(rear_switch, bool, NULL, 0444); 66module_param_array(rear_switch, bool, NULL, 0444);
67MODULE_PARM_DESC(rear_switch, "Enable shared rear/line-in switch"); 67MODULE_PARM_DESC(rear_switch, "Enable shared rear/line-in switch");
68 68
69static struct pci_device_id snd_ymfpci_ids[] = { 69static DEFINE_PCI_DEVICE_TABLE(snd_ymfpci_ids) = {
70 { PCI_VDEVICE(YAMAHA, 0x0004), 0, }, /* YMF724 */ 70 { PCI_VDEVICE(YAMAHA, 0x0004), 0, }, /* YMF724 */
71 { PCI_VDEVICE(YAMAHA, 0x000d), 0, }, /* YMF724F */ 71 { PCI_VDEVICE(YAMAHA, 0x000d), 0, }, /* YMF724F */
72 { PCI_VDEVICE(YAMAHA, 0x000a), 0, }, /* YMF740 */ 72 { PCI_VDEVICE(YAMAHA, 0x000a), 0, }, /* YMF740 */
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c b/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c
index 5cfa608823f7..0d668f471620 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c
@@ -21,7 +21,6 @@
21 */ 21 */
22 22
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/vmalloc.h>
25#include <linux/delay.h> 24#include <linux/delay.h>
26#include <sound/core.h> 25#include <sound/core.h>
27#include <sound/asoundef.h> 26#include <sound/asoundef.h>
@@ -29,49 +28,6 @@
29 28
30 29
31/* 30/*
32 * we use a vmalloc'ed (sg-)buffer
33 */
34
35/* get the physical page pointer on the given offset */
36static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs, unsigned long offset)
37{
38 void *pageptr = subs->runtime->dma_area + offset;
39 return vmalloc_to_page(pageptr);
40}
41
42/*
43 * hw_params callback
44 * NOTE: this may be called not only once per pcm open!
45 */
46static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, size_t size)
47{
48 struct snd_pcm_runtime *runtime = subs->runtime;
49 if (runtime->dma_area) {
50 if (runtime->dma_bytes >= size)
51 return 0; /* already enough large */
52 vfree(runtime->dma_area);
53 }
54 runtime->dma_area = vmalloc_32_user(size);
55 if (! runtime->dma_area)
56 return -ENOMEM;
57 runtime->dma_bytes = size;
58 return 0;
59}
60
61/*
62 * hw_free callback
63 * NOTE: this may be called not only once per pcm open!
64 */
65static int snd_pcm_free_vmalloc_buffer(struct snd_pcm_substream *subs)
66{
67 struct snd_pcm_runtime *runtime = subs->runtime;
68
69 vfree(runtime->dma_area);
70 runtime->dma_area = NULL;
71 return 0;
72}
73
74/*
75 * clear the SRAM contents 31 * clear the SRAM contents
76 */ 32 */
77static int pdacf_pcm_clear_sram(struct snd_pdacf *chip) 33static int pdacf_pcm_clear_sram(struct snd_pdacf *chip)
@@ -147,7 +103,8 @@ static int pdacf_pcm_trigger(struct snd_pcm_substream *subs, int cmd)
147static int pdacf_pcm_hw_params(struct snd_pcm_substream *subs, 103static int pdacf_pcm_hw_params(struct snd_pcm_substream *subs,
148 struct snd_pcm_hw_params *hw_params) 104 struct snd_pcm_hw_params *hw_params)
149{ 105{
150 return snd_pcm_alloc_vmalloc_buffer(subs, params_buffer_bytes(hw_params)); 106 return snd_pcm_lib_alloc_vmalloc_32_buffer
107 (subs, params_buffer_bytes(hw_params));
151} 108}
152 109
153/* 110/*
@@ -155,7 +112,7 @@ static int pdacf_pcm_hw_params(struct snd_pcm_substream *subs,
155 */ 112 */
156static int pdacf_pcm_hw_free(struct snd_pcm_substream *subs) 113static int pdacf_pcm_hw_free(struct snd_pcm_substream *subs)
157{ 114{
158 return snd_pcm_free_vmalloc_buffer(subs); 115 return snd_pcm_lib_free_vmalloc_buffer(subs);
159} 116}
160 117
161/* 118/*
@@ -319,7 +276,8 @@ static struct snd_pcm_ops pdacf_pcm_capture_ops = {
319 .prepare = pdacf_pcm_prepare, 276 .prepare = pdacf_pcm_prepare,
320 .trigger = pdacf_pcm_trigger, 277 .trigger = pdacf_pcm_trigger,
321 .pointer = pdacf_pcm_capture_pointer, 278 .pointer = pdacf_pcm_capture_pointer,
322 .page = snd_pcm_get_vmalloc_page, 279 .page = snd_pcm_lib_get_vmalloc_page,
280 .mmap = snd_pcm_lib_mmap_vmalloc,
323}; 281};
324 282
325 283
diff --git a/sound/ppc/awacs.c b/sound/ppc/awacs.c
index 2e156467b814..b36679384b27 100644
--- a/sound/ppc/awacs.c
+++ b/sound/ppc/awacs.c
@@ -751,8 +751,8 @@ static void snd_pmac_awacs_suspend(struct snd_pmac *chip)
751 751
752static void snd_pmac_awacs_resume(struct snd_pmac *chip) 752static void snd_pmac_awacs_resume(struct snd_pmac *chip)
753{ 753{
754 if (machine_is_compatible("PowerBook3,1") 754 if (of_machine_is_compatible("PowerBook3,1")
755 || machine_is_compatible("PowerBook3,2")) { 755 || of_machine_is_compatible("PowerBook3,2")) {
756 msleep(100); 756 msleep(100);
757 snd_pmac_awacs_write_reg(chip, 1, 757 snd_pmac_awacs_write_reg(chip, 1,
758 chip->awacs_reg[1] & ~MASK_PAROUT); 758 chip->awacs_reg[1] & ~MASK_PAROUT);
@@ -780,16 +780,16 @@ static void snd_pmac_awacs_resume(struct snd_pmac *chip)
780} 780}
781#endif /* CONFIG_PM */ 781#endif /* CONFIG_PM */
782 782
783#define IS_PM7500 (machine_is_compatible("AAPL,7500") \ 783#define IS_PM7500 (of_machine_is_compatible("AAPL,7500") \
784 || machine_is_compatible("AAPL,8500") \ 784 || of_machine_is_compatible("AAPL,8500") \
785 || machine_is_compatible("AAPL,9500")) 785 || of_machine_is_compatible("AAPL,9500"))
786#define IS_PM5500 (machine_is_compatible("AAPL,e411")) 786#define IS_PM5500 (of_machine_is_compatible("AAPL,e411"))
787#define IS_BEIGE (machine_is_compatible("AAPL,Gossamer")) 787#define IS_BEIGE (of_machine_is_compatible("AAPL,Gossamer"))
788#define IS_IMAC1 (machine_is_compatible("PowerMac2,1")) 788#define IS_IMAC1 (of_machine_is_compatible("PowerMac2,1"))
789#define IS_IMAC2 (machine_is_compatible("PowerMac2,2") \ 789#define IS_IMAC2 (of_machine_is_compatible("PowerMac2,2") \
790 || machine_is_compatible("PowerMac4,1")) 790 || of_machine_is_compatible("PowerMac4,1"))
791#define IS_G4AGP (machine_is_compatible("PowerMac3,1")) 791#define IS_G4AGP (of_machine_is_compatible("PowerMac3,1"))
792#define IS_LOMBARD (machine_is_compatible("PowerBook1,1")) 792#define IS_LOMBARD (of_machine_is_compatible("PowerBook1,1"))
793 793
794static int imac1, imac2; 794static int imac1, imac2;
795 795
diff --git a/sound/ppc/burgundy.c b/sound/ppc/burgundy.c
index 0accfe49735b..1f72e1c786bf 100644
--- a/sound/ppc/burgundy.c
+++ b/sound/ppc/burgundy.c
@@ -582,7 +582,7 @@ static int snd_pmac_burgundy_detect_headphone(struct snd_pmac *chip)
582static void snd_pmac_burgundy_update_automute(struct snd_pmac *chip, int do_notify) 582static void snd_pmac_burgundy_update_automute(struct snd_pmac *chip, int do_notify)
583{ 583{
584 if (chip->auto_mute) { 584 if (chip->auto_mute) {
585 int imac = machine_is_compatible("iMac"); 585 int imac = of_machine_is_compatible("iMac");
586 int reg, oreg; 586 int reg, oreg;
587 reg = oreg = snd_pmac_burgundy_rcb(chip, 587 reg = oreg = snd_pmac_burgundy_rcb(chip,
588 MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES); 588 MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES);
@@ -620,7 +620,7 @@ static void snd_pmac_burgundy_update_automute(struct snd_pmac *chip, int do_noti
620 */ 620 */
621int __devinit snd_pmac_burgundy_init(struct snd_pmac *chip) 621int __devinit snd_pmac_burgundy_init(struct snd_pmac *chip)
622{ 622{
623 int imac = machine_is_compatible("iMac"); 623 int imac = of_machine_is_compatible("iMac");
624 int i, err; 624 int i, err;
625 625
626 /* Checks to see the chip is alive and kicking */ 626 /* Checks to see the chip is alive and kicking */
diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c
index 7bc492ee77ec..85081172403f 100644
--- a/sound/ppc/pmac.c
+++ b/sound/ppc/pmac.c
@@ -922,11 +922,11 @@ static void __devinit detect_byte_swap(struct snd_pmac *chip)
922 } 922 }
923 923
924 /* it seems the Pismo & iBook can't byte-swap in hardware. */ 924 /* it seems the Pismo & iBook can't byte-swap in hardware. */
925 if (machine_is_compatible("PowerBook3,1") || 925 if (of_machine_is_compatible("PowerBook3,1") ||
926 machine_is_compatible("PowerBook2,1")) 926 of_machine_is_compatible("PowerBook2,1"))
927 chip->can_byte_swap = 0 ; 927 chip->can_byte_swap = 0 ;
928 928
929 if (machine_is_compatible("PowerBook2,1")) 929 if (of_machine_is_compatible("PowerBook2,1"))
930 chip->can_duplex = 0; 930 chip->can_duplex = 0;
931} 931}
932 932
@@ -959,11 +959,11 @@ static int __devinit snd_pmac_detect(struct snd_pmac *chip)
959 chip->control_mask = MASK_IEPC | MASK_IEE | 0x11; /* default */ 959 chip->control_mask = MASK_IEPC | MASK_IEE | 0x11; /* default */
960 960
961 /* check machine type */ 961 /* check machine type */
962 if (machine_is_compatible("AAPL,3400/2400") 962 if (of_machine_is_compatible("AAPL,3400/2400")
963 || machine_is_compatible("AAPL,3500")) 963 || of_machine_is_compatible("AAPL,3500"))
964 chip->is_pbook_3400 = 1; 964 chip->is_pbook_3400 = 1;
965 else if (machine_is_compatible("PowerBook1,1") 965 else if (of_machine_is_compatible("PowerBook1,1")
966 || machine_is_compatible("AAPL,PowerBook1998")) 966 || of_machine_is_compatible("AAPL,PowerBook1998"))
967 chip->is_pbook_G3 = 1; 967 chip->is_pbook_G3 = 1;
968 chip->node = of_find_node_by_name(NULL, "awacs"); 968 chip->node = of_find_node_by_name(NULL, "awacs");
969 sound = of_node_get(chip->node); 969 sound = of_node_get(chip->node);
@@ -1033,8 +1033,8 @@ static int __devinit snd_pmac_detect(struct snd_pmac *chip)
1033 } 1033 }
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 = machine_is_compatible("PowerMac4,2") 1036 chip->can_capture = of_machine_is_compatible("PowerMac4,2")
1037 || machine_is_compatible("PowerBook4,1"); 1037 || of_machine_is_compatible("PowerBook4,1");
1038 chip->can_duplex = 0; 1038 chip->can_duplex = 0;
1039 // chip->can_byte_swap = 0; /* FIXME: check this */ 1039 // chip->can_byte_swap = 0; /* FIXME: check this */
1040 chip->num_freqs = ARRAY_SIZE(tumbler_freqs); 1040 chip->num_freqs = ARRAY_SIZE(tumbler_freqs);
diff --git a/sound/soc/au1x/Kconfig b/sound/soc/au1x/Kconfig
index 410a893aa66b..4b67140fdec3 100644
--- a/sound/soc/au1x/Kconfig
+++ b/sound/soc/au1x/Kconfig
@@ -22,11 +22,13 @@ config SND_SOC_AU1XPSC_AC97
22## 22##
23## Boards 23## Boards
24## 24##
25config SND_SOC_SAMPLE_PSC_AC97 25config SND_SOC_DB1200
26 tristate "Sample Au12x0/Au1550 PSC AC97 sound machine" 26 tristate "DB1200 AC97+I2S audio support"
27 depends on SND_SOC_AU1XPSC 27 depends on SND_SOC_AU1XPSC
28 select SND_SOC_AU1XPSC_AC97 28 select SND_SOC_AU1XPSC_AC97
29 select SND_SOC_AC97_CODEC 29 select SND_SOC_AC97_CODEC
30 select SND_SOC_AU1XPSC_I2S
31 select SND_SOC_WM8731
30 help 32 help
31 This is a sample AC97 sound machine for use in Au12x0/Au1550 33 Select this option to enable audio (AC97 or I2S) on the
32 based systems which have audio on PSC1 (e.g. Db1200 demoboard). 34 Alchemy/AMD/RMI DB1200 demoboard.
diff --git a/sound/soc/au1x/Makefile b/sound/soc/au1x/Makefile
index 6c6950b8003a..16873076e8c4 100644
--- a/sound/soc/au1x/Makefile
+++ b/sound/soc/au1x/Makefile
@@ -8,6 +8,6 @@ obj-$(CONFIG_SND_SOC_AU1XPSC_I2S) += snd-soc-au1xpsc-i2s.o
8obj-$(CONFIG_SND_SOC_AU1XPSC_AC97) += snd-soc-au1xpsc-ac97.o 8obj-$(CONFIG_SND_SOC_AU1XPSC_AC97) += snd-soc-au1xpsc-ac97.o
9 9
10# Boards 10# Boards
11snd-soc-sample-ac97-objs := sample-ac97.o 11snd-soc-db1200-objs := db1200.o
12 12
13obj-$(CONFIG_SND_SOC_SAMPLE_PSC_AC97) += snd-soc-sample-ac97.o 13obj-$(CONFIG_SND_SOC_DB1200) += snd-soc-db1200.o
diff --git a/sound/soc/au1x/db1200.c b/sound/soc/au1x/db1200.c
new file mode 100644
index 000000000000..cdf7be1b9b91
--- /dev/null
+++ b/sound/soc/au1x/db1200.c
@@ -0,0 +1,141 @@
1/*
2 * DB1200 ASoC audio fabric support code.
3 *
4 * (c) 2008-9 Manuel Lauss <manuel.lauss@gmail.com>
5 *
6 */
7
8#include <linux/module.h>
9#include <linux/moduleparam.h>
10#include <linux/timer.h>
11#include <linux/interrupt.h>
12#include <linux/platform_device.h>
13#include <sound/core.h>
14#include <sound/pcm.h>
15#include <sound/soc.h>
16#include <sound/soc-dapm.h>
17#include <asm/mach-au1x00/au1000.h>
18#include <asm/mach-au1x00/au1xxx_psc.h>
19#include <asm/mach-au1x00/au1xxx_dbdma.h>
20#include <asm/mach-db1x00/bcsr.h>
21
22#include "../codecs/ac97.h"
23#include "../codecs/wm8731.h"
24#include "psc.h"
25
26/*------------------------- AC97 PART ---------------------------*/
27
28static struct snd_soc_dai_link db1200_ac97_dai = {
29 .name = "AC97",
30 .stream_name = "AC97 HiFi",
31 .cpu_dai = &au1xpsc_ac97_dai,
32 .codec_dai = &ac97_dai,
33};
34
35static struct snd_soc_card db1200_ac97_machine = {
36 .name = "DB1200_AC97",
37 .dai_link = &db1200_ac97_dai,
38 .num_links = 1,
39 .platform = &au1xpsc_soc_platform,
40};
41
42static struct snd_soc_device db1200_ac97_devdata = {
43 .card = &db1200_ac97_machine,
44 .codec_dev = &soc_codec_dev_ac97,
45};
46
47/*------------------------- I2S PART ---------------------------*/
48
49static int db1200_i2s_startup(struct snd_pcm_substream *substream)
50{
51 struct snd_soc_pcm_runtime *rtd = substream->private_data;
52 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
53 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
54 int ret;
55
56 /* WM8731 has its own 12MHz crystal */
57 snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK,
58 12000000, SND_SOC_CLOCK_IN);
59
60 /* codec is bitclock and lrclk master */
61 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_LEFT_J |
62 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
63 if (ret < 0)
64 goto out;
65
66 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_LEFT_J |
67 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
68 if (ret < 0)
69 goto out;
70
71 ret = 0;
72out:
73 return ret;
74}
75
76static struct snd_soc_ops db1200_i2s_wm8731_ops = {
77 .startup = db1200_i2s_startup,
78};
79
80static struct snd_soc_dai_link db1200_i2s_dai = {
81 .name = "WM8731",
82 .stream_name = "WM8731 PCM",
83 .cpu_dai = &au1xpsc_i2s_dai,
84 .codec_dai = &wm8731_dai,
85 .ops = &db1200_i2s_wm8731_ops,
86};
87
88static struct snd_soc_card db1200_i2s_machine = {
89 .name = "DB1200_I2S",
90 .dai_link = &db1200_i2s_dai,
91 .num_links = 1,
92 .platform = &au1xpsc_soc_platform,
93};
94
95static struct snd_soc_device db1200_i2s_devdata = {
96 .card = &db1200_i2s_machine,
97 .codec_dev = &soc_codec_dev_wm8731,
98};
99
100/*------------------------- COMMON PART ---------------------------*/
101
102static struct platform_device *db1200_asoc_dev;
103
104static int __init db1200_audio_load(void)
105{
106 int ret;
107
108 ret = -ENOMEM;
109 db1200_asoc_dev = platform_device_alloc("soc-audio", -1);
110 if (!db1200_asoc_dev)
111 goto out;
112
113 /* DB1200 board setup set PSC1MUX to preferred audio device */
114 if (bcsr_read(BCSR_RESETS) & BCSR_RESETS_PSC1MUX)
115 platform_set_drvdata(db1200_asoc_dev, &db1200_i2s_devdata);
116 else
117 platform_set_drvdata(db1200_asoc_dev, &db1200_ac97_devdata);
118
119 db1200_ac97_devdata.dev = &db1200_asoc_dev->dev;
120 db1200_i2s_devdata.dev = &db1200_asoc_dev->dev;
121 ret = platform_device_add(db1200_asoc_dev);
122
123 if (ret) {
124 platform_device_put(db1200_asoc_dev);
125 db1200_asoc_dev = NULL;
126 }
127out:
128 return ret;
129}
130
131static void __exit db1200_audio_unload(void)
132{
133 platform_device_unregister(db1200_asoc_dev);
134}
135
136module_init(db1200_audio_load);
137module_exit(db1200_audio_unload);
138
139MODULE_LICENSE("GPL");
140MODULE_DESCRIPTION("DB1200 ASoC audio support");
141MODULE_AUTHOR("Manuel Lauss");
diff --git a/sound/soc/au1x/dbdma2.c b/sound/soc/au1x/dbdma2.c
index 19e4d37eba1c..6d9f4c624949 100644
--- a/sound/soc/au1x/dbdma2.c
+++ b/sound/soc/au1x/dbdma2.c
@@ -51,8 +51,8 @@ struct au1xpsc_audio_dmadata {
51 struct snd_pcm_substream *substream; 51 struct snd_pcm_substream *substream;
52 unsigned long curr_period; /* current segment DDMA is working on */ 52 unsigned long curr_period; /* current segment DDMA is working on */
53 unsigned long q_period; /* queue period(s) */ 53 unsigned long q_period; /* queue period(s) */
54 unsigned long dma_area; /* address of queued DMA area */ 54 dma_addr_t dma_area; /* address of queued DMA area */
55 unsigned long dma_area_s; /* start address of DMA area */ 55 dma_addr_t dma_area_s; /* start address of DMA area */
56 unsigned long pos; /* current byte position being played */ 56 unsigned long pos; /* current byte position being played */
57 unsigned long periods; /* number of SG segments in total */ 57 unsigned long periods; /* number of SG segments in total */
58 unsigned long period_bytes; /* size in bytes of one SG segment */ 58 unsigned long period_bytes; /* size in bytes of one SG segment */
@@ -94,8 +94,7 @@ static const struct snd_pcm_hardware au1xpsc_pcm_hardware = {
94 94
95static void au1x_pcm_queue_tx(struct au1xpsc_audio_dmadata *cd) 95static void au1x_pcm_queue_tx(struct au1xpsc_audio_dmadata *cd)
96{ 96{
97 au1xxx_dbdma_put_source_flags(cd->ddma_chan, 97 au1xxx_dbdma_put_source(cd->ddma_chan, cd->dma_area,
98 (void *)phys_to_virt(cd->dma_area),
99 cd->period_bytes, DDMA_FLAGS_IE); 98 cd->period_bytes, DDMA_FLAGS_IE);
100 99
101 /* update next-to-queue period */ 100 /* update next-to-queue period */
@@ -109,9 +108,8 @@ static void au1x_pcm_queue_tx(struct au1xpsc_audio_dmadata *cd)
109 108
110static void au1x_pcm_queue_rx(struct au1xpsc_audio_dmadata *cd) 109static void au1x_pcm_queue_rx(struct au1xpsc_audio_dmadata *cd)
111{ 110{
112 au1xxx_dbdma_put_dest_flags(cd->ddma_chan, 111 au1xxx_dbdma_put_dest(cd->ddma_chan, cd->dma_area,
113 (void *)phys_to_virt(cd->dma_area), 112 cd->period_bytes, DDMA_FLAGS_IE);
114 cd->period_bytes, DDMA_FLAGS_IE);
115 113
116 /* update next-to-queue period */ 114 /* update next-to-queue period */
117 ++cd->q_period; 115 ++cd->q_period;
@@ -233,7 +231,7 @@ static int au1xpsc_pcm_hw_params(struct snd_pcm_substream *substream,
233 pcd->substream = substream; 231 pcd->substream = substream;
234 pcd->period_bytes = params_period_bytes(params); 232 pcd->period_bytes = params_period_bytes(params);
235 pcd->periods = params_periods(params); 233 pcd->periods = params_periods(params);
236 pcd->dma_area_s = pcd->dma_area = (unsigned long)runtime->dma_addr; 234 pcd->dma_area_s = pcd->dma_area = runtime->dma_addr;
237 pcd->q_period = 0; 235 pcd->q_period = 0;
238 pcd->curr_period = 0; 236 pcd->curr_period = 0;
239 pcd->pos = 0; 237 pcd->pos = 0;
diff --git a/sound/soc/au1x/sample-ac97.c b/sound/soc/au1x/sample-ac97.c
deleted file mode 100644
index 27683eb7905e..000000000000
--- a/sound/soc/au1x/sample-ac97.c
+++ /dev/null
@@ -1,144 +0,0 @@
1/*
2 * Sample Au12x0/Au1550 PSC AC97 sound machine.
3 *
4 * Copyright (c) 2007-2008 Manuel Lauss <mano@roarinelk.homelinux.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms outlined in the file COPYING at the root of this
8 * source archive.
9 *
10 * This is a very generic AC97 sound machine driver for boards which
11 * have (AC97) audio at PSC1 (e.g. DB1200 demoboards).
12 */
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 <sound/core.h>
20#include <sound/pcm.h>
21#include <sound/soc.h>
22#include <sound/soc-dapm.h>
23#include <asm/mach-au1x00/au1000.h>
24#include <asm/mach-au1x00/au1xxx_psc.h>
25#include <asm/mach-au1x00/au1xxx_dbdma.h>
26
27#include "../codecs/ac97.h"
28#include "psc.h"
29
30static int au1xpsc_sample_ac97_init(struct snd_soc_codec *codec)
31{
32 snd_soc_dapm_sync(codec);
33 return 0;
34}
35
36static struct snd_soc_dai_link au1xpsc_sample_ac97_dai = {
37 .name = "AC97",
38 .stream_name = "AC97 HiFi",
39 .cpu_dai = &au1xpsc_ac97_dai, /* see psc-ac97.c */
40 .codec_dai = &ac97_dai, /* see codecs/ac97.c */
41 .init = au1xpsc_sample_ac97_init,
42 .ops = NULL,
43};
44
45static struct snd_soc_card au1xpsc_sample_ac97_machine = {
46 .name = "Au1xxx PSC AC97 Audio",
47 .dai_link = &au1xpsc_sample_ac97_dai,
48 .num_links = 1,
49};
50
51static struct snd_soc_device au1xpsc_sample_ac97_devdata = {
52 .card = &au1xpsc_sample_ac97_machine,
53 .platform = &au1xpsc_soc_platform, /* see dbdma2.c */
54 .codec_dev = &soc_codec_dev_ac97,
55};
56
57static struct resource au1xpsc_psc1_res[] = {
58 [0] = {
59 .start = CPHYSADDR(PSC1_BASE_ADDR),
60 .end = CPHYSADDR(PSC1_BASE_ADDR) + 0x000fffff,
61 .flags = IORESOURCE_MEM,
62 },
63 [1] = {
64#ifdef CONFIG_SOC_AU1200
65 .start = AU1200_PSC1_INT,
66 .end = AU1200_PSC1_INT,
67#elif defined(CONFIG_SOC_AU1550)
68 .start = AU1550_PSC1_INT,
69 .end = AU1550_PSC1_INT,
70#endif
71 .flags = IORESOURCE_IRQ,
72 },
73 [2] = {
74 .start = DSCR_CMD0_PSC1_TX,
75 .end = DSCR_CMD0_PSC1_TX,
76 .flags = IORESOURCE_DMA,
77 },
78 [3] = {
79 .start = DSCR_CMD0_PSC1_RX,
80 .end = DSCR_CMD0_PSC1_RX,
81 .flags = IORESOURCE_DMA,
82 },
83};
84
85static struct platform_device *au1xpsc_sample_ac97_dev;
86
87static int __init au1xpsc_sample_ac97_load(void)
88{
89 int ret;
90
91#ifdef CONFIG_SOC_AU1200
92 unsigned long io;
93
94 /* modify sys_pinfunc for AC97 on PSC1 */
95 io = au_readl(SYS_PINFUNC);
96 io |= SYS_PINFUNC_P1C;
97 io &= ~(SYS_PINFUNC_P1A | SYS_PINFUNC_P1B);
98 au_writel(io, SYS_PINFUNC);
99 au_sync();
100#endif
101
102 ret = -ENOMEM;
103
104 /* setup PSC clock source for AC97 part: external clock provided
105 * by codec. The psc-ac97.c driver depends on this setting!
106 */
107 au_writel(PSC_SEL_CLK_SERCLK, PSC1_BASE_ADDR + PSC_SEL_OFFSET);
108 au_sync();
109
110 au1xpsc_sample_ac97_dev = platform_device_alloc("soc-audio", -1);
111 if (!au1xpsc_sample_ac97_dev)
112 goto out;
113
114 au1xpsc_sample_ac97_dev->resource =
115 kmemdup(au1xpsc_psc1_res, sizeof(struct resource) *
116 ARRAY_SIZE(au1xpsc_psc1_res), GFP_KERNEL);
117 au1xpsc_sample_ac97_dev->num_resources = ARRAY_SIZE(au1xpsc_psc1_res);
118 au1xpsc_sample_ac97_dev->id = 1;
119
120 platform_set_drvdata(au1xpsc_sample_ac97_dev,
121 &au1xpsc_sample_ac97_devdata);
122 au1xpsc_sample_ac97_devdata.dev = &au1xpsc_sample_ac97_dev->dev;
123 ret = platform_device_add(au1xpsc_sample_ac97_dev);
124
125 if (ret) {
126 platform_device_put(au1xpsc_sample_ac97_dev);
127 au1xpsc_sample_ac97_dev = NULL;
128 }
129
130out:
131 return ret;
132}
133
134static void __exit au1xpsc_sample_ac97_exit(void)
135{
136 platform_device_unregister(au1xpsc_sample_ac97_dev);
137}
138
139module_init(au1xpsc_sample_ac97_load);
140module_exit(au1xpsc_sample_ac97_exit);
141
142MODULE_LICENSE("GPL");
143MODULE_DESCRIPTION("Au1xxx PSC sample AC97 machine");
144MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>");
diff --git a/sound/soc/blackfin/bf5xx-ac97-pcm.c b/sound/soc/blackfin/bf5xx-ac97-pcm.c
index cf0dfb7ca221..67cbfe7283da 100644
--- a/sound/soc/blackfin/bf5xx-ac97-pcm.c
+++ b/sound/soc/blackfin/bf5xx-ac97-pcm.c
@@ -349,9 +349,7 @@ static int bf5xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
349 sport_handle->tx_dma_buf = dma_alloc_coherent(NULL, \ 349 sport_handle->tx_dma_buf = dma_alloc_coherent(NULL, \
350 size, &sport_handle->tx_dma_phy, GFP_KERNEL); 350 size, &sport_handle->tx_dma_phy, GFP_KERNEL);
351 if (!sport_handle->tx_dma_buf) { 351 if (!sport_handle->tx_dma_buf) {
352 pr_err("Failed to allocate memory for tx dma \ 352 pr_err("Failed to allocate memory for tx dma buf - Please increase uncached DMA memory region\n");
353 buf - Please increase uncached DMA \
354 memory region\n");
355 return -ENOMEM; 353 return -ENOMEM;
356 } else 354 } else
357 memset(sport_handle->tx_dma_buf, 0, size); 355 memset(sport_handle->tx_dma_buf, 0, size);
@@ -362,9 +360,7 @@ static int bf5xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
362 sport_handle->rx_dma_buf = dma_alloc_coherent(NULL, \ 360 sport_handle->rx_dma_buf = dma_alloc_coherent(NULL, \
363 size, &sport_handle->rx_dma_phy, GFP_KERNEL); 361 size, &sport_handle->rx_dma_phy, GFP_KERNEL);
364 if (!sport_handle->rx_dma_buf) { 362 if (!sport_handle->rx_dma_buf) {
365 pr_err("Failed to allocate memory for rx dma \ 363 pr_err("Failed to allocate memory for rx dma buf - Please increase uncached DMA memory region\n");
366 buf - Please increase uncached DMA \
367 memory region\n");
368 return -ENOMEM; 364 return -ENOMEM;
369 } else 365 } else
370 memset(sport_handle->rx_dma_buf, 0, size); 366 memset(sport_handle->rx_dma_buf, 0, size);
diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.c b/sound/soc/blackfin/bf5xx-i2s-pcm.c
index 62fbb8459569..c6c6a4a7d948 100644
--- a/sound/soc/blackfin/bf5xx-i2s-pcm.c
+++ b/sound/soc/blackfin/bf5xx-i2s-pcm.c
@@ -207,8 +207,7 @@ static int bf5xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
207 buf->area = dma_alloc_coherent(pcm->card->dev, size, 207 buf->area = dma_alloc_coherent(pcm->card->dev, size,
208 &buf->addr, GFP_KERNEL); 208 &buf->addr, GFP_KERNEL);
209 if (!buf->area) { 209 if (!buf->area) {
210 pr_err("Failed to allocate dma memory \ 210 pr_err("Failed to allocate dma memory - Please increase uncached DMA memory region\n");
211 Please increase uncached DMA memory region\n");
212 return -ENOMEM; 211 return -ENOMEM;
213 } 212 }
214 buf->bytes = size; 213 buf->bytes = size;
diff --git a/sound/soc/blackfin/bf5xx-tdm-pcm.c b/sound/soc/blackfin/bf5xx-tdm-pcm.c
index a8c73cbbd685..5e03bb2f3cd7 100644
--- a/sound/soc/blackfin/bf5xx-tdm-pcm.c
+++ b/sound/soc/blackfin/bf5xx-tdm-pcm.c
@@ -244,8 +244,7 @@ static int bf5xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
244 buf->area = dma_alloc_coherent(pcm->card->dev, size * 4, 244 buf->area = dma_alloc_coherent(pcm->card->dev, size * 4,
245 &buf->addr, GFP_KERNEL); 245 &buf->addr, GFP_KERNEL);
246 if (!buf->area) { 246 if (!buf->area) {
247 pr_err("Failed to allocate dma memory \ 247 pr_err("Failed to allocate dma memory - Please increase uncached DMA memory region\n");
248 Please increase uncached DMA memory region\n");
249 return -ENOMEM; 248 return -ENOMEM;
250 } 249 }
251 buf->bytes = size; 250 buf->bytes = size;
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 52b005f8fed4..1743d565e996 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -23,6 +23,7 @@ config SND_SOC_ALL_CODECS
23 select SND_SOC_AK4671 if I2C 23 select SND_SOC_AK4671 if I2C
24 select SND_SOC_CS4270 if I2C 24 select SND_SOC_CS4270 if I2C
25 select SND_SOC_MAX9877 if I2C 25 select SND_SOC_MAX9877 if I2C
26 select SND_SOC_DA7210 if I2C
26 select SND_SOC_PCM3008 27 select SND_SOC_PCM3008
27 select SND_SOC_SPDIF 28 select SND_SOC_SPDIF
28 select SND_SOC_SSM2602 if I2C 29 select SND_SOC_SSM2602 if I2C
@@ -35,6 +36,7 @@ config SND_SOC_ALL_CODECS
35 select SND_SOC_TWL4030 if TWL4030_CORE 36 select SND_SOC_TWL4030 if TWL4030_CORE
36 select SND_SOC_UDA134X 37 select SND_SOC_UDA134X
37 select SND_SOC_UDA1380 if I2C 38 select SND_SOC_UDA1380 if I2C
39 select SND_SOC_WM2000 if I2C
38 select SND_SOC_WM8350 if MFD_WM8350 40 select SND_SOC_WM8350 if MFD_WM8350
39 select SND_SOC_WM8400 if MFD_WM8400 41 select SND_SOC_WM8400 if MFD_WM8400
40 select SND_SOC_WM8510 if SND_SOC_I2C_AND_SPI 42 select SND_SOC_WM8510 if SND_SOC_I2C_AND_SPI
@@ -49,14 +51,18 @@ config SND_SOC_ALL_CODECS
49 select SND_SOC_WM8776 if SND_SOC_I2C_AND_SPI 51 select SND_SOC_WM8776 if SND_SOC_I2C_AND_SPI
50 select SND_SOC_WM8900 if I2C 52 select SND_SOC_WM8900 if I2C
51 select SND_SOC_WM8903 if I2C 53 select SND_SOC_WM8903 if I2C
54 select SND_SOC_WM8904 if I2C
52 select SND_SOC_WM8940 if I2C 55 select SND_SOC_WM8940 if I2C
56 select SND_SOC_WM8955 if I2C
53 select SND_SOC_WM8960 if I2C 57 select SND_SOC_WM8960 if I2C
54 select SND_SOC_WM8961 if I2C 58 select SND_SOC_WM8961 if I2C
55 select SND_SOC_WM8971 if I2C 59 select SND_SOC_WM8971 if I2C
56 select SND_SOC_WM8974 if I2C 60 select SND_SOC_WM8974 if I2C
61 select SND_SOC_WM8978 if I2C
57 select SND_SOC_WM8988 if SND_SOC_I2C_AND_SPI 62 select SND_SOC_WM8988 if SND_SOC_I2C_AND_SPI
58 select SND_SOC_WM8990 if I2C 63 select SND_SOC_WM8990 if I2C
59 select SND_SOC_WM8993 if I2C 64 select SND_SOC_WM8993 if I2C
65 select SND_SOC_WM8994 if MFD_WM8994
60 select SND_SOC_WM9081 if I2C 66 select SND_SOC_WM9081 if I2C
61 select SND_SOC_WM9705 if SND_SOC_AC97_BUS 67 select SND_SOC_WM9705 if SND_SOC_AC97_BUS
62 select SND_SOC_WM9712 if SND_SOC_AC97_BUS 68 select SND_SOC_WM9712 if SND_SOC_AC97_BUS
@@ -112,6 +118,9 @@ config SND_SOC_AK4671
112config SND_SOC_CS4270 118config SND_SOC_CS4270
113 tristate 119 tristate
114 120
121config SND_SOC_DA7210
122 tristate
123
115# Cirrus Logic CS4270 Codec VD = 3.3V Errata 124# Cirrus Logic CS4270 Codec VD = 3.3V Errata
116# Select if you are affected by the errata where the part will not function 125# Select if you are affected by the errata where the part will not function
117# if MCLK divide-by-1.5 is selected and VD is set to 3.3V. The driver will 126# if MCLK divide-by-1.5 is selected and VD is set to 3.3V. The driver will
@@ -203,9 +212,15 @@ config SND_SOC_WM8900
203config SND_SOC_WM8903 212config SND_SOC_WM8903
204 tristate 213 tristate
205 214
215config SND_SOC_WM8904
216 tristate
217
206config SND_SOC_WM8940 218config SND_SOC_WM8940
207 tristate 219 tristate
208 220
221config SND_SOC_WM8955
222 tristate
223
209config SND_SOC_WM8960 224config SND_SOC_WM8960
210 tristate 225 tristate
211 226
@@ -218,6 +233,9 @@ config SND_SOC_WM8971
218config SND_SOC_WM8974 233config SND_SOC_WM8974
219 tristate 234 tristate
220 235
236config SND_SOC_WM8978
237 tristate
238
221config SND_SOC_WM8988 239config SND_SOC_WM8988
222 tristate 240 tristate
223 241
@@ -227,6 +245,9 @@ config SND_SOC_WM8990
227config SND_SOC_WM8993 245config SND_SOC_WM8993
228 tristate 246 tristate
229 247
248config SND_SOC_WM8994
249 tristate
250
230config SND_SOC_WM9081 251config SND_SOC_WM9081
231 tristate 252 tristate
232 253
@@ -245,3 +266,6 @@ config SND_SOC_MAX9877
245 266
246config SND_SOC_TPA6130A2 267config SND_SOC_TPA6130A2
247 tristate 268 tristate
269
270config SND_SOC_WM2000
271 tristate
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index dbaecb133ac7..dd5ce6df6292 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -10,6 +10,7 @@ snd-soc-ak4642-objs := ak4642.o
10snd-soc-ak4671-objs := ak4671.o 10snd-soc-ak4671-objs := ak4671.o
11snd-soc-cs4270-objs := cs4270.o 11snd-soc-cs4270-objs := cs4270.o
12snd-soc-cx20442-objs := cx20442.o 12snd-soc-cx20442-objs := cx20442.o
13snd-soc-da7210-objs := da7210.o
13snd-soc-l3-objs := l3.o 14snd-soc-l3-objs := l3.o
14snd-soc-pcm3008-objs := pcm3008.o 15snd-soc-pcm3008-objs := pcm3008.o
15snd-soc-spdif-objs := spdif_transciever.o 16snd-soc-spdif-objs := spdif_transciever.o
@@ -36,14 +37,18 @@ snd-soc-wm8753-objs := wm8753.o
36snd-soc-wm8776-objs := wm8776.o 37snd-soc-wm8776-objs := wm8776.o
37snd-soc-wm8900-objs := wm8900.o 38snd-soc-wm8900-objs := wm8900.o
38snd-soc-wm8903-objs := wm8903.o 39snd-soc-wm8903-objs := wm8903.o
40snd-soc-wm8904-objs := wm8904.o
39snd-soc-wm8940-objs := wm8940.o 41snd-soc-wm8940-objs := wm8940.o
42snd-soc-wm8955-objs := wm8955.o
40snd-soc-wm8960-objs := wm8960.o 43snd-soc-wm8960-objs := wm8960.o
41snd-soc-wm8961-objs := wm8961.o 44snd-soc-wm8961-objs := wm8961.o
42snd-soc-wm8971-objs := wm8971.o 45snd-soc-wm8971-objs := wm8971.o
43snd-soc-wm8974-objs := wm8974.o 46snd-soc-wm8974-objs := wm8974.o
47snd-soc-wm8978-objs := wm8978.o
44snd-soc-wm8988-objs := wm8988.o 48snd-soc-wm8988-objs := wm8988.o
45snd-soc-wm8990-objs := wm8990.o 49snd-soc-wm8990-objs := wm8990.o
46snd-soc-wm8993-objs := wm8993.o 50snd-soc-wm8993-objs := wm8993.o
51snd-soc-wm8994-objs := wm8994.o
47snd-soc-wm9081-objs := wm9081.o 52snd-soc-wm9081-objs := wm9081.o
48snd-soc-wm9705-objs := wm9705.o 53snd-soc-wm9705-objs := wm9705.o
49snd-soc-wm9712-objs := wm9712.o 54snd-soc-wm9712-objs := wm9712.o
@@ -53,6 +58,7 @@ snd-soc-wm-hubs-objs := wm_hubs.o
53# Amp 58# Amp
54snd-soc-max9877-objs := max9877.o 59snd-soc-max9877-objs := max9877.o
55snd-soc-tpa6130a2-objs := tpa6130a2.o 60snd-soc-tpa6130a2-objs := tpa6130a2.o
61snd-soc-wm2000-objs := wm2000.o
56 62
57obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o 63obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o
58obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o 64obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o
@@ -66,6 +72,7 @@ obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o
66obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o 72obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o
67obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o 73obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
68obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o 74obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o
75obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o
69obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o 76obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o
70obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o 77obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o
71obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o 78obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o
@@ -92,14 +99,18 @@ obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o
92obj-$(CONFIG_SND_SOC_WM8776) += snd-soc-wm8776.o 99obj-$(CONFIG_SND_SOC_WM8776) += snd-soc-wm8776.o
93obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o 100obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o
94obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o 101obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o
95obj-$(CONFIG_SND_SOC_WM8971) += snd-soc-wm8971.o 102obj-$(CONFIG_SND_SOC_WM8904) += snd-soc-wm8904.o
96obj-$(CONFIG_SND_SOC_WM8974) += snd-soc-wm8974.o
97obj-$(CONFIG_SND_SOC_WM8940) += snd-soc-wm8940.o 103obj-$(CONFIG_SND_SOC_WM8940) += snd-soc-wm8940.o
104obj-$(CONFIG_SND_SOC_WM8955) += snd-soc-wm8955.o
98obj-$(CONFIG_SND_SOC_WM8960) += snd-soc-wm8960.o 105obj-$(CONFIG_SND_SOC_WM8960) += snd-soc-wm8960.o
99obj-$(CONFIG_SND_SOC_WM8961) += snd-soc-wm8961.o 106obj-$(CONFIG_SND_SOC_WM8961) += snd-soc-wm8961.o
107obj-$(CONFIG_SND_SOC_WM8971) += snd-soc-wm8971.o
108obj-$(CONFIG_SND_SOC_WM8974) += snd-soc-wm8974.o
109obj-$(CONFIG_SND_SOC_WM8978) += snd-soc-wm8978.o
100obj-$(CONFIG_SND_SOC_WM8988) += snd-soc-wm8988.o 110obj-$(CONFIG_SND_SOC_WM8988) += snd-soc-wm8988.o
101obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o 111obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o
102obj-$(CONFIG_SND_SOC_WM8993) += snd-soc-wm8993.o 112obj-$(CONFIG_SND_SOC_WM8993) += snd-soc-wm8993.o
113obj-$(CONFIG_SND_SOC_WM8994) += snd-soc-wm8994.o
103obj-$(CONFIG_SND_SOC_WM9081) += snd-soc-wm9081.o 114obj-$(CONFIG_SND_SOC_WM9081) += snd-soc-wm9081.o
104obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-wm9705.o 115obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-wm9705.o
105obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o 116obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o
@@ -109,3 +120,4 @@ obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o
109# Amp 120# Amp
110obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o 121obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o
111obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o 122obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o
123obj-$(CONFIG_SND_SOC_WM2000) += snd-soc-wm2000.o
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c
index 2c18e3d1b71e..3c80137d5938 100644
--- a/sound/soc/codecs/ad1836.c
+++ b/sound/soc/codecs/ad1836.c
@@ -171,57 +171,35 @@ static int ad1836_hw_params(struct snd_pcm_substream *substream,
171 return 0; 171 return 0;
172} 172}
173 173
174 174#ifdef CONFIG_PM
175/* 175static int ad1836_soc_suspend(struct platform_device *pdev,
176 * interface to read/write ad1836 register 176 pm_message_t state)
177 */
178#define AD1836_SPI_REG_SHFT 12
179#define AD1836_SPI_READ (1 << 11)
180#define AD1836_SPI_VAL_MSK 0x3FF
181
182/*
183 * write to the ad1836 register space
184 */
185
186static int ad1836_write_reg(struct snd_soc_codec *codec, unsigned int reg,
187 unsigned int value)
188{ 177{
189 u16 *reg_cache = codec->reg_cache; 178 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
190 int ret = 0; 179 struct snd_soc_codec *codec = socdev->card->codec;
191 180
192 if (value != reg_cache[reg]) { 181 /* reset clock control mode */
193 unsigned short buf; 182 u16 adc_ctrl2 = snd_soc_read(codec, AD1836_ADC_CTRL2);
194 struct spi_transfer t = { 183 adc_ctrl2 &= ~AD1836_ADC_SERFMT_MASK;
195 .tx_buf = &buf,
196 .len = 2,
197 };
198 struct spi_message m;
199
200 buf = (reg << AD1836_SPI_REG_SHFT) |
201 (value & AD1836_SPI_VAL_MSK);
202 spi_message_init(&m);
203 spi_message_add_tail(&t, &m);
204 ret = spi_sync(codec->control_data, &m);
205 if (ret == 0)
206 reg_cache[reg] = value;
207 }
208 184
209 return ret; 185 return snd_soc_write(codec, AD1836_ADC_CTRL2, adc_ctrl2);
210} 186}
211 187
212/* 188static int ad1836_soc_resume(struct platform_device *pdev)
213 * read from the ad1836 register space cache
214 */
215static unsigned int ad1836_read_reg_cache(struct snd_soc_codec *codec,
216 unsigned int reg)
217{ 189{
218 u16 *reg_cache = codec->reg_cache; 190 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
191 struct snd_soc_codec *codec = socdev->card->codec;
219 192
220 if (reg >= codec->reg_cache_size) 193 /* restore clock control mode */
221 return -EINVAL; 194 u16 adc_ctrl2 = snd_soc_read(codec, AD1836_ADC_CTRL2);
195 adc_ctrl2 |= AD1836_ADC_AUX;
222 196
223 return reg_cache[reg]; 197 return snd_soc_write(codec, AD1836_ADC_CTRL2, adc_ctrl2);
224} 198}
199#else
200#define ad1836_soc_suspend NULL
201#define ad1836_soc_resume NULL
202#endif
225 203
226static int __devinit ad1836_spi_probe(struct spi_device *spi) 204static int __devinit ad1836_spi_probe(struct spi_device *spi)
227{ 205{
@@ -306,32 +284,38 @@ static int ad1836_register(struct ad1836_priv *ad1836)
306 codec->owner = THIS_MODULE; 284 codec->owner = THIS_MODULE;
307 codec->dai = &ad1836_dai; 285 codec->dai = &ad1836_dai;
308 codec->num_dai = 1; 286 codec->num_dai = 1;
309 codec->write = ad1836_write_reg;
310 codec->read = ad1836_read_reg_cache;
311 INIT_LIST_HEAD(&codec->dapm_widgets); 287 INIT_LIST_HEAD(&codec->dapm_widgets);
312 INIT_LIST_HEAD(&codec->dapm_paths); 288 INIT_LIST_HEAD(&codec->dapm_paths);
313 289
314 ad1836_dai.dev = codec->dev; 290 ad1836_dai.dev = codec->dev;
315 ad1836_codec = codec; 291 ad1836_codec = codec;
316 292
293 ret = snd_soc_codec_set_cache_io(codec, 4, 12, SND_SOC_SPI);
294 if (ret < 0) {
295 dev_err(codec->dev, "failed to set cache I/O: %d\n",
296 ret);
297 kfree(ad1836);
298 return ret;
299 }
300
317 /* default setting for ad1836 */ 301 /* default setting for ad1836 */
318 /* de-emphasis: 48kHz, power-on dac */ 302 /* de-emphasis: 48kHz, power-on dac */
319 codec->write(codec, AD1836_DAC_CTRL1, 0x300); 303 snd_soc_write(codec, AD1836_DAC_CTRL1, 0x300);
320 /* unmute dac channels */ 304 /* unmute dac channels */
321 codec->write(codec, AD1836_DAC_CTRL2, 0x0); 305 snd_soc_write(codec, AD1836_DAC_CTRL2, 0x0);
322 /* high-pass filter enable, power-on adc */ 306 /* high-pass filter enable, power-on adc */
323 codec->write(codec, AD1836_ADC_CTRL1, 0x100); 307 snd_soc_write(codec, AD1836_ADC_CTRL1, 0x100);
324 /* unmute adc channles, adc aux mode */ 308 /* unmute adc channles, adc aux mode */
325 codec->write(codec, AD1836_ADC_CTRL2, 0x180); 309 snd_soc_write(codec, AD1836_ADC_CTRL2, 0x180);
326 /* left/right diff:PGA/MUX */ 310 /* left/right diff:PGA/MUX */
327 codec->write(codec, AD1836_ADC_CTRL3, 0x3A); 311 snd_soc_write(codec, AD1836_ADC_CTRL3, 0x3A);
328 /* volume */ 312 /* volume */
329 codec->write(codec, AD1836_DAC_L1_VOL, 0x3FF); 313 snd_soc_write(codec, AD1836_DAC_L1_VOL, 0x3FF);
330 codec->write(codec, AD1836_DAC_R1_VOL, 0x3FF); 314 snd_soc_write(codec, AD1836_DAC_R1_VOL, 0x3FF);
331 codec->write(codec, AD1836_DAC_L2_VOL, 0x3FF); 315 snd_soc_write(codec, AD1836_DAC_L2_VOL, 0x3FF);
332 codec->write(codec, AD1836_DAC_R2_VOL, 0x3FF); 316 snd_soc_write(codec, AD1836_DAC_R2_VOL, 0x3FF);
333 codec->write(codec, AD1836_DAC_L3_VOL, 0x3FF); 317 snd_soc_write(codec, AD1836_DAC_L3_VOL, 0x3FF);
334 codec->write(codec, AD1836_DAC_R3_VOL, 0x3FF); 318 snd_soc_write(codec, AD1836_DAC_R3_VOL, 0x3FF);
335 319
336 ret = snd_soc_register_codec(codec); 320 ret = snd_soc_register_codec(codec);
337 if (ret != 0) { 321 if (ret != 0) {
@@ -404,6 +388,8 @@ static int ad1836_remove(struct platform_device *pdev)
404struct snd_soc_codec_device soc_codec_dev_ad1836 = { 388struct snd_soc_codec_device soc_codec_dev_ad1836 = {
405 .probe = ad1836_probe, 389 .probe = ad1836_probe,
406 .remove = ad1836_remove, 390 .remove = ad1836_remove,
391 .suspend = ad1836_soc_suspend,
392 .resume = ad1836_soc_resume,
407}; 393};
408EXPORT_SYMBOL_GPL(soc_codec_dev_ad1836); 394EXPORT_SYMBOL_GPL(soc_codec_dev_ad1836);
409 395
diff --git a/sound/soc/codecs/ad1836.h b/sound/soc/codecs/ad1836.h
index 7660ee6973c0..e9d90d3951c5 100644
--- a/sound/soc/codecs/ad1836.h
+++ b/sound/soc/codecs/ad1836.h
@@ -54,6 +54,7 @@
54#define AD1836_ADC_SERFMT_MASK (7 << 6) 54#define AD1836_ADC_SERFMT_MASK (7 << 6)
55#define AD1836_ADC_SERFMT_PCK256 (0x4 << 6) 55#define AD1836_ADC_SERFMT_PCK256 (0x4 << 6)
56#define AD1836_ADC_SERFMT_PCK128 (0x5 << 6) 56#define AD1836_ADC_SERFMT_PCK128 (0x5 << 6)
57#define AD1836_ADC_AUX (0x6 << 6)
57 58
58#define AD1836_ADC_CTRL3 14 59#define AD1836_ADC_CTRL3 14
59 60
diff --git a/sound/soc/codecs/ad1938.c b/sound/soc/codecs/ad1938.c
index 5d489186c05b..c233810d463d 100644
--- a/sound/soc/codecs/ad1938.c
+++ b/sound/soc/codecs/ad1938.c
@@ -46,6 +46,11 @@ struct ad1938_priv {
46 u8 reg_cache[AD1938_NUM_REGS]; 46 u8 reg_cache[AD1938_NUM_REGS];
47}; 47};
48 48
49/* ad1938 register cache & default register settings */
50static const u8 ad1938_reg[AD1938_NUM_REGS] = {
51 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0,
52};
53
49static struct snd_soc_codec *ad1938_codec; 54static struct snd_soc_codec *ad1938_codec;
50struct snd_soc_codec_device soc_codec_dev_ad1938; 55struct snd_soc_codec_device soc_codec_dev_ad1938;
51static int ad1938_register(struct ad1938_priv *ad1938); 56static int ad1938_register(struct ad1938_priv *ad1938);
@@ -97,6 +102,7 @@ static const struct snd_kcontrol_new ad1938_snd_controls[] = {
97static const struct snd_soc_dapm_widget ad1938_dapm_widgets[] = { 102static const struct snd_soc_dapm_widget ad1938_dapm_widgets[] = {
98 SND_SOC_DAPM_DAC("DAC", "Playback", AD1938_DAC_CTRL0, 0, 1), 103 SND_SOC_DAPM_DAC("DAC", "Playback", AD1938_DAC_CTRL0, 0, 1),
99 SND_SOC_DAPM_ADC("ADC", "Capture", SND_SOC_NOPM, 0, 0), 104 SND_SOC_DAPM_ADC("ADC", "Capture", SND_SOC_NOPM, 0, 0),
105 SND_SOC_DAPM_SUPPLY("PLL_PWR", AD1938_PLL_CLK_CTRL0, 0, 1, NULL, 0),
100 SND_SOC_DAPM_SUPPLY("ADC_PWR", AD1938_ADC_CTRL0, 0, 1, NULL, 0), 106 SND_SOC_DAPM_SUPPLY("ADC_PWR", AD1938_ADC_CTRL0, 0, 1, NULL, 0),
101 SND_SOC_DAPM_OUTPUT("DAC1OUT"), 107 SND_SOC_DAPM_OUTPUT("DAC1OUT"),
102 SND_SOC_DAPM_OUTPUT("DAC2OUT"), 108 SND_SOC_DAPM_OUTPUT("DAC2OUT"),
@@ -107,6 +113,8 @@ static const struct snd_soc_dapm_widget ad1938_dapm_widgets[] = {
107}; 113};
108 114
109static const struct snd_soc_dapm_route audio_paths[] = { 115static const struct snd_soc_dapm_route audio_paths[] = {
116 { "DAC", NULL, "PLL_PWR" },
117 { "ADC", NULL, "PLL_PWR" },
110 { "DAC", NULL, "ADC_PWR" }, 118 { "DAC", NULL, "ADC_PWR" },
111 { "ADC", NULL, "ADC_PWR" }, 119 { "ADC", NULL, "ADC_PWR" },
112 { "DAC1OUT", "DAC1 Switch", "DAC" }, 120 { "DAC1OUT", "DAC1 Switch", "DAC" },
@@ -126,30 +134,20 @@ static int ad1938_mute(struct snd_soc_dai *dai, int mute)
126 struct snd_soc_codec *codec = dai->codec; 134 struct snd_soc_codec *codec = dai->codec;
127 int reg; 135 int reg;
128 136
129 reg = codec->read(codec, AD1938_DAC_CTRL2); 137 reg = snd_soc_read(codec, AD1938_DAC_CTRL2);
130 reg = (mute > 0) ? reg | AD1938_DAC_MASTER_MUTE : reg & 138 reg = (mute > 0) ? reg | AD1938_DAC_MASTER_MUTE : reg &
131 (~AD1938_DAC_MASTER_MUTE); 139 (~AD1938_DAC_MASTER_MUTE);
132 codec->write(codec, AD1938_DAC_CTRL2, reg); 140 snd_soc_write(codec, AD1938_DAC_CTRL2, reg);
133
134 return 0;
135}
136
137static inline int ad1938_pll_powerctrl(struct snd_soc_codec *codec, int cmd)
138{
139 int reg = codec->read(codec, AD1938_PLL_CLK_CTRL0);
140 reg = (cmd > 0) ? reg & (~AD1938_PLL_POWERDOWN) : reg |
141 AD1938_PLL_POWERDOWN;
142 codec->write(codec, AD1938_PLL_CLK_CTRL0, reg);
143 141
144 return 0; 142 return 0;
145} 143}
146 144
147static int ad1938_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, 145static int ad1938_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
148 unsigned int mask, int slots, int width) 146 unsigned int rx_mask, int slots, int width)
149{ 147{
150 struct snd_soc_codec *codec = dai->codec; 148 struct snd_soc_codec *codec = dai->codec;
151 int dac_reg = codec->read(codec, AD1938_DAC_CTRL1); 149 int dac_reg = snd_soc_read(codec, AD1938_DAC_CTRL1);
152 int adc_reg = codec->read(codec, AD1938_ADC_CTRL2); 150 int adc_reg = snd_soc_read(codec, AD1938_ADC_CTRL2);
153 151
154 dac_reg &= ~AD1938_DAC_CHAN_MASK; 152 dac_reg &= ~AD1938_DAC_CHAN_MASK;
155 adc_reg &= ~AD1938_ADC_CHAN_MASK; 153 adc_reg &= ~AD1938_ADC_CHAN_MASK;
@@ -175,8 +173,8 @@ static int ad1938_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
175 return -EINVAL; 173 return -EINVAL;
176 } 174 }
177 175
178 codec->write(codec, AD1938_DAC_CTRL1, dac_reg); 176 snd_soc_write(codec, AD1938_DAC_CTRL1, dac_reg);
179 codec->write(codec, AD1938_ADC_CTRL2, adc_reg); 177 snd_soc_write(codec, AD1938_ADC_CTRL2, adc_reg);
180 178
181 return 0; 179 return 0;
182} 180}
@@ -187,8 +185,8 @@ static int ad1938_set_dai_fmt(struct snd_soc_dai *codec_dai,
187 struct snd_soc_codec *codec = codec_dai->codec; 185 struct snd_soc_codec *codec = codec_dai->codec;
188 int adc_reg, dac_reg; 186 int adc_reg, dac_reg;
189 187
190 adc_reg = codec->read(codec, AD1938_ADC_CTRL2); 188 adc_reg = snd_soc_read(codec, AD1938_ADC_CTRL2);
191 dac_reg = codec->read(codec, AD1938_DAC_CTRL1); 189 dac_reg = snd_soc_read(codec, AD1938_DAC_CTRL1);
192 190
193 /* At present, the driver only support AUX ADC mode(SND_SOC_DAIFMT_I2S 191 /* At present, the driver only support AUX ADC mode(SND_SOC_DAIFMT_I2S
194 * with TDM) and ADC&DAC TDM mode(SND_SOC_DAIFMT_DSP_A) 192 * with TDM) and ADC&DAC TDM mode(SND_SOC_DAIFMT_DSP_A)
@@ -265,8 +263,8 @@ static int ad1938_set_dai_fmt(struct snd_soc_dai *codec_dai,
265 return -EINVAL; 263 return -EINVAL;
266 } 264 }
267 265
268 codec->write(codec, AD1938_ADC_CTRL2, adc_reg); 266 snd_soc_write(codec, AD1938_ADC_CTRL2, adc_reg);
269 codec->write(codec, AD1938_DAC_CTRL1, dac_reg); 267 snd_soc_write(codec, AD1938_DAC_CTRL1, dac_reg);
270 268
271 return 0; 269 return 0;
272} 270}
@@ -295,134 +293,13 @@ static int ad1938_hw_params(struct snd_pcm_substream *substream,
295 break; 293 break;
296 } 294 }
297 295
298 reg = codec->read(codec, AD1938_DAC_CTRL2); 296 reg = snd_soc_read(codec, AD1938_DAC_CTRL2);
299 reg = (reg & (~AD1938_DAC_WORD_LEN_MASK)) | word_len; 297 reg = (reg & (~AD1938_DAC_WORD_LEN_MASK)) | word_len;
300 codec->write(codec, AD1938_DAC_CTRL2, reg); 298 snd_soc_write(codec, AD1938_DAC_CTRL2, reg);
301 299
302 reg = codec->read(codec, AD1938_ADC_CTRL1); 300 reg = snd_soc_read(codec, AD1938_ADC_CTRL1);
303 reg = (reg & (~AD1938_ADC_WORD_LEN_MASK)) | word_len; 301 reg = (reg & (~AD1938_ADC_WORD_LEN_MASK)) | word_len;
304 codec->write(codec, AD1938_ADC_CTRL1, reg); 302 snd_soc_write(codec, AD1938_ADC_CTRL1, reg);
305
306 return 0;
307}
308
309static int ad1938_set_bias_level(struct snd_soc_codec *codec,
310 enum snd_soc_bias_level level)
311{
312 switch (level) {
313 case SND_SOC_BIAS_ON:
314 ad1938_pll_powerctrl(codec, 1);
315 break;
316 case SND_SOC_BIAS_PREPARE:
317 break;
318 case SND_SOC_BIAS_STANDBY:
319 case SND_SOC_BIAS_OFF:
320 ad1938_pll_powerctrl(codec, 0);
321 break;
322 }
323 codec->bias_level = level;
324 return 0;
325}
326
327/*
328 * interface to read/write ad1938 register
329 */
330
331#define AD1938_SPI_ADDR 0x4
332#define AD1938_SPI_READ 0x1
333#define AD1938_SPI_BUFLEN 3
334
335/*
336 * write to the ad1938 register space
337 */
338
339static int ad1938_write_reg(struct snd_soc_codec *codec, unsigned int reg,
340 unsigned int value)
341{
342 u8 *reg_cache = codec->reg_cache;
343 int ret = 0;
344
345 if (value != reg_cache[reg]) {
346 uint8_t buf[AD1938_SPI_BUFLEN];
347 struct spi_transfer t = {
348 .tx_buf = buf,
349 .len = AD1938_SPI_BUFLEN,
350 };
351 struct spi_message m;
352
353 buf[0] = AD1938_SPI_ADDR << 1;
354 buf[1] = reg;
355 buf[2] = value;
356 spi_message_init(&m);
357 spi_message_add_tail(&t, &m);
358 ret = spi_sync(codec->control_data, &m);
359 if (ret == 0)
360 reg_cache[reg] = value;
361 }
362
363 return ret;
364}
365
366/*
367 * read from the ad1938 register space cache
368 */
369
370static unsigned int ad1938_read_reg_cache(struct snd_soc_codec *codec,
371 unsigned int reg)
372{
373 u8 *reg_cache = codec->reg_cache;
374
375 if (reg >= codec->reg_cache_size)
376 return -EINVAL;
377
378 return reg_cache[reg];
379}
380
381/*
382 * read from the ad1938 register space
383 */
384
385static unsigned int ad1938_read_reg(struct snd_soc_codec *codec,
386 unsigned int reg)
387{
388 char w_buf[AD1938_SPI_BUFLEN];
389 char r_buf[AD1938_SPI_BUFLEN];
390 int ret;
391
392 struct spi_transfer t = {
393 .tx_buf = w_buf,
394 .rx_buf = r_buf,
395 .len = AD1938_SPI_BUFLEN,
396 };
397 struct spi_message m;
398
399 w_buf[0] = (AD1938_SPI_ADDR << 1) | AD1938_SPI_READ;
400 w_buf[1] = reg;
401 w_buf[2] = 0;
402
403 spi_message_init(&m);
404 spi_message_add_tail(&t, &m);
405 ret = spi_sync(codec->control_data, &m);
406 if (ret == 0)
407 return r_buf[2];
408 else
409 return -EIO;
410}
411
412static int ad1938_fill_cache(struct snd_soc_codec *codec)
413{
414 int i;
415 u8 *reg_cache = codec->reg_cache;
416 struct spi_device *spi = codec->control_data;
417
418 for (i = 0; i < codec->reg_cache_size; i++) {
419 int ret = ad1938_read_reg(codec, i);
420 if (ret == -EIO) {
421 dev_err(&spi->dev, "AD1938 SPI read failure\n");
422 return ret;
423 }
424 reg_cache[i] = ret;
425 }
426 303
427 return 0; 304 return 0;
428} 305}
@@ -512,32 +389,37 @@ static int ad1938_register(struct ad1938_priv *ad1938)
512 codec->owner = THIS_MODULE; 389 codec->owner = THIS_MODULE;
513 codec->dai = &ad1938_dai; 390 codec->dai = &ad1938_dai;
514 codec->num_dai = 1; 391 codec->num_dai = 1;
515 codec->write = ad1938_write_reg;
516 codec->read = ad1938_read_reg_cache;
517 codec->set_bias_level = ad1938_set_bias_level;
518 INIT_LIST_HEAD(&codec->dapm_widgets); 392 INIT_LIST_HEAD(&codec->dapm_widgets);
519 INIT_LIST_HEAD(&codec->dapm_paths); 393 INIT_LIST_HEAD(&codec->dapm_paths);
520 394
521 ad1938_dai.dev = codec->dev; 395 ad1938_dai.dev = codec->dev;
522 ad1938_codec = codec; 396 ad1938_codec = codec;
523 397
398 memcpy(codec->reg_cache, ad1938_reg, AD1938_NUM_REGS);
399
400 ret = snd_soc_codec_set_cache_io(codec, 16, 8, SND_SOC_SPI);
401 if (ret < 0) {
402 dev_err(codec->dev, "failed to set cache I/O: %d\n",
403 ret);
404 kfree(ad1938);
405 return ret;
406 }
407
524 /* default setting for ad1938 */ 408 /* default setting for ad1938 */
525 409
526 /* unmute dac channels */ 410 /* unmute dac channels */
527 codec->write(codec, AD1938_DAC_CHNL_MUTE, 0x0); 411 snd_soc_write(codec, AD1938_DAC_CHNL_MUTE, 0x0);
528 /* de-emphasis: 48kHz, powedown dac */ 412 /* de-emphasis: 48kHz, powedown dac */
529 codec->write(codec, AD1938_DAC_CTRL2, 0x1A); 413 snd_soc_write(codec, AD1938_DAC_CTRL2, 0x1A);
530 /* powerdown dac, dac in tdm mode */ 414 /* powerdown dac, dac in tdm mode */
531 codec->write(codec, AD1938_DAC_CTRL0, 0x41); 415 snd_soc_write(codec, AD1938_DAC_CTRL0, 0x41);
532 /* high-pass filter enable */ 416 /* high-pass filter enable */
533 codec->write(codec, AD1938_ADC_CTRL0, 0x3); 417 snd_soc_write(codec, AD1938_ADC_CTRL0, 0x3);
534 /* sata delay=1, adc aux mode */ 418 /* sata delay=1, adc aux mode */
535 codec->write(codec, AD1938_ADC_CTRL1, 0x43); 419 snd_soc_write(codec, AD1938_ADC_CTRL1, 0x43);
536 /* pll input: mclki/xi */ 420 /* pll input: mclki/xi */
537 codec->write(codec, AD1938_PLL_CLK_CTRL0, 0x9D); 421 snd_soc_write(codec, AD1938_PLL_CLK_CTRL0, 0x9D);
538 codec->write(codec, AD1938_PLL_CLK_CTRL1, 0x04); 422 snd_soc_write(codec, AD1938_PLL_CLK_CTRL1, 0x04);
539
540 ad1938_fill_cache(codec);
541 423
542 ret = snd_soc_register_codec(codec); 424 ret = snd_soc_register_codec(codec);
543 if (ret != 0) { 425 if (ret != 0) {
@@ -559,7 +441,6 @@ static int ad1938_register(struct ad1938_priv *ad1938)
559 441
560static void ad1938_unregister(struct ad1938_priv *ad1938) 442static void ad1938_unregister(struct ad1938_priv *ad1938)
561{ 443{
562 ad1938_set_bias_level(&ad1938->codec, SND_SOC_BIAS_OFF);
563 snd_soc_unregister_dai(&ad1938_dai); 444 snd_soc_unregister_dai(&ad1938_dai);
564 snd_soc_unregister_codec(&ad1938->codec); 445 snd_soc_unregister_codec(&ad1938->codec);
565 kfree(ad1938); 446 kfree(ad1938);
@@ -593,7 +474,6 @@ static int ad1938_probe(struct platform_device *pdev)
593 ARRAY_SIZE(ad1938_dapm_widgets)); 474 ARRAY_SIZE(ad1938_dapm_widgets));
594 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); 475 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
595 476
596 ad1938_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
597 477
598pcm_err: 478pcm_err:
599 return ret; 479 return ret;
@@ -610,37 +490,9 @@ static int ad1938_remove(struct platform_device *pdev)
610 return 0; 490 return 0;
611} 491}
612 492
613#ifdef CONFIG_PM
614static int ad1938_suspend(struct platform_device *pdev,
615 pm_message_t state)
616{
617 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
618 struct snd_soc_codec *codec = socdev->card->codec;
619
620 ad1938_set_bias_level(codec, SND_SOC_BIAS_OFF);
621 return 0;
622}
623
624static int ad1938_resume(struct platform_device *pdev)
625{
626 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
627 struct snd_soc_codec *codec = socdev->card->codec;
628
629 if (codec->suspend_bias_level == SND_SOC_BIAS_ON)
630 ad1938_set_bias_level(codec, SND_SOC_BIAS_ON);
631
632 return 0;
633}
634#else
635#define ad1938_suspend NULL
636#define ad1938_resume NULL
637#endif
638
639struct snd_soc_codec_device soc_codec_dev_ad1938 = { 493struct snd_soc_codec_device soc_codec_dev_ad1938 = {
640 .probe = ad1938_probe, 494 .probe = ad1938_probe,
641 .remove = ad1938_remove, 495 .remove = ad1938_remove,
642 .suspend = ad1938_suspend,
643 .resume = ad1938_resume,
644}; 496};
645EXPORT_SYMBOL_GPL(soc_codec_dev_ad1938); 497EXPORT_SYMBOL_GPL(soc_codec_dev_ad1938);
646 498
diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c
index 3a14c6fc4f5e..b9ef7e45891d 100644
--- a/sound/soc/codecs/ak4104.c
+++ b/sound/soc/codecs/ak4104.c
@@ -185,9 +185,7 @@ struct snd_soc_dai ak4104_dai = {
185 .stream_name = "Playback", 185 .stream_name = "Playback",
186 .channels_min = 2, 186 .channels_min = 2,
187 .channels_max = 2, 187 .channels_max = 2,
188 .rates = SNDRV_PCM_RATE_44100 | 188 .rates = SNDRV_PCM_RATE_8000_192000,
189 SNDRV_PCM_RATE_48000 |
190 SNDRV_PCM_RATE_32000,
191 .formats = SNDRV_PCM_FMTBIT_S16_LE | 189 .formats = SNDRV_PCM_FMTBIT_S16_LE |
192 SNDRV_PCM_FMTBIT_S24_3LE | 190 SNDRV_PCM_FMTBIT_S24_3LE |
193 SNDRV_PCM_FMTBIT_S24_LE 191 SNDRV_PCM_FMTBIT_S24_LE
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index ffe122d1cd76..dfbeb2db61b3 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -28,6 +28,7 @@
28#include <sound/initval.h> 28#include <sound/initval.h>
29#include <linux/i2c.h> 29#include <linux/i2c.h>
30#include <linux/delay.h> 30#include <linux/delay.h>
31#include <linux/regulator/consumer.h>
31 32
32#include "cs4270.h" 33#include "cs4270.h"
33 34
@@ -106,6 +107,10 @@
106#define CS4270_MUTE_DAC_A 0x01 107#define CS4270_MUTE_DAC_A 0x01
107#define CS4270_MUTE_DAC_B 0x02 108#define CS4270_MUTE_DAC_B 0x02
108 109
110static const char *supply_names[] = {
111 "va", "vd", "vlc"
112};
113
109/* Private data for the CS4270 */ 114/* Private data for the CS4270 */
110struct cs4270_private { 115struct cs4270_private {
111 struct snd_soc_codec codec; 116 struct snd_soc_codec codec;
@@ -114,6 +119,9 @@ struct cs4270_private {
114 unsigned int mode; /* The mode (I2S or left-justified) */ 119 unsigned int mode; /* The mode (I2S or left-justified) */
115 unsigned int slave_mode; 120 unsigned int slave_mode;
116 unsigned int manual_mute; 121 unsigned int manual_mute;
122
123 /* power domain regulators */
124 struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)];
117}; 125};
118 126
119/** 127/**
@@ -192,6 +200,11 @@ static struct cs4270_mode_ratios cs4270_mode_ratios[] = {
192 * This function must be called by the machine driver's 'startup' function, 200 * This function must be called by the machine driver's 'startup' function,
193 * otherwise the list of supported sample rates will not be available in 201 * otherwise the list of supported sample rates will not be available in
194 * time for ALSA. 202 * time for ALSA.
203 *
204 * For setups with variable MCLKs, pass 0 as 'freq' argument. This will cause
205 * theoretically possible sample rates to be enabled. Call it again with a
206 * proper value set one the external clock is set (most probably you would do
207 * that from a machine's driver 'hw_param' hook.
195 */ 208 */
196static int cs4270_set_dai_sysclk(struct snd_soc_dai *codec_dai, 209static int cs4270_set_dai_sysclk(struct snd_soc_dai *codec_dai,
197 int clk_id, unsigned int freq, int dir) 210 int clk_id, unsigned int freq, int dir)
@@ -205,20 +218,27 @@ static int cs4270_set_dai_sysclk(struct snd_soc_dai *codec_dai,
205 218
206 cs4270->mclk = freq; 219 cs4270->mclk = freq;
207 220
208 for (i = 0; i < NUM_MCLK_RATIOS; i++) { 221 if (cs4270->mclk) {
209 unsigned int rate = freq / cs4270_mode_ratios[i].ratio; 222 for (i = 0; i < NUM_MCLK_RATIOS; i++) {
210 rates |= snd_pcm_rate_to_rate_bit(rate); 223 unsigned int rate = freq / cs4270_mode_ratios[i].ratio;
211 if (rate < rate_min) 224 rates |= snd_pcm_rate_to_rate_bit(rate);
212 rate_min = rate; 225 if (rate < rate_min)
213 if (rate > rate_max) 226 rate_min = rate;
214 rate_max = rate; 227 if (rate > rate_max)
215 } 228 rate_max = rate;
216 /* FIXME: soc should support a rate list */ 229 }
217 rates &= ~SNDRV_PCM_RATE_KNOT; 230 /* FIXME: soc should support a rate list */
231 rates &= ~SNDRV_PCM_RATE_KNOT;
218 232
219 if (!rates) { 233 if (!rates) {
220 dev_err(codec->dev, "could not find a valid sample rate\n"); 234 dev_err(codec->dev, "could not find a valid sample rate\n");
221 return -EINVAL; 235 return -EINVAL;
236 }
237 } else {
238 /* enable all possible rates */
239 rates = SNDRV_PCM_RATE_8000_192000;
240 rate_min = 8000;
241 rate_max = 192000;
222 } 242 }
223 243
224 codec_dai->playback.rates = rates; 244 codec_dai->playback.rates = rates;
@@ -579,7 +599,8 @@ static int cs4270_probe(struct platform_device *pdev)
579{ 599{
580 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 600 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
581 struct snd_soc_codec *codec = cs4270_codec; 601 struct snd_soc_codec *codec = cs4270_codec;
582 int ret; 602 struct cs4270_private *cs4270 = codec->private_data;
603 int i, ret;
583 604
584 /* Connect the codec to the socdev. snd_soc_new_pcms() needs this. */ 605 /* Connect the codec to the socdev. snd_soc_new_pcms() needs this. */
585 socdev->card->codec = codec; 606 socdev->card->codec = codec;
@@ -599,8 +620,26 @@ static int cs4270_probe(struct platform_device *pdev)
599 goto error_free_pcms; 620 goto error_free_pcms;
600 } 621 }
601 622
623 /* get the power supply regulators */
624 for (i = 0; i < ARRAY_SIZE(supply_names); i++)
625 cs4270->supplies[i].supply = supply_names[i];
626
627 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(cs4270->supplies),
628 cs4270->supplies);
629 if (ret < 0)
630 goto error_free_pcms;
631
632 ret = regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies),
633 cs4270->supplies);
634 if (ret < 0)
635 goto error_free_regulators;
636
602 return 0; 637 return 0;
603 638
639error_free_regulators:
640 regulator_bulk_free(ARRAY_SIZE(cs4270->supplies),
641 cs4270->supplies);
642
604error_free_pcms: 643error_free_pcms:
605 snd_soc_free_pcms(socdev); 644 snd_soc_free_pcms(socdev);
606 645
@@ -616,8 +655,12 @@ error_free_pcms:
616static int cs4270_remove(struct platform_device *pdev) 655static int cs4270_remove(struct platform_device *pdev)
617{ 656{
618 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 657 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
658 struct snd_soc_codec *codec = cs4270_codec;
659 struct cs4270_private *cs4270 = codec->private_data;
619 660
620 snd_soc_free_pcms(socdev); 661 snd_soc_free_pcms(socdev);
662 regulator_bulk_disable(ARRAY_SIZE(cs4270->supplies), cs4270->supplies);
663 regulator_bulk_free(ARRAY_SIZE(cs4270->supplies), cs4270->supplies);
621 664
622 return 0; 665 return 0;
623}; 666};
@@ -799,17 +842,33 @@ MODULE_DEVICE_TABLE(i2c, cs4270_id);
799static int cs4270_soc_suspend(struct platform_device *pdev, pm_message_t mesg) 842static int cs4270_soc_suspend(struct platform_device *pdev, pm_message_t mesg)
800{ 843{
801 struct snd_soc_codec *codec = cs4270_codec; 844 struct snd_soc_codec *codec = cs4270_codec;
802 int reg = snd_soc_read(codec, CS4270_PWRCTL) | CS4270_PWRCTL_PDN_ALL; 845 struct cs4270_private *cs4270 = codec->private_data;
846 int reg, ret;
803 847
804 return snd_soc_write(codec, CS4270_PWRCTL, reg); 848 reg = snd_soc_read(codec, CS4270_PWRCTL) | CS4270_PWRCTL_PDN_ALL;
849 if (reg < 0)
850 return reg;
851
852 ret = snd_soc_write(codec, CS4270_PWRCTL, reg);
853 if (ret < 0)
854 return ret;
855
856 regulator_bulk_disable(ARRAY_SIZE(cs4270->supplies),
857 cs4270->supplies);
858
859 return 0;
805} 860}
806 861
807static int cs4270_soc_resume(struct platform_device *pdev) 862static int cs4270_soc_resume(struct platform_device *pdev)
808{ 863{
809 struct snd_soc_codec *codec = cs4270_codec; 864 struct snd_soc_codec *codec = cs4270_codec;
865 struct cs4270_private *cs4270 = codec->private_data;
810 struct i2c_client *i2c_client = codec->control_data; 866 struct i2c_client *i2c_client = codec->control_data;
811 int reg; 867 int reg;
812 868
869 regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies),
870 cs4270->supplies);
871
813 /* In case the device was put to hard reset during sleep, we need to 872 /* In case the device was put to hard reset during sleep, we need to
814 * wait 500ns here before any I2C communication. */ 873 * wait 500ns here before any I2C communication. */
815 ndelay(500); 874 ndelay(500);
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c
new file mode 100644
index 000000000000..cf2975a7294a
--- /dev/null
+++ b/sound/soc/codecs/da7210.c
@@ -0,0 +1,589 @@
1/*
2 * DA7210 ALSA Soc codec driver
3 *
4 * Copyright (c) 2009 Dialog Semiconductor
5 * Written by David Chen <Dajun.chen@diasemi.com>
6 *
7 * Copyright (C) 2009 Renesas Solutions Corp.
8 * Cleanups by Kuninori Morimoto <morimoto.kuninori@renesas.com>
9 *
10 * Tested on SuperH Ecovec24 board with S16/S24 LE in 48KHz using I2S
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version.
16 */
17
18#include <linux/module.h>
19#include <linux/moduleparam.h>
20#include <linux/kernel.h>
21#include <linux/init.h>
22#include <linux/delay.h>
23#include <linux/pm.h>
24#include <linux/i2c.h>
25#include <linux/platform_device.h>
26#include <sound/core.h>
27#include <sound/pcm.h>
28#include <sound/pcm_params.h>
29#include <sound/soc.h>
30#include <sound/soc-dapm.h>
31#include <sound/tlv.h>
32#include <sound/initval.h>
33#include <asm/div64.h>
34
35#include "da7210.h"
36
37/* DA7210 register space */
38#define DA7210_STATUS 0x02
39#define DA7210_STARTUP1 0x03
40#define DA7210_MIC_L 0x07
41#define DA7210_MIC_R 0x08
42#define DA7210_INMIX_L 0x0D
43#define DA7210_INMIX_R 0x0E
44#define DA7210_ADC_HPF 0x0F
45#define DA7210_ADC 0x10
46#define DA7210_DAC_HPF 0x14
47#define DA7210_DAC_L 0x15
48#define DA7210_DAC_R 0x16
49#define DA7210_DAC_SEL 0x17
50#define DA7210_OUTMIX_L 0x1C
51#define DA7210_OUTMIX_R 0x1D
52#define DA7210_HP_L_VOL 0x21
53#define DA7210_HP_R_VOL 0x22
54#define DA7210_HP_CFG 0x23
55#define DA7210_DAI_SRC_SEL 0x25
56#define DA7210_DAI_CFG1 0x26
57#define DA7210_DAI_CFG3 0x28
58#define DA7210_PLL_DIV3 0x2B
59#define DA7210_PLL 0x2C
60
61/* STARTUP1 bit fields */
62#define DA7210_SC_MST_EN (1 << 0)
63
64/* MIC_L bit fields */
65#define DA7210_MICBIAS_EN (1 << 6)
66#define DA7210_MIC_L_EN (1 << 7)
67
68/* MIC_R bit fields */
69#define DA7210_MIC_R_EN (1 << 7)
70
71/* INMIX_L bit fields */
72#define DA7210_IN_L_EN (1 << 7)
73
74/* INMIX_R bit fields */
75#define DA7210_IN_R_EN (1 << 7)
76
77/* ADC_HPF bit fields */
78#define DA7210_ADC_VOICE_EN (1 << 7)
79
80/* ADC bit fields */
81#define DA7210_ADC_L_EN (1 << 3)
82#define DA7210_ADC_R_EN (1 << 7)
83
84/* DAC_HPF fields */
85#define DA7210_DAC_VOICE_EN (1 << 7)
86
87/* DAC_SEL bit fields */
88#define DA7210_DAC_L_SRC_DAI_L (4 << 0)
89#define DA7210_DAC_L_EN (1 << 3)
90#define DA7210_DAC_R_SRC_DAI_R (5 << 4)
91#define DA7210_DAC_R_EN (1 << 7)
92
93/* OUTMIX_L bit fields */
94#define DA7210_OUT_L_EN (1 << 7)
95
96/* OUTMIX_R bit fields */
97#define DA7210_OUT_R_EN (1 << 7)
98
99/* HP_CFG bit fields */
100#define DA7210_HP_2CAP_MODE (1 << 1)
101#define DA7210_HP_SENSE_EN (1 << 2)
102#define DA7210_HP_L_EN (1 << 3)
103#define DA7210_HP_MODE (1 << 6)
104#define DA7210_HP_R_EN (1 << 7)
105
106/* DAI_SRC_SEL bit fields */
107#define DA7210_DAI_OUT_L_SRC (6 << 0)
108#define DA7210_DAI_OUT_R_SRC (7 << 4)
109
110/* DAI_CFG1 bit fields */
111#define DA7210_DAI_WORD_S16_LE (0 << 0)
112#define DA7210_DAI_WORD_S24_LE (2 << 0)
113#define DA7210_DAI_FLEN_64BIT (1 << 2)
114#define DA7210_DAI_MODE_MASTER (1 << 7)
115
116/* DAI_CFG3 bit fields */
117#define DA7210_DAI_FORMAT_I2SMODE (0 << 0)
118#define DA7210_DAI_OE (1 << 3)
119#define DA7210_DAI_EN (1 << 7)
120
121/*PLL_DIV3 bit fields */
122#define DA7210_MCLK_RANGE_10_20_MHZ (1 << 4)
123#define DA7210_PLL_BYP (1 << 6)
124
125/* PLL bit fields */
126#define DA7210_PLL_FS_48000 (11 << 0)
127
128#define DA7210_VERSION "0.0.1"
129
130/* Codec private data */
131struct da7210_priv {
132 struct snd_soc_codec codec;
133};
134
135static struct snd_soc_codec *da7210_codec;
136
137/*
138 * Register cache
139 */
140static const u8 da7210_reg[] = {
141 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R0 - R7 */
142 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, /* R8 - RF */
143 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x10, 0x54, /* R10 - R17 */
144 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R18 - R1F */
145 0x00, 0x00, 0x00, 0x02, 0x00, 0x76, 0x00, 0x00, /* R20 - R27 */
146 0x04, 0x00, 0x00, 0x30, 0x2A, 0x00, 0x40, 0x00, /* R28 - R2F */
147 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, /* R30 - R37 */
148 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, /* R38 - R3F */
149 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R40 - R4F */
150 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R48 - R4F */
151 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R50 - R57 */
152 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R58 - R5F */
153 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R60 - R67 */
154 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R68 - R6F */
155 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R70 - R77 */
156 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0x00, /* R78 - R7F */
157 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, /* R80 - R87 */
158 0x00, /* R88 */
159};
160
161/*
162 * Read da7210 register cache
163 */
164static inline u32 da7210_read_reg_cache(struct snd_soc_codec *codec, u32 reg)
165{
166 u8 *cache = codec->reg_cache;
167 BUG_ON(reg > ARRAY_SIZE(da7210_reg));
168 return cache[reg];
169}
170
171/*
172 * Write to the da7210 register space
173 */
174static int da7210_write(struct snd_soc_codec *codec, u32 reg, u32 value)
175{
176 u8 *cache = codec->reg_cache;
177 u8 data[2];
178
179 BUG_ON(codec->volatile_register);
180
181 data[0] = reg & 0xff;
182 data[1] = value & 0xff;
183
184 if (reg >= codec->reg_cache_size)
185 return -EIO;
186
187 if (2 != codec->hw_write(codec->control_data, data, 2))
188 return -EIO;
189
190 cache[reg] = value;
191 return 0;
192}
193
194/*
195 * Read from the da7210 register space.
196 */
197static inline u32 da7210_read(struct snd_soc_codec *codec, u32 reg)
198{
199 if (DA7210_STATUS == reg)
200 return i2c_smbus_read_byte_data(codec->control_data, reg);
201
202 return da7210_read_reg_cache(codec, reg);
203}
204
205static int da7210_startup(struct snd_pcm_substream *substream,
206 struct snd_soc_dai *dai)
207{
208 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
209 struct snd_soc_codec *codec = dai->codec;
210
211 if (is_play) {
212 /* PlayBack Volume 40 */
213 snd_soc_update_bits(codec, DA7210_HP_L_VOL, 0x3F, 40);
214 snd_soc_update_bits(codec, DA7210_HP_R_VOL, 0x3F, 40);
215
216 /* Enable Out */
217 snd_soc_update_bits(codec, DA7210_OUTMIX_L, 0x1F, 0x10);
218 snd_soc_update_bits(codec, DA7210_OUTMIX_R, 0x1F, 0x10);
219
220 } else {
221 /* Volume 7 */
222 snd_soc_update_bits(codec, DA7210_MIC_L, 0x7, 0x7);
223 snd_soc_update_bits(codec, DA7210_MIC_R, 0x7, 0x7);
224
225 /* Enable Mic */
226 snd_soc_update_bits(codec, DA7210_INMIX_L, 0x1F, 0x1);
227 snd_soc_update_bits(codec, DA7210_INMIX_R, 0x1F, 0x1);
228 }
229
230 return 0;
231}
232
233/*
234 * Set PCM DAI word length.
235 */
236static int da7210_hw_params(struct snd_pcm_substream *substream,
237 struct snd_pcm_hw_params *params,
238 struct snd_soc_dai *dai)
239{
240 struct snd_soc_pcm_runtime *rtd = substream->private_data;
241 struct snd_soc_device *socdev = rtd->socdev;
242 struct snd_soc_codec *codec = socdev->card->codec;
243 u32 dai_cfg1;
244 u32 reg, mask;
245
246 /* set DAI source to Left and Right ADC */
247 da7210_write(codec, DA7210_DAI_SRC_SEL,
248 DA7210_DAI_OUT_R_SRC | DA7210_DAI_OUT_L_SRC);
249
250 /* Enable DAI */
251 da7210_write(codec, DA7210_DAI_CFG3, DA7210_DAI_OE | DA7210_DAI_EN);
252
253 dai_cfg1 = 0xFC & da7210_read(codec, DA7210_DAI_CFG1);
254
255 switch (params_format(params)) {
256 case SNDRV_PCM_FORMAT_S16_LE:
257 dai_cfg1 |= DA7210_DAI_WORD_S16_LE;
258 break;
259 case SNDRV_PCM_FORMAT_S24_LE:
260 dai_cfg1 |= DA7210_DAI_WORD_S24_LE;
261 break;
262 default:
263 return -EINVAL;
264 }
265
266 da7210_write(codec, DA7210_DAI_CFG1, dai_cfg1);
267
268 /* FIXME
269 *
270 * It support 48K only now
271 */
272 switch (params_rate(params)) {
273 case 48000:
274 if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) {
275 reg = DA7210_DAC_HPF;
276 mask = DA7210_DAC_VOICE_EN;
277 } else {
278 reg = DA7210_ADC_HPF;
279 mask = DA7210_ADC_VOICE_EN;
280 }
281 break;
282 default:
283 return -EINVAL;
284 }
285
286 snd_soc_update_bits(codec, reg, mask, 0);
287
288 return 0;
289}
290
291/*
292 * Set DAI mode and Format
293 */
294static int da7210_set_dai_fmt(struct snd_soc_dai *codec_dai, u32 fmt)
295{
296 struct snd_soc_codec *codec = codec_dai->codec;
297 u32 dai_cfg1;
298 u32 dai_cfg3;
299
300 dai_cfg1 = 0x7f & da7210_read(codec, DA7210_DAI_CFG1);
301 dai_cfg3 = 0xfc & da7210_read(codec, DA7210_DAI_CFG3);
302
303 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
304 case SND_SOC_DAIFMT_CBM_CFM:
305 dai_cfg1 |= DA7210_DAI_MODE_MASTER;
306 break;
307 default:
308 return -EINVAL;
309 }
310
311 /* FIXME
312 *
313 * It support I2S only now
314 */
315 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
316 case SND_SOC_DAIFMT_I2S:
317 dai_cfg3 |= DA7210_DAI_FORMAT_I2SMODE;
318 break;
319 default:
320 return -EINVAL;
321 }
322
323 /* FIXME
324 *
325 * It support 64bit data transmission only now
326 */
327 dai_cfg1 |= DA7210_DAI_FLEN_64BIT;
328
329 da7210_write(codec, DA7210_DAI_CFG1, dai_cfg1);
330 da7210_write(codec, DA7210_DAI_CFG3, dai_cfg3);
331
332 return 0;
333}
334
335#define DA7210_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE)
336
337/* DAI operations */
338static struct snd_soc_dai_ops da7210_dai_ops = {
339 .startup = da7210_startup,
340 .hw_params = da7210_hw_params,
341 .set_fmt = da7210_set_dai_fmt,
342};
343
344struct snd_soc_dai da7210_dai = {
345 .name = "DA7210 IIS",
346 .id = 0,
347 /* playback capabilities */
348 .playback = {
349 .stream_name = "Playback",
350 .channels_min = 1,
351 .channels_max = 2,
352 .rates = SNDRV_PCM_RATE_8000_96000,
353 .formats = DA7210_FORMATS,
354 },
355 /* capture capabilities */
356 .capture = {
357 .stream_name = "Capture",
358 .channels_min = 1,
359 .channels_max = 2,
360 .rates = SNDRV_PCM_RATE_8000_96000,
361 .formats = DA7210_FORMATS,
362 },
363 .ops = &da7210_dai_ops,
364};
365EXPORT_SYMBOL_GPL(da7210_dai);
366
367/*
368 * Initialize the DA7210 driver
369 * register the mixer and dsp interfaces with the kernel
370 */
371static int da7210_init(struct da7210_priv *da7210)
372{
373 struct snd_soc_codec *codec = &da7210->codec;
374 int ret = 0;
375
376 if (da7210_codec) {
377 dev_err(codec->dev, "Another da7210 is registered\n");
378 return -EINVAL;
379 }
380
381 mutex_init(&codec->mutex);
382 INIT_LIST_HEAD(&codec->dapm_widgets);
383 INIT_LIST_HEAD(&codec->dapm_paths);
384
385 codec->private_data = da7210;
386 codec->name = "DA7210";
387 codec->owner = THIS_MODULE;
388 codec->read = da7210_read;
389 codec->write = da7210_write;
390 codec->dai = &da7210_dai;
391 codec->num_dai = 1;
392 codec->hw_write = (hw_write_t)i2c_master_send;
393 codec->reg_cache_size = ARRAY_SIZE(da7210_reg);
394 codec->reg_cache = kmemdup(da7210_reg,
395 sizeof(da7210_reg), GFP_KERNEL);
396
397 if (!codec->reg_cache)
398 return -ENOMEM;
399
400 da7210_dai.dev = codec->dev;
401 da7210_codec = codec;
402
403 ret = snd_soc_register_codec(codec);
404 if (ret) {
405 dev_err(codec->dev, "Failed to register CODEC: %d\n", ret);
406 goto init_err;
407 }
408
409 ret = snd_soc_register_dai(&da7210_dai);
410 if (ret) {
411 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
412 goto init_err;
413 }
414
415 /* FIXME
416 *
417 * This driver use fixed value here
418 */
419
420 /*
421 * ADC settings
422 */
423
424 /* Enable Left & Right MIC PGA and Mic Bias */
425 da7210_write(codec, DA7210_MIC_L, DA7210_MIC_L_EN | DA7210_MICBIAS_EN);
426 da7210_write(codec, DA7210_MIC_R, DA7210_MIC_R_EN);
427
428 /* Enable Left and Right input PGA */
429 da7210_write(codec, DA7210_INMIX_L, DA7210_IN_L_EN);
430 da7210_write(codec, DA7210_INMIX_R, DA7210_IN_R_EN);
431
432 /* Enable Left and Right ADC */
433 da7210_write(codec, DA7210_ADC, DA7210_ADC_L_EN | DA7210_ADC_R_EN);
434
435 /*
436 * DAC settings
437 */
438
439 /* Enable Left and Right DAC */
440 da7210_write(codec, DA7210_DAC_SEL,
441 DA7210_DAC_L_SRC_DAI_L | DA7210_DAC_L_EN |
442 DA7210_DAC_R_SRC_DAI_R | DA7210_DAC_R_EN);
443
444 /* Enable Left and Right out PGA */
445 da7210_write(codec, DA7210_OUTMIX_L, DA7210_OUT_L_EN);
446 da7210_write(codec, DA7210_OUTMIX_R, DA7210_OUT_R_EN);
447
448 /* Enable Left and Right HeadPhone PGA */
449 da7210_write(codec, DA7210_HP_CFG,
450 DA7210_HP_2CAP_MODE | DA7210_HP_SENSE_EN |
451 DA7210_HP_L_EN | DA7210_HP_MODE | DA7210_HP_R_EN);
452
453 /* Diable PLL and bypass it */
454 da7210_write(codec, DA7210_PLL, DA7210_PLL_FS_48000);
455
456 /* Bypass PLL and set MCLK freq rang to 10-20MHz */
457 da7210_write(codec, DA7210_PLL_DIV3,
458 DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP);
459
460 /* Activate all enabled subsystem */
461 da7210_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN);
462
463 return ret;
464
465init_err:
466 kfree(codec->reg_cache);
467 codec->reg_cache = NULL;
468
469 return ret;
470
471}
472
473#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
474static int __devinit da7210_i2c_probe(struct i2c_client *i2c,
475 const struct i2c_device_id *id)
476{
477 struct da7210_priv *da7210;
478 struct snd_soc_codec *codec;
479 int ret;
480
481 da7210 = kzalloc(sizeof(struct da7210_priv), GFP_KERNEL);
482 if (!da7210)
483 return -ENOMEM;
484
485 codec = &da7210->codec;
486 codec->dev = &i2c->dev;
487
488 i2c_set_clientdata(i2c, da7210);
489 codec->control_data = i2c;
490
491 ret = da7210_init(da7210);
492 if (ret < 0)
493 pr_err("Failed to initialise da7210 audio codec\n");
494
495 return ret;
496}
497
498static int __devexit da7210_i2c_remove(struct i2c_client *client)
499{
500 struct da7210_priv *da7210 = i2c_get_clientdata(client);
501
502 snd_soc_unregister_dai(&da7210_dai);
503 kfree(da7210->codec.reg_cache);
504 kfree(da7210);
505 da7210_codec = NULL;
506
507 return 0;
508}
509
510static const struct i2c_device_id da7210_i2c_id[] = {
511 { "da7210", 0 },
512 { }
513};
514MODULE_DEVICE_TABLE(i2c, da7210_i2c_id);
515
516/* I2C codec control layer */
517static struct i2c_driver da7210_i2c_driver = {
518 .driver = {
519 .name = "DA7210 I2C Codec",
520 .owner = THIS_MODULE,
521 },
522 .probe = da7210_i2c_probe,
523 .remove = __devexit_p(da7210_i2c_remove),
524 .id_table = da7210_i2c_id,
525};
526#endif
527
528static int da7210_probe(struct platform_device *pdev)
529{
530 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
531 struct snd_soc_codec *codec;
532 int ret;
533
534 if (!da7210_codec) {
535 dev_err(&pdev->dev, "Codec device not registered\n");
536 return -ENODEV;
537 }
538
539 socdev->card->codec = da7210_codec;
540 codec = da7210_codec;
541
542 /* Register pcms */
543 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
544 if (ret < 0)
545 goto pcm_err;
546
547 dev_info(&pdev->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION);
548
549pcm_err:
550 return ret;
551}
552
553static int da7210_remove(struct platform_device *pdev)
554{
555 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
556
557 snd_soc_free_pcms(socdev);
558 snd_soc_dapm_free(socdev);
559
560 return 0;
561}
562
563struct snd_soc_codec_device soc_codec_dev_da7210 = {
564 .probe = da7210_probe,
565 .remove = da7210_remove,
566};
567EXPORT_SYMBOL_GPL(soc_codec_dev_da7210);
568
569static int __init da7210_modinit(void)
570{
571 int ret = 0;
572#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
573 ret = i2c_add_driver(&da7210_i2c_driver);
574#endif
575 return ret;
576}
577module_init(da7210_modinit);
578
579static void __exit da7210_exit(void)
580{
581#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
582 i2c_del_driver(&da7210_i2c_driver);
583#endif
584}
585module_exit(da7210_exit);
586
587MODULE_DESCRIPTION("ASoC DA7210 driver");
588MODULE_AUTHOR("David Chen, Kuninori Morimoto");
589MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/da7210.h b/sound/soc/codecs/da7210.h
new file mode 100644
index 000000000000..390d621eb742
--- /dev/null
+++ b/sound/soc/codecs/da7210.h
@@ -0,0 +1,24 @@
1/*
2 * da7210.h -- audio driver for da7210
3 *
4 * Copyright (c) 2009 Dialog Semiconductor
5 * Written by David Chen <Dajun.chen@diasemi.com>
6 *
7 * Copyright (C) 2009 Renesas Solutions Corp.
8 * Cleanups by Kuninori Morimoto <morimoto.kuninori@renesas.com>
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
17#ifndef _DA7210_H
18#define _DA7210_H
19
20extern struct snd_soc_dai da7210_dai;
21extern struct snd_soc_codec_device soc_codec_dev_da7210;
22
23#endif
24
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 2b4dc2b0b017..e4b946a19ea3 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -765,9 +765,10 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
765 struct snd_soc_codec *codec = socdev->card->codec; 765 struct snd_soc_codec *codec = socdev->card->codec;
766 struct aic3x_priv *aic3x = codec->private_data; 766 struct aic3x_priv *aic3x = codec->private_data;
767 int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0; 767 int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0;
768 u8 data, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1; 768 u8 data, j, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1;
769 u16 pll_d = 1; 769 u16 d, pll_d = 1;
770 u8 reg; 770 u8 reg;
771 int clk;
771 772
772 /* select data word length */ 773 /* select data word length */
773 data = 774 data =
@@ -833,48 +834,70 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
833 if (bypass_pll) 834 if (bypass_pll)
834 return 0; 835 return 0;
835 836
836 /* Use PLL 837 /* Use PLL, compute apropriate setup for j, d, r and p, the closest
837 * find an apropriate setup for j, d, r and p by iterating over 838 * one wins the game. Try with d==0 first, next with d!=0.
838 * p and r - j and d are calculated for each fraction. 839 * Constraints for j are according to the datasheet.
839 * Up to 128 values are probed, the closest one wins the game.
840 * The sysclk is divided by 1000 to prevent integer overflows. 840 * The sysclk is divided by 1000 to prevent integer overflows.
841 */ 841 */
842
842 codec_clk = (2048 * fsref) / (aic3x->sysclk / 1000); 843 codec_clk = (2048 * fsref) / (aic3x->sysclk / 1000);
843 844
844 for (r = 1; r <= 16; r++) 845 for (r = 1; r <= 16; r++)
845 for (p = 1; p <= 8; p++) { 846 for (p = 1; p <= 8; p++) {
846 int clk, tmp = (codec_clk * pll_r * 10) / pll_p; 847 for (j = 4; j <= 55; j++) {
847 u8 j = tmp / 10000; 848 /* This is actually 1000*((j+(d/10000))*r)/p
848 u16 d = tmp % 10000; 849 * The term had to be converted to get
850 * rid of the division by 10000; d = 0 here
851 */
852 int tmp_clk = (1000 * j * r) / p;
853
854 /* Check whether this values get closer than
855 * the best ones we had before
856 */
857 if (abs(codec_clk - tmp_clk) <
858 abs(codec_clk - last_clk)) {
859 pll_j = j; pll_d = 0;
860 pll_r = r; pll_p = p;
861 last_clk = tmp_clk;
862 }
863
864 /* Early exit for exact matches */
865 if (tmp_clk == codec_clk)
866 goto found;
867 }
868 }
849 869
850 if (j > 63) 870 /* try with d != 0 */
851 continue; 871 for (p = 1; p <= 8; p++) {
872 j = codec_clk * p / 1000;
852 873
853 if (d != 0 && aic3x->sysclk < 10000000) 874 if (j < 4 || j > 11)
854 continue; 875 continue;
855 876
856 /* This is actually 1000 * ((j + (d/10000)) * r) / p 877 /* do not use codec_clk here since we'd loose precision */
857 * The term had to be converted to get rid of the 878 d = ((2048 * p * fsref) - j * aic3x->sysclk)
858 * division by 10000 */ 879 * 100 / (aic3x->sysclk/100);
859 clk = ((10000 * j * r) + (d * r)) / (10 * p);
860 880
861 /* check whether this values get closer than the best 881 clk = (10000 * j + d) / (10 * p);
862 * ones we had before */
863 if (abs(codec_clk - clk) < abs(codec_clk - last_clk)) {
864 pll_j = j; pll_d = d; pll_r = r; pll_p = p;
865 last_clk = clk;
866 }
867 882
868 /* Early exit for exact matches */ 883 /* check whether this values get closer than the best
869 if (clk == codec_clk) 884 * ones we had before */
870 break; 885 if (abs(codec_clk - clk) < abs(codec_clk - last_clk)) {
886 pll_j = j; pll_d = d; pll_r = 1; pll_p = p;
887 last_clk = clk;
871 } 888 }
872 889
890 /* Early exit for exact matches */
891 if (clk == codec_clk)
892 goto found;
893 }
894
873 if (last_clk == 0) { 895 if (last_clk == 0) {
874 printk(KERN_ERR "%s(): unable to setup PLL\n", __func__); 896 printk(KERN_ERR "%s(): unable to setup PLL\n", __func__);
875 return -EINVAL; 897 return -EINVAL;
876 } 898 }
877 899
900found:
878 data = aic3x_read_reg_cache(codec, AIC3X_PLL_PROGA_REG); 901 data = aic3x_read_reg_cache(codec, AIC3X_PLL_PROGA_REG);
879 aic3x_write(codec, AIC3X_PLL_PROGA_REG, data | (pll_p << PLLP_SHIFT)); 902 aic3x_write(codec, AIC3X_PLL_PROGA_REG, data | (pll_p << PLLP_SHIFT));
880 aic3x_write(codec, AIC3X_OVRF_STATUS_AND_PLLR_REG, pll_r << PLLR_SHIFT); 903 aic3x_write(codec, AIC3X_OVRF_STATUS_AND_PLLR_REG, pll_r << PLLR_SHIFT);
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
index 9c8903dbe647..f9f367d29a90 100644
--- a/sound/soc/codecs/tlv320dac33.c
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -30,6 +30,7 @@
30#include <linux/platform_device.h> 30#include <linux/platform_device.h>
31#include <linux/interrupt.h> 31#include <linux/interrupt.h>
32#include <linux/gpio.h> 32#include <linux/gpio.h>
33#include <linux/regulator/consumer.h>
33#include <sound/core.h> 34#include <sound/core.h>
34#include <sound/pcm.h> 35#include <sound/pcm.h>
35#include <sound/pcm_params.h> 36#include <sound/pcm_params.h>
@@ -58,11 +59,26 @@ enum dac33_state {
58 DAC33_FLUSH, 59 DAC33_FLUSH,
59}; 60};
60 61
62enum dac33_fifo_modes {
63 DAC33_FIFO_BYPASS = 0,
64 DAC33_FIFO_MODE1,
65 DAC33_FIFO_MODE7,
66 DAC33_FIFO_LAST_MODE,
67};
68
69#define DAC33_NUM_SUPPLIES 3
70static const char *dac33_supply_names[DAC33_NUM_SUPPLIES] = {
71 "AVDD",
72 "DVDD",
73 "IOVDD",
74};
75
61struct tlv320dac33_priv { 76struct tlv320dac33_priv {
62 struct mutex mutex; 77 struct mutex mutex;
63 struct workqueue_struct *dac33_wq; 78 struct workqueue_struct *dac33_wq;
64 struct work_struct work; 79 struct work_struct work;
65 struct snd_soc_codec codec; 80 struct snd_soc_codec codec;
81 struct regulator_bulk_data supplies[DAC33_NUM_SUPPLIES];
66 int power_gpio; 82 int power_gpio;
67 int chip_power; 83 int chip_power;
68 int irq; 84 int irq;
@@ -73,8 +89,9 @@ struct tlv320dac33_priv {
73 * this */ 89 * this */
74 unsigned int nsample_max; /* nsample should not be higher than 90 unsigned int nsample_max; /* nsample should not be higher than
75 * this */ 91 * this */
76 unsigned int nsample_switch; /* Use FIFO or bypass FIFO switch */ 92 enum dac33_fifo_modes fifo_mode;/* FIFO mode selection */
77 unsigned int nsample; /* burst read amount from host */ 93 unsigned int nsample; /* burst read amount from host */
94 u8 burst_bclkdiv; /* BCLK divider value in burst mode */
78 95
79 enum dac33_state state; 96 enum dac33_state state;
80}; 97};
@@ -297,28 +314,49 @@ static inline void dac33_soft_power(struct snd_soc_codec *codec, int power)
297 dac33_write(codec, DAC33_PWR_CTRL, reg); 314 dac33_write(codec, DAC33_PWR_CTRL, reg);
298} 315}
299 316
300static void dac33_hard_power(struct snd_soc_codec *codec, int power) 317static int dac33_hard_power(struct snd_soc_codec *codec, int power)
301{ 318{
302 struct tlv320dac33_priv *dac33 = codec->private_data; 319 struct tlv320dac33_priv *dac33 = codec->private_data;
320 int ret;
303 321
304 mutex_lock(&dac33->mutex); 322 mutex_lock(&dac33->mutex);
305 if (power) { 323 if (power) {
306 if (dac33->power_gpio >= 0) { 324 ret = regulator_bulk_enable(ARRAY_SIZE(dac33->supplies),
307 gpio_set_value(dac33->power_gpio, 1); 325 dac33->supplies);
308 dac33->chip_power = 1; 326 if (ret != 0) {
309 /* Restore registers */ 327 dev_err(codec->dev,
310 dac33_restore_regs(codec); 328 "Failed to enable supplies: %d\n", ret);
329 goto exit;
311 } 330 }
331
332 if (dac33->power_gpio >= 0)
333 gpio_set_value(dac33->power_gpio, 1);
334
335 dac33->chip_power = 1;
336
337 /* Restore registers */
338 dac33_restore_regs(codec);
339
312 dac33_soft_power(codec, 1); 340 dac33_soft_power(codec, 1);
313 } else { 341 } else {
314 dac33_soft_power(codec, 0); 342 dac33_soft_power(codec, 0);
315 if (dac33->power_gpio >= 0) { 343 if (dac33->power_gpio >= 0)
316 gpio_set_value(dac33->power_gpio, 0); 344 gpio_set_value(dac33->power_gpio, 0);
317 dac33->chip_power = 0; 345
346 ret = regulator_bulk_disable(ARRAY_SIZE(dac33->supplies),
347 dac33->supplies);
348 if (ret != 0) {
349 dev_err(codec->dev,
350 "Failed to disable supplies: %d\n", ret);
351 goto exit;
318 } 352 }
353
354 dac33->chip_power = 0;
319 } 355 }
320 mutex_unlock(&dac33->mutex);
321 356
357exit:
358 mutex_unlock(&dac33->mutex);
359 return ret;
322} 360}
323 361
324static int dac33_get_nsample(struct snd_kcontrol *kcontrol, 362static int dac33_get_nsample(struct snd_kcontrol *kcontrol,
@@ -351,39 +389,48 @@ static int dac33_set_nsample(struct snd_kcontrol *kcontrol,
351 return ret; 389 return ret;
352} 390}
353 391
354static int dac33_get_nsample_switch(struct snd_kcontrol *kcontrol, 392static int dac33_get_fifo_mode(struct snd_kcontrol *kcontrol,
355 struct snd_ctl_elem_value *ucontrol) 393 struct snd_ctl_elem_value *ucontrol)
356{ 394{
357 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 395 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
358 struct tlv320dac33_priv *dac33 = codec->private_data; 396 struct tlv320dac33_priv *dac33 = codec->private_data;
359 397
360 ucontrol->value.integer.value[0] = dac33->nsample_switch; 398 ucontrol->value.integer.value[0] = dac33->fifo_mode;
361 399
362 return 0; 400 return 0;
363} 401}
364 402
365static int dac33_set_nsample_switch(struct snd_kcontrol *kcontrol, 403static int dac33_set_fifo_mode(struct snd_kcontrol *kcontrol,
366 struct snd_ctl_elem_value *ucontrol) 404 struct snd_ctl_elem_value *ucontrol)
367{ 405{
368 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 406 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
369 struct tlv320dac33_priv *dac33 = codec->private_data; 407 struct tlv320dac33_priv *dac33 = codec->private_data;
370 int ret = 0; 408 int ret = 0;
371 409
372 if (dac33->nsample_switch == ucontrol->value.integer.value[0]) 410 if (dac33->fifo_mode == ucontrol->value.integer.value[0])
373 return 0; 411 return 0;
374 /* Do not allow changes while stream is running*/ 412 /* Do not allow changes while stream is running*/
375 if (codec->active) 413 if (codec->active)
376 return -EPERM; 414 return -EPERM;
377 415
378 if (ucontrol->value.integer.value[0] < 0 || 416 if (ucontrol->value.integer.value[0] < 0 ||
379 ucontrol->value.integer.value[0] > 1) 417 ucontrol->value.integer.value[0] >= DAC33_FIFO_LAST_MODE)
380 ret = -EINVAL; 418 ret = -EINVAL;
381 else 419 else
382 dac33->nsample_switch = ucontrol->value.integer.value[0]; 420 dac33->fifo_mode = ucontrol->value.integer.value[0];
383 421
384 return ret; 422 return ret;
385} 423}
386 424
425/* Codec operation modes */
426static const char *dac33_fifo_mode_texts[] = {
427 "Bypass", "Mode 1", "Mode 7"
428};
429
430static const struct soc_enum dac33_fifo_mode_enum =
431 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(dac33_fifo_mode_texts),
432 dac33_fifo_mode_texts);
433
387/* 434/*
388 * DACL/R digital volume control: 435 * DACL/R digital volume control:
389 * from 0 dB to -63.5 in 0.5 dB steps 436 * from 0 dB to -63.5 in 0.5 dB steps
@@ -406,8 +453,8 @@ static const struct snd_kcontrol_new dac33_snd_controls[] = {
406static const struct snd_kcontrol_new dac33_nsample_snd_controls[] = { 453static const struct snd_kcontrol_new dac33_nsample_snd_controls[] = {
407 SOC_SINGLE_EXT("nSample", 0, 0, 5900, 0, 454 SOC_SINGLE_EXT("nSample", 0, 0, 5900, 0,
408 dac33_get_nsample, dac33_set_nsample), 455 dac33_get_nsample, dac33_set_nsample),
409 SOC_SINGLE_EXT("nSample Switch", 0, 0, 1, 0, 456 SOC_ENUM_EXT("FIFO Mode", dac33_fifo_mode_enum,
410 dac33_get_nsample_switch, dac33_set_nsample_switch), 457 dac33_get_fifo_mode, dac33_set_fifo_mode),
411}; 458};
412 459
413/* Analog bypass */ 460/* Analog bypass */
@@ -469,6 +516,8 @@ static int dac33_add_widgets(struct snd_soc_codec *codec)
469static int dac33_set_bias_level(struct snd_soc_codec *codec, 516static int dac33_set_bias_level(struct snd_soc_codec *codec,
470 enum snd_soc_bias_level level) 517 enum snd_soc_bias_level level)
471{ 518{
519 int ret;
520
472 switch (level) { 521 switch (level) {
473 case SND_SOC_BIAS_ON: 522 case SND_SOC_BIAS_ON:
474 dac33_soft_power(codec, 1); 523 dac33_soft_power(codec, 1);
@@ -476,12 +525,19 @@ static int dac33_set_bias_level(struct snd_soc_codec *codec,
476 case SND_SOC_BIAS_PREPARE: 525 case SND_SOC_BIAS_PREPARE:
477 break; 526 break;
478 case SND_SOC_BIAS_STANDBY: 527 case SND_SOC_BIAS_STANDBY:
479 if (codec->bias_level == SND_SOC_BIAS_OFF) 528 if (codec->bias_level == SND_SOC_BIAS_OFF) {
480 dac33_hard_power(codec, 1); 529 ret = dac33_hard_power(codec, 1);
530 if (ret != 0)
531 return ret;
532 }
533
481 dac33_soft_power(codec, 0); 534 dac33_soft_power(codec, 0);
482 break; 535 break;
483 case SND_SOC_BIAS_OFF: 536 case SND_SOC_BIAS_OFF:
484 dac33_hard_power(codec, 0); 537 ret = dac33_hard_power(codec, 0);
538 if (ret != 0)
539 return ret;
540
485 break; 541 break;
486 } 542 }
487 codec->bias_level = level; 543 codec->bias_level = level;
@@ -489,6 +545,51 @@ static int dac33_set_bias_level(struct snd_soc_codec *codec,
489 return 0; 545 return 0;
490} 546}
491 547
548static inline void dac33_prefill_handler(struct tlv320dac33_priv *dac33)
549{
550 struct snd_soc_codec *codec;
551
552 codec = &dac33->codec;
553
554 switch (dac33->fifo_mode) {
555 case DAC33_FIFO_MODE1:
556 dac33_write16(codec, DAC33_NSAMPLE_MSB,
557 DAC33_THRREG(dac33->nsample));
558 dac33_write16(codec, DAC33_PREFILL_MSB,
559 DAC33_THRREG(dac33->alarm_threshold));
560 break;
561 case DAC33_FIFO_MODE7:
562 dac33_write16(codec, DAC33_PREFILL_MSB,
563 DAC33_THRREG(10));
564 break;
565 default:
566 dev_warn(codec->dev, "Unhandled FIFO mode: %d\n",
567 dac33->fifo_mode);
568 break;
569 }
570}
571
572static inline void dac33_playback_handler(struct tlv320dac33_priv *dac33)
573{
574 struct snd_soc_codec *codec;
575
576 codec = &dac33->codec;
577
578 switch (dac33->fifo_mode) {
579 case DAC33_FIFO_MODE1:
580 dac33_write16(codec, DAC33_NSAMPLE_MSB,
581 DAC33_THRREG(dac33->nsample));
582 break;
583 case DAC33_FIFO_MODE7:
584 /* At the moment we are not using interrupts in mode7 */
585 break;
586 default:
587 dev_warn(codec->dev, "Unhandled FIFO mode: %d\n",
588 dac33->fifo_mode);
589 break;
590 }
591}
592
492static void dac33_work(struct work_struct *work) 593static void dac33_work(struct work_struct *work)
493{ 594{
494 struct snd_soc_codec *codec; 595 struct snd_soc_codec *codec;
@@ -502,14 +603,10 @@ static void dac33_work(struct work_struct *work)
502 switch (dac33->state) { 603 switch (dac33->state) {
503 case DAC33_PREFILL: 604 case DAC33_PREFILL:
504 dac33->state = DAC33_PLAYBACK; 605 dac33->state = DAC33_PLAYBACK;
505 dac33_write16(codec, DAC33_NSAMPLE_MSB, 606 dac33_prefill_handler(dac33);
506 DAC33_THRREG(dac33->nsample));
507 dac33_write16(codec, DAC33_PREFILL_MSB,
508 DAC33_THRREG(dac33->alarm_threshold));
509 break; 607 break;
510 case DAC33_PLAYBACK: 608 case DAC33_PLAYBACK:
511 dac33_write16(codec, DAC33_NSAMPLE_MSB, 609 dac33_playback_handler(dac33);
512 DAC33_THRREG(dac33->nsample));
513 break; 610 break;
514 case DAC33_IDLE: 611 case DAC33_IDLE:
515 break; 612 break;
@@ -547,7 +644,7 @@ static void dac33_shutdown(struct snd_pcm_substream *substream,
547 unsigned int pwr_ctrl; 644 unsigned int pwr_ctrl;
548 645
549 /* Stop pending workqueue */ 646 /* Stop pending workqueue */
550 if (dac33->nsample_switch) 647 if (dac33->fifo_mode)
551 cancel_work_sync(&dac33->work); 648 cancel_work_sync(&dac33->work);
552 649
553 mutex_lock(&dac33->mutex); 650 mutex_lock(&dac33->mutex);
@@ -603,7 +700,7 @@ static int dac33_hw_params(struct snd_pcm_substream *substream,
603} 700}
604 701
605#define CALC_OSCSET(rate, refclk) ( \ 702#define CALC_OSCSET(rate, refclk) ( \
606 ((((rate * 10000) / refclk) * 4096) + 5000) / 10000) 703 ((((rate * 10000) / refclk) * 4096) + 7000) / 10000)
607#define CALC_RATIOSET(rate, refclk) ( \ 704#define CALC_RATIOSET(rate, refclk) ( \
608 ((((refclk * 100000) / rate) * 16384) + 50000) / 100000) 705 ((((refclk * 100000) / rate) * 16384) + 50000) / 100000)
609 706
@@ -619,7 +716,7 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
619 struct snd_soc_codec *codec = socdev->card->codec; 716 struct snd_soc_codec *codec = socdev->card->codec;
620 struct tlv320dac33_priv *dac33 = codec->private_data; 717 struct tlv320dac33_priv *dac33 = codec->private_data;
621 unsigned int oscset, ratioset, pwr_ctrl, reg_tmp; 718 unsigned int oscset, ratioset, pwr_ctrl, reg_tmp;
622 u8 aictrl_a, fifoctrl_a; 719 u8 aictrl_a, aictrl_b, fifoctrl_a;
623 720
624 switch (substream->runtime->rate) { 721 switch (substream->runtime->rate) {
625 case 44100: 722 case 44100:
@@ -637,7 +734,10 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
637 734
638 aictrl_a = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_A); 735 aictrl_a = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_A);
639 aictrl_a &= ~(DAC33_NCYCL_MASK | DAC33_WLEN_MASK); 736 aictrl_a &= ~(DAC33_NCYCL_MASK | DAC33_WLEN_MASK);
737 /* Read FIFO control A, and clear FIFO flush bit */
640 fifoctrl_a = dac33_read_reg_cache(codec, DAC33_FIFO_CTRL_A); 738 fifoctrl_a = dac33_read_reg_cache(codec, DAC33_FIFO_CTRL_A);
739 fifoctrl_a &= ~DAC33_FIFOFLUSH;
740
641 fifoctrl_a &= ~DAC33_WIDTH; 741 fifoctrl_a &= ~DAC33_WIDTH;
642 switch (substream->runtime->format) { 742 switch (substream->runtime->format) {
643 case SNDRV_PCM_FORMAT_S16_LE: 743 case SNDRV_PCM_FORMAT_S16_LE:
@@ -675,7 +775,8 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
675 775
676 dac33_oscwait(codec); 776 dac33_oscwait(codec);
677 777
678 if (dac33->nsample_switch) { 778 if (dac33->fifo_mode) {
779 /* Generic for all FIFO modes */
679 /* 50-51 : ASRC Control registers */ 780 /* 50-51 : ASRC Control registers */
680 dac33_write(codec, DAC33_ASRC_CTRL_A, (1 << 4)); /* div=2 */ 781 dac33_write(codec, DAC33_ASRC_CTRL_A, (1 << 4)); /* div=2 */
681 dac33_write(codec, DAC33_ASRC_CTRL_B, 1); /* ??? */ 782 dac33_write(codec, DAC33_ASRC_CTRL_B, 1); /* ??? */
@@ -685,38 +786,101 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
685 786
686 /* Set interrupts to high active */ 787 /* Set interrupts to high active */
687 dac33_write(codec, DAC33_INTP_CTRL_A, DAC33_INTPM_AHIGH); 788 dac33_write(codec, DAC33_INTP_CTRL_A, DAC33_INTPM_AHIGH);
688
689 dac33_write(codec, DAC33_FIFO_IRQ_MODE_B,
690 DAC33_ATM(DAC33_FIFO_IRQ_MODE_LEVEL));
691 dac33_write(codec, DAC33_FIFO_IRQ_MASK, DAC33_MAT);
692 } else { 789 } else {
790 /* FIFO bypass mode */
693 /* 50-51 : ASRC Control registers */ 791 /* 50-51 : ASRC Control registers */
694 dac33_write(codec, DAC33_ASRC_CTRL_A, DAC33_SRCBYP); 792 dac33_write(codec, DAC33_ASRC_CTRL_A, DAC33_SRCBYP);
695 dac33_write(codec, DAC33_ASRC_CTRL_B, 0); /* ??? */ 793 dac33_write(codec, DAC33_ASRC_CTRL_B, 0); /* ??? */
696 } 794 }
697 795
698 if (dac33->nsample_switch) 796 /* Interrupt behaviour configuration */
797 switch (dac33->fifo_mode) {
798 case DAC33_FIFO_MODE1:
799 dac33_write(codec, DAC33_FIFO_IRQ_MODE_B,
800 DAC33_ATM(DAC33_FIFO_IRQ_MODE_LEVEL));
801 dac33_write(codec, DAC33_FIFO_IRQ_MASK, DAC33_MAT);
802 break;
803 case DAC33_FIFO_MODE7:
804 /* Disable all interrupts */
805 dac33_write(codec, DAC33_FIFO_IRQ_MASK, 0);
806 break;
807 default:
808 /* in FIFO bypass mode, the interrupts are not used */
809 break;
810 }
811
812 aictrl_b = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_B);
813
814 switch (dac33->fifo_mode) {
815 case DAC33_FIFO_MODE1:
816 /*
817 * For mode1:
818 * Disable the FIFO bypass (Enable the use of FIFO)
819 * Select nSample mode
820 * BCLK is only running when data is needed by DAC33
821 */
699 fifoctrl_a &= ~DAC33_FBYPAS; 822 fifoctrl_a &= ~DAC33_FBYPAS;
700 else 823 fifoctrl_a &= ~DAC33_FAUTO;
824 aictrl_b &= ~DAC33_BCLKON;
825 break;
826 case DAC33_FIFO_MODE7:
827 /*
828 * For mode1:
829 * Disable the FIFO bypass (Enable the use of FIFO)
830 * Select Threshold mode
831 * BCLK is only running when data is needed by DAC33
832 */
833 fifoctrl_a &= ~DAC33_FBYPAS;
834 fifoctrl_a |= DAC33_FAUTO;
835 aictrl_b &= ~DAC33_BCLKON;
836 break;
837 default:
838 /*
839 * For FIFO bypass mode:
840 * Enable the FIFO bypass (Disable the FIFO use)
841 * Set the BCLK as continous
842 */
701 fifoctrl_a |= DAC33_FBYPAS; 843 fifoctrl_a |= DAC33_FBYPAS;
702 dac33_write(codec, DAC33_FIFO_CTRL_A, fifoctrl_a); 844 aictrl_b |= DAC33_BCLKON;
845 break;
846 }
703 847
848 dac33_write(codec, DAC33_FIFO_CTRL_A, fifoctrl_a);
704 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_A, aictrl_a); 849 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_A, aictrl_a);
705 reg_tmp = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_B); 850 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_B, aictrl_b);
706 if (dac33->nsample_switch)
707 reg_tmp &= ~DAC33_BCLKON;
708 else
709 reg_tmp |= DAC33_BCLKON;
710 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_B, reg_tmp);
711 851
712 if (dac33->nsample_switch) { 852 /*
713 /* 20: BCLK divide ratio */ 853 * BCLK divide ratio
714 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C, 3); 854 * 0: 1.5
855 * 1: 1
856 * 2: 2
857 * ...
858 * 254: 254
859 * 255: 255
860 */
861 if (dac33->fifo_mode)
862 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C,
863 dac33->burst_bclkdiv);
864 else
865 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C, 32);
715 866
867 switch (dac33->fifo_mode) {
868 case DAC33_FIFO_MODE1:
716 dac33_write16(codec, DAC33_ATHR_MSB, 869 dac33_write16(codec, DAC33_ATHR_MSB,
717 DAC33_THRREG(dac33->alarm_threshold)); 870 DAC33_THRREG(dac33->alarm_threshold));
718 } else { 871 break;
719 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C, 32); 872 case DAC33_FIFO_MODE7:
873 /*
874 * Configure the threshold levels, and leave 10 sample space
875 * at the bottom, and also at the top of the FIFO
876 */
877 dac33_write16(codec, DAC33_UTHR_MSB,
878 DAC33_THRREG(DAC33_BUFFER_SIZE_SAMPLES - 10));
879 dac33_write16(codec, DAC33_LTHR_MSB,
880 DAC33_THRREG(10));
881 break;
882 default:
883 break;
720 } 884 }
721 885
722 mutex_unlock(&dac33->mutex); 886 mutex_unlock(&dac33->mutex);
@@ -789,7 +953,7 @@ static int dac33_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
789 case SNDRV_PCM_TRIGGER_START: 953 case SNDRV_PCM_TRIGGER_START:
790 case SNDRV_PCM_TRIGGER_RESUME: 954 case SNDRV_PCM_TRIGGER_RESUME:
791 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 955 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
792 if (dac33->nsample_switch) { 956 if (dac33->fifo_mode) {
793 dac33->state = DAC33_PREFILL; 957 dac33->state = DAC33_PREFILL;
794 queue_work(dac33->dac33_wq, &dac33->work); 958 queue_work(dac33->dac33_wq, &dac33->work);
795 } 959 }
@@ -797,7 +961,7 @@ static int dac33_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
797 case SNDRV_PCM_TRIGGER_STOP: 961 case SNDRV_PCM_TRIGGER_STOP:
798 case SNDRV_PCM_TRIGGER_SUSPEND: 962 case SNDRV_PCM_TRIGGER_SUSPEND:
799 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 963 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
800 if (dac33->nsample_switch) { 964 if (dac33->fifo_mode) {
801 dac33->state = DAC33_FLUSH; 965 dac33->state = DAC33_FLUSH;
802 queue_work(dac33->dac33_wq, &dac33->work); 966 queue_work(dac33->dac33_wq, &dac33->work);
803 } 967 }
@@ -843,6 +1007,7 @@ static int dac33_set_dai_fmt(struct snd_soc_dai *codec_dai,
843 unsigned int fmt) 1007 unsigned int fmt)
844{ 1008{
845 struct snd_soc_codec *codec = codec_dai->codec; 1009 struct snd_soc_codec *codec = codec_dai->codec;
1010 struct tlv320dac33_priv *dac33 = codec->private_data;
846 u8 aictrl_a, aictrl_b; 1011 u8 aictrl_a, aictrl_b;
847 1012
848 aictrl_a = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_A); 1013 aictrl_a = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_A);
@@ -855,7 +1020,11 @@ static int dac33_set_dai_fmt(struct snd_soc_dai *codec_dai,
855 break; 1020 break;
856 case SND_SOC_DAIFMT_CBS_CFS: 1021 case SND_SOC_DAIFMT_CBS_CFS:
857 /* Codec Slave */ 1022 /* Codec Slave */
858 aictrl_a &= ~(DAC33_MSBCLK | DAC33_MSWCLK); 1023 if (dac33->fifo_mode) {
1024 dev_err(codec->dev, "FIFO mode requires master mode\n");
1025 return -EINVAL;
1026 } else
1027 aictrl_a &= ~(DAC33_MSBCLK | DAC33_MSWCLK);
859 break; 1028 break;
860 default: 1029 default:
861 return -EINVAL; 1030 return -EINVAL;
@@ -959,6 +1128,9 @@ static int dac33_soc_probe(struct platform_device *pdev)
959 /* power on device */ 1128 /* power on device */
960 dac33_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1129 dac33_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
961 1130
1131 /* Bias level configuration has enabled regulator an extra time */
1132 regulator_bulk_disable(ARRAY_SIZE(dac33->supplies), dac33->supplies);
1133
962 return 0; 1134 return 0;
963 1135
964pcm_err: 1136pcm_err:
@@ -1033,13 +1205,13 @@ struct snd_soc_dai dac33_dai = {
1033}; 1205};
1034EXPORT_SYMBOL_GPL(dac33_dai); 1206EXPORT_SYMBOL_GPL(dac33_dai);
1035 1207
1036static int dac33_i2c_probe(struct i2c_client *client, 1208static int __devinit dac33_i2c_probe(struct i2c_client *client,
1037 const struct i2c_device_id *id) 1209 const struct i2c_device_id *id)
1038{ 1210{
1039 struct tlv320dac33_platform_data *pdata; 1211 struct tlv320dac33_platform_data *pdata;
1040 struct tlv320dac33_priv *dac33; 1212 struct tlv320dac33_priv *dac33;
1041 struct snd_soc_codec *codec; 1213 struct snd_soc_codec *codec;
1042 int ret = 0; 1214 int ret, i;
1043 1215
1044 if (client->dev.platform_data == NULL) { 1216 if (client->dev.platform_data == NULL) {
1045 dev_err(&client->dev, "Platform data not set\n"); 1217 dev_err(&client->dev, "Platform data not set\n");
@@ -1080,10 +1252,11 @@ static int dac33_i2c_probe(struct i2c_client *client,
1080 i2c_set_clientdata(client, dac33); 1252 i2c_set_clientdata(client, dac33);
1081 1253
1082 dac33->power_gpio = pdata->power_gpio; 1254 dac33->power_gpio = pdata->power_gpio;
1255 dac33->burst_bclkdiv = pdata->burst_bclkdiv;
1083 dac33->irq = client->irq; 1256 dac33->irq = client->irq;
1084 dac33->nsample = NSAMPLE_MAX; 1257 dac33->nsample = NSAMPLE_MAX;
1085 /* Disable FIFO use by default */ 1258 /* Disable FIFO use by default */
1086 dac33->nsample_switch = 0; 1259 dac33->fifo_mode = DAC33_FIFO_BYPASS;
1087 1260
1088 tlv320dac33_codec = codec; 1261 tlv320dac33_codec = codec;
1089 1262
@@ -1130,6 +1303,24 @@ static int dac33_i2c_probe(struct i2c_client *client,
1130 } 1303 }
1131 } 1304 }
1132 1305
1306 for (i = 0; i < ARRAY_SIZE(dac33->supplies); i++)
1307 dac33->supplies[i].supply = dac33_supply_names[i];
1308
1309 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(dac33->supplies),
1310 dac33->supplies);
1311
1312 if (ret != 0) {
1313 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
1314 goto err_get;
1315 }
1316
1317 ret = regulator_bulk_enable(ARRAY_SIZE(dac33->supplies),
1318 dac33->supplies);
1319 if (ret != 0) {
1320 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
1321 goto err_enable;
1322 }
1323
1133 ret = snd_soc_register_codec(codec); 1324 ret = snd_soc_register_codec(codec);
1134 if (ret != 0) { 1325 if (ret != 0) {
1135 dev_err(codec->dev, "Failed to register codec: %d\n", ret); 1326 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
@@ -1149,6 +1340,10 @@ static int dac33_i2c_probe(struct i2c_client *client,
1149 return ret; 1340 return ret;
1150 1341
1151error_codec: 1342error_codec:
1343 regulator_bulk_disable(ARRAY_SIZE(dac33->supplies), dac33->supplies);
1344err_enable:
1345 regulator_bulk_free(ARRAY_SIZE(dac33->supplies), dac33->supplies);
1346err_get:
1152 if (dac33->irq >= 0) { 1347 if (dac33->irq >= 0) {
1153 free_irq(dac33->irq, &dac33->codec); 1348 free_irq(dac33->irq, &dac33->codec);
1154 destroy_workqueue(dac33->dac33_wq); 1349 destroy_workqueue(dac33->dac33_wq);
@@ -1165,7 +1360,7 @@ error_reg:
1165 return ret; 1360 return ret;
1166} 1361}
1167 1362
1168static int dac33_i2c_remove(struct i2c_client *client) 1363static int __devexit dac33_i2c_remove(struct i2c_client *client)
1169{ 1364{
1170 struct tlv320dac33_priv *dac33; 1365 struct tlv320dac33_priv *dac33;
1171 1366
@@ -1177,6 +1372,8 @@ static int dac33_i2c_remove(struct i2c_client *client)
1177 if (dac33->irq >= 0) 1372 if (dac33->irq >= 0)
1178 free_irq(dac33->irq, &dac33->codec); 1373 free_irq(dac33->irq, &dac33->codec);
1179 1374
1375 regulator_bulk_free(ARRAY_SIZE(dac33->supplies), dac33->supplies);
1376
1180 destroy_workqueue(dac33->dac33_wq); 1377 destroy_workqueue(dac33->dac33_wq);
1181 snd_soc_unregister_dai(&dac33_dai); 1378 snd_soc_unregister_dai(&dac33_dai);
1182 snd_soc_unregister_codec(&dac33->codec); 1379 snd_soc_unregister_codec(&dac33->codec);
diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
index 6b650c1aa3d1..958d49c969ac 100644
--- a/sound/soc/codecs/tpa6130a2.c
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -25,6 +25,7 @@
25#include <linux/device.h> 25#include <linux/device.h>
26#include <linux/i2c.h> 26#include <linux/i2c.h>
27#include <linux/gpio.h> 27#include <linux/gpio.h>
28#include <linux/regulator/consumer.h>
28#include <sound/tpa6130a2-plat.h> 29#include <sound/tpa6130a2-plat.h>
29#include <sound/soc.h> 30#include <sound/soc.h>
30#include <sound/soc-dapm.h> 31#include <sound/soc-dapm.h>
@@ -34,10 +35,22 @@
34 35
35static struct i2c_client *tpa6130a2_client; 36static struct i2c_client *tpa6130a2_client;
36 37
38#define TPA6130A2_NUM_SUPPLIES 2
39static const char *tpa6130a2_supply_names[TPA6130A2_NUM_SUPPLIES] = {
40 "CPVSS",
41 "Vdd",
42};
43
44static const char *tpa6140a2_supply_names[TPA6130A2_NUM_SUPPLIES] = {
45 "HPVdd",
46 "AVdd",
47};
48
37/* This struct is used to save the context */ 49/* This struct is used to save the context */
38struct tpa6130a2_data { 50struct tpa6130a2_data {
39 struct mutex mutex; 51 struct mutex mutex;
40 unsigned char regs[TPA6130A2_CACHEREGNUM]; 52 unsigned char regs[TPA6130A2_CACHEREGNUM];
53 struct regulator_bulk_data supplies[TPA6130A2_NUM_SUPPLIES];
41 int power_gpio; 54 int power_gpio;
42 unsigned char power_state; 55 unsigned char power_state;
43}; 56};
@@ -106,10 +119,11 @@ static void tpa6130a2_initialize(void)
106 tpa6130a2_i2c_write(i, data->regs[i]); 119 tpa6130a2_i2c_write(i, data->regs[i]);
107} 120}
108 121
109static void tpa6130a2_power(int power) 122static int tpa6130a2_power(int power)
110{ 123{
111 struct tpa6130a2_data *data; 124 struct tpa6130a2_data *data;
112 u8 val; 125 u8 val;
126 int ret;
113 127
114 BUG_ON(tpa6130a2_client == NULL); 128 BUG_ON(tpa6130a2_client == NULL);
115 data = i2c_get_clientdata(tpa6130a2_client); 129 data = i2c_get_clientdata(tpa6130a2_client);
@@ -117,11 +131,20 @@ static void tpa6130a2_power(int power)
117 mutex_lock(&data->mutex); 131 mutex_lock(&data->mutex);
118 if (power) { 132 if (power) {
119 /* Power on */ 133 /* Power on */
120 if (data->power_gpio >= 0) { 134 if (data->power_gpio >= 0)
121 gpio_set_value(data->power_gpio, 1); 135 gpio_set_value(data->power_gpio, 1);
122 data->power_state = 1; 136
123 tpa6130a2_initialize(); 137 ret = regulator_bulk_enable(ARRAY_SIZE(data->supplies),
138 data->supplies);
139 if (ret != 0) {
140 dev_err(&tpa6130a2_client->dev,
141 "Failed to enable supplies: %d\n", ret);
142 goto exit;
124 } 143 }
144
145 data->power_state = 1;
146 tpa6130a2_initialize();
147
125 /* Clear SWS */ 148 /* Clear SWS */
126 val = tpa6130a2_read(TPA6130A2_REG_CONTROL); 149 val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
127 val &= ~TPA6130A2_SWS; 150 val &= ~TPA6130A2_SWS;
@@ -131,13 +154,25 @@ static void tpa6130a2_power(int power)
131 val = tpa6130a2_read(TPA6130A2_REG_CONTROL); 154 val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
132 val |= TPA6130A2_SWS; 155 val |= TPA6130A2_SWS;
133 tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val); 156 tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val);
157
134 /* Power off */ 158 /* Power off */
135 if (data->power_gpio >= 0) { 159 if (data->power_gpio >= 0)
136 gpio_set_value(data->power_gpio, 0); 160 gpio_set_value(data->power_gpio, 0);
137 data->power_state = 0; 161
162 ret = regulator_bulk_disable(ARRAY_SIZE(data->supplies),
163 data->supplies);
164 if (ret != 0) {
165 dev_err(&tpa6130a2_client->dev,
166 "Failed to disable supplies: %d\n", ret);
167 goto exit;
138 } 168 }
169
170 data->power_state = 0;
139 } 171 }
172
173exit:
140 mutex_unlock(&data->mutex); 174 mutex_unlock(&data->mutex);
175 return ret;
141} 176}
142 177
143static int tpa6130a2_get_reg(struct snd_kcontrol *kcontrol, 178static int tpa6130a2_get_reg(struct snd_kcontrol *kcontrol,
@@ -237,12 +272,8 @@ static const struct snd_kcontrol_new tpa6130a2_controls[] = {
237 */ 272 */
238static void tpa6130a2_channel_enable(u8 channel, int enable) 273static void tpa6130a2_channel_enable(u8 channel, int enable)
239{ 274{
240 struct tpa6130a2_data *data;
241 u8 val; 275 u8 val;
242 276
243 BUG_ON(tpa6130a2_client == NULL);
244 data = i2c_get_clientdata(tpa6130a2_client);
245
246 if (enable) { 277 if (enable) {
247 /* Enable channel */ 278 /* Enable channel */
248 /* Enable amplifier */ 279 /* Enable amplifier */
@@ -299,15 +330,17 @@ static int tpa6130a2_right_event(struct snd_soc_dapm_widget *w,
299static int tpa6130a2_supply_event(struct snd_soc_dapm_widget *w, 330static int tpa6130a2_supply_event(struct snd_soc_dapm_widget *w,
300 struct snd_kcontrol *kcontrol, int event) 331 struct snd_kcontrol *kcontrol, int event)
301{ 332{
333 int ret = 0;
334
302 switch (event) { 335 switch (event) {
303 case SND_SOC_DAPM_POST_PMU: 336 case SND_SOC_DAPM_POST_PMU:
304 tpa6130a2_power(1); 337 ret = tpa6130a2_power(1);
305 break; 338 break;
306 case SND_SOC_DAPM_POST_PMD: 339 case SND_SOC_DAPM_POST_PMD:
307 tpa6130a2_power(0); 340 ret = tpa6130a2_power(0);
308 break; 341 break;
309 } 342 }
310 return 0; 343 return ret;
311} 344}
312 345
313static const struct snd_soc_dapm_widget tpa6130a2_dapm_widgets[] = { 346static const struct snd_soc_dapm_widget tpa6130a2_dapm_widgets[] = {
@@ -346,13 +379,13 @@ int tpa6130a2_add_controls(struct snd_soc_codec *codec)
346} 379}
347EXPORT_SYMBOL_GPL(tpa6130a2_add_controls); 380EXPORT_SYMBOL_GPL(tpa6130a2_add_controls);
348 381
349static int tpa6130a2_probe(struct i2c_client *client, 382static int __devinit tpa6130a2_probe(struct i2c_client *client,
350 const struct i2c_device_id *id) 383 const struct i2c_device_id *id)
351{ 384{
352 struct device *dev; 385 struct device *dev;
353 struct tpa6130a2_data *data; 386 struct tpa6130a2_data *data;
354 struct tpa6130a2_platform_data *pdata; 387 struct tpa6130a2_platform_data *pdata;
355 int ret; 388 int i, ret;
356 389
357 dev = &client->dev; 390 dev = &client->dev;
358 391
@@ -387,15 +420,38 @@ static int tpa6130a2_probe(struct i2c_client *client,
387 if (ret < 0) { 420 if (ret < 0) {
388 dev_err(dev, "Failed to request power GPIO (%d)\n", 421 dev_err(dev, "Failed to request power GPIO (%d)\n",
389 data->power_gpio); 422 data->power_gpio);
390 goto fail; 423 goto err_gpio;
391 } 424 }
392 gpio_direction_output(data->power_gpio, 0); 425 gpio_direction_output(data->power_gpio, 0);
393 } else {
394 data->power_state = 1;
395 tpa6130a2_initialize();
396 } 426 }
397 427
398 tpa6130a2_power(1); 428 switch (pdata->id) {
429 case TPA6130A2:
430 for (i = 0; i < ARRAY_SIZE(data->supplies); i++)
431 data->supplies[i].supply = tpa6130a2_supply_names[i];
432 break;
433 case TPA6140A2:
434 for (i = 0; i < ARRAY_SIZE(data->supplies); i++)
435 data->supplies[i].supply = tpa6140a2_supply_names[i];;
436 break;
437 default:
438 dev_warn(dev, "Unknown TPA model (%d). Assuming 6130A2\n",
439 pdata->id);
440 for (i = 0; i < ARRAY_SIZE(data->supplies); i++)
441 data->supplies[i].supply = tpa6130a2_supply_names[i];
442 }
443
444 ret = regulator_bulk_get(dev, ARRAY_SIZE(data->supplies),
445 data->supplies);
446 if (ret != 0) {
447 dev_err(dev, "Failed to request supplies: %d\n", ret);
448 goto err_regulator;
449 }
450
451 ret = tpa6130a2_power(1);
452 if (ret != 0)
453 goto err_power;
454
399 455
400 /* Read version */ 456 /* Read version */
401 ret = tpa6130a2_i2c_read(TPA6130A2_REG_VERSION) & 457 ret = tpa6130a2_i2c_read(TPA6130A2_REG_VERSION) &
@@ -404,10 +460,18 @@ static int tpa6130a2_probe(struct i2c_client *client,
404 dev_warn(dev, "UNTESTED version detected (%d)\n", ret); 460 dev_warn(dev, "UNTESTED version detected (%d)\n", ret);
405 461
406 /* Disable the chip */ 462 /* Disable the chip */
407 tpa6130a2_power(0); 463 ret = tpa6130a2_power(0);
464 if (ret != 0)
465 goto err_power;
408 466
409 return 0; 467 return 0;
410fail: 468
469err_power:
470 regulator_bulk_free(ARRAY_SIZE(data->supplies), data->supplies);
471err_regulator:
472 if (data->power_gpio >= 0)
473 gpio_free(data->power_gpio);
474err_gpio:
411 kfree(data); 475 kfree(data);
412 i2c_set_clientdata(tpa6130a2_client, NULL); 476 i2c_set_clientdata(tpa6130a2_client, NULL);
413 tpa6130a2_client = NULL; 477 tpa6130a2_client = NULL;
@@ -415,7 +479,7 @@ fail:
415 return ret; 479 return ret;
416} 480}
417 481
418static int tpa6130a2_remove(struct i2c_client *client) 482static int __devexit tpa6130a2_remove(struct i2c_client *client)
419{ 483{
420 struct tpa6130a2_data *data = i2c_get_clientdata(client); 484 struct tpa6130a2_data *data = i2c_get_clientdata(client);
421 485
@@ -423,6 +487,9 @@ static int tpa6130a2_remove(struct i2c_client *client)
423 487
424 if (data->power_gpio >= 0) 488 if (data->power_gpio >= 0)
425 gpio_free(data->power_gpio); 489 gpio_free(data->power_gpio);
490
491 regulator_bulk_free(ARRAY_SIZE(data->supplies), data->supplies);
492
426 kfree(data); 493 kfree(data);
427 tpa6130a2_client = NULL; 494 tpa6130a2_client = NULL;
428 495
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index 2a27f7b56726..6f5d4af20052 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -55,7 +55,7 @@ static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = {
55 0x0c, /* REG_ATXR1PGA (0xB) */ 55 0x0c, /* REG_ATXR1PGA (0xB) */
56 0x00, /* REG_AVTXL2PGA (0xC) */ 56 0x00, /* REG_AVTXL2PGA (0xC) */
57 0x00, /* REG_AVTXR2PGA (0xD) */ 57 0x00, /* REG_AVTXR2PGA (0xD) */
58 0x01, /* REG_AUDIO_IF (0xE) */ 58 0x00, /* REG_AUDIO_IF (0xE) */
59 0x00, /* REG_VOICE_IF (0xF) */ 59 0x00, /* REG_VOICE_IF (0xF) */
60 0x00, /* REG_ARXR1PGA (0x10) */ 60 0x00, /* REG_ARXR1PGA (0x10) */
61 0x00, /* REG_ARXL1PGA (0x11) */ 61 0x00, /* REG_ARXL1PGA (0x11) */
@@ -64,19 +64,19 @@ static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = {
64 0x00, /* REG_VRXPGA (0x14) */ 64 0x00, /* REG_VRXPGA (0x14) */
65 0x00, /* REG_VSTPGA (0x15) */ 65 0x00, /* REG_VSTPGA (0x15) */
66 0x00, /* REG_VRX2ARXPGA (0x16) */ 66 0x00, /* REG_VRX2ARXPGA (0x16) */
67 0x0c, /* REG_AVDAC_CTL (0x17) */ 67 0x00, /* REG_AVDAC_CTL (0x17) */
68 0x00, /* REG_ARX2VTXPGA (0x18) */ 68 0x00, /* REG_ARX2VTXPGA (0x18) */
69 0x00, /* REG_ARXL1_APGA_CTL (0x19) */ 69 0x00, /* REG_ARXL1_APGA_CTL (0x19) */
70 0x00, /* REG_ARXR1_APGA_CTL (0x1A) */ 70 0x00, /* REG_ARXR1_APGA_CTL (0x1A) */
71 0x4b, /* REG_ARXL2_APGA_CTL (0x1B) */ 71 0x4a, /* REG_ARXL2_APGA_CTL (0x1B) */
72 0x4b, /* REG_ARXR2_APGA_CTL (0x1C) */ 72 0x4a, /* REG_ARXR2_APGA_CTL (0x1C) */
73 0x00, /* REG_ATX2ARXPGA (0x1D) */ 73 0x00, /* REG_ATX2ARXPGA (0x1D) */
74 0x00, /* REG_BT_IF (0x1E) */ 74 0x00, /* REG_BT_IF (0x1E) */
75 0x00, /* REG_BTPGA (0x1F) */ 75 0x00, /* REG_BTPGA (0x1F) */
76 0x00, /* REG_BTSTPGA (0x20) */ 76 0x00, /* REG_BTSTPGA (0x20) */
77 0x00, /* REG_EAR_CTL (0x21) */ 77 0x00, /* REG_EAR_CTL (0x21) */
78 0x24, /* REG_HS_SEL (0x22) */ 78 0x00, /* REG_HS_SEL (0x22) */
79 0x0a, /* REG_HS_GAIN_SET (0x23) */ 79 0x00, /* REG_HS_GAIN_SET (0x23) */
80 0x00, /* REG_HS_POPN_SET (0x24) */ 80 0x00, /* REG_HS_POPN_SET (0x24) */
81 0x00, /* REG_PREDL_CTL (0x25) */ 81 0x00, /* REG_PREDL_CTL (0x25) */
82 0x00, /* REG_PREDR_CTL (0x26) */ 82 0x00, /* REG_PREDR_CTL (0x26) */
@@ -99,7 +99,7 @@ static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = {
99 0x00, /* REG_I2S_RX_SCRAMBLE_H (0x37) */ 99 0x00, /* REG_I2S_RX_SCRAMBLE_H (0x37) */
100 0x00, /* REG_I2S_RX_SCRAMBLE_M (0x38) */ 100 0x00, /* REG_I2S_RX_SCRAMBLE_M (0x38) */
101 0x00, /* REG_I2S_RX_SCRAMBLE_L (0x39) */ 101 0x00, /* REG_I2S_RX_SCRAMBLE_L (0x39) */
102 0x16, /* REG_APLL_CTL (0x3A) */ 102 0x06, /* REG_APLL_CTL (0x3A) */
103 0x00, /* REG_DTMF_CTL (0x3B) */ 103 0x00, /* REG_DTMF_CTL (0x3B) */
104 0x00, /* REG_DTMF_PGA_CTL2 (0x3C) */ 104 0x00, /* REG_DTMF_PGA_CTL2 (0x3C) */
105 0x00, /* REG_DTMF_PGA_CTL1 (0x3D) */ 105 0x00, /* REG_DTMF_PGA_CTL1 (0x3D) */
@@ -1203,6 +1203,8 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1203 SND_SOC_DAPM_SUPPLY("APLL Enable", SND_SOC_NOPM, 0, 0, apll_event, 1203 SND_SOC_DAPM_SUPPLY("APLL Enable", SND_SOC_NOPM, 0, 0, apll_event,
1204 SND_SOC_DAPM_PRE_PMU|SND_SOC_DAPM_POST_PMD), 1204 SND_SOC_DAPM_PRE_PMU|SND_SOC_DAPM_POST_PMD),
1205 1205
1206 SND_SOC_DAPM_SUPPLY("AIF Enable", TWL4030_REG_AUDIO_IF, 0, 0, NULL, 0),
1207
1206 /* Output MIXER controls */ 1208 /* Output MIXER controls */
1207 /* Earpiece */ 1209 /* Earpiece */
1208 SND_SOC_DAPM_MIXER("Earpiece Mixer", SND_SOC_NOPM, 0, 0, 1210 SND_SOC_DAPM_MIXER("Earpiece Mixer", SND_SOC_NOPM, 0, 0,
@@ -1337,6 +1339,11 @@ static const struct snd_soc_dapm_route intercon[] = {
1337 {"Digital L2 Playback Mixer", NULL, "APLL Enable"}, 1339 {"Digital L2 Playback Mixer", NULL, "APLL Enable"},
1338 {"Digital Voice Playback Mixer", NULL, "APLL Enable"}, 1340 {"Digital Voice Playback Mixer", NULL, "APLL Enable"},
1339 1341
1342 {"Digital R1 Playback Mixer", NULL, "AIF Enable"},
1343 {"Digital L1 Playback Mixer", NULL, "AIF Enable"},
1344 {"Digital R2 Playback Mixer", NULL, "AIF Enable"},
1345 {"Digital L2 Playback Mixer", NULL, "AIF Enable"},
1346
1340 {"Analog L1 Playback Mixer", NULL, "Digital L1 Playback Mixer"}, 1347 {"Analog L1 Playback Mixer", NULL, "Digital L1 Playback Mixer"},
1341 {"Analog R1 Playback Mixer", NULL, "Digital R1 Playback Mixer"}, 1348 {"Analog R1 Playback Mixer", NULL, "Digital R1 Playback Mixer"},
1342 {"Analog L2 Playback Mixer", NULL, "Digital L2 Playback Mixer"}, 1349 {"Analog L2 Playback Mixer", NULL, "Digital L2 Playback Mixer"},
@@ -1455,6 +1462,11 @@ static const struct snd_soc_dapm_route intercon[] = {
1455 {"ADC Virtual Left2", NULL, "APLL Enable"}, 1462 {"ADC Virtual Left2", NULL, "APLL Enable"},
1456 {"ADC Virtual Right2", NULL, "APLL Enable"}, 1463 {"ADC Virtual Right2", NULL, "APLL Enable"},
1457 1464
1465 {"ADC Virtual Left1", NULL, "AIF Enable"},
1466 {"ADC Virtual Right1", NULL, "AIF Enable"},
1467 {"ADC Virtual Left2", NULL, "AIF Enable"},
1468 {"ADC Virtual Right2", NULL, "AIF Enable"},
1469
1458 /* Analog bypass routes */ 1470 /* Analog bypass routes */
1459 {"Right1 Analog Loopback", "Switch", "Analog Right"}, 1471 {"Right1 Analog Loopback", "Switch", "Analog Right"},
1460 {"Left1 Analog Loopback", "Switch", "Analog Left"}, 1472 {"Left1 Analog Loopback", "Switch", "Analog Left"},
@@ -2152,8 +2164,6 @@ static int twl4030_soc_remove(struct platform_device *pdev)
2152 twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF); 2164 twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF);
2153 snd_soc_free_pcms(socdev); 2165 snd_soc_free_pcms(socdev);
2154 snd_soc_dapm_free(socdev); 2166 snd_soc_dapm_free(socdev);
2155 kfree(codec->private_data);
2156 kfree(codec);
2157 2167
2158 return 0; 2168 return 0;
2159} 2169}
@@ -2192,7 +2202,7 @@ static int __devinit twl4030_codec_probe(struct platform_device *pdev)
2192 codec->write = twl4030_write; 2202 codec->write = twl4030_write;
2193 codec->set_bias_level = twl4030_set_bias_level; 2203 codec->set_bias_level = twl4030_set_bias_level;
2194 codec->dai = twl4030_dai; 2204 codec->dai = twl4030_dai;
2195 codec->num_dai = ARRAY_SIZE(twl4030_dai), 2205 codec->num_dai = ARRAY_SIZE(twl4030_dai);
2196 codec->reg_cache_size = sizeof(twl4030_reg); 2206 codec->reg_cache_size = sizeof(twl4030_reg);
2197 codec->reg_cache = kmemdup(twl4030_reg, sizeof(twl4030_reg), 2207 codec->reg_cache = kmemdup(twl4030_reg, sizeof(twl4030_reg),
2198 GFP_KERNEL); 2208 GFP_KERNEL);
@@ -2237,6 +2247,9 @@ static int __devexit twl4030_codec_remove(struct platform_device *pdev)
2237{ 2247{
2238 struct twl4030_priv *twl4030 = platform_get_drvdata(pdev); 2248 struct twl4030_priv *twl4030 = platform_get_drvdata(pdev);
2239 2249
2250 snd_soc_unregister_dais(&twl4030_dai[0], ARRAY_SIZE(twl4030_dai));
2251 snd_soc_unregister_codec(&twl4030->codec);
2252 kfree(twl4030->codec.reg_cache);
2240 kfree(twl4030); 2253 kfree(twl4030);
2241 2254
2242 twl4030_codec = NULL; 2255 twl4030_codec = NULL;
diff --git a/sound/soc/codecs/twl4030.h b/sound/soc/codecs/twl4030.h
index dd6396ec9c79..f206d242ca31 100644
--- a/sound/soc/codecs/twl4030.h
+++ b/sound/soc/codecs/twl4030.h
@@ -25,7 +25,7 @@
25/* Register descriptions are here */ 25/* Register descriptions are here */
26#include <linux/mfd/twl4030-codec.h> 26#include <linux/mfd/twl4030-codec.h>
27 27
28/* Sgadow register used by the audio driver */ 28/* Shadow register used by the audio driver */
29#define TWL4030_REG_SW_SHADOW 0x4A 29#define TWL4030_REG_SW_SHADOW 0x4A
30#define TWL4030_CACHEREGNUM (TWL4030_REG_SW_SHADOW + 1) 30#define TWL4030_CACHEREGNUM (TWL4030_REG_SW_SHADOW + 1)
31 31
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c
index a2763c2e7348..9cd0a66b7663 100644
--- a/sound/soc/codecs/uda1380.c
+++ b/sound/soc/codecs/uda1380.c
@@ -137,7 +137,7 @@ static void uda1380_flush_work(struct work_struct *work)
137{ 137{
138 int bit, reg; 138 int bit, reg;
139 139
140 for_each_bit(bit, &uda1380_cache_dirty, UDA1380_CACHEREGNUM - 0x10) { 140 for_each_set_bit(bit, &uda1380_cache_dirty, UDA1380_CACHEREGNUM - 0x10) {
141 reg = 0x10 + bit; 141 reg = 0x10 + bit;
142 pr_debug("uda1380: flush reg %x val %x:\n", reg, 142 pr_debug("uda1380: flush reg %x val %x:\n", reg,
143 uda1380_read_reg_cache(uda1380_codec, reg)); 143 uda1380_read_reg_cache(uda1380_codec, reg));
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c
new file mode 100644
index 000000000000..217b02680597
--- /dev/null
+++ b/sound/soc/codecs/wm2000.c
@@ -0,0 +1,888 @@
1/*
2 * wm2000.c -- WM2000 ALSA Soc Audio driver
3 *
4 * Copyright 2008-2010 Wolfson Microelectronics PLC.
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * The download image for the WM2000 will be requested as
13 * 'wm2000_anc.bin' by default (overridable via platform data) at
14 * runtime and is expected to be in flat binary format. This is
15 * generated by Wolfson configuration tools and includes
16 * system-specific callibration information. If supplied as a
17 * sequence of ASCII-encoded hexidecimal bytes this can be converted
18 * into a flat binary with a command such as this on the command line:
19 *
20 * perl -e 'while (<>) { s/[\r\n]+// ; printf("%c", hex($_)); }'
21 * < file > wm2000_anc.bin
22 */
23
24#include <linux/module.h>
25#include <linux/moduleparam.h>
26#include <linux/version.h>
27#include <linux/kernel.h>
28#include <linux/init.h>
29#include <linux/firmware.h>
30#include <linux/delay.h>
31#include <linux/pm.h>
32#include <linux/i2c.h>
33#include <linux/platform_device.h>
34#include <linux/debugfs.h>
35#include <sound/core.h>
36#include <sound/pcm.h>
37#include <sound/pcm_params.h>
38#include <sound/soc.h>
39#include <sound/soc-dapm.h>
40#include <sound/initval.h>
41#include <sound/tlv.h>
42
43#include <sound/wm2000.h>
44
45#include "wm2000.h"
46
47enum wm2000_anc_mode {
48 ANC_ACTIVE = 0,
49 ANC_BYPASS = 1,
50 ANC_STANDBY = 2,
51 ANC_OFF = 3,
52};
53
54struct wm2000_priv {
55 struct i2c_client *i2c;
56
57 enum wm2000_anc_mode anc_mode;
58
59 unsigned int anc_active:1;
60 unsigned int anc_eng_ena:1;
61 unsigned int spk_ena:1;
62
63 unsigned int mclk_div:1;
64 unsigned int speech_clarity:1;
65
66 int anc_download_size;
67 char *anc_download;
68};
69
70static struct i2c_client *wm2000_i2c;
71
72static int wm2000_write(struct i2c_client *i2c, unsigned int reg,
73 unsigned int value)
74{
75 u8 data[3];
76 int ret;
77
78 data[0] = (reg >> 8) & 0xff;
79 data[1] = reg & 0xff;
80 data[2] = value & 0xff;
81
82 dev_vdbg(&i2c->dev, "write %x = %x\n", reg, value);
83
84 ret = i2c_master_send(i2c, data, 3);
85 if (ret == 3)
86 return 0;
87 if (ret < 0)
88 return ret;
89 else
90 return -EIO;
91}
92
93static unsigned int wm2000_read(struct i2c_client *i2c, unsigned int r)
94{
95 struct i2c_msg xfer[2];
96 u8 reg[2];
97 u8 data;
98 int ret;
99
100 /* Write register */
101 reg[0] = (r >> 8) & 0xff;
102 reg[1] = r & 0xff;
103 xfer[0].addr = i2c->addr;
104 xfer[0].flags = 0;
105 xfer[0].len = sizeof(reg);
106 xfer[0].buf = &reg[0];
107
108 /* Read data */
109 xfer[1].addr = i2c->addr;
110 xfer[1].flags = I2C_M_RD;
111 xfer[1].len = 1;
112 xfer[1].buf = &data;
113
114 ret = i2c_transfer(i2c->adapter, xfer, 2);
115 if (ret != 2) {
116 dev_err(&i2c->dev, "i2c_transfer() returned %d\n", ret);
117 return 0;
118 }
119
120 dev_vdbg(&i2c->dev, "read %x from %x\n", data, r);
121
122 return data;
123}
124
125static void wm2000_reset(struct wm2000_priv *wm2000)
126{
127 struct i2c_client *i2c = wm2000->i2c;
128
129 wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_ANC_ENG_CLR);
130 wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_RAM_CLR);
131 wm2000_write(i2c, WM2000_REG_ID1, 0);
132
133 wm2000->anc_mode = ANC_OFF;
134}
135
136static int wm2000_poll_bit(struct i2c_client *i2c,
137 unsigned int reg, u8 mask, int timeout)
138{
139 int val;
140
141 val = wm2000_read(i2c, reg);
142
143 while (!(val & mask) && --timeout) {
144 msleep(1);
145 val = wm2000_read(i2c, reg);
146 }
147
148 if (timeout == 0)
149 return 0;
150 else
151 return 1;
152}
153
154static int wm2000_power_up(struct i2c_client *i2c, int analogue)
155{
156 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
157 int ret, timeout;
158
159 BUG_ON(wm2000->anc_mode != ANC_OFF);
160
161 dev_dbg(&i2c->dev, "Beginning power up\n");
162
163 if (!wm2000->mclk_div) {
164 dev_dbg(&i2c->dev, "Disabling MCLK divider\n");
165 wm2000_write(i2c, WM2000_REG_SYS_CTL2,
166 WM2000_MCLK_DIV2_ENA_CLR);
167 } else {
168 dev_dbg(&i2c->dev, "Enabling MCLK divider\n");
169 wm2000_write(i2c, WM2000_REG_SYS_CTL2,
170 WM2000_MCLK_DIV2_ENA_SET);
171 }
172
173 wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_ANC_ENG_CLR);
174 wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_ANC_ENG_SET);
175
176 /* Wait for ANC engine to become ready */
177 if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT,
178 WM2000_ANC_ENG_IDLE, 1)) {
179 dev_err(&i2c->dev, "ANC engine failed to reset\n");
180 return -ETIMEDOUT;
181 }
182
183 if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
184 WM2000_STATUS_BOOT_COMPLETE, 1)) {
185 dev_err(&i2c->dev, "ANC engine failed to initialise\n");
186 return -ETIMEDOUT;
187 }
188
189 wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_RAM_SET);
190
191 /* Open code download of the data since it is the only bulk
192 * write we do. */
193 dev_dbg(&i2c->dev, "Downloading %d bytes\n",
194 wm2000->anc_download_size - 2);
195
196 ret = i2c_master_send(i2c, wm2000->anc_download,
197 wm2000->anc_download_size);
198 if (ret < 0) {
199 dev_err(&i2c->dev, "i2c_transfer() failed: %d\n", ret);
200 return ret;
201 }
202 if (ret != wm2000->anc_download_size) {
203 dev_err(&i2c->dev, "i2c_transfer() failed, %d != %d\n",
204 ret, wm2000->anc_download_size);
205 return -EIO;
206 }
207
208 dev_dbg(&i2c->dev, "Download complete\n");
209
210 if (analogue) {
211 timeout = 248;
212 wm2000_write(i2c, WM2000_REG_ANA_VMID_PU_TIME, timeout / 4);
213
214 wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
215 WM2000_MODE_ANA_SEQ_INCLUDE |
216 WM2000_MODE_MOUSE_ENABLE |
217 WM2000_MODE_THERMAL_ENABLE);
218 } else {
219 timeout = 10;
220
221 wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
222 WM2000_MODE_MOUSE_ENABLE |
223 WM2000_MODE_THERMAL_ENABLE);
224 }
225
226 ret = wm2000_read(i2c, WM2000_REG_SPEECH_CLARITY);
227 if (wm2000->speech_clarity)
228 ret &= ~WM2000_SPEECH_CLARITY;
229 else
230 ret |= WM2000_SPEECH_CLARITY;
231 wm2000_write(i2c, WM2000_REG_SPEECH_CLARITY, ret);
232
233 wm2000_write(i2c, WM2000_REG_SYS_START0, 0x33);
234 wm2000_write(i2c, WM2000_REG_SYS_START1, 0x02);
235
236 wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_ANC_INT_N_CLR);
237
238 if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
239 WM2000_STATUS_MOUSE_ACTIVE, timeout)) {
240 dev_err(&i2c->dev, "Timed out waiting for device after %dms\n",
241 timeout * 10);
242 return -ETIMEDOUT;
243 }
244
245 dev_dbg(&i2c->dev, "ANC active\n");
246 if (analogue)
247 dev_dbg(&i2c->dev, "Analogue active\n");
248 wm2000->anc_mode = ANC_ACTIVE;
249
250 return 0;
251}
252
253static int wm2000_power_down(struct i2c_client *i2c, int analogue)
254{
255 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
256 int timeout;
257
258 if (analogue) {
259 timeout = 248;
260 wm2000_write(i2c, WM2000_REG_ANA_VMID_PD_TIME, timeout / 4);
261 wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
262 WM2000_MODE_ANA_SEQ_INCLUDE |
263 WM2000_MODE_POWER_DOWN);
264 } else {
265 timeout = 10;
266 wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
267 WM2000_MODE_POWER_DOWN);
268 }
269
270 if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
271 WM2000_STATUS_POWER_DOWN_COMPLETE, timeout)) {
272 dev_err(&i2c->dev, "Timeout waiting for ANC power down\n");
273 return -ETIMEDOUT;
274 }
275
276 if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT,
277 WM2000_ANC_ENG_IDLE, 1)) {
278 dev_err(&i2c->dev, "Timeout waiting for ANC engine idle\n");
279 return -ETIMEDOUT;
280 }
281
282 dev_dbg(&i2c->dev, "powered off\n");
283 wm2000->anc_mode = ANC_OFF;
284
285 return 0;
286}
287
288static int wm2000_enter_bypass(struct i2c_client *i2c, int analogue)
289{
290 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
291
292 BUG_ON(wm2000->anc_mode != ANC_ACTIVE);
293
294 if (analogue) {
295 wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
296 WM2000_MODE_ANA_SEQ_INCLUDE |
297 WM2000_MODE_THERMAL_ENABLE |
298 WM2000_MODE_BYPASS_ENTRY);
299 } else {
300 wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
301 WM2000_MODE_THERMAL_ENABLE |
302 WM2000_MODE_BYPASS_ENTRY);
303 }
304
305 if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
306 WM2000_STATUS_ANC_DISABLED, 10)) {
307 dev_err(&i2c->dev, "Timeout waiting for ANC disable\n");
308 return -ETIMEDOUT;
309 }
310
311 if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT,
312 WM2000_ANC_ENG_IDLE, 1)) {
313 dev_err(&i2c->dev, "Timeout waiting for ANC engine idle\n");
314 return -ETIMEDOUT;
315 }
316
317 wm2000_write(i2c, WM2000_REG_SYS_CTL1, WM2000_SYS_STBY);
318 wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_RAM_CLR);
319
320 wm2000->anc_mode = ANC_BYPASS;
321 dev_dbg(&i2c->dev, "bypass enabled\n");
322
323 return 0;
324}
325
326static int wm2000_exit_bypass(struct i2c_client *i2c, int analogue)
327{
328 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
329
330 BUG_ON(wm2000->anc_mode != ANC_BYPASS);
331
332 wm2000_write(i2c, WM2000_REG_SYS_CTL1, 0);
333
334 if (analogue) {
335 wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
336 WM2000_MODE_ANA_SEQ_INCLUDE |
337 WM2000_MODE_MOUSE_ENABLE |
338 WM2000_MODE_THERMAL_ENABLE);
339 } else {
340 wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
341 WM2000_MODE_MOUSE_ENABLE |
342 WM2000_MODE_THERMAL_ENABLE);
343 }
344
345 wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_RAM_SET);
346 wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_ANC_INT_N_CLR);
347
348 if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
349 WM2000_STATUS_MOUSE_ACTIVE, 10)) {
350 dev_err(&i2c->dev, "Timed out waiting for MOUSE\n");
351 return -ETIMEDOUT;
352 }
353
354 wm2000->anc_mode = ANC_ACTIVE;
355 dev_dbg(&i2c->dev, "MOUSE active\n");
356
357 return 0;
358}
359
360static int wm2000_enter_standby(struct i2c_client *i2c, int analogue)
361{
362 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
363 int timeout;
364
365 BUG_ON(wm2000->anc_mode != ANC_ACTIVE);
366
367 if (analogue) {
368 timeout = 248;
369 wm2000_write(i2c, WM2000_REG_ANA_VMID_PD_TIME, timeout / 4);
370
371 wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
372 WM2000_MODE_ANA_SEQ_INCLUDE |
373 WM2000_MODE_THERMAL_ENABLE |
374 WM2000_MODE_STANDBY_ENTRY);
375 } else {
376 timeout = 10;
377
378 wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
379 WM2000_MODE_THERMAL_ENABLE |
380 WM2000_MODE_STANDBY_ENTRY);
381 }
382
383 if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
384 WM2000_STATUS_ANC_DISABLED, timeout)) {
385 dev_err(&i2c->dev,
386 "Timed out waiting for ANC disable after 1ms\n");
387 return -ETIMEDOUT;
388 }
389
390 if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT, WM2000_ANC_ENG_IDLE,
391 1)) {
392 dev_err(&i2c->dev,
393 "Timed out waiting for standby after %dms\n",
394 timeout * 10);
395 return -ETIMEDOUT;
396 }
397
398 wm2000_write(i2c, WM2000_REG_SYS_CTL1, WM2000_SYS_STBY);
399 wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_RAM_CLR);
400
401 wm2000->anc_mode = ANC_STANDBY;
402 dev_dbg(&i2c->dev, "standby\n");
403 if (analogue)
404 dev_dbg(&i2c->dev, "Analogue disabled\n");
405
406 return 0;
407}
408
409static int wm2000_exit_standby(struct i2c_client *i2c, int analogue)
410{
411 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
412 int timeout;
413
414 BUG_ON(wm2000->anc_mode != ANC_STANDBY);
415
416 wm2000_write(i2c, WM2000_REG_SYS_CTL1, 0);
417
418 if (analogue) {
419 timeout = 248;
420 wm2000_write(i2c, WM2000_REG_ANA_VMID_PU_TIME, timeout / 4);
421
422 wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
423 WM2000_MODE_ANA_SEQ_INCLUDE |
424 WM2000_MODE_THERMAL_ENABLE |
425 WM2000_MODE_MOUSE_ENABLE);
426 } else {
427 timeout = 10;
428
429 wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
430 WM2000_MODE_THERMAL_ENABLE |
431 WM2000_MODE_MOUSE_ENABLE);
432 }
433
434 wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_RAM_SET);
435 wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_ANC_INT_N_CLR);
436
437 if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
438 WM2000_STATUS_MOUSE_ACTIVE, timeout)) {
439 dev_err(&i2c->dev, "Timed out waiting for MOUSE after %dms\n",
440 timeout * 10);
441 return -ETIMEDOUT;
442 }
443
444 wm2000->anc_mode = ANC_ACTIVE;
445 dev_dbg(&i2c->dev, "MOUSE active\n");
446 if (analogue)
447 dev_dbg(&i2c->dev, "Analogue enabled\n");
448
449 return 0;
450}
451
452typedef int (*wm2000_mode_fn)(struct i2c_client *i2c, int analogue);
453
454static struct {
455 enum wm2000_anc_mode source;
456 enum wm2000_anc_mode dest;
457 int analogue;
458 wm2000_mode_fn step[2];
459} anc_transitions[] = {
460 {
461 .source = ANC_OFF,
462 .dest = ANC_ACTIVE,
463 .analogue = 1,
464 .step = {
465 wm2000_power_up,
466 },
467 },
468 {
469 .source = ANC_OFF,
470 .dest = ANC_STANDBY,
471 .step = {
472 wm2000_power_up,
473 wm2000_enter_standby,
474 },
475 },
476 {
477 .source = ANC_OFF,
478 .dest = ANC_BYPASS,
479 .analogue = 1,
480 .step = {
481 wm2000_power_up,
482 wm2000_enter_bypass,
483 },
484 },
485 {
486 .source = ANC_ACTIVE,
487 .dest = ANC_BYPASS,
488 .analogue = 1,
489 .step = {
490 wm2000_enter_bypass,
491 },
492 },
493 {
494 .source = ANC_ACTIVE,
495 .dest = ANC_STANDBY,
496 .analogue = 1,
497 .step = {
498 wm2000_enter_standby,
499 },
500 },
501 {
502 .source = ANC_ACTIVE,
503 .dest = ANC_OFF,
504 .analogue = 1,
505 .step = {
506 wm2000_power_down,
507 },
508 },
509 {
510 .source = ANC_BYPASS,
511 .dest = ANC_ACTIVE,
512 .analogue = 1,
513 .step = {
514 wm2000_exit_bypass,
515 },
516 },
517 {
518 .source = ANC_BYPASS,
519 .dest = ANC_STANDBY,
520 .analogue = 1,
521 .step = {
522 wm2000_exit_bypass,
523 wm2000_enter_standby,
524 },
525 },
526 {
527 .source = ANC_BYPASS,
528 .dest = ANC_OFF,
529 .step = {
530 wm2000_exit_bypass,
531 wm2000_power_down,
532 },
533 },
534 {
535 .source = ANC_STANDBY,
536 .dest = ANC_ACTIVE,
537 .analogue = 1,
538 .step = {
539 wm2000_exit_standby,
540 },
541 },
542 {
543 .source = ANC_STANDBY,
544 .dest = ANC_BYPASS,
545 .analogue = 1,
546 .step = {
547 wm2000_exit_standby,
548 wm2000_enter_bypass,
549 },
550 },
551 {
552 .source = ANC_STANDBY,
553 .dest = ANC_OFF,
554 .step = {
555 wm2000_exit_standby,
556 wm2000_power_down,
557 },
558 },
559};
560
561static int wm2000_anc_transition(struct wm2000_priv *wm2000,
562 enum wm2000_anc_mode mode)
563{
564 struct i2c_client *i2c = wm2000->i2c;
565 int i, j;
566 int ret;
567
568 if (wm2000->anc_mode == mode)
569 return 0;
570
571 for (i = 0; i < ARRAY_SIZE(anc_transitions); i++)
572 if (anc_transitions[i].source == wm2000->anc_mode &&
573 anc_transitions[i].dest == mode)
574 break;
575 if (i == ARRAY_SIZE(anc_transitions)) {
576 dev_err(&i2c->dev, "No transition for %d->%d\n",
577 wm2000->anc_mode, mode);
578 return -EINVAL;
579 }
580
581 for (j = 0; j < ARRAY_SIZE(anc_transitions[j].step); j++) {
582 if (!anc_transitions[i].step[j])
583 break;
584 ret = anc_transitions[i].step[j](i2c,
585 anc_transitions[i].analogue);
586 if (ret != 0)
587 return ret;
588 }
589
590 return 0;
591}
592
593static int wm2000_anc_set_mode(struct wm2000_priv *wm2000)
594{
595 struct i2c_client *i2c = wm2000->i2c;
596 enum wm2000_anc_mode mode;
597
598 if (wm2000->anc_eng_ena && wm2000->spk_ena)
599 if (wm2000->anc_active)
600 mode = ANC_ACTIVE;
601 else
602 mode = ANC_BYPASS;
603 else
604 mode = ANC_STANDBY;
605
606 dev_dbg(&i2c->dev, "Set mode %d (enabled %d, mute %d, active %d)\n",
607 mode, wm2000->anc_eng_ena, !wm2000->spk_ena,
608 wm2000->anc_active);
609
610 return wm2000_anc_transition(wm2000, mode);
611}
612
613static int wm2000_anc_mode_get(struct snd_kcontrol *kcontrol,
614 struct snd_ctl_elem_value *ucontrol)
615{
616 struct wm2000_priv *wm2000 = dev_get_drvdata(&wm2000_i2c->dev);
617
618 ucontrol->value.enumerated.item[0] = wm2000->anc_active;
619
620 return 0;
621}
622
623static int wm2000_anc_mode_put(struct snd_kcontrol *kcontrol,
624 struct snd_ctl_elem_value *ucontrol)
625{
626 struct wm2000_priv *wm2000 = dev_get_drvdata(&wm2000_i2c->dev);
627 int anc_active = ucontrol->value.enumerated.item[0];
628
629 if (anc_active > 1)
630 return -EINVAL;
631
632 wm2000->anc_active = anc_active;
633
634 return wm2000_anc_set_mode(wm2000);
635}
636
637static int wm2000_speaker_get(struct snd_kcontrol *kcontrol,
638 struct snd_ctl_elem_value *ucontrol)
639{
640 struct wm2000_priv *wm2000 = dev_get_drvdata(&wm2000_i2c->dev);
641
642 ucontrol->value.enumerated.item[0] = wm2000->spk_ena;
643
644 return 0;
645}
646
647static int wm2000_speaker_put(struct snd_kcontrol *kcontrol,
648 struct snd_ctl_elem_value *ucontrol)
649{
650 struct wm2000_priv *wm2000 = dev_get_drvdata(&wm2000_i2c->dev);
651 int val = ucontrol->value.enumerated.item[0];
652
653 if (val > 1)
654 return -EINVAL;
655
656 wm2000->spk_ena = val;
657
658 return wm2000_anc_set_mode(wm2000);
659}
660
661static const struct snd_kcontrol_new wm2000_controls[] = {
662 SOC_SINGLE_BOOL_EXT("WM2000 ANC Switch", 0,
663 wm2000_anc_mode_get,
664 wm2000_anc_mode_put),
665 SOC_SINGLE_BOOL_EXT("WM2000 Switch", 0,
666 wm2000_speaker_get,
667 wm2000_speaker_put),
668};
669
670static int wm2000_anc_power_event(struct snd_soc_dapm_widget *w,
671 struct snd_kcontrol *kcontrol, int event)
672{
673 struct wm2000_priv *wm2000 = dev_get_drvdata(&wm2000_i2c->dev);
674
675 if (SND_SOC_DAPM_EVENT_ON(event))
676 wm2000->anc_eng_ena = 1;
677
678 if (SND_SOC_DAPM_EVENT_OFF(event))
679 wm2000->anc_eng_ena = 0;
680
681 return wm2000_anc_set_mode(wm2000);
682}
683
684static const struct snd_soc_dapm_widget wm2000_dapm_widgets[] = {
685/* Externally visible pins */
686SND_SOC_DAPM_OUTPUT("WM2000 SPKN"),
687SND_SOC_DAPM_OUTPUT("WM2000 SPKP"),
688
689SND_SOC_DAPM_INPUT("WM2000 LINN"),
690SND_SOC_DAPM_INPUT("WM2000 LINP"),
691
692SND_SOC_DAPM_PGA_E("ANC Engine", SND_SOC_NOPM, 0, 0, NULL, 0,
693 wm2000_anc_power_event,
694 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
695};
696
697/* Target, Path, Source */
698static const struct snd_soc_dapm_route audio_map[] = {
699 { "WM2000 SPKN", NULL, "ANC Engine" },
700 { "WM2000 SPKP", NULL, "ANC Engine" },
701 { "ANC Engine", NULL, "WM2000 LINN" },
702 { "ANC Engine", NULL, "WM2000 LINP" },
703};
704
705/* Called from the machine driver */
706int wm2000_add_controls(struct snd_soc_codec *codec)
707{
708 int ret;
709
710 if (!wm2000_i2c) {
711 pr_err("WM2000 not yet probed\n");
712 return -ENODEV;
713 }
714
715 ret = snd_soc_dapm_new_controls(codec, wm2000_dapm_widgets,
716 ARRAY_SIZE(wm2000_dapm_widgets));
717 if (ret < 0)
718 return ret;
719
720 ret = snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
721 if (ret < 0)
722 return ret;
723
724 return snd_soc_add_controls(codec, wm2000_controls,
725 ARRAY_SIZE(wm2000_controls));
726}
727EXPORT_SYMBOL_GPL(wm2000_add_controls);
728
729static int __devinit wm2000_i2c_probe(struct i2c_client *i2c,
730 const struct i2c_device_id *i2c_id)
731{
732 struct wm2000_priv *wm2000;
733 struct wm2000_platform_data *pdata;
734 const char *filename;
735 const struct firmware *fw;
736 int reg, ret;
737 u16 id;
738
739 if (wm2000_i2c) {
740 dev_err(&i2c->dev, "Another WM2000 is already registered\n");
741 return -EINVAL;
742 }
743
744 wm2000 = kzalloc(sizeof(struct wm2000_priv), GFP_KERNEL);
745 if (wm2000 == NULL) {
746 dev_err(&i2c->dev, "Unable to allocate private data\n");
747 return -ENOMEM;
748 }
749
750 /* Verify that this is a WM2000 */
751 reg = wm2000_read(i2c, WM2000_REG_ID1);
752 id = reg << 8;
753 reg = wm2000_read(i2c, WM2000_REG_ID2);
754 id |= reg & 0xff;
755
756 if (id != 0x2000) {
757 dev_err(&i2c->dev, "Device is not a WM2000 - ID %x\n", id);
758 ret = -ENODEV;
759 goto err;
760 }
761
762 reg = wm2000_read(i2c, WM2000_REG_REVISON);
763 dev_info(&i2c->dev, "revision %c\n", reg + 'A');
764
765 filename = "wm2000_anc.bin";
766 pdata = dev_get_platdata(&i2c->dev);
767 if (pdata) {
768 wm2000->mclk_div = pdata->mclkdiv2;
769 wm2000->speech_clarity = !pdata->speech_enh_disable;
770
771 if (pdata->download_file)
772 filename = pdata->download_file;
773 }
774
775 ret = request_firmware(&fw, filename, &i2c->dev);
776 if (ret != 0) {
777 dev_err(&i2c->dev, "Failed to acquire ANC data: %d\n", ret);
778 goto err;
779 }
780
781 /* Pre-cook the concatenation of the register address onto the image */
782 wm2000->anc_download_size = fw->size + 2;
783 wm2000->anc_download = kmalloc(wm2000->anc_download_size, GFP_KERNEL);
784 if (wm2000->anc_download == NULL) {
785 dev_err(&i2c->dev, "Out of memory\n");
786 ret = -ENOMEM;
787 goto err_fw;
788 }
789
790 wm2000->anc_download[0] = 0x80;
791 wm2000->anc_download[1] = 0x00;
792 memcpy(wm2000->anc_download + 2, fw->data, fw->size);
793
794 release_firmware(fw);
795
796 dev_set_drvdata(&i2c->dev, wm2000);
797 wm2000->anc_eng_ena = 1;
798 wm2000->i2c = i2c;
799
800 wm2000_reset(wm2000);
801
802 /* This will trigger a transition to standby mode by default */
803 wm2000_anc_set_mode(wm2000);
804
805 wm2000_i2c = i2c;
806
807 return 0;
808
809err_fw:
810 release_firmware(fw);
811err:
812 kfree(wm2000);
813 return ret;
814}
815
816static __devexit int wm2000_i2c_remove(struct i2c_client *i2c)
817{
818 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
819
820 wm2000_anc_transition(wm2000, ANC_OFF);
821
822 wm2000_i2c = NULL;
823 kfree(wm2000->anc_download);
824 kfree(wm2000);
825
826 return 0;
827}
828
829static void wm2000_i2c_shutdown(struct i2c_client *i2c)
830{
831 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
832
833 wm2000_anc_transition(wm2000, ANC_OFF);
834}
835
836#ifdef CONFIG_PM
837static int wm2000_i2c_suspend(struct i2c_client *i2c, pm_message_t mesg)
838{
839 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
840
841 return wm2000_anc_transition(wm2000, ANC_OFF);
842}
843
844static int wm2000_i2c_resume(struct i2c_client *i2c)
845{
846 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
847
848 return wm2000_anc_set_mode(wm2000);
849}
850#else
851#define wm2000_i2c_suspend NULL
852#define wm2000_i2c_resume NULL
853#endif
854
855static const struct i2c_device_id wm2000_i2c_id[] = {
856 { "wm2000", 0 },
857 { }
858};
859MODULE_DEVICE_TABLE(i2c, wm2000_i2c_id);
860
861static struct i2c_driver wm2000_i2c_driver = {
862 .driver = {
863 .name = "wm2000",
864 .owner = THIS_MODULE,
865 },
866 .probe = wm2000_i2c_probe,
867 .remove = __devexit_p(wm2000_i2c_remove),
868 .suspend = wm2000_i2c_suspend,
869 .resume = wm2000_i2c_resume,
870 .shutdown = wm2000_i2c_shutdown,
871 .id_table = wm2000_i2c_id,
872};
873
874static int __init wm2000_init(void)
875{
876 return i2c_add_driver(&wm2000_i2c_driver);
877}
878module_init(wm2000_init);
879
880static void __exit wm2000_exit(void)
881{
882 i2c_del_driver(&wm2000_i2c_driver);
883}
884module_exit(wm2000_exit);
885
886MODULE_DESCRIPTION("ASoC WM2000 driver");
887MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfonmicro.com>");
888MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm2000.h b/sound/soc/codecs/wm2000.h
new file mode 100644
index 000000000000..c18e261c3c7f
--- /dev/null
+++ b/sound/soc/codecs/wm2000.h
@@ -0,0 +1,79 @@
1/*
2 * wm2000.h -- WM2000 Soc Audio driver
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#ifndef _WM2000_H
10#define _WM2000_H
11
12struct wm2000_setup_data {
13 unsigned short i2c_address;
14 int mclk_div; /* Set to a non-zero value if MCLK_DIV_2 required */
15};
16
17extern int wm2000_add_controls(struct snd_soc_codec *codec);
18
19extern struct snd_soc_dai wm2000_dai;
20extern struct snd_soc_codec_device soc_codec_dev_wm2000;
21
22#define WM2000_REG_SYS_START 0x8000
23#define WM2000_REG_SPEECH_CLARITY 0x8fef
24#define WM2000_REG_SYS_WATCHDOG 0x8ff6
25#define WM2000_REG_ANA_VMID_PD_TIME 0x8ff7
26#define WM2000_REG_ANA_VMID_PU_TIME 0x8ff8
27#define WM2000_REG_CAT_FLTR_INDX 0x8ff9
28#define WM2000_REG_CAT_GAIN_0 0x8ffa
29#define WM2000_REG_SYS_STATUS 0x8ffc
30#define WM2000_REG_SYS_MODE_CNTRL 0x8ffd
31#define WM2000_REG_SYS_START0 0x8ffe
32#define WM2000_REG_SYS_START1 0x8fff
33#define WM2000_REG_ID1 0xf000
34#define WM2000_REG_ID2 0xf001
35#define WM2000_REG_REVISON 0xf002
36#define WM2000_REG_SYS_CTL1 0xf003
37#define WM2000_REG_SYS_CTL2 0xf004
38#define WM2000_REG_ANC_STAT 0xf005
39#define WM2000_REG_IF_CTL 0xf006
40
41/* SPEECH_CLARITY */
42#define WM2000_SPEECH_CLARITY 0x01
43
44/* SYS_STATUS */
45#define WM2000_STATUS_MOUSE_ACTIVE 0x40
46#define WM2000_STATUS_CAT_FREQ_COMPLETE 0x20
47#define WM2000_STATUS_CAT_GAIN_COMPLETE 0x10
48#define WM2000_STATUS_THERMAL_SHUTDOWN_COMPLETE 0x08
49#define WM2000_STATUS_ANC_DISABLED 0x04
50#define WM2000_STATUS_POWER_DOWN_COMPLETE 0x02
51#define WM2000_STATUS_BOOT_COMPLETE 0x01
52
53/* SYS_MODE_CNTRL */
54#define WM2000_MODE_ANA_SEQ_INCLUDE 0x80
55#define WM2000_MODE_MOUSE_ENABLE 0x40
56#define WM2000_MODE_CAT_FREQ_ENABLE 0x20
57#define WM2000_MODE_CAT_GAIN_ENABLE 0x10
58#define WM2000_MODE_BYPASS_ENTRY 0x08
59#define WM2000_MODE_STANDBY_ENTRY 0x04
60#define WM2000_MODE_THERMAL_ENABLE 0x02
61#define WM2000_MODE_POWER_DOWN 0x01
62
63/* SYS_CTL1 */
64#define WM2000_SYS_STBY 0x01
65
66/* SYS_CTL2 */
67#define WM2000_MCLK_DIV2_ENA_CLR 0x80
68#define WM2000_MCLK_DIV2_ENA_SET 0x40
69#define WM2000_ANC_ENG_CLR 0x20
70#define WM2000_ANC_ENG_SET 0x10
71#define WM2000_ANC_INT_N_CLR 0x08
72#define WM2000_ANC_INT_N_SET 0x04
73#define WM2000_RAM_CLR 0x02
74#define WM2000_RAM_SET 0x01
75
76/* ANC_STAT */
77#define WM2000_ANC_ENG_IDLE 0x01
78
79#endif
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
index 718ef912e758..df2c6d9617fb 100644
--- a/sound/soc/codecs/wm8350.c
+++ b/sound/soc/codecs/wm8350.c
@@ -1349,7 +1349,7 @@ static irqreturn_t wm8350_hp_jack_handler(int irq, void *data)
1349 int mask; 1349 int mask;
1350 struct wm8350_jack_data *jack = NULL; 1350 struct wm8350_jack_data *jack = NULL;
1351 1351
1352 switch (irq) { 1352 switch (irq - wm8350->irq_base) {
1353 case WM8350_IRQ_CODEC_JCK_DET_L: 1353 case WM8350_IRQ_CODEC_JCK_DET_L:
1354 jack = &priv->hpl; 1354 jack = &priv->hpl;
1355 mask = WM8350_JACK_L_LVL; 1355 mask = WM8350_JACK_L_LVL;
@@ -1424,7 +1424,7 @@ int wm8350_hp_jack_detect(struct snd_soc_codec *codec, enum wm8350_jack which,
1424 wm8350_set_bits(wm8350, WM8350_JACK_DETECT, ena); 1424 wm8350_set_bits(wm8350, WM8350_JACK_DETECT, ena);
1425 1425
1426 /* Sync status */ 1426 /* Sync status */
1427 wm8350_hp_jack_handler(irq, priv); 1427 wm8350_hp_jack_handler(irq + wm8350->irq_base, priv);
1428 1428
1429 return 0; 1429 return 0;
1430} 1430}
@@ -1521,8 +1521,8 @@ static int wm8350_remove(struct platform_device *pdev)
1521 WM8350_JDL_ENA | WM8350_JDR_ENA); 1521 WM8350_JDL_ENA | WM8350_JDR_ENA);
1522 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_TOCLK_ENA); 1522 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_TOCLK_ENA);
1523 1523
1524 wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L); 1524 wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L, priv);
1525 wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R); 1525 wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R, priv);
1526 1526
1527 priv->hpl.jack = NULL; 1527 priv->hpl.jack = NULL;
1528 priv->hpr.jack = NULL; 1528 priv->hpr.jack = NULL;
diff --git a/sound/soc/codecs/wm8727.c b/sound/soc/codecs/wm8727.c
index d8ffbd641d71..63a254e293ca 100644
--- a/sound/soc/codecs/wm8727.c
+++ b/sound/soc/codecs/wm8727.c
@@ -44,23 +44,16 @@ struct snd_soc_dai wm8727_dai = {
44}; 44};
45EXPORT_SYMBOL_GPL(wm8727_dai); 45EXPORT_SYMBOL_GPL(wm8727_dai);
46 46
47static struct snd_soc_codec *wm8727_codec;
48
47static int wm8727_soc_probe(struct platform_device *pdev) 49static int wm8727_soc_probe(struct platform_device *pdev)
48{ 50{
49 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 51 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
50 struct snd_soc_codec *codec;
51 int ret = 0; 52 int ret = 0;
52 53
53 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); 54 BUG_ON(!wm8727_codec);
54 if (codec == NULL) 55
55 return -ENOMEM; 56 socdev->card->codec = wm8727_codec;
56 mutex_init(&codec->mutex);
57 codec->name = "WM8727";
58 codec->owner = THIS_MODULE;
59 codec->dai = &wm8727_dai;
60 codec->num_dai = 1;
61 socdev->card->codec = codec;
62 INIT_LIST_HEAD(&codec->dapm_widgets);
63 INIT_LIST_HEAD(&codec->dapm_paths);
64 57
65 /* register pcms */ 58 /* register pcms */
66 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 59 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
@@ -80,12 +73,9 @@ pcm_err:
80static int wm8727_soc_remove(struct platform_device *pdev) 73static int wm8727_soc_remove(struct platform_device *pdev)
81{ 74{
82 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 75 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
83 struct snd_soc_codec *codec = socdev->card->codec;
84 76
85 if (codec == NULL)
86 return 0;
87 snd_soc_free_pcms(socdev); 77 snd_soc_free_pcms(socdev);
88 kfree(codec); 78
89 return 0; 79 return 0;
90} 80}
91 81
@@ -98,13 +88,55 @@ EXPORT_SYMBOL_GPL(soc_codec_dev_wm8727);
98 88
99static __devinit int wm8727_platform_probe(struct platform_device *pdev) 89static __devinit int wm8727_platform_probe(struct platform_device *pdev)
100{ 90{
91 struct snd_soc_codec *codec;
92 int ret;
93
94 if (wm8727_codec) {
95 dev_err(&pdev->dev, "Another WM8727 is registered\n");
96 return -EBUSY;
97 }
98
99 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
100 if (codec == NULL)
101 return -ENOMEM;
102 wm8727_codec = codec;
103
104 platform_set_drvdata(pdev, codec);
105
106 mutex_init(&codec->mutex);
107 codec->dev = &pdev->dev;
108 codec->name = "WM8727";
109 codec->owner = THIS_MODULE;
110 codec->dai = &wm8727_dai;
111 codec->num_dai = 1;
112 INIT_LIST_HEAD(&codec->dapm_widgets);
113 INIT_LIST_HEAD(&codec->dapm_paths);
114
101 wm8727_dai.dev = &pdev->dev; 115 wm8727_dai.dev = &pdev->dev;
102 return snd_soc_register_dai(&wm8727_dai); 116
117 ret = snd_soc_register_codec(codec);
118 if (ret != 0) {
119 dev_err(&pdev->dev, "Failed to register CODEC: %d\n", ret);
120 goto err;
121 }
122
123 ret = snd_soc_register_dai(&wm8727_dai);
124 if (ret != 0) {
125 dev_err(&pdev->dev, "Failed to register DAI: %d\n", ret);
126 goto err_codec;
127 }
128
129err_codec:
130 snd_soc_unregister_codec(codec);
131err:
132 kfree(codec);
133 return ret;
103} 134}
104 135
105static int __devexit wm8727_platform_remove(struct platform_device *pdev) 136static int __devexit wm8727_platform_remove(struct platform_device *pdev)
106{ 137{
107 snd_soc_unregister_dai(&wm8727_dai); 138 snd_soc_unregister_dai(&wm8727_dai);
139 snd_soc_unregister_codec(platform_get_drvdata(pdev));
108 return 0; 140 return 0;
109} 141}
110 142
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index 3a497810f939..5a2619dbf283 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -456,6 +456,9 @@ static int wm8731_resume(struct platform_device *pdev)
456 456
457 /* Sync reg_cache with the hardware */ 457 /* Sync reg_cache with the hardware */
458 for (i = 0; i < ARRAY_SIZE(wm8731_reg); i++) { 458 for (i = 0; i < ARRAY_SIZE(wm8731_reg); i++) {
459 if (cache[i] == wm8731_reg[i])
460 continue;
461
459 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001); 462 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
460 data[1] = cache[i] & 0x00ff; 463 data[1] = cache[i] & 0x00ff;
461 codec->hw_write(codec->control_data, data, 2); 464 codec->hw_write(codec->control_data, data, 2);
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index d6850dacda29..c2444e7c8480 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -1507,10 +1507,6 @@ static int wm8753_suspend(struct platform_device *pdev, pm_message_t state)
1507 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1507 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1508 struct snd_soc_codec *codec = socdev->card->codec; 1508 struct snd_soc_codec *codec = socdev->card->codec;
1509 1509
1510 /* we only need to suspend if we are a valid card */
1511 if (!codec->card)
1512 return 0;
1513
1514 wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF); 1510 wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF);
1515 return 0; 1511 return 0;
1516} 1512}
@@ -1523,10 +1519,6 @@ static int wm8753_resume(struct platform_device *pdev)
1523 u8 data[2]; 1519 u8 data[2];
1524 u16 *cache = codec->reg_cache; 1520 u16 *cache = codec->reg_cache;
1525 1521
1526 /* we only need to resume if we are a valid card */
1527 if (!codec->card)
1528 return 0;
1529
1530 /* Sync reg_cache with the hardware */ 1522 /* Sync reg_cache with the hardware */
1531 for (i = 0; i < ARRAY_SIZE(wm8753_reg); i++) { 1523 for (i = 0; i < ARRAY_SIZE(wm8753_reg); i++) {
1532 if (i + 1 == WM8753_RESET) 1524 if (i + 1 == WM8753_RESET)
diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c
index ab2c0da18091..44e7d9d82f87 100644
--- a/sound/soc/codecs/wm8776.c
+++ b/sound/soc/codecs/wm8776.c
@@ -406,6 +406,8 @@ static int wm8776_resume(struct platform_device *pdev)
406 406
407 /* Sync reg_cache with the hardware */ 407 /* Sync reg_cache with the hardware */
408 for (i = 0; i < ARRAY_SIZE(wm8776_reg); i++) { 408 for (i = 0; i < ARRAY_SIZE(wm8776_reg); i++) {
409 if (cache[i] == wm8776_reg[i])
410 continue;
409 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001); 411 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
410 data[1] = cache[i] & 0x00ff; 412 data[1] = cache[i] & 0x00ff;
411 codec->hw_write(codec->control_data, data, 2); 413 codec->hw_write(codec->control_data, data, 2);
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
new file mode 100644
index 000000000000..593e47d0e0eb
--- /dev/null
+++ b/sound/soc/codecs/wm8904.c
@@ -0,0 +1,2656 @@
1/*
2 * wm8904.c -- WM8904 ALSA SoC Audio driver
3 *
4 * Copyright 2009 Wolfson Microelectronics plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.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 version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/module.h>
15#include <linux/moduleparam.h>
16#include <linux/init.h>
17#include <linux/delay.h>
18#include <linux/pm.h>
19#include <linux/i2c.h>
20#include <linux/platform_device.h>
21#include <linux/regulator/consumer.h>
22#include <sound/core.h>
23#include <sound/pcm.h>
24#include <sound/pcm_params.h>
25#include <sound/soc.h>
26#include <sound/soc-dapm.h>
27#include <sound/initval.h>
28#include <sound/tlv.h>
29#include <sound/wm8904.h>
30
31#include "wm8904.h"
32
33static struct snd_soc_codec *wm8904_codec;
34struct snd_soc_codec_device soc_codec_dev_wm8904;
35
36enum wm8904_type {
37 WM8904,
38 WM8912,
39};
40
41#define WM8904_NUM_DCS_CHANNELS 4
42
43#define WM8904_NUM_SUPPLIES 5
44static const char *wm8904_supply_names[WM8904_NUM_SUPPLIES] = {
45 "DCVDD",
46 "DBVDD",
47 "AVDD",
48 "CPVDD",
49 "MICVDD",
50};
51
52/* codec private data */
53struct wm8904_priv {
54 struct snd_soc_codec codec;
55 u16 reg_cache[WM8904_MAX_REGISTER + 1];
56
57 enum wm8904_type devtype;
58
59 struct regulator_bulk_data supplies[WM8904_NUM_SUPPLIES];
60
61 struct wm8904_pdata *pdata;
62
63 int deemph;
64
65 /* Platform provided DRC configuration */
66 const char **drc_texts;
67 int drc_cfg;
68 struct soc_enum drc_enum;
69
70 /* Platform provided ReTune mobile configuration */
71 int num_retune_mobile_texts;
72 const char **retune_mobile_texts;
73 int retune_mobile_cfg;
74 struct soc_enum retune_mobile_enum;
75
76 /* FLL setup */
77 int fll_src;
78 int fll_fref;
79 int fll_fout;
80
81 /* Clocking configuration */
82 unsigned int mclk_rate;
83 int sysclk_src;
84 unsigned int sysclk_rate;
85
86 int tdm_width;
87 int tdm_slots;
88 int bclk;
89 int fs;
90
91 /* DC servo configuration - cached offset values */
92 int dcs_state[WM8904_NUM_DCS_CHANNELS];
93};
94
95static const u16 wm8904_reg[WM8904_MAX_REGISTER + 1] = {
96 0x8904, /* R0 - SW Reset and ID */
97 0x0000, /* R1 - Revision */
98 0x0000, /* R2 */
99 0x0000, /* R3 */
100 0x0018, /* R4 - Bias Control 0 */
101 0x0000, /* R5 - VMID Control 0 */
102 0x0000, /* R6 - Mic Bias Control 0 */
103 0x0000, /* R7 - Mic Bias Control 1 */
104 0x0001, /* R8 - Analogue DAC 0 */
105 0x9696, /* R9 - mic Filter Control */
106 0x0001, /* R10 - Analogue ADC 0 */
107 0x0000, /* R11 */
108 0x0000, /* R12 - Power Management 0 */
109 0x0000, /* R13 */
110 0x0000, /* R14 - Power Management 2 */
111 0x0000, /* R15 - Power Management 3 */
112 0x0000, /* R16 */
113 0x0000, /* R17 */
114 0x0000, /* R18 - Power Management 6 */
115 0x0000, /* R19 */
116 0x945E, /* R20 - Clock Rates 0 */
117 0x0C05, /* R21 - Clock Rates 1 */
118 0x0006, /* R22 - Clock Rates 2 */
119 0x0000, /* R23 */
120 0x0050, /* R24 - Audio Interface 0 */
121 0x000A, /* R25 - Audio Interface 1 */
122 0x00E4, /* R26 - Audio Interface 2 */
123 0x0040, /* R27 - Audio Interface 3 */
124 0x0000, /* R28 */
125 0x0000, /* R29 */
126 0x00C0, /* R30 - DAC Digital Volume Left */
127 0x00C0, /* R31 - DAC Digital Volume Right */
128 0x0000, /* R32 - DAC Digital 0 */
129 0x0008, /* R33 - DAC Digital 1 */
130 0x0000, /* R34 */
131 0x0000, /* R35 */
132 0x00C0, /* R36 - ADC Digital Volume Left */
133 0x00C0, /* R37 - ADC Digital Volume Right */
134 0x0010, /* R38 - ADC Digital 0 */
135 0x0000, /* R39 - Digital Microphone 0 */
136 0x01AF, /* R40 - DRC 0 */
137 0x3248, /* R41 - DRC 1 */
138 0x0000, /* R42 - DRC 2 */
139 0x0000, /* R43 - DRC 3 */
140 0x0085, /* R44 - Analogue Left Input 0 */
141 0x0085, /* R45 - Analogue Right Input 0 */
142 0x0044, /* R46 - Analogue Left Input 1 */
143 0x0044, /* R47 - Analogue Right Input 1 */
144 0x0000, /* R48 */
145 0x0000, /* R49 */
146 0x0000, /* R50 */
147 0x0000, /* R51 */
148 0x0000, /* R52 */
149 0x0000, /* R53 */
150 0x0000, /* R54 */
151 0x0000, /* R55 */
152 0x0000, /* R56 */
153 0x002D, /* R57 - Analogue OUT1 Left */
154 0x002D, /* R58 - Analogue OUT1 Right */
155 0x0039, /* R59 - Analogue OUT2 Left */
156 0x0039, /* R60 - Analogue OUT2 Right */
157 0x0000, /* R61 - Analogue OUT12 ZC */
158 0x0000, /* R62 */
159 0x0000, /* R63 */
160 0x0000, /* R64 */
161 0x0000, /* R65 */
162 0x0000, /* R66 */
163 0x0000, /* R67 - DC Servo 0 */
164 0x0000, /* R68 - DC Servo 1 */
165 0xAAAA, /* R69 - DC Servo 2 */
166 0x0000, /* R70 */
167 0xAAAA, /* R71 - DC Servo 4 */
168 0xAAAA, /* R72 - DC Servo 5 */
169 0x0000, /* R73 - DC Servo 6 */
170 0x0000, /* R74 - DC Servo 7 */
171 0x0000, /* R75 - DC Servo 8 */
172 0x0000, /* R76 - DC Servo 9 */
173 0x0000, /* R77 - DC Servo Readback 0 */
174 0x0000, /* R78 */
175 0x0000, /* R79 */
176 0x0000, /* R80 */
177 0x0000, /* R81 */
178 0x0000, /* R82 */
179 0x0000, /* R83 */
180 0x0000, /* R84 */
181 0x0000, /* R85 */
182 0x0000, /* R86 */
183 0x0000, /* R87 */
184 0x0000, /* R88 */
185 0x0000, /* R89 */
186 0x0000, /* R90 - Analogue HP 0 */
187 0x0000, /* R91 */
188 0x0000, /* R92 */
189 0x0000, /* R93 */
190 0x0000, /* R94 - Analogue Lineout 0 */
191 0x0000, /* R95 */
192 0x0000, /* R96 */
193 0x0000, /* R97 */
194 0x0000, /* R98 - Charge Pump 0 */
195 0x0000, /* R99 */
196 0x0000, /* R100 */
197 0x0000, /* R101 */
198 0x0000, /* R102 */
199 0x0000, /* R103 */
200 0x0004, /* R104 - Class W 0 */
201 0x0000, /* R105 */
202 0x0000, /* R106 */
203 0x0000, /* R107 */
204 0x0000, /* R108 - Write Sequencer 0 */
205 0x0000, /* R109 - Write Sequencer 1 */
206 0x0000, /* R110 - Write Sequencer 2 */
207 0x0000, /* R111 - Write Sequencer 3 */
208 0x0000, /* R112 - Write Sequencer 4 */
209 0x0000, /* R113 */
210 0x0000, /* R114 */
211 0x0000, /* R115 */
212 0x0000, /* R116 - FLL Control 1 */
213 0x0007, /* R117 - FLL Control 2 */
214 0x0000, /* R118 - FLL Control 3 */
215 0x2EE0, /* R119 - FLL Control 4 */
216 0x0004, /* R120 - FLL Control 5 */
217 0x0014, /* R121 - GPIO Control 1 */
218 0x0010, /* R122 - GPIO Control 2 */
219 0x0010, /* R123 - GPIO Control 3 */
220 0x0000, /* R124 - GPIO Control 4 */
221 0x0000, /* R125 */
222 0x0000, /* R126 - Digital Pulls */
223 0x0000, /* R127 - Interrupt Status */
224 0xFFFF, /* R128 - Interrupt Status Mask */
225 0x0000, /* R129 - Interrupt Polarity */
226 0x0000, /* R130 - Interrupt Debounce */
227 0x0000, /* R131 */
228 0x0000, /* R132 */
229 0x0000, /* R133 */
230 0x0000, /* R134 - EQ1 */
231 0x000C, /* R135 - EQ2 */
232 0x000C, /* R136 - EQ3 */
233 0x000C, /* R137 - EQ4 */
234 0x000C, /* R138 - EQ5 */
235 0x000C, /* R139 - EQ6 */
236 0x0FCA, /* R140 - EQ7 */
237 0x0400, /* R141 - EQ8 */
238 0x00D8, /* R142 - EQ9 */
239 0x1EB5, /* R143 - EQ10 */
240 0xF145, /* R144 - EQ11 */
241 0x0B75, /* R145 - EQ12 */
242 0x01C5, /* R146 - EQ13 */
243 0x1C58, /* R147 - EQ14 */
244 0xF373, /* R148 - EQ15 */
245 0x0A54, /* R149 - EQ16 */
246 0x0558, /* R150 - EQ17 */
247 0x168E, /* R151 - EQ18 */
248 0xF829, /* R152 - EQ19 */
249 0x07AD, /* R153 - EQ20 */
250 0x1103, /* R154 - EQ21 */
251 0x0564, /* R155 - EQ22 */
252 0x0559, /* R156 - EQ23 */
253 0x4000, /* R157 - EQ24 */
254 0x0000, /* R158 */
255 0x0000, /* R159 */
256 0x0000, /* R160 */
257 0x0000, /* R161 - Control Interface Test 1 */
258 0x0000, /* R162 */
259 0x0000, /* R163 */
260 0x0000, /* R164 */
261 0x0000, /* R165 */
262 0x0000, /* R166 */
263 0x0000, /* R167 */
264 0x0000, /* R168 */
265 0x0000, /* R169 */
266 0x0000, /* R170 */
267 0x0000, /* R171 */
268 0x0000, /* R172 */
269 0x0000, /* R173 */
270 0x0000, /* R174 */
271 0x0000, /* R175 */
272 0x0000, /* R176 */
273 0x0000, /* R177 */
274 0x0000, /* R178 */
275 0x0000, /* R179 */
276 0x0000, /* R180 */
277 0x0000, /* R181 */
278 0x0000, /* R182 */
279 0x0000, /* R183 */
280 0x0000, /* R184 */
281 0x0000, /* R185 */
282 0x0000, /* R186 */
283 0x0000, /* R187 */
284 0x0000, /* R188 */
285 0x0000, /* R189 */
286 0x0000, /* R190 */
287 0x0000, /* R191 */
288 0x0000, /* R192 */
289 0x0000, /* R193 */
290 0x0000, /* R194 */
291 0x0000, /* R195 */
292 0x0000, /* R196 */
293 0x0000, /* R197 */
294 0x0000, /* R198 */
295 0x0000, /* R199 */
296 0x0000, /* R200 */
297 0x0000, /* R201 */
298 0x0000, /* R202 */
299 0x0000, /* R203 */
300 0x0000, /* R204 - Analogue Output Bias 0 */
301 0x0000, /* R205 */
302 0x0000, /* R206 */
303 0x0000, /* R207 */
304 0x0000, /* R208 */
305 0x0000, /* R209 */
306 0x0000, /* R210 */
307 0x0000, /* R211 */
308 0x0000, /* R212 */
309 0x0000, /* R213 */
310 0x0000, /* R214 */
311 0x0000, /* R215 */
312 0x0000, /* R216 */
313 0x0000, /* R217 */
314 0x0000, /* R218 */
315 0x0000, /* R219 */
316 0x0000, /* R220 */
317 0x0000, /* R221 */
318 0x0000, /* R222 */
319 0x0000, /* R223 */
320 0x0000, /* R224 */
321 0x0000, /* R225 */
322 0x0000, /* R226 */
323 0x0000, /* R227 */
324 0x0000, /* R228 */
325 0x0000, /* R229 */
326 0x0000, /* R230 */
327 0x0000, /* R231 */
328 0x0000, /* R232 */
329 0x0000, /* R233 */
330 0x0000, /* R234 */
331 0x0000, /* R235 */
332 0x0000, /* R236 */
333 0x0000, /* R237 */
334 0x0000, /* R238 */
335 0x0000, /* R239 */
336 0x0000, /* R240 */
337 0x0000, /* R241 */
338 0x0000, /* R242 */
339 0x0000, /* R243 */
340 0x0000, /* R244 */
341 0x0000, /* R245 */
342 0x0000, /* R246 */
343 0x0000, /* R247 - FLL NCO Test 0 */
344 0x0019, /* R248 - FLL NCO Test 1 */
345};
346
347static struct {
348 int readable;
349 int writable;
350 int vol;
351} wm8904_access[] = {
352 { 0xFFFF, 0xFFFF, 1 }, /* R0 - SW Reset and ID */
353 { 0x0000, 0x0000, 0 }, /* R1 - Revision */
354 { 0x0000, 0x0000, 0 }, /* R2 */
355 { 0x0000, 0x0000, 0 }, /* R3 */
356 { 0x001F, 0x001F, 0 }, /* R4 - Bias Control 0 */
357 { 0x0047, 0x0047, 0 }, /* R5 - VMID Control 0 */
358 { 0x007F, 0x007F, 0 }, /* R6 - Mic Bias Control 0 */
359 { 0xC007, 0xC007, 0 }, /* R7 - Mic Bias Control 1 */
360 { 0x001E, 0x001E, 0 }, /* R8 - Analogue DAC 0 */
361 { 0xFFFF, 0xFFFF, 0 }, /* R9 - mic Filter Control */
362 { 0x0001, 0x0001, 0 }, /* R10 - Analogue ADC 0 */
363 { 0x0000, 0x0000, 0 }, /* R11 */
364 { 0x0003, 0x0003, 0 }, /* R12 - Power Management 0 */
365 { 0x0000, 0x0000, 0 }, /* R13 */
366 { 0x0003, 0x0003, 0 }, /* R14 - Power Management 2 */
367 { 0x0003, 0x0003, 0 }, /* R15 - Power Management 3 */
368 { 0x0000, 0x0000, 0 }, /* R16 */
369 { 0x0000, 0x0000, 0 }, /* R17 */
370 { 0x000F, 0x000F, 0 }, /* R18 - Power Management 6 */
371 { 0x0000, 0x0000, 0 }, /* R19 */
372 { 0x7001, 0x7001, 0 }, /* R20 - Clock Rates 0 */
373 { 0x3C07, 0x3C07, 0 }, /* R21 - Clock Rates 1 */
374 { 0xD00F, 0xD00F, 0 }, /* R22 - Clock Rates 2 */
375 { 0x0000, 0x0000, 0 }, /* R23 */
376 { 0x1FFF, 0x1FFF, 0 }, /* R24 - Audio Interface 0 */
377 { 0x3DDF, 0x3DDF, 0 }, /* R25 - Audio Interface 1 */
378 { 0x0F1F, 0x0F1F, 0 }, /* R26 - Audio Interface 2 */
379 { 0x0FFF, 0x0FFF, 0 }, /* R27 - Audio Interface 3 */
380 { 0x0000, 0x0000, 0 }, /* R28 */
381 { 0x0000, 0x0000, 0 }, /* R29 */
382 { 0x00FF, 0x01FF, 0 }, /* R30 - DAC Digital Volume Left */
383 { 0x00FF, 0x01FF, 0 }, /* R31 - DAC Digital Volume Right */
384 { 0x0FFF, 0x0FFF, 0 }, /* R32 - DAC Digital 0 */
385 { 0x1E4E, 0x1E4E, 0 }, /* R33 - DAC Digital 1 */
386 { 0x0000, 0x0000, 0 }, /* R34 */
387 { 0x0000, 0x0000, 0 }, /* R35 */
388 { 0x00FF, 0x01FF, 0 }, /* R36 - ADC Digital Volume Left */
389 { 0x00FF, 0x01FF, 0 }, /* R37 - ADC Digital Volume Right */
390 { 0x0073, 0x0073, 0 }, /* R38 - ADC Digital 0 */
391 { 0x1800, 0x1800, 0 }, /* R39 - Digital Microphone 0 */
392 { 0xDFEF, 0xDFEF, 0 }, /* R40 - DRC 0 */
393 { 0xFFFF, 0xFFFF, 0 }, /* R41 - DRC 1 */
394 { 0x003F, 0x003F, 0 }, /* R42 - DRC 2 */
395 { 0x07FF, 0x07FF, 0 }, /* R43 - DRC 3 */
396 { 0x009F, 0x009F, 0 }, /* R44 - Analogue Left Input 0 */
397 { 0x009F, 0x009F, 0 }, /* R45 - Analogue Right Input 0 */
398 { 0x007F, 0x007F, 0 }, /* R46 - Analogue Left Input 1 */
399 { 0x007F, 0x007F, 0 }, /* R47 - Analogue Right Input 1 */
400 { 0x0000, 0x0000, 0 }, /* R48 */
401 { 0x0000, 0x0000, 0 }, /* R49 */
402 { 0x0000, 0x0000, 0 }, /* R50 */
403 { 0x0000, 0x0000, 0 }, /* R51 */
404 { 0x0000, 0x0000, 0 }, /* R52 */
405 { 0x0000, 0x0000, 0 }, /* R53 */
406 { 0x0000, 0x0000, 0 }, /* R54 */
407 { 0x0000, 0x0000, 0 }, /* R55 */
408 { 0x0000, 0x0000, 0 }, /* R56 */
409 { 0x017F, 0x01FF, 0 }, /* R57 - Analogue OUT1 Left */
410 { 0x017F, 0x01FF, 0 }, /* R58 - Analogue OUT1 Right */
411 { 0x017F, 0x01FF, 0 }, /* R59 - Analogue OUT2 Left */
412 { 0x017F, 0x01FF, 0 }, /* R60 - Analogue OUT2 Right */
413 { 0x000F, 0x000F, 0 }, /* R61 - Analogue OUT12 ZC */
414 { 0x0000, 0x0000, 0 }, /* R62 */
415 { 0x0000, 0x0000, 0 }, /* R63 */
416 { 0x0000, 0x0000, 0 }, /* R64 */
417 { 0x0000, 0x0000, 0 }, /* R65 */
418 { 0x0000, 0x0000, 0 }, /* R66 */
419 { 0x000F, 0x000F, 0 }, /* R67 - DC Servo 0 */
420 { 0xFFFF, 0xFFFF, 1 }, /* R68 - DC Servo 1 */
421 { 0x0F0F, 0x0F0F, 0 }, /* R69 - DC Servo 2 */
422 { 0x0000, 0x0000, 0 }, /* R70 */
423 { 0x007F, 0x007F, 0 }, /* R71 - DC Servo 4 */
424 { 0x007F, 0x007F, 0 }, /* R72 - DC Servo 5 */
425 { 0x00FF, 0x00FF, 1 }, /* R73 - DC Servo 6 */
426 { 0x00FF, 0x00FF, 1 }, /* R74 - DC Servo 7 */
427 { 0x00FF, 0x00FF, 1 }, /* R75 - DC Servo 8 */
428 { 0x00FF, 0x00FF, 1 }, /* R76 - DC Servo 9 */
429 { 0x0FFF, 0x0000, 1 }, /* R77 - DC Servo Readback 0 */
430 { 0x0000, 0x0000, 0 }, /* R78 */
431 { 0x0000, 0x0000, 0 }, /* R79 */
432 { 0x0000, 0x0000, 0 }, /* R80 */
433 { 0x0000, 0x0000, 0 }, /* R81 */
434 { 0x0000, 0x0000, 0 }, /* R82 */
435 { 0x0000, 0x0000, 0 }, /* R83 */
436 { 0x0000, 0x0000, 0 }, /* R84 */
437 { 0x0000, 0x0000, 0 }, /* R85 */
438 { 0x0000, 0x0000, 0 }, /* R86 */
439 { 0x0000, 0x0000, 0 }, /* R87 */
440 { 0x0000, 0x0000, 0 }, /* R88 */
441 { 0x0000, 0x0000, 0 }, /* R89 */
442 { 0x00FF, 0x00FF, 0 }, /* R90 - Analogue HP 0 */
443 { 0x0000, 0x0000, 0 }, /* R91 */
444 { 0x0000, 0x0000, 0 }, /* R92 */
445 { 0x0000, 0x0000, 0 }, /* R93 */
446 { 0x00FF, 0x00FF, 0 }, /* R94 - Analogue Lineout 0 */
447 { 0x0000, 0x0000, 0 }, /* R95 */
448 { 0x0000, 0x0000, 0 }, /* R96 */
449 { 0x0000, 0x0000, 0 }, /* R97 */
450 { 0x0001, 0x0001, 0 }, /* R98 - Charge Pump 0 */
451 { 0x0000, 0x0000, 0 }, /* R99 */
452 { 0x0000, 0x0000, 0 }, /* R100 */
453 { 0x0000, 0x0000, 0 }, /* R101 */
454 { 0x0000, 0x0000, 0 }, /* R102 */
455 { 0x0000, 0x0000, 0 }, /* R103 */
456 { 0x0001, 0x0001, 0 }, /* R104 - Class W 0 */
457 { 0x0000, 0x0000, 0 }, /* R105 */
458 { 0x0000, 0x0000, 0 }, /* R106 */
459 { 0x0000, 0x0000, 0 }, /* R107 */
460 { 0x011F, 0x011F, 0 }, /* R108 - Write Sequencer 0 */
461 { 0x7FFF, 0x7FFF, 0 }, /* R109 - Write Sequencer 1 */
462 { 0x4FFF, 0x4FFF, 0 }, /* R110 - Write Sequencer 2 */
463 { 0x003F, 0x033F, 0 }, /* R111 - Write Sequencer 3 */
464 { 0x03F1, 0x0000, 0 }, /* R112 - Write Sequencer 4 */
465 { 0x0000, 0x0000, 0 }, /* R113 */
466 { 0x0000, 0x0000, 0 }, /* R114 */
467 { 0x0000, 0x0000, 0 }, /* R115 */
468 { 0x0007, 0x0007, 0 }, /* R116 - FLL Control 1 */
469 { 0x3F77, 0x3F77, 0 }, /* R117 - FLL Control 2 */
470 { 0xFFFF, 0xFFFF, 0 }, /* R118 - FLL Control 3 */
471 { 0x7FEF, 0x7FEF, 0 }, /* R119 - FLL Control 4 */
472 { 0x001B, 0x001B, 0 }, /* R120 - FLL Control 5 */
473 { 0x003F, 0x003F, 0 }, /* R121 - GPIO Control 1 */
474 { 0x003F, 0x003F, 0 }, /* R122 - GPIO Control 2 */
475 { 0x003F, 0x003F, 0 }, /* R123 - GPIO Control 3 */
476 { 0x038F, 0x038F, 0 }, /* R124 - GPIO Control 4 */
477 { 0x0000, 0x0000, 0 }, /* R125 */
478 { 0x00FF, 0x00FF, 0 }, /* R126 - Digital Pulls */
479 { 0x07FF, 0x03FF, 1 }, /* R127 - Interrupt Status */
480 { 0x03FF, 0x03FF, 0 }, /* R128 - Interrupt Status Mask */
481 { 0x03FF, 0x03FF, 0 }, /* R129 - Interrupt Polarity */
482 { 0x03FF, 0x03FF, 0 }, /* R130 - Interrupt Debounce */
483 { 0x0000, 0x0000, 0 }, /* R131 */
484 { 0x0000, 0x0000, 0 }, /* R132 */
485 { 0x0000, 0x0000, 0 }, /* R133 */
486 { 0x0001, 0x0001, 0 }, /* R134 - EQ1 */
487 { 0x001F, 0x001F, 0 }, /* R135 - EQ2 */
488 { 0x001F, 0x001F, 0 }, /* R136 - EQ3 */
489 { 0x001F, 0x001F, 0 }, /* R137 - EQ4 */
490 { 0x001F, 0x001F, 0 }, /* R138 - EQ5 */
491 { 0x001F, 0x001F, 0 }, /* R139 - EQ6 */
492 { 0xFFFF, 0xFFFF, 0 }, /* R140 - EQ7 */
493 { 0xFFFF, 0xFFFF, 0 }, /* R141 - EQ8 */
494 { 0xFFFF, 0xFFFF, 0 }, /* R142 - EQ9 */
495 { 0xFFFF, 0xFFFF, 0 }, /* R143 - EQ10 */
496 { 0xFFFF, 0xFFFF, 0 }, /* R144 - EQ11 */
497 { 0xFFFF, 0xFFFF, 0 }, /* R145 - EQ12 */
498 { 0xFFFF, 0xFFFF, 0 }, /* R146 - EQ13 */
499 { 0xFFFF, 0xFFFF, 0 }, /* R147 - EQ14 */
500 { 0xFFFF, 0xFFFF, 0 }, /* R148 - EQ15 */
501 { 0xFFFF, 0xFFFF, 0 }, /* R149 - EQ16 */
502 { 0xFFFF, 0xFFFF, 0 }, /* R150 - EQ17 */
503 { 0xFFFF, 0xFFFF, 0 }, /* R151wm8523_dai - EQ18 */
504 { 0xFFFF, 0xFFFF, 0 }, /* R152 - EQ19 */
505 { 0xFFFF, 0xFFFF, 0 }, /* R153 - EQ20 */
506 { 0xFFFF, 0xFFFF, 0 }, /* R154 - EQ21 */
507 { 0xFFFF, 0xFFFF, 0 }, /* R155 - EQ22 */
508 { 0xFFFF, 0xFFFF, 0 }, /* R156 - EQ23 */
509 { 0xFFFF, 0xFFFF, 0 }, /* R157 - EQ24 */
510 { 0x0000, 0x0000, 0 }, /* R158 */
511 { 0x0000, 0x0000, 0 }, /* R159 */
512 { 0x0000, 0x0000, 0 }, /* R160 */
513 { 0x0002, 0x0002, 0 }, /* R161 - Control Interface Test 1 */
514 { 0x0000, 0x0000, 0 }, /* R162 */
515 { 0x0000, 0x0000, 0 }, /* R163 */
516 { 0x0000, 0x0000, 0 }, /* R164 */
517 { 0x0000, 0x0000, 0 }, /* R165 */
518 { 0x0000, 0x0000, 0 }, /* R166 */
519 { 0x0000, 0x0000, 0 }, /* R167 */
520 { 0x0000, 0x0000, 0 }, /* R168 */
521 { 0x0000, 0x0000, 0 }, /* R169 */
522 { 0x0000, 0x0000, 0 }, /* R170 */
523 { 0x0000, 0x0000, 0 }, /* R171 */
524 { 0x0000, 0x0000, 0 }, /* R172 */
525 { 0x0000, 0x0000, 0 }, /* R173 */
526 { 0x0000, 0x0000, 0 }, /* R174 */
527 { 0x0000, 0x0000, 0 }, /* R175 */
528 { 0x0000, 0x0000, 0 }, /* R176 */
529 { 0x0000, 0x0000, 0 }, /* R177 */
530 { 0x0000, 0x0000, 0 }, /* R178 */
531 { 0x0000, 0x0000, 0 }, /* R179 */
532 { 0x0000, 0x0000, 0 }, /* R180 */
533 { 0x0000, 0x0000, 0 }, /* R181 */
534 { 0x0000, 0x0000, 0 }, /* R182 */
535 { 0x0000, 0x0000, 0 }, /* R183 */
536 { 0x0000, 0x0000, 0 }, /* R184 */
537 { 0x0000, 0x0000, 0 }, /* R185 */
538 { 0x0000, 0x0000, 0 }, /* R186 */
539 { 0x0000, 0x0000, 0 }, /* R187 */
540 { 0x0000, 0x0000, 0 }, /* R188 */
541 { 0x0000, 0x0000, 0 }, /* R189 */
542 { 0x0000, 0x0000, 0 }, /* R190 */
543 { 0x0000, 0x0000, 0 }, /* R191 */
544 { 0x0000, 0x0000, 0 }, /* R192 */
545 { 0x0000, 0x0000, 0 }, /* R193 */
546 { 0x0000, 0x0000, 0 }, /* R194 */
547 { 0x0000, 0x0000, 0 }, /* R195 */
548 { 0x0000, 0x0000, 0 }, /* R196 */
549 { 0x0000, 0x0000, 0 }, /* R197 */
550 { 0x0000, 0x0000, 0 }, /* R198 */
551 { 0x0000, 0x0000, 0 }, /* R199 */
552 { 0x0000, 0x0000, 0 }, /* R200 */
553 { 0x0000, 0x0000, 0 }, /* R201 */
554 { 0x0000, 0x0000, 0 }, /* R202 */
555 { 0x0000, 0x0000, 0 }, /* R203 */
556 { 0x0070, 0x0070, 0 }, /* R204 - Analogue Output Bias 0 */
557 { 0x0000, 0x0000, 0 }, /* R205 */
558 { 0x0000, 0x0000, 0 }, /* R206 */
559 { 0x0000, 0x0000, 0 }, /* R207 */
560 { 0x0000, 0x0000, 0 }, /* R208 */
561 { 0x0000, 0x0000, 0 }, /* R209 */
562 { 0x0000, 0x0000, 0 }, /* R210 */
563 { 0x0000, 0x0000, 0 }, /* R211 */
564 { 0x0000, 0x0000, 0 }, /* R212 */
565 { 0x0000, 0x0000, 0 }, /* R213 */
566 { 0x0000, 0x0000, 0 }, /* R214 */
567 { 0x0000, 0x0000, 0 }, /* R215 */
568 { 0x0000, 0x0000, 0 }, /* R216 */
569 { 0x0000, 0x0000, 0 }, /* R217 */
570 { 0x0000, 0x0000, 0 }, /* R218 */
571 { 0x0000, 0x0000, 0 }, /* R219 */
572 { 0x0000, 0x0000, 0 }, /* R220 */
573 { 0x0000, 0x0000, 0 }, /* R221 */
574 { 0x0000, 0x0000, 0 }, /* R222 */
575 { 0x0000, 0x0000, 0 }, /* R223 */
576 { 0x0000, 0x0000, 0 }, /* R224 */
577 { 0x0000, 0x0000, 0 }, /* R225 */
578 { 0x0000, 0x0000, 0 }, /* R226 */
579 { 0x0000, 0x0000, 0 }, /* R227 */
580 { 0x0000, 0x0000, 0 }, /* R228 */
581 { 0x0000, 0x0000, 0 }, /* R229 */
582 { 0x0000, 0x0000, 0 }, /* R230 */
583 { 0x0000, 0x0000, 0 }, /* R231 */
584 { 0x0000, 0x0000, 0 }, /* R232 */
585 { 0x0000, 0x0000, 0 }, /* R233 */
586 { 0x0000, 0x0000, 0 }, /* R234 */
587 { 0x0000, 0x0000, 0 }, /* R235 */
588 { 0x0000, 0x0000, 0 }, /* R236 */
589 { 0x0000, 0x0000, 0 }, /* R237 */
590 { 0x0000, 0x0000, 0 }, /* R238 */
591 { 0x0000, 0x0000, 0 }, /* R239 */
592 { 0x0000, 0x0000, 0 }, /* R240 */
593 { 0x0000, 0x0000, 0 }, /* R241 */
594 { 0x0000, 0x0000, 0 }, /* R242 */
595 { 0x0000, 0x0000, 0 }, /* R243 */
596 { 0x0000, 0x0000, 0 }, /* R244 */
597 { 0x0000, 0x0000, 0 }, /* R245 */
598 { 0x0000, 0x0000, 0 }, /* R246 */
599 { 0x0001, 0x0001, 0 }, /* R247 - FLL NCO Test 0 */
600 { 0x003F, 0x003F, 0 }, /* R248 - FLL NCO Test 1 */
601};
602
603static int wm8904_volatile_register(unsigned int reg)
604{
605 return wm8904_access[reg].vol;
606}
607
608static int wm8904_reset(struct snd_soc_codec *codec)
609{
610 return snd_soc_write(codec, WM8904_SW_RESET_AND_ID, 0);
611}
612
613static int wm8904_configure_clocking(struct snd_soc_codec *codec)
614{
615 struct wm8904_priv *wm8904 = codec->private_data;
616 unsigned int clock0, clock2, rate;
617
618 /* Gate the clock while we're updating to avoid misclocking */
619 clock2 = snd_soc_read(codec, WM8904_CLOCK_RATES_2);
620 snd_soc_update_bits(codec, WM8904_CLOCK_RATES_2,
621 WM8904_SYSCLK_SRC, 0);
622
623 /* This should be done on init() for bypass paths */
624 switch (wm8904->sysclk_src) {
625 case WM8904_CLK_MCLK:
626 dev_dbg(codec->dev, "Using %dHz MCLK\n", wm8904->mclk_rate);
627
628 clock2 &= ~WM8904_SYSCLK_SRC;
629 rate = wm8904->mclk_rate;
630
631 /* Ensure the FLL is stopped */
632 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
633 WM8904_FLL_OSC_ENA | WM8904_FLL_ENA, 0);
634 break;
635
636 case WM8904_CLK_FLL:
637 dev_dbg(codec->dev, "Using %dHz FLL clock\n",
638 wm8904->fll_fout);
639
640 clock2 |= WM8904_SYSCLK_SRC;
641 rate = wm8904->fll_fout;
642 break;
643
644 default:
645 dev_err(codec->dev, "System clock not configured\n");
646 return -EINVAL;
647 }
648
649 /* SYSCLK shouldn't be over 13.5MHz */
650 if (rate > 13500000) {
651 clock0 = WM8904_MCLK_DIV;
652 wm8904->sysclk_rate = rate / 2;
653 } else {
654 clock0 = 0;
655 wm8904->sysclk_rate = rate;
656 }
657
658 snd_soc_update_bits(codec, WM8904_CLOCK_RATES_0, WM8904_MCLK_DIV,
659 clock0);
660
661 snd_soc_update_bits(codec, WM8904_CLOCK_RATES_2,
662 WM8904_CLK_SYS_ENA | WM8904_SYSCLK_SRC, clock2);
663
664 dev_dbg(codec->dev, "CLK_SYS is %dHz\n", wm8904->sysclk_rate);
665
666 return 0;
667}
668
669static void wm8904_set_drc(struct snd_soc_codec *codec)
670{
671 struct wm8904_priv *wm8904 = codec->private_data;
672 struct wm8904_pdata *pdata = wm8904->pdata;
673 int save, i;
674
675 /* Save any enables; the configuration should clear them. */
676 save = snd_soc_read(codec, WM8904_DRC_0);
677
678 for (i = 0; i < WM8904_DRC_REGS; i++)
679 snd_soc_update_bits(codec, WM8904_DRC_0 + i, 0xffff,
680 pdata->drc_cfgs[wm8904->drc_cfg].regs[i]);
681
682 /* Reenable the DRC */
683 snd_soc_update_bits(codec, WM8904_DRC_0,
684 WM8904_DRC_ENA | WM8904_DRC_DAC_PATH, save);
685}
686
687static int wm8904_put_drc_enum(struct snd_kcontrol *kcontrol,
688 struct snd_ctl_elem_value *ucontrol)
689{
690 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
691 struct wm8904_priv *wm8904 = codec->private_data;
692 struct wm8904_pdata *pdata = wm8904->pdata;
693 int value = ucontrol->value.integer.value[0];
694
695 if (value >= pdata->num_drc_cfgs)
696 return -EINVAL;
697
698 wm8904->drc_cfg = value;
699
700 wm8904_set_drc(codec);
701
702 return 0;
703}
704
705static int wm8904_get_drc_enum(struct snd_kcontrol *kcontrol,
706 struct snd_ctl_elem_value *ucontrol)
707{
708 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
709 struct wm8904_priv *wm8904 = codec->private_data;
710
711 ucontrol->value.enumerated.item[0] = wm8904->drc_cfg;
712
713 return 0;
714}
715
716static void wm8904_set_retune_mobile(struct snd_soc_codec *codec)
717{
718 struct wm8904_priv *wm8904 = codec->private_data;
719 struct wm8904_pdata *pdata = wm8904->pdata;
720 int best, best_val, save, i, cfg;
721
722 if (!pdata || !wm8904->num_retune_mobile_texts)
723 return;
724
725 /* Find the version of the currently selected configuration
726 * with the nearest sample rate. */
727 cfg = wm8904->retune_mobile_cfg;
728 best = 0;
729 best_val = INT_MAX;
730 for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) {
731 if (strcmp(pdata->retune_mobile_cfgs[i].name,
732 wm8904->retune_mobile_texts[cfg]) == 0 &&
733 abs(pdata->retune_mobile_cfgs[i].rate
734 - wm8904->fs) < best_val) {
735 best = i;
736 best_val = abs(pdata->retune_mobile_cfgs[i].rate
737 - wm8904->fs);
738 }
739 }
740
741 dev_dbg(codec->dev, "ReTune Mobile %s/%dHz for %dHz sample rate\n",
742 pdata->retune_mobile_cfgs[best].name,
743 pdata->retune_mobile_cfgs[best].rate,
744 wm8904->fs);
745
746 /* The EQ will be disabled while reconfiguring it, remember the
747 * current configuration.
748 */
749 save = snd_soc_read(codec, WM8904_EQ1);
750
751 for (i = 0; i < WM8904_EQ_REGS; i++)
752 snd_soc_update_bits(codec, WM8904_EQ1 + i, 0xffff,
753 pdata->retune_mobile_cfgs[best].regs[i]);
754
755 snd_soc_update_bits(codec, WM8904_EQ1, WM8904_EQ_ENA, save);
756}
757
758static int wm8904_put_retune_mobile_enum(struct snd_kcontrol *kcontrol,
759 struct snd_ctl_elem_value *ucontrol)
760{
761 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
762 struct wm8904_priv *wm8904 = codec->private_data;
763 struct wm8904_pdata *pdata = wm8904->pdata;
764 int value = ucontrol->value.integer.value[0];
765
766 if (value >= pdata->num_retune_mobile_cfgs)
767 return -EINVAL;
768
769 wm8904->retune_mobile_cfg = value;
770
771 wm8904_set_retune_mobile(codec);
772
773 return 0;
774}
775
776static int wm8904_get_retune_mobile_enum(struct snd_kcontrol *kcontrol,
777 struct snd_ctl_elem_value *ucontrol)
778{
779 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
780 struct wm8904_priv *wm8904 = codec->private_data;
781
782 ucontrol->value.enumerated.item[0] = wm8904->retune_mobile_cfg;
783
784 return 0;
785}
786
787static int deemph_settings[] = { 0, 32000, 44100, 48000 };
788
789static int wm8904_set_deemph(struct snd_soc_codec *codec)
790{
791 struct wm8904_priv *wm8904 = codec->private_data;
792 int val, i, best;
793
794 /* If we're using deemphasis select the nearest available sample
795 * rate.
796 */
797 if (wm8904->deemph) {
798 best = 1;
799 for (i = 2; i < ARRAY_SIZE(deemph_settings); i++) {
800 if (abs(deemph_settings[i] - wm8904->fs) <
801 abs(deemph_settings[best] - wm8904->fs))
802 best = i;
803 }
804
805 val = best << WM8904_DEEMPH_SHIFT;
806 } else {
807 val = 0;
808 }
809
810 dev_dbg(codec->dev, "Set deemphasis %d\n", val);
811
812 return snd_soc_update_bits(codec, WM8904_DAC_DIGITAL_1,
813 WM8904_DEEMPH_MASK, val);
814}
815
816static int wm8904_get_deemph(struct snd_kcontrol *kcontrol,
817 struct snd_ctl_elem_value *ucontrol)
818{
819 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
820 struct wm8904_priv *wm8904 = codec->private_data;
821
822 return wm8904->deemph;
823}
824
825static int wm8904_put_deemph(struct snd_kcontrol *kcontrol,
826 struct snd_ctl_elem_value *ucontrol)
827{
828 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
829 struct wm8904_priv *wm8904 = codec->private_data;
830 int deemph = ucontrol->value.enumerated.item[0];
831
832 if (deemph > 1)
833 return -EINVAL;
834
835 wm8904->deemph = deemph;
836
837 return wm8904_set_deemph(codec);
838}
839
840static const DECLARE_TLV_DB_SCALE(dac_boost_tlv, 0, 600, 0);
841static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
842static const DECLARE_TLV_DB_SCALE(out_tlv, -5700, 100, 0);
843static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -3600, 300, 0);
844static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
845
846static const char *input_mode_text[] = {
847 "Single-Ended", "Differential Line", "Differential Mic"
848};
849
850static const struct soc_enum lin_mode =
851 SOC_ENUM_SINGLE(WM8904_ANALOGUE_LEFT_INPUT_1, 0, 3, input_mode_text);
852
853static const struct soc_enum rin_mode =
854 SOC_ENUM_SINGLE(WM8904_ANALOGUE_RIGHT_INPUT_1, 0, 3, input_mode_text);
855
856static const char *hpf_mode_text[] = {
857 "Hi-fi", "Voice 1", "Voice 2", "Voice 3"
858};
859
860static const struct soc_enum hpf_mode =
861 SOC_ENUM_SINGLE(WM8904_ADC_DIGITAL_0, 5, 4, hpf_mode_text);
862
863static const struct snd_kcontrol_new wm8904_adc_snd_controls[] = {
864SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8904_ADC_DIGITAL_VOLUME_LEFT,
865 WM8904_ADC_DIGITAL_VOLUME_RIGHT, 1, 119, 0, digital_tlv),
866
867SOC_ENUM("Left Caputure Mode", lin_mode),
868SOC_ENUM("Right Capture Mode", rin_mode),
869
870/* No TLV since it depends on mode */
871SOC_DOUBLE_R("Capture Volume", WM8904_ANALOGUE_LEFT_INPUT_0,
872 WM8904_ANALOGUE_RIGHT_INPUT_0, 0, 31, 0),
873SOC_DOUBLE_R("Capture Switch", WM8904_ANALOGUE_LEFT_INPUT_0,
874 WM8904_ANALOGUE_RIGHT_INPUT_0, 7, 1, 0),
875
876SOC_SINGLE("High Pass Filter Switch", WM8904_ADC_DIGITAL_0, 4, 1, 0),
877SOC_ENUM("High Pass Filter Mode", hpf_mode),
878
879SOC_SINGLE("ADC 128x OSR Switch", WM8904_ANALOGUE_ADC_0, 0, 1, 0),
880};
881
882static const char *drc_path_text[] = {
883 "ADC", "DAC"
884};
885
886static const struct soc_enum drc_path =
887 SOC_ENUM_SINGLE(WM8904_DRC_0, 14, 2, drc_path_text);
888
889static const struct snd_kcontrol_new wm8904_dac_snd_controls[] = {
890SOC_SINGLE_TLV("Digital Playback Boost Volume",
891 WM8904_AUDIO_INTERFACE_0, 9, 3, 0, dac_boost_tlv),
892SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8904_DAC_DIGITAL_VOLUME_LEFT,
893 WM8904_DAC_DIGITAL_VOLUME_RIGHT, 1, 96, 0, digital_tlv),
894
895SOC_DOUBLE_R_TLV("Headphone Volume", WM8904_ANALOGUE_OUT1_LEFT,
896 WM8904_ANALOGUE_OUT1_RIGHT, 0, 63, 0, out_tlv),
897SOC_DOUBLE_R("Headphone Switch", WM8904_ANALOGUE_OUT1_LEFT,
898 WM8904_ANALOGUE_OUT1_RIGHT, 8, 1, 1),
899SOC_DOUBLE_R("Headphone ZC Switch", WM8904_ANALOGUE_OUT1_LEFT,
900 WM8904_ANALOGUE_OUT1_RIGHT, 6, 1, 0),
901
902SOC_DOUBLE_R_TLV("Line Output Volume", WM8904_ANALOGUE_OUT2_LEFT,
903 WM8904_ANALOGUE_OUT2_RIGHT, 0, 63, 0, out_tlv),
904SOC_DOUBLE_R("Line Output Switch", WM8904_ANALOGUE_OUT2_LEFT,
905 WM8904_ANALOGUE_OUT2_RIGHT, 8, 1, 1),
906SOC_DOUBLE_R("Line Output ZC Switch", WM8904_ANALOGUE_OUT2_LEFT,
907 WM8904_ANALOGUE_OUT2_RIGHT, 6, 1, 0),
908
909SOC_SINGLE("EQ Switch", WM8904_EQ1, 0, 1, 0),
910SOC_SINGLE("DRC Switch", WM8904_DRC_0, 15, 1, 0),
911SOC_ENUM("DRC Path", drc_path),
912SOC_SINGLE("DAC OSRx2 Switch", WM8904_DAC_DIGITAL_1, 6, 1, 0),
913SOC_SINGLE_BOOL_EXT("DAC Deemphasis Switch", 0,
914 wm8904_get_deemph, wm8904_put_deemph),
915};
916
917static const struct snd_kcontrol_new wm8904_snd_controls[] = {
918SOC_DOUBLE_TLV("Digital Sidetone Volume", WM8904_DAC_DIGITAL_0, 4, 8, 15, 0,
919 sidetone_tlv),
920};
921
922static const struct snd_kcontrol_new wm8904_eq_controls[] = {
923SOC_SINGLE_TLV("EQ1 Volume", WM8904_EQ2, 0, 24, 0, eq_tlv),
924SOC_SINGLE_TLV("EQ2 Volume", WM8904_EQ3, 0, 24, 0, eq_tlv),
925SOC_SINGLE_TLV("EQ3 Volume", WM8904_EQ4, 0, 24, 0, eq_tlv),
926SOC_SINGLE_TLV("EQ4 Volume", WM8904_EQ5, 0, 24, 0, eq_tlv),
927SOC_SINGLE_TLV("EQ5 Volume", WM8904_EQ6, 0, 24, 0, eq_tlv),
928};
929
930static int cp_event(struct snd_soc_dapm_widget *w,
931 struct snd_kcontrol *kcontrol, int event)
932{
933 BUG_ON(event != SND_SOC_DAPM_POST_PMU);
934
935 /* Maximum startup time */
936 udelay(500);
937
938 return 0;
939}
940
941static int sysclk_event(struct snd_soc_dapm_widget *w,
942 struct snd_kcontrol *kcontrol, int event)
943{
944 struct snd_soc_codec *codec = w->codec;
945 struct wm8904_priv *wm8904 = codec->private_data;
946
947 switch (event) {
948 case SND_SOC_DAPM_PRE_PMU:
949 /* If we're using the FLL then we only start it when
950 * required; we assume that the configuration has been
951 * done previously and all we need to do is kick it
952 * off.
953 */
954 switch (wm8904->sysclk_src) {
955 case WM8904_CLK_FLL:
956 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
957 WM8904_FLL_OSC_ENA,
958 WM8904_FLL_OSC_ENA);
959
960 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
961 WM8904_FLL_ENA,
962 WM8904_FLL_ENA);
963 break;
964
965 default:
966 break;
967 }
968 break;
969
970 case SND_SOC_DAPM_POST_PMD:
971 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
972 WM8904_FLL_OSC_ENA | WM8904_FLL_ENA, 0);
973 break;
974 }
975
976 return 0;
977}
978
979static int out_pga_event(struct snd_soc_dapm_widget *w,
980 struct snd_kcontrol *kcontrol, int event)
981{
982 struct snd_soc_codec *codec = w->codec;
983 struct wm8904_priv *wm8904 = codec->private_data;
984 int reg, val;
985 int dcs_mask;
986 int dcs_l, dcs_r;
987 int dcs_l_reg, dcs_r_reg;
988 int timeout;
989 int pwr_reg;
990
991 /* This code is shared between HP and LINEOUT; we do all our
992 * power management in stereo pairs to avoid latency issues so
993 * we reuse shift to identify which rather than strcmp() the
994 * name. */
995 reg = w->shift;
996
997 switch (reg) {
998 case WM8904_ANALOGUE_HP_0:
999 pwr_reg = WM8904_POWER_MANAGEMENT_2;
1000 dcs_mask = WM8904_DCS_ENA_CHAN_0 | WM8904_DCS_ENA_CHAN_1;
1001 dcs_r_reg = WM8904_DC_SERVO_8;
1002 dcs_l_reg = WM8904_DC_SERVO_9;
1003 dcs_l = 0;
1004 dcs_r = 1;
1005 break;
1006 case WM8904_ANALOGUE_LINEOUT_0:
1007 pwr_reg = WM8904_POWER_MANAGEMENT_3;
1008 dcs_mask = WM8904_DCS_ENA_CHAN_2 | WM8904_DCS_ENA_CHAN_3;
1009 dcs_r_reg = WM8904_DC_SERVO_6;
1010 dcs_l_reg = WM8904_DC_SERVO_7;
1011 dcs_l = 2;
1012 dcs_r = 3;
1013 break;
1014 default:
1015 BUG();
1016 return -EINVAL;
1017 }
1018
1019 switch (event) {
1020 case SND_SOC_DAPM_PRE_PMU:
1021 /* Power on the PGAs */
1022 snd_soc_update_bits(codec, pwr_reg,
1023 WM8904_HPL_PGA_ENA | WM8904_HPR_PGA_ENA,
1024 WM8904_HPL_PGA_ENA | WM8904_HPR_PGA_ENA);
1025
1026 /* Power on the amplifier */
1027 snd_soc_update_bits(codec, reg,
1028 WM8904_HPL_ENA | WM8904_HPR_ENA,
1029 WM8904_HPL_ENA | WM8904_HPR_ENA);
1030
1031
1032 /* Enable the first stage */
1033 snd_soc_update_bits(codec, reg,
1034 WM8904_HPL_ENA_DLY | WM8904_HPR_ENA_DLY,
1035 WM8904_HPL_ENA_DLY | WM8904_HPR_ENA_DLY);
1036
1037 /* Power up the DC servo */
1038 snd_soc_update_bits(codec, WM8904_DC_SERVO_0,
1039 dcs_mask, dcs_mask);
1040
1041 /* Either calibrate the DC servo or restore cached state
1042 * if we have that.
1043 */
1044 if (wm8904->dcs_state[dcs_l] || wm8904->dcs_state[dcs_r]) {
1045 dev_dbg(codec->dev, "Restoring DC servo state\n");
1046
1047 snd_soc_write(codec, dcs_l_reg,
1048 wm8904->dcs_state[dcs_l]);
1049 snd_soc_write(codec, dcs_r_reg,
1050 wm8904->dcs_state[dcs_r]);
1051
1052 snd_soc_write(codec, WM8904_DC_SERVO_1, dcs_mask);
1053
1054 timeout = 20;
1055 } else {
1056 dev_dbg(codec->dev, "Calibrating DC servo\n");
1057
1058 snd_soc_write(codec, WM8904_DC_SERVO_1,
1059 dcs_mask << WM8904_DCS_TRIG_STARTUP_0_SHIFT);
1060
1061 timeout = 500;
1062 }
1063
1064 /* Wait for DC servo to complete */
1065 dcs_mask <<= WM8904_DCS_CAL_COMPLETE_SHIFT;
1066 do {
1067 val = snd_soc_read(codec, WM8904_DC_SERVO_READBACK_0);
1068 if ((val & dcs_mask) == dcs_mask)
1069 break;
1070
1071 msleep(1);
1072 } while (--timeout);
1073
1074 if ((val & dcs_mask) != dcs_mask)
1075 dev_warn(codec->dev, "DC servo timed out\n");
1076 else
1077 dev_dbg(codec->dev, "DC servo ready\n");
1078
1079 /* Enable the output stage */
1080 snd_soc_update_bits(codec, reg,
1081 WM8904_HPL_ENA_OUTP | WM8904_HPR_ENA_OUTP,
1082 WM8904_HPL_ENA_OUTP | WM8904_HPR_ENA_OUTP);
1083 break;
1084
1085 case SND_SOC_DAPM_POST_PMU:
1086 /* Unshort the output itself */
1087 snd_soc_update_bits(codec, reg,
1088 WM8904_HPL_RMV_SHORT |
1089 WM8904_HPR_RMV_SHORT,
1090 WM8904_HPL_RMV_SHORT |
1091 WM8904_HPR_RMV_SHORT);
1092
1093 break;
1094
1095 case SND_SOC_DAPM_PRE_PMD:
1096 /* Short the output */
1097 snd_soc_update_bits(codec, reg,
1098 WM8904_HPL_RMV_SHORT |
1099 WM8904_HPR_RMV_SHORT, 0);
1100 break;
1101
1102 case SND_SOC_DAPM_POST_PMD:
1103 /* Cache the DC servo configuration; this will be
1104 * invalidated if we change the configuration. */
1105 wm8904->dcs_state[dcs_l] = snd_soc_read(codec, dcs_l_reg);
1106 wm8904->dcs_state[dcs_r] = snd_soc_read(codec, dcs_r_reg);
1107
1108 snd_soc_update_bits(codec, WM8904_DC_SERVO_0,
1109 dcs_mask, 0);
1110
1111 /* Disable the amplifier input and output stages */
1112 snd_soc_update_bits(codec, reg,
1113 WM8904_HPL_ENA | WM8904_HPR_ENA |
1114 WM8904_HPL_ENA_DLY | WM8904_HPR_ENA_DLY |
1115 WM8904_HPL_ENA_OUTP | WM8904_HPR_ENA_OUTP,
1116 0);
1117
1118 /* PGAs too */
1119 snd_soc_update_bits(codec, pwr_reg,
1120 WM8904_HPL_PGA_ENA | WM8904_HPR_PGA_ENA,
1121 0);
1122 break;
1123 }
1124
1125 return 0;
1126}
1127
1128static const char *lin_text[] = {
1129 "IN1L", "IN2L", "IN3L"
1130};
1131
1132static const struct soc_enum lin_enum =
1133 SOC_ENUM_SINGLE(WM8904_ANALOGUE_LEFT_INPUT_1, 2, 3, lin_text);
1134
1135static const struct snd_kcontrol_new lin_mux =
1136 SOC_DAPM_ENUM("Left Capture Mux", lin_enum);
1137
1138static const struct soc_enum lin_inv_enum =
1139 SOC_ENUM_SINGLE(WM8904_ANALOGUE_LEFT_INPUT_1, 4, 3, lin_text);
1140
1141static const struct snd_kcontrol_new lin_inv_mux =
1142 SOC_DAPM_ENUM("Left Capture Inveting Mux", lin_inv_enum);
1143
1144static const char *rin_text[] = {
1145 "IN1R", "IN2R", "IN3R"
1146};
1147
1148static const struct soc_enum rin_enum =
1149 SOC_ENUM_SINGLE(WM8904_ANALOGUE_RIGHT_INPUT_1, 2, 3, rin_text);
1150
1151static const struct snd_kcontrol_new rin_mux =
1152 SOC_DAPM_ENUM("Right Capture Mux", rin_enum);
1153
1154static const struct soc_enum rin_inv_enum =
1155 SOC_ENUM_SINGLE(WM8904_ANALOGUE_RIGHT_INPUT_1, 4, 3, rin_text);
1156
1157static const struct snd_kcontrol_new rin_inv_mux =
1158 SOC_DAPM_ENUM("Right Capture Inveting Mux", rin_inv_enum);
1159
1160static const char *aif_text[] = {
1161 "Left", "Right"
1162};
1163
1164static const struct soc_enum aifoutl_enum =
1165 SOC_ENUM_SINGLE(WM8904_AUDIO_INTERFACE_0, 7, 2, aif_text);
1166
1167static const struct snd_kcontrol_new aifoutl_mux =
1168 SOC_DAPM_ENUM("AIFOUTL Mux", aifoutl_enum);
1169
1170static const struct soc_enum aifoutr_enum =
1171 SOC_ENUM_SINGLE(WM8904_AUDIO_INTERFACE_0, 6, 2, aif_text);
1172
1173static const struct snd_kcontrol_new aifoutr_mux =
1174 SOC_DAPM_ENUM("AIFOUTR Mux", aifoutr_enum);
1175
1176static const struct soc_enum aifinl_enum =
1177 SOC_ENUM_SINGLE(WM8904_AUDIO_INTERFACE_0, 5, 2, aif_text);
1178
1179static const struct snd_kcontrol_new aifinl_mux =
1180 SOC_DAPM_ENUM("AIFINL Mux", aifinl_enum);
1181
1182static const struct soc_enum aifinr_enum =
1183 SOC_ENUM_SINGLE(WM8904_AUDIO_INTERFACE_0, 4, 2, aif_text);
1184
1185static const struct snd_kcontrol_new aifinr_mux =
1186 SOC_DAPM_ENUM("AIFINR Mux", aifinr_enum);
1187
1188static const struct snd_soc_dapm_widget wm8904_core_dapm_widgets[] = {
1189SND_SOC_DAPM_SUPPLY("SYSCLK", WM8904_CLOCK_RATES_2, 2, 0, sysclk_event,
1190 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1191SND_SOC_DAPM_SUPPLY("CLK_DSP", WM8904_CLOCK_RATES_2, 1, 0, NULL, 0),
1192SND_SOC_DAPM_SUPPLY("TOCLK", WM8904_CLOCK_RATES_2, 0, 0, NULL, 0),
1193};
1194
1195static const struct snd_soc_dapm_widget wm8904_adc_dapm_widgets[] = {
1196SND_SOC_DAPM_INPUT("IN1L"),
1197SND_SOC_DAPM_INPUT("IN1R"),
1198SND_SOC_DAPM_INPUT("IN2L"),
1199SND_SOC_DAPM_INPUT("IN2R"),
1200SND_SOC_DAPM_INPUT("IN3L"),
1201SND_SOC_DAPM_INPUT("IN3R"),
1202
1203SND_SOC_DAPM_MICBIAS("MICBIAS", WM8904_MIC_BIAS_CONTROL_0, 0, 0),
1204
1205SND_SOC_DAPM_MUX("Left Capture Mux", SND_SOC_NOPM, 0, 0, &lin_mux),
1206SND_SOC_DAPM_MUX("Left Capture Inverting Mux", SND_SOC_NOPM, 0, 0,
1207 &lin_inv_mux),
1208SND_SOC_DAPM_MUX("Right Capture Mux", SND_SOC_NOPM, 0, 0, &rin_mux),
1209SND_SOC_DAPM_MUX("Right Capture Inverting Mux", SND_SOC_NOPM, 0, 0,
1210 &rin_inv_mux),
1211
1212SND_SOC_DAPM_PGA("Left Capture PGA", WM8904_POWER_MANAGEMENT_0, 1, 0,
1213 NULL, 0),
1214SND_SOC_DAPM_PGA("Right Capture PGA", WM8904_POWER_MANAGEMENT_0, 0, 0,
1215 NULL, 0),
1216
1217SND_SOC_DAPM_ADC("ADCL", NULL, WM8904_POWER_MANAGEMENT_6, 1, 0),
1218SND_SOC_DAPM_ADC("ADCR", NULL, WM8904_POWER_MANAGEMENT_6, 0, 0),
1219
1220SND_SOC_DAPM_MUX("AIFOUTL Mux", SND_SOC_NOPM, 0, 0, &aifoutl_mux),
1221SND_SOC_DAPM_MUX("AIFOUTR Mux", SND_SOC_NOPM, 0, 0, &aifoutr_mux),
1222
1223SND_SOC_DAPM_AIF_OUT("AIFOUTL", "Capture", 0, SND_SOC_NOPM, 0, 0),
1224SND_SOC_DAPM_AIF_OUT("AIFOUTR", "Capture", 1, SND_SOC_NOPM, 0, 0),
1225};
1226
1227static const struct snd_soc_dapm_widget wm8904_dac_dapm_widgets[] = {
1228SND_SOC_DAPM_AIF_IN("AIFINL", "Playback", 0, SND_SOC_NOPM, 0, 0),
1229SND_SOC_DAPM_AIF_IN("AIFINR", "Playback", 1, SND_SOC_NOPM, 0, 0),
1230
1231SND_SOC_DAPM_MUX("DACL Mux", SND_SOC_NOPM, 0, 0, &aifinl_mux),
1232SND_SOC_DAPM_MUX("DACR Mux", SND_SOC_NOPM, 0, 0, &aifinr_mux),
1233
1234SND_SOC_DAPM_DAC("DACL", NULL, WM8904_POWER_MANAGEMENT_6, 3, 0),
1235SND_SOC_DAPM_DAC("DACR", NULL, WM8904_POWER_MANAGEMENT_6, 2, 0),
1236
1237SND_SOC_DAPM_SUPPLY("Charge pump", WM8904_CHARGE_PUMP_0, 0, 0, cp_event,
1238 SND_SOC_DAPM_POST_PMU),
1239
1240SND_SOC_DAPM_PGA("HPL PGA", SND_SOC_NOPM, 1, 0, NULL, 0),
1241SND_SOC_DAPM_PGA("HPR PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
1242
1243SND_SOC_DAPM_PGA("LINEL PGA", SND_SOC_NOPM, 1, 0, NULL, 0),
1244SND_SOC_DAPM_PGA("LINER PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
1245
1246SND_SOC_DAPM_PGA_E("Headphone Output", SND_SOC_NOPM, WM8904_ANALOGUE_HP_0,
1247 0, NULL, 0, out_pga_event,
1248 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1249 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
1250SND_SOC_DAPM_PGA_E("Line Output", SND_SOC_NOPM, WM8904_ANALOGUE_LINEOUT_0,
1251 0, NULL, 0, out_pga_event,
1252 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1253 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
1254
1255SND_SOC_DAPM_OUTPUT("HPOUTL"),
1256SND_SOC_DAPM_OUTPUT("HPOUTR"),
1257SND_SOC_DAPM_OUTPUT("LINEOUTL"),
1258SND_SOC_DAPM_OUTPUT("LINEOUTR"),
1259};
1260
1261static const char *out_mux_text[] = {
1262 "DAC", "Bypass"
1263};
1264
1265static const struct soc_enum hpl_enum =
1266 SOC_ENUM_SINGLE(WM8904_ANALOGUE_OUT12_ZC, 3, 2, out_mux_text);
1267
1268static const struct snd_kcontrol_new hpl_mux =
1269 SOC_DAPM_ENUM("HPL Mux", hpl_enum);
1270
1271static const struct soc_enum hpr_enum =
1272 SOC_ENUM_SINGLE(WM8904_ANALOGUE_OUT12_ZC, 2, 2, out_mux_text);
1273
1274static const struct snd_kcontrol_new hpr_mux =
1275 SOC_DAPM_ENUM("HPR Mux", hpr_enum);
1276
1277static const struct soc_enum linel_enum =
1278 SOC_ENUM_SINGLE(WM8904_ANALOGUE_OUT12_ZC, 1, 2, out_mux_text);
1279
1280static const struct snd_kcontrol_new linel_mux =
1281 SOC_DAPM_ENUM("LINEL Mux", linel_enum);
1282
1283static const struct soc_enum liner_enum =
1284 SOC_ENUM_SINGLE(WM8904_ANALOGUE_OUT12_ZC, 0, 2, out_mux_text);
1285
1286static const struct snd_kcontrol_new liner_mux =
1287 SOC_DAPM_ENUM("LINEL Mux", liner_enum);
1288
1289static const char *sidetone_text[] = {
1290 "None", "Left", "Right"
1291};
1292
1293static const struct soc_enum dacl_sidetone_enum =
1294 SOC_ENUM_SINGLE(WM8904_DAC_DIGITAL_0, 2, 3, sidetone_text);
1295
1296static const struct snd_kcontrol_new dacl_sidetone_mux =
1297 SOC_DAPM_ENUM("Left Sidetone Mux", dacl_sidetone_enum);
1298
1299static const struct soc_enum dacr_sidetone_enum =
1300 SOC_ENUM_SINGLE(WM8904_DAC_DIGITAL_0, 0, 3, sidetone_text);
1301
1302static const struct snd_kcontrol_new dacr_sidetone_mux =
1303 SOC_DAPM_ENUM("Right Sidetone Mux", dacr_sidetone_enum);
1304
1305static const struct snd_soc_dapm_widget wm8904_dapm_widgets[] = {
1306SND_SOC_DAPM_SUPPLY("Class G", WM8904_CLASS_W_0, 0, 1, NULL, 0),
1307SND_SOC_DAPM_PGA("Left Bypass", SND_SOC_NOPM, 0, 0, NULL, 0),
1308SND_SOC_DAPM_PGA("Right Bypass", SND_SOC_NOPM, 0, 0, NULL, 0),
1309
1310SND_SOC_DAPM_MUX("Left Sidetone", SND_SOC_NOPM, 0, 0, &dacl_sidetone_mux),
1311SND_SOC_DAPM_MUX("Right Sidetone", SND_SOC_NOPM, 0, 0, &dacr_sidetone_mux),
1312
1313SND_SOC_DAPM_MUX("HPL Mux", SND_SOC_NOPM, 0, 0, &hpl_mux),
1314SND_SOC_DAPM_MUX("HPR Mux", SND_SOC_NOPM, 0, 0, &hpr_mux),
1315SND_SOC_DAPM_MUX("LINEL Mux", SND_SOC_NOPM, 0, 0, &linel_mux),
1316SND_SOC_DAPM_MUX("LINER Mux", SND_SOC_NOPM, 0, 0, &liner_mux),
1317};
1318
1319static const struct snd_soc_dapm_route core_intercon[] = {
1320 { "CLK_DSP", NULL, "SYSCLK" },
1321 { "TOCLK", NULL, "SYSCLK" },
1322};
1323
1324static const struct snd_soc_dapm_route adc_intercon[] = {
1325 { "Left Capture Mux", "IN1L", "IN1L" },
1326 { "Left Capture Mux", "IN2L", "IN2L" },
1327 { "Left Capture Mux", "IN3L", "IN3L" },
1328
1329 { "Left Capture Inverting Mux", "IN1L", "IN1L" },
1330 { "Left Capture Inverting Mux", "IN2L", "IN2L" },
1331 { "Left Capture Inverting Mux", "IN3L", "IN3L" },
1332
1333 { "Right Capture Mux", "IN1R", "IN1R" },
1334 { "Right Capture Mux", "IN2R", "IN2R" },
1335 { "Right Capture Mux", "IN3R", "IN3R" },
1336
1337 { "Right Capture Inverting Mux", "IN1R", "IN1R" },
1338 { "Right Capture Inverting Mux", "IN2R", "IN2R" },
1339 { "Right Capture Inverting Mux", "IN3R", "IN3R" },
1340
1341 { "Left Capture PGA", NULL, "Left Capture Mux" },
1342 { "Left Capture PGA", NULL, "Left Capture Inverting Mux" },
1343
1344 { "Right Capture PGA", NULL, "Right Capture Mux" },
1345 { "Right Capture PGA", NULL, "Right Capture Inverting Mux" },
1346
1347 { "AIFOUTL", "Left", "ADCL" },
1348 { "AIFOUTL", "Right", "ADCR" },
1349 { "AIFOUTR", "Left", "ADCL" },
1350 { "AIFOUTR", "Right", "ADCR" },
1351
1352 { "ADCL", NULL, "CLK_DSP" },
1353 { "ADCL", NULL, "Left Capture PGA" },
1354
1355 { "ADCR", NULL, "CLK_DSP" },
1356 { "ADCR", NULL, "Right Capture PGA" },
1357};
1358
1359static const struct snd_soc_dapm_route dac_intercon[] = {
1360 { "DACL", "Right", "AIFINR" },
1361 { "DACL", "Left", "AIFINL" },
1362 { "DACL", NULL, "CLK_DSP" },
1363
1364 { "DACR", "Right", "AIFINR" },
1365 { "DACR", "Left", "AIFINL" },
1366 { "DACR", NULL, "CLK_DSP" },
1367
1368 { "Charge pump", NULL, "SYSCLK" },
1369
1370 { "Headphone Output", NULL, "HPL PGA" },
1371 { "Headphone Output", NULL, "HPR PGA" },
1372 { "Headphone Output", NULL, "Charge pump" },
1373 { "Headphone Output", NULL, "TOCLK" },
1374
1375 { "Line Output", NULL, "LINEL PGA" },
1376 { "Line Output", NULL, "LINER PGA" },
1377 { "Line Output", NULL, "Charge pump" },
1378 { "Line Output", NULL, "TOCLK" },
1379
1380 { "HPOUTL", NULL, "Headphone Output" },
1381 { "HPOUTR", NULL, "Headphone Output" },
1382
1383 { "LINEOUTL", NULL, "Line Output" },
1384 { "LINEOUTR", NULL, "Line Output" },
1385};
1386
1387static const struct snd_soc_dapm_route wm8904_intercon[] = {
1388 { "Left Sidetone", "Left", "ADCL" },
1389 { "Left Sidetone", "Right", "ADCR" },
1390 { "DACL", NULL, "Left Sidetone" },
1391
1392 { "Right Sidetone", "Left", "ADCL" },
1393 { "Right Sidetone", "Right", "ADCR" },
1394 { "DACR", NULL, "Right Sidetone" },
1395
1396 { "Left Bypass", NULL, "Class G" },
1397 { "Left Bypass", NULL, "Left Capture PGA" },
1398
1399 { "Right Bypass", NULL, "Class G" },
1400 { "Right Bypass", NULL, "Right Capture PGA" },
1401
1402 { "HPL Mux", "DAC", "DACL" },
1403 { "HPL Mux", "Bypass", "Left Bypass" },
1404
1405 { "HPR Mux", "DAC", "DACR" },
1406 { "HPR Mux", "Bypass", "Right Bypass" },
1407
1408 { "LINEL Mux", "DAC", "DACL" },
1409 { "LINEL Mux", "Bypass", "Left Bypass" },
1410
1411 { "LINER Mux", "DAC", "DACR" },
1412 { "LINER Mux", "Bypass", "Right Bypass" },
1413
1414 { "HPL PGA", NULL, "HPL Mux" },
1415 { "HPR PGA", NULL, "HPR Mux" },
1416
1417 { "LINEL PGA", NULL, "LINEL Mux" },
1418 { "LINER PGA", NULL, "LINER Mux" },
1419};
1420
1421static const struct snd_soc_dapm_route wm8912_intercon[] = {
1422 { "HPL PGA", NULL, "DACL" },
1423 { "HPR PGA", NULL, "DACR" },
1424
1425 { "LINEL PGA", NULL, "DACL" },
1426 { "LINER PGA", NULL, "DACR" },
1427};
1428
1429static int wm8904_add_widgets(struct snd_soc_codec *codec)
1430{
1431 struct wm8904_priv *wm8904 = codec->private_data;
1432
1433 snd_soc_dapm_new_controls(codec, wm8904_core_dapm_widgets,
1434 ARRAY_SIZE(wm8904_core_dapm_widgets));
1435 snd_soc_dapm_add_routes(codec, core_intercon,
1436 ARRAY_SIZE(core_intercon));
1437
1438 switch (wm8904->devtype) {
1439 case WM8904:
1440 snd_soc_add_controls(codec, wm8904_adc_snd_controls,
1441 ARRAY_SIZE(wm8904_adc_snd_controls));
1442 snd_soc_add_controls(codec, wm8904_dac_snd_controls,
1443 ARRAY_SIZE(wm8904_dac_snd_controls));
1444 snd_soc_add_controls(codec, wm8904_snd_controls,
1445 ARRAY_SIZE(wm8904_snd_controls));
1446
1447 snd_soc_dapm_new_controls(codec, wm8904_adc_dapm_widgets,
1448 ARRAY_SIZE(wm8904_adc_dapm_widgets));
1449 snd_soc_dapm_new_controls(codec, wm8904_dac_dapm_widgets,
1450 ARRAY_SIZE(wm8904_dac_dapm_widgets));
1451 snd_soc_dapm_new_controls(codec, wm8904_dapm_widgets,
1452 ARRAY_SIZE(wm8904_dapm_widgets));
1453
1454 snd_soc_dapm_add_routes(codec, core_intercon,
1455 ARRAY_SIZE(core_intercon));
1456 snd_soc_dapm_add_routes(codec, adc_intercon,
1457 ARRAY_SIZE(adc_intercon));
1458 snd_soc_dapm_add_routes(codec, dac_intercon,
1459 ARRAY_SIZE(dac_intercon));
1460 snd_soc_dapm_add_routes(codec, wm8904_intercon,
1461 ARRAY_SIZE(wm8904_intercon));
1462 break;
1463
1464 case WM8912:
1465 snd_soc_add_controls(codec, wm8904_dac_snd_controls,
1466 ARRAY_SIZE(wm8904_dac_snd_controls));
1467
1468 snd_soc_dapm_new_controls(codec, wm8904_dac_dapm_widgets,
1469 ARRAY_SIZE(wm8904_dac_dapm_widgets));
1470
1471 snd_soc_dapm_add_routes(codec, dac_intercon,
1472 ARRAY_SIZE(dac_intercon));
1473 snd_soc_dapm_add_routes(codec, wm8912_intercon,
1474 ARRAY_SIZE(wm8912_intercon));
1475 break;
1476 }
1477
1478 snd_soc_dapm_new_widgets(codec);
1479 return 0;
1480}
1481
1482static struct {
1483 int ratio;
1484 unsigned int clk_sys_rate;
1485} clk_sys_rates[] = {
1486 { 64, 0 },
1487 { 128, 1 },
1488 { 192, 2 },
1489 { 256, 3 },
1490 { 384, 4 },
1491 { 512, 5 },
1492 { 786, 6 },
1493 { 1024, 7 },
1494 { 1408, 8 },
1495 { 1536, 9 },
1496};
1497
1498static struct {
1499 int rate;
1500 int sample_rate;
1501} sample_rates[] = {
1502 { 8000, 0 },
1503 { 11025, 1 },
1504 { 12000, 1 },
1505 { 16000, 2 },
1506 { 22050, 3 },
1507 { 24000, 3 },
1508 { 32000, 4 },
1509 { 44100, 5 },
1510 { 48000, 5 },
1511};
1512
1513static struct {
1514 int div; /* *10 due to .5s */
1515 int bclk_div;
1516} bclk_divs[] = {
1517 { 10, 0 },
1518 { 15, 1 },
1519 { 20, 2 },
1520 { 30, 3 },
1521 { 40, 4 },
1522 { 50, 5 },
1523 { 55, 6 },
1524 { 60, 7 },
1525 { 80, 8 },
1526 { 100, 9 },
1527 { 110, 10 },
1528 { 120, 11 },
1529 { 160, 12 },
1530 { 200, 13 },
1531 { 220, 14 },
1532 { 240, 16 },
1533 { 200, 17 },
1534 { 320, 18 },
1535 { 440, 19 },
1536 { 480, 20 },
1537};
1538
1539
1540static int wm8904_hw_params(struct snd_pcm_substream *substream,
1541 struct snd_pcm_hw_params *params,
1542 struct snd_soc_dai *dai)
1543{
1544 struct snd_soc_codec *codec = dai->codec;
1545 struct wm8904_priv *wm8904 = codec->private_data;
1546 int ret, i, best, best_val, cur_val;
1547 unsigned int aif1 = 0;
1548 unsigned int aif2 = 0;
1549 unsigned int aif3 = 0;
1550 unsigned int clock1 = 0;
1551 unsigned int dac_digital1 = 0;
1552
1553 /* What BCLK do we need? */
1554 wm8904->fs = params_rate(params);
1555 if (wm8904->tdm_slots) {
1556 dev_dbg(codec->dev, "Configuring for %d %d bit TDM slots\n",
1557 wm8904->tdm_slots, wm8904->tdm_width);
1558 wm8904->bclk = snd_soc_calc_bclk(wm8904->fs,
1559 wm8904->tdm_width, 2,
1560 wm8904->tdm_slots);
1561 } else {
1562 wm8904->bclk = snd_soc_params_to_bclk(params);
1563 }
1564
1565 switch (params_format(params)) {
1566 case SNDRV_PCM_FORMAT_S16_LE:
1567 break;
1568 case SNDRV_PCM_FORMAT_S20_3LE:
1569 aif1 |= 0x40;
1570 break;
1571 case SNDRV_PCM_FORMAT_S24_LE:
1572 aif1 |= 0x80;
1573 break;
1574 case SNDRV_PCM_FORMAT_S32_LE:
1575 aif1 |= 0xc0;
1576 break;
1577 default:
1578 return -EINVAL;
1579 }
1580
1581
1582 dev_dbg(codec->dev, "Target BCLK is %dHz\n", wm8904->bclk);
1583
1584 ret = wm8904_configure_clocking(codec);
1585 if (ret != 0)
1586 return ret;
1587
1588 /* Select nearest CLK_SYS_RATE */
1589 best = 0;
1590 best_val = abs((wm8904->sysclk_rate / clk_sys_rates[0].ratio)
1591 - wm8904->fs);
1592 for (i = 1; i < ARRAY_SIZE(clk_sys_rates); i++) {
1593 cur_val = abs((wm8904->sysclk_rate /
1594 clk_sys_rates[i].ratio) - wm8904->fs);;
1595 if (cur_val < best_val) {
1596 best = i;
1597 best_val = cur_val;
1598 }
1599 }
1600 dev_dbg(codec->dev, "Selected CLK_SYS_RATIO of %d\n",
1601 clk_sys_rates[best].ratio);
1602 clock1 |= (clk_sys_rates[best].clk_sys_rate
1603 << WM8904_CLK_SYS_RATE_SHIFT);
1604
1605 /* SAMPLE_RATE */
1606 best = 0;
1607 best_val = abs(wm8904->fs - sample_rates[0].rate);
1608 for (i = 1; i < ARRAY_SIZE(sample_rates); i++) {
1609 /* Closest match */
1610 cur_val = abs(wm8904->fs - sample_rates[i].rate);
1611 if (cur_val < best_val) {
1612 best = i;
1613 best_val = cur_val;
1614 }
1615 }
1616 dev_dbg(codec->dev, "Selected SAMPLE_RATE of %dHz\n",
1617 sample_rates[best].rate);
1618 clock1 |= (sample_rates[best].sample_rate
1619 << WM8904_SAMPLE_RATE_SHIFT);
1620
1621 /* Enable sloping stopband filter for low sample rates */
1622 if (wm8904->fs <= 24000)
1623 dac_digital1 |= WM8904_DAC_SB_FILT;
1624
1625 /* BCLK_DIV */
1626 best = 0;
1627 best_val = INT_MAX;
1628 for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) {
1629 cur_val = ((wm8904->sysclk_rate * 10) / bclk_divs[i].div)
1630 - wm8904->bclk;
1631 if (cur_val < 0) /* Table is sorted */
1632 break;
1633 if (cur_val < best_val) {
1634 best = i;
1635 best_val = cur_val;
1636 }
1637 }
1638 wm8904->bclk = (wm8904->sysclk_rate * 10) / bclk_divs[best].div;
1639 dev_dbg(codec->dev, "Selected BCLK_DIV of %d for %dHz BCLK\n",
1640 bclk_divs[best].div, wm8904->bclk);
1641 aif2 |= bclk_divs[best].bclk_div;
1642
1643 /* LRCLK is a simple fraction of BCLK */
1644 dev_dbg(codec->dev, "LRCLK_RATE is %d\n", wm8904->bclk / wm8904->fs);
1645 aif3 |= wm8904->bclk / wm8904->fs;
1646
1647 /* Apply the settings */
1648 snd_soc_update_bits(codec, WM8904_DAC_DIGITAL_1,
1649 WM8904_DAC_SB_FILT, dac_digital1);
1650 snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_1,
1651 WM8904_AIF_WL_MASK, aif1);
1652 snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_2,
1653 WM8904_BCLK_DIV_MASK, aif2);
1654 snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_3,
1655 WM8904_LRCLK_RATE_MASK, aif3);
1656 snd_soc_update_bits(codec, WM8904_CLOCK_RATES_1,
1657 WM8904_SAMPLE_RATE_MASK |
1658 WM8904_CLK_SYS_RATE_MASK, clock1);
1659
1660 /* Update filters for the new settings */
1661 wm8904_set_retune_mobile(codec);
1662 wm8904_set_deemph(codec);
1663
1664 return 0;
1665}
1666
1667
1668static int wm8904_set_sysclk(struct snd_soc_dai *dai, int clk_id,
1669 unsigned int freq, int dir)
1670{
1671 struct snd_soc_codec *codec = dai->codec;
1672 struct wm8904_priv *priv = codec->private_data;
1673
1674 switch (clk_id) {
1675 case WM8904_CLK_MCLK:
1676 priv->sysclk_src = clk_id;
1677 priv->mclk_rate = freq;
1678 break;
1679
1680 case WM8904_CLK_FLL:
1681 priv->sysclk_src = clk_id;
1682 break;
1683
1684 default:
1685 return -EINVAL;
1686 }
1687
1688 dev_dbg(dai->dev, "Clock source is %d at %uHz\n", clk_id, freq);
1689
1690 wm8904_configure_clocking(codec);
1691
1692 return 0;
1693}
1694
1695static int wm8904_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1696{
1697 struct snd_soc_codec *codec = dai->codec;
1698 unsigned int aif1 = 0;
1699 unsigned int aif3 = 0;
1700
1701 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1702 case SND_SOC_DAIFMT_CBS_CFS:
1703 break;
1704 case SND_SOC_DAIFMT_CBS_CFM:
1705 aif3 |= WM8904_LRCLK_DIR;
1706 break;
1707 case SND_SOC_DAIFMT_CBM_CFS:
1708 aif1 |= WM8904_BCLK_DIR;
1709 break;
1710 case SND_SOC_DAIFMT_CBM_CFM:
1711 aif1 |= WM8904_BCLK_DIR;
1712 aif3 |= WM8904_LRCLK_DIR;
1713 break;
1714 default:
1715 return -EINVAL;
1716 }
1717
1718 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1719 case SND_SOC_DAIFMT_DSP_B:
1720 aif1 |= WM8904_AIF_LRCLK_INV;
1721 case SND_SOC_DAIFMT_DSP_A:
1722 aif1 |= 0x3;
1723 break;
1724 case SND_SOC_DAIFMT_I2S:
1725 aif1 |= 0x2;
1726 break;
1727 case SND_SOC_DAIFMT_RIGHT_J:
1728 break;
1729 case SND_SOC_DAIFMT_LEFT_J:
1730 aif1 |= 0x1;
1731 break;
1732 default:
1733 return -EINVAL;
1734 }
1735
1736 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1737 case SND_SOC_DAIFMT_DSP_A:
1738 case SND_SOC_DAIFMT_DSP_B:
1739 /* frame inversion not valid for DSP modes */
1740 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1741 case SND_SOC_DAIFMT_NB_NF:
1742 break;
1743 case SND_SOC_DAIFMT_IB_NF:
1744 aif1 |= WM8904_AIF_BCLK_INV;
1745 break;
1746 default:
1747 return -EINVAL;
1748 }
1749 break;
1750
1751 case SND_SOC_DAIFMT_I2S:
1752 case SND_SOC_DAIFMT_RIGHT_J:
1753 case SND_SOC_DAIFMT_LEFT_J:
1754 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1755 case SND_SOC_DAIFMT_NB_NF:
1756 break;
1757 case SND_SOC_DAIFMT_IB_IF:
1758 aif1 |= WM8904_AIF_BCLK_INV | WM8904_AIF_LRCLK_INV;
1759 break;
1760 case SND_SOC_DAIFMT_IB_NF:
1761 aif1 |= WM8904_AIF_BCLK_INV;
1762 break;
1763 case SND_SOC_DAIFMT_NB_IF:
1764 aif1 |= WM8904_AIF_LRCLK_INV;
1765 break;
1766 default:
1767 return -EINVAL;
1768 }
1769 break;
1770 default:
1771 return -EINVAL;
1772 }
1773
1774 snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_1,
1775 WM8904_AIF_BCLK_INV | WM8904_AIF_LRCLK_INV |
1776 WM8904_AIF_FMT_MASK | WM8904_BCLK_DIR, aif1);
1777 snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_3,
1778 WM8904_LRCLK_DIR, aif3);
1779
1780 return 0;
1781}
1782
1783
1784static int wm8904_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
1785 unsigned int rx_mask, int slots, int slot_width)
1786{
1787 struct snd_soc_codec *codec = dai->codec;
1788 struct wm8904_priv *wm8904 = codec->private_data;
1789 int aif1 = 0;
1790
1791 /* Don't need to validate anything if we're turning off TDM */
1792 if (slots == 0)
1793 goto out;
1794
1795 /* Note that we allow configurations we can't handle ourselves -
1796 * for example, we can generate clocks for slots 2 and up even if
1797 * we can't use those slots ourselves.
1798 */
1799 aif1 |= WM8904_AIFADC_TDM | WM8904_AIFDAC_TDM;
1800
1801 switch (rx_mask) {
1802 case 3:
1803 break;
1804 case 0xc:
1805 aif1 |= WM8904_AIFADC_TDM_CHAN;
1806 break;
1807 default:
1808 return -EINVAL;
1809 }
1810
1811
1812 switch (tx_mask) {
1813 case 3:
1814 break;
1815 case 0xc:
1816 aif1 |= WM8904_AIFDAC_TDM_CHAN;
1817 break;
1818 default:
1819 return -EINVAL;
1820 }
1821
1822out:
1823 wm8904->tdm_width = slot_width;
1824 wm8904->tdm_slots = slots / 2;
1825
1826 snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_1,
1827 WM8904_AIFADC_TDM | WM8904_AIFADC_TDM_CHAN |
1828 WM8904_AIFDAC_TDM | WM8904_AIFDAC_TDM_CHAN, aif1);
1829
1830 return 0;
1831}
1832
1833struct _fll_div {
1834 u16 fll_fratio;
1835 u16 fll_outdiv;
1836 u16 fll_clk_ref_div;
1837 u16 n;
1838 u16 k;
1839};
1840
1841/* The size in bits of the FLL divide multiplied by 10
1842 * to allow rounding later */
1843#define FIXED_FLL_SIZE ((1 << 16) * 10)
1844
1845static struct {
1846 unsigned int min;
1847 unsigned int max;
1848 u16 fll_fratio;
1849 int ratio;
1850} fll_fratios[] = {
1851 { 0, 64000, 4, 16 },
1852 { 64000, 128000, 3, 8 },
1853 { 128000, 256000, 2, 4 },
1854 { 256000, 1000000, 1, 2 },
1855 { 1000000, 13500000, 0, 1 },
1856};
1857
1858static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
1859 unsigned int Fout)
1860{
1861 u64 Kpart;
1862 unsigned int K, Ndiv, Nmod, target;
1863 unsigned int div;
1864 int i;
1865
1866 /* Fref must be <=13.5MHz */
1867 div = 1;
1868 fll_div->fll_clk_ref_div = 0;
1869 while ((Fref / div) > 13500000) {
1870 div *= 2;
1871 fll_div->fll_clk_ref_div++;
1872
1873 if (div > 8) {
1874 pr_err("Can't scale %dMHz input down to <=13.5MHz\n",
1875 Fref);
1876 return -EINVAL;
1877 }
1878 }
1879
1880 pr_debug("Fref=%u Fout=%u\n", Fref, Fout);
1881
1882 /* Apply the division for our remaining calculations */
1883 Fref /= div;
1884
1885 /* Fvco should be 90-100MHz; don't check the upper bound */
1886 div = 4;
1887 while (Fout * div < 90000000) {
1888 div++;
1889 if (div > 64) {
1890 pr_err("Unable to find FLL_OUTDIV for Fout=%uHz\n",
1891 Fout);
1892 return -EINVAL;
1893 }
1894 }
1895 target = Fout * div;
1896 fll_div->fll_outdiv = div - 1;
1897
1898 pr_debug("Fvco=%dHz\n", target);
1899
1900 /* Find an appropraite FLL_FRATIO and factor it out of the target */
1901 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
1902 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
1903 fll_div->fll_fratio = fll_fratios[i].fll_fratio;
1904 target /= fll_fratios[i].ratio;
1905 break;
1906 }
1907 }
1908 if (i == ARRAY_SIZE(fll_fratios)) {
1909 pr_err("Unable to find FLL_FRATIO for Fref=%uHz\n", Fref);
1910 return -EINVAL;
1911 }
1912
1913 /* Now, calculate N.K */
1914 Ndiv = target / Fref;
1915
1916 fll_div->n = Ndiv;
1917 Nmod = target % Fref;
1918 pr_debug("Nmod=%d\n", Nmod);
1919
1920 /* Calculate fractional part - scale up so we can round. */
1921 Kpart = FIXED_FLL_SIZE * (long long)Nmod;
1922
1923 do_div(Kpart, Fref);
1924
1925 K = Kpart & 0xFFFFFFFF;
1926
1927 if ((K % 10) >= 5)
1928 K += 5;
1929
1930 /* Move down to proper range now rounding is done */
1931 fll_div->k = K / 10;
1932
1933 pr_debug("N=%x K=%x FLL_FRATIO=%x FLL_OUTDIV=%x FLL_CLK_REF_DIV=%x\n",
1934 fll_div->n, fll_div->k,
1935 fll_div->fll_fratio, fll_div->fll_outdiv,
1936 fll_div->fll_clk_ref_div);
1937
1938 return 0;
1939}
1940
1941static int wm8904_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
1942 unsigned int Fref, unsigned int Fout)
1943{
1944 struct snd_soc_codec *codec = dai->codec;
1945 struct wm8904_priv *wm8904 = codec->private_data;
1946 struct _fll_div fll_div;
1947 int ret, val;
1948 int clock2, fll1;
1949
1950 /* Any change? */
1951 if (source == wm8904->fll_src && Fref == wm8904->fll_fref &&
1952 Fout == wm8904->fll_fout)
1953 return 0;
1954
1955 clock2 = snd_soc_read(codec, WM8904_CLOCK_RATES_2);
1956
1957 if (Fout == 0) {
1958 dev_dbg(codec->dev, "FLL disabled\n");
1959
1960 wm8904->fll_fref = 0;
1961 wm8904->fll_fout = 0;
1962
1963 /* Gate SYSCLK to avoid glitches */
1964 snd_soc_update_bits(codec, WM8904_CLOCK_RATES_2,
1965 WM8904_CLK_SYS_ENA, 0);
1966
1967 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
1968 WM8904_FLL_OSC_ENA | WM8904_FLL_ENA, 0);
1969
1970 goto out;
1971 }
1972
1973 /* Validate the FLL ID */
1974 switch (source) {
1975 case WM8904_FLL_MCLK:
1976 case WM8904_FLL_LRCLK:
1977 case WM8904_FLL_BCLK:
1978 ret = fll_factors(&fll_div, Fref, Fout);
1979 if (ret != 0)
1980 return ret;
1981 break;
1982
1983 case WM8904_FLL_FREE_RUNNING:
1984 dev_dbg(codec->dev, "Using free running FLL\n");
1985 /* Force 12MHz and output/4 for now */
1986 Fout = 12000000;
1987 Fref = 12000000;
1988
1989 memset(&fll_div, 0, sizeof(fll_div));
1990 fll_div.fll_outdiv = 3;
1991 break;
1992
1993 default:
1994 dev_err(codec->dev, "Unknown FLL ID %d\n", fll_id);
1995 return -EINVAL;
1996 }
1997
1998 /* Save current state then disable the FLL and SYSCLK to avoid
1999 * misclocking */
2000 fll1 = snd_soc_read(codec, WM8904_FLL_CONTROL_1);
2001 snd_soc_update_bits(codec, WM8904_CLOCK_RATES_2,
2002 WM8904_CLK_SYS_ENA, 0);
2003 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
2004 WM8904_FLL_OSC_ENA | WM8904_FLL_ENA, 0);
2005
2006 /* Unlock forced oscilator control to switch it on/off */
2007 snd_soc_update_bits(codec, WM8904_CONTROL_INTERFACE_TEST_1,
2008 WM8904_USER_KEY, WM8904_USER_KEY);
2009
2010 if (fll_id == WM8904_FLL_FREE_RUNNING) {
2011 val = WM8904_FLL_FRC_NCO;
2012 } else {
2013 val = 0;
2014 }
2015
2016 snd_soc_update_bits(codec, WM8904_FLL_NCO_TEST_1, WM8904_FLL_FRC_NCO,
2017 val);
2018 snd_soc_update_bits(codec, WM8904_CONTROL_INTERFACE_TEST_1,
2019 WM8904_USER_KEY, 0);
2020
2021 switch (fll_id) {
2022 case WM8904_FLL_MCLK:
2023 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_5,
2024 WM8904_FLL_CLK_REF_SRC_MASK, 0);
2025 break;
2026
2027 case WM8904_FLL_LRCLK:
2028 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_5,
2029 WM8904_FLL_CLK_REF_SRC_MASK, 1);
2030 break;
2031
2032 case WM8904_FLL_BCLK:
2033 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_5,
2034 WM8904_FLL_CLK_REF_SRC_MASK, 2);
2035 break;
2036 }
2037
2038 if (fll_div.k)
2039 val = WM8904_FLL_FRACN_ENA;
2040 else
2041 val = 0;
2042 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
2043 WM8904_FLL_FRACN_ENA, val);
2044
2045 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_2,
2046 WM8904_FLL_OUTDIV_MASK | WM8904_FLL_FRATIO_MASK,
2047 (fll_div.fll_outdiv << WM8904_FLL_OUTDIV_SHIFT) |
2048 (fll_div.fll_fratio << WM8904_FLL_FRATIO_SHIFT));
2049
2050 snd_soc_write(codec, WM8904_FLL_CONTROL_3, fll_div.k);
2051
2052 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_4, WM8904_FLL_N_MASK,
2053 fll_div.n << WM8904_FLL_N_SHIFT);
2054
2055 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_5,
2056 WM8904_FLL_CLK_REF_DIV_MASK,
2057 fll_div.fll_clk_ref_div
2058 << WM8904_FLL_CLK_REF_DIV_SHIFT);
2059
2060 dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout);
2061
2062 wm8904->fll_fref = Fref;
2063 wm8904->fll_fout = Fout;
2064 wm8904->fll_src = source;
2065
2066 /* Enable the FLL if it was previously active */
2067 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
2068 WM8904_FLL_OSC_ENA, fll1);
2069 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
2070 WM8904_FLL_ENA, fll1);
2071
2072out:
2073 /* Reenable SYSCLK if it was previously active */
2074 snd_soc_update_bits(codec, WM8904_CLOCK_RATES_2,
2075 WM8904_CLK_SYS_ENA, clock2);
2076
2077 return 0;
2078}
2079
2080static int wm8904_digital_mute(struct snd_soc_dai *codec_dai, int mute)
2081{
2082 struct snd_soc_codec *codec = codec_dai->codec;
2083 int val;
2084
2085 if (mute)
2086 val = WM8904_DAC_MUTE;
2087 else
2088 val = 0;
2089
2090 snd_soc_update_bits(codec, WM8904_DAC_DIGITAL_1, WM8904_DAC_MUTE, val);
2091
2092 return 0;
2093}
2094
2095static void wm8904_sync_cache(struct snd_soc_codec *codec)
2096{
2097 struct wm8904_priv *wm8904 = codec->private_data;
2098 int i;
2099
2100 if (!codec->cache_sync)
2101 return;
2102
2103 codec->cache_only = 0;
2104
2105 /* Sync back cached values if they're different from the
2106 * hardware default.
2107 */
2108 for (i = 1; i < ARRAY_SIZE(wm8904->reg_cache); i++) {
2109 if (!wm8904_access[i].writable)
2110 continue;
2111
2112 if (wm8904->reg_cache[i] == wm8904_reg[i])
2113 continue;
2114
2115 snd_soc_write(codec, i, wm8904->reg_cache[i]);
2116 }
2117
2118 codec->cache_sync = 0;
2119}
2120
2121static int wm8904_set_bias_level(struct snd_soc_codec *codec,
2122 enum snd_soc_bias_level level)
2123{
2124 struct wm8904_priv *wm8904 = codec->private_data;
2125 int ret;
2126
2127 switch (level) {
2128 case SND_SOC_BIAS_ON:
2129 break;
2130
2131 case SND_SOC_BIAS_PREPARE:
2132 /* VMID resistance 2*50k */
2133 snd_soc_update_bits(codec, WM8904_VMID_CONTROL_0,
2134 WM8904_VMID_RES_MASK,
2135 0x1 << WM8904_VMID_RES_SHIFT);
2136
2137 /* Normal bias current */
2138 snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0,
2139 WM8904_ISEL_MASK, 2 << WM8904_ISEL_SHIFT);
2140 break;
2141
2142 case SND_SOC_BIAS_STANDBY:
2143 if (codec->bias_level == SND_SOC_BIAS_OFF) {
2144 ret = regulator_bulk_enable(ARRAY_SIZE(wm8904->supplies),
2145 wm8904->supplies);
2146 if (ret != 0) {
2147 dev_err(codec->dev,
2148 "Failed to enable supplies: %d\n",
2149 ret);
2150 return ret;
2151 }
2152
2153 wm8904_sync_cache(codec);
2154
2155 /* Enable bias */
2156 snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0,
2157 WM8904_BIAS_ENA, WM8904_BIAS_ENA);
2158
2159 /* Enable VMID, VMID buffering, 2*5k resistance */
2160 snd_soc_update_bits(codec, WM8904_VMID_CONTROL_0,
2161 WM8904_VMID_ENA |
2162 WM8904_VMID_RES_MASK,
2163 WM8904_VMID_ENA |
2164 0x3 << WM8904_VMID_RES_SHIFT);
2165
2166 /* Let VMID ramp */
2167 msleep(1);
2168 }
2169
2170 /* Maintain VMID with 2*250k */
2171 snd_soc_update_bits(codec, WM8904_VMID_CONTROL_0,
2172 WM8904_VMID_RES_MASK,
2173 0x2 << WM8904_VMID_RES_SHIFT);
2174
2175 /* Bias current *0.5 */
2176 snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0,
2177 WM8904_ISEL_MASK, 0);
2178 break;
2179
2180 case SND_SOC_BIAS_OFF:
2181 /* Turn off VMID */
2182 snd_soc_update_bits(codec, WM8904_VMID_CONTROL_0,
2183 WM8904_VMID_RES_MASK | WM8904_VMID_ENA, 0);
2184
2185 /* Stop bias generation */
2186 snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0,
2187 WM8904_BIAS_ENA, 0);
2188
2189#ifdef CONFIG_REGULATOR
2190 /* Post 2.6.34 we will be able to get a callback when
2191 * the regulators are disabled which we can use but
2192 * for now just assume that the power will be cut if
2193 * the regulator API is in use.
2194 */
2195 codec->cache_sync = 1;
2196#endif
2197
2198 regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies),
2199 wm8904->supplies);
2200 break;
2201 }
2202 codec->bias_level = level;
2203 return 0;
2204}
2205
2206#define WM8904_RATES SNDRV_PCM_RATE_8000_96000
2207
2208#define WM8904_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
2209 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
2210
2211static struct snd_soc_dai_ops wm8904_dai_ops = {
2212 .set_sysclk = wm8904_set_sysclk,
2213 .set_fmt = wm8904_set_fmt,
2214 .set_tdm_slot = wm8904_set_tdm_slot,
2215 .set_pll = wm8904_set_fll,
2216 .hw_params = wm8904_hw_params,
2217 .digital_mute = wm8904_digital_mute,
2218};
2219
2220struct snd_soc_dai wm8904_dai = {
2221 .name = "WM8904",
2222 .playback = {
2223 .stream_name = "Playback",
2224 .channels_min = 2,
2225 .channels_max = 2,
2226 .rates = WM8904_RATES,
2227 .formats = WM8904_FORMATS,
2228 },
2229 .capture = {
2230 .stream_name = "Capture",
2231 .channels_min = 2,
2232 .channels_max = 2,
2233 .rates = WM8904_RATES,
2234 .formats = WM8904_FORMATS,
2235 },
2236 .ops = &wm8904_dai_ops,
2237 .symmetric_rates = 1,
2238};
2239EXPORT_SYMBOL_GPL(wm8904_dai);
2240
2241#ifdef CONFIG_PM
2242static int wm8904_suspend(struct platform_device *pdev, pm_message_t state)
2243{
2244 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2245 struct snd_soc_codec *codec = socdev->card->codec;
2246
2247 wm8904_set_bias_level(codec, SND_SOC_BIAS_OFF);
2248
2249 return 0;
2250}
2251
2252static int wm8904_resume(struct platform_device *pdev)
2253{
2254 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2255 struct snd_soc_codec *codec = socdev->card->codec;
2256
2257 wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2258
2259 return 0;
2260}
2261#else
2262#define wm8904_suspend NULL
2263#define wm8904_resume NULL
2264#endif
2265
2266static void wm8904_handle_retune_mobile_pdata(struct wm8904_priv *wm8904)
2267{
2268 struct snd_soc_codec *codec = &wm8904->codec;
2269 struct wm8904_pdata *pdata = wm8904->pdata;
2270 struct snd_kcontrol_new control =
2271 SOC_ENUM_EXT("EQ Mode",
2272 wm8904->retune_mobile_enum,
2273 wm8904_get_retune_mobile_enum,
2274 wm8904_put_retune_mobile_enum);
2275 int ret, i, j;
2276 const char **t;
2277
2278 /* We need an array of texts for the enum API but the number
2279 * of texts is likely to be less than the number of
2280 * configurations due to the sample rate dependency of the
2281 * configurations. */
2282 wm8904->num_retune_mobile_texts = 0;
2283 wm8904->retune_mobile_texts = NULL;
2284 for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) {
2285 for (j = 0; j < wm8904->num_retune_mobile_texts; j++) {
2286 if (strcmp(pdata->retune_mobile_cfgs[i].name,
2287 wm8904->retune_mobile_texts[j]) == 0)
2288 break;
2289 }
2290
2291 if (j != wm8904->num_retune_mobile_texts)
2292 continue;
2293
2294 /* Expand the array... */
2295 t = krealloc(wm8904->retune_mobile_texts,
2296 sizeof(char *) *
2297 (wm8904->num_retune_mobile_texts + 1),
2298 GFP_KERNEL);
2299 if (t == NULL)
2300 continue;
2301
2302 /* ...store the new entry... */
2303 t[wm8904->num_retune_mobile_texts] =
2304 pdata->retune_mobile_cfgs[i].name;
2305
2306 /* ...and remember the new version. */
2307 wm8904->num_retune_mobile_texts++;
2308 wm8904->retune_mobile_texts = t;
2309 }
2310
2311 dev_dbg(codec->dev, "Allocated %d unique ReTune Mobile names\n",
2312 wm8904->num_retune_mobile_texts);
2313
2314 wm8904->retune_mobile_enum.max = wm8904->num_retune_mobile_texts;
2315 wm8904->retune_mobile_enum.texts = wm8904->retune_mobile_texts;
2316
2317 ret = snd_soc_add_controls(&wm8904->codec, &control, 1);
2318 if (ret != 0)
2319 dev_err(wm8904->codec.dev,
2320 "Failed to add ReTune Mobile control: %d\n", ret);
2321}
2322
2323static void wm8904_handle_pdata(struct wm8904_priv *wm8904)
2324{
2325 struct snd_soc_codec *codec = &wm8904->codec;
2326 struct wm8904_pdata *pdata = wm8904->pdata;
2327 int ret, i;
2328
2329 if (!pdata) {
2330 snd_soc_add_controls(&wm8904->codec, wm8904_eq_controls,
2331 ARRAY_SIZE(wm8904_eq_controls));
2332 return;
2333 }
2334
2335 dev_dbg(codec->dev, "%d DRC configurations\n", pdata->num_drc_cfgs);
2336
2337 if (pdata->num_drc_cfgs) {
2338 struct snd_kcontrol_new control =
2339 SOC_ENUM_EXT("DRC Mode", wm8904->drc_enum,
2340 wm8904_get_drc_enum, wm8904_put_drc_enum);
2341
2342 /* We need an array of texts for the enum API */
2343 wm8904->drc_texts = kmalloc(sizeof(char *)
2344 * pdata->num_drc_cfgs, GFP_KERNEL);
2345 if (!wm8904->drc_texts) {
2346 dev_err(wm8904->codec.dev,
2347 "Failed to allocate %d DRC config texts\n",
2348 pdata->num_drc_cfgs);
2349 return;
2350 }
2351
2352 for (i = 0; i < pdata->num_drc_cfgs; i++)
2353 wm8904->drc_texts[i] = pdata->drc_cfgs[i].name;
2354
2355 wm8904->drc_enum.max = pdata->num_drc_cfgs;
2356 wm8904->drc_enum.texts = wm8904->drc_texts;
2357
2358 ret = snd_soc_add_controls(&wm8904->codec, &control, 1);
2359 if (ret != 0)
2360 dev_err(wm8904->codec.dev,
2361 "Failed to add DRC mode control: %d\n", ret);
2362
2363 wm8904_set_drc(codec);
2364 }
2365
2366 dev_dbg(codec->dev, "%d ReTune Mobile configurations\n",
2367 pdata->num_retune_mobile_cfgs);
2368
2369 if (pdata->num_retune_mobile_cfgs)
2370 wm8904_handle_retune_mobile_pdata(wm8904);
2371 else
2372 snd_soc_add_controls(&wm8904->codec, wm8904_eq_controls,
2373 ARRAY_SIZE(wm8904_eq_controls));
2374}
2375
2376static int wm8904_probe(struct platform_device *pdev)
2377{
2378 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2379 struct snd_soc_codec *codec;
2380 int ret = 0;
2381
2382 if (wm8904_codec == NULL) {
2383 dev_err(&pdev->dev, "Codec device not registered\n");
2384 return -ENODEV;
2385 }
2386
2387 socdev->card->codec = wm8904_codec;
2388 codec = wm8904_codec;
2389
2390 /* register pcms */
2391 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
2392 if (ret < 0) {
2393 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
2394 goto pcm_err;
2395 }
2396
2397 wm8904_handle_pdata(codec->private_data);
2398
2399 wm8904_add_widgets(codec);
2400
2401 return ret;
2402
2403pcm_err:
2404 return ret;
2405}
2406
2407static int wm8904_remove(struct platform_device *pdev)
2408{
2409 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2410
2411 snd_soc_free_pcms(socdev);
2412 snd_soc_dapm_free(socdev);
2413
2414 return 0;
2415}
2416
2417struct snd_soc_codec_device soc_codec_dev_wm8904 = {
2418 .probe = wm8904_probe,
2419 .remove = wm8904_remove,
2420 .suspend = wm8904_suspend,
2421 .resume = wm8904_resume,
2422};
2423EXPORT_SYMBOL_GPL(soc_codec_dev_wm8904);
2424
2425static int wm8904_register(struct wm8904_priv *wm8904,
2426 enum snd_soc_control_type control)
2427{
2428 int ret;
2429 struct snd_soc_codec *codec = &wm8904->codec;
2430 int i;
2431
2432 if (wm8904_codec) {
2433 dev_err(codec->dev, "Another WM8904 is registered\n");
2434 return -EINVAL;
2435 }
2436
2437 mutex_init(&codec->mutex);
2438 INIT_LIST_HEAD(&codec->dapm_widgets);
2439 INIT_LIST_HEAD(&codec->dapm_paths);
2440
2441 codec->private_data = wm8904;
2442 codec->name = "WM8904";
2443 codec->owner = THIS_MODULE;
2444 codec->bias_level = SND_SOC_BIAS_OFF;
2445 codec->set_bias_level = wm8904_set_bias_level;
2446 codec->dai = &wm8904_dai;
2447 codec->num_dai = 1;
2448 codec->reg_cache_size = WM8904_MAX_REGISTER;
2449 codec->reg_cache = &wm8904->reg_cache;
2450 codec->volatile_register = wm8904_volatile_register;
2451 codec->cache_sync = 1;
2452 codec->idle_bias_off = 1;
2453
2454 switch (wm8904->devtype) {
2455 case WM8904:
2456 break;
2457 case WM8912:
2458 memset(&wm8904_dai.capture, 0, sizeof(wm8904_dai.capture));
2459 break;
2460 default:
2461 dev_err(codec->dev, "Unknown device type %d\n",
2462 wm8904->devtype);
2463 return -EINVAL;
2464 }
2465
2466 memcpy(codec->reg_cache, wm8904_reg, sizeof(wm8904_reg));
2467
2468 ret = snd_soc_codec_set_cache_io(codec, 8, 16, control);
2469 if (ret != 0) {
2470 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
2471 goto err;
2472 }
2473
2474 for (i = 0; i < ARRAY_SIZE(wm8904->supplies); i++)
2475 wm8904->supplies[i].supply = wm8904_supply_names[i];
2476
2477 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8904->supplies),
2478 wm8904->supplies);
2479 if (ret != 0) {
2480 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
2481 goto err;
2482 }
2483
2484 ret = regulator_bulk_enable(ARRAY_SIZE(wm8904->supplies),
2485 wm8904->supplies);
2486 if (ret != 0) {
2487 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
2488 goto err_get;
2489 }
2490
2491 ret = snd_soc_read(codec, WM8904_SW_RESET_AND_ID);
2492 if (ret < 0) {
2493 dev_err(codec->dev, "Failed to read ID register\n");
2494 goto err_enable;
2495 }
2496 if (ret != wm8904_reg[WM8904_SW_RESET_AND_ID]) {
2497 dev_err(codec->dev, "Device is not a WM8904, ID is %x\n", ret);
2498 ret = -EINVAL;
2499 goto err_enable;
2500 }
2501
2502 ret = snd_soc_read(codec, WM8904_REVISION);
2503 if (ret < 0) {
2504 dev_err(codec->dev, "Failed to read device revision: %d\n",
2505 ret);
2506 goto err_enable;
2507 }
2508 dev_info(codec->dev, "revision %c\n", ret + 'A');
2509
2510 ret = wm8904_reset(codec);
2511 if (ret < 0) {
2512 dev_err(codec->dev, "Failed to issue reset\n");
2513 goto err_enable;
2514 }
2515
2516 wm8904_dai.dev = codec->dev;
2517
2518 /* Change some default settings - latch VU and enable ZC */
2519 wm8904->reg_cache[WM8904_ADC_DIGITAL_VOLUME_LEFT] |= WM8904_ADC_VU;
2520 wm8904->reg_cache[WM8904_ADC_DIGITAL_VOLUME_RIGHT] |= WM8904_ADC_VU;
2521 wm8904->reg_cache[WM8904_DAC_DIGITAL_VOLUME_LEFT] |= WM8904_DAC_VU;
2522 wm8904->reg_cache[WM8904_DAC_DIGITAL_VOLUME_RIGHT] |= WM8904_DAC_VU;
2523 wm8904->reg_cache[WM8904_ANALOGUE_OUT1_LEFT] |= WM8904_HPOUT_VU |
2524 WM8904_HPOUTLZC;
2525 wm8904->reg_cache[WM8904_ANALOGUE_OUT1_RIGHT] |= WM8904_HPOUT_VU |
2526 WM8904_HPOUTRZC;
2527 wm8904->reg_cache[WM8904_ANALOGUE_OUT2_LEFT] |= WM8904_LINEOUT_VU |
2528 WM8904_LINEOUTLZC;
2529 wm8904->reg_cache[WM8904_ANALOGUE_OUT2_RIGHT] |= WM8904_LINEOUT_VU |
2530 WM8904_LINEOUTRZC;
2531 wm8904->reg_cache[WM8904_CLOCK_RATES_0] &= ~WM8904_SR_MODE;
2532
2533 /* Set Class W by default - this will be managed by the Class
2534 * G widget at runtime where bypass paths are available.
2535 */
2536 wm8904->reg_cache[WM8904_CLASS_W_0] |= WM8904_CP_DYN_PWR;
2537
2538 /* Use normal bias source */
2539 wm8904->reg_cache[WM8904_BIAS_CONTROL_0] &= ~WM8904_POBCTRL;
2540
2541 wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2542
2543 /* Bias level configuration will have done an extra enable */
2544 regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2545
2546 wm8904_codec = codec;
2547
2548 ret = snd_soc_register_codec(codec);
2549 if (ret != 0) {
2550 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
2551 return ret;
2552 }
2553
2554 ret = snd_soc_register_dai(&wm8904_dai);
2555 if (ret != 0) {
2556 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
2557 snd_soc_unregister_codec(codec);
2558 return ret;
2559 }
2560
2561 return 0;
2562
2563err_enable:
2564 regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2565err_get:
2566 regulator_bulk_free(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2567err:
2568 kfree(wm8904);
2569 return ret;
2570}
2571
2572static void wm8904_unregister(struct wm8904_priv *wm8904)
2573{
2574 wm8904_set_bias_level(&wm8904->codec, SND_SOC_BIAS_OFF);
2575 regulator_bulk_free(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2576 snd_soc_unregister_dai(&wm8904_dai);
2577 snd_soc_unregister_codec(&wm8904->codec);
2578 kfree(wm8904);
2579 wm8904_codec = NULL;
2580}
2581
2582#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
2583static __devinit int wm8904_i2c_probe(struct i2c_client *i2c,
2584 const struct i2c_device_id *id)
2585{
2586 struct wm8904_priv *wm8904;
2587 struct snd_soc_codec *codec;
2588
2589 wm8904 = kzalloc(sizeof(struct wm8904_priv), GFP_KERNEL);
2590 if (wm8904 == NULL)
2591 return -ENOMEM;
2592
2593 codec = &wm8904->codec;
2594 codec->hw_write = (hw_write_t)i2c_master_send;
2595
2596 wm8904->devtype = id->driver_data;
2597
2598 i2c_set_clientdata(i2c, wm8904);
2599 codec->control_data = i2c;
2600 wm8904->pdata = i2c->dev.platform_data;
2601
2602 codec->dev = &i2c->dev;
2603
2604 return wm8904_register(wm8904, SND_SOC_I2C);
2605}
2606
2607static __devexit int wm8904_i2c_remove(struct i2c_client *client)
2608{
2609 struct wm8904_priv *wm8904 = i2c_get_clientdata(client);
2610 wm8904_unregister(wm8904);
2611 return 0;
2612}
2613
2614static const struct i2c_device_id wm8904_i2c_id[] = {
2615 { "wm8904", WM8904 },
2616 { "wm8912", WM8912 },
2617 { }
2618};
2619MODULE_DEVICE_TABLE(i2c, wm8904_i2c_id);
2620
2621static struct i2c_driver wm8904_i2c_driver = {
2622 .driver = {
2623 .name = "WM8904",
2624 .owner = THIS_MODULE,
2625 },
2626 .probe = wm8904_i2c_probe,
2627 .remove = __devexit_p(wm8904_i2c_remove),
2628 .id_table = wm8904_i2c_id,
2629};
2630#endif
2631
2632static int __init wm8904_modinit(void)
2633{
2634 int ret;
2635#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
2636 ret = i2c_add_driver(&wm8904_i2c_driver);
2637 if (ret != 0) {
2638 printk(KERN_ERR "Failed to register WM8904 I2C driver: %d\n",
2639 ret);
2640 }
2641#endif
2642 return 0;
2643}
2644module_init(wm8904_modinit);
2645
2646static void __exit wm8904_exit(void)
2647{
2648#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
2649 i2c_del_driver(&wm8904_i2c_driver);
2650#endif
2651}
2652module_exit(wm8904_exit);
2653
2654MODULE_DESCRIPTION("ASoC WM8904 driver");
2655MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
2656MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8904.h b/sound/soc/codecs/wm8904.h
new file mode 100644
index 000000000000..b68886df34e4
--- /dev/null
+++ b/sound/soc/codecs/wm8904.h
@@ -0,0 +1,1681 @@
1/*
2 * wm8904.h -- WM8904 ASoC driver
3 *
4 * Copyright 2009 Wolfson Microelectronics, plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef _WM8904_H
14#define _WM8904_H
15
16#define WM8904_CLK_MCLK 1
17#define WM8904_CLK_FLL 2
18
19#define WM8904_FLL_MCLK 1
20#define WM8904_FLL_BCLK 2
21#define WM8904_FLL_LRCLK 3
22#define WM8904_FLL_FREE_RUNNING 4
23
24extern struct snd_soc_dai wm8904_dai;
25extern struct snd_soc_codec_device soc_codec_dev_wm8904;
26
27/*
28 * Register values.
29 */
30#define WM8904_SW_RESET_AND_ID 0x00
31#define WM8904_REVISION 0x01
32#define WM8904_BIAS_CONTROL_0 0x04
33#define WM8904_VMID_CONTROL_0 0x05
34#define WM8904_MIC_BIAS_CONTROL_0 0x06
35#define WM8904_MIC_BIAS_CONTROL_1 0x07
36#define WM8904_ANALOGUE_DAC_0 0x08
37#define WM8904_MIC_FILTER_CONTROL 0x09
38#define WM8904_ANALOGUE_ADC_0 0x0A
39#define WM8904_POWER_MANAGEMENT_0 0x0C
40#define WM8904_POWER_MANAGEMENT_2 0x0E
41#define WM8904_POWER_MANAGEMENT_3 0x0F
42#define WM8904_POWER_MANAGEMENT_6 0x12
43#define WM8904_CLOCK_RATES_0 0x14
44#define WM8904_CLOCK_RATES_1 0x15
45#define WM8904_CLOCK_RATES_2 0x16
46#define WM8904_AUDIO_INTERFACE_0 0x18
47#define WM8904_AUDIO_INTERFACE_1 0x19
48#define WM8904_AUDIO_INTERFACE_2 0x1A
49#define WM8904_AUDIO_INTERFACE_3 0x1B
50#define WM8904_DAC_DIGITAL_VOLUME_LEFT 0x1E
51#define WM8904_DAC_DIGITAL_VOLUME_RIGHT 0x1F
52#define WM8904_DAC_DIGITAL_0 0x20
53#define WM8904_DAC_DIGITAL_1 0x21
54#define WM8904_ADC_DIGITAL_VOLUME_LEFT 0x24
55#define WM8904_ADC_DIGITAL_VOLUME_RIGHT 0x25
56#define WM8904_ADC_DIGITAL_0 0x26
57#define WM8904_DIGITAL_MICROPHONE_0 0x27
58#define WM8904_DRC_0 0x28
59#define WM8904_DRC_1 0x29
60#define WM8904_DRC_2 0x2A
61#define WM8904_DRC_3 0x2B
62#define WM8904_ANALOGUE_LEFT_INPUT_0 0x2C
63#define WM8904_ANALOGUE_RIGHT_INPUT_0 0x2D
64#define WM8904_ANALOGUE_LEFT_INPUT_1 0x2E
65#define WM8904_ANALOGUE_RIGHT_INPUT_1 0x2F
66#define WM8904_ANALOGUE_OUT1_LEFT 0x39
67#define WM8904_ANALOGUE_OUT1_RIGHT 0x3A
68#define WM8904_ANALOGUE_OUT2_LEFT 0x3B
69#define WM8904_ANALOGUE_OUT2_RIGHT 0x3C
70#define WM8904_ANALOGUE_OUT12_ZC 0x3D
71#define WM8904_DC_SERVO_0 0x43
72#define WM8904_DC_SERVO_1 0x44
73#define WM8904_DC_SERVO_2 0x45
74#define WM8904_DC_SERVO_4 0x47
75#define WM8904_DC_SERVO_5 0x48
76#define WM8904_DC_SERVO_6 0x49
77#define WM8904_DC_SERVO_7 0x4A
78#define WM8904_DC_SERVO_8 0x4B
79#define WM8904_DC_SERVO_9 0x4C
80#define WM8904_DC_SERVO_READBACK_0 0x4D
81#define WM8904_ANALOGUE_HP_0 0x5A
82#define WM8904_ANALOGUE_LINEOUT_0 0x5E
83#define WM8904_CHARGE_PUMP_0 0x62
84#define WM8904_CLASS_W_0 0x68
85#define WM8904_WRITE_SEQUENCER_0 0x6C
86#define WM8904_WRITE_SEQUENCER_1 0x6D
87#define WM8904_WRITE_SEQUENCER_2 0x6E
88#define WM8904_WRITE_SEQUENCER_3 0x6F
89#define WM8904_WRITE_SEQUENCER_4 0x70
90#define WM8904_FLL_CONTROL_1 0x74
91#define WM8904_FLL_CONTROL_2 0x75
92#define WM8904_FLL_CONTROL_3 0x76
93#define WM8904_FLL_CONTROL_4 0x77
94#define WM8904_FLL_CONTROL_5 0x78
95#define WM8904_GPIO_CONTROL_1 0x79
96#define WM8904_GPIO_CONTROL_2 0x7A
97#define WM8904_GPIO_CONTROL_3 0x7B
98#define WM8904_GPIO_CONTROL_4 0x7C
99#define WM8904_DIGITAL_PULLS 0x7E
100#define WM8904_INTERRUPT_STATUS 0x7F
101#define WM8904_INTERRUPT_STATUS_MASK 0x80
102#define WM8904_INTERRUPT_POLARITY 0x81
103#define WM8904_INTERRUPT_DEBOUNCE 0x82
104#define WM8904_EQ1 0x86
105#define WM8904_EQ2 0x87
106#define WM8904_EQ3 0x88
107#define WM8904_EQ4 0x89
108#define WM8904_EQ5 0x8A
109#define WM8904_EQ6 0x8B
110#define WM8904_EQ7 0x8C
111#define WM8904_EQ8 0x8D
112#define WM8904_EQ9 0x8E
113#define WM8904_EQ10 0x8F
114#define WM8904_EQ11 0x90
115#define WM8904_EQ12 0x91
116#define WM8904_EQ13 0x92
117#define WM8904_EQ14 0x93
118#define WM8904_EQ15 0x94
119#define WM8904_EQ16 0x95
120#define WM8904_EQ17 0x96
121#define WM8904_EQ18 0x97
122#define WM8904_EQ19 0x98
123#define WM8904_EQ20 0x99
124#define WM8904_EQ21 0x9A
125#define WM8904_EQ22 0x9B
126#define WM8904_EQ23 0x9C
127#define WM8904_EQ24 0x9D
128#define WM8904_CONTROL_INTERFACE_TEST_1 0xA1
129#define WM8904_ANALOGUE_OUTPUT_BIAS_0 0xCC
130#define WM8904_FLL_NCO_TEST_0 0xF7
131#define WM8904_FLL_NCO_TEST_1 0xF8
132
133#define WM8904_REGISTER_COUNT 101
134#define WM8904_MAX_REGISTER 0xF8
135
136/*
137 * Field Definitions.
138 */
139
140/*
141 * R0 (0x00) - SW Reset and ID
142 */
143#define WM8904_SW_RST_DEV_ID1_MASK 0xFFFF /* SW_RST_DEV_ID1 - [15:0] */
144#define WM8904_SW_RST_DEV_ID1_SHIFT 0 /* SW_RST_DEV_ID1 - [15:0] */
145#define WM8904_SW_RST_DEV_ID1_WIDTH 16 /* SW_RST_DEV_ID1 - [15:0] */
146
147/*
148 * R1 (0x01) - Revision
149 */
150#define WM8904_REVISION_MASK 0x000F /* REVISION - [3:0] */
151#define WM8904_REVISION_SHIFT 0 /* REVISION - [3:0] */
152#define WM8904_REVISION_WIDTH 16 /* REVISION - [3:0] */
153
154/*
155 * R4 (0x04) - Bias Control 0
156 */
157#define WM8904_POBCTRL 0x0010 /* POBCTRL */
158#define WM8904_POBCTRL_MASK 0x0010 /* POBCTRL */
159#define WM8904_POBCTRL_SHIFT 4 /* POBCTRL */
160#define WM8904_POBCTRL_WIDTH 1 /* POBCTRL */
161#define WM8904_ISEL_MASK 0x000C /* ISEL - [3:2] */
162#define WM8904_ISEL_SHIFT 2 /* ISEL - [3:2] */
163#define WM8904_ISEL_WIDTH 2 /* ISEL - [3:2] */
164#define WM8904_STARTUP_BIAS_ENA 0x0002 /* STARTUP_BIAS_ENA */
165#define WM8904_STARTUP_BIAS_ENA_MASK 0x0002 /* STARTUP_BIAS_ENA */
166#define WM8904_STARTUP_BIAS_ENA_SHIFT 1 /* STARTUP_BIAS_ENA */
167#define WM8904_STARTUP_BIAS_ENA_WIDTH 1 /* STARTUP_BIAS_ENA */
168#define WM8904_BIAS_ENA 0x0001 /* BIAS_ENA */
169#define WM8904_BIAS_ENA_MASK 0x0001 /* BIAS_ENA */
170#define WM8904_BIAS_ENA_SHIFT 0 /* BIAS_ENA */
171#define WM8904_BIAS_ENA_WIDTH 1 /* BIAS_ENA */
172
173/*
174 * R5 (0x05) - VMID Control 0
175 */
176#define WM8904_VMID_BUF_ENA 0x0040 /* VMID_BUF_ENA */
177#define WM8904_VMID_BUF_ENA_MASK 0x0040 /* VMID_BUF_ENA */
178#define WM8904_VMID_BUF_ENA_SHIFT 6 /* VMID_BUF_ENA */
179#define WM8904_VMID_BUF_ENA_WIDTH 1 /* VMID_BUF_ENA */
180#define WM8904_VMID_RES_MASK 0x0006 /* VMID_RES - [2:1] */
181#define WM8904_VMID_RES_SHIFT 1 /* VMID_RES - [2:1] */
182#define WM8904_VMID_RES_WIDTH 2 /* VMID_RES - [2:1] */
183#define WM8904_VMID_ENA 0x0001 /* VMID_ENA */
184#define WM8904_VMID_ENA_MASK 0x0001 /* VMID_ENA */
185#define WM8904_VMID_ENA_SHIFT 0 /* VMID_ENA */
186#define WM8904_VMID_ENA_WIDTH 1 /* VMID_ENA */
187
188/*
189 * R6 (0x06) - Mic Bias Control 0
190 */
191#define WM8904_MICDET_THR_MASK 0x0070 /* MICDET_THR - [6:4] */
192#define WM8904_MICDET_THR_SHIFT 4 /* MICDET_THR - [6:4] */
193#define WM8904_MICDET_THR_WIDTH 3 /* MICDET_THR - [6:4] */
194#define WM8904_MICSHORT_THR_MASK 0x000C /* MICSHORT_THR - [3:2] */
195#define WM8904_MICSHORT_THR_SHIFT 2 /* MICSHORT_THR - [3:2] */
196#define WM8904_MICSHORT_THR_WIDTH 2 /* MICSHORT_THR - [3:2] */
197#define WM8904_MICDET_ENA 0x0002 /* MICDET_ENA */
198#define WM8904_MICDET_ENA_MASK 0x0002 /* MICDET_ENA */
199#define WM8904_MICDET_ENA_SHIFT 1 /* MICDET_ENA */
200#define WM8904_MICDET_ENA_WIDTH 1 /* MICDET_ENA */
201#define WM8904_MICBIAS_ENA 0x0001 /* MICBIAS_ENA */
202#define WM8904_MICBIAS_ENA_MASK 0x0001 /* MICBIAS_ENA */
203#define WM8904_MICBIAS_ENA_SHIFT 0 /* MICBIAS_ENA */
204#define WM8904_MICBIAS_ENA_WIDTH 1 /* MICBIAS_ENA */
205
206/*
207 * R7 (0x07) - Mic Bias Control 1
208 */
209#define WM8904_MIC_DET_FILTER_ENA 0x8000 /* MIC_DET_FILTER_ENA */
210#define WM8904_MIC_DET_FILTER_ENA_MASK 0x8000 /* MIC_DET_FILTER_ENA */
211#define WM8904_MIC_DET_FILTER_ENA_SHIFT 15 /* MIC_DET_FILTER_ENA */
212#define WM8904_MIC_DET_FILTER_ENA_WIDTH 1 /* MIC_DET_FILTER_ENA */
213#define WM8904_MIC_SHORT_FILTER_ENA 0x4000 /* MIC_SHORT_FILTER_ENA */
214#define WM8904_MIC_SHORT_FILTER_ENA_MASK 0x4000 /* MIC_SHORT_FILTER_ENA */
215#define WM8904_MIC_SHORT_FILTER_ENA_SHIFT 14 /* MIC_SHORT_FILTER_ENA */
216#define WM8904_MIC_SHORT_FILTER_ENA_WIDTH 1 /* MIC_SHORT_FILTER_ENA */
217#define WM8904_MICBIAS_SEL_MASK 0x0007 /* MICBIAS_SEL - [2:0] */
218#define WM8904_MICBIAS_SEL_SHIFT 0 /* MICBIAS_SEL - [2:0] */
219#define WM8904_MICBIAS_SEL_WIDTH 3 /* MICBIAS_SEL - [2:0] */
220
221/*
222 * R8 (0x08) - Analogue DAC 0
223 */
224#define WM8904_DAC_BIAS_SEL_MASK 0x0018 /* DAC_BIAS_SEL - [4:3] */
225#define WM8904_DAC_BIAS_SEL_SHIFT 3 /* DAC_BIAS_SEL - [4:3] */
226#define WM8904_DAC_BIAS_SEL_WIDTH 2 /* DAC_BIAS_SEL - [4:3] */
227#define WM8904_DAC_VMID_BIAS_SEL_MASK 0x0006 /* DAC_VMID_BIAS_SEL - [2:1] */
228#define WM8904_DAC_VMID_BIAS_SEL_SHIFT 1 /* DAC_VMID_BIAS_SEL - [2:1] */
229#define WM8904_DAC_VMID_BIAS_SEL_WIDTH 2 /* DAC_VMID_BIAS_SEL - [2:1] */
230
231/*
232 * R9 (0x09) - mic Filter Control
233 */
234#define WM8904_MIC_DET_SET_THRESHOLD_MASK 0xF000 /* MIC_DET_SET_THRESHOLD - [15:12] */
235#define WM8904_MIC_DET_SET_THRESHOLD_SHIFT 12 /* MIC_DET_SET_THRESHOLD - [15:12] */
236#define WM8904_MIC_DET_SET_THRESHOLD_WIDTH 4 /* MIC_DET_SET_THRESHOLD - [15:12] */
237#define WM8904_MIC_DET_RESET_THRESHOLD_MASK 0x0F00 /* MIC_DET_RESET_THRESHOLD - [11:8] */
238#define WM8904_MIC_DET_RESET_THRESHOLD_SHIFT 8 /* MIC_DET_RESET_THRESHOLD - [11:8] */
239#define WM8904_MIC_DET_RESET_THRESHOLD_WIDTH 4 /* MIC_DET_RESET_THRESHOLD - [11:8] */
240#define WM8904_MIC_SHORT_SET_THRESHOLD_MASK 0x00F0 /* MIC_SHORT_SET_THRESHOLD - [7:4] */
241#define WM8904_MIC_SHORT_SET_THRESHOLD_SHIFT 4 /* MIC_SHORT_SET_THRESHOLD - [7:4] */
242#define WM8904_MIC_SHORT_SET_THRESHOLD_WIDTH 4 /* MIC_SHORT_SET_THRESHOLD - [7:4] */
243#define WM8904_MIC_SHORT_RESET_THRESHOLD_MASK 0x000F /* MIC_SHORT_RESET_THRESHOLD - [3:0] */
244#define WM8904_MIC_SHORT_RESET_THRESHOLD_SHIFT 0 /* MIC_SHORT_RESET_THRESHOLD - [3:0] */
245#define WM8904_MIC_SHORT_RESET_THRESHOLD_WIDTH 4 /* MIC_SHORT_RESET_THRESHOLD - [3:0] */
246
247/*
248 * R10 (0x0A) - Analogue ADC 0
249 */
250#define WM8904_ADC_OSR128 0x0001 /* ADC_OSR128 */
251#define WM8904_ADC_OSR128_MASK 0x0001 /* ADC_OSR128 */
252#define WM8904_ADC_OSR128_SHIFT 0 /* ADC_OSR128 */
253#define WM8904_ADC_OSR128_WIDTH 1 /* ADC_OSR128 */
254
255/*
256 * R12 (0x0C) - Power Management 0
257 */
258#define WM8904_INL_ENA 0x0002 /* INL_ENA */
259#define WM8904_INL_ENA_MASK 0x0002 /* INL_ENA */
260#define WM8904_INL_ENA_SHIFT 1 /* INL_ENA */
261#define WM8904_INL_ENA_WIDTH 1 /* INL_ENA */
262#define WM8904_INR_ENA 0x0001 /* INR_ENA */
263#define WM8904_INR_ENA_MASK 0x0001 /* INR_ENA */
264#define WM8904_INR_ENA_SHIFT 0 /* INR_ENA */
265#define WM8904_INR_ENA_WIDTH 1 /* INR_ENA */
266
267/*
268 * R14 (0x0E) - Power Management 2
269 */
270#define WM8904_HPL_PGA_ENA 0x0002 /* HPL_PGA_ENA */
271#define WM8904_HPL_PGA_ENA_MASK 0x0002 /* HPL_PGA_ENA */
272#define WM8904_HPL_PGA_ENA_SHIFT 1 /* HPL_PGA_ENA */
273#define WM8904_HPL_PGA_ENA_WIDTH 1 /* HPL_PGA_ENA */
274#define WM8904_HPR_PGA_ENA 0x0001 /* HPR_PGA_ENA */
275#define WM8904_HPR_PGA_ENA_MASK 0x0001 /* HPR_PGA_ENA */
276#define WM8904_HPR_PGA_ENA_SHIFT 0 /* HPR_PGA_ENA */
277#define WM8904_HPR_PGA_ENA_WIDTH 1 /* HPR_PGA_ENA */
278
279/*
280 * R15 (0x0F) - Power Management 3
281 */
282#define WM8904_LINEOUTL_PGA_ENA 0x0002 /* LINEOUTL_PGA_ENA */
283#define WM8904_LINEOUTL_PGA_ENA_MASK 0x0002 /* LINEOUTL_PGA_ENA */
284#define WM8904_LINEOUTL_PGA_ENA_SHIFT 1 /* LINEOUTL_PGA_ENA */
285#define WM8904_LINEOUTL_PGA_ENA_WIDTH 1 /* LINEOUTL_PGA_ENA */
286#define WM8904_LINEOUTR_PGA_ENA 0x0001 /* LINEOUTR_PGA_ENA */
287#define WM8904_LINEOUTR_PGA_ENA_MASK 0x0001 /* LINEOUTR_PGA_ENA */
288#define WM8904_LINEOUTR_PGA_ENA_SHIFT 0 /* LINEOUTR_PGA_ENA */
289#define WM8904_LINEOUTR_PGA_ENA_WIDTH 1 /* LINEOUTR_PGA_ENA */
290
291/*
292 * R18 (0x12) - Power Management 6
293 */
294#define WM8904_DACL_ENA 0x0008 /* DACL_ENA */
295#define WM8904_DACL_ENA_MASK 0x0008 /* DACL_ENA */
296#define WM8904_DACL_ENA_SHIFT 3 /* DACL_ENA */
297#define WM8904_DACL_ENA_WIDTH 1 /* DACL_ENA */
298#define WM8904_DACR_ENA 0x0004 /* DACR_ENA */
299#define WM8904_DACR_ENA_MASK 0x0004 /* DACR_ENA */
300#define WM8904_DACR_ENA_SHIFT 2 /* DACR_ENA */
301#define WM8904_DACR_ENA_WIDTH 1 /* DACR_ENA */
302#define WM8904_ADCL_ENA 0x0002 /* ADCL_ENA */
303#define WM8904_ADCL_ENA_MASK 0x0002 /* ADCL_ENA */
304#define WM8904_ADCL_ENA_SHIFT 1 /* ADCL_ENA */
305#define WM8904_ADCL_ENA_WIDTH 1 /* ADCL_ENA */
306#define WM8904_ADCR_ENA 0x0001 /* ADCR_ENA */
307#define WM8904_ADCR_ENA_MASK 0x0001 /* ADCR_ENA */
308#define WM8904_ADCR_ENA_SHIFT 0 /* ADCR_ENA */
309#define WM8904_ADCR_ENA_WIDTH 1 /* ADCR_ENA */
310
311/*
312 * R20 (0x14) - Clock Rates 0
313 */
314#define WM8904_TOCLK_RATE_DIV16 0x4000 /* TOCLK_RATE_DIV16 */
315#define WM8904_TOCLK_RATE_DIV16_MASK 0x4000 /* TOCLK_RATE_DIV16 */
316#define WM8904_TOCLK_RATE_DIV16_SHIFT 14 /* TOCLK_RATE_DIV16 */
317#define WM8904_TOCLK_RATE_DIV16_WIDTH 1 /* TOCLK_RATE_DIV16 */
318#define WM8904_TOCLK_RATE_X4 0x2000 /* TOCLK_RATE_X4 */
319#define WM8904_TOCLK_RATE_X4_MASK 0x2000 /* TOCLK_RATE_X4 */
320#define WM8904_TOCLK_RATE_X4_SHIFT 13 /* TOCLK_RATE_X4 */
321#define WM8904_TOCLK_RATE_X4_WIDTH 1 /* TOCLK_RATE_X4 */
322#define WM8904_SR_MODE 0x1000 /* SR_MODE */
323#define WM8904_SR_MODE_MASK 0x1000 /* SR_MODE */
324#define WM8904_SR_MODE_SHIFT 12 /* SR_MODE */
325#define WM8904_SR_MODE_WIDTH 1 /* SR_MODE */
326#define WM8904_MCLK_DIV 0x0001 /* MCLK_DIV */
327#define WM8904_MCLK_DIV_MASK 0x0001 /* MCLK_DIV */
328#define WM8904_MCLK_DIV_SHIFT 0 /* MCLK_DIV */
329#define WM8904_MCLK_DIV_WIDTH 1 /* MCLK_DIV */
330
331/*
332 * R21 (0x15) - Clock Rates 1
333 */
334#define WM8904_CLK_SYS_RATE_MASK 0x3C00 /* CLK_SYS_RATE - [13:10] */
335#define WM8904_CLK_SYS_RATE_SHIFT 10 /* CLK_SYS_RATE - [13:10] */
336#define WM8904_CLK_SYS_RATE_WIDTH 4 /* CLK_SYS_RATE - [13:10] */
337#define WM8904_SAMPLE_RATE_MASK 0x0007 /* SAMPLE_RATE - [2:0] */
338#define WM8904_SAMPLE_RATE_SHIFT 0 /* SAMPLE_RATE - [2:0] */
339#define WM8904_SAMPLE_RATE_WIDTH 3 /* SAMPLE_RATE - [2:0] */
340
341/*
342 * R22 (0x16) - Clock Rates 2
343 */
344#define WM8904_MCLK_INV 0x8000 /* MCLK_INV */
345#define WM8904_MCLK_INV_MASK 0x8000 /* MCLK_INV */
346#define WM8904_MCLK_INV_SHIFT 15 /* MCLK_INV */
347#define WM8904_MCLK_INV_WIDTH 1 /* MCLK_INV */
348#define WM8904_SYSCLK_SRC 0x4000 /* SYSCLK_SRC */
349#define WM8904_SYSCLK_SRC_MASK 0x4000 /* SYSCLK_SRC */
350#define WM8904_SYSCLK_SRC_SHIFT 14 /* SYSCLK_SRC */
351#define WM8904_SYSCLK_SRC_WIDTH 1 /* SYSCLK_SRC */
352#define WM8904_TOCLK_RATE 0x1000 /* TOCLK_RATE */
353#define WM8904_TOCLK_RATE_MASK 0x1000 /* TOCLK_RATE */
354#define WM8904_TOCLK_RATE_SHIFT 12 /* TOCLK_RATE */
355#define WM8904_TOCLK_RATE_WIDTH 1 /* TOCLK_RATE */
356#define WM8904_OPCLK_ENA 0x0008 /* OPCLK_ENA */
357#define WM8904_OPCLK_ENA_MASK 0x0008 /* OPCLK_ENA */
358#define WM8904_OPCLK_ENA_SHIFT 3 /* OPCLK_ENA */
359#define WM8904_OPCLK_ENA_WIDTH 1 /* OPCLK_ENA */
360#define WM8904_CLK_SYS_ENA 0x0004 /* CLK_SYS_ENA */
361#define WM8904_CLK_SYS_ENA_MASK 0x0004 /* CLK_SYS_ENA */
362#define WM8904_CLK_SYS_ENA_SHIFT 2 /* CLK_SYS_ENA */
363#define WM8904_CLK_SYS_ENA_WIDTH 1 /* CLK_SYS_ENA */
364#define WM8904_CLK_DSP_ENA 0x0002 /* CLK_DSP_ENA */
365#define WM8904_CLK_DSP_ENA_MASK 0x0002 /* CLK_DSP_ENA */
366#define WM8904_CLK_DSP_ENA_SHIFT 1 /* CLK_DSP_ENA */
367#define WM8904_CLK_DSP_ENA_WIDTH 1 /* CLK_DSP_ENA */
368#define WM8904_TOCLK_ENA 0x0001 /* TOCLK_ENA */
369#define WM8904_TOCLK_ENA_MASK 0x0001 /* TOCLK_ENA */
370#define WM8904_TOCLK_ENA_SHIFT 0 /* TOCLK_ENA */
371#define WM8904_TOCLK_ENA_WIDTH 1 /* TOCLK_ENA */
372
373/*
374 * R24 (0x18) - Audio Interface 0
375 */
376#define WM8904_DACL_DATINV 0x1000 /* DACL_DATINV */
377#define WM8904_DACL_DATINV_MASK 0x1000 /* DACL_DATINV */
378#define WM8904_DACL_DATINV_SHIFT 12 /* DACL_DATINV */
379#define WM8904_DACL_DATINV_WIDTH 1 /* DACL_DATINV */
380#define WM8904_DACR_DATINV 0x0800 /* DACR_DATINV */
381#define WM8904_DACR_DATINV_MASK 0x0800 /* DACR_DATINV */
382#define WM8904_DACR_DATINV_SHIFT 11 /* DACR_DATINV */
383#define WM8904_DACR_DATINV_WIDTH 1 /* DACR_DATINV */
384#define WM8904_DAC_BOOST_MASK 0x0600 /* DAC_BOOST - [10:9] */
385#define WM8904_DAC_BOOST_SHIFT 9 /* DAC_BOOST - [10:9] */
386#define WM8904_DAC_BOOST_WIDTH 2 /* DAC_BOOST - [10:9] */
387#define WM8904_LOOPBACK 0x0100 /* LOOPBACK */
388#define WM8904_LOOPBACK_MASK 0x0100 /* LOOPBACK */
389#define WM8904_LOOPBACK_SHIFT 8 /* LOOPBACK */
390#define WM8904_LOOPBACK_WIDTH 1 /* LOOPBACK */
391#define WM8904_AIFADCL_SRC 0x0080 /* AIFADCL_SRC */
392#define WM8904_AIFADCL_SRC_MASK 0x0080 /* AIFADCL_SRC */
393#define WM8904_AIFADCL_SRC_SHIFT 7 /* AIFADCL_SRC */
394#define WM8904_AIFADCL_SRC_WIDTH 1 /* AIFADCL_SRC */
395#define WM8904_AIFADCR_SRC 0x0040 /* AIFADCR_SRC */
396#define WM8904_AIFADCR_SRC_MASK 0x0040 /* AIFADCR_SRC */
397#define WM8904_AIFADCR_SRC_SHIFT 6 /* AIFADCR_SRC */
398#define WM8904_AIFADCR_SRC_WIDTH 1 /* AIFADCR_SRC */
399#define WM8904_AIFDACL_SRC 0x0020 /* AIFDACL_SRC */
400#define WM8904_AIFDACL_SRC_MASK 0x0020 /* AIFDACL_SRC */
401#define WM8904_AIFDACL_SRC_SHIFT 5 /* AIFDACL_SRC */
402#define WM8904_AIFDACL_SRC_WIDTH 1 /* AIFDACL_SRC */
403#define WM8904_AIFDACR_SRC 0x0010 /* AIFDACR_SRC */
404#define WM8904_AIFDACR_SRC_MASK 0x0010 /* AIFDACR_SRC */
405#define WM8904_AIFDACR_SRC_SHIFT 4 /* AIFDACR_SRC */
406#define WM8904_AIFDACR_SRC_WIDTH 1 /* AIFDACR_SRC */
407#define WM8904_ADC_COMP 0x0008 /* ADC_COMP */
408#define WM8904_ADC_COMP_MASK 0x0008 /* ADC_COMP */
409#define WM8904_ADC_COMP_SHIFT 3 /* ADC_COMP */
410#define WM8904_ADC_COMP_WIDTH 1 /* ADC_COMP */
411#define WM8904_ADC_COMPMODE 0x0004 /* ADC_COMPMODE */
412#define WM8904_ADC_COMPMODE_MASK 0x0004 /* ADC_COMPMODE */
413#define WM8904_ADC_COMPMODE_SHIFT 2 /* ADC_COMPMODE */
414#define WM8904_ADC_COMPMODE_WIDTH 1 /* ADC_COMPMODE */
415#define WM8904_DAC_COMP 0x0002 /* DAC_COMP */
416#define WM8904_DAC_COMP_MASK 0x0002 /* DAC_COMP */
417#define WM8904_DAC_COMP_SHIFT 1 /* DAC_COMP */
418#define WM8904_DAC_COMP_WIDTH 1 /* DAC_COMP */
419#define WM8904_DAC_COMPMODE 0x0001 /* DAC_COMPMODE */
420#define WM8904_DAC_COMPMODE_MASK 0x0001 /* DAC_COMPMODE */
421#define WM8904_DAC_COMPMODE_SHIFT 0 /* DAC_COMPMODE */
422#define WM8904_DAC_COMPMODE_WIDTH 1 /* DAC_COMPMODE */
423
424/*
425 * R25 (0x19) - Audio Interface 1
426 */
427#define WM8904_AIFDAC_TDM 0x2000 /* AIFDAC_TDM */
428#define WM8904_AIFDAC_TDM_MASK 0x2000 /* AIFDAC_TDM */
429#define WM8904_AIFDAC_TDM_SHIFT 13 /* AIFDAC_TDM */
430#define WM8904_AIFDAC_TDM_WIDTH 1 /* AIFDAC_TDM */
431#define WM8904_AIFDAC_TDM_CHAN 0x1000 /* AIFDAC_TDM_CHAN */
432#define WM8904_AIFDAC_TDM_CHAN_MASK 0x1000 /* AIFDAC_TDM_CHAN */
433#define WM8904_AIFDAC_TDM_CHAN_SHIFT 12 /* AIFDAC_TDM_CHAN */
434#define WM8904_AIFDAC_TDM_CHAN_WIDTH 1 /* AIFDAC_TDM_CHAN */
435#define WM8904_AIFADC_TDM 0x0800 /* AIFADC_TDM */
436#define WM8904_AIFADC_TDM_MASK 0x0800 /* AIFADC_TDM */
437#define WM8904_AIFADC_TDM_SHIFT 11 /* AIFADC_TDM */
438#define WM8904_AIFADC_TDM_WIDTH 1 /* AIFADC_TDM */
439#define WM8904_AIFADC_TDM_CHAN 0x0400 /* AIFADC_TDM_CHAN */
440#define WM8904_AIFADC_TDM_CHAN_MASK 0x0400 /* AIFADC_TDM_CHAN */
441#define WM8904_AIFADC_TDM_CHAN_SHIFT 10 /* AIFADC_TDM_CHAN */
442#define WM8904_AIFADC_TDM_CHAN_WIDTH 1 /* AIFADC_TDM_CHAN */
443#define WM8904_AIF_TRIS 0x0100 /* AIF_TRIS */
444#define WM8904_AIF_TRIS_MASK 0x0100 /* AIF_TRIS */
445#define WM8904_AIF_TRIS_SHIFT 8 /* AIF_TRIS */
446#define WM8904_AIF_TRIS_WIDTH 1 /* AIF_TRIS */
447#define WM8904_AIF_BCLK_INV 0x0080 /* AIF_BCLK_INV */
448#define WM8904_AIF_BCLK_INV_MASK 0x0080 /* AIF_BCLK_INV */
449#define WM8904_AIF_BCLK_INV_SHIFT 7 /* AIF_BCLK_INV */
450#define WM8904_AIF_BCLK_INV_WIDTH 1 /* AIF_BCLK_INV */
451#define WM8904_BCLK_DIR 0x0040 /* BCLK_DIR */
452#define WM8904_BCLK_DIR_MASK 0x0040 /* BCLK_DIR */
453#define WM8904_BCLK_DIR_SHIFT 6 /* BCLK_DIR */
454#define WM8904_BCLK_DIR_WIDTH 1 /* BCLK_DIR */
455#define WM8904_AIF_LRCLK_INV 0x0010 /* AIF_LRCLK_INV */
456#define WM8904_AIF_LRCLK_INV_MASK 0x0010 /* AIF_LRCLK_INV */
457#define WM8904_AIF_LRCLK_INV_SHIFT 4 /* AIF_LRCLK_INV */
458#define WM8904_AIF_LRCLK_INV_WIDTH 1 /* AIF_LRCLK_INV */
459#define WM8904_AIF_WL_MASK 0x000C /* AIF_WL - [3:2] */
460#define WM8904_AIF_WL_SHIFT 2 /* AIF_WL - [3:2] */
461#define WM8904_AIF_WL_WIDTH 2 /* AIF_WL - [3:2] */
462#define WM8904_AIF_FMT_MASK 0x0003 /* AIF_FMT - [1:0] */
463#define WM8904_AIF_FMT_SHIFT 0 /* AIF_FMT - [1:0] */
464#define WM8904_AIF_FMT_WIDTH 2 /* AIF_FMT - [1:0] */
465
466/*
467 * R26 (0x1A) - Audio Interface 2
468 */
469#define WM8904_OPCLK_DIV_MASK 0x0F00 /* OPCLK_DIV - [11:8] */
470#define WM8904_OPCLK_DIV_SHIFT 8 /* OPCLK_DIV - [11:8] */
471#define WM8904_OPCLK_DIV_WIDTH 4 /* OPCLK_DIV - [11:8] */
472#define WM8904_BCLK_DIV_MASK 0x001F /* BCLK_DIV - [4:0] */
473#define WM8904_BCLK_DIV_SHIFT 0 /* BCLK_DIV - [4:0] */
474#define WM8904_BCLK_DIV_WIDTH 5 /* BCLK_DIV - [4:0] */
475
476/*
477 * R27 (0x1B) - Audio Interface 3
478 */
479#define WM8904_LRCLK_DIR 0x0800 /* LRCLK_DIR */
480#define WM8904_LRCLK_DIR_MASK 0x0800 /* LRCLK_DIR */
481#define WM8904_LRCLK_DIR_SHIFT 11 /* LRCLK_DIR */
482#define WM8904_LRCLK_DIR_WIDTH 1 /* LRCLK_DIR */
483#define WM8904_LRCLK_RATE_MASK 0x07FF /* LRCLK_RATE - [10:0] */
484#define WM8904_LRCLK_RATE_SHIFT 0 /* LRCLK_RATE - [10:0] */
485#define WM8904_LRCLK_RATE_WIDTH 11 /* LRCLK_RATE - [10:0] */
486
487/*
488 * R30 (0x1E) - DAC Digital Volume Left
489 */
490#define WM8904_DAC_VU 0x0100 /* DAC_VU */
491#define WM8904_DAC_VU_MASK 0x0100 /* DAC_VU */
492#define WM8904_DAC_VU_SHIFT 8 /* DAC_VU */
493#define WM8904_DAC_VU_WIDTH 1 /* DAC_VU */
494#define WM8904_DACL_VOL_MASK 0x00FF /* DACL_VOL - [7:0] */
495#define WM8904_DACL_VOL_SHIFT 0 /* DACL_VOL - [7:0] */
496#define WM8904_DACL_VOL_WIDTH 8 /* DACL_VOL - [7:0] */
497
498/*
499 * R31 (0x1F) - DAC Digital Volume Right
500 */
501#define WM8904_DAC_VU 0x0100 /* DAC_VU */
502#define WM8904_DAC_VU_MASK 0x0100 /* DAC_VU */
503#define WM8904_DAC_VU_SHIFT 8 /* DAC_VU */
504#define WM8904_DAC_VU_WIDTH 1 /* DAC_VU */
505#define WM8904_DACR_VOL_MASK 0x00FF /* DACR_VOL - [7:0] */
506#define WM8904_DACR_VOL_SHIFT 0 /* DACR_VOL - [7:0] */
507#define WM8904_DACR_VOL_WIDTH 8 /* DACR_VOL - [7:0] */
508
509/*
510 * R32 (0x20) - DAC Digital 0
511 */
512#define WM8904_ADCL_DAC_SVOL_MASK 0x0F00 /* ADCL_DAC_SVOL - [11:8] */
513#define WM8904_ADCL_DAC_SVOL_SHIFT 8 /* ADCL_DAC_SVOL - [11:8] */
514#define WM8904_ADCL_DAC_SVOL_WIDTH 4 /* ADCL_DAC_SVOL - [11:8] */
515#define WM8904_ADCR_DAC_SVOL_MASK 0x00F0 /* ADCR_DAC_SVOL - [7:4] */
516#define WM8904_ADCR_DAC_SVOL_SHIFT 4 /* ADCR_DAC_SVOL - [7:4] */
517#define WM8904_ADCR_DAC_SVOL_WIDTH 4 /* ADCR_DAC_SVOL - [7:4] */
518#define WM8904_ADC_TO_DACL_MASK 0x000C /* ADC_TO_DACL - [3:2] */
519#define WM8904_ADC_TO_DACL_SHIFT 2 /* ADC_TO_DACL - [3:2] */
520#define WM8904_ADC_TO_DACL_WIDTH 2 /* ADC_TO_DACL - [3:2] */
521#define WM8904_ADC_TO_DACR_MASK 0x0003 /* ADC_TO_DACR - [1:0] */
522#define WM8904_ADC_TO_DACR_SHIFT 0 /* ADC_TO_DACR - [1:0] */
523#define WM8904_ADC_TO_DACR_WIDTH 2 /* ADC_TO_DACR - [1:0] */
524
525/*
526 * R33 (0x21) - DAC Digital 1
527 */
528#define WM8904_DAC_MONO 0x1000 /* DAC_MONO */
529#define WM8904_DAC_MONO_MASK 0x1000 /* DAC_MONO */
530#define WM8904_DAC_MONO_SHIFT 12 /* DAC_MONO */
531#define WM8904_DAC_MONO_WIDTH 1 /* DAC_MONO */
532#define WM8904_DAC_SB_FILT 0x0800 /* DAC_SB_FILT */
533#define WM8904_DAC_SB_FILT_MASK 0x0800 /* DAC_SB_FILT */
534#define WM8904_DAC_SB_FILT_SHIFT 11 /* DAC_SB_FILT */
535#define WM8904_DAC_SB_FILT_WIDTH 1 /* DAC_SB_FILT */
536#define WM8904_DAC_MUTERATE 0x0400 /* DAC_MUTERATE */
537#define WM8904_DAC_MUTERATE_MASK 0x0400 /* DAC_MUTERATE */
538#define WM8904_DAC_MUTERATE_SHIFT 10 /* DAC_MUTERATE */
539#define WM8904_DAC_MUTERATE_WIDTH 1 /* DAC_MUTERATE */
540#define WM8904_DAC_UNMUTE_RAMP 0x0200 /* DAC_UNMUTE_RAMP */
541#define WM8904_DAC_UNMUTE_RAMP_MASK 0x0200 /* DAC_UNMUTE_RAMP */
542#define WM8904_DAC_UNMUTE_RAMP_SHIFT 9 /* DAC_UNMUTE_RAMP */
543#define WM8904_DAC_UNMUTE_RAMP_WIDTH 1 /* DAC_UNMUTE_RAMP */
544#define WM8904_DAC_OSR128 0x0040 /* DAC_OSR128 */
545#define WM8904_DAC_OSR128_MASK 0x0040 /* DAC_OSR128 */
546#define WM8904_DAC_OSR128_SHIFT 6 /* DAC_OSR128 */
547#define WM8904_DAC_OSR128_WIDTH 1 /* DAC_OSR128 */
548#define WM8904_DAC_MUTE 0x0008 /* DAC_MUTE */
549#define WM8904_DAC_MUTE_MASK 0x0008 /* DAC_MUTE */
550#define WM8904_DAC_MUTE_SHIFT 3 /* DAC_MUTE */
551#define WM8904_DAC_MUTE_WIDTH 1 /* DAC_MUTE */
552#define WM8904_DEEMPH_MASK 0x0006 /* DEEMPH - [2:1] */
553#define WM8904_DEEMPH_SHIFT 1 /* DEEMPH - [2:1] */
554#define WM8904_DEEMPH_WIDTH 2 /* DEEMPH - [2:1] */
555
556/*
557 * R36 (0x24) - ADC Digital Volume Left
558 */
559#define WM8904_ADC_VU 0x0100 /* ADC_VU */
560#define WM8904_ADC_VU_MASK 0x0100 /* ADC_VU */
561#define WM8904_ADC_VU_SHIFT 8 /* ADC_VU */
562#define WM8904_ADC_VU_WIDTH 1 /* ADC_VU */
563#define WM8904_ADCL_VOL_MASK 0x00FF /* ADCL_VOL - [7:0] */
564#define WM8904_ADCL_VOL_SHIFT 0 /* ADCL_VOL - [7:0] */
565#define WM8904_ADCL_VOL_WIDTH 8 /* ADCL_VOL - [7:0] */
566
567/*
568 * R37 (0x25) - ADC Digital Volume Right
569 */
570#define WM8904_ADC_VU 0x0100 /* ADC_VU */
571#define WM8904_ADC_VU_MASK 0x0100 /* ADC_VU */
572#define WM8904_ADC_VU_SHIFT 8 /* ADC_VU */
573#define WM8904_ADC_VU_WIDTH 1 /* ADC_VU */
574#define WM8904_ADCR_VOL_MASK 0x00FF /* ADCR_VOL - [7:0] */
575#define WM8904_ADCR_VOL_SHIFT 0 /* ADCR_VOL - [7:0] */
576#define WM8904_ADCR_VOL_WIDTH 8 /* ADCR_VOL - [7:0] */
577
578/*
579 * R38 (0x26) - ADC Digital 0
580 */
581#define WM8904_ADC_HPF_CUT_MASK 0x0060 /* ADC_HPF_CUT - [6:5] */
582#define WM8904_ADC_HPF_CUT_SHIFT 5 /* ADC_HPF_CUT - [6:5] */
583#define WM8904_ADC_HPF_CUT_WIDTH 2 /* ADC_HPF_CUT - [6:5] */
584#define WM8904_ADC_HPF 0x0010 /* ADC_HPF */
585#define WM8904_ADC_HPF_MASK 0x0010 /* ADC_HPF */
586#define WM8904_ADC_HPF_SHIFT 4 /* ADC_HPF */
587#define WM8904_ADC_HPF_WIDTH 1 /* ADC_HPF */
588#define WM8904_ADCL_DATINV 0x0002 /* ADCL_DATINV */
589#define WM8904_ADCL_DATINV_MASK 0x0002 /* ADCL_DATINV */
590#define WM8904_ADCL_DATINV_SHIFT 1 /* ADCL_DATINV */
591#define WM8904_ADCL_DATINV_WIDTH 1 /* ADCL_DATINV */
592#define WM8904_ADCR_DATINV 0x0001 /* ADCR_DATINV */
593#define WM8904_ADCR_DATINV_MASK 0x0001 /* ADCR_DATINV */
594#define WM8904_ADCR_DATINV_SHIFT 0 /* ADCR_DATINV */
595#define WM8904_ADCR_DATINV_WIDTH 1 /* ADCR_DATINV */
596
597/*
598 * R39 (0x27) - Digital Microphone 0
599 */
600#define WM8904_DMIC_ENA 0x1000 /* DMIC_ENA */
601#define WM8904_DMIC_ENA_MASK 0x1000 /* DMIC_ENA */
602#define WM8904_DMIC_ENA_SHIFT 12 /* DMIC_ENA */
603#define WM8904_DMIC_ENA_WIDTH 1 /* DMIC_ENA */
604#define WM8904_DMIC_SRC 0x0800 /* DMIC_SRC */
605#define WM8904_DMIC_SRC_MASK 0x0800 /* DMIC_SRC */
606#define WM8904_DMIC_SRC_SHIFT 11 /* DMIC_SRC */
607#define WM8904_DMIC_SRC_WIDTH 1 /* DMIC_SRC */
608
609/*
610 * R40 (0x28) - DRC 0
611 */
612#define WM8904_DRC_ENA 0x8000 /* DRC_ENA */
613#define WM8904_DRC_ENA_MASK 0x8000 /* DRC_ENA */
614#define WM8904_DRC_ENA_SHIFT 15 /* DRC_ENA */
615#define WM8904_DRC_ENA_WIDTH 1 /* DRC_ENA */
616#define WM8904_DRC_DAC_PATH 0x4000 /* DRC_DAC_PATH */
617#define WM8904_DRC_DAC_PATH_MASK 0x4000 /* DRC_DAC_PATH */
618#define WM8904_DRC_DAC_PATH_SHIFT 14 /* DRC_DAC_PATH */
619#define WM8904_DRC_DAC_PATH_WIDTH 1 /* DRC_DAC_PATH */
620#define WM8904_DRC_GS_HYST_LVL_MASK 0x1800 /* DRC_GS_HYST_LVL - [12:11] */
621#define WM8904_DRC_GS_HYST_LVL_SHIFT 11 /* DRC_GS_HYST_LVL - [12:11] */
622#define WM8904_DRC_GS_HYST_LVL_WIDTH 2 /* DRC_GS_HYST_LVL - [12:11] */
623#define WM8904_DRC_STARTUP_GAIN_MASK 0x07C0 /* DRC_STARTUP_GAIN - [10:6] */
624#define WM8904_DRC_STARTUP_GAIN_SHIFT 6 /* DRC_STARTUP_GAIN - [10:6] */
625#define WM8904_DRC_STARTUP_GAIN_WIDTH 5 /* DRC_STARTUP_GAIN - [10:6] */
626#define WM8904_DRC_FF_DELAY 0x0020 /* DRC_FF_DELAY */
627#define WM8904_DRC_FF_DELAY_MASK 0x0020 /* DRC_FF_DELAY */
628#define WM8904_DRC_FF_DELAY_SHIFT 5 /* DRC_FF_DELAY */
629#define WM8904_DRC_FF_DELAY_WIDTH 1 /* DRC_FF_DELAY */
630#define WM8904_DRC_GS_ENA 0x0008 /* DRC_GS_ENA */
631#define WM8904_DRC_GS_ENA_MASK 0x0008 /* DRC_GS_ENA */
632#define WM8904_DRC_GS_ENA_SHIFT 3 /* DRC_GS_ENA */
633#define WM8904_DRC_GS_ENA_WIDTH 1 /* DRC_GS_ENA */
634#define WM8904_DRC_QR 0x0004 /* DRC_QR */
635#define WM8904_DRC_QR_MASK 0x0004 /* DRC_QR */
636#define WM8904_DRC_QR_SHIFT 2 /* DRC_QR */
637#define WM8904_DRC_QR_WIDTH 1 /* DRC_QR */
638#define WM8904_DRC_ANTICLIP 0x0002 /* DRC_ANTICLIP */
639#define WM8904_DRC_ANTICLIP_MASK 0x0002 /* DRC_ANTICLIP */
640#define WM8904_DRC_ANTICLIP_SHIFT 1 /* DRC_ANTICLIP */
641#define WM8904_DRC_ANTICLIP_WIDTH 1 /* DRC_ANTICLIP */
642#define WM8904_DRC_GS_HYST 0x0001 /* DRC_GS_HYST */
643#define WM8904_DRC_GS_HYST_MASK 0x0001 /* DRC_GS_HYST */
644#define WM8904_DRC_GS_HYST_SHIFT 0 /* DRC_GS_HYST */
645#define WM8904_DRC_GS_HYST_WIDTH 1 /* DRC_GS_HYST */
646
647/*
648 * R41 (0x29) - DRC 1
649 */
650#define WM8904_DRC_ATK_MASK 0xF000 /* DRC_ATK - [15:12] */
651#define WM8904_DRC_ATK_SHIFT 12 /* DRC_ATK - [15:12] */
652#define WM8904_DRC_ATK_WIDTH 4 /* DRC_ATK - [15:12] */
653#define WM8904_DRC_DCY_MASK 0x0F00 /* DRC_DCY - [11:8] */
654#define WM8904_DRC_DCY_SHIFT 8 /* DRC_DCY - [11:8] */
655#define WM8904_DRC_DCY_WIDTH 4 /* DRC_DCY - [11:8] */
656#define WM8904_DRC_QR_THR_MASK 0x00C0 /* DRC_QR_THR - [7:6] */
657#define WM8904_DRC_QR_THR_SHIFT 6 /* DRC_QR_THR - [7:6] */
658#define WM8904_DRC_QR_THR_WIDTH 2 /* DRC_QR_THR - [7:6] */
659#define WM8904_DRC_QR_DCY_MASK 0x0030 /* DRC_QR_DCY - [5:4] */
660#define WM8904_DRC_QR_DCY_SHIFT 4 /* DRC_QR_DCY - [5:4] */
661#define WM8904_DRC_QR_DCY_WIDTH 2 /* DRC_QR_DCY - [5:4] */
662#define WM8904_DRC_MINGAIN_MASK 0x000C /* DRC_MINGAIN - [3:2] */
663#define WM8904_DRC_MINGAIN_SHIFT 2 /* DRC_MINGAIN - [3:2] */
664#define WM8904_DRC_MINGAIN_WIDTH 2 /* DRC_MINGAIN - [3:2] */
665#define WM8904_DRC_MAXGAIN_MASK 0x0003 /* DRC_MAXGAIN - [1:0] */
666#define WM8904_DRC_MAXGAIN_SHIFT 0 /* DRC_MAXGAIN - [1:0] */
667#define WM8904_DRC_MAXGAIN_WIDTH 2 /* DRC_MAXGAIN - [1:0] */
668
669/*
670 * R42 (0x2A) - DRC 2
671 */
672#define WM8904_DRC_HI_COMP_MASK 0x0038 /* DRC_HI_COMP - [5:3] */
673#define WM8904_DRC_HI_COMP_SHIFT 3 /* DRC_HI_COMP - [5:3] */
674#define WM8904_DRC_HI_COMP_WIDTH 3 /* DRC_HI_COMP - [5:3] */
675#define WM8904_DRC_LO_COMP_MASK 0x0007 /* DRC_LO_COMP - [2:0] */
676#define WM8904_DRC_LO_COMP_SHIFT 0 /* DRC_LO_COMP - [2:0] */
677#define WM8904_DRC_LO_COMP_WIDTH 3 /* DRC_LO_COMP - [2:0] */
678
679/*
680 * R43 (0x2B) - DRC 3
681 */
682#define WM8904_DRC_KNEE_IP_MASK 0x07E0 /* DRC_KNEE_IP - [10:5] */
683#define WM8904_DRC_KNEE_IP_SHIFT 5 /* DRC_KNEE_IP - [10:5] */
684#define WM8904_DRC_KNEE_IP_WIDTH 6 /* DRC_KNEE_IP - [10:5] */
685#define WM8904_DRC_KNEE_OP_MASK 0x001F /* DRC_KNEE_OP - [4:0] */
686#define WM8904_DRC_KNEE_OP_SHIFT 0 /* DRC_KNEE_OP - [4:0] */
687#define WM8904_DRC_KNEE_OP_WIDTH 5 /* DRC_KNEE_OP - [4:0] */
688
689/*
690 * R44 (0x2C) - Analogue Left Input 0
691 */
692#define WM8904_LINMUTE 0x0080 /* LINMUTE */
693#define WM8904_LINMUTE_MASK 0x0080 /* LINMUTE */
694#define WM8904_LINMUTE_SHIFT 7 /* LINMUTE */
695#define WM8904_LINMUTE_WIDTH 1 /* LINMUTE */
696#define WM8904_LIN_VOL_MASK 0x001F /* LIN_VOL - [4:0] */
697#define WM8904_LIN_VOL_SHIFT 0 /* LIN_VOL - [4:0] */
698#define WM8904_LIN_VOL_WIDTH 5 /* LIN_VOL - [4:0] */
699
700/*
701 * R45 (0x2D) - Analogue Right Input 0
702 */
703#define WM8904_RINMUTE 0x0080 /* RINMUTE */
704#define WM8904_RINMUTE_MASK 0x0080 /* RINMUTE */
705#define WM8904_RINMUTE_SHIFT 7 /* RINMUTE */
706#define WM8904_RINMUTE_WIDTH 1 /* RINMUTE */
707#define WM8904_RIN_VOL_MASK 0x001F /* RIN_VOL - [4:0] */
708#define WM8904_RIN_VOL_SHIFT 0 /* RIN_VOL - [4:0] */
709#define WM8904_RIN_VOL_WIDTH 5 /* RIN_VOL - [4:0] */
710
711/*
712 * R46 (0x2E) - Analogue Left Input 1
713 */
714#define WM8904_INL_CM_ENA 0x0040 /* INL_CM_ENA */
715#define WM8904_INL_CM_ENA_MASK 0x0040 /* INL_CM_ENA */
716#define WM8904_INL_CM_ENA_SHIFT 6 /* INL_CM_ENA */
717#define WM8904_INL_CM_ENA_WIDTH 1 /* INL_CM_ENA */
718#define WM8904_L_IP_SEL_N_MASK 0x0030 /* L_IP_SEL_N - [5:4] */
719#define WM8904_L_IP_SEL_N_SHIFT 4 /* L_IP_SEL_N - [5:4] */
720#define WM8904_L_IP_SEL_N_WIDTH 2 /* L_IP_SEL_N - [5:4] */
721#define WM8904_L_IP_SEL_P_MASK 0x000C /* L_IP_SEL_P - [3:2] */
722#define WM8904_L_IP_SEL_P_SHIFT 2 /* L_IP_SEL_P - [3:2] */
723#define WM8904_L_IP_SEL_P_WIDTH 2 /* L_IP_SEL_P - [3:2] */
724#define WM8904_L_MODE_MASK 0x0003 /* L_MODE - [1:0] */
725#define WM8904_L_MODE_SHIFT 0 /* L_MODE - [1:0] */
726#define WM8904_L_MODE_WIDTH 2 /* L_MODE - [1:0] */
727
728/*
729 * R47 (0x2F) - Analogue Right Input 1
730 */
731#define WM8904_INR_CM_ENA 0x0040 /* INR_CM_ENA */
732#define WM8904_INR_CM_ENA_MASK 0x0040 /* INR_CM_ENA */
733#define WM8904_INR_CM_ENA_SHIFT 6 /* INR_CM_ENA */
734#define WM8904_INR_CM_ENA_WIDTH 1 /* INR_CM_ENA */
735#define WM8904_R_IP_SEL_N_MASK 0x0030 /* R_IP_SEL_N - [5:4] */
736#define WM8904_R_IP_SEL_N_SHIFT 4 /* R_IP_SEL_N - [5:4] */
737#define WM8904_R_IP_SEL_N_WIDTH 2 /* R_IP_SEL_N - [5:4] */
738#define WM8904_R_IP_SEL_P_MASK 0x000C /* R_IP_SEL_P - [3:2] */
739#define WM8904_R_IP_SEL_P_SHIFT 2 /* R_IP_SEL_P - [3:2] */
740#define WM8904_R_IP_SEL_P_WIDTH 2 /* R_IP_SEL_P - [3:2] */
741#define WM8904_R_MODE_MASK 0x0003 /* R_MODE - [1:0] */
742#define WM8904_R_MODE_SHIFT 0 /* R_MODE - [1:0] */
743#define WM8904_R_MODE_WIDTH 2 /* R_MODE - [1:0] */
744
745/*
746 * R57 (0x39) - Analogue OUT1 Left
747 */
748#define WM8904_HPOUTL_MUTE 0x0100 /* HPOUTL_MUTE */
749#define WM8904_HPOUTL_MUTE_MASK 0x0100 /* HPOUTL_MUTE */
750#define WM8904_HPOUTL_MUTE_SHIFT 8 /* HPOUTL_MUTE */
751#define WM8904_HPOUTL_MUTE_WIDTH 1 /* HPOUTL_MUTE */
752#define WM8904_HPOUT_VU 0x0080 /* HPOUT_VU */
753#define WM8904_HPOUT_VU_MASK 0x0080 /* HPOUT_VU */
754#define WM8904_HPOUT_VU_SHIFT 7 /* HPOUT_VU */
755#define WM8904_HPOUT_VU_WIDTH 1 /* HPOUT_VU */
756#define WM8904_HPOUTLZC 0x0040 /* HPOUTLZC */
757#define WM8904_HPOUTLZC_MASK 0x0040 /* HPOUTLZC */
758#define WM8904_HPOUTLZC_SHIFT 6 /* HPOUTLZC */
759#define WM8904_HPOUTLZC_WIDTH 1 /* HPOUTLZC */
760#define WM8904_HPOUTL_VOL_MASK 0x003F /* HPOUTL_VOL - [5:0] */
761#define WM8904_HPOUTL_VOL_SHIFT 0 /* HPOUTL_VOL - [5:0] */
762#define WM8904_HPOUTL_VOL_WIDTH 6 /* HPOUTL_VOL - [5:0] */
763
764/*
765 * R58 (0x3A) - Analogue OUT1 Right
766 */
767#define WM8904_HPOUTR_MUTE 0x0100 /* HPOUTR_MUTE */
768#define WM8904_HPOUTR_MUTE_MASK 0x0100 /* HPOUTR_MUTE */
769#define WM8904_HPOUTR_MUTE_SHIFT 8 /* HPOUTR_MUTE */
770#define WM8904_HPOUTR_MUTE_WIDTH 1 /* HPOUTR_MUTE */
771#define WM8904_HPOUT_VU 0x0080 /* HPOUT_VU */
772#define WM8904_HPOUT_VU_MASK 0x0080 /* HPOUT_VU */
773#define WM8904_HPOUT_VU_SHIFT 7 /* HPOUT_VU */
774#define WM8904_HPOUT_VU_WIDTH 1 /* HPOUT_VU */
775#define WM8904_HPOUTRZC 0x0040 /* HPOUTRZC */
776#define WM8904_HPOUTRZC_MASK 0x0040 /* HPOUTRZC */
777#define WM8904_HPOUTRZC_SHIFT 6 /* HPOUTRZC */
778#define WM8904_HPOUTRZC_WIDTH 1 /* HPOUTRZC */
779#define WM8904_HPOUTR_VOL_MASK 0x003F /* HPOUTR_VOL - [5:0] */
780#define WM8904_HPOUTR_VOL_SHIFT 0 /* HPOUTR_VOL - [5:0] */
781#define WM8904_HPOUTR_VOL_WIDTH 6 /* HPOUTR_VOL - [5:0] */
782
783/*
784 * R59 (0x3B) - Analogue OUT2 Left
785 */
786#define WM8904_LINEOUTL_MUTE 0x0100 /* LINEOUTL_MUTE */
787#define WM8904_LINEOUTL_MUTE_MASK 0x0100 /* LINEOUTL_MUTE */
788#define WM8904_LINEOUTL_MUTE_SHIFT 8 /* LINEOUTL_MUTE */
789#define WM8904_LINEOUTL_MUTE_WIDTH 1 /* LINEOUTL_MUTE */
790#define WM8904_LINEOUT_VU 0x0080 /* LINEOUT_VU */
791#define WM8904_LINEOUT_VU_MASK 0x0080 /* LINEOUT_VU */
792#define WM8904_LINEOUT_VU_SHIFT 7 /* LINEOUT_VU */
793#define WM8904_LINEOUT_VU_WIDTH 1 /* LINEOUT_VU */
794#define WM8904_LINEOUTLZC 0x0040 /* LINEOUTLZC */
795#define WM8904_LINEOUTLZC_MASK 0x0040 /* LINEOUTLZC */
796#define WM8904_LINEOUTLZC_SHIFT 6 /* LINEOUTLZC */
797#define WM8904_LINEOUTLZC_WIDTH 1 /* LINEOUTLZC */
798#define WM8904_LINEOUTL_VOL_MASK 0x003F /* LINEOUTL_VOL - [5:0] */
799#define WM8904_LINEOUTL_VOL_SHIFT 0 /* LINEOUTL_VOL - [5:0] */
800#define WM8904_LINEOUTL_VOL_WIDTH 6 /* LINEOUTL_VOL - [5:0] */
801
802/*
803 * R60 (0x3C) - Analogue OUT2 Right
804 */
805#define WM8904_LINEOUTR_MUTE 0x0100 /* LINEOUTR_MUTE */
806#define WM8904_LINEOUTR_MUTE_MASK 0x0100 /* LINEOUTR_MUTE */
807#define WM8904_LINEOUTR_MUTE_SHIFT 8 /* LINEOUTR_MUTE */
808#define WM8904_LINEOUTR_MUTE_WIDTH 1 /* LINEOUTR_MUTE */
809#define WM8904_LINEOUT_VU 0x0080 /* LINEOUT_VU */
810#define WM8904_LINEOUT_VU_MASK 0x0080 /* LINEOUT_VU */
811#define WM8904_LINEOUT_VU_SHIFT 7 /* LINEOUT_VU */
812#define WM8904_LINEOUT_VU_WIDTH 1 /* LINEOUT_VU */
813#define WM8904_LINEOUTRZC 0x0040 /* LINEOUTRZC */
814#define WM8904_LINEOUTRZC_MASK 0x0040 /* LINEOUTRZC */
815#define WM8904_LINEOUTRZC_SHIFT 6 /* LINEOUTRZC */
816#define WM8904_LINEOUTRZC_WIDTH 1 /* LINEOUTRZC */
817#define WM8904_LINEOUTR_VOL_MASK 0x003F /* LINEOUTR_VOL - [5:0] */
818#define WM8904_LINEOUTR_VOL_SHIFT 0 /* LINEOUTR_VOL - [5:0] */
819#define WM8904_LINEOUTR_VOL_WIDTH 6 /* LINEOUTR_VOL - [5:0] */
820
821/*
822 * R61 (0x3D) - Analogue OUT12 ZC
823 */
824#define WM8904_HPL_BYP_ENA 0x0008 /* HPL_BYP_ENA */
825#define WM8904_HPL_BYP_ENA_MASK 0x0008 /* HPL_BYP_ENA */
826#define WM8904_HPL_BYP_ENA_SHIFT 3 /* HPL_BYP_ENA */
827#define WM8904_HPL_BYP_ENA_WIDTH 1 /* HPL_BYP_ENA */
828#define WM8904_HPR_BYP_ENA 0x0004 /* HPR_BYP_ENA */
829#define WM8904_HPR_BYP_ENA_MASK 0x0004 /* HPR_BYP_ENA */
830#define WM8904_HPR_BYP_ENA_SHIFT 2 /* HPR_BYP_ENA */
831#define WM8904_HPR_BYP_ENA_WIDTH 1 /* HPR_BYP_ENA */
832#define WM8904_LINEOUTL_BYP_ENA 0x0002 /* LINEOUTL_BYP_ENA */
833#define WM8904_LINEOUTL_BYP_ENA_MASK 0x0002 /* LINEOUTL_BYP_ENA */
834#define WM8904_LINEOUTL_BYP_ENA_SHIFT 1 /* LINEOUTL_BYP_ENA */
835#define WM8904_LINEOUTL_BYP_ENA_WIDTH 1 /* LINEOUTL_BYP_ENA */
836#define WM8904_LINEOUTR_BYP_ENA 0x0001 /* LINEOUTR_BYP_ENA */
837#define WM8904_LINEOUTR_BYP_ENA_MASK 0x0001 /* LINEOUTR_BYP_ENA */
838#define WM8904_LINEOUTR_BYP_ENA_SHIFT 0 /* LINEOUTR_BYP_ENA */
839#define WM8904_LINEOUTR_BYP_ENA_WIDTH 1 /* LINEOUTR_BYP_ENA */
840
841/*
842 * R67 (0x43) - DC Servo 0
843 */
844#define WM8904_DCS_ENA_CHAN_3 0x0008 /* DCS_ENA_CHAN_3 */
845#define WM8904_DCS_ENA_CHAN_3_MASK 0x0008 /* DCS_ENA_CHAN_3 */
846#define WM8904_DCS_ENA_CHAN_3_SHIFT 3 /* DCS_ENA_CHAN_3 */
847#define WM8904_DCS_ENA_CHAN_3_WIDTH 1 /* DCS_ENA_CHAN_3 */
848#define WM8904_DCS_ENA_CHAN_2 0x0004 /* DCS_ENA_CHAN_2 */
849#define WM8904_DCS_ENA_CHAN_2_MASK 0x0004 /* DCS_ENA_CHAN_2 */
850#define WM8904_DCS_ENA_CHAN_2_SHIFT 2 /* DCS_ENA_CHAN_2 */
851#define WM8904_DCS_ENA_CHAN_2_WIDTH 1 /* DCS_ENA_CHAN_2 */
852#define WM8904_DCS_ENA_CHAN_1 0x0002 /* DCS_ENA_CHAN_1 */
853#define WM8904_DCS_ENA_CHAN_1_MASK 0x0002 /* DCS_ENA_CHAN_1 */
854#define WM8904_DCS_ENA_CHAN_1_SHIFT 1 /* DCS_ENA_CHAN_1 */
855#define WM8904_DCS_ENA_CHAN_1_WIDTH 1 /* DCS_ENA_CHAN_1 */
856#define WM8904_DCS_ENA_CHAN_0 0x0001 /* DCS_ENA_CHAN_0 */
857#define WM8904_DCS_ENA_CHAN_0_MASK 0x0001 /* DCS_ENA_CHAN_0 */
858#define WM8904_DCS_ENA_CHAN_0_SHIFT 0 /* DCS_ENA_CHAN_0 */
859#define WM8904_DCS_ENA_CHAN_0_WIDTH 1 /* DCS_ENA_CHAN_0 */
860
861/*
862 * R68 (0x44) - DC Servo 1
863 */
864#define WM8904_DCS_TRIG_SINGLE_3 0x8000 /* DCS_TRIG_SINGLE_3 */
865#define WM8904_DCS_TRIG_SINGLE_3_MASK 0x8000 /* DCS_TRIG_SINGLE_3 */
866#define WM8904_DCS_TRIG_SINGLE_3_SHIFT 15 /* DCS_TRIG_SINGLE_3 */
867#define WM8904_DCS_TRIG_SINGLE_3_WIDTH 1 /* DCS_TRIG_SINGLE_3 */
868#define WM8904_DCS_TRIG_SINGLE_2 0x4000 /* DCS_TRIG_SINGLE_2 */
869#define WM8904_DCS_TRIG_SINGLE_2_MASK 0x4000 /* DCS_TRIG_SINGLE_2 */
870#define WM8904_DCS_TRIG_SINGLE_2_SHIFT 14 /* DCS_TRIG_SINGLE_2 */
871#define WM8904_DCS_TRIG_SINGLE_2_WIDTH 1 /* DCS_TRIG_SINGLE_2 */
872#define WM8904_DCS_TRIG_SINGLE_1 0x2000 /* DCS_TRIG_SINGLE_1 */
873#define WM8904_DCS_TRIG_SINGLE_1_MASK 0x2000 /* DCS_TRIG_SINGLE_1 */
874#define WM8904_DCS_TRIG_SINGLE_1_SHIFT 13 /* DCS_TRIG_SINGLE_1 */
875#define WM8904_DCS_TRIG_SINGLE_1_WIDTH 1 /* DCS_TRIG_SINGLE_1 */
876#define WM8904_DCS_TRIG_SINGLE_0 0x1000 /* DCS_TRIG_SINGLE_0 */
877#define WM8904_DCS_TRIG_SINGLE_0_MASK 0x1000 /* DCS_TRIG_SINGLE_0 */
878#define WM8904_DCS_TRIG_SINGLE_0_SHIFT 12 /* DCS_TRIG_SINGLE_0 */
879#define WM8904_DCS_TRIG_SINGLE_0_WIDTH 1 /* DCS_TRIG_SINGLE_0 */
880#define WM8904_DCS_TRIG_SERIES_3 0x0800 /* DCS_TRIG_SERIES_3 */
881#define WM8904_DCS_TRIG_SERIES_3_MASK 0x0800 /* DCS_TRIG_SERIES_3 */
882#define WM8904_DCS_TRIG_SERIES_3_SHIFT 11 /* DCS_TRIG_SERIES_3 */
883#define WM8904_DCS_TRIG_SERIES_3_WIDTH 1 /* DCS_TRIG_SERIES_3 */
884#define WM8904_DCS_TRIG_SERIES_2 0x0400 /* DCS_TRIG_SERIES_2 */
885#define WM8904_DCS_TRIG_SERIES_2_MASK 0x0400 /* DCS_TRIG_SERIES_2 */
886#define WM8904_DCS_TRIG_SERIES_2_SHIFT 10 /* DCS_TRIG_SERIES_2 */
887#define WM8904_DCS_TRIG_SERIES_2_WIDTH 1 /* DCS_TRIG_SERIES_2 */
888#define WM8904_DCS_TRIG_SERIES_1 0x0200 /* DCS_TRIG_SERIES_1 */
889#define WM8904_DCS_TRIG_SERIES_1_MASK 0x0200 /* DCS_TRIG_SERIES_1 */
890#define WM8904_DCS_TRIG_SERIES_1_SHIFT 9 /* DCS_TRIG_SERIES_1 */
891#define WM8904_DCS_TRIG_SERIES_1_WIDTH 1 /* DCS_TRIG_SERIES_1 */
892#define WM8904_DCS_TRIG_SERIES_0 0x0100 /* DCS_TRIG_SERIES_0 */
893#define WM8904_DCS_TRIG_SERIES_0_MASK 0x0100 /* DCS_TRIG_SERIES_0 */
894#define WM8904_DCS_TRIG_SERIES_0_SHIFT 8 /* DCS_TRIG_SERIES_0 */
895#define WM8904_DCS_TRIG_SERIES_0_WIDTH 1 /* DCS_TRIG_SERIES_0 */
896#define WM8904_DCS_TRIG_STARTUP_3 0x0080 /* DCS_TRIG_STARTUP_3 */
897#define WM8904_DCS_TRIG_STARTUP_3_MASK 0x0080 /* DCS_TRIG_STARTUP_3 */
898#define WM8904_DCS_TRIG_STARTUP_3_SHIFT 7 /* DCS_TRIG_STARTUP_3 */
899#define WM8904_DCS_TRIG_STARTUP_3_WIDTH 1 /* DCS_TRIG_STARTUP_3 */
900#define WM8904_DCS_TRIG_STARTUP_2 0x0040 /* DCS_TRIG_STARTUP_2 */
901#define WM8904_DCS_TRIG_STARTUP_2_MASK 0x0040 /* DCS_TRIG_STARTUP_2 */
902#define WM8904_DCS_TRIG_STARTUP_2_SHIFT 6 /* DCS_TRIG_STARTUP_2 */
903#define WM8904_DCS_TRIG_STARTUP_2_WIDTH 1 /* DCS_TRIG_STARTUP_2 */
904#define WM8904_DCS_TRIG_STARTUP_1 0x0020 /* DCS_TRIG_STARTUP_1 */
905#define WM8904_DCS_TRIG_STARTUP_1_MASK 0x0020 /* DCS_TRIG_STARTUP_1 */
906#define WM8904_DCS_TRIG_STARTUP_1_SHIFT 5 /* DCS_TRIG_STARTUP_1 */
907#define WM8904_DCS_TRIG_STARTUP_1_WIDTH 1 /* DCS_TRIG_STARTUP_1 */
908#define WM8904_DCS_TRIG_STARTUP_0 0x0010 /* DCS_TRIG_STARTUP_0 */
909#define WM8904_DCS_TRIG_STARTUP_0_MASK 0x0010 /* DCS_TRIG_STARTUP_0 */
910#define WM8904_DCS_TRIG_STARTUP_0_SHIFT 4 /* DCS_TRIG_STARTUP_0 */
911#define WM8904_DCS_TRIG_STARTUP_0_WIDTH 1 /* DCS_TRIG_STARTUP_0 */
912#define WM8904_DCS_TRIG_DAC_WR_3 0x0008 /* DCS_TRIG_DAC_WR_3 */
913#define WM8904_DCS_TRIG_DAC_WR_3_MASK 0x0008 /* DCS_TRIG_DAC_WR_3 */
914#define WM8904_DCS_TRIG_DAC_WR_3_SHIFT 3 /* DCS_TRIG_DAC_WR_3 */
915#define WM8904_DCS_TRIG_DAC_WR_3_WIDTH 1 /* DCS_TRIG_DAC_WR_3 */
916#define WM8904_DCS_TRIG_DAC_WR_2 0x0004 /* DCS_TRIG_DAC_WR_2 */
917#define WM8904_DCS_TRIG_DAC_WR_2_MASK 0x0004 /* DCS_TRIG_DAC_WR_2 */
918#define WM8904_DCS_TRIG_DAC_WR_2_SHIFT 2 /* DCS_TRIG_DAC_WR_2 */
919#define WM8904_DCS_TRIG_DAC_WR_2_WIDTH 1 /* DCS_TRIG_DAC_WR_2 */
920#define WM8904_DCS_TRIG_DAC_WR_1 0x0002 /* DCS_TRIG_DAC_WR_1 */
921#define WM8904_DCS_TRIG_DAC_WR_1_MASK 0x0002 /* DCS_TRIG_DAC_WR_1 */
922#define WM8904_DCS_TRIG_DAC_WR_1_SHIFT 1 /* DCS_TRIG_DAC_WR_1 */
923#define WM8904_DCS_TRIG_DAC_WR_1_WIDTH 1 /* DCS_TRIG_DAC_WR_1 */
924#define WM8904_DCS_TRIG_DAC_WR_0 0x0001 /* DCS_TRIG_DAC_WR_0 */
925#define WM8904_DCS_TRIG_DAC_WR_0_MASK 0x0001 /* DCS_TRIG_DAC_WR_0 */
926#define WM8904_DCS_TRIG_DAC_WR_0_SHIFT 0 /* DCS_TRIG_DAC_WR_0 */
927#define WM8904_DCS_TRIG_DAC_WR_0_WIDTH 1 /* DCS_TRIG_DAC_WR_0 */
928
929/*
930 * R69 (0x45) - DC Servo 2
931 */
932#define WM8904_DCS_TIMER_PERIOD_23_MASK 0x0F00 /* DCS_TIMER_PERIOD_23 - [11:8] */
933#define WM8904_DCS_TIMER_PERIOD_23_SHIFT 8 /* DCS_TIMER_PERIOD_23 - [11:8] */
934#define WM8904_DCS_TIMER_PERIOD_23_WIDTH 4 /* DCS_TIMER_PERIOD_23 - [11:8] */
935#define WM8904_DCS_TIMER_PERIOD_01_MASK 0x000F /* DCS_TIMER_PERIOD_01 - [3:0] */
936#define WM8904_DCS_TIMER_PERIOD_01_SHIFT 0 /* DCS_TIMER_PERIOD_01 - [3:0] */
937#define WM8904_DCS_TIMER_PERIOD_01_WIDTH 4 /* DCS_TIMER_PERIOD_01 - [3:0] */
938
939/*
940 * R71 (0x47) - DC Servo 4
941 */
942#define WM8904_DCS_SERIES_NO_23_MASK 0x007F /* DCS_SERIES_NO_23 - [6:0] */
943#define WM8904_DCS_SERIES_NO_23_SHIFT 0 /* DCS_SERIES_NO_23 - [6:0] */
944#define WM8904_DCS_SERIES_NO_23_WIDTH 7 /* DCS_SERIES_NO_23 - [6:0] */
945
946/*
947 * R72 (0x48) - DC Servo 5
948 */
949#define WM8904_DCS_SERIES_NO_01_MASK 0x007F /* DCS_SERIES_NO_01 - [6:0] */
950#define WM8904_DCS_SERIES_NO_01_SHIFT 0 /* DCS_SERIES_NO_01 - [6:0] */
951#define WM8904_DCS_SERIES_NO_01_WIDTH 7 /* DCS_SERIES_NO_01 - [6:0] */
952
953/*
954 * R73 (0x49) - DC Servo 6
955 */
956#define WM8904_DCS_DAC_WR_VAL_3_MASK 0x00FF /* DCS_DAC_WR_VAL_3 - [7:0] */
957#define WM8904_DCS_DAC_WR_VAL_3_SHIFT 0 /* DCS_DAC_WR_VAL_3 - [7:0] */
958#define WM8904_DCS_DAC_WR_VAL_3_WIDTH 8 /* DCS_DAC_WR_VAL_3 - [7:0] */
959
960/*
961 * R74 (0x4A) - DC Servo 7
962 */
963#define WM8904_DCS_DAC_WR_VAL_2_MASK 0x00FF /* DCS_DAC_WR_VAL_2 - [7:0] */
964#define WM8904_DCS_DAC_WR_VAL_2_SHIFT 0 /* DCS_DAC_WR_VAL_2 - [7:0] */
965#define WM8904_DCS_DAC_WR_VAL_2_WIDTH 8 /* DCS_DAC_WR_VAL_2 - [7:0] */
966
967/*
968 * R75 (0x4B) - DC Servo 8
969 */
970#define WM8904_DCS_DAC_WR_VAL_1_MASK 0x00FF /* DCS_DAC_WR_VAL_1 - [7:0] */
971#define WM8904_DCS_DAC_WR_VAL_1_SHIFT 0 /* DCS_DAC_WR_VAL_1 - [7:0] */
972#define WM8904_DCS_DAC_WR_VAL_1_WIDTH 8 /* DCS_DAC_WR_VAL_1 - [7:0] */
973
974/*
975 * R76 (0x4C) - DC Servo 9
976 */
977#define WM8904_DCS_DAC_WR_VAL_0_MASK 0x00FF /* DCS_DAC_WR_VAL_0 - [7:0] */
978#define WM8904_DCS_DAC_WR_VAL_0_SHIFT 0 /* DCS_DAC_WR_VAL_0 - [7:0] */
979#define WM8904_DCS_DAC_WR_VAL_0_WIDTH 8 /* DCS_DAC_WR_VAL_0 - [7:0] */
980
981/*
982 * R77 (0x4D) - DC Servo Readback 0
983 */
984#define WM8904_DCS_CAL_COMPLETE_MASK 0x0F00 /* DCS_CAL_COMPLETE - [11:8] */
985#define WM8904_DCS_CAL_COMPLETE_SHIFT 8 /* DCS_CAL_COMPLETE - [11:8] */
986#define WM8904_DCS_CAL_COMPLETE_WIDTH 4 /* DCS_CAL_COMPLETE - [11:8] */
987#define WM8904_DCS_DAC_WR_COMPLETE_MASK 0x00F0 /* DCS_DAC_WR_COMPLETE - [7:4] */
988#define WM8904_DCS_DAC_WR_COMPLETE_SHIFT 4 /* DCS_DAC_WR_COMPLETE - [7:4] */
989#define WM8904_DCS_DAC_WR_COMPLETE_WIDTH 4 /* DCS_DAC_WR_COMPLETE - [7:4] */
990#define WM8904_DCS_STARTUP_COMPLETE_MASK 0x000F /* DCS_STARTUP_COMPLETE - [3:0] */
991#define WM8904_DCS_STARTUP_COMPLETE_SHIFT 0 /* DCS_STARTUP_COMPLETE - [3:0] */
992#define WM8904_DCS_STARTUP_COMPLETE_WIDTH 4 /* DCS_STARTUP_COMPLETE - [3:0] */
993
994/*
995 * R90 (0x5A) - Analogue HP 0
996 */
997#define WM8904_HPL_RMV_SHORT 0x0080 /* HPL_RMV_SHORT */
998#define WM8904_HPL_RMV_SHORT_MASK 0x0080 /* HPL_RMV_SHORT */
999#define WM8904_HPL_RMV_SHORT_SHIFT 7 /* HPL_RMV_SHORT */
1000#define WM8904_HPL_RMV_SHORT_WIDTH 1 /* HPL_RMV_SHORT */
1001#define WM8904_HPL_ENA_OUTP 0x0040 /* HPL_ENA_OUTP */
1002#define WM8904_HPL_ENA_OUTP_MASK 0x0040 /* HPL_ENA_OUTP */
1003#define WM8904_HPL_ENA_OUTP_SHIFT 6 /* HPL_ENA_OUTP */
1004#define WM8904_HPL_ENA_OUTP_WIDTH 1 /* HPL_ENA_OUTP */
1005#define WM8904_HPL_ENA_DLY 0x0020 /* HPL_ENA_DLY */
1006#define WM8904_HPL_ENA_DLY_MASK 0x0020 /* HPL_ENA_DLY */
1007#define WM8904_HPL_ENA_DLY_SHIFT 5 /* HPL_ENA_DLY */
1008#define WM8904_HPL_ENA_DLY_WIDTH 1 /* HPL_ENA_DLY */
1009#define WM8904_HPL_ENA 0x0010 /* HPL_ENA */
1010#define WM8904_HPL_ENA_MASK 0x0010 /* HPL_ENA */
1011#define WM8904_HPL_ENA_SHIFT 4 /* HPL_ENA */
1012#define WM8904_HPL_ENA_WIDTH 1 /* HPL_ENA */
1013#define WM8904_HPR_RMV_SHORT 0x0008 /* HPR_RMV_SHORT */
1014#define WM8904_HPR_RMV_SHORT_MASK 0x0008 /* HPR_RMV_SHORT */
1015#define WM8904_HPR_RMV_SHORT_SHIFT 3 /* HPR_RMV_SHORT */
1016#define WM8904_HPR_RMV_SHORT_WIDTH 1 /* HPR_RMV_SHORT */
1017#define WM8904_HPR_ENA_OUTP 0x0004 /* HPR_ENA_OUTP */
1018#define WM8904_HPR_ENA_OUTP_MASK 0x0004 /* HPR_ENA_OUTP */
1019#define WM8904_HPR_ENA_OUTP_SHIFT 2 /* HPR_ENA_OUTP */
1020#define WM8904_HPR_ENA_OUTP_WIDTH 1 /* HPR_ENA_OUTP */
1021#define WM8904_HPR_ENA_DLY 0x0002 /* HPR_ENA_DLY */
1022#define WM8904_HPR_ENA_DLY_MASK 0x0002 /* HPR_ENA_DLY */
1023#define WM8904_HPR_ENA_DLY_SHIFT 1 /* HPR_ENA_DLY */
1024#define WM8904_HPR_ENA_DLY_WIDTH 1 /* HPR_ENA_DLY */
1025#define WM8904_HPR_ENA 0x0001 /* HPR_ENA */
1026#define WM8904_HPR_ENA_MASK 0x0001 /* HPR_ENA */
1027#define WM8904_HPR_ENA_SHIFT 0 /* HPR_ENA */
1028#define WM8904_HPR_ENA_WIDTH 1 /* HPR_ENA */
1029
1030/*
1031 * R94 (0x5E) - Analogue Lineout 0
1032 */
1033#define WM8904_LINEOUTL_RMV_SHORT 0x0080 /* LINEOUTL_RMV_SHORT */
1034#define WM8904_LINEOUTL_RMV_SHORT_MASK 0x0080 /* LINEOUTL_RMV_SHORT */
1035#define WM8904_LINEOUTL_RMV_SHORT_SHIFT 7 /* LINEOUTL_RMV_SHORT */
1036#define WM8904_LINEOUTL_RMV_SHORT_WIDTH 1 /* LINEOUTL_RMV_SHORT */
1037#define WM8904_LINEOUTL_ENA_OUTP 0x0040 /* LINEOUTL_ENA_OUTP */
1038#define WM8904_LINEOUTL_ENA_OUTP_MASK 0x0040 /* LINEOUTL_ENA_OUTP */
1039#define WM8904_LINEOUTL_ENA_OUTP_SHIFT 6 /* LINEOUTL_ENA_OUTP */
1040#define WM8904_LINEOUTL_ENA_OUTP_WIDTH 1 /* LINEOUTL_ENA_OUTP */
1041#define WM8904_LINEOUTL_ENA_DLY 0x0020 /* LINEOUTL_ENA_DLY */
1042#define WM8904_LINEOUTL_ENA_DLY_MASK 0x0020 /* LINEOUTL_ENA_DLY */
1043#define WM8904_LINEOUTL_ENA_DLY_SHIFT 5 /* LINEOUTL_ENA_DLY */
1044#define WM8904_LINEOUTL_ENA_DLY_WIDTH 1 /* LINEOUTL_ENA_DLY */
1045#define WM8904_LINEOUTL_ENA 0x0010 /* LINEOUTL_ENA */
1046#define WM8904_LINEOUTL_ENA_MASK 0x0010 /* LINEOUTL_ENA */
1047#define WM8904_LINEOUTL_ENA_SHIFT 4 /* LINEOUTL_ENA */
1048#define WM8904_LINEOUTL_ENA_WIDTH 1 /* LINEOUTL_ENA */
1049#define WM8904_LINEOUTR_RMV_SHORT 0x0008 /* LINEOUTR_RMV_SHORT */
1050#define WM8904_LINEOUTR_RMV_SHORT_MASK 0x0008 /* LINEOUTR_RMV_SHORT */
1051#define WM8904_LINEOUTR_RMV_SHORT_SHIFT 3 /* LINEOUTR_RMV_SHORT */
1052#define WM8904_LINEOUTR_RMV_SHORT_WIDTH 1 /* LINEOUTR_RMV_SHORT */
1053#define WM8904_LINEOUTR_ENA_OUTP 0x0004 /* LINEOUTR_ENA_OUTP */
1054#define WM8904_LINEOUTR_ENA_OUTP_MASK 0x0004 /* LINEOUTR_ENA_OUTP */
1055#define WM8904_LINEOUTR_ENA_OUTP_SHIFT 2 /* LINEOUTR_ENA_OUTP */
1056#define WM8904_LINEOUTR_ENA_OUTP_WIDTH 1 /* LINEOUTR_ENA_OUTP */
1057#define WM8904_LINEOUTR_ENA_DLY 0x0002 /* LINEOUTR_ENA_DLY */
1058#define WM8904_LINEOUTR_ENA_DLY_MASK 0x0002 /* LINEOUTR_ENA_DLY */
1059#define WM8904_LINEOUTR_ENA_DLY_SHIFT 1 /* LINEOUTR_ENA_DLY */
1060#define WM8904_LINEOUTR_ENA_DLY_WIDTH 1 /* LINEOUTR_ENA_DLY */
1061#define WM8904_LINEOUTR_ENA 0x0001 /* LINEOUTR_ENA */
1062#define WM8904_LINEOUTR_ENA_MASK 0x0001 /* LINEOUTR_ENA */
1063#define WM8904_LINEOUTR_ENA_SHIFT 0 /* LINEOUTR_ENA */
1064#define WM8904_LINEOUTR_ENA_WIDTH 1 /* LINEOUTR_ENA */
1065
1066/*
1067 * R98 (0x62) - Charge Pump 0
1068 */
1069#define WM8904_CP_ENA 0x0001 /* CP_ENA */
1070#define WM8904_CP_ENA_MASK 0x0001 /* CP_ENA */
1071#define WM8904_CP_ENA_SHIFT 0 /* CP_ENA */
1072#define WM8904_CP_ENA_WIDTH 1 /* CP_ENA */
1073
1074/*
1075 * R104 (0x68) - Class W 0
1076 */
1077#define WM8904_CP_DYN_PWR 0x0001 /* CP_DYN_PWR */
1078#define WM8904_CP_DYN_PWR_MASK 0x0001 /* CP_DYN_PWR */
1079#define WM8904_CP_DYN_PWR_SHIFT 0 /* CP_DYN_PWR */
1080#define WM8904_CP_DYN_PWR_WIDTH 1 /* CP_DYN_PWR */
1081
1082/*
1083 * R108 (0x6C) - Write Sequencer 0
1084 */
1085#define WM8904_WSEQ_ENA 0x0100 /* WSEQ_ENA */
1086#define WM8904_WSEQ_ENA_MASK 0x0100 /* WSEQ_ENA */
1087#define WM8904_WSEQ_ENA_SHIFT 8 /* WSEQ_ENA */
1088#define WM8904_WSEQ_ENA_WIDTH 1 /* WSEQ_ENA */
1089#define WM8904_WSEQ_WRITE_INDEX_MASK 0x001F /* WSEQ_WRITE_INDEX - [4:0] */
1090#define WM8904_WSEQ_WRITE_INDEX_SHIFT 0 /* WSEQ_WRITE_INDEX - [4:0] */
1091#define WM8904_WSEQ_WRITE_INDEX_WIDTH 5 /* WSEQ_WRITE_INDEX - [4:0] */
1092
1093/*
1094 * R109 (0x6D) - Write Sequencer 1
1095 */
1096#define WM8904_WSEQ_DATA_WIDTH_MASK 0x7000 /* WSEQ_DATA_WIDTH - [14:12] */
1097#define WM8904_WSEQ_DATA_WIDTH_SHIFT 12 /* WSEQ_DATA_WIDTH - [14:12] */
1098#define WM8904_WSEQ_DATA_WIDTH_WIDTH 3 /* WSEQ_DATA_WIDTH - [14:12] */
1099#define WM8904_WSEQ_DATA_START_MASK 0x0F00 /* WSEQ_DATA_START - [11:8] */
1100#define WM8904_WSEQ_DATA_START_SHIFT 8 /* WSEQ_DATA_START - [11:8] */
1101#define WM8904_WSEQ_DATA_START_WIDTH 4 /* WSEQ_DATA_START - [11:8] */
1102#define WM8904_WSEQ_ADDR_MASK 0x00FF /* WSEQ_ADDR - [7:0] */
1103#define WM8904_WSEQ_ADDR_SHIFT 0 /* WSEQ_ADDR - [7:0] */
1104#define WM8904_WSEQ_ADDR_WIDTH 8 /* WSEQ_ADDR - [7:0] */
1105
1106/*
1107 * R110 (0x6E) - Write Sequencer 2
1108 */
1109#define WM8904_WSEQ_EOS 0x4000 /* WSEQ_EOS */
1110#define WM8904_WSEQ_EOS_MASK 0x4000 /* WSEQ_EOS */
1111#define WM8904_WSEQ_EOS_SHIFT 14 /* WSEQ_EOS */
1112#define WM8904_WSEQ_EOS_WIDTH 1 /* WSEQ_EOS */
1113#define WM8904_WSEQ_DELAY_MASK 0x0F00 /* WSEQ_DELAY - [11:8] */
1114#define WM8904_WSEQ_DELAY_SHIFT 8 /* WSEQ_DELAY - [11:8] */
1115#define WM8904_WSEQ_DELAY_WIDTH 4 /* WSEQ_DELAY - [11:8] */
1116#define WM8904_WSEQ_DATA_MASK 0x00FF /* WSEQ_DATA - [7:0] */
1117#define WM8904_WSEQ_DATA_SHIFT 0 /* WSEQ_DATA - [7:0] */
1118#define WM8904_WSEQ_DATA_WIDTH 8 /* WSEQ_DATA - [7:0] */
1119
1120/*
1121 * R111 (0x6F) - Write Sequencer 3
1122 */
1123#define WM8904_WSEQ_ABORT 0x0200 /* WSEQ_ABORT */
1124#define WM8904_WSEQ_ABORT_MASK 0x0200 /* WSEQ_ABORT */
1125#define WM8904_WSEQ_ABORT_SHIFT 9 /* WSEQ_ABORT */
1126#define WM8904_WSEQ_ABORT_WIDTH 1 /* WSEQ_ABORT */
1127#define WM8904_WSEQ_START 0x0100 /* WSEQ_START */
1128#define WM8904_WSEQ_START_MASK 0x0100 /* WSEQ_START */
1129#define WM8904_WSEQ_START_SHIFT 8 /* WSEQ_START */
1130#define WM8904_WSEQ_START_WIDTH 1 /* WSEQ_START */
1131#define WM8904_WSEQ_START_INDEX_MASK 0x003F /* WSEQ_START_INDEX - [5:0] */
1132#define WM8904_WSEQ_START_INDEX_SHIFT 0 /* WSEQ_START_INDEX - [5:0] */
1133#define WM8904_WSEQ_START_INDEX_WIDTH 6 /* WSEQ_START_INDEX - [5:0] */
1134
1135/*
1136 * R112 (0x70) - Write Sequencer 4
1137 */
1138#define WM8904_WSEQ_CURRENT_INDEX_MASK 0x03F0 /* WSEQ_CURRENT_INDEX - [9:4] */
1139#define WM8904_WSEQ_CURRENT_INDEX_SHIFT 4 /* WSEQ_CURRENT_INDEX - [9:4] */
1140#define WM8904_WSEQ_CURRENT_INDEX_WIDTH 6 /* WSEQ_CURRENT_INDEX - [9:4] */
1141#define WM8904_WSEQ_BUSY 0x0001 /* WSEQ_BUSY */
1142#define WM8904_WSEQ_BUSY_MASK 0x0001 /* WSEQ_BUSY */
1143#define WM8904_WSEQ_BUSY_SHIFT 0 /* WSEQ_BUSY */
1144#define WM8904_WSEQ_BUSY_WIDTH 1 /* WSEQ_BUSY */
1145
1146/*
1147 * R116 (0x74) - FLL Control 1
1148 */
1149#define WM8904_FLL_FRACN_ENA 0x0004 /* FLL_FRACN_ENA */
1150#define WM8904_FLL_FRACN_ENA_MASK 0x0004 /* FLL_FRACN_ENA */
1151#define WM8904_FLL_FRACN_ENA_SHIFT 2 /* FLL_FRACN_ENA */
1152#define WM8904_FLL_FRACN_ENA_WIDTH 1 /* FLL_FRACN_ENA */
1153#define WM8904_FLL_OSC_ENA 0x0002 /* FLL_OSC_ENA */
1154#define WM8904_FLL_OSC_ENA_MASK 0x0002 /* FLL_OSC_ENA */
1155#define WM8904_FLL_OSC_ENA_SHIFT 1 /* FLL_OSC_ENA */
1156#define WM8904_FLL_OSC_ENA_WIDTH 1 /* FLL_OSC_ENA */
1157#define WM8904_FLL_ENA 0x0001 /* FLL_ENA */
1158#define WM8904_FLL_ENA_MASK 0x0001 /* FLL_ENA */
1159#define WM8904_FLL_ENA_SHIFT 0 /* FLL_ENA */
1160#define WM8904_FLL_ENA_WIDTH 1 /* FLL_ENA */
1161
1162/*
1163 * R117 (0x75) - FLL Control 2
1164 */
1165#define WM8904_FLL_OUTDIV_MASK 0x3F00 /* FLL_OUTDIV - [13:8] */
1166#define WM8904_FLL_OUTDIV_SHIFT 8 /* FLL_OUTDIV - [13:8] */
1167#define WM8904_FLL_OUTDIV_WIDTH 6 /* FLL_OUTDIV - [13:8] */
1168#define WM8904_FLL_CTRL_RATE_MASK 0x0070 /* FLL_CTRL_RATE - [6:4] */
1169#define WM8904_FLL_CTRL_RATE_SHIFT 4 /* FLL_CTRL_RATE - [6:4] */
1170#define WM8904_FLL_CTRL_RATE_WIDTH 3 /* FLL_CTRL_RATE - [6:4] */
1171#define WM8904_FLL_FRATIO_MASK 0x0007 /* FLL_FRATIO - [2:0] */
1172#define WM8904_FLL_FRATIO_SHIFT 0 /* FLL_FRATIO - [2:0] */
1173#define WM8904_FLL_FRATIO_WIDTH 3 /* FLL_FRATIO - [2:0] */
1174
1175/*
1176 * R118 (0x76) - FLL Control 3
1177 */
1178#define WM8904_FLL_K_MASK 0xFFFF /* FLL_K - [15:0] */
1179#define WM8904_FLL_K_SHIFT 0 /* FLL_K - [15:0] */
1180#define WM8904_FLL_K_WIDTH 16 /* FLL_K - [15:0] */
1181
1182/*
1183 * R119 (0x77) - FLL Control 4
1184 */
1185#define WM8904_FLL_N_MASK 0x7FE0 /* FLL_N - [14:5] */
1186#define WM8904_FLL_N_SHIFT 5 /* FLL_N - [14:5] */
1187#define WM8904_FLL_N_WIDTH 10 /* FLL_N - [14:5] */
1188#define WM8904_FLL_GAIN_MASK 0x000F /* FLL_GAIN - [3:0] */
1189#define WM8904_FLL_GAIN_SHIFT 0 /* FLL_GAIN - [3:0] */
1190#define WM8904_FLL_GAIN_WIDTH 4 /* FLL_GAIN - [3:0] */
1191
1192/*
1193 * R120 (0x78) - FLL Control 5
1194 */
1195#define WM8904_FLL_CLK_REF_DIV_MASK 0x0018 /* FLL_CLK_REF_DIV - [4:3] */
1196#define WM8904_FLL_CLK_REF_DIV_SHIFT 3 /* FLL_CLK_REF_DIV - [4:3] */
1197#define WM8904_FLL_CLK_REF_DIV_WIDTH 2 /* FLL_CLK_REF_DIV - [4:3] */
1198#define WM8904_FLL_CLK_REF_SRC_MASK 0x0003 /* FLL_CLK_REF_SRC - [1:0] */
1199#define WM8904_FLL_CLK_REF_SRC_SHIFT 0 /* FLL_CLK_REF_SRC - [1:0] */
1200#define WM8904_FLL_CLK_REF_SRC_WIDTH 2 /* FLL_CLK_REF_SRC - [1:0] */
1201
1202/*
1203 * R121 (0x79) - GPIO Control 1
1204 */
1205#define WM8904_GPIO1_PU 0x0020 /* GPIO1_PU */
1206#define WM8904_GPIO1_PU_MASK 0x0020 /* GPIO1_PU */
1207#define WM8904_GPIO1_PU_SHIFT 5 /* GPIO1_PU */
1208#define WM8904_GPIO1_PU_WIDTH 1 /* GPIO1_PU */
1209#define WM8904_GPIO1_PD 0x0010 /* GPIO1_PD */
1210#define WM8904_GPIO1_PD_MASK 0x0010 /* GPIO1_PD */
1211#define WM8904_GPIO1_PD_SHIFT 4 /* GPIO1_PD */
1212#define WM8904_GPIO1_PD_WIDTH 1 /* GPIO1_PD */
1213#define WM8904_GPIO1_SEL_MASK 0x000F /* GPIO1_SEL - [3:0] */
1214#define WM8904_GPIO1_SEL_SHIFT 0 /* GPIO1_SEL - [3:0] */
1215#define WM8904_GPIO1_SEL_WIDTH 4 /* GPIO1_SEL - [3:0] */
1216
1217/*
1218 * R122 (0x7A) - GPIO Control 2
1219 */
1220#define WM8904_GPIO2_PU 0x0020 /* GPIO2_PU */
1221#define WM8904_GPIO2_PU_MASK 0x0020 /* GPIO2_PU */
1222#define WM8904_GPIO2_PU_SHIFT 5 /* GPIO2_PU */
1223#define WM8904_GPIO2_PU_WIDTH 1 /* GPIO2_PU */
1224#define WM8904_GPIO2_PD 0x0010 /* GPIO2_PD */
1225#define WM8904_GPIO2_PD_MASK 0x0010 /* GPIO2_PD */
1226#define WM8904_GPIO2_PD_SHIFT 4 /* GPIO2_PD */
1227#define WM8904_GPIO2_PD_WIDTH 1 /* GPIO2_PD */
1228#define WM8904_GPIO2_SEL_MASK 0x000F /* GPIO2_SEL - [3:0] */
1229#define WM8904_GPIO2_SEL_SHIFT 0 /* GPIO2_SEL - [3:0] */
1230#define WM8904_GPIO2_SEL_WIDTH 4 /* GPIO2_SEL - [3:0] */
1231
1232/*
1233 * R123 (0x7B) - GPIO Control 3
1234 */
1235#define WM8904_GPIO3_PU 0x0020 /* GPIO3_PU */
1236#define WM8904_GPIO3_PU_MASK 0x0020 /* GPIO3_PU */
1237#define WM8904_GPIO3_PU_SHIFT 5 /* GPIO3_PU */
1238#define WM8904_GPIO3_PU_WIDTH 1 /* GPIO3_PU */
1239#define WM8904_GPIO3_PD 0x0010 /* GPIO3_PD */
1240#define WM8904_GPIO3_PD_MASK 0x0010 /* GPIO3_PD */
1241#define WM8904_GPIO3_PD_SHIFT 4 /* GPIO3_PD */
1242#define WM8904_GPIO3_PD_WIDTH 1 /* GPIO3_PD */
1243#define WM8904_GPIO3_SEL_MASK 0x000F /* GPIO3_SEL - [3:0] */
1244#define WM8904_GPIO3_SEL_SHIFT 0 /* GPIO3_SEL - [3:0] */
1245#define WM8904_GPIO3_SEL_WIDTH 4 /* GPIO3_SEL - [3:0] */
1246
1247/*
1248 * R124 (0x7C) - GPIO Control 4
1249 */
1250#define WM8904_GPI7_ENA 0x0200 /* GPI7_ENA */
1251#define WM8904_GPI7_ENA_MASK 0x0200 /* GPI7_ENA */
1252#define WM8904_GPI7_ENA_SHIFT 9 /* GPI7_ENA */
1253#define WM8904_GPI7_ENA_WIDTH 1 /* GPI7_ENA */
1254#define WM8904_GPI8_ENA 0x0100 /* GPI8_ENA */
1255#define WM8904_GPI8_ENA_MASK 0x0100 /* GPI8_ENA */
1256#define WM8904_GPI8_ENA_SHIFT 8 /* GPI8_ENA */
1257#define WM8904_GPI8_ENA_WIDTH 1 /* GPI8_ENA */
1258#define WM8904_GPIO_BCLK_MODE_ENA 0x0080 /* GPIO_BCLK_MODE_ENA */
1259#define WM8904_GPIO_BCLK_MODE_ENA_MASK 0x0080 /* GPIO_BCLK_MODE_ENA */
1260#define WM8904_GPIO_BCLK_MODE_ENA_SHIFT 7 /* GPIO_BCLK_MODE_ENA */
1261#define WM8904_GPIO_BCLK_MODE_ENA_WIDTH 1 /* GPIO_BCLK_MODE_ENA */
1262#define WM8904_GPIO_BCLK_SEL_MASK 0x000F /* GPIO_BCLK_SEL - [3:0] */
1263#define WM8904_GPIO_BCLK_SEL_SHIFT 0 /* GPIO_BCLK_SEL - [3:0] */
1264#define WM8904_GPIO_BCLK_SEL_WIDTH 4 /* GPIO_BCLK_SEL - [3:0] */
1265
1266/*
1267 * R126 (0x7E) - Digital Pulls
1268 */
1269#define WM8904_MCLK_PU 0x0080 /* MCLK_PU */
1270#define WM8904_MCLK_PU_MASK 0x0080 /* MCLK_PU */
1271#define WM8904_MCLK_PU_SHIFT 7 /* MCLK_PU */
1272#define WM8904_MCLK_PU_WIDTH 1 /* MCLK_PU */
1273#define WM8904_MCLK_PD 0x0040 /* MCLK_PD */
1274#define WM8904_MCLK_PD_MASK 0x0040 /* MCLK_PD */
1275#define WM8904_MCLK_PD_SHIFT 6 /* MCLK_PD */
1276#define WM8904_MCLK_PD_WIDTH 1 /* MCLK_PD */
1277#define WM8904_DACDAT_PU 0x0020 /* DACDAT_PU */
1278#define WM8904_DACDAT_PU_MASK 0x0020 /* DACDAT_PU */
1279#define WM8904_DACDAT_PU_SHIFT 5 /* DACDAT_PU */
1280#define WM8904_DACDAT_PU_WIDTH 1 /* DACDAT_PU */
1281#define WM8904_DACDAT_PD 0x0010 /* DACDAT_PD */
1282#define WM8904_DACDAT_PD_MASK 0x0010 /* DACDAT_PD */
1283#define WM8904_DACDAT_PD_SHIFT 4 /* DACDAT_PD */
1284#define WM8904_DACDAT_PD_WIDTH 1 /* DACDAT_PD */
1285#define WM8904_LRCLK_PU 0x0008 /* LRCLK_PU */
1286#define WM8904_LRCLK_PU_MASK 0x0008 /* LRCLK_PU */
1287#define WM8904_LRCLK_PU_SHIFT 3 /* LRCLK_PU */
1288#define WM8904_LRCLK_PU_WIDTH 1 /* LRCLK_PU */
1289#define WM8904_LRCLK_PD 0x0004 /* LRCLK_PD */
1290#define WM8904_LRCLK_PD_MASK 0x0004 /* LRCLK_PD */
1291#define WM8904_LRCLK_PD_SHIFT 2 /* LRCLK_PD */
1292#define WM8904_LRCLK_PD_WIDTH 1 /* LRCLK_PD */
1293#define WM8904_BCLK_PU 0x0002 /* BCLK_PU */
1294#define WM8904_BCLK_PU_MASK 0x0002 /* BCLK_PU */
1295#define WM8904_BCLK_PU_SHIFT 1 /* BCLK_PU */
1296#define WM8904_BCLK_PU_WIDTH 1 /* BCLK_PU */
1297#define WM8904_BCLK_PD 0x0001 /* BCLK_PD */
1298#define WM8904_BCLK_PD_MASK 0x0001 /* BCLK_PD */
1299#define WM8904_BCLK_PD_SHIFT 0 /* BCLK_PD */
1300#define WM8904_BCLK_PD_WIDTH 1 /* BCLK_PD */
1301
1302/*
1303 * R127 (0x7F) - Interrupt Status
1304 */
1305#define WM8904_IRQ 0x0400 /* IRQ */
1306#define WM8904_IRQ_MASK 0x0400 /* IRQ */
1307#define WM8904_IRQ_SHIFT 10 /* IRQ */
1308#define WM8904_IRQ_WIDTH 1 /* IRQ */
1309#define WM8904_GPIO_BCLK_EINT 0x0200 /* GPIO_BCLK_EINT */
1310#define WM8904_GPIO_BCLK_EINT_MASK 0x0200 /* GPIO_BCLK_EINT */
1311#define WM8904_GPIO_BCLK_EINT_SHIFT 9 /* GPIO_BCLK_EINT */
1312#define WM8904_GPIO_BCLK_EINT_WIDTH 1 /* GPIO_BCLK_EINT */
1313#define WM8904_WSEQ_EINT 0x0100 /* WSEQ_EINT */
1314#define WM8904_WSEQ_EINT_MASK 0x0100 /* WSEQ_EINT */
1315#define WM8904_WSEQ_EINT_SHIFT 8 /* WSEQ_EINT */
1316#define WM8904_WSEQ_EINT_WIDTH 1 /* WSEQ_EINT */
1317#define WM8904_GPIO3_EINT 0x0080 /* GPIO3_EINT */
1318#define WM8904_GPIO3_EINT_MASK 0x0080 /* GPIO3_EINT */
1319#define WM8904_GPIO3_EINT_SHIFT 7 /* GPIO3_EINT */
1320#define WM8904_GPIO3_EINT_WIDTH 1 /* GPIO3_EINT */
1321#define WM8904_GPIO2_EINT 0x0040 /* GPIO2_EINT */
1322#define WM8904_GPIO2_EINT_MASK 0x0040 /* GPIO2_EINT */
1323#define WM8904_GPIO2_EINT_SHIFT 6 /* GPIO2_EINT */
1324#define WM8904_GPIO2_EINT_WIDTH 1 /* GPIO2_EINT */
1325#define WM8904_GPIO1_EINT 0x0020 /* GPIO1_EINT */
1326#define WM8904_GPIO1_EINT_MASK 0x0020 /* GPIO1_EINT */
1327#define WM8904_GPIO1_EINT_SHIFT 5 /* GPIO1_EINT */
1328#define WM8904_GPIO1_EINT_WIDTH 1 /* GPIO1_EINT */
1329#define WM8904_GPI8_EINT 0x0010 /* GPI8_EINT */
1330#define WM8904_GPI8_EINT_MASK 0x0010 /* GPI8_EINT */
1331#define WM8904_GPI8_EINT_SHIFT 4 /* GPI8_EINT */
1332#define WM8904_GPI8_EINT_WIDTH 1 /* GPI8_EINT */
1333#define WM8904_GPI7_EINT 0x0008 /* GPI7_EINT */
1334#define WM8904_GPI7_EINT_MASK 0x0008 /* GPI7_EINT */
1335#define WM8904_GPI7_EINT_SHIFT 3 /* GPI7_EINT */
1336#define WM8904_GPI7_EINT_WIDTH 1 /* GPI7_EINT */
1337#define WM8904_FLL_LOCK_EINT 0x0004 /* FLL_LOCK_EINT */
1338#define WM8904_FLL_LOCK_EINT_MASK 0x0004 /* FLL_LOCK_EINT */
1339#define WM8904_FLL_LOCK_EINT_SHIFT 2 /* FLL_LOCK_EINT */
1340#define WM8904_FLL_LOCK_EINT_WIDTH 1 /* FLL_LOCK_EINT */
1341#define WM8904_MIC_SHRT_EINT 0x0002 /* MIC_SHRT_EINT */
1342#define WM8904_MIC_SHRT_EINT_MASK 0x0002 /* MIC_SHRT_EINT */
1343#define WM8904_MIC_SHRT_EINT_SHIFT 1 /* MIC_SHRT_EINT */
1344#define WM8904_MIC_SHRT_EINT_WIDTH 1 /* MIC_SHRT_EINT */
1345#define WM8904_MIC_DET_EINT 0x0001 /* MIC_DET_EINT */
1346#define WM8904_MIC_DET_EINT_MASK 0x0001 /* MIC_DET_EINT */
1347#define WM8904_MIC_DET_EINT_SHIFT 0 /* MIC_DET_EINT */
1348#define WM8904_MIC_DET_EINT_WIDTH 1 /* MIC_DET_EINT */
1349
1350/*
1351 * R128 (0x80) - Interrupt Status Mask
1352 */
1353#define WM8904_IM_GPIO_BCLK_EINT 0x0200 /* IM_GPIO_BCLK_EINT */
1354#define WM8904_IM_GPIO_BCLK_EINT_MASK 0x0200 /* IM_GPIO_BCLK_EINT */
1355#define WM8904_IM_GPIO_BCLK_EINT_SHIFT 9 /* IM_GPIO_BCLK_EINT */
1356#define WM8904_IM_GPIO_BCLK_EINT_WIDTH 1 /* IM_GPIO_BCLK_EINT */
1357#define WM8904_IM_WSEQ_EINT 0x0100 /* IM_WSEQ_EINT */
1358#define WM8904_IM_WSEQ_EINT_MASK 0x0100 /* IM_WSEQ_EINT */
1359#define WM8904_IM_WSEQ_EINT_SHIFT 8 /* IM_WSEQ_EINT */
1360#define WM8904_IM_WSEQ_EINT_WIDTH 1 /* IM_WSEQ_EINT */
1361#define WM8904_IM_GPIO3_EINT 0x0080 /* IM_GPIO3_EINT */
1362#define WM8904_IM_GPIO3_EINT_MASK 0x0080 /* IM_GPIO3_EINT */
1363#define WM8904_IM_GPIO3_EINT_SHIFT 7 /* IM_GPIO3_EINT */
1364#define WM8904_IM_GPIO3_EINT_WIDTH 1 /* IM_GPIO3_EINT */
1365#define WM8904_IM_GPIO2_EINT 0x0040 /* IM_GPIO2_EINT */
1366#define WM8904_IM_GPIO2_EINT_MASK 0x0040 /* IM_GPIO2_EINT */
1367#define WM8904_IM_GPIO2_EINT_SHIFT 6 /* IM_GPIO2_EINT */
1368#define WM8904_IM_GPIO2_EINT_WIDTH 1 /* IM_GPIO2_EINT */
1369#define WM8904_IM_GPIO1_EINT 0x0020 /* IM_GPIO1_EINT */
1370#define WM8904_IM_GPIO1_EINT_MASK 0x0020 /* IM_GPIO1_EINT */
1371#define WM8904_IM_GPIO1_EINT_SHIFT 5 /* IM_GPIO1_EINT */
1372#define WM8904_IM_GPIO1_EINT_WIDTH 1 /* IM_GPIO1_EINT */
1373#define WM8904_IM_GPI8_EINT 0x0010 /* IM_GPI8_EINT */
1374#define WM8904_IM_GPI8_EINT_MASK 0x0010 /* IM_GPI8_EINT */
1375#define WM8904_IM_GPI8_EINT_SHIFT 4 /* IM_GPI8_EINT */
1376#define WM8904_IM_GPI8_EINT_WIDTH 1 /* IM_GPI8_EINT */
1377#define WM8904_IM_GPI7_EINT 0x0008 /* IM_GPI7_EINT */
1378#define WM8904_IM_GPI7_EINT_MASK 0x0008 /* IM_GPI7_EINT */
1379#define WM8904_IM_GPI7_EINT_SHIFT 3 /* IM_GPI7_EINT */
1380#define WM8904_IM_GPI7_EINT_WIDTH 1 /* IM_GPI7_EINT */
1381#define WM8904_IM_FLL_LOCK_EINT 0x0004 /* IM_FLL_LOCK_EINT */
1382#define WM8904_IM_FLL_LOCK_EINT_MASK 0x0004 /* IM_FLL_LOCK_EINT */
1383#define WM8904_IM_FLL_LOCK_EINT_SHIFT 2 /* IM_FLL_LOCK_EINT */
1384#define WM8904_IM_FLL_LOCK_EINT_WIDTH 1 /* IM_FLL_LOCK_EINT */
1385#define WM8904_IM_MIC_SHRT_EINT 0x0002 /* IM_MIC_SHRT_EINT */
1386#define WM8904_IM_MIC_SHRT_EINT_MASK 0x0002 /* IM_MIC_SHRT_EINT */
1387#define WM8904_IM_MIC_SHRT_EINT_SHIFT 1 /* IM_MIC_SHRT_EINT */
1388#define WM8904_IM_MIC_SHRT_EINT_WIDTH 1 /* IM_MIC_SHRT_EINT */
1389#define WM8904_IM_MIC_DET_EINT 0x0001 /* IM_MIC_DET_EINT */
1390#define WM8904_IM_MIC_DET_EINT_MASK 0x0001 /* IM_MIC_DET_EINT */
1391#define WM8904_IM_MIC_DET_EINT_SHIFT 0 /* IM_MIC_DET_EINT */
1392#define WM8904_IM_MIC_DET_EINT_WIDTH 1 /* IM_MIC_DET_EINT */
1393
1394/*
1395 * R129 (0x81) - Interrupt Polarity
1396 */
1397#define WM8904_GPIO_BCLK_EINT_POL 0x0200 /* GPIO_BCLK_EINT_POL */
1398#define WM8904_GPIO_BCLK_EINT_POL_MASK 0x0200 /* GPIO_BCLK_EINT_POL */
1399#define WM8904_GPIO_BCLK_EINT_POL_SHIFT 9 /* GPIO_BCLK_EINT_POL */
1400#define WM8904_GPIO_BCLK_EINT_POL_WIDTH 1 /* GPIO_BCLK_EINT_POL */
1401#define WM8904_WSEQ_EINT_POL 0x0100 /* WSEQ_EINT_POL */
1402#define WM8904_WSEQ_EINT_POL_MASK 0x0100 /* WSEQ_EINT_POL */
1403#define WM8904_WSEQ_EINT_POL_SHIFT 8 /* WSEQ_EINT_POL */
1404#define WM8904_WSEQ_EINT_POL_WIDTH 1 /* WSEQ_EINT_POL */
1405#define WM8904_GPIO3_EINT_POL 0x0080 /* GPIO3_EINT_POL */
1406#define WM8904_GPIO3_EINT_POL_MASK 0x0080 /* GPIO3_EINT_POL */
1407#define WM8904_GPIO3_EINT_POL_SHIFT 7 /* GPIO3_EINT_POL */
1408#define WM8904_GPIO3_EINT_POL_WIDTH 1 /* GPIO3_EINT_POL */
1409#define WM8904_GPIO2_EINT_POL 0x0040 /* GPIO2_EINT_POL */
1410#define WM8904_GPIO2_EINT_POL_MASK 0x0040 /* GPIO2_EINT_POL */
1411#define WM8904_GPIO2_EINT_POL_SHIFT 6 /* GPIO2_EINT_POL */
1412#define WM8904_GPIO2_EINT_POL_WIDTH 1 /* GPIO2_EINT_POL */
1413#define WM8904_GPIO1_EINT_POL 0x0020 /* GPIO1_EINT_POL */
1414#define WM8904_GPIO1_EINT_POL_MASK 0x0020 /* GPIO1_EINT_POL */
1415#define WM8904_GPIO1_EINT_POL_SHIFT 5 /* GPIO1_EINT_POL */
1416#define WM8904_GPIO1_EINT_POL_WIDTH 1 /* GPIO1_EINT_POL */
1417#define WM8904_GPI8_EINT_POL 0x0010 /* GPI8_EINT_POL */
1418#define WM8904_GPI8_EINT_POL_MASK 0x0010 /* GPI8_EINT_POL */
1419#define WM8904_GPI8_EINT_POL_SHIFT 4 /* GPI8_EINT_POL */
1420#define WM8904_GPI8_EINT_POL_WIDTH 1 /* GPI8_EINT_POL */
1421#define WM8904_GPI7_EINT_POL 0x0008 /* GPI7_EINT_POL */
1422#define WM8904_GPI7_EINT_POL_MASK 0x0008 /* GPI7_EINT_POL */
1423#define WM8904_GPI7_EINT_POL_SHIFT 3 /* GPI7_EINT_POL */
1424#define WM8904_GPI7_EINT_POL_WIDTH 1 /* GPI7_EINT_POL */
1425#define WM8904_FLL_LOCK_EINT_POL 0x0004 /* FLL_LOCK_EINT_POL */
1426#define WM8904_FLL_LOCK_EINT_POL_MASK 0x0004 /* FLL_LOCK_EINT_POL */
1427#define WM8904_FLL_LOCK_EINT_POL_SHIFT 2 /* FLL_LOCK_EINT_POL */
1428#define WM8904_FLL_LOCK_EINT_POL_WIDTH 1 /* FLL_LOCK_EINT_POL */
1429#define WM8904_MIC_SHRT_EINT_POL 0x0002 /* MIC_SHRT_EINT_POL */
1430#define WM8904_MIC_SHRT_EINT_POL_MASK 0x0002 /* MIC_SHRT_EINT_POL */
1431#define WM8904_MIC_SHRT_EINT_POL_SHIFT 1 /* MIC_SHRT_EINT_POL */
1432#define WM8904_MIC_SHRT_EINT_POL_WIDTH 1 /* MIC_SHRT_EINT_POL */
1433#define WM8904_MIC_DET_EINT_POL 0x0001 /* MIC_DET_EINT_POL */
1434#define WM8904_MIC_DET_EINT_POL_MASK 0x0001 /* MIC_DET_EINT_POL */
1435#define WM8904_MIC_DET_EINT_POL_SHIFT 0 /* MIC_DET_EINT_POL */
1436#define WM8904_MIC_DET_EINT_POL_WIDTH 1 /* MIC_DET_EINT_POL */
1437
1438/*
1439 * R130 (0x82) - Interrupt Debounce
1440 */
1441#define WM8904_GPIO_BCLK_EINT_DB 0x0200 /* GPIO_BCLK_EINT_DB */
1442#define WM8904_GPIO_BCLK_EINT_DB_MASK 0x0200 /* GPIO_BCLK_EINT_DB */
1443#define WM8904_GPIO_BCLK_EINT_DB_SHIFT 9 /* GPIO_BCLK_EINT_DB */
1444#define WM8904_GPIO_BCLK_EINT_DB_WIDTH 1 /* GPIO_BCLK_EINT_DB */
1445#define WM8904_WSEQ_EINT_DB 0x0100 /* WSEQ_EINT_DB */
1446#define WM8904_WSEQ_EINT_DB_MASK 0x0100 /* WSEQ_EINT_DB */
1447#define WM8904_WSEQ_EINT_DB_SHIFT 8 /* WSEQ_EINT_DB */
1448#define WM8904_WSEQ_EINT_DB_WIDTH 1 /* WSEQ_EINT_DB */
1449#define WM8904_GPIO3_EINT_DB 0x0080 /* GPIO3_EINT_DB */
1450#define WM8904_GPIO3_EINT_DB_MASK 0x0080 /* GPIO3_EINT_DB */
1451#define WM8904_GPIO3_EINT_DB_SHIFT 7 /* GPIO3_EINT_DB */
1452#define WM8904_GPIO3_EINT_DB_WIDTH 1 /* GPIO3_EINT_DB */
1453#define WM8904_GPIO2_EINT_DB 0x0040 /* GPIO2_EINT_DB */
1454#define WM8904_GPIO2_EINT_DB_MASK 0x0040 /* GPIO2_EINT_DB */
1455#define WM8904_GPIO2_EINT_DB_SHIFT 6 /* GPIO2_EINT_DB */
1456#define WM8904_GPIO2_EINT_DB_WIDTH 1 /* GPIO2_EINT_DB */
1457#define WM8904_GPIO1_EINT_DB 0x0020 /* GPIO1_EINT_DB */
1458#define WM8904_GPIO1_EINT_DB_MASK 0x0020 /* GPIO1_EINT_DB */
1459#define WM8904_GPIO1_EINT_DB_SHIFT 5 /* GPIO1_EINT_DB */
1460#define WM8904_GPIO1_EINT_DB_WIDTH 1 /* GPIO1_EINT_DB */
1461#define WM8904_GPI8_EINT_DB 0x0010 /* GPI8_EINT_DB */
1462#define WM8904_GPI8_EINT_DB_MASK 0x0010 /* GPI8_EINT_DB */
1463#define WM8904_GPI8_EINT_DB_SHIFT 4 /* GPI8_EINT_DB */
1464#define WM8904_GPI8_EINT_DB_WIDTH 1 /* GPI8_EINT_DB */
1465#define WM8904_GPI7_EINT_DB 0x0008 /* GPI7_EINT_DB */
1466#define WM8904_GPI7_EINT_DB_MASK 0x0008 /* GPI7_EINT_DB */
1467#define WM8904_GPI7_EINT_DB_SHIFT 3 /* GPI7_EINT_DB */
1468#define WM8904_GPI7_EINT_DB_WIDTH 1 /* GPI7_EINT_DB */
1469#define WM8904_FLL_LOCK_EINT_DB 0x0004 /* FLL_LOCK_EINT_DB */
1470#define WM8904_FLL_LOCK_EINT_DB_MASK 0x0004 /* FLL_LOCK_EINT_DB */
1471#define WM8904_FLL_LOCK_EINT_DB_SHIFT 2 /* FLL_LOCK_EINT_DB */
1472#define WM8904_FLL_LOCK_EINT_DB_WIDTH 1 /* FLL_LOCK_EINT_DB */
1473#define WM8904_MIC_SHRT_EINT_DB 0x0002 /* MIC_SHRT_EINT_DB */
1474#define WM8904_MIC_SHRT_EINT_DB_MASK 0x0002 /* MIC_SHRT_EINT_DB */
1475#define WM8904_MIC_SHRT_EINT_DB_SHIFT 1 /* MIC_SHRT_EINT_DB */
1476#define WM8904_MIC_SHRT_EINT_DB_WIDTH 1 /* MIC_SHRT_EINT_DB */
1477#define WM8904_MIC_DET_EINT_DB 0x0001 /* MIC_DET_EINT_DB */
1478#define WM8904_MIC_DET_EINT_DB_MASK 0x0001 /* MIC_DET_EINT_DB */
1479#define WM8904_MIC_DET_EINT_DB_SHIFT 0 /* MIC_DET_EINT_DB */
1480#define WM8904_MIC_DET_EINT_DB_WIDTH 1 /* MIC_DET_EINT_DB */
1481
1482/*
1483 * R134 (0x86) - EQ1
1484 */
1485#define WM8904_EQ_ENA 0x0001 /* EQ_ENA */
1486#define WM8904_EQ_ENA_MASK 0x0001 /* EQ_ENA */
1487#define WM8904_EQ_ENA_SHIFT 0 /* EQ_ENA */
1488#define WM8904_EQ_ENA_WIDTH 1 /* EQ_ENA */
1489
1490/*
1491 * R135 (0x87) - EQ2
1492 */
1493#define WM8904_EQ_B1_GAIN_MASK 0x001F /* EQ_B1_GAIN - [4:0] */
1494#define WM8904_EQ_B1_GAIN_SHIFT 0 /* EQ_B1_GAIN - [4:0] */
1495#define WM8904_EQ_B1_GAIN_WIDTH 5 /* EQ_B1_GAIN - [4:0] */
1496
1497/*
1498 * R136 (0x88) - EQ3
1499 */
1500#define WM8904_EQ_B2_GAIN_MASK 0x001F /* EQ_B2_GAIN - [4:0] */
1501#define WM8904_EQ_B2_GAIN_SHIFT 0 /* EQ_B2_GAIN - [4:0] */
1502#define WM8904_EQ_B2_GAIN_WIDTH 5 /* EQ_B2_GAIN - [4:0] */
1503
1504/*
1505 * R137 (0x89) - EQ4
1506 */
1507#define WM8904_EQ_B3_GAIN_MASK 0x001F /* EQ_B3_GAIN - [4:0] */
1508#define WM8904_EQ_B3_GAIN_SHIFT 0 /* EQ_B3_GAIN - [4:0] */
1509#define WM8904_EQ_B3_GAIN_WIDTH 5 /* EQ_B3_GAIN - [4:0] */
1510
1511/*
1512 * R138 (0x8A) - EQ5
1513 */
1514#define WM8904_EQ_B4_GAIN_MASK 0x001F /* EQ_B4_GAIN - [4:0] */
1515#define WM8904_EQ_B4_GAIN_SHIFT 0 /* EQ_B4_GAIN - [4:0] */
1516#define WM8904_EQ_B4_GAIN_WIDTH 5 /* EQ_B4_GAIN - [4:0] */
1517
1518/*
1519 * R139 (0x8B) - EQ6
1520 */
1521#define WM8904_EQ_B5_GAIN_MASK 0x001F /* EQ_B5_GAIN - [4:0] */
1522#define WM8904_EQ_B5_GAIN_SHIFT 0 /* EQ_B5_GAIN - [4:0] */
1523#define WM8904_EQ_B5_GAIN_WIDTH 5 /* EQ_B5_GAIN - [4:0] */
1524
1525/*
1526 * R140 (0x8C) - EQ7
1527 */
1528#define WM8904_EQ_B1_A_MASK 0xFFFF /* EQ_B1_A - [15:0] */
1529#define WM8904_EQ_B1_A_SHIFT 0 /* EQ_B1_A - [15:0] */
1530#define WM8904_EQ_B1_A_WIDTH 16 /* EQ_B1_A - [15:0] */
1531
1532/*
1533 * R141 (0x8D) - EQ8
1534 */
1535#define WM8904_EQ_B1_B_MASK 0xFFFF /* EQ_B1_B - [15:0] */
1536#define WM8904_EQ_B1_B_SHIFT 0 /* EQ_B1_B - [15:0] */
1537#define WM8904_EQ_B1_B_WIDTH 16 /* EQ_B1_B - [15:0] */
1538
1539/*
1540 * R142 (0x8E) - EQ9
1541 */
1542#define WM8904_EQ_B1_PG_MASK 0xFFFF /* EQ_B1_PG - [15:0] */
1543#define WM8904_EQ_B1_PG_SHIFT 0 /* EQ_B1_PG - [15:0] */
1544#define WM8904_EQ_B1_PG_WIDTH 16 /* EQ_B1_PG - [15:0] */
1545
1546/*
1547 * R143 (0x8F) - EQ10
1548 */
1549#define WM8904_EQ_B2_A_MASK 0xFFFF /* EQ_B2_A - [15:0] */
1550#define WM8904_EQ_B2_A_SHIFT 0 /* EQ_B2_A - [15:0] */
1551#define WM8904_EQ_B2_A_WIDTH 16 /* EQ_B2_A - [15:0] */
1552
1553/*
1554 * R144 (0x90) - EQ11
1555 */
1556#define WM8904_EQ_B2_B_MASK 0xFFFF /* EQ_B2_B - [15:0] */
1557#define WM8904_EQ_B2_B_SHIFT 0 /* EQ_B2_B - [15:0] */
1558#define WM8904_EQ_B2_B_WIDTH 16 /* EQ_B2_B - [15:0] */
1559
1560/*
1561 * R145 (0x91) - EQ12
1562 */
1563#define WM8904_EQ_B2_C_MASK 0xFFFF /* EQ_B2_C - [15:0] */
1564#define WM8904_EQ_B2_C_SHIFT 0 /* EQ_B2_C - [15:0] */
1565#define WM8904_EQ_B2_C_WIDTH 16 /* EQ_B2_C - [15:0] */
1566
1567/*
1568 * R146 (0x92) - EQ13
1569 */
1570#define WM8904_EQ_B2_PG_MASK 0xFFFF /* EQ_B2_PG - [15:0] */
1571#define WM8904_EQ_B2_PG_SHIFT 0 /* EQ_B2_PG - [15:0] */
1572#define WM8904_EQ_B2_PG_WIDTH 16 /* EQ_B2_PG - [15:0] */
1573
1574/*
1575 * R147 (0x93) - EQ14
1576 */
1577#define WM8904_EQ_B3_A_MASK 0xFFFF /* EQ_B3_A - [15:0] */
1578#define WM8904_EQ_B3_A_SHIFT 0 /* EQ_B3_A - [15:0] */
1579#define WM8904_EQ_B3_A_WIDTH 16 /* EQ_B3_A - [15:0] */
1580
1581/*
1582 * R148 (0x94) - EQ15
1583 */
1584#define WM8904_EQ_B3_B_MASK 0xFFFF /* EQ_B3_B - [15:0] */
1585#define WM8904_EQ_B3_B_SHIFT 0 /* EQ_B3_B - [15:0] */
1586#define WM8904_EQ_B3_B_WIDTH 16 /* EQ_B3_B - [15:0] */
1587
1588/*
1589 * R149 (0x95) - EQ16
1590 */
1591#define WM8904_EQ_B3_C_MASK 0xFFFF /* EQ_B3_C - [15:0] */
1592#define WM8904_EQ_B3_C_SHIFT 0 /* EQ_B3_C - [15:0] */
1593#define WM8904_EQ_B3_C_WIDTH 16 /* EQ_B3_C - [15:0] */
1594
1595/*
1596 * R150 (0x96) - EQ17
1597 */
1598#define WM8904_EQ_B3_PG_MASK 0xFFFF /* EQ_B3_PG - [15:0] */
1599#define WM8904_EQ_B3_PG_SHIFT 0 /* EQ_B3_PG - [15:0] */
1600#define WM8904_EQ_B3_PG_WIDTH 16 /* EQ_B3_PG - [15:0] */
1601
1602/*
1603 * R151 (0x97) - EQ18
1604 */
1605#define WM8904_EQ_B4_A_MASK 0xFFFF /* EQ_B4_A - [15:0] */
1606#define WM8904_EQ_B4_A_SHIFT 0 /* EQ_B4_A - [15:0] */
1607#define WM8904_EQ_B4_A_WIDTH 16 /* EQ_B4_A - [15:0] */
1608
1609/*
1610 * R152 (0x98) - EQ19
1611 */
1612#define WM8904_EQ_B4_B_MASK 0xFFFF /* EQ_B4_B - [15:0] */
1613#define WM8904_EQ_B4_B_SHIFT 0 /* EQ_B4_B - [15:0] */
1614#define WM8904_EQ_B4_B_WIDTH 16 /* EQ_B4_B - [15:0] */
1615
1616/*
1617 * R153 (0x99) - EQ20
1618 */
1619#define WM8904_EQ_B4_C_MASK 0xFFFF /* EQ_B4_C - [15:0] */
1620#define WM8904_EQ_B4_C_SHIFT 0 /* EQ_B4_C - [15:0] */
1621#define WM8904_EQ_B4_C_WIDTH 16 /* EQ_B4_C - [15:0] */
1622
1623/*
1624 * R154 (0x9A) - EQ21
1625 */
1626#define WM8904_EQ_B4_PG_MASK 0xFFFF /* EQ_B4_PG - [15:0] */
1627#define WM8904_EQ_B4_PG_SHIFT 0 /* EQ_B4_PG - [15:0] */
1628#define WM8904_EQ_B4_PG_WIDTH 16 /* EQ_B4_PG - [15:0] */
1629
1630/*
1631 * R155 (0x9B) - EQ22
1632 */
1633#define WM8904_EQ_B5_A_MASK 0xFFFF /* EQ_B5_A - [15:0] */
1634#define WM8904_EQ_B5_A_SHIFT 0 /* EQ_B5_A - [15:0] */
1635#define WM8904_EQ_B5_A_WIDTH 16 /* EQ_B5_A - [15:0] */
1636
1637/*
1638 * R156 (0x9C) - EQ23
1639 */
1640#define WM8904_EQ_B5_B_MASK 0xFFFF /* EQ_B5_B - [15:0] */
1641#define WM8904_EQ_B5_B_SHIFT 0 /* EQ_B5_B - [15:0] */
1642#define WM8904_EQ_B5_B_WIDTH 16 /* EQ_B5_B - [15:0] */
1643
1644/*
1645 * R157 (0x9D) - EQ24
1646 */
1647#define WM8904_EQ_B5_PG_MASK 0xFFFF /* EQ_B5_PG - [15:0] */
1648#define WM8904_EQ_B5_PG_SHIFT 0 /* EQ_B5_PG - [15:0] */
1649#define WM8904_EQ_B5_PG_WIDTH 16 /* EQ_B5_PG - [15:0] */
1650
1651/*
1652 * R161 (0xA1) - Control Interface Test 1
1653 */
1654#define WM8904_USER_KEY 0x0002 /* USER_KEY */
1655#define WM8904_USER_KEY_MASK 0x0002 /* USER_KEY */
1656#define WM8904_USER_KEY_SHIFT 1 /* USER_KEY */
1657#define WM8904_USER_KEY_WIDTH 1 /* USER_KEY */
1658
1659/*
1660 * R204 (0xCC) - Analogue Output Bias 0
1661 */
1662#define WM8904_PGA_BIAS_MASK 0x0070 /* PGA_BIAS - [6:4] */
1663#define WM8904_PGA_BIAS_SHIFT 4 /* PGA_BIAS - [6:4] */
1664#define WM8904_PGA_BIAS_WIDTH 3 /* PGA_BIAS - [6:4] */
1665
1666/*
1667 * R247 (0xF7) - FLL NCO Test 0
1668 */
1669#define WM8904_FLL_FRC_NCO 0x0001 /* FLL_FRC_NCO */
1670#define WM8904_FLL_FRC_NCO_MASK 0x0001 /* FLL_FRC_NCO */
1671#define WM8904_FLL_FRC_NCO_SHIFT 0 /* FLL_FRC_NCO */
1672#define WM8904_FLL_FRC_NCO_WIDTH 1 /* FLL_FRC_NCO */
1673
1674/*
1675 * R248 (0xF8) - FLL NCO Test 1
1676 */
1677#define WM8904_FLL_FRC_NCO_VAL_MASK 0x003F /* FLL_FRC_NCO_VAL - [5:0] */
1678#define WM8904_FLL_FRC_NCO_VAL_SHIFT 0 /* FLL_FRC_NCO_VAL - [5:0] */
1679#define WM8904_FLL_FRC_NCO_VAL_WIDTH 6 /* FLL_FRC_NCO_VAL - [5:0] */
1680
1681#endif
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c
new file mode 100644
index 000000000000..615dab2b62ef
--- /dev/null
+++ b/sound/soc/codecs/wm8955.c
@@ -0,0 +1,1151 @@
1/*
2 * wm8955.c -- WM8955 ALSA SoC Audio driver
3 *
4 * Copyright 2009 Wolfson Microelectronics plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/init.h>
16#include <linux/delay.h>
17#include <linux/pm.h>
18#include <linux/i2c.h>
19#include <linux/platform_device.h>
20#include <linux/regulator/consumer.h>
21#include <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/pcm_params.h>
24#include <sound/soc.h>
25#include <sound/soc-dapm.h>
26#include <sound/initval.h>
27#include <sound/tlv.h>
28#include <sound/wm8955.h>
29
30#include "wm8955.h"
31
32static struct snd_soc_codec *wm8955_codec;
33struct snd_soc_codec_device soc_codec_dev_wm8955;
34
35#define WM8955_NUM_SUPPLIES 4
36static const char *wm8955_supply_names[WM8955_NUM_SUPPLIES] = {
37 "DCVDD",
38 "DBVDD",
39 "HPVDD",
40 "AVDD",
41};
42
43/* codec private data */
44struct wm8955_priv {
45 struct snd_soc_codec codec;
46 u16 reg_cache[WM8955_MAX_REGISTER + 1];
47
48 unsigned int mclk_rate;
49
50 int deemph;
51 int fs;
52
53 struct regulator_bulk_data supplies[WM8955_NUM_SUPPLIES];
54
55 struct wm8955_pdata *pdata;
56};
57
58static const u16 wm8955_reg[WM8955_MAX_REGISTER + 1] = {
59 0x0000, /* R0 */
60 0x0000, /* R1 */
61 0x0079, /* R2 - LOUT1 volume */
62 0x0079, /* R3 - ROUT1 volume */
63 0x0000, /* R4 */
64 0x0008, /* R5 - DAC Control */
65 0x0000, /* R6 */
66 0x000A, /* R7 - Audio Interface */
67 0x0000, /* R8 - Sample Rate */
68 0x0000, /* R9 */
69 0x00FF, /* R10 - Left DAC volume */
70 0x00FF, /* R11 - Right DAC volume */
71 0x000F, /* R12 - Bass control */
72 0x000F, /* R13 - Treble control */
73 0x0000, /* R14 */
74 0x0000, /* R15 - Reset */
75 0x0000, /* R16 */
76 0x0000, /* R17 */
77 0x0000, /* R18 */
78 0x0000, /* R19 */
79 0x0000, /* R20 */
80 0x0000, /* R21 */
81 0x0000, /* R22 */
82 0x00C1, /* R23 - Additional control (1) */
83 0x0000, /* R24 - Additional control (2) */
84 0x0000, /* R25 - Power Management (1) */
85 0x0000, /* R26 - Power Management (2) */
86 0x0000, /* R27 - Additional Control (3) */
87 0x0000, /* R28 */
88 0x0000, /* R29 */
89 0x0000, /* R30 */
90 0x0000, /* R31 */
91 0x0000, /* R32 */
92 0x0000, /* R33 */
93 0x0050, /* R34 - Left out Mix (1) */
94 0x0050, /* R35 - Left out Mix (2) */
95 0x0050, /* R36 - Right out Mix (1) */
96 0x0050, /* R37 - Right Out Mix (2) */
97 0x0050, /* R38 - Mono out Mix (1) */
98 0x0050, /* R39 - Mono out Mix (2) */
99 0x0079, /* R40 - LOUT2 volume */
100 0x0079, /* R41 - ROUT2 volume */
101 0x0079, /* R42 - MONOOUT volume */
102 0x0000, /* R43 - Clocking / PLL */
103 0x0103, /* R44 - PLL Control 1 */
104 0x0024, /* R45 - PLL Control 2 */
105 0x01BA, /* R46 - PLL Control 3 */
106 0x0000, /* R47 */
107 0x0000, /* R48 */
108 0x0000, /* R49 */
109 0x0000, /* R50 */
110 0x0000, /* R51 */
111 0x0000, /* R52 */
112 0x0000, /* R53 */
113 0x0000, /* R54 */
114 0x0000, /* R55 */
115 0x0000, /* R56 */
116 0x0000, /* R57 */
117 0x0000, /* R58 */
118 0x0000, /* R59 - PLL Control 4 */
119};
120
121static int wm8955_reset(struct snd_soc_codec *codec)
122{
123 return snd_soc_write(codec, WM8955_RESET, 0);
124}
125
126struct pll_factors {
127 int n;
128 int k;
129 int outdiv;
130};
131
132/* The size in bits of the FLL divide multiplied by 10
133 * to allow rounding later */
134#define FIXED_FLL_SIZE ((1 << 22) * 10)
135
136static int wm8995_pll_factors(struct device *dev,
137 int Fref, int Fout, struct pll_factors *pll)
138{
139 u64 Kpart;
140 unsigned int K, Ndiv, Nmod, target;
141
142 dev_dbg(dev, "Fref=%u Fout=%u\n", Fref, Fout);
143
144 /* The oscilator should run at should be 90-100MHz, and
145 * there's a divide by 4 plus an optional divide by 2 in the
146 * output path to generate the system clock. The clock table
147 * is sortd so we should always generate a suitable target. */
148 target = Fout * 4;
149 if (target < 90000000) {
150 pll->outdiv = 1;
151 target *= 2;
152 } else {
153 pll->outdiv = 0;
154 }
155
156 WARN_ON(target < 90000000 || target > 100000000);
157
158 dev_dbg(dev, "Fvco=%dHz\n", target);
159
160 /* Now, calculate N.K */
161 Ndiv = target / Fref;
162
163 pll->n = Ndiv;
164 Nmod = target % Fref;
165 dev_dbg(dev, "Nmod=%d\n", Nmod);
166
167 /* Calculate fractional part - scale up so we can round. */
168 Kpart = FIXED_FLL_SIZE * (long long)Nmod;
169
170 do_div(Kpart, Fref);
171
172 K = Kpart & 0xFFFFFFFF;
173
174 if ((K % 10) >= 5)
175 K += 5;
176
177 /* Move down to proper range now rounding is done */
178 pll->k = K / 10;
179
180 dev_dbg(dev, "N=%x K=%x OUTDIV=%x\n", pll->n, pll->k, pll->outdiv);
181
182 return 0;
183}
184
185/* Lookup table specifiying SRATE (table 25 in datasheet); some of the
186 * output frequencies have been rounded to the standard frequencies
187 * they are intended to match where the error is slight. */
188static struct {
189 int mclk;
190 int fs;
191 int usb;
192 int sr;
193} clock_cfgs[] = {
194 { 18432000, 8000, 0, 3, },
195 { 18432000, 12000, 0, 9, },
196 { 18432000, 16000, 0, 11, },
197 { 18432000, 24000, 0, 29, },
198 { 18432000, 32000, 0, 13, },
199 { 18432000, 48000, 0, 1, },
200 { 18432000, 96000, 0, 15, },
201
202 { 16934400, 8018, 0, 19, },
203 { 16934400, 11025, 0, 25, },
204 { 16934400, 22050, 0, 27, },
205 { 16934400, 44100, 0, 17, },
206 { 16934400, 88200, 0, 31, },
207
208 { 12000000, 8000, 1, 2, },
209 { 12000000, 11025, 1, 25, },
210 { 12000000, 12000, 1, 8, },
211 { 12000000, 16000, 1, 10, },
212 { 12000000, 22050, 1, 27, },
213 { 12000000, 24000, 1, 28, },
214 { 12000000, 32000, 1, 12, },
215 { 12000000, 44100, 1, 17, },
216 { 12000000, 48000, 1, 0, },
217 { 12000000, 88200, 1, 31, },
218 { 12000000, 96000, 1, 14, },
219
220 { 12288000, 8000, 0, 2, },
221 { 12288000, 12000, 0, 8, },
222 { 12288000, 16000, 0, 10, },
223 { 12288000, 24000, 0, 28, },
224 { 12288000, 32000, 0, 12, },
225 { 12288000, 48000, 0, 0, },
226 { 12288000, 96000, 0, 14, },
227
228 { 12289600, 8018, 0, 18, },
229 { 12289600, 11025, 0, 24, },
230 { 12289600, 22050, 0, 26, },
231 { 11289600, 44100, 0, 16, },
232 { 11289600, 88200, 0, 31, },
233};
234
235static int wm8955_configure_clocking(struct snd_soc_codec *codec)
236{
237 struct wm8955_priv *wm8955 = codec->private_data;
238 int i, ret, val;
239 int clocking = 0;
240 int srate = 0;
241 int sr = -1;
242 struct pll_factors pll;
243
244 /* If we're not running a sample rate currently just pick one */
245 if (wm8955->fs == 0)
246 wm8955->fs = 8000;
247
248 /* Can we generate an exact output? */
249 for (i = 0; i < ARRAY_SIZE(clock_cfgs); i++) {
250 if (wm8955->fs != clock_cfgs[i].fs)
251 continue;
252 sr = i;
253
254 if (wm8955->mclk_rate == clock_cfgs[i].mclk)
255 break;
256 }
257
258 /* We should never get here with an unsupported sample rate */
259 if (sr == -1) {
260 dev_err(codec->dev, "Sample rate %dHz unsupported\n",
261 wm8955->fs);
262 WARN_ON(sr == -1);
263 return -EINVAL;
264 }
265
266 if (i == ARRAY_SIZE(clock_cfgs)) {
267 /* If we can't generate the right clock from MCLK then
268 * we should configure the PLL to supply us with an
269 * appropriate clock.
270 */
271 clocking |= WM8955_MCLKSEL;
272
273 /* Use the last divider configuration we saw for the
274 * sample rate. */
275 ret = wm8995_pll_factors(codec->dev, wm8955->mclk_rate,
276 clock_cfgs[sr].mclk, &pll);
277 if (ret != 0) {
278 dev_err(codec->dev,
279 "Unable to generate %dHz from %dHz MCLK\n",
280 wm8955->fs, wm8955->mclk_rate);
281 return -EINVAL;
282 }
283
284 snd_soc_update_bits(codec, WM8955_PLL_CONTROL_1,
285 WM8955_N_MASK | WM8955_K_21_18_MASK,
286 (pll.n << WM8955_N_SHIFT) |
287 pll.k >> 18);
288 snd_soc_update_bits(codec, WM8955_PLL_CONTROL_2,
289 WM8955_K_17_9_MASK,
290 (pll.k >> 9) & WM8955_K_17_9_MASK);
291 snd_soc_update_bits(codec, WM8955_PLL_CONTROL_2,
292 WM8955_K_8_0_MASK,
293 pll.k & WM8955_K_8_0_MASK);
294 if (pll.k)
295 snd_soc_update_bits(codec, WM8955_PLL_CONTROL_4,
296 WM8955_KEN, WM8955_KEN);
297 else
298 snd_soc_update_bits(codec, WM8955_PLL_CONTROL_4,
299 WM8955_KEN, 0);
300
301 if (pll.outdiv)
302 val = WM8955_PLL_RB | WM8955_PLLOUTDIV2;
303 else
304 val = WM8955_PLL_RB;
305
306 /* Now start the PLL running */
307 snd_soc_update_bits(codec, WM8955_CLOCKING_PLL,
308 WM8955_PLL_RB | WM8955_PLLOUTDIV2, val);
309 snd_soc_update_bits(codec, WM8955_CLOCKING_PLL,
310 WM8955_PLLEN, WM8955_PLLEN);
311 }
312
313 srate = clock_cfgs[sr].usb | (clock_cfgs[sr].sr << WM8955_SR_SHIFT);
314
315 snd_soc_update_bits(codec, WM8955_SAMPLE_RATE,
316 WM8955_USB | WM8955_SR_MASK, srate);
317 snd_soc_update_bits(codec, WM8955_CLOCKING_PLL,
318 WM8955_MCLKSEL, clocking);
319
320 return 0;
321}
322
323static int wm8955_sysclk(struct snd_soc_dapm_widget *w,
324 struct snd_kcontrol *kcontrol, int event)
325{
326 struct snd_soc_codec *codec = w->codec;
327 int ret = 0;
328
329 /* Always disable the clocks - if we're doing reconfiguration this
330 * avoids misclocking.
331 */
332 snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1,
333 WM8955_DIGENB, 0);
334 snd_soc_update_bits(codec, WM8955_CLOCKING_PLL,
335 WM8955_PLL_RB | WM8955_PLLEN, 0);
336
337 switch (event) {
338 case SND_SOC_DAPM_POST_PMD:
339 break;
340 case SND_SOC_DAPM_PRE_PMU:
341 ret = wm8955_configure_clocking(codec);
342 break;
343 default:
344 ret = -EINVAL;
345 break;
346 }
347
348 return ret;
349}
350
351static int deemph_settings[] = { 0, 32000, 44100, 48000 };
352
353static int wm8955_set_deemph(struct snd_soc_codec *codec)
354{
355 struct wm8955_priv *wm8955 = codec->private_data;
356 int val, i, best;
357
358 /* If we're using deemphasis select the nearest available sample
359 * rate.
360 */
361 if (wm8955->deemph) {
362 best = 1;
363 for (i = 2; i < ARRAY_SIZE(deemph_settings); i++) {
364 if (abs(deemph_settings[i] - wm8955->fs) <
365 abs(deemph_settings[best] - wm8955->fs))
366 best = i;
367 }
368
369 val = best << WM8955_DEEMPH_SHIFT;
370 } else {
371 val = 0;
372 }
373
374 dev_dbg(codec->dev, "Set deemphasis %d\n", val);
375
376 return snd_soc_update_bits(codec, WM8955_DAC_CONTROL,
377 WM8955_DEEMPH_MASK, val);
378}
379
380static int wm8955_get_deemph(struct snd_kcontrol *kcontrol,
381 struct snd_ctl_elem_value *ucontrol)
382{
383 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
384 struct wm8955_priv *wm8955 = codec->private_data;
385
386 return wm8955->deemph;
387}
388
389static int wm8955_put_deemph(struct snd_kcontrol *kcontrol,
390 struct snd_ctl_elem_value *ucontrol)
391{
392 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
393 struct wm8955_priv *wm8955 = codec->private_data;
394 int deemph = ucontrol->value.enumerated.item[0];
395
396 if (deemph > 1)
397 return -EINVAL;
398
399 wm8955->deemph = deemph;
400
401 return wm8955_set_deemph(codec);
402}
403
404static const char *bass_mode_text[] = {
405 "Linear", "Adaptive",
406};
407
408static const struct soc_enum bass_mode =
409 SOC_ENUM_SINGLE(WM8955_BASS_CONTROL, 7, 2, bass_mode_text);
410
411static const char *bass_cutoff_text[] = {
412 "Low", "High"
413};
414
415static const struct soc_enum bass_cutoff =
416 SOC_ENUM_SINGLE(WM8955_BASS_CONTROL, 6, 2, bass_cutoff_text);
417
418static const char *treble_cutoff_text[] = {
419 "High", "Low"
420};
421
422static const struct soc_enum treble_cutoff =
423 SOC_ENUM_SINGLE(WM8955_TREBLE_CONTROL, 6, 2, treble_cutoff_text);
424
425static const DECLARE_TLV_DB_SCALE(digital_tlv, -12750, 50, 1);
426static const DECLARE_TLV_DB_SCALE(atten_tlv, -600, 600, 0);
427static const DECLARE_TLV_DB_SCALE(bypass_tlv, -1500, 300, 0);
428static const DECLARE_TLV_DB_SCALE(mono_tlv, -2100, 300, 0);
429static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1);
430static const DECLARE_TLV_DB_SCALE(treble_tlv, -1200, 150, 1);
431
432static const struct snd_kcontrol_new wm8955_snd_controls[] = {
433SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8955_LEFT_DAC_VOLUME,
434 WM8955_RIGHT_DAC_VOLUME, 0, 255, 0, digital_tlv),
435SOC_SINGLE_TLV("Playback Attenuation Volume", WM8955_DAC_CONTROL, 7, 1, 1,
436 atten_tlv),
437SOC_SINGLE_BOOL_EXT("DAC Deemphasis Switch", 0,
438 wm8955_get_deemph, wm8955_put_deemph),
439
440SOC_ENUM("Bass Mode", bass_mode),
441SOC_ENUM("Bass Cutoff", bass_cutoff),
442SOC_SINGLE("Bass Volume", WM8955_BASS_CONTROL, 0, 15, 1),
443
444SOC_ENUM("Treble Cutoff", treble_cutoff),
445SOC_SINGLE_TLV("Treble Volume", WM8955_TREBLE_CONTROL, 0, 14, 1, treble_tlv),
446
447SOC_SINGLE_TLV("Left Bypass Volume", WM8955_LEFT_OUT_MIX_1, 4, 7, 1,
448 bypass_tlv),
449SOC_SINGLE_TLV("Left Mono Volume", WM8955_LEFT_OUT_MIX_2, 4, 7, 1,
450 bypass_tlv),
451
452SOC_SINGLE_TLV("Right Mono Volume", WM8955_RIGHT_OUT_MIX_1, 4, 7, 1,
453 bypass_tlv),
454SOC_SINGLE_TLV("Right Bypass Volume", WM8955_RIGHT_OUT_MIX_2, 4, 7, 1,
455 bypass_tlv),
456
457/* Not a stereo pair so they line up with the DAPM switches */
458SOC_SINGLE_TLV("Mono Left Bypass Volume", WM8955_MONO_OUT_MIX_1, 4, 7, 1,
459 mono_tlv),
460SOC_SINGLE_TLV("Mono Right Bypass Volume", WM8955_MONO_OUT_MIX_2, 4, 7, 1,
461 mono_tlv),
462
463SOC_DOUBLE_R_TLV("Headphone Volume", WM8955_LOUT1_VOLUME,
464 WM8955_ROUT1_VOLUME, 0, 127, 0, out_tlv),
465SOC_DOUBLE_R("Headphone ZC Switch", WM8955_LOUT1_VOLUME,
466 WM8955_ROUT1_VOLUME, 7, 1, 0),
467
468SOC_DOUBLE_R_TLV("Speaker Volume", WM8955_LOUT2_VOLUME,
469 WM8955_ROUT2_VOLUME, 0, 127, 0, out_tlv),
470SOC_DOUBLE_R("Speaker ZC Switch", WM8955_LOUT2_VOLUME,
471 WM8955_ROUT2_VOLUME, 7, 1, 0),
472
473SOC_SINGLE_TLV("Mono Volume", WM8955_MONOOUT_VOLUME, 0, 127, 0, out_tlv),
474SOC_SINGLE("Mono ZC Switch", WM8955_MONOOUT_VOLUME, 7, 1, 0),
475};
476
477static const struct snd_kcontrol_new lmixer[] = {
478SOC_DAPM_SINGLE("Playback Switch", WM8955_LEFT_OUT_MIX_1, 8, 1, 0),
479SOC_DAPM_SINGLE("Bypass Switch", WM8955_LEFT_OUT_MIX_1, 7, 1, 0),
480SOC_DAPM_SINGLE("Right Playback Switch", WM8955_LEFT_OUT_MIX_2, 8, 1, 0),
481SOC_DAPM_SINGLE("Mono Switch", WM8955_LEFT_OUT_MIX_2, 7, 1, 0),
482};
483
484static const struct snd_kcontrol_new rmixer[] = {
485SOC_DAPM_SINGLE("Left Playback Switch", WM8955_RIGHT_OUT_MIX_1, 8, 1, 0),
486SOC_DAPM_SINGLE("Mono Switch", WM8955_RIGHT_OUT_MIX_1, 7, 1, 0),
487SOC_DAPM_SINGLE("Playback Switch", WM8955_RIGHT_OUT_MIX_2, 8, 1, 0),
488SOC_DAPM_SINGLE("Bypass Switch", WM8955_RIGHT_OUT_MIX_2, 7, 1, 0),
489};
490
491static const struct snd_kcontrol_new mmixer[] = {
492SOC_DAPM_SINGLE("Left Playback Switch", WM8955_MONO_OUT_MIX_1, 8, 1, 0),
493SOC_DAPM_SINGLE("Left Bypass Switch", WM8955_MONO_OUT_MIX_1, 7, 1, 0),
494SOC_DAPM_SINGLE("Right Playback Switch", WM8955_MONO_OUT_MIX_2, 8, 1, 0),
495SOC_DAPM_SINGLE("Right Bypass Switch", WM8955_MONO_OUT_MIX_2, 7, 1, 0),
496};
497
498static const struct snd_soc_dapm_widget wm8955_dapm_widgets[] = {
499SND_SOC_DAPM_INPUT("MONOIN-"),
500SND_SOC_DAPM_INPUT("MONOIN+"),
501SND_SOC_DAPM_INPUT("LINEINR"),
502SND_SOC_DAPM_INPUT("LINEINL"),
503
504SND_SOC_DAPM_PGA("Mono Input", SND_SOC_NOPM, 0, 0, NULL, 0),
505
506SND_SOC_DAPM_SUPPLY("SYSCLK", WM8955_POWER_MANAGEMENT_1, 0, 1, wm8955_sysclk,
507 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
508SND_SOC_DAPM_SUPPLY("TSDEN", WM8955_ADDITIONAL_CONTROL_1, 8, 0, NULL, 0),
509
510SND_SOC_DAPM_DAC("DACL", "Playback", WM8955_POWER_MANAGEMENT_2, 8, 0),
511SND_SOC_DAPM_DAC("DACR", "Playback", WM8955_POWER_MANAGEMENT_2, 7, 0),
512
513SND_SOC_DAPM_PGA("LOUT1 PGA", WM8955_POWER_MANAGEMENT_2, 6, 0, NULL, 0),
514SND_SOC_DAPM_PGA("ROUT1 PGA", WM8955_POWER_MANAGEMENT_2, 5, 0, NULL, 0),
515SND_SOC_DAPM_PGA("LOUT2 PGA", WM8955_POWER_MANAGEMENT_2, 4, 0, NULL, 0),
516SND_SOC_DAPM_PGA("ROUT2 PGA", WM8955_POWER_MANAGEMENT_2, 3, 0, NULL, 0),
517SND_SOC_DAPM_PGA("MOUT PGA", WM8955_POWER_MANAGEMENT_2, 2, 0, NULL, 0),
518SND_SOC_DAPM_PGA("OUT3 PGA", WM8955_POWER_MANAGEMENT_2, 1, 0, NULL, 0),
519
520/* The names are chosen to make the control names nice */
521SND_SOC_DAPM_MIXER("Left", SND_SOC_NOPM, 0, 0,
522 lmixer, ARRAY_SIZE(lmixer)),
523SND_SOC_DAPM_MIXER("Right", SND_SOC_NOPM, 0, 0,
524 rmixer, ARRAY_SIZE(rmixer)),
525SND_SOC_DAPM_MIXER("Mono", SND_SOC_NOPM, 0, 0,
526 mmixer, ARRAY_SIZE(mmixer)),
527
528SND_SOC_DAPM_OUTPUT("LOUT1"),
529SND_SOC_DAPM_OUTPUT("ROUT1"),
530SND_SOC_DAPM_OUTPUT("LOUT2"),
531SND_SOC_DAPM_OUTPUT("ROUT2"),
532SND_SOC_DAPM_OUTPUT("MONOOUT"),
533SND_SOC_DAPM_OUTPUT("OUT3"),
534};
535
536static const struct snd_soc_dapm_route wm8955_intercon[] = {
537 { "DACL", NULL, "SYSCLK" },
538 { "DACR", NULL, "SYSCLK" },
539
540 { "Mono Input", NULL, "MONOIN-" },
541 { "Mono Input", NULL, "MONOIN+" },
542
543 { "Left", "Playback Switch", "DACL" },
544 { "Left", "Right Playback Switch", "DACR" },
545 { "Left", "Bypass Switch", "LINEINL" },
546 { "Left", "Mono Switch", "Mono Input" },
547
548 { "Right", "Playback Switch", "DACR" },
549 { "Right", "Left Playback Switch", "DACL" },
550 { "Right", "Bypass Switch", "LINEINR" },
551 { "Right", "Mono Switch", "Mono Input" },
552
553 { "Mono", "Left Playback Switch", "DACL" },
554 { "Mono", "Right Playback Switch", "DACR" },
555 { "Mono", "Left Bypass Switch", "LINEINL" },
556 { "Mono", "Right Bypass Switch", "LINEINR" },
557
558 { "LOUT1 PGA", NULL, "Left" },
559 { "LOUT1", NULL, "TSDEN" },
560 { "LOUT1", NULL, "LOUT1 PGA" },
561
562 { "ROUT1 PGA", NULL, "Right" },
563 { "ROUT1", NULL, "TSDEN" },
564 { "ROUT1", NULL, "ROUT1 PGA" },
565
566 { "LOUT2 PGA", NULL, "Left" },
567 { "LOUT2", NULL, "TSDEN" },
568 { "LOUT2", NULL, "LOUT2 PGA" },
569
570 { "ROUT2 PGA", NULL, "Right" },
571 { "ROUT2", NULL, "TSDEN" },
572 { "ROUT2", NULL, "ROUT2 PGA" },
573
574 { "MOUT PGA", NULL, "Mono" },
575 { "MONOOUT", NULL, "MOUT PGA" },
576
577 /* OUT3 not currently implemented */
578 { "OUT3", NULL, "OUT3 PGA" },
579};
580
581static int wm8955_add_widgets(struct snd_soc_codec *codec)
582{
583 snd_soc_add_controls(codec, wm8955_snd_controls,
584 ARRAY_SIZE(wm8955_snd_controls));
585
586 snd_soc_dapm_new_controls(codec, wm8955_dapm_widgets,
587 ARRAY_SIZE(wm8955_dapm_widgets));
588
589 snd_soc_dapm_add_routes(codec, wm8955_intercon,
590 ARRAY_SIZE(wm8955_intercon));
591
592 return 0;
593}
594
595static int wm8955_hw_params(struct snd_pcm_substream *substream,
596 struct snd_pcm_hw_params *params,
597 struct snd_soc_dai *dai)
598{
599 struct snd_soc_codec *codec = dai->codec;
600 struct wm8955_priv *wm8955 = codec->private_data;
601 int ret;
602 int wl;
603
604 switch (params_format(params)) {
605 case SNDRV_PCM_FORMAT_S16_LE:
606 wl = 0;
607 break;
608 case SNDRV_PCM_FORMAT_S20_3LE:
609 wl = 0x4;
610 break;
611 case SNDRV_PCM_FORMAT_S24_LE:
612 wl = 0x8;
613 break;
614 case SNDRV_PCM_FORMAT_S32_LE:
615 wl = 0xc;
616 break;
617 default:
618 return -EINVAL;
619 }
620 snd_soc_update_bits(codec, WM8955_AUDIO_INTERFACE,
621 WM8955_WL_MASK, wl);
622
623 wm8955->fs = params_rate(params);
624 wm8955_set_deemph(codec);
625
626 /* If the chip is clocked then disable the clocks and force a
627 * reconfiguration, otherwise DAPM will power up the
628 * clocks for us later. */
629 ret = snd_soc_read(codec, WM8955_POWER_MANAGEMENT_1);
630 if (ret < 0)
631 return ret;
632 if (ret & WM8955_DIGENB) {
633 snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1,
634 WM8955_DIGENB, 0);
635 snd_soc_update_bits(codec, WM8955_CLOCKING_PLL,
636 WM8955_PLL_RB | WM8955_PLLEN, 0);
637
638 wm8955_configure_clocking(codec);
639 }
640
641 return 0;
642}
643
644
645static int wm8955_set_sysclk(struct snd_soc_dai *dai, int clk_id,
646 unsigned int freq, int dir)
647{
648 struct snd_soc_codec *codec = dai->codec;
649 struct wm8955_priv *priv = codec->private_data;
650 int div;
651
652 switch (clk_id) {
653 case WM8955_CLK_MCLK:
654 if (freq > 15000000) {
655 priv->mclk_rate = freq /= 2;
656 div = WM8955_MCLKDIV2;
657 } else {
658 priv->mclk_rate = freq;
659 div = 0;
660 }
661
662 snd_soc_update_bits(codec, WM8955_SAMPLE_RATE,
663 WM8955_MCLKDIV2, div);
664 break;
665
666 default:
667 return -EINVAL;
668 }
669
670 dev_dbg(dai->dev, "Clock source is %d at %uHz\n", clk_id, freq);
671
672 return 0;
673}
674
675static int wm8955_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
676{
677 struct snd_soc_codec *codec = dai->codec;
678 u16 aif = 0;
679
680 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
681 case SND_SOC_DAIFMT_CBS_CFS:
682 break;
683 case SND_SOC_DAIFMT_CBM_CFM:
684 aif |= WM8955_MS;
685 break;
686 default:
687 return -EINVAL;
688 }
689
690 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
691 case SND_SOC_DAIFMT_DSP_B:
692 aif |= WM8955_LRP;
693 case SND_SOC_DAIFMT_DSP_A:
694 aif |= 0x3;
695 break;
696 case SND_SOC_DAIFMT_I2S:
697 aif |= 0x2;
698 break;
699 case SND_SOC_DAIFMT_RIGHT_J:
700 break;
701 case SND_SOC_DAIFMT_LEFT_J:
702 aif |= 0x1;
703 break;
704 default:
705 return -EINVAL;
706 }
707
708 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
709 case SND_SOC_DAIFMT_DSP_A:
710 case SND_SOC_DAIFMT_DSP_B:
711 /* frame inversion not valid for DSP modes */
712 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
713 case SND_SOC_DAIFMT_NB_NF:
714 break;
715 case SND_SOC_DAIFMT_IB_NF:
716 aif |= WM8955_BCLKINV;
717 break;
718 default:
719 return -EINVAL;
720 }
721 break;
722
723 case SND_SOC_DAIFMT_I2S:
724 case SND_SOC_DAIFMT_RIGHT_J:
725 case SND_SOC_DAIFMT_LEFT_J:
726 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
727 case SND_SOC_DAIFMT_NB_NF:
728 break;
729 case SND_SOC_DAIFMT_IB_IF:
730 aif |= WM8955_BCLKINV | WM8955_LRP;
731 break;
732 case SND_SOC_DAIFMT_IB_NF:
733 aif |= WM8955_BCLKINV;
734 break;
735 case SND_SOC_DAIFMT_NB_IF:
736 aif |= WM8955_LRP;
737 break;
738 default:
739 return -EINVAL;
740 }
741 break;
742 default:
743 return -EINVAL;
744 }
745
746 snd_soc_update_bits(codec, WM8955_AUDIO_INTERFACE,
747 WM8955_MS | WM8955_FORMAT_MASK | WM8955_BCLKINV |
748 WM8955_LRP, aif);
749
750 return 0;
751}
752
753
754static int wm8955_digital_mute(struct snd_soc_dai *codec_dai, int mute)
755{
756 struct snd_soc_codec *codec = codec_dai->codec;
757 int val;
758
759 if (mute)
760 val = WM8955_DACMU;
761 else
762 val = 0;
763
764 snd_soc_update_bits(codec, WM8955_DAC_CONTROL, WM8955_DACMU, val);
765
766 return 0;
767}
768
769static int wm8955_set_bias_level(struct snd_soc_codec *codec,
770 enum snd_soc_bias_level level)
771{
772 struct wm8955_priv *wm8955 = codec->private_data;
773 int ret, i;
774
775 switch (level) {
776 case SND_SOC_BIAS_ON:
777 break;
778
779 case SND_SOC_BIAS_PREPARE:
780 /* VMID resistance 2*50k */
781 snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1,
782 WM8955_VMIDSEL_MASK,
783 0x1 << WM8955_VMIDSEL_SHIFT);
784
785 /* Default bias current */
786 snd_soc_update_bits(codec, WM8955_ADDITIONAL_CONTROL_1,
787 WM8955_VSEL_MASK,
788 0x2 << WM8955_VSEL_SHIFT);
789 break;
790
791 case SND_SOC_BIAS_STANDBY:
792 if (codec->bias_level == SND_SOC_BIAS_OFF) {
793 ret = regulator_bulk_enable(ARRAY_SIZE(wm8955->supplies),
794 wm8955->supplies);
795 if (ret != 0) {
796 dev_err(codec->dev,
797 "Failed to enable supplies: %d\n",
798 ret);
799 return ret;
800 }
801
802 /* Sync back cached values if they're
803 * different from the hardware default.
804 */
805 for (i = 0; i < ARRAY_SIZE(wm8955->reg_cache); i++) {
806 if (i == WM8955_RESET)
807 continue;
808
809 if (wm8955->reg_cache[i] == wm8955_reg[i])
810 continue;
811
812 snd_soc_write(codec, i, wm8955->reg_cache[i]);
813 }
814
815 /* Enable VREF and VMID */
816 snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1,
817 WM8955_VREF |
818 WM8955_VMIDSEL_MASK,
819 WM8955_VREF |
820 0x3 << WM8955_VREF_SHIFT);
821
822 /* Let VMID ramp */
823 msleep(500);
824
825 /* High resistance VROI to maintain outputs */
826 snd_soc_update_bits(codec,
827 WM8955_ADDITIONAL_CONTROL_3,
828 WM8955_VROI, WM8955_VROI);
829 }
830
831 /* Maintain VMID with 2*250k */
832 snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1,
833 WM8955_VMIDSEL_MASK,
834 0x2 << WM8955_VMIDSEL_SHIFT);
835
836 /* Minimum bias current */
837 snd_soc_update_bits(codec, WM8955_ADDITIONAL_CONTROL_1,
838 WM8955_VSEL_MASK, 0);
839 break;
840
841 case SND_SOC_BIAS_OFF:
842 /* Low resistance VROI to help discharge */
843 snd_soc_update_bits(codec,
844 WM8955_ADDITIONAL_CONTROL_3,
845 WM8955_VROI, 0);
846
847 /* Turn off VMID and VREF */
848 snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1,
849 WM8955_VREF |
850 WM8955_VMIDSEL_MASK, 0);
851
852 regulator_bulk_disable(ARRAY_SIZE(wm8955->supplies),
853 wm8955->supplies);
854 break;
855 }
856 codec->bias_level = level;
857 return 0;
858}
859
860#define WM8955_RATES SNDRV_PCM_RATE_8000_96000
861
862#define WM8955_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
863 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
864
865static struct snd_soc_dai_ops wm8955_dai_ops = {
866 .set_sysclk = wm8955_set_sysclk,
867 .set_fmt = wm8955_set_fmt,
868 .hw_params = wm8955_hw_params,
869 .digital_mute = wm8955_digital_mute,
870};
871
872struct snd_soc_dai wm8955_dai = {
873 .name = "WM8955",
874 .playback = {
875 .stream_name = "Playback",
876 .channels_min = 2,
877 .channels_max = 2,
878 .rates = WM8955_RATES,
879 .formats = WM8955_FORMATS,
880 },
881 .ops = &wm8955_dai_ops,
882};
883EXPORT_SYMBOL_GPL(wm8955_dai);
884
885#ifdef CONFIG_PM
886static int wm8955_suspend(struct platform_device *pdev, pm_message_t state)
887{
888 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
889 struct snd_soc_codec *codec = socdev->card->codec;
890
891 wm8955_set_bias_level(codec, SND_SOC_BIAS_OFF);
892
893 return 0;
894}
895
896static int wm8955_resume(struct platform_device *pdev)
897{
898 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
899 struct snd_soc_codec *codec = socdev->card->codec;
900
901 wm8955_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
902
903 return 0;
904}
905#else
906#define wm8955_suspend NULL
907#define wm8955_resume NULL
908#endif
909
910static int wm8955_probe(struct platform_device *pdev)
911{
912 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
913 struct snd_soc_codec *codec;
914 int ret = 0;
915
916 if (wm8955_codec == NULL) {
917 dev_err(&pdev->dev, "Codec device not registered\n");
918 return -ENODEV;
919 }
920
921 socdev->card->codec = wm8955_codec;
922 codec = wm8955_codec;
923
924 /* register pcms */
925 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
926 if (ret < 0) {
927 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
928 goto pcm_err;
929 }
930
931 wm8955_add_widgets(codec);
932
933 return ret;
934
935pcm_err:
936 return ret;
937}
938
939static int wm8955_remove(struct platform_device *pdev)
940{
941 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
942
943 snd_soc_free_pcms(socdev);
944 snd_soc_dapm_free(socdev);
945
946 return 0;
947}
948
949struct snd_soc_codec_device soc_codec_dev_wm8955 = {
950 .probe = wm8955_probe,
951 .remove = wm8955_remove,
952 .suspend = wm8955_suspend,
953 .resume = wm8955_resume,
954};
955EXPORT_SYMBOL_GPL(soc_codec_dev_wm8955);
956
957static int wm8955_register(struct wm8955_priv *wm8955,
958 enum snd_soc_control_type control)
959{
960 int ret;
961 struct snd_soc_codec *codec = &wm8955->codec;
962 int i;
963
964 if (wm8955_codec) {
965 dev_err(codec->dev, "Another WM8955 is registered\n");
966 return -EINVAL;
967 }
968
969 mutex_init(&codec->mutex);
970 INIT_LIST_HEAD(&codec->dapm_widgets);
971 INIT_LIST_HEAD(&codec->dapm_paths);
972
973 codec->private_data = wm8955;
974 codec->name = "WM8955";
975 codec->owner = THIS_MODULE;
976 codec->bias_level = SND_SOC_BIAS_OFF;
977 codec->set_bias_level = wm8955_set_bias_level;
978 codec->dai = &wm8955_dai;
979 codec->num_dai = 1;
980 codec->reg_cache_size = WM8955_MAX_REGISTER;
981 codec->reg_cache = &wm8955->reg_cache;
982
983 memcpy(codec->reg_cache, wm8955_reg, sizeof(wm8955_reg));
984
985 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
986 if (ret != 0) {
987 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
988 goto err;
989 }
990
991 for (i = 0; i < ARRAY_SIZE(wm8955->supplies); i++)
992 wm8955->supplies[i].supply = wm8955_supply_names[i];
993
994 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8955->supplies),
995 wm8955->supplies);
996 if (ret != 0) {
997 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
998 goto err;
999 }
1000
1001 ret = regulator_bulk_enable(ARRAY_SIZE(wm8955->supplies),
1002 wm8955->supplies);
1003 if (ret != 0) {
1004 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
1005 goto err_get;
1006 }
1007
1008 ret = wm8955_reset(codec);
1009 if (ret < 0) {
1010 dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
1011 goto err_enable;
1012 }
1013
1014 wm8955_dai.dev = codec->dev;
1015
1016 /* Change some default settings - latch VU and enable ZC */
1017 wm8955->reg_cache[WM8955_LEFT_DAC_VOLUME] |= WM8955_LDVU;
1018 wm8955->reg_cache[WM8955_RIGHT_DAC_VOLUME] |= WM8955_RDVU;
1019 wm8955->reg_cache[WM8955_LOUT1_VOLUME] |= WM8955_LO1VU | WM8955_LO1ZC;
1020 wm8955->reg_cache[WM8955_ROUT1_VOLUME] |= WM8955_RO1VU | WM8955_RO1ZC;
1021 wm8955->reg_cache[WM8955_LOUT2_VOLUME] |= WM8955_LO2VU | WM8955_LO2ZC;
1022 wm8955->reg_cache[WM8955_ROUT2_VOLUME] |= WM8955_RO2VU | WM8955_RO2ZC;
1023 wm8955->reg_cache[WM8955_MONOOUT_VOLUME] |= WM8955_MOZC;
1024
1025 /* Also enable adaptive bass boost by default */
1026 wm8955->reg_cache[WM8955_BASS_CONTROL] |= WM8955_BB;
1027
1028 /* Set platform data values */
1029 if (wm8955->pdata) {
1030 if (wm8955->pdata->out2_speaker)
1031 wm8955->reg_cache[WM8955_ADDITIONAL_CONTROL_2]
1032 |= WM8955_ROUT2INV;
1033
1034 if (wm8955->pdata->monoin_diff)
1035 wm8955->reg_cache[WM8955_MONO_OUT_MIX_1]
1036 |= WM8955_DMEN;
1037 }
1038
1039 wm8955_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1040
1041 /* Bias level configuration will have done an extra enable */
1042 regulator_bulk_disable(ARRAY_SIZE(wm8955->supplies), wm8955->supplies);
1043
1044 wm8955_codec = codec;
1045
1046 ret = snd_soc_register_codec(codec);
1047 if (ret != 0) {
1048 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
1049 return ret;
1050 }
1051
1052 ret = snd_soc_register_dai(&wm8955_dai);
1053 if (ret != 0) {
1054 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
1055 snd_soc_unregister_codec(codec);
1056 return ret;
1057 }
1058
1059 return 0;
1060
1061err_enable:
1062 regulator_bulk_disable(ARRAY_SIZE(wm8955->supplies), wm8955->supplies);
1063err_get:
1064 regulator_bulk_free(ARRAY_SIZE(wm8955->supplies), wm8955->supplies);
1065err:
1066 kfree(wm8955);
1067 return ret;
1068}
1069
1070static void wm8955_unregister(struct wm8955_priv *wm8955)
1071{
1072 wm8955_set_bias_level(&wm8955->codec, SND_SOC_BIAS_OFF);
1073 regulator_bulk_free(ARRAY_SIZE(wm8955->supplies), wm8955->supplies);
1074 snd_soc_unregister_dai(&wm8955_dai);
1075 snd_soc_unregister_codec(&wm8955->codec);
1076 kfree(wm8955);
1077 wm8955_codec = NULL;
1078}
1079
1080#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1081static __devinit int wm8955_i2c_probe(struct i2c_client *i2c,
1082 const struct i2c_device_id *id)
1083{
1084 struct wm8955_priv *wm8955;
1085 struct snd_soc_codec *codec;
1086
1087 wm8955 = kzalloc(sizeof(struct wm8955_priv), GFP_KERNEL);
1088 if (wm8955 == NULL)
1089 return -ENOMEM;
1090
1091 codec = &wm8955->codec;
1092 codec->hw_write = (hw_write_t)i2c_master_send;
1093
1094 i2c_set_clientdata(i2c, wm8955);
1095 codec->control_data = i2c;
1096 wm8955->pdata = i2c->dev.platform_data;
1097
1098 codec->dev = &i2c->dev;
1099
1100 return wm8955_register(wm8955, SND_SOC_I2C);
1101}
1102
1103static __devexit int wm8955_i2c_remove(struct i2c_client *client)
1104{
1105 struct wm8955_priv *wm8955 = i2c_get_clientdata(client);
1106 wm8955_unregister(wm8955);
1107 return 0;
1108}
1109
1110static const struct i2c_device_id wm8955_i2c_id[] = {
1111 { "wm8955", 0 },
1112 { }
1113};
1114MODULE_DEVICE_TABLE(i2c, wm8955_i2c_id);
1115
1116static struct i2c_driver wm8955_i2c_driver = {
1117 .driver = {
1118 .name = "wm8955",
1119 .owner = THIS_MODULE,
1120 },
1121 .probe = wm8955_i2c_probe,
1122 .remove = __devexit_p(wm8955_i2c_remove),
1123 .id_table = wm8955_i2c_id,
1124};
1125#endif
1126
1127static int __init wm8955_modinit(void)
1128{
1129 int ret;
1130#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1131 ret = i2c_add_driver(&wm8955_i2c_driver);
1132 if (ret != 0) {
1133 printk(KERN_ERR "Failed to register WM8955 I2C driver: %d\n",
1134 ret);
1135 }
1136#endif
1137 return 0;
1138}
1139module_init(wm8955_modinit);
1140
1141static void __exit wm8955_exit(void)
1142{
1143#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1144 i2c_del_driver(&wm8955_i2c_driver);
1145#endif
1146}
1147module_exit(wm8955_exit);
1148
1149MODULE_DESCRIPTION("ASoC WM8955 driver");
1150MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
1151MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8955.h b/sound/soc/codecs/wm8955.h
new file mode 100644
index 000000000000..ae349c8531f6
--- /dev/null
+++ b/sound/soc/codecs/wm8955.h
@@ -0,0 +1,489 @@
1/*
2 * wm8955.h -- WM8904 ASoC driver
3 *
4 * Copyright 2009 Wolfson Microelectronics, plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef _WM8955_H
14#define _WM8955_H
15
16#define WM8955_CLK_MCLK 1
17
18extern struct snd_soc_dai wm8955_dai;
19extern struct snd_soc_codec_device soc_codec_dev_wm8955;
20
21/*
22 * Register values.
23 */
24#define WM8955_LOUT1_VOLUME 0x02
25#define WM8955_ROUT1_VOLUME 0x03
26#define WM8955_DAC_CONTROL 0x05
27#define WM8955_AUDIO_INTERFACE 0x07
28#define WM8955_SAMPLE_RATE 0x08
29#define WM8955_LEFT_DAC_VOLUME 0x0A
30#define WM8955_RIGHT_DAC_VOLUME 0x0B
31#define WM8955_BASS_CONTROL 0x0C
32#define WM8955_TREBLE_CONTROL 0x0D
33#define WM8955_RESET 0x0F
34#define WM8955_ADDITIONAL_CONTROL_1 0x17
35#define WM8955_ADDITIONAL_CONTROL_2 0x18
36#define WM8955_POWER_MANAGEMENT_1 0x19
37#define WM8955_POWER_MANAGEMENT_2 0x1A
38#define WM8955_ADDITIONAL_CONTROL_3 0x1B
39#define WM8955_LEFT_OUT_MIX_1 0x22
40#define WM8955_LEFT_OUT_MIX_2 0x23
41#define WM8955_RIGHT_OUT_MIX_1 0x24
42#define WM8955_RIGHT_OUT_MIX_2 0x25
43#define WM8955_MONO_OUT_MIX_1 0x26
44#define WM8955_MONO_OUT_MIX_2 0x27
45#define WM8955_LOUT2_VOLUME 0x28
46#define WM8955_ROUT2_VOLUME 0x29
47#define WM8955_MONOOUT_VOLUME 0x2A
48#define WM8955_CLOCKING_PLL 0x2B
49#define WM8955_PLL_CONTROL_1 0x2C
50#define WM8955_PLL_CONTROL_2 0x2D
51#define WM8955_PLL_CONTROL_3 0x2E
52#define WM8955_PLL_CONTROL_4 0x3B
53
54#define WM8955_REGISTER_COUNT 29
55#define WM8955_MAX_REGISTER 0x3B
56
57/*
58 * Field Definitions.
59 */
60
61/*
62 * R2 (0x02) - LOUT1 volume
63 */
64#define WM8955_LO1VU 0x0100 /* LO1VU */
65#define WM8955_LO1VU_MASK 0x0100 /* LO1VU */
66#define WM8955_LO1VU_SHIFT 8 /* LO1VU */
67#define WM8955_LO1VU_WIDTH 1 /* LO1VU */
68#define WM8955_LO1ZC 0x0080 /* LO1ZC */
69#define WM8955_LO1ZC_MASK 0x0080 /* LO1ZC */
70#define WM8955_LO1ZC_SHIFT 7 /* LO1ZC */
71#define WM8955_LO1ZC_WIDTH 1 /* LO1ZC */
72#define WM8955_LOUTVOL_MASK 0x007F /* LOUTVOL - [6:0] */
73#define WM8955_LOUTVOL_SHIFT 0 /* LOUTVOL - [6:0] */
74#define WM8955_LOUTVOL_WIDTH 7 /* LOUTVOL - [6:0] */
75
76/*
77 * R3 (0x03) - ROUT1 volume
78 */
79#define WM8955_RO1VU 0x0100 /* RO1VU */
80#define WM8955_RO1VU_MASK 0x0100 /* RO1VU */
81#define WM8955_RO1VU_SHIFT 8 /* RO1VU */
82#define WM8955_RO1VU_WIDTH 1 /* RO1VU */
83#define WM8955_RO1ZC 0x0080 /* RO1ZC */
84#define WM8955_RO1ZC_MASK 0x0080 /* RO1ZC */
85#define WM8955_RO1ZC_SHIFT 7 /* RO1ZC */
86#define WM8955_RO1ZC_WIDTH 1 /* RO1ZC */
87#define WM8955_ROUTVOL_MASK 0x007F /* ROUTVOL - [6:0] */
88#define WM8955_ROUTVOL_SHIFT 0 /* ROUTVOL - [6:0] */
89#define WM8955_ROUTVOL_WIDTH 7 /* ROUTVOL - [6:0] */
90
91/*
92 * R5 (0x05) - DAC Control
93 */
94#define WM8955_DAT 0x0080 /* DAT */
95#define WM8955_DAT_MASK 0x0080 /* DAT */
96#define WM8955_DAT_SHIFT 7 /* DAT */
97#define WM8955_DAT_WIDTH 1 /* DAT */
98#define WM8955_DACMU 0x0008 /* DACMU */
99#define WM8955_DACMU_MASK 0x0008 /* DACMU */
100#define WM8955_DACMU_SHIFT 3 /* DACMU */
101#define WM8955_DACMU_WIDTH 1 /* DACMU */
102#define WM8955_DEEMPH_MASK 0x0006 /* DEEMPH - [2:1] */
103#define WM8955_DEEMPH_SHIFT 1 /* DEEMPH - [2:1] */
104#define WM8955_DEEMPH_WIDTH 2 /* DEEMPH - [2:1] */
105
106/*
107 * R7 (0x07) - Audio Interface
108 */
109#define WM8955_BCLKINV 0x0080 /* BCLKINV */
110#define WM8955_BCLKINV_MASK 0x0080 /* BCLKINV */
111#define WM8955_BCLKINV_SHIFT 7 /* BCLKINV */
112#define WM8955_BCLKINV_WIDTH 1 /* BCLKINV */
113#define WM8955_MS 0x0040 /* MS */
114#define WM8955_MS_MASK 0x0040 /* MS */
115#define WM8955_MS_SHIFT 6 /* MS */
116#define WM8955_MS_WIDTH 1 /* MS */
117#define WM8955_LRSWAP 0x0020 /* LRSWAP */
118#define WM8955_LRSWAP_MASK 0x0020 /* LRSWAP */
119#define WM8955_LRSWAP_SHIFT 5 /* LRSWAP */
120#define WM8955_LRSWAP_WIDTH 1 /* LRSWAP */
121#define WM8955_LRP 0x0010 /* LRP */
122#define WM8955_LRP_MASK 0x0010 /* LRP */
123#define WM8955_LRP_SHIFT 4 /* LRP */
124#define WM8955_LRP_WIDTH 1 /* LRP */
125#define WM8955_WL_MASK 0x000C /* WL - [3:2] */
126#define WM8955_WL_SHIFT 2 /* WL - [3:2] */
127#define WM8955_WL_WIDTH 2 /* WL - [3:2] */
128#define WM8955_FORMAT_MASK 0x0003 /* FORMAT - [1:0] */
129#define WM8955_FORMAT_SHIFT 0 /* FORMAT - [1:0] */
130#define WM8955_FORMAT_WIDTH 2 /* FORMAT - [1:0] */
131
132/*
133 * R8 (0x08) - Sample Rate
134 */
135#define WM8955_BCLKDIV2 0x0080 /* BCLKDIV2 */
136#define WM8955_BCLKDIV2_MASK 0x0080 /* BCLKDIV2 */
137#define WM8955_BCLKDIV2_SHIFT 7 /* BCLKDIV2 */
138#define WM8955_BCLKDIV2_WIDTH 1 /* BCLKDIV2 */
139#define WM8955_MCLKDIV2 0x0040 /* MCLKDIV2 */
140#define WM8955_MCLKDIV2_MASK 0x0040 /* MCLKDIV2 */
141#define WM8955_MCLKDIV2_SHIFT 6 /* MCLKDIV2 */
142#define WM8955_MCLKDIV2_WIDTH 1 /* MCLKDIV2 */
143#define WM8955_SR_MASK 0x003E /* SR - [5:1] */
144#define WM8955_SR_SHIFT 1 /* SR - [5:1] */
145#define WM8955_SR_WIDTH 5 /* SR - [5:1] */
146#define WM8955_USB 0x0001 /* USB */
147#define WM8955_USB_MASK 0x0001 /* USB */
148#define WM8955_USB_SHIFT 0 /* USB */
149#define WM8955_USB_WIDTH 1 /* USB */
150
151/*
152 * R10 (0x0A) - Left DAC volume
153 */
154#define WM8955_LDVU 0x0100 /* LDVU */
155#define WM8955_LDVU_MASK 0x0100 /* LDVU */
156#define WM8955_LDVU_SHIFT 8 /* LDVU */
157#define WM8955_LDVU_WIDTH 1 /* LDVU */
158#define WM8955_LDACVOL_MASK 0x00FF /* LDACVOL - [7:0] */
159#define WM8955_LDACVOL_SHIFT 0 /* LDACVOL - [7:0] */
160#define WM8955_LDACVOL_WIDTH 8 /* LDACVOL - [7:0] */
161
162/*
163 * R11 (0x0B) - Right DAC volume
164 */
165#define WM8955_RDVU 0x0100 /* RDVU */
166#define WM8955_RDVU_MASK 0x0100 /* RDVU */
167#define WM8955_RDVU_SHIFT 8 /* RDVU */
168#define WM8955_RDVU_WIDTH 1 /* RDVU */
169#define WM8955_RDACVOL_MASK 0x00FF /* RDACVOL - [7:0] */
170#define WM8955_RDACVOL_SHIFT 0 /* RDACVOL - [7:0] */
171#define WM8955_RDACVOL_WIDTH 8 /* RDACVOL - [7:0] */
172
173/*
174 * R12 (0x0C) - Bass control
175 */
176#define WM8955_BB 0x0080 /* BB */
177#define WM8955_BB_MASK 0x0080 /* BB */
178#define WM8955_BB_SHIFT 7 /* BB */
179#define WM8955_BB_WIDTH 1 /* BB */
180#define WM8955_BC 0x0040 /* BC */
181#define WM8955_BC_MASK 0x0040 /* BC */
182#define WM8955_BC_SHIFT 6 /* BC */
183#define WM8955_BC_WIDTH 1 /* BC */
184#define WM8955_BASS_MASK 0x000F /* BASS - [3:0] */
185#define WM8955_BASS_SHIFT 0 /* BASS - [3:0] */
186#define WM8955_BASS_WIDTH 4 /* BASS - [3:0] */
187
188/*
189 * R13 (0x0D) - Treble control
190 */
191#define WM8955_TC 0x0040 /* TC */
192#define WM8955_TC_MASK 0x0040 /* TC */
193#define WM8955_TC_SHIFT 6 /* TC */
194#define WM8955_TC_WIDTH 1 /* TC */
195#define WM8955_TRBL_MASK 0x000F /* TRBL - [3:0] */
196#define WM8955_TRBL_SHIFT 0 /* TRBL - [3:0] */
197#define WM8955_TRBL_WIDTH 4 /* TRBL - [3:0] */
198
199/*
200 * R15 (0x0F) - Reset
201 */
202#define WM8955_RESET_MASK 0x01FF /* RESET - [8:0] */
203#define WM8955_RESET_SHIFT 0 /* RESET - [8:0] */
204#define WM8955_RESET_WIDTH 9 /* RESET - [8:0] */
205
206/*
207 * R23 (0x17) - Additional control (1)
208 */
209#define WM8955_TSDEN 0x0100 /* TSDEN */
210#define WM8955_TSDEN_MASK 0x0100 /* TSDEN */
211#define WM8955_TSDEN_SHIFT 8 /* TSDEN */
212#define WM8955_TSDEN_WIDTH 1 /* TSDEN */
213#define WM8955_VSEL_MASK 0x00C0 /* VSEL - [7:6] */
214#define WM8955_VSEL_SHIFT 6 /* VSEL - [7:6] */
215#define WM8955_VSEL_WIDTH 2 /* VSEL - [7:6] */
216#define WM8955_DMONOMIX_MASK 0x0030 /* DMONOMIX - [5:4] */
217#define WM8955_DMONOMIX_SHIFT 4 /* DMONOMIX - [5:4] */
218#define WM8955_DMONOMIX_WIDTH 2 /* DMONOMIX - [5:4] */
219#define WM8955_DACINV 0x0002 /* DACINV */
220#define WM8955_DACINV_MASK 0x0002 /* DACINV */
221#define WM8955_DACINV_SHIFT 1 /* DACINV */
222#define WM8955_DACINV_WIDTH 1 /* DACINV */
223#define WM8955_TOEN 0x0001 /* TOEN */
224#define WM8955_TOEN_MASK 0x0001 /* TOEN */
225#define WM8955_TOEN_SHIFT 0 /* TOEN */
226#define WM8955_TOEN_WIDTH 1 /* TOEN */
227
228/*
229 * R24 (0x18) - Additional control (2)
230 */
231#define WM8955_OUT3SW_MASK 0x0180 /* OUT3SW - [8:7] */
232#define WM8955_OUT3SW_SHIFT 7 /* OUT3SW - [8:7] */
233#define WM8955_OUT3SW_WIDTH 2 /* OUT3SW - [8:7] */
234#define WM8955_ROUT2INV 0x0010 /* ROUT2INV */
235#define WM8955_ROUT2INV_MASK 0x0010 /* ROUT2INV */
236#define WM8955_ROUT2INV_SHIFT 4 /* ROUT2INV */
237#define WM8955_ROUT2INV_WIDTH 1 /* ROUT2INV */
238#define WM8955_DACOSR 0x0001 /* DACOSR */
239#define WM8955_DACOSR_MASK 0x0001 /* DACOSR */
240#define WM8955_DACOSR_SHIFT 0 /* DACOSR */
241#define WM8955_DACOSR_WIDTH 1 /* DACOSR */
242
243/*
244 * R25 (0x19) - Power Management (1)
245 */
246#define WM8955_VMIDSEL_MASK 0x0180 /* VMIDSEL - [8:7] */
247#define WM8955_VMIDSEL_SHIFT 7 /* VMIDSEL - [8:7] */
248#define WM8955_VMIDSEL_WIDTH 2 /* VMIDSEL - [8:7] */
249#define WM8955_VREF 0x0040 /* VREF */
250#define WM8955_VREF_MASK 0x0040 /* VREF */
251#define WM8955_VREF_SHIFT 6 /* VREF */
252#define WM8955_VREF_WIDTH 1 /* VREF */
253#define WM8955_DIGENB 0x0001 /* DIGENB */
254#define WM8955_DIGENB_MASK 0x0001 /* DIGENB */
255#define WM8955_DIGENB_SHIFT 0 /* DIGENB */
256#define WM8955_DIGENB_WIDTH 1 /* DIGENB */
257
258/*
259 * R26 (0x1A) - Power Management (2)
260 */
261#define WM8955_DACL 0x0100 /* DACL */
262#define WM8955_DACL_MASK 0x0100 /* DACL */
263#define WM8955_DACL_SHIFT 8 /* DACL */
264#define WM8955_DACL_WIDTH 1 /* DACL */
265#define WM8955_DACR 0x0080 /* DACR */
266#define WM8955_DACR_MASK 0x0080 /* DACR */
267#define WM8955_DACR_SHIFT 7 /* DACR */
268#define WM8955_DACR_WIDTH 1 /* DACR */
269#define WM8955_LOUT1 0x0040 /* LOUT1 */
270#define WM8955_LOUT1_MASK 0x0040 /* LOUT1 */
271#define WM8955_LOUT1_SHIFT 6 /* LOUT1 */
272#define WM8955_LOUT1_WIDTH 1 /* LOUT1 */
273#define WM8955_ROUT1 0x0020 /* ROUT1 */
274#define WM8955_ROUT1_MASK 0x0020 /* ROUT1 */
275#define WM8955_ROUT1_SHIFT 5 /* ROUT1 */
276#define WM8955_ROUT1_WIDTH 1 /* ROUT1 */
277#define WM8955_LOUT2 0x0010 /* LOUT2 */
278#define WM8955_LOUT2_MASK 0x0010 /* LOUT2 */
279#define WM8955_LOUT2_SHIFT 4 /* LOUT2 */
280#define WM8955_LOUT2_WIDTH 1 /* LOUT2 */
281#define WM8955_ROUT2 0x0008 /* ROUT2 */
282#define WM8955_ROUT2_MASK 0x0008 /* ROUT2 */
283#define WM8955_ROUT2_SHIFT 3 /* ROUT2 */
284#define WM8955_ROUT2_WIDTH 1 /* ROUT2 */
285#define WM8955_MONO 0x0004 /* MONO */
286#define WM8955_MONO_MASK 0x0004 /* MONO */
287#define WM8955_MONO_SHIFT 2 /* MONO */
288#define WM8955_MONO_WIDTH 1 /* MONO */
289#define WM8955_OUT3 0x0002 /* OUT3 */
290#define WM8955_OUT3_MASK 0x0002 /* OUT3 */
291#define WM8955_OUT3_SHIFT 1 /* OUT3 */
292#define WM8955_OUT3_WIDTH 1 /* OUT3 */
293
294/*
295 * R27 (0x1B) - Additional Control (3)
296 */
297#define WM8955_VROI 0x0040 /* VROI */
298#define WM8955_VROI_MASK 0x0040 /* VROI */
299#define WM8955_VROI_SHIFT 6 /* VROI */
300#define WM8955_VROI_WIDTH 1 /* VROI */
301
302/*
303 * R34 (0x22) - Left out Mix (1)
304 */
305#define WM8955_LD2LO 0x0100 /* LD2LO */
306#define WM8955_LD2LO_MASK 0x0100 /* LD2LO */
307#define WM8955_LD2LO_SHIFT 8 /* LD2LO */
308#define WM8955_LD2LO_WIDTH 1 /* LD2LO */
309#define WM8955_LI2LO 0x0080 /* LI2LO */
310#define WM8955_LI2LO_MASK 0x0080 /* LI2LO */
311#define WM8955_LI2LO_SHIFT 7 /* LI2LO */
312#define WM8955_LI2LO_WIDTH 1 /* LI2LO */
313#define WM8955_LI2LOVOL_MASK 0x0070 /* LI2LOVOL - [6:4] */
314#define WM8955_LI2LOVOL_SHIFT 4 /* LI2LOVOL - [6:4] */
315#define WM8955_LI2LOVOL_WIDTH 3 /* LI2LOVOL - [6:4] */
316
317/*
318 * R35 (0x23) - Left out Mix (2)
319 */
320#define WM8955_RD2LO 0x0100 /* RD2LO */
321#define WM8955_RD2LO_MASK 0x0100 /* RD2LO */
322#define WM8955_RD2LO_SHIFT 8 /* RD2LO */
323#define WM8955_RD2LO_WIDTH 1 /* RD2LO */
324#define WM8955_RI2LO 0x0080 /* RI2LO */
325#define WM8955_RI2LO_MASK 0x0080 /* RI2LO */
326#define WM8955_RI2LO_SHIFT 7 /* RI2LO */
327#define WM8955_RI2LO_WIDTH 1 /* RI2LO */
328#define WM8955_RI2LOVOL_MASK 0x0070 /* RI2LOVOL - [6:4] */
329#define WM8955_RI2LOVOL_SHIFT 4 /* RI2LOVOL - [6:4] */
330#define WM8955_RI2LOVOL_WIDTH 3 /* RI2LOVOL - [6:4] */
331
332/*
333 * R36 (0x24) - Right out Mix (1)
334 */
335#define WM8955_LD2RO 0x0100 /* LD2RO */
336#define WM8955_LD2RO_MASK 0x0100 /* LD2RO */
337#define WM8955_LD2RO_SHIFT 8 /* LD2RO */
338#define WM8955_LD2RO_WIDTH 1 /* LD2RO */
339#define WM8955_LI2RO 0x0080 /* LI2RO */
340#define WM8955_LI2RO_MASK 0x0080 /* LI2RO */
341#define WM8955_LI2RO_SHIFT 7 /* LI2RO */
342#define WM8955_LI2RO_WIDTH 1 /* LI2RO */
343#define WM8955_LI2ROVOL_MASK 0x0070 /* LI2ROVOL - [6:4] */
344#define WM8955_LI2ROVOL_SHIFT 4 /* LI2ROVOL - [6:4] */
345#define WM8955_LI2ROVOL_WIDTH 3 /* LI2ROVOL - [6:4] */
346
347/*
348 * R37 (0x25) - Right Out Mix (2)
349 */
350#define WM8955_RD2RO 0x0100 /* RD2RO */
351#define WM8955_RD2RO_MASK 0x0100 /* RD2RO */
352#define WM8955_RD2RO_SHIFT 8 /* RD2RO */
353#define WM8955_RD2RO_WIDTH 1 /* RD2RO */
354#define WM8955_RI2RO 0x0080 /* RI2RO */
355#define WM8955_RI2RO_MASK 0x0080 /* RI2RO */
356#define WM8955_RI2RO_SHIFT 7 /* RI2RO */
357#define WM8955_RI2RO_WIDTH 1 /* RI2RO */
358#define WM8955_RI2ROVOL_MASK 0x0070 /* RI2ROVOL - [6:4] */
359#define WM8955_RI2ROVOL_SHIFT 4 /* RI2ROVOL - [6:4] */
360#define WM8955_RI2ROVOL_WIDTH 3 /* RI2ROVOL - [6:4] */
361
362/*
363 * R38 (0x26) - Mono out Mix (1)
364 */
365#define WM8955_LD2MO 0x0100 /* LD2MO */
366#define WM8955_LD2MO_MASK 0x0100 /* LD2MO */
367#define WM8955_LD2MO_SHIFT 8 /* LD2MO */
368#define WM8955_LD2MO_WIDTH 1 /* LD2MO */
369#define WM8955_LI2MO 0x0080 /* LI2MO */
370#define WM8955_LI2MO_MASK 0x0080 /* LI2MO */
371#define WM8955_LI2MO_SHIFT 7 /* LI2MO */
372#define WM8955_LI2MO_WIDTH 1 /* LI2MO */
373#define WM8955_LI2MOVOL_MASK 0x0070 /* LI2MOVOL - [6:4] */
374#define WM8955_LI2MOVOL_SHIFT 4 /* LI2MOVOL - [6:4] */
375#define WM8955_LI2MOVOL_WIDTH 3 /* LI2MOVOL - [6:4] */
376#define WM8955_DMEN 0x0001 /* DMEN */
377#define WM8955_DMEN_MASK 0x0001 /* DMEN */
378#define WM8955_DMEN_SHIFT 0 /* DMEN */
379#define WM8955_DMEN_WIDTH 1 /* DMEN */
380
381/*
382 * R39 (0x27) - Mono out Mix (2)
383 */
384#define WM8955_RD2MO 0x0100 /* RD2MO */
385#define WM8955_RD2MO_MASK 0x0100 /* RD2MO */
386#define WM8955_RD2MO_SHIFT 8 /* RD2MO */
387#define WM8955_RD2MO_WIDTH 1 /* RD2MO */
388#define WM8955_RI2MO 0x0080 /* RI2MO */
389#define WM8955_RI2MO_MASK 0x0080 /* RI2MO */
390#define WM8955_RI2MO_SHIFT 7 /* RI2MO */
391#define WM8955_RI2MO_WIDTH 1 /* RI2MO */
392#define WM8955_RI2MOVOL_MASK 0x0070 /* RI2MOVOL - [6:4] */
393#define WM8955_RI2MOVOL_SHIFT 4 /* RI2MOVOL - [6:4] */
394#define WM8955_RI2MOVOL_WIDTH 3 /* RI2MOVOL - [6:4] */
395
396/*
397 * R40 (0x28) - LOUT2 volume
398 */
399#define WM8955_LO2VU 0x0100 /* LO2VU */
400#define WM8955_LO2VU_MASK 0x0100 /* LO2VU */
401#define WM8955_LO2VU_SHIFT 8 /* LO2VU */
402#define WM8955_LO2VU_WIDTH 1 /* LO2VU */
403#define WM8955_LO2ZC 0x0080 /* LO2ZC */
404#define WM8955_LO2ZC_MASK 0x0080 /* LO2ZC */
405#define WM8955_LO2ZC_SHIFT 7 /* LO2ZC */
406#define WM8955_LO2ZC_WIDTH 1 /* LO2ZC */
407#define WM8955_LOUT2VOL_MASK 0x007F /* LOUT2VOL - [6:0] */
408#define WM8955_LOUT2VOL_SHIFT 0 /* LOUT2VOL - [6:0] */
409#define WM8955_LOUT2VOL_WIDTH 7 /* LOUT2VOL - [6:0] */
410
411/*
412 * R41 (0x29) - ROUT2 volume
413 */
414#define WM8955_RO2VU 0x0100 /* RO2VU */
415#define WM8955_RO2VU_MASK 0x0100 /* RO2VU */
416#define WM8955_RO2VU_SHIFT 8 /* RO2VU */
417#define WM8955_RO2VU_WIDTH 1 /* RO2VU */
418#define WM8955_RO2ZC 0x0080 /* RO2ZC */
419#define WM8955_RO2ZC_MASK 0x0080 /* RO2ZC */
420#define WM8955_RO2ZC_SHIFT 7 /* RO2ZC */
421#define WM8955_RO2ZC_WIDTH 1 /* RO2ZC */
422#define WM8955_ROUT2VOL_MASK 0x007F /* ROUT2VOL - [6:0] */
423#define WM8955_ROUT2VOL_SHIFT 0 /* ROUT2VOL - [6:0] */
424#define WM8955_ROUT2VOL_WIDTH 7 /* ROUT2VOL - [6:0] */
425
426/*
427 * R42 (0x2A) - MONOOUT volume
428 */
429#define WM8955_MOZC 0x0080 /* MOZC */
430#define WM8955_MOZC_MASK 0x0080 /* MOZC */
431#define WM8955_MOZC_SHIFT 7 /* MOZC */
432#define WM8955_MOZC_WIDTH 1 /* MOZC */
433#define WM8955_MOUTVOL_MASK 0x007F /* MOUTVOL - [6:0] */
434#define WM8955_MOUTVOL_SHIFT 0 /* MOUTVOL - [6:0] */
435#define WM8955_MOUTVOL_WIDTH 7 /* MOUTVOL - [6:0] */
436
437/*
438 * R43 (0x2B) - Clocking / PLL
439 */
440#define WM8955_MCLKSEL 0x0100 /* MCLKSEL */
441#define WM8955_MCLKSEL_MASK 0x0100 /* MCLKSEL */
442#define WM8955_MCLKSEL_SHIFT 8 /* MCLKSEL */
443#define WM8955_MCLKSEL_WIDTH 1 /* MCLKSEL */
444#define WM8955_PLLOUTDIV2 0x0020 /* PLLOUTDIV2 */
445#define WM8955_PLLOUTDIV2_MASK 0x0020 /* PLLOUTDIV2 */
446#define WM8955_PLLOUTDIV2_SHIFT 5 /* PLLOUTDIV2 */
447#define WM8955_PLLOUTDIV2_WIDTH 1 /* PLLOUTDIV2 */
448#define WM8955_PLL_RB 0x0010 /* PLL_RB */
449#define WM8955_PLL_RB_MASK 0x0010 /* PLL_RB */
450#define WM8955_PLL_RB_SHIFT 4 /* PLL_RB */
451#define WM8955_PLL_RB_WIDTH 1 /* PLL_RB */
452#define WM8955_PLLEN 0x0008 /* PLLEN */
453#define WM8955_PLLEN_MASK 0x0008 /* PLLEN */
454#define WM8955_PLLEN_SHIFT 3 /* PLLEN */
455#define WM8955_PLLEN_WIDTH 1 /* PLLEN */
456
457/*
458 * R44 (0x2C) - PLL Control 1
459 */
460#define WM8955_N_MASK 0x01E0 /* N - [8:5] */
461#define WM8955_N_SHIFT 5 /* N - [8:5] */
462#define WM8955_N_WIDTH 4 /* N - [8:5] */
463#define WM8955_K_21_18_MASK 0x000F /* K(21:18) - [3:0] */
464#define WM8955_K_21_18_SHIFT 0 /* K(21:18) - [3:0] */
465#define WM8955_K_21_18_WIDTH 4 /* K(21:18) - [3:0] */
466
467/*
468 * R45 (0x2D) - PLL Control 2
469 */
470#define WM8955_K_17_9_MASK 0x01FF /* K(17:9) - [8:0] */
471#define WM8955_K_17_9_SHIFT 0 /* K(17:9) - [8:0] */
472#define WM8955_K_17_9_WIDTH 9 /* K(17:9) - [8:0] */
473
474/*
475 * R46 (0x2E) - PLL Control 3
476 */
477#define WM8955_K_8_0_MASK 0x01FF /* K(8:0) - [8:0] */
478#define WM8955_K_8_0_SHIFT 0 /* K(8:0) - [8:0] */
479#define WM8955_K_8_0_WIDTH 9 /* K(8:0) - [8:0] */
480
481/*
482 * R59 (0x3B) - PLL Control 4
483 */
484#define WM8955_KEN 0x0080 /* KEN */
485#define WM8955_KEN_MASK 0x0080 /* KEN */
486#define WM8955_KEN_SHIFT 7 /* KEN */
487#define WM8955_KEN_WIDTH 1 /* KEN */
488
489#endif
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c
index a8007d58813f..d2342c5e0425 100644
--- a/sound/soc/codecs/wm8961.c
+++ b/sound/soc/codecs/wm8961.c
@@ -1022,6 +1022,9 @@ static int wm8961_resume(struct platform_device *pdev)
1022 int i; 1022 int i;
1023 1023
1024 for (i = 0; i < codec->reg_cache_size; i++) { 1024 for (i = 0; i < codec->reg_cache_size; i++) {
1025 if (reg_cache[i] == wm8961_reg_defaults[i])
1026 continue;
1027
1025 if (i == WM8961_SOFTWARE_RESET) 1028 if (i == WM8961_SOFTWARE_RESET)
1026 continue; 1029 continue;
1027 1030
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c
index 8812751da8c9..ee637af4737a 100644
--- a/sound/soc/codecs/wm8974.c
+++ b/sound/soc/codecs/wm8974.c
@@ -170,6 +170,10 @@ SOC_ENUM("Aux Mode", wm8974_auxmode),
170 170
171SOC_SINGLE("Capture Boost(+20dB)", WM8974_ADCBOOST, 8, 1, 0), 171SOC_SINGLE("Capture Boost(+20dB)", WM8974_ADCBOOST, 8, 1, 0),
172SOC_SINGLE("Mono Playback Switch", WM8974_MONOMIX, 6, 1, 1), 172SOC_SINGLE("Mono Playback Switch", WM8974_MONOMIX, 6, 1, 1),
173
174/* DAC / ADC oversampling */
175SOC_SINGLE("DAC 128x Oversampling Switch", WM8974_DAC, 8, 1, 0),
176SOC_SINGLE("ADC 128x Oversampling Switch", WM8974_ADC, 8, 1, 0),
173}; 177};
174 178
175/* Speaker Output Mixer */ 179/* Speaker Output Mixer */
@@ -381,14 +385,6 @@ static int wm8974_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
381 reg = snd_soc_read(codec, WM8974_CLOCK) & 0x11f; 385 reg = snd_soc_read(codec, WM8974_CLOCK) & 0x11f;
382 snd_soc_write(codec, WM8974_CLOCK, reg | div); 386 snd_soc_write(codec, WM8974_CLOCK, reg | div);
383 break; 387 break;
384 case WM8974_ADCCLK:
385 reg = snd_soc_read(codec, WM8974_ADC) & 0x1f7;
386 snd_soc_write(codec, WM8974_ADC, reg | div);
387 break;
388 case WM8974_DACCLK:
389 reg = snd_soc_read(codec, WM8974_DAC) & 0x1f7;
390 snd_soc_write(codec, WM8974_DAC, reg | div);
391 break;
392 case WM8974_BCLKDIV: 388 case WM8974_BCLKDIV:
393 reg = snd_soc_read(codec, WM8974_CLOCK) & 0x1e3; 389 reg = snd_soc_read(codec, WM8974_CLOCK) & 0x1e3;
394 snd_soc_write(codec, WM8974_CLOCK, reg | div); 390 snd_soc_write(codec, WM8974_CLOCK, reg | div);
diff --git a/sound/soc/codecs/wm8974.h b/sound/soc/codecs/wm8974.h
index 98de9562d4d2..896a7f0f3fc4 100644
--- a/sound/soc/codecs/wm8974.h
+++ b/sound/soc/codecs/wm8974.h
@@ -57,17 +57,7 @@
57/* Clock divider Id's */ 57/* Clock divider Id's */
58#define WM8974_OPCLKDIV 0 58#define WM8974_OPCLKDIV 0
59#define WM8974_MCLKDIV 1 59#define WM8974_MCLKDIV 1
60#define WM8974_ADCCLK 2 60#define WM8974_BCLKDIV 2
61#define WM8974_DACCLK 3
62#define WM8974_BCLKDIV 4
63
64/* DAC clock dividers */
65#define WM8974_DACCLK_F2 (1 << 3)
66#define WM8974_DACCLK_F4 (0 << 3)
67
68/* ADC clock dividers */
69#define WM8974_ADCCLK_F2 (1 << 3)
70#define WM8974_ADCCLK_F4 (0 << 3)
71 61
72/* PLL Out dividers */ 62/* PLL Out dividers */
73#define WM8974_OPCLKDIV_1 (0 << 4) 63#define WM8974_OPCLKDIV_1 (0 << 4)
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c
new file mode 100644
index 000000000000..28bb59ea6ea1
--- /dev/null
+++ b/sound/soc/codecs/wm8978.c
@@ -0,0 +1,1149 @@
1/*
2 * wm8978.c -- WM8978 ALSA SoC Audio Codec driver
3 *
4 * Copyright (C) 2009-2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
5 * Copyright (C) 2007 Carlos Munoz <carlos@kenati.com>
6 * Copyright 2006-2009 Wolfson Microelectronics PLC.
7 * Based on wm8974 and wm8990 by Liam Girdwood <lrg@slimlogic.co.uk>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/module.h>
15#include <linux/moduleparam.h>
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/delay.h>
19#include <linux/pm.h>
20#include <linux/i2c.h>
21#include <linux/platform_device.h>
22#include <sound/core.h>
23#include <sound/pcm.h>
24#include <sound/pcm_params.h>
25#include <sound/soc.h>
26#include <sound/soc-dapm.h>
27#include <sound/initval.h>
28#include <sound/tlv.h>
29#include <asm/div64.h>
30
31#include "wm8978.h"
32
33static struct snd_soc_codec *wm8978_codec;
34
35/* wm8978 register cache. Note that register 0 is not included in the cache. */
36static const u16 wm8978_reg[WM8978_CACHEREGNUM] = {
37 0x0000, 0x0000, 0x0000, 0x0000, /* 0x00...0x03 */
38 0x0050, 0x0000, 0x0140, 0x0000, /* 0x04...0x07 */
39 0x0000, 0x0000, 0x0000, 0x00ff, /* 0x08...0x0b */
40 0x00ff, 0x0000, 0x0100, 0x00ff, /* 0x0c...0x0f */
41 0x00ff, 0x0000, 0x012c, 0x002c, /* 0x10...0x13 */
42 0x002c, 0x002c, 0x002c, 0x0000, /* 0x14...0x17 */
43 0x0032, 0x0000, 0x0000, 0x0000, /* 0x18...0x1b */
44 0x0000, 0x0000, 0x0000, 0x0000, /* 0x1c...0x1f */
45 0x0038, 0x000b, 0x0032, 0x0000, /* 0x20...0x23 */
46 0x0008, 0x000c, 0x0093, 0x00e9, /* 0x24...0x27 */
47 0x0000, 0x0000, 0x0000, 0x0000, /* 0x28...0x2b */
48 0x0033, 0x0010, 0x0010, 0x0100, /* 0x2c...0x2f */
49 0x0100, 0x0002, 0x0001, 0x0001, /* 0x30...0x33 */
50 0x0039, 0x0039, 0x0039, 0x0039, /* 0x34...0x37 */
51 0x0001, 0x0001, /* 0x38...0x3b */
52};
53
54/* codec private data */
55struct wm8978_priv {
56 struct snd_soc_codec codec;
57 unsigned int f_pllout;
58 unsigned int f_mclk;
59 unsigned int f_256fs;
60 unsigned int f_opclk;
61 int mclk_idx;
62 enum wm8978_sysclk_src sysclk;
63 u16 reg_cache[WM8978_CACHEREGNUM];
64};
65
66static const char *wm8978_companding[] = {"Off", "NC", "u-law", "A-law"};
67static const char *wm8978_eqmode[] = {"Capture", "Playback"};
68static const char *wm8978_bw[] = {"Narrow", "Wide"};
69static const char *wm8978_eq1[] = {"80Hz", "105Hz", "135Hz", "175Hz"};
70static const char *wm8978_eq2[] = {"230Hz", "300Hz", "385Hz", "500Hz"};
71static const char *wm8978_eq3[] = {"650Hz", "850Hz", "1.1kHz", "1.4kHz"};
72static const char *wm8978_eq4[] = {"1.8kHz", "2.4kHz", "3.2kHz", "4.1kHz"};
73static const char *wm8978_eq5[] = {"5.3kHz", "6.9kHz", "9kHz", "11.7kHz"};
74static const char *wm8978_alc3[] = {"ALC", "Limiter"};
75static const char *wm8978_alc1[] = {"Off", "Right", "Left", "Both"};
76
77static const SOC_ENUM_SINGLE_DECL(adc_compand, WM8978_COMPANDING_CONTROL, 1,
78 wm8978_companding);
79static const SOC_ENUM_SINGLE_DECL(dac_compand, WM8978_COMPANDING_CONTROL, 3,
80 wm8978_companding);
81static const SOC_ENUM_SINGLE_DECL(eqmode, WM8978_EQ1, 8, wm8978_eqmode);
82static const SOC_ENUM_SINGLE_DECL(eq1, WM8978_EQ1, 5, wm8978_eq1);
83static const SOC_ENUM_SINGLE_DECL(eq2bw, WM8978_EQ2, 8, wm8978_bw);
84static const SOC_ENUM_SINGLE_DECL(eq2, WM8978_EQ2, 5, wm8978_eq2);
85static const SOC_ENUM_SINGLE_DECL(eq3bw, WM8978_EQ3, 8, wm8978_bw);
86static const SOC_ENUM_SINGLE_DECL(eq3, WM8978_EQ3, 5, wm8978_eq3);
87static const SOC_ENUM_SINGLE_DECL(eq4bw, WM8978_EQ4, 8, wm8978_bw);
88static const SOC_ENUM_SINGLE_DECL(eq4, WM8978_EQ4, 5, wm8978_eq4);
89static const SOC_ENUM_SINGLE_DECL(eq5, WM8978_EQ5, 5, wm8978_eq5);
90static const SOC_ENUM_SINGLE_DECL(alc3, WM8978_ALC_CONTROL_3, 8, wm8978_alc3);
91static const SOC_ENUM_SINGLE_DECL(alc1, WM8978_ALC_CONTROL_1, 7, wm8978_alc1);
92
93static const DECLARE_TLV_DB_SCALE(digital_tlv, -12750, 50, 1);
94static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
95static const DECLARE_TLV_DB_SCALE(inpga_tlv, -1200, 75, 0);
96static const DECLARE_TLV_DB_SCALE(spk_tlv, -5700, 100, 0);
97static const DECLARE_TLV_DB_SCALE(boost_tlv, -1500, 300, 1);
98
99static const struct snd_kcontrol_new wm8978_snd_controls[] = {
100
101 SOC_SINGLE("Digital Loopback Switch",
102 WM8978_COMPANDING_CONTROL, 0, 1, 0),
103
104 SOC_ENUM("ADC Companding", adc_compand),
105 SOC_ENUM("DAC Companding", dac_compand),
106
107 SOC_DOUBLE("DAC Inversion Switch", WM8978_DAC_CONTROL, 0, 1, 1, 0),
108
109 SOC_DOUBLE_R_TLV("PCM Volume",
110 WM8978_LEFT_DAC_DIGITAL_VOLUME, WM8978_RIGHT_DAC_DIGITAL_VOLUME,
111 0, 255, 0, digital_tlv),
112
113 SOC_SINGLE("High Pass Filter Switch", WM8978_ADC_CONTROL, 8, 1, 0),
114 SOC_SINGLE("High Pass Cut Off", WM8978_ADC_CONTROL, 4, 7, 0),
115 SOC_DOUBLE("ADC Inversion Switch", WM8978_ADC_CONTROL, 0, 1, 1, 0),
116
117 SOC_DOUBLE_R_TLV("ADC Volume",
118 WM8978_LEFT_ADC_DIGITAL_VOLUME, WM8978_RIGHT_ADC_DIGITAL_VOLUME,
119 0, 255, 0, digital_tlv),
120
121 SOC_ENUM("Equaliser Function", eqmode),
122 SOC_ENUM("EQ1 Cut Off", eq1),
123 SOC_SINGLE_TLV("EQ1 Volume", WM8978_EQ1, 0, 24, 1, eq_tlv),
124
125 SOC_ENUM("Equaliser EQ2 Bandwith", eq2bw),
126 SOC_ENUM("EQ2 Cut Off", eq2),
127 SOC_SINGLE_TLV("EQ2 Volume", WM8978_EQ2, 0, 24, 1, eq_tlv),
128
129 SOC_ENUM("Equaliser EQ3 Bandwith", eq3bw),
130 SOC_ENUM("EQ3 Cut Off", eq3),
131 SOC_SINGLE_TLV("EQ3 Volume", WM8978_EQ3, 0, 24, 1, eq_tlv),
132
133 SOC_ENUM("Equaliser EQ4 Bandwith", eq4bw),
134 SOC_ENUM("EQ4 Cut Off", eq4),
135 SOC_SINGLE_TLV("EQ4 Volume", WM8978_EQ4, 0, 24, 1, eq_tlv),
136
137 SOC_ENUM("EQ5 Cut Off", eq5),
138 SOC_SINGLE_TLV("EQ5 Volume", WM8978_EQ5, 0, 24, 1, eq_tlv),
139
140 SOC_SINGLE("DAC Playback Limiter Switch",
141 WM8978_DAC_LIMITER_1, 8, 1, 0),
142 SOC_SINGLE("DAC Playback Limiter Decay",
143 WM8978_DAC_LIMITER_1, 4, 15, 0),
144 SOC_SINGLE("DAC Playback Limiter Attack",
145 WM8978_DAC_LIMITER_1, 0, 15, 0),
146
147 SOC_SINGLE("DAC Playback Limiter Threshold",
148 WM8978_DAC_LIMITER_2, 4, 7, 0),
149 SOC_SINGLE("DAC Playback Limiter Boost",
150 WM8978_DAC_LIMITER_2, 0, 15, 0),
151
152 SOC_ENUM("ALC Enable Switch", alc1),
153 SOC_SINGLE("ALC Capture Min Gain", WM8978_ALC_CONTROL_1, 0, 7, 0),
154 SOC_SINGLE("ALC Capture Max Gain", WM8978_ALC_CONTROL_1, 3, 7, 0),
155
156 SOC_SINGLE("ALC Capture Hold", WM8978_ALC_CONTROL_2, 4, 7, 0),
157 SOC_SINGLE("ALC Capture Target", WM8978_ALC_CONTROL_2, 0, 15, 0),
158
159 SOC_ENUM("ALC Capture Mode", alc3),
160 SOC_SINGLE("ALC Capture Decay", WM8978_ALC_CONTROL_3, 4, 15, 0),
161 SOC_SINGLE("ALC Capture Attack", WM8978_ALC_CONTROL_3, 0, 15, 0),
162
163 SOC_SINGLE("ALC Capture Noise Gate Switch", WM8978_NOISE_GATE, 3, 1, 0),
164 SOC_SINGLE("ALC Capture Noise Gate Threshold",
165 WM8978_NOISE_GATE, 0, 7, 0),
166
167 SOC_DOUBLE_R("Capture PGA ZC Switch",
168 WM8978_LEFT_INP_PGA_CONTROL, WM8978_RIGHT_INP_PGA_CONTROL,
169 7, 1, 0),
170
171 /* OUT1 - Headphones */
172 SOC_DOUBLE_R("Headphone Playback ZC Switch",
173 WM8978_LOUT1_HP_CONTROL, WM8978_ROUT1_HP_CONTROL, 7, 1, 0),
174
175 SOC_DOUBLE_R_TLV("Headphone Playback Volume",
176 WM8978_LOUT1_HP_CONTROL, WM8978_ROUT1_HP_CONTROL,
177 0, 63, 0, spk_tlv),
178
179 /* OUT2 - Speakers */
180 SOC_DOUBLE_R("Speaker Playback ZC Switch",
181 WM8978_LOUT2_SPK_CONTROL, WM8978_ROUT2_SPK_CONTROL, 7, 1, 0),
182
183 SOC_DOUBLE_R_TLV("Speaker Playback Volume",
184 WM8978_LOUT2_SPK_CONTROL, WM8978_ROUT2_SPK_CONTROL,
185 0, 63, 0, spk_tlv),
186
187 /* OUT3/4 - Line Output */
188 SOC_DOUBLE_R("Line Playback Switch",
189 WM8978_OUT3_MIXER_CONTROL, WM8978_OUT4_MIXER_CONTROL, 6, 1, 1),
190
191 /* Mixer #3: Boost (Input) mixer */
192 SOC_DOUBLE_R("PGA Boost (+20dB)",
193 WM8978_LEFT_ADC_BOOST_CONTROL, WM8978_RIGHT_ADC_BOOST_CONTROL,
194 8, 1, 0),
195 SOC_DOUBLE_R_TLV("L2/R2 Boost Volume",
196 WM8978_LEFT_ADC_BOOST_CONTROL, WM8978_RIGHT_ADC_BOOST_CONTROL,
197 4, 7, 0, boost_tlv),
198 SOC_DOUBLE_R_TLV("Aux Boost Volume",
199 WM8978_LEFT_ADC_BOOST_CONTROL, WM8978_RIGHT_ADC_BOOST_CONTROL,
200 0, 7, 0, boost_tlv),
201
202 /* Input PGA volume */
203 SOC_DOUBLE_R_TLV("Input PGA Volume",
204 WM8978_LEFT_INP_PGA_CONTROL, WM8978_RIGHT_INP_PGA_CONTROL,
205 0, 63, 0, inpga_tlv),
206
207 /* Headphone */
208 SOC_DOUBLE_R("Headphone Switch",
209 WM8978_LOUT1_HP_CONTROL, WM8978_ROUT1_HP_CONTROL, 6, 1, 1),
210
211 /* Speaker */
212 SOC_DOUBLE_R("Speaker Switch",
213 WM8978_LOUT2_SPK_CONTROL, WM8978_ROUT2_SPK_CONTROL, 6, 1, 1),
214
215 /* DAC / ADC oversampling */
216 SOC_SINGLE("DAC 128x Oversampling Switch", WM8978_DAC_CONTROL, 8, 1, 0),
217 SOC_SINGLE("ADC 128x Oversampling Switch", WM8978_ADC_CONTROL, 8, 1, 0),
218};
219
220/* Mixer #1: Output (OUT1, OUT2) Mixer: mix AUX, Input mixer output and DAC */
221static const struct snd_kcontrol_new wm8978_left_out_mixer[] = {
222 SOC_DAPM_SINGLE("Line Bypass Switch", WM8978_LEFT_MIXER_CONTROL, 1, 1, 0),
223 SOC_DAPM_SINGLE("Aux Playback Switch", WM8978_LEFT_MIXER_CONTROL, 5, 1, 0),
224 SOC_DAPM_SINGLE("PCM Playback Switch", WM8978_LEFT_MIXER_CONTROL, 0, 1, 0),
225};
226
227static const struct snd_kcontrol_new wm8978_right_out_mixer[] = {
228 SOC_DAPM_SINGLE("Line Bypass Switch", WM8978_RIGHT_MIXER_CONTROL, 1, 1, 0),
229 SOC_DAPM_SINGLE("Aux Playback Switch", WM8978_RIGHT_MIXER_CONTROL, 5, 1, 0),
230 SOC_DAPM_SINGLE("PCM Playback Switch", WM8978_RIGHT_MIXER_CONTROL, 0, 1, 0),
231};
232
233/* OUT3/OUT4 Mixer not implemented */
234
235/* Mixer #2: Input PGA Mute */
236static const struct snd_kcontrol_new wm8978_left_input_mixer[] = {
237 SOC_DAPM_SINGLE("L2 Switch", WM8978_INPUT_CONTROL, 2, 1, 0),
238 SOC_DAPM_SINGLE("MicN Switch", WM8978_INPUT_CONTROL, 1, 1, 0),
239 SOC_DAPM_SINGLE("MicP Switch", WM8978_INPUT_CONTROL, 0, 1, 0),
240};
241static const struct snd_kcontrol_new wm8978_right_input_mixer[] = {
242 SOC_DAPM_SINGLE("R2 Switch", WM8978_INPUT_CONTROL, 6, 1, 0),
243 SOC_DAPM_SINGLE("MicN Switch", WM8978_INPUT_CONTROL, 5, 1, 0),
244 SOC_DAPM_SINGLE("MicP Switch", WM8978_INPUT_CONTROL, 4, 1, 0),
245};
246
247static const struct snd_soc_dapm_widget wm8978_dapm_widgets[] = {
248 SND_SOC_DAPM_DAC("Left DAC", "Left HiFi Playback",
249 WM8978_POWER_MANAGEMENT_3, 0, 0),
250 SND_SOC_DAPM_DAC("Right DAC", "Right HiFi Playback",
251 WM8978_POWER_MANAGEMENT_3, 1, 0),
252 SND_SOC_DAPM_ADC("Left ADC", "Left HiFi Capture",
253 WM8978_POWER_MANAGEMENT_2, 0, 0),
254 SND_SOC_DAPM_ADC("Right ADC", "Right HiFi Capture",
255 WM8978_POWER_MANAGEMENT_2, 1, 0),
256
257 /* Mixer #1: OUT1,2 */
258 SOC_MIXER_ARRAY("Left Output Mixer", WM8978_POWER_MANAGEMENT_3,
259 2, 0, wm8978_left_out_mixer),
260 SOC_MIXER_ARRAY("Right Output Mixer", WM8978_POWER_MANAGEMENT_3,
261 3, 0, wm8978_right_out_mixer),
262
263 SOC_MIXER_ARRAY("Left Input Mixer", WM8978_POWER_MANAGEMENT_2,
264 2, 0, wm8978_left_input_mixer),
265 SOC_MIXER_ARRAY("Right Input Mixer", WM8978_POWER_MANAGEMENT_2,
266 3, 0, wm8978_right_input_mixer),
267
268 SND_SOC_DAPM_PGA("Left Boost Mixer", WM8978_POWER_MANAGEMENT_2,
269 4, 0, NULL, 0),
270 SND_SOC_DAPM_PGA("Right Boost Mixer", WM8978_POWER_MANAGEMENT_2,
271 5, 0, NULL, 0),
272
273 SND_SOC_DAPM_PGA("Left Capture PGA", WM8978_LEFT_INP_PGA_CONTROL,
274 6, 1, NULL, 0),
275 SND_SOC_DAPM_PGA("Right Capture PGA", WM8978_RIGHT_INP_PGA_CONTROL,
276 6, 1, NULL, 0),
277
278 SND_SOC_DAPM_PGA("Left Headphone Out", WM8978_POWER_MANAGEMENT_2,
279 7, 0, NULL, 0),
280 SND_SOC_DAPM_PGA("Right Headphone Out", WM8978_POWER_MANAGEMENT_2,
281 8, 0, NULL, 0),
282
283 SND_SOC_DAPM_PGA("Left Speaker Out", WM8978_POWER_MANAGEMENT_3,
284 6, 0, NULL, 0),
285 SND_SOC_DAPM_PGA("Right Speaker Out", WM8978_POWER_MANAGEMENT_3,
286 5, 0, NULL, 0),
287
288 SND_SOC_DAPM_MIXER("OUT4 VMID", WM8978_POWER_MANAGEMENT_3,
289 8, 0, NULL, 0),
290
291 SND_SOC_DAPM_MICBIAS("Mic Bias", WM8978_POWER_MANAGEMENT_1, 4, 0),
292
293 SND_SOC_DAPM_INPUT("LMICN"),
294 SND_SOC_DAPM_INPUT("LMICP"),
295 SND_SOC_DAPM_INPUT("RMICN"),
296 SND_SOC_DAPM_INPUT("RMICP"),
297 SND_SOC_DAPM_INPUT("LAUX"),
298 SND_SOC_DAPM_INPUT("RAUX"),
299 SND_SOC_DAPM_INPUT("L2"),
300 SND_SOC_DAPM_INPUT("R2"),
301 SND_SOC_DAPM_OUTPUT("LHP"),
302 SND_SOC_DAPM_OUTPUT("RHP"),
303 SND_SOC_DAPM_OUTPUT("LSPK"),
304 SND_SOC_DAPM_OUTPUT("RSPK"),
305};
306
307static const struct snd_soc_dapm_route audio_map[] = {
308 /* Output mixer */
309 {"Right Output Mixer", "PCM Playback Switch", "Right DAC"},
310 {"Right Output Mixer", "Aux Playback Switch", "RAUX"},
311 {"Right Output Mixer", "Line Bypass Switch", "Right Boost Mixer"},
312
313 {"Left Output Mixer", "PCM Playback Switch", "Left DAC"},
314 {"Left Output Mixer", "Aux Playback Switch", "LAUX"},
315 {"Left Output Mixer", "Line Bypass Switch", "Left Boost Mixer"},
316
317 /* Outputs */
318 {"Right Headphone Out", NULL, "Right Output Mixer"},
319 {"RHP", NULL, "Right Headphone Out"},
320
321 {"Left Headphone Out", NULL, "Left Output Mixer"},
322 {"LHP", NULL, "Left Headphone Out"},
323
324 {"Right Speaker Out", NULL, "Right Output Mixer"},
325 {"RSPK", NULL, "Right Speaker Out"},
326
327 {"Left Speaker Out", NULL, "Left Output Mixer"},
328 {"LSPK", NULL, "Left Speaker Out"},
329
330 /* Boost Mixer */
331 {"Right ADC", NULL, "Right Boost Mixer"},
332
333 {"Right Boost Mixer", NULL, "RAUX"},
334 {"Right Boost Mixer", NULL, "Right Capture PGA"},
335 {"Right Boost Mixer", NULL, "R2"},
336
337 {"Left ADC", NULL, "Left Boost Mixer"},
338
339 {"Left Boost Mixer", NULL, "LAUX"},
340 {"Left Boost Mixer", NULL, "Left Capture PGA"},
341 {"Left Boost Mixer", NULL, "L2"},
342
343 /* Input PGA */
344 {"Right Capture PGA", NULL, "Right Input Mixer"},
345 {"Left Capture PGA", NULL, "Left Input Mixer"},
346
347 {"Right Input Mixer", "R2 Switch", "R2"},
348 {"Right Input Mixer", "MicN Switch", "RMICN"},
349 {"Right Input Mixer", "MicP Switch", "RMICP"},
350
351 {"Left Input Mixer", "L2 Switch", "L2"},
352 {"Left Input Mixer", "MicN Switch", "LMICN"},
353 {"Left Input Mixer", "MicP Switch", "LMICP"},
354};
355
356static int wm8978_add_widgets(struct snd_soc_codec *codec)
357{
358 snd_soc_dapm_new_controls(codec, wm8978_dapm_widgets,
359 ARRAY_SIZE(wm8978_dapm_widgets));
360
361 /* set up the WM8978 audio map */
362 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
363
364 return 0;
365}
366
367/* PLL divisors */
368struct wm8978_pll_div {
369 u32 k;
370 u8 n;
371 u8 div2;
372};
373
374#define FIXED_PLL_SIZE (1 << 24)
375
376static void pll_factors(struct wm8978_pll_div *pll_div, unsigned int target,
377 unsigned int source)
378{
379 u64 k_part;
380 unsigned int k, n_div, n_mod;
381
382 n_div = target / source;
383 if (n_div < 6) {
384 source >>= 1;
385 pll_div->div2 = 1;
386 n_div = target / source;
387 } else {
388 pll_div->div2 = 0;
389 }
390
391 if (n_div < 6 || n_div > 12)
392 dev_warn(wm8978_codec->dev,
393 "WM8978 N value exceeds recommended range! N = %u\n",
394 n_div);
395
396 pll_div->n = n_div;
397 n_mod = target - source * n_div;
398 k_part = FIXED_PLL_SIZE * (long long)n_mod + source / 2;
399
400 do_div(k_part, source);
401
402 k = k_part & 0xFFFFFFFF;
403
404 pll_div->k = k;
405}
406
407/* MCLK dividers */
408static const int mclk_numerator[] = {1, 3, 2, 3, 4, 6, 8, 12};
409static const int mclk_denominator[] = {1, 2, 1, 1, 1, 1, 1, 1};
410
411/*
412 * find index >= idx, such that, for a given f_out,
413 * 3 * f_mclk / 4 <= f_PLLOUT < 13 * f_mclk / 4
414 * f_out can be f_256fs or f_opclk, currently only used for f_256fs. Can be
415 * generalised for f_opclk with suitable coefficient arrays, but currently
416 * the OPCLK divisor is calculated directly, not iteratively.
417 */
418static int wm8978_enum_mclk(unsigned int f_out, unsigned int f_mclk,
419 unsigned int *f_pllout)
420{
421 int i;
422
423 for (i = 0; i < ARRAY_SIZE(mclk_numerator); i++) {
424 unsigned int f_pllout_x4 = 4 * f_out * mclk_numerator[i] /
425 mclk_denominator[i];
426 if (3 * f_mclk <= f_pllout_x4 && f_pllout_x4 < 13 * f_mclk) {
427 *f_pllout = f_pllout_x4 / 4;
428 return i;
429 }
430 }
431
432 return -EINVAL;
433}
434
435/*
436 * Calculate internal frequencies and dividers, according to Figure 40
437 * "PLL and Clock Select Circuit" in WM8978 datasheet Rev. 2.6
438 */
439static int wm8978_configure_pll(struct snd_soc_codec *codec)
440{
441 struct wm8978_priv *wm8978 = codec->private_data;
442 struct wm8978_pll_div pll_div;
443 unsigned int f_opclk = wm8978->f_opclk, f_mclk = wm8978->f_mclk,
444 f_256fs = wm8978->f_256fs;
445 unsigned int f2;
446
447 if (!f_mclk)
448 return -EINVAL;
449
450 if (f_opclk) {
451 unsigned int opclk_div;
452 /* Cannot set up MCLK divider now, do later */
453 wm8978->mclk_idx = -1;
454
455 /*
456 * The user needs OPCLK. Choose OPCLKDIV to put
457 * 6 <= R = f2 / f1 < 13, 1 <= OPCLKDIV <= 4.
458 * f_opclk = f_mclk * prescale * R / 4 / OPCLKDIV, where
459 * prescale = 1, or prescale = 2. Prescale is calculated inside
460 * pll_factors(). We have to select f_PLLOUT, such that
461 * f_mclk * 3 / 4 <= f_PLLOUT < f_mclk * 13 / 4. Must be
462 * f_mclk * 3 / 16 <= f_opclk < f_mclk * 13 / 4.
463 */
464 if (16 * f_opclk < 3 * f_mclk || 4 * f_opclk >= 13 * f_mclk)
465 return -EINVAL;
466
467 if (4 * f_opclk < 3 * f_mclk)
468 /* Have to use OPCLKDIV */
469 opclk_div = (3 * f_mclk / 4 + f_opclk - 1) / f_opclk;
470 else
471 opclk_div = 1;
472
473 dev_dbg(codec->dev, "%s: OPCLKDIV=%d\n", __func__, opclk_div);
474
475 snd_soc_update_bits(codec, WM8978_GPIO_CONTROL, 0x30,
476 (opclk_div - 1) << 4);
477
478 wm8978->f_pllout = f_opclk * opclk_div;
479 } else if (f_256fs) {
480 /*
481 * Not using OPCLK, but PLL is used for the codec, choose R:
482 * 6 <= R = f2 / f1 < 13, to put 1 <= MCLKDIV <= 12.
483 * f_256fs = f_mclk * prescale * R / 4 / MCLKDIV, where
484 * prescale = 1, or prescale = 2. Prescale is calculated inside
485 * pll_factors(). We have to select f_PLLOUT, such that
486 * f_mclk * 3 / 4 <= f_PLLOUT < f_mclk * 13 / 4. Must be
487 * f_mclk * 3 / 48 <= f_256fs < f_mclk * 13 / 4. This means MCLK
488 * must be 3.781MHz <= f_MCLK <= 32.768MHz
489 */
490 int idx = wm8978_enum_mclk(f_256fs, f_mclk, &wm8978->f_pllout);
491 if (idx < 0)
492 return idx;
493
494 wm8978->mclk_idx = idx;
495
496 /* GPIO1 into default mode as input - before configuring PLL */
497 snd_soc_update_bits(codec, WM8978_GPIO_CONTROL, 7, 0);
498 } else {
499 return -EINVAL;
500 }
501
502 f2 = wm8978->f_pllout * 4;
503
504 dev_dbg(codec->dev, "%s: f_MCLK=%uHz, f_PLLOUT=%uHz\n", __func__,
505 wm8978->f_mclk, wm8978->f_pllout);
506
507 pll_factors(&pll_div, f2, wm8978->f_mclk);
508
509 dev_dbg(codec->dev, "%s: calculated PLL N=0x%x, K=0x%x, div2=%d\n",
510 __func__, pll_div.n, pll_div.k, pll_div.div2);
511
512 /* Turn PLL off for configuration... */
513 snd_soc_update_bits(codec, WM8978_POWER_MANAGEMENT_1, 0x20, 0);
514
515 snd_soc_write(codec, WM8978_PLL_N, (pll_div.div2 << 4) | pll_div.n);
516 snd_soc_write(codec, WM8978_PLL_K1, pll_div.k >> 18);
517 snd_soc_write(codec, WM8978_PLL_K2, (pll_div.k >> 9) & 0x1ff);
518 snd_soc_write(codec, WM8978_PLL_K3, pll_div.k & 0x1ff);
519
520 /* ...and on again */
521 snd_soc_update_bits(codec, WM8978_POWER_MANAGEMENT_1, 0x20, 0x20);
522
523 if (f_opclk)
524 /* Output PLL (OPCLK) to GPIO1 */
525 snd_soc_update_bits(codec, WM8978_GPIO_CONTROL, 7, 4);
526
527 return 0;
528}
529
530/*
531 * Configure WM8978 clock dividers.
532 */
533static int wm8978_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
534 int div_id, int div)
535{
536 struct snd_soc_codec *codec = codec_dai->codec;
537 struct wm8978_priv *wm8978 = codec->private_data;
538 int ret = 0;
539
540 switch (div_id) {
541 case WM8978_OPCLKRATE:
542 wm8978->f_opclk = div;
543
544 if (wm8978->f_mclk)
545 /*
546 * We know the MCLK frequency, the user has requested
547 * OPCLK, configure the PLL based on that and start it
548 * and OPCLK immediately. We will configure PLL to match
549 * user-requested OPCLK frquency as good as possible.
550 * In fact, it is likely, that matching the sampling
551 * rate, when it becomes known, is more important, and
552 * we will not be reconfiguring PLL then, because we
553 * must not interrupt OPCLK. But it should be fine,
554 * because typically the user will request OPCLK to run
555 * at 256fs or 512fs, and for these cases we will also
556 * find an exact MCLK divider configuration - it will
557 * be equal to or double the OPCLK divisor.
558 */
559 ret = wm8978_configure_pll(codec);
560 break;
561 case WM8978_BCLKDIV:
562 if (div & ~0x1c)
563 return -EINVAL;
564 snd_soc_update_bits(codec, WM8978_CLOCKING, 0x1c, div);
565 break;
566 default:
567 return -EINVAL;
568 }
569
570 dev_dbg(codec->dev, "%s: ID %d, value %u\n", __func__, div_id, div);
571
572 return ret;
573}
574
575/*
576 * @freq: when .set_pll() us not used, freq is codec MCLK input frequency
577 */
578static int wm8978_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id,
579 unsigned int freq, int dir)
580{
581 struct snd_soc_codec *codec = codec_dai->codec;
582 struct wm8978_priv *wm8978 = codec->private_data;
583 int ret = 0;
584
585 dev_dbg(codec->dev, "%s: ID %d, freq %u\n", __func__, clk_id, freq);
586
587 if (freq) {
588 wm8978->f_mclk = freq;
589
590 /* Even if MCLK is used for system clock, might have to drive OPCLK */
591 if (wm8978->f_opclk)
592 ret = wm8978_configure_pll(codec);
593
594 /* Our sysclk is fixed to 256 * fs, will configure in .hw_params() */
595
596 if (!ret)
597 wm8978->sysclk = clk_id;
598 }
599
600 if (wm8978->sysclk == WM8978_PLL && (!freq || clk_id == WM8978_MCLK)) {
601 /* Clock CODEC directly from MCLK */
602 snd_soc_update_bits(codec, WM8978_CLOCKING, 0x100, 0);
603
604 /* GPIO1 into default mode as input - before configuring PLL */
605 snd_soc_update_bits(codec, WM8978_GPIO_CONTROL, 7, 0);
606
607 /* Turn off PLL */
608 snd_soc_update_bits(codec, WM8978_POWER_MANAGEMENT_1, 0x20, 0);
609 wm8978->sysclk = WM8978_MCLK;
610 wm8978->f_pllout = 0;
611 wm8978->f_opclk = 0;
612 }
613
614 return ret;
615}
616
617/*
618 * Set ADC and Voice DAC format.
619 */
620static int wm8978_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
621{
622 struct snd_soc_codec *codec = codec_dai->codec;
623 /*
624 * BCLK polarity mask = 0x100, LRC clock polarity mask = 0x80,
625 * Data Format mask = 0x18: all will be calculated anew
626 */
627 u16 iface = snd_soc_read(codec, WM8978_AUDIO_INTERFACE) & ~0x198;
628 u16 clk = snd_soc_read(codec, WM8978_CLOCKING);
629
630 dev_dbg(codec->dev, "%s\n", __func__);
631
632 /* set master/slave audio interface */
633 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
634 case SND_SOC_DAIFMT_CBM_CFM:
635 clk |= 1;
636 break;
637 case SND_SOC_DAIFMT_CBS_CFS:
638 clk &= ~1;
639 break;
640 default:
641 return -EINVAL;
642 }
643
644 /* interface format */
645 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
646 case SND_SOC_DAIFMT_I2S:
647 iface |= 0x10;
648 break;
649 case SND_SOC_DAIFMT_RIGHT_J:
650 break;
651 case SND_SOC_DAIFMT_LEFT_J:
652 iface |= 0x8;
653 break;
654 case SND_SOC_DAIFMT_DSP_A:
655 iface |= 0x18;
656 break;
657 default:
658 return -EINVAL;
659 }
660
661 /* clock inversion */
662 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
663 case SND_SOC_DAIFMT_NB_NF:
664 break;
665 case SND_SOC_DAIFMT_IB_IF:
666 iface |= 0x180;
667 break;
668 case SND_SOC_DAIFMT_IB_NF:
669 iface |= 0x100;
670 break;
671 case SND_SOC_DAIFMT_NB_IF:
672 iface |= 0x80;
673 break;
674 default:
675 return -EINVAL;
676 }
677
678 snd_soc_write(codec, WM8978_AUDIO_INTERFACE, iface);
679 snd_soc_write(codec, WM8978_CLOCKING, clk);
680
681 return 0;
682}
683
684/*
685 * Set PCM DAI bit size and sample rate.
686 */
687static int wm8978_hw_params(struct snd_pcm_substream *substream,
688 struct snd_pcm_hw_params *params,
689 struct snd_soc_dai *dai)
690{
691 struct snd_soc_pcm_runtime *rtd = substream->private_data;
692 struct snd_soc_device *socdev = rtd->socdev;
693 struct snd_soc_codec *codec = socdev->card->codec;
694 struct wm8978_priv *wm8978 = codec->private_data;
695 /* Word length mask = 0x60 */
696 u16 iface_ctl = snd_soc_read(codec, WM8978_AUDIO_INTERFACE) & ~0x60;
697 /* Sampling rate mask = 0xe (for filters) */
698 u16 add_ctl = snd_soc_read(codec, WM8978_ADDITIONAL_CONTROL) & ~0xe;
699 u16 clking = snd_soc_read(codec, WM8978_CLOCKING);
700 enum wm8978_sysclk_src current_clk_id = clking & 0x100 ?
701 WM8978_PLL : WM8978_MCLK;
702 unsigned int f_sel, diff, diff_best = INT_MAX;
703 int i, best = 0;
704
705 if (!wm8978->f_mclk)
706 return -EINVAL;
707
708 /* bit size */
709 switch (params_format(params)) {
710 case SNDRV_PCM_FORMAT_S16_LE:
711 break;
712 case SNDRV_PCM_FORMAT_S20_3LE:
713 iface_ctl |= 0x20;
714 break;
715 case SNDRV_PCM_FORMAT_S24_LE:
716 iface_ctl |= 0x40;
717 break;
718 case SNDRV_PCM_FORMAT_S32_LE:
719 iface_ctl |= 0x60;
720 break;
721 }
722
723 /* filter coefficient */
724 switch (params_rate(params)) {
725 case 8000:
726 add_ctl |= 0x5 << 1;
727 break;
728 case 11025:
729 add_ctl |= 0x4 << 1;
730 break;
731 case 16000:
732 add_ctl |= 0x3 << 1;
733 break;
734 case 22050:
735 add_ctl |= 0x2 << 1;
736 break;
737 case 32000:
738 add_ctl |= 0x1 << 1;
739 break;
740 case 44100:
741 case 48000:
742 break;
743 }
744
745 /* Sampling rate is known now, can configure the MCLK divider */
746 wm8978->f_256fs = params_rate(params) * 256;
747
748 if (wm8978->sysclk == WM8978_MCLK) {
749 wm8978->mclk_idx = -1;
750 f_sel = wm8978->f_mclk;
751 } else {
752 if (!wm8978->f_pllout) {
753 /* We only enter here, if OPCLK is not used */
754 int ret = wm8978_configure_pll(codec);
755 if (ret < 0)
756 return ret;
757 }
758 f_sel = wm8978->f_pllout;
759 }
760
761 if (wm8978->mclk_idx < 0) {
762 /* Either MCLK is used directly, or OPCLK is used */
763 if (f_sel < wm8978->f_256fs || f_sel > 12 * wm8978->f_256fs)
764 return -EINVAL;
765
766 for (i = 0; i < ARRAY_SIZE(mclk_numerator); i++) {
767 diff = abs(wm8978->f_256fs * 3 -
768 f_sel * 3 * mclk_denominator[i] / mclk_numerator[i]);
769
770 if (diff < diff_best) {
771 diff_best = diff;
772 best = i;
773 }
774
775 if (!diff)
776 break;
777 }
778 } else {
779 /* OPCLK not used, codec driven by PLL */
780 best = wm8978->mclk_idx;
781 diff = 0;
782 }
783
784 if (diff)
785 dev_warn(codec->dev, "Imprecise sampling rate: %uHz%s\n",
786 f_sel * mclk_denominator[best] / mclk_numerator[best] / 256,
787 wm8978->sysclk == WM8978_MCLK ?
788 ", consider using PLL" : "");
789
790 dev_dbg(codec->dev, "%s: fmt %d, rate %u, MCLK divisor #%d\n", __func__,
791 params_format(params), params_rate(params), best);
792
793 /* MCLK divisor mask = 0xe0 */
794 snd_soc_update_bits(codec, WM8978_CLOCKING, 0xe0, best << 5);
795
796 snd_soc_write(codec, WM8978_AUDIO_INTERFACE, iface_ctl);
797 snd_soc_write(codec, WM8978_ADDITIONAL_CONTROL, add_ctl);
798
799 if (wm8978->sysclk != current_clk_id) {
800 if (wm8978->sysclk == WM8978_PLL)
801 /* Run CODEC from PLL instead of MCLK */
802 snd_soc_update_bits(codec, WM8978_CLOCKING,
803 0x100, 0x100);
804 else
805 /* Clock CODEC directly from MCLK */
806 snd_soc_update_bits(codec, WM8978_CLOCKING, 0x100, 0);
807 }
808
809 return 0;
810}
811
812static int wm8978_mute(struct snd_soc_dai *dai, int mute)
813{
814 struct snd_soc_codec *codec = dai->codec;
815
816 dev_dbg(codec->dev, "%s: %d\n", __func__, mute);
817
818 if (mute)
819 snd_soc_update_bits(codec, WM8978_DAC_CONTROL, 0x40, 0x40);
820 else
821 snd_soc_update_bits(codec, WM8978_DAC_CONTROL, 0x40, 0);
822
823 return 0;
824}
825
826static int wm8978_set_bias_level(struct snd_soc_codec *codec,
827 enum snd_soc_bias_level level)
828{
829 u16 power1 = snd_soc_read(codec, WM8978_POWER_MANAGEMENT_1) & ~3;
830
831 switch (level) {
832 case SND_SOC_BIAS_ON:
833 case SND_SOC_BIAS_PREPARE:
834 power1 |= 1; /* VMID 75k */
835 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1, power1);
836 break;
837 case SND_SOC_BIAS_STANDBY:
838 /* bit 3: enable bias, bit 2: enable I/O tie off buffer */
839 power1 |= 0xc;
840
841 if (codec->bias_level == SND_SOC_BIAS_OFF) {
842 /* Initial cap charge at VMID 5k */
843 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1,
844 power1 | 0x3);
845 mdelay(100);
846 }
847
848 power1 |= 0x2; /* VMID 500k */
849 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1, power1);
850 break;
851 case SND_SOC_BIAS_OFF:
852 /* Preserve PLL - OPCLK may be used by someone */
853 snd_soc_update_bits(codec, WM8978_POWER_MANAGEMENT_1, ~0x20, 0);
854 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_2, 0);
855 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_3, 0);
856 break;
857 }
858
859 dev_dbg(codec->dev, "%s: %d, %x\n", __func__, level, power1);
860
861 codec->bias_level = level;
862 return 0;
863}
864
865#define WM8978_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
866 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
867
868static struct snd_soc_dai_ops wm8978_dai_ops = {
869 .hw_params = wm8978_hw_params,
870 .digital_mute = wm8978_mute,
871 .set_fmt = wm8978_set_dai_fmt,
872 .set_clkdiv = wm8978_set_dai_clkdiv,
873 .set_sysclk = wm8978_set_dai_sysclk,
874};
875
876/* Also supports 12kHz */
877struct snd_soc_dai wm8978_dai = {
878 .name = "WM8978 HiFi",
879 .id = 1,
880 .playback = {
881 .stream_name = "Playback",
882 .channels_min = 1,
883 .channels_max = 2,
884 .rates = SNDRV_PCM_RATE_8000_48000,
885 .formats = WM8978_FORMATS,
886 },
887 .capture = {
888 .stream_name = "Capture",
889 .channels_min = 1,
890 .channels_max = 2,
891 .rates = SNDRV_PCM_RATE_8000_48000,
892 .formats = WM8978_FORMATS,
893 },
894 .ops = &wm8978_dai_ops,
895};
896EXPORT_SYMBOL_GPL(wm8978_dai);
897
898static int wm8978_suspend(struct platform_device *pdev, pm_message_t state)
899{
900 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
901 struct snd_soc_codec *codec = socdev->card->codec;
902
903 wm8978_set_bias_level(codec, SND_SOC_BIAS_OFF);
904 /* Also switch PLL off */
905 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1, 0);
906
907 return 0;
908}
909
910static int wm8978_resume(struct platform_device *pdev)
911{
912 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
913 struct snd_soc_codec *codec = socdev->card->codec;
914 struct wm8978_priv *wm8978 = codec->private_data;
915 int i;
916 u16 *cache = codec->reg_cache;
917
918 /* Sync reg_cache with the hardware */
919 for (i = 0; i < ARRAY_SIZE(wm8978_reg); i++) {
920 if (i == WM8978_RESET)
921 continue;
922 if (cache[i] != wm8978_reg[i])
923 snd_soc_write(codec, i, cache[i]);
924 }
925
926 wm8978_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
927
928 if (wm8978->f_pllout)
929 /* Switch PLL on */
930 snd_soc_update_bits(codec, WM8978_POWER_MANAGEMENT_1, 0x20, 0x20);
931
932 return 0;
933}
934
935static int wm8978_probe(struct platform_device *pdev)
936{
937 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
938 struct snd_soc_codec *codec;
939 int ret = 0;
940
941 if (wm8978_codec == NULL) {
942 dev_err(&pdev->dev, "Codec device not registered\n");
943 return -ENODEV;
944 }
945
946 socdev->card->codec = wm8978_codec;
947 codec = wm8978_codec;
948
949 /* register pcms */
950 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
951 if (ret < 0) {
952 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
953 goto pcm_err;
954 }
955
956 snd_soc_add_controls(codec, wm8978_snd_controls,
957 ARRAY_SIZE(wm8978_snd_controls));
958 wm8978_add_widgets(codec);
959
960pcm_err:
961 return ret;
962}
963
964/* power down chip */
965static int wm8978_remove(struct platform_device *pdev)
966{
967 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
968
969 snd_soc_free_pcms(socdev);
970 snd_soc_dapm_free(socdev);
971
972 return 0;
973}
974
975struct snd_soc_codec_device soc_codec_dev_wm8978 = {
976 .probe = wm8978_probe,
977 .remove = wm8978_remove,
978 .suspend = wm8978_suspend,
979 .resume = wm8978_resume,
980};
981EXPORT_SYMBOL_GPL(soc_codec_dev_wm8978);
982
983/*
984 * These registers contain an "update" bit - bit 8. This means, for example,
985 * that one can write new DAC digital volume for both channels, but only when
986 * the update bit is set, will also the volume be updated - simultaneously for
987 * both channels.
988 */
989static const int update_reg[] = {
990 WM8978_LEFT_DAC_DIGITAL_VOLUME,
991 WM8978_RIGHT_DAC_DIGITAL_VOLUME,
992 WM8978_LEFT_ADC_DIGITAL_VOLUME,
993 WM8978_RIGHT_ADC_DIGITAL_VOLUME,
994 WM8978_LEFT_INP_PGA_CONTROL,
995 WM8978_RIGHT_INP_PGA_CONTROL,
996 WM8978_LOUT1_HP_CONTROL,
997 WM8978_ROUT1_HP_CONTROL,
998 WM8978_LOUT2_SPK_CONTROL,
999 WM8978_ROUT2_SPK_CONTROL,
1000};
1001
1002static __devinit int wm8978_register(struct wm8978_priv *wm8978)
1003{
1004 int ret, i;
1005 struct snd_soc_codec *codec = &wm8978->codec;
1006
1007 if (wm8978_codec) {
1008 dev_err(codec->dev, "Another WM8978 is registered\n");
1009 return -EINVAL;
1010 }
1011
1012 /*
1013 * Set default system clock to PLL, it is more precise, this is also the
1014 * default hardware setting
1015 */
1016 wm8978->sysclk = WM8978_PLL;
1017
1018 mutex_init(&codec->mutex);
1019 INIT_LIST_HEAD(&codec->dapm_widgets);
1020 INIT_LIST_HEAD(&codec->dapm_paths);
1021
1022 codec->private_data = wm8978;
1023 codec->name = "WM8978";
1024 codec->owner = THIS_MODULE;
1025 codec->bias_level = SND_SOC_BIAS_OFF;
1026 codec->set_bias_level = wm8978_set_bias_level;
1027 codec->dai = &wm8978_dai;
1028 codec->num_dai = 1;
1029 codec->reg_cache_size = WM8978_CACHEREGNUM;
1030 codec->reg_cache = &wm8978->reg_cache;
1031
1032 ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_I2C);
1033 if (ret < 0) {
1034 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1035 goto err;
1036 }
1037
1038 memcpy(codec->reg_cache, wm8978_reg, sizeof(wm8978_reg));
1039
1040 /*
1041 * Set the update bit in all registers, that have one. This way all
1042 * writes to those registers will also cause the update bit to be
1043 * written.
1044 */
1045 for (i = 0; i < ARRAY_SIZE(update_reg); i++)
1046 ((u16 *)codec->reg_cache)[update_reg[i]] |= 0x100;
1047
1048 /* Reset the codec */
1049 ret = snd_soc_write(codec, WM8978_RESET, 0);
1050 if (ret < 0) {
1051 dev_err(codec->dev, "Failed to issue reset\n");
1052 goto err;
1053 }
1054
1055 wm8978_dai.dev = codec->dev;
1056
1057 wm8978_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1058
1059 wm8978_codec = codec;
1060
1061 ret = snd_soc_register_codec(codec);
1062 if (ret != 0) {
1063 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
1064 goto err;
1065 }
1066
1067 ret = snd_soc_register_dai(&wm8978_dai);
1068 if (ret != 0) {
1069 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
1070 goto err_codec;
1071 }
1072
1073 return 0;
1074
1075err_codec:
1076 snd_soc_unregister_codec(codec);
1077err:
1078 kfree(wm8978);
1079 return ret;
1080}
1081
1082static __devexit void wm8978_unregister(struct wm8978_priv *wm8978)
1083{
1084 wm8978_set_bias_level(&wm8978->codec, SND_SOC_BIAS_OFF);
1085 snd_soc_unregister_dai(&wm8978_dai);
1086 snd_soc_unregister_codec(&wm8978->codec);
1087 kfree(wm8978);
1088 wm8978_codec = NULL;
1089}
1090
1091static __devinit int wm8978_i2c_probe(struct i2c_client *i2c,
1092 const struct i2c_device_id *id)
1093{
1094 struct wm8978_priv *wm8978;
1095 struct snd_soc_codec *codec;
1096
1097 wm8978 = kzalloc(sizeof(struct wm8978_priv), GFP_KERNEL);
1098 if (wm8978 == NULL)
1099 return -ENOMEM;
1100
1101 codec = &wm8978->codec;
1102 codec->hw_write = (hw_write_t)i2c_master_send;
1103
1104 i2c_set_clientdata(i2c, wm8978);
1105 codec->control_data = i2c;
1106
1107 codec->dev = &i2c->dev;
1108
1109 return wm8978_register(wm8978);
1110}
1111
1112static __devexit int wm8978_i2c_remove(struct i2c_client *client)
1113{
1114 struct wm8978_priv *wm8978 = i2c_get_clientdata(client);
1115 wm8978_unregister(wm8978);
1116 return 0;
1117}
1118
1119static const struct i2c_device_id wm8978_i2c_id[] = {
1120 { "wm8978", 0 },
1121 { }
1122};
1123MODULE_DEVICE_TABLE(i2c, wm8978_i2c_id);
1124
1125static struct i2c_driver wm8978_i2c_driver = {
1126 .driver = {
1127 .name = "WM8978",
1128 .owner = THIS_MODULE,
1129 },
1130 .probe = wm8978_i2c_probe,
1131 .remove = __devexit_p(wm8978_i2c_remove),
1132 .id_table = wm8978_i2c_id,
1133};
1134
1135static int __init wm8978_modinit(void)
1136{
1137 return i2c_add_driver(&wm8978_i2c_driver);
1138}
1139module_init(wm8978_modinit);
1140
1141static void __exit wm8978_exit(void)
1142{
1143 i2c_del_driver(&wm8978_i2c_driver);
1144}
1145module_exit(wm8978_exit);
1146
1147MODULE_DESCRIPTION("ASoC WM8978 codec driver");
1148MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
1149MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8978.h b/sound/soc/codecs/wm8978.h
new file mode 100644
index 000000000000..56ec83270917
--- /dev/null
+++ b/sound/soc/codecs/wm8978.h
@@ -0,0 +1,86 @@
1/*
2 * wm8978.h -- codec driver for WM8978
3 *
4 * Copyright 2009 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
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 __WM8978_H__
12#define __WM8978_H__
13
14/*
15 * Register values.
16 */
17#define WM8978_RESET 0x00
18#define WM8978_POWER_MANAGEMENT_1 0x01
19#define WM8978_POWER_MANAGEMENT_2 0x02
20#define WM8978_POWER_MANAGEMENT_3 0x03
21#define WM8978_AUDIO_INTERFACE 0x04
22#define WM8978_COMPANDING_CONTROL 0x05
23#define WM8978_CLOCKING 0x06
24#define WM8978_ADDITIONAL_CONTROL 0x07
25#define WM8978_GPIO_CONTROL 0x08
26#define WM8978_JACK_DETECT_CONTROL_1 0x09
27#define WM8978_DAC_CONTROL 0x0A
28#define WM8978_LEFT_DAC_DIGITAL_VOLUME 0x0B
29#define WM8978_RIGHT_DAC_DIGITAL_VOLUME 0x0C
30#define WM8978_JACK_DETECT_CONTROL_2 0x0D
31#define WM8978_ADC_CONTROL 0x0E
32#define WM8978_LEFT_ADC_DIGITAL_VOLUME 0x0F
33#define WM8978_RIGHT_ADC_DIGITAL_VOLUME 0x10
34#define WM8978_EQ1 0x12
35#define WM8978_EQ2 0x13
36#define WM8978_EQ3 0x14
37#define WM8978_EQ4 0x15
38#define WM8978_EQ5 0x16
39#define WM8978_DAC_LIMITER_1 0x18
40#define WM8978_DAC_LIMITER_2 0x19
41#define WM8978_NOTCH_FILTER_1 0x1b
42#define WM8978_NOTCH_FILTER_2 0x1c
43#define WM8978_NOTCH_FILTER_3 0x1d
44#define WM8978_NOTCH_FILTER_4 0x1e
45#define WM8978_ALC_CONTROL_1 0x20
46#define WM8978_ALC_CONTROL_2 0x21
47#define WM8978_ALC_CONTROL_3 0x22
48#define WM8978_NOISE_GATE 0x23
49#define WM8978_PLL_N 0x24
50#define WM8978_PLL_K1 0x25
51#define WM8978_PLL_K2 0x26
52#define WM8978_PLL_K3 0x27
53#define WM8978_3D_CONTROL 0x29
54#define WM8978_BEEP_CONTROL 0x2b
55#define WM8978_INPUT_CONTROL 0x2c
56#define WM8978_LEFT_INP_PGA_CONTROL 0x2d
57#define WM8978_RIGHT_INP_PGA_CONTROL 0x2e
58#define WM8978_LEFT_ADC_BOOST_CONTROL 0x2f
59#define WM8978_RIGHT_ADC_BOOST_CONTROL 0x30
60#define WM8978_OUTPUT_CONTROL 0x31
61#define WM8978_LEFT_MIXER_CONTROL 0x32
62#define WM8978_RIGHT_MIXER_CONTROL 0x33
63#define WM8978_LOUT1_HP_CONTROL 0x34
64#define WM8978_ROUT1_HP_CONTROL 0x35
65#define WM8978_LOUT2_SPK_CONTROL 0x36
66#define WM8978_ROUT2_SPK_CONTROL 0x37
67#define WM8978_OUT3_MIXER_CONTROL 0x38
68#define WM8978_OUT4_MIXER_CONTROL 0x39
69
70#define WM8978_CACHEREGNUM 58
71
72/* Clock divider Id's */
73enum wm8978_clk_id {
74 WM8978_OPCLKRATE,
75 WM8978_BCLKDIV,
76};
77
78enum wm8978_sysclk_src {
79 WM8978_PLL,
80 WM8978_MCLK
81};
82
83extern struct snd_soc_dai wm8978_dai;
84extern struct snd_soc_codec_device soc_codec_dev_wm8978;
85
86#endif /* __WM8978_H__ */
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index 341481e0e830..a54dc77b7f34 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -1319,10 +1319,6 @@ static int wm8990_suspend(struct platform_device *pdev, pm_message_t state)
1319 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1319 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1320 struct snd_soc_codec *codec = socdev->card->codec; 1320 struct snd_soc_codec *codec = socdev->card->codec;
1321 1321
1322 /* we only need to suspend if we are a valid card */
1323 if (!codec->card)
1324 return 0;
1325
1326 wm8990_set_bias_level(codec, SND_SOC_BIAS_OFF); 1322 wm8990_set_bias_level(codec, SND_SOC_BIAS_OFF);
1327 return 0; 1323 return 0;
1328} 1324}
@@ -1335,10 +1331,6 @@ static int wm8990_resume(struct platform_device *pdev)
1335 u8 data[2]; 1331 u8 data[2];
1336 u16 *cache = codec->reg_cache; 1332 u16 *cache = codec->reg_cache;
1337 1333
1338 /* we only need to resume if we are a valid card */
1339 if (!codec->card)
1340 return 0;
1341
1342 /* Sync reg_cache with the hardware */ 1334 /* Sync reg_cache with the hardware */
1343 for (i = 0; i < ARRAY_SIZE(wm8990_reg); i++) { 1335 for (i = 0; i < ARRAY_SIZE(wm8990_reg); i++) {
1344 if (i + 1 == WM8990_RESET) 1336 if (i + 1 == WM8990_RESET)
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c
index 2981afae842c..bf022f68b84f 100644
--- a/sound/soc/codecs/wm8993.c
+++ b/sound/soc/codecs/wm8993.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * wm8993.c -- WM8993 ALSA SoC audio driver 2 * wm8993.c -- WM8993 ALSA SoC audio driver
3 * 3 *
4 * Copyright 2009 Wolfson Microelectronics plc 4 * Copyright 2009, 2010 Wolfson Microelectronics plc
5 * 5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 * 7 *
@@ -16,6 +16,7 @@
16#include <linux/delay.h> 16#include <linux/delay.h>
17#include <linux/pm.h> 17#include <linux/pm.h>
18#include <linux/i2c.h> 18#include <linux/i2c.h>
19#include <linux/regulator/consumer.h>
19#include <linux/spi/spi.h> 20#include <linux/spi/spi.h>
20#include <sound/core.h> 21#include <sound/core.h>
21#include <sound/pcm.h> 22#include <sound/pcm.h>
@@ -29,6 +30,16 @@
29#include "wm8993.h" 30#include "wm8993.h"
30#include "wm_hubs.h" 31#include "wm_hubs.h"
31 32
33#define WM8993_NUM_SUPPLIES 6
34static const char *wm8993_supply_names[WM8993_NUM_SUPPLIES] = {
35 "DCVDD",
36 "DBVDD",
37 "AVDD1",
38 "AVDD2",
39 "CPVDD",
40 "SPKVDD",
41};
42
32static u16 wm8993_reg_defaults[WM8993_REGISTER_COUNT] = { 43static u16 wm8993_reg_defaults[WM8993_REGISTER_COUNT] = {
33 0x8993, /* R0 - Software Reset */ 44 0x8993, /* R0 - Software Reset */
34 0x0000, /* R1 - Power Management (1) */ 45 0x0000, /* R1 - Power Management (1) */
@@ -213,7 +224,9 @@ static struct {
213}; 224};
214 225
215struct wm8993_priv { 226struct wm8993_priv {
227 struct wm_hubs_data hubs_data;
216 u16 reg_cache[WM8993_REGISTER_COUNT]; 228 u16 reg_cache[WM8993_REGISTER_COUNT];
229 struct regulator_bulk_data supplies[WM8993_NUM_SUPPLIES];
217 struct wm8993_platform_data pdata; 230 struct wm8993_platform_data pdata;
218 struct snd_soc_codec codec; 231 struct snd_soc_codec codec;
219 int master; 232 int master;
@@ -227,36 +240,9 @@ struct wm8993_priv {
227 int class_w_users; 240 int class_w_users;
228 unsigned int fll_fref; 241 unsigned int fll_fref;
229 unsigned int fll_fout; 242 unsigned int fll_fout;
243 int fll_src;
230}; 244};
231 245
232static unsigned int wm8993_read_hw(struct snd_soc_codec *codec, u8 reg)
233{
234 struct i2c_msg xfer[2];
235 u16 data;
236 int ret;
237 struct i2c_client *i2c = codec->control_data;
238
239 /* Write register */
240 xfer[0].addr = i2c->addr;
241 xfer[0].flags = 0;
242 xfer[0].len = 1;
243 xfer[0].buf = &reg;
244
245 /* Read data */
246 xfer[1].addr = i2c->addr;
247 xfer[1].flags = I2C_M_RD;
248 xfer[1].len = 2;
249 xfer[1].buf = (u8 *)&data;
250
251 ret = i2c_transfer(i2c->adapter, xfer, 2);
252 if (ret != 2) {
253 dev_err(codec->dev, "Failed to read 0x%x: %d\n", reg, ret);
254 return 0;
255 }
256
257 return (data >> 8) | ((data & 0xff) << 8);
258}
259
260static int wm8993_volatile(unsigned int reg) 246static int wm8993_volatile(unsigned int reg)
261{ 247{
262 switch (reg) { 248 switch (reg) {
@@ -271,48 +257,6 @@ static int wm8993_volatile(unsigned int reg)
271 } 257 }
272} 258}
273 259
274static unsigned int wm8993_read(struct snd_soc_codec *codec,
275 unsigned int reg)
276{
277 u16 *reg_cache = codec->reg_cache;
278
279 BUG_ON(reg > WM8993_MAX_REGISTER);
280
281 if (wm8993_volatile(reg))
282 return wm8993_read_hw(codec, reg);
283 else
284 return reg_cache[reg];
285}
286
287static int wm8993_write(struct snd_soc_codec *codec, unsigned int reg,
288 unsigned int value)
289{
290 u16 *reg_cache = codec->reg_cache;
291 u8 data[3];
292 int ret;
293
294 BUG_ON(reg > WM8993_MAX_REGISTER);
295
296 /* data is
297 * D15..D9 WM8993 register offset
298 * D8...D0 register data
299 */
300 data[0] = reg;
301 data[1] = value >> 8;
302 data[2] = value & 0x00ff;
303
304 if (!wm8993_volatile(reg))
305 reg_cache[reg] = value;
306
307 ret = codec->hw_write(codec->control_data, data, 3);
308
309 if (ret == 3)
310 return 0;
311 if (ret < 0)
312 return ret;
313 return -EIO;
314}
315
316struct _fll_div { 260struct _fll_div {
317 u16 fll_fratio; 261 u16 fll_fratio;
318 u16 fll_outdiv; 262 u16 fll_outdiv;
@@ -441,9 +385,9 @@ static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
441 wm8993->fll_fref = 0; 385 wm8993->fll_fref = 0;
442 wm8993->fll_fout = 0; 386 wm8993->fll_fout = 0;
443 387
444 reg1 = wm8993_read(codec, WM8993_FLL_CONTROL_1); 388 reg1 = snd_soc_read(codec, WM8993_FLL_CONTROL_1);
445 reg1 &= ~WM8993_FLL_ENA; 389 reg1 &= ~WM8993_FLL_ENA;
446 wm8993_write(codec, WM8993_FLL_CONTROL_1, reg1); 390 snd_soc_write(codec, WM8993_FLL_CONTROL_1, reg1);
447 391
448 return 0; 392 return 0;
449 } 393 }
@@ -452,7 +396,7 @@ static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
452 if (ret != 0) 396 if (ret != 0)
453 return ret; 397 return ret;
454 398
455 reg5 = wm8993_read(codec, WM8993_FLL_CONTROL_5); 399 reg5 = snd_soc_read(codec, WM8993_FLL_CONTROL_5);
456 reg5 &= ~WM8993_FLL_CLK_SRC_MASK; 400 reg5 &= ~WM8993_FLL_CLK_SRC_MASK;
457 401
458 switch (fll_id) { 402 switch (fll_id) {
@@ -474,38 +418,39 @@ static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
474 418
475 /* Any FLL configuration change requires that the FLL be 419 /* Any FLL configuration change requires that the FLL be
476 * disabled first. */ 420 * disabled first. */
477 reg1 = wm8993_read(codec, WM8993_FLL_CONTROL_1); 421 reg1 = snd_soc_read(codec, WM8993_FLL_CONTROL_1);
478 reg1 &= ~WM8993_FLL_ENA; 422 reg1 &= ~WM8993_FLL_ENA;
479 wm8993_write(codec, WM8993_FLL_CONTROL_1, reg1); 423 snd_soc_write(codec, WM8993_FLL_CONTROL_1, reg1);
480 424
481 /* Apply the configuration */ 425 /* Apply the configuration */
482 if (fll_div.k) 426 if (fll_div.k)
483 reg1 |= WM8993_FLL_FRAC_MASK; 427 reg1 |= WM8993_FLL_FRAC_MASK;
484 else 428 else
485 reg1 &= ~WM8993_FLL_FRAC_MASK; 429 reg1 &= ~WM8993_FLL_FRAC_MASK;
486 wm8993_write(codec, WM8993_FLL_CONTROL_1, reg1); 430 snd_soc_write(codec, WM8993_FLL_CONTROL_1, reg1);
487 431
488 wm8993_write(codec, WM8993_FLL_CONTROL_2, 432 snd_soc_write(codec, WM8993_FLL_CONTROL_2,
489 (fll_div.fll_outdiv << WM8993_FLL_OUTDIV_SHIFT) | 433 (fll_div.fll_outdiv << WM8993_FLL_OUTDIV_SHIFT) |
490 (fll_div.fll_fratio << WM8993_FLL_FRATIO_SHIFT)); 434 (fll_div.fll_fratio << WM8993_FLL_FRATIO_SHIFT));
491 wm8993_write(codec, WM8993_FLL_CONTROL_3, fll_div.k); 435 snd_soc_write(codec, WM8993_FLL_CONTROL_3, fll_div.k);
492 436
493 reg4 = wm8993_read(codec, WM8993_FLL_CONTROL_4); 437 reg4 = snd_soc_read(codec, WM8993_FLL_CONTROL_4);
494 reg4 &= ~WM8993_FLL_N_MASK; 438 reg4 &= ~WM8993_FLL_N_MASK;
495 reg4 |= fll_div.n << WM8993_FLL_N_SHIFT; 439 reg4 |= fll_div.n << WM8993_FLL_N_SHIFT;
496 wm8993_write(codec, WM8993_FLL_CONTROL_4, reg4); 440 snd_soc_write(codec, WM8993_FLL_CONTROL_4, reg4);
497 441
498 reg5 &= ~WM8993_FLL_CLK_REF_DIV_MASK; 442 reg5 &= ~WM8993_FLL_CLK_REF_DIV_MASK;
499 reg5 |= fll_div.fll_clk_ref_div << WM8993_FLL_CLK_REF_DIV_SHIFT; 443 reg5 |= fll_div.fll_clk_ref_div << WM8993_FLL_CLK_REF_DIV_SHIFT;
500 wm8993_write(codec, WM8993_FLL_CONTROL_5, reg5); 444 snd_soc_write(codec, WM8993_FLL_CONTROL_5, reg5);
501 445
502 /* Enable the FLL */ 446 /* Enable the FLL */
503 wm8993_write(codec, WM8993_FLL_CONTROL_1, reg1 | WM8993_FLL_ENA); 447 snd_soc_write(codec, WM8993_FLL_CONTROL_1, reg1 | WM8993_FLL_ENA);
504 448
505 dev_dbg(codec->dev, "FLL enabled at %dHz->%dHz\n", Fref, Fout); 449 dev_dbg(codec->dev, "FLL enabled at %dHz->%dHz\n", Fref, Fout);
506 450
507 wm8993->fll_fref = Fref; 451 wm8993->fll_fref = Fref;
508 wm8993->fll_fout = Fout; 452 wm8993->fll_fout = Fout;
453 wm8993->fll_src = source;
509 454
510 return 0; 455 return 0;
511} 456}
@@ -520,7 +465,7 @@ static int configure_clock(struct snd_soc_codec *codec)
520 case WM8993_SYSCLK_MCLK: 465 case WM8993_SYSCLK_MCLK:
521 dev_dbg(codec->dev, "Using %dHz MCLK\n", wm8993->mclk_rate); 466 dev_dbg(codec->dev, "Using %dHz MCLK\n", wm8993->mclk_rate);
522 467
523 reg = wm8993_read(codec, WM8993_CLOCKING_2); 468 reg = snd_soc_read(codec, WM8993_CLOCKING_2);
524 reg &= ~(WM8993_MCLK_DIV | WM8993_SYSCLK_SRC); 469 reg &= ~(WM8993_MCLK_DIV | WM8993_SYSCLK_SRC);
525 if (wm8993->mclk_rate > 13500000) { 470 if (wm8993->mclk_rate > 13500000) {
526 reg |= WM8993_MCLK_DIV; 471 reg |= WM8993_MCLK_DIV;
@@ -529,14 +474,14 @@ static int configure_clock(struct snd_soc_codec *codec)
529 reg &= ~WM8993_MCLK_DIV; 474 reg &= ~WM8993_MCLK_DIV;
530 wm8993->sysclk_rate = wm8993->mclk_rate; 475 wm8993->sysclk_rate = wm8993->mclk_rate;
531 } 476 }
532 wm8993_write(codec, WM8993_CLOCKING_2, reg); 477 snd_soc_write(codec, WM8993_CLOCKING_2, reg);
533 break; 478 break;
534 479
535 case WM8993_SYSCLK_FLL: 480 case WM8993_SYSCLK_FLL:
536 dev_dbg(codec->dev, "Using %dHz FLL clock\n", 481 dev_dbg(codec->dev, "Using %dHz FLL clock\n",
537 wm8993->fll_fout); 482 wm8993->fll_fout);
538 483
539 reg = wm8993_read(codec, WM8993_CLOCKING_2); 484 reg = snd_soc_read(codec, WM8993_CLOCKING_2);
540 reg |= WM8993_SYSCLK_SRC; 485 reg |= WM8993_SYSCLK_SRC;
541 if (wm8993->fll_fout > 13500000) { 486 if (wm8993->fll_fout > 13500000) {
542 reg |= WM8993_MCLK_DIV; 487 reg |= WM8993_MCLK_DIV;
@@ -545,7 +490,7 @@ static int configure_clock(struct snd_soc_codec *codec)
545 reg &= ~WM8993_MCLK_DIV; 490 reg &= ~WM8993_MCLK_DIV;
546 wm8993->sysclk_rate = wm8993->fll_fout; 491 wm8993->sysclk_rate = wm8993->fll_fout;
547 } 492 }
548 wm8993_write(codec, WM8993_CLOCKING_2, reg); 493 snd_soc_write(codec, WM8993_CLOCKING_2, reg);
549 break; 494 break;
550 495
551 default: 496 default:
@@ -978,10 +923,33 @@ static const struct snd_soc_dapm_route routes[] = {
978 { "Right Headphone Mux", "DAC", "DACR" }, 923 { "Right Headphone Mux", "DAC", "DACR" },
979}; 924};
980 925
926static void wm8993_cache_restore(struct snd_soc_codec *codec)
927{
928 u16 *cache = codec->reg_cache;
929 int i;
930
931 if (!codec->cache_sync)
932 return;
933
934 /* Reenable hardware writes */
935 codec->cache_only = 0;
936
937 /* Restore the register settings */
938 for (i = 1; i < WM8993_MAX_REGISTER; i++) {
939 if (cache[i] == wm8993_reg_defaults[i])
940 continue;
941 snd_soc_write(codec, i, cache[i]);
942 }
943
944 /* We're in sync again */
945 codec->cache_sync = 0;
946}
947
981static int wm8993_set_bias_level(struct snd_soc_codec *codec, 948static int wm8993_set_bias_level(struct snd_soc_codec *codec,
982 enum snd_soc_bias_level level) 949 enum snd_soc_bias_level level)
983{ 950{
984 struct wm8993_priv *wm8993 = codec->private_data; 951 struct wm8993_priv *wm8993 = codec->private_data;
952 int ret;
985 953
986 switch (level) { 954 switch (level) {
987 case SND_SOC_BIAS_ON: 955 case SND_SOC_BIAS_ON:
@@ -995,6 +963,18 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec,
995 963
996 case SND_SOC_BIAS_STANDBY: 964 case SND_SOC_BIAS_STANDBY:
997 if (codec->bias_level == SND_SOC_BIAS_OFF) { 965 if (codec->bias_level == SND_SOC_BIAS_OFF) {
966 ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies),
967 wm8993->supplies);
968 if (ret != 0)
969 return ret;
970
971 wm8993_cache_restore(codec);
972
973 /* Tune DC servo configuration */
974 snd_soc_write(codec, 0x44, 3);
975 snd_soc_write(codec, 0x56, 3);
976 snd_soc_write(codec, 0x44, 0);
977
998 /* Bring up VMID with fast soft start */ 978 /* Bring up VMID with fast soft start */
999 snd_soc_update_bits(codec, WM8993_ANTIPOP2, 979 snd_soc_update_bits(codec, WM8993_ANTIPOP2,
1000 WM8993_STARTUP_BIAS_ENA | 980 WM8993_STARTUP_BIAS_ENA |
@@ -1042,6 +1022,18 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec,
1042 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1, 1022 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
1043 WM8993_VMID_SEL_MASK | WM8993_BIAS_ENA, 1023 WM8993_VMID_SEL_MASK | WM8993_BIAS_ENA,
1044 0); 1024 0);
1025
1026#ifdef CONFIG_REGULATOR
1027 /* Post 2.6.34 we will be able to get a callback when
1028 * the regulators are disabled which we can use but
1029 * for now just assume that the power will be cut if
1030 * the regulator API is in use.
1031 */
1032 codec->cache_sync = 1;
1033#endif
1034
1035 regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies),
1036 wm8993->supplies);
1045 break; 1037 break;
1046 } 1038 }
1047 1039
@@ -1075,8 +1067,8 @@ static int wm8993_set_dai_fmt(struct snd_soc_dai *dai,
1075{ 1067{
1076 struct snd_soc_codec *codec = dai->codec; 1068 struct snd_soc_codec *codec = dai->codec;
1077 struct wm8993_priv *wm8993 = codec->private_data; 1069 struct wm8993_priv *wm8993 = codec->private_data;
1078 unsigned int aif1 = wm8993_read(codec, WM8993_AUDIO_INTERFACE_1); 1070 unsigned int aif1 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_1);
1079 unsigned int aif4 = wm8993_read(codec, WM8993_AUDIO_INTERFACE_4); 1071 unsigned int aif4 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_4);
1080 1072
1081 aif1 &= ~(WM8993_BCLK_DIR | WM8993_AIF_BCLK_INV | 1073 aif1 &= ~(WM8993_BCLK_DIR | WM8993_AIF_BCLK_INV |
1082 WM8993_AIF_LRCLK_INV | WM8993_AIF_FMT_MASK); 1074 WM8993_AIF_LRCLK_INV | WM8993_AIF_FMT_MASK);
@@ -1159,8 +1151,8 @@ static int wm8993_set_dai_fmt(struct snd_soc_dai *dai,
1159 return -EINVAL; 1151 return -EINVAL;
1160 } 1152 }
1161 1153
1162 wm8993_write(codec, WM8993_AUDIO_INTERFACE_1, aif1); 1154 snd_soc_write(codec, WM8993_AUDIO_INTERFACE_1, aif1);
1163 wm8993_write(codec, WM8993_AUDIO_INTERFACE_4, aif4); 1155 snd_soc_write(codec, WM8993_AUDIO_INTERFACE_4, aif4);
1164 1156
1165 return 0; 1157 return 0;
1166} 1158}
@@ -1174,16 +1166,16 @@ static int wm8993_hw_params(struct snd_pcm_substream *substream,
1174 int ret, i, best, best_val, cur_val; 1166 int ret, i, best, best_val, cur_val;
1175 unsigned int clocking1, clocking3, aif1, aif4; 1167 unsigned int clocking1, clocking3, aif1, aif4;
1176 1168
1177 clocking1 = wm8993_read(codec, WM8993_CLOCKING_1); 1169 clocking1 = snd_soc_read(codec, WM8993_CLOCKING_1);
1178 clocking1 &= ~WM8993_BCLK_DIV_MASK; 1170 clocking1 &= ~WM8993_BCLK_DIV_MASK;
1179 1171
1180 clocking3 = wm8993_read(codec, WM8993_CLOCKING_3); 1172 clocking3 = snd_soc_read(codec, WM8993_CLOCKING_3);
1181 clocking3 &= ~(WM8993_CLK_SYS_RATE_MASK | WM8993_SAMPLE_RATE_MASK); 1173 clocking3 &= ~(WM8993_CLK_SYS_RATE_MASK | WM8993_SAMPLE_RATE_MASK);
1182 1174
1183 aif1 = wm8993_read(codec, WM8993_AUDIO_INTERFACE_1); 1175 aif1 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_1);
1184 aif1 &= ~WM8993_AIF_WL_MASK; 1176 aif1 &= ~WM8993_AIF_WL_MASK;
1185 1177
1186 aif4 = wm8993_read(codec, WM8993_AUDIO_INTERFACE_4); 1178 aif4 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_4);
1187 aif4 &= ~WM8993_LRCLK_RATE_MASK; 1179 aif4 &= ~WM8993_LRCLK_RATE_MASK;
1188 1180
1189 /* What BCLK do we need? */ 1181 /* What BCLK do we need? */
@@ -1276,14 +1268,14 @@ static int wm8993_hw_params(struct snd_pcm_substream *substream,
1276 dev_dbg(codec->dev, "LRCLK_RATE is %d\n", wm8993->bclk / wm8993->fs); 1268 dev_dbg(codec->dev, "LRCLK_RATE is %d\n", wm8993->bclk / wm8993->fs);
1277 aif4 |= wm8993->bclk / wm8993->fs; 1269 aif4 |= wm8993->bclk / wm8993->fs;
1278 1270
1279 wm8993_write(codec, WM8993_CLOCKING_1, clocking1); 1271 snd_soc_write(codec, WM8993_CLOCKING_1, clocking1);
1280 wm8993_write(codec, WM8993_CLOCKING_3, clocking3); 1272 snd_soc_write(codec, WM8993_CLOCKING_3, clocking3);
1281 wm8993_write(codec, WM8993_AUDIO_INTERFACE_1, aif1); 1273 snd_soc_write(codec, WM8993_AUDIO_INTERFACE_1, aif1);
1282 wm8993_write(codec, WM8993_AUDIO_INTERFACE_4, aif4); 1274 snd_soc_write(codec, WM8993_AUDIO_INTERFACE_4, aif4);
1283 1275
1284 /* ReTune Mobile? */ 1276 /* ReTune Mobile? */
1285 if (wm8993->pdata.num_retune_configs) { 1277 if (wm8993->pdata.num_retune_configs) {
1286 u16 eq1 = wm8993_read(codec, WM8993_EQ1); 1278 u16 eq1 = snd_soc_read(codec, WM8993_EQ1);
1287 struct wm8993_retune_mobile_setting *s; 1279 struct wm8993_retune_mobile_setting *s;
1288 1280
1289 best = 0; 1281 best = 0;
@@ -1306,7 +1298,7 @@ static int wm8993_hw_params(struct snd_pcm_substream *substream,
1306 snd_soc_update_bits(codec, WM8993_EQ1, WM8993_EQ_ENA, 0); 1298 snd_soc_update_bits(codec, WM8993_EQ1, WM8993_EQ_ENA, 0);
1307 1299
1308 for (i = 1; i < ARRAY_SIZE(s->config); i++) 1300 for (i = 1; i < ARRAY_SIZE(s->config); i++)
1309 wm8993_write(codec, WM8993_EQ1 + i, s->config[i]); 1301 snd_soc_write(codec, WM8993_EQ1 + i, s->config[i]);
1310 1302
1311 snd_soc_update_bits(codec, WM8993_EQ1, WM8993_EQ_ENA, eq1); 1303 snd_soc_update_bits(codec, WM8993_EQ1, WM8993_EQ_ENA, eq1);
1312 } 1304 }
@@ -1319,14 +1311,14 @@ static int wm8993_digital_mute(struct snd_soc_dai *codec_dai, int mute)
1319 struct snd_soc_codec *codec = codec_dai->codec; 1311 struct snd_soc_codec *codec = codec_dai->codec;
1320 unsigned int reg; 1312 unsigned int reg;
1321 1313
1322 reg = wm8993_read(codec, WM8993_DAC_CTRL); 1314 reg = snd_soc_read(codec, WM8993_DAC_CTRL);
1323 1315
1324 if (mute) 1316 if (mute)
1325 reg |= WM8993_DAC_MUTE; 1317 reg |= WM8993_DAC_MUTE;
1326 else 1318 else
1327 reg &= ~WM8993_DAC_MUTE; 1319 reg &= ~WM8993_DAC_MUTE;
1328 1320
1329 wm8993_write(codec, WM8993_DAC_CTRL, reg); 1321 snd_soc_write(codec, WM8993_DAC_CTRL, reg);
1330 1322
1331 return 0; 1323 return 0;
1332} 1324}
@@ -1480,9 +1472,66 @@ static int wm8993_remove(struct platform_device *pdev)
1480 return 0; 1472 return 0;
1481} 1473}
1482 1474
1475#ifdef CONFIG_PM
1476static int wm8993_suspend(struct platform_device *pdev, pm_message_t state)
1477{
1478 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1479 struct snd_soc_codec *codec = socdev->card->codec;
1480 struct wm8993_priv *wm8993 = codec->private_data;
1481 int fll_fout = wm8993->fll_fout;
1482 int fll_fref = wm8993->fll_fref;
1483 int ret;
1484
1485 /* Stop the FLL in an orderly fashion */
1486 ret = wm8993_set_fll(codec->dai, 0, 0, 0, 0);
1487 if (ret != 0) {
1488 dev_err(&pdev->dev, "Failed to stop FLL\n");
1489 return ret;
1490 }
1491
1492 wm8993->fll_fout = fll_fout;
1493 wm8993->fll_fref = fll_fref;
1494
1495 wm8993_set_bias_level(codec, SND_SOC_BIAS_OFF);
1496
1497 return 0;
1498}
1499
1500static int wm8993_resume(struct platform_device *pdev)
1501{
1502 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1503 struct snd_soc_codec *codec = socdev->card->codec;
1504 struct wm8993_priv *wm8993 = codec->private_data;
1505 int ret;
1506
1507 wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1508
1509 /* Restart the FLL? */
1510 if (wm8993->fll_fout) {
1511 int fll_fout = wm8993->fll_fout;
1512 int fll_fref = wm8993->fll_fref;
1513
1514 wm8993->fll_fref = 0;
1515 wm8993->fll_fout = 0;
1516
1517 ret = wm8993_set_fll(codec->dai, 0, wm8993->fll_src,
1518 fll_fref, fll_fout);
1519 if (ret != 0)
1520 dev_err(codec->dev, "Failed to restart FLL\n");
1521 }
1522
1523 return 0;
1524}
1525#else
1526#define wm8993_suspend NULL
1527#define wm8993_resume NULL
1528#endif
1529
1483struct snd_soc_codec_device soc_codec_dev_wm8993 = { 1530struct snd_soc_codec_device soc_codec_dev_wm8993 = {
1484 .probe = wm8993_probe, 1531 .probe = wm8993_probe,
1485 .remove = wm8993_remove, 1532 .remove = wm8993_remove,
1533 .suspend = wm8993_suspend,
1534 .resume = wm8993_resume,
1486}; 1535};
1487EXPORT_SYMBOL_GPL(soc_codec_dev_wm8993); 1536EXPORT_SYMBOL_GPL(soc_codec_dev_wm8993);
1488 1537
@@ -1493,6 +1542,7 @@ static int wm8993_i2c_probe(struct i2c_client *i2c,
1493 struct snd_soc_codec *codec; 1542 struct snd_soc_codec *codec;
1494 unsigned int val; 1543 unsigned int val;
1495 int ret; 1544 int ret;
1545 int i;
1496 1546
1497 if (wm8993_codec) { 1547 if (wm8993_codec) {
1498 dev_err(&i2c->dev, "A WM8993 is already registered\n"); 1548 dev_err(&i2c->dev, "A WM8993 is already registered\n");
@@ -1513,9 +1563,7 @@ static int wm8993_i2c_probe(struct i2c_client *i2c,
1513 INIT_LIST_HEAD(&codec->dapm_paths); 1563 INIT_LIST_HEAD(&codec->dapm_paths);
1514 1564
1515 codec->name = "WM8993"; 1565 codec->name = "WM8993";
1516 codec->read = wm8993_read; 1566 codec->volatile_register = wm8993_volatile;
1517 codec->write = wm8993_write;
1518 codec->hw_write = (hw_write_t)i2c_master_send;
1519 codec->reg_cache = wm8993->reg_cache; 1567 codec->reg_cache = wm8993->reg_cache;
1520 codec->reg_cache_size = ARRAY_SIZE(wm8993->reg_cache); 1568 codec->reg_cache_size = ARRAY_SIZE(wm8993->reg_cache);
1521 codec->bias_level = SND_SOC_BIAS_OFF; 1569 codec->bias_level = SND_SOC_BIAS_OFF;
@@ -1524,25 +1572,53 @@ static int wm8993_i2c_probe(struct i2c_client *i2c,
1524 codec->num_dai = 1; 1572 codec->num_dai = 1;
1525 codec->private_data = wm8993; 1573 codec->private_data = wm8993;
1526 1574
1575 wm8993->hubs_data.hp_startup_mode = 1;
1576 wm8993->hubs_data.dcs_codes = -2;
1577
1527 memcpy(wm8993->reg_cache, wm8993_reg_defaults, 1578 memcpy(wm8993->reg_cache, wm8993_reg_defaults,
1528 sizeof(wm8993->reg_cache)); 1579 sizeof(wm8993->reg_cache));
1529 1580
1581 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
1582 if (ret != 0) {
1583 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1584 goto err;
1585 }
1586
1530 i2c_set_clientdata(i2c, wm8993); 1587 i2c_set_clientdata(i2c, wm8993);
1531 codec->control_data = i2c; 1588 codec->control_data = i2c;
1532 wm8993_codec = codec; 1589 wm8993_codec = codec;
1533 1590
1534 codec->dev = &i2c->dev; 1591 codec->dev = &i2c->dev;
1535 1592
1536 val = wm8993_read_hw(codec, WM8993_SOFTWARE_RESET); 1593 for (i = 0; i < ARRAY_SIZE(wm8993->supplies); i++)
1594 wm8993->supplies[i].supply = wm8993_supply_names[i];
1595
1596 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8993->supplies),
1597 wm8993->supplies);
1598 if (ret != 0) {
1599 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
1600 goto err;
1601 }
1602
1603 ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies),
1604 wm8993->supplies);
1605 if (ret != 0) {
1606 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
1607 goto err_get;
1608 }
1609
1610 val = snd_soc_read(codec, WM8993_SOFTWARE_RESET);
1537 if (val != wm8993_reg_defaults[WM8993_SOFTWARE_RESET]) { 1611 if (val != wm8993_reg_defaults[WM8993_SOFTWARE_RESET]) {
1538 dev_err(codec->dev, "Invalid ID register value %x\n", val); 1612 dev_err(codec->dev, "Invalid ID register value %x\n", val);
1539 ret = -EINVAL; 1613 ret = -EINVAL;
1540 goto err; 1614 goto err_enable;
1541 } 1615 }
1542 1616
1543 ret = wm8993_write(codec, WM8993_SOFTWARE_RESET, 0xffff); 1617 ret = snd_soc_write(codec, WM8993_SOFTWARE_RESET, 0xffff);
1544 if (ret != 0) 1618 if (ret != 0)
1545 goto err; 1619 goto err_enable;
1620
1621 codec->cache_only = 1;
1546 1622
1547 /* By default we're using the output mixers */ 1623 /* By default we're using the output mixers */
1548 wm8993->class_w_users = 2; 1624 wm8993->class_w_users = 2;
@@ -1572,7 +1648,7 @@ static int wm8993_i2c_probe(struct i2c_client *i2c,
1572 1648
1573 ret = wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1649 ret = wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1574 if (ret != 0) 1650 if (ret != 0)
1575 goto err; 1651 goto err_enable;
1576 1652
1577 wm8993_dai.dev = codec->dev; 1653 wm8993_dai.dev = codec->dev;
1578 1654
@@ -1586,6 +1662,10 @@ static int wm8993_i2c_probe(struct i2c_client *i2c,
1586 1662
1587err_bias: 1663err_bias:
1588 wm8993_set_bias_level(codec, SND_SOC_BIAS_OFF); 1664 wm8993_set_bias_level(codec, SND_SOC_BIAS_OFF);
1665err_enable:
1666 regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
1667err_get:
1668 regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
1589err: 1669err:
1590 wm8993_codec = NULL; 1670 wm8993_codec = NULL;
1591 kfree(wm8993); 1671 kfree(wm8993);
@@ -1600,6 +1680,7 @@ static int wm8993_i2c_remove(struct i2c_client *client)
1600 snd_soc_unregister_dai(&wm8993_dai); 1680 snd_soc_unregister_dai(&wm8993_dai);
1601 1681
1602 wm8993_set_bias_level(&wm8993->codec, SND_SOC_BIAS_OFF); 1682 wm8993_set_bias_level(&wm8993->codec, SND_SOC_BIAS_OFF);
1683 regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
1603 kfree(wm8993); 1684 kfree(wm8993);
1604 1685
1605 return 0; 1686 return 0;
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
new file mode 100644
index 000000000000..29f3771c33a4
--- /dev/null
+++ b/sound/soc/codecs/wm8994.c
@@ -0,0 +1,3867 @@
1/*
2 * wm8994.c -- WM8994 ALSA SoC Audio driver
3 *
4 * Copyright 2009 Wolfson Microelectronics plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.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 version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/module.h>
15#include <linux/moduleparam.h>
16#include <linux/init.h>
17#include <linux/delay.h>
18#include <linux/pm.h>
19#include <linux/i2c.h>
20#include <linux/platform_device.h>
21#include <linux/regulator/consumer.h>
22#include <sound/core.h>
23#include <sound/pcm.h>
24#include <sound/pcm_params.h>
25#include <sound/soc.h>
26#include <sound/soc-dapm.h>
27#include <sound/initval.h>
28#include <sound/tlv.h>
29
30#include <linux/mfd/wm8994/core.h>
31#include <linux/mfd/wm8994/registers.h>
32#include <linux/mfd/wm8994/pdata.h>
33#include <linux/mfd/wm8994/gpio.h>
34
35#include "wm8994.h"
36#include "wm_hubs.h"
37
38static struct snd_soc_codec *wm8994_codec;
39struct snd_soc_codec_device soc_codec_dev_wm8994;
40
41struct fll_config {
42 int src;
43 int in;
44 int out;
45};
46
47#define WM8994_NUM_DRC 3
48#define WM8994_NUM_EQ 3
49
50static int wm8994_drc_base[] = {
51 WM8994_AIF1_DRC1_1,
52 WM8994_AIF1_DRC2_1,
53 WM8994_AIF2_DRC_1,
54};
55
56static int wm8994_retune_mobile_base[] = {
57 WM8994_AIF1_DAC1_EQ_GAINS_1,
58 WM8994_AIF1_DAC2_EQ_GAINS_1,
59 WM8994_AIF2_EQ_GAINS_1,
60};
61
62#define WM8994_REG_CACHE_SIZE 0x621
63
64/* codec private data */
65struct wm8994_priv {
66 struct wm_hubs_data hubs;
67 struct snd_soc_codec codec;
68 u16 reg_cache[WM8994_REG_CACHE_SIZE + 1];
69 int sysclk[2];
70 int sysclk_rate[2];
71 int mclk[2];
72 int aifclk[2];
73 struct fll_config fll[2], fll_suspend[2];
74
75 int dac_rates[2];
76 int lrclk_shared[2];
77
78 /* Platform dependant DRC configuration */
79 const char **drc_texts;
80 int drc_cfg[WM8994_NUM_DRC];
81 struct soc_enum drc_enum;
82
83 /* Platform dependant ReTune mobile configuration */
84 int num_retune_mobile_texts;
85 const char **retune_mobile_texts;
86 int retune_mobile_cfg[WM8994_NUM_EQ];
87 struct soc_enum retune_mobile_enum;
88
89 struct wm8994_pdata *pdata;
90};
91
92static struct {
93 unsigned short readable; /* Mask of readable bits */
94 unsigned short writable; /* Mask of writable bits */
95 unsigned short vol; /* Mask of volatile bits */
96} access_masks[] = {
97 { 0xFFFF, 0xFFFF, 0x0000 }, /* R0 - Software Reset */
98 { 0x3B37, 0x3B37, 0x0000 }, /* R1 - Power Management (1) */
99 { 0x6BF0, 0x6BF0, 0x0000 }, /* R2 - Power Management (2) */
100 { 0x3FF0, 0x3FF0, 0x0000 }, /* R3 - Power Management (3) */
101 { 0x3F3F, 0x3F3F, 0x0000 }, /* R4 - Power Management (4) */
102 { 0x3F0F, 0x3F0F, 0x0000 }, /* R5 - Power Management (5) */
103 { 0x003F, 0x003F, 0x0000 }, /* R6 - Power Management (6) */
104 { 0x0000, 0x0000, 0x0000 }, /* R7 */
105 { 0x0000, 0x0000, 0x0000 }, /* R8 */
106 { 0x0000, 0x0000, 0x0000 }, /* R9 */
107 { 0x0000, 0x0000, 0x0000 }, /* R10 */
108 { 0x0000, 0x0000, 0x0000 }, /* R11 */
109 { 0x0000, 0x0000, 0x0000 }, /* R12 */
110 { 0x0000, 0x0000, 0x0000 }, /* R13 */
111 { 0x0000, 0x0000, 0x0000 }, /* R14 */
112 { 0x0000, 0x0000, 0x0000 }, /* R15 */
113 { 0x0000, 0x0000, 0x0000 }, /* R16 */
114 { 0x0000, 0x0000, 0x0000 }, /* R17 */
115 { 0x0000, 0x0000, 0x0000 }, /* R18 */
116 { 0x0000, 0x0000, 0x0000 }, /* R19 */
117 { 0x0000, 0x0000, 0x0000 }, /* R20 */
118 { 0x01C0, 0x01C0, 0x0000 }, /* R21 - Input Mixer (1) */
119 { 0x0000, 0x0000, 0x0000 }, /* R22 */
120 { 0x0000, 0x0000, 0x0000 }, /* R23 */
121 { 0x00DF, 0x01DF, 0x0000 }, /* R24 - Left Line Input 1&2 Volume */
122 { 0x00DF, 0x01DF, 0x0000 }, /* R25 - Left Line Input 3&4 Volume */
123 { 0x00DF, 0x01DF, 0x0000 }, /* R26 - Right Line Input 1&2 Volume */
124 { 0x00DF, 0x01DF, 0x0000 }, /* R27 - Right Line Input 3&4 Volume */
125 { 0x00FF, 0x01FF, 0x0000 }, /* R28 - Left Output Volume */
126 { 0x00FF, 0x01FF, 0x0000 }, /* R29 - Right Output Volume */
127 { 0x0077, 0x0077, 0x0000 }, /* R30 - Line Outputs Volume */
128 { 0x0030, 0x0030, 0x0000 }, /* R31 - HPOUT2 Volume */
129 { 0x00FF, 0x01FF, 0x0000 }, /* R32 - Left OPGA Volume */
130 { 0x00FF, 0x01FF, 0x0000 }, /* R33 - Right OPGA Volume */
131 { 0x007F, 0x007F, 0x0000 }, /* R34 - SPKMIXL Attenuation */
132 { 0x017F, 0x017F, 0x0000 }, /* R35 - SPKMIXR Attenuation */
133 { 0x003F, 0x003F, 0x0000 }, /* R36 - SPKOUT Mixers */
134 { 0x003F, 0x003F, 0x0000 }, /* R37 - ClassD */
135 { 0x00FF, 0x01FF, 0x0000 }, /* R38 - Speaker Volume Left */
136 { 0x00FF, 0x01FF, 0x0000 }, /* R39 - Speaker Volume Right */
137 { 0x00FF, 0x00FF, 0x0000 }, /* R40 - Input Mixer (2) */
138 { 0x01B7, 0x01B7, 0x0000 }, /* R41 - Input Mixer (3) */
139 { 0x01B7, 0x01B7, 0x0000 }, /* R42 - Input Mixer (4) */
140 { 0x01C7, 0x01C7, 0x0000 }, /* R43 - Input Mixer (5) */
141 { 0x01C7, 0x01C7, 0x0000 }, /* R44 - Input Mixer (6) */
142 { 0x01FF, 0x01FF, 0x0000 }, /* R45 - Output Mixer (1) */
143 { 0x01FF, 0x01FF, 0x0000 }, /* R46 - Output Mixer (2) */
144 { 0x0FFF, 0x0FFF, 0x0000 }, /* R47 - Output Mixer (3) */
145 { 0x0FFF, 0x0FFF, 0x0000 }, /* R48 - Output Mixer (4) */
146 { 0x0FFF, 0x0FFF, 0x0000 }, /* R49 - Output Mixer (5) */
147 { 0x0FFF, 0x0FFF, 0x0000 }, /* R50 - Output Mixer (6) */
148 { 0x0038, 0x0038, 0x0000 }, /* R51 - HPOUT2 Mixer */
149 { 0x0077, 0x0077, 0x0000 }, /* R52 - Line Mixer (1) */
150 { 0x0077, 0x0077, 0x0000 }, /* R53 - Line Mixer (2) */
151 { 0x03FF, 0x03FF, 0x0000 }, /* R54 - Speaker Mixer */
152 { 0x00C1, 0x00C1, 0x0000 }, /* R55 - Additional Control */
153 { 0x00F0, 0x00F0, 0x0000 }, /* R56 - AntiPOP (1) */
154 { 0x01EF, 0x01EF, 0x0000 }, /* R57 - AntiPOP (2) */
155 { 0x00FF, 0x00FF, 0x0000 }, /* R58 - MICBIAS */
156 { 0x000F, 0x000F, 0x0000 }, /* R59 - LDO 1 */
157 { 0x0007, 0x0007, 0x0000 }, /* R60 - LDO 2 */
158 { 0x0000, 0x0000, 0x0000 }, /* R61 */
159 { 0x0000, 0x0000, 0x0000 }, /* R62 */
160 { 0x0000, 0x0000, 0x0000 }, /* R63 */
161 { 0x0000, 0x0000, 0x0000 }, /* R64 */
162 { 0x0000, 0x0000, 0x0000 }, /* R65 */
163 { 0x0000, 0x0000, 0x0000 }, /* R66 */
164 { 0x0000, 0x0000, 0x0000 }, /* R67 */
165 { 0x0000, 0x0000, 0x0000 }, /* R68 */
166 { 0x0000, 0x0000, 0x0000 }, /* R69 */
167 { 0x0000, 0x0000, 0x0000 }, /* R70 */
168 { 0x0000, 0x0000, 0x0000 }, /* R71 */
169 { 0x0000, 0x0000, 0x0000 }, /* R72 */
170 { 0x0000, 0x0000, 0x0000 }, /* R73 */
171 { 0x0000, 0x0000, 0x0000 }, /* R74 */
172 { 0x0000, 0x0000, 0x0000 }, /* R75 */
173 { 0x8000, 0x8000, 0x0000 }, /* R76 - Charge Pump (1) */
174 { 0x0000, 0x0000, 0x0000 }, /* R77 */
175 { 0x0000, 0x0000, 0x0000 }, /* R78 */
176 { 0x0000, 0x0000, 0x0000 }, /* R79 */
177 { 0x0000, 0x0000, 0x0000 }, /* R80 */
178 { 0x0301, 0x0301, 0x0000 }, /* R81 - Class W (1) */
179 { 0x0000, 0x0000, 0x0000 }, /* R82 */
180 { 0x0000, 0x0000, 0x0000 }, /* R83 */
181 { 0x333F, 0x333F, 0x0000 }, /* R84 - DC Servo (1) */
182 { 0x0FEF, 0x0FEF, 0x0000 }, /* R85 - DC Servo (2) */
183 { 0x0000, 0x0000, 0x0000 }, /* R86 */
184 { 0xFFFF, 0xFFFF, 0x0000 }, /* R87 - DC Servo (4) */
185 { 0x0333, 0x0000, 0x0000 }, /* R88 - DC Servo Readback */
186 { 0x0000, 0x0000, 0x0000 }, /* R89 */
187 { 0x0000, 0x0000, 0x0000 }, /* R90 */
188 { 0x0000, 0x0000, 0x0000 }, /* R91 */
189 { 0x0000, 0x0000, 0x0000 }, /* R92 */
190 { 0x0000, 0x0000, 0x0000 }, /* R93 */
191 { 0x0000, 0x0000, 0x0000 }, /* R94 */
192 { 0x0000, 0x0000, 0x0000 }, /* R95 */
193 { 0x00EE, 0x00EE, 0x0000 }, /* R96 - Analogue HP (1) */
194 { 0x0000, 0x0000, 0x0000 }, /* R97 */
195 { 0x0000, 0x0000, 0x0000 }, /* R98 */
196 { 0x0000, 0x0000, 0x0000 }, /* R99 */
197 { 0x0000, 0x0000, 0x0000 }, /* R100 */
198 { 0x0000, 0x0000, 0x0000 }, /* R101 */
199 { 0x0000, 0x0000, 0x0000 }, /* R102 */
200 { 0x0000, 0x0000, 0x0000 }, /* R103 */
201 { 0x0000, 0x0000, 0x0000 }, /* R104 */
202 { 0x0000, 0x0000, 0x0000 }, /* R105 */
203 { 0x0000, 0x0000, 0x0000 }, /* R106 */
204 { 0x0000, 0x0000, 0x0000 }, /* R107 */
205 { 0x0000, 0x0000, 0x0000 }, /* R108 */
206 { 0x0000, 0x0000, 0x0000 }, /* R109 */
207 { 0x0000, 0x0000, 0x0000 }, /* R110 */
208 { 0x0000, 0x0000, 0x0000 }, /* R111 */
209 { 0x0000, 0x0000, 0x0000 }, /* R112 */
210 { 0x0000, 0x0000, 0x0000 }, /* R113 */
211 { 0x0000, 0x0000, 0x0000 }, /* R114 */
212 { 0x0000, 0x0000, 0x0000 }, /* R115 */
213 { 0x0000, 0x0000, 0x0000 }, /* R116 */
214 { 0x0000, 0x0000, 0x0000 }, /* R117 */
215 { 0x0000, 0x0000, 0x0000 }, /* R118 */
216 { 0x0000, 0x0000, 0x0000 }, /* R119 */
217 { 0x0000, 0x0000, 0x0000 }, /* R120 */
218 { 0x0000, 0x0000, 0x0000 }, /* R121 */
219 { 0x0000, 0x0000, 0x0000 }, /* R122 */
220 { 0x0000, 0x0000, 0x0000 }, /* R123 */
221 { 0x0000, 0x0000, 0x0000 }, /* R124 */
222 { 0x0000, 0x0000, 0x0000 }, /* R125 */
223 { 0x0000, 0x0000, 0x0000 }, /* R126 */
224 { 0x0000, 0x0000, 0x0000 }, /* R127 */
225 { 0x0000, 0x0000, 0x0000 }, /* R128 */
226 { 0x0000, 0x0000, 0x0000 }, /* R129 */
227 { 0x0000, 0x0000, 0x0000 }, /* R130 */
228 { 0x0000, 0x0000, 0x0000 }, /* R131 */
229 { 0x0000, 0x0000, 0x0000 }, /* R132 */
230 { 0x0000, 0x0000, 0x0000 }, /* R133 */
231 { 0x0000, 0x0000, 0x0000 }, /* R134 */
232 { 0x0000, 0x0000, 0x0000 }, /* R135 */
233 { 0x0000, 0x0000, 0x0000 }, /* R136 */
234 { 0x0000, 0x0000, 0x0000 }, /* R137 */
235 { 0x0000, 0x0000, 0x0000 }, /* R138 */
236 { 0x0000, 0x0000, 0x0000 }, /* R139 */
237 { 0x0000, 0x0000, 0x0000 }, /* R140 */
238 { 0x0000, 0x0000, 0x0000 }, /* R141 */
239 { 0x0000, 0x0000, 0x0000 }, /* R142 */
240 { 0x0000, 0x0000, 0x0000 }, /* R143 */
241 { 0x0000, 0x0000, 0x0000 }, /* R144 */
242 { 0x0000, 0x0000, 0x0000 }, /* R145 */
243 { 0x0000, 0x0000, 0x0000 }, /* R146 */
244 { 0x0000, 0x0000, 0x0000 }, /* R147 */
245 { 0x0000, 0x0000, 0x0000 }, /* R148 */
246 { 0x0000, 0x0000, 0x0000 }, /* R149 */
247 { 0x0000, 0x0000, 0x0000 }, /* R150 */
248 { 0x0000, 0x0000, 0x0000 }, /* R151 */
249 { 0x0000, 0x0000, 0x0000 }, /* R152 */
250 { 0x0000, 0x0000, 0x0000 }, /* R153 */
251 { 0x0000, 0x0000, 0x0000 }, /* R154 */
252 { 0x0000, 0x0000, 0x0000 }, /* R155 */
253 { 0x0000, 0x0000, 0x0000 }, /* R156 */
254 { 0x0000, 0x0000, 0x0000 }, /* R157 */
255 { 0x0000, 0x0000, 0x0000 }, /* R158 */
256 { 0x0000, 0x0000, 0x0000 }, /* R159 */
257 { 0x0000, 0x0000, 0x0000 }, /* R160 */
258 { 0x0000, 0x0000, 0x0000 }, /* R161 */
259 { 0x0000, 0x0000, 0x0000 }, /* R162 */
260 { 0x0000, 0x0000, 0x0000 }, /* R163 */
261 { 0x0000, 0x0000, 0x0000 }, /* R164 */
262 { 0x0000, 0x0000, 0x0000 }, /* R165 */
263 { 0x0000, 0x0000, 0x0000 }, /* R166 */
264 { 0x0000, 0x0000, 0x0000 }, /* R167 */
265 { 0x0000, 0x0000, 0x0000 }, /* R168 */
266 { 0x0000, 0x0000, 0x0000 }, /* R169 */
267 { 0x0000, 0x0000, 0x0000 }, /* R170 */
268 { 0x0000, 0x0000, 0x0000 }, /* R171 */
269 { 0x0000, 0x0000, 0x0000 }, /* R172 */
270 { 0x0000, 0x0000, 0x0000 }, /* R173 */
271 { 0x0000, 0x0000, 0x0000 }, /* R174 */
272 { 0x0000, 0x0000, 0x0000 }, /* R175 */
273 { 0x0000, 0x0000, 0x0000 }, /* R176 */
274 { 0x0000, 0x0000, 0x0000 }, /* R177 */
275 { 0x0000, 0x0000, 0x0000 }, /* R178 */
276 { 0x0000, 0x0000, 0x0000 }, /* R179 */
277 { 0x0000, 0x0000, 0x0000 }, /* R180 */
278 { 0x0000, 0x0000, 0x0000 }, /* R181 */
279 { 0x0000, 0x0000, 0x0000 }, /* R182 */
280 { 0x0000, 0x0000, 0x0000 }, /* R183 */
281 { 0x0000, 0x0000, 0x0000 }, /* R184 */
282 { 0x0000, 0x0000, 0x0000 }, /* R185 */
283 { 0x0000, 0x0000, 0x0000 }, /* R186 */
284 { 0x0000, 0x0000, 0x0000 }, /* R187 */
285 { 0x0000, 0x0000, 0x0000 }, /* R188 */
286 { 0x0000, 0x0000, 0x0000 }, /* R189 */
287 { 0x0000, 0x0000, 0x0000 }, /* R190 */
288 { 0x0000, 0x0000, 0x0000 }, /* R191 */
289 { 0x0000, 0x0000, 0x0000 }, /* R192 */
290 { 0x0000, 0x0000, 0x0000 }, /* R193 */
291 { 0x0000, 0x0000, 0x0000 }, /* R194 */
292 { 0x0000, 0x0000, 0x0000 }, /* R195 */
293 { 0x0000, 0x0000, 0x0000 }, /* R196 */
294 { 0x0000, 0x0000, 0x0000 }, /* R197 */
295 { 0x0000, 0x0000, 0x0000 }, /* R198 */
296 { 0x0000, 0x0000, 0x0000 }, /* R199 */
297 { 0x0000, 0x0000, 0x0000 }, /* R200 */
298 { 0x0000, 0x0000, 0x0000 }, /* R201 */
299 { 0x0000, 0x0000, 0x0000 }, /* R202 */
300 { 0x0000, 0x0000, 0x0000 }, /* R203 */
301 { 0x0000, 0x0000, 0x0000 }, /* R204 */
302 { 0x0000, 0x0000, 0x0000 }, /* R205 */
303 { 0x0000, 0x0000, 0x0000 }, /* R206 */
304 { 0x0000, 0x0000, 0x0000 }, /* R207 */
305 { 0x0000, 0x0000, 0x0000 }, /* R208 */
306 { 0x0000, 0x0000, 0x0000 }, /* R209 */
307 { 0x0000, 0x0000, 0x0000 }, /* R210 */
308 { 0x0000, 0x0000, 0x0000 }, /* R211 */
309 { 0x0000, 0x0000, 0x0000 }, /* R212 */
310 { 0x0000, 0x0000, 0x0000 }, /* R213 */
311 { 0x0000, 0x0000, 0x0000 }, /* R214 */
312 { 0x0000, 0x0000, 0x0000 }, /* R215 */
313 { 0x0000, 0x0000, 0x0000 }, /* R216 */
314 { 0x0000, 0x0000, 0x0000 }, /* R217 */
315 { 0x0000, 0x0000, 0x0000 }, /* R218 */
316 { 0x0000, 0x0000, 0x0000 }, /* R219 */
317 { 0x0000, 0x0000, 0x0000 }, /* R220 */
318 { 0x0000, 0x0000, 0x0000 }, /* R221 */
319 { 0x0000, 0x0000, 0x0000 }, /* R222 */
320 { 0x0000, 0x0000, 0x0000 }, /* R223 */
321 { 0x0000, 0x0000, 0x0000 }, /* R224 */
322 { 0x0000, 0x0000, 0x0000 }, /* R225 */
323 { 0x0000, 0x0000, 0x0000 }, /* R226 */
324 { 0x0000, 0x0000, 0x0000 }, /* R227 */
325 { 0x0000, 0x0000, 0x0000 }, /* R228 */
326 { 0x0000, 0x0000, 0x0000 }, /* R229 */
327 { 0x0000, 0x0000, 0x0000 }, /* R230 */
328 { 0x0000, 0x0000, 0x0000 }, /* R231 */
329 { 0x0000, 0x0000, 0x0000 }, /* R232 */
330 { 0x0000, 0x0000, 0x0000 }, /* R233 */
331 { 0x0000, 0x0000, 0x0000 }, /* R234 */
332 { 0x0000, 0x0000, 0x0000 }, /* R235 */
333 { 0x0000, 0x0000, 0x0000 }, /* R236 */
334 { 0x0000, 0x0000, 0x0000 }, /* R237 */
335 { 0x0000, 0x0000, 0x0000 }, /* R238 */
336 { 0x0000, 0x0000, 0x0000 }, /* R239 */
337 { 0x0000, 0x0000, 0x0000 }, /* R240 */
338 { 0x0000, 0x0000, 0x0000 }, /* R241 */
339 { 0x0000, 0x0000, 0x0000 }, /* R242 */
340 { 0x0000, 0x0000, 0x0000 }, /* R243 */
341 { 0x0000, 0x0000, 0x0000 }, /* R244 */
342 { 0x0000, 0x0000, 0x0000 }, /* R245 */
343 { 0x0000, 0x0000, 0x0000 }, /* R246 */
344 { 0x0000, 0x0000, 0x0000 }, /* R247 */
345 { 0x0000, 0x0000, 0x0000 }, /* R248 */
346 { 0x0000, 0x0000, 0x0000 }, /* R249 */
347 { 0x0000, 0x0000, 0x0000 }, /* R250 */
348 { 0x0000, 0x0000, 0x0000 }, /* R251 */
349 { 0x0000, 0x0000, 0x0000 }, /* R252 */
350 { 0x0000, 0x0000, 0x0000 }, /* R253 */
351 { 0x0000, 0x0000, 0x0000 }, /* R254 */
352 { 0x0000, 0x0000, 0x0000 }, /* R255 */
353 { 0x000F, 0x0000, 0x0000 }, /* R256 - Chip Revision */
354 { 0x0074, 0x0074, 0x0000 }, /* R257 - Control Interface */
355 { 0x0000, 0x0000, 0x0000 }, /* R258 */
356 { 0x0000, 0x0000, 0x0000 }, /* R259 */
357 { 0x0000, 0x0000, 0x0000 }, /* R260 */
358 { 0x0000, 0x0000, 0x0000 }, /* R261 */
359 { 0x0000, 0x0000, 0x0000 }, /* R262 */
360 { 0x0000, 0x0000, 0x0000 }, /* R263 */
361 { 0x0000, 0x0000, 0x0000 }, /* R264 */
362 { 0x0000, 0x0000, 0x0000 }, /* R265 */
363 { 0x0000, 0x0000, 0x0000 }, /* R266 */
364 { 0x0000, 0x0000, 0x0000 }, /* R267 */
365 { 0x0000, 0x0000, 0x0000 }, /* R268 */
366 { 0x0000, 0x0000, 0x0000 }, /* R269 */
367 { 0x0000, 0x0000, 0x0000 }, /* R270 */
368 { 0x0000, 0x0000, 0x0000 }, /* R271 */
369 { 0x807F, 0x837F, 0x0000 }, /* R272 - Write Sequencer Ctrl (1) */
370 { 0x017F, 0x0000, 0x0000 }, /* R273 - Write Sequencer Ctrl (2) */
371 { 0x0000, 0x0000, 0x0000 }, /* R274 */
372 { 0x0000, 0x0000, 0x0000 }, /* R275 */
373 { 0x0000, 0x0000, 0x0000 }, /* R276 */
374 { 0x0000, 0x0000, 0x0000 }, /* R277 */
375 { 0x0000, 0x0000, 0x0000 }, /* R278 */
376 { 0x0000, 0x0000, 0x0000 }, /* R279 */
377 { 0x0000, 0x0000, 0x0000 }, /* R280 */
378 { 0x0000, 0x0000, 0x0000 }, /* R281 */
379 { 0x0000, 0x0000, 0x0000 }, /* R282 */
380 { 0x0000, 0x0000, 0x0000 }, /* R283 */
381 { 0x0000, 0x0000, 0x0000 }, /* R284 */
382 { 0x0000, 0x0000, 0x0000 }, /* R285 */
383 { 0x0000, 0x0000, 0x0000 }, /* R286 */
384 { 0x0000, 0x0000, 0x0000 }, /* R287 */
385 { 0x0000, 0x0000, 0x0000 }, /* R288 */
386 { 0x0000, 0x0000, 0x0000 }, /* R289 */
387 { 0x0000, 0x0000, 0x0000 }, /* R290 */
388 { 0x0000, 0x0000, 0x0000 }, /* R291 */
389 { 0x0000, 0x0000, 0x0000 }, /* R292 */
390 { 0x0000, 0x0000, 0x0000 }, /* R293 */
391 { 0x0000, 0x0000, 0x0000 }, /* R294 */
392 { 0x0000, 0x0000, 0x0000 }, /* R295 */
393 { 0x0000, 0x0000, 0x0000 }, /* R296 */
394 { 0x0000, 0x0000, 0x0000 }, /* R297 */
395 { 0x0000, 0x0000, 0x0000 }, /* R298 */
396 { 0x0000, 0x0000, 0x0000 }, /* R299 */
397 { 0x0000, 0x0000, 0x0000 }, /* R300 */
398 { 0x0000, 0x0000, 0x0000 }, /* R301 */
399 { 0x0000, 0x0000, 0x0000 }, /* R302 */
400 { 0x0000, 0x0000, 0x0000 }, /* R303 */
401 { 0x0000, 0x0000, 0x0000 }, /* R304 */
402 { 0x0000, 0x0000, 0x0000 }, /* R305 */
403 { 0x0000, 0x0000, 0x0000 }, /* R306 */
404 { 0x0000, 0x0000, 0x0000 }, /* R307 */
405 { 0x0000, 0x0000, 0x0000 }, /* R308 */
406 { 0x0000, 0x0000, 0x0000 }, /* R309 */
407 { 0x0000, 0x0000, 0x0000 }, /* R310 */
408 { 0x0000, 0x0000, 0x0000 }, /* R311 */
409 { 0x0000, 0x0000, 0x0000 }, /* R312 */
410 { 0x0000, 0x0000, 0x0000 }, /* R313 */
411 { 0x0000, 0x0000, 0x0000 }, /* R314 */
412 { 0x0000, 0x0000, 0x0000 }, /* R315 */
413 { 0x0000, 0x0000, 0x0000 }, /* R316 */
414 { 0x0000, 0x0000, 0x0000 }, /* R317 */
415 { 0x0000, 0x0000, 0x0000 }, /* R318 */
416 { 0x0000, 0x0000, 0x0000 }, /* R319 */
417 { 0x0000, 0x0000, 0x0000 }, /* R320 */
418 { 0x0000, 0x0000, 0x0000 }, /* R321 */
419 { 0x0000, 0x0000, 0x0000 }, /* R322 */
420 { 0x0000, 0x0000, 0x0000 }, /* R323 */
421 { 0x0000, 0x0000, 0x0000 }, /* R324 */
422 { 0x0000, 0x0000, 0x0000 }, /* R325 */
423 { 0x0000, 0x0000, 0x0000 }, /* R326 */
424 { 0x0000, 0x0000, 0x0000 }, /* R327 */
425 { 0x0000, 0x0000, 0x0000 }, /* R328 */
426 { 0x0000, 0x0000, 0x0000 }, /* R329 */
427 { 0x0000, 0x0000, 0x0000 }, /* R330 */
428 { 0x0000, 0x0000, 0x0000 }, /* R331 */
429 { 0x0000, 0x0000, 0x0000 }, /* R332 */
430 { 0x0000, 0x0000, 0x0000 }, /* R333 */
431 { 0x0000, 0x0000, 0x0000 }, /* R334 */
432 { 0x0000, 0x0000, 0x0000 }, /* R335 */
433 { 0x0000, 0x0000, 0x0000 }, /* R336 */
434 { 0x0000, 0x0000, 0x0000 }, /* R337 */
435 { 0x0000, 0x0000, 0x0000 }, /* R338 */
436 { 0x0000, 0x0000, 0x0000 }, /* R339 */
437 { 0x0000, 0x0000, 0x0000 }, /* R340 */
438 { 0x0000, 0x0000, 0x0000 }, /* R341 */
439 { 0x0000, 0x0000, 0x0000 }, /* R342 */
440 { 0x0000, 0x0000, 0x0000 }, /* R343 */
441 { 0x0000, 0x0000, 0x0000 }, /* R344 */
442 { 0x0000, 0x0000, 0x0000 }, /* R345 */
443 { 0x0000, 0x0000, 0x0000 }, /* R346 */
444 { 0x0000, 0x0000, 0x0000 }, /* R347 */
445 { 0x0000, 0x0000, 0x0000 }, /* R348 */
446 { 0x0000, 0x0000, 0x0000 }, /* R349 */
447 { 0x0000, 0x0000, 0x0000 }, /* R350 */
448 { 0x0000, 0x0000, 0x0000 }, /* R351 */
449 { 0x0000, 0x0000, 0x0000 }, /* R352 */
450 { 0x0000, 0x0000, 0x0000 }, /* R353 */
451 { 0x0000, 0x0000, 0x0000 }, /* R354 */
452 { 0x0000, 0x0000, 0x0000 }, /* R355 */
453 { 0x0000, 0x0000, 0x0000 }, /* R356 */
454 { 0x0000, 0x0000, 0x0000 }, /* R357 */
455 { 0x0000, 0x0000, 0x0000 }, /* R358 */
456 { 0x0000, 0x0000, 0x0000 }, /* R359 */
457 { 0x0000, 0x0000, 0x0000 }, /* R360 */
458 { 0x0000, 0x0000, 0x0000 }, /* R361 */
459 { 0x0000, 0x0000, 0x0000 }, /* R362 */
460 { 0x0000, 0x0000, 0x0000 }, /* R363 */
461 { 0x0000, 0x0000, 0x0000 }, /* R364 */
462 { 0x0000, 0x0000, 0x0000 }, /* R365 */
463 { 0x0000, 0x0000, 0x0000 }, /* R366 */
464 { 0x0000, 0x0000, 0x0000 }, /* R367 */
465 { 0x0000, 0x0000, 0x0000 }, /* R368 */
466 { 0x0000, 0x0000, 0x0000 }, /* R369 */
467 { 0x0000, 0x0000, 0x0000 }, /* R370 */
468 { 0x0000, 0x0000, 0x0000 }, /* R371 */
469 { 0x0000, 0x0000, 0x0000 }, /* R372 */
470 { 0x0000, 0x0000, 0x0000 }, /* R373 */
471 { 0x0000, 0x0000, 0x0000 }, /* R374 */
472 { 0x0000, 0x0000, 0x0000 }, /* R375 */
473 { 0x0000, 0x0000, 0x0000 }, /* R376 */
474 { 0x0000, 0x0000, 0x0000 }, /* R377 */
475 { 0x0000, 0x0000, 0x0000 }, /* R378 */
476 { 0x0000, 0x0000, 0x0000 }, /* R379 */
477 { 0x0000, 0x0000, 0x0000 }, /* R380 */
478 { 0x0000, 0x0000, 0x0000 }, /* R381 */
479 { 0x0000, 0x0000, 0x0000 }, /* R382 */
480 { 0x0000, 0x0000, 0x0000 }, /* R383 */
481 { 0x0000, 0x0000, 0x0000 }, /* R384 */
482 { 0x0000, 0x0000, 0x0000 }, /* R385 */
483 { 0x0000, 0x0000, 0x0000 }, /* R386 */
484 { 0x0000, 0x0000, 0x0000 }, /* R387 */
485 { 0x0000, 0x0000, 0x0000 }, /* R388 */
486 { 0x0000, 0x0000, 0x0000 }, /* R389 */
487 { 0x0000, 0x0000, 0x0000 }, /* R390 */
488 { 0x0000, 0x0000, 0x0000 }, /* R391 */
489 { 0x0000, 0x0000, 0x0000 }, /* R392 */
490 { 0x0000, 0x0000, 0x0000 }, /* R393 */
491 { 0x0000, 0x0000, 0x0000 }, /* R394 */
492 { 0x0000, 0x0000, 0x0000 }, /* R395 */
493 { 0x0000, 0x0000, 0x0000 }, /* R396 */
494 { 0x0000, 0x0000, 0x0000 }, /* R397 */
495 { 0x0000, 0x0000, 0x0000 }, /* R398 */
496 { 0x0000, 0x0000, 0x0000 }, /* R399 */
497 { 0x0000, 0x0000, 0x0000 }, /* R400 */
498 { 0x0000, 0x0000, 0x0000 }, /* R401 */
499 { 0x0000, 0x0000, 0x0000 }, /* R402 */
500 { 0x0000, 0x0000, 0x0000 }, /* R403 */
501 { 0x0000, 0x0000, 0x0000 }, /* R404 */
502 { 0x0000, 0x0000, 0x0000 }, /* R405 */
503 { 0x0000, 0x0000, 0x0000 }, /* R406 */
504 { 0x0000, 0x0000, 0x0000 }, /* R407 */
505 { 0x0000, 0x0000, 0x0000 }, /* R408 */
506 { 0x0000, 0x0000, 0x0000 }, /* R409 */
507 { 0x0000, 0x0000, 0x0000 }, /* R410 */
508 { 0x0000, 0x0000, 0x0000 }, /* R411 */
509 { 0x0000, 0x0000, 0x0000 }, /* R412 */
510 { 0x0000, 0x0000, 0x0000 }, /* R413 */
511 { 0x0000, 0x0000, 0x0000 }, /* R414 */
512 { 0x0000, 0x0000, 0x0000 }, /* R415 */
513 { 0x0000, 0x0000, 0x0000 }, /* R416 */
514 { 0x0000, 0x0000, 0x0000 }, /* R417 */
515 { 0x0000, 0x0000, 0x0000 }, /* R418 */
516 { 0x0000, 0x0000, 0x0000 }, /* R419 */
517 { 0x0000, 0x0000, 0x0000 }, /* R420 */
518 { 0x0000, 0x0000, 0x0000 }, /* R421 */
519 { 0x0000, 0x0000, 0x0000 }, /* R422 */
520 { 0x0000, 0x0000, 0x0000 }, /* R423 */
521 { 0x0000, 0x0000, 0x0000 }, /* R424 */
522 { 0x0000, 0x0000, 0x0000 }, /* R425 */
523 { 0x0000, 0x0000, 0x0000 }, /* R426 */
524 { 0x0000, 0x0000, 0x0000 }, /* R427 */
525 { 0x0000, 0x0000, 0x0000 }, /* R428 */
526 { 0x0000, 0x0000, 0x0000 }, /* R429 */
527 { 0x0000, 0x0000, 0x0000 }, /* R430 */
528 { 0x0000, 0x0000, 0x0000 }, /* R431 */
529 { 0x0000, 0x0000, 0x0000 }, /* R432 */
530 { 0x0000, 0x0000, 0x0000 }, /* R433 */
531 { 0x0000, 0x0000, 0x0000 }, /* R434 */
532 { 0x0000, 0x0000, 0x0000 }, /* R435 */
533 { 0x0000, 0x0000, 0x0000 }, /* R436 */
534 { 0x0000, 0x0000, 0x0000 }, /* R437 */
535 { 0x0000, 0x0000, 0x0000 }, /* R438 */
536 { 0x0000, 0x0000, 0x0000 }, /* R439 */
537 { 0x0000, 0x0000, 0x0000 }, /* R440 */
538 { 0x0000, 0x0000, 0x0000 }, /* R441 */
539 { 0x0000, 0x0000, 0x0000 }, /* R442 */
540 { 0x0000, 0x0000, 0x0000 }, /* R443 */
541 { 0x0000, 0x0000, 0x0000 }, /* R444 */
542 { 0x0000, 0x0000, 0x0000 }, /* R445 */
543 { 0x0000, 0x0000, 0x0000 }, /* R446 */
544 { 0x0000, 0x0000, 0x0000 }, /* R447 */
545 { 0x0000, 0x0000, 0x0000 }, /* R448 */
546 { 0x0000, 0x0000, 0x0000 }, /* R449 */
547 { 0x0000, 0x0000, 0x0000 }, /* R450 */
548 { 0x0000, 0x0000, 0x0000 }, /* R451 */
549 { 0x0000, 0x0000, 0x0000 }, /* R452 */
550 { 0x0000, 0x0000, 0x0000 }, /* R453 */
551 { 0x0000, 0x0000, 0x0000 }, /* R454 */
552 { 0x0000, 0x0000, 0x0000 }, /* R455 */
553 { 0x0000, 0x0000, 0x0000 }, /* R456 */
554 { 0x0000, 0x0000, 0x0000 }, /* R457 */
555 { 0x0000, 0x0000, 0x0000 }, /* R458 */
556 { 0x0000, 0x0000, 0x0000 }, /* R459 */
557 { 0x0000, 0x0000, 0x0000 }, /* R460 */
558 { 0x0000, 0x0000, 0x0000 }, /* R461 */
559 { 0x0000, 0x0000, 0x0000 }, /* R462 */
560 { 0x0000, 0x0000, 0x0000 }, /* R463 */
561 { 0x0000, 0x0000, 0x0000 }, /* R464 */
562 { 0x0000, 0x0000, 0x0000 }, /* R465 */
563 { 0x0000, 0x0000, 0x0000 }, /* R466 */
564 { 0x0000, 0x0000, 0x0000 }, /* R467 */
565 { 0x0000, 0x0000, 0x0000 }, /* R468 */
566 { 0x0000, 0x0000, 0x0000 }, /* R469 */
567 { 0x0000, 0x0000, 0x0000 }, /* R470 */
568 { 0x0000, 0x0000, 0x0000 }, /* R471 */
569 { 0x0000, 0x0000, 0x0000 }, /* R472 */
570 { 0x0000, 0x0000, 0x0000 }, /* R473 */
571 { 0x0000, 0x0000, 0x0000 }, /* R474 */
572 { 0x0000, 0x0000, 0x0000 }, /* R475 */
573 { 0x0000, 0x0000, 0x0000 }, /* R476 */
574 { 0x0000, 0x0000, 0x0000 }, /* R477 */
575 { 0x0000, 0x0000, 0x0000 }, /* R478 */
576 { 0x0000, 0x0000, 0x0000 }, /* R479 */
577 { 0x0000, 0x0000, 0x0000 }, /* R480 */
578 { 0x0000, 0x0000, 0x0000 }, /* R481 */
579 { 0x0000, 0x0000, 0x0000 }, /* R482 */
580 { 0x0000, 0x0000, 0x0000 }, /* R483 */
581 { 0x0000, 0x0000, 0x0000 }, /* R484 */
582 { 0x0000, 0x0000, 0x0000 }, /* R485 */
583 { 0x0000, 0x0000, 0x0000 }, /* R486 */
584 { 0x0000, 0x0000, 0x0000 }, /* R487 */
585 { 0x0000, 0x0000, 0x0000 }, /* R488 */
586 { 0x0000, 0x0000, 0x0000 }, /* R489 */
587 { 0x0000, 0x0000, 0x0000 }, /* R490 */
588 { 0x0000, 0x0000, 0x0000 }, /* R491 */
589 { 0x0000, 0x0000, 0x0000 }, /* R492 */
590 { 0x0000, 0x0000, 0x0000 }, /* R493 */
591 { 0x0000, 0x0000, 0x0000 }, /* R494 */
592 { 0x0000, 0x0000, 0x0000 }, /* R495 */
593 { 0x0000, 0x0000, 0x0000 }, /* R496 */
594 { 0x0000, 0x0000, 0x0000 }, /* R497 */
595 { 0x0000, 0x0000, 0x0000 }, /* R498 */
596 { 0x0000, 0x0000, 0x0000 }, /* R499 */
597 { 0x0000, 0x0000, 0x0000 }, /* R500 */
598 { 0x0000, 0x0000, 0x0000 }, /* R501 */
599 { 0x0000, 0x0000, 0x0000 }, /* R502 */
600 { 0x0000, 0x0000, 0x0000 }, /* R503 */
601 { 0x0000, 0x0000, 0x0000 }, /* R504 */
602 { 0x0000, 0x0000, 0x0000 }, /* R505 */
603 { 0x0000, 0x0000, 0x0000 }, /* R506 */
604 { 0x0000, 0x0000, 0x0000 }, /* R507 */
605 { 0x0000, 0x0000, 0x0000 }, /* R508 */
606 { 0x0000, 0x0000, 0x0000 }, /* R509 */
607 { 0x0000, 0x0000, 0x0000 }, /* R510 */
608 { 0x0000, 0x0000, 0x0000 }, /* R511 */
609 { 0x001F, 0x001F, 0x0000 }, /* R512 - AIF1 Clocking (1) */
610 { 0x003F, 0x003F, 0x0000 }, /* R513 - AIF1 Clocking (2) */
611 { 0x0000, 0x0000, 0x0000 }, /* R514 */
612 { 0x0000, 0x0000, 0x0000 }, /* R515 */
613 { 0x001F, 0x001F, 0x0000 }, /* R516 - AIF2 Clocking (1) */
614 { 0x003F, 0x003F, 0x0000 }, /* R517 - AIF2 Clocking (2) */
615 { 0x0000, 0x0000, 0x0000 }, /* R518 */
616 { 0x0000, 0x0000, 0x0000 }, /* R519 */
617 { 0x001F, 0x001F, 0x0000 }, /* R520 - Clocking (1) */
618 { 0x0777, 0x0777, 0x0000 }, /* R521 - Clocking (2) */
619 { 0x0000, 0x0000, 0x0000 }, /* R522 */
620 { 0x0000, 0x0000, 0x0000 }, /* R523 */
621 { 0x0000, 0x0000, 0x0000 }, /* R524 */
622 { 0x0000, 0x0000, 0x0000 }, /* R525 */
623 { 0x0000, 0x0000, 0x0000 }, /* R526 */
624 { 0x0000, 0x0000, 0x0000 }, /* R527 */
625 { 0x00FF, 0x00FF, 0x0000 }, /* R528 - AIF1 Rate */
626 { 0x00FF, 0x00FF, 0x0000 }, /* R529 - AIF2 Rate */
627 { 0x000F, 0x0000, 0x0000 }, /* R530 - Rate Status */
628 { 0x0000, 0x0000, 0x0000 }, /* R531 */
629 { 0x0000, 0x0000, 0x0000 }, /* R532 */
630 { 0x0000, 0x0000, 0x0000 }, /* R533 */
631 { 0x0000, 0x0000, 0x0000 }, /* R534 */
632 { 0x0000, 0x0000, 0x0000 }, /* R535 */
633 { 0x0000, 0x0000, 0x0000 }, /* R536 */
634 { 0x0000, 0x0000, 0x0000 }, /* R537 */
635 { 0x0000, 0x0000, 0x0000 }, /* R538 */
636 { 0x0000, 0x0000, 0x0000 }, /* R539 */
637 { 0x0000, 0x0000, 0x0000 }, /* R540 */
638 { 0x0000, 0x0000, 0x0000 }, /* R541 */
639 { 0x0000, 0x0000, 0x0000 }, /* R542 */
640 { 0x0000, 0x0000, 0x0000 }, /* R543 */
641 { 0x0007, 0x0007, 0x0000 }, /* R544 - FLL1 Control (1) */
642 { 0x3F77, 0x3F77, 0x0000 }, /* R545 - FLL1 Control (2) */
643 { 0xFFFF, 0xFFFF, 0x0000 }, /* R546 - FLL1 Control (3) */
644 { 0x7FEF, 0x7FEF, 0x0000 }, /* R547 - FLL1 Control (4) */
645 { 0x1FDB, 0x1FDB, 0x0000 }, /* R548 - FLL1 Control (5) */
646 { 0x0000, 0x0000, 0x0000 }, /* R549 */
647 { 0x0000, 0x0000, 0x0000 }, /* R550 */
648 { 0x0000, 0x0000, 0x0000 }, /* R551 */
649 { 0x0000, 0x0000, 0x0000 }, /* R552 */
650 { 0x0000, 0x0000, 0x0000 }, /* R553 */
651 { 0x0000, 0x0000, 0x0000 }, /* R554 */
652 { 0x0000, 0x0000, 0x0000 }, /* R555 */
653 { 0x0000, 0x0000, 0x0000 }, /* R556 */
654 { 0x0000, 0x0000, 0x0000 }, /* R557 */
655 { 0x0000, 0x0000, 0x0000 }, /* R558 */
656 { 0x0000, 0x0000, 0x0000 }, /* R559 */
657 { 0x0000, 0x0000, 0x0000 }, /* R560 */
658 { 0x0000, 0x0000, 0x0000 }, /* R561 */
659 { 0x0000, 0x0000, 0x0000 }, /* R562 */
660 { 0x0000, 0x0000, 0x0000 }, /* R563 */
661 { 0x0000, 0x0000, 0x0000 }, /* R564 */
662 { 0x0000, 0x0000, 0x0000 }, /* R565 */
663 { 0x0000, 0x0000, 0x0000 }, /* R566 */
664 { 0x0000, 0x0000, 0x0000 }, /* R567 */
665 { 0x0000, 0x0000, 0x0000 }, /* R568 */
666 { 0x0000, 0x0000, 0x0000 }, /* R569 */
667 { 0x0000, 0x0000, 0x0000 }, /* R570 */
668 { 0x0000, 0x0000, 0x0000 }, /* R571 */
669 { 0x0000, 0x0000, 0x0000 }, /* R572 */
670 { 0x0000, 0x0000, 0x0000 }, /* R573 */
671 { 0x0000, 0x0000, 0x0000 }, /* R574 */
672 { 0x0000, 0x0000, 0x0000 }, /* R575 */
673 { 0x0007, 0x0007, 0x0000 }, /* R576 - FLL2 Control (1) */
674 { 0x3F77, 0x3F77, 0x0000 }, /* R577 - FLL2 Control (2) */
675 { 0xFFFF, 0xFFFF, 0x0000 }, /* R578 - FLL2 Control (3) */
676 { 0x7FEF, 0x7FEF, 0x0000 }, /* R579 - FLL2 Control (4) */
677 { 0x1FDB, 0x1FDB, 0x0000 }, /* R580 - FLL2 Control (5) */
678 { 0x0000, 0x0000, 0x0000 }, /* R581 */
679 { 0x0000, 0x0000, 0x0000 }, /* R582 */
680 { 0x0000, 0x0000, 0x0000 }, /* R583 */
681 { 0x0000, 0x0000, 0x0000 }, /* R584 */
682 { 0x0000, 0x0000, 0x0000 }, /* R585 */
683 { 0x0000, 0x0000, 0x0000 }, /* R586 */
684 { 0x0000, 0x0000, 0x0000 }, /* R587 */
685 { 0x0000, 0x0000, 0x0000 }, /* R588 */
686 { 0x0000, 0x0000, 0x0000 }, /* R589 */
687 { 0x0000, 0x0000, 0x0000 }, /* R590 */
688 { 0x0000, 0x0000, 0x0000 }, /* R591 */
689 { 0x0000, 0x0000, 0x0000 }, /* R592 */
690 { 0x0000, 0x0000, 0x0000 }, /* R593 */
691 { 0x0000, 0x0000, 0x0000 }, /* R594 */
692 { 0x0000, 0x0000, 0x0000 }, /* R595 */
693 { 0x0000, 0x0000, 0x0000 }, /* R596 */
694 { 0x0000, 0x0000, 0x0000 }, /* R597 */
695 { 0x0000, 0x0000, 0x0000 }, /* R598 */
696 { 0x0000, 0x0000, 0x0000 }, /* R599 */
697 { 0x0000, 0x0000, 0x0000 }, /* R600 */
698 { 0x0000, 0x0000, 0x0000 }, /* R601 */
699 { 0x0000, 0x0000, 0x0000 }, /* R602 */
700 { 0x0000, 0x0000, 0x0000 }, /* R603 */
701 { 0x0000, 0x0000, 0x0000 }, /* R604 */
702 { 0x0000, 0x0000, 0x0000 }, /* R605 */
703 { 0x0000, 0x0000, 0x0000 }, /* R606 */
704 { 0x0000, 0x0000, 0x0000 }, /* R607 */
705 { 0x0000, 0x0000, 0x0000 }, /* R608 */
706 { 0x0000, 0x0000, 0x0000 }, /* R609 */
707 { 0x0000, 0x0000, 0x0000 }, /* R610 */
708 { 0x0000, 0x0000, 0x0000 }, /* R611 */
709 { 0x0000, 0x0000, 0x0000 }, /* R612 */
710 { 0x0000, 0x0000, 0x0000 }, /* R613 */
711 { 0x0000, 0x0000, 0x0000 }, /* R614 */
712 { 0x0000, 0x0000, 0x0000 }, /* R615 */
713 { 0x0000, 0x0000, 0x0000 }, /* R616 */
714 { 0x0000, 0x0000, 0x0000 }, /* R617 */
715 { 0x0000, 0x0000, 0x0000 }, /* R618 */
716 { 0x0000, 0x0000, 0x0000 }, /* R619 */
717 { 0x0000, 0x0000, 0x0000 }, /* R620 */
718 { 0x0000, 0x0000, 0x0000 }, /* R621 */
719 { 0x0000, 0x0000, 0x0000 }, /* R622 */
720 { 0x0000, 0x0000, 0x0000 }, /* R623 */
721 { 0x0000, 0x0000, 0x0000 }, /* R624 */
722 { 0x0000, 0x0000, 0x0000 }, /* R625 */
723 { 0x0000, 0x0000, 0x0000 }, /* R626 */
724 { 0x0000, 0x0000, 0x0000 }, /* R627 */
725 { 0x0000, 0x0000, 0x0000 }, /* R628 */
726 { 0x0000, 0x0000, 0x0000 }, /* R629 */
727 { 0x0000, 0x0000, 0x0000 }, /* R630 */
728 { 0x0000, 0x0000, 0x0000 }, /* R631 */
729 { 0x0000, 0x0000, 0x0000 }, /* R632 */
730 { 0x0000, 0x0000, 0x0000 }, /* R633 */
731 { 0x0000, 0x0000, 0x0000 }, /* R634 */
732 { 0x0000, 0x0000, 0x0000 }, /* R635 */
733 { 0x0000, 0x0000, 0x0000 }, /* R636 */
734 { 0x0000, 0x0000, 0x0000 }, /* R637 */
735 { 0x0000, 0x0000, 0x0000 }, /* R638 */
736 { 0x0000, 0x0000, 0x0000 }, /* R639 */
737 { 0x0000, 0x0000, 0x0000 }, /* R640 */
738 { 0x0000, 0x0000, 0x0000 }, /* R641 */
739 { 0x0000, 0x0000, 0x0000 }, /* R642 */
740 { 0x0000, 0x0000, 0x0000 }, /* R643 */
741 { 0x0000, 0x0000, 0x0000 }, /* R644 */
742 { 0x0000, 0x0000, 0x0000 }, /* R645 */
743 { 0x0000, 0x0000, 0x0000 }, /* R646 */
744 { 0x0000, 0x0000, 0x0000 }, /* R647 */
745 { 0x0000, 0x0000, 0x0000 }, /* R648 */
746 { 0x0000, 0x0000, 0x0000 }, /* R649 */
747 { 0x0000, 0x0000, 0x0000 }, /* R650 */
748 { 0x0000, 0x0000, 0x0000 }, /* R651 */
749 { 0x0000, 0x0000, 0x0000 }, /* R652 */
750 { 0x0000, 0x0000, 0x0000 }, /* R653 */
751 { 0x0000, 0x0000, 0x0000 }, /* R654 */
752 { 0x0000, 0x0000, 0x0000 }, /* R655 */
753 { 0x0000, 0x0000, 0x0000 }, /* R656 */
754 { 0x0000, 0x0000, 0x0000 }, /* R657 */
755 { 0x0000, 0x0000, 0x0000 }, /* R658 */
756 { 0x0000, 0x0000, 0x0000 }, /* R659 */
757 { 0x0000, 0x0000, 0x0000 }, /* R660 */
758 { 0x0000, 0x0000, 0x0000 }, /* R661 */
759 { 0x0000, 0x0000, 0x0000 }, /* R662 */
760 { 0x0000, 0x0000, 0x0000 }, /* R663 */
761 { 0x0000, 0x0000, 0x0000 }, /* R664 */
762 { 0x0000, 0x0000, 0x0000 }, /* R665 */
763 { 0x0000, 0x0000, 0x0000 }, /* R666 */
764 { 0x0000, 0x0000, 0x0000 }, /* R667 */
765 { 0x0000, 0x0000, 0x0000 }, /* R668 */
766 { 0x0000, 0x0000, 0x0000 }, /* R669 */
767 { 0x0000, 0x0000, 0x0000 }, /* R670 */
768 { 0x0000, 0x0000, 0x0000 }, /* R671 */
769 { 0x0000, 0x0000, 0x0000 }, /* R672 */
770 { 0x0000, 0x0000, 0x0000 }, /* R673 */
771 { 0x0000, 0x0000, 0x0000 }, /* R674 */
772 { 0x0000, 0x0000, 0x0000 }, /* R675 */
773 { 0x0000, 0x0000, 0x0000 }, /* R676 */
774 { 0x0000, 0x0000, 0x0000 }, /* R677 */
775 { 0x0000, 0x0000, 0x0000 }, /* R678 */
776 { 0x0000, 0x0000, 0x0000 }, /* R679 */
777 { 0x0000, 0x0000, 0x0000 }, /* R680 */
778 { 0x0000, 0x0000, 0x0000 }, /* R681 */
779 { 0x0000, 0x0000, 0x0000 }, /* R682 */
780 { 0x0000, 0x0000, 0x0000 }, /* R683 */
781 { 0x0000, 0x0000, 0x0000 }, /* R684 */
782 { 0x0000, 0x0000, 0x0000 }, /* R685 */
783 { 0x0000, 0x0000, 0x0000 }, /* R686 */
784 { 0x0000, 0x0000, 0x0000 }, /* R687 */
785 { 0x0000, 0x0000, 0x0000 }, /* R688 */
786 { 0x0000, 0x0000, 0x0000 }, /* R689 */
787 { 0x0000, 0x0000, 0x0000 }, /* R690 */
788 { 0x0000, 0x0000, 0x0000 }, /* R691 */
789 { 0x0000, 0x0000, 0x0000 }, /* R692 */
790 { 0x0000, 0x0000, 0x0000 }, /* R693 */
791 { 0x0000, 0x0000, 0x0000 }, /* R694 */
792 { 0x0000, 0x0000, 0x0000 }, /* R695 */
793 { 0x0000, 0x0000, 0x0000 }, /* R696 */
794 { 0x0000, 0x0000, 0x0000 }, /* R697 */
795 { 0x0000, 0x0000, 0x0000 }, /* R698 */
796 { 0x0000, 0x0000, 0x0000 }, /* R699 */
797 { 0x0000, 0x0000, 0x0000 }, /* R700 */
798 { 0x0000, 0x0000, 0x0000 }, /* R701 */
799 { 0x0000, 0x0000, 0x0000 }, /* R702 */
800 { 0x0000, 0x0000, 0x0000 }, /* R703 */
801 { 0x0000, 0x0000, 0x0000 }, /* R704 */
802 { 0x0000, 0x0000, 0x0000 }, /* R705 */
803 { 0x0000, 0x0000, 0x0000 }, /* R706 */
804 { 0x0000, 0x0000, 0x0000 }, /* R707 */
805 { 0x0000, 0x0000, 0x0000 }, /* R708 */
806 { 0x0000, 0x0000, 0x0000 }, /* R709 */
807 { 0x0000, 0x0000, 0x0000 }, /* R710 */
808 { 0x0000, 0x0000, 0x0000 }, /* R711 */
809 { 0x0000, 0x0000, 0x0000 }, /* R712 */
810 { 0x0000, 0x0000, 0x0000 }, /* R713 */
811 { 0x0000, 0x0000, 0x0000 }, /* R714 */
812 { 0x0000, 0x0000, 0x0000 }, /* R715 */
813 { 0x0000, 0x0000, 0x0000 }, /* R716 */
814 { 0x0000, 0x0000, 0x0000 }, /* R717 */
815 { 0x0000, 0x0000, 0x0000 }, /* R718 */
816 { 0x0000, 0x0000, 0x0000 }, /* R719 */
817 { 0x0000, 0x0000, 0x0000 }, /* R720 */
818 { 0x0000, 0x0000, 0x0000 }, /* R721 */
819 { 0x0000, 0x0000, 0x0000 }, /* R722 */
820 { 0x0000, 0x0000, 0x0000 }, /* R723 */
821 { 0x0000, 0x0000, 0x0000 }, /* R724 */
822 { 0x0000, 0x0000, 0x0000 }, /* R725 */
823 { 0x0000, 0x0000, 0x0000 }, /* R726 */
824 { 0x0000, 0x0000, 0x0000 }, /* R727 */
825 { 0x0000, 0x0000, 0x0000 }, /* R728 */
826 { 0x0000, 0x0000, 0x0000 }, /* R729 */
827 { 0x0000, 0x0000, 0x0000 }, /* R730 */
828 { 0x0000, 0x0000, 0x0000 }, /* R731 */
829 { 0x0000, 0x0000, 0x0000 }, /* R732 */
830 { 0x0000, 0x0000, 0x0000 }, /* R733 */
831 { 0x0000, 0x0000, 0x0000 }, /* R734 */
832 { 0x0000, 0x0000, 0x0000 }, /* R735 */
833 { 0x0000, 0x0000, 0x0000 }, /* R736 */
834 { 0x0000, 0x0000, 0x0000 }, /* R737 */
835 { 0x0000, 0x0000, 0x0000 }, /* R738 */
836 { 0x0000, 0x0000, 0x0000 }, /* R739 */
837 { 0x0000, 0x0000, 0x0000 }, /* R740 */
838 { 0x0000, 0x0000, 0x0000 }, /* R741 */
839 { 0x0000, 0x0000, 0x0000 }, /* R742 */
840 { 0x0000, 0x0000, 0x0000 }, /* R743 */
841 { 0x0000, 0x0000, 0x0000 }, /* R744 */
842 { 0x0000, 0x0000, 0x0000 }, /* R745 */
843 { 0x0000, 0x0000, 0x0000 }, /* R746 */
844 { 0x0000, 0x0000, 0x0000 }, /* R747 */
845 { 0x0000, 0x0000, 0x0000 }, /* R748 */
846 { 0x0000, 0x0000, 0x0000 }, /* R749 */
847 { 0x0000, 0x0000, 0x0000 }, /* R750 */
848 { 0x0000, 0x0000, 0x0000 }, /* R751 */
849 { 0x0000, 0x0000, 0x0000 }, /* R752 */
850 { 0x0000, 0x0000, 0x0000 }, /* R753 */
851 { 0x0000, 0x0000, 0x0000 }, /* R754 */
852 { 0x0000, 0x0000, 0x0000 }, /* R755 */
853 { 0x0000, 0x0000, 0x0000 }, /* R756 */
854 { 0x0000, 0x0000, 0x0000 }, /* R757 */
855 { 0x0000, 0x0000, 0x0000 }, /* R758 */
856 { 0x0000, 0x0000, 0x0000 }, /* R759 */
857 { 0x0000, 0x0000, 0x0000 }, /* R760 */
858 { 0x0000, 0x0000, 0x0000 }, /* R761 */
859 { 0x0000, 0x0000, 0x0000 }, /* R762 */
860 { 0x0000, 0x0000, 0x0000 }, /* R763 */
861 { 0x0000, 0x0000, 0x0000 }, /* R764 */
862 { 0x0000, 0x0000, 0x0000 }, /* R765 */
863 { 0x0000, 0x0000, 0x0000 }, /* R766 */
864 { 0x0000, 0x0000, 0x0000 }, /* R767 */
865 { 0xE1F8, 0xE1F8, 0x0000 }, /* R768 - AIF1 Control (1) */
866 { 0xCD1F, 0xCD1F, 0x0000 }, /* R769 - AIF1 Control (2) */
867 { 0xF000, 0xF000, 0x0000 }, /* R770 - AIF1 Master/Slave */
868 { 0x01F0, 0x01F0, 0x0000 }, /* R771 - AIF1 BCLK */
869 { 0x0FFF, 0x0FFF, 0x0000 }, /* R772 - AIF1ADC LRCLK */
870 { 0x0FFF, 0x0FFF, 0x0000 }, /* R773 - AIF1DAC LRCLK */
871 { 0x0003, 0x0003, 0x0000 }, /* R774 - AIF1DAC Data */
872 { 0x0003, 0x0003, 0x0000 }, /* R775 - AIF1ADC Data */
873 { 0x0000, 0x0000, 0x0000 }, /* R776 */
874 { 0x0000, 0x0000, 0x0000 }, /* R777 */
875 { 0x0000, 0x0000, 0x0000 }, /* R778 */
876 { 0x0000, 0x0000, 0x0000 }, /* R779 */
877 { 0x0000, 0x0000, 0x0000 }, /* R780 */
878 { 0x0000, 0x0000, 0x0000 }, /* R781 */
879 { 0x0000, 0x0000, 0x0000 }, /* R782 */
880 { 0x0000, 0x0000, 0x0000 }, /* R783 */
881 { 0xF1F8, 0xF1F8, 0x0000 }, /* R784 - AIF2 Control (1) */
882 { 0xFD1F, 0xFD1F, 0x0000 }, /* R785 - AIF2 Control (2) */
883 { 0xF000, 0xF000, 0x0000 }, /* R786 - AIF2 Master/Slave */
884 { 0x01F0, 0x01F0, 0x0000 }, /* R787 - AIF2 BCLK */
885 { 0x0FFF, 0x0FFF, 0x0000 }, /* R788 - AIF2ADC LRCLK */
886 { 0x0FFF, 0x0FFF, 0x0000 }, /* R789 - AIF2DAC LRCLK */
887 { 0x0003, 0x0003, 0x0000 }, /* R790 - AIF2DAC Data */
888 { 0x0003, 0x0003, 0x0000 }, /* R791 - AIF2ADC Data */
889 { 0x0000, 0x0000, 0x0000 }, /* R792 */
890 { 0x0000, 0x0000, 0x0000 }, /* R793 */
891 { 0x0000, 0x0000, 0x0000 }, /* R794 */
892 { 0x0000, 0x0000, 0x0000 }, /* R795 */
893 { 0x0000, 0x0000, 0x0000 }, /* R796 */
894 { 0x0000, 0x0000, 0x0000 }, /* R797 */
895 { 0x0000, 0x0000, 0x0000 }, /* R798 */
896 { 0x0000, 0x0000, 0x0000 }, /* R799 */
897 { 0x0000, 0x0000, 0x0000 }, /* R800 */
898 { 0x0000, 0x0000, 0x0000 }, /* R801 */
899 { 0x0000, 0x0000, 0x0000 }, /* R802 */
900 { 0x0000, 0x0000, 0x0000 }, /* R803 */
901 { 0x0000, 0x0000, 0x0000 }, /* R804 */
902 { 0x0000, 0x0000, 0x0000 }, /* R805 */
903 { 0x0000, 0x0000, 0x0000 }, /* R806 */
904 { 0x0000, 0x0000, 0x0000 }, /* R807 */
905 { 0x0000, 0x0000, 0x0000 }, /* R808 */
906 { 0x0000, 0x0000, 0x0000 }, /* R809 */
907 { 0x0000, 0x0000, 0x0000 }, /* R810 */
908 { 0x0000, 0x0000, 0x0000 }, /* R811 */
909 { 0x0000, 0x0000, 0x0000 }, /* R812 */
910 { 0x0000, 0x0000, 0x0000 }, /* R813 */
911 { 0x0000, 0x0000, 0x0000 }, /* R814 */
912 { 0x0000, 0x0000, 0x0000 }, /* R815 */
913 { 0x0000, 0x0000, 0x0000 }, /* R816 */
914 { 0x0000, 0x0000, 0x0000 }, /* R817 */
915 { 0x0000, 0x0000, 0x0000 }, /* R818 */
916 { 0x0000, 0x0000, 0x0000 }, /* R819 */
917 { 0x0000, 0x0000, 0x0000 }, /* R820 */
918 { 0x0000, 0x0000, 0x0000 }, /* R821 */
919 { 0x0000, 0x0000, 0x0000 }, /* R822 */
920 { 0x0000, 0x0000, 0x0000 }, /* R823 */
921 { 0x0000, 0x0000, 0x0000 }, /* R824 */
922 { 0x0000, 0x0000, 0x0000 }, /* R825 */
923 { 0x0000, 0x0000, 0x0000 }, /* R826 */
924 { 0x0000, 0x0000, 0x0000 }, /* R827 */
925 { 0x0000, 0x0000, 0x0000 }, /* R828 */
926 { 0x0000, 0x0000, 0x0000 }, /* R829 */
927 { 0x0000, 0x0000, 0x0000 }, /* R830 */
928 { 0x0000, 0x0000, 0x0000 }, /* R831 */
929 { 0x0000, 0x0000, 0x0000 }, /* R832 */
930 { 0x0000, 0x0000, 0x0000 }, /* R833 */
931 { 0x0000, 0x0000, 0x0000 }, /* R834 */
932 { 0x0000, 0x0000, 0x0000 }, /* R835 */
933 { 0x0000, 0x0000, 0x0000 }, /* R836 */
934 { 0x0000, 0x0000, 0x0000 }, /* R837 */
935 { 0x0000, 0x0000, 0x0000 }, /* R838 */
936 { 0x0000, 0x0000, 0x0000 }, /* R839 */
937 { 0x0000, 0x0000, 0x0000 }, /* R840 */
938 { 0x0000, 0x0000, 0x0000 }, /* R841 */
939 { 0x0000, 0x0000, 0x0000 }, /* R842 */
940 { 0x0000, 0x0000, 0x0000 }, /* R843 */
941 { 0x0000, 0x0000, 0x0000 }, /* R844 */
942 { 0x0000, 0x0000, 0x0000 }, /* R845 */
943 { 0x0000, 0x0000, 0x0000 }, /* R846 */
944 { 0x0000, 0x0000, 0x0000 }, /* R847 */
945 { 0x0000, 0x0000, 0x0000 }, /* R848 */
946 { 0x0000, 0x0000, 0x0000 }, /* R849 */
947 { 0x0000, 0x0000, 0x0000 }, /* R850 */
948 { 0x0000, 0x0000, 0x0000 }, /* R851 */
949 { 0x0000, 0x0000, 0x0000 }, /* R852 */
950 { 0x0000, 0x0000, 0x0000 }, /* R853 */
951 { 0x0000, 0x0000, 0x0000 }, /* R854 */
952 { 0x0000, 0x0000, 0x0000 }, /* R855 */
953 { 0x0000, 0x0000, 0x0000 }, /* R856 */
954 { 0x0000, 0x0000, 0x0000 }, /* R857 */
955 { 0x0000, 0x0000, 0x0000 }, /* R858 */
956 { 0x0000, 0x0000, 0x0000 }, /* R859 */
957 { 0x0000, 0x0000, 0x0000 }, /* R860 */
958 { 0x0000, 0x0000, 0x0000 }, /* R861 */
959 { 0x0000, 0x0000, 0x0000 }, /* R862 */
960 { 0x0000, 0x0000, 0x0000 }, /* R863 */
961 { 0x0000, 0x0000, 0x0000 }, /* R864 */
962 { 0x0000, 0x0000, 0x0000 }, /* R865 */
963 { 0x0000, 0x0000, 0x0000 }, /* R866 */
964 { 0x0000, 0x0000, 0x0000 }, /* R867 */
965 { 0x0000, 0x0000, 0x0000 }, /* R868 */
966 { 0x0000, 0x0000, 0x0000 }, /* R869 */
967 { 0x0000, 0x0000, 0x0000 }, /* R870 */
968 { 0x0000, 0x0000, 0x0000 }, /* R871 */
969 { 0x0000, 0x0000, 0x0000 }, /* R872 */
970 { 0x0000, 0x0000, 0x0000 }, /* R873 */
971 { 0x0000, 0x0000, 0x0000 }, /* R874 */
972 { 0x0000, 0x0000, 0x0000 }, /* R875 */
973 { 0x0000, 0x0000, 0x0000 }, /* R876 */
974 { 0x0000, 0x0000, 0x0000 }, /* R877 */
975 { 0x0000, 0x0000, 0x0000 }, /* R878 */
976 { 0x0000, 0x0000, 0x0000 }, /* R879 */
977 { 0x0000, 0x0000, 0x0000 }, /* R880 */
978 { 0x0000, 0x0000, 0x0000 }, /* R881 */
979 { 0x0000, 0x0000, 0x0000 }, /* R882 */
980 { 0x0000, 0x0000, 0x0000 }, /* R883 */
981 { 0x0000, 0x0000, 0x0000 }, /* R884 */
982 { 0x0000, 0x0000, 0x0000 }, /* R885 */
983 { 0x0000, 0x0000, 0x0000 }, /* R886 */
984 { 0x0000, 0x0000, 0x0000 }, /* R887 */
985 { 0x0000, 0x0000, 0x0000 }, /* R888 */
986 { 0x0000, 0x0000, 0x0000 }, /* R889 */
987 { 0x0000, 0x0000, 0x0000 }, /* R890 */
988 { 0x0000, 0x0000, 0x0000 }, /* R891 */
989 { 0x0000, 0x0000, 0x0000 }, /* R892 */
990 { 0x0000, 0x0000, 0x0000 }, /* R893 */
991 { 0x0000, 0x0000, 0x0000 }, /* R894 */
992 { 0x0000, 0x0000, 0x0000 }, /* R895 */
993 { 0x0000, 0x0000, 0x0000 }, /* R896 */
994 { 0x0000, 0x0000, 0x0000 }, /* R897 */
995 { 0x0000, 0x0000, 0x0000 }, /* R898 */
996 { 0x0000, 0x0000, 0x0000 }, /* R899 */
997 { 0x0000, 0x0000, 0x0000 }, /* R900 */
998 { 0x0000, 0x0000, 0x0000 }, /* R901 */
999 { 0x0000, 0x0000, 0x0000 }, /* R902 */
1000 { 0x0000, 0x0000, 0x0000 }, /* R903 */
1001 { 0x0000, 0x0000, 0x0000 }, /* R904 */
1002 { 0x0000, 0x0000, 0x0000 }, /* R905 */
1003 { 0x0000, 0x0000, 0x0000 }, /* R906 */
1004 { 0x0000, 0x0000, 0x0000 }, /* R907 */
1005 { 0x0000, 0x0000, 0x0000 }, /* R908 */
1006 { 0x0000, 0x0000, 0x0000 }, /* R909 */
1007 { 0x0000, 0x0000, 0x0000 }, /* R910 */
1008 { 0x0000, 0x0000, 0x0000 }, /* R911 */
1009 { 0x0000, 0x0000, 0x0000 }, /* R912 */
1010 { 0x0000, 0x0000, 0x0000 }, /* R913 */
1011 { 0x0000, 0x0000, 0x0000 }, /* R914 */
1012 { 0x0000, 0x0000, 0x0000 }, /* R915 */
1013 { 0x0000, 0x0000, 0x0000 }, /* R916 */
1014 { 0x0000, 0x0000, 0x0000 }, /* R917 */
1015 { 0x0000, 0x0000, 0x0000 }, /* R918 */
1016 { 0x0000, 0x0000, 0x0000 }, /* R919 */
1017 { 0x0000, 0x0000, 0x0000 }, /* R920 */
1018 { 0x0000, 0x0000, 0x0000 }, /* R921 */
1019 { 0x0000, 0x0000, 0x0000 }, /* R922 */
1020 { 0x0000, 0x0000, 0x0000 }, /* R923 */
1021 { 0x0000, 0x0000, 0x0000 }, /* R924 */
1022 { 0x0000, 0x0000, 0x0000 }, /* R925 */
1023 { 0x0000, 0x0000, 0x0000 }, /* R926 */
1024 { 0x0000, 0x0000, 0x0000 }, /* R927 */
1025 { 0x0000, 0x0000, 0x0000 }, /* R928 */
1026 { 0x0000, 0x0000, 0x0000 }, /* R929 */
1027 { 0x0000, 0x0000, 0x0000 }, /* R930 */
1028 { 0x0000, 0x0000, 0x0000 }, /* R931 */
1029 { 0x0000, 0x0000, 0x0000 }, /* R932 */
1030 { 0x0000, 0x0000, 0x0000 }, /* R933 */
1031 { 0x0000, 0x0000, 0x0000 }, /* R934 */
1032 { 0x0000, 0x0000, 0x0000 }, /* R935 */
1033 { 0x0000, 0x0000, 0x0000 }, /* R936 */
1034 { 0x0000, 0x0000, 0x0000 }, /* R937 */
1035 { 0x0000, 0x0000, 0x0000 }, /* R938 */
1036 { 0x0000, 0x0000, 0x0000 }, /* R939 */
1037 { 0x0000, 0x0000, 0x0000 }, /* R940 */
1038 { 0x0000, 0x0000, 0x0000 }, /* R941 */
1039 { 0x0000, 0x0000, 0x0000 }, /* R942 */
1040 { 0x0000, 0x0000, 0x0000 }, /* R943 */
1041 { 0x0000, 0x0000, 0x0000 }, /* R944 */
1042 { 0x0000, 0x0000, 0x0000 }, /* R945 */
1043 { 0x0000, 0x0000, 0x0000 }, /* R946 */
1044 { 0x0000, 0x0000, 0x0000 }, /* R947 */
1045 { 0x0000, 0x0000, 0x0000 }, /* R948 */
1046 { 0x0000, 0x0000, 0x0000 }, /* R949 */
1047 { 0x0000, 0x0000, 0x0000 }, /* R950 */
1048 { 0x0000, 0x0000, 0x0000 }, /* R951 */
1049 { 0x0000, 0x0000, 0x0000 }, /* R952 */
1050 { 0x0000, 0x0000, 0x0000 }, /* R953 */
1051 { 0x0000, 0x0000, 0x0000 }, /* R954 */
1052 { 0x0000, 0x0000, 0x0000 }, /* R955 */
1053 { 0x0000, 0x0000, 0x0000 }, /* R956 */
1054 { 0x0000, 0x0000, 0x0000 }, /* R957 */
1055 { 0x0000, 0x0000, 0x0000 }, /* R958 */
1056 { 0x0000, 0x0000, 0x0000 }, /* R959 */
1057 { 0x0000, 0x0000, 0x0000 }, /* R960 */
1058 { 0x0000, 0x0000, 0x0000 }, /* R961 */
1059 { 0x0000, 0x0000, 0x0000 }, /* R962 */
1060 { 0x0000, 0x0000, 0x0000 }, /* R963 */
1061 { 0x0000, 0x0000, 0x0000 }, /* R964 */
1062 { 0x0000, 0x0000, 0x0000 }, /* R965 */
1063 { 0x0000, 0x0000, 0x0000 }, /* R966 */
1064 { 0x0000, 0x0000, 0x0000 }, /* R967 */
1065 { 0x0000, 0x0000, 0x0000 }, /* R968 */
1066 { 0x0000, 0x0000, 0x0000 }, /* R969 */
1067 { 0x0000, 0x0000, 0x0000 }, /* R970 */
1068 { 0x0000, 0x0000, 0x0000 }, /* R971 */
1069 { 0x0000, 0x0000, 0x0000 }, /* R972 */
1070 { 0x0000, 0x0000, 0x0000 }, /* R973 */
1071 { 0x0000, 0x0000, 0x0000 }, /* R974 */
1072 { 0x0000, 0x0000, 0x0000 }, /* R975 */
1073 { 0x0000, 0x0000, 0x0000 }, /* R976 */
1074 { 0x0000, 0x0000, 0x0000 }, /* R977 */
1075 { 0x0000, 0x0000, 0x0000 }, /* R978 */
1076 { 0x0000, 0x0000, 0x0000 }, /* R979 */
1077 { 0x0000, 0x0000, 0x0000 }, /* R980 */
1078 { 0x0000, 0x0000, 0x0000 }, /* R981 */
1079 { 0x0000, 0x0000, 0x0000 }, /* R982 */
1080 { 0x0000, 0x0000, 0x0000 }, /* R983 */
1081 { 0x0000, 0x0000, 0x0000 }, /* R984 */
1082 { 0x0000, 0x0000, 0x0000 }, /* R985 */
1083 { 0x0000, 0x0000, 0x0000 }, /* R986 */
1084 { 0x0000, 0x0000, 0x0000 }, /* R987 */
1085 { 0x0000, 0x0000, 0x0000 }, /* R988 */
1086 { 0x0000, 0x0000, 0x0000 }, /* R989 */
1087 { 0x0000, 0x0000, 0x0000 }, /* R990 */
1088 { 0x0000, 0x0000, 0x0000 }, /* R991 */
1089 { 0x0000, 0x0000, 0x0000 }, /* R992 */
1090 { 0x0000, 0x0000, 0x0000 }, /* R993 */
1091 { 0x0000, 0x0000, 0x0000 }, /* R994 */
1092 { 0x0000, 0x0000, 0x0000 }, /* R995 */
1093 { 0x0000, 0x0000, 0x0000 }, /* R996 */
1094 { 0x0000, 0x0000, 0x0000 }, /* R997 */
1095 { 0x0000, 0x0000, 0x0000 }, /* R998 */
1096 { 0x0000, 0x0000, 0x0000 }, /* R999 */
1097 { 0x0000, 0x0000, 0x0000 }, /* R1000 */
1098 { 0x0000, 0x0000, 0x0000 }, /* R1001 */
1099 { 0x0000, 0x0000, 0x0000 }, /* R1002 */
1100 { 0x0000, 0x0000, 0x0000 }, /* R1003 */
1101 { 0x0000, 0x0000, 0x0000 }, /* R1004 */
1102 { 0x0000, 0x0000, 0x0000 }, /* R1005 */
1103 { 0x0000, 0x0000, 0x0000 }, /* R1006 */
1104 { 0x0000, 0x0000, 0x0000 }, /* R1007 */
1105 { 0x0000, 0x0000, 0x0000 }, /* R1008 */
1106 { 0x0000, 0x0000, 0x0000 }, /* R1009 */
1107 { 0x0000, 0x0000, 0x0000 }, /* R1010 */
1108 { 0x0000, 0x0000, 0x0000 }, /* R1011 */
1109 { 0x0000, 0x0000, 0x0000 }, /* R1012 */
1110 { 0x0000, 0x0000, 0x0000 }, /* R1013 */
1111 { 0x0000, 0x0000, 0x0000 }, /* R1014 */
1112 { 0x0000, 0x0000, 0x0000 }, /* R1015 */
1113 { 0x0000, 0x0000, 0x0000 }, /* R1016 */
1114 { 0x0000, 0x0000, 0x0000 }, /* R1017 */
1115 { 0x0000, 0x0000, 0x0000 }, /* R1018 */
1116 { 0x0000, 0x0000, 0x0000 }, /* R1019 */
1117 { 0x0000, 0x0000, 0x0000 }, /* R1020 */
1118 { 0x0000, 0x0000, 0x0000 }, /* R1021 */
1119 { 0x0000, 0x0000, 0x0000 }, /* R1022 */
1120 { 0x0000, 0x0000, 0x0000 }, /* R1023 */
1121 { 0x00FF, 0x01FF, 0x0000 }, /* R1024 - AIF1 ADC1 Left Volume */
1122 { 0x00FF, 0x01FF, 0x0000 }, /* R1025 - AIF1 ADC1 Right Volume */
1123 { 0x00FF, 0x01FF, 0x0000 }, /* R1026 - AIF1 DAC1 Left Volume */
1124 { 0x00FF, 0x01FF, 0x0000 }, /* R1027 - AIF1 DAC1 Right Volume */
1125 { 0x00FF, 0x01FF, 0x0000 }, /* R1028 - AIF1 ADC2 Left Volume */
1126 { 0x00FF, 0x01FF, 0x0000 }, /* R1029 - AIF1 ADC2 Right Volume */
1127 { 0x00FF, 0x01FF, 0x0000 }, /* R1030 - AIF1 DAC2 Left Volume */
1128 { 0x00FF, 0x01FF, 0x0000 }, /* R1031 - AIF1 DAC2 Right Volume */
1129 { 0x0000, 0x0000, 0x0000 }, /* R1032 */
1130 { 0x0000, 0x0000, 0x0000 }, /* R1033 */
1131 { 0x0000, 0x0000, 0x0000 }, /* R1034 */
1132 { 0x0000, 0x0000, 0x0000 }, /* R1035 */
1133 { 0x0000, 0x0000, 0x0000 }, /* R1036 */
1134 { 0x0000, 0x0000, 0x0000 }, /* R1037 */
1135 { 0x0000, 0x0000, 0x0000 }, /* R1038 */
1136 { 0x0000, 0x0000, 0x0000 }, /* R1039 */
1137 { 0xF800, 0xF800, 0x0000 }, /* R1040 - AIF1 ADC1 Filters */
1138 { 0x7800, 0x7800, 0x0000 }, /* R1041 - AIF1 ADC2 Filters */
1139 { 0x0000, 0x0000, 0x0000 }, /* R1042 */
1140 { 0x0000, 0x0000, 0x0000 }, /* R1043 */
1141 { 0x0000, 0x0000, 0x0000 }, /* R1044 */
1142 { 0x0000, 0x0000, 0x0000 }, /* R1045 */
1143 { 0x0000, 0x0000, 0x0000 }, /* R1046 */
1144 { 0x0000, 0x0000, 0x0000 }, /* R1047 */
1145 { 0x0000, 0x0000, 0x0000 }, /* R1048 */
1146 { 0x0000, 0x0000, 0x0000 }, /* R1049 */
1147 { 0x0000, 0x0000, 0x0000 }, /* R1050 */
1148 { 0x0000, 0x0000, 0x0000 }, /* R1051 */
1149 { 0x0000, 0x0000, 0x0000 }, /* R1052 */
1150 { 0x0000, 0x0000, 0x0000 }, /* R1053 */
1151 { 0x0000, 0x0000, 0x0000 }, /* R1054 */
1152 { 0x0000, 0x0000, 0x0000 }, /* R1055 */
1153 { 0x02B6, 0x02B6, 0x0000 }, /* R1056 - AIF1 DAC1 Filters (1) */
1154 { 0x3F00, 0x3F00, 0x0000 }, /* R1057 - AIF1 DAC1 Filters (2) */
1155 { 0x02B6, 0x02B6, 0x0000 }, /* R1058 - AIF1 DAC2 Filters (1) */
1156 { 0x3F00, 0x3F00, 0x0000 }, /* R1059 - AIF1 DAC2 Filters (2) */
1157 { 0x0000, 0x0000, 0x0000 }, /* R1060 */
1158 { 0x0000, 0x0000, 0x0000 }, /* R1061 */
1159 { 0x0000, 0x0000, 0x0000 }, /* R1062 */
1160 { 0x0000, 0x0000, 0x0000 }, /* R1063 */
1161 { 0x0000, 0x0000, 0x0000 }, /* R1064 */
1162 { 0x0000, 0x0000, 0x0000 }, /* R1065 */
1163 { 0x0000, 0x0000, 0x0000 }, /* R1066 */
1164 { 0x0000, 0x0000, 0x0000 }, /* R1067 */
1165 { 0x0000, 0x0000, 0x0000 }, /* R1068 */
1166 { 0x0000, 0x0000, 0x0000 }, /* R1069 */
1167 { 0x0000, 0x0000, 0x0000 }, /* R1070 */
1168 { 0x0000, 0x0000, 0x0000 }, /* R1071 */
1169 { 0x0000, 0x0000, 0x0000 }, /* R1072 */
1170 { 0x0000, 0x0000, 0x0000 }, /* R1073 */
1171 { 0x0000, 0x0000, 0x0000 }, /* R1074 */
1172 { 0x0000, 0x0000, 0x0000 }, /* R1075 */
1173 { 0x0000, 0x0000, 0x0000 }, /* R1076 */
1174 { 0x0000, 0x0000, 0x0000 }, /* R1077 */
1175 { 0x0000, 0x0000, 0x0000 }, /* R1078 */
1176 { 0x0000, 0x0000, 0x0000 }, /* R1079 */
1177 { 0x0000, 0x0000, 0x0000 }, /* R1080 */
1178 { 0x0000, 0x0000, 0x0000 }, /* R1081 */
1179 { 0x0000, 0x0000, 0x0000 }, /* R1082 */
1180 { 0x0000, 0x0000, 0x0000 }, /* R1083 */
1181 { 0x0000, 0x0000, 0x0000 }, /* R1084 */
1182 { 0x0000, 0x0000, 0x0000 }, /* R1085 */
1183 { 0x0000, 0x0000, 0x0000 }, /* R1086 */
1184 { 0x0000, 0x0000, 0x0000 }, /* R1087 */
1185 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1088 - AIF1 DRC1 (1) */
1186 { 0x1FFF, 0x1FFF, 0x0000 }, /* R1089 - AIF1 DRC1 (2) */
1187 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1090 - AIF1 DRC1 (3) */
1188 { 0x07FF, 0x07FF, 0x0000 }, /* R1091 - AIF1 DRC1 (4) */
1189 { 0x03FF, 0x03FF, 0x0000 }, /* R1092 - AIF1 DRC1 (5) */
1190 { 0x0000, 0x0000, 0x0000 }, /* R1093 */
1191 { 0x0000, 0x0000, 0x0000 }, /* R1094 */
1192 { 0x0000, 0x0000, 0x0000 }, /* R1095 */
1193 { 0x0000, 0x0000, 0x0000 }, /* R1096 */
1194 { 0x0000, 0x0000, 0x0000 }, /* R1097 */
1195 { 0x0000, 0x0000, 0x0000 }, /* R1098 */
1196 { 0x0000, 0x0000, 0x0000 }, /* R1099 */
1197 { 0x0000, 0x0000, 0x0000 }, /* R1100 */
1198 { 0x0000, 0x0000, 0x0000 }, /* R1101 */
1199 { 0x0000, 0x0000, 0x0000 }, /* R1102 */
1200 { 0x0000, 0x0000, 0x0000 }, /* R1103 */
1201 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1104 - AIF1 DRC2 (1) */
1202 { 0x1FFF, 0x1FFF, 0x0000 }, /* R1105 - AIF1 DRC2 (2) */
1203 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1106 - AIF1 DRC2 (3) */
1204 { 0x07FF, 0x07FF, 0x0000 }, /* R1107 - AIF1 DRC2 (4) */
1205 { 0x03FF, 0x03FF, 0x0000 }, /* R1108 - AIF1 DRC2 (5) */
1206 { 0x0000, 0x0000, 0x0000 }, /* R1109 */
1207 { 0x0000, 0x0000, 0x0000 }, /* R1110 */
1208 { 0x0000, 0x0000, 0x0000 }, /* R1111 */
1209 { 0x0000, 0x0000, 0x0000 }, /* R1112 */
1210 { 0x0000, 0x0000, 0x0000 }, /* R1113 */
1211 { 0x0000, 0x0000, 0x0000 }, /* R1114 */
1212 { 0x0000, 0x0000, 0x0000 }, /* R1115 */
1213 { 0x0000, 0x0000, 0x0000 }, /* R1116 */
1214 { 0x0000, 0x0000, 0x0000 }, /* R1117 */
1215 { 0x0000, 0x0000, 0x0000 }, /* R1118 */
1216 { 0x0000, 0x0000, 0x0000 }, /* R1119 */
1217 { 0x0000, 0x0000, 0x0000 }, /* R1120 */
1218 { 0x0000, 0x0000, 0x0000 }, /* R1121 */
1219 { 0x0000, 0x0000, 0x0000 }, /* R1122 */
1220 { 0x0000, 0x0000, 0x0000 }, /* R1123 */
1221 { 0x0000, 0x0000, 0x0000 }, /* R1124 */
1222 { 0x0000, 0x0000, 0x0000 }, /* R1125 */
1223 { 0x0000, 0x0000, 0x0000 }, /* R1126 */
1224 { 0x0000, 0x0000, 0x0000 }, /* R1127 */
1225 { 0x0000, 0x0000, 0x0000 }, /* R1128 */
1226 { 0x0000, 0x0000, 0x0000 }, /* R1129 */
1227 { 0x0000, 0x0000, 0x0000 }, /* R1130 */
1228 { 0x0000, 0x0000, 0x0000 }, /* R1131 */
1229 { 0x0000, 0x0000, 0x0000 }, /* R1132 */
1230 { 0x0000, 0x0000, 0x0000 }, /* R1133 */
1231 { 0x0000, 0x0000, 0x0000 }, /* R1134 */
1232 { 0x0000, 0x0000, 0x0000 }, /* R1135 */
1233 { 0x0000, 0x0000, 0x0000 }, /* R1136 */
1234 { 0x0000, 0x0000, 0x0000 }, /* R1137 */
1235 { 0x0000, 0x0000, 0x0000 }, /* R1138 */
1236 { 0x0000, 0x0000, 0x0000 }, /* R1139 */
1237 { 0x0000, 0x0000, 0x0000 }, /* R1140 */
1238 { 0x0000, 0x0000, 0x0000 }, /* R1141 */
1239 { 0x0000, 0x0000, 0x0000 }, /* R1142 */
1240 { 0x0000, 0x0000, 0x0000 }, /* R1143 */
1241 { 0x0000, 0x0000, 0x0000 }, /* R1144 */
1242 { 0x0000, 0x0000, 0x0000 }, /* R1145 */
1243 { 0x0000, 0x0000, 0x0000 }, /* R1146 */
1244 { 0x0000, 0x0000, 0x0000 }, /* R1147 */
1245 { 0x0000, 0x0000, 0x0000 }, /* R1148 */
1246 { 0x0000, 0x0000, 0x0000 }, /* R1149 */
1247 { 0x0000, 0x0000, 0x0000 }, /* R1150 */
1248 { 0x0000, 0x0000, 0x0000 }, /* R1151 */
1249 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1152 - AIF1 DAC1 EQ Gains (1) */
1250 { 0xFFC0, 0xFFC0, 0x0000 }, /* R1153 - AIF1 DAC1 EQ Gains (2) */
1251 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1154 - AIF1 DAC1 EQ Band 1 A */
1252 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1155 - AIF1 DAC1 EQ Band 1 B */
1253 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1156 - AIF1 DAC1 EQ Band 1 PG */
1254 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1157 - AIF1 DAC1 EQ Band 2 A */
1255 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1158 - AIF1 DAC1 EQ Band 2 B */
1256 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1159 - AIF1 DAC1 EQ Band 2 C */
1257 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1160 - AIF1 DAC1 EQ Band 2 PG */
1258 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1161 - AIF1 DAC1 EQ Band 3 A */
1259 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1162 - AIF1 DAC1 EQ Band 3 B */
1260 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1163 - AIF1 DAC1 EQ Band 3 C */
1261 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1164 - AIF1 DAC1 EQ Band 3 PG */
1262 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1165 - AIF1 DAC1 EQ Band 4 A */
1263 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1166 - AIF1 DAC1 EQ Band 4 B */
1264 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1167 - AIF1 DAC1 EQ Band 4 C */
1265 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1168 - AIF1 DAC1 EQ Band 4 PG */
1266 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1169 - AIF1 DAC1 EQ Band 5 A */
1267 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1170 - AIF1 DAC1 EQ Band 5 B */
1268 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1171 - AIF1 DAC1 EQ Band 5 PG */
1269 { 0x0000, 0x0000, 0x0000 }, /* R1172 */
1270 { 0x0000, 0x0000, 0x0000 }, /* R1173 */
1271 { 0x0000, 0x0000, 0x0000 }, /* R1174 */
1272 { 0x0000, 0x0000, 0x0000 }, /* R1175 */
1273 { 0x0000, 0x0000, 0x0000 }, /* R1176 */
1274 { 0x0000, 0x0000, 0x0000 }, /* R1177 */
1275 { 0x0000, 0x0000, 0x0000 }, /* R1178 */
1276 { 0x0000, 0x0000, 0x0000 }, /* R1179 */
1277 { 0x0000, 0x0000, 0x0000 }, /* R1180 */
1278 { 0x0000, 0x0000, 0x0000 }, /* R1181 */
1279 { 0x0000, 0x0000, 0x0000 }, /* R1182 */
1280 { 0x0000, 0x0000, 0x0000 }, /* R1183 */
1281 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1184 - AIF1 DAC2 EQ Gains (1) */
1282 { 0xFFC0, 0xFFC0, 0x0000 }, /* R1185 - AIF1 DAC2 EQ Gains (2) */
1283 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1186 - AIF1 DAC2 EQ Band 1 A */
1284 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1187 - AIF1 DAC2 EQ Band 1 B */
1285 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1188 - AIF1 DAC2 EQ Band 1 PG */
1286 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1189 - AIF1 DAC2 EQ Band 2 A */
1287 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1190 - AIF1 DAC2 EQ Band 2 B */
1288 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1191 - AIF1 DAC2 EQ Band 2 C */
1289 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1192 - AIF1 DAC2 EQ Band 2 PG */
1290 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1193 - AIF1 DAC2 EQ Band 3 A */
1291 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1194 - AIF1 DAC2 EQ Band 3 B */
1292 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1195 - AIF1 DAC2 EQ Band 3 C */
1293 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1196 - AIF1 DAC2 EQ Band 3 PG */
1294 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1197 - AIF1 DAC2 EQ Band 4 A */
1295 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1198 - AIF1 DAC2 EQ Band 4 B */
1296 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1199 - AIF1 DAC2 EQ Band 4 C */
1297 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1200 - AIF1 DAC2 EQ Band 4 PG */
1298 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1201 - AIF1 DAC2 EQ Band 5 A */
1299 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1202 - AIF1 DAC2 EQ Band 5 B */
1300 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1203 - AIF1 DAC2 EQ Band 5 PG */
1301 { 0x0000, 0x0000, 0x0000 }, /* R1204 */
1302 { 0x0000, 0x0000, 0x0000 }, /* R1205 */
1303 { 0x0000, 0x0000, 0x0000 }, /* R1206 */
1304 { 0x0000, 0x0000, 0x0000 }, /* R1207 */
1305 { 0x0000, 0x0000, 0x0000 }, /* R1208 */
1306 { 0x0000, 0x0000, 0x0000 }, /* R1209 */
1307 { 0x0000, 0x0000, 0x0000 }, /* R1210 */
1308 { 0x0000, 0x0000, 0x0000 }, /* R1211 */
1309 { 0x0000, 0x0000, 0x0000 }, /* R1212 */
1310 { 0x0000, 0x0000, 0x0000 }, /* R1213 */
1311 { 0x0000, 0x0000, 0x0000 }, /* R1214 */
1312 { 0x0000, 0x0000, 0x0000 }, /* R1215 */
1313 { 0x0000, 0x0000, 0x0000 }, /* R1216 */
1314 { 0x0000, 0x0000, 0x0000 }, /* R1217 */
1315 { 0x0000, 0x0000, 0x0000 }, /* R1218 */
1316 { 0x0000, 0x0000, 0x0000 }, /* R1219 */
1317 { 0x0000, 0x0000, 0x0000 }, /* R1220 */
1318 { 0x0000, 0x0000, 0x0000 }, /* R1221 */
1319 { 0x0000, 0x0000, 0x0000 }, /* R1222 */
1320 { 0x0000, 0x0000, 0x0000 }, /* R1223 */
1321 { 0x0000, 0x0000, 0x0000 }, /* R1224 */
1322 { 0x0000, 0x0000, 0x0000 }, /* R1225 */
1323 { 0x0000, 0x0000, 0x0000 }, /* R1226 */
1324 { 0x0000, 0x0000, 0x0000 }, /* R1227 */
1325 { 0x0000, 0x0000, 0x0000 }, /* R1228 */
1326 { 0x0000, 0x0000, 0x0000 }, /* R1229 */
1327 { 0x0000, 0x0000, 0x0000 }, /* R1230 */
1328 { 0x0000, 0x0000, 0x0000 }, /* R1231 */
1329 { 0x0000, 0x0000, 0x0000 }, /* R1232 */
1330 { 0x0000, 0x0000, 0x0000 }, /* R1233 */
1331 { 0x0000, 0x0000, 0x0000 }, /* R1234 */
1332 { 0x0000, 0x0000, 0x0000 }, /* R1235 */
1333 { 0x0000, 0x0000, 0x0000 }, /* R1236 */
1334 { 0x0000, 0x0000, 0x0000 }, /* R1237 */
1335 { 0x0000, 0x0000, 0x0000 }, /* R1238 */
1336 { 0x0000, 0x0000, 0x0000 }, /* R1239 */
1337 { 0x0000, 0x0000, 0x0000 }, /* R1240 */
1338 { 0x0000, 0x0000, 0x0000 }, /* R1241 */
1339 { 0x0000, 0x0000, 0x0000 }, /* R1242 */
1340 { 0x0000, 0x0000, 0x0000 }, /* R1243 */
1341 { 0x0000, 0x0000, 0x0000 }, /* R1244 */
1342 { 0x0000, 0x0000, 0x0000 }, /* R1245 */
1343 { 0x0000, 0x0000, 0x0000 }, /* R1246 */
1344 { 0x0000, 0x0000, 0x0000 }, /* R1247 */
1345 { 0x0000, 0x0000, 0x0000 }, /* R1248 */
1346 { 0x0000, 0x0000, 0x0000 }, /* R1249 */
1347 { 0x0000, 0x0000, 0x0000 }, /* R1250 */
1348 { 0x0000, 0x0000, 0x0000 }, /* R1251 */
1349 { 0x0000, 0x0000, 0x0000 }, /* R1252 */
1350 { 0x0000, 0x0000, 0x0000 }, /* R1253 */
1351 { 0x0000, 0x0000, 0x0000 }, /* R1254 */
1352 { 0x0000, 0x0000, 0x0000 }, /* R1255 */
1353 { 0x0000, 0x0000, 0x0000 }, /* R1256 */
1354 { 0x0000, 0x0000, 0x0000 }, /* R1257 */
1355 { 0x0000, 0x0000, 0x0000 }, /* R1258 */
1356 { 0x0000, 0x0000, 0x0000 }, /* R1259 */
1357 { 0x0000, 0x0000, 0x0000 }, /* R1260 */
1358 { 0x0000, 0x0000, 0x0000 }, /* R1261 */
1359 { 0x0000, 0x0000, 0x0000 }, /* R1262 */
1360 { 0x0000, 0x0000, 0x0000 }, /* R1263 */
1361 { 0x0000, 0x0000, 0x0000 }, /* R1264 */
1362 { 0x0000, 0x0000, 0x0000 }, /* R1265 */
1363 { 0x0000, 0x0000, 0x0000 }, /* R1266 */
1364 { 0x0000, 0x0000, 0x0000 }, /* R1267 */
1365 { 0x0000, 0x0000, 0x0000 }, /* R1268 */
1366 { 0x0000, 0x0000, 0x0000 }, /* R1269 */
1367 { 0x0000, 0x0000, 0x0000 }, /* R1270 */
1368 { 0x0000, 0x0000, 0x0000 }, /* R1271 */
1369 { 0x0000, 0x0000, 0x0000 }, /* R1272 */
1370 { 0x0000, 0x0000, 0x0000 }, /* R1273 */
1371 { 0x0000, 0x0000, 0x0000 }, /* R1274 */
1372 { 0x0000, 0x0000, 0x0000 }, /* R1275 */
1373 { 0x0000, 0x0000, 0x0000 }, /* R1276 */
1374 { 0x0000, 0x0000, 0x0000 }, /* R1277 */
1375 { 0x0000, 0x0000, 0x0000 }, /* R1278 */
1376 { 0x0000, 0x0000, 0x0000 }, /* R1279 */
1377 { 0x00FF, 0x01FF, 0x0000 }, /* R1280 - AIF2 ADC Left Volume */
1378 { 0x00FF, 0x01FF, 0x0000 }, /* R1281 - AIF2 ADC Right Volume */
1379 { 0x00FF, 0x01FF, 0x0000 }, /* R1282 - AIF2 DAC Left Volume */
1380 { 0x00FF, 0x01FF, 0x0000 }, /* R1283 - AIF2 DAC Right Volume */
1381 { 0x0000, 0x0000, 0x0000 }, /* R1284 */
1382 { 0x0000, 0x0000, 0x0000 }, /* R1285 */
1383 { 0x0000, 0x0000, 0x0000 }, /* R1286 */
1384 { 0x0000, 0x0000, 0x0000 }, /* R1287 */
1385 { 0x0000, 0x0000, 0x0000 }, /* R1288 */
1386 { 0x0000, 0x0000, 0x0000 }, /* R1289 */
1387 { 0x0000, 0x0000, 0x0000 }, /* R1290 */
1388 { 0x0000, 0x0000, 0x0000 }, /* R1291 */
1389 { 0x0000, 0x0000, 0x0000 }, /* R1292 */
1390 { 0x0000, 0x0000, 0x0000 }, /* R1293 */
1391 { 0x0000, 0x0000, 0x0000 }, /* R1294 */
1392 { 0x0000, 0x0000, 0x0000 }, /* R1295 */
1393 { 0xF800, 0xF800, 0x0000 }, /* R1296 - AIF2 ADC Filters */
1394 { 0x0000, 0x0000, 0x0000 }, /* R1297 */
1395 { 0x0000, 0x0000, 0x0000 }, /* R1298 */
1396 { 0x0000, 0x0000, 0x0000 }, /* R1299 */
1397 { 0x0000, 0x0000, 0x0000 }, /* R1300 */
1398 { 0x0000, 0x0000, 0x0000 }, /* R1301 */
1399 { 0x0000, 0x0000, 0x0000 }, /* R1302 */
1400 { 0x0000, 0x0000, 0x0000 }, /* R1303 */
1401 { 0x0000, 0x0000, 0x0000 }, /* R1304 */
1402 { 0x0000, 0x0000, 0x0000 }, /* R1305 */
1403 { 0x0000, 0x0000, 0x0000 }, /* R1306 */
1404 { 0x0000, 0x0000, 0x0000 }, /* R1307 */
1405 { 0x0000, 0x0000, 0x0000 }, /* R1308 */
1406 { 0x0000, 0x0000, 0x0000 }, /* R1309 */
1407 { 0x0000, 0x0000, 0x0000 }, /* R1310 */
1408 { 0x0000, 0x0000, 0x0000 }, /* R1311 */
1409 { 0x02B6, 0x02B6, 0x0000 }, /* R1312 - AIF2 DAC Filters (1) */
1410 { 0x3F00, 0x3F00, 0x0000 }, /* R1313 - AIF2 DAC Filters (2) */
1411 { 0x0000, 0x0000, 0x0000 }, /* R1314 */
1412 { 0x0000, 0x0000, 0x0000 }, /* R1315 */
1413 { 0x0000, 0x0000, 0x0000 }, /* R1316 */
1414 { 0x0000, 0x0000, 0x0000 }, /* R1317 */
1415 { 0x0000, 0x0000, 0x0000 }, /* R1318 */
1416 { 0x0000, 0x0000, 0x0000 }, /* R1319 */
1417 { 0x0000, 0x0000, 0x0000 }, /* R1320 */
1418 { 0x0000, 0x0000, 0x0000 }, /* R1321 */
1419 { 0x0000, 0x0000, 0x0000 }, /* R1322 */
1420 { 0x0000, 0x0000, 0x0000 }, /* R1323 */
1421 { 0x0000, 0x0000, 0x0000 }, /* R1324 */
1422 { 0x0000, 0x0000, 0x0000 }, /* R1325 */
1423 { 0x0000, 0x0000, 0x0000 }, /* R1326 */
1424 { 0x0000, 0x0000, 0x0000 }, /* R1327 */
1425 { 0x0000, 0x0000, 0x0000 }, /* R1328 */
1426 { 0x0000, 0x0000, 0x0000 }, /* R1329 */
1427 { 0x0000, 0x0000, 0x0000 }, /* R1330 */
1428 { 0x0000, 0x0000, 0x0000 }, /* R1331 */
1429 { 0x0000, 0x0000, 0x0000 }, /* R1332 */
1430 { 0x0000, 0x0000, 0x0000 }, /* R1333 */
1431 { 0x0000, 0x0000, 0x0000 }, /* R1334 */
1432 { 0x0000, 0x0000, 0x0000 }, /* R1335 */
1433 { 0x0000, 0x0000, 0x0000 }, /* R1336 */
1434 { 0x0000, 0x0000, 0x0000 }, /* R1337 */
1435 { 0x0000, 0x0000, 0x0000 }, /* R1338 */
1436 { 0x0000, 0x0000, 0x0000 }, /* R1339 */
1437 { 0x0000, 0x0000, 0x0000 }, /* R1340 */
1438 { 0x0000, 0x0000, 0x0000 }, /* R1341 */
1439 { 0x0000, 0x0000, 0x0000 }, /* R1342 */
1440 { 0x0000, 0x0000, 0x0000 }, /* R1343 */
1441 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1344 - AIF2 DRC (1) */
1442 { 0x1FFF, 0x1FFF, 0x0000 }, /* R1345 - AIF2 DRC (2) */
1443 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1346 - AIF2 DRC (3) */
1444 { 0x07FF, 0x07FF, 0x0000 }, /* R1347 - AIF2 DRC (4) */
1445 { 0x03FF, 0x03FF, 0x0000 }, /* R1348 - AIF2 DRC (5) */
1446 { 0x0000, 0x0000, 0x0000 }, /* R1349 */
1447 { 0x0000, 0x0000, 0x0000 }, /* R1350 */
1448 { 0x0000, 0x0000, 0x0000 }, /* R1351 */
1449 { 0x0000, 0x0000, 0x0000 }, /* R1352 */
1450 { 0x0000, 0x0000, 0x0000 }, /* R1353 */
1451 { 0x0000, 0x0000, 0x0000 }, /* R1354 */
1452 { 0x0000, 0x0000, 0x0000 }, /* R1355 */
1453 { 0x0000, 0x0000, 0x0000 }, /* R1356 */
1454 { 0x0000, 0x0000, 0x0000 }, /* R1357 */
1455 { 0x0000, 0x0000, 0x0000 }, /* R1358 */
1456 { 0x0000, 0x0000, 0x0000 }, /* R1359 */
1457 { 0x0000, 0x0000, 0x0000 }, /* R1360 */
1458 { 0x0000, 0x0000, 0x0000 }, /* R1361 */
1459 { 0x0000, 0x0000, 0x0000 }, /* R1362 */
1460 { 0x0000, 0x0000, 0x0000 }, /* R1363 */
1461 { 0x0000, 0x0000, 0x0000 }, /* R1364 */
1462 { 0x0000, 0x0000, 0x0000 }, /* R1365 */
1463 { 0x0000, 0x0000, 0x0000 }, /* R1366 */
1464 { 0x0000, 0x0000, 0x0000 }, /* R1367 */
1465 { 0x0000, 0x0000, 0x0000 }, /* R1368 */
1466 { 0x0000, 0x0000, 0x0000 }, /* R1369 */
1467 { 0x0000, 0x0000, 0x0000 }, /* R1370 */
1468 { 0x0000, 0x0000, 0x0000 }, /* R1371 */
1469 { 0x0000, 0x0000, 0x0000 }, /* R1372 */
1470 { 0x0000, 0x0000, 0x0000 }, /* R1373 */
1471 { 0x0000, 0x0000, 0x0000 }, /* R1374 */
1472 { 0x0000, 0x0000, 0x0000 }, /* R1375 */
1473 { 0x0000, 0x0000, 0x0000 }, /* R1376 */
1474 { 0x0000, 0x0000, 0x0000 }, /* R1377 */
1475 { 0x0000, 0x0000, 0x0000 }, /* R1378 */
1476 { 0x0000, 0x0000, 0x0000 }, /* R1379 */
1477 { 0x0000, 0x0000, 0x0000 }, /* R1380 */
1478 { 0x0000, 0x0000, 0x0000 }, /* R1381 */
1479 { 0x0000, 0x0000, 0x0000 }, /* R1382 */
1480 { 0x0000, 0x0000, 0x0000 }, /* R1383 */
1481 { 0x0000, 0x0000, 0x0000 }, /* R1384 */
1482 { 0x0000, 0x0000, 0x0000 }, /* R1385 */
1483 { 0x0000, 0x0000, 0x0000 }, /* R1386 */
1484 { 0x0000, 0x0000, 0x0000 }, /* R1387 */
1485 { 0x0000, 0x0000, 0x0000 }, /* R1388 */
1486 { 0x0000, 0x0000, 0x0000 }, /* R1389 */
1487 { 0x0000, 0x0000, 0x0000 }, /* R1390 */
1488 { 0x0000, 0x0000, 0x0000 }, /* R1391 */
1489 { 0x0000, 0x0000, 0x0000 }, /* R1392 */
1490 { 0x0000, 0x0000, 0x0000 }, /* R1393 */
1491 { 0x0000, 0x0000, 0x0000 }, /* R1394 */
1492 { 0x0000, 0x0000, 0x0000 }, /* R1395 */
1493 { 0x0000, 0x0000, 0x0000 }, /* R1396 */
1494 { 0x0000, 0x0000, 0x0000 }, /* R1397 */
1495 { 0x0000, 0x0000, 0x0000 }, /* R1398 */
1496 { 0x0000, 0x0000, 0x0000 }, /* R1399 */
1497 { 0x0000, 0x0000, 0x0000 }, /* R1400 */
1498 { 0x0000, 0x0000, 0x0000 }, /* R1401 */
1499 { 0x0000, 0x0000, 0x0000 }, /* R1402 */
1500 { 0x0000, 0x0000, 0x0000 }, /* R1403 */
1501 { 0x0000, 0x0000, 0x0000 }, /* R1404 */
1502 { 0x0000, 0x0000, 0x0000 }, /* R1405 */
1503 { 0x0000, 0x0000, 0x0000 }, /* R1406 */
1504 { 0x0000, 0x0000, 0x0000 }, /* R1407 */
1505 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1408 - AIF2 EQ Gains (1) */
1506 { 0xFFC0, 0xFFC0, 0x0000 }, /* R1409 - AIF2 EQ Gains (2) */
1507 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1410 - AIF2 EQ Band 1 A */
1508 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1411 - AIF2 EQ Band 1 B */
1509 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1412 - AIF2 EQ Band 1 PG */
1510 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1413 - AIF2 EQ Band 2 A */
1511 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1414 - AIF2 EQ Band 2 B */
1512 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1415 - AIF2 EQ Band 2 C */
1513 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1416 - AIF2 EQ Band 2 PG */
1514 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1417 - AIF2 EQ Band 3 A */
1515 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1418 - AIF2 EQ Band 3 B */
1516 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1419 - AIF2 EQ Band 3 C */
1517 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1420 - AIF2 EQ Band 3 PG */
1518 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1421 - AIF2 EQ Band 4 A */
1519 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1422 - AIF2 EQ Band 4 B */
1520 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1423 - AIF2 EQ Band 4 C */
1521 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1424 - AIF2 EQ Band 4 PG */
1522 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1425 - AIF2 EQ Band 5 A */
1523 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1426 - AIF2 EQ Band 5 B */
1524 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1427 - AIF2 EQ Band 5 PG */
1525 { 0x0000, 0x0000, 0x0000 }, /* R1428 */
1526 { 0x0000, 0x0000, 0x0000 }, /* R1429 */
1527 { 0x0000, 0x0000, 0x0000 }, /* R1430 */
1528 { 0x0000, 0x0000, 0x0000 }, /* R1431 */
1529 { 0x0000, 0x0000, 0x0000 }, /* R1432 */
1530 { 0x0000, 0x0000, 0x0000 }, /* R1433 */
1531 { 0x0000, 0x0000, 0x0000 }, /* R1434 */
1532 { 0x0000, 0x0000, 0x0000 }, /* R1435 */
1533 { 0x0000, 0x0000, 0x0000 }, /* R1436 */
1534 { 0x0000, 0x0000, 0x0000 }, /* R1437 */
1535 { 0x0000, 0x0000, 0x0000 }, /* R1438 */
1536 { 0x0000, 0x0000, 0x0000 }, /* R1439 */
1537 { 0x0000, 0x0000, 0x0000 }, /* R1440 */
1538 { 0x0000, 0x0000, 0x0000 }, /* R1441 */
1539 { 0x0000, 0x0000, 0x0000 }, /* R1442 */
1540 { 0x0000, 0x0000, 0x0000 }, /* R1443 */
1541 { 0x0000, 0x0000, 0x0000 }, /* R1444 */
1542 { 0x0000, 0x0000, 0x0000 }, /* R1445 */
1543 { 0x0000, 0x0000, 0x0000 }, /* R1446 */
1544 { 0x0000, 0x0000, 0x0000 }, /* R1447 */
1545 { 0x0000, 0x0000, 0x0000 }, /* R1448 */
1546 { 0x0000, 0x0000, 0x0000 }, /* R1449 */
1547 { 0x0000, 0x0000, 0x0000 }, /* R1450 */
1548 { 0x0000, 0x0000, 0x0000 }, /* R1451 */
1549 { 0x0000, 0x0000, 0x0000 }, /* R1452 */
1550 { 0x0000, 0x0000, 0x0000 }, /* R1453 */
1551 { 0x0000, 0x0000, 0x0000 }, /* R1454 */
1552 { 0x0000, 0x0000, 0x0000 }, /* R1455 */
1553 { 0x0000, 0x0000, 0x0000 }, /* R1456 */
1554 { 0x0000, 0x0000, 0x0000 }, /* R1457 */
1555 { 0x0000, 0x0000, 0x0000 }, /* R1458 */
1556 { 0x0000, 0x0000, 0x0000 }, /* R1459 */
1557 { 0x0000, 0x0000, 0x0000 }, /* R1460 */
1558 { 0x0000, 0x0000, 0x0000 }, /* R1461 */
1559 { 0x0000, 0x0000, 0x0000 }, /* R1462 */
1560 { 0x0000, 0x0000, 0x0000 }, /* R1463 */
1561 { 0x0000, 0x0000, 0x0000 }, /* R1464 */
1562 { 0x0000, 0x0000, 0x0000 }, /* R1465 */
1563 { 0x0000, 0x0000, 0x0000 }, /* R1466 */
1564 { 0x0000, 0x0000, 0x0000 }, /* R1467 */
1565 { 0x0000, 0x0000, 0x0000 }, /* R1468 */
1566 { 0x0000, 0x0000, 0x0000 }, /* R1469 */
1567 { 0x0000, 0x0000, 0x0000 }, /* R1470 */
1568 { 0x0000, 0x0000, 0x0000 }, /* R1471 */
1569 { 0x0000, 0x0000, 0x0000 }, /* R1472 */
1570 { 0x0000, 0x0000, 0x0000 }, /* R1473 */
1571 { 0x0000, 0x0000, 0x0000 }, /* R1474 */
1572 { 0x0000, 0x0000, 0x0000 }, /* R1475 */
1573 { 0x0000, 0x0000, 0x0000 }, /* R1476 */
1574 { 0x0000, 0x0000, 0x0000 }, /* R1477 */
1575 { 0x0000, 0x0000, 0x0000 }, /* R1478 */
1576 { 0x0000, 0x0000, 0x0000 }, /* R1479 */
1577 { 0x0000, 0x0000, 0x0000 }, /* R1480 */
1578 { 0x0000, 0x0000, 0x0000 }, /* R1481 */
1579 { 0x0000, 0x0000, 0x0000 }, /* R1482 */
1580 { 0x0000, 0x0000, 0x0000 }, /* R1483 */
1581 { 0x0000, 0x0000, 0x0000 }, /* R1484 */
1582 { 0x0000, 0x0000, 0x0000 }, /* R1485 */
1583 { 0x0000, 0x0000, 0x0000 }, /* R1486 */
1584 { 0x0000, 0x0000, 0x0000 }, /* R1487 */
1585 { 0x0000, 0x0000, 0x0000 }, /* R1488 */
1586 { 0x0000, 0x0000, 0x0000 }, /* R1489 */
1587 { 0x0000, 0x0000, 0x0000 }, /* R1490 */
1588 { 0x0000, 0x0000, 0x0000 }, /* R1491 */
1589 { 0x0000, 0x0000, 0x0000 }, /* R1492 */
1590 { 0x0000, 0x0000, 0x0000 }, /* R1493 */
1591 { 0x0000, 0x0000, 0x0000 }, /* R1494 */
1592 { 0x0000, 0x0000, 0x0000 }, /* R1495 */
1593 { 0x0000, 0x0000, 0x0000 }, /* R1496 */
1594 { 0x0000, 0x0000, 0x0000 }, /* R1497 */
1595 { 0x0000, 0x0000, 0x0000 }, /* R1498 */
1596 { 0x0000, 0x0000, 0x0000 }, /* R1499 */
1597 { 0x0000, 0x0000, 0x0000 }, /* R1500 */
1598 { 0x0000, 0x0000, 0x0000 }, /* R1501 */
1599 { 0x0000, 0x0000, 0x0000 }, /* R1502 */
1600 { 0x0000, 0x0000, 0x0000 }, /* R1503 */
1601 { 0x0000, 0x0000, 0x0000 }, /* R1504 */
1602 { 0x0000, 0x0000, 0x0000 }, /* R1505 */
1603 { 0x0000, 0x0000, 0x0000 }, /* R1506 */
1604 { 0x0000, 0x0000, 0x0000 }, /* R1507 */
1605 { 0x0000, 0x0000, 0x0000 }, /* R1508 */
1606 { 0x0000, 0x0000, 0x0000 }, /* R1509 */
1607 { 0x0000, 0x0000, 0x0000 }, /* R1510 */
1608 { 0x0000, 0x0000, 0x0000 }, /* R1511 */
1609 { 0x0000, 0x0000, 0x0000 }, /* R1512 */
1610 { 0x0000, 0x0000, 0x0000 }, /* R1513 */
1611 { 0x0000, 0x0000, 0x0000 }, /* R1514 */
1612 { 0x0000, 0x0000, 0x0000 }, /* R1515 */
1613 { 0x0000, 0x0000, 0x0000 }, /* R1516 */
1614 { 0x0000, 0x0000, 0x0000 }, /* R1517 */
1615 { 0x0000, 0x0000, 0x0000 }, /* R1518 */
1616 { 0x0000, 0x0000, 0x0000 }, /* R1519 */
1617 { 0x0000, 0x0000, 0x0000 }, /* R1520 */
1618 { 0x0000, 0x0000, 0x0000 }, /* R1521 */
1619 { 0x0000, 0x0000, 0x0000 }, /* R1522 */
1620 { 0x0000, 0x0000, 0x0000 }, /* R1523 */
1621 { 0x0000, 0x0000, 0x0000 }, /* R1524 */
1622 { 0x0000, 0x0000, 0x0000 }, /* R1525 */
1623 { 0x0000, 0x0000, 0x0000 }, /* R1526 */
1624 { 0x0000, 0x0000, 0x0000 }, /* R1527 */
1625 { 0x0000, 0x0000, 0x0000 }, /* R1528 */
1626 { 0x0000, 0x0000, 0x0000 }, /* R1529 */
1627 { 0x0000, 0x0000, 0x0000 }, /* R1530 */
1628 { 0x0000, 0x0000, 0x0000 }, /* R1531 */
1629 { 0x0000, 0x0000, 0x0000 }, /* R1532 */
1630 { 0x0000, 0x0000, 0x0000 }, /* R1533 */
1631 { 0x0000, 0x0000, 0x0000 }, /* R1534 */
1632 { 0x0000, 0x0000, 0x0000 }, /* R1535 */
1633 { 0x01EF, 0x01EF, 0x0000 }, /* R1536 - DAC1 Mixer Volumes */
1634 { 0x0037, 0x0037, 0x0000 }, /* R1537 - DAC1 Left Mixer Routing */
1635 { 0x0037, 0x0037, 0x0000 }, /* R1538 - DAC1 Right Mixer Routing */
1636 { 0x01EF, 0x01EF, 0x0000 }, /* R1539 - DAC2 Mixer Volumes */
1637 { 0x0037, 0x0037, 0x0000 }, /* R1540 - DAC2 Left Mixer Routing */
1638 { 0x0037, 0x0037, 0x0000 }, /* R1541 - DAC2 Right Mixer Routing */
1639 { 0x0003, 0x0003, 0x0000 }, /* R1542 - AIF1 ADC1 Left Mixer Routing */
1640 { 0x0003, 0x0003, 0x0000 }, /* R1543 - AIF1 ADC1 Right Mixer Routing */
1641 { 0x0003, 0x0003, 0x0000 }, /* R1544 - AIF1 ADC2 Left Mixer Routing */
1642 { 0x0003, 0x0003, 0x0000 }, /* R1545 - AIF1 ADC2 Right mixer Routing */
1643 { 0x0000, 0x0000, 0x0000 }, /* R1546 */
1644 { 0x0000, 0x0000, 0x0000 }, /* R1547 */
1645 { 0x0000, 0x0000, 0x0000 }, /* R1548 */
1646 { 0x0000, 0x0000, 0x0000 }, /* R1549 */
1647 { 0x0000, 0x0000, 0x0000 }, /* R1550 */
1648 { 0x0000, 0x0000, 0x0000 }, /* R1551 */
1649 { 0x02FF, 0x03FF, 0x0000 }, /* R1552 - DAC1 Left Volume */
1650 { 0x02FF, 0x03FF, 0x0000 }, /* R1553 - DAC1 Right Volume */
1651 { 0x02FF, 0x03FF, 0x0000 }, /* R1554 - DAC2 Left Volume */
1652 { 0x02FF, 0x03FF, 0x0000 }, /* R1555 - DAC2 Right Volume */
1653 { 0x0003, 0x0003, 0x0000 }, /* R1556 - DAC Softmute */
1654 { 0x0000, 0x0000, 0x0000 }, /* R1557 */
1655 { 0x0000, 0x0000, 0x0000 }, /* R1558 */
1656 { 0x0000, 0x0000, 0x0000 }, /* R1559 */
1657 { 0x0000, 0x0000, 0x0000 }, /* R1560 */
1658 { 0x0000, 0x0000, 0x0000 }, /* R1561 */
1659 { 0x0000, 0x0000, 0x0000 }, /* R1562 */
1660 { 0x0000, 0x0000, 0x0000 }, /* R1563 */
1661 { 0x0000, 0x0000, 0x0000 }, /* R1564 */
1662 { 0x0000, 0x0000, 0x0000 }, /* R1565 */
1663 { 0x0000, 0x0000, 0x0000 }, /* R1566 */
1664 { 0x0000, 0x0000, 0x0000 }, /* R1567 */
1665 { 0x0003, 0x0003, 0x0000 }, /* R1568 - Oversampling */
1666 { 0x03C3, 0x03C3, 0x0000 }, /* R1569 - Sidetone */
1667};
1668
1669static int wm8994_readable(unsigned int reg)
1670{
1671 if (reg >= ARRAY_SIZE(access_masks))
1672 return 0;
1673 return access_masks[reg].readable != 0;
1674}
1675
1676static int wm8994_volatile(unsigned int reg)
1677{
1678 if (reg >= WM8994_REG_CACHE_SIZE)
1679 return 1;
1680
1681 switch (reg) {
1682 case WM8994_SOFTWARE_RESET:
1683 case WM8994_CHIP_REVISION:
1684 case WM8994_DC_SERVO_1:
1685 case WM8994_DC_SERVO_READBACK:
1686 case WM8994_RATE_STATUS:
1687 case WM8994_LDO_1:
1688 case WM8994_LDO_2:
1689 return 1;
1690 default:
1691 return 0;
1692 }
1693}
1694
1695static int wm8994_write(struct snd_soc_codec *codec, unsigned int reg,
1696 unsigned int value)
1697{
1698 struct wm8994_priv *wm8994 = codec->private_data;
1699
1700 BUG_ON(reg > WM8994_MAX_REGISTER);
1701
1702 if (!wm8994_volatile(reg))
1703 wm8994->reg_cache[reg] = value;
1704
1705 return wm8994_reg_write(codec->control_data, reg, value);
1706}
1707
1708static unsigned int wm8994_read(struct snd_soc_codec *codec,
1709 unsigned int reg)
1710{
1711 u16 *reg_cache = codec->reg_cache;
1712
1713 BUG_ON(reg > WM8994_MAX_REGISTER);
1714
1715 if (wm8994_volatile(reg))
1716 return wm8994_reg_read(codec->control_data, reg);
1717 else
1718 return reg_cache[reg];
1719}
1720
1721static int configure_aif_clock(struct snd_soc_codec *codec, int aif)
1722{
1723 struct wm8994_priv *wm8994 = codec->private_data;
1724 int rate;
1725 int reg1 = 0;
1726 int offset;
1727
1728 if (aif)
1729 offset = 4;
1730 else
1731 offset = 0;
1732
1733 switch (wm8994->sysclk[aif]) {
1734 case WM8994_SYSCLK_MCLK1:
1735 rate = wm8994->mclk[0];
1736 break;
1737
1738 case WM8994_SYSCLK_MCLK2:
1739 reg1 |= 0x8;
1740 rate = wm8994->mclk[1];
1741 break;
1742
1743 case WM8994_SYSCLK_FLL1:
1744 reg1 |= 0x10;
1745 rate = wm8994->fll[0].out;
1746 break;
1747
1748 case WM8994_SYSCLK_FLL2:
1749 reg1 |= 0x18;
1750 rate = wm8994->fll[1].out;
1751 break;
1752
1753 default:
1754 return -EINVAL;
1755 }
1756
1757 if (rate >= 13500000) {
1758 rate /= 2;
1759 reg1 |= WM8994_AIF1CLK_DIV;
1760
1761 dev_dbg(codec->dev, "Dividing AIF%d clock to %dHz\n",
1762 aif + 1, rate);
1763 }
1764 wm8994->aifclk[aif] = rate;
1765
1766 snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1 + offset,
1767 WM8994_AIF1CLK_SRC_MASK | WM8994_AIF1CLK_DIV,
1768 reg1);
1769
1770 return 0;
1771}
1772
1773static int configure_clock(struct snd_soc_codec *codec)
1774{
1775 struct wm8994_priv *wm8994 = codec->private_data;
1776 int old, new;
1777
1778 /* Bring up the AIF clocks first */
1779 configure_aif_clock(codec, 0);
1780 configure_aif_clock(codec, 1);
1781
1782 /* Then switch CLK_SYS over to the higher of them; a change
1783 * can only happen as a result of a clocking change which can
1784 * only be made outside of DAPM so we can safely redo the
1785 * clocking.
1786 */
1787
1788 /* If they're equal it doesn't matter which is used */
1789 if (wm8994->aifclk[0] == wm8994->aifclk[1])
1790 return 0;
1791
1792 if (wm8994->aifclk[0] < wm8994->aifclk[1])
1793 new = WM8994_SYSCLK_SRC;
1794 else
1795 new = 0;
1796
1797 old = snd_soc_read(codec, WM8994_CLOCKING_1) & WM8994_SYSCLK_SRC;
1798
1799 /* If there's no change then we're done. */
1800 if (old == new)
1801 return 0;
1802
1803 snd_soc_update_bits(codec, WM8994_CLOCKING_1, WM8994_SYSCLK_SRC, new);
1804
1805 snd_soc_dapm_sync(codec);
1806
1807 return 0;
1808}
1809
1810static int check_clk_sys(struct snd_soc_dapm_widget *source,
1811 struct snd_soc_dapm_widget *sink)
1812{
1813 int reg = snd_soc_read(source->codec, WM8994_CLOCKING_1);
1814 const char *clk;
1815
1816 /* Check what we're currently using for CLK_SYS */
1817 if (reg & WM8994_SYSCLK_SRC)
1818 clk = "AIF2CLK";
1819 else
1820 clk = "AIF1CLK";
1821
1822 return strcmp(source->name, clk) == 0;
1823}
1824
1825static const char *sidetone_hpf_text[] = {
1826 "2.7kHz", "1.35kHz", "675Hz", "370Hz", "180Hz", "90Hz", "45Hz"
1827};
1828
1829static const struct soc_enum sidetone_hpf =
1830 SOC_ENUM_SINGLE(WM8994_SIDETONE, 7, 7, sidetone_hpf_text);
1831
1832static const DECLARE_TLV_DB_SCALE(aif_tlv, 0, 600, 0);
1833static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
1834static const DECLARE_TLV_DB_SCALE(st_tlv, -3600, 300, 0);
1835static const DECLARE_TLV_DB_SCALE(wm8994_3d_tlv, -1600, 183, 0);
1836static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
1837
1838#define WM8994_DRC_SWITCH(xname, reg, shift) \
1839{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
1840 .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\
1841 .put = wm8994_put_drc_sw, \
1842 .private_value = SOC_SINGLE_VALUE(reg, shift, 1, 0) }
1843
1844static int wm8994_put_drc_sw(struct snd_kcontrol *kcontrol,
1845 struct snd_ctl_elem_value *ucontrol)
1846{
1847 struct soc_mixer_control *mc =
1848 (struct soc_mixer_control *)kcontrol->private_value;
1849 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1850 int mask, ret;
1851
1852 /* Can't enable both ADC and DAC paths simultaneously */
1853 if (mc->shift == WM8994_AIF1DAC1_DRC_ENA_SHIFT)
1854 mask = WM8994_AIF1ADC1L_DRC_ENA_MASK |
1855 WM8994_AIF1ADC1R_DRC_ENA_MASK;
1856 else
1857 mask = WM8994_AIF1DAC1_DRC_ENA_MASK;
1858
1859 ret = snd_soc_read(codec, mc->reg);
1860 if (ret < 0)
1861 return ret;
1862 if (ret & mask)
1863 return -EINVAL;
1864
1865 return snd_soc_put_volsw(kcontrol, ucontrol);
1866}
1867
1868
1869
1870static void wm8994_set_drc(struct snd_soc_codec *codec, int drc)
1871{
1872 struct wm8994_priv *wm8994 = codec->private_data;
1873 struct wm8994_pdata *pdata = wm8994->pdata;
1874 int base = wm8994_drc_base[drc];
1875 int cfg = wm8994->drc_cfg[drc];
1876 int save, i;
1877
1878 /* Save any enables; the configuration should clear them. */
1879 save = snd_soc_read(codec, base);
1880 save &= WM8994_AIF1DAC1_DRC_ENA | WM8994_AIF1ADC1L_DRC_ENA |
1881 WM8994_AIF1ADC1R_DRC_ENA;
1882
1883 for (i = 0; i < WM8994_DRC_REGS; i++)
1884 snd_soc_update_bits(codec, base + i, 0xffff,
1885 pdata->drc_cfgs[cfg].regs[i]);
1886
1887 snd_soc_update_bits(codec, base, WM8994_AIF1DAC1_DRC_ENA |
1888 WM8994_AIF1ADC1L_DRC_ENA |
1889 WM8994_AIF1ADC1R_DRC_ENA, save);
1890}
1891
1892/* Icky as hell but saves code duplication */
1893static int wm8994_get_drc(const char *name)
1894{
1895 if (strcmp(name, "AIF1DRC1 Mode") == 0)
1896 return 0;
1897 if (strcmp(name, "AIF1DRC2 Mode") == 0)
1898 return 1;
1899 if (strcmp(name, "AIF2DRC Mode") == 0)
1900 return 2;
1901 return -EINVAL;
1902}
1903
1904static int wm8994_put_drc_enum(struct snd_kcontrol *kcontrol,
1905 struct snd_ctl_elem_value *ucontrol)
1906{
1907 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1908 struct wm8994_priv *wm8994 = codec->private_data;
1909 struct wm8994_pdata *pdata = wm8994->pdata;
1910 int drc = wm8994_get_drc(kcontrol->id.name);
1911 int value = ucontrol->value.integer.value[0];
1912
1913 if (drc < 0)
1914 return drc;
1915
1916 if (value >= pdata->num_drc_cfgs)
1917 return -EINVAL;
1918
1919 wm8994->drc_cfg[drc] = value;
1920
1921 wm8994_set_drc(codec, drc);
1922
1923 return 0;
1924}
1925
1926static int wm8994_get_drc_enum(struct snd_kcontrol *kcontrol,
1927 struct snd_ctl_elem_value *ucontrol)
1928{
1929 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1930 struct wm8994_priv *wm8994 = codec->private_data;
1931 int drc = wm8994_get_drc(kcontrol->id.name);
1932
1933 ucontrol->value.enumerated.item[0] = wm8994->drc_cfg[drc];
1934
1935 return 0;
1936}
1937
1938static void wm8994_set_retune_mobile(struct snd_soc_codec *codec, int block)
1939{
1940 struct wm8994_priv *wm8994 = codec->private_data;
1941 struct wm8994_pdata *pdata = wm8994->pdata;
1942 int base = wm8994_retune_mobile_base[block];
1943 int iface, best, best_val, save, i, cfg;
1944
1945 if (!pdata || !wm8994->num_retune_mobile_texts)
1946 return;
1947
1948 switch (block) {
1949 case 0:
1950 case 1:
1951 iface = 0;
1952 break;
1953 case 2:
1954 iface = 1;
1955 break;
1956 default:
1957 return;
1958 }
1959
1960 /* Find the version of the currently selected configuration
1961 * with the nearest sample rate. */
1962 cfg = wm8994->retune_mobile_cfg[block];
1963 best = 0;
1964 best_val = INT_MAX;
1965 for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) {
1966 if (strcmp(pdata->retune_mobile_cfgs[i].name,
1967 wm8994->retune_mobile_texts[cfg]) == 0 &&
1968 abs(pdata->retune_mobile_cfgs[i].rate
1969 - wm8994->dac_rates[iface]) < best_val) {
1970 best = i;
1971 best_val = abs(pdata->retune_mobile_cfgs[i].rate
1972 - wm8994->dac_rates[iface]);
1973 }
1974 }
1975
1976 dev_dbg(codec->dev, "ReTune Mobile %d %s/%dHz for %dHz sample rate\n",
1977 block,
1978 pdata->retune_mobile_cfgs[best].name,
1979 pdata->retune_mobile_cfgs[best].rate,
1980 wm8994->dac_rates[iface]);
1981
1982 /* The EQ will be disabled while reconfiguring it, remember the
1983 * current configuration.
1984 */
1985 save = snd_soc_read(codec, base);
1986 save &= WM8994_AIF1DAC1_EQ_ENA;
1987
1988 for (i = 0; i < WM8994_EQ_REGS; i++)
1989 snd_soc_update_bits(codec, base + i, 0xffff,
1990 pdata->retune_mobile_cfgs[best].regs[i]);
1991
1992 snd_soc_update_bits(codec, base, WM8994_AIF1DAC1_EQ_ENA, save);
1993}
1994
1995/* Icky as hell but saves code duplication */
1996static int wm8994_get_retune_mobile_block(const char *name)
1997{
1998 if (strcmp(name, "AIF1.1 EQ Mode") == 0)
1999 return 0;
2000 if (strcmp(name, "AIF1.2 EQ Mode") == 0)
2001 return 1;
2002 if (strcmp(name, "AIF2 EQ Mode") == 0)
2003 return 2;
2004 return -EINVAL;
2005}
2006
2007static int wm8994_put_retune_mobile_enum(struct snd_kcontrol *kcontrol,
2008 struct snd_ctl_elem_value *ucontrol)
2009{
2010 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2011 struct wm8994_priv *wm8994 = codec->private_data;
2012 struct wm8994_pdata *pdata = wm8994->pdata;
2013 int block = wm8994_get_retune_mobile_block(kcontrol->id.name);
2014 int value = ucontrol->value.integer.value[0];
2015
2016 if (block < 0)
2017 return block;
2018
2019 if (value >= pdata->num_retune_mobile_cfgs)
2020 return -EINVAL;
2021
2022 wm8994->retune_mobile_cfg[block] = value;
2023
2024 wm8994_set_retune_mobile(codec, block);
2025
2026 return 0;
2027}
2028
2029static int wm8994_get_retune_mobile_enum(struct snd_kcontrol *kcontrol,
2030 struct snd_ctl_elem_value *ucontrol)
2031{
2032 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2033 struct wm8994_priv *wm8994 = codec->private_data;
2034 int block = wm8994_get_retune_mobile_block(kcontrol->id.name);
2035
2036 ucontrol->value.enumerated.item[0] = wm8994->retune_mobile_cfg[block];
2037
2038 return 0;
2039}
2040
2041static const struct snd_kcontrol_new wm8994_snd_controls[] = {
2042SOC_DOUBLE_R_TLV("AIF1ADC1 Volume", WM8994_AIF1_ADC1_LEFT_VOLUME,
2043 WM8994_AIF1_ADC1_RIGHT_VOLUME,
2044 1, 119, 0, digital_tlv),
2045SOC_DOUBLE_R_TLV("AIF1ADC2 Volume", WM8994_AIF1_ADC2_LEFT_VOLUME,
2046 WM8994_AIF1_ADC2_RIGHT_VOLUME,
2047 1, 119, 0, digital_tlv),
2048SOC_DOUBLE_R_TLV("AIF2ADC Volume", WM8994_AIF2_ADC_LEFT_VOLUME,
2049 WM8994_AIF2_ADC_RIGHT_VOLUME,
2050 1, 119, 0, digital_tlv),
2051
2052SOC_DOUBLE_R_TLV("AIF1DAC1 Volume", WM8994_AIF1_DAC1_LEFT_VOLUME,
2053 WM8994_AIF1_DAC1_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
2054SOC_DOUBLE_R_TLV("AIF1DAC2 Volume", WM8994_AIF1_DAC2_LEFT_VOLUME,
2055 WM8994_AIF1_DAC2_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
2056SOC_DOUBLE_R_TLV("AIF2DAC Volume", WM8994_AIF2_DAC_LEFT_VOLUME,
2057 WM8994_AIF2_DAC_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
2058
2059SOC_SINGLE_TLV("AIF1 Boost Volume", WM8994_AIF1_CONTROL_2, 10, 3, 0, aif_tlv),
2060SOC_SINGLE_TLV("AIF2 Boost Volume", WM8994_AIF2_CONTROL_2, 10, 3, 0, aif_tlv),
2061
2062SOC_SINGLE("AIF1DAC1 EQ Switch", WM8994_AIF1_DAC1_EQ_GAINS_1, 0, 1, 0),
2063SOC_SINGLE("AIF1DAC2 EQ Switch", WM8994_AIF1_DAC2_EQ_GAINS_1, 0, 1, 0),
2064SOC_SINGLE("AIF2 EQ Switch", WM8994_AIF2_EQ_GAINS_1, 0, 1, 0),
2065
2066WM8994_DRC_SWITCH("AIF1DAC1 DRC Switch", WM8994_AIF1_DRC1_1, 2),
2067WM8994_DRC_SWITCH("AIF1ADC1L DRC Switch", WM8994_AIF1_DRC1_1, 1),
2068WM8994_DRC_SWITCH("AIF1ADC1R DRC Switch", WM8994_AIF1_DRC1_1, 0),
2069
2070WM8994_DRC_SWITCH("AIF1DAC2 DRC Switch", WM8994_AIF1_DRC2_1, 2),
2071WM8994_DRC_SWITCH("AIF1ADC2L DRC Switch", WM8994_AIF1_DRC2_1, 1),
2072WM8994_DRC_SWITCH("AIF1ADC2R DRC Switch", WM8994_AIF1_DRC2_1, 0),
2073
2074WM8994_DRC_SWITCH("AIF2DAC DRC Switch", WM8994_AIF2_DRC_1, 2),
2075WM8994_DRC_SWITCH("AIF2ADCL DRC Switch", WM8994_AIF2_DRC_1, 1),
2076WM8994_DRC_SWITCH("AIF2ADCR DRC Switch", WM8994_AIF2_DRC_1, 0),
2077
2078SOC_SINGLE_TLV("DAC1 Right Sidetone Volume", WM8994_DAC1_MIXER_VOLUMES,
2079 5, 12, 0, st_tlv),
2080SOC_SINGLE_TLV("DAC1 Left Sidetone Volume", WM8994_DAC1_MIXER_VOLUMES,
2081 0, 12, 0, st_tlv),
2082SOC_SINGLE_TLV("DAC2 Right Sidetone Volume", WM8994_DAC2_MIXER_VOLUMES,
2083 5, 12, 0, st_tlv),
2084SOC_SINGLE_TLV("DAC2 Left Sidetone Volume", WM8994_DAC2_MIXER_VOLUMES,
2085 0, 12, 0, st_tlv),
2086SOC_ENUM("Sidetone HPF Mux", sidetone_hpf),
2087SOC_SINGLE("Sidetone HPF Switch", WM8994_SIDETONE, 6, 1, 0),
2088
2089SOC_DOUBLE_R_TLV("DAC1 Volume", WM8994_DAC1_LEFT_VOLUME,
2090 WM8994_DAC1_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
2091SOC_DOUBLE_R("DAC1 Switch", WM8994_DAC1_LEFT_VOLUME,
2092 WM8994_DAC1_RIGHT_VOLUME, 9, 1, 1),
2093
2094SOC_DOUBLE_R_TLV("DAC2 Volume", WM8994_DAC2_LEFT_VOLUME,
2095 WM8994_DAC2_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
2096SOC_DOUBLE_R("DAC2 Switch", WM8994_DAC2_LEFT_VOLUME,
2097 WM8994_DAC2_RIGHT_VOLUME, 9, 1, 1),
2098
2099SOC_SINGLE_TLV("SPKL DAC2 Volume", WM8994_SPKMIXL_ATTENUATION,
2100 6, 1, 1, wm_hubs_spkmix_tlv),
2101SOC_SINGLE_TLV("SPKL DAC1 Volume", WM8994_SPKMIXL_ATTENUATION,
2102 2, 1, 1, wm_hubs_spkmix_tlv),
2103
2104SOC_SINGLE_TLV("SPKR DAC2 Volume", WM8994_SPKMIXR_ATTENUATION,
2105 6, 1, 1, wm_hubs_spkmix_tlv),
2106SOC_SINGLE_TLV("SPKR DAC1 Volume", WM8994_SPKMIXR_ATTENUATION,
2107 2, 1, 1, wm_hubs_spkmix_tlv),
2108
2109SOC_SINGLE_TLV("AIF1DAC1 3D Stereo Volume", WM8994_AIF1_DAC1_FILTERS_2,
2110 10, 15, 0, wm8994_3d_tlv),
2111SOC_SINGLE("AIF1DAC1 3D Stereo Switch", WM8994_AIF1_DAC2_FILTERS_2,
2112 8, 1, 0),
2113SOC_SINGLE_TLV("AIF1DAC2 3D Stereo Volume", WM8994_AIF1_DAC2_FILTERS_2,
2114 10, 15, 0, wm8994_3d_tlv),
2115SOC_SINGLE("AIF1DAC2 3D Stereo Switch", WM8994_AIF1_DAC2_FILTERS_2,
2116 8, 1, 0),
2117SOC_SINGLE_TLV("AIF2DAC 3D Stereo Volume", WM8994_AIF1_DAC1_FILTERS_2,
2118 10, 15, 0, wm8994_3d_tlv),
2119SOC_SINGLE("AIF2DAC 3D Stereo Switch", WM8994_AIF1_DAC2_FILTERS_2,
2120 8, 1, 0),
2121};
2122
2123static const struct snd_kcontrol_new wm8994_eq_controls[] = {
2124SOC_SINGLE_TLV("AIF1DAC1 EQ1 Volume", WM8994_AIF1_DAC1_EQ_GAINS_1, 11, 31, 0,
2125 eq_tlv),
2126SOC_SINGLE_TLV("AIF1DAC1 EQ2 Volume", WM8994_AIF1_DAC1_EQ_GAINS_1, 6, 31, 0,
2127 eq_tlv),
2128SOC_SINGLE_TLV("AIF1DAC1 EQ3 Volume", WM8994_AIF1_DAC1_EQ_GAINS_1, 1, 31, 0,
2129 eq_tlv),
2130SOC_SINGLE_TLV("AIF1DAC1 EQ4 Volume", WM8994_AIF1_DAC1_EQ_GAINS_2, 11, 31, 0,
2131 eq_tlv),
2132SOC_SINGLE_TLV("AIF1DAC1 EQ5 Volume", WM8994_AIF1_DAC1_EQ_GAINS_2, 6, 31, 0,
2133 eq_tlv),
2134
2135SOC_SINGLE_TLV("AIF1DAC2 EQ1 Volume", WM8994_AIF1_DAC2_EQ_GAINS_1, 11, 31, 0,
2136 eq_tlv),
2137SOC_SINGLE_TLV("AIF1DAC2 EQ2 Volume", WM8994_AIF1_DAC2_EQ_GAINS_1, 6, 31, 0,
2138 eq_tlv),
2139SOC_SINGLE_TLV("AIF1DAC2 EQ3 Volume", WM8994_AIF1_DAC2_EQ_GAINS_1, 1, 31, 0,
2140 eq_tlv),
2141SOC_SINGLE_TLV("AIF1DAC2 EQ4 Volume", WM8994_AIF1_DAC2_EQ_GAINS_2, 11, 31, 0,
2142 eq_tlv),
2143SOC_SINGLE_TLV("AIF1DAC2 EQ5 Volume", WM8994_AIF1_DAC2_EQ_GAINS_2, 6, 31, 0,
2144 eq_tlv),
2145
2146SOC_SINGLE_TLV("AIF2 EQ1 Volume", WM8994_AIF2_EQ_GAINS_1, 11, 31, 0,
2147 eq_tlv),
2148SOC_SINGLE_TLV("AIF2 EQ2 Volume", WM8994_AIF2_EQ_GAINS_1, 6, 31, 0,
2149 eq_tlv),
2150SOC_SINGLE_TLV("AIF2 EQ3 Volume", WM8994_AIF2_EQ_GAINS_1, 1, 31, 0,
2151 eq_tlv),
2152SOC_SINGLE_TLV("AIF2 EQ4 Volume", WM8994_AIF2_EQ_GAINS_2, 11, 31, 0,
2153 eq_tlv),
2154SOC_SINGLE_TLV("AIF2 EQ5 Volume", WM8994_AIF2_EQ_GAINS_2, 6, 31, 0,
2155 eq_tlv),
2156};
2157
2158static int clk_sys_event(struct snd_soc_dapm_widget *w,
2159 struct snd_kcontrol *kcontrol, int event)
2160{
2161 struct snd_soc_codec *codec = w->codec;
2162
2163 switch (event) {
2164 case SND_SOC_DAPM_PRE_PMU:
2165 return configure_clock(codec);
2166
2167 case SND_SOC_DAPM_POST_PMD:
2168 configure_clock(codec);
2169 break;
2170 }
2171
2172 return 0;
2173}
2174
2175static void wm8994_update_class_w(struct snd_soc_codec *codec)
2176{
2177 int enable = 1;
2178 int source = 0; /* GCC flow analysis can't track enable */
2179 int reg, reg_r;
2180
2181 /* Only support direct DAC->headphone paths */
2182 reg = snd_soc_read(codec, WM8994_OUTPUT_MIXER_1);
2183 if (!(reg & WM8994_DAC1L_TO_HPOUT1L)) {
2184 dev_dbg(codec->dev, "HPL connected to output mixer\n");
2185 enable = 0;
2186 }
2187
2188 reg = snd_soc_read(codec, WM8994_OUTPUT_MIXER_2);
2189 if (!(reg & WM8994_DAC1R_TO_HPOUT1R)) {
2190 dev_dbg(codec->dev, "HPR connected to output mixer\n");
2191 enable = 0;
2192 }
2193
2194 /* We also need the same setting for L/R and only one path */
2195 reg = snd_soc_read(codec, WM8994_DAC1_LEFT_MIXER_ROUTING);
2196 switch (reg) {
2197 case WM8994_AIF2DACL_TO_DAC1L:
2198 dev_dbg(codec->dev, "Class W source AIF2DAC\n");
2199 source = 2 << WM8994_CP_DYN_SRC_SEL_SHIFT;
2200 break;
2201 case WM8994_AIF1DAC2L_TO_DAC1L:
2202 dev_dbg(codec->dev, "Class W source AIF1DAC2\n");
2203 source = 1 << WM8994_CP_DYN_SRC_SEL_SHIFT;
2204 break;
2205 case WM8994_AIF1DAC1L_TO_DAC1L:
2206 dev_dbg(codec->dev, "Class W source AIF1DAC1\n");
2207 source = 0 << WM8994_CP_DYN_SRC_SEL_SHIFT;
2208 break;
2209 default:
2210 dev_dbg(codec->dev, "DAC mixer setting: %x\n", reg);
2211 enable = 0;
2212 break;
2213 }
2214
2215 reg_r = snd_soc_read(codec, WM8994_DAC1_RIGHT_MIXER_ROUTING);
2216 if (reg_r != reg) {
2217 dev_dbg(codec->dev, "Left and right DAC mixers different\n");
2218 enable = 0;
2219 }
2220
2221 if (enable) {
2222 dev_dbg(codec->dev, "Class W enabled\n");
2223 snd_soc_update_bits(codec, WM8994_CLASS_W_1,
2224 WM8994_CP_DYN_PWR |
2225 WM8994_CP_DYN_SRC_SEL_MASK,
2226 source | WM8994_CP_DYN_PWR);
2227
2228 } else {
2229 dev_dbg(codec->dev, "Class W disabled\n");
2230 snd_soc_update_bits(codec, WM8994_CLASS_W_1,
2231 WM8994_CP_DYN_PWR, 0);
2232 }
2233}
2234
2235static const char *hp_mux_text[] = {
2236 "Mixer",
2237 "DAC",
2238};
2239
2240#define WM8994_HP_ENUM(xname, xenum) \
2241{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
2242 .info = snd_soc_info_enum_double, \
2243 .get = snd_soc_dapm_get_enum_double, \
2244 .put = wm8994_put_hp_enum, \
2245 .private_value = (unsigned long)&xenum }
2246
2247static int wm8994_put_hp_enum(struct snd_kcontrol *kcontrol,
2248 struct snd_ctl_elem_value *ucontrol)
2249{
2250 struct snd_soc_dapm_widget *w = snd_kcontrol_chip(kcontrol);
2251 struct snd_soc_codec *codec = w->codec;
2252 int ret;
2253
2254 ret = snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
2255
2256 wm8994_update_class_w(codec);
2257
2258 return ret;
2259}
2260
2261static const struct soc_enum hpl_enum =
2262 SOC_ENUM_SINGLE(WM8994_OUTPUT_MIXER_1, 8, 2, hp_mux_text);
2263
2264static const struct snd_kcontrol_new hpl_mux =
2265 WM8994_HP_ENUM("Left Headphone Mux", hpl_enum);
2266
2267static const struct soc_enum hpr_enum =
2268 SOC_ENUM_SINGLE(WM8994_OUTPUT_MIXER_2, 8, 2, hp_mux_text);
2269
2270static const struct snd_kcontrol_new hpr_mux =
2271 WM8994_HP_ENUM("Right Headphone Mux", hpr_enum);
2272
2273static const char *adc_mux_text[] = {
2274 "ADC",
2275 "DMIC",
2276};
2277
2278static const struct soc_enum adc_enum =
2279 SOC_ENUM_SINGLE(0, 0, 2, adc_mux_text);
2280
2281static const struct snd_kcontrol_new adcl_mux =
2282 SOC_DAPM_ENUM_VIRT("ADCL Mux", adc_enum);
2283
2284static const struct snd_kcontrol_new adcr_mux =
2285 SOC_DAPM_ENUM_VIRT("ADCR Mux", adc_enum);
2286
2287static const struct snd_kcontrol_new left_speaker_mixer[] = {
2288SOC_DAPM_SINGLE("DAC2 Switch", WM8994_SPEAKER_MIXER, 9, 1, 0),
2289SOC_DAPM_SINGLE("Input Switch", WM8994_SPEAKER_MIXER, 7, 1, 0),
2290SOC_DAPM_SINGLE("IN1LP Switch", WM8994_SPEAKER_MIXER, 5, 1, 0),
2291SOC_DAPM_SINGLE("Output Switch", WM8994_SPEAKER_MIXER, 3, 1, 0),
2292SOC_DAPM_SINGLE("DAC1 Switch", WM8994_SPEAKER_MIXER, 1, 1, 0),
2293};
2294
2295static const struct snd_kcontrol_new right_speaker_mixer[] = {
2296SOC_DAPM_SINGLE("DAC2 Switch", WM8994_SPEAKER_MIXER, 8, 1, 0),
2297SOC_DAPM_SINGLE("Input Switch", WM8994_SPEAKER_MIXER, 6, 1, 0),
2298SOC_DAPM_SINGLE("IN1RP Switch", WM8994_SPEAKER_MIXER, 4, 1, 0),
2299SOC_DAPM_SINGLE("Output Switch", WM8994_SPEAKER_MIXER, 2, 1, 0),
2300SOC_DAPM_SINGLE("DAC1 Switch", WM8994_SPEAKER_MIXER, 0, 1, 0),
2301};
2302
2303/* Debugging; dump chip status after DAPM transitions */
2304static int post_ev(struct snd_soc_dapm_widget *w,
2305 struct snd_kcontrol *kcontrol, int event)
2306{
2307 struct snd_soc_codec *codec = w->codec;
2308 dev_dbg(codec->dev, "SRC status: %x\n",
2309 snd_soc_read(codec,
2310 WM8994_RATE_STATUS));
2311 return 0;
2312}
2313
2314static const struct snd_kcontrol_new aif1adc1l_mix[] = {
2315SOC_DAPM_SINGLE("ADC/DMIC Switch", WM8994_AIF1_ADC1_LEFT_MIXER_ROUTING,
2316 1, 1, 0),
2317SOC_DAPM_SINGLE("AIF2 Switch", WM8994_AIF1_ADC1_LEFT_MIXER_ROUTING,
2318 0, 1, 0),
2319};
2320
2321static const struct snd_kcontrol_new aif1adc1r_mix[] = {
2322SOC_DAPM_SINGLE("ADC/DMIC Switch", WM8994_AIF1_ADC1_RIGHT_MIXER_ROUTING,
2323 1, 1, 0),
2324SOC_DAPM_SINGLE("AIF2 Switch", WM8994_AIF1_ADC1_RIGHT_MIXER_ROUTING,
2325 0, 1, 0),
2326};
2327
2328static const struct snd_kcontrol_new aif2dac2l_mix[] = {
2329SOC_DAPM_SINGLE("Right Sidetone Switch", WM8994_DAC2_LEFT_MIXER_ROUTING,
2330 5, 1, 0),
2331SOC_DAPM_SINGLE("Left Sidetone Switch", WM8994_DAC2_LEFT_MIXER_ROUTING,
2332 4, 1, 0),
2333SOC_DAPM_SINGLE("AIF2 Switch", WM8994_DAC2_LEFT_MIXER_ROUTING,
2334 2, 1, 0),
2335SOC_DAPM_SINGLE("AIF1.2 Switch", WM8994_DAC2_LEFT_MIXER_ROUTING,
2336 1, 1, 0),
2337SOC_DAPM_SINGLE("AIF1.1 Switch", WM8994_DAC2_LEFT_MIXER_ROUTING,
2338 0, 1, 0),
2339};
2340
2341static const struct snd_kcontrol_new aif2dac2r_mix[] = {
2342SOC_DAPM_SINGLE("Right Sidetone Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING,
2343 5, 1, 0),
2344SOC_DAPM_SINGLE("Left Sidetone Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING,
2345 4, 1, 0),
2346SOC_DAPM_SINGLE("AIF2 Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING,
2347 2, 1, 0),
2348SOC_DAPM_SINGLE("AIF1.2 Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING,
2349 1, 1, 0),
2350SOC_DAPM_SINGLE("AIF1.1 Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING,
2351 0, 1, 0),
2352};
2353
2354#define WM8994_CLASS_W_SWITCH(xname, reg, shift, max, invert) \
2355{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
2356 .info = snd_soc_info_volsw, \
2357 .get = snd_soc_dapm_get_volsw, .put = wm8994_put_class_w, \
2358 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
2359
2360static int wm8994_put_class_w(struct snd_kcontrol *kcontrol,
2361 struct snd_ctl_elem_value *ucontrol)
2362{
2363 struct snd_soc_dapm_widget *w = snd_kcontrol_chip(kcontrol);
2364 struct snd_soc_codec *codec = w->codec;
2365 int ret;
2366
2367 ret = snd_soc_dapm_put_volsw(kcontrol, ucontrol);
2368
2369 wm8994_update_class_w(codec);
2370
2371 return ret;
2372}
2373
2374static const struct snd_kcontrol_new dac1l_mix[] = {
2375WM8994_CLASS_W_SWITCH("Right Sidetone Switch", WM8994_DAC1_LEFT_MIXER_ROUTING,
2376 5, 1, 0),
2377WM8994_CLASS_W_SWITCH("Left Sidetone Switch", WM8994_DAC1_LEFT_MIXER_ROUTING,
2378 4, 1, 0),
2379WM8994_CLASS_W_SWITCH("AIF2 Switch", WM8994_DAC1_LEFT_MIXER_ROUTING,
2380 2, 1, 0),
2381WM8994_CLASS_W_SWITCH("AIF1.2 Switch", WM8994_DAC1_LEFT_MIXER_ROUTING,
2382 1, 1, 0),
2383WM8994_CLASS_W_SWITCH("AIF1.1 Switch", WM8994_DAC1_LEFT_MIXER_ROUTING,
2384 0, 1, 0),
2385};
2386
2387static const struct snd_kcontrol_new dac1r_mix[] = {
2388WM8994_CLASS_W_SWITCH("Right Sidetone Switch", WM8994_DAC1_RIGHT_MIXER_ROUTING,
2389 5, 1, 0),
2390WM8994_CLASS_W_SWITCH("Left Sidetone Switch", WM8994_DAC1_RIGHT_MIXER_ROUTING,
2391 4, 1, 0),
2392WM8994_CLASS_W_SWITCH("AIF2 Switch", WM8994_DAC1_RIGHT_MIXER_ROUTING,
2393 2, 1, 0),
2394WM8994_CLASS_W_SWITCH("AIF1.2 Switch", WM8994_DAC1_RIGHT_MIXER_ROUTING,
2395 1, 1, 0),
2396WM8994_CLASS_W_SWITCH("AIF1.1 Switch", WM8994_DAC1_RIGHT_MIXER_ROUTING,
2397 0, 1, 0),
2398};
2399
2400static const char *sidetone_text[] = {
2401 "ADC/DMIC1", "DMIC2",
2402};
2403
2404static const struct soc_enum sidetone1_enum =
2405 SOC_ENUM_SINGLE(WM8994_SIDETONE, 0, 2, sidetone_text);
2406
2407static const struct snd_kcontrol_new sidetone1_mux =
2408 SOC_DAPM_ENUM("Left Sidetone Mux", sidetone1_enum);
2409
2410static const struct soc_enum sidetone2_enum =
2411 SOC_ENUM_SINGLE(WM8994_SIDETONE, 1, 2, sidetone_text);
2412
2413static const struct snd_kcontrol_new sidetone2_mux =
2414 SOC_DAPM_ENUM("Right Sidetone Mux", sidetone2_enum);
2415
2416static const char *aif1dac_text[] = {
2417 "AIF1DACDAT", "AIF3DACDAT",
2418};
2419
2420static const struct soc_enum aif1dac_enum =
2421 SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 0, 2, aif1dac_text);
2422
2423static const struct snd_kcontrol_new aif1dac_mux =
2424 SOC_DAPM_ENUM("AIF1DAC Mux", aif1dac_enum);
2425
2426static const char *aif2dac_text[] = {
2427 "AIF2DACDAT", "AIF3DACDAT",
2428};
2429
2430static const struct soc_enum aif2dac_enum =
2431 SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 1, 2, aif2dac_text);
2432
2433static const struct snd_kcontrol_new aif2dac_mux =
2434 SOC_DAPM_ENUM("AIF2DAC Mux", aif2dac_enum);
2435
2436static const char *aif2adc_text[] = {
2437 "AIF2ADCDAT", "AIF3DACDAT",
2438};
2439
2440static const struct soc_enum aif2adc_enum =
2441 SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 2, 2, aif2adc_text);
2442
2443static const struct snd_kcontrol_new aif2adc_mux =
2444 SOC_DAPM_ENUM("AIF2ADC Mux", aif2adc_enum);
2445
2446static const char *aif3adc_text[] = {
2447 "AIF1ADCDAT", "AIF2ADCDAT", "AIF2DACDAT",
2448};
2449
2450static const struct soc_enum aif3adc_enum =
2451 SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 3, 3, aif3adc_text);
2452
2453static const struct snd_kcontrol_new aif3adc_mux =
2454 SOC_DAPM_ENUM("AIF3ADC Mux", aif3adc_enum);
2455
2456static const struct snd_soc_dapm_widget wm8994_dapm_widgets[] = {
2457SND_SOC_DAPM_INPUT("DMIC1DAT"),
2458SND_SOC_DAPM_INPUT("DMIC2DAT"),
2459
2460SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event,
2461 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
2462
2463SND_SOC_DAPM_SUPPLY("DSP1CLK", WM8994_CLOCKING_1, 3, 0, NULL, 0),
2464SND_SOC_DAPM_SUPPLY("DSP2CLK", WM8994_CLOCKING_1, 2, 0, NULL, 0),
2465SND_SOC_DAPM_SUPPLY("DSPINTCLK", WM8994_CLOCKING_1, 1, 0, NULL, 0),
2466
2467SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8994_AIF1_CLOCKING_1, 0, 0, NULL, 0),
2468SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8994_AIF2_CLOCKING_1, 0, 0, NULL, 0),
2469
2470SND_SOC_DAPM_AIF_OUT("AIF1ADC1L", "AIF1 Capture",
2471 0, WM8994_POWER_MANAGEMENT_4, 9, 0),
2472SND_SOC_DAPM_AIF_OUT("AIF1ADC1R", "AIF1 Capture",
2473 0, WM8994_POWER_MANAGEMENT_4, 8, 0),
2474SND_SOC_DAPM_AIF_IN("AIF1DAC1L", NULL, 0,
2475 WM8994_POWER_MANAGEMENT_5, 9, 0),
2476SND_SOC_DAPM_AIF_IN("AIF1DAC1R", NULL, 0,
2477 WM8994_POWER_MANAGEMENT_5, 8, 0),
2478
2479SND_SOC_DAPM_AIF_OUT("AIF1ADC2L", "AIF1 Capture",
2480 0, WM8994_POWER_MANAGEMENT_4, 11, 0),
2481SND_SOC_DAPM_AIF_OUT("AIF1ADC2R", "AIF1 Capture",
2482 0, WM8994_POWER_MANAGEMENT_4, 10, 0),
2483SND_SOC_DAPM_AIF_IN("AIF1DAC2L", NULL, 0,
2484 WM8994_POWER_MANAGEMENT_5, 11, 0),
2485SND_SOC_DAPM_AIF_IN("AIF1DAC2R", NULL, 0,
2486 WM8994_POWER_MANAGEMENT_5, 10, 0),
2487
2488SND_SOC_DAPM_MIXER("AIF1ADC1L Mixer", SND_SOC_NOPM, 0, 0,
2489 aif1adc1l_mix, ARRAY_SIZE(aif1adc1l_mix)),
2490SND_SOC_DAPM_MIXER("AIF1ADC1R Mixer", SND_SOC_NOPM, 0, 0,
2491 aif1adc1r_mix, ARRAY_SIZE(aif1adc1r_mix)),
2492
2493SND_SOC_DAPM_MIXER("AIF2DAC2L Mixer", SND_SOC_NOPM, 0, 0,
2494 aif2dac2l_mix, ARRAY_SIZE(aif2dac2l_mix)),
2495SND_SOC_DAPM_MIXER("AIF2DAC2R Mixer", SND_SOC_NOPM, 0, 0,
2496 aif2dac2r_mix, ARRAY_SIZE(aif2dac2r_mix)),
2497
2498SND_SOC_DAPM_MUX("Left Sidetone", SND_SOC_NOPM, 0, 0, &sidetone1_mux),
2499SND_SOC_DAPM_MUX("Right Sidetone", SND_SOC_NOPM, 0, 0, &sidetone2_mux),
2500
2501SND_SOC_DAPM_MIXER("DAC1L Mixer", SND_SOC_NOPM, 0, 0,
2502 dac1l_mix, ARRAY_SIZE(dac1l_mix)),
2503SND_SOC_DAPM_MIXER("DAC1R Mixer", SND_SOC_NOPM, 0, 0,
2504 dac1r_mix, ARRAY_SIZE(dac1r_mix)),
2505
2506SND_SOC_DAPM_AIF_OUT("AIF2ADCL", NULL, 0,
2507 WM8994_POWER_MANAGEMENT_4, 13, 0),
2508SND_SOC_DAPM_AIF_OUT("AIF2ADCR", NULL, 0,
2509 WM8994_POWER_MANAGEMENT_4, 12, 0),
2510SND_SOC_DAPM_AIF_IN("AIF2DACL", NULL, 0,
2511 WM8994_POWER_MANAGEMENT_5, 13, 0),
2512SND_SOC_DAPM_AIF_IN("AIF2DACR", NULL, 0,
2513 WM8994_POWER_MANAGEMENT_5, 12, 0),
2514
2515SND_SOC_DAPM_AIF_IN("AIF1DACDAT", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
2516SND_SOC_DAPM_AIF_IN("AIF2DACDAT", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0),
2517SND_SOC_DAPM_AIF_OUT("AIF2ADCDAT", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0),
2518
2519SND_SOC_DAPM_MUX("AIF1DAC Mux", SND_SOC_NOPM, 0, 0, &aif1dac_mux),
2520SND_SOC_DAPM_MUX("AIF2DAC Mux", SND_SOC_NOPM, 0, 0, &aif2dac_mux),
2521SND_SOC_DAPM_MUX("AIF2ADC Mux", SND_SOC_NOPM, 0, 0, &aif2adc_mux),
2522SND_SOC_DAPM_MUX("AIF3ADC Mux", SND_SOC_NOPM, 0, 0, &aif3adc_mux),
2523
2524SND_SOC_DAPM_AIF_IN("AIF3DACDAT", "AIF3 Playback", 0, SND_SOC_NOPM, 0, 0),
2525SND_SOC_DAPM_AIF_IN("AIF3ADCDAT", "AIF3 Capture", 0, SND_SOC_NOPM, 0, 0),
2526
2527SND_SOC_DAPM_SUPPLY("TOCLK", WM8994_CLOCKING_1, 4, 0, NULL, 0),
2528
2529SND_SOC_DAPM_ADC("DMIC2L", NULL, WM8994_POWER_MANAGEMENT_4, 5, 0),
2530SND_SOC_DAPM_ADC("DMIC2R", NULL, WM8994_POWER_MANAGEMENT_4, 4, 0),
2531SND_SOC_DAPM_ADC("DMIC1L", NULL, WM8994_POWER_MANAGEMENT_4, 3, 0),
2532SND_SOC_DAPM_ADC("DMIC1R", NULL, WM8994_POWER_MANAGEMENT_4, 2, 0),
2533
2534/* Power is done with the muxes since the ADC power also controls the
2535 * downsampling chain, the chip will automatically manage the analogue
2536 * specific portions.
2537 */
2538SND_SOC_DAPM_ADC("ADCL", NULL, SND_SOC_NOPM, 1, 0),
2539SND_SOC_DAPM_ADC("ADCR", NULL, SND_SOC_NOPM, 0, 0),
2540
2541SND_SOC_DAPM_MUX("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux),
2542SND_SOC_DAPM_MUX("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux),
2543
2544SND_SOC_DAPM_DAC("DAC2L", NULL, WM8994_POWER_MANAGEMENT_5, 3, 0),
2545SND_SOC_DAPM_DAC("DAC2R", NULL, WM8994_POWER_MANAGEMENT_5, 2, 0),
2546SND_SOC_DAPM_DAC("DAC1L", NULL, WM8994_POWER_MANAGEMENT_5, 1, 0),
2547SND_SOC_DAPM_DAC("DAC1R", NULL, WM8994_POWER_MANAGEMENT_5, 0, 0),
2548
2549SND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM, 0, 0, &hpl_mux),
2550SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0, &hpr_mux),
2551
2552SND_SOC_DAPM_MIXER("SPKL", WM8994_POWER_MANAGEMENT_3, 8, 0,
2553 left_speaker_mixer, ARRAY_SIZE(left_speaker_mixer)),
2554SND_SOC_DAPM_MIXER("SPKR", WM8994_POWER_MANAGEMENT_3, 9, 0,
2555 right_speaker_mixer, ARRAY_SIZE(right_speaker_mixer)),
2556
2557SND_SOC_DAPM_POST("Debug log", post_ev),
2558};
2559
2560static const struct snd_soc_dapm_route intercon[] = {
2561
2562 { "CLK_SYS", NULL, "AIF1CLK", check_clk_sys },
2563 { "CLK_SYS", NULL, "AIF2CLK", check_clk_sys },
2564
2565 { "DSP1CLK", NULL, "CLK_SYS" },
2566 { "DSP2CLK", NULL, "CLK_SYS" },
2567 { "DSPINTCLK", NULL, "CLK_SYS" },
2568
2569 { "AIF1ADC1L", NULL, "AIF1CLK" },
2570 { "AIF1ADC1L", NULL, "DSP1CLK" },
2571 { "AIF1ADC1R", NULL, "AIF1CLK" },
2572 { "AIF1ADC1R", NULL, "DSP1CLK" },
2573 { "AIF1ADC1R", NULL, "DSPINTCLK" },
2574
2575 { "AIF1DAC1L", NULL, "AIF1CLK" },
2576 { "AIF1DAC1L", NULL, "DSP1CLK" },
2577 { "AIF1DAC1R", NULL, "AIF1CLK" },
2578 { "AIF1DAC1R", NULL, "DSP1CLK" },
2579 { "AIF1DAC1R", NULL, "DSPINTCLK" },
2580
2581 { "AIF1ADC2L", NULL, "AIF1CLK" },
2582 { "AIF1ADC2L", NULL, "DSP1CLK" },
2583 { "AIF1ADC2R", NULL, "AIF1CLK" },
2584 { "AIF1ADC2R", NULL, "DSP1CLK" },
2585 { "AIF1ADC2R", NULL, "DSPINTCLK" },
2586
2587 { "AIF1DAC2L", NULL, "AIF1CLK" },
2588 { "AIF1DAC2L", NULL, "DSP1CLK" },
2589 { "AIF1DAC2R", NULL, "AIF1CLK" },
2590 { "AIF1DAC2R", NULL, "DSP1CLK" },
2591 { "AIF1DAC2R", NULL, "DSPINTCLK" },
2592
2593 { "AIF2ADCL", NULL, "AIF2CLK" },
2594 { "AIF2ADCL", NULL, "DSP2CLK" },
2595 { "AIF2ADCR", NULL, "AIF2CLK" },
2596 { "AIF2ADCR", NULL, "DSP2CLK" },
2597 { "AIF2ADCR", NULL, "DSPINTCLK" },
2598
2599 { "AIF2DACL", NULL, "AIF2CLK" },
2600 { "AIF2DACL", NULL, "DSP2CLK" },
2601 { "AIF2DACR", NULL, "AIF2CLK" },
2602 { "AIF2DACR", NULL, "DSP2CLK" },
2603 { "AIF2DACR", NULL, "DSPINTCLK" },
2604
2605 { "DMIC1L", NULL, "DMIC1DAT" },
2606 { "DMIC1L", NULL, "CLK_SYS" },
2607 { "DMIC1R", NULL, "DMIC1DAT" },
2608 { "DMIC1R", NULL, "CLK_SYS" },
2609 { "DMIC2L", NULL, "DMIC2DAT" },
2610 { "DMIC2L", NULL, "CLK_SYS" },
2611 { "DMIC2R", NULL, "DMIC2DAT" },
2612 { "DMIC2R", NULL, "CLK_SYS" },
2613
2614 { "ADCL", NULL, "AIF1CLK" },
2615 { "ADCL", NULL, "DSP1CLK" },
2616 { "ADCL", NULL, "DSPINTCLK" },
2617
2618 { "ADCR", NULL, "AIF1CLK" },
2619 { "ADCR", NULL, "DSP1CLK" },
2620 { "ADCR", NULL, "DSPINTCLK" },
2621
2622 { "ADCL Mux", "ADC", "ADCL" },
2623 { "ADCL Mux", "DMIC", "DMIC1L" },
2624 { "ADCR Mux", "ADC", "ADCR" },
2625 { "ADCR Mux", "DMIC", "DMIC1R" },
2626
2627 { "DAC1L", NULL, "AIF1CLK" },
2628 { "DAC1L", NULL, "DSP1CLK" },
2629 { "DAC1L", NULL, "DSPINTCLK" },
2630
2631 { "DAC1R", NULL, "AIF1CLK" },
2632 { "DAC1R", NULL, "DSP1CLK" },
2633 { "DAC1R", NULL, "DSPINTCLK" },
2634
2635 { "DAC2L", NULL, "AIF2CLK" },
2636 { "DAC2L", NULL, "DSP2CLK" },
2637 { "DAC2L", NULL, "DSPINTCLK" },
2638
2639 { "DAC2R", NULL, "AIF2DACR" },
2640 { "DAC2R", NULL, "AIF2CLK" },
2641 { "DAC2R", NULL, "DSP2CLK" },
2642 { "DAC2R", NULL, "DSPINTCLK" },
2643
2644 { "TOCLK", NULL, "CLK_SYS" },
2645
2646 /* AIF1 outputs */
2647 { "AIF1ADC1L", NULL, "AIF1ADC1L Mixer" },
2648 { "AIF1ADC1L Mixer", "ADC/DMIC Switch", "ADCL Mux" },
2649 { "AIF1ADC1L Mixer", "AIF2 Switch", "AIF2DACL" },
2650
2651 { "AIF1ADC1R", NULL, "AIF1ADC1R Mixer" },
2652 { "AIF1ADC1R Mixer", "ADC/DMIC Switch", "ADCR Mux" },
2653 { "AIF1ADC1R Mixer", "AIF2 Switch", "AIF2DACR" },
2654
2655 /* Pin level routing for AIF3 */
2656 { "AIF1DAC1L", NULL, "AIF1DAC Mux" },
2657 { "AIF1DAC1R", NULL, "AIF1DAC Mux" },
2658 { "AIF1DAC2L", NULL, "AIF1DAC Mux" },
2659 { "AIF1DAC2R", NULL, "AIF1DAC Mux" },
2660
2661 { "AIF2DACL", NULL, "AIF2DAC Mux" },
2662 { "AIF2DACR", NULL, "AIF2DAC Mux" },
2663
2664 { "AIF1DAC Mux", "AIF1DACDAT", "AIF1DACDAT" },
2665 { "AIF1DAC Mux", "AIF3DACDAT", "AIF3DACDAT" },
2666 { "AIF2DAC Mux", "AIF2DACDAT", "AIF2DACDAT" },
2667 { "AIF2DAC Mux", "AIF3DACDAT", "AIF3DACDAT" },
2668 { "AIF2ADC Mux", "AIF2ADCDAT", "AIF2ADCL" },
2669 { "AIF2ADC Mux", "AIF2ADCDAT", "AIF2ADCR" },
2670 { "AIF2ADC Mux", "AIF3DACDAT", "AIF3ADCDAT" },
2671
2672 /* DAC1 inputs */
2673 { "DAC1L", NULL, "DAC1L Mixer" },
2674 { "DAC1L Mixer", "AIF2 Switch", "AIF2DACL" },
2675 { "DAC1L Mixer", "AIF1.2 Switch", "AIF1DAC2L" },
2676 { "DAC1L Mixer", "AIF1.1 Switch", "AIF1DAC1L" },
2677 { "DAC1L Mixer", "Left Sidetone Switch", "Left Sidetone" },
2678 { "DAC1L Mixer", "Right Sidetone Switch", "Right Sidetone" },
2679
2680 { "DAC1R", NULL, "DAC1R Mixer" },
2681 { "DAC1R Mixer", "AIF2 Switch", "AIF2DACR" },
2682 { "DAC1R Mixer", "AIF1.2 Switch", "AIF1DAC2R" },
2683 { "DAC1R Mixer", "AIF1.1 Switch", "AIF1DAC1R" },
2684 { "DAC1R Mixer", "Left Sidetone Switch", "Left Sidetone" },
2685 { "DAC1R Mixer", "Right Sidetone Switch", "Right Sidetone" },
2686
2687 /* DAC2/AIF2 outputs */
2688 { "AIF2ADCL", NULL, "AIF2DAC2L Mixer" },
2689 { "DAC2L", NULL, "AIF2DAC2L Mixer" },
2690 { "AIF2DAC2L Mixer", "AIF2 Switch", "AIF2DACL" },
2691 { "AIF2DAC2L Mixer", "AIF1.2 Switch", "AIF1DAC2L" },
2692 { "AIF2DAC2L Mixer", "AIF1.1 Switch", "AIF1DAC1L" },
2693 { "AIF2DAC2L Mixer", "Left Sidetone Switch", "Left Sidetone" },
2694 { "AIF2DAC2L Mixer", "Right Sidetone Switch", "Right Sidetone" },
2695
2696 { "AIF2ADCR", NULL, "AIF2DAC2R Mixer" },
2697 { "DAC2R", NULL, "AIF2DAC2R Mixer" },
2698 { "AIF2DAC2R Mixer", "AIF2 Switch", "AIF2DACR" },
2699 { "AIF2DAC2R Mixer", "AIF1.2 Switch", "AIF1DAC2R" },
2700 { "AIF2DAC2R Mixer", "AIF1.1 Switch", "AIF1DAC1R" },
2701 { "AIF2DAC2R Mixer", "Left Sidetone Switch", "Left Sidetone" },
2702 { "AIF2DAC2R Mixer", "Right Sidetone Switch", "Right Sidetone" },
2703
2704 { "AIF2ADCDAT", NULL, "AIF2ADC Mux" },
2705
2706 /* AIF3 output */
2707 { "AIF3ADCDAT", "AIF1ADCDAT", "AIF1ADC1L" },
2708 { "AIF3ADCDAT", "AIF1ADCDAT", "AIF1ADC1R" },
2709 { "AIF3ADCDAT", "AIF1ADCDAT", "AIF1ADC2L" },
2710 { "AIF3ADCDAT", "AIF1ADCDAT", "AIF1ADC2R" },
2711 { "AIF3ADCDAT", "AIF2ADCDAT", "AIF2ADCL" },
2712 { "AIF3ADCDAT", "AIF2ADCDAT", "AIF2ADCR" },
2713 { "AIF3ADCDAT", "AIF2DACDAT", "AIF2DACL" },
2714 { "AIF3ADCDAT", "AIF2DACDAT", "AIF2DACR" },
2715
2716 /* Sidetone */
2717 { "Left Sidetone", "ADC/DMIC1", "ADCL Mux" },
2718 { "Left Sidetone", "DMIC2", "DMIC2L" },
2719 { "Right Sidetone", "ADC/DMIC1", "ADCR Mux" },
2720 { "Right Sidetone", "DMIC2", "DMIC2R" },
2721
2722 /* Output stages */
2723 { "Left Output Mixer", "DAC Switch", "DAC1L" },
2724 { "Right Output Mixer", "DAC Switch", "DAC1R" },
2725
2726 { "SPKL", "DAC1 Switch", "DAC1L" },
2727 { "SPKL", "DAC2 Switch", "DAC2L" },
2728
2729 { "SPKR", "DAC1 Switch", "DAC1R" },
2730 { "SPKR", "DAC2 Switch", "DAC2R" },
2731
2732 { "Left Headphone Mux", "DAC", "DAC1L" },
2733 { "Right Headphone Mux", "DAC", "DAC1R" },
2734};
2735
2736/* The size in bits of the FLL divide multiplied by 10
2737 * to allow rounding later */
2738#define FIXED_FLL_SIZE ((1 << 16) * 10)
2739
2740struct fll_div {
2741 u16 outdiv;
2742 u16 n;
2743 u16 k;
2744 u16 clk_ref_div;
2745 u16 fll_fratio;
2746};
2747
2748static int wm8994_get_fll_config(struct fll_div *fll,
2749 int freq_in, int freq_out)
2750{
2751 u64 Kpart;
2752 unsigned int K, Ndiv, Nmod;
2753
2754 pr_debug("FLL input=%dHz, output=%dHz\n", freq_in, freq_out);
2755
2756 /* Scale the input frequency down to <= 13.5MHz */
2757 fll->clk_ref_div = 0;
2758 while (freq_in > 13500000) {
2759 fll->clk_ref_div++;
2760 freq_in /= 2;
2761
2762 if (fll->clk_ref_div > 3)
2763 return -EINVAL;
2764 }
2765 pr_debug("CLK_REF_DIV=%d, Fref=%dHz\n", fll->clk_ref_div, freq_in);
2766
2767 /* Scale the output to give 90MHz<=Fvco<=100MHz */
2768 fll->outdiv = 3;
2769 while (freq_out * (fll->outdiv + 1) < 90000000) {
2770 fll->outdiv++;
2771 if (fll->outdiv > 63)
2772 return -EINVAL;
2773 }
2774 freq_out *= fll->outdiv + 1;
2775 pr_debug("OUTDIV=%d, Fvco=%dHz\n", fll->outdiv, freq_out);
2776
2777 if (freq_in > 1000000) {
2778 fll->fll_fratio = 0;
2779 } else {
2780 fll->fll_fratio = 3;
2781 freq_in *= 8;
2782 }
2783 pr_debug("FLL_FRATIO=%d, Fref=%dHz\n", fll->fll_fratio, freq_in);
2784
2785 /* Now, calculate N.K */
2786 Ndiv = freq_out / freq_in;
2787
2788 fll->n = Ndiv;
2789 Nmod = freq_out % freq_in;
2790 pr_debug("Nmod=%d\n", Nmod);
2791
2792 /* Calculate fractional part - scale up so we can round. */
2793 Kpart = FIXED_FLL_SIZE * (long long)Nmod;
2794
2795 do_div(Kpart, freq_in);
2796
2797 K = Kpart & 0xFFFFFFFF;
2798
2799 if ((K % 10) >= 5)
2800 K += 5;
2801
2802 /* Move down to proper range now rounding is done */
2803 fll->k = K / 10;
2804
2805 pr_debug("N=%x K=%x\n", fll->n, fll->k);
2806
2807 return 0;
2808}
2809
2810static int wm8994_set_fll(struct snd_soc_dai *dai, int id, int src,
2811 unsigned int freq_in, unsigned int freq_out)
2812{
2813 struct snd_soc_codec *codec = dai->codec;
2814 struct wm8994_priv *wm8994 = codec->private_data;
2815 int reg_offset, ret;
2816 struct fll_div fll;
2817 u16 reg, aif1, aif2;
2818
2819 aif1 = snd_soc_read(codec, WM8994_AIF1_CLOCKING_1)
2820 & WM8994_AIF1CLK_ENA;
2821
2822 aif2 = snd_soc_read(codec, WM8994_AIF2_CLOCKING_1)
2823 & WM8994_AIF2CLK_ENA;
2824
2825 switch (id) {
2826 case WM8994_FLL1:
2827 reg_offset = 0;
2828 id = 0;
2829 break;
2830 case WM8994_FLL2:
2831 reg_offset = 0x20;
2832 id = 1;
2833 break;
2834 default:
2835 return -EINVAL;
2836 }
2837
2838 /* Are we changing anything? */
2839 if (wm8994->fll[id].src == src &&
2840 wm8994->fll[id].in == freq_in && wm8994->fll[id].out == freq_out)
2841 return 0;
2842
2843 /* If we're stopping the FLL redo the old config - no
2844 * registers will actually be written but we avoid GCC flow
2845 * analysis bugs spewing warnings.
2846 */
2847 if (freq_out)
2848 ret = wm8994_get_fll_config(&fll, freq_in, freq_out);
2849 else
2850 ret = wm8994_get_fll_config(&fll, wm8994->fll[id].in,
2851 wm8994->fll[id].out);
2852 if (ret < 0)
2853 return ret;
2854
2855 /* Gate the AIF clocks while we reclock */
2856 snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1,
2857 WM8994_AIF1CLK_ENA, 0);
2858 snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1,
2859 WM8994_AIF2CLK_ENA, 0);
2860
2861 /* We always need to disable the FLL while reconfiguring */
2862 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_1 + reg_offset,
2863 WM8994_FLL1_ENA, 0);
2864
2865 reg = (fll.outdiv << WM8994_FLL1_OUTDIV_SHIFT) |
2866 (fll.fll_fratio << WM8994_FLL1_FRATIO_SHIFT);
2867 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_2 + reg_offset,
2868 WM8994_FLL1_OUTDIV_MASK |
2869 WM8994_FLL1_FRATIO_MASK, reg);
2870
2871 snd_soc_write(codec, WM8994_FLL1_CONTROL_3 + reg_offset, fll.k);
2872
2873 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_4 + reg_offset,
2874 WM8994_FLL1_N_MASK,
2875 fll.n << WM8994_FLL1_N_SHIFT);
2876
2877 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_5 + reg_offset,
2878 WM8994_FLL1_REFCLK_DIV_MASK,
2879 fll.clk_ref_div << WM8994_FLL1_REFCLK_DIV_SHIFT);
2880
2881 /* Enable (with fractional mode if required) */
2882 if (freq_out) {
2883 if (fll.k)
2884 reg = WM8994_FLL1_ENA | WM8994_FLL1_FRAC;
2885 else
2886 reg = WM8994_FLL1_ENA;
2887 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_1 + reg_offset,
2888 WM8994_FLL1_ENA | WM8994_FLL1_FRAC,
2889 reg);
2890 }
2891
2892 wm8994->fll[id].in = freq_in;
2893 wm8994->fll[id].out = freq_out;
2894
2895 /* Enable any gated AIF clocks */
2896 snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1,
2897 WM8994_AIF1CLK_ENA, aif1);
2898 snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1,
2899 WM8994_AIF2CLK_ENA, aif2);
2900
2901 configure_clock(codec);
2902
2903 return 0;
2904}
2905
2906static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai,
2907 int clk_id, unsigned int freq, int dir)
2908{
2909 struct snd_soc_codec *codec = dai->codec;
2910 struct wm8994_priv *wm8994 = codec->private_data;
2911
2912 switch (dai->id) {
2913 case 1:
2914 case 2:
2915 break;
2916
2917 default:
2918 /* AIF3 shares clocking with AIF1/2 */
2919 return -EINVAL;
2920 }
2921
2922 switch (clk_id) {
2923 case WM8994_SYSCLK_MCLK1:
2924 wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_MCLK1;
2925 wm8994->mclk[0] = freq;
2926 dev_dbg(dai->dev, "AIF%d using MCLK1 at %uHz\n",
2927 dai->id, freq);
2928 break;
2929
2930 case WM8994_SYSCLK_MCLK2:
2931 /* TODO: Set GPIO AF */
2932 wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_MCLK2;
2933 wm8994->mclk[1] = freq;
2934 dev_dbg(dai->dev, "AIF%d using MCLK2 at %uHz\n",
2935 dai->id, freq);
2936 break;
2937
2938 case WM8994_SYSCLK_FLL1:
2939 wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_FLL1;
2940 dev_dbg(dai->dev, "AIF%d using FLL1\n", dai->id);
2941 break;
2942
2943 case WM8994_SYSCLK_FLL2:
2944 wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_FLL2;
2945 dev_dbg(dai->dev, "AIF%d using FLL2\n", dai->id);
2946 break;
2947
2948 default:
2949 return -EINVAL;
2950 }
2951
2952 configure_clock(codec);
2953
2954 return 0;
2955}
2956
2957static int wm8994_set_bias_level(struct snd_soc_codec *codec,
2958 enum snd_soc_bias_level level)
2959{
2960 switch (level) {
2961 case SND_SOC_BIAS_ON:
2962 break;
2963
2964 case SND_SOC_BIAS_PREPARE:
2965 /* VMID=2x40k */
2966 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
2967 WM8994_VMID_SEL_MASK, 0x2);
2968 break;
2969
2970 case SND_SOC_BIAS_STANDBY:
2971 if (codec->bias_level == SND_SOC_BIAS_OFF) {
2972 /* Tweak DC servo configuration for improved
2973 * performance. */
2974 snd_soc_write(codec, 0x102, 0x3);
2975 snd_soc_write(codec, 0x56, 0x3);
2976 snd_soc_write(codec, 0x102, 0);
2977
2978 /* Discharge LINEOUT1 & 2 */
2979 snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
2980 WM8994_LINEOUT1_DISCH |
2981 WM8994_LINEOUT2_DISCH,
2982 WM8994_LINEOUT1_DISCH |
2983 WM8994_LINEOUT2_DISCH);
2984
2985 /* Startup bias, VMID ramp & buffer */
2986 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
2987 WM8994_STARTUP_BIAS_ENA |
2988 WM8994_VMID_BUF_ENA |
2989 WM8994_VMID_RAMP_MASK,
2990 WM8994_STARTUP_BIAS_ENA |
2991 WM8994_VMID_BUF_ENA |
2992 (0x11 << WM8994_VMID_RAMP_SHIFT));
2993
2994 /* Main bias enable, VMID=2x40k */
2995 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
2996 WM8994_BIAS_ENA |
2997 WM8994_VMID_SEL_MASK,
2998 WM8994_BIAS_ENA | 0x2);
2999
3000 msleep(20);
3001 }
3002
3003 /* VMID=2x500k */
3004 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
3005 WM8994_VMID_SEL_MASK, 0x4);
3006
3007 break;
3008
3009 case SND_SOC_BIAS_OFF:
3010 /* Switch over to startup biases */
3011 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
3012 WM8994_BIAS_SRC | WM8994_STARTUP_BIAS_ENA |
3013 WM8994_VMID_BUF_ENA |
3014 WM8994_VMID_RAMP_MASK,
3015 WM8994_BIAS_SRC | WM8994_STARTUP_BIAS_ENA |
3016 WM8994_VMID_BUF_ENA |
3017 (1 << WM8994_VMID_RAMP_SHIFT));
3018
3019 /* Disable main biases */
3020 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
3021 WM8994_BIAS_ENA | WM8994_VMID_SEL_MASK, 0);
3022
3023 /* Discharge line */
3024 snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
3025 WM8994_LINEOUT1_DISCH |
3026 WM8994_LINEOUT2_DISCH,
3027 WM8994_LINEOUT1_DISCH |
3028 WM8994_LINEOUT2_DISCH);
3029
3030 msleep(5);
3031
3032 /* Switch off startup biases */
3033 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
3034 WM8994_BIAS_SRC | WM8994_STARTUP_BIAS_ENA |
3035 WM8994_VMID_BUF_ENA |
3036 WM8994_VMID_RAMP_MASK, 0);
3037
3038 break;
3039 }
3040 codec->bias_level = level;
3041 return 0;
3042}
3043
3044static int wm8994_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
3045{
3046 struct snd_soc_codec *codec = dai->codec;
3047 int ms_reg;
3048 int aif1_reg;
3049 int ms = 0;
3050 int aif1 = 0;
3051
3052 switch (dai->id) {
3053 case 1:
3054 ms_reg = WM8994_AIF1_MASTER_SLAVE;
3055 aif1_reg = WM8994_AIF1_CONTROL_1;
3056 break;
3057 case 2:
3058 ms_reg = WM8994_AIF2_MASTER_SLAVE;
3059 aif1_reg = WM8994_AIF2_CONTROL_1;
3060 break;
3061 default:
3062 return -EINVAL;
3063 }
3064
3065 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
3066 case SND_SOC_DAIFMT_CBS_CFS:
3067 break;
3068 case SND_SOC_DAIFMT_CBM_CFM:
3069 ms = WM8994_AIF1_MSTR;
3070 break;
3071 default:
3072 return -EINVAL;
3073 }
3074
3075 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
3076 case SND_SOC_DAIFMT_DSP_B:
3077 aif1 |= WM8994_AIF1_LRCLK_INV;
3078 case SND_SOC_DAIFMT_DSP_A:
3079 aif1 |= 0x18;
3080 break;
3081 case SND_SOC_DAIFMT_I2S:
3082 aif1 |= 0x10;
3083 break;
3084 case SND_SOC_DAIFMT_RIGHT_J:
3085 break;
3086 case SND_SOC_DAIFMT_LEFT_J:
3087 aif1 |= 0x8;
3088 break;
3089 default:
3090 return -EINVAL;
3091 }
3092
3093 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
3094 case SND_SOC_DAIFMT_DSP_A:
3095 case SND_SOC_DAIFMT_DSP_B:
3096 /* frame inversion not valid for DSP modes */
3097 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
3098 case SND_SOC_DAIFMT_NB_NF:
3099 break;
3100 case SND_SOC_DAIFMT_IB_NF:
3101 aif1 |= WM8994_AIF1_BCLK_INV;
3102 break;
3103 default:
3104 return -EINVAL;
3105 }
3106 break;
3107
3108 case SND_SOC_DAIFMT_I2S:
3109 case SND_SOC_DAIFMT_RIGHT_J:
3110 case SND_SOC_DAIFMT_LEFT_J:
3111 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
3112 case SND_SOC_DAIFMT_NB_NF:
3113 break;
3114 case SND_SOC_DAIFMT_IB_IF:
3115 aif1 |= WM8994_AIF1_BCLK_INV | WM8994_AIF1_LRCLK_INV;
3116 break;
3117 case SND_SOC_DAIFMT_IB_NF:
3118 aif1 |= WM8994_AIF1_BCLK_INV;
3119 break;
3120 case SND_SOC_DAIFMT_NB_IF:
3121 aif1 |= WM8994_AIF1_LRCLK_INV;
3122 break;
3123 default:
3124 return -EINVAL;
3125 }
3126 break;
3127 default:
3128 return -EINVAL;
3129 }
3130
3131 snd_soc_update_bits(codec, aif1_reg,
3132 WM8994_AIF1_BCLK_INV | WM8994_AIF1_LRCLK_INV |
3133 WM8994_AIF1_FMT_MASK,
3134 aif1);
3135 snd_soc_update_bits(codec, ms_reg, WM8994_AIF1_MSTR,
3136 ms);
3137
3138 return 0;
3139}
3140
3141static struct {
3142 int val, rate;
3143} srs[] = {
3144 { 0, 8000 },
3145 { 1, 11025 },
3146 { 2, 12000 },
3147 { 3, 16000 },
3148 { 4, 22050 },
3149 { 5, 24000 },
3150 { 6, 32000 },
3151 { 7, 44100 },
3152 { 8, 48000 },
3153 { 9, 88200 },
3154 { 10, 96000 },
3155};
3156
3157static int fs_ratios[] = {
3158 64, 128, 192, 256, 348, 512, 768, 1024, 1408, 1536
3159};
3160
3161static int bclk_divs[] = {
3162 10, 15, 20, 30, 40, 50, 60, 80, 110, 120, 160, 220, 240, 320, 440, 480,
3163 640, 880, 960, 1280, 1760, 1920
3164};
3165
3166static int wm8994_hw_params(struct snd_pcm_substream *substream,
3167 struct snd_pcm_hw_params *params,
3168 struct snd_soc_dai *dai)
3169{
3170 struct snd_soc_codec *codec = dai->codec;
3171 struct wm8994_priv *wm8994 = codec->private_data;
3172 int aif1_reg;
3173 int bclk_reg;
3174 int lrclk_reg;
3175 int rate_reg;
3176 int aif1 = 0;
3177 int bclk = 0;
3178 int lrclk = 0;
3179 int rate_val = 0;
3180 int id = dai->id - 1;
3181
3182 int i, cur_val, best_val, bclk_rate, best;
3183
3184 switch (dai->id) {
3185 case 1:
3186 aif1_reg = WM8994_AIF1_CONTROL_1;
3187 bclk_reg = WM8994_AIF1_BCLK;
3188 rate_reg = WM8994_AIF1_RATE;
3189 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
3190 wm8994->lrclk_shared[0])
3191 lrclk_reg = WM8994_AIF1DAC_LRCLK;
3192 else
3193 lrclk_reg = WM8994_AIF1ADC_LRCLK;
3194 break;
3195 case 2:
3196 aif1_reg = WM8994_AIF2_CONTROL_1;
3197 bclk_reg = WM8994_AIF2_BCLK;
3198 rate_reg = WM8994_AIF2_RATE;
3199 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
3200 wm8994->lrclk_shared[1])
3201 lrclk_reg = WM8994_AIF2DAC_LRCLK;
3202 else
3203 lrclk_reg = WM8994_AIF2ADC_LRCLK;
3204 break;
3205 default:
3206 return -EINVAL;
3207 }
3208
3209 bclk_rate = params_rate(params) * 2;
3210 switch (params_format(params)) {
3211 case SNDRV_PCM_FORMAT_S16_LE:
3212 bclk_rate *= 16;
3213 break;
3214 case SNDRV_PCM_FORMAT_S20_3LE:
3215 bclk_rate *= 20;
3216 aif1 |= 0x20;
3217 break;
3218 case SNDRV_PCM_FORMAT_S24_LE:
3219 bclk_rate *= 24;
3220 aif1 |= 0x40;
3221 break;
3222 case SNDRV_PCM_FORMAT_S32_LE:
3223 bclk_rate *= 32;
3224 aif1 |= 0x60;
3225 break;
3226 default:
3227 return -EINVAL;
3228 }
3229
3230 /* Try to find an appropriate sample rate; look for an exact match. */
3231 for (i = 0; i < ARRAY_SIZE(srs); i++)
3232 if (srs[i].rate == params_rate(params))
3233 break;
3234 if (i == ARRAY_SIZE(srs))
3235 return -EINVAL;
3236 rate_val |= srs[i].val << WM8994_AIF1_SR_SHIFT;
3237
3238 dev_dbg(dai->dev, "Sample rate is %dHz\n", srs[i].rate);
3239 dev_dbg(dai->dev, "AIF%dCLK is %dHz, target BCLK %dHz\n",
3240 dai->id, wm8994->aifclk[id], bclk_rate);
3241
3242 if (wm8994->aifclk[id] == 0) {
3243 dev_err(dai->dev, "AIF%dCLK not configured\n", dai->id);
3244 return -EINVAL;
3245 }
3246
3247 /* AIFCLK/fs ratio; look for a close match in either direction */
3248 best = 0;
3249 best_val = abs((fs_ratios[0] * params_rate(params))
3250 - wm8994->aifclk[id]);
3251 for (i = 1; i < ARRAY_SIZE(fs_ratios); i++) {
3252 cur_val = abs((fs_ratios[i] * params_rate(params))
3253 - wm8994->aifclk[id]);
3254 if (cur_val >= best_val)
3255 continue;
3256 best = i;
3257 best_val = cur_val;
3258 }
3259 dev_dbg(dai->dev, "Selected AIF%dCLK/fs = %d\n",
3260 dai->id, fs_ratios[best]);
3261 rate_val |= best;
3262
3263 /* We may not get quite the right frequency if using
3264 * approximate clocks so look for the closest match that is
3265 * higher than the target (we need to ensure that there enough
3266 * BCLKs to clock out the samples).
3267 */
3268 best = 0;
3269 for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) {
3270 cur_val = (wm8994->aifclk[id] * 10 / bclk_divs[i]) - bclk_rate;
3271 if (cur_val < 0) /* BCLK table is sorted */
3272 break;
3273 best = i;
3274 }
3275 bclk_rate = wm8994->aifclk[id] * 10 / bclk_divs[best];
3276 dev_dbg(dai->dev, "Using BCLK_DIV %d for actual BCLK %dHz\n",
3277 bclk_divs[best], bclk_rate);
3278 bclk |= best << WM8994_AIF1_BCLK_DIV_SHIFT;
3279
3280 lrclk = bclk_rate / params_rate(params);
3281 dev_dbg(dai->dev, "Using LRCLK rate %d for actual LRCLK %dHz\n",
3282 lrclk, bclk_rate / lrclk);
3283
3284 snd_soc_update_bits(codec, aif1_reg, WM8994_AIF1_WL_MASK, aif1);
3285 snd_soc_update_bits(codec, bclk_reg, WM8994_AIF1_BCLK_DIV_MASK, bclk);
3286 snd_soc_update_bits(codec, lrclk_reg, WM8994_AIF1DAC_RATE_MASK,
3287 lrclk);
3288 snd_soc_update_bits(codec, rate_reg, WM8994_AIF1_SR_MASK |
3289 WM8994_AIF1CLK_RATE_MASK, rate_val);
3290
3291 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
3292 switch (dai->id) {
3293 case 1:
3294 wm8994->dac_rates[0] = params_rate(params);
3295 wm8994_set_retune_mobile(codec, 0);
3296 wm8994_set_retune_mobile(codec, 1);
3297 break;
3298 case 2:
3299 wm8994->dac_rates[1] = params_rate(params);
3300 wm8994_set_retune_mobile(codec, 2);
3301 break;
3302 }
3303 }
3304
3305 return 0;
3306}
3307
3308static int wm8994_aif_mute(struct snd_soc_dai *codec_dai, int mute)
3309{
3310 struct snd_soc_codec *codec = codec_dai->codec;
3311 int mute_reg;
3312 int reg;
3313
3314 switch (codec_dai->id) {
3315 case 1:
3316 mute_reg = WM8994_AIF1_DAC1_FILTERS_1;
3317 break;
3318 case 2:
3319 mute_reg = WM8994_AIF2_DAC_FILTERS_1;
3320 break;
3321 default:
3322 return -EINVAL;
3323 }
3324
3325 if (mute)
3326 reg = WM8994_AIF1DAC1_MUTE;
3327 else
3328 reg = 0;
3329
3330 snd_soc_update_bits(codec, mute_reg, WM8994_AIF1DAC1_MUTE, reg);
3331
3332 return 0;
3333}
3334
3335#define WM8994_RATES SNDRV_PCM_RATE_8000_96000
3336
3337#define WM8994_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
3338 SNDRV_PCM_FMTBIT_S24_LE)
3339
3340static struct snd_soc_dai_ops wm8994_aif1_dai_ops = {
3341 .set_sysclk = wm8994_set_dai_sysclk,
3342 .set_fmt = wm8994_set_dai_fmt,
3343 .hw_params = wm8994_hw_params,
3344 .digital_mute = wm8994_aif_mute,
3345 .set_pll = wm8994_set_fll,
3346};
3347
3348static struct snd_soc_dai_ops wm8994_aif2_dai_ops = {
3349 .set_sysclk = wm8994_set_dai_sysclk,
3350 .set_fmt = wm8994_set_dai_fmt,
3351 .hw_params = wm8994_hw_params,
3352 .digital_mute = wm8994_aif_mute,
3353 .set_pll = wm8994_set_fll,
3354};
3355
3356struct snd_soc_dai wm8994_dai[] = {
3357 {
3358 .name = "WM8994 AIF1",
3359 .id = 1,
3360 .playback = {
3361 .stream_name = "AIF1 Playback",
3362 .channels_min = 2,
3363 .channels_max = 2,
3364 .rates = WM8994_RATES,
3365 .formats = WM8994_FORMATS,
3366 },
3367 .capture = {
3368 .stream_name = "AIF1 Capture",
3369 .channels_min = 2,
3370 .channels_max = 2,
3371 .rates = WM8994_RATES,
3372 .formats = WM8994_FORMATS,
3373 },
3374 .ops = &wm8994_aif1_dai_ops,
3375 },
3376 {
3377 .name = "WM8994 AIF2",
3378 .id = 2,
3379 .playback = {
3380 .stream_name = "AIF2 Playback",
3381 .channels_min = 2,
3382 .channels_max = 2,
3383 .rates = WM8994_RATES,
3384 .formats = WM8994_FORMATS,
3385 },
3386 .capture = {
3387 .stream_name = "AIF2 Capture",
3388 .channels_min = 2,
3389 .channels_max = 2,
3390 .rates = WM8994_RATES,
3391 .formats = WM8994_FORMATS,
3392 },
3393 .ops = &wm8994_aif2_dai_ops,
3394 },
3395 {
3396 .name = "WM8994 AIF3",
3397 .playback = {
3398 .stream_name = "AIF3 Playback",
3399 .channels_min = 2,
3400 .channels_max = 2,
3401 .rates = WM8994_RATES,
3402 .formats = WM8994_FORMATS,
3403 },
3404 .playback = {
3405 .stream_name = "AIF3 Capture",
3406 .channels_min = 2,
3407 .channels_max = 2,
3408 .rates = WM8994_RATES,
3409 .formats = WM8994_FORMATS,
3410 },
3411 }
3412};
3413EXPORT_SYMBOL_GPL(wm8994_dai);
3414
3415#ifdef CONFIG_PM
3416static int wm8994_suspend(struct platform_device *pdev, pm_message_t state)
3417{
3418 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
3419 struct snd_soc_codec *codec = socdev->card->codec;
3420 struct wm8994_priv *wm8994 = codec->private_data;
3421 int i, ret;
3422
3423 for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) {
3424 memcpy(&wm8994->fll_suspend[i], &wm8994->fll[i],
3425 sizeof(struct fll_config));
3426 ret = wm8994_set_fll(&codec->dai[0], i + 1, 0, 0, 0);
3427 if (ret < 0)
3428 dev_warn(codec->dev, "Failed to stop FLL%d: %d\n",
3429 i + 1, ret);
3430 }
3431
3432 wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF);
3433
3434 return 0;
3435}
3436
3437static int wm8994_resume(struct platform_device *pdev)
3438{
3439 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
3440 struct snd_soc_codec *codec = socdev->card->codec;
3441 struct wm8994_priv *wm8994 = codec->private_data;
3442 u16 *reg_cache = codec->reg_cache;
3443 int i, ret;
3444
3445 /* Restore the registers */
3446 for (i = 1; i < ARRAY_SIZE(wm8994->reg_cache); i++) {
3447 switch (i) {
3448 case WM8994_LDO_1:
3449 case WM8994_LDO_2:
3450 case WM8994_SOFTWARE_RESET:
3451 /* Handled by other MFD drivers */
3452 continue;
3453 default:
3454 break;
3455 }
3456
3457 if (!access_masks[i].writable)
3458 continue;
3459
3460 wm8994_reg_write(codec->control_data, i, reg_cache[i]);
3461 }
3462
3463 wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
3464
3465 for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) {
3466 ret = wm8994_set_fll(&codec->dai[0], i + 1,
3467 wm8994->fll_suspend[i].src,
3468 wm8994->fll_suspend[i].in,
3469 wm8994->fll_suspend[i].out);
3470 if (ret < 0)
3471 dev_warn(codec->dev, "Failed to restore FLL%d: %d\n",
3472 i + 1, ret);
3473 }
3474
3475 return 0;
3476}
3477#else
3478#define wm8994_suspend NULL
3479#define wm8994_resume NULL
3480#endif
3481
3482static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994)
3483{
3484 struct snd_soc_codec *codec = &wm8994->codec;
3485 struct wm8994_pdata *pdata = wm8994->pdata;
3486 struct snd_kcontrol_new controls[] = {
3487 SOC_ENUM_EXT("AIF1.1 EQ Mode",
3488 wm8994->retune_mobile_enum,
3489 wm8994_get_retune_mobile_enum,
3490 wm8994_put_retune_mobile_enum),
3491 SOC_ENUM_EXT("AIF1.2 EQ Mode",
3492 wm8994->retune_mobile_enum,
3493 wm8994_get_retune_mobile_enum,
3494 wm8994_put_retune_mobile_enum),
3495 SOC_ENUM_EXT("AIF2 EQ Mode",
3496 wm8994->retune_mobile_enum,
3497 wm8994_get_retune_mobile_enum,
3498 wm8994_put_retune_mobile_enum),
3499 };
3500 int ret, i, j;
3501 const char **t;
3502
3503 /* We need an array of texts for the enum API but the number
3504 * of texts is likely to be less than the number of
3505 * configurations due to the sample rate dependency of the
3506 * configurations. */
3507 wm8994->num_retune_mobile_texts = 0;
3508 wm8994->retune_mobile_texts = NULL;
3509 for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) {
3510 for (j = 0; j < wm8994->num_retune_mobile_texts; j++) {
3511 if (strcmp(pdata->retune_mobile_cfgs[i].name,
3512 wm8994->retune_mobile_texts[j]) == 0)
3513 break;
3514 }
3515
3516 if (j != wm8994->num_retune_mobile_texts)
3517 continue;
3518
3519 /* Expand the array... */
3520 t = krealloc(wm8994->retune_mobile_texts,
3521 sizeof(char *) *
3522 (wm8994->num_retune_mobile_texts + 1),
3523 GFP_KERNEL);
3524 if (t == NULL)
3525 continue;
3526
3527 /* ...store the new entry... */
3528 t[wm8994->num_retune_mobile_texts] =
3529 pdata->retune_mobile_cfgs[i].name;
3530
3531 /* ...and remember the new version. */
3532 wm8994->num_retune_mobile_texts++;
3533 wm8994->retune_mobile_texts = t;
3534 }
3535
3536 dev_dbg(codec->dev, "Allocated %d unique ReTune Mobile names\n",
3537 wm8994->num_retune_mobile_texts);
3538
3539 wm8994->retune_mobile_enum.max = wm8994->num_retune_mobile_texts;
3540 wm8994->retune_mobile_enum.texts = wm8994->retune_mobile_texts;
3541
3542 ret = snd_soc_add_controls(&wm8994->codec, controls,
3543 ARRAY_SIZE(controls));
3544 if (ret != 0)
3545 dev_err(wm8994->codec.dev,
3546 "Failed to add ReTune Mobile controls: %d\n", ret);
3547}
3548
3549static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
3550{
3551 struct snd_soc_codec *codec = &wm8994->codec;
3552 struct wm8994_pdata *pdata = wm8994->pdata;
3553 int ret, i;
3554
3555 if (!pdata)
3556 return;
3557
3558 wm_hubs_handle_analogue_pdata(codec, pdata->lineout1_diff,
3559 pdata->lineout2_diff,
3560 pdata->lineout1fb,
3561 pdata->lineout2fb,
3562 pdata->jd_scthr,
3563 pdata->jd_thr,
3564 pdata->micbias1_lvl,
3565 pdata->micbias2_lvl);
3566
3567 dev_dbg(codec->dev, "%d DRC configurations\n", pdata->num_drc_cfgs);
3568
3569 if (pdata->num_drc_cfgs) {
3570 struct snd_kcontrol_new controls[] = {
3571 SOC_ENUM_EXT("AIF1DRC1 Mode", wm8994->drc_enum,
3572 wm8994_get_drc_enum, wm8994_put_drc_enum),
3573 SOC_ENUM_EXT("AIF1DRC2 Mode", wm8994->drc_enum,
3574 wm8994_get_drc_enum, wm8994_put_drc_enum),
3575 SOC_ENUM_EXT("AIF2DRC Mode", wm8994->drc_enum,
3576 wm8994_get_drc_enum, wm8994_put_drc_enum),
3577 };
3578
3579 /* We need an array of texts for the enum API */
3580 wm8994->drc_texts = kmalloc(sizeof(char *)
3581 * pdata->num_drc_cfgs, GFP_KERNEL);
3582 if (!wm8994->drc_texts) {
3583 dev_err(wm8994->codec.dev,
3584 "Failed to allocate %d DRC config texts\n",
3585 pdata->num_drc_cfgs);
3586 return;
3587 }
3588
3589 for (i = 0; i < pdata->num_drc_cfgs; i++)
3590 wm8994->drc_texts[i] = pdata->drc_cfgs[i].name;
3591
3592 wm8994->drc_enum.max = pdata->num_drc_cfgs;
3593 wm8994->drc_enum.texts = wm8994->drc_texts;
3594
3595 ret = snd_soc_add_controls(&wm8994->codec, controls,
3596 ARRAY_SIZE(controls));
3597 if (ret != 0)
3598 dev_err(wm8994->codec.dev,
3599 "Failed to add DRC mode controls: %d\n", ret);
3600
3601 for (i = 0; i < WM8994_NUM_DRC; i++)
3602 wm8994_set_drc(codec, i);
3603 }
3604
3605 dev_dbg(codec->dev, "%d ReTune Mobile configurations\n",
3606 pdata->num_retune_mobile_cfgs);
3607
3608 if (pdata->num_retune_mobile_cfgs)
3609 wm8994_handle_retune_mobile_pdata(wm8994);
3610 else
3611 snd_soc_add_controls(&wm8994->codec, wm8994_eq_controls,
3612 ARRAY_SIZE(wm8994_eq_controls));
3613}
3614
3615static int wm8994_probe(struct platform_device *pdev)
3616{
3617 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
3618 struct snd_soc_codec *codec;
3619 int ret = 0;
3620
3621 if (wm8994_codec == NULL) {
3622 dev_err(&pdev->dev, "Codec device not registered\n");
3623 return -ENODEV;
3624 }
3625
3626 socdev->card->codec = wm8994_codec;
3627 codec = wm8994_codec;
3628
3629 /* register pcms */
3630 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
3631 if (ret < 0) {
3632 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
3633 return ret;
3634 }
3635
3636 wm8994_handle_pdata(codec->private_data);
3637
3638 wm_hubs_add_analogue_controls(codec);
3639 snd_soc_add_controls(codec, wm8994_snd_controls,
3640 ARRAY_SIZE(wm8994_snd_controls));
3641 snd_soc_dapm_new_controls(codec, wm8994_dapm_widgets,
3642 ARRAY_SIZE(wm8994_dapm_widgets));
3643 wm_hubs_add_analogue_routes(codec, 0, 0);
3644 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
3645
3646 return 0;
3647}
3648
3649static int wm8994_remove(struct platform_device *pdev)
3650{
3651 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
3652
3653 snd_soc_free_pcms(socdev);
3654 snd_soc_dapm_free(socdev);
3655
3656 return 0;
3657}
3658
3659struct snd_soc_codec_device soc_codec_dev_wm8994 = {
3660 .probe = wm8994_probe,
3661 .remove = wm8994_remove,
3662 .suspend = wm8994_suspend,
3663 .resume = wm8994_resume,
3664};
3665EXPORT_SYMBOL_GPL(soc_codec_dev_wm8994);
3666
3667static int wm8994_codec_probe(struct platform_device *pdev)
3668{
3669 int ret;
3670 struct wm8994_priv *wm8994;
3671 struct snd_soc_codec *codec;
3672 int i;
3673 u16 rev;
3674
3675 if (wm8994_codec) {
3676 dev_err(&pdev->dev, "Another WM8994 is registered\n");
3677 return -EINVAL;
3678 }
3679
3680 wm8994 = kzalloc(sizeof(struct wm8994_priv), GFP_KERNEL);
3681 if (!wm8994) {
3682 dev_err(&pdev->dev, "Failed to allocate private data\n");
3683 return -ENOMEM;
3684 }
3685
3686 codec = &wm8994->codec;
3687
3688 mutex_init(&codec->mutex);
3689 INIT_LIST_HEAD(&codec->dapm_widgets);
3690 INIT_LIST_HEAD(&codec->dapm_paths);
3691
3692 codec->private_data = wm8994;
3693 codec->control_data = dev_get_drvdata(pdev->dev.parent);
3694 codec->name = "WM8994";
3695 codec->owner = THIS_MODULE;
3696 codec->read = wm8994_read;
3697 codec->write = wm8994_write;
3698 codec->readable_register = wm8994_readable;
3699 codec->bias_level = SND_SOC_BIAS_OFF;
3700 codec->set_bias_level = wm8994_set_bias_level;
3701 codec->dai = &wm8994_dai[0];
3702 codec->num_dai = 3;
3703 codec->reg_cache_size = WM8994_MAX_REGISTER;
3704 codec->reg_cache = &wm8994->reg_cache;
3705 codec->dev = &pdev->dev;
3706
3707 wm8994->pdata = pdev->dev.parent->platform_data;
3708
3709 /* Fill the cache with physical values we inherited; don't reset */
3710 ret = wm8994_bulk_read(codec->control_data, 0,
3711 ARRAY_SIZE(wm8994->reg_cache) - 1,
3712 codec->reg_cache);
3713 if (ret < 0) {
3714 dev_err(codec->dev, "Failed to fill register cache: %d\n",
3715 ret);
3716 goto err;
3717 }
3718
3719 /* Clear the cached values for unreadable/volatile registers to
3720 * avoid potential confusion.
3721 */
3722 for (i = 0; i < ARRAY_SIZE(wm8994->reg_cache); i++)
3723 if (wm8994_volatile(i) || !wm8994_readable(i))
3724 wm8994->reg_cache[i] = 0;
3725
3726 /* Set revision-specific configuration */
3727 rev = snd_soc_read(codec, WM8994_CHIP_REVISION);
3728 switch (rev) {
3729 case 2:
3730 case 3:
3731 wm8994->hubs.dcs_codes = -5;
3732 wm8994->hubs.hp_startup_mode = 1;
3733 break;
3734 default:
3735 break;
3736 }
3737
3738
3739 /* Remember if AIFnLRCLK is configured as a GPIO. This should be
3740 * configured on init - if a system wants to do this dynamically
3741 * at runtime we can deal with that then.
3742 */
3743 ret = wm8994_reg_read(codec->control_data, WM8994_GPIO_1);
3744 if (ret < 0) {
3745 dev_err(codec->dev, "Failed to read GPIO1 state: %d\n", ret);
3746 goto err;
3747 }
3748 if ((ret & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) {
3749 wm8994->lrclk_shared[0] = 1;
3750 wm8994_dai[0].symmetric_rates = 1;
3751 } else {
3752 wm8994->lrclk_shared[0] = 0;
3753 }
3754
3755 ret = wm8994_reg_read(codec->control_data, WM8994_GPIO_6);
3756 if (ret < 0) {
3757 dev_err(codec->dev, "Failed to read GPIO6 state: %d\n", ret);
3758 goto err;
3759 }
3760 if ((ret & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) {
3761 wm8994->lrclk_shared[1] = 1;
3762 wm8994_dai[1].symmetric_rates = 1;
3763 } else {
3764 wm8994->lrclk_shared[1] = 0;
3765 }
3766
3767 for (i = 0; i < ARRAY_SIZE(wm8994_dai); i++)
3768 wm8994_dai[i].dev = codec->dev;
3769
3770 wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
3771
3772 wm8994_codec = codec;
3773
3774 /* Latch volume updates (right only; we always do left then right). */
3775 snd_soc_update_bits(codec, WM8994_AIF1_DAC1_RIGHT_VOLUME,
3776 WM8994_AIF1DAC1_VU, WM8994_AIF1DAC1_VU);
3777 snd_soc_update_bits(codec, WM8994_AIF1_DAC2_RIGHT_VOLUME,
3778 WM8994_AIF1DAC2_VU, WM8994_AIF1DAC2_VU);
3779 snd_soc_update_bits(codec, WM8994_AIF2_DAC_RIGHT_VOLUME,
3780 WM8994_AIF2DAC_VU, WM8994_AIF2DAC_VU);
3781 snd_soc_update_bits(codec, WM8994_AIF1_ADC1_RIGHT_VOLUME,
3782 WM8994_AIF1ADC1_VU, WM8994_AIF1ADC1_VU);
3783 snd_soc_update_bits(codec, WM8994_AIF1_ADC2_RIGHT_VOLUME,
3784 WM8994_AIF1ADC2_VU, WM8994_AIF1ADC2_VU);
3785 snd_soc_update_bits(codec, WM8994_AIF2_ADC_RIGHT_VOLUME,
3786 WM8994_AIF2ADC_VU, WM8994_AIF1ADC2_VU);
3787 snd_soc_update_bits(codec, WM8994_DAC1_RIGHT_VOLUME,
3788 WM8994_DAC1_VU, WM8994_DAC1_VU);
3789 snd_soc_update_bits(codec, WM8994_DAC2_RIGHT_VOLUME,
3790 WM8994_DAC2_VU, WM8994_DAC2_VU);
3791
3792 /* Set the low bit of the 3D stereo depth so TLV matches */
3793 snd_soc_update_bits(codec, WM8994_AIF1_DAC1_FILTERS_2,
3794 1 << WM8994_AIF1DAC1_3D_GAIN_SHIFT,
3795 1 << WM8994_AIF1DAC1_3D_GAIN_SHIFT);
3796 snd_soc_update_bits(codec, WM8994_AIF1_DAC2_FILTERS_2,
3797 1 << WM8994_AIF1DAC2_3D_GAIN_SHIFT,
3798 1 << WM8994_AIF1DAC2_3D_GAIN_SHIFT);
3799 snd_soc_update_bits(codec, WM8994_AIF2_DAC_FILTERS_2,
3800 1 << WM8994_AIF2DAC_3D_GAIN_SHIFT,
3801 1 << WM8994_AIF2DAC_3D_GAIN_SHIFT);
3802
3803 wm8994_update_class_w(codec);
3804
3805 ret = snd_soc_register_codec(codec);
3806 if (ret != 0) {
3807 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
3808 goto err;
3809 }
3810
3811 ret = snd_soc_register_dais(wm8994_dai, ARRAY_SIZE(wm8994_dai));
3812 if (ret != 0) {
3813 dev_err(codec->dev, "Failed to register DAIs: %d\n", ret);
3814 goto err_codec;
3815 }
3816
3817 platform_set_drvdata(pdev, wm8994);
3818
3819 return 0;
3820
3821err_codec:
3822 snd_soc_unregister_codec(codec);
3823err:
3824 kfree(wm8994);
3825 return ret;
3826}
3827
3828static int __devexit wm8994_codec_remove(struct platform_device *pdev)
3829{
3830 struct wm8994_priv *wm8994 = platform_get_drvdata(pdev);
3831 struct snd_soc_codec *codec = &wm8994->codec;
3832
3833 wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF);
3834 snd_soc_unregister_dais(wm8994_dai, ARRAY_SIZE(wm8994_dai));
3835 snd_soc_unregister_codec(&wm8994->codec);
3836 kfree(wm8994);
3837 wm8994_codec = NULL;
3838
3839 return 0;
3840}
3841
3842static struct platform_driver wm8994_codec_driver = {
3843 .driver = {
3844 .name = "wm8994-codec",
3845 .owner = THIS_MODULE,
3846 },
3847 .probe = wm8994_codec_probe,
3848 .remove = __devexit_p(wm8994_codec_remove),
3849};
3850
3851static __init int wm8994_init(void)
3852{
3853 return platform_driver_register(&wm8994_codec_driver);
3854}
3855module_init(wm8994_init);
3856
3857static __exit void wm8994_exit(void)
3858{
3859 platform_driver_unregister(&wm8994_codec_driver);
3860}
3861module_exit(wm8994_exit);
3862
3863
3864MODULE_DESCRIPTION("ASoC WM8994 driver");
3865MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
3866MODULE_LICENSE("GPL");
3867MODULE_ALIAS("platform:wm8994-codec");
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h
new file mode 100644
index 000000000000..0a5e1424dea0
--- /dev/null
+++ b/sound/soc/codecs/wm8994.h
@@ -0,0 +1,26 @@
1/*
2 * wm8994.h -- WM8994 Soc Audio driver
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#ifndef _WM8994_H
10#define _WM8994_H
11
12#include <sound/soc.h>
13
14extern struct snd_soc_codec_device soc_codec_dev_wm8994;
15extern struct snd_soc_dai wm8994_dai[];
16
17/* Sources for AIF1/2 SYSCLK - use with set_dai_sysclk() */
18#define WM8994_SYSCLK_MCLK1 1
19#define WM8994_SYSCLK_MCLK2 2
20#define WM8994_SYSCLK_FLL1 3
21#define WM8994_SYSCLK_FLL2 4
22
23#define WM8994_FLL1 1
24#define WM8994_FLL2 2
25
26#endif
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index c58aab375edb..ceb86b4ddb25 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -23,13 +23,12 @@
23#include <sound/ac97_codec.h> 23#include <sound/ac97_codec.h>
24#include <sound/initval.h> 24#include <sound/initval.h>
25#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
26#include <sound/tlv.h>
26#include <sound/soc.h> 27#include <sound/soc.h>
27#include <sound/soc-dapm.h> 28#include <sound/soc-dapm.h>
28 29
29#include "wm9713.h" 30#include "wm9713.h"
30 31
31#define WM9713_VERSION "0.15"
32
33struct wm9713_priv { 32struct wm9713_priv {
34 u32 pll_in; /* PLL input frequency */ 33 u32 pll_in; /* PLL input frequency */
35}; 34};
@@ -115,15 +114,27 @@ SOC_ENUM_SINGLE(AC97_3D_CONTROL, 12, 3, wm9713_mic_select), /* mic selection 18
115SOC_ENUM_SINGLE(MICB_MUX, 0, 2, wm9713_micb_select), /* mic selection 19 */ 114SOC_ENUM_SINGLE(MICB_MUX, 0, 2, wm9713_micb_select), /* mic selection 19 */
116}; 115};
117 116
117static const DECLARE_TLV_DB_SCALE(out_tlv, -4650, 150, 0);
118static const DECLARE_TLV_DB_SCALE(main_tlv, -3450, 150, 0);
119static const DECLARE_TLV_DB_SCALE(misc_tlv, -1500, 300, 0);
120static unsigned int mic_tlv[] = {
121 TLV_DB_RANGE_HEAD(2),
122 0, 2, TLV_DB_SCALE_ITEM(1200, 600, 0),
123 3, 3, TLV_DB_SCALE_ITEM(3000, 0, 0),
124};
125
118static const struct snd_kcontrol_new wm9713_snd_ac97_controls[] = { 126static const struct snd_kcontrol_new wm9713_snd_ac97_controls[] = {
119SOC_DOUBLE("Speaker Playback Volume", AC97_MASTER, 8, 0, 31, 1), 127SOC_DOUBLE_TLV("Speaker Playback Volume", AC97_MASTER, 8, 0, 31, 1, out_tlv),
120SOC_DOUBLE("Speaker Playback Switch", AC97_MASTER, 15, 7, 1, 1), 128SOC_DOUBLE("Speaker Playback Switch", AC97_MASTER, 15, 7, 1, 1),
121SOC_DOUBLE("Headphone Playback Volume", AC97_HEADPHONE, 8, 0, 31, 1), 129SOC_DOUBLE_TLV("Headphone Playback Volume", AC97_HEADPHONE, 8, 0, 31, 1,
130 out_tlv),
122SOC_DOUBLE("Headphone Playback Switch", AC97_HEADPHONE, 15, 7, 1, 1), 131SOC_DOUBLE("Headphone Playback Switch", AC97_HEADPHONE, 15, 7, 1, 1),
123SOC_DOUBLE("Line In Volume", AC97_PC_BEEP, 8, 0, 31, 1), 132SOC_DOUBLE_TLV("Line In Volume", AC97_PC_BEEP, 8, 0, 31, 1, main_tlv),
124SOC_DOUBLE("PCM Playback Volume", AC97_PHONE, 8, 0, 31, 1), 133SOC_DOUBLE_TLV("PCM Playback Volume", AC97_PHONE, 8, 0, 31, 1, main_tlv),
125SOC_SINGLE("Mic 1 Volume", AC97_MIC, 8, 31, 1), 134SOC_SINGLE_TLV("Mic 1 Volume", AC97_MIC, 8, 31, 1, main_tlv),
126SOC_SINGLE("Mic 2 Volume", AC97_MIC, 0, 31, 1), 135SOC_SINGLE_TLV("Mic 2 Volume", AC97_MIC, 0, 31, 1, main_tlv),
136SOC_SINGLE_TLV("Mic 1 Preamp Volume", AC97_3D_CONTROL, 10, 3, 0, mic_tlv),
137SOC_SINGLE_TLV("Mic 2 Preamp Volume", AC97_3D_CONTROL, 12, 3, 0, mic_tlv),
127 138
128SOC_SINGLE("Mic Boost (+20dB) Switch", AC97_LINE, 5, 1, 0), 139SOC_SINGLE("Mic Boost (+20dB) Switch", AC97_LINE, 5, 1, 0),
129SOC_SINGLE("Mic Headphone Mixer Volume", AC97_LINE, 0, 7, 1), 140SOC_SINGLE("Mic Headphone Mixer Volume", AC97_LINE, 0, 7, 1),
@@ -133,7 +144,7 @@ SOC_ENUM("Capture Volume Steps", wm9713_enum[5]),
133SOC_DOUBLE("Capture Volume", AC97_CD, 8, 0, 31, 0), 144SOC_DOUBLE("Capture Volume", AC97_CD, 8, 0, 31, 0),
134SOC_SINGLE("Capture ZC Switch", AC97_CD, 7, 1, 0), 145SOC_SINGLE("Capture ZC Switch", AC97_CD, 7, 1, 0),
135 146
136SOC_SINGLE("Capture to Headphone Volume", AC97_VIDEO, 11, 7, 1), 147SOC_SINGLE_TLV("Capture to Headphone Volume", AC97_VIDEO, 11, 7, 1, misc_tlv),
137SOC_SINGLE("Capture to Mono Boost (+20dB) Switch", AC97_VIDEO, 8, 1, 0), 148SOC_SINGLE("Capture to Mono Boost (+20dB) Switch", AC97_VIDEO, 8, 1, 0),
138SOC_SINGLE("Capture ADC Boost (+20dB) Switch", AC97_VIDEO, 6, 1, 0), 149SOC_SINGLE("Capture ADC Boost (+20dB) Switch", AC97_VIDEO, 6, 1, 0),
139 150
@@ -154,28 +165,43 @@ SOC_DOUBLE("Headphone Playback ZC Switch", AC97_HEADPHONE, 14, 6, 1, 0),
154 165
155SOC_SINGLE("Out4 Playback Switch", AC97_MASTER_MONO, 15, 1, 1), 166SOC_SINGLE("Out4 Playback Switch", AC97_MASTER_MONO, 15, 1, 1),
156SOC_SINGLE("Out4 Playback ZC Switch", AC97_MASTER_MONO, 14, 1, 0), 167SOC_SINGLE("Out4 Playback ZC Switch", AC97_MASTER_MONO, 14, 1, 0),
157SOC_SINGLE("Out4 Playback Volume", AC97_MASTER_MONO, 8, 63, 1), 168SOC_SINGLE_TLV("Out4 Playback Volume", AC97_MASTER_MONO, 8, 31, 1, out_tlv),
158 169
159SOC_SINGLE("Out3 Playback Switch", AC97_MASTER_MONO, 7, 1, 1), 170SOC_SINGLE("Out3 Playback Switch", AC97_MASTER_MONO, 7, 1, 1),
160SOC_SINGLE("Out3 Playback ZC Switch", AC97_MASTER_MONO, 6, 1, 0), 171SOC_SINGLE("Out3 Playback ZC Switch", AC97_MASTER_MONO, 6, 1, 0),
161SOC_SINGLE("Out3 Playback Volume", AC97_MASTER_MONO, 0, 63, 1), 172SOC_SINGLE_TLV("Out3 Playback Volume", AC97_MASTER_MONO, 0, 31, 1, out_tlv),
162 173
163SOC_SINGLE("Mono Capture Volume", AC97_MASTER_TONE, 8, 31, 1), 174SOC_SINGLE_TLV("Mono Capture Volume", AC97_MASTER_TONE, 8, 31, 1, main_tlv),
164SOC_SINGLE("Mono Playback Switch", AC97_MASTER_TONE, 7, 1, 1), 175SOC_SINGLE("Mono Playback Switch", AC97_MASTER_TONE, 7, 1, 1),
165SOC_SINGLE("Mono Playback ZC Switch", AC97_MASTER_TONE, 6, 1, 0), 176SOC_SINGLE("Mono Playback ZC Switch", AC97_MASTER_TONE, 6, 1, 0),
166SOC_SINGLE("Mono Playback Volume", AC97_MASTER_TONE, 0, 31, 1), 177SOC_SINGLE_TLV("Mono Playback Volume", AC97_MASTER_TONE, 0, 31, 1, out_tlv),
167 178
168SOC_SINGLE("Beep Playback Headphone Volume", AC97_AUX, 12, 7, 1), 179SOC_SINGLE_TLV("Headphone Mixer Beep Playback Volume", AC97_AUX, 12, 7, 1,
169SOC_SINGLE("Beep Playback Speaker Volume", AC97_AUX, 8, 7, 1), 180 misc_tlv),
170SOC_SINGLE("Beep Playback Mono Volume", AC97_AUX, 4, 7, 1), 181SOC_SINGLE_TLV("Speaker Mixer Beep Playback Volume", AC97_AUX, 8, 7, 1,
182 misc_tlv),
183SOC_SINGLE_TLV("Mono Mixer Beep Playback Volume", AC97_AUX, 4, 7, 1, misc_tlv),
171 184
172SOC_SINGLE("Voice Playback Headphone Volume", AC97_PCM, 12, 7, 1), 185SOC_SINGLE_TLV("Voice Playback Headphone Volume", AC97_PCM, 12, 7, 1,
186 misc_tlv),
173SOC_SINGLE("Voice Playback Master Volume", AC97_PCM, 8, 7, 1), 187SOC_SINGLE("Voice Playback Master Volume", AC97_PCM, 8, 7, 1),
174SOC_SINGLE("Voice Playback Mono Volume", AC97_PCM, 4, 7, 1), 188SOC_SINGLE("Voice Playback Mono Volume", AC97_PCM, 4, 7, 1),
175 189
190SOC_SINGLE_TLV("Headphone Mixer Aux Playback Volume", AC97_REC_SEL, 12, 7, 1,
191 misc_tlv),
192
193SOC_SINGLE_TLV("Speaker Mixer Voice Playback Volume", AC97_PCM, 8, 7, 1,
194 misc_tlv),
195SOC_SINGLE_TLV("Speaker Mixer Aux Playback Volume", AC97_REC_SEL, 8, 7, 1,
196 misc_tlv),
197
198SOC_SINGLE_TLV("Mono Mixer Voice Playback Volume", AC97_PCM, 4, 7, 1,
199 misc_tlv),
200SOC_SINGLE_TLV("Mono Mixer Aux Playback Volume", AC97_REC_SEL, 4, 7, 1,
201 misc_tlv),
202
176SOC_SINGLE("Aux Playback Headphone Volume", AC97_REC_SEL, 12, 7, 1), 203SOC_SINGLE("Aux Playback Headphone Volume", AC97_REC_SEL, 12, 7, 1),
177SOC_SINGLE("Aux Playback Master Volume", AC97_REC_SEL, 8, 7, 1), 204SOC_SINGLE("Aux Playback Master Volume", AC97_REC_SEL, 8, 7, 1),
178SOC_SINGLE("Aux Playback Mono Volume", AC97_REC_SEL, 4, 7, 1),
179 205
180SOC_ENUM("Bass Control", wm9713_enum[16]), 206SOC_ENUM("Bass Control", wm9713_enum[16]),
181SOC_SINGLE("Bass Cut-off Switch", AC97_GENERAL_PURPOSE, 12, 1, 1), 207SOC_SINGLE("Bass Cut-off Switch", AC97_GENERAL_PURPOSE, 12, 1, 1),
@@ -1186,8 +1212,6 @@ static int wm9713_soc_probe(struct platform_device *pdev)
1186 struct snd_soc_codec *codec; 1212 struct snd_soc_codec *codec;
1187 int ret = 0, reg; 1213 int ret = 0, reg;
1188 1214
1189 printk(KERN_INFO "WM9713/WM9714 SoC Audio Codec %s\n", WM9713_VERSION);
1190
1191 socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), 1215 socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec),
1192 GFP_KERNEL); 1216 GFP_KERNEL);
1193 if (socdev->card->codec == NULL) 1217 if (socdev->card->codec == NULL)
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index d73c30536a2c..0ad9f5d536c6 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -68,24 +68,77 @@ static void wait_for_dc_servo(struct snd_soc_codec *codec)
68 int count = 0; 68 int count = 0;
69 69
70 dev_dbg(codec->dev, "Waiting for DC servo...\n"); 70 dev_dbg(codec->dev, "Waiting for DC servo...\n");
71
71 do { 72 do {
72 count++; 73 count++;
73 msleep(1); 74 msleep(1);
74 reg = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_0); 75 reg = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_0);
75 dev_dbg(codec->dev, "DC servo status: %x\n", reg); 76 dev_dbg(codec->dev, "DC servo: %x\n", reg);
76 } while ((reg & WM8993_DCS_CAL_COMPLETE_MASK) 77 } while (reg & WM8993_DCS_DATAPATH_BUSY);
77 != WM8993_DCS_CAL_COMPLETE_MASK && count < 1000);
78 78
79 if ((reg & WM8993_DCS_CAL_COMPLETE_MASK) 79 if (reg & WM8993_DCS_DATAPATH_BUSY)
80 != WM8993_DCS_CAL_COMPLETE_MASK)
81 dev_err(codec->dev, "Timed out waiting for DC Servo\n"); 80 dev_err(codec->dev, "Timed out waiting for DC Servo\n");
82} 81}
83 82
84/* 83/*
84 * Startup calibration of the DC servo
85 */
86static void calibrate_dc_servo(struct snd_soc_codec *codec)
87{
88 struct wm_hubs_data *hubs = codec->private_data;
89 u16 reg, dcs_cfg;
90
91 /* Set for 32 series updates */
92 snd_soc_update_bits(codec, WM8993_DC_SERVO_1,
93 WM8993_DCS_SERIES_NO_01_MASK,
94 32 << WM8993_DCS_SERIES_NO_01_SHIFT);
95
96 /* Enable the DC servo. Write all bits to avoid triggering startup
97 * or write calibration.
98 */
99 snd_soc_update_bits(codec, WM8993_DC_SERVO_0,
100 0xFFFF,
101 WM8993_DCS_ENA_CHAN_0 |
102 WM8993_DCS_ENA_CHAN_1 |
103 WM8993_DCS_TRIG_SERIES_1 |
104 WM8993_DCS_TRIG_SERIES_0);
105
106 wait_for_dc_servo(codec);
107
108 /* Apply correction to DC servo result */
109 if (hubs->dcs_codes) {
110 dev_dbg(codec->dev, "Applying %d code DC servo correction\n",
111 hubs->dcs_codes);
112
113 /* HPOUT1L */
114 reg = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_1) &
115 WM8993_DCS_INTEG_CHAN_0_MASK;;
116 reg += hubs->dcs_codes;
117 dcs_cfg = reg << WM8993_DCS_DAC_WR_VAL_1_SHIFT;
118
119 /* HPOUT1R */
120 reg = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2) &
121 WM8993_DCS_INTEG_CHAN_1_MASK;
122 reg += hubs->dcs_codes;
123 dcs_cfg |= reg;
124
125 /* Do it */
126 snd_soc_write(codec, WM8993_DC_SERVO_3, dcs_cfg);
127 snd_soc_update_bits(codec, WM8993_DC_SERVO_0,
128 WM8993_DCS_TRIG_DAC_WR_0 |
129 WM8993_DCS_TRIG_DAC_WR_1,
130 WM8993_DCS_TRIG_DAC_WR_0 |
131 WM8993_DCS_TRIG_DAC_WR_1);
132
133 wait_for_dc_servo(codec);
134 }
135}
136
137/*
85 * Update the DC servo calibration on gain changes 138 * Update the DC servo calibration on gain changes
86 */ 139 */
87static int wm8993_put_dc_servo(struct snd_kcontrol *kcontrol, 140static int wm8993_put_dc_servo(struct snd_kcontrol *kcontrol,
88 struct snd_ctl_elem_value *ucontrol) 141 struct snd_ctl_elem_value *ucontrol)
89{ 142{
90 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 143 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
91 int ret; 144 int ret;
@@ -251,6 +304,47 @@ SOC_SINGLE_TLV("LINEOUT2 Volume", WM8993_LINE_OUTPUTS_VOLUME, 0, 1, 1,
251 line_tlv), 304 line_tlv),
252}; 305};
253 306
307static int hp_supply_event(struct snd_soc_dapm_widget *w,
308 struct snd_kcontrol *kcontrol, int event)
309{
310 struct snd_soc_codec *codec = w->codec;
311 struct wm_hubs_data *hubs = codec->private_data;
312
313 switch (event) {
314 case SND_SOC_DAPM_PRE_PMU:
315 switch (hubs->hp_startup_mode) {
316 case 0:
317 break;
318 case 1:
319 /* Enable the headphone amp */
320 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
321 WM8993_HPOUT1L_ENA |
322 WM8993_HPOUT1R_ENA,
323 WM8993_HPOUT1L_ENA |
324 WM8993_HPOUT1R_ENA);
325
326 /* Enable the second stage */
327 snd_soc_update_bits(codec, WM8993_ANALOGUE_HP_0,
328 WM8993_HPOUT1L_DLY |
329 WM8993_HPOUT1R_DLY,
330 WM8993_HPOUT1L_DLY |
331 WM8993_HPOUT1R_DLY);
332 break;
333 default:
334 dev_err(codec->dev, "Unknown HP startup mode %d\n",
335 hubs->hp_startup_mode);
336 break;
337 }
338
339 case SND_SOC_DAPM_PRE_PMD:
340 snd_soc_update_bits(codec, WM8993_CHARGE_PUMP_1,
341 WM8993_CP_ENA, 0);
342 break;
343 }
344
345 return 0;
346}
347
254static int hp_event(struct snd_soc_dapm_widget *w, 348static int hp_event(struct snd_soc_dapm_widget *w,
255 struct snd_kcontrol *kcontrol, int event) 349 struct snd_kcontrol *kcontrol, int event)
256{ 350{
@@ -271,14 +365,11 @@ static int hp_event(struct snd_soc_dapm_widget *w,
271 reg |= WM8993_HPOUT1L_DLY | WM8993_HPOUT1R_DLY; 365 reg |= WM8993_HPOUT1L_DLY | WM8993_HPOUT1R_DLY;
272 snd_soc_write(codec, WM8993_ANALOGUE_HP_0, reg); 366 snd_soc_write(codec, WM8993_ANALOGUE_HP_0, reg);
273 367
274 /* Start the DC servo */ 368 /* Smallest supported update interval */
275 snd_soc_update_bits(codec, WM8993_DC_SERVO_0, 369 snd_soc_update_bits(codec, WM8993_DC_SERVO_1,
276 0xFFFF, 370 WM8993_DCS_TIMER_PERIOD_01_MASK, 1);
277 WM8993_DCS_ENA_CHAN_0 | 371
278 WM8993_DCS_ENA_CHAN_1 | 372 calibrate_dc_servo(codec);
279 WM8993_DCS_TRIG_STARTUP_1 |
280 WM8993_DCS_TRIG_STARTUP_0);
281 wait_for_dc_servo(codec);
282 373
283 reg |= WM8993_HPOUT1R_OUTP | WM8993_HPOUT1R_RMV_SHORT | 374 reg |= WM8993_HPOUT1R_OUTP | WM8993_HPOUT1R_RMV_SHORT |
284 WM8993_HPOUT1L_OUTP | WM8993_HPOUT1L_RMV_SHORT; 375 WM8993_HPOUT1L_OUTP | WM8993_HPOUT1L_RMV_SHORT;
@@ -286,23 +377,19 @@ static int hp_event(struct snd_soc_dapm_widget *w,
286 break; 377 break;
287 378
288 case SND_SOC_DAPM_PRE_PMD: 379 case SND_SOC_DAPM_PRE_PMD:
289 reg &= ~(WM8993_HPOUT1L_RMV_SHORT | 380 snd_soc_update_bits(codec, WM8993_ANALOGUE_HP_0,
290 WM8993_HPOUT1L_DLY | 381 WM8993_HPOUT1L_DLY |
291 WM8993_HPOUT1L_OUTP | 382 WM8993_HPOUT1R_DLY |
292 WM8993_HPOUT1R_RMV_SHORT | 383 WM8993_HPOUT1L_RMV_SHORT |
293 WM8993_HPOUT1R_DLY | 384 WM8993_HPOUT1R_RMV_SHORT, 0);
294 WM8993_HPOUT1R_OUTP);
295 385
296 snd_soc_update_bits(codec, WM8993_DC_SERVO_0, 386 snd_soc_update_bits(codec, WM8993_ANALOGUE_HP_0,
297 0xffff, 0); 387 WM8993_HPOUT1L_OUTP |
388 WM8993_HPOUT1R_OUTP, 0);
298 389
299 snd_soc_write(codec, WM8993_ANALOGUE_HP_0, reg);
300 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1, 390 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
301 WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA, 391 WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA,
302 0); 392 0);
303
304 snd_soc_update_bits(codec, WM8993_CHARGE_PUMP_1,
305 WM8993_CP_ENA, 0);
306 break; 393 break;
307 } 394 }
308 395
@@ -473,6 +560,8 @@ SND_SOC_DAPM_MIXER("Right Output Mixer", WM8993_POWER_MANAGEMENT_3, 4, 0,
473SND_SOC_DAPM_PGA("Left Output PGA", WM8993_POWER_MANAGEMENT_3, 7, 0, NULL, 0), 560SND_SOC_DAPM_PGA("Left Output PGA", WM8993_POWER_MANAGEMENT_3, 7, 0, NULL, 0),
474SND_SOC_DAPM_PGA("Right Output PGA", WM8993_POWER_MANAGEMENT_3, 6, 0, NULL, 0), 561SND_SOC_DAPM_PGA("Right Output PGA", WM8993_POWER_MANAGEMENT_3, 6, 0, NULL, 0),
475 562
563SND_SOC_DAPM_SUPPLY("Headphone Supply", SND_SOC_NOPM, 0, 0, hp_supply_event,
564 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
476SND_SOC_DAPM_PGA_E("Headphone PGA", SND_SOC_NOPM, 0, 0, 565SND_SOC_DAPM_PGA_E("Headphone PGA", SND_SOC_NOPM, 0, 0,
477 NULL, 0, 566 NULL, 0,
478 hp_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 567 hp_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
@@ -626,6 +715,7 @@ static const struct snd_soc_dapm_route analogue_routes[] = {
626 { "Headphone PGA", NULL, "Left Headphone Mux" }, 715 { "Headphone PGA", NULL, "Left Headphone Mux" },
627 { "Headphone PGA", NULL, "Right Headphone Mux" }, 716 { "Headphone PGA", NULL, "Right Headphone Mux" },
628 { "Headphone PGA", NULL, "CLK_SYS" }, 717 { "Headphone PGA", NULL, "CLK_SYS" },
718 { "Headphone PGA", NULL, "Headphone Supply" },
629 719
630 { "HPOUT1L", NULL, "Headphone PGA" }, 720 { "HPOUT1L", NULL, "Headphone PGA" },
631 { "HPOUT1R", NULL, "Headphone PGA" }, 721 { "HPOUT1R", NULL, "Headphone PGA" },
@@ -753,6 +843,12 @@ int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *codec,
753 WM8993_LINEOUT2_MODE, 843 WM8993_LINEOUT2_MODE,
754 WM8993_LINEOUT2_MODE); 844 WM8993_LINEOUT2_MODE);
755 845
846 /* If the line outputs are differential then we aren't presenting
847 * VMID as an output and can disable it.
848 */
849 if (lineout1_diff && lineout2_diff)
850 codec->idle_bias_off = 1;
851
756 if (lineout1fb) 852 if (lineout1fb)
757 snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL, 853 snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL,
758 WM8993_LINEOUT1_FB, WM8993_LINEOUT1_FB); 854 WM8993_LINEOUT1_FB, WM8993_LINEOUT1_FB);
diff --git a/sound/soc/codecs/wm_hubs.h b/sound/soc/codecs/wm_hubs.h
index 36d3fba1de8b..420104fe9c90 100644
--- a/sound/soc/codecs/wm_hubs.h
+++ b/sound/soc/codecs/wm_hubs.h
@@ -18,6 +18,12 @@ struct snd_soc_codec;
18 18
19extern const unsigned int wm_hubs_spkmix_tlv[]; 19extern const unsigned int wm_hubs_spkmix_tlv[];
20 20
21/* This *must* be the first element of the codec->private_data struct */
22struct wm_hubs_data {
23 int dcs_codes;
24 int hp_startup_mode;
25};
26
21extern int wm_hubs_add_analogue_controls(struct snd_soc_codec *); 27extern int wm_hubs_add_analogue_controls(struct snd_soc_codec *);
22extern int wm_hubs_add_analogue_routes(struct snd_soc_codec *, int, int); 28extern int wm_hubs_add_analogue_routes(struct snd_soc_codec *, int, int);
23extern int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *, 29extern int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *,
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index 0a302e1080d9..ab6518d86f18 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -767,14 +767,26 @@ static int davinci_mcasp_trigger(struct snd_pcm_substream *substream,
767 int ret = 0; 767 int ret = 0;
768 768
769 switch (cmd) { 769 switch (cmd) {
770 case SNDRV_PCM_TRIGGER_START:
771 case SNDRV_PCM_TRIGGER_RESUME: 770 case SNDRV_PCM_TRIGGER_RESUME:
771 case SNDRV_PCM_TRIGGER_START:
772 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 772 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
773 if (!dev->clk_active) {
774 clk_enable(dev->clk);
775 dev->clk_active = 1;
776 }
773 davinci_mcasp_start(dev, substream->stream); 777 davinci_mcasp_start(dev, substream->stream);
774 break; 778 break;
775 779
776 case SNDRV_PCM_TRIGGER_STOP:
777 case SNDRV_PCM_TRIGGER_SUSPEND: 780 case SNDRV_PCM_TRIGGER_SUSPEND:
781 davinci_mcasp_stop(dev, substream->stream);
782 if (dev->clk_active) {
783 clk_disable(dev->clk);
784 dev->clk_active = 0;
785 }
786
787 break;
788
789 case SNDRV_PCM_TRIGGER_STOP:
778 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 790 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
779 davinci_mcasp_stop(dev, substream->stream); 791 davinci_mcasp_stop(dev, substream->stream);
780 break; 792 break;
@@ -866,6 +878,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
866 } 878 }
867 879
868 clk_enable(dev->clk); 880 clk_enable(dev->clk);
881 dev->clk_active = 1;
869 882
870 dev->base = (void __iomem *)IO_ADDRESS(mem->start); 883 dev->base = (void __iomem *)IO_ADDRESS(mem->start);
871 dev->op_mode = pdata->op_mode; 884 dev->op_mode = pdata->op_mode;
diff --git a/sound/soc/davinci/davinci-mcasp.h b/sound/soc/davinci/davinci-mcasp.h
index 582c9249ef09..e755b5121ec7 100644
--- a/sound/soc/davinci/davinci-mcasp.h
+++ b/sound/soc/davinci/davinci-mcasp.h
@@ -44,6 +44,7 @@ struct davinci_audio_dev {
44 int sample_rate; 44 int sample_rate;
45 struct clk *clk; 45 struct clk *clk;
46 unsigned int codec_fmt; 46 unsigned int codec_fmt;
47 u8 clk_active;
47 48
48 /* McASP specific data */ 49 /* McASP specific data */
49 int tdm_slots; 50 int tdm_slots;
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c
index ad4d7f47a86b..80c7fdf2f521 100644
--- a/sound/soc/davinci/davinci-pcm.c
+++ b/sound/soc/davinci/davinci-pcm.c
@@ -49,7 +49,7 @@ static void print_buf_info(int slot, char *name)
49static struct snd_pcm_hardware pcm_hardware_playback = { 49static struct snd_pcm_hardware pcm_hardware_playback = {
50 .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | 50 .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
51 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | 51 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
52 SNDRV_PCM_INFO_PAUSE), 52 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
53 .formats = (SNDRV_PCM_FMTBIT_S16_LE), 53 .formats = (SNDRV_PCM_FMTBIT_S16_LE),
54 .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | 54 .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
55 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | 55 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 |
diff --git a/sound/soc/fsl/efika-audio-fabric.c b/sound/soc/fsl/efika-audio-fabric.c
index 3326e2a1e863..1a5b8e0d6a34 100644
--- a/sound/soc/fsl/efika-audio-fabric.c
+++ b/sound/soc/fsl/efika-audio-fabric.c
@@ -55,7 +55,7 @@ static __init int efika_fabric_init(void)
55 struct platform_device *pdev; 55 struct platform_device *pdev;
56 int rc; 56 int rc;
57 57
58 if (!machine_is_compatible("bplan,efika")) 58 if (!of_machine_is_compatible("bplan,efika"))
59 return -ENODEV; 59 return -ENODEV;
60 60
61 card.platform = &mpc5200_audio_dma_platform; 61 card.platform = &mpc5200_audio_dma_platform;
diff --git a/sound/soc/fsl/pcm030-audio-fabric.c b/sound/soc/fsl/pcm030-audio-fabric.c
index b928ef7d28eb..6644cba7cbf2 100644
--- a/sound/soc/fsl/pcm030-audio-fabric.c
+++ b/sound/soc/fsl/pcm030-audio-fabric.c
@@ -55,7 +55,7 @@ static __init int pcm030_fabric_init(void)
55 struct platform_device *pdev; 55 struct platform_device *pdev;
56 int rc; 56 int rc;
57 57
58 if (!machine_is_compatible("phytec,pcm030")) 58 if (!of_machine_is_compatible("phytec,pcm030"))
59 return -ENODEV; 59 return -ENODEV;
60 60
61 card.platform = &mpc5200_audio_dma_platform; 61 card.platform = &mpc5200_audio_dma_platform;
diff --git a/sound/soc/imx/Kconfig b/sound/soc/imx/Kconfig
index a700562e8692..c7d0fd9b7de8 100644
--- a/sound/soc/imx/Kconfig
+++ b/sound/soc/imx/Kconfig
@@ -1,21 +1,13 @@
1config SND_MX1_MX2_SOC 1config SND_IMX_SOC
2 tristate "SoC Audio for Freecale i.MX1x i.MX2x CPUs" 2 tristate "SoC Audio for Freescale i.MX CPUs"
3 depends on ARCH_MX2 || ARCH_MX1 3 depends on ARCH_MXC && BROKEN
4 select SND_PCM 4 select SND_PCM
5 select FIQ
6 select SND_SOC_AC97_BUS
5 help 7 help
6 Say Y or M if you want to add support for codecs attached to 8 Say Y or M if you want to add support for codecs attached to
7 the MX1 or MX2 SSI interface. 9 the i.MX SSI interface.
8 10
9config SND_MXC_SOC_SSI 11config SND_MXC_SOC_SSI
10 tristate 12 tristate
11 13
12config SND_SOC_MX27VIS_WM8974
13 tristate "SoC Audio support for MX27 - WM8974 Visstrim_sm10 board"
14 depends on SND_MX1_MX2_SOC && MACH_MX27 && MACH_IMX27_VISSTRIM_M10
15 select SND_MXC_SOC_SSI
16 select SND_SOC_WM8974
17 help
18 Say Y if you want to add support for SoC audio on Visstrim SM10
19 board with WM8974.
20
21
diff --git a/sound/soc/imx/Makefile b/sound/soc/imx/Makefile
index c2ffd2c8df5a..9f8bb92ddfcc 100644
--- a/sound/soc/imx/Makefile
+++ b/sound/soc/imx/Makefile
@@ -1,10 +1,12 @@
1# i.MX Platform Support 1# i.MX Platform Support
2snd-soc-mx1_mx2-objs := mx1_mx2-pcm.o 2snd-soc-imx-objs := imx-ssi.o imx-pcm-fiq.o
3snd-soc-mxc-ssi-objs := mxc-ssi.o
4 3
5obj-$(CONFIG_SND_MX1_MX2_SOC) += snd-soc-mx1_mx2.o 4ifdef CONFIG_MACH_MX27
6obj-$(CONFIG_SND_MXC_SOC_SSI) += snd-soc-mxc-ssi.o 5snd-soc-imx-objs += imx-pcm-dma-mx2.o
6endif
7
8obj-$(CONFIG_SND_IMX_SOC) += snd-soc-imx.o
7 9
8# i.MX Machine Support 10# i.MX Machine Support
9snd-soc-mx27vis-wm8974-objs := mx27vis_wm8974.o 11snd-soc-phycore-ac97-objs := phycore-ac97.o
10obj-$(CONFIG_SND_SOC_MX27VIS_WM8974) += snd-soc-mx27vis-wm8974.o 12obj-$(CONFIG_SND_SOC_PHYCORE_AC97) += snd-soc-phycore-ac97.o
diff --git a/sound/soc/imx/imx-pcm-dma-mx2.c b/sound/soc/imx/imx-pcm-dma-mx2.c
new file mode 100644
index 000000000000..19452e44afdc
--- /dev/null
+++ b/sound/soc/imx/imx-pcm-dma-mx2.c
@@ -0,0 +1,313 @@
1/*
2 * imx-pcm-dma-mx2.c -- ALSA Soc Audio Layer
3 *
4 * Copyright 2009 Sascha Hauer <s.hauer@pengutronix.de>
5 *
6 * This code is based on code copyrighted by Freescale,
7 * Liam Girdwood, Javier Martin and probably others.
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#include <linux/clk.h>
15#include <linux/delay.h>
16#include <linux/device.h>
17#include <linux/dma-mapping.h>
18#include <linux/init.h>
19#include <linux/interrupt.h>
20#include <linux/module.h>
21#include <linux/platform_device.h>
22
23#include <sound/core.h>
24#include <sound/initval.h>
25#include <sound/pcm.h>
26#include <sound/pcm_params.h>
27#include <sound/soc.h>
28
29#include <mach/dma-mx1-mx2.h>
30
31#include "imx-ssi.h"
32
33struct imx_pcm_runtime_data {
34 int sg_count;
35 struct scatterlist *sg_list;
36 int period;
37 int periods;
38 unsigned long dma_addr;
39 int dma;
40 struct snd_pcm_substream *substream;
41 unsigned long offset;
42 unsigned long size;
43 unsigned long period_cnt;
44 void *buf;
45 int period_time;
46};
47
48/* Called by the DMA framework when a period has elapsed */
49static void imx_ssi_dma_progression(int channel, void *data,
50 struct scatterlist *sg)
51{
52 struct snd_pcm_substream *substream = data;
53 struct snd_pcm_runtime *runtime = substream->runtime;
54 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
55
56 if (!sg)
57 return;
58
59 runtime = iprtd->substream->runtime;
60
61 iprtd->offset = sg->dma_address - runtime->dma_addr;
62
63 snd_pcm_period_elapsed(iprtd->substream);
64}
65
66static void imx_ssi_dma_callback(int channel, void *data)
67{
68 pr_err("%s shouldn't be called\n", __func__);
69}
70
71static void snd_imx_dma_err_callback(int channel, void *data, int err)
72{
73 pr_err("DMA error callback called\n");
74
75 pr_err("DMA timeout on channel %d -%s%s%s%s\n",
76 channel,
77 err & IMX_DMA_ERR_BURST ? " burst" : "",
78 err & IMX_DMA_ERR_REQUEST ? " request" : "",
79 err & IMX_DMA_ERR_TRANSFER ? " transfer" : "",
80 err & IMX_DMA_ERR_BUFFER ? " buffer" : "");
81}
82
83static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream)
84{
85 struct snd_soc_pcm_runtime *rtd = substream->private_data;
86 struct imx_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data;
87 struct snd_pcm_runtime *runtime = substream->runtime;
88 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
89 int ret;
90
91 iprtd->dma = imx_dma_request_by_prio(DRV_NAME, DMA_PRIO_HIGH);
92 if (iprtd->dma < 0) {
93 pr_err("Failed to claim the audio DMA\n");
94 return -ENODEV;
95 }
96
97 ret = imx_dma_setup_handlers(iprtd->dma,
98 imx_ssi_dma_callback,
99 snd_imx_dma_err_callback, substream);
100 if (ret)
101 goto out;
102
103 ret = imx_dma_setup_progression_handler(iprtd->dma,
104 imx_ssi_dma_progression);
105 if (ret) {
106 pr_err("Failed to setup the DMA handler\n");
107 goto out;
108 }
109
110 ret = imx_dma_config_channel(iprtd->dma,
111 IMX_DMA_MEMSIZE_16 | IMX_DMA_TYPE_FIFO,
112 IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR,
113 dma_params->dma, 1);
114 if (ret < 0) {
115 pr_err("Cannot configure DMA channel: %d\n", ret);
116 goto out;
117 }
118
119 imx_dma_config_burstlen(iprtd->dma, dma_params->burstsize * 2);
120
121 return 0;
122out:
123 imx_dma_free(iprtd->dma);
124 return ret;
125}
126
127static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream,
128 struct snd_pcm_hw_params *params)
129{
130 struct snd_pcm_runtime *runtime = substream->runtime;
131 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
132 int i;
133 unsigned long dma_addr;
134
135 imx_ssi_dma_alloc(substream);
136
137 iprtd->size = params_buffer_bytes(params);
138 iprtd->periods = params_periods(params);
139 iprtd->period = params_period_bytes(params);
140 iprtd->offset = 0;
141 iprtd->period_time = HZ / (params_rate(params) /
142 params_period_size(params));
143
144 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
145
146 if (iprtd->sg_count != iprtd->periods) {
147 kfree(iprtd->sg_list);
148
149 iprtd->sg_list = kcalloc(iprtd->periods + 1,
150 sizeof(struct scatterlist), GFP_KERNEL);
151 if (!iprtd->sg_list)
152 return -ENOMEM;
153 iprtd->sg_count = iprtd->periods + 1;
154 }
155
156 sg_init_table(iprtd->sg_list, iprtd->sg_count);
157 dma_addr = runtime->dma_addr;
158
159 for (i = 0; i < iprtd->periods; i++) {
160 iprtd->sg_list[i].page_link = 0;
161 iprtd->sg_list[i].offset = 0;
162 iprtd->sg_list[i].dma_address = dma_addr;
163 iprtd->sg_list[i].length = iprtd->period;
164 dma_addr += iprtd->period;
165 }
166
167 /* close the loop */
168 iprtd->sg_list[iprtd->sg_count - 1].offset = 0;
169 iprtd->sg_list[iprtd->sg_count - 1].length = 0;
170 iprtd->sg_list[iprtd->sg_count - 1].page_link =
171 ((unsigned long) iprtd->sg_list | 0x01) & ~0x02;
172 return 0;
173}
174
175static int snd_imx_pcm_hw_free(struct snd_pcm_substream *substream)
176{
177 struct snd_pcm_runtime *runtime = substream->runtime;
178 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
179
180 if (iprtd->dma >= 0) {
181 imx_dma_free(iprtd->dma);
182 iprtd->dma = -EINVAL;
183 }
184
185 kfree(iprtd->sg_list);
186 iprtd->sg_list = NULL;
187
188 return 0;
189}
190
191static int snd_imx_pcm_prepare(struct snd_pcm_substream *substream)
192{
193 struct snd_pcm_runtime *runtime = substream->runtime;
194 struct snd_soc_pcm_runtime *rtd = substream->private_data;
195 struct imx_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data;
196 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
197 int err;
198
199 iprtd->substream = substream;
200 iprtd->buf = (unsigned int *)substream->dma_buffer.area;
201 iprtd->period_cnt = 0;
202
203 pr_debug("%s: buf: %p period: %d periods: %d\n",
204 __func__, iprtd->buf, iprtd->period, iprtd->periods);
205
206 err = imx_dma_setup_sg(iprtd->dma, iprtd->sg_list, iprtd->sg_count,
207 IMX_DMA_LENGTH_LOOP, dma_params->dma_addr,
208 substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
209 DMA_MODE_WRITE : DMA_MODE_READ);
210 if (err)
211 return err;
212
213 return 0;
214}
215
216static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
217{
218 struct snd_pcm_runtime *runtime = substream->runtime;
219 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
220
221 switch (cmd) {
222 case SNDRV_PCM_TRIGGER_START:
223 case SNDRV_PCM_TRIGGER_RESUME:
224 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
225 imx_dma_enable(iprtd->dma);
226
227 break;
228
229 case SNDRV_PCM_TRIGGER_STOP:
230 case SNDRV_PCM_TRIGGER_SUSPEND:
231 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
232 imx_dma_disable(iprtd->dma);
233
234 break;
235 default:
236 return -EINVAL;
237 }
238
239 return 0;
240}
241
242static snd_pcm_uframes_t snd_imx_pcm_pointer(struct snd_pcm_substream *substream)
243{
244 struct snd_pcm_runtime *runtime = substream->runtime;
245 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
246
247 return bytes_to_frames(substream->runtime, iprtd->offset);
248}
249
250static struct snd_pcm_hardware snd_imx_hardware = {
251 .info = SNDRV_PCM_INFO_INTERLEAVED |
252 SNDRV_PCM_INFO_BLOCK_TRANSFER |
253 SNDRV_PCM_INFO_MMAP |
254 SNDRV_PCM_INFO_MMAP_VALID |
255 SNDRV_PCM_INFO_PAUSE |
256 SNDRV_PCM_INFO_RESUME,
257 .formats = SNDRV_PCM_FMTBIT_S16_LE,
258 .rate_min = 8000,
259 .channels_min = 2,
260 .channels_max = 2,
261 .buffer_bytes_max = IMX_SSI_DMABUF_SIZE,
262 .period_bytes_min = 128,
263 .period_bytes_max = 16 * 1024,
264 .periods_min = 2,
265 .periods_max = 255,
266 .fifo_size = 0,
267};
268
269static int snd_imx_open(struct snd_pcm_substream *substream)
270{
271 struct snd_pcm_runtime *runtime = substream->runtime;
272 struct imx_pcm_runtime_data *iprtd;
273 int ret;
274
275 iprtd = kzalloc(sizeof(*iprtd), GFP_KERNEL);
276 runtime->private_data = iprtd;
277
278 ret = snd_pcm_hw_constraint_integer(substream->runtime,
279 SNDRV_PCM_HW_PARAM_PERIODS);
280 if (ret < 0)
281 return ret;
282
283 snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware);
284 return 0;
285}
286
287static struct snd_pcm_ops imx_pcm_ops = {
288 .open = snd_imx_open,
289 .ioctl = snd_pcm_lib_ioctl,
290 .hw_params = snd_imx_pcm_hw_params,
291 .hw_free = snd_imx_pcm_hw_free,
292 .prepare = snd_imx_pcm_prepare,
293 .trigger = snd_imx_pcm_trigger,
294 .pointer = snd_imx_pcm_pointer,
295 .mmap = snd_imx_pcm_mmap,
296};
297
298static struct snd_soc_platform imx_soc_platform_dma = {
299 .name = "imx-audio",
300 .pcm_ops = &imx_pcm_ops,
301 .pcm_new = imx_pcm_new,
302 .pcm_free = imx_pcm_free,
303};
304
305struct snd_soc_platform *imx_ssi_dma_mx2_init(struct platform_device *pdev,
306 struct imx_ssi *ssi)
307{
308 ssi->dma_params_tx.burstsize = DMA_TXFIFO_BURST;
309 ssi->dma_params_rx.burstsize = DMA_RXFIFO_BURST;
310
311 return &imx_soc_platform_dma;
312}
313
diff --git a/sound/soc/imx/imx-pcm-fiq.c b/sound/soc/imx/imx-pcm-fiq.c
new file mode 100644
index 000000000000..d9cb9849b033
--- /dev/null
+++ b/sound/soc/imx/imx-pcm-fiq.c
@@ -0,0 +1,297 @@
1/*
2 * imx-pcm-fiq.c -- ALSA Soc Audio Layer
3 *
4 * Copyright 2009 Sascha Hauer <s.hauer@pengutronix.de>
5 *
6 * This code is based on code copyrighted by Freescale,
7 * Liam Girdwood, Javier Martin and probably others.
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#include <linux/clk.h>
15#include <linux/delay.h>
16#include <linux/device.h>
17#include <linux/dma-mapping.h>
18#include <linux/init.h>
19#include <linux/interrupt.h>
20#include <linux/module.h>
21#include <linux/platform_device.h>
22
23#include <sound/core.h>
24#include <sound/initval.h>
25#include <sound/pcm.h>
26#include <sound/pcm_params.h>
27#include <sound/soc.h>
28
29#include <asm/fiq.h>
30
31#include <mach/ssi.h>
32
33#include "imx-ssi.h"
34
35struct imx_pcm_runtime_data {
36 int period;
37 int periods;
38 unsigned long offset;
39 unsigned long last_offset;
40 unsigned long size;
41 struct timer_list timer;
42 int poll_time;
43};
44
45static inline void imx_ssi_set_next_poll(struct imx_pcm_runtime_data *iprtd)
46{
47 iprtd->timer.expires = jiffies + iprtd->poll_time;
48}
49
50static void imx_ssi_timer_callback(unsigned long data)
51{
52 struct snd_pcm_substream *substream = (void *)data;
53 struct snd_pcm_runtime *runtime = substream->runtime;
54 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
55 struct pt_regs regs;
56 unsigned long delta;
57
58 get_fiq_regs(&regs);
59
60 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
61 iprtd->offset = regs.ARM_r8 & 0xffff;
62 else
63 iprtd->offset = regs.ARM_r9 & 0xffff;
64
65 /* How much data have we transferred since the last period report? */
66 if (iprtd->offset >= iprtd->last_offset)
67 delta = iprtd->offset - iprtd->last_offset;
68 else
69 delta = runtime->buffer_size + iprtd->offset
70 - iprtd->last_offset;
71
72 /* If we've transferred at least a period then report it and
73 * reset our poll time */
74 if (delta >= runtime->period_size) {
75 snd_pcm_period_elapsed(substream);
76 iprtd->last_offset = iprtd->offset;
77
78 imx_ssi_set_next_poll(iprtd);
79 }
80
81 /* Restart the timer; if we didn't report we'll run on the next tick */
82 add_timer(&iprtd->timer);
83
84}
85
86static struct fiq_handler fh = {
87 .name = DRV_NAME,
88};
89
90static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream,
91 struct snd_pcm_hw_params *params)
92{
93 struct snd_pcm_runtime *runtime = substream->runtime;
94 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
95
96 iprtd->size = params_buffer_bytes(params);
97 iprtd->periods = params_periods(params);
98 iprtd->period = params_period_bytes(params) ;
99 iprtd->offset = 0;
100 iprtd->last_offset = 0;
101 iprtd->poll_time = HZ / (params_rate(params) / params_period_size(params));
102
103 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
104
105 return 0;
106}
107
108static int snd_imx_pcm_prepare(struct snd_pcm_substream *substream)
109{
110 struct snd_pcm_runtime *runtime = substream->runtime;
111 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
112 struct pt_regs regs;
113
114 get_fiq_regs(&regs);
115 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
116 regs.ARM_r8 = (iprtd->period * iprtd->periods - 1) << 16;
117 else
118 regs.ARM_r9 = (iprtd->period * iprtd->periods - 1) << 16;
119
120 set_fiq_regs(&regs);
121
122 return 0;
123}
124
125static int fiq_enable;
126static int imx_pcm_fiq;
127
128static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
129{
130 struct snd_pcm_runtime *runtime = substream->runtime;
131 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
132
133 switch (cmd) {
134 case SNDRV_PCM_TRIGGER_START:
135 case SNDRV_PCM_TRIGGER_RESUME:
136 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
137 imx_ssi_set_next_poll(iprtd);
138 add_timer(&iprtd->timer);
139 if (++fiq_enable == 1)
140 enable_fiq(imx_pcm_fiq);
141
142 break;
143
144 case SNDRV_PCM_TRIGGER_STOP:
145 case SNDRV_PCM_TRIGGER_SUSPEND:
146 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
147 del_timer(&iprtd->timer);
148 if (--fiq_enable == 0)
149 disable_fiq(imx_pcm_fiq);
150
151
152 break;
153 default:
154 return -EINVAL;
155 }
156
157 return 0;
158}
159
160static snd_pcm_uframes_t snd_imx_pcm_pointer(struct snd_pcm_substream *substream)
161{
162 struct snd_pcm_runtime *runtime = substream->runtime;
163 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
164
165 return bytes_to_frames(substream->runtime, iprtd->offset);
166}
167
168static struct snd_pcm_hardware snd_imx_hardware = {
169 .info = SNDRV_PCM_INFO_INTERLEAVED |
170 SNDRV_PCM_INFO_BLOCK_TRANSFER |
171 SNDRV_PCM_INFO_MMAP |
172 SNDRV_PCM_INFO_MMAP_VALID |
173 SNDRV_PCM_INFO_PAUSE |
174 SNDRV_PCM_INFO_RESUME,
175 .formats = SNDRV_PCM_FMTBIT_S16_LE,
176 .rate_min = 8000,
177 .channels_min = 2,
178 .channels_max = 2,
179 .buffer_bytes_max = IMX_SSI_DMABUF_SIZE,
180 .period_bytes_min = 128,
181 .period_bytes_max = 16 * 1024,
182 .periods_min = 2,
183 .periods_max = 255,
184 .fifo_size = 0,
185};
186
187static int snd_imx_open(struct snd_pcm_substream *substream)
188{
189 struct snd_pcm_runtime *runtime = substream->runtime;
190 struct imx_pcm_runtime_data *iprtd;
191 int ret;
192
193 iprtd = kzalloc(sizeof(*iprtd), GFP_KERNEL);
194 runtime->private_data = iprtd;
195
196 init_timer(&iprtd->timer);
197 iprtd->timer.data = (unsigned long)substream;
198 iprtd->timer.function = imx_ssi_timer_callback;
199
200 ret = snd_pcm_hw_constraint_integer(substream->runtime,
201 SNDRV_PCM_HW_PARAM_PERIODS);
202 if (ret < 0)
203 return ret;
204
205 snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware);
206 return 0;
207}
208
209static int snd_imx_close(struct snd_pcm_substream *substream)
210{
211 struct snd_pcm_runtime *runtime = substream->runtime;
212 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
213
214 del_timer_sync(&iprtd->timer);
215 kfree(iprtd);
216
217 return 0;
218}
219
220static struct snd_pcm_ops imx_pcm_ops = {
221 .open = snd_imx_open,
222 .close = snd_imx_close,
223 .ioctl = snd_pcm_lib_ioctl,
224 .hw_params = snd_imx_pcm_hw_params,
225 .prepare = snd_imx_pcm_prepare,
226 .trigger = snd_imx_pcm_trigger,
227 .pointer = snd_imx_pcm_pointer,
228 .mmap = snd_imx_pcm_mmap,
229};
230
231static int imx_pcm_fiq_new(struct snd_card *card, struct snd_soc_dai *dai,
232 struct snd_pcm *pcm)
233{
234 int ret;
235
236 ret = imx_pcm_new(card, dai, pcm);
237 if (ret)
238 return ret;
239
240 if (dai->playback.channels_min) {
241 struct snd_pcm_substream *substream =
242 pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
243 struct snd_dma_buffer *buf = &substream->dma_buffer;
244
245 imx_ssi_fiq_tx_buffer = (unsigned long)buf->area;
246 }
247
248 if (dai->capture.channels_min) {
249 struct snd_pcm_substream *substream =
250 pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
251 struct snd_dma_buffer *buf = &substream->dma_buffer;
252
253 imx_ssi_fiq_rx_buffer = (unsigned long)buf->area;
254 }
255
256 set_fiq_handler(&imx_ssi_fiq_start,
257 &imx_ssi_fiq_end - &imx_ssi_fiq_start);
258
259 return 0;
260}
261
262static struct snd_soc_platform imx_soc_platform_fiq = {
263 .pcm_ops = &imx_pcm_ops,
264 .pcm_new = imx_pcm_fiq_new,
265 .pcm_free = imx_pcm_free,
266};
267
268struct snd_soc_platform *imx_ssi_fiq_init(struct platform_device *pdev,
269 struct imx_ssi *ssi)
270{
271 int ret = 0;
272
273 ret = claim_fiq(&fh);
274 if (ret) {
275 dev_err(&pdev->dev, "failed to claim fiq: %d", ret);
276 return ERR_PTR(ret);
277 }
278
279 mxc_set_irq_fiq(ssi->irq, 1);
280
281 imx_pcm_fiq = ssi->irq;
282
283 imx_ssi_fiq_base = (unsigned long)ssi->base;
284
285 ssi->dma_params_tx.burstsize = 4;
286 ssi->dma_params_rx.burstsize = 6;
287
288 return &imx_soc_platform_fiq;
289}
290
291void imx_ssi_fiq_exit(struct platform_device *pdev,
292 struct imx_ssi *ssi)
293{
294 mxc_set_irq_fiq(ssi->irq, 0);
295 release_fiq(&fh);
296}
297
diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c
new file mode 100644
index 000000000000..56f46a75d297
--- /dev/null
+++ b/sound/soc/imx/imx-ssi.c
@@ -0,0 +1,758 @@
1/*
2 * imx-ssi.c -- ALSA Soc Audio Layer
3 *
4 * Copyright 2009 Sascha Hauer <s.hauer@pengutronix.de>
5 *
6 * This code is based on code copyrighted by Freescale,
7 * Liam Girdwood, Javier Martin and probably others.
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 * The i.MX SSI core has some nasty limitations in AC97 mode. While most
16 * sane processor vendors have a FIFO per AC97 slot, the i.MX has only
17 * one FIFO which combines all valid receive slots. We cannot even select
18 * which slots we want to receive. The WM9712 with which this driver
19 * was developped with always sends GPIO status data in slot 12 which
20 * we receive in our (PCM-) data stream. The only chance we have is to
21 * manually skip this data in the FIQ handler. With sampling rates different
22 * from 48000Hz not every frame has valid receive data, so the ratio
23 * between pcm data and GPIO status data changes. Our FIQ handler is not
24 * able to handle this, hence this driver only works with 48000Hz sampling
25 * rate.
26 * Reading and writing AC97 registers is another challange. The core
27 * provides us status bits when the read register is updated with *another*
28 * value. When we read the same register two times (and the register still
29 * contains the same value) these status bits are not set. We work
30 * around this by not polling these bits but only wait a fixed delay.
31 *
32 */
33
34#include <linux/clk.h>
35#include <linux/delay.h>
36#include <linux/device.h>
37#include <linux/dma-mapping.h>
38#include <linux/init.h>
39#include <linux/interrupt.h>
40#include <linux/module.h>
41#include <linux/platform_device.h>
42
43#include <sound/core.h>
44#include <sound/initval.h>
45#include <sound/pcm.h>
46#include <sound/pcm_params.h>
47#include <sound/soc.h>
48
49#include <mach/ssi.h>
50#include <mach/hardware.h>
51
52#include "imx-ssi.h"
53
54#define SSI_SACNT_DEFAULT (SSI_SACNT_AC97EN | SSI_SACNT_FV)
55
56/*
57 * SSI Network Mode or TDM slots configuration.
58 * Should only be called when port is inactive (i.e. SSIEN = 0).
59 */
60static int imx_ssi_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai,
61 unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
62{
63 struct imx_ssi *ssi = cpu_dai->private_data;
64 u32 sccr;
65
66 sccr = readl(ssi->base + SSI_STCCR);
67 sccr &= ~SSI_STCCR_DC_MASK;
68 sccr |= SSI_STCCR_DC(slots - 1);
69 writel(sccr, ssi->base + SSI_STCCR);
70
71 sccr = readl(ssi->base + SSI_SRCCR);
72 sccr &= ~SSI_STCCR_DC_MASK;
73 sccr |= SSI_STCCR_DC(slots - 1);
74 writel(sccr, ssi->base + SSI_SRCCR);
75
76 writel(tx_mask, ssi->base + SSI_STMSK);
77 writel(rx_mask, ssi->base + SSI_SRMSK);
78
79 return 0;
80}
81
82/*
83 * SSI DAI format configuration.
84 * Should only be called when port is inactive (i.e. SSIEN = 0).
85 * Note: We don't use the I2S modes but instead manually configure the
86 * SSI for I2S because the I2S mode is only a register preset.
87 */
88static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
89{
90 struct imx_ssi *ssi = cpu_dai->private_data;
91 u32 strcr = 0, scr;
92
93 scr = readl(ssi->base + SSI_SCR) & ~(SSI_SCR_SYN | SSI_SCR_NET);
94
95 /* DAI mode */
96 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
97 case SND_SOC_DAIFMT_I2S:
98 /* data on rising edge of bclk, frame low 1clk before data */
99 strcr |= SSI_STCR_TFSI | SSI_STCR_TEFS | SSI_STCR_TXBIT0;
100 scr |= SSI_SCR_NET;
101 break;
102 case SND_SOC_DAIFMT_LEFT_J:
103 /* data on rising edge of bclk, frame high with data */
104 strcr |= SSI_STCR_TXBIT0;
105 break;
106 case SND_SOC_DAIFMT_DSP_B:
107 /* data on rising edge of bclk, frame high with data */
108 strcr |= SSI_STCR_TFSL;
109 break;
110 case SND_SOC_DAIFMT_DSP_A:
111 /* data on rising edge of bclk, frame high 1clk before data */
112 strcr |= SSI_STCR_TFSL | SSI_STCR_TEFS;
113 break;
114 }
115
116 /* DAI clock inversion */
117 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
118 case SND_SOC_DAIFMT_IB_IF:
119 strcr |= SSI_STCR_TFSI;
120 strcr &= ~SSI_STCR_TSCKP;
121 break;
122 case SND_SOC_DAIFMT_IB_NF:
123 strcr &= ~(SSI_STCR_TSCKP | SSI_STCR_TFSI);
124 break;
125 case SND_SOC_DAIFMT_NB_IF:
126 strcr |= SSI_STCR_TFSI | SSI_STCR_TSCKP;
127 break;
128 case SND_SOC_DAIFMT_NB_NF:
129 strcr &= ~SSI_STCR_TFSI;
130 strcr |= SSI_STCR_TSCKP;
131 break;
132 }
133
134 /* DAI clock master masks */
135 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
136 case SND_SOC_DAIFMT_CBM_CFM:
137 break;
138 default:
139 /* Master mode not implemented, needs handling of clocks. */
140 return -EINVAL;
141 }
142
143 strcr |= SSI_STCR_TFEN0;
144
145 writel(strcr, ssi->base + SSI_STCR);
146 writel(strcr, ssi->base + SSI_SRCR);
147 writel(scr, ssi->base + SSI_SCR);
148
149 return 0;
150}
151
152/*
153 * SSI system clock configuration.
154 * Should only be called when port is inactive (i.e. SSIEN = 0).
155 */
156static int imx_ssi_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
157 int clk_id, unsigned int freq, int dir)
158{
159 struct imx_ssi *ssi = cpu_dai->private_data;
160 u32 scr;
161
162 scr = readl(ssi->base + SSI_SCR);
163
164 switch (clk_id) {
165 case IMX_SSP_SYS_CLK:
166 if (dir == SND_SOC_CLOCK_OUT)
167 scr |= SSI_SCR_SYS_CLK_EN;
168 else
169 scr &= ~SSI_SCR_SYS_CLK_EN;
170 break;
171 default:
172 return -EINVAL;
173 }
174
175 writel(scr, ssi->base + SSI_SCR);
176
177 return 0;
178}
179
180/*
181 * SSI Clock dividers
182 * Should only be called when port is inactive (i.e. SSIEN = 0).
183 */
184static int imx_ssi_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
185 int div_id, int div)
186{
187 struct imx_ssi *ssi = cpu_dai->private_data;
188 u32 stccr, srccr;
189
190 stccr = readl(ssi->base + SSI_STCCR);
191 srccr = readl(ssi->base + SSI_SRCCR);
192
193 switch (div_id) {
194 case IMX_SSI_TX_DIV_2:
195 stccr &= ~SSI_STCCR_DIV2;
196 stccr |= div;
197 break;
198 case IMX_SSI_TX_DIV_PSR:
199 stccr &= ~SSI_STCCR_PSR;
200 stccr |= div;
201 break;
202 case IMX_SSI_TX_DIV_PM:
203 stccr &= ~0xff;
204 stccr |= SSI_STCCR_PM(div);
205 break;
206 case IMX_SSI_RX_DIV_2:
207 stccr &= ~SSI_STCCR_DIV2;
208 stccr |= div;
209 break;
210 case IMX_SSI_RX_DIV_PSR:
211 stccr &= ~SSI_STCCR_PSR;
212 stccr |= div;
213 break;
214 case IMX_SSI_RX_DIV_PM:
215 stccr &= ~0xff;
216 stccr |= SSI_STCCR_PM(div);
217 break;
218 default:
219 return -EINVAL;
220 }
221
222 writel(stccr, ssi->base + SSI_STCCR);
223 writel(srccr, ssi->base + SSI_SRCCR);
224
225 return 0;
226}
227
228/*
229 * Should only be called when port is inactive (i.e. SSIEN = 0),
230 * although can be called multiple times by upper layers.
231 */
232static int imx_ssi_hw_params(struct snd_pcm_substream *substream,
233 struct snd_pcm_hw_params *params,
234 struct snd_soc_dai *cpu_dai)
235{
236 struct imx_ssi *ssi = cpu_dai->private_data;
237 u32 reg, sccr;
238
239 /* Tx/Rx config */
240 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
241 reg = SSI_STCCR;
242 cpu_dai->dma_data = &ssi->dma_params_tx;
243 } else {
244 reg = SSI_SRCCR;
245 cpu_dai->dma_data = &ssi->dma_params_rx;
246 }
247
248 sccr = readl(ssi->base + reg) & ~SSI_STCCR_WL_MASK;
249
250 /* DAI data (word) size */
251 switch (params_format(params)) {
252 case SNDRV_PCM_FORMAT_S16_LE:
253 sccr |= SSI_SRCCR_WL(16);
254 break;
255 case SNDRV_PCM_FORMAT_S20_3LE:
256 sccr |= SSI_SRCCR_WL(20);
257 break;
258 case SNDRV_PCM_FORMAT_S24_LE:
259 sccr |= SSI_SRCCR_WL(24);
260 break;
261 }
262
263 writel(sccr, ssi->base + reg);
264
265 return 0;
266}
267
268static int imx_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
269 struct snd_soc_dai *dai)
270{
271 struct snd_soc_pcm_runtime *rtd = substream->private_data;
272 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
273 struct imx_ssi *ssi = cpu_dai->private_data;
274 unsigned int sier_bits, sier;
275 unsigned int scr;
276
277 scr = readl(ssi->base + SSI_SCR);
278 sier = readl(ssi->base + SSI_SIER);
279
280 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
281 if (ssi->flags & IMX_SSI_DMA)
282 sier_bits = SSI_SIER_TDMAE;
283 else
284 sier_bits = SSI_SIER_TIE | SSI_SIER_TFE0_EN;
285 } else {
286 if (ssi->flags & IMX_SSI_DMA)
287 sier_bits = SSI_SIER_RDMAE;
288 else
289 sier_bits = SSI_SIER_RIE | SSI_SIER_RFF0_EN;
290 }
291
292 switch (cmd) {
293 case SNDRV_PCM_TRIGGER_START:
294 case SNDRV_PCM_TRIGGER_RESUME:
295 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
296 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
297 scr |= SSI_SCR_TE;
298 else
299 scr |= SSI_SCR_RE;
300 sier |= sier_bits;
301
302 if (++ssi->enabled == 1)
303 scr |= SSI_SCR_SSIEN;
304
305 break;
306
307 case SNDRV_PCM_TRIGGER_STOP:
308 case SNDRV_PCM_TRIGGER_SUSPEND:
309 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
310 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
311 scr &= ~SSI_SCR_TE;
312 else
313 scr &= ~SSI_SCR_RE;
314 sier &= ~sier_bits;
315
316 if (--ssi->enabled == 0)
317 scr &= ~SSI_SCR_SSIEN;
318
319 break;
320 default:
321 return -EINVAL;
322 }
323
324 if (!(ssi->flags & IMX_SSI_USE_AC97))
325 /* rx/tx are always enabled to access ac97 registers */
326 writel(scr, ssi->base + SSI_SCR);
327
328 writel(sier, ssi->base + SSI_SIER);
329
330 return 0;
331}
332
333static struct snd_soc_dai_ops imx_ssi_pcm_dai_ops = {
334 .hw_params = imx_ssi_hw_params,
335 .set_fmt = imx_ssi_set_dai_fmt,
336 .set_clkdiv = imx_ssi_set_dai_clkdiv,
337 .set_sysclk = imx_ssi_set_dai_sysclk,
338 .set_tdm_slot = imx_ssi_set_dai_tdm_slot,
339 .trigger = imx_ssi_trigger,
340};
341
342static struct snd_soc_dai imx_ssi_dai = {
343 .playback = {
344 .channels_min = 2,
345 .channels_max = 2,
346 .rates = SNDRV_PCM_RATE_8000_96000,
347 .formats = SNDRV_PCM_FMTBIT_S16_LE,
348 },
349 .capture = {
350 .channels_min = 2,
351 .channels_max = 2,
352 .rates = SNDRV_PCM_RATE_8000_96000,
353 .formats = SNDRV_PCM_FMTBIT_S16_LE,
354 },
355 .ops = &imx_ssi_pcm_dai_ops,
356};
357
358int snd_imx_pcm_mmap(struct snd_pcm_substream *substream,
359 struct vm_area_struct *vma)
360{
361 struct snd_pcm_runtime *runtime = substream->runtime;
362 int ret;
363
364 ret = dma_mmap_coherent(NULL, vma, runtime->dma_area,
365 runtime->dma_addr, runtime->dma_bytes);
366
367 pr_debug("%s: ret: %d %p 0x%08x 0x%08x\n", __func__, ret,
368 runtime->dma_area,
369 runtime->dma_addr,
370 runtime->dma_bytes);
371 return ret;
372}
373
374static int imx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
375{
376 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
377 struct snd_dma_buffer *buf = &substream->dma_buffer;
378 size_t size = IMX_SSI_DMABUF_SIZE;
379
380 buf->dev.type = SNDRV_DMA_TYPE_DEV;
381 buf->dev.dev = pcm->card->dev;
382 buf->private_data = NULL;
383 buf->area = dma_alloc_writecombine(pcm->card->dev, size,
384 &buf->addr, GFP_KERNEL);
385 if (!buf->area)
386 return -ENOMEM;
387 buf->bytes = size;
388
389 return 0;
390}
391
392static u64 imx_pcm_dmamask = DMA_BIT_MASK(32);
393
394int imx_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
395 struct snd_pcm *pcm)
396{
397
398 int ret = 0;
399
400 if (!card->dev->dma_mask)
401 card->dev->dma_mask = &imx_pcm_dmamask;
402 if (!card->dev->coherent_dma_mask)
403 card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
404 if (dai->playback.channels_min) {
405 ret = imx_pcm_preallocate_dma_buffer(pcm,
406 SNDRV_PCM_STREAM_PLAYBACK);
407 if (ret)
408 goto out;
409 }
410
411 if (dai->capture.channels_min) {
412 ret = imx_pcm_preallocate_dma_buffer(pcm,
413 SNDRV_PCM_STREAM_CAPTURE);
414 if (ret)
415 goto out;
416 }
417
418out:
419 return ret;
420}
421
422void imx_pcm_free(struct snd_pcm *pcm)
423{
424 struct snd_pcm_substream *substream;
425 struct snd_dma_buffer *buf;
426 int stream;
427
428 for (stream = 0; stream < 2; stream++) {
429 substream = pcm->streams[stream].substream;
430 if (!substream)
431 continue;
432
433 buf = &substream->dma_buffer;
434 if (!buf->area)
435 continue;
436
437 dma_free_writecombine(pcm->card->dev, buf->bytes,
438 buf->area, buf->addr);
439 buf->area = NULL;
440 }
441}
442
443struct snd_soc_platform imx_soc_platform = {
444 .name = "imx-audio",
445};
446EXPORT_SYMBOL_GPL(imx_soc_platform);
447
448static struct snd_soc_dai imx_ac97_dai = {
449 .name = "AC97",
450 .ac97_control = 1,
451 .playback = {
452 .stream_name = "AC97 Playback",
453 .channels_min = 2,
454 .channels_max = 2,
455 .rates = SNDRV_PCM_RATE_48000,
456 .formats = SNDRV_PCM_FMTBIT_S16_LE,
457 },
458 .capture = {
459 .stream_name = "AC97 Capture",
460 .channels_min = 2,
461 .channels_max = 2,
462 .rates = SNDRV_PCM_RATE_48000,
463 .formats = SNDRV_PCM_FMTBIT_S16_LE,
464 },
465 .ops = &imx_ssi_pcm_dai_ops,
466};
467
468static void setup_channel_to_ac97(struct imx_ssi *imx_ssi)
469{
470 void __iomem *base = imx_ssi->base;
471
472 writel(0x0, base + SSI_SCR);
473 writel(0x0, base + SSI_STCR);
474 writel(0x0, base + SSI_SRCR);
475
476 writel(SSI_SCR_SYN | SSI_SCR_NET, base + SSI_SCR);
477
478 writel(SSI_SFCSR_RFWM0(8) |
479 SSI_SFCSR_TFWM0(8) |
480 SSI_SFCSR_RFWM1(8) |
481 SSI_SFCSR_TFWM1(8), base + SSI_SFCSR);
482
483 writel(SSI_STCCR_WL(16) | SSI_STCCR_DC(12), base + SSI_STCCR);
484 writel(SSI_STCCR_WL(16) | SSI_STCCR_DC(12), base + SSI_SRCCR);
485
486 writel(SSI_SCR_SYN | SSI_SCR_NET | SSI_SCR_SSIEN, base + SSI_SCR);
487 writel(SSI_SOR_WAIT(3), base + SSI_SOR);
488
489 writel(SSI_SCR_SYN | SSI_SCR_NET | SSI_SCR_SSIEN |
490 SSI_SCR_TE | SSI_SCR_RE,
491 base + SSI_SCR);
492
493 writel(SSI_SACNT_DEFAULT, base + SSI_SACNT);
494 writel(0xff, base + SSI_SACCDIS);
495 writel(0x300, base + SSI_SACCEN);
496}
497
498static struct imx_ssi *ac97_ssi;
499
500static void imx_ssi_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
501 unsigned short val)
502{
503 struct imx_ssi *imx_ssi = ac97_ssi;
504 void __iomem *base = imx_ssi->base;
505 unsigned int lreg;
506 unsigned int lval;
507
508 if (reg > 0x7f)
509 return;
510
511 pr_debug("%s: 0x%02x 0x%04x\n", __func__, reg, val);
512
513 lreg = reg << 12;
514 writel(lreg, base + SSI_SACADD);
515
516 lval = val << 4;
517 writel(lval , base + SSI_SACDAT);
518
519 writel(SSI_SACNT_DEFAULT | SSI_SACNT_WR, base + SSI_SACNT);
520 udelay(100);
521}
522
523static unsigned short imx_ssi_ac97_read(struct snd_ac97 *ac97,
524 unsigned short reg)
525{
526 struct imx_ssi *imx_ssi = ac97_ssi;
527 void __iomem *base = imx_ssi->base;
528
529 unsigned short val = -1;
530 unsigned int lreg;
531
532 lreg = (reg & 0x7f) << 12 ;
533 writel(lreg, base + SSI_SACADD);
534 writel(SSI_SACNT_DEFAULT | SSI_SACNT_RD, base + SSI_SACNT);
535
536 udelay(100);
537
538 val = (readl(base + SSI_SACDAT) >> 4) & 0xffff;
539
540 pr_debug("%s: 0x%02x 0x%04x\n", __func__, reg, val);
541
542 return val;
543}
544
545static void imx_ssi_ac97_reset(struct snd_ac97 *ac97)
546{
547 struct imx_ssi *imx_ssi = ac97_ssi;
548
549 if (imx_ssi->ac97_reset)
550 imx_ssi->ac97_reset(ac97);
551}
552
553static void imx_ssi_ac97_warm_reset(struct snd_ac97 *ac97)
554{
555 struct imx_ssi *imx_ssi = ac97_ssi;
556
557 if (imx_ssi->ac97_warm_reset)
558 imx_ssi->ac97_warm_reset(ac97);
559}
560
561struct snd_ac97_bus_ops soc_ac97_ops = {
562 .read = imx_ssi_ac97_read,
563 .write = imx_ssi_ac97_write,
564 .reset = imx_ssi_ac97_reset,
565 .warm_reset = imx_ssi_ac97_warm_reset
566};
567EXPORT_SYMBOL_GPL(soc_ac97_ops);
568
569struct snd_soc_dai imx_ssi_pcm_dai[2];
570EXPORT_SYMBOL_GPL(imx_ssi_pcm_dai);
571
572static int imx_ssi_probe(struct platform_device *pdev)
573{
574 struct resource *res;
575 struct imx_ssi *ssi;
576 struct imx_ssi_platform_data *pdata = pdev->dev.platform_data;
577 struct snd_soc_platform *platform;
578 int ret = 0;
579 unsigned int val;
580 struct snd_soc_dai *dai = &imx_ssi_pcm_dai[pdev->id];
581
582 if (dai->id >= ARRAY_SIZE(imx_ssi_pcm_dai))
583 return -EINVAL;
584
585 ssi = kzalloc(sizeof(*ssi), GFP_KERNEL);
586 if (!ssi)
587 return -ENOMEM;
588
589 if (pdata) {
590 ssi->ac97_reset = pdata->ac97_reset;
591 ssi->ac97_warm_reset = pdata->ac97_warm_reset;
592 ssi->flags = pdata->flags;
593 }
594
595 ssi->irq = platform_get_irq(pdev, 0);
596
597 ssi->clk = clk_get(&pdev->dev, NULL);
598 if (IS_ERR(ssi->clk)) {
599 ret = PTR_ERR(ssi->clk);
600 dev_err(&pdev->dev, "Cannot get the clock: %d\n",
601 ret);
602 goto failed_clk;
603 }
604 clk_enable(ssi->clk);
605
606 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
607 if (!res) {
608 ret = -ENODEV;
609 goto failed_get_resource;
610 }
611
612 if (!request_mem_region(res->start, resource_size(res), DRV_NAME)) {
613 dev_err(&pdev->dev, "request_mem_region failed\n");
614 ret = -EBUSY;
615 goto failed_get_resource;
616 }
617
618 ssi->base = ioremap(res->start, resource_size(res));
619 if (!ssi->base) {
620 dev_err(&pdev->dev, "ioremap failed\n");
621 ret = -ENODEV;
622 goto failed_ioremap;
623 }
624
625 if (ssi->flags & IMX_SSI_USE_AC97) {
626 if (ac97_ssi) {
627 ret = -EBUSY;
628 goto failed_ac97;
629 }
630 ac97_ssi = ssi;
631 setup_channel_to_ac97(ssi);
632 memcpy(dai, &imx_ac97_dai, sizeof(imx_ac97_dai));
633 } else
634 memcpy(dai, &imx_ssi_dai, sizeof(imx_ssi_dai));
635
636 writel(0x0, ssi->base + SSI_SIER);
637
638 ssi->dma_params_rx.dma_addr = res->start + SSI_SRX0;
639 ssi->dma_params_tx.dma_addr = res->start + SSI_STX0;
640
641 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx0");
642 if (res)
643 ssi->dma_params_tx.dma = res->start;
644
645 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx0");
646 if (res)
647 ssi->dma_params_rx.dma = res->start;
648
649 dai->id = pdev->id;
650 dai->dev = &pdev->dev;
651 dai->name = kasprintf(GFP_KERNEL, "imx-ssi.%d", pdev->id);
652 dai->private_data = ssi;
653
654 if ((cpu_is_mx27() || cpu_is_mx21()) &&
655 !(ssi->flags & IMX_SSI_USE_AC97)) {
656 ssi->flags |= IMX_SSI_DMA;
657 platform = imx_ssi_dma_mx2_init(pdev, ssi);
658 } else
659 platform = imx_ssi_fiq_init(pdev, ssi);
660
661 imx_soc_platform.pcm_ops = platform->pcm_ops;
662 imx_soc_platform.pcm_new = platform->pcm_new;
663 imx_soc_platform.pcm_free = platform->pcm_free;
664
665 val = SSI_SFCSR_TFWM0(ssi->dma_params_tx.burstsize) |
666 SSI_SFCSR_RFWM0(ssi->dma_params_rx.burstsize);
667 writel(val, ssi->base + SSI_SFCSR);
668
669 ret = snd_soc_register_dai(dai);
670 if (ret) {
671 dev_err(&pdev->dev, "register DAI failed\n");
672 goto failed_register;
673 }
674
675 platform_set_drvdata(pdev, ssi);
676
677 return 0;
678
679failed_register:
680failed_ac97:
681 iounmap(ssi->base);
682failed_ioremap:
683 release_mem_region(res->start, resource_size(res));
684failed_get_resource:
685 clk_disable(ssi->clk);
686 clk_put(ssi->clk);
687failed_clk:
688 kfree(ssi);
689
690 return ret;
691}
692
693static int __devexit imx_ssi_remove(struct platform_device *pdev)
694{
695 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
696 struct imx_ssi *ssi = platform_get_drvdata(pdev);
697 struct snd_soc_dai *dai = &imx_ssi_pcm_dai[pdev->id];
698
699 snd_soc_unregister_dai(dai);
700
701 if (ssi->flags & IMX_SSI_USE_AC97)
702 ac97_ssi = NULL;
703
704 if (!(ssi->flags & IMX_SSI_DMA))
705 imx_ssi_fiq_exit(pdev, ssi);
706
707 iounmap(ssi->base);
708 release_mem_region(res->start, resource_size(res));
709 clk_disable(ssi->clk);
710 clk_put(ssi->clk);
711 kfree(ssi);
712
713 return 0;
714}
715
716static struct platform_driver imx_ssi_driver = {
717 .probe = imx_ssi_probe,
718 .remove = __devexit_p(imx_ssi_remove),
719
720 .driver = {
721 .name = DRV_NAME,
722 .owner = THIS_MODULE,
723 },
724};
725
726static int __init imx_ssi_init(void)
727{
728 int ret;
729
730 ret = snd_soc_register_platform(&imx_soc_platform);
731 if (ret) {
732 pr_err("failed to register soc platform: %d\n", ret);
733 return ret;
734 }
735
736 ret = platform_driver_register(&imx_ssi_driver);
737 if (ret) {
738 snd_soc_unregister_platform(&imx_soc_platform);
739 return ret;
740 }
741
742 return 0;
743}
744
745static void __exit imx_ssi_exit(void)
746{
747 platform_driver_unregister(&imx_ssi_driver);
748 snd_soc_unregister_platform(&imx_soc_platform);
749}
750
751module_init(imx_ssi_init);
752module_exit(imx_ssi_exit);
753
754/* Module information */
755MODULE_AUTHOR("Sascha Hauer, <s.hauer@pengutronix.de>");
756MODULE_DESCRIPTION("i.MX I2S/ac97 SoC Interface");
757MODULE_LICENSE("GPL");
758
diff --git a/sound/soc/imx/imx-ssi.h b/sound/soc/imx/imx-ssi.h
new file mode 100644
index 000000000000..55f26ebcd8c2
--- /dev/null
+++ b/sound/soc/imx/imx-ssi.h
@@ -0,0 +1,237 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License version 2 as
4 * published by the Free Software Foundation.
5 */
6
7#ifndef _IMX_SSI_H
8#define _IMX_SSI_H
9
10#define SSI_STX0 0x00
11#define SSI_STX1 0x04
12#define SSI_SRX0 0x08
13#define SSI_SRX1 0x0c
14
15#define SSI_SCR 0x10
16#define SSI_SCR_CLK_IST (1 << 9)
17#define SSI_SCR_CLK_IST_SHIFT 9
18#define SSI_SCR_TCH_EN (1 << 8)
19#define SSI_SCR_SYS_CLK_EN (1 << 7)
20#define SSI_SCR_I2S_MODE_NORM (0 << 5)
21#define SSI_SCR_I2S_MODE_MSTR (1 << 5)
22#define SSI_SCR_I2S_MODE_SLAVE (2 << 5)
23#define SSI_I2S_MODE_MASK (3 << 5)
24#define SSI_SCR_SYN (1 << 4)
25#define SSI_SCR_NET (1 << 3)
26#define SSI_SCR_RE (1 << 2)
27#define SSI_SCR_TE (1 << 1)
28#define SSI_SCR_SSIEN (1 << 0)
29
30#define SSI_SISR 0x14
31#define SSI_SISR_MASK ((1 << 19) - 1)
32#define SSI_SISR_CMDAU (1 << 18)
33#define SSI_SISR_CMDDU (1 << 17)
34#define SSI_SISR_RXT (1 << 16)
35#define SSI_SISR_RDR1 (1 << 15)
36#define SSI_SISR_RDR0 (1 << 14)
37#define SSI_SISR_TDE1 (1 << 13)
38#define SSI_SISR_TDE0 (1 << 12)
39#define SSI_SISR_ROE1 (1 << 11)
40#define SSI_SISR_ROE0 (1 << 10)
41#define SSI_SISR_TUE1 (1 << 9)
42#define SSI_SISR_TUE0 (1 << 8)
43#define SSI_SISR_TFS (1 << 7)
44#define SSI_SISR_RFS (1 << 6)
45#define SSI_SISR_TLS (1 << 5)
46#define SSI_SISR_RLS (1 << 4)
47#define SSI_SISR_RFF1 (1 << 3)
48#define SSI_SISR_RFF0 (1 << 2)
49#define SSI_SISR_TFE1 (1 << 1)
50#define SSI_SISR_TFE0 (1 << 0)
51
52#define SSI_SIER 0x18
53#define SSI_SIER_RDMAE (1 << 22)
54#define SSI_SIER_RIE (1 << 21)
55#define SSI_SIER_TDMAE (1 << 20)
56#define SSI_SIER_TIE (1 << 19)
57#define SSI_SIER_CMDAU_EN (1 << 18)
58#define SSI_SIER_CMDDU_EN (1 << 17)
59#define SSI_SIER_RXT_EN (1 << 16)
60#define SSI_SIER_RDR1_EN (1 << 15)
61#define SSI_SIER_RDR0_EN (1 << 14)
62#define SSI_SIER_TDE1_EN (1 << 13)
63#define SSI_SIER_TDE0_EN (1 << 12)
64#define SSI_SIER_ROE1_EN (1 << 11)
65#define SSI_SIER_ROE0_EN (1 << 10)
66#define SSI_SIER_TUE1_EN (1 << 9)
67#define SSI_SIER_TUE0_EN (1 << 8)
68#define SSI_SIER_TFS_EN (1 << 7)
69#define SSI_SIER_RFS_EN (1 << 6)
70#define SSI_SIER_TLS_EN (1 << 5)
71#define SSI_SIER_RLS_EN (1 << 4)
72#define SSI_SIER_RFF1_EN (1 << 3)
73#define SSI_SIER_RFF0_EN (1 << 2)
74#define SSI_SIER_TFE1_EN (1 << 1)
75#define SSI_SIER_TFE0_EN (1 << 0)
76
77#define SSI_STCR 0x1c
78#define SSI_STCR_TXBIT0 (1 << 9)
79#define SSI_STCR_TFEN1 (1 << 8)
80#define SSI_STCR_TFEN0 (1 << 7)
81#define SSI_FIFO_ENABLE_0_SHIFT 7
82#define SSI_STCR_TFDIR (1 << 6)
83#define SSI_STCR_TXDIR (1 << 5)
84#define SSI_STCR_TSHFD (1 << 4)
85#define SSI_STCR_TSCKP (1 << 3)
86#define SSI_STCR_TFSI (1 << 2)
87#define SSI_STCR_TFSL (1 << 1)
88#define SSI_STCR_TEFS (1 << 0)
89
90#define SSI_SRCR 0x20
91#define SSI_SRCR_RXBIT0 (1 << 9)
92#define SSI_SRCR_RFEN1 (1 << 8)
93#define SSI_SRCR_RFEN0 (1 << 7)
94#define SSI_FIFO_ENABLE_0_SHIFT 7
95#define SSI_SRCR_RFDIR (1 << 6)
96#define SSI_SRCR_RXDIR (1 << 5)
97#define SSI_SRCR_RSHFD (1 << 4)
98#define SSI_SRCR_RSCKP (1 << 3)
99#define SSI_SRCR_RFSI (1 << 2)
100#define SSI_SRCR_RFSL (1 << 1)
101#define SSI_SRCR_REFS (1 << 0)
102
103#define SSI_SRCCR 0x28
104#define SSI_SRCCR_DIV2 (1 << 18)
105#define SSI_SRCCR_PSR (1 << 17)
106#define SSI_SRCCR_WL(x) ((((x) - 2) >> 1) << 13)
107#define SSI_SRCCR_DC(x) (((x) & 0x1f) << 8)
108#define SSI_SRCCR_PM(x) (((x) & 0xff) << 0)
109#define SSI_SRCCR_WL_MASK (0xf << 13)
110#define SSI_SRCCR_DC_MASK (0x1f << 8)
111#define SSI_SRCCR_PM_MASK (0xff << 0)
112
113#define SSI_STCCR 0x24
114#define SSI_STCCR_DIV2 (1 << 18)
115#define SSI_STCCR_PSR (1 << 17)
116#define SSI_STCCR_WL(x) ((((x) - 2) >> 1) << 13)
117#define SSI_STCCR_DC(x) (((x) & 0x1f) << 8)
118#define SSI_STCCR_PM(x) (((x) & 0xff) << 0)
119#define SSI_STCCR_WL_MASK (0xf << 13)
120#define SSI_STCCR_DC_MASK (0x1f << 8)
121#define SSI_STCCR_PM_MASK (0xff << 0)
122
123#define SSI_SFCSR 0x2c
124#define SSI_SFCSR_RFCNT1(x) (((x) & 0xf) << 28)
125#define SSI_RX_FIFO_1_COUNT_SHIFT 28
126#define SSI_SFCSR_TFCNT1(x) (((x) & 0xf) << 24)
127#define SSI_TX_FIFO_1_COUNT_SHIFT 24
128#define SSI_SFCSR_RFWM1(x) (((x) & 0xf) << 20)
129#define SSI_SFCSR_TFWM1(x) (((x) & 0xf) << 16)
130#define SSI_SFCSR_RFCNT0(x) (((x) & 0xf) << 12)
131#define SSI_RX_FIFO_0_COUNT_SHIFT 12
132#define SSI_SFCSR_TFCNT0(x) (((x) & 0xf) << 8)
133#define SSI_TX_FIFO_0_COUNT_SHIFT 8
134#define SSI_SFCSR_RFWM0(x) (((x) & 0xf) << 4)
135#define SSI_SFCSR_TFWM0(x) (((x) & 0xf) << 0)
136#define SSI_SFCSR_RFWM0_MASK (0xf << 4)
137#define SSI_SFCSR_TFWM0_MASK (0xf << 0)
138
139#define SSI_STR 0x30
140#define SSI_STR_TEST (1 << 15)
141#define SSI_STR_RCK2TCK (1 << 14)
142#define SSI_STR_RFS2TFS (1 << 13)
143#define SSI_STR_RXSTATE(x) (((x) & 0xf) << 8)
144#define SSI_STR_TXD2RXD (1 << 7)
145#define SSI_STR_TCK2RCK (1 << 6)
146#define SSI_STR_TFS2RFS (1 << 5)
147#define SSI_STR_TXSTATE(x) (((x) & 0xf) << 0)
148
149#define SSI_SOR 0x34
150#define SSI_SOR_CLKOFF (1 << 6)
151#define SSI_SOR_RX_CLR (1 << 5)
152#define SSI_SOR_TX_CLR (1 << 4)
153#define SSI_SOR_INIT (1 << 3)
154#define SSI_SOR_WAIT(x) (((x) & 0x3) << 1)
155#define SSI_SOR_WAIT_MASK (0x3 << 1)
156#define SSI_SOR_SYNRST (1 << 0)
157
158#define SSI_SACNT 0x38
159#define SSI_SACNT_FRDIV(x) (((x) & 0x3f) << 5)
160#define SSI_SACNT_WR (1 << 4)
161#define SSI_SACNT_RD (1 << 3)
162#define SSI_SACNT_TIF (1 << 2)
163#define SSI_SACNT_FV (1 << 1)
164#define SSI_SACNT_AC97EN (1 << 0)
165
166#define SSI_SACADD 0x3c
167#define SSI_SACDAT 0x40
168#define SSI_SATAG 0x44
169#define SSI_STMSK 0x48
170#define SSI_SRMSK 0x4c
171#define SSI_SACCST 0x50
172#define SSI_SACCEN 0x54
173#define SSI_SACCDIS 0x58
174
175/* SSI clock sources */
176#define IMX_SSP_SYS_CLK 0
177
178/* SSI audio dividers */
179#define IMX_SSI_TX_DIV_2 0
180#define IMX_SSI_TX_DIV_PSR 1
181#define IMX_SSI_TX_DIV_PM 2
182#define IMX_SSI_RX_DIV_2 3
183#define IMX_SSI_RX_DIV_PSR 4
184#define IMX_SSI_RX_DIV_PM 5
185
186extern struct snd_soc_dai imx_ssi_pcm_dai[2];
187extern struct snd_soc_platform imx_soc_platform;
188
189#define DRV_NAME "imx-ssi"
190
191struct imx_pcm_dma_params {
192 int dma;
193 unsigned long dma_addr;
194 int burstsize;
195};
196
197struct imx_ssi {
198 struct platform_device *ac97_dev;
199
200 struct snd_soc_device imx_ac97;
201 struct clk *clk;
202 void __iomem *base;
203 int irq;
204 int fiq_enable;
205 unsigned int offset;
206
207 unsigned int flags;
208
209 void (*ac97_reset) (struct snd_ac97 *ac97);
210 void (*ac97_warm_reset)(struct snd_ac97 *ac97);
211
212 struct imx_pcm_dma_params dma_params_rx;
213 struct imx_pcm_dma_params dma_params_tx;
214
215 int enabled;
216};
217
218struct snd_soc_platform *imx_ssi_fiq_init(struct platform_device *pdev,
219 struct imx_ssi *ssi);
220void imx_ssi_fiq_exit(struct platform_device *pdev, struct imx_ssi *ssi);
221struct snd_soc_platform *imx_ssi_dma_mx2_init(struct platform_device *pdev,
222 struct imx_ssi *ssi);
223
224int snd_imx_pcm_mmap(struct snd_pcm_substream *substream, struct vm_area_struct *vma);
225int imx_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
226 struct snd_pcm *pcm);
227void imx_pcm_free(struct snd_pcm *pcm);
228
229/*
230 * Do not change this as the FIQ handler depends on this size
231 */
232#define IMX_SSI_DMABUF_SIZE (64 * 1024)
233
234#define DMA_RXFIFO_BURST 0x4
235#define DMA_TXFIFO_BURST 0x6
236
237#endif /* _IMX_SSI_H */
diff --git a/sound/soc/imx/mx1_mx2-pcm.c b/sound/soc/imx/mx1_mx2-pcm.c
deleted file mode 100644
index bffffcd5ff34..000000000000
--- a/sound/soc/imx/mx1_mx2-pcm.c
+++ /dev/null
@@ -1,488 +0,0 @@
1/*
2 * mx1_mx2-pcm.c -- ALSA SoC interface for Freescale i.MX1x, i.MX2x CPUs
3 *
4 * Copyright 2009 Vista Silicon S.L.
5 * Author: Javier Martin
6 * javier.martin@vista-silicon.com
7 *
8 * Based on mxc-pcm.c by Liam Girdwood.
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 */
16
17#include <linux/module.h>
18#include <linux/init.h>
19#include <linux/platform_device.h>
20#include <linux/slab.h>
21#include <linux/dma-mapping.h>
22#include <sound/core.h>
23#include <sound/pcm.h>
24#include <sound/pcm_params.h>
25#include <sound/soc.h>
26#include <asm/dma.h>
27#include <mach/hardware.h>
28#include <mach/dma-mx1-mx2.h>
29
30#include "mx1_mx2-pcm.h"
31
32
33static const struct snd_pcm_hardware mx1_mx2_pcm_hardware = {
34 .info = (SNDRV_PCM_INFO_INTERLEAVED |
35 SNDRV_PCM_INFO_BLOCK_TRANSFER |
36 SNDRV_PCM_INFO_MMAP |
37 SNDRV_PCM_INFO_MMAP_VALID),
38 .formats = SNDRV_PCM_FMTBIT_S16_LE,
39 .buffer_bytes_max = 32 * 1024,
40 .period_bytes_min = 64,
41 .period_bytes_max = 8 * 1024,
42 .periods_min = 2,
43 .periods_max = 255,
44 .fifo_size = 0,
45};
46
47struct mx1_mx2_runtime_data {
48 int dma_ch;
49 int active;
50 unsigned int period;
51 unsigned int periods;
52 int tx_spin;
53 spinlock_t dma_lock;
54 struct mx1_mx2_pcm_dma_params *dma_params;
55};
56
57
58/**
59 * This function stops the current dma transfer for playback
60 * and clears the dma pointers.
61 *
62 * @param substream pointer to the structure of the current stream.
63 *
64 */
65static int audio_stop_dma(struct snd_pcm_substream *substream)
66{
67 struct snd_pcm_runtime *runtime = substream->runtime;
68 struct mx1_mx2_runtime_data *prtd = runtime->private_data;
69 unsigned long flags;
70
71 spin_lock_irqsave(&prtd->dma_lock, flags);
72
73 pr_debug("%s\n", __func__);
74
75 prtd->active = 0;
76 prtd->period = 0;
77 prtd->periods = 0;
78
79 /* this stops the dma channel and clears the buffer ptrs */
80
81 imx_dma_disable(prtd->dma_ch);
82
83 spin_unlock_irqrestore(&prtd->dma_lock, flags);
84
85 return 0;
86}
87
88/**
89 * This function is called whenever a new audio block needs to be
90 * transferred to the codec. The function receives the address and the size
91 * of the new block and start a new DMA transfer.
92 *
93 * @param substream pointer to the structure of the current stream.
94 *
95 */
96static int dma_new_period(struct snd_pcm_substream *substream)
97{
98 struct snd_pcm_runtime *runtime = substream->runtime;
99 struct mx1_mx2_runtime_data *prtd = runtime->private_data;
100 unsigned int dma_size;
101 unsigned int offset;
102 int ret = 0;
103 dma_addr_t mem_addr;
104 unsigned int dev_addr;
105
106 if (prtd->active) {
107 dma_size = frames_to_bytes(runtime, runtime->period_size);
108 offset = dma_size * prtd->period;
109
110 pr_debug("%s: period (%d) out of (%d)\n", __func__,
111 prtd->period,
112 runtime->periods);
113 pr_debug("period_size %d frames\n offset %d bytes\n",
114 (unsigned int)runtime->period_size,
115 offset);
116 pr_debug("dma_size %d bytes\n", dma_size);
117
118 snd_BUG_ON(dma_size > mx1_mx2_pcm_hardware.period_bytes_max);
119
120 mem_addr = (dma_addr_t)(runtime->dma_addr + offset);
121 dev_addr = prtd->dma_params->per_address;
122 pr_debug("%s: mem_addr is %x\n dev_addr is %x\n",
123 __func__, mem_addr, dev_addr);
124
125 ret = imx_dma_setup_single(prtd->dma_ch, mem_addr,
126 dma_size, dev_addr,
127 prtd->dma_params->transfer_type);
128 if (ret < 0) {
129 printk(KERN_ERR "Error %d configuring DMA\n", ret);
130 return ret;
131 }
132 imx_dma_enable(prtd->dma_ch);
133
134 pr_debug("%s: transfer enabled\nmem_addr = %x\n",
135 __func__, (unsigned int) mem_addr);
136 pr_debug("dev_addr = %x\ndma_size = %d\n",
137 (unsigned int) dev_addr, dma_size);
138
139 prtd->tx_spin = 1; /* FGA little trick to retrieve DMA pos */
140 prtd->period++;
141 prtd->period %= runtime->periods;
142 }
143 return ret;
144}
145
146
147/**
148 * This is a callback which will be called
149 * when a TX transfer finishes. The call occurs
150 * in interrupt context.
151 *
152 * @param dat pointer to the structure of the current stream.
153 *
154 */
155static void audio_dma_irq(int channel, void *data)
156{
157 struct snd_pcm_substream *substream;
158 struct snd_pcm_runtime *runtime;
159 struct mx1_mx2_runtime_data *prtd;
160 unsigned int dma_size;
161 unsigned int previous_period;
162 unsigned int offset;
163
164 substream = data;
165 runtime = substream->runtime;
166 prtd = runtime->private_data;
167 previous_period = prtd->periods;
168 dma_size = frames_to_bytes(runtime, runtime->period_size);
169 offset = dma_size * previous_period;
170
171 prtd->tx_spin = 0;
172 prtd->periods++;
173 prtd->periods %= runtime->periods;
174
175 pr_debug("%s: irq per %d offset %x\n", __func__, prtd->periods, offset);
176
177 /*
178 * If we are getting a callback for an active stream then we inform
179 * the PCM middle layer we've finished a period
180 */
181 if (prtd->active)
182 snd_pcm_period_elapsed(substream);
183
184 /*
185 * Trig next DMA transfer
186 */
187 dma_new_period(substream);
188}
189
190/**
191 * This function configures the hardware to allow audio
192 * playback operations. It is called by ALSA framework.
193 *
194 * @param substream pointer to the structure of the current stream.
195 *
196 * @return 0 on success, -1 otherwise.
197 */
198static int
199snd_mx1_mx2_prepare(struct snd_pcm_substream *substream)
200{
201 struct snd_pcm_runtime *runtime = substream->runtime;
202 struct mx1_mx2_runtime_data *prtd = runtime->private_data;
203
204 prtd->period = 0;
205 prtd->periods = 0;
206
207 return 0;
208}
209
210static int mx1_mx2_pcm_hw_params(struct snd_pcm_substream *substream,
211 struct snd_pcm_hw_params *hw_params)
212{
213 struct snd_pcm_runtime *runtime = substream->runtime;
214 int ret;
215
216 ret = snd_pcm_lib_malloc_pages(substream,
217 params_buffer_bytes(hw_params));
218 if (ret < 0) {
219 printk(KERN_ERR "%s: Error %d failed to malloc pcm pages \n",
220 __func__, ret);
221 return ret;
222 }
223
224 pr_debug("%s: snd_imx1_mx2_audio_hw_params runtime->dma_addr 0x(%x)\n",
225 __func__, (unsigned int)runtime->dma_addr);
226 pr_debug("%s: snd_imx1_mx2_audio_hw_params runtime->dma_area 0x(%x)\n",
227 __func__, (unsigned int)runtime->dma_area);
228 pr_debug("%s: snd_imx1_mx2_audio_hw_params runtime->dma_bytes 0x(%x)\n",
229 __func__, (unsigned int)runtime->dma_bytes);
230
231 return ret;
232}
233
234static int mx1_mx2_pcm_hw_free(struct snd_pcm_substream *substream)
235{
236 struct snd_pcm_runtime *runtime = substream->runtime;
237 struct mx1_mx2_runtime_data *prtd = runtime->private_data;
238
239 imx_dma_free(prtd->dma_ch);
240
241 snd_pcm_lib_free_pages(substream);
242
243 return 0;
244}
245
246static int mx1_mx2_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
247{
248 struct mx1_mx2_runtime_data *prtd = substream->runtime->private_data;
249 int ret = 0;
250
251 switch (cmd) {
252 case SNDRV_PCM_TRIGGER_START:
253 prtd->tx_spin = 0;
254 /* requested stream startup */
255 prtd->active = 1;
256 pr_debug("%s: starting dma_new_period\n", __func__);
257 ret = dma_new_period(substream);
258 break;
259 case SNDRV_PCM_TRIGGER_STOP:
260 /* requested stream shutdown */
261 pr_debug("%s: stopping dma transfer\n", __func__);
262 ret = audio_stop_dma(substream);
263 break;
264 default:
265 ret = -EINVAL;
266 break;
267 }
268
269 return ret;
270}
271
272static snd_pcm_uframes_t
273mx1_mx2_pcm_pointer(struct snd_pcm_substream *substream)
274{
275 struct snd_pcm_runtime *runtime = substream->runtime;
276 struct mx1_mx2_runtime_data *prtd = runtime->private_data;
277 unsigned int offset = 0;
278
279 /* tx_spin value is used here to check if a transfer is active */
280 if (prtd->tx_spin) {
281 offset = (runtime->period_size * (prtd->periods)) +
282 (runtime->period_size >> 1);
283 if (offset >= runtime->buffer_size)
284 offset = runtime->period_size >> 1;
285 } else {
286 offset = (runtime->period_size * (prtd->periods));
287 if (offset >= runtime->buffer_size)
288 offset = 0;
289 }
290 pr_debug("%s: pointer offset %x\n", __func__, offset);
291
292 return offset;
293}
294
295static int mx1_mx2_pcm_open(struct snd_pcm_substream *substream)
296{
297 struct snd_pcm_runtime *runtime = substream->runtime;
298 struct mx1_mx2_runtime_data *prtd;
299 struct snd_soc_pcm_runtime *rtd = substream->private_data;
300 struct mx1_mx2_pcm_dma_params *dma_data = rtd->dai->cpu_dai->dma_data;
301 int ret;
302
303 snd_soc_set_runtime_hwparams(substream, &mx1_mx2_pcm_hardware);
304
305 ret = snd_pcm_hw_constraint_integer(runtime,
306 SNDRV_PCM_HW_PARAM_PERIODS);
307 if (ret < 0)
308 return ret;
309
310 prtd = kzalloc(sizeof(struct mx1_mx2_runtime_data), GFP_KERNEL);
311 if (prtd == NULL) {
312 ret = -ENOMEM;
313 goto out;
314 }
315
316 runtime->private_data = prtd;
317
318 if (!dma_data)
319 return -ENODEV;
320
321 prtd->dma_params = dma_data;
322
323 pr_debug("%s: Requesting dma channel (%s)\n", __func__,
324 prtd->dma_params->name);
325 ret = imx_dma_request_by_prio(prtd->dma_params->name, DMA_PRIO_HIGH);
326 if (ret < 0) {
327 printk(KERN_ERR "Error %d requesting dma channel\n", ret);
328 return ret;
329 }
330 prtd->dma_ch = ret;
331 imx_dma_config_burstlen(prtd->dma_ch,
332 prtd->dma_params->watermark_level);
333
334 ret = imx_dma_config_channel(prtd->dma_ch,
335 prtd->dma_params->per_config,
336 prtd->dma_params->mem_config,
337 prtd->dma_params->event_id, 0);
338
339 if (ret) {
340 pr_debug(KERN_ERR "Error %d configuring dma channel %d\n",
341 ret, prtd->dma_ch);
342 return ret;
343 }
344
345 pr_debug("%s: Setting tx dma callback function\n", __func__);
346 ret = imx_dma_setup_handlers(prtd->dma_ch,
347 audio_dma_irq, NULL,
348 (void *)substream);
349 if (ret < 0) {
350 printk(KERN_ERR "Error %d setting dma callback function\n", ret);
351 return ret;
352 }
353 return 0;
354
355 out:
356 return ret;
357}
358
359static int mx1_mx2_pcm_close(struct snd_pcm_substream *substream)
360{
361 struct snd_pcm_runtime *runtime = substream->runtime;
362 struct mx1_mx2_runtime_data *prtd = runtime->private_data;
363
364 kfree(prtd);
365
366 return 0;
367}
368
369static int mx1_mx2_pcm_mmap(struct snd_pcm_substream *substream,
370 struct vm_area_struct *vma)
371{
372 struct snd_pcm_runtime *runtime = substream->runtime;
373 return dma_mmap_writecombine(substream->pcm->card->dev, vma,
374 runtime->dma_area,
375 runtime->dma_addr,
376 runtime->dma_bytes);
377}
378
379static struct snd_pcm_ops mx1_mx2_pcm_ops = {
380 .open = mx1_mx2_pcm_open,
381 .close = mx1_mx2_pcm_close,
382 .ioctl = snd_pcm_lib_ioctl,
383 .hw_params = mx1_mx2_pcm_hw_params,
384 .hw_free = mx1_mx2_pcm_hw_free,
385 .prepare = snd_mx1_mx2_prepare,
386 .trigger = mx1_mx2_pcm_trigger,
387 .pointer = mx1_mx2_pcm_pointer,
388 .mmap = mx1_mx2_pcm_mmap,
389};
390
391static u64 mx1_mx2_pcm_dmamask = 0xffffffff;
392
393static int mx1_mx2_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
394{
395 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
396 struct snd_dma_buffer *buf = &substream->dma_buffer;
397 size_t size = mx1_mx2_pcm_hardware.buffer_bytes_max;
398 buf->dev.type = SNDRV_DMA_TYPE_DEV;
399 buf->dev.dev = pcm->card->dev;
400 buf->private_data = NULL;
401
402 /* Reserve uncached-buffered memory area for DMA */
403 buf->area = dma_alloc_writecombine(pcm->card->dev, size,
404 &buf->addr, GFP_KERNEL);
405
406 pr_debug("%s: preallocate_dma_buffer: area=%p, addr=%p, size=%d\n",
407 __func__, (void *) buf->area, (void *) buf->addr, size);
408
409 if (!buf->area)
410 return -ENOMEM;
411
412 buf->bytes = size;
413 return 0;
414}
415
416static void mx1_mx2_pcm_free_dma_buffers(struct snd_pcm *pcm)
417{
418 struct snd_pcm_substream *substream;
419 struct snd_dma_buffer *buf;
420 int stream;
421
422 for (stream = 0; stream < 2; stream++) {
423 substream = pcm->streams[stream].substream;
424 if (!substream)
425 continue;
426
427 buf = &substream->dma_buffer;
428 if (!buf->area)
429 continue;
430
431 dma_free_writecombine(pcm->card->dev, buf->bytes,
432 buf->area, buf->addr);
433 buf->area = NULL;
434 }
435}
436
437static int mx1_mx2_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
438 struct snd_pcm *pcm)
439{
440 int ret = 0;
441
442 if (!card->dev->dma_mask)
443 card->dev->dma_mask = &mx1_mx2_pcm_dmamask;
444 if (!card->dev->coherent_dma_mask)
445 card->dev->coherent_dma_mask = 0xffffffff;
446
447 if (dai->playback.channels_min) {
448 ret = mx1_mx2_pcm_preallocate_dma_buffer(pcm,
449 SNDRV_PCM_STREAM_PLAYBACK);
450 pr_debug("%s: preallocate playback buffer\n", __func__);
451 if (ret)
452 goto out;
453 }
454
455 if (dai->capture.channels_min) {
456 ret = mx1_mx2_pcm_preallocate_dma_buffer(pcm,
457 SNDRV_PCM_STREAM_CAPTURE);
458 pr_debug("%s: preallocate capture buffer\n", __func__);
459 if (ret)
460 goto out;
461 }
462 out:
463 return ret;
464}
465
466struct snd_soc_platform mx1_mx2_soc_platform = {
467 .name = "mx1_mx2-audio",
468 .pcm_ops = &mx1_mx2_pcm_ops,
469 .pcm_new = mx1_mx2_pcm_new,
470 .pcm_free = mx1_mx2_pcm_free_dma_buffers,
471};
472EXPORT_SYMBOL_GPL(mx1_mx2_soc_platform);
473
474static int __init mx1_mx2_soc_platform_init(void)
475{
476 return snd_soc_register_platform(&mx1_mx2_soc_platform);
477}
478module_init(mx1_mx2_soc_platform_init);
479
480static void __exit mx1_mx2_soc_platform_exit(void)
481{
482 snd_soc_unregister_platform(&mx1_mx2_soc_platform);
483}
484module_exit(mx1_mx2_soc_platform_exit);
485
486MODULE_AUTHOR("Javier Martin, javier.martin@vista-silicon.com");
487MODULE_DESCRIPTION("Freescale i.MX2x, i.MX1x PCM DMA module");
488MODULE_LICENSE("GPL");
diff --git a/sound/soc/imx/mx1_mx2-pcm.h b/sound/soc/imx/mx1_mx2-pcm.h
deleted file mode 100644
index 2e528106570b..000000000000
--- a/sound/soc/imx/mx1_mx2-pcm.h
+++ /dev/null
@@ -1,26 +0,0 @@
1/*
2 * mx1_mx2-pcm.h :- ASoC platform header for Freescale i.MX1x, i.MX2x
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#ifndef _MX1_MX2_PCM_H
10#define _MX1_MX2_PCM_H
11
12/* DMA information for mx1_mx2 platforms */
13struct mx1_mx2_pcm_dma_params {
14 char *name; /* stream identifier */
15 unsigned int transfer_type; /* READ or WRITE DMA transfer */
16 dma_addr_t per_address; /* physical address of SSI fifo */
17 int event_id; /* fixed DMA number for SSI fifo */
18 int watermark_level; /* SSI fifo watermark level */
19 int per_config; /* DMA Config flags for peripheral */
20 int mem_config; /* DMA Config flags for RAM */
21 };
22
23/* platform data */
24extern struct snd_soc_platform mx1_mx2_soc_platform;
25
26#endif
diff --git a/sound/soc/imx/mx27vis_wm8974.c b/sound/soc/imx/mx27vis_wm8974.c
deleted file mode 100644
index 07d2a248438c..000000000000
--- a/sound/soc/imx/mx27vis_wm8974.c
+++ /dev/null
@@ -1,318 +0,0 @@
1/*
2 * mx27vis_wm8974.c -- SoC audio for mx27vis
3 *
4 * Copyright 2009 Vista Silicon S.L.
5 * Author: Javier Martin
6 * 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 */
14
15#include <linux/module.h>
16#include <linux/moduleparam.h>
17#include <linux/device.h>
18#include <linux/i2c.h>
19#include <sound/core.h>
20#include <sound/pcm.h>
21#include <sound/soc.h>
22#include <sound/soc-dapm.h>
23
24
25#include "../codecs/wm8974.h"
26#include "mx1_mx2-pcm.h"
27#include "mxc-ssi.h"
28#include <mach/gpio.h>
29#include <mach/iomux.h>
30
31#define IGNORED_ARG 0
32
33
34static struct snd_soc_card mx27vis;
35
36/**
37 * This function connects SSI1 (HPCR1) as slave to
38 * SSI1 external signals (PPCR1)
39 * As slave, HPCR1 must set TFSDIR and TCLKDIR as inputs from
40 * port 4
41 */
42void audmux_connect_1_4(void)
43{
44 pr_debug("AUDMUX: normal operation mode\n");
45 /* Reset HPCR1 and PPCR1 */
46
47 DAM_HPCR1 = 0x00000000;
48 DAM_PPCR1 = 0x00000000;
49
50 /* set to synchronous */
51 DAM_HPCR1 |= AUDMUX_HPCR_SYN;
52 DAM_PPCR1 |= AUDMUX_PPCR_SYN;
53
54
55 /* set Rx sources 1 <--> 4 */
56 DAM_HPCR1 |= AUDMUX_HPCR_RXDSEL(3); /* port 4 */
57 DAM_PPCR1 |= AUDMUX_PPCR_RXDSEL(0); /* port 1 */
58
59 /* set Tx frame and Clock direction and source 4 --> 1 output */
60 DAM_HPCR1 |= AUDMUX_HPCR_TFSDIR | AUDMUX_HPCR_TCLKDIR;
61 DAM_HPCR1 |= AUDMUX_HPCR_TFCSEL(3); /* TxDS and TxCclk from port 4 */
62
63 return;
64}
65
66static int mx27vis_hifi_hw_params(struct snd_pcm_substream *substream,
67 struct snd_pcm_hw_params *params)
68{
69 struct snd_soc_pcm_runtime *rtd = substream->private_data;
70 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
71 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
72 unsigned int pll_out = 0, bclk = 0, fmt = 0, mclk = 0;
73 int ret = 0;
74
75 /*
76 * The WM8974 is better at generating accurate audio clocks than the
77 * MX27 SSI controller, so we will use it as master when we can.
78 */
79 switch (params_rate(params)) {
80 case 8000:
81 fmt = SND_SOC_DAIFMT_CBM_CFM;
82 mclk = WM8974_MCLKDIV_12;
83 pll_out = 24576000;
84 break;
85 case 16000:
86 fmt = SND_SOC_DAIFMT_CBM_CFM;
87 pll_out = 12288000;
88 break;
89 case 48000:
90 fmt = SND_SOC_DAIFMT_CBM_CFM;
91 bclk = WM8974_BCLKDIV_4;
92 pll_out = 12288000;
93 break;
94 case 96000:
95 fmt = SND_SOC_DAIFMT_CBM_CFM;
96 bclk = WM8974_BCLKDIV_2;
97 pll_out = 12288000;
98 break;
99 case 11025:
100 fmt = SND_SOC_DAIFMT_CBM_CFM;
101 bclk = WM8974_BCLKDIV_16;
102 pll_out = 11289600;
103 break;
104 case 22050:
105 fmt = SND_SOC_DAIFMT_CBM_CFM;
106 bclk = WM8974_BCLKDIV_8;
107 pll_out = 11289600;
108 break;
109 case 44100:
110 fmt = SND_SOC_DAIFMT_CBM_CFM;
111 bclk = WM8974_BCLKDIV_4;
112 mclk = WM8974_MCLKDIV_2;
113 pll_out = 11289600;
114 break;
115 case 88200:
116 fmt = SND_SOC_DAIFMT_CBM_CFM;
117 bclk = WM8974_BCLKDIV_2;
118 pll_out = 11289600;
119 break;
120 }
121
122 /* set codec DAI configuration */
123 ret = codec_dai->ops->set_fmt(codec_dai,
124 SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_IF |
125 SND_SOC_DAIFMT_SYNC | fmt);
126 if (ret < 0) {
127 printk(KERN_ERR "Error from codec DAI configuration\n");
128 return ret;
129 }
130
131 /* set cpu DAI configuration */
132 ret = cpu_dai->ops->set_fmt(cpu_dai,
133 SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
134 SND_SOC_DAIFMT_SYNC | fmt);
135 if (ret < 0) {
136 printk(KERN_ERR "Error from cpu DAI configuration\n");
137 return ret;
138 }
139
140 /* Put DC field of STCCR to 1 (not zero) */
141 ret = cpu_dai->ops->set_tdm_slot(cpu_dai, 0, 2);
142
143 /* set the SSI system clock as input */
144 ret = cpu_dai->ops->set_sysclk(cpu_dai, IMX_SSP_SYS_CLK, 0,
145 SND_SOC_CLOCK_IN);
146 if (ret < 0) {
147 printk(KERN_ERR "Error when setting system SSI clk\n");
148 return ret;
149 }
150
151 /* set codec BCLK division for sample rate */
152 ret = codec_dai->ops->set_clkdiv(codec_dai, WM8974_BCLKDIV, bclk);
153 if (ret < 0) {
154 printk(KERN_ERR "Error when setting BCLK division\n");
155 return ret;
156 }
157
158
159 /* codec PLL input is 25 MHz */
160 ret = codec_dai->ops->set_pll(codec_dai, IGNORED_ARG, IGNORED_ARG,
161 25000000, pll_out);
162 if (ret < 0) {
163 printk(KERN_ERR "Error when setting PLL input\n");
164 return ret;
165 }
166
167 /*set codec MCLK division for sample rate */
168 ret = codec_dai->ops->set_clkdiv(codec_dai, WM8974_MCLKDIV, mclk);
169 if (ret < 0) {
170 printk(KERN_ERR "Error when setting MCLK division\n");
171 return ret;
172 }
173
174 return 0;
175}
176
177static int mx27vis_hifi_hw_free(struct snd_pcm_substream *substream)
178{
179 struct snd_soc_pcm_runtime *rtd = substream->private_data;
180 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
181
182 /* disable the PLL */
183 return codec_dai->ops->set_pll(codec_dai, IGNORED_ARG, IGNORED_ARG,
184 0, 0);
185}
186
187/*
188 * mx27vis WM8974 HiFi DAI opserations.
189 */
190static struct snd_soc_ops mx27vis_hifi_ops = {
191 .hw_params = mx27vis_hifi_hw_params,
192 .hw_free = mx27vis_hifi_hw_free,
193};
194
195
196static int mx27vis_suspend(struct platform_device *pdev, pm_message_t state)
197{
198 return 0;
199}
200
201static int mx27vis_resume(struct platform_device *pdev)
202{
203 return 0;
204}
205
206static int mx27vis_probe(struct platform_device *pdev)
207{
208 int ret = 0;
209
210 ret = get_ssi_clk(0, &pdev->dev);
211
212 if (ret < 0) {
213 printk(KERN_ERR "%s: cant get ssi clock\n", __func__);
214 return ret;
215 }
216
217
218 return 0;
219}
220
221static int mx27vis_remove(struct platform_device *pdev)
222{
223 put_ssi_clk(0);
224 return 0;
225}
226
227static struct snd_soc_dai_link mx27vis_dai[] = {
228{ /* Hifi Playback*/
229 .name = "WM8974",
230 .stream_name = "WM8974 HiFi",
231 .cpu_dai = &imx_ssi_pcm_dai[0],
232 .codec_dai = &wm8974_dai,
233 .ops = &mx27vis_hifi_ops,
234},
235};
236
237static struct snd_soc_card mx27vis = {
238 .name = "mx27vis",
239 .platform = &mx1_mx2_soc_platform,
240 .probe = mx27vis_probe,
241 .remove = mx27vis_remove,
242 .suspend_pre = mx27vis_suspend,
243 .resume_post = mx27vis_resume,
244 .dai_link = mx27vis_dai,
245 .num_links = ARRAY_SIZE(mx27vis_dai),
246};
247
248static struct snd_soc_device mx27vis_snd_devdata = {
249 .card = &mx27vis,
250 .codec_dev = &soc_codec_dev_wm8974,
251};
252
253static struct platform_device *mx27vis_snd_device;
254
255/* Temporal definition of board specific behaviour */
256void gpio_ssi_active(int ssi_num)
257{
258 int ret = 0;
259
260 unsigned int ssi1_pins[] = {
261 PC20_PF_SSI1_FS,
262 PC21_PF_SSI1_RXD,
263 PC22_PF_SSI1_TXD,
264 PC23_PF_SSI1_CLK,
265 };
266 unsigned int ssi2_pins[] = {
267 PC24_PF_SSI2_FS,
268 PC25_PF_SSI2_RXD,
269 PC26_PF_SSI2_TXD,
270 PC27_PF_SSI2_CLK,
271 };
272 if (ssi_num == 0)
273 ret = mxc_gpio_setup_multiple_pins(ssi1_pins,
274 ARRAY_SIZE(ssi1_pins), "USB OTG");
275 else
276 ret = mxc_gpio_setup_multiple_pins(ssi2_pins,
277 ARRAY_SIZE(ssi2_pins), "USB OTG");
278 if (ret)
279 printk(KERN_ERR "Error requesting ssi %x pins\n", ssi_num);
280}
281
282
283static int __init mx27vis_init(void)
284{
285 int ret;
286
287 mx27vis_snd_device = platform_device_alloc("soc-audio", -1);
288 if (!mx27vis_snd_device)
289 return -ENOMEM;
290
291 platform_set_drvdata(mx27vis_snd_device, &mx27vis_snd_devdata);
292 mx27vis_snd_devdata.dev = &mx27vis_snd_device->dev;
293 ret = platform_device_add(mx27vis_snd_device);
294
295 if (ret) {
296 printk(KERN_ERR "ASoC: Platform device allocation failed\n");
297 platform_device_put(mx27vis_snd_device);
298 }
299
300 /* WM8974 uses SSI1 (HPCR1) via AUDMUX port 4 for audio (PPCR1) */
301 gpio_ssi_active(0);
302 audmux_connect_1_4();
303
304 return ret;
305}
306
307static void __exit mx27vis_exit(void)
308{
309 /* We should call some "ssi_gpio_inactive()" properly */
310}
311
312module_init(mx27vis_init);
313module_exit(mx27vis_exit);
314
315
316MODULE_AUTHOR("Javier Martin, javier.martin@vista-silicon.com");
317MODULE_DESCRIPTION("ALSA SoC WM8974 mx27vis");
318MODULE_LICENSE("GPL");
diff --git a/sound/soc/imx/mxc-ssi.c b/sound/soc/imx/mxc-ssi.c
deleted file mode 100644
index ccdefe60e752..000000000000
--- a/sound/soc/imx/mxc-ssi.c
+++ /dev/null
@@ -1,860 +0,0 @@
1/*
2 * mxc-ssi.c -- SSI driver for Freescale IMX
3 *
4 * Copyright 2006 Wolfson Microelectronics PLC.
5 * Author: Liam Girdwood
6 * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
7 *
8 * Based on mxc-alsa-mc13783 (C) 2006 Freescale.
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 * TODO:
16 * Need to rework SSI register defs when new defs go into mainline.
17 * Add support for TDM and FIFO 1.
18 * Add support for i.mx3x DMA interface.
19 *
20 */
21
22
23#include <linux/module.h>
24#include <linux/init.h>
25#include <linux/platform_device.h>
26#include <linux/slab.h>
27#include <linux/dma-mapping.h>
28#include <linux/clk.h>
29#include <sound/core.h>
30#include <sound/pcm.h>
31#include <sound/pcm_params.h>
32#include <sound/soc.h>
33#include <mach/dma-mx1-mx2.h>
34#include <asm/mach-types.h>
35
36#include "mxc-ssi.h"
37#include "mx1_mx2-pcm.h"
38
39#define SSI1_PORT 0
40#define SSI2_PORT 1
41
42static int ssi_active[2] = {0, 0};
43
44/* DMA information for mx1_mx2 platforms */
45static struct mx1_mx2_pcm_dma_params imx_ssi1_pcm_stereo_out0 = {
46 .name = "SSI1 PCM Stereo out 0",
47 .transfer_type = DMA_MODE_WRITE,
48 .per_address = SSI1_BASE_ADDR + STX0,
49 .event_id = DMA_REQ_SSI1_TX0,
50 .watermark_level = TXFIFO_WATERMARK,
51 .per_config = IMX_DMA_MEMSIZE_16 | IMX_DMA_TYPE_FIFO,
52 .mem_config = IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR,
53};
54
55static struct mx1_mx2_pcm_dma_params imx_ssi1_pcm_stereo_out1 = {
56 .name = "SSI1 PCM Stereo out 1",
57 .transfer_type = DMA_MODE_WRITE,
58 .per_address = SSI1_BASE_ADDR + STX1,
59 .event_id = DMA_REQ_SSI1_TX1,
60 .watermark_level = TXFIFO_WATERMARK,
61 .per_config = IMX_DMA_MEMSIZE_16 | IMX_DMA_TYPE_FIFO,
62 .mem_config = IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR,
63};
64
65static struct mx1_mx2_pcm_dma_params imx_ssi1_pcm_stereo_in0 = {
66 .name = "SSI1 PCM Stereo in 0",
67 .transfer_type = DMA_MODE_READ,
68 .per_address = SSI1_BASE_ADDR + SRX0,
69 .event_id = DMA_REQ_SSI1_RX0,
70 .watermark_level = RXFIFO_WATERMARK,
71 .per_config = IMX_DMA_MEMSIZE_16 | IMX_DMA_TYPE_FIFO,
72 .mem_config = IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR,
73};
74
75static struct mx1_mx2_pcm_dma_params imx_ssi1_pcm_stereo_in1 = {
76 .name = "SSI1 PCM Stereo in 1",
77 .transfer_type = DMA_MODE_READ,
78 .per_address = SSI1_BASE_ADDR + SRX1,
79 .event_id = DMA_REQ_SSI1_RX1,
80 .watermark_level = RXFIFO_WATERMARK,
81 .per_config = IMX_DMA_MEMSIZE_16 | IMX_DMA_TYPE_FIFO,
82 .mem_config = IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR,
83};
84
85static struct mx1_mx2_pcm_dma_params imx_ssi2_pcm_stereo_out0 = {
86 .name = "SSI2 PCM Stereo out 0",
87 .transfer_type = DMA_MODE_WRITE,
88 .per_address = SSI2_BASE_ADDR + STX0,
89 .event_id = DMA_REQ_SSI2_TX0,
90 .watermark_level = TXFIFO_WATERMARK,
91 .per_config = IMX_DMA_MEMSIZE_16 | IMX_DMA_TYPE_FIFO,
92 .mem_config = IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR,
93};
94
95static struct mx1_mx2_pcm_dma_params imx_ssi2_pcm_stereo_out1 = {
96 .name = "SSI2 PCM Stereo out 1",
97 .transfer_type = DMA_MODE_WRITE,
98 .per_address = SSI2_BASE_ADDR + STX1,
99 .event_id = DMA_REQ_SSI2_TX1,
100 .watermark_level = TXFIFO_WATERMARK,
101 .per_config = IMX_DMA_MEMSIZE_16 | IMX_DMA_TYPE_FIFO,
102 .mem_config = IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR,
103};
104
105static struct mx1_mx2_pcm_dma_params imx_ssi2_pcm_stereo_in0 = {
106 .name = "SSI2 PCM Stereo in 0",
107 .transfer_type = DMA_MODE_READ,
108 .per_address = SSI2_BASE_ADDR + SRX0,
109 .event_id = DMA_REQ_SSI2_RX0,
110 .watermark_level = RXFIFO_WATERMARK,
111 .per_config = IMX_DMA_MEMSIZE_16 | IMX_DMA_TYPE_FIFO,
112 .mem_config = IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR,
113};
114
115static struct mx1_mx2_pcm_dma_params imx_ssi2_pcm_stereo_in1 = {
116 .name = "SSI2 PCM Stereo in 1",
117 .transfer_type = DMA_MODE_READ,
118 .per_address = SSI2_BASE_ADDR + SRX1,
119 .event_id = DMA_REQ_SSI2_RX1,
120 .watermark_level = RXFIFO_WATERMARK,
121 .per_config = IMX_DMA_MEMSIZE_16 | IMX_DMA_TYPE_FIFO,
122 .mem_config = IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR,
123};
124
125static struct clk *ssi_clk0, *ssi_clk1;
126
127int get_ssi_clk(int ssi, struct device *dev)
128{
129 switch (ssi) {
130 case 0:
131 ssi_clk0 = clk_get(dev, "ssi1");
132 if (IS_ERR(ssi_clk0))
133 return PTR_ERR(ssi_clk0);
134 return 0;
135 case 1:
136 ssi_clk1 = clk_get(dev, "ssi2");
137 if (IS_ERR(ssi_clk1))
138 return PTR_ERR(ssi_clk1);
139 return 0;
140 default:
141 return -EINVAL;
142 }
143}
144EXPORT_SYMBOL(get_ssi_clk);
145
146void put_ssi_clk(int ssi)
147{
148 switch (ssi) {
149 case 0:
150 clk_put(ssi_clk0);
151 ssi_clk0 = NULL;
152 break;
153 case 1:
154 clk_put(ssi_clk1);
155 ssi_clk1 = NULL;
156 break;
157 }
158}
159EXPORT_SYMBOL(put_ssi_clk);
160
161/*
162 * SSI system clock configuration.
163 * Should only be called when port is inactive (i.e. SSIEN = 0).
164 */
165static int imx_ssi_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
166 int clk_id, unsigned int freq, int dir)
167{
168 u32 scr;
169
170 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
171 scr = SSI1_SCR;
172 pr_debug("%s: SCR for SSI1 is %x\n", __func__, scr);
173 } else {
174 scr = SSI2_SCR;
175 pr_debug("%s: SCR for SSI2 is %x\n", __func__, scr);
176 }
177
178 if (scr & SSI_SCR_SSIEN) {
179 printk(KERN_WARNING "Warning ssi already enabled\n");
180 return 0;
181 }
182
183 switch (clk_id) {
184 case IMX_SSP_SYS_CLK:
185 if (dir == SND_SOC_CLOCK_OUT) {
186 scr |= SSI_SCR_SYS_CLK_EN;
187 pr_debug("%s: clk of is output\n", __func__);
188 } else {
189 scr &= ~SSI_SCR_SYS_CLK_EN;
190 pr_debug("%s: clk of is input\n", __func__);
191 }
192 break;
193 default:
194 return -EINVAL;
195 }
196
197 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
198 pr_debug("%s: writeback of SSI1_SCR\n", __func__);
199 SSI1_SCR = scr;
200 } else {
201 pr_debug("%s: writeback of SSI2_SCR\n", __func__);
202 SSI2_SCR = scr;
203 }
204
205 return 0;
206}
207
208/*
209 * SSI Clock dividers
210 * Should only be called when port is inactive (i.e. SSIEN = 0).
211 */
212static int imx_ssi_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
213 int div_id, int div)
214{
215 u32 stccr, srccr;
216
217 pr_debug("%s\n", __func__);
218 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
219 if (SSI1_SCR & SSI_SCR_SSIEN)
220 return 0;
221 srccr = SSI1_STCCR;
222 stccr = SSI1_STCCR;
223 } else {
224 if (SSI2_SCR & SSI_SCR_SSIEN)
225 return 0;
226 srccr = SSI2_STCCR;
227 stccr = SSI2_STCCR;
228 }
229
230 switch (div_id) {
231 case IMX_SSI_TX_DIV_2:
232 stccr &= ~SSI_STCCR_DIV2;
233 stccr |= div;
234 break;
235 case IMX_SSI_TX_DIV_PSR:
236 stccr &= ~SSI_STCCR_PSR;
237 stccr |= div;
238 break;
239 case IMX_SSI_TX_DIV_PM:
240 stccr &= ~0xff;
241 stccr |= SSI_STCCR_PM(div);
242 break;
243 case IMX_SSI_RX_DIV_2:
244 stccr &= ~SSI_STCCR_DIV2;
245 stccr |= div;
246 break;
247 case IMX_SSI_RX_DIV_PSR:
248 stccr &= ~SSI_STCCR_PSR;
249 stccr |= div;
250 break;
251 case IMX_SSI_RX_DIV_PM:
252 stccr &= ~0xff;
253 stccr |= SSI_STCCR_PM(div);
254 break;
255 default:
256 return -EINVAL;
257 }
258
259 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
260 SSI1_STCCR = stccr;
261 SSI1_SRCCR = srccr;
262 } else {
263 SSI2_STCCR = stccr;
264 SSI2_SRCCR = srccr;
265 }
266 return 0;
267}
268
269/*
270 * SSI Network Mode or TDM slots configuration.
271 * Should only be called when port is inactive (i.e. SSIEN = 0).
272 */
273static int imx_ssi_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai,
274 unsigned int mask, int slots)
275{
276 u32 stmsk, srmsk, stccr;
277
278 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
279 if (SSI1_SCR & SSI_SCR_SSIEN) {
280 printk(KERN_WARNING "Warning ssi already enabled\n");
281 return 0;
282 }
283 stccr = SSI1_STCCR;
284 } else {
285 if (SSI2_SCR & SSI_SCR_SSIEN) {
286 printk(KERN_WARNING "Warning ssi already enabled\n");
287 return 0;
288 }
289 stccr = SSI2_STCCR;
290 }
291
292 stmsk = srmsk = mask;
293 stccr &= ~SSI_STCCR_DC_MASK;
294 stccr |= SSI_STCCR_DC(slots - 1);
295
296 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
297 SSI1_STMSK = stmsk;
298 SSI1_SRMSK = srmsk;
299 SSI1_SRCCR = SSI1_STCCR = stccr;
300 } else {
301 SSI2_STMSK = stmsk;
302 SSI2_SRMSK = srmsk;
303 SSI2_SRCCR = SSI2_STCCR = stccr;
304 }
305
306 return 0;
307}
308
309/*
310 * SSI DAI format configuration.
311 * Should only be called when port is inactive (i.e. SSIEN = 0).
312 * Note: We don't use the I2S modes but instead manually configure the
313 * SSI for I2S.
314 */
315static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai,
316 unsigned int fmt)
317{
318 u32 stcr = 0, srcr = 0, scr;
319
320 /*
321 * This is done to avoid this function to modify
322 * previous set values in stcr
323 */
324 stcr = SSI1_STCR;
325
326 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2)
327 scr = SSI1_SCR & ~(SSI_SCR_SYN | SSI_SCR_NET);
328 else
329 scr = SSI2_SCR & ~(SSI_SCR_SYN | SSI_SCR_NET);
330
331 if (scr & SSI_SCR_SSIEN) {
332 printk(KERN_WARNING "Warning ssi already enabled\n");
333 return 0;
334 }
335
336 /* DAI mode */
337 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
338 case SND_SOC_DAIFMT_I2S:
339 /* data on rising edge of bclk, frame low 1clk before data */
340 stcr |= SSI_STCR_TFSI | SSI_STCR_TEFS | SSI_STCR_TXBIT0;
341 srcr |= SSI_SRCR_RFSI | SSI_SRCR_REFS | SSI_SRCR_RXBIT0;
342 break;
343 case SND_SOC_DAIFMT_LEFT_J:
344 /* data on rising edge of bclk, frame high with data */
345 stcr |= SSI_STCR_TXBIT0;
346 srcr |= SSI_SRCR_RXBIT0;
347 break;
348 case SND_SOC_DAIFMT_DSP_B:
349 /* data on rising edge of bclk, frame high with data */
350 stcr |= SSI_STCR_TFSL;
351 srcr |= SSI_SRCR_RFSL;
352 break;
353 case SND_SOC_DAIFMT_DSP_A:
354 /* data on rising edge of bclk, frame high 1clk before data */
355 stcr |= SSI_STCR_TFSL | SSI_STCR_TEFS;
356 srcr |= SSI_SRCR_RFSL | SSI_SRCR_REFS;
357 break;
358 }
359
360 /* DAI clock inversion */
361 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
362 case SND_SOC_DAIFMT_IB_IF:
363 stcr |= SSI_STCR_TFSI;
364 stcr &= ~SSI_STCR_TSCKP;
365 srcr |= SSI_SRCR_RFSI;
366 srcr &= ~SSI_SRCR_RSCKP;
367 break;
368 case SND_SOC_DAIFMT_IB_NF:
369 stcr &= ~(SSI_STCR_TSCKP | SSI_STCR_TFSI);
370 srcr &= ~(SSI_SRCR_RSCKP | SSI_SRCR_RFSI);
371 break;
372 case SND_SOC_DAIFMT_NB_IF:
373 stcr |= SSI_STCR_TFSI | SSI_STCR_TSCKP;
374 srcr |= SSI_SRCR_RFSI | SSI_SRCR_RSCKP;
375 break;
376 case SND_SOC_DAIFMT_NB_NF:
377 stcr &= ~SSI_STCR_TFSI;
378 stcr |= SSI_STCR_TSCKP;
379 srcr &= ~SSI_SRCR_RFSI;
380 srcr |= SSI_SRCR_RSCKP;
381 break;
382 }
383
384 /* DAI clock master masks */
385 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
386 case SND_SOC_DAIFMT_CBS_CFS:
387 stcr |= SSI_STCR_TFDIR | SSI_STCR_TXDIR;
388 srcr |= SSI_SRCR_RFDIR | SSI_SRCR_RXDIR;
389 break;
390 case SND_SOC_DAIFMT_CBM_CFS:
391 stcr |= SSI_STCR_TFDIR;
392 srcr |= SSI_SRCR_RFDIR;
393 break;
394 case SND_SOC_DAIFMT_CBS_CFM:
395 stcr |= SSI_STCR_TXDIR;
396 srcr |= SSI_SRCR_RXDIR;
397 break;
398 }
399
400 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
401 SSI1_STCR = stcr;
402 SSI1_SRCR = srcr;
403 SSI1_SCR = scr;
404 } else {
405 SSI2_STCR = stcr;
406 SSI2_SRCR = srcr;
407 SSI2_SCR = scr;
408 }
409
410 return 0;
411}
412
413static int imx_ssi_startup(struct snd_pcm_substream *substream,
414 struct snd_soc_dai *dai)
415{
416 struct snd_soc_pcm_runtime *rtd = substream->private_data;
417 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
418
419 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
420 /* set up TX DMA params */
421 switch (cpu_dai->id) {
422 case IMX_DAI_SSI0:
423 cpu_dai->dma_data = &imx_ssi1_pcm_stereo_out0;
424 break;
425 case IMX_DAI_SSI1:
426 cpu_dai->dma_data = &imx_ssi1_pcm_stereo_out1;
427 break;
428 case IMX_DAI_SSI2:
429 cpu_dai->dma_data = &imx_ssi2_pcm_stereo_out0;
430 break;
431 case IMX_DAI_SSI3:
432 cpu_dai->dma_data = &imx_ssi2_pcm_stereo_out1;
433 }
434 pr_debug("%s: (playback)\n", __func__);
435 } else {
436 /* set up RX DMA params */
437 switch (cpu_dai->id) {
438 case IMX_DAI_SSI0:
439 cpu_dai->dma_data = &imx_ssi1_pcm_stereo_in0;
440 break;
441 case IMX_DAI_SSI1:
442 cpu_dai->dma_data = &imx_ssi1_pcm_stereo_in1;
443 break;
444 case IMX_DAI_SSI2:
445 cpu_dai->dma_data = &imx_ssi2_pcm_stereo_in0;
446 break;
447 case IMX_DAI_SSI3:
448 cpu_dai->dma_data = &imx_ssi2_pcm_stereo_in1;
449 }
450 pr_debug("%s: (capture)\n", __func__);
451 }
452
453 /*
454 * we cant really change any SSI values after SSI is enabled
455 * need to fix in software for max flexibility - lrg
456 */
457 if (cpu_dai->active) {
458 printk(KERN_WARNING "Warning ssi already enabled\n");
459 return 0;
460 }
461
462 /* reset the SSI port - Sect 45.4.4 */
463 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
464
465 if (!ssi_clk0)
466 return -EINVAL;
467
468 if (ssi_active[SSI1_PORT]++) {
469 pr_debug("%s: exit before reset\n", __func__);
470 return 0;
471 }
472
473 /* SSI1 Reset */
474 SSI1_SCR = 0;
475
476 SSI1_SFCSR = SSI_SFCSR_RFWM1(RXFIFO_WATERMARK) |
477 SSI_SFCSR_RFWM0(RXFIFO_WATERMARK) |
478 SSI_SFCSR_TFWM1(TXFIFO_WATERMARK) |
479 SSI_SFCSR_TFWM0(TXFIFO_WATERMARK);
480 } else {
481
482 if (!ssi_clk1)
483 return -EINVAL;
484
485 if (ssi_active[SSI2_PORT]++) {
486 pr_debug("%s: exit before reset\n", __func__);
487 return 0;
488 }
489
490 /* SSI2 Reset */
491 SSI2_SCR = 0;
492
493 SSI2_SFCSR = SSI_SFCSR_RFWM1(RXFIFO_WATERMARK) |
494 SSI_SFCSR_RFWM0(RXFIFO_WATERMARK) |
495 SSI_SFCSR_TFWM1(TXFIFO_WATERMARK) |
496 SSI_SFCSR_TFWM0(TXFIFO_WATERMARK);
497 }
498
499 return 0;
500}
501
502int imx_ssi_hw_tx_params(struct snd_pcm_substream *substream,
503 struct snd_pcm_hw_params *params)
504{
505 struct snd_soc_pcm_runtime *rtd = substream->private_data;
506 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
507 u32 stccr, stcr, sier;
508
509 pr_debug("%s\n", __func__);
510
511 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
512 stccr = SSI1_STCCR & ~SSI_STCCR_WL_MASK;
513 stcr = SSI1_STCR;
514 sier = SSI1_SIER;
515 } else {
516 stccr = SSI2_STCCR & ~SSI_STCCR_WL_MASK;
517 stcr = SSI2_STCR;
518 sier = SSI2_SIER;
519 }
520
521 /* DAI data (word) size */
522 switch (params_format(params)) {
523 case SNDRV_PCM_FORMAT_S16_LE:
524 stccr |= SSI_STCCR_WL(16);
525 break;
526 case SNDRV_PCM_FORMAT_S20_3LE:
527 stccr |= SSI_STCCR_WL(20);
528 break;
529 case SNDRV_PCM_FORMAT_S24_LE:
530 stccr |= SSI_STCCR_WL(24);
531 break;
532 }
533
534 /* enable interrupts */
535 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2)
536 stcr |= SSI_STCR_TFEN0;
537 else
538 stcr |= SSI_STCR_TFEN1;
539 sier |= SSI_SIER_TDMAE;
540
541 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
542 SSI1_STCR = stcr;
543 SSI1_STCCR = stccr;
544 SSI1_SIER = sier;
545 } else {
546 SSI2_STCR = stcr;
547 SSI2_STCCR = stccr;
548 SSI2_SIER = sier;
549 }
550
551 return 0;
552}
553
554int imx_ssi_hw_rx_params(struct snd_pcm_substream *substream,
555 struct snd_pcm_hw_params *params)
556{
557 struct snd_soc_pcm_runtime *rtd = substream->private_data;
558 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
559 u32 srccr, srcr, sier;
560
561 pr_debug("%s\n", __func__);
562
563 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
564 srccr = SSI1_SRCCR & ~SSI_SRCCR_WL_MASK;
565 srcr = SSI1_SRCR;
566 sier = SSI1_SIER;
567 } else {
568 srccr = SSI2_SRCCR & ~SSI_SRCCR_WL_MASK;
569 srcr = SSI2_SRCR;
570 sier = SSI2_SIER;
571 }
572
573 /* DAI data (word) size */
574 switch (params_format(params)) {
575 case SNDRV_PCM_FORMAT_S16_LE:
576 srccr |= SSI_SRCCR_WL(16);
577 break;
578 case SNDRV_PCM_FORMAT_S20_3LE:
579 srccr |= SSI_SRCCR_WL(20);
580 break;
581 case SNDRV_PCM_FORMAT_S24_LE:
582 srccr |= SSI_SRCCR_WL(24);
583 break;
584 }
585
586 /* enable interrupts */
587 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2)
588 srcr |= SSI_SRCR_RFEN0;
589 else
590 srcr |= SSI_SRCR_RFEN1;
591 sier |= SSI_SIER_RDMAE;
592
593 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
594 SSI1_SRCR = srcr;
595 SSI1_SRCCR = srccr;
596 SSI1_SIER = sier;
597 } else {
598 SSI2_SRCR = srcr;
599 SSI2_SRCCR = srccr;
600 SSI2_SIER = sier;
601 }
602
603 return 0;
604}
605
606/*
607 * Should only be called when port is inactive (i.e. SSIEN = 0),
608 * although can be called multiple times by upper layers.
609 */
610int imx_ssi_hw_params(struct snd_pcm_substream *substream,
611 struct snd_pcm_hw_params *params,
612 struct snd_soc_dai *dai)
613{
614 struct snd_soc_pcm_runtime *rtd = substream->private_data;
615 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
616
617 int ret;
618
619 /* cant change any parameters when SSI is running */
620 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
621 if (SSI1_SCR & SSI_SCR_SSIEN) {
622 printk(KERN_WARNING "Warning ssi already enabled\n");
623 return 0;
624 }
625 } else {
626 if (SSI2_SCR & SSI_SCR_SSIEN) {
627 printk(KERN_WARNING "Warning ssi already enabled\n");
628 return 0;
629 }
630 }
631
632 /*
633 * Configure both tx and rx params with the same settings. This is
634 * really a harware restriction because SSI must be disabled until
635 * we can change those values. If there is an active audio stream in
636 * one direction, enabling the other direction with different
637 * settings would mean disturbing the running one.
638 */
639 ret = imx_ssi_hw_tx_params(substream, params);
640 if (ret < 0)
641 return ret;
642 return imx_ssi_hw_rx_params(substream, params);
643}
644
645int imx_ssi_prepare(struct snd_pcm_substream *substream,
646 struct snd_soc_dai *dai)
647{
648 struct snd_soc_pcm_runtime *rtd = substream->private_data;
649 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
650 int ret;
651
652 pr_debug("%s\n", __func__);
653
654 /* Enable clks here to follow SSI recommended init sequence */
655 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
656 ret = clk_enable(ssi_clk0);
657 if (ret < 0)
658 printk(KERN_ERR "Unable to enable ssi_clk0\n");
659 } else {
660 ret = clk_enable(ssi_clk1);
661 if (ret < 0)
662 printk(KERN_ERR "Unable to enable ssi_clk1\n");
663 }
664
665 return 0;
666}
667
668static int imx_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
669 struct snd_soc_dai *dai)
670{
671 struct snd_soc_pcm_runtime *rtd = substream->private_data;
672 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
673 u32 scr;
674
675 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2)
676 scr = SSI1_SCR;
677 else
678 scr = SSI2_SCR;
679
680 switch (cmd) {
681 case SNDRV_PCM_TRIGGER_START:
682 case SNDRV_PCM_TRIGGER_RESUME:
683 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
684 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
685 scr |= SSI_SCR_TE | SSI_SCR_SSIEN;
686 else
687 scr |= SSI_SCR_RE | SSI_SCR_SSIEN;
688 break;
689 case SNDRV_PCM_TRIGGER_SUSPEND:
690 case SNDRV_PCM_TRIGGER_STOP:
691 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
692 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
693 scr &= ~SSI_SCR_TE;
694 else
695 scr &= ~SSI_SCR_RE;
696 break;
697 default:
698 return -EINVAL;
699 }
700
701 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2)
702 SSI1_SCR = scr;
703 else
704 SSI2_SCR = scr;
705
706 return 0;
707}
708
709static void imx_ssi_shutdown(struct snd_pcm_substream *substream,
710 struct snd_soc_dai *dai)
711{
712 struct snd_soc_pcm_runtime *rtd = substream->private_data;
713 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
714
715 /* shutdown SSI if neither Tx or Rx is active */
716 if (!cpu_dai->active) {
717
718 if (cpu_dai->id == IMX_DAI_SSI0 ||
719 cpu_dai->id == IMX_DAI_SSI2) {
720
721 if (--ssi_active[SSI1_PORT] > 1)
722 return;
723
724 SSI1_SCR = 0;
725 clk_disable(ssi_clk0);
726 } else {
727 if (--ssi_active[SSI2_PORT])
728 return;
729 SSI2_SCR = 0;
730 clk_disable(ssi_clk1);
731 }
732 }
733}
734
735#ifdef CONFIG_PM
736static int imx_ssi_suspend(struct platform_device *dev,
737 struct snd_soc_dai *dai)
738{
739 return 0;
740}
741
742static int imx_ssi_resume(struct platform_device *pdev,
743 struct snd_soc_dai *dai)
744{
745 return 0;
746}
747
748#else
749#define imx_ssi_suspend NULL
750#define imx_ssi_resume NULL
751#endif
752
753#define IMX_SSI_RATES \
754 (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | \
755 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \
756 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
757 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | \
758 SNDRV_PCM_RATE_96000)
759
760#define IMX_SSI_BITS \
761 (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
762 SNDRV_PCM_FMTBIT_S24_LE)
763
764static struct snd_soc_dai_ops imx_ssi_pcm_dai_ops = {
765 .startup = imx_ssi_startup,
766 .shutdown = imx_ssi_shutdown,
767 .trigger = imx_ssi_trigger,
768 .prepare = imx_ssi_prepare,
769 .hw_params = imx_ssi_hw_params,
770 .set_sysclk = imx_ssi_set_dai_sysclk,
771 .set_clkdiv = imx_ssi_set_dai_clkdiv,
772 .set_fmt = imx_ssi_set_dai_fmt,
773 .set_tdm_slot = imx_ssi_set_dai_tdm_slot,
774};
775
776struct snd_soc_dai imx_ssi_pcm_dai[] = {
777{
778 .name = "imx-i2s-1-0",
779 .id = IMX_DAI_SSI0,
780 .suspend = imx_ssi_suspend,
781 .resume = imx_ssi_resume,
782 .playback = {
783 .channels_min = 1,
784 .channels_max = 2,
785 .formats = IMX_SSI_BITS,
786 .rates = IMX_SSI_RATES,},
787 .capture = {
788 .channels_min = 1,
789 .channels_max = 2,
790 .formats = IMX_SSI_BITS,
791 .rates = IMX_SSI_RATES,},
792 .ops = &imx_ssi_pcm_dai_ops,
793},
794{
795 .name = "imx-i2s-2-0",
796 .id = IMX_DAI_SSI1,
797 .playback = {
798 .channels_min = 1,
799 .channels_max = 2,
800 .formats = IMX_SSI_BITS,
801 .rates = IMX_SSI_RATES,},
802 .capture = {
803 .channels_min = 1,
804 .channels_max = 2,
805 .formats = IMX_SSI_BITS,
806 .rates = IMX_SSI_RATES,},
807 .ops = &imx_ssi_pcm_dai_ops,
808},
809{
810 .name = "imx-i2s-1-1",
811 .id = IMX_DAI_SSI2,
812 .suspend = imx_ssi_suspend,
813 .resume = imx_ssi_resume,
814 .playback = {
815 .channels_min = 1,
816 .channels_max = 2,
817 .formats = IMX_SSI_BITS,
818 .rates = IMX_SSI_RATES,},
819 .capture = {
820 .channels_min = 1,
821 .channels_max = 2,
822 .formats = IMX_SSI_BITS,
823 .rates = IMX_SSI_RATES,},
824 .ops = &imx_ssi_pcm_dai_ops,
825},
826{
827 .name = "imx-i2s-2-1",
828 .id = IMX_DAI_SSI3,
829 .playback = {
830 .channels_min = 1,
831 .channels_max = 2,
832 .formats = IMX_SSI_BITS,
833 .rates = IMX_SSI_RATES,},
834 .capture = {
835 .channels_min = 1,
836 .channels_max = 2,
837 .formats = IMX_SSI_BITS,
838 .rates = IMX_SSI_RATES,},
839 .ops = &imx_ssi_pcm_dai_ops,
840},
841};
842EXPORT_SYMBOL_GPL(imx_ssi_pcm_dai);
843
844static int __init imx_ssi_init(void)
845{
846 return snd_soc_register_dais(imx_ssi_pcm_dai,
847 ARRAY_SIZE(imx_ssi_pcm_dai));
848}
849
850static void __exit imx_ssi_exit(void)
851{
852 snd_soc_unregister_dais(imx_ssi_pcm_dai,
853 ARRAY_SIZE(imx_ssi_pcm_dai));
854}
855
856module_init(imx_ssi_init);
857module_exit(imx_ssi_exit);
858MODULE_AUTHOR("Liam Girdwood, liam.girdwood@wolfsonmicro.com");
859MODULE_DESCRIPTION("i.MX ASoC I2S driver");
860MODULE_LICENSE("GPL");
diff --git a/sound/soc/imx/mxc-ssi.h b/sound/soc/imx/mxc-ssi.h
deleted file mode 100644
index 12bbdc9c7ecd..000000000000
--- a/sound/soc/imx/mxc-ssi.h
+++ /dev/null
@@ -1,238 +0,0 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License version 2 as
4 * published by the Free Software Foundation.
5 */
6
7#ifndef _IMX_SSI_H
8#define _IMX_SSI_H
9
10#include <mach/hardware.h>
11
12/* SSI regs definition - MOVE to /arch/arm/plat-mxc/include/mach/ when stable */
13#define SSI1_IO_BASE_ADDR IO_ADDRESS(SSI1_BASE_ADDR)
14#define SSI2_IO_BASE_ADDR IO_ADDRESS(SSI2_BASE_ADDR)
15
16#define STX0 0x00
17#define STX1 0x04
18#define SRX0 0x08
19#define SRX1 0x0c
20#define SCR 0x10
21#define SISR 0x14
22#define SIER 0x18
23#define STCR 0x1c
24#define SRCR 0x20
25#define STCCR 0x24
26#define SRCCR 0x28
27#define SFCSR 0x2c
28#define STR 0x30
29#define SOR 0x34
30#define SACNT 0x38
31#define SACADD 0x3c
32#define SACDAT 0x40
33#define SATAG 0x44
34#define STMSK 0x48
35#define SRMSK 0x4c
36
37#define SSI1_STX0 (*((volatile u32 *)(SSI1_IO_BASE_ADDR + STX0)))
38#define SSI1_STX1 (*((volatile u32 *)(SSI1_IO_BASE_ADDR + STX1)))
39#define SSI1_SRX0 (*((volatile u32 *)(SSI1_IO_BASE_ADDR + SRX0)))
40#define SSI1_SRX1 (*((volatile u32 *)(SSI1_IO_BASE_ADDR + SRX1)))
41#define SSI1_SCR (*((volatile u32 *)(SSI1_IO_BASE_ADDR + SCR)))
42#define SSI1_SISR (*((volatile u32 *)(SSI1_IO_BASE_ADDR + SISR)))
43#define SSI1_SIER (*((volatile u32 *)(SSI1_IO_BASE_ADDR + SIER)))
44#define SSI1_STCR (*((volatile u32 *)(SSI1_IO_BASE_ADDR + STCR)))
45#define SSI1_SRCR (*((volatile u32 *)(SSI1_IO_BASE_ADDR + SRCR)))
46#define SSI1_STCCR (*((volatile u32 *)(SSI1_IO_BASE_ADDR + STCCR)))
47#define SSI1_SRCCR (*((volatile u32 *)(SSI1_IO_BASE_ADDR + SRCCR)))
48#define SSI1_SFCSR (*((volatile u32 *)(SSI1_IO_BASE_ADDR + SFCSR)))
49#define SSI1_STR (*((volatile u32 *)(SSI1_IO_BASE_ADDR + STR)))
50#define SSI1_SOR (*((volatile u32 *)(SSI1_IO_BASE_ADDR + SOR)))
51#define SSI1_SACNT (*((volatile u32 *)(SSI1_IO_BASE_ADDR + SACNT)))
52#define SSI1_SACADD (*((volatile u32 *)(SSI1_IO_BASE_ADDR + SACADD)))
53#define SSI1_SACDAT (*((volatile u32 *)(SSI1_IO_BASE_ADDR + SACDAT)))
54#define SSI1_SATAG (*((volatile u32 *)(SSI1_IO_BASE_ADDR + SATAG)))
55#define SSI1_STMSK (*((volatile u32 *)(SSI1_IO_BASE_ADDR + STMSK)))
56#define SSI1_SRMSK (*((volatile u32 *)(SSI1_IO_BASE_ADDR + SRMSK)))
57
58
59#define SSI2_STX0 (*((volatile u32 *)(SSI2_IO_BASE_ADDR + STX0)))
60#define SSI2_STX1 (*((volatile u32 *)(SSI2_IO_BASE_ADDR + STX1)))
61#define SSI2_SRX0 (*((volatile u32 *)(SSI2_IO_BASE_ADDR + SRX0)))
62#define SSI2_SRX1 (*((volatile u32 *)(SSI2_IO_BASE_ADDR + SRX1)))
63#define SSI2_SCR (*((volatile u32 *)(SSI2_IO_BASE_ADDR + SCR)))
64#define SSI2_SISR (*((volatile u32 *)(SSI2_IO_BASE_ADDR + SISR)))
65#define SSI2_SIER (*((volatile u32 *)(SSI2_IO_BASE_ADDR + SIER)))
66#define SSI2_STCR (*((volatile u32 *)(SSI2_IO_BASE_ADDR + STCR)))
67#define SSI2_SRCR (*((volatile u32 *)(SSI2_IO_BASE_ADDR + SRCR)))
68#define SSI2_STCCR (*((volatile u32 *)(SSI2_IO_BASE_ADDR + STCCR)))
69#define SSI2_SRCCR (*((volatile u32 *)(SSI2_IO_BASE_ADDR + SRCCR)))
70#define SSI2_SFCSR (*((volatile u32 *)(SSI2_IO_BASE_ADDR + SFCSR)))
71#define SSI2_STR (*((volatile u32 *)(SSI2_IO_BASE_ADDR + STR)))
72#define SSI2_SOR (*((volatile u32 *)(SSI2_IO_BASE_ADDR + SOR)))
73#define SSI2_SACNT (*((volatile u32 *)(SSI2_IO_BASE_ADDR + SACNT)))
74#define SSI2_SACADD (*((volatile u32 *)(SSI2_IO_BASE_ADDR + SACADD)))
75#define SSI2_SACDAT (*((volatile u32 *)(SSI2_IO_BASE_ADDR + SACDAT)))
76#define SSI2_SATAG (*((volatile u32 *)(SSI2_IO_BASE_ADDR + SATAG)))
77#define SSI2_STMSK (*((volatile u32 *)(SSI2_IO_BASE_ADDR + STMSK)))
78#define SSI2_SRMSK (*((volatile u32 *)(SSI2_IO_BASE_ADDR + SRMSK)))
79
80#define SSI_SCR_CLK_IST (1 << 9)
81#define SSI_SCR_TCH_EN (1 << 8)
82#define SSI_SCR_SYS_CLK_EN (1 << 7)
83#define SSI_SCR_I2S_MODE_NORM (0 << 5)
84#define SSI_SCR_I2S_MODE_MSTR (1 << 5)
85#define SSI_SCR_I2S_MODE_SLAVE (2 << 5)
86#define SSI_SCR_SYN (1 << 4)
87#define SSI_SCR_NET (1 << 3)
88#define SSI_SCR_RE (1 << 2)
89#define SSI_SCR_TE (1 << 1)
90#define SSI_SCR_SSIEN (1 << 0)
91
92#define SSI_SISR_CMDAU (1 << 18)
93#define SSI_SISR_CMDDU (1 << 17)
94#define SSI_SISR_RXT (1 << 16)
95#define SSI_SISR_RDR1 (1 << 15)
96#define SSI_SISR_RDR0 (1 << 14)
97#define SSI_SISR_TDE1 (1 << 13)
98#define SSI_SISR_TDE0 (1 << 12)
99#define SSI_SISR_ROE1 (1 << 11)
100#define SSI_SISR_ROE0 (1 << 10)
101#define SSI_SISR_TUE1 (1 << 9)
102#define SSI_SISR_TUE0 (1 << 8)
103#define SSI_SISR_TFS (1 << 7)
104#define SSI_SISR_RFS (1 << 6)
105#define SSI_SISR_TLS (1 << 5)
106#define SSI_SISR_RLS (1 << 4)
107#define SSI_SISR_RFF1 (1 << 3)
108#define SSI_SISR_RFF0 (1 << 2)
109#define SSI_SISR_TFE1 (1 << 1)
110#define SSI_SISR_TFE0 (1 << 0)
111
112#define SSI_SIER_RDMAE (1 << 22)
113#define SSI_SIER_RIE (1 << 21)
114#define SSI_SIER_TDMAE (1 << 20)
115#define SSI_SIER_TIE (1 << 19)
116#define SSI_SIER_CMDAU_EN (1 << 18)
117#define SSI_SIER_CMDDU_EN (1 << 17)
118#define SSI_SIER_RXT_EN (1 << 16)
119#define SSI_SIER_RDR1_EN (1 << 15)
120#define SSI_SIER_RDR0_EN (1 << 14)
121#define SSI_SIER_TDE1_EN (1 << 13)
122#define SSI_SIER_TDE0_EN (1 << 12)
123#define SSI_SIER_ROE1_EN (1 << 11)
124#define SSI_SIER_ROE0_EN (1 << 10)
125#define SSI_SIER_TUE1_EN (1 << 9)
126#define SSI_SIER_TUE0_EN (1 << 8)
127#define SSI_SIER_TFS_EN (1 << 7)
128#define SSI_SIER_RFS_EN (1 << 6)
129#define SSI_SIER_TLS_EN (1 << 5)
130#define SSI_SIER_RLS_EN (1 << 4)
131#define SSI_SIER_RFF1_EN (1 << 3)
132#define SSI_SIER_RFF0_EN (1 << 2)
133#define SSI_SIER_TFE1_EN (1 << 1)
134#define SSI_SIER_TFE0_EN (1 << 0)
135
136#define SSI_STCR_TXBIT0 (1 << 9)
137#define SSI_STCR_TFEN1 (1 << 8)
138#define SSI_STCR_TFEN0 (1 << 7)
139#define SSI_STCR_TFDIR (1 << 6)
140#define SSI_STCR_TXDIR (1 << 5)
141#define SSI_STCR_TSHFD (1 << 4)
142#define SSI_STCR_TSCKP (1 << 3)
143#define SSI_STCR_TFSI (1 << 2)
144#define SSI_STCR_TFSL (1 << 1)
145#define SSI_STCR_TEFS (1 << 0)
146
147#define SSI_SRCR_RXBIT0 (1 << 9)
148#define SSI_SRCR_RFEN1 (1 << 8)
149#define SSI_SRCR_RFEN0 (1 << 7)
150#define SSI_SRCR_RFDIR (1 << 6)
151#define SSI_SRCR_RXDIR (1 << 5)
152#define SSI_SRCR_RSHFD (1 << 4)
153#define SSI_SRCR_RSCKP (1 << 3)
154#define SSI_SRCR_RFSI (1 << 2)
155#define SSI_SRCR_RFSL (1 << 1)
156#define SSI_SRCR_REFS (1 << 0)
157
158#define SSI_STCCR_DIV2 (1 << 18)
159#define SSI_STCCR_PSR (1 << 15)
160#define SSI_STCCR_WL(x) ((((x) - 2) >> 1) << 13)
161#define SSI_STCCR_DC(x) (((x) & 0x1f) << 8)
162#define SSI_STCCR_PM(x) (((x) & 0xff) << 0)
163#define SSI_STCCR_WL_MASK (0xf << 13)
164#define SSI_STCCR_DC_MASK (0x1f << 8)
165#define SSI_STCCR_PM_MASK (0xff << 0)
166
167#define SSI_SRCCR_DIV2 (1 << 18)
168#define SSI_SRCCR_PSR (1 << 15)
169#define SSI_SRCCR_WL(x) ((((x) - 2) >> 1) << 13)
170#define SSI_SRCCR_DC(x) (((x) & 0x1f) << 8)
171#define SSI_SRCCR_PM(x) (((x) & 0xff) << 0)
172#define SSI_SRCCR_WL_MASK (0xf << 13)
173#define SSI_SRCCR_DC_MASK (0x1f << 8)
174#define SSI_SRCCR_PM_MASK (0xff << 0)
175
176
177#define SSI_SFCSR_RFCNT1(x) (((x) & 0xf) << 28)
178#define SSI_SFCSR_TFCNT1(x) (((x) & 0xf) << 24)
179#define SSI_SFCSR_RFWM1(x) (((x) & 0xf) << 20)
180#define SSI_SFCSR_TFWM1(x) (((x) & 0xf) << 16)
181#define SSI_SFCSR_RFCNT0(x) (((x) & 0xf) << 12)
182#define SSI_SFCSR_TFCNT0(x) (((x) & 0xf) << 8)
183#define SSI_SFCSR_RFWM0(x) (((x) & 0xf) << 4)
184#define SSI_SFCSR_TFWM0(x) (((x) & 0xf) << 0)
185
186#define SSI_STR_TEST (1 << 15)
187#define SSI_STR_RCK2TCK (1 << 14)
188#define SSI_STR_RFS2TFS (1 << 13)
189#define SSI_STR_RXSTATE(x) (((x) & 0xf) << 8)
190#define SSI_STR_TXD2RXD (1 << 7)
191#define SSI_STR_TCK2RCK (1 << 6)
192#define SSI_STR_TFS2RFS (1 << 5)
193#define SSI_STR_TXSTATE(x) (((x) & 0xf) << 0)
194
195#define SSI_SOR_CLKOFF (1 << 6)
196#define SSI_SOR_RX_CLR (1 << 5)
197#define SSI_SOR_TX_CLR (1 << 4)
198#define SSI_SOR_INIT (1 << 3)
199#define SSI_SOR_WAIT(x) (((x) & 0x3) << 1)
200#define SSI_SOR_SYNRST (1 << 0)
201
202#define SSI_SACNT_FRDIV(x) (((x) & 0x3f) << 5)
203#define SSI_SACNT_WR (x << 4)
204#define SSI_SACNT_RD (x << 3)
205#define SSI_SACNT_TIF (x << 2)
206#define SSI_SACNT_FV (x << 1)
207#define SSI_SACNT_AC97EN (x << 0)
208
209/* Watermarks for FIFO's */
210#define TXFIFO_WATERMARK 0x4
211#define RXFIFO_WATERMARK 0x4
212
213/* i.MX DAI SSP ID's */
214#define IMX_DAI_SSI0 0 /* SSI1 FIFO 0 */
215#define IMX_DAI_SSI1 1 /* SSI1 FIFO 1 */
216#define IMX_DAI_SSI2 2 /* SSI2 FIFO 0 */
217#define IMX_DAI_SSI3 3 /* SSI2 FIFO 1 */
218
219/* SSI clock sources */
220#define IMX_SSP_SYS_CLK 0
221
222/* SSI audio dividers */
223#define IMX_SSI_TX_DIV_2 0
224#define IMX_SSI_TX_DIV_PSR 1
225#define IMX_SSI_TX_DIV_PM 2
226#define IMX_SSI_RX_DIV_2 3
227#define IMX_SSI_RX_DIV_PSR 4
228#define IMX_SSI_RX_DIV_PM 5
229
230
231/* SSI Div 2 */
232#define IMX_SSI_DIV_2_OFF (~SSI_STCCR_DIV2)
233#define IMX_SSI_DIV_2_ON SSI_STCCR_DIV2
234
235extern struct snd_soc_dai imx_ssi_pcm_dai[4];
236extern int get_ssi_clk(int ssi, struct device *dev);
237extern void put_ssi_clk(int ssi);
238#endif
diff --git a/sound/soc/imx/phycore-ac97.c b/sound/soc/imx/phycore-ac97.c
new file mode 100644
index 000000000000..a8307d55c70e
--- /dev/null
+++ b/sound/soc/imx/phycore-ac97.c
@@ -0,0 +1,90 @@
1/*
2 * phycore-ac97.c -- SoC audio for imx_phycore in AC97 mode
3 *
4 * Copyright 2009 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 */
12
13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/device.h>
16#include <linux/i2c.h>
17#include <sound/core.h>
18#include <sound/pcm.h>
19#include <sound/soc.h>
20#include <sound/soc-dapm.h>
21#include <asm/mach-types.h>
22
23#include "../codecs/wm9712.h"
24#include "imx-ssi.h"
25
26static struct snd_soc_card imx_phycore;
27
28static struct snd_soc_ops imx_phycore_hifi_ops = {
29};
30
31static struct snd_soc_dai_link imx_phycore_dai_ac97[] = {
32 {
33 .name = "HiFi",
34 .stream_name = "HiFi",
35 .codec_dai = &wm9712_dai[WM9712_DAI_AC97_HIFI],
36 .ops = &imx_phycore_hifi_ops,
37 },
38};
39
40static struct snd_soc_card imx_phycore = {
41 .name = "PhyCORE-audio",
42 .platform = &imx_soc_platform,
43 .dai_link = imx_phycore_dai_ac97,
44 .num_links = ARRAY_SIZE(imx_phycore_dai_ac97),
45};
46
47static struct snd_soc_device imx_phycore_snd_devdata = {
48 .card = &imx_phycore,
49 .codec_dev = &soc_codec_dev_wm9712,
50};
51
52static struct platform_device *imx_phycore_snd_device;
53
54static int __init imx_phycore_init(void)
55{
56 int ret;
57
58 if (!machine_is_pcm043() && !machine_is_pca100())
59 /* return happy. We might run on a totally different machine */
60 return 0;
61
62 imx_phycore_snd_device = platform_device_alloc("soc-audio", -1);
63 if (!imx_phycore_snd_device)
64 return -ENOMEM;
65
66 imx_phycore_dai_ac97[0].cpu_dai = &imx_ssi_pcm_dai[0];
67
68 platform_set_drvdata(imx_phycore_snd_device, &imx_phycore_snd_devdata);
69 imx_phycore_snd_devdata.dev = &imx_phycore_snd_device->dev;
70 ret = platform_device_add(imx_phycore_snd_device);
71
72 if (ret) {
73 printk(KERN_ERR "ASoC: Platform device allocation failed\n");
74 platform_device_put(imx_phycore_snd_device);
75 }
76
77 return ret;
78}
79
80static void __exit imx_phycore_exit(void)
81{
82 platform_device_unregister(imx_phycore_snd_device);
83}
84
85late_initcall(imx_phycore_init);
86module_exit(imx_phycore_exit);
87
88MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
89MODULE_DESCRIPTION("PhyCORE ALSA SoC driver");
90MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
index 61952aa6cd5a..f11963c21873 100644
--- a/sound/soc/omap/Kconfig
+++ b/sound/soc/omap/Kconfig
@@ -6,6 +6,9 @@ config SND_OMAP_SOC_MCBSP
6 tristate 6 tristate
7 select OMAP_MCBSP 7 select OMAP_MCBSP
8 8
9config SND_OMAP_SOC_MCPDM
10 tristate
11
9config SND_OMAP_SOC_N810 12config SND_OMAP_SOC_N810
10 tristate "SoC Audio support for Nokia N810" 13 tristate "SoC Audio support for Nokia N810"
11 depends on SND_OMAP_SOC && MACH_NOKIA_N810 && I2C 14 depends on SND_OMAP_SOC && MACH_NOKIA_N810 && I2C
@@ -94,12 +97,14 @@ config SND_OMAP_SOC_OMAP3_PANDORA
94 Say Y if you want to add support for SoC audio on the OMAP3 Pandora. 97 Say Y if you want to add support for SoC audio on the OMAP3 Pandora.
95 98
96config SND_OMAP_SOC_OMAP3_BEAGLE 99config SND_OMAP_SOC_OMAP3_BEAGLE
97 tristate "SoC Audio support for OMAP3 Beagle" 100 tristate "SoC Audio support for OMAP3 Beagle and Devkit8000"
98 depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP3_BEAGLE 101 depends on TWL4030_CORE && SND_OMAP_SOC
102 depends on (MACH_OMAP3_BEAGLE || MACH_DEVKIT8000)
99 select SND_OMAP_SOC_MCBSP 103 select SND_OMAP_SOC_MCBSP
100 select SND_SOC_TWL4030 104 select SND_SOC_TWL4030
101 help 105 help
102 Say Y if you want to add support for SoC audio on the Beagleboard. 106 Say Y if you want to add support for SoC audio on the Beagleboard or
107 the clone Devkit8000.
103 108
104config SND_OMAP_SOC_ZOOM2 109config SND_OMAP_SOC_ZOOM2
105 tristate "SoC Audio support for Zoom2" 110 tristate "SoC Audio support for Zoom2"
diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile
index 19283e5edfbf..0bc00ca14b37 100644
--- a/sound/soc/omap/Makefile
+++ b/sound/soc/omap/Makefile
@@ -1,9 +1,11 @@
1# OMAP Platform Support 1# OMAP Platform Support
2snd-soc-omap-objs := omap-pcm.o 2snd-soc-omap-objs := omap-pcm.o
3snd-soc-omap-mcbsp-objs := omap-mcbsp.o 3snd-soc-omap-mcbsp-objs := omap-mcbsp.o
4snd-soc-omap-mcpdm-objs := omap-mcpdm.o mcpdm.o
4 5
5obj-$(CONFIG_SND_OMAP_SOC) += snd-soc-omap.o 6obj-$(CONFIG_SND_OMAP_SOC) += snd-soc-omap.o
6obj-$(CONFIG_SND_OMAP_SOC_MCBSP) += snd-soc-omap-mcbsp.o 7obj-$(CONFIG_SND_OMAP_SOC_MCBSP) += snd-soc-omap-mcbsp.o
8obj-$(CONFIG_SND_OMAP_SOC_MCPDM) += snd-soc-omap-mcpdm.o
7 9
8# OMAP Machine Support 10# OMAP Machine Support
9snd-soc-n810-objs := n810.o 11snd-soc-n810-objs := n810.o
diff --git a/sound/soc/omap/mcpdm.c b/sound/soc/omap/mcpdm.c
new file mode 100644
index 000000000000..ad8df6cfae88
--- /dev/null
+++ b/sound/soc/omap/mcpdm.c
@@ -0,0 +1,484 @@
1/*
2 * mcpdm.c -- McPDM interface driver
3 *
4 * Author: Jorge Eduardo Candelaria <x0107209@ti.com>
5 * Copyright (C) 2009 - Texas Instruments, 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/init.h>
25#include <linux/device.h>
26#include <linux/platform_device.h>
27#include <linux/wait.h>
28#include <linux/interrupt.h>
29#include <linux/err.h>
30#include <linux/clk.h>
31#include <linux/delay.h>
32#include <linux/io.h>
33#include <linux/irq.h>
34
35#include "mcpdm.h"
36
37static struct omap_mcpdm *mcpdm;
38
39static inline void omap_mcpdm_write(u16 reg, u32 val)
40{
41 __raw_writel(val, mcpdm->io_base + reg);
42}
43
44static inline int omap_mcpdm_read(u16 reg)
45{
46 return __raw_readl(mcpdm->io_base + reg);
47}
48
49static void omap_mcpdm_reg_dump(void)
50{
51 dev_dbg(mcpdm->dev, "***********************\n");
52 dev_dbg(mcpdm->dev, "IRQSTATUS_RAW: 0x%04x\n",
53 omap_mcpdm_read(MCPDM_IRQSTATUS_RAW));
54 dev_dbg(mcpdm->dev, "IRQSTATUS: 0x%04x\n",
55 omap_mcpdm_read(MCPDM_IRQSTATUS));
56 dev_dbg(mcpdm->dev, "IRQENABLE_SET: 0x%04x\n",
57 omap_mcpdm_read(MCPDM_IRQENABLE_SET));
58 dev_dbg(mcpdm->dev, "IRQENABLE_CLR: 0x%04x\n",
59 omap_mcpdm_read(MCPDM_IRQENABLE_CLR));
60 dev_dbg(mcpdm->dev, "IRQWAKE_EN: 0x%04x\n",
61 omap_mcpdm_read(MCPDM_IRQWAKE_EN));
62 dev_dbg(mcpdm->dev, "DMAENABLE_SET: 0x%04x\n",
63 omap_mcpdm_read(MCPDM_DMAENABLE_SET));
64 dev_dbg(mcpdm->dev, "DMAENABLE_CLR: 0x%04x\n",
65 omap_mcpdm_read(MCPDM_DMAENABLE_CLR));
66 dev_dbg(mcpdm->dev, "DMAWAKEEN: 0x%04x\n",
67 omap_mcpdm_read(MCPDM_DMAWAKEEN));
68 dev_dbg(mcpdm->dev, "CTRL: 0x%04x\n",
69 omap_mcpdm_read(MCPDM_CTRL));
70 dev_dbg(mcpdm->dev, "DN_DATA: 0x%04x\n",
71 omap_mcpdm_read(MCPDM_DN_DATA));
72 dev_dbg(mcpdm->dev, "UP_DATA: 0x%04x\n",
73 omap_mcpdm_read(MCPDM_UP_DATA));
74 dev_dbg(mcpdm->dev, "FIFO_CTRL_DN: 0x%04x\n",
75 omap_mcpdm_read(MCPDM_FIFO_CTRL_DN));
76 dev_dbg(mcpdm->dev, "FIFO_CTRL_UP: 0x%04x\n",
77 omap_mcpdm_read(MCPDM_FIFO_CTRL_UP));
78 dev_dbg(mcpdm->dev, "DN_OFFSET: 0x%04x\n",
79 omap_mcpdm_read(MCPDM_DN_OFFSET));
80 dev_dbg(mcpdm->dev, "***********************\n");
81}
82
83/*
84 * Takes the McPDM module in and out of reset state.
85 * Uplink and downlink can be reset individually.
86 */
87static void omap_mcpdm_reset_capture(int reset)
88{
89 int ctrl = omap_mcpdm_read(MCPDM_CTRL);
90
91 if (reset)
92 ctrl |= SW_UP_RST;
93 else
94 ctrl &= ~SW_UP_RST;
95
96 omap_mcpdm_write(MCPDM_CTRL, ctrl);
97}
98
99static void omap_mcpdm_reset_playback(int reset)
100{
101 int ctrl = omap_mcpdm_read(MCPDM_CTRL);
102
103 if (reset)
104 ctrl |= SW_DN_RST;
105 else
106 ctrl &= ~SW_DN_RST;
107
108 omap_mcpdm_write(MCPDM_CTRL, ctrl);
109}
110
111/*
112 * Enables the transfer through the PDM interface to/from the Phoenix
113 * codec by enabling the corresponding UP or DN channels.
114 */
115void omap_mcpdm_start(int stream)
116{
117 int ctrl = omap_mcpdm_read(MCPDM_CTRL);
118
119 if (stream)
120 ctrl |= mcpdm->up_channels;
121 else
122 ctrl |= mcpdm->dn_channels;
123
124 omap_mcpdm_write(MCPDM_CTRL, ctrl);
125}
126
127/*
128 * Disables the transfer through the PDM interface to/from the Phoenix
129 * codec by disabling the corresponding UP or DN channels.
130 */
131void omap_mcpdm_stop(int stream)
132{
133 int ctrl = omap_mcpdm_read(MCPDM_CTRL);
134
135 if (stream)
136 ctrl &= ~mcpdm->up_channels;
137 else
138 ctrl &= ~mcpdm->dn_channels;
139
140 omap_mcpdm_write(MCPDM_CTRL, ctrl);
141}
142
143/*
144 * Configures McPDM uplink for audio recording.
145 * This function should be called before omap_mcpdm_start.
146 */
147int omap_mcpdm_capture_open(struct omap_mcpdm_link *uplink)
148{
149 int irq_mask = 0;
150 int ctrl;
151
152 if (!uplink)
153 return -EINVAL;
154
155 mcpdm->uplink = uplink;
156
157 /* Enable irq request generation */
158 irq_mask |= uplink->irq_mask & MCPDM_UPLINK_IRQ_MASK;
159 omap_mcpdm_write(MCPDM_IRQENABLE_SET, irq_mask);
160
161 /* Configure uplink threshold */
162 if (uplink->threshold > UP_THRES_MAX)
163 uplink->threshold = UP_THRES_MAX;
164
165 omap_mcpdm_write(MCPDM_FIFO_CTRL_UP, uplink->threshold);
166
167 /* Configure DMA controller */
168 omap_mcpdm_write(MCPDM_DMAENABLE_SET, DMA_UP_ENABLE);
169
170 /* Set pdm out format */
171 ctrl = omap_mcpdm_read(MCPDM_CTRL);
172 ctrl &= ~PDMOUTFORMAT;
173 ctrl |= uplink->format & PDMOUTFORMAT;
174
175 /* Uplink channels */
176 mcpdm->up_channels = uplink->channels & (PDM_UP_MASK | PDM_STATUS_MASK);
177
178 omap_mcpdm_write(MCPDM_CTRL, ctrl);
179
180 return 0;
181}
182
183/*
184 * Configures McPDM downlink for audio playback.
185 * This function should be called before omap_mcpdm_start.
186 */
187int omap_mcpdm_playback_open(struct omap_mcpdm_link *downlink)
188{
189 int irq_mask = 0;
190 int ctrl;
191
192 if (!downlink)
193 return -EINVAL;
194
195 mcpdm->downlink = downlink;
196
197 /* Enable irq request generation */
198 irq_mask |= downlink->irq_mask & MCPDM_DOWNLINK_IRQ_MASK;
199 omap_mcpdm_write(MCPDM_IRQENABLE_SET, irq_mask);
200
201 /* Configure uplink threshold */
202 if (downlink->threshold > DN_THRES_MAX)
203 downlink->threshold = DN_THRES_MAX;
204
205 omap_mcpdm_write(MCPDM_FIFO_CTRL_DN, downlink->threshold);
206
207 /* Enable DMA request generation */
208 omap_mcpdm_write(MCPDM_DMAENABLE_SET, DMA_DN_ENABLE);
209
210 /* Set pdm out format */
211 ctrl = omap_mcpdm_read(MCPDM_CTRL);
212 ctrl &= ~PDMOUTFORMAT;
213 ctrl |= downlink->format & PDMOUTFORMAT;
214
215 /* Downlink channels */
216 mcpdm->dn_channels = downlink->channels & (PDM_DN_MASK | PDM_CMD_MASK);
217
218 omap_mcpdm_write(MCPDM_CTRL, ctrl);
219
220 return 0;
221}
222
223/*
224 * Cleans McPDM uplink configuration.
225 * This function should be called when the stream is closed.
226 */
227int omap_mcpdm_capture_close(struct omap_mcpdm_link *uplink)
228{
229 int irq_mask = 0;
230
231 if (!uplink)
232 return -EINVAL;
233
234 /* Disable irq request generation */
235 irq_mask |= uplink->irq_mask & MCPDM_UPLINK_IRQ_MASK;
236 omap_mcpdm_write(MCPDM_IRQENABLE_CLR, irq_mask);
237
238 /* Disable DMA request generation */
239 omap_mcpdm_write(MCPDM_DMAENABLE_CLR, DMA_UP_ENABLE);
240
241 /* Clear Downlink channels */
242 mcpdm->up_channels = 0;
243
244 mcpdm->uplink = NULL;
245
246 return 0;
247}
248
249/*
250 * Cleans McPDM downlink configuration.
251 * This function should be called when the stream is closed.
252 */
253int omap_mcpdm_playback_close(struct omap_mcpdm_link *downlink)
254{
255 int irq_mask = 0;
256
257 if (!downlink)
258 return -EINVAL;
259
260 /* Disable irq request generation */
261 irq_mask |= downlink->irq_mask & MCPDM_DOWNLINK_IRQ_MASK;
262 omap_mcpdm_write(MCPDM_IRQENABLE_CLR, irq_mask);
263
264 /* Disable DMA request generation */
265 omap_mcpdm_write(MCPDM_DMAENABLE_CLR, DMA_DN_ENABLE);
266
267 /* clear Downlink channels */
268 mcpdm->dn_channels = 0;
269
270 mcpdm->downlink = NULL;
271
272 return 0;
273}
274
275static irqreturn_t omap_mcpdm_irq_handler(int irq, void *dev_id)
276{
277 struct omap_mcpdm *mcpdm_irq = dev_id;
278 int irq_status;
279
280 irq_status = omap_mcpdm_read(MCPDM_IRQSTATUS);
281
282 /* Acknowledge irq event */
283 omap_mcpdm_write(MCPDM_IRQSTATUS, irq_status);
284
285 if (irq & MCPDM_DN_IRQ_FULL) {
286 dev_err(mcpdm_irq->dev, "DN FIFO error %x\n", irq_status);
287 omap_mcpdm_reset_playback(1);
288 omap_mcpdm_playback_open(mcpdm_irq->downlink);
289 omap_mcpdm_reset_playback(0);
290 }
291
292 if (irq & MCPDM_DN_IRQ_EMPTY) {
293 dev_err(mcpdm_irq->dev, "DN FIFO error %x\n", irq_status);
294 omap_mcpdm_reset_playback(1);
295 omap_mcpdm_playback_open(mcpdm_irq->downlink);
296 omap_mcpdm_reset_playback(0);
297 }
298
299 if (irq & MCPDM_DN_IRQ) {
300 dev_dbg(mcpdm_irq->dev, "DN write request\n");
301 }
302
303 if (irq & MCPDM_UP_IRQ_FULL) {
304 dev_err(mcpdm_irq->dev, "UP FIFO error %x\n", irq_status);
305 omap_mcpdm_reset_capture(1);
306 omap_mcpdm_capture_open(mcpdm_irq->uplink);
307 omap_mcpdm_reset_capture(0);
308 }
309
310 if (irq & MCPDM_UP_IRQ_EMPTY) {
311 dev_err(mcpdm_irq->dev, "UP FIFO error %x\n", irq_status);
312 omap_mcpdm_reset_capture(1);
313 omap_mcpdm_capture_open(mcpdm_irq->uplink);
314 omap_mcpdm_reset_capture(0);
315 }
316
317 if (irq & MCPDM_UP_IRQ) {
318 dev_dbg(mcpdm_irq->dev, "UP write request\n");
319 }
320
321 return IRQ_HANDLED;
322}
323
324int omap_mcpdm_request(void)
325{
326 int ret;
327
328 clk_enable(mcpdm->clk);
329
330 spin_lock(&mcpdm->lock);
331
332 if (!mcpdm->free) {
333 dev_err(mcpdm->dev, "McPDM interface is in use\n");
334 spin_unlock(&mcpdm->lock);
335 ret = -EBUSY;
336 goto err;
337 }
338 mcpdm->free = 0;
339
340 spin_unlock(&mcpdm->lock);
341
342 /* Disable lines while request is ongoing */
343 omap_mcpdm_write(MCPDM_CTRL, 0x00);
344
345 ret = request_irq(mcpdm->irq, omap_mcpdm_irq_handler,
346 0, "McPDM", (void *)mcpdm);
347 if (ret) {
348 dev_err(mcpdm->dev, "Request for McPDM IRQ failed\n");
349 goto err;
350 }
351
352 return 0;
353
354err:
355 clk_disable(mcpdm->clk);
356 return ret;
357}
358
359void omap_mcpdm_free(void)
360{
361 spin_lock(&mcpdm->lock);
362 if (mcpdm->free) {
363 dev_err(mcpdm->dev, "McPDM interface is already free\n");
364 spin_unlock(&mcpdm->lock);
365 return;
366 }
367 mcpdm->free = 1;
368 spin_unlock(&mcpdm->lock);
369
370 clk_disable(mcpdm->clk);
371
372 free_irq(mcpdm->irq, (void *)mcpdm);
373}
374
375/* Enable/disable DC offset cancelation for the analog
376 * headset path (PDM channels 1 and 2).
377 */
378int omap_mcpdm_set_offset(int offset1, int offset2)
379{
380 int offset;
381
382 if ((offset1 > DN_OFST_MAX) || (offset2 > DN_OFST_MAX))
383 return -EINVAL;
384
385 offset = (offset1 << DN_OFST_RX1) | (offset2 << DN_OFST_RX2);
386
387 /* offset cancellation for channel 1 */
388 if (offset1)
389 offset |= DN_OFST_RX1_EN;
390 else
391 offset &= ~DN_OFST_RX1_EN;
392
393 /* offset cancellation for channel 2 */
394 if (offset2)
395 offset |= DN_OFST_RX2_EN;
396 else
397 offset &= ~DN_OFST_RX2_EN;
398
399 omap_mcpdm_write(MCPDM_DN_OFFSET, offset);
400
401 return 0;
402}
403
404static int __devinit omap_mcpdm_probe(struct platform_device *pdev)
405{
406 struct resource *res;
407 int ret = 0;
408
409 mcpdm = kzalloc(sizeof(struct omap_mcpdm), GFP_KERNEL);
410 if (!mcpdm) {
411 ret = -ENOMEM;
412 goto exit;
413 }
414
415 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
416 if (res == NULL) {
417 dev_err(&pdev->dev, "no resource\n");
418 goto err_resource;
419 }
420
421 spin_lock_init(&mcpdm->lock);
422 mcpdm->free = 1;
423 mcpdm->io_base = ioremap(res->start, resource_size(res));
424 if (!mcpdm->io_base) {
425 ret = -ENOMEM;
426 goto err_resource;
427 }
428
429 mcpdm->irq = platform_get_irq(pdev, 0);
430
431 mcpdm->clk = clk_get(&pdev->dev, "pdm_ck");
432 if (IS_ERR(mcpdm->clk)) {
433 ret = PTR_ERR(mcpdm->clk);
434 dev_err(&pdev->dev, "unable to get pdm_ck: %d\n", ret);
435 goto err_clk;
436 }
437
438 mcpdm->dev = &pdev->dev;
439 platform_set_drvdata(pdev, mcpdm);
440
441 return 0;
442
443err_clk:
444 iounmap(mcpdm->io_base);
445err_resource:
446 kfree(mcpdm);
447exit:
448 return ret;
449}
450
451static int __devexit omap_mcpdm_remove(struct platform_device *pdev)
452{
453 struct omap_mcpdm *mcpdm_ptr = platform_get_drvdata(pdev);
454
455 platform_set_drvdata(pdev, NULL);
456
457 clk_put(mcpdm_ptr->clk);
458
459 iounmap(mcpdm_ptr->io_base);
460
461 mcpdm_ptr->clk = NULL;
462 mcpdm_ptr->free = 0;
463 mcpdm_ptr->dev = NULL;
464
465 kfree(mcpdm_ptr);
466
467 return 0;
468}
469
470static struct platform_driver omap_mcpdm_driver = {
471 .probe = omap_mcpdm_probe,
472 .remove = __devexit_p(omap_mcpdm_remove),
473 .driver = {
474 .name = "omap-mcpdm",
475 },
476};
477
478static struct platform_device *omap_mcpdm_device;
479
480static int __init omap_mcpdm_init(void)
481{
482 return platform_driver_register(&omap_mcpdm_driver);
483}
484arch_initcall(omap_mcpdm_init);
diff --git a/sound/soc/omap/mcpdm.h b/sound/soc/omap/mcpdm.h
new file mode 100644
index 000000000000..7bb326ef0886
--- /dev/null
+++ b/sound/soc/omap/mcpdm.h
@@ -0,0 +1,151 @@
1/*
2 * mcpdm.h -- Defines for McPDM driver
3 *
4 * Author: Jorge Eduardo Candelaria <x0107209@ti.com>
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 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 */
21
22/* McPDM registers */
23
24#define MCPDM_REVISION 0x00
25#define MCPDM_SYSCONFIG 0x10
26#define MCPDM_IRQSTATUS_RAW 0x24
27#define MCPDM_IRQSTATUS 0x28
28#define MCPDM_IRQENABLE_SET 0x2C
29#define MCPDM_IRQENABLE_CLR 0x30
30#define MCPDM_IRQWAKE_EN 0x34
31#define MCPDM_DMAENABLE_SET 0x38
32#define MCPDM_DMAENABLE_CLR 0x3C
33#define MCPDM_DMAWAKEEN 0x40
34#define MCPDM_CTRL 0x44
35#define MCPDM_DN_DATA 0x48
36#define MCPDM_UP_DATA 0x4C
37#define MCPDM_FIFO_CTRL_DN 0x50
38#define MCPDM_FIFO_CTRL_UP 0x54
39#define MCPDM_DN_OFFSET 0x58
40
41/*
42 * MCPDM_IRQ bit fields
43 * IRQSTATUS_RAW, IRQSTATUS, IRQENABLE_SET, IRQENABLE_CLR
44 */
45
46#define MCPDM_DN_IRQ (1 << 0)
47#define MCPDM_DN_IRQ_EMPTY (1 << 1)
48#define MCPDM_DN_IRQ_ALMST_EMPTY (1 << 2)
49#define MCPDM_DN_IRQ_FULL (1 << 3)
50
51#define MCPDM_UP_IRQ (1 << 8)
52#define MCPDM_UP_IRQ_EMPTY (1 << 9)
53#define MCPDM_UP_IRQ_ALMST_FULL (1 << 10)
54#define MCPDM_UP_IRQ_FULL (1 << 11)
55
56#define MCPDM_DOWNLINK_IRQ_MASK 0x00F
57#define MCPDM_UPLINK_IRQ_MASK 0xF00
58
59/*
60 * MCPDM_DMAENABLE bit fields
61 */
62
63#define DMA_DN_ENABLE 0x1
64#define DMA_UP_ENABLE 0x2
65
66/*
67 * MCPDM_CTRL bit fields
68 */
69
70#define PDM_UP1_EN 0x0001
71#define PDM_UP2_EN 0x0002
72#define PDM_UP3_EN 0x0004
73#define PDM_DN1_EN 0x0008
74#define PDM_DN2_EN 0x0010
75#define PDM_DN3_EN 0x0020
76#define PDM_DN4_EN 0x0040
77#define PDM_DN5_EN 0x0080
78#define PDMOUTFORMAT 0x0100
79#define CMD_INT 0x0200
80#define STATUS_INT 0x0400
81#define SW_UP_RST 0x0800
82#define SW_DN_RST 0x1000
83#define PDM_UP_MASK 0x007
84#define PDM_DN_MASK 0x0F8
85#define PDM_CMD_MASK 0x200
86#define PDM_STATUS_MASK 0x400
87
88
89#define PDMOUTFORMAT_LJUST (0 << 8)
90#define PDMOUTFORMAT_RJUST (1 << 8)
91
92/*
93 * MCPDM_FIFO_CTRL bit fields
94 */
95
96#define UP_THRES_MAX 0xF
97#define DN_THRES_MAX 0xF
98
99/*
100 * MCPDM_DN_OFFSET bit fields
101 */
102
103#define DN_OFST_RX1_EN 0x0001
104#define DN_OFST_RX2_EN 0x0100
105
106#define DN_OFST_RX1 1
107#define DN_OFST_RX2 9
108#define DN_OFST_MAX 0x1F
109
110#define MCPDM_UPLINK 1
111#define MCPDM_DOWNLINK 2
112
113struct omap_mcpdm_link {
114 int irq_mask;
115 int threshold;
116 int format;
117 int channels;
118};
119
120struct omap_mcpdm_platform_data {
121 unsigned long phys_base;
122 u16 irq;
123};
124
125struct omap_mcpdm {
126 struct device *dev;
127 unsigned long phys_base;
128 void __iomem *io_base;
129 u8 free;
130 int irq;
131
132 spinlock_t lock;
133 struct omap_mcpdm_platform_data *pdata;
134 struct clk *clk;
135 struct omap_mcpdm_link *downlink;
136 struct omap_mcpdm_link *uplink;
137 struct completion irq_completion;
138
139 int dn_channels;
140 int up_channels;
141};
142
143extern void omap_mcpdm_start(int stream);
144extern void omap_mcpdm_stop(int stream);
145extern int omap_mcpdm_capture_open(struct omap_mcpdm_link *uplink);
146extern int omap_mcpdm_playback_open(struct omap_mcpdm_link *downlink);
147extern int omap_mcpdm_capture_close(struct omap_mcpdm_link *uplink);
148extern int omap_mcpdm_playback_close(struct omap_mcpdm_link *downlink);
149extern int omap_mcpdm_request(void);
150extern void omap_mcpdm_free(void);
151extern int omap_mcpdm_set_offset(int offset1, int offset2);
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index 6bbbd2ab0ee7..e814a9591f78 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -39,6 +39,14 @@
39 39
40#define OMAP_MCBSP_RATES (SNDRV_PCM_RATE_8000_96000) 40#define OMAP_MCBSP_RATES (SNDRV_PCM_RATE_8000_96000)
41 41
42#define OMAP_MCBSP_SOC_SINGLE_S16_EXT(xname, xmin, xmax, \
43 xhandler_get, xhandler_put) \
44{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
45 .info = omap_mcbsp_st_info_volsw, \
46 .get = xhandler_get, .put = xhandler_put, \
47 .private_value = (unsigned long) &(struct soc_mixer_control) \
48 {.min = xmin, .max = xmax} }
49
42struct omap_mcbsp_data { 50struct omap_mcbsp_data {
43 unsigned int bus_id; 51 unsigned int bus_id;
44 struct omap_mcbsp_reg_cfg regs; 52 struct omap_mcbsp_reg_cfg regs;
@@ -82,11 +90,11 @@ static const int omap1_dma_reqs[][2] = {};
82static const unsigned long omap1_mcbsp_port[][2] = {}; 90static const unsigned long omap1_mcbsp_port[][2] = {};
83#endif 91#endif
84 92
85#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) 93#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
86static const int omap24xx_dma_reqs[][2] = { 94static const int omap24xx_dma_reqs[][2] = {
87 { OMAP24XX_DMA_MCBSP1_TX, OMAP24XX_DMA_MCBSP1_RX }, 95 { OMAP24XX_DMA_MCBSP1_TX, OMAP24XX_DMA_MCBSP1_RX },
88 { OMAP24XX_DMA_MCBSP2_TX, OMAP24XX_DMA_MCBSP2_RX }, 96 { OMAP24XX_DMA_MCBSP2_TX, OMAP24XX_DMA_MCBSP2_RX },
89#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP34XX) 97#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3)
90 { OMAP24XX_DMA_MCBSP3_TX, OMAP24XX_DMA_MCBSP3_RX }, 98 { OMAP24XX_DMA_MCBSP3_TX, OMAP24XX_DMA_MCBSP3_RX },
91 { OMAP24XX_DMA_MCBSP4_TX, OMAP24XX_DMA_MCBSP4_RX }, 99 { OMAP24XX_DMA_MCBSP4_TX, OMAP24XX_DMA_MCBSP4_RX },
92 { OMAP24XX_DMA_MCBSP5_TX, OMAP24XX_DMA_MCBSP5_RX }, 100 { OMAP24XX_DMA_MCBSP5_TX, OMAP24XX_DMA_MCBSP5_RX },
@@ -124,7 +132,7 @@ static const unsigned long omap2430_mcbsp_port[][2] = {
124static const unsigned long omap2430_mcbsp_port[][2] = {}; 132static const unsigned long omap2430_mcbsp_port[][2] = {};
125#endif 133#endif
126 134
127#if defined(CONFIG_ARCH_OMAP34XX) 135#if defined(CONFIG_ARCH_OMAP3)
128static const unsigned long omap34xx_mcbsp_port[][2] = { 136static const unsigned long omap34xx_mcbsp_port[][2] = {
129 { OMAP34XX_MCBSP1_BASE + OMAP_MCBSP_REG_DXR, 137 { OMAP34XX_MCBSP1_BASE + OMAP_MCBSP_REG_DXR,
130 OMAP34XX_MCBSP1_BASE + OMAP_MCBSP_REG_DRR }, 138 OMAP34XX_MCBSP1_BASE + OMAP_MCBSP_REG_DRR },
@@ -287,6 +295,8 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
287 omap_mcbsp_dai_dma_params[id][substream->stream].dma_req = dma; 295 omap_mcbsp_dai_dma_params[id][substream->stream].dma_req = dma;
288 omap_mcbsp_dai_dma_params[id][substream->stream].port_addr = port; 296 omap_mcbsp_dai_dma_params[id][substream->stream].port_addr = port;
289 omap_mcbsp_dai_dma_params[id][substream->stream].sync_mode = sync_mode; 297 omap_mcbsp_dai_dma_params[id][substream->stream].sync_mode = sync_mode;
298 omap_mcbsp_dai_dma_params[id][substream->stream].data_type =
299 OMAP_DMA_DATA_TYPE_S16;
290 cpu_dai->dma_data = &omap_mcbsp_dai_dma_params[id][substream->stream]; 300 cpu_dai->dma_data = &omap_mcbsp_dai_dma_params[id][substream->stream];
291 301
292 if (mcbsp_data->configured) { 302 if (mcbsp_data->configured) {
@@ -637,6 +647,136 @@ struct snd_soc_dai omap_mcbsp_dai[] = {
637 647
638EXPORT_SYMBOL_GPL(omap_mcbsp_dai); 648EXPORT_SYMBOL_GPL(omap_mcbsp_dai);
639 649
650int omap_mcbsp_st_info_volsw(struct snd_kcontrol *kcontrol,
651 struct snd_ctl_elem_info *uinfo)
652{
653 struct soc_mixer_control *mc =
654 (struct soc_mixer_control *)kcontrol->private_value;
655 int max = mc->max;
656 int min = mc->min;
657
658 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
659 uinfo->count = 1;
660 uinfo->value.integer.min = min;
661 uinfo->value.integer.max = max;
662 return 0;
663}
664
665#define OMAP_MCBSP_ST_SET_CHANNEL_VOLUME(id, channel) \
666static int \
667omap_mcbsp##id##_set_st_ch##channel##_volume(struct snd_kcontrol *kc, \
668 struct snd_ctl_elem_value *uc) \
669{ \
670 struct soc_mixer_control *mc = \
671 (struct soc_mixer_control *)kc->private_value; \
672 int max = mc->max; \
673 int min = mc->min; \
674 int val = uc->value.integer.value[0]; \
675 \
676 if (val < min || val > max) \
677 return -EINVAL; \
678 \
679 /* OMAP McBSP implementation uses index values 0..4 */ \
680 return omap_st_set_chgain((id)-1, channel, val); \
681}
682
683#define OMAP_MCBSP_ST_GET_CHANNEL_VOLUME(id, channel) \
684static int \
685omap_mcbsp##id##_get_st_ch##channel##_volume(struct snd_kcontrol *kc, \
686 struct snd_ctl_elem_value *uc) \
687{ \
688 s16 chgain; \
689 \
690 if (omap_st_get_chgain((id)-1, channel, &chgain)) \
691 return -EAGAIN; \
692 \
693 uc->value.integer.value[0] = chgain; \
694 return 0; \
695}
696
697OMAP_MCBSP_ST_SET_CHANNEL_VOLUME(2, 0)
698OMAP_MCBSP_ST_SET_CHANNEL_VOLUME(2, 1)
699OMAP_MCBSP_ST_SET_CHANNEL_VOLUME(3, 0)
700OMAP_MCBSP_ST_SET_CHANNEL_VOLUME(3, 1)
701OMAP_MCBSP_ST_GET_CHANNEL_VOLUME(2, 0)
702OMAP_MCBSP_ST_GET_CHANNEL_VOLUME(2, 1)
703OMAP_MCBSP_ST_GET_CHANNEL_VOLUME(3, 0)
704OMAP_MCBSP_ST_GET_CHANNEL_VOLUME(3, 1)
705
706static int omap_mcbsp_st_put_mode(struct snd_kcontrol *kcontrol,
707 struct snd_ctl_elem_value *ucontrol)
708{
709 struct soc_mixer_control *mc =
710 (struct soc_mixer_control *)kcontrol->private_value;
711 u8 value = ucontrol->value.integer.value[0];
712
713 if (value == omap_st_is_enabled(mc->reg))
714 return 0;
715
716 if (value)
717 omap_st_enable(mc->reg);
718 else
719 omap_st_disable(mc->reg);
720
721 return 1;
722}
723
724static int omap_mcbsp_st_get_mode(struct snd_kcontrol *kcontrol,
725 struct snd_ctl_elem_value *ucontrol)
726{
727 struct soc_mixer_control *mc =
728 (struct soc_mixer_control *)kcontrol->private_value;
729
730 ucontrol->value.integer.value[0] = omap_st_is_enabled(mc->reg);
731 return 0;
732}
733
734static const struct snd_kcontrol_new omap_mcbsp2_st_controls[] = {
735 SOC_SINGLE_EXT("McBSP2 Sidetone Switch", 1, 0, 1, 0,
736 omap_mcbsp_st_get_mode, omap_mcbsp_st_put_mode),
737 OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP2 Sidetone Channel 0 Volume",
738 -32768, 32767,
739 omap_mcbsp2_get_st_ch0_volume,
740 omap_mcbsp2_set_st_ch0_volume),
741 OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP2 Sidetone Channel 1 Volume",
742 -32768, 32767,
743 omap_mcbsp2_get_st_ch1_volume,
744 omap_mcbsp2_set_st_ch1_volume),
745};
746
747static const struct snd_kcontrol_new omap_mcbsp3_st_controls[] = {
748 SOC_SINGLE_EXT("McBSP3 Sidetone Switch", 2, 0, 1, 0,
749 omap_mcbsp_st_get_mode, omap_mcbsp_st_put_mode),
750 OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP3 Sidetone Channel 0 Volume",
751 -32768, 32767,
752 omap_mcbsp3_get_st_ch0_volume,
753 omap_mcbsp3_set_st_ch0_volume),
754 OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP3 Sidetone Channel 1 Volume",
755 -32768, 32767,
756 omap_mcbsp3_get_st_ch1_volume,
757 omap_mcbsp3_set_st_ch1_volume),
758};
759
760int omap_mcbsp_st_add_controls(struct snd_soc_codec *codec, int mcbsp_id)
761{
762 if (!cpu_is_omap34xx())
763 return -ENODEV;
764
765 switch (mcbsp_id) {
766 case 1: /* McBSP 2 */
767 return snd_soc_add_controls(codec, omap_mcbsp2_st_controls,
768 ARRAY_SIZE(omap_mcbsp2_st_controls));
769 case 2: /* McBSP 3 */
770 return snd_soc_add_controls(codec, omap_mcbsp3_st_controls,
771 ARRAY_SIZE(omap_mcbsp3_st_controls));
772 default:
773 break;
774 }
775
776 return -EINVAL;
777}
778EXPORT_SYMBOL_GPL(omap_mcbsp_st_add_controls);
779
640static int __init snd_omap_mcbsp_init(void) 780static int __init snd_omap_mcbsp_init(void)
641{ 781{
642 return snd_soc_register_dais(omap_mcbsp_dai, 782 return snd_soc_register_dais(omap_mcbsp_dai,
diff --git a/sound/soc/omap/omap-mcbsp.h b/sound/soc/omap/omap-mcbsp.h
index 647d2f981ab0..6c363e5f4387 100644
--- a/sound/soc/omap/omap-mcbsp.h
+++ b/sound/soc/omap/omap-mcbsp.h
@@ -50,11 +50,13 @@ enum omap_mcbsp_div {
50#undef NUM_LINKS 50#undef NUM_LINKS
51#define NUM_LINKS 3 51#define NUM_LINKS 3
52#endif 52#endif
53#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP34XX) 53#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3)
54#undef NUM_LINKS 54#undef NUM_LINKS
55#define NUM_LINKS 5 55#define NUM_LINKS 5
56#endif 56#endif
57 57
58extern struct snd_soc_dai omap_mcbsp_dai[NUM_LINKS]; 58extern struct snd_soc_dai omap_mcbsp_dai[NUM_LINKS];
59 59
60int omap_mcbsp_st_add_controls(struct snd_soc_codec *codec, int mcbsp_id);
61
60#endif 62#endif
diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c
new file mode 100644
index 000000000000..25f19e4728bf
--- /dev/null
+++ b/sound/soc/omap/omap-mcpdm.c
@@ -0,0 +1,251 @@
1/*
2 * omap-mcpdm.c -- OMAP ALSA SoC DAI driver using McPDM port
3 *
4 * Copyright (C) 2009 Texas Instruments
5 *
6 * Author: Misael Lopez Cruz <x0052729@ti.com>
7 * Contact: Jorge Eduardo Candelaria <x0107209@ti.com>
8 * Margarita Olaya <magi.olaya@ti.com>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * version 2 as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22 * 02110-1301 USA
23 *
24 */
25
26#include <linux/init.h>
27#include <linux/module.h>
28#include <linux/device.h>
29#include <sound/core.h>
30#include <sound/pcm.h>
31#include <sound/pcm_params.h>
32#include <sound/initval.h>
33#include <sound/soc.h>
34
35#include <plat/control.h>
36#include <plat/dma.h>
37#include <plat/mcbsp.h>
38#include "mcpdm.h"
39#include "omap-mcpdm.h"
40#include "omap-pcm.h"
41
42struct omap_mcpdm_data {
43 struct omap_mcpdm_link *links;
44 int active;
45};
46
47static struct omap_mcpdm_link omap_mcpdm_links[] = {
48 /* downlink */
49 {
50 .irq_mask = MCPDM_DN_IRQ_EMPTY | MCPDM_DN_IRQ_FULL,
51 .threshold = 1,
52 .format = PDMOUTFORMAT_LJUST,
53 },
54 /* uplink */
55 {
56 .irq_mask = MCPDM_UP_IRQ_EMPTY | MCPDM_UP_IRQ_FULL,
57 .threshold = 1,
58 .format = PDMOUTFORMAT_LJUST,
59 },
60};
61
62static struct omap_mcpdm_data mcpdm_data = {
63 .links = omap_mcpdm_links,
64 .active = 0,
65};
66
67/*
68 * Stream DMA parameters
69 */
70static struct omap_pcm_dma_data omap_mcpdm_dai_dma_params[] = {
71 {
72 .name = "Audio playback",
73 .dma_req = OMAP44XX_DMA_MCPDM_DL,
74 .data_type = OMAP_DMA_DATA_TYPE_S32,
75 .sync_mode = OMAP_DMA_SYNC_PACKET,
76 .packet_size = 16,
77 .port_addr = OMAP44XX_MCPDM_L3_BASE + MCPDM_DN_DATA,
78 },
79 {
80 .name = "Audio capture",
81 .dma_req = OMAP44XX_DMA_MCPDM_UP,
82 .data_type = OMAP_DMA_DATA_TYPE_S32,
83 .sync_mode = OMAP_DMA_SYNC_PACKET,
84 .packet_size = 16,
85 .port_addr = OMAP44XX_MCPDM_L3_BASE + MCPDM_UP_DATA,
86 },
87};
88
89static int omap_mcpdm_dai_startup(struct snd_pcm_substream *substream,
90 struct snd_soc_dai *dai)
91{
92 struct snd_soc_pcm_runtime *rtd = substream->private_data;
93 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
94 int err = 0;
95
96 if (!cpu_dai->active)
97 err = omap_mcpdm_request();
98
99 return err;
100}
101
102static void omap_mcpdm_dai_shutdown(struct snd_pcm_substream *substream,
103 struct snd_soc_dai *dai)
104{
105 struct snd_soc_pcm_runtime *rtd = substream->private_data;
106 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
107
108 if (!cpu_dai->active)
109 omap_mcpdm_free();
110}
111
112static int omap_mcpdm_dai_trigger(struct snd_pcm_substream *substream, int cmd,
113 struct snd_soc_dai *dai)
114{
115 struct snd_soc_pcm_runtime *rtd = substream->private_data;
116 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
117 struct omap_mcpdm_data *mcpdm_priv = cpu_dai->private_data;
118 int stream = substream->stream;
119 int err = 0;
120
121 switch (cmd) {
122 case SNDRV_PCM_TRIGGER_START:
123 case SNDRV_PCM_TRIGGER_RESUME:
124 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
125 if (!mcpdm_priv->active++)
126 omap_mcpdm_start(stream);
127 break;
128
129 case SNDRV_PCM_TRIGGER_STOP:
130 case SNDRV_PCM_TRIGGER_SUSPEND:
131 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
132 if (!--mcpdm_priv->active)
133 omap_mcpdm_stop(stream);
134 break;
135 default:
136 err = -EINVAL;
137 }
138
139 return err;
140}
141
142static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream,
143 struct snd_pcm_hw_params *params,
144 struct snd_soc_dai *dai)
145{
146 struct snd_soc_pcm_runtime *rtd = substream->private_data;
147 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
148 struct omap_mcpdm_data *mcpdm_priv = cpu_dai->private_data;
149 struct omap_mcpdm_link *mcpdm_links = mcpdm_priv->links;
150 int stream = substream->stream;
151 int channels, err, link_mask = 0;
152
153 cpu_dai->dma_data = &omap_mcpdm_dai_dma_params[stream];
154
155 channels = params_channels(params);
156 switch (channels) {
157 case 4:
158 if (stream == SNDRV_PCM_STREAM_CAPTURE)
159 /* up to 2 channels for capture */
160 return -EINVAL;
161 link_mask |= 1 << 3;
162 case 3:
163 if (stream == SNDRV_PCM_STREAM_CAPTURE)
164 /* up to 2 channels for capture */
165 return -EINVAL;
166 link_mask |= 1 << 2;
167 case 2:
168 link_mask |= 1 << 1;
169 case 1:
170 link_mask |= 1 << 0;
171 break;
172 default:
173 /* unsupported number of channels */
174 return -EINVAL;
175 }
176
177 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
178 mcpdm_links[stream].channels = link_mask << 3;
179 err = omap_mcpdm_playback_open(&mcpdm_links[stream]);
180 } else {
181 mcpdm_links[stream].channels = link_mask << 0;
182 err = omap_mcpdm_capture_open(&mcpdm_links[stream]);
183 }
184
185 return err;
186}
187
188static int omap_mcpdm_dai_hw_free(struct snd_pcm_substream *substream,
189 struct snd_soc_dai *dai)
190{
191 struct snd_soc_pcm_runtime *rtd = substream->private_data;
192 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
193 struct omap_mcpdm_data *mcpdm_priv = cpu_dai->private_data;
194 struct omap_mcpdm_link *mcpdm_links = mcpdm_priv->links;
195 int stream = substream->stream;
196 int err;
197
198 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
199 err = omap_mcpdm_playback_close(&mcpdm_links[stream]);
200 else
201 err = omap_mcpdm_capture_close(&mcpdm_links[stream]);
202
203 return err;
204}
205
206static struct snd_soc_dai_ops omap_mcpdm_dai_ops = {
207 .startup = omap_mcpdm_dai_startup,
208 .shutdown = omap_mcpdm_dai_shutdown,
209 .trigger = omap_mcpdm_dai_trigger,
210 .hw_params = omap_mcpdm_dai_hw_params,
211 .hw_free = omap_mcpdm_dai_hw_free,
212};
213
214#define OMAP_MCPDM_RATES (SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
215#define OMAP_MCPDM_FORMATS (SNDRV_PCM_FMTBIT_S32_LE)
216
217struct snd_soc_dai omap_mcpdm_dai = {
218 .name = "omap-mcpdm",
219 .id = -1,
220 .playback = {
221 .channels_min = 1,
222 .channels_max = 4,
223 .rates = OMAP_MCPDM_RATES,
224 .formats = OMAP_MCPDM_FORMATS,
225 },
226 .capture = {
227 .channels_min = 1,
228 .channels_max = 2,
229 .rates = OMAP_MCPDM_RATES,
230 .formats = OMAP_MCPDM_FORMATS,
231 },
232 .ops = &omap_mcpdm_dai_ops,
233 .private_data = &mcpdm_data,
234};
235EXPORT_SYMBOL_GPL(omap_mcpdm_dai);
236
237static int __init snd_omap_mcpdm_init(void)
238{
239 return snd_soc_register_dai(&omap_mcpdm_dai);
240}
241module_init(snd_omap_mcpdm_init);
242
243static void __exit snd_omap_mcpdm_exit(void)
244{
245 snd_soc_unregister_dai(&omap_mcpdm_dai);
246}
247module_exit(snd_omap_mcpdm_exit);
248
249MODULE_AUTHOR("Misael Lopez Cruz <x0052729@ti.com>");
250MODULE_DESCRIPTION("OMAP PDM SoC Interface");
251MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/omap-mcpdm.h b/sound/soc/omap/omap-mcpdm.h
new file mode 100644
index 000000000000..73b80d559345
--- /dev/null
+++ b/sound/soc/omap/omap-mcpdm.h
@@ -0,0 +1,29 @@
1/*
2 * omap-mcpdm.h
3 *
4 * Copyright (C) 2009 Texas Instruments
5 *
6 * Contact: Misael Lopez Cruz <x0052729@ti.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#ifndef __OMAP_MCPDM_H__
25#define __OMAP_MCPDM_H__
26
27extern struct snd_soc_dai omap_mcpdm_dai;
28
29#endif /* End of __OMAP_MCPDM_H__ */
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c
index 9db2770e9640..825db385f01f 100644
--- a/sound/soc/omap/omap-pcm.c
+++ b/sound/soc/omap/omap-pcm.c
@@ -37,7 +37,8 @@ static const struct snd_pcm_hardware omap_pcm_hardware = {
37 SNDRV_PCM_INFO_INTERLEAVED | 37 SNDRV_PCM_INFO_INTERLEAVED |
38 SNDRV_PCM_INFO_PAUSE | 38 SNDRV_PCM_INFO_PAUSE |
39 SNDRV_PCM_INFO_RESUME, 39 SNDRV_PCM_INFO_RESUME,
40 .formats = SNDRV_PCM_FMTBIT_S16_LE, 40 .formats = SNDRV_PCM_FMTBIT_S16_LE |
41 SNDRV_PCM_FMTBIT_S32_LE,
41 .period_bytes_min = 32, 42 .period_bytes_min = 32,
42 .period_bytes_max = 64 * 1024, 43 .period_bytes_max = 64 * 1024,
43 .periods_min = 2, 44 .periods_min = 2,
@@ -149,6 +150,7 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream)
149 struct omap_runtime_data *prtd = runtime->private_data; 150 struct omap_runtime_data *prtd = runtime->private_data;
150 struct omap_pcm_dma_data *dma_data = prtd->dma_data; 151 struct omap_pcm_dma_data *dma_data = prtd->dma_data;
151 struct omap_dma_channel_params dma_params; 152 struct omap_dma_channel_params dma_params;
153 int bytes;
152 154
153 /* return if this is a bufferless transfer e.g. 155 /* return if this is a bufferless transfer e.g.
154 * codec <--> BT codec or GSM modem -- lg FIXME */ 156 * codec <--> BT codec or GSM modem -- lg FIXME */
@@ -156,11 +158,7 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream)
156 return 0; 158 return 0;
157 159
158 memset(&dma_params, 0, sizeof(dma_params)); 160 memset(&dma_params, 0, sizeof(dma_params));
159 /* 161 dma_params.data_type = dma_data->data_type;
160 * Note: Regardless of interface data formats supported by OMAP McBSP
161 * or EAC blocks, internal representation is always fixed 16-bit/sample
162 */
163 dma_params.data_type = OMAP_DMA_DATA_TYPE_S16;
164 dma_params.trigger = dma_data->dma_req; 162 dma_params.trigger = dma_data->dma_req;
165 dma_params.sync_mode = dma_data->sync_mode; 163 dma_params.sync_mode = dma_data->sync_mode;
166 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 164 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
@@ -170,6 +168,7 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream)
170 dma_params.src_start = runtime->dma_addr; 168 dma_params.src_start = runtime->dma_addr;
171 dma_params.dst_start = dma_data->port_addr; 169 dma_params.dst_start = dma_data->port_addr;
172 dma_params.dst_port = OMAP_DMA_PORT_MPUI; 170 dma_params.dst_port = OMAP_DMA_PORT_MPUI;
171 dma_params.dst_fi = dma_data->packet_size;
173 } else { 172 } else {
174 dma_params.src_amode = OMAP_DMA_AMODE_CONSTANT; 173 dma_params.src_amode = OMAP_DMA_AMODE_CONSTANT;
175 dma_params.dst_amode = OMAP_DMA_AMODE_POST_INC; 174 dma_params.dst_amode = OMAP_DMA_AMODE_POST_INC;
@@ -177,6 +176,7 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream)
177 dma_params.src_start = dma_data->port_addr; 176 dma_params.src_start = dma_data->port_addr;
178 dma_params.dst_start = runtime->dma_addr; 177 dma_params.dst_start = runtime->dma_addr;
179 dma_params.src_port = OMAP_DMA_PORT_MPUI; 178 dma_params.src_port = OMAP_DMA_PORT_MPUI;
179 dma_params.src_fi = dma_data->packet_size;
180 } 180 }
181 /* 181 /*
182 * Set DMA transfer frame size equal to ALSA period size and frame 182 * Set DMA transfer frame size equal to ALSA period size and frame
@@ -184,7 +184,8 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream)
184 * we can transfer the whole ALSA buffer with single DMA transfer but 184 * we can transfer the whole ALSA buffer with single DMA transfer but
185 * still can get an interrupt at each period bounary 185 * still can get an interrupt at each period bounary
186 */ 186 */
187 dma_params.elem_count = snd_pcm_lib_period_bytes(substream) / 2; 187 bytes = snd_pcm_lib_period_bytes(substream);
188 dma_params.elem_count = bytes >> dma_data->data_type;
188 dma_params.frame_count = runtime->periods; 189 dma_params.frame_count = runtime->periods;
189 omap_set_dma_params(prtd->dma_ch, &dma_params); 190 omap_set_dma_params(prtd->dma_ch, &dma_params);
190 191
diff --git a/sound/soc/omap/omap-pcm.h b/sound/soc/omap/omap-pcm.h
index 38a821dd4118..b19975d26907 100644
--- a/sound/soc/omap/omap-pcm.h
+++ b/sound/soc/omap/omap-pcm.h
@@ -29,8 +29,10 @@ struct omap_pcm_dma_data {
29 char *name; /* stream identifier */ 29 char *name; /* stream identifier */
30 int dma_req; /* DMA request line */ 30 int dma_req; /* DMA request line */
31 unsigned long port_addr; /* transmit/receive register */ 31 unsigned long port_addr; /* transmit/receive register */
32 int sync_mode; /* DMA sync mode */
33 void (*set_threshold)(struct snd_pcm_substream *substream); 32 void (*set_threshold)(struct snd_pcm_substream *substream);
33 int data_type; /* data type 8,16,32 */
34 int sync_mode; /* DMA sync mode */
35 int packet_size; /* packet size only in PACKET mode */
34}; 36};
35 37
36extern struct snd_soc_platform omap_soc_platform; 38extern struct snd_soc_platform omap_soc_platform;
diff --git a/sound/soc/omap/omap3beagle.c b/sound/soc/omap/omap3beagle.c
index d88ad5ca526c..240e0975dd6a 100644
--- a/sound/soc/omap/omap3beagle.c
+++ b/sound/soc/omap/omap3beagle.c
@@ -117,11 +117,11 @@ static int __init omap3beagle_soc_init(void)
117{ 117{
118 int ret; 118 int ret;
119 119
120 if (!machine_is_omap3_beagle()) { 120 if (!(machine_is_omap3_beagle() || machine_is_devkit8000())) {
121 pr_debug("Not OMAP3 Beagle!\n"); 121 pr_debug("Not OMAP3 Beagle or Devkit8000!\n");
122 return -ENODEV; 122 return -ENODEV;
123 } 123 }
124 pr_info("OMAP3 Beagle SoC init\n"); 124 pr_info("OMAP3 Beagle/Devkit8000 SoC init\n");
125 125
126 omap3beagle_snd_device = platform_device_alloc("soc-audio", -1); 126 omap3beagle_snd_device = platform_device_alloc("soc-audio", -1);
127 if (!omap3beagle_snd_device) { 127 if (!omap3beagle_snd_device) {
diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c
index 68980c19a3bc..de10f76baded 100644
--- a/sound/soc/omap/omap3pandora.c
+++ b/sound/soc/omap/omap3pandora.c
@@ -23,6 +23,7 @@
23#include <linux/platform_device.h> 23#include <linux/platform_device.h>
24#include <linux/gpio.h> 24#include <linux/gpio.h>
25#include <linux/delay.h> 25#include <linux/delay.h>
26#include <linux/regulator/consumer.h>
26 27
27#include <sound/core.h> 28#include <sound/core.h>
28#include <sound/pcm.h> 29#include <sound/pcm.h>
@@ -40,6 +41,8 @@
40 41
41#define PREFIX "ASoC omap3pandora: " 42#define PREFIX "ASoC omap3pandora: "
42 43
44static struct regulator *omap3pandora_dac_reg;
45
43static int omap3pandora_cmn_hw_params(struct snd_pcm_substream *substream, 46static int omap3pandora_cmn_hw_params(struct snd_pcm_substream *substream,
44 struct snd_pcm_hw_params *params, unsigned int fmt) 47 struct snd_pcm_hw_params *params, unsigned int fmt)
45{ 48{
@@ -106,21 +109,37 @@ static int omap3pandora_in_hw_params(struct snd_pcm_substream *substream,
106 SND_SOC_DAIFMT_CBS_CFS); 109 SND_SOC_DAIFMT_CBS_CFS);
107} 110}
108 111
109static int omap3pandora_hp_event(struct snd_soc_dapm_widget *w, 112static int omap3pandora_dac_event(struct snd_soc_dapm_widget *w,
110 struct snd_kcontrol *k, int event) 113 struct snd_kcontrol *k, int event)
111{ 114{
115 /*
116 * The PCM1773 DAC datasheet requires 1ms delay between switching
117 * VCC power on/off and /PD pin high/low
118 */
112 if (SND_SOC_DAPM_EVENT_ON(event)) { 119 if (SND_SOC_DAPM_EVENT_ON(event)) {
120 regulator_enable(omap3pandora_dac_reg);
121 mdelay(1);
113 gpio_set_value(OMAP3_PANDORA_DAC_POWER_GPIO, 1); 122 gpio_set_value(OMAP3_PANDORA_DAC_POWER_GPIO, 1);
114 gpio_set_value(OMAP3_PANDORA_AMP_POWER_GPIO, 1);
115 } else { 123 } else {
116 gpio_set_value(OMAP3_PANDORA_AMP_POWER_GPIO, 0);
117 mdelay(1);
118 gpio_set_value(OMAP3_PANDORA_DAC_POWER_GPIO, 0); 124 gpio_set_value(OMAP3_PANDORA_DAC_POWER_GPIO, 0);
125 mdelay(1);
126 regulator_disable(omap3pandora_dac_reg);
119 } 127 }
120 128
121 return 0; 129 return 0;
122} 130}
123 131
132static int omap3pandora_hp_event(struct snd_soc_dapm_widget *w,
133 struct snd_kcontrol *k, int event)
134{
135 if (SND_SOC_DAPM_EVENT_ON(event))
136 gpio_set_value(OMAP3_PANDORA_AMP_POWER_GPIO, 1);
137 else
138 gpio_set_value(OMAP3_PANDORA_AMP_POWER_GPIO, 0);
139
140 return 0;
141}
142
124/* 143/*
125 * Audio paths on Pandora board: 144 * Audio paths on Pandora board:
126 * 145 *
@@ -130,7 +149,9 @@ static int omap3pandora_hp_event(struct snd_soc_dapm_widget *w,
130 * |P| <--- TWL4030 <--------- Line In and MICs 149 * |P| <--- TWL4030 <--------- Line In and MICs
131 */ 150 */
132static const struct snd_soc_dapm_widget omap3pandora_out_dapm_widgets[] = { 151static const struct snd_soc_dapm_widget omap3pandora_out_dapm_widgets[] = {
133 SND_SOC_DAPM_DAC("PCM DAC", "HiFi Playback", SND_SOC_NOPM, 0, 0), 152 SND_SOC_DAPM_DAC_E("PCM DAC", "HiFi Playback", SND_SOC_NOPM,
153 0, 0, omap3pandora_dac_event,
154 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
134 SND_SOC_DAPM_PGA_E("Headphone Amplifier", SND_SOC_NOPM, 155 SND_SOC_DAPM_PGA_E("Headphone Amplifier", SND_SOC_NOPM,
135 0, 0, NULL, 0, omap3pandora_hp_event, 156 0, 0, NULL, 0, omap3pandora_hp_event,
136 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 157 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
@@ -306,8 +327,18 @@ static int __init omap3pandora_soc_init(void)
306 goto fail2; 327 goto fail2;
307 } 328 }
308 329
330 omap3pandora_dac_reg = regulator_get(&omap3pandora_snd_device->dev, "vcc");
331 if (IS_ERR(omap3pandora_dac_reg)) {
332 pr_err(PREFIX "Failed to get DAC regulator from %s: %ld\n",
333 dev_name(&omap3pandora_snd_device->dev),
334 PTR_ERR(omap3pandora_dac_reg));
335 goto fail3;
336 }
337
309 return 0; 338 return 0;
310 339
340fail3:
341 platform_device_del(omap3pandora_snd_device);
311fail2: 342fail2:
312 platform_device_put(omap3pandora_snd_device); 343 platform_device_put(omap3pandora_snd_device);
313fail1: 344fail1:
@@ -320,6 +351,7 @@ module_init(omap3pandora_soc_init);
320 351
321static void __exit omap3pandora_soc_exit(void) 352static void __exit omap3pandora_soc_exit(void)
322{ 353{
354 regulator_put(omap3pandora_dac_reg);
323 platform_device_unregister(omap3pandora_snd_device); 355 platform_device_unregister(omap3pandora_snd_device);
324 gpio_free(OMAP3_PANDORA_AMP_POWER_GPIO); 356 gpio_free(OMAP3_PANDORA_AMP_POWER_GPIO);
325 gpio_free(OMAP3_PANDORA_DAC_POWER_GPIO); 357 gpio_free(OMAP3_PANDORA_DAC_POWER_GPIO);
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
index cf00df9c40f4..9e95e5117c88 100644
--- a/sound/soc/pxa/pxa-ssp.c
+++ b/sound/soc/pxa/pxa-ssp.c
@@ -155,7 +155,7 @@ static int pxa_ssp_suspend(struct snd_soc_dai *cpu_dai)
155 struct ssp_device *ssp = priv->ssp; 155 struct ssp_device *ssp = priv->ssp;
156 156
157 if (!cpu_dai->active) 157 if (!cpu_dai->active)
158 return 0; 158 clk_enable(ssp->clk);
159 159
160 priv->cr0 = __raw_readl(ssp->mmio_base + SSCR0); 160 priv->cr0 = __raw_readl(ssp->mmio_base + SSCR0);
161 priv->cr1 = __raw_readl(ssp->mmio_base + SSCR1); 161 priv->cr1 = __raw_readl(ssp->mmio_base + SSCR1);
@@ -173,18 +173,19 @@ static int pxa_ssp_resume(struct snd_soc_dai *cpu_dai)
173 struct ssp_device *ssp = priv->ssp; 173 struct ssp_device *ssp = priv->ssp;
174 uint32_t sssr = SSSR_ROR | SSSR_TUR | SSSR_BCE; 174 uint32_t sssr = SSSR_ROR | SSSR_TUR | SSSR_BCE;
175 175
176 if (!cpu_dai->active)
177 return 0;
178
179 clk_enable(ssp->clk); 176 clk_enable(ssp->clk);
180 177
181 __raw_writel(sssr, ssp->mmio_base + SSSR); 178 __raw_writel(sssr, ssp->mmio_base + SSSR);
182
183 __raw_writel(priv->cr0 & ~SSCR0_SSE, ssp->mmio_base + SSCR0); 179 __raw_writel(priv->cr0 & ~SSCR0_SSE, ssp->mmio_base + SSCR0);
184 __raw_writel(priv->cr1, ssp->mmio_base + SSCR1); 180 __raw_writel(priv->cr1, ssp->mmio_base + SSCR1);
185 __raw_writel(priv->to, ssp->mmio_base + SSTO); 181 __raw_writel(priv->to, ssp->mmio_base + SSTO);
186 __raw_writel(priv->psp, ssp->mmio_base + SSPSP); 182 __raw_writel(priv->psp, ssp->mmio_base + SSPSP);
187 __raw_writel(priv->cr0 | SSCR0_SSE, ssp->mmio_base + SSCR0); 183
184 if (cpu_dai->active)
185 ssp_enable(ssp);
186 else
187 clk_disable(ssp->clk);
188
188 return 0; 189 return 0;
189} 190}
190 191
diff --git a/sound/soc/pxa/raumfeld.c b/sound/soc/pxa/raumfeld.c
index acfce1c0f1c9..7e3f41696c41 100644
--- a/sound/soc/pxa/raumfeld.c
+++ b/sound/soc/pxa/raumfeld.c
@@ -41,7 +41,9 @@ static struct i2c_board_info max9486_hwmon_info = {
41}; 41};
42 42
43#define MAX9485_MCLK_FREQ_112896 0x22 43#define MAX9485_MCLK_FREQ_112896 0x22
44#define MAX9485_MCLK_FREQ_122880 0x23 44#define MAX9485_MCLK_FREQ_122880 0x23
45#define MAX9485_MCLK_FREQ_225792 0x32
46#define MAX9485_MCLK_FREQ_245760 0x33
45 47
46static void set_max9485_clk(char clk) 48static void set_max9485_clk(char clk)
47{ 49{
@@ -71,9 +73,17 @@ static int raumfeld_cs4270_startup(struct snd_pcm_substream *substream)
71 struct snd_soc_pcm_runtime *rtd = substream->private_data; 73 struct snd_soc_pcm_runtime *rtd = substream->private_data;
72 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 74 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
73 75
74 set_max9485_clk(MAX9485_MCLK_FREQ_112896); 76 /* set freq to 0 to enable all possible codec sample rates */
77 return snd_soc_dai_set_sysclk(codec_dai, 0, 0, 0);
78}
75 79
76 return snd_soc_dai_set_sysclk(codec_dai, 0, 11289600, 0); 80static void raumfeld_cs4270_shutdown(struct snd_pcm_substream *substream)
81{
82 struct snd_soc_pcm_runtime *rtd = substream->private_data;
83 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
84
85 /* set freq to 0 to enable all possible codec sample rates */
86 snd_soc_dai_set_sysclk(codec_dai, 0, 0, 0);
77} 87}
78 88
79static int raumfeld_cs4270_hw_params(struct snd_pcm_substream *substream, 89static int raumfeld_cs4270_hw_params(struct snd_pcm_substream *substream,
@@ -86,20 +96,24 @@ static int raumfeld_cs4270_hw_params(struct snd_pcm_substream *substream,
86 int ret = 0; 96 int ret = 0;
87 97
88 switch (params_rate(params)) { 98 switch (params_rate(params)) {
89 case 8000: 99 case 44100:
90 case 16000: 100 set_max9485_clk(MAX9485_MCLK_FREQ_112896);
101 clk = 11289600;
102 break;
91 case 48000: 103 case 48000:
92 case 96000:
93 set_max9485_clk(MAX9485_MCLK_FREQ_122880); 104 set_max9485_clk(MAX9485_MCLK_FREQ_122880);
94 clk = 12288000; 105 clk = 12288000;
95 break; 106 break;
96 case 11025:
97 case 22050:
98 case 44100:
99 case 88200: 107 case 88200:
100 set_max9485_clk(MAX9485_MCLK_FREQ_112896); 108 set_max9485_clk(MAX9485_MCLK_FREQ_225792);
101 clk = 11289600; 109 clk = 22579200;
102 break; 110 break;
111 case 96000:
112 set_max9485_clk(MAX9485_MCLK_FREQ_245760);
113 clk = 24576000;
114 break;
115 default:
116 return -EINVAL;
103 } 117 }
104 118
105 fmt = SND_SOC_DAIFMT_I2S | 119 fmt = SND_SOC_DAIFMT_I2S |
@@ -128,7 +142,7 @@ static int raumfeld_cs4270_hw_params(struct snd_pcm_substream *substream,
128 if (ret < 0) 142 if (ret < 0)
129 return ret; 143 return ret;
130 144
131 ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_EXT, 0, 1); 145 ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_EXT, clk, 1);
132 if (ret < 0) 146 if (ret < 0)
133 return ret; 147 return ret;
134 148
@@ -137,6 +151,7 @@ static int raumfeld_cs4270_hw_params(struct snd_pcm_substream *substream,
137 151
138static struct snd_soc_ops raumfeld_cs4270_ops = { 152static struct snd_soc_ops raumfeld_cs4270_ops = {
139 .startup = raumfeld_cs4270_startup, 153 .startup = raumfeld_cs4270_startup,
154 .shutdown = raumfeld_cs4270_shutdown,
140 .hw_params = raumfeld_cs4270_hw_params, 155 .hw_params = raumfeld_cs4270_hw_params,
141}; 156};
142 157
@@ -181,20 +196,24 @@ static int raumfeld_ak4104_hw_params(struct snd_pcm_substream *substream,
181 int fmt, ret = 0, clk = 0; 196 int fmt, ret = 0, clk = 0;
182 197
183 switch (params_rate(params)) { 198 switch (params_rate(params)) {
184 case 8000: 199 case 44100:
185 case 16000: 200 set_max9485_clk(MAX9485_MCLK_FREQ_112896);
201 clk = 11289600;
202 break;
186 case 48000: 203 case 48000:
187 case 96000:
188 set_max9485_clk(MAX9485_MCLK_FREQ_122880); 204 set_max9485_clk(MAX9485_MCLK_FREQ_122880);
189 clk = 12288000; 205 clk = 12288000;
190 break; 206 break;
191 case 11025:
192 case 22050:
193 case 44100:
194 case 88200: 207 case 88200:
195 set_max9485_clk(MAX9485_MCLK_FREQ_112896); 208 set_max9485_clk(MAX9485_MCLK_FREQ_225792);
196 clk = 11289600; 209 clk = 22579200;
210 break;
211 case 96000:
212 set_max9485_clk(MAX9485_MCLK_FREQ_245760);
213 clk = 24576000;
197 break; 214 break;
215 default:
216 return -EINVAL;
198 } 217 }
199 218
200 fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF; 219 fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF;
@@ -217,7 +236,7 @@ static int raumfeld_ak4104_hw_params(struct snd_pcm_substream *substream,
217 if (ret < 0) 236 if (ret < 0)
218 return ret; 237 return ret;
219 238
220 ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_EXT, 0, 1); 239 ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_EXT, clk, 1);
221 if (ret < 0) 240 if (ret < 0)
222 return ret; 241 return ret;
223 242
diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig
index b489f1ae103d..15fe57e5a232 100644
--- a/sound/soc/s3c24xx/Kconfig
+++ b/sound/soc/s3c24xx/Kconfig
@@ -27,12 +27,10 @@ config SND_S3C64XX_SOC_I2S
27config SND_S3C_SOC_PCM 27config SND_S3C_SOC_PCM
28 tristate 28 tristate
29 29
30config SND_S3C2443_SOC_AC97 30config SND_S3C_SOC_AC97
31 tristate 31 tristate
32 select S3C2410_DMA
33 select AC97_BUS
34 select SND_SOC_AC97_BUS 32 select SND_SOC_AC97_BUS
35 33
36config SND_S3C24XX_SOC_NEO1973_WM8753 34config SND_S3C24XX_SOC_NEO1973_WM8753
37 tristate "SoC I2S Audio support for NEO1973 - WM8753" 35 tristate "SoC I2S Audio support for NEO1973 - WM8753"
38 depends on SND_S3C24XX_SOC && MACH_NEO1973_GTA01 36 depends on SND_S3C24XX_SOC && MACH_NEO1973_GTA01
@@ -71,8 +69,10 @@ config SND_S3C64XX_SOC_WM8580
71config SND_S3C24XX_SOC_SMDK2443_WM9710 69config SND_S3C24XX_SOC_SMDK2443_WM9710
72 tristate "SoC AC97 Audio support for SMDK2443 - WM9710" 70 tristate "SoC AC97 Audio support for SMDK2443 - WM9710"
73 depends on SND_S3C24XX_SOC && MACH_SMDK2443 71 depends on SND_S3C24XX_SOC && MACH_SMDK2443
74 select SND_S3C2443_SOC_AC97 72 select S3C2410_DMA
73 select AC97_BUS
75 select SND_SOC_AC97_CODEC 74 select SND_SOC_AC97_CODEC
75 select SND_S3C_SOC_AC97
76 help 76 help
77 Say Y if you want to add support for SoC audio on smdk2443 77 Say Y if you want to add support for SoC audio on smdk2443
78 with the WM9710. 78 with the WM9710.
@@ -80,8 +80,10 @@ config SND_S3C24XX_SOC_SMDK2443_WM9710
80config SND_S3C24XX_SOC_LN2440SBC_ALC650 80config SND_S3C24XX_SOC_LN2440SBC_ALC650
81 tristate "SoC AC97 Audio support for LN2440SBC - ALC650" 81 tristate "SoC AC97 Audio support for LN2440SBC - ALC650"
82 depends on SND_S3C24XX_SOC && ARCH_S3C2410 82 depends on SND_S3C24XX_SOC && ARCH_S3C2410
83 select SND_S3C2443_SOC_AC97 83 select S3C2410_DMA
84 select AC97_BUS
84 select SND_SOC_AC97_CODEC 85 select SND_SOC_AC97_CODEC
86 select SND_S3C_SOC_AC97
85 help 87 help
86 Say Y if you want to add support for SoC audio on ln2440sbc 88 Say Y if you want to add support for SoC audio on ln2440sbc
87 with the ALC650. 89 with the ALC650.
@@ -111,3 +113,11 @@ config SND_S3C24XX_SOC_SIMTEC_HERMES
111 select SND_S3C24XX_SOC_I2S 113 select SND_S3C24XX_SOC_I2S
112 select SND_SOC_TLV320AIC3X 114 select SND_SOC_TLV320AIC3X
113 select SND_S3C24XX_SOC_SIMTEC 115 select SND_S3C24XX_SOC_SIMTEC
116
117config SND_SOC_SMDK_WM9713
118 tristate "SoC AC97 Audio support for SMDK with WM9713"
119 depends on SND_S3C24XX_SOC && MACH_SMDK6410
120 select SND_SOC_WM9713
121 select SND_S3C_SOC_AC97
122 help
123 Sat Y if you want to add support for SoC audio on the SMDK.
diff --git a/sound/soc/s3c24xx/Makefile b/sound/soc/s3c24xx/Makefile
index b744657733d7..df071a376fa2 100644
--- a/sound/soc/s3c24xx/Makefile
+++ b/sound/soc/s3c24xx/Makefile
@@ -3,13 +3,13 @@ snd-soc-s3c24xx-objs := s3c-dma.o
3snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o 3snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o
4snd-soc-s3c2412-i2s-objs := s3c2412-i2s.o 4snd-soc-s3c2412-i2s-objs := s3c2412-i2s.o
5snd-soc-s3c64xx-i2s-objs := s3c64xx-i2s.o 5snd-soc-s3c64xx-i2s-objs := s3c64xx-i2s.o
6snd-soc-s3c2443-ac97-objs := s3c2443-ac97.o 6snd-soc-s3c-ac97-objs := s3c-ac97.o
7snd-soc-s3c-i2s-v2-objs := s3c-i2s-v2.o 7snd-soc-s3c-i2s-v2-objs := s3c-i2s-v2.o
8snd-soc-s3c-pcm-objs := s3c-pcm.o 8snd-soc-s3c-pcm-objs := s3c-pcm.o
9 9
10obj-$(CONFIG_SND_S3C24XX_SOC) += snd-soc-s3c24xx.o 10obj-$(CONFIG_SND_S3C24XX_SOC) += snd-soc-s3c24xx.o
11obj-$(CONFIG_SND_S3C24XX_SOC_I2S) += snd-soc-s3c24xx-i2s.o 11obj-$(CONFIG_SND_S3C24XX_SOC_I2S) += snd-soc-s3c24xx-i2s.o
12obj-$(CONFIG_SND_S3C2443_SOC_AC97) += snd-soc-s3c2443-ac97.o 12obj-$(CONFIG_SND_S3C_SOC_AC97) += snd-soc-s3c-ac97.o
13obj-$(CONFIG_SND_S3C2412_SOC_I2S) += snd-soc-s3c2412-i2s.o 13obj-$(CONFIG_SND_S3C2412_SOC_I2S) += snd-soc-s3c2412-i2s.o
14obj-$(CONFIG_SND_S3C64XX_SOC_I2S) += snd-soc-s3c64xx-i2s.o 14obj-$(CONFIG_SND_S3C64XX_SOC_I2S) += snd-soc-s3c64xx-i2s.o
15obj-$(CONFIG_SND_S3C_I2SV2_SOC) += snd-soc-s3c-i2s-v2.o 15obj-$(CONFIG_SND_S3C_I2SV2_SOC) += snd-soc-s3c-i2s-v2.o
@@ -26,6 +26,7 @@ snd-soc-s3c24xx-simtec-objs := s3c24xx_simtec.o
26snd-soc-s3c24xx-simtec-hermes-objs := s3c24xx_simtec_hermes.o 26snd-soc-s3c24xx-simtec-hermes-objs := s3c24xx_simtec_hermes.o
27snd-soc-s3c24xx-simtec-tlv320aic23-objs := s3c24xx_simtec_tlv320aic23.o 27snd-soc-s3c24xx-simtec-tlv320aic23-objs := s3c24xx_simtec_tlv320aic23.o
28snd-soc-smdk64xx-wm8580-objs := smdk64xx_wm8580.o 28snd-soc-smdk64xx-wm8580-objs := smdk64xx_wm8580.o
29snd-soc-smdk-wm9713-objs := smdk_wm9713.o
29 30
30obj-$(CONFIG_SND_S3C24XX_SOC_JIVE_WM8750) += snd-soc-jive-wm8750.o 31obj-$(CONFIG_SND_S3C24XX_SOC_JIVE_WM8750) += snd-soc-jive-wm8750.o
31obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o 32obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o
@@ -37,4 +38,4 @@ obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC) += snd-soc-s3c24xx-simtec.o
37obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC_HERMES) += snd-soc-s3c24xx-simtec-hermes.o 38obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC_HERMES) += snd-soc-s3c24xx-simtec-hermes.o
38obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC_TLV320AIC23) += snd-soc-s3c24xx-simtec-tlv320aic23.o 39obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC_TLV320AIC23) += snd-soc-s3c24xx-simtec-tlv320aic23.o
39obj-$(CONFIG_SND_S3C64XX_SOC_WM8580) += snd-soc-smdk64xx-wm8580.o 40obj-$(CONFIG_SND_S3C64XX_SOC_WM8580) += snd-soc-smdk64xx-wm8580.o
40 41obj-$(CONFIG_SND_SOC_SMDK_WM9713) += snd-soc-smdk-wm9713.o
diff --git a/sound/soc/s3c24xx/ln2440sbc_alc650.c b/sound/soc/s3c24xx/ln2440sbc_alc650.c
index d00d359a03e6..ffa954fe6931 100644
--- a/sound/soc/s3c24xx/ln2440sbc_alc650.c
+++ b/sound/soc/s3c24xx/ln2440sbc_alc650.c
@@ -25,7 +25,7 @@
25 25
26#include "../codecs/ac97.h" 26#include "../codecs/ac97.h"
27#include "s3c-dma.h" 27#include "s3c-dma.h"
28#include "s3c24xx-ac97.h" 28#include "s3c-ac97.h"
29 29
30static struct snd_soc_card ln2440sbc; 30static struct snd_soc_card ln2440sbc;
31 31
@@ -33,7 +33,7 @@ static struct snd_soc_dai_link ln2440sbc_dai[] = {
33{ 33{
34 .name = "AC97", 34 .name = "AC97",
35 .stream_name = "AC97 HiFi", 35 .stream_name = "AC97 HiFi",
36 .cpu_dai = &s3c2443_ac97_dai[0], 36 .cpu_dai = &s3c_ac97_dai[S3C_AC97_DAI_PCM],
37 .codec_dai = &ac97_dai, 37 .codec_dai = &ac97_dai,
38}, 38},
39}; 39};
diff --git a/sound/soc/s3c24xx/s3c-ac97.c b/sound/soc/s3c24xx/s3c-ac97.c
new file mode 100644
index 000000000000..ee8ed9d7e703
--- /dev/null
+++ b/sound/soc/s3c24xx/s3c-ac97.c
@@ -0,0 +1,518 @@
1/* sound/soc/s3c24xx/s3c-ac97.c
2 *
3 * ALSA SoC Audio Layer - S3C AC97 Controller driver
4 * Evolved from s3c2443-ac97.c
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#include <linux/init.h>
16#include <linux/module.h>
17#include <linux/io.h>
18#include <linux/delay.h>
19#include <linux/clk.h>
20
21#include <sound/soc.h>
22
23#include <plat/regs-ac97.h>
24#include <mach/dma.h>
25#include <plat/audio.h>
26
27#include "s3c-dma.h"
28#include "s3c-ac97.h"
29
30#define AC_CMD_ADDR(x) (x << 16)
31#define AC_CMD_DATA(x) (x & 0xffff)
32
33struct s3c_ac97_info {
34 unsigned state;
35 struct clk *ac97_clk;
36 void __iomem *regs;
37 struct mutex lock;
38 struct completion done;
39};
40static struct s3c_ac97_info s3c_ac97;
41
42static struct s3c2410_dma_client s3c_dma_client_out = {
43 .name = "AC97 PCMOut"
44};
45
46static struct s3c2410_dma_client s3c_dma_client_in = {
47 .name = "AC97 PCMIn"
48};
49
50static struct s3c2410_dma_client s3c_dma_client_micin = {
51 .name = "AC97 MicIn"
52};
53
54static struct s3c_dma_params s3c_ac97_pcm_out = {
55 .client = &s3c_dma_client_out,
56 .dma_size = 4,
57};
58
59static struct s3c_dma_params s3c_ac97_pcm_in = {
60 .client = &s3c_dma_client_in,
61 .dma_size = 4,
62};
63
64static struct s3c_dma_params s3c_ac97_mic_in = {
65 .client = &s3c_dma_client_micin,
66 .dma_size = 4,
67};
68
69static void s3c_ac97_activate(struct snd_ac97 *ac97)
70{
71 u32 ac_glbctrl, stat;
72
73 stat = readl(s3c_ac97.regs + S3C_AC97_GLBSTAT) & 0x7;
74 if (stat == S3C_AC97_GLBSTAT_MAINSTATE_ACTIVE)
75 return; /* Return if already active */
76
77 INIT_COMPLETION(s3c_ac97.done);
78
79 ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL);
80 ac_glbctrl = S3C_AC97_GLBCTRL_ACLINKON;
81 writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
82 msleep(1);
83
84 ac_glbctrl |= S3C_AC97_GLBCTRL_TRANSFERDATAENABLE;
85 writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
86 msleep(1);
87
88 ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL);
89 ac_glbctrl |= S3C_AC97_GLBCTRL_CODECREADYIE;
90 writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
91
92 if (!wait_for_completion_timeout(&s3c_ac97.done, HZ))
93 printk(KERN_ERR "AC97: Unable to activate!");
94}
95
96static unsigned short s3c_ac97_read(struct snd_ac97 *ac97,
97 unsigned short reg)
98{
99 u32 ac_glbctrl, ac_codec_cmd;
100 u32 stat, addr, data;
101
102 mutex_lock(&s3c_ac97.lock);
103
104 s3c_ac97_activate(ac97);
105
106 INIT_COMPLETION(s3c_ac97.done);
107
108 ac_codec_cmd = readl(s3c_ac97.regs + S3C_AC97_CODEC_CMD);
109 ac_codec_cmd = S3C_AC97_CODEC_CMD_READ | AC_CMD_ADDR(reg);
110 writel(ac_codec_cmd, s3c_ac97.regs + S3C_AC97_CODEC_CMD);
111
112 udelay(50);
113
114 ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL);
115 ac_glbctrl |= S3C_AC97_GLBCTRL_CODECREADYIE;
116 writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
117
118 if (!wait_for_completion_timeout(&s3c_ac97.done, HZ))
119 printk(KERN_ERR "AC97: Unable to read!");
120
121 stat = readl(s3c_ac97.regs + S3C_AC97_STAT);
122 addr = (stat >> 16) & 0x7f;
123 data = (stat & 0xffff);
124
125 if (addr != reg)
126 printk(KERN_ERR "s3c-ac97: req addr = %02x, rep addr = %02x\n", reg, addr);
127
128 mutex_unlock(&s3c_ac97.lock);
129
130 return (unsigned short)data;
131}
132
133static void s3c_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
134 unsigned short val)
135{
136 u32 ac_glbctrl, ac_codec_cmd;
137
138 mutex_lock(&s3c_ac97.lock);
139
140 s3c_ac97_activate(ac97);
141
142 INIT_COMPLETION(s3c_ac97.done);
143
144 ac_codec_cmd = readl(s3c_ac97.regs + S3C_AC97_CODEC_CMD);
145 ac_codec_cmd = AC_CMD_ADDR(reg) | AC_CMD_DATA(val);
146 writel(ac_codec_cmd, s3c_ac97.regs + S3C_AC97_CODEC_CMD);
147
148 udelay(50);
149
150 ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL);
151 ac_glbctrl |= S3C_AC97_GLBCTRL_CODECREADYIE;
152 writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
153
154 if (!wait_for_completion_timeout(&s3c_ac97.done, HZ))
155 printk(KERN_ERR "AC97: Unable to write!");
156
157 ac_codec_cmd = readl(s3c_ac97.regs + S3C_AC97_CODEC_CMD);
158 ac_codec_cmd |= S3C_AC97_CODEC_CMD_READ;
159 writel(ac_codec_cmd, s3c_ac97.regs + S3C_AC97_CODEC_CMD);
160
161 mutex_unlock(&s3c_ac97.lock);
162}
163
164static void s3c_ac97_cold_reset(struct snd_ac97 *ac97)
165{
166 writel(S3C_AC97_GLBCTRL_COLDRESET,
167 s3c_ac97.regs + S3C_AC97_GLBCTRL);
168 msleep(1);
169
170 writel(0, s3c_ac97.regs + S3C_AC97_GLBCTRL);
171 msleep(1);
172}
173
174static void s3c_ac97_warm_reset(struct snd_ac97 *ac97)
175{
176 u32 stat;
177
178 stat = readl(s3c_ac97.regs + S3C_AC97_GLBSTAT) & 0x7;
179 if (stat == S3C_AC97_GLBSTAT_MAINSTATE_ACTIVE)
180 return; /* Return if already active */
181
182 writel(S3C_AC97_GLBCTRL_WARMRESET, s3c_ac97.regs + S3C_AC97_GLBCTRL);
183 msleep(1);
184
185 writel(0, s3c_ac97.regs + S3C_AC97_GLBCTRL);
186 msleep(1);
187
188 s3c_ac97_activate(ac97);
189}
190
191static irqreturn_t s3c_ac97_irq(int irq, void *dev_id)
192{
193 u32 ac_glbctrl, ac_glbstat;
194
195 ac_glbstat = readl(s3c_ac97.regs + S3C_AC97_GLBSTAT);
196
197 if (ac_glbstat & S3C_AC97_GLBSTAT_CODECREADY) {
198
199 ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL);
200 ac_glbctrl &= ~S3C_AC97_GLBCTRL_CODECREADYIE;
201 writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
202
203 complete(&s3c_ac97.done);
204 }
205
206 ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL);
207 ac_glbctrl |= (1<<30); /* Clear interrupt */
208 writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
209
210 return IRQ_HANDLED;
211}
212
213struct snd_ac97_bus_ops soc_ac97_ops = {
214 .read = s3c_ac97_read,
215 .write = s3c_ac97_write,
216 .warm_reset = s3c_ac97_warm_reset,
217 .reset = s3c_ac97_cold_reset,
218};
219EXPORT_SYMBOL_GPL(soc_ac97_ops);
220
221static int s3c_ac97_hw_params(struct snd_pcm_substream *substream,
222 struct snd_pcm_hw_params *params,
223 struct snd_soc_dai *dai)
224{
225 struct snd_soc_pcm_runtime *rtd = substream->private_data;
226 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
227
228 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
229 cpu_dai->dma_data = &s3c_ac97_pcm_out;
230 else
231 cpu_dai->dma_data = &s3c_ac97_pcm_in;
232
233 return 0;
234}
235
236static int s3c_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
237 struct snd_soc_dai *dai)
238{
239 u32 ac_glbctrl;
240 struct snd_soc_pcm_runtime *rtd = substream->private_data;
241 int channel = ((struct s3c_dma_params *)
242 rtd->dai->cpu_dai->dma_data)->channel;
243
244 ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL);
245 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
246 ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMINTM_MASK;
247 else
248 ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMOUTTM_MASK;
249
250 switch (cmd) {
251 case SNDRV_PCM_TRIGGER_START:
252 case SNDRV_PCM_TRIGGER_RESUME:
253 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
254 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
255 ac_glbctrl |= S3C_AC97_GLBCTRL_PCMINTM_DMA;
256 else
257 ac_glbctrl |= S3C_AC97_GLBCTRL_PCMOUTTM_DMA;
258 break;
259
260 case SNDRV_PCM_TRIGGER_STOP:
261 case SNDRV_PCM_TRIGGER_SUSPEND:
262 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
263 break;
264 }
265
266 writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
267
268 s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED);
269
270 return 0;
271}
272
273static int s3c_ac97_hw_mic_params(struct snd_pcm_substream *substream,
274 struct snd_pcm_hw_params *params,
275 struct snd_soc_dai *dai)
276{
277 struct snd_soc_pcm_runtime *rtd = substream->private_data;
278 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
279
280 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
281 return -ENODEV;
282 else
283 cpu_dai->dma_data = &s3c_ac97_mic_in;
284
285 return 0;
286}
287
288static int s3c_ac97_mic_trigger(struct snd_pcm_substream *substream,
289 int cmd, struct snd_soc_dai *dai)
290{
291 u32 ac_glbctrl;
292 struct snd_soc_pcm_runtime *rtd = substream->private_data;
293 int channel = ((struct s3c_dma_params *)
294 rtd->dai->cpu_dai->dma_data)->channel;
295
296 ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL);
297 ac_glbctrl &= ~S3C_AC97_GLBCTRL_MICINTM_MASK;
298
299 switch (cmd) {
300 case SNDRV_PCM_TRIGGER_START:
301 case SNDRV_PCM_TRIGGER_RESUME:
302 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
303 ac_glbctrl |= S3C_AC97_GLBCTRL_MICINTM_DMA;
304 break;
305
306 case SNDRV_PCM_TRIGGER_STOP:
307 case SNDRV_PCM_TRIGGER_SUSPEND:
308 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
309 break;
310 }
311
312 writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
313
314 s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED);
315
316 return 0;
317}
318
319static struct snd_soc_dai_ops s3c_ac97_dai_ops = {
320 .hw_params = s3c_ac97_hw_params,
321 .trigger = s3c_ac97_trigger,
322};
323
324static struct snd_soc_dai_ops s3c_ac97_mic_dai_ops = {
325 .hw_params = s3c_ac97_hw_mic_params,
326 .trigger = s3c_ac97_mic_trigger,
327};
328
329struct snd_soc_dai s3c_ac97_dai[] = {
330 [S3C_AC97_DAI_PCM] = {
331 .name = "s3c-ac97",
332 .id = S3C_AC97_DAI_PCM,
333 .ac97_control = 1,
334 .playback = {
335 .stream_name = "AC97 Playback",
336 .channels_min = 2,
337 .channels_max = 2,
338 .rates = SNDRV_PCM_RATE_8000_48000,
339 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
340 .capture = {
341 .stream_name = "AC97 Capture",
342 .channels_min = 2,
343 .channels_max = 2,
344 .rates = SNDRV_PCM_RATE_8000_48000,
345 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
346 .ops = &s3c_ac97_dai_ops,
347 },
348 [S3C_AC97_DAI_MIC] = {
349 .name = "s3c-ac97-mic",
350 .id = S3C_AC97_DAI_MIC,
351 .ac97_control = 1,
352 .capture = {
353 .stream_name = "AC97 Mic Capture",
354 .channels_min = 1,
355 .channels_max = 1,
356 .rates = SNDRV_PCM_RATE_8000_48000,
357 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
358 .ops = &s3c_ac97_mic_dai_ops,
359 },
360};
361EXPORT_SYMBOL_GPL(s3c_ac97_dai);
362
363static __devinit int s3c_ac97_probe(struct platform_device *pdev)
364{
365 struct resource *mem_res, *dmatx_res, *dmarx_res, *dmamic_res, *irq_res;
366 struct s3c_audio_pdata *ac97_pdata;
367 int ret;
368
369 ac97_pdata = pdev->dev.platform_data;
370 if (!ac97_pdata || !ac97_pdata->cfg_gpio) {
371 dev_err(&pdev->dev, "cfg_gpio callback not provided!\n");
372 return -EINVAL;
373 }
374
375 /* Check for availability of necessary resource */
376 dmatx_res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
377 if (!dmatx_res) {
378 dev_err(&pdev->dev, "Unable to get AC97-TX dma resource\n");
379 return -ENXIO;
380 }
381
382 dmarx_res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
383 if (!dmarx_res) {
384 dev_err(&pdev->dev, "Unable to get AC97-RX dma resource\n");
385 return -ENXIO;
386 }
387
388 dmamic_res = platform_get_resource(pdev, IORESOURCE_DMA, 2);
389 if (!dmamic_res) {
390 dev_err(&pdev->dev, "Unable to get AC97-MIC dma resource\n");
391 return -ENXIO;
392 }
393
394 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
395 if (!mem_res) {
396 dev_err(&pdev->dev, "Unable to get register resource\n");
397 return -ENXIO;
398 }
399
400 irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
401 if (!irq_res) {
402 dev_err(&pdev->dev, "AC97 IRQ not provided!\n");
403 return -ENXIO;
404 }
405
406 if (!request_mem_region(mem_res->start,
407 resource_size(mem_res), "s3c-ac97")) {
408 dev_err(&pdev->dev, "Unable to request register region\n");
409 return -EBUSY;
410 }
411
412 s3c_ac97_pcm_out.channel = dmatx_res->start;
413 s3c_ac97_pcm_out.dma_addr = mem_res->start + S3C_AC97_PCM_DATA;
414 s3c_ac97_pcm_in.channel = dmarx_res->start;
415 s3c_ac97_pcm_in.dma_addr = mem_res->start + S3C_AC97_PCM_DATA;
416 s3c_ac97_mic_in.channel = dmamic_res->start;
417 s3c_ac97_mic_in.dma_addr = mem_res->start + S3C_AC97_MIC_DATA;
418
419 init_completion(&s3c_ac97.done);
420 mutex_init(&s3c_ac97.lock);
421
422 s3c_ac97.regs = ioremap(mem_res->start, resource_size(mem_res));
423 if (s3c_ac97.regs == NULL) {
424 dev_err(&pdev->dev, "Unable to ioremap register region\n");
425 ret = -ENXIO;
426 goto err1;
427 }
428
429 s3c_ac97.ac97_clk = clk_get(&pdev->dev, "ac97");
430 if (IS_ERR(s3c_ac97.ac97_clk)) {
431 dev_err(&pdev->dev, "s3c-ac97 failed to get ac97_clock\n");
432 ret = -ENODEV;
433 goto err2;
434 }
435 clk_enable(s3c_ac97.ac97_clk);
436
437 if (ac97_pdata->cfg_gpio(pdev)) {
438 dev_err(&pdev->dev, "Unable to configure gpio\n");
439 ret = -EINVAL;
440 goto err3;
441 }
442
443 ret = request_irq(irq_res->start, s3c_ac97_irq,
444 IRQF_DISABLED, "AC97", NULL);
445 if (ret < 0) {
446 printk(KERN_ERR "s3c-ac97: interrupt request failed.\n");
447 goto err4;
448 }
449
450 s3c_ac97_dai[S3C_AC97_DAI_PCM].dev = &pdev->dev;
451 s3c_ac97_dai[S3C_AC97_DAI_MIC].dev = &pdev->dev;
452
453 ret = snd_soc_register_dais(s3c_ac97_dai, ARRAY_SIZE(s3c_ac97_dai));
454 if (ret)
455 goto err5;
456
457 return 0;
458
459err5:
460 free_irq(irq_res->start, NULL);
461err4:
462err3:
463 clk_disable(s3c_ac97.ac97_clk);
464 clk_put(s3c_ac97.ac97_clk);
465err2:
466 iounmap(s3c_ac97.regs);
467err1:
468 release_mem_region(mem_res->start, resource_size(mem_res));
469
470 return ret;
471}
472
473static __devexit int s3c_ac97_remove(struct platform_device *pdev)
474{
475 struct resource *mem_res, *irq_res;
476
477 snd_soc_unregister_dais(s3c_ac97_dai, ARRAY_SIZE(s3c_ac97_dai));
478
479 irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
480 if (irq_res)
481 free_irq(irq_res->start, NULL);
482
483 clk_disable(s3c_ac97.ac97_clk);
484 clk_put(s3c_ac97.ac97_clk);
485
486 iounmap(s3c_ac97.regs);
487
488 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
489 if (mem_res)
490 release_mem_region(mem_res->start, resource_size(mem_res));
491
492 return 0;
493}
494
495static struct platform_driver s3c_ac97_driver = {
496 .probe = s3c_ac97_probe,
497 .remove = s3c_ac97_remove,
498 .driver = {
499 .name = "s3c-ac97",
500 .owner = THIS_MODULE,
501 },
502};
503
504static int __init s3c_ac97_init(void)
505{
506 return platform_driver_register(&s3c_ac97_driver);
507}
508module_init(s3c_ac97_init);
509
510static void __exit s3c_ac97_exit(void)
511{
512 platform_driver_unregister(&s3c_ac97_driver);
513}
514module_exit(s3c_ac97_exit);
515
516MODULE_AUTHOR("Jaswinder Singh, <jassi.brar@samsung.com>");
517MODULE_DESCRIPTION("AC97 driver for the Samsung SoC");
518MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/s3c-ac97.h b/sound/soc/s3c24xx/s3c-ac97.h
new file mode 100644
index 000000000000..278198379def
--- /dev/null
+++ b/sound/soc/s3c24xx/s3c-ac97.h
@@ -0,0 +1,23 @@
1/* sound/soc/s3c24xx/s3c-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
21extern struct snd_soc_dai s3c_ac97_dai[];
22
23#endif /* __S3C_AC97_H_ */
diff --git a/sound/soc/s3c24xx/s3c-pcm.c b/sound/soc/s3c24xx/s3c-pcm.c
index 9e61a7c2d9ac..a98f40c3cd29 100644
--- a/sound/soc/s3c24xx/s3c-pcm.c
+++ b/sound/soc/s3c24xx/s3c-pcm.c
@@ -229,8 +229,7 @@ static int s3c_pcm_hw_params(struct snd_pcm_substream *substream,
229 229
230 spin_unlock_irqrestore(&pcm->lock, flags); 230 spin_unlock_irqrestore(&pcm->lock, flags);
231 231
232 dev_dbg(pcm->dev, "PCMSOURCE_CLK-%lu SCLK=%ufs \ 232 dev_dbg(pcm->dev, "PCMSOURCE_CLK-%lu SCLK=%ufs SCLK_DIV=%d SYNC_DIV=%d\n",
233 SCLK_DIV=%d SYNC_DIV=%d\n",
234 clk_get_rate(clk), pcm->sclk_per_fs, 233 clk_get_rate(clk), pcm->sclk_per_fs,
235 sclk_div, sync_div); 234 sclk_div, sync_div);
236 235
diff --git a/sound/soc/s3c24xx/s3c2443-ac97.c b/sound/soc/s3c24xx/s3c2443-ac97.c
deleted file mode 100644
index 0191e3acb0b4..000000000000
--- a/sound/soc/s3c24xx/s3c2443-ac97.c
+++ /dev/null
@@ -1,432 +0,0 @@
1/*
2 * s3c2443-ac97.c -- ALSA Soc Audio Layer
3 *
4 * (c) 2007 Wolfson Microelectronics PLC.
5 * Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
6 *
7 * Copyright (C) 2005, Sean Choi <sh428.choi@samsung.com>
8 * All rights reserved.
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#include <linux/init.h>
16#include <linux/module.h>
17#include <linux/platform_device.h>
18#include <linux/interrupt.h>
19#include <linux/io.h>
20#include <linux/wait.h>
21#include <linux/delay.h>
22#include <linux/gpio.h>
23#include <linux/clk.h>
24
25#include <sound/core.h>
26#include <sound/pcm.h>
27#include <sound/ac97_codec.h>
28#include <sound/initval.h>
29#include <sound/soc.h>
30
31#include <mach/hardware.h>
32#include <plat/regs-ac97.h>
33#include <mach/regs-gpio.h>
34#include <mach/regs-clock.h>
35#include <asm/dma.h>
36#include <mach/dma.h>
37
38#include "s3c-dma.h"
39#include "s3c24xx-ac97.h"
40
41struct s3c24xx_ac97_info {
42 void __iomem *regs;
43 struct clk *ac97_clk;
44};
45static struct s3c24xx_ac97_info s3c24xx_ac97;
46
47static DECLARE_COMPLETION(ac97_completion);
48static u32 codec_ready;
49static DEFINE_MUTEX(ac97_mutex);
50
51static unsigned short s3c2443_ac97_read(struct snd_ac97 *ac97,
52 unsigned short reg)
53{
54 u32 ac_glbctrl;
55 u32 ac_codec_cmd;
56 u32 stat, addr, data;
57
58 mutex_lock(&ac97_mutex);
59
60 codec_ready = S3C_AC97_GLBSTAT_CODECREADY;
61 ac_codec_cmd = readl(s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD);
62 ac_codec_cmd = S3C_AC97_CODEC_CMD_READ | AC_CMD_ADDR(reg);
63 writel(ac_codec_cmd, s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD);
64
65 udelay(50);
66
67 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
68 ac_glbctrl |= S3C_AC97_GLBCTRL_CODECREADYIE;
69 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
70
71 wait_for_completion(&ac97_completion);
72
73 stat = readl(s3c24xx_ac97.regs + S3C_AC97_STAT);
74 addr = (stat >> 16) & 0x7f;
75 data = (stat & 0xffff);
76
77 if (addr != reg)
78 printk(KERN_ERR "s3c24xx-ac97: req addr = %02x,"
79 " rep addr = %02x\n", reg, addr);
80
81 mutex_unlock(&ac97_mutex);
82
83 return (unsigned short)data;
84}
85
86static void s3c2443_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
87 unsigned short val)
88{
89 u32 ac_glbctrl;
90 u32 ac_codec_cmd;
91
92 mutex_lock(&ac97_mutex);
93
94 codec_ready = S3C_AC97_GLBSTAT_CODECREADY;
95 ac_codec_cmd = readl(s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD);
96 ac_codec_cmd = AC_CMD_ADDR(reg) | AC_CMD_DATA(val);
97 writel(ac_codec_cmd, s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD);
98
99 udelay(50);
100
101 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
102 ac_glbctrl |= S3C_AC97_GLBCTRL_CODECREADYIE;
103 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
104
105 wait_for_completion(&ac97_completion);
106
107 ac_codec_cmd = readl(s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD);
108 ac_codec_cmd |= S3C_AC97_CODEC_CMD_READ;
109 writel(ac_codec_cmd, s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD);
110
111 mutex_unlock(&ac97_mutex);
112
113}
114
115static void s3c2443_ac97_warm_reset(struct snd_ac97 *ac97)
116{
117 u32 ac_glbctrl;
118
119 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
120 ac_glbctrl = S3C_AC97_GLBCTRL_WARMRESET;
121 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
122 msleep(1);
123
124 ac_glbctrl = 0;
125 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
126 msleep(1);
127}
128
129static void s3c2443_ac97_cold_reset(struct snd_ac97 *ac97)
130{
131 u32 ac_glbctrl;
132
133 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
134 ac_glbctrl = S3C_AC97_GLBCTRL_COLDRESET;
135 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
136 msleep(1);
137
138 ac_glbctrl = 0;
139 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
140 msleep(1);
141
142 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
143 ac_glbctrl = S3C_AC97_GLBCTRL_ACLINKON;
144 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
145 msleep(1);
146
147 ac_glbctrl |= S3C_AC97_GLBCTRL_TRANSFERDATAENABLE;
148 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
149 msleep(1);
150
151 ac_glbctrl |= S3C_AC97_GLBCTRL_PCMOUTTM_DMA |
152 S3C_AC97_GLBCTRL_PCMINTM_DMA | S3C_AC97_GLBCTRL_MICINTM_DMA;
153 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
154}
155
156static irqreturn_t s3c2443_ac97_irq(int irq, void *dev_id)
157{
158 int status;
159 u32 ac_glbctrl;
160
161 status = readl(s3c24xx_ac97.regs + S3C_AC97_GLBSTAT) & codec_ready;
162
163 if (status) {
164 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
165 ac_glbctrl &= ~S3C_AC97_GLBCTRL_CODECREADYIE;
166 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
167 complete(&ac97_completion);
168 }
169 return IRQ_HANDLED;
170}
171
172struct snd_ac97_bus_ops soc_ac97_ops = {
173 .read = s3c2443_ac97_read,
174 .write = s3c2443_ac97_write,
175 .warm_reset = s3c2443_ac97_warm_reset,
176 .reset = s3c2443_ac97_cold_reset,
177};
178
179static struct s3c2410_dma_client s3c2443_dma_client_out = {
180 .name = "AC97 PCM Stereo out"
181};
182
183static struct s3c2410_dma_client s3c2443_dma_client_in = {
184 .name = "AC97 PCM Stereo in"
185};
186
187static struct s3c2410_dma_client s3c2443_dma_client_micin = {
188 .name = "AC97 Mic Mono in"
189};
190
191static struct s3c_dma_params s3c2443_ac97_pcm_stereo_out = {
192 .client = &s3c2443_dma_client_out,
193 .channel = DMACH_PCM_OUT,
194 .dma_addr = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA,
195 .dma_size = 4,
196};
197
198static struct s3c_dma_params s3c2443_ac97_pcm_stereo_in = {
199 .client = &s3c2443_dma_client_in,
200 .channel = DMACH_PCM_IN,
201 .dma_addr = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA,
202 .dma_size = 4,
203};
204
205static struct s3c_dma_params s3c2443_ac97_mic_mono_in = {
206 .client = &s3c2443_dma_client_micin,
207 .channel = DMACH_MIC_IN,
208 .dma_addr = S3C2440_PA_AC97 + S3C_AC97_MIC_DATA,
209 .dma_size = 4,
210};
211
212static int s3c2443_ac97_probe(struct platform_device *pdev,
213 struct snd_soc_dai *dai)
214{
215 int ret;
216 u32 ac_glbctrl;
217
218 s3c24xx_ac97.regs = ioremap(S3C2440_PA_AC97, 0x100);
219 if (s3c24xx_ac97.regs == NULL)
220 return -ENXIO;
221
222 s3c24xx_ac97.ac97_clk = clk_get(&pdev->dev, "ac97");
223 if (s3c24xx_ac97.ac97_clk == NULL) {
224 printk(KERN_ERR "s3c2443-ac97 failed to get ac97_clock\n");
225 iounmap(s3c24xx_ac97.regs);
226 return -ENODEV;
227 }
228 clk_enable(s3c24xx_ac97.ac97_clk);
229
230 s3c2410_gpio_cfgpin(S3C2410_GPE0, S3C2443_GPE0_AC_nRESET);
231 s3c2410_gpio_cfgpin(S3C2410_GPE1, S3C2443_GPE1_AC_SYNC);
232 s3c2410_gpio_cfgpin(S3C2410_GPE2, S3C2443_GPE2_AC_BITCLK);
233 s3c2410_gpio_cfgpin(S3C2410_GPE3, S3C2443_GPE3_AC_SDI);
234 s3c2410_gpio_cfgpin(S3C2410_GPE4, S3C2443_GPE4_AC_SDO);
235
236 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
237 ac_glbctrl = S3C_AC97_GLBCTRL_COLDRESET;
238 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
239 msleep(1);
240
241 ac_glbctrl = 0;
242 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
243 msleep(1);
244
245 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
246 ac_glbctrl = S3C_AC97_GLBCTRL_ACLINKON;
247 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
248 msleep(1);
249
250 ac_glbctrl |= S3C_AC97_GLBCTRL_TRANSFERDATAENABLE;
251 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
252
253 ret = request_irq(IRQ_S3C244x_AC97, s3c2443_ac97_irq,
254 IRQF_DISABLED, "AC97", NULL);
255 if (ret < 0) {
256 printk(KERN_ERR "s3c24xx-ac97: interrupt request failed.\n");
257 clk_disable(s3c24xx_ac97.ac97_clk);
258 clk_put(s3c24xx_ac97.ac97_clk);
259 iounmap(s3c24xx_ac97.regs);
260 }
261 return ret;
262}
263
264static void s3c2443_ac97_remove(struct platform_device *pdev,
265 struct snd_soc_dai *dai)
266{
267 free_irq(IRQ_S3C244x_AC97, NULL);
268 clk_disable(s3c24xx_ac97.ac97_clk);
269 clk_put(s3c24xx_ac97.ac97_clk);
270 iounmap(s3c24xx_ac97.regs);
271}
272
273static int s3c2443_ac97_hw_params(struct snd_pcm_substream *substream,
274 struct snd_pcm_hw_params *params,
275 struct snd_soc_dai *dai)
276{
277 struct snd_soc_pcm_runtime *rtd = substream->private_data;
278 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
279
280 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
281 cpu_dai->dma_data = &s3c2443_ac97_pcm_stereo_out;
282 else
283 cpu_dai->dma_data = &s3c2443_ac97_pcm_stereo_in;
284
285 return 0;
286}
287
288static int s3c2443_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
289 struct snd_soc_dai *dai)
290{
291 u32 ac_glbctrl;
292 struct snd_soc_pcm_runtime *rtd = substream->private_data;
293 int channel = ((struct s3c_dma_params *)
294 rtd->dai->cpu_dai->dma_data)->channel;
295
296 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
297 switch (cmd) {
298 case SNDRV_PCM_TRIGGER_START:
299 case SNDRV_PCM_TRIGGER_RESUME:
300 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
301 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
302 ac_glbctrl |= S3C_AC97_GLBCTRL_PCMINTM_DMA;
303 else
304 ac_glbctrl |= S3C_AC97_GLBCTRL_PCMOUTTM_DMA;
305 break;
306 case SNDRV_PCM_TRIGGER_STOP:
307 case SNDRV_PCM_TRIGGER_SUSPEND:
308 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
309 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
310 ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMINTM_MASK;
311 else
312 ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMOUTTM_MASK;
313 break;
314 }
315 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
316
317 s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED);
318
319 return 0;
320}
321
322static int s3c2443_ac97_hw_mic_params(struct snd_pcm_substream *substream,
323 struct snd_pcm_hw_params *params,
324 struct snd_soc_dai *dai)
325{
326 struct snd_soc_pcm_runtime *rtd = substream->private_data;
327 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
328
329 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
330 return -ENODEV;
331 else
332 cpu_dai->dma_data = &s3c2443_ac97_mic_mono_in;
333
334 return 0;
335}
336
337static int s3c2443_ac97_mic_trigger(struct snd_pcm_substream *substream,
338 int cmd, struct snd_soc_dai *dai)
339{
340 u32 ac_glbctrl;
341 struct snd_soc_pcm_runtime *rtd = substream->private_data;
342 int channel = ((struct s3c_dma_params *)
343 rtd->dai->cpu_dai->dma_data)->channel;
344
345 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
346 switch (cmd) {
347 case SNDRV_PCM_TRIGGER_START:
348 case SNDRV_PCM_TRIGGER_RESUME:
349 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
350 ac_glbctrl |= S3C_AC97_GLBCTRL_PCMINTM_DMA;
351 break;
352 case SNDRV_PCM_TRIGGER_STOP:
353 case SNDRV_PCM_TRIGGER_SUSPEND:
354 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
355 ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMINTM_MASK;
356 }
357 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
358
359 s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED);
360
361 return 0;
362}
363
364#define s3c2443_AC97_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
365 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \
366 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
367
368static struct snd_soc_dai_ops s3c2443_ac97_dai_ops = {
369 .hw_params = s3c2443_ac97_hw_params,
370 .trigger = s3c2443_ac97_trigger,
371};
372
373static struct snd_soc_dai_ops s3c2443_ac97_mic_dai_ops = {
374 .hw_params = s3c2443_ac97_hw_mic_params,
375 .trigger = s3c2443_ac97_mic_trigger,
376};
377
378struct snd_soc_dai s3c2443_ac97_dai[] = {
379{
380 .name = "s3c2443-ac97",
381 .id = 0,
382 .ac97_control = 1,
383 .probe = s3c2443_ac97_probe,
384 .remove = s3c2443_ac97_remove,
385 .playback = {
386 .stream_name = "AC97 Playback",
387 .channels_min = 2,
388 .channels_max = 2,
389 .rates = s3c2443_AC97_RATES,
390 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
391 .capture = {
392 .stream_name = "AC97 Capture",
393 .channels_min = 2,
394 .channels_max = 2,
395 .rates = s3c2443_AC97_RATES,
396 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
397 .ops = &s3c2443_ac97_dai_ops,
398},
399{
400 .name = "pxa2xx-ac97-mic",
401 .id = 1,
402 .ac97_control = 1,
403 .capture = {
404 .stream_name = "AC97 Mic Capture",
405 .channels_min = 1,
406 .channels_max = 1,
407 .rates = s3c2443_AC97_RATES,
408 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
409 .ops = &s3c2443_ac97_mic_dai_ops,
410},
411};
412EXPORT_SYMBOL_GPL(s3c2443_ac97_dai);
413EXPORT_SYMBOL_GPL(soc_ac97_ops);
414
415static int __init s3c2443_ac97_init(void)
416{
417 return snd_soc_register_dais(s3c2443_ac97_dai,
418 ARRAY_SIZE(s3c2443_ac97_dai));
419}
420module_init(s3c2443_ac97_init);
421
422static void __exit s3c2443_ac97_exit(void)
423{
424 snd_soc_unregister_dais(s3c2443_ac97_dai,
425 ARRAY_SIZE(s3c2443_ac97_dai));
426}
427module_exit(s3c2443_ac97_exit);
428
429
430MODULE_AUTHOR("Graeme Gregory");
431MODULE_DESCRIPTION("AC97 driver for the Samsung s3c2443 chip");
432MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/s3c24xx-ac97.h b/sound/soc/s3c24xx/s3c24xx-ac97.h
deleted file mode 100644
index e96f941a810b..000000000000
--- a/sound/soc/s3c24xx/s3c24xx-ac97.h
+++ /dev/null
@@ -1,25 +0,0 @@
1/*
2 * s3c24xx-ac97.c -- ALSA Soc Audio Layer
3 *
4 * (c) 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 * 10th Nov 2006 Initial version.
15 */
16
17#ifndef S3C24XXAC97_H_
18#define S3C24XXAC97_H_
19
20#define AC_CMD_ADDR(x) (x << 16)
21#define AC_CMD_DATA(x) (x & 0xffff)
22
23extern struct snd_soc_dai s3c2443_ac97_dai[];
24
25#endif /*S3C24XXAC97_H_*/
diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.c b/sound/soc/s3c24xx/s3c64xx-i2s.c
index 22fdb799c883..a72c251401ac 100644
--- a/sound/soc/s3c24xx/s3c64xx-i2s.c
+++ b/sound/soc/s3c24xx/s3c64xx-i2s.c
@@ -15,16 +15,10 @@
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/device.h> 17#include <linux/device.h>
18#include <linux/delay.h>
19#include <linux/clk.h> 18#include <linux/clk.h>
20#include <linux/kernel.h>
21#include <linux/gpio.h> 19#include <linux/gpio.h>
22#include <linux/io.h> 20#include <linux/io.h>
23 21
24#include <sound/core.h>
25#include <sound/pcm.h>
26#include <sound/pcm_params.h>
27#include <sound/initval.h>
28#include <sound/soc.h> 22#include <sound/soc.h>
29 23
30#include <plat/regs-s3c2412-iis.h> 24#include <plat/regs-s3c2412-iis.h>
@@ -38,6 +32,11 @@
38#include "s3c-dma.h" 32#include "s3c-dma.h"
39#include "s3c64xx-i2s.h" 33#include "s3c64xx-i2s.h"
40 34
35/* The value should be set to maximum of the total number
36 * of I2Sv3 controllers that any supported SoC has.
37 */
38#define MAX_I2SV3 2
39
41static struct s3c2410_dma_client s3c64xx_dma_client_out = { 40static struct s3c2410_dma_client s3c64xx_dma_client_out = {
42 .name = "I2S PCM Stereo out" 41 .name = "I2S PCM Stereo out"
43}; 42};
@@ -46,37 +45,12 @@ static struct s3c2410_dma_client s3c64xx_dma_client_in = {
46 .name = "I2S PCM Stereo in" 45 .name = "I2S PCM Stereo in"
47}; 46};
48 47
49static struct s3c_dma_params s3c64xx_i2s_pcm_stereo_out[2] = { 48static struct s3c_dma_params s3c64xx_i2s_pcm_stereo_out[MAX_I2SV3];
50 [0] = { 49static struct s3c_dma_params s3c64xx_i2s_pcm_stereo_in[MAX_I2SV3];
51 .channel = DMACH_I2S0_OUT, 50static struct s3c_i2sv2_info s3c64xx_i2s[MAX_I2SV3];
52 .client = &s3c64xx_dma_client_out,
53 .dma_addr = S3C64XX_PA_IIS0 + S3C2412_IISTXD,
54 .dma_size = 4,
55 },
56 [1] = {
57 .channel = DMACH_I2S1_OUT,
58 .client = &s3c64xx_dma_client_out,
59 .dma_addr = S3C64XX_PA_IIS1 + S3C2412_IISTXD,
60 .dma_size = 4,
61 },
62};
63
64static struct s3c_dma_params s3c64xx_i2s_pcm_stereo_in[2] = {
65 [0] = {
66 .channel = DMACH_I2S0_IN,
67 .client = &s3c64xx_dma_client_in,
68 .dma_addr = S3C64XX_PA_IIS0 + S3C2412_IISRXD,
69 .dma_size = 4,
70 },
71 [1] = {
72 .channel = DMACH_I2S1_IN,
73 .client = &s3c64xx_dma_client_in,
74 .dma_addr = S3C64XX_PA_IIS1 + S3C2412_IISRXD,
75 .dma_size = 4,
76 },
77};
78 51
79static struct s3c_i2sv2_info s3c64xx_i2s[2]; 52struct snd_soc_dai s3c64xx_i2s_dai[MAX_I2SV3];
53EXPORT_SYMBOL_GPL(s3c64xx_i2s_dai);
80 54
81static inline struct s3c_i2sv2_info *to_info(struct snd_soc_dai *cpu_dai) 55static inline struct s3c_i2sv2_info *to_info(struct snd_soc_dai *cpu_dai)
82{ 56{
@@ -169,55 +143,13 @@ static struct snd_soc_dai_ops s3c64xx_i2s_dai_ops = {
169 .set_sysclk = s3c64xx_i2s_set_sysclk, 143 .set_sysclk = s3c64xx_i2s_set_sysclk,
170}; 144};
171 145
172struct snd_soc_dai s3c64xx_i2s_dai[] = {
173 {
174 .name = "s3c64xx-i2s",
175 .id = 0,
176 .probe = s3c64xx_i2s_probe,
177 .playback = {
178 .channels_min = 2,
179 .channels_max = 2,
180 .rates = S3C64XX_I2S_RATES,
181 .formats = S3C64XX_I2S_FMTS,
182 },
183 .capture = {
184 .channels_min = 2,
185 .channels_max = 2,
186 .rates = S3C64XX_I2S_RATES,
187 .formats = S3C64XX_I2S_FMTS,
188 },
189 .ops = &s3c64xx_i2s_dai_ops,
190 .symmetric_rates = 1,
191 },
192 {
193 .name = "s3c64xx-i2s",
194 .id = 1,
195 .probe = s3c64xx_i2s_probe,
196 .playback = {
197 .channels_min = 2,
198 .channels_max = 2,
199 .rates = S3C64XX_I2S_RATES,
200 .formats = S3C64XX_I2S_FMTS,
201 },
202 .capture = {
203 .channels_min = 2,
204 .channels_max = 2,
205 .rates = S3C64XX_I2S_RATES,
206 .formats = S3C64XX_I2S_FMTS,
207 },
208 .ops = &s3c64xx_i2s_dai_ops,
209 .symmetric_rates = 1,
210 },
211};
212EXPORT_SYMBOL_GPL(s3c64xx_i2s_dai);
213
214static __devinit int s3c64xx_iis_dev_probe(struct platform_device *pdev) 146static __devinit int s3c64xx_iis_dev_probe(struct platform_device *pdev)
215{ 147{
216 struct s3c_i2sv2_info *i2s; 148 struct s3c_i2sv2_info *i2s;
217 struct snd_soc_dai *dai; 149 struct snd_soc_dai *dai;
218 int ret; 150 int ret;
219 151
220 if (pdev->id >= ARRAY_SIZE(s3c64xx_i2s)) { 152 if (pdev->id >= MAX_I2SV3) {
221 dev_err(&pdev->dev, "id %d out of range\n", pdev->id); 153 dev_err(&pdev->dev, "id %d out of range\n", pdev->id);
222 return -EINVAL; 154 return -EINVAL;
223 } 155 }
@@ -225,10 +157,40 @@ static __devinit int s3c64xx_iis_dev_probe(struct platform_device *pdev)
225 i2s = &s3c64xx_i2s[pdev->id]; 157 i2s = &s3c64xx_i2s[pdev->id];
226 dai = &s3c64xx_i2s_dai[pdev->id]; 158 dai = &s3c64xx_i2s_dai[pdev->id];
227 dai->dev = &pdev->dev; 159 dai->dev = &pdev->dev;
160 dai->name = "s3c64xx-i2s";
161 dai->id = pdev->id;
162 dai->symmetric_rates = 1;
163 dai->playback.channels_min = 2;
164 dai->playback.channels_max = 2;
165 dai->playback.rates = S3C64XX_I2S_RATES;
166 dai->playback.formats = S3C64XX_I2S_FMTS;
167 dai->capture.channels_min = 2;
168 dai->capture.channels_max = 2;
169 dai->capture.rates = S3C64XX_I2S_RATES;
170 dai->capture.formats = S3C64XX_I2S_FMTS;
171 dai->probe = s3c64xx_i2s_probe;
172 dai->ops = &s3c64xx_i2s_dai_ops;
228 173
229 i2s->dma_capture = &s3c64xx_i2s_pcm_stereo_in[pdev->id]; 174 i2s->dma_capture = &s3c64xx_i2s_pcm_stereo_in[pdev->id];
230 i2s->dma_playback = &s3c64xx_i2s_pcm_stereo_out[pdev->id]; 175 i2s->dma_playback = &s3c64xx_i2s_pcm_stereo_out[pdev->id];
231 176
177 if (pdev->id == 0) {
178 i2s->dma_capture->channel = DMACH_I2S0_IN;
179 i2s->dma_capture->dma_addr = S3C64XX_PA_IIS0 + S3C2412_IISRXD;
180 i2s->dma_playback->channel = DMACH_I2S0_OUT;
181 i2s->dma_playback->dma_addr = S3C64XX_PA_IIS0 + S3C2412_IISTXD;
182 } else {
183 i2s->dma_capture->channel = DMACH_I2S1_IN;
184 i2s->dma_capture->dma_addr = S3C64XX_PA_IIS1 + S3C2412_IISRXD;
185 i2s->dma_playback->channel = DMACH_I2S1_OUT;
186 i2s->dma_playback->dma_addr = S3C64XX_PA_IIS1 + S3C2412_IISTXD;
187 }
188
189 i2s->dma_capture->client = &s3c64xx_dma_client_in;
190 i2s->dma_capture->dma_size = 4;
191 i2s->dma_playback->client = &s3c64xx_dma_client_out;
192 i2s->dma_playback->dma_size = 4;
193
232 i2s->iis_cclk = clk_get(&pdev->dev, "audio-bus"); 194 i2s->iis_cclk = clk_get(&pdev->dev, "audio-bus");
233 if (IS_ERR(i2s->iis_cclk)) { 195 if (IS_ERR(i2s->iis_cclk)) {
234 dev_err(&pdev->dev, "failed to get audio-bus\n"); 196 dev_err(&pdev->dev, "failed to get audio-bus\n");
diff --git a/sound/soc/s3c24xx/smdk2443_wm9710.c b/sound/soc/s3c24xx/smdk2443_wm9710.c
index 12b783b12fcb..362258835e8d 100644
--- a/sound/soc/s3c24xx/smdk2443_wm9710.c
+++ b/sound/soc/s3c24xx/smdk2443_wm9710.c
@@ -21,7 +21,7 @@
21 21
22#include "../codecs/ac97.h" 22#include "../codecs/ac97.h"
23#include "s3c-dma.h" 23#include "s3c-dma.h"
24#include "s3c24xx-ac97.h" 24#include "s3c-ac97.h"
25 25
26static struct snd_soc_card smdk2443; 26static struct snd_soc_card smdk2443;
27 27
@@ -29,7 +29,7 @@ static struct snd_soc_dai_link smdk2443_dai[] = {
29{ 29{
30 .name = "AC97", 30 .name = "AC97",
31 .stream_name = "AC97 HiFi", 31 .stream_name = "AC97 HiFi",
32 .cpu_dai = &s3c2443_ac97_dai[0], 32 .cpu_dai = &s3c_ac97_dai[S3C_AC97_DAI_PCM],
33 .codec_dai = &ac97_dai, 33 .codec_dai = &ac97_dai,
34}, 34},
35}; 35};
diff --git a/sound/soc/s3c24xx/smdk_wm9713.c b/sound/soc/s3c24xx/smdk_wm9713.c
new file mode 100644
index 000000000000..24fd39f38ccb
--- /dev/null
+++ b/sound/soc/s3c24xx/smdk_wm9713.c
@@ -0,0 +1,94 @@
1/*
2 * smdk_wm9713.c -- SoC audio for SMDK
3 *
4 * Copyright 2010 Samsung Electronics Co. Ltd.
5 * Author: Jaswinder Singh Brar <jassi.brar@samsung.com>
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 as
9 * published by the Free Software Foundation; either version 2 of the
10 * License, or (at your option) any later version.
11 *
12 */
13
14#include <linux/module.h>
15#include <linux/device.h>
16#include <sound/soc.h>
17
18#include "../codecs/wm9713.h"
19#include "s3c-dma.h"
20#include "s3c-ac97.h"
21
22static struct snd_soc_card smdk;
23
24/*
25 * Default CFG switch settings to use this driver:
26 *
27 * SMDK6410: Set CFG1 1-3 On, CFG2 1-4 Off
28 */
29
30/*
31 Playback (HeadPhone):-
32 $ amixer sset 'Headphone' unmute
33 $ amixer sset 'Right Headphone Out Mux' 'Headphone'
34 $ amixer sset 'Left Headphone Out Mux' 'Headphone'
35 $ amixer sset 'Right HP Mixer PCM' unmute
36 $ amixer sset 'Left HP Mixer PCM' unmute
37
38 Capture (LineIn):-
39 $ amixer sset 'Right Capture Source' 'Line'
40 $ amixer sset 'Left Capture Source' 'Line'
41*/
42
43static struct snd_soc_dai_link smdk_dai = {
44 .name = "AC97",
45 .stream_name = "AC97 PCM",
46 .cpu_dai = &s3c_ac97_dai[S3C_AC97_DAI_PCM],
47 .codec_dai = &wm9713_dai[WM9713_DAI_AC97_HIFI],
48};
49
50static struct snd_soc_card smdk = {
51 .name = "SMDK",
52 .platform = &s3c24xx_soc_platform,
53 .dai_link = &smdk_dai,
54 .num_links = 1,
55};
56
57static struct snd_soc_device smdk_snd_ac97_devdata = {
58 .card = &smdk,
59 .codec_dev = &soc_codec_dev_wm9713,
60};
61
62static struct platform_device *smdk_snd_ac97_device;
63
64static int __init smdk_init(void)
65{
66 int ret;
67
68 smdk_snd_ac97_device = platform_device_alloc("soc-audio", -1);
69 if (!smdk_snd_ac97_device)
70 return -ENOMEM;
71
72 platform_set_drvdata(smdk_snd_ac97_device,
73 &smdk_snd_ac97_devdata);
74 smdk_snd_ac97_devdata.dev = &smdk_snd_ac97_device->dev;
75
76 ret = platform_device_add(smdk_snd_ac97_device);
77 if (ret)
78 platform_device_put(smdk_snd_ac97_device);
79
80 return ret;
81}
82
83static void __exit smdk_exit(void)
84{
85 platform_device_unregister(smdk_snd_ac97_device);
86}
87
88module_init(smdk_init);
89module_exit(smdk_exit);
90
91/* Module information */
92MODULE_AUTHOR("Jaswinder Singh Brar, jassi.brar@samsung.com");
93MODULE_DESCRIPTION("ALSA SoC SMDK+WM9713");
94MODULE_LICENSE("GPL");
diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig
index 9e6976586554..106674979b53 100644
--- a/sound/soc/sh/Kconfig
+++ b/sound/soc/sh/Kconfig
@@ -26,6 +26,13 @@ config SND_SOC_SH4_FSI
26 help 26 help
27 This option enables FSI sound support 27 This option enables FSI sound support
28 28
29config SND_SOC_SH4_SIU
30 tristate
31 depends on (SUPERH || ARCH_SHMOBILE) && HAVE_CLK
32 select DMA_ENGINE
33 select DMADEVICES
34 select SH_DMAE
35
29## 36##
30## Boards 37## Boards
31## 38##
@@ -47,4 +54,20 @@ config SND_FSI_AK4642
47 This option enables generic sound support for the 54 This option enables generic sound support for the
48 FSI - AK4642 unit 55 FSI - AK4642 unit
49 56
57config SND_FSI_DA7210
58 bool "FSI-DA7210 sound support"
59 depends on SND_SOC_SH4_FSI
60 select SND_SOC_DA7210
61 help
62 This option enables generic sound support for the
63 FSI - DA7210 unit
64
65config SND_SIU_MIGOR
66 tristate "SIU sound support on Migo-R"
67 depends on SH_MIGOR
68 select SND_SOC_SH4_SIU
69 select SND_SOC_WM8978
70 help
71 This option enables sound support for the SH7722 Migo-R board
72
50endmenu 73endmenu
diff --git a/sound/soc/sh/Makefile b/sound/soc/sh/Makefile
index a6997872f24e..8a5a19293bda 100644
--- a/sound/soc/sh/Makefile
+++ b/sound/soc/sh/Makefile
@@ -6,13 +6,19 @@ obj-$(CONFIG_SND_SOC_PCM_SH7760) += snd-soc-dma-sh7760.o
6snd-soc-hac-objs := hac.o 6snd-soc-hac-objs := hac.o
7snd-soc-ssi-objs := ssi.o 7snd-soc-ssi-objs := ssi.o
8snd-soc-fsi-objs := fsi.o 8snd-soc-fsi-objs := fsi.o
9snd-soc-siu-objs := siu_pcm.o siu_dai.o
9obj-$(CONFIG_SND_SOC_SH4_HAC) += snd-soc-hac.o 10obj-$(CONFIG_SND_SOC_SH4_HAC) += snd-soc-hac.o
10obj-$(CONFIG_SND_SOC_SH4_SSI) += snd-soc-ssi.o 11obj-$(CONFIG_SND_SOC_SH4_SSI) += snd-soc-ssi.o
11obj-$(CONFIG_SND_SOC_SH4_FSI) += snd-soc-fsi.o 12obj-$(CONFIG_SND_SOC_SH4_FSI) += snd-soc-fsi.o
13obj-$(CONFIG_SND_SOC_SH4_SIU) += snd-soc-siu.o
12 14
13## boards 15## boards
14snd-soc-sh7760-ac97-objs := sh7760-ac97.o 16snd-soc-sh7760-ac97-objs := sh7760-ac97.o
15snd-soc-fsi-ak4642-objs := fsi-ak4642.o 17snd-soc-fsi-ak4642-objs := fsi-ak4642.o
18snd-soc-fsi-da7210-objs := fsi-da7210.o
19snd-soc-migor-objs := migor.o
16 20
17obj-$(CONFIG_SND_SH7760_AC97) += snd-soc-sh7760-ac97.o 21obj-$(CONFIG_SND_SH7760_AC97) += snd-soc-sh7760-ac97.o
18obj-$(CONFIG_SND_FSI_AK4642) += snd-soc-fsi-ak4642.o 22obj-$(CONFIG_SND_FSI_AK4642) += snd-soc-fsi-ak4642.o
23obj-$(CONFIG_SND_FSI_DA7210) += snd-soc-fsi-da7210.o
24obj-$(CONFIG_SND_SIU_MIGOR) += snd-soc-migor.o
diff --git a/sound/soc/sh/fsi-da7210.c b/sound/soc/sh/fsi-da7210.c
new file mode 100644
index 000000000000..33b4d177f466
--- /dev/null
+++ b/sound/soc/sh/fsi-da7210.c
@@ -0,0 +1,83 @@
1/*
2 * fsi-da7210.c
3 *
4 * Copyright (C) 2009 Renesas Solutions Corp.
5 * Kuninori Morimoto <morimoto.kuninori@renesas.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/interrupt.h>
14#include <linux/platform_device.h>
15#include <linux/io.h>
16#include <linux/i2c.h>
17#include <sound/core.h>
18#include <sound/pcm.h>
19#include <sound/pcm_params.h>
20#include <sound/soc.h>
21#include <sound/soc-dapm.h>
22
23#include <sound/sh_fsi.h>
24#include "../codecs/da7210.h"
25
26static int fsi_da7210_init(struct snd_soc_codec *codec)
27{
28 return snd_soc_dai_set_fmt(&da7210_dai,
29 SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
30 SND_SOC_DAIFMT_CBM_CFM);
31}
32
33static struct snd_soc_dai_link fsi_da7210_dai = {
34 .name = "DA7210",
35 .stream_name = "DA7210",
36 .cpu_dai = &fsi_soc_dai[1], /* FSI B */
37 .codec_dai = &da7210_dai,
38 .init = fsi_da7210_init,
39};
40
41static struct snd_soc_card fsi_soc_card = {
42 .name = "FSI",
43 .platform = &fsi_soc_platform,
44 .dai_link = &fsi_da7210_dai,
45 .num_links = 1,
46};
47
48static struct snd_soc_device fsi_da7210_snd_devdata = {
49 .card = &fsi_soc_card,
50 .codec_dev = &soc_codec_dev_da7210,
51};
52
53static struct platform_device *fsi_da7210_snd_device;
54
55static int __init fsi_da7210_sound_init(void)
56{
57 int ret;
58
59 fsi_da7210_snd_device = platform_device_alloc("soc-audio", -1);
60 if (!fsi_da7210_snd_device)
61 return -ENOMEM;
62
63 platform_set_drvdata(fsi_da7210_snd_device, &fsi_da7210_snd_devdata);
64 fsi_da7210_snd_devdata.dev = &fsi_da7210_snd_device->dev;
65 ret = platform_device_add(fsi_da7210_snd_device);
66 if (ret)
67 platform_device_put(fsi_da7210_snd_device);
68
69 return ret;
70}
71
72static void __exit fsi_da7210_sound_exit(void)
73{
74 platform_device_unregister(fsi_da7210_snd_device);
75}
76
77module_init(fsi_da7210_sound_init);
78module_exit(fsi_da7210_sound_exit);
79
80/* Module information */
81MODULE_DESCRIPTION("ALSA SoC FSI DA2710");
82MODULE_AUTHOR("Kuninori Morimoto <morimoto.kuninori@renesas.com>");
83MODULE_LICENSE("GPL");
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 42813b808389..993abb730dfa 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -67,6 +67,7 @@
67/* DOFF_ST */ 67/* DOFF_ST */
68#define ERR_OVER 0x00000010 68#define ERR_OVER 0x00000010
69#define ERR_UNDER 0x00000001 69#define ERR_UNDER 0x00000001
70#define ST_ERR (ERR_OVER | ERR_UNDER)
70 71
71/* CLK_RST */ 72/* CLK_RST */
72#define B_CLK 0x00000010 73#define B_CLK 0x00000010
@@ -92,6 +93,7 @@
92struct fsi_priv { 93struct fsi_priv {
93 void __iomem *base; 94 void __iomem *base;
94 struct snd_pcm_substream *substream; 95 struct snd_pcm_substream *substream;
96 struct fsi_master *master;
95 97
96 int fifo_max; 98 int fifo_max;
97 int chan; 99 int chan;
@@ -108,10 +110,9 @@ struct fsi_master {
108 struct fsi_priv fsia; 110 struct fsi_priv fsia;
109 struct fsi_priv fsib; 111 struct fsi_priv fsib;
110 struct sh_fsi_platform_info *info; 112 struct sh_fsi_platform_info *info;
113 spinlock_t lock;
111}; 114};
112 115
113static struct fsi_master *master;
114
115/************************************************************************ 116/************************************************************************
116 117
117 118
@@ -119,35 +120,35 @@ static struct fsi_master *master;
119 120
120 121
121************************************************************************/ 122************************************************************************/
122static int __fsi_reg_write(u32 reg, u32 data) 123static void __fsi_reg_write(u32 reg, u32 data)
123{ 124{
124 /* valid data area is 24bit */ 125 /* valid data area is 24bit */
125 data &= 0x00ffffff; 126 data &= 0x00ffffff;
126 127
127 return ctrl_outl(data, reg); 128 __raw_writel(data, reg);
128} 129}
129 130
130static u32 __fsi_reg_read(u32 reg) 131static u32 __fsi_reg_read(u32 reg)
131{ 132{
132 return ctrl_inl(reg); 133 return __raw_readl(reg);
133} 134}
134 135
135static int __fsi_reg_mask_set(u32 reg, u32 mask, u32 data) 136static void __fsi_reg_mask_set(u32 reg, u32 mask, u32 data)
136{ 137{
137 u32 val = __fsi_reg_read(reg); 138 u32 val = __fsi_reg_read(reg);
138 139
139 val &= ~mask; 140 val &= ~mask;
140 val |= data & mask; 141 val |= data & mask;
141 142
142 return __fsi_reg_write(reg, val); 143 __fsi_reg_write(reg, val);
143} 144}
144 145
145static int fsi_reg_write(struct fsi_priv *fsi, u32 reg, u32 data) 146static void fsi_reg_write(struct fsi_priv *fsi, u32 reg, u32 data)
146{ 147{
147 if (reg > REG_END) 148 if (reg > REG_END)
148 return -1; 149 return;
149 150
150 return __fsi_reg_write((u32)(fsi->base + reg), data); 151 __fsi_reg_write((u32)(fsi->base + reg), data);
151} 152}
152 153
153static u32 fsi_reg_read(struct fsi_priv *fsi, u32 reg) 154static u32 fsi_reg_read(struct fsi_priv *fsi, u32 reg)
@@ -158,39 +159,55 @@ static u32 fsi_reg_read(struct fsi_priv *fsi, u32 reg)
158 return __fsi_reg_read((u32)(fsi->base + reg)); 159 return __fsi_reg_read((u32)(fsi->base + reg));
159} 160}
160 161
161static int fsi_reg_mask_set(struct fsi_priv *fsi, u32 reg, u32 mask, u32 data) 162static void fsi_reg_mask_set(struct fsi_priv *fsi, u32 reg, u32 mask, u32 data)
162{ 163{
163 if (reg > REG_END) 164 if (reg > REG_END)
164 return -1; 165 return;
165 166
166 return __fsi_reg_mask_set((u32)(fsi->base + reg), mask, data); 167 __fsi_reg_mask_set((u32)(fsi->base + reg), mask, data);
167} 168}
168 169
169static int fsi_master_write(u32 reg, u32 data) 170static void fsi_master_write(struct fsi_master *master, u32 reg, u32 data)
170{ 171{
172 unsigned long flags;
173
171 if ((reg < MREG_START) || 174 if ((reg < MREG_START) ||
172 (reg > MREG_END)) 175 (reg > MREG_END))
173 return -1; 176 return;
174 177
175 return __fsi_reg_write((u32)(master->base + reg), data); 178 spin_lock_irqsave(&master->lock, flags);
179 __fsi_reg_write((u32)(master->base + reg), data);
180 spin_unlock_irqrestore(&master->lock, flags);
176} 181}
177 182
178static u32 fsi_master_read(u32 reg) 183static u32 fsi_master_read(struct fsi_master *master, u32 reg)
179{ 184{
185 u32 ret;
186 unsigned long flags;
187
180 if ((reg < MREG_START) || 188 if ((reg < MREG_START) ||
181 (reg > MREG_END)) 189 (reg > MREG_END))
182 return 0; 190 return 0;
183 191
184 return __fsi_reg_read((u32)(master->base + reg)); 192 spin_lock_irqsave(&master->lock, flags);
193 ret = __fsi_reg_read((u32)(master->base + reg));
194 spin_unlock_irqrestore(&master->lock, flags);
195
196 return ret;
185} 197}
186 198
187static int fsi_master_mask_set(u32 reg, u32 mask, u32 data) 199static void fsi_master_mask_set(struct fsi_master *master,
200 u32 reg, u32 mask, u32 data)
188{ 201{
202 unsigned long flags;
203
189 if ((reg < MREG_START) || 204 if ((reg < MREG_START) ||
190 (reg > MREG_END)) 205 (reg > MREG_END))
191 return -1; 206 return;
192 207
193 return __fsi_reg_mask_set((u32)(master->base + reg), mask, data); 208 spin_lock_irqsave(&master->lock, flags);
209 __fsi_reg_mask_set((u32)(master->base + reg), mask, data);
210 spin_unlock_irqrestore(&master->lock, flags);
194} 211}
195 212
196/************************************************************************ 213/************************************************************************
@@ -200,43 +217,35 @@ static int fsi_master_mask_set(u32 reg, u32 mask, u32 data)
200 217
201 218
202************************************************************************/ 219************************************************************************/
203static struct fsi_priv *fsi_get(struct snd_pcm_substream *substream) 220static struct fsi_master *fsi_get_master(struct fsi_priv *fsi)
204{ 221{
205 struct snd_soc_pcm_runtime *rtd; 222 return fsi->master;
206 struct fsi_priv *fsi = NULL; 223}
207 224
208 if (!substream || !master) 225static int fsi_is_port_a(struct fsi_priv *fsi)
209 return NULL; 226{
227 return fsi->master->base == fsi->base;
228}
210 229
211 rtd = substream->private_data; 230static struct snd_soc_dai *fsi_get_dai(struct snd_pcm_substream *substream)
212 switch (rtd->dai->cpu_dai->id) { 231{
213 case 0: 232 struct snd_soc_pcm_runtime *rtd = substream->private_data;
214 fsi = &master->fsia; 233 struct snd_soc_dai_link *machine = rtd->dai;
215 break;
216 case 1:
217 fsi = &master->fsib;
218 break;
219 }
220 234
221 return fsi; 235 return machine->cpu_dai;
222} 236}
223 237
224static int fsi_is_port_a(struct fsi_priv *fsi) 238static struct fsi_priv *fsi_get_priv(struct snd_pcm_substream *substream)
225{ 239{
226 /* return 240 struct snd_soc_dai *dai = fsi_get_dai(substream);
227 * 1 : port a
228 * 0 : port b
229 */
230 241
231 if (fsi == &master->fsia) 242 return dai->private_data;
232 return 1;
233
234 return 0;
235} 243}
236 244
237static u32 fsi_get_info_flags(struct fsi_priv *fsi) 245static u32 fsi_get_info_flags(struct fsi_priv *fsi)
238{ 246{
239 int is_porta = fsi_is_port_a(fsi); 247 int is_porta = fsi_is_port_a(fsi);
248 struct fsi_master *master = fsi_get_master(fsi);
240 249
241 return is_porta ? master->info->porta_flags : 250 return is_porta ? master->info->porta_flags :
242 master->info->portb_flags; 251 master->info->portb_flags;
@@ -314,27 +323,30 @@ static int fsi_get_fifo_residue(struct fsi_priv *fsi, int is_play)
314static void fsi_irq_enable(struct fsi_priv *fsi, int is_play) 323static void fsi_irq_enable(struct fsi_priv *fsi, int is_play)
315{ 324{
316 u32 data = fsi_port_ab_io_bit(fsi, is_play); 325 u32 data = fsi_port_ab_io_bit(fsi, is_play);
326 struct fsi_master *master = fsi_get_master(fsi);
317 327
318 fsi_master_mask_set(IMSK, data, data); 328 fsi_master_mask_set(master, IMSK, data, data);
319 fsi_master_mask_set(IEMSK, data, data); 329 fsi_master_mask_set(master, IEMSK, data, data);
320} 330}
321 331
322static void fsi_irq_disable(struct fsi_priv *fsi, int is_play) 332static void fsi_irq_disable(struct fsi_priv *fsi, int is_play)
323{ 333{
324 u32 data = fsi_port_ab_io_bit(fsi, is_play); 334 u32 data = fsi_port_ab_io_bit(fsi, is_play);
335 struct fsi_master *master = fsi_get_master(fsi);
325 336
326 fsi_master_mask_set(IMSK, data, 0); 337 fsi_master_mask_set(master, IMSK, data, 0);
327 fsi_master_mask_set(IEMSK, data, 0); 338 fsi_master_mask_set(master, IEMSK, data, 0);
328} 339}
329 340
330static void fsi_clk_ctrl(struct fsi_priv *fsi, int enable) 341static void fsi_clk_ctrl(struct fsi_priv *fsi, int enable)
331{ 342{
332 u32 val = fsi_is_port_a(fsi) ? (1 << 0) : (1 << 4); 343 u32 val = fsi_is_port_a(fsi) ? (1 << 0) : (1 << 4);
344 struct fsi_master *master = fsi_get_master(fsi);
333 345
334 if (enable) 346 if (enable)
335 fsi_master_mask_set(CLK_RST, val, val); 347 fsi_master_mask_set(master, CLK_RST, val, val);
336 else 348 else
337 fsi_master_mask_set(CLK_RST, val, 0); 349 fsi_master_mask_set(master, CLK_RST, val, 0);
338} 350}
339 351
340static void fsi_irq_init(struct fsi_priv *fsi, int is_play) 352static void fsi_irq_init(struct fsi_priv *fsi, int is_play)
@@ -355,43 +367,46 @@ static void fsi_irq_init(struct fsi_priv *fsi, int is_play)
355 fsi_reg_mask_set(fsi, ctrl, FIFO_CLR, FIFO_CLR); 367 fsi_reg_mask_set(fsi, ctrl, FIFO_CLR, FIFO_CLR);
356 368
357 /* clear interrupt factor */ 369 /* clear interrupt factor */
358 fsi_master_mask_set(INT_ST, data, 0); 370 fsi_master_mask_set(fsi_get_master(fsi), INT_ST, data, 0);
359} 371}
360 372
361static void fsi_soft_all_reset(void) 373static void fsi_soft_all_reset(struct fsi_master *master)
362{ 374{
363 u32 status = fsi_master_read(SOFT_RST); 375 u32 status = fsi_master_read(master, SOFT_RST);
364 376
365 /* port AB reset */ 377 /* port AB reset */
366 status &= 0x000000ff; 378 status &= 0x000000ff;
367 fsi_master_write(SOFT_RST, status); 379 fsi_master_write(master, SOFT_RST, status);
368 mdelay(10); 380 mdelay(10);
369 381
370 /* soft reset */ 382 /* soft reset */
371 status &= 0x000000f0; 383 status &= 0x000000f0;
372 fsi_master_write(SOFT_RST, status); 384 fsi_master_write(master, SOFT_RST, status);
373 status |= 0x00000001; 385 status |= 0x00000001;
374 fsi_master_write(SOFT_RST, status); 386 fsi_master_write(master, SOFT_RST, status);
375 mdelay(10); 387 mdelay(10);
376} 388}
377 389
378/* playback interrupt */ 390/* playback interrupt */
379static int fsi_data_push(struct fsi_priv *fsi) 391static int fsi_data_push(struct fsi_priv *fsi, int startup)
380{ 392{
381 struct snd_pcm_runtime *runtime; 393 struct snd_pcm_runtime *runtime;
382 struct snd_pcm_substream *substream = NULL; 394 struct snd_pcm_substream *substream = NULL;
395 u32 status;
383 int send; 396 int send;
384 int fifo_free; 397 int fifo_free;
385 int width; 398 int width;
386 u8 *start; 399 u8 *start;
387 int i; 400 int i, over_period;
388 401
389 if (!fsi || 402 if (!fsi ||
390 !fsi->substream || 403 !fsi->substream ||
391 !fsi->substream->runtime) 404 !fsi->substream->runtime)
392 return -EINVAL; 405 return -EINVAL;
393 406
394 runtime = fsi->substream->runtime; 407 over_period = 0;
408 substream = fsi->substream;
409 runtime = substream->runtime;
395 410
396 /* FSI FIFO has limit. 411 /* FSI FIFO has limit.
397 * So, this driver can not send periods data at a time 412 * So, this driver can not send periods data at a time
@@ -399,7 +414,7 @@ static int fsi_data_push(struct fsi_priv *fsi)
399 if (fsi->byte_offset >= 414 if (fsi->byte_offset >=
400 fsi->period_len * (fsi->periods + 1)) { 415 fsi->period_len * (fsi->periods + 1)) {
401 416
402 substream = fsi->substream; 417 over_period = 1;
403 fsi->periods = (fsi->periods + 1) % runtime->periods; 418 fsi->periods = (fsi->periods + 1) % runtime->periods;
404 419
405 if (0 == fsi->periods) 420 if (0 == fsi->periods)
@@ -438,30 +453,44 @@ static int fsi_data_push(struct fsi_priv *fsi)
438 453
439 fsi->byte_offset += send * width; 454 fsi->byte_offset += send * width;
440 455
456 status = fsi_reg_read(fsi, DOFF_ST);
457 if (!startup) {
458 struct snd_soc_dai *dai = fsi_get_dai(substream);
459
460 if (status & ERR_OVER)
461 dev_err(dai->dev, "over run\n");
462 if (status & ERR_UNDER)
463 dev_err(dai->dev, "under run\n");
464 }
465 fsi_reg_write(fsi, DOFF_ST, 0);
466
441 fsi_irq_enable(fsi, 1); 467 fsi_irq_enable(fsi, 1);
442 468
443 if (substream) 469 if (over_period)
444 snd_pcm_period_elapsed(substream); 470 snd_pcm_period_elapsed(substream);
445 471
446 return 0; 472 return 0;
447} 473}
448 474
449static int fsi_data_pop(struct fsi_priv *fsi) 475static int fsi_data_pop(struct fsi_priv *fsi, int startup)
450{ 476{
451 struct snd_pcm_runtime *runtime; 477 struct snd_pcm_runtime *runtime;
452 struct snd_pcm_substream *substream = NULL; 478 struct snd_pcm_substream *substream = NULL;
479 u32 status;
453 int free; 480 int free;
454 int fifo_fill; 481 int fifo_fill;
455 int width; 482 int width;
456 u8 *start; 483 u8 *start;
457 int i; 484 int i, over_period;
458 485
459 if (!fsi || 486 if (!fsi ||
460 !fsi->substream || 487 !fsi->substream ||
461 !fsi->substream->runtime) 488 !fsi->substream->runtime)
462 return -EINVAL; 489 return -EINVAL;
463 490
464 runtime = fsi->substream->runtime; 491 over_period = 0;
492 substream = fsi->substream;
493 runtime = substream->runtime;
465 494
466 /* FSI FIFO has limit. 495 /* FSI FIFO has limit.
467 * So, this driver can not send periods data at a time 496 * So, this driver can not send periods data at a time
@@ -469,7 +498,7 @@ static int fsi_data_pop(struct fsi_priv *fsi)
469 if (fsi->byte_offset >= 498 if (fsi->byte_offset >=
470 fsi->period_len * (fsi->periods + 1)) { 499 fsi->period_len * (fsi->periods + 1)) {
471 500
472 substream = fsi->substream; 501 over_period = 1;
473 fsi->periods = (fsi->periods + 1) % runtime->periods; 502 fsi->periods = (fsi->periods + 1) % runtime->periods;
474 503
475 if (0 == fsi->periods) 504 if (0 == fsi->periods)
@@ -507,9 +536,20 @@ static int fsi_data_pop(struct fsi_priv *fsi)
507 536
508 fsi->byte_offset += fifo_fill * width; 537 fsi->byte_offset += fifo_fill * width;
509 538
539 status = fsi_reg_read(fsi, DIFF_ST);
540 if (!startup) {
541 struct snd_soc_dai *dai = fsi_get_dai(substream);
542
543 if (status & ERR_OVER)
544 dev_err(dai->dev, "over run\n");
545 if (status & ERR_UNDER)
546 dev_err(dai->dev, "under run\n");
547 }
548 fsi_reg_write(fsi, DIFF_ST, 0);
549
510 fsi_irq_enable(fsi, 0); 550 fsi_irq_enable(fsi, 0);
511 551
512 if (substream) 552 if (over_period)
513 snd_pcm_period_elapsed(substream); 553 snd_pcm_period_elapsed(substream);
514 554
515 return 0; 555 return 0;
@@ -517,23 +557,24 @@ static int fsi_data_pop(struct fsi_priv *fsi)
517 557
518static irqreturn_t fsi_interrupt(int irq, void *data) 558static irqreturn_t fsi_interrupt(int irq, void *data)
519{ 559{
520 u32 status = fsi_master_read(SOFT_RST) & ~0x00000010; 560 struct fsi_master *master = data;
521 u32 int_st = fsi_master_read(INT_ST); 561 u32 status = fsi_master_read(master, SOFT_RST) & ~0x00000010;
562 u32 int_st = fsi_master_read(master, INT_ST);
522 563
523 /* clear irq status */ 564 /* clear irq status */
524 fsi_master_write(SOFT_RST, status); 565 fsi_master_write(master, SOFT_RST, status);
525 fsi_master_write(SOFT_RST, status | 0x00000010); 566 fsi_master_write(master, SOFT_RST, status | 0x00000010);
526 567
527 if (int_st & INT_A_OUT) 568 if (int_st & INT_A_OUT)
528 fsi_data_push(&master->fsia); 569 fsi_data_push(&master->fsia, 0);
529 if (int_st & INT_B_OUT) 570 if (int_st & INT_B_OUT)
530 fsi_data_push(&master->fsib); 571 fsi_data_push(&master->fsib, 0);
531 if (int_st & INT_A_IN) 572 if (int_st & INT_A_IN)
532 fsi_data_pop(&master->fsia); 573 fsi_data_pop(&master->fsia, 0);
533 if (int_st & INT_B_IN) 574 if (int_st & INT_B_IN)
534 fsi_data_pop(&master->fsib); 575 fsi_data_pop(&master->fsib, 0);
535 576
536 fsi_master_write(INT_ST, 0x0000000); 577 fsi_master_write(master, INT_ST, 0x0000000);
537 578
538 return IRQ_HANDLED; 579 return IRQ_HANDLED;
539} 580}
@@ -548,7 +589,7 @@ static irqreturn_t fsi_interrupt(int irq, void *data)
548static int fsi_dai_startup(struct snd_pcm_substream *substream, 589static int fsi_dai_startup(struct snd_pcm_substream *substream,
549 struct snd_soc_dai *dai) 590 struct snd_soc_dai *dai)
550{ 591{
551 struct fsi_priv *fsi = fsi_get(substream); 592 struct fsi_priv *fsi = fsi_get_priv(substream);
552 const char *msg; 593 const char *msg;
553 u32 flags = fsi_get_info_flags(fsi); 594 u32 flags = fsi_get_info_flags(fsi);
554 u32 fmt; 595 u32 fmt;
@@ -667,7 +708,7 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
667static void fsi_dai_shutdown(struct snd_pcm_substream *substream, 708static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
668 struct snd_soc_dai *dai) 709 struct snd_soc_dai *dai)
669{ 710{
670 struct fsi_priv *fsi = fsi_get(substream); 711 struct fsi_priv *fsi = fsi_get_priv(substream);
671 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 712 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
672 713
673 fsi_irq_disable(fsi, is_play); 714 fsi_irq_disable(fsi, is_play);
@@ -679,7 +720,7 @@ static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
679static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd, 720static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
680 struct snd_soc_dai *dai) 721 struct snd_soc_dai *dai)
681{ 722{
682 struct fsi_priv *fsi = fsi_get(substream); 723 struct fsi_priv *fsi = fsi_get_priv(substream);
683 struct snd_pcm_runtime *runtime = substream->runtime; 724 struct snd_pcm_runtime *runtime = substream->runtime;
684 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 725 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
685 int ret = 0; 726 int ret = 0;
@@ -689,7 +730,7 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
689 fsi_stream_push(fsi, substream, 730 fsi_stream_push(fsi, substream,
690 frames_to_bytes(runtime, runtime->buffer_size), 731 frames_to_bytes(runtime, runtime->buffer_size),
691 frames_to_bytes(runtime, runtime->period_size)); 732 frames_to_bytes(runtime, runtime->period_size));
692 ret = is_play ? fsi_data_push(fsi) : fsi_data_pop(fsi); 733 ret = is_play ? fsi_data_push(fsi, 1) : fsi_data_pop(fsi, 1);
693 break; 734 break;
694 case SNDRV_PCM_TRIGGER_STOP: 735 case SNDRV_PCM_TRIGGER_STOP:
695 fsi_irq_disable(fsi, is_play); 736 fsi_irq_disable(fsi, is_play);
@@ -760,7 +801,7 @@ static int fsi_hw_free(struct snd_pcm_substream *substream)
760static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream) 801static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream)
761{ 802{
762 struct snd_pcm_runtime *runtime = substream->runtime; 803 struct snd_pcm_runtime *runtime = substream->runtime;
763 struct fsi_priv *fsi = fsi_get(substream); 804 struct fsi_priv *fsi = fsi_get_priv(substream);
764 long location; 805 long location;
765 806
766 location = (fsi->byte_offset - 1); 807 location = (fsi->byte_offset - 1);
@@ -870,10 +911,16 @@ EXPORT_SYMBOL_GPL(fsi_soc_platform);
870************************************************************************/ 911************************************************************************/
871static int fsi_probe(struct platform_device *pdev) 912static int fsi_probe(struct platform_device *pdev)
872{ 913{
914 struct fsi_master *master;
873 struct resource *res; 915 struct resource *res;
874 unsigned int irq; 916 unsigned int irq;
875 int ret; 917 int ret;
876 918
919 if (0 != pdev->id) {
920 dev_err(&pdev->dev, "current fsi support id 0 only now\n");
921 return -ENODEV;
922 }
923
877 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 924 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
878 irq = platform_get_irq(pdev, 0); 925 irq = platform_get_irq(pdev, 0);
879 if (!res || (int)irq <= 0) { 926 if (!res || (int)irq <= 0) {
@@ -899,15 +946,20 @@ static int fsi_probe(struct platform_device *pdev)
899 master->irq = irq; 946 master->irq = irq;
900 master->info = pdev->dev.platform_data; 947 master->info = pdev->dev.platform_data;
901 master->fsia.base = master->base; 948 master->fsia.base = master->base;
949 master->fsia.master = master;
902 master->fsib.base = master->base + 0x40; 950 master->fsib.base = master->base + 0x40;
951 master->fsib.master = master;
952 spin_lock_init(&master->lock);
903 953
904 pm_runtime_enable(&pdev->dev); 954 pm_runtime_enable(&pdev->dev);
905 pm_runtime_resume(&pdev->dev); 955 pm_runtime_resume(&pdev->dev);
906 956
907 fsi_soc_dai[0].dev = &pdev->dev; 957 fsi_soc_dai[0].dev = &pdev->dev;
958 fsi_soc_dai[0].private_data = &master->fsia;
908 fsi_soc_dai[1].dev = &pdev->dev; 959 fsi_soc_dai[1].dev = &pdev->dev;
960 fsi_soc_dai[1].private_data = &master->fsib;
909 961
910 fsi_soft_all_reset(); 962 fsi_soft_all_reset(master);
911 963
912 ret = request_irq(irq, &fsi_interrupt, IRQF_DISABLED, "fsi", master); 964 ret = request_irq(irq, &fsi_interrupt, IRQF_DISABLED, "fsi", master);
913 if (ret) { 965 if (ret) {
@@ -937,6 +989,10 @@ exit:
937 989
938static int fsi_remove(struct platform_device *pdev) 990static int fsi_remove(struct platform_device *pdev)
939{ 991{
992 struct fsi_master *master;
993
994 master = fsi_get_master(fsi_soc_dai[0].private_data);
995
940 snd_soc_unregister_dais(fsi_soc_dai, ARRAY_SIZE(fsi_soc_dai)); 996 snd_soc_unregister_dais(fsi_soc_dai, ARRAY_SIZE(fsi_soc_dai));
941 snd_soc_unregister_platform(&fsi_soc_platform); 997 snd_soc_unregister_platform(&fsi_soc_platform);
942 998
@@ -946,7 +1002,12 @@ static int fsi_remove(struct platform_device *pdev)
946 1002
947 iounmap(master->base); 1003 iounmap(master->base);
948 kfree(master); 1004 kfree(master);
949 master = NULL; 1005
1006 fsi_soc_dai[0].dev = NULL;
1007 fsi_soc_dai[0].private_data = NULL;
1008 fsi_soc_dai[1].dev = NULL;
1009 fsi_soc_dai[1].private_data = NULL;
1010
950 return 0; 1011 return 0;
951} 1012}
952 1013
diff --git a/sound/soc/sh/migor.c b/sound/soc/sh/migor.c
new file mode 100644
index 000000000000..b823a5c9b9bc
--- /dev/null
+++ b/sound/soc/sh/migor.c
@@ -0,0 +1,218 @@
1/*
2 * ALSA SoC driver for Migo-R
3 *
4 * Copyright (C) 2009-2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
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/device.h>
12#include <linux/firmware.h>
13#include <linux/module.h>
14
15#include <asm/clock.h>
16
17#include <cpu/sh7722.h>
18
19#include <sound/core.h>
20#include <sound/pcm.h>
21#include <sound/soc.h>
22#include <sound/soc-dapm.h>
23
24#include "../codecs/wm8978.h"
25#include "siu.h"
26
27/* Default 8000Hz sampling frequency */
28static unsigned long codec_freq = 8000 * 512;
29
30static unsigned int use_count;
31
32/* External clock, sourced from the codec at the SIUMCKB pin */
33static unsigned long siumckb_recalc(struct clk *clk)
34{
35 return codec_freq;
36}
37
38static struct clk_ops siumckb_clk_ops = {
39 .recalc = siumckb_recalc,
40};
41
42static struct clk siumckb_clk = {
43 .name = "siumckb_clk",
44 .id = -1,
45 .ops = &siumckb_clk_ops,
46 .rate = 0, /* initialised at run-time */
47};
48
49static int migor_hw_params(struct snd_pcm_substream *substream,
50 struct snd_pcm_hw_params *params)
51{
52 struct snd_soc_pcm_runtime *rtd = substream->private_data;
53 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
54 int ret;
55 unsigned int rate = params_rate(params);
56
57 ret = snd_soc_dai_set_sysclk(codec_dai, WM8978_PLL, 13000000,
58 SND_SOC_CLOCK_IN);
59 if (ret < 0)
60 return ret;
61
62 ret = snd_soc_dai_set_clkdiv(codec_dai, WM8978_OPCLKRATE, rate * 512);
63 if (ret < 0)
64 return ret;
65
66 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_NB_IF |
67 SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS);
68 if (ret < 0)
69 return ret;
70
71 ret = snd_soc_dai_set_fmt(rtd->dai->cpu_dai, SND_SOC_DAIFMT_NB_IF |
72 SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS);
73 if (ret < 0)
74 return ret;
75
76 codec_freq = rate * 512;
77 /*
78 * This propagates the parent frequency change to children and
79 * recalculates the frequency table
80 */
81 clk_set_rate(&siumckb_clk, codec_freq);
82 dev_dbg(codec_dai->dev, "%s: configure %luHz\n", __func__, codec_freq);
83
84 ret = snd_soc_dai_set_sysclk(rtd->dai->cpu_dai, SIU_CLKB_EXT,
85 codec_freq / 2, SND_SOC_CLOCK_IN);
86
87 if (!ret)
88 use_count++;
89
90 return ret;
91}
92
93static int migor_hw_free(struct snd_pcm_substream *substream)
94{
95 struct snd_soc_pcm_runtime *rtd = substream->private_data;
96 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
97
98 if (use_count) {
99 use_count--;
100
101 if (!use_count)
102 snd_soc_dai_set_sysclk(codec_dai, WM8978_PLL, 0,
103 SND_SOC_CLOCK_IN);
104 } else {
105 dev_dbg(codec_dai->dev, "Unbalanced hw_free!\n");
106 }
107
108 return 0;
109}
110
111static struct snd_soc_ops migor_dai_ops = {
112 .hw_params = migor_hw_params,
113 .hw_free = migor_hw_free,
114};
115
116static const struct snd_soc_dapm_widget migor_dapm_widgets[] = {
117 SND_SOC_DAPM_HP("Headphone", NULL),
118 SND_SOC_DAPM_MIC("Onboard Microphone", NULL),
119 SND_SOC_DAPM_MIC("External Microphone", NULL),
120};
121
122static const struct snd_soc_dapm_route audio_map[] = {
123 /* Headphone output connected to LHP/RHP, enable OUT4 for VMID */
124 { "Headphone", NULL, "OUT4 VMID" },
125 { "OUT4 VMID", NULL, "LHP" },
126 { "OUT4 VMID", NULL, "RHP" },
127
128 /* On-board microphone */
129 { "RMICN", NULL, "Mic Bias" },
130 { "RMICP", NULL, "Mic Bias" },
131 { "Mic Bias", NULL, "Onboard Microphone" },
132
133 /* External microphone */
134 { "LMICN", NULL, "Mic Bias" },
135 { "LMICP", NULL, "Mic Bias" },
136 { "Mic Bias", NULL, "External Microphone" },
137};
138
139static int migor_dai_init(struct snd_soc_codec *codec)
140{
141 snd_soc_dapm_new_controls(codec, migor_dapm_widgets,
142 ARRAY_SIZE(migor_dapm_widgets));
143
144 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
145
146 return 0;
147}
148
149/* migor digital audio interface glue - connects codec <--> CPU */
150static struct snd_soc_dai_link migor_dai = {
151 .name = "wm8978",
152 .stream_name = "WM8978",
153 .cpu_dai = &siu_i2s_dai,
154 .codec_dai = &wm8978_dai,
155 .ops = &migor_dai_ops,
156 .init = migor_dai_init,
157};
158
159/* migor audio machine driver */
160static struct snd_soc_card snd_soc_migor = {
161 .name = "Migo-R",
162 .platform = &siu_platform,
163 .dai_link = &migor_dai,
164 .num_links = 1,
165};
166
167/* migor audio subsystem */
168static struct snd_soc_device migor_snd_devdata = {
169 .card = &snd_soc_migor,
170 .codec_dev = &soc_codec_dev_wm8978,
171};
172
173static struct platform_device *migor_snd_device;
174
175static int __init migor_init(void)
176{
177 int ret;
178
179 ret = clk_register(&siumckb_clk);
180 if (ret < 0)
181 return ret;
182
183 /* Port number used on this machine: port B */
184 migor_snd_device = platform_device_alloc("soc-audio", 1);
185 if (!migor_snd_device) {
186 ret = -ENOMEM;
187 goto epdevalloc;
188 }
189
190 platform_set_drvdata(migor_snd_device, &migor_snd_devdata);
191
192 migor_snd_devdata.dev = &migor_snd_device->dev;
193
194 ret = platform_device_add(migor_snd_device);
195 if (ret)
196 goto epdevadd;
197
198 return 0;
199
200epdevadd:
201 platform_device_put(migor_snd_device);
202epdevalloc:
203 clk_unregister(&siumckb_clk);
204 return ret;
205}
206
207static void __exit migor_exit(void)
208{
209 clk_unregister(&siumckb_clk);
210 platform_device_unregister(migor_snd_device);
211}
212
213module_init(migor_init);
214module_exit(migor_exit);
215
216MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
217MODULE_DESCRIPTION("ALSA SoC Migor");
218MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/sh/siu.h b/sound/soc/sh/siu.h
new file mode 100644
index 000000000000..c0bfab8fed3d
--- /dev/null
+++ b/sound/soc/sh/siu.h
@@ -0,0 +1,193 @@
1/*
2 * siu.h - ALSA SoC driver for Renesas SH7343, SH7722 SIU peripheral.
3 *
4 * Copyright (C) 2009-2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
5 * Copyright (C) 2006 Carlos Munoz <carlos@kenati.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#ifndef SIU_H
23#define SIU_H
24
25/* Common kernel and user-space firmware-building defines and types */
26
27#define YRAM0_SIZE (0x0040 / 4) /* 16 */
28#define YRAM1_SIZE (0x0080 / 4) /* 32 */
29#define YRAM2_SIZE (0x0040 / 4) /* 16 */
30#define YRAM3_SIZE (0x0080 / 4) /* 32 */
31#define YRAM4_SIZE (0x0080 / 4) /* 32 */
32#define YRAM_DEF_SIZE (YRAM0_SIZE + YRAM1_SIZE + YRAM2_SIZE + \
33 YRAM3_SIZE + YRAM4_SIZE)
34#define YRAM_FIR_SIZE (0x0400 / 4) /* 256 */
35#define YRAM_IIR_SIZE (0x0200 / 4) /* 128 */
36
37#define XRAM0_SIZE (0x0400 / 4) /* 256 */
38#define XRAM1_SIZE (0x0200 / 4) /* 128 */
39#define XRAM2_SIZE (0x0200 / 4) /* 128 */
40
41/* PRAM program array size */
42#define PRAM0_SIZE (0x0100 / 4) /* 64 */
43#define PRAM1_SIZE ((0x2000 - 0x0100) / 4) /* 1984 */
44
45#include <linux/types.h>
46
47struct siu_spb_param {
48 __u32 ab1a; /* input FIFO address */
49 __u32 ab0a; /* output FIFO address */
50 __u32 dir; /* 0=the ather except CPUOUTPUT, 1=CPUINPUT */
51 __u32 event; /* SPB program starting conditions */
52 __u32 stfifo; /* STFIFO register setting value */
53 __u32 trdat; /* TRDAT register setting value */
54};
55
56struct siu_firmware {
57 __u32 yram_fir_coeff[YRAM_FIR_SIZE];
58 __u32 pram0[PRAM0_SIZE];
59 __u32 pram1[PRAM1_SIZE];
60 __u32 yram0[YRAM0_SIZE];
61 __u32 yram1[YRAM1_SIZE];
62 __u32 yram2[YRAM2_SIZE];
63 __u32 yram3[YRAM3_SIZE];
64 __u32 yram4[YRAM4_SIZE];
65 __u32 spbpar_num;
66 struct siu_spb_param spbpar[32];
67};
68
69#ifdef __KERNEL__
70
71#include <linux/dmaengine.h>
72#include <linux/interrupt.h>
73#include <linux/io.h>
74
75#include <asm/dmaengine.h>
76
77#include <sound/core.h>
78#include <sound/pcm.h>
79#include <sound/soc-dai.h>
80
81#define SIU_PERIOD_BYTES_MAX 8192 /* DMA transfer/period size */
82#define SIU_PERIOD_BYTES_MIN 256 /* DMA transfer/period size */
83#define SIU_PERIODS_MAX 64 /* Max periods in buffer */
84#define SIU_PERIODS_MIN 4 /* Min periods in buffer */
85#define SIU_BUFFER_BYTES_MAX (SIU_PERIOD_BYTES_MAX * SIU_PERIODS_MAX)
86
87/* SIU ports: only one can be used at a time */
88enum {
89 SIU_PORT_A,
90 SIU_PORT_B,
91 SIU_PORT_NUM,
92};
93
94/* SIU clock configuration */
95enum {
96 SIU_CLKA_PLL,
97 SIU_CLKA_EXT,
98 SIU_CLKB_PLL,
99 SIU_CLKB_EXT
100};
101
102struct siu_info {
103 int port_id;
104 u32 __iomem *pram;
105 u32 __iomem *xram;
106 u32 __iomem *yram;
107 u32 __iomem *reg;
108 struct siu_firmware fw;
109};
110
111struct siu_stream {
112 struct tasklet_struct tasklet;
113 struct snd_pcm_substream *substream;
114 snd_pcm_format_t format;
115 size_t buf_bytes;
116 size_t period_bytes;
117 int cur_period; /* Period currently in dma */
118 u32 volume;
119 snd_pcm_sframes_t xfer_cnt; /* Number of frames */
120 u8 rw_flg; /* transfer status */
121 /* DMA status */
122 struct dma_chan *chan; /* DMA channel */
123 struct dma_async_tx_descriptor *tx_desc;
124 dma_cookie_t cookie;
125 struct sh_dmae_slave param;
126};
127
128struct siu_port {
129 unsigned long play_cap; /* Used to track full duplex */
130 struct snd_pcm *pcm;
131 struct siu_stream playback;
132 struct siu_stream capture;
133 u32 stfifo; /* STFIFO value from firmware */
134 u32 trdat; /* TRDAT value from firmware */
135};
136
137extern struct siu_port *siu_ports[SIU_PORT_NUM];
138
139static inline struct siu_port *siu_port_info(struct snd_pcm_substream *substream)
140{
141 struct platform_device *pdev =
142 to_platform_device(substream->pcm->card->dev);
143 return siu_ports[pdev->id];
144}
145
146/* Register access */
147static inline void siu_write32(u32 __iomem *addr, u32 val)
148{
149 __raw_writel(val, addr);
150}
151
152static inline u32 siu_read32(u32 __iomem *addr)
153{
154 return __raw_readl(addr);
155}
156
157/* SIU registers */
158#define SIU_IFCTL (0x000 / sizeof(u32))
159#define SIU_SRCTL (0x004 / sizeof(u32))
160#define SIU_SFORM (0x008 / sizeof(u32))
161#define SIU_CKCTL (0x00c / sizeof(u32))
162#define SIU_TRDAT (0x010 / sizeof(u32))
163#define SIU_STFIFO (0x014 / sizeof(u32))
164#define SIU_DPAK (0x01c / sizeof(u32))
165#define SIU_CKREV (0x020 / sizeof(u32))
166#define SIU_EVNTC (0x028 / sizeof(u32))
167#define SIU_SBCTL (0x040 / sizeof(u32))
168#define SIU_SBPSET (0x044 / sizeof(u32))
169#define SIU_SBFSTS (0x068 / sizeof(u32))
170#define SIU_SBDVCA (0x06c / sizeof(u32))
171#define SIU_SBDVCB (0x070 / sizeof(u32))
172#define SIU_SBACTIV (0x074 / sizeof(u32))
173#define SIU_DMAIA (0x090 / sizeof(u32))
174#define SIU_DMAIB (0x094 / sizeof(u32))
175#define SIU_DMAOA (0x098 / sizeof(u32))
176#define SIU_DMAOB (0x09c / sizeof(u32))
177#define SIU_DMAML (0x0a0 / sizeof(u32))
178#define SIU_SPSTS (0x0cc / sizeof(u32))
179#define SIU_SPCTL (0x0d0 / sizeof(u32))
180#define SIU_BRGASEL (0x100 / sizeof(u32))
181#define SIU_BRRA (0x104 / sizeof(u32))
182#define SIU_BRGBSEL (0x108 / sizeof(u32))
183#define SIU_BRRB (0x10c / sizeof(u32))
184
185extern struct snd_soc_platform siu_platform;
186extern struct snd_soc_dai siu_i2s_dai;
187
188int siu_init_port(int port, struct siu_port **port_info, struct snd_card *card);
189void siu_free_port(struct siu_port *port_info);
190
191#endif
192
193#endif /* SIU_H */
diff --git a/sound/soc/sh/siu_dai.c b/sound/soc/sh/siu_dai.c
new file mode 100644
index 000000000000..5452d19607e1
--- /dev/null
+++ b/sound/soc/sh/siu_dai.c
@@ -0,0 +1,847 @@
1/*
2 * siu_dai.c - ALSA SoC driver for Renesas SH7343, SH7722 SIU peripheral.
3 *
4 * Copyright (C) 2009-2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
5 * Copyright (C) 2006 Carlos Munoz <carlos@kenati.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <linux/delay.h>
23#include <linux/firmware.h>
24#include <linux/pm_runtime.h>
25
26#include <asm/clock.h>
27#include <asm/siu.h>
28
29#include <sound/control.h>
30#include <sound/soc-dai.h>
31
32#include "siu.h"
33
34/* Board specifics */
35#if defined(CONFIG_CPU_SUBTYPE_SH7722)
36# define SIU_MAX_VOLUME 0x1000
37#else
38# define SIU_MAX_VOLUME 0x7fff
39#endif
40
41#define PRAM_SIZE 0x2000
42#define XRAM_SIZE 0x800
43#define YRAM_SIZE 0x800
44
45#define XRAM_OFFSET 0x4000
46#define YRAM_OFFSET 0x6000
47#define REG_OFFSET 0xc000
48
49#define PLAYBACK_ENABLED 1
50#define CAPTURE_ENABLED 2
51
52#define VOLUME_CAPTURE 0
53#define VOLUME_PLAYBACK 1
54#define DFLT_VOLUME_LEVEL 0x08000800
55
56/*
57 * SPDIF is only available on port A and on some SIU implementations it is only
58 * available for input. Due to the lack of hardware to test it, SPDIF is left
59 * disabled in this driver version
60 */
61struct format_flag {
62 u32 i2s;
63 u32 pcm;
64 u32 spdif;
65 u32 mask;
66};
67
68struct port_flag {
69 struct format_flag playback;
70 struct format_flag capture;
71};
72
73static struct port_flag siu_flags[SIU_PORT_NUM] = {
74 [SIU_PORT_A] = {
75 .playback = {
76 .i2s = 0x50000000,
77 .pcm = 0x40000000,
78 .spdif = 0x80000000, /* not on all SIU versions */
79 .mask = 0xd0000000,
80 },
81 .capture = {
82 .i2s = 0x05000000,
83 .pcm = 0x04000000,
84 .spdif = 0x08000000,
85 .mask = 0x0d000000,
86 },
87 },
88 [SIU_PORT_B] = {
89 .playback = {
90 .i2s = 0x00500000,
91 .pcm = 0x00400000,
92 .spdif = 0, /* impossible - turn off */
93 .mask = 0x00500000,
94 },
95 .capture = {
96 .i2s = 0x00050000,
97 .pcm = 0x00040000,
98 .spdif = 0, /* impossible - turn off */
99 .mask = 0x00050000,
100 },
101 },
102};
103
104static void siu_dai_start(struct siu_port *port_info)
105{
106 struct siu_info *info = siu_i2s_dai.private_data;
107 u32 __iomem *base = info->reg;
108
109 dev_dbg(port_info->pcm->card->dev, "%s\n", __func__);
110
111 /* Turn on SIU clock */
112 pm_runtime_get_sync(siu_i2s_dai.dev);
113
114 /* Issue software reset to siu */
115 siu_write32(base + SIU_SRCTL, 0);
116
117 /* Wait for the reset to take effect */
118 udelay(1);
119
120 port_info->stfifo = 0;
121 port_info->trdat = 0;
122
123 /* portA, portB, SIU operate */
124 siu_write32(base + SIU_SRCTL, 0x301);
125
126 /* portA=256fs, portB=256fs */
127 siu_write32(base + SIU_CKCTL, 0x40400000);
128
129 /* portA's BRG does not divide SIUCKA */
130 siu_write32(base + SIU_BRGASEL, 0);
131 siu_write32(base + SIU_BRRA, 0);
132
133 /* portB's BRG divides SIUCKB by half */
134 siu_write32(base + SIU_BRGBSEL, 1);
135 siu_write32(base + SIU_BRRB, 0);
136
137 siu_write32(base + SIU_IFCTL, 0x44440000);
138
139 /* portA: 32 bit/fs, master; portB: 32 bit/fs, master */
140 siu_write32(base + SIU_SFORM, 0x0c0c0000);
141
142 /*
143 * Volume levels: looks like the DSP firmware implements volume controls
144 * differently from what's described in the datasheet
145 */
146 siu_write32(base + SIU_SBDVCA, port_info->playback.volume);
147 siu_write32(base + SIU_SBDVCB, port_info->capture.volume);
148}
149
150static void siu_dai_stop(void)
151{
152 struct siu_info *info = siu_i2s_dai.private_data;
153 u32 __iomem *base = info->reg;
154
155 /* SIU software reset */
156 siu_write32(base + SIU_SRCTL, 0);
157
158 /* Turn off SIU clock */
159 pm_runtime_put_sync(siu_i2s_dai.dev);
160}
161
162static void siu_dai_spbAselect(struct siu_port *port_info)
163{
164 struct siu_info *info = siu_i2s_dai.private_data;
165 struct siu_firmware *fw = &info->fw;
166 u32 *ydef = fw->yram0;
167 u32 idx;
168
169 /* path A use */
170 if (!info->port_id)
171 idx = 1; /* portA */
172 else
173 idx = 2; /* portB */
174
175 ydef[0] = (fw->spbpar[idx].ab1a << 16) |
176 (fw->spbpar[idx].ab0a << 8) |
177 (fw->spbpar[idx].dir << 7) | 3;
178 ydef[1] = fw->yram0[1]; /* 0x03000300 */
179 ydef[2] = (16 / 2) << 24;
180 ydef[3] = fw->yram0[3]; /* 0 */
181 ydef[4] = fw->yram0[4]; /* 0 */
182 ydef[7] = fw->spbpar[idx].event;
183 port_info->stfifo |= fw->spbpar[idx].stfifo;
184 port_info->trdat |= fw->spbpar[idx].trdat;
185}
186
187static void siu_dai_spbBselect(struct siu_port *port_info)
188{
189 struct siu_info *info = siu_i2s_dai.private_data;
190 struct siu_firmware *fw = &info->fw;
191 u32 *ydef = fw->yram0;
192 u32 idx;
193
194 /* path B use */
195 if (!info->port_id)
196 idx = 7; /* portA */
197 else
198 idx = 8; /* portB */
199
200 ydef[5] = (fw->spbpar[idx].ab1a << 16) |
201 (fw->spbpar[idx].ab0a << 8) | 1;
202 ydef[6] = fw->spbpar[idx].event;
203 port_info->stfifo |= fw->spbpar[idx].stfifo;
204 port_info->trdat |= fw->spbpar[idx].trdat;
205}
206
207static void siu_dai_open(struct siu_stream *siu_stream)
208{
209 struct siu_info *info = siu_i2s_dai.private_data;
210 u32 __iomem *base = info->reg;
211 u32 srctl, ifctl;
212
213 srctl = siu_read32(base + SIU_SRCTL);
214 ifctl = siu_read32(base + SIU_IFCTL);
215
216 switch (info->port_id) {
217 case SIU_PORT_A:
218 /* portA operates */
219 srctl |= 0x200;
220 ifctl &= ~0xc2;
221 break;
222 case SIU_PORT_B:
223 /* portB operates */
224 srctl |= 0x100;
225 ifctl &= ~0x31;
226 break;
227 }
228
229 siu_write32(base + SIU_SRCTL, srctl);
230 /* Unmute and configure portA */
231 siu_write32(base + SIU_IFCTL, ifctl);
232}
233
234/*
235 * At the moment only fixed Left-upper, Left-lower, Right-upper, Right-lower
236 * packing is supported
237 */
238static void siu_dai_pcmdatapack(struct siu_stream *siu_stream)
239{
240 struct siu_info *info = siu_i2s_dai.private_data;
241 u32 __iomem *base = info->reg;
242 u32 dpak;
243
244 dpak = siu_read32(base + SIU_DPAK);
245
246 switch (info->port_id) {
247 case SIU_PORT_A:
248 dpak &= ~0xc0000000;
249 break;
250 case SIU_PORT_B:
251 dpak &= ~0x00c00000;
252 break;
253 }
254
255 siu_write32(base + SIU_DPAK, dpak);
256}
257
258static int siu_dai_spbstart(struct siu_port *port_info)
259{
260 struct siu_info *info = siu_i2s_dai.private_data;
261 u32 __iomem *base = info->reg;
262 struct siu_firmware *fw = &info->fw;
263 u32 *ydef = fw->yram0;
264 int cnt;
265 u32 __iomem *add;
266 u32 *ptr;
267
268 /* Load SPB Program in PRAM */
269 ptr = fw->pram0;
270 add = info->pram;
271 for (cnt = 0; cnt < PRAM0_SIZE; cnt++, add++, ptr++)
272 siu_write32(add, *ptr);
273
274 ptr = fw->pram1;
275 add = info->pram + (0x0100 / sizeof(u32));
276 for (cnt = 0; cnt < PRAM1_SIZE; cnt++, add++, ptr++)
277 siu_write32(add, *ptr);
278
279 /* XRAM initialization */
280 add = info->xram;
281 for (cnt = 0; cnt < XRAM0_SIZE + XRAM1_SIZE + XRAM2_SIZE; cnt++, add++)
282 siu_write32(add, 0);
283
284 /* YRAM variable area initialization */
285 add = info->yram;
286 for (cnt = 0; cnt < YRAM_DEF_SIZE; cnt++, add++)
287 siu_write32(add, ydef[cnt]);
288
289 /* YRAM FIR coefficient area initialization */
290 add = info->yram + (0x0200 / sizeof(u32));
291 for (cnt = 0; cnt < YRAM_FIR_SIZE; cnt++, add++)
292 siu_write32(add, fw->yram_fir_coeff[cnt]);
293
294 /* YRAM IIR coefficient area initialization */
295 add = info->yram + (0x0600 / sizeof(u32));
296 for (cnt = 0; cnt < YRAM_IIR_SIZE; cnt++, add++)
297 siu_write32(add, 0);
298
299 siu_write32(base + SIU_TRDAT, port_info->trdat);
300 port_info->trdat = 0x0;
301
302
303 /* SPB start condition: software */
304 siu_write32(base + SIU_SBACTIV, 0);
305 /* Start SPB */
306 siu_write32(base + SIU_SBCTL, 0xc0000000);
307 /* Wait for program to halt */
308 cnt = 0x10000;
309 while (--cnt && siu_read32(base + SIU_SBCTL) != 0x80000000)
310 cpu_relax();
311
312 if (!cnt)
313 return -EBUSY;
314
315 /* SPB program start address setting */
316 siu_write32(base + SIU_SBPSET, 0x00400000);
317 /* SPB hardware start(FIFOCTL source) */
318 siu_write32(base + SIU_SBACTIV, 0xc0000000);
319
320 return 0;
321}
322
323static void siu_dai_spbstop(struct siu_port *port_info)
324{
325 struct siu_info *info = siu_i2s_dai.private_data;
326 u32 __iomem *base = info->reg;
327
328 siu_write32(base + SIU_SBACTIV, 0);
329 /* SPB stop */
330 siu_write32(base + SIU_SBCTL, 0);
331
332 port_info->stfifo = 0;
333}
334
335/* API functions */
336
337/* Playback and capture hardware properties are identical */
338static struct snd_pcm_hardware siu_dai_pcm_hw = {
339 .info = SNDRV_PCM_INFO_INTERLEAVED,
340 .formats = SNDRV_PCM_FMTBIT_S16,
341 .rates = SNDRV_PCM_RATE_8000_48000,
342 .rate_min = 8000,
343 .rate_max = 48000,
344 .channels_min = 2,
345 .channels_max = 2,
346 .buffer_bytes_max = SIU_BUFFER_BYTES_MAX,
347 .period_bytes_min = SIU_PERIOD_BYTES_MIN,
348 .period_bytes_max = SIU_PERIOD_BYTES_MAX,
349 .periods_min = SIU_PERIODS_MIN,
350 .periods_max = SIU_PERIODS_MAX,
351};
352
353static int siu_dai_info_volume(struct snd_kcontrol *kctrl,
354 struct snd_ctl_elem_info *uinfo)
355{
356 struct siu_port *port_info = snd_kcontrol_chip(kctrl);
357
358 dev_dbg(port_info->pcm->card->dev, "%s\n", __func__);
359
360 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
361 uinfo->count = 2;
362 uinfo->value.integer.min = 0;
363 uinfo->value.integer.max = SIU_MAX_VOLUME;
364
365 return 0;
366}
367
368static int siu_dai_get_volume(struct snd_kcontrol *kctrl,
369 struct snd_ctl_elem_value *ucontrol)
370{
371 struct siu_port *port_info = snd_kcontrol_chip(kctrl);
372 struct device *dev = port_info->pcm->card->dev;
373 u32 vol;
374
375 dev_dbg(dev, "%s\n", __func__);
376
377 switch (kctrl->private_value) {
378 case VOLUME_PLAYBACK:
379 /* Playback is always on port 0 */
380 vol = port_info->playback.volume;
381 ucontrol->value.integer.value[0] = vol & 0xffff;
382 ucontrol->value.integer.value[1] = vol >> 16 & 0xffff;
383 break;
384 case VOLUME_CAPTURE:
385 /* Capture is always on port 1 */
386 vol = port_info->capture.volume;
387 ucontrol->value.integer.value[0] = vol & 0xffff;
388 ucontrol->value.integer.value[1] = vol >> 16 & 0xffff;
389 break;
390 default:
391 dev_err(dev, "%s() invalid private_value=%ld\n",
392 __func__, kctrl->private_value);
393 return -EINVAL;
394 }
395
396 return 0;
397}
398
399static int siu_dai_put_volume(struct snd_kcontrol *kctrl,
400 struct snd_ctl_elem_value *ucontrol)
401{
402 struct siu_port *port_info = snd_kcontrol_chip(kctrl);
403 struct device *dev = port_info->pcm->card->dev;
404 struct siu_info *info = siu_i2s_dai.private_data;
405 u32 __iomem *base = info->reg;
406 u32 new_vol;
407 u32 cur_vol;
408
409 dev_dbg(dev, "%s\n", __func__);
410
411 if (ucontrol->value.integer.value[0] < 0 ||
412 ucontrol->value.integer.value[0] > SIU_MAX_VOLUME ||
413 ucontrol->value.integer.value[1] < 0 ||
414 ucontrol->value.integer.value[1] > SIU_MAX_VOLUME)
415 return -EINVAL;
416
417 new_vol = ucontrol->value.integer.value[0] |
418 ucontrol->value.integer.value[1] << 16;
419
420 /* See comment above - DSP firmware implementation */
421 switch (kctrl->private_value) {
422 case VOLUME_PLAYBACK:
423 /* Playback is always on port 0 */
424 cur_vol = port_info->playback.volume;
425 siu_write32(base + SIU_SBDVCA, new_vol);
426 port_info->playback.volume = new_vol;
427 break;
428 case VOLUME_CAPTURE:
429 /* Capture is always on port 1 */
430 cur_vol = port_info->capture.volume;
431 siu_write32(base + SIU_SBDVCB, new_vol);
432 port_info->capture.volume = new_vol;
433 break;
434 default:
435 dev_err(dev, "%s() invalid private_value=%ld\n",
436 __func__, kctrl->private_value);
437 return -EINVAL;
438 }
439
440 if (cur_vol != new_vol)
441 return 1;
442
443 return 0;
444}
445
446static struct snd_kcontrol_new playback_controls = {
447 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
448 .name = "PCM Playback Volume",
449 .index = 0,
450 .info = siu_dai_info_volume,
451 .get = siu_dai_get_volume,
452 .put = siu_dai_put_volume,
453 .private_value = VOLUME_PLAYBACK,
454};
455
456static struct snd_kcontrol_new capture_controls = {
457 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
458 .name = "PCM Capture Volume",
459 .index = 0,
460 .info = siu_dai_info_volume,
461 .get = siu_dai_get_volume,
462 .put = siu_dai_put_volume,
463 .private_value = VOLUME_CAPTURE,
464};
465
466int siu_init_port(int port, struct siu_port **port_info, struct snd_card *card)
467{
468 struct device *dev = card->dev;
469 struct snd_kcontrol *kctrl;
470 int ret;
471
472 *port_info = kzalloc(sizeof(**port_info), GFP_KERNEL);
473 if (!*port_info)
474 return -ENOMEM;
475
476 dev_dbg(dev, "%s: port #%d@%p\n", __func__, port, *port_info);
477
478 (*port_info)->playback.volume = DFLT_VOLUME_LEVEL;
479 (*port_info)->capture.volume = DFLT_VOLUME_LEVEL;
480
481 /*
482 * Add mixer support. The SPB is used to change the volume. Both
483 * ports use the same SPB. Therefore, we only register one
484 * control instance since it will be used by both channels.
485 * In error case we continue without controls.
486 */
487 kctrl = snd_ctl_new1(&playback_controls, *port_info);
488 ret = snd_ctl_add(card, kctrl);
489 if (ret < 0)
490 dev_err(dev,
491 "failed to add playback controls %p port=%d err=%d\n",
492 kctrl, port, ret);
493
494 kctrl = snd_ctl_new1(&capture_controls, *port_info);
495 ret = snd_ctl_add(card, kctrl);
496 if (ret < 0)
497 dev_err(dev,
498 "failed to add capture controls %p port=%d err=%d\n",
499 kctrl, port, ret);
500
501 return 0;
502}
503
504void siu_free_port(struct siu_port *port_info)
505{
506 kfree(port_info);
507}
508
509static int siu_dai_startup(struct snd_pcm_substream *substream,
510 struct snd_soc_dai *dai)
511{
512 struct siu_info *info = siu_i2s_dai.private_data;
513 struct snd_pcm_runtime *rt = substream->runtime;
514 struct siu_port *port_info = siu_port_info(substream);
515 int ret;
516
517 dev_dbg(substream->pcm->card->dev, "%s: port=%d@%p\n", __func__,
518 info->port_id, port_info);
519
520 snd_soc_set_runtime_hwparams(substream, &siu_dai_pcm_hw);
521
522 ret = snd_pcm_hw_constraint_integer(rt, SNDRV_PCM_HW_PARAM_PERIODS);
523 if (unlikely(ret < 0))
524 return ret;
525
526 siu_dai_start(port_info);
527
528 return 0;
529}
530
531static void siu_dai_shutdown(struct snd_pcm_substream *substream,
532 struct snd_soc_dai *dai)
533{
534 struct siu_info *info = siu_i2s_dai.private_data;
535 struct siu_port *port_info = siu_port_info(substream);
536
537 dev_dbg(substream->pcm->card->dev, "%s: port=%d@%p\n", __func__,
538 info->port_id, port_info);
539
540 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
541 port_info->play_cap &= ~PLAYBACK_ENABLED;
542 else
543 port_info->play_cap &= ~CAPTURE_ENABLED;
544
545 /* Stop the siu if the other stream is not using it */
546 if (!port_info->play_cap) {
547 /* during stmread or stmwrite ? */
548 BUG_ON(port_info->playback.rw_flg || port_info->capture.rw_flg);
549 siu_dai_spbstop(port_info);
550 siu_dai_stop();
551 }
552}
553
554/* PCM part of siu_dai_playback_prepare() / siu_dai_capture_prepare() */
555static int siu_dai_prepare(struct snd_pcm_substream *substream,
556 struct snd_soc_dai *dai)
557{
558 struct siu_info *info = siu_i2s_dai.private_data;
559 struct snd_pcm_runtime *rt = substream->runtime;
560 struct siu_port *port_info = siu_port_info(substream);
561 struct siu_stream *siu_stream;
562 int self, ret;
563
564 dev_dbg(substream->pcm->card->dev,
565 "%s: port %d, active streams %lx, %d channels\n",
566 __func__, info->port_id, port_info->play_cap, rt->channels);
567
568 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
569 self = PLAYBACK_ENABLED;
570 siu_stream = &port_info->playback;
571 } else {
572 self = CAPTURE_ENABLED;
573 siu_stream = &port_info->capture;
574 }
575
576 /* Set up the siu if not already done */
577 if (!port_info->play_cap) {
578 siu_stream->rw_flg = 0; /* stream-data transfer flag */
579
580 siu_dai_spbAselect(port_info);
581 siu_dai_spbBselect(port_info);
582
583 siu_dai_open(siu_stream);
584
585 siu_dai_pcmdatapack(siu_stream);
586
587 ret = siu_dai_spbstart(port_info);
588 if (ret < 0)
589 goto fail;
590 }
591
592 port_info->play_cap |= self;
593
594fail:
595 return ret;
596}
597
598/*
599 * SIU can set bus format to I2S / PCM / SPDIF independently for playback and
600 * capture, however, the current API sets the bus format globally for a DAI.
601 */
602static int siu_dai_set_fmt(struct snd_soc_dai *dai,
603 unsigned int fmt)
604{
605 struct siu_info *info = siu_i2s_dai.private_data;
606 u32 __iomem *base = info->reg;
607 u32 ifctl;
608
609 dev_dbg(dai->dev, "%s: fmt 0x%x on port %d\n",
610 __func__, fmt, info->port_id);
611
612 if (info->port_id < 0)
613 return -ENODEV;
614
615 /* Here select between I2S / PCM / SPDIF */
616 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
617 case SND_SOC_DAIFMT_I2S:
618 ifctl = siu_flags[info->port_id].playback.i2s |
619 siu_flags[info->port_id].capture.i2s;
620 break;
621 case SND_SOC_DAIFMT_LEFT_J:
622 ifctl = siu_flags[info->port_id].playback.pcm |
623 siu_flags[info->port_id].capture.pcm;
624 break;
625 /* SPDIF disabled - see comment at the top */
626 default:
627 return -EINVAL;
628 }
629
630 ifctl |= ~(siu_flags[info->port_id].playback.mask |
631 siu_flags[info->port_id].capture.mask) &
632 siu_read32(base + SIU_IFCTL);
633 siu_write32(base + SIU_IFCTL, ifctl);
634
635 return 0;
636}
637
638static int siu_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
639 unsigned int freq, int dir)
640{
641 struct clk *siu_clk, *parent_clk;
642 char *siu_name, *parent_name;
643 int ret;
644
645 if (dir != SND_SOC_CLOCK_IN)
646 return -EINVAL;
647
648 dev_dbg(dai->dev, "%s: using clock %d\n", __func__, clk_id);
649
650 switch (clk_id) {
651 case SIU_CLKA_PLL:
652 siu_name = "siua_clk";
653 parent_name = "pll_clk";
654 break;
655 case SIU_CLKA_EXT:
656 siu_name = "siua_clk";
657 parent_name = "siumcka_clk";
658 break;
659 case SIU_CLKB_PLL:
660 siu_name = "siub_clk";
661 parent_name = "pll_clk";
662 break;
663 case SIU_CLKB_EXT:
664 siu_name = "siub_clk";
665 parent_name = "siumckb_clk";
666 break;
667 default:
668 return -EINVAL;
669 }
670
671 siu_clk = clk_get(siu_i2s_dai.dev, siu_name);
672 if (IS_ERR(siu_clk))
673 return PTR_ERR(siu_clk);
674
675 parent_clk = clk_get(siu_i2s_dai.dev, parent_name);
676 if (!IS_ERR(parent_clk)) {
677 ret = clk_set_parent(siu_clk, parent_clk);
678 if (!ret)
679 clk_set_rate(siu_clk, freq);
680 clk_put(parent_clk);
681 }
682
683 clk_put(siu_clk);
684
685 return 0;
686}
687
688static struct snd_soc_dai_ops siu_dai_ops = {
689 .startup = siu_dai_startup,
690 .shutdown = siu_dai_shutdown,
691 .prepare = siu_dai_prepare,
692 .set_sysclk = siu_dai_set_sysclk,
693 .set_fmt = siu_dai_set_fmt,
694};
695
696struct snd_soc_dai siu_i2s_dai = {
697 .name = "sh-siu",
698 .id = 0,
699 .playback = {
700 .channels_min = 2,
701 .channels_max = 2,
702 .formats = SNDRV_PCM_FMTBIT_S16,
703 .rates = SNDRV_PCM_RATE_8000_48000,
704 },
705 .capture = {
706 .channels_min = 2,
707 .channels_max = 2,
708 .formats = SNDRV_PCM_FMTBIT_S16,
709 .rates = SNDRV_PCM_RATE_8000_48000,
710 },
711 .ops = &siu_dai_ops,
712};
713EXPORT_SYMBOL_GPL(siu_i2s_dai);
714
715static int __devinit siu_probe(struct platform_device *pdev)
716{
717 const struct firmware *fw_entry;
718 struct resource *res, *region;
719 struct siu_info *info;
720 int ret;
721
722 info = kmalloc(sizeof(*info), GFP_KERNEL);
723 if (!info)
724 return -ENOMEM;
725
726 ret = request_firmware(&fw_entry, "siu_spb.bin", &pdev->dev);
727 if (ret)
728 goto ereqfw;
729
730 /*
731 * Loaded firmware is "const" - read only, but we have to modify it in
732 * snd_siu_sh7343_spbAselect() and snd_siu_sh7343_spbBselect()
733 */
734 memcpy(&info->fw, fw_entry->data, fw_entry->size);
735
736 release_firmware(fw_entry);
737
738 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
739 if (!res) {
740 ret = -ENODEV;
741 goto egetres;
742 }
743
744 region = request_mem_region(res->start, resource_size(res),
745 pdev->name);
746 if (!region) {
747 dev_err(&pdev->dev, "SIU region already claimed\n");
748 ret = -EBUSY;
749 goto ereqmemreg;
750 }
751
752 ret = -ENOMEM;
753 info->pram = ioremap(res->start, PRAM_SIZE);
754 if (!info->pram)
755 goto emappram;
756 info->xram = ioremap(res->start + XRAM_OFFSET, XRAM_SIZE);
757 if (!info->xram)
758 goto emapxram;
759 info->yram = ioremap(res->start + YRAM_OFFSET, YRAM_SIZE);
760 if (!info->yram)
761 goto emapyram;
762 info->reg = ioremap(res->start + REG_OFFSET, resource_size(res) -
763 REG_OFFSET);
764 if (!info->reg)
765 goto emapreg;
766
767 siu_i2s_dai.dev = &pdev->dev;
768 siu_i2s_dai.private_data = info;
769
770 ret = snd_soc_register_dais(&siu_i2s_dai, 1);
771 if (ret < 0)
772 goto edaiinit;
773
774 ret = snd_soc_register_platform(&siu_platform);
775 if (ret < 0)
776 goto esocregp;
777
778 pm_runtime_enable(&pdev->dev);
779
780 return ret;
781
782esocregp:
783 snd_soc_unregister_dais(&siu_i2s_dai, 1);
784edaiinit:
785 iounmap(info->reg);
786emapreg:
787 iounmap(info->yram);
788emapyram:
789 iounmap(info->xram);
790emapxram:
791 iounmap(info->pram);
792emappram:
793 release_mem_region(res->start, resource_size(res));
794ereqmemreg:
795egetres:
796ereqfw:
797 kfree(info);
798
799 return ret;
800}
801
802static int __devexit siu_remove(struct platform_device *pdev)
803{
804 struct siu_info *info = siu_i2s_dai.private_data;
805 struct resource *res;
806
807 pm_runtime_disable(&pdev->dev);
808
809 snd_soc_unregister_platform(&siu_platform);
810 snd_soc_unregister_dais(&siu_i2s_dai, 1);
811
812 iounmap(info->reg);
813 iounmap(info->yram);
814 iounmap(info->xram);
815 iounmap(info->pram);
816 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
817 if (res)
818 release_mem_region(res->start, resource_size(res));
819 kfree(info);
820
821 return 0;
822}
823
824static struct platform_driver siu_driver = {
825 .driver = {
826 .name = "sh_siu",
827 },
828 .probe = siu_probe,
829 .remove = __devexit_p(siu_remove),
830};
831
832static int __init siu_init(void)
833{
834 return platform_driver_register(&siu_driver);
835}
836
837static void __exit siu_exit(void)
838{
839 platform_driver_unregister(&siu_driver);
840}
841
842module_init(siu_init)
843module_exit(siu_exit)
844
845MODULE_AUTHOR("Carlos Munoz <carlos@kenati.com>");
846MODULE_DESCRIPTION("ALSA SoC SH7722 SIU driver");
847MODULE_LICENSE("GPL");
diff --git a/sound/soc/sh/siu_pcm.c b/sound/soc/sh/siu_pcm.c
new file mode 100644
index 000000000000..ba7f8d05d977
--- /dev/null
+++ b/sound/soc/sh/siu_pcm.c
@@ -0,0 +1,616 @@
1/*
2 * siu_pcm.c - ALSA driver for Renesas SH7343, SH7722 SIU peripheral.
3 *
4 * Copyright (C) 2009-2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
5 * Copyright (C) 2006 Carlos Munoz <carlos@kenati.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21#include <linux/delay.h>
22#include <linux/dma-mapping.h>
23#include <linux/dmaengine.h>
24#include <linux/interrupt.h>
25#include <linux/module.h>
26#include <linux/platform_device.h>
27#include <linux/slab.h>
28
29#include <sound/control.h>
30#include <sound/core.h>
31#include <sound/pcm.h>
32#include <sound/pcm_params.h>
33#include <sound/soc-dai.h>
34
35#include <asm/dmaengine.h>
36#include <asm/siu.h>
37
38#include "siu.h"
39
40#define GET_MAX_PERIODS(buf_bytes, period_bytes) \
41 ((buf_bytes) / (period_bytes))
42#define PERIOD_OFFSET(buf_addr, period_num, period_bytes) \
43 ((buf_addr) + ((period_num) * (period_bytes)))
44
45#define RWF_STM_RD 0x01 /* Read in progress */
46#define RWF_STM_WT 0x02 /* Write in progress */
47
48struct siu_port *siu_ports[SIU_PORT_NUM];
49
50/* transfersize is number of u32 dma transfers per period */
51static int siu_pcm_stmwrite_stop(struct siu_port *port_info)
52{
53 struct siu_info *info = siu_i2s_dai.private_data;
54 u32 __iomem *base = info->reg;
55 struct siu_stream *siu_stream = &port_info->playback;
56 u32 stfifo;
57
58 if (!siu_stream->rw_flg)
59 return -EPERM;
60
61 /* output FIFO disable */
62 stfifo = siu_read32(base + SIU_STFIFO);
63 siu_write32(base + SIU_STFIFO, stfifo & ~0x0c180c18);
64 pr_debug("%s: STFIFO %x -> %x\n", __func__,
65 stfifo, stfifo & ~0x0c180c18);
66
67 /* during stmwrite clear */
68 siu_stream->rw_flg = 0;
69
70 return 0;
71}
72
73static int siu_pcm_stmwrite_start(struct siu_port *port_info)
74{
75 struct siu_stream *siu_stream = &port_info->playback;
76
77 if (siu_stream->rw_flg)
78 return -EPERM;
79
80 /* Current period in buffer */
81 port_info->playback.cur_period = 0;
82
83 /* during stmwrite flag set */
84 siu_stream->rw_flg = RWF_STM_WT;
85
86 /* DMA transfer start */
87 tasklet_schedule(&siu_stream->tasklet);
88
89 return 0;
90}
91
92static void siu_dma_tx_complete(void *arg)
93{
94 struct siu_stream *siu_stream = arg;
95
96 if (!siu_stream->rw_flg)
97 return;
98
99 /* Update completed period count */
100 if (++siu_stream->cur_period >=
101 GET_MAX_PERIODS(siu_stream->buf_bytes,
102 siu_stream->period_bytes))
103 siu_stream->cur_period = 0;
104
105 pr_debug("%s: done period #%d (%u/%u bytes), cookie %d\n",
106 __func__, siu_stream->cur_period,
107 siu_stream->cur_period * siu_stream->period_bytes,
108 siu_stream->buf_bytes, siu_stream->cookie);
109
110 tasklet_schedule(&siu_stream->tasklet);
111
112 /* Notify alsa: a period is done */
113 snd_pcm_period_elapsed(siu_stream->substream);
114}
115
116static int siu_pcm_wr_set(struct siu_port *port_info,
117 dma_addr_t buff, u32 size)
118{
119 struct siu_info *info = siu_i2s_dai.private_data;
120 u32 __iomem *base = info->reg;
121 struct siu_stream *siu_stream = &port_info->playback;
122 struct snd_pcm_substream *substream = siu_stream->substream;
123 struct device *dev = substream->pcm->card->dev;
124 struct dma_async_tx_descriptor *desc;
125 dma_cookie_t cookie;
126 struct scatterlist sg;
127 u32 stfifo;
128
129 sg_init_table(&sg, 1);
130 sg_set_page(&sg, pfn_to_page(PFN_DOWN(buff)),
131 size, offset_in_page(buff));
132 sg_dma_address(&sg) = buff;
133
134 desc = siu_stream->chan->device->device_prep_slave_sg(siu_stream->chan,
135 &sg, 1, DMA_TO_DEVICE, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
136 if (!desc) {
137 dev_err(dev, "Failed to allocate a dma descriptor\n");
138 return -ENOMEM;
139 }
140
141 desc->callback = siu_dma_tx_complete;
142 desc->callback_param = siu_stream;
143 cookie = desc->tx_submit(desc);
144 if (cookie < 0) {
145 dev_err(dev, "Failed to submit a dma transfer\n");
146 return cookie;
147 }
148
149 siu_stream->tx_desc = desc;
150 siu_stream->cookie = cookie;
151
152 dma_async_issue_pending(siu_stream->chan);
153
154 /* only output FIFO enable */
155 stfifo = siu_read32(base + SIU_STFIFO);
156 siu_write32(base + SIU_STFIFO, stfifo | (port_info->stfifo & 0x0c180c18));
157 dev_dbg(dev, "%s: STFIFO %x -> %x\n", __func__,
158 stfifo, stfifo | (port_info->stfifo & 0x0c180c18));
159
160 return 0;
161}
162
163static int siu_pcm_rd_set(struct siu_port *port_info,
164 dma_addr_t buff, size_t size)
165{
166 struct siu_info *info = siu_i2s_dai.private_data;
167 u32 __iomem *base = info->reg;
168 struct siu_stream *siu_stream = &port_info->capture;
169 struct snd_pcm_substream *substream = siu_stream->substream;
170 struct device *dev = substream->pcm->card->dev;
171 struct dma_async_tx_descriptor *desc;
172 dma_cookie_t cookie;
173 struct scatterlist sg;
174 u32 stfifo;
175
176 dev_dbg(dev, "%s: %u@%llx\n", __func__, size, (unsigned long long)buff);
177
178 sg_init_table(&sg, 1);
179 sg_set_page(&sg, pfn_to_page(PFN_DOWN(buff)),
180 size, offset_in_page(buff));
181 sg_dma_address(&sg) = buff;
182
183 desc = siu_stream->chan->device->device_prep_slave_sg(siu_stream->chan,
184 &sg, 1, DMA_FROM_DEVICE, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
185 if (!desc) {
186 dev_err(dev, "Failed to allocate dma descriptor\n");
187 return -ENOMEM;
188 }
189
190 desc->callback = siu_dma_tx_complete;
191 desc->callback_param = siu_stream;
192 cookie = desc->tx_submit(desc);
193 if (cookie < 0) {
194 dev_err(dev, "Failed to submit dma descriptor\n");
195 return cookie;
196 }
197
198 siu_stream->tx_desc = desc;
199 siu_stream->cookie = cookie;
200
201 dma_async_issue_pending(siu_stream->chan);
202
203 /* only input FIFO enable */
204 stfifo = siu_read32(base + SIU_STFIFO);
205 siu_write32(base + SIU_STFIFO, siu_read32(base + SIU_STFIFO) |
206 (port_info->stfifo & 0x13071307));
207 dev_dbg(dev, "%s: STFIFO %x -> %x\n", __func__,
208 stfifo, stfifo | (port_info->stfifo & 0x13071307));
209
210 return 0;
211}
212
213static void siu_io_tasklet(unsigned long data)
214{
215 struct siu_stream *siu_stream = (struct siu_stream *)data;
216 struct snd_pcm_substream *substream = siu_stream->substream;
217 struct device *dev = substream->pcm->card->dev;
218 struct snd_pcm_runtime *rt = substream->runtime;
219 struct siu_port *port_info = siu_port_info(substream);
220
221 dev_dbg(dev, "%s: flags %x\n", __func__, siu_stream->rw_flg);
222
223 if (!siu_stream->rw_flg) {
224 dev_dbg(dev, "%s: stream inactive\n", __func__);
225 return;
226 }
227
228 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
229 dma_addr_t buff;
230 size_t count;
231 u8 *virt;
232
233 buff = (dma_addr_t)PERIOD_OFFSET(rt->dma_addr,
234 siu_stream->cur_period,
235 siu_stream->period_bytes);
236 virt = PERIOD_OFFSET(rt->dma_area,
237 siu_stream->cur_period,
238 siu_stream->period_bytes);
239 count = siu_stream->period_bytes;
240
241 /* DMA transfer start */
242 siu_pcm_rd_set(port_info, buff, count);
243 } else {
244 siu_pcm_wr_set(port_info,
245 (dma_addr_t)PERIOD_OFFSET(rt->dma_addr,
246 siu_stream->cur_period,
247 siu_stream->period_bytes),
248 siu_stream->period_bytes);
249 }
250}
251
252/* Capture */
253static int siu_pcm_stmread_start(struct siu_port *port_info)
254{
255 struct siu_stream *siu_stream = &port_info->capture;
256
257 if (siu_stream->xfer_cnt > 0x1000000)
258 return -EINVAL;
259 if (siu_stream->rw_flg)
260 return -EPERM;
261
262 /* Current period in buffer */
263 siu_stream->cur_period = 0;
264
265 /* during stmread flag set */
266 siu_stream->rw_flg = RWF_STM_RD;
267
268 tasklet_schedule(&siu_stream->tasklet);
269
270 return 0;
271}
272
273static int siu_pcm_stmread_stop(struct siu_port *port_info)
274{
275 struct siu_info *info = siu_i2s_dai.private_data;
276 u32 __iomem *base = info->reg;
277 struct siu_stream *siu_stream = &port_info->capture;
278 struct device *dev = siu_stream->substream->pcm->card->dev;
279 u32 stfifo;
280
281 if (!siu_stream->rw_flg)
282 return -EPERM;
283
284 /* input FIFO disable */
285 stfifo = siu_read32(base + SIU_STFIFO);
286 siu_write32(base + SIU_STFIFO, stfifo & ~0x13071307);
287 dev_dbg(dev, "%s: STFIFO %x -> %x\n", __func__,
288 stfifo, stfifo & ~0x13071307);
289
290 /* during stmread flag clear */
291 siu_stream->rw_flg = 0;
292
293 return 0;
294}
295
296static int siu_pcm_hw_params(struct snd_pcm_substream *ss,
297 struct snd_pcm_hw_params *hw_params)
298{
299 struct siu_info *info = siu_i2s_dai.private_data;
300 struct device *dev = ss->pcm->card->dev;
301 int ret;
302
303 dev_dbg(dev, "%s: port=%d\n", __func__, info->port_id);
304
305 ret = snd_pcm_lib_malloc_pages(ss, params_buffer_bytes(hw_params));
306 if (ret < 0)
307 dev_err(dev, "snd_pcm_lib_malloc_pages() failed\n");
308
309 return ret;
310}
311
312static int siu_pcm_hw_free(struct snd_pcm_substream *ss)
313{
314 struct siu_info *info = siu_i2s_dai.private_data;
315 struct siu_port *port_info = siu_port_info(ss);
316 struct device *dev = ss->pcm->card->dev;
317 struct siu_stream *siu_stream;
318
319 if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK)
320 siu_stream = &port_info->playback;
321 else
322 siu_stream = &port_info->capture;
323
324 dev_dbg(dev, "%s: port=%d\n", __func__, info->port_id);
325
326 return snd_pcm_lib_free_pages(ss);
327}
328
329static bool filter(struct dma_chan *chan, void *slave)
330{
331 struct sh_dmae_slave *param = slave;
332
333 pr_debug("%s: slave ID %d\n", __func__, param->slave_id);
334
335 if (unlikely(param->dma_dev != chan->device->dev))
336 return false;
337
338 chan->private = param;
339 return true;
340}
341
342static int siu_pcm_open(struct snd_pcm_substream *ss)
343{
344 /* Playback / Capture */
345 struct siu_info *info = siu_i2s_dai.private_data;
346 struct siu_port *port_info = siu_port_info(ss);
347 struct siu_stream *siu_stream;
348 u32 port = info->port_id;
349 struct siu_platform *pdata = siu_i2s_dai.dev->platform_data;
350 struct device *dev = ss->pcm->card->dev;
351 dma_cap_mask_t mask;
352 struct sh_dmae_slave *param;
353
354 dma_cap_zero(mask);
355 dma_cap_set(DMA_SLAVE, mask);
356
357 dev_dbg(dev, "%s, port=%d@%p\n", __func__, port, port_info);
358
359 if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK) {
360 siu_stream = &port_info->playback;
361 param = &siu_stream->param;
362 param->slave_id = port ? SHDMA_SLAVE_SIUB_TX :
363 SHDMA_SLAVE_SIUA_TX;
364 } else {
365 siu_stream = &port_info->capture;
366 param = &siu_stream->param;
367 param->slave_id = port ? SHDMA_SLAVE_SIUB_RX :
368 SHDMA_SLAVE_SIUA_RX;
369 }
370
371 param->dma_dev = pdata->dma_dev;
372 /* Get DMA channel */
373 siu_stream->chan = dma_request_channel(mask, filter, param);
374 if (!siu_stream->chan) {
375 dev_err(dev, "DMA channel allocation failed!\n");
376 return -EBUSY;
377 }
378
379 siu_stream->substream = ss;
380
381 return 0;
382}
383
384static int siu_pcm_close(struct snd_pcm_substream *ss)
385{
386 struct siu_info *info = siu_i2s_dai.private_data;
387 struct device *dev = ss->pcm->card->dev;
388 struct siu_port *port_info = siu_port_info(ss);
389 struct siu_stream *siu_stream;
390
391 dev_dbg(dev, "%s: port=%d\n", __func__, info->port_id);
392
393 if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK)
394 siu_stream = &port_info->playback;
395 else
396 siu_stream = &port_info->capture;
397
398 dma_release_channel(siu_stream->chan);
399 siu_stream->chan = NULL;
400
401 siu_stream->substream = NULL;
402
403 return 0;
404}
405
406static int siu_pcm_prepare(struct snd_pcm_substream *ss)
407{
408 struct siu_info *info = siu_i2s_dai.private_data;
409 struct siu_port *port_info = siu_port_info(ss);
410 struct device *dev = ss->pcm->card->dev;
411 struct snd_pcm_runtime *rt = ss->runtime;
412 struct siu_stream *siu_stream;
413 snd_pcm_sframes_t xfer_cnt;
414
415 if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK)
416 siu_stream = &port_info->playback;
417 else
418 siu_stream = &port_info->capture;
419
420 rt = siu_stream->substream->runtime;
421
422 siu_stream->buf_bytes = snd_pcm_lib_buffer_bytes(ss);
423 siu_stream->period_bytes = snd_pcm_lib_period_bytes(ss);
424
425 dev_dbg(dev, "%s: port=%d, %d channels, period=%u bytes\n", __func__,
426 info->port_id, rt->channels, siu_stream->period_bytes);
427
428 /* We only support buffers that are multiples of the period */
429 if (siu_stream->buf_bytes % siu_stream->period_bytes) {
430 dev_err(dev, "%s() - buffer=%d not multiple of period=%d\n",
431 __func__, siu_stream->buf_bytes,
432 siu_stream->period_bytes);
433 return -EINVAL;
434 }
435
436 xfer_cnt = bytes_to_frames(rt, siu_stream->period_bytes);
437 if (!xfer_cnt || xfer_cnt > 0x1000000)
438 return -EINVAL;
439
440 siu_stream->format = rt->format;
441 siu_stream->xfer_cnt = xfer_cnt;
442
443 dev_dbg(dev, "port=%d buf=%lx buf_bytes=%d period_bytes=%d "
444 "format=%d channels=%d xfer_cnt=%d\n", info->port_id,
445 (unsigned long)rt->dma_addr, siu_stream->buf_bytes,
446 siu_stream->period_bytes,
447 siu_stream->format, rt->channels, (int)xfer_cnt);
448
449 return 0;
450}
451
452static int siu_pcm_trigger(struct snd_pcm_substream *ss, int cmd)
453{
454 struct siu_info *info = siu_i2s_dai.private_data;
455 struct device *dev = ss->pcm->card->dev;
456 struct siu_port *port_info = siu_port_info(ss);
457 int ret;
458
459 dev_dbg(dev, "%s: port=%d@%p, cmd=%d\n", __func__,
460 info->port_id, port_info, cmd);
461
462 switch (cmd) {
463 case SNDRV_PCM_TRIGGER_START:
464 if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK)
465 ret = siu_pcm_stmwrite_start(port_info);
466 else
467 ret = siu_pcm_stmread_start(port_info);
468
469 if (ret < 0)
470 dev_warn(dev, "%s: start failed on port=%d\n",
471 __func__, info->port_id);
472
473 break;
474 case SNDRV_PCM_TRIGGER_STOP:
475 if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK)
476 siu_pcm_stmwrite_stop(port_info);
477 else
478 siu_pcm_stmread_stop(port_info);
479 ret = 0;
480
481 break;
482 default:
483 dev_err(dev, "%s() unsupported cmd=%d\n", __func__, cmd);
484 ret = -EINVAL;
485 }
486
487 return ret;
488}
489
490/*
491 * So far only resolution of one period is supported, subject to extending the
492 * dmangine API
493 */
494static snd_pcm_uframes_t siu_pcm_pointer_dma(struct snd_pcm_substream *ss)
495{
496 struct device *dev = ss->pcm->card->dev;
497 struct siu_info *info = siu_i2s_dai.private_data;
498 u32 __iomem *base = info->reg;
499 struct siu_port *port_info = siu_port_info(ss);
500 struct snd_pcm_runtime *rt = ss->runtime;
501 size_t ptr;
502 struct siu_stream *siu_stream;
503
504 if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK)
505 siu_stream = &port_info->playback;
506 else
507 siu_stream = &port_info->capture;
508
509 /*
510 * ptr is the offset into the buffer where the dma is currently at. We
511 * check if the dma buffer has just wrapped.
512 */
513 ptr = PERIOD_OFFSET(rt->dma_addr,
514 siu_stream->cur_period,
515 siu_stream->period_bytes) - rt->dma_addr;
516
517 dev_dbg(dev,
518 "%s: port=%d, events %x, FSTS %x, xferred %u/%u, cookie %d\n",
519 __func__, info->port_id, siu_read32(base + SIU_EVNTC),
520 siu_read32(base + SIU_SBFSTS), ptr, siu_stream->buf_bytes,
521 siu_stream->cookie);
522
523 if (ptr >= siu_stream->buf_bytes)
524 ptr = 0;
525
526 return bytes_to_frames(ss->runtime, ptr);
527}
528
529static int siu_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
530 struct snd_pcm *pcm)
531{
532 /* card->dev == socdev->dev, see snd_soc_new_pcms() */
533 struct siu_info *info = siu_i2s_dai.private_data;
534 struct platform_device *pdev = to_platform_device(card->dev);
535 int ret;
536 int i;
537
538 /* pdev->id selects between SIUA and SIUB */
539 if (pdev->id < 0 || pdev->id >= SIU_PORT_NUM)
540 return -EINVAL;
541
542 info->port_id = pdev->id;
543
544 /*
545 * While the siu has 2 ports, only one port can be on at a time (only 1
546 * SPB). So far all the boards using the siu had only one of the ports
547 * wired to a codec. To simplify things, we only register one port with
548 * alsa. In case both ports are needed, it should be changed here
549 */
550 for (i = pdev->id; i < pdev->id + 1; i++) {
551 struct siu_port **port_info = &siu_ports[i];
552
553 ret = siu_init_port(i, port_info, card);
554 if (ret < 0)
555 return ret;
556
557 ret = snd_pcm_lib_preallocate_pages_for_all(pcm,
558 SNDRV_DMA_TYPE_DEV, NULL,
559 SIU_BUFFER_BYTES_MAX, SIU_BUFFER_BYTES_MAX);
560 if (ret < 0) {
561 dev_err(card->dev,
562 "snd_pcm_lib_preallocate_pages_for_all() err=%d",
563 ret);
564 goto fail;
565 }
566
567 (*port_info)->pcm = pcm;
568
569 /* IO tasklets */
570 tasklet_init(&(*port_info)->playback.tasklet, siu_io_tasklet,
571 (unsigned long)&(*port_info)->playback);
572 tasklet_init(&(*port_info)->capture.tasklet, siu_io_tasklet,
573 (unsigned long)&(*port_info)->capture);
574 }
575
576 dev_info(card->dev, "SuperH SIU driver initialized.\n");
577 return 0;
578
579fail:
580 siu_free_port(siu_ports[pdev->id]);
581 dev_err(card->dev, "SIU: failed to initialize.\n");
582 return ret;
583}
584
585static void siu_pcm_free(struct snd_pcm *pcm)
586{
587 struct platform_device *pdev = to_platform_device(pcm->card->dev);
588 struct siu_port *port_info = siu_ports[pdev->id];
589
590 tasklet_kill(&port_info->capture.tasklet);
591 tasklet_kill(&port_info->playback.tasklet);
592
593 siu_free_port(port_info);
594 snd_pcm_lib_preallocate_free_for_all(pcm);
595
596 dev_dbg(pcm->card->dev, "%s\n", __func__);
597}
598
599static struct snd_pcm_ops siu_pcm_ops = {
600 .open = siu_pcm_open,
601 .close = siu_pcm_close,
602 .ioctl = snd_pcm_lib_ioctl,
603 .hw_params = siu_pcm_hw_params,
604 .hw_free = siu_pcm_hw_free,
605 .prepare = siu_pcm_prepare,
606 .trigger = siu_pcm_trigger,
607 .pointer = siu_pcm_pointer_dma,
608};
609
610struct snd_soc_platform siu_platform = {
611 .name = "siu-audio",
612 .pcm_ops = &siu_pcm_ops,
613 .pcm_new = siu_pcm_new,
614 .pcm_free = siu_pcm_free,
615};
616EXPORT_SYMBOL_GPL(siu_platform);
diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c
index d2505e8b06c9..5869dc3be781 100644
--- a/sound/soc/soc-cache.c
+++ b/sound/soc/soc-cache.c
@@ -15,6 +15,74 @@
15#include <linux/spi/spi.h> 15#include <linux/spi/spi.h>
16#include <sound/soc.h> 16#include <sound/soc.h>
17 17
18static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec,
19 unsigned int reg)
20{
21 u16 *cache = codec->reg_cache;
22 if (reg >= codec->reg_cache_size)
23 return -1;
24 return cache[reg];
25}
26
27static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg,
28 unsigned int value)
29{
30 u16 *cache = codec->reg_cache;
31 u8 data[2];
32 int ret;
33
34 BUG_ON(codec->volatile_register);
35
36 data[0] = (reg << 4) | ((value >> 8) & 0x000f);
37 data[1] = value & 0x00ff;
38
39 if (reg < codec->reg_cache_size)
40 cache[reg] = value;
41
42 if (codec->cache_only) {
43 codec->cache_sync = 1;
44 return 0;
45 }
46
47 ret = codec->hw_write(codec->control_data, data, 2);
48 if (ret == 2)
49 return 0;
50 if (ret < 0)
51 return ret;
52 else
53 return -EIO;
54}
55
56#if defined(CONFIG_SPI_MASTER)
57static int snd_soc_4_12_spi_write(void *control_data, const char *data,
58 int len)
59{
60 struct spi_device *spi = control_data;
61 struct spi_transfer t;
62 struct spi_message m;
63 u8 msg[2];
64
65 if (len <= 0)
66 return 0;
67
68 msg[0] = data[1];
69 msg[1] = data[0];
70
71 spi_message_init(&m);
72 memset(&t, 0, (sizeof t));
73
74 t.tx_buf = &msg[0];
75 t.len = len;
76
77 spi_message_add_tail(&t, &m);
78 spi_sync(spi, &m);
79
80 return len;
81}
82#else
83#define snd_soc_4_12_spi_write NULL
84#endif
85
18static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec, 86static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec,
19 unsigned int reg) 87 unsigned int reg)
20{ 88{
@@ -38,6 +106,12 @@ static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg,
38 106
39 if (reg < codec->reg_cache_size) 107 if (reg < codec->reg_cache_size)
40 cache[reg] = value; 108 cache[reg] = value;
109
110 if (codec->cache_only) {
111 codec->cache_sync = 1;
112 return 0;
113 }
114
41 ret = codec->hw_write(codec->control_data, data, 2); 115 ret = codec->hw_write(codec->control_data, data, 2);
42 if (ret == 2) 116 if (ret == 2)
43 return 0; 117 return 0;
@@ -91,6 +165,11 @@ static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg,
91 if (reg < codec->reg_cache_size) 165 if (reg < codec->reg_cache_size)
92 cache[reg] = value; 166 cache[reg] = value;
93 167
168 if (codec->cache_only) {
169 codec->cache_sync = 1;
170 return 0;
171 }
172
94 if (codec->hw_write(codec->control_data, data, 2) == 2) 173 if (codec->hw_write(codec->control_data, data, 2) == 2)
95 return 0; 174 return 0;
96 else 175 else
@@ -119,6 +198,11 @@ static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg,
119 if (!snd_soc_codec_volatile_register(codec, reg)) 198 if (!snd_soc_codec_volatile_register(codec, reg))
120 reg_cache[reg] = value; 199 reg_cache[reg] = value;
121 200
201 if (codec->cache_only) {
202 codec->cache_sync = 1;
203 return 0;
204 }
205
122 if (codec->hw_write(codec->control_data, data, 3) == 3) 206 if (codec->hw_write(codec->control_data, data, 3) == 3)
123 return 0; 207 return 0;
124 else 208 else
@@ -131,10 +215,14 @@ static unsigned int snd_soc_8_16_read(struct snd_soc_codec *codec,
131 u16 *cache = codec->reg_cache; 215 u16 *cache = codec->reg_cache;
132 216
133 if (reg >= codec->reg_cache_size || 217 if (reg >= codec->reg_cache_size ||
134 snd_soc_codec_volatile_register(codec, reg)) 218 snd_soc_codec_volatile_register(codec, reg)) {
219 if (codec->cache_only)
220 return -EINVAL;
221
135 return codec->hw_read(codec, reg); 222 return codec->hw_read(codec, reg);
136 else 223 } else {
137 return cache[reg]; 224 return cache[reg];
225 }
138} 226}
139 227
140#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) 228#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
@@ -171,6 +259,114 @@ static unsigned int snd_soc_8_16_read_i2c(struct snd_soc_codec *codec,
171#define snd_soc_8_16_read_i2c NULL 259#define snd_soc_8_16_read_i2c NULL
172#endif 260#endif
173 261
262#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
263static unsigned int snd_soc_16_8_read_i2c(struct snd_soc_codec *codec,
264 unsigned int r)
265{
266 struct i2c_msg xfer[2];
267 u16 reg = r;
268 u8 data;
269 int ret;
270 struct i2c_client *client = codec->control_data;
271
272 /* Write register */
273 xfer[0].addr = client->addr;
274 xfer[0].flags = 0;
275 xfer[0].len = 2;
276 xfer[0].buf = (u8 *)&reg;
277
278 /* Read data */
279 xfer[1].addr = client->addr;
280 xfer[1].flags = I2C_M_RD;
281 xfer[1].len = 1;
282 xfer[1].buf = &data;
283
284 ret = i2c_transfer(client->adapter, xfer, 2);
285 if (ret != 2) {
286 dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
287 return 0;
288 }
289
290 return data;
291}
292#else
293#define snd_soc_16_8_read_i2c NULL
294#endif
295
296static unsigned int snd_soc_16_8_read(struct snd_soc_codec *codec,
297 unsigned int reg)
298{
299 u16 *cache = codec->reg_cache;
300
301 reg &= 0xff;
302 if (reg >= codec->reg_cache_size)
303 return -1;
304 return cache[reg];
305}
306
307static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg,
308 unsigned int value)
309{
310 u16 *cache = codec->reg_cache;
311 u8 data[3];
312 int ret;
313
314 BUG_ON(codec->volatile_register);
315
316 data[0] = (reg >> 8) & 0xff;
317 data[1] = reg & 0xff;
318 data[2] = value;
319
320 reg &= 0xff;
321 if (reg < codec->reg_cache_size)
322 cache[reg] = value;
323
324 if (codec->cache_only) {
325 codec->cache_sync = 1;
326 return 0;
327 }
328
329 ret = codec->hw_write(codec->control_data, data, 3);
330 if (ret == 3)
331 return 0;
332 if (ret < 0)
333 return ret;
334 else
335 return -EIO;
336}
337
338#if defined(CONFIG_SPI_MASTER)
339static int snd_soc_16_8_spi_write(void *control_data, const char *data,
340 int len)
341{
342 struct spi_device *spi = control_data;
343 struct spi_transfer t;
344 struct spi_message m;
345 u8 msg[3];
346
347 if (len <= 0)
348 return 0;
349
350 msg[0] = data[0];
351 msg[1] = data[1];
352 msg[2] = data[2];
353
354 spi_message_init(&m);
355 memset(&t, 0, (sizeof t));
356
357 t.tx_buf = &msg[0];
358 t.len = len;
359
360 spi_message_add_tail(&t, &m);
361 spi_sync(spi, &m);
362
363 return len;
364}
365#else
366#define snd_soc_16_8_spi_write NULL
367#endif
368
369
174static struct { 370static struct {
175 int addr_bits; 371 int addr_bits;
176 int data_bits; 372 int data_bits;
@@ -180,9 +376,14 @@ static struct {
180 unsigned int (*i2c_read)(struct snd_soc_codec *, unsigned int); 376 unsigned int (*i2c_read)(struct snd_soc_codec *, unsigned int);
181} io_types[] = { 377} io_types[] = {
182 { 378 {
379 .addr_bits = 4, .data_bits = 12,
380 .write = snd_soc_4_12_write, .read = snd_soc_4_12_read,
381 .spi_write = snd_soc_4_12_spi_write,
382 },
383 {
183 .addr_bits = 7, .data_bits = 9, 384 .addr_bits = 7, .data_bits = 9,
184 .write = snd_soc_7_9_write, .read = snd_soc_7_9_read, 385 .write = snd_soc_7_9_write, .read = snd_soc_7_9_read,
185 .spi_write = snd_soc_7_9_spi_write 386 .spi_write = snd_soc_7_9_spi_write,
186 }, 387 },
187 { 388 {
188 .addr_bits = 8, .data_bits = 8, 389 .addr_bits = 8, .data_bits = 8,
@@ -193,6 +394,12 @@ static struct {
193 .write = snd_soc_8_16_write, .read = snd_soc_8_16_read, 394 .write = snd_soc_8_16_write, .read = snd_soc_8_16_read,
194 .i2c_read = snd_soc_8_16_read_i2c, 395 .i2c_read = snd_soc_8_16_read_i2c,
195 }, 396 },
397 {
398 .addr_bits = 16, .data_bits = 8,
399 .write = snd_soc_16_8_write, .read = snd_soc_16_8_read,
400 .i2c_read = snd_soc_16_8_read_i2c,
401 .spi_write = snd_soc_16_8_spi_write,
402 },
196}; 403};
197 404
198/** 405/**
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 0a6440c6f54a..a03bac943aaf 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -130,6 +130,29 @@ static ssize_t codec_reg_show(struct device *dev,
130 130
131static DEVICE_ATTR(codec_reg, 0444, codec_reg_show, NULL); 131static DEVICE_ATTR(codec_reg, 0444, codec_reg_show, NULL);
132 132
133static ssize_t pmdown_time_show(struct device *dev,
134 struct device_attribute *attr, char *buf)
135{
136 struct snd_soc_device *socdev = dev_get_drvdata(dev);
137 struct snd_soc_card *card = socdev->card;
138
139 return sprintf(buf, "%ld\n", card->pmdown_time);
140}
141
142static ssize_t pmdown_time_set(struct device *dev,
143 struct device_attribute *attr,
144 const char *buf, size_t count)
145{
146 struct snd_soc_device *socdev = dev_get_drvdata(dev);
147 struct snd_soc_card *card = socdev->card;
148
149 strict_strtol(buf, 10, &card->pmdown_time);
150
151 return count;
152}
153
154static DEVICE_ATTR(pmdown_time, 0644, pmdown_time_show, pmdown_time_set);
155
133#ifdef CONFIG_DEBUG_FS 156#ifdef CONFIG_DEBUG_FS
134static int codec_reg_open_file(struct inode *inode, struct file *file) 157static int codec_reg_open_file(struct inode *inode, struct file *file)
135{ 158{
@@ -542,7 +565,7 @@ static int soc_codec_close(struct snd_pcm_substream *substream)
542 /* start delayed pop wq here for playback streams */ 565 /* start delayed pop wq here for playback streams */
543 codec_dai->pop_wait = 1; 566 codec_dai->pop_wait = 1;
544 schedule_delayed_work(&card->delayed_work, 567 schedule_delayed_work(&card->delayed_work,
545 msecs_to_jiffies(pmdown_time)); 568 msecs_to_jiffies(card->pmdown_time));
546 } else { 569 } else {
547 /* capture streams can be powered down now */ 570 /* capture streams can be powered down now */
548 snd_soc_dapm_stream_event(codec, 571 snd_soc_dapm_stream_event(codec,
@@ -940,6 +963,12 @@ static int soc_resume(struct device *dev)
940 struct snd_soc_card *card = socdev->card; 963 struct snd_soc_card *card = socdev->card;
941 struct snd_soc_dai *cpu_dai = card->dai_link[0].cpu_dai; 964 struct snd_soc_dai *cpu_dai = card->dai_link[0].cpu_dai;
942 965
966 /* If the initialization of this soc device failed, there is no codec
967 * associated with it. Just bail out in this case.
968 */
969 if (!card->codec)
970 return 0;
971
943 /* AC97 devices might have other drivers hanging off them so 972 /* AC97 devices might have other drivers hanging off them so
944 * need to resume immediately. Other drivers don't have that 973 * need to resume immediately. Other drivers don't have that
945 * problem and may take a substantial amount of time to resume 974 * problem and may take a substantial amount of time to resume
@@ -1039,6 +1068,8 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1039 dev_dbg(card->dev, "All components present, instantiating\n"); 1068 dev_dbg(card->dev, "All components present, instantiating\n");
1040 1069
1041 /* Found everything, bring it up */ 1070 /* Found everything, bring it up */
1071 card->pmdown_time = pmdown_time;
1072
1042 if (card->probe) { 1073 if (card->probe) {
1043 ret = card->probe(pdev); 1074 ret = card->probe(pdev);
1044 if (ret < 0) 1075 if (ret < 0)
@@ -1122,6 +1153,10 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1122 if (ret < 0) 1153 if (ret < 0)
1123 printk(KERN_WARNING "asoc: failed to add dapm sysfs entries\n"); 1154 printk(KERN_WARNING "asoc: failed to add dapm sysfs entries\n");
1124 1155
1156 ret = device_create_file(card->socdev->dev, &dev_attr_pmdown_time);
1157 if (ret < 0)
1158 printk(KERN_WARNING "asoc: failed to add pmdown_time sysfs\n");
1159
1125 ret = device_create_file(card->socdev->dev, &dev_attr_codec_reg); 1160 ret = device_create_file(card->socdev->dev, &dev_attr_codec_reg);
1126 if (ret < 0) 1161 if (ret < 0)
1127 printk(KERN_WARNING "asoc: failed to add codec sysfs files\n"); 1162 printk(KERN_WARNING "asoc: failed to add codec sysfs files\n");
@@ -1276,8 +1311,8 @@ static int soc_new_pcm(struct snd_soc_device *socdev,
1276 codec_dai->codec = card->codec; 1311 codec_dai->codec = card->codec;
1277 1312
1278 /* check client and interface hw capabilities */ 1313 /* check client and interface hw capabilities */
1279 sprintf(new_name, "%s %s-%d", dai_link->stream_name, codec_dai->name, 1314 snprintf(new_name, sizeof(new_name), "%s %s-%d",
1280 num); 1315 dai_link->stream_name, codec_dai->name, num);
1281 1316
1282 if (codec_dai->playback.channels_min) 1317 if (codec_dai->playback.channels_min)
1283 playback = 1; 1318 playback = 1;
@@ -1368,6 +1403,7 @@ int snd_soc_new_ac97_codec(struct snd_soc_codec *codec,
1368 1403
1369 codec->ac97->bus->ops = ops; 1404 codec->ac97->bus->ops = ops;
1370 codec->ac97->num = num; 1405 codec->ac97->num = num;
1406 codec->dev = &codec->ac97->dev;
1371 mutex_unlock(&codec->mutex); 1407 mutex_unlock(&codec->mutex);
1372 return 0; 1408 return 0;
1373} 1409}
@@ -1427,9 +1463,9 @@ EXPORT_SYMBOL_GPL(snd_soc_update_bits);
1427 * 1463 *
1428 * Returns 1 for change else 0. 1464 * Returns 1 for change else 0.
1429 */ 1465 */
1430static int snd_soc_update_bits_locked(struct snd_soc_codec *codec, 1466int snd_soc_update_bits_locked(struct snd_soc_codec *codec,
1431 unsigned short reg, unsigned int mask, 1467 unsigned short reg, unsigned int mask,
1432 unsigned int value) 1468 unsigned int value)
1433{ 1469{
1434 int change; 1470 int change;
1435 1471
@@ -1439,6 +1475,7 @@ static int snd_soc_update_bits_locked(struct snd_soc_codec *codec,
1439 1475
1440 return change; 1476 return change;
1441} 1477}
1478EXPORT_SYMBOL_GPL(snd_soc_update_bits_locked);
1442 1479
1443/** 1480/**
1444 * snd_soc_test_bits - test register for change 1481 * snd_soc_test_bits - test register for change
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 0d294ef72590..6c3351095786 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -44,13 +44,6 @@
44#include <sound/soc-dapm.h> 44#include <sound/soc-dapm.h>
45#include <sound/initval.h> 45#include <sound/initval.h>
46 46
47/* debug */
48#ifdef DEBUG
49#define dump_dapm(codec, action) dbg_dump_dapm(codec, action)
50#else
51#define dump_dapm(codec, action)
52#endif
53
54/* dapm power sequences - make this per codec in the future */ 47/* dapm power sequences - make this per codec in the future */
55static int dapm_up_seq[] = { 48static int dapm_up_seq[] = {
56 [snd_soc_dapm_pre] = 0, 49 [snd_soc_dapm_pre] = 0,
@@ -739,6 +732,8 @@ static int dapm_seq_compare(struct snd_soc_dapm_widget *a,
739 struct snd_soc_dapm_widget *b, 732 struct snd_soc_dapm_widget *b,
740 int sort[]) 733 int sort[])
741{ 734{
735 if (a->codec != b->codec)
736 return (unsigned long)a - (unsigned long)b;
742 if (sort[a->id] != sort[b->id]) 737 if (sort[a->id] != sort[b->id])
743 return sort[a->id] - sort[b->id]; 738 return sort[a->id] - sort[b->id];
744 if (a->reg != b->reg) 739 if (a->reg != b->reg)
@@ -1017,13 +1012,28 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
1017 sys_power = 0; 1012 sys_power = 0;
1018 break; 1013 break;
1019 case SND_SOC_DAPM_STREAM_NOP: 1014 case SND_SOC_DAPM_STREAM_NOP:
1020 sys_power = codec->bias_level != SND_SOC_BIAS_STANDBY; 1015 switch (codec->bias_level) {
1016 case SND_SOC_BIAS_STANDBY:
1017 case SND_SOC_BIAS_OFF:
1018 sys_power = 0;
1019 break;
1020 default:
1021 sys_power = 1;
1022 break;
1023 }
1021 break; 1024 break;
1022 default: 1025 default:
1023 break; 1026 break;
1024 } 1027 }
1025 } 1028 }
1026 1029
1030 if (sys_power && codec->bias_level == SND_SOC_BIAS_OFF) {
1031 ret = snd_soc_dapm_set_bias_level(socdev,
1032 SND_SOC_BIAS_STANDBY);
1033 if (ret != 0)
1034 pr_err("Failed to turn on bias: %d\n", ret);
1035 }
1036
1027 /* If we're changing to all on or all off then prepare */ 1037 /* If we're changing to all on or all off then prepare */
1028 if ((sys_power && codec->bias_level == SND_SOC_BIAS_STANDBY) || 1038 if ((sys_power && codec->bias_level == SND_SOC_BIAS_STANDBY) ||
1029 (!sys_power && codec->bias_level == SND_SOC_BIAS_ON)) { 1039 (!sys_power && codec->bias_level == SND_SOC_BIAS_ON)) {
@@ -1047,6 +1057,14 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
1047 pr_err("Failed to apply standby bias: %d\n", ret); 1057 pr_err("Failed to apply standby bias: %d\n", ret);
1048 } 1058 }
1049 1059
1060 /* If we're in standby and can support bias off then do that */
1061 if (codec->bias_level == SND_SOC_BIAS_STANDBY &&
1062 codec->idle_bias_off) {
1063 ret = snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_OFF);
1064 if (ret != 0)
1065 pr_err("Failed to turn off bias: %d\n", ret);
1066 }
1067
1050 /* If we just powered up then move to active bias */ 1068 /* If we just powered up then move to active bias */
1051 if (codec->bias_level == SND_SOC_BIAS_PREPARE && sys_power) { 1069 if (codec->bias_level == SND_SOC_BIAS_PREPARE && sys_power) {
1052 ret = snd_soc_dapm_set_bias_level(socdev, 1070 ret = snd_soc_dapm_set_bias_level(socdev,
@@ -1061,66 +1079,6 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
1061 return 0; 1079 return 0;
1062} 1080}
1063 1081
1064#ifdef DEBUG
1065static void dbg_dump_dapm(struct snd_soc_codec* codec, const char *action)
1066{
1067 struct snd_soc_dapm_widget *w;
1068 struct snd_soc_dapm_path *p = NULL;
1069 int in, out;
1070
1071 printk("DAPM %s %s\n", codec->name, action);
1072
1073 list_for_each_entry(w, &codec->dapm_widgets, list) {
1074
1075 /* only display widgets that effect routing */
1076 switch (w->id) {
1077 case snd_soc_dapm_pre:
1078 case snd_soc_dapm_post:
1079 case snd_soc_dapm_vmid:
1080 continue;
1081 case snd_soc_dapm_mux:
1082 case snd_soc_dapm_value_mux:
1083 case snd_soc_dapm_output:
1084 case snd_soc_dapm_input:
1085 case snd_soc_dapm_switch:
1086 case snd_soc_dapm_hp:
1087 case snd_soc_dapm_mic:
1088 case snd_soc_dapm_spk:
1089 case snd_soc_dapm_line:
1090 case snd_soc_dapm_micbias:
1091 case snd_soc_dapm_dac:
1092 case snd_soc_dapm_adc:
1093 case snd_soc_dapm_pga:
1094 case snd_soc_dapm_mixer:
1095 case snd_soc_dapm_mixer_named_ctl:
1096 case snd_soc_dapm_supply:
1097 case snd_soc_dapm_aif_in:
1098 case snd_soc_dapm_aif_out:
1099 if (w->name) {
1100 in = is_connected_input_ep(w);
1101 dapm_clear_walk(w->codec);
1102 out = is_connected_output_ep(w);
1103 dapm_clear_walk(w->codec);
1104 printk("%s: %s in %d out %d\n", w->name,
1105 w->power ? "On":"Off",in, out);
1106
1107 list_for_each_entry(p, &w->sources, list_sink) {
1108 if (p->connect)
1109 printk(" in %s %s\n", p->name ? p->name : "static",
1110 p->source->name);
1111 }
1112 list_for_each_entry(p, &w->sinks, list_source) {
1113 if (p->connect)
1114 printk(" out %s %s\n", p->name ? p->name : "static",
1115 p->sink->name);
1116 }
1117 }
1118 break;
1119 }
1120 }
1121}
1122#endif
1123
1124#ifdef CONFIG_DEBUG_FS 1082#ifdef CONFIG_DEBUG_FS
1125static int dapm_widget_power_open_file(struct inode *inode, struct file *file) 1083static int dapm_widget_power_open_file(struct inode *inode, struct file *file)
1126{ 1084{
@@ -1147,9 +1105,16 @@ static ssize_t dapm_widget_power_read_file(struct file *file,
1147 out = is_connected_output_ep(w); 1105 out = is_connected_output_ep(w);
1148 dapm_clear_walk(w->codec); 1106 dapm_clear_walk(w->codec);
1149 1107
1150 ret = snprintf(buf, PAGE_SIZE, "%s: %s in %d out %d\n", 1108 ret = snprintf(buf, PAGE_SIZE, "%s: %s in %d out %d",
1151 w->name, w->power ? "On" : "Off", in, out); 1109 w->name, w->power ? "On" : "Off", in, out);
1152 1110
1111 if (w->reg >= 0)
1112 ret += snprintf(buf + ret, PAGE_SIZE - ret,
1113 " - R%d(0x%x) bit %d",
1114 w->reg, w->reg, w->shift);
1115
1116 ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n");
1117
1153 if (w->sname) 1118 if (w->sname)
1154 ret += snprintf(buf + ret, PAGE_SIZE - ret, " stream %s %s\n", 1119 ret += snprintf(buf + ret, PAGE_SIZE - ret, " stream %s %s\n",
1155 w->sname, 1120 w->sname,
@@ -1245,18 +1210,15 @@ static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
1245 path->connect = 0; /* old connection must be powered down */ 1210 path->connect = 0; /* old connection must be powered down */
1246 } 1211 }
1247 1212
1248 if (found) { 1213 if (found)
1249 dapm_power_widgets(widget->codec, SND_SOC_DAPM_STREAM_NOP); 1214 dapm_power_widgets(widget->codec, SND_SOC_DAPM_STREAM_NOP);
1250 dump_dapm(widget->codec, "mux power update");
1251 }
1252 1215
1253 return 0; 1216 return 0;
1254} 1217}
1255 1218
1256/* test and update the power status of a mixer or switch widget */ 1219/* test and update the power status of a mixer or switch widget */
1257static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget, 1220static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
1258 struct snd_kcontrol *kcontrol, int reg, 1221 struct snd_kcontrol *kcontrol, int connect)
1259 int val_mask, int val, int invert)
1260{ 1222{
1261 struct snd_soc_dapm_path *path; 1223 struct snd_soc_dapm_path *path;
1262 int found = 0; 1224 int found = 0;
@@ -1266,9 +1228,6 @@ static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
1266 widget->id != snd_soc_dapm_switch) 1228 widget->id != snd_soc_dapm_switch)
1267 return -ENODEV; 1229 return -ENODEV;
1268 1230
1269 if (!snd_soc_test_bits(widget->codec, reg, val_mask, val))
1270 return 0;
1271
1272 /* find dapm widget path assoc with kcontrol */ 1231 /* find dapm widget path assoc with kcontrol */
1273 list_for_each_entry(path, &widget->codec->dapm_paths, list) { 1232 list_for_each_entry(path, &widget->codec->dapm_paths, list) {
1274 if (path->kcontrol != kcontrol) 1233 if (path->kcontrol != kcontrol)
@@ -1276,19 +1235,12 @@ static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
1276 1235
1277 /* found, now check type */ 1236 /* found, now check type */
1278 found = 1; 1237 found = 1;
1279 if (val) 1238 path->connect = connect;
1280 /* new connection */
1281 path->connect = invert ? 0:1;
1282 else
1283 /* old connection must be powered down */
1284 path->connect = invert ? 1:0;
1285 break; 1239 break;
1286 } 1240 }
1287 1241
1288 if (found) { 1242 if (found)
1289 dapm_power_widgets(widget->codec, SND_SOC_DAPM_STREAM_NOP); 1243 dapm_power_widgets(widget->codec, SND_SOC_DAPM_STREAM_NOP);
1290 dump_dapm(widget->codec, "mixer power update");
1291 }
1292 1244
1293 return 0; 1245 return 0;
1294} 1246}
@@ -1404,9 +1356,7 @@ static int snd_soc_dapm_set_pin(struct snd_soc_codec *codec,
1404 */ 1356 */
1405int snd_soc_dapm_sync(struct snd_soc_codec *codec) 1357int snd_soc_dapm_sync(struct snd_soc_codec *codec)
1406{ 1358{
1407 int ret = dapm_power_widgets(codec, SND_SOC_DAPM_STREAM_NOP); 1359 return dapm_power_widgets(codec, SND_SOC_DAPM_STREAM_NOP);
1408 dump_dapm(codec, "sync");
1409 return ret;
1410} 1360}
1411EXPORT_SYMBOL_GPL(snd_soc_dapm_sync); 1361EXPORT_SYMBOL_GPL(snd_soc_dapm_sync);
1412 1362
@@ -1688,6 +1638,7 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
1688 unsigned int mask = (1 << fls(max)) - 1; 1638 unsigned int mask = (1 << fls(max)) - 1;
1689 unsigned int invert = mc->invert; 1639 unsigned int invert = mc->invert;
1690 unsigned int val, val2, val_mask; 1640 unsigned int val, val2, val_mask;
1641 int connect;
1691 int ret; 1642 int ret;
1692 1643
1693 val = (ucontrol->value.integer.value[0] & mask); 1644 val = (ucontrol->value.integer.value[0] & mask);
@@ -1714,7 +1665,17 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
1714 return 1; 1665 return 1;
1715 } 1666 }
1716 1667
1717 dapm_mixer_update_power(widget, kcontrol, reg, val_mask, val, invert); 1668 if (snd_soc_test_bits(widget->codec, reg, val_mask, val)) {
1669 if (val)
1670 /* new connection */
1671 connect = invert ? 0:1;
1672 else
1673 /* old connection must be powered down */
1674 connect = invert ? 1:0;
1675
1676 dapm_mixer_update_power(widget, kcontrol, connect);
1677 }
1678
1718 if (widget->event) { 1679 if (widget->event) {
1719 if (widget->event_flags & SND_SOC_DAPM_PRE_REG) { 1680 if (widget->event_flags & SND_SOC_DAPM_PRE_REG) {
1720 ret = widget->event(widget, kcontrol, 1681 ret = widget->event(widget, kcontrol,
@@ -2152,7 +2113,6 @@ int snd_soc_dapm_stream_event(struct snd_soc_codec *codec,
2152 2113
2153 dapm_power_widgets(codec, event); 2114 dapm_power_widgets(codec, event);
2154 mutex_unlock(&codec->mutex); 2115 mutex_unlock(&codec->mutex);
2155 dump_dapm(codec, __func__);
2156 return 0; 2116 return 0;
2157} 2117}
2158EXPORT_SYMBOL_GPL(snd_soc_dapm_stream_event); 2118EXPORT_SYMBOL_GPL(snd_soc_dapm_stream_event);
diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig
index 73525c048e7f..8c2925814ce4 100644
--- a/sound/usb/Kconfig
+++ b/sound/usb/Kconfig
@@ -21,6 +21,18 @@ config SND_USB_AUDIO
21 To compile this driver as a module, choose M here: the module 21 To compile this driver as a module, choose M here: the module
22 will be called snd-usb-audio. 22 will be called snd-usb-audio.
23 23
24config SND_USB_UA101
25 tristate "Edirol UA-101 driver (EXPERIMENTAL)"
26 depends on EXPERIMENTAL
27 select SND_PCM
28 select SND_RAWMIDI
29 help
30 Say Y here to include support for the Edirol UA-101 audio/MIDI
31 interface.
32
33 To compile this driver as a module, choose M here: the module
34 will be called snd-ua101.
35
24config SND_USB_USX2Y 36config SND_USB_USX2Y
25 tristate "Tascam US-122, US-224 and US-428 USB driver" 37 tristate "Tascam US-122, US-224 and US-428 USB driver"
26 depends on X86 || PPC || ALPHA 38 depends on X86 || PPC || ALPHA
diff --git a/sound/usb/Makefile b/sound/usb/Makefile
index abb288bfe35d..5bf64aef9558 100644
--- a/sound/usb/Makefile
+++ b/sound/usb/Makefile
@@ -4,9 +4,11 @@
4 4
5snd-usb-audio-objs := usbaudio.o usbmixer.o 5snd-usb-audio-objs := usbaudio.o usbmixer.o
6snd-usb-lib-objs := usbmidi.o 6snd-usb-lib-objs := usbmidi.o
7snd-ua101-objs := ua101.o
7 8
8# Toplevel Module Dependency 9# Toplevel Module Dependency
9obj-$(CONFIG_SND_USB_AUDIO) += snd-usb-audio.o snd-usb-lib.o 10obj-$(CONFIG_SND_USB_AUDIO) += snd-usb-audio.o snd-usb-lib.o
11obj-$(CONFIG_SND_USB_UA101) += snd-ua101.o snd-usb-lib.o
10obj-$(CONFIG_SND_USB_USX2Y) += snd-usb-lib.o 12obj-$(CONFIG_SND_USB_USX2Y) += snd-usb-lib.o
11obj-$(CONFIG_SND_USB_US122L) += snd-usb-lib.o 13obj-$(CONFIG_SND_USB_US122L) += snd-usb-lib.o
12 14
diff --git a/sound/usb/ua101.c b/sound/usb/ua101.c
new file mode 100644
index 000000000000..4f4ccdf70dd0
--- /dev/null
+++ b/sound/usb/ua101.c
@@ -0,0 +1,1421 @@
1/*
2 * Edirol UA-101 driver
3 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
4 *
5 * This driver is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License, version 2.
7 *
8 * This driver is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this driver. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include <linux/init.h>
18#include <linux/module.h>
19#include <linux/slab.h>
20#include <linux/usb.h>
21#include <linux/usb/audio.h>
22#include <sound/core.h>
23#include <sound/initval.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26#include "usbaudio.h"
27
28MODULE_DESCRIPTION("Edirol UA-101 driver");
29MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
30MODULE_LICENSE("GPL v2");
31MODULE_SUPPORTED_DEVICE("{{Edirol,UA-101}}");
32
33/* I use my UA-1A for testing because I don't have a UA-101 ... */
34#define UA1A_HACK
35
36/*
37 * Should not be lower than the minimum scheduling delay of the host
38 * controller. Some Intel controllers need more than one frame; as long as
39 * that driver doesn't tell us about this, use 1.5 frames just to be sure.
40 */
41#define MIN_QUEUE_LENGTH 12
42/* Somewhat random. */
43#define MAX_QUEUE_LENGTH 30
44/*
45 * This magic value optimizes memory usage efficiency for the UA-101's packet
46 * sizes at all sample rates, taking into account the stupid cache pool sizes
47 * that usb_buffer_alloc() uses.
48 */
49#define DEFAULT_QUEUE_LENGTH 21
50
51#define MAX_PACKET_SIZE 672 /* hardware specific */
52#define MAX_MEMORY_BUFFERS DIV_ROUND_UP(MAX_QUEUE_LENGTH, \
53 PAGE_SIZE / MAX_PACKET_SIZE)
54
55static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
56static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
57static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
58static unsigned int queue_length = 21;
59
60module_param_array(index, int, NULL, 0444);
61MODULE_PARM_DESC(index, "card index");
62module_param_array(id, charp, NULL, 0444);
63MODULE_PARM_DESC(id, "ID string");
64module_param_array(enable, bool, NULL, 0444);
65MODULE_PARM_DESC(enable, "enable card");
66module_param(queue_length, uint, 0644);
67MODULE_PARM_DESC(queue_length, "USB queue length in microframes, "
68 __stringify(MIN_QUEUE_LENGTH)"-"__stringify(MAX_QUEUE_LENGTH));
69
70enum {
71 INTF_PLAYBACK,
72 INTF_CAPTURE,
73 INTF_MIDI,
74
75 INTF_COUNT
76};
77
78/* bits in struct ua101::states */
79enum {
80 USB_CAPTURE_RUNNING,
81 USB_PLAYBACK_RUNNING,
82 ALSA_CAPTURE_OPEN,
83 ALSA_PLAYBACK_OPEN,
84 ALSA_CAPTURE_RUNNING,
85 ALSA_PLAYBACK_RUNNING,
86 CAPTURE_URB_COMPLETED,
87 PLAYBACK_URB_COMPLETED,
88 DISCONNECTED,
89};
90
91struct ua101 {
92 struct usb_device *dev;
93 struct snd_card *card;
94 struct usb_interface *intf[INTF_COUNT];
95 int card_index;
96 struct snd_pcm *pcm;
97 struct list_head midi_list;
98 u64 format_bit;
99 unsigned int rate;
100 unsigned int packets_per_second;
101 spinlock_t lock;
102 struct mutex mutex;
103 unsigned long states;
104
105 /* FIFO to synchronize playback rate to capture rate */
106 unsigned int rate_feedback_start;
107 unsigned int rate_feedback_count;
108 u8 rate_feedback[MAX_QUEUE_LENGTH];
109
110 struct list_head ready_playback_urbs;
111 struct tasklet_struct playback_tasklet;
112 wait_queue_head_t alsa_capture_wait;
113 wait_queue_head_t rate_feedback_wait;
114 wait_queue_head_t alsa_playback_wait;
115 struct ua101_stream {
116 struct snd_pcm_substream *substream;
117 unsigned int usb_pipe;
118 unsigned int channels;
119 unsigned int frame_bytes;
120 unsigned int max_packet_bytes;
121 unsigned int period_pos;
122 unsigned int buffer_pos;
123 unsigned int queue_length;
124 struct ua101_urb {
125 struct urb urb;
126 struct usb_iso_packet_descriptor iso_frame_desc[1];
127 struct list_head ready_list;
128 } *urbs[MAX_QUEUE_LENGTH];
129 struct {
130 unsigned int size;
131 void *addr;
132 dma_addr_t dma;
133 } buffers[MAX_MEMORY_BUFFERS];
134 } capture, playback;
135
136 unsigned int fps[10];
137 unsigned int frame_counter;
138};
139
140static DEFINE_MUTEX(devices_mutex);
141static unsigned int devices_used;
142static struct usb_driver ua101_driver;
143
144static void abort_alsa_playback(struct ua101 *ua);
145static void abort_alsa_capture(struct ua101 *ua);
146
147static const char *usb_error_string(int err)
148{
149 switch (err) {
150 case -ENODEV:
151 return "no device";
152 case -ENOENT:
153 return "endpoint not enabled";
154 case -EPIPE:
155 return "endpoint stalled";
156 case -ENOSPC:
157 return "not enough bandwidth";
158 case -ESHUTDOWN:
159 return "device disabled";
160 case -EHOSTUNREACH:
161 return "device suspended";
162 case -EINVAL:
163 case -EAGAIN:
164 case -EFBIG:
165 case -EMSGSIZE:
166 return "internal error";
167 default:
168 return "unknown error";
169 }
170}
171
172static void abort_usb_capture(struct ua101 *ua)
173{
174 if (test_and_clear_bit(USB_CAPTURE_RUNNING, &ua->states)) {
175 wake_up(&ua->alsa_capture_wait);
176 wake_up(&ua->rate_feedback_wait);
177 }
178}
179
180static void abort_usb_playback(struct ua101 *ua)
181{
182 if (test_and_clear_bit(USB_PLAYBACK_RUNNING, &ua->states))
183 wake_up(&ua->alsa_playback_wait);
184}
185
186static void playback_urb_complete(struct urb *usb_urb)
187{
188 struct ua101_urb *urb = (struct ua101_urb *)usb_urb;
189 struct ua101 *ua = urb->urb.context;
190 unsigned long flags;
191
192 if (unlikely(urb->urb.status == -ENOENT || /* unlinked */
193 urb->urb.status == -ENODEV || /* device removed */
194 urb->urb.status == -ECONNRESET || /* unlinked */
195 urb->urb.status == -ESHUTDOWN)) { /* device disabled */
196 abort_usb_playback(ua);
197 abort_alsa_playback(ua);
198 return;
199 }
200
201 if (test_bit(USB_PLAYBACK_RUNNING, &ua->states)) {
202 /* append URB to FIFO */
203 spin_lock_irqsave(&ua->lock, flags);
204 list_add_tail(&urb->ready_list, &ua->ready_playback_urbs);
205 if (ua->rate_feedback_count > 0)
206 tasklet_schedule(&ua->playback_tasklet);
207 ua->playback.substream->runtime->delay -=
208 urb->urb.iso_frame_desc[0].length /
209 ua->playback.frame_bytes;
210 spin_unlock_irqrestore(&ua->lock, flags);
211 }
212}
213
214static void first_playback_urb_complete(struct urb *urb)
215{
216 struct ua101 *ua = urb->context;
217
218 urb->complete = playback_urb_complete;
219 playback_urb_complete(urb);
220
221 set_bit(PLAYBACK_URB_COMPLETED, &ua->states);
222 wake_up(&ua->alsa_playback_wait);
223}
224
225/* copy data from the ALSA ring buffer into the URB buffer */
226static bool copy_playback_data(struct ua101_stream *stream, struct urb *urb,
227 unsigned int frames)
228{
229 struct snd_pcm_runtime *runtime;
230 unsigned int frame_bytes, frames1;
231 const u8 *source;
232
233 runtime = stream->substream->runtime;
234 frame_bytes = stream->frame_bytes;
235 source = runtime->dma_area + stream->buffer_pos * frame_bytes;
236 if (stream->buffer_pos + frames <= runtime->buffer_size) {
237 memcpy(urb->transfer_buffer, source, frames * frame_bytes);
238 } else {
239 /* wrap around at end of ring buffer */
240 frames1 = runtime->buffer_size - stream->buffer_pos;
241 memcpy(urb->transfer_buffer, source, frames1 * frame_bytes);
242 memcpy(urb->transfer_buffer + frames1 * frame_bytes,
243 runtime->dma_area, (frames - frames1) * frame_bytes);
244 }
245
246 stream->buffer_pos += frames;
247 if (stream->buffer_pos >= runtime->buffer_size)
248 stream->buffer_pos -= runtime->buffer_size;
249 stream->period_pos += frames;
250 if (stream->period_pos >= runtime->period_size) {
251 stream->period_pos -= runtime->period_size;
252 return true;
253 }
254 return false;
255}
256
257static inline void add_with_wraparound(struct ua101 *ua,
258 unsigned int *value, unsigned int add)
259{
260 *value += add;
261 if (*value >= ua->playback.queue_length)
262 *value -= ua->playback.queue_length;
263}
264
265static void playback_tasklet(unsigned long data)
266{
267 struct ua101 *ua = (void *)data;
268 unsigned long flags;
269 unsigned int frames;
270 struct ua101_urb *urb;
271 bool do_period_elapsed = false;
272 int err;
273
274 if (unlikely(!test_bit(USB_PLAYBACK_RUNNING, &ua->states)))
275 return;
276
277 /*
278 * Synchronizing the playback rate to the capture rate is done by using
279 * the same sequence of packet sizes for both streams.
280 * Submitting a playback URB therefore requires both a ready URB and
281 * the size of the corresponding capture packet, i.e., both playback
282 * and capture URBs must have been completed. Since the USB core does
283 * not guarantee that playback and capture complete callbacks are
284 * called alternately, we use two FIFOs for packet sizes and read URBs;
285 * submitting playback URBs is possible as long as both FIFOs are
286 * nonempty.
287 */
288 spin_lock_irqsave(&ua->lock, flags);
289 while (ua->rate_feedback_count > 0 &&
290 !list_empty(&ua->ready_playback_urbs)) {
291 /* take packet size out of FIFO */
292 frames = ua->rate_feedback[ua->rate_feedback_start];
293 add_with_wraparound(ua, &ua->rate_feedback_start, 1);
294 ua->rate_feedback_count--;
295
296 /* take URB out of FIFO */
297 urb = list_first_entry(&ua->ready_playback_urbs,
298 struct ua101_urb, ready_list);
299 list_del(&urb->ready_list);
300
301 /* fill packet with data or silence */
302 urb->urb.iso_frame_desc[0].length =
303 frames * ua->playback.frame_bytes;
304 if (test_bit(ALSA_PLAYBACK_RUNNING, &ua->states))
305 do_period_elapsed |= copy_playback_data(&ua->playback,
306 &urb->urb,
307 frames);
308 else
309 memset(urb->urb.transfer_buffer, 0,
310 urb->urb.iso_frame_desc[0].length);
311
312 /* and off you go ... */
313 err = usb_submit_urb(&urb->urb, GFP_ATOMIC);
314 if (unlikely(err < 0)) {
315 spin_unlock_irqrestore(&ua->lock, flags);
316 abort_usb_playback(ua);
317 abort_alsa_playback(ua);
318 dev_err(&ua->dev->dev, "USB request error %d: %s\n",
319 err, usb_error_string(err));
320 return;
321 }
322 ua->playback.substream->runtime->delay += frames;
323 }
324 spin_unlock_irqrestore(&ua->lock, flags);
325 if (do_period_elapsed)
326 snd_pcm_period_elapsed(ua->playback.substream);
327}
328
329/* copy data from the URB buffer into the ALSA ring buffer */
330static bool copy_capture_data(struct ua101_stream *stream, struct urb *urb,
331 unsigned int frames)
332{
333 struct snd_pcm_runtime *runtime;
334 unsigned int frame_bytes, frames1;
335 u8 *dest;
336
337 runtime = stream->substream->runtime;
338 frame_bytes = stream->frame_bytes;
339 dest = runtime->dma_area + stream->buffer_pos * frame_bytes;
340 if (stream->buffer_pos + frames <= runtime->buffer_size) {
341 memcpy(dest, urb->transfer_buffer, frames * frame_bytes);
342 } else {
343 /* wrap around at end of ring buffer */
344 frames1 = runtime->buffer_size - stream->buffer_pos;
345 memcpy(dest, urb->transfer_buffer, frames1 * frame_bytes);
346 memcpy(runtime->dma_area,
347 urb->transfer_buffer + frames1 * frame_bytes,
348 (frames - frames1) * frame_bytes);
349 }
350
351 stream->buffer_pos += frames;
352 if (stream->buffer_pos >= runtime->buffer_size)
353 stream->buffer_pos -= runtime->buffer_size;
354 stream->period_pos += frames;
355 if (stream->period_pos >= runtime->period_size) {
356 stream->period_pos -= runtime->period_size;
357 return true;
358 }
359 return false;
360}
361
362static void capture_urb_complete(struct urb *urb)
363{
364 struct ua101 *ua = urb->context;
365 struct ua101_stream *stream = &ua->capture;
366 unsigned long flags;
367 unsigned int frames, write_ptr;
368 bool do_period_elapsed;
369 int err;
370
371 if (unlikely(urb->status == -ENOENT || /* unlinked */
372 urb->status == -ENODEV || /* device removed */
373 urb->status == -ECONNRESET || /* unlinked */
374 urb->status == -ESHUTDOWN)) /* device disabled */
375 goto stream_stopped;
376
377 if (urb->status >= 0 && urb->iso_frame_desc[0].status >= 0)
378 frames = urb->iso_frame_desc[0].actual_length /
379 stream->frame_bytes;
380 else
381 frames = 0;
382
383 spin_lock_irqsave(&ua->lock, flags);
384
385 if (frames > 0 && test_bit(ALSA_CAPTURE_RUNNING, &ua->states))
386 do_period_elapsed = copy_capture_data(stream, urb, frames);
387 else
388 do_period_elapsed = false;
389
390 if (test_bit(USB_CAPTURE_RUNNING, &ua->states)) {
391 err = usb_submit_urb(urb, GFP_ATOMIC);
392 if (unlikely(err < 0)) {
393 spin_unlock_irqrestore(&ua->lock, flags);
394 dev_err(&ua->dev->dev, "USB request error %d: %s\n",
395 err, usb_error_string(err));
396 goto stream_stopped;
397 }
398
399 /* append packet size to FIFO */
400 write_ptr = ua->rate_feedback_start;
401 add_with_wraparound(ua, &write_ptr, ua->rate_feedback_count);
402 ua->rate_feedback[write_ptr] = frames;
403 if (ua->rate_feedback_count < ua->playback.queue_length) {
404 ua->rate_feedback_count++;
405 if (ua->rate_feedback_count ==
406 ua->playback.queue_length)
407 wake_up(&ua->rate_feedback_wait);
408 } else {
409 /*
410 * Ring buffer overflow; this happens when the playback
411 * stream is not running. Throw away the oldest entry,
412 * so that the playback stream, when it starts, sees
413 * the most recent packet sizes.
414 */
415 add_with_wraparound(ua, &ua->rate_feedback_start, 1);
416 }
417 if (test_bit(USB_PLAYBACK_RUNNING, &ua->states) &&
418 !list_empty(&ua->ready_playback_urbs))
419 tasklet_schedule(&ua->playback_tasklet);
420 }
421
422 spin_unlock_irqrestore(&ua->lock, flags);
423
424 if (do_period_elapsed)
425 snd_pcm_period_elapsed(stream->substream);
426
427 /* for debugging: measure the sample rate relative to the USB clock */
428 ua->fps[ua->frame_counter++ / ua->packets_per_second] += frames;
429 if (ua->frame_counter >= ARRAY_SIZE(ua->fps) * ua->packets_per_second) {
430 printk(KERN_DEBUG "capture rate:");
431 for (frames = 0; frames < ARRAY_SIZE(ua->fps); ++frames)
432 printk(KERN_CONT " %u", ua->fps[frames]);
433 printk(KERN_CONT "\n");
434 memset(ua->fps, 0, sizeof(ua->fps));
435 ua->frame_counter = 0;
436 }
437 return;
438
439stream_stopped:
440 abort_usb_playback(ua);
441 abort_usb_capture(ua);
442 abort_alsa_playback(ua);
443 abort_alsa_capture(ua);
444}
445
446static void first_capture_urb_complete(struct urb *urb)
447{
448 struct ua101 *ua = urb->context;
449
450 urb->complete = capture_urb_complete;
451 capture_urb_complete(urb);
452
453 set_bit(CAPTURE_URB_COMPLETED, &ua->states);
454 wake_up(&ua->alsa_capture_wait);
455}
456
457static int submit_stream_urbs(struct ua101 *ua, struct ua101_stream *stream)
458{
459 unsigned int i;
460
461 for (i = 0; i < stream->queue_length; ++i) {
462 int err = usb_submit_urb(&stream->urbs[i]->urb, GFP_KERNEL);
463 if (err < 0) {
464 dev_err(&ua->dev->dev, "USB request error %d: %s\n",
465 err, usb_error_string(err));
466 return err;
467 }
468 }
469 return 0;
470}
471
472static void kill_stream_urbs(struct ua101_stream *stream)
473{
474 unsigned int i;
475
476 for (i = 0; i < stream->queue_length; ++i)
477 usb_kill_urb(&stream->urbs[i]->urb);
478}
479
480static int enable_iso_interface(struct ua101 *ua, unsigned int intf_index)
481{
482 struct usb_host_interface *alts;
483
484 alts = ua->intf[intf_index]->cur_altsetting;
485 if (alts->desc.bAlternateSetting != 1) {
486 int err = usb_set_interface(ua->dev,
487 alts->desc.bInterfaceNumber, 1);
488 if (err < 0) {
489 dev_err(&ua->dev->dev,
490 "cannot initialize interface; error %d: %s\n",
491 err, usb_error_string(err));
492 return err;
493 }
494 }
495 return 0;
496}
497
498static void disable_iso_interface(struct ua101 *ua, unsigned int intf_index)
499{
500 struct usb_host_interface *alts;
501
502 alts = ua->intf[intf_index]->cur_altsetting;
503 if (alts->desc.bAlternateSetting != 0) {
504 int err = usb_set_interface(ua->dev,
505 alts->desc.bInterfaceNumber, 0);
506 if (err < 0 && !test_bit(DISCONNECTED, &ua->states))
507 dev_warn(&ua->dev->dev,
508 "interface reset failed; error %d: %s\n",
509 err, usb_error_string(err));
510 }
511}
512
513static void stop_usb_capture(struct ua101 *ua)
514{
515 clear_bit(USB_CAPTURE_RUNNING, &ua->states);
516
517 kill_stream_urbs(&ua->capture);
518
519 disable_iso_interface(ua, INTF_CAPTURE);
520}
521
522static int start_usb_capture(struct ua101 *ua)
523{
524 int err;
525
526 if (test_bit(DISCONNECTED, &ua->states))
527 return -ENODEV;
528
529 if (test_bit(USB_CAPTURE_RUNNING, &ua->states))
530 return 0;
531
532 kill_stream_urbs(&ua->capture);
533
534 err = enable_iso_interface(ua, INTF_CAPTURE);
535 if (err < 0)
536 return err;
537
538 clear_bit(CAPTURE_URB_COMPLETED, &ua->states);
539 ua->capture.urbs[0]->urb.complete = first_capture_urb_complete;
540 ua->rate_feedback_start = 0;
541 ua->rate_feedback_count = 0;
542
543 set_bit(USB_CAPTURE_RUNNING, &ua->states);
544 err = submit_stream_urbs(ua, &ua->capture);
545 if (err < 0)
546 stop_usb_capture(ua);
547 return err;
548}
549
550static void stop_usb_playback(struct ua101 *ua)
551{
552 clear_bit(USB_PLAYBACK_RUNNING, &ua->states);
553
554 kill_stream_urbs(&ua->playback);
555
556 tasklet_kill(&ua->playback_tasklet);
557
558 disable_iso_interface(ua, INTF_PLAYBACK);
559}
560
561static int start_usb_playback(struct ua101 *ua)
562{
563 unsigned int i, frames;
564 struct urb *urb;
565 int err = 0;
566
567 if (test_bit(DISCONNECTED, &ua->states))
568 return -ENODEV;
569
570 if (test_bit(USB_PLAYBACK_RUNNING, &ua->states))
571 return 0;
572
573 kill_stream_urbs(&ua->playback);
574 tasklet_kill(&ua->playback_tasklet);
575
576 err = enable_iso_interface(ua, INTF_PLAYBACK);
577 if (err < 0)
578 return err;
579
580 clear_bit(PLAYBACK_URB_COMPLETED, &ua->states);
581 ua->playback.urbs[0]->urb.complete =
582 first_playback_urb_complete;
583 spin_lock_irq(&ua->lock);
584 INIT_LIST_HEAD(&ua->ready_playback_urbs);
585 spin_unlock_irq(&ua->lock);
586
587 /*
588 * We submit the initial URBs all at once, so we have to wait for the
589 * packet size FIFO to be full.
590 */
591 wait_event(ua->rate_feedback_wait,
592 ua->rate_feedback_count >= ua->playback.queue_length ||
593 !test_bit(USB_CAPTURE_RUNNING, &ua->states) ||
594 test_bit(DISCONNECTED, &ua->states));
595 if (test_bit(DISCONNECTED, &ua->states)) {
596 stop_usb_playback(ua);
597 return -ENODEV;
598 }
599 if (!test_bit(USB_CAPTURE_RUNNING, &ua->states)) {
600 stop_usb_playback(ua);
601 return -EIO;
602 }
603
604 for (i = 0; i < ua->playback.queue_length; ++i) {
605 /* all initial URBs contain silence */
606 spin_lock_irq(&ua->lock);
607 frames = ua->rate_feedback[ua->rate_feedback_start];
608 add_with_wraparound(ua, &ua->rate_feedback_start, 1);
609 ua->rate_feedback_count--;
610 spin_unlock_irq(&ua->lock);
611 urb = &ua->playback.urbs[i]->urb;
612 urb->iso_frame_desc[0].length =
613 frames * ua->playback.frame_bytes;
614 memset(urb->transfer_buffer, 0,
615 urb->iso_frame_desc[0].length);
616 }
617
618 set_bit(USB_PLAYBACK_RUNNING, &ua->states);
619 err = submit_stream_urbs(ua, &ua->playback);
620 if (err < 0)
621 stop_usb_playback(ua);
622 return err;
623}
624
625static void abort_alsa_capture(struct ua101 *ua)
626{
627 if (test_bit(ALSA_CAPTURE_RUNNING, &ua->states))
628 snd_pcm_stop(ua->capture.substream, SNDRV_PCM_STATE_XRUN);
629}
630
631static void abort_alsa_playback(struct ua101 *ua)
632{
633 if (test_bit(ALSA_PLAYBACK_RUNNING, &ua->states))
634 snd_pcm_stop(ua->playback.substream, SNDRV_PCM_STATE_XRUN);
635}
636
637static int set_stream_hw(struct ua101 *ua, struct snd_pcm_substream *substream,
638 unsigned int channels)
639{
640 int err;
641
642 substream->runtime->hw.info =
643 SNDRV_PCM_INFO_MMAP |
644 SNDRV_PCM_INFO_MMAP_VALID |
645 SNDRV_PCM_INFO_BATCH |
646 SNDRV_PCM_INFO_INTERLEAVED |
647 SNDRV_PCM_INFO_BLOCK_TRANSFER |
648 SNDRV_PCM_INFO_FIFO_IN_FRAMES;
649 substream->runtime->hw.formats = ua->format_bit;
650 substream->runtime->hw.rates = snd_pcm_rate_to_rate_bit(ua->rate);
651 substream->runtime->hw.rate_min = ua->rate;
652 substream->runtime->hw.rate_max = ua->rate;
653 substream->runtime->hw.channels_min = channels;
654 substream->runtime->hw.channels_max = channels;
655 substream->runtime->hw.buffer_bytes_max = 45000 * 1024;
656 substream->runtime->hw.period_bytes_min = 1;
657 substream->runtime->hw.period_bytes_max = UINT_MAX;
658 substream->runtime->hw.periods_min = 2;
659 substream->runtime->hw.periods_max = UINT_MAX;
660 err = snd_pcm_hw_constraint_minmax(substream->runtime,
661 SNDRV_PCM_HW_PARAM_PERIOD_TIME,
662 1500000 / ua->packets_per_second,
663 8192000);
664 if (err < 0)
665 return err;
666 err = snd_pcm_hw_constraint_msbits(substream->runtime, 0, 32, 24);
667 return err;
668}
669
670static int capture_pcm_open(struct snd_pcm_substream *substream)
671{
672 struct ua101 *ua = substream->private_data;
673 int err;
674
675 ua->capture.substream = substream;
676 err = set_stream_hw(ua, substream, ua->capture.channels);
677 if (err < 0)
678 return err;
679 substream->runtime->hw.fifo_size =
680 DIV_ROUND_CLOSEST(ua->rate, ua->packets_per_second);
681 substream->runtime->delay = substream->runtime->hw.fifo_size;
682
683 mutex_lock(&ua->mutex);
684 err = start_usb_capture(ua);
685 if (err >= 0)
686 set_bit(ALSA_CAPTURE_OPEN, &ua->states);
687 mutex_unlock(&ua->mutex);
688 return err;
689}
690
691static int playback_pcm_open(struct snd_pcm_substream *substream)
692{
693 struct ua101 *ua = substream->private_data;
694 int err;
695
696 ua->playback.substream = substream;
697 err = set_stream_hw(ua, substream, ua->playback.channels);
698 if (err < 0)
699 return err;
700 substream->runtime->hw.fifo_size =
701 DIV_ROUND_CLOSEST(ua->rate * ua->playback.queue_length,
702 ua->packets_per_second);
703
704 mutex_lock(&ua->mutex);
705 err = start_usb_capture(ua);
706 if (err < 0)
707 goto error;
708 err = start_usb_playback(ua);
709 if (err < 0) {
710 if (!test_bit(ALSA_CAPTURE_OPEN, &ua->states))
711 stop_usb_capture(ua);
712 goto error;
713 }
714 set_bit(ALSA_PLAYBACK_OPEN, &ua->states);
715error:
716 mutex_unlock(&ua->mutex);
717 return err;
718}
719
720static int capture_pcm_close(struct snd_pcm_substream *substream)
721{
722 struct ua101 *ua = substream->private_data;
723
724 mutex_lock(&ua->mutex);
725 clear_bit(ALSA_CAPTURE_OPEN, &ua->states);
726 if (!test_bit(ALSA_PLAYBACK_OPEN, &ua->states))
727 stop_usb_capture(ua);
728 mutex_unlock(&ua->mutex);
729 return 0;
730}
731
732static int playback_pcm_close(struct snd_pcm_substream *substream)
733{
734 struct ua101 *ua = substream->private_data;
735
736 mutex_lock(&ua->mutex);
737 stop_usb_playback(ua);
738 clear_bit(ALSA_PLAYBACK_OPEN, &ua->states);
739 if (!test_bit(ALSA_CAPTURE_OPEN, &ua->states))
740 stop_usb_capture(ua);
741 mutex_unlock(&ua->mutex);
742 return 0;
743}
744
745static int capture_pcm_hw_params(struct snd_pcm_substream *substream,
746 struct snd_pcm_hw_params *hw_params)
747{
748 struct ua101 *ua = substream->private_data;
749 int err;
750
751 mutex_lock(&ua->mutex);
752 err = start_usb_capture(ua);
753 mutex_unlock(&ua->mutex);
754 if (err < 0)
755 return err;
756
757 return snd_pcm_lib_alloc_vmalloc_buffer(substream,
758 params_buffer_bytes(hw_params));
759}
760
761static int playback_pcm_hw_params(struct snd_pcm_substream *substream,
762 struct snd_pcm_hw_params *hw_params)
763{
764 struct ua101 *ua = substream->private_data;
765 int err;
766
767 mutex_lock(&ua->mutex);
768 err = start_usb_capture(ua);
769 if (err >= 0)
770 err = start_usb_playback(ua);
771 mutex_unlock(&ua->mutex);
772 if (err < 0)
773 return err;
774
775 return snd_pcm_lib_alloc_vmalloc_buffer(substream,
776 params_buffer_bytes(hw_params));
777}
778
779static int ua101_pcm_hw_free(struct snd_pcm_substream *substream)
780{
781 return snd_pcm_lib_free_vmalloc_buffer(substream);
782}
783
784static int capture_pcm_prepare(struct snd_pcm_substream *substream)
785{
786 struct ua101 *ua = substream->private_data;
787 int err;
788
789 mutex_lock(&ua->mutex);
790 err = start_usb_capture(ua);
791 mutex_unlock(&ua->mutex);
792 if (err < 0)
793 return err;
794
795 /*
796 * The EHCI driver schedules the first packet of an iso stream at 10 ms
797 * in the future, i.e., no data is actually captured for that long.
798 * Take the wait here so that the stream is known to be actually
799 * running when the start trigger has been called.
800 */
801 wait_event(ua->alsa_capture_wait,
802 test_bit(CAPTURE_URB_COMPLETED, &ua->states) ||
803 !test_bit(USB_CAPTURE_RUNNING, &ua->states));
804 if (test_bit(DISCONNECTED, &ua->states))
805 return -ENODEV;
806 if (!test_bit(USB_CAPTURE_RUNNING, &ua->states))
807 return -EIO;
808
809 ua->capture.period_pos = 0;
810 ua->capture.buffer_pos = 0;
811 return 0;
812}
813
814static int playback_pcm_prepare(struct snd_pcm_substream *substream)
815{
816 struct ua101 *ua = substream->private_data;
817 int err;
818
819 mutex_lock(&ua->mutex);
820 err = start_usb_capture(ua);
821 if (err >= 0)
822 err = start_usb_playback(ua);
823 mutex_unlock(&ua->mutex);
824 if (err < 0)
825 return err;
826
827 /* see the comment in capture_pcm_prepare() */
828 wait_event(ua->alsa_playback_wait,
829 test_bit(PLAYBACK_URB_COMPLETED, &ua->states) ||
830 !test_bit(USB_PLAYBACK_RUNNING, &ua->states));
831 if (test_bit(DISCONNECTED, &ua->states))
832 return -ENODEV;
833 if (!test_bit(USB_PLAYBACK_RUNNING, &ua->states))
834 return -EIO;
835
836 substream->runtime->delay = 0;
837 ua->playback.period_pos = 0;
838 ua->playback.buffer_pos = 0;
839 return 0;
840}
841
842static int capture_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
843{
844 struct ua101 *ua = substream->private_data;
845
846 switch (cmd) {
847 case SNDRV_PCM_TRIGGER_START:
848 if (!test_bit(USB_CAPTURE_RUNNING, &ua->states))
849 return -EIO;
850 set_bit(ALSA_CAPTURE_RUNNING, &ua->states);
851 return 0;
852 case SNDRV_PCM_TRIGGER_STOP:
853 clear_bit(ALSA_CAPTURE_RUNNING, &ua->states);
854 return 0;
855 default:
856 return -EINVAL;
857 }
858}
859
860static int playback_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
861{
862 struct ua101 *ua = substream->private_data;
863
864 switch (cmd) {
865 case SNDRV_PCM_TRIGGER_START:
866 if (!test_bit(USB_PLAYBACK_RUNNING, &ua->states))
867 return -EIO;
868 set_bit(ALSA_PLAYBACK_RUNNING, &ua->states);
869 return 0;
870 case SNDRV_PCM_TRIGGER_STOP:
871 clear_bit(ALSA_PLAYBACK_RUNNING, &ua->states);
872 return 0;
873 default:
874 return -EINVAL;
875 }
876}
877
878static inline snd_pcm_uframes_t ua101_pcm_pointer(struct ua101 *ua,
879 struct ua101_stream *stream)
880{
881 unsigned long flags;
882 unsigned int pos;
883
884 spin_lock_irqsave(&ua->lock, flags);
885 pos = stream->buffer_pos;
886 spin_unlock_irqrestore(&ua->lock, flags);
887 return pos;
888}
889
890static snd_pcm_uframes_t capture_pcm_pointer(struct snd_pcm_substream *subs)
891{
892 struct ua101 *ua = subs->private_data;
893
894 return ua101_pcm_pointer(ua, &ua->capture);
895}
896
897static snd_pcm_uframes_t playback_pcm_pointer(struct snd_pcm_substream *subs)
898{
899 struct ua101 *ua = subs->private_data;
900
901 return ua101_pcm_pointer(ua, &ua->playback);
902}
903
904static struct snd_pcm_ops capture_pcm_ops = {
905 .open = capture_pcm_open,
906 .close = capture_pcm_close,
907 .ioctl = snd_pcm_lib_ioctl,
908 .hw_params = capture_pcm_hw_params,
909 .hw_free = ua101_pcm_hw_free,
910 .prepare = capture_pcm_prepare,
911 .trigger = capture_pcm_trigger,
912 .pointer = capture_pcm_pointer,
913 .page = snd_pcm_lib_get_vmalloc_page,
914 .mmap = snd_pcm_lib_mmap_vmalloc,
915};
916
917static struct snd_pcm_ops playback_pcm_ops = {
918 .open = playback_pcm_open,
919 .close = playback_pcm_close,
920 .ioctl = snd_pcm_lib_ioctl,
921 .hw_params = playback_pcm_hw_params,
922 .hw_free = ua101_pcm_hw_free,
923 .prepare = playback_pcm_prepare,
924 .trigger = playback_pcm_trigger,
925 .pointer = playback_pcm_pointer,
926 .page = snd_pcm_lib_get_vmalloc_page,
927 .mmap = snd_pcm_lib_mmap_vmalloc,
928};
929
930static const struct uac_format_type_i_discrete_descriptor *
931find_format_descriptor(struct usb_interface *interface)
932{
933 struct usb_host_interface *alt;
934 u8 *extra;
935 int extralen;
936
937 if (interface->num_altsetting != 2) {
938 dev_err(&interface->dev, "invalid num_altsetting\n");
939 return NULL;
940 }
941
942 alt = &interface->altsetting[0];
943 if (alt->desc.bNumEndpoints != 0) {
944 dev_err(&interface->dev, "invalid bNumEndpoints\n");
945 return NULL;
946 }
947
948 alt = &interface->altsetting[1];
949 if (alt->desc.bNumEndpoints != 1) {
950 dev_err(&interface->dev, "invalid bNumEndpoints\n");
951 return NULL;
952 }
953
954 extra = alt->extra;
955 extralen = alt->extralen;
956 while (extralen >= sizeof(struct usb_descriptor_header)) {
957 struct uac_format_type_i_discrete_descriptor *desc;
958
959 desc = (struct uac_format_type_i_discrete_descriptor *)extra;
960 if (desc->bLength > extralen) {
961 dev_err(&interface->dev, "descriptor overflow\n");
962 return NULL;
963 }
964 if (desc->bLength == UAC_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(1) &&
965 desc->bDescriptorType == USB_DT_CS_INTERFACE &&
966 desc->bDescriptorSubtype == UAC_FORMAT_TYPE) {
967 if (desc->bFormatType != UAC_FORMAT_TYPE_I_PCM ||
968 desc->bSamFreqType != 1) {
969 dev_err(&interface->dev,
970 "invalid format type\n");
971 return NULL;
972 }
973 return desc;
974 }
975 extralen -= desc->bLength;
976 extra += desc->bLength;
977 }
978 dev_err(&interface->dev, "sample format descriptor not found\n");
979 return NULL;
980}
981
982static int detect_usb_format(struct ua101 *ua)
983{
984 const struct uac_format_type_i_discrete_descriptor *fmt_capture;
985 const struct uac_format_type_i_discrete_descriptor *fmt_playback;
986 const struct usb_endpoint_descriptor *epd;
987 unsigned int rate2;
988
989 fmt_capture = find_format_descriptor(ua->intf[INTF_CAPTURE]);
990 fmt_playback = find_format_descriptor(ua->intf[INTF_PLAYBACK]);
991 if (!fmt_capture || !fmt_playback)
992 return -ENXIO;
993
994 switch (fmt_capture->bSubframeSize) {
995 case 3:
996 ua->format_bit = SNDRV_PCM_FMTBIT_S24_3LE;
997 break;
998 case 4:
999 ua->format_bit = SNDRV_PCM_FMTBIT_S32_LE;
1000 break;
1001 default:
1002 dev_err(&ua->dev->dev, "sample width is not 24 or 32 bits\n");
1003 return -ENXIO;
1004 }
1005 if (fmt_capture->bSubframeSize != fmt_playback->bSubframeSize) {
1006 dev_err(&ua->dev->dev,
1007 "playback/capture sample widths do not match\n");
1008 return -ENXIO;
1009 }
1010
1011 if (fmt_capture->bBitResolution != 24 ||
1012 fmt_playback->bBitResolution != 24) {
1013 dev_err(&ua->dev->dev, "sample width is not 24 bits\n");
1014 return -ENXIO;
1015 }
1016
1017 ua->rate = combine_triple(fmt_capture->tSamFreq[0]);
1018 rate2 = combine_triple(fmt_playback->tSamFreq[0]);
1019 if (ua->rate != rate2) {
1020 dev_err(&ua->dev->dev,
1021 "playback/capture rates do not match: %u/%u\n",
1022 rate2, ua->rate);
1023 return -ENXIO;
1024 }
1025
1026 switch (ua->dev->speed) {
1027 case USB_SPEED_FULL:
1028 ua->packets_per_second = 1000;
1029 break;
1030 case USB_SPEED_HIGH:
1031 ua->packets_per_second = 8000;
1032 break;
1033 default:
1034 dev_err(&ua->dev->dev, "unknown device speed\n");
1035 return -ENXIO;
1036 }
1037
1038 ua->capture.channels = fmt_capture->bNrChannels;
1039 ua->playback.channels = fmt_playback->bNrChannels;
1040 ua->capture.frame_bytes =
1041 fmt_capture->bSubframeSize * ua->capture.channels;
1042 ua->playback.frame_bytes =
1043 fmt_playback->bSubframeSize * ua->playback.channels;
1044
1045 epd = &ua->intf[INTF_CAPTURE]->altsetting[1].endpoint[0].desc;
1046 if (!usb_endpoint_is_isoc_in(epd)) {
1047 dev_err(&ua->dev->dev, "invalid capture endpoint\n");
1048 return -ENXIO;
1049 }
1050 ua->capture.usb_pipe = usb_rcvisocpipe(ua->dev, usb_endpoint_num(epd));
1051 ua->capture.max_packet_bytes = le16_to_cpu(epd->wMaxPacketSize);
1052
1053 epd = &ua->intf[INTF_PLAYBACK]->altsetting[1].endpoint[0].desc;
1054 if (!usb_endpoint_is_isoc_out(epd)) {
1055 dev_err(&ua->dev->dev, "invalid playback endpoint\n");
1056 return -ENXIO;
1057 }
1058 ua->playback.usb_pipe = usb_sndisocpipe(ua->dev, usb_endpoint_num(epd));
1059 ua->playback.max_packet_bytes = le16_to_cpu(epd->wMaxPacketSize);
1060 return 0;
1061}
1062
1063static int alloc_stream_buffers(struct ua101 *ua, struct ua101_stream *stream)
1064{
1065 unsigned int remaining_packets, packets, packets_per_page, i;
1066 size_t size;
1067
1068 stream->queue_length = queue_length;
1069 stream->queue_length = max(stream->queue_length,
1070 (unsigned int)MIN_QUEUE_LENGTH);
1071 stream->queue_length = min(stream->queue_length,
1072 (unsigned int)MAX_QUEUE_LENGTH);
1073
1074 /*
1075 * The cache pool sizes used by usb_buffer_alloc() (128, 512, 2048) are
1076 * quite bad when used with the packet sizes of this device (e.g. 280,
1077 * 520, 624). Therefore, we allocate and subdivide entire pages, using
1078 * a smaller buffer only for the last chunk.
1079 */
1080 remaining_packets = stream->queue_length;
1081 packets_per_page = PAGE_SIZE / stream->max_packet_bytes;
1082 for (i = 0; i < ARRAY_SIZE(stream->buffers); ++i) {
1083 packets = min(remaining_packets, packets_per_page);
1084 size = packets * stream->max_packet_bytes;
1085 stream->buffers[i].addr =
1086 usb_buffer_alloc(ua->dev, size, GFP_KERNEL,
1087 &stream->buffers[i].dma);
1088 if (!stream->buffers[i].addr)
1089 return -ENOMEM;
1090 stream->buffers[i].size = size;
1091 remaining_packets -= packets;
1092 if (!remaining_packets)
1093 break;
1094 }
1095 if (remaining_packets) {
1096 dev_err(&ua->dev->dev, "too many packets\n");
1097 return -ENXIO;
1098 }
1099 return 0;
1100}
1101
1102static void free_stream_buffers(struct ua101 *ua, struct ua101_stream *stream)
1103{
1104 unsigned int i;
1105
1106 for (i = 0; i < ARRAY_SIZE(stream->buffers); ++i)
1107 usb_buffer_free(ua->dev,
1108 stream->buffers[i].size,
1109 stream->buffers[i].addr,
1110 stream->buffers[i].dma);
1111}
1112
1113static int alloc_stream_urbs(struct ua101 *ua, struct ua101_stream *stream,
1114 void (*urb_complete)(struct urb *))
1115{
1116 unsigned max_packet_size = stream->max_packet_bytes;
1117 struct ua101_urb *urb;
1118 unsigned int b, u = 0;
1119
1120 for (b = 0; b < ARRAY_SIZE(stream->buffers); ++b) {
1121 unsigned int size = stream->buffers[b].size;
1122 u8 *addr = stream->buffers[b].addr;
1123 dma_addr_t dma = stream->buffers[b].dma;
1124
1125 while (size >= max_packet_size) {
1126 if (u >= stream->queue_length)
1127 goto bufsize_error;
1128 urb = kmalloc(sizeof(*urb), GFP_KERNEL);
1129 if (!urb)
1130 return -ENOMEM;
1131 usb_init_urb(&urb->urb);
1132 urb->urb.dev = ua->dev;
1133 urb->urb.pipe = stream->usb_pipe;
1134 urb->urb.transfer_flags = URB_ISO_ASAP |
1135 URB_NO_TRANSFER_DMA_MAP;
1136 urb->urb.transfer_buffer = addr;
1137 urb->urb.transfer_dma = dma;
1138 urb->urb.transfer_buffer_length = max_packet_size;
1139 urb->urb.number_of_packets = 1;
1140 urb->urb.interval = 1;
1141 urb->urb.context = ua;
1142 urb->urb.complete = urb_complete;
1143 urb->urb.iso_frame_desc[0].offset = 0;
1144 urb->urb.iso_frame_desc[0].length = max_packet_size;
1145 stream->urbs[u++] = urb;
1146 size -= max_packet_size;
1147 addr += max_packet_size;
1148 dma += max_packet_size;
1149 }
1150 }
1151 if (u == stream->queue_length)
1152 return 0;
1153bufsize_error:
1154 dev_err(&ua->dev->dev, "internal buffer size error\n");
1155 return -ENXIO;
1156}
1157
1158static void free_stream_urbs(struct ua101_stream *stream)
1159{
1160 unsigned int i;
1161
1162 for (i = 0; i < stream->queue_length; ++i)
1163 kfree(stream->urbs[i]);
1164}
1165
1166static void free_usb_related_resources(struct ua101 *ua,
1167 struct usb_interface *interface)
1168{
1169 unsigned int i;
1170
1171 free_stream_urbs(&ua->capture);
1172 free_stream_urbs(&ua->playback);
1173 free_stream_buffers(ua, &ua->capture);
1174 free_stream_buffers(ua, &ua->playback);
1175
1176 for (i = 0; i < ARRAY_SIZE(ua->intf); ++i)
1177 if (ua->intf[i]) {
1178 usb_set_intfdata(ua->intf[i], NULL);
1179 if (ua->intf[i] != interface)
1180 usb_driver_release_interface(&ua101_driver,
1181 ua->intf[i]);
1182 }
1183}
1184
1185static void ua101_card_free(struct snd_card *card)
1186{
1187 struct ua101 *ua = card->private_data;
1188
1189 mutex_destroy(&ua->mutex);
1190}
1191
1192static int ua101_probe(struct usb_interface *interface,
1193 const struct usb_device_id *usb_id)
1194{
1195 static const struct snd_usb_midi_endpoint_info midi_ep = {
1196 .out_cables = 0x0001,
1197 .in_cables = 0x0001
1198 };
1199 static const struct snd_usb_audio_quirk midi_quirk = {
1200 .type = QUIRK_MIDI_FIXED_ENDPOINT,
1201 .data = &midi_ep
1202 };
1203 struct snd_card *card;
1204 struct ua101 *ua;
1205 unsigned int card_index, i;
1206 char usb_path[32];
1207 int err;
1208
1209 if (interface->altsetting->desc.bInterfaceNumber != 0)
1210 return -ENODEV;
1211
1212 mutex_lock(&devices_mutex);
1213
1214 for (card_index = 0; card_index < SNDRV_CARDS; ++card_index)
1215 if (enable[card_index] && !(devices_used & (1 << card_index)))
1216 break;
1217 if (card_index >= SNDRV_CARDS) {
1218 mutex_unlock(&devices_mutex);
1219 return -ENOENT;
1220 }
1221 err = snd_card_create(index[card_index], id[card_index], THIS_MODULE,
1222 sizeof(*ua), &card);
1223 if (err < 0) {
1224 mutex_unlock(&devices_mutex);
1225 return err;
1226 }
1227 card->private_free = ua101_card_free;
1228 ua = card->private_data;
1229 ua->dev = interface_to_usbdev(interface);
1230 ua->card = card;
1231 ua->card_index = card_index;
1232 INIT_LIST_HEAD(&ua->midi_list);
1233 spin_lock_init(&ua->lock);
1234 mutex_init(&ua->mutex);
1235 INIT_LIST_HEAD(&ua->ready_playback_urbs);
1236 tasklet_init(&ua->playback_tasklet,
1237 playback_tasklet, (unsigned long)ua);
1238 init_waitqueue_head(&ua->alsa_capture_wait);
1239 init_waitqueue_head(&ua->rate_feedback_wait);
1240 init_waitqueue_head(&ua->alsa_playback_wait);
1241
1242#ifdef UA1A_HACK
1243 if (ua->dev->descriptor.idProduct == cpu_to_le16(0x0018)) {
1244 ua->intf[2] = interface;
1245 ua->intf[0] = usb_ifnum_to_if(ua->dev, 1);
1246 ua->intf[1] = usb_ifnum_to_if(ua->dev, 2);
1247 usb_driver_claim_interface(&ua101_driver, ua->intf[0], ua);
1248 usb_driver_claim_interface(&ua101_driver, ua->intf[1], ua);
1249 } else {
1250#endif
1251 ua->intf[0] = interface;
1252 for (i = 1; i < ARRAY_SIZE(ua->intf); ++i) {
1253 ua->intf[i] = usb_ifnum_to_if(ua->dev, i);
1254 if (!ua->intf[i]) {
1255 dev_err(&ua->dev->dev, "interface %u not found\n", i);
1256 err = -ENXIO;
1257 goto probe_error;
1258 }
1259 err = usb_driver_claim_interface(&ua101_driver,
1260 ua->intf[i], ua);
1261 if (err < 0) {
1262 ua->intf[i] = NULL;
1263 err = -EBUSY;
1264 goto probe_error;
1265 }
1266 }
1267#ifdef UA1A_HACK
1268 }
1269#endif
1270
1271 snd_card_set_dev(card, &interface->dev);
1272
1273#ifdef UA1A_HACK
1274 if (ua->dev->descriptor.idProduct == cpu_to_le16(0x0018)) {
1275 ua->format_bit = SNDRV_PCM_FMTBIT_S16_LE;
1276 ua->rate = 44100;
1277 ua->packets_per_second = 1000;
1278 ua->capture.channels = 2;
1279 ua->playback.channels = 2;
1280 ua->capture.frame_bytes = 4;
1281 ua->playback.frame_bytes = 4;
1282 ua->capture.usb_pipe = usb_rcvisocpipe(ua->dev, 2);
1283 ua->playback.usb_pipe = usb_sndisocpipe(ua->dev, 1);
1284 ua->capture.max_packet_bytes = 192;
1285 ua->playback.max_packet_bytes = 192;
1286 } else {
1287#endif
1288 err = detect_usb_format(ua);
1289 if (err < 0)
1290 goto probe_error;
1291#ifdef UA1A_HACK
1292 }
1293#endif
1294
1295 strcpy(card->driver, "UA-101");
1296 strcpy(card->shortname, "UA-101");
1297 usb_make_path(ua->dev, usb_path, sizeof(usb_path));
1298 snprintf(ua->card->longname, sizeof(ua->card->longname),
1299 "EDIROL UA-101 (serial %s), %u Hz at %s, %s speed",
1300 ua->dev->serial ? ua->dev->serial : "?", ua->rate, usb_path,
1301 ua->dev->speed == USB_SPEED_HIGH ? "high" : "full");
1302
1303 err = alloc_stream_buffers(ua, &ua->capture);
1304 if (err < 0)
1305 goto probe_error;
1306 err = alloc_stream_buffers(ua, &ua->playback);
1307 if (err < 0)
1308 goto probe_error;
1309
1310 err = alloc_stream_urbs(ua, &ua->capture, capture_urb_complete);
1311 if (err < 0)
1312 goto probe_error;
1313 err = alloc_stream_urbs(ua, &ua->playback, playback_urb_complete);
1314 if (err < 0)
1315 goto probe_error;
1316
1317 err = snd_pcm_new(card, "UA-101", 0, 1, 1, &ua->pcm);
1318 if (err < 0)
1319 goto probe_error;
1320 ua->pcm->private_data = ua;
1321 strcpy(ua->pcm->name, "UA-101");
1322 snd_pcm_set_ops(ua->pcm, SNDRV_PCM_STREAM_PLAYBACK, &playback_pcm_ops);
1323 snd_pcm_set_ops(ua->pcm, SNDRV_PCM_STREAM_CAPTURE, &capture_pcm_ops);
1324
1325#ifdef UA1A_HACK
1326 if (ua->dev->descriptor.idProduct != cpu_to_le16(0x0018)) {
1327#endif
1328 err = snd_usbmidi_create(card, ua->intf[INTF_MIDI],
1329 &ua->midi_list, &midi_quirk);
1330 if (err < 0)
1331 goto probe_error;
1332#ifdef UA1A_HACK
1333 }
1334#endif
1335
1336 err = snd_card_register(card);
1337 if (err < 0)
1338 goto probe_error;
1339
1340 usb_set_intfdata(interface, ua);
1341 devices_used |= 1 << card_index;
1342
1343 mutex_unlock(&devices_mutex);
1344 return 0;
1345
1346probe_error:
1347 free_usb_related_resources(ua, interface);
1348 snd_card_free(card);
1349 mutex_unlock(&devices_mutex);
1350 return err;
1351}
1352
1353static void ua101_disconnect(struct usb_interface *interface)
1354{
1355 struct ua101 *ua = usb_get_intfdata(interface);
1356 struct list_head *midi;
1357
1358 if (!ua)
1359 return;
1360
1361 mutex_lock(&devices_mutex);
1362
1363 set_bit(DISCONNECTED, &ua->states);
1364 wake_up(&ua->rate_feedback_wait);
1365
1366 /* make sure that userspace cannot create new requests */
1367 snd_card_disconnect(ua->card);
1368
1369 /* make sure that there are no pending USB requests */
1370 __list_for_each(midi, &ua->midi_list)
1371 snd_usbmidi_disconnect(midi);
1372 abort_alsa_playback(ua);
1373 abort_alsa_capture(ua);
1374 mutex_lock(&ua->mutex);
1375 stop_usb_playback(ua);
1376 stop_usb_capture(ua);
1377 mutex_unlock(&ua->mutex);
1378
1379 free_usb_related_resources(ua, interface);
1380
1381 devices_used &= ~(1 << ua->card_index);
1382
1383 snd_card_free_when_closed(ua->card);
1384
1385 mutex_unlock(&devices_mutex);
1386}
1387
1388static struct usb_device_id ua101_ids[] = {
1389#ifdef UA1A_HACK
1390 { USB_DEVICE(0x0582, 0x0018) },
1391#endif
1392 { USB_DEVICE(0x0582, 0x007d) },
1393 { USB_DEVICE(0x0582, 0x008d) },
1394 { }
1395};
1396MODULE_DEVICE_TABLE(usb, ua101_ids);
1397
1398static struct usb_driver ua101_driver = {
1399 .name = "snd-ua101",
1400 .id_table = ua101_ids,
1401 .probe = ua101_probe,
1402 .disconnect = ua101_disconnect,
1403#if 0
1404 .suspend = ua101_suspend,
1405 .resume = ua101_resume,
1406#endif
1407};
1408
1409static int __init alsa_card_ua101_init(void)
1410{
1411 return usb_register(&ua101_driver);
1412}
1413
1414static void __exit alsa_card_ua101_exit(void)
1415{
1416 usb_deregister(&ua101_driver);
1417 mutex_destroy(&devices_mutex);
1418}
1419
1420module_init(alsa_card_ua101_init);
1421module_exit(alsa_card_ua101_exit);
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index 9edef4684978..c539f7fe292f 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -44,9 +44,11 @@
44#include <linux/slab.h> 44#include <linux/slab.h>
45#include <linux/string.h> 45#include <linux/string.h>
46#include <linux/usb.h> 46#include <linux/usb.h>
47#include <linux/vmalloc.h>
48#include <linux/moduleparam.h> 47#include <linux/moduleparam.h>
49#include <linux/mutex.h> 48#include <linux/mutex.h>
49#include <linux/usb/audio.h>
50#include <linux/usb/ch9.h>
51
50#include <sound/core.h> 52#include <sound/core.h>
51#include <sound/info.h> 53#include <sound/info.h>
52#include <sound/pcm.h> 54#include <sound/pcm.h>
@@ -170,11 +172,12 @@ struct snd_usb_substream {
170 unsigned int curpacksize; /* current packet size in bytes (for capture) */ 172 unsigned int curpacksize; /* current packet size in bytes (for capture) */
171 unsigned int curframesize; /* current packet size in frames (for capture) */ 173 unsigned int curframesize; /* current packet size in frames (for capture) */
172 unsigned int fill_max: 1; /* fill max packet size always */ 174 unsigned int fill_max: 1; /* fill max packet size always */
175 unsigned int txfr_quirk:1; /* allow sub-frame alignment */
173 unsigned int fmt_type; /* USB audio format type (1-3) */ 176 unsigned int fmt_type; /* USB audio format type (1-3) */
174 177
175 unsigned int running: 1; /* running status */ 178 unsigned int running: 1; /* running status */
176 179
177 unsigned int hwptr_done; /* processed frame position in the buffer */ 180 unsigned int hwptr_done; /* processed byte position in the buffer */
178 unsigned int transfer_done; /* processed frames since last period update */ 181 unsigned int transfer_done; /* processed frames since last period update */
179 unsigned long active_mask; /* bitmask of active urbs */ 182 unsigned long active_mask; /* bitmask of active urbs */
180 unsigned long unlink_mask; /* bitmask of unlinked urbs */ 183 unsigned long unlink_mask; /* bitmask of unlinked urbs */
@@ -343,7 +346,7 @@ static int retire_capture_urb(struct snd_usb_substream *subs,
343 unsigned long flags; 346 unsigned long flags;
344 unsigned char *cp; 347 unsigned char *cp;
345 int i; 348 int i;
346 unsigned int stride, len, oldptr; 349 unsigned int stride, frames, bytes, oldptr;
347 int period_elapsed = 0; 350 int period_elapsed = 0;
348 351
349 stride = runtime->frame_bits >> 3; 352 stride = runtime->frame_bits >> 3;
@@ -354,29 +357,39 @@ static int retire_capture_urb(struct snd_usb_substream *subs,
354 snd_printd(KERN_ERR "frame %d active: %d\n", i, urb->iso_frame_desc[i].status); 357 snd_printd(KERN_ERR "frame %d active: %d\n", i, urb->iso_frame_desc[i].status);
355 // continue; 358 // continue;
356 } 359 }
357 len = urb->iso_frame_desc[i].actual_length / stride; 360 bytes = urb->iso_frame_desc[i].actual_length;
358 if (! len) 361 frames = bytes / stride;
359 continue; 362 if (!subs->txfr_quirk)
363 bytes = frames * stride;
364 if (bytes % (runtime->sample_bits >> 3) != 0) {
365#ifdef CONFIG_SND_DEBUG_VERBOSE
366 int oldbytes = bytes;
367#endif
368 bytes = frames * stride;
369 snd_printdd(KERN_ERR "Corrected urb data len. %d->%d\n",
370 oldbytes, bytes);
371 }
360 /* update the current pointer */ 372 /* update the current pointer */
361 spin_lock_irqsave(&subs->lock, flags); 373 spin_lock_irqsave(&subs->lock, flags);
362 oldptr = subs->hwptr_done; 374 oldptr = subs->hwptr_done;
363 subs->hwptr_done += len; 375 subs->hwptr_done += bytes;
364 if (subs->hwptr_done >= runtime->buffer_size) 376 if (subs->hwptr_done >= runtime->buffer_size * stride)
365 subs->hwptr_done -= runtime->buffer_size; 377 subs->hwptr_done -= runtime->buffer_size * stride;
366 subs->transfer_done += len; 378 frames = (bytes + (oldptr % stride)) / stride;
379 subs->transfer_done += frames;
367 if (subs->transfer_done >= runtime->period_size) { 380 if (subs->transfer_done >= runtime->period_size) {
368 subs->transfer_done -= runtime->period_size; 381 subs->transfer_done -= runtime->period_size;
369 period_elapsed = 1; 382 period_elapsed = 1;
370 } 383 }
371 spin_unlock_irqrestore(&subs->lock, flags); 384 spin_unlock_irqrestore(&subs->lock, flags);
372 /* copy a data chunk */ 385 /* copy a data chunk */
373 if (oldptr + len > runtime->buffer_size) { 386 if (oldptr + bytes > runtime->buffer_size * stride) {
374 unsigned int cnt = runtime->buffer_size - oldptr; 387 unsigned int bytes1 =
375 unsigned int blen = cnt * stride; 388 runtime->buffer_size * stride - oldptr;
376 memcpy(runtime->dma_area + oldptr * stride, cp, blen); 389 memcpy(runtime->dma_area + oldptr, cp, bytes1);
377 memcpy(runtime->dma_area, cp + blen, len * stride - blen); 390 memcpy(runtime->dma_area, cp + bytes1, bytes - bytes1);
378 } else { 391 } else {
379 memcpy(runtime->dma_area + oldptr * stride, cp, len * stride); 392 memcpy(runtime->dma_area + oldptr, cp, bytes);
380 } 393 }
381 } 394 }
382 if (period_elapsed) 395 if (period_elapsed)
@@ -563,34 +576,34 @@ static int prepare_playback_urb(struct snd_usb_substream *subs,
563 struct snd_pcm_runtime *runtime, 576 struct snd_pcm_runtime *runtime,
564 struct urb *urb) 577 struct urb *urb)
565{ 578{
566 int i, stride, offs; 579 int i, stride;
567 unsigned int counts; 580 unsigned int counts, frames, bytes;
568 unsigned long flags; 581 unsigned long flags;
569 int period_elapsed = 0; 582 int period_elapsed = 0;
570 struct snd_urb_ctx *ctx = urb->context; 583 struct snd_urb_ctx *ctx = urb->context;
571 584
572 stride = runtime->frame_bits >> 3; 585 stride = runtime->frame_bits >> 3;
573 586
574 offs = 0; 587 frames = 0;
575 urb->dev = ctx->subs->dev; /* we need to set this at each time */ 588 urb->dev = ctx->subs->dev; /* we need to set this at each time */
576 urb->number_of_packets = 0; 589 urb->number_of_packets = 0;
577 spin_lock_irqsave(&subs->lock, flags); 590 spin_lock_irqsave(&subs->lock, flags);
578 for (i = 0; i < ctx->packets; i++) { 591 for (i = 0; i < ctx->packets; i++) {
579 counts = snd_usb_audio_next_packet_size(subs); 592 counts = snd_usb_audio_next_packet_size(subs);
580 /* set up descriptor */ 593 /* set up descriptor */
581 urb->iso_frame_desc[i].offset = offs * stride; 594 urb->iso_frame_desc[i].offset = frames * stride;
582 urb->iso_frame_desc[i].length = counts * stride; 595 urb->iso_frame_desc[i].length = counts * stride;
583 offs += counts; 596 frames += counts;
584 urb->number_of_packets++; 597 urb->number_of_packets++;
585 subs->transfer_done += counts; 598 subs->transfer_done += counts;
586 if (subs->transfer_done >= runtime->period_size) { 599 if (subs->transfer_done >= runtime->period_size) {
587 subs->transfer_done -= runtime->period_size; 600 subs->transfer_done -= runtime->period_size;
588 period_elapsed = 1; 601 period_elapsed = 1;
589 if (subs->fmt_type == USB_FORMAT_TYPE_II) { 602 if (subs->fmt_type == UAC_FORMAT_TYPE_II) {
590 if (subs->transfer_done > 0) { 603 if (subs->transfer_done > 0) {
591 /* FIXME: fill-max mode is not 604 /* FIXME: fill-max mode is not
592 * supported yet */ 605 * supported yet */
593 offs -= subs->transfer_done; 606 frames -= subs->transfer_done;
594 counts -= subs->transfer_done; 607 counts -= subs->transfer_done;
595 urb->iso_frame_desc[i].length = 608 urb->iso_frame_desc[i].length =
596 counts * stride; 609 counts * stride;
@@ -600,7 +613,7 @@ static int prepare_playback_urb(struct snd_usb_substream *subs,
600 if (i < ctx->packets) { 613 if (i < ctx->packets) {
601 /* add a transfer delimiter */ 614 /* add a transfer delimiter */
602 urb->iso_frame_desc[i].offset = 615 urb->iso_frame_desc[i].offset =
603 offs * stride; 616 frames * stride;
604 urb->iso_frame_desc[i].length = 0; 617 urb->iso_frame_desc[i].length = 0;
605 urb->number_of_packets++; 618 urb->number_of_packets++;
606 } 619 }
@@ -610,26 +623,25 @@ static int prepare_playback_urb(struct snd_usb_substream *subs,
610 if (period_elapsed) /* finish at the period boundary */ 623 if (period_elapsed) /* finish at the period boundary */
611 break; 624 break;
612 } 625 }
613 if (subs->hwptr_done + offs > runtime->buffer_size) { 626 bytes = frames * stride;
627 if (subs->hwptr_done + bytes > runtime->buffer_size * stride) {
614 /* err, the transferred area goes over buffer boundary. */ 628 /* err, the transferred area goes over buffer boundary. */
615 unsigned int len = runtime->buffer_size - subs->hwptr_done; 629 unsigned int bytes1 =
630 runtime->buffer_size * stride - subs->hwptr_done;
616 memcpy(urb->transfer_buffer, 631 memcpy(urb->transfer_buffer,
617 runtime->dma_area + subs->hwptr_done * stride, 632 runtime->dma_area + subs->hwptr_done, bytes1);
618 len * stride); 633 memcpy(urb->transfer_buffer + bytes1,
619 memcpy(urb->transfer_buffer + len * stride, 634 runtime->dma_area, bytes - bytes1);
620 runtime->dma_area,
621 (offs - len) * stride);
622 } else { 635 } else {
623 memcpy(urb->transfer_buffer, 636 memcpy(urb->transfer_buffer,
624 runtime->dma_area + subs->hwptr_done * stride, 637 runtime->dma_area + subs->hwptr_done, bytes);
625 offs * stride);
626 } 638 }
627 subs->hwptr_done += offs; 639 subs->hwptr_done += bytes;
628 if (subs->hwptr_done >= runtime->buffer_size) 640 if (subs->hwptr_done >= runtime->buffer_size * stride)
629 subs->hwptr_done -= runtime->buffer_size; 641 subs->hwptr_done -= runtime->buffer_size * stride;
630 runtime->delay += offs; 642 runtime->delay += frames;
631 spin_unlock_irqrestore(&subs->lock, flags); 643 spin_unlock_irqrestore(&subs->lock, flags);
632 urb->transfer_buffer_length = offs * stride; 644 urb->transfer_buffer_length = bytes;
633 if (period_elapsed) 645 if (period_elapsed)
634 snd_pcm_period_elapsed(subs->pcm_substream); 646 snd_pcm_period_elapsed(subs->pcm_substream);
635 return 0; 647 return 0;
@@ -735,41 +747,6 @@ static void snd_complete_sync_urb(struct urb *urb)
735} 747}
736 748
737 749
738/* get the physical page pointer at the given offset */
739static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs,
740 unsigned long offset)
741{
742 void *pageptr = subs->runtime->dma_area + offset;
743 return vmalloc_to_page(pageptr);
744}
745
746/* allocate virtual buffer; may be called more than once */
747static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, size_t size)
748{
749 struct snd_pcm_runtime *runtime = subs->runtime;
750 if (runtime->dma_area) {
751 if (runtime->dma_bytes >= size)
752 return 0; /* already large enough */
753 vfree(runtime->dma_area);
754 }
755 runtime->dma_area = vmalloc_user(size);
756 if (!runtime->dma_area)
757 return -ENOMEM;
758 runtime->dma_bytes = size;
759 return 0;
760}
761
762/* free virtual buffer; may be called more than once */
763static int snd_pcm_free_vmalloc_buffer(struct snd_pcm_substream *subs)
764{
765 struct snd_pcm_runtime *runtime = subs->runtime;
766
767 vfree(runtime->dma_area);
768 runtime->dma_area = NULL;
769 return 0;
770}
771
772
773/* 750/*
774 * unlink active urbs. 751 * unlink active urbs.
775 */ 752 */
@@ -937,18 +914,18 @@ static int wait_clear_urbs(struct snd_usb_substream *subs)
937 914
938 915
939/* 916/*
940 * return the current pcm pointer. just return the hwptr_done value. 917 * return the current pcm pointer. just based on the hwptr_done value.
941 */ 918 */
942static snd_pcm_uframes_t snd_usb_pcm_pointer(struct snd_pcm_substream *substream) 919static snd_pcm_uframes_t snd_usb_pcm_pointer(struct snd_pcm_substream *substream)
943{ 920{
944 struct snd_usb_substream *subs; 921 struct snd_usb_substream *subs;
945 snd_pcm_uframes_t hwptr_done; 922 unsigned int hwptr_done;
946 923
947 subs = (struct snd_usb_substream *)substream->runtime->private_data; 924 subs = (struct snd_usb_substream *)substream->runtime->private_data;
948 spin_lock(&subs->lock); 925 spin_lock(&subs->lock);
949 hwptr_done = subs->hwptr_done; 926 hwptr_done = subs->hwptr_done;
950 spin_unlock(&subs->lock); 927 spin_unlock(&subs->lock);
951 return hwptr_done; 928 return hwptr_done / (substream->runtime->frame_bits >> 3);
952} 929}
953 930
954 931
@@ -1130,7 +1107,7 @@ static int init_substream_urbs(struct snd_usb_substream *subs, unsigned int peri
1130 u->packets = (i + 1) * total_packs / subs->nurbs 1107 u->packets = (i + 1) * total_packs / subs->nurbs
1131 - i * total_packs / subs->nurbs; 1108 - i * total_packs / subs->nurbs;
1132 u->buffer_size = maxsize * u->packets; 1109 u->buffer_size = maxsize * u->packets;
1133 if (subs->fmt_type == USB_FORMAT_TYPE_II) 1110 if (subs->fmt_type == UAC_FORMAT_TYPE_II)
1134 u->packets++; /* for transfer delimiter */ 1111 u->packets++; /* for transfer delimiter */
1135 u->urb = usb_alloc_urb(u->packets, GFP_KERNEL); 1112 u->urb = usb_alloc_urb(u->packets, GFP_KERNEL);
1136 if (!u->urb) 1113 if (!u->urb)
@@ -1206,7 +1183,7 @@ static struct audioformat *find_format(struct snd_usb_substream *subs, unsigned
1206 if (i >= fp->nr_rates) 1183 if (i >= fp->nr_rates)
1207 continue; 1184 continue;
1208 } 1185 }
1209 attr = fp->ep_attr & EP_ATTR_MASK; 1186 attr = fp->ep_attr & USB_ENDPOINT_SYNCTYPE;
1210 if (! found) { 1187 if (! found) {
1211 found = fp; 1188 found = fp;
1212 cur_attr = attr; 1189 cur_attr = attr;
@@ -1218,14 +1195,14 @@ static struct audioformat *find_format(struct snd_usb_substream *subs, unsigned
1218 * M-audio audiophile USB. 1195 * M-audio audiophile USB.
1219 */ 1196 */
1220 if (attr != cur_attr) { 1197 if (attr != cur_attr) {
1221 if ((attr == EP_ATTR_ASYNC && 1198 if ((attr == USB_ENDPOINT_SYNC_ASYNC &&
1222 subs->direction == SNDRV_PCM_STREAM_PLAYBACK) || 1199 subs->direction == SNDRV_PCM_STREAM_PLAYBACK) ||
1223 (attr == EP_ATTR_ADAPTIVE && 1200 (attr == USB_ENDPOINT_SYNC_ADAPTIVE &&
1224 subs->direction == SNDRV_PCM_STREAM_CAPTURE)) 1201 subs->direction == SNDRV_PCM_STREAM_CAPTURE))
1225 continue; 1202 continue;
1226 if ((cur_attr == EP_ATTR_ASYNC && 1203 if ((cur_attr == USB_ENDPOINT_SYNC_ASYNC &&
1227 subs->direction == SNDRV_PCM_STREAM_PLAYBACK) || 1204 subs->direction == SNDRV_PCM_STREAM_PLAYBACK) ||
1228 (cur_attr == EP_ATTR_ADAPTIVE && 1205 (cur_attr == USB_ENDPOINT_SYNC_ADAPTIVE &&
1229 subs->direction == SNDRV_PCM_STREAM_CAPTURE)) { 1206 subs->direction == SNDRV_PCM_STREAM_CAPTURE)) {
1230 found = fp; 1207 found = fp;
1231 cur_attr = attr; 1208 cur_attr = attr;
@@ -1255,11 +1232,11 @@ static int init_usb_pitch(struct usb_device *dev, int iface,
1255 1232
1256 ep = get_endpoint(alts, 0)->bEndpointAddress; 1233 ep = get_endpoint(alts, 0)->bEndpointAddress;
1257 /* if endpoint has pitch control, enable it */ 1234 /* if endpoint has pitch control, enable it */
1258 if (fmt->attributes & EP_CS_ATTR_PITCH_CONTROL) { 1235 if (fmt->attributes & UAC_EP_CS_ATTR_PITCH_CONTROL) {
1259 data[0] = 1; 1236 data[0] = 1;
1260 if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, 1237 if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR,
1261 USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, 1238 USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT,
1262 PITCH_CONTROL << 8, ep, data, 1, 1000)) < 0) { 1239 UAC_EP_CS_ATTR_PITCH_CONTROL << 8, ep, data, 1, 1000)) < 0) {
1263 snd_printk(KERN_ERR "%d:%d:%d: cannot set enable PITCH\n", 1240 snd_printk(KERN_ERR "%d:%d:%d: cannot set enable PITCH\n",
1264 dev->devnum, iface, ep); 1241 dev->devnum, iface, ep);
1265 return err; 1242 return err;
@@ -1278,21 +1255,21 @@ static int init_usb_sample_rate(struct usb_device *dev, int iface,
1278 1255
1279 ep = get_endpoint(alts, 0)->bEndpointAddress; 1256 ep = get_endpoint(alts, 0)->bEndpointAddress;
1280 /* if endpoint has sampling rate control, set it */ 1257 /* if endpoint has sampling rate control, set it */
1281 if (fmt->attributes & EP_CS_ATTR_SAMPLE_RATE) { 1258 if (fmt->attributes & UAC_EP_CS_ATTR_SAMPLE_RATE) {
1282 int crate; 1259 int crate;
1283 data[0] = rate; 1260 data[0] = rate;
1284 data[1] = rate >> 8; 1261 data[1] = rate >> 8;
1285 data[2] = rate >> 16; 1262 data[2] = rate >> 16;
1286 if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, 1263 if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR,
1287 USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, 1264 USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT,
1288 SAMPLING_FREQ_CONTROL << 8, ep, data, 3, 1000)) < 0) { 1265 UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep, data, 3, 1000)) < 0) {
1289 snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d to ep %#x\n", 1266 snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d to ep %#x\n",
1290 dev->devnum, iface, fmt->altsetting, rate, ep); 1267 dev->devnum, iface, fmt->altsetting, rate, ep);
1291 return err; 1268 return err;
1292 } 1269 }
1293 if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, 1270 if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC_GET_CUR,
1294 USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_IN, 1271 USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_IN,
1295 SAMPLING_FREQ_CONTROL << 8, ep, data, 3, 1000)) < 0) { 1272 UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep, data, 3, 1000)) < 0) {
1296 snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq at ep %#x\n", 1273 snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq at ep %#x\n",
1297 dev->devnum, iface, fmt->altsetting, ep); 1274 dev->devnum, iface, fmt->altsetting, ep);
1298 return 0; /* some devices don't support reading */ 1275 return 0; /* some devices don't support reading */
@@ -1307,6 +1284,47 @@ static int init_usb_sample_rate(struct usb_device *dev, int iface,
1307} 1284}
1308 1285
1309/* 1286/*
1287 * For E-Mu 0404USB/0202USB/TrackerPre sample rate should be set for device,
1288 * not for interface.
1289 */
1290static void set_format_emu_quirk(struct snd_usb_substream *subs,
1291 struct audioformat *fmt)
1292{
1293 unsigned char emu_samplerate_id = 0;
1294
1295 /* When capture is active
1296 * sample rate shouldn't be changed
1297 * by playback substream
1298 */
1299 if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) {
1300 if (subs->stream->substream[SNDRV_PCM_STREAM_CAPTURE].interface != -1)
1301 return;
1302 }
1303
1304 switch (fmt->rate_min) {
1305 case 48000:
1306 emu_samplerate_id = EMU_QUIRK_SR_48000HZ;
1307 break;
1308 case 88200:
1309 emu_samplerate_id = EMU_QUIRK_SR_88200HZ;
1310 break;
1311 case 96000:
1312 emu_samplerate_id = EMU_QUIRK_SR_96000HZ;
1313 break;
1314 case 176400:
1315 emu_samplerate_id = EMU_QUIRK_SR_176400HZ;
1316 break;
1317 case 192000:
1318 emu_samplerate_id = EMU_QUIRK_SR_192000HZ;
1319 break;
1320 default:
1321 emu_samplerate_id = EMU_QUIRK_SR_44100HZ;
1322 break;
1323 }
1324 snd_emuusb_set_samplerate(subs->stream->chip, emu_samplerate_id);
1325}
1326
1327/*
1310 * find a matching format and set up the interface 1328 * find a matching format and set up the interface
1311 */ 1329 */
1312static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt) 1330static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
@@ -1369,9 +1387,9 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
1369 * descriptors which fool us. if it has only one EP, 1387 * descriptors which fool us. if it has only one EP,
1370 * assume it as adaptive-out or sync-in. 1388 * assume it as adaptive-out or sync-in.
1371 */ 1389 */
1372 attr = fmt->ep_attr & EP_ATTR_MASK; 1390 attr = fmt->ep_attr & USB_ENDPOINT_SYNCTYPE;
1373 if (((is_playback && attr == EP_ATTR_ASYNC) || 1391 if (((is_playback && attr == USB_ENDPOINT_SYNC_ASYNC) ||
1374 (! is_playback && attr == EP_ATTR_ADAPTIVE)) && 1392 (! is_playback && attr == USB_ENDPOINT_SYNC_ADAPTIVE)) &&
1375 altsd->bNumEndpoints >= 2) { 1393 altsd->bNumEndpoints >= 2) {
1376 /* check sync-pipe endpoint */ 1394 /* check sync-pipe endpoint */
1377 /* ... and check descriptor size before accessing bSynchAddress 1395 /* ... and check descriptor size before accessing bSynchAddress
@@ -1411,7 +1429,7 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
1411 } 1429 }
1412 1430
1413 /* always fill max packet size */ 1431 /* always fill max packet size */
1414 if (fmt->attributes & EP_CS_ATTR_FILL_MAX) 1432 if (fmt->attributes & UAC_EP_CS_ATTR_FILL_MAX)
1415 subs->fill_max = 1; 1433 subs->fill_max = 1;
1416 1434
1417 if ((err = init_usb_pitch(dev, subs->interface, alts, fmt)) < 0) 1435 if ((err = init_usb_pitch(dev, subs->interface, alts, fmt)) < 0)
@@ -1419,6 +1437,14 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
1419 1437
1420 subs->cur_audiofmt = fmt; 1438 subs->cur_audiofmt = fmt;
1421 1439
1440 switch (subs->stream->chip->usb_id) {
1441 case USB_ID(0x041e, 0x3f02): /* E-Mu 0202 USB */
1442 case USB_ID(0x041e, 0x3f04): /* E-Mu 0404 USB */
1443 case USB_ID(0x041e, 0x3f0a): /* E-Mu Tracker Pre */
1444 set_format_emu_quirk(subs, fmt);
1445 break;
1446 }
1447
1422#if 0 1448#if 0
1423 printk(KERN_DEBUG 1449 printk(KERN_DEBUG
1424 "setting done: format = %d, rate = %d..%d, channels = %d\n", 1450 "setting done: format = %d, rate = %d..%d, channels = %d\n",
@@ -1449,8 +1475,8 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream,
1449 unsigned int channels, rate, format; 1475 unsigned int channels, rate, format;
1450 int ret, changed; 1476 int ret, changed;
1451 1477
1452 ret = snd_pcm_alloc_vmalloc_buffer(substream, 1478 ret = snd_pcm_lib_alloc_vmalloc_buffer(substream,
1453 params_buffer_bytes(hw_params)); 1479 params_buffer_bytes(hw_params));
1454 if (ret < 0) 1480 if (ret < 0)
1455 return ret; 1481 return ret;
1456 1482
@@ -1507,7 +1533,7 @@ static int snd_usb_hw_free(struct snd_pcm_substream *substream)
1507 subs->period_bytes = 0; 1533 subs->period_bytes = 0;
1508 if (!subs->stream->chip->shutdown) 1534 if (!subs->stream->chip->shutdown)
1509 release_substream_urbs(subs, 0); 1535 release_substream_urbs(subs, 0);
1510 return snd_pcm_free_vmalloc_buffer(substream); 1536 return snd_pcm_lib_free_vmalloc_buffer(substream);
1511} 1537}
1512 1538
1513/* 1539/*
@@ -1861,7 +1887,7 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre
1861 runtime->hw.channels_min = fp->channels; 1887 runtime->hw.channels_min = fp->channels;
1862 if (runtime->hw.channels_max < fp->channels) 1888 if (runtime->hw.channels_max < fp->channels)
1863 runtime->hw.channels_max = fp->channels; 1889 runtime->hw.channels_max = fp->channels;
1864 if (fp->fmt_type == USB_FORMAT_TYPE_II && fp->frame_size > 0) { 1890 if (fp->fmt_type == UAC_FORMAT_TYPE_II && fp->frame_size > 0) {
1865 /* FIXME: there might be more than one audio formats... */ 1891 /* FIXME: there might be more than one audio formats... */
1866 runtime->hw.period_bytes_min = runtime->hw.period_bytes_max = 1892 runtime->hw.period_bytes_min = runtime->hw.period_bytes_max =
1867 fp->frame_size; 1893 fp->frame_size;
@@ -1973,7 +1999,8 @@ static struct snd_pcm_ops snd_usb_playback_ops = {
1973 .prepare = snd_usb_pcm_prepare, 1999 .prepare = snd_usb_pcm_prepare,
1974 .trigger = snd_usb_pcm_playback_trigger, 2000 .trigger = snd_usb_pcm_playback_trigger,
1975 .pointer = snd_usb_pcm_pointer, 2001 .pointer = snd_usb_pcm_pointer,
1976 .page = snd_pcm_get_vmalloc_page, 2002 .page = snd_pcm_lib_get_vmalloc_page,
2003 .mmap = snd_pcm_lib_mmap_vmalloc,
1977}; 2004};
1978 2005
1979static struct snd_pcm_ops snd_usb_capture_ops = { 2006static struct snd_pcm_ops snd_usb_capture_ops = {
@@ -1985,7 +2012,8 @@ static struct snd_pcm_ops snd_usb_capture_ops = {
1985 .prepare = snd_usb_pcm_prepare, 2012 .prepare = snd_usb_pcm_prepare,
1986 .trigger = snd_usb_pcm_capture_trigger, 2013 .trigger = snd_usb_pcm_capture_trigger,
1987 .pointer = snd_usb_pcm_pointer, 2014 .pointer = snd_usb_pcm_pointer,
1988 .page = snd_pcm_get_vmalloc_page, 2015 .page = snd_pcm_lib_get_vmalloc_page,
2016 .mmap = snd_pcm_lib_mmap_vmalloc,
1989}; 2017};
1990 2018
1991 2019
@@ -2093,7 +2121,7 @@ static struct usb_device_id usb_audio_ids [] = {
2093#include "usbquirks.h" 2121#include "usbquirks.h"
2094 { .match_flags = (USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS), 2122 { .match_flags = (USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS),
2095 .bInterfaceClass = USB_CLASS_AUDIO, 2123 .bInterfaceClass = USB_CLASS_AUDIO,
2096 .bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL }, 2124 .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL },
2097 { } /* Terminating entry */ 2125 { } /* Terminating entry */
2098}; 2126};
2099 2127
@@ -2132,7 +2160,7 @@ static void proc_dump_substream_formats(struct snd_usb_substream *subs, struct s
2132 snd_iprintf(buffer, " Endpoint: %d %s (%s)\n", 2160 snd_iprintf(buffer, " Endpoint: %d %s (%s)\n",
2133 fp->endpoint & USB_ENDPOINT_NUMBER_MASK, 2161 fp->endpoint & USB_ENDPOINT_NUMBER_MASK,
2134 fp->endpoint & USB_DIR_IN ? "IN" : "OUT", 2162 fp->endpoint & USB_DIR_IN ? "IN" : "OUT",
2135 sync_types[(fp->ep_attr & EP_ATTR_MASK) >> 2]); 2163 sync_types[(fp->ep_attr & USB_ENDPOINT_SYNCTYPE) >> 2]);
2136 if (fp->rates & SNDRV_PCM_RATE_CONTINUOUS) { 2164 if (fp->rates & SNDRV_PCM_RATE_CONTINUOUS) {
2137 snd_iprintf(buffer, " Rates: %d - %d (continuous)\n", 2165 snd_iprintf(buffer, " Rates: %d - %d (continuous)\n",
2138 fp->rate_min, fp->rate_max); 2166 fp->rate_min, fp->rate_max);
@@ -2227,6 +2255,7 @@ static void init_substream(struct snd_usb_stream *as, int stream, struct audiofo
2227 subs->stream = as; 2255 subs->stream = as;
2228 subs->direction = stream; 2256 subs->direction = stream;
2229 subs->dev = as->chip->dev; 2257 subs->dev = as->chip->dev;
2258 subs->txfr_quirk = as->chip->txfr_quirk;
2230 if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) { 2259 if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) {
2231 subs->ops = audio_urb_ops[stream]; 2260 subs->ops = audio_urb_ops[stream];
2232 } else { 2261 } else {
@@ -2394,29 +2423,68 @@ static int is_big_endian_format(struct snd_usb_audio *chip, struct audioformat *
2394 * @format: the format tag (wFormatTag) 2423 * @format: the format tag (wFormatTag)
2395 * @fmt: the format type descriptor 2424 * @fmt: the format type descriptor
2396 */ 2425 */
2397static int parse_audio_format_i_type(struct snd_usb_audio *chip, struct audioformat *fp, 2426static int parse_audio_format_i_type(struct snd_usb_audio *chip,
2398 int format, unsigned char *fmt) 2427 struct audioformat *fp,
2428 int format, void *_fmt,
2429 int protocol)
2399{ 2430{
2400 int pcm_format; 2431 int pcm_format, i;
2401 int sample_width, sample_bytes; 2432 int sample_width, sample_bytes;
2402 2433
2434 switch (protocol) {
2435 case UAC_VERSION_1: {
2436 struct uac_format_type_i_discrete_descriptor *fmt = _fmt;
2437 sample_width = fmt->bBitResolution;
2438 sample_bytes = fmt->bSubframeSize;
2439 break;
2440 }
2441
2442 case UAC_VERSION_2: {
2443 struct uac_format_type_i_ext_descriptor *fmt = _fmt;
2444 sample_width = fmt->bBitResolution;
2445 sample_bytes = fmt->bSubslotSize;
2446
2447 /*
2448 * FIXME
2449 * USB audio class v2 devices specify a bitmap of possible
2450 * audio formats rather than one fix value. For now, we just
2451 * pick one of them and report that as the only possible
2452 * value for this setting.
2453 * The bit allocation map is in fact compatible to the
2454 * wFormatTag of the v1 AS streaming descriptors, which is why
2455 * we can simply map the matrix.
2456 */
2457
2458 for (i = 0; i < 5; i++)
2459 if (format & (1UL << i)) {
2460 format = i + 1;
2461 break;
2462 }
2463
2464 break;
2465 }
2466
2467 default:
2468 return -EINVAL;
2469 }
2470
2403 /* FIXME: correct endianess and sign? */ 2471 /* FIXME: correct endianess and sign? */
2404 pcm_format = -1; 2472 pcm_format = -1;
2405 sample_width = fmt[6]; 2473
2406 sample_bytes = fmt[5];
2407 switch (format) { 2474 switch (format) {
2408 case 0: /* some devices don't define this correctly... */ 2475 case UAC_FORMAT_TYPE_I_UNDEFINED: /* some devices don't define this correctly... */
2409 snd_printdd(KERN_INFO "%d:%u:%d : format type 0 is detected, processed as PCM\n", 2476 snd_printdd(KERN_INFO "%d:%u:%d : format type 0 is detected, processed as PCM\n",
2410 chip->dev->devnum, fp->iface, fp->altsetting); 2477 chip->dev->devnum, fp->iface, fp->altsetting);
2411 /* fall-through */ 2478 /* fall-through */
2412 case USB_AUDIO_FORMAT_PCM: 2479 case UAC_FORMAT_TYPE_I_PCM:
2413 if (sample_width > sample_bytes * 8) { 2480 if (sample_width > sample_bytes * 8) {
2414 snd_printk(KERN_INFO "%d:%u:%d : sample bitwidth %d in over sample bytes %d\n", 2481 snd_printk(KERN_INFO "%d:%u:%d : sample bitwidth %d in over sample bytes %d\n",
2415 chip->dev->devnum, fp->iface, fp->altsetting, 2482 chip->dev->devnum, fp->iface, fp->altsetting,
2416 sample_width, sample_bytes); 2483 sample_width, sample_bytes);
2417 } 2484 }
2418 /* check the format byte size */ 2485 /* check the format byte size */
2419 switch (fmt[5]) { 2486 printk(" XXXXX SAMPLE BYTES %d\n", sample_bytes);
2487 switch (sample_bytes) {
2420 case 1: 2488 case 1:
2421 pcm_format = SNDRV_PCM_FORMAT_S8; 2489 pcm_format = SNDRV_PCM_FORMAT_S8;
2422 break; 2490 break;
@@ -2437,12 +2505,12 @@ static int parse_audio_format_i_type(struct snd_usb_audio *chip, struct audiofor
2437 break; 2505 break;
2438 default: 2506 default:
2439 snd_printk(KERN_INFO "%d:%u:%d : unsupported sample bitwidth %d in %d bytes\n", 2507 snd_printk(KERN_INFO "%d:%u:%d : unsupported sample bitwidth %d in %d bytes\n",
2440 chip->dev->devnum, fp->iface, 2508 chip->dev->devnum, fp->iface, fp->altsetting,
2441 fp->altsetting, sample_width, sample_bytes); 2509 sample_width, sample_bytes);
2442 break; 2510 break;
2443 } 2511 }
2444 break; 2512 break;
2445 case USB_AUDIO_FORMAT_PCM8: 2513 case UAC_FORMAT_TYPE_I_PCM8:
2446 pcm_format = SNDRV_PCM_FORMAT_U8; 2514 pcm_format = SNDRV_PCM_FORMAT_U8;
2447 2515
2448 /* Dallas DS4201 workaround: it advertises U8 format, but really 2516 /* Dallas DS4201 workaround: it advertises U8 format, but really
@@ -2450,13 +2518,13 @@ static int parse_audio_format_i_type(struct snd_usb_audio *chip, struct audiofor
2450 if (chip->usb_id == USB_ID(0x04fa, 0x4201)) 2518 if (chip->usb_id == USB_ID(0x04fa, 0x4201))
2451 pcm_format = SNDRV_PCM_FORMAT_S8; 2519 pcm_format = SNDRV_PCM_FORMAT_S8;
2452 break; 2520 break;
2453 case USB_AUDIO_FORMAT_IEEE_FLOAT: 2521 case UAC_FORMAT_TYPE_I_IEEE_FLOAT:
2454 pcm_format = SNDRV_PCM_FORMAT_FLOAT_LE; 2522 pcm_format = SNDRV_PCM_FORMAT_FLOAT_LE;
2455 break; 2523 break;
2456 case USB_AUDIO_FORMAT_ALAW: 2524 case UAC_FORMAT_TYPE_I_ALAW:
2457 pcm_format = SNDRV_PCM_FORMAT_A_LAW; 2525 pcm_format = SNDRV_PCM_FORMAT_A_LAW;
2458 break; 2526 break;
2459 case USB_AUDIO_FORMAT_MU_LAW: 2527 case UAC_FORMAT_TYPE_I_MULAW:
2460 pcm_format = SNDRV_PCM_FORMAT_MU_LAW; 2528 pcm_format = SNDRV_PCM_FORMAT_MU_LAW;
2461 break; 2529 break;
2462 default: 2530 default:
@@ -2470,7 +2538,7 @@ static int parse_audio_format_i_type(struct snd_usb_audio *chip, struct audiofor
2470 2538
2471/* 2539/*
2472 * parse the format descriptor and stores the possible sample rates 2540 * parse the format descriptor and stores the possible sample rates
2473 * on the audioformat table. 2541 * on the audioformat table (audio class v1).
2474 * 2542 *
2475 * @dev: usb device 2543 * @dev: usb device
2476 * @fp: audioformat record 2544 * @fp: audioformat record
@@ -2478,13 +2546,13 @@ static int parse_audio_format_i_type(struct snd_usb_audio *chip, struct audiofor
2478 * @offset: the start offset of descriptor pointing the rate type 2546 * @offset: the start offset of descriptor pointing the rate type
2479 * (7 for type I and II, 8 for type II) 2547 * (7 for type I and II, 8 for type II)
2480 */ 2548 */
2481static int parse_audio_format_rates(struct snd_usb_audio *chip, struct audioformat *fp, 2549static int parse_audio_format_rates_v1(struct snd_usb_audio *chip, struct audioformat *fp,
2482 unsigned char *fmt, int offset) 2550 unsigned char *fmt, int offset)
2483{ 2551{
2484 int nr_rates = fmt[offset]; 2552 int nr_rates = fmt[offset];
2485 2553
2486 if (fmt[0] < offset + 1 + 3 * (nr_rates ? nr_rates : 2)) { 2554 if (fmt[0] < offset + 1 + 3 * (nr_rates ? nr_rates : 2)) {
2487 snd_printk(KERN_ERR "%d:%u:%d : invalid FORMAT_TYPE desc\n", 2555 snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n",
2488 chip->dev->devnum, fp->iface, fp->altsetting); 2556 chip->dev->devnum, fp->iface, fp->altsetting);
2489 return -1; 2557 return -1;
2490 } 2558 }
@@ -2535,14 +2603,87 @@ static int parse_audio_format_rates(struct snd_usb_audio *chip, struct audioform
2535} 2603}
2536 2604
2537/* 2605/*
2606 * parse the format descriptor and stores the possible sample rates
2607 * on the audioformat table (audio class v2).
2608 */
2609static int parse_audio_format_rates_v2(struct snd_usb_audio *chip,
2610 struct audioformat *fp,
2611 struct usb_host_interface *iface)
2612{
2613 struct usb_device *dev = chip->dev;
2614 unsigned char tmp[2], *data;
2615 int i, nr_rates, data_size, ret = 0;
2616
2617 /* get the number of sample rates first by only fetching 2 bytes */
2618 ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_RANGE,
2619 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
2620 0x0100, chip->clock_id << 8, tmp, sizeof(tmp), 1000);
2621
2622 if (ret < 0) {
2623 snd_printk(KERN_ERR "unable to retrieve number of sample rates\n");
2624 goto err;
2625 }
2626
2627 nr_rates = (tmp[1] << 8) | tmp[0];
2628 data_size = 2 + 12 * nr_rates;
2629 data = kzalloc(data_size, GFP_KERNEL);
2630 if (!data) {
2631 ret = -ENOMEM;
2632 goto err;
2633 }
2634
2635 /* now get the full information */
2636 ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_RANGE,
2637 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
2638 0x0100, chip->clock_id << 8, data, data_size, 1000);
2639
2640 if (ret < 0) {
2641 snd_printk(KERN_ERR "unable to retrieve sample rate range\n");
2642 ret = -EINVAL;
2643 goto err_free;
2644 }
2645
2646 fp->rate_table = kmalloc(sizeof(int) * nr_rates, GFP_KERNEL);
2647 if (!fp->rate_table) {
2648 ret = -ENOMEM;
2649 goto err_free;
2650 }
2651
2652 fp->nr_rates = 0;
2653 fp->rate_min = fp->rate_max = 0;
2654
2655 for (i = 0; i < nr_rates; i++) {
2656 int rate = combine_quad(&data[2 + 12 * i]);
2657
2658 fp->rate_table[fp->nr_rates] = rate;
2659 if (!fp->rate_min || rate < fp->rate_min)
2660 fp->rate_min = rate;
2661 if (!fp->rate_max || rate > fp->rate_max)
2662 fp->rate_max = rate;
2663 fp->rates |= snd_pcm_rate_to_rate_bit(rate);
2664 fp->nr_rates++;
2665 }
2666
2667err_free:
2668 kfree(data);
2669err:
2670 return ret;
2671}
2672
2673/*
2538 * parse the format type I and III descriptors 2674 * parse the format type I and III descriptors
2539 */ 2675 */
2540static int parse_audio_format_i(struct snd_usb_audio *chip, struct audioformat *fp, 2676static int parse_audio_format_i(struct snd_usb_audio *chip,
2541 int format, unsigned char *fmt) 2677 struct audioformat *fp,
2678 int format, void *_fmt,
2679 struct usb_host_interface *iface)
2542{ 2680{
2543 int pcm_format; 2681 struct usb_interface_descriptor *altsd = get_iface_desc(iface);
2682 struct uac_format_type_i_discrete_descriptor *fmt = _fmt;
2683 int protocol = altsd->bInterfaceProtocol;
2684 int pcm_format, ret;
2544 2685
2545 if (fmt[3] == USB_FORMAT_TYPE_III) { 2686 if (fmt->bFormatType == UAC_FORMAT_TYPE_III) {
2546 /* FIXME: the format type is really IECxxx 2687 /* FIXME: the format type is really IECxxx
2547 * but we give normal PCM format to get the existing 2688 * but we give normal PCM format to get the existing
2548 * apps working... 2689 * apps working...
@@ -2560,34 +2701,57 @@ static int parse_audio_format_i(struct snd_usb_audio *chip, struct audioformat *
2560 pcm_format = SNDRV_PCM_FORMAT_S16_LE; 2701 pcm_format = SNDRV_PCM_FORMAT_S16_LE;
2561 } 2702 }
2562 } else { 2703 } else {
2563 pcm_format = parse_audio_format_i_type(chip, fp, format, fmt); 2704 pcm_format = parse_audio_format_i_type(chip, fp, format, fmt, protocol);
2564 if (pcm_format < 0) 2705 if (pcm_format < 0)
2565 return -1; 2706 return -1;
2566 } 2707 }
2708
2567 fp->format = pcm_format; 2709 fp->format = pcm_format;
2568 fp->channels = fmt[4]; 2710
2711 /* gather possible sample rates */
2712 /* audio class v1 reports possible sample rates as part of the
2713 * proprietary class specific descriptor.
2714 * audio class v2 uses class specific EP0 range requests for that.
2715 */
2716 switch (protocol) {
2717 case UAC_VERSION_1:
2718 fp->channels = fmt->bNrChannels;
2719 ret = parse_audio_format_rates_v1(chip, fp, _fmt, 7);
2720 break;
2721 case UAC_VERSION_2:
2722 /* fp->channels is already set in this case */
2723 ret = parse_audio_format_rates_v2(chip, fp, iface);
2724 break;
2725 }
2726
2569 if (fp->channels < 1) { 2727 if (fp->channels < 1) {
2570 snd_printk(KERN_ERR "%d:%u:%d : invalid channels %d\n", 2728 snd_printk(KERN_ERR "%d:%u:%d : invalid channels %d\n",
2571 chip->dev->devnum, fp->iface, fp->altsetting, fp->channels); 2729 chip->dev->devnum, fp->iface, fp->altsetting, fp->channels);
2572 return -1; 2730 return -1;
2573 } 2731 }
2574 return parse_audio_format_rates(chip, fp, fmt, 7); 2732
2733 return ret;
2575} 2734}
2576 2735
2577/* 2736/*
2578 * prase the format type II descriptor 2737 * parse the format type II descriptor
2579 */ 2738 */
2580static int parse_audio_format_ii(struct snd_usb_audio *chip, struct audioformat *fp, 2739static int parse_audio_format_ii(struct snd_usb_audio *chip,
2581 int format, unsigned char *fmt) 2740 struct audioformat *fp,
2741 int format, void *_fmt,
2742 struct usb_host_interface *iface)
2582{ 2743{
2583 int brate, framesize; 2744 int brate, framesize, ret;
2745 struct usb_interface_descriptor *altsd = get_iface_desc(iface);
2746 int protocol = altsd->bInterfaceProtocol;
2747
2584 switch (format) { 2748 switch (format) {
2585 case USB_AUDIO_FORMAT_AC3: 2749 case UAC_FORMAT_TYPE_II_AC3:
2586 /* FIXME: there is no AC3 format defined yet */ 2750 /* FIXME: there is no AC3 format defined yet */
2587 // fp->format = SNDRV_PCM_FORMAT_AC3; 2751 // fp->format = SNDRV_PCM_FORMAT_AC3;
2588 fp->format = SNDRV_PCM_FORMAT_U8; /* temporarily hack to receive byte streams */ 2752 fp->format = SNDRV_PCM_FORMAT_U8; /* temporarily hack to receive byte streams */
2589 break; 2753 break;
2590 case USB_AUDIO_FORMAT_MPEG: 2754 case UAC_FORMAT_TYPE_II_MPEG:
2591 fp->format = SNDRV_PCM_FORMAT_MPEG; 2755 fp->format = SNDRV_PCM_FORMAT_MPEG;
2592 break; 2756 break;
2593 default: 2757 default:
@@ -2596,26 +2760,46 @@ static int parse_audio_format_ii(struct snd_usb_audio *chip, struct audioformat
2596 fp->format = SNDRV_PCM_FORMAT_MPEG; 2760 fp->format = SNDRV_PCM_FORMAT_MPEG;
2597 break; 2761 break;
2598 } 2762 }
2763
2599 fp->channels = 1; 2764 fp->channels = 1;
2600 brate = combine_word(&fmt[4]); /* fmt[4,5] : wMaxBitRate (in kbps) */ 2765
2601 framesize = combine_word(&fmt[6]); /* fmt[6,7]: wSamplesPerFrame */ 2766 switch (protocol) {
2602 snd_printd(KERN_INFO "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize); 2767 case UAC_VERSION_1: {
2603 fp->frame_size = framesize; 2768 struct uac_format_type_ii_discrete_descriptor *fmt = _fmt;
2604 return parse_audio_format_rates(chip, fp, fmt, 8); /* fmt[8..] sample rates */ 2769 brate = le16_to_cpu(fmt->wMaxBitRate);
2770 framesize = le16_to_cpu(fmt->wSamplesPerFrame);
2771 snd_printd(KERN_INFO "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize);
2772 fp->frame_size = framesize;
2773 ret = parse_audio_format_rates_v1(chip, fp, _fmt, 8); /* fmt[8..] sample rates */
2774 break;
2775 }
2776 case UAC_VERSION_2: {
2777 struct uac_format_type_ii_ext_descriptor *fmt = _fmt;
2778 brate = le16_to_cpu(fmt->wMaxBitRate);
2779 framesize = le16_to_cpu(fmt->wSamplesPerFrame);
2780 snd_printd(KERN_INFO "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize);
2781 fp->frame_size = framesize;
2782 ret = parse_audio_format_rates_v2(chip, fp, iface);
2783 break;
2784 }
2785 }
2786
2787 return ret;
2605} 2788}
2606 2789
2607static int parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp, 2790static int parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp,
2608 int format, unsigned char *fmt, int stream) 2791 int format, unsigned char *fmt, int stream,
2792 struct usb_host_interface *iface)
2609{ 2793{
2610 int err; 2794 int err;
2611 2795
2612 switch (fmt[3]) { 2796 switch (fmt[3]) {
2613 case USB_FORMAT_TYPE_I: 2797 case UAC_FORMAT_TYPE_I:
2614 case USB_FORMAT_TYPE_III: 2798 case UAC_FORMAT_TYPE_III:
2615 err = parse_audio_format_i(chip, fp, format, fmt); 2799 err = parse_audio_format_i(chip, fp, format, fmt, iface);
2616 break; 2800 break;
2617 case USB_FORMAT_TYPE_II: 2801 case UAC_FORMAT_TYPE_II:
2618 err = parse_audio_format_ii(chip, fp, format, fmt); 2802 err = parse_audio_format_ii(chip, fp, format, fmt, iface);
2619 break; 2803 break;
2620 default: 2804 default:
2621 snd_printd(KERN_INFO "%d:%u:%d : format type %d is not supported yet\n", 2805 snd_printd(KERN_INFO "%d:%u:%d : format type %d is not supported yet\n",
@@ -2633,7 +2817,7 @@ static int parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp
2633 if (chip->usb_id == USB_ID(0x041e, 0x3000) || 2817 if (chip->usb_id == USB_ID(0x041e, 0x3000) ||
2634 chip->usb_id == USB_ID(0x041e, 0x3020) || 2818 chip->usb_id == USB_ID(0x041e, 0x3020) ||
2635 chip->usb_id == USB_ID(0x041e, 0x3061)) { 2819 chip->usb_id == USB_ID(0x041e, 0x3061)) {
2636 if (fmt[3] == USB_FORMAT_TYPE_I && 2820 if (fmt[3] == UAC_FORMAT_TYPE_I &&
2637 fp->rates != SNDRV_PCM_RATE_48000 && 2821 fp->rates != SNDRV_PCM_RATE_48000 &&
2638 fp->rates != SNDRV_PCM_RATE_96000) 2822 fp->rates != SNDRV_PCM_RATE_96000)
2639 return -1; 2823 return -1;
@@ -2662,10 +2846,10 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
2662 struct usb_host_interface *alts; 2846 struct usb_host_interface *alts;
2663 struct usb_interface_descriptor *altsd; 2847 struct usb_interface_descriptor *altsd;
2664 int i, altno, err, stream; 2848 int i, altno, err, stream;
2665 int format; 2849 int format = 0, num_channels = 0;
2666 struct audioformat *fp = NULL; 2850 struct audioformat *fp = NULL;
2667 unsigned char *fmt, *csep; 2851 unsigned char *fmt, *csep;
2668 int num; 2852 int num, protocol;
2669 2853
2670 dev = chip->dev; 2854 dev = chip->dev;
2671 2855
@@ -2684,10 +2868,11 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
2684 for (i = 0; i < num; i++) { 2868 for (i = 0; i < num; i++) {
2685 alts = &iface->altsetting[i]; 2869 alts = &iface->altsetting[i];
2686 altsd = get_iface_desc(alts); 2870 altsd = get_iface_desc(alts);
2871 protocol = altsd->bInterfaceProtocol;
2687 /* skip invalid one */ 2872 /* skip invalid one */
2688 if ((altsd->bInterfaceClass != USB_CLASS_AUDIO && 2873 if ((altsd->bInterfaceClass != USB_CLASS_AUDIO &&
2689 altsd->bInterfaceClass != USB_CLASS_VENDOR_SPEC) || 2874 altsd->bInterfaceClass != USB_CLASS_VENDOR_SPEC) ||
2690 (altsd->bInterfaceSubClass != USB_SUBCLASS_AUDIO_STREAMING && 2875 (altsd->bInterfaceSubClass != USB_SUBCLASS_AUDIOSTREAMING &&
2691 altsd->bInterfaceSubClass != USB_SUBCLASS_VENDOR_SPEC) || 2876 altsd->bInterfaceSubClass != USB_SUBCLASS_VENDOR_SPEC) ||
2692 altsd->bNumEndpoints < 1 || 2877 altsd->bNumEndpoints < 1 ||
2693 le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) == 0) 2878 le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) == 0)
@@ -2708,30 +2893,65 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
2708 continue; 2893 continue;
2709 2894
2710 /* get audio formats */ 2895 /* get audio formats */
2711 fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, AS_GENERAL); 2896 switch (protocol) {
2712 if (!fmt) { 2897 case UAC_VERSION_1: {
2713 snd_printk(KERN_ERR "%d:%u:%d : AS_GENERAL descriptor not found\n", 2898 struct uac_as_header_descriptor_v1 *as =
2714 dev->devnum, iface_no, altno); 2899 snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL);
2715 continue; 2900
2901 if (!as) {
2902 snd_printk(KERN_ERR "%d:%u:%d : UAC_AS_GENERAL descriptor not found\n",
2903 dev->devnum, iface_no, altno);
2904 continue;
2905 }
2906
2907 if (as->bLength < sizeof(*as)) {
2908 snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_AS_GENERAL desc\n",
2909 dev->devnum, iface_no, altno);
2910 continue;
2911 }
2912
2913 format = le16_to_cpu(as->wFormatTag); /* remember the format value */
2914 break;
2716 } 2915 }
2717 2916
2718 if (fmt[0] < 7) { 2917 case UAC_VERSION_2: {
2719 snd_printk(KERN_ERR "%d:%u:%d : invalid AS_GENERAL desc\n", 2918 struct uac_as_header_descriptor_v2 *as =
2720 dev->devnum, iface_no, altno); 2919 snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL);
2721 continue; 2920
2921 if (!as) {
2922 snd_printk(KERN_ERR "%d:%u:%d : UAC_AS_GENERAL descriptor not found\n",
2923 dev->devnum, iface_no, altno);
2924 continue;
2925 }
2926
2927 if (as->bLength < sizeof(*as)) {
2928 snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_AS_GENERAL desc\n",
2929 dev->devnum, iface_no, altno);
2930 continue;
2931 }
2932
2933 num_channels = as->bNrChannels;
2934 format = le32_to_cpu(as->bmFormats);
2935
2936 break;
2722 } 2937 }
2723 2938
2724 format = (fmt[6] << 8) | fmt[5]; /* remember the format value */ 2939 default:
2940 snd_printk(KERN_ERR "%d:%u:%d : unknown interface protocol %04x\n",
2941 dev->devnum, iface_no, altno, protocol);
2942 continue;
2943 }
2725 2944
2726 /* get format type */ 2945 /* get format type */
2727 fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, FORMAT_TYPE); 2946 fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_FORMAT_TYPE);
2728 if (!fmt) { 2947 if (!fmt) {
2729 snd_printk(KERN_ERR "%d:%u:%d : no FORMAT_TYPE desc\n", 2948 snd_printk(KERN_ERR "%d:%u:%d : no UAC_FORMAT_TYPE desc\n",
2730 dev->devnum, iface_no, altno); 2949 dev->devnum, iface_no, altno);
2731 continue; 2950 continue;
2732 } 2951 }
2733 if (fmt[0] < 8) { 2952 if (((protocol == UAC_VERSION_1) && (fmt[0] < 8)) ||
2734 snd_printk(KERN_ERR "%d:%u:%d : invalid FORMAT_TYPE desc\n", 2953 ((protocol == UAC_VERSION_2) && (fmt[0] != 6))) {
2954 snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n",
2735 dev->devnum, iface_no, altno); 2955 dev->devnum, iface_no, altno);
2736 continue; 2956 continue;
2737 } 2957 }
@@ -2744,6 +2964,7 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
2744 if (fmt[4] == 1 && fmt[5] == 2 && altno == 2 && num == 3 && 2964 if (fmt[4] == 1 && fmt[5] == 2 && altno == 2 && num == 3 &&
2745 fp && fp->altsetting == 1 && fp->channels == 1 && 2965 fp && fp->altsetting == 1 && fp->channels == 1 &&
2746 fp->format == SNDRV_PCM_FORMAT_S16_LE && 2966 fp->format == SNDRV_PCM_FORMAT_S16_LE &&
2967 protocol == UAC_VERSION_1 &&
2747 le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) == 2968 le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) ==
2748 fp->maxpacksize * 2) 2969 fp->maxpacksize * 2)
2749 continue; 2970 continue;
@@ -2752,7 +2973,7 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
2752 /* Creamware Noah has this descriptor after the 2nd endpoint */ 2973 /* Creamware Noah has this descriptor after the 2nd endpoint */
2753 if (!csep && altsd->bNumEndpoints >= 2) 2974 if (!csep && altsd->bNumEndpoints >= 2)
2754 csep = snd_usb_find_desc(alts->endpoint[1].extra, alts->endpoint[1].extralen, NULL, USB_DT_CS_ENDPOINT); 2975 csep = snd_usb_find_desc(alts->endpoint[1].extra, alts->endpoint[1].extralen, NULL, USB_DT_CS_ENDPOINT);
2755 if (!csep || csep[0] < 7 || csep[2] != EP_GENERAL) { 2976 if (!csep || csep[0] < 7 || csep[2] != UAC_EP_GENERAL) {
2756 snd_printk(KERN_WARNING "%d:%u:%d : no or invalid" 2977 snd_printk(KERN_WARNING "%d:%u:%d : no or invalid"
2757 " class specific endpoint descriptor\n", 2978 " class specific endpoint descriptor\n",
2758 dev->devnum, iface_no, altno); 2979 dev->devnum, iface_no, altno);
@@ -2772,6 +2993,8 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
2772 fp->ep_attr = get_endpoint(alts, 0)->bmAttributes; 2993 fp->ep_attr = get_endpoint(alts, 0)->bmAttributes;
2773 fp->datainterval = parse_datainterval(chip, alts); 2994 fp->datainterval = parse_datainterval(chip, alts);
2774 fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize); 2995 fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
2996 /* num_channels is only set for v2 interfaces */
2997 fp->channels = num_channels;
2775 if (snd_usb_get_speed(dev) == USB_SPEED_HIGH) 2998 if (snd_usb_get_speed(dev) == USB_SPEED_HIGH)
2776 fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1) 2999 fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1)
2777 * (fp->maxpacksize & 0x7ff); 3000 * (fp->maxpacksize & 0x7ff);
@@ -2784,12 +3007,12 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
2784 /* Optoplay sets the sample rate attribute although 3007 /* Optoplay sets the sample rate attribute although
2785 * it seems not supporting it in fact. 3008 * it seems not supporting it in fact.
2786 */ 3009 */
2787 fp->attributes &= ~EP_CS_ATTR_SAMPLE_RATE; 3010 fp->attributes &= ~UAC_EP_CS_ATTR_SAMPLE_RATE;
2788 break; 3011 break;
2789 case USB_ID(0x041e, 0x3020): /* Creative SB Audigy 2 NX */ 3012 case USB_ID(0x041e, 0x3020): /* Creative SB Audigy 2 NX */
2790 case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */ 3013 case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
2791 /* doesn't set the sample rate attribute, but supports it */ 3014 /* doesn't set the sample rate attribute, but supports it */
2792 fp->attributes |= EP_CS_ATTR_SAMPLE_RATE; 3015 fp->attributes |= UAC_EP_CS_ATTR_SAMPLE_RATE;
2793 break; 3016 break;
2794 case USB_ID(0x047f, 0x0ca1): /* plantronics headset */ 3017 case USB_ID(0x047f, 0x0ca1): /* plantronics headset */
2795 case USB_ID(0x077d, 0x07af): /* Griffin iMic (note that there is 3018 case USB_ID(0x077d, 0x07af): /* Griffin iMic (note that there is
@@ -2798,16 +3021,16 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
2798 * plantronics headset and Griffin iMic have set adaptive-in 3021 * plantronics headset and Griffin iMic have set adaptive-in
2799 * although it's really not... 3022 * although it's really not...
2800 */ 3023 */
2801 fp->ep_attr &= ~EP_ATTR_MASK; 3024 fp->ep_attr &= ~USB_ENDPOINT_SYNCTYPE;
2802 if (stream == SNDRV_PCM_STREAM_PLAYBACK) 3025 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
2803 fp->ep_attr |= EP_ATTR_ADAPTIVE; 3026 fp->ep_attr |= USB_ENDPOINT_SYNC_ADAPTIVE;
2804 else 3027 else
2805 fp->ep_attr |= EP_ATTR_SYNC; 3028 fp->ep_attr |= USB_ENDPOINT_SYNC_SYNC;
2806 break; 3029 break;
2807 } 3030 }
2808 3031
2809 /* ok, let's parse further... */ 3032 /* ok, let's parse further... */
2810 if (parse_audio_format(chip, fp, format, fmt, stream) < 0) { 3033 if (parse_audio_format(chip, fp, format, fmt, stream, alts) < 0) {
2811 kfree(fp->rate_table); 3034 kfree(fp->rate_table);
2812 kfree(fp); 3035 kfree(fp);
2813 continue; 3036 continue;
@@ -2849,6 +3072,65 @@ static void snd_usb_stream_disconnect(struct list_head *head)
2849 } 3072 }
2850} 3073}
2851 3074
3075static int snd_usb_create_stream(struct snd_usb_audio *chip, int ctrlif, int interface)
3076{
3077 struct usb_device *dev = chip->dev;
3078 struct usb_host_interface *alts;
3079 struct usb_interface_descriptor *altsd;
3080 struct usb_interface *iface = usb_ifnum_to_if(dev, interface);
3081
3082 if (!iface) {
3083 snd_printk(KERN_ERR "%d:%u:%d : does not exist\n",
3084 dev->devnum, ctrlif, interface);
3085 return -EINVAL;
3086 }
3087
3088 if (usb_interface_claimed(iface)) {
3089 snd_printdd(KERN_INFO "%d:%d:%d: skipping, already claimed\n",
3090 dev->devnum, ctrlif, interface);
3091 return -EINVAL;
3092 }
3093
3094 alts = &iface->altsetting[0];
3095 altsd = get_iface_desc(alts);
3096 if ((altsd->bInterfaceClass == USB_CLASS_AUDIO ||
3097 altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC) &&
3098 altsd->bInterfaceSubClass == USB_SUBCLASS_MIDISTREAMING) {
3099 int err = snd_usbmidi_create(chip->card, iface,
3100 &chip->midi_list, NULL);
3101 if (err < 0) {
3102 snd_printk(KERN_ERR "%d:%u:%d: cannot create sequencer device\n",
3103 dev->devnum, ctrlif, interface);
3104 return -EINVAL;
3105 }
3106 usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L);
3107
3108 return 0;
3109 }
3110
3111 if ((altsd->bInterfaceClass != USB_CLASS_AUDIO &&
3112 altsd->bInterfaceClass != USB_CLASS_VENDOR_SPEC) ||
3113 altsd->bInterfaceSubClass != USB_SUBCLASS_AUDIOSTREAMING) {
3114 snd_printdd(KERN_ERR "%d:%u:%d: skipping non-supported interface %d\n",
3115 dev->devnum, ctrlif, interface, altsd->bInterfaceClass);
3116 /* skip non-supported classes */
3117 return -EINVAL;
3118 }
3119
3120 if (snd_usb_get_speed(dev) == USB_SPEED_LOW) {
3121 snd_printk(KERN_ERR "low speed audio streaming not supported\n");
3122 return -EINVAL;
3123 }
3124
3125 if (! parse_audio_endpoints(chip, interface)) {
3126 usb_set_interface(dev, interface, 0); /* reset the current interface */
3127 usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L);
3128 return -EINVAL;
3129 }
3130
3131 return 0;
3132}
3133
2852/* 3134/*
2853 * parse audio control descriptor and create pcm/midi streams 3135 * parse audio control descriptor and create pcm/midi streams
2854 */ 3136 */
@@ -2856,67 +3138,81 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
2856{ 3138{
2857 struct usb_device *dev = chip->dev; 3139 struct usb_device *dev = chip->dev;
2858 struct usb_host_interface *host_iface; 3140 struct usb_host_interface *host_iface;
2859 struct usb_interface *iface; 3141 struct usb_interface_descriptor *altsd;
2860 unsigned char *p1; 3142 void *control_header;
2861 int i, j; 3143 int i, protocol;
2862 3144
2863 /* find audiocontrol interface */ 3145 /* find audiocontrol interface */
2864 host_iface = &usb_ifnum_to_if(dev, ctrlif)->altsetting[0]; 3146 host_iface = &usb_ifnum_to_if(dev, ctrlif)->altsetting[0];
2865 if (!(p1 = snd_usb_find_csint_desc(host_iface->extra, host_iface->extralen, NULL, HEADER))) { 3147 control_header = snd_usb_find_csint_desc(host_iface->extra,
2866 snd_printk(KERN_ERR "cannot find HEADER\n"); 3148 host_iface->extralen,
2867 return -EINVAL; 3149 NULL, UAC_HEADER);
2868 } 3150 altsd = get_iface_desc(host_iface);
2869 if (! p1[7] || p1[0] < 8 + p1[7]) { 3151 protocol = altsd->bInterfaceProtocol;
2870 snd_printk(KERN_ERR "invalid HEADER\n"); 3152
3153 if (!control_header) {
3154 snd_printk(KERN_ERR "cannot find UAC_HEADER\n");
2871 return -EINVAL; 3155 return -EINVAL;
2872 } 3156 }
2873 3157
2874 /* 3158 switch (protocol) {
2875 * parse all USB audio streaming interfaces 3159 case UAC_VERSION_1: {
2876 */ 3160 struct uac_ac_header_descriptor_v1 *h1 = control_header;
2877 for (i = 0; i < p1[7]; i++) { 3161
2878 struct usb_host_interface *alts; 3162 if (!h1->bInCollection) {
2879 struct usb_interface_descriptor *altsd; 3163 snd_printk(KERN_INFO "skipping empty audio interface (v1)\n");
2880 j = p1[8 + i]; 3164 return -EINVAL;
2881 iface = usb_ifnum_to_if(dev, j);
2882 if (!iface) {
2883 snd_printk(KERN_ERR "%d:%u:%d : does not exist\n",
2884 dev->devnum, ctrlif, j);
2885 continue;
2886 }
2887 if (usb_interface_claimed(iface)) {
2888 snd_printdd(KERN_INFO "%d:%d:%d: skipping, already claimed\n", dev->devnum, ctrlif, j);
2889 continue;
2890 } 3165 }
2891 alts = &iface->altsetting[0]; 3166
2892 altsd = get_iface_desc(alts); 3167 if (h1->bLength < sizeof(*h1) + h1->bInCollection) {
2893 if ((altsd->bInterfaceClass == USB_CLASS_AUDIO || 3168 snd_printk(KERN_ERR "invalid UAC_HEADER (v1)\n");
2894 altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC) && 3169 return -EINVAL;
2895 altsd->bInterfaceSubClass == USB_SUBCLASS_MIDI_STREAMING) {
2896 int err = snd_usbmidi_create(chip->card, iface,
2897 &chip->midi_list, NULL);
2898 if (err < 0) {
2899 snd_printk(KERN_ERR "%d:%u:%d: cannot create sequencer device\n", dev->devnum, ctrlif, j);
2900 continue;
2901 }
2902 usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L);
2903 continue;
2904 } 3170 }
2905 if ((altsd->bInterfaceClass != USB_CLASS_AUDIO && 3171
2906 altsd->bInterfaceClass != USB_CLASS_VENDOR_SPEC) || 3172 for (i = 0; i < h1->bInCollection; i++)
2907 altsd->bInterfaceSubClass != USB_SUBCLASS_AUDIO_STREAMING) { 3173 snd_usb_create_stream(chip, ctrlif, h1->baInterfaceNr[i]);
2908 snd_printdd(KERN_ERR "%d:%u:%d: skipping non-supported interface %d\n", dev->devnum, ctrlif, j, altsd->bInterfaceClass); 3174
2909 /* skip non-supported classes */ 3175 break;
2910 continue; 3176 }
3177
3178 case UAC_VERSION_2: {
3179 struct uac_clock_source_descriptor *cs;
3180 struct usb_interface_assoc_descriptor *assoc =
3181 usb_ifnum_to_if(dev, ctrlif)->intf_assoc;
3182
3183 if (!assoc) {
3184 snd_printk(KERN_ERR "Audio class v2 interfaces need an interface association\n");
3185 return -EINVAL;
2911 } 3186 }
2912 if (snd_usb_get_speed(dev) == USB_SPEED_LOW) { 3187
2913 snd_printk(KERN_ERR "low speed audio streaming not supported\n"); 3188 /* FIXME: for now, we expect there is at least one clock source
2914 continue; 3189 * descriptor and we always take the first one.
3190 * We should properly support devices with multiple clock sources,
3191 * clock selectors and sample rate conversion units. */
3192
3193 cs = snd_usb_find_csint_desc(host_iface->extra, host_iface->extralen,
3194 NULL, UAC_CLOCK_SOURCE);
3195
3196 if (!cs) {
3197 snd_printk(KERN_ERR "CLOCK_SOURCE descriptor not found\n");
3198 return -EINVAL;
2915 } 3199 }
2916 if (! parse_audio_endpoints(chip, j)) { 3200
2917 usb_set_interface(dev, j, 0); /* reset the current interface */ 3201 chip->clock_id = cs->bClockID;
2918 usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L); 3202
3203 for (i = 0; i < assoc->bInterfaceCount; i++) {
3204 int intf = assoc->bFirstInterface + i;
3205
3206 if (intf != ctrlif)
3207 snd_usb_create_stream(chip, ctrlif, intf);
2919 } 3208 }
3209
3210 break;
3211 }
3212
3213 default:
3214 snd_printk(KERN_ERR "unknown protocol version 0x%02x\n", protocol);
3215 return -EINVAL;
2920 } 3216 }
2921 3217
2922 return 0; 3218 return 0;
@@ -3007,7 +3303,7 @@ static int create_uaxx_quirk(struct snd_usb_audio *chip,
3007 static const struct audioformat ua_format = { 3303 static const struct audioformat ua_format = {
3008 .format = SNDRV_PCM_FORMAT_S24_3LE, 3304 .format = SNDRV_PCM_FORMAT_S24_3LE,
3009 .channels = 2, 3305 .channels = 2,
3010 .fmt_type = USB_FORMAT_TYPE_I, 3306 .fmt_type = UAC_FORMAT_TYPE_I,
3011 .altsetting = 1, 3307 .altsetting = 1,
3012 .altset_idx = 1, 3308 .altset_idx = 1,
3013 .rates = SNDRV_PCM_RATE_CONTINUOUS, 3309 .rates = SNDRV_PCM_RATE_CONTINUOUS,
@@ -3099,7 +3395,7 @@ static int create_ua1000_quirk(struct snd_usb_audio *chip,
3099{ 3395{
3100 static const struct audioformat ua1000_format = { 3396 static const struct audioformat ua1000_format = {
3101 .format = SNDRV_PCM_FORMAT_S32_LE, 3397 .format = SNDRV_PCM_FORMAT_S32_LE,
3102 .fmt_type = USB_FORMAT_TYPE_I, 3398 .fmt_type = UAC_FORMAT_TYPE_I,
3103 .altsetting = 1, 3399 .altsetting = 1,
3104 .altset_idx = 1, 3400 .altset_idx = 1,
3105 .attributes = 0, 3401 .attributes = 0,
@@ -3142,59 +3438,6 @@ static int create_ua1000_quirk(struct snd_usb_audio *chip,
3142 return 0; 3438 return 0;
3143} 3439}
3144 3440
3145/*
3146 * Create a stream for an Edirol UA-101 interface.
3147 * Copy, paste and modify from Edirol UA-1000
3148 */
3149static int create_ua101_quirk(struct snd_usb_audio *chip,
3150 struct usb_interface *iface,
3151 const struct snd_usb_audio_quirk *quirk)
3152{
3153 static const struct audioformat ua101_format = {
3154 .format = SNDRV_PCM_FORMAT_S32_LE,
3155 .fmt_type = USB_FORMAT_TYPE_I,
3156 .altsetting = 1,
3157 .altset_idx = 1,
3158 .attributes = 0,
3159 .rates = SNDRV_PCM_RATE_CONTINUOUS,
3160 };
3161 struct usb_host_interface *alts;
3162 struct usb_interface_descriptor *altsd;
3163 struct audioformat *fp;
3164 int stream, err;
3165
3166 if (iface->num_altsetting != 2)
3167 return -ENXIO;
3168 alts = &iface->altsetting[1];
3169 altsd = get_iface_desc(alts);
3170 if (alts->extralen != 18 || alts->extra[1] != USB_DT_CS_INTERFACE ||
3171 altsd->bNumEndpoints != 1)
3172 return -ENXIO;
3173
3174 fp = kmemdup(&ua101_format, sizeof(*fp), GFP_KERNEL);
3175 if (!fp)
3176 return -ENOMEM;
3177
3178 fp->channels = alts->extra[11];
3179 fp->iface = altsd->bInterfaceNumber;
3180 fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress;
3181 fp->ep_attr = get_endpoint(alts, 0)->bmAttributes;
3182 fp->datainterval = parse_datainterval(chip, alts);
3183 fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
3184 fp->rate_max = fp->rate_min = combine_triple(&alts->extra[15]);
3185
3186 stream = (fp->endpoint & USB_DIR_IN)
3187 ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
3188 err = add_audio_endpoint(chip, stream, fp);
3189 if (err < 0) {
3190 kfree(fp);
3191 return err;
3192 }
3193 /* FIXME: playback must be synchronized to capture */
3194 usb_set_interface(chip->dev, fp->iface, 0);
3195 return 0;
3196}
3197
3198static int snd_usb_create_quirk(struct snd_usb_audio *chip, 3441static int snd_usb_create_quirk(struct snd_usb_audio *chip,
3199 struct usb_interface *iface, 3442 struct usb_interface *iface,
3200 const struct snd_usb_audio_quirk *quirk); 3443 const struct snd_usb_audio_quirk *quirk);
@@ -3232,6 +3475,18 @@ static int ignore_interface_quirk(struct snd_usb_audio *chip,
3232 return 0; 3475 return 0;
3233} 3476}
3234 3477
3478/*
3479 * Allow alignment on audio sub-slot (channel samples) rather than
3480 * on audio slots (audio frames)
3481 */
3482static int create_align_transfer_quirk(struct snd_usb_audio *chip,
3483 struct usb_interface *iface,
3484 const struct snd_usb_audio_quirk *quirk)
3485{
3486 chip->txfr_quirk = 1;
3487 return 1; /* Continue with creating streams and mixer */
3488}
3489
3235 3490
3236/* 3491/*
3237 * boot quirks 3492 * boot quirks
@@ -3327,6 +3582,32 @@ static int snd_usb_cm6206_boot_quirk(struct usb_device *dev)
3327} 3582}
3328 3583
3329/* 3584/*
3585 * This call will put the synth in "USB send" mode, i.e it will send MIDI
3586 * messages through USB (this is disabled at startup). The synth will
3587 * acknowledge by sending a sysex on endpoint 0x85 and by displaying a USB
3588 * sign on its LCD. Values here are chosen based on sniffing USB traffic
3589 * under Windows.
3590 */
3591static int snd_usb_accessmusic_boot_quirk(struct usb_device *dev)
3592{
3593 int err, actual_length;
3594
3595 /* "midi send" enable */
3596 static const u8 seq[] = { 0x4e, 0x73, 0x52, 0x01 };
3597
3598 void *buf = kmemdup(seq, ARRAY_SIZE(seq), GFP_KERNEL);
3599 if (!buf)
3600 return -ENOMEM;
3601 err = usb_interrupt_msg(dev, usb_sndintpipe(dev, 0x05), buf,
3602 ARRAY_SIZE(seq), &actual_length, 1000);
3603 kfree(buf);
3604 if (err < 0)
3605 return err;
3606
3607 return 0;
3608}
3609
3610/*
3330 * Setup quirks 3611 * Setup quirks
3331 */ 3612 */
3332#define AUDIOPHILE_SET 0x01 /* if set, parse device_setup */ 3613#define AUDIOPHILE_SET 0x01 /* if set, parse device_setup */
@@ -3406,8 +3687,8 @@ static int snd_usb_create_quirk(struct snd_usb_audio *chip,
3406 [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk, 3687 [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk,
3407 [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk, 3688 [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk,
3408 [QUIRK_AUDIO_EDIROL_UA1000] = create_ua1000_quirk, 3689 [QUIRK_AUDIO_EDIROL_UA1000] = create_ua1000_quirk,
3409 [QUIRK_AUDIO_EDIROL_UA101] = create_ua101_quirk, 3690 [QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk,
3410 [QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk 3691 [QUIRK_AUDIO_ALIGN_TRANSFER] = create_align_transfer_quirk
3411 }; 3692 };
3412 3693
3413 if (quirk->type < QUIRK_TYPE_COUNT) { 3694 if (quirk->type < QUIRK_TYPE_COUNT) {
@@ -3596,7 +3877,6 @@ static void *snd_usb_audio_probe(struct usb_device *dev,
3596 ifnum = get_iface_desc(alts)->bInterfaceNumber; 3877 ifnum = get_iface_desc(alts)->bInterfaceNumber;
3597 id = USB_ID(le16_to_cpu(dev->descriptor.idVendor), 3878 id = USB_ID(le16_to_cpu(dev->descriptor.idVendor),
3598 le16_to_cpu(dev->descriptor.idProduct)); 3879 le16_to_cpu(dev->descriptor.idProduct));
3599
3600 if (quirk && quirk->ifnum >= 0 && ifnum != quirk->ifnum) 3880 if (quirk && quirk->ifnum >= 0 && ifnum != quirk->ifnum)
3601 goto __err_val; 3881 goto __err_val;
3602 3882
@@ -3624,6 +3904,12 @@ static void *snd_usb_audio_probe(struct usb_device *dev,
3624 goto __err_val; 3904 goto __err_val;
3625 } 3905 }
3626 3906
3907 /* Access Music VirusTI Desktop */
3908 if (id == USB_ID(0x133e, 0x0815)) {
3909 if (snd_usb_accessmusic_boot_quirk(dev) < 0)
3910 goto __err_val;
3911 }
3912
3627 /* 3913 /*
3628 * found a config. now register to ALSA 3914 * found a config. now register to ALSA
3629 */ 3915 */
@@ -3661,6 +3947,7 @@ static void *snd_usb_audio_probe(struct usb_device *dev,
3661 } 3947 }
3662 } 3948 }
3663 3949
3950 chip->txfr_quirk = 0;
3664 err = 1; /* continue */ 3951 err = 1; /* continue */
3665 if (quirk && quirk->ifnum != QUIRK_NO_INTERFACE) { 3952 if (quirk && quirk->ifnum != QUIRK_NO_INTERFACE) {
3666 /* need some special handlings */ 3953 /* need some special handlings */
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
index 40ba8115fb81..6b016d4aac6b 100644
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -21,93 +21,6 @@
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */ 22 */
23 23
24
25/*
26 */
27
28#define USB_SUBCLASS_AUDIO_CONTROL 0x01
29#define USB_SUBCLASS_AUDIO_STREAMING 0x02
30#define USB_SUBCLASS_MIDI_STREAMING 0x03
31#define USB_SUBCLASS_VENDOR_SPEC 0xff
32
33#define HEADER 0x01
34#define INPUT_TERMINAL 0x02
35#define OUTPUT_TERMINAL 0x03
36#define MIXER_UNIT 0x04
37#define SELECTOR_UNIT 0x05
38#define FEATURE_UNIT 0x06
39#define PROCESSING_UNIT 0x07
40#define EXTENSION_UNIT 0x08
41
42#define AS_GENERAL 0x01
43#define FORMAT_TYPE 0x02
44#define FORMAT_SPECIFIC 0x03
45
46#define EP_GENERAL 0x01
47
48#define MS_GENERAL 0x01
49#define MIDI_IN_JACK 0x02
50#define MIDI_OUT_JACK 0x03
51
52/* endpoint attributes */
53#define EP_ATTR_MASK 0x0c
54#define EP_ATTR_ASYNC 0x04
55#define EP_ATTR_ADAPTIVE 0x08
56#define EP_ATTR_SYNC 0x0c
57
58/* cs endpoint attributes */
59#define EP_CS_ATTR_SAMPLE_RATE 0x01
60#define EP_CS_ATTR_PITCH_CONTROL 0x02
61#define EP_CS_ATTR_FILL_MAX 0x80
62
63/* Audio Class specific Request Codes */
64
65#define SET_CUR 0x01
66#define GET_CUR 0x81
67#define SET_MIN 0x02
68#define GET_MIN 0x82
69#define SET_MAX 0x03
70#define GET_MAX 0x83
71#define SET_RES 0x04
72#define GET_RES 0x84
73#define SET_MEM 0x05
74#define GET_MEM 0x85
75#define GET_STAT 0xff
76
77/* Terminal Control Selectors */
78
79#define COPY_PROTECT_CONTROL 0x01
80
81/* Endpoint Control Selectors */
82
83#define SAMPLING_FREQ_CONTROL 0x01
84#define PITCH_CONTROL 0x02
85
86/* Format Types */
87#define USB_FORMAT_TYPE_I 0x01
88#define USB_FORMAT_TYPE_II 0x02
89#define USB_FORMAT_TYPE_III 0x03
90
91/* type I */
92#define USB_AUDIO_FORMAT_PCM 0x01
93#define USB_AUDIO_FORMAT_PCM8 0x02
94#define USB_AUDIO_FORMAT_IEEE_FLOAT 0x03
95#define USB_AUDIO_FORMAT_ALAW 0x04
96#define USB_AUDIO_FORMAT_MU_LAW 0x05
97
98/* type II */
99#define USB_AUDIO_FORMAT_MPEG 0x1001
100#define USB_AUDIO_FORMAT_AC3 0x1002
101
102/* type III */
103#define USB_AUDIO_FORMAT_IEC1937_AC3 0x2001
104#define USB_AUDIO_FORMAT_IEC1937_MPEG1_LAYER1 0x2002
105#define USB_AUDIO_FORMAT_IEC1937_MPEG2_NOEXT 0x2003
106#define USB_AUDIO_FORMAT_IEC1937_MPEG2_EXT 0x2004
107#define USB_AUDIO_FORMAT_IEC1937_MPEG2_LAYER1_LS 0x2005
108#define USB_AUDIO_FORMAT_IEC1937_MPEG2_LAYER23_LS 0x2006
109
110
111/* maximum number of endpoints per interface */ 24/* maximum number of endpoints per interface */
112#define MIDI_MAX_ENDPOINTS 2 25#define MIDI_MAX_ENDPOINTS 2
113 26
@@ -125,9 +38,13 @@ struct snd_usb_audio {
125 struct snd_card *card; 38 struct snd_card *card;
126 u32 usb_id; 39 u32 usb_id;
127 int shutdown; 40 int shutdown;
41 unsigned int txfr_quirk:1; /* Subframe boundaries on transfers */
128 int num_interfaces; 42 int num_interfaces;
129 int num_suspended_intf; 43 int num_suspended_intf;
130 44
45 /* for audio class v2 */
46 int clock_id;
47
131 struct list_head pcm_list; /* list of pcm streams */ 48 struct list_head pcm_list; /* list of pcm streams */
132 int pcm_devs; 49 int pcm_devs;
133 50
@@ -159,8 +76,8 @@ enum quirk_type {
159 QUIRK_AUDIO_STANDARD_INTERFACE, 76 QUIRK_AUDIO_STANDARD_INTERFACE,
160 QUIRK_AUDIO_FIXED_ENDPOINT, 77 QUIRK_AUDIO_FIXED_ENDPOINT,
161 QUIRK_AUDIO_EDIROL_UA1000, 78 QUIRK_AUDIO_EDIROL_UA1000,
162 QUIRK_AUDIO_EDIROL_UA101,
163 QUIRK_AUDIO_EDIROL_UAXX, 79 QUIRK_AUDIO_EDIROL_UAXX,
80 QUIRK_AUDIO_ALIGN_TRANSFER,
164 81
165 QUIRK_TYPE_COUNT 82 QUIRK_TYPE_COUNT
166}; 83};
@@ -209,6 +126,16 @@ struct snd_usb_midi_endpoint_info {
209/* 126/*
210 */ 127 */
211 128
129/*E-mu USB samplerate control quirk*/
130enum {
131 EMU_QUIRK_SR_44100HZ = 0,
132 EMU_QUIRK_SR_48000HZ,
133 EMU_QUIRK_SR_88200HZ,
134 EMU_QUIRK_SR_96000HZ,
135 EMU_QUIRK_SR_176400HZ,
136 EMU_QUIRK_SR_192000HZ
137};
138
212#define combine_word(s) ((*(s)) | ((unsigned int)(s)[1] << 8)) 139#define combine_word(s) ((*(s)) | ((unsigned int)(s)[1] << 8))
213#define combine_triple(s) (combine_word(s) | ((unsigned int)(s)[2] << 16)) 140#define combine_triple(s) (combine_word(s) | ((unsigned int)(s)[2] << 16))
214#define combine_quad(s) (combine_triple(s) | ((unsigned int)(s)[3] << 24)) 141#define combine_quad(s) (combine_triple(s) | ((unsigned int)(s)[3] << 24))
@@ -234,6 +161,9 @@ void snd_usbmidi_input_stop(struct list_head* p);
234void snd_usbmidi_input_start(struct list_head* p); 161void snd_usbmidi_input_start(struct list_head* p);
235void snd_usbmidi_disconnect(struct list_head *p); 162void snd_usbmidi_disconnect(struct list_head *p);
236 163
164void snd_emuusb_set_samplerate(struct snd_usb_audio *chip,
165 unsigned char samplerate_id);
166
237/* 167/*
238 * retrieve usb_interface descriptor from the host interface 168 * retrieve usb_interface descriptor from the host interface
239 * (conditional for compatibility with the older API) 169 * (conditional for compatibility with the older API)
diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c
index 6e89b8368d9a..2c59afd99611 100644
--- a/sound/usb/usbmidi.c
+++ b/sound/usb/usbmidi.c
@@ -46,6 +46,8 @@
46#include <linux/timer.h> 46#include <linux/timer.h>
47#include <linux/usb.h> 47#include <linux/usb.h>
48#include <linux/wait.h> 48#include <linux/wait.h>
49#include <linux/usb/audio.h>
50
49#include <sound/core.h> 51#include <sound/core.h>
50#include <sound/control.h> 52#include <sound/control.h>
51#include <sound/rawmidi.h> 53#include <sound/rawmidi.h>
@@ -1162,10 +1164,22 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi* umidi,
1162 pipe = usb_sndintpipe(umidi->dev, ep_info->out_ep); 1164 pipe = usb_sndintpipe(umidi->dev, ep_info->out_ep);
1163 else 1165 else
1164 pipe = usb_sndbulkpipe(umidi->dev, ep_info->out_ep); 1166 pipe = usb_sndbulkpipe(umidi->dev, ep_info->out_ep);
1165 if (umidi->usb_id == USB_ID(0x0a92, 0x1020)) /* ESI M4U */ 1167 switch (umidi->usb_id) {
1166 ep->max_transfer = 4; 1168 default:
1167 else
1168 ep->max_transfer = usb_maxpacket(umidi->dev, pipe, 1); 1169 ep->max_transfer = usb_maxpacket(umidi->dev, pipe, 1);
1170 break;
1171 /*
1172 * Various chips declare a packet size larger than 4 bytes, but
1173 * do not actually work with larger packets:
1174 */
1175 case USB_ID(0x0a92, 0x1020): /* ESI M4U */
1176 case USB_ID(0x1430, 0x474b): /* RedOctane GH MIDI INTERFACE */
1177 case USB_ID(0x15ca, 0x0101): /* Textech USB Midi Cable */
1178 case USB_ID(0x15ca, 0x1806): /* Textech USB Midi Cable */
1179 case USB_ID(0x1a86, 0x752d): /* QinHeng CH345 "USB2.0-MIDI" */
1180 ep->max_transfer = 4;
1181 break;
1182 }
1169 for (i = 0; i < OUTPUT_URBS; ++i) { 1183 for (i = 0; i < OUTPUT_URBS; ++i) {
1170 buffer = usb_buffer_alloc(umidi->dev, 1184 buffer = usb_buffer_alloc(umidi->dev,
1171 ep->max_transfer, GFP_KERNEL, 1185 ep->max_transfer, GFP_KERNEL,
@@ -1407,6 +1421,12 @@ static struct port_info {
1407 EXTERNAL_PORT(0x086a, 0x0001, 8, "%s Broadcast"), 1421 EXTERNAL_PORT(0x086a, 0x0001, 8, "%s Broadcast"),
1408 EXTERNAL_PORT(0x086a, 0x0002, 8, "%s Broadcast"), 1422 EXTERNAL_PORT(0x086a, 0x0002, 8, "%s Broadcast"),
1409 EXTERNAL_PORT(0x086a, 0x0003, 4, "%s Broadcast"), 1423 EXTERNAL_PORT(0x086a, 0x0003, 4, "%s Broadcast"),
1424 /* Access Music Virus TI */
1425 EXTERNAL_PORT(0x133e, 0x0815, 0, "%s MIDI"),
1426 PORT_INFO(0x133e, 0x0815, 1, "%s Synth", 0,
1427 SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC |
1428 SNDRV_SEQ_PORT_TYPE_HARDWARE |
1429 SNDRV_SEQ_PORT_TYPE_SYNTHESIZER),
1410}; 1430};
1411 1431
1412static struct port_info *find_port_info(struct snd_usb_midi* umidi, int number) 1432static struct port_info *find_port_info(struct snd_usb_midi* umidi, int number)
@@ -1522,7 +1542,7 @@ static int snd_usbmidi_get_ms_info(struct snd_usb_midi* umidi,
1522 if (hostif->extralen >= 7 && 1542 if (hostif->extralen >= 7 &&
1523 ms_header->bLength >= 7 && 1543 ms_header->bLength >= 7 &&
1524 ms_header->bDescriptorType == USB_DT_CS_INTERFACE && 1544 ms_header->bDescriptorType == USB_DT_CS_INTERFACE &&
1525 ms_header->bDescriptorSubtype == HEADER) 1545 ms_header->bDescriptorSubtype == UAC_HEADER)
1526 snd_printdd(KERN_INFO "MIDIStreaming version %02x.%02x\n", 1546 snd_printdd(KERN_INFO "MIDIStreaming version %02x.%02x\n",
1527 ms_header->bcdMSC[1], ms_header->bcdMSC[0]); 1547 ms_header->bcdMSC[1], ms_header->bcdMSC[0]);
1528 else 1548 else
@@ -1538,7 +1558,7 @@ static int snd_usbmidi_get_ms_info(struct snd_usb_midi* umidi,
1538 if (hostep->extralen < 4 || 1558 if (hostep->extralen < 4 ||
1539 ms_ep->bLength < 4 || 1559 ms_ep->bLength < 4 ||
1540 ms_ep->bDescriptorType != USB_DT_CS_ENDPOINT || 1560 ms_ep->bDescriptorType != USB_DT_CS_ENDPOINT ||
1541 ms_ep->bDescriptorSubtype != MS_GENERAL) 1561 ms_ep->bDescriptorSubtype != UAC_MS_GENERAL)
1542 continue; 1562 continue;
1543 if (usb_endpoint_dir_out(ep)) { 1563 if (usb_endpoint_dir_out(ep)) {
1544 if (endpoints[epidx].out_ep) { 1564 if (endpoints[epidx].out_ep) {
@@ -1750,9 +1770,9 @@ static int snd_usbmidi_detect_yamaha(struct snd_usb_midi* umidi,
1750 cs_desc < hostif->extra + hostif->extralen && cs_desc[0] >= 2; 1770 cs_desc < hostif->extra + hostif->extralen && cs_desc[0] >= 2;
1751 cs_desc += cs_desc[0]) { 1771 cs_desc += cs_desc[0]) {
1752 if (cs_desc[1] == USB_DT_CS_INTERFACE) { 1772 if (cs_desc[1] == USB_DT_CS_INTERFACE) {
1753 if (cs_desc[2] == MIDI_IN_JACK) 1773 if (cs_desc[2] == UAC_MIDI_IN_JACK)
1754 endpoint->in_cables = (endpoint->in_cables << 1) | 1; 1774 endpoint->in_cables = (endpoint->in_cables << 1) | 1;
1755 else if (cs_desc[2] == MIDI_OUT_JACK) 1775 else if (cs_desc[2] == UAC_MIDI_OUT_JACK)
1756 endpoint->out_cables = (endpoint->out_cables << 1) | 1; 1776 endpoint->out_cables = (endpoint->out_cables << 1) | 1;
1757 } 1777 }
1758 } 1778 }
diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c
index c998220b99c6..8e8f871b74ca 100644
--- a/sound/usb/usbmixer.c
+++ b/sound/usb/usbmixer.c
@@ -32,6 +32,8 @@
32#include <linux/slab.h> 32#include <linux/slab.h>
33#include <linux/string.h> 33#include <linux/string.h>
34#include <linux/usb.h> 34#include <linux/usb.h>
35#include <linux/usb/audio.h>
36
35#include <sound/core.h> 37#include <sound/core.h>
36#include <sound/control.h> 38#include <sound/control.h>
37#include <sound/hwdep.h> 39#include <sound/hwdep.h>
@@ -69,13 +71,16 @@ static const struct rc_config {
69 { USB_ID(0x041e, 0x3048), 2, 2, 6, 6, 2, 0x6e91 }, /* Toshiba SB0500 */ 71 { USB_ID(0x041e, 0x3048), 2, 2, 6, 6, 2, 0x6e91 }, /* Toshiba SB0500 */
70}; 72};
71 73
74#define MAX_ID_ELEMS 256
75
72struct usb_mixer_interface { 76struct usb_mixer_interface {
73 struct snd_usb_audio *chip; 77 struct snd_usb_audio *chip;
74 unsigned int ctrlif; 78 unsigned int ctrlif;
75 struct list_head list; 79 struct list_head list;
76 unsigned int ignore_ctl_error; 80 unsigned int ignore_ctl_error;
77 struct urb *urb; 81 struct urb *urb;
78 struct usb_mixer_elem_info **id_elems; /* array[256], indexed by unit id */ 82 /* array[MAX_ID_ELEMS], indexed by unit id */
83 struct usb_mixer_elem_info **id_elems;
79 84
80 /* Sound Blaster remote control stuff */ 85 /* Sound Blaster remote control stuff */
81 const struct rc_config *rc_cfg; 86 const struct rc_config *rc_cfg;
@@ -105,7 +110,7 @@ struct mixer_build {
105 struct usb_mixer_interface *mixer; 110 struct usb_mixer_interface *mixer;
106 unsigned char *buffer; 111 unsigned char *buffer;
107 unsigned int buflen; 112 unsigned int buflen;
108 DECLARE_BITMAP(unitbitmap, 256); 113 DECLARE_BITMAP(unitbitmap, MAX_ID_ELEMS);
109 struct usb_audio_term oterm; 114 struct usb_audio_term oterm;
110 const struct usbmix_name_map *map; 115 const struct usbmix_name_map *map;
111 const struct usbmix_selector_map *selector_map; 116 const struct usbmix_selector_map *selector_map;
@@ -123,6 +128,7 @@ struct usb_mixer_elem_info {
123 int channels; 128 int channels;
124 int val_type; 129 int val_type;
125 int min, max, res; 130 int min, max, res;
131 int dBmin, dBmax;
126 int cached; 132 int cached;
127 int cache_val[MAX_CHANNELS]; 133 int cache_val[MAX_CHANNELS];
128 u8 initialized; 134 u8 initialized;
@@ -186,6 +192,21 @@ enum {
186 USB_PROC_DCR_RELEASE = 6, 192 USB_PROC_DCR_RELEASE = 6,
187}; 193};
188 194
195/*E-mu 0202(0404) eXtension Unit(XU) control*/
196enum {
197 USB_XU_CLOCK_RATE = 0xe301,
198 USB_XU_CLOCK_SOURCE = 0xe302,
199 USB_XU_DIGITAL_IO_STATUS = 0xe303,
200 USB_XU_DEVICE_OPTIONS = 0xe304,
201 USB_XU_DIRECT_MONITORING = 0xe305,
202 USB_XU_METERING = 0xe306
203};
204enum {
205 USB_XU_CLOCK_SOURCE_SELECTOR = 0x02, /* clock source*/
206 USB_XU_CLOCK_RATE_SELECTOR = 0x03, /* clock rate */
207 USB_XU_DIGITAL_FORMAT_SELECTOR = 0x01, /* the spdif format */
208 USB_XU_SOFT_LIMIT_SELECTOR = 0x03 /* soft limiter */
209};
189 210
190/* 211/*
191 * manual mapping of mixer names 212 * manual mapping of mixer names
@@ -194,42 +215,50 @@ enum {
194 */ 215 */
195#include "usbmixer_maps.c" 216#include "usbmixer_maps.c"
196 217
197/* get the mapped name if the unit matches */ 218static const struct usbmix_name_map *
198static int check_mapped_name(struct mixer_build *state, int unitid, int control, char *buf, int buflen) 219find_map(struct mixer_build *state, int unitid, int control)
199{ 220{
200 const struct usbmix_name_map *p; 221 const struct usbmix_name_map *p = state->map;
201 222
202 if (! state->map) 223 if (!p)
203 return 0; 224 return NULL;
204 225
205 for (p = state->map; p->id; p++) { 226 for (p = state->map; p->id; p++) {
206 if (p->id == unitid && p->name && 227 if (p->id == unitid &&
207 (! control || ! p->control || control == p->control)) { 228 (!control || !p->control || control == p->control))
208 buflen--; 229 return p;
209 return strlcpy(buf, p->name, buflen);
210 }
211 } 230 }
212 return 0; 231 return NULL;
213} 232}
214 233
215/* check whether the control should be ignored */ 234/* get the mapped name if the unit matches */
216static int check_ignored_ctl(struct mixer_build *state, int unitid, int control) 235static int
236check_mapped_name(const struct usbmix_name_map *p, char *buf, int buflen)
217{ 237{
218 const struct usbmix_name_map *p; 238 if (!p || !p->name)
239 return 0;
240
241 buflen--;
242 return strlcpy(buf, p->name, buflen);
243}
219 244
220 if (! state->map) 245/* check whether the control should be ignored */
246static inline int
247check_ignored_ctl(const struct usbmix_name_map *p)
248{
249 if (!p || p->name || p->dB)
221 return 0; 250 return 0;
222 for (p = state->map; p->id; p++) { 251 return 1;
223 if (p->id == unitid && ! p->name && 252}
224 (! control || ! p->control || control == p->control)) { 253
225 /* 254/* dB mapping */
226 printk(KERN_DEBUG "ignored control %d:%d\n", 255static inline void check_mapped_dB(const struct usbmix_name_map *p,
227 unitid, control); 256 struct usb_mixer_elem_info *cval)
228 */ 257{
229 return 1; 258 if (p && p->dB) {
230 } 259 cval->dBmin = p->dB->min;
260 cval->dBmax = p->dB->max;
231 } 261 }
232 return 0;
233} 262}
234 263
235/* get the mapped selector source name */ 264/* get the mapped selector source name */
@@ -257,7 +286,7 @@ static void *find_audio_control_unit(struct mixer_build *state, unsigned char un
257 p = NULL; 286 p = NULL;
258 while ((p = snd_usb_find_desc(state->buffer, state->buflen, p, 287 while ((p = snd_usb_find_desc(state->buffer, state->buflen, p,
259 USB_DT_CS_INTERFACE)) != NULL) { 288 USB_DT_CS_INTERFACE)) != NULL) {
260 if (p[0] >= 4 && p[2] >= INPUT_TERMINAL && p[2] <= EXTENSION_UNIT && p[3] == unit) 289 if (p[0] >= 4 && p[2] >= UAC_INPUT_TERMINAL && p[2] <= UAC_EXTENSION_UNIT_V1 && p[3] == unit)
261 return p; 290 return p;
262 } 291 }
263 return NULL; 292 return NULL;
@@ -378,14 +407,14 @@ static int get_ctl_value(struct usb_mixer_elem_info *cval, int request, int vali
378 407
379static int get_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int *value) 408static int get_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int *value)
380{ 409{
381 return get_ctl_value(cval, GET_CUR, validx, value); 410 return get_ctl_value(cval, UAC_GET_CUR, validx, value);
382} 411}
383 412
384/* channel = 0: master, 1 = first channel */ 413/* channel = 0: master, 1 = first channel */
385static inline int get_cur_mix_raw(struct usb_mixer_elem_info *cval, 414static inline int get_cur_mix_raw(struct usb_mixer_elem_info *cval,
386 int channel, int *value) 415 int channel, int *value)
387{ 416{
388 return get_ctl_value(cval, GET_CUR, (cval->control << 8) | channel, value); 417 return get_ctl_value(cval, UAC_GET_CUR, (cval->control << 8) | channel, value);
389} 418}
390 419
391static int get_cur_mix_value(struct usb_mixer_elem_info *cval, 420static int get_cur_mix_value(struct usb_mixer_elem_info *cval,
@@ -439,14 +468,14 @@ static int set_ctl_value(struct usb_mixer_elem_info *cval, int request, int vali
439 468
440static int set_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int value) 469static int set_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int value)
441{ 470{
442 return set_ctl_value(cval, SET_CUR, validx, value); 471 return set_ctl_value(cval, UAC_SET_CUR, validx, value);
443} 472}
444 473
445static int set_cur_mix_value(struct usb_mixer_elem_info *cval, int channel, 474static int set_cur_mix_value(struct usb_mixer_elem_info *cval, int channel,
446 int index, int value) 475 int index, int value)
447{ 476{
448 int err; 477 int err;
449 err = set_ctl_value(cval, SET_CUR, (cval->control << 8) | channel, 478 err = set_ctl_value(cval, UAC_SET_CUR, (cval->control << 8) | channel,
450 value); 479 value);
451 if (err < 0) 480 if (err < 0)
452 return err; 481 return err;
@@ -466,20 +495,8 @@ static int mixer_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
466 495
467 if (size < sizeof(scale)) 496 if (size < sizeof(scale))
468 return -ENOMEM; 497 return -ENOMEM;
469 /* USB descriptions contain the dB scale in 1/256 dB unit 498 scale[2] = cval->dBmin;
470 * while ALSA TLV contains in 1/100 dB unit 499 scale[3] = cval->dBmax;
471 */
472 scale[2] = (convert_signed_value(cval, cval->min) * 100) / 256;
473 scale[3] = (convert_signed_value(cval, cval->max) * 100) / 256;
474 if (scale[3] <= scale[2]) {
475 /* something is wrong; assume it's either from/to 0dB */
476 if (scale[2] < 0)
477 scale[3] = 0;
478 else if (scale[2] > 0)
479 scale[2] = 0;
480 else /* totally crap, return an error */
481 return -EINVAL;
482 }
483 if (copy_to_user(_tlv, scale, sizeof(scale))) 500 if (copy_to_user(_tlv, scale, sizeof(scale)))
484 return -EFAULT; 501 return -EFAULT;
485 return 0; 502 return 0;
@@ -588,13 +605,13 @@ static int get_term_name(struct mixer_build *state, struct usb_audio_term *iterm
588 if (term_only) 605 if (term_only)
589 return 0; 606 return 0;
590 switch (iterm->type >> 16) { 607 switch (iterm->type >> 16) {
591 case SELECTOR_UNIT: 608 case UAC_SELECTOR_UNIT:
592 strcpy(name, "Selector"); return 8; 609 strcpy(name, "Selector"); return 8;
593 case PROCESSING_UNIT: 610 case UAC_PROCESSING_UNIT_V1:
594 strcpy(name, "Process Unit"); return 12; 611 strcpy(name, "Process Unit"); return 12;
595 case EXTENSION_UNIT: 612 case UAC_EXTENSION_UNIT_V1:
596 strcpy(name, "Ext Unit"); return 8; 613 strcpy(name, "Ext Unit"); return 8;
597 case MIXER_UNIT: 614 case UAC_MIXER_UNIT:
598 strcpy(name, "Mixer"); return 5; 615 strcpy(name, "Mixer"); return 5;
599 default: 616 default:
600 return sprintf(name, "Unit %d", iterm->id); 617 return sprintf(name, "Unit %d", iterm->id);
@@ -633,22 +650,22 @@ static int check_input_term(struct mixer_build *state, int id, struct usb_audio_
633 while ((p1 = find_audio_control_unit(state, id)) != NULL) { 650 while ((p1 = find_audio_control_unit(state, id)) != NULL) {
634 term->id = id; 651 term->id = id;
635 switch (p1[2]) { 652 switch (p1[2]) {
636 case INPUT_TERMINAL: 653 case UAC_INPUT_TERMINAL:
637 term->type = combine_word(p1 + 4); 654 term->type = combine_word(p1 + 4);
638 term->channels = p1[7]; 655 term->channels = p1[7];
639 term->chconfig = combine_word(p1 + 8); 656 term->chconfig = combine_word(p1 + 8);
640 term->name = p1[11]; 657 term->name = p1[11];
641 return 0; 658 return 0;
642 case FEATURE_UNIT: 659 case UAC_FEATURE_UNIT:
643 id = p1[4]; 660 id = p1[4];
644 break; /* continue to parse */ 661 break; /* continue to parse */
645 case MIXER_UNIT: 662 case UAC_MIXER_UNIT:
646 term->type = p1[2] << 16; /* virtual type */ 663 term->type = p1[2] << 16; /* virtual type */
647 term->channels = p1[5 + p1[4]]; 664 term->channels = p1[5 + p1[4]];
648 term->chconfig = combine_word(p1 + 6 + p1[4]); 665 term->chconfig = combine_word(p1 + 6 + p1[4]);
649 term->name = p1[p1[0] - 1]; 666 term->name = p1[p1[0] - 1];
650 return 0; 667 return 0;
651 case SELECTOR_UNIT: 668 case UAC_SELECTOR_UNIT:
652 /* call recursively to retrieve the channel info */ 669 /* call recursively to retrieve the channel info */
653 if (check_input_term(state, p1[5], term) < 0) 670 if (check_input_term(state, p1[5], term) < 0)
654 return -ENODEV; 671 return -ENODEV;
@@ -656,8 +673,8 @@ static int check_input_term(struct mixer_build *state, int id, struct usb_audio_
656 term->id = id; 673 term->id = id;
657 term->name = p1[9 + p1[0] - 1]; 674 term->name = p1[9 + p1[0] - 1];
658 return 0; 675 return 0;
659 case PROCESSING_UNIT: 676 case UAC_PROCESSING_UNIT_V1:
660 case EXTENSION_UNIT: 677 case UAC_EXTENSION_UNIT_V1:
661 if (p1[6] == 1) { 678 if (p1[6] == 1) {
662 id = p1[7]; 679 id = p1[7];
663 break; /* continue to parse */ 680 break; /* continue to parse */
@@ -720,6 +737,7 @@ static int get_min_max(struct usb_mixer_elem_info *cval, int default_min)
720 cval->min = default_min; 737 cval->min = default_min;
721 cval->max = cval->min + 1; 738 cval->max = cval->min + 1;
722 cval->res = 1; 739 cval->res = 1;
740 cval->dBmin = cval->dBmax = 0;
723 741
724 if (cval->val_type == USB_MIXER_BOOLEAN || 742 if (cval->val_type == USB_MIXER_BOOLEAN ||
725 cval->val_type == USB_MIXER_INV_BOOLEAN) { 743 cval->val_type == USB_MIXER_INV_BOOLEAN) {
@@ -734,23 +752,23 @@ static int get_min_max(struct usb_mixer_elem_info *cval, int default_min)
734 break; 752 break;
735 } 753 }
736 } 754 }
737 if (get_ctl_value(cval, GET_MAX, (cval->control << 8) | minchn, &cval->max) < 0 || 755 if (get_ctl_value(cval, UAC_GET_MAX, (cval->control << 8) | minchn, &cval->max) < 0 ||
738 get_ctl_value(cval, GET_MIN, (cval->control << 8) | minchn, &cval->min) < 0) { 756 get_ctl_value(cval, UAC_GET_MIN, (cval->control << 8) | minchn, &cval->min) < 0) {
739 snd_printd(KERN_ERR "%d:%d: cannot get min/max values for control %d (id %d)\n", 757 snd_printd(KERN_ERR "%d:%d: cannot get min/max values for control %d (id %d)\n",
740 cval->id, cval->mixer->ctrlif, cval->control, cval->id); 758 cval->id, cval->mixer->ctrlif, cval->control, cval->id);
741 return -EINVAL; 759 return -EINVAL;
742 } 760 }
743 if (get_ctl_value(cval, GET_RES, (cval->control << 8) | minchn, &cval->res) < 0) { 761 if (get_ctl_value(cval, UAC_GET_RES, (cval->control << 8) | minchn, &cval->res) < 0) {
744 cval->res = 1; 762 cval->res = 1;
745 } else { 763 } else {
746 int last_valid_res = cval->res; 764 int last_valid_res = cval->res;
747 765
748 while (cval->res > 1) { 766 while (cval->res > 1) {
749 if (set_ctl_value(cval, SET_RES, (cval->control << 8) | minchn, cval->res / 2) < 0) 767 if (set_ctl_value(cval, UAC_SET_RES, (cval->control << 8) | minchn, cval->res / 2) < 0)
750 break; 768 break;
751 cval->res /= 2; 769 cval->res /= 2;
752 } 770 }
753 if (get_ctl_value(cval, GET_RES, (cval->control << 8) | minchn, &cval->res) < 0) 771 if (get_ctl_value(cval, UAC_GET_RES, (cval->control << 8) | minchn, &cval->res) < 0)
754 cval->res = last_valid_res; 772 cval->res = last_valid_res;
755 } 773 }
756 if (cval->res == 0) 774 if (cval->res == 0)
@@ -787,6 +805,24 @@ static int get_min_max(struct usb_mixer_elem_info *cval, int default_min)
787 805
788 cval->initialized = 1; 806 cval->initialized = 1;
789 } 807 }
808
809 /* USB descriptions contain the dB scale in 1/256 dB unit
810 * while ALSA TLV contains in 1/100 dB unit
811 */
812 cval->dBmin = (convert_signed_value(cval, cval->min) * 100) / 256;
813 cval->dBmax = (convert_signed_value(cval, cval->max) * 100) / 256;
814 if (cval->dBmin > cval->dBmax) {
815 /* something is wrong; assume it's either from/to 0dB */
816 if (cval->dBmin < 0)
817 cval->dBmax = 0;
818 else if (cval->dBmin > 0)
819 cval->dBmin = 0;
820 if (cval->dBmin > cval->dBmax) {
821 /* totally crap, return an error */
822 return -EINVAL;
823 }
824 }
825
790 return 0; 826 return 0;
791} 827}
792 828
@@ -912,6 +948,7 @@ static void build_feature_ctl(struct mixer_build *state, unsigned char *desc,
912 int nameid = desc[desc[0] - 1]; 948 int nameid = desc[desc[0] - 1];
913 struct snd_kcontrol *kctl; 949 struct snd_kcontrol *kctl;
914 struct usb_mixer_elem_info *cval; 950 struct usb_mixer_elem_info *cval;
951 const struct usbmix_name_map *map;
915 952
916 control++; /* change from zero-based to 1-based value */ 953 control++; /* change from zero-based to 1-based value */
917 954
@@ -920,7 +957,8 @@ static void build_feature_ctl(struct mixer_build *state, unsigned char *desc,
920 return; 957 return;
921 } 958 }
922 959
923 if (check_ignored_ctl(state, unitid, control)) 960 map = find_map(state, unitid, control);
961 if (check_ignored_ctl(map))
924 return; 962 return;
925 963
926 cval = kzalloc(sizeof(*cval), GFP_KERNEL); 964 cval = kzalloc(sizeof(*cval), GFP_KERNEL);
@@ -954,10 +992,11 @@ static void build_feature_ctl(struct mixer_build *state, unsigned char *desc,
954 } 992 }
955 kctl->private_free = usb_mixer_elem_free; 993 kctl->private_free = usb_mixer_elem_free;
956 994
957 len = check_mapped_name(state, unitid, control, kctl->id.name, sizeof(kctl->id.name)); 995 len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name));
958 mapped_name = len != 0; 996 mapped_name = len != 0;
959 if (! len && nameid) 997 if (! len && nameid)
960 len = snd_usb_copy_string_desc(state, nameid, kctl->id.name, sizeof(kctl->id.name)); 998 len = snd_usb_copy_string_desc(state, nameid,
999 kctl->id.name, sizeof(kctl->id.name));
961 1000
962 switch (control) { 1001 switch (control) {
963 case USB_FEATURE_MUTE: 1002 case USB_FEATURE_MUTE:
@@ -995,6 +1034,7 @@ static void build_feature_ctl(struct mixer_build *state, unsigned char *desc,
995 kctl->vd[0].access |= 1034 kctl->vd[0].access |=
996 SNDRV_CTL_ELEM_ACCESS_TLV_READ | 1035 SNDRV_CTL_ELEM_ACCESS_TLV_READ |
997 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK; 1036 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
1037 check_mapped_dB(map, cval);
998 } 1038 }
999 break; 1039 break;
1000 1040
@@ -1048,29 +1088,30 @@ static void build_feature_ctl(struct mixer_build *state, unsigned char *desc,
1048 * 1088 *
1049 * most of controlls are defined here. 1089 * most of controlls are defined here.
1050 */ 1090 */
1051static int parse_audio_feature_unit(struct mixer_build *state, int unitid, unsigned char *ftr) 1091static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void *_ftr)
1052{ 1092{
1053 int channels, i, j; 1093 int channels, i, j;
1054 struct usb_audio_term iterm; 1094 struct usb_audio_term iterm;
1055 unsigned int master_bits, first_ch_bits; 1095 unsigned int master_bits, first_ch_bits;
1056 int err, csize; 1096 int err, csize;
1097 struct uac_feature_unit_descriptor *ftr = _ftr;
1057 1098
1058 if (ftr[0] < 7 || ! (csize = ftr[5]) || ftr[0] < 7 + csize) { 1099 if (ftr->bLength < 7 || ! (csize = ftr->bControlSize) || ftr->bLength < 7 + csize) {
1059 snd_printk(KERN_ERR "usbaudio: unit %u: invalid FEATURE_UNIT descriptor\n", unitid); 1100 snd_printk(KERN_ERR "usbaudio: unit %u: invalid UAC_FEATURE_UNIT descriptor\n", unitid);
1060 return -EINVAL; 1101 return -EINVAL;
1061 } 1102 }
1062 1103
1063 /* parse the source unit */ 1104 /* parse the source unit */
1064 if ((err = parse_audio_unit(state, ftr[4])) < 0) 1105 if ((err = parse_audio_unit(state, ftr->bSourceID)) < 0)
1065 return err; 1106 return err;
1066 1107
1067 /* determine the input source type and name */ 1108 /* determine the input source type and name */
1068 if (check_input_term(state, ftr[4], &iterm) < 0) 1109 if (check_input_term(state, ftr->bSourceID, &iterm) < 0)
1069 return -EINVAL; 1110 return -EINVAL;
1070 1111
1071 channels = (ftr[0] - 7) / csize - 1; 1112 channels = (ftr->bLength - 7) / csize - 1;
1072 1113
1073 master_bits = snd_usb_combine_bytes(ftr + 6, csize); 1114 master_bits = snd_usb_combine_bytes(ftr->controls, csize);
1074 /* master configuration quirks */ 1115 /* master configuration quirks */
1075 switch (state->chip->usb_id) { 1116 switch (state->chip->usb_id) {
1076 case USB_ID(0x08bb, 0x2702): 1117 case USB_ID(0x08bb, 0x2702):
@@ -1081,21 +1122,21 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, unsig
1081 break; 1122 break;
1082 } 1123 }
1083 if (channels > 0) 1124 if (channels > 0)
1084 first_ch_bits = snd_usb_combine_bytes(ftr + 6 + csize, csize); 1125 first_ch_bits = snd_usb_combine_bytes(ftr->controls + csize, csize);
1085 else 1126 else
1086 first_ch_bits = 0; 1127 first_ch_bits = 0;
1087 /* check all control types */ 1128 /* check all control types */
1088 for (i = 0; i < 10; i++) { 1129 for (i = 0; i < 10; i++) {
1089 unsigned int ch_bits = 0; 1130 unsigned int ch_bits = 0;
1090 for (j = 0; j < channels; j++) { 1131 for (j = 0; j < channels; j++) {
1091 unsigned int mask = snd_usb_combine_bytes(ftr + 6 + csize * (j+1), csize); 1132 unsigned int mask = snd_usb_combine_bytes(ftr->controls + csize * (j+1), csize);
1092 if (mask & (1 << i)) 1133 if (mask & (1 << i))
1093 ch_bits |= (1 << j); 1134 ch_bits |= (1 << j);
1094 } 1135 }
1095 if (ch_bits & 1) /* the first channel must be set (for ease of programming) */ 1136 if (ch_bits & 1) /* the first channel must be set (for ease of programming) */
1096 build_feature_ctl(state, ftr, ch_bits, i, &iterm, unitid); 1137 build_feature_ctl(state, _ftr, ch_bits, i, &iterm, unitid);
1097 if (master_bits & (1 << i)) 1138 if (master_bits & (1 << i))
1098 build_feature_ctl(state, ftr, 0, i, &iterm, unitid); 1139 build_feature_ctl(state, _ftr, 0, i, &iterm, unitid);
1099 } 1140 }
1100 1141
1101 return 0; 1142 return 0;
@@ -1122,8 +1163,10 @@ static void build_mixer_unit_ctl(struct mixer_build *state, unsigned char *desc,
1122 unsigned int num_outs = desc[5 + input_pins]; 1163 unsigned int num_outs = desc[5 + input_pins];
1123 unsigned int i, len; 1164 unsigned int i, len;
1124 struct snd_kcontrol *kctl; 1165 struct snd_kcontrol *kctl;
1166 const struct usbmix_name_map *map;
1125 1167
1126 if (check_ignored_ctl(state, unitid, 0)) 1168 map = find_map(state, unitid, 0);
1169 if (check_ignored_ctl(map))
1127 return; 1170 return;
1128 1171
1129 cval = kzalloc(sizeof(*cval), GFP_KERNEL); 1172 cval = kzalloc(sizeof(*cval), GFP_KERNEL);
@@ -1152,7 +1195,7 @@ static void build_mixer_unit_ctl(struct mixer_build *state, unsigned char *desc,
1152 } 1195 }
1153 kctl->private_free = usb_mixer_elem_free; 1196 kctl->private_free = usb_mixer_elem_free;
1154 1197
1155 len = check_mapped_name(state, unitid, 0, kctl->id.name, sizeof(kctl->id.name)); 1198 len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name));
1156 if (! len) 1199 if (! len)
1157 len = get_term_name(state, iterm, kctl->id.name, sizeof(kctl->id.name), 0); 1200 len = get_term_name(state, iterm, kctl->id.name, sizeof(kctl->id.name), 0);
1158 if (! len) 1201 if (! len)
@@ -1330,7 +1373,32 @@ static struct procunit_info procunits[] = {
1330 { USB_PROC_DCR, "DCR", dcr_proc_info }, 1373 { USB_PROC_DCR, "DCR", dcr_proc_info },
1331 { 0 }, 1374 { 0 },
1332}; 1375};
1333 1376/*
1377 * predefined data for extension units
1378 */
1379static struct procunit_value_info clock_rate_xu_info[] = {
1380 { USB_XU_CLOCK_RATE_SELECTOR, "Selector", USB_MIXER_U8, 0 },
1381 { 0 }
1382};
1383static struct procunit_value_info clock_source_xu_info[] = {
1384 { USB_XU_CLOCK_SOURCE_SELECTOR, "External", USB_MIXER_BOOLEAN },
1385 { 0 }
1386};
1387static struct procunit_value_info spdif_format_xu_info[] = {
1388 { USB_XU_DIGITAL_FORMAT_SELECTOR, "SPDIF/AC3", USB_MIXER_BOOLEAN },
1389 { 0 }
1390};
1391static struct procunit_value_info soft_limit_xu_info[] = {
1392 { USB_XU_SOFT_LIMIT_SELECTOR, " ", USB_MIXER_BOOLEAN },
1393 { 0 }
1394};
1395static struct procunit_info extunits[] = {
1396 { USB_XU_CLOCK_RATE, "Clock rate", clock_rate_xu_info },
1397 { USB_XU_CLOCK_SOURCE, "DigitalIn CLK source", clock_source_xu_info },
1398 { USB_XU_DIGITAL_IO_STATUS, "DigitalOut format:", spdif_format_xu_info },
1399 { USB_XU_DEVICE_OPTIONS, "AnalogueIn Soft Limit", soft_limit_xu_info },
1400 { 0 }
1401};
1334/* 1402/*
1335 * build a processing/extension unit 1403 * build a processing/extension unit
1336 */ 1404 */
@@ -1342,6 +1410,7 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned
1342 int i, err, nameid, type, len; 1410 int i, err, nameid, type, len;
1343 struct procunit_info *info; 1411 struct procunit_info *info;
1344 struct procunit_value_info *valinfo; 1412 struct procunit_value_info *valinfo;
1413 const struct usbmix_name_map *map;
1345 static struct procunit_value_info default_value_info[] = { 1414 static struct procunit_value_info default_value_info[] = {
1346 { 0x01, "Switch", USB_MIXER_BOOLEAN }, 1415 { 0x01, "Switch", USB_MIXER_BOOLEAN },
1347 { 0 } 1416 { 0 }
@@ -1371,7 +1440,8 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned
1371 /* FIXME: bitmap might be longer than 8bit */ 1440 /* FIXME: bitmap might be longer than 8bit */
1372 if (! (dsc[12 + num_ins] & (1 << (valinfo->control - 1)))) 1441 if (! (dsc[12 + num_ins] & (1 << (valinfo->control - 1))))
1373 continue; 1442 continue;
1374 if (check_ignored_ctl(state, unitid, valinfo->control)) 1443 map = find_map(state, unitid, valinfo->control);
1444 if (check_ignored_ctl(map))
1375 continue; 1445 continue;
1376 cval = kzalloc(sizeof(*cval), GFP_KERNEL); 1446 cval = kzalloc(sizeof(*cval), GFP_KERNEL);
1377 if (! cval) { 1447 if (! cval) {
@@ -1391,8 +1461,18 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned
1391 cval->max = dsc[15]; 1461 cval->max = dsc[15];
1392 cval->res = 1; 1462 cval->res = 1;
1393 cval->initialized = 1; 1463 cval->initialized = 1;
1394 } else 1464 } else {
1395 get_min_max(cval, valinfo->min_value); 1465 if (type == USB_XU_CLOCK_RATE) {
1466 /* E-Mu USB 0404/0202/TrackerPre
1467 * samplerate control quirk
1468 */
1469 cval->min = 0;
1470 cval->max = 5;
1471 cval->res = 1;
1472 cval->initialized = 1;
1473 } else
1474 get_min_max(cval, valinfo->min_value);
1475 }
1396 1476
1397 kctl = snd_ctl_new1(&mixer_procunit_ctl, cval); 1477 kctl = snd_ctl_new1(&mixer_procunit_ctl, cval);
1398 if (! kctl) { 1478 if (! kctl) {
@@ -1402,8 +1482,9 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned
1402 } 1482 }
1403 kctl->private_free = usb_mixer_elem_free; 1483 kctl->private_free = usb_mixer_elem_free;
1404 1484
1405 if (check_mapped_name(state, unitid, cval->control, kctl->id.name, sizeof(kctl->id.name))) 1485 if (check_mapped_name(map, kctl->id.name,
1406 ; 1486 sizeof(kctl->id.name)))
1487 /* nothing */ ;
1407 else if (info->name) 1488 else if (info->name)
1408 strlcpy(kctl->id.name, info->name, sizeof(kctl->id.name)); 1489 strlcpy(kctl->id.name, info->name, sizeof(kctl->id.name));
1409 else { 1490 else {
@@ -1433,7 +1514,7 @@ static int parse_audio_processing_unit(struct mixer_build *state, int unitid, un
1433 1514
1434static int parse_audio_extension_unit(struct mixer_build *state, int unitid, unsigned char *desc) 1515static int parse_audio_extension_unit(struct mixer_build *state, int unitid, unsigned char *desc)
1435{ 1516{
1436 return build_audio_procunit(state, unitid, desc, NULL, "Extension Unit"); 1517 return build_audio_procunit(state, unitid, desc, extunits, "Extension Unit");
1437} 1518}
1438 1519
1439 1520
@@ -1542,6 +1623,7 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsi
1542 int err; 1623 int err;
1543 struct usb_mixer_elem_info *cval; 1624 struct usb_mixer_elem_info *cval;
1544 struct snd_kcontrol *kctl; 1625 struct snd_kcontrol *kctl;
1626 const struct usbmix_name_map *map;
1545 char **namelist; 1627 char **namelist;
1546 1628
1547 if (! num_ins || desc[0] < 5 + num_ins) { 1629 if (! num_ins || desc[0] < 5 + num_ins) {
@@ -1557,7 +1639,8 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsi
1557 if (num_ins == 1) /* only one ? nonsense! */ 1639 if (num_ins == 1) /* only one ? nonsense! */
1558 return 0; 1640 return 0;
1559 1641
1560 if (check_ignored_ctl(state, unitid, 0)) 1642 map = find_map(state, unitid, 0);
1643 if (check_ignored_ctl(map))
1561 return 0; 1644 return 0;
1562 1645
1563 cval = kzalloc(sizeof(*cval), GFP_KERNEL); 1646 cval = kzalloc(sizeof(*cval), GFP_KERNEL);
@@ -1612,7 +1695,7 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsi
1612 kctl->private_free = usb_mixer_selector_elem_free; 1695 kctl->private_free = usb_mixer_selector_elem_free;
1613 1696
1614 nameid = desc[desc[0] - 1]; 1697 nameid = desc[desc[0] - 1];
1615 len = check_mapped_name(state, unitid, 0, kctl->id.name, sizeof(kctl->id.name)); 1698 len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name));
1616 if (len) 1699 if (len)
1617 ; 1700 ;
1618 else if (nameid) 1701 else if (nameid)
@@ -1656,17 +1739,17 @@ static int parse_audio_unit(struct mixer_build *state, int unitid)
1656 } 1739 }
1657 1740
1658 switch (p1[2]) { 1741 switch (p1[2]) {
1659 case INPUT_TERMINAL: 1742 case UAC_INPUT_TERMINAL:
1660 return 0; /* NOP */ 1743 return 0; /* NOP */
1661 case MIXER_UNIT: 1744 case UAC_MIXER_UNIT:
1662 return parse_audio_mixer_unit(state, unitid, p1); 1745 return parse_audio_mixer_unit(state, unitid, p1);
1663 case SELECTOR_UNIT: 1746 case UAC_SELECTOR_UNIT:
1664 return parse_audio_selector_unit(state, unitid, p1); 1747 return parse_audio_selector_unit(state, unitid, p1);
1665 case FEATURE_UNIT: 1748 case UAC_FEATURE_UNIT:
1666 return parse_audio_feature_unit(state, unitid, p1); 1749 return parse_audio_feature_unit(state, unitid, p1);
1667 case PROCESSING_UNIT: 1750 case UAC_PROCESSING_UNIT_V1:
1668 return parse_audio_processing_unit(state, unitid, p1); 1751 return parse_audio_processing_unit(state, unitid, p1);
1669 case EXTENSION_UNIT: 1752 case UAC_EXTENSION_UNIT_V1:
1670 return parse_audio_extension_unit(state, unitid, p1); 1753 return parse_audio_extension_unit(state, unitid, p1);
1671 default: 1754 default:
1672 snd_printk(KERN_ERR "usbaudio: unit %u: unexpected type 0x%02x\n", unitid, p1[2]); 1755 snd_printk(KERN_ERR "usbaudio: unit %u: unexpected type 0x%02x\n", unitid, p1[2]);
@@ -1696,11 +1779,11 @@ static int snd_usb_mixer_dev_free(struct snd_device *device)
1696/* 1779/*
1697 * create mixer controls 1780 * create mixer controls
1698 * 1781 *
1699 * walk through all OUTPUT_TERMINAL descriptors to search for mixers 1782 * walk through all UAC_OUTPUT_TERMINAL descriptors to search for mixers
1700 */ 1783 */
1701static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer) 1784static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
1702{ 1785{
1703 unsigned char *desc; 1786 struct uac_output_terminal_descriptor_v1 *desc;
1704 struct mixer_build state; 1787 struct mixer_build state;
1705 int err; 1788 int err;
1706 const struct usbmix_ctl_map *map; 1789 const struct usbmix_ctl_map *map;
@@ -1724,14 +1807,14 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
1724 } 1807 }
1725 1808
1726 desc = NULL; 1809 desc = NULL;
1727 while ((desc = snd_usb_find_csint_desc(hostif->extra, hostif->extralen, desc, OUTPUT_TERMINAL)) != NULL) { 1810 while ((desc = snd_usb_find_csint_desc(hostif->extra, hostif->extralen, desc, UAC_OUTPUT_TERMINAL)) != NULL) {
1728 if (desc[0] < 9) 1811 if (desc->bLength < 9)
1729 continue; /* invalid descriptor? */ 1812 continue; /* invalid descriptor? */
1730 set_bit(desc[3], state.unitbitmap); /* mark terminal ID as visited */ 1813 set_bit(desc->bTerminalID, state.unitbitmap); /* mark terminal ID as visited */
1731 state.oterm.id = desc[3]; 1814 state.oterm.id = desc->bTerminalID;
1732 state.oterm.type = combine_word(&desc[4]); 1815 state.oterm.type = le16_to_cpu(desc->wTerminalType);
1733 state.oterm.name = desc[8]; 1816 state.oterm.name = desc->iTerminal;
1734 err = parse_audio_unit(&state, desc[7]); 1817 err = parse_audio_unit(&state, desc->bSourceID);
1735 if (err < 0) 1818 if (err < 0)
1736 return err; 1819 return err;
1737 } 1820 }
@@ -1748,6 +1831,46 @@ static void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer,
1748 info->elem_id); 1831 info->elem_id);
1749} 1832}
1750 1833
1834static void snd_usb_mixer_dump_cval(struct snd_info_buffer *buffer,
1835 int unitid,
1836 struct usb_mixer_elem_info *cval)
1837{
1838 static char *val_types[] = {"BOOLEAN", "INV_BOOLEAN",
1839 "S8", "U8", "S16", "U16"};
1840 snd_iprintf(buffer, " Unit: %i\n", unitid);
1841 if (cval->elem_id)
1842 snd_iprintf(buffer, " Control: name=\"%s\", index=%i\n",
1843 cval->elem_id->name, cval->elem_id->index);
1844 snd_iprintf(buffer, " Info: id=%i, control=%i, cmask=0x%x, "
1845 "channels=%i, type=\"%s\"\n", cval->id,
1846 cval->control, cval->cmask, cval->channels,
1847 val_types[cval->val_type]);
1848 snd_iprintf(buffer, " Volume: min=%i, max=%i, dBmin=%i, dBmax=%i\n",
1849 cval->min, cval->max, cval->dBmin, cval->dBmax);
1850}
1851
1852static void snd_usb_mixer_proc_read(struct snd_info_entry *entry,
1853 struct snd_info_buffer *buffer)
1854{
1855 struct snd_usb_audio *chip = entry->private_data;
1856 struct usb_mixer_interface *mixer;
1857 struct usb_mixer_elem_info *cval;
1858 int unitid;
1859
1860 list_for_each_entry(mixer, &chip->mixer_list, list) {
1861 snd_iprintf(buffer,
1862 "USB Mixer: usb_id=0x%08x, ctrlif=%i, ctlerr=%i\n",
1863 chip->usb_id, mixer->ctrlif,
1864 mixer->ignore_ctl_error);
1865 snd_iprintf(buffer, "Card: %s\n", chip->card->longname);
1866 for (unitid = 0; unitid < MAX_ID_ELEMS; unitid++) {
1867 for (cval = mixer->id_elems[unitid]; cval;
1868 cval = cval->next_id_elem)
1869 snd_usb_mixer_dump_cval(buffer, unitid, cval);
1870 }
1871 }
1872}
1873
1751static void snd_usb_mixer_memory_change(struct usb_mixer_interface *mixer, 1874static void snd_usb_mixer_memory_change(struct usb_mixer_interface *mixer,
1752 int unitid) 1875 int unitid)
1753{ 1876{
@@ -1924,7 +2047,7 @@ static int snd_usb_soundblaster_remote_init(struct usb_mixer_interface *mixer)
1924 } 2047 }
1925 mixer->rc_setup_packet->bRequestType = 2048 mixer->rc_setup_packet->bRequestType =
1926 USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE; 2049 USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
1927 mixer->rc_setup_packet->bRequest = GET_MEM; 2050 mixer->rc_setup_packet->bRequest = UAC_GET_MEM;
1928 mixer->rc_setup_packet->wValue = cpu_to_le16(0); 2051 mixer->rc_setup_packet->wValue = cpu_to_le16(0);
1929 mixer->rc_setup_packet->wIndex = cpu_to_le16(0); 2052 mixer->rc_setup_packet->wIndex = cpu_to_le16(0);
1930 mixer->rc_setup_packet->wLength = cpu_to_le16(len); 2053 mixer->rc_setup_packet->wLength = cpu_to_le16(len);
@@ -2047,7 +2170,7 @@ static void snd_audigy2nx_proc_read(struct snd_info_entry *entry,
2047 snd_iprintf(buffer, "%s: ", jacks[i].name); 2170 snd_iprintf(buffer, "%s: ", jacks[i].name);
2048 err = snd_usb_ctl_msg(mixer->chip->dev, 2171 err = snd_usb_ctl_msg(mixer->chip->dev,
2049 usb_rcvctrlpipe(mixer->chip->dev, 0), 2172 usb_rcvctrlpipe(mixer->chip->dev, 0),
2050 GET_MEM, USB_DIR_IN | USB_TYPE_CLASS | 2173 UAC_GET_MEM, USB_DIR_IN | USB_TYPE_CLASS |
2051 USB_RECIP_INTERFACE, 0, 2174 USB_RECIP_INTERFACE, 0,
2052 jacks[i].unitid << 8, buf, 3, 100); 2175 jacks[i].unitid << 8, buf, 3, 100);
2053 if (err == 3 && (buf[0] == 3 || buf[0] == 6)) 2176 if (err == 3 && (buf[0] == 3 || buf[0] == 6))
@@ -2109,6 +2232,24 @@ static int snd_xonar_u1_controls_create(struct usb_mixer_interface *mixer)
2109 return 0; 2232 return 0;
2110} 2233}
2111 2234
2235void snd_emuusb_set_samplerate(struct snd_usb_audio *chip,
2236 unsigned char samplerate_id)
2237{
2238 struct usb_mixer_interface *mixer;
2239 struct usb_mixer_elem_info *cval;
2240 int unitid = 12; /* SamleRate ExtensionUnit ID */
2241
2242 list_for_each_entry(mixer, &chip->mixer_list, list) {
2243 cval = mixer->id_elems[unitid];
2244 if (cval) {
2245 set_cur_ctl_value(cval, cval->control << 8,
2246 samplerate_id);
2247 snd_usb_mixer_notify_id(mixer, unitid);
2248 }
2249 break;
2250 }
2251}
2252
2112int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif, 2253int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
2113 int ignore_error) 2254 int ignore_error)
2114{ 2255{
@@ -2116,7 +2257,9 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
2116 .dev_free = snd_usb_mixer_dev_free 2257 .dev_free = snd_usb_mixer_dev_free
2117 }; 2258 };
2118 struct usb_mixer_interface *mixer; 2259 struct usb_mixer_interface *mixer;
2119 int err; 2260 struct snd_info_entry *entry;
2261 struct usb_host_interface *host_iface;
2262 int err, protocol;
2120 2263
2121 strcpy(chip->card->mixername, "USB Mixer"); 2264 strcpy(chip->card->mixername, "USB Mixer");
2122 2265
@@ -2126,12 +2269,23 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
2126 mixer->chip = chip; 2269 mixer->chip = chip;
2127 mixer->ctrlif = ctrlif; 2270 mixer->ctrlif = ctrlif;
2128 mixer->ignore_ctl_error = ignore_error; 2271 mixer->ignore_ctl_error = ignore_error;
2129 mixer->id_elems = kcalloc(256, sizeof(*mixer->id_elems), GFP_KERNEL); 2272 mixer->id_elems = kcalloc(MAX_ID_ELEMS, sizeof(*mixer->id_elems),
2273 GFP_KERNEL);
2130 if (!mixer->id_elems) { 2274 if (!mixer->id_elems) {
2131 kfree(mixer); 2275 kfree(mixer);
2132 return -ENOMEM; 2276 return -ENOMEM;
2133 } 2277 }
2134 2278
2279 host_iface = &usb_ifnum_to_if(chip->dev, ctrlif)->altsetting[0];
2280 protocol = host_iface->desc.bInterfaceProtocol;
2281
2282 /* FIXME! */
2283 if (protocol != UAC_VERSION_1) {
2284 snd_printk(KERN_WARNING "mixer interface protocol 0x%02x not yet supported\n",
2285 protocol);
2286 return 0;
2287 }
2288
2135 if ((err = snd_usb_mixer_controls(mixer)) < 0 || 2289 if ((err = snd_usb_mixer_controls(mixer)) < 0 ||
2136 (err = snd_usb_mixer_status_create(mixer)) < 0) 2290 (err = snd_usb_mixer_status_create(mixer)) < 0)
2137 goto _error; 2291 goto _error;
@@ -2142,8 +2296,6 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
2142 if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020) || 2296 if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020) ||
2143 mixer->chip->usb_id == USB_ID(0x041e, 0x3040) || 2297 mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
2144 mixer->chip->usb_id == USB_ID(0x041e, 0x3048)) { 2298 mixer->chip->usb_id == USB_ID(0x041e, 0x3048)) {
2145 struct snd_info_entry *entry;
2146
2147 if ((err = snd_audigy2nx_controls_create(mixer)) < 0) 2299 if ((err = snd_audigy2nx_controls_create(mixer)) < 0)
2148 goto _error; 2300 goto _error;
2149 if (!snd_card_proc_new(chip->card, "audigy2nx", &entry)) 2301 if (!snd_card_proc_new(chip->card, "audigy2nx", &entry))
@@ -2161,6 +2313,11 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
2161 err = snd_device_new(chip->card, SNDRV_DEV_LOWLEVEL, mixer, &dev_ops); 2313 err = snd_device_new(chip->card, SNDRV_DEV_LOWLEVEL, mixer, &dev_ops);
2162 if (err < 0) 2314 if (err < 0)
2163 goto _error; 2315 goto _error;
2316
2317 if (list_empty(&chip->mixer_list) &&
2318 !snd_card_proc_new(chip->card, "usbmixer", &entry))
2319 snd_info_set_text_ops(entry, chip, snd_usb_mixer_proc_read);
2320
2164 list_add(&mixer->list, &chip->mixer_list); 2321 list_add(&mixer->list, &chip->mixer_list);
2165 return 0; 2322 return 0;
2166 2323
diff --git a/sound/usb/usbmixer_maps.c b/sound/usb/usbmixer_maps.c
index 77c35885e21c..79e903a60862 100644
--- a/sound/usb/usbmixer_maps.c
+++ b/sound/usb/usbmixer_maps.c
@@ -19,11 +19,16 @@
19 * 19 *
20 */ 20 */
21 21
22struct usbmix_dB_map {
23 u32 min;
24 u32 max;
25};
22 26
23struct usbmix_name_map { 27struct usbmix_name_map {
24 int id; 28 int id;
25 const char *name; 29 const char *name;
26 int control; 30 int control;
31 struct usbmix_dB_map *dB;
27}; 32};
28 33
29struct usbmix_selector_map { 34struct usbmix_selector_map {
@@ -72,7 +77,7 @@ static struct usbmix_name_map extigy_map[] = {
72 { 8, "Line Playback" }, /* FU */ 77 { 8, "Line Playback" }, /* FU */
73 /* 9: IT mic */ 78 /* 9: IT mic */
74 { 10, "Mic Playback" }, /* FU */ 79 { 10, "Mic Playback" }, /* FU */
75 { 11, "Capture Input Source" }, /* SU */ 80 { 11, "Capture Source" }, /* SU */
76 { 12, "Capture" }, /* FU */ 81 { 12, "Capture" }, /* FU */
77 /* 13: OT pcm capture */ 82 /* 13: OT pcm capture */
78 /* 14: MU (w/o controls) */ 83 /* 14: MU (w/o controls) */
@@ -102,6 +107,9 @@ static struct usbmix_name_map extigy_map[] = {
102 * e.g. no Master and fake PCM volume 107 * e.g. no Master and fake PCM volume
103 * Pavel Mihaylov <bin@bash.info> 108 * Pavel Mihaylov <bin@bash.info>
104 */ 109 */
110static struct usbmix_dB_map mp3plus_dB_1 = {-4781, 0}; /* just guess */
111static struct usbmix_dB_map mp3plus_dB_2 = {-1781, 618}; /* just guess */
112
105static struct usbmix_name_map mp3plus_map[] = { 113static struct usbmix_name_map mp3plus_map[] = {
106 /* 1: IT pcm */ 114 /* 1: IT pcm */
107 /* 2: IT mic */ 115 /* 2: IT mic */
@@ -110,16 +118,19 @@ static struct usbmix_name_map mp3plus_map[] = {
110 /* 5: OT digital out */ 118 /* 5: OT digital out */
111 /* 6: OT speaker */ 119 /* 6: OT speaker */
112 /* 7: OT pcm capture */ 120 /* 7: OT pcm capture */
113 { 8, "Capture Input Source" }, /* FU, default PCM Capture Source */ 121 { 8, "Capture Source" }, /* FU, default PCM Capture Source */
114 /* (Mic, Input 1 = Line input, Input 2 = Optical input) */ 122 /* (Mic, Input 1 = Line input, Input 2 = Optical input) */
115 { 9, "Master Playback" }, /* FU, default Speaker 1 */ 123 { 9, "Master Playback" }, /* FU, default Speaker 1 */
116 /* { 10, "Mic Capture", 1 }, */ /* FU, Mic Capture */ 124 /* { 10, "Mic Capture", 1 }, */ /* FU, Mic Capture */
117 /* { 10, "Mic Capture", 2 }, */ /* FU, Mic Capture */ 125 { 10, /* "Mic Capture", */ NULL, 2, .dB = &mp3plus_dB_2 },
126 /* FU, Mic Capture */
118 { 10, "Mic Boost", 7 }, /* FU, default Auto Gain Input */ 127 { 10, "Mic Boost", 7 }, /* FU, default Auto Gain Input */
119 { 11, "Line Capture" }, /* FU, default PCM Capture */ 128 { 11, "Line Capture", .dB = &mp3plus_dB_2 },
129 /* FU, default PCM Capture */
120 { 12, "Digital In Playback" }, /* FU, default PCM 1 */ 130 { 12, "Digital In Playback" }, /* FU, default PCM 1 */
121 /* { 13, "Mic Playback" }, */ /* FU, default Mic Playback */ 131 { 13, /* "Mic Playback", */ .dB = &mp3plus_dB_1 },
122 { 14, "Line Playback" }, /* FU, default Speaker */ 132 /* FU, default Mic Playback */
133 { 14, "Line Playback", .dB = &mp3plus_dB_1 }, /* FU, default Speaker */
123 /* 15: MU */ 134 /* 15: MU */
124 { 0 } /* terminator */ 135 { 0 } /* terminator */
125}; 136};
diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h
index a892bda03df9..f06faf7917b9 100644
--- a/sound/usb/usbquirks.h
+++ b/sound/usb/usbquirks.h
@@ -91,7 +91,7 @@
91 .idVendor = 0x046d, 91 .idVendor = 0x046d,
92 .idProduct = 0x0850, 92 .idProduct = 0x0850,
93 .bInterfaceClass = USB_CLASS_AUDIO, 93 .bInterfaceClass = USB_CLASS_AUDIO,
94 .bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL 94 .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL
95}, 95},
96{ 96{
97 .match_flags = USB_DEVICE_ID_MATCH_DEVICE | 97 .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
@@ -100,7 +100,7 @@
100 .idVendor = 0x046d, 100 .idVendor = 0x046d,
101 .idProduct = 0x08ae, 101 .idProduct = 0x08ae,
102 .bInterfaceClass = USB_CLASS_AUDIO, 102 .bInterfaceClass = USB_CLASS_AUDIO,
103 .bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL 103 .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL
104}, 104},
105{ 105{
106 .match_flags = USB_DEVICE_ID_MATCH_DEVICE | 106 .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
@@ -109,7 +109,7 @@
109 .idVendor = 0x046d, 109 .idVendor = 0x046d,
110 .idProduct = 0x08c6, 110 .idProduct = 0x08c6,
111 .bInterfaceClass = USB_CLASS_AUDIO, 111 .bInterfaceClass = USB_CLASS_AUDIO,
112 .bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL 112 .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL
113}, 113},
114{ 114{
115 .match_flags = USB_DEVICE_ID_MATCH_DEVICE | 115 .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
@@ -118,7 +118,7 @@
118 .idVendor = 0x046d, 118 .idVendor = 0x046d,
119 .idProduct = 0x08f0, 119 .idProduct = 0x08f0,
120 .bInterfaceClass = USB_CLASS_AUDIO, 120 .bInterfaceClass = USB_CLASS_AUDIO,
121 .bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL 121 .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL
122}, 122},
123{ 123{
124 .match_flags = USB_DEVICE_ID_MATCH_DEVICE | 124 .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
@@ -127,7 +127,7 @@
127 .idVendor = 0x046d, 127 .idVendor = 0x046d,
128 .idProduct = 0x08f5, 128 .idProduct = 0x08f5,
129 .bInterfaceClass = USB_CLASS_AUDIO, 129 .bInterfaceClass = USB_CLASS_AUDIO,
130 .bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL 130 .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL
131}, 131},
132{ 132{
133 .match_flags = USB_DEVICE_ID_MATCH_DEVICE | 133 .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
@@ -136,7 +136,7 @@
136 .idVendor = 0x046d, 136 .idVendor = 0x046d,
137 .idProduct = 0x08f6, 137 .idProduct = 0x08f6,
138 .bInterfaceClass = USB_CLASS_AUDIO, 138 .bInterfaceClass = USB_CLASS_AUDIO,
139 .bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL 139 .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL
140}, 140},
141{ 141{
142 USB_DEVICE(0x046d, 0x0990), 142 USB_DEVICE(0x046d, 0x0990),
@@ -301,7 +301,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
301 .iface = 1, 301 .iface = 1,
302 .altsetting = 1, 302 .altsetting = 1,
303 .altset_idx = 1, 303 .altset_idx = 1,
304 .attributes = EP_CS_ATTR_FILL_MAX, 304 .attributes = UAC_EP_CS_ATTR_FILL_MAX,
305 .endpoint = 0x81, 305 .endpoint = 0x81,
306 .ep_attr = 0x05, 306 .ep_attr = 0x05,
307 .rates = SNDRV_PCM_RATE_CONTINUOUS, 307 .rates = SNDRV_PCM_RATE_CONTINUOUS,
@@ -1266,37 +1266,6 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1266 } 1266 }
1267 } 1267 }
1268}, 1268},
1269/* Roland UA-101 in High-Speed Mode only */
1270{
1271 USB_DEVICE(0x0582, 0x007d),
1272 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1273 .vendor_name = "Roland",
1274 .product_name = "UA-101",
1275 .ifnum = QUIRK_ANY_INTERFACE,
1276 .type = QUIRK_COMPOSITE,
1277 .data = (const struct snd_usb_audio_quirk[]) {
1278 {
1279 .ifnum = 0,
1280 .type = QUIRK_AUDIO_EDIROL_UA101
1281 },
1282 {
1283 .ifnum = 1,
1284 .type = QUIRK_AUDIO_EDIROL_UA101
1285 },
1286 {
1287 .ifnum = 2,
1288 .type = QUIRK_MIDI_FIXED_ENDPOINT,
1289 .data = & (const struct snd_usb_midi_endpoint_info) {
1290 .out_cables = 0x0001,
1291 .in_cables = 0x0001
1292 }
1293 },
1294 {
1295 .ifnum = -1
1296 }
1297 }
1298 }
1299},
1300{ 1269{
1301 /* has ID 0x0081 when not in "Advanced Driver" mode */ 1270 /* has ID 0x0081 when not in "Advanced Driver" mode */
1302 USB_DEVICE(0x0582, 0x0080), 1271 USB_DEVICE(0x0582, 0x0080),
@@ -2073,6 +2042,33 @@ YAMAHA_DEVICE(0x7010, "UB99"),
2073 } 2042 }
2074}, 2043},
2075 2044
2045/* Access Music devices */
2046{
2047 /* VirusTI Desktop */
2048 USB_DEVICE_VENDOR_SPEC(0x133e, 0x0815),
2049 .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
2050 .ifnum = QUIRK_ANY_INTERFACE,
2051 .type = QUIRK_COMPOSITE,
2052 .data = &(const struct snd_usb_audio_quirk[]) {
2053 {
2054 .ifnum = 3,
2055 .type = QUIRK_MIDI_FIXED_ENDPOINT,
2056 .data = &(const struct snd_usb_midi_endpoint_info) {
2057 .out_cables = 0x0003,
2058 .in_cables = 0x0003
2059 }
2060 },
2061 {
2062 .ifnum = 4,
2063 .type = QUIRK_IGNORE_INTERFACE
2064 },
2065 {
2066 .ifnum = -1
2067 }
2068 }
2069 }
2070},
2071
2076/* */ 2072/* */
2077{ 2073{
2078 /* aka. Serato Scratch Live DJ Box */ 2074 /* aka. Serato Scratch Live DJ Box */
@@ -2105,6 +2101,165 @@ YAMAHA_DEVICE(0x7010, "UB99"),
2105 } 2101 }
2106}, 2102},
2107 2103
2104/* Hauppauge HVR-950Q and HVR-850 */
2105{
2106 USB_DEVICE_VENDOR_SPEC(0x2040, 0x7200),
2107 .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
2108 USB_DEVICE_ID_MATCH_INT_CLASS |
2109 USB_DEVICE_ID_MATCH_INT_SUBCLASS,
2110 .bInterfaceClass = USB_CLASS_AUDIO,
2111 .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
2112 .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
2113 .vendor_name = "Hauppauge",
2114 .product_name = "HVR-950Q",
2115 .ifnum = QUIRK_ANY_INTERFACE,
2116 .type = QUIRK_AUDIO_ALIGN_TRANSFER,
2117 }
2118},
2119{
2120 USB_DEVICE_VENDOR_SPEC(0x2040, 0x7201),
2121 .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
2122 USB_DEVICE_ID_MATCH_INT_CLASS |
2123 USB_DEVICE_ID_MATCH_INT_SUBCLASS,
2124 .bInterfaceClass = USB_CLASS_AUDIO,
2125 .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
2126 .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
2127 .vendor_name = "Hauppauge",
2128 .product_name = "HVR-950Q",
2129 .ifnum = QUIRK_ANY_INTERFACE,
2130 .type = QUIRK_AUDIO_ALIGN_TRANSFER,
2131 }
2132},
2133{
2134 USB_DEVICE_VENDOR_SPEC(0x2040, 0x7202),
2135 .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
2136 USB_DEVICE_ID_MATCH_INT_CLASS |
2137 USB_DEVICE_ID_MATCH_INT_SUBCLASS,
2138 .bInterfaceClass = USB_CLASS_AUDIO,
2139 .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
2140 .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
2141 .vendor_name = "Hauppauge",
2142 .product_name = "HVR-950Q",
2143 .ifnum = QUIRK_ANY_INTERFACE,
2144 .type = QUIRK_AUDIO_ALIGN_TRANSFER,
2145 }
2146},
2147{
2148 USB_DEVICE_VENDOR_SPEC(0x2040, 0x7203),
2149 .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
2150 USB_DEVICE_ID_MATCH_INT_CLASS |
2151 USB_DEVICE_ID_MATCH_INT_SUBCLASS,
2152 .bInterfaceClass = USB_CLASS_AUDIO,
2153 .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
2154 .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
2155 .vendor_name = "Hauppauge",
2156 .product_name = "HVR-950Q",
2157 .ifnum = QUIRK_ANY_INTERFACE,
2158 .type = QUIRK_AUDIO_ALIGN_TRANSFER,
2159 }
2160},
2161{
2162 USB_DEVICE_VENDOR_SPEC(0x2040, 0x7204),
2163 .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
2164 USB_DEVICE_ID_MATCH_INT_CLASS |
2165 USB_DEVICE_ID_MATCH_INT_SUBCLASS,
2166 .bInterfaceClass = USB_CLASS_AUDIO,
2167 .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
2168 .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
2169 .vendor_name = "Hauppauge",
2170 .product_name = "HVR-950Q",
2171 .ifnum = QUIRK_ANY_INTERFACE,
2172 .type = QUIRK_AUDIO_ALIGN_TRANSFER,
2173 }
2174},
2175{
2176 USB_DEVICE_VENDOR_SPEC(0x2040, 0x7205),
2177 .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
2178 USB_DEVICE_ID_MATCH_INT_CLASS |
2179 USB_DEVICE_ID_MATCH_INT_SUBCLASS,
2180 .bInterfaceClass = USB_CLASS_AUDIO,
2181 .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
2182 .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
2183 .vendor_name = "Hauppauge",
2184 .product_name = "HVR-950Q",
2185 .ifnum = QUIRK_ANY_INTERFACE,
2186 .type = QUIRK_AUDIO_ALIGN_TRANSFER,
2187 }
2188},
2189{
2190 USB_DEVICE_VENDOR_SPEC(0x2040, 0x7250),
2191 .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
2192 USB_DEVICE_ID_MATCH_INT_CLASS |
2193 USB_DEVICE_ID_MATCH_INT_SUBCLASS,
2194 .bInterfaceClass = USB_CLASS_AUDIO,
2195 .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
2196 .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
2197 .vendor_name = "Hauppauge",
2198 .product_name = "HVR-950Q",
2199 .ifnum = QUIRK_ANY_INTERFACE,
2200 .type = QUIRK_AUDIO_ALIGN_TRANSFER,
2201 }
2202},
2203{
2204 USB_DEVICE_VENDOR_SPEC(0x2040, 0x7230),
2205 .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
2206 USB_DEVICE_ID_MATCH_INT_CLASS |
2207 USB_DEVICE_ID_MATCH_INT_SUBCLASS,
2208 .bInterfaceClass = USB_CLASS_AUDIO,
2209 .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
2210 .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
2211 .vendor_name = "Hauppauge",
2212 .product_name = "HVR-850",
2213 .ifnum = QUIRK_ANY_INTERFACE,
2214 .type = QUIRK_AUDIO_ALIGN_TRANSFER,
2215 }
2216},
2217
2218/* Digidesign Mbox */
2219{
2220 /* Thanks to Clemens Ladisch <clemens@ladisch.de> */
2221 USB_DEVICE(0x0dba, 0x1000),
2222 .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
2223 .vendor_name = "Digidesign",
2224 .product_name = "MBox",
2225 .ifnum = QUIRK_ANY_INTERFACE,
2226 .type = QUIRK_COMPOSITE,
2227 .data = (const struct snd_usb_audio_quirk[]){
2228 {
2229 .ifnum = 0,
2230 .type = QUIRK_IGNORE_INTERFACE,
2231 },
2232 {
2233 .ifnum = 1,
2234 .type = QUIRK_AUDIO_FIXED_ENDPOINT,
2235 .data = &(const struct audioformat) {
2236 .format = SNDRV_PCM_FORMAT_S24_3BE,
2237 .channels = 2,
2238 .iface = 1,
2239 .altsetting = 1,
2240 .altset_idx = 1,
2241 .attributes = UAC_EP_CS_ATTR_SAMPLE_RATE,
2242 .endpoint = 0x02,
2243 .ep_attr = 0x01,
2244 .maxpacksize = 0x130,
2245 .rates = SNDRV_PCM_RATE_44100 |
2246 SNDRV_PCM_RATE_48000,
2247 .rate_min = 44100,
2248 .rate_max = 48000,
2249 .nr_rates = 2,
2250 .rate_table = (unsigned int[]) {
2251 44100, 48000
2252 }
2253 }
2254 },
2255 {
2256 .ifnum = -1
2257 }
2258 }
2259
2260 }
2261},
2262
2108{ 2263{
2109 /* 2264 /*
2110 * Some USB MIDI devices don't have an audio control interface, 2265 * Some USB MIDI devices don't have an audio control interface,
@@ -2113,7 +2268,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
2113 .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS | 2268 .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS |
2114 USB_DEVICE_ID_MATCH_INT_SUBCLASS, 2269 USB_DEVICE_ID_MATCH_INT_SUBCLASS,
2115 .bInterfaceClass = USB_CLASS_AUDIO, 2270 .bInterfaceClass = USB_CLASS_AUDIO,
2116 .bInterfaceSubClass = USB_SUBCLASS_MIDI_STREAMING, 2271 .bInterfaceSubClass = USB_SUBCLASS_MIDISTREAMING,
2117 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { 2272 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
2118 .ifnum = QUIRK_ANY_INTERFACE, 2273 .ifnum = QUIRK_ANY_INTERFACE,
2119 .type = QUIRK_MIDI_STANDARD_INTERFACE 2274 .type = QUIRK_MIDI_STANDARD_INTERFACE
diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c
index 91bb29666d26..44deb21b1777 100644
--- a/sound/usb/usx2y/us122l.c
+++ b/sound/usb/usx2y/us122l.c
@@ -16,6 +16,8 @@
16 * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 16 * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */ 17 */
18 18
19#include <linux/usb.h>
20#include <linux/usb/audio.h>
19#include <sound/core.h> 21#include <sound/core.h>
20#include <sound/hwdep.h> 22#include <sound/hwdep.h>
21#include <sound/pcm.h> 23#include <sound/pcm.h>
@@ -315,9 +317,9 @@ static int us122l_set_sample_rate(struct usb_device *dev, int rate)
315 data[0] = rate; 317 data[0] = rate;
316 data[1] = rate >> 8; 318 data[1] = rate >> 8;
317 data[2] = rate >> 16; 319 data[2] = rate >> 16;
318 err = us122l_ctl_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, 320 err = us122l_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR,
319 USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, 321 USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT,
320 SAMPLING_FREQ_CONTROL << 8, ep, data, 3, 1000); 322 UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep, data, 3, 1000);
321 if (err < 0) 323 if (err < 0)
322 snd_printk(KERN_ERR "%d: cannot set freq %d to ep 0x%x\n", 324 snd_printk(KERN_ERR "%d: cannot set freq %d to ep 0x%x\n",
323 dev->devnum, rate, ep); 325 dev->devnum, rate, ep);