aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/aoa/soundbus/core.c2
-rw-r--r--sound/aoa/soundbus/soundbus.h2
-rw-r--r--sound/aoa/soundbus/sysfs.c2
-rw-r--r--sound/core/control.c5
-rw-r--r--sound/core/init.c9
-rw-r--r--sound/core/oss/mixer_oss.c22
-rw-r--r--sound/core/pcm.c42
-rw-r--r--sound/core/pcm_lib.c25
-rw-r--r--sound/core/pcm_misc.c16
-rw-r--r--sound/core/pcm_native.c21
-rw-r--r--sound/core/rawmidi.c2
-rw-r--r--sound/core/seq/oss/seq_oss_init.c9
-rw-r--r--sound/drivers/Kconfig26
-rw-r--r--sound/drivers/virmidi.c2
-rw-r--r--sound/i2c/other/ak4xxx-adda.c4
-rw-r--r--sound/isa/Kconfig36
-rw-r--r--sound/isa/Makefile4
-rw-r--r--sound/isa/ad1816a/ad1816a.c2
-rw-r--r--sound/isa/azt2320.c2
-rw-r--r--sound/isa/galaxy/Makefile10
-rw-r--r--sound/isa/galaxy/azt1605.c91
-rw-r--r--sound/isa/galaxy/azt2316.c111
-rw-r--r--sound/isa/galaxy/galaxy.c652
-rw-r--r--sound/isa/gus/gusmax.c4
-rw-r--r--sound/isa/msnd/msnd_pinnacle.c13
-rw-r--r--sound/isa/sb/emu8000_pcm.c9
-rw-r--r--sound/isa/sb/sb8.c2
-rw-r--r--sound/isa/sgalaxy.c369
-rw-r--r--sound/oss/Kconfig8
-rw-r--r--sound/oss/Makefile1
-rw-r--r--sound/oss/ad1848.c2
-rw-r--r--sound/oss/au1550_ac97.c122
-rw-r--r--sound/oss/dmasound/dmasound_core.c78
-rw-r--r--sound/oss/midi_synth.c4
-rw-r--r--sound/oss/msnd_pinnacle.c42
-rw-r--r--sound/oss/sh_dac_audio.c309
-rw-r--r--sound/oss/sound_timer.c2
-rw-r--r--sound/oss/soundcard.c63
-rw-r--r--sound/oss/swarm_cs4297a.c41
-rw-r--r--sound/oss/vidc.c3
-rw-r--r--sound/oss/vwsnd.c38
-rw-r--r--sound/oss/waveartist.c10
-rw-r--r--sound/pci/Kconfig17
-rw-r--r--sound/pci/als4000.c4
-rw-r--r--sound/pci/asihpi/asihpi.c16
-rw-r--r--sound/pci/asihpi/hpi.h68
-rw-r--r--sound/pci/asihpi/hpi6000.c7
-rw-r--r--sound/pci/asihpi/hpi6205.c7
-rw-r--r--sound/pci/asihpi/hpi_internal.h40
-rw-r--r--sound/pci/asihpi/hpicmn.c10
-rw-r--r--sound/pci/asihpi/hpidebug.c2
-rw-r--r--sound/pci/asihpi/hpidebug.h4
-rw-r--r--sound/pci/asihpi/hpifunc.c327
-rw-r--r--sound/pci/asihpi/hpimsgx.c2
-rw-r--r--sound/pci/asihpi/hpioctl.c21
-rw-r--r--sound/pci/ca0106/ca0106_main.c34
-rw-r--r--sound/pci/echoaudio/echoaudio.c2
-rw-r--r--sound/pci/emu10k1/emu10k1.c4
-rw-r--r--sound/pci/emu10k1/emumpu401.c2
-rw-r--r--sound/pci/emu10k1/emupcm.c30
-rw-r--r--sound/pci/emu10k1/memory.c4
-rw-r--r--sound/pci/hda/hda_codec.c270
-rw-r--r--sound/pci/hda/hda_codec.h49
-rw-r--r--sound/pci/hda/hda_eld.c49
-rw-r--r--sound/pci/hda/hda_hwdep.c4
-rw-r--r--sound/pci/hda/hda_intel.c14
-rw-r--r--sound/pci/hda/hda_local.h2
-rw-r--r--sound/pci/hda/hda_proc.c7
-rw-r--r--sound/pci/hda/patch_analog.c8
-rw-r--r--sound/pci/hda/patch_cirrus.c52
-rw-r--r--sound/pci/hda/patch_conexant.c161
-rw-r--r--sound/pci/hda/patch_hdmi.c102
-rw-r--r--sound/pci/hda/patch_intelhdmi.c12
-rw-r--r--sound/pci/hda/patch_nvhdmi.c78
-rw-r--r--sound/pci/hda/patch_realtek.c895
-rw-r--r--sound/pci/hda/patch_sigmatel.c40
-rw-r--r--sound/pci/hda/patch_via.c32
-rw-r--r--sound/pci/ice1712/delta.c10
-rw-r--r--sound/pci/ice1712/delta.h4
-rw-r--r--sound/pci/ice1712/pontis.c6
-rw-r--r--sound/pci/ice1712/prodigy192.c2
-rw-r--r--sound/pci/intel8x0.c6
-rw-r--r--sound/pci/oxygen/oxygen.c8
-rw-r--r--sound/pci/oxygen/oxygen.h2
-rw-r--r--sound/pci/oxygen/oxygen_lib.c76
-rw-r--r--sound/pci/oxygen/oxygen_mixer.c5
-rw-r--r--sound/pci/oxygen/oxygen_pcm.c12
-rw-r--r--sound/pci/oxygen/oxygen_regs.h10
-rw-r--r--sound/pci/oxygen/virtuoso.c6
-rw-r--r--sound/pci/oxygen/xonar_cs43xx.c8
-rw-r--r--sound/pci/oxygen/xonar_pcm179x.c29
-rw-r--r--sound/pci/oxygen/xonar_wm87x6.c143
-rw-r--r--sound/pci/riptide/riptide.c29
-rw-r--r--sound/pci/rme96.c8
-rw-r--r--sound/pci/rme9652/hdsp.c9
-rw-r--r--sound/pci/rme9652/hdspm.c1
-rw-r--r--sound/pci/sis7019.c16
-rw-r--r--sound/pci/trident/trident_main.c2
-rw-r--r--sound/pci/via82xx.c9
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf.c9
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf.h1
-rw-r--r--sound/pcmcia/vx/vxpocket.c9
-rw-r--r--sound/pcmcia/vx/vxpocket.h1
-rw-r--r--sound/ppc/snd_ps3.c2
-rw-r--r--sound/ppc/tumbler.c2
-rw-r--r--sound/soc/Kconfig4
-rw-r--r--sound/soc/Makefile4
-rw-r--r--sound/soc/atmel/atmel-pcm.c1
-rw-r--r--sound/soc/atmel/atmel_ssc_dai.c1
-rw-r--r--sound/soc/au1x/psc-ac97.c13
-rw-r--r--sound/soc/au1x/psc-i2s.c13
-rw-r--r--sound/soc/au1x/psc.h1
-rw-r--r--sound/soc/blackfin/Kconfig7
-rw-r--r--sound/soc/blackfin/bf5xx-ac97.c6
-rw-r--r--sound/soc/blackfin/bf5xx-ad1980.c10
-rw-r--r--sound/soc/blackfin/bf5xx-tdm.c6
-rw-r--r--sound/soc/codecs/Kconfig20
-rw-r--r--sound/soc/codecs/Makefile6
-rw-r--r--sound/soc/codecs/ad1836.c1
-rw-r--r--sound/soc/codecs/ad193x.c41
-rw-r--r--sound/soc/codecs/ad193x.h5
-rw-r--r--sound/soc/codecs/ad1980.c10
-rw-r--r--sound/soc/codecs/ad1980.h6
-rw-r--r--sound/soc/codecs/ak4642.c36
-rw-r--r--sound/soc/codecs/cs42l51.c763
-rw-r--r--sound/soc/codecs/cs42l51.h163
-rw-r--r--sound/soc/codecs/da7210.c48
-rw-r--r--sound/soc/codecs/jz4740.c511
-rw-r--r--sound/soc/codecs/jz4740.h20
-rw-r--r--sound/soc/codecs/spdif_transciever.c94
-rw-r--r--sound/soc/codecs/spdif_transciever.h1
-rw-r--r--sound/soc/codecs/tlv320aic23.c7
-rw-r--r--sound/soc/codecs/tlv320dac33.c180
-rw-r--r--sound/soc/codecs/twl4030.c388
-rw-r--r--sound/soc/codecs/twl4030.h4
-rw-r--r--sound/soc/codecs/twl6040.c58
-rw-r--r--sound/soc/codecs/uda134x.c64
-rw-r--r--sound/soc/codecs/uda134x.h5
-rw-r--r--sound/soc/codecs/wm2000.c2
-rw-r--r--sound/soc/codecs/wm8523.c10
-rw-r--r--sound/soc/codecs/wm8580.c6
-rw-r--r--sound/soc/codecs/wm8711.c3
-rw-r--r--sound/soc/codecs/wm8741.c579
-rw-r--r--sound/soc/codecs/wm8741.h214
-rw-r--r--sound/soc/codecs/wm8750.c11
-rw-r--r--sound/soc/codecs/wm8776.c7
-rw-r--r--sound/soc/codecs/wm8904.c13
-rw-r--r--sound/soc/codecs/wm8940.c7
-rw-r--r--sound/soc/codecs/wm8955.c10
-rw-r--r--sound/soc/codecs/wm8960.c99
-rw-r--r--sound/soc/codecs/wm8961.c9
-rw-r--r--sound/soc/codecs/wm8974.c3
-rw-r--r--sound/soc/codecs/wm8978.c10
-rw-r--r--sound/soc/codecs/wm8990.c4
-rw-r--r--sound/soc/codecs/wm8994.c98
-rw-r--r--sound/soc/codecs/wm8994.h3
-rw-r--r--sound/soc/codecs/wm9081.c11
-rw-r--r--sound/soc/codecs/wm_hubs.c2
-rw-r--r--sound/soc/davinci/davinci-i2s.c163
-rw-r--r--sound/soc/davinci/davinci-i2s.h5
-rw-r--r--sound/soc/davinci/davinci-mcasp.c6
-rw-r--r--sound/soc/davinci/davinci-pcm.c7
-rw-r--r--sound/soc/davinci/davinci-pcm.h3
-rw-r--r--sound/soc/davinci/davinci-vcif.c2
-rw-r--r--sound/soc/ep93xx/Kconfig18
-rw-r--r--sound/soc/ep93xx/Makefile11
-rw-r--r--sound/soc/ep93xx/ep93xx-i2s.c487
-rw-r--r--sound/soc/ep93xx/ep93xx-i2s.h18
-rw-r--r--sound/soc/ep93xx/ep93xx-pcm.c319
-rw-r--r--sound/soc/ep93xx/ep93xx-pcm.h22
-rw-r--r--sound/soc/ep93xx/snappercl15.c150
-rw-r--r--sound/soc/fsl/mpc5200_dma.c4
-rw-r--r--sound/soc/fsl/mpc5200_dma.h4
-rw-r--r--sound/soc/fsl/mpc5200_psc_ac97.c26
-rw-r--r--sound/soc/fsl/mpc5200_psc_i2s.c5
-rw-r--r--sound/soc/fsl/mpc5200_psc_i2s.h12
-rw-r--r--sound/soc/fsl/mpc8610_hpcd.c6
-rw-r--r--sound/soc/imx/Kconfig21
-rw-r--r--sound/soc/imx/Makefile2
-rw-r--r--sound/soc/imx/eukrea-tlv320.c137
-rw-r--r--sound/soc/imx/imx-pcm-dma-mx2.c6
-rw-r--r--sound/soc/imx/imx-pcm-fiq.c6
-rw-r--r--sound/soc/imx/imx-ssi.c16
-rw-r--r--sound/soc/jz4740/Kconfig23
-rw-r--r--sound/soc/jz4740/Makefile13
-rw-r--r--sound/soc/jz4740/jz4740-i2s.c540
-rw-r--r--sound/soc/jz4740/jz4740-i2s.h18
-rw-r--r--sound/soc/jz4740/jz4740-pcm.c373
-rw-r--r--sound/soc/jz4740/jz4740-pcm.h22
-rw-r--r--sound/soc/jz4740/qi_lb60.c166
-rw-r--r--sound/soc/kirkwood/Kconfig20
-rw-r--r--sound/soc/kirkwood/Makefile9
-rw-r--r--sound/soc/kirkwood/kirkwood-dma.c383
-rw-r--r--sound/soc/kirkwood/kirkwood-dma.h17
-rw-r--r--sound/soc/kirkwood/kirkwood-i2s.c495
-rw-r--r--sound/soc/kirkwood/kirkwood-i2s.h17
-rw-r--r--sound/soc/kirkwood/kirkwood-openrd.c126
-rw-r--r--sound/soc/kirkwood/kirkwood.h129
-rw-r--r--sound/soc/nuc900/Kconfig27
-rw-r--r--sound/soc/nuc900/Makefile11
-rw-r--r--sound/soc/nuc900/nuc900-ac97.c430
-rw-r--r--sound/soc/nuc900/nuc900-audio.c81
-rw-r--r--sound/soc/nuc900/nuc900-audio.h117
-rw-r--r--sound/soc/nuc900/nuc900-pcm.c354
-rw-r--r--sound/soc/omap/omap-mcbsp.c175
-rw-r--r--sound/soc/omap/omap3pandora.c36
-rw-r--r--sound/soc/omap/rx51.c73
-rw-r--r--sound/soc/s3c24xx/Kconfig10
-rw-r--r--sound/soc/s3c24xx/Makefile2
-rw-r--r--sound/soc/s3c24xx/s3c-ac97.c1
-rw-r--r--sound/soc/s3c24xx/s3c-dma.c3
-rw-r--r--sound/soc/s3c24xx/s3c-i2s-v2.c3
-rw-r--r--sound/soc/s3c24xx/smartq_wm8987.c295
-rw-r--r--sound/soc/s3c24xx/smdk_wm9713.c3
-rw-r--r--sound/soc/s6000/s6000-i2s.c38
-rw-r--r--sound/soc/sh/Kconfig4
-rw-r--r--sound/soc/sh/fsi-ak4642.c13
-rw-r--r--sound/soc/sh/fsi-da7210.c13
-rw-r--r--sound/soc/sh/fsi.c257
-rw-r--r--sound/soc/sh/migor.c15
-rw-r--r--sound/soc/soc-cache.c9
-rw-r--r--sound/soc/soc-core.c119
-rw-r--r--sound/sound_core.c9
-rw-r--r--sound/sparc/amd7930.c14
-rw-r--r--sound/sparc/cs4231.c36
-rw-r--r--sound/sparc/dbri.c14
-rw-r--r--sound/synth/emux/emux_hwdep.c3
-rw-r--r--sound/usb/Kconfig2
-rw-r--r--sound/usb/caiaq/audio.c175
-rw-r--r--sound/usb/caiaq/control.c208
-rw-r--r--sound/usb/caiaq/device.c10
-rw-r--r--sound/usb/caiaq/device.h6
-rw-r--r--sound/usb/caiaq/input.c248
-rw-r--r--sound/usb/card.c52
-rw-r--r--sound/usb/clock.c62
-rw-r--r--sound/usb/clock.h4
-rw-r--r--sound/usb/endpoint.c18
-rw-r--r--sound/usb/format.c23
-rw-r--r--sound/usb/helper.c17
-rw-r--r--sound/usb/midi.c23
-rw-r--r--sound/usb/mixer.c90
-rw-r--r--sound/usb/mixer.h1
-rw-r--r--sound/usb/pcm.c9
-rw-r--r--sound/usb/pcm.h3
-rw-r--r--sound/usb/proc.c2
-rw-r--r--sound/usb/quirks-table.h203
-rw-r--r--sound/usb/quirks.c1
-rw-r--r--sound/usb/urb.c2
-rw-r--r--sound/usb/usx2y/usx2yhwdeppcm.c2
249 files changed, 13337 insertions, 2412 deletions
diff --git a/sound/aoa/soundbus/core.c b/sound/aoa/soundbus/core.c
index 99ca7120e26..7487eb76e03 100644
--- a/sound/aoa/soundbus/core.c
+++ b/sound/aoa/soundbus/core.c
@@ -59,7 +59,7 @@ static int soundbus_probe(struct device *dev)
59static int soundbus_uevent(struct device *dev, struct kobj_uevent_env *env) 59static int soundbus_uevent(struct device *dev, struct kobj_uevent_env *env)
60{ 60{
61 struct soundbus_dev * soundbus_dev; 61 struct soundbus_dev * soundbus_dev;
62 struct of_device * of; 62 struct platform_device * of;
63 const char *compat; 63 const char *compat;
64 int retval = 0; 64 int retval = 0;
65 int cplen, seen = 0; 65 int cplen, seen = 0;
diff --git a/sound/aoa/soundbus/soundbus.h b/sound/aoa/soundbus/soundbus.h
index a0f223c13f6..adecbf36f4f 100644
--- a/sound/aoa/soundbus/soundbus.h
+++ b/sound/aoa/soundbus/soundbus.h
@@ -141,7 +141,7 @@ struct soundbus_dev {
141 struct list_head onbuslist; 141 struct list_head onbuslist;
142 142
143 /* the of device it represents */ 143 /* the of device it represents */
144 struct of_device ofdev; 144 struct platform_device ofdev;
145 145
146 /* what modules go by */ 146 /* what modules go by */
147 char modalias[32]; 147 char modalias[32];
diff --git a/sound/aoa/soundbus/sysfs.c b/sound/aoa/soundbus/sysfs.c
index 6496e754f00..e0980b5c2cd 100644
--- a/sound/aoa/soundbus/sysfs.c
+++ b/sound/aoa/soundbus/sysfs.c
@@ -16,7 +16,7 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
16 char *buf) 16 char *buf)
17{ 17{
18 struct soundbus_dev *sdev = to_soundbus_device(dev); 18 struct soundbus_dev *sdev = to_soundbus_device(dev);
19 struct of_device *of = &sdev->ofdev; 19 struct platform_device *of = &sdev->ofdev;
20 int length; 20 int length;
21 21
22 if (*sdev->modalias) { 22 if (*sdev->modalias) {
diff --git a/sound/core/control.c b/sound/core/control.c
index 070aab49019..45a818002d9 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -31,6 +31,7 @@
31 31
32/* max number of user-defined controls */ 32/* max number of user-defined controls */
33#define MAX_USER_CONTROLS 32 33#define MAX_USER_CONTROLS 32
34#define MAX_CONTROL_COUNT 1028
34 35
35struct snd_kctl_ioctl { 36struct snd_kctl_ioctl {
36 struct list_head list; /* list of all ioctls */ 37 struct list_head list; /* list of all ioctls */
@@ -195,6 +196,10 @@ static struct snd_kcontrol *snd_ctl_new(struct snd_kcontrol *control,
195 196
196 if (snd_BUG_ON(!control || !control->count)) 197 if (snd_BUG_ON(!control || !control->count))
197 return NULL; 198 return NULL;
199
200 if (control->count > MAX_CONTROL_COUNT)
201 return NULL;
202
198 kctl = kzalloc(sizeof(*kctl) + sizeof(struct snd_kcontrol_volatile) * control->count, GFP_KERNEL); 203 kctl = kzalloc(sizeof(*kctl) + sizeof(struct snd_kcontrol_volatile) * control->count, GFP_KERNEL);
199 if (kctl == NULL) { 204 if (kctl == NULL) {
200 snd_printk(KERN_ERR "Cannot allocate control instance\n"); 205 snd_printk(KERN_ERR "Cannot allocate control instance\n");
diff --git a/sound/core/init.c b/sound/core/init.c
index ec4a50ce565..2de45fbd70f 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -607,11 +607,16 @@ card_id_store_attr(struct device *dev, struct device_attribute *attr,
607 return -EEXIST; 607 return -EEXIST;
608 } 608 }
609 for (idx = 0; idx < snd_ecards_limit; idx++) { 609 for (idx = 0; idx < snd_ecards_limit; idx++) {
610 if (snd_cards[idx] && !strcmp(snd_cards[idx]->id, buf1)) 610 if (snd_cards[idx] && !strcmp(snd_cards[idx]->id, buf1)) {
611 goto __exist; 611 if (card == snd_cards[idx])
612 goto __ok;
613 else
614 goto __exist;
615 }
612 } 616 }
613 strcpy(card->id, buf1); 617 strcpy(card->id, buf1);
614 snd_info_card_id_change(card); 618 snd_info_card_id_change(card);
619__ok:
615 mutex_unlock(&snd_card_mutex); 620 mutex_unlock(&snd_card_mutex);
616 621
617 return count; 622 return count;
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c
index 8442a088677..822dd56993c 100644
--- a/sound/core/oss/mixer_oss.c
+++ b/sound/core/oss/mixer_oss.c
@@ -77,7 +77,7 @@ static int snd_mixer_oss_release(struct inode *inode, struct file *file)
77 struct snd_mixer_oss_file *fmixer; 77 struct snd_mixer_oss_file *fmixer;
78 78
79 if (file->private_data) { 79 if (file->private_data) {
80 fmixer = (struct snd_mixer_oss_file *) file->private_data; 80 fmixer = file->private_data;
81 module_put(fmixer->card->module); 81 module_put(fmixer->card->module);
82 snd_card_file_remove(fmixer->card, file); 82 snd_card_file_remove(fmixer->card, file);
83 kfree(fmixer); 83 kfree(fmixer);
@@ -368,7 +368,7 @@ static int snd_mixer_oss_ioctl1(struct snd_mixer_oss_file *fmixer, unsigned int
368 368
369static long snd_mixer_oss_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 369static long snd_mixer_oss_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
370{ 370{
371 return snd_mixer_oss_ioctl1((struct snd_mixer_oss_file *) file->private_data, cmd, arg); 371 return snd_mixer_oss_ioctl1(file->private_data, cmd, arg);
372} 372}
373 373
374int snd_mixer_oss_ioctl_card(struct snd_card *card, unsigned int cmd, unsigned long arg) 374int snd_mixer_oss_ioctl_card(struct snd_card *card, unsigned int cmd, unsigned long arg)
@@ -582,7 +582,7 @@ static int snd_mixer_oss_get_volume1(struct snd_mixer_oss_file *fmixer,
582 struct snd_mixer_oss_slot *pslot, 582 struct snd_mixer_oss_slot *pslot,
583 int *left, int *right) 583 int *left, int *right)
584{ 584{
585 struct slot *slot = (struct slot *)pslot->private_data; 585 struct slot *slot = pslot->private_data;
586 586
587 *left = *right = 100; 587 *left = *right = 100;
588 if (slot->present & SNDRV_MIXER_OSS_PRESENT_PVOLUME) { 588 if (slot->present & SNDRV_MIXER_OSS_PRESENT_PVOLUME) {
@@ -693,7 +693,7 @@ static int snd_mixer_oss_put_volume1(struct snd_mixer_oss_file *fmixer,
693 struct snd_mixer_oss_slot *pslot, 693 struct snd_mixer_oss_slot *pslot,
694 int left, int right) 694 int left, int right)
695{ 695{
696 struct slot *slot = (struct slot *)pslot->private_data; 696 struct slot *slot = pslot->private_data;
697 697
698 if (slot->present & SNDRV_MIXER_OSS_PRESENT_PVOLUME) { 698 if (slot->present & SNDRV_MIXER_OSS_PRESENT_PVOLUME) {
699 snd_mixer_oss_put_volume1_vol(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_PVOLUME], left, right); 699 snd_mixer_oss_put_volume1_vol(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_PVOLUME], left, right);
@@ -742,7 +742,7 @@ static int snd_mixer_oss_get_recsrc1_sw(struct snd_mixer_oss_file *fmixer,
742 struct snd_mixer_oss_slot *pslot, 742 struct snd_mixer_oss_slot *pslot,
743 int *active) 743 int *active)
744{ 744{
745 struct slot *slot = (struct slot *)pslot->private_data; 745 struct slot *slot = pslot->private_data;
746 int left, right; 746 int left, right;
747 747
748 left = right = 1; 748 left = right = 1;
@@ -755,7 +755,7 @@ static int snd_mixer_oss_get_recsrc1_route(struct snd_mixer_oss_file *fmixer,
755 struct snd_mixer_oss_slot *pslot, 755 struct snd_mixer_oss_slot *pslot,
756 int *active) 756 int *active)
757{ 757{
758 struct slot *slot = (struct slot *)pslot->private_data; 758 struct slot *slot = pslot->private_data;
759 int left, right; 759 int left, right;
760 760
761 left = right = 1; 761 left = right = 1;
@@ -768,7 +768,7 @@ static int snd_mixer_oss_put_recsrc1_sw(struct snd_mixer_oss_file *fmixer,
768 struct snd_mixer_oss_slot *pslot, 768 struct snd_mixer_oss_slot *pslot,
769 int active) 769 int active)
770{ 770{
771 struct slot *slot = (struct slot *)pslot->private_data; 771 struct slot *slot = pslot->private_data;
772 772
773 snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_CSWITCH], active, active, 0); 773 snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_CSWITCH], active, active, 0);
774 return 0; 774 return 0;
@@ -778,7 +778,7 @@ static int snd_mixer_oss_put_recsrc1_route(struct snd_mixer_oss_file *fmixer,
778 struct snd_mixer_oss_slot *pslot, 778 struct snd_mixer_oss_slot *pslot,
779 int active) 779 int active)
780{ 780{
781 struct slot *slot = (struct slot *)pslot->private_data; 781 struct slot *slot = pslot->private_data;
782 782
783 snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_CROUTE], active, active, 1); 783 snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_CROUTE], active, active, 1);
784 return 0; 784 return 0;
@@ -815,7 +815,7 @@ static int snd_mixer_oss_get_recsrc2(struct snd_mixer_oss_file *fmixer, unsigned
815 if (!(mixer->mask_recsrc & (1 << idx))) 815 if (!(mixer->mask_recsrc & (1 << idx)))
816 continue; 816 continue;
817 pslot = &mixer->slots[idx]; 817 pslot = &mixer->slots[idx];
818 slot = (struct slot *)pslot->private_data; 818 slot = pslot->private_data;
819 if (slot->signature != SNDRV_MIXER_OSS_SIGNATURE) 819 if (slot->signature != SNDRV_MIXER_OSS_SIGNATURE)
820 continue; 820 continue;
821 if (!(slot->present & SNDRV_MIXER_OSS_PRESENT_CAPTURE)) 821 if (!(slot->present & SNDRV_MIXER_OSS_PRESENT_CAPTURE))
@@ -864,7 +864,7 @@ static int snd_mixer_oss_put_recsrc2(struct snd_mixer_oss_file *fmixer, unsigned
864 if (!(mixer->mask_recsrc & (1 << idx))) 864 if (!(mixer->mask_recsrc & (1 << idx)))
865 continue; 865 continue;
866 pslot = &mixer->slots[idx]; 866 pslot = &mixer->slots[idx];
867 slot = (struct slot *)pslot->private_data; 867 slot = pslot->private_data;
868 if (slot->signature != SNDRV_MIXER_OSS_SIGNATURE) 868 if (slot->signature != SNDRV_MIXER_OSS_SIGNATURE)
869 continue; 869 continue;
870 if (!(slot->present & SNDRV_MIXER_OSS_PRESENT_CAPTURE)) 870 if (!(slot->present & SNDRV_MIXER_OSS_PRESENT_CAPTURE))
@@ -929,7 +929,7 @@ static int snd_mixer_oss_build_test(struct snd_mixer_oss *mixer, struct slot *sl
929 929
930static void snd_mixer_oss_slot_free(struct snd_mixer_oss_slot *chn) 930static void snd_mixer_oss_slot_free(struct snd_mixer_oss_slot *chn)
931{ 931{
932 struct slot *p = (struct slot *)chn->private_data; 932 struct slot *p = chn->private_data;
933 if (p) { 933 if (p) {
934 if (p->allocated && p->assigned) { 934 if (p->allocated && p->assigned) {
935 kfree(p->assigned->name); 935 kfree(p->assigned->name);
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index cbe815dfbdc..6b4b1287b31 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -203,10 +203,16 @@ static char *snd_pcm_format_names[] = {
203 FORMAT(S18_3BE), 203 FORMAT(S18_3BE),
204 FORMAT(U18_3LE), 204 FORMAT(U18_3LE),
205 FORMAT(U18_3BE), 205 FORMAT(U18_3BE),
206 FORMAT(G723_24),
207 FORMAT(G723_24_1B),
208 FORMAT(G723_40),
209 FORMAT(G723_40_1B),
206}; 210};
207 211
208const char *snd_pcm_format_name(snd_pcm_format_t format) 212const char *snd_pcm_format_name(snd_pcm_format_t format)
209{ 213{
214 if (format >= ARRAY_SIZE(snd_pcm_format_names))
215 return "Unknown";
210 return snd_pcm_format_names[format]; 216 return snd_pcm_format_names[format];
211} 217}
212EXPORT_SYMBOL_GPL(snd_pcm_format_name); 218EXPORT_SYMBOL_GPL(snd_pcm_format_name);
@@ -358,22 +364,24 @@ static void snd_pcm_stream_proc_info_read(struct snd_info_entry *entry,
358static void snd_pcm_substream_proc_info_read(struct snd_info_entry *entry, 364static void snd_pcm_substream_proc_info_read(struct snd_info_entry *entry,
359 struct snd_info_buffer *buffer) 365 struct snd_info_buffer *buffer)
360{ 366{
361 snd_pcm_proc_info_read((struct snd_pcm_substream *)entry->private_data, 367 snd_pcm_proc_info_read(entry->private_data, buffer);
362 buffer);
363} 368}
364 369
365static void snd_pcm_substream_proc_hw_params_read(struct snd_info_entry *entry, 370static void snd_pcm_substream_proc_hw_params_read(struct snd_info_entry *entry,
366 struct snd_info_buffer *buffer) 371 struct snd_info_buffer *buffer)
367{ 372{
368 struct snd_pcm_substream *substream = entry->private_data; 373 struct snd_pcm_substream *substream = entry->private_data;
369 struct snd_pcm_runtime *runtime = substream->runtime; 374 struct snd_pcm_runtime *runtime;
375
376 mutex_lock(&substream->pcm->open_mutex);
377 runtime = substream->runtime;
370 if (!runtime) { 378 if (!runtime) {
371 snd_iprintf(buffer, "closed\n"); 379 snd_iprintf(buffer, "closed\n");
372 return; 380 goto unlock;
373 } 381 }
374 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) { 382 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) {
375 snd_iprintf(buffer, "no setup\n"); 383 snd_iprintf(buffer, "no setup\n");
376 return; 384 goto unlock;
377 } 385 }
378 snd_iprintf(buffer, "access: %s\n", snd_pcm_access_name(runtime->access)); 386 snd_iprintf(buffer, "access: %s\n", snd_pcm_access_name(runtime->access));
379 snd_iprintf(buffer, "format: %s\n", snd_pcm_format_name(runtime->format)); 387 snd_iprintf(buffer, "format: %s\n", snd_pcm_format_name(runtime->format));
@@ -392,20 +400,25 @@ static void snd_pcm_substream_proc_hw_params_read(struct snd_info_entry *entry,
392 snd_iprintf(buffer, "OSS period frames: %lu\n", (unsigned long)runtime->oss.period_frames); 400 snd_iprintf(buffer, "OSS period frames: %lu\n", (unsigned long)runtime->oss.period_frames);
393 } 401 }
394#endif 402#endif
403 unlock:
404 mutex_unlock(&substream->pcm->open_mutex);
395} 405}
396 406
397static void snd_pcm_substream_proc_sw_params_read(struct snd_info_entry *entry, 407static void snd_pcm_substream_proc_sw_params_read(struct snd_info_entry *entry,
398 struct snd_info_buffer *buffer) 408 struct snd_info_buffer *buffer)
399{ 409{
400 struct snd_pcm_substream *substream = entry->private_data; 410 struct snd_pcm_substream *substream = entry->private_data;
401 struct snd_pcm_runtime *runtime = substream->runtime; 411 struct snd_pcm_runtime *runtime;
412
413 mutex_lock(&substream->pcm->open_mutex);
414 runtime = substream->runtime;
402 if (!runtime) { 415 if (!runtime) {
403 snd_iprintf(buffer, "closed\n"); 416 snd_iprintf(buffer, "closed\n");
404 return; 417 goto unlock;
405 } 418 }
406 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) { 419 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) {
407 snd_iprintf(buffer, "no setup\n"); 420 snd_iprintf(buffer, "no setup\n");
408 return; 421 goto unlock;
409 } 422 }
410 snd_iprintf(buffer, "tstamp_mode: %s\n", snd_pcm_tstamp_mode_name(runtime->tstamp_mode)); 423 snd_iprintf(buffer, "tstamp_mode: %s\n", snd_pcm_tstamp_mode_name(runtime->tstamp_mode));
411 snd_iprintf(buffer, "period_step: %u\n", runtime->period_step); 424 snd_iprintf(buffer, "period_step: %u\n", runtime->period_step);
@@ -415,24 +428,29 @@ static void snd_pcm_substream_proc_sw_params_read(struct snd_info_entry *entry,
415 snd_iprintf(buffer, "silence_threshold: %lu\n", runtime->silence_threshold); 428 snd_iprintf(buffer, "silence_threshold: %lu\n", runtime->silence_threshold);
416 snd_iprintf(buffer, "silence_size: %lu\n", runtime->silence_size); 429 snd_iprintf(buffer, "silence_size: %lu\n", runtime->silence_size);
417 snd_iprintf(buffer, "boundary: %lu\n", runtime->boundary); 430 snd_iprintf(buffer, "boundary: %lu\n", runtime->boundary);
431 unlock:
432 mutex_unlock(&substream->pcm->open_mutex);
418} 433}
419 434
420static void snd_pcm_substream_proc_status_read(struct snd_info_entry *entry, 435static void snd_pcm_substream_proc_status_read(struct snd_info_entry *entry,
421 struct snd_info_buffer *buffer) 436 struct snd_info_buffer *buffer)
422{ 437{
423 struct snd_pcm_substream *substream = entry->private_data; 438 struct snd_pcm_substream *substream = entry->private_data;
424 struct snd_pcm_runtime *runtime = substream->runtime; 439 struct snd_pcm_runtime *runtime;
425 struct snd_pcm_status status; 440 struct snd_pcm_status status;
426 int err; 441 int err;
442
443 mutex_lock(&substream->pcm->open_mutex);
444 runtime = substream->runtime;
427 if (!runtime) { 445 if (!runtime) {
428 snd_iprintf(buffer, "closed\n"); 446 snd_iprintf(buffer, "closed\n");
429 return; 447 goto unlock;
430 } 448 }
431 memset(&status, 0, sizeof(status)); 449 memset(&status, 0, sizeof(status));
432 err = snd_pcm_status(substream, &status); 450 err = snd_pcm_status(substream, &status);
433 if (err < 0) { 451 if (err < 0) {
434 snd_iprintf(buffer, "error %d\n", err); 452 snd_iprintf(buffer, "error %d\n", err);
435 return; 453 goto unlock;
436 } 454 }
437 snd_iprintf(buffer, "state: %s\n", snd_pcm_state_name(status.state)); 455 snd_iprintf(buffer, "state: %s\n", snd_pcm_state_name(status.state));
438 snd_iprintf(buffer, "owner_pid : %d\n", pid_vnr(substream->pid)); 456 snd_iprintf(buffer, "owner_pid : %d\n", pid_vnr(substream->pid));
@@ -446,6 +464,8 @@ static void snd_pcm_substream_proc_status_read(struct snd_info_entry *entry,
446 snd_iprintf(buffer, "-----\n"); 464 snd_iprintf(buffer, "-----\n");
447 snd_iprintf(buffer, "hw_ptr : %ld\n", runtime->status->hw_ptr); 465 snd_iprintf(buffer, "hw_ptr : %ld\n", runtime->status->hw_ptr);
448 snd_iprintf(buffer, "appl_ptr : %ld\n", runtime->control->appl_ptr); 466 snd_iprintf(buffer, "appl_ptr : %ld\n", runtime->control->appl_ptr);
467 unlock:
468 mutex_unlock(&substream->pcm->open_mutex);
449} 469}
450 470
451#ifdef CONFIG_SND_PCM_XRUN_DEBUG 471#ifdef CONFIG_SND_PCM_XRUN_DEBUG
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index d6ecca27bb6..a1707cca9c6 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -67,6 +67,8 @@ void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_ufram
67 } else { 67 } else {
68 if (new_hw_ptr == ULONG_MAX) { /* initialization */ 68 if (new_hw_ptr == ULONG_MAX) { /* initialization */
69 snd_pcm_sframes_t avail = snd_pcm_playback_hw_avail(runtime); 69 snd_pcm_sframes_t avail = snd_pcm_playback_hw_avail(runtime);
70 if (avail > runtime->buffer_size)
71 avail = runtime->buffer_size;
70 runtime->silence_filled = avail > 0 ? avail : 0; 72 runtime->silence_filled = avail > 0 ? avail : 0;
71 runtime->silence_start = (runtime->status->hw_ptr + 73 runtime->silence_start = (runtime->status->hw_ptr +
72 runtime->silence_filled) % 74 runtime->silence_filled) %
@@ -287,8 +289,11 @@ int snd_pcm_update_state(struct snd_pcm_substream *substream,
287 return -EPIPE; 289 return -EPIPE;
288 } 290 }
289 } 291 }
290 if (avail >= runtime->control->avail_min) 292 if (runtime->twake) {
291 wake_up(runtime->twake ? &runtime->tsleep : &runtime->sleep); 293 if (avail >= runtime->twake)
294 wake_up(&runtime->tsleep);
295 } else if (avail >= runtime->control->avail_min)
296 wake_up(&runtime->sleep);
292 return 0; 297 return 0;
293} 298}
294 299
@@ -1711,7 +1716,7 @@ EXPORT_SYMBOL(snd_pcm_period_elapsed);
1711 * The available space is stored on availp. When err = 0 and avail = 0 1716 * The available space is stored on availp. When err = 0 and avail = 0
1712 * on the capture stream, it indicates the stream is in DRAINING state. 1717 * on the capture stream, it indicates the stream is in DRAINING state.
1713 */ 1718 */
1714static int wait_for_avail_min(struct snd_pcm_substream *substream, 1719static int wait_for_avail(struct snd_pcm_substream *substream,
1715 snd_pcm_uframes_t *availp) 1720 snd_pcm_uframes_t *availp)
1716{ 1721{
1717 struct snd_pcm_runtime *runtime = substream->runtime; 1722 struct snd_pcm_runtime *runtime = substream->runtime;
@@ -1761,7 +1766,7 @@ static int wait_for_avail_min(struct snd_pcm_substream *substream,
1761 avail = snd_pcm_playback_avail(runtime); 1766 avail = snd_pcm_playback_avail(runtime);
1762 else 1767 else
1763 avail = snd_pcm_capture_avail(runtime); 1768 avail = snd_pcm_capture_avail(runtime);
1764 if (avail >= runtime->control->avail_min) 1769 if (avail >= runtime->twake)
1765 break; 1770 break;
1766 } 1771 }
1767 _endloop: 1772 _endloop:
@@ -1824,7 +1829,7 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream,
1824 goto _end_unlock; 1829 goto _end_unlock;
1825 } 1830 }
1826 1831
1827 runtime->twake = 1; 1832 runtime->twake = runtime->control->avail_min ? : 1;
1828 while (size > 0) { 1833 while (size > 0) {
1829 snd_pcm_uframes_t frames, appl_ptr, appl_ofs; 1834 snd_pcm_uframes_t frames, appl_ptr, appl_ofs;
1830 snd_pcm_uframes_t avail; 1835 snd_pcm_uframes_t avail;
@@ -1837,7 +1842,9 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream,
1837 err = -EAGAIN; 1842 err = -EAGAIN;
1838 goto _end_unlock; 1843 goto _end_unlock;
1839 } 1844 }
1840 err = wait_for_avail_min(substream, &avail); 1845 runtime->twake = min_t(snd_pcm_uframes_t, size,
1846 runtime->control->avail_min ? : 1);
1847 err = wait_for_avail(substream, &avail);
1841 if (err < 0) 1848 if (err < 0)
1842 goto _end_unlock; 1849 goto _end_unlock;
1843 } 1850 }
@@ -2046,7 +2053,7 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream,
2046 goto _end_unlock; 2053 goto _end_unlock;
2047 } 2054 }
2048 2055
2049 runtime->twake = 1; 2056 runtime->twake = runtime->control->avail_min ? : 1;
2050 while (size > 0) { 2057 while (size > 0) {
2051 snd_pcm_uframes_t frames, appl_ptr, appl_ofs; 2058 snd_pcm_uframes_t frames, appl_ptr, appl_ofs;
2052 snd_pcm_uframes_t avail; 2059 snd_pcm_uframes_t avail;
@@ -2064,7 +2071,9 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream,
2064 err = -EAGAIN; 2071 err = -EAGAIN;
2065 goto _end_unlock; 2072 goto _end_unlock;
2066 } 2073 }
2067 err = wait_for_avail_min(substream, &avail); 2074 runtime->twake = min_t(snd_pcm_uframes_t, size,
2075 runtime->control->avail_min ? : 1);
2076 err = wait_for_avail(substream, &avail);
2068 if (err < 0) 2077 if (err < 0)
2069 goto _end_unlock; 2078 goto _end_unlock;
2070 if (!avail) 2079 if (!avail)
diff --git a/sound/core/pcm_misc.c b/sound/core/pcm_misc.c
index ea2bf82c937..434af3c56d5 100644
--- a/sound/core/pcm_misc.c
+++ b/sound/core/pcm_misc.c
@@ -128,6 +128,14 @@ static struct pcm_format_data pcm_formats[SNDRV_PCM_FORMAT_LAST+1] = {
128 .width = 4, .phys = 4, .le = -1, .signd = -1, 128 .width = 4, .phys = 4, .le = -1, .signd = -1,
129 .silence = {}, 129 .silence = {},
130 }, 130 },
131 [SNDRV_PCM_FORMAT_G723_24] = {
132 .width = 3, .phys = 3, .le = -1, .signd = -1,
133 .silence = {},
134 },
135 [SNDRV_PCM_FORMAT_G723_40] = {
136 .width = 5, .phys = 5, .le = -1, .signd = -1,
137 .silence = {},
138 },
131 /* FIXME: the following three formats are not defined properly yet */ 139 /* FIXME: the following three formats are not defined properly yet */
132 [SNDRV_PCM_FORMAT_MPEG] = { 140 [SNDRV_PCM_FORMAT_MPEG] = {
133 .le = -1, .signd = -1, 141 .le = -1, .signd = -1,
@@ -186,6 +194,14 @@ static struct pcm_format_data pcm_formats[SNDRV_PCM_FORMAT_LAST+1] = {
186 .width = 18, .phys = 24, .le = 0, .signd = 0, 194 .width = 18, .phys = 24, .le = 0, .signd = 0,
187 .silence = { 0x02, 0x00, 0x00 }, 195 .silence = { 0x02, 0x00, 0x00 },
188 }, 196 },
197 [SNDRV_PCM_FORMAT_G723_24_1B] = {
198 .width = 3, .phys = 8, .le = -1, .signd = -1,
199 .silence = {},
200 },
201 [SNDRV_PCM_FORMAT_G723_40_1B] = {
202 .width = 5, .phys = 8, .le = -1, .signd = -1,
203 .silence = {},
204 },
189}; 205};
190 206
191 207
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 2d2e1b65ee9..8bc7cb3db33 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -142,7 +142,7 @@ int snd_pcm_info_user(struct snd_pcm_substream *substream,
142 142
143#ifdef RULES_DEBUG 143#ifdef RULES_DEBUG
144#define HW_PARAM(v) [SNDRV_PCM_HW_PARAM_##v] = #v 144#define HW_PARAM(v) [SNDRV_PCM_HW_PARAM_##v] = #v
145char *snd_pcm_hw_param_names[] = { 145static const char * const snd_pcm_hw_param_names[] = {
146 HW_PARAM(ACCESS), 146 HW_PARAM(ACCESS),
147 HW_PARAM(FORMAT), 147 HW_PARAM(FORMAT),
148 HW_PARAM(SUBFORMAT), 148 HW_PARAM(SUBFORMAT),
@@ -451,13 +451,11 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
451 snd_pcm_timer_resolution_change(substream); 451 snd_pcm_timer_resolution_change(substream);
452 runtime->status->state = SNDRV_PCM_STATE_SETUP; 452 runtime->status->state = SNDRV_PCM_STATE_SETUP;
453 453
454 if (substream->latency_pm_qos_req) { 454 if (pm_qos_request_active(&substream->latency_pm_qos_req))
455 pm_qos_remove_request(substream->latency_pm_qos_req); 455 pm_qos_remove_request(&substream->latency_pm_qos_req);
456 substream->latency_pm_qos_req = NULL;
457 }
458 if ((usecs = period_to_usecs(runtime)) >= 0) 456 if ((usecs = period_to_usecs(runtime)) >= 0)
459 substream->latency_pm_qos_req = pm_qos_add_request( 457 pm_qos_add_request(&substream->latency_pm_qos_req,
460 PM_QOS_CPU_DMA_LATENCY, usecs); 458 PM_QOS_CPU_DMA_LATENCY, usecs);
461 return 0; 459 return 0;
462 _error: 460 _error:
463 /* hardware might be unuseable from this time, 461 /* hardware might be unuseable from this time,
@@ -512,8 +510,7 @@ static int snd_pcm_hw_free(struct snd_pcm_substream *substream)
512 if (substream->ops->hw_free) 510 if (substream->ops->hw_free)
513 result = substream->ops->hw_free(substream); 511 result = substream->ops->hw_free(substream);
514 runtime->status->state = SNDRV_PCM_STATE_OPEN; 512 runtime->status->state = SNDRV_PCM_STATE_OPEN;
515 pm_qos_remove_request(substream->latency_pm_qos_req); 513 pm_qos_remove_request(&substream->latency_pm_qos_req);
516 substream->latency_pm_qos_req = NULL;
517 return result; 514 return result;
518} 515}
519 516
@@ -983,6 +980,10 @@ static int snd_pcm_do_pause(struct snd_pcm_substream *substream, int push)
983{ 980{
984 if (substream->runtime->trigger_master != substream) 981 if (substream->runtime->trigger_master != substream)
985 return 0; 982 return 0;
983 /* some drivers might use hw_ptr to recover from the pause -
984 update the hw_ptr now */
985 if (push)
986 snd_pcm_update_hw_ptr(substream);
986 /* The jiffies check in snd_pcm_update_hw_ptr*() is done by 987 /* The jiffies check in snd_pcm_update_hw_ptr*() is done by
987 * a delta betwen the current jiffies, this gives a large enough 988 * a delta betwen the current jiffies, this gives a large enough
988 * delta, effectively to skip the check once. 989 * delta, effectively to skip the check once.
@@ -1993,6 +1994,8 @@ void snd_pcm_release_substream(struct snd_pcm_substream *substream)
1993 substream->ops->close(substream); 1994 substream->ops->close(substream);
1994 substream->hw_opened = 0; 1995 substream->hw_opened = 0;
1995 } 1996 }
1997 if (pm_qos_request_active(&substream->latency_pm_qos_req))
1998 pm_qos_remove_request(&substream->latency_pm_qos_req);
1996 if (substream->pcm_release) { 1999 if (substream->pcm_release) {
1997 substream->pcm_release(substream); 2000 substream->pcm_release(substream);
1998 substream->pcm_release = NULL; 2001 substream->pcm_release = NULL;
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index eb68326c37d..a7868ad4d53 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -829,6 +829,8 @@ static int snd_rawmidi_control_ioctl(struct snd_card *card,
829 829
830 if (get_user(device, (int __user *)argp)) 830 if (get_user(device, (int __user *)argp))
831 return -EFAULT; 831 return -EFAULT;
832 if (device >= SNDRV_RAWMIDI_DEVICES) /* next device is -1 */
833 device = SNDRV_RAWMIDI_DEVICES - 1;
832 mutex_lock(&register_mutex); 834 mutex_lock(&register_mutex);
833 device = device < 0 ? 0 : device + 1; 835 device = device < 0 ? 0 : device + 1;
834 while (device < SNDRV_RAWMIDI_DEVICES) { 836 while (device < SNDRV_RAWMIDI_DEVICES) {
diff --git a/sound/core/seq/oss/seq_oss_init.c b/sound/core/seq/oss/seq_oss_init.c
index 685712276ac..69cd7b3c362 100644
--- a/sound/core/seq/oss/seq_oss_init.c
+++ b/sound/core/seq/oss/seq_oss_init.c
@@ -281,13 +281,10 @@ snd_seq_oss_open(struct file *file, int level)
281 return 0; 281 return 0;
282 282
283 _error: 283 _error:
284 snd_seq_oss_writeq_delete(dp->writeq);
285 snd_seq_oss_readq_delete(dp->readq);
286 snd_seq_oss_synth_cleanup(dp); 284 snd_seq_oss_synth_cleanup(dp);
287 snd_seq_oss_midi_cleanup(dp); 285 snd_seq_oss_midi_cleanup(dp);
288 delete_port(dp);
289 delete_seq_queue(dp->queue); 286 delete_seq_queue(dp->queue);
290 kfree(dp); 287 delete_port(dp);
291 288
292 return rc; 289 return rc;
293} 290}
@@ -350,8 +347,10 @@ create_port(struct seq_oss_devinfo *dp)
350static int 347static int
351delete_port(struct seq_oss_devinfo *dp) 348delete_port(struct seq_oss_devinfo *dp)
352{ 349{
353 if (dp->port < 0) 350 if (dp->port < 0) {
351 kfree(dp);
354 return 0; 352 return 0;
353 }
355 354
356 debug_printk(("delete_port %i\n", dp->port)); 355 debug_printk(("delete_port %i\n", dp->port));
357 return snd_seq_event_port_detach(dp->cseq, dp->port); 356 return snd_seq_event_port_detach(dp->cseq, dp->port);
diff --git a/sound/drivers/Kconfig b/sound/drivers/Kconfig
index b6ae7628525..c8961165277 100644
--- a/sound/drivers/Kconfig
+++ b/sound/drivers/Kconfig
@@ -174,7 +174,7 @@ config SND_ML403_AC97CR
174 select SND_AC97_CODEC 174 select SND_AC97_CODEC
175 help 175 help
176 Say Y here to include support for the 176 Say Y here to include support for the
177 opb_ac97_controller_ref_v1_00_a ip core found in Xilinx' ML403 177 opb_ac97_controller_ref_v1_00_a ip core found in Xilinx's ML403
178 reference design. 178 reference design.
179 179
180 To compile this driver as a module, choose M here: the module 180 To compile this driver as a module, choose M here: the module
@@ -189,9 +189,25 @@ config SND_AC97_POWER_SAVE
189 AC97 codecs. In this mode, the power-mode is dynamically 189 AC97 codecs. In this mode, the power-mode is dynamically
190 controlled at each open/close. 190 controlled at each open/close.
191 191
192 The mode is activated by passing power_save=1 option to 192 The mode is activated by passing 'power_save=X' to the
193 snd-ac97-codec driver. You can toggle it dynamically over 193 snd-ac97-codec driver module, where 'X' is the time-out
194 sysfs, too. 194 value, a nonnegative integer that specifies how many
195 seconds of idle time the driver must count before it may
196 put the AC97 into power-save mode; a value of 0 (zero)
197 disables the use of this power-save mode.
198
199 After the snd-ac97-codec driver module has been loaded,
200 the 'power_save' parameter can be set via sysfs as follows:
201
202 echo 10 > /sys/module/snd_ac97_codec/parameters/power_save
203
204 In this case, the time-out is set to 10 seconds; setting
205 the time-out to 1 second (the minimum activation value)
206 isn't recommended because many applications try to reopen
207 the device frequently. A value of 10 seconds would be a
208 good choice for normal operations.
209
210 See Documentation/sound/alsa/powersave.txt for more details.
195 211
196config SND_AC97_POWER_SAVE_DEFAULT 212config SND_AC97_POWER_SAVE_DEFAULT
197 int "Default time-out for AC97 power-save mode" 213 int "Default time-out for AC97 power-save mode"
@@ -201,4 +217,6 @@ config SND_AC97_POWER_SAVE_DEFAULT
201 The default time-out value in seconds for AC97 automatic 217 The default time-out value in seconds for AC97 automatic
202 power-save mode. 0 means to disable the power-save mode. 218 power-save mode. 0 means to disable the power-save mode.
203 219
220 See SND_AC97_POWER_SAVE for more details.
221
204endif # SND_DRIVERS 222endif # SND_DRIVERS
diff --git a/sound/drivers/virmidi.c b/sound/drivers/virmidi.c
index 0e631c3221e..f4cd49336f3 100644
--- a/sound/drivers/virmidi.c
+++ b/sound/drivers/virmidi.c
@@ -94,7 +94,7 @@ static int __devinit snd_virmidi_probe(struct platform_device *devptr)
94 sizeof(struct snd_card_virmidi), &card); 94 sizeof(struct snd_card_virmidi), &card);
95 if (err < 0) 95 if (err < 0)
96 return err; 96 return err;
97 vmidi = (struct snd_card_virmidi *)card->private_data; 97 vmidi = card->private_data;
98 vmidi->card = card; 98 vmidi->card = card;
99 99
100 if (midi_devs[dev] > MAX_MIDI_DEVICES) { 100 if (midi_devs[dev] > MAX_MIDI_DEVICES) {
diff --git a/sound/i2c/other/ak4xxx-adda.c b/sound/i2c/other/ak4xxx-adda.c
index 1adb8a3c2b6..57ccba88700 100644
--- a/sound/i2c/other/ak4xxx-adda.c
+++ b/sound/i2c/other/ak4xxx-adda.c
@@ -878,7 +878,7 @@ static int build_deemphasis(struct snd_akm4xxx *ak, int num_emphs)
878static void proc_regs_read(struct snd_info_entry *entry, 878static void proc_regs_read(struct snd_info_entry *entry,
879 struct snd_info_buffer *buffer) 879 struct snd_info_buffer *buffer)
880{ 880{
881 struct snd_akm4xxx *ak = (struct snd_akm4xxx *)entry->private_data; 881 struct snd_akm4xxx *ak = entry->private_data;
882 int reg, val, chip; 882 int reg, val, chip;
883 for (chip = 0; chip < ak->num_chips; chip++) { 883 for (chip = 0; chip < ak->num_chips; chip++) {
884 for (reg = 0; reg < ak->total_regs; reg++) { 884 for (reg = 0; reg < ak->total_regs; reg++) {
@@ -900,7 +900,7 @@ static int proc_init(struct snd_akm4xxx *ak)
900 return 0; 900 return 0;
901} 901}
902#else /* !CONFIG_PROC_FS */ 902#else /* !CONFIG_PROC_FS */
903static int proc_init(struct snd_akm4xxx *ak) {} 903static int proc_init(struct snd_akm4xxx *ak) { return 0; }
904#endif 904#endif
905 905
906int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak) 906int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak)
diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig
index c6990c68079..52064cfa91f 100644
--- a/sound/isa/Kconfig
+++ b/sound/isa/Kconfig
@@ -77,6 +77,32 @@ config SND_ALS100
77 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
78 will be called snd-als100. 78 will be called snd-als100.
79 79
80config SND_AZT1605
81 tristate "Aztech AZT1605 Driver"
82 depends on SND
83 select SND_WSS_LIB
84 select SND_MPU401_UART
85 select SND_OPL3_LIB
86 help
87 Say Y here to include support for Aztech Sound Galaxy cards
88 based on the AZT1605 chipset.
89
90 To compile this driver as a module, choose M here: the module
91 will be called snd-azt1605.
92
93config SND_AZT2316
94 tristate "Aztech AZT2316 Driver"
95 depends on SND
96 select SND_WSS_LIB
97 select SND_MPU401_UART
98 select SND_OPL3_LIB
99 help
100 Say Y here to include support for Aztech Sound Galaxy cards
101 based on the AZT2316 chipset.
102
103 To compile this driver as a module, choose M here: the module
104 will be called snd-azt2316.
105
80config SND_AZT2320 106config SND_AZT2320
81 tristate "Aztech Systems AZT2320" 107 tristate "Aztech Systems AZT2320"
82 depends on PNP 108 depends on PNP
@@ -351,16 +377,6 @@ config SND_SB16_CSP
351 coprocessor can do variable tasks like various compression and 377 coprocessor can do variable tasks like various compression and
352 decompression algorithms. 378 decompression algorithms.
353 379
354config SND_SGALAXY
355 tristate "Aztech Sound Galaxy"
356 select SND_WSS_LIB
357 help
358 Say Y here to include support for Aztech Sound Galaxy
359 soundcards.
360
361 To compile this driver as a module, choose M here: the module
362 will be called snd-sgalaxy.
363
364config SND_SSCAPE 380config SND_SSCAPE
365 tristate "Ensoniq SoundScape driver" 381 tristate "Ensoniq SoundScape driver"
366 select SND_MPU401_UART 382 select SND_MPU401_UART
diff --git a/sound/isa/Makefile b/sound/isa/Makefile
index c73d30c4f46..8d781e419e2 100644
--- a/sound/isa/Makefile
+++ b/sound/isa/Makefile
@@ -10,7 +10,6 @@ snd-cmi8330-objs := cmi8330.o
10snd-es18xx-objs := es18xx.o 10snd-es18xx-objs := es18xx.o
11snd-opl3sa2-objs := opl3sa2.o 11snd-opl3sa2-objs := opl3sa2.o
12snd-sc6000-objs := sc6000.o 12snd-sc6000-objs := sc6000.o
13snd-sgalaxy-objs := sgalaxy.o
14snd-sscape-objs := sscape.o 13snd-sscape-objs := sscape.o
15 14
16# Toplevel Module Dependency 15# Toplevel Module Dependency
@@ -21,8 +20,7 @@ obj-$(CONFIG_SND_CMI8330) += snd-cmi8330.o
21obj-$(CONFIG_SND_ES18XX) += snd-es18xx.o 20obj-$(CONFIG_SND_ES18XX) += snd-es18xx.o
22obj-$(CONFIG_SND_OPL3SA2) += snd-opl3sa2.o 21obj-$(CONFIG_SND_OPL3SA2) += snd-opl3sa2.o
23obj-$(CONFIG_SND_SC6000) += snd-sc6000.o 22obj-$(CONFIG_SND_SC6000) += snd-sc6000.o
24obj-$(CONFIG_SND_SGALAXY) += snd-sgalaxy.o
25obj-$(CONFIG_SND_SSCAPE) += snd-sscape.o 23obj-$(CONFIG_SND_SSCAPE) += snd-sscape.o
26 24
27obj-$(CONFIG_SND) += ad1816a/ ad1848/ cs423x/ es1688/ gus/ msnd/ opti9xx/ \ 25obj-$(CONFIG_SND) += ad1816a/ ad1848/ cs423x/ es1688/ galaxy/ gus/ msnd/ opti9xx/ \
28 sb/ wavefront/ wss/ 26 sb/ wavefront/ wss/
diff --git a/sound/isa/ad1816a/ad1816a.c b/sound/isa/ad1816a/ad1816a.c
index bbcbf92a8eb..3cb75bc9769 100644
--- a/sound/isa/ad1816a/ad1816a.c
+++ b/sound/isa/ad1816a/ad1816a.c
@@ -162,7 +162,7 @@ static int __devinit snd_card_ad1816a_probe(int dev, struct pnp_card_link *pcard
162 sizeof(struct snd_card_ad1816a), &card); 162 sizeof(struct snd_card_ad1816a), &card);
163 if (error < 0) 163 if (error < 0)
164 return error; 164 return error;
165 acard = (struct snd_card_ad1816a *)card->private_data; 165 acard = card->private_data;
166 166
167 if ((error = snd_card_ad1816a_pnp(dev, acard, pcard, pid))) { 167 if ((error = snd_card_ad1816a_pnp(dev, acard, pcard, pid))) {
168 snd_card_free(card); 168 snd_card_free(card);
diff --git a/sound/isa/azt2320.c b/sound/isa/azt2320.c
index f7aa637b0d1..aac8dc15c2f 100644
--- a/sound/isa/azt2320.c
+++ b/sound/isa/azt2320.c
@@ -188,7 +188,7 @@ static int __devinit snd_card_azt2320_probe(int dev,
188 sizeof(struct snd_card_azt2320), &card); 188 sizeof(struct snd_card_azt2320), &card);
189 if (error < 0) 189 if (error < 0)
190 return error; 190 return error;
191 acard = (struct snd_card_azt2320 *)card->private_data; 191 acard = card->private_data;
192 192
193 if ((error = snd_card_azt2320_pnp(dev, acard, pcard, pid))) { 193 if ((error = snd_card_azt2320_pnp(dev, acard, pcard, pid))) {
194 snd_card_free(card); 194 snd_card_free(card);
diff --git a/sound/isa/galaxy/Makefile b/sound/isa/galaxy/Makefile
new file mode 100644
index 00000000000..e307066d431
--- /dev/null
+++ b/sound/isa/galaxy/Makefile
@@ -0,0 +1,10 @@
1#
2# Makefile for ALSA
3# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
4#
5
6snd-azt1605-objs := azt1605.o
7snd-azt2316-objs := azt2316.o
8
9obj-$(CONFIG_SND_AZT1605) += snd-azt1605.o
10obj-$(CONFIG_SND_AZT2316) += snd-azt2316.o
diff --git a/sound/isa/galaxy/azt1605.c b/sound/isa/galaxy/azt1605.c
new file mode 100644
index 00000000000..9a97643cb71
--- /dev/null
+++ b/sound/isa/galaxy/azt1605.c
@@ -0,0 +1,91 @@
1/*
2 * Aztech AZT1605 Driver
3 * Copyright (C) 2007,2010 Rene Herman
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program 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 program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 */
19
20#define AZT1605
21
22#define CRD_NAME "Aztech AZT1605"
23#define DRV_NAME "AZT1605"
24#define DEV_NAME "azt1605"
25
26#define GALAXY_DSP_MAJOR 2
27#define GALAXY_DSP_MINOR 1
28
29#define GALAXY_CONFIG_SIZE 3
30
31/*
32 * 24-bit config register
33 */
34
35#define GALAXY_CONFIG_SBA_220 (0 << 0)
36#define GALAXY_CONFIG_SBA_240 (1 << 0)
37#define GALAXY_CONFIG_SBA_260 (2 << 0)
38#define GALAXY_CONFIG_SBA_280 (3 << 0)
39#define GALAXY_CONFIG_SBA_MASK GALAXY_CONFIG_SBA_280
40
41#define GALAXY_CONFIG_MPUA_300 (0 << 2)
42#define GALAXY_CONFIG_MPUA_330 (1 << 2)
43
44#define GALAXY_CONFIG_MPU_ENABLE (1 << 3)
45
46#define GALAXY_CONFIG_GAME_ENABLE (1 << 4)
47
48#define GALAXY_CONFIG_CD_PANASONIC (1 << 5)
49#define GALAXY_CONFIG_CD_MITSUMI (1 << 6)
50#define GALAXY_CONFIG_CD_MASK (\
51 GALAXY_CONFIG_CD_PANASONIC | GALAXY_CONFIG_CD_MITSUMI)
52
53#define GALAXY_CONFIG_UNUSED (1 << 7)
54#define GALAXY_CONFIG_UNUSED_MASK GALAXY_CONFIG_UNUSED
55
56#define GALAXY_CONFIG_SBIRQ_2 (1 << 8)
57#define GALAXY_CONFIG_SBIRQ_3 (1 << 9)
58#define GALAXY_CONFIG_SBIRQ_5 (1 << 10)
59#define GALAXY_CONFIG_SBIRQ_7 (1 << 11)
60
61#define GALAXY_CONFIG_MPUIRQ_2 (1 << 12)
62#define GALAXY_CONFIG_MPUIRQ_3 (1 << 13)
63#define GALAXY_CONFIG_MPUIRQ_5 (1 << 14)
64#define GALAXY_CONFIG_MPUIRQ_7 (1 << 15)
65
66#define GALAXY_CONFIG_WSSA_530 (0 << 16)
67#define GALAXY_CONFIG_WSSA_604 (1 << 16)
68#define GALAXY_CONFIG_WSSA_E80 (2 << 16)
69#define GALAXY_CONFIG_WSSA_F40 (3 << 16)
70
71#define GALAXY_CONFIG_WSS_ENABLE (1 << 18)
72
73#define GALAXY_CONFIG_CDIRQ_11 (1 << 19)
74#define GALAXY_CONFIG_CDIRQ_12 (1 << 20)
75#define GALAXY_CONFIG_CDIRQ_15 (1 << 21)
76#define GALAXY_CONFIG_CDIRQ_MASK (\
77 GALAXY_CONFIG_CDIRQ_11 | GALAXY_CONFIG_CDIRQ_12 |\
78 GALAXY_CONFIG_CDIRQ_15)
79
80#define GALAXY_CONFIG_CDDMA_DISABLE (0 << 22)
81#define GALAXY_CONFIG_CDDMA_0 (1 << 22)
82#define GALAXY_CONFIG_CDDMA_1 (2 << 22)
83#define GALAXY_CONFIG_CDDMA_3 (3 << 22)
84#define GALAXY_CONFIG_CDDMA_MASK GALAXY_CONFIG_CDDMA_3
85
86#define GALAXY_CONFIG_MASK (\
87 GALAXY_CONFIG_SBA_MASK | GALAXY_CONFIG_CD_MASK |\
88 GALAXY_CONFIG_UNUSED_MASK | GALAXY_CONFIG_CDIRQ_MASK |\
89 GALAXY_CONFIG_CDDMA_MASK)
90
91#include "galaxy.c"
diff --git a/sound/isa/galaxy/azt2316.c b/sound/isa/galaxy/azt2316.c
new file mode 100644
index 00000000000..189441141df
--- /dev/null
+++ b/sound/isa/galaxy/azt2316.c
@@ -0,0 +1,111 @@
1/*
2 * Aztech AZT2316 Driver
3 * Copyright (C) 2007,2010 Rene Herman
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program 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 program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 */
19
20#define AZT2316
21
22#define CRD_NAME "Aztech AZT2316"
23#define DRV_NAME "AZT2316"
24#define DEV_NAME "azt2316"
25
26#define GALAXY_DSP_MAJOR 3
27#define GALAXY_DSP_MINOR 1
28
29#define GALAXY_CONFIG_SIZE 4
30
31/*
32 * 32-bit config register
33 */
34
35#define GALAXY_CONFIG_SBA_220 (0 << 0)
36#define GALAXY_CONFIG_SBA_240 (1 << 0)
37#define GALAXY_CONFIG_SBA_260 (2 << 0)
38#define GALAXY_CONFIG_SBA_280 (3 << 0)
39#define GALAXY_CONFIG_SBA_MASK GALAXY_CONFIG_SBA_280
40
41#define GALAXY_CONFIG_SBIRQ_2 (1 << 2)
42#define GALAXY_CONFIG_SBIRQ_5 (1 << 3)
43#define GALAXY_CONFIG_SBIRQ_7 (1 << 4)
44#define GALAXY_CONFIG_SBIRQ_10 (1 << 5)
45
46#define GALAXY_CONFIG_SBDMA_DISABLE (0 << 6)
47#define GALAXY_CONFIG_SBDMA_0 (1 << 6)
48#define GALAXY_CONFIG_SBDMA_1 (2 << 6)
49#define GALAXY_CONFIG_SBDMA_3 (3 << 6)
50
51#define GALAXY_CONFIG_WSSA_530 (0 << 8)
52#define GALAXY_CONFIG_WSSA_604 (1 << 8)
53#define GALAXY_CONFIG_WSSA_E80 (2 << 8)
54#define GALAXY_CONFIG_WSSA_F40 (3 << 8)
55
56#define GALAXY_CONFIG_WSS_ENABLE (1 << 10)
57
58#define GALAXY_CONFIG_GAME_ENABLE (1 << 11)
59
60#define GALAXY_CONFIG_MPUA_300 (0 << 12)
61#define GALAXY_CONFIG_MPUA_330 (1 << 12)
62
63#define GALAXY_CONFIG_MPU_ENABLE (1 << 13)
64
65#define GALAXY_CONFIG_CDA_310 (0 << 14)
66#define GALAXY_CONFIG_CDA_320 (1 << 14)
67#define GALAXY_CONFIG_CDA_340 (2 << 14)
68#define GALAXY_CONFIG_CDA_350 (3 << 14)
69#define GALAXY_CONFIG_CDA_MASK GALAXY_CONFIG_CDA_350
70
71#define GALAXY_CONFIG_CD_DISABLE (0 << 16)
72#define GALAXY_CONFIG_CD_PANASONIC (1 << 16)
73#define GALAXY_CONFIG_CD_SONY (2 << 16)
74#define GALAXY_CONFIG_CD_MITSUMI (3 << 16)
75#define GALAXY_CONFIG_CD_AZTECH (4 << 16)
76#define GALAXY_CONFIG_CD_UNUSED_5 (5 << 16)
77#define GALAXY_CONFIG_CD_UNUSED_6 (6 << 16)
78#define GALAXY_CONFIG_CD_UNUSED_7 (7 << 16)
79#define GALAXY_CONFIG_CD_MASK GALAXY_CONFIG_CD_UNUSED_7
80
81#define GALAXY_CONFIG_CDDMA8_DISABLE (0 << 20)
82#define GALAXY_CONFIG_CDDMA8_0 (1 << 20)
83#define GALAXY_CONFIG_CDDMA8_1 (2 << 20)
84#define GALAXY_CONFIG_CDDMA8_3 (3 << 20)
85#define GALAXY_CONFIG_CDDMA8_MASK GALAXY_CONFIG_CDDMA8_3
86
87#define GALAXY_CONFIG_CDDMA16_DISABLE (0 << 22)
88#define GALAXY_CONFIG_CDDMA16_5 (1 << 22)
89#define GALAXY_CONFIG_CDDMA16_6 (2 << 22)
90#define GALAXY_CONFIG_CDDMA16_7 (3 << 22)
91#define GALAXY_CONFIG_CDDMA16_MASK GALAXY_CONFIG_CDDMA16_7
92
93#define GALAXY_CONFIG_MPUIRQ_2 (1 << 24)
94#define GALAXY_CONFIG_MPUIRQ_5 (1 << 25)
95#define GALAXY_CONFIG_MPUIRQ_7 (1 << 26)
96#define GALAXY_CONFIG_MPUIRQ_10 (1 << 27)
97
98#define GALAXY_CONFIG_CDIRQ_5 (1 << 28)
99#define GALAXY_CONFIG_CDIRQ_11 (1 << 29)
100#define GALAXY_CONFIG_CDIRQ_12 (1 << 30)
101#define GALAXY_CONFIG_CDIRQ_15 (1 << 31)
102#define GALAXY_CONFIG_CDIRQ_MASK (\
103 GALAXY_CONFIG_CDIRQ_5 | GALAXY_CONFIG_CDIRQ_11 |\
104 GALAXY_CONFIG_CDIRQ_12 | GALAXY_CONFIG_CDIRQ_15)
105
106#define GALAXY_CONFIG_MASK (\
107 GALAXY_CONFIG_SBA_MASK | GALAXY_CONFIG_CDA_MASK |\
108 GALAXY_CONFIG_CD_MASK | GALAXY_CONFIG_CDDMA16_MASK |\
109 GALAXY_CONFIG_CDDMA8_MASK | GALAXY_CONFIG_CDIRQ_MASK)
110
111#include "galaxy.c"
diff --git a/sound/isa/galaxy/galaxy.c b/sound/isa/galaxy/galaxy.c
new file mode 100644
index 00000000000..ee54df082b9
--- /dev/null
+++ b/sound/isa/galaxy/galaxy.c
@@ -0,0 +1,652 @@
1/*
2 * Aztech AZT1605/AZT2316 Driver
3 * Copyright (C) 2007,2010 Rene Herman
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program 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 program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 */
19
20#include <linux/kernel.h>
21#include <linux/module.h>
22#include <linux/isa.h>
23#include <linux/delay.h>
24#include <linux/io.h>
25#include <asm/processor.h>
26#include <sound/core.h>
27#include <sound/initval.h>
28#include <sound/wss.h>
29#include <sound/mpu401.h>
30#include <sound/opl3.h>
31
32MODULE_DESCRIPTION(CRD_NAME);
33MODULE_AUTHOR("Rene Herman");
34MODULE_LICENSE("GPL");
35
36static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
37static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
38static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE;
39
40module_param_array(index, int, NULL, 0444);
41MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard.");
42module_param_array(id, charp, NULL, 0444);
43MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard.");
44module_param_array(enable, bool, NULL, 0444);
45MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
46
47static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
48static long wss_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
49static long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
50static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
51static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
52static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
53static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;
54static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;
55
56module_param_array(port, long, NULL, 0444);
57MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
58module_param_array(wss_port, long, NULL, 0444);
59MODULE_PARM_DESC(wss_port, "WSS port # for " CRD_NAME " driver.");
60module_param_array(mpu_port, long, NULL, 0444);
61MODULE_PARM_DESC(mpu_port, "MPU-401 port # for " CRD_NAME " driver.");
62module_param_array(fm_port, long, NULL, 0444);
63MODULE_PARM_DESC(fm_port, "FM port # for " CRD_NAME " driver.");
64module_param_array(irq, int, NULL, 0444);
65MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver.");
66module_param_array(mpu_irq, int, NULL, 0444);
67MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " CRD_NAME " driver.");
68module_param_array(dma1, int, NULL, 0444);
69MODULE_PARM_DESC(dma1, "Playback DMA # for " CRD_NAME " driver.");
70module_param_array(dma2, int, NULL, 0444);
71MODULE_PARM_DESC(dma2, "Capture DMA # for " CRD_NAME " driver.");
72
73/*
74 * Generic SB DSP support routines
75 */
76
77#define DSP_PORT_RESET 0x6
78#define DSP_PORT_READ 0xa
79#define DSP_PORT_COMMAND 0xc
80#define DSP_PORT_STATUS 0xc
81#define DSP_PORT_DATA_AVAIL 0xe
82
83#define DSP_SIGNATURE 0xaa
84
85#define DSP_COMMAND_GET_VERSION 0xe1
86
87static int __devinit dsp_get_byte(void __iomem *port, u8 *val)
88{
89 int loops = 1000;
90
91 while (!(ioread8(port + DSP_PORT_DATA_AVAIL) & 0x80)) {
92 if (!loops--)
93 return -EIO;
94 cpu_relax();
95 }
96 *val = ioread8(port + DSP_PORT_READ);
97 return 0;
98}
99
100static int __devinit dsp_reset(void __iomem *port)
101{
102 u8 val;
103
104 iowrite8(1, port + DSP_PORT_RESET);
105 udelay(10);
106 iowrite8(0, port + DSP_PORT_RESET);
107
108 if (dsp_get_byte(port, &val) < 0 || val != DSP_SIGNATURE)
109 return -ENODEV;
110
111 return 0;
112}
113
114static int __devinit dsp_command(void __iomem *port, u8 cmd)
115{
116 int loops = 1000;
117
118 while (ioread8(port + DSP_PORT_STATUS) & 0x80) {
119 if (!loops--)
120 return -EIO;
121 cpu_relax();
122 }
123 iowrite8(cmd, port + DSP_PORT_COMMAND);
124 return 0;
125}
126
127static int __devinit dsp_get_version(void __iomem *port, u8 *major, u8 *minor)
128{
129 int err;
130
131 err = dsp_command(port, DSP_COMMAND_GET_VERSION);
132 if (err < 0)
133 return err;
134
135 err = dsp_get_byte(port, major);
136 if (err < 0)
137 return err;
138
139 err = dsp_get_byte(port, minor);
140 if (err < 0)
141 return err;
142
143 return 0;
144}
145
146/*
147 * Generic WSS support routines
148 */
149
150#define WSS_CONFIG_DMA_0 (1 << 0)
151#define WSS_CONFIG_DMA_1 (2 << 0)
152#define WSS_CONFIG_DMA_3 (3 << 0)
153#define WSS_CONFIG_DUPLEX (1 << 2)
154#define WSS_CONFIG_IRQ_7 (1 << 3)
155#define WSS_CONFIG_IRQ_9 (2 << 3)
156#define WSS_CONFIG_IRQ_10 (3 << 3)
157#define WSS_CONFIG_IRQ_11 (4 << 3)
158
159#define WSS_PORT_CONFIG 0
160#define WSS_PORT_SIGNATURE 3
161
162#define WSS_SIGNATURE 4
163
164static int __devinit wss_detect(void __iomem *wss_port)
165{
166 if ((ioread8(wss_port + WSS_PORT_SIGNATURE) & 0x3f) != WSS_SIGNATURE)
167 return -ENODEV;
168
169 return 0;
170}
171
172static void wss_set_config(void __iomem *wss_port, u8 wss_config)
173{
174 iowrite8(wss_config, wss_port + WSS_PORT_CONFIG);
175}
176
177/*
178 * Aztech Sound Galaxy specifics
179 */
180
181#define GALAXY_PORT_CONFIG 1024
182#define CONFIG_PORT_SET 4
183
184#define DSP_COMMAND_GALAXY_8 8
185#define GALAXY_COMMAND_GET_TYPE 5
186
187#define DSP_COMMAND_GALAXY_9 9
188#define GALAXY_COMMAND_WSSMODE 0
189#define GALAXY_COMMAND_SB8MODE 1
190
191#define GALAXY_MODE_WSS GALAXY_COMMAND_WSSMODE
192#define GALAXY_MODE_SB8 GALAXY_COMMAND_SB8MODE
193
194struct snd_galaxy {
195 void __iomem *port;
196 void __iomem *config_port;
197 void __iomem *wss_port;
198 u32 config;
199 struct resource *res_port;
200 struct resource *res_config_port;
201 struct resource *res_wss_port;
202};
203
204static u32 config[SNDRV_CARDS];
205static u8 wss_config[SNDRV_CARDS];
206
207static int __devinit snd_galaxy_match(struct device *dev, unsigned int n)
208{
209 if (!enable[n])
210 return 0;
211
212 switch (port[n]) {
213 case SNDRV_AUTO_PORT:
214 dev_err(dev, "please specify port\n");
215 return 0;
216 case 0x220:
217 config[n] |= GALAXY_CONFIG_SBA_220;
218 break;
219 case 0x240:
220 config[n] |= GALAXY_CONFIG_SBA_240;
221 break;
222 case 0x260:
223 config[n] |= GALAXY_CONFIG_SBA_260;
224 break;
225 case 0x280:
226 config[n] |= GALAXY_CONFIG_SBA_280;
227 break;
228 default:
229 dev_err(dev, "invalid port %#lx\n", port[n]);
230 return 0;
231 }
232
233 switch (wss_port[n]) {
234 case SNDRV_AUTO_PORT:
235 dev_err(dev, "please specify wss_port\n");
236 return 0;
237 case 0x530:
238 config[n] |= GALAXY_CONFIG_WSS_ENABLE | GALAXY_CONFIG_WSSA_530;
239 break;
240 case 0x604:
241 config[n] |= GALAXY_CONFIG_WSS_ENABLE | GALAXY_CONFIG_WSSA_604;
242 break;
243 case 0xe80:
244 config[n] |= GALAXY_CONFIG_WSS_ENABLE | GALAXY_CONFIG_WSSA_E80;
245 break;
246 case 0xf40:
247 config[n] |= GALAXY_CONFIG_WSS_ENABLE | GALAXY_CONFIG_WSSA_F40;
248 break;
249 default:
250 dev_err(dev, "invalid WSS port %#lx\n", wss_port[n]);
251 return 0;
252 }
253
254 switch (irq[n]) {
255 case SNDRV_AUTO_IRQ:
256 dev_err(dev, "please specify irq\n");
257 return 0;
258 case 7:
259 wss_config[n] |= WSS_CONFIG_IRQ_7;
260 break;
261 case 2:
262 irq[n] = 9;
263 case 9:
264 wss_config[n] |= WSS_CONFIG_IRQ_9;
265 break;
266 case 10:
267 wss_config[n] |= WSS_CONFIG_IRQ_10;
268 break;
269 case 11:
270 wss_config[n] |= WSS_CONFIG_IRQ_11;
271 break;
272 default:
273 dev_err(dev, "invalid IRQ %d\n", irq[n]);
274 return 0;
275 }
276
277 switch (dma1[n]) {
278 case SNDRV_AUTO_DMA:
279 dev_err(dev, "please specify dma1\n");
280 return 0;
281 case 0:
282 wss_config[n] |= WSS_CONFIG_DMA_0;
283 break;
284 case 1:
285 wss_config[n] |= WSS_CONFIG_DMA_1;
286 break;
287 case 3:
288 wss_config[n] |= WSS_CONFIG_DMA_3;
289 break;
290 default:
291 dev_err(dev, "invalid playback DMA %d\n", dma1[n]);
292 return 0;
293 }
294
295 if (dma2[n] == SNDRV_AUTO_DMA || dma2[n] == dma1[n]) {
296 dma2[n] = -1;
297 goto mpu;
298 }
299
300 wss_config[n] |= WSS_CONFIG_DUPLEX;
301 switch (dma2[n]) {
302 case 0:
303 break;
304 case 1:
305 if (dma1[n] == 0)
306 break;
307 default:
308 dev_err(dev, "invalid capture DMA %d\n", dma2[n]);
309 return 0;
310 }
311
312mpu:
313 switch (mpu_port[n]) {
314 case SNDRV_AUTO_PORT:
315 dev_warn(dev, "mpu_port not specified; not using MPU-401\n");
316 mpu_port[n] = -1;
317 goto fm;
318 case 0x300:
319 config[n] |= GALAXY_CONFIG_MPU_ENABLE | GALAXY_CONFIG_MPUA_300;
320 break;
321 case 0x330:
322 config[n] |= GALAXY_CONFIG_MPU_ENABLE | GALAXY_CONFIG_MPUA_330;
323 break;
324 default:
325 dev_err(dev, "invalid MPU port %#lx\n", mpu_port[n]);
326 return 0;
327 }
328
329 switch (mpu_irq[n]) {
330 case SNDRV_AUTO_IRQ:
331 dev_warn(dev, "mpu_irq not specified: using polling mode\n");
332 mpu_irq[n] = -1;
333 break;
334 case 2:
335 mpu_irq[n] = 9;
336 case 9:
337 config[n] |= GALAXY_CONFIG_MPUIRQ_2;
338 break;
339#ifdef AZT1605
340 case 3:
341 config[n] |= GALAXY_CONFIG_MPUIRQ_3;
342 break;
343#endif
344 case 5:
345 config[n] |= GALAXY_CONFIG_MPUIRQ_5;
346 break;
347 case 7:
348 config[n] |= GALAXY_CONFIG_MPUIRQ_7;
349 break;
350#ifdef AZT2316
351 case 10:
352 config[n] |= GALAXY_CONFIG_MPUIRQ_10;
353 break;
354#endif
355 default:
356 dev_err(dev, "invalid MPU IRQ %d\n", mpu_irq[n]);
357 return 0;
358 }
359
360 if (mpu_irq[n] == irq[n]) {
361 dev_err(dev, "cannot share IRQ between WSS and MPU-401\n");
362 return 0;
363 }
364
365fm:
366 switch (fm_port[n]) {
367 case SNDRV_AUTO_PORT:
368 dev_warn(dev, "fm_port not specified: not using OPL3\n");
369 fm_port[n] = -1;
370 break;
371 case 0x388:
372 break;
373 default:
374 dev_err(dev, "illegal FM port %#lx\n", fm_port[n]);
375 return 0;
376 }
377
378 config[n] |= GALAXY_CONFIG_GAME_ENABLE;
379 return 1;
380}
381
382static int __devinit galaxy_init(struct snd_galaxy *galaxy, u8 *type)
383{
384 u8 major;
385 u8 minor;
386 int err;
387
388 err = dsp_reset(galaxy->port);
389 if (err < 0)
390 return err;
391
392 err = dsp_get_version(galaxy->port, &major, &minor);
393 if (err < 0)
394 return err;
395
396 if (major != GALAXY_DSP_MAJOR || minor != GALAXY_DSP_MINOR)
397 return -ENODEV;
398
399 err = dsp_command(galaxy->port, DSP_COMMAND_GALAXY_8);
400 if (err < 0)
401 return err;
402
403 err = dsp_command(galaxy->port, GALAXY_COMMAND_GET_TYPE);
404 if (err < 0)
405 return err;
406
407 err = dsp_get_byte(galaxy->port, type);
408 if (err < 0)
409 return err;
410
411 return 0;
412}
413
414static int __devinit galaxy_set_mode(struct snd_galaxy *galaxy, u8 mode)
415{
416 int err;
417
418 err = dsp_command(galaxy->port, DSP_COMMAND_GALAXY_9);
419 if (err < 0)
420 return err;
421
422 err = dsp_command(galaxy->port, mode);
423 if (err < 0)
424 return err;
425
426#ifdef AZT1605
427 /*
428 * Needed for MPU IRQ on AZT1605, but AZT2316 loses WSS again
429 */
430 err = dsp_reset(galaxy->port);
431 if (err < 0)
432 return err;
433#endif
434
435 return 0;
436}
437
438static void galaxy_set_config(struct snd_galaxy *galaxy, u32 config)
439{
440 u8 tmp = ioread8(galaxy->config_port + CONFIG_PORT_SET);
441 int i;
442
443 iowrite8(tmp | 0x80, galaxy->config_port + CONFIG_PORT_SET);
444 for (i = 0; i < GALAXY_CONFIG_SIZE; i++) {
445 iowrite8(config, galaxy->config_port + i);
446 config >>= 8;
447 }
448 iowrite8(tmp & 0x7f, galaxy->config_port + CONFIG_PORT_SET);
449 msleep(10);
450}
451
452static void __devinit galaxy_config(struct snd_galaxy *galaxy, u32 config)
453{
454 int i;
455
456 for (i = GALAXY_CONFIG_SIZE; i; i--) {
457 u8 tmp = ioread8(galaxy->config_port + i - 1);
458 galaxy->config = (galaxy->config << 8) | tmp;
459 }
460 config |= galaxy->config & GALAXY_CONFIG_MASK;
461 galaxy_set_config(galaxy, config);
462}
463
464static int __devinit galaxy_wss_config(struct snd_galaxy *galaxy, u8 wss_config)
465{
466 int err;
467
468 err = wss_detect(galaxy->wss_port);
469 if (err < 0)
470 return err;
471
472 wss_set_config(galaxy->wss_port, wss_config);
473
474 err = galaxy_set_mode(galaxy, GALAXY_MODE_WSS);
475 if (err < 0)
476 return err;
477
478 return 0;
479}
480
481static void snd_galaxy_free(struct snd_card *card)
482{
483 struct snd_galaxy *galaxy = card->private_data;
484
485 if (galaxy->wss_port) {
486 wss_set_config(galaxy->wss_port, 0);
487 ioport_unmap(galaxy->wss_port);
488 release_and_free_resource(galaxy->res_wss_port);
489 }
490 if (galaxy->config_port) {
491 galaxy_set_config(galaxy, galaxy->config);
492 ioport_unmap(galaxy->config_port);
493 release_and_free_resource(galaxy->res_config_port);
494 }
495 if (galaxy->port) {
496 ioport_unmap(galaxy->port);
497 release_and_free_resource(galaxy->res_port);
498 }
499}
500
501static int __devinit snd_galaxy_probe(struct device *dev, unsigned int n)
502{
503 struct snd_galaxy *galaxy;
504 struct snd_wss *chip;
505 struct snd_card *card;
506 u8 type;
507 int err;
508
509 err = snd_card_create(index[n], id[n], THIS_MODULE, sizeof *galaxy,
510 &card);
511 if (err < 0)
512 return err;
513
514 snd_card_set_dev(card, dev);
515
516 card->private_free = snd_galaxy_free;
517 galaxy = card->private_data;
518
519 galaxy->res_port = request_region(port[n], 16, DRV_NAME);
520 if (!galaxy->res_port) {
521 dev_err(dev, "could not grab ports %#lx-%#lx\n", port[n],
522 port[n] + 15);
523 err = -EBUSY;
524 goto error;
525 }
526 galaxy->port = ioport_map(port[n], 16);
527
528 err = galaxy_init(galaxy, &type);
529 if (err < 0) {
530 dev_err(dev, "did not find a Sound Galaxy at %#lx\n", port[n]);
531 goto error;
532 }
533 dev_info(dev, "Sound Galaxy (type %d) found at %#lx\n", type, port[n]);
534
535 galaxy->res_config_port = request_region(port[n] + GALAXY_PORT_CONFIG,
536 16, DRV_NAME);
537 if (!galaxy->res_config_port) {
538 dev_err(dev, "could not grab ports %#lx-%#lx\n",
539 port[n] + GALAXY_PORT_CONFIG,
540 port[n] + GALAXY_PORT_CONFIG + 15);
541 err = -EBUSY;
542 goto error;
543 }
544 galaxy->config_port = ioport_map(port[n] + GALAXY_PORT_CONFIG, 16);
545
546 galaxy_config(galaxy, config[n]);
547
548 galaxy->res_wss_port = request_region(wss_port[n], 4, DRV_NAME);
549 if (!galaxy->res_wss_port) {
550 dev_err(dev, "could not grab ports %#lx-%#lx\n", wss_port[n],
551 wss_port[n] + 3);
552 err = -EBUSY;
553 goto error;
554 }
555 galaxy->wss_port = ioport_map(wss_port[n], 4);
556
557 err = galaxy_wss_config(galaxy, wss_config[n]);
558 if (err < 0) {
559 dev_err(dev, "could not configure WSS\n");
560 goto error;
561 }
562
563 strcpy(card->driver, DRV_NAME);
564 strcpy(card->shortname, DRV_NAME);
565 sprintf(card->longname, "%s at %#lx/%#lx, irq %d, dma %d/%d",
566 card->shortname, port[n], wss_port[n], irq[n], dma1[n],
567 dma2[n]);
568
569 err = snd_wss_create(card, wss_port[n] + 4, -1, irq[n], dma1[n],
570 dma2[n], WSS_HW_DETECT, 0, &chip);
571 if (err < 0)
572 goto error;
573
574 err = snd_wss_pcm(chip, 0, NULL);
575 if (err < 0)
576 goto error;
577
578 err = snd_wss_mixer(chip);
579 if (err < 0)
580 goto error;
581
582 err = snd_wss_timer(chip, 0, NULL);
583 if (err < 0)
584 goto error;
585
586 if (mpu_port[n] >= 0) {
587 err = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
588 mpu_port[n], 0, mpu_irq[n],
589 IRQF_DISABLED, NULL);
590 if (err < 0)
591 goto error;
592 }
593
594 if (fm_port[n] >= 0) {
595 struct snd_opl3 *opl3;
596
597 err = snd_opl3_create(card, fm_port[n], fm_port[n] + 2,
598 OPL3_HW_AUTO, 0, &opl3);
599 if (err < 0) {
600 dev_err(dev, "no OPL device at %#lx\n", fm_port[n]);
601 goto error;
602 }
603 err = snd_opl3_timer_new(opl3, 1, 2);
604 if (err < 0)
605 goto error;
606
607 err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
608 if (err < 0)
609 goto error;
610 }
611
612 err = snd_card_register(card);
613 if (err < 0)
614 goto error;
615
616 dev_set_drvdata(dev, card);
617 return 0;
618
619error:
620 snd_card_free(card);
621 return err;
622}
623
624static int __devexit snd_galaxy_remove(struct device *dev, unsigned int n)
625{
626 snd_card_free(dev_get_drvdata(dev));
627 dev_set_drvdata(dev, NULL);
628 return 0;
629}
630
631static struct isa_driver snd_galaxy_driver = {
632 .match = snd_galaxy_match,
633 .probe = snd_galaxy_probe,
634 .remove = __devexit_p(snd_galaxy_remove),
635
636 .driver = {
637 .name = DEV_NAME
638 }
639};
640
641static int __init alsa_card_galaxy_init(void)
642{
643 return isa_register_driver(&snd_galaxy_driver, SNDRV_CARDS);
644}
645
646static void __exit alsa_card_galaxy_exit(void)
647{
648 isa_unregister_driver(&snd_galaxy_driver);
649}
650
651module_init(alsa_card_galaxy_init);
652module_exit(alsa_card_galaxy_exit);
diff --git a/sound/isa/gus/gusmax.c b/sound/isa/gus/gusmax.c
index f26eac8d811..3e4a58b7291 100644
--- a/sound/isa/gus/gusmax.c
+++ b/sound/isa/gus/gusmax.c
@@ -191,7 +191,7 @@ static int __devinit snd_gusmax_mixer(struct snd_wss *chip)
191 191
192static void snd_gusmax_free(struct snd_card *card) 192static void snd_gusmax_free(struct snd_card *card)
193{ 193{
194 struct snd_gusmax *maxcard = (struct snd_gusmax *)card->private_data; 194 struct snd_gusmax *maxcard = card->private_data;
195 195
196 if (maxcard == NULL) 196 if (maxcard == NULL)
197 return; 197 return;
@@ -219,7 +219,7 @@ static int __devinit snd_gusmax_probe(struct device *pdev, unsigned int dev)
219 if (err < 0) 219 if (err < 0)
220 return err; 220 return err;
221 card->private_free = snd_gusmax_free; 221 card->private_free = snd_gusmax_free;
222 maxcard = (struct snd_gusmax *)card->private_data; 222 maxcard = card->private_data;
223 maxcard->card = card; 223 maxcard->card = card;
224 maxcard->irq = -1; 224 maxcard->irq = -1;
225 225
diff --git a/sound/isa/msnd/msnd_pinnacle.c b/sound/isa/msnd/msnd_pinnacle.c
index 60b6abd7161..91d6023a63e 100644
--- a/sound/isa/msnd/msnd_pinnacle.c
+++ b/sound/isa/msnd/msnd_pinnacle.c
@@ -549,7 +549,10 @@ static int __devinit snd_msnd_attach(struct snd_card *card)
549 printk(KERN_ERR LOGNAME ": Couldn't grab IRQ %d\n", chip->irq); 549 printk(KERN_ERR LOGNAME ": Couldn't grab IRQ %d\n", chip->irq);
550 return err; 550 return err;
551 } 551 }
552 request_region(chip->io, DSP_NUMIO, card->shortname); 552 if (request_region(chip->io, DSP_NUMIO, card->shortname) == NULL) {
553 free_irq(chip->irq, chip);
554 return -EBUSY;
555 }
553 556
554 if (!request_mem_region(chip->base, BUFFSIZE, card->shortname)) { 557 if (!request_mem_region(chip->base, BUFFSIZE, card->shortname)) {
555 printk(KERN_ERR LOGNAME 558 printk(KERN_ERR LOGNAME
@@ -761,9 +764,9 @@ static long io[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
761static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; 764static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
762static long mem[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; 765static long mem[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
763 766
767#ifndef MSND_CLASSIC
764static long cfg[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; 768static long cfg[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
765 769
766#ifndef MSND_CLASSIC
767/* Extra Peripheral Configuration (Default: Disable) */ 770/* Extra Peripheral Configuration (Default: Disable) */
768static long ide_io0[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; 771static long ide_io0[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
769static long ide_io1[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; 772static long ide_io1[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
@@ -891,7 +894,11 @@ static int __devinit snd_msnd_isa_probe(struct device *pdev, unsigned int idx)
891 struct snd_card *card; 894 struct snd_card *card;
892 struct snd_msnd *chip; 895 struct snd_msnd *chip;
893 896
894 if (has_isapnp(idx) || cfg[idx] == SNDRV_AUTO_PORT) { 897 if (has_isapnp(idx)
898#ifndef MSND_CLASSIC
899 || cfg[idx] == SNDRV_AUTO_PORT
900#endif
901 ) {
895 printk(KERN_INFO LOGNAME ": Assuming PnP mode\n"); 902 printk(KERN_INFO LOGNAME ": Assuming PnP mode\n");
896 return -ENODEV; 903 return -ENODEV;
897 } 904 }
diff --git a/sound/isa/sb/emu8000_pcm.c b/sound/isa/sb/emu8000_pcm.c
index ccedbfed061..2f85c66f8e3 100644
--- a/sound/isa/sb/emu8000_pcm.c
+++ b/sound/isa/sb/emu8000_pcm.c
@@ -433,7 +433,8 @@ static int emu8k_transfer_block(struct snd_emu8000 *emu, int offset, unsigned sh
433 while (count > 0) { 433 while (count > 0) {
434 unsigned short sval; 434 unsigned short sval;
435 CHECK_SCHEDULER(); 435 CHECK_SCHEDULER();
436 get_user(sval, buf); 436 if (get_user(sval, buf))
437 return -EFAULT;
437 EMU8000_SMLD_WRITE(emu, sval); 438 EMU8000_SMLD_WRITE(emu, sval);
438 buf++; 439 buf++;
439 count--; 440 count--;
@@ -525,12 +526,14 @@ static int emu8k_pcm_copy(struct snd_pcm_substream *subs,
525 while (count-- > 0) { 526 while (count-- > 0) {
526 unsigned short sval; 527 unsigned short sval;
527 CHECK_SCHEDULER(); 528 CHECK_SCHEDULER();
528 get_user(sval, buf); 529 if (get_user(sval, buf))
530 return -EFAULT;
529 EMU8000_SMLD_WRITE(emu, sval); 531 EMU8000_SMLD_WRITE(emu, sval);
530 buf++; 532 buf++;
531 if (rec->voices > 1) { 533 if (rec->voices > 1) {
532 CHECK_SCHEDULER(); 534 CHECK_SCHEDULER();
533 get_user(sval, buf); 535 if (get_user(sval, buf))
536 return -EFAULT;
534 EMU8000_SMRD_WRITE(emu, sval); 537 EMU8000_SMRD_WRITE(emu, sval);
535 buf++; 538 buf++;
536 } 539 }
diff --git a/sound/isa/sb/sb8.c b/sound/isa/sb/sb8.c
index 81284a8fa0c..2259e3f726a 100644
--- a/sound/isa/sb/sb8.c
+++ b/sound/isa/sb/sb8.c
@@ -72,7 +72,7 @@ static irqreturn_t snd_sb8_interrupt(int irq, void *dev_id)
72 72
73static void snd_sb8_free(struct snd_card *card) 73static void snd_sb8_free(struct snd_card *card)
74{ 74{
75 struct snd_sb8 *acard = (struct snd_sb8 *)card->private_data; 75 struct snd_sb8 *acard = card->private_data;
76 76
77 if (acard == NULL) 77 if (acard == NULL)
78 return; 78 return;
diff --git a/sound/isa/sgalaxy.c b/sound/isa/sgalaxy.c
deleted file mode 100644
index 6fe27b9d944..00000000000
--- a/sound/isa/sgalaxy.c
+++ /dev/null
@@ -1,369 +0,0 @@
1/*
2 * Driver for Aztech Sound Galaxy cards
3 * Copyright (c) by Christopher Butler <chrisb@sandy.force9.co.uk.
4 *
5 * I don't have documentation for this card, I based this driver on the
6 * driver for OSS/Free included in the kernel source (drivers/sound/sgalaxy.c)
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 */
23
24#include <linux/init.h>
25#include <linux/err.h>
26#include <linux/isa.h>
27#include <linux/delay.h>
28#include <linux/time.h>
29#include <linux/interrupt.h>
30#include <linux/moduleparam.h>
31#include <asm/dma.h>
32#include <sound/core.h>
33#include <sound/sb.h>
34#include <sound/wss.h>
35#include <sound/control.h>
36#define SNDRV_LEGACY_FIND_FREE_IRQ
37#define SNDRV_LEGACY_FIND_FREE_DMA
38#include <sound/initval.h>
39
40MODULE_AUTHOR("Christopher Butler <chrisb@sandy.force9.co.uk>");
41MODULE_DESCRIPTION("Aztech Sound Galaxy");
42MODULE_LICENSE("GPL");
43MODULE_SUPPORTED_DEVICE("{{Aztech Systems,Sound Galaxy}}");
44
45static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
46static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
47static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
48static long sbport[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240 */
49static long wssport[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x530,0xe80,0xf40,0x604 */
50static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 7,9,10,11 */
51static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3 */
52
53module_param_array(index, int, NULL, 0444);
54MODULE_PARM_DESC(index, "Index value for Sound Galaxy soundcard.");
55module_param_array(id, charp, NULL, 0444);
56MODULE_PARM_DESC(id, "ID string for Sound Galaxy soundcard.");
57module_param_array(sbport, long, NULL, 0444);
58MODULE_PARM_DESC(sbport, "Port # for Sound Galaxy SB driver.");
59module_param_array(wssport, long, NULL, 0444);
60MODULE_PARM_DESC(wssport, "Port # for Sound Galaxy WSS driver.");
61module_param_array(irq, int, NULL, 0444);
62MODULE_PARM_DESC(irq, "IRQ # for Sound Galaxy driver.");
63module_param_array(dma1, int, NULL, 0444);
64MODULE_PARM_DESC(dma1, "DMA1 # for Sound Galaxy driver.");
65
66#define SGALAXY_AUXC_LEFT 18
67#define SGALAXY_AUXC_RIGHT 19
68
69#define PFX "sgalaxy: "
70
71/*
72
73 */
74
75#define AD1848P1( port, x ) ( port + c_d_c_AD1848##x )
76
77/* from lowlevel/sb/sb.c - to avoid having to allocate a struct snd_sb for the */
78/* short time we actually need it.. */
79
80static int snd_sgalaxy_sbdsp_reset(unsigned long port)
81{
82 int i;
83
84 outb(1, SBP1(port, RESET));
85 udelay(10);
86 outb(0, SBP1(port, RESET));
87 udelay(30);
88 for (i = 0; i < 1000 && !(inb(SBP1(port, DATA_AVAIL)) & 0x80); i++);
89 if (inb(SBP1(port, READ)) != 0xaa) {
90 snd_printd("sb_reset: failed at 0x%lx!!!\n", port);
91 return -ENODEV;
92 }
93 return 0;
94}
95
96static int __devinit snd_sgalaxy_sbdsp_command(unsigned long port,
97 unsigned char val)
98{
99 int i;
100
101 for (i = 10000; i; i--)
102 if ((inb(SBP1(port, STATUS)) & 0x80) == 0) {
103 outb(val, SBP1(port, COMMAND));
104 return 1;
105 }
106
107 return 0;
108}
109
110static irqreturn_t snd_sgalaxy_dummy_interrupt(int irq, void *dev_id)
111{
112 return IRQ_NONE;
113}
114
115static int __devinit snd_sgalaxy_setup_wss(unsigned long port, int irq, int dma)
116{
117 static int interrupt_bits[] = {-1, -1, -1, -1, -1, -1, -1, 0x08, -1,
118 0x10, 0x18, 0x20, -1, -1, -1, -1};
119 static int dma_bits[] = {1, 2, 0, 3};
120 int tmp, tmp1;
121
122 if ((tmp = inb(port + 3)) == 0xff)
123 {
124 snd_printdd("I/O address dead (0x%lx)\n", port);
125 return 0;
126 }
127#if 0
128 snd_printdd("WSS signature = 0x%x\n", tmp);
129#endif
130
131 if ((tmp & 0x3f) != 0x04 &&
132 (tmp & 0x3f) != 0x0f &&
133 (tmp & 0x3f) != 0x00) {
134 snd_printdd("No WSS signature detected on port 0x%lx\n",
135 port + 3);
136 return 0;
137 }
138
139#if 0
140 snd_printdd(PFX "setting up IRQ/DMA for WSS\n");
141#endif
142
143 /* initialize IRQ for WSS codec */
144 tmp = interrupt_bits[irq % 16];
145 if (tmp < 0)
146 return -EINVAL;
147
148 if (request_irq(irq, snd_sgalaxy_dummy_interrupt, IRQF_DISABLED, "sgalaxy", NULL)) {
149 snd_printk(KERN_ERR "sgalaxy: can't grab irq %d\n", irq);
150 return -EIO;
151 }
152
153 outb(tmp | 0x40, port);
154 tmp1 = dma_bits[dma % 4];
155 outb(tmp | tmp1, port);
156
157 free_irq(irq, NULL);
158
159 return 0;
160}
161
162static int __devinit snd_sgalaxy_detect(int dev, int irq, int dma)
163{
164#if 0
165 snd_printdd(PFX "switching to WSS mode\n");
166#endif
167
168 /* switch to WSS mode */
169 snd_sgalaxy_sbdsp_reset(sbport[dev]);
170
171 snd_sgalaxy_sbdsp_command(sbport[dev], 9);
172 snd_sgalaxy_sbdsp_command(sbport[dev], 0);
173
174 udelay(400);
175 return snd_sgalaxy_setup_wss(wssport[dev], irq, dma);
176}
177
178static struct snd_kcontrol_new snd_sgalaxy_controls[] = {
179WSS_DOUBLE("Aux Playback Switch", 0,
180 SGALAXY_AUXC_LEFT, SGALAXY_AUXC_RIGHT, 7, 7, 1, 1),
181WSS_DOUBLE("Aux Playback Volume", 0,
182 SGALAXY_AUXC_LEFT, SGALAXY_AUXC_RIGHT, 0, 0, 31, 0)
183};
184
185static int __devinit snd_sgalaxy_mixer(struct snd_wss *chip)
186{
187 struct snd_card *card = chip->card;
188 struct snd_ctl_elem_id id1, id2;
189 unsigned int idx;
190 int err;
191
192 memset(&id1, 0, sizeof(id1));
193 memset(&id2, 0, sizeof(id2));
194 id1.iface = id2.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
195 /* reassign AUX0 to LINE */
196 strcpy(id1.name, "Aux Playback Switch");
197 strcpy(id2.name, "Line Playback Switch");
198 if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
199 return err;
200 strcpy(id1.name, "Aux Playback Volume");
201 strcpy(id2.name, "Line Playback Volume");
202 if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
203 return err;
204 /* reassign AUX1 to FM */
205 strcpy(id1.name, "Aux Playback Switch"); id1.index = 1;
206 strcpy(id2.name, "FM Playback Switch");
207 if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
208 return err;
209 strcpy(id1.name, "Aux Playback Volume");
210 strcpy(id2.name, "FM Playback Volume");
211 if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
212 return err;
213 /* build AUX2 input */
214 for (idx = 0; idx < ARRAY_SIZE(snd_sgalaxy_controls); idx++) {
215 err = snd_ctl_add(card,
216 snd_ctl_new1(&snd_sgalaxy_controls[idx], chip));
217 if (err < 0)
218 return err;
219 }
220 return 0;
221}
222
223static int __devinit snd_sgalaxy_match(struct device *devptr, unsigned int dev)
224{
225 if (!enable[dev])
226 return 0;
227 if (sbport[dev] == SNDRV_AUTO_PORT) {
228 snd_printk(KERN_ERR PFX "specify SB port\n");
229 return 0;
230 }
231 if (wssport[dev] == SNDRV_AUTO_PORT) {
232 snd_printk(KERN_ERR PFX "specify WSS port\n");
233 return 0;
234 }
235 return 1;
236}
237
238static int __devinit snd_sgalaxy_probe(struct device *devptr, unsigned int dev)
239{
240 static int possible_irqs[] = {7, 9, 10, 11, -1};
241 static int possible_dmas[] = {1, 3, 0, -1};
242 int err, xirq, xdma1;
243 struct snd_card *card;
244 struct snd_wss *chip;
245
246 err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
247 if (err < 0)
248 return err;
249
250 xirq = irq[dev];
251 if (xirq == SNDRV_AUTO_IRQ) {
252 if ((xirq = snd_legacy_find_free_irq(possible_irqs)) < 0) {
253 snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
254 err = -EBUSY;
255 goto _err;
256 }
257 }
258 xdma1 = dma1[dev];
259 if (xdma1 == SNDRV_AUTO_DMA) {
260 if ((xdma1 = snd_legacy_find_free_dma(possible_dmas)) < 0) {
261 snd_printk(KERN_ERR PFX "unable to find a free DMA\n");
262 err = -EBUSY;
263 goto _err;
264 }
265 }
266
267 if ((err = snd_sgalaxy_detect(dev, xirq, xdma1)) < 0)
268 goto _err;
269
270 err = snd_wss_create(card, wssport[dev] + 4, -1,
271 xirq, xdma1, -1,
272 WSS_HW_DETECT, 0, &chip);
273 if (err < 0)
274 goto _err;
275 card->private_data = chip;
276
277 err = snd_wss_pcm(chip, 0, NULL);
278 if (err < 0) {
279 snd_printdd(PFX "error creating new WSS PCM device\n");
280 goto _err;
281 }
282 err = snd_wss_mixer(chip);
283 if (err < 0) {
284 snd_printdd(PFX "error creating new WSS mixer\n");
285 goto _err;
286 }
287 if ((err = snd_sgalaxy_mixer(chip)) < 0) {
288 snd_printdd(PFX "the mixer rewrite failed\n");
289 goto _err;
290 }
291
292 strcpy(card->driver, "Sound Galaxy");
293 strcpy(card->shortname, "Sound Galaxy");
294 sprintf(card->longname, "Sound Galaxy at 0x%lx, irq %d, dma %d",
295 wssport[dev], xirq, xdma1);
296
297 snd_card_set_dev(card, devptr);
298
299 if ((err = snd_card_register(card)) < 0)
300 goto _err;
301
302 dev_set_drvdata(devptr, card);
303 return 0;
304
305 _err:
306 snd_card_free(card);
307 return err;
308}
309
310static int __devexit snd_sgalaxy_remove(struct device *devptr, unsigned int dev)
311{
312 snd_card_free(dev_get_drvdata(devptr));
313 dev_set_drvdata(devptr, NULL);
314 return 0;
315}
316
317#ifdef CONFIG_PM
318static int snd_sgalaxy_suspend(struct device *pdev, unsigned int n,
319 pm_message_t state)
320{
321 struct snd_card *card = dev_get_drvdata(pdev);
322 struct snd_wss *chip = card->private_data;
323
324 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
325 chip->suspend(chip);
326 return 0;
327}
328
329static int snd_sgalaxy_resume(struct device *pdev, unsigned int n)
330{
331 struct snd_card *card = dev_get_drvdata(pdev);
332 struct snd_wss *chip = card->private_data;
333
334 chip->resume(chip);
335 snd_wss_out(chip, SGALAXY_AUXC_LEFT, chip->image[SGALAXY_AUXC_LEFT]);
336 snd_wss_out(chip, SGALAXY_AUXC_RIGHT, chip->image[SGALAXY_AUXC_RIGHT]);
337
338 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
339 return 0;
340}
341#endif
342
343#define DEV_NAME "sgalaxy"
344
345static struct isa_driver snd_sgalaxy_driver = {
346 .match = snd_sgalaxy_match,
347 .probe = snd_sgalaxy_probe,
348 .remove = __devexit_p(snd_sgalaxy_remove),
349#ifdef CONFIG_PM
350 .suspend = snd_sgalaxy_suspend,
351 .resume = snd_sgalaxy_resume,
352#endif
353 .driver = {
354 .name = DEV_NAME
355 },
356};
357
358static int __init alsa_card_sgalaxy_init(void)
359{
360 return isa_register_driver(&snd_sgalaxy_driver, SNDRV_CARDS);
361}
362
363static void __exit alsa_card_sgalaxy_exit(void)
364{
365 isa_unregister_driver(&snd_sgalaxy_driver);
366}
367
368module_init(alsa_card_sgalaxy_init)
369module_exit(alsa_card_sgalaxy_exit)
diff --git a/sound/oss/Kconfig b/sound/oss/Kconfig
index a513651fa14..76c09021807 100644
--- a/sound/oss/Kconfig
+++ b/sound/oss/Kconfig
@@ -545,11 +545,3 @@ config SOUND_KAHLUA
545 545
546endif # SOUND_OSS 546endif # SOUND_OSS
547 547
548config SOUND_SH_DAC_AUDIO
549 tristate "SuperH DAC audio support"
550 depends on CPU_SH3 && HIGH_RES_TIMERS
551
552config SOUND_SH_DAC_AUDIO_CHANNEL
553 int "DAC channel"
554 default "1"
555 depends on SOUND_SH_DAC_AUDIO
diff --git a/sound/oss/Makefile b/sound/oss/Makefile
index 567b8a74178..96f14dcd0cd 100644
--- a/sound/oss/Makefile
+++ b/sound/oss/Makefile
@@ -9,7 +9,6 @@ obj-$(CONFIG_SOUND_OSS) += sound.o
9 9
10# Please leave it as is, cause the link order is significant ! 10# Please leave it as is, cause the link order is significant !
11 11
12obj-$(CONFIG_SOUND_SH_DAC_AUDIO) += sh_dac_audio.o
13obj-$(CONFIG_SOUND_AEDSP16) += aedsp16.o 12obj-$(CONFIG_SOUND_AEDSP16) += aedsp16.o
14obj-$(CONFIG_SOUND_PSS) += pss.o ad1848.o mpu401.o 13obj-$(CONFIG_SOUND_PSS) += pss.o ad1848.o mpu401.o
15obj-$(CONFIG_SOUND_TRIX) += trix.o ad1848.o sb_lib.o uart401.o 14obj-$(CONFIG_SOUND_TRIX) += trix.o ad1848.o sb_lib.o uart401.o
diff --git a/sound/oss/ad1848.c b/sound/oss/ad1848.c
index 24793c5b65a..4d2a6ae978f 100644
--- a/sound/oss/ad1848.c
+++ b/sound/oss/ad1848.c
@@ -716,7 +716,7 @@ static int ad1848_mixer_ioctl(int dev, unsigned int cmd, void __user *arg)
716 716
717 default: 717 default:
718 if (get_user(val, (int __user *)arg)) 718 if (get_user(val, (int __user *)arg))
719 return -EFAULT; 719 return -EFAULT;
720 val = ad1848_mixer_set(devc, cmd & 0xff, val); 720 val = ad1848_mixer_set(devc, cmd & 0xff, val);
721 break; 721 break;
722 } 722 }
diff --git a/sound/oss/au1550_ac97.c b/sound/oss/au1550_ac97.c
index c1070e33b32..a8f626d99c5 100644
--- a/sound/oss/au1550_ac97.c
+++ b/sound/oss/au1550_ac97.c
@@ -49,7 +49,6 @@
49#include <linux/poll.h> 49#include <linux/poll.h>
50#include <linux/bitops.h> 50#include <linux/bitops.h>
51#include <linux/spinlock.h> 51#include <linux/spinlock.h>
52#include <linux/smp_lock.h>
53#include <linux/ac97_codec.h> 52#include <linux/ac97_codec.h>
54#include <linux/mutex.h> 53#include <linux/mutex.h>
55 54
@@ -77,6 +76,7 @@
77/* Boot options 76/* Boot options
78 * 0 = no VRA, 1 = use VRA if codec supports it 77 * 0 = no VRA, 1 = use VRA if codec supports it
79 */ 78 */
79static DEFINE_MUTEX(au1550_ac97_mutex);
80static int vra = 1; 80static int vra = 1;
81module_param(vra, bool, 0); 81module_param(vra, bool, 0);
82MODULE_PARM_DESC(vra, "if 1 use VRA if codec supports it"); 82MODULE_PARM_DESC(vra, "if 1 use VRA if codec supports it");
@@ -162,25 +162,16 @@ ld2(unsigned int x)
162static void 162static void
163au1550_delay(int msec) 163au1550_delay(int msec)
164{ 164{
165 unsigned long tmo;
166 signed long tmo2;
167
168 if (in_interrupt()) 165 if (in_interrupt())
169 return; 166 return;
170 167
171 tmo = jiffies + (msec * HZ) / 1000; 168 schedule_timeout_uninterruptible(msecs_to_jiffies(msec));
172 for (;;) {
173 tmo2 = tmo - jiffies;
174 if (tmo2 <= 0)
175 break;
176 schedule_timeout(tmo2);
177 }
178} 169}
179 170
180static u16 171static u16
181rdcodec(struct ac97_codec *codec, u8 addr) 172rdcodec(struct ac97_codec *codec, u8 addr)
182{ 173{
183 struct au1550_state *s = (struct au1550_state *)codec->private_data; 174 struct au1550_state *s = codec->private_data;
184 unsigned long flags; 175 unsigned long flags;
185 u32 cmd, val; 176 u32 cmd, val;
186 u16 data; 177 u16 data;
@@ -248,7 +239,7 @@ rdcodec(struct ac97_codec *codec, u8 addr)
248static void 239static void
249wrcodec(struct ac97_codec *codec, u8 addr, u16 data) 240wrcodec(struct ac97_codec *codec, u8 addr, u16 data)
250{ 241{
251 struct au1550_state *s = (struct au1550_state *)codec->private_data; 242 struct au1550_state *s = codec->private_data;
252 unsigned long flags; 243 unsigned long flags;
253 u32 cmd, val; 244 u32 cmd, val;
254 int i; 245 int i;
@@ -807,7 +798,9 @@ au1550_llseek(struct file *file, loff_t offset, int origin)
807static int 798static int
808au1550_open_mixdev(struct inode *inode, struct file *file) 799au1550_open_mixdev(struct inode *inode, struct file *file)
809{ 800{
801 mutex_lock(&au1550_ac97_mutex);
810 file->private_data = &au1550_state; 802 file->private_data = &au1550_state;
803 mutex_unlock(&au1550_ac97_mutex);
811 return 0; 804 return 0;
812} 805}
813 806
@@ -824,22 +817,26 @@ mixdev_ioctl(struct ac97_codec *codec, unsigned int cmd,
824 return codec->mixer_ioctl(codec, cmd, arg); 817 return codec->mixer_ioctl(codec, cmd, arg);
825} 818}
826 819
827static int 820static long
828au1550_ioctl_mixdev(struct inode *inode, struct file *file, 821au1550_ioctl_mixdev(struct file *file, unsigned int cmd, unsigned long arg)
829 unsigned int cmd, unsigned long arg)
830{ 822{
831 struct au1550_state *s = (struct au1550_state *)file->private_data; 823 struct au1550_state *s = file->private_data;
832 struct ac97_codec *codec = s->codec; 824 struct ac97_codec *codec = s->codec;
825 int ret;
826
827 mutex_lock(&au1550_ac97_mutex);
828 ret = mixdev_ioctl(codec, cmd, arg);
829 mutex_unlock(&au1550_ac97_mutex);
833 830
834 return mixdev_ioctl(codec, cmd, arg); 831 return ret;
835} 832}
836 833
837static /*const */ struct file_operations au1550_mixer_fops = { 834static /*const */ struct file_operations au1550_mixer_fops = {
838 owner:THIS_MODULE, 835 .owner = THIS_MODULE,
839 llseek:au1550_llseek, 836 .llseek = au1550_llseek,
840 ioctl:au1550_ioctl_mixdev, 837 .unlocked_ioctl = au1550_ioctl_mixdev,
841 open:au1550_open_mixdev, 838 .open = au1550_open_mixdev,
842 release:au1550_release_mixdev, 839 .release = au1550_release_mixdev,
843}; 840};
844 841
845static int 842static int
@@ -1034,7 +1031,7 @@ copy_dmabuf_user(struct dmabuf *db, char* userbuf, int count, int to_user)
1034static ssize_t 1031static ssize_t
1035au1550_read(struct file *file, char *buffer, size_t count, loff_t *ppos) 1032au1550_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
1036{ 1033{
1037 struct au1550_state *s = (struct au1550_state *)file->private_data; 1034 struct au1550_state *s = file->private_data;
1038 struct dmabuf *db = &s->dma_adc; 1035 struct dmabuf *db = &s->dma_adc;
1039 DECLARE_WAITQUEUE(wait, current); 1036 DECLARE_WAITQUEUE(wait, current);
1040 ssize_t ret; 1037 ssize_t ret;
@@ -1114,7 +1111,7 @@ out2:
1114static ssize_t 1111static ssize_t
1115au1550_write(struct file *file, const char *buffer, size_t count, loff_t * ppos) 1112au1550_write(struct file *file, const char *buffer, size_t count, loff_t * ppos)
1116{ 1113{
1117 struct au1550_state *s = (struct au1550_state *)file->private_data; 1114 struct au1550_state *s = file->private_data;
1118 struct dmabuf *db = &s->dma_dac; 1115 struct dmabuf *db = &s->dma_dac;
1119 DECLARE_WAITQUEUE(wait, current); 1116 DECLARE_WAITQUEUE(wait, current);
1120 ssize_t ret = 0; 1117 ssize_t ret = 0;
@@ -1214,7 +1211,7 @@ out2:
1214static unsigned int 1211static unsigned int
1215au1550_poll(struct file *file, struct poll_table_struct *wait) 1212au1550_poll(struct file *file, struct poll_table_struct *wait)
1216{ 1213{
1217 struct au1550_state *s = (struct au1550_state *)file->private_data; 1214 struct au1550_state *s = file->private_data;
1218 unsigned long flags; 1215 unsigned long flags;
1219 unsigned int mask = 0; 1216 unsigned int mask = 0;
1220 1217
@@ -1253,12 +1250,12 @@ au1550_poll(struct file *file, struct poll_table_struct *wait)
1253static int 1250static int
1254au1550_mmap(struct file *file, struct vm_area_struct *vma) 1251au1550_mmap(struct file *file, struct vm_area_struct *vma)
1255{ 1252{
1256 struct au1550_state *s = (struct au1550_state *)file->private_data; 1253 struct au1550_state *s = file->private_data;
1257 struct dmabuf *db; 1254 struct dmabuf *db;
1258 unsigned long size; 1255 unsigned long size;
1259 int ret = 0; 1256 int ret = 0;
1260 1257
1261 lock_kernel(); 1258 mutex_lock(&au1550_ac97_mutex);
1262 mutex_lock(&s->sem); 1259 mutex_lock(&s->sem);
1263 if (vma->vm_flags & VM_WRITE) 1260 if (vma->vm_flags & VM_WRITE)
1264 db = &s->dma_dac; 1261 db = &s->dma_dac;
@@ -1286,7 +1283,7 @@ au1550_mmap(struct file *file, struct vm_area_struct *vma)
1286 db->mapped = 1; 1283 db->mapped = 1;
1287out: 1284out:
1288 mutex_unlock(&s->sem); 1285 mutex_unlock(&s->sem);
1289 unlock_kernel(); 1286 mutex_unlock(&au1550_ac97_mutex);
1290 return ret; 1287 return ret;
1291} 1288}
1292 1289
@@ -1343,10 +1340,9 @@ dma_count_done(struct dmabuf *db)
1343 1340
1344 1341
1345static int 1342static int
1346au1550_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 1343au1550_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
1347 unsigned long arg)
1348{ 1344{
1349 struct au1550_state *s = (struct au1550_state *)file->private_data; 1345 struct au1550_state *s = file->private_data;
1350 unsigned long flags; 1346 unsigned long flags;
1351 audio_buf_info abinfo; 1347 audio_buf_info abinfo;
1352 count_info cinfo; 1348 count_info cinfo;
@@ -1780,6 +1776,17 @@ au1550_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
1780 return mixdev_ioctl(s->codec, cmd, arg); 1776 return mixdev_ioctl(s->codec, cmd, arg);
1781} 1777}
1782 1778
1779static long
1780au1550_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
1781{
1782 int ret;
1783
1784 mutex_lock(&au1550_ac97_mutex);
1785 ret = au1550_ioctl(file, cmd, arg);
1786 mutex_unlock(&au1550_ac97_mutex);
1787
1788 return ret;
1789}
1783 1790
1784static int 1791static int
1785au1550_open(struct inode *inode, struct file *file) 1792au1550_open(struct inode *inode, struct file *file)
@@ -1797,21 +1804,22 @@ au1550_open(struct inode *inode, struct file *file)
1797#endif 1804#endif
1798 1805
1799 file->private_data = s; 1806 file->private_data = s;
1807 mutex_lock(&au1550_ac97_mutex);
1800 /* wait for device to become free */ 1808 /* wait for device to become free */
1801 mutex_lock(&s->open_mutex); 1809 mutex_lock(&s->open_mutex);
1802 while (s->open_mode & file->f_mode) { 1810 while (s->open_mode & file->f_mode) {
1803 if (file->f_flags & O_NONBLOCK) { 1811 ret = -EBUSY;
1804 mutex_unlock(&s->open_mutex); 1812 if (file->f_flags & O_NONBLOCK)
1805 return -EBUSY; 1813 goto out;
1806 }
1807 add_wait_queue(&s->open_wait, &wait); 1814 add_wait_queue(&s->open_wait, &wait);
1808 __set_current_state(TASK_INTERRUPTIBLE); 1815 __set_current_state(TASK_INTERRUPTIBLE);
1809 mutex_unlock(&s->open_mutex); 1816 mutex_unlock(&s->open_mutex);
1810 schedule(); 1817 schedule();
1811 remove_wait_queue(&s->open_wait, &wait); 1818 remove_wait_queue(&s->open_wait, &wait);
1812 set_current_state(TASK_RUNNING); 1819 set_current_state(TASK_RUNNING);
1820 ret = -ERESTARTSYS;
1813 if (signal_pending(current)) 1821 if (signal_pending(current))
1814 return -ERESTARTSYS; 1822 goto out2;
1815 mutex_lock(&s->open_mutex); 1823 mutex_lock(&s->open_mutex);
1816 } 1824 }
1817 1825
@@ -1840,30 +1848,34 @@ au1550_open(struct inode *inode, struct file *file)
1840 1848
1841 if (file->f_mode & FMODE_READ) { 1849 if (file->f_mode & FMODE_READ) {
1842 if ((ret = prog_dmabuf_adc(s))) 1850 if ((ret = prog_dmabuf_adc(s)))
1843 return ret; 1851 goto out;
1844 } 1852 }
1845 if (file->f_mode & FMODE_WRITE) { 1853 if (file->f_mode & FMODE_WRITE) {
1846 if ((ret = prog_dmabuf_dac(s))) 1854 if ((ret = prog_dmabuf_dac(s)))
1847 return ret; 1855 goto out;
1848 } 1856 }
1849 1857
1850 s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); 1858 s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
1851 mutex_unlock(&s->open_mutex);
1852 mutex_init(&s->sem); 1859 mutex_init(&s->sem);
1853 return 0; 1860 ret = 0;
1861out:
1862 mutex_unlock(&s->open_mutex);
1863out2:
1864 mutex_unlock(&au1550_ac97_mutex);
1865 return ret;
1854} 1866}
1855 1867
1856static int 1868static int
1857au1550_release(struct inode *inode, struct file *file) 1869au1550_release(struct inode *inode, struct file *file)
1858{ 1870{
1859 struct au1550_state *s = (struct au1550_state *)file->private_data; 1871 struct au1550_state *s = file->private_data;
1860 1872
1861 lock_kernel(); 1873 mutex_lock(&au1550_ac97_mutex);
1862 1874
1863 if (file->f_mode & FMODE_WRITE) { 1875 if (file->f_mode & FMODE_WRITE) {
1864 unlock_kernel(); 1876 mutex_unlock(&au1550_ac97_mutex);
1865 drain_dac(s, file->f_flags & O_NONBLOCK); 1877 drain_dac(s, file->f_flags & O_NONBLOCK);
1866 lock_kernel(); 1878 mutex_lock(&au1550_ac97_mutex);
1867 } 1879 }
1868 1880
1869 mutex_lock(&s->open_mutex); 1881 mutex_lock(&s->open_mutex);
@@ -1880,20 +1892,20 @@ au1550_release(struct inode *inode, struct file *file)
1880 s->open_mode &= ((~file->f_mode) & (FMODE_READ|FMODE_WRITE)); 1892 s->open_mode &= ((~file->f_mode) & (FMODE_READ|FMODE_WRITE));
1881 mutex_unlock(&s->open_mutex); 1893 mutex_unlock(&s->open_mutex);
1882 wake_up(&s->open_wait); 1894 wake_up(&s->open_wait);
1883 unlock_kernel(); 1895 mutex_unlock(&au1550_ac97_mutex);
1884 return 0; 1896 return 0;
1885} 1897}
1886 1898
1887static /*const */ struct file_operations au1550_audio_fops = { 1899static /*const */ struct file_operations au1550_audio_fops = {
1888 owner: THIS_MODULE, 1900 .owner = THIS_MODULE,
1889 llseek: au1550_llseek, 1901 .llseek = au1550_llseek,
1890 read: au1550_read, 1902 .read = au1550_read,
1891 write: au1550_write, 1903 .write = au1550_write,
1892 poll: au1550_poll, 1904 .poll = au1550_poll,
1893 ioctl: au1550_ioctl, 1905 .unlocked_ioctl = au1550_unlocked_ioctl,
1894 mmap: au1550_mmap, 1906 .mmap = au1550_mmap,
1895 open: au1550_open, 1907 .open = au1550_open,
1896 release: au1550_release, 1908 .release = au1550_release,
1897}; 1909};
1898 1910
1899MODULE_AUTHOR("Advanced Micro Devices (AMD), dan@embeddededge.com"); 1911MODULE_AUTHOR("Advanced Micro Devices (AMD), dan@embeddededge.com");
diff --git a/sound/oss/dmasound/dmasound_core.c b/sound/oss/dmasound/dmasound_core.c
index 3f3c3f71db4..87e2c72651f 100644
--- a/sound/oss/dmasound/dmasound_core.c
+++ b/sound/oss/dmasound/dmasound_core.c
@@ -181,7 +181,7 @@
181#include <linux/init.h> 181#include <linux/init.h>
182#include <linux/soundcard.h> 182#include <linux/soundcard.h>
183#include <linux/poll.h> 183#include <linux/poll.h>
184#include <linux/smp_lock.h> 184#include <linux/mutex.h>
185 185
186#include <asm/uaccess.h> 186#include <asm/uaccess.h>
187 187
@@ -194,6 +194,7 @@
194 * Declarations 194 * Declarations
195 */ 195 */
196 196
197static DEFINE_MUTEX(dmasound_core_mutex);
197int dmasound_catchRadius = 0; 198int dmasound_catchRadius = 0;
198module_param(dmasound_catchRadius, int, 0); 199module_param(dmasound_catchRadius, int, 0);
199 200
@@ -323,22 +324,26 @@ static struct {
323 324
324static int mixer_open(struct inode *inode, struct file *file) 325static int mixer_open(struct inode *inode, struct file *file)
325{ 326{
326 if (!try_module_get(dmasound.mach.owner)) 327 mutex_lock(&dmasound_core_mutex);
328 if (!try_module_get(dmasound.mach.owner)) {
329 mutex_unlock(&dmasound_core_mutex);
327 return -ENODEV; 330 return -ENODEV;
331 }
328 mixer.busy = 1; 332 mixer.busy = 1;
333 mutex_unlock(&dmasound_core_mutex);
329 return 0; 334 return 0;
330} 335}
331 336
332static int mixer_release(struct inode *inode, struct file *file) 337static int mixer_release(struct inode *inode, struct file *file)
333{ 338{
334 lock_kernel(); 339 mutex_lock(&dmasound_core_mutex);
335 mixer.busy = 0; 340 mixer.busy = 0;
336 module_put(dmasound.mach.owner); 341 module_put(dmasound.mach.owner);
337 unlock_kernel(); 342 mutex_unlock(&dmasound_core_mutex);
338 return 0; 343 return 0;
339} 344}
340static int mixer_ioctl(struct inode *inode, struct file *file, u_int cmd, 345
341 u_long arg) 346static int mixer_ioctl(struct file *file, u_int cmd, u_long arg)
342{ 347{
343 if (_SIOC_DIR(cmd) & _SIOC_WRITE) 348 if (_SIOC_DIR(cmd) & _SIOC_WRITE)
344 mixer.modify_counter++; 349 mixer.modify_counter++;
@@ -362,11 +367,22 @@ static int mixer_ioctl(struct inode *inode, struct file *file, u_int cmd,
362 return -EINVAL; 367 return -EINVAL;
363} 368}
364 369
370static long mixer_unlocked_ioctl(struct file *file, u_int cmd, u_long arg)
371{
372 int ret;
373
374 mutex_lock(&dmasound_core_mutex);
375 ret = mixer_ioctl(file, cmd, arg);
376 mutex_unlock(&dmasound_core_mutex);
377
378 return ret;
379}
380
365static const struct file_operations mixer_fops = 381static const struct file_operations mixer_fops =
366{ 382{
367 .owner = THIS_MODULE, 383 .owner = THIS_MODULE,
368 .llseek = no_llseek, 384 .llseek = no_llseek,
369 .ioctl = mixer_ioctl, 385 .unlocked_ioctl = mixer_unlocked_ioctl,
370 .open = mixer_open, 386 .open = mixer_open,
371 .release = mixer_release, 387 .release = mixer_release,
372}; 388};
@@ -737,8 +753,11 @@ static int sq_open(struct inode *inode, struct file *file)
737{ 753{
738 int rc; 754 int rc;
739 755
740 if (!try_module_get(dmasound.mach.owner)) 756 mutex_lock(&dmasound_core_mutex);
757 if (!try_module_get(dmasound.mach.owner)) {
758 mutex_unlock(&dmasound_core_mutex);
741 return -ENODEV; 759 return -ENODEV;
760 }
742 761
743 rc = write_sq_open(file); /* checks the f_mode */ 762 rc = write_sq_open(file); /* checks the f_mode */
744 if (rc) 763 if (rc)
@@ -781,10 +800,11 @@ static int sq_open(struct inode *inode, struct file *file)
781 sound_set_format(AFMT_MU_LAW); 800 sound_set_format(AFMT_MU_LAW);
782 } 801 }
783#endif 802#endif
784 803 mutex_unlock(&dmasound_core_mutex);
785 return 0; 804 return 0;
786 out: 805 out:
787 module_put(dmasound.mach.owner); 806 module_put(dmasound.mach.owner);
807 mutex_unlock(&dmasound_core_mutex);
788 return rc; 808 return rc;
789} 809}
790 810
@@ -850,7 +870,7 @@ static int sq_release(struct inode *inode, struct file *file)
850{ 870{
851 int rc = 0; 871 int rc = 0;
852 872
853 lock_kernel(); 873 mutex_lock(&dmasound_core_mutex);
854 874
855 if (file->f_mode & FMODE_WRITE) { 875 if (file->f_mode & FMODE_WRITE) {
856 if (write_sq.busy) 876 if (write_sq.busy)
@@ -881,7 +901,7 @@ static int sq_release(struct inode *inode, struct file *file)
881 write_sq_wake_up(file); /* checks f_mode */ 901 write_sq_wake_up(file); /* checks f_mode */
882#endif /* blocking open() */ 902#endif /* blocking open() */
883 903
884 unlock_kernel(); 904 mutex_unlock(&dmasound_core_mutex);
885 905
886 return rc; 906 return rc;
887} 907}
@@ -955,8 +975,7 @@ printk("dmasound_core: tried to set_queue_frags on a locked queue\n") ;
955 return 0 ; 975 return 0 ;
956} 976}
957 977
958static int sq_ioctl(struct inode *inode, struct file *file, u_int cmd, 978static int sq_ioctl(struct file *file, u_int cmd, u_long arg)
959 u_long arg)
960{ 979{
961 int val, result; 980 int val, result;
962 u_long fmt; 981 u_long fmt;
@@ -1114,18 +1133,29 @@ static int sq_ioctl(struct inode *inode, struct file *file, u_int cmd,
1114 return IOCTL_OUT(arg,val); 1133 return IOCTL_OUT(arg,val);
1115 1134
1116 default: 1135 default:
1117 return mixer_ioctl(inode, file, cmd, arg); 1136 return mixer_ioctl(file, cmd, arg);
1118 } 1137 }
1119 return -EINVAL; 1138 return -EINVAL;
1120} 1139}
1121 1140
1141static long sq_unlocked_ioctl(struct file *file, u_int cmd, u_long arg)
1142{
1143 int ret;
1144
1145 mutex_lock(&dmasound_core_mutex);
1146 ret = sq_ioctl(file, cmd, arg);
1147 mutex_unlock(&dmasound_core_mutex);
1148
1149 return ret;
1150}
1151
1122static const struct file_operations sq_fops = 1152static const struct file_operations sq_fops =
1123{ 1153{
1124 .owner = THIS_MODULE, 1154 .owner = THIS_MODULE,
1125 .llseek = no_llseek, 1155 .llseek = no_llseek,
1126 .write = sq_write, 1156 .write = sq_write,
1127 .poll = sq_poll, 1157 .poll = sq_poll,
1128 .ioctl = sq_ioctl, 1158 .unlocked_ioctl = sq_unlocked_ioctl,
1129 .open = sq_open, 1159 .open = sq_open,
1130 .release = sq_release, 1160 .release = sq_release,
1131}; 1161};
@@ -1226,12 +1256,17 @@ static int state_open(struct inode *inode, struct file *file)
1226{ 1256{
1227 char *buffer = state.buf; 1257 char *buffer = state.buf;
1228 int len = 0; 1258 int len = 0;
1259 int ret;
1229 1260
1261 mutex_lock(&dmasound_core_mutex);
1262 ret = -EBUSY;
1230 if (state.busy) 1263 if (state.busy)
1231 return -EBUSY; 1264 goto out;
1232 1265
1266 ret = -ENODEV;
1233 if (!try_module_get(dmasound.mach.owner)) 1267 if (!try_module_get(dmasound.mach.owner))
1234 return -ENODEV; 1268 goto out;
1269
1235 state.ptr = 0; 1270 state.ptr = 0;
1236 state.busy = 1; 1271 state.busy = 1;
1237 1272
@@ -1293,15 +1328,18 @@ printk("dmasound: stat buffer used %d bytes\n", len) ;
1293 printk(KERN_ERR "dmasound_core: stat buffer overflowed!\n"); 1328 printk(KERN_ERR "dmasound_core: stat buffer overflowed!\n");
1294 1329
1295 state.len = len; 1330 state.len = len;
1296 return 0; 1331 ret = 0;
1332out:
1333 mutex_unlock(&dmasound_core_mutex);
1334 return ret;
1297} 1335}
1298 1336
1299static int state_release(struct inode *inode, struct file *file) 1337static int state_release(struct inode *inode, struct file *file)
1300{ 1338{
1301 lock_kernel(); 1339 mutex_lock(&dmasound_core_mutex);
1302 state.busy = 0; 1340 state.busy = 0;
1303 module_put(dmasound.mach.owner); 1341 module_put(dmasound.mach.owner);
1304 unlock_kernel(); 1342 mutex_unlock(&dmasound_core_mutex);
1305 return 0; 1343 return 0;
1306} 1344}
1307 1345
diff --git a/sound/oss/midi_synth.c b/sound/oss/midi_synth.c
index 3bc7104c537..3c09374ea5b 100644
--- a/sound/oss/midi_synth.c
+++ b/sound/oss/midi_synth.c
@@ -523,7 +523,9 @@ midi_synth_load_patch(int dev, int format, const char __user *addr,
523 { 523 {
524 unsigned char data; 524 unsigned char data;
525 525
526 get_user(*(unsigned char *) &data, (unsigned char __user *) &((addr)[hdr_size + i])); 526 if (get_user(data,
527 (unsigned char __user *)(addr + hdr_size + i)))
528 return -EFAULT;
527 529
528 eox_seen = (i > 0 && data & 0x80); /* End of sysex */ 530 eox_seen = (i > 0 && data & 0x80); /* End of sysex */
529 531
diff --git a/sound/oss/msnd_pinnacle.c b/sound/oss/msnd_pinnacle.c
index a1e3f9671be..b4c1eb504c2 100644
--- a/sound/oss/msnd_pinnacle.c
+++ b/sound/oss/msnd_pinnacle.c
@@ -39,7 +39,7 @@
39#include <linux/delay.h> 39#include <linux/delay.h>
40#include <linux/init.h> 40#include <linux/init.h>
41#include <linux/interrupt.h> 41#include <linux/interrupt.h>
42#include <linux/smp_lock.h> 42#include <linux/mutex.h>
43#include <linux/gfp.h> 43#include <linux/gfp.h>
44#include <asm/irq.h> 44#include <asm/irq.h>
45#include <asm/io.h> 45#include <asm/io.h>
@@ -79,6 +79,7 @@
79 dev.rec_sample_rate / \ 79 dev.rec_sample_rate / \
80 dev.rec_channels) 80 dev.rec_channels)
81 81
82static DEFINE_MUTEX(msnd_pinnacle_mutex);
82static multisound_dev_t dev; 83static multisound_dev_t dev;
83 84
84#ifndef HAVE_DSPCODEH 85#ifndef HAVE_DSPCODEH
@@ -639,21 +640,26 @@ static int mixer_ioctl(unsigned int cmd, unsigned long arg)
639 return -EINVAL; 640 return -EINVAL;
640} 641}
641 642
642static int dev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) 643static long dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
643{ 644{
644 int minor = iminor(inode); 645 int minor = iminor(file->f_path.dentry->d_inode);
646 int ret;
645 647
646 if (cmd == OSS_GETVERSION) { 648 if (cmd == OSS_GETVERSION) {
647 int sound_version = SOUND_VERSION; 649 int sound_version = SOUND_VERSION;
648 return put_user(sound_version, (int __user *)arg); 650 return put_user(sound_version, (int __user *)arg);
649 } 651 }
650 652
653 ret = -EINVAL;
654
655 mutex_lock(&msnd_pinnacle_mutex);
651 if (minor == dev.dsp_minor) 656 if (minor == dev.dsp_minor)
652 return dsp_ioctl(file, cmd, arg); 657 ret = dsp_ioctl(file, cmd, arg);
653 else if (minor == dev.mixer_minor) 658 else if (minor == dev.mixer_minor)
654 return mixer_ioctl(cmd, arg); 659 ret = mixer_ioctl(cmd, arg);
660 mutex_unlock(&msnd_pinnacle_mutex);
655 661
656 return -EINVAL; 662 return ret;
657} 663}
658 664
659static void dsp_write_flush(void) 665static void dsp_write_flush(void)
@@ -756,12 +762,15 @@ static int dev_open(struct inode *inode, struct file *file)
756 int minor = iminor(inode); 762 int minor = iminor(inode);
757 int err = 0; 763 int err = 0;
758 764
765 mutex_lock(&msnd_pinnacle_mutex);
759 if (minor == dev.dsp_minor) { 766 if (minor == dev.dsp_minor) {
760 if ((file->f_mode & FMODE_WRITE && 767 if ((file->f_mode & FMODE_WRITE &&
761 test_bit(F_AUDIO_WRITE_INUSE, &dev.flags)) || 768 test_bit(F_AUDIO_WRITE_INUSE, &dev.flags)) ||
762 (file->f_mode & FMODE_READ && 769 (file->f_mode & FMODE_READ &&
763 test_bit(F_AUDIO_READ_INUSE, &dev.flags))) 770 test_bit(F_AUDIO_READ_INUSE, &dev.flags))) {
764 return -EBUSY; 771 err = -EBUSY;
772 goto out;
773 }
765 774
766 if ((err = dsp_open(file)) >= 0) { 775 if ((err = dsp_open(file)) >= 0) {
767 dev.nresets = 0; 776 dev.nresets = 0;
@@ -782,7 +791,8 @@ static int dev_open(struct inode *inode, struct file *file)
782 /* nothing */ 791 /* nothing */
783 } else 792 } else
784 err = -EINVAL; 793 err = -EINVAL;
785 794out:
795 mutex_unlock(&msnd_pinnacle_mutex);
786 return err; 796 return err;
787} 797}
788 798
@@ -791,14 +801,14 @@ static int dev_release(struct inode *inode, struct file *file)
791 int minor = iminor(inode); 801 int minor = iminor(inode);
792 int err = 0; 802 int err = 0;
793 803
794 lock_kernel(); 804 mutex_lock(&msnd_pinnacle_mutex);
795 if (minor == dev.dsp_minor) 805 if (minor == dev.dsp_minor)
796 err = dsp_release(file); 806 err = dsp_release(file);
797 else if (minor == dev.mixer_minor) { 807 else if (minor == dev.mixer_minor) {
798 /* nothing */ 808 /* nothing */
799 } else 809 } else
800 err = -EINVAL; 810 err = -EINVAL;
801 unlock_kernel(); 811 mutex_unlock(&msnd_pinnacle_mutex);
802 return err; 812 return err;
803} 813}
804 814
@@ -1105,7 +1115,7 @@ static const struct file_operations dev_fileops = {
1105 .owner = THIS_MODULE, 1115 .owner = THIS_MODULE,
1106 .read = dev_read, 1116 .read = dev_read,
1107 .write = dev_write, 1117 .write = dev_write,
1108 .ioctl = dev_ioctl, 1118 .unlocked_ioctl = dev_ioctl,
1109 .open = dev_open, 1119 .open = dev_open,
1110 .release = dev_release, 1120 .release = dev_release,
1111}; 1121};
@@ -1391,9 +1401,13 @@ static int __init attach_multisound(void)
1391 printk(KERN_ERR LOGNAME ": Couldn't grab IRQ %d\n", dev.irq); 1401 printk(KERN_ERR LOGNAME ": Couldn't grab IRQ %d\n", dev.irq);
1392 return err; 1402 return err;
1393 } 1403 }
1394 request_region(dev.io, dev.numio, dev.name); 1404 if (request_region(dev.io, dev.numio, dev.name) == NULL) {
1405 free_irq(dev.irq, &dev);
1406 return -EBUSY;
1407 }
1395 1408
1396 if ((err = dsp_full_reset()) < 0) { 1409 err = dsp_full_reset();
1410 if (err < 0) {
1397 release_region(dev.io, dev.numio); 1411 release_region(dev.io, dev.numio);
1398 free_irq(dev.irq, &dev); 1412 free_irq(dev.irq, &dev);
1399 return err; 1413 return err;
diff --git a/sound/oss/sh_dac_audio.c b/sound/oss/sh_dac_audio.c
deleted file mode 100644
index 4153752507e..00000000000
--- a/sound/oss/sh_dac_audio.c
+++ /dev/null
@@ -1,309 +0,0 @@
1/*
2 * sound/oss/sh_dac_audio.c
3 *
4 * SH DAC based sound :(
5 *
6 * Copyright (C) 2004,2005 Andriy Skulysh
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
10 * for more details.
11 */
12#include <linux/module.h>
13#include <linux/init.h>
14#include <linux/sched.h>
15#include <linux/linkage.h>
16#include <linux/slab.h>
17#include <linux/fs.h>
18#include <linux/sound.h>
19#include <linux/soundcard.h>
20#include <linux/interrupt.h>
21#include <linux/hrtimer.h>
22#include <asm/io.h>
23#include <asm/uaccess.h>
24#include <asm/irq.h>
25#include <asm/delay.h>
26#include <asm/clock.h>
27#include <cpu/dac.h>
28#include <asm/machvec.h>
29#include <mach/hp6xx.h>
30#include <asm/hd64461.h>
31
32#define MODNAME "sh_dac_audio"
33
34#define BUFFER_SIZE 48000
35
36static int rate;
37static int empty;
38static char *data_buffer, *buffer_begin, *buffer_end;
39static int in_use, device_major;
40static struct hrtimer hrtimer;
41static ktime_t wakeups_per_second;
42
43static void dac_audio_start_timer(void)
44{
45 hrtimer_start(&hrtimer, wakeups_per_second, HRTIMER_MODE_REL);
46}
47
48static void dac_audio_stop_timer(void)
49{
50 hrtimer_cancel(&hrtimer);
51}
52
53static void dac_audio_reset(void)
54{
55 dac_audio_stop_timer();
56 buffer_begin = buffer_end = data_buffer;
57 empty = 1;
58}
59
60static void dac_audio_sync(void)
61{
62 while (!empty)
63 schedule();
64}
65
66static void dac_audio_start(void)
67{
68 if (mach_is_hp6xx()) {
69 u16 v = __raw_readw(HD64461_GPADR);
70 v &= ~HD64461_GPADR_SPEAKER;
71 __raw_writew(v, HD64461_GPADR);
72 }
73
74 sh_dac_enable(CONFIG_SOUND_SH_DAC_AUDIO_CHANNEL);
75}
76static void dac_audio_stop(void)
77{
78 dac_audio_stop_timer();
79
80 if (mach_is_hp6xx()) {
81 u16 v = __raw_readw(HD64461_GPADR);
82 v |= HD64461_GPADR_SPEAKER;
83 __raw_writew(v, HD64461_GPADR);
84 }
85
86 sh_dac_output(0, CONFIG_SOUND_SH_DAC_AUDIO_CHANNEL);
87 sh_dac_disable(CONFIG_SOUND_SH_DAC_AUDIO_CHANNEL);
88}
89
90static void dac_audio_set_rate(void)
91{
92 wakeups_per_second = ktime_set(0, 1000000000 / rate);
93}
94
95static int dac_audio_ioctl(struct inode *inode, struct file *file,
96 unsigned int cmd, unsigned long arg)
97{
98 int val;
99
100 switch (cmd) {
101 case OSS_GETVERSION:
102 return put_user(SOUND_VERSION, (int *)arg);
103
104 case SNDCTL_DSP_SYNC:
105 dac_audio_sync();
106 return 0;
107
108 case SNDCTL_DSP_RESET:
109 dac_audio_reset();
110 return 0;
111
112 case SNDCTL_DSP_GETFMTS:
113 return put_user(AFMT_U8, (int *)arg);
114
115 case SNDCTL_DSP_SETFMT:
116 return put_user(AFMT_U8, (int *)arg);
117
118 case SNDCTL_DSP_NONBLOCK:
119 spin_lock(&file->f_lock);
120 file->f_flags |= O_NONBLOCK;
121 spin_unlock(&file->f_lock);
122 return 0;
123
124 case SNDCTL_DSP_GETCAPS:
125 return 0;
126
127 case SOUND_PCM_WRITE_RATE:
128 val = *(int *)arg;
129 if (val > 0) {
130 rate = val;
131 dac_audio_set_rate();
132 }
133 return put_user(rate, (int *)arg);
134
135 case SNDCTL_DSP_STEREO:
136 return put_user(0, (int *)arg);
137
138 case SOUND_PCM_WRITE_CHANNELS:
139 return put_user(1, (int *)arg);
140
141 case SNDCTL_DSP_SETDUPLEX:
142 return -EINVAL;
143
144 case SNDCTL_DSP_PROFILE:
145 return -EINVAL;
146
147 case SNDCTL_DSP_GETBLKSIZE:
148 return put_user(BUFFER_SIZE, (int *)arg);
149
150 case SNDCTL_DSP_SETFRAGMENT:
151 return 0;
152
153 default:
154 printk(KERN_ERR "sh_dac_audio: unimplemented ioctl=0x%x\n",
155 cmd);
156 return -EINVAL;
157 }
158 return -EINVAL;
159}
160
161static ssize_t dac_audio_write(struct file *file, const char *buf, size_t count,
162 loff_t * ppos)
163{
164 int free;
165 int nbytes;
166
167 if (!count) {
168 dac_audio_sync();
169 return 0;
170 }
171
172 free = buffer_begin - buffer_end;
173
174 if (free < 0)
175 free += BUFFER_SIZE;
176 if ((free == 0) && (empty))
177 free = BUFFER_SIZE;
178 if (count > free)
179 count = free;
180 if (buffer_begin > buffer_end) {
181 if (copy_from_user((void *)buffer_end, buf, count))
182 return -EFAULT;
183
184 buffer_end += count;
185 } else {
186 nbytes = data_buffer + BUFFER_SIZE - buffer_end;
187 if (nbytes > count) {
188 if (copy_from_user((void *)buffer_end, buf, count))
189 return -EFAULT;
190 buffer_end += count;
191 } else {
192 if (copy_from_user((void *)buffer_end, buf, nbytes))
193 return -EFAULT;
194 if (copy_from_user
195 ((void *)data_buffer, buf + nbytes, count - nbytes))
196 return -EFAULT;
197 buffer_end = data_buffer + count - nbytes;
198 }
199 }
200
201 if (empty) {
202 empty = 0;
203 dac_audio_start_timer();
204 }
205
206 return count;
207}
208
209static ssize_t dac_audio_read(struct file *file, char *buf, size_t count,
210 loff_t * ppos)
211{
212 return -EINVAL;
213}
214
215static int dac_audio_open(struct inode *inode, struct file *file)
216{
217 if (file->f_mode & FMODE_READ)
218 return -ENODEV;
219 if (in_use)
220 return -EBUSY;
221
222 in_use = 1;
223
224 dac_audio_start();
225
226 return 0;
227}
228
229static int dac_audio_release(struct inode *inode, struct file *file)
230{
231 dac_audio_sync();
232 dac_audio_stop();
233 in_use = 0;
234
235 return 0;
236}
237
238const struct file_operations dac_audio_fops = {
239 .read = dac_audio_read,
240 .write = dac_audio_write,
241 .ioctl = dac_audio_ioctl,
242 .open = dac_audio_open,
243 .release = dac_audio_release,
244};
245
246static enum hrtimer_restart sh_dac_audio_timer(struct hrtimer *handle)
247{
248 if (!empty) {
249 sh_dac_output(*buffer_begin, CONFIG_SOUND_SH_DAC_AUDIO_CHANNEL);
250 buffer_begin++;
251
252 if (buffer_begin == data_buffer + BUFFER_SIZE)
253 buffer_begin = data_buffer;
254 if (buffer_begin == buffer_end)
255 empty = 1;
256 }
257
258 if (!empty)
259 hrtimer_start(&hrtimer, wakeups_per_second, HRTIMER_MODE_REL);
260
261 return HRTIMER_NORESTART;
262}
263
264static int __init dac_audio_init(void)
265{
266 if ((device_major = register_sound_dsp(&dac_audio_fops, -1)) < 0) {
267 printk(KERN_ERR "Cannot register dsp device");
268 return device_major;
269 }
270
271 in_use = 0;
272
273 data_buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL);
274 if (data_buffer == NULL)
275 return -ENOMEM;
276
277 dac_audio_reset();
278 rate = 8000;
279 dac_audio_set_rate();
280
281 /* Today: High Resolution Timer driven DAC playback.
282 * The timer callback gets called once per sample. Ouch.
283 *
284 * Future: A much better approach would be to use the
285 * SH7720 CMT+DMAC+DAC hardware combination like this:
286 * - Program sample rate using CMT0 or CMT1
287 * - Program DMAC to use CMT for timing and output to DAC
288 * - Play sound using DMAC, let CPU sleep.
289 * - While at it, rewrite this driver to use ALSA.
290 */
291
292 hrtimer_init(&hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
293 hrtimer.function = sh_dac_audio_timer;
294
295 return 0;
296}
297
298static void __exit dac_audio_exit(void)
299{
300 unregister_sound_dsp(device_major);
301 kfree((void *)data_buffer);
302}
303
304module_init(dac_audio_init);
305module_exit(dac_audio_exit);
306
307MODULE_AUTHOR("Andriy Skulysh, askulysh@image.kiev.ua");
308MODULE_DESCRIPTION("SH DAC sound driver");
309MODULE_LICENSE("GPL");
diff --git a/sound/oss/sound_timer.c b/sound/oss/sound_timer.c
index f0f0c19fbff..48cda6c4c25 100644
--- a/sound/oss/sound_timer.c
+++ b/sound/oss/sound_timer.c
@@ -26,7 +26,7 @@ static unsigned long prev_event_time;
26static volatile unsigned long usecs_per_tmr; /* Length of the current interval */ 26static volatile unsigned long usecs_per_tmr; /* Length of the current interval */
27 27
28static struct sound_lowlev_timer *tmr; 28static struct sound_lowlev_timer *tmr;
29static spinlock_t lock; 29static DEFINE_SPINLOCK(lock);
30 30
31static unsigned long tmr2ticks(int tmr_value) 31static unsigned long tmr2ticks(int tmr_value)
32{ 32{
diff --git a/sound/oss/soundcard.c b/sound/oss/soundcard.c
index 2d9c5131262..46c0d03dbec 100644
--- a/sound/oss/soundcard.c
+++ b/sound/oss/soundcard.c
@@ -40,7 +40,7 @@
40#include <linux/major.h> 40#include <linux/major.h>
41#include <linux/delay.h> 41#include <linux/delay.h>
42#include <linux/proc_fs.h> 42#include <linux/proc_fs.h>
43#include <linux/smp_lock.h> 43#include <linux/mutex.h>
44#include <linux/module.h> 44#include <linux/module.h>
45#include <linux/mm.h> 45#include <linux/mm.h>
46#include <linux/device.h> 46#include <linux/device.h>
@@ -56,6 +56,7 @@
56 * Table for permanently allocated memory (used when unloading the module) 56 * Table for permanently allocated memory (used when unloading the module)
57 */ 57 */
58void * sound_mem_blocks[MAX_MEM_BLOCKS]; 58void * sound_mem_blocks[MAX_MEM_BLOCKS];
59static DEFINE_MUTEX(soundcard_mutex);
59int sound_nblocks = 0; 60int sound_nblocks = 0;
60 61
61/* Persistent DMA buffers */ 62/* Persistent DMA buffers */
@@ -151,7 +152,7 @@ static ssize_t sound_read(struct file *file, char __user *buf, size_t count, lof
151 * big one anyway, we might as well bandage here.. 152 * big one anyway, we might as well bandage here..
152 */ 153 */
153 154
154 lock_kernel(); 155 mutex_lock(&soundcard_mutex);
155 156
156 DEB(printk("sound_read(dev=%d, count=%d)\n", dev, count)); 157 DEB(printk("sound_read(dev=%d, count=%d)\n", dev, count));
157 switch (dev & 0x0f) { 158 switch (dev & 0x0f) {
@@ -169,7 +170,7 @@ static ssize_t sound_read(struct file *file, char __user *buf, size_t count, lof
169 case SND_DEV_MIDIN: 170 case SND_DEV_MIDIN:
170 ret = MIDIbuf_read(dev, file, buf, count); 171 ret = MIDIbuf_read(dev, file, buf, count);
171 } 172 }
172 unlock_kernel(); 173 mutex_unlock(&soundcard_mutex);
173 return ret; 174 return ret;
174} 175}
175 176
@@ -178,7 +179,7 @@ static ssize_t sound_write(struct file *file, const char __user *buf, size_t cou
178 int dev = iminor(file->f_path.dentry->d_inode); 179 int dev = iminor(file->f_path.dentry->d_inode);
179 int ret = -EINVAL; 180 int ret = -EINVAL;
180 181
181 lock_kernel(); 182 mutex_lock(&soundcard_mutex);
182 DEB(printk("sound_write(dev=%d, count=%d)\n", dev, count)); 183 DEB(printk("sound_write(dev=%d, count=%d)\n", dev, count));
183 switch (dev & 0x0f) { 184 switch (dev & 0x0f) {
184 case SND_DEV_SEQ: 185 case SND_DEV_SEQ:
@@ -196,7 +197,7 @@ static ssize_t sound_write(struct file *file, const char __user *buf, size_t cou
196 ret = MIDIbuf_write(dev, file, buf, count); 197 ret = MIDIbuf_write(dev, file, buf, count);
197 break; 198 break;
198 } 199 }
199 unlock_kernel(); 200 mutex_unlock(&soundcard_mutex);
200 return ret; 201 return ret;
201} 202}
202 203
@@ -210,50 +211,52 @@ static int sound_open(struct inode *inode, struct file *file)
210 printk(KERN_ERR "Invalid minor device %d\n", dev); 211 printk(KERN_ERR "Invalid minor device %d\n", dev);
211 return -ENXIO; 212 return -ENXIO;
212 } 213 }
214 mutex_lock(&soundcard_mutex);
213 switch (dev & 0x0f) { 215 switch (dev & 0x0f) {
214 case SND_DEV_CTL: 216 case SND_DEV_CTL:
215 dev >>= 4; 217 dev >>= 4;
216 if (dev >= 0 && dev < MAX_MIXER_DEV && mixer_devs[dev] == NULL) { 218 if (dev >= 0 && dev < MAX_MIXER_DEV && mixer_devs[dev] == NULL) {
217 request_module("mixer%d", dev); 219 request_module("mixer%d", dev);
218 } 220 }
221 retval = -ENXIO;
219 if (dev && (dev >= num_mixers || mixer_devs[dev] == NULL)) 222 if (dev && (dev >= num_mixers || mixer_devs[dev] == NULL))
220 return -ENXIO; 223 break;
221 224
222 if (!try_module_get(mixer_devs[dev]->owner)) 225 if (!try_module_get(mixer_devs[dev]->owner))
223 return -ENXIO; 226 break;
227
228 retval = 0;
224 break; 229 break;
225 230
226 case SND_DEV_SEQ: 231 case SND_DEV_SEQ:
227 case SND_DEV_SEQ2: 232 case SND_DEV_SEQ2:
228 if ((retval = sequencer_open(dev, file)) < 0) 233 retval = sequencer_open(dev, file);
229 return retval;
230 break; 234 break;
231 235
232 case SND_DEV_MIDIN: 236 case SND_DEV_MIDIN:
233 if ((retval = MIDIbuf_open(dev, file)) < 0) 237 retval = MIDIbuf_open(dev, file);
234 return retval;
235 break; 238 break;
236 239
237 case SND_DEV_DSP: 240 case SND_DEV_DSP:
238 case SND_DEV_DSP16: 241 case SND_DEV_DSP16:
239 case SND_DEV_AUDIO: 242 case SND_DEV_AUDIO:
240 if ((retval = audio_open(dev, file)) < 0) 243 retval = audio_open(dev, file);
241 return retval;
242 break; 244 break;
243 245
244 default: 246 default:
245 printk(KERN_ERR "Invalid minor device %d\n", dev); 247 printk(KERN_ERR "Invalid minor device %d\n", dev);
246 return -ENXIO; 248 retval = -ENXIO;
247 } 249 }
248 250
249 return 0; 251 mutex_unlock(&soundcard_mutex);
252 return retval;
250} 253}
251 254
252static int sound_release(struct inode *inode, struct file *file) 255static int sound_release(struct inode *inode, struct file *file)
253{ 256{
254 int dev = iminor(inode); 257 int dev = iminor(inode);
255 258
256 lock_kernel(); 259 mutex_lock(&soundcard_mutex);
257 DEB(printk("sound_release(dev=%d)\n", dev)); 260 DEB(printk("sound_release(dev=%d)\n", dev));
258 switch (dev & 0x0f) { 261 switch (dev & 0x0f) {
259 case SND_DEV_CTL: 262 case SND_DEV_CTL:
@@ -278,7 +281,7 @@ static int sound_release(struct inode *inode, struct file *file)
278 default: 281 default:
279 printk(KERN_ERR "Sound error: Releasing unknown device 0x%02x\n", dev); 282 printk(KERN_ERR "Sound error: Releasing unknown device 0x%02x\n", dev);
280 } 283 }
281 unlock_kernel(); 284 mutex_unlock(&soundcard_mutex);
282 285
283 return 0; 286 return 0;
284} 287}
@@ -352,7 +355,7 @@ static long sound_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
352 if (cmd == OSS_GETVERSION) 355 if (cmd == OSS_GETVERSION)
353 return __put_user(SOUND_VERSION, (int __user *)p); 356 return __put_user(SOUND_VERSION, (int __user *)p);
354 357
355 lock_kernel(); 358 mutex_lock(&soundcard_mutex);
356 if (_IOC_TYPE(cmd) == 'M' && num_mixers > 0 && /* Mixer ioctl */ 359 if (_IOC_TYPE(cmd) == 'M' && num_mixers > 0 && /* Mixer ioctl */
357 (dev & 0x0f) != SND_DEV_CTL) { 360 (dev & 0x0f) != SND_DEV_CTL) {
358 dtype = dev & 0x0f; 361 dtype = dev & 0x0f;
@@ -367,7 +370,7 @@ static long sound_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
367 ret = sound_mixer_ioctl(dev >> 4, cmd, p); 370 ret = sound_mixer_ioctl(dev >> 4, cmd, p);
368 break; 371 break;
369 } 372 }
370 unlock_kernel(); 373 mutex_unlock(&soundcard_mutex);
371 return ret; 374 return ret;
372 } 375 }
373 376
@@ -389,15 +392,15 @@ static long sound_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
389 case SND_DEV_DSP: 392 case SND_DEV_DSP:
390 case SND_DEV_DSP16: 393 case SND_DEV_DSP16:
391 case SND_DEV_AUDIO: 394 case SND_DEV_AUDIO:
392 return audio_ioctl(dev, file, cmd, p); 395 ret = audio_ioctl(dev, file, cmd, p);
393 break; 396 break;
394 397
395 case SND_DEV_MIDIN: 398 case SND_DEV_MIDIN:
396 return MIDIbuf_ioctl(dev, file, cmd, p); 399 ret = MIDIbuf_ioctl(dev, file, cmd, p);
397 break; 400 break;
398 401
399 } 402 }
400 unlock_kernel(); 403 mutex_unlock(&soundcard_mutex);
401 return ret; 404 return ret;
402} 405}
403 406
@@ -437,35 +440,35 @@ static int sound_mmap(struct file *file, struct vm_area_struct *vma)
437 printk(KERN_ERR "Sound: mmap() not supported for other than audio devices\n"); 440 printk(KERN_ERR "Sound: mmap() not supported for other than audio devices\n");
438 return -EINVAL; 441 return -EINVAL;
439 } 442 }
440 lock_kernel(); 443 mutex_lock(&soundcard_mutex);
441 if (vma->vm_flags & VM_WRITE) /* Map write and read/write to the output buf */ 444 if (vma->vm_flags & VM_WRITE) /* Map write and read/write to the output buf */
442 dmap = audio_devs[dev]->dmap_out; 445 dmap = audio_devs[dev]->dmap_out;
443 else if (vma->vm_flags & VM_READ) 446 else if (vma->vm_flags & VM_READ)
444 dmap = audio_devs[dev]->dmap_in; 447 dmap = audio_devs[dev]->dmap_in;
445 else { 448 else {
446 printk(KERN_ERR "Sound: Undefined mmap() access\n"); 449 printk(KERN_ERR "Sound: Undefined mmap() access\n");
447 unlock_kernel(); 450 mutex_unlock(&soundcard_mutex);
448 return -EINVAL; 451 return -EINVAL;
449 } 452 }
450 453
451 if (dmap == NULL) { 454 if (dmap == NULL) {
452 printk(KERN_ERR "Sound: mmap() error. dmap == NULL\n"); 455 printk(KERN_ERR "Sound: mmap() error. dmap == NULL\n");
453 unlock_kernel(); 456 mutex_unlock(&soundcard_mutex);
454 return -EIO; 457 return -EIO;
455 } 458 }
456 if (dmap->raw_buf == NULL) { 459 if (dmap->raw_buf == NULL) {
457 printk(KERN_ERR "Sound: mmap() called when raw_buf == NULL\n"); 460 printk(KERN_ERR "Sound: mmap() called when raw_buf == NULL\n");
458 unlock_kernel(); 461 mutex_unlock(&soundcard_mutex);
459 return -EIO; 462 return -EIO;
460 } 463 }
461 if (dmap->mapping_flags) { 464 if (dmap->mapping_flags) {
462 printk(KERN_ERR "Sound: mmap() called twice for the same DMA buffer\n"); 465 printk(KERN_ERR "Sound: mmap() called twice for the same DMA buffer\n");
463 unlock_kernel(); 466 mutex_unlock(&soundcard_mutex);
464 return -EIO; 467 return -EIO;
465 } 468 }
466 if (vma->vm_pgoff != 0) { 469 if (vma->vm_pgoff != 0) {
467 printk(KERN_ERR "Sound: mmap() offset must be 0.\n"); 470 printk(KERN_ERR "Sound: mmap() offset must be 0.\n");
468 unlock_kernel(); 471 mutex_unlock(&soundcard_mutex);
469 return -EINVAL; 472 return -EINVAL;
470 } 473 }
471 size = vma->vm_end - vma->vm_start; 474 size = vma->vm_end - vma->vm_start;
@@ -476,7 +479,7 @@ static int sound_mmap(struct file *file, struct vm_area_struct *vma)
476 if (remap_pfn_range(vma, vma->vm_start, 479 if (remap_pfn_range(vma, vma->vm_start,
477 virt_to_phys(dmap->raw_buf) >> PAGE_SHIFT, 480 virt_to_phys(dmap->raw_buf) >> PAGE_SHIFT,
478 vma->vm_end - vma->vm_start, vma->vm_page_prot)) { 481 vma->vm_end - vma->vm_start, vma->vm_page_prot)) {
479 unlock_kernel(); 482 mutex_unlock(&soundcard_mutex);
480 return -EAGAIN; 483 return -EAGAIN;
481 } 484 }
482 485
@@ -488,7 +491,7 @@ static int sound_mmap(struct file *file, struct vm_area_struct *vma)
488 memset(dmap->raw_buf, 491 memset(dmap->raw_buf,
489 dmap->neutral_byte, 492 dmap->neutral_byte,
490 dmap->bytes_in_use); 493 dmap->bytes_in_use);
491 unlock_kernel(); 494 mutex_unlock(&soundcard_mutex);
492 return 0; 495 return 0;
493} 496}
494 497
diff --git a/sound/oss/swarm_cs4297a.c b/sound/oss/swarm_cs4297a.c
index 3136c88eacd..44357d877a2 100644
--- a/sound/oss/swarm_cs4297a.c
+++ b/sound/oss/swarm_cs4297a.c
@@ -93,6 +93,7 @@
93 93
94struct cs4297a_state; 94struct cs4297a_state;
95 95
96static DEFINE_MUTEX(swarm_cs4297a_mutex);
96static void stop_dac(struct cs4297a_state *s); 97static void stop_dac(struct cs4297a_state *s);
97static void stop_adc(struct cs4297a_state *s); 98static void stop_adc(struct cs4297a_state *s);
98static void start_dac(struct cs4297a_state *s); 99static void start_dac(struct cs4297a_state *s);
@@ -1534,6 +1535,7 @@ static int cs4297a_open_mixdev(struct inode *inode, struct file *file)
1534 CS_DBGOUT(CS_FUNCTION | CS_OPEN, 4, 1535 CS_DBGOUT(CS_FUNCTION | CS_OPEN, 4,
1535 printk(KERN_INFO "cs4297a: cs4297a_open_mixdev()+\n")); 1536 printk(KERN_INFO "cs4297a: cs4297a_open_mixdev()+\n"));
1536 1537
1538 mutex_lock(&swarm_cs4297a_mutex);
1537 list_for_each(entry, &cs4297a_devs) 1539 list_for_each(entry, &cs4297a_devs)
1538 { 1540 {
1539 s = list_entry(entry, struct cs4297a_state, list); 1541 s = list_entry(entry, struct cs4297a_state, list);
@@ -1544,6 +1546,8 @@ static int cs4297a_open_mixdev(struct inode *inode, struct file *file)
1544 { 1546 {
1545 CS_DBGOUT(CS_FUNCTION | CS_OPEN | CS_ERROR, 2, 1547 CS_DBGOUT(CS_FUNCTION | CS_OPEN | CS_ERROR, 2,
1546 printk(KERN_INFO "cs4297a: cs4297a_open_mixdev()- -ENODEV\n")); 1548 printk(KERN_INFO "cs4297a: cs4297a_open_mixdev()- -ENODEV\n"));
1549
1550 mutex_unlock(&swarm_cs4297a_mutex);
1547 return -ENODEV; 1551 return -ENODEV;
1548 } 1552 }
1549 VALIDATE_STATE(s); 1553 VALIDATE_STATE(s);
@@ -1551,6 +1555,7 @@ static int cs4297a_open_mixdev(struct inode *inode, struct file *file)
1551 1555
1552 CS_DBGOUT(CS_FUNCTION | CS_OPEN, 4, 1556 CS_DBGOUT(CS_FUNCTION | CS_OPEN, 4,
1553 printk(KERN_INFO "cs4297a: cs4297a_open_mixdev()- 0\n")); 1557 printk(KERN_INFO "cs4297a: cs4297a_open_mixdev()- 0\n"));
1558 mutex_unlock(&swarm_cs4297a_mutex);
1554 1559
1555 return nonseekable_open(inode, file); 1560 return nonseekable_open(inode, file);
1556} 1561}
@@ -1566,11 +1571,15 @@ static int cs4297a_release_mixdev(struct inode *inode, struct file *file)
1566} 1571}
1567 1572
1568 1573
1569static int cs4297a_ioctl_mixdev(struct inode *inode, struct file *file, 1574static int cs4297a_ioctl_mixdev(struct file *file,
1570 unsigned int cmd, unsigned long arg) 1575 unsigned int cmd, unsigned long arg)
1571{ 1576{
1572 return mixer_ioctl((struct cs4297a_state *) file->private_data, cmd, 1577 int ret;
1578 mutex_lock(&swarm_cs4297a_mutex);
1579 ret = mixer_ioctl((struct cs4297a_state *) file->private_data, cmd,
1573 arg); 1580 arg);
1581 mutex_unlock(&swarm_cs4297a_mutex);
1582 return ret;
1574} 1583}
1575 1584
1576 1585
@@ -1580,7 +1589,7 @@ static int cs4297a_ioctl_mixdev(struct inode *inode, struct file *file,
1580static const struct file_operations cs4297a_mixer_fops = { 1589static const struct file_operations cs4297a_mixer_fops = {
1581 .owner = THIS_MODULE, 1590 .owner = THIS_MODULE,
1582 .llseek = no_llseek, 1591 .llseek = no_llseek,
1583 .ioctl = cs4297a_ioctl_mixdev, 1592 .unlocked_ioctl = cs4297a_ioctl_mixdev,
1584 .open = cs4297a_open_mixdev, 1593 .open = cs4297a_open_mixdev,
1585 .release = cs4297a_release_mixdev, 1594 .release = cs4297a_release_mixdev,
1586}; 1595};
@@ -1944,7 +1953,7 @@ static int cs4297a_mmap(struct file *file, struct vm_area_struct *vma)
1944} 1953}
1945 1954
1946 1955
1947static int cs4297a_ioctl(struct inode *inode, struct file *file, 1956static int cs4297a_ioctl(struct file *file,
1948 unsigned int cmd, unsigned long arg) 1957 unsigned int cmd, unsigned long arg)
1949{ 1958{
1950 struct cs4297a_state *s = 1959 struct cs4297a_state *s =
@@ -2337,6 +2346,16 @@ static int cs4297a_ioctl(struct inode *inode, struct file *file,
2337 return mixer_ioctl(s, cmd, arg); 2346 return mixer_ioctl(s, cmd, arg);
2338} 2347}
2339 2348
2349static long cs4297a_unlocked_ioctl(struct file *file, u_int cmd, u_long arg)
2350{
2351 int ret;
2352
2353 mutex_lock(&swarm_cs4297a_mutex);
2354 ret = cs4297a_ioctl(file, cmd, arg);
2355 mutex_unlock(&swarm_cs4297a_mutex);
2356
2357 return ret;
2358}
2340 2359
2341static int cs4297a_release(struct inode *inode, struct file *file) 2360static int cs4297a_release(struct inode *inode, struct file *file)
2342{ 2361{
@@ -2369,7 +2388,7 @@ static int cs4297a_release(struct inode *inode, struct file *file)
2369 return 0; 2388 return 0;
2370} 2389}
2371 2390
2372static int cs4297a_open(struct inode *inode, struct file *file) 2391static int cs4297a_locked_open(struct inode *inode, struct file *file)
2373{ 2392{
2374 int minor = iminor(inode); 2393 int minor = iminor(inode);
2375 struct cs4297a_state *s=NULL; 2394 struct cs4297a_state *s=NULL;
@@ -2486,6 +2505,16 @@ static int cs4297a_open(struct inode *inode, struct file *file)
2486 return nonseekable_open(inode, file); 2505 return nonseekable_open(inode, file);
2487} 2506}
2488 2507
2508static int cs4297a_open(struct inode *inode, struct file *file)
2509{
2510 int ret;
2511
2512 mutex_lock(&swarm_cs4297a_mutex);
2513 ret = cs4297a_open(inode, file);
2514 mutex_unlock(&swarm_cs4297a_mutex);
2515
2516 return ret;
2517}
2489 2518
2490// ****************************************************************************************** 2519// ******************************************************************************************
2491// Wave (audio) file operations struct. 2520// Wave (audio) file operations struct.
@@ -2496,7 +2525,7 @@ static const struct file_operations cs4297a_audio_fops = {
2496 .read = cs4297a_read, 2525 .read = cs4297a_read,
2497 .write = cs4297a_write, 2526 .write = cs4297a_write,
2498 .poll = cs4297a_poll, 2527 .poll = cs4297a_poll,
2499 .ioctl = cs4297a_ioctl, 2528 .unlocked_ioctl = cs4297a_unlocked_ioctl,
2500 .mmap = cs4297a_mmap, 2529 .mmap = cs4297a_mmap,
2501 .open = cs4297a_open, 2530 .open = cs4297a_open,
2502 .release = cs4297a_release, 2531 .release = cs4297a_release,
diff --git a/sound/oss/vidc.c b/sound/oss/vidc.c
index ac39a531df1..f0e0caa5320 100644
--- a/sound/oss/vidc.c
+++ b/sound/oss/vidc.c
@@ -491,9 +491,6 @@ static void __init attach_vidc(struct address_info *hw_config)
491 vidc_adev = adev; 491 vidc_adev = adev;
492 vidc_mixer_set(SOUND_MIXER_VOLUME, (85 | 85 << 8)); 492 vidc_mixer_set(SOUND_MIXER_VOLUME, (85 | 85 << 8));
493 493
494#if defined(CONFIG_SOUND_SOFTOSS) || defined(CONFIG_SOUND_SOFTOSS_MODULE)
495 softoss_dev = adev;
496#endif
497 return; 494 return;
498 495
499irq_failed: 496irq_failed:
diff --git a/sound/oss/vwsnd.c b/sound/oss/vwsnd.c
index 20b3b325aa8..643f1113b1d 100644
--- a/sound/oss/vwsnd.c
+++ b/sound/oss/vwsnd.c
@@ -145,7 +145,6 @@
145#include <linux/init.h> 145#include <linux/init.h>
146 146
147#include <linux/spinlock.h> 147#include <linux/spinlock.h>
148#include <linux/smp_lock.h>
149#include <linux/wait.h> 148#include <linux/wait.h>
150#include <linux/interrupt.h> 149#include <linux/interrupt.h>
151#include <linux/mutex.h> 150#include <linux/mutex.h>
@@ -160,6 +159,7 @@
160 159
161#ifdef VWSND_DEBUG 160#ifdef VWSND_DEBUG
162 161
162static DEFINE_MUTEX(vwsnd_mutex);
163static int shut_up = 1; 163static int shut_up = 1;
164 164
165/* 165/*
@@ -2429,8 +2429,7 @@ static unsigned int vwsnd_audio_poll(struct file *file,
2429 return mask; 2429 return mask;
2430} 2430}
2431 2431
2432static int vwsnd_audio_do_ioctl(struct inode *inode, 2432static int vwsnd_audio_do_ioctl(struct file *file,
2433 struct file *file,
2434 unsigned int cmd, 2433 unsigned int cmd,
2435 unsigned long arg) 2434 unsigned long arg)
2436{ 2435{
@@ -2446,8 +2445,8 @@ static int vwsnd_audio_do_ioctl(struct inode *inode,
2446 int ival; 2445 int ival;
2447 2446
2448 2447
2449 DBGEV("(inode=0x%p, file=0x%p, cmd=0x%x, arg=0x%lx)\n", 2448 DBGEV("(file=0x%p, cmd=0x%x, arg=0x%lx)\n",
2450 inode, file, cmd, arg); 2449 file, cmd, arg);
2451 switch (cmd) { 2450 switch (cmd) {
2452 case OSS_GETVERSION: /* _SIOR ('M', 118, int) */ 2451 case OSS_GETVERSION: /* _SIOR ('M', 118, int) */
2453 DBGX("OSS_GETVERSION\n"); 2452 DBGX("OSS_GETVERSION\n");
@@ -2885,17 +2884,19 @@ static int vwsnd_audio_do_ioctl(struct inode *inode,
2885 return -EINVAL; 2884 return -EINVAL;
2886} 2885}
2887 2886
2888static int vwsnd_audio_ioctl(struct inode *inode, 2887static long vwsnd_audio_ioctl(struct file *file,
2889 struct file *file,
2890 unsigned int cmd, 2888 unsigned int cmd,
2891 unsigned long arg) 2889 unsigned long arg)
2892{ 2890{
2893 vwsnd_dev_t *devc = (vwsnd_dev_t *) file->private_data; 2891 vwsnd_dev_t *devc = (vwsnd_dev_t *) file->private_data;
2894 int ret; 2892 int ret;
2895 2893
2894 mutex_lock(&vwsnd_mutex);
2896 mutex_lock(&devc->io_mutex); 2895 mutex_lock(&devc->io_mutex);
2897 ret = vwsnd_audio_do_ioctl(inode, file, cmd, arg); 2896 ret = vwsnd_audio_do_ioctl(file, cmd, arg);
2898 mutex_unlock(&devc->io_mutex); 2897 mutex_unlock(&devc->io_mutex);
2898 mutex_unlock(&vwsnd_mutex);
2899
2899 return ret; 2900 return ret;
2900} 2901}
2901 2902
@@ -2921,6 +2922,7 @@ static int vwsnd_audio_open(struct inode *inode, struct file *file)
2921 2922
2922 DBGE("(inode=0x%p, file=0x%p)\n", inode, file); 2923 DBGE("(inode=0x%p, file=0x%p)\n", inode, file);
2923 2924
2925 mutex_lock(&vwsnd_mutex);
2924 INC_USE_COUNT; 2926 INC_USE_COUNT;
2925 for (devc = vwsnd_dev_list; devc; devc = devc->next_dev) 2927 for (devc = vwsnd_dev_list; devc; devc = devc->next_dev)
2926 if ((devc->audio_minor & ~0x0F) == (minor & ~0x0F)) 2928 if ((devc->audio_minor & ~0x0F) == (minor & ~0x0F))
@@ -2928,6 +2930,7 @@ static int vwsnd_audio_open(struct inode *inode, struct file *file)
2928 2930
2929 if (devc == NULL) { 2931 if (devc == NULL) {
2930 DEC_USE_COUNT; 2932 DEC_USE_COUNT;
2933 mutex_unlock(&vwsnd_mutex);
2931 return -ENODEV; 2934 return -ENODEV;
2932 } 2935 }
2933 2936
@@ -2936,11 +2939,13 @@ static int vwsnd_audio_open(struct inode *inode, struct file *file)
2936 mutex_unlock(&devc->open_mutex); 2939 mutex_unlock(&devc->open_mutex);
2937 if (file->f_flags & O_NONBLOCK) { 2940 if (file->f_flags & O_NONBLOCK) {
2938 DEC_USE_COUNT; 2941 DEC_USE_COUNT;
2942 mutex_unlock(&vwsnd_mutex);
2939 return -EBUSY; 2943 return -EBUSY;
2940 } 2944 }
2941 interruptible_sleep_on(&devc->open_wait); 2945 interruptible_sleep_on(&devc->open_wait);
2942 if (signal_pending(current)) { 2946 if (signal_pending(current)) {
2943 DEC_USE_COUNT; 2947 DEC_USE_COUNT;
2948 mutex_unlock(&vwsnd_mutex);
2944 return -ERESTARTSYS; 2949 return -ERESTARTSYS;
2945 } 2950 }
2946 mutex_lock(&devc->open_mutex); 2951 mutex_lock(&devc->open_mutex);
@@ -2993,6 +2998,7 @@ static int vwsnd_audio_open(struct inode *inode, struct file *file)
2993 2998
2994 file->private_data = devc; 2999 file->private_data = devc;
2995 DBGRV(); 3000 DBGRV();
3001 mutex_unlock(&vwsnd_mutex);
2996 return 0; 3002 return 0;
2997} 3003}
2998 3004
@@ -3006,7 +3012,7 @@ static int vwsnd_audio_release(struct inode *inode, struct file *file)
3006 vwsnd_port_t *wport = NULL, *rport = NULL; 3012 vwsnd_port_t *wport = NULL, *rport = NULL;
3007 int err = 0; 3013 int err = 0;
3008 3014
3009 lock_kernel(); 3015 mutex_lock(&vwsnd_mutex);
3010 mutex_lock(&devc->io_mutex); 3016 mutex_lock(&devc->io_mutex);
3011 { 3017 {
3012 DBGEV("(inode=0x%p, file=0x%p)\n", inode, file); 3018 DBGEV("(inode=0x%p, file=0x%p)\n", inode, file);
@@ -3034,7 +3040,7 @@ static int vwsnd_audio_release(struct inode *inode, struct file *file)
3034 wake_up(&devc->open_wait); 3040 wake_up(&devc->open_wait);
3035 DEC_USE_COUNT; 3041 DEC_USE_COUNT;
3036 DBGR(); 3042 DBGR();
3037 unlock_kernel(); 3043 mutex_unlock(&vwsnd_mutex);
3038 return err; 3044 return err;
3039} 3045}
3040 3046
@@ -3044,7 +3050,7 @@ static const struct file_operations vwsnd_audio_fops = {
3044 .read = vwsnd_audio_read, 3050 .read = vwsnd_audio_read,
3045 .write = vwsnd_audio_write, 3051 .write = vwsnd_audio_write,
3046 .poll = vwsnd_audio_poll, 3052 .poll = vwsnd_audio_poll,
3047 .ioctl = vwsnd_audio_ioctl, 3053 .unlocked_ioctl = vwsnd_audio_ioctl,
3048 .mmap = vwsnd_audio_mmap, 3054 .mmap = vwsnd_audio_mmap,
3049 .open = vwsnd_audio_open, 3055 .open = vwsnd_audio_open,
3050 .release = vwsnd_audio_release, 3056 .release = vwsnd_audio_release,
@@ -3062,15 +3068,18 @@ static int vwsnd_mixer_open(struct inode *inode, struct file *file)
3062 DBGEV("(inode=0x%p, file=0x%p)\n", inode, file); 3068 DBGEV("(inode=0x%p, file=0x%p)\n", inode, file);
3063 3069
3064 INC_USE_COUNT; 3070 INC_USE_COUNT;
3071 mutex_lock(&vwsnd_mutex);
3065 for (devc = vwsnd_dev_list; devc; devc = devc->next_dev) 3072 for (devc = vwsnd_dev_list; devc; devc = devc->next_dev)
3066 if (devc->mixer_minor == iminor(inode)) 3073 if (devc->mixer_minor == iminor(inode))
3067 break; 3074 break;
3068 3075
3069 if (devc == NULL) { 3076 if (devc == NULL) {
3070 DEC_USE_COUNT; 3077 DEC_USE_COUNT;
3078 mutex_unlock(&vwsnd_mutex);
3071 return -ENODEV; 3079 return -ENODEV;
3072 } 3080 }
3073 file->private_data = devc; 3081 file->private_data = devc;
3082 mutex_unlock(&vwsnd_mutex);
3074 return 0; 3083 return 0;
3075} 3084}
3076 3085
@@ -3203,8 +3212,7 @@ static int mixer_write_ioctl(vwsnd_dev_t *devc, unsigned int nr, void __user *ar
3203 3212
3204/* This is the ioctl entry to the mixer driver. */ 3213/* This is the ioctl entry to the mixer driver. */
3205 3214
3206static int vwsnd_mixer_ioctl(struct inode *ioctl, 3215static long vwsnd_mixer_ioctl(struct file *file,
3207 struct file *file,
3208 unsigned int cmd, 3216 unsigned int cmd,
3209 unsigned long arg) 3217 unsigned long arg)
3210{ 3218{
@@ -3215,6 +3223,7 @@ static int vwsnd_mixer_ioctl(struct inode *ioctl,
3215 3223
3216 DBGEV("(devc=0x%p, cmd=0x%x, arg=0x%lx)\n", devc, cmd, arg); 3224 DBGEV("(devc=0x%p, cmd=0x%x, arg=0x%lx)\n", devc, cmd, arg);
3217 3225
3226 mutex_lock(&vwsnd_mutex);
3218 mutex_lock(&devc->mix_mutex); 3227 mutex_lock(&devc->mix_mutex);
3219 { 3228 {
3220 if ((cmd & ~nrmask) == MIXER_READ(0)) 3229 if ((cmd & ~nrmask) == MIXER_READ(0))
@@ -3225,13 +3234,14 @@ static int vwsnd_mixer_ioctl(struct inode *ioctl,
3225 retval = -EINVAL; 3234 retval = -EINVAL;
3226 } 3235 }
3227 mutex_unlock(&devc->mix_mutex); 3236 mutex_unlock(&devc->mix_mutex);
3237 mutex_unlock(&vwsnd_mutex);
3228 return retval; 3238 return retval;
3229} 3239}
3230 3240
3231static const struct file_operations vwsnd_mixer_fops = { 3241static const struct file_operations vwsnd_mixer_fops = {
3232 .owner = THIS_MODULE, 3242 .owner = THIS_MODULE,
3233 .llseek = no_llseek, 3243 .llseek = no_llseek,
3234 .ioctl = vwsnd_mixer_ioctl, 3244 .unlocked_ioctl = vwsnd_mixer_ioctl,
3235 .open = vwsnd_mixer_open, 3245 .open = vwsnd_mixer_open,
3236 .release = vwsnd_mixer_release, 3246 .release = vwsnd_mixer_release,
3237}; 3247};
diff --git a/sound/oss/waveartist.c b/sound/oss/waveartist.c
index e688dde6bbd..52468742d9f 100644
--- a/sound/oss/waveartist.c
+++ b/sound/oss/waveartist.c
@@ -184,14 +184,8 @@ waveartist_iack(wavnc_info *devc)
184static inline int 184static inline int
185waveartist_sleep(int timeout_ms) 185waveartist_sleep(int timeout_ms)
186{ 186{
187 unsigned int timeout = timeout_ms * 10 * HZ / 100; 187 unsigned int timeout = msecs_to_jiffies(timeout_ms*100);
188 188 return schedule_timeout_interruptible(timeout);
189 do {
190 set_current_state(TASK_INTERRUPTIBLE);
191 timeout = schedule_timeout(timeout);
192 } while (timeout);
193
194 return 0;
195} 189}
196 190
197static int 191static int
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index e7a8cd058ef..12e34653b8a 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -207,12 +207,12 @@ config SND_CMIPCI
207 207
208config SND_OXYGEN_LIB 208config SND_OXYGEN_LIB
209 tristate 209 tristate
210 select SND_PCM
211 select SND_MPU401_UART
212 210
213config SND_OXYGEN 211config SND_OXYGEN
214 tristate "C-Media 8788 (Oxygen)" 212 tristate "C-Media 8788 (Oxygen)"
215 select SND_OXYGEN_LIB 213 select SND_OXYGEN_LIB
214 select SND_PCM
215 select SND_MPU401_UART
216 help 216 help
217 Say Y here to include support for sound cards based on the 217 Say Y here to include support for sound cards based on the
218 C-Media CMI8788 (Oxygen HD Audio) chip: 218 C-Media CMI8788 (Oxygen HD Audio) chip:
@@ -581,6 +581,8 @@ config SND_HDSPM
581config SND_HIFIER 581config SND_HIFIER
582 tristate "TempoTec HiFier Fantasia" 582 tristate "TempoTec HiFier Fantasia"
583 select SND_OXYGEN_LIB 583 select SND_OXYGEN_LIB
584 select SND_PCM
585 select SND_MPU401_UART
584 help 586 help
585 Say Y here to include support for the MediaTek/TempoTec HiFier 587 Say Y here to include support for the MediaTek/TempoTec HiFier
586 Fantasia sound card. 588 Fantasia sound card.
@@ -815,14 +817,17 @@ config SND_VIA82XX_MODEM
815 will be called snd-via82xx-modem. 817 will be called snd-via82xx-modem.
816 818
817config SND_VIRTUOSO 819config SND_VIRTUOSO
818 tristate "Asus Virtuoso 100/200 (Xonar)" 820 tristate "Asus Virtuoso 66/100/200 (Xonar)"
819 select SND_OXYGEN_LIB 821 select SND_OXYGEN_LIB
822 select SND_PCM
823 select SND_MPU401_UART
824 select SND_JACK if INPUT=y || INPUT=SND
820 help 825 help
821 Say Y here to include support for sound cards based on the 826 Say Y here to include support for sound cards based on the
822 Asus AV100/AV200 chips, i.e., Xonar D1, DX, D2, D2X, 827 Asus AV66/AV100/AV200 chips, i.e., Xonar D1, DX, D2, D2X, DS,
823 Essence ST (Deluxe), and Essence STX. 828 Essence ST (Deluxe), and Essence STX.
824 Support for the DS is experimental. 829 Support for the HDAV1.3 (Deluxe) is incomplete; for the
825 Support for the HDAV1.3 (Deluxe) is very experimental. 830 HDAV1.3 Slim and Xense, missing.
826 831
827 To compile this driver as a module, choose M here: the module 832 To compile this driver as a module, choose M here: the module
828 will be called snd-virtuoso. 833 will be called snd-virtuoso.
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c
index 6cf1de8042e..0e247cb90ec 100644
--- a/sound/pci/als4000.c
+++ b/sound/pci/als4000.c
@@ -763,9 +763,9 @@ static void snd_als4000_configure(struct snd_sb *chip)
763 /* SPECS_PAGE: 39 */ 763 /* SPECS_PAGE: 39 */
764 for (i = ALS4K_GCR91_DMA0_ADDR; i <= ALS4K_GCR96_DMA3_MODE_COUNT; ++i) 764 for (i = ALS4K_GCR91_DMA0_ADDR; i <= ALS4K_GCR96_DMA3_MODE_COUNT; ++i)
765 snd_als4k_gcr_write(chip, i, 0); 765 snd_als4k_gcr_write(chip, i, 0);
766 766 /* enable burst mode to prevent dropouts during high PCI bus usage */
767 snd_als4k_gcr_write(chip, ALS4K_GCR99_DMA_EMULATION_CTRL, 767 snd_als4k_gcr_write(chip, ALS4K_GCR99_DMA_EMULATION_CTRL,
768 snd_als4k_gcr_read(chip, ALS4K_GCR99_DMA_EMULATION_CTRL)); 768 (snd_als4k_gcr_read(chip, ALS4K_GCR99_DMA_EMULATION_CTRL) & ~0x07) | 0x04);
769 spin_unlock_irq(&chip->reg_lock); 769 spin_unlock_irq(&chip->reg_lock);
770} 770}
771 771
diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c
index 1db586af4f9..c80b0b863c5 100644
--- a/sound/pci/asihpi/asihpi.c
+++ b/sound/pci/asihpi/asihpi.c
@@ -460,6 +460,7 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream,
460 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream); 460 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
461 int err; 461 int err;
462 u16 format; 462 u16 format;
463 int width;
463 unsigned int bytes_per_sec; 464 unsigned int bytes_per_sec;
464 465
465 print_hwparams(params); 466 print_hwparams(params);
@@ -512,9 +513,10 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream,
512 dpcm->hpi_buffer_attached); 513 dpcm->hpi_buffer_attached);
513 } 514 }
514 bytes_per_sec = params_rate(params) * params_channels(params); 515 bytes_per_sec = params_rate(params) * params_channels(params);
515 bytes_per_sec *= snd_pcm_format_width(params_format(params)); 516 width = snd_pcm_format_width(params_format(params));
517 bytes_per_sec *= width;
516 bytes_per_sec /= 8; 518 bytes_per_sec /= 8;
517 if (bytes_per_sec <= 0) 519 if (width < 0 || bytes_per_sec == 0)
518 return -EINVAL; 520 return -EINVAL;
519 521
520 dpcm->bytes_per_sec = bytes_per_sec; 522 dpcm->bytes_per_sec = bytes_per_sec;
@@ -1383,7 +1385,7 @@ static char *asihpi_src_names[] =
1383 1385
1384compile_time_assert( 1386compile_time_assert(
1385 (ARRAY_SIZE(asihpi_src_names) == 1387 (ARRAY_SIZE(asihpi_src_names) ==
1386 (HPI_SOURCENODE_LAST_INDEX-HPI_SOURCENODE_BASE+1)), 1388 (HPI_SOURCENODE_LAST_INDEX-HPI_SOURCENODE_NONE+1)),
1387 assert_src_names_size); 1389 assert_src_names_size);
1388 1390
1389#if ASI_STYLE_NAMES 1391#if ASI_STYLE_NAMES
@@ -1414,7 +1416,7 @@ static char *asihpi_dst_names[] =
1414 1416
1415compile_time_assert( 1417compile_time_assert(
1416 (ARRAY_SIZE(asihpi_dst_names) == 1418 (ARRAY_SIZE(asihpi_dst_names) ==
1417 (HPI_DESTNODE_LAST_INDEX-HPI_DESTNODE_BASE+1)), 1419 (HPI_DESTNODE_LAST_INDEX-HPI_DESTNODE_NONE+1)),
1418 assert_dst_names_size); 1420 assert_dst_names_size);
1419 1421
1420static inline int ctl_add(struct snd_card *card, struct snd_kcontrol_new *ctl, 1422static inline int ctl_add(struct snd_card *card, struct snd_kcontrol_new *ctl,
@@ -2171,7 +2173,7 @@ static int snd_asihpi_mux_info(struct snd_kcontrol *kcontrol,
2171 &src_node_type, &src_node_index); 2173 &src_node_type, &src_node_index);
2172 2174
2173 sprintf(uinfo->value.enumerated.name, "%s %d", 2175 sprintf(uinfo->value.enumerated.name, "%s %d",
2174 asihpi_src_names[src_node_type - HPI_SOURCENODE_BASE], 2176 asihpi_src_names[src_node_type - HPI_SOURCENODE_NONE],
2175 src_node_index); 2177 src_node_index);
2176 return 0; 2178 return 0;
2177} 2179}
@@ -2603,8 +2605,8 @@ static int __devinit snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi)
2603 2605
2604 } 2606 }
2605 2607
2606 hpi_ctl.src_node_type -= HPI_SOURCENODE_BASE; 2608 hpi_ctl.src_node_type -= HPI_SOURCENODE_NONE;
2607 hpi_ctl.dst_node_type -= HPI_DESTNODE_BASE; 2609 hpi_ctl.dst_node_type -= HPI_DESTNODE_NONE;
2608 2610
2609 /* ASI50xx in SSX mode has multiple meters on the same node. 2611 /* ASI50xx in SSX mode has multiple meters on the same node.
2610 Use subindex to create distinct ALSA controls 2612 Use subindex to create distinct ALSA controls
diff --git a/sound/pci/asihpi/hpi.h b/sound/pci/asihpi/hpi.h
index 0173bbe62b6..23399d02f66 100644
--- a/sound/pci/asihpi/hpi.h
+++ b/sound/pci/asihpi/hpi.h
@@ -50,7 +50,8 @@ i.e 3.05.02 is a development version
50#define HPI_VER_RELEASE(v) ((int)(v & 0xFF)) 50#define HPI_VER_RELEASE(v) ((int)(v & 0xFF))
51 51
52/* Use single digits for versions less that 10 to avoid octal. */ 52/* Use single digits for versions less that 10 to avoid octal. */
53#define HPI_VER HPI_VERSION_CONSTRUCTOR(4L, 3, 25) 53#define HPI_VER HPI_VERSION_CONSTRUCTOR(4L, 4, 1)
54#define HPI_VER_STRING "4.04.01"
54 55
55/* Library version as documented in hpi-api-versions.txt */ 56/* Library version as documented in hpi-api-versions.txt */
56#define HPI_LIB_VER HPI_VERSION_CONSTRUCTOR(9, 0, 0) 57#define HPI_LIB_VER HPI_VERSION_CONSTRUCTOR(9, 0, 0)
@@ -203,8 +204,6 @@ enum HPI_SOURCENODES {
203 exists on a destination node can be searched for using a source 204 exists on a destination node can be searched for using a source
204 node value of either 0, or HPI_SOURCENODE_NONE */ 205 node value of either 0, or HPI_SOURCENODE_NONE */
205 HPI_SOURCENODE_NONE = 100, 206 HPI_SOURCENODE_NONE = 100,
206 /** \deprecated Use HPI_SOURCENODE_NONE instead. */
207 HPI_SOURCENODE_BASE = 100,
208 /** Out Stream (Play) node. */ 207 /** Out Stream (Play) node. */
209 HPI_SOURCENODE_OSTREAM = 101, 208 HPI_SOURCENODE_OSTREAM = 101,
210 /** Line in node - could be analog, AES/EBU or network. */ 209 /** Line in node - could be analog, AES/EBU or network. */
@@ -235,8 +234,6 @@ enum HPI_DESTNODES {
235 exists on a source node can be searched for using a destination 234 exists on a source node can be searched for using a destination
236 node value of either 0, or HPI_DESTNODE_NONE */ 235 node value of either 0, or HPI_DESTNODE_NONE */
237 HPI_DESTNODE_NONE = 200, 236 HPI_DESTNODE_NONE = 200,
238 /** \deprecated Use HPI_DESTNODE_NONE instead. */
239 HPI_DESTNODE_BASE = 200,
240 /** In Stream (Record) node. */ 237 /** In Stream (Record) node. */
241 HPI_DESTNODE_ISTREAM = 201, 238 HPI_DESTNODE_ISTREAM = 201,
242 HPI_DESTNODE_LINEOUT = 202, /**< line out node. */ 239 HPI_DESTNODE_LINEOUT = 202, /**< line out node. */
@@ -432,7 +429,18 @@ Property 2 - adapter can do stream grouping (supports SSX2)
432Property 1 - adapter can do samplerate conversion (MRX) 429Property 1 - adapter can do samplerate conversion (MRX)
433Property 2 - adapter can do timestretch (TSX) 430Property 2 - adapter can do timestretch (TSX)
434*/ 431*/
435 HPI_ADAPTER_PROPERTY_CAPS2 = 269 432 HPI_ADAPTER_PROPERTY_CAPS2 = 269,
433
434/** Readonly adapter sync header connection count.
435*/
436 HPI_ADAPTER_PROPERTY_SYNC_HEADER_CONNECTIONS = 270,
437/** Readonly supports SSX2 property.
438Indicates the adapter supports SSX2 in some mode setting. The
439return value is true (1) or false (0). If the current adapter
440mode is MONO SSX2 is disabled, even though this property will
441return true.
442*/
443 HPI_ADAPTER_PROPERTY_SUPPORTS_SSX2 = 271
436}; 444};
437 445
438/** Adapter mode commands 446/** Adapter mode commands
@@ -813,8 +821,6 @@ enum HPI_SAMPLECLOCK_SOURCES {
813/** The sampleclock output is derived from its local samplerate generator. 821/** The sampleclock output is derived from its local samplerate generator.
814 The local samplerate may be set using HPI_SampleClock_SetLocalRate(). */ 822 The local samplerate may be set using HPI_SampleClock_SetLocalRate(). */
815 HPI_SAMPLECLOCK_SOURCE_LOCAL = 1, 823 HPI_SAMPLECLOCK_SOURCE_LOCAL = 1,
816/** \deprecated Use HPI_SAMPLECLOCK_SOURCE_LOCAL instead */
817 HPI_SAMPLECLOCK_SOURCE_ADAPTER = 1,
818/** The adapter is clocked from a dedicated AES/EBU SampleClock input.*/ 824/** The adapter is clocked from a dedicated AES/EBU SampleClock input.*/
819 HPI_SAMPLECLOCK_SOURCE_AESEBU_SYNC = 2, 825 HPI_SAMPLECLOCK_SOURCE_AESEBU_SYNC = 2,
820/** From external wordclock connector */ 826/** From external wordclock connector */
@@ -825,10 +831,6 @@ enum HPI_SAMPLECLOCK_SOURCES {
825 HPI_SAMPLECLOCK_SOURCE_SMPTE = 5, 831 HPI_SAMPLECLOCK_SOURCE_SMPTE = 5,
826/** One of the aesebu inputs */ 832/** One of the aesebu inputs */
827 HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT = 6, 833 HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT = 6,
828/** \deprecated The first aesebu input with a valid signal
829Superseded by separate Auto enable flag
830*/
831 HPI_SAMPLECLOCK_SOURCE_AESEBU_AUTO = 7,
832/** From a network interface e.g. Cobranet or Livewire at either 48 or 96kHz */ 834/** From a network interface e.g. Cobranet or Livewire at either 48 or 96kHz */
833 HPI_SAMPLECLOCK_SOURCE_NETWORK = 8, 835 HPI_SAMPLECLOCK_SOURCE_NETWORK = 8,
834/** From previous adjacent module (ASI2416 only)*/ 836/** From previous adjacent module (ASI2416 only)*/
@@ -1015,8 +1017,6 @@ enum HPI_ERROR_CODES {
1015 HPI_ERROR_CONTROL_DISABLED = 404, 1017 HPI_ERROR_CONTROL_DISABLED = 404,
1016 /** I2C transaction failed due to a missing ACK. */ 1018 /** I2C transaction failed due to a missing ACK. */
1017 HPI_ERROR_CONTROL_I2C_MISSING_ACK = 405, 1019 HPI_ERROR_CONTROL_I2C_MISSING_ACK = 405,
1018 /** Control attribute is valid, but not supported by this hardware. */
1019 HPI_ERROR_UNSUPPORTED_CONTROL_ATTRIBUTE = 406,
1020 /** Control is busy, or coming out of 1020 /** Control is busy, or coming out of
1021 reset and cannot be accessed at this time. */ 1021 reset and cannot be accessed at this time. */
1022 HPI_ERROR_CONTROL_NOT_READY = 407, 1022 HPI_ERROR_CONTROL_NOT_READY = 407,
@@ -1827,13 +1827,41 @@ u16 hpi_parametricEQ__get_coeffs(const struct hpi_hsubsys *ph_subsys,
1827 Compressor Expander control 1827 Compressor Expander control
1828*******************************/ 1828*******************************/
1829 1829
1830u16 hpi_compander_set(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1830u16 hpi_compander_set_enable(const struct hpi_hsubsys *ph_subsys,
1831 u16 attack, u16 decay, short ratio100, short threshold0_01dB, 1831 u32 h_control, u32 on);
1832 short makeup_gain0_01dB); 1832
1833u16 hpi_compander_get_enable(const struct hpi_hsubsys *ph_subsys,
1834 u32 h_control, u32 *pon);
1835
1836u16 hpi_compander_set_makeup_gain(const struct hpi_hsubsys *ph_subsys,
1837 u32 h_control, short makeup_gain0_01dB);
1838
1839u16 hpi_compander_get_makeup_gain(const struct hpi_hsubsys *ph_subsys,
1840 u32 h_control, short *pn_makeup_gain0_01dB);
1841
1842u16 hpi_compander_set_attack_time_constant(const struct hpi_hsubsys
1843 *ph_subsys, u32 h_control, u32 index, u32 attack);
1844
1845u16 hpi_compander_get_attack_time_constant(const struct hpi_hsubsys
1846 *ph_subsys, u32 h_control, u32 index, u32 *pw_attack);
1847
1848u16 hpi_compander_set_decay_time_constant(const struct hpi_hsubsys *ph_subsys,
1849 u32 h_control, u32 index, u32 decay);
1850
1851u16 hpi_compander_get_decay_time_constant(const struct hpi_hsubsys *ph_subsys,
1852 u32 h_control, u32 index, u32 *pw_decay);
1853
1854u16 hpi_compander_set_threshold(const struct hpi_hsubsys *ph_subsys,
1855 u32 h_control, u32 index, short threshold0_01dB);
1856
1857u16 hpi_compander_get_threshold(const struct hpi_hsubsys *ph_subsys,
1858 u32 h_control, u32 index, short *pn_threshold0_01dB);
1859
1860u16 hpi_compander_set_ratio(const struct hpi_hsubsys *ph_subsys,
1861 u32 h_control, u32 index, u32 ratio100);
1833 1862
1834u16 hpi_compander_get(const struct hpi_hsubsys *ph_subsys, u32 h_control, 1863u16 hpi_compander_get_ratio(const struct hpi_hsubsys *ph_subsys,
1835 u16 *pw_attack, u16 *pw_decay, short *pw_ratio100, 1864 u32 h_control, u32 index, u32 *pw_ratio100);
1836 short *pn_threshold0_01dB, short *pn_makeup_gain0_01dB);
1837 1865
1838/******************************* 1866/*******************************
1839 Cobranet HMI control 1867 Cobranet HMI control
diff --git a/sound/pci/asihpi/hpi6000.c b/sound/pci/asihpi/hpi6000.c
index 12dab5e4892..f7e374ec441 100644
--- a/sound/pci/asihpi/hpi6000.c
+++ b/sound/pci/asihpi/hpi6000.c
@@ -687,6 +687,7 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
687 switch (pao->pci.subsys_device_id) { 687 switch (pao->pci.subsys_device_id) {
688 case 0x5100: 688 case 0x5100:
689 case 0x5110: /* ASI5100 revB or higher with C6711D */ 689 case 0x5110: /* ASI5100 revB or higher with C6711D */
690 case 0x5200: /* ASI5200 PC_ie version of ASI5100 */
690 case 0x6100: 691 case 0x6100:
691 case 0x6200: 692 case 0x6200:
692 boot_load_family = HPI_ADAPTER_FAMILY_ASI(0x6200); 693 boot_load_family = HPI_ADAPTER_FAMILY_ASI(0x6200);
@@ -1133,6 +1134,12 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
1133 subsys_device_id) == 1134 subsys_device_id) ==
1134 HPI_ADAPTER_FAMILY_ASI(0x5100)) 1135 HPI_ADAPTER_FAMILY_ASI(0x5100))
1135 mask = 0x00000000L; 1136 mask = 0x00000000L;
1137 /* ASI5200 uses AX6 code, */
1138 /* but has no PLD r/w register to test */
1139 if (HPI_ADAPTER_FAMILY_ASI(pao->pci.
1140 subsys_device_id) ==
1141 HPI_ADAPTER_FAMILY_ASI(0x5200))
1142 mask = 0x00000000L;
1136 break; 1143 break;
1137 case HPI_ADAPTER_FAMILY_ASI(0x8800): 1144 case HPI_ADAPTER_FAMILY_ASI(0x8800):
1138 /* ASI8800 has 16bit path to FPGA */ 1145 /* ASI8800 has 16bit path to FPGA */
diff --git a/sound/pci/asihpi/hpi6205.c b/sound/pci/asihpi/hpi6205.c
index 3b441344822..22c5fc62553 100644
--- a/sound/pci/asihpi/hpi6205.c
+++ b/sound/pci/asihpi/hpi6205.c
@@ -941,8 +941,7 @@ static void outstream_host_buffer_free(struct hpi_adapter_obj *pao,
941 941
942} 942}
943 943
944static u32 outstream_get_space_available(struct hpi_hostbuffer_status 944static u32 outstream_get_space_available(struct hpi_hostbuffer_status *status)
945 *status)
946{ 945{
947 return status->size_in_bytes - (status->host_index - 946 return status->size_in_bytes - (status->host_index -
948 status->dSP_index); 947 status->dSP_index);
@@ -987,6 +986,10 @@ static void outstream_write(struct hpi_adapter_obj *pao,
987 /* write it */ 986 /* write it */
988 phm->function = HPI_OSTREAM_WRITE; 987 phm->function = HPI_OSTREAM_WRITE;
989 hw_message(pao, phm, phr); 988 hw_message(pao, phm, phr);
989
990 if (phr->error)
991 return;
992
990 /* update status information that the DSP would typically 993 /* update status information that the DSP would typically
991 * update (and will update next time the DSP 994 * update (and will update next time the DSP
992 * buffer update task reads data from the host BBM buffer) 995 * buffer update task reads data from the host BBM buffer)
diff --git a/sound/pci/asihpi/hpi_internal.h b/sound/pci/asihpi/hpi_internal.h
index fdd0ce02aa6..16f502d459d 100644
--- a/sound/pci/asihpi/hpi_internal.h
+++ b/sound/pci/asihpi/hpi_internal.h
@@ -104,9 +104,9 @@ typedef void hpi_handler_func(struct hpi_message *, struct hpi_response *);
104#define STR_ROLE_FIELD_MAX 255U 104#define STR_ROLE_FIELD_MAX 255U
105 105
106struct hpi_entity_str { 106struct hpi_entity_str {
107 uint16_t size; 107 u16 size;
108 uint8_t type; 108 u8 type;
109 uint8_t role; 109 u8 role;
110}; 110};
111 111
112#if defined(_MSC_VER) 112#if defined(_MSC_VER)
@@ -119,11 +119,11 @@ struct hpi_entity {
119#if ! defined(HPI_OS_DSP_C6000) || (defined(HPI_OS_DSP_C6000) && (__TI_COMPILER_VERSION__ > 6000008)) 119#if ! defined(HPI_OS_DSP_C6000) || (defined(HPI_OS_DSP_C6000) && (__TI_COMPILER_VERSION__ > 6000008))
120 /* DSP C6000 compiler v6.0.8 and lower 120 /* DSP C6000 compiler v6.0.8 and lower
121 do not support flexible array member */ 121 do not support flexible array member */
122 uint8_t value[]; 122 u8 value[];
123#else 123#else
124 /* NOTE! Using sizeof(struct hpi_entity) will give erroneous results */ 124 /* NOTE! Using sizeof(struct hpi_entity) will give erroneous results */
125#define HPI_INTERNAL_WARN_ABOUT_ENTITY_VALUE 125#define HPI_INTERNAL_WARN_ABOUT_ENTITY_VALUE
126 uint8_t value[1]; 126 u8 value[1];
127#endif 127#endif
128}; 128};
129 129
@@ -142,12 +142,15 @@ enum HPI_BUSES {
142/******************************************* CONTROL ATTRIBUTES ****/ 142/******************************************* CONTROL ATTRIBUTES ****/
143/* (in order of control type ID */ 143/* (in order of control type ID */
144 144
145 /* This allows for 255 control types, 256 unique attributes each */ 145/* This allows for 255 control types, 256 unique attributes each */
146#define HPI_CTL_ATTR(ctl, ai) (HPI_CONTROL_##ctl * 0x100 + ai) 146#define HPI_CTL_ATTR(ctl, ai) (HPI_CONTROL_##ctl * 0x100 + ai)
147 147
148/* Get the sub-index of the attribute for a control type */ 148/* Get the sub-index of the attribute for a control type */
149#define HPI_CTL_ATTR_INDEX(i) (i&0xff) 149#define HPI_CTL_ATTR_INDEX(i) (i&0xff)
150 150
151/* Extract the control from the control attribute */
152#define HPI_CTL_ATTR_CONTROL(i) (i>>8)
153
151/* Generic control attributes. */ 154/* Generic control attributes. */
152 155
153/** Enable a control. 156/** Enable a control.
@@ -311,8 +314,7 @@ Used for HPI_ChannelModeSet/Get()
311/* Microphone control attributes */ 314/* Microphone control attributes */
312#define HPI_MICROPHONE_PHANTOM_POWER HPI_CTL_ATTR(MICROPHONE, 1) 315#define HPI_MICROPHONE_PHANTOM_POWER HPI_CTL_ATTR(MICROPHONE, 1)
313 316
314/** Equalizer control attributes 317/** Equalizer control attributes */
315*/
316/** Used to get number of filters in an EQ. (Can't set) */ 318/** Used to get number of filters in an EQ. (Can't set) */
317#define HPI_EQUALIZER_NUM_FILTERS HPI_CTL_ATTR(EQUALIZER, 1) 319#define HPI_EQUALIZER_NUM_FILTERS HPI_CTL_ATTR(EQUALIZER, 1)
318/** Set/get the filter by type, freq, Q, gain */ 320/** Set/get the filter by type, freq, Q, gain */
@@ -320,13 +322,15 @@ Used for HPI_ChannelModeSet/Get()
320/** Get the biquad coefficients */ 322/** Get the biquad coefficients */
321#define HPI_EQUALIZER_COEFFICIENTS HPI_CTL_ATTR(EQUALIZER, 3) 323#define HPI_EQUALIZER_COEFFICIENTS HPI_CTL_ATTR(EQUALIZER, 3)
322 324
323#define HPI_COMPANDER_PARAMS HPI_CTL_ATTR(COMPANDER, 1) 325/* Note compander also uses HPI_GENERIC_ENABLE */
326#define HPI_COMPANDER_PARAMS HPI_CTL_ATTR(COMPANDER, 1)
327#define HPI_COMPANDER_MAKEUPGAIN HPI_CTL_ATTR(COMPANDER, 2)
328#define HPI_COMPANDER_THRESHOLD HPI_CTL_ATTR(COMPANDER, 3)
329#define HPI_COMPANDER_RATIO HPI_CTL_ATTR(COMPANDER, 4)
330#define HPI_COMPANDER_ATTACK HPI_CTL_ATTR(COMPANDER, 5)
331#define HPI_COMPANDER_DECAY HPI_CTL_ATTR(COMPANDER, 6)
324 332
325/* Cobranet control attributes. 333/* Cobranet control attributes. */
326 MUST be distinct from all other control attributes.
327 This is so that host side processing can easily identify a Cobranet control
328 and apply additional host side operations (like copying data) as required.
329*/
330#define HPI_COBRANET_SET HPI_CTL_ATTR(COBRANET, 1) 334#define HPI_COBRANET_SET HPI_CTL_ATTR(COBRANET, 1)
331#define HPI_COBRANET_GET HPI_CTL_ATTR(COBRANET, 2) 335#define HPI_COBRANET_GET HPI_CTL_ATTR(COBRANET, 2)
332#define HPI_COBRANET_SET_DATA HPI_CTL_ATTR(COBRANET, 3) 336#define HPI_COBRANET_SET_DATA HPI_CTL_ATTR(COBRANET, 3)
@@ -1512,11 +1516,11 @@ struct hpi_control_cache_single {
1512 struct hpi_control_cache_info i; 1516 struct hpi_control_cache_info i;
1513 union { 1517 union {
1514 struct { /* volume */ 1518 struct { /* volume */
1515 u16 an_log[2]; 1519 short an_log[2];
1516 } v; 1520 } v;
1517 struct { /* peak meter */ 1521 struct { /* peak meter */
1518 u16 an_log_peak[2]; 1522 short an_log_peak[2];
1519 u16 an_logRMS[2]; 1523 short an_logRMS[2];
1520 } p; 1524 } p;
1521 struct { /* channel mode */ 1525 struct { /* channel mode */
1522 u16 mode; 1526 u16 mode;
@@ -1526,7 +1530,7 @@ struct hpi_control_cache_single {
1526 u16 source_node_index; 1530 u16 source_node_index;
1527 } x; 1531 } x;
1528 struct { /* level/trim */ 1532 struct { /* level/trim */
1529 u16 an_log[2]; 1533 short an_log[2];
1530 } l; 1534 } l;
1531 struct { /* tuner - partial caching. 1535 struct { /* tuner - partial caching.
1532 some attributes go to the DSP. */ 1536 some attributes go to the DSP. */
diff --git a/sound/pci/asihpi/hpicmn.c b/sound/pci/asihpi/hpicmn.c
index fcd64539d9e..dda4f1c6f65 100644
--- a/sound/pci/asihpi/hpicmn.c
+++ b/sound/pci/asihpi/hpicmn.c
@@ -353,7 +353,12 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
353 phr->u.c.param1 = pC->u.t.band; 353 phr->u.c.param1 = pC->u.t.band;
354 else if ((phm->u.c.attribute == HPI_TUNER_LEVEL) 354 else if ((phm->u.c.attribute == HPI_TUNER_LEVEL)
355 && (phm->u.c.param1 == HPI_TUNER_LEVEL_AVERAGE)) 355 && (phm->u.c.param1 == HPI_TUNER_LEVEL_AVERAGE))
356 phr->u.c.param1 = pC->u.t.level; 356 if (pC->u.t.level == HPI_ERROR_ILLEGAL_CACHE_VALUE) {
357 phr->u.c.param1 = 0;
358 phr->error =
359 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
360 } else
361 phr->u.c.param1 = pC->u.t.level;
357 else 362 else
358 found = 0; 363 found = 0;
359 break; 364 break;
@@ -397,7 +402,8 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
397 if (pC->u.clk.source_index == 402 if (pC->u.clk.source_index ==
398 HPI_ERROR_ILLEGAL_CACHE_VALUE) { 403 HPI_ERROR_ILLEGAL_CACHE_VALUE) {
399 phr->u.c.param1 = 0; 404 phr->u.c.param1 = 0;
400 phr->error = HPI_ERROR_INVALID_OPERATION; 405 phr->error =
406 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
401 } else 407 } else
402 phr->u.c.param1 = pC->u.clk.source_index; 408 phr->u.c.param1 = pC->u.clk.source_index;
403 } else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SAMPLERATE) 409 } else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SAMPLERATE)
diff --git a/sound/pci/asihpi/hpidebug.c b/sound/pci/asihpi/hpidebug.c
index 4cd85a401b3..949836ec913 100644
--- a/sound/pci/asihpi/hpidebug.c
+++ b/sound/pci/asihpi/hpidebug.c
@@ -111,7 +111,7 @@ make_treenode_from_array(hpi_control_type_strings, HPI_CONTROL_TYPE_STRINGS)
111 &hpi_profile_strings,\ 111 &hpi_profile_strings,\
112 &hpi_control_strings, \ 112 &hpi_control_strings, \
113 &hpi_asyncevent_strings \ 113 &hpi_asyncevent_strings \
114}; 114}
115 make_treenode_from_array(hpi_function_strings, HPI_FUNCTION_STRINGS) 115 make_treenode_from_array(hpi_function_strings, HPI_FUNCTION_STRINGS)
116 116
117 compile_time_assert(HPI_OBJ_MAXINDEX == 14, obj_list_doesnt_match); 117 compile_time_assert(HPI_OBJ_MAXINDEX == 14, obj_list_doesnt_match);
diff --git a/sound/pci/asihpi/hpidebug.h b/sound/pci/asihpi/hpidebug.h
index 44dccadcc25..a2f0952a99f 100644
--- a/sound/pci/asihpi/hpidebug.h
+++ b/sound/pci/asihpi/hpidebug.h
@@ -356,7 +356,7 @@ compile_time_assert((HPI_CONTROL_LAST_INDEX + 1 == 27),
356 "HPI_SOURCENODE_ADAPTER" \ 356 "HPI_SOURCENODE_ADAPTER" \
357} 357}
358 358
359compile_time_assert((HPI_SOURCENODE_LAST_INDEX - HPI_SOURCENODE_BASE + 1) == 359compile_time_assert((HPI_SOURCENODE_LAST_INDEX - HPI_SOURCENODE_NONE + 1) ==
360 (12), sourcenode_strings_match_defs); 360 (12), sourcenode_strings_match_defs);
361 361
362#define HPI_DESTNODE_STRINGS \ 362#define HPI_DESTNODE_STRINGS \
@@ -370,7 +370,7 @@ compile_time_assert((HPI_SOURCENODE_LAST_INDEX - HPI_SOURCENODE_BASE + 1) ==
370 "HPI_DESTNODE_COBRANET", \ 370 "HPI_DESTNODE_COBRANET", \
371 "HPI_DESTNODE_ANALOG" \ 371 "HPI_DESTNODE_ANALOG" \
372} 372}
373compile_time_assert((HPI_DESTNODE_LAST_INDEX - HPI_DESTNODE_BASE + 1) == (8), 373compile_time_assert((HPI_DESTNODE_LAST_INDEX - HPI_DESTNODE_NONE + 1) == (8),
374 destnode_strings_match_defs); 374 destnode_strings_match_defs);
375 375
376#define HPI_CONTROL_CHANNEL_MODE_STRINGS \ 376#define HPI_CONTROL_CHANNEL_MODE_STRINGS \
diff --git a/sound/pci/asihpi/hpifunc.c b/sound/pci/asihpi/hpifunc.c
index 298eef3e20e..1e92eb6dd50 100644
--- a/sound/pci/asihpi/hpifunc.c
+++ b/sound/pci/asihpi/hpifunc.c
@@ -96,8 +96,7 @@ void hpi_stream_response_to_legacy(struct hpi_stream_res *pSR)
96 96
97static struct hpi_hsubsys gh_subsys; 97static struct hpi_hsubsys gh_subsys;
98 98
99struct hpi_hsubsys *hpi_subsys_create(void 99struct hpi_hsubsys *hpi_subsys_create(void)
100 )
101{ 100{
102 struct hpi_message hm; 101 struct hpi_message hm;
103 struct hpi_response hr; 102 struct hpi_response hr;
@@ -302,6 +301,7 @@ u16 hpi_adapter_set_mode_ex(const struct hpi_hsubsys *ph_subsys,
302{ 301{
303 struct hpi_message hm; 302 struct hpi_message hm;
304 struct hpi_response hr; 303 struct hpi_response hr;
304
305 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER, 305 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
306 HPI_ADAPTER_SET_MODE); 306 HPI_ADAPTER_SET_MODE);
307 hm.adapter_index = adapter_index; 307 hm.adapter_index = adapter_index;
@@ -510,7 +510,7 @@ u16 hpi_adapter_debug_read(const struct hpi_hsubsys *ph_subsys,
510 hm.adapter_index = adapter_index; 510 hm.adapter_index = adapter_index;
511 hm.u.ax.debug_read.dsp_address = dsp_address; 511 hm.u.ax.debug_read.dsp_address = dsp_address;
512 512
513 if (*count_bytes > sizeof(hr.u.bytes)) 513 if (*count_bytes > (int)sizeof(hr.u.bytes))
514 *count_bytes = sizeof(hr.u.bytes); 514 *count_bytes = sizeof(hr.u.bytes);
515 515
516 hm.u.ax.debug_read.count_bytes = *count_bytes; 516 hm.u.ax.debug_read.count_bytes = *count_bytes;
@@ -976,6 +976,7 @@ u16 hpi_outstream_ancillary_read(const struct hpi_hsubsys *ph_subsys,
976{ 976{
977 struct hpi_message hm; 977 struct hpi_message hm;
978 struct hpi_response hr; 978 struct hpi_response hr;
979
979 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM, 980 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
980 HPI_OSTREAM_ANC_READ); 981 HPI_OSTREAM_ANC_READ);
981 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index); 982 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
@@ -1581,6 +1582,7 @@ u16 hpi_control_param_set(const struct hpi_hsubsys *ph_subsys,
1581{ 1582{
1582 struct hpi_message hm; 1583 struct hpi_message hm;
1583 struct hpi_response hr; 1584 struct hpi_response hr;
1585
1584 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 1586 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
1585 HPI_CONTROL_SET_STATE); 1587 HPI_CONTROL_SET_STATE);
1586 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 1588 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
@@ -1591,6 +1593,22 @@ u16 hpi_control_param_set(const struct hpi_hsubsys *ph_subsys,
1591 return hr.error; 1593 return hr.error;
1592} 1594}
1593 1595
1596static u16 hpi_control_log_set2(u32 h_control, u16 attrib, short sv0,
1597 short sv1)
1598{
1599 struct hpi_message hm;
1600 struct hpi_response hr;
1601
1602 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
1603 HPI_CONTROL_SET_STATE);
1604 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
1605 hm.u.c.attribute = attrib;
1606 hm.u.c.an_log_value[0] = sv0;
1607 hm.u.c.an_log_value[1] = sv1;
1608 hpi_send_recv(&hm, &hr);
1609 return hr.error;
1610}
1611
1594static 1612static
1595u16 hpi_control_param_get(const struct hpi_hsubsys *ph_subsys, 1613u16 hpi_control_param_get(const struct hpi_hsubsys *ph_subsys,
1596 const u32 h_control, const u16 attrib, u32 param1, u32 param2, 1614 const u32 h_control, const u16 attrib, u32 param1, u32 param2,
@@ -1598,6 +1616,7 @@ u16 hpi_control_param_get(const struct hpi_hsubsys *ph_subsys,
1598{ 1616{
1599 struct hpi_message hm; 1617 struct hpi_message hm;
1600 struct hpi_response hr; 1618 struct hpi_response hr;
1619
1601 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 1620 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
1602 HPI_CONTROL_GET_STATE); 1621 HPI_CONTROL_GET_STATE);
1603 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 1622 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
@@ -1605,8 +1624,8 @@ u16 hpi_control_param_get(const struct hpi_hsubsys *ph_subsys,
1605 hm.u.c.param1 = param1; 1624 hm.u.c.param1 = param1;
1606 hm.u.c.param2 = param2; 1625 hm.u.c.param2 = param2;
1607 hpi_send_recv(&hm, &hr); 1626 hpi_send_recv(&hm, &hr);
1608 if (pparam1) 1627
1609 *pparam1 = hr.u.c.param1; 1628 *pparam1 = hr.u.c.param1;
1610 if (pparam2) 1629 if (pparam2)
1611 *pparam2 = hr.u.c.param2; 1630 *pparam2 = hr.u.c.param2;
1612 1631
@@ -1617,10 +1636,23 @@ u16 hpi_control_param_get(const struct hpi_hsubsys *ph_subsys,
1617 hpi_control_param_get(s, h, a, 0, 0, p1, NULL) 1636 hpi_control_param_get(s, h, a, 0, 0, p1, NULL)
1618#define hpi_control_param2_get(s, h, a, p1, p2) \ 1637#define hpi_control_param2_get(s, h, a, p1, p2) \
1619 hpi_control_param_get(s, h, a, 0, 0, p1, p2) 1638 hpi_control_param_get(s, h, a, 0, 0, p1, p2)
1620#define hpi_control_ex_param1_get(s, h, a, p1) \ 1639
1621 hpi_control_ex_param_get(s, h, a, 0, 0, p1, NULL) 1640static u16 hpi_control_log_get2(const struct hpi_hsubsys *ph_subsys,
1622#define hpi_control_ex_param2_get(s, h, a, p1, p2) \ 1641 u32 h_control, u16 attrib, short *sv0, short *sv1)
1623 hpi_control_ex_param_get(s, h, a, 0, 0, p1, p2) 1642{
1643 struct hpi_message hm;
1644 struct hpi_response hr;
1645 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
1646 HPI_CONTROL_GET_STATE);
1647 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
1648 hm.u.c.attribute = attrib;
1649
1650 hpi_send_recv(&hm, &hr);
1651 *sv0 = hr.u.c.an_log_value[0];
1652 if (sv1)
1653 *sv1 = hr.u.c.an_log_value[1];
1654 return hr.error;
1655}
1624 1656
1625static 1657static
1626u16 hpi_control_query(const struct hpi_hsubsys *ph_subsys, 1658u16 hpi_control_query(const struct hpi_hsubsys *ph_subsys,
@@ -1629,6 +1661,7 @@ u16 hpi_control_query(const struct hpi_hsubsys *ph_subsys,
1629{ 1661{
1630 struct hpi_message hm; 1662 struct hpi_message hm;
1631 struct hpi_response hr; 1663 struct hpi_response hr;
1664
1632 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 1665 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
1633 HPI_CONTROL_GET_INFO); 1666 HPI_CONTROL_GET_INFO);
1634 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 1667 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
@@ -1643,9 +1676,8 @@ u16 hpi_control_query(const struct hpi_hsubsys *ph_subsys,
1643 return hr.error; 1676 return hr.error;
1644} 1677}
1645 1678
1646static u16 hpi_control_get_string(const struct hpi_hsubsys *ph_subsys, 1679static u16 hpi_control_get_string(const u32 h_control, const u16 attribute,
1647 const u32 h_control, const u16 attribute, char *psz_string, 1680 char *psz_string, const u32 string_length)
1648 const u32 string_length)
1649{ 1681{
1650 unsigned int sub_string_index = 0, j = 0; 1682 unsigned int sub_string_index = 0, j = 0;
1651 char c = 0; 1683 char c = 0;
@@ -1916,6 +1948,7 @@ u16 hpi_cobranet_hmi_write(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1916{ 1948{
1917 struct hpi_message hm; 1949 struct hpi_message hm;
1918 struct hpi_response hr; 1950 struct hpi_response hr;
1951
1919 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX, 1952 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX,
1920 HPI_CONTROL_SET_STATE); 1953 HPI_CONTROL_SET_STATE);
1921 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 1954 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
@@ -1941,6 +1974,7 @@ u16 hpi_cobranet_hmi_read(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1941{ 1974{
1942 struct hpi_message hm; 1975 struct hpi_message hm;
1943 struct hpi_response hr; 1976 struct hpi_response hr;
1977
1944 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX, 1978 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX,
1945 HPI_CONTROL_GET_STATE); 1979 HPI_CONTROL_GET_STATE);
1946 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 1980 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
@@ -1980,6 +2014,7 @@ u16 hpi_cobranet_hmi_get_status(const struct hpi_hsubsys *ph_subsys,
1980{ 2014{
1981 struct hpi_message hm; 2015 struct hpi_message hm;
1982 struct hpi_response hr; 2016 struct hpi_response hr;
2017
1983 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX, 2018 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX,
1984 HPI_CONTROL_GET_STATE); 2019 HPI_CONTROL_GET_STATE);
1985 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 2020 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
@@ -2006,6 +2041,7 @@ u16 hpi_cobranet_getI_paddress(const struct hpi_hsubsys *ph_subsys,
2006 u32 byte_count; 2041 u32 byte_count;
2007 u32 iP; 2042 u32 iP;
2008 u16 error; 2043 u16 error;
2044
2009 error = hpi_cobranet_hmi_read(ph_subsys, h_control, 2045 error = hpi_cobranet_hmi_read(ph_subsys, h_control,
2010 HPI_COBRANET_HMI_cobra_ip_mon_currentIP, 4, &byte_count, 2046 HPI_COBRANET_HMI_cobra_ip_mon_currentIP, 4, &byte_count,
2011 (u8 *)&iP); 2047 (u8 *)&iP);
@@ -2082,6 +2118,7 @@ u16 hpi_cobranet_getMA_caddress(const struct hpi_hsubsys *ph_subsys,
2082 u32 byte_count; 2118 u32 byte_count;
2083 u16 error; 2119 u16 error;
2084 u32 mAC; 2120 u32 mAC;
2121
2085 error = hpi_cobranet_hmi_read(ph_subsys, h_control, 2122 error = hpi_cobranet_hmi_read(ph_subsys, h_control,
2086 HPI_COBRANET_HMI_cobra_if_phy_address, 4, &byte_count, 2123 HPI_COBRANET_HMI_cobra_if_phy_address, 4, &byte_count,
2087 (u8 *)&mAC); 2124 (u8 *)&mAC);
@@ -2103,53 +2140,111 @@ u16 hpi_cobranet_getMA_caddress(const struct hpi_hsubsys *ph_subsys,
2103 return error; 2140 return error;
2104} 2141}
2105 2142
2106u16 hpi_compander_set(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2143u16 hpi_compander_set_enable(const struct hpi_hsubsys *ph_subsys,
2107 u16 attack, u16 decay, short ratio100, short threshold0_01dB, 2144 u32 h_control, u32 enable)
2108 short makeup_gain0_01dB) 2145{
2146 return hpi_control_param_set(ph_subsys, h_control, HPI_GENERIC_ENABLE,
2147 enable, 0);
2148}
2149
2150u16 hpi_compander_get_enable(const struct hpi_hsubsys *ph_subsys,
2151 u32 h_control, u32 *enable)
2152{
2153 return hpi_control_param1_get(ph_subsys, h_control,
2154 HPI_GENERIC_ENABLE, enable);
2155}
2156
2157u16 hpi_compander_set_makeup_gain(const struct hpi_hsubsys *ph_subsys,
2158 u32 h_control, short makeup_gain0_01dB)
2159{
2160 return hpi_control_log_set2(h_control, HPI_COMPANDER_MAKEUPGAIN,
2161 makeup_gain0_01dB, 0);
2162}
2163
2164u16 hpi_compander_get_makeup_gain(const struct hpi_hsubsys *ph_subsys,
2165 u32 h_control, short *makeup_gain0_01dB)
2166{
2167 return hpi_control_log_get2(ph_subsys, h_control,
2168 HPI_COMPANDER_MAKEUPGAIN, makeup_gain0_01dB, NULL);
2169}
2170
2171u16 hpi_compander_set_attack_time_constant(const struct hpi_hsubsys
2172 *ph_subsys, u32 h_control, unsigned int index, u32 attack)
2173{
2174 return hpi_control_param_set(ph_subsys, h_control,
2175 HPI_COMPANDER_ATTACK, attack, index);
2176}
2177
2178u16 hpi_compander_get_attack_time_constant(const struct hpi_hsubsys
2179 *ph_subsys, u32 h_control, unsigned int index, u32 *attack)
2180{
2181 return hpi_control_param_get(ph_subsys, h_control,
2182 HPI_COMPANDER_ATTACK, 0, index, attack, NULL);
2183}
2184
2185u16 hpi_compander_set_decay_time_constant(const struct hpi_hsubsys *ph_subsys,
2186 u32 h_control, unsigned int index, u32 decay)
2187{
2188 return hpi_control_param_set(ph_subsys, h_control,
2189 HPI_COMPANDER_DECAY, decay, index);
2190}
2191
2192u16 hpi_compander_get_decay_time_constant(const struct hpi_hsubsys *ph_subsys,
2193 u32 h_control, unsigned int index, u32 *decay)
2194{
2195 return hpi_control_param_get(ph_subsys, h_control,
2196 HPI_COMPANDER_DECAY, 0, index, decay, NULL);
2197
2198}
2199
2200u16 hpi_compander_set_threshold(const struct hpi_hsubsys *ph_subsys,
2201 u32 h_control, unsigned int index, short threshold0_01dB)
2109{ 2202{
2110 struct hpi_message hm; 2203 struct hpi_message hm;
2111 struct hpi_response hr; 2204 struct hpi_response hr;
2205
2112 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 2206 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2113 HPI_CONTROL_SET_STATE); 2207 HPI_CONTROL_SET_STATE);
2114 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 2208 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
2115 2209 hm.u.c.attribute = HPI_COMPANDER_THRESHOLD;
2116 hm.u.c.param1 = attack + ((u32)ratio100 << 16); 2210 hm.u.c.param2 = index;
2117 hm.u.c.param2 = (decay & 0xFFFFL);
2118 hm.u.c.an_log_value[0] = threshold0_01dB; 2211 hm.u.c.an_log_value[0] = threshold0_01dB;
2119 hm.u.c.an_log_value[1] = makeup_gain0_01dB;
2120 hm.u.c.attribute = HPI_COMPANDER_PARAMS;
2121 2212
2122 hpi_send_recv(&hm, &hr); 2213 hpi_send_recv(&hm, &hr);
2123 2214
2124 return hr.error; 2215 return hr.error;
2125} 2216}
2126 2217
2127u16 hpi_compander_get(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2218u16 hpi_compander_get_threshold(const struct hpi_hsubsys *ph_subsys,
2128 u16 *pw_attack, u16 *pw_decay, short *pw_ratio100, 2219 u32 h_control, unsigned int index, short *threshold0_01dB)
2129 short *pn_threshold0_01dB, short *pn_makeup_gain0_01dB)
2130{ 2220{
2131 struct hpi_message hm; 2221 struct hpi_message hm;
2132 struct hpi_response hr; 2222 struct hpi_response hr;
2223
2133 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 2224 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2134 HPI_CONTROL_GET_STATE); 2225 HPI_CONTROL_GET_STATE);
2135 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 2226 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
2136 hm.u.c.attribute = HPI_COMPANDER_PARAMS; 2227 hm.u.c.attribute = HPI_COMPANDER_THRESHOLD;
2228 hm.u.c.param2 = index;
2137 2229
2138 hpi_send_recv(&hm, &hr); 2230 hpi_send_recv(&hm, &hr);
2231 *threshold0_01dB = hr.u.c.an_log_value[0];
2139 2232
2140 if (pw_attack) 2233 return hr.error;
2141 *pw_attack = (short)(hr.u.c.param1 & 0xFFFF); 2234}
2142 if (pw_decay)
2143 *pw_decay = (short)(hr.u.c.param2 & 0xFFFF);
2144 if (pw_ratio100)
2145 *pw_ratio100 = (short)(hr.u.c.param1 >> 16);
2146 2235
2147 if (pn_threshold0_01dB) 2236u16 hpi_compander_set_ratio(const struct hpi_hsubsys *ph_subsys,
2148 *pn_threshold0_01dB = hr.u.c.an_log_value[0]; 2237 u32 h_control, u32 index, u32 ratio100)
2149 if (pn_makeup_gain0_01dB) 2238{
2150 *pn_makeup_gain0_01dB = hr.u.c.an_log_value[1]; 2239 return hpi_control_param_set(ph_subsys, h_control,
2240 HPI_COMPANDER_RATIO, ratio100, index);
2241}
2151 2242
2152 return hr.error; 2243u16 hpi_compander_get_ratio(const struct hpi_hsubsys *ph_subsys,
2244 u32 h_control, u32 index, u32 *ratio100)
2245{
2246 return hpi_control_param_get(ph_subsys, h_control,
2247 HPI_COMPANDER_RATIO, 0, index, ratio100, NULL);
2153} 2248}
2154 2249
2155u16 hpi_level_query_range(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2250u16 hpi_level_query_range(const struct hpi_hsubsys *ph_subsys, u32 h_control,
@@ -2157,6 +2252,7 @@ u16 hpi_level_query_range(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2157{ 2252{
2158 struct hpi_message hm; 2253 struct hpi_message hm;
2159 struct hpi_response hr; 2254 struct hpi_response hr;
2255
2160 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 2256 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2161 HPI_CONTROL_GET_STATE); 2257 HPI_CONTROL_GET_STATE);
2162 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 2258 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
@@ -2181,37 +2277,16 @@ u16 hpi_level_set_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2181 short an_gain0_01dB[HPI_MAX_CHANNELS] 2277 short an_gain0_01dB[HPI_MAX_CHANNELS]
2182 ) 2278 )
2183{ 2279{
2184 struct hpi_message hm; 2280 return hpi_control_log_set2(h_control, HPI_LEVEL_GAIN,
2185 struct hpi_response hr; 2281 an_gain0_01dB[0], an_gain0_01dB[1]);
2186
2187 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2188 HPI_CONTROL_SET_STATE);
2189 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
2190 memcpy(hm.u.c.an_log_value, an_gain0_01dB,
2191 sizeof(short) * HPI_MAX_CHANNELS);
2192 hm.u.c.attribute = HPI_LEVEL_GAIN;
2193
2194 hpi_send_recv(&hm, &hr);
2195
2196 return hr.error;
2197} 2282}
2198 2283
2199u16 hpi_level_get_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control, 2284u16 hpi_level_get_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2200 short an_gain0_01dB[HPI_MAX_CHANNELS] 2285 short an_gain0_01dB[HPI_MAX_CHANNELS]
2201 ) 2286 )
2202{ 2287{
2203 struct hpi_message hm; 2288 return hpi_control_log_get2(ph_subsys, h_control, HPI_LEVEL_GAIN,
2204 struct hpi_response hr; 2289 &an_gain0_01dB[0], &an_gain0_01dB[1]);
2205 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2206 HPI_CONTROL_GET_STATE);
2207 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
2208 hm.u.c.attribute = HPI_LEVEL_GAIN;
2209
2210 hpi_send_recv(&hm, &hr);
2211
2212 memcpy(an_gain0_01dB, hr.u.c.an_log_value,
2213 sizeof(short) * HPI_MAX_CHANNELS);
2214 return hr.error;
2215} 2290}
2216 2291
2217u16 hpi_meter_query_channels(const struct hpi_hsubsys *ph_subsys, 2292u16 hpi_meter_query_channels(const struct hpi_hsubsys *ph_subsys,
@@ -2413,6 +2488,7 @@ u16 hpi_parametricEQ__get_band(const struct hpi_hsubsys *ph_subsys,
2413{ 2488{
2414 struct hpi_message hm; 2489 struct hpi_message hm;
2415 struct hpi_response hr; 2490 struct hpi_response hr;
2491
2416 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 2492 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2417 HPI_CONTROL_GET_STATE); 2493 HPI_CONTROL_GET_STATE);
2418 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 2494 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
@@ -2439,6 +2515,7 @@ u16 hpi_parametricEQ__set_band(const struct hpi_hsubsys *ph_subsys,
2439{ 2515{
2440 struct hpi_message hm; 2516 struct hpi_message hm;
2441 struct hpi_response hr; 2517 struct hpi_response hr;
2518
2442 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 2519 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2443 HPI_CONTROL_SET_STATE); 2520 HPI_CONTROL_SET_STATE);
2444 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 2521 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
@@ -2460,6 +2537,7 @@ u16 hpi_parametricEQ__get_coeffs(const struct hpi_hsubsys *ph_subsys,
2460{ 2537{
2461 struct hpi_message hm; 2538 struct hpi_message hm;
2462 struct hpi_response hr; 2539 struct hpi_response hr;
2540
2463 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 2541 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2464 HPI_CONTROL_GET_STATE); 2542 HPI_CONTROL_GET_STATE);
2465 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 2543 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
@@ -2623,8 +2701,8 @@ u16 hpi_tone_detector_get_frequency(const struct hpi_hsubsys *ph_subsys,
2623u16 hpi_tone_detector_get_state(const struct hpi_hsubsys *ph_subsys, 2701u16 hpi_tone_detector_get_state(const struct hpi_hsubsys *ph_subsys,
2624 u32 h_control, u32 *state) 2702 u32 h_control, u32 *state)
2625{ 2703{
2626 return hpi_control_param_get(ph_subsys, h_control, 2704 return hpi_control_param1_get(ph_subsys, h_control,
2627 HPI_TONEDETECTOR_STATE, 0, 0, (u32 *)state, NULL); 2705 HPI_TONEDETECTOR_STATE, state);
2628} 2706}
2629 2707
2630u16 hpi_tone_detector_set_enable(const struct hpi_hsubsys *ph_subsys, 2708u16 hpi_tone_detector_set_enable(const struct hpi_hsubsys *ph_subsys,
@@ -2637,8 +2715,8 @@ u16 hpi_tone_detector_set_enable(const struct hpi_hsubsys *ph_subsys,
2637u16 hpi_tone_detector_get_enable(const struct hpi_hsubsys *ph_subsys, 2715u16 hpi_tone_detector_get_enable(const struct hpi_hsubsys *ph_subsys,
2638 u32 h_control, u32 *enable) 2716 u32 h_control, u32 *enable)
2639{ 2717{
2640 return hpi_control_param_get(ph_subsys, h_control, HPI_GENERIC_ENABLE, 2718 return hpi_control_param1_get(ph_subsys, h_control,
2641 0, 0, (u32 *)enable, NULL); 2719 HPI_GENERIC_ENABLE, enable);
2642} 2720}
2643 2721
2644u16 hpi_tone_detector_set_event_enable(const struct hpi_hsubsys *ph_subsys, 2722u16 hpi_tone_detector_set_event_enable(const struct hpi_hsubsys *ph_subsys,
@@ -2651,8 +2729,8 @@ u16 hpi_tone_detector_set_event_enable(const struct hpi_hsubsys *ph_subsys,
2651u16 hpi_tone_detector_get_event_enable(const struct hpi_hsubsys *ph_subsys, 2729u16 hpi_tone_detector_get_event_enable(const struct hpi_hsubsys *ph_subsys,
2652 u32 h_control, u32 *event_enable) 2730 u32 h_control, u32 *event_enable)
2653{ 2731{
2654 return hpi_control_param_get(ph_subsys, h_control, 2732 return hpi_control_param1_get(ph_subsys, h_control,
2655 HPI_GENERIC_EVENT_ENABLE, 0, 0, (u32 *)event_enable, NULL); 2733 HPI_GENERIC_EVENT_ENABLE, event_enable);
2656} 2734}
2657 2735
2658u16 hpi_tone_detector_set_threshold(const struct hpi_hsubsys *ph_subsys, 2736u16 hpi_tone_detector_set_threshold(const struct hpi_hsubsys *ph_subsys,
@@ -2665,15 +2743,15 @@ u16 hpi_tone_detector_set_threshold(const struct hpi_hsubsys *ph_subsys,
2665u16 hpi_tone_detector_get_threshold(const struct hpi_hsubsys *ph_subsys, 2743u16 hpi_tone_detector_get_threshold(const struct hpi_hsubsys *ph_subsys,
2666 u32 h_control, int *threshold) 2744 u32 h_control, int *threshold)
2667{ 2745{
2668 return hpi_control_param_get(ph_subsys, h_control, 2746 return hpi_control_param1_get(ph_subsys, h_control,
2669 HPI_TONEDETECTOR_THRESHOLD, 0, 0, (u32 *)threshold, NULL); 2747 HPI_TONEDETECTOR_THRESHOLD, (u32 *)threshold);
2670} 2748}
2671 2749
2672u16 hpi_silence_detector_get_state(const struct hpi_hsubsys *ph_subsys, 2750u16 hpi_silence_detector_get_state(const struct hpi_hsubsys *ph_subsys,
2673 u32 h_control, u32 *state) 2751 u32 h_control, u32 *state)
2674{ 2752{
2675 return hpi_control_param_get(ph_subsys, h_control, 2753 return hpi_control_param1_get(ph_subsys, h_control,
2676 HPI_SILENCEDETECTOR_STATE, 0, 0, (u32 *)state, NULL); 2754 HPI_SILENCEDETECTOR_STATE, state);
2677} 2755}
2678 2756
2679u16 hpi_silence_detector_set_enable(const struct hpi_hsubsys *ph_subsys, 2757u16 hpi_silence_detector_set_enable(const struct hpi_hsubsys *ph_subsys,
@@ -2686,50 +2764,50 @@ u16 hpi_silence_detector_set_enable(const struct hpi_hsubsys *ph_subsys,
2686u16 hpi_silence_detector_get_enable(const struct hpi_hsubsys *ph_subsys, 2764u16 hpi_silence_detector_get_enable(const struct hpi_hsubsys *ph_subsys,
2687 u32 h_control, u32 *enable) 2765 u32 h_control, u32 *enable)
2688{ 2766{
2689 return hpi_control_param_get(ph_subsys, h_control, HPI_GENERIC_ENABLE, 2767 return hpi_control_param1_get(ph_subsys, h_control,
2690 0, 0, (u32 *)enable, NULL); 2768 HPI_GENERIC_ENABLE, enable);
2691} 2769}
2692 2770
2693u16 hpi_silence_detector_set_event_enable(const struct hpi_hsubsys *ph_subsys, 2771u16 hpi_silence_detector_set_event_enable(const struct hpi_hsubsys *ph_subsys,
2694 u32 h_control, u32 event_enable) 2772 u32 h_control, u32 event_enable)
2695{ 2773{
2696 return hpi_control_param_set(ph_subsys, h_control, 2774 return hpi_control_param_set(ph_subsys, h_control,
2697 HPI_GENERIC_EVENT_ENABLE, (u32)event_enable, 0); 2775 HPI_GENERIC_EVENT_ENABLE, event_enable, 0);
2698} 2776}
2699 2777
2700u16 hpi_silence_detector_get_event_enable(const struct hpi_hsubsys *ph_subsys, 2778u16 hpi_silence_detector_get_event_enable(const struct hpi_hsubsys *ph_subsys,
2701 u32 h_control, u32 *event_enable) 2779 u32 h_control, u32 *event_enable)
2702{ 2780{
2703 return hpi_control_param_get(ph_subsys, h_control, 2781 return hpi_control_param1_get(ph_subsys, h_control,
2704 HPI_GENERIC_EVENT_ENABLE, 0, 0, (u32 *)event_enable, NULL); 2782 HPI_GENERIC_EVENT_ENABLE, event_enable);
2705} 2783}
2706 2784
2707u16 hpi_silence_detector_set_delay(const struct hpi_hsubsys *ph_subsys, 2785u16 hpi_silence_detector_set_delay(const struct hpi_hsubsys *ph_subsys,
2708 u32 h_control, u32 delay) 2786 u32 h_control, u32 delay)
2709{ 2787{
2710 return hpi_control_param_set(ph_subsys, h_control, 2788 return hpi_control_param_set(ph_subsys, h_control,
2711 HPI_SILENCEDETECTOR_DELAY, (u32)delay, 0); 2789 HPI_SILENCEDETECTOR_DELAY, delay, 0);
2712} 2790}
2713 2791
2714u16 hpi_silence_detector_get_delay(const struct hpi_hsubsys *ph_subsys, 2792u16 hpi_silence_detector_get_delay(const struct hpi_hsubsys *ph_subsys,
2715 u32 h_control, u32 *delay) 2793 u32 h_control, u32 *delay)
2716{ 2794{
2717 return hpi_control_param_get(ph_subsys, h_control, 2795 return hpi_control_param1_get(ph_subsys, h_control,
2718 HPI_SILENCEDETECTOR_DELAY, 0, 0, (u32 *)delay, NULL); 2796 HPI_SILENCEDETECTOR_DELAY, delay);
2719} 2797}
2720 2798
2721u16 hpi_silence_detector_set_threshold(const struct hpi_hsubsys *ph_subsys, 2799u16 hpi_silence_detector_set_threshold(const struct hpi_hsubsys *ph_subsys,
2722 u32 h_control, int threshold) 2800 u32 h_control, int threshold)
2723{ 2801{
2724 return hpi_control_param_set(ph_subsys, h_control, 2802 return hpi_control_param_set(ph_subsys, h_control,
2725 HPI_SILENCEDETECTOR_THRESHOLD, (u32)threshold, 0); 2803 HPI_SILENCEDETECTOR_THRESHOLD, threshold, 0);
2726} 2804}
2727 2805
2728u16 hpi_silence_detector_get_threshold(const struct hpi_hsubsys *ph_subsys, 2806u16 hpi_silence_detector_get_threshold(const struct hpi_hsubsys *ph_subsys,
2729 u32 h_control, int *threshold) 2807 u32 h_control, int *threshold)
2730{ 2808{
2731 return hpi_control_param_get(ph_subsys, h_control, 2809 return hpi_control_param1_get(ph_subsys, h_control,
2732 HPI_SILENCEDETECTOR_THRESHOLD, 0, 0, (u32 *)threshold, NULL); 2810 HPI_SILENCEDETECTOR_THRESHOLD, (u32 *)threshold);
2733} 2811}
2734 2812
2735u16 hpi_tuner_query_band(const struct hpi_hsubsys *ph_subsys, 2813u16 hpi_tuner_query_band(const struct hpi_hsubsys *ph_subsys,
@@ -2822,6 +2900,7 @@ u16 hpi_tuner_getRF_level(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2822{ 2900{
2823 struct hpi_message hm; 2901 struct hpi_message hm;
2824 struct hpi_response hr; 2902 struct hpi_response hr;
2903
2825 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 2904 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2826 HPI_CONTROL_GET_STATE); 2905 HPI_CONTROL_GET_STATE);
2827 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 2906 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
@@ -2838,6 +2917,7 @@ u16 hpi_tuner_get_rawRF_level(const struct hpi_hsubsys *ph_subsys,
2838{ 2917{
2839 struct hpi_message hm; 2918 struct hpi_message hm;
2840 struct hpi_response hr; 2919 struct hpi_response hr;
2920
2841 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 2921 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2842 HPI_CONTROL_GET_STATE); 2922 HPI_CONTROL_GET_STATE);
2843 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 2923 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
@@ -2894,14 +2974,14 @@ u16 hpi_tuner_get_program(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2894u16 hpi_tuner_get_hd_radio_dsp_version(const struct hpi_hsubsys *ph_subsys, 2974u16 hpi_tuner_get_hd_radio_dsp_version(const struct hpi_hsubsys *ph_subsys,
2895 u32 h_control, char *psz_dsp_version, const u32 string_size) 2975 u32 h_control, char *psz_dsp_version, const u32 string_size)
2896{ 2976{
2897 return hpi_control_get_string(ph_subsys, h_control, 2977 return hpi_control_get_string(h_control,
2898 HPI_TUNER_HDRADIO_DSP_VERSION, psz_dsp_version, string_size); 2978 HPI_TUNER_HDRADIO_DSP_VERSION, psz_dsp_version, string_size);
2899} 2979}
2900 2980
2901u16 hpi_tuner_get_hd_radio_sdk_version(const struct hpi_hsubsys *ph_subsys, 2981u16 hpi_tuner_get_hd_radio_sdk_version(const struct hpi_hsubsys *ph_subsys,
2902 u32 h_control, char *psz_sdk_version, const u32 string_size) 2982 u32 h_control, char *psz_sdk_version, const u32 string_size)
2903{ 2983{
2904 return hpi_control_get_string(ph_subsys, h_control, 2984 return hpi_control_get_string(h_control,
2905 HPI_TUNER_HDRADIO_SDK_VERSION, psz_sdk_version, string_size); 2985 HPI_TUNER_HDRADIO_SDK_VERSION, psz_sdk_version, string_size);
2906} 2986}
2907 2987
@@ -2942,15 +3022,15 @@ u16 hpi_tuner_get_mode(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2942u16 hpi_tuner_get_hd_radio_signal_quality(const struct hpi_hsubsys *ph_subsys, 3022u16 hpi_tuner_get_hd_radio_signal_quality(const struct hpi_hsubsys *ph_subsys,
2943 u32 h_control, u32 *pquality) 3023 u32 h_control, u32 *pquality)
2944{ 3024{
2945 return hpi_control_param_get(ph_subsys, h_control, 3025 return hpi_control_param1_get(ph_subsys, h_control,
2946 HPI_TUNER_HDRADIO_SIGNAL_QUALITY, 0, 0, pquality, NULL); 3026 HPI_TUNER_HDRADIO_SIGNAL_QUALITY, pquality);
2947} 3027}
2948 3028
2949u16 hpi_tuner_get_hd_radio_signal_blend(const struct hpi_hsubsys *ph_subsys, 3029u16 hpi_tuner_get_hd_radio_signal_blend(const struct hpi_hsubsys *ph_subsys,
2950 u32 h_control, u32 *pblend) 3030 u32 h_control, u32 *pblend)
2951{ 3031{
2952 return hpi_control_param_get(ph_subsys, h_control, 3032 return hpi_control_param1_get(ph_subsys, h_control,
2953 HPI_TUNER_HDRADIO_BLEND, 0, 0, pblend, NULL); 3033 HPI_TUNER_HDRADIO_BLEND, pblend);
2954} 3034}
2955 3035
2956u16 hpi_tuner_set_hd_radio_signal_blend(const struct hpi_hsubsys *ph_subsys, 3036u16 hpi_tuner_set_hd_radio_signal_blend(const struct hpi_hsubsys *ph_subsys,
@@ -2965,6 +3045,7 @@ u16 hpi_tuner_getRDS(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2965{ 3045{
2966 struct hpi_message hm; 3046 struct hpi_message hm;
2967 struct hpi_response hr; 3047 struct hpi_response hr;
3048
2968 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 3049 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2969 HPI_CONTROL_GET_STATE); 3050 HPI_CONTROL_GET_STATE);
2970 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 3051 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
@@ -2981,43 +3062,43 @@ u16 hpi_tuner_getRDS(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2981u16 HPI_PAD__get_channel_name(const struct hpi_hsubsys *ph_subsys, 3062u16 HPI_PAD__get_channel_name(const struct hpi_hsubsys *ph_subsys,
2982 u32 h_control, char *psz_string, const u32 data_length) 3063 u32 h_control, char *psz_string, const u32 data_length)
2983{ 3064{
2984 return hpi_control_get_string(ph_subsys, h_control, 3065 return hpi_control_get_string(h_control, HPI_PAD_CHANNEL_NAME,
2985 HPI_PAD_CHANNEL_NAME, psz_string, data_length); 3066 psz_string, data_length);
2986} 3067}
2987 3068
2988u16 HPI_PAD__get_artist(const struct hpi_hsubsys *ph_subsys, u32 h_control, 3069u16 HPI_PAD__get_artist(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2989 char *psz_string, const u32 data_length) 3070 char *psz_string, const u32 data_length)
2990{ 3071{
2991 return hpi_control_get_string(ph_subsys, h_control, HPI_PAD_ARTIST, 3072 return hpi_control_get_string(h_control, HPI_PAD_ARTIST, psz_string,
2992 psz_string, data_length); 3073 data_length);
2993} 3074}
2994 3075
2995u16 HPI_PAD__get_title(const struct hpi_hsubsys *ph_subsys, u32 h_control, 3076u16 HPI_PAD__get_title(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2996 char *psz_string, const u32 data_length) 3077 char *psz_string, const u32 data_length)
2997{ 3078{
2998 return hpi_control_get_string(ph_subsys, h_control, HPI_PAD_TITLE, 3079 return hpi_control_get_string(h_control, HPI_PAD_TITLE, psz_string,
2999 psz_string, data_length); 3080 data_length);
3000} 3081}
3001 3082
3002u16 HPI_PAD__get_comment(const struct hpi_hsubsys *ph_subsys, u32 h_control, 3083u16 HPI_PAD__get_comment(const struct hpi_hsubsys *ph_subsys, u32 h_control,
3003 char *psz_string, const u32 data_length) 3084 char *psz_string, const u32 data_length)
3004{ 3085{
3005 return hpi_control_get_string(ph_subsys, h_control, HPI_PAD_COMMENT, 3086 return hpi_control_get_string(h_control, HPI_PAD_COMMENT, psz_string,
3006 psz_string, data_length); 3087 data_length);
3007} 3088}
3008 3089
3009u16 HPI_PAD__get_program_type(const struct hpi_hsubsys *ph_subsys, 3090u16 HPI_PAD__get_program_type(const struct hpi_hsubsys *ph_subsys,
3010 u32 h_control, u32 *ppTY) 3091 u32 h_control, u32 *ppTY)
3011{ 3092{
3012 return hpi_control_param_get(ph_subsys, h_control, 3093 return hpi_control_param1_get(ph_subsys, h_control,
3013 HPI_PAD_PROGRAM_TYPE, 0, 0, ppTY, NULL); 3094 HPI_PAD_PROGRAM_TYPE, ppTY);
3014} 3095}
3015 3096
3016u16 HPI_PAD__get_rdsPI(const struct hpi_hsubsys *ph_subsys, u32 h_control, 3097u16 HPI_PAD__get_rdsPI(const struct hpi_hsubsys *ph_subsys, u32 h_control,
3017 u32 *ppI) 3098 u32 *ppI)
3018{ 3099{
3019 return hpi_control_param_get(ph_subsys, h_control, HPI_PAD_PROGRAM_ID, 3100 return hpi_control_param1_get(ph_subsys, h_control,
3020 0, 0, ppI, NULL); 3101 HPI_PAD_PROGRAM_ID, ppI);
3021} 3102}
3022 3103
3023u16 hpi_volume_query_channels(const struct hpi_hsubsys *ph_subsys, 3104u16 hpi_volume_query_channels(const struct hpi_hsubsys *ph_subsys,
@@ -3031,36 +3112,16 @@ u16 hpi_volume_set_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control,
3031 short an_log_gain[HPI_MAX_CHANNELS] 3112 short an_log_gain[HPI_MAX_CHANNELS]
3032 ) 3113 )
3033{ 3114{
3034 struct hpi_message hm; 3115 return hpi_control_log_set2(h_control, HPI_VOLUME_GAIN,
3035 struct hpi_response hr; 3116 an_log_gain[0], an_log_gain[1]);
3036 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
3037 HPI_CONTROL_SET_STATE);
3038 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
3039 memcpy(hm.u.c.an_log_value, an_log_gain,
3040 sizeof(short) * HPI_MAX_CHANNELS);
3041 hm.u.c.attribute = HPI_VOLUME_GAIN;
3042
3043 hpi_send_recv(&hm, &hr);
3044
3045 return hr.error;
3046} 3117}
3047 3118
3048u16 hpi_volume_get_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control, 3119u16 hpi_volume_get_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control,
3049 short an_log_gain[HPI_MAX_CHANNELS] 3120 short an_log_gain[HPI_MAX_CHANNELS]
3050 ) 3121 )
3051{ 3122{
3052 struct hpi_message hm; 3123 return hpi_control_log_get2(ph_subsys, h_control, HPI_VOLUME_GAIN,
3053 struct hpi_response hr; 3124 &an_log_gain[0], &an_log_gain[1]);
3054 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
3055 HPI_CONTROL_GET_STATE);
3056 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
3057 hm.u.c.attribute = HPI_VOLUME_GAIN;
3058
3059 hpi_send_recv(&hm, &hr);
3060
3061 memcpy(an_log_gain, hr.u.c.an_log_value,
3062 sizeof(short) * HPI_MAX_CHANNELS);
3063 return hr.error;
3064} 3125}
3065 3126
3066u16 hpi_volume_query_range(const struct hpi_hsubsys *ph_subsys, u32 h_control, 3127u16 hpi_volume_query_range(const struct hpi_hsubsys *ph_subsys, u32 h_control,
@@ -3068,6 +3129,7 @@ u16 hpi_volume_query_range(const struct hpi_hsubsys *ph_subsys, u32 h_control,
3068{ 3129{
3069 struct hpi_message hm; 3130 struct hpi_message hm;
3070 struct hpi_response hr; 3131 struct hpi_response hr;
3132
3071 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 3133 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
3072 HPI_CONTROL_GET_STATE); 3134 HPI_CONTROL_GET_STATE);
3073 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 3135 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
@@ -3094,6 +3156,7 @@ u16 hpi_volume_auto_fade_profile(const struct hpi_hsubsys *ph_subsys,
3094{ 3156{
3095 struct hpi_message hm; 3157 struct hpi_message hm;
3096 struct hpi_response hr; 3158 struct hpi_response hr;
3159
3097 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL, 3160 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
3098 HPI_CONTROL_SET_STATE); 3161 HPI_CONTROL_SET_STATE);
3099 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index); 3162 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
@@ -3170,43 +3233,42 @@ static size_t entity_type_to_size[LAST_ENTITY_TYPE] = {
3170 6 * sizeof(char), 3233 6 * sizeof(char),
3171}; 3234};
3172 3235
3173inline size_t hpi_entity_size(struct hpi_entity *entity_ptr) 3236static inline size_t hpi_entity_size(struct hpi_entity *entity_ptr)
3174{ 3237{
3175 return entity_ptr->header.size; 3238 return entity_ptr->header.size;
3176} 3239}
3177 3240
3178inline size_t hpi_entity_header_size(struct hpi_entity *entity_ptr) 3241static inline size_t hpi_entity_header_size(struct hpi_entity *entity_ptr)
3179{ 3242{
3180 return sizeof(entity_ptr->header); 3243 return sizeof(entity_ptr->header);
3181} 3244}
3182 3245
3183inline size_t hpi_entity_value_size(struct hpi_entity *entity_ptr) 3246static inline size_t hpi_entity_value_size(struct hpi_entity *entity_ptr)
3184{ 3247{
3185 return hpi_entity_size(entity_ptr) - 3248 return hpi_entity_size(entity_ptr) -
3186 hpi_entity_header_size(entity_ptr); 3249 hpi_entity_header_size(entity_ptr);
3187} 3250}
3188 3251
3189inline size_t hpi_entity_item_count(struct hpi_entity *entity_ptr) 3252static inline size_t hpi_entity_item_count(struct hpi_entity *entity_ptr)
3190{ 3253{
3191 return hpi_entity_value_size(entity_ptr) / 3254 return hpi_entity_value_size(entity_ptr) /
3192 entity_type_to_size[entity_ptr->header.type]; 3255 entity_type_to_size[entity_ptr->header.type];
3193} 3256}
3194 3257
3195inline struct hpi_entity *hpi_entity_ptr_to_next(struct hpi_entity 3258static inline struct hpi_entity *hpi_entity_ptr_to_next(struct hpi_entity
3196 *entity_ptr) 3259 *entity_ptr)
3197{ 3260{
3198 return (void *)(((uint8_t *) entity_ptr) + 3261 return (void *)(((u8 *)entity_ptr) + hpi_entity_size(entity_ptr));
3199 hpi_entity_size(entity_ptr));
3200} 3262}
3201 3263
3202inline u16 hpi_entity_check_type(const enum e_entity_type t) 3264static inline u16 hpi_entity_check_type(const enum e_entity_type t)
3203{ 3265{
3204 if (t >= 0 && t < STR_TYPE_FIELD_MAX) 3266 if (t >= 0 && t < STR_TYPE_FIELD_MAX)
3205 return 0; 3267 return 0;
3206 return HPI_ERROR_ENTITY_TYPE_INVALID; 3268 return HPI_ERROR_ENTITY_TYPE_INVALID;
3207} 3269}
3208 3270
3209inline u16 hpi_entity_check_role(const enum e_entity_role r) 3271static inline u16 hpi_entity_check_role(const enum e_entity_role r)
3210{ 3272{
3211 if (r >= 0 && r < STR_ROLE_FIELD_MAX) 3273 if (r >= 0 && r < STR_ROLE_FIELD_MAX)
3212 return 0; 3274 return 0;
@@ -3624,6 +3686,7 @@ u16 hpi_async_event_wait(const struct hpi_hsubsys *ph_subsys, u32 h_async,
3624 u16 maximum_events, struct hpi_async_event *p_events, 3686 u16 maximum_events, struct hpi_async_event *p_events,
3625 u16 *pw_number_returned) 3687 u16 *pw_number_returned)
3626{ 3688{
3689
3627 return 0; 3690 return 0;
3628} 3691}
3629 3692
diff --git a/sound/pci/asihpi/hpimsgx.c b/sound/pci/asihpi/hpimsgx.c
index 2ee90dc3d89..f01ab964f60 100644
--- a/sound/pci/asihpi/hpimsgx.c
+++ b/sound/pci/asihpi/hpimsgx.c
@@ -741,7 +741,7 @@ static void HPIMSGX__reset(u16 adapter_index)
741 hpi_init_response(&hr, HPI_OBJ_SUBSYSTEM, 741 hpi_init_response(&hr, HPI_OBJ_SUBSYSTEM,
742 HPI_SUBSYS_FIND_ADAPTERS, 0); 742 HPI_SUBSYS_FIND_ADAPTERS, 0);
743 memcpy(&gRESP_HPI_SUBSYS_FIND_ADAPTERS, &hr, 743 memcpy(&gRESP_HPI_SUBSYS_FIND_ADAPTERS, &hr,
744 sizeof(&gRESP_HPI_SUBSYS_FIND_ADAPTERS)); 744 sizeof(gRESP_HPI_SUBSYS_FIND_ADAPTERS));
745 745
746 for (adapter = 0; adapter < HPI_MAX_ADAPTERS; adapter++) { 746 for (adapter = 0; adapter < HPI_MAX_ADAPTERS; adapter++) {
747 747
diff --git a/sound/pci/asihpi/hpioctl.c b/sound/pci/asihpi/hpioctl.c
index 7396ac54e99..62895a719fc 100644
--- a/sound/pci/asihpi/hpioctl.c
+++ b/sound/pci/asihpi/hpioctl.c
@@ -121,11 +121,17 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
121 phpi_ioctl_data = (struct hpi_ioctl_linux __user *)arg; 121 phpi_ioctl_data = (struct hpi_ioctl_linux __user *)arg;
122 122
123 /* Read the message and response pointers from user space. */ 123 /* Read the message and response pointers from user space. */
124 get_user(puhm, &phpi_ioctl_data->phm); 124 if (get_user(puhm, &phpi_ioctl_data->phm) ||
125 get_user(puhr, &phpi_ioctl_data->phr); 125 get_user(puhr, &phpi_ioctl_data->phr)) {
126 err = -EFAULT;
127 goto out;
128 }
126 129
127 /* Now read the message size and data from user space. */ 130 /* Now read the message size and data from user space. */
128 get_user(hm->h.size, (u16 __user *)puhm); 131 if (get_user(hm->h.size, (u16 __user *)puhm)) {
132 err = -EFAULT;
133 goto out;
134 }
129 if (hm->h.size > sizeof(*hm)) 135 if (hm->h.size > sizeof(*hm))
130 hm->h.size = sizeof(*hm); 136 hm->h.size = sizeof(*hm);
131 137
@@ -138,7 +144,10 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
138 goto out; 144 goto out;
139 } 145 }
140 146
141 get_user(res_max_size, (u16 __user *)puhr); 147 if (get_user(res_max_size, (u16 __user *)puhr)) {
148 err = -EFAULT;
149 goto out;
150 }
142 /* printk(KERN_INFO "user response size %d\n", res_max_size); */ 151 /* printk(KERN_INFO "user response size %d\n", res_max_size); */
143 if (res_max_size < sizeof(struct hpi_response_header)) { 152 if (res_max_size < sizeof(struct hpi_response_header)) {
144 HPI_DEBUG_LOG(WARNING, "small res size %d\n", res_max_size); 153 HPI_DEBUG_LOG(WARNING, "small res size %d\n", res_max_size);
@@ -464,9 +473,7 @@ void __init asihpi_init(void)
464 473
465 memset(adapters, 0, sizeof(adapters)); 474 memset(adapters, 0, sizeof(adapters));
466 475
467 printk(KERN_INFO "ASIHPI driver %d.%02d.%02d\n", 476 printk(KERN_INFO "ASIHPI driver " HPI_VER_STRING "\n");
468 HPI_VER_MAJOR(HPI_VER), HPI_VER_MINOR(HPI_VER),
469 HPI_VER_RELEASE(HPI_VER));
470 477
471 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM, 478 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
472 HPI_SUBSYS_DRIVER_LOAD); 479 HPI_SUBSYS_DRIVER_LOAD);
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index 0a3d3d6e77b..8e69620da20 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -1002,29 +1002,27 @@ snd_ca0106_pcm_pointer_playback(struct snd_pcm_substream *substream)
1002 struct snd_ca0106 *emu = snd_pcm_substream_chip(substream); 1002 struct snd_ca0106 *emu = snd_pcm_substream_chip(substream);
1003 struct snd_pcm_runtime *runtime = substream->runtime; 1003 struct snd_pcm_runtime *runtime = substream->runtime;
1004 struct snd_ca0106_pcm *epcm = runtime->private_data; 1004 struct snd_ca0106_pcm *epcm = runtime->private_data;
1005 snd_pcm_uframes_t ptr, ptr1, ptr2,ptr3,ptr4 = 0; 1005 unsigned int ptr, prev_ptr;
1006 int channel = epcm->channel_id; 1006 int channel = epcm->channel_id;
1007 int timeout = 10;
1007 1008
1008 if (!epcm->running) 1009 if (!epcm->running)
1009 return 0; 1010 return 0;
1010 1011
1011 ptr3 = snd_ca0106_ptr_read(emu, PLAYBACK_LIST_PTR, channel); 1012 prev_ptr = -1;
1012 ptr1 = snd_ca0106_ptr_read(emu, PLAYBACK_POINTER, channel); 1013 do {
1013 ptr4 = snd_ca0106_ptr_read(emu, PLAYBACK_LIST_PTR, channel); 1014 ptr = snd_ca0106_ptr_read(emu, PLAYBACK_LIST_PTR, channel);
1014 if (ptr3 != ptr4) ptr1 = snd_ca0106_ptr_read(emu, PLAYBACK_POINTER, channel); 1015 ptr = (ptr >> 3) * runtime->period_size;
1015 ptr2 = bytes_to_frames(runtime, ptr1); 1016 ptr += bytes_to_frames(runtime,
1016 ptr2+= (ptr4 >> 3) * runtime->period_size; 1017 snd_ca0106_ptr_read(emu, PLAYBACK_POINTER, channel));
1017 ptr=ptr2; 1018 if (ptr >= runtime->buffer_size)
1018 if (ptr >= runtime->buffer_size) 1019 ptr -= runtime->buffer_size;
1019 ptr -= runtime->buffer_size; 1020 if (prev_ptr == ptr)
1020 /* 1021 return ptr;
1021 printk(KERN_DEBUG "ptr1 = 0x%lx, ptr2=0x%lx, ptr=0x%lx, " 1022 prev_ptr = ptr;
1022 "buffer_size = 0x%x, period_size = 0x%x, bits=%d, rate=%d\n", 1023 } while (--timeout);
1023 ptr1, ptr2, ptr, (int)runtime->buffer_size, 1024 snd_printk(KERN_WARNING "ca0106: unstable DMA pointer!\n");
1024 (int)runtime->period_size, (int)runtime->frame_bits, 1025 return 0;
1025 (int)runtime->rate);
1026 */
1027 return ptr;
1028} 1026}
1029 1027
1030/* pointer_capture callback */ 1028/* pointer_capture callback */
diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c
index 668a5ec0449..20763dd03fa 100644
--- a/sound/pci/echoaudio/echoaudio.c
+++ b/sound/pci/echoaudio/echoaudio.c
@@ -2250,6 +2250,8 @@ static int snd_echo_resume(struct pci_dev *pci)
2250 DE_INIT(("resume start\n")); 2250 DE_INIT(("resume start\n"));
2251 pci_restore_state(pci); 2251 pci_restore_state(pci);
2252 commpage_bak = kmalloc(sizeof(struct echoaudio), GFP_KERNEL); 2252 commpage_bak = kmalloc(sizeof(struct echoaudio), GFP_KERNEL);
2253 if (commpage_bak == NULL)
2254 return -ENOMEM;
2253 commpage = chip->comm_page; 2255 commpage = chip->comm_page;
2254 memcpy(commpage_bak, commpage, sizeof(struct comm_page)); 2256 memcpy(commpage_bak, commpage, sizeof(struct comm_page));
2255 2257
diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c
index 4203782d7cb..aff8387c45c 100644
--- a/sound/pci/emu10k1/emu10k1.c
+++ b/sound/pci/emu10k1/emu10k1.c
@@ -52,6 +52,7 @@ static int max_synth_voices[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 64};
52static int max_buffer_size[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 128}; 52static int max_buffer_size[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 128};
53static int enable_ir[SNDRV_CARDS]; 53static int enable_ir[SNDRV_CARDS];
54static uint subsystem[SNDRV_CARDS]; /* Force card subsystem model */ 54static uint subsystem[SNDRV_CARDS]; /* Force card subsystem model */
55static uint delay_pcm_irq[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
55 56
56module_param_array(index, int, NULL, 0444); 57module_param_array(index, int, NULL, 0444);
57MODULE_PARM_DESC(index, "Index value for the EMU10K1 soundcard."); 58MODULE_PARM_DESC(index, "Index value for the EMU10K1 soundcard.");
@@ -73,6 +74,8 @@ module_param_array(enable_ir, bool, NULL, 0444);
73MODULE_PARM_DESC(enable_ir, "Enable IR."); 74MODULE_PARM_DESC(enable_ir, "Enable IR.");
74module_param_array(subsystem, uint, NULL, 0444); 75module_param_array(subsystem, uint, NULL, 0444);
75MODULE_PARM_DESC(subsystem, "Force card subsystem model."); 76MODULE_PARM_DESC(subsystem, "Force card subsystem model.");
77module_param_array(delay_pcm_irq, uint, NULL, 0444);
78MODULE_PARM_DESC(delay_pcm_irq, "Delay PCM interrupt by specified number of samples (default 0).");
76/* 79/*
77 * Class 0401: 1102:0008 (rev 00) Subsystem: 1102:1001 -> Audigy2 Value Model:SB0400 80 * Class 0401: 1102:0008 (rev 00) Subsystem: 1102:1001 -> Audigy2 Value Model:SB0400
78 */ 81 */
@@ -127,6 +130,7 @@ static int __devinit snd_card_emu10k1_probe(struct pci_dev *pci,
127 &emu)) < 0) 130 &emu)) < 0)
128 goto error; 131 goto error;
129 card->private_data = emu; 132 card->private_data = emu;
133 emu->delay_pcm_irq = delay_pcm_irq[dev] & 0x1f;
130 if ((err = snd_emu10k1_pcm(emu, 0, NULL)) < 0) 134 if ((err = snd_emu10k1_pcm(emu, 0, NULL)) < 0)
131 goto error; 135 goto error;
132 if ((err = snd_emu10k1_pcm_mic(emu, 1, NULL)) < 0) 136 if ((err = snd_emu10k1_pcm_mic(emu, 1, NULL)) < 0)
diff --git a/sound/pci/emu10k1/emumpu401.c b/sound/pci/emu10k1/emumpu401.c
index 8578c70c61f..bab564824ef 100644
--- a/sound/pci/emu10k1/emumpu401.c
+++ b/sound/pci/emu10k1/emumpu401.c
@@ -321,7 +321,7 @@ static struct snd_rawmidi_ops snd_emu10k1_midi_input =
321 321
322static void snd_emu10k1_midi_free(struct snd_rawmidi *rmidi) 322static void snd_emu10k1_midi_free(struct snd_rawmidi *rmidi)
323{ 323{
324 struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)rmidi->private_data; 324 struct snd_emu10k1_midi *midi = rmidi->private_data;
325 midi->interrupt = NULL; 325 midi->interrupt = NULL;
326 midi->rmidi = NULL; 326 midi->rmidi = NULL;
327} 327}
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c
index 55b83ef73c6..622bace148e 100644
--- a/sound/pci/emu10k1/emupcm.c
+++ b/sound/pci/emu10k1/emupcm.c
@@ -332,7 +332,7 @@ static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu,
332 evoice->epcm->ccca_start_addr = start_addr + ccis; 332 evoice->epcm->ccca_start_addr = start_addr + ccis;
333 if (extra) { 333 if (extra) {
334 start_addr += ccis; 334 start_addr += ccis;
335 end_addr += ccis; 335 end_addr += ccis + emu->delay_pcm_irq;
336 } 336 }
337 if (stereo && !extra) { 337 if (stereo && !extra) {
338 snd_emu10k1_ptr_write(emu, CPF, voice, CPF_STEREO_MASK); 338 snd_emu10k1_ptr_write(emu, CPF, voice, CPF_STEREO_MASK);
@@ -360,7 +360,9 @@ static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu,
360 /* Assumption that PT is already 0 so no harm overwriting */ 360 /* Assumption that PT is already 0 so no harm overwriting */
361 snd_emu10k1_ptr_write(emu, PTRX, voice, (send_amount[0] << 8) | send_amount[1]); 361 snd_emu10k1_ptr_write(emu, PTRX, voice, (send_amount[0] << 8) | send_amount[1]);
362 snd_emu10k1_ptr_write(emu, DSL, voice, end_addr | (send_amount[3] << 24)); 362 snd_emu10k1_ptr_write(emu, DSL, voice, end_addr | (send_amount[3] << 24));
363 snd_emu10k1_ptr_write(emu, PSST, voice, start_addr | (send_amount[2] << 24)); 363 snd_emu10k1_ptr_write(emu, PSST, voice,
364 (start_addr + (extra ? emu->delay_pcm_irq : 0)) |
365 (send_amount[2] << 24));
364 if (emu->card_capabilities->emu_model) 366 if (emu->card_capabilities->emu_model)
365 pitch_target = PITCH_48000; /* Disable interpolators on emu1010 card */ 367 pitch_target = PITCH_48000; /* Disable interpolators on emu1010 card */
366 else 368 else
@@ -732,6 +734,23 @@ static void snd_emu10k1_playback_stop_voice(struct snd_emu10k1 *emu, struct snd_
732 snd_emu10k1_ptr_write(emu, IP, voice, 0); 734 snd_emu10k1_ptr_write(emu, IP, voice, 0);
733} 735}
734 736
737static inline void snd_emu10k1_playback_mangle_extra(struct snd_emu10k1 *emu,
738 struct snd_emu10k1_pcm *epcm,
739 struct snd_pcm_substream *substream,
740 struct snd_pcm_runtime *runtime)
741{
742 unsigned int ptr, period_pos;
743
744 /* try to sychronize the current position for the interrupt
745 source voice */
746 period_pos = runtime->status->hw_ptr - runtime->hw_ptr_interrupt;
747 period_pos %= runtime->period_size;
748 ptr = snd_emu10k1_ptr_read(emu, CCCA, epcm->extra->number);
749 ptr &= ~0x00ffffff;
750 ptr |= epcm->ccca_start_addr + period_pos;
751 snd_emu10k1_ptr_write(emu, CCCA, epcm->extra->number, ptr);
752}
753
735static int snd_emu10k1_playback_trigger(struct snd_pcm_substream *substream, 754static int snd_emu10k1_playback_trigger(struct snd_pcm_substream *substream,
736 int cmd) 755 int cmd)
737{ 756{
@@ -753,6 +772,8 @@ static int snd_emu10k1_playback_trigger(struct snd_pcm_substream *substream,
753 /* follow thru */ 772 /* follow thru */
754 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 773 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
755 case SNDRV_PCM_TRIGGER_RESUME: 774 case SNDRV_PCM_TRIGGER_RESUME:
775 if (cmd == SNDRV_PCM_TRIGGER_PAUSE_RELEASE)
776 snd_emu10k1_playback_mangle_extra(emu, epcm, substream, runtime);
756 mix = &emu->pcm_mixer[substream->number]; 777 mix = &emu->pcm_mixer[substream->number];
757 snd_emu10k1_playback_prepare_voice(emu, epcm->voices[0], 1, 0, mix); 778 snd_emu10k1_playback_prepare_voice(emu, epcm->voices[0], 1, 0, mix);
758 snd_emu10k1_playback_prepare_voice(emu, epcm->voices[1], 0, 0, mix); 779 snd_emu10k1_playback_prepare_voice(emu, epcm->voices[1], 0, 0, mix);
@@ -869,8 +890,9 @@ static snd_pcm_uframes_t snd_emu10k1_playback_pointer(struct snd_pcm_substream *
869#endif 890#endif
870 /* 891 /*
871 printk(KERN_DEBUG 892 printk(KERN_DEBUG
872 "ptr = 0x%x, buffer_size = 0x%x, period_size = 0x%x\n", 893 "ptr = 0x%lx, buffer_size = 0x%lx, period_size = 0x%lx\n",
873 ptr, runtime->buffer_size, runtime->period_size); 894 (long)ptr, (long)runtime->buffer_size,
895 (long)runtime->period_size);
874 */ 896 */
875 return ptr; 897 return ptr;
876} 898}
diff --git a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c
index ffb1ddb8dc2..957a311514c 100644
--- a/sound/pci/emu10k1/memory.c
+++ b/sound/pci/emu10k1/memory.c
@@ -310,8 +310,10 @@ snd_emu10k1_alloc_pages(struct snd_emu10k1 *emu, struct snd_pcm_substream *subst
310 if (snd_BUG_ON(!hdr)) 310 if (snd_BUG_ON(!hdr))
311 return NULL; 311 return NULL;
312 312
313 idx = runtime->period_size >= runtime->buffer_size ?
314 (emu->delay_pcm_irq * 2) : 0;
313 mutex_lock(&hdr->block_mutex); 315 mutex_lock(&hdr->block_mutex);
314 blk = search_empty(emu, runtime->dma_bytes); 316 blk = search_empty(emu, runtime->dma_bytes + idx);
315 if (blk == NULL) { 317 if (blk == NULL) {
316 mutex_unlock(&hdr->block_mutex); 318 mutex_unlock(&hdr->block_mutex);
317 return NULL; 319 return NULL;
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index ba2098d20cc..14829210ef0 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -396,15 +396,18 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
396 } 396 }
397 for (n = prev_nid + 1; n <= val; n++) { 397 for (n = prev_nid + 1; n <= val; n++) {
398 if (conns >= max_conns) { 398 if (conns >= max_conns) {
399 snd_printk(KERN_ERR 399 snd_printk(KERN_ERR "hda_codec: "
400 "Too many connections\n"); 400 "Too many connections %d for NID 0x%x\n",
401 conns, nid);
401 return -EINVAL; 402 return -EINVAL;
402 } 403 }
403 conn_list[conns++] = n; 404 conn_list[conns++] = n;
404 } 405 }
405 } else { 406 } else {
406 if (conns >= max_conns) { 407 if (conns >= max_conns) {
407 snd_printk(KERN_ERR "Too many connections\n"); 408 snd_printk(KERN_ERR "hda_codec: "
409 "Too many connections %d for NID 0x%x\n",
410 conns, nid);
408 return -EINVAL; 411 return -EINVAL;
409 } 412 }
410 conn_list[conns++] = val; 413 conn_list[conns++] = val;
@@ -586,6 +589,7 @@ int /*__devinit*/ snd_hda_bus_new(struct snd_card *card,
586 bus->ops = temp->ops; 589 bus->ops = temp->ops;
587 590
588 mutex_init(&bus->cmd_mutex); 591 mutex_init(&bus->cmd_mutex);
592 mutex_init(&bus->prepare_mutex);
589 INIT_LIST_HEAD(&bus->codec_list); 593 INIT_LIST_HEAD(&bus->codec_list);
590 594
591 snprintf(bus->workq_name, sizeof(bus->workq_name), 595 snprintf(bus->workq_name, sizeof(bus->workq_name),
@@ -730,15 +734,17 @@ static void /*__devinit*/ setup_fg_nodes(struct hda_codec *codec)
730 total_nodes = snd_hda_get_sub_nodes(codec, AC_NODE_ROOT, &nid); 734 total_nodes = snd_hda_get_sub_nodes(codec, AC_NODE_ROOT, &nid);
731 for (i = 0; i < total_nodes; i++, nid++) { 735 for (i = 0; i < total_nodes; i++, nid++) {
732 function_id = snd_hda_param_read(codec, nid, 736 function_id = snd_hda_param_read(codec, nid,
733 AC_PAR_FUNCTION_TYPE) & 0xff; 737 AC_PAR_FUNCTION_TYPE);
734 switch (function_id) { 738 switch (function_id & 0xff) {
735 case AC_GRP_AUDIO_FUNCTION: 739 case AC_GRP_AUDIO_FUNCTION:
736 codec->afg = nid; 740 codec->afg = nid;
737 codec->function_id = function_id; 741 codec->afg_function_id = function_id & 0xff;
742 codec->afg_unsol = (function_id >> 8) & 1;
738 break; 743 break;
739 case AC_GRP_MODEM_FUNCTION: 744 case AC_GRP_MODEM_FUNCTION:
740 codec->mfg = nid; 745 codec->mfg = nid;
741 codec->function_id = function_id; 746 codec->mfg_function_id = function_id & 0xff;
747 codec->mfg_unsol = (function_id >> 8) & 1;
742 break; 748 break;
743 default: 749 default:
744 break; 750 break;
@@ -966,6 +972,36 @@ static void restore_init_pincfgs(struct hda_codec *codec)
966} 972}
967 973
968/* 974/*
975 * audio-converter setup caches
976 */
977struct hda_cvt_setup {
978 hda_nid_t nid;
979 u8 stream_tag;
980 u8 channel_id;
981 u16 format_id;
982 unsigned char active; /* cvt is currently used */
983 unsigned char dirty; /* setups should be cleared */
984};
985
986/* get or create a cache entry for the given audio converter NID */
987static struct hda_cvt_setup *
988get_hda_cvt_setup(struct hda_codec *codec, hda_nid_t nid)
989{
990 struct hda_cvt_setup *p;
991 int i;
992
993 for (i = 0; i < codec->cvt_setups.used; i++) {
994 p = snd_array_elem(&codec->cvt_setups, i);
995 if (p->nid == nid)
996 return p;
997 }
998 p = snd_array_new(&codec->cvt_setups);
999 if (p)
1000 p->nid = nid;
1001 return p;
1002}
1003
1004/*
969 * codec destructor 1005 * codec destructor
970 */ 1006 */
971static void snd_hda_codec_free(struct hda_codec *codec) 1007static void snd_hda_codec_free(struct hda_codec *codec)
@@ -1039,6 +1075,7 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus,
1039 snd_array_init(&codec->nids, sizeof(struct hda_nid_item), 32); 1075 snd_array_init(&codec->nids, sizeof(struct hda_nid_item), 32);
1040 snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16); 1076 snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16);
1041 snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16); 1077 snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16);
1078 snd_array_init(&codec->cvt_setups, sizeof(struct hda_cvt_setup), 8);
1042 if (codec->bus->modelname) { 1079 if (codec->bus->modelname) {
1043 codec->modelname = kstrdup(codec->bus->modelname, GFP_KERNEL); 1080 codec->modelname = kstrdup(codec->bus->modelname, GFP_KERNEL);
1044 if (!codec->modelname) { 1081 if (!codec->modelname) {
@@ -1176,37 +1213,126 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid,
1176 u32 stream_tag, 1213 u32 stream_tag,
1177 int channel_id, int format) 1214 int channel_id, int format)
1178{ 1215{
1216 struct hda_codec *c;
1217 struct hda_cvt_setup *p;
1218 unsigned int oldval, newval;
1219 int i;
1220
1179 if (!nid) 1221 if (!nid)
1180 return; 1222 return;
1181 1223
1182 snd_printdd("hda_codec_setup_stream: " 1224 snd_printdd("hda_codec_setup_stream: "
1183 "NID=0x%x, stream=0x%x, channel=%d, format=0x%x\n", 1225 "NID=0x%x, stream=0x%x, channel=%d, format=0x%x\n",
1184 nid, stream_tag, channel_id, format); 1226 nid, stream_tag, channel_id, format);
1185 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CHANNEL_STREAMID, 1227 p = get_hda_cvt_setup(codec, nid);
1186 (stream_tag << 4) | channel_id); 1228 if (!p)
1187 msleep(1); 1229 return;
1188 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, format); 1230 /* update the stream-id if changed */
1231 if (p->stream_tag != stream_tag || p->channel_id != channel_id) {
1232 oldval = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0);
1233 newval = (stream_tag << 4) | channel_id;
1234 if (oldval != newval)
1235 snd_hda_codec_write(codec, nid, 0,
1236 AC_VERB_SET_CHANNEL_STREAMID,
1237 newval);
1238 p->stream_tag = stream_tag;
1239 p->channel_id = channel_id;
1240 }
1241 /* update the format-id if changed */
1242 if (p->format_id != format) {
1243 oldval = snd_hda_codec_read(codec, nid, 0,
1244 AC_VERB_GET_STREAM_FORMAT, 0);
1245 if (oldval != format) {
1246 msleep(1);
1247 snd_hda_codec_write(codec, nid, 0,
1248 AC_VERB_SET_STREAM_FORMAT,
1249 format);
1250 }
1251 p->format_id = format;
1252 }
1253 p->active = 1;
1254 p->dirty = 0;
1255
1256 /* make other inactive cvts with the same stream-tag dirty */
1257 list_for_each_entry(c, &codec->bus->codec_list, list) {
1258 for (i = 0; i < c->cvt_setups.used; i++) {
1259 p = snd_array_elem(&c->cvt_setups, i);
1260 if (!p->active && p->stream_tag == stream_tag)
1261 p->dirty = 1;
1262 }
1263 }
1189} 1264}
1190EXPORT_SYMBOL_HDA(snd_hda_codec_setup_stream); 1265EXPORT_SYMBOL_HDA(snd_hda_codec_setup_stream);
1191 1266
1267static void really_cleanup_stream(struct hda_codec *codec,
1268 struct hda_cvt_setup *q);
1269
1192/** 1270/**
1193 * snd_hda_codec_cleanup_stream - clean up the codec for closing 1271 * __snd_hda_codec_cleanup_stream - clean up the codec for closing
1194 * @codec: the CODEC to clean up 1272 * @codec: the CODEC to clean up
1195 * @nid: the NID to clean up 1273 * @nid: the NID to clean up
1274 * @do_now: really clean up the stream instead of clearing the active flag
1196 */ 1275 */
1197void snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid) 1276void __snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid,
1277 int do_now)
1198{ 1278{
1279 struct hda_cvt_setup *p;
1280
1199 if (!nid) 1281 if (!nid)
1200 return; 1282 return;
1201 1283
1202 snd_printdd("hda_codec_cleanup_stream: NID=0x%x\n", nid); 1284 snd_printdd("hda_codec_cleanup_stream: NID=0x%x\n", nid);
1285 p = get_hda_cvt_setup(codec, nid);
1286 if (p) {
1287 /* here we just clear the active flag when do_now isn't set;
1288 * actual clean-ups will be done later in
1289 * purify_inactive_streams() called from snd_hda_codec_prpapre()
1290 */
1291 if (do_now)
1292 really_cleanup_stream(codec, p);
1293 else
1294 p->active = 0;
1295 }
1296}
1297EXPORT_SYMBOL_HDA(__snd_hda_codec_cleanup_stream);
1298
1299static void really_cleanup_stream(struct hda_codec *codec,
1300 struct hda_cvt_setup *q)
1301{
1302 hda_nid_t nid = q->nid;
1203 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CHANNEL_STREAMID, 0); 1303 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CHANNEL_STREAMID, 0);
1204#if 0 /* keep the format */
1205 msleep(1);
1206 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, 0); 1304 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, 0);
1207#endif 1305 memset(q, 0, sizeof(*q));
1306 q->nid = nid;
1307}
1308
1309/* clean up the all conflicting obsolete streams */
1310static void purify_inactive_streams(struct hda_codec *codec)
1311{
1312 struct hda_codec *c;
1313 int i;
1314
1315 list_for_each_entry(c, &codec->bus->codec_list, list) {
1316 for (i = 0; i < c->cvt_setups.used; i++) {
1317 struct hda_cvt_setup *p;
1318 p = snd_array_elem(&c->cvt_setups, i);
1319 if (p->dirty)
1320 really_cleanup_stream(c, p);
1321 }
1322 }
1323}
1324
1325/* clean up all streams; called from suspend */
1326static void hda_cleanup_all_streams(struct hda_codec *codec)
1327{
1328 int i;
1329
1330 for (i = 0; i < codec->cvt_setups.used; i++) {
1331 struct hda_cvt_setup *p = snd_array_elem(&codec->cvt_setups, i);
1332 if (p->stream_tag)
1333 really_cleanup_stream(codec, p);
1334 }
1208} 1335}
1209EXPORT_SYMBOL_HDA(snd_hda_codec_cleanup_stream);
1210 1336
1211/* 1337/*
1212 * amp access functions 1338 * amp access functions
@@ -1565,6 +1691,17 @@ void snd_hda_codec_resume_amp(struct hda_codec *codec)
1565EXPORT_SYMBOL_HDA(snd_hda_codec_resume_amp); 1691EXPORT_SYMBOL_HDA(snd_hda_codec_resume_amp);
1566#endif /* SND_HDA_NEEDS_RESUME */ 1692#endif /* SND_HDA_NEEDS_RESUME */
1567 1693
1694static u32 get_amp_max_value(struct hda_codec *codec, hda_nid_t nid, int dir,
1695 unsigned int ofs)
1696{
1697 u32 caps = query_amp_caps(codec, nid, dir);
1698 /* get num steps */
1699 caps = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT;
1700 if (ofs < caps)
1701 caps -= ofs;
1702 return caps;
1703}
1704
1568/** 1705/**
1569 * snd_hda_mixer_amp_volume_info - Info callback for a standard AMP mixer 1706 * snd_hda_mixer_amp_volume_info - Info callback for a standard AMP mixer
1570 * 1707 *
@@ -1579,23 +1716,17 @@ int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol,
1579 u8 chs = get_amp_channels(kcontrol); 1716 u8 chs = get_amp_channels(kcontrol);
1580 int dir = get_amp_direction(kcontrol); 1717 int dir = get_amp_direction(kcontrol);
1581 unsigned int ofs = get_amp_offset(kcontrol); 1718 unsigned int ofs = get_amp_offset(kcontrol);
1582 u32 caps;
1583 1719
1584 caps = query_amp_caps(codec, nid, dir); 1720 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1585 /* num steps */ 1721 uinfo->count = chs == 3 ? 2 : 1;
1586 caps = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT; 1722 uinfo->value.integer.min = 0;
1587 if (!caps) { 1723 uinfo->value.integer.max = get_amp_max_value(codec, nid, dir, ofs);
1724 if (!uinfo->value.integer.max) {
1588 printk(KERN_WARNING "hda_codec: " 1725 printk(KERN_WARNING "hda_codec: "
1589 "num_steps = 0 for NID=0x%x (ctl = %s)\n", nid, 1726 "num_steps = 0 for NID=0x%x (ctl = %s)\n", nid,
1590 kcontrol->id.name); 1727 kcontrol->id.name);
1591 return -EINVAL; 1728 return -EINVAL;
1592 } 1729 }
1593 if (ofs < caps)
1594 caps -= ofs;
1595 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1596 uinfo->count = chs == 3 ? 2 : 1;
1597 uinfo->value.integer.min = 0;
1598 uinfo->value.integer.max = caps;
1599 return 0; 1730 return 0;
1600} 1731}
1601EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_volume_info); 1732EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_volume_info);
@@ -1620,8 +1751,14 @@ update_amp_value(struct hda_codec *codec, hda_nid_t nid,
1620 int ch, int dir, int idx, unsigned int ofs, 1751 int ch, int dir, int idx, unsigned int ofs,
1621 unsigned int val) 1752 unsigned int val)
1622{ 1753{
1754 unsigned int maxval;
1755
1623 if (val > 0) 1756 if (val > 0)
1624 val += ofs; 1757 val += ofs;
1758 /* ofs = 0: raw max value */
1759 maxval = get_amp_max_value(codec, nid, dir, 0);
1760 if (val > maxval)
1761 val = maxval;
1625 return snd_hda_codec_amp_update(codec, nid, ch, dir, idx, 1762 return snd_hda_codec_amp_update(codec, nid, ch, dir, idx,
1626 HDA_AMP_VOLMASK, val); 1763 HDA_AMP_VOLMASK, val);
1627} 1764}
@@ -2912,6 +3049,7 @@ static void hda_call_codec_suspend(struct hda_codec *codec)
2912{ 3049{
2913 if (codec->patch_ops.suspend) 3050 if (codec->patch_ops.suspend)
2914 codec->patch_ops.suspend(codec, PMSG_SUSPEND); 3051 codec->patch_ops.suspend(codec, PMSG_SUSPEND);
3052 hda_cleanup_all_streams(codec);
2915 hda_set_power_state(codec, 3053 hda_set_power_state(codec,
2916 codec->afg ? codec->afg : codec->mfg, 3054 codec->afg ? codec->afg : codec->mfg,
2917 AC_PWRST_D3); 3055 AC_PWRST_D3);
@@ -2999,26 +3137,31 @@ struct hda_rate_tbl {
2999 unsigned int hda_fmt; 3137 unsigned int hda_fmt;
3000}; 3138};
3001 3139
3140/* rate = base * mult / div */
3141#define HDA_RATE(base, mult, div) \
3142 (AC_FMT_BASE_##base##K | (((mult) - 1) << AC_FMT_MULT_SHIFT) | \
3143 (((div) - 1) << AC_FMT_DIV_SHIFT))
3144
3002static struct hda_rate_tbl rate_bits[] = { 3145static struct hda_rate_tbl rate_bits[] = {
3003 /* rate in Hz, ALSA rate bitmask, HDA format value */ 3146 /* rate in Hz, ALSA rate bitmask, HDA format value */
3004 3147
3005 /* autodetected value used in snd_hda_query_supported_pcm */ 3148 /* autodetected value used in snd_hda_query_supported_pcm */
3006 { 8000, SNDRV_PCM_RATE_8000, 0x0500 }, /* 1/6 x 48 */ 3149 { 8000, SNDRV_PCM_RATE_8000, HDA_RATE(48, 1, 6) },
3007 { 11025, SNDRV_PCM_RATE_11025, 0x4300 }, /* 1/4 x 44 */ 3150 { 11025, SNDRV_PCM_RATE_11025, HDA_RATE(44, 1, 4) },
3008 { 16000, SNDRV_PCM_RATE_16000, 0x0200 }, /* 1/3 x 48 */ 3151 { 16000, SNDRV_PCM_RATE_16000, HDA_RATE(48, 1, 3) },
3009 { 22050, SNDRV_PCM_RATE_22050, 0x4100 }, /* 1/2 x 44 */ 3152 { 22050, SNDRV_PCM_RATE_22050, HDA_RATE(44, 1, 2) },
3010 { 32000, SNDRV_PCM_RATE_32000, 0x0a00 }, /* 2/3 x 48 */ 3153 { 32000, SNDRV_PCM_RATE_32000, HDA_RATE(48, 2, 3) },
3011 { 44100, SNDRV_PCM_RATE_44100, 0x4000 }, /* 44 */ 3154 { 44100, SNDRV_PCM_RATE_44100, HDA_RATE(44, 1, 1) },
3012 { 48000, SNDRV_PCM_RATE_48000, 0x0000 }, /* 48 */ 3155 { 48000, SNDRV_PCM_RATE_48000, HDA_RATE(48, 1, 1) },
3013 { 88200, SNDRV_PCM_RATE_88200, 0x4800 }, /* 2 x 44 */ 3156 { 88200, SNDRV_PCM_RATE_88200, HDA_RATE(44, 2, 1) },
3014 { 96000, SNDRV_PCM_RATE_96000, 0x0800 }, /* 2 x 48 */ 3157 { 96000, SNDRV_PCM_RATE_96000, HDA_RATE(48, 2, 1) },
3015 { 176400, SNDRV_PCM_RATE_176400, 0x5800 },/* 4 x 44 */ 3158 { 176400, SNDRV_PCM_RATE_176400, HDA_RATE(44, 4, 1) },
3016 { 192000, SNDRV_PCM_RATE_192000, 0x1800 }, /* 4 x 48 */ 3159 { 192000, SNDRV_PCM_RATE_192000, HDA_RATE(48, 4, 1) },
3017#define AC_PAR_PCM_RATE_BITS 11 3160#define AC_PAR_PCM_RATE_BITS 11
3018 /* up to bits 10, 384kHZ isn't supported properly */ 3161 /* up to bits 10, 384kHZ isn't supported properly */
3019 3162
3020 /* not autodetected value */ 3163 /* not autodetected value */
3021 { 9600, SNDRV_PCM_RATE_KNOT, 0x0400 }, /* 1/5 x 48 */ 3164 { 9600, SNDRV_PCM_RATE_KNOT, HDA_RATE(48, 1, 5) },
3022 3165
3023 { 0 } /* terminator */ 3166 { 0 } /* terminator */
3024}; 3167};
@@ -3037,7 +3180,8 @@ static struct hda_rate_tbl rate_bits[] = {
3037unsigned int snd_hda_calc_stream_format(unsigned int rate, 3180unsigned int snd_hda_calc_stream_format(unsigned int rate,
3038 unsigned int channels, 3181 unsigned int channels,
3039 unsigned int format, 3182 unsigned int format,
3040 unsigned int maxbps) 3183 unsigned int maxbps,
3184 unsigned short spdif_ctls)
3041{ 3185{
3042 int i; 3186 int i;
3043 unsigned int val = 0; 3187 unsigned int val = 0;
@@ -3060,20 +3204,20 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate,
3060 3204
3061 switch (snd_pcm_format_width(format)) { 3205 switch (snd_pcm_format_width(format)) {
3062 case 8: 3206 case 8:
3063 val |= 0x00; 3207 val |= AC_FMT_BITS_8;
3064 break; 3208 break;
3065 case 16: 3209 case 16:
3066 val |= 0x10; 3210 val |= AC_FMT_BITS_16;
3067 break; 3211 break;
3068 case 20: 3212 case 20:
3069 case 24: 3213 case 24:
3070 case 32: 3214 case 32:
3071 if (maxbps >= 32 || format == SNDRV_PCM_FORMAT_FLOAT_LE) 3215 if (maxbps >= 32 || format == SNDRV_PCM_FORMAT_FLOAT_LE)
3072 val |= 0x40; 3216 val |= AC_FMT_BITS_32;
3073 else if (maxbps >= 24) 3217 else if (maxbps >= 24)
3074 val |= 0x30; 3218 val |= AC_FMT_BITS_24;
3075 else 3219 else
3076 val |= 0x20; 3220 val |= AC_FMT_BITS_20;
3077 break; 3221 break;
3078 default: 3222 default:
3079 snd_printdd("invalid format width %d\n", 3223 snd_printdd("invalid format width %d\n",
@@ -3081,6 +3225,9 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate,
3081 return 0; 3225 return 0;
3082 } 3226 }
3083 3227
3228 if (spdif_ctls & AC_DIG1_NONAUDIO)
3229 val |= AC_FMT_TYPE_NON_PCM;
3230
3084 return val; 3231 return val;
3085} 3232}
3086EXPORT_SYMBOL_HDA(snd_hda_calc_stream_format); 3233EXPORT_SYMBOL_HDA(snd_hda_calc_stream_format);
@@ -3352,6 +3499,35 @@ static int set_pcm_default_values(struct hda_codec *codec,
3352 return 0; 3499 return 0;
3353} 3500}
3354 3501
3502/*
3503 * codec prepare/cleanup entries
3504 */
3505int snd_hda_codec_prepare(struct hda_codec *codec,
3506 struct hda_pcm_stream *hinfo,
3507 unsigned int stream,
3508 unsigned int format,
3509 struct snd_pcm_substream *substream)
3510{
3511 int ret;
3512 mutex_lock(&codec->bus->prepare_mutex);
3513 ret = hinfo->ops.prepare(hinfo, codec, stream, format, substream);
3514 if (ret >= 0)
3515 purify_inactive_streams(codec);
3516 mutex_unlock(&codec->bus->prepare_mutex);
3517 return ret;
3518}
3519EXPORT_SYMBOL_HDA(snd_hda_codec_prepare);
3520
3521void snd_hda_codec_cleanup(struct hda_codec *codec,
3522 struct hda_pcm_stream *hinfo,
3523 struct snd_pcm_substream *substream)
3524{
3525 mutex_lock(&codec->bus->prepare_mutex);
3526 hinfo->ops.cleanup(hinfo, codec, substream);
3527 mutex_unlock(&codec->bus->prepare_mutex);
3528}
3529EXPORT_SYMBOL_HDA(snd_hda_codec_cleanup);
3530
3355/* global */ 3531/* global */
3356const char *snd_hda_pcm_type_name[HDA_PCM_NTYPES] = { 3532const char *snd_hda_pcm_type_name[HDA_PCM_NTYPES] = {
3357 "Audio", "SPDIF", "HDMI", "Modem" 3533 "Audio", "SPDIF", "HDMI", "Modem"
@@ -4360,7 +4536,7 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
4360 cfg->hp_outs--; 4536 cfg->hp_outs--;
4361 memmove(cfg->hp_pins + i, cfg->hp_pins + i + 1, 4537 memmove(cfg->hp_pins + i, cfg->hp_pins + i + 1,
4362 sizeof(cfg->hp_pins[0]) * (cfg->hp_outs - i)); 4538 sizeof(cfg->hp_pins[0]) * (cfg->hp_outs - i));
4363 memmove(sequences_hp + i - 1, sequences_hp + i, 4539 memmove(sequences_hp + i, sequences_hp + i + 1,
4364 sizeof(sequences_hp[0]) * (cfg->hp_outs - i)); 4540 sizeof(sequences_hp[0]) * (cfg->hp_outs - i));
4365 } 4541 }
4366 } 4542 }
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 5991d14e1ec..62c70224010 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -224,6 +224,27 @@ enum {
224/* Input converter SDI select */ 224/* Input converter SDI select */
225#define AC_SDI_SELECT (0xf<<0) 225#define AC_SDI_SELECT (0xf<<0)
226 226
227/* stream format id */
228#define AC_FMT_CHAN_SHIFT 0
229#define AC_FMT_CHAN_MASK (0x0f << 0)
230#define AC_FMT_BITS_SHIFT 4
231#define AC_FMT_BITS_MASK (7 << 4)
232#define AC_FMT_BITS_8 (0 << 4)
233#define AC_FMT_BITS_16 (1 << 4)
234#define AC_FMT_BITS_20 (2 << 4)
235#define AC_FMT_BITS_24 (3 << 4)
236#define AC_FMT_BITS_32 (4 << 4)
237#define AC_FMT_DIV_SHIFT 8
238#define AC_FMT_DIV_MASK (7 << 8)
239#define AC_FMT_MULT_SHIFT 11
240#define AC_FMT_MULT_MASK (7 << 11)
241#define AC_FMT_BASE_SHIFT 14
242#define AC_FMT_BASE_48K (0 << 14)
243#define AC_FMT_BASE_44K (1 << 14)
244#define AC_FMT_TYPE_SHIFT 15
245#define AC_FMT_TYPE_PCM (0 << 15)
246#define AC_FMT_TYPE_NON_PCM (1 << 15)
247
227/* Unsolicited response control */ 248/* Unsolicited response control */
228#define AC_UNSOL_TAG (0x3f<<0) 249#define AC_UNSOL_TAG (0x3f<<0)
229#define AC_UNSOL_ENABLED (1<<7) 250#define AC_UNSOL_ENABLED (1<<7)
@@ -364,6 +385,9 @@ enum {
364#define AC_DIG2_CC (0x7f<<0) 385#define AC_DIG2_CC (0x7f<<0)
365 386
366/* Pin widget control - 8bit */ 387/* Pin widget control - 8bit */
388#define AC_PINCTL_EPT (0x3<<0)
389#define AC_PINCTL_EPT_NATIVE 0
390#define AC_PINCTL_EPT_HBR 3
367#define AC_PINCTL_VREFEN (0x7<<0) 391#define AC_PINCTL_VREFEN (0x7<<0)
368#define AC_PINCTL_VREF_HIZ 0 /* Hi-Z */ 392#define AC_PINCTL_VREF_HIZ 0 /* Hi-Z */
369#define AC_PINCTL_VREF_50 1 /* 50% */ 393#define AC_PINCTL_VREF_50 1 /* 50% */
@@ -624,6 +648,7 @@ struct hda_bus {
624 struct hda_codec *caddr_tbl[HDA_MAX_CODEC_ADDRESS + 1]; 648 struct hda_codec *caddr_tbl[HDA_MAX_CODEC_ADDRESS + 1];
625 649
626 struct mutex cmd_mutex; 650 struct mutex cmd_mutex;
651 struct mutex prepare_mutex;
627 652
628 /* unsolicited event queue */ 653 /* unsolicited event queue */
629 struct hda_bus_unsolicited *unsol; 654 struct hda_bus_unsolicited *unsol;
@@ -760,7 +785,10 @@ struct hda_codec {
760 hda_nid_t mfg; /* MFG node id */ 785 hda_nid_t mfg; /* MFG node id */
761 786
762 /* ids */ 787 /* ids */
763 u32 function_id; 788 u8 afg_function_id;
789 u8 mfg_function_id;
790 u8 afg_unsol;
791 u8 mfg_unsol;
764 u32 vendor_id; 792 u32 vendor_id;
765 u32 subsystem_id; 793 u32 subsystem_id;
766 u32 revision_id; 794 u32 revision_id;
@@ -805,6 +833,7 @@ struct hda_codec {
805 hda_nid_t *slave_dig_outs; /* optional digital out slave widgets */ 833 hda_nid_t *slave_dig_outs; /* optional digital out slave widgets */
806 struct snd_array init_pins; /* initial (BIOS) pin configurations */ 834 struct snd_array init_pins; /* initial (BIOS) pin configurations */
807 struct snd_array driver_pins; /* pin configs set by codec parser */ 835 struct snd_array driver_pins; /* pin configs set by codec parser */
836 struct snd_array cvt_setups; /* audio convert setups */
808 837
809#ifdef CONFIG_SND_HDA_HWDEP 838#ifdef CONFIG_SND_HDA_HWDEP
810 struct snd_hwdep *hwdep; /* assigned hwdep device */ 839 struct snd_hwdep *hwdep; /* assigned hwdep device */
@@ -921,14 +950,28 @@ int snd_hda_codec_build_controls(struct hda_codec *codec);
921 */ 950 */
922int snd_hda_build_pcms(struct hda_bus *bus); 951int snd_hda_build_pcms(struct hda_bus *bus);
923int snd_hda_codec_build_pcms(struct hda_codec *codec); 952int snd_hda_codec_build_pcms(struct hda_codec *codec);
953
954int snd_hda_codec_prepare(struct hda_codec *codec,
955 struct hda_pcm_stream *hinfo,
956 unsigned int stream,
957 unsigned int format,
958 struct snd_pcm_substream *substream);
959void snd_hda_codec_cleanup(struct hda_codec *codec,
960 struct hda_pcm_stream *hinfo,
961 struct snd_pcm_substream *substream);
962
924void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, 963void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid,
925 u32 stream_tag, 964 u32 stream_tag,
926 int channel_id, int format); 965 int channel_id, int format);
927void snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid); 966void __snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid,
967 int do_now);
968#define snd_hda_codec_cleanup_stream(codec, nid) \
969 __snd_hda_codec_cleanup_stream(codec, nid, 0)
928unsigned int snd_hda_calc_stream_format(unsigned int rate, 970unsigned int snd_hda_calc_stream_format(unsigned int rate,
929 unsigned int channels, 971 unsigned int channels,
930 unsigned int format, 972 unsigned int format,
931 unsigned int maxbps); 973 unsigned int maxbps,
974 unsigned short spdif_ctls);
932int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid, 975int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid,
933 unsigned int format); 976 unsigned int format);
934 977
diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c
index d8da18a9e98..26c3ade7358 100644
--- a/sound/pci/hda/hda_eld.c
+++ b/sound/pci/hda/hda_eld.c
@@ -597,3 +597,52 @@ void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld)
597EXPORT_SYMBOL_HDA(snd_hda_eld_proc_free); 597EXPORT_SYMBOL_HDA(snd_hda_eld_proc_free);
598 598
599#endif /* CONFIG_PROC_FS */ 599#endif /* CONFIG_PROC_FS */
600
601/* update PCM info based on ELD */
602void hdmi_eld_update_pcm_info(struct hdmi_eld *eld, struct hda_pcm_stream *pcm,
603 struct hda_pcm_stream *codec_pars)
604{
605 int i;
606
607 pcm->rates = 0;
608 pcm->formats = 0;
609 pcm->maxbps = 0;
610 pcm->channels_min = -1;
611 pcm->channels_max = 0;
612 for (i = 0; i < eld->sad_count; i++) {
613 struct cea_sad *a = &eld->sad[i];
614 pcm->rates |= a->rates;
615 if (a->channels < pcm->channels_min)
616 pcm->channels_min = a->channels;
617 if (a->channels > pcm->channels_max)
618 pcm->channels_max = a->channels;
619 if (a->format == AUDIO_CODING_TYPE_LPCM) {
620 if (a->sample_bits & AC_SUPPCM_BITS_16) {
621 pcm->formats |= SNDRV_PCM_FMTBIT_S16_LE;
622 if (pcm->maxbps < 16)
623 pcm->maxbps = 16;
624 }
625 if (a->sample_bits & AC_SUPPCM_BITS_20) {
626 pcm->formats |= SNDRV_PCM_FMTBIT_S32_LE;
627 if (pcm->maxbps < 20)
628 pcm->maxbps = 20;
629 }
630 if (a->sample_bits & AC_SUPPCM_BITS_24) {
631 pcm->formats |= SNDRV_PCM_FMTBIT_S32_LE;
632 if (pcm->maxbps < 24)
633 pcm->maxbps = 24;
634 }
635 }
636 }
637
638 if (!codec_pars)
639 return;
640
641 /* restrict the parameters by the values the codec provides */
642 pcm->rates &= codec_pars->rates;
643 pcm->formats &= codec_pars->formats;
644 pcm->channels_min = max(pcm->channels_min, codec_pars->channels_min);
645 pcm->channels_max = min(pcm->channels_max, codec_pars->channels_max);
646 pcm->maxbps = min(pcm->maxbps, codec_pars->maxbps);
647}
648EXPORT_SYMBOL_HDA(hdmi_eld_update_pcm_info);
diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c
index a1fc83753cc..bf3ced51e0f 100644
--- a/sound/pci/hda/hda_hwdep.c
+++ b/sound/pci/hda/hda_hwdep.c
@@ -649,7 +649,9 @@ static void parse_codec_mode(char *buf, struct hda_bus *bus,
649 *codecp = NULL; 649 *codecp = NULL;
650 if (sscanf(buf, "%i %i %i", &vendorid, &subid, &caddr) == 3) { 650 if (sscanf(buf, "%i %i %i", &vendorid, &subid, &caddr) == 3) {
651 list_for_each_entry(codec, &bus->codec_list, list) { 651 list_for_each_entry(codec, &bus->codec_list, list) {
652 if (codec->addr == caddr) { 652 if (codec->vendor_id == vendorid &&
653 codec->subsystem_id == subid &&
654 codec->addr == caddr) {
653 *codecp = codec; 655 *codecp = codec;
654 break; 656 break;
655 } 657 }
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 1df25cf5ce3..34940a07905 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -126,6 +126,7 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
126 "{Intel, ICH10}," 126 "{Intel, ICH10},"
127 "{Intel, PCH}," 127 "{Intel, PCH},"
128 "{Intel, CPT}," 128 "{Intel, CPT},"
129 "{Intel, PBG},"
129 "{Intel, SCH}," 130 "{Intel, SCH},"
130 "{ATI, SB450}," 131 "{ATI, SB450},"
131 "{ATI, SB600}," 132 "{ATI, SB600},"
@@ -1634,7 +1635,7 @@ static int azx_pcm_hw_free(struct snd_pcm_substream *substream)
1634 azx_dev->period_bytes = 0; 1635 azx_dev->period_bytes = 0;
1635 azx_dev->format_val = 0; 1636 azx_dev->format_val = 0;
1636 1637
1637 hinfo->ops.cleanup(hinfo, apcm->codec, substream); 1638 snd_hda_codec_cleanup(apcm->codec, hinfo, substream);
1638 1639
1639 return snd_pcm_lib_free_pages(substream); 1640 return snd_pcm_lib_free_pages(substream);
1640} 1641}
@@ -1653,7 +1654,8 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
1653 format_val = snd_hda_calc_stream_format(runtime->rate, 1654 format_val = snd_hda_calc_stream_format(runtime->rate,
1654 runtime->channels, 1655 runtime->channels,
1655 runtime->format, 1656 runtime->format,
1656 hinfo->maxbps); 1657 hinfo->maxbps,
1658 apcm->codec->spdif_ctls);
1657 if (!format_val) { 1659 if (!format_val) {
1658 snd_printk(KERN_ERR SFX 1660 snd_printk(KERN_ERR SFX
1659 "invalid format_val, rate=%d, ch=%d, format=%d\n", 1661 "invalid format_val, rate=%d, ch=%d, format=%d\n",
@@ -1687,8 +1689,8 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
1687 else 1689 else
1688 azx_dev->fifo_size = 0; 1690 azx_dev->fifo_size = 0;
1689 1691
1690 return hinfo->ops.prepare(hinfo, apcm->codec, azx_dev->stream_tag, 1692 return snd_hda_codec_prepare(apcm->codec, hinfo, azx_dev->stream_tag,
1691 azx_dev->format_val, substream); 1693 azx_dev->format_val, substream);
1692} 1694}
1693 1695
1694static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) 1696static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
@@ -1960,7 +1962,7 @@ static void azx_irq_pending_work(struct work_struct *work)
1960 spin_unlock_irq(&chip->reg_lock); 1962 spin_unlock_irq(&chip->reg_lock);
1961 if (!pending) 1963 if (!pending)
1962 return; 1964 return;
1963 cond_resched(); 1965 msleep(1);
1964 } 1966 }
1965} 1967}
1966 1968
@@ -2748,6 +2750,8 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
2748 { PCI_DEVICE(0x8086, 0x3b57), .driver_data = AZX_DRIVER_ICH }, 2750 { PCI_DEVICE(0x8086, 0x3b57), .driver_data = AZX_DRIVER_ICH },
2749 /* CPT */ 2751 /* CPT */
2750 { PCI_DEVICE(0x8086, 0x1c20), .driver_data = AZX_DRIVER_PCH }, 2752 { PCI_DEVICE(0x8086, 0x1c20), .driver_data = AZX_DRIVER_PCH },
2753 /* PBG */
2754 { PCI_DEVICE(0x8086, 0x1d20), .driver_data = AZX_DRIVER_PCH },
2751 /* SCH */ 2755 /* SCH */
2752 { PCI_DEVICE(0x8086, 0x811b), .driver_data = AZX_DRIVER_SCH }, 2756 { PCI_DEVICE(0x8086, 0x811b), .driver_data = AZX_DRIVER_SCH },
2753 /* ATI SB 450/600 */ 2757 /* ATI SB 450/600 */
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 7a97f126f6f..28ab4aead48 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -604,6 +604,8 @@ struct hdmi_eld {
604int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid); 604int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid);
605int snd_hdmi_get_eld(struct hdmi_eld *, struct hda_codec *, hda_nid_t); 605int snd_hdmi_get_eld(struct hdmi_eld *, struct hda_codec *, hda_nid_t);
606void snd_hdmi_show_eld(struct hdmi_eld *eld); 606void snd_hdmi_show_eld(struct hdmi_eld *eld);
607void hdmi_eld_update_pcm_info(struct hdmi_eld *eld, struct hda_pcm_stream *pcm,
608 struct hda_pcm_stream *codec_pars);
607 609
608#ifdef CONFIG_PROC_FS 610#ifdef CONFIG_PROC_FS
609int snd_hda_eld_proc_new(struct hda_codec *codec, struct hdmi_eld *eld, 611int snd_hda_eld_proc_new(struct hda_codec *codec, struct hdmi_eld *eld,
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
index f97d35de66c..f025200f2a6 100644
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -557,7 +557,12 @@ static void print_codec_info(struct snd_info_entry *entry,
557 else 557 else
558 snd_iprintf(buffer, "Not Set\n"); 558 snd_iprintf(buffer, "Not Set\n");
559 snd_iprintf(buffer, "Address: %d\n", codec->addr); 559 snd_iprintf(buffer, "Address: %d\n", codec->addr);
560 snd_iprintf(buffer, "Function Id: 0x%x\n", codec->function_id); 560 if (codec->afg)
561 snd_iprintf(buffer, "AFG Function Id: 0x%x (unsol %u)\n",
562 codec->afg_function_id, codec->afg_unsol);
563 if (codec->mfg)
564 snd_iprintf(buffer, "MFG Function Id: 0x%x (unsol %u)\n",
565 codec->mfg_function_id, codec->mfg_unsol);
561 snd_iprintf(buffer, "Vendor Id: 0x%08x\n", codec->vendor_id); 566 snd_iprintf(buffer, "Vendor Id: 0x%08x\n", codec->vendor_id);
562 snd_iprintf(buffer, "Subsystem Id: 0x%08x\n", codec->subsystem_id); 567 snd_iprintf(buffer, "Subsystem Id: 0x%08x\n", codec->subsystem_id);
563 snd_iprintf(buffer, "Revision Id: 0x%x\n", codec->revision_id); 568 snd_iprintf(buffer, "Revision Id: 0x%x\n", codec->revision_id);
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index afbe314a5bf..10bbbaf6ebc 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -3641,6 +3641,7 @@ static struct snd_pci_quirk ad1984_cfg_tbl[] = {
3641 /* Lenovo Thinkpad T61/X61 */ 3641 /* Lenovo Thinkpad T61/X61 */
3642 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo Thinkpad", AD1984_THINKPAD), 3642 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo Thinkpad", AD1984_THINKPAD),
3643 SND_PCI_QUIRK(0x1028, 0x0214, "Dell T3400", AD1984_DELL_DESKTOP), 3643 SND_PCI_QUIRK(0x1028, 0x0214, "Dell T3400", AD1984_DELL_DESKTOP),
3644 SND_PCI_QUIRK(0x1028, 0x0233, "Dell Latitude E6400", AD1984_DELL_DESKTOP),
3644 {} 3645 {}
3645}; 3646};
3646 3647
@@ -3662,7 +3663,12 @@ static int patch_ad1984(struct hda_codec *codec)
3662 codec->patch_ops.build_pcms = ad1984_build_pcms; 3663 codec->patch_ops.build_pcms = ad1984_build_pcms;
3663 break; 3664 break;
3664 case AD1984_THINKPAD: 3665 case AD1984_THINKPAD:
3665 spec->multiout.dig_out_nid = AD1884_SPDIF_OUT; 3666 if (codec->subsystem_id == 0x17aa20fb) {
3667 /* Thinpad X300 does not have the ability to do SPDIF,
3668 or attach to docking station to use SPDIF */
3669 spec->multiout.dig_out_nid = 0;
3670 } else
3671 spec->multiout.dig_out_nid = AD1884_SPDIF_OUT;
3666 spec->input_mux = &ad1984_thinkpad_capture_source; 3672 spec->input_mux = &ad1984_thinkpad_capture_source;
3667 spec->mixers[0] = ad1984_thinkpad_mixers; 3673 spec->mixers[0] = ad1984_thinkpad_mixers;
3668 spec->init_verbs[spec->num_init_verbs++] = ad1984_thinkpad_init_verbs; 3674 spec->init_verbs[spec->num_init_verbs++] = ad1984_thinkpad_init_verbs;
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index 350ee8ac415..488fd9ade1b 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -656,7 +656,7 @@ static int change_cur_input(struct hda_codec *codec, unsigned int idx,
656 return 0; 656 return 0;
657 if (spec->cur_adc && spec->cur_adc != spec->adc_nid[idx]) { 657 if (spec->cur_adc && spec->cur_adc != spec->adc_nid[idx]) {
658 /* stream is running, let's swap the current ADC */ 658 /* stream is running, let's swap the current ADC */
659 snd_hda_codec_cleanup_stream(codec, spec->cur_adc); 659 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
660 spec->cur_adc = spec->adc_nid[idx]; 660 spec->cur_adc = spec->adc_nid[idx];
661 snd_hda_codec_setup_stream(codec, spec->cur_adc, 661 snd_hda_codec_setup_stream(codec, spec->cur_adc,
662 spec->cur_adc_stream_tag, 0, 662 spec->cur_adc_stream_tag, 0,
@@ -972,6 +972,53 @@ static struct hda_verb cs_coef_init_verbs[] = {
972 {} /* terminator */ 972 {} /* terminator */
973}; 973};
974 974
975/* Errata: CS4207 rev C0/C1/C2 Silicon
976 *
977 * http://www.cirrus.com/en/pubs/errata/ER880C3.pdf
978 *
979 * 6. At high temperature (TA > +85°C), the digital supply current (IVD)
980 * may be excessive (up to an additional 200 μA), which is most easily
981 * observed while the part is being held in reset (RESET# active low).
982 *
983 * Root Cause: At initial powerup of the device, the logic that drives
984 * the clock and write enable to the S/PDIF SRC RAMs is not properly
985 * initialized.
986 * Certain random patterns will cause a steady leakage current in those
987 * RAM cells. The issue will resolve once the SRCs are used (turned on).
988 *
989 * Workaround: The following verb sequence briefly turns on the S/PDIF SRC
990 * blocks, which will alleviate the issue.
991 */
992
993static struct hda_verb cs_errata_init_verbs[] = {
994 {0x01, AC_VERB_SET_POWER_STATE, 0x00}, /* AFG: D0 */
995 {0x11, AC_VERB_SET_PROC_STATE, 0x01}, /* VPW: processing on */
996
997 {0x11, AC_VERB_SET_COEF_INDEX, 0x0008},
998 {0x11, AC_VERB_SET_PROC_COEF, 0x9999},
999 {0x11, AC_VERB_SET_COEF_INDEX, 0x0017},
1000 {0x11, AC_VERB_SET_PROC_COEF, 0xa412},
1001 {0x11, AC_VERB_SET_COEF_INDEX, 0x0001},
1002 {0x11, AC_VERB_SET_PROC_COEF, 0x0009},
1003
1004 {0x07, AC_VERB_SET_POWER_STATE, 0x00}, /* S/PDIF Rx: D0 */
1005 {0x08, AC_VERB_SET_POWER_STATE, 0x00}, /* S/PDIF Tx: D0 */
1006
1007 {0x11, AC_VERB_SET_COEF_INDEX, 0x0017},
1008 {0x11, AC_VERB_SET_PROC_COEF, 0x2412},
1009 {0x11, AC_VERB_SET_COEF_INDEX, 0x0008},
1010 {0x11, AC_VERB_SET_PROC_COEF, 0x0000},
1011 {0x11, AC_VERB_SET_COEF_INDEX, 0x0001},
1012 {0x11, AC_VERB_SET_PROC_COEF, 0x0008},
1013 {0x11, AC_VERB_SET_PROC_STATE, 0x00},
1014
1015 {0x07, AC_VERB_SET_POWER_STATE, 0x03}, /* S/PDIF Rx: D3 */
1016 {0x08, AC_VERB_SET_POWER_STATE, 0x03}, /* S/PDIF Tx: D3 */
1017 /*{0x01, AC_VERB_SET_POWER_STATE, 0x03},*/ /* AFG: D3 This is already handled */
1018
1019 {} /* terminator */
1020};
1021
975/* SPDIF setup */ 1022/* SPDIF setup */
976static void init_digital(struct hda_codec *codec) 1023static void init_digital(struct hda_codec *codec)
977{ 1024{
@@ -991,6 +1038,9 @@ static int cs_init(struct hda_codec *codec)
991{ 1038{
992 struct cs_spec *spec = codec->spec; 1039 struct cs_spec *spec = codec->spec;
993 1040
1041 /* init_verb sequence for C0/C1/C2 errata*/
1042 snd_hda_sequence_write(codec, cs_errata_init_verbs);
1043
994 snd_hda_sequence_write(codec, cs_coef_init_verbs); 1044 snd_hda_sequence_write(codec, cs_coef_init_verbs);
995 1045
996 if (spec->gpio_mask) { 1046 if (spec->gpio_mask) {
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 2bf2cb5da95..972e7c453b3 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -116,6 +116,7 @@ struct conexant_spec {
116 unsigned int dell_vostro:1; 116 unsigned int dell_vostro:1;
117 unsigned int ideapad:1; 117 unsigned int ideapad:1;
118 unsigned int thinkpad:1; 118 unsigned int thinkpad:1;
119 unsigned int hp_laptop:1;
119 120
120 unsigned int ext_mic_present; 121 unsigned int ext_mic_present;
121 unsigned int recording; 122 unsigned int recording;
@@ -131,6 +132,8 @@ struct conexant_spec {
131 unsigned int dc_enable; 132 unsigned int dc_enable;
132 unsigned int dc_input_bias; /* offset into cxt5066_olpc_dc_bias */ 133 unsigned int dc_input_bias; /* offset into cxt5066_olpc_dc_bias */
133 unsigned int mic_boost; /* offset into cxt5066_analog_mic_boost */ 134 unsigned int mic_boost; /* offset into cxt5066_analog_mic_boost */
135
136 unsigned int beep_amp;
134}; 137};
135 138
136static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo, 139static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo,
@@ -515,6 +518,15 @@ static struct snd_kcontrol_new cxt_capture_mixers[] = {
515 {} 518 {}
516}; 519};
517 520
521#ifdef CONFIG_SND_HDA_INPUT_BEEP
522/* additional beep mixers; the actual parameters are overwritten at build */
523static struct snd_kcontrol_new cxt_beep_mixer[] = {
524 HDA_CODEC_VOLUME_MONO("Beep Playback Volume", 0, 1, 0, HDA_OUTPUT),
525 HDA_CODEC_MUTE_BEEP_MONO("Beep Playback Switch", 0, 1, 0, HDA_OUTPUT),
526 { } /* end */
527};
528#endif
529
518static const char *slave_vols[] = { 530static const char *slave_vols[] = {
519 "Headphone Playback Volume", 531 "Headphone Playback Volume",
520 "Speaker Playback Volume", 532 "Speaker Playback Volume",
@@ -580,16 +592,52 @@ static int conexant_build_controls(struct hda_codec *codec)
580 return err; 592 return err;
581 } 593 }
582 594
595#ifdef CONFIG_SND_HDA_INPUT_BEEP
596 /* create beep controls if needed */
597 if (spec->beep_amp) {
598 struct snd_kcontrol_new *knew;
599 for (knew = cxt_beep_mixer; knew->name; knew++) {
600 struct snd_kcontrol *kctl;
601 kctl = snd_ctl_new1(knew, codec);
602 if (!kctl)
603 return -ENOMEM;
604 kctl->private_value = spec->beep_amp;
605 err = snd_hda_ctl_add(codec, 0, kctl);
606 if (err < 0)
607 return err;
608 }
609 }
610#endif
611
583 return 0; 612 return 0;
584} 613}
585 614
615#ifdef CONFIG_SND_HDA_POWER_SAVE
616static int conexant_suspend(struct hda_codec *codec, pm_message_t state)
617{
618 snd_hda_shutup_pins(codec);
619 return 0;
620}
621#endif
622
586static struct hda_codec_ops conexant_patch_ops = { 623static struct hda_codec_ops conexant_patch_ops = {
587 .build_controls = conexant_build_controls, 624 .build_controls = conexant_build_controls,
588 .build_pcms = conexant_build_pcms, 625 .build_pcms = conexant_build_pcms,
589 .init = conexant_init, 626 .init = conexant_init,
590 .free = conexant_free, 627 .free = conexant_free,
628#ifdef CONFIG_SND_HDA_POWER_SAVE
629 .suspend = conexant_suspend,
630#endif
631 .reboot_notify = snd_hda_shutup_pins,
591}; 632};
592 633
634#ifdef CONFIG_SND_HDA_INPUT_BEEP
635#define set_beep_amp(spec, nid, idx, dir) \
636 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir))
637#else
638#define set_beep_amp(spec, nid, idx, dir) /* NOP */
639#endif
640
593/* 641/*
594 * EAPD control 642 * EAPD control
595 * the private value = nid | (invert << 8) 643 * the private value = nid | (invert << 8)
@@ -1130,9 +1178,10 @@ static int patch_cxt5045(struct hda_codec *codec)
1130 spec->num_init_verbs = 1; 1178 spec->num_init_verbs = 1;
1131 spec->init_verbs[0] = cxt5045_init_verbs; 1179 spec->init_verbs[0] = cxt5045_init_verbs;
1132 spec->spdif_route = 0; 1180 spec->spdif_route = 0;
1133 spec->num_channel_mode = ARRAY_SIZE(cxt5045_modes), 1181 spec->num_channel_mode = ARRAY_SIZE(cxt5045_modes);
1134 spec->channel_mode = cxt5045_modes, 1182 spec->channel_mode = cxt5045_modes;
1135 1183
1184 set_beep_amp(spec, 0x16, 0, 1);
1136 1185
1137 codec->patch_ops = conexant_patch_ops; 1186 codec->patch_ops = conexant_patch_ops;
1138 1187
@@ -1211,6 +1260,9 @@ static int patch_cxt5045(struct hda_codec *codec)
1211 break; 1260 break;
1212 } 1261 }
1213 1262
1263 if (spec->beep_amp)
1264 snd_hda_attach_beep_device(codec, spec->beep_amp);
1265
1214 return 0; 1266 return 0;
1215} 1267}
1216 1268
@@ -1632,6 +1684,11 @@ static void cxt5051_update_speaker(struct hda_codec *codec)
1632 pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0; 1684 pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0;
1633 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 1685 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
1634 pinctl); 1686 pinctl);
1687 /* on ideapad there is an aditional speaker (subwoofer) to mute */
1688 if (spec->ideapad)
1689 snd_hda_codec_write(codec, 0x1b, 0,
1690 AC_VERB_SET_PIN_WIDGET_CONTROL,
1691 pinctl);
1635} 1692}
1636 1693
1637/* turn on/off EAPD (+ mute HP) as a master switch */ 1694/* turn on/off EAPD (+ mute HP) as a master switch */
@@ -1677,7 +1734,7 @@ static void cxt5051_portc_automic(struct hda_codec *codec)
1677 new_adc = spec->adc_nids[spec->cur_adc_idx]; 1734 new_adc = spec->adc_nids[spec->cur_adc_idx];
1678 if (spec->cur_adc && spec->cur_adc != new_adc) { 1735 if (spec->cur_adc && spec->cur_adc != new_adc) {
1679 /* stream is running, let's swap the current ADC */ 1736 /* stream is running, let's swap the current ADC */
1680 snd_hda_codec_cleanup_stream(codec, spec->cur_adc); 1737 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
1681 spec->cur_adc = new_adc; 1738 spec->cur_adc = new_adc;
1682 snd_hda_codec_setup_stream(codec, new_adc, 1739 snd_hda_codec_setup_stream(codec, new_adc,
1683 spec->cur_adc_stream_tag, 0, 1740 spec->cur_adc_stream_tag, 0,
@@ -1888,6 +1945,13 @@ static void cxt5051_init_mic_port(struct hda_codec *codec, hda_nid_t nid,
1888#endif 1945#endif
1889} 1946}
1890 1947
1948static struct hda_verb cxt5051_ideapad_init_verbs[] = {
1949 /* Subwoofer */
1950 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1951 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1952 { } /* end */
1953};
1954
1891/* initialize jack-sensing, too */ 1955/* initialize jack-sensing, too */
1892static int cxt5051_init(struct hda_codec *codec) 1956static int cxt5051_init(struct hda_codec *codec)
1893{ 1957{
@@ -1917,6 +1981,7 @@ enum {
1917 CXT5051_LENOVO_X200, /* Lenovo X200 laptop, also used for Advanced Mini Dock 250410 */ 1981 CXT5051_LENOVO_X200, /* Lenovo X200 laptop, also used for Advanced Mini Dock 250410 */
1918 CXT5051_F700, /* HP Compaq Presario F700 */ 1982 CXT5051_F700, /* HP Compaq Presario F700 */
1919 CXT5051_TOSHIBA, /* Toshiba M300 & co */ 1983 CXT5051_TOSHIBA, /* Toshiba M300 & co */
1984 CXT5051_IDEAPAD, /* Lenovo IdeaPad Y430 */
1920 CXT5051_MODELS 1985 CXT5051_MODELS
1921}; 1986};
1922 1987
@@ -1927,6 +1992,7 @@ static const char *cxt5051_models[CXT5051_MODELS] = {
1927 [CXT5051_LENOVO_X200] = "lenovo-x200", 1992 [CXT5051_LENOVO_X200] = "lenovo-x200",
1928 [CXT5051_F700] = "hp-700", 1993 [CXT5051_F700] = "hp-700",
1929 [CXT5051_TOSHIBA] = "toshiba", 1994 [CXT5051_TOSHIBA] = "toshiba",
1995 [CXT5051_IDEAPAD] = "ideapad",
1930}; 1996};
1931 1997
1932static struct snd_pci_quirk cxt5051_cfg_tbl[] = { 1998static struct snd_pci_quirk cxt5051_cfg_tbl[] = {
@@ -1938,6 +2004,7 @@ static struct snd_pci_quirk cxt5051_cfg_tbl[] = {
1938 CXT5051_LAPTOP), 2004 CXT5051_LAPTOP),
1939 SND_PCI_QUIRK(0x14f1, 0x5051, "HP Spartan 1.1", CXT5051_HP), 2005 SND_PCI_QUIRK(0x14f1, 0x5051, "HP Spartan 1.1", CXT5051_HP),
1940 SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT5051_LENOVO_X200), 2006 SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT5051_LENOVO_X200),
2007 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo IdeaPad", CXT5051_IDEAPAD),
1941 {} 2008 {}
1942}; 2009};
1943 2010
@@ -1972,6 +2039,8 @@ static int patch_cxt5051(struct hda_codec *codec)
1972 spec->cur_adc = 0; 2039 spec->cur_adc = 0;
1973 spec->cur_adc_idx = 0; 2040 spec->cur_adc_idx = 0;
1974 2041
2042 set_beep_amp(spec, 0x13, 0, HDA_OUTPUT);
2043
1975 codec->patch_ops.unsol_event = cxt5051_hp_unsol_event; 2044 codec->patch_ops.unsol_event = cxt5051_hp_unsol_event;
1976 2045
1977 board_config = snd_hda_check_board_config(codec, CXT5051_MODELS, 2046 board_config = snd_hda_check_board_config(codec, CXT5051_MODELS,
@@ -1989,6 +2058,10 @@ static int patch_cxt5051(struct hda_codec *codec)
1989 break; 2058 break;
1990 case CXT5051_LENOVO_X200: 2059 case CXT5051_LENOVO_X200:
1991 spec->init_verbs[0] = cxt5051_lenovo_x200_init_verbs; 2060 spec->init_verbs[0] = cxt5051_lenovo_x200_init_verbs;
2061 /* Thinkpad X301 does not have S/PDIF wired and no ability
2062 to use a docking station. */
2063 if (codec->subsystem_id == 0x17aa211f)
2064 spec->multiout.dig_out_nid = 0;
1992 break; 2065 break;
1993 case CXT5051_F700: 2066 case CXT5051_F700:
1994 spec->init_verbs[0] = cxt5051_f700_init_verbs; 2067 spec->init_verbs[0] = cxt5051_f700_init_verbs;
@@ -1999,8 +2072,16 @@ static int patch_cxt5051(struct hda_codec *codec)
1999 spec->mixers[0] = cxt5051_toshiba_mixers; 2072 spec->mixers[0] = cxt5051_toshiba_mixers;
2000 spec->auto_mic = AUTO_MIC_PORTB; 2073 spec->auto_mic = AUTO_MIC_PORTB;
2001 break; 2074 break;
2075 case CXT5051_IDEAPAD:
2076 spec->init_verbs[spec->num_init_verbs++] =
2077 cxt5051_ideapad_init_verbs;
2078 spec->ideapad = 1;
2079 break;
2002 } 2080 }
2003 2081
2082 if (spec->beep_amp)
2083 snd_hda_attach_beep_device(codec, spec->beep_amp);
2084
2004 return 0; 2085 return 0;
2005} 2086}
2006 2087
@@ -2219,6 +2300,18 @@ static void cxt5066_ideapad_automic(struct hda_codec *codec)
2219 } 2300 }
2220} 2301}
2221 2302
2303/* toggle input of built-in digital mic and mic jack appropriately */
2304static void cxt5066_hp_laptop_automic(struct hda_codec *codec)
2305{
2306 unsigned int present;
2307
2308 present = snd_hda_jack_detect(codec, 0x1b);
2309 snd_printdd("CXT5066: external microphone present=%d\n", present);
2310 snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_CONNECT_SEL,
2311 present ? 1 : 3);
2312}
2313
2314
2222/* toggle input of built-in digital mic and mic jack appropriately 2315/* toggle input of built-in digital mic and mic jack appropriately
2223 order is: external mic -> dock mic -> interal mic */ 2316 order is: external mic -> dock mic -> interal mic */
2224static void cxt5066_thinkpad_automic(struct hda_codec *codec) 2317static void cxt5066_thinkpad_automic(struct hda_codec *codec)
@@ -2328,6 +2421,20 @@ static void cxt5066_ideapad_event(struct hda_codec *codec, unsigned int res)
2328} 2421}
2329 2422
2330/* unsolicited event for jack sensing */ 2423/* unsolicited event for jack sensing */
2424static void cxt5066_hp_laptop_event(struct hda_codec *codec, unsigned int res)
2425{
2426 snd_printdd("CXT5066_hp_laptop: unsol event %x (%x)\n", res, res >> 26);
2427 switch (res >> 26) {
2428 case CONEXANT_HP_EVENT:
2429 cxt5066_hp_automute(codec);
2430 break;
2431 case CONEXANT_MIC_EVENT:
2432 cxt5066_hp_laptop_automic(codec);
2433 break;
2434 }
2435}
2436
2437/* unsolicited event for jack sensing */
2331static void cxt5066_thinkpad_event(struct hda_codec *codec, unsigned int res) 2438static void cxt5066_thinkpad_event(struct hda_codec *codec, unsigned int res)
2332{ 2439{
2333 snd_printdd("CXT5066_thinkpad: unsol event %x (%x)\n", res, res >> 26); 2440 snd_printdd("CXT5066_thinkpad: unsol event %x (%x)\n", res, res >> 26);
@@ -2616,7 +2723,6 @@ static struct snd_kcontrol_new cxt5066_vostro_mixers[] = {
2616 .put = cxt5066_mic_boost_mux_enum_put, 2723 .put = cxt5066_mic_boost_mux_enum_put,
2617 .private_value = 0x23 | 0x100, 2724 .private_value = 0x23 | 0x100,
2618 }, 2725 },
2619 HDA_CODEC_VOLUME_MONO("Beep Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
2620 {} 2726 {}
2621}; 2727};
2622 2728
@@ -2910,6 +3016,14 @@ static struct hda_verb cxt5066_init_verbs_portd_lo[] = {
2910 { } /* end */ 3016 { } /* end */
2911}; 3017};
2912 3018
3019
3020static struct hda_verb cxt5066_init_verbs_hp_laptop[] = {
3021 {0x14, AC_VERB_SET_CONNECT_SEL, 0x0},
3022 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
3023 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
3024 { } /* end */
3025};
3026
2913/* initialize jack-sensing, too */ 3027/* initialize jack-sensing, too */
2914static int cxt5066_init(struct hda_codec *codec) 3028static int cxt5066_init(struct hda_codec *codec)
2915{ 3029{
@@ -2925,6 +3039,8 @@ static int cxt5066_init(struct hda_codec *codec)
2925 cxt5066_ideapad_automic(codec); 3039 cxt5066_ideapad_automic(codec);
2926 else if (spec->thinkpad) 3040 else if (spec->thinkpad)
2927 cxt5066_thinkpad_automic(codec); 3041 cxt5066_thinkpad_automic(codec);
3042 else if (spec->hp_laptop)
3043 cxt5066_hp_laptop_automic(codec);
2928 } 3044 }
2929 cxt5066_set_mic_boost(codec); 3045 cxt5066_set_mic_boost(codec);
2930 return 0; 3046 return 0;
@@ -2952,6 +3068,7 @@ enum {
2952 CXT5066_DELL_VOSTO, /* Dell Vostro 1015i */ 3068 CXT5066_DELL_VOSTO, /* Dell Vostro 1015i */
2953 CXT5066_IDEAPAD, /* Lenovo IdeaPad U150 */ 3069 CXT5066_IDEAPAD, /* Lenovo IdeaPad U150 */
2954 CXT5066_THINKPAD, /* Lenovo ThinkPad T410s, others? */ 3070 CXT5066_THINKPAD, /* Lenovo ThinkPad T410s, others? */
3071 CXT5066_HP_LAPTOP, /* HP Laptop */
2955 CXT5066_MODELS 3072 CXT5066_MODELS
2956}; 3073};
2957 3074
@@ -2962,6 +3079,7 @@ static const char *cxt5066_models[CXT5066_MODELS] = {
2962 [CXT5066_DELL_VOSTO] = "dell-vostro", 3079 [CXT5066_DELL_VOSTO] = "dell-vostro",
2963 [CXT5066_IDEAPAD] = "ideapad", 3080 [CXT5066_IDEAPAD] = "ideapad",
2964 [CXT5066_THINKPAD] = "thinkpad", 3081 [CXT5066_THINKPAD] = "thinkpad",
3082 [CXT5066_HP_LAPTOP] = "hp-laptop",
2965}; 3083};
2966 3084
2967static struct snd_pci_quirk cxt5066_cfg_tbl[] = { 3085static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
@@ -2970,15 +3088,22 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
2970 SND_PCI_QUIRK(0x1028, 0x02f5, "Dell", 3088 SND_PCI_QUIRK(0x1028, 0x02f5, "Dell",
2971 CXT5066_DELL_LAPTOP), 3089 CXT5066_DELL_LAPTOP),
2972 SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5), 3090 SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5),
3091 SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTO),
2973 SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTO), 3092 SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTO),
2974 SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD), 3093 SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD),
3094 SND_PCI_QUIRK(0x103c, 0x360b, "HP G60", CXT5066_HP_LAPTOP),
3095 SND_PCI_QUIRK(0x1179, 0xff1e, "Toshiba Satellite C650D", CXT5066_IDEAPAD),
2975 SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5), 3096 SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5),
2976 SND_PCI_QUIRK(0x1179, 0xffe0, "Toshiba Satellite Pro T130-15F", CXT5066_OLPC_XO_1_5), 3097 SND_PCI_QUIRK(0x1179, 0xffe0, "Toshiba Satellite Pro T130-15F", CXT5066_OLPC_XO_1_5),
3098 SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400s", CXT5066_THINKPAD),
2977 SND_PCI_QUIRK(0x17aa, 0x21b2, "Thinkpad X100e", CXT5066_IDEAPAD), 3099 SND_PCI_QUIRK(0x17aa, 0x21b2, "Thinkpad X100e", CXT5066_IDEAPAD),
2978 SND_PCI_QUIRK(0x17aa, 0x21b3, "Thinkpad Edge 13 (197)", CXT5066_IDEAPAD), 3100 SND_PCI_QUIRK(0x17aa, 0x21b3, "Thinkpad Edge 13 (197)", CXT5066_IDEAPAD),
2979 SND_PCI_QUIRK(0x17aa, 0x21b4, "Thinkpad Edge", CXT5066_IDEAPAD), 3101 SND_PCI_QUIRK(0x17aa, 0x21b4, "Thinkpad Edge", CXT5066_IDEAPAD),
3102 SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD),
3103 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G series", CXT5066_IDEAPAD),
3104 SND_PCI_QUIRK(0x17aa, 0x390a, "Lenovo S10-3t", CXT5066_IDEAPAD),
3105 SND_PCI_QUIRK(0x17aa, 0x3938, "Lenovo G series (AMD)", CXT5066_IDEAPAD),
2980 SND_PCI_QUIRK(0x17aa, 0x3a0d, "ideapad", CXT5066_IDEAPAD), 3106 SND_PCI_QUIRK(0x17aa, 0x3a0d, "ideapad", CXT5066_IDEAPAD),
2981 SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD),
2982 {} 3107 {}
2983}; 3108};
2984 3109
@@ -3014,6 +3139,8 @@ static int patch_cxt5066(struct hda_codec *codec)
3014 spec->cur_adc = 0; 3139 spec->cur_adc = 0;
3015 spec->cur_adc_idx = 0; 3140 spec->cur_adc_idx = 0;
3016 3141
3142 set_beep_amp(spec, 0x13, 0, HDA_OUTPUT);
3143
3017 board_config = snd_hda_check_board_config(codec, CXT5066_MODELS, 3144 board_config = snd_hda_check_board_config(codec, CXT5066_MODELS,
3018 cxt5066_models, cxt5066_cfg_tbl); 3145 cxt5066_models, cxt5066_cfg_tbl);
3019 switch (board_config) { 3146 switch (board_config) {
@@ -3031,6 +3158,23 @@ static int patch_cxt5066(struct hda_codec *codec)
3031 spec->num_init_verbs++; 3158 spec->num_init_verbs++;
3032 spec->dell_automute = 1; 3159 spec->dell_automute = 1;
3033 break; 3160 break;
3161 case CXT5066_HP_LAPTOP:
3162 codec->patch_ops.init = cxt5066_init;
3163 codec->patch_ops.unsol_event = cxt5066_hp_laptop_event;
3164 spec->init_verbs[spec->num_init_verbs] =
3165 cxt5066_init_verbs_hp_laptop;
3166 spec->num_init_verbs++;
3167 spec->hp_laptop = 1;
3168 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
3169 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
3170 /* no S/PDIF out */
3171 spec->multiout.dig_out_nid = 0;
3172 /* input source automatically selected */
3173 spec->input_mux = NULL;
3174 spec->port_d_mode = 0;
3175 spec->mic_boost = 3; /* default 30dB gain */
3176 break;
3177
3034 case CXT5066_OLPC_XO_1_5: 3178 case CXT5066_OLPC_XO_1_5:
3035 codec->patch_ops.init = cxt5066_olpc_init; 3179 codec->patch_ops.init = cxt5066_olpc_init;
3036 codec->patch_ops.unsol_event = cxt5066_olpc_unsol_event; 3180 codec->patch_ops.unsol_event = cxt5066_olpc_unsol_event;
@@ -3062,7 +3206,6 @@ static int patch_cxt5066(struct hda_codec *codec)
3062 spec->port_d_mode = 0; 3206 spec->port_d_mode = 0;
3063 spec->dell_vostro = 1; 3207 spec->dell_vostro = 1;
3064 spec->mic_boost = 3; /* default 30dB gain */ 3208 spec->mic_boost = 3; /* default 30dB gain */
3065 snd_hda_attach_beep_device(codec, 0x13);
3066 3209
3067 /* no S/PDIF out */ 3210 /* no S/PDIF out */
3068 spec->multiout.dig_out_nid = 0; 3211 spec->multiout.dig_out_nid = 0;
@@ -3104,6 +3247,9 @@ static int patch_cxt5066(struct hda_codec *codec)
3104 break; 3247 break;
3105 } 3248 }
3106 3249
3250 if (spec->beep_amp)
3251 snd_hda_attach_beep_device(codec, spec->beep_amp);
3252
3107 return 0; 3253 return 0;
3108} 3254}
3109 3255
@@ -3121,6 +3267,8 @@ static struct hda_codec_preset snd_hda_preset_conexant[] = {
3121 .patch = patch_cxt5066 }, 3267 .patch = patch_cxt5066 },
3122 { .id = 0x14f15067, .name = "CX20583 (Pebble HSF)", 3268 { .id = 0x14f15067, .name = "CX20583 (Pebble HSF)",
3123 .patch = patch_cxt5066 }, 3269 .patch = patch_cxt5066 },
3270 { .id = 0x14f15068, .name = "CX20584",
3271 .patch = patch_cxt5066 },
3124 { .id = 0x14f15069, .name = "CX20585", 3272 { .id = 0x14f15069, .name = "CX20585",
3125 .patch = patch_cxt5066 }, 3273 .patch = patch_cxt5066 },
3126 {} /* terminator */ 3274 {} /* terminator */
@@ -3131,6 +3279,7 @@ MODULE_ALIAS("snd-hda-codec-id:14f15047");
3131MODULE_ALIAS("snd-hda-codec-id:14f15051"); 3279MODULE_ALIAS("snd-hda-codec-id:14f15051");
3132MODULE_ALIAS("snd-hda-codec-id:14f15066"); 3280MODULE_ALIAS("snd-hda-codec-id:14f15066");
3133MODULE_ALIAS("snd-hda-codec-id:14f15067"); 3281MODULE_ALIAS("snd-hda-codec-id:14f15067");
3282MODULE_ALIAS("snd-hda-codec-id:14f15068");
3134MODULE_ALIAS("snd-hda-codec-id:14f15069"); 3283MODULE_ALIAS("snd-hda-codec-id:14f15069");
3135 3284
3136MODULE_LICENSE("GPL"); 3285MODULE_LICENSE("GPL");
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 2fc53961054..afd6022a96a 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -46,6 +46,7 @@ struct hdmi_spec {
46 * export one pcm per pipe 46 * export one pcm per pipe
47 */ 47 */
48 struct hda_pcm pcm_rec[MAX_HDMI_CVTS]; 48 struct hda_pcm pcm_rec[MAX_HDMI_CVTS];
49 struct hda_pcm_stream codec_pcm_pars[MAX_HDMI_CVTS];
49 50
50 /* 51 /*
51 * nvhdmi specific 52 * nvhdmi specific
@@ -698,30 +699,93 @@ static void hdmi_unsol_event(struct hda_codec *codec, unsigned int res)
698 * Callbacks 699 * Callbacks
699 */ 700 */
700 701
701static void hdmi_setup_stream(struct hda_codec *codec, hda_nid_t nid, 702/* HBR should be Non-PCM, 8 channels */
703#define is_hbr_format(format) \
704 ((format & AC_FMT_TYPE_NON_PCM) && (format & AC_FMT_CHAN_MASK) == 7)
705
706static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t nid,
702 u32 stream_tag, int format) 707 u32 stream_tag, int format)
703{ 708{
704 int tag; 709 struct hdmi_spec *spec = codec->spec;
705 int fmt; 710 int pinctl;
711 int new_pinctl = 0;
712 int i;
713
714 for (i = 0; i < spec->num_pins; i++) {
715 if (spec->pin_cvt[i] != nid)
716 continue;
717 if (!(snd_hda_query_pin_caps(codec, spec->pin[i]) & AC_PINCAP_HBR))
718 continue;
706 719
707 tag = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0) >> 4; 720 pinctl = snd_hda_codec_read(codec, spec->pin[i], 0,
708 fmt = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_STREAM_FORMAT, 0); 721 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
722
723 new_pinctl = pinctl & ~AC_PINCTL_EPT;
724 if (is_hbr_format(format))
725 new_pinctl |= AC_PINCTL_EPT_HBR;
726 else
727 new_pinctl |= AC_PINCTL_EPT_NATIVE;
728
729 snd_printdd("hdmi_setup_stream: "
730 "NID=0x%x, %spinctl=0x%x\n",
731 spec->pin[i],
732 pinctl == new_pinctl ? "" : "new-",
733 new_pinctl);
734
735 if (pinctl != new_pinctl)
736 snd_hda_codec_write(codec, spec->pin[i], 0,
737 AC_VERB_SET_PIN_WIDGET_CONTROL,
738 new_pinctl);
739 }
709 740
710 snd_printdd("hdmi_setup_stream: " 741 if (is_hbr_format(format) && !new_pinctl) {
711 "NID=0x%x, %sstream=0x%x, %sformat=0x%x\n", 742 snd_printdd("hdmi_setup_stream: HBR is not supported\n");
712 nid, 743 return -EINVAL;
713 tag == stream_tag ? "" : "new-", 744 }
714 stream_tag,
715 fmt == format ? "" : "new-",
716 format);
717 745
718 if (tag != stream_tag) 746 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
719 snd_hda_codec_write(codec, nid, 0, 747 return 0;
720 AC_VERB_SET_CHANNEL_STREAMID, 748}
721 stream_tag << 4); 749
722 if (fmt != format) 750/*
723 snd_hda_codec_write(codec, nid, 0, 751 * HDA PCM callbacks
724 AC_VERB_SET_STREAM_FORMAT, format); 752 */
753static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
754 struct hda_codec *codec,
755 struct snd_pcm_substream *substream)
756{
757 struct hdmi_spec *spec = codec->spec;
758 struct hdmi_eld *eld;
759 struct hda_pcm_stream *codec_pars;
760 unsigned int idx;
761
762 for (idx = 0; idx < spec->num_cvts; idx++)
763 if (hinfo->nid == spec->cvt[idx])
764 break;
765 if (snd_BUG_ON(idx >= spec->num_cvts) ||
766 snd_BUG_ON(idx >= spec->num_pins))
767 return -EINVAL;
768
769 /* save the PCM info the codec provides */
770 codec_pars = &spec->codec_pcm_pars[idx];
771 if (!codec_pars->rates)
772 *codec_pars = *hinfo;
773
774 eld = &spec->sink_eld[idx];
775 if (eld->sad_count > 0) {
776 hdmi_eld_update_pcm_info(eld, hinfo, codec_pars);
777 if (hinfo->channels_min > hinfo->channels_max ||
778 !hinfo->rates || !hinfo->formats)
779 return -ENODEV;
780 } else {
781 /* fallback to the codec default */
782 hinfo->channels_min = codec_pars->channels_min;
783 hinfo->channels_max = codec_pars->channels_max;
784 hinfo->rates = codec_pars->rates;
785 hinfo->formats = codec_pars->formats;
786 hinfo->maxbps = codec_pars->maxbps;
787 }
788 return 0;
725} 789}
726 790
727/* 791/*
diff --git a/sound/pci/hda/patch_intelhdmi.c b/sound/pci/hda/patch_intelhdmi.c
index b81d23e42ac..36a9b83a617 100644
--- a/sound/pci/hda/patch_intelhdmi.c
+++ b/sound/pci/hda/patch_intelhdmi.c
@@ -66,23 +66,15 @@ static int intel_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
66 66
67 hdmi_setup_audio_infoframe(codec, hinfo->nid, substream); 67 hdmi_setup_audio_infoframe(codec, hinfo->nid, substream);
68 68
69 hdmi_setup_stream(codec, hinfo->nid, stream_tag, format); 69 return hdmi_setup_stream(codec, hinfo->nid, stream_tag, format);
70 return 0;
71}
72
73static int intel_hdmi_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
74 struct hda_codec *codec,
75 struct snd_pcm_substream *substream)
76{
77 return 0;
78} 70}
79 71
80static struct hda_pcm_stream intel_hdmi_pcm_playback = { 72static struct hda_pcm_stream intel_hdmi_pcm_playback = {
81 .substreams = 1, 73 .substreams = 1,
82 .channels_min = 2, 74 .channels_min = 2,
83 .ops = { 75 .ops = {
76 .open = hdmi_pcm_open,
84 .prepare = intel_hdmi_playback_pcm_prepare, 77 .prepare = intel_hdmi_playback_pcm_prepare,
85 .cleanup = intel_hdmi_playback_pcm_cleanup,
86 }, 78 },
87}; 79};
88 80
diff --git a/sound/pci/hda/patch_nvhdmi.c b/sound/pci/hda/patch_nvhdmi.c
index b0652acee9b..baa108b9d6a 100644
--- a/sound/pci/hda/patch_nvhdmi.c
+++ b/sound/pci/hda/patch_nvhdmi.c
@@ -84,7 +84,7 @@ static struct hda_verb nvhdmi_basic_init_7x[] = {
84#else 84#else
85/* support all rates and formats */ 85/* support all rates and formats */
86#define SUPPORTED_RATES \ 86#define SUPPORTED_RATES \
87 (SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\ 87 (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\
88 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |\ 88 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |\
89 SNDRV_PCM_RATE_192000) 89 SNDRV_PCM_RATE_192000)
90#define SUPPORTED_MAXBPS 24 90#define SUPPORTED_MAXBPS 24
@@ -202,8 +202,7 @@ static int nvhdmi_dig_playback_pcm_prepare_8ch_89(struct hda_pcm_stream *hinfo,
202 202
203 hdmi_setup_audio_infoframe(codec, hinfo->nid, substream); 203 hdmi_setup_audio_infoframe(codec, hinfo->nid, substream);
204 204
205 hdmi_setup_stream(codec, hinfo->nid, stream_tag, format); 205 return hdmi_setup_stream(codec, hinfo->nid, stream_tag, format);
206 return 0;
207} 206}
208 207
209static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo, 208static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo,
@@ -327,13 +326,6 @@ static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo,
327 return 0; 326 return 0;
328} 327}
329 328
330static int nvhdmi_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
331 struct hda_codec *codec,
332 struct snd_pcm_substream *substream)
333{
334 return 0;
335}
336
337static int nvhdmi_dig_playback_pcm_prepare_2ch(struct hda_pcm_stream *hinfo, 329static int nvhdmi_dig_playback_pcm_prepare_2ch(struct hda_pcm_stream *hinfo,
338 struct hda_codec *codec, 330 struct hda_codec *codec,
339 unsigned int stream_tag, 331 unsigned int stream_tag,
@@ -348,12 +340,9 @@ static int nvhdmi_dig_playback_pcm_prepare_2ch(struct hda_pcm_stream *hinfo,
348static struct hda_pcm_stream nvhdmi_pcm_digital_playback_8ch_89 = { 340static struct hda_pcm_stream nvhdmi_pcm_digital_playback_8ch_89 = {
349 .substreams = 1, 341 .substreams = 1,
350 .channels_min = 2, 342 .channels_min = 2,
351 .rates = SUPPORTED_RATES,
352 .maxbps = SUPPORTED_MAXBPS,
353 .formats = SUPPORTED_FORMATS,
354 .ops = { 343 .ops = {
344 .open = hdmi_pcm_open,
355 .prepare = nvhdmi_dig_playback_pcm_prepare_8ch_89, 345 .prepare = nvhdmi_dig_playback_pcm_prepare_8ch_89,
356 .cleanup = nvhdmi_playback_pcm_cleanup,
357 }, 346 },
358}; 347};
359 348
@@ -541,26 +530,32 @@ static int patch_nvhdmi_2ch(struct hda_codec *codec)
541 * patch entries 530 * patch entries
542 */ 531 */
543static struct hda_codec_preset snd_hda_preset_nvhdmi[] = { 532static struct hda_codec_preset snd_hda_preset_nvhdmi[] = {
544 { .id = 0x10de0002, .name = "MCP77/78 HDMI", 533 { .id = 0x10de0002, .name = "MCP77/78 HDMI", .patch = patch_nvhdmi_8ch_7x },
545 .patch = patch_nvhdmi_8ch_7x }, 534 { .id = 0x10de0003, .name = "MCP77/78 HDMI", .patch = patch_nvhdmi_8ch_7x },
546 { .id = 0x10de0003, .name = "MCP77/78 HDMI", 535 { .id = 0x10de0005, .name = "MCP77/78 HDMI", .patch = patch_nvhdmi_8ch_7x },
547 .patch = patch_nvhdmi_8ch_7x }, 536 { .id = 0x10de0006, .name = "MCP77/78 HDMI", .patch = patch_nvhdmi_8ch_7x },
548 { .id = 0x10de0005, .name = "MCP77/78 HDMI", 537 { .id = 0x10de0007, .name = "MCP79/7A HDMI", .patch = patch_nvhdmi_8ch_7x },
549 .patch = patch_nvhdmi_8ch_7x }, 538 { .id = 0x10de000a, .name = "GPU 0a HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
550 { .id = 0x10de0006, .name = "MCP77/78 HDMI", 539 { .id = 0x10de000b, .name = "GPU 0b HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
551 .patch = patch_nvhdmi_8ch_7x }, 540 { .id = 0x10de000c, .name = "MCP89 HDMI", .patch = patch_nvhdmi_8ch_89 },
552 { .id = 0x10de0007, .name = "MCP79/7A HDMI", 541 { .id = 0x10de000d, .name = "GPU 0d HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
553 .patch = patch_nvhdmi_8ch_7x }, 542 { .id = 0x10de0010, .name = "GPU 10 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
554 { .id = 0x10de000a, .name = "GT220 HDMI", 543 { .id = 0x10de0011, .name = "GPU 11 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
555 .patch = patch_nvhdmi_8ch_89 }, 544 { .id = 0x10de0012, .name = "GPU 12 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
556 { .id = 0x10de000b, .name = "GT21x HDMI", 545 { .id = 0x10de0013, .name = "GPU 13 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
557 .patch = patch_nvhdmi_8ch_89 }, 546 { .id = 0x10de0014, .name = "GPU 14 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
558 { .id = 0x10de000c, .name = "MCP89 HDMI", 547 { .id = 0x10de0018, .name = "GPU 18 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
559 .patch = patch_nvhdmi_8ch_89 }, 548 { .id = 0x10de0019, .name = "GPU 19 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
560 { .id = 0x10de000d, .name = "GT240 HDMI", 549 { .id = 0x10de001a, .name = "GPU 1a HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
561 .patch = patch_nvhdmi_8ch_89 }, 550 { .id = 0x10de001b, .name = "GPU 1b HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
562 { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch }, 551 { .id = 0x10de001c, .name = "GPU 1c HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
563 { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch }, 552 { .id = 0x10de0040, .name = "GPU 40 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
553 { .id = 0x10de0041, .name = "GPU 41 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
554 { .id = 0x10de0042, .name = "GPU 42 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
555 { .id = 0x10de0043, .name = "GPU 43 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
556 { .id = 0x10de0044, .name = "GPU 44 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
557 { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch },
558 { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch },
564 {} /* terminator */ 559 {} /* terminator */
565}; 560};
566 561
@@ -573,6 +568,21 @@ MODULE_ALIAS("snd-hda-codec-id:10de000a");
573MODULE_ALIAS("snd-hda-codec-id:10de000b"); 568MODULE_ALIAS("snd-hda-codec-id:10de000b");
574MODULE_ALIAS("snd-hda-codec-id:10de000c"); 569MODULE_ALIAS("snd-hda-codec-id:10de000c");
575MODULE_ALIAS("snd-hda-codec-id:10de000d"); 570MODULE_ALIAS("snd-hda-codec-id:10de000d");
571MODULE_ALIAS("snd-hda-codec-id:10de0010");
572MODULE_ALIAS("snd-hda-codec-id:10de0011");
573MODULE_ALIAS("snd-hda-codec-id:10de0012");
574MODULE_ALIAS("snd-hda-codec-id:10de0013");
575MODULE_ALIAS("snd-hda-codec-id:10de0014");
576MODULE_ALIAS("snd-hda-codec-id:10de0018");
577MODULE_ALIAS("snd-hda-codec-id:10de0019");
578MODULE_ALIAS("snd-hda-codec-id:10de001a");
579MODULE_ALIAS("snd-hda-codec-id:10de001b");
580MODULE_ALIAS("snd-hda-codec-id:10de001c");
581MODULE_ALIAS("snd-hda-codec-id:10de0040");
582MODULE_ALIAS("snd-hda-codec-id:10de0041");
583MODULE_ALIAS("snd-hda-codec-id:10de0042");
584MODULE_ALIAS("snd-hda-codec-id:10de0043");
585MODULE_ALIAS("snd-hda-codec-id:10de0044");
576MODULE_ALIAS("snd-hda-codec-id:10de0067"); 586MODULE_ALIAS("snd-hda-codec-id:10de0067");
577MODULE_ALIAS("snd-hda-codec-id:10de8001"); 587MODULE_ALIAS("snd-hda-codec-id:10de8001");
578 588
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 596ea2f12cf..a432e6efd19 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -137,6 +137,7 @@ enum {
137 ALC269VB_DMIC, 137 ALC269VB_DMIC,
138 ALC269_FUJITSU, 138 ALC269_FUJITSU,
139 ALC269_LIFEBOOK, 139 ALC269_LIFEBOOK,
140 ALC271_ACER,
140 ALC269_AUTO, 141 ALC269_AUTO,
141 ALC269_MODEL_LAST /* last tag */ 142 ALC269_MODEL_LAST /* last tag */
142}; 143};
@@ -256,6 +257,13 @@ enum {
256 ALC882_MODEL_LAST, 257 ALC882_MODEL_LAST,
257}; 258};
258 259
260/* ALC680 models */
261enum {
262 ALC680_BASE,
263 ALC680_AUTO,
264 ALC680_MODEL_LAST,
265};
266
259/* for GPIO Poll */ 267/* for GPIO Poll */
260#define GPIO_MASK 0x03 268#define GPIO_MASK 0x03
261 269
@@ -326,6 +334,12 @@ struct alc_spec {
326 hda_nid_t *capsrc_nids; 334 hda_nid_t *capsrc_nids;
327 hda_nid_t dig_in_nid; /* digital-in NID; optional */ 335 hda_nid_t dig_in_nid; /* digital-in NID; optional */
328 336
337 /* capture setup for dynamic dual-adc switch */
338 unsigned int cur_adc_idx;
339 hda_nid_t cur_adc;
340 unsigned int cur_adc_stream_tag;
341 unsigned int cur_adc_format;
342
329 /* capture source */ 343 /* capture source */
330 unsigned int num_mux_defs; 344 unsigned int num_mux_defs;
331 const struct hda_input_mux *input_mux; 345 const struct hda_input_mux *input_mux;
@@ -367,6 +381,7 @@ struct alc_spec {
367 381
368 /* other flags */ 382 /* other flags */
369 unsigned int no_analog :1; /* digital I/O only */ 383 unsigned int no_analog :1; /* digital I/O only */
384 unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */
370 int init_amp; 385 int init_amp;
371 386
372 /* for virtual master */ 387 /* for virtual master */
@@ -833,9 +848,13 @@ static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
833 848
834 if (auto_pin_type <= AUTO_PIN_FRONT_MIC) { 849 if (auto_pin_type <= AUTO_PIN_FRONT_MIC) {
835 unsigned int pincap; 850 unsigned int pincap;
851 unsigned int oldval;
852 oldval = snd_hda_codec_read(codec, nid, 0,
853 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
836 pincap = snd_hda_query_pin_caps(codec, nid); 854 pincap = snd_hda_query_pin_caps(codec, nid);
837 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT; 855 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
838 if (pincap & AC_PINCAP_VREF_80) 856 /* if the default pin setup is vref50, we give it priority */
857 if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50)
839 val = PIN_VREF80; 858 val = PIN_VREF80;
840 else if (pincap & AC_PINCAP_VREF_50) 859 else if (pincap & AC_PINCAP_VREF_50)
841 val = PIN_VREF50; 860 val = PIN_VREF50;
@@ -1003,6 +1022,29 @@ static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
1003 return -1; 1022 return -1;
1004} 1023}
1005 1024
1025/* switch the current ADC according to the jack state */
1026static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec)
1027{
1028 struct alc_spec *spec = codec->spec;
1029 unsigned int present;
1030 hda_nid_t new_adc;
1031
1032 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1033 if (present)
1034 spec->cur_adc_idx = 1;
1035 else
1036 spec->cur_adc_idx = 0;
1037 new_adc = spec->adc_nids[spec->cur_adc_idx];
1038 if (spec->cur_adc && spec->cur_adc != new_adc) {
1039 /* stream is running, let's swap the current ADC */
1040 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
1041 spec->cur_adc = new_adc;
1042 snd_hda_codec_setup_stream(codec, new_adc,
1043 spec->cur_adc_stream_tag, 0,
1044 spec->cur_adc_format);
1045 }
1046}
1047
1006static void alc_mic_automute(struct hda_codec *codec) 1048static void alc_mic_automute(struct hda_codec *codec)
1007{ 1049{
1008 struct alc_spec *spec = codec->spec; 1050 struct alc_spec *spec = codec->spec;
@@ -1017,6 +1059,11 @@ static void alc_mic_automute(struct hda_codec *codec)
1017 if (snd_BUG_ON(!spec->adc_nids)) 1059 if (snd_BUG_ON(!spec->adc_nids))
1018 return; 1060 return;
1019 1061
1062 if (spec->dual_adc_switch) {
1063 alc_dual_mic_adc_auto_switch(codec);
1064 return;
1065 }
1066
1020 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0]; 1067 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1021 1068
1022 present = snd_hda_jack_detect(codec, spec->ext_mic.pin); 1069 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
@@ -1499,6 +1546,73 @@ static int alc_read_coef_idx(struct hda_codec *codec,
1499 return val; 1546 return val;
1500} 1547}
1501 1548
1549/* set right pin controls for digital I/O */
1550static void alc_auto_init_digital(struct hda_codec *codec)
1551{
1552 struct alc_spec *spec = codec->spec;
1553 int i;
1554 hda_nid_t pin;
1555
1556 for (i = 0; i < spec->autocfg.dig_outs; i++) {
1557 pin = spec->autocfg.dig_out_pins[i];
1558 if (pin) {
1559 snd_hda_codec_write(codec, pin, 0,
1560 AC_VERB_SET_PIN_WIDGET_CONTROL,
1561 PIN_OUT);
1562 }
1563 }
1564 pin = spec->autocfg.dig_in_pin;
1565 if (pin)
1566 snd_hda_codec_write(codec, pin, 0,
1567 AC_VERB_SET_PIN_WIDGET_CONTROL,
1568 PIN_IN);
1569}
1570
1571/* parse digital I/Os and set up NIDs in BIOS auto-parse mode */
1572static void alc_auto_parse_digital(struct hda_codec *codec)
1573{
1574 struct alc_spec *spec = codec->spec;
1575 int i, err;
1576 hda_nid_t dig_nid;
1577
1578 /* support multiple SPDIFs; the secondary is set up as a slave */
1579 for (i = 0; i < spec->autocfg.dig_outs; i++) {
1580 err = snd_hda_get_connections(codec,
1581 spec->autocfg.dig_out_pins[i],
1582 &dig_nid, 1);
1583 if (err < 0)
1584 continue;
1585 if (!i) {
1586 spec->multiout.dig_out_nid = dig_nid;
1587 spec->dig_out_type = spec->autocfg.dig_out_type[0];
1588 } else {
1589 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
1590 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
1591 break;
1592 spec->slave_dig_outs[i - 1] = dig_nid;
1593 }
1594 }
1595
1596 if (spec->autocfg.dig_in_pin) {
1597 dig_nid = codec->start_nid;
1598 for (i = 0; i < codec->num_nodes; i++, dig_nid++) {
1599 unsigned int wcaps = get_wcaps(codec, dig_nid);
1600 if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
1601 continue;
1602 if (!(wcaps & AC_WCAP_DIGITAL))
1603 continue;
1604 if (!(wcaps & AC_WCAP_CONN_LIST))
1605 continue;
1606 err = get_connection_index(codec, dig_nid,
1607 spec->autocfg.dig_in_pin);
1608 if (err >= 0) {
1609 spec->dig_in_nid = dig_nid;
1610 break;
1611 }
1612 }
1613 }
1614}
1615
1502/* 1616/*
1503 * ALC888 1617 * ALC888
1504 */ 1618 */
@@ -3607,6 +3721,41 @@ static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3607 return 0; 3721 return 0;
3608} 3722}
3609 3723
3724/* analog capture with dynamic dual-adc changes */
3725static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3726 struct hda_codec *codec,
3727 unsigned int stream_tag,
3728 unsigned int format,
3729 struct snd_pcm_substream *substream)
3730{
3731 struct alc_spec *spec = codec->spec;
3732 spec->cur_adc = spec->adc_nids[spec->cur_adc_idx];
3733 spec->cur_adc_stream_tag = stream_tag;
3734 spec->cur_adc_format = format;
3735 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
3736 return 0;
3737}
3738
3739static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3740 struct hda_codec *codec,
3741 struct snd_pcm_substream *substream)
3742{
3743 struct alc_spec *spec = codec->spec;
3744 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
3745 spec->cur_adc = 0;
3746 return 0;
3747}
3748
3749static struct hda_pcm_stream dualmic_pcm_analog_capture = {
3750 .substreams = 1,
3751 .channels_min = 2,
3752 .channels_max = 2,
3753 .nid = 0, /* fill later */
3754 .ops = {
3755 .prepare = dualmic_capture_pcm_prepare,
3756 .cleanup = dualmic_capture_pcm_cleanup
3757 },
3758};
3610 3759
3611/* 3760/*
3612 */ 3761 */
@@ -4936,7 +5085,7 @@ static void alc880_auto_init_input_src(struct hda_codec *codec)
4936static int alc880_parse_auto_config(struct hda_codec *codec) 5085static int alc880_parse_auto_config(struct hda_codec *codec)
4937{ 5086{
4938 struct alc_spec *spec = codec->spec; 5087 struct alc_spec *spec = codec->spec;
4939 int i, err; 5088 int err;
4940 static hda_nid_t alc880_ignore[] = { 0x1d, 0 }; 5089 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
4941 5090
4942 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 5091 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
@@ -4967,25 +5116,7 @@ static int alc880_parse_auto_config(struct hda_codec *codec)
4967 5116
4968 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 5117 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4969 5118
4970 /* check multiple SPDIF-out (for recent codecs) */ 5119 alc_auto_parse_digital(codec);
4971 for (i = 0; i < spec->autocfg.dig_outs; i++) {
4972 hda_nid_t dig_nid;
4973 err = snd_hda_get_connections(codec,
4974 spec->autocfg.dig_out_pins[i],
4975 &dig_nid, 1);
4976 if (err < 0)
4977 continue;
4978 if (!i)
4979 spec->multiout.dig_out_nid = dig_nid;
4980 else {
4981 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
4982 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
4983 break;
4984 spec->slave_dig_outs[i - 1] = dig_nid;
4985 }
4986 }
4987 if (spec->autocfg.dig_in_pin)
4988 spec->dig_in_nid = ALC880_DIGIN_NID;
4989 5120
4990 if (spec->kctls.list) 5121 if (spec->kctls.list)
4991 add_mixer(spec, spec->kctls.list); 5122 add_mixer(spec, spec->kctls.list);
@@ -5008,6 +5139,7 @@ static void alc880_auto_init(struct hda_codec *codec)
5008 alc880_auto_init_extra_out(codec); 5139 alc880_auto_init_extra_out(codec);
5009 alc880_auto_init_analog_input(codec); 5140 alc880_auto_init_analog_input(codec);
5010 alc880_auto_init_input_src(codec); 5141 alc880_auto_init_input_src(codec);
5142 alc_auto_init_digital(codec);
5011 if (spec->unsol_event) 5143 if (spec->unsol_event)
5012 alc_inithook(codec); 5144 alc_inithook(codec);
5013} 5145}
@@ -5045,6 +5177,39 @@ static void fixup_automic_adc(struct hda_codec *codec)
5045 spec->auto_mic = 0; /* disable auto-mic to be sure */ 5177 spec->auto_mic = 0; /* disable auto-mic to be sure */
5046} 5178}
5047 5179
5180/* select or unmute the given capsrc route */
5181static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap,
5182 int idx)
5183{
5184 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5185 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5186 HDA_AMP_MUTE, 0);
5187 } else {
5188 snd_hda_codec_write_cache(codec, cap, 0,
5189 AC_VERB_SET_CONNECT_SEL, idx);
5190 }
5191}
5192
5193/* set the default connection to that pin */
5194static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
5195{
5196 struct alc_spec *spec = codec->spec;
5197 int i;
5198
5199 for (i = 0; i < spec->num_adc_nids; i++) {
5200 hda_nid_t cap = spec->capsrc_nids ?
5201 spec->capsrc_nids[i] : spec->adc_nids[i];
5202 int idx;
5203
5204 idx = get_connection_index(codec, cap, pin);
5205 if (idx < 0)
5206 continue;
5207 select_or_unmute_capsrc(codec, cap, idx);
5208 return i; /* return the found index */
5209 }
5210 return -1; /* not found */
5211}
5212
5048/* choose the ADC/MUX containing the input pin and initialize the setup */ 5213/* choose the ADC/MUX containing the input pin and initialize the setup */
5049static void fixup_single_adc(struct hda_codec *codec) 5214static void fixup_single_adc(struct hda_codec *codec)
5050{ 5215{
@@ -5061,33 +5226,24 @@ static void fixup_single_adc(struct hda_codec *codec)
5061 } 5226 }
5062 if (!pin) 5227 if (!pin)
5063 return; 5228 return;
5064 5229 i = init_capsrc_for_pin(codec, pin);
5065 /* set the default connection to that pin */ 5230 if (i >= 0) {
5066 for (i = 0; i < spec->num_adc_nids; i++) {
5067 hda_nid_t cap = spec->capsrc_nids ?
5068 spec->capsrc_nids[i] : spec->adc_nids[i];
5069 int idx;
5070
5071 idx = get_connection_index(codec, cap, pin);
5072 if (idx < 0)
5073 continue;
5074 /* use only this ADC */ 5231 /* use only this ADC */
5075 if (spec->capsrc_nids) 5232 if (spec->capsrc_nids)
5076 spec->capsrc_nids += i; 5233 spec->capsrc_nids += i;
5077 spec->adc_nids += i; 5234 spec->adc_nids += i;
5078 spec->num_adc_nids = 1; 5235 spec->num_adc_nids = 1;
5079 /* select or unmute this route */
5080 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5081 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5082 HDA_AMP_MUTE, 0);
5083 } else {
5084 snd_hda_codec_write_cache(codec, cap, 0,
5085 AC_VERB_SET_CONNECT_SEL, idx);
5086 }
5087 return;
5088 } 5236 }
5089} 5237}
5090 5238
5239/* initialize dual adcs */
5240static void fixup_dual_adc_switch(struct hda_codec *codec)
5241{
5242 struct alc_spec *spec = codec->spec;
5243 init_capsrc_for_pin(codec, spec->ext_mic.pin);
5244 init_capsrc_for_pin(codec, spec->int_mic.pin);
5245}
5246
5091static void set_capture_mixer(struct hda_codec *codec) 5247static void set_capture_mixer(struct hda_codec *codec)
5092{ 5248{
5093 struct alc_spec *spec = codec->spec; 5249 struct alc_spec *spec = codec->spec;
@@ -5101,7 +5257,10 @@ static void set_capture_mixer(struct hda_codec *codec)
5101 }; 5257 };
5102 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) { 5258 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
5103 int mux = 0; 5259 int mux = 0;
5104 if (spec->auto_mic) 5260 int num_adcs = spec->num_adc_nids;
5261 if (spec->dual_adc_switch)
5262 fixup_dual_adc_switch(codec);
5263 else if (spec->auto_mic)
5105 fixup_automic_adc(codec); 5264 fixup_automic_adc(codec);
5106 else if (spec->input_mux) { 5265 else if (spec->input_mux) {
5107 if (spec->input_mux->num_items > 1) 5266 if (spec->input_mux->num_items > 1)
@@ -5109,7 +5268,9 @@ static void set_capture_mixer(struct hda_codec *codec)
5109 else if (spec->input_mux->num_items == 1) 5268 else if (spec->input_mux->num_items == 1)
5110 fixup_single_adc(codec); 5269 fixup_single_adc(codec);
5111 } 5270 }
5112 spec->cap_mixer = caps[mux][spec->num_adc_nids - 1]; 5271 if (spec->dual_adc_switch)
5272 num_adcs = 1;
5273 spec->cap_mixer = caps[mux][num_adcs - 1];
5113 } 5274 }
5114} 5275}
5115 5276
@@ -5183,6 +5344,8 @@ static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids,
5183 5344
5184static struct snd_pci_quirk beep_white_list[] = { 5345static struct snd_pci_quirk beep_white_list[] = {
5185 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1), 5346 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
5347 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
5348 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
5186 {} 5349 {}
5187}; 5350};
5188 5351
@@ -6624,6 +6787,7 @@ static void alc260_auto_init(struct hda_codec *codec)
6624 alc260_auto_init_multi_out(codec); 6787 alc260_auto_init_multi_out(codec);
6625 alc260_auto_init_analog_input(codec); 6788 alc260_auto_init_analog_input(codec);
6626 alc260_auto_init_input_src(codec); 6789 alc260_auto_init_input_src(codec);
6790 alc_auto_init_digital(codec);
6627 if (spec->unsol_event) 6791 if (spec->unsol_event)
6628 alc_inithook(codec); 6792 alc_inithook(codec);
6629} 6793}
@@ -6640,6 +6804,29 @@ static struct hda_amp_list alc260_loopbacks[] = {
6640#endif 6804#endif
6641 6805
6642/* 6806/*
6807 * Pin config fixes
6808 */
6809enum {
6810 PINFIX_HP_DC5750,
6811};
6812
6813static struct alc_pincfg alc260_hp_dc5750_pinfix[] = {
6814 { 0x11, 0x90130110 }, /* speaker */
6815 { }
6816};
6817
6818static const struct alc_fixup alc260_fixups[] = {
6819 [PINFIX_HP_DC5750] = {
6820 .pins = alc260_hp_dc5750_pinfix
6821 },
6822};
6823
6824static struct snd_pci_quirk alc260_fixup_tbl[] = {
6825 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750),
6826 {}
6827};
6828
6829/*
6643 * ALC260 configurations 6830 * ALC260 configurations
6644 */ 6831 */
6645static const char *alc260_models[ALC260_MODEL_LAST] = { 6832static const char *alc260_models[ALC260_MODEL_LAST] = {
@@ -6838,6 +7025,9 @@ static int patch_alc260(struct hda_codec *codec)
6838 board_config = ALC260_AUTO; 7025 board_config = ALC260_AUTO;
6839 } 7026 }
6840 7027
7028 if (board_config == ALC260_AUTO)
7029 alc_pick_fixup(codec, alc260_fixup_tbl, alc260_fixups, 1);
7030
6841 if (board_config == ALC260_AUTO) { 7031 if (board_config == ALC260_AUTO) {
6842 /* automatic parse from the BIOS config */ 7032 /* automatic parse from the BIOS config */
6843 err = alc260_parse_auto_config(codec); 7033 err = alc260_parse_auto_config(codec);
@@ -6863,6 +7053,7 @@ static int patch_alc260(struct hda_codec *codec)
6863 7053
6864 spec->stream_analog_playback = &alc260_pcm_analog_playback; 7054 spec->stream_analog_playback = &alc260_pcm_analog_playback;
6865 spec->stream_analog_capture = &alc260_pcm_analog_capture; 7055 spec->stream_analog_capture = &alc260_pcm_analog_capture;
7056 spec->stream_analog_alt_capture = &alc260_pcm_analog_capture;
6866 7057
6867 spec->stream_digital_playback = &alc260_pcm_digital_playback; 7058 spec->stream_digital_playback = &alc260_pcm_digital_playback;
6868 spec->stream_digital_capture = &alc260_pcm_digital_capture; 7059 spec->stream_digital_capture = &alc260_pcm_digital_capture;
@@ -6883,6 +7074,9 @@ static int patch_alc260(struct hda_codec *codec)
6883 set_capture_mixer(codec); 7074 set_capture_mixer(codec);
6884 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT); 7075 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
6885 7076
7077 if (board_config == ALC260_AUTO)
7078 alc_pick_fixup(codec, alc260_fixup_tbl, alc260_fixups, 0);
7079
6886 spec->vmaster_nid = 0x08; 7080 spec->vmaster_nid = 0x08;
6887 7081
6888 codec->patch_ops = alc_patch_ops; 7082 codec->patch_ops = alc_patch_ops;
@@ -7003,7 +7197,7 @@ static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7003 .num_items = 4, 7197 .num_items = 4,
7004 .items = { 7198 .items = {
7005 { "Mic", 0x0 }, 7199 { "Mic", 0x0 },
7006 { "iMic", 0x1 }, 7200 { "Int Mic", 0x1 },
7007 { "Line", 0x2 }, 7201 { "Line", 0x2 },
7008 { "CD", 0x4 }, 7202 { "CD", 0x4 },
7009 }, 7203 },
@@ -8573,8 +8767,8 @@ static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
8573 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8767 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8574 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8768 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8575 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8769 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8576 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8770 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8577 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8771 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8578 { } /* end */ 8772 { } /* end */
8579}; 8773};
8580 8774
@@ -10265,7 +10459,8 @@ static struct alc_config_preset alc882_presets[] = {
10265 * Pin config fixes 10459 * Pin config fixes
10266 */ 10460 */
10267enum { 10461enum {
10268 PINFIX_ABIT_AW9D_MAX 10462 PINFIX_ABIT_AW9D_MAX,
10463 PINFIX_PB_M5210,
10269}; 10464};
10270 10465
10271static struct alc_pincfg alc882_abit_aw9d_pinfix[] = { 10466static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
@@ -10275,13 +10470,22 @@ static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
10275 { } 10470 { }
10276}; 10471};
10277 10472
10473static const struct hda_verb pb_m5210_verbs[] = {
10474 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
10475 {}
10476};
10477
10278static const struct alc_fixup alc882_fixups[] = { 10478static const struct alc_fixup alc882_fixups[] = {
10279 [PINFIX_ABIT_AW9D_MAX] = { 10479 [PINFIX_ABIT_AW9D_MAX] = {
10280 .pins = alc882_abit_aw9d_pinfix 10480 .pins = alc882_abit_aw9d_pinfix
10281 }, 10481 },
10482 [PINFIX_PB_M5210] = {
10483 .verbs = pb_m5210_verbs
10484 },
10282}; 10485};
10283 10486
10284static struct snd_pci_quirk alc882_fixup_tbl[] = { 10487static struct snd_pci_quirk alc882_fixup_tbl[] = {
10488 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210),
10285 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX), 10489 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
10286 {} 10490 {}
10287}; 10491};
@@ -10446,7 +10650,7 @@ static int alc882_parse_auto_config(struct hda_codec *codec)
10446{ 10650{
10447 struct alc_spec *spec = codec->spec; 10651 struct alc_spec *spec = codec->spec;
10448 static hda_nid_t alc882_ignore[] = { 0x1d, 0 }; 10652 static hda_nid_t alc882_ignore[] = { 0x1d, 0 };
10449 int i, err; 10653 int err;
10450 10654
10451 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 10655 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10452 alc882_ignore); 10656 alc882_ignore);
@@ -10476,25 +10680,7 @@ static int alc882_parse_auto_config(struct hda_codec *codec)
10476 10680
10477 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 10681 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10478 10682
10479 /* check multiple SPDIF-out (for recent codecs) */ 10683 alc_auto_parse_digital(codec);
10480 for (i = 0; i < spec->autocfg.dig_outs; i++) {
10481 hda_nid_t dig_nid;
10482 err = snd_hda_get_connections(codec,
10483 spec->autocfg.dig_out_pins[i],
10484 &dig_nid, 1);
10485 if (err < 0)
10486 continue;
10487 if (!i)
10488 spec->multiout.dig_out_nid = dig_nid;
10489 else {
10490 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
10491 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
10492 break;
10493 spec->slave_dig_outs[i - 1] = dig_nid;
10494 }
10495 }
10496 if (spec->autocfg.dig_in_pin)
10497 spec->dig_in_nid = ALC880_DIGIN_NID;
10498 10684
10499 if (spec->kctls.list) 10685 if (spec->kctls.list)
10500 add_mixer(spec, spec->kctls.list); 10686 add_mixer(spec, spec->kctls.list);
@@ -10524,6 +10710,7 @@ static void alc882_auto_init(struct hda_codec *codec)
10524 alc882_auto_init_hp_out(codec); 10710 alc882_auto_init_hp_out(codec);
10525 alc882_auto_init_analog_input(codec); 10711 alc882_auto_init_analog_input(codec);
10526 alc882_auto_init_input_src(codec); 10712 alc882_auto_init_input_src(codec);
10713 alc_auto_init_digital(codec);
10527 if (spec->unsol_event) 10714 if (spec->unsol_event)
10528 alc_inithook(codec); 10715 alc_inithook(codec);
10529} 10716}
@@ -12054,12 +12241,7 @@ static int alc262_parse_auto_config(struct hda_codec *codec)
12054 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 12241 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12055 12242
12056 dig_only: 12243 dig_only:
12057 if (spec->autocfg.dig_outs) { 12244 alc_auto_parse_digital(codec);
12058 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
12059 spec->dig_out_type = spec->autocfg.dig_out_type[0];
12060 }
12061 if (spec->autocfg.dig_in_pin)
12062 spec->dig_in_nid = ALC262_DIGIN_NID;
12063 12245
12064 if (spec->kctls.list) 12246 if (spec->kctls.list)
12065 add_mixer(spec, spec->kctls.list); 12247 add_mixer(spec, spec->kctls.list);
@@ -12091,6 +12273,7 @@ static void alc262_auto_init(struct hda_codec *codec)
12091 alc262_auto_init_hp_out(codec); 12273 alc262_auto_init_hp_out(codec);
12092 alc262_auto_init_analog_input(codec); 12274 alc262_auto_init_analog_input(codec);
12093 alc262_auto_init_input_src(codec); 12275 alc262_auto_init_input_src(codec);
12276 alc_auto_init_digital(codec);
12094 if (spec->unsol_event) 12277 if (spec->unsol_event)
12095 alc_inithook(codec); 12278 alc_inithook(codec);
12096} 12279}
@@ -13024,10 +13207,14 @@ static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13024 dac = 0x02; 13207 dac = 0x02;
13025 break; 13208 break;
13026 case 0x15: 13209 case 0x15:
13210 case 0x1a: /* ALC259/269 only */
13211 case 0x1b: /* ALC259/269 only */
13027 case 0x21: /* ALC269vb has this pin, too */ 13212 case 0x21: /* ALC269vb has this pin, too */
13028 dac = 0x03; 13213 dac = 0x03;
13029 break; 13214 break;
13030 default: 13215 default:
13216 snd_printd(KERN_WARNING "hda_codec: "
13217 "ignoring pin 0x%x as unknown\n", nid);
13031 return 0; 13218 return 0;
13032 } 13219 }
13033 if (spec->multiout.dac_nids[0] != dac && 13220 if (spec->multiout.dac_nids[0] != dac &&
@@ -13078,7 +13265,7 @@ static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
13078 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); 13265 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
13079 if (err < 0) 13266 if (err < 0)
13080 return err; 13267 return err;
13081 } else { 13268 } else if (nid) {
13082 err = alc268_new_analog_output(spec, nid, "Speaker", 0); 13269 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
13083 if (err < 0) 13270 if (err < 0)
13084 return err; 13271 return err;
@@ -13227,10 +13414,7 @@ static int alc268_parse_auto_config(struct hda_codec *codec)
13227 13414
13228 dig_only: 13415 dig_only:
13229 /* digital only support output */ 13416 /* digital only support output */
13230 if (spec->autocfg.dig_outs) { 13417 alc_auto_parse_digital(codec);
13231 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
13232 spec->dig_out_type = spec->autocfg.dig_out_type[0];
13233 }
13234 if (spec->kctls.list) 13418 if (spec->kctls.list)
13235 add_mixer(spec, spec->kctls.list); 13419 add_mixer(spec, spec->kctls.list);
13236 13420
@@ -13260,6 +13444,7 @@ static void alc268_auto_init(struct hda_codec *codec)
13260 alc268_auto_init_hp_out(codec); 13444 alc268_auto_init_hp_out(codec);
13261 alc268_auto_init_mono_speaker_out(codec); 13445 alc268_auto_init_mono_speaker_out(codec);
13262 alc268_auto_init_analog_input(codec); 13446 alc268_auto_init_analog_input(codec);
13447 alc_auto_init_digital(codec);
13263 if (spec->unsol_event) 13448 if (spec->unsol_event)
13264 alc_inithook(codec); 13449 alc_inithook(codec);
13265} 13450}
@@ -13303,7 +13488,6 @@ static struct snd_pci_quirk alc268_cfg_tbl[] = {
13303 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA), 13488 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
13304 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER), 13489 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
13305 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1), 13490 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
13306 SND_PCI_QUIRK(0x1854, 0x1775, "LG R510", ALC268_DELL),
13307 {} 13491 {}
13308}; 13492};
13309 13493
@@ -13694,6 +13878,12 @@ static struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
13694 { } /* end */ 13878 { } /* end */
13695}; 13879};
13696 13880
13881static struct snd_kcontrol_new alc269_asus_mixer[] = {
13882 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13883 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
13884 { } /* end */
13885};
13886
13697/* capture mixer elements */ 13887/* capture mixer elements */
13698static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = { 13888static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
13699 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 13889 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
@@ -13914,6 +14104,20 @@ static struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
13914 {} 14104 {}
13915}; 14105};
13916 14106
14107static struct hda_verb alc271_acer_dmic_verbs[] = {
14108 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14109 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14110 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14111 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14112 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14113 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14114 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},
14115 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14116 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14117 {0x22, AC_VERB_SET_CONNECT_SEL, 6},
14118 { }
14119};
14120
13917/* toggle speaker-output according to the hp-jack state */ 14121/* toggle speaker-output according to the hp-jack state */
13918static void alc269_speaker_automute(struct hda_codec *codec) 14122static void alc269_speaker_automute(struct hda_codec *codec)
13919{ 14123{
@@ -14152,6 +14356,36 @@ static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14152} 14356}
14153#endif /* CONFIG_SND_HDA_POWER_SAVE */ 14357#endif /* CONFIG_SND_HDA_POWER_SAVE */
14154 14358
14359static int alc275_setup_dual_adc(struct hda_codec *codec)
14360{
14361 struct alc_spec *spec = codec->spec;
14362
14363 if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic)
14364 return 0;
14365 if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) ||
14366 (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) {
14367 if (spec->ext_mic.pin <= 0x12) {
14368 spec->private_adc_nids[0] = 0x08;
14369 spec->private_adc_nids[1] = 0x11;
14370 spec->private_capsrc_nids[0] = 0x23;
14371 spec->private_capsrc_nids[1] = 0x22;
14372 } else {
14373 spec->private_adc_nids[0] = 0x11;
14374 spec->private_adc_nids[1] = 0x08;
14375 spec->private_capsrc_nids[0] = 0x22;
14376 spec->private_capsrc_nids[1] = 0x23;
14377 }
14378 spec->adc_nids = spec->private_adc_nids;
14379 spec->capsrc_nids = spec->private_capsrc_nids;
14380 spec->num_adc_nids = 2;
14381 spec->dual_adc_switch = 1;
14382 snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n",
14383 spec->adc_nids[0], spec->adc_nids[1]);
14384 return 1;
14385 }
14386 return 0;
14387}
14388
14155/* 14389/*
14156 * BIOS auto configuration 14390 * BIOS auto configuration
14157 */ 14391 */
@@ -14175,8 +14409,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
14175 14409
14176 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 14410 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14177 14411
14178 if (spec->autocfg.dig_outs) 14412 alc_auto_parse_digital(codec);
14179 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
14180 14413
14181 if (spec->kctls.list) 14414 if (spec->kctls.list)
14182 add_mixer(spec, spec->kctls.list); 14415 add_mixer(spec, spec->kctls.list);
@@ -14191,13 +14424,15 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
14191 14424
14192 spec->num_mux_defs = 1; 14425 spec->num_mux_defs = 1;
14193 spec->input_mux = &spec->private_imux[0]; 14426 spec->input_mux = &spec->private_imux[0];
14194 fillup_priv_adc_nids(codec, alc269_adc_candidates, 14427
14195 sizeof(alc269_adc_candidates)); 14428 if (!alc275_setup_dual_adc(codec))
14429 fillup_priv_adc_nids(codec, alc269_adc_candidates,
14430 sizeof(alc269_adc_candidates));
14196 14431
14197 /* set default input source */ 14432 /* set default input source */
14198 snd_hda_codec_write_cache(codec, spec->capsrc_nids[0], 14433 if (!spec->dual_adc_switch)
14199 0, AC_VERB_SET_CONNECT_SEL, 14434 select_or_unmute_capsrc(codec, spec->capsrc_nids[0],
14200 spec->input_mux->items[0].index); 14435 spec->input_mux->items[0].index);
14201 14436
14202 err = alc_auto_add_mic_boost(codec); 14437 err = alc_auto_add_mic_boost(codec);
14203 if (err < 0) 14438 if (err < 0)
@@ -14221,12 +14456,14 @@ static void alc269_auto_init(struct hda_codec *codec)
14221 alc269_auto_init_multi_out(codec); 14456 alc269_auto_init_multi_out(codec);
14222 alc269_auto_init_hp_out(codec); 14457 alc269_auto_init_hp_out(codec);
14223 alc269_auto_init_analog_input(codec); 14458 alc269_auto_init_analog_input(codec);
14459 alc_auto_init_digital(codec);
14224 if (spec->unsol_event) 14460 if (spec->unsol_event)
14225 alc_inithook(codec); 14461 alc_inithook(codec);
14226} 14462}
14227 14463
14228enum { 14464enum {
14229 ALC269_FIXUP_SONY_VAIO, 14465 ALC269_FIXUP_SONY_VAIO,
14466 ALC269_FIXUP_DELL_M101Z,
14230}; 14467};
14231 14468
14232static const struct hda_verb alc269_sony_vaio_fixup_verbs[] = { 14469static const struct hda_verb alc269_sony_vaio_fixup_verbs[] = {
@@ -14238,10 +14475,20 @@ static const struct alc_fixup alc269_fixups[] = {
14238 [ALC269_FIXUP_SONY_VAIO] = { 14475 [ALC269_FIXUP_SONY_VAIO] = {
14239 .verbs = alc269_sony_vaio_fixup_verbs 14476 .verbs = alc269_sony_vaio_fixup_verbs
14240 }, 14477 },
14478 [ALC269_FIXUP_DELL_M101Z] = {
14479 .verbs = (const struct hda_verb[]) {
14480 /* Enables internal speaker */
14481 {0x20, AC_VERB_SET_COEF_INDEX, 13},
14482 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
14483 {}
14484 }
14485 },
14241}; 14486};
14242 14487
14243static struct snd_pci_quirk alc269_fixup_tbl[] = { 14488static struct snd_pci_quirk alc269_fixup_tbl[] = {
14244 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), 14489 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
14490 SND_PCI_QUIRK(0x104d, 0x9077, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
14491 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
14245 {} 14492 {}
14246}; 14493};
14247 14494
@@ -14261,6 +14508,7 @@ static const char *alc269_models[ALC269_MODEL_LAST] = {
14261 14508
14262static struct snd_pci_quirk alc269_cfg_tbl[] = { 14509static struct snd_pci_quirk alc269_cfg_tbl[] = {
14263 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1), 14510 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
14511 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),
14264 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", 14512 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
14265 ALC269_AMIC), 14513 ALC269_AMIC),
14266 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC), 14514 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
@@ -14422,6 +14670,23 @@ static struct alc_config_preset alc269_presets[] = {
14422 .unsol_event = alc269_lifebook_unsol_event, 14670 .unsol_event = alc269_lifebook_unsol_event,
14423 .init_hook = alc269_lifebook_init_hook, 14671 .init_hook = alc269_lifebook_init_hook,
14424 }, 14672 },
14673 [ALC271_ACER] = {
14674 .mixers = { alc269_asus_mixer },
14675 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
14676 .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs },
14677 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14678 .dac_nids = alc269_dac_nids,
14679 .adc_nids = alc262_dmic_adc_nids,
14680 .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids),
14681 .capsrc_nids = alc262_dmic_capsrc_nids,
14682 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14683 .channel_mode = alc269_modes,
14684 .input_mux = &alc269_capture_source,
14685 .dig_out_nid = ALC880_DIGOUT_NID,
14686 .unsol_event = alc_sku_unsol_event,
14687 .setup = alc269vb_laptop_dmic_setup,
14688 .init_hook = alc_inithook,
14689 },
14425}; 14690};
14426 14691
14427static int patch_alc269(struct hda_codec *codec) 14692static int patch_alc269(struct hda_codec *codec)
@@ -14493,6 +14758,10 @@ static int patch_alc269(struct hda_codec *codec)
14493 */ 14758 */
14494 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback; 14759 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
14495 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture; 14760 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
14761 } else if (spec->dual_adc_switch) {
14762 spec->stream_analog_playback = &alc269_pcm_analog_playback;
14763 /* switch ADC dynamically */
14764 spec->stream_analog_capture = &dualmic_pcm_analog_capture;
14496 } else { 14765 } else {
14497 spec->stream_analog_playback = &alc269_pcm_analog_playback; 14766 spec->stream_analog_playback = &alc269_pcm_analog_playback;
14498 spec->stream_analog_capture = &alc269_pcm_analog_capture; 14767 spec->stream_analog_capture = &alc269_pcm_analog_capture;
@@ -15378,8 +15647,7 @@ static int alc861_parse_auto_config(struct hda_codec *codec)
15378 15647
15379 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 15648 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
15380 15649
15381 if (spec->autocfg.dig_outs) 15650 alc_auto_parse_digital(codec);
15382 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
15383 15651
15384 if (spec->kctls.list) 15652 if (spec->kctls.list)
15385 add_mixer(spec, spec->kctls.list); 15653 add_mixer(spec, spec->kctls.list);
@@ -15405,6 +15673,7 @@ static void alc861_auto_init(struct hda_codec *codec)
15405 alc861_auto_init_multi_out(codec); 15673 alc861_auto_init_multi_out(codec);
15406 alc861_auto_init_hp_out(codec); 15674 alc861_auto_init_hp_out(codec);
15407 alc861_auto_init_analog_input(codec); 15675 alc861_auto_init_analog_input(codec);
15676 alc_auto_init_digital(codec);
15408 if (spec->unsol_event) 15677 if (spec->unsol_event)
15409 alc_inithook(codec); 15678 alc_inithook(codec);
15410} 15679}
@@ -16509,8 +16778,7 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec)
16509 16778
16510 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 16779 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16511 16780
16512 if (spec->autocfg.dig_outs) 16781 alc_auto_parse_digital(codec);
16513 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
16514 16782
16515 if (spec->kctls.list) 16783 if (spec->kctls.list)
16516 add_mixer(spec, spec->kctls.list); 16784 add_mixer(spec, spec->kctls.list);
@@ -16537,6 +16805,7 @@ static void alc861vd_auto_init(struct hda_codec *codec)
16537 alc861vd_auto_init_hp_out(codec); 16805 alc861vd_auto_init_hp_out(codec);
16538 alc861vd_auto_init_analog_input(codec); 16806 alc861vd_auto_init_analog_input(codec);
16539 alc861vd_auto_init_input_src(codec); 16807 alc861vd_auto_init_input_src(codec);
16808 alc_auto_init_digital(codec);
16540 if (spec->unsol_event) 16809 if (spec->unsol_event)
16541 alc_inithook(codec); 16810 alc_inithook(codec);
16542} 16811}
@@ -18520,7 +18789,7 @@ static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
18520 hda_nid_t dac) 18789 hda_nid_t dac)
18521{ 18790{
18522 int i, num; 18791 int i, num;
18523 hda_nid_t srcs[4]; 18792 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
18524 18793
18525 alc_set_pin_output(codec, nid, pin_type); 18794 alc_set_pin_output(codec, nid, pin_type);
18526 /* need the manual connection? */ 18795 /* need the manual connection? */
@@ -18624,8 +18893,7 @@ static int alc662_parse_auto_config(struct hda_codec *codec)
18624 18893
18625 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 18894 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
18626 18895
18627 if (spec->autocfg.dig_outs) 18896 alc_auto_parse_digital(codec);
18628 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
18629 18897
18630 if (spec->kctls.list) 18898 if (spec->kctls.list)
18631 add_mixer(spec, spec->kctls.list); 18899 add_mixer(spec, spec->kctls.list);
@@ -18635,7 +18903,7 @@ static int alc662_parse_auto_config(struct hda_codec *codec)
18635 18903
18636 add_verb(spec, alc662_init_verbs); 18904 add_verb(spec, alc662_init_verbs);
18637 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 || 18905 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
18638 codec->vendor_id == 0x10ec0665) 18906 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
18639 add_verb(spec, alc663_init_verbs); 18907 add_verb(spec, alc663_init_verbs);
18640 18908
18641 if (codec->vendor_id == 0x10ec0272) 18909 if (codec->vendor_id == 0x10ec0272)
@@ -18662,6 +18930,7 @@ static void alc662_auto_init(struct hda_codec *codec)
18662 alc662_auto_init_hp_out(codec); 18930 alc662_auto_init_hp_out(codec);
18663 alc662_auto_init_analog_input(codec); 18931 alc662_auto_init_analog_input(codec);
18664 alc662_auto_init_input_src(codec); 18932 alc662_auto_init_input_src(codec);
18933 alc_auto_init_digital(codec);
18665 if (spec->unsol_event) 18934 if (spec->unsol_event)
18666 alc_inithook(codec); 18935 alc_inithook(codec);
18667} 18936}
@@ -18781,6 +19050,445 @@ static int patch_alc888(struct hda_codec *codec)
18781} 19050}
18782 19051
18783/* 19052/*
19053 * ALC680 support
19054 */
19055#define ALC680_DIGIN_NID ALC880_DIGIN_NID
19056#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
19057#define alc680_modes alc260_modes
19058
19059static hda_nid_t alc680_dac_nids[3] = {
19060 /* Lout1, Lout2, hp */
19061 0x02, 0x03, 0x04
19062};
19063
19064static hda_nid_t alc680_adc_nids[3] = {
19065 /* ADC0-2 */
19066 /* DMIC, MIC, Line-in*/
19067 0x07, 0x08, 0x09
19068};
19069
19070/*
19071 * Analog capture ADC cgange
19072 */
19073static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
19074 struct hda_codec *codec,
19075 unsigned int stream_tag,
19076 unsigned int format,
19077 struct snd_pcm_substream *substream)
19078{
19079 struct alc_spec *spec = codec->spec;
19080 struct auto_pin_cfg *cfg = &spec->autocfg;
19081 unsigned int pre_mic, pre_line;
19082
19083 pre_mic = snd_hda_jack_detect(codec, cfg->input_pins[AUTO_PIN_MIC]);
19084 pre_line = snd_hda_jack_detect(codec, cfg->input_pins[AUTO_PIN_LINE]);
19085
19086 spec->cur_adc_stream_tag = stream_tag;
19087 spec->cur_adc_format = format;
19088
19089 if (pre_mic || pre_line) {
19090 if (pre_mic)
19091 snd_hda_codec_setup_stream(codec, 0x08, stream_tag, 0,
19092 format);
19093 else
19094 snd_hda_codec_setup_stream(codec, 0x09, stream_tag, 0,
19095 format);
19096 } else
19097 snd_hda_codec_setup_stream(codec, 0x07, stream_tag, 0, format);
19098 return 0;
19099}
19100
19101static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
19102 struct hda_codec *codec,
19103 struct snd_pcm_substream *substream)
19104{
19105 snd_hda_codec_cleanup_stream(codec, 0x07);
19106 snd_hda_codec_cleanup_stream(codec, 0x08);
19107 snd_hda_codec_cleanup_stream(codec, 0x09);
19108 return 0;
19109}
19110
19111static struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
19112 .substreams = 1, /* can be overridden */
19113 .channels_min = 2,
19114 .channels_max = 2,
19115 /* NID is set in alc_build_pcms */
19116 .ops = {
19117 .prepare = alc680_capture_pcm_prepare,
19118 .cleanup = alc680_capture_pcm_cleanup
19119 },
19120};
19121
19122static struct snd_kcontrol_new alc680_base_mixer[] = {
19123 /* output mixer control */
19124 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
19125 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
19126 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
19127 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
19128 HDA_CODEC_VOLUME("Int Mic Boost", 0x12, 0, HDA_INPUT),
19129 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
19130 HDA_CODEC_VOLUME("Line In Boost", 0x19, 0, HDA_INPUT),
19131 { }
19132};
19133
19134static struct hda_bind_ctls alc680_bind_cap_vol = {
19135 .ops = &snd_hda_bind_vol,
19136 .values = {
19137 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19138 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19139 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19140 0
19141 },
19142};
19143
19144static struct hda_bind_ctls alc680_bind_cap_switch = {
19145 .ops = &snd_hda_bind_sw,
19146 .values = {
19147 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19148 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19149 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19150 0
19151 },
19152};
19153
19154static struct snd_kcontrol_new alc680_master_capture_mixer[] = {
19155 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
19156 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
19157 { } /* end */
19158};
19159
19160/*
19161 * generic initialization of ADC, input mixers and output mixers
19162 */
19163static struct hda_verb alc680_init_verbs[] = {
19164 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19165 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19166 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19167
19168 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19169 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19170 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19171 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
19172 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
19173 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19174
19175 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19176 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19177 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19178 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19179 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19180
19181 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
19182 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
19183
19184 { }
19185};
19186
19187/* toggle speaker-output according to the hp-jack state */
19188static void alc680_base_setup(struct hda_codec *codec)
19189{
19190 struct alc_spec *spec = codec->spec;
19191
19192 spec->autocfg.hp_pins[0] = 0x16;
19193 spec->autocfg.speaker_pins[0] = 0x14;
19194 spec->autocfg.speaker_pins[1] = 0x15;
19195 spec->autocfg.input_pins[AUTO_PIN_MIC] = 0x18;
19196 spec->autocfg.input_pins[AUTO_PIN_LINE] = 0x19;
19197}
19198
19199static void alc680_rec_autoswitch(struct hda_codec *codec)
19200{
19201 struct alc_spec *spec = codec->spec;
19202 struct auto_pin_cfg *cfg = &spec->autocfg;
19203 unsigned int present;
19204 hda_nid_t new_adc;
19205
19206 present = snd_hda_jack_detect(codec, cfg->input_pins[AUTO_PIN_MIC]);
19207
19208 new_adc = present ? 0x8 : 0x7;
19209 __snd_hda_codec_cleanup_stream(codec, !present ? 0x8 : 0x7, 1);
19210 snd_hda_codec_setup_stream(codec, new_adc,
19211 spec->cur_adc_stream_tag, 0,
19212 spec->cur_adc_format);
19213
19214}
19215
19216static void alc680_unsol_event(struct hda_codec *codec,
19217 unsigned int res)
19218{
19219 if ((res >> 26) == ALC880_HP_EVENT)
19220 alc_automute_amp(codec);
19221 if ((res >> 26) == ALC880_MIC_EVENT)
19222 alc680_rec_autoswitch(codec);
19223}
19224
19225static void alc680_inithook(struct hda_codec *codec)
19226{
19227 alc_automute_amp(codec);
19228 alc680_rec_autoswitch(codec);
19229}
19230
19231/* create input playback/capture controls for the given pin */
19232static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
19233 const char *ctlname, int idx)
19234{
19235 hda_nid_t dac;
19236 int err;
19237
19238 switch (nid) {
19239 case 0x14:
19240 dac = 0x02;
19241 break;
19242 case 0x15:
19243 dac = 0x03;
19244 break;
19245 case 0x16:
19246 dac = 0x04;
19247 break;
19248 default:
19249 return 0;
19250 }
19251 if (spec->multiout.dac_nids[0] != dac &&
19252 spec->multiout.dac_nids[1] != dac) {
19253 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
19254 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
19255 HDA_OUTPUT));
19256 if (err < 0)
19257 return err;
19258
19259 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
19260 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
19261
19262 if (err < 0)
19263 return err;
19264 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
19265 }
19266
19267 return 0;
19268}
19269
19270/* add playback controls from the parsed DAC table */
19271static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec,
19272 const struct auto_pin_cfg *cfg)
19273{
19274 hda_nid_t nid;
19275 int err;
19276
19277 spec->multiout.dac_nids = spec->private_dac_nids;
19278
19279 nid = cfg->line_out_pins[0];
19280 if (nid) {
19281 const char *name;
19282 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
19283 name = "Speaker";
19284 else
19285 name = "Front";
19286 err = alc680_new_analog_output(spec, nid, name, 0);
19287 if (err < 0)
19288 return err;
19289 }
19290
19291 nid = cfg->speaker_pins[0];
19292 if (nid) {
19293 err = alc680_new_analog_output(spec, nid, "Speaker", 0);
19294 if (err < 0)
19295 return err;
19296 }
19297 nid = cfg->hp_pins[0];
19298 if (nid) {
19299 err = alc680_new_analog_output(spec, nid, "Headphone", 0);
19300 if (err < 0)
19301 return err;
19302 }
19303
19304 return 0;
19305}
19306
19307static void alc680_auto_set_output_and_unmute(struct hda_codec *codec,
19308 hda_nid_t nid, int pin_type)
19309{
19310 alc_set_pin_output(codec, nid, pin_type);
19311}
19312
19313static void alc680_auto_init_multi_out(struct hda_codec *codec)
19314{
19315 struct alc_spec *spec = codec->spec;
19316 hda_nid_t nid = spec->autocfg.line_out_pins[0];
19317 if (nid) {
19318 int pin_type = get_pin_type(spec->autocfg.line_out_type);
19319 alc680_auto_set_output_and_unmute(codec, nid, pin_type);
19320 }
19321}
19322
19323static void alc680_auto_init_hp_out(struct hda_codec *codec)
19324{
19325 struct alc_spec *spec = codec->spec;
19326 hda_nid_t pin;
19327
19328 pin = spec->autocfg.hp_pins[0];
19329 if (pin)
19330 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP);
19331 pin = spec->autocfg.speaker_pins[0];
19332 if (pin)
19333 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT);
19334}
19335
19336/* pcm configuration: identical with ALC880 */
19337#define alc680_pcm_analog_playback alc880_pcm_analog_playback
19338#define alc680_pcm_analog_capture alc880_pcm_analog_capture
19339#define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
19340#define alc680_pcm_digital_playback alc880_pcm_digital_playback
19341#define alc680_pcm_digital_capture alc880_pcm_digital_capture
19342
19343/*
19344 * BIOS auto configuration
19345 */
19346static int alc680_parse_auto_config(struct hda_codec *codec)
19347{
19348 struct alc_spec *spec = codec->spec;
19349 int err;
19350 static hda_nid_t alc680_ignore[] = { 0 };
19351
19352 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19353 alc680_ignore);
19354 if (err < 0)
19355 return err;
19356
19357 if (!spec->autocfg.line_outs) {
19358 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
19359 spec->multiout.max_channels = 2;
19360 spec->no_analog = 1;
19361 goto dig_only;
19362 }
19363 return 0; /* can't find valid BIOS pin config */
19364 }
19365 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg);
19366 if (err < 0)
19367 return err;
19368
19369 spec->multiout.max_channels = 2;
19370
19371 dig_only:
19372 /* digital only support output */
19373 alc_auto_parse_digital(codec);
19374 if (spec->kctls.list)
19375 add_mixer(spec, spec->kctls.list);
19376
19377 add_verb(spec, alc680_init_verbs);
19378
19379 err = alc_auto_add_mic_boost(codec);
19380 if (err < 0)
19381 return err;
19382
19383 return 1;
19384}
19385
19386#define alc680_auto_init_analog_input alc882_auto_init_analog_input
19387
19388/* init callback for auto-configuration model -- overriding the default init */
19389static void alc680_auto_init(struct hda_codec *codec)
19390{
19391 struct alc_spec *spec = codec->spec;
19392 alc680_auto_init_multi_out(codec);
19393 alc680_auto_init_hp_out(codec);
19394 alc680_auto_init_analog_input(codec);
19395 alc_auto_init_digital(codec);
19396 if (spec->unsol_event)
19397 alc_inithook(codec);
19398}
19399
19400/*
19401 * configuration and preset
19402 */
19403static const char *alc680_models[ALC680_MODEL_LAST] = {
19404 [ALC680_BASE] = "base",
19405 [ALC680_AUTO] = "auto",
19406};
19407
19408static struct snd_pci_quirk alc680_cfg_tbl[] = {
19409 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
19410 {}
19411};
19412
19413static struct alc_config_preset alc680_presets[] = {
19414 [ALC680_BASE] = {
19415 .mixers = { alc680_base_mixer },
19416 .cap_mixer = alc680_master_capture_mixer,
19417 .init_verbs = { alc680_init_verbs },
19418 .num_dacs = ARRAY_SIZE(alc680_dac_nids),
19419 .dac_nids = alc680_dac_nids,
19420 .dig_out_nid = ALC680_DIGOUT_NID,
19421 .num_channel_mode = ARRAY_SIZE(alc680_modes),
19422 .channel_mode = alc680_modes,
19423 .unsol_event = alc680_unsol_event,
19424 .setup = alc680_base_setup,
19425 .init_hook = alc680_inithook,
19426
19427 },
19428};
19429
19430static int patch_alc680(struct hda_codec *codec)
19431{
19432 struct alc_spec *spec;
19433 int board_config;
19434 int err;
19435
19436 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19437 if (spec == NULL)
19438 return -ENOMEM;
19439
19440 codec->spec = spec;
19441
19442 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST,
19443 alc680_models,
19444 alc680_cfg_tbl);
19445
19446 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) {
19447 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19448 codec->chip_name);
19449 board_config = ALC680_AUTO;
19450 }
19451
19452 if (board_config == ALC680_AUTO) {
19453 /* automatic parse from the BIOS config */
19454 err = alc680_parse_auto_config(codec);
19455 if (err < 0) {
19456 alc_free(codec);
19457 return err;
19458 } else if (!err) {
19459 printk(KERN_INFO
19460 "hda_codec: Cannot set up configuration "
19461 "from BIOS. Using base mode...\n");
19462 board_config = ALC680_BASE;
19463 }
19464 }
19465
19466 if (board_config != ALC680_AUTO)
19467 setup_preset(codec, &alc680_presets[board_config]);
19468
19469 spec->stream_analog_playback = &alc680_pcm_analog_playback;
19470 spec->stream_analog_capture = &alc680_pcm_analog_auto_capture;
19471 spec->stream_digital_playback = &alc680_pcm_digital_playback;
19472 spec->stream_digital_capture = &alc680_pcm_digital_capture;
19473
19474 if (!spec->adc_nids) {
19475 spec->adc_nids = alc680_adc_nids;
19476 spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids);
19477 }
19478
19479 if (!spec->cap_mixer)
19480 set_capture_mixer(codec);
19481
19482 spec->vmaster_nid = 0x02;
19483
19484 codec->patch_ops = alc_patch_ops;
19485 if (board_config == ALC680_AUTO)
19486 spec->init_hook = alc680_auto_init;
19487
19488 return 0;
19489}
19490
19491/*
18784 * patch entries 19492 * patch entries
18785 */ 19493 */
18786static struct hda_codec_preset snd_hda_preset_realtek[] = { 19494static struct hda_codec_preset snd_hda_preset_realtek[] = {
@@ -18804,6 +19512,7 @@ static struct hda_codec_preset snd_hda_preset_realtek[] = {
18804 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, 19512 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
18805 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 }, 19513 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
18806 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 }, 19514 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
19515 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
18807 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, 19516 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
18808 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, 19517 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
18809 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 }, 19518 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index f1e7babd692..95148e58026 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -94,6 +94,7 @@ enum {
94 STAC_92HD83XXX_PWR_REF, 94 STAC_92HD83XXX_PWR_REF,
95 STAC_DELL_S14, 95 STAC_DELL_S14,
96 STAC_92HD83XXX_HP, 96 STAC_92HD83XXX_HP,
97 STAC_HP_DV7_4000,
97 STAC_92HD83XXX_MODELS 98 STAC_92HD83XXX_MODELS
98}; 99};
99 100
@@ -202,6 +203,7 @@ struct sigmatel_spec {
202 unsigned int spdif_mute: 1; 203 unsigned int spdif_mute: 1;
203 unsigned int check_volume_offset:1; 204 unsigned int check_volume_offset:1;
204 unsigned int auto_mic:1; 205 unsigned int auto_mic:1;
206 unsigned int linear_tone_beep:1;
205 207
206 /* gpio lines */ 208 /* gpio lines */
207 unsigned int eapd_mask; 209 unsigned int eapd_mask;
@@ -1631,10 +1633,17 @@ static unsigned int dell_s14_pin_configs[10] = {
1631 0x40f000f0, 0x40f000f0, 1633 0x40f000f0, 0x40f000f0,
1632}; 1634};
1633 1635
1636static unsigned int hp_dv7_4000_pin_configs[10] = {
1637 0x03a12050, 0x0321201f, 0x40f000f0, 0x90170110,
1638 0x40f000f0, 0x40f000f0, 0x90170110, 0xd5a30140,
1639 0x40f000f0, 0x40f000f0,
1640};
1641
1634static unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = { 1642static unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = {
1635 [STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs, 1643 [STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs,
1636 [STAC_92HD83XXX_PWR_REF] = ref92hd83xxx_pin_configs, 1644 [STAC_92HD83XXX_PWR_REF] = ref92hd83xxx_pin_configs,
1637 [STAC_DELL_S14] = dell_s14_pin_configs, 1645 [STAC_DELL_S14] = dell_s14_pin_configs,
1646 [STAC_HP_DV7_4000] = hp_dv7_4000_pin_configs,
1638}; 1647};
1639 1648
1640static const char *stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = { 1649static const char *stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = {
@@ -1643,6 +1652,7 @@ static const char *stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = {
1643 [STAC_92HD83XXX_PWR_REF] = "mic-ref", 1652 [STAC_92HD83XXX_PWR_REF] = "mic-ref",
1644 [STAC_DELL_S14] = "dell-s14", 1653 [STAC_DELL_S14] = "dell-s14",
1645 [STAC_92HD83XXX_HP] = "hp", 1654 [STAC_92HD83XXX_HP] = "hp",
1655 [STAC_HP_DV7_4000] = "hp-dv7-4000",
1646}; 1656};
1647 1657
1648static struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { 1658static struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = {
@@ -3802,7 +3812,7 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
3802 return err; 3812 return err;
3803 if (codec->beep) { 3813 if (codec->beep) {
3804 /* IDT/STAC codecs have linear beep tone parameter */ 3814 /* IDT/STAC codecs have linear beep tone parameter */
3805 codec->beep->linear_tone = 1; 3815 codec->beep->linear_tone = spec->linear_tone_beep;
3806 /* if no beep switch is available, make its own one */ 3816 /* if no beep switch is available, make its own one */
3807 caps = query_amp_caps(codec, nid, HDA_OUTPUT); 3817 caps = query_amp_caps(codec, nid, HDA_OUTPUT);
3808 if (!(caps & AC_AMPCAP_MUTE)) { 3818 if (!(caps & AC_AMPCAP_MUTE)) {
@@ -5005,6 +5015,7 @@ static int patch_stac9200(struct hda_codec *codec)
5005 5015
5006 codec->no_trigger_sense = 1; 5016 codec->no_trigger_sense = 1;
5007 codec->spec = spec; 5017 codec->spec = spec;
5018 spec->linear_tone_beep = 1;
5008 spec->num_pins = ARRAY_SIZE(stac9200_pin_nids); 5019 spec->num_pins = ARRAY_SIZE(stac9200_pin_nids);
5009 spec->pin_nids = stac9200_pin_nids; 5020 spec->pin_nids = stac9200_pin_nids;
5010 spec->board_config = snd_hda_check_board_config(codec, STAC_9200_MODELS, 5021 spec->board_config = snd_hda_check_board_config(codec, STAC_9200_MODELS,
@@ -5068,6 +5079,7 @@ static int patch_stac925x(struct hda_codec *codec)
5068 5079
5069 codec->no_trigger_sense = 1; 5080 codec->no_trigger_sense = 1;
5070 codec->spec = spec; 5081 codec->spec = spec;
5082 spec->linear_tone_beep = 1;
5071 spec->num_pins = ARRAY_SIZE(stac925x_pin_nids); 5083 spec->num_pins = ARRAY_SIZE(stac925x_pin_nids);
5072 spec->pin_nids = stac925x_pin_nids; 5084 spec->pin_nids = stac925x_pin_nids;
5073 5085
@@ -5153,6 +5165,7 @@ static int patch_stac92hd73xx(struct hda_codec *codec)
5153 5165
5154 codec->no_trigger_sense = 1; 5166 codec->no_trigger_sense = 1;
5155 codec->spec = spec; 5167 codec->spec = spec;
5168 spec->linear_tone_beep = 0;
5156 codec->slave_dig_outs = stac92hd73xx_slave_dig_outs; 5169 codec->slave_dig_outs = stac92hd73xx_slave_dig_outs;
5157 spec->num_pins = ARRAY_SIZE(stac92hd73xx_pin_nids); 5170 spec->num_pins = ARRAY_SIZE(stac92hd73xx_pin_nids);
5158 spec->pin_nids = stac92hd73xx_pin_nids; 5171 spec->pin_nids = stac92hd73xx_pin_nids;
@@ -5300,6 +5313,7 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)
5300 5313
5301 codec->no_trigger_sense = 1; 5314 codec->no_trigger_sense = 1;
5302 codec->spec = spec; 5315 codec->spec = spec;
5316 spec->linear_tone_beep = 1;
5303 codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs; 5317 codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs;
5304 spec->digbeep_nid = 0x21; 5318 spec->digbeep_nid = 0x21;
5305 spec->mux_nids = stac92hd83xxx_mux_nids; 5319 spec->mux_nids = stac92hd83xxx_mux_nids;
@@ -5335,6 +5349,8 @@ again:
5335 case 0x111d7667: 5349 case 0x111d7667:
5336 case 0x111d7668: 5350 case 0x111d7668:
5337 case 0x111d7669: 5351 case 0x111d7669:
5352 case 0x111d76d1:
5353 case 0x111d76d9:
5338 spec->num_pins = ARRAY_SIZE(stac92hd88xxx_pin_nids); 5354 spec->num_pins = ARRAY_SIZE(stac92hd88xxx_pin_nids);
5339 spec->pin_nids = stac92hd88xxx_pin_nids; 5355 spec->pin_nids = stac92hd88xxx_pin_nids;
5340 spec->mono_nid = 0; 5356 spec->mono_nid = 0;
@@ -5522,6 +5538,7 @@ static int patch_stac92hd71bxx(struct hda_codec *codec)
5522 5538
5523 codec->no_trigger_sense = 1; 5539 codec->no_trigger_sense = 1;
5524 codec->spec = spec; 5540 codec->spec = spec;
5541 spec->linear_tone_beep = 0;
5525 codec->patch_ops = stac92xx_patch_ops; 5542 codec->patch_ops = stac92xx_patch_ops;
5526 spec->num_pins = STAC92HD71BXX_NUM_PINS; 5543 spec->num_pins = STAC92HD71BXX_NUM_PINS;
5527 switch (codec->vendor_id) { 5544 switch (codec->vendor_id) {
@@ -5779,6 +5796,7 @@ static int patch_stac922x(struct hda_codec *codec)
5779 5796
5780 codec->no_trigger_sense = 1; 5797 codec->no_trigger_sense = 1;
5781 codec->spec = spec; 5798 codec->spec = spec;
5799 spec->linear_tone_beep = 1;
5782 spec->num_pins = ARRAY_SIZE(stac922x_pin_nids); 5800 spec->num_pins = ARRAY_SIZE(stac922x_pin_nids);
5783 spec->pin_nids = stac922x_pin_nids; 5801 spec->pin_nids = stac922x_pin_nids;
5784 spec->board_config = snd_hda_check_board_config(codec, STAC_922X_MODELS, 5802 spec->board_config = snd_hda_check_board_config(codec, STAC_922X_MODELS,
@@ -5883,6 +5901,7 @@ static int patch_stac927x(struct hda_codec *codec)
5883 5901
5884 codec->no_trigger_sense = 1; 5902 codec->no_trigger_sense = 1;
5885 codec->spec = spec; 5903 codec->spec = spec;
5904 spec->linear_tone_beep = 1;
5886 codec->slave_dig_outs = stac927x_slave_dig_outs; 5905 codec->slave_dig_outs = stac927x_slave_dig_outs;
5887 spec->num_pins = ARRAY_SIZE(stac927x_pin_nids); 5906 spec->num_pins = ARRAY_SIZE(stac927x_pin_nids);
5888 spec->pin_nids = stac927x_pin_nids; 5907 spec->pin_nids = stac927x_pin_nids;
@@ -6018,6 +6037,7 @@ static int patch_stac9205(struct hda_codec *codec)
6018 6037
6019 codec->no_trigger_sense = 1; 6038 codec->no_trigger_sense = 1;
6020 codec->spec = spec; 6039 codec->spec = spec;
6040 spec->linear_tone_beep = 1;
6021 spec->num_pins = ARRAY_SIZE(stac9205_pin_nids); 6041 spec->num_pins = ARRAY_SIZE(stac9205_pin_nids);
6022 spec->pin_nids = stac9205_pin_nids; 6042 spec->pin_nids = stac9205_pin_nids;
6023 spec->board_config = snd_hda_check_board_config(codec, STAC_9205_MODELS, 6043 spec->board_config = snd_hda_check_board_config(codec, STAC_9205_MODELS,
@@ -6174,6 +6194,7 @@ static int patch_stac9872(struct hda_codec *codec)
6174 return -ENOMEM; 6194 return -ENOMEM;
6175 codec->no_trigger_sense = 1; 6195 codec->no_trigger_sense = 1;
6176 codec->spec = spec; 6196 codec->spec = spec;
6197 spec->linear_tone_beep = 1;
6177 spec->num_pins = ARRAY_SIZE(stac9872_pin_nids); 6198 spec->num_pins = ARRAY_SIZE(stac9872_pin_nids);
6178 spec->pin_nids = stac9872_pin_nids; 6199 spec->pin_nids = stac9872_pin_nids;
6179 6200
@@ -6264,6 +6285,8 @@ static struct hda_codec_preset snd_hda_preset_sigmatel[] = {
6264 { .id = 0x111d76d4, .name = "92HD83C1C5", .patch = patch_stac92hd83xxx}, 6285 { .id = 0x111d76d4, .name = "92HD83C1C5", .patch = patch_stac92hd83xxx},
6265 { .id = 0x111d7605, .name = "92HD81B1X5", .patch = patch_stac92hd83xxx}, 6286 { .id = 0x111d7605, .name = "92HD81B1X5", .patch = patch_stac92hd83xxx},
6266 { .id = 0x111d76d5, .name = "92HD81B1C5", .patch = patch_stac92hd83xxx}, 6287 { .id = 0x111d76d5, .name = "92HD81B1C5", .patch = patch_stac92hd83xxx},
6288 { .id = 0x111d76d1, .name = "92HD87B1/3", .patch = patch_stac92hd83xxx},
6289 { .id = 0x111d76d9, .name = "92HD87B2/4", .patch = patch_stac92hd83xxx},
6267 { .id = 0x111d7666, .name = "92HD88B3", .patch = patch_stac92hd83xxx}, 6290 { .id = 0x111d7666, .name = "92HD88B3", .patch = patch_stac92hd83xxx},
6268 { .id = 0x111d7667, .name = "92HD88B1", .patch = patch_stac92hd83xxx}, 6291 { .id = 0x111d7667, .name = "92HD88B1", .patch = patch_stac92hd83xxx},
6269 { .id = 0x111d7668, .name = "92HD88B2", .patch = patch_stac92hd83xxx}, 6292 { .id = 0x111d7668, .name = "92HD88B2", .patch = patch_stac92hd83xxx},
@@ -6280,6 +6303,21 @@ static struct hda_codec_preset snd_hda_preset_sigmatel[] = {
6280 { .id = 0x111d76b5, .name = "92HD71B6X", .patch = patch_stac92hd71bxx }, 6303 { .id = 0x111d76b5, .name = "92HD71B6X", .patch = patch_stac92hd71bxx },
6281 { .id = 0x111d76b6, .name = "92HD71B5X", .patch = patch_stac92hd71bxx }, 6304 { .id = 0x111d76b6, .name = "92HD71B5X", .patch = patch_stac92hd71bxx },
6282 { .id = 0x111d76b7, .name = "92HD71B5X", .patch = patch_stac92hd71bxx }, 6305 { .id = 0x111d76b7, .name = "92HD71B5X", .patch = patch_stac92hd71bxx },
6306 { .id = 0x111d76c0, .name = "92HD89C3", .patch = patch_stac92hd73xx },
6307 { .id = 0x111d76c1, .name = "92HD89C2", .patch = patch_stac92hd73xx },
6308 { .id = 0x111d76c2, .name = "92HD89C1", .patch = patch_stac92hd73xx },
6309 { .id = 0x111d76c3, .name = "92HD89B3", .patch = patch_stac92hd73xx },
6310 { .id = 0x111d76c4, .name = "92HD89B2", .patch = patch_stac92hd73xx },
6311 { .id = 0x111d76c5, .name = "92HD89B1", .patch = patch_stac92hd73xx },
6312 { .id = 0x111d76c6, .name = "92HD89E3", .patch = patch_stac92hd73xx },
6313 { .id = 0x111d76c7, .name = "92HD89E2", .patch = patch_stac92hd73xx },
6314 { .id = 0x111d76c8, .name = "92HD89E1", .patch = patch_stac92hd73xx },
6315 { .id = 0x111d76c9, .name = "92HD89D3", .patch = patch_stac92hd73xx },
6316 { .id = 0x111d76ca, .name = "92HD89D2", .patch = patch_stac92hd73xx },
6317 { .id = 0x111d76cb, .name = "92HD89D1", .patch = patch_stac92hd73xx },
6318 { .id = 0x111d76cc, .name = "92HD89F3", .patch = patch_stac92hd73xx },
6319 { .id = 0x111d76cd, .name = "92HD89F2", .patch = patch_stac92hd73xx },
6320 { .id = 0x111d76ce, .name = "92HD89F1", .patch = patch_stac92hd73xx },
6283 {} /* terminator */ 6321 {} /* terminator */
6284}; 6322};
6285 6323
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index 73453814e09..ae3acb2b42d 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -552,24 +552,30 @@ static void via_auto_init_hp_out(struct hda_codec *codec)
552 } 552 }
553} 553}
554 554
555static int is_smart51_pins(struct via_spec *spec, hda_nid_t pin);
556
555static void via_auto_init_analog_input(struct hda_codec *codec) 557static void via_auto_init_analog_input(struct hda_codec *codec)
556{ 558{
557 struct via_spec *spec = codec->spec; 559 struct via_spec *spec = codec->spec;
560 unsigned int ctl;
558 int i; 561 int i;
559 562
560 for (i = 0; i < AUTO_PIN_LAST; i++) { 563 for (i = 0; i < AUTO_PIN_LAST; i++) {
561 hda_nid_t nid = spec->autocfg.input_pins[i]; 564 hda_nid_t nid = spec->autocfg.input_pins[i];
565 if (!nid)
566 continue;
562 567
568 if (spec->smart51_enabled && is_smart51_pins(spec, nid))
569 ctl = PIN_OUT;
570 else if (i <= AUTO_PIN_FRONT_MIC)
571 ctl = PIN_VREF50;
572 else
573 ctl = PIN_IN;
563 snd_hda_codec_write(codec, nid, 0, 574 snd_hda_codec_write(codec, nid, 0,
564 AC_VERB_SET_PIN_WIDGET_CONTROL, 575 AC_VERB_SET_PIN_WIDGET_CONTROL, ctl);
565 (i <= AUTO_PIN_FRONT_MIC ?
566 PIN_VREF50 : PIN_IN));
567
568 } 576 }
569} 577}
570 578
571static int is_smart51_pins(struct via_spec *spec, hda_nid_t pin);
572
573static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid, 579static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid,
574 unsigned int *affected_parm) 580 unsigned int *affected_parm)
575{ 581{
@@ -658,6 +664,8 @@ static void set_jack_power_state(struct hda_codec *codec)
658 /* PW0 (19h), SW1 (18h), AOW1 (11h) */ 664 /* PW0 (19h), SW1 (18h), AOW1 (11h) */
659 parm = AC_PWRST_D3; 665 parm = AC_PWRST_D3;
660 set_pin_power_state(codec, 0x19, &parm); 666 set_pin_power_state(codec, 0x19, &parm);
667 if (spec->smart51_enabled)
668 parm = AC_PWRST_D0;
661 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, 669 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE,
662 parm); 670 parm);
663 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, 671 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE,
@@ -667,6 +675,8 @@ static void set_jack_power_state(struct hda_codec *codec)
667 if (is_8ch) { 675 if (is_8ch) {
668 parm = AC_PWRST_D3; 676 parm = AC_PWRST_D3;
669 set_pin_power_state(codec, 0x22, &parm); 677 set_pin_power_state(codec, 0x22, &parm);
678 if (spec->smart51_enabled)
679 parm = AC_PWRST_D0;
670 snd_hda_codec_write(codec, 0x26, 0, 680 snd_hda_codec_write(codec, 0x26, 0,
671 AC_VERB_SET_POWER_STATE, parm); 681 AC_VERB_SET_POWER_STATE, parm);
672 snd_hda_codec_write(codec, 0x24, 0, 682 snd_hda_codec_write(codec, 0x24, 0,
@@ -3915,6 +3925,13 @@ static int vt1708S_auto_fill_dac_nids(struct via_spec *spec,
3915 } 3925 }
3916 } 3926 }
3917 3927
3928 /* for Smart 5.1, line/mic inputs double as output pins */
3929 if (cfg->line_outs == 1) {
3930 spec->multiout.num_dacs = 3;
3931 spec->multiout.dac_nids[AUTO_SEQ_SURROUND] = 0x11;
3932 spec->multiout.dac_nids[AUTO_SEQ_CENLFE] = 0x24;
3933 }
3934
3918 return 0; 3935 return 0;
3919} 3936}
3920 3937
@@ -3932,7 +3949,8 @@ static int vt1708S_auto_create_multi_out_ctls(struct via_spec *spec,
3932 for (i = 0; i <= AUTO_SEQ_SIDE; i++) { 3949 for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
3933 nid = cfg->line_out_pins[i]; 3950 nid = cfg->line_out_pins[i];
3934 3951
3935 if (!nid) 3952 /* for Smart 5.1, there are always at least six channels */
3953 if (!nid && i > AUTO_SEQ_CENLFE)
3936 continue; 3954 continue;
3937 3955
3938 nid_vol = nid_vols[i]; 3956 nid_vol = nid_vols[i];
diff --git a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c
index d216362626d..712c1710f9a 100644
--- a/sound/pci/ice1712/delta.c
+++ b/sound/pci/ice1712/delta.c
@@ -563,6 +563,7 @@ static int __devinit snd_ice1712_delta_init(struct snd_ice1712 *ice)
563 case ICE1712_SUBDEVICE_DELTA1010E: 563 case ICE1712_SUBDEVICE_DELTA1010E:
564 case ICE1712_SUBDEVICE_DELTA1010LT: 564 case ICE1712_SUBDEVICE_DELTA1010LT:
565 case ICE1712_SUBDEVICE_MEDIASTATION: 565 case ICE1712_SUBDEVICE_MEDIASTATION:
566 case ICE1712_SUBDEVICE_EDIROLDA2496:
566 ice->num_total_dacs = 8; 567 ice->num_total_dacs = 8;
567 ice->num_total_adcs = 8; 568 ice->num_total_adcs = 8;
568 break; 569 break;
@@ -635,6 +636,7 @@ static int __devinit snd_ice1712_delta_init(struct snd_ice1712 *ice)
635 err = snd_ice1712_akm4xxx_init(ak, &akm_delta410, &akm_delta410_priv, ice); 636 err = snd_ice1712_akm4xxx_init(ak, &akm_delta410, &akm_delta410_priv, ice);
636 break; 637 break;
637 case ICE1712_SUBDEVICE_DELTA1010LT: 638 case ICE1712_SUBDEVICE_DELTA1010LT:
639 case ICE1712_SUBDEVICE_EDIROLDA2496:
638 err = snd_ice1712_akm4xxx_init(ak, &akm_delta1010lt, &akm_delta1010lt_priv, ice); 640 err = snd_ice1712_akm4xxx_init(ak, &akm_delta1010lt, &akm_delta1010lt_priv, ice);
639 break; 641 break;
640 case ICE1712_SUBDEVICE_DELTA66: 642 case ICE1712_SUBDEVICE_DELTA66:
@@ -734,6 +736,7 @@ static int __devinit snd_ice1712_delta_add_controls(struct snd_ice1712 *ice)
734 case ICE1712_SUBDEVICE_DELTA66: 736 case ICE1712_SUBDEVICE_DELTA66:
735 case ICE1712_SUBDEVICE_VX442: 737 case ICE1712_SUBDEVICE_VX442:
736 case ICE1712_SUBDEVICE_DELTA66E: 738 case ICE1712_SUBDEVICE_DELTA66E:
739 case ICE1712_SUBDEVICE_EDIROLDA2496:
737 err = snd_ice1712_akm4xxx_build_controls(ice); 740 err = snd_ice1712_akm4xxx_build_controls(ice);
738 if (err < 0) 741 if (err < 0)
739 return err; 742 return err;
@@ -813,5 +816,12 @@ struct snd_ice1712_card_info snd_ice1712_delta_cards[] __devinitdata = {
813 .chip_init = snd_ice1712_delta_init, 816 .chip_init = snd_ice1712_delta_init,
814 .build_controls = snd_ice1712_delta_add_controls, 817 .build_controls = snd_ice1712_delta_add_controls,
815 }, 818 },
819 {
820 .subvendor = ICE1712_SUBDEVICE_EDIROLDA2496,
821 .name = "Edirol DA2496",
822 .model = "da2496",
823 .chip_init = snd_ice1712_delta_init,
824 .build_controls = snd_ice1712_delta_add_controls,
825 },
816 { } /* terminator */ 826 { } /* terminator */
817}; 827};
diff --git a/sound/pci/ice1712/delta.h b/sound/pci/ice1712/delta.h
index f7f14df81f2..1a0ac6cd650 100644
--- a/sound/pci/ice1712/delta.h
+++ b/sound/pci/ice1712/delta.h
@@ -34,7 +34,8 @@
34 "{MidiMan M Audio,Delta 410},"\ 34 "{MidiMan M Audio,Delta 410},"\
35 "{MidiMan M Audio,Audiophile 24/96},"\ 35 "{MidiMan M Audio,Audiophile 24/96},"\
36 "{Digigram,VX442},"\ 36 "{Digigram,VX442},"\
37 "{Lionstracs,Mediastation}," 37 "{Lionstracs,Mediastation},"\
38 "{Edirol,DA2496},"
38 39
39#define ICE1712_SUBDEVICE_DELTA1010 0x121430d6 40#define ICE1712_SUBDEVICE_DELTA1010 0x121430d6
40#define ICE1712_SUBDEVICE_DELTA1010E 0xff1430d6 41#define ICE1712_SUBDEVICE_DELTA1010E 0xff1430d6
@@ -47,6 +48,7 @@
47#define ICE1712_SUBDEVICE_DELTA1010LT 0x12143bd6 48#define ICE1712_SUBDEVICE_DELTA1010LT 0x12143bd6
48#define ICE1712_SUBDEVICE_VX442 0x12143cd6 49#define ICE1712_SUBDEVICE_VX442 0x12143cd6
49#define ICE1712_SUBDEVICE_MEDIASTATION 0x694c0100 50#define ICE1712_SUBDEVICE_MEDIASTATION 0x694c0100
51#define ICE1712_SUBDEVICE_EDIROLDA2496 0xce164010
50 52
51/* entry point */ 53/* entry point */
52extern struct snd_ice1712_card_info snd_ice1712_delta_cards[]; 54extern struct snd_ice1712_card_info snd_ice1712_delta_cards[];
diff --git a/sound/pci/ice1712/pontis.c b/sound/pci/ice1712/pontis.c
index 6bc3f91b728..cdb873f5da5 100644
--- a/sound/pci/ice1712/pontis.c
+++ b/sound/pci/ice1712/pontis.c
@@ -638,7 +638,7 @@ static struct snd_kcontrol_new pontis_controls[] __devinitdata = {
638 */ 638 */
639static void wm_proc_regs_write(struct snd_info_entry *entry, struct snd_info_buffer *buffer) 639static void wm_proc_regs_write(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
640{ 640{
641 struct snd_ice1712 *ice = (struct snd_ice1712 *)entry->private_data; 641 struct snd_ice1712 *ice = entry->private_data;
642 char line[64]; 642 char line[64];
643 unsigned int reg, val; 643 unsigned int reg, val;
644 mutex_lock(&ice->gpio_mutex); 644 mutex_lock(&ice->gpio_mutex);
@@ -653,7 +653,7 @@ static void wm_proc_regs_write(struct snd_info_entry *entry, struct snd_info_buf
653 653
654static void wm_proc_regs_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) 654static void wm_proc_regs_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
655{ 655{
656 struct snd_ice1712 *ice = (struct snd_ice1712 *)entry->private_data; 656 struct snd_ice1712 *ice = entry->private_data;
657 int reg, val; 657 int reg, val;
658 658
659 mutex_lock(&ice->gpio_mutex); 659 mutex_lock(&ice->gpio_mutex);
@@ -676,7 +676,7 @@ static void wm_proc_init(struct snd_ice1712 *ice)
676 676
677static void cs_proc_regs_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) 677static void cs_proc_regs_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
678{ 678{
679 struct snd_ice1712 *ice = (struct snd_ice1712 *)entry->private_data; 679 struct snd_ice1712 *ice = entry->private_data;
680 int reg, val; 680 int reg, val;
681 681
682 mutex_lock(&ice->gpio_mutex); 682 mutex_lock(&ice->gpio_mutex);
diff --git a/sound/pci/ice1712/prodigy192.c b/sound/pci/ice1712/prodigy192.c
index 2a8e5cd8f2d..e36ddb94c38 100644
--- a/sound/pci/ice1712/prodigy192.c
+++ b/sound/pci/ice1712/prodigy192.c
@@ -654,7 +654,7 @@ static int prodigy192_ak4114_init(struct snd_ice1712 *ice)
654static void stac9460_proc_regs_read(struct snd_info_entry *entry, 654static void stac9460_proc_regs_read(struct snd_info_entry *entry,
655 struct snd_info_buffer *buffer) 655 struct snd_info_buffer *buffer)
656{ 656{
657 struct snd_ice1712 *ice = (struct snd_ice1712 *)entry->private_data; 657 struct snd_ice1712 *ice = entry->private_data;
658 int reg, val; 658 int reg, val;
659 /* registers 0x0 - 0x14 */ 659 /* registers 0x0 - 0x14 */
660 for (reg = 0; reg <= 0x15; reg++) { 660 for (reg = 0; reg <= 0x15; reg++) {
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index 6433e65c950..46774924957 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -1776,6 +1776,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
1776 }, 1776 },
1777 { 1777 {
1778 .subvendor = 0x1014, 1778 .subvendor = 0x1014,
1779 .subdevice = 0x0534,
1780 .name = "ThinkPad X31",
1781 .type = AC97_TUNE_INV_EAPD
1782 },
1783 {
1784 .subvendor = 0x1014,
1779 .subdevice = 0x1f00, 1785 .subdevice = 0x1f00,
1780 .name = "MS-9128", 1786 .name = "MS-9128",
1781 .type = AC97_TUNE_ALC_JACK 1787 .type = AC97_TUNE_ALC_JACK
diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c
index 289cb4dacfc..98a8eb3c92f 100644
--- a/sound/pci/oxygen/oxygen.c
+++ b/sound/pci/oxygen/oxygen.c
@@ -79,6 +79,7 @@ static DEFINE_PCI_DEVICE_TABLE(oxygen_ids) = {
79 { OXYGEN_PCI_SUBID(0x13f6, 0x0001), .driver_data = MODEL_CMEDIA_REF }, 79 { OXYGEN_PCI_SUBID(0x13f6, 0x0001), .driver_data = MODEL_CMEDIA_REF },
80 { OXYGEN_PCI_SUBID(0x13f6, 0x0010), .driver_data = MODEL_CMEDIA_REF }, 80 { OXYGEN_PCI_SUBID(0x13f6, 0x0010), .driver_data = MODEL_CMEDIA_REF },
81 { OXYGEN_PCI_SUBID(0x13f6, 0x8788), .driver_data = MODEL_CMEDIA_REF }, 81 { OXYGEN_PCI_SUBID(0x13f6, 0x8788), .driver_data = MODEL_CMEDIA_REF },
82 { OXYGEN_PCI_SUBID(0x13f6, 0xffff), .driver_data = MODEL_CMEDIA_REF },
82 { OXYGEN_PCI_SUBID(0x147a, 0xa017), .driver_data = MODEL_CMEDIA_REF }, 83 { OXYGEN_PCI_SUBID(0x147a, 0xa017), .driver_data = MODEL_CMEDIA_REF },
83 { OXYGEN_PCI_SUBID(0x1a58, 0x0910), .driver_data = MODEL_CMEDIA_REF }, 84 { OXYGEN_PCI_SUBID(0x1a58, 0x0910), .driver_data = MODEL_CMEDIA_REF },
84 { OXYGEN_PCI_SUBID(0x415a, 0x5431), .driver_data = MODEL_MERIDIAN }, 85 { OXYGEN_PCI_SUBID(0x415a, 0x5431), .driver_data = MODEL_MERIDIAN },
@@ -505,7 +506,8 @@ static const struct oxygen_model model_generic = {
505 PLAYBACK_2_TO_AC97_1 | 506 PLAYBACK_2_TO_AC97_1 |
506 CAPTURE_0_FROM_I2S_1 | 507 CAPTURE_0_FROM_I2S_1 |
507 CAPTURE_1_FROM_SPDIF | 508 CAPTURE_1_FROM_SPDIF |
508 CAPTURE_2_FROM_AC97_1, 509 CAPTURE_2_FROM_AC97_1 |
510 AC97_CD_INPUT,
509 .dac_channels = 8, 511 .dac_channels = 8,
510 .dac_volume_min = 0, 512 .dac_volume_min = 0,
511 .dac_volume_max = 255, 513 .dac_volume_max = 255,
@@ -543,6 +545,10 @@ static int __devinit get_oxygen_model(struct oxygen *chip,
543 chip->model.suspend = claro_suspend; 545 chip->model.suspend = claro_suspend;
544 chip->model.resume = claro_resume; 546 chip->model.resume = claro_resume;
545 chip->model.set_adc_params = set_ak5385_params; 547 chip->model.set_adc_params = set_ak5385_params;
548 chip->model.device_config = PLAYBACK_0_TO_I2S |
549 PLAYBACK_1_TO_SPDIF |
550 CAPTURE_0_FROM_I2S_2 |
551 CAPTURE_1_FROM_SPDIF;
546 break; 552 break;
547 } 553 }
548 if (id->driver_data == MODEL_MERIDIAN || 554 if (id->driver_data == MODEL_MERIDIAN ||
diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h
index 6147216af74..7d5222caa0a 100644
--- a/sound/pci/oxygen/oxygen.h
+++ b/sound/pci/oxygen/oxygen.h
@@ -34,6 +34,7 @@
34 /* CAPTURE_3_FROM_I2S_3 not implemented */ 34 /* CAPTURE_3_FROM_I2S_3 not implemented */
35#define MIDI_OUTPUT 0x0800 35#define MIDI_OUTPUT 0x0800
36#define MIDI_INPUT 0x1000 36#define MIDI_INPUT 0x1000
37#define AC97_CD_INPUT 0x2000
37 38
38enum { 39enum {
39 CONTROL_SPDIF_PCM, 40 CONTROL_SPDIF_PCM,
@@ -155,6 +156,7 @@ void oxygen_pci_remove(struct pci_dev *pci);
155int oxygen_pci_suspend(struct pci_dev *pci, pm_message_t state); 156int oxygen_pci_suspend(struct pci_dev *pci, pm_message_t state);
156int oxygen_pci_resume(struct pci_dev *pci); 157int oxygen_pci_resume(struct pci_dev *pci);
157#endif 158#endif
159void oxygen_pci_shutdown(struct pci_dev *pci);
158 160
159/* oxygen_mixer.c */ 161/* oxygen_mixer.c */
160 162
diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c
index fad03d64e3a..e5ebe56fb0c 100644
--- a/sound/pci/oxygen/oxygen_lib.c
+++ b/sound/pci/oxygen/oxygen_lib.c
@@ -308,25 +308,46 @@ static void oxygen_restore_eeprom(struct oxygen *chip,
308 } 308 }
309} 309}
310 310
311static void pci_bridge_magic(void) 311static void configure_pcie_bridge(struct pci_dev *pci)
312{ 312{
313 struct pci_dev *pci = NULL; 313 enum { PEX811X, PI7C9X110 };
314 static const struct pci_device_id bridge_ids[] = {
315 { PCI_VDEVICE(PLX, 0x8111), .driver_data = PEX811X },
316 { PCI_VDEVICE(PLX, 0x8112), .driver_data = PEX811X },
317 { PCI_DEVICE(0x12d8, 0xe110), .driver_data = PI7C9X110 },
318 { }
319 };
320 struct pci_dev *bridge;
321 const struct pci_device_id *id;
314 u32 tmp; 322 u32 tmp;
315 323
316 for (;;) { 324 if (!pci->bus || !pci->bus->self)
317 /* If there is any Pericom PI7C9X110 PCI-E/PCI bridge ... */ 325 return;
318 pci = pci_get_device(0x12d8, 0xe110, pci); 326 bridge = pci->bus->self;
319 if (!pci) 327
320 break; 328 id = pci_match_id(bridge_ids, bridge);
321 /* 329 if (!id)
322 * ... configure its secondary internal arbiter to park to 330 return;
323 * the secondary port, instead of to the last master. 331
324 */ 332 switch (id->driver_data) {
325 if (!pci_read_config_dword(pci, 0x40, &tmp)) { 333 case PEX811X: /* PLX PEX8111/PEX8112 PCIe/PCI bridge */
326 tmp |= 1; 334 pci_read_config_dword(bridge, 0x48, &tmp);
327 pci_write_config_dword(pci, 0x40, tmp); 335 tmp |= 1; /* enable blind prefetching */
328 } 336 tmp |= 1 << 11; /* enable beacon generation */
329 /* Why? Try asking C-Media. */ 337 pci_write_config_dword(bridge, 0x48, tmp);
338
339 pci_write_config_dword(bridge, 0x84, 0x0c);
340 pci_read_config_dword(bridge, 0x88, &tmp);
341 tmp &= ~(7 << 27);
342 tmp |= 2 << 27; /* set prefetch size to 128 bytes */
343 pci_write_config_dword(bridge, 0x88, tmp);
344 break;
345
346 case PI7C9X110: /* Pericom PI7C9X110 PCIe/PCI bridge */
347 pci_read_config_dword(bridge, 0x40, &tmp);
348 tmp |= 1; /* park the PCI arbiter to the sound chip */
349 pci_write_config_dword(bridge, 0x40, tmp);
350 break;
330 } 351 }
331} 352}
332 353
@@ -519,16 +540,21 @@ static void oxygen_init(struct oxygen *chip)
519 } 540 }
520} 541}
521 542
522static void oxygen_card_free(struct snd_card *card) 543static void oxygen_shutdown(struct oxygen *chip)
523{ 544{
524 struct oxygen *chip = card->private_data;
525
526 spin_lock_irq(&chip->reg_lock); 545 spin_lock_irq(&chip->reg_lock);
527 chip->interrupt_mask = 0; 546 chip->interrupt_mask = 0;
528 chip->pcm_running = 0; 547 chip->pcm_running = 0;
529 oxygen_write16(chip, OXYGEN_DMA_STATUS, 0); 548 oxygen_write16(chip, OXYGEN_DMA_STATUS, 0);
530 oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, 0); 549 oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, 0);
531 spin_unlock_irq(&chip->reg_lock); 550 spin_unlock_irq(&chip->reg_lock);
551}
552
553static void oxygen_card_free(struct snd_card *card)
554{
555 struct oxygen *chip = card->private_data;
556
557 oxygen_shutdown(chip);
532 if (chip->irq >= 0) 558 if (chip->irq >= 0)
533 free_irq(chip->irq, chip); 559 free_irq(chip->irq, chip);
534 flush_scheduled_work(); 560 flush_scheduled_work();
@@ -608,7 +634,7 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
608 snd_card_set_dev(card, &pci->dev); 634 snd_card_set_dev(card, &pci->dev);
609 card->private_free = oxygen_card_free; 635 card->private_free = oxygen_card_free;
610 636
611 pci_bridge_magic(); 637 configure_pcie_bridge(pci);
612 oxygen_init(chip); 638 oxygen_init(chip);
613 chip->model.init(chip); 639 chip->model.init(chip);
614 640
@@ -778,3 +804,13 @@ int oxygen_pci_resume(struct pci_dev *pci)
778} 804}
779EXPORT_SYMBOL(oxygen_pci_resume); 805EXPORT_SYMBOL(oxygen_pci_resume);
780#endif /* CONFIG_PM */ 806#endif /* CONFIG_PM */
807
808void oxygen_pci_shutdown(struct pci_dev *pci)
809{
810 struct snd_card *card = pci_get_drvdata(pci);
811 struct oxygen *chip = card->private_data;
812
813 oxygen_shutdown(chip);
814 chip->model.cleanup(chip);
815}
816EXPORT_SYMBOL(oxygen_pci_shutdown);
diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c
index f375b8a2786..2849b36f5f7 100644
--- a/sound/pci/oxygen/oxygen_mixer.c
+++ b/sound/pci/oxygen/oxygen_mixer.c
@@ -708,7 +708,7 @@ static int ac97_fp_rec_volume_put(struct snd_kcontrol *ctl,
708 .private_value = ((codec) << 24) | ((stereo) << 16) | (index), \ 708 .private_value = ((codec) << 24) | ((stereo) << 16) | (index), \
709 } 709 }
710 710
711static DECLARE_TLV_DB_SCALE(monitor_db_scale, -1000, 1000, 0); 711static DECLARE_TLV_DB_SCALE(monitor_db_scale, -600, 600, 0);
712static DECLARE_TLV_DB_SCALE(ac97_db_scale, -3450, 150, 0); 712static DECLARE_TLV_DB_SCALE(ac97_db_scale, -3450, 150, 0);
713static DECLARE_TLV_DB_SCALE(ac97_rec_db_scale, 0, 150, 0); 713static DECLARE_TLV_DB_SCALE(ac97_rec_db_scale, 0, 150, 0);
714 714
@@ -972,6 +972,9 @@ static int add_controls(struct oxygen *chip,
972 if (!strcmp(template.name, "Stereo Upmixing") && 972 if (!strcmp(template.name, "Stereo Upmixing") &&
973 chip->model.dac_channels == 2) 973 chip->model.dac_channels == 2)
974 continue; 974 continue;
975 if (!strncmp(template.name, "CD Capture ", 11) &&
976 !(chip->model.device_config & AC97_CD_INPUT))
977 continue;
975 if (!strcmp(template.name, "Master Playback Volume") && 978 if (!strcmp(template.name, "Master Playback Volume") &&
976 chip->model.dac_tlv) { 979 chip->model.dac_tlv) {
977 template.tlv.p = chip->model.dac_tlv; 980 template.tlv.p = chip->model.dac_tlv;
diff --git a/sound/pci/oxygen/oxygen_pcm.c b/sound/pci/oxygen/oxygen_pcm.c
index 9dff6954c39..814667442eb 100644
--- a/sound/pci/oxygen/oxygen_pcm.c
+++ b/sound/pci/oxygen/oxygen_pcm.c
@@ -56,8 +56,8 @@ static const struct snd_pcm_hardware oxygen_stereo_hardware = {
56 .channels_max = 2, 56 .channels_max = 2,
57 .buffer_bytes_max = BUFFER_BYTES_MAX, 57 .buffer_bytes_max = BUFFER_BYTES_MAX,
58 .period_bytes_min = PERIOD_BYTES_MIN, 58 .period_bytes_min = PERIOD_BYTES_MIN,
59 .period_bytes_max = BUFFER_BYTES_MAX / 2, 59 .period_bytes_max = BUFFER_BYTES_MAX,
60 .periods_min = 2, 60 .periods_min = 1,
61 .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN, 61 .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN,
62}; 62};
63static const struct snd_pcm_hardware oxygen_multichannel_hardware = { 63static const struct snd_pcm_hardware oxygen_multichannel_hardware = {
@@ -82,8 +82,8 @@ static const struct snd_pcm_hardware oxygen_multichannel_hardware = {
82 .channels_max = 8, 82 .channels_max = 8,
83 .buffer_bytes_max = BUFFER_BYTES_MAX_MULTICH, 83 .buffer_bytes_max = BUFFER_BYTES_MAX_MULTICH,
84 .period_bytes_min = PERIOD_BYTES_MIN, 84 .period_bytes_min = PERIOD_BYTES_MIN,
85 .period_bytes_max = BUFFER_BYTES_MAX_MULTICH / 2, 85 .period_bytes_max = BUFFER_BYTES_MAX_MULTICH,
86 .periods_min = 2, 86 .periods_min = 1,
87 .periods_max = BUFFER_BYTES_MAX_MULTICH / PERIOD_BYTES_MIN, 87 .periods_max = BUFFER_BYTES_MAX_MULTICH / PERIOD_BYTES_MIN,
88}; 88};
89static const struct snd_pcm_hardware oxygen_ac97_hardware = { 89static const struct snd_pcm_hardware oxygen_ac97_hardware = {
@@ -100,8 +100,8 @@ static const struct snd_pcm_hardware oxygen_ac97_hardware = {
100 .channels_max = 2, 100 .channels_max = 2,
101 .buffer_bytes_max = BUFFER_BYTES_MAX, 101 .buffer_bytes_max = BUFFER_BYTES_MAX,
102 .period_bytes_min = PERIOD_BYTES_MIN, 102 .period_bytes_min = PERIOD_BYTES_MIN,
103 .period_bytes_max = BUFFER_BYTES_MAX / 2, 103 .period_bytes_max = BUFFER_BYTES_MAX,
104 .periods_min = 2, 104 .periods_min = 1,
105 .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN, 105 .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN,
106}; 106};
107 107
diff --git a/sound/pci/oxygen/oxygen_regs.h b/sound/pci/oxygen/oxygen_regs.h
index 72de159d456..4dcd41b7825 100644
--- a/sound/pci/oxygen/oxygen_regs.h
+++ b/sound/pci/oxygen/oxygen_regs.h
@@ -436,13 +436,15 @@
436/* OXYGEN_CHANNEL_* */ 436/* OXYGEN_CHANNEL_* */
437 437
438#define OXYGEN_CODEC_VERSION 0xe4 438#define OXYGEN_CODEC_VERSION 0xe4
439#define OXYGEN_XCID_MASK 0x07 439#define OXYGEN_CODEC_ID_MASK 0x07
440 440
441#define OXYGEN_REVISION 0xe6 441#define OXYGEN_REVISION 0xe6
442#define OXYGEN_REVISION_XPKGID_MASK 0x0007 442#define OXYGEN_PACKAGE_ID_MASK 0x0007
443#define OXYGEN_PACKAGE_ID_8786 0x0004
444#define OXYGEN_PACKAGE_ID_8787 0x0006
445#define OXYGEN_PACKAGE_ID_8788 0x0007
443#define OXYGEN_REVISION_MASK 0xfff8 446#define OXYGEN_REVISION_MASK 0xfff8
444#define OXYGEN_REVISION_2 0x0008 /* bit flag */ 447#define OXYGEN_REVISION_2 0x0008
445#define OXYGEN_REVISION_8787 0x0014 /* 8 bits */
446 448
447#define OXYGEN_OFFSIN_48K 0xe8 449#define OXYGEN_OFFSIN_48K 0xe8
448#define OXYGEN_OFFSBASE_48K 0xe9 450#define OXYGEN_OFFSBASE_48K 0xe9
diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c
index f03a2f2cffe..469010a8b84 100644
--- a/sound/pci/oxygen/virtuoso.c
+++ b/sound/pci/oxygen/virtuoso.c
@@ -25,9 +25,9 @@
25#include "xonar.h" 25#include "xonar.h"
26 26
27MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); 27MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
28MODULE_DESCRIPTION("Asus AVx00 driver"); 28MODULE_DESCRIPTION("Asus Virtuoso driver");
29MODULE_LICENSE("GPL v2"); 29MODULE_LICENSE("GPL v2");
30MODULE_SUPPORTED_DEVICE("{{Asus,AV100},{Asus,AV200}}"); 30MODULE_SUPPORTED_DEVICE("{{Asus,AV66},{Asus,AV100},{Asus,AV200}}");
31 31
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;
@@ -49,6 +49,7 @@ static DEFINE_PCI_DEVICE_TABLE(xonar_ids) = {
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, 0x835e) },
52 { OXYGEN_PCI_SUBID(0x1043, 0x838e) }, 53 { OXYGEN_PCI_SUBID(0x1043, 0x838e) },
53 { OXYGEN_PCI_SUBID_BROKEN_EEPROM }, 54 { OXYGEN_PCI_SUBID_BROKEN_EEPROM },
54 { } 55 { }
@@ -95,6 +96,7 @@ static struct pci_driver xonar_driver = {
95 .suspend = oxygen_pci_suspend, 96 .suspend = oxygen_pci_suspend,
96 .resume = oxygen_pci_resume, 97 .resume = oxygen_pci_resume,
97#endif 98#endif
99 .shutdown = oxygen_pci_shutdown,
98}; 100};
99 101
100static int __init alsa_card_xonar_init(void) 102static int __init alsa_card_xonar_init(void)
diff --git a/sound/pci/oxygen/xonar_cs43xx.c b/sound/pci/oxygen/xonar_cs43xx.c
index 7c4986b27f2..aa27c31049a 100644
--- a/sound/pci/oxygen/xonar_cs43xx.c
+++ b/sound/pci/oxygen/xonar_cs43xx.c
@@ -367,13 +367,6 @@ static void xonar_d1_line_mic_ac97_switch(struct oxygen *chip,
367 367
368static const DECLARE_TLV_DB_SCALE(cs4362a_db_scale, -6000, 100, 0); 368static const DECLARE_TLV_DB_SCALE(cs4362a_db_scale, -6000, 100, 0);
369 369
370static int xonar_d1_control_filter(struct snd_kcontrol_new *template)
371{
372 if (!strncmp(template->name, "CD Capture ", 11))
373 return 1; /* no CD input */
374 return 0;
375}
376
377static int xonar_d1_mixer_init(struct oxygen *chip) 370static int xonar_d1_mixer_init(struct oxygen *chip)
378{ 371{
379 int err; 372 int err;
@@ -391,7 +384,6 @@ static const struct oxygen_model model_xonar_d1 = {
391 .longname = "Asus Virtuoso 100", 384 .longname = "Asus Virtuoso 100",
392 .chip = "AV200", 385 .chip = "AV200",
393 .init = xonar_d1_init, 386 .init = xonar_d1_init,
394 .control_filter = xonar_d1_control_filter,
395 .mixer_init = xonar_d1_mixer_init, 387 .mixer_init = xonar_d1_mixer_init,
396 .cleanup = xonar_d1_cleanup, 388 .cleanup = xonar_d1_cleanup,
397 .suspend = xonar_d1_suspend, 389 .suspend = xonar_d1_suspend,
diff --git a/sound/pci/oxygen/xonar_pcm179x.c b/sound/pci/oxygen/xonar_pcm179x.c
index ba18fb546b4..d491fd6c0be 100644
--- a/sound/pci/oxygen/xonar_pcm179x.c
+++ b/sound/pci/oxygen/xonar_pcm179x.c
@@ -132,6 +132,18 @@
132 * GPIO 5 <- 0 132 * GPIO 5 <- 0
133 */ 133 */
134 134
135/*
136 * Xonar HDAV1.3 Slim
137 * ------------------
138 *
139 * CMI8788:
140 *
141 * GPIO 1 -> enable output
142 *
143 * TXD -> HDMI controller
144 * RXD <- HDMI controller
145 */
146
135#include <linux/pci.h> 147#include <linux/pci.h>
136#include <linux/delay.h> 148#include <linux/delay.h>
137#include <linux/mutex.h> 149#include <linux/mutex.h>
@@ -362,7 +374,6 @@ static void xonar_st_init_common(struct oxygen *chip)
362{ 374{
363 struct xonar_pcm179x *data = chip->model_data; 375 struct xonar_pcm179x *data = chip->model_data;
364 376
365 data->generic.anti_pop_delay = 100;
366 data->generic.output_enable_bit = GPIO_ST_OUTPUT_ENABLE; 377 data->generic.output_enable_bit = GPIO_ST_OUTPUT_ENABLE;
367 data->dacs = chip->model.private_data ? 4 : 1; 378 data->dacs = chip->model.private_data ? 4 : 1;
368 data->hp_gain_offset = 2*-18; 379 data->hp_gain_offset = 2*-18;
@@ -408,6 +419,7 @@ static void xonar_st_init(struct oxygen *chip)
408{ 419{
409 struct xonar_pcm179x *data = chip->model_data; 420 struct xonar_pcm179x *data = chip->model_data;
410 421
422 data->generic.anti_pop_delay = 100;
411 data->has_cs2000 = 1; 423 data->has_cs2000 = 1;
412 data->cs2000_fun_cfg_1 = CS2000_REF_CLK_DIV_1; 424 data->cs2000_fun_cfg_1 = CS2000_REF_CLK_DIV_1;
413 425
@@ -428,6 +440,7 @@ static void xonar_stx_init(struct oxygen *chip)
428 struct xonar_pcm179x *data = chip->model_data; 440 struct xonar_pcm179x *data = chip->model_data;
429 441
430 xonar_st_init_i2c(chip); 442 xonar_st_init_i2c(chip);
443 data->generic.anti_pop_delay = 800;
431 data->generic.ext_power_reg = OXYGEN_GPI_DATA; 444 data->generic.ext_power_reg = OXYGEN_GPI_DATA;
432 data->generic.ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK; 445 data->generic.ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK;
433 data->generic.ext_power_bit = GPI_EXT_POWER; 446 data->generic.ext_power_bit = GPI_EXT_POWER;
@@ -915,13 +928,6 @@ static int xonar_d2_control_filter(struct snd_kcontrol_new *template)
915 return 0; 928 return 0;
916} 929}
917 930
918static int xonar_st_control_filter(struct snd_kcontrol_new *template)
919{
920 if (!strncmp(template->name, "CD Capture ", 11))
921 return 1; /* no CD input */
922 return 0;
923}
924
925static int add_pcm1796_controls(struct oxygen *chip) 931static int add_pcm1796_controls(struct oxygen *chip)
926{ 932{
927 int err; 933 int err;
@@ -991,7 +997,8 @@ static const struct oxygen_model model_xonar_d2 = {
991 CAPTURE_0_FROM_I2S_2 | 997 CAPTURE_0_FROM_I2S_2 |
992 CAPTURE_1_FROM_SPDIF | 998 CAPTURE_1_FROM_SPDIF |
993 MIDI_OUTPUT | 999 MIDI_OUTPUT |
994 MIDI_INPUT, 1000 MIDI_INPUT |
1001 AC97_CD_INPUT,
995 .dac_channels = 8, 1002 .dac_channels = 8,
996 .dac_volume_min = 255 - 2*60, 1003 .dac_volume_min = 255 - 2*60,
997 .dac_volume_max = 255, 1004 .dac_volume_max = 255,
@@ -1037,7 +1044,6 @@ static const struct oxygen_model model_xonar_st = {
1037 .longname = "Asus Virtuoso 100", 1044 .longname = "Asus Virtuoso 100",
1038 .chip = "AV200", 1045 .chip = "AV200",
1039 .init = xonar_st_init, 1046 .init = xonar_st_init,
1040 .control_filter = xonar_st_control_filter,
1041 .mixer_init = xonar_st_mixer_init, 1047 .mixer_init = xonar_st_mixer_init,
1042 .cleanup = xonar_st_cleanup, 1048 .cleanup = xonar_st_cleanup,
1043 .suspend = xonar_st_suspend, 1049 .suspend = xonar_st_suspend,
@@ -1108,6 +1114,9 @@ int __devinit get_xonar_pcm179x_model(struct oxygen *chip,
1108 chip->model.resume = xonar_stx_resume; 1114 chip->model.resume = xonar_stx_resume;
1109 chip->model.set_dac_params = set_pcm1796_params; 1115 chip->model.set_dac_params = set_pcm1796_params;
1110 break; 1116 break;
1117 case 0x835e:
1118 snd_printk(KERN_ERR "the HDAV1.3 Slim is not supported\n");
1119 return -ENODEV;
1111 default: 1120 default:
1112 return -EINVAL; 1121 return -EINVAL;
1113 } 1122 }
diff --git a/sound/pci/oxygen/xonar_wm87x6.c b/sound/pci/oxygen/xonar_wm87x6.c
index dbc4b89d74e..200f7601276 100644
--- a/sound/pci/oxygen/xonar_wm87x6.c
+++ b/sound/pci/oxygen/xonar_wm87x6.c
@@ -25,16 +25,24 @@
25 * SPI 0 -> WM8766 (surround, center/LFE, back) 25 * SPI 0 -> WM8766 (surround, center/LFE, back)
26 * SPI 1 -> WM8776 (front, input) 26 * SPI 1 -> WM8776 (front, input)
27 * 27 *
28 * GPIO 4 <- headphone detect 28 * GPIO 4 <- headphone detect, 0 = plugged
29 * GPIO 6 -> route input jack to input 1/2 (1/0) 29 * GPIO 6 -> route input jack to mic-in (0) or line-in (1)
30 * GPIO 7 -> enable output to speakers 30 * GPIO 7 -> enable output to front L/R speaker channels
31 * GPIO 8 -> enable output to speakers 31 * GPIO 8 -> enable output to other speaker channels and front panel headphone
32 *
33 * WM8766:
34 *
35 * input 1 <- line
36 * input 2 <- mic
37 * input 3 <- front mic
38 * input 4 <- aux
32 */ 39 */
33 40
34#include <linux/pci.h> 41#include <linux/pci.h>
35#include <linux/delay.h> 42#include <linux/delay.h>
36#include <sound/control.h> 43#include <sound/control.h>
37#include <sound/core.h> 44#include <sound/core.h>
45#include <sound/jack.h>
38#include <sound/pcm.h> 46#include <sound/pcm.h>
39#include <sound/pcm_params.h> 47#include <sound/pcm_params.h>
40#include <sound/tlv.h> 48#include <sound/tlv.h>
@@ -44,7 +52,8 @@
44 52
45#define GPIO_DS_HP_DETECT 0x0010 53#define GPIO_DS_HP_DETECT 0x0010
46#define GPIO_DS_INPUT_ROUTE 0x0040 54#define GPIO_DS_INPUT_ROUTE 0x0040
47#define GPIO_DS_OUTPUT_ENABLE 0x0180 55#define GPIO_DS_OUTPUT_FRONTLR 0x0080
56#define GPIO_DS_OUTPUT_ENABLE 0x0100
48 57
49#define LC_CONTROL_LIMITER 0x40000000 58#define LC_CONTROL_LIMITER 0x40000000
50#define LC_CONTROL_ALC 0x20000000 59#define LC_CONTROL_ALC 0x20000000
@@ -53,7 +62,10 @@ struct xonar_wm87x6 {
53 struct xonar_generic generic; 62 struct xonar_generic generic;
54 u16 wm8776_regs[0x17]; 63 u16 wm8776_regs[0x17];
55 u16 wm8766_regs[0x10]; 64 u16 wm8766_regs[0x10];
65 struct snd_kcontrol *line_adcmux_control;
66 struct snd_kcontrol *mic_adcmux_control;
56 struct snd_kcontrol *lc_controls[13]; 67 struct snd_kcontrol *lc_controls[13];
68 struct snd_jack *hp_jack;
57}; 69};
58 70
59static void wm8776_write(struct oxygen *chip, 71static void wm8776_write(struct oxygen *chip,
@@ -95,8 +107,12 @@ static void wm8766_write(struct oxygen *chip,
95 (0 << OXYGEN_SPI_CODEC_SHIFT) | 107 (0 << OXYGEN_SPI_CODEC_SHIFT) |
96 OXYGEN_SPI_CEN_LATCH_CLOCK_LO, 108 OXYGEN_SPI_CEN_LATCH_CLOCK_LO,
97 (reg << 9) | value); 109 (reg << 9) | value);
98 if (reg < ARRAY_SIZE(data->wm8766_regs)) 110 if (reg < ARRAY_SIZE(data->wm8766_regs)) {
111 if ((reg >= WM8766_LDA1 && reg <= WM8766_RDA1) ||
112 (reg >= WM8766_LDA2 && reg <= WM8766_MASTDA))
113 value &= ~WM8766_UPDATE;
99 data->wm8766_regs[reg] = value; 114 data->wm8766_regs[reg] = value;
115 }
100} 116}
101 117
102static void wm8766_write_cached(struct oxygen *chip, 118static void wm8766_write_cached(struct oxygen *chip,
@@ -105,12 +121,8 @@ static void wm8766_write_cached(struct oxygen *chip,
105 struct xonar_wm87x6 *data = chip->model_data; 121 struct xonar_wm87x6 *data = chip->model_data;
106 122
107 if (reg >= ARRAY_SIZE(data->wm8766_regs) || 123 if (reg >= ARRAY_SIZE(data->wm8766_regs) ||
108 value != data->wm8766_regs[reg]) { 124 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); 125 wm8766_write(chip, reg, value);
113 }
114} 126}
115 127
116static void wm8776_registers_init(struct oxygen *chip) 128static void wm8776_registers_init(struct oxygen *chip)
@@ -139,7 +151,10 @@ static void wm8776_registers_init(struct oxygen *chip)
139 151
140static void wm8766_registers_init(struct oxygen *chip) 152static void wm8766_registers_init(struct oxygen *chip)
141{ 153{
154 struct xonar_wm87x6 *data = chip->model_data;
155
142 wm8766_write(chip, WM8766_RESET, 0); 156 wm8766_write(chip, WM8766_RESET, 0);
157 wm8766_write(chip, WM8766_DAC_CTRL, data->wm8766_regs[WM8766_DAC_CTRL]);
143 wm8766_write(chip, WM8766_INT_CTRL, WM8766_FMT_LJUST | WM8766_IWL_24); 158 wm8766_write(chip, WM8766_INT_CTRL, WM8766_FMT_LJUST | WM8766_IWL_24);
144 wm8766_write(chip, WM8766_DAC_CTRL2, 159 wm8766_write(chip, WM8766_DAC_CTRL2,
145 WM8766_ZCD | (chip->dac_mute ? WM8766_DMUTE_MASK : 0)); 160 WM8766_ZCD | (chip->dac_mute ? WM8766_DMUTE_MASK : 0));
@@ -168,6 +183,40 @@ static void wm8776_init(struct oxygen *chip)
168 wm8776_registers_init(chip); 183 wm8776_registers_init(chip);
169} 184}
170 185
186static void wm8766_init(struct oxygen *chip)
187{
188 struct xonar_wm87x6 *data = chip->model_data;
189
190 data->wm8766_regs[WM8766_DAC_CTRL] =
191 WM8766_PL_LEFT_LEFT | WM8766_PL_RIGHT_RIGHT;
192 wm8766_registers_init(chip);
193}
194
195static void xonar_ds_handle_hp_jack(struct oxygen *chip)
196{
197 struct xonar_wm87x6 *data = chip->model_data;
198 bool hp_plugged;
199 unsigned int reg;
200
201 mutex_lock(&chip->mutex);
202
203 hp_plugged = !(oxygen_read16(chip, OXYGEN_GPIO_DATA) &
204 GPIO_DS_HP_DETECT);
205
206 oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
207 hp_plugged ? 0 : GPIO_DS_OUTPUT_FRONTLR,
208 GPIO_DS_OUTPUT_FRONTLR);
209
210 reg = data->wm8766_regs[WM8766_DAC_CTRL] & ~WM8766_MUTEALL;
211 if (hp_plugged)
212 reg |= WM8766_MUTEALL;
213 wm8766_write_cached(chip, WM8766_DAC_CTRL, reg);
214
215 snd_jack_report(data->hp_jack, hp_plugged ? SND_JACK_HEADPHONE : 0);
216
217 mutex_unlock(&chip->mutex);
218}
219
171static void xonar_ds_init(struct oxygen *chip) 220static void xonar_ds_init(struct oxygen *chip)
172{ 221{
173 struct xonar_wm87x6 *data = chip->model_data; 222 struct xonar_wm87x6 *data = chip->model_data;
@@ -176,16 +225,22 @@ static void xonar_ds_init(struct oxygen *chip)
176 data->generic.output_enable_bit = GPIO_DS_OUTPUT_ENABLE; 225 data->generic.output_enable_bit = GPIO_DS_OUTPUT_ENABLE;
177 226
178 wm8776_init(chip); 227 wm8776_init(chip);
179 wm8766_registers_init(chip); 228 wm8766_init(chip);
180 229
181 oxygen_write16_masked(chip, OXYGEN_GPIO_CONTROL, GPIO_DS_INPUT_ROUTE, 230 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
182 GPIO_DS_HP_DETECT | GPIO_DS_INPUT_ROUTE); 231 GPIO_DS_INPUT_ROUTE | GPIO_DS_OUTPUT_FRONTLR);
232 oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL,
233 GPIO_DS_HP_DETECT);
183 oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, GPIO_DS_INPUT_ROUTE); 234 oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, GPIO_DS_INPUT_ROUTE);
184 oxygen_set_bits16(chip, OXYGEN_GPIO_INTERRUPT_MASK, GPIO_DS_HP_DETECT); 235 oxygen_set_bits16(chip, OXYGEN_GPIO_INTERRUPT_MASK, GPIO_DS_HP_DETECT);
185 chip->interrupt_mask |= OXYGEN_INT_GPIO; 236 chip->interrupt_mask |= OXYGEN_INT_GPIO;
186 237
187 xonar_enable_output(chip); 238 xonar_enable_output(chip);
188 239
240 snd_jack_new(chip->card, "Headphone",
241 SND_JACK_HEADPHONE, &data->hp_jack);
242 xonar_ds_handle_hp_jack(chip);
243
189 snd_component_add(chip->card, "WM8776"); 244 snd_component_add(chip->card, "WM8776");
190 snd_component_add(chip->card, "WM8766"); 245 snd_component_add(chip->card, "WM8766");
191} 246}
@@ -193,6 +248,7 @@ static void xonar_ds_init(struct oxygen *chip)
193static void xonar_ds_cleanup(struct oxygen *chip) 248static void xonar_ds_cleanup(struct oxygen *chip)
194{ 249{
195 xonar_disable_output(chip); 250 xonar_disable_output(chip);
251 wm8776_write(chip, WM8776_RESET, 0);
196} 252}
197 253
198static void xonar_ds_suspend(struct oxygen *chip) 254static void xonar_ds_suspend(struct oxygen *chip)
@@ -205,6 +261,7 @@ static void xonar_ds_resume(struct oxygen *chip)
205 wm8776_registers_init(chip); 261 wm8776_registers_init(chip);
206 wm8766_registers_init(chip); 262 wm8766_registers_init(chip);
207 xonar_enable_output(chip); 263 xonar_enable_output(chip);
264 xonar_ds_handle_hp_jack(chip);
208} 265}
209 266
210static void wm8776_adc_hardware_filter(unsigned int channel, 267static void wm8776_adc_hardware_filter(unsigned int channel,
@@ -320,12 +377,27 @@ static void update_wm87x6_mute(struct oxygen *chip)
320 (chip->dac_mute ? WM8766_DMUTE_MASK : 0)); 377 (chip->dac_mute ? WM8766_DMUTE_MASK : 0));
321} 378}
322 379
323static void xonar_ds_gpio_changed(struct oxygen *chip) 380static void update_wm8766_center_lfe_mix(struct oxygen *chip, bool mixed)
324{ 381{
325 u16 bits; 382 struct xonar_wm87x6 *data = chip->model_data;
383 unsigned int reg;
326 384
327 bits = oxygen_read16(chip, OXYGEN_GPIO_DATA); 385 /*
328 snd_printk(KERN_INFO "HP detect: %d\n", !!(bits & GPIO_DS_HP_DETECT)); 386 * The WM8766 can mix left and right channels, but this setting
387 * applies to all three stereo pairs.
388 */
389 reg = data->wm8766_regs[WM8766_DAC_CTRL] &
390 ~(WM8766_PL_LEFT_MASK | WM8766_PL_RIGHT_MASK);
391 if (mixed)
392 reg |= WM8766_PL_LEFT_LRMIX | WM8766_PL_RIGHT_LRMIX;
393 else
394 reg |= WM8766_PL_LEFT_LEFT | WM8766_PL_RIGHT_RIGHT;
395 wm8766_write_cached(chip, WM8766_DAC_CTRL, reg);
396}
397
398static void xonar_ds_gpio_changed(struct oxygen *chip)
399{
400 xonar_ds_handle_hp_jack(chip);
329} 401}
330 402
331static int wm8776_bit_switch_get(struct snd_kcontrol *ctl, 403static int wm8776_bit_switch_get(struct snd_kcontrol *ctl,
@@ -603,6 +675,7 @@ static int wm8776_input_mux_put(struct snd_kcontrol *ctl,
603{ 675{
604 struct oxygen *chip = ctl->private_data; 676 struct oxygen *chip = ctl->private_data;
605 struct xonar_wm87x6 *data = chip->model_data; 677 struct xonar_wm87x6 *data = chip->model_data;
678 struct snd_kcontrol *other_ctl;
606 unsigned int mux_bit = ctl->private_value; 679 unsigned int mux_bit = ctl->private_value;
607 u16 reg; 680 u16 reg;
608 int changed; 681 int changed;
@@ -610,8 +683,18 @@ static int wm8776_input_mux_put(struct snd_kcontrol *ctl,
610 mutex_lock(&chip->mutex); 683 mutex_lock(&chip->mutex);
611 reg = data->wm8776_regs[WM8776_ADCMUX]; 684 reg = data->wm8776_regs[WM8776_ADCMUX];
612 if (value->value.integer.value[0]) { 685 if (value->value.integer.value[0]) {
613 reg &= ~0x003;
614 reg |= mux_bit; 686 reg |= mux_bit;
687 /* line-in and mic-in are exclusive */
688 mux_bit ^= 3;
689 if (reg & mux_bit) {
690 reg &= ~mux_bit;
691 if (mux_bit == 1)
692 other_ctl = data->line_adcmux_control;
693 else
694 other_ctl = data->mic_adcmux_control;
695 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
696 &other_ctl->id);
697 }
615 } else 698 } else
616 reg &= ~mux_bit; 699 reg &= ~mux_bit;
617 changed = reg != data->wm8776_regs[WM8776_ADCMUX]; 700 changed = reg != data->wm8776_regs[WM8776_ADCMUX];
@@ -882,7 +965,10 @@ static const struct snd_kcontrol_new ds_controls[] = {
882 .put = wm8776_input_mux_put, 965 .put = wm8776_input_mux_put,
883 .private_value = 1 << 1, 966 .private_value = 1 << 1,
884 }, 967 },
885 WM8776_BIT_SWITCH("Aux", WM8776_ADCMUX, 1 << 2, 0, 0), 968 WM8776_BIT_SWITCH("Front Mic Capture Switch",
969 WM8776_ADCMUX, 1 << 2, 0, 0),
970 WM8776_BIT_SWITCH("Aux Capture Switch",
971 WM8776_ADCMUX, 1 << 3, 0, 0),
886 { 972 {
887 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 973 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
888 .name = "ADC Filter Capture Enum", 974 .name = "ADC Filter Capture Enum",
@@ -942,13 +1028,6 @@ static const struct snd_kcontrol_new lc_controls[] = {
942 LC_CONTROL_ALC, wm8776_ngth_db_scale), 1028 LC_CONTROL_ALC, wm8776_ngth_db_scale),
943}; 1029};
944 1030
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) 1031static int xonar_ds_mixer_init(struct oxygen *chip)
953{ 1032{
954 struct xonar_wm87x6 *data = chip->model_data; 1033 struct xonar_wm87x6 *data = chip->model_data;
@@ -963,7 +1042,13 @@ static int xonar_ds_mixer_init(struct oxygen *chip)
963 err = snd_ctl_add(chip->card, ctl); 1042 err = snd_ctl_add(chip->card, ctl);
964 if (err < 0) 1043 if (err < 0)
965 return err; 1044 return err;
1045 if (!strcmp(ctl->id.name, "Line Capture Switch"))
1046 data->line_adcmux_control = ctl;
1047 else if (!strcmp(ctl->id.name, "Mic Capture Switch"))
1048 data->mic_adcmux_control = ctl;
966 } 1049 }
1050 if (!data->line_adcmux_control || !data->mic_adcmux_control)
1051 return -ENXIO;
967 BUILD_BUG_ON(ARRAY_SIZE(lc_controls) != ARRAY_SIZE(data->lc_controls)); 1052 BUILD_BUG_ON(ARRAY_SIZE(lc_controls) != ARRAY_SIZE(data->lc_controls));
968 for (i = 0; i < ARRAY_SIZE(lc_controls); ++i) { 1053 for (i = 0; i < ARRAY_SIZE(lc_controls); ++i) {
969 ctl = snd_ctl_new1(&lc_controls[i], chip); 1054 ctl = snd_ctl_new1(&lc_controls[i], chip);
@@ -979,10 +1064,9 @@ static int xonar_ds_mixer_init(struct oxygen *chip)
979 1064
980static const struct oxygen_model model_xonar_ds = { 1065static const struct oxygen_model model_xonar_ds = {
981 .shortname = "Xonar DS", 1066 .shortname = "Xonar DS",
982 .longname = "Asus Virtuoso 200", 1067 .longname = "Asus Virtuoso 66",
983 .chip = "AV200", 1068 .chip = "AV200",
984 .init = xonar_ds_init, 1069 .init = xonar_ds_init,
985 .control_filter = xonar_ds_control_filter,
986 .mixer_init = xonar_ds_mixer_init, 1070 .mixer_init = xonar_ds_mixer_init,
987 .cleanup = xonar_ds_cleanup, 1071 .cleanup = xonar_ds_cleanup,
988 .suspend = xonar_ds_suspend, 1072 .suspend = xonar_ds_suspend,
@@ -993,6 +1077,7 @@ static const struct oxygen_model model_xonar_ds = {
993 .set_adc_params = set_wm8776_adc_params, 1077 .set_adc_params = set_wm8776_adc_params,
994 .update_dac_volume = update_wm87x6_volume, 1078 .update_dac_volume = update_wm87x6_volume,
995 .update_dac_mute = update_wm87x6_mute, 1079 .update_dac_mute = update_wm87x6_mute,
1080 .update_center_lfe_mix = update_wm8766_center_lfe_mix,
996 .gpio_changed = xonar_ds_gpio_changed, 1081 .gpio_changed = xonar_ds_gpio_changed,
997 .dac_tlv = wm87x6_dac_db_scale, 1082 .dac_tlv = wm87x6_dac_db_scale,
998 .model_data_size = sizeof(struct xonar_wm87x6), 1083 .model_data_size = sizeof(struct xonar_wm87x6),
diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c
index ad446267761..ad5202efd7a 100644
--- a/sound/pci/riptide/riptide.c
+++ b/sound/pci/riptide/riptide.c
@@ -97,6 +97,7 @@
97#include <linux/gameport.h> 97#include <linux/gameport.h>
98#include <linux/device.h> 98#include <linux/device.h>
99#include <linux/firmware.h> 99#include <linux/firmware.h>
100#include <linux/kernel.h>
100#include <asm/io.h> 101#include <asm/io.h>
101#include <sound/core.h> 102#include <sound/core.h>
102#include <sound/info.h> 103#include <sound/info.h>
@@ -667,13 +668,12 @@ static u32 atoh(const unsigned char *in, unsigned int len)
667 unsigned char c; 668 unsigned char c;
668 669
669 while (len) { 670 while (len) {
671 int value;
672
670 c = in[len - 1]; 673 c = in[len - 1];
671 if ((c >= '0') && (c <= '9')) 674 value = hex_to_bin(c);
672 sum += mult * (c - '0'); 675 if (value >= 0)
673 else if ((c >= 'A') && (c <= 'F')) 676 sum += mult * value;
674 sum += mult * (c - ('A' - 10));
675 else if ((c >= 'a') && (c <= 'f'))
676 sum += mult * (c - ('a' - 10));
677 mult *= 16; 677 mult *= 16;
678 --len; 678 --len;
679 } 679 }
@@ -1224,15 +1224,14 @@ static int try_to_load_firmware(struct cmdif *cif, struct snd_riptide *chip)
1224 firmware.firmware.ASIC, firmware.firmware.CODEC, 1224 firmware.firmware.ASIC, firmware.firmware.CODEC,
1225 firmware.firmware.AUXDSP, firmware.firmware.PROG); 1225 firmware.firmware.AUXDSP, firmware.firmware.PROG);
1226 1226
1227 if (!chip)
1228 return 1;
1229
1227 for (i = 0; i < FIRMWARE_VERSIONS; i++) { 1230 for (i = 0; i < FIRMWARE_VERSIONS; i++) {
1228 if (!memcmp(&firmware_versions[i], &firmware, sizeof(firmware))) 1231 if (!memcmp(&firmware_versions[i], &firmware, sizeof(firmware)))
1229 break; 1232 return 1; /* OK */
1230 }
1231 if (i >= FIRMWARE_VERSIONS)
1232 return 0; /* no match */
1233 1233
1234 if (!chip) 1234 }
1235 return 1; /* OK */
1236 1235
1237 snd_printdd("Writing Firmware\n"); 1236 snd_printdd("Writing Firmware\n");
1238 if (!chip->fw_entry) { 1237 if (!chip->fw_entry) {
@@ -1615,7 +1614,10 @@ static int snd_riptide_playback_open(struct snd_pcm_substream *substream)
1615 1614
1616 chip->playback_substream[sub_num] = substream; 1615 chip->playback_substream[sub_num] = substream;
1617 runtime->hw = snd_riptide_playback; 1616 runtime->hw = snd_riptide_playback;
1617
1618 data = kzalloc(sizeof(struct pcmhw), GFP_KERNEL); 1618 data = kzalloc(sizeof(struct pcmhw), GFP_KERNEL);
1619 if (data == NULL)
1620 return -ENOMEM;
1619 data->paths = lbus_play_paths[sub_num]; 1621 data->paths = lbus_play_paths[sub_num];
1620 data->id = play_ids[sub_num]; 1622 data->id = play_ids[sub_num];
1621 data->source = play_sources[sub_num]; 1623 data->source = play_sources[sub_num];
@@ -1635,7 +1637,10 @@ static int snd_riptide_capture_open(struct snd_pcm_substream *substream)
1635 1637
1636 chip->capture_substream = substream; 1638 chip->capture_substream = substream;
1637 runtime->hw = snd_riptide_capture; 1639 runtime->hw = snd_riptide_capture;
1640
1638 data = kzalloc(sizeof(struct pcmhw), GFP_KERNEL); 1641 data = kzalloc(sizeof(struct pcmhw), GFP_KERNEL);
1642 if (data == NULL)
1643 return -ENOMEM;
1639 data->paths = lbus_rec_path; 1644 data->paths = lbus_rec_path;
1640 data->id = PADC; 1645 data->id = PADC;
1641 data->source = ACLNK2PADC; 1646 data->source = ACLNK2PADC;
diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c
index d19dc052c39..d5f5b440fc4 100644
--- a/sound/pci/rme96.c
+++ b/sound/pci/rme96.c
@@ -1527,14 +1527,14 @@ snd_rme96_free(void *private_data)
1527static void 1527static void
1528snd_rme96_free_spdif_pcm(struct snd_pcm *pcm) 1528snd_rme96_free_spdif_pcm(struct snd_pcm *pcm)
1529{ 1529{
1530 struct rme96 *rme96 = (struct rme96 *) pcm->private_data; 1530 struct rme96 *rme96 = pcm->private_data;
1531 rme96->spdif_pcm = NULL; 1531 rme96->spdif_pcm = NULL;
1532} 1532}
1533 1533
1534static void 1534static void
1535snd_rme96_free_adat_pcm(struct snd_pcm *pcm) 1535snd_rme96_free_adat_pcm(struct snd_pcm *pcm)
1536{ 1536{
1537 struct rme96 *rme96 = (struct rme96 *) pcm->private_data; 1537 struct rme96 *rme96 = pcm->private_data;
1538 rme96->adat_pcm = NULL; 1538 rme96->adat_pcm = NULL;
1539} 1539}
1540 1540
@@ -1661,7 +1661,7 @@ static void
1661snd_rme96_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) 1661snd_rme96_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
1662{ 1662{
1663 int n; 1663 int n;
1664 struct rme96 *rme96 = (struct rme96 *)entry->private_data; 1664 struct rme96 *rme96 = entry->private_data;
1665 1665
1666 rme96->rcreg = readl(rme96->iobase + RME96_IO_CONTROL_REGISTER); 1666 rme96->rcreg = readl(rme96->iobase + RME96_IO_CONTROL_REGISTER);
1667 1667
@@ -2348,7 +2348,7 @@ snd_rme96_probe(struct pci_dev *pci,
2348 if (err < 0) 2348 if (err < 0)
2349 return err; 2349 return err;
2350 card->private_free = snd_rme96_card_free; 2350 card->private_free = snd_rme96_card_free;
2351 rme96 = (struct rme96 *)card->private_data; 2351 rme96 = card->private_data;
2352 rme96->card = card; 2352 rme96->card = card;
2353 rme96->pci = pci; 2353 rme96->pci = pci;
2354 snd_card_set_dev(card, &pci->dev); 2354 snd_card_set_dev(card, &pci->dev);
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index b92adef8e81..0b720cf7783 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -3284,7 +3284,7 @@ static int snd_hdsp_create_controls(struct snd_card *card, struct hdsp *hdsp)
3284static void 3284static void
3285snd_hdsp_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) 3285snd_hdsp_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
3286{ 3286{
3287 struct hdsp *hdsp = (struct hdsp *) entry->private_data; 3287 struct hdsp *hdsp = entry->private_data;
3288 unsigned int status; 3288 unsigned int status;
3289 unsigned int status2; 3289 unsigned int status2;
3290 char *pref_sync_ref; 3290 char *pref_sync_ref;
@@ -4566,7 +4566,7 @@ static int hdsp_get_peak(struct hdsp *hdsp, struct hdsp_peak_rms __user *peak_rm
4566 4566
4567static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigned int cmd, unsigned long arg) 4567static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigned int cmd, unsigned long arg)
4568{ 4568{
4569 struct hdsp *hdsp = (struct hdsp *)hw->private_data; 4569 struct hdsp *hdsp = hw->private_data;
4570 void __user *argp = (void __user *)arg; 4570 void __user *argp = (void __user *)arg;
4571 int err; 4571 int err;
4572 4572
@@ -4609,6 +4609,7 @@ static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigne
4609 if (err < 0) 4609 if (err < 0)
4610 return err; 4610 return err;
4611 4611
4612 memset(&info, 0, sizeof(info));
4612 spin_lock_irqsave(&hdsp->lock, flags); 4613 spin_lock_irqsave(&hdsp->lock, flags);
4613 info.pref_sync_ref = (unsigned char)hdsp_pref_sync_ref(hdsp); 4614 info.pref_sync_ref = (unsigned char)hdsp_pref_sync_ref(hdsp);
4614 info.wordclock_sync_check = (unsigned char)hdsp_wc_sync_check(hdsp); 4615 info.wordclock_sync_check = (unsigned char)hdsp_wc_sync_check(hdsp);
@@ -5155,7 +5156,7 @@ static int snd_hdsp_free(struct hdsp *hdsp)
5155 5156
5156static void snd_hdsp_card_free(struct snd_card *card) 5157static void snd_hdsp_card_free(struct snd_card *card)
5157{ 5158{
5158 struct hdsp *hdsp = (struct hdsp *) card->private_data; 5159 struct hdsp *hdsp = card->private_data;
5159 5160
5160 if (hdsp) 5161 if (hdsp)
5161 snd_hdsp_free(hdsp); 5162 snd_hdsp_free(hdsp);
@@ -5181,7 +5182,7 @@ static int __devinit snd_hdsp_probe(struct pci_dev *pci,
5181 if (err < 0) 5182 if (err < 0)
5182 return err; 5183 return err;
5183 5184
5184 hdsp = (struct hdsp *) card->private_data; 5185 hdsp = card->private_data;
5185 card->private_free = snd_hdsp_card_free; 5186 card->private_free = snd_hdsp_card_free;
5186 hdsp->dev = dev; 5187 hdsp->dev = dev;
5187 hdsp->pci = pci; 5188 hdsp->pci = pci;
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index 547b713d720..0c98ef9156d 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -4127,6 +4127,7 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep * hw, struct file *file,
4127 4127
4128 case SNDRV_HDSPM_IOCTL_GET_CONFIG_INFO: 4128 case SNDRV_HDSPM_IOCTL_GET_CONFIG_INFO:
4129 4129
4130 memset(&info, 0, sizeof(info));
4130 spin_lock_irq(&hdspm->lock); 4131 spin_lock_irq(&hdspm->lock);
4131 info.pref_sync_ref = hdspm_pref_sync_ref(hdspm); 4132 info.pref_sync_ref = hdspm_pref_sync_ref(hdspm);
4132 info.wordclock_sync_check = hdspm_wc_sync_check(hdspm); 4133 info.wordclock_sync_check = hdspm_wc_sync_check(hdspm);
diff --git a/sound/pci/sis7019.c b/sound/pci/sis7019.c
index 9cc1b5aa014..1b8f6742b5f 100644
--- a/sound/pci/sis7019.c
+++ b/sound/pci/sis7019.c
@@ -264,11 +264,13 @@ static void sis_update_voice(struct voice *voice)
264 * if using small periods. 264 * if using small periods.
265 * 265 *
266 * If we're less than 9 samples behind, we're on target. 266 * If we're less than 9 samples behind, we're on target.
267 * Otherwise, shorten the next vperiod by the amount we've
268 * been delayed.
267 */ 269 */
268 if (sync > -9) 270 if (sync > -9)
269 voice->vperiod = voice->sync_period_size + 1; 271 voice->vperiod = voice->sync_period_size + 1;
270 else 272 else
271 voice->vperiod = voice->sync_period_size - 4; 273 voice->vperiod = voice->sync_period_size + sync + 10;
272 274
273 if (voice->vperiod < voice->buffer_size) { 275 if (voice->vperiod < voice->buffer_size) {
274 sis_update_sso(voice, voice->vperiod); 276 sis_update_sso(voice, voice->vperiod);
@@ -736,7 +738,7 @@ static void sis_prepare_timing_voice(struct voice *voice,
736 period_size = buffer_size; 738 period_size = buffer_size;
737 739
738 /* Initially, we want to interrupt just a bit behind the end of 740 /* Initially, we want to interrupt just a bit behind the end of
739 * the period we're clocking out. 10 samples seems to give a good 741 * the period we're clocking out. 12 samples seems to give a good
740 * delay. 742 * delay.
741 * 743 *
742 * We want to spread our interrupts throughout the virtual period, 744 * We want to spread our interrupts throughout the virtual period,
@@ -747,7 +749,7 @@ static void sis_prepare_timing_voice(struct voice *voice,
747 * 749 *
748 * This is all moot if we don't need to use virtual periods. 750 * This is all moot if we don't need to use virtual periods.
749 */ 751 */
750 vperiod = runtime->period_size + 10; 752 vperiod = runtime->period_size + 12;
751 if (vperiod > period_size) { 753 if (vperiod > period_size) {
752 u16 tail = vperiod % period_size; 754 u16 tail = vperiod % period_size;
753 u16 quarter_period = period_size / 4; 755 u16 quarter_period = period_size / 4;
@@ -776,7 +778,7 @@ static void sis_prepare_timing_voice(struct voice *voice,
776 */ 778 */
777 timing->flags |= VOICE_SYNC_TIMING; 779 timing->flags |= VOICE_SYNC_TIMING;
778 timing->sync_base = voice->ctrl_base; 780 timing->sync_base = voice->ctrl_base;
779 timing->sync_cso = runtime->period_size - 1; 781 timing->sync_cso = runtime->period_size;
780 timing->sync_period_size = runtime->period_size; 782 timing->sync_period_size = runtime->period_size;
781 timing->sync_buffer_size = runtime->buffer_size; 783 timing->sync_buffer_size = runtime->buffer_size;
782 timing->period_size = period_size; 784 timing->period_size = period_size;
@@ -1047,7 +1049,7 @@ static int sis_chip_free(struct sis7019 *sis)
1047 /* Reset the chip, and disable all interrputs. 1049 /* Reset the chip, and disable all interrputs.
1048 */ 1050 */
1049 outl(SIS_GCR_SOFTWARE_RESET, sis->ioport + SIS_GCR); 1051 outl(SIS_GCR_SOFTWARE_RESET, sis->ioport + SIS_GCR);
1050 udelay(10); 1052 udelay(25);
1051 outl(0, sis->ioport + SIS_GCR); 1053 outl(0, sis->ioport + SIS_GCR);
1052 outl(0, sis->ioport + SIS_GIER); 1054 outl(0, sis->ioport + SIS_GIER);
1053 1055
@@ -1083,7 +1085,7 @@ static int sis_chip_init(struct sis7019 *sis)
1083 /* Reset the audio controller 1085 /* Reset the audio controller
1084 */ 1086 */
1085 outl(SIS_GCR_SOFTWARE_RESET, io + SIS_GCR); 1087 outl(SIS_GCR_SOFTWARE_RESET, io + SIS_GCR);
1086 udelay(10); 1088 udelay(25);
1087 outl(0, io + SIS_GCR); 1089 outl(0, io + SIS_GCR);
1088 1090
1089 /* Get the AC-link semaphore, and reset the codecs 1091 /* Get the AC-link semaphore, and reset the codecs
@@ -1096,7 +1098,7 @@ static int sis_chip_init(struct sis7019 *sis)
1096 return -EIO; 1098 return -EIO;
1097 1099
1098 outl(SIS_AC97_CMD_CODEC_COLD_RESET, io + SIS_AC97_CMD); 1100 outl(SIS_AC97_CMD_CODEC_COLD_RESET, io + SIS_AC97_CMD);
1099 udelay(10); 1101 udelay(250);
1100 1102
1101 count = 0xffff; 1103 count = 0xffff;
1102 while ((inw(io + SIS_AC97_STATUS) & SIS_AC97_STATUS_BUSY) && --count) 1104 while ((inw(io + SIS_AC97_STATUS) & SIS_AC97_STATUS_BUSY) && --count)
diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c
index 6d943f6f6b7..2870a4fdc13 100644
--- a/sound/pci/trident/trident_main.c
+++ b/sound/pci/trident/trident_main.c
@@ -1055,7 +1055,7 @@ static int snd_trident_capture_prepare(struct snd_pcm_substream *substream)
1055 1055
1056 spin_lock_irq(&trident->reg_lock); 1056 spin_lock_irq(&trident->reg_lock);
1057 1057
1058 // Initilize the channel and set channel Mode 1058 // Initialize the channel and set channel Mode
1059 outb(0, TRID_REG(trident, LEGACY_DMAR15)); 1059 outb(0, TRID_REG(trident, LEGACY_DMAR15));
1060 1060
1061 // Set DMA channel operation mode register 1061 // Set DMA channel operation mode register
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index 7e494b6a1d0..8c5f8b5a59f 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -85,6 +85,7 @@ static int joystick;
85static int ac97_clock = 48000; 85static int ac97_clock = 48000;
86static char *ac97_quirk; 86static char *ac97_quirk;
87static int dxs_support; 87static int dxs_support;
88static int dxs_init_volume = 31;
88static int nodelay; 89static int nodelay;
89 90
90module_param(index, int, 0444); 91module_param(index, int, 0444);
@@ -103,6 +104,8 @@ module_param(ac97_quirk, charp, 0444);
103MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware."); 104MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware.");
104module_param(dxs_support, int, 0444); 105module_param(dxs_support, int, 0444);
105MODULE_PARM_DESC(dxs_support, "Support for DXS channels (0 = auto, 1 = enable, 2 = disable, 3 = 48k only, 4 = no VRA, 5 = enable any sample rate)"); 106MODULE_PARM_DESC(dxs_support, "Support for DXS channels (0 = auto, 1 = enable, 2 = disable, 3 = 48k only, 4 = no VRA, 5 = enable any sample rate)");
107module_param(dxs_init_volume, int, 0644);
108MODULE_PARM_DESC(dxs_init_volume, "initial DXS volume (0-31)");
106module_param(nodelay, int, 0444); 109module_param(nodelay, int, 0444);
107MODULE_PARM_DESC(nodelay, "Disable 500ms init delay"); 110MODULE_PARM_DESC(nodelay, "Disable 500ms init delay");
108 111
@@ -1245,8 +1248,10 @@ static int snd_via8233_playback_open(struct snd_pcm_substream *substream)
1245 return err; 1248 return err;
1246 stream = viadev->reg_offset / 0x10; 1249 stream = viadev->reg_offset / 0x10;
1247 if (chip->dxs_controls[stream]) { 1250 if (chip->dxs_controls[stream]) {
1248 chip->playback_volume[stream][0] = 0; 1251 chip->playback_volume[stream][0] =
1249 chip->playback_volume[stream][1] = 0; 1252 VIA_DXS_MAX_VOLUME - (dxs_init_volume & 31);
1253 chip->playback_volume[stream][1] =
1254 VIA_DXS_MAX_VOLUME - (dxs_init_volume & 31);
1250 chip->dxs_controls[stream]->vd[0].access &= 1255 chip->dxs_controls[stream]->vd[0].access &=
1251 ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; 1256 ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
1252 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE | 1257 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE |
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.c b/sound/pcmcia/pdaudiocf/pdaudiocf.c
index df110df52a8..7ab9174a8a8 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf.c
@@ -139,8 +139,8 @@ static int snd_pdacf_probe(struct pcmcia_device *link)
139 pdacf->p_dev = link; 139 pdacf->p_dev = link;
140 link->priv = pdacf; 140 link->priv = pdacf;
141 141
142 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; 142 link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
143 link->io.NumPorts1 = 16; 143 link->resource[0]->end = 16;
144 144
145 link->conf.Attributes = CONF_ENABLE_IRQ | CONF_ENABLE_PULSE_IRQ; 145 link->conf.Attributes = CONF_ENABLE_IRQ | CONF_ENABLE_PULSE_IRQ;
146 link->conf.IntType = INT_MEMORY_AND_IO; 146 link->conf.IntType = INT_MEMORY_AND_IO;
@@ -219,7 +219,7 @@ static int pdacf_config(struct pcmcia_device *link)
219 snd_printdd(KERN_DEBUG "pdacf_config called\n"); 219 snd_printdd(KERN_DEBUG "pdacf_config called\n");
220 link->conf.ConfigIndex = 0x5; 220 link->conf.ConfigIndex = 0x5;
221 221
222 ret = pcmcia_request_io(link, &link->io); 222 ret = pcmcia_request_io(link);
223 if (ret) 223 if (ret)
224 goto failed; 224 goto failed;
225 225
@@ -231,7 +231,8 @@ static int pdacf_config(struct pcmcia_device *link)
231 if (ret) 231 if (ret)
232 goto failed; 232 goto failed;
233 233
234 if (snd_pdacf_assign_resources(pdacf, link->io.BasePort1, link->irq) < 0) 234 if (snd_pdacf_assign_resources(pdacf, link->resource[0]->start,
235 link->irq) < 0)
235 goto failed; 236 goto failed;
236 237
237 return 0; 238 return 0;
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.h b/sound/pcmcia/pdaudiocf/pdaudiocf.h
index a0a7ec64222..5cc3e457307 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf.h
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf.h
@@ -24,7 +24,6 @@
24#include <sound/pcm.h> 24#include <sound/pcm.h>
25#include <asm/io.h> 25#include <asm/io.h>
26#include <linux/interrupt.h> 26#include <linux/interrupt.h>
27#include <pcmcia/cs_types.h>
28#include <pcmcia/cs.h> 27#include <pcmcia/cs.h>
29#include <pcmcia/cistpl.h> 28#include <pcmcia/cistpl.h>
30#include <pcmcia/ds.h> 29#include <pcmcia/ds.h>
diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c
index 624b47a85f0..a6edfc3be29 100644
--- a/sound/pcmcia/vx/vxpocket.c
+++ b/sound/pcmcia/vx/vxpocket.c
@@ -159,8 +159,8 @@ static int snd_vxpocket_new(struct snd_card *card, int ibl,
159 vxp->p_dev = link; 159 vxp->p_dev = link;
160 link->priv = chip; 160 link->priv = chip;
161 161
162 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; 162 link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
163 link->io.NumPorts1 = 16; 163 link->resource[0]->end = 16;
164 164
165 link->conf.Attributes = CONF_ENABLE_IRQ; 165 link->conf.Attributes = CONF_ENABLE_IRQ;
166 link->conf.IntType = INT_MEMORY_AND_IO; 166 link->conf.IntType = INT_MEMORY_AND_IO;
@@ -226,7 +226,7 @@ static int vxpocket_config(struct pcmcia_device *link)
226 strcpy(chip->card->driver, vxp440_hw.name); 226 strcpy(chip->card->driver, vxp440_hw.name);
227 } 227 }
228 228
229 ret = pcmcia_request_io(link, &link->io); 229 ret = pcmcia_request_io(link);
230 if (ret) 230 if (ret)
231 goto failed; 231 goto failed;
232 232
@@ -241,7 +241,8 @@ static int vxpocket_config(struct pcmcia_device *link)
241 chip->dev = &link->dev; 241 chip->dev = &link->dev;
242 snd_card_set_dev(chip->card, chip->dev); 242 snd_card_set_dev(chip->card, chip->dev);
243 243
244 if (snd_vxpocket_assign_resources(chip, link->io.BasePort1, link->irq) < 0) 244 if (snd_vxpocket_assign_resources(chip, link->resource[0]->start,
245 link->irq) < 0)
245 goto failed; 246 goto failed;
246 247
247 return 0; 248 return 0;
diff --git a/sound/pcmcia/vx/vxpocket.h b/sound/pcmcia/vx/vxpocket.h
index ea4df16a28e..d9110669d04 100644
--- a/sound/pcmcia/vx/vxpocket.h
+++ b/sound/pcmcia/vx/vxpocket.h
@@ -23,7 +23,6 @@
23 23
24#include <sound/vx_core.h> 24#include <sound/vx_core.h>
25 25
26#include <pcmcia/cs_types.h>
27#include <pcmcia/cs.h> 26#include <pcmcia/cs.h>
28#include <pcmcia/cistpl.h> 27#include <pcmcia/cistpl.h>
29#include <pcmcia/ds.h> 28#include <pcmcia/ds.h>
diff --git a/sound/ppc/snd_ps3.c b/sound/ppc/snd_ps3.c
index 2f12da4da56..581a670e826 100644
--- a/sound/ppc/snd_ps3.c
+++ b/sound/ppc/snd_ps3.c
@@ -579,7 +579,7 @@ static int snd_ps3_delay_to_bytes(struct snd_pcm_substream *substream,
579 rate * delay_ms / 1000) 579 rate * delay_ms / 1000)
580 * substream->runtime->channels; 580 * substream->runtime->channels;
581 581
582 pr_debug(KERN_ERR "%s: time=%d rate=%d bytes=%ld, frames=%d, ret=%d\n", 582 pr_debug("%s: time=%d rate=%d bytes=%ld, frames=%d, ret=%d\n",
583 __func__, 583 __func__,
584 delay_ms, 584 delay_ms,
585 rate, 585 rate,
diff --git a/sound/ppc/tumbler.c b/sound/ppc/tumbler.c
index 20afdf9772e..961d9829769 100644
--- a/sound/ppc/tumbler.c
+++ b/sound/ppc/tumbler.c
@@ -785,7 +785,7 @@ static int snapper_set_capture_source(struct pmac_tumbler *mix)
785 if (! mix->i2c.client) 785 if (! mix->i2c.client)
786 return -ENODEV; 786 return -ENODEV;
787 if (mix->capture_source) 787 if (mix->capture_source)
788 mix->acs = mix->acs |= 2; 788 mix->acs |= 2;
789 else 789 else
790 mix->acs &= ~2; 790 mix->acs &= ~2;
791 return i2c_smbus_write_byte_data(mix->i2c.client, TAS_REG_ACS, mix->acs); 791 return i2c_smbus_write_byte_data(mix->i2c.client, TAS_REG_ACS, mix->acs);
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index b1749bc6797..3e598e756e5 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -28,9 +28,13 @@ source "sound/soc/atmel/Kconfig"
28source "sound/soc/au1x/Kconfig" 28source "sound/soc/au1x/Kconfig"
29source "sound/soc/blackfin/Kconfig" 29source "sound/soc/blackfin/Kconfig"
30source "sound/soc/davinci/Kconfig" 30source "sound/soc/davinci/Kconfig"
31source "sound/soc/ep93xx/Kconfig"
31source "sound/soc/fsl/Kconfig" 32source "sound/soc/fsl/Kconfig"
32source "sound/soc/imx/Kconfig" 33source "sound/soc/imx/Kconfig"
34source "sound/soc/jz4740/Kconfig"
35source "sound/soc/nuc900/Kconfig"
33source "sound/soc/omap/Kconfig" 36source "sound/soc/omap/Kconfig"
37source "sound/soc/kirkwood/Kconfig"
34source "sound/soc/pxa/Kconfig" 38source "sound/soc/pxa/Kconfig"
35source "sound/soc/s3c24xx/Kconfig" 39source "sound/soc/s3c24xx/Kconfig"
36source "sound/soc/s6000/Kconfig" 40source "sound/soc/s6000/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 1470141d416..eb183443eee 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -6,9 +6,13 @@ obj-$(CONFIG_SND_SOC) += atmel/
6obj-$(CONFIG_SND_SOC) += au1x/ 6obj-$(CONFIG_SND_SOC) += au1x/
7obj-$(CONFIG_SND_SOC) += blackfin/ 7obj-$(CONFIG_SND_SOC) += blackfin/
8obj-$(CONFIG_SND_SOC) += davinci/ 8obj-$(CONFIG_SND_SOC) += davinci/
9obj-$(CONFIG_SND_SOC) += ep93xx/
9obj-$(CONFIG_SND_SOC) += fsl/ 10obj-$(CONFIG_SND_SOC) += fsl/
10obj-$(CONFIG_SND_SOC) += imx/ 11obj-$(CONFIG_SND_SOC) += imx/
12obj-$(CONFIG_SND_SOC) += jz4740/
13obj-$(CONFIG_SND_SOC) += nuc900/
11obj-$(CONFIG_SND_SOC) += omap/ 14obj-$(CONFIG_SND_SOC) += omap/
15obj-$(CONFIG_SND_SOC) += kirkwood/
12obj-$(CONFIG_SND_SOC) += pxa/ 16obj-$(CONFIG_SND_SOC) += pxa/
13obj-$(CONFIG_SND_SOC) += s3c24xx/ 17obj-$(CONFIG_SND_SOC) += s3c24xx/
14obj-$(CONFIG_SND_SOC) += s6000/ 18obj-$(CONFIG_SND_SOC) += s6000/
diff --git a/sound/soc/atmel/atmel-pcm.c b/sound/soc/atmel/atmel-pcm.c
index f6b3cc04b34..dc5249fba85 100644
--- a/sound/soc/atmel/atmel-pcm.c
+++ b/sound/soc/atmel/atmel-pcm.c
@@ -77,7 +77,6 @@ struct atmel_runtime_data {
77 size_t period_size; 77 size_t period_size;
78 78
79 dma_addr_t period_ptr; /* physical address of next period */ 79 dma_addr_t period_ptr; /* physical address of next period */
80 int periods; /* period index of period_ptr */
81 80
82 /* PDC register save */ 81 /* PDC register save */
83 u32 pdc_xpr_save; 82 u32 pdc_xpr_save;
diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c
index 0b59806905d..c85844d4845 100644
--- a/sound/soc/atmel/atmel_ssc_dai.c
+++ b/sound/soc/atmel/atmel_ssc_dai.c
@@ -549,7 +549,6 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
549 printk(KERN_WARNING "atmel_ssc_dai: unsupported DAI format 0x%x\n", 549 printk(KERN_WARNING "atmel_ssc_dai: unsupported DAI format 0x%x\n",
550 ssc_p->daifmt); 550 ssc_p->daifmt);
551 return -EINVAL; 551 return -EINVAL;
552 break;
553 } 552 }
554 pr_debug("atmel_ssc_hw_params: " 553 pr_debug("atmel_ssc_hw_params: "
555 "RCMR=%08x RFMR=%08x TCMR=%08x TFMR=%08x\n", 554 "RCMR=%08x RFMR=%08x TCMR=%08x TFMR=%08x\n",
diff --git a/sound/soc/au1x/psc-ac97.c b/sound/soc/au1x/psc-ac97.c
index a61ccd2d505..d14a5a91a46 100644
--- a/sound/soc/au1x/psc-ac97.c
+++ b/sound/soc/au1x/psc-ac97.c
@@ -375,12 +375,10 @@ static int __devinit au1xpsc_ac97_drvprobe(struct platform_device *pdev)
375 } 375 }
376 376
377 ret = -EBUSY; 377 ret = -EBUSY;
378 wd->ioarea = request_mem_region(r->start, r->end - r->start + 1, 378 if (!request_mem_region(r->start, resource_size(r), pdev->name))
379 "au1xpsc_ac97");
380 if (!wd->ioarea)
381 goto out0; 379 goto out0;
382 380
383 wd->mmio = ioremap(r->start, 0xffff); 381 wd->mmio = ioremap(r->start, resource_size(r));
384 if (!wd->mmio) 382 if (!wd->mmio)
385 goto out1; 383 goto out1;
386 384
@@ -410,8 +408,7 @@ static int __devinit au1xpsc_ac97_drvprobe(struct platform_device *pdev)
410 408
411 snd_soc_unregister_dai(&au1xpsc_ac97_dai); 409 snd_soc_unregister_dai(&au1xpsc_ac97_dai);
412out1: 410out1:
413 release_resource(wd->ioarea); 411 release_mem_region(r->start, resource_size(r));
414 kfree(wd->ioarea);
415out0: 412out0:
416 kfree(wd); 413 kfree(wd);
417 return ret; 414 return ret;
@@ -420,6 +417,7 @@ out0:
420static int __devexit au1xpsc_ac97_drvremove(struct platform_device *pdev) 417static int __devexit au1xpsc_ac97_drvremove(struct platform_device *pdev)
421{ 418{
422 struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev); 419 struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev);
420 struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
423 421
424 if (wd->dmapd) 422 if (wd->dmapd)
425 au1xpsc_pcm_destroy(wd->dmapd); 423 au1xpsc_pcm_destroy(wd->dmapd);
@@ -433,8 +431,7 @@ static int __devexit au1xpsc_ac97_drvremove(struct platform_device *pdev)
433 au_sync(); 431 au_sync();
434 432
435 iounmap(wd->mmio); 433 iounmap(wd->mmio);
436 release_resource(wd->ioarea); 434 release_mem_region(r->start, resource_size(r));
437 kfree(wd->ioarea);
438 kfree(wd); 435 kfree(wd);
439 436
440 au1xpsc_ac97_workdata = NULL; /* MDEV */ 437 au1xpsc_ac97_workdata = NULL; /* MDEV */
diff --git a/sound/soc/au1x/psc-i2s.c b/sound/soc/au1x/psc-i2s.c
index 24454c98d0e..6083fe7799f 100644
--- a/sound/soc/au1x/psc-i2s.c
+++ b/sound/soc/au1x/psc-i2s.c
@@ -321,12 +321,10 @@ static int __devinit au1xpsc_i2s_drvprobe(struct platform_device *pdev)
321 } 321 }
322 322
323 ret = -EBUSY; 323 ret = -EBUSY;
324 wd->ioarea = request_mem_region(r->start, r->end - r->start + 1, 324 if (!request_mem_region(r->start, resource_size(r), pdev->name))
325 "au1xpsc_i2s");
326 if (!wd->ioarea)
327 goto out0; 325 goto out0;
328 326
329 wd->mmio = ioremap(r->start, 0xffff); 327 wd->mmio = ioremap(r->start, resource_size(r));
330 if (!wd->mmio) 328 if (!wd->mmio)
331 goto out1; 329 goto out1;
332 330
@@ -362,8 +360,7 @@ static int __devinit au1xpsc_i2s_drvprobe(struct platform_device *pdev)
362 360
363 snd_soc_unregister_dai(&au1xpsc_i2s_dai); 361 snd_soc_unregister_dai(&au1xpsc_i2s_dai);
364out1: 362out1:
365 release_resource(wd->ioarea); 363 release_mem_region(r->start, resource_size(r));
366 kfree(wd->ioarea);
367out0: 364out0:
368 kfree(wd); 365 kfree(wd);
369 return ret; 366 return ret;
@@ -372,6 +369,7 @@ out0:
372static int __devexit au1xpsc_i2s_drvremove(struct platform_device *pdev) 369static int __devexit au1xpsc_i2s_drvremove(struct platform_device *pdev)
373{ 370{
374 struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev); 371 struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev);
372 struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
375 373
376 if (wd->dmapd) 374 if (wd->dmapd)
377 au1xpsc_pcm_destroy(wd->dmapd); 375 au1xpsc_pcm_destroy(wd->dmapd);
@@ -384,8 +382,7 @@ static int __devexit au1xpsc_i2s_drvremove(struct platform_device *pdev)
384 au_sync(); 382 au_sync();
385 383
386 iounmap(wd->mmio); 384 iounmap(wd->mmio);
387 release_resource(wd->ioarea); 385 release_mem_region(r->start, resource_size(r));
388 kfree(wd->ioarea);
389 kfree(wd); 386 kfree(wd);
390 387
391 au1xpsc_i2s_workdata = NULL; /* MDEV */ 388 au1xpsc_i2s_workdata = NULL; /* MDEV */
diff --git a/sound/soc/au1x/psc.h b/sound/soc/au1x/psc.h
index 32d3807d3f5..093775d4dc3 100644
--- a/sound/soc/au1x/psc.h
+++ b/sound/soc/au1x/psc.h
@@ -32,7 +32,6 @@ struct au1xpsc_audio_data {
32 unsigned long rate; 32 unsigned long rate;
33 33
34 unsigned long pm[2]; 34 unsigned long pm[2];
35 struct resource *ioarea;
36 struct mutex lock; 35 struct mutex lock;
37 struct platform_device *dmapd; 36 struct platform_device *dmapd;
38}; 37};
diff --git a/sound/soc/blackfin/Kconfig b/sound/soc/blackfin/Kconfig
index 8ef25025f3d..3abeeddc67d 100644
--- a/sound/soc/blackfin/Kconfig
+++ b/sound/soc/blackfin/Kconfig
@@ -105,13 +105,18 @@ config SND_BF5XX_RESET_GPIO_NUM
105 Set the correct GPIO for RESET the sound chip. 105 Set the correct GPIO for RESET the sound chip.
106 106
107config SND_BF5XX_SOC_AD1980 107config SND_BF5XX_SOC_AD1980
108 tristate "SoC AD1980/1 Audio support for BF5xx" 108 tristate "SoC AD1980/1 Audio support for BF5xx (Obsolete)"
109 depends on SND_BF5XX_AC97 109 depends on SND_BF5XX_AC97
110 select SND_BF5XX_SOC_AC97 110 select SND_BF5XX_SOC_AC97
111 select SND_SOC_AD1980 111 select SND_SOC_AD1980
112 help 112 help
113 Say Y if you want to add support for SoC audio on BF5xx STAMP/EZKIT. 113 Say Y if you want to add support for SoC audio on BF5xx STAMP/EZKIT.
114 114
115 Warning:
116 Because Analog Devices Inc. discontinued the ad1980 sound chip since
117 Sep. 2009, this ad1980 driver is not maintained, tested and supported
118 by ADI now.
119
115config SND_BF5XX_SOC_SPORT 120config SND_BF5XX_SOC_SPORT
116 tristate 121 tristate
117 122
diff --git a/sound/soc/blackfin/bf5xx-ac97.c b/sound/soc/blackfin/bf5xx-ac97.c
index 523b7fc33f4..c0eba510998 100644
--- a/sound/soc/blackfin/bf5xx-ac97.c
+++ b/sound/soc/blackfin/bf5xx-ac97.c
@@ -255,8 +255,7 @@ EXPORT_SYMBOL_GPL(soc_ac97_ops);
255#ifdef CONFIG_PM 255#ifdef CONFIG_PM
256static int bf5xx_ac97_suspend(struct snd_soc_dai *dai) 256static int bf5xx_ac97_suspend(struct snd_soc_dai *dai)
257{ 257{
258 struct sport_device *sport = 258 struct sport_device *sport = dai->private_data;
259 (struct sport_device *)dai->private_data;
260 259
261 pr_debug("%s : sport %d\n", __func__, dai->id); 260 pr_debug("%s : sport %d\n", __func__, dai->id);
262 if (!dai->active) 261 if (!dai->active)
@@ -271,8 +270,7 @@ static int bf5xx_ac97_suspend(struct snd_soc_dai *dai)
271static int bf5xx_ac97_resume(struct snd_soc_dai *dai) 270static int bf5xx_ac97_resume(struct snd_soc_dai *dai)
272{ 271{
273 int ret; 272 int ret;
274 struct sport_device *sport = 273 struct sport_device *sport = dai->private_data;
275 (struct sport_device *)dai->private_data;
276 274
277 pr_debug("%s : sport %d\n", __func__, dai->id); 275 pr_debug("%s : sport %d\n", __func__, dai->id);
278 if (!dai->active) 276 if (!dai->active)
diff --git a/sound/soc/blackfin/bf5xx-ad1980.c b/sound/soc/blackfin/bf5xx-ad1980.c
index d8f59127377..92f7c327bb7 100644
--- a/sound/soc/blackfin/bf5xx-ad1980.c
+++ b/sound/soc/blackfin/bf5xx-ad1980.c
@@ -26,6 +26,14 @@
26 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 26 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27 */ 27 */
28 28
29/*
30 * WARNING:
31 *
32 * Because Analog Devices Inc. discontinued the ad1980 sound chip since
33 * Sep. 2009, this ad1980 driver is not maintained, tested and supported
34 * by ADI now.
35 */
36
29#include <linux/module.h> 37#include <linux/module.h>
30#include <linux/moduleparam.h> 38#include <linux/moduleparam.h>
31#include <linux/device.h> 39#include <linux/device.h>
@@ -109,5 +117,5 @@ module_exit(bf5xx_board_exit);
109 117
110/* Module information */ 118/* Module information */
111MODULE_AUTHOR("Cliff Cai"); 119MODULE_AUTHOR("Cliff Cai");
112MODULE_DESCRIPTION("ALSA SoC AD1980/1 BF5xx board"); 120MODULE_DESCRIPTION("ALSA SoC AD1980/1 BF5xx board (Obsolete)");
113MODULE_LICENSE("GPL"); 121MODULE_LICENSE("GPL");
diff --git a/sound/soc/blackfin/bf5xx-tdm.c b/sound/soc/blackfin/bf5xx-tdm.c
index 4b360124083..24c14269f4b 100644
--- a/sound/soc/blackfin/bf5xx-tdm.c
+++ b/sound/soc/blackfin/bf5xx-tdm.c
@@ -210,8 +210,7 @@ static int bf5xx_tdm_set_channel_map(struct snd_soc_dai *dai,
210#ifdef CONFIG_PM 210#ifdef CONFIG_PM
211static int bf5xx_tdm_suspend(struct snd_soc_dai *dai) 211static int bf5xx_tdm_suspend(struct snd_soc_dai *dai)
212{ 212{
213 struct sport_device *sport = 213 struct sport_device *sport = dai->private_data;
214 (struct sport_device *)dai->private_data;
215 214
216 if (!dai->active) 215 if (!dai->active)
217 return 0; 216 return 0;
@@ -225,8 +224,7 @@ static int bf5xx_tdm_suspend(struct snd_soc_dai *dai)
225static int bf5xx_tdm_resume(struct snd_soc_dai *dai) 224static int bf5xx_tdm_resume(struct snd_soc_dai *dai)
226{ 225{
227 int ret; 226 int ret;
228 struct sport_device *sport = 227 struct sport_device *sport = dai->private_data;
229 (struct sport_device *)dai->private_data;
230 228
231 if (!dai->active) 229 if (!dai->active)
232 return 0; 230 return 0;
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 5da30eb6ad0..83f5c67d3c4 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -22,9 +22,11 @@ config SND_SOC_ALL_CODECS
22 select SND_SOC_AK4642 if I2C 22 select SND_SOC_AK4642 if I2C
23 select SND_SOC_AK4671 if I2C 23 select SND_SOC_AK4671 if I2C
24 select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC 24 select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC
25 select SND_SOC_CS42L51 if I2C
25 select SND_SOC_CS4270 if I2C 26 select SND_SOC_CS4270 if I2C
26 select SND_SOC_MAX9877 if I2C
27 select SND_SOC_DA7210 if I2C 27 select SND_SOC_DA7210 if I2C
28 select SND_SOC_JZ4740 if SOC_JZ4740
29 select SND_SOC_MAX9877 if I2C
28 select SND_SOC_PCM3008 30 select SND_SOC_PCM3008
29 select SND_SOC_SPDIF 31 select SND_SOC_SPDIF
30 select SND_SOC_SSM2602 if I2C 32 select SND_SOC_SSM2602 if I2C
@@ -48,6 +50,7 @@ config SND_SOC_ALL_CODECS
48 select SND_SOC_WM8727 50 select SND_SOC_WM8727
49 select SND_SOC_WM8728 if SND_SOC_I2C_AND_SPI 51 select SND_SOC_WM8728 if SND_SOC_I2C_AND_SPI
50 select SND_SOC_WM8731 if SND_SOC_I2C_AND_SPI 52 select SND_SOC_WM8731 if SND_SOC_I2C_AND_SPI
53 select SND_SOC_WM8741 if SND_SOC_I2C_AND_SPI
51 select SND_SOC_WM8750 if SND_SOC_I2C_AND_SPI 54 select SND_SOC_WM8750 if SND_SOC_I2C_AND_SPI
52 select SND_SOC_WM8753 if SND_SOC_I2C_AND_SPI 55 select SND_SOC_WM8753 if SND_SOC_I2C_AND_SPI
53 select SND_SOC_WM8776 if SND_SOC_I2C_AND_SPI 56 select SND_SOC_WM8776 if SND_SOC_I2C_AND_SPI
@@ -120,13 +123,13 @@ config SND_SOC_AK4671
120config SND_SOC_CQ0093VC 123config SND_SOC_CQ0093VC
121 tristate 124 tristate
122 125
126config SND_SOC_CS42L51
127 tristate
128
123# Cirrus Logic CS4270 Codec 129# Cirrus Logic CS4270 Codec
124config SND_SOC_CS4270 130config SND_SOC_CS4270
125 tristate 131 tristate
126 132
127config SND_SOC_DA7210
128 tristate
129
130# Cirrus Logic CS4270 Codec VD = 3.3V Errata 133# Cirrus Logic CS4270 Codec VD = 3.3V Errata
131# Select if you are affected by the errata where the part will not function 134# Select if you are affected by the errata where the part will not function
132# if MCLK divide-by-1.5 is selected and VD is set to 3.3V. The driver will 135# if MCLK divide-by-1.5 is selected and VD is set to 3.3V. The driver will
@@ -138,9 +141,15 @@ config SND_SOC_CS4270_VD33_ERRATA
138config SND_SOC_CX20442 141config SND_SOC_CX20442
139 tristate 142 tristate
140 143
144config SND_SOC_JZ4740_CODEC
145 tristate
146
141config SND_SOC_L3 147config SND_SOC_L3
142 tristate 148 tristate
143 149
150config SND_SOC_DA7210
151 tristate
152
144config SND_SOC_PCM3008 153config SND_SOC_PCM3008
145 tristate 154 tristate
146 155
@@ -206,6 +215,9 @@ config SND_SOC_WM8728
206config SND_SOC_WM8731 215config SND_SOC_WM8731
207 tristate 216 tristate
208 217
218config SND_SOC_WM8741
219 tristate
220
209config SND_SOC_WM8750 221config SND_SOC_WM8750
210 tristate 222 tristate
211 223
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 91429eab070..53524095759 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -9,6 +9,7 @@ snd-soc-ak4535-objs := ak4535.o
9snd-soc-ak4642-objs := ak4642.o 9snd-soc-ak4642-objs := ak4642.o
10snd-soc-ak4671-objs := ak4671.o 10snd-soc-ak4671-objs := ak4671.o
11snd-soc-cq93vc-objs := cq93vc.o 11snd-soc-cq93vc-objs := cq93vc.o
12snd-soc-cs42l51-objs := cs42l51.o
12snd-soc-cs4270-objs := cs4270.o 13snd-soc-cs4270-objs := cs4270.o
13snd-soc-cx20442-objs := cx20442.o 14snd-soc-cx20442-objs := cx20442.o
14snd-soc-da7210-objs := da7210.o 15snd-soc-da7210-objs := da7210.o
@@ -34,6 +35,7 @@ snd-soc-wm8711-objs := wm8711.o
34snd-soc-wm8727-objs := wm8727.o 35snd-soc-wm8727-objs := wm8727.o
35snd-soc-wm8728-objs := wm8728.o 36snd-soc-wm8728-objs := wm8728.o
36snd-soc-wm8731-objs := wm8731.o 37snd-soc-wm8731-objs := wm8731.o
38snd-soc-wm8741-objs := wm8741.o
37snd-soc-wm8750-objs := wm8750.o 39snd-soc-wm8750-objs := wm8750.o
38snd-soc-wm8753-objs := wm8753.o 40snd-soc-wm8753-objs := wm8753.o
39snd-soc-wm8776-objs := wm8776.o 41snd-soc-wm8776-objs := wm8776.o
@@ -56,6 +58,7 @@ snd-soc-wm9705-objs := wm9705.o
56snd-soc-wm9712-objs := wm9712.o 58snd-soc-wm9712-objs := wm9712.o
57snd-soc-wm9713-objs := wm9713.o 59snd-soc-wm9713-objs := wm9713.o
58snd-soc-wm-hubs-objs := wm_hubs.o 60snd-soc-wm-hubs-objs := wm_hubs.o
61snd-soc-jz4740-codec-objs := jz4740.o
59 62
60# Amp 63# Amp
61snd-soc-max9877-objs := max9877.o 64snd-soc-max9877-objs := max9877.o
@@ -74,10 +77,12 @@ obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o
74obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o 77obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o
75obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o 78obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o
76obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o 79obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o
80obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o
77obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o 81obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
78obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o 82obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o
79obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o 83obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o
80obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o 84obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o
85obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o
81obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o 86obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o
82obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o 87obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o
83obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o 88obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o
@@ -99,6 +104,7 @@ obj-$(CONFIG_SND_SOC_WM8711) += snd-soc-wm8711.o
99obj-$(CONFIG_SND_SOC_WM8727) += snd-soc-wm8727.o 104obj-$(CONFIG_SND_SOC_WM8727) += snd-soc-wm8727.o
100obj-$(CONFIG_SND_SOC_WM8728) += snd-soc-wm8728.o 105obj-$(CONFIG_SND_SOC_WM8728) += snd-soc-wm8728.o
101obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o 106obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o
107obj-$(CONFIG_SND_SOC_WM8741) += snd-soc-wm8741.o
102obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o 108obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o
103obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o 109obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o
104obj-$(CONFIG_SND_SOC_WM8776) += snd-soc-wm8776.o 110obj-$(CONFIG_SND_SOC_WM8776) += snd-soc-wm8776.o
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c
index 21753842322..a01006c8c60 100644
--- a/sound/soc/codecs/ad1836.c
+++ b/sound/soc/codecs/ad1836.c
@@ -272,6 +272,7 @@ static int ad1836_register(struct ad1836_priv *ad1836)
272 272
273 if (ad1836_codec) { 273 if (ad1836_codec) {
274 dev_err(codec->dev, "Another ad1836 is registered\n"); 274 dev_err(codec->dev, "Another ad1836 is registered\n");
275 kfree(ad1836);
275 return -EINVAL; 276 return -EINVAL;
276 } 277 }
277 278
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c
index c8ca1142b2f..1def75e4862 100644
--- a/sound/soc/codecs/ad193x.c
+++ b/sound/soc/codecs/ad193x.c
@@ -24,6 +24,7 @@
24 24
25/* codec private data */ 25/* codec private data */
26struct ad193x_priv { 26struct ad193x_priv {
27 unsigned int sysclk;
27 struct snd_soc_codec codec; 28 struct snd_soc_codec codec;
28 u8 reg_cache[AD193X_NUM_REGS]; 29 u8 reg_cache[AD193X_NUM_REGS];
29}; 30};
@@ -251,15 +252,32 @@ static int ad193x_set_dai_fmt(struct snd_soc_dai *codec_dai,
251 return 0; 252 return 0;
252} 253}
253 254
255static int ad193x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
256 int clk_id, unsigned int freq, int dir)
257{
258 struct snd_soc_codec *codec = codec_dai->codec;
259 struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec);
260 switch (freq) {
261 case 12288000:
262 case 18432000:
263 case 24576000:
264 case 36864000:
265 ad193x->sysclk = freq;
266 return 0;
267 }
268 return -EINVAL;
269}
270
254static int ad193x_hw_params(struct snd_pcm_substream *substream, 271static int ad193x_hw_params(struct snd_pcm_substream *substream,
255 struct snd_pcm_hw_params *params, 272 struct snd_pcm_hw_params *params,
256 struct snd_soc_dai *dai) 273 struct snd_soc_dai *dai)
257{ 274{
258 int word_len = 0, reg = 0; 275 int word_len = 0, reg = 0, master_rate = 0;
259 276
260 struct snd_soc_pcm_runtime *rtd = substream->private_data; 277 struct snd_soc_pcm_runtime *rtd = substream->private_data;
261 struct snd_soc_device *socdev = rtd->socdev; 278 struct snd_soc_device *socdev = rtd->socdev;
262 struct snd_soc_codec *codec = socdev->card->codec; 279 struct snd_soc_codec *codec = socdev->card->codec;
280 struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec);
263 281
264 /* bit size */ 282 /* bit size */
265 switch (params_format(params)) { 283 switch (params_format(params)) {
@@ -275,6 +293,25 @@ static int ad193x_hw_params(struct snd_pcm_substream *substream,
275 break; 293 break;
276 } 294 }
277 295
296 switch (ad193x->sysclk) {
297 case 12288000:
298 master_rate = AD193X_PLL_INPUT_256;
299 break;
300 case 18432000:
301 master_rate = AD193X_PLL_INPUT_384;
302 break;
303 case 24576000:
304 master_rate = AD193X_PLL_INPUT_512;
305 break;
306 case 36864000:
307 master_rate = AD193X_PLL_INPUT_768;
308 break;
309 }
310
311 reg = snd_soc_read(codec, AD193X_PLL_CLK_CTRL0);
312 reg = (reg & AD193X_PLL_INPUT_MASK) | master_rate;
313 snd_soc_write(codec, AD193X_PLL_CLK_CTRL0, reg);
314
278 reg = snd_soc_read(codec, AD193X_DAC_CTRL2); 315 reg = snd_soc_read(codec, AD193X_DAC_CTRL2);
279 reg = (reg & (~AD193X_DAC_WORD_LEN_MASK)) | word_len; 316 reg = (reg & (~AD193X_DAC_WORD_LEN_MASK)) | word_len;
280 snd_soc_write(codec, AD193X_DAC_CTRL2, reg); 317 snd_soc_write(codec, AD193X_DAC_CTRL2, reg);
@@ -348,6 +385,7 @@ static int ad193x_bus_probe(struct device *dev, void *ctrl_data, int bus_type)
348 /* pll input: mclki/xi */ 385 /* pll input: mclki/xi */
349 snd_soc_write(codec, AD193X_PLL_CLK_CTRL0, 0x99); /* mclk=24.576Mhz: 0x9D; mclk=12.288Mhz: 0x99 */ 386 snd_soc_write(codec, AD193X_PLL_CLK_CTRL0, 0x99); /* mclk=24.576Mhz: 0x9D; mclk=12.288Mhz: 0x99 */
350 snd_soc_write(codec, AD193X_PLL_CLK_CTRL1, 0x04); 387 snd_soc_write(codec, AD193X_PLL_CLK_CTRL1, 0x04);
388 ad193x->sysclk = 12288000;
351 389
352 ret = snd_soc_register_codec(codec); 390 ret = snd_soc_register_codec(codec);
353 if (ret != 0) { 391 if (ret != 0) {
@@ -383,6 +421,7 @@ static struct snd_soc_dai_ops ad193x_dai_ops = {
383 .hw_params = ad193x_hw_params, 421 .hw_params = ad193x_hw_params,
384 .digital_mute = ad193x_mute, 422 .digital_mute = ad193x_mute,
385 .set_tdm_slot = ad193x_set_tdm_slot, 423 .set_tdm_slot = ad193x_set_tdm_slot,
424 .set_sysclk = ad193x_set_dai_sysclk,
386 .set_fmt = ad193x_set_dai_fmt, 425 .set_fmt = ad193x_set_dai_fmt,
387}; 426};
388 427
diff --git a/sound/soc/codecs/ad193x.h b/sound/soc/codecs/ad193x.h
index a03c880d52f..654ba64ae04 100644
--- a/sound/soc/codecs/ad193x.h
+++ b/sound/soc/codecs/ad193x.h
@@ -11,6 +11,11 @@
11 11
12#define AD193X_PLL_CLK_CTRL0 0x800 12#define AD193X_PLL_CLK_CTRL0 0x800
13#define AD193X_PLL_POWERDOWN 0x01 13#define AD193X_PLL_POWERDOWN 0x01
14#define AD193X_PLL_INPUT_MASK (~0x6)
15#define AD193X_PLL_INPUT_256 (0 << 1)
16#define AD193X_PLL_INPUT_384 (1 << 1)
17#define AD193X_PLL_INPUT_512 (2 << 1)
18#define AD193X_PLL_INPUT_768 (3 << 1)
14#define AD193X_PLL_CLK_CTRL1 0x801 19#define AD193X_PLL_CLK_CTRL1 0x801
15#define AD193X_DAC_CTRL0 0x802 20#define AD193X_DAC_CTRL0 0x802
16#define AD193X_DAC_POWERDOWN 0x01 21#define AD193X_DAC_POWERDOWN 0x01
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
index 042072738cd..70cfaec3be2 100644
--- a/sound/soc/codecs/ad1980.c
+++ b/sound/soc/codecs/ad1980.c
@@ -11,6 +11,14 @@
11 * option) any later version. 11 * option) any later version.
12 */ 12 */
13 13
14/*
15 * WARNING:
16 *
17 * Because Analog Devices Inc. discontinued the ad1980 sound chip since
18 * Sep. 2009, this ad1980 driver is not maintained, tested and supported
19 * by ADI now.
20 */
21
14#include <linux/init.h> 22#include <linux/init.h>
15#include <linux/slab.h> 23#include <linux/slab.h>
16#include <linux/module.h> 24#include <linux/module.h>
@@ -298,6 +306,6 @@ struct snd_soc_codec_device soc_codec_dev_ad1980 = {
298}; 306};
299EXPORT_SYMBOL_GPL(soc_codec_dev_ad1980); 307EXPORT_SYMBOL_GPL(soc_codec_dev_ad1980);
300 308
301MODULE_DESCRIPTION("ASoC ad1980 driver"); 309MODULE_DESCRIPTION("ASoC ad1980 driver (Obsolete)");
302MODULE_AUTHOR("Roy Huang, Cliff Cai"); 310MODULE_AUTHOR("Roy Huang, Cliff Cai");
303MODULE_LICENSE("GPL"); 311MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ad1980.h b/sound/soc/codecs/ad1980.h
index db6c8500d66..538f37c9080 100644
--- a/sound/soc/codecs/ad1980.h
+++ b/sound/soc/codecs/ad1980.h
@@ -1,5 +1,11 @@
1/* 1/*
2 * ad1980.h -- ad1980 Soc Audio driver 2 * ad1980.h -- ad1980 Soc Audio driver
3 *
4 * WARNING:
5 *
6 * Because Analog Devices Inc. discontinued the ad1980 sound chip since
7 * Sep. 2009, this ad1980 driver is not maintained, tested and supported
8 * by ADI now.
3 */ 9 */
4 10
5#ifndef _AD1980_H 11#ifndef _AD1980_H
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
index 7528a54102b..3d7dc55305e 100644
--- a/sound/soc/codecs/ak4642.c
+++ b/sound/soc/codecs/ak4642.c
@@ -22,20 +22,13 @@
22 * AK4643 is tested. 22 * AK4643 is tested.
23 */ 23 */
24 24
25#include <linux/module.h>
26#include <linux/moduleparam.h>
27#include <linux/init.h>
28#include <linux/delay.h> 25#include <linux/delay.h>
29#include <linux/pm.h>
30#include <linux/i2c.h> 26#include <linux/i2c.h>
31#include <linux/platform_device.h> 27#include <linux/platform_device.h>
32#include <linux/slab.h> 28#include <linux/slab.h>
33#include <sound/core.h>
34#include <sound/pcm.h>
35#include <sound/pcm_params.h>
36#include <sound/soc.h>
37#include <sound/soc-dapm.h> 29#include <sound/soc-dapm.h>
38#include <sound/initval.h> 30#include <sound/initval.h>
31#include <sound/tlv.h>
39 32
40#include "ak4642.h" 33#include "ak4642.h"
41 34
@@ -111,6 +104,23 @@
111 104
112struct snd_soc_codec_device soc_codec_dev_ak4642; 105struct snd_soc_codec_device soc_codec_dev_ak4642;
113 106
107/*
108 * Playback Volume (table 39)
109 *
110 * max : 0x00 : +12.0 dB
111 * ( 0.5 dB step )
112 * min : 0xFE : -115.0 dB
113 * mute: 0xFF
114 */
115static const DECLARE_TLV_DB_SCALE(out_tlv, -11500, 50, 1);
116
117static const struct snd_kcontrol_new ak4642_snd_controls[] = {
118
119 SOC_DOUBLE_R_TLV("Digital Playback Volume", L_DVC, R_DVC,
120 0, 0xFF, 1, out_tlv),
121};
122
123
114/* codec private data */ 124/* codec private data */
115struct ak4642_priv { 125struct ak4642_priv {
116 struct snd_soc_codec codec; 126 struct snd_soc_codec codec;
@@ -204,7 +214,6 @@ static int ak4642_dai_startup(struct snd_pcm_substream *substream,
204 * 214 *
205 * PLL, Master Mode 215 * PLL, Master Mode
206 * Audio I/F Format :MSB justified (ADC & DAC) 216 * Audio I/F Format :MSB justified (ADC & DAC)
207 * Digital Volume: -8dB
208 * Bass Boost Level : Middle 217 * Bass Boost Level : Middle
209 * 218 *
210 * This operation came from example code of 219 * This operation came from example code of
@@ -214,8 +223,6 @@ static int ak4642_dai_startup(struct snd_pcm_substream *substream,
214 ak4642_write(codec, 0x0e, 0x19); 223 ak4642_write(codec, 0x0e, 0x19);
215 ak4642_write(codec, 0x09, 0x91); 224 ak4642_write(codec, 0x09, 0x91);
216 ak4642_write(codec, 0x0c, 0x91); 225 ak4642_write(codec, 0x0c, 0x91);
217 ak4642_write(codec, 0x0a, 0x28);
218 ak4642_write(codec, 0x0d, 0x28);
219 ak4642_write(codec, 0x00, 0x64); 226 ak4642_write(codec, 0x00, 0x64);
220 snd_soc_update_bits(codec, PW_MGMT2, PMHP_MASK, PMHP); 227 snd_soc_update_bits(codec, PW_MGMT2, PMHP_MASK, PMHP);
221 snd_soc_update_bits(codec, PW_MGMT2, HPMTN, HPMTN); 228 snd_soc_update_bits(codec, PW_MGMT2, HPMTN, HPMTN);
@@ -491,8 +498,10 @@ static int ak4642_i2c_probe(struct i2c_client *i2c,
491 codec->control_data = i2c; 498 codec->control_data = i2c;
492 499
493 ret = ak4642_init(ak4642); 500 ret = ak4642_init(ak4642);
494 if (ret < 0) 501 if (ret < 0) {
495 printk(KERN_ERR "failed to initialise AK4642\n"); 502 printk(KERN_ERR "failed to initialise AK4642\n");
503 kfree(ak4642);
504 }
496 505
497 return ret; 506 return ret;
498} 507}
@@ -548,6 +557,9 @@ static int ak4642_probe(struct platform_device *pdev)
548 goto pcm_err; 557 goto pcm_err;
549 } 558 }
550 559
560 snd_soc_add_controls(ak4642_codec, ak4642_snd_controls,
561 ARRAY_SIZE(ak4642_snd_controls));
562
551 dev_info(&pdev->dev, "AK4642 Audio Codec %s", AK4642_VERSION); 563 dev_info(&pdev->dev, "AK4642 Audio Codec %s", AK4642_VERSION);
552 return ret; 564 return ret;
553 565
diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c
new file mode 100644
index 00000000000..dd9b8550c40
--- /dev/null
+++ b/sound/soc/codecs/cs42l51.c
@@ -0,0 +1,763 @@
1/*
2 * cs42l51.c
3 *
4 * ASoC Driver for Cirrus Logic CS42L51 codecs
5 *
6 * Copyright (c) 2010 Arnaud Patard <apatard@mandriva.com>
7 *
8 * Based on cs4270.c - Copyright (c) Freescale Semiconductor
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 * 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 * For now:
20 * - Only I2C is support. Not SPI
21 * - master mode *NOT* supported
22 */
23
24#include <linux/module.h>
25#include <linux/platform_device.h>
26#include <linux/slab.h>
27#include <sound/core.h>
28#include <sound/soc.h>
29#include <sound/soc-dapm.h>
30#include <sound/tlv.h>
31#include <sound/initval.h>
32#include <sound/pcm_params.h>
33#include <sound/pcm.h>
34#include <linux/i2c.h>
35
36#include "cs42l51.h"
37
38enum master_slave_mode {
39 MODE_SLAVE,
40 MODE_SLAVE_AUTO,
41 MODE_MASTER,
42};
43
44struct cs42l51_private {
45 unsigned int mclk;
46 unsigned int audio_mode; /* The mode (I2S or left-justified) */
47 enum master_slave_mode func;
48 struct snd_soc_codec codec;
49 u8 reg_cache[CS42L51_NUMREGS];
50};
51
52static struct snd_soc_codec *cs42l51_codec;
53
54#define CS42L51_FORMATS ( \
55 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \
56 SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S18_3BE | \
57 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE | \
58 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE)
59
60static int cs42l51_fill_cache(struct snd_soc_codec *codec)
61{
62 u8 *cache = codec->reg_cache + 1;
63 struct i2c_client *i2c_client = codec->control_data;
64 s32 length;
65
66 length = i2c_smbus_read_i2c_block_data(i2c_client,
67 CS42L51_FIRSTREG | 0x80, CS42L51_NUMREGS, cache);
68 if (length != CS42L51_NUMREGS) {
69 dev_err(&i2c_client->dev,
70 "I2C read failure, addr=0x%x (ret=%d vs %d)\n",
71 i2c_client->addr, length, CS42L51_NUMREGS);
72 return -EIO;
73 }
74
75 return 0;
76}
77
78static int cs42l51_i2c_probe(struct i2c_client *i2c_client,
79 const struct i2c_device_id *id)
80{
81 struct snd_soc_codec *codec;
82 struct cs42l51_private *cs42l51;
83 int ret = 0;
84 int reg;
85
86 if (cs42l51_codec)
87 return -EBUSY;
88
89 /* Verify that we have a CS42L51 */
90 ret = i2c_smbus_read_byte_data(i2c_client, CS42L51_CHIP_REV_ID);
91 if (ret < 0) {
92 dev_err(&i2c_client->dev, "failed to read I2C\n");
93 goto error;
94 }
95
96 if ((ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_A)) &&
97 (ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_B))) {
98 dev_err(&i2c_client->dev, "Invalid chip id\n");
99 ret = -ENODEV;
100 goto error;
101 }
102
103 dev_info(&i2c_client->dev, "found device cs42l51 rev %d\n",
104 ret & 7);
105
106 cs42l51 = kzalloc(sizeof(struct cs42l51_private), GFP_KERNEL);
107 if (!cs42l51) {
108 dev_err(&i2c_client->dev, "could not allocate codec\n");
109 return -ENOMEM;
110 }
111 codec = &cs42l51->codec;
112
113 mutex_init(&codec->mutex);
114 INIT_LIST_HEAD(&codec->dapm_widgets);
115 INIT_LIST_HEAD(&codec->dapm_paths);
116
117 codec->dev = &i2c_client->dev;
118 codec->name = "CS42L51";
119 codec->owner = THIS_MODULE;
120 codec->dai = &cs42l51_dai;
121 codec->num_dai = 1;
122 snd_soc_codec_set_drvdata(codec, cs42l51);
123
124 codec->control_data = i2c_client;
125 codec->reg_cache = cs42l51->reg_cache;
126 codec->reg_cache_size = CS42L51_NUMREGS;
127 i2c_set_clientdata(i2c_client, codec);
128
129 ret = cs42l51_fill_cache(codec);
130 if (ret < 0) {
131 dev_err(&i2c_client->dev, "failed to fill register cache\n");
132 goto error_alloc;
133 }
134
135 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
136 if (ret < 0) {
137 dev_err(&i2c_client->dev, "Failed to set cache I/O: %d\n", ret);
138 goto error_alloc;
139 }
140
141 /*
142 * DAC configuration
143 * - Use signal processor
144 * - auto mute
145 * - vol changes immediate
146 * - no de-emphasize
147 */
148 reg = CS42L51_DAC_CTL_DATA_SEL(1)
149 | CS42L51_DAC_CTL_AMUTE | CS42L51_DAC_CTL_DACSZ(0);
150 ret = snd_soc_write(codec, CS42L51_DAC_CTL, reg);
151 if (ret < 0)
152 goto error_alloc;
153
154 cs42l51_dai.dev = codec->dev;
155 cs42l51_codec = codec;
156
157 ret = snd_soc_register_codec(codec);
158 if (ret != 0) {
159 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
160 goto error_alloc;
161 }
162
163 ret = snd_soc_register_dai(&cs42l51_dai);
164 if (ret < 0) {
165 dev_err(&i2c_client->dev, "failed to register DAIe\n");
166 goto error_reg;
167 }
168
169 return 0;
170
171error_reg:
172 snd_soc_unregister_codec(codec);
173error_alloc:
174 kfree(cs42l51);
175error:
176 return ret;
177}
178
179static int cs42l51_i2c_remove(struct i2c_client *client)
180{
181 struct cs42l51_private *cs42l51 = i2c_get_clientdata(client);
182 snd_soc_unregister_dai(&cs42l51_dai);
183 snd_soc_unregister_codec(cs42l51_codec);
184 cs42l51_codec = NULL;
185 kfree(cs42l51);
186 return 0;
187}
188
189
190static const struct i2c_device_id cs42l51_id[] = {
191 {"cs42l51", 0},
192 {}
193};
194MODULE_DEVICE_TABLE(i2c, cs42l51_id);
195
196static struct i2c_driver cs42l51_i2c_driver = {
197 .driver = {
198 .name = "CS42L51 I2C",
199 .owner = THIS_MODULE,
200 },
201 .id_table = cs42l51_id,
202 .probe = cs42l51_i2c_probe,
203 .remove = cs42l51_i2c_remove,
204};
205
206static int cs42l51_get_chan_mix(struct snd_kcontrol *kcontrol,
207 struct snd_ctl_elem_value *ucontrol)
208{
209 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
210 unsigned long value = snd_soc_read(codec, CS42L51_PCM_MIXER)&3;
211
212 switch (value) {
213 default:
214 case 0:
215 ucontrol->value.integer.value[0] = 0;
216 break;
217 /* same value : (L+R)/2 and (R+L)/2 */
218 case 1:
219 case 2:
220 ucontrol->value.integer.value[0] = 1;
221 break;
222 case 3:
223 ucontrol->value.integer.value[0] = 2;
224 break;
225 }
226
227 return 0;
228}
229
230#define CHAN_MIX_NORMAL 0x00
231#define CHAN_MIX_BOTH 0x55
232#define CHAN_MIX_SWAP 0xFF
233
234static int cs42l51_set_chan_mix(struct snd_kcontrol *kcontrol,
235 struct snd_ctl_elem_value *ucontrol)
236{
237 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
238 unsigned char val;
239
240 switch (ucontrol->value.integer.value[0]) {
241 default:
242 case 0:
243 val = CHAN_MIX_NORMAL;
244 break;
245 case 1:
246 val = CHAN_MIX_BOTH;
247 break;
248 case 2:
249 val = CHAN_MIX_SWAP;
250 break;
251 }
252
253 snd_soc_write(codec, CS42L51_PCM_MIXER, val);
254
255 return 1;
256}
257
258static const DECLARE_TLV_DB_SCALE(adc_pcm_tlv, -5150, 50, 0);
259static const DECLARE_TLV_DB_SCALE(tone_tlv, -1050, 150, 0);
260/* This is a lie. after -102 db, it stays at -102 */
261/* maybe a range would be better */
262static const DECLARE_TLV_DB_SCALE(aout_tlv, -11550, 50, 0);
263
264static const DECLARE_TLV_DB_SCALE(boost_tlv, 1600, 1600, 0);
265static const char *chan_mix[] = {
266 "L R",
267 "L+R",
268 "R L",
269};
270
271static const struct soc_enum cs42l51_chan_mix =
272 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(chan_mix), chan_mix);
273
274static const struct snd_kcontrol_new cs42l51_snd_controls[] = {
275 SOC_DOUBLE_R_SX_TLV("PCM Playback Volume",
276 CS42L51_PCMA_VOL, CS42L51_PCMB_VOL,
277 7, 0xffffff99, 0x18, adc_pcm_tlv),
278 SOC_DOUBLE_R("PCM Playback Switch",
279 CS42L51_PCMA_VOL, CS42L51_PCMB_VOL, 7, 1, 1),
280 SOC_DOUBLE_R_SX_TLV("Analog Playback Volume",
281 CS42L51_AOUTA_VOL, CS42L51_AOUTB_VOL,
282 8, 0xffffff19, 0x18, aout_tlv),
283 SOC_DOUBLE_R_SX_TLV("ADC Mixer Volume",
284 CS42L51_ADCA_VOL, CS42L51_ADCB_VOL,
285 7, 0xffffff99, 0x18, adc_pcm_tlv),
286 SOC_DOUBLE_R("ADC Mixer Switch",
287 CS42L51_ADCA_VOL, CS42L51_ADCB_VOL, 7, 1, 1),
288 SOC_SINGLE("Playback Deemphasis Switch", CS42L51_DAC_CTL, 3, 1, 0),
289 SOC_SINGLE("Auto-Mute Switch", CS42L51_DAC_CTL, 2, 1, 0),
290 SOC_SINGLE("Soft Ramp Switch", CS42L51_DAC_CTL, 1, 1, 0),
291 SOC_SINGLE("Zero Cross Switch", CS42L51_DAC_CTL, 0, 0, 0),
292 SOC_DOUBLE_TLV("Mic Boost Volume",
293 CS42L51_MIC_CTL, 0, 1, 1, 0, boost_tlv),
294 SOC_SINGLE_TLV("Bass Volume", CS42L51_TONE_CTL, 0, 0xf, 1, tone_tlv),
295 SOC_SINGLE_TLV("Treble Volume", CS42L51_TONE_CTL, 4, 0xf, 1, tone_tlv),
296 SOC_ENUM_EXT("PCM channel mixer",
297 cs42l51_chan_mix,
298 cs42l51_get_chan_mix, cs42l51_set_chan_mix),
299};
300
301/*
302 * to power down, one must:
303 * 1.) Enable the PDN bit
304 * 2.) enable power-down for the select channels
305 * 3.) disable the PDN bit.
306 */
307static int cs42l51_pdn_event(struct snd_soc_dapm_widget *w,
308 struct snd_kcontrol *kcontrol, int event)
309{
310 unsigned long value;
311
312 value = snd_soc_read(w->codec, CS42L51_POWER_CTL1);
313 value &= ~CS42L51_POWER_CTL1_PDN;
314
315 switch (event) {
316 case SND_SOC_DAPM_PRE_PMD:
317 value |= CS42L51_POWER_CTL1_PDN;
318 break;
319 default:
320 case SND_SOC_DAPM_POST_PMD:
321 break;
322 }
323 snd_soc_update_bits(w->codec, CS42L51_POWER_CTL1,
324 CS42L51_POWER_CTL1_PDN, value);
325
326 return 0;
327}
328
329static const char *cs42l51_dac_names[] = {"Direct PCM",
330 "DSP PCM", "ADC"};
331static const struct soc_enum cs42l51_dac_mux_enum =
332 SOC_ENUM_SINGLE(CS42L51_DAC_CTL, 6, 3, cs42l51_dac_names);
333static const struct snd_kcontrol_new cs42l51_dac_mux_controls =
334 SOC_DAPM_ENUM("Route", cs42l51_dac_mux_enum);
335
336static const char *cs42l51_adcl_names[] = {"AIN1 Left", "AIN2 Left",
337 "MIC Left", "MIC+preamp Left"};
338static const struct soc_enum cs42l51_adcl_mux_enum =
339 SOC_ENUM_SINGLE(CS42L51_ADC_INPUT, 4, 4, cs42l51_adcl_names);
340static const struct snd_kcontrol_new cs42l51_adcl_mux_controls =
341 SOC_DAPM_ENUM("Route", cs42l51_adcl_mux_enum);
342
343static const char *cs42l51_adcr_names[] = {"AIN1 Right", "AIN2 Right",
344 "MIC Right", "MIC+preamp Right"};
345static const struct soc_enum cs42l51_adcr_mux_enum =
346 SOC_ENUM_SINGLE(CS42L51_ADC_INPUT, 6, 4, cs42l51_adcr_names);
347static const struct snd_kcontrol_new cs42l51_adcr_mux_controls =
348 SOC_DAPM_ENUM("Route", cs42l51_adcr_mux_enum);
349
350static const struct snd_soc_dapm_widget cs42l51_dapm_widgets[] = {
351 SND_SOC_DAPM_MICBIAS("Mic Bias", CS42L51_MIC_POWER_CTL, 1, 1),
352 SND_SOC_DAPM_PGA_E("Left PGA", CS42L51_POWER_CTL1, 3, 1, NULL, 0,
353 cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD),
354 SND_SOC_DAPM_PGA_E("Right PGA", CS42L51_POWER_CTL1, 4, 1, NULL, 0,
355 cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD),
356 SND_SOC_DAPM_ADC_E("Left ADC", "Left HiFi Capture",
357 CS42L51_POWER_CTL1, 1, 1,
358 cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD),
359 SND_SOC_DAPM_ADC_E("Right ADC", "Right HiFi Capture",
360 CS42L51_POWER_CTL1, 2, 1,
361 cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD),
362 SND_SOC_DAPM_DAC_E("Left DAC", "Left HiFi Playback",
363 CS42L51_POWER_CTL1, 5, 1,
364 cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD),
365 SND_SOC_DAPM_DAC_E("Right DAC", "Right HiFi Playback",
366 CS42L51_POWER_CTL1, 6, 1,
367 cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD),
368
369 /* analog/mic */
370 SND_SOC_DAPM_INPUT("AIN1L"),
371 SND_SOC_DAPM_INPUT("AIN1R"),
372 SND_SOC_DAPM_INPUT("AIN2L"),
373 SND_SOC_DAPM_INPUT("AIN2R"),
374 SND_SOC_DAPM_INPUT("MICL"),
375 SND_SOC_DAPM_INPUT("MICR"),
376
377 SND_SOC_DAPM_MIXER("Mic Preamp Left",
378 CS42L51_MIC_POWER_CTL, 2, 1, NULL, 0),
379 SND_SOC_DAPM_MIXER("Mic Preamp Right",
380 CS42L51_MIC_POWER_CTL, 3, 1, NULL, 0),
381
382 /* HP */
383 SND_SOC_DAPM_OUTPUT("HPL"),
384 SND_SOC_DAPM_OUTPUT("HPR"),
385
386 /* mux */
387 SND_SOC_DAPM_MUX("DAC Mux", SND_SOC_NOPM, 0, 0,
388 &cs42l51_dac_mux_controls),
389 SND_SOC_DAPM_MUX("PGA-ADC Mux Left", SND_SOC_NOPM, 0, 0,
390 &cs42l51_adcl_mux_controls),
391 SND_SOC_DAPM_MUX("PGA-ADC Mux Right", SND_SOC_NOPM, 0, 0,
392 &cs42l51_adcr_mux_controls),
393};
394
395static const struct snd_soc_dapm_route cs42l51_routes[] = {
396 {"HPL", NULL, "Left DAC"},
397 {"HPR", NULL, "Right DAC"},
398
399 {"Left ADC", NULL, "Left PGA"},
400 {"Right ADC", NULL, "Right PGA"},
401
402 {"Mic Preamp Left", NULL, "MICL"},
403 {"Mic Preamp Right", NULL, "MICR"},
404
405 {"PGA-ADC Mux Left", "AIN1 Left", "AIN1L" },
406 {"PGA-ADC Mux Left", "AIN2 Left", "AIN2L" },
407 {"PGA-ADC Mux Left", "MIC Left", "MICL" },
408 {"PGA-ADC Mux Left", "MIC+preamp Left", "Mic Preamp Left" },
409 {"PGA-ADC Mux Right", "AIN1 Right", "AIN1R" },
410 {"PGA-ADC Mux Right", "AIN2 Right", "AIN2R" },
411 {"PGA-ADC Mux Right", "MIC Right", "MICR" },
412 {"PGA-ADC Mux Right", "MIC+preamp Right", "Mic Preamp Right" },
413
414 {"Left PGA", NULL, "PGA-ADC Mux Left"},
415 {"Right PGA", NULL, "PGA-ADC Mux Right"},
416};
417
418static int cs42l51_set_dai_fmt(struct snd_soc_dai *codec_dai,
419 unsigned int format)
420{
421 struct snd_soc_codec *codec = codec_dai->codec;
422 struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
423 int ret = 0;
424
425 switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
426 case SND_SOC_DAIFMT_I2S:
427 case SND_SOC_DAIFMT_LEFT_J:
428 case SND_SOC_DAIFMT_RIGHT_J:
429 cs42l51->audio_mode = format & SND_SOC_DAIFMT_FORMAT_MASK;
430 break;
431 default:
432 dev_err(codec->dev, "invalid DAI format\n");
433 ret = -EINVAL;
434 }
435
436 switch (format & SND_SOC_DAIFMT_MASTER_MASK) {
437 case SND_SOC_DAIFMT_CBM_CFM:
438 cs42l51->func = MODE_MASTER;
439 break;
440 case SND_SOC_DAIFMT_CBS_CFS:
441 cs42l51->func = MODE_SLAVE_AUTO;
442 break;
443 default:
444 ret = -EINVAL;
445 break;
446 }
447
448 return ret;
449}
450
451struct cs42l51_ratios {
452 unsigned int ratio;
453 unsigned char speed_mode;
454 unsigned char mclk;
455};
456
457static struct cs42l51_ratios slave_ratios[] = {
458 { 512, CS42L51_QSM_MODE, 0 }, { 768, CS42L51_QSM_MODE, 0 },
459 { 1024, CS42L51_QSM_MODE, 0 }, { 1536, CS42L51_QSM_MODE, 0 },
460 { 2048, CS42L51_QSM_MODE, 0 }, { 3072, CS42L51_QSM_MODE, 0 },
461 { 256, CS42L51_HSM_MODE, 0 }, { 384, CS42L51_HSM_MODE, 0 },
462 { 512, CS42L51_HSM_MODE, 0 }, { 768, CS42L51_HSM_MODE, 0 },
463 { 1024, CS42L51_HSM_MODE, 0 }, { 1536, CS42L51_HSM_MODE, 0 },
464 { 128, CS42L51_SSM_MODE, 0 }, { 192, CS42L51_SSM_MODE, 0 },
465 { 256, CS42L51_SSM_MODE, 0 }, { 384, CS42L51_SSM_MODE, 0 },
466 { 512, CS42L51_SSM_MODE, 0 }, { 768, CS42L51_SSM_MODE, 0 },
467 { 128, CS42L51_DSM_MODE, 0 }, { 192, CS42L51_DSM_MODE, 0 },
468 { 256, CS42L51_DSM_MODE, 0 }, { 384, CS42L51_DSM_MODE, 0 },
469};
470
471static struct cs42l51_ratios slave_auto_ratios[] = {
472 { 1024, CS42L51_QSM_MODE, 0 }, { 1536, CS42L51_QSM_MODE, 0 },
473 { 2048, CS42L51_QSM_MODE, 1 }, { 3072, CS42L51_QSM_MODE, 1 },
474 { 512, CS42L51_HSM_MODE, 0 }, { 768, CS42L51_HSM_MODE, 0 },
475 { 1024, CS42L51_HSM_MODE, 1 }, { 1536, CS42L51_HSM_MODE, 1 },
476 { 256, CS42L51_SSM_MODE, 0 }, { 384, CS42L51_SSM_MODE, 0 },
477 { 512, CS42L51_SSM_MODE, 1 }, { 768, CS42L51_SSM_MODE, 1 },
478 { 128, CS42L51_DSM_MODE, 0 }, { 192, CS42L51_DSM_MODE, 0 },
479 { 256, CS42L51_DSM_MODE, 1 }, { 384, CS42L51_DSM_MODE, 1 },
480};
481
482static int cs42l51_set_dai_sysclk(struct snd_soc_dai *codec_dai,
483 int clk_id, unsigned int freq, int dir)
484{
485 struct snd_soc_codec *codec = codec_dai->codec;
486 struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
487 struct cs42l51_ratios *ratios = NULL;
488 int nr_ratios = 0;
489 unsigned int rates = 0;
490 unsigned int rate_min = -1;
491 unsigned int rate_max = 0;
492 int i;
493
494 cs42l51->mclk = freq;
495
496 switch (cs42l51->func) {
497 case MODE_MASTER:
498 return -EINVAL;
499 case MODE_SLAVE:
500 ratios = slave_ratios;
501 nr_ratios = ARRAY_SIZE(slave_ratios);
502 break;
503 case MODE_SLAVE_AUTO:
504 ratios = slave_auto_ratios;
505 nr_ratios = ARRAY_SIZE(slave_auto_ratios);
506 break;
507 }
508
509 for (i = 0; i < nr_ratios; i++) {
510 unsigned int rate = freq / ratios[i].ratio;
511 rates |= snd_pcm_rate_to_rate_bit(rate);
512 if (rate < rate_min)
513 rate_min = rate;
514 if (rate > rate_max)
515 rate_max = rate;
516 }
517 rates &= ~SNDRV_PCM_RATE_KNOT;
518
519 if (!rates) {
520 dev_err(codec->dev, "could not find a valid sample rate\n");
521 return -EINVAL;
522 }
523
524 codec_dai->playback.rates = rates;
525 codec_dai->playback.rate_min = rate_min;
526 codec_dai->playback.rate_max = rate_max;
527
528 codec_dai->capture.rates = rates;
529 codec_dai->capture.rate_min = rate_min;
530 codec_dai->capture.rate_max = rate_max;
531
532 return 0;
533}
534
535static int cs42l51_hw_params(struct snd_pcm_substream *substream,
536 struct snd_pcm_hw_params *params,
537 struct snd_soc_dai *dai)
538{
539 struct snd_soc_pcm_runtime *rtd = substream->private_data;
540 struct snd_soc_device *socdev = rtd->socdev;
541 struct snd_soc_codec *codec = socdev->card->codec;
542 struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
543 int ret;
544 unsigned int i;
545 unsigned int rate;
546 unsigned int ratio;
547 struct cs42l51_ratios *ratios = NULL;
548 int nr_ratios = 0;
549 int intf_ctl, power_ctl, fmt;
550
551 switch (cs42l51->func) {
552 case MODE_MASTER:
553 return -EINVAL;
554 case MODE_SLAVE:
555 ratios = slave_ratios;
556 nr_ratios = ARRAY_SIZE(slave_ratios);
557 break;
558 case MODE_SLAVE_AUTO:
559 ratios = slave_auto_ratios;
560 nr_ratios = ARRAY_SIZE(slave_auto_ratios);
561 break;
562 }
563
564 /* Figure out which MCLK/LRCK ratio to use */
565 rate = params_rate(params); /* Sampling rate, in Hz */
566 ratio = cs42l51->mclk / rate; /* MCLK/LRCK ratio */
567 for (i = 0; i < nr_ratios; i++) {
568 if (ratios[i].ratio == ratio)
569 break;
570 }
571
572 if (i == nr_ratios) {
573 /* We did not find a matching ratio */
574 dev_err(codec->dev, "could not find matching ratio\n");
575 return -EINVAL;
576 }
577
578 intf_ctl = snd_soc_read(codec, CS42L51_INTF_CTL);
579 power_ctl = snd_soc_read(codec, CS42L51_MIC_POWER_CTL);
580
581 intf_ctl &= ~(CS42L51_INTF_CTL_MASTER | CS42L51_INTF_CTL_ADC_I2S
582 | CS42L51_INTF_CTL_DAC_FORMAT(7));
583 power_ctl &= ~(CS42L51_MIC_POWER_CTL_SPEED(3)
584 | CS42L51_MIC_POWER_CTL_MCLK_DIV2);
585
586 switch (cs42l51->func) {
587 case MODE_MASTER:
588 intf_ctl |= CS42L51_INTF_CTL_MASTER;
589 power_ctl |= CS42L51_MIC_POWER_CTL_SPEED(ratios[i].speed_mode);
590 break;
591 case MODE_SLAVE:
592 power_ctl |= CS42L51_MIC_POWER_CTL_SPEED(ratios[i].speed_mode);
593 break;
594 case MODE_SLAVE_AUTO:
595 power_ctl |= CS42L51_MIC_POWER_CTL_AUTO;
596 break;
597 }
598
599 switch (cs42l51->audio_mode) {
600 case SND_SOC_DAIFMT_I2S:
601 intf_ctl |= CS42L51_INTF_CTL_ADC_I2S;
602 intf_ctl |= CS42L51_INTF_CTL_DAC_FORMAT(CS42L51_DAC_DIF_I2S);
603 break;
604 case SND_SOC_DAIFMT_LEFT_J:
605 intf_ctl |= CS42L51_INTF_CTL_DAC_FORMAT(CS42L51_DAC_DIF_LJ24);
606 break;
607 case SND_SOC_DAIFMT_RIGHT_J:
608 switch (params_format(params)) {
609 case SNDRV_PCM_FORMAT_S16_LE:
610 case SNDRV_PCM_FORMAT_S16_BE:
611 fmt = CS42L51_DAC_DIF_RJ16;
612 break;
613 case SNDRV_PCM_FORMAT_S18_3LE:
614 case SNDRV_PCM_FORMAT_S18_3BE:
615 fmt = CS42L51_DAC_DIF_RJ18;
616 break;
617 case SNDRV_PCM_FORMAT_S20_3LE:
618 case SNDRV_PCM_FORMAT_S20_3BE:
619 fmt = CS42L51_DAC_DIF_RJ20;
620 break;
621 case SNDRV_PCM_FORMAT_S24_LE:
622 case SNDRV_PCM_FORMAT_S24_BE:
623 fmt = CS42L51_DAC_DIF_RJ24;
624 break;
625 default:
626 dev_err(codec->dev, "unknown format\n");
627 return -EINVAL;
628 }
629 intf_ctl |= CS42L51_INTF_CTL_DAC_FORMAT(fmt);
630 break;
631 default:
632 dev_err(codec->dev, "unknown format\n");
633 return -EINVAL;
634 }
635
636 if (ratios[i].mclk)
637 power_ctl |= CS42L51_MIC_POWER_CTL_MCLK_DIV2;
638
639 ret = snd_soc_write(codec, CS42L51_INTF_CTL, intf_ctl);
640 if (ret < 0)
641 return ret;
642
643 ret = snd_soc_write(codec, CS42L51_MIC_POWER_CTL, power_ctl);
644 if (ret < 0)
645 return ret;
646
647 return 0;
648}
649
650static int cs42l51_dai_mute(struct snd_soc_dai *dai, int mute)
651{
652 struct snd_soc_codec *codec = dai->codec;
653 int reg;
654 int mask = CS42L51_DAC_OUT_CTL_DACA_MUTE|CS42L51_DAC_OUT_CTL_DACB_MUTE;
655
656 reg = snd_soc_read(codec, CS42L51_DAC_OUT_CTL);
657
658 if (mute)
659 reg |= mask;
660 else
661 reg &= ~mask;
662
663 return snd_soc_write(codec, CS42L51_DAC_OUT_CTL, reg);
664}
665
666static struct snd_soc_dai_ops cs42l51_dai_ops = {
667 .hw_params = cs42l51_hw_params,
668 .set_sysclk = cs42l51_set_dai_sysclk,
669 .set_fmt = cs42l51_set_dai_fmt,
670 .digital_mute = cs42l51_dai_mute,
671};
672
673struct snd_soc_dai cs42l51_dai = {
674 .name = "CS42L51 HiFi",
675 .playback = {
676 .stream_name = "Playback",
677 .channels_min = 1,
678 .channels_max = 2,
679 .rates = SNDRV_PCM_RATE_8000_96000,
680 .formats = CS42L51_FORMATS,
681 },
682 .capture = {
683 .stream_name = "Capture",
684 .channels_min = 1,
685 .channels_max = 2,
686 .rates = SNDRV_PCM_RATE_8000_96000,
687 .formats = CS42L51_FORMATS,
688 },
689 .ops = &cs42l51_dai_ops,
690};
691EXPORT_SYMBOL_GPL(cs42l51_dai);
692
693
694static int cs42l51_probe(struct platform_device *pdev)
695{
696 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
697 struct snd_soc_codec *codec;
698 int ret = 0;
699
700 if (!cs42l51_codec) {
701 dev_err(&pdev->dev, "CS42L51 codec not yet registered\n");
702 return -EINVAL;
703 }
704
705 socdev->card->codec = cs42l51_codec;
706 codec = socdev->card->codec;
707
708 /* Register PCMs */
709 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
710 if (ret < 0) {
711 dev_err(&pdev->dev, "failed to create PCMs\n");
712 return ret;
713 }
714
715 snd_soc_add_controls(codec, cs42l51_snd_controls,
716 ARRAY_SIZE(cs42l51_snd_controls));
717 snd_soc_dapm_new_controls(codec, cs42l51_dapm_widgets,
718 ARRAY_SIZE(cs42l51_dapm_widgets));
719 snd_soc_dapm_add_routes(codec, cs42l51_routes,
720 ARRAY_SIZE(cs42l51_routes));
721
722 return 0;
723}
724
725
726static int cs42l51_remove(struct platform_device *pdev)
727{
728 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
729
730 snd_soc_free_pcms(socdev);
731 snd_soc_dapm_free(socdev);
732
733 return 0;
734}
735
736struct snd_soc_codec_device soc_codec_device_cs42l51 = {
737 .probe = cs42l51_probe,
738 .remove = cs42l51_remove
739};
740EXPORT_SYMBOL_GPL(soc_codec_device_cs42l51);
741
742static int __init cs42l51_init(void)
743{
744 int ret;
745
746 ret = i2c_add_driver(&cs42l51_i2c_driver);
747 if (ret != 0) {
748 printk(KERN_ERR "%s: can't add i2c driver\n", __func__);
749 return ret;
750 }
751 return 0;
752}
753module_init(cs42l51_init);
754
755static void __exit cs42l51_exit(void)
756{
757 i2c_del_driver(&cs42l51_i2c_driver);
758}
759module_exit(cs42l51_exit);
760
761MODULE_AUTHOR("Arnaud Patard <apatard@mandriva.com>");
762MODULE_DESCRIPTION("Cirrus Logic CS42L51 ALSA SoC Codec Driver");
763MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/cs42l51.h b/sound/soc/codecs/cs42l51.h
new file mode 100644
index 00000000000..8f0bd9786ad
--- /dev/null
+++ b/sound/soc/codecs/cs42l51.h
@@ -0,0 +1,163 @@
1/*
2 * cs42l51.h
3 *
4 * ASoC Driver for Cirrus Logic CS42L51 codecs
5 *
6 * Copyright (c) 2010 Arnaud Patard <apatard@mandriva.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 as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
18#ifndef _CS42L51_H
19#define _CS42L51_H
20
21#define CS42L51_CHIP_ID 0x1B
22#define CS42L51_CHIP_REV_A 0x00
23#define CS42L51_CHIP_REV_B 0x01
24
25#define CS42L51_CHIP_REV_ID 0x01
26#define CS42L51_MK_CHIP_REV(a, b) ((a)<<3|(b))
27
28#define CS42L51_POWER_CTL1 0x02
29#define CS42L51_POWER_CTL1_PDN_DACB (1<<6)
30#define CS42L51_POWER_CTL1_PDN_DACA (1<<5)
31#define CS42L51_POWER_CTL1_PDN_PGAB (1<<4)
32#define CS42L51_POWER_CTL1_PDN_PGAA (1<<3)
33#define CS42L51_POWER_CTL1_PDN_ADCB (1<<2)
34#define CS42L51_POWER_CTL1_PDN_ADCA (1<<1)
35#define CS42L51_POWER_CTL1_PDN (1<<0)
36
37#define CS42L51_MIC_POWER_CTL 0x03
38#define CS42L51_MIC_POWER_CTL_AUTO (1<<7)
39#define CS42L51_MIC_POWER_CTL_SPEED(x) (((x)&3)<<5)
40#define CS42L51_QSM_MODE 3
41#define CS42L51_HSM_MODE 2
42#define CS42L51_SSM_MODE 1
43#define CS42L51_DSM_MODE 0
44#define CS42L51_MIC_POWER_CTL_3ST_SP (1<<4)
45#define CS42L51_MIC_POWER_CTL_PDN_MICB (1<<3)
46#define CS42L51_MIC_POWER_CTL_PDN_MICA (1<<2)
47#define CS42L51_MIC_POWER_CTL_PDN_BIAS (1<<1)
48#define CS42L51_MIC_POWER_CTL_MCLK_DIV2 (1<<0)
49
50#define CS42L51_INTF_CTL 0x04
51#define CS42L51_INTF_CTL_LOOPBACK (1<<7)
52#define CS42L51_INTF_CTL_MASTER (1<<6)
53#define CS42L51_INTF_CTL_DAC_FORMAT(x) (((x)&7)<<3)
54#define CS42L51_DAC_DIF_LJ24 0x00
55#define CS42L51_DAC_DIF_I2S 0x01
56#define CS42L51_DAC_DIF_RJ24 0x02
57#define CS42L51_DAC_DIF_RJ20 0x03
58#define CS42L51_DAC_DIF_RJ18 0x04
59#define CS42L51_DAC_DIF_RJ16 0x05
60#define CS42L51_INTF_CTL_ADC_I2S (1<<2)
61#define CS42L51_INTF_CTL_DIGMIX (1<<1)
62#define CS42L51_INTF_CTL_MICMIX (1<<0)
63
64#define CS42L51_MIC_CTL 0x05
65#define CS42L51_MIC_CTL_ADC_SNGVOL (1<<7)
66#define CS42L51_MIC_CTL_ADCD_DBOOST (1<<6)
67#define CS42L51_MIC_CTL_ADCA_DBOOST (1<<5)
68#define CS42L51_MIC_CTL_MICBIAS_SEL (1<<4)
69#define CS42L51_MIC_CTL_MICBIAS_LVL(x) (((x)&3)<<2)
70#define CS42L51_MIC_CTL_MICB_BOOST (1<<1)
71#define CS42L51_MIC_CTL_MICA_BOOST (1<<0)
72
73#define CS42L51_ADC_CTL 0x06
74#define CS42L51_ADC_CTL_ADCB_HPFEN (1<<7)
75#define CS42L51_ADC_CTL_ADCB_HPFRZ (1<<6)
76#define CS42L51_ADC_CTL_ADCA_HPFEN (1<<5)
77#define CS42L51_ADC_CTL_ADCA_HPFRZ (1<<4)
78#define CS42L51_ADC_CTL_SOFTB (1<<3)
79#define CS42L51_ADC_CTL_ZCROSSB (1<<2)
80#define CS42L51_ADC_CTL_SOFTA (1<<1)
81#define CS42L51_ADC_CTL_ZCROSSA (1<<0)
82
83#define CS42L51_ADC_INPUT 0x07
84#define CS42L51_ADC_INPUT_AINB_MUX(x) (((x)&3)<<6)
85#define CS42L51_ADC_INPUT_AINA_MUX(x) (((x)&3)<<4)
86#define CS42L51_ADC_INPUT_INV_ADCB (1<<3)
87#define CS42L51_ADC_INPUT_INV_ADCA (1<<2)
88#define CS42L51_ADC_INPUT_ADCB_MUTE (1<<1)
89#define CS42L51_ADC_INPUT_ADCA_MUTE (1<<0)
90
91#define CS42L51_DAC_OUT_CTL 0x08
92#define CS42L51_DAC_OUT_CTL_HP_GAIN(x) (((x)&7)<<5)
93#define CS42L51_DAC_OUT_CTL_DAC_SNGVOL (1<<4)
94#define CS42L51_DAC_OUT_CTL_INV_PCMB (1<<3)
95#define CS42L51_DAC_OUT_CTL_INV_PCMA (1<<2)
96#define CS42L51_DAC_OUT_CTL_DACB_MUTE (1<<1)
97#define CS42L51_DAC_OUT_CTL_DACA_MUTE (1<<0)
98
99#define CS42L51_DAC_CTL 0x09
100#define CS42L51_DAC_CTL_DATA_SEL(x) (((x)&3)<<6)
101#define CS42L51_DAC_CTL_FREEZE (1<<5)
102#define CS42L51_DAC_CTL_DEEMPH (1<<3)
103#define CS42L51_DAC_CTL_AMUTE (1<<2)
104#define CS42L51_DAC_CTL_DACSZ(x) (((x)&3)<<0)
105
106#define CS42L51_ALC_PGA_CTL 0x0A
107#define CS42L51_ALC_PGB_CTL 0x0B
108#define CS42L51_ALC_PGX_ALCX_SRDIS (1<<7)
109#define CS42L51_ALC_PGX_ALCX_ZCDIS (1<<6)
110#define CS42L51_ALC_PGX_PGX_VOL(x) (((x)&0x1f)<<0)
111
112#define CS42L51_ADCA_ATT 0x0C
113#define CS42L51_ADCB_ATT 0x0D
114
115#define CS42L51_ADCA_VOL 0x0E
116#define CS42L51_ADCB_VOL 0x0F
117#define CS42L51_PCMA_VOL 0x10
118#define CS42L51_PCMB_VOL 0x11
119#define CS42L51_MIX_MUTE_ADCMIX (1<<7)
120#define CS42L51_MIX_VOLUME(x) (((x)&0x7f)<<0)
121
122#define CS42L51_BEEP_FREQ 0x12
123#define CS42L51_BEEP_VOL 0x13
124#define CS42L51_BEEP_CONF 0x14
125
126#define CS42L51_TONE_CTL 0x15
127#define CS42L51_TONE_CTL_TREB(x) (((x)&0xf)<<4)
128#define CS42L51_TONE_CTL_BASS(x) (((x)&0xf)<<0)
129
130#define CS42L51_AOUTA_VOL 0x16
131#define CS42L51_AOUTB_VOL 0x17
132#define CS42L51_PCM_MIXER 0x18
133#define CS42L51_LIMIT_THRES_DIS 0x19
134#define CS42L51_LIMIT_REL 0x1A
135#define CS42L51_LIMIT_ATT 0x1B
136#define CS42L51_ALC_EN 0x1C
137#define CS42L51_ALC_REL 0x1D
138#define CS42L51_ALC_THRES 0x1E
139#define CS42L51_NOISE_CONF 0x1F
140
141#define CS42L51_STATUS 0x20
142#define CS42L51_STATUS_SP_CLKERR (1<<6)
143#define CS42L51_STATUS_SPEA_OVFL (1<<5)
144#define CS42L51_STATUS_SPEB_OVFL (1<<4)
145#define CS42L51_STATUS_PCMA_OVFL (1<<3)
146#define CS42L51_STATUS_PCMB_OVFL (1<<2)
147#define CS42L51_STATUS_ADCA_OVFL (1<<1)
148#define CS42L51_STATUS_ADCB_OVFL (1<<0)
149
150#define CS42L51_CHARGE_FREQ 0x21
151
152#define CS42L51_FIRSTREG 0x01
153/*
154 * Hack: with register 0x21, it makes 33 registers. Looks like someone in the
155 * i2c layer doesn't like i2c smbus block read of 33 regs. Workaround by using
156 * 32 regs
157 */
158#define CS42L51_LASTREG 0x20
159#define CS42L51_NUMREGS (CS42L51_LASTREG - CS42L51_FIRSTREG + 1)
160
161extern struct snd_soc_dai cs42l51_dai;
162extern struct snd_soc_codec_device soc_codec_device_cs42l51;
163#endif
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c
index 75af2d6e0e7..3c51d6a5752 100644
--- a/sound/soc/codecs/da7210.c
+++ b/sound/soc/codecs/da7210.c
@@ -15,23 +15,15 @@
15 * option) any later version. 15 * option) any later version.
16 */ 16 */
17 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> 18#include <linux/delay.h>
23#include <linux/pm.h>
24#include <linux/i2c.h> 19#include <linux/i2c.h>
25#include <linux/platform_device.h> 20#include <linux/platform_device.h>
26#include <linux/slab.h> 21#include <linux/slab.h>
27#include <sound/core.h>
28#include <sound/pcm.h> 22#include <sound/pcm.h>
29#include <sound/pcm_params.h> 23#include <sound/pcm_params.h>
30#include <sound/soc.h>
31#include <sound/soc-dapm.h> 24#include <sound/soc-dapm.h>
32#include <sound/tlv.h>
33#include <sound/initval.h> 25#include <sound/initval.h>
34#include <asm/div64.h> 26#include <sound/tlv.h>
35 27
36#include "da7210.h" 28#include "da7210.h"
37 29
@@ -145,6 +137,29 @@
145 137
146#define DA7210_VERSION "0.0.1" 138#define DA7210_VERSION "0.0.1"
147 139
140/*
141 * Playback Volume
142 *
143 * max : 0x3F (+15.0 dB)
144 * (1.5 dB step)
145 * min : 0x11 (-54.0 dB)
146 * mute : 0x10
147 * reserved : 0x00 - 0x0F
148 *
149 * ** FIXME **
150 *
151 * Reserved area are considered as "mute".
152 * -> min = -79.5 dB
153 */
154static const DECLARE_TLV_DB_SCALE(hp_out_tlv, -7950, 150, 1);
155
156static const struct snd_kcontrol_new da7210_snd_controls[] = {
157
158 SOC_DOUBLE_R_TLV("HeadPhone Playback Volume",
159 DA7210_HP_L_VOL, DA7210_HP_R_VOL,
160 0, 0x3F, 0, hp_out_tlv),
161};
162
148/* Codec private data */ 163/* Codec private data */
149struct da7210_priv { 164struct da7210_priv {
150 struct snd_soc_codec codec; 165 struct snd_soc_codec codec;
@@ -227,10 +242,6 @@ static int da7210_startup(struct snd_pcm_substream *substream,
227 struct snd_soc_codec *codec = dai->codec; 242 struct snd_soc_codec *codec = dai->codec;
228 243
229 if (is_play) { 244 if (is_play) {
230 /* PlayBack Volume 40 */
231 snd_soc_update_bits(codec, DA7210_HP_L_VOL, 0x3F, 40);
232 snd_soc_update_bits(codec, DA7210_HP_R_VOL, 0x3F, 40);
233
234 /* Enable Out */ 245 /* Enable Out */
235 snd_soc_update_bits(codec, DA7210_OUTMIX_L, 0x1F, 0x10); 246 snd_soc_update_bits(codec, DA7210_OUTMIX_L, 0x1F, 0x10);
236 snd_soc_update_bits(codec, DA7210_OUTMIX_R, 0x1F, 0x10); 247 snd_soc_update_bits(codec, DA7210_OUTMIX_R, 0x1F, 0x10);
@@ -488,7 +499,7 @@ static int da7210_init(struct da7210_priv *da7210)
488 ret = snd_soc_register_dai(&da7210_dai); 499 ret = snd_soc_register_dai(&da7210_dai);
489 if (ret) { 500 if (ret) {
490 dev_err(codec->dev, "Failed to register DAI: %d\n", ret); 501 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
491 goto init_err; 502 goto codec_err;
492 } 503 }
493 504
494 /* FIXME 505 /* FIXME
@@ -574,6 +585,8 @@ static int da7210_init(struct da7210_priv *da7210)
574 585
575 return ret; 586 return ret;
576 587
588codec_err:
589 snd_soc_unregister_codec(codec);
577init_err: 590init_err:
578 kfree(codec->reg_cache); 591 kfree(codec->reg_cache);
579 codec->reg_cache = NULL; 592 codec->reg_cache = NULL;
@@ -601,8 +614,10 @@ static int __devinit da7210_i2c_probe(struct i2c_client *i2c,
601 codec->control_data = i2c; 614 codec->control_data = i2c;
602 615
603 ret = da7210_init(da7210); 616 ret = da7210_init(da7210);
604 if (ret < 0) 617 if (ret < 0) {
605 pr_err("Failed to initialise da7210 audio codec\n"); 618 pr_err("Failed to initialise da7210 audio codec\n");
619 kfree(da7210);
620 }
606 621
607 return ret; 622 return ret;
608} 623}
@@ -656,6 +671,9 @@ static int da7210_probe(struct platform_device *pdev)
656 if (ret < 0) 671 if (ret < 0)
657 goto pcm_err; 672 goto pcm_err;
658 673
674 snd_soc_add_controls(da7210_codec, da7210_snd_controls,
675 ARRAY_SIZE(da7210_snd_controls));
676
659 dev_info(&pdev->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION); 677 dev_info(&pdev->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION);
660 678
661pcm_err: 679pcm_err:
diff --git a/sound/soc/codecs/jz4740.c b/sound/soc/codecs/jz4740.c
new file mode 100644
index 00000000000..66557de1e4f
--- /dev/null
+++ b/sound/soc/codecs/jz4740.c
@@ -0,0 +1,511 @@
1/*
2 * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
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 * You should have received a copy of the GNU General Public License along
9 * with this program; if not, write to the Free Software Foundation, Inc.,
10 * 675 Mass Ave, Cambridge, MA 02139, USA.
11 *
12 */
13
14#include <linux/kernel.h>
15#include <linux/module.h>
16#include <linux/platform_device.h>
17#include <linux/slab.h>
18
19#include <linux/delay.h>
20
21#include <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/pcm_params.h>
24#include <sound/initval.h>
25#include <sound/soc-dapm.h>
26#include <sound/soc.h>
27
28#define JZ4740_REG_CODEC_1 0x0
29#define JZ4740_REG_CODEC_2 0x1
30
31#define JZ4740_CODEC_1_LINE_ENABLE BIT(29)
32#define JZ4740_CODEC_1_MIC_ENABLE BIT(28)
33#define JZ4740_CODEC_1_SW1_ENABLE BIT(27)
34#define JZ4740_CODEC_1_ADC_ENABLE BIT(26)
35#define JZ4740_CODEC_1_SW2_ENABLE BIT(25)
36#define JZ4740_CODEC_1_DAC_ENABLE BIT(24)
37#define JZ4740_CODEC_1_VREF_DISABLE BIT(20)
38#define JZ4740_CODEC_1_VREF_AMP_DISABLE BIT(19)
39#define JZ4740_CODEC_1_VREF_PULLDOWN BIT(18)
40#define JZ4740_CODEC_1_VREF_LOW_CURRENT BIT(17)
41#define JZ4740_CODEC_1_VREF_HIGH_CURRENT BIT(16)
42#define JZ4740_CODEC_1_HEADPHONE_DISABLE BIT(14)
43#define JZ4740_CODEC_1_HEADPHONE_AMP_CHANGE_ANY BIT(13)
44#define JZ4740_CODEC_1_HEADPHONE_CHARGE BIT(12)
45#define JZ4740_CODEC_1_HEADPHONE_PULLDOWN (BIT(11) | BIT(10))
46#define JZ4740_CODEC_1_HEADPHONE_POWERDOWN_M BIT(9)
47#define JZ4740_CODEC_1_HEADPHONE_POWERDOWN BIT(8)
48#define JZ4740_CODEC_1_SUSPEND BIT(1)
49#define JZ4740_CODEC_1_RESET BIT(0)
50
51#define JZ4740_CODEC_1_LINE_ENABLE_OFFSET 29
52#define JZ4740_CODEC_1_MIC_ENABLE_OFFSET 28
53#define JZ4740_CODEC_1_SW1_ENABLE_OFFSET 27
54#define JZ4740_CODEC_1_ADC_ENABLE_OFFSET 26
55#define JZ4740_CODEC_1_SW2_ENABLE_OFFSET 25
56#define JZ4740_CODEC_1_DAC_ENABLE_OFFSET 24
57#define JZ4740_CODEC_1_HEADPHONE_DISABLE_OFFSET 14
58#define JZ4740_CODEC_1_HEADPHONE_POWERDOWN_OFFSET 8
59
60#define JZ4740_CODEC_2_INPUT_VOLUME_MASK 0x1f0000
61#define JZ4740_CODEC_2_SAMPLE_RATE_MASK 0x000f00
62#define JZ4740_CODEC_2_MIC_BOOST_GAIN_MASK 0x000030
63#define JZ4740_CODEC_2_HEADPHONE_VOLUME_MASK 0x000003
64
65#define JZ4740_CODEC_2_INPUT_VOLUME_OFFSET 16
66#define JZ4740_CODEC_2_SAMPLE_RATE_OFFSET 8
67#define JZ4740_CODEC_2_MIC_BOOST_GAIN_OFFSET 4
68#define JZ4740_CODEC_2_HEADPHONE_VOLUME_OFFSET 0
69
70static const uint32_t jz4740_codec_regs[] = {
71 0x021b2302, 0x00170803,
72};
73
74struct jz4740_codec {
75 void __iomem *base;
76 struct resource *mem;
77
78 uint32_t reg_cache[2];
79 struct snd_soc_codec codec;
80};
81
82static inline struct jz4740_codec *codec_to_jz4740(struct snd_soc_codec *codec)
83{
84 return container_of(codec, struct jz4740_codec, codec);
85}
86
87static unsigned int jz4740_codec_read(struct snd_soc_codec *codec,
88 unsigned int reg)
89{
90 struct jz4740_codec *jz4740_codec = codec_to_jz4740(codec);
91 return readl(jz4740_codec->base + (reg << 2));
92}
93
94static int jz4740_codec_write(struct snd_soc_codec *codec, unsigned int reg,
95 unsigned int val)
96{
97 struct jz4740_codec *jz4740_codec = codec_to_jz4740(codec);
98
99 jz4740_codec->reg_cache[reg] = val;
100 writel(val, jz4740_codec->base + (reg << 2));
101
102 return 0;
103}
104
105static const struct snd_kcontrol_new jz4740_codec_controls[] = {
106 SOC_SINGLE("Master Playback Volume", JZ4740_REG_CODEC_2,
107 JZ4740_CODEC_2_HEADPHONE_VOLUME_OFFSET, 3, 0),
108 SOC_SINGLE("Master Capture Volume", JZ4740_REG_CODEC_2,
109 JZ4740_CODEC_2_INPUT_VOLUME_OFFSET, 31, 0),
110 SOC_SINGLE("Master Playback Switch", JZ4740_REG_CODEC_1,
111 JZ4740_CODEC_1_HEADPHONE_DISABLE_OFFSET, 1, 1),
112 SOC_SINGLE("Mic Capture Volume", JZ4740_REG_CODEC_2,
113 JZ4740_CODEC_2_MIC_BOOST_GAIN_OFFSET, 3, 0),
114};
115
116static const struct snd_kcontrol_new jz4740_codec_output_controls[] = {
117 SOC_DAPM_SINGLE("Bypass Switch", JZ4740_REG_CODEC_1,
118 JZ4740_CODEC_1_SW1_ENABLE_OFFSET, 1, 0),
119 SOC_DAPM_SINGLE("DAC Switch", JZ4740_REG_CODEC_1,
120 JZ4740_CODEC_1_SW2_ENABLE_OFFSET, 1, 0),
121};
122
123static const struct snd_kcontrol_new jz4740_codec_input_controls[] = {
124 SOC_DAPM_SINGLE("Line Capture Switch", JZ4740_REG_CODEC_1,
125 JZ4740_CODEC_1_LINE_ENABLE_OFFSET, 1, 0),
126 SOC_DAPM_SINGLE("Mic Capture Switch", JZ4740_REG_CODEC_1,
127 JZ4740_CODEC_1_MIC_ENABLE_OFFSET, 1, 0),
128};
129
130static const struct snd_soc_dapm_widget jz4740_codec_dapm_widgets[] = {
131 SND_SOC_DAPM_ADC("ADC", "Capture", JZ4740_REG_CODEC_1,
132 JZ4740_CODEC_1_ADC_ENABLE_OFFSET, 0),
133 SND_SOC_DAPM_DAC("DAC", "Playback", JZ4740_REG_CODEC_1,
134 JZ4740_CODEC_1_DAC_ENABLE_OFFSET, 0),
135
136 SND_SOC_DAPM_MIXER("Output Mixer", JZ4740_REG_CODEC_1,
137 JZ4740_CODEC_1_HEADPHONE_POWERDOWN_OFFSET, 1,
138 jz4740_codec_output_controls,
139 ARRAY_SIZE(jz4740_codec_output_controls)),
140
141 SND_SOC_DAPM_MIXER_NAMED_CTL("Input Mixer", SND_SOC_NOPM, 0, 0,
142 jz4740_codec_input_controls,
143 ARRAY_SIZE(jz4740_codec_input_controls)),
144 SND_SOC_DAPM_MIXER("Line Input", SND_SOC_NOPM, 0, 0, NULL, 0),
145
146 SND_SOC_DAPM_OUTPUT("LOUT"),
147 SND_SOC_DAPM_OUTPUT("ROUT"),
148
149 SND_SOC_DAPM_INPUT("MIC"),
150 SND_SOC_DAPM_INPUT("LIN"),
151 SND_SOC_DAPM_INPUT("RIN"),
152};
153
154static const struct snd_soc_dapm_route jz4740_codec_dapm_routes[] = {
155 {"Line Input", NULL, "LIN"},
156 {"Line Input", NULL, "RIN"},
157
158 {"Input Mixer", "Line Capture Switch", "Line Input"},
159 {"Input Mixer", "Mic Capture Switch", "MIC"},
160
161 {"ADC", NULL, "Input Mixer"},
162
163 {"Output Mixer", "Bypass Switch", "Input Mixer"},
164 {"Output Mixer", "DAC Switch", "DAC"},
165
166 {"LOUT", NULL, "Output Mixer"},
167 {"ROUT", NULL, "Output Mixer"},
168};
169
170static int jz4740_codec_hw_params(struct snd_pcm_substream *substream,
171 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
172{
173 uint32_t val;
174 struct snd_soc_pcm_runtime *rtd = substream->private_data;
175 struct snd_soc_device *socdev = rtd->socdev;
176 struct snd_soc_codec *codec = socdev->card->codec;
177
178 switch (params_rate(params)) {
179 case 8000:
180 val = 0;
181 break;
182 case 11025:
183 val = 1;
184 break;
185 case 12000:
186 val = 2;
187 break;
188 case 16000:
189 val = 3;
190 break;
191 case 22050:
192 val = 4;
193 break;
194 case 24000:
195 val = 5;
196 break;
197 case 32000:
198 val = 6;
199 break;
200 case 44100:
201 val = 7;
202 break;
203 case 48000:
204 val = 8;
205 break;
206 default:
207 return -EINVAL;
208 }
209
210 val <<= JZ4740_CODEC_2_SAMPLE_RATE_OFFSET;
211
212 snd_soc_update_bits(codec, JZ4740_REG_CODEC_2,
213 JZ4740_CODEC_2_SAMPLE_RATE_MASK, val);
214
215 return 0;
216}
217
218static struct snd_soc_dai_ops jz4740_codec_dai_ops = {
219 .hw_params = jz4740_codec_hw_params,
220};
221
222struct snd_soc_dai jz4740_codec_dai = {
223 .name = "jz4740",
224 .playback = {
225 .stream_name = "Playback",
226 .channels_min = 2,
227 .channels_max = 2,
228 .rates = SNDRV_PCM_RATE_8000_48000,
229 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8,
230 },
231 .capture = {
232 .stream_name = "Capture",
233 .channels_min = 2,
234 .channels_max = 2,
235 .rates = SNDRV_PCM_RATE_8000_48000,
236 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8,
237 },
238 .ops = &jz4740_codec_dai_ops,
239 .symmetric_rates = 1,
240};
241EXPORT_SYMBOL_GPL(jz4740_codec_dai);
242
243static void jz4740_codec_wakeup(struct snd_soc_codec *codec)
244{
245 int i;
246 uint32_t *cache = codec->reg_cache;
247
248 snd_soc_update_bits(codec, JZ4740_REG_CODEC_1,
249 JZ4740_CODEC_1_RESET, JZ4740_CODEC_1_RESET);
250 udelay(2);
251
252 snd_soc_update_bits(codec, JZ4740_REG_CODEC_1,
253 JZ4740_CODEC_1_SUSPEND | JZ4740_CODEC_1_RESET, 0);
254
255 for (i = 0; i < ARRAY_SIZE(jz4740_codec_regs); ++i)
256 jz4740_codec_write(codec, i, cache[i]);
257}
258
259static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec,
260 enum snd_soc_bias_level level)
261{
262 unsigned int mask;
263 unsigned int value;
264
265 switch (level) {
266 case SND_SOC_BIAS_ON:
267 break;
268 case SND_SOC_BIAS_PREPARE:
269 mask = JZ4740_CODEC_1_VREF_DISABLE |
270 JZ4740_CODEC_1_VREF_AMP_DISABLE |
271 JZ4740_CODEC_1_HEADPHONE_POWERDOWN_M;
272 value = 0;
273
274 snd_soc_update_bits(codec, JZ4740_REG_CODEC_1, mask, value);
275 break;
276 case SND_SOC_BIAS_STANDBY:
277 /* The only way to clear the suspend flag is to reset the codec */
278 if (codec->bias_level == SND_SOC_BIAS_OFF)
279 jz4740_codec_wakeup(codec);
280
281 mask = JZ4740_CODEC_1_VREF_DISABLE |
282 JZ4740_CODEC_1_VREF_AMP_DISABLE |
283 JZ4740_CODEC_1_HEADPHONE_POWERDOWN_M;
284 value = JZ4740_CODEC_1_VREF_DISABLE |
285 JZ4740_CODEC_1_VREF_AMP_DISABLE |
286 JZ4740_CODEC_1_HEADPHONE_POWERDOWN_M;
287
288 snd_soc_update_bits(codec, JZ4740_REG_CODEC_1, mask, value);
289 break;
290 case SND_SOC_BIAS_OFF:
291 mask = JZ4740_CODEC_1_SUSPEND;
292 value = JZ4740_CODEC_1_SUSPEND;
293
294 snd_soc_update_bits(codec, JZ4740_REG_CODEC_1, mask, value);
295 break;
296 default:
297 break;
298 }
299
300 codec->bias_level = level;
301
302 return 0;
303}
304
305static struct snd_soc_codec *jz4740_codec_codec;
306
307static int jz4740_codec_dev_probe(struct platform_device *pdev)
308{
309 int ret;
310 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
311 struct snd_soc_codec *codec = jz4740_codec_codec;
312
313 BUG_ON(!codec);
314
315 socdev->card->codec = codec;
316
317 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
318 if (ret) {
319 dev_err(&pdev->dev, "Failed to create pcms: %d\n", ret);
320 return ret;
321 }
322
323 snd_soc_add_controls(codec, jz4740_codec_controls,
324 ARRAY_SIZE(jz4740_codec_controls));
325
326 snd_soc_dapm_new_controls(codec, jz4740_codec_dapm_widgets,
327 ARRAY_SIZE(jz4740_codec_dapm_widgets));
328
329 snd_soc_dapm_add_routes(codec, jz4740_codec_dapm_routes,
330 ARRAY_SIZE(jz4740_codec_dapm_routes));
331
332 snd_soc_dapm_new_widgets(codec);
333
334 return 0;
335}
336
337static int jz4740_codec_dev_remove(struct platform_device *pdev)
338{
339 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
340
341 snd_soc_free_pcms(socdev);
342 snd_soc_dapm_free(socdev);
343
344 return 0;
345}
346
347#ifdef CONFIG_PM_SLEEP
348
349static int jz4740_codec_suspend(struct platform_device *pdev, pm_message_t state)
350{
351 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
352 struct snd_soc_codec *codec = socdev->card->codec;
353
354 return jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_OFF);
355}
356
357static int jz4740_codec_resume(struct platform_device *pdev)
358{
359 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
360 struct snd_soc_codec *codec = socdev->card->codec;
361
362 return jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
363}
364
365#else
366#define jz4740_codec_suspend NULL
367#define jz4740_codec_resume NULL
368#endif
369
370struct snd_soc_codec_device soc_codec_dev_jz4740_codec = {
371 .probe = jz4740_codec_dev_probe,
372 .remove = jz4740_codec_dev_remove,
373 .suspend = jz4740_codec_suspend,
374 .resume = jz4740_codec_resume,
375};
376EXPORT_SYMBOL_GPL(soc_codec_dev_jz4740_codec);
377
378static int __devinit jz4740_codec_probe(struct platform_device *pdev)
379{
380 int ret;
381 struct jz4740_codec *jz4740_codec;
382 struct snd_soc_codec *codec;
383 struct resource *mem;
384
385 jz4740_codec = kzalloc(sizeof(*jz4740_codec), GFP_KERNEL);
386 if (!jz4740_codec)
387 return -ENOMEM;
388
389 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
390 if (!mem) {
391 dev_err(&pdev->dev, "Failed to get mmio memory resource\n");
392 ret = -ENOENT;
393 goto err_free_codec;
394 }
395
396 mem = request_mem_region(mem->start, resource_size(mem), pdev->name);
397 if (!mem) {
398 dev_err(&pdev->dev, "Failed to request mmio memory region\n");
399 ret = -EBUSY;
400 goto err_free_codec;
401 }
402
403 jz4740_codec->base = ioremap(mem->start, resource_size(mem));
404 if (!jz4740_codec->base) {
405 dev_err(&pdev->dev, "Failed to ioremap mmio memory\n");
406 ret = -EBUSY;
407 goto err_release_mem_region;
408 }
409 jz4740_codec->mem = mem;
410
411 jz4740_codec_dai.dev = &pdev->dev;
412
413 codec = &jz4740_codec->codec;
414
415 codec->dev = &pdev->dev;
416 codec->name = "jz4740";
417 codec->owner = THIS_MODULE;
418
419 codec->read = jz4740_codec_read;
420 codec->write = jz4740_codec_write;
421 codec->set_bias_level = jz4740_codec_set_bias_level;
422 codec->bias_level = SND_SOC_BIAS_OFF;
423
424 codec->dai = &jz4740_codec_dai;
425 codec->num_dai = 1;
426
427 codec->reg_cache = jz4740_codec->reg_cache;
428 codec->reg_cache_size = 2;
429 memcpy(codec->reg_cache, jz4740_codec_regs, sizeof(jz4740_codec_regs));
430
431 mutex_init(&codec->mutex);
432 INIT_LIST_HEAD(&codec->dapm_widgets);
433 INIT_LIST_HEAD(&codec->dapm_paths);
434
435 jz4740_codec_codec = codec;
436
437 snd_soc_update_bits(codec, JZ4740_REG_CODEC_1,
438 JZ4740_CODEC_1_SW2_ENABLE, JZ4740_CODEC_1_SW2_ENABLE);
439
440 platform_set_drvdata(pdev, jz4740_codec);
441
442 ret = snd_soc_register_codec(codec);
443 if (ret) {
444 dev_err(&pdev->dev, "Failed to register codec\n");
445 goto err_iounmap;
446 }
447
448 ret = snd_soc_register_dai(&jz4740_codec_dai);
449 if (ret) {
450 dev_err(&pdev->dev, "Failed to register codec dai\n");
451 goto err_unregister_codec;
452 }
453
454 jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
455
456 return 0;
457
458err_unregister_codec:
459 snd_soc_unregister_codec(codec);
460err_iounmap:
461 iounmap(jz4740_codec->base);
462err_release_mem_region:
463 release_mem_region(mem->start, resource_size(mem));
464err_free_codec:
465 kfree(jz4740_codec);
466
467 return ret;
468}
469
470static int __devexit jz4740_codec_remove(struct platform_device *pdev)
471{
472 struct jz4740_codec *jz4740_codec = platform_get_drvdata(pdev);
473 struct resource *mem = jz4740_codec->mem;
474
475 snd_soc_unregister_dai(&jz4740_codec_dai);
476 snd_soc_unregister_codec(&jz4740_codec->codec);
477
478 iounmap(jz4740_codec->base);
479 release_mem_region(mem->start, resource_size(mem));
480
481 platform_set_drvdata(pdev, NULL);
482 kfree(jz4740_codec);
483
484 return 0;
485}
486
487static struct platform_driver jz4740_codec_driver = {
488 .probe = jz4740_codec_probe,
489 .remove = __devexit_p(jz4740_codec_remove),
490 .driver = {
491 .name = "jz4740-codec",
492 .owner = THIS_MODULE,
493 },
494};
495
496static int __init jz4740_codec_init(void)
497{
498 return platform_driver_register(&jz4740_codec_driver);
499}
500module_init(jz4740_codec_init);
501
502static void __exit jz4740_codec_exit(void)
503{
504 platform_driver_unregister(&jz4740_codec_driver);
505}
506module_exit(jz4740_codec_exit);
507
508MODULE_DESCRIPTION("JZ4740 SoC internal codec driver");
509MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
510MODULE_LICENSE("GPL v2");
511MODULE_ALIAS("platform:jz4740-codec");
diff --git a/sound/soc/codecs/jz4740.h b/sound/soc/codecs/jz4740.h
new file mode 100644
index 00000000000..b5a0691be76
--- /dev/null
+++ b/sound/soc/codecs/jz4740.h
@@ -0,0 +1,20 @@
1/*
2 * Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de>
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 * You should have received a copy of the GNU General Public License along
9 * with this program; if not, write to the Free Software Foundation, Inc.,
10 * 675 Mass Ave, Cambridge, MA 02139, USA.
11 *
12 */
13
14#ifndef __SND_SOC_CODECS_JZ4740_CODEC_H__
15#define __SND_SOC_CODECS_JZ4740_CODEC_H__
16
17extern struct snd_soc_dai jz4740_codec_dai;
18extern struct snd_soc_codec_device soc_codec_dev_jz4740_codec;
19
20#endif
diff --git a/sound/soc/codecs/spdif_transciever.c b/sound/soc/codecs/spdif_transciever.c
index a6319114105..9119836051a 100644
--- a/sound/soc/codecs/spdif_transciever.c
+++ b/sound/soc/codecs/spdif_transciever.c
@@ -16,8 +16,10 @@
16 16
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/moduleparam.h> 18#include <linux/moduleparam.h>
19#include <linux/slab.h>
19#include <sound/soc.h> 20#include <sound/soc.h>
20#include <sound/pcm.h> 21#include <sound/pcm.h>
22#include <sound/initval.h>
21 23
22#include "spdif_transciever.h" 24#include "spdif_transciever.h"
23 25
@@ -26,6 +28,48 @@ MODULE_LICENSE("GPL");
26#define STUB_RATES SNDRV_PCM_RATE_8000_96000 28#define STUB_RATES SNDRV_PCM_RATE_8000_96000
27#define STUB_FORMATS SNDRV_PCM_FMTBIT_S16_LE 29#define STUB_FORMATS SNDRV_PCM_FMTBIT_S16_LE
28 30
31static struct snd_soc_codec *spdif_dit_codec;
32
33static int spdif_dit_codec_probe(struct platform_device *pdev)
34{
35 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
36 struct snd_soc_codec *codec;
37 int ret;
38
39 if (spdif_dit_codec == NULL) {
40 dev_err(&pdev->dev, "Codec device not registered\n");
41 return -ENODEV;
42 }
43
44 socdev->card->codec = spdif_dit_codec;
45 codec = spdif_dit_codec;
46
47 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
48 if (ret < 0) {
49 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
50 goto err_create_pcms;
51 }
52
53 return 0;
54
55err_create_pcms:
56 return ret;
57}
58
59static int spdif_dit_codec_remove(struct platform_device *pdev)
60{
61 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
62
63 snd_soc_free_pcms(socdev);
64
65 return 0;
66}
67
68struct snd_soc_codec_device soc_codec_dev_spdif_dit = {
69 .probe = spdif_dit_codec_probe,
70 .remove = spdif_dit_codec_remove,
71}; EXPORT_SYMBOL_GPL(soc_codec_dev_spdif_dit);
72
29struct snd_soc_dai dit_stub_dai = { 73struct snd_soc_dai dit_stub_dai = {
30 .name = "DIT", 74 .name = "DIT",
31 .playback = { 75 .playback = {
@@ -40,13 +84,61 @@ EXPORT_SYMBOL_GPL(dit_stub_dai);
40 84
41static int spdif_dit_probe(struct platform_device *pdev) 85static int spdif_dit_probe(struct platform_device *pdev)
42{ 86{
87 struct snd_soc_codec *codec;
88 int ret;
89
90 if (spdif_dit_codec) {
91 dev_err(&pdev->dev, "Another Codec is registered\n");
92 ret = -EINVAL;
93 goto err_reg_codec;
94 }
95
96 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
97 if (codec == NULL)
98 return -ENOMEM;
99
100 codec->dev = &pdev->dev;
101
102 mutex_init(&codec->mutex);
103
104 INIT_LIST_HEAD(&codec->dapm_widgets);
105 INIT_LIST_HEAD(&codec->dapm_paths);
106
107 codec->name = "spdif-dit";
108 codec->owner = THIS_MODULE;
109 codec->dai = &dit_stub_dai;
110 codec->num_dai = 1;
111
112 spdif_dit_codec = codec;
113
114 ret = snd_soc_register_codec(codec);
115 if (ret < 0) {
116 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
117 goto err_reg_codec;
118 }
119
43 dit_stub_dai.dev = &pdev->dev; 120 dit_stub_dai.dev = &pdev->dev;
44 return snd_soc_register_dai(&dit_stub_dai); 121 ret = snd_soc_register_dai(&dit_stub_dai);
122 if (ret < 0) {
123 dev_err(codec->dev, "Failed to register dai: %d\n", ret);
124 goto err_reg_dai;
125 }
126
127 return 0;
128
129err_reg_dai:
130 snd_soc_unregister_codec(codec);
131err_reg_codec:
132 kfree(spdif_dit_codec);
133 return ret;
45} 134}
46 135
47static int spdif_dit_remove(struct platform_device *pdev) 136static int spdif_dit_remove(struct platform_device *pdev)
48{ 137{
49 snd_soc_unregister_dai(&dit_stub_dai); 138 snd_soc_unregister_dai(&dit_stub_dai);
139 snd_soc_unregister_codec(spdif_dit_codec);
140 kfree(spdif_dit_codec);
141 spdif_dit_codec = NULL;
50 return 0; 142 return 0;
51} 143}
52 144
diff --git a/sound/soc/codecs/spdif_transciever.h b/sound/soc/codecs/spdif_transciever.h
index 296f2eb6c4e..1e102124f54 100644
--- a/sound/soc/codecs/spdif_transciever.h
+++ b/sound/soc/codecs/spdif_transciever.h
@@ -12,6 +12,7 @@
12#ifndef CODEC_STUBS_H 12#ifndef CODEC_STUBS_H
13#define CODEC_STUBS_H 13#define CODEC_STUBS_H
14 14
15extern struct snd_soc_codec_device soc_codec_dev_spdif_dit;
15extern struct snd_soc_dai dit_stub_dai; 16extern struct snd_soc_dai dit_stub_dai;
16 17
17#endif /* CODEC_STUBS_H */ 18#endif /* CODEC_STUBS_H */
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index b0bae3508b2..0a4b0fef335 100644
--- a/sound/soc/codecs/tlv320aic23.c
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -560,13 +560,16 @@ static int tlv320aic23_set_bias_level(struct snd_soc_codec *codec,
560 switch (level) { 560 switch (level) {
561 case SND_SOC_BIAS_ON: 561 case SND_SOC_BIAS_ON:
562 /* vref/mid, osc on, dac unmute */ 562 /* vref/mid, osc on, dac unmute */
563 reg &= ~(TLV320AIC23_DEVICE_PWR_OFF | TLV320AIC23_OSC_OFF | \
564 TLV320AIC23_DAC_OFF);
563 tlv320aic23_write(codec, TLV320AIC23_PWR, reg); 565 tlv320aic23_write(codec, TLV320AIC23_PWR, reg);
564 break; 566 break;
565 case SND_SOC_BIAS_PREPARE: 567 case SND_SOC_BIAS_PREPARE:
566 break; 568 break;
567 case SND_SOC_BIAS_STANDBY: 569 case SND_SOC_BIAS_STANDBY:
568 /* everything off except vref/vmid, */ 570 /* everything off except vref/vmid, */
569 tlv320aic23_write(codec, TLV320AIC23_PWR, reg | 0x0040); 571 tlv320aic23_write(codec, TLV320AIC23_PWR, reg | \
572 TLV320AIC23_CLK_OFF);
570 break; 573 break;
571 case SND_SOC_BIAS_OFF: 574 case SND_SOC_BIAS_OFF:
572 /* everything off, dac mute, inactive */ 575 /* everything off, dac mute, inactive */
@@ -615,7 +618,6 @@ static int tlv320aic23_suspend(struct platform_device *pdev,
615 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 618 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
616 struct snd_soc_codec *codec = socdev->card->codec; 619 struct snd_soc_codec *codec = socdev->card->codec;
617 620
618 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0);
619 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_OFF); 621 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_OFF);
620 622
621 return 0; 623 return 0;
@@ -632,7 +634,6 @@ static int tlv320aic23_resume(struct platform_device *pdev)
632 u16 val = tlv320aic23_read_reg_cache(codec, reg); 634 u16 val = tlv320aic23_read_reg_cache(codec, reg);
633 tlv320aic23_write(codec, reg, val); 635 tlv320aic23_write(codec, reg, val);
634 } 636 }
635
636 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 637 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
637 638
638 return 0; 639 return 0;
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
index 65adc77eada..8651b01ed22 100644
--- a/sound/soc/codecs/tlv320dac33.c
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -49,8 +49,6 @@
49 49
50#define NSAMPLE_MAX 5700 50#define NSAMPLE_MAX 5700
51 51
52#define LATENCY_TIME_MS 20
53
54#define MODE7_LTHR 10 52#define MODE7_LTHR 10
55#define MODE7_UTHR (DAC33_BUFFER_SIZE_SAMPLES - 10) 53#define MODE7_UTHR (DAC33_BUFFER_SIZE_SAMPLES - 10)
56 54
@@ -62,6 +60,9 @@
62#define US_TO_SAMPLES(rate, us) \ 60#define US_TO_SAMPLES(rate, us) \
63 (rate / (1000000 / us)) 61 (rate / (1000000 / us))
64 62
63#define UTHR_FROM_PERIOD_SIZE(samples, playrate, burstrate) \
64 ((samples * 5000) / ((burstrate * 5000) / (burstrate - playrate)))
65
65static void dac33_calculate_times(struct snd_pcm_substream *substream); 66static void dac33_calculate_times(struct snd_pcm_substream *substream);
66static int dac33_prepare_chip(struct snd_pcm_substream *substream); 67static int dac33_prepare_chip(struct snd_pcm_substream *substream);
67 68
@@ -107,6 +108,10 @@ struct tlv320dac33_priv {
107 * this */ 108 * this */
108 enum dac33_fifo_modes fifo_mode;/* FIFO mode selection */ 109 enum dac33_fifo_modes fifo_mode;/* FIFO mode selection */
109 unsigned int nsample; /* burst read amount from host */ 110 unsigned int nsample; /* burst read amount from host */
111 int mode1_latency; /* latency caused by the i2c writes in
112 * us */
113 int auto_fifo_config; /* Configure the FIFO based on the
114 * period size */
110 u8 burst_bclkdiv; /* BCLK divider value in burst mode */ 115 u8 burst_bclkdiv; /* BCLK divider value in burst mode */
111 unsigned int burst_rate; /* Interface speed in Burst modes */ 116 unsigned int burst_rate; /* Interface speed in Burst modes */
112 117
@@ -120,6 +125,8 @@ struct tlv320dac33_priv {
120 * samples */ 125 * samples */
121 unsigned int mode7_us_to_lthr; /* Time to reach lthr from uthr */ 126 unsigned int mode7_us_to_lthr; /* Time to reach lthr from uthr */
122 127
128 unsigned int uthr;
129
123 enum dac33_state state; 130 enum dac33_state state;
124}; 131};
125 132
@@ -442,6 +449,39 @@ static int dac33_set_nsample(struct snd_kcontrol *kcontrol,
442 return ret; 449 return ret;
443} 450}
444 451
452static int dac33_get_uthr(struct snd_kcontrol *kcontrol,
453 struct snd_ctl_elem_value *ucontrol)
454{
455 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
456 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
457
458 ucontrol->value.integer.value[0] = dac33->uthr;
459
460 return 0;
461}
462
463static int dac33_set_uthr(struct snd_kcontrol *kcontrol,
464 struct snd_ctl_elem_value *ucontrol)
465{
466 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
467 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
468 int ret = 0;
469
470 if (dac33->substream)
471 return -EBUSY;
472
473 if (dac33->uthr == ucontrol->value.integer.value[0])
474 return 0;
475
476 if (ucontrol->value.integer.value[0] < (MODE7_LTHR + 10) ||
477 ucontrol->value.integer.value[0] > MODE7_UTHR)
478 ret = -EINVAL;
479 else
480 dac33->uthr = ucontrol->value.integer.value[0];
481
482 return ret;
483}
484
445static int dac33_get_fifo_mode(struct snd_kcontrol *kcontrol, 485static int dac33_get_fifo_mode(struct snd_kcontrol *kcontrol,
446 struct snd_ctl_elem_value *ucontrol) 486 struct snd_ctl_elem_value *ucontrol)
447{ 487{
@@ -503,13 +543,18 @@ static const struct snd_kcontrol_new dac33_snd_controls[] = {
503 DAC33_LINEL_TO_LLO_VOL, DAC33_LINER_TO_RLO_VOL, 0, 127, 1), 543 DAC33_LINEL_TO_LLO_VOL, DAC33_LINER_TO_RLO_VOL, 0, 127, 1),
504}; 544};
505 545
506static const struct snd_kcontrol_new dac33_nsample_snd_controls[] = { 546static const struct snd_kcontrol_new dac33_mode_snd_controls[] = {
507 SOC_SINGLE_EXT("nSample", 0, 0, 5900, 0,
508 dac33_get_nsample, dac33_set_nsample),
509 SOC_ENUM_EXT("FIFO Mode", dac33_fifo_mode_enum, 547 SOC_ENUM_EXT("FIFO Mode", dac33_fifo_mode_enum,
510 dac33_get_fifo_mode, dac33_set_fifo_mode), 548 dac33_get_fifo_mode, dac33_set_fifo_mode),
511}; 549};
512 550
551static const struct snd_kcontrol_new dac33_fifo_snd_controls[] = {
552 SOC_SINGLE_EXT("nSample", 0, 0, 5900, 0,
553 dac33_get_nsample, dac33_set_nsample),
554 SOC_SINGLE_EXT("UTHR", 0, 0, MODE7_UTHR, 0,
555 dac33_get_uthr, dac33_set_uthr),
556};
557
513/* Analog bypass */ 558/* Analog bypass */
514static const struct snd_kcontrol_new dac33_dapm_abypassl_control = 559static const struct snd_kcontrol_new dac33_dapm_abypassl_control =
515 SOC_DAPM_SINGLE("Switch", DAC33_LINEL_TO_LLO_VOL, 7, 1, 1); 560 SOC_DAPM_SINGLE("Switch", DAC33_LINEL_TO_LLO_VOL, 7, 1, 1);
@@ -612,7 +657,7 @@ static inline void dac33_prefill_handler(struct tlv320dac33_priv *dac33)
612 switch (dac33->fifo_mode) { 657 switch (dac33->fifo_mode) {
613 case DAC33_FIFO_MODE1: 658 case DAC33_FIFO_MODE1:
614 dac33_write16(codec, DAC33_NSAMPLE_MSB, 659 dac33_write16(codec, DAC33_NSAMPLE_MSB,
615 DAC33_THRREG(dac33->nsample + dac33->alarm_threshold)); 660 DAC33_THRREG(dac33->nsample));
616 661
617 /* Take the timestamps */ 662 /* Take the timestamps */
618 spin_lock_irq(&dac33->lock); 663 spin_lock_irq(&dac33->lock);
@@ -761,6 +806,10 @@ static void dac33_shutdown(struct snd_pcm_substream *substream,
761 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); 806 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
762 807
763 dac33->substream = NULL; 808 dac33->substream = NULL;
809
810 /* Reset the nSample restrictions */
811 dac33->nsample_min = 0;
812 dac33->nsample_max = NSAMPLE_MAX;
764} 813}
765 814
766static int dac33_hw_params(struct snd_pcm_substream *substream, 815static int dac33_hw_params(struct snd_pcm_substream *substream,
@@ -985,7 +1034,7 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
985 * Configure the threshold levels, and leave 10 sample space 1034 * Configure the threshold levels, and leave 10 sample space
986 * at the bottom, and also at the top of the FIFO 1035 * at the bottom, and also at the top of the FIFO
987 */ 1036 */
988 dac33_write16(codec, DAC33_UTHR_MSB, DAC33_THRREG(MODE7_UTHR)); 1037 dac33_write16(codec, DAC33_UTHR_MSB, DAC33_THRREG(dac33->uthr));
989 dac33_write16(codec, DAC33_LTHR_MSB, DAC33_THRREG(MODE7_LTHR)); 1038 dac33_write16(codec, DAC33_LTHR_MSB, DAC33_THRREG(MODE7_LTHR));
990 break; 1039 break;
991 default: 1040 default:
@@ -1003,57 +1052,71 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream)
1003 struct snd_soc_device *socdev = rtd->socdev; 1052 struct snd_soc_device *socdev = rtd->socdev;
1004 struct snd_soc_codec *codec = socdev->card->codec; 1053 struct snd_soc_codec *codec = socdev->card->codec;
1005 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); 1054 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
1055 unsigned int period_size = substream->runtime->period_size;
1056 unsigned int rate = substream->runtime->rate;
1006 unsigned int nsample_limit; 1057 unsigned int nsample_limit;
1007 1058
1008 /* In bypass mode we don't need to calculate */ 1059 /* In bypass mode we don't need to calculate */
1009 if (!dac33->fifo_mode) 1060 if (!dac33->fifo_mode)
1010 return; 1061 return;
1011 1062
1012 /* Number of samples (16bit, stereo) in one period */
1013 dac33->nsample_min = snd_pcm_lib_period_bytes(substream) / 4;
1014
1015 /* Number of samples (16bit, stereo) in ALSA buffer */
1016 dac33->nsample_max = snd_pcm_lib_buffer_bytes(substream) / 4;
1017 /* Subtract one period from the total */
1018 dac33->nsample_max -= dac33->nsample_min;
1019
1020 /* Number of samples for LATENCY_TIME_MS / 2 */
1021 dac33->alarm_threshold = substream->runtime->rate /
1022 (1000 / (LATENCY_TIME_MS / 2));
1023
1024 /* Find and fix up the lowest nsmaple limit */
1025 nsample_limit = substream->runtime->rate / (1000 / LATENCY_TIME_MS);
1026
1027 if (dac33->nsample_min < nsample_limit)
1028 dac33->nsample_min = nsample_limit;
1029
1030 if (dac33->nsample < dac33->nsample_min)
1031 dac33->nsample = dac33->nsample_min;
1032
1033 /*
1034 * Find and fix up the highest nsmaple limit
1035 * In order to not overflow the DAC33 buffer substract the
1036 * alarm_threshold value from the size of the DAC33 buffer
1037 */
1038 nsample_limit = DAC33_BUFFER_SIZE_SAMPLES - dac33->alarm_threshold;
1039
1040 if (dac33->nsample_max > nsample_limit)
1041 dac33->nsample_max = nsample_limit;
1042
1043 if (dac33->nsample > dac33->nsample_max)
1044 dac33->nsample = dac33->nsample_max;
1045
1046 switch (dac33->fifo_mode) { 1063 switch (dac33->fifo_mode) {
1047 case DAC33_FIFO_MODE1: 1064 case DAC33_FIFO_MODE1:
1065 /* Number of samples under i2c latency */
1066 dac33->alarm_threshold = US_TO_SAMPLES(rate,
1067 dac33->mode1_latency);
1068 if (dac33->auto_fifo_config) {
1069 if (period_size <= dac33->alarm_threshold)
1070 /*
1071 * Configure nSamaple to number of periods,
1072 * which covers the latency requironment.
1073 */
1074 dac33->nsample = period_size *
1075 ((dac33->alarm_threshold / period_size) +
1076 (dac33->alarm_threshold % period_size ?
1077 1 : 0));
1078 else
1079 dac33->nsample = period_size;
1080 } else {
1081 /* nSample time shall not be shorter than i2c latency */
1082 dac33->nsample_min = dac33->alarm_threshold;
1083 /*
1084 * nSample should not be bigger than alsa buffer minus
1085 * size of one period to avoid overruns
1086 */
1087 dac33->nsample_max = substream->runtime->buffer_size -
1088 period_size;
1089 nsample_limit = DAC33_BUFFER_SIZE_SAMPLES -
1090 dac33->alarm_threshold;
1091 if (dac33->nsample_max > nsample_limit)
1092 dac33->nsample_max = nsample_limit;
1093
1094 /* Correct the nSample if it is outside of the ranges */
1095 if (dac33->nsample < dac33->nsample_min)
1096 dac33->nsample = dac33->nsample_min;
1097 if (dac33->nsample > dac33->nsample_max)
1098 dac33->nsample = dac33->nsample_max;
1099 }
1100
1048 dac33->mode1_us_burst = SAMPLES_TO_US(dac33->burst_rate, 1101 dac33->mode1_us_burst = SAMPLES_TO_US(dac33->burst_rate,
1049 dac33->nsample); 1102 dac33->nsample);
1050 dac33->t_stamp1 = 0; 1103 dac33->t_stamp1 = 0;
1051 dac33->t_stamp2 = 0; 1104 dac33->t_stamp2 = 0;
1052 break; 1105 break;
1053 case DAC33_FIFO_MODE7: 1106 case DAC33_FIFO_MODE7:
1107 if (dac33->auto_fifo_config) {
1108 dac33->uthr = UTHR_FROM_PERIOD_SIZE(
1109 period_size,
1110 rate,
1111 dac33->burst_rate) + 9;
1112 if (dac33->uthr > MODE7_UTHR)
1113 dac33->uthr = MODE7_UTHR;
1114 if (dac33->uthr < (MODE7_LTHR + 10))
1115 dac33->uthr = (MODE7_LTHR + 10);
1116 }
1054 dac33->mode7_us_to_lthr = 1117 dac33->mode7_us_to_lthr =
1055 SAMPLES_TO_US(substream->runtime->rate, 1118 SAMPLES_TO_US(substream->runtime->rate,
1056 MODE7_UTHR - MODE7_LTHR + 1); 1119 dac33->uthr - MODE7_LTHR + 1);
1057 dac33->t_stamp1 = 0; 1120 dac33->t_stamp1 = 0;
1058 break; 1121 break;
1059 default: 1122 default:
@@ -1104,7 +1167,7 @@ static snd_pcm_sframes_t dac33_dai_delay(
1104 struct snd_soc_codec *codec = socdev->card->codec; 1167 struct snd_soc_codec *codec = socdev->card->codec;
1105 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); 1168 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
1106 unsigned long long t0, t1, t_now; 1169 unsigned long long t0, t1, t_now;
1107 unsigned int time_delta; 1170 unsigned int time_delta, uthr;
1108 int samples_out, samples_in, samples; 1171 int samples_out, samples_in, samples;
1109 snd_pcm_sframes_t delay = 0; 1172 snd_pcm_sframes_t delay = 0;
1110 1173
@@ -1182,6 +1245,7 @@ static snd_pcm_sframes_t dac33_dai_delay(
1182 case DAC33_FIFO_MODE7: 1245 case DAC33_FIFO_MODE7:
1183 spin_lock(&dac33->lock); 1246 spin_lock(&dac33->lock);
1184 t0 = dac33->t_stamp1; 1247 t0 = dac33->t_stamp1;
1248 uthr = dac33->uthr;
1185 spin_unlock(&dac33->lock); 1249 spin_unlock(&dac33->lock);
1186 t_now = ktime_to_us(ktime_get()); 1250 t_now = ktime_to_us(ktime_get());
1187 1251
@@ -1194,7 +1258,7 @@ static snd_pcm_sframes_t dac33_dai_delay(
1194 * Either the timestamps are messed or equal. Report 1258 * Either the timestamps are messed or equal. Report
1195 * maximum delay 1259 * maximum delay
1196 */ 1260 */
1197 delay = MODE7_UTHR; 1261 delay = uthr;
1198 goto out; 1262 goto out;
1199 } 1263 }
1200 1264
@@ -1208,8 +1272,8 @@ static snd_pcm_sframes_t dac33_dai_delay(
1208 substream->runtime->rate, 1272 substream->runtime->rate,
1209 time_delta); 1273 time_delta);
1210 1274
1211 if (likely(MODE7_UTHR > samples_out)) 1275 if (likely(uthr > samples_out))
1212 delay = MODE7_UTHR - samples_out; 1276 delay = uthr - samples_out;
1213 else 1277 else
1214 delay = 0; 1278 delay = 0;
1215 } else { 1279 } else {
@@ -1227,8 +1291,8 @@ static snd_pcm_sframes_t dac33_dai_delay(
1227 time_delta); 1291 time_delta);
1228 delay = MODE7_LTHR + samples_in - samples_out; 1292 delay = MODE7_LTHR + samples_in - samples_out;
1229 1293
1230 if (unlikely(delay > MODE7_UTHR)) 1294 if (unlikely(delay > uthr))
1231 delay = MODE7_UTHR; 1295 delay = uthr;
1232 } 1296 }
1233 break; 1297 break;
1234 default: 1298 default:
@@ -1347,10 +1411,15 @@ static int dac33_soc_probe(struct platform_device *pdev)
1347 1411
1348 snd_soc_add_controls(codec, dac33_snd_controls, 1412 snd_soc_add_controls(codec, dac33_snd_controls,
1349 ARRAY_SIZE(dac33_snd_controls)); 1413 ARRAY_SIZE(dac33_snd_controls));
1350 /* Only add the nSample controls, if we have valid IRQ number */ 1414 /* Only add the FIFO controls, if we have valid IRQ number */
1351 if (dac33->irq >= 0) 1415 if (dac33->irq >= 0) {
1352 snd_soc_add_controls(codec, dac33_nsample_snd_controls, 1416 snd_soc_add_controls(codec, dac33_mode_snd_controls,
1353 ARRAY_SIZE(dac33_nsample_snd_controls)); 1417 ARRAY_SIZE(dac33_mode_snd_controls));
1418 /* FIFO usage controls only, if autoio config is not selected */
1419 if (!dac33->auto_fifo_config)
1420 snd_soc_add_controls(codec, dac33_fifo_snd_controls,
1421 ARRAY_SIZE(dac33_fifo_snd_controls));
1422 }
1354 1423
1355 dac33_add_widgets(codec); 1424 dac33_add_widgets(codec);
1356 1425
@@ -1481,9 +1550,14 @@ static int __devinit dac33_i2c_probe(struct i2c_client *client,
1481 /* Pre calculate the burst rate */ 1550 /* Pre calculate the burst rate */
1482 dac33->burst_rate = BURST_BASEFREQ_HZ / dac33->burst_bclkdiv / 32; 1551 dac33->burst_rate = BURST_BASEFREQ_HZ / dac33->burst_bclkdiv / 32;
1483 dac33->keep_bclk = pdata->keep_bclk; 1552 dac33->keep_bclk = pdata->keep_bclk;
1553 dac33->auto_fifo_config = pdata->auto_fifo_config;
1554 dac33->mode1_latency = pdata->mode1_latency;
1555 if (!dac33->mode1_latency)
1556 dac33->mode1_latency = 10000; /* 10ms */
1484 dac33->irq = client->irq; 1557 dac33->irq = client->irq;
1485 dac33->nsample = NSAMPLE_MAX; 1558 dac33->nsample = NSAMPLE_MAX;
1486 dac33->nsample_max = NSAMPLE_MAX; 1559 dac33->nsample_max = NSAMPLE_MAX;
1560 dac33->uthr = MODE7_UTHR;
1487 /* Disable FIFO use by default */ 1561 /* Disable FIFO use by default */
1488 dac33->fifo_mode = DAC33_FIFO_BYPASS; 1562 dac33->fifo_mode = DAC33_FIFO_BYPASS;
1489 1563
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index b4fcdb01fc4..7b618bbff88 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -43,37 +43,37 @@
43 */ 43 */
44static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = { 44static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = {
45 0x00, /* this register not used */ 45 0x00, /* this register not used */
46 0x91, /* REG_CODEC_MODE (0x1) */ 46 0x00, /* REG_CODEC_MODE (0x1) */
47 0xc3, /* REG_OPTION (0x2) */ 47 0x00, /* REG_OPTION (0x2) */
48 0x00, /* REG_UNKNOWN (0x3) */ 48 0x00, /* REG_UNKNOWN (0x3) */
49 0x00, /* REG_MICBIAS_CTL (0x4) */ 49 0x00, /* REG_MICBIAS_CTL (0x4) */
50 0x20, /* REG_ANAMICL (0x5) */ 50 0x00, /* REG_ANAMICL (0x5) */
51 0x00, /* REG_ANAMICR (0x6) */ 51 0x00, /* REG_ANAMICR (0x6) */
52 0x00, /* REG_AVADC_CTL (0x7) */ 52 0x00, /* REG_AVADC_CTL (0x7) */
53 0x00, /* REG_ADCMICSEL (0x8) */ 53 0x00, /* REG_ADCMICSEL (0x8) */
54 0x00, /* REG_DIGMIXING (0x9) */ 54 0x00, /* REG_DIGMIXING (0x9) */
55 0x0c, /* REG_ATXL1PGA (0xA) */ 55 0x0f, /* REG_ATXL1PGA (0xA) */
56 0x0c, /* REG_ATXR1PGA (0xB) */ 56 0x0f, /* REG_ATXR1PGA (0xB) */
57 0x00, /* REG_AVTXL2PGA (0xC) */ 57 0x0f, /* REG_AVTXL2PGA (0xC) */
58 0x00, /* REG_AVTXR2PGA (0xD) */ 58 0x0f, /* REG_AVTXR2PGA (0xD) */
59 0x00, /* REG_AUDIO_IF (0xE) */ 59 0x00, /* REG_AUDIO_IF (0xE) */
60 0x00, /* REG_VOICE_IF (0xF) */ 60 0x00, /* REG_VOICE_IF (0xF) */
61 0x00, /* REG_ARXR1PGA (0x10) */ 61 0x3f, /* REG_ARXR1PGA (0x10) */
62 0x00, /* REG_ARXL1PGA (0x11) */ 62 0x3f, /* REG_ARXL1PGA (0x11) */
63 0x6c, /* REG_ARXR2PGA (0x12) */ 63 0x3f, /* REG_ARXR2PGA (0x12) */
64 0x6c, /* REG_ARXL2PGA (0x13) */ 64 0x3f, /* REG_ARXL2PGA (0x13) */
65 0x00, /* REG_VRXPGA (0x14) */ 65 0x25, /* REG_VRXPGA (0x14) */
66 0x00, /* REG_VSTPGA (0x15) */ 66 0x00, /* REG_VSTPGA (0x15) */
67 0x00, /* REG_VRX2ARXPGA (0x16) */ 67 0x00, /* REG_VRX2ARXPGA (0x16) */
68 0x00, /* REG_AVDAC_CTL (0x17) */ 68 0x00, /* REG_AVDAC_CTL (0x17) */
69 0x00, /* REG_ARX2VTXPGA (0x18) */ 69 0x00, /* REG_ARX2VTXPGA (0x18) */
70 0x00, /* REG_ARXL1_APGA_CTL (0x19) */ 70 0x32, /* REG_ARXL1_APGA_CTL (0x19) */
71 0x00, /* REG_ARXR1_APGA_CTL (0x1A) */ 71 0x32, /* REG_ARXR1_APGA_CTL (0x1A) */
72 0x4a, /* REG_ARXL2_APGA_CTL (0x1B) */ 72 0x32, /* REG_ARXL2_APGA_CTL (0x1B) */
73 0x4a, /* REG_ARXR2_APGA_CTL (0x1C) */ 73 0x32, /* REG_ARXR2_APGA_CTL (0x1C) */
74 0x00, /* REG_ATX2ARXPGA (0x1D) */ 74 0x00, /* REG_ATX2ARXPGA (0x1D) */
75 0x00, /* REG_BT_IF (0x1E) */ 75 0x00, /* REG_BT_IF (0x1E) */
76 0x00, /* REG_BTPGA (0x1F) */ 76 0x55, /* REG_BTPGA (0x1F) */
77 0x00, /* REG_BTSTPGA (0x20) */ 77 0x00, /* REG_BTSTPGA (0x20) */
78 0x00, /* REG_EAR_CTL (0x21) */ 78 0x00, /* REG_EAR_CTL (0x21) */
79 0x00, /* REG_HS_SEL (0x22) */ 79 0x00, /* REG_HS_SEL (0x22) */
@@ -85,32 +85,32 @@ static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = {
85 0x00, /* REG_PRECKR_CTL (0x28) */ 85 0x00, /* REG_PRECKR_CTL (0x28) */
86 0x00, /* REG_HFL_CTL (0x29) */ 86 0x00, /* REG_HFL_CTL (0x29) */
87 0x00, /* REG_HFR_CTL (0x2A) */ 87 0x00, /* REG_HFR_CTL (0x2A) */
88 0x00, /* REG_ALC_CTL (0x2B) */ 88 0x05, /* REG_ALC_CTL (0x2B) */
89 0x00, /* REG_ALC_SET1 (0x2C) */ 89 0x00, /* REG_ALC_SET1 (0x2C) */
90 0x00, /* REG_ALC_SET2 (0x2D) */ 90 0x00, /* REG_ALC_SET2 (0x2D) */
91 0x00, /* REG_BOOST_CTL (0x2E) */ 91 0x00, /* REG_BOOST_CTL (0x2E) */
92 0x00, /* REG_SOFTVOL_CTL (0x2F) */ 92 0x00, /* REG_SOFTVOL_CTL (0x2F) */
93 0x00, /* REG_DTMF_FREQSEL (0x30) */ 93 0x13, /* REG_DTMF_FREQSEL (0x30) */
94 0x00, /* REG_DTMF_TONEXT1H (0x31) */ 94 0x00, /* REG_DTMF_TONEXT1H (0x31) */
95 0x00, /* REG_DTMF_TONEXT1L (0x32) */ 95 0x00, /* REG_DTMF_TONEXT1L (0x32) */
96 0x00, /* REG_DTMF_TONEXT2H (0x33) */ 96 0x00, /* REG_DTMF_TONEXT2H (0x33) */
97 0x00, /* REG_DTMF_TONEXT2L (0x34) */ 97 0x00, /* REG_DTMF_TONEXT2L (0x34) */
98 0x00, /* REG_DTMF_TONOFF (0x35) */ 98 0x79, /* REG_DTMF_TONOFF (0x35) */
99 0x00, /* REG_DTMF_WANONOFF (0x36) */ 99 0x11, /* REG_DTMF_WANONOFF (0x36) */
100 0x00, /* REG_I2S_RX_SCRAMBLE_H (0x37) */ 100 0x00, /* REG_I2S_RX_SCRAMBLE_H (0x37) */
101 0x00, /* REG_I2S_RX_SCRAMBLE_M (0x38) */ 101 0x00, /* REG_I2S_RX_SCRAMBLE_M (0x38) */
102 0x00, /* REG_I2S_RX_SCRAMBLE_L (0x39) */ 102 0x00, /* REG_I2S_RX_SCRAMBLE_L (0x39) */
103 0x06, /* REG_APLL_CTL (0x3A) */ 103 0x06, /* REG_APLL_CTL (0x3A) */
104 0x00, /* REG_DTMF_CTL (0x3B) */ 104 0x00, /* REG_DTMF_CTL (0x3B) */
105 0x00, /* REG_DTMF_PGA_CTL2 (0x3C) */ 105 0x44, /* REG_DTMF_PGA_CTL2 (0x3C) */
106 0x00, /* REG_DTMF_PGA_CTL1 (0x3D) */ 106 0x69, /* REG_DTMF_PGA_CTL1 (0x3D) */
107 0x00, /* REG_MISC_SET_1 (0x3E) */ 107 0x00, /* REG_MISC_SET_1 (0x3E) */
108 0x00, /* REG_PCMBTMUX (0x3F) */ 108 0x00, /* REG_PCMBTMUX (0x3F) */
109 0x00, /* not used (0x40) */ 109 0x00, /* not used (0x40) */
110 0x00, /* not used (0x41) */ 110 0x00, /* not used (0x41) */
111 0x00, /* not used (0x42) */ 111 0x00, /* not used (0x42) */
112 0x00, /* REG_RX_PATH_SEL (0x43) */ 112 0x00, /* REG_RX_PATH_SEL (0x43) */
113 0x00, /* REG_VDL_APGA_CTL (0x44) */ 113 0x32, /* REG_VDL_APGA_CTL (0x44) */
114 0x00, /* REG_VIBRA_CTL (0x45) */ 114 0x00, /* REG_VIBRA_CTL (0x45) */
115 0x00, /* REG_VIBRA_SET (0x46) */ 115 0x00, /* REG_VIBRA_SET (0x46) */
116 0x00, /* REG_VIBRA_PWM_SET (0x47) */ 116 0x00, /* REG_VIBRA_PWM_SET (0x47) */
@@ -143,6 +143,9 @@ struct twl4030_priv {
143 u8 earpiece_enabled; 143 u8 earpiece_enabled;
144 u8 predrivel_enabled, predriver_enabled; 144 u8 predrivel_enabled, predriver_enabled;
145 u8 carkitl_enabled, carkitr_enabled; 145 u8 carkitl_enabled, carkitr_enabled;
146
147 /* Delay needed after enabling the digimic interface */
148 unsigned int digimic_delay;
146}; 149};
147 150
148/* 151/*
@@ -244,58 +247,95 @@ static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable)
244 udelay(10); 247 udelay(10);
245} 248}
246 249
247static void twl4030_init_chip(struct snd_soc_codec *codec) 250static inline void twl4030_check_defaults(struct snd_soc_codec *codec)
248{ 251{
249 u8 *cache = codec->reg_cache; 252 int i, difference = 0;
250 int i; 253 u8 val;
254
255 dev_dbg(codec->dev, "Checking TWL audio default configuration\n");
256 for (i = 1; i <= TWL4030_REG_MISC_SET_2; i++) {
257 twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &val, i);
258 if (val != twl4030_reg[i]) {
259 difference++;
260 dev_dbg(codec->dev,
261 "Reg 0x%02x: chip: 0x%02x driver: 0x%02x\n",
262 i, val, twl4030_reg[i]);
263 }
264 }
265 dev_dbg(codec->dev, "Found %d non maching registers. %s\n",
266 difference, difference ? "Not OK" : "OK");
267}
251 268
252 /* clear CODECPDZ prior to setting register defaults */ 269static inline void twl4030_reset_registers(struct snd_soc_codec *codec)
253 twl4030_codec_enable(codec, 0); 270{
271 int i;
254 272
255 /* set all audio section registers to reasonable defaults */ 273 /* set all audio section registers to reasonable defaults */
256 for (i = TWL4030_REG_OPTION; i <= TWL4030_REG_MISC_SET_2; i++) 274 for (i = TWL4030_REG_OPTION; i <= TWL4030_REG_MISC_SET_2; i++)
257 if (i != TWL4030_REG_APLL_CTL) 275 if (i != TWL4030_REG_APLL_CTL)
258 twl4030_write(codec, i, cache[i]); 276 twl4030_write(codec, i, twl4030_reg[i]);
259 277
260} 278}
261 279
262static void twl4030_apll_enable(struct snd_soc_codec *codec, int enable) 280static void twl4030_init_chip(struct platform_device *pdev)
263{ 281{
282 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
283 struct twl4030_setup_data *setup = socdev->codec_data;
284 struct snd_soc_codec *codec = socdev->card->codec;
264 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 285 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
265 int status = -1; 286 u8 reg, byte;
287 int i = 0;
266 288
267 if (enable) { 289 /* Check defaults, if instructed before anything else */
268 twl4030->apll_enabled++; 290 if (setup && setup->check_defaults)
269 if (twl4030->apll_enabled == 1) 291 twl4030_check_defaults(codec);
270 status = twl4030_codec_enable_resource(
271 TWL4030_CODEC_RES_APLL);
272 } else {
273 twl4030->apll_enabled--;
274 if (!twl4030->apll_enabled)
275 status = twl4030_codec_disable_resource(
276 TWL4030_CODEC_RES_APLL);
277 }
278 292
279 if (status >= 0) 293 /* Reset registers, if no setup data or if instructed to do so */
280 twl4030_write_reg_cache(codec, TWL4030_REG_APLL_CTL, status); 294 if (!setup || (setup && setup->reset_registers))
281} 295 twl4030_reset_registers(codec);
282 296
283static void twl4030_power_up(struct snd_soc_codec *codec) 297 /* Refresh APLL_CTL register from HW */
284{ 298 twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte,
285 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 299 TWL4030_REG_APLL_CTL);
286 u8 anamicl, regmisc1, byte; 300 twl4030_write_reg_cache(codec, TWL4030_REG_APLL_CTL, byte);
287 int i = 0; 301
302 /* anti-pop when changing analog gain */
303 reg = twl4030_read_reg_cache(codec, TWL4030_REG_MISC_SET_1);
304 twl4030_write(codec, TWL4030_REG_MISC_SET_1,
305 reg | TWL4030_SMOOTH_ANAVOL_EN);
288 306
289 if (twl4030->codec_powered) 307 twl4030_write(codec, TWL4030_REG_OPTION,
308 TWL4030_ATXL1_EN | TWL4030_ATXR1_EN |
309 TWL4030_ARXL2_EN | TWL4030_ARXR2_EN);
310
311 /* REG_ARXR2_APGA_CTL reset according to the TRM: 0dB, DA_EN */
312 twl4030_write(codec, TWL4030_REG_ARXR2_APGA_CTL, 0x32);
313
314 /* Machine dependent setup */
315 if (!setup)
290 return; 316 return;
291 317
292 /* set CODECPDZ to turn on codec */ 318 twl4030->digimic_delay = setup->digimic_delay;
293 twl4030_codec_enable(codec, 1); 319
320 /* Configuration for headset ramp delay from setup data */
321 if (setup->sysclk != twl4030->sysclk)
322 dev_warn(codec->dev,
323 "Mismatch in APLL mclk: %u (configured: %u)\n",
324 setup->sysclk, twl4030->sysclk);
325
326 reg = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET);
327 reg &= ~TWL4030_RAMP_DELAY;
328 reg |= (setup->ramp_delay_value << 2);
329 twl4030_write_reg_cache(codec, TWL4030_REG_HS_POPN_SET, reg);
294 330
295 /* initiate offset cancellation */ 331 /* initiate offset cancellation */
296 anamicl = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICL); 332 twl4030_codec_enable(codec, 1);
333
334 reg = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICL);
335 reg &= ~TWL4030_OFFSET_CNCL_SEL;
336 reg |= setup->offset_cncl_path;
297 twl4030_write(codec, TWL4030_REG_ANAMICL, 337 twl4030_write(codec, TWL4030_REG_ANAMICL,
298 anamicl | TWL4030_CNCL_OFFSET_START); 338 reg | TWL4030_CNCL_OFFSET_START);
299 339
300 /* wait for offset cancellation to complete */ 340 /* wait for offset cancellation to complete */
301 do { 341 do {
@@ -310,23 +350,28 @@ static void twl4030_power_up(struct snd_soc_codec *codec)
310 /* Make sure that the reg_cache has the same value as the HW */ 350 /* Make sure that the reg_cache has the same value as the HW */
311 twl4030_write_reg_cache(codec, TWL4030_REG_ANAMICL, byte); 351 twl4030_write_reg_cache(codec, TWL4030_REG_ANAMICL, byte);
312 352
313 /* anti-pop when changing analog gain */
314 regmisc1 = twl4030_read_reg_cache(codec, TWL4030_REG_MISC_SET_1);
315 twl4030_write(codec, TWL4030_REG_MISC_SET_1,
316 regmisc1 | TWL4030_SMOOTH_ANAVOL_EN);
317
318 /* toggle CODECPDZ as per TRM */
319 twl4030_codec_enable(codec, 0); 353 twl4030_codec_enable(codec, 0);
320 twl4030_codec_enable(codec, 1);
321} 354}
322 355
323/* 356static void twl4030_apll_enable(struct snd_soc_codec *codec, int enable)
324 * Unconditional power down
325 */
326static void twl4030_power_down(struct snd_soc_codec *codec)
327{ 357{
328 /* power down */ 358 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
329 twl4030_codec_enable(codec, 0); 359 int status = -1;
360
361 if (enable) {
362 twl4030->apll_enabled++;
363 if (twl4030->apll_enabled == 1)
364 status = twl4030_codec_enable_resource(
365 TWL4030_CODEC_RES_APLL);
366 } else {
367 twl4030->apll_enabled--;
368 if (!twl4030->apll_enabled)
369 status = twl4030_codec_disable_resource(
370 TWL4030_CODEC_RES_APLL);
371 }
372
373 if (status >= 0)
374 twl4030_write_reg_cache(codec, TWL4030_REG_APLL_CTL, status);
330} 375}
331 376
332/* Earpiece */ 377/* Earpiece */
@@ -500,10 +545,11 @@ static const struct snd_kcontrol_new twl4030_dapm_abypassl2_control =
500static const struct snd_kcontrol_new twl4030_dapm_abypassv_control = 545static const struct snd_kcontrol_new twl4030_dapm_abypassv_control =
501 SOC_DAPM_SINGLE("Switch", TWL4030_REG_VDL_APGA_CTL, 2, 1, 0); 546 SOC_DAPM_SINGLE("Switch", TWL4030_REG_VDL_APGA_CTL, 2, 1, 0);
502 547
503/* Digital bypass gain, 0 mutes the bypass */ 548/* Digital bypass gain, mute instead of -30dB */
504static const unsigned int twl4030_dapm_dbypass_tlv[] = { 549static const unsigned int twl4030_dapm_dbypass_tlv[] = {
505 TLV_DB_RANGE_HEAD(2), 550 TLV_DB_RANGE_HEAD(3),
506 0, 3, TLV_DB_SCALE_ITEM(-2400, 0, 1), 551 0, 1, TLV_DB_SCALE_ITEM(-3000, 600, 1),
552 2, 3, TLV_DB_SCALE_ITEM(-2400, 0, 0),
507 4, 7, TLV_DB_SCALE_ITEM(-1800, 600, 0), 553 4, 7, TLV_DB_SCALE_ITEM(-1800, 600, 0),
508}; 554};
509 555
@@ -531,36 +577,6 @@ static const struct snd_kcontrol_new twl4030_dapm_dbypassv_control =
531 TWL4030_REG_VSTPGA, 0, 0x29, 0, 577 TWL4030_REG_VSTPGA, 0, 0x29, 0,
532 twl4030_dapm_dbypassv_tlv); 578 twl4030_dapm_dbypassv_tlv);
533 579
534static int micpath_event(struct snd_soc_dapm_widget *w,
535 struct snd_kcontrol *kcontrol, int event)
536{
537 struct soc_enum *e = (struct soc_enum *)w->kcontrols->private_value;
538 unsigned char adcmicsel, micbias_ctl;
539
540 adcmicsel = twl4030_read_reg_cache(w->codec, TWL4030_REG_ADCMICSEL);
541 micbias_ctl = twl4030_read_reg_cache(w->codec, TWL4030_REG_MICBIAS_CTL);
542 /* Prepare the bits for the given TX path:
543 * shift_l == 0: TX1 microphone path
544 * shift_l == 2: TX2 microphone path */
545 if (e->shift_l) {
546 /* TX2 microphone path */
547 if (adcmicsel & TWL4030_TX2IN_SEL)
548 micbias_ctl |= TWL4030_MICBIAS2_CTL; /* digimic */
549 else
550 micbias_ctl &= ~TWL4030_MICBIAS2_CTL;
551 } else {
552 /* TX1 microphone path */
553 if (adcmicsel & TWL4030_TX1IN_SEL)
554 micbias_ctl |= TWL4030_MICBIAS1_CTL; /* digimic */
555 else
556 micbias_ctl &= ~TWL4030_MICBIAS1_CTL;
557 }
558
559 twl4030_write(w->codec, TWL4030_REG_MICBIAS_CTL, micbias_ctl);
560
561 return 0;
562}
563
564/* 580/*
565 * Output PGA builder: 581 * Output PGA builder:
566 * Handle the muting and unmuting of the given output (turning off the 582 * Handle the muting and unmuting of the given output (turning off the
@@ -814,6 +830,16 @@ static int headsetrpga_event(struct snd_soc_dapm_widget *w,
814 return 0; 830 return 0;
815} 831}
816 832
833static int digimic_event(struct snd_soc_dapm_widget *w,
834 struct snd_kcontrol *kcontrol, int event)
835{
836 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec);
837
838 if (twl4030->digimic_delay)
839 mdelay(twl4030->digimic_delay);
840 return 0;
841}
842
817/* 843/*
818 * Some of the gain controls in TWL (mostly those which are associated with 844 * Some of the gain controls in TWL (mostly those which are associated with
819 * the outputs) are implemented in an interesting way: 845 * the outputs) are implemented in an interesting way:
@@ -1374,14 +1400,10 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1374 /* Analog/Digital mic path selection. 1400 /* Analog/Digital mic path selection.
1375 TX1 Left/Right: either analog Left/Right or Digimic0 1401 TX1 Left/Right: either analog Left/Right or Digimic0
1376 TX2 Left/Right: either analog Left/Right or Digimic1 */ 1402 TX2 Left/Right: either analog Left/Right or Digimic1 */
1377 SND_SOC_DAPM_MUX_E("TX1 Capture Route", SND_SOC_NOPM, 0, 0, 1403 SND_SOC_DAPM_MUX("TX1 Capture Route", SND_SOC_NOPM, 0, 0,
1378 &twl4030_dapm_micpathtx1_control, micpath_event, 1404 &twl4030_dapm_micpathtx1_control),
1379 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD| 1405 SND_SOC_DAPM_MUX("TX2 Capture Route", SND_SOC_NOPM, 0, 0,
1380 SND_SOC_DAPM_POST_REG), 1406 &twl4030_dapm_micpathtx2_control),
1381 SND_SOC_DAPM_MUX_E("TX2 Capture Route", SND_SOC_NOPM, 0, 0,
1382 &twl4030_dapm_micpathtx2_control, micpath_event,
1383 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD|
1384 SND_SOC_DAPM_POST_REG),
1385 1407
1386 /* Analog input mixers for the capture amplifiers */ 1408 /* Analog input mixers for the capture amplifiers */
1387 SND_SOC_DAPM_MIXER("Analog Left", 1409 SND_SOC_DAPM_MIXER("Analog Left",
@@ -1398,10 +1420,17 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1398 SND_SOC_DAPM_PGA("ADC Physical Right", 1420 SND_SOC_DAPM_PGA("ADC Physical Right",
1399 TWL4030_REG_AVADC_CTL, 1, 0, NULL, 0), 1421 TWL4030_REG_AVADC_CTL, 1, 0, NULL, 0),
1400 1422
1401 SND_SOC_DAPM_PGA("Digimic0 Enable", 1423 SND_SOC_DAPM_PGA_E("Digimic0 Enable",
1402 TWL4030_REG_ADCMICSEL, 1, 0, NULL, 0), 1424 TWL4030_REG_ADCMICSEL, 1, 0, NULL, 0,
1403 SND_SOC_DAPM_PGA("Digimic1 Enable", 1425 digimic_event, SND_SOC_DAPM_POST_PMU),
1404 TWL4030_REG_ADCMICSEL, 3, 0, NULL, 0), 1426 SND_SOC_DAPM_PGA_E("Digimic1 Enable",
1427 TWL4030_REG_ADCMICSEL, 3, 0, NULL, 0,
1428 digimic_event, SND_SOC_DAPM_POST_PMU),
1429
1430 SND_SOC_DAPM_SUPPLY("micbias1 select", TWL4030_REG_MICBIAS_CTL, 5, 0,
1431 NULL, 0),
1432 SND_SOC_DAPM_SUPPLY("micbias2 select", TWL4030_REG_MICBIAS_CTL, 6, 0,
1433 NULL, 0),
1405 1434
1406 SND_SOC_DAPM_MICBIAS("Mic Bias 1", TWL4030_REG_MICBIAS_CTL, 0, 0), 1435 SND_SOC_DAPM_MICBIAS("Mic Bias 1", TWL4030_REG_MICBIAS_CTL, 0, 0),
1407 SND_SOC_DAPM_MICBIAS("Mic Bias 2", TWL4030_REG_MICBIAS_CTL, 1, 0), 1436 SND_SOC_DAPM_MICBIAS("Mic Bias 2", TWL4030_REG_MICBIAS_CTL, 1, 0),
@@ -1419,8 +1448,11 @@ static const struct snd_soc_dapm_route intercon[] = {
1419 /* Supply for the digital part (APLL) */ 1448 /* Supply for the digital part (APLL) */
1420 {"Digital Voice Playback Mixer", NULL, "APLL Enable"}, 1449 {"Digital Voice Playback Mixer", NULL, "APLL Enable"},
1421 1450
1422 {"Digital R1 Playback Mixer", NULL, "AIF Enable"}, 1451 {"DAC Left1", NULL, "AIF Enable"},
1423 {"Digital L1 Playback Mixer", NULL, "AIF Enable"}, 1452 {"DAC Right1", NULL, "AIF Enable"},
1453 {"DAC Left2", NULL, "AIF Enable"},
1454 {"DAC Right1", NULL, "AIF Enable"},
1455
1424 {"Digital R2 Playback Mixer", NULL, "AIF Enable"}, 1456 {"Digital R2 Playback Mixer", NULL, "AIF Enable"},
1425 {"Digital L2 Playback Mixer", NULL, "AIF Enable"}, 1457 {"Digital L2 Playback Mixer", NULL, "AIF Enable"},
1426 1458
@@ -1491,10 +1523,10 @@ static const struct snd_soc_dapm_route intercon[] = {
1491 1523
1492 /* outputs */ 1524 /* outputs */
1493 /* Must be always connected (for AIF and APLL) */ 1525 /* Must be always connected (for AIF and APLL) */
1494 {"Virtual HiFi OUT", NULL, "Digital L1 Playback Mixer"}, 1526 {"Virtual HiFi OUT", NULL, "DAC Left1"},
1495 {"Virtual HiFi OUT", NULL, "Digital R1 Playback Mixer"}, 1527 {"Virtual HiFi OUT", NULL, "DAC Right1"},
1496 {"Virtual HiFi OUT", NULL, "Digital L2 Playback Mixer"}, 1528 {"Virtual HiFi OUT", NULL, "DAC Left2"},
1497 {"Virtual HiFi OUT", NULL, "Digital R2 Playback Mixer"}, 1529 {"Virtual HiFi OUT", NULL, "DAC Right2"},
1498 /* Must be always connected (for APLL) */ 1530 /* Must be always connected (for APLL) */
1499 {"Virtual Voice OUT", NULL, "Digital Voice Playback Mixer"}, 1531 {"Virtual Voice OUT", NULL, "Digital Voice Playback Mixer"},
1500 /* Physical outputs */ 1532 /* Physical outputs */
@@ -1531,6 +1563,9 @@ static const struct snd_soc_dapm_route intercon[] = {
1531 {"Digimic0 Enable", NULL, "DIGIMIC0"}, 1563 {"Digimic0 Enable", NULL, "DIGIMIC0"},
1532 {"Digimic1 Enable", NULL, "DIGIMIC1"}, 1564 {"Digimic1 Enable", NULL, "DIGIMIC1"},
1533 1565
1566 {"DIGIMIC0", NULL, "micbias1 select"},
1567 {"DIGIMIC1", NULL, "micbias2 select"},
1568
1534 /* TX1 Left capture path */ 1569 /* TX1 Left capture path */
1535 {"TX1 Capture Route", "Analog", "ADC Physical Left"}, 1570 {"TX1 Capture Route", "Analog", "ADC Physical Left"},
1536 {"TX1 Capture Route", "Digimic0", "Digimic0 Enable"}, 1571 {"TX1 Capture Route", "Digimic0", "Digimic0 Enable"},
@@ -1605,10 +1640,10 @@ static int twl4030_set_bias_level(struct snd_soc_codec *codec,
1605 break; 1640 break;
1606 case SND_SOC_BIAS_STANDBY: 1641 case SND_SOC_BIAS_STANDBY:
1607 if (codec->bias_level == SND_SOC_BIAS_OFF) 1642 if (codec->bias_level == SND_SOC_BIAS_OFF)
1608 twl4030_power_up(codec); 1643 twl4030_codec_enable(codec, 1);
1609 break; 1644 break;
1610 case SND_SOC_BIAS_OFF: 1645 case SND_SOC_BIAS_OFF:
1611 twl4030_power_down(codec); 1646 twl4030_codec_enable(codec, 0);
1612 break; 1647 break;
1613 } 1648 }
1614 codec->bias_level = level; 1649 codec->bias_level = level;
@@ -1794,13 +1829,6 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
1794 return -EINVAL; 1829 return -EINVAL;
1795 } 1830 }
1796 1831
1797 if (mode != old_mode) {
1798 /* change rate and set CODECPDZ */
1799 twl4030_codec_enable(codec, 0);
1800 twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode);
1801 twl4030_codec_enable(codec, 1);
1802 }
1803
1804 /* sample size */ 1832 /* sample size */
1805 old_format = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF); 1833 old_format = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF);
1806 format = old_format; 1834 format = old_format;
@@ -1818,16 +1846,20 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
1818 return -EINVAL; 1846 return -EINVAL;
1819 } 1847 }
1820 1848
1821 if (format != old_format) { 1849 if (format != old_format || mode != old_mode) {
1822 1850 if (twl4030->codec_powered) {
1823 /* clear CODECPDZ before changing format (codec requirement) */ 1851 /*
1824 twl4030_codec_enable(codec, 0); 1852 * If the codec is powered, than we need to toggle the
1825 1853 * codec power.
1826 /* change format */ 1854 */
1827 twl4030_write(codec, TWL4030_REG_AUDIO_IF, format); 1855 twl4030_codec_enable(codec, 0);
1828 1856 twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode);
1829 /* set CODECPDZ afterwards */ 1857 twl4030_write(codec, TWL4030_REG_AUDIO_IF, format);
1830 twl4030_codec_enable(codec, 1); 1858 twl4030_codec_enable(codec, 1);
1859 } else {
1860 twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode);
1861 twl4030_write(codec, TWL4030_REG_AUDIO_IF, format);
1862 }
1831 } 1863 }
1832 1864
1833 /* Store the important parameters for the DAI configuration and set 1865 /* Store the important parameters for the DAI configuration and set
@@ -1877,6 +1909,7 @@ static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai,
1877 unsigned int fmt) 1909 unsigned int fmt)
1878{ 1910{
1879 struct snd_soc_codec *codec = codec_dai->codec; 1911 struct snd_soc_codec *codec = codec_dai->codec;
1912 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
1880 u8 old_format, format; 1913 u8 old_format, format;
1881 1914
1882 /* get format */ 1915 /* get format */
@@ -1911,15 +1944,17 @@ static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai,
1911 } 1944 }
1912 1945
1913 if (format != old_format) { 1946 if (format != old_format) {
1914 1947 if (twl4030->codec_powered) {
1915 /* clear CODECPDZ before changing format (codec requirement) */ 1948 /*
1916 twl4030_codec_enable(codec, 0); 1949 * If the codec is powered, than we need to toggle the
1917 1950 * codec power.
1918 /* change format */ 1951 */
1919 twl4030_write(codec, TWL4030_REG_AUDIO_IF, format); 1952 twl4030_codec_enable(codec, 0);
1920 1953 twl4030_write(codec, TWL4030_REG_AUDIO_IF, format);
1921 /* set CODECPDZ afterwards */ 1954 twl4030_codec_enable(codec, 1);
1922 twl4030_codec_enable(codec, 1); 1955 } else {
1956 twl4030_write(codec, TWL4030_REG_AUDIO_IF, format);
1957 }
1923 } 1958 }
1924 1959
1925 return 0; 1960 return 0;
@@ -2011,6 +2046,7 @@ static int twl4030_voice_hw_params(struct snd_pcm_substream *substream,
2011 struct snd_soc_pcm_runtime *rtd = substream->private_data; 2046 struct snd_soc_pcm_runtime *rtd = substream->private_data;
2012 struct snd_soc_device *socdev = rtd->socdev; 2047 struct snd_soc_device *socdev = rtd->socdev;
2013 struct snd_soc_codec *codec = socdev->card->codec; 2048 struct snd_soc_codec *codec = socdev->card->codec;
2049 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
2014 u8 old_mode, mode; 2050 u8 old_mode, mode;
2015 2051
2016 /* Enable voice digital filters */ 2052 /* Enable voice digital filters */
@@ -2035,10 +2071,17 @@ static int twl4030_voice_hw_params(struct snd_pcm_substream *substream,
2035 } 2071 }
2036 2072
2037 if (mode != old_mode) { 2073 if (mode != old_mode) {
2038 /* change rate and set CODECPDZ */ 2074 if (twl4030->codec_powered) {
2039 twl4030_codec_enable(codec, 0); 2075 /*
2040 twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode); 2076 * If the codec is powered, than we need to toggle the
2041 twl4030_codec_enable(codec, 1); 2077 * codec power.
2078 */
2079 twl4030_codec_enable(codec, 0);
2080 twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode);
2081 twl4030_codec_enable(codec, 1);
2082 } else {
2083 twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode);
2084 }
2042 } 2085 }
2043 2086
2044 return 0; 2087 return 0;
@@ -2068,6 +2111,7 @@ static int twl4030_voice_set_dai_fmt(struct snd_soc_dai *codec_dai,
2068 unsigned int fmt) 2111 unsigned int fmt)
2069{ 2112{
2070 struct snd_soc_codec *codec = codec_dai->codec; 2113 struct snd_soc_codec *codec = codec_dai->codec;
2114 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
2071 u8 old_format, format; 2115 u8 old_format, format;
2072 2116
2073 /* get format */ 2117 /* get format */
@@ -2099,10 +2143,17 @@ static int twl4030_voice_set_dai_fmt(struct snd_soc_dai *codec_dai,
2099 } 2143 }
2100 2144
2101 if (format != old_format) { 2145 if (format != old_format) {
2102 /* change format and set CODECPDZ */ 2146 if (twl4030->codec_powered) {
2103 twl4030_codec_enable(codec, 0); 2147 /*
2104 twl4030_write(codec, TWL4030_REG_VOICE_IF, format); 2148 * If the codec is powered, than we need to toggle the
2105 twl4030_codec_enable(codec, 1); 2149 * codec power.
2150 */
2151 twl4030_codec_enable(codec, 0);
2152 twl4030_write(codec, TWL4030_REG_VOICE_IF, format);
2153 twl4030_codec_enable(codec, 1);
2154 } else {
2155 twl4030_write(codec, TWL4030_REG_VOICE_IF, format);
2156 }
2106 } 2157 }
2107 2158
2108 return 0; 2159 return 0;
@@ -2202,31 +2253,15 @@ static struct snd_soc_codec *twl4030_codec;
2202static int twl4030_soc_probe(struct platform_device *pdev) 2253static int twl4030_soc_probe(struct platform_device *pdev)
2203{ 2254{
2204 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 2255 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2205 struct twl4030_setup_data *setup = socdev->codec_data;
2206 struct snd_soc_codec *codec; 2256 struct snd_soc_codec *codec;
2207 struct twl4030_priv *twl4030;
2208 int ret; 2257 int ret;
2209 2258
2210 BUG_ON(!twl4030_codec); 2259 BUG_ON(!twl4030_codec);
2211 2260
2212 codec = twl4030_codec; 2261 codec = twl4030_codec;
2213 twl4030 = snd_soc_codec_get_drvdata(codec);
2214 socdev->card->codec = codec; 2262 socdev->card->codec = codec;
2215 2263
2216 /* Configuration for headset ramp delay from setup data */ 2264 twl4030_init_chip(pdev);
2217 if (setup) {
2218 unsigned char hs_pop;
2219
2220 if (setup->sysclk != twl4030->sysclk)
2221 dev_warn(&pdev->dev,
2222 "Mismatch in APLL mclk: %u (configured: %u)\n",
2223 setup->sysclk, twl4030->sysclk);
2224
2225 hs_pop = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET);
2226 hs_pop &= ~TWL4030_RAMP_DELAY;
2227 hs_pop |= (setup->ramp_delay_value << 2);
2228 twl4030_write_reg_cache(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
2229 }
2230 2265
2231 /* register pcms */ 2266 /* register pcms */
2232 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 2267 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
@@ -2247,6 +2282,8 @@ static int twl4030_soc_remove(struct platform_device *pdev)
2247 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 2282 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2248 struct snd_soc_codec *codec = socdev->card->codec; 2283 struct snd_soc_codec *codec = socdev->card->codec;
2249 2284
2285 /* Reset registers to their chip default before leaving */
2286 twl4030_reset_registers(codec);
2250 twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF); 2287 twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF);
2251 snd_soc_free_pcms(socdev); 2288 snd_soc_free_pcms(socdev);
2252 snd_soc_dapm_free(socdev); 2289 snd_soc_dapm_free(socdev);
@@ -2287,6 +2324,7 @@ static int __devinit twl4030_codec_probe(struct platform_device *pdev)
2287 codec->read = twl4030_read_reg_cache; 2324 codec->read = twl4030_read_reg_cache;
2288 codec->write = twl4030_write; 2325 codec->write = twl4030_write;
2289 codec->set_bias_level = twl4030_set_bias_level; 2326 codec->set_bias_level = twl4030_set_bias_level;
2327 codec->idle_bias_off = 1;
2290 codec->dai = twl4030_dai; 2328 codec->dai = twl4030_dai;
2291 codec->num_dai = ARRAY_SIZE(twl4030_dai); 2329 codec->num_dai = ARRAY_SIZE(twl4030_dai);
2292 codec->reg_cache_size = sizeof(twl4030_reg); 2330 codec->reg_cache_size = sizeof(twl4030_reg);
@@ -2302,9 +2340,7 @@ static int __devinit twl4030_codec_probe(struct platform_device *pdev)
2302 2340
2303 /* Set the defaults, and power up the codec */ 2341 /* Set the defaults, and power up the codec */
2304 twl4030->sysclk = twl4030_codec_get_mclk() / 1000; 2342 twl4030->sysclk = twl4030_codec_get_mclk() / 1000;
2305 twl4030_init_chip(codec);
2306 codec->bias_level = SND_SOC_BIAS_OFF; 2343 codec->bias_level = SND_SOC_BIAS_OFF;
2307 twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2308 2344
2309 ret = snd_soc_register_codec(codec); 2345 ret = snd_soc_register_codec(codec);
2310 if (ret != 0) { 2346 if (ret != 0) {
@@ -2322,7 +2358,7 @@ static int __devinit twl4030_codec_probe(struct platform_device *pdev)
2322 return 0; 2358 return 0;
2323 2359
2324error_codec: 2360error_codec:
2325 twl4030_power_down(codec); 2361 twl4030_codec_enable(codec, 0);
2326 kfree(codec->reg_cache); 2362 kfree(codec->reg_cache);
2327error_cache: 2363error_cache:
2328 kfree(twl4030); 2364 kfree(twl4030);
diff --git a/sound/soc/codecs/twl4030.h b/sound/soc/codecs/twl4030.h
index f206d242ca3..6c57430f6e2 100644
--- a/sound/soc/codecs/twl4030.h
+++ b/sound/soc/codecs/twl4030.h
@@ -41,7 +41,11 @@ extern struct snd_soc_codec_device soc_codec_dev_twl4030;
41 41
42struct twl4030_setup_data { 42struct twl4030_setup_data {
43 unsigned int ramp_delay_value; 43 unsigned int ramp_delay_value;
44 unsigned int digimic_delay; /* in ms */
44 unsigned int sysclk; 45 unsigned int sysclk;
46 unsigned int offset_cncl_path;
47 unsigned int check_defaults:1;
48 unsigned int reset_registers:1;
45 unsigned int hs_extmute:1; 49 unsigned int hs_extmute:1;
46 void (*set_hs_extmute)(int mute); 50 void (*set_hs_extmute)(int mute);
47}; 51};
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
index af36346ff33..64a807f1a8a 100644
--- a/sound/soc/codecs/twl6040.c
+++ b/sound/soc/codecs/twl6040.c
@@ -360,6 +360,13 @@ static int headset_power_mode(struct snd_soc_codec *codec, int high_perf)
360 return 0; 360 return 0;
361} 361}
362 362
363static int twl6040_hs_dac_event(struct snd_soc_dapm_widget *w,
364 struct snd_kcontrol *kcontrol, int event)
365{
366 msleep(1);
367 return 0;
368}
369
363static int twl6040_power_mode_event(struct snd_soc_dapm_widget *w, 370static int twl6040_power_mode_event(struct snd_soc_dapm_widget *w,
364 struct snd_kcontrol *kcontrol, int event) 371 struct snd_kcontrol *kcontrol, int event)
365{ 372{
@@ -371,6 +378,8 @@ static int twl6040_power_mode_event(struct snd_soc_dapm_widget *w,
371 else 378 else
372 priv->non_lp--; 379 priv->non_lp--;
373 380
381 msleep(1);
382
374 return 0; 383 return 0;
375} 384}
376 385
@@ -471,20 +480,6 @@ static const struct snd_kcontrol_new hfdacl_switch_controls =
471static const struct snd_kcontrol_new hfdacr_switch_controls = 480static const struct snd_kcontrol_new hfdacr_switch_controls =
472 SOC_DAPM_SINGLE("Switch", TWL6040_REG_HFRCTL, 2, 1, 0); 481 SOC_DAPM_SINGLE("Switch", TWL6040_REG_HFRCTL, 2, 1, 0);
473 482
474/* Headset driver switches */
475static const struct snd_kcontrol_new hsl_driver_switch_controls =
476 SOC_DAPM_SINGLE("Switch", TWL6040_REG_HSLCTL, 2, 1, 0);
477
478static const struct snd_kcontrol_new hsr_driver_switch_controls =
479 SOC_DAPM_SINGLE("Switch", TWL6040_REG_HSRCTL, 2, 1, 0);
480
481/* Handsfree driver switches */
482static const struct snd_kcontrol_new hfl_driver_switch_controls =
483 SOC_DAPM_SINGLE("Switch", TWL6040_REG_HFLCTL, 4, 1, 0);
484
485static const struct snd_kcontrol_new hfr_driver_switch_controls =
486 SOC_DAPM_SINGLE("Switch", TWL6040_REG_HFRCTL, 4, 1, 0);
487
488static const struct snd_kcontrol_new ep_driver_switch_controls = 483static const struct snd_kcontrol_new ep_driver_switch_controls =
489 SOC_DAPM_SINGLE("Switch", TWL6040_REG_EARCTL, 0, 1, 0); 484 SOC_DAPM_SINGLE("Switch", TWL6040_REG_EARCTL, 0, 1, 0);
490 485
@@ -548,10 +543,14 @@ static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = {
548 TWL6040_REG_DMICBCTL, 4, 0), 543 TWL6040_REG_DMICBCTL, 4, 0),
549 544
550 /* DACs */ 545 /* DACs */
551 SND_SOC_DAPM_DAC("HSDAC Left", "Headset Playback", 546 SND_SOC_DAPM_DAC_E("HSDAC Left", "Headset Playback",
552 TWL6040_REG_HSLCTL, 0, 0), 547 TWL6040_REG_HSLCTL, 0, 0,
553 SND_SOC_DAPM_DAC("HSDAC Right", "Headset Playback", 548 twl6040_hs_dac_event,
554 TWL6040_REG_HSRCTL, 0, 0), 549 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
550 SND_SOC_DAPM_DAC_E("HSDAC Right", "Headset Playback",
551 TWL6040_REG_HSRCTL, 0, 0,
552 twl6040_hs_dac_event,
553 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
555 SND_SOC_DAPM_DAC_E("HFDAC Left", "Handsfree Playback", 554 SND_SOC_DAPM_DAC_E("HFDAC Left", "Handsfree Playback",
556 TWL6040_REG_HFLCTL, 0, 0, 555 TWL6040_REG_HFLCTL, 0, 0,
557 twl6040_power_mode_event, 556 twl6040_power_mode_event,
@@ -571,18 +570,19 @@ static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = {
571 SND_SOC_DAPM_SWITCH("HFDAC Right Playback", 570 SND_SOC_DAPM_SWITCH("HFDAC Right Playback",
572 SND_SOC_NOPM, 0, 0, &hfdacr_switch_controls), 571 SND_SOC_NOPM, 0, 0, &hfdacr_switch_controls),
573 572
574 SND_SOC_DAPM_SWITCH("Headset Left Driver", 573 /* Analog playback drivers */
575 SND_SOC_NOPM, 0, 0, &hsl_driver_switch_controls), 574 SND_SOC_DAPM_PGA_E("Handsfree Left Driver",
576 SND_SOC_DAPM_SWITCH("Headset Right Driver", 575 TWL6040_REG_HFLCTL, 4, 0, NULL, 0,
577 SND_SOC_NOPM, 0, 0, &hsr_driver_switch_controls),
578 SND_SOC_DAPM_SWITCH_E("Handsfree Left Driver",
579 SND_SOC_NOPM, 0, 0, &hfl_driver_switch_controls,
580 twl6040_power_mode_event, 576 twl6040_power_mode_event,
581 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 577 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
582 SND_SOC_DAPM_SWITCH_E("Handsfree Right Driver", 578 SND_SOC_DAPM_PGA_E("Handsfree Right Driver",
583 SND_SOC_NOPM, 0, 0, &hfr_driver_switch_controls, 579 TWL6040_REG_HFRCTL, 4, 0, NULL, 0,
584 twl6040_power_mode_event, 580 twl6040_power_mode_event,
585 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 581 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
582 SND_SOC_DAPM_PGA("Headset Left Driver",
583 TWL6040_REG_HSLCTL, 2, 0, NULL, 0),
584 SND_SOC_DAPM_PGA("Headset Right Driver",
585 TWL6040_REG_HSRCTL, 2, 0, NULL, 0),
586 SND_SOC_DAPM_SWITCH_E("Earphone Driver", 586 SND_SOC_DAPM_SWITCH_E("Earphone Driver",
587 SND_SOC_NOPM, 0, 0, &ep_driver_switch_controls, 587 SND_SOC_NOPM, 0, 0, &ep_driver_switch_controls,
588 twl6040_power_mode_event, 588 twl6040_power_mode_event,
@@ -616,8 +616,8 @@ static const struct snd_soc_dapm_route intercon[] = {
616 {"HSDAC Left Playback", "Switch", "HSDAC Left"}, 616 {"HSDAC Left Playback", "Switch", "HSDAC Left"},
617 {"HSDAC Right Playback", "Switch", "HSDAC Right"}, 617 {"HSDAC Right Playback", "Switch", "HSDAC Right"},
618 618
619 {"Headset Left Driver", "Switch", "HSDAC Left Playback"}, 619 {"Headset Left Driver", NULL, "HSDAC Left Playback"},
620 {"Headset Right Driver", "Switch", "HSDAC Right Playback"}, 620 {"Headset Right Driver", NULL, "HSDAC Right Playback"},
621 621
622 {"HSOL", NULL, "Headset Left Driver"}, 622 {"HSOL", NULL, "Headset Left Driver"},
623 {"HSOR", NULL, "Headset Right Driver"}, 623 {"HSOR", NULL, "Headset Right Driver"},
@@ -928,7 +928,7 @@ static int twl6040_set_dai_sysclk(struct snd_soc_dai *codec_dai,
928 case 19200000: 928 case 19200000:
929 /* mclk input, pll disabled */ 929 /* mclk input, pll disabled */
930 hppllctl |= TWL6040_MCLK_19200KHZ | 930 hppllctl |= TWL6040_MCLK_19200KHZ |
931 TWL6040_HPLLSQRBP | 931 TWL6040_HPLLSQRENA |
932 TWL6040_HPLLBP; 932 TWL6040_HPLLBP;
933 break; 933 break;
934 case 26000000: 934 case 26000000:
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c
index 28aac53c97b..f3b4c1d6a82 100644
--- a/sound/soc/codecs/uda134x.c
+++ b/sound/soc/codecs/uda134x.c
@@ -28,19 +28,6 @@
28#include "uda134x.h" 28#include "uda134x.h"
29 29
30 30
31#define POWER_OFF_ON_STANDBY 1
32/*
33 ALSA SOC usually puts the device in standby mode when it's not used
34 for sometime. If you define POWER_OFF_ON_STANDBY the driver will
35 turn off the ADC/DAC when this callback is invoked and turn it back
36 on when needed. Unfortunately this will result in a very light bump
37 (it can be audible only with good earphones). If this bothers you
38 just comment this line, you will have slightly higher power
39 consumption . Please note that sending the L3 command for ADC is
40 enough to make the bump, so it doesn't make difference if you
41 completely take off power from the codec.
42 */
43
44#define UDA134X_RATES SNDRV_PCM_RATE_8000_48000 31#define UDA134X_RATES SNDRV_PCM_RATE_8000_48000
45#define UDA134X_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | \ 32#define UDA134X_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | \
46 SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S20_3LE) 33 SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S20_3LE)
@@ -58,7 +45,7 @@ static const char uda134x_reg[UDA134X_REGS_NUM] = {
58 /* Extended address registers */ 45 /* Extended address registers */
59 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 46 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
60 /* Status, data regs */ 47 /* Status, data regs */
61 0x00, 0x83, 0x00, 0x40, 0x80, 0x00, 48 0x00, 0x83, 0x00, 0x40, 0x80, 0xC0, 0x00,
62}; 49};
63 50
64/* 51/*
@@ -117,6 +104,7 @@ static int uda134x_write(struct snd_soc_codec *codec, unsigned int reg,
117 case UDA134X_DATA000: 104 case UDA134X_DATA000:
118 case UDA134X_DATA001: 105 case UDA134X_DATA001:
119 case UDA134X_DATA010: 106 case UDA134X_DATA010:
107 case UDA134X_DATA011:
120 addr = UDA134X_DATA0_ADDR; 108 addr = UDA134X_DATA0_ADDR;
121 break; 109 break;
122 case UDA134X_DATA1: 110 case UDA134X_DATA1:
@@ -353,8 +341,22 @@ static int uda134x_set_bias_level(struct snd_soc_codec *codec,
353 switch (level) { 341 switch (level) {
354 case SND_SOC_BIAS_ON: 342 case SND_SOC_BIAS_ON:
355 /* ADC, DAC on */ 343 /* ADC, DAC on */
356 reg = uda134x_read_reg_cache(codec, UDA134X_STATUS1); 344 switch (pd->model) {
357 uda134x_write(codec, UDA134X_STATUS1, reg | 0x03); 345 case UDA134X_UDA1340:
346 case UDA134X_UDA1344:
347 case UDA134X_UDA1345:
348 reg = uda134x_read_reg_cache(codec, UDA134X_DATA011);
349 uda134x_write(codec, UDA134X_DATA011, reg | 0x03);
350 break;
351 case UDA134X_UDA1341:
352 reg = uda134x_read_reg_cache(codec, UDA134X_STATUS1);
353 uda134x_write(codec, UDA134X_STATUS1, reg | 0x03);
354 break;
355 default:
356 printk(KERN_ERR "UDA134X SoC codec: "
357 "unsupported model %d\n", pd->model);
358 return -EINVAL;
359 }
358 break; 360 break;
359 case SND_SOC_BIAS_PREPARE: 361 case SND_SOC_BIAS_PREPARE:
360 /* power on */ 362 /* power on */
@@ -367,8 +369,22 @@ static int uda134x_set_bias_level(struct snd_soc_codec *codec,
367 break; 369 break;
368 case SND_SOC_BIAS_STANDBY: 370 case SND_SOC_BIAS_STANDBY:
369 /* ADC, DAC power off */ 371 /* ADC, DAC power off */
370 reg = uda134x_read_reg_cache(codec, UDA134X_STATUS1); 372 switch (pd->model) {
371 uda134x_write(codec, UDA134X_STATUS1, reg & ~(0x03)); 373 case UDA134X_UDA1340:
374 case UDA134X_UDA1344:
375 case UDA134X_UDA1345:
376 reg = uda134x_read_reg_cache(codec, UDA134X_DATA011);
377 uda134x_write(codec, UDA134X_DATA011, reg & ~(0x03));
378 break;
379 case UDA134X_UDA1341:
380 reg = uda134x_read_reg_cache(codec, UDA134X_STATUS1);
381 uda134x_write(codec, UDA134X_STATUS1, reg & ~(0x03));
382 break;
383 default:
384 printk(KERN_ERR "UDA134X SoC codec: "
385 "unsupported model %d\n", pd->model);
386 return -EINVAL;
387 }
372 break; 388 break;
373 case SND_SOC_BIAS_OFF: 389 case SND_SOC_BIAS_OFF:
374 /* power off */ 390 /* power off */
@@ -531,9 +547,7 @@ static int uda134x_soc_probe(struct platform_device *pdev)
531 codec->num_dai = 1; 547 codec->num_dai = 1;
532 codec->read = uda134x_read_reg_cache; 548 codec->read = uda134x_read_reg_cache;
533 codec->write = uda134x_write; 549 codec->write = uda134x_write;
534#ifdef POWER_OFF_ON_STANDBY 550
535 codec->set_bias_level = uda134x_set_bias_level;
536#endif
537 INIT_LIST_HEAD(&codec->dapm_widgets); 551 INIT_LIST_HEAD(&codec->dapm_widgets);
538 INIT_LIST_HEAD(&codec->dapm_paths); 552 INIT_LIST_HEAD(&codec->dapm_paths);
539 553
@@ -544,6 +558,14 @@ static int uda134x_soc_probe(struct platform_device *pdev)
544 558
545 uda134x_reset(codec); 559 uda134x_reset(codec);
546 560
561 if (pd->is_powered_on_standby) {
562 codec->set_bias_level = NULL;
563 uda134x_set_bias_level(codec, SND_SOC_BIAS_ON);
564 } else {
565 codec->set_bias_level = uda134x_set_bias_level;
566 uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
567 }
568
547 /* register pcms */ 569 /* register pcms */
548 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 570 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
549 if (ret < 0) { 571 if (ret < 0) {
diff --git a/sound/soc/codecs/uda134x.h b/sound/soc/codecs/uda134x.h
index 94f440490b3..205f03b3eaf 100644
--- a/sound/soc/codecs/uda134x.h
+++ b/sound/soc/codecs/uda134x.h
@@ -23,9 +23,10 @@
23#define UDA134X_DATA000 10 23#define UDA134X_DATA000 10
24#define UDA134X_DATA001 11 24#define UDA134X_DATA001 11
25#define UDA134X_DATA010 12 25#define UDA134X_DATA010 12
26#define UDA134X_DATA1 13 26#define UDA134X_DATA011 13
27#define UDA134X_DATA1 14
27 28
28#define UDA134X_REGS_NUM 14 29#define UDA134X_REGS_NUM 15
29 30
30#define STATUS0_DAIFMT_MASK (~(7<<1)) 31#define STATUS0_DAIFMT_MASK (~(7<<1))
31#define STATUS0_SYSCLK_MASK (~(3<<4)) 32#define STATUS0_SYSCLK_MASK (~(3<<4))
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c
index 002e289d125..4bcd168794e 100644
--- a/sound/soc/codecs/wm2000.c
+++ b/sound/soc/codecs/wm2000.c
@@ -795,6 +795,8 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c,
795 795
796 dev_set_drvdata(&i2c->dev, wm2000); 796 dev_set_drvdata(&i2c->dev, wm2000);
797 wm2000->anc_eng_ena = 1; 797 wm2000->anc_eng_ena = 1;
798 wm2000->anc_active = 1;
799 wm2000->spk_ena = 1;
798 wm2000->i2c = i2c; 800 wm2000->i2c = i2c;
799 801
800 wm2000_reset(wm2000); 802 wm2000_reset(wm2000);
diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c
index 37242a7d307..0ad039b4adf 100644
--- a/sound/soc/codecs/wm8523.c
+++ b/sound/soc/codecs/wm8523.c
@@ -482,7 +482,8 @@ static int wm8523_register(struct wm8523_priv *wm8523,
482 482
483 if (wm8523_codec) { 483 if (wm8523_codec) {
484 dev_err(codec->dev, "Another WM8523 is registered\n"); 484 dev_err(codec->dev, "Another WM8523 is registered\n");
485 return -EINVAL; 485 ret = -EINVAL;
486 goto err;
486 } 487 }
487 488
488 mutex_init(&codec->mutex); 489 mutex_init(&codec->mutex);
@@ -570,18 +571,19 @@ static int wm8523_register(struct wm8523_priv *wm8523,
570 ret = snd_soc_register_codec(codec); 571 ret = snd_soc_register_codec(codec);
571 if (ret != 0) { 572 if (ret != 0) {
572 dev_err(codec->dev, "Failed to register codec: %d\n", ret); 573 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
573 return ret; 574 goto err_enable;
574 } 575 }
575 576
576 ret = snd_soc_register_dai(&wm8523_dai); 577 ret = snd_soc_register_dai(&wm8523_dai);
577 if (ret != 0) { 578 if (ret != 0) {
578 dev_err(codec->dev, "Failed to register DAI: %d\n", ret); 579 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
579 snd_soc_unregister_codec(codec); 580 goto err_codec;
580 return ret;
581 } 581 }
582 582
583 return 0; 583 return 0;
584 584
585err_codec:
586 snd_soc_unregister_codec(codec);
585err_enable: 587err_enable:
586 regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies); 588 regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
587err_get: 589err_get:
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c
index c3571ee5c11..72deeabef4f 100644
--- a/sound/soc/codecs/wm8580.c
+++ b/sound/soc/codecs/wm8580.c
@@ -269,9 +269,9 @@ SOC_DOUBLE("DAC2 Invert Switch", WM8580_DAC_CONTROL4, 2, 3, 1, 0),
269SOC_DOUBLE("DAC3 Invert Switch", WM8580_DAC_CONTROL4, 4, 5, 1, 0), 269SOC_DOUBLE("DAC3 Invert Switch", WM8580_DAC_CONTROL4, 4, 5, 1, 0),
270 270
271SOC_SINGLE("DAC ZC Switch", WM8580_DAC_CONTROL5, 5, 1, 0), 271SOC_SINGLE("DAC ZC Switch", WM8580_DAC_CONTROL5, 5, 1, 0),
272SOC_SINGLE("DAC1 Switch", WM8580_DAC_CONTROL5, 0, 1, 0), 272SOC_SINGLE("DAC1 Switch", WM8580_DAC_CONTROL5, 0, 1, 1),
273SOC_SINGLE("DAC2 Switch", WM8580_DAC_CONTROL5, 1, 1, 0), 273SOC_SINGLE("DAC2 Switch", WM8580_DAC_CONTROL5, 1, 1, 1),
274SOC_SINGLE("DAC3 Switch", WM8580_DAC_CONTROL5, 2, 1, 0), 274SOC_SINGLE("DAC3 Switch", WM8580_DAC_CONTROL5, 2, 1, 1),
275 275
276SOC_DOUBLE("ADC Mute Switch", WM8580_ADC_CONTROL1, 0, 1, 1, 0), 276SOC_DOUBLE("ADC Mute Switch", WM8580_ADC_CONTROL1, 0, 1, 1, 0),
277SOC_SINGLE("ADC High-Pass Filter Switch", WM8580_ADC_CONTROL1, 4, 1, 0), 277SOC_SINGLE("ADC High-Pass Filter Switch", WM8580_ADC_CONTROL1, 4, 1, 0),
diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c
index effb14eee7d..e2dba07f026 100644
--- a/sound/soc/codecs/wm8711.c
+++ b/sound/soc/codecs/wm8711.c
@@ -439,7 +439,8 @@ static int wm8711_register(struct wm8711_priv *wm8711,
439 439
440 if (wm8711_codec) { 440 if (wm8711_codec) {
441 dev_err(codec->dev, "Another WM8711 is registered\n"); 441 dev_err(codec->dev, "Another WM8711 is registered\n");
442 return -EINVAL; 442 ret = -EINVAL;
443 goto err;
443 } 444 }
444 445
445 mutex_init(&codec->mutex); 446 mutex_init(&codec->mutex);
diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c
new file mode 100644
index 00000000000..b9ea8904ad4
--- /dev/null
+++ b/sound/soc/codecs/wm8741.c
@@ -0,0 +1,579 @@
1/*
2 * wm8741.c -- WM8741 ALSA SoC Audio driver
3 *
4 * Copyright 2010 Wolfson Microelectronics plc
5 *
6 * Author: Ian Lartey <ian@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 <linux/slab.h>
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/initval.h>
29#include <sound/tlv.h>
30
31#include "wm8741.h"
32
33static struct snd_soc_codec *wm8741_codec;
34struct snd_soc_codec_device soc_codec_dev_wm8741;
35
36#define WM8741_NUM_SUPPLIES 2
37static const char *wm8741_supply_names[WM8741_NUM_SUPPLIES] = {
38 "AVDD",
39 "DVDD",
40};
41
42#define WM8741_NUM_RATES 4
43
44/* codec private data */
45struct wm8741_priv {
46 struct snd_soc_codec codec;
47 u16 reg_cache[WM8741_REGISTER_COUNT];
48 struct regulator_bulk_data supplies[WM8741_NUM_SUPPLIES];
49 unsigned int sysclk;
50 unsigned int rate_constraint_list[WM8741_NUM_RATES];
51 struct snd_pcm_hw_constraint_list rate_constraint;
52};
53
54static const u16 wm8741_reg_defaults[WM8741_REGISTER_COUNT] = {
55 0x0000, /* R0 - DACLLSB Attenuation */
56 0x0000, /* R1 - DACLMSB Attenuation */
57 0x0000, /* R2 - DACRLSB Attenuation */
58 0x0000, /* R3 - DACRMSB Attenuation */
59 0x0000, /* R4 - Volume Control */
60 0x000A, /* R5 - Format Control */
61 0x0000, /* R6 - Filter Control */
62 0x0000, /* R7 - Mode Control 1 */
63 0x0002, /* R8 - Mode Control 2 */
64 0x0000, /* R9 - Reset */
65 0x0002, /* R32 - ADDITONAL_CONTROL_1 */
66};
67
68
69static int wm8741_reset(struct snd_soc_codec *codec)
70{
71 return snd_soc_write(codec, WM8741_RESET, 0);
72}
73
74static const DECLARE_TLV_DB_SCALE(dac_tlv_fine, -12700, 13, 0);
75static const DECLARE_TLV_DB_SCALE(dac_tlv, -12700, 400, 0);
76
77static const struct snd_kcontrol_new wm8741_snd_controls[] = {
78SOC_DOUBLE_R_TLV("Fine Playback Volume", WM8741_DACLLSB_ATTENUATION,
79 WM8741_DACRLSB_ATTENUATION, 1, 255, 1, dac_tlv_fine),
80SOC_DOUBLE_R_TLV("Playback Volume", WM8741_DACLMSB_ATTENUATION,
81 WM8741_DACRMSB_ATTENUATION, 0, 511, 1, dac_tlv),
82};
83
84static const struct snd_soc_dapm_widget wm8741_dapm_widgets[] = {
85SND_SOC_DAPM_DAC("DACL", "Playback", SND_SOC_NOPM, 0, 0),
86SND_SOC_DAPM_DAC("DACR", "Playback", SND_SOC_NOPM, 0, 0),
87SND_SOC_DAPM_OUTPUT("VOUTLP"),
88SND_SOC_DAPM_OUTPUT("VOUTLN"),
89SND_SOC_DAPM_OUTPUT("VOUTRP"),
90SND_SOC_DAPM_OUTPUT("VOUTRN"),
91};
92
93static const struct snd_soc_dapm_route intercon[] = {
94 { "VOUTLP", NULL, "DACL" },
95 { "VOUTLN", NULL, "DACL" },
96 { "VOUTRP", NULL, "DACR" },
97 { "VOUTRN", NULL, "DACR" },
98};
99
100static int wm8741_add_widgets(struct snd_soc_codec *codec)
101{
102 snd_soc_dapm_new_controls(codec, wm8741_dapm_widgets,
103 ARRAY_SIZE(wm8741_dapm_widgets));
104
105 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
106
107 return 0;
108}
109
110static struct {
111 int value;
112 int ratio;
113} lrclk_ratios[WM8741_NUM_RATES] = {
114 { 1, 256 },
115 { 2, 384 },
116 { 3, 512 },
117 { 4, 768 },
118};
119
120
121static int wm8741_startup(struct snd_pcm_substream *substream,
122 struct snd_soc_dai *dai)
123{
124 struct snd_soc_codec *codec = dai->codec;
125 struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
126
127 /* The set of sample rates that can be supported depends on the
128 * MCLK supplied to the CODEC - enforce this.
129 */
130 if (!wm8741->sysclk) {
131 dev_err(codec->dev,
132 "No MCLK configured, call set_sysclk() on init\n");
133 return -EINVAL;
134 }
135
136 snd_pcm_hw_constraint_list(substream->runtime, 0,
137 SNDRV_PCM_HW_PARAM_RATE,
138 &wm8741->rate_constraint);
139
140 return 0;
141}
142
143static int wm8741_hw_params(struct snd_pcm_substream *substream,
144 struct snd_pcm_hw_params *params,
145 struct snd_soc_dai *dai)
146{
147 struct snd_soc_pcm_runtime *rtd = substream->private_data;
148 struct snd_soc_device *socdev = rtd->socdev;
149 struct snd_soc_codec *codec = socdev->card->codec;
150 struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
151 u16 iface = snd_soc_read(codec, WM8741_FORMAT_CONTROL) & 0x1FC;
152 int i;
153
154 /* Find a supported LRCLK ratio */
155 for (i = 0; i < ARRAY_SIZE(lrclk_ratios); i++) {
156 if (wm8741->sysclk / params_rate(params) ==
157 lrclk_ratios[i].ratio)
158 break;
159 }
160
161 /* Should never happen, should be handled by constraints */
162 if (i == ARRAY_SIZE(lrclk_ratios)) {
163 dev_err(codec->dev, "MCLK/fs ratio %d unsupported\n",
164 wm8741->sysclk / params_rate(params));
165 return -EINVAL;
166 }
167
168 /* bit size */
169 switch (params_format(params)) {
170 case SNDRV_PCM_FORMAT_S16_LE:
171 break;
172 case SNDRV_PCM_FORMAT_S20_3LE:
173 iface |= 0x0001;
174 break;
175 case SNDRV_PCM_FORMAT_S24_LE:
176 iface |= 0x0002;
177 break;
178 case SNDRV_PCM_FORMAT_S32_LE:
179 iface |= 0x0003;
180 break;
181 default:
182 dev_dbg(codec->dev, "wm8741_hw_params: Unsupported bit size param = %d",
183 params_format(params));
184 return -EINVAL;
185 }
186
187 dev_dbg(codec->dev, "wm8741_hw_params: bit size param = %d",
188 params_format(params));
189
190 snd_soc_write(codec, WM8741_FORMAT_CONTROL, iface);
191 return 0;
192}
193
194static int wm8741_set_dai_sysclk(struct snd_soc_dai *codec_dai,
195 int clk_id, unsigned int freq, int dir)
196{
197 struct snd_soc_codec *codec = codec_dai->codec;
198 struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
199 unsigned int val;
200 int i;
201
202 dev_dbg(codec->dev, "wm8741_set_dai_sysclk info: freq=%dHz\n", freq);
203
204 wm8741->sysclk = freq;
205
206 wm8741->rate_constraint.count = 0;
207
208 for (i = 0; i < ARRAY_SIZE(lrclk_ratios); i++) {
209 dev_dbg(codec->dev, "index = %d, ratio = %d, freq = %d",
210 i, lrclk_ratios[i].ratio, freq);
211
212 val = freq / lrclk_ratios[i].ratio;
213 /* Check that it's a standard rate since core can't
214 * cope with others and having the odd rates confuses
215 * constraint matching.
216 */
217 switch (val) {
218 case 32000:
219 case 44100:
220 case 48000:
221 case 64000:
222 case 88200:
223 case 96000:
224 dev_dbg(codec->dev, "Supported sample rate: %dHz\n",
225 val);
226 wm8741->rate_constraint_list[i] = val;
227 wm8741->rate_constraint.count++;
228 break;
229 default:
230 dev_dbg(codec->dev, "Skipping sample rate: %dHz\n",
231 val);
232 }
233 }
234
235 /* Need at least one supported rate... */
236 if (wm8741->rate_constraint.count == 0)
237 return -EINVAL;
238
239 return 0;
240}
241
242static int wm8741_set_dai_fmt(struct snd_soc_dai *codec_dai,
243 unsigned int fmt)
244{
245 struct snd_soc_codec *codec = codec_dai->codec;
246 u16 iface = snd_soc_read(codec, WM8741_FORMAT_CONTROL) & 0x1C3;
247
248 /* check master/slave audio interface */
249 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
250 case SND_SOC_DAIFMT_CBS_CFS:
251 break;
252 default:
253 return -EINVAL;
254 }
255
256 /* interface format */
257 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
258 case SND_SOC_DAIFMT_I2S:
259 iface |= 0x0008;
260 break;
261 case SND_SOC_DAIFMT_RIGHT_J:
262 break;
263 case SND_SOC_DAIFMT_LEFT_J:
264 iface |= 0x0004;
265 break;
266 case SND_SOC_DAIFMT_DSP_A:
267 iface |= 0x0003;
268 break;
269 case SND_SOC_DAIFMT_DSP_B:
270 iface |= 0x0013;
271 break;
272 default:
273 return -EINVAL;
274 }
275
276 /* clock inversion */
277 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
278 case SND_SOC_DAIFMT_NB_NF:
279 break;
280 case SND_SOC_DAIFMT_IB_IF:
281 iface |= 0x0010;
282 break;
283 case SND_SOC_DAIFMT_IB_NF:
284 iface |= 0x0020;
285 break;
286 case SND_SOC_DAIFMT_NB_IF:
287 iface |= 0x0030;
288 break;
289 default:
290 return -EINVAL;
291 }
292
293
294 dev_dbg(codec->dev, "wm8741_set_dai_fmt: Format=%x, Clock Inv=%x\n",
295 fmt & SND_SOC_DAIFMT_FORMAT_MASK,
296 ((fmt & SND_SOC_DAIFMT_INV_MASK)));
297
298 snd_soc_write(codec, WM8741_FORMAT_CONTROL, iface);
299 return 0;
300}
301
302#define WM8741_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
303 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | \
304 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | \
305 SNDRV_PCM_RATE_192000)
306
307#define WM8741_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
308 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
309
310static struct snd_soc_dai_ops wm8741_dai_ops = {
311 .startup = wm8741_startup,
312 .hw_params = wm8741_hw_params,
313 .set_sysclk = wm8741_set_dai_sysclk,
314 .set_fmt = wm8741_set_dai_fmt,
315};
316
317struct snd_soc_dai wm8741_dai = {
318 .name = "WM8741",
319 .playback = {
320 .stream_name = "Playback",
321 .channels_min = 2, /* Mono modes not yet supported */
322 .channels_max = 2,
323 .rates = WM8741_RATES,
324 .formats = WM8741_FORMATS,
325 },
326 .ops = &wm8741_dai_ops,
327};
328EXPORT_SYMBOL_GPL(wm8741_dai);
329
330#ifdef CONFIG_PM
331static int wm8741_resume(struct platform_device *pdev)
332{
333 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
334 struct snd_soc_codec *codec = socdev->card->codec;
335 u16 *cache = codec->reg_cache;
336 int i;
337
338 /* RESTORE REG Cache */
339 for (i = 0; i < WM8741_REGISTER_COUNT; i++) {
340 if (cache[i] == wm8741_reg_defaults[i] || WM8741_RESET == i)
341 continue;
342 snd_soc_write(codec, i, cache[i]);
343 }
344 return 0;
345}
346#else
347#define wm8741_suspend NULL
348#define wm8741_resume NULL
349#endif
350
351static int wm8741_probe(struct platform_device *pdev)
352{
353 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
354 struct snd_soc_codec *codec;
355 int ret = 0;
356
357 if (wm8741_codec == NULL) {
358 dev_err(&pdev->dev, "Codec device not registered\n");
359 return -ENODEV;
360 }
361
362 socdev->card->codec = wm8741_codec;
363 codec = wm8741_codec;
364
365 /* register pcms */
366 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
367 if (ret < 0) {
368 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
369 goto pcm_err;
370 }
371
372 snd_soc_add_controls(codec, wm8741_snd_controls,
373 ARRAY_SIZE(wm8741_snd_controls));
374 wm8741_add_widgets(codec);
375
376 return ret;
377
378pcm_err:
379 return ret;
380}
381
382static int wm8741_remove(struct platform_device *pdev)
383{
384 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
385
386 snd_soc_free_pcms(socdev);
387 snd_soc_dapm_free(socdev);
388
389 return 0;
390}
391
392struct snd_soc_codec_device soc_codec_dev_wm8741 = {
393 .probe = wm8741_probe,
394 .remove = wm8741_remove,
395 .resume = wm8741_resume,
396};
397EXPORT_SYMBOL_GPL(soc_codec_dev_wm8741);
398
399static int wm8741_register(struct wm8741_priv *wm8741,
400 enum snd_soc_control_type control)
401{
402 int ret;
403 struct snd_soc_codec *codec = &wm8741->codec;
404 int i;
405
406 if (wm8741_codec) {
407 dev_err(codec->dev, "Another WM8741 is registered\n");
408 return -EINVAL;
409 }
410
411 mutex_init(&codec->mutex);
412 INIT_LIST_HEAD(&codec->dapm_widgets);
413 INIT_LIST_HEAD(&codec->dapm_paths);
414
415 snd_soc_codec_set_drvdata(codec, wm8741);
416 codec->name = "WM8741";
417 codec->owner = THIS_MODULE;
418 codec->bias_level = SND_SOC_BIAS_OFF;
419 codec->set_bias_level = NULL;
420 codec->dai = &wm8741_dai;
421 codec->num_dai = 1;
422 codec->reg_cache_size = WM8741_REGISTER_COUNT;
423 codec->reg_cache = &wm8741->reg_cache;
424
425 wm8741->rate_constraint.list = &wm8741->rate_constraint_list[0];
426 wm8741->rate_constraint.count =
427 ARRAY_SIZE(wm8741->rate_constraint_list);
428
429 memcpy(codec->reg_cache, wm8741_reg_defaults,
430 sizeof(wm8741->reg_cache));
431
432 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
433 if (ret != 0) {
434 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
435 goto err;
436 }
437
438 for (i = 0; i < ARRAY_SIZE(wm8741->supplies); i++)
439 wm8741->supplies[i].supply = wm8741_supply_names[i];
440
441 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8741->supplies),
442 wm8741->supplies);
443 if (ret != 0) {
444 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
445 goto err;
446 }
447
448 ret = regulator_bulk_enable(ARRAY_SIZE(wm8741->supplies),
449 wm8741->supplies);
450 if (ret != 0) {
451 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
452 goto err_get;
453 }
454
455 ret = wm8741_reset(codec);
456 if (ret < 0) {
457 dev_err(codec->dev, "Failed to issue reset\n");
458 goto err_enable;
459 }
460
461 wm8741_dai.dev = codec->dev;
462
463 /* Change some default settings - latch VU */
464 wm8741->reg_cache[WM8741_DACLLSB_ATTENUATION] |= WM8741_UPDATELL;
465 wm8741->reg_cache[WM8741_DACLMSB_ATTENUATION] |= WM8741_UPDATELM;
466 wm8741->reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERL;
467 wm8741->reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERM;
468
469 wm8741_codec = codec;
470
471 ret = snd_soc_register_codec(codec);
472 if (ret != 0) {
473 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
474 return ret;
475 }
476
477 ret = snd_soc_register_dai(&wm8741_dai);
478 if (ret != 0) {
479 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
480 snd_soc_unregister_codec(codec);
481 return ret;
482 }
483
484 dev_dbg(codec->dev, "Successful registration\n");
485 return 0;
486
487err_enable:
488 regulator_bulk_disable(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
489
490err_get:
491 regulator_bulk_free(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
492
493err:
494 kfree(wm8741);
495 return ret;
496}
497
498static void wm8741_unregister(struct wm8741_priv *wm8741)
499{
500 regulator_bulk_free(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
501
502 snd_soc_unregister_dai(&wm8741_dai);
503 snd_soc_unregister_codec(&wm8741->codec);
504 kfree(wm8741);
505 wm8741_codec = NULL;
506}
507
508#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
509static __devinit int wm8741_i2c_probe(struct i2c_client *i2c,
510 const struct i2c_device_id *id)
511{
512 struct wm8741_priv *wm8741;
513 struct snd_soc_codec *codec;
514
515 wm8741 = kzalloc(sizeof(struct wm8741_priv), GFP_KERNEL);
516 if (wm8741 == NULL)
517 return -ENOMEM;
518
519 codec = &wm8741->codec;
520 codec->hw_write = (hw_write_t)i2c_master_send;
521
522 i2c_set_clientdata(i2c, wm8741);
523 codec->control_data = i2c;
524
525 codec->dev = &i2c->dev;
526
527 return wm8741_register(wm8741, SND_SOC_I2C);
528}
529
530static __devexit int wm8741_i2c_remove(struct i2c_client *client)
531{
532 struct wm8741_priv *wm8741 = i2c_get_clientdata(client);
533 wm8741_unregister(wm8741);
534 return 0;
535}
536
537static const struct i2c_device_id wm8741_i2c_id[] = {
538 { "wm8741", 0 },
539 { }
540};
541MODULE_DEVICE_TABLE(i2c, wm8741_i2c_id);
542
543
544static struct i2c_driver wm8741_i2c_driver = {
545 .driver = {
546 .name = "WM8741",
547 .owner = THIS_MODULE,
548 },
549 .probe = wm8741_i2c_probe,
550 .remove = __devexit_p(wm8741_i2c_remove),
551 .id_table = wm8741_i2c_id,
552};
553#endif
554
555static int __init wm8741_modinit(void)
556{
557 int ret;
558#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
559 ret = i2c_add_driver(&wm8741_i2c_driver);
560 if (ret != 0) {
561 printk(KERN_ERR "Failed to register WM8741 I2C driver: %d\n",
562 ret);
563 }
564#endif
565 return 0;
566}
567module_init(wm8741_modinit);
568
569static void __exit wm8741_exit(void)
570{
571#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
572 i2c_del_driver(&wm8741_i2c_driver);
573#endif
574}
575module_exit(wm8741_exit);
576
577MODULE_DESCRIPTION("ASoC WM8741 driver");
578MODULE_AUTHOR("Ian Lartey <ian@opensource.wolfsonmicro.com>");
579MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8741.h b/sound/soc/codecs/wm8741.h
new file mode 100644
index 00000000000..fdef6ecd1f6
--- /dev/null
+++ b/sound/soc/codecs/wm8741.h
@@ -0,0 +1,214 @@
1/*
2 * wm8741.h -- WM8423 ASoC driver
3 *
4 * Copyright 2010 Wolfson Microelectronics, plc
5 *
6 * Author: Ian Lartey <ian@opensource.wolfsonmicro.com>
7 *
8 * Based on wm8753.h
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 _WM8741_H
16#define _WM8741_H
17
18/*
19 * Register values.
20 */
21#define WM8741_DACLLSB_ATTENUATION 0x00
22#define WM8741_DACLMSB_ATTENUATION 0x01
23#define WM8741_DACRLSB_ATTENUATION 0x02
24#define WM8741_DACRMSB_ATTENUATION 0x03
25#define WM8741_VOLUME_CONTROL 0x04
26#define WM8741_FORMAT_CONTROL 0x05
27#define WM8741_FILTER_CONTROL 0x06
28#define WM8741_MODE_CONTROL_1 0x07
29#define WM8741_MODE_CONTROL_2 0x08
30#define WM8741_RESET 0x09
31#define WM8741_ADDITIONAL_CONTROL_1 0x20
32
33#define WM8741_REGISTER_COUNT 11
34#define WM8741_MAX_REGISTER 0x20
35
36/*
37 * Field Definitions.
38 */
39
40/*
41 * R0 (0x00) - DACLLSB_ATTENUATION
42 */
43#define WM8741_UPDATELL 0x0020 /* UPDATELL */
44#define WM8741_UPDATELL_MASK 0x0020 /* UPDATELL */
45#define WM8741_UPDATELL_SHIFT 5 /* UPDATELL */
46#define WM8741_UPDATELL_WIDTH 1 /* UPDATELL */
47#define WM8741_LAT_4_0_MASK 0x001F /* LAT[4:0] - [4:0] */
48#define WM8741_LAT_4_0_SHIFT 0 /* LAT[4:0] - [4:0] */
49#define WM8741_LAT_4_0_WIDTH 5 /* LAT[4:0] - [4:0] */
50
51/*
52 * R1 (0x01) - DACLMSB_ATTENUATION
53 */
54#define WM8741_UPDATELM 0x0020 /* UPDATELM */
55#define WM8741_UPDATELM_MASK 0x0020 /* UPDATELM */
56#define WM8741_UPDATELM_SHIFT 5 /* UPDATELM */
57#define WM8741_UPDATELM_WIDTH 1 /* UPDATELM */
58#define WM8741_LAT_9_5_0_MASK 0x001F /* LAT[9:5] - [4:0] */
59#define WM8741_LAT_9_5_0_SHIFT 0 /* LAT[9:5] - [4:0] */
60#define WM8741_LAT_9_5_0_WIDTH 5 /* LAT[9:5] - [4:0] */
61
62/*
63 * R2 (0x02) - DACRLSB_ATTENUATION
64 */
65#define WM8741_UPDATERL 0x0020 /* UPDATERL */
66#define WM8741_UPDATERL_MASK 0x0020 /* UPDATERL */
67#define WM8741_UPDATERL_SHIFT 5 /* UPDATERL */
68#define WM8741_UPDATERL_WIDTH 1 /* UPDATERL */
69#define WM8741_RAT_4_0_MASK 0x001F /* RAT[4:0] - [4:0] */
70#define WM8741_RAT_4_0_SHIFT 0 /* RAT[4:0] - [4:0] */
71#define WM8741_RAT_4_0_WIDTH 5 /* RAT[4:0] - [4:0] */
72
73/*
74 * R3 (0x03) - DACRMSB_ATTENUATION
75 */
76#define WM8741_UPDATERM 0x0020 /* UPDATERM */
77#define WM8741_UPDATERM_MASK 0x0020 /* UPDATERM */
78#define WM8741_UPDATERM_SHIFT 5 /* UPDATERM */
79#define WM8741_UPDATERM_WIDTH 1 /* UPDATERM */
80#define WM8741_RAT_9_5_0_MASK 0x001F /* RAT[9:5] - [4:0] */
81#define WM8741_RAT_9_5_0_SHIFT 0 /* RAT[9:5] - [4:0] */
82#define WM8741_RAT_9_5_0_WIDTH 5 /* RAT[9:5] - [4:0] */
83
84/*
85 * R4 (0x04) - VOLUME_CONTROL
86 */
87#define WM8741_AMUTE 0x0080 /* AMUTE */
88#define WM8741_AMUTE_MASK 0x0080 /* AMUTE */
89#define WM8741_AMUTE_SHIFT 7 /* AMUTE */
90#define WM8741_AMUTE_WIDTH 1 /* AMUTE */
91#define WM8741_ZFLAG_MASK 0x0060 /* ZFLAG - [6:5] */
92#define WM8741_ZFLAG_SHIFT 5 /* ZFLAG - [6:5] */
93#define WM8741_ZFLAG_WIDTH 2 /* ZFLAG - [6:5] */
94#define WM8741_IZD 0x0010 /* IZD */
95#define WM8741_IZD_MASK 0x0010 /* IZD */
96#define WM8741_IZD_SHIFT 4 /* IZD */
97#define WM8741_IZD_WIDTH 1 /* IZD */
98#define WM8741_SOFT 0x0008 /* SOFT MUTE */
99#define WM8741_SOFT_MASK 0x0008 /* SOFT MUTE */
100#define WM8741_SOFT_SHIFT 3 /* SOFT MUTE */
101#define WM8741_SOFT_WIDTH 1 /* SOFT MUTE */
102#define WM8741_ATC 0x0004 /* ATC */
103#define WM8741_ATC_MASK 0x0004 /* ATC */
104#define WM8741_ATC_SHIFT 2 /* ATC */
105#define WM8741_ATC_WIDTH 1 /* ATC */
106#define WM8741_ATT2DB 0x0002 /* ATT2DB */
107#define WM8741_ATT2DB_MASK 0x0002 /* ATT2DB */
108#define WM8741_ATT2DB_SHIFT 1 /* ATT2DB */
109#define WM8741_ATT2DB_WIDTH 1 /* ATT2DB */
110#define WM8741_VOL_RAMP 0x0001 /* VOL_RAMP */
111#define WM8741_VOL_RAMP_MASK 0x0001 /* VOL_RAMP */
112#define WM8741_VOL_RAMP_SHIFT 0 /* VOL_RAMP */
113#define WM8741_VOL_RAMP_WIDTH 1 /* VOL_RAMP */
114
115/*
116 * R5 (0x05) - FORMAT_CONTROL
117 */
118#define WM8741_PWDN 0x0080 /* PWDN */
119#define WM8741_PWDN_MASK 0x0080 /* PWDN */
120#define WM8741_PWDN_SHIFT 7 /* PWDN */
121#define WM8741_PWDN_WIDTH 1 /* PWDN */
122#define WM8741_REV 0x0040 /* REV */
123#define WM8741_REV_MASK 0x0040 /* REV */
124#define WM8741_REV_SHIFT 6 /* REV */
125#define WM8741_REV_WIDTH 1 /* REV */
126#define WM8741_BCP 0x0020 /* BCP */
127#define WM8741_BCP_MASK 0x0020 /* BCP */
128#define WM8741_BCP_SHIFT 5 /* BCP */
129#define WM8741_BCP_WIDTH 1 /* BCP */
130#define WM8741_LRP 0x0010 /* LRP */
131#define WM8741_LRP_MASK 0x0010 /* LRP */
132#define WM8741_LRP_SHIFT 4 /* LRP */
133#define WM8741_LRP_WIDTH 1 /* LRP */
134#define WM8741_FMT_MASK 0x000C /* FMT - [3:2] */
135#define WM8741_FMT_SHIFT 2 /* FMT - [3:2] */
136#define WM8741_FMT_WIDTH 2 /* FMT - [3:2] */
137#define WM8741_IWL_MASK 0x0003 /* IWL - [1:0] */
138#define WM8741_IWL_SHIFT 0 /* IWL - [1:0] */
139#define WM8741_IWL_WIDTH 2 /* IWL - [1:0] */
140
141/*
142 * R6 (0x06) - FILTER_CONTROL
143 */
144#define WM8741_ZFLAG_HI 0x0080 /* ZFLAG_HI */
145#define WM8741_ZFLAG_HI_MASK 0x0080 /* ZFLAG_HI */
146#define WM8741_ZFLAG_HI_SHIFT 7 /* ZFLAG_HI */
147#define WM8741_ZFLAG_HI_WIDTH 1 /* ZFLAG_HI */
148#define WM8741_DEEMPH_MASK 0x0060 /* DEEMPH - [6:5] */
149#define WM8741_DEEMPH_SHIFT 5 /* DEEMPH - [6:5] */
150#define WM8741_DEEMPH_WIDTH 2 /* DEEMPH - [6:5] */
151#define WM8741_DSDFILT_MASK 0x0018 /* DSDFILT - [4:3] */
152#define WM8741_DSDFILT_SHIFT 3 /* DSDFILT - [4:3] */
153#define WM8741_DSDFILT_WIDTH 2 /* DSDFILT - [4:3] */
154#define WM8741_FIRSEL_MASK 0x0007 /* FIRSEL - [2:0] */
155#define WM8741_FIRSEL_SHIFT 0 /* FIRSEL - [2:0] */
156#define WM8741_FIRSEL_WIDTH 3 /* FIRSEL - [2:0] */
157
158/*
159 * R7 (0x07) - MODE_CONTROL_1
160 */
161#define WM8741_MODE8X 0x0080 /* MODE8X */
162#define WM8741_MODE8X_MASK 0x0080 /* MODE8X */
163#define WM8741_MODE8X_SHIFT 7 /* MODE8X */
164#define WM8741_MODE8X_WIDTH 1 /* MODE8X */
165#define WM8741_OSR_MASK 0x0060 /* OSR - [6:5] */
166#define WM8741_OSR_SHIFT 5 /* OSR - [6:5] */
167#define WM8741_OSR_WIDTH 2 /* OSR - [6:5] */
168#define WM8741_SR_MASK 0x001C /* SR - [4:2] */
169#define WM8741_SR_SHIFT 2 /* SR - [4:2] */
170#define WM8741_SR_WIDTH 3 /* SR - [4:2] */
171#define WM8741_MODESEL_MASK 0x0003 /* MODESEL - [1:0] */
172#define WM8741_MODESEL_SHIFT 0 /* MODESEL - [1:0] */
173#define WM8741_MODESEL_WIDTH 2 /* MODESEL - [1:0] */
174
175/*
176 * R8 (0x08) - MODE_CONTROL_2
177 */
178#define WM8741_DSD_GAIN 0x0040 /* DSD_GAIN */
179#define WM8741_DSD_GAIN_MASK 0x0040 /* DSD_GAIN */
180#define WM8741_DSD_GAIN_SHIFT 6 /* DSD_GAIN */
181#define WM8741_DSD_GAIN_WIDTH 1 /* DSD_GAIN */
182#define WM8741_SDOUT 0x0020 /* SDOUT */
183#define WM8741_SDOUT_MASK 0x0020 /* SDOUT */
184#define WM8741_SDOUT_SHIFT 5 /* SDOUT */
185#define WM8741_SDOUT_WIDTH 1 /* SDOUT */
186#define WM8741_DOUT 0x0010 /* DOUT */
187#define WM8741_DOUT_MASK 0x0010 /* DOUT */
188#define WM8741_DOUT_SHIFT 4 /* DOUT */
189#define WM8741_DOUT_WIDTH 1 /* DOUT */
190#define WM8741_DIFF_MASK 0x000C /* DIFF - [3:2] */
191#define WM8741_DIFF_SHIFT 2 /* DIFF - [3:2] */
192#define WM8741_DIFF_WIDTH 2 /* DIFF - [3:2] */
193#define WM8741_DITHER_MASK 0x0003 /* DITHER - [1:0] */
194#define WM8741_DITHER_SHIFT 0 /* DITHER - [1:0] */
195#define WM8741_DITHER_WIDTH 2 /* DITHER - [1:0] */
196
197/*
198 * R32 (0x20) - ADDITONAL_CONTROL_1
199 */
200#define WM8741_DSD_LEVEL 0x0002 /* DSD_LEVEL */
201#define WM8741_DSD_LEVEL_MASK 0x0002 /* DSD_LEVEL */
202#define WM8741_DSD_LEVEL_SHIFT 1 /* DSD_LEVEL */
203#define WM8741_DSD_LEVEL_WIDTH 1 /* DSD_LEVEL */
204#define WM8741_DSD_NO_NOTCH 0x0001 /* DSD_NO_NOTCH */
205#define WM8741_DSD_NO_NOTCH_MASK 0x0001 /* DSD_NO_NOTCH */
206#define WM8741_DSD_NO_NOTCH_SHIFT 0 /* DSD_NO_NOTCH */
207#define WM8741_DSD_NO_NOTCH_WIDTH 1 /* DSD_NO_NOTCH */
208
209#define WM8741_SYSCLK 0
210
211extern struct snd_soc_dai wm8741_dai;
212extern struct snd_soc_codec_device soc_codec_dev_wm8741;
213
214#endif
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
index 9407e193fcc..e2c05e3e323 100644
--- a/sound/soc/codecs/wm8750.c
+++ b/sound/soc/codecs/wm8750.c
@@ -884,6 +884,7 @@ static int wm8750_i2c_remove(struct i2c_client *client)
884 884
885static const struct i2c_device_id wm8750_i2c_id[] = { 885static const struct i2c_device_id wm8750_i2c_id[] = {
886 { "wm8750", 0 }, 886 { "wm8750", 0 },
887 { "wm8987", 0 }, /* WM8987 is register compatible with WM8750 */
887 { } 888 { }
888}; 889};
889MODULE_DEVICE_TABLE(i2c, wm8750_i2c_id); 890MODULE_DEVICE_TABLE(i2c, wm8750_i2c_id);
@@ -925,14 +926,22 @@ static int __devexit wm8750_spi_remove(struct spi_device *spi)
925 return 0; 926 return 0;
926} 927}
927 928
929static const struct spi_device_id wm8750_spi_id[] = {
930 { "wm8750", 0 },
931 { "wm8987", 0 },
932 { }
933};
934MODULE_DEVICE_TABLE(spi, wm8750_spi_id);
935
928static struct spi_driver wm8750_spi_driver = { 936static struct spi_driver wm8750_spi_driver = {
929 .driver = { 937 .driver = {
930 .name = "wm8750", 938 .name = "WM8750 SPI Codec",
931 .bus = &spi_bus_type, 939 .bus = &spi_bus_type,
932 .owner = THIS_MODULE, 940 .owner = THIS_MODULE,
933 }, 941 },
934 .probe = wm8750_spi_probe, 942 .probe = wm8750_spi_probe,
935 .remove = __devexit_p(wm8750_spi_remove), 943 .remove = __devexit_p(wm8750_spi_remove),
944 .id_table = wm8750_spi_id,
936}; 945};
937#endif 946#endif
938 947
diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c
index 4e212ed62ea..f8154e66152 100644
--- a/sound/soc/codecs/wm8776.c
+++ b/sound/soc/codecs/wm8776.c
@@ -178,13 +178,6 @@ static int wm8776_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
178 case SND_SOC_DAIFMT_LEFT_J: 178 case SND_SOC_DAIFMT_LEFT_J:
179 iface |= 0x0001; 179 iface |= 0x0001;
180 break; 180 break;
181 /* FIXME: CHECK A/B */
182 case SND_SOC_DAIFMT_DSP_A:
183 iface |= 0x0003;
184 break;
185 case SND_SOC_DAIFMT_DSP_B:
186 iface |= 0x0007;
187 break;
188 default: 181 default:
189 return -EINVAL; 182 return -EINVAL;
190 } 183 }
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index 87f14f8675f..f7dcabf6283 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -2433,7 +2433,8 @@ static int wm8904_register(struct wm8904_priv *wm8904,
2433 2433
2434 if (wm8904_codec) { 2434 if (wm8904_codec) {
2435 dev_err(codec->dev, "Another WM8904 is registered\n"); 2435 dev_err(codec->dev, "Another WM8904 is registered\n");
2436 return -EINVAL; 2436 ret = -EINVAL;
2437 goto err;
2437 } 2438 }
2438 2439
2439 mutex_init(&codec->mutex); 2440 mutex_init(&codec->mutex);
@@ -2462,7 +2463,8 @@ static int wm8904_register(struct wm8904_priv *wm8904,
2462 default: 2463 default:
2463 dev_err(codec->dev, "Unknown device type %d\n", 2464 dev_err(codec->dev, "Unknown device type %d\n",
2464 wm8904->devtype); 2465 wm8904->devtype);
2465 return -EINVAL; 2466 ret = -EINVAL;
2467 goto err;
2466 } 2468 }
2467 2469
2468 memcpy(codec->reg_cache, wm8904_reg, sizeof(wm8904_reg)); 2470 memcpy(codec->reg_cache, wm8904_reg, sizeof(wm8904_reg));
@@ -2566,18 +2568,19 @@ static int wm8904_register(struct wm8904_priv *wm8904,
2566 ret = snd_soc_register_codec(codec); 2568 ret = snd_soc_register_codec(codec);
2567 if (ret != 0) { 2569 if (ret != 0) {
2568 dev_err(codec->dev, "Failed to register codec: %d\n", ret); 2570 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
2569 return ret; 2571 goto err_enable;
2570 } 2572 }
2571 2573
2572 ret = snd_soc_register_dai(&wm8904_dai); 2574 ret = snd_soc_register_dai(&wm8904_dai);
2573 if (ret != 0) { 2575 if (ret != 0) {
2574 dev_err(codec->dev, "Failed to register DAI: %d\n", ret); 2576 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
2575 snd_soc_unregister_codec(codec); 2577 goto err_codec;
2576 return ret;
2577 } 2578 }
2578 2579
2579 return 0; 2580 return 0;
2580 2581
2582err_codec:
2583 snd_soc_unregister_codec(codec);
2581err_enable: 2584err_enable:
2582 regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); 2585 regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2583err_get: 2586err_get:
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c
index e3c4bbfaae2..f0c11138e61 100644
--- a/sound/soc/codecs/wm8940.c
+++ b/sound/soc/codecs/wm8940.c
@@ -845,6 +845,7 @@ static void wm8940_unregister(struct wm8940_priv *wm8940)
845static int wm8940_i2c_probe(struct i2c_client *i2c, 845static int wm8940_i2c_probe(struct i2c_client *i2c,
846 const struct i2c_device_id *id) 846 const struct i2c_device_id *id)
847{ 847{
848 int ret;
848 struct wm8940_priv *wm8940; 849 struct wm8940_priv *wm8940;
849 struct snd_soc_codec *codec; 850 struct snd_soc_codec *codec;
850 851
@@ -858,7 +859,11 @@ static int wm8940_i2c_probe(struct i2c_client *i2c,
858 codec->control_data = i2c; 859 codec->control_data = i2c;
859 codec->dev = &i2c->dev; 860 codec->dev = &i2c->dev;
860 861
861 return wm8940_register(wm8940, SND_SOC_I2C); 862 ret = wm8940_register(wm8940, SND_SOC_I2C);
863 if (ret < 0)
864 kfree(wm8940);
865
866 return ret;
862} 867}
863 868
864static int __devexit wm8940_i2c_remove(struct i2c_client *client) 869static int __devexit wm8940_i2c_remove(struct i2c_client *client)
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c
index fedb76452f1..5f025593d84 100644
--- a/sound/soc/codecs/wm8955.c
+++ b/sound/soc/codecs/wm8955.c
@@ -964,7 +964,8 @@ static int wm8955_register(struct wm8955_priv *wm8955,
964 964
965 if (wm8955_codec) { 965 if (wm8955_codec) {
966 dev_err(codec->dev, "Another WM8955 is registered\n"); 966 dev_err(codec->dev, "Another WM8955 is registered\n");
967 return -EINVAL; 967 ret = -EINVAL;
968 goto err;
968 } 969 }
969 970
970 mutex_init(&codec->mutex); 971 mutex_init(&codec->mutex);
@@ -1047,18 +1048,19 @@ static int wm8955_register(struct wm8955_priv *wm8955,
1047 ret = snd_soc_register_codec(codec); 1048 ret = snd_soc_register_codec(codec);
1048 if (ret != 0) { 1049 if (ret != 0) {
1049 dev_err(codec->dev, "Failed to register codec: %d\n", ret); 1050 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
1050 return ret; 1051 goto err_enable;
1051 } 1052 }
1052 1053
1053 ret = snd_soc_register_dai(&wm8955_dai); 1054 ret = snd_soc_register_dai(&wm8955_dai);
1054 if (ret != 0) { 1055 if (ret != 0) {
1055 dev_err(codec->dev, "Failed to register DAI: %d\n", ret); 1056 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
1056 snd_soc_unregister_codec(codec); 1057 goto err_codec;
1057 return ret;
1058 } 1058 }
1059 1059
1060 return 0; 1060 return 0;
1061 1061
1062err_codec:
1063 snd_soc_unregister_codec(codec);
1062err_enable: 1064err_enable:
1063 regulator_bulk_disable(ARRAY_SIZE(wm8955->supplies), wm8955->supplies); 1065 regulator_bulk_disable(ARRAY_SIZE(wm8955->supplies), wm8955->supplies);
1064err_get: 1066err_get:
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index 7233cc68435..3c6ee61f6c9 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -79,12 +79,13 @@ struct wm8960_priv {
79 struct snd_soc_dapm_widget *lout1; 79 struct snd_soc_dapm_widget *lout1;
80 struct snd_soc_dapm_widget *rout1; 80 struct snd_soc_dapm_widget *rout1;
81 struct snd_soc_dapm_widget *out3; 81 struct snd_soc_dapm_widget *out3;
82 bool deemph;
83 int playback_fs;
82}; 84};
83 85
84#define wm8960_reset(c) snd_soc_write(c, WM8960_RESET, 0) 86#define wm8960_reset(c) snd_soc_write(c, WM8960_RESET, 0)
85 87
86/* enumerated controls */ 88/* enumerated controls */
87static const char *wm8960_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"};
88static const char *wm8960_polarity[] = {"No Inversion", "Left Inverted", 89static const char *wm8960_polarity[] = {"No Inversion", "Left Inverted",
89 "Right Inverted", "Stereo Inversion"}; 90 "Right Inverted", "Stereo Inversion"};
90static const char *wm8960_3d_upper_cutoff[] = {"High", "Low"}; 91static const char *wm8960_3d_upper_cutoff[] = {"High", "Low"};
@@ -93,7 +94,6 @@ static const char *wm8960_alcfunc[] = {"Off", "Right", "Left", "Stereo"};
93static const char *wm8960_alcmode[] = {"ALC", "Limiter"}; 94static const char *wm8960_alcmode[] = {"ALC", "Limiter"};
94 95
95static const struct soc_enum wm8960_enum[] = { 96static const struct soc_enum wm8960_enum[] = {
96 SOC_ENUM_SINGLE(WM8960_DACCTL1, 1, 4, wm8960_deemph),
97 SOC_ENUM_SINGLE(WM8960_DACCTL1, 5, 4, wm8960_polarity), 97 SOC_ENUM_SINGLE(WM8960_DACCTL1, 5, 4, wm8960_polarity),
98 SOC_ENUM_SINGLE(WM8960_DACCTL2, 5, 4, wm8960_polarity), 98 SOC_ENUM_SINGLE(WM8960_DACCTL2, 5, 4, wm8960_polarity),
99 SOC_ENUM_SINGLE(WM8960_3D, 6, 2, wm8960_3d_upper_cutoff), 99 SOC_ENUM_SINGLE(WM8960_3D, 6, 2, wm8960_3d_upper_cutoff),
@@ -102,6 +102,59 @@ static const struct soc_enum wm8960_enum[] = {
102 SOC_ENUM_SINGLE(WM8960_ALC3, 8, 2, wm8960_alcmode), 102 SOC_ENUM_SINGLE(WM8960_ALC3, 8, 2, wm8960_alcmode),
103}; 103};
104 104
105static const int deemph_settings[] = { 0, 32000, 44100, 48000 };
106
107static int wm8960_set_deemph(struct snd_soc_codec *codec)
108{
109 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
110 int val, i, best;
111
112 /* If we're using deemphasis select the nearest available sample
113 * rate.
114 */
115 if (wm8960->deemph) {
116 best = 1;
117 for (i = 2; i < ARRAY_SIZE(deemph_settings); i++) {
118 if (abs(deemph_settings[i] - wm8960->playback_fs) <
119 abs(deemph_settings[best] - wm8960->playback_fs))
120 best = i;
121 }
122
123 val = best << 1;
124 } else {
125 val = 0;
126 }
127
128 dev_dbg(codec->dev, "Set deemphasis %d\n", val);
129
130 return snd_soc_update_bits(codec, WM8960_DACCTL1,
131 0x6, val);
132}
133
134static int wm8960_get_deemph(struct snd_kcontrol *kcontrol,
135 struct snd_ctl_elem_value *ucontrol)
136{
137 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
138 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
139
140 return wm8960->deemph;
141}
142
143static int wm8960_put_deemph(struct snd_kcontrol *kcontrol,
144 struct snd_ctl_elem_value *ucontrol)
145{
146 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
147 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
148 int deemph = ucontrol->value.enumerated.item[0];
149
150 if (deemph > 1)
151 return -EINVAL;
152
153 wm8960->deemph = deemph;
154
155 return wm8960_set_deemph(codec);
156}
157
105static const DECLARE_TLV_DB_SCALE(adc_tlv, -9700, 50, 0); 158static const DECLARE_TLV_DB_SCALE(adc_tlv, -9700, 50, 0);
106static const DECLARE_TLV_DB_SCALE(dac_tlv, -12700, 50, 1); 159static const DECLARE_TLV_DB_SCALE(dac_tlv, -12700, 50, 1);
107static const DECLARE_TLV_DB_SCALE(bypass_tlv, -2100, 300, 0); 160static const DECLARE_TLV_DB_SCALE(bypass_tlv, -2100, 300, 0);
@@ -131,23 +184,24 @@ SOC_SINGLE("Speaker DC Volume", WM8960_CLASSD3, 3, 5, 0),
131SOC_SINGLE("Speaker AC Volume", WM8960_CLASSD3, 0, 5, 0), 184SOC_SINGLE("Speaker AC Volume", WM8960_CLASSD3, 0, 5, 0),
132 185
133SOC_SINGLE("PCM Playback -6dB Switch", WM8960_DACCTL1, 7, 1, 0), 186SOC_SINGLE("PCM Playback -6dB Switch", WM8960_DACCTL1, 7, 1, 0),
134SOC_ENUM("ADC Polarity", wm8960_enum[1]), 187SOC_ENUM("ADC Polarity", wm8960_enum[0]),
135SOC_ENUM("Playback De-emphasis", wm8960_enum[0]),
136SOC_SINGLE("ADC High Pass Filter Switch", WM8960_DACCTL1, 0, 1, 0), 188SOC_SINGLE("ADC High Pass Filter Switch", WM8960_DACCTL1, 0, 1, 0),
137 189
138SOC_ENUM("DAC Polarity", wm8960_enum[2]), 190SOC_ENUM("DAC Polarity", wm8960_enum[2]),
191SOC_SINGLE_BOOL_EXT("DAC Deemphasis Switch", 0,
192 wm8960_get_deemph, wm8960_put_deemph),
139 193
140SOC_ENUM("3D Filter Upper Cut-Off", wm8960_enum[3]), 194SOC_ENUM("3D Filter Upper Cut-Off", wm8960_enum[2]),
141SOC_ENUM("3D Filter Lower Cut-Off", wm8960_enum[4]), 195SOC_ENUM("3D Filter Lower Cut-Off", wm8960_enum[3]),
142SOC_SINGLE("3D Volume", WM8960_3D, 1, 15, 0), 196SOC_SINGLE("3D Volume", WM8960_3D, 1, 15, 0),
143SOC_SINGLE("3D Switch", WM8960_3D, 0, 1, 0), 197SOC_SINGLE("3D Switch", WM8960_3D, 0, 1, 0),
144 198
145SOC_ENUM("ALC Function", wm8960_enum[5]), 199SOC_ENUM("ALC Function", wm8960_enum[4]),
146SOC_SINGLE("ALC Max Gain", WM8960_ALC1, 4, 7, 0), 200SOC_SINGLE("ALC Max Gain", WM8960_ALC1, 4, 7, 0),
147SOC_SINGLE("ALC Target", WM8960_ALC1, 0, 15, 1), 201SOC_SINGLE("ALC Target", WM8960_ALC1, 0, 15, 1),
148SOC_SINGLE("ALC Min Gain", WM8960_ALC2, 4, 7, 0), 202SOC_SINGLE("ALC Min Gain", WM8960_ALC2, 4, 7, 0),
149SOC_SINGLE("ALC Hold Time", WM8960_ALC2, 0, 15, 0), 203SOC_SINGLE("ALC Hold Time", WM8960_ALC2, 0, 15, 0),
150SOC_ENUM("ALC Mode", wm8960_enum[6]), 204SOC_ENUM("ALC Mode", wm8960_enum[5]),
151SOC_SINGLE("ALC Decay", WM8960_ALC3, 4, 15, 0), 205SOC_SINGLE("ALC Decay", WM8960_ALC3, 4, 15, 0),
152SOC_SINGLE("ALC Attack", WM8960_ALC3, 0, 15, 0), 206SOC_SINGLE("ALC Attack", WM8960_ALC3, 0, 15, 0),
153 207
@@ -433,6 +487,21 @@ static int wm8960_set_dai_fmt(struct snd_soc_dai *codec_dai,
433 return 0; 487 return 0;
434} 488}
435 489
490static struct {
491 int rate;
492 unsigned int val;
493} alc_rates[] = {
494 { 48000, 0 },
495 { 44100, 0 },
496 { 32000, 1 },
497 { 22050, 2 },
498 { 24000, 2 },
499 { 16000, 3 },
500 { 11250, 4 },
501 { 12000, 4 },
502 { 8000, 5 },
503};
504
436static int wm8960_hw_params(struct snd_pcm_substream *substream, 505static int wm8960_hw_params(struct snd_pcm_substream *substream,
437 struct snd_pcm_hw_params *params, 506 struct snd_pcm_hw_params *params,
438 struct snd_soc_dai *dai) 507 struct snd_soc_dai *dai)
@@ -440,7 +509,9 @@ static int wm8960_hw_params(struct snd_pcm_substream *substream,
440 struct snd_soc_pcm_runtime *rtd = substream->private_data; 509 struct snd_soc_pcm_runtime *rtd = substream->private_data;
441 struct snd_soc_device *socdev = rtd->socdev; 510 struct snd_soc_device *socdev = rtd->socdev;
442 struct snd_soc_codec *codec = socdev->card->codec; 511 struct snd_soc_codec *codec = socdev->card->codec;
512 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
443 u16 iface = snd_soc_read(codec, WM8960_IFACE1) & 0xfff3; 513 u16 iface = snd_soc_read(codec, WM8960_IFACE1) & 0xfff3;
514 int i;
444 515
445 /* bit size */ 516 /* bit size */
446 switch (params_format(params)) { 517 switch (params_format(params)) {
@@ -454,6 +525,18 @@ static int wm8960_hw_params(struct snd_pcm_substream *substream,
454 break; 525 break;
455 } 526 }
456 527
528 /* Update filters for the new rate */
529 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
530 wm8960->playback_fs = params_rate(params);
531 wm8960_set_deemph(codec);
532 } else {
533 for (i = 0; i < ARRAY_SIZE(alc_rates); i++)
534 if (alc_rates[i].rate == params_rate(params))
535 snd_soc_update_bits(codec,
536 WM8960_ADDCTL3, 0x7,
537 alc_rates[i].val);
538 }
539
457 /* set iface */ 540 /* set iface */
458 snd_soc_write(codec, WM8960_IFACE1, iface); 541 snd_soc_write(codec, WM8960_IFACE1, iface);
459 return 0; 542 return 0;
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c
index 5b9a756242f..2549d3a297a 100644
--- a/sound/soc/codecs/wm8961.c
+++ b/sound/soc/codecs/wm8961.c
@@ -1102,7 +1102,7 @@ static int wm8961_register(struct wm8961_priv *wm8961)
1102 ret = wm8961_reset(codec); 1102 ret = wm8961_reset(codec);
1103 if (ret < 0) { 1103 if (ret < 0) {
1104 dev_err(codec->dev, "Failed to issue reset\n"); 1104 dev_err(codec->dev, "Failed to issue reset\n");
1105 return ret; 1105 goto err;
1106 } 1106 }
1107 1107
1108 /* Enable class W */ 1108 /* Enable class W */
@@ -1147,18 +1147,19 @@ static int wm8961_register(struct wm8961_priv *wm8961)
1147 ret = snd_soc_register_codec(codec); 1147 ret = snd_soc_register_codec(codec);
1148 if (ret != 0) { 1148 if (ret != 0) {
1149 dev_err(codec->dev, "Failed to register codec: %d\n", ret); 1149 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
1150 return ret; 1150 goto err;
1151 } 1151 }
1152 1152
1153 ret = snd_soc_register_dai(&wm8961_dai); 1153 ret = snd_soc_register_dai(&wm8961_dai);
1154 if (ret != 0) { 1154 if (ret != 0) {
1155 dev_err(codec->dev, "Failed to register DAI: %d\n", ret); 1155 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
1156 snd_soc_unregister_codec(codec); 1156 goto err_codec;
1157 return ret;
1158 } 1157 }
1159 1158
1160 return 0; 1159 return 0;
1161 1160
1161err_codec:
1162 snd_soc_unregister_codec(codec);
1162err: 1163err:
1163 kfree(wm8961); 1164 kfree(wm8961);
1164 return ret; 1165 return ret;
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c
index a2c4b2f37cc..1468fe10cbb 100644
--- a/sound/soc/codecs/wm8974.c
+++ b/sound/soc/codecs/wm8974.c
@@ -670,7 +670,8 @@ static __devinit int wm8974_register(struct wm8974_priv *wm8974)
670 670
671 if (wm8974_codec) { 671 if (wm8974_codec) {
672 dev_err(codec->dev, "Another WM8974 is registered\n"); 672 dev_err(codec->dev, "Another WM8974 is registered\n");
673 return -EINVAL; 673 ret = -EINVAL;
674 goto err;
674 } 675 }
675 676
676 mutex_init(&codec->mutex); 677 mutex_init(&codec->mutex);
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c
index 51d5f433215..8a1ad778e7e 100644
--- a/sound/soc/codecs/wm8978.c
+++ b/sound/soc/codecs/wm8978.c
@@ -1076,7 +1076,6 @@ static __devinit int wm8978_register(struct wm8978_priv *wm8978)
1076err_codec: 1076err_codec:
1077 snd_soc_unregister_codec(codec); 1077 snd_soc_unregister_codec(codec);
1078err: 1078err:
1079 kfree(wm8978);
1080 return ret; 1079 return ret;
1081} 1080}
1082 1081
@@ -1085,13 +1084,13 @@ static __devexit void wm8978_unregister(struct wm8978_priv *wm8978)
1085 wm8978_set_bias_level(&wm8978->codec, SND_SOC_BIAS_OFF); 1084 wm8978_set_bias_level(&wm8978->codec, SND_SOC_BIAS_OFF);
1086 snd_soc_unregister_dai(&wm8978_dai); 1085 snd_soc_unregister_dai(&wm8978_dai);
1087 snd_soc_unregister_codec(&wm8978->codec); 1086 snd_soc_unregister_codec(&wm8978->codec);
1088 kfree(wm8978);
1089 wm8978_codec = NULL; 1087 wm8978_codec = NULL;
1090} 1088}
1091 1089
1092static __devinit int wm8978_i2c_probe(struct i2c_client *i2c, 1090static __devinit int wm8978_i2c_probe(struct i2c_client *i2c,
1093 const struct i2c_device_id *id) 1091 const struct i2c_device_id *id)
1094{ 1092{
1093 int ret;
1095 struct wm8978_priv *wm8978; 1094 struct wm8978_priv *wm8978;
1096 struct snd_soc_codec *codec; 1095 struct snd_soc_codec *codec;
1097 1096
@@ -1107,13 +1106,18 @@ static __devinit int wm8978_i2c_probe(struct i2c_client *i2c,
1107 1106
1108 codec->dev = &i2c->dev; 1107 codec->dev = &i2c->dev;
1109 1108
1110 return wm8978_register(wm8978); 1109 ret = wm8978_register(wm8978);
1110 if (ret < 0)
1111 kfree(wm8978);
1112
1113 return ret;
1111} 1114}
1112 1115
1113static __devexit int wm8978_i2c_remove(struct i2c_client *client) 1116static __devexit int wm8978_i2c_remove(struct i2c_client *client)
1114{ 1117{
1115 struct wm8978_priv *wm8978 = i2c_get_clientdata(client); 1118 struct wm8978_priv *wm8978 = i2c_get_clientdata(client);
1116 wm8978_unregister(wm8978); 1119 wm8978_unregister(wm8978);
1120 kfree(wm8978);
1117 return 0; 1121 return 0;
1118} 1122}
1119 1123
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index c018772cc43..dd8d909788c 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -30,8 +30,6 @@
30 30
31#include "wm8990.h" 31#include "wm8990.h"
32 32
33#define WM8990_VERSION "0.2"
34
35/* codec private data */ 33/* codec private data */
36struct wm8990_priv { 34struct wm8990_priv {
37 unsigned int sysclk; 35 unsigned int sysclk;
@@ -1511,8 +1509,6 @@ static int wm8990_probe(struct platform_device *pdev)
1511 struct wm8990_priv *wm8990; 1509 struct wm8990_priv *wm8990;
1512 int ret; 1510 int ret;
1513 1511
1514 pr_info("WM8990 Audio Codec %s\n", WM8990_VERSION);
1515
1516 setup = socdev->codec_data; 1512 setup = socdev->codec_data;
1517 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); 1513 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
1518 if (codec == NULL) 1514 if (codec == NULL)
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index e84a1177f35..522249d5c2b 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -95,6 +95,7 @@ struct wm8994_priv {
95 95
96 struct wm8994_micdet micdet[2]; 96 struct wm8994_micdet micdet[2];
97 97
98 int revision;
98 struct wm8994_pdata *pdata; 99 struct wm8994_pdata *pdata;
99}; 100};
100 101
@@ -1677,6 +1678,26 @@ static struct {
1677 1678
1678static int wm8994_readable(unsigned int reg) 1679static int wm8994_readable(unsigned int reg)
1679{ 1680{
1681 switch (reg) {
1682 case WM8994_GPIO_1:
1683 case WM8994_GPIO_2:
1684 case WM8994_GPIO_3:
1685 case WM8994_GPIO_4:
1686 case WM8994_GPIO_5:
1687 case WM8994_GPIO_6:
1688 case WM8994_GPIO_7:
1689 case WM8994_GPIO_8:
1690 case WM8994_GPIO_9:
1691 case WM8994_GPIO_10:
1692 case WM8994_GPIO_11:
1693 case WM8994_INTERRUPT_STATUS_1:
1694 case WM8994_INTERRUPT_STATUS_2:
1695 case WM8994_INTERRUPT_RAW_STATUS_2:
1696 return 1;
1697 default:
1698 break;
1699 }
1700
1680 if (reg >= ARRAY_SIZE(access_masks)) 1701 if (reg >= ARRAY_SIZE(access_masks))
1681 return 0; 1702 return 0;
1682 return access_masks[reg].readable != 0; 1703 return access_masks[reg].readable != 0;
@@ -2341,6 +2362,20 @@ SOC_DAPM_SINGLE("AIF2 Switch", WM8994_AIF1_ADC1_RIGHT_MIXER_ROUTING,
2341 0, 1, 0), 2362 0, 1, 0),
2342}; 2363};
2343 2364
2365static const struct snd_kcontrol_new aif1adc2l_mix[] = {
2366SOC_DAPM_SINGLE("DMIC Switch", WM8994_AIF1_ADC2_LEFT_MIXER_ROUTING,
2367 1, 1, 0),
2368SOC_DAPM_SINGLE("AIF2 Switch", WM8994_AIF1_ADC2_LEFT_MIXER_ROUTING,
2369 0, 1, 0),
2370};
2371
2372static const struct snd_kcontrol_new aif1adc2r_mix[] = {
2373SOC_DAPM_SINGLE("DMIC Switch", WM8994_AIF1_ADC2_RIGHT_MIXER_ROUTING,
2374 1, 1, 0),
2375SOC_DAPM_SINGLE("AIF2 Switch", WM8994_AIF1_ADC2_RIGHT_MIXER_ROUTING,
2376 0, 1, 0),
2377};
2378
2344static const struct snd_kcontrol_new aif2dac2l_mix[] = { 2379static const struct snd_kcontrol_new aif2dac2l_mix[] = {
2345SOC_DAPM_SINGLE("Right Sidetone Switch", WM8994_DAC2_LEFT_MIXER_ROUTING, 2380SOC_DAPM_SINGLE("Right Sidetone Switch", WM8994_DAC2_LEFT_MIXER_ROUTING,
2346 5, 1, 0), 2381 5, 1, 0),
@@ -2472,6 +2507,7 @@ static const struct snd_kcontrol_new aif3adc_mux =
2472static const struct snd_soc_dapm_widget wm8994_dapm_widgets[] = { 2507static const struct snd_soc_dapm_widget wm8994_dapm_widgets[] = {
2473SND_SOC_DAPM_INPUT("DMIC1DAT"), 2508SND_SOC_DAPM_INPUT("DMIC1DAT"),
2474SND_SOC_DAPM_INPUT("DMIC2DAT"), 2509SND_SOC_DAPM_INPUT("DMIC2DAT"),
2510SND_SOC_DAPM_INPUT("Clock"),
2475 2511
2476SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event, 2512SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event,
2477 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 2513 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
@@ -2506,6 +2542,11 @@ SND_SOC_DAPM_MIXER("AIF1ADC1L Mixer", SND_SOC_NOPM, 0, 0,
2506SND_SOC_DAPM_MIXER("AIF1ADC1R Mixer", SND_SOC_NOPM, 0, 0, 2542SND_SOC_DAPM_MIXER("AIF1ADC1R Mixer", SND_SOC_NOPM, 0, 0,
2507 aif1adc1r_mix, ARRAY_SIZE(aif1adc1r_mix)), 2543 aif1adc1r_mix, ARRAY_SIZE(aif1adc1r_mix)),
2508 2544
2545SND_SOC_DAPM_MIXER("AIF1ADC2L Mixer", SND_SOC_NOPM, 0, 0,
2546 aif1adc2l_mix, ARRAY_SIZE(aif1adc2l_mix)),
2547SND_SOC_DAPM_MIXER("AIF1ADC2R Mixer", SND_SOC_NOPM, 0, 0,
2548 aif1adc2r_mix, ARRAY_SIZE(aif1adc2r_mix)),
2549
2509SND_SOC_DAPM_MIXER("AIF2DAC2L Mixer", SND_SOC_NOPM, 0, 0, 2550SND_SOC_DAPM_MIXER("AIF2DAC2L Mixer", SND_SOC_NOPM, 0, 0,
2510 aif2dac2l_mix, ARRAY_SIZE(aif2dac2l_mix)), 2551 aif2dac2l_mix, ARRAY_SIZE(aif2dac2l_mix)),
2511SND_SOC_DAPM_MIXER("AIF2DAC2R Mixer", SND_SOC_NOPM, 0, 0, 2552SND_SOC_DAPM_MIXER("AIF2DAC2R Mixer", SND_SOC_NOPM, 0, 0,
@@ -2668,6 +2709,14 @@ static const struct snd_soc_dapm_route intercon[] = {
2668 { "AIF1ADC1R Mixer", "ADC/DMIC Switch", "ADCR Mux" }, 2709 { "AIF1ADC1R Mixer", "ADC/DMIC Switch", "ADCR Mux" },
2669 { "AIF1ADC1R Mixer", "AIF2 Switch", "AIF2DACR" }, 2710 { "AIF1ADC1R Mixer", "AIF2 Switch", "AIF2DACR" },
2670 2711
2712 { "AIF1ADC2L", NULL, "AIF1ADC2L Mixer" },
2713 { "AIF1ADC2L Mixer", "DMIC Switch", "DMIC2L" },
2714 { "AIF1ADC2L Mixer", "AIF2 Switch", "AIF2DACL" },
2715
2716 { "AIF1ADC2R", NULL, "AIF1ADC2R Mixer" },
2717 { "AIF1ADC2R Mixer", "DMIC Switch", "DMIC2R" },
2718 { "AIF1ADC2R Mixer", "AIF2 Switch", "AIF2DACR" },
2719
2671 /* Pin level routing for AIF3 */ 2720 /* Pin level routing for AIF3 */
2672 { "AIF1DAC1L", NULL, "AIF1DAC Mux" }, 2721 { "AIF1DAC1L", NULL, "AIF1DAC Mux" },
2673 { "AIF1DAC1R", NULL, "AIF1DAC Mux" }, 2722 { "AIF1DAC1R", NULL, "AIF1DAC Mux" },
@@ -2946,11 +2995,14 @@ static int wm8994_set_fll(struct snd_soc_dai *dai, int id, int src,
2946 return 0; 2995 return 0;
2947} 2996}
2948 2997
2998static int opclk_divs[] = { 10, 20, 30, 40, 55, 60, 80, 120, 160 };
2999
2949static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai, 3000static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai,
2950 int clk_id, unsigned int freq, int dir) 3001 int clk_id, unsigned int freq, int dir)
2951{ 3002{
2952 struct snd_soc_codec *codec = dai->codec; 3003 struct snd_soc_codec *codec = dai->codec;
2953 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 3004 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
3005 int i;
2954 3006
2955 switch (dai->id) { 3007 switch (dai->id) {
2956 case 1: 3008 case 1:
@@ -2988,6 +3040,25 @@ static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai,
2988 dev_dbg(dai->dev, "AIF%d using FLL2\n", dai->id); 3040 dev_dbg(dai->dev, "AIF%d using FLL2\n", dai->id);
2989 break; 3041 break;
2990 3042
3043 case WM8994_SYSCLK_OPCLK:
3044 /* Special case - a division (times 10) is given and
3045 * no effect on main clocking.
3046 */
3047 if (freq) {
3048 for (i = 0; i < ARRAY_SIZE(opclk_divs); i++)
3049 if (opclk_divs[i] == freq)
3050 break;
3051 if (i == ARRAY_SIZE(opclk_divs))
3052 return -EINVAL;
3053 snd_soc_update_bits(codec, WM8994_CLOCKING_2,
3054 WM8994_OPCLK_DIV_MASK, i);
3055 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_2,
3056 WM8994_OPCLK_ENA, WM8994_OPCLK_ENA);
3057 } else {
3058 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_2,
3059 WM8994_OPCLK_ENA, 0);
3060 }
3061
2991 default: 3062 default:
2992 return -EINVAL; 3063 return -EINVAL;
2993 } 3064 }
@@ -3000,6 +3071,8 @@ static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai,
3000static int wm8994_set_bias_level(struct snd_soc_codec *codec, 3071static int wm8994_set_bias_level(struct snd_soc_codec *codec,
3001 enum snd_soc_bias_level level) 3072 enum snd_soc_bias_level level)
3002{ 3073{
3074 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
3075
3003 switch (level) { 3076 switch (level) {
3004 case SND_SOC_BIAS_ON: 3077 case SND_SOC_BIAS_ON:
3005 break; 3078 break;
@@ -3012,11 +3085,16 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
3012 3085
3013 case SND_SOC_BIAS_STANDBY: 3086 case SND_SOC_BIAS_STANDBY:
3014 if (codec->bias_level == SND_SOC_BIAS_OFF) { 3087 if (codec->bias_level == SND_SOC_BIAS_OFF) {
3015 /* Tweak DC servo configuration for improved 3088 /* Tweak DC servo and DSP configuration for
3016 * performance. */ 3089 * improved performance. */
3017 snd_soc_write(codec, 0x102, 0x3); 3090 if (wm8994->revision < 4) {
3018 snd_soc_write(codec, 0x56, 0x3); 3091 /* Tweak DC servo and DSP configuration for
3019 snd_soc_write(codec, 0x102, 0); 3092 * improved performance. */
3093 snd_soc_write(codec, 0x102, 0x3);
3094 snd_soc_write(codec, 0x56, 0x3);
3095 snd_soc_write(codec, 0x817, 0);
3096 snd_soc_write(codec, 0x102, 0);
3097 }
3020 3098
3021 /* Discharge LINEOUT1 & 2 */ 3099 /* Discharge LINEOUT1 & 2 */
3022 snd_soc_update_bits(codec, WM8994_ANTIPOP_1, 3100 snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
@@ -3849,7 +3927,6 @@ static int wm8994_codec_probe(struct platform_device *pdev)
3849 struct wm8994_priv *wm8994; 3927 struct wm8994_priv *wm8994;
3850 struct snd_soc_codec *codec; 3928 struct snd_soc_codec *codec;
3851 int i; 3929 int i;
3852 u16 rev;
3853 3930
3854 if (wm8994_codec) { 3931 if (wm8994_codec) {
3855 dev_err(&pdev->dev, "Another WM8994 is registered\n"); 3932 dev_err(&pdev->dev, "Another WM8994 is registered\n");
@@ -3903,8 +3980,8 @@ static int wm8994_codec_probe(struct platform_device *pdev)
3903 wm8994->reg_cache[i] = 0; 3980 wm8994->reg_cache[i] = 0;
3904 3981
3905 /* Set revision-specific configuration */ 3982 /* Set revision-specific configuration */
3906 rev = snd_soc_read(codec, WM8994_CHIP_REVISION); 3983 wm8994->revision = snd_soc_read(codec, WM8994_CHIP_REVISION);
3907 switch (rev) { 3984 switch (wm8994->revision) {
3908 case 2: 3985 case 2:
3909 case 3: 3986 case 3:
3910 wm8994->hubs.dcs_codes = -5; 3987 wm8994->hubs.dcs_codes = -5;
@@ -4004,6 +4081,11 @@ static int wm8994_codec_probe(struct platform_device *pdev)
4004 1 << WM8994_AIF2DAC_3D_GAIN_SHIFT, 4081 1 << WM8994_AIF2DAC_3D_GAIN_SHIFT,
4005 1 << WM8994_AIF2DAC_3D_GAIN_SHIFT); 4082 1 << WM8994_AIF2DAC_3D_GAIN_SHIFT);
4006 4083
4084 /* Unconditionally enable AIF1 ADC TDM mode; it only affects
4085 * behaviour on idle TDM clock cycles. */
4086 snd_soc_update_bits(codec, WM8994_AIF1_CONTROL_1,
4087 WM8994_AIF1ADC_TDM, WM8994_AIF1ADC_TDM);
4088
4007 wm8994_update_class_w(codec); 4089 wm8994_update_class_w(codec);
4008 4090
4009 ret = snd_soc_register_codec(codec); 4091 ret = snd_soc_register_codec(codec);
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h
index 7072dc53935..2e0ca67a8df 100644
--- a/sound/soc/codecs/wm8994.h
+++ b/sound/soc/codecs/wm8994.h
@@ -20,6 +20,9 @@ extern struct snd_soc_dai wm8994_dai[];
20#define WM8994_SYSCLK_FLL1 3 20#define WM8994_SYSCLK_FLL1 3
21#define WM8994_SYSCLK_FLL2 4 21#define WM8994_SYSCLK_FLL2 4
22 22
23/* OPCLK is also configured with set_dai_sysclk, specify division*10 as rate. */
24#define WM8994_SYSCLK_OPCLK 5
25
23#define WM8994_FLL1 1 26#define WM8994_FLL1 1
24#define WM8994_FLL2 2 27#define WM8994_FLL2 2
25 28
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c
index 13186fb4dcb..76b37ff6c26 100644
--- a/sound/soc/codecs/wm9081.c
+++ b/sound/soc/codecs/wm9081.c
@@ -1356,7 +1356,7 @@ static int wm9081_register(struct wm9081_priv *wm9081,
1356 ret = snd_soc_codec_set_cache_io(codec, 8, 16, control); 1356 ret = snd_soc_codec_set_cache_io(codec, 8, 16, control);
1357 if (ret != 0) { 1357 if (ret != 0) {
1358 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 1358 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1359 return ret; 1359 goto err;
1360 } 1360 }
1361 1361
1362 reg = snd_soc_read(codec, WM9081_SOFTWARE_RESET); 1362 reg = snd_soc_read(codec, WM9081_SOFTWARE_RESET);
@@ -1369,7 +1369,7 @@ static int wm9081_register(struct wm9081_priv *wm9081,
1369 ret = wm9081_reset(codec); 1369 ret = wm9081_reset(codec);
1370 if (ret < 0) { 1370 if (ret < 0) {
1371 dev_err(codec->dev, "Failed to issue reset\n"); 1371 dev_err(codec->dev, "Failed to issue reset\n");
1372 return ret; 1372 goto err;
1373 } 1373 }
1374 1374
1375 wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1375 wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
@@ -1388,18 +1388,19 @@ static int wm9081_register(struct wm9081_priv *wm9081,
1388 ret = snd_soc_register_codec(codec); 1388 ret = snd_soc_register_codec(codec);
1389 if (ret != 0) { 1389 if (ret != 0) {
1390 dev_err(codec->dev, "Failed to register codec: %d\n", ret); 1390 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
1391 return ret; 1391 goto err;
1392 } 1392 }
1393 1393
1394 ret = snd_soc_register_dai(&wm9081_dai); 1394 ret = snd_soc_register_dai(&wm9081_dai);
1395 if (ret != 0) { 1395 if (ret != 0) {
1396 dev_err(codec->dev, "Failed to register DAI: %d\n", ret); 1396 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
1397 snd_soc_unregister_codec(codec); 1397 goto err_codec;
1398 return ret;
1399 } 1398 }
1400 1399
1401 return 0; 1400 return 0;
1402 1401
1402err_codec:
1403 snd_soc_unregister_codec(codec);
1403err: 1404err:
1404 kfree(wm9081); 1405 kfree(wm9081);
1405 return ret; 1406 return ret;
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index 16f1a57da08..2cb81538cd9 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -410,6 +410,8 @@ static int hp_event(struct snd_soc_dapm_widget *w,
410 WM8993_HPOUT1L_DLY | 410 WM8993_HPOUT1L_DLY |
411 WM8993_HPOUT1R_DLY, 0); 411 WM8993_HPOUT1R_DLY, 0);
412 412
413 snd_soc_write(codec, WM8993_DC_SERVO_0, 0);
414
413 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1, 415 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
414 WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA, 416 WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA,
415 0); 417 0);
diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c
index adadcd3aa1b..9e8932abf15 100644
--- a/sound/soc/davinci/davinci-i2s.c
+++ b/sound/soc/davinci/davinci-i2s.c
@@ -26,6 +26,7 @@
26#include <mach/asp.h> 26#include <mach/asp.h>
27 27
28#include "davinci-pcm.h" 28#include "davinci-pcm.h"
29#include "davinci-i2s.h"
29 30
30 31
31/* 32/*
@@ -68,16 +69,21 @@
68#define DAVINCI_MCBSP_RCR_RDATDLY(v) ((v) << 16) 69#define DAVINCI_MCBSP_RCR_RDATDLY(v) ((v) << 16)
69#define DAVINCI_MCBSP_RCR_RFIG (1 << 18) 70#define DAVINCI_MCBSP_RCR_RFIG (1 << 18)
70#define DAVINCI_MCBSP_RCR_RWDLEN2(v) ((v) << 21) 71#define DAVINCI_MCBSP_RCR_RWDLEN2(v) ((v) << 21)
72#define DAVINCI_MCBSP_RCR_RFRLEN2(v) ((v) << 24)
73#define DAVINCI_MCBSP_RCR_RPHASE BIT(31)
71 74
72#define DAVINCI_MCBSP_XCR_XWDLEN1(v) ((v) << 5) 75#define DAVINCI_MCBSP_XCR_XWDLEN1(v) ((v) << 5)
73#define DAVINCI_MCBSP_XCR_XFRLEN1(v) ((v) << 8) 76#define DAVINCI_MCBSP_XCR_XFRLEN1(v) ((v) << 8)
74#define DAVINCI_MCBSP_XCR_XDATDLY(v) ((v) << 16) 77#define DAVINCI_MCBSP_XCR_XDATDLY(v) ((v) << 16)
75#define DAVINCI_MCBSP_XCR_XFIG (1 << 18) 78#define DAVINCI_MCBSP_XCR_XFIG (1 << 18)
76#define DAVINCI_MCBSP_XCR_XWDLEN2(v) ((v) << 21) 79#define DAVINCI_MCBSP_XCR_XWDLEN2(v) ((v) << 21)
80#define DAVINCI_MCBSP_XCR_XFRLEN2(v) ((v) << 24)
81#define DAVINCI_MCBSP_XCR_XPHASE BIT(31)
77 82
78#define DAVINCI_MCBSP_SRGR_FWID(v) ((v) << 8) 83#define DAVINCI_MCBSP_SRGR_FWID(v) ((v) << 8)
79#define DAVINCI_MCBSP_SRGR_FPER(v) ((v) << 16) 84#define DAVINCI_MCBSP_SRGR_FPER(v) ((v) << 16)
80#define DAVINCI_MCBSP_SRGR_FSGM (1 << 28) 85#define DAVINCI_MCBSP_SRGR_FSGM (1 << 28)
86#define DAVINCI_MCBSP_SRGR_CLKSM BIT(29)
81 87
82#define DAVINCI_MCBSP_PCR_CLKRP (1 << 0) 88#define DAVINCI_MCBSP_PCR_CLKRP (1 << 0)
83#define DAVINCI_MCBSP_PCR_CLKXP (1 << 1) 89#define DAVINCI_MCBSP_PCR_CLKXP (1 << 1)
@@ -116,6 +122,7 @@ static const unsigned char double_fmt[SNDRV_PCM_FORMAT_S32_LE + 1] = {
116}; 122};
117 123
118struct davinci_mcbsp_dev { 124struct davinci_mcbsp_dev {
125 struct device *dev;
119 struct davinci_pcm_dma_params dma_params[2]; 126 struct davinci_pcm_dma_params dma_params[2];
120 void __iomem *base; 127 void __iomem *base;
121#define MOD_DSP_A 0 128#define MOD_DSP_A 0
@@ -144,6 +151,11 @@ struct davinci_mcbsp_dev {
144 * won't end up being swapped because of the underrun. 151 * won't end up being swapped because of the underrun.
145 */ 152 */
146 unsigned enable_channel_combine:1; 153 unsigned enable_channel_combine:1;
154
155 unsigned int fmt;
156 int clk_div;
157 int clk_input_pin;
158 bool i2s_accurate_sck;
147}; 159};
148 160
149static inline void davinci_mcbsp_write_reg(struct davinci_mcbsp_dev *dev, 161static inline void davinci_mcbsp_write_reg(struct davinci_mcbsp_dev *dev,
@@ -254,10 +266,12 @@ static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
254 struct davinci_mcbsp_dev *dev = cpu_dai->private_data; 266 struct davinci_mcbsp_dev *dev = cpu_dai->private_data;
255 unsigned int pcr; 267 unsigned int pcr;
256 unsigned int srgr; 268 unsigned int srgr;
269 /* Attention srgr is updated by hw_params! */
257 srgr = DAVINCI_MCBSP_SRGR_FSGM | 270 srgr = DAVINCI_MCBSP_SRGR_FSGM |
258 DAVINCI_MCBSP_SRGR_FPER(DEFAULT_BITPERSAMPLE * 2 - 1) | 271 DAVINCI_MCBSP_SRGR_FPER(DEFAULT_BITPERSAMPLE * 2 - 1) |
259 DAVINCI_MCBSP_SRGR_FWID(DEFAULT_BITPERSAMPLE - 1); 272 DAVINCI_MCBSP_SRGR_FWID(DEFAULT_BITPERSAMPLE - 1);
260 273
274 dev->fmt = fmt;
261 /* set master/slave audio interface */ 275 /* set master/slave audio interface */
262 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 276 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
263 case SND_SOC_DAIFMT_CBS_CFS: 277 case SND_SOC_DAIFMT_CBS_CFS:
@@ -268,11 +282,26 @@ static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
268 DAVINCI_MCBSP_PCR_CLKRM; 282 DAVINCI_MCBSP_PCR_CLKRM;
269 break; 283 break;
270 case SND_SOC_DAIFMT_CBM_CFS: 284 case SND_SOC_DAIFMT_CBM_CFS:
271 /* McBSP CLKR pin is the input for the Sample Rate Generator. 285 pcr = DAVINCI_MCBSP_PCR_FSRM | DAVINCI_MCBSP_PCR_FSXM;
272 * McBSP FSR and FSX are driven by the Sample Rate Generator. */ 286 /*
273 pcr = DAVINCI_MCBSP_PCR_SCLKME | 287 * Selection of the clock input pin that is the
274 DAVINCI_MCBSP_PCR_FSXM | 288 * input for the Sample Rate Generator.
275 DAVINCI_MCBSP_PCR_FSRM; 289 * McBSP FSR and FSX are driven by the Sample Rate
290 * Generator.
291 */
292 switch (dev->clk_input_pin) {
293 case MCBSP_CLKS:
294 pcr |= DAVINCI_MCBSP_PCR_CLKXM |
295 DAVINCI_MCBSP_PCR_CLKRM;
296 break;
297 case MCBSP_CLKR:
298 pcr |= DAVINCI_MCBSP_PCR_SCLKME;
299 break;
300 default:
301 dev_err(dev->dev, "bad clk_input_pin\n");
302 return -EINVAL;
303 }
304
276 break; 305 break;
277 case SND_SOC_DAIFMT_CBM_CFM: 306 case SND_SOC_DAIFMT_CBM_CFM:
278 /* codec is master */ 307 /* codec is master */
@@ -372,6 +401,18 @@ static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
372 return 0; 401 return 0;
373} 402}
374 403
404static int davinci_i2s_dai_set_clkdiv(struct snd_soc_dai *cpu_dai,
405 int div_id, int div)
406{
407 struct davinci_mcbsp_dev *dev = cpu_dai->private_data;
408
409 if (div_id != DAVINCI_MCBSP_CLKGDV)
410 return -ENODEV;
411
412 dev->clk_div = div;
413 return 0;
414}
415
375static int davinci_i2s_hw_params(struct snd_pcm_substream *substream, 416static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
376 struct snd_pcm_hw_params *params, 417 struct snd_pcm_hw_params *params,
377 struct snd_soc_dai *dai) 418 struct snd_soc_dai *dai)
@@ -380,8 +421,8 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
380 struct davinci_pcm_dma_params *dma_params = 421 struct davinci_pcm_dma_params *dma_params =
381 &dev->dma_params[substream->stream]; 422 &dev->dma_params[substream->stream];
382 struct snd_interval *i = NULL; 423 struct snd_interval *i = NULL;
383 int mcbsp_word_length; 424 int mcbsp_word_length, master;
384 unsigned int rcr, xcr, srgr; 425 unsigned int rcr, xcr, srgr, clk_div, freq, framesize;
385 u32 spcr; 426 u32 spcr;
386 snd_pcm_format_t fmt; 427 snd_pcm_format_t fmt;
387 unsigned element_cnt = 1; 428 unsigned element_cnt = 1;
@@ -396,12 +437,59 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
396 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr); 437 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
397 } 438 }
398 439
399 i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS); 440 master = dev->fmt & SND_SOC_DAIFMT_MASTER_MASK;
400 srgr = DAVINCI_MCBSP_SRGR_FSGM; 441 fmt = params_format(params);
401 srgr |= DAVINCI_MCBSP_SRGR_FWID(snd_interval_value(i) - 1); 442 mcbsp_word_length = asp_word_length[fmt];
402 443
403 i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_FRAME_BITS); 444 switch (master) {
404 srgr |= DAVINCI_MCBSP_SRGR_FPER(snd_interval_value(i) - 1); 445 case SND_SOC_DAIFMT_CBS_CFS:
446 freq = clk_get_rate(dev->clk);
447 srgr = DAVINCI_MCBSP_SRGR_FSGM |
448 DAVINCI_MCBSP_SRGR_CLKSM;
449 srgr |= DAVINCI_MCBSP_SRGR_FWID(mcbsp_word_length *
450 8 - 1);
451 if (dev->i2s_accurate_sck) {
452 clk_div = 256;
453 do {
454 framesize = (freq / (--clk_div)) /
455 params->rate_num *
456 params->rate_den;
457 } while (((framesize < 33) || (framesize > 4095)) &&
458 (clk_div));
459 clk_div--;
460 srgr |= DAVINCI_MCBSP_SRGR_FPER(framesize - 1);
461 } else {
462 /* symmetric waveforms */
463 clk_div = freq / (mcbsp_word_length * 16) /
464 params->rate_num * params->rate_den;
465 srgr |= DAVINCI_MCBSP_SRGR_FPER(mcbsp_word_length *
466 16 - 1);
467 }
468 clk_div &= 0xFF;
469 srgr |= clk_div;
470 break;
471 case SND_SOC_DAIFMT_CBM_CFS:
472 srgr = DAVINCI_MCBSP_SRGR_FSGM;
473 clk_div = dev->clk_div - 1;
474 srgr |= DAVINCI_MCBSP_SRGR_FWID(mcbsp_word_length * 8 - 1);
475 srgr |= DAVINCI_MCBSP_SRGR_FPER(mcbsp_word_length * 16 - 1);
476 clk_div &= 0xFF;
477 srgr |= clk_div;
478 break;
479 case SND_SOC_DAIFMT_CBM_CFM:
480 /* Clock and frame sync given from external sources */
481 i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS);
482 srgr = DAVINCI_MCBSP_SRGR_FSGM;
483 srgr |= DAVINCI_MCBSP_SRGR_FWID(snd_interval_value(i) - 1);
484 pr_debug("%s - %d FWID set: re-read srgr = %X\n",
485 __func__, __LINE__, snd_interval_value(i) - 1);
486
487 i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_FRAME_BITS);
488 srgr |= DAVINCI_MCBSP_SRGR_FPER(snd_interval_value(i) - 1);
489 break;
490 default:
491 return -EINVAL;
492 }
405 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SRGR_REG, srgr); 493 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SRGR_REG, srgr);
406 494
407 rcr = DAVINCI_MCBSP_RCR_RFIG; 495 rcr = DAVINCI_MCBSP_RCR_RFIG;
@@ -426,12 +514,41 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
426 element_cnt = 1; 514 element_cnt = 1;
427 fmt = double_fmt[fmt]; 515 fmt = double_fmt[fmt];
428 } 516 }
517 switch (master) {
518 case SND_SOC_DAIFMT_CBS_CFS:
519 case SND_SOC_DAIFMT_CBS_CFM:
520 rcr |= DAVINCI_MCBSP_RCR_RFRLEN2(0);
521 xcr |= DAVINCI_MCBSP_XCR_XFRLEN2(0);
522 rcr |= DAVINCI_MCBSP_RCR_RPHASE;
523 xcr |= DAVINCI_MCBSP_XCR_XPHASE;
524 break;
525 case SND_SOC_DAIFMT_CBM_CFM:
526 case SND_SOC_DAIFMT_CBM_CFS:
527 rcr |= DAVINCI_MCBSP_RCR_RFRLEN2(element_cnt - 1);
528 xcr |= DAVINCI_MCBSP_XCR_XFRLEN2(element_cnt - 1);
529 break;
530 default:
531 return -EINVAL;
532 }
429 } 533 }
430 dma_params->acnt = dma_params->data_type = data_type[fmt]; 534 dma_params->acnt = dma_params->data_type = data_type[fmt];
431 dma_params->fifo_level = 0; 535 dma_params->fifo_level = 0;
432 mcbsp_word_length = asp_word_length[fmt]; 536 mcbsp_word_length = asp_word_length[fmt];
433 rcr |= DAVINCI_MCBSP_RCR_RFRLEN1(element_cnt - 1); 537
434 xcr |= DAVINCI_MCBSP_XCR_XFRLEN1(element_cnt - 1); 538 switch (master) {
539 case SND_SOC_DAIFMT_CBS_CFS:
540 case SND_SOC_DAIFMT_CBS_CFM:
541 rcr |= DAVINCI_MCBSP_RCR_RFRLEN1(0);
542 xcr |= DAVINCI_MCBSP_XCR_XFRLEN1(0);
543 break;
544 case SND_SOC_DAIFMT_CBM_CFM:
545 case SND_SOC_DAIFMT_CBM_CFS:
546 rcr |= DAVINCI_MCBSP_RCR_RFRLEN1(element_cnt - 1);
547 xcr |= DAVINCI_MCBSP_XCR_XFRLEN1(element_cnt - 1);
548 break;
549 default:
550 return -EINVAL;
551 }
435 552
436 rcr |= DAVINCI_MCBSP_RCR_RWDLEN1(mcbsp_word_length) | 553 rcr |= DAVINCI_MCBSP_RCR_RWDLEN1(mcbsp_word_length) |
437 DAVINCI_MCBSP_RCR_RWDLEN2(mcbsp_word_length); 554 DAVINCI_MCBSP_RCR_RWDLEN2(mcbsp_word_length);
@@ -442,6 +559,10 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
442 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_XCR_REG, xcr); 559 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_XCR_REG, xcr);
443 else 560 else
444 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_RCR_REG, rcr); 561 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_RCR_REG, rcr);
562
563 pr_debug("%s - %d srgr=%X\n", __func__, __LINE__, srgr);
564 pr_debug("%s - %d xcr=%X\n", __func__, __LINE__, xcr);
565 pr_debug("%s - %d rcr=%X\n", __func__, __LINE__, rcr);
445 return 0; 566 return 0;
446} 567}
447 568
@@ -500,6 +621,7 @@ static struct snd_soc_dai_ops davinci_i2s_dai_ops = {
500 .trigger = davinci_i2s_trigger, 621 .trigger = davinci_i2s_trigger,
501 .hw_params = davinci_i2s_hw_params, 622 .hw_params = davinci_i2s_hw_params,
502 .set_fmt = davinci_i2s_set_dai_fmt, 623 .set_fmt = davinci_i2s_set_dai_fmt,
624 .set_clkdiv = davinci_i2s_dai_set_clkdiv,
503 625
504}; 626};
505 627
@@ -526,6 +648,8 @@ static int davinci_i2s_probe(struct platform_device *pdev)
526 struct snd_platform_data *pdata = pdev->dev.platform_data; 648 struct snd_platform_data *pdata = pdev->dev.platform_data;
527 struct davinci_mcbsp_dev *dev; 649 struct davinci_mcbsp_dev *dev;
528 struct resource *mem, *ioarea, *res; 650 struct resource *mem, *ioarea, *res;
651 enum dma_event_q asp_chan_q = EVENTQ_0;
652 enum dma_event_q ram_chan_q = EVENTQ_1;
529 int ret; 653 int ret;
530 654
531 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 655 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -552,7 +676,17 @@ static int davinci_i2s_probe(struct platform_device *pdev)
552 pdata->sram_size_playback; 676 pdata->sram_size_playback;
553 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].sram_size = 677 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].sram_size =
554 pdata->sram_size_capture; 678 pdata->sram_size_capture;
679 dev->clk_input_pin = pdata->clk_input_pin;
680 dev->i2s_accurate_sck = pdata->i2s_accurate_sck;
681 asp_chan_q = pdata->asp_chan_q;
682 ram_chan_q = pdata->ram_chan_q;
555 } 683 }
684
685 dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].asp_chan_q = asp_chan_q;
686 dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].ram_chan_q = ram_chan_q;
687 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].asp_chan_q = asp_chan_q;
688 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].ram_chan_q = ram_chan_q;
689
556 dev->clk = clk_get(&pdev->dev, NULL); 690 dev->clk = clk_get(&pdev->dev, NULL);
557 if (IS_ERR(dev->clk)) { 691 if (IS_ERR(dev->clk)) {
558 ret = -ENODEV; 692 ret = -ENODEV;
@@ -584,6 +718,7 @@ static int davinci_i2s_probe(struct platform_device *pdev)
584 goto err_free_mem; 718 goto err_free_mem;
585 } 719 }
586 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].channel = res->start; 720 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].channel = res->start;
721 dev->dev = &pdev->dev;
587 722
588 davinci_i2s_dai.private_data = dev; 723 davinci_i2s_dai.private_data = dev;
589 davinci_i2s_dai.capture.dma_data = dev->dma_params; 724 davinci_i2s_dai.capture.dma_data = dev->dma_params;
diff --git a/sound/soc/davinci/davinci-i2s.h b/sound/soc/davinci/davinci-i2s.h
index 241648ce887..0b1e77b8c27 100644
--- a/sound/soc/davinci/davinci-i2s.h
+++ b/sound/soc/davinci/davinci-i2s.h
@@ -12,6 +12,11 @@
12#ifndef _DAVINCI_I2S_H 12#ifndef _DAVINCI_I2S_H
13#define _DAVINCI_I2S_H 13#define _DAVINCI_I2S_H
14 14
15/* McBSP dividers */
16enum davinci_mcbsp_div {
17 DAVINCI_MCBSP_CLKGDV, /* Sample rate generator divider */
18};
19
15extern struct snd_soc_dai davinci_i2s_dai; 20extern struct snd_soc_dai davinci_i2s_dai;
16 21
17#endif 22#endif
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index d3955096d87..b24720894af 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -890,7 +890,8 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
890 dev->rxnumevt = pdata->rxnumevt; 890 dev->rxnumevt = pdata->rxnumevt;
891 891
892 dma_data = &dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]; 892 dma_data = &dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK];
893 dma_data->eventq_no = pdata->eventq_no; 893 dma_data->asp_chan_q = pdata->asp_chan_q;
894 dma_data->ram_chan_q = pdata->ram_chan_q;
894 dma_data->dma_addr = (dma_addr_t) (pdata->tx_dma_offset + 895 dma_data->dma_addr = (dma_addr_t) (pdata->tx_dma_offset +
895 io_v2p(dev->base)); 896 io_v2p(dev->base));
896 897
@@ -904,7 +905,8 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
904 dma_data->channel = res->start; 905 dma_data->channel = res->start;
905 906
906 dma_data = &dev->dma_params[SNDRV_PCM_STREAM_CAPTURE]; 907 dma_data = &dev->dma_params[SNDRV_PCM_STREAM_CAPTURE];
907 dma_data->eventq_no = pdata->eventq_no; 908 dma_data->asp_chan_q = pdata->asp_chan_q;
909 dma_data->ram_chan_q = pdata->ram_chan_q;
908 dma_data->dma_addr = (dma_addr_t)(pdata->rx_dma_offset + 910 dma_data->dma_addr = (dma_addr_t)(pdata->rx_dma_offset +
909 io_v2p(dev->base)); 911 io_v2p(dev->base));
910 912
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c
index 2dc406f42fe..a7124116d2e 100644
--- a/sound/soc/davinci/davinci-pcm.c
+++ b/sound/soc/davinci/davinci-pcm.c
@@ -381,7 +381,7 @@ static int request_ping_pong(struct snd_pcm_substream *substream,
381 /* Request ram master channel */ 381 /* Request ram master channel */
382 link = prtd->ram_channel = edma_alloc_channel(EDMA_CHANNEL_ANY, 382 link = prtd->ram_channel = edma_alloc_channel(EDMA_CHANNEL_ANY,
383 davinci_pcm_dma_irq, substream, 383 davinci_pcm_dma_irq, substream,
384 EVENTQ_1); 384 prtd->params->ram_chan_q);
385 if (link < 0) 385 if (link < 0)
386 goto exit1; 386 goto exit1;
387 387
@@ -477,7 +477,8 @@ static int davinci_pcm_dma_request(struct snd_pcm_substream *substream)
477 477
478 /* Request asp master DMA channel */ 478 /* Request asp master DMA channel */
479 link = prtd->asp_channel = edma_alloc_channel(params->channel, 479 link = prtd->asp_channel = edma_alloc_channel(params->channel,
480 davinci_pcm_dma_irq, substream, EVENTQ_0); 480 davinci_pcm_dma_irq, substream,
481 prtd->params->asp_chan_q);
481 if (link < 0) 482 if (link < 0)
482 goto exit1; 483 goto exit1;
483 484
@@ -800,7 +801,7 @@ static void davinci_pcm_free(struct snd_pcm *pcm)
800 dma_free_writecombine(pcm->card->dev, buf->bytes, 801 dma_free_writecombine(pcm->card->dev, buf->bytes,
801 buf->area, buf->addr); 802 buf->area, buf->addr);
802 buf->area = NULL; 803 buf->area = NULL;
803 iram_dma = (struct snd_dma_buffer *)buf->private_data; 804 iram_dma = buf->private_data;
804 if (iram_dma) { 805 if (iram_dma) {
805 sram_free(iram_dma->area, iram_dma->bytes); 806 sram_free(iram_dma->area, iram_dma->bytes);
806 kfree(iram_dma); 807 kfree(iram_dma);
diff --git a/sound/soc/davinci/davinci-pcm.h b/sound/soc/davinci/davinci-pcm.h
index 0764944cf10..b799a02333d 100644
--- a/sound/soc/davinci/davinci-pcm.h
+++ b/sound/soc/davinci/davinci-pcm.h
@@ -21,7 +21,8 @@ struct davinci_pcm_dma_params {
21 unsigned short acnt; 21 unsigned short acnt;
22 dma_addr_t dma_addr; /* device physical address for DMA */ 22 dma_addr_t dma_addr; /* device physical address for DMA */
23 unsigned sram_size; 23 unsigned sram_size;
24 enum dma_event_q eventq_no; /* event queue number */ 24 enum dma_event_q asp_chan_q; /* event queue number for ASP channel */
25 enum dma_event_q ram_chan_q; /* event queue number for RAM channel */
25 unsigned char data_type; /* xfer data type */ 26 unsigned char data_type; /* xfer data type */
26 unsigned char convert_mono_stereo; 27 unsigned char convert_mono_stereo;
27 unsigned int fifo_level; 28 unsigned int fifo_level;
diff --git a/sound/soc/davinci/davinci-vcif.c b/sound/soc/davinci/davinci-vcif.c
index 9aa980d3823..48678533da7 100644
--- a/sound/soc/davinci/davinci-vcif.c
+++ b/sound/soc/davinci/davinci-vcif.c
@@ -203,7 +203,7 @@ static int davinci_vcif_probe(struct platform_device *pdev)
203 int ret; 203 int ret;
204 204
205 davinci_vcif_dev = kzalloc(sizeof(struct davinci_vcif_dev), GFP_KERNEL); 205 davinci_vcif_dev = kzalloc(sizeof(struct davinci_vcif_dev), GFP_KERNEL);
206 if (!davinci_vc) { 206 if (!davinci_vcif_dev) {
207 dev_dbg(&pdev->dev, 207 dev_dbg(&pdev->dev,
208 "could not allocate memory for private data\n"); 208 "could not allocate memory for private data\n");
209 return -ENOMEM; 209 return -ENOMEM;
diff --git a/sound/soc/ep93xx/Kconfig b/sound/soc/ep93xx/Kconfig
new file mode 100644
index 00000000000..f617f560f46
--- /dev/null
+++ b/sound/soc/ep93xx/Kconfig
@@ -0,0 +1,18 @@
1config SND_EP93XX_SOC
2 tristate "SoC Audio support for the Cirrus Logic EP93xx series"
3 depends on ARCH_EP93XX && SND_SOC
4 help
5 Say Y or M if you want to add support for codecs attached to
6 the EP93xx I2S interface.
7
8config SND_EP93XX_SOC_I2S
9 tristate
10
11config SND_EP93XX_SOC_SNAPPERCL15
12 tristate "SoC Audio support for Bluewater Systems Snapper CL15 module"
13 depends on SND_EP93XX_SOC && MACH_SNAPPER_CL15
14 select SND_EP93XX_SOC_I2S
15 select SND_SOC_TLV320AIC23
16 help
17 Say Y or M here if you want to add support for I2S audio on the
18 Bluewater Systems Snapper CL15 module.
diff --git a/sound/soc/ep93xx/Makefile b/sound/soc/ep93xx/Makefile
new file mode 100644
index 00000000000..272e60f57b9
--- /dev/null
+++ b/sound/soc/ep93xx/Makefile
@@ -0,0 +1,11 @@
1# EP93xx Platform Support
2snd-soc-ep93xx-objs := ep93xx-pcm.o
3snd-soc-ep93xx-i2s-objs := ep93xx-i2s.o
4
5obj-$(CONFIG_SND_EP93XX_SOC) += snd-soc-ep93xx.o
6obj-$(CONFIG_SND_EP93XX_SOC_I2S) += snd-soc-ep93xx-i2s.o
7
8# EP93XX Machine Support
9snd-soc-snappercl15-objs := snappercl15.o
10
11obj-$(CONFIG_SND_EP93XX_SOC_SNAPPERCL15) += snd-soc-snappercl15.o
diff --git a/sound/soc/ep93xx/ep93xx-i2s.c b/sound/soc/ep93xx/ep93xx-i2s.c
new file mode 100644
index 00000000000..00b94663218
--- /dev/null
+++ b/sound/soc/ep93xx/ep93xx-i2s.c
@@ -0,0 +1,487 @@
1/*
2 * linux/sound/soc/ep93xx-i2s.c
3 * EP93xx I2S driver
4 *
5 * Copyright (C) 2010 Ryan Mallon <ryan@bluewatersys.com>
6 *
7 * Based on the original driver by:
8 * Copyright (C) 2007 Chase Douglas <chasedouglas@gmail>
9 * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 *
15 */
16
17#include <linux/module.h>
18#include <linux/init.h>
19#include <linux/slab.h>
20#include <linux/clk.h>
21#include <linux/io.h>
22
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26#include <sound/initval.h>
27#include <sound/soc.h>
28
29#include <mach/hardware.h>
30#include <mach/ep93xx-regs.h>
31#include <mach/dma.h>
32
33#include "ep93xx-pcm.h"
34#include "ep93xx-i2s.h"
35
36#define EP93XX_I2S_TXCLKCFG 0x00
37#define EP93XX_I2S_RXCLKCFG 0x04
38#define EP93XX_I2S_GLCTRL 0x0C
39
40#define EP93XX_I2S_TXLINCTRLDATA 0x28
41#define EP93XX_I2S_TXCTRL 0x2C
42#define EP93XX_I2S_TXWRDLEN 0x30
43#define EP93XX_I2S_TX0EN 0x34
44
45#define EP93XX_I2S_RXLINCTRLDATA 0x58
46#define EP93XX_I2S_RXCTRL 0x5C
47#define EP93XX_I2S_RXWRDLEN 0x60
48#define EP93XX_I2S_RX0EN 0x64
49
50#define EP93XX_I2S_WRDLEN_16 (0 << 0)
51#define EP93XX_I2S_WRDLEN_24 (1 << 0)
52#define EP93XX_I2S_WRDLEN_32 (2 << 0)
53
54#define EP93XX_I2S_LINCTRLDATA_R_JUST (1 << 2) /* Right justify */
55
56#define EP93XX_I2S_CLKCFG_LRS (1 << 0) /* lrclk polarity */
57#define EP93XX_I2S_CLKCFG_CKP (1 << 1) /* Bit clock polarity */
58#define EP93XX_I2S_CLKCFG_REL (1 << 2) /* First bit transition */
59#define EP93XX_I2S_CLKCFG_MASTER (1 << 3) /* Master mode */
60#define EP93XX_I2S_CLKCFG_NBCG (1 << 4) /* Not bit clock gating */
61
62struct ep93xx_i2s_info {
63 struct clk *mclk;
64 struct clk *sclk;
65 struct clk *lrclk;
66 struct ep93xx_pcm_dma_params *dma_params;
67 struct resource *mem;
68 void __iomem *regs;
69};
70
71struct ep93xx_pcm_dma_params ep93xx_i2s_dma_params[] = {
72 [SNDRV_PCM_STREAM_PLAYBACK] = {
73 .name = "i2s-pcm-out",
74 .dma_port = EP93XX_DMA_M2P_PORT_I2S1,
75 },
76 [SNDRV_PCM_STREAM_CAPTURE] = {
77 .name = "i2s-pcm-in",
78 .dma_port = EP93XX_DMA_M2P_PORT_I2S1,
79 },
80};
81
82static inline void ep93xx_i2s_write_reg(struct ep93xx_i2s_info *info,
83 unsigned reg, unsigned val)
84{
85 __raw_writel(val, info->regs + reg);
86}
87
88static inline unsigned ep93xx_i2s_read_reg(struct ep93xx_i2s_info *info,
89 unsigned reg)
90{
91 return __raw_readl(info->regs + reg);
92}
93
94static void ep93xx_i2s_enable(struct ep93xx_i2s_info *info, int stream)
95{
96 unsigned base_reg;
97 int i;
98
99 if ((ep93xx_i2s_read_reg(info, EP93XX_I2S_TX0EN) & 0x1) == 0 &&
100 (ep93xx_i2s_read_reg(info, EP93XX_I2S_RX0EN) & 0x1) == 0) {
101 /* Enable clocks */
102 clk_enable(info->mclk);
103 clk_enable(info->sclk);
104 clk_enable(info->lrclk);
105
106 /* Enable i2s */
107 ep93xx_i2s_write_reg(info, EP93XX_I2S_GLCTRL, 1);
108 }
109
110 /* Enable fifos */
111 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
112 base_reg = EP93XX_I2S_TX0EN;
113 else
114 base_reg = EP93XX_I2S_RX0EN;
115 for (i = 0; i < 3; i++)
116 ep93xx_i2s_write_reg(info, base_reg + (i * 4), 1);
117}
118
119static void ep93xx_i2s_disable(struct ep93xx_i2s_info *info, int stream)
120{
121 unsigned base_reg;
122 int i;
123
124 /* Disable fifos */
125 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
126 base_reg = EP93XX_I2S_TX0EN;
127 else
128 base_reg = EP93XX_I2S_RX0EN;
129 for (i = 0; i < 3; i++)
130 ep93xx_i2s_write_reg(info, base_reg + (i * 4), 0);
131
132 if ((ep93xx_i2s_read_reg(info, EP93XX_I2S_TX0EN) & 0x1) == 0 &&
133 (ep93xx_i2s_read_reg(info, EP93XX_I2S_RX0EN) & 0x1) == 0) {
134 /* Disable i2s */
135 ep93xx_i2s_write_reg(info, EP93XX_I2S_GLCTRL, 0);
136
137 /* Disable clocks */
138 clk_disable(info->lrclk);
139 clk_disable(info->sclk);
140 clk_disable(info->mclk);
141 }
142}
143
144static int ep93xx_i2s_startup(struct snd_pcm_substream *substream,
145 struct snd_soc_dai *dai)
146{
147 struct snd_soc_pcm_runtime *rtd = substream->private_data;
148 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
149 struct ep93xx_i2s_info *info = rtd->dai->cpu_dai->private_data;
150
151 snd_soc_dai_set_dma_data(cpu_dai, substream,
152 &info->dma_params[substream->stream]);
153 return 0;
154}
155
156static void ep93xx_i2s_shutdown(struct snd_pcm_substream *substream,
157 struct snd_soc_dai *dai)
158{
159 struct snd_soc_pcm_runtime *rtd = substream->private_data;
160 struct ep93xx_i2s_info *info = rtd->dai->cpu_dai->private_data;
161
162 ep93xx_i2s_disable(info, substream->stream);
163}
164
165static int ep93xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
166 unsigned int fmt)
167{
168 struct ep93xx_i2s_info *info = cpu_dai->private_data;
169 unsigned int clk_cfg, lin_ctrl;
170
171 clk_cfg = ep93xx_i2s_read_reg(info, EP93XX_I2S_RXCLKCFG);
172 lin_ctrl = ep93xx_i2s_read_reg(info, EP93XX_I2S_RXLINCTRLDATA);
173
174 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
175 case SND_SOC_DAIFMT_I2S:
176 clk_cfg |= EP93XX_I2S_CLKCFG_REL;
177 lin_ctrl &= ~EP93XX_I2S_LINCTRLDATA_R_JUST;
178 break;
179
180 case SND_SOC_DAIFMT_LEFT_J:
181 clk_cfg &= ~EP93XX_I2S_CLKCFG_REL;
182 lin_ctrl &= ~EP93XX_I2S_LINCTRLDATA_R_JUST;
183 break;
184
185 case SND_SOC_DAIFMT_RIGHT_J:
186 clk_cfg &= ~EP93XX_I2S_CLKCFG_REL;
187 lin_ctrl |= EP93XX_I2S_LINCTRLDATA_R_JUST;
188 break;
189
190 default:
191 return -EINVAL;
192 }
193
194 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
195 case SND_SOC_DAIFMT_CBS_CFS:
196 /* CPU is master */
197 clk_cfg |= EP93XX_I2S_CLKCFG_MASTER;
198 break;
199
200 case SND_SOC_DAIFMT_CBM_CFM:
201 /* Codec is master */
202 clk_cfg &= ~EP93XX_I2S_CLKCFG_MASTER;
203 break;
204
205 default:
206 return -EINVAL;
207 }
208
209 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
210 case SND_SOC_DAIFMT_NB_NF:
211 /* Negative bit clock, lrclk low on left word */
212 clk_cfg &= ~(EP93XX_I2S_CLKCFG_CKP | EP93XX_I2S_CLKCFG_REL);
213 break;
214
215 case SND_SOC_DAIFMT_NB_IF:
216 /* Negative bit clock, lrclk low on right word */
217 clk_cfg &= ~EP93XX_I2S_CLKCFG_CKP;
218 clk_cfg |= EP93XX_I2S_CLKCFG_REL;
219 break;
220
221 case SND_SOC_DAIFMT_IB_NF:
222 /* Positive bit clock, lrclk low on left word */
223 clk_cfg |= EP93XX_I2S_CLKCFG_CKP;
224 clk_cfg &= ~EP93XX_I2S_CLKCFG_REL;
225 break;
226
227 case SND_SOC_DAIFMT_IB_IF:
228 /* Positive bit clock, lrclk low on right word */
229 clk_cfg |= EP93XX_I2S_CLKCFG_CKP | EP93XX_I2S_CLKCFG_REL;
230 break;
231 }
232
233 /* Write new register values */
234 ep93xx_i2s_write_reg(info, EP93XX_I2S_RXCLKCFG, clk_cfg);
235 ep93xx_i2s_write_reg(info, EP93XX_I2S_TXCLKCFG, clk_cfg);
236 ep93xx_i2s_write_reg(info, EP93XX_I2S_RXLINCTRLDATA, lin_ctrl);
237 ep93xx_i2s_write_reg(info, EP93XX_I2S_TXLINCTRLDATA, lin_ctrl);
238 return 0;
239}
240
241static int ep93xx_i2s_hw_params(struct snd_pcm_substream *substream,
242 struct snd_pcm_hw_params *params,
243 struct snd_soc_dai *dai)
244{
245 struct snd_soc_pcm_runtime *rtd = substream->private_data;
246 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
247 struct ep93xx_i2s_info *info = cpu_dai->private_data;
248 unsigned word_len, div, sdiv, lrdiv;
249 int found = 0, err;
250
251 switch (params_format(params)) {
252 case SNDRV_PCM_FORMAT_S16_LE:
253 word_len = EP93XX_I2S_WRDLEN_16;
254 break;
255
256 case SNDRV_PCM_FORMAT_S24_LE:
257 word_len = EP93XX_I2S_WRDLEN_24;
258 break;
259
260 case SNDRV_PCM_FORMAT_S32_LE:
261 word_len = EP93XX_I2S_WRDLEN_32;
262 break;
263
264 default:
265 return -EINVAL;
266 }
267
268 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
269 ep93xx_i2s_write_reg(info, EP93XX_I2S_TXWRDLEN, word_len);
270 else
271 ep93xx_i2s_write_reg(info, EP93XX_I2S_RXWRDLEN, word_len);
272
273 /*
274 * Calculate the sdiv (bit clock) and lrdiv (left/right clock) values.
275 * If the lrclk is pulse length is larger than the word size, then the
276 * bit clock will be gated for the unused bits.
277 */
278 div = (clk_get_rate(info->mclk) / params_rate(params)) *
279 params_channels(params);
280 for (sdiv = 2; sdiv <= 4; sdiv += 2)
281 for (lrdiv = 32; lrdiv <= 128; lrdiv <<= 1)
282 if (sdiv * lrdiv == div) {
283 found = 1;
284 goto out;
285 }
286out:
287 if (!found)
288 return -EINVAL;
289
290 err = clk_set_rate(info->sclk, clk_get_rate(info->mclk) / sdiv);
291 if (err)
292 return err;
293
294 err = clk_set_rate(info->lrclk, clk_get_rate(info->sclk) / lrdiv);
295 if (err)
296 return err;
297
298 ep93xx_i2s_enable(info, substream->stream);
299 return 0;
300}
301
302static int ep93xx_i2s_set_sysclk(struct snd_soc_dai *cpu_dai, int clk_id,
303 unsigned int freq, int dir)
304{
305 struct ep93xx_i2s_info *info = cpu_dai->private_data;
306
307 if (dir == SND_SOC_CLOCK_IN || clk_id != 0)
308 return -EINVAL;
309
310 return clk_set_rate(info->mclk, freq);
311}
312
313#ifdef CONFIG_PM
314static int ep93xx_i2s_suspend(struct snd_soc_dai *dai)
315{
316 struct ep93xx_i2s_info *info = dai->private_data;
317
318 if (!dai->active)
319 return;
320
321 ep93xx_i2s_disable(info, SNDRV_PCM_STREAM_PLAYBACK);
322 ep93xx_i2s_disable(info, SNDRV_PCM_STREAM_CAPTURE);
323}
324
325static int ep93xx_i2s_resume(struct snd_soc_dai *dai)
326{
327 struct ep93xx_i2s_info *info = dai->private_data;
328
329 if (!dai->active)
330 return;
331
332 ep93xx_i2s_enable(info, SNDRV_PCM_STREAM_PLAYBACK);
333 ep93xx_i2s_enable(info, SNDRV_PCM_STREAM_CAPTURE);
334}
335#else
336#define ep93xx_i2s_suspend NULL
337#define ep93xx_i2s_resume NULL
338#endif
339
340static struct snd_soc_dai_ops ep93xx_i2s_dai_ops = {
341 .startup = ep93xx_i2s_startup,
342 .shutdown = ep93xx_i2s_shutdown,
343 .hw_params = ep93xx_i2s_hw_params,
344 .set_sysclk = ep93xx_i2s_set_sysclk,
345 .set_fmt = ep93xx_i2s_set_dai_fmt,
346};
347
348#define EP93XX_I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
349 SNDRV_PCM_FMTBIT_S24_LE | \
350 SNDRV_PCM_FMTBIT_S32_LE)
351
352struct snd_soc_dai ep93xx_i2s_dai = {
353 .name = "ep93xx-i2s",
354 .id = 0,
355 .symmetric_rates= 1,
356 .suspend = ep93xx_i2s_suspend,
357 .resume = ep93xx_i2s_resume,
358 .playback = {
359 .channels_min = 2,
360 .channels_max = 2,
361 .rates = SNDRV_PCM_RATE_8000_48000,
362 .formats = EP93XX_I2S_FORMATS,
363 },
364 .capture = {
365 .channels_min = 2,
366 .channels_max = 2,
367 .rates = SNDRV_PCM_RATE_8000_48000,
368 .formats = EP93XX_I2S_FORMATS,
369 },
370 .ops = &ep93xx_i2s_dai_ops,
371};
372EXPORT_SYMBOL_GPL(ep93xx_i2s_dai);
373
374static int ep93xx_i2s_probe(struct platform_device *pdev)
375{
376 struct ep93xx_i2s_info *info;
377 struct resource *res;
378 int err;
379
380 info = kzalloc(sizeof(struct ep93xx_i2s_info), GFP_KERNEL);
381 if (!info) {
382 err = -ENOMEM;
383 goto fail;
384 }
385
386 ep93xx_i2s_dai.dev = &pdev->dev;
387 ep93xx_i2s_dai.private_data = info;
388 info->dma_params = ep93xx_i2s_dma_params;
389
390 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
391 if (!res) {
392 err = -ENODEV;
393 goto fail;
394 }
395
396 info->mem = request_mem_region(res->start, resource_size(res),
397 pdev->name);
398 if (!info->mem) {
399 err = -EBUSY;
400 goto fail;
401 }
402
403 info->regs = ioremap(info->mem->start, resource_size(info->mem));
404 if (!info->regs) {
405 err = -ENXIO;
406 goto fail_release_mem;
407 }
408
409 info->mclk = clk_get(&pdev->dev, "mclk");
410 if (IS_ERR(info->mclk)) {
411 err = PTR_ERR(info->mclk);
412 goto fail_unmap_mem;
413 }
414
415 info->sclk = clk_get(&pdev->dev, "sclk");
416 if (IS_ERR(info->sclk)) {
417 err = PTR_ERR(info->sclk);
418 goto fail_put_mclk;
419 }
420
421 info->lrclk = clk_get(&pdev->dev, "lrclk");
422 if (IS_ERR(info->lrclk)) {
423 err = PTR_ERR(info->lrclk);
424 goto fail_put_sclk;
425 }
426
427 err = snd_soc_register_dai(&ep93xx_i2s_dai);
428 if (err)
429 goto fail_put_lrclk;
430
431 return 0;
432
433fail_put_lrclk:
434 clk_put(info->lrclk);
435fail_put_sclk:
436 clk_put(info->sclk);
437fail_put_mclk:
438 clk_put(info->mclk);
439fail_unmap_mem:
440 iounmap(info->regs);
441fail_release_mem:
442 release_mem_region(info->mem->start, resource_size(info->mem));
443 kfree(info);
444fail:
445 return err;
446}
447
448static int __devexit ep93xx_i2s_remove(struct platform_device *pdev)
449{
450 struct ep93xx_i2s_info *info = ep93xx_i2s_dai.private_data;
451
452 snd_soc_unregister_dai(&ep93xx_i2s_dai);
453 clk_put(info->lrclk);
454 clk_put(info->sclk);
455 clk_put(info->mclk);
456 iounmap(info->regs);
457 release_mem_region(info->mem->start, resource_size(info->mem));
458 kfree(info);
459 return 0;
460}
461
462static struct platform_driver ep93xx_i2s_driver = {
463 .probe = ep93xx_i2s_probe,
464 .remove = __devexit_p(ep93xx_i2s_remove),
465 .driver = {
466 .name = "ep93xx-i2s",
467 .owner = THIS_MODULE,
468 },
469};
470
471static int __init ep93xx_i2s_init(void)
472{
473 return platform_driver_register(&ep93xx_i2s_driver);
474}
475
476static void __exit ep93xx_i2s_exit(void)
477{
478 platform_driver_unregister(&ep93xx_i2s_driver);
479}
480
481module_init(ep93xx_i2s_init);
482module_exit(ep93xx_i2s_exit);
483
484MODULE_ALIAS("platform:ep93xx-i2s");
485MODULE_AUTHOR("Ryan Mallon <ryan@bluewatersys.com>");
486MODULE_DESCRIPTION("EP93XX I2S driver");
487MODULE_LICENSE("GPL");
diff --git a/sound/soc/ep93xx/ep93xx-i2s.h b/sound/soc/ep93xx/ep93xx-i2s.h
new file mode 100644
index 00000000000..3bd4ebfaa1d
--- /dev/null
+++ b/sound/soc/ep93xx/ep93xx-i2s.h
@@ -0,0 +1,18 @@
1/*
2 * linux/sound/soc/ep93xx-i2s.h
3 * EP93xx I2S driver
4 *
5 * Copyright (C) 2010 Ryan Mallon <ryan@bluewatersys.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 version 2 as
9 * published by the Free Software Foundation.
10 *
11 */
12
13#ifndef _EP93XX_SND_SOC_I2S_H
14#define _EP93XX_SND_SOC_I2S_H
15
16extern struct snd_soc_dai ep93xx_i2s_dai;
17
18#endif /* _EP93XX_SND_SOC_I2S_H */
diff --git a/sound/soc/ep93xx/ep93xx-pcm.c b/sound/soc/ep93xx/ep93xx-pcm.c
new file mode 100644
index 00000000000..4ba93840079
--- /dev/null
+++ b/sound/soc/ep93xx/ep93xx-pcm.c
@@ -0,0 +1,319 @@
1/*
2 * linux/sound/arm/ep93xx-pcm.c - EP93xx ALSA PCM interface
3 *
4 * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
5 * Copyright (C) 2006 Applied Data Systems
6 *
7 * Rewritten for the SoC audio subsystem (Based on PXA2xx code):
8 * Copyright (c) 2008 Ryan Mallon <ryan@bluewatersys.com>
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/module.h>
16#include <linux/init.h>
17#include <linux/device.h>
18#include <linux/slab.h>
19#include <linux/dma-mapping.h>
20
21#include <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/pcm_params.h>
24#include <sound/soc.h>
25
26#include <mach/dma.h>
27#include <mach/hardware.h>
28#include <mach/ep93xx-regs.h>
29
30#include "ep93xx-pcm.h"
31
32static const struct snd_pcm_hardware ep93xx_pcm_hardware = {
33 .info = (SNDRV_PCM_INFO_MMAP |
34 SNDRV_PCM_INFO_MMAP_VALID |
35 SNDRV_PCM_INFO_INTERLEAVED |
36 SNDRV_PCM_INFO_BLOCK_TRANSFER),
37
38 .rates = SNDRV_PCM_RATE_8000_48000,
39 .rate_min = SNDRV_PCM_RATE_8000,
40 .rate_max = SNDRV_PCM_RATE_48000,
41
42 .formats = (SNDRV_PCM_FMTBIT_S16_LE |
43 SNDRV_PCM_FMTBIT_S24_LE |
44 SNDRV_PCM_FMTBIT_S32_LE),
45
46 .buffer_bytes_max = 131072,
47 .period_bytes_min = 32,
48 .period_bytes_max = 32768,
49 .periods_min = 1,
50 .periods_max = 32,
51 .fifo_size = 32,
52};
53
54struct ep93xx_runtime_data
55{
56 struct ep93xx_dma_m2p_client cl;
57 struct ep93xx_pcm_dma_params *params;
58 int pointer_bytes;
59 struct tasklet_struct period_tasklet;
60 int periods;
61 struct ep93xx_dma_buffer buf[32];
62};
63
64static void ep93xx_pcm_period_elapsed(unsigned long data)
65{
66 struct snd_pcm_substream *substream = (struct snd_pcm_substream *)data;
67 snd_pcm_period_elapsed(substream);
68}
69
70static void ep93xx_pcm_buffer_started(void *cookie,
71 struct ep93xx_dma_buffer *buf)
72{
73}
74
75static void ep93xx_pcm_buffer_finished(void *cookie,
76 struct ep93xx_dma_buffer *buf,
77 int bytes, int error)
78{
79 struct snd_pcm_substream *substream = cookie;
80 struct ep93xx_runtime_data *rtd = substream->runtime->private_data;
81
82 if (buf == rtd->buf + rtd->periods - 1)
83 rtd->pointer_bytes = 0;
84 else
85 rtd->pointer_bytes += buf->size;
86
87 if (!error) {
88 ep93xx_dma_m2p_submit_recursive(&rtd->cl, buf);
89 tasklet_schedule(&rtd->period_tasklet);
90 } else {
91 snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
92 }
93}
94
95static int ep93xx_pcm_open(struct snd_pcm_substream *substream)
96{
97 struct snd_soc_pcm_runtime *soc_rtd = substream->private_data;
98 struct snd_soc_dai *cpu_dai = soc_rtd->dai->cpu_dai;
99 struct ep93xx_pcm_dma_params *dma_params;
100 struct ep93xx_runtime_data *rtd;
101 int ret;
102
103 dma_params = snd_soc_dai_get_dma_data(cpu_dai, substream);
104 snd_soc_set_runtime_hwparams(substream, &ep93xx_pcm_hardware);
105
106 rtd = kmalloc(sizeof(*rtd), GFP_KERNEL);
107 if (!rtd)
108 return -ENOMEM;
109
110 memset(&rtd->period_tasklet, 0, sizeof(rtd->period_tasklet));
111 rtd->period_tasklet.func = ep93xx_pcm_period_elapsed;
112 rtd->period_tasklet.data = (unsigned long)substream;
113
114 rtd->cl.name = dma_params->name;
115 rtd->cl.flags = dma_params->dma_port | EP93XX_DMA_M2P_IGNORE_ERROR |
116 ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
117 EP93XX_DMA_M2P_TX : EP93XX_DMA_M2P_RX);
118 rtd->cl.cookie = substream;
119 rtd->cl.buffer_started = ep93xx_pcm_buffer_started;
120 rtd->cl.buffer_finished = ep93xx_pcm_buffer_finished;
121 ret = ep93xx_dma_m2p_client_register(&rtd->cl);
122 if (ret < 0) {
123 kfree(rtd);
124 return ret;
125 }
126
127 substream->runtime->private_data = rtd;
128 return 0;
129}
130
131static int ep93xx_pcm_close(struct snd_pcm_substream *substream)
132{
133 struct ep93xx_runtime_data *rtd = substream->runtime->private_data;
134
135 ep93xx_dma_m2p_client_unregister(&rtd->cl);
136 kfree(rtd);
137 return 0;
138}
139
140static int ep93xx_pcm_hw_params(struct snd_pcm_substream *substream,
141 struct snd_pcm_hw_params *params)
142{
143 struct snd_pcm_runtime *runtime = substream->runtime;
144 struct ep93xx_runtime_data *rtd = runtime->private_data;
145 size_t totsize = params_buffer_bytes(params);
146 size_t period = params_period_bytes(params);
147 int i;
148
149 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
150 runtime->dma_bytes = totsize;
151
152 rtd->periods = (totsize + period - 1) / period;
153 for (i = 0; i < rtd->periods; i++) {
154 rtd->buf[i].bus_addr = runtime->dma_addr + (i * period);
155 rtd->buf[i].size = period;
156 if ((i + 1) * period > totsize)
157 rtd->buf[i].size = totsize - (i * period);
158 }
159
160 return 0;
161}
162
163static int ep93xx_pcm_hw_free(struct snd_pcm_substream *substream)
164{
165 snd_pcm_set_runtime_buffer(substream, NULL);
166 return 0;
167}
168
169static int ep93xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
170{
171 struct ep93xx_runtime_data *rtd = substream->runtime->private_data;
172 int ret;
173 int i;
174
175 ret = 0;
176 switch (cmd) {
177 case SNDRV_PCM_TRIGGER_START:
178 case SNDRV_PCM_TRIGGER_RESUME:
179 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
180 rtd->pointer_bytes = 0;
181 for (i = 0; i < rtd->periods; i++)
182 ep93xx_dma_m2p_submit(&rtd->cl, rtd->buf + i);
183 break;
184
185 case SNDRV_PCM_TRIGGER_STOP:
186 case SNDRV_PCM_TRIGGER_SUSPEND:
187 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
188 ep93xx_dma_m2p_flush(&rtd->cl);
189 break;
190
191 default:
192 ret = -EINVAL;
193 break;
194 }
195
196 return ret;
197}
198
199static snd_pcm_uframes_t ep93xx_pcm_pointer(struct snd_pcm_substream *substream)
200{
201 struct snd_pcm_runtime *runtime = substream->runtime;
202 struct ep93xx_runtime_data *rtd = substream->runtime->private_data;
203
204 /* FIXME: implement this with sub-period granularity */
205 return bytes_to_frames(runtime, rtd->pointer_bytes);
206}
207
208static int ep93xx_pcm_mmap(struct snd_pcm_substream *substream,
209 struct vm_area_struct *vma)
210{
211 struct snd_pcm_runtime *runtime = substream->runtime;
212
213 return dma_mmap_writecombine(substream->pcm->card->dev, vma,
214 runtime->dma_area,
215 runtime->dma_addr,
216 runtime->dma_bytes);
217}
218
219static struct snd_pcm_ops ep93xx_pcm_ops = {
220 .open = ep93xx_pcm_open,
221 .close = ep93xx_pcm_close,
222 .ioctl = snd_pcm_lib_ioctl,
223 .hw_params = ep93xx_pcm_hw_params,
224 .hw_free = ep93xx_pcm_hw_free,
225 .trigger = ep93xx_pcm_trigger,
226 .pointer = ep93xx_pcm_pointer,
227 .mmap = ep93xx_pcm_mmap,
228};
229
230static int ep93xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
231{
232 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
233 struct snd_dma_buffer *buf = &substream->dma_buffer;
234 size_t size = ep93xx_pcm_hardware.buffer_bytes_max;
235
236 buf->dev.type = SNDRV_DMA_TYPE_DEV;
237 buf->dev.dev = pcm->card->dev;
238 buf->private_data = NULL;
239 buf->area = dma_alloc_writecombine(pcm->card->dev, size,
240 &buf->addr, GFP_KERNEL);
241 buf->bytes = size;
242
243 return (buf->area == NULL) ? -ENOMEM : 0;
244}
245
246static void ep93xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
247{
248 struct snd_pcm_substream *substream;
249 struct snd_dma_buffer *buf;
250 int stream;
251
252 for (stream = 0; stream < 2; stream++) {
253 substream = pcm->streams[stream].substream;
254 if (!substream)
255 continue;
256
257 buf = &substream->dma_buffer;
258 if (!buf->area)
259 continue;
260
261 dma_free_writecombine(pcm->card->dev, buf->bytes, buf->area,
262 buf->addr);
263 buf->area = NULL;
264 }
265}
266
267static u64 ep93xx_pcm_dmamask = 0xffffffff;
268
269static int ep93xx_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
270 struct snd_pcm *pcm)
271{
272 int ret = 0;
273
274 if (!card->dev->dma_mask)
275 card->dev->dma_mask = &ep93xx_pcm_dmamask;
276 if (!card->dev->coherent_dma_mask)
277 card->dev->coherent_dma_mask = 0xffffffff;
278
279 if (dai->playback.channels_min) {
280 ret = ep93xx_pcm_preallocate_dma_buffer(pcm,
281 SNDRV_PCM_STREAM_PLAYBACK);
282 if (ret)
283 return ret;
284 }
285
286 if (dai->capture.channels_min) {
287 ret = ep93xx_pcm_preallocate_dma_buffer(pcm,
288 SNDRV_PCM_STREAM_CAPTURE);
289 if (ret)
290 return ret;
291 }
292
293 return 0;
294}
295
296struct snd_soc_platform ep93xx_soc_platform = {
297 .name = "ep93xx-audio",
298 .pcm_ops = &ep93xx_pcm_ops,
299 .pcm_new = &ep93xx_pcm_new,
300 .pcm_free = &ep93xx_pcm_free_dma_buffers,
301};
302EXPORT_SYMBOL_GPL(ep93xx_soc_platform);
303
304static int __init ep93xx_soc_platform_init(void)
305{
306 return snd_soc_register_platform(&ep93xx_soc_platform);
307}
308
309static void __exit ep93xx_soc_platform_exit(void)
310{
311 snd_soc_unregister_platform(&ep93xx_soc_platform);
312}
313
314module_init(ep93xx_soc_platform_init);
315module_exit(ep93xx_soc_platform_exit);
316
317MODULE_AUTHOR("Ryan Mallon <ryan@bluewatersys.com>");
318MODULE_DESCRIPTION("EP93xx ALSA PCM interface");
319MODULE_LICENSE("GPL");
diff --git a/sound/soc/ep93xx/ep93xx-pcm.h b/sound/soc/ep93xx/ep93xx-pcm.h
new file mode 100644
index 00000000000..4ffdd3f62fe
--- /dev/null
+++ b/sound/soc/ep93xx/ep93xx-pcm.h
@@ -0,0 +1,22 @@
1/*
2 * sound/soc/ep93xx/ep93xx-pcm.h - EP93xx ALSA PCM interface
3 *
4 * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
5 * Copyright (C) 2006 Applied Data Systems
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 version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef _EP93XX_SND_SOC_PCM_H
13#define _EP93XX_SND_SOC_PCM_H
14
15struct ep93xx_pcm_dma_params {
16 char *name;
17 int dma_port;
18};
19
20extern struct snd_soc_platform ep93xx_soc_platform;
21
22#endif /* _EP93XX_SND_SOC_PCM_H */
diff --git a/sound/soc/ep93xx/snappercl15.c b/sound/soc/ep93xx/snappercl15.c
new file mode 100644
index 00000000000..64955340ff7
--- /dev/null
+++ b/sound/soc/ep93xx/snappercl15.c
@@ -0,0 +1,150 @@
1/*
2 * snappercl15.c -- SoC audio for Bluewater Systems Snapper CL15 module
3 *
4 * Copyright (C) 2008 Bluewater Systems Ltd
5 * Author: Ryan Mallon <ryan@bluewatersys.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
14#include <linux/platform_device.h>
15#include <sound/core.h>
16#include <sound/pcm.h>
17#include <sound/soc.h>
18#include <sound/soc-dapm.h>
19
20#include <asm/mach-types.h>
21#include <mach/hardware.h>
22
23#include "../codecs/tlv320aic23.h"
24#include "ep93xx-pcm.h"
25#include "ep93xx-i2s.h"
26
27#define CODEC_CLOCK 5644800
28
29static int snappercl15_hw_params(struct snd_pcm_substream *substream,
30 struct snd_pcm_hw_params *params)
31{
32 struct snd_soc_pcm_runtime *rtd = substream->private_data;
33 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
34 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
35 int err;
36
37 err = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
38 SND_SOC_DAIFMT_NB_IF |
39 SND_SOC_DAIFMT_CBS_CFS);
40
41 err = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
42 SND_SOC_DAIFMT_NB_IF |
43 SND_SOC_DAIFMT_CBS_CFS);
44 if (err)
45 return err;
46
47 err = snd_soc_dai_set_sysclk(codec_dai, 0, CODEC_CLOCK,
48 SND_SOC_CLOCK_IN);
49 if (err)
50 return err;
51
52 err = snd_soc_dai_set_sysclk(cpu_dai, 0, CODEC_CLOCK,
53 SND_SOC_CLOCK_OUT);
54 if (err)
55 return err;
56
57 return 0;
58}
59
60static struct snd_soc_ops snappercl15_ops = {
61 .hw_params = snappercl15_hw_params,
62};
63
64static const struct snd_soc_dapm_widget tlv320aic23_dapm_widgets[] = {
65 SND_SOC_DAPM_HP("Headphone Jack", NULL),
66 SND_SOC_DAPM_LINE("Line In", NULL),
67 SND_SOC_DAPM_MIC("Mic Jack", NULL),
68};
69
70static const struct snd_soc_dapm_route audio_map[] = {
71 {"Headphone Jack", NULL, "LHPOUT"},
72 {"Headphone Jack", NULL, "RHPOUT"},
73
74 {"LLINEIN", NULL, "Line In"},
75 {"RLINEIN", NULL, "Line In"},
76
77 {"MICIN", NULL, "Mic Jack"},
78};
79
80static int snappercl15_tlv320aic23_init(struct snd_soc_codec *codec)
81{
82 snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets,
83 ARRAY_SIZE(tlv320aic23_dapm_widgets));
84
85 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
86 return 0;
87}
88
89static struct snd_soc_dai_link snappercl15_dai = {
90 .name = "tlv320aic23",
91 .stream_name = "AIC23",
92 .cpu_dai = &ep93xx_i2s_dai,
93 .codec_dai = &tlv320aic23_dai,
94 .init = snappercl15_tlv320aic23_init,
95 .ops = &snappercl15_ops,
96};
97
98static struct snd_soc_card snd_soc_snappercl15 = {
99 .name = "Snapper CL15",
100 .platform = &ep93xx_soc_platform,
101 .dai_link = &snappercl15_dai,
102 .num_links = 1,
103};
104
105static struct snd_soc_device snappercl15_snd_devdata = {
106 .card = &snd_soc_snappercl15,
107 .codec_dev = &soc_codec_dev_tlv320aic23,
108};
109
110static struct platform_device *snappercl15_snd_device;
111
112static int __init snappercl15_init(void)
113{
114 int ret;
115
116 if (!machine_is_snapper_cl15())
117 return -ENODEV;
118
119 ret = ep93xx_i2s_acquire(EP93XX_SYSCON_DEVCFG_I2SONAC97,
120 EP93XX_SYSCON_I2SCLKDIV_ORIDE |
121 EP93XX_SYSCON_I2SCLKDIV_SPOL);
122 if (ret)
123 return ret;
124
125 snappercl15_snd_device = platform_device_alloc("soc-audio", -1);
126 if (!snappercl15_snd_device)
127 return -ENOMEM;
128
129 platform_set_drvdata(snappercl15_snd_device, &snappercl15_snd_devdata);
130 snappercl15_snd_devdata.dev = &snappercl15_snd_device->dev;
131 ret = platform_device_add(snappercl15_snd_device);
132 if (ret)
133 platform_device_put(snappercl15_snd_device);
134
135 return ret;
136}
137
138static void __exit snappercl15_exit(void)
139{
140 platform_device_unregister(snappercl15_snd_device);
141 ep93xx_i2s_release();
142}
143
144module_init(snappercl15_init);
145module_exit(snappercl15_exit);
146
147MODULE_AUTHOR("Ryan Mallon <ryan@bluewatersys.com>");
148MODULE_DESCRIPTION("ALSA SoC Snapper CL15");
149MODULE_LICENSE("GPL");
150
diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c
index 1d4e7164e80..3dcd1469f28 100644
--- a/sound/soc/fsl/mpc5200_dma.c
+++ b/sound/soc/fsl/mpc5200_dma.c
@@ -369,7 +369,7 @@ struct snd_soc_platform mpc5200_audio_dma_platform = {
369}; 369};
370EXPORT_SYMBOL_GPL(mpc5200_audio_dma_platform); 370EXPORT_SYMBOL_GPL(mpc5200_audio_dma_platform);
371 371
372int mpc5200_audio_dma_create(struct of_device *op) 372int mpc5200_audio_dma_create(struct platform_device *op)
373{ 373{
374 phys_addr_t fifo; 374 phys_addr_t fifo;
375 struct psc_dma *psc_dma; 375 struct psc_dma *psc_dma;
@@ -488,7 +488,7 @@ out_unmap:
488} 488}
489EXPORT_SYMBOL_GPL(mpc5200_audio_dma_create); 489EXPORT_SYMBOL_GPL(mpc5200_audio_dma_create);
490 490
491int mpc5200_audio_dma_destroy(struct of_device *op) 491int mpc5200_audio_dma_destroy(struct platform_device *op)
492{ 492{
493 struct psc_dma *psc_dma = dev_get_drvdata(&op->dev); 493 struct psc_dma *psc_dma = dev_get_drvdata(&op->dev);
494 494
diff --git a/sound/soc/fsl/mpc5200_dma.h b/sound/soc/fsl/mpc5200_dma.h
index e1ec6d91ea3..ca99586f2ad 100644
--- a/sound/soc/fsl/mpc5200_dma.h
+++ b/sound/soc/fsl/mpc5200_dma.h
@@ -81,8 +81,8 @@ to_psc_dma_stream(struct snd_pcm_substream *substream, struct psc_dma *psc_dma)
81 return &psc_dma->playback; 81 return &psc_dma->playback;
82} 82}
83 83
84int mpc5200_audio_dma_create(struct of_device *op); 84int mpc5200_audio_dma_create(struct platform_device *op);
85int mpc5200_audio_dma_destroy(struct of_device *op); 85int mpc5200_audio_dma_destroy(struct platform_device *op);
86 86
87extern struct snd_soc_platform mpc5200_audio_dma_platform; 87extern struct snd_soc_platform mpc5200_audio_dma_platform;
88 88
diff --git a/sound/soc/fsl/mpc5200_psc_ac97.c b/sound/soc/fsl/mpc5200_psc_ac97.c
index e2ee220bfb7..a9560235dae 100644
--- a/sound/soc/fsl/mpc5200_psc_ac97.c
+++ b/sound/soc/fsl/mpc5200_psc_ac97.c
@@ -20,6 +20,7 @@
20 20
21#include <asm/time.h> 21#include <asm/time.h>
22#include <asm/delay.h> 22#include <asm/delay.h>
23#include <asm/mpc52xx.h>
23#include <asm/mpc52xx_psc.h> 24#include <asm/mpc52xx_psc.h>
24 25
25#include "mpc5200_dma.h" 26#include "mpc5200_dma.h"
@@ -100,19 +101,32 @@ static void psc_ac97_warm_reset(struct snd_ac97 *ac97)
100{ 101{
101 struct mpc52xx_psc __iomem *regs = psc_dma->psc_regs; 102 struct mpc52xx_psc __iomem *regs = psc_dma->psc_regs;
102 103
104 mutex_lock(&psc_dma->mutex);
105
103 out_be32(&regs->sicr, psc_dma->sicr | MPC52xx_PSC_SICR_AWR); 106 out_be32(&regs->sicr, psc_dma->sicr | MPC52xx_PSC_SICR_AWR);
104 udelay(3); 107 udelay(3);
105 out_be32(&regs->sicr, psc_dma->sicr); 108 out_be32(&regs->sicr, psc_dma->sicr);
109
110 mutex_unlock(&psc_dma->mutex);
106} 111}
107 112
108static void psc_ac97_cold_reset(struct snd_ac97 *ac97) 113static void psc_ac97_cold_reset(struct snd_ac97 *ac97)
109{ 114{
110 struct mpc52xx_psc __iomem *regs = psc_dma->psc_regs; 115 struct mpc52xx_psc __iomem *regs = psc_dma->psc_regs;
111 116
112 /* Do a cold reset */ 117 mutex_lock(&psc_dma->mutex);
113 out_8(&regs->op1, MPC52xx_PSC_OP_RES); 118 dev_dbg(psc_dma->dev, "cold reset\n");
114 udelay(10); 119
115 out_8(&regs->op0, MPC52xx_PSC_OP_RES); 120 mpc5200_psc_ac97_gpio_reset(psc_dma->id);
121
122 /* Notify the PSC that a reset has occurred */
123 out_be32(&regs->sicr, psc_dma->sicr | MPC52xx_PSC_SICR_ACRB);
124
125 /* Re-enable RX and TX */
126 out_8(&regs->command, MPC52xx_PSC_TX_ENABLE | MPC52xx_PSC_RX_ENABLE);
127
128 mutex_unlock(&psc_dma->mutex);
129
116 msleep(1); 130 msleep(1);
117 psc_ac97_warm_reset(ac97); 131 psc_ac97_warm_reset(ac97);
118} 132}
@@ -263,7 +277,7 @@ EXPORT_SYMBOL_GPL(psc_ac97_dai);
263 * - Probe/remove operations 277 * - Probe/remove operations
264 * - OF device match table 278 * - OF device match table
265 */ 279 */
266static int __devinit psc_ac97_of_probe(struct of_device *op, 280static int __devinit psc_ac97_of_probe(struct platform_device *op,
267 const struct of_device_id *match) 281 const struct of_device_id *match)
268{ 282{
269 int rc, i; 283 int rc, i;
@@ -303,7 +317,7 @@ static int __devinit psc_ac97_of_probe(struct of_device *op,
303 return 0; 317 return 0;
304} 318}
305 319
306static int __devexit psc_ac97_of_remove(struct of_device *op) 320static int __devexit psc_ac97_of_remove(struct platform_device *op)
307{ 321{
308 return mpc5200_audio_dma_destroy(op); 322 return mpc5200_audio_dma_destroy(op);
309} 323}
diff --git a/sound/soc/fsl/mpc5200_psc_i2s.c b/sound/soc/fsl/mpc5200_psc_i2s.c
index 4f455bd6851..534f04cb15d 100644
--- a/sound/soc/fsl/mpc5200_psc_i2s.c
+++ b/sound/soc/fsl/mpc5200_psc_i2s.c
@@ -16,7 +16,6 @@
16 16
17#include <asm/mpc52xx_psc.h> 17#include <asm/mpc52xx_psc.h>
18 18
19#include "mpc5200_psc_i2s.h"
20#include "mpc5200_dma.h" 19#include "mpc5200_dma.h"
21 20
22/** 21/**
@@ -153,7 +152,7 @@ EXPORT_SYMBOL_GPL(psc_i2s_dai);
153 * - Probe/remove operations 152 * - Probe/remove operations
154 * - OF device match table 153 * - OF device match table
155 */ 154 */
156static int __devinit psc_i2s_of_probe(struct of_device *op, 155static int __devinit psc_i2s_of_probe(struct platform_device *op,
157 const struct of_device_id *match) 156 const struct of_device_id *match)
158{ 157{
159 int rc; 158 int rc;
@@ -206,7 +205,7 @@ static int __devinit psc_i2s_of_probe(struct of_device *op,
206 205
207} 206}
208 207
209static int __devexit psc_i2s_of_remove(struct of_device *op) 208static int __devexit psc_i2s_of_remove(struct platform_device *op)
210{ 209{
211 return mpc5200_audio_dma_destroy(op); 210 return mpc5200_audio_dma_destroy(op);
212} 211}
diff --git a/sound/soc/fsl/mpc5200_psc_i2s.h b/sound/soc/fsl/mpc5200_psc_i2s.h
deleted file mode 100644
index ce55e070fdf..00000000000
--- a/sound/soc/fsl/mpc5200_psc_i2s.h
+++ /dev/null
@@ -1,12 +0,0 @@
1/*
2 * Freescale MPC5200 PSC in I2S mode
3 * ALSA SoC Digital Audio Interface (DAI) driver
4 *
5 */
6
7#ifndef __SOUND_SOC_FSL_MPC52xx_PSC_I2S_H__
8#define __SOUND_SOC_FSL_MPC52xx_PSC_I2S_H__
9
10extern struct snd_soc_dai psc_i2s_dai[];
11
12#endif /* __SOUND_SOC_FSL_MPC52xx_PSC_I2S_H__ */
diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c
index 6a2764ee820..3b13b8d6526 100644
--- a/sound/soc/fsl/mpc8610_hpcd.c
+++ b/sound/soc/fsl/mpc8610_hpcd.c
@@ -46,7 +46,7 @@ struct mpc8610_hpcd_data {
46}; 46};
47 47
48/** 48/**
49 * mpc8610_hpcd_machine_probe: initalize the board 49 * mpc8610_hpcd_machine_probe: initialize the board
50 * 50 *
51 * This function is called when platform_device_add() is called. It is used 51 * This function is called when platform_device_add() is called. It is used
52 * to initialize the board-specific hardware. 52 * to initialize the board-specific hardware.
@@ -200,7 +200,7 @@ static struct snd_soc_ops mpc8610_hpcd_ops = {
200 * SSI devices. We also probably aren't compatible with the generic Elo DMA 200 * SSI devices. We also probably aren't compatible with the generic Elo DMA
201 * device driver. 201 * device driver.
202 */ 202 */
203static int mpc8610_hpcd_probe(struct of_device *ofdev, 203static int mpc8610_hpcd_probe(struct platform_device *ofdev,
204 const struct of_device_id *match) 204 const struct of_device_id *match)
205{ 205{
206 struct device_node *np = ofdev->dev.of_node; 206 struct device_node *np = ofdev->dev.of_node;
@@ -534,7 +534,7 @@ error:
534 * 534 *
535 * This function is called when the OF device is removed. 535 * This function is called when the OF device is removed.
536 */ 536 */
537static int mpc8610_hpcd_remove(struct of_device *ofdev) 537static int mpc8610_hpcd_remove(struct platform_device *ofdev)
538{ 538{
539 struct platform_device *sound_device = dev_get_drvdata(&ofdev->dev); 539 struct platform_device *sound_device = dev_get_drvdata(&ofdev->dev);
540 struct mpc8610_hpcd_data *machine_data = 540 struct mpc8610_hpcd_data *machine_data =
diff --git a/sound/soc/imx/Kconfig b/sound/soc/imx/Kconfig
index 252defea93b..687c76fc083 100644
--- a/sound/soc/imx/Kconfig
+++ b/sound/soc/imx/Kconfig
@@ -1,4 +1,4 @@
1config SND_IMX_SOC 1menuconfig SND_IMX_SOC
2 tristate "SoC Audio for Freescale i.MX CPUs" 2 tristate "SoC Audio for Freescale i.MX CPUs"
3 depends on ARCH_MXC 3 depends on ARCH_MXC
4 select SND_PCM 4 select SND_PCM
@@ -8,14 +8,12 @@ config SND_IMX_SOC
8 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
9 the i.MX SSI interface. 9 the i.MX SSI interface.
10 10
11config SND_MXC_SOC_SSI 11if SND_IMX_SOC
12 tristate
13 12
14config SND_MXC_SOC_WM1133_EV1 13config SND_MXC_SOC_WM1133_EV1
15 tristate "Audio on the the i.MX31ADS with WM1133-EV1 fitted" 14 tristate "Audio on the the i.MX31ADS with WM1133-EV1 fitted"
16 depends on SND_IMX_SOC && MACH_MX31ADS_WM1133_EV1 && EXPERIMENTAL 15 depends on MACH_MX31ADS_WM1133_EV1 && EXPERIMENTAL
17 select SND_SOC_WM8350 16 select SND_SOC_WM8350
18 select SND_MXC_SOC_SSI
19 help 17 help
20 Enable support for audio on the i.MX31ADS with the WM1133-EV1 18 Enable support for audio on the i.MX31ADS with the WM1133-EV1
21 PMIC board with WM8835x fitted. 19 PMIC board with WM8835x fitted.
@@ -23,8 +21,19 @@ config SND_MXC_SOC_WM1133_EV1
23config SND_SOC_PHYCORE_AC97 21config SND_SOC_PHYCORE_AC97
24 tristate "SoC Audio support for Phytec phyCORE (and phyCARD) boards" 22 tristate "SoC Audio support for Phytec phyCORE (and phyCARD) boards"
25 depends on MACH_PCM043 || MACH_PCA100 23 depends on MACH_PCM043 || MACH_PCA100
26 select SND_MXC_SOC_SSI
27 select SND_SOC_WM9712 24 select SND_SOC_WM9712
28 help 25 help
29 Say Y if you want to add support for SoC audio on Phytec phyCORE 26 Say Y if you want to add support for SoC audio on Phytec phyCORE
30 and phyCARD boards in AC97 mode 27 and phyCARD boards in AC97 mode
28
29config SND_SOC_EUKREA_TLV320
30 tristate "Eukrea TLV320"
31 depends on MACH_EUKREA_MBIMX27_BASEBOARD \
32 || MACH_EUKREA_MBIMXSD25_BASEBOARD \
33 || MACH_EUKREA_MBIMXSD35_BASEBOARD
34 select SND_SOC_TLV320AIC23
35 help
36 Enable I2S based access to the TLV320AIC23B codec attached
37 to the SSI interface
38
39endif # SND_IMX_SOC
diff --git a/sound/soc/imx/Makefile b/sound/soc/imx/Makefile
index 2d203635ac1..7bc57baf2b0 100644
--- a/sound/soc/imx/Makefile
+++ b/sound/soc/imx/Makefile
@@ -8,8 +8,10 @@ endif
8obj-$(CONFIG_SND_IMX_SOC) += snd-soc-imx.o 8obj-$(CONFIG_SND_IMX_SOC) += snd-soc-imx.o
9 9
10# i.MX Machine Support 10# i.MX Machine Support
11snd-soc-eukrea-tlv320-objs := eukrea-tlv320.o
11snd-soc-phycore-ac97-objs := phycore-ac97.o 12snd-soc-phycore-ac97-objs := phycore-ac97.o
12snd-soc-wm1133-ev1-objs := wm1133-ev1.o 13snd-soc-wm1133-ev1-objs := wm1133-ev1.o
13 14
15obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o
14obj-$(CONFIG_SND_SOC_PHYCORE_AC97) += snd-soc-phycore-ac97.o 16obj-$(CONFIG_SND_SOC_PHYCORE_AC97) += snd-soc-phycore-ac97.o
15obj-$(CONFIG_SND_MXC_SOC_WM1133_EV1) += snd-soc-wm1133-ev1.o 17obj-$(CONFIG_SND_MXC_SOC_WM1133_EV1) += snd-soc-wm1133-ev1.o
diff --git a/sound/soc/imx/eukrea-tlv320.c b/sound/soc/imx/eukrea-tlv320.c
new file mode 100644
index 00000000000..f15dfbdc47e
--- /dev/null
+++ b/sound/soc/imx/eukrea-tlv320.c
@@ -0,0 +1,137 @@
1/*
2 * eukrea-tlv320.c -- SoC audio for eukrea_cpuimxXX in I2S mode
3 *
4 * Copyright 2010 Eric Bénard, Eukréa Electromatique <eric@eukrea.com>
5 *
6 * based on sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c
7 * which is Copyright 2009 Simtec Electronics
8 * and on sound/soc/imx/phycore-ac97.c which is
9 * Copyright 2009 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 *
16 */
17
18#include <linux/module.h>
19#include <linux/moduleparam.h>
20#include <linux/device.h>
21#include <linux/i2c.h>
22#include <sound/core.h>
23#include <sound/pcm.h>
24#include <sound/soc.h>
25#include <sound/soc-dapm.h>
26#include <asm/mach-types.h>
27
28#include "../codecs/tlv320aic23.h"
29#include "imx-ssi.h"
30
31#define CODEC_CLOCK 12000000
32
33static int eukrea_tlv320_hw_params(struct snd_pcm_substream *substream,
34 struct snd_pcm_hw_params *params)
35{
36 struct snd_soc_pcm_runtime *rtd = substream->private_data;
37 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
38 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
39 int ret;
40
41 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
42 SND_SOC_DAIFMT_NB_NF |
43 SND_SOC_DAIFMT_CBM_CFM);
44 if (ret) {
45 pr_err("%s: failed set cpu dai format\n", __func__);
46 return ret;
47 }
48
49 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
50 SND_SOC_DAIFMT_NB_NF |
51 SND_SOC_DAIFMT_CBM_CFM);
52 if (ret) {
53 pr_err("%s: failed set codec dai format\n", __func__);
54 return ret;
55 }
56
57 ret = snd_soc_dai_set_sysclk(codec_dai, 0,
58 CODEC_CLOCK, SND_SOC_CLOCK_OUT);
59 if (ret) {
60 pr_err("%s: failed setting codec sysclk\n", __func__);
61 return ret;
62 }
63 snd_soc_dai_set_tdm_slot(cpu_dai, 0xffffffc, 0xffffffc, 2, 0);
64
65 ret = snd_soc_dai_set_sysclk(cpu_dai, IMX_SSP_SYS_CLK, 0,
66 SND_SOC_CLOCK_IN);
67 if (ret) {
68 pr_err("can't set CPU system clock IMX_SSP_SYS_CLK\n");
69 return ret;
70 }
71
72 return 0;
73}
74
75static struct snd_soc_ops eukrea_tlv320_snd_ops = {
76 .hw_params = eukrea_tlv320_hw_params,
77};
78
79static struct snd_soc_dai_link eukrea_tlv320_dai = {
80 .name = "tlv320aic23",
81 .stream_name = "TLV320AIC23",
82 .codec_dai = &tlv320aic23_dai,
83 .ops = &eukrea_tlv320_snd_ops,
84};
85
86static struct snd_soc_card eukrea_tlv320 = {
87 .name = "cpuimx-audio",
88 .platform = &imx_soc_platform,
89 .dai_link = &eukrea_tlv320_dai,
90 .num_links = 1,
91};
92
93static struct snd_soc_device eukrea_tlv320_snd_devdata = {
94 .card = &eukrea_tlv320,
95 .codec_dev = &soc_codec_dev_tlv320aic23,
96};
97
98static struct platform_device *eukrea_tlv320_snd_device;
99
100static int __init eukrea_tlv320_init(void)
101{
102 int ret;
103
104 if (!machine_is_eukrea_cpuimx27() && !machine_is_eukrea_cpuimx25sd()
105 && !machine_is_eukrea_cpuimx35sd())
106 /* return happy. We might run on a totally different machine */
107 return 0;
108
109 eukrea_tlv320_snd_device = platform_device_alloc("soc-audio", -1);
110 if (!eukrea_tlv320_snd_device)
111 return -ENOMEM;
112
113 eukrea_tlv320_dai.cpu_dai = &imx_ssi_pcm_dai[0];
114
115 platform_set_drvdata(eukrea_tlv320_snd_device, &eukrea_tlv320_snd_devdata);
116 eukrea_tlv320_snd_devdata.dev = &eukrea_tlv320_snd_device->dev;
117 ret = platform_device_add(eukrea_tlv320_snd_device);
118
119 if (ret) {
120 printk(KERN_ERR "ASoC: Platform device allocation failed\n");
121 platform_device_put(eukrea_tlv320_snd_device);
122 }
123
124 return ret;
125}
126
127static void __exit eukrea_tlv320_exit(void)
128{
129 platform_device_unregister(eukrea_tlv320_snd_device);
130}
131
132module_init(eukrea_tlv320_init);
133module_exit(eukrea_tlv320_exit);
134
135MODULE_AUTHOR("Eric Bénard <eric@eukrea.com>");
136MODULE_DESCRIPTION("CPUIMX ALSA SoC driver");
137MODULE_LICENSE("GPL");
diff --git a/sound/soc/imx/imx-pcm-dma-mx2.c b/sound/soc/imx/imx-pcm-dma-mx2.c
index 05f19c9284f..0a595da4811 100644
--- a/sound/soc/imx/imx-pcm-dma-mx2.c
+++ b/sound/soc/imx/imx-pcm-dma-mx2.c
@@ -292,12 +292,16 @@ static int snd_imx_open(struct snd_pcm_substream *substream)
292 int ret; 292 int ret;
293 293
294 iprtd = kzalloc(sizeof(*iprtd), GFP_KERNEL); 294 iprtd = kzalloc(sizeof(*iprtd), GFP_KERNEL);
295 if (iprtd == NULL)
296 return -ENOMEM;
295 runtime->private_data = iprtd; 297 runtime->private_data = iprtd;
296 298
297 ret = snd_pcm_hw_constraint_integer(substream->runtime, 299 ret = snd_pcm_hw_constraint_integer(substream->runtime,
298 SNDRV_PCM_HW_PARAM_PERIODS); 300 SNDRV_PCM_HW_PARAM_PERIODS);
299 if (ret < 0) 301 if (ret < 0) {
302 kfree(iprtd);
300 return ret; 303 return ret;
304 }
301 305
302 snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware); 306 snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware);
303 return 0; 307 return 0;
diff --git a/sound/soc/imx/imx-pcm-fiq.c b/sound/soc/imx/imx-pcm-fiq.c
index 6b518e07eea..b2bf27282cd 100644
--- a/sound/soc/imx/imx-pcm-fiq.c
+++ b/sound/soc/imx/imx-pcm-fiq.c
@@ -192,6 +192,8 @@ static int snd_imx_open(struct snd_pcm_substream *substream)
192 int ret; 192 int ret;
193 193
194 iprtd = kzalloc(sizeof(*iprtd), GFP_KERNEL); 194 iprtd = kzalloc(sizeof(*iprtd), GFP_KERNEL);
195 if (iprtd == NULL)
196 return -ENOMEM;
195 runtime->private_data = iprtd; 197 runtime->private_data = iprtd;
196 198
197 iprtd->substream = substream; 199 iprtd->substream = substream;
@@ -202,8 +204,10 @@ static int snd_imx_open(struct snd_pcm_substream *substream)
202 204
203 ret = snd_pcm_hw_constraint_integer(substream->runtime, 205 ret = snd_pcm_hw_constraint_integer(substream->runtime,
204 SNDRV_PCM_HW_PARAM_PERIODS); 206 SNDRV_PCM_HW_PARAM_PERIODS);
205 if (ret < 0) 207 if (ret < 0) {
208 kfree(iprtd);
206 return ret; 209 return ret;
210 }
207 211
208 snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware); 212 snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware);
209 return 0; 213 return 0;
diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c
index 80b4fee2442..c81da05a4f1 100644
--- a/sound/soc/imx/imx-ssi.c
+++ b/sound/soc/imx/imx-ssi.c
@@ -23,7 +23,7 @@
23 * between pcm data and GPIO status data changes. Our FIQ handler is not 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 24 * able to handle this, hence this driver only works with 48000Hz sampling
25 * rate. 25 * rate.
26 * Reading and writing AC97 registers is another challange. The core 26 * Reading and writing AC97 registers is another challenge. The core
27 * provides us status bits when the read register is updated with *another* 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 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 29 * contains the same value) these status bits are not set. We work
@@ -83,8 +83,6 @@ static int imx_ssi_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai,
83/* 83/*
84 * SSI DAI format configuration. 84 * SSI DAI format configuration.
85 * Should only be called when port is inactive (i.e. SSIEN = 0). 85 * Should only be called when port is inactive (i.e. SSIEN = 0).
86 * Note: We don't use the I2S modes but instead manually configure the
87 * SSI for I2S because the I2S mode is only a register preset.
88 */ 86 */
89static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) 87static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
90{ 88{
@@ -99,6 +97,10 @@ static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
99 /* data on rising edge of bclk, frame low 1clk before data */ 97 /* data on rising edge of bclk, frame low 1clk before data */
100 strcr |= SSI_STCR_TFSI | SSI_STCR_TEFS | SSI_STCR_TXBIT0; 98 strcr |= SSI_STCR_TFSI | SSI_STCR_TEFS | SSI_STCR_TXBIT0;
101 scr |= SSI_SCR_NET; 99 scr |= SSI_SCR_NET;
100 if (ssi->flags & IMX_SSI_USE_I2S_SLAVE) {
101 scr &= ~SSI_I2S_MODE_MASK;
102 scr |= SSI_SCR_I2S_MODE_SLAVE;
103 }
102 break; 104 break;
103 case SND_SOC_DAIFMT_LEFT_J: 105 case SND_SOC_DAIFMT_LEFT_J:
104 /* data on rising edge of bclk, frame high with data */ 106 /* data on rising edge of bclk, frame high with data */
@@ -143,6 +145,11 @@ static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
143 145
144 strcr |= SSI_STCR_TFEN0; 146 strcr |= SSI_STCR_TFEN0;
145 147
148 if (ssi->flags & IMX_SSI_NET)
149 scr |= SSI_SCR_NET;
150 if (ssi->flags & IMX_SSI_SYN)
151 scr |= SSI_SCR_SYN;
152
146 writel(strcr, ssi->base + SSI_STCR); 153 writel(strcr, ssi->base + SSI_STCR);
147 writel(strcr, ssi->base + SSI_SRCR); 154 writel(strcr, ssi->base + SSI_SRCR);
148 writel(scr, ssi->base + SSI_SCR); 155 writel(scr, ssi->base + SSI_SCR);
@@ -247,6 +254,9 @@ static int imx_ssi_hw_params(struct snd_pcm_substream *substream,
247 dma_data = &ssi->dma_params_rx; 254 dma_data = &ssi->dma_params_rx;
248 } 255 }
249 256
257 if (ssi->flags & IMX_SSI_SYN)
258 reg = SSI_STCCR;
259
250 snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data); 260 snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
251 261
252 sccr = readl(ssi->base + reg) & ~SSI_STCCR_WL_MASK; 262 sccr = readl(ssi->base + reg) & ~SSI_STCCR_WL_MASK;
diff --git a/sound/soc/jz4740/Kconfig b/sound/soc/jz4740/Kconfig
new file mode 100644
index 00000000000..5351cba66c9
--- /dev/null
+++ b/sound/soc/jz4740/Kconfig
@@ -0,0 +1,23 @@
1config SND_JZ4740_SOC
2 tristate "SoC Audio for Ingenic JZ4740 SoC"
3 depends on MACH_JZ4740 && SND_SOC
4 help
5 Say Y or M if you want to add support for codecs attached to
6 the JZ4740 I2S interface. You will also need to select the audio
7 interfaces to support below.
8
9config SND_JZ4740_SOC_I2S
10 depends on SND_JZ4740_SOC
11 tristate "SoC Audio (I2S protocol) for Ingenic JZ4740 SoC"
12 help
13 Say Y if you want to use I2S protocol and I2S codec on Ingenic JZ4740
14 based boards.
15
16config SND_JZ4740_SOC_QI_LB60
17 tristate "SoC Audio support for Qi LB60"
18 depends on SND_JZ4740_SOC && JZ4740_QI_LB60
19 select SND_JZ4740_SOC_I2S
20 select SND_SOC_JZ4740_CODEC
21 help
22 Say Y if you want to add support for ASoC audio on the Qi LB60 board
23 a.k.a Qi Ben NanoNote.
diff --git a/sound/soc/jz4740/Makefile b/sound/soc/jz4740/Makefile
new file mode 100644
index 00000000000..be873c1b0c2
--- /dev/null
+++ b/sound/soc/jz4740/Makefile
@@ -0,0 +1,13 @@
1#
2# Jz4740 Platform Support
3#
4snd-soc-jz4740-objs := jz4740-pcm.o
5snd-soc-jz4740-i2s-objs := jz4740-i2s.o
6
7obj-$(CONFIG_SND_JZ4740_SOC) += snd-soc-jz4740.o
8obj-$(CONFIG_SND_JZ4740_SOC_I2S) += snd-soc-jz4740-i2s.o
9
10# Jz4740 Machine Support
11snd-soc-qi-lb60-objs := qi_lb60.o
12
13obj-$(CONFIG_SND_JZ4740_SOC_QI_LB60) += snd-soc-qi-lb60.o
diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
new file mode 100644
index 00000000000..eb518f0c5e0
--- /dev/null
+++ b/sound/soc/jz4740/jz4740-i2s.c
@@ -0,0 +1,540 @@
1/*
2 * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * You should have received a copy of the GNU General Public License along
10 * with this program; if not, write to the Free Software Foundation, Inc.,
11 * 675 Mass Ave, Cambridge, MA 02139, USA.
12 *
13 */
14
15#include <linux/init.h>
16#include <linux/io.h>
17#include <linux/kernel.h>
18#include <linux/module.h>
19#include <linux/platform_device.h>
20#include <linux/slab.h>
21
22#include <linux/clk.h>
23#include <linux/delay.h>
24
25#include <linux/dma-mapping.h>
26
27#include <sound/core.h>
28#include <sound/pcm.h>
29#include <sound/pcm_params.h>
30#include <sound/soc.h>
31#include <sound/soc-dapm.h>
32#include <sound/initval.h>
33
34#include "jz4740-i2s.h"
35#include "jz4740-pcm.h"
36
37#define JZ_REG_AIC_CONF 0x00
38#define JZ_REG_AIC_CTRL 0x04
39#define JZ_REG_AIC_I2S_FMT 0x10
40#define JZ_REG_AIC_FIFO_STATUS 0x14
41#define JZ_REG_AIC_I2S_STATUS 0x1c
42#define JZ_REG_AIC_CLK_DIV 0x30
43#define JZ_REG_AIC_FIFO 0x34
44
45#define JZ_AIC_CONF_FIFO_RX_THRESHOLD_MASK (0xf << 12)
46#define JZ_AIC_CONF_FIFO_TX_THRESHOLD_MASK (0xf << 8)
47#define JZ_AIC_CONF_OVERFLOW_PLAY_LAST BIT(6)
48#define JZ_AIC_CONF_INTERNAL_CODEC BIT(5)
49#define JZ_AIC_CONF_I2S BIT(4)
50#define JZ_AIC_CONF_RESET BIT(3)
51#define JZ_AIC_CONF_BIT_CLK_MASTER BIT(2)
52#define JZ_AIC_CONF_SYNC_CLK_MASTER BIT(1)
53#define JZ_AIC_CONF_ENABLE BIT(0)
54
55#define JZ_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET 12
56#define JZ_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET 8
57
58#define JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE_MASK (0x7 << 19)
59#define JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_MASK (0x7 << 16)
60#define JZ_AIC_CTRL_ENABLE_RX_DMA BIT(15)
61#define JZ_AIC_CTRL_ENABLE_TX_DMA BIT(14)
62#define JZ_AIC_CTRL_MONO_TO_STEREO BIT(11)
63#define JZ_AIC_CTRL_SWITCH_ENDIANNESS BIT(10)
64#define JZ_AIC_CTRL_SIGNED_TO_UNSIGNED BIT(9)
65#define JZ_AIC_CTRL_FLUSH BIT(8)
66#define JZ_AIC_CTRL_ENABLE_ROR_INT BIT(6)
67#define JZ_AIC_CTRL_ENABLE_TUR_INT BIT(5)
68#define JZ_AIC_CTRL_ENABLE_RFS_INT BIT(4)
69#define JZ_AIC_CTRL_ENABLE_TFS_INT BIT(3)
70#define JZ_AIC_CTRL_ENABLE_LOOPBACK BIT(2)
71#define JZ_AIC_CTRL_ENABLE_PLAYBACK BIT(1)
72#define JZ_AIC_CTRL_ENABLE_CAPTURE BIT(0)
73
74#define JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE_OFFSET 19
75#define JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_OFFSET 16
76
77#define JZ_AIC_I2S_FMT_DISABLE_BIT_CLK BIT(12)
78#define JZ_AIC_I2S_FMT_ENABLE_SYS_CLK BIT(4)
79#define JZ_AIC_I2S_FMT_MSB BIT(0)
80
81#define JZ_AIC_I2S_STATUS_BUSY BIT(2)
82
83#define JZ_AIC_CLK_DIV_MASK 0xf
84
85struct jz4740_i2s {
86 struct resource *mem;
87 void __iomem *base;
88 dma_addr_t phys_base;
89
90 struct clk *clk_aic;
91 struct clk *clk_i2s;
92
93 struct jz4740_pcm_config pcm_config_playback;
94 struct jz4740_pcm_config pcm_config_capture;
95};
96
97static inline uint32_t jz4740_i2s_read(const struct jz4740_i2s *i2s,
98 unsigned int reg)
99{
100 return readl(i2s->base + reg);
101}
102
103static inline void jz4740_i2s_write(const struct jz4740_i2s *i2s,
104 unsigned int reg, uint32_t value)
105{
106 writel(value, i2s->base + reg);
107}
108
109static inline struct jz4740_i2s *jz4740_dai_to_i2s(struct snd_soc_dai *dai)
110{
111 return dai->private_data;
112}
113
114static int jz4740_i2s_startup(struct snd_pcm_substream *substream,
115 struct snd_soc_dai *dai)
116{
117 struct jz4740_i2s *i2s = jz4740_dai_to_i2s(dai);
118 uint32_t conf, ctrl;
119
120 if (dai->active)
121 return 0;
122
123 ctrl = jz4740_i2s_read(i2s, JZ_REG_AIC_CTRL);
124 ctrl |= JZ_AIC_CTRL_FLUSH;
125 jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl);
126
127 clk_enable(i2s->clk_i2s);
128
129 conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
130 conf |= JZ_AIC_CONF_ENABLE;
131 jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
132
133 return 0;
134}
135
136static void jz4740_i2s_shutdown(struct snd_pcm_substream *substream,
137 struct snd_soc_dai *dai)
138{
139 struct jz4740_i2s *i2s = jz4740_dai_to_i2s(dai);
140 uint32_t conf;
141
142 if (!dai->active)
143 return;
144
145 conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
146 conf &= ~JZ_AIC_CONF_ENABLE;
147 jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
148
149 clk_disable(i2s->clk_i2s);
150}
151
152static int jz4740_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
153 struct snd_soc_dai *dai)
154{
155 struct jz4740_i2s *i2s = jz4740_dai_to_i2s(dai);
156
157 uint32_t ctrl;
158 uint32_t mask;
159
160 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
161 mask = JZ_AIC_CTRL_ENABLE_PLAYBACK | JZ_AIC_CTRL_ENABLE_TX_DMA;
162 else
163 mask = JZ_AIC_CTRL_ENABLE_CAPTURE | JZ_AIC_CTRL_ENABLE_RX_DMA;
164
165 ctrl = jz4740_i2s_read(i2s, JZ_REG_AIC_CTRL);
166
167 switch (cmd) {
168 case SNDRV_PCM_TRIGGER_START:
169 case SNDRV_PCM_TRIGGER_RESUME:
170 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
171 ctrl |= mask;
172 break;
173 case SNDRV_PCM_TRIGGER_STOP:
174 case SNDRV_PCM_TRIGGER_SUSPEND:
175 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
176 ctrl &= ~mask;
177 break;
178 default:
179 return -EINVAL;
180 }
181
182 jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl);
183
184 return 0;
185}
186
187static int jz4740_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
188{
189 struct jz4740_i2s *i2s = jz4740_dai_to_i2s(dai);
190
191 uint32_t format = 0;
192 uint32_t conf;
193
194 conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
195
196 conf &= ~(JZ_AIC_CONF_BIT_CLK_MASTER | JZ_AIC_CONF_SYNC_CLK_MASTER);
197
198 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
199 case SND_SOC_DAIFMT_CBS_CFS:
200 conf |= JZ_AIC_CONF_BIT_CLK_MASTER | JZ_AIC_CONF_SYNC_CLK_MASTER;
201 format |= JZ_AIC_I2S_FMT_ENABLE_SYS_CLK;
202 break;
203 case SND_SOC_DAIFMT_CBM_CFS:
204 conf |= JZ_AIC_CONF_SYNC_CLK_MASTER;
205 break;
206 case SND_SOC_DAIFMT_CBS_CFM:
207 conf |= JZ_AIC_CONF_BIT_CLK_MASTER;
208 break;
209 case SND_SOC_DAIFMT_CBM_CFM:
210 break;
211 default:
212 return -EINVAL;
213 }
214
215 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
216 case SND_SOC_DAIFMT_MSB:
217 format |= JZ_AIC_I2S_FMT_MSB;
218 break;
219 case SND_SOC_DAIFMT_I2S:
220 break;
221 default:
222 return -EINVAL;
223 }
224
225 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
226 case SND_SOC_DAIFMT_NB_NF:
227 break;
228 default:
229 return -EINVAL;
230 }
231
232 jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
233 jz4740_i2s_write(i2s, JZ_REG_AIC_I2S_FMT, format);
234
235 return 0;
236}
237
238static int jz4740_i2s_hw_params(struct snd_pcm_substream *substream,
239 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
240{
241 struct jz4740_i2s *i2s = jz4740_dai_to_i2s(dai);
242 enum jz4740_dma_width dma_width;
243 struct jz4740_pcm_config *pcm_config;
244 unsigned int sample_size;
245 uint32_t ctrl;
246
247 ctrl = jz4740_i2s_read(i2s, JZ_REG_AIC_CTRL);
248
249 switch (params_format(params)) {
250 case SNDRV_PCM_FORMAT_S8:
251 sample_size = 0;
252 dma_width = JZ4740_DMA_WIDTH_8BIT;
253 break;
254 case SNDRV_PCM_FORMAT_S16:
255 sample_size = 1;
256 dma_width = JZ4740_DMA_WIDTH_16BIT;
257 break;
258 default:
259 return -EINVAL;
260 }
261
262 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
263 ctrl &= ~JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE_MASK;
264 ctrl |= sample_size << JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE_OFFSET;
265 if (params_channels(params) == 1)
266 ctrl |= JZ_AIC_CTRL_MONO_TO_STEREO;
267 else
268 ctrl &= ~JZ_AIC_CTRL_MONO_TO_STEREO;
269
270 pcm_config = &i2s->pcm_config_playback;
271 pcm_config->dma_config.dst_width = dma_width;
272
273 } else {
274 ctrl &= ~JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_MASK;
275 ctrl |= sample_size << JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_OFFSET;
276
277 pcm_config = &i2s->pcm_config_capture;
278 pcm_config->dma_config.src_width = dma_width;
279 }
280
281 jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl);
282
283 snd_soc_dai_set_dma_data(dai, substream, pcm_config);
284
285 return 0;
286}
287
288static int jz4740_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id,
289 unsigned int freq, int dir)
290{
291 struct jz4740_i2s *i2s = jz4740_dai_to_i2s(dai);
292 struct clk *parent;
293 int ret = 0;
294
295 switch (clk_id) {
296 case JZ4740_I2S_CLKSRC_EXT:
297 parent = clk_get(NULL, "ext");
298 clk_set_parent(i2s->clk_i2s, parent);
299 break;
300 case JZ4740_I2S_CLKSRC_PLL:
301 parent = clk_get(NULL, "pll half");
302 clk_set_parent(i2s->clk_i2s, parent);
303 ret = clk_set_rate(i2s->clk_i2s, freq);
304 break;
305 default:
306 return -EINVAL;
307 }
308 clk_put(parent);
309
310 return ret;
311}
312
313static int jz4740_i2s_suspend(struct snd_soc_dai *dai)
314{
315 struct jz4740_i2s *i2s = jz4740_dai_to_i2s(dai);
316 uint32_t conf;
317
318 if (dai->active) {
319 conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
320 conf &= ~JZ_AIC_CONF_ENABLE;
321 jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
322
323 clk_disable(i2s->clk_i2s);
324 }
325
326 clk_disable(i2s->clk_aic);
327
328 return 0;
329}
330
331static int jz4740_i2s_resume(struct snd_soc_dai *dai)
332{
333 struct jz4740_i2s *i2s = jz4740_dai_to_i2s(dai);
334 uint32_t conf;
335
336 clk_enable(i2s->clk_aic);
337
338 if (dai->active) {
339 clk_enable(i2s->clk_i2s);
340
341 conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
342 conf |= JZ_AIC_CONF_ENABLE;
343 jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
344 }
345
346 return 0;
347}
348
349static int jz4740_i2s_probe(struct platform_device *pdev, struct snd_soc_dai *dai)
350{
351 struct jz4740_i2s *i2s = jz4740_dai_to_i2s(dai);
352 uint32_t conf;
353
354 conf = (7 << JZ_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET) |
355 (8 << JZ_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET) |
356 JZ_AIC_CONF_OVERFLOW_PLAY_LAST |
357 JZ_AIC_CONF_I2S |
358 JZ_AIC_CONF_INTERNAL_CODEC;
359
360 jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, JZ_AIC_CONF_RESET);
361 jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
362
363 return 0;
364}
365
366static struct snd_soc_dai_ops jz4740_i2s_dai_ops = {
367 .startup = jz4740_i2s_startup,
368 .shutdown = jz4740_i2s_shutdown,
369 .trigger = jz4740_i2s_trigger,
370 .hw_params = jz4740_i2s_hw_params,
371 .set_fmt = jz4740_i2s_set_fmt,
372 .set_sysclk = jz4740_i2s_set_sysclk,
373};
374
375#define JZ4740_I2S_FMTS (SNDRV_PCM_FMTBIT_S8 | \
376 SNDRV_PCM_FMTBIT_S16_LE)
377
378struct snd_soc_dai jz4740_i2s_dai = {
379 .name = "jz4740-i2s",
380 .probe = jz4740_i2s_probe,
381 .playback = {
382 .channels_min = 1,
383 .channels_max = 2,
384 .rates = SNDRV_PCM_RATE_8000_48000,
385 .formats = JZ4740_I2S_FMTS,
386 },
387 .capture = {
388 .channels_min = 2,
389 .channels_max = 2,
390 .rates = SNDRV_PCM_RATE_8000_48000,
391 .formats = JZ4740_I2S_FMTS,
392 },
393 .symmetric_rates = 1,
394 .ops = &jz4740_i2s_dai_ops,
395 .suspend = jz4740_i2s_suspend,
396 .resume = jz4740_i2s_resume,
397};
398EXPORT_SYMBOL_GPL(jz4740_i2s_dai);
399
400static void __devinit jz4740_i2c_init_pcm_config(struct jz4740_i2s *i2s)
401{
402 struct jz4740_dma_config *dma_config;
403
404 /* Playback */
405 dma_config = &i2s->pcm_config_playback.dma_config;
406 dma_config->src_width = JZ4740_DMA_WIDTH_32BIT,
407 dma_config->transfer_size = JZ4740_DMA_TRANSFER_SIZE_16BYTE;
408 dma_config->request_type = JZ4740_DMA_TYPE_AIC_TRANSMIT;
409 dma_config->flags = JZ4740_DMA_SRC_AUTOINC;
410 dma_config->mode = JZ4740_DMA_MODE_SINGLE;
411 i2s->pcm_config_playback.fifo_addr = i2s->phys_base + JZ_REG_AIC_FIFO;
412
413 /* Capture */
414 dma_config = &i2s->pcm_config_capture.dma_config;
415 dma_config->dst_width = JZ4740_DMA_WIDTH_32BIT,
416 dma_config->transfer_size = JZ4740_DMA_TRANSFER_SIZE_16BYTE;
417 dma_config->request_type = JZ4740_DMA_TYPE_AIC_RECEIVE;
418 dma_config->flags = JZ4740_DMA_DST_AUTOINC;
419 dma_config->mode = JZ4740_DMA_MODE_SINGLE;
420 i2s->pcm_config_capture.fifo_addr = i2s->phys_base + JZ_REG_AIC_FIFO;
421}
422
423static int __devinit jz4740_i2s_dev_probe(struct platform_device *pdev)
424{
425 struct jz4740_i2s *i2s;
426 int ret;
427
428 i2s = kzalloc(sizeof(*i2s), GFP_KERNEL);
429
430 if (!i2s)
431 return -ENOMEM;
432
433 i2s->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
434 if (!i2s->mem) {
435 ret = -ENOENT;
436 goto err_free;
437 }
438
439 i2s->mem = request_mem_region(i2s->mem->start, resource_size(i2s->mem),
440 pdev->name);
441 if (!i2s->mem) {
442 ret = -EBUSY;
443 goto err_free;
444 }
445
446 i2s->base = ioremap_nocache(i2s->mem->start, resource_size(i2s->mem));
447 if (!i2s->base) {
448 ret = -EBUSY;
449 goto err_release_mem_region;
450 }
451
452 i2s->phys_base = i2s->mem->start;
453
454 i2s->clk_aic = clk_get(&pdev->dev, "aic");
455 if (IS_ERR(i2s->clk_aic)) {
456 ret = PTR_ERR(i2s->clk_aic);
457 goto err_iounmap;
458 }
459
460 i2s->clk_i2s = clk_get(&pdev->dev, "i2s");
461 if (IS_ERR(i2s->clk_i2s)) {
462 ret = PTR_ERR(i2s->clk_i2s);
463 goto err_clk_put_aic;
464 }
465
466 clk_enable(i2s->clk_aic);
467
468 jz4740_i2c_init_pcm_config(i2s);
469
470 jz4740_i2s_dai.private_data = i2s;
471 ret = snd_soc_register_dai(&jz4740_i2s_dai);
472
473 if (ret) {
474 dev_err(&pdev->dev, "Failed to register DAI\n");
475 goto err_clk_put_i2s;
476 }
477
478 platform_set_drvdata(pdev, i2s);
479
480 return 0;
481
482err_clk_put_i2s:
483 clk_disable(i2s->clk_aic);
484 clk_put(i2s->clk_i2s);
485err_clk_put_aic:
486 clk_put(i2s->clk_aic);
487err_iounmap:
488 iounmap(i2s->base);
489err_release_mem_region:
490 release_mem_region(i2s->mem->start, resource_size(i2s->mem));
491err_free:
492 kfree(i2s);
493
494 return ret;
495}
496
497static int __devexit jz4740_i2s_dev_remove(struct platform_device *pdev)
498{
499 struct jz4740_i2s *i2s = platform_get_drvdata(pdev);
500
501 snd_soc_unregister_dai(&jz4740_i2s_dai);
502
503 clk_disable(i2s->clk_aic);
504 clk_put(i2s->clk_i2s);
505 clk_put(i2s->clk_aic);
506
507 iounmap(i2s->base);
508 release_mem_region(i2s->mem->start, resource_size(i2s->mem));
509
510 platform_set_drvdata(pdev, NULL);
511 kfree(i2s);
512
513 return 0;
514}
515
516static struct platform_driver jz4740_i2s_driver = {
517 .probe = jz4740_i2s_dev_probe,
518 .remove = __devexit_p(jz4740_i2s_dev_remove),
519 .driver = {
520 .name = "jz4740-i2s",
521 .owner = THIS_MODULE,
522 },
523};
524
525static int __init jz4740_i2s_init(void)
526{
527 return platform_driver_register(&jz4740_i2s_driver);
528}
529module_init(jz4740_i2s_init);
530
531static void __exit jz4740_i2s_exit(void)
532{
533 platform_driver_unregister(&jz4740_i2s_driver);
534}
535module_exit(jz4740_i2s_exit);
536
537MODULE_AUTHOR("Lars-Peter Clausen, <lars@metafoo.de>");
538MODULE_DESCRIPTION("Ingenic JZ4740 SoC I2S driver");
539MODULE_LICENSE("GPL");
540MODULE_ALIAS("platform:jz4740-i2s");
diff --git a/sound/soc/jz4740/jz4740-i2s.h b/sound/soc/jz4740/jz4740-i2s.h
new file mode 100644
index 00000000000..da22ed88a58
--- /dev/null
+++ b/sound/soc/jz4740/jz4740-i2s.h
@@ -0,0 +1,18 @@
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 _JZ4740_I2S_H
8#define _JZ4740_I2S_H
9
10/* I2S clock source */
11#define JZ4740_I2S_CLKSRC_EXT 0
12#define JZ4740_I2S_CLKSRC_PLL 1
13
14#define JZ4740_I2S_BIT_CLK 0
15
16extern struct snd_soc_dai jz4740_i2s_dai;
17
18#endif
diff --git a/sound/soc/jz4740/jz4740-pcm.c b/sound/soc/jz4740/jz4740-pcm.c
new file mode 100644
index 00000000000..ee68d850c8d
--- /dev/null
+++ b/sound/soc/jz4740/jz4740-pcm.c
@@ -0,0 +1,373 @@
1/*
2 * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * You should have received a copy of the GNU General Public License along
10 * with this program; if not, write to the Free Software Foundation, Inc.,
11 * 675 Mass Ave, Cambridge, MA 02139, USA.
12 *
13 */
14
15#include <linux/init.h>
16#include <linux/interrupt.h>
17#include <linux/kernel.h>
18#include <linux/module.h>
19#include <linux/platform_device.h>
20#include <linux/slab.h>
21
22#include <linux/dma-mapping.h>
23
24#include <sound/core.h>
25#include <sound/pcm.h>
26#include <sound/pcm_params.h>
27#include <sound/soc.h>
28
29#include <asm/mach-jz4740/dma.h>
30#include "jz4740-pcm.h"
31
32struct jz4740_runtime_data {
33 unsigned long dma_period;
34 dma_addr_t dma_start;
35 dma_addr_t dma_pos;
36 dma_addr_t dma_end;
37
38 struct jz4740_dma_chan *dma;
39
40 dma_addr_t fifo_addr;
41};
42
43/* identify hardware playback capabilities */
44static const struct snd_pcm_hardware jz4740_pcm_hardware = {
45 .info = SNDRV_PCM_INFO_MMAP |
46 SNDRV_PCM_INFO_MMAP_VALID |
47 SNDRV_PCM_INFO_INTERLEAVED |
48 SNDRV_PCM_INFO_BLOCK_TRANSFER,
49 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8,
50
51 .rates = SNDRV_PCM_RATE_8000_48000,
52 .channels_min = 1,
53 .channels_max = 2,
54 .period_bytes_min = 16,
55 .period_bytes_max = 2 * PAGE_SIZE,
56 .periods_min = 2,
57 .periods_max = 128,
58 .buffer_bytes_max = 128 * 2 * PAGE_SIZE,
59 .fifo_size = 32,
60};
61
62static void jz4740_pcm_start_transfer(struct jz4740_runtime_data *prtd,
63 struct snd_pcm_substream *substream)
64{
65 unsigned long count;
66
67 if (prtd->dma_pos == prtd->dma_end)
68 prtd->dma_pos = prtd->dma_start;
69
70 if (prtd->dma_pos + prtd->dma_period > prtd->dma_end)
71 count = prtd->dma_end - prtd->dma_pos;
72 else
73 count = prtd->dma_period;
74
75 jz4740_dma_disable(prtd->dma);
76
77 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
78 jz4740_dma_set_src_addr(prtd->dma, prtd->dma_pos);
79 jz4740_dma_set_dst_addr(prtd->dma, prtd->fifo_addr);
80 } else {
81 jz4740_dma_set_src_addr(prtd->dma, prtd->fifo_addr);
82 jz4740_dma_set_dst_addr(prtd->dma, prtd->dma_pos);
83 }
84
85 jz4740_dma_set_transfer_count(prtd->dma, count);
86
87 prtd->dma_pos += count;
88
89 jz4740_dma_enable(prtd->dma);
90}
91
92static void jz4740_pcm_dma_transfer_done(struct jz4740_dma_chan *dma, int err,
93 void *dev_id)
94{
95 struct snd_pcm_substream *substream = dev_id;
96 struct snd_pcm_runtime *runtime = substream->runtime;
97 struct jz4740_runtime_data *prtd = runtime->private_data;
98
99 snd_pcm_period_elapsed(substream);
100
101 jz4740_pcm_start_transfer(prtd, substream);
102}
103
104static int jz4740_pcm_hw_params(struct snd_pcm_substream *substream,
105 struct snd_pcm_hw_params *params)
106{
107 struct snd_pcm_runtime *runtime = substream->runtime;
108 struct jz4740_runtime_data *prtd = runtime->private_data;
109 struct snd_soc_pcm_runtime *rtd = substream->private_data;
110 struct jz4740_pcm_config *config;
111
112 config = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
113
114 if (!config)
115 return 0;
116
117 if (!prtd->dma) {
118 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
119 prtd->dma = jz4740_dma_request(substream, "PCM Capture");
120 else
121 prtd->dma = jz4740_dma_request(substream, "PCM Playback");
122 }
123
124 if (!prtd->dma)
125 return -EBUSY;
126
127 jz4740_dma_configure(prtd->dma, &config->dma_config);
128 prtd->fifo_addr = config->fifo_addr;
129
130 jz4740_dma_set_complete_cb(prtd->dma, jz4740_pcm_dma_transfer_done);
131
132 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
133 runtime->dma_bytes = params_buffer_bytes(params);
134
135 prtd->dma_period = params_period_bytes(params);
136 prtd->dma_start = runtime->dma_addr;
137 prtd->dma_pos = prtd->dma_start;
138 prtd->dma_end = prtd->dma_start + runtime->dma_bytes;
139
140 return 0;
141}
142
143static int jz4740_pcm_hw_free(struct snd_pcm_substream *substream)
144{
145 struct jz4740_runtime_data *prtd = substream->runtime->private_data;
146
147 snd_pcm_set_runtime_buffer(substream, NULL);
148 if (prtd->dma) {
149 jz4740_dma_free(prtd->dma);
150 prtd->dma = NULL;
151 }
152
153 return 0;
154}
155
156static int jz4740_pcm_prepare(struct snd_pcm_substream *substream)
157{
158 struct jz4740_runtime_data *prtd = substream->runtime->private_data;
159
160 if (!prtd->dma)
161 return -EBUSY;
162
163 prtd->dma_pos = prtd->dma_start;
164
165 return 0;
166}
167
168static int jz4740_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
169{
170 struct snd_pcm_runtime *runtime = substream->runtime;
171 struct jz4740_runtime_data *prtd = runtime->private_data;
172
173 switch (cmd) {
174 case SNDRV_PCM_TRIGGER_START:
175 case SNDRV_PCM_TRIGGER_RESUME:
176 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
177 jz4740_pcm_start_transfer(prtd, substream);
178 break;
179 case SNDRV_PCM_TRIGGER_STOP:
180 case SNDRV_PCM_TRIGGER_SUSPEND:
181 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
182 jz4740_dma_disable(prtd->dma);
183 break;
184 default:
185 break;
186 }
187
188 return 0;
189}
190
191static snd_pcm_uframes_t jz4740_pcm_pointer(struct snd_pcm_substream *substream)
192{
193 struct snd_pcm_runtime *runtime = substream->runtime;
194 struct jz4740_runtime_data *prtd = runtime->private_data;
195 unsigned long byte_offset;
196 snd_pcm_uframes_t offset;
197 struct jz4740_dma_chan *dma = prtd->dma;
198
199 /* prtd->dma_pos points to the end of the current transfer. So by
200 * subtracting prdt->dma_start we get the offset to the end of the
201 * current period in bytes. By subtracting the residue of the transfer
202 * we get the current offset in bytes. */
203 byte_offset = prtd->dma_pos - prtd->dma_start;
204 byte_offset -= jz4740_dma_get_residue(dma);
205
206 offset = bytes_to_frames(runtime, byte_offset);
207 if (offset >= runtime->buffer_size)
208 offset = 0;
209
210 return offset;
211}
212
213static int jz4740_pcm_open(struct snd_pcm_substream *substream)
214{
215 struct snd_pcm_runtime *runtime = substream->runtime;
216 struct jz4740_runtime_data *prtd;
217
218 prtd = kzalloc(sizeof(*prtd), GFP_KERNEL);
219 if (prtd == NULL)
220 return -ENOMEM;
221
222 snd_soc_set_runtime_hwparams(substream, &jz4740_pcm_hardware);
223
224 runtime->private_data = prtd;
225
226 return 0;
227}
228
229static int jz4740_pcm_close(struct snd_pcm_substream *substream)
230{
231 struct snd_pcm_runtime *runtime = substream->runtime;
232 struct jz4740_runtime_data *prtd = runtime->private_data;
233
234 kfree(prtd);
235
236 return 0;
237}
238
239static int jz4740_pcm_mmap(struct snd_pcm_substream *substream,
240 struct vm_area_struct *vma)
241{
242 return remap_pfn_range(vma, vma->vm_start,
243 substream->dma_buffer.addr >> PAGE_SHIFT,
244 vma->vm_end - vma->vm_start, vma->vm_page_prot);
245}
246
247static struct snd_pcm_ops jz4740_pcm_ops = {
248 .open = jz4740_pcm_open,
249 .close = jz4740_pcm_close,
250 .ioctl = snd_pcm_lib_ioctl,
251 .hw_params = jz4740_pcm_hw_params,
252 .hw_free = jz4740_pcm_hw_free,
253 .prepare = jz4740_pcm_prepare,
254 .trigger = jz4740_pcm_trigger,
255 .pointer = jz4740_pcm_pointer,
256 .mmap = jz4740_pcm_mmap,
257};
258
259static int jz4740_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
260{
261 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
262 struct snd_dma_buffer *buf = &substream->dma_buffer;
263 size_t size = jz4740_pcm_hardware.buffer_bytes_max;
264
265 buf->dev.type = SNDRV_DMA_TYPE_DEV;
266 buf->dev.dev = pcm->card->dev;
267 buf->private_data = NULL;
268
269 buf->area = dma_alloc_noncoherent(pcm->card->dev, size,
270 &buf->addr, GFP_KERNEL);
271 if (!buf->area)
272 return -ENOMEM;
273
274 buf->bytes = size;
275
276 return 0;
277}
278
279static void jz4740_pcm_free(struct snd_pcm *pcm)
280{
281 struct snd_pcm_substream *substream;
282 struct snd_dma_buffer *buf;
283 int stream;
284
285 for (stream = 0; stream < SNDRV_PCM_STREAM_LAST; ++stream) {
286 substream = pcm->streams[stream].substream;
287 if (!substream)
288 continue;
289
290 buf = &substream->dma_buffer;
291 if (!buf->area)
292 continue;
293
294 dma_free_noncoherent(pcm->card->dev, buf->bytes, buf->area,
295 buf->addr);
296 buf->area = NULL;
297 }
298}
299
300static u64 jz4740_pcm_dmamask = DMA_BIT_MASK(32);
301
302int jz4740_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
303 struct snd_pcm *pcm)
304{
305 int ret = 0;
306
307 if (!card->dev->dma_mask)
308 card->dev->dma_mask = &jz4740_pcm_dmamask;
309
310 if (!card->dev->coherent_dma_mask)
311 card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
312
313 if (dai->playback.channels_min) {
314 ret = jz4740_pcm_preallocate_dma_buffer(pcm,
315 SNDRV_PCM_STREAM_PLAYBACK);
316 if (ret)
317 goto err;
318 }
319
320 if (dai->capture.channels_min) {
321 ret = jz4740_pcm_preallocate_dma_buffer(pcm,
322 SNDRV_PCM_STREAM_CAPTURE);
323 if (ret)
324 goto err;
325 }
326
327err:
328 return ret;
329}
330
331struct snd_soc_platform jz4740_soc_platform = {
332 .name = "jz4740-pcm",
333 .pcm_ops = &jz4740_pcm_ops,
334 .pcm_new = jz4740_pcm_new,
335 .pcm_free = jz4740_pcm_free,
336};
337EXPORT_SYMBOL_GPL(jz4740_soc_platform);
338
339static int __devinit jz4740_pcm_probe(struct platform_device *pdev)
340{
341 return snd_soc_register_platform(&jz4740_soc_platform);
342}
343
344static int __devexit jz4740_pcm_remove(struct platform_device *pdev)
345{
346 snd_soc_unregister_platform(&jz4740_soc_platform);
347 return 0;
348}
349
350static struct platform_driver jz4740_pcm_driver = {
351 .probe = jz4740_pcm_probe,
352 .remove = __devexit_p(jz4740_pcm_remove),
353 .driver = {
354 .name = "jz4740-pcm",
355 .owner = THIS_MODULE,
356 },
357};
358
359static int __init jz4740_soc_platform_init(void)
360{
361 return platform_driver_register(&jz4740_pcm_driver);
362}
363module_init(jz4740_soc_platform_init);
364
365static void __exit jz4740_soc_platform_exit(void)
366{
367 return platform_driver_unregister(&jz4740_pcm_driver);
368}
369module_exit(jz4740_soc_platform_exit);
370
371MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
372MODULE_DESCRIPTION("Ingenic SoC JZ4740 PCM driver");
373MODULE_LICENSE("GPL");
diff --git a/sound/soc/jz4740/jz4740-pcm.h b/sound/soc/jz4740/jz4740-pcm.h
new file mode 100644
index 00000000000..e3f221e2779
--- /dev/null
+++ b/sound/soc/jz4740/jz4740-pcm.h
@@ -0,0 +1,22 @@
1/*
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 as
5 * published by the Free Software Foundation.
6 */
7
8#ifndef _JZ4740_PCM_H
9#define _JZ4740_PCM_H
10
11#include <linux/dma-mapping.h>
12#include <asm/mach-jz4740/dma.h>
13
14/* platform data */
15extern struct snd_soc_platform jz4740_soc_platform;
16
17struct jz4740_pcm_config {
18 struct jz4740_dma_config dma_config;
19 phys_addr_t fifo_addr;
20};
21
22#endif
diff --git a/sound/soc/jz4740/qi_lb60.c b/sound/soc/jz4740/qi_lb60.c
new file mode 100644
index 00000000000..f15f4918f15
--- /dev/null
+++ b/sound/soc/jz4740/qi_lb60.c
@@ -0,0 +1,166 @@
1/*
2 * Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de>
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 * You should have received a copy of the GNU General Public License along
9 * with this program; if not, write to the Free Software Foundation, Inc.,
10 * 675 Mass Ave, Cambridge, MA 02139, USA.
11 *
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 <linux/gpio.h>
24
25#include "../codecs/jz4740.h"
26#include "jz4740-pcm.h"
27#include "jz4740-i2s.h"
28
29
30#define QI_LB60_SND_GPIO JZ_GPIO_PORTB(29)
31#define QI_LB60_AMP_GPIO JZ_GPIO_PORTD(4)
32
33static int qi_lb60_spk_event(struct snd_soc_dapm_widget *widget,
34 struct snd_kcontrol *ctrl, int event)
35{
36 int on = 0;
37 if (event & SND_SOC_DAPM_POST_PMU)
38 on = 1;
39 else if (event & SND_SOC_DAPM_PRE_PMD)
40 on = 0;
41
42 gpio_set_value(QI_LB60_SND_GPIO, on);
43 gpio_set_value(QI_LB60_AMP_GPIO, on);
44
45 return 0;
46}
47
48static const struct snd_soc_dapm_widget qi_lb60_widgets[] = {
49 SND_SOC_DAPM_SPK("Speaker", qi_lb60_spk_event),
50 SND_SOC_DAPM_MIC("Mic", NULL),
51};
52
53static const struct snd_soc_dapm_route qi_lb60_routes[] = {
54 {"Mic", NULL, "MIC"},
55 {"Speaker", NULL, "LOUT"},
56 {"Speaker", NULL, "ROUT"},
57};
58
59#define QI_LB60_DAIFMT (SND_SOC_DAIFMT_I2S | \
60 SND_SOC_DAIFMT_NB_NF | \
61 SND_SOC_DAIFMT_CBM_CFM)
62
63static int qi_lb60_codec_init(struct snd_soc_codec *codec)
64{
65 int ret;
66 struct snd_soc_dai *cpu_dai = codec->socdev->card->dai_link->cpu_dai;
67
68 snd_soc_dapm_nc_pin(codec, "LIN");
69 snd_soc_dapm_nc_pin(codec, "RIN");
70
71 ret = snd_soc_dai_set_fmt(cpu_dai, QI_LB60_DAIFMT);
72 if (ret < 0) {
73 dev_err(codec->dev, "Failed to set cpu dai format: %d\n", ret);
74 return ret;
75 }
76
77 snd_soc_dapm_new_controls(codec, qi_lb60_widgets, ARRAY_SIZE(qi_lb60_widgets));
78 snd_soc_dapm_add_routes(codec, qi_lb60_routes, ARRAY_SIZE(qi_lb60_routes));
79 snd_soc_dapm_sync(codec);
80
81 return 0;
82}
83
84static struct snd_soc_dai_link qi_lb60_dai = {
85 .name = "jz4740",
86 .stream_name = "jz4740",
87 .cpu_dai = &jz4740_i2s_dai,
88 .codec_dai = &jz4740_codec_dai,
89 .init = qi_lb60_codec_init,
90};
91
92static struct snd_soc_card qi_lb60 = {
93 .name = "QI LB60",
94 .dai_link = &qi_lb60_dai,
95 .num_links = 1,
96 .platform = &jz4740_soc_platform,
97};
98
99static struct snd_soc_device qi_lb60_snd_devdata = {
100 .card = &qi_lb60,
101 .codec_dev = &soc_codec_dev_jz4740_codec,
102};
103
104static struct platform_device *qi_lb60_snd_device;
105
106static int __init qi_lb60_init(void)
107{
108 int ret;
109
110 qi_lb60_snd_device = platform_device_alloc("soc-audio", -1);
111
112 if (!qi_lb60_snd_device)
113 return -ENOMEM;
114
115 ret = gpio_request(QI_LB60_SND_GPIO, "SND");
116 if (ret) {
117 pr_err("qi_lb60 snd: Failed to request SND GPIO(%d): %d\n",
118 QI_LB60_SND_GPIO, ret);
119 goto err_device_put;
120 }
121
122 ret = gpio_request(QI_LB60_AMP_GPIO, "AMP");
123 if (ret) {
124 pr_err("qi_lb60 snd: Failed to request AMP GPIO(%d): %d\n",
125 QI_LB60_AMP_GPIO, ret);
126 goto err_gpio_free_snd;
127 }
128
129 gpio_direction_output(QI_LB60_SND_GPIO, 0);
130 gpio_direction_output(QI_LB60_AMP_GPIO, 0);
131
132 platform_set_drvdata(qi_lb60_snd_device, &qi_lb60_snd_devdata);
133 qi_lb60_snd_devdata.dev = &qi_lb60_snd_device->dev;
134
135 ret = platform_device_add(qi_lb60_snd_device);
136 if (ret) {
137 pr_err("qi_lb60 snd: Failed to add snd soc device: %d\n", ret);
138 goto err_unset_pdata;
139 }
140
141 return 0;
142
143err_unset_pdata:
144 platform_set_drvdata(qi_lb60_snd_device, NULL);
145/*err_gpio_free_amp:*/
146 gpio_free(QI_LB60_AMP_GPIO);
147err_gpio_free_snd:
148 gpio_free(QI_LB60_SND_GPIO);
149err_device_put:
150 platform_device_put(qi_lb60_snd_device);
151
152 return ret;
153}
154module_init(qi_lb60_init);
155
156static void __exit qi_lb60_exit(void)
157{
158 gpio_free(QI_LB60_AMP_GPIO);
159 gpio_free(QI_LB60_SND_GPIO);
160 platform_device_unregister(qi_lb60_snd_device);
161}
162module_exit(qi_lb60_exit);
163
164MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
165MODULE_DESCRIPTION("ALSA SoC QI LB60 Audio support");
166MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/kirkwood/Kconfig b/sound/soc/kirkwood/Kconfig
new file mode 100644
index 00000000000..16ec2a2dba4
--- /dev/null
+++ b/sound/soc/kirkwood/Kconfig
@@ -0,0 +1,20 @@
1config SND_KIRKWOOD_SOC
2 tristate "SoC Audio for the Marvell Kirkwood chip"
3 depends on ARCH_KIRKWOOD
4 help
5 Say Y or M if you want to add support for codecs attached to
6 the Kirkwood I2S interface. You will also need to select the
7 audio interfaces to support below.
8
9config SND_KIRKWOOD_SOC_I2S
10 tristate
11
12config SND_KIRKWOOD_SOC_OPENRD
13 tristate "SoC Audio support for Kirkwood Openrd Client"
14 depends on SND_KIRKWOOD_SOC && MACH_OPENRD_CLIENT
15 select SND_KIRKWOOD_SOC_I2S
16 select SND_SOC_CS42L51
17 help
18 Say Y if you want to add support for SoC audio on
19 Openrd Client.
20
diff --git a/sound/soc/kirkwood/Makefile b/sound/soc/kirkwood/Makefile
new file mode 100644
index 00000000000..33a16dcab5b
--- /dev/null
+++ b/sound/soc/kirkwood/Makefile
@@ -0,0 +1,9 @@
1snd-soc-kirkwood-objs := kirkwood-dma.o
2snd-soc-kirkwood-i2s-objs := kirkwood-i2s.o
3
4obj-$(CONFIG_SND_KIRKWOOD_SOC) += snd-soc-kirkwood.o
5obj-$(CONFIG_SND_KIRKWOOD_SOC_I2S) += snd-soc-kirkwood-i2s.o
6
7snd-soc-openrd-objs := kirkwood-openrd.o
8
9obj-$(CONFIG_SND_KIRKWOOD_SOC_OPENRD) += snd-soc-openrd.o
diff --git a/sound/soc/kirkwood/kirkwood-dma.c b/sound/soc/kirkwood/kirkwood-dma.c
new file mode 100644
index 00000000000..a30205be3e2
--- /dev/null
+++ b/sound/soc/kirkwood/kirkwood-dma.c
@@ -0,0 +1,383 @@
1/*
2 * kirkwood-dma.c
3 *
4 * (c) 2010 Arnaud Patard <apatard@mandriva.com>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 */
11
12#include <linux/init.h>
13#include <linux/module.h>
14#include <linux/device.h>
15#include <linux/io.h>
16#include <linux/slab.h>
17#include <linux/interrupt.h>
18#include <linux/dma-mapping.h>
19#include <linux/mbus.h>
20#include <sound/soc.h>
21#include "kirkwood-dma.h"
22#include "kirkwood.h"
23
24#define KIRKWOOD_RATES \
25 (SNDRV_PCM_RATE_44100 | \
26 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000)
27#define KIRKWOOD_FORMATS \
28 (SNDRV_PCM_FMTBIT_S16_LE | \
29 SNDRV_PCM_FMTBIT_S24_LE | \
30 SNDRV_PCM_FMTBIT_S32_LE)
31
32struct kirkwood_dma_priv {
33 struct snd_pcm_substream *play_stream;
34 struct snd_pcm_substream *rec_stream;
35 struct kirkwood_dma_data *data;
36};
37
38static struct snd_pcm_hardware kirkwood_dma_snd_hw = {
39 .info = (SNDRV_PCM_INFO_INTERLEAVED |
40 SNDRV_PCM_INFO_MMAP |
41 SNDRV_PCM_INFO_MMAP_VALID |
42 SNDRV_PCM_INFO_BLOCK_TRANSFER |
43 SNDRV_PCM_INFO_PAUSE),
44 .formats = KIRKWOOD_FORMATS,
45 .rates = KIRKWOOD_RATES,
46 .rate_min = 44100,
47 .rate_max = 96000,
48 .channels_min = 1,
49 .channels_max = 2,
50 .buffer_bytes_max = KIRKWOOD_SND_MAX_PERIOD_BYTES * KIRKWOOD_SND_MAX_PERIODS,
51 .period_bytes_min = KIRKWOOD_SND_MIN_PERIOD_BYTES,
52 .period_bytes_max = KIRKWOOD_SND_MAX_PERIOD_BYTES,
53 .periods_min = KIRKWOOD_SND_MIN_PERIODS,
54 .periods_max = KIRKWOOD_SND_MAX_PERIODS,
55 .fifo_size = 0,
56};
57
58static u64 kirkwood_dma_dmamask = 0xFFFFFFFFUL;
59
60static irqreturn_t kirkwood_dma_irq(int irq, void *dev_id)
61{
62 struct kirkwood_dma_priv *prdata = dev_id;
63 struct kirkwood_dma_data *priv = prdata->data;
64 unsigned long mask, status, cause;
65
66 mask = readl(priv->io + KIRKWOOD_INT_MASK);
67 status = readl(priv->io + KIRKWOOD_INT_CAUSE) & mask;
68
69 cause = readl(priv->io + KIRKWOOD_ERR_CAUSE);
70 if (unlikely(cause)) {
71 printk(KERN_WARNING "%s: got err interrupt 0x%lx\n",
72 __func__, cause);
73 writel(cause, priv->io + KIRKWOOD_ERR_CAUSE);
74 return IRQ_HANDLED;
75 }
76
77 /* we've enabled only bytes interrupts ... */
78 if (status & ~(KIRKWOOD_INT_CAUSE_PLAY_BYTES | \
79 KIRKWOOD_INT_CAUSE_REC_BYTES)) {
80 printk(KERN_WARNING "%s: unexpected interrupt %lx\n",
81 __func__, status);
82 return IRQ_NONE;
83 }
84
85 /* ack int */
86 writel(status, priv->io + KIRKWOOD_INT_CAUSE);
87
88 if (status & KIRKWOOD_INT_CAUSE_PLAY_BYTES)
89 snd_pcm_period_elapsed(prdata->play_stream);
90
91 if (status & KIRKWOOD_INT_CAUSE_REC_BYTES)
92 snd_pcm_period_elapsed(prdata->rec_stream);
93
94 return IRQ_HANDLED;
95}
96
97static void kirkwood_dma_conf_mbus_windows(void __iomem *base, int win,
98 unsigned long dma,
99 struct mbus_dram_target_info *dram)
100{
101 int i;
102
103 /* First disable and clear windows */
104 writel(0, base + KIRKWOOD_AUDIO_WIN_CTRL_REG(win));
105 writel(0, base + KIRKWOOD_AUDIO_WIN_BASE_REG(win));
106
107 /* try to find matching cs for current dma address */
108 for (i = 0; i < dram->num_cs; i++) {
109 struct mbus_dram_window *cs = dram->cs + i;
110 if ((cs->base & 0xffff0000) < (dma & 0xffff0000)) {
111 writel(cs->base & 0xffff0000,
112 base + KIRKWOOD_AUDIO_WIN_BASE_REG(win));
113 writel(((cs->size - 1) & 0xffff0000) |
114 (cs->mbus_attr << 8) |
115 (dram->mbus_dram_target_id << 4) | 1,
116 base + KIRKWOOD_AUDIO_WIN_CTRL_REG(win));
117 }
118 }
119}
120
121static int kirkwood_dma_open(struct snd_pcm_substream *substream)
122{
123 int err;
124 struct snd_pcm_runtime *runtime = substream->runtime;
125 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
126 struct snd_soc_dai *cpu_dai = soc_runtime->dai->cpu_dai;
127 struct kirkwood_dma_data *priv;
128 struct kirkwood_dma_priv *prdata = cpu_dai->private_data;
129 unsigned long addr;
130
131 priv = snd_soc_dai_get_dma_data(cpu_dai, substream);
132 snd_soc_set_runtime_hwparams(substream, &kirkwood_dma_snd_hw);
133
134 /* Ensure that all constraints linked to dma burst are fullfilled */
135 err = snd_pcm_hw_constraint_minmax(runtime,
136 SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
137 priv->burst * 2,
138 KIRKWOOD_AUDIO_BUF_MAX-1);
139 if (err < 0)
140 return err;
141
142 err = snd_pcm_hw_constraint_step(runtime, 0,
143 SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
144 priv->burst);
145 if (err < 0)
146 return err;
147
148 err = snd_pcm_hw_constraint_step(substream->runtime, 0,
149 SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
150 priv->burst);
151 if (err < 0)
152 return err;
153
154 if (soc_runtime->dai->cpu_dai->private_data == NULL) {
155 prdata = kzalloc(sizeof(struct kirkwood_dma_priv), GFP_KERNEL);
156 if (prdata == NULL)
157 return -ENOMEM;
158
159 prdata->data = priv;
160
161 err = request_irq(priv->irq, kirkwood_dma_irq, IRQF_SHARED,
162 "kirkwood-i2s", prdata);
163 if (err) {
164 kfree(prdata);
165 return -EBUSY;
166 }
167
168 soc_runtime->dai->cpu_dai->private_data = prdata;
169
170 /*
171 * Enable Error interrupts. We're only ack'ing them but
172 * it's usefull for diagnostics
173 */
174 writel((unsigned long)-1, priv->io + KIRKWOOD_ERR_MASK);
175 }
176
177 addr = virt_to_phys(substream->dma_buffer.area);
178 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
179 prdata->play_stream = substream;
180 kirkwood_dma_conf_mbus_windows(priv->io,
181 KIRKWOOD_PLAYBACK_WIN, addr, priv->dram);
182 } else {
183 prdata->rec_stream = substream;
184 kirkwood_dma_conf_mbus_windows(priv->io,
185 KIRKWOOD_RECORD_WIN, addr, priv->dram);
186 }
187
188 return 0;
189}
190
191static int kirkwood_dma_close(struct snd_pcm_substream *substream)
192{
193 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
194 struct snd_soc_dai *cpu_dai = soc_runtime->dai->cpu_dai;
195 struct kirkwood_dma_priv *prdata = cpu_dai->private_data;
196 struct kirkwood_dma_data *priv;
197
198 priv = snd_soc_dai_get_dma_data(cpu_dai, substream);
199
200 if (!prdata || !priv)
201 return 0;
202
203 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
204 prdata->play_stream = NULL;
205 else
206 prdata->rec_stream = NULL;
207
208 if (!prdata->play_stream && !prdata->rec_stream) {
209 writel(0, priv->io + KIRKWOOD_ERR_MASK);
210 free_irq(priv->irq, prdata);
211 kfree(prdata);
212 soc_runtime->dai->cpu_dai->private_data = NULL;
213 }
214
215 return 0;
216}
217
218static int kirkwood_dma_hw_params(struct snd_pcm_substream *substream,
219 struct snd_pcm_hw_params *params)
220{
221 struct snd_pcm_runtime *runtime = substream->runtime;
222
223 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
224 runtime->dma_bytes = params_buffer_bytes(params);
225
226 return 0;
227}
228
229static int kirkwood_dma_hw_free(struct snd_pcm_substream *substream)
230{
231 snd_pcm_set_runtime_buffer(substream, NULL);
232 return 0;
233}
234
235static int kirkwood_dma_prepare(struct snd_pcm_substream *substream)
236{
237 struct snd_pcm_runtime *runtime = substream->runtime;
238 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
239 struct snd_soc_dai *cpu_dai = soc_runtime->dai->cpu_dai;
240 struct kirkwood_dma_data *priv;
241 unsigned long size, count;
242
243 priv = snd_soc_dai_get_dma_data(cpu_dai, substream);
244
245 /* compute buffer size in term of "words" as requested in specs */
246 size = frames_to_bytes(runtime, runtime->buffer_size);
247 size = (size>>2)-1;
248 count = snd_pcm_lib_period_bytes(substream);
249
250 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
251 writel(count, priv->io + KIRKWOOD_PLAY_BYTE_INT_COUNT);
252 writel(runtime->dma_addr, priv->io + KIRKWOOD_PLAY_BUF_ADDR);
253 writel(size, priv->io + KIRKWOOD_PLAY_BUF_SIZE);
254 } else {
255 writel(count, priv->io + KIRKWOOD_REC_BYTE_INT_COUNT);
256 writel(runtime->dma_addr, priv->io + KIRKWOOD_REC_BUF_ADDR);
257 writel(size, priv->io + KIRKWOOD_REC_BUF_SIZE);
258 }
259
260
261 return 0;
262}
263
264static snd_pcm_uframes_t kirkwood_dma_pointer(struct snd_pcm_substream
265 *substream)
266{
267 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
268 struct snd_soc_dai *cpu_dai = soc_runtime->dai->cpu_dai;
269 struct kirkwood_dma_data *priv;
270 snd_pcm_uframes_t count;
271
272 priv = snd_soc_dai_get_dma_data(cpu_dai, substream);
273
274 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
275 count = bytes_to_frames(substream->runtime,
276 readl(priv->io + KIRKWOOD_PLAY_BYTE_COUNT));
277 else
278 count = bytes_to_frames(substream->runtime,
279 readl(priv->io + KIRKWOOD_REC_BYTE_COUNT));
280
281 return count;
282}
283
284struct snd_pcm_ops kirkwood_dma_ops = {
285 .open = kirkwood_dma_open,
286 .close = kirkwood_dma_close,
287 .ioctl = snd_pcm_lib_ioctl,
288 .hw_params = kirkwood_dma_hw_params,
289 .hw_free = kirkwood_dma_hw_free,
290 .prepare = kirkwood_dma_prepare,
291 .pointer = kirkwood_dma_pointer,
292};
293
294static int kirkwood_dma_preallocate_dma_buffer(struct snd_pcm *pcm,
295 int stream)
296{
297 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
298 struct snd_dma_buffer *buf = &substream->dma_buffer;
299 size_t size = kirkwood_dma_snd_hw.buffer_bytes_max;
300
301 buf->dev.type = SNDRV_DMA_TYPE_DEV;
302 buf->dev.dev = pcm->card->dev;
303 buf->area = dma_alloc_coherent(pcm->card->dev, size,
304 &buf->addr, GFP_KERNEL);
305 if (!buf->area)
306 return -ENOMEM;
307 buf->bytes = size;
308 buf->private_data = NULL;
309
310 return 0;
311}
312
313static int kirkwood_dma_new(struct snd_card *card,
314 struct snd_soc_dai *dai, struct snd_pcm *pcm)
315{
316 int ret;
317
318 if (!card->dev->dma_mask)
319 card->dev->dma_mask = &kirkwood_dma_dmamask;
320 if (!card->dev->coherent_dma_mask)
321 card->dev->coherent_dma_mask = 0xffffffff;
322
323 if (dai->playback.channels_min) {
324 ret = kirkwood_dma_preallocate_dma_buffer(pcm,
325 SNDRV_PCM_STREAM_PLAYBACK);
326 if (ret)
327 return ret;
328 }
329
330 if (dai->capture.channels_min) {
331 ret = kirkwood_dma_preallocate_dma_buffer(pcm,
332 SNDRV_PCM_STREAM_CAPTURE);
333 if (ret)
334 return ret;
335 }
336
337 return 0;
338}
339
340static void kirkwood_dma_free_dma_buffers(struct snd_pcm *pcm)
341{
342 struct snd_pcm_substream *substream;
343 struct snd_dma_buffer *buf;
344 int stream;
345
346 for (stream = 0; stream < 2; stream++) {
347 substream = pcm->streams[stream].substream;
348 if (!substream)
349 continue;
350 buf = &substream->dma_buffer;
351 if (!buf->area)
352 continue;
353
354 dma_free_coherent(pcm->card->dev, buf->bytes,
355 buf->area, buf->addr);
356 buf->area = NULL;
357 }
358}
359
360struct snd_soc_platform kirkwood_soc_platform = {
361 .name = "kirkwood-dma",
362 .pcm_ops = &kirkwood_dma_ops,
363 .pcm_new = kirkwood_dma_new,
364 .pcm_free = kirkwood_dma_free_dma_buffers,
365};
366EXPORT_SYMBOL_GPL(kirkwood_soc_platform);
367
368static int __init kirkwood_soc_platform_init(void)
369{
370 return snd_soc_register_platform(&kirkwood_soc_platform);
371}
372module_init(kirkwood_soc_platform_init);
373
374static void __exit kirkwood_soc_platform_exit(void)
375{
376 snd_soc_unregister_platform(&kirkwood_soc_platform);
377}
378module_exit(kirkwood_soc_platform_exit);
379
380MODULE_AUTHOR("Arnaud Patard <apatard@mandriva.com>");
381MODULE_DESCRIPTION("Marvell Kirkwood Audio DMA module");
382MODULE_LICENSE("GPL");
383
diff --git a/sound/soc/kirkwood/kirkwood-dma.h b/sound/soc/kirkwood/kirkwood-dma.h
new file mode 100644
index 00000000000..ba4454cd34f
--- /dev/null
+++ b/sound/soc/kirkwood/kirkwood-dma.h
@@ -0,0 +1,17 @@
1/*
2 * kirkwood-dma.h
3 *
4 * (c) 2010 Arnaud Patard <apatard@mandriva.com>
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#ifndef _KIRKWOOD_DMA_H
13#define _KIRKWOOD_DMA_H
14
15extern struct snd_soc_platform kirkwood_soc_platform;
16
17#endif
diff --git a/sound/soc/kirkwood/kirkwood-i2s.c b/sound/soc/kirkwood/kirkwood-i2s.c
new file mode 100644
index 00000000000..981ffc2a13c
--- /dev/null
+++ b/sound/soc/kirkwood/kirkwood-i2s.c
@@ -0,0 +1,495 @@
1/*
2 * kirkwood-i2s.c
3 *
4 * (c) 2010 Arnaud Patard <apatard@mandriva.com>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 */
11
12#include <linux/init.h>
13#include <linux/module.h>
14#include <linux/platform_device.h>
15#include <linux/io.h>
16#include <linux/slab.h>
17#include <linux/mbus.h>
18#include <linux/delay.h>
19#include <sound/pcm.h>
20#include <sound/pcm_params.h>
21#include <sound/soc.h>
22#include <plat/audio.h>
23#include "kirkwood-i2s.h"
24#include "kirkwood.h"
25
26#define DRV_NAME "kirkwood-i2s"
27
28#define KIRKWOOD_I2S_RATES \
29 (SNDRV_PCM_RATE_44100 | \
30 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000)
31#define KIRKWOOD_I2S_FORMATS \
32 (SNDRV_PCM_FMTBIT_S16_LE | \
33 SNDRV_PCM_FMTBIT_S24_LE | \
34 SNDRV_PCM_FMTBIT_S32_LE)
35
36
37struct snd_soc_dai kirkwood_i2s_dai;
38static struct kirkwood_dma_data *priv;
39
40static int kirkwood_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
41 unsigned int fmt)
42{
43 unsigned long mask;
44 unsigned long value;
45
46 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
47 case SND_SOC_DAIFMT_RIGHT_J:
48 mask = KIRKWOOD_I2S_CTL_RJ;
49 break;
50 case SND_SOC_DAIFMT_LEFT_J:
51 mask = KIRKWOOD_I2S_CTL_LJ;
52 break;
53 case SND_SOC_DAIFMT_I2S:
54 mask = KIRKWOOD_I2S_CTL_I2S;
55 break;
56 default:
57 return -EINVAL;
58 }
59
60 /*
61 * Set same format for playback and record
62 * This avoids some troubles.
63 */
64 value = readl(priv->io+KIRKWOOD_I2S_PLAYCTL);
65 value &= ~KIRKWOOD_I2S_CTL_JUST_MASK;
66 value |= mask;
67 writel(value, priv->io+KIRKWOOD_I2S_PLAYCTL);
68
69 value = readl(priv->io+KIRKWOOD_I2S_RECCTL);
70 value &= ~KIRKWOOD_I2S_CTL_JUST_MASK;
71 value |= mask;
72 writel(value, priv->io+KIRKWOOD_I2S_RECCTL);
73
74 return 0;
75}
76
77static inline void kirkwood_set_dco(void __iomem *io, unsigned long rate)
78{
79 unsigned long value;
80
81 value = KIRKWOOD_DCO_CTL_OFFSET_0;
82 switch (rate) {
83 default:
84 case 44100:
85 value |= KIRKWOOD_DCO_CTL_FREQ_11;
86 break;
87 case 48000:
88 value |= KIRKWOOD_DCO_CTL_FREQ_12;
89 break;
90 case 96000:
91 value |= KIRKWOOD_DCO_CTL_FREQ_24;
92 break;
93 }
94 writel(value, io + KIRKWOOD_DCO_CTL);
95
96 /* wait for dco locked */
97 do {
98 cpu_relax();
99 value = readl(io + KIRKWOOD_DCO_SPCR_STATUS);
100 value &= KIRKWOOD_DCO_SPCR_STATUS;
101 } while (value == 0);
102}
103
104static int kirkwood_i2s_hw_params(struct snd_pcm_substream *substream,
105 struct snd_pcm_hw_params *params,
106 struct snd_soc_dai *dai)
107{
108 unsigned int i2s_reg, reg;
109 unsigned long i2s_value, value;
110
111 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
112 i2s_reg = KIRKWOOD_I2S_PLAYCTL;
113 reg = KIRKWOOD_PLAYCTL;
114 } else {
115 i2s_reg = KIRKWOOD_I2S_RECCTL;
116 reg = KIRKWOOD_RECCTL;
117 }
118
119 /* set dco conf */
120 kirkwood_set_dco(priv->io, params_rate(params));
121
122 i2s_value = readl(priv->io+i2s_reg);
123 i2s_value &= ~KIRKWOOD_I2S_CTL_SIZE_MASK;
124
125 value = readl(priv->io+reg);
126 value &= ~KIRKWOOD_PLAYCTL_SIZE_MASK;
127
128 /*
129 * Size settings in play/rec i2s control regs and play/rec control
130 * regs must be the same.
131 */
132 switch (params_format(params)) {
133 case SNDRV_PCM_FORMAT_S16_LE:
134 i2s_value |= KIRKWOOD_I2S_CTL_SIZE_16;
135 value |= KIRKWOOD_PLAYCTL_SIZE_16_C;
136 break;
137 /*
138 * doesn't work... S20_3LE != kirkwood 20bit format ?
139 *
140 case SNDRV_PCM_FORMAT_S20_3LE:
141 i2s_value |= KIRKWOOD_I2S_CTL_SIZE_20;
142 value |= KIRKWOOD_PLAYCTL_SIZE_20;
143 break;
144 */
145 case SNDRV_PCM_FORMAT_S24_LE:
146 i2s_value |= KIRKWOOD_I2S_CTL_SIZE_24;
147 value |= KIRKWOOD_PLAYCTL_SIZE_24;
148 break;
149 case SNDRV_PCM_FORMAT_S32_LE:
150 i2s_value |= KIRKWOOD_I2S_CTL_SIZE_32;
151 value |= KIRKWOOD_PLAYCTL_SIZE_32;
152 break;
153 default:
154 return -EINVAL;
155 }
156
157 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
158 value &= ~KIRKWOOD_PLAYCTL_MONO_MASK;
159 if (params_channels(params) == 1)
160 value |= KIRKWOOD_PLAYCTL_MONO_BOTH;
161 else
162 value |= KIRKWOOD_PLAYCTL_MONO_OFF;
163 }
164
165 writel(i2s_value, priv->io+i2s_reg);
166 writel(value, priv->io+reg);
167
168 return 0;
169}
170
171static int kirkwood_i2s_play_trigger(struct snd_pcm_substream *substream,
172 int cmd, struct snd_soc_dai *dai)
173{
174 unsigned long value;
175
176 /*
177 * specs says KIRKWOOD_PLAYCTL must be read 2 times before
178 * changing it. So read 1 time here and 1 later.
179 */
180 value = readl(priv->io + KIRKWOOD_PLAYCTL);
181
182 switch (cmd) {
183 case SNDRV_PCM_TRIGGER_START:
184 /* stop audio, enable interrupts */
185 value = readl(priv->io + KIRKWOOD_PLAYCTL);
186 value |= KIRKWOOD_PLAYCTL_PAUSE;
187 writel(value, priv->io + KIRKWOOD_PLAYCTL);
188
189 value = readl(priv->io + KIRKWOOD_INT_MASK);
190 value |= KIRKWOOD_INT_CAUSE_PLAY_BYTES;
191 writel(value, priv->io + KIRKWOOD_INT_MASK);
192
193 /* configure audio & enable i2s playback */
194 value = readl(priv->io + KIRKWOOD_PLAYCTL);
195 value &= ~KIRKWOOD_PLAYCTL_BURST_MASK;
196 value &= ~(KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE
197 | KIRKWOOD_PLAYCTL_SPDIF_EN);
198
199 if (priv->burst == 32)
200 value |= KIRKWOOD_PLAYCTL_BURST_32;
201 else
202 value |= KIRKWOOD_PLAYCTL_BURST_128;
203 value |= KIRKWOOD_PLAYCTL_I2S_EN;
204 writel(value, priv->io + KIRKWOOD_PLAYCTL);
205 break;
206
207 case SNDRV_PCM_TRIGGER_STOP:
208 /* stop audio, disable interrupts */
209 value = readl(priv->io + KIRKWOOD_PLAYCTL);
210 value |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE;
211 writel(value, priv->io + KIRKWOOD_PLAYCTL);
212
213 value = readl(priv->io + KIRKWOOD_INT_MASK);
214 value &= ~KIRKWOOD_INT_CAUSE_PLAY_BYTES;
215 writel(value, priv->io + KIRKWOOD_INT_MASK);
216
217 /* disable all playbacks */
218 value = readl(priv->io + KIRKWOOD_PLAYCTL);
219 value &= ~(KIRKWOOD_PLAYCTL_I2S_EN | KIRKWOOD_PLAYCTL_SPDIF_EN);
220 writel(value, priv->io + KIRKWOOD_PLAYCTL);
221 break;
222
223 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
224 case SNDRV_PCM_TRIGGER_SUSPEND:
225 value = readl(priv->io + KIRKWOOD_PLAYCTL);
226 value |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE;
227 writel(value, priv->io + KIRKWOOD_PLAYCTL);
228 break;
229
230 case SNDRV_PCM_TRIGGER_RESUME:
231 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
232 value = readl(priv->io + KIRKWOOD_PLAYCTL);
233 value &= ~(KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE);
234 writel(value, priv->io + KIRKWOOD_PLAYCTL);
235 break;
236
237 default:
238 return -EINVAL;
239 }
240
241 return 0;
242}
243
244static int kirkwood_i2s_rec_trigger(struct snd_pcm_substream *substream,
245 int cmd, struct snd_soc_dai *dai)
246{
247 unsigned long value;
248
249 value = readl(priv->io + KIRKWOOD_RECCTL);
250
251 switch (cmd) {
252 case SNDRV_PCM_TRIGGER_START:
253 /* stop audio, enable interrupts */
254 value = readl(priv->io + KIRKWOOD_RECCTL);
255 value |= KIRKWOOD_RECCTL_PAUSE;
256 writel(value, priv->io + KIRKWOOD_RECCTL);
257
258 value = readl(priv->io + KIRKWOOD_INT_MASK);
259 value |= KIRKWOOD_INT_CAUSE_REC_BYTES;
260 writel(value, priv->io + KIRKWOOD_INT_MASK);
261
262 /* configure audio & enable i2s record */
263 value = readl(priv->io + KIRKWOOD_RECCTL);
264 value &= ~KIRKWOOD_RECCTL_BURST_MASK;
265 value &= ~KIRKWOOD_RECCTL_MONO;
266 value &= ~(KIRKWOOD_RECCTL_PAUSE | KIRKWOOD_RECCTL_MUTE
267 | KIRKWOOD_RECCTL_SPDIF_EN);
268
269 if (priv->burst == 32)
270 value |= KIRKWOOD_RECCTL_BURST_32;
271 else
272 value |= KIRKWOOD_RECCTL_BURST_128;
273 value |= KIRKWOOD_RECCTL_I2S_EN;
274
275 writel(value, priv->io + KIRKWOOD_RECCTL);
276 break;
277
278 case SNDRV_PCM_TRIGGER_STOP:
279 /* stop audio, disable interrupts */
280 value = readl(priv->io + KIRKWOOD_RECCTL);
281 value |= KIRKWOOD_RECCTL_PAUSE | KIRKWOOD_RECCTL_MUTE;
282 writel(value, priv->io + KIRKWOOD_RECCTL);
283
284 value = readl(priv->io + KIRKWOOD_INT_MASK);
285 value &= ~KIRKWOOD_INT_CAUSE_REC_BYTES;
286 writel(value, priv->io + KIRKWOOD_INT_MASK);
287
288 /* disable all records */
289 value = readl(priv->io + KIRKWOOD_RECCTL);
290 value &= ~(KIRKWOOD_RECCTL_I2S_EN | KIRKWOOD_RECCTL_SPDIF_EN);
291 writel(value, priv->io + KIRKWOOD_RECCTL);
292 break;
293
294 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
295 case SNDRV_PCM_TRIGGER_SUSPEND:
296 value = readl(priv->io + KIRKWOOD_RECCTL);
297 value |= KIRKWOOD_RECCTL_PAUSE | KIRKWOOD_RECCTL_MUTE;
298 writel(value, priv->io + KIRKWOOD_RECCTL);
299 break;
300
301 case SNDRV_PCM_TRIGGER_RESUME:
302 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
303 value = readl(priv->io + KIRKWOOD_RECCTL);
304 value &= ~(KIRKWOOD_RECCTL_PAUSE | KIRKWOOD_RECCTL_MUTE);
305 writel(value, priv->io + KIRKWOOD_RECCTL);
306 break;
307
308 default:
309 return -EINVAL;
310 }
311
312 return 0;
313}
314
315static int kirkwood_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
316 struct snd_soc_dai *dai)
317{
318 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
319 return kirkwood_i2s_play_trigger(substream, cmd, dai);
320 else
321 return kirkwood_i2s_rec_trigger(substream, cmd, dai);
322
323 return 0;
324}
325
326static int kirkwood_i2s_probe(struct platform_device *pdev,
327 struct snd_soc_dai *dai)
328{
329 unsigned long value;
330 unsigned int reg_data;
331
332 /* put system in a "safe" state : */
333 /* disable audio interrupts */
334 writel(0xffffffff, priv->io + KIRKWOOD_INT_CAUSE);
335 writel(0, priv->io + KIRKWOOD_INT_MASK);
336
337 reg_data = readl(priv->io + 0x1200);
338 reg_data &= (~(0x333FF8));
339 reg_data |= 0x111D18;
340 writel(reg_data, priv->io + 0x1200);
341
342 msleep(500);
343
344 reg_data = readl(priv->io + 0x1200);
345 reg_data &= (~(0x333FF8));
346 reg_data |= 0x111D18;
347 writel(reg_data, priv->io + 0x1200);
348
349 /* disable playback/record */
350 value = readl(priv->io + KIRKWOOD_PLAYCTL);
351 value &= ~(KIRKWOOD_PLAYCTL_I2S_EN|KIRKWOOD_PLAYCTL_SPDIF_EN);
352 writel(value, priv->io + KIRKWOOD_PLAYCTL);
353
354 value = readl(priv->io + KIRKWOOD_RECCTL);
355 value &= ~(KIRKWOOD_RECCTL_I2S_EN | KIRKWOOD_RECCTL_SPDIF_EN);
356 writel(value, priv->io + KIRKWOOD_RECCTL);
357
358 return 0;
359
360}
361
362static void kirkwood_i2s_remove(struct platform_device *pdev,
363 struct snd_soc_dai *dai)
364{
365}
366
367static struct snd_soc_dai_ops kirkwood_i2s_dai_ops = {
368 .trigger = kirkwood_i2s_trigger,
369 .hw_params = kirkwood_i2s_hw_params,
370 .set_fmt = kirkwood_i2s_set_fmt,
371};
372
373
374struct snd_soc_dai kirkwood_i2s_dai = {
375 .name = DRV_NAME,
376 .id = 0,
377 .probe = kirkwood_i2s_probe,
378 .remove = kirkwood_i2s_remove,
379 .playback = {
380 .channels_min = 1,
381 .channels_max = 2,
382 .rates = KIRKWOOD_I2S_RATES,
383 .formats = KIRKWOOD_I2S_FORMATS,},
384 .capture = {
385 .channels_min = 1,
386 .channels_max = 2,
387 .rates = KIRKWOOD_I2S_RATES,
388 .formats = KIRKWOOD_I2S_FORMATS,},
389 .ops = &kirkwood_i2s_dai_ops,
390};
391EXPORT_SYMBOL_GPL(kirkwood_i2s_dai);
392
393static __devinit int kirkwood_i2s_dev_probe(struct platform_device *pdev)
394{
395 struct resource *mem;
396 struct kirkwood_asoc_platform_data *data =
397 pdev->dev.platform_data;
398 int err;
399
400 priv = kzalloc(sizeof(struct kirkwood_dma_data), GFP_KERNEL);
401 if (!priv) {
402 dev_err(&pdev->dev, "allocation failed\n");
403 err = -ENOMEM;
404 goto error;
405 }
406
407 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
408 if (!mem) {
409 dev_err(&pdev->dev, "platform_get_resource failed\n");
410 err = -ENXIO;
411 goto err_alloc;
412 }
413
414 priv->mem = request_mem_region(mem->start, SZ_16K, DRV_NAME);
415 if (!priv->mem) {
416 dev_err(&pdev->dev, "request_mem_region failed\n");
417 err = -EBUSY;
418 goto error;
419 }
420
421 priv->io = ioremap(priv->mem->start, SZ_16K);
422 if (!priv->io) {
423 dev_err(&pdev->dev, "ioremap failed\n");
424 err = -ENOMEM;
425 goto err_iomem;
426 }
427
428 priv->irq = platform_get_irq(pdev, 0);
429 if (priv->irq <= 0) {
430 dev_err(&pdev->dev, "platform_get_irq failed\n");
431 err = -ENXIO;
432 goto err_ioremap;
433 }
434
435 if (!data || !data->dram) {
436 dev_err(&pdev->dev, "no platform data ?!\n");
437 err = -EINVAL;
438 goto err_ioremap;
439 }
440
441 priv->dram = data->dram;
442 priv->burst = data->burst;
443
444 kirkwood_i2s_dai.capture.dma_data = priv;
445 kirkwood_i2s_dai.playback.dma_data = priv;
446
447 return snd_soc_register_dai(&kirkwood_i2s_dai);
448
449err_ioremap:
450 iounmap(priv->io);
451err_iomem:
452 release_mem_region(priv->mem->start, SZ_16K);
453err_alloc:
454 kfree(priv);
455error:
456 return err;
457}
458
459static __devexit int kirkwood_i2s_dev_remove(struct platform_device *pdev)
460{
461 if (priv) {
462 iounmap(priv->io);
463 release_mem_region(priv->mem->start, SZ_16K);
464 kfree(priv);
465 }
466 snd_soc_unregister_dai(&kirkwood_i2s_dai);
467 return 0;
468}
469
470static struct platform_driver kirkwood_i2s_driver = {
471 .probe = kirkwood_i2s_dev_probe,
472 .remove = kirkwood_i2s_dev_remove,
473 .driver = {
474 .name = DRV_NAME,
475 .owner = THIS_MODULE,
476 },
477};
478
479static int __init kirkwood_i2s_init(void)
480{
481 return platform_driver_register(&kirkwood_i2s_driver);
482}
483module_init(kirkwood_i2s_init);
484
485static void __exit kirkwood_i2s_exit(void)
486{
487 platform_driver_unregister(&kirkwood_i2s_driver);
488}
489module_exit(kirkwood_i2s_exit);
490
491/* Module information */
492MODULE_AUTHOR("Arnaud Patard, <apatard@mandriva.com>");
493MODULE_DESCRIPTION("Kirkwood I2S SoC Interface");
494MODULE_LICENSE("GPL");
495MODULE_ALIAS("platform:kirkwood-i2s");
diff --git a/sound/soc/kirkwood/kirkwood-i2s.h b/sound/soc/kirkwood/kirkwood-i2s.h
new file mode 100644
index 00000000000..c5595c616d7
--- /dev/null
+++ b/sound/soc/kirkwood/kirkwood-i2s.h
@@ -0,0 +1,17 @@
1/*
2 * kirkwood-i2s.h
3 *
4 * (c) 2010 Arnaud Patard <apatard@mandriva.com>
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#ifndef _KIRKWOOD_I2S_H
13#define _KIRKWOOD_I2S_H
14
15extern struct snd_soc_dai kirkwood_i2s_dai;
16
17#endif
diff --git a/sound/soc/kirkwood/kirkwood-openrd.c b/sound/soc/kirkwood/kirkwood-openrd.c
new file mode 100644
index 00000000000..0353d06bc41
--- /dev/null
+++ b/sound/soc/kirkwood/kirkwood-openrd.c
@@ -0,0 +1,126 @@
1/*
2 * kirkwood-openrd.c
3 *
4 * (c) 2010 Arnaud Patard <apatard@mandriva.com>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 */
11
12#include <linux/module.h>
13#include <linux/moduleparam.h>
14#include <linux/interrupt.h>
15#include <linux/platform_device.h>
16#include <linux/slab.h>
17#include <sound/soc.h>
18#include <mach/kirkwood.h>
19#include <plat/audio.h>
20#include <asm/mach-types.h>
21#include "kirkwood-i2s.h"
22#include "kirkwood-dma.h"
23#include "../codecs/cs42l51.h"
24
25static int openrd_client_hw_params(struct snd_pcm_substream *substream,
26 struct snd_pcm_hw_params *params)
27{
28 struct snd_soc_pcm_runtime *rtd = substream->private_data;
29 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
30 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
31 int ret;
32 unsigned int freq, fmt;
33
34 fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS;
35 ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
36 if (ret < 0)
37 return ret;
38
39 ret = snd_soc_dai_set_fmt(codec_dai, fmt);
40 if (ret < 0)
41 return ret;
42
43 switch (params_rate(params)) {
44 default:
45 case 44100:
46 freq = 11289600;
47 break;
48 case 48000:
49 freq = 12288000;
50 break;
51 case 96000:
52 freq = 24576000;
53 break;
54 }
55
56 return snd_soc_dai_set_sysclk(codec_dai, 0, freq, SND_SOC_CLOCK_IN);
57
58}
59
60static struct snd_soc_ops openrd_client_ops = {
61 .hw_params = openrd_client_hw_params,
62};
63
64
65static struct snd_soc_dai_link openrd_client_dai[] = {
66{
67 .name = "CS42L51",
68 .stream_name = "CS42L51 HiFi",
69 .cpu_dai = &kirkwood_i2s_dai,
70 .codec_dai = &cs42l51_dai,
71 .ops = &openrd_client_ops,
72},
73};
74
75
76static struct snd_soc_card openrd_client = {
77 .name = "OpenRD Client",
78 .platform = &kirkwood_soc_platform,
79 .dai_link = openrd_client_dai,
80 .num_links = ARRAY_SIZE(openrd_client_dai),
81};
82
83static struct snd_soc_device openrd_client_snd_devdata = {
84 .card = &openrd_client,
85 .codec_dev = &soc_codec_device_cs42l51,
86};
87
88static struct platform_device *openrd_client_snd_device;
89
90static int __init openrd_client_init(void)
91{
92 int ret;
93
94 if (!machine_is_openrd_client())
95 return 0;
96
97 openrd_client_snd_device = platform_device_alloc("soc-audio", -1);
98 if (!openrd_client_snd_device)
99 return -ENOMEM;
100
101 platform_set_drvdata(openrd_client_snd_device,
102 &openrd_client_snd_devdata);
103 openrd_client_snd_devdata.dev = &openrd_client_snd_device->dev;
104
105 ret = platform_device_add(openrd_client_snd_device);
106 if (ret) {
107 printk(KERN_ERR "%s: platform_device_add failed\n", __func__);
108 platform_device_put(openrd_client_snd_device);
109 }
110
111 return ret;
112}
113
114static void __exit openrd_client_exit(void)
115{
116 platform_device_unregister(openrd_client_snd_device);
117}
118
119module_init(openrd_client_init);
120module_exit(openrd_client_exit);
121
122/* Module information */
123MODULE_AUTHOR("Arnaud Patard <apatard@mandriva.com>");
124MODULE_DESCRIPTION("ALSA SoC OpenRD Client");
125MODULE_LICENSE("GPL");
126MODULE_ALIAS("platform:soc-audio");
diff --git a/sound/soc/kirkwood/kirkwood.h b/sound/soc/kirkwood/kirkwood.h
new file mode 100644
index 00000000000..bb6e6a5648c
--- /dev/null
+++ b/sound/soc/kirkwood/kirkwood.h
@@ -0,0 +1,129 @@
1/*
2 * kirkwood.h
3 *
4 * (c) 2010 Arnaud Patard <apatard@mandriva.com>
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#ifndef _KIRKWOOD_AUDIO_H
13#define _KIRKWOOD_AUDIO_H
14
15#define KIRKWOOD_RECORD_WIN 0
16#define KIRKWOOD_PLAYBACK_WIN 1
17#define KIRKWOOD_MAX_AUDIO_WIN 2
18
19#define KIRKWOOD_AUDIO_WIN_BASE_REG(win) (0xA00 + ((win)<<3))
20#define KIRKWOOD_AUDIO_WIN_CTRL_REG(win) (0xA04 + ((win)<<3))
21
22
23#define KIRKWOOD_RECCTL 0x1000
24#define KIRKWOOD_RECCTL_SPDIF_EN (1<<11)
25#define KIRKWOOD_RECCTL_I2S_EN (1<<10)
26#define KIRKWOOD_RECCTL_PAUSE (1<<9)
27#define KIRKWOOD_RECCTL_MUTE (1<<8)
28#define KIRKWOOD_RECCTL_BURST_MASK (3<<5)
29#define KIRKWOOD_RECCTL_BURST_128 (2<<5)
30#define KIRKWOOD_RECCTL_BURST_32 (1<<5)
31#define KIRKWOOD_RECCTL_MONO (1<<4)
32#define KIRKWOOD_RECCTL_MONO_CHAN_RIGHT (1<<3)
33#define KIRKWOOD_RECCTL_MONO_CHAN_LEFT (0<<3)
34#define KIRKWOOD_RECCTL_SIZE_MASK (7<<0)
35#define KIRKWOOD_RECCTL_SIZE_16 (7<<0)
36#define KIRKWOOD_RECCTL_SIZE_16_C (3<<0)
37#define KIRKWOOD_RECCTL_SIZE_20 (2<<0)
38#define KIRKWOOD_RECCTL_SIZE_24 (1<<0)
39#define KIRKWOOD_RECCTL_SIZE_32 (0<<0)
40
41#define KIRKWOOD_REC_BUF_ADDR 0x1004
42#define KIRKWOOD_REC_BUF_SIZE 0x1008
43#define KIRKWOOD_REC_BYTE_COUNT 0x100C
44
45#define KIRKWOOD_PLAYCTL 0x1100
46#define KIRKWOOD_PLAYCTL_PLAY_BUSY (1<<16)
47#define KIRKWOOD_PLAYCTL_BURST_MASK (3<<11)
48#define KIRKWOOD_PLAYCTL_BURST_128 (2<<11)
49#define KIRKWOOD_PLAYCTL_BURST_32 (1<<11)
50#define KIRKWOOD_PLAYCTL_PAUSE (1<<9)
51#define KIRKWOOD_PLAYCTL_SPDIF_MUTE (1<<8)
52#define KIRKWOOD_PLAYCTL_MONO_MASK (3<<5)
53#define KIRKWOOD_PLAYCTL_MONO_BOTH (3<<5)
54#define KIRKWOOD_PLAYCTL_MONO_OFF (0<<5)
55#define KIRKWOOD_PLAYCTL_I2S_MUTE (1<<7)
56#define KIRKWOOD_PLAYCTL_SPDIF_EN (1<<4)
57#define KIRKWOOD_PLAYCTL_I2S_EN (1<<3)
58#define KIRKWOOD_PLAYCTL_SIZE_MASK (7<<0)
59#define KIRKWOOD_PLAYCTL_SIZE_16 (7<<0)
60#define KIRKWOOD_PLAYCTL_SIZE_16_C (3<<0)
61#define KIRKWOOD_PLAYCTL_SIZE_20 (2<<0)
62#define KIRKWOOD_PLAYCTL_SIZE_24 (1<<0)
63#define KIRKWOOD_PLAYCTL_SIZE_32 (0<<0)
64
65#define KIRKWOOD_PLAY_BUF_ADDR 0x1104
66#define KIRKWOOD_PLAY_BUF_SIZE 0x1108
67#define KIRKWOOD_PLAY_BYTE_COUNT 0x110C
68
69#define KIRKWOOD_DCO_CTL 0x1204
70#define KIRKWOOD_DCO_CTL_OFFSET_MASK (0xFFF<<2)
71#define KIRKWOOD_DCO_CTL_OFFSET_0 (0x800<<2)
72#define KIRKWOOD_DCO_CTL_FREQ_MASK (3<<0)
73#define KIRKWOOD_DCO_CTL_FREQ_11 (0<<0)
74#define KIRKWOOD_DCO_CTL_FREQ_12 (1<<0)
75#define KIRKWOOD_DCO_CTL_FREQ_24 (2<<0)
76
77#define KIRKWOOD_DCO_SPCR_STATUS 0x120c
78#define KIRKWOOD_DCO_SPCR_STATUS_DCO_LOCK (1<<16)
79
80#define KIRKWOOD_ERR_CAUSE 0x1300
81#define KIRKWOOD_ERR_MASK 0x1304
82
83#define KIRKWOOD_INT_CAUSE 0x1308
84#define KIRKWOOD_INT_MASK 0x130C
85#define KIRKWOOD_INT_CAUSE_PLAY_BYTES (1<<14)
86#define KIRKWOOD_INT_CAUSE_REC_BYTES (1<<13)
87#define KIRKWOOD_INT_CAUSE_DMA_PLAY_END (1<<7)
88#define KIRKWOOD_INT_CAUSE_DMA_PLAY_3Q (1<<6)
89#define KIRKWOOD_INT_CAUSE_DMA_PLAY_HALF (1<<5)
90#define KIRKWOOD_INT_CAUSE_DMA_PLAY_1Q (1<<4)
91#define KIRKWOOD_INT_CAUSE_DMA_REC_END (1<<3)
92#define KIRKWOOD_INT_CAUSE_DMA_REC_3Q (1<<2)
93#define KIRKWOOD_INT_CAUSE_DMA_REC_HALF (1<<1)
94#define KIRKWOOD_INT_CAUSE_DMA_REC_1Q (1<<0)
95
96#define KIRKWOOD_REC_BYTE_INT_COUNT 0x1310
97#define KIRKWOOD_PLAY_BYTE_INT_COUNT 0x1314
98#define KIRKWOOD_BYTE_INT_COUNT_MASK 0xffffff
99
100#define KIRKWOOD_I2S_PLAYCTL 0x2508
101#define KIRKWOOD_I2S_RECCTL 0x2408
102#define KIRKWOOD_I2S_CTL_JUST_MASK (0xf<<26)
103#define KIRKWOOD_I2S_CTL_LJ (0<<26)
104#define KIRKWOOD_I2S_CTL_I2S (5<<26)
105#define KIRKWOOD_I2S_CTL_RJ (8<<26)
106#define KIRKWOOD_I2S_CTL_SIZE_MASK (3<<30)
107#define KIRKWOOD_I2S_CTL_SIZE_16 (3<<30)
108#define KIRKWOOD_I2S_CTL_SIZE_20 (2<<30)
109#define KIRKWOOD_I2S_CTL_SIZE_24 (1<<30)
110#define KIRKWOOD_I2S_CTL_SIZE_32 (0<<30)
111
112#define KIRKWOOD_AUDIO_BUF_MAX (16*1024*1024)
113
114/* Theses values come from the marvell alsa driver */
115/* need to find where they come from */
116#define KIRKWOOD_SND_MIN_PERIODS 8
117#define KIRKWOOD_SND_MAX_PERIODS 16
118#define KIRKWOOD_SND_MIN_PERIOD_BYTES 0x4000
119#define KIRKWOOD_SND_MAX_PERIOD_BYTES 0x4000
120
121struct kirkwood_dma_data {
122 struct resource *mem;
123 void __iomem *io;
124 int irq;
125 int burst;
126 struct mbus_dram_target_info *dram;
127};
128
129#endif
diff --git a/sound/soc/nuc900/Kconfig b/sound/soc/nuc900/Kconfig
new file mode 100644
index 00000000000..a0ed1c618f6
--- /dev/null
+++ b/sound/soc/nuc900/Kconfig
@@ -0,0 +1,27 @@
1##
2## NUC900 series AC97 API
3##
4config SND_SOC_NUC900
5 tristate "SoC Audio for NUC900 series"
6 depends on ARCH_W90X900
7 help
8 This option enables support for AC97 mode on the NUC900 SoC.
9
10config SND_SOC_NUC900_AC97
11 tristate
12 select AC97_BUS
13 select SND_AC97_CODEC
14 select SND_SOC_AC97_BUS
15
16
17##
18## Boards
19##
20config SND_SOC_NUC900EVB
21 tristate "NUC900 AC97 support for demo board"
22 depends on SND_SOC_NUC900
23 select SND_SOC_NUC900_AC97
24 select SND_SOC_AC97_CODEC
25 help
26 Select this option to enable audio (AC97) on the
27 NUC900 demoboard.
diff --git a/sound/soc/nuc900/Makefile b/sound/soc/nuc900/Makefile
new file mode 100644
index 00000000000..7e46c715031
--- /dev/null
+++ b/sound/soc/nuc900/Makefile
@@ -0,0 +1,11 @@
1# NUC900 series audio
2snd-soc-nuc900-pcm-objs := nuc900-pcm.o
3snd-soc-nuc900-ac97-objs := nuc900-ac97.o
4
5obj-$(CONFIG_SND_SOC_NUC900) += snd-soc-nuc900-pcm.o
6obj-$(CONFIG_SND_SOC_NUC900_AC97) += snd-soc-nuc900-ac97.o
7
8# Boards
9snd-soc-nuc900-audio-objs := nuc900-audio.o
10
11obj-$(CONFIG_SND_SOC_NUC900EVB) += snd-soc-nuc900-audio.o
diff --git a/sound/soc/nuc900/nuc900-ac97.c b/sound/soc/nuc900/nuc900-ac97.c
new file mode 100644
index 00000000000..caa7c901bc2
--- /dev/null
+++ b/sound/soc/nuc900/nuc900-ac97.c
@@ -0,0 +1,430 @@
1/*
2 * Copyright (c) 2009-2010 Nuvoton technology corporation.
3 *
4 * Wan ZongShun <mcuos.com@gmail.com>
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 as published by
8 * the Free Software Foundation;version 2 of the License.
9 *
10 */
11
12#include <linux/init.h>
13#include <linux/module.h>
14#include <linux/slab.h>
15#include <linux/device.h>
16#include <linux/delay.h>
17#include <linux/mutex.h>
18#include <linux/suspend.h>
19#include <sound/core.h>
20#include <sound/pcm.h>
21#include <sound/initval.h>
22#include <sound/soc.h>
23#include <linux/device.h>
24#include <linux/clk.h>
25
26#include <mach/mfp.h>
27
28#include "nuc900-audio.h"
29
30static DEFINE_MUTEX(ac97_mutex);
31struct nuc900_audio *nuc900_ac97_data;
32
33static int nuc900_checkready(void)
34{
35 struct nuc900_audio *nuc900_audio = nuc900_ac97_data;
36
37 if (!(AUDIO_READ(nuc900_audio->mmio + ACTL_ACIS0) & CODEC_READY))
38 return -EPERM;
39
40 return 0;
41}
42
43/* AC97 controller reads codec register */
44static unsigned short nuc900_ac97_read(struct snd_ac97 *ac97,
45 unsigned short reg)
46{
47 struct nuc900_audio *nuc900_audio = nuc900_ac97_data;
48 unsigned long timeout = 0x10000, val;
49
50 mutex_lock(&ac97_mutex);
51
52 val = nuc900_checkready();
53 if (!!val) {
54 dev_err(nuc900_audio->dev, "AC97 codec is not ready\n");
55 goto out;
56 }
57
58 /* set the R_WB bit and write register index */
59 AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACOS1, R_WB | reg);
60
61 /* set the valid frame bit and valid slots */
62 val = AUDIO_READ(nuc900_audio->mmio + ACTL_ACOS0);
63 val |= (VALID_FRAME | SLOT1_VALID);
64 AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACOS0, val);
65
66 udelay(100);
67
68 /* polling the AC_R_FINISH */
69 while (!(AUDIO_READ(nuc900_audio->mmio + ACTL_ACCON) & AC_R_FINISH)
70 && timeout--)
71 mdelay(1);
72
73 if (!timeout) {
74 dev_err(nuc900_audio->dev, "AC97 read register time out !\n");
75 val = -EPERM;
76 goto out;
77 }
78
79 val = AUDIO_READ(nuc900_audio->mmio + ACTL_ACOS0) ;
80 val &= ~SLOT1_VALID;
81 AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACOS0, val);
82
83 if (AUDIO_READ(nuc900_audio->mmio + ACTL_ACIS1) >> 2 != reg) {
84 dev_err(nuc900_audio->dev,
85 "R_INDEX of REG_ACTL_ACIS1 not match!\n");
86 }
87
88 udelay(100);
89 val = (AUDIO_READ(nuc900_audio->mmio + ACTL_ACIS2) & 0xFFFF);
90
91out:
92 mutex_unlock(&ac97_mutex);
93 return val;
94}
95
96/* AC97 controller writes to codec register */
97static void nuc900_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
98 unsigned short val)
99{
100 struct nuc900_audio *nuc900_audio = nuc900_ac97_data;
101 unsigned long tmp, timeout = 0x10000;
102
103 mutex_lock(&ac97_mutex);
104
105 tmp = nuc900_checkready();
106 if (!!tmp)
107 dev_err(nuc900_audio->dev, "AC97 codec is not ready\n");
108
109 /* clear the R_WB bit and write register index */
110 AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACOS1, reg);
111
112 /* write register value */
113 AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACOS2, val);
114
115 /* set the valid frame bit and valid slots */
116 tmp = AUDIO_READ(nuc900_audio->mmio + ACTL_ACOS0);
117 tmp |= SLOT1_VALID | SLOT2_VALID | VALID_FRAME;
118 AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACOS0, tmp);
119
120 udelay(100);
121
122 /* polling the AC_W_FINISH */
123 while ((AUDIO_READ(nuc900_audio->mmio + ACTL_ACCON) & AC_W_FINISH)
124 && timeout--)
125 mdelay(1);
126
127 if (!timeout)
128 dev_err(nuc900_audio->dev, "AC97 write register time out !\n");
129
130 tmp = AUDIO_READ(nuc900_audio->mmio + ACTL_ACOS0);
131 tmp &= ~(SLOT1_VALID | SLOT2_VALID);
132 AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACOS0, tmp);
133
134 mutex_unlock(&ac97_mutex);
135
136}
137
138static void nuc900_ac97_warm_reset(struct snd_ac97 *ac97)
139{
140 struct nuc900_audio *nuc900_audio = nuc900_ac97_data;
141 unsigned long val;
142
143 mutex_lock(&ac97_mutex);
144
145 /* warm reset AC 97 */
146 val = AUDIO_READ(nuc900_audio->mmio + ACTL_ACCON);
147 val |= AC_W_RES;
148 AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACCON, val);
149
150 udelay(100);
151
152 val = nuc900_checkready();
153 if (!!val)
154 dev_err(nuc900_audio->dev, "AC97 codec is not ready\n");
155
156 mutex_unlock(&ac97_mutex);
157}
158
159static void nuc900_ac97_cold_reset(struct snd_ac97 *ac97)
160{
161 struct nuc900_audio *nuc900_audio = nuc900_ac97_data;
162 unsigned long val;
163
164 mutex_lock(&ac97_mutex);
165
166 /* reset Audio Controller */
167 val = AUDIO_READ(nuc900_audio->mmio + ACTL_RESET);
168 val |= ACTL_RESET_BIT;
169 AUDIO_WRITE(nuc900_audio->mmio + ACTL_RESET, val);
170
171 val = AUDIO_READ(nuc900_audio->mmio + ACTL_RESET);
172 val &= (~ACTL_RESET_BIT);
173 AUDIO_WRITE(nuc900_audio->mmio + ACTL_RESET, val);
174
175 /* reset AC-link interface */
176
177 val = AUDIO_READ(nuc900_audio->mmio + ACTL_RESET);
178 val |= AC_RESET;
179 AUDIO_WRITE(nuc900_audio->mmio + ACTL_RESET, val);
180
181 val = AUDIO_READ(nuc900_audio->mmio + ACTL_RESET);
182 val &= ~AC_RESET;
183 AUDIO_WRITE(nuc900_audio->mmio + ACTL_RESET, val);
184
185 /* cold reset AC 97 */
186 val = AUDIO_READ(nuc900_audio->mmio + ACTL_ACCON);
187 val |= AC_C_RES;
188 AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACCON, val);
189
190 val = AUDIO_READ(nuc900_audio->mmio + ACTL_ACCON);
191 val &= (~AC_C_RES);
192 AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACCON, val);
193
194 udelay(100);
195
196 mutex_unlock(&ac97_mutex);
197
198}
199
200/* AC97 controller operations */
201struct snd_ac97_bus_ops soc_ac97_ops = {
202 .read = nuc900_ac97_read,
203 .write = nuc900_ac97_write,
204 .reset = nuc900_ac97_cold_reset,
205 .warm_reset = nuc900_ac97_warm_reset,
206}
207EXPORT_SYMBOL_GPL(soc_ac97_ops);
208
209static int nuc900_ac97_trigger(struct snd_pcm_substream *substream,
210 int cmd, struct snd_soc_dai *dai)
211{
212 struct nuc900_audio *nuc900_audio = nuc900_ac97_data;
213 int ret;
214 unsigned long val, tmp;
215
216 ret = 0;
217
218 switch (cmd) {
219 case SNDRV_PCM_TRIGGER_START:
220 case SNDRV_PCM_TRIGGER_RESUME:
221 val = AUDIO_READ(nuc900_audio->mmio + ACTL_RESET);
222 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
223 tmp = AUDIO_READ(nuc900_audio->mmio + ACTL_ACOS0);
224 tmp |= (SLOT3_VALID | SLOT4_VALID | VALID_FRAME);
225 AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACOS0, tmp);
226
227 tmp = AUDIO_READ(nuc900_audio->mmio + ACTL_PSR);
228 tmp |= (P_DMA_END_IRQ | P_DMA_MIDDLE_IRQ);
229 AUDIO_WRITE(nuc900_audio->mmio + ACTL_PSR, tmp);
230 val |= AC_PLAY;
231 } else {
232 tmp = AUDIO_READ(nuc900_audio->mmio + ACTL_RSR);
233 tmp |= (R_DMA_END_IRQ | R_DMA_MIDDLE_IRQ);
234
235 AUDIO_WRITE(nuc900_audio->mmio + ACTL_RSR, tmp);
236 val |= AC_RECORD;
237 }
238
239 AUDIO_WRITE(nuc900_audio->mmio + ACTL_RESET, val);
240
241 break;
242 case SNDRV_PCM_TRIGGER_STOP:
243 case SNDRV_PCM_TRIGGER_SUSPEND:
244 val = AUDIO_READ(nuc900_audio->mmio + ACTL_RESET);
245 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
246 tmp = AUDIO_READ(nuc900_audio->mmio + ACTL_ACOS0);
247 tmp &= ~(SLOT3_VALID | SLOT4_VALID);
248 AUDIO_WRITE(nuc900_audio->mmio + ACTL_ACOS0, tmp);
249
250 AUDIO_WRITE(nuc900_audio->mmio + ACTL_PSR, RESET_PRSR);
251 val &= ~AC_PLAY;
252 } else {
253 AUDIO_WRITE(nuc900_audio->mmio + ACTL_RSR, RESET_PRSR);
254 val &= ~AC_RECORD;
255 }
256
257 AUDIO_WRITE(nuc900_audio->mmio + ACTL_RESET, val);
258
259 break;
260 default:
261 ret = -EINVAL;
262 }
263
264 return ret;
265}
266
267static int nuc900_ac97_probe(struct platform_device *pdev,
268 struct snd_soc_dai *dai)
269{
270 struct nuc900_audio *nuc900_audio = nuc900_ac97_data;
271 unsigned long val;
272
273 mutex_lock(&ac97_mutex);
274
275 /* enable unit clock */
276 clk_enable(nuc900_audio->clk);
277
278 /* enable audio controller and AC-link interface */
279 val = AUDIO_READ(nuc900_audio->mmio + ACTL_CON);
280 val |= (IIS_AC_PIN_SEL | ACLINK_EN);
281 AUDIO_WRITE(nuc900_audio->mmio + ACTL_CON, val);
282
283 mutex_unlock(&ac97_mutex);
284
285 return 0;
286}
287
288static void nuc900_ac97_remove(struct platform_device *pdev,
289 struct snd_soc_dai *dai)
290{
291 struct nuc900_audio *nuc900_audio = nuc900_ac97_data;
292
293 clk_disable(nuc900_audio->clk);
294}
295
296static struct snd_soc_dai_ops nuc900_ac97_dai_ops = {
297 .trigger = nuc900_ac97_trigger,
298};
299
300struct snd_soc_dai nuc900_ac97_dai = {
301 .name = "nuc900-ac97",
302 .probe = nuc900_ac97_probe,
303 .remove = nuc900_ac97_remove,
304 .ac97_control = 1,
305 .playback = {
306 .rates = SNDRV_PCM_RATE_8000_48000,
307 .formats = SNDRV_PCM_FMTBIT_S16_LE,
308 .channels_min = 1,
309 .channels_max = 2,
310 },
311 .capture = {
312 .rates = SNDRV_PCM_RATE_8000_48000,
313 .formats = SNDRV_PCM_FMTBIT_S16_LE,
314 .channels_min = 1,
315 .channels_max = 2,
316 },
317 .ops = &nuc900_ac97_dai_ops,
318}
319EXPORT_SYMBOL_GPL(nuc900_ac97_dai);
320
321static int __devinit nuc900_ac97_drvprobe(struct platform_device *pdev)
322{
323 struct nuc900_audio *nuc900_audio;
324 int ret;
325
326 if (nuc900_ac97_data)
327 return -EBUSY;
328
329 nuc900_audio = kzalloc(sizeof(struct nuc900_audio), GFP_KERNEL);
330 if (!nuc900_audio)
331 return -ENOMEM;
332
333 spin_lock_init(&nuc900_audio->lock);
334
335 nuc900_audio->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
336 if (!nuc900_audio->res) {
337 ret = -ENODEV;
338 goto out0;
339 }
340
341 if (!request_mem_region(nuc900_audio->res->start,
342 resource_size(nuc900_audio->res), pdev->name)) {
343 ret = -EBUSY;
344 goto out0;
345 }
346
347 nuc900_audio->mmio = ioremap(nuc900_audio->res->start,
348 resource_size(nuc900_audio->res));
349 if (!nuc900_audio->mmio) {
350 ret = -ENOMEM;
351 goto out1;
352 }
353
354 nuc900_audio->clk = clk_get(&pdev->dev, NULL);
355 if (IS_ERR(nuc900_audio->clk)) {
356 ret = PTR_ERR(nuc900_audio->clk);
357 goto out2;
358 }
359
360 nuc900_audio->irq_num = platform_get_irq(pdev, 0);
361 if (!nuc900_audio->irq_num) {
362 ret = -EBUSY;
363 goto out2;
364 }
365
366 nuc900_ac97_data = nuc900_audio;
367
368 nuc900_audio->dev = nuc900_ac97_dai.dev = &pdev->dev;
369
370 ret = snd_soc_register_dai(&nuc900_ac97_dai);
371 if (ret)
372 goto out3;
373
374 mfp_set_groupg(nuc900_audio->dev); /* enbale ac97 multifunction pin*/
375
376 return 0;
377
378out3:
379 clk_put(nuc900_audio->clk);
380out2:
381 iounmap(nuc900_audio->mmio);
382out1:
383 release_mem_region(nuc900_audio->res->start,
384 resource_size(nuc900_audio->res));
385out0:
386 kfree(nuc900_audio);
387 return ret;
388}
389
390static int __devexit nuc900_ac97_drvremove(struct platform_device *pdev)
391{
392
393 snd_soc_unregister_dai(&nuc900_ac97_dai);
394
395 clk_put(nuc900_ac97_data->clk);
396 iounmap(nuc900_ac97_data->mmio);
397 release_mem_region(nuc900_ac97_data->res->start,
398 resource_size(nuc900_ac97_data->res));
399
400 nuc900_ac97_data = NULL;
401
402 return 0;
403}
404
405static struct platform_driver nuc900_ac97_driver = {
406 .driver = {
407 .name = "nuc900-audio",
408 .owner = THIS_MODULE,
409 },
410 .probe = nuc900_ac97_drvprobe,
411 .remove = __devexit_p(nuc900_ac97_drvremove),
412};
413
414static int __init nuc900_ac97_init(void)
415{
416 return platform_driver_register(&nuc900_ac97_driver);
417}
418
419static void __exit nuc900_ac97_exit(void)
420{
421 platform_driver_unregister(&nuc900_ac97_driver);
422}
423
424module_init(nuc900_ac97_init);
425module_exit(nuc900_ac97_exit);
426
427MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>");
428MODULE_DESCRIPTION("NUC900 AC97 SoC driver!");
429MODULE_LICENSE("GPL");
430MODULE_ALIAS("platform:nuc900-ac97");
diff --git a/sound/soc/nuc900/nuc900-audio.c b/sound/soc/nuc900/nuc900-audio.c
new file mode 100644
index 00000000000..72e6f518f7b
--- /dev/null
+++ b/sound/soc/nuc900/nuc900-audio.c
@@ -0,0 +1,81 @@
1/*
2 * Copyright (c) 2010 Nuvoton technology corporation.
3 *
4 * Wan ZongShun <mcuos.com@gmail.com>
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 as published by
8 * the Free Software Foundation;version 2 of the License.
9 *
10 */
11
12#include <linux/module.h>
13#include <linux/moduleparam.h>
14#include <linux/timer.h>
15#include <linux/interrupt.h>
16#include <linux/platform_device.h>
17
18#include <sound/core.h>
19#include <sound/pcm.h>
20#include <sound/soc.h>
21#include <sound/soc-dapm.h>
22
23#include "../codecs/ac97.h"
24#include "nuc900-audio.h"
25
26static struct snd_soc_dai_link nuc900evb_ac97_dai = {
27 .name = "AC97",
28 .stream_name = "AC97 HiFi",
29 .cpu_dai = &nuc900_ac97_dai,
30 .codec_dai = &ac97_dai,
31};
32
33static struct snd_soc_card nuc900evb_audio_machine = {
34 .name = "NUC900EVB_AC97",
35 .dai_link = &nuc900evb_ac97_dai,
36 .num_links = 1,
37 .platform = &nuc900_soc_platform,
38};
39
40static struct snd_soc_device nuc900evb_ac97_devdata = {
41 .card = &nuc900evb_audio_machine,
42 .codec_dev = &soc_codec_dev_ac97,
43};
44
45static struct platform_device *nuc900evb_asoc_dev;
46
47static int __init nuc900evb_audio_init(void)
48{
49 int ret;
50
51 ret = -ENOMEM;
52 nuc900evb_asoc_dev = platform_device_alloc("soc-audio", -1);
53 if (!nuc900evb_asoc_dev)
54 goto out;
55
56 /* nuc900 board audio device */
57 platform_set_drvdata(nuc900evb_asoc_dev, &nuc900evb_ac97_devdata);
58
59 nuc900evb_ac97_devdata.dev = &nuc900evb_asoc_dev->dev;
60 ret = platform_device_add(nuc900evb_asoc_dev);
61
62 if (ret) {
63 platform_device_put(nuc900evb_asoc_dev);
64 nuc900evb_asoc_dev = NULL;
65 }
66
67out:
68 return ret;
69}
70
71static void __exit nuc900evb_audio_exit(void)
72{
73 platform_device_unregister(nuc900evb_asoc_dev);
74}
75
76module_init(nuc900evb_audio_init);
77module_exit(nuc900evb_audio_exit);
78
79MODULE_LICENSE("GPL");
80MODULE_DESCRIPTION("NUC900 Series ASoC audio support");
81MODULE_AUTHOR("Wan ZongShun");
diff --git a/sound/soc/nuc900/nuc900-audio.h b/sound/soc/nuc900/nuc900-audio.h
new file mode 100644
index 00000000000..3038f519729
--- /dev/null
+++ b/sound/soc/nuc900/nuc900-audio.h
@@ -0,0 +1,117 @@
1/*
2 * Copyright (c) 2010 Nuvoton technology corporation.
3 *
4 * Wan ZongShun <mcuos.com@gmail.com>
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 as published by
8 * the Free Software Foundation;version 2 of the License.
9 *
10 */
11
12#ifndef _NUC900_AUDIO_H
13#define _NUC900_AUDIO_H
14
15#include <linux/io.h>
16
17/* Audio Control Registers */
18#define ACTL_CON 0x00
19#define ACTL_RESET 0x04
20#define ACTL_RDSTB 0x08
21#define ACTL_RDST_LENGTH 0x0C
22#define ACTL_RDSTC 0x10
23#define ACTL_RSR 0x14
24#define ACTL_PDSTB 0x18
25#define ACTL_PDST_LENGTH 0x1C
26#define ACTL_PDSTC 0x20
27#define ACTL_PSR 0x24
28#define ACTL_IISCON 0x28
29#define ACTL_ACCON 0x2C
30#define ACTL_ACOS0 0x30
31#define ACTL_ACOS1 0x34
32#define ACTL_ACOS2 0x38
33#define ACTL_ACIS0 0x3C
34#define ACTL_ACIS1 0x40
35#define ACTL_ACIS2 0x44
36#define ACTL_COUNTER 0x48
37
38/* bit definition of REG_ACTL_CON register */
39#define R_DMA_IRQ 0x1000
40#define T_DMA_IRQ 0x0800
41#define IIS_AC_PIN_SEL 0x0100
42#define FIFO_TH 0x0080
43#define ADC_EN 0x0010
44#define M80_EN 0x0008
45#define ACLINK_EN 0x0004
46#define IIS_EN 0x0002
47
48/* bit definition of REG_ACTL_RESET register */
49#define W5691_PLAY 0x20000
50#define ACTL_RESET_BIT 0x10000
51#define RECORD_RIGHT_CHNNEL 0x08000
52#define RECORD_LEFT_CHNNEL 0x04000
53#define PLAY_RIGHT_CHNNEL 0x02000
54#define PLAY_LEFT_CHNNEL 0x01000
55#define DAC_PLAY 0x00800
56#define ADC_RECORD 0x00400
57#define M80_PLAY 0x00200
58#define AC_RECORD 0x00100
59#define AC_PLAY 0x00080
60#define IIS_RECORD 0x00040
61#define IIS_PLAY 0x00020
62#define DAC_RESET 0x00010
63#define ADC_RESET 0x00008
64#define M80_RESET 0x00004
65#define AC_RESET 0x00002
66#define IIS_RESET 0x00001
67
68/* bit definition of REG_ACTL_ACCON register */
69#define AC_BCLK_PU_EN 0x20
70#define AC_R_FINISH 0x10
71#define AC_W_FINISH 0x08
72#define AC_W_RES 0x04
73#define AC_C_RES 0x02
74
75/* bit definition of ACTL_RSR register */
76#define R_FIFO_EMPTY 0x04
77#define R_DMA_END_IRQ 0x02
78#define R_DMA_MIDDLE_IRQ 0x01
79
80/* bit definition of ACTL_PSR register */
81#define P_FIFO_EMPTY 0x04
82#define P_DMA_END_IRQ 0x02
83#define P_DMA_MIDDLE_IRQ 0x01
84
85/* bit definition of ACTL_ACOS0 register */
86#define SLOT1_VALID 0x01
87#define SLOT2_VALID 0x02
88#define SLOT3_VALID 0x04
89#define SLOT4_VALID 0x08
90#define VALID_FRAME 0x10
91
92/* bit definition of ACTL_ACOS1 register */
93#define R_WB 0x80
94
95#define CODEC_READY 0x10
96#define RESET_PRSR 0x00
97#define AUDIO_WRITE(addr, val) __raw_writel(val, addr)
98#define AUDIO_READ(addr) __raw_readl(addr)
99
100struct nuc900_audio {
101 void __iomem *mmio;
102 spinlock_t lock;
103 dma_addr_t dma_addr[2];
104 unsigned long buffersize[2];
105 unsigned long irq_num;
106 struct snd_pcm_substream *substream;
107 struct resource *res;
108 struct clk *clk;
109 struct device *dev;
110
111};
112
113extern struct nuc900_audio *nuc900_ac97_data;
114extern struct snd_soc_dai nuc900_ac97_dai;
115extern struct snd_soc_platform nuc900_soc_platform;
116
117#endif /*end _NUC900_AUDIO_H */
diff --git a/sound/soc/nuc900/nuc900-pcm.c b/sound/soc/nuc900/nuc900-pcm.c
new file mode 100644
index 00000000000..e81e803b3a6
--- /dev/null
+++ b/sound/soc/nuc900/nuc900-pcm.c
@@ -0,0 +1,354 @@
1/*
2 * Copyright (c) 2010 Nuvoton technology corporation.
3 *
4 * Wan ZongShun <mcuos.com@gmail.com>
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 as published by
8 * the Free Software Foundation;version 2 of the License.
9 *
10 */
11
12#include <linux/module.h>
13#include <linux/init.h>
14#include <linux/io.h>
15#include <linux/platform_device.h>
16#include <linux/slab.h>
17#include <linux/dma-mapping.h>
18
19#include <sound/core.h>
20#include <sound/pcm.h>
21#include <sound/pcm_params.h>
22#include <sound/soc.h>
23
24#include <mach/hardware.h>
25
26#include "nuc900-audio.h"
27
28static const struct snd_pcm_hardware nuc900_pcm_hardware = {
29 .info = SNDRV_PCM_INFO_INTERLEAVED |
30 SNDRV_PCM_INFO_BLOCK_TRANSFER |
31 SNDRV_PCM_INFO_MMAP |
32 SNDRV_PCM_INFO_MMAP_VALID |
33 SNDRV_PCM_INFO_PAUSE |
34 SNDRV_PCM_INFO_RESUME,
35 .formats = SNDRV_PCM_FMTBIT_S16_LE,
36 .channels_min = 1,
37 .channels_max = 2,
38 .buffer_bytes_max = 4*1024,
39 .period_bytes_min = 1*1024,
40 .period_bytes_max = 4*1024,
41 .periods_min = 1,
42 .periods_max = 1024,
43};
44
45static int nuc900_dma_hw_params(struct snd_pcm_substream *substream,
46 struct snd_pcm_hw_params *params)
47{
48 struct snd_pcm_runtime *runtime = substream->runtime;
49 struct nuc900_audio *nuc900_audio = runtime->private_data;
50 unsigned long flags;
51 int ret = 0;
52
53 spin_lock_irqsave(&nuc900_audio->lock, flags);
54
55 ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
56 if (ret < 0)
57 return ret;
58
59 nuc900_audio->substream = substream;
60 nuc900_audio->dma_addr[substream->stream] = runtime->dma_addr;
61 nuc900_audio->buffersize[substream->stream] =
62 params_buffer_bytes(params);
63
64 spin_unlock_irqrestore(&nuc900_audio->lock, flags);
65
66 return ret;
67}
68
69static void nuc900_update_dma_register(struct snd_pcm_substream *substream,
70 dma_addr_t dma_addr, size_t count)
71{
72 struct snd_pcm_runtime *runtime = substream->runtime;
73 struct nuc900_audio *nuc900_audio = runtime->private_data;
74 void __iomem *mmio_addr, *mmio_len;
75
76 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
77 mmio_addr = nuc900_audio->mmio + ACTL_PDSTB;
78 mmio_len = nuc900_audio->mmio + ACTL_PDST_LENGTH;
79 } else {
80 mmio_addr = nuc900_audio->mmio + ACTL_RDSTB;
81 mmio_len = nuc900_audio->mmio + ACTL_RDST_LENGTH;
82 }
83
84 AUDIO_WRITE(mmio_addr, dma_addr);
85 AUDIO_WRITE(mmio_len, count);
86}
87
88static void nuc900_dma_start(struct snd_pcm_substream *substream)
89{
90 struct snd_pcm_runtime *runtime = substream->runtime;
91 struct nuc900_audio *nuc900_audio = runtime->private_data;
92 unsigned long val;
93
94 val = AUDIO_READ(nuc900_audio->mmio + ACTL_CON);
95 val |= (T_DMA_IRQ | R_DMA_IRQ);
96 AUDIO_WRITE(nuc900_audio->mmio + ACTL_CON, val);
97}
98
99static void nuc900_dma_stop(struct snd_pcm_substream *substream)
100{
101 struct snd_pcm_runtime *runtime = substream->runtime;
102 struct nuc900_audio *nuc900_audio = runtime->private_data;
103 unsigned long val;
104
105 val = AUDIO_READ(nuc900_audio->mmio + ACTL_CON);
106 val &= ~(T_DMA_IRQ | R_DMA_IRQ);
107 AUDIO_WRITE(nuc900_audio->mmio + ACTL_CON, val);
108}
109
110static irqreturn_t nuc900_dma_interrupt(int irq, void *dev_id)
111{
112 struct snd_pcm_substream *substream = dev_id;
113 struct nuc900_audio *nuc900_audio = substream->runtime->private_data;
114 unsigned long val;
115
116 spin_lock(&nuc900_audio->lock);
117
118 val = AUDIO_READ(nuc900_audio->mmio + ACTL_CON);
119
120 if (val & R_DMA_IRQ) {
121 AUDIO_WRITE(nuc900_audio->mmio + ACTL_CON, val | R_DMA_IRQ);
122
123 val = AUDIO_READ(nuc900_audio->mmio + ACTL_RSR);
124
125 if (val & R_DMA_MIDDLE_IRQ) {
126 val |= R_DMA_MIDDLE_IRQ;
127 AUDIO_WRITE(nuc900_audio->mmio + ACTL_RSR, val);
128 }
129
130 if (val & R_DMA_END_IRQ) {
131 val |= R_DMA_END_IRQ;
132 AUDIO_WRITE(nuc900_audio->mmio + ACTL_RSR, val);
133 }
134 } else if (val & T_DMA_IRQ) {
135 AUDIO_WRITE(nuc900_audio->mmio + ACTL_CON, val | T_DMA_IRQ);
136
137 val = AUDIO_READ(nuc900_audio->mmio + ACTL_PSR);
138
139 if (val & P_DMA_MIDDLE_IRQ) {
140 val |= P_DMA_MIDDLE_IRQ;
141 AUDIO_WRITE(nuc900_audio->mmio + ACTL_PSR, val);
142 }
143
144 if (val & P_DMA_END_IRQ) {
145 val |= P_DMA_END_IRQ;
146 AUDIO_WRITE(nuc900_audio->mmio + ACTL_PSR, val);
147 }
148 } else {
149 dev_err(nuc900_audio->dev, "Wrong DMA interrupt status!\n");
150 spin_unlock(&nuc900_audio->lock);
151 return IRQ_HANDLED;
152 }
153
154 spin_unlock(&nuc900_audio->lock);
155
156 snd_pcm_period_elapsed(substream);
157
158 return IRQ_HANDLED;
159}
160
161static int nuc900_dma_hw_free(struct snd_pcm_substream *substream)
162{
163 snd_pcm_lib_free_pages(substream);
164 return 0;
165}
166
167static int nuc900_dma_prepare(struct snd_pcm_substream *substream)
168{
169 struct snd_pcm_runtime *runtime = substream->runtime;
170 struct nuc900_audio *nuc900_audio = runtime->private_data;
171 unsigned long flags, val;
172
173 spin_lock_irqsave(&nuc900_audio->lock, flags);
174
175 nuc900_update_dma_register(substream,
176 nuc900_audio->dma_addr[substream->stream],
177 nuc900_audio->buffersize[substream->stream]);
178
179 val = AUDIO_READ(nuc900_audio->mmio + ACTL_RESET);
180
181 switch (runtime->channels) {
182 case 1:
183 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
184 val &= ~(PLAY_LEFT_CHNNEL | PLAY_RIGHT_CHNNEL);
185 val |= PLAY_RIGHT_CHNNEL;
186 } else {
187 val &= ~(RECORD_LEFT_CHNNEL | RECORD_RIGHT_CHNNEL);
188 val |= RECORD_RIGHT_CHNNEL;
189 }
190 AUDIO_WRITE(nuc900_audio->mmio + ACTL_RESET, val);
191 break;
192 case 2:
193 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
194 val |= (PLAY_LEFT_CHNNEL | PLAY_RIGHT_CHNNEL);
195 else
196 val |= (RECORD_LEFT_CHNNEL | RECORD_RIGHT_CHNNEL);
197 AUDIO_WRITE(nuc900_audio->mmio + ACTL_RESET, val);
198 break;
199 default:
200 return -EINVAL;
201 }
202 spin_unlock_irqrestore(&nuc900_audio->lock, flags);
203 return 0;
204}
205
206static int nuc900_dma_trigger(struct snd_pcm_substream *substream, int cmd)
207{
208 int ret = 0;
209
210 switch (cmd) {
211 case SNDRV_PCM_TRIGGER_START:
212 case SNDRV_PCM_TRIGGER_RESUME:
213 nuc900_dma_start(substream);
214 break;
215
216 case SNDRV_PCM_TRIGGER_STOP:
217 case SNDRV_PCM_TRIGGER_SUSPEND:
218 nuc900_dma_stop(substream);
219 break;
220
221 default:
222 ret = -EINVAL;
223 break;
224 }
225
226 return ret;
227}
228
229int nuc900_dma_getposition(struct snd_pcm_substream *substream,
230 dma_addr_t *src, dma_addr_t *dst)
231{
232 struct snd_pcm_runtime *runtime = substream->runtime;
233 struct nuc900_audio *nuc900_audio = runtime->private_data;
234
235 if (src != NULL)
236 *src = AUDIO_READ(nuc900_audio->mmio + ACTL_PDSTC);
237
238 if (dst != NULL)
239 *dst = AUDIO_READ(nuc900_audio->mmio + ACTL_RDSTC);
240
241 return 0;
242}
243
244static snd_pcm_uframes_t nuc900_dma_pointer(struct snd_pcm_substream *substream)
245{
246 struct snd_pcm_runtime *runtime = substream->runtime;
247 dma_addr_t src, dst;
248 unsigned long res;
249
250 nuc900_dma_getposition(substream, &src, &dst);
251
252 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
253 res = dst - runtime->dma_addr;
254 else
255 res = src - runtime->dma_addr;
256
257 return bytes_to_frames(substream->runtime, res);
258}
259
260static int nuc900_dma_open(struct snd_pcm_substream *substream)
261{
262 struct snd_pcm_runtime *runtime = substream->runtime;
263 struct nuc900_audio *nuc900_audio;
264
265 snd_soc_set_runtime_hwparams(substream, &nuc900_pcm_hardware);
266
267 nuc900_audio = nuc900_ac97_data;
268
269 if (request_irq(nuc900_audio->irq_num, nuc900_dma_interrupt,
270 IRQF_DISABLED, "nuc900-dma", substream))
271 return -EBUSY;
272
273 runtime->private_data = nuc900_audio;
274
275 return 0;
276}
277
278static int nuc900_dma_close(struct snd_pcm_substream *substream)
279{
280 struct snd_pcm_runtime *runtime = substream->runtime;
281 struct nuc900_audio *nuc900_audio = runtime->private_data;
282
283 free_irq(nuc900_audio->irq_num, substream);
284
285 return 0;
286}
287
288static int nuc900_dma_mmap(struct snd_pcm_substream *substream,
289 struct vm_area_struct *vma)
290{
291 struct snd_pcm_runtime *runtime = substream->runtime;
292
293 return dma_mmap_writecombine(substream->pcm->card->dev, vma,
294 runtime->dma_area,
295 runtime->dma_addr,
296 runtime->dma_bytes);
297}
298
299static struct snd_pcm_ops nuc900_dma_ops = {
300 .open = nuc900_dma_open,
301 .close = nuc900_dma_close,
302 .ioctl = snd_pcm_lib_ioctl,
303 .hw_params = nuc900_dma_hw_params,
304 .hw_free = nuc900_dma_hw_free,
305 .prepare = nuc900_dma_prepare,
306 .trigger = nuc900_dma_trigger,
307 .pointer = nuc900_dma_pointer,
308 .mmap = nuc900_dma_mmap,
309};
310
311static void nuc900_dma_free_dma_buffers(struct snd_pcm *pcm)
312{
313 snd_pcm_lib_preallocate_free_for_all(pcm);
314}
315
316static u64 nuc900_pcm_dmamask = DMA_BIT_MASK(32);
317static int nuc900_dma_new(struct snd_card *card,
318 struct snd_soc_dai *dai, struct snd_pcm *pcm)
319{
320 if (!card->dev->dma_mask)
321 card->dev->dma_mask = &nuc900_pcm_dmamask;
322 if (!card->dev->coherent_dma_mask)
323 card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
324
325 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
326 card->dev, 4 * 1024, (4 * 1024) - 1);
327
328 return 0;
329}
330
331struct snd_soc_platform nuc900_soc_platform = {
332 .name = "nuc900-dma",
333 .pcm_ops = &nuc900_dma_ops,
334 .pcm_new = nuc900_dma_new,
335 .pcm_free = nuc900_dma_free_dma_buffers,
336}
337EXPORT_SYMBOL_GPL(nuc900_soc_platform);
338
339static int __init nuc900_soc_platform_init(void)
340{
341 return snd_soc_register_platform(&nuc900_soc_platform);
342}
343
344static void __exit nuc900_soc_platform_exit(void)
345{
346 snd_soc_unregister_platform(&nuc900_soc_platform);
347}
348
349module_init(nuc900_soc_platform_init);
350module_exit(nuc900_soc_platform_exit);
351
352MODULE_AUTHOR("Wan ZongShun, <mcuos.com@gmail.com>");
353MODULE_DESCRIPTION("nuc900 Audio DMA module");
354MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index 6f44cb4d30b..86f213905e2 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -59,6 +59,7 @@ struct omap_mcbsp_data {
59 int configured; 59 int configured;
60 unsigned int in_freq; 60 unsigned int in_freq;
61 int clk_div; 61 int clk_div;
62 int wlen;
62}; 63};
63 64
64#define to_mcbsp(priv) container_of((priv), struct omap_mcbsp_data, bus_id) 65#define to_mcbsp(priv) container_of((priv), struct omap_mcbsp_data, bus_id)
@@ -154,20 +155,51 @@ static void omap_mcbsp_set_threshold(struct snd_pcm_substream *substream)
154 struct snd_soc_pcm_runtime *rtd = substream->private_data; 155 struct snd_soc_pcm_runtime *rtd = substream->private_data;
155 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 156 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
156 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data); 157 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data);
158 struct omap_pcm_dma_data *dma_data;
157 int dma_op_mode = omap_mcbsp_get_dma_op_mode(mcbsp_data->bus_id); 159 int dma_op_mode = omap_mcbsp_get_dma_op_mode(mcbsp_data->bus_id);
158 int samples; 160 int words;
161
162 dma_data = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
159 163
160 /* TODO: Currently, MODE_ELEMENT == MODE_FRAME */ 164 /* TODO: Currently, MODE_ELEMENT == MODE_FRAME */
161 if (dma_op_mode == MCBSP_DMA_MODE_THRESHOLD) 165 if (dma_op_mode == MCBSP_DMA_MODE_THRESHOLD)
162 samples = snd_pcm_lib_period_bytes(substream) >> 1; 166 /*
167 * Configure McBSP threshold based on either:
168 * packet_size, when the sDMA is in packet mode, or
169 * based on the period size.
170 */
171 if (dma_data->packet_size)
172 words = dma_data->packet_size;
173 else
174 words = snd_pcm_lib_period_bytes(substream) /
175 (mcbsp_data->wlen / 8);
163 else 176 else
164 samples = 1; 177 words = 1;
165 178
166 /* Configure McBSP internal buffer usage */ 179 /* Configure McBSP internal buffer usage */
167 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 180 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
168 omap_mcbsp_set_tx_threshold(mcbsp_data->bus_id, samples - 1); 181 omap_mcbsp_set_tx_threshold(mcbsp_data->bus_id, words);
169 else 182 else
170 omap_mcbsp_set_rx_threshold(mcbsp_data->bus_id, samples - 1); 183 omap_mcbsp_set_rx_threshold(mcbsp_data->bus_id, words);
184}
185
186static int omap_mcbsp_hwrule_min_buffersize(struct snd_pcm_hw_params *params,
187 struct snd_pcm_hw_rule *rule)
188{
189 struct snd_interval *buffer_size = hw_param_interval(params,
190 SNDRV_PCM_HW_PARAM_BUFFER_SIZE);
191 struct snd_interval *channels = hw_param_interval(params,
192 SNDRV_PCM_HW_PARAM_CHANNELS);
193 struct omap_mcbsp_data *mcbsp_data = rule->private;
194 struct snd_interval frames;
195 int size;
196
197 snd_interval_any(&frames);
198 size = omap_mcbsp_get_fifo_size(mcbsp_data->bus_id);
199
200 frames.min = size / channels->min;
201 frames.integer = 1;
202 return snd_interval_refine(buffer_size, &frames);
171} 203}
172 204
173static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream, 205static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream,
@@ -182,33 +214,35 @@ static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream,
182 if (!cpu_dai->active) 214 if (!cpu_dai->active)
183 err = omap_mcbsp_request(bus_id); 215 err = omap_mcbsp_request(bus_id);
184 216
217 /*
218 * OMAP3 McBSP FIFO is word structured.
219 * McBSP2 has 1024 + 256 = 1280 word long buffer,
220 * McBSP1,3,4,5 has 128 word long buffer
221 * This means that the size of the FIFO depends on the sample format.
222 * For example on McBSP3:
223 * 16bit samples: size is 128 * 2 = 256 bytes
224 * 32bit samples: size is 128 * 4 = 512 bytes
225 * It is simpler to place constraint for buffer and period based on
226 * channels.
227 * McBSP3 as example again (16 or 32 bit samples):
228 * 1 channel (mono): size is 128 frames (128 words)
229 * 2 channels (stereo): size is 128 / 2 = 64 frames (2 * 64 words)
230 * 4 channels: size is 128 / 4 = 32 frames (4 * 32 words)
231 */
185 if (cpu_is_omap343x()) { 232 if (cpu_is_omap343x()) {
186 int dma_op_mode = omap_mcbsp_get_dma_op_mode(bus_id);
187 int max_period;
188
189 /* 233 /*
190 * McBSP2 in OMAP3 has 1024 * 32-bit internal audio buffer. 234 * Rule for the buffer size. We should not allow
191 * Set constraint for minimum buffer size to the same than FIFO 235 * smaller buffer than the FIFO size to avoid underruns
192 * size in order to avoid underruns in playback startup because 236 */
193 * HW is keeping the DMA request active until FIFO is filled. 237 snd_pcm_hw_rule_add(substream->runtime, 0,
194 */ 238 SNDRV_PCM_HW_PARAM_CHANNELS,
195 if (bus_id == 1) 239 omap_mcbsp_hwrule_min_buffersize,
196 snd_pcm_hw_constraint_minmax(substream->runtime, 240 mcbsp_data,
197 SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 241 SNDRV_PCM_HW_PARAM_BUFFER_SIZE, -1);
198 4096, UINT_MAX); 242
199 243 /* Make sure, that the period size is always even */
200 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 244 snd_pcm_hw_constraint_step(substream->runtime, 0,
201 max_period = omap_mcbsp_get_max_tx_threshold(bus_id); 245 SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 2);
202 else
203 max_period = omap_mcbsp_get_max_rx_threshold(bus_id);
204
205 max_period++;
206 max_period <<= 1;
207
208 if (dma_op_mode == MCBSP_DMA_MODE_THRESHOLD)
209 snd_pcm_hw_constraint_minmax(substream->runtime,
210 SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
211 32, max_period);
212 } 246 }
213 247
214 return err; 248 return err;
@@ -289,11 +323,14 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
289 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 323 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
290 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data); 324 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data);
291 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs; 325 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs;
292 int dma, bus_id = mcbsp_data->bus_id, id = cpu_dai->id; 326 struct omap_pcm_dma_data *dma_data;
327 int dma, bus_id = mcbsp_data->bus_id;
293 int wlen, channels, wpf, sync_mode = OMAP_DMA_SYNC_ELEMENT; 328 int wlen, channels, wpf, sync_mode = OMAP_DMA_SYNC_ELEMENT;
329 int pkt_size = 0;
294 unsigned long port; 330 unsigned long port;
295 unsigned int format, div, framesize, master; 331 unsigned int format, div, framesize, master;
296 332
333 dma_data = &omap_mcbsp_dai_dma_params[cpu_dai->id][substream->stream];
297 if (cpu_class_is_omap1()) { 334 if (cpu_class_is_omap1()) {
298 dma = omap1_dma_reqs[bus_id][substream->stream]; 335 dma = omap1_dma_reqs[bus_id][substream->stream];
299 port = omap1_mcbsp_port[bus_id][substream->stream]; 336 port = omap1_mcbsp_port[bus_id][substream->stream];
@@ -306,35 +343,74 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
306 } else if (cpu_is_omap343x()) { 343 } else if (cpu_is_omap343x()) {
307 dma = omap24xx_dma_reqs[bus_id][substream->stream]; 344 dma = omap24xx_dma_reqs[bus_id][substream->stream];
308 port = omap34xx_mcbsp_port[bus_id][substream->stream]; 345 port = omap34xx_mcbsp_port[bus_id][substream->stream];
309 omap_mcbsp_dai_dma_params[id][substream->stream].set_threshold =
310 omap_mcbsp_set_threshold;
311 /* TODO: Currently, MODE_ELEMENT == MODE_FRAME */
312 if (omap_mcbsp_get_dma_op_mode(bus_id) ==
313 MCBSP_DMA_MODE_THRESHOLD)
314 sync_mode = OMAP_DMA_SYNC_FRAME;
315 } else { 346 } else {
316 return -ENODEV; 347 return -ENODEV;
317 } 348 }
318 omap_mcbsp_dai_dma_params[id][substream->stream].name =
319 substream->stream ? "Audio Capture" : "Audio Playback";
320 omap_mcbsp_dai_dma_params[id][substream->stream].dma_req = dma;
321 omap_mcbsp_dai_dma_params[id][substream->stream].port_addr = port;
322 omap_mcbsp_dai_dma_params[id][substream->stream].sync_mode = sync_mode;
323 switch (params_format(params)) { 349 switch (params_format(params)) {
324 case SNDRV_PCM_FORMAT_S16_LE: 350 case SNDRV_PCM_FORMAT_S16_LE:
325 omap_mcbsp_dai_dma_params[id][substream->stream].data_type = 351 dma_data->data_type = OMAP_DMA_DATA_TYPE_S16;
326 OMAP_DMA_DATA_TYPE_S16; 352 wlen = 16;
327 break; 353 break;
328 case SNDRV_PCM_FORMAT_S32_LE: 354 case SNDRV_PCM_FORMAT_S32_LE:
329 omap_mcbsp_dai_dma_params[id][substream->stream].data_type = 355 dma_data->data_type = OMAP_DMA_DATA_TYPE_S32;
330 OMAP_DMA_DATA_TYPE_S32; 356 wlen = 32;
331 break; 357 break;
332 default: 358 default:
333 return -EINVAL; 359 return -EINVAL;
334 } 360 }
361 if (cpu_is_omap343x()) {
362 dma_data->set_threshold = omap_mcbsp_set_threshold;
363 /* TODO: Currently, MODE_ELEMENT == MODE_FRAME */
364 if (omap_mcbsp_get_dma_op_mode(bus_id) ==
365 MCBSP_DMA_MODE_THRESHOLD) {
366 int period_words, max_thrsh;
367
368 period_words = params_period_bytes(params) / (wlen / 8);
369 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
370 max_thrsh = omap_mcbsp_get_max_tx_threshold(
371 mcbsp_data->bus_id);
372 else
373 max_thrsh = omap_mcbsp_get_max_rx_threshold(
374 mcbsp_data->bus_id);
375 /*
376 * If the period contains less or equal number of words,
377 * we are using the original threshold mode setup:
378 * McBSP threshold = sDMA frame size = period_size
379 * Otherwise we switch to sDMA packet mode:
380 * McBSP threshold = sDMA packet size
381 * sDMA frame size = period size
382 */
383 if (period_words > max_thrsh) {
384 int divider = 0;
385
386 /*
387 * Look for the biggest threshold value, which
388 * divides the period size evenly.
389 */
390 divider = period_words / max_thrsh;
391 if (period_words % max_thrsh)
392 divider++;
393 while (period_words % divider &&
394 divider < period_words)
395 divider++;
396 if (divider == period_words)
397 return -EINVAL;
398
399 pkt_size = period_words / divider;
400 sync_mode = OMAP_DMA_SYNC_PACKET;
401 } else {
402 sync_mode = OMAP_DMA_SYNC_FRAME;
403 }
404 }
405 }
335 406
336 snd_soc_dai_set_dma_data(cpu_dai, substream, 407 dma_data->name = substream->stream ? "Audio Capture" : "Audio Playback";
337 &omap_mcbsp_dai_dma_params[id][substream->stream]); 408 dma_data->dma_req = dma;
409 dma_data->port_addr = port;
410 dma_data->sync_mode = sync_mode;
411 dma_data->packet_size = pkt_size;
412
413 snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
338 414
339 if (mcbsp_data->configured) { 415 if (mcbsp_data->configured) {
340 /* McBSP already configured by another stream */ 416 /* McBSP already configured by another stream */
@@ -360,7 +436,6 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
360 switch (params_format(params)) { 436 switch (params_format(params)) {
361 case SNDRV_PCM_FORMAT_S16_LE: 437 case SNDRV_PCM_FORMAT_S16_LE:
362 /* Set word lengths */ 438 /* Set word lengths */
363 wlen = 16;
364 regs->rcr2 |= RWDLEN2(OMAP_MCBSP_WORD_16); 439 regs->rcr2 |= RWDLEN2(OMAP_MCBSP_WORD_16);
365 regs->rcr1 |= RWDLEN1(OMAP_MCBSP_WORD_16); 440 regs->rcr1 |= RWDLEN1(OMAP_MCBSP_WORD_16);
366 regs->xcr2 |= XWDLEN2(OMAP_MCBSP_WORD_16); 441 regs->xcr2 |= XWDLEN2(OMAP_MCBSP_WORD_16);
@@ -368,7 +443,6 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
368 break; 443 break;
369 case SNDRV_PCM_FORMAT_S32_LE: 444 case SNDRV_PCM_FORMAT_S32_LE:
370 /* Set word lengths */ 445 /* Set word lengths */
371 wlen = 32;
372 regs->rcr2 |= RWDLEN2(OMAP_MCBSP_WORD_32); 446 regs->rcr2 |= RWDLEN2(OMAP_MCBSP_WORD_32);
373 regs->rcr1 |= RWDLEN1(OMAP_MCBSP_WORD_32); 447 regs->rcr1 |= RWDLEN1(OMAP_MCBSP_WORD_32);
374 regs->xcr2 |= XWDLEN2(OMAP_MCBSP_WORD_32); 448 regs->xcr2 |= XWDLEN2(OMAP_MCBSP_WORD_32);
@@ -409,6 +483,7 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
409 } 483 }
410 484
411 omap_mcbsp_config(bus_id, &mcbsp_data->regs); 485 omap_mcbsp_config(bus_id, &mcbsp_data->regs);
486 mcbsp_data->wlen = wlen;
412 mcbsp_data->configured = 1; 487 mcbsp_data->configured = 1;
413 488
414 return 0; 489 return 0;
diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c
index 87ce842fa2e..9eecac135bb 100644
--- a/sound/soc/omap/omap3pandora.c
+++ b/sound/soc/omap/omap3pandora.c
@@ -43,12 +43,14 @@
43 43
44static struct regulator *omap3pandora_dac_reg; 44static struct regulator *omap3pandora_dac_reg;
45 45
46static int omap3pandora_cmn_hw_params(struct snd_pcm_substream *substream, 46static int omap3pandora_hw_params(struct snd_pcm_substream *substream,
47 struct snd_pcm_hw_params *params, unsigned int fmt) 47 struct snd_pcm_hw_params *params)
48{ 48{
49 struct snd_soc_pcm_runtime *rtd = substream->private_data; 49 struct snd_soc_pcm_runtime *rtd = substream->private_data;
50 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 50 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
51 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 51 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
52 int fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
53 SND_SOC_DAIFMT_CBS_CFS;
52 int ret; 54 int ret;
53 55
54 /* Set codec DAI configuration */ 56 /* Set codec DAI configuration */
@@ -91,24 +93,6 @@ static int omap3pandora_cmn_hw_params(struct snd_pcm_substream *substream,
91 return 0; 93 return 0;
92} 94}
93 95
94static int omap3pandora_out_hw_params(struct snd_pcm_substream *substream,
95 struct snd_pcm_hw_params *params)
96{
97 return omap3pandora_cmn_hw_params(substream, params,
98 SND_SOC_DAIFMT_I2S |
99 SND_SOC_DAIFMT_IB_NF |
100 SND_SOC_DAIFMT_CBS_CFS);
101}
102
103static int omap3pandora_in_hw_params(struct snd_pcm_substream *substream,
104 struct snd_pcm_hw_params *params)
105{
106 return omap3pandora_cmn_hw_params(substream, params,
107 SND_SOC_DAIFMT_I2S |
108 SND_SOC_DAIFMT_NB_NF |
109 SND_SOC_DAIFMT_CBS_CFS);
110}
111
112static int omap3pandora_dac_event(struct snd_soc_dapm_widget *w, 96static int omap3pandora_dac_event(struct snd_soc_dapm_widget *w,
113 struct snd_kcontrol *k, int event) 97 struct snd_kcontrol *k, int event)
114{ 98{
@@ -231,12 +215,8 @@ static int omap3pandora_in_init(struct snd_soc_codec *codec)
231 return snd_soc_dapm_sync(codec); 215 return snd_soc_dapm_sync(codec);
232} 216}
233 217
234static struct snd_soc_ops omap3pandora_out_ops = { 218static struct snd_soc_ops omap3pandora_ops = {
235 .hw_params = omap3pandora_out_hw_params, 219 .hw_params = omap3pandora_hw_params,
236};
237
238static struct snd_soc_ops omap3pandora_in_ops = {
239 .hw_params = omap3pandora_in_hw_params,
240}; 220};
241 221
242/* Digital audio interface glue - connects codec <--> CPU */ 222/* Digital audio interface glue - connects codec <--> CPU */
@@ -246,14 +226,14 @@ static struct snd_soc_dai_link omap3pandora_dai[] = {
246 .stream_name = "HiFi Out", 226 .stream_name = "HiFi Out",
247 .cpu_dai = &omap_mcbsp_dai[0], 227 .cpu_dai = &omap_mcbsp_dai[0],
248 .codec_dai = &twl4030_dai[TWL4030_DAI_HIFI], 228 .codec_dai = &twl4030_dai[TWL4030_DAI_HIFI],
249 .ops = &omap3pandora_out_ops, 229 .ops = &omap3pandora_ops,
250 .init = omap3pandora_out_init, 230 .init = omap3pandora_out_init,
251 }, { 231 }, {
252 .name = "TWL4030", 232 .name = "TWL4030",
253 .stream_name = "Line/Mic In", 233 .stream_name = "Line/Mic In",
254 .cpu_dai = &omap_mcbsp_dai[1], 234 .cpu_dai = &omap_mcbsp_dai[1],
255 .codec_dai = &twl4030_dai[TWL4030_DAI_HIFI], 235 .codec_dai = &twl4030_dai[TWL4030_DAI_HIFI],
256 .ops = &omap3pandora_in_ops, 236 .ops = &omap3pandora_ops,
257 .init = omap3pandora_in_init, 237 .init = omap3pandora_in_init,
258 } 238 }
259}; 239};
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c
index 47d831ef2db..88052d29617 100644
--- a/sound/soc/omap/rx51.c
+++ b/sound/soc/omap/rx51.c
@@ -27,6 +27,7 @@
27#include <linux/gpio.h> 27#include <linux/gpio.h>
28#include <linux/platform_device.h> 28#include <linux/platform_device.h>
29#include <sound/core.h> 29#include <sound/core.h>
30#include <sound/jack.h>
30#include <sound/pcm.h> 31#include <sound/pcm.h>
31#include <sound/soc.h> 32#include <sound/soc.h>
32#include <sound/soc-dapm.h> 33#include <sound/soc-dapm.h>
@@ -37,14 +38,22 @@
37#include "omap-pcm.h" 38#include "omap-pcm.h"
38#include "../codecs/tlv320aic3x.h" 39#include "../codecs/tlv320aic3x.h"
39 40
41#define RX51_TVOUT_SEL_GPIO 40
42#define RX51_JACK_DETECT_GPIO 177
40/* 43/*
41 * REVISIT: TWL4030 GPIO base in RX-51. Now statically defined to 192. This 44 * REVISIT: TWL4030 GPIO base in RX-51. Now statically defined to 192. This
42 * gpio is reserved in arch/arm/mach-omap2/board-rx51-peripherals.c 45 * gpio is reserved in arch/arm/mach-omap2/board-rx51-peripherals.c
43 */ 46 */
44#define RX51_SPEAKER_AMP_TWL_GPIO (192 + 7) 47#define RX51_SPEAKER_AMP_TWL_GPIO (192 + 7)
45 48
49enum {
50 RX51_JACK_DISABLED,
51 RX51_JACK_TVOUT, /* tv-out */
52};
53
46static int rx51_spk_func; 54static int rx51_spk_func;
47static int rx51_dmic_func; 55static int rx51_dmic_func;
56static int rx51_jack_func;
48 57
49static void rx51_ext_control(struct snd_soc_codec *codec) 58static void rx51_ext_control(struct snd_soc_codec *codec)
50{ 59{
@@ -57,6 +66,9 @@ static void rx51_ext_control(struct snd_soc_codec *codec)
57 else 66 else
58 snd_soc_dapm_disable_pin(codec, "DMic"); 67 snd_soc_dapm_disable_pin(codec, "DMic");
59 68
69 gpio_set_value(RX51_TVOUT_SEL_GPIO,
70 rx51_jack_func == RX51_JACK_TVOUT);
71
60 snd_soc_dapm_sync(codec); 72 snd_soc_dapm_sync(codec);
61} 73}
62 74
@@ -162,6 +174,40 @@ static int rx51_set_input(struct snd_kcontrol *kcontrol,
162 return 1; 174 return 1;
163} 175}
164 176
177static int rx51_get_jack(struct snd_kcontrol *kcontrol,
178 struct snd_ctl_elem_value *ucontrol)
179{
180 ucontrol->value.integer.value[0] = rx51_jack_func;
181
182 return 0;
183}
184
185static int rx51_set_jack(struct snd_kcontrol *kcontrol,
186 struct snd_ctl_elem_value *ucontrol)
187{
188 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
189
190 if (rx51_jack_func == ucontrol->value.integer.value[0])
191 return 0;
192
193 rx51_jack_func = ucontrol->value.integer.value[0];
194 rx51_ext_control(codec);
195
196 return 1;
197}
198
199static struct snd_soc_jack rx51_av_jack;
200
201static struct snd_soc_jack_gpio rx51_av_jack_gpios[] = {
202 {
203 .gpio = RX51_JACK_DETECT_GPIO,
204 .name = "avdet-gpio",
205 .report = SND_JACK_VIDEOOUT,
206 .invert = 1,
207 .debounce_time = 200,
208 },
209};
210
165static const struct snd_soc_dapm_widget aic34_dapm_widgets[] = { 211static const struct snd_soc_dapm_widget aic34_dapm_widgets[] = {
166 SND_SOC_DAPM_SPK("Ext Spk", rx51_spk_event), 212 SND_SOC_DAPM_SPK("Ext Spk", rx51_spk_event),
167 SND_SOC_DAPM_MIC("DMic", NULL), 213 SND_SOC_DAPM_MIC("DMic", NULL),
@@ -177,10 +223,12 @@ static const struct snd_soc_dapm_route audio_map[] = {
177 223
178static const char *spk_function[] = {"Off", "On"}; 224static const char *spk_function[] = {"Off", "On"};
179static const char *input_function[] = {"ADC", "Digital Mic"}; 225static const char *input_function[] = {"ADC", "Digital Mic"};
226static const char *jack_function[] = {"Off", "TV-OUT"};
180 227
181static const struct soc_enum rx51_enum[] = { 228static const struct soc_enum rx51_enum[] = {
182 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spk_function), spk_function), 229 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spk_function), spk_function),
183 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(input_function), input_function), 230 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(input_function), input_function),
231 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(jack_function), jack_function),
184}; 232};
185 233
186static const struct snd_kcontrol_new aic34_rx51_controls[] = { 234static const struct snd_kcontrol_new aic34_rx51_controls[] = {
@@ -188,10 +236,13 @@ static const struct snd_kcontrol_new aic34_rx51_controls[] = {
188 rx51_get_spk, rx51_set_spk), 236 rx51_get_spk, rx51_set_spk),
189 SOC_ENUM_EXT("Input Select", rx51_enum[1], 237 SOC_ENUM_EXT("Input Select", rx51_enum[1],
190 rx51_get_input, rx51_set_input), 238 rx51_get_input, rx51_set_input),
239 SOC_ENUM_EXT("Jack Function", rx51_enum[2],
240 rx51_get_jack, rx51_set_jack),
191}; 241};
192 242
193static int rx51_aic34_init(struct snd_soc_codec *codec) 243static int rx51_aic34_init(struct snd_soc_codec *codec)
194{ 244{
245 struct snd_soc_card *card = codec->socdev->card;
195 int err; 246 int err;
196 247
197 /* Set up NC codec pins */ 248 /* Set up NC codec pins */
@@ -214,7 +265,16 @@ static int rx51_aic34_init(struct snd_soc_codec *codec)
214 265
215 snd_soc_dapm_sync(codec); 266 snd_soc_dapm_sync(codec);
216 267
217 return 0; 268 /* AV jack detection */
269 err = snd_soc_jack_new(card, "AV Jack",
270 SND_JACK_VIDEOOUT, &rx51_av_jack);
271 if (err)
272 return err;
273 err = snd_soc_jack_add_gpios(&rx51_av_jack,
274 ARRAY_SIZE(rx51_av_jack_gpios),
275 rx51_av_jack_gpios);
276
277 return err;
218} 278}
219 279
220/* Digital audio interface glue - connects codec <--> CPU */ 280/* Digital audio interface glue - connects codec <--> CPU */
@@ -259,6 +319,11 @@ static int __init rx51_soc_init(void)
259 if (!machine_is_nokia_rx51()) 319 if (!machine_is_nokia_rx51())
260 return -ENODEV; 320 return -ENODEV;
261 321
322 err = gpio_request(RX51_TVOUT_SEL_GPIO, "tvout_sel");
323 if (err)
324 goto err_gpio_tvout_sel;
325 gpio_direction_output(RX51_TVOUT_SEL_GPIO, 0);
326
262 rx51_snd_device = platform_device_alloc("soc-audio", -1); 327 rx51_snd_device = platform_device_alloc("soc-audio", -1);
263 if (!rx51_snd_device) { 328 if (!rx51_snd_device) {
264 err = -ENOMEM; 329 err = -ENOMEM;
@@ -277,13 +342,19 @@ static int __init rx51_soc_init(void)
277err2: 342err2:
278 platform_device_put(rx51_snd_device); 343 platform_device_put(rx51_snd_device);
279err1: 344err1:
345 gpio_free(RX51_TVOUT_SEL_GPIO);
346err_gpio_tvout_sel:
280 347
281 return err; 348 return err;
282} 349}
283 350
284static void __exit rx51_soc_exit(void) 351static void __exit rx51_soc_exit(void)
285{ 352{
353 snd_soc_jack_free_gpios(&rx51_av_jack, ARRAY_SIZE(rx51_av_jack_gpios),
354 rx51_av_jack_gpios);
355
286 platform_device_unregister(rx51_snd_device); 356 platform_device_unregister(rx51_snd_device);
357 gpio_free(RX51_TVOUT_SEL_GPIO);
287} 358}
288 359
289module_init(rx51_soc_init); 360module_init(rx51_soc_init);
diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig
index 2a7cc222d09..213963ac3c2 100644
--- a/sound/soc/s3c24xx/Kconfig
+++ b/sound/soc/s3c24xx/Kconfig
@@ -1,6 +1,6 @@
1config SND_S3C24XX_SOC 1config SND_S3C24XX_SOC
2 tristate "SoC Audio for the Samsung S3CXXXX chips" 2 tristate "SoC Audio for the Samsung S3CXXXX chips"
3 depends on ARCH_S3C2410 || ARCH_S3C64XX 3 depends on ARCH_S3C2410 || ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210
4 select S3C64XX_DMA if ARCH_S3C64XX 4 select S3C64XX_DMA if ARCH_S3C64XX
5 help 5 help
6 Say Y or M if you want to add support for codecs attached to 6 Say Y or M if you want to add support for codecs attached to
@@ -120,8 +120,14 @@ config SND_S3C24XX_SOC_SIMTEC_HERMES
120 120
121config SND_SOC_SMDK_WM9713 121config SND_SOC_SMDK_WM9713
122 tristate "SoC AC97 Audio support for SMDK with WM9713" 122 tristate "SoC AC97 Audio support for SMDK with WM9713"
123 depends on SND_S3C24XX_SOC && MACH_SMDK6410 123 depends on SND_S3C24XX_SOC && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDKV210 || MACH_SMDKC110)
124 select SND_SOC_WM9713 124 select SND_SOC_WM9713
125 select SND_S3C_SOC_AC97 125 select SND_S3C_SOC_AC97
126 help 126 help
127 Sat Y if you want to add support for SoC audio on the SMDK. 127 Sat Y if you want to add support for SoC audio on the SMDK.
128
129config SND_S3C64XX_SOC_SMARTQ
130 tristate "SoC I2S Audio support for SmartQ board"
131 depends on SND_S3C24XX_SOC && MACH_SMARTQ
132 select SND_S3C64XX_SOC_I2S
133 select SND_SOC_WM8750
diff --git a/sound/soc/s3c24xx/Makefile b/sound/soc/s3c24xx/Makefile
index 81d8dc503f8..50172c385d9 100644
--- a/sound/soc/s3c24xx/Makefile
+++ b/sound/soc/s3c24xx/Makefile
@@ -29,6 +29,7 @@ snd-soc-s3c24xx-simtec-hermes-objs := s3c24xx_simtec_hermes.o
29snd-soc-s3c24xx-simtec-tlv320aic23-objs := s3c24xx_simtec_tlv320aic23.o 29snd-soc-s3c24xx-simtec-tlv320aic23-objs := s3c24xx_simtec_tlv320aic23.o
30snd-soc-smdk64xx-wm8580-objs := smdk64xx_wm8580.o 30snd-soc-smdk64xx-wm8580-objs := smdk64xx_wm8580.o
31snd-soc-smdk-wm9713-objs := smdk_wm9713.o 31snd-soc-smdk-wm9713-objs := smdk_wm9713.o
32snd-soc-s3c64xx-smartq-wm8987-objs := smartq_wm8987.o
32 33
33obj-$(CONFIG_SND_S3C24XX_SOC_JIVE_WM8750) += snd-soc-jive-wm8750.o 34obj-$(CONFIG_SND_S3C24XX_SOC_JIVE_WM8750) += snd-soc-jive-wm8750.o
34obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o 35obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o
@@ -41,3 +42,4 @@ obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC_HERMES) += snd-soc-s3c24xx-simtec-hermes.o
41obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC_TLV320AIC23) += snd-soc-s3c24xx-simtec-tlv320aic23.o 42obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC_TLV320AIC23) += snd-soc-s3c24xx-simtec-tlv320aic23.o
42obj-$(CONFIG_SND_S3C64XX_SOC_WM8580) += snd-soc-smdk64xx-wm8580.o 43obj-$(CONFIG_SND_S3C64XX_SOC_WM8580) += snd-soc-smdk64xx-wm8580.o
43obj-$(CONFIG_SND_SOC_SMDK_WM9713) += snd-soc-smdk-wm9713.o 44obj-$(CONFIG_SND_SOC_SMDK_WM9713) += snd-soc-smdk-wm9713.o
45obj-$(CONFIG_SND_S3C64XX_SOC_SMARTQ) += snd-soc-s3c64xx-smartq-wm8987.o
diff --git a/sound/soc/s3c24xx/s3c-ac97.c b/sound/soc/s3c24xx/s3c-ac97.c
index ecf4fd04ae9..31f6d45b638 100644
--- a/sound/soc/s3c24xx/s3c-ac97.c
+++ b/sound/soc/s3c24xx/s3c-ac97.c
@@ -31,7 +31,6 @@
31#define AC_CMD_DATA(x) (x & 0xffff) 31#define AC_CMD_DATA(x) (x & 0xffff)
32 32
33struct s3c_ac97_info { 33struct s3c_ac97_info {
34 unsigned state;
35 struct clk *ac97_clk; 34 struct clk *ac97_clk;
36 void __iomem *regs; 35 void __iomem *regs;
37 struct mutex lock; 36 struct mutex lock;
diff --git a/sound/soc/s3c24xx/s3c-dma.c b/sound/soc/s3c24xx/s3c-dma.c
index 1b61c23ff30..f1b1bc4bacf 100644
--- a/sound/soc/s3c24xx/s3c-dma.c
+++ b/sound/soc/s3c24xx/s3c-dma.c
@@ -94,8 +94,7 @@ static void s3c_dma_enqueue(struct snd_pcm_substream *substream)
94 94
95 if ((pos + len) > prtd->dma_end) { 95 if ((pos + len) > prtd->dma_end) {
96 len = prtd->dma_end - pos; 96 len = prtd->dma_end - pos;
97 pr_debug(KERN_DEBUG "%s: corrected dma len %ld\n", 97 pr_debug("%s: corrected dma len %ld\n", __func__, len);
98 __func__, len);
99 } 98 }
100 99
101 ret = s3c2410_dma_enqueue(prtd->params->channel, 100 ret = s3c2410_dma_enqueue(prtd->params->channel,
diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.c b/sound/soc/s3c24xx/s3c-i2s-v2.c
index 13311c8cf96..64376b2aac7 100644
--- a/sound/soc/s3c24xx/s3c-i2s-v2.c
+++ b/sound/soc/s3c24xx/s3c-i2s-v2.c
@@ -32,7 +32,8 @@
32 32
33#undef S3C_IIS_V2_SUPPORTED 33#undef S3C_IIS_V2_SUPPORTED
34 34
35#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413) 35#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413) \
36 || defined(CONFIG_CPU_S5PV210)
36#define S3C_IIS_V2_SUPPORTED 37#define S3C_IIS_V2_SUPPORTED
37#endif 38#endif
38 39
diff --git a/sound/soc/s3c24xx/smartq_wm8987.c b/sound/soc/s3c24xx/smartq_wm8987.c
new file mode 100644
index 00000000000..b480348140b
--- /dev/null
+++ b/sound/soc/s3c24xx/smartq_wm8987.c
@@ -0,0 +1,295 @@
1/* sound/soc/s3c24xx/smartq_wm8987.c
2 *
3 * Copyright 2010 Maurus Cuelenaere <mcuelenaere@gmail.com>
4 *
5 * Based on smdk6410_wm8987.c
6 * Copyright 2007 Wolfson Microelectronics PLC. - linux@wolfsonmicro.com
7 * Graeme Gregory - graeme.gregory@wolfsonmicro.com
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 *
14 */
15
16#include <linux/module.h>
17#include <linux/platform_device.h>
18#include <linux/gpio.h>
19
20#include <sound/pcm.h>
21#include <sound/pcm_params.h>
22#include <sound/soc-dapm.h>
23#include <sound/jack.h>
24
25#include <asm/mach-types.h>
26
27#include "s3c-dma.h"
28#include "s3c64xx-i2s.h"
29
30#include "../codecs/wm8750.h"
31
32/*
33 * WM8987 is register compatible with WM8750, so using that as base driver.
34 */
35
36static struct snd_soc_card snd_soc_smartq;
37
38static int smartq_hifi_hw_params(struct snd_pcm_substream *substream,
39 struct snd_pcm_hw_params *params)
40{
41 struct snd_soc_pcm_runtime *rtd = substream->private_data;
42 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
43 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
44 struct s3c_i2sv2_rate_calc div;
45 unsigned int clk = 0;
46 int ret;
47
48 s3c_i2sv2_iis_calc_rate(&div, NULL, params_rate(params),
49 s3c_i2sv2_get_clock(cpu_dai));
50
51 switch (params_rate(params)) {
52 case 8000:
53 case 16000:
54 case 32000:
55 case 48000:
56 case 96000:
57 clk = 12288000;
58 break;
59 case 11025:
60 case 22050:
61 case 44100:
62 case 88200:
63 clk = 11289600;
64 break;
65 }
66
67 /* set codec DAI configuration */
68 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
69 SND_SOC_DAIFMT_NB_NF |
70 SND_SOC_DAIFMT_CBS_CFS);
71 if (ret < 0)
72 return ret;
73
74 /* set cpu DAI configuration */
75 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
76 SND_SOC_DAIFMT_NB_NF |
77 SND_SOC_DAIFMT_CBS_CFS);
78 if (ret < 0)
79 return ret;
80
81 /* set the codec system clock for DAC and ADC */
82 ret = snd_soc_dai_set_sysclk(codec_dai, WM8750_SYSCLK, clk,
83 SND_SOC_CLOCK_IN);
84 if (ret < 0)
85 return ret;
86
87 /* set MCLK division for sample rate */
88 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_I2SV2_DIV_RCLK, div.fs_div);
89 if (ret < 0)
90 return ret;
91
92 /* set prescaler division for sample rate */
93 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_I2SV2_DIV_PRESCALER,
94 div.clk_div - 1);
95 if (ret < 0)
96 return ret;
97
98 return 0;
99}
100
101/*
102 * SmartQ WM8987 HiFi DAI operations.
103 */
104static struct snd_soc_ops smartq_hifi_ops = {
105 .hw_params = smartq_hifi_hw_params,
106};
107
108static struct snd_soc_jack smartq_jack;
109
110static struct snd_soc_jack_pin smartq_jack_pins[] = {
111 /* Disable speaker when headphone is plugged in */
112 {
113 .pin = "Internal Speaker",
114 .mask = SND_JACK_HEADPHONE,
115 },
116};
117
118static struct snd_soc_jack_gpio smartq_jack_gpios[] = {
119 {
120 .gpio = S3C64XX_GPL(12),
121 .name = "headphone detect",
122 .report = SND_JACK_HEADPHONE,
123 .debounce_time = 200,
124 },
125};
126
127static const struct snd_kcontrol_new wm8987_smartq_controls[] = {
128 SOC_DAPM_PIN_SWITCH("Internal Speaker"),
129 SOC_DAPM_PIN_SWITCH("Headphone Jack"),
130 SOC_DAPM_PIN_SWITCH("Internal Mic"),
131};
132
133static int smartq_speaker_event(struct snd_soc_dapm_widget *w,
134 struct snd_kcontrol *k,
135 int event)
136{
137 gpio_set_value(S3C64XX_GPK(12), SND_SOC_DAPM_EVENT_OFF(event));
138
139 return 0;
140}
141
142static const struct snd_soc_dapm_widget wm8987_dapm_widgets[] = {
143 SND_SOC_DAPM_SPK("Internal Speaker", smartq_speaker_event),
144 SND_SOC_DAPM_HP("Headphone Jack", NULL),
145 SND_SOC_DAPM_MIC("Internal Mic", NULL),
146};
147
148static const struct snd_soc_dapm_route audio_map[] = {
149 {"Headphone Jack", NULL, "LOUT2"},
150 {"Headphone Jack", NULL, "ROUT2"},
151
152 {"Internal Speaker", NULL, "LOUT2"},
153 {"Internal Speaker", NULL, "ROUT2"},
154
155 {"Mic Bias", NULL, "Internal Mic"},
156 {"LINPUT2", NULL, "Mic Bias"},
157};
158
159static int smartq_wm8987_init(struct snd_soc_codec *codec)
160{
161 int err = 0;
162
163 /* Add SmartQ specific widgets */
164 snd_soc_dapm_new_controls(codec, wm8987_dapm_widgets,
165 ARRAY_SIZE(wm8987_dapm_widgets));
166
167 /* add SmartQ specific controls */
168 err = snd_soc_add_controls(codec, wm8987_smartq_controls,
169 ARRAY_SIZE(wm8987_smartq_controls));
170
171 if (err < 0)
172 return err;
173
174 /* setup SmartQ specific audio path */
175 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
176
177 /* set endpoints to not connected */
178 snd_soc_dapm_nc_pin(codec, "LINPUT1");
179 snd_soc_dapm_nc_pin(codec, "RINPUT1");
180 snd_soc_dapm_nc_pin(codec, "OUT3");
181 snd_soc_dapm_nc_pin(codec, "ROUT1");
182
183 /* set endpoints to default off mode */
184 snd_soc_dapm_enable_pin(codec, "Internal Speaker");
185 snd_soc_dapm_enable_pin(codec, "Internal Mic");
186 snd_soc_dapm_disable_pin(codec, "Headphone Jack");
187
188 err = snd_soc_dapm_sync(codec);
189 if (err)
190 return err;
191
192 /* Headphone jack detection */
193 err = snd_soc_jack_new(&snd_soc_smartq, "Headphone Jack",
194 SND_JACK_HEADPHONE, &smartq_jack);
195 if (err)
196 return err;
197
198 err = snd_soc_jack_add_pins(&smartq_jack, ARRAY_SIZE(smartq_jack_pins),
199 smartq_jack_pins);
200 if (err)
201 return err;
202
203 err = snd_soc_jack_add_gpios(&smartq_jack,
204 ARRAY_SIZE(smartq_jack_gpios),
205 smartq_jack_gpios);
206
207 return err;
208}
209
210static struct snd_soc_dai_link smartq_dai[] = {
211 {
212 .name = "wm8987",
213 .stream_name = "SmartQ Hi-Fi",
214 .cpu_dai = &s3c64xx_i2s_dai[0],
215 .codec_dai = &wm8750_dai,
216 .init = smartq_wm8987_init,
217 .ops = &smartq_hifi_ops,
218 },
219};
220
221static struct snd_soc_card snd_soc_smartq = {
222 .name = "SmartQ",
223 .platform = &s3c24xx_soc_platform,
224 .dai_link = smartq_dai,
225 .num_links = ARRAY_SIZE(smartq_dai),
226};
227
228static struct snd_soc_device smartq_snd_devdata = {
229 .card = &snd_soc_smartq,
230 .codec_dev = &soc_codec_dev_wm8750,
231};
232
233static struct platform_device *smartq_snd_device;
234
235static int __init smartq_init(void)
236{
237 int ret;
238
239 if (!machine_is_smartq7() && !machine_is_smartq5()) {
240 pr_info("Only SmartQ is supported by this ASoC driver\n");
241 return -ENODEV;
242 }
243
244 smartq_snd_device = platform_device_alloc("soc-audio", -1);
245 if (!smartq_snd_device)
246 return -ENOMEM;
247
248 platform_set_drvdata(smartq_snd_device, &smartq_snd_devdata);
249 smartq_snd_devdata.dev = &smartq_snd_device->dev;
250
251 ret = platform_device_add(smartq_snd_device);
252 if (ret) {
253 platform_device_put(smartq_snd_device);
254 return ret;
255 }
256
257 /* Initialise GPIOs used by amplifiers */
258 ret = gpio_request(S3C64XX_GPK(12), "amplifiers shutdown");
259 if (ret) {
260 dev_err(&smartq_snd_device->dev, "Failed to register GPK12\n");
261 goto err_unregister_device;
262 }
263
264 /* Disable amplifiers */
265 ret = gpio_direction_output(S3C64XX_GPK(12), 1);
266 if (ret) {
267 dev_err(&smartq_snd_device->dev, "Failed to configure GPK12\n");
268 goto err_free_gpio_amp_shut;
269 }
270
271 return 0;
272
273err_free_gpio_amp_shut:
274 gpio_free(S3C64XX_GPK(12));
275err_unregister_device:
276 platform_device_unregister(smartq_snd_device);
277
278 return ret;
279}
280
281static void __exit smartq_exit(void)
282{
283 snd_soc_jack_free_gpios(&smartq_jack, ARRAY_SIZE(smartq_jack_gpios),
284 smartq_jack_gpios);
285
286 platform_device_unregister(smartq_snd_device);
287}
288
289module_init(smartq_init);
290module_exit(smartq_exit);
291
292/* Module information */
293MODULE_AUTHOR("Maurus Cuelenaere <mcuelenaere@gmail.com>");
294MODULE_DESCRIPTION("ALSA SoC SmartQ WM8987");
295MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/smdk_wm9713.c b/sound/soc/s3c24xx/smdk_wm9713.c
index 24fd39f38cc..5527b9e88c9 100644
--- a/sound/soc/s3c24xx/smdk_wm9713.c
+++ b/sound/soc/s3c24xx/smdk_wm9713.c
@@ -25,6 +25,9 @@ static struct snd_soc_card smdk;
25 * Default CFG switch settings to use this driver: 25 * Default CFG switch settings to use this driver:
26 * 26 *
27 * SMDK6410: Set CFG1 1-3 On, CFG2 1-4 Off 27 * SMDK6410: Set CFG1 1-3 On, CFG2 1-4 Off
28 * SMDKC100: Set CFG6 1-3 On, CFG7 1 On
29 * SMDKC110: Set CFGB10 1-2 Off, CFGB12 1-3 On
30 * SMDKV210: Set CFGB10 1-2 Off, CFGB12 1-3 On
28 */ 31 */
29 32
30/* 33/*
diff --git a/sound/soc/s6000/s6000-i2s.c b/sound/soc/s6000/s6000-i2s.c
index 5b9ac1759bd..59e3fa7bcb0 100644
--- a/sound/soc/s6000/s6000-i2s.c
+++ b/sound/soc/s6000/s6000-i2s.c
@@ -451,16 +451,15 @@ static int __devinit s6000_i2s_probe(struct platform_device *pdev)
451 goto err_release_none; 451 goto err_release_none;
452 } 452 }
453 453
454 region = request_mem_region(scbmem->start, 454 region = request_mem_region(scbmem->start, resource_size(scbmem),
455 scbmem->end - scbmem->start + 1, 455 pdev->name);
456 pdev->name);
457 if (!region) { 456 if (!region) {
458 dev_err(&pdev->dev, "I2S SCB region already claimed\n"); 457 dev_err(&pdev->dev, "I2S SCB region already claimed\n");
459 ret = -EBUSY; 458 ret = -EBUSY;
460 goto err_release_none; 459 goto err_release_none;
461 } 460 }
462 461
463 mmio = ioremap(scbmem->start, scbmem->end - scbmem->start + 1); 462 mmio = ioremap(scbmem->start, resource_size(scbmem));
464 if (!mmio) { 463 if (!mmio) {
465 dev_err(&pdev->dev, "can't ioremap SCB region\n"); 464 dev_err(&pdev->dev, "can't ioremap SCB region\n");
466 ret = -ENOMEM; 465 ret = -ENOMEM;
@@ -474,9 +473,8 @@ static int __devinit s6000_i2s_probe(struct platform_device *pdev)
474 goto err_release_map; 473 goto err_release_map;
475 } 474 }
476 475
477 region = request_mem_region(sifmem->start, 476 region = request_mem_region(sifmem->start, resource_size(sifmem),
478 sifmem->end - sifmem->start + 1, 477 pdev->name);
479 pdev->name);
480 if (!region) { 478 if (!region) {
481 dev_err(&pdev->dev, "I2S SIF region already claimed\n"); 479 dev_err(&pdev->dev, "I2S SIF region already claimed\n");
482 ret = -EBUSY; 480 ret = -EBUSY;
@@ -490,8 +488,8 @@ static int __devinit s6000_i2s_probe(struct platform_device *pdev)
490 goto err_release_sif; 488 goto err_release_sif;
491 } 489 }
492 490
493 region = request_mem_region(dma1->start, dma1->end - dma1->start + 1, 491 region = request_mem_region(dma1->start, resource_size(dma1),
494 pdev->name); 492 pdev->name);
495 if (!region) { 493 if (!region) {
496 dev_err(&pdev->dev, "I2S DMA region already claimed\n"); 494 dev_err(&pdev->dev, "I2S DMA region already claimed\n");
497 ret = -EBUSY; 495 ret = -EBUSY;
@@ -500,9 +498,8 @@ static int __devinit s6000_i2s_probe(struct platform_device *pdev)
500 498
501 dma2 = platform_get_resource(pdev, IORESOURCE_DMA, 1); 499 dma2 = platform_get_resource(pdev, IORESOURCE_DMA, 1);
502 if (dma2) { 500 if (dma2) {
503 region = request_mem_region(dma2->start, 501 region = request_mem_region(dma2->start, resource_size(dma2),
504 dma2->end - dma2->start + 1, 502 pdev->name);
505 pdev->name);
506 if (!region) { 503 if (!region) {
507 dev_err(&pdev->dev, 504 dev_err(&pdev->dev,
508 "I2S DMA region already claimed\n"); 505 "I2S DMA region already claimed\n");
@@ -561,15 +558,15 @@ err_release_dev:
561 kfree(dev); 558 kfree(dev);
562err_release_dma2: 559err_release_dma2:
563 if (dma2) 560 if (dma2)
564 release_mem_region(dma2->start, dma2->end - dma2->start + 1); 561 release_mem_region(dma2->start, resource_size(dma2));
565err_release_dma1: 562err_release_dma1:
566 release_mem_region(dma1->start, dma1->end - dma1->start + 1); 563 release_mem_region(dma1->start, resource_size(dma1));
567err_release_sif: 564err_release_sif:
568 release_mem_region(sifmem->start, (sifmem->end - sifmem->start) + 1); 565 release_mem_region(sifmem->start, resource_size(sifmem));
569err_release_map: 566err_release_map:
570 iounmap(mmio); 567 iounmap(mmio);
571err_release_scb: 568err_release_scb:
572 release_mem_region(scbmem->start, (scbmem->end - scbmem->start) + 1); 569 release_mem_region(scbmem->start, resource_size(scbmem));
573err_release_none: 570err_release_none:
574 return ret; 571 return ret;
575} 572}
@@ -590,19 +587,18 @@ static void __devexit s6000_i2s_remove(struct platform_device *pdev)
590 kfree(dev); 587 kfree(dev);
591 588
592 region = platform_get_resource(pdev, IORESOURCE_DMA, 0); 589 region = platform_get_resource(pdev, IORESOURCE_DMA, 0);
593 release_mem_region(region->start, region->end - region->start + 1); 590 release_mem_region(region->start, resource_size(region));
594 591
595 region = platform_get_resource(pdev, IORESOURCE_DMA, 1); 592 region = platform_get_resource(pdev, IORESOURCE_DMA, 1);
596 if (region) 593 if (region)
597 release_mem_region(region->start, 594 release_mem_region(region->start, resource_size(region));
598 region->end - region->start + 1);
599 595
600 region = platform_get_resource(pdev, IORESOURCE_MEM, 0); 596 region = platform_get_resource(pdev, IORESOURCE_MEM, 0);
601 release_mem_region(region->start, (region->end - region->start) + 1); 597 release_mem_region(region->start, resource_size(region));
602 598
603 iounmap(mmio); 599 iounmap(mmio);
604 region = platform_get_resource(pdev, IORESOURCE_IO, 0); 600 region = platform_get_resource(pdev, IORESOURCE_IO, 0);
605 release_mem_region(region->start, (region->end - region->start) + 1); 601 release_mem_region(region->start, resource_size(region));
606} 602}
607 603
608static struct platform_driver s6000_i2s_driver = { 604static struct platform_driver s6000_i2s_driver = {
diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig
index a1d14bc3c76..52d7e8ed9c1 100644
--- a/sound/soc/sh/Kconfig
+++ b/sound/soc/sh/Kconfig
@@ -48,7 +48,7 @@ config SND_SH7760_AC97
48 48
49config SND_FSI_AK4642 49config SND_FSI_AK4642
50 bool "FSI-AK4642 sound support" 50 bool "FSI-AK4642 sound support"
51 depends on SND_SOC_SH4_FSI 51 depends on SND_SOC_SH4_FSI && I2C_SH_MOBILE
52 select SND_SOC_AK4642 52 select SND_SOC_AK4642
53 help 53 help
54 This option enables generic sound support for the 54 This option enables generic sound support for the
@@ -56,7 +56,7 @@ config SND_FSI_AK4642
56 56
57config SND_FSI_DA7210 57config SND_FSI_DA7210
58 bool "FSI-DA7210 sound support" 58 bool "FSI-DA7210 sound support"
59 depends on SND_SOC_SH4_FSI 59 depends on SND_SOC_SH4_FSI && I2C_SH_MOBILE
60 select SND_SOC_DA7210 60 select SND_SOC_DA7210
61 help 61 help
62 This option enables generic sound support for the 62 This option enables generic sound support for the
diff --git a/sound/soc/sh/fsi-ak4642.c b/sound/soc/sh/fsi-ak4642.c
index be018542314..dad575a2262 100644
--- a/sound/soc/sh/fsi-ak4642.c
+++ b/sound/soc/sh/fsi-ak4642.c
@@ -9,16 +9,7 @@
9 * for more details. 9 * for more details.
10 */ 10 */
11 11
12#include <linux/module.h>
13#include <linux/moduleparam.h>
14#include <linux/platform_device.h> 12#include <linux/platform_device.h>
15#include <linux/i2c.h>
16#include <linux/io.h>
17#include <sound/core.h>
18#include <sound/pcm.h>
19#include <sound/soc.h>
20#include <sound/soc-dapm.h>
21
22#include <sound/sh_fsi.h> 13#include <sound/sh_fsi.h>
23#include <../sound/soc/codecs/ak4642.h> 14#include <../sound/soc/codecs/ak4642.h>
24 15
@@ -38,7 +29,7 @@ static int fsi_ak4642_dai_init(struct snd_soc_codec *codec)
38static struct snd_soc_dai_link fsi_dai_link = { 29static struct snd_soc_dai_link fsi_dai_link = {
39 .name = "AK4642", 30 .name = "AK4642",
40 .stream_name = "AK4642", 31 .stream_name = "AK4642",
41 .cpu_dai = &fsi_soc_dai[0], /* fsi */ 32 .cpu_dai = &fsi_soc_dai[FSI_PORT_A],
42 .codec_dai = &ak4642_dai, 33 .codec_dai = &ak4642_dai,
43 .init = fsi_ak4642_dai_init, 34 .init = fsi_ak4642_dai_init,
44 .ops = NULL, 35 .ops = NULL,
@@ -62,7 +53,7 @@ static int __init fsi_ak4642_init(void)
62{ 53{
63 int ret = -ENOMEM; 54 int ret = -ENOMEM;
64 55
65 fsi_snd_device = platform_device_alloc("soc-audio", -1); 56 fsi_snd_device = platform_device_alloc("soc-audio", FSI_PORT_A);
66 if (!fsi_snd_device) 57 if (!fsi_snd_device)
67 goto out; 58 goto out;
68 59
diff --git a/sound/soc/sh/fsi-da7210.c b/sound/soc/sh/fsi-da7210.c
index 33b4d177f46..121bbb07bb0 100644
--- a/sound/soc/sh/fsi-da7210.c
+++ b/sound/soc/sh/fsi-da7210.c
@@ -10,16 +10,7 @@
10 * option) any later version. 10 * option) any later version.
11 */ 11 */
12 12
13#include <linux/interrupt.h>
14#include <linux/platform_device.h> 13#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> 14#include <sound/sh_fsi.h>
24#include "../codecs/da7210.h" 15#include "../codecs/da7210.h"
25 16
@@ -33,7 +24,7 @@ static int fsi_da7210_init(struct snd_soc_codec *codec)
33static struct snd_soc_dai_link fsi_da7210_dai = { 24static struct snd_soc_dai_link fsi_da7210_dai = {
34 .name = "DA7210", 25 .name = "DA7210",
35 .stream_name = "DA7210", 26 .stream_name = "DA7210",
36 .cpu_dai = &fsi_soc_dai[1], /* FSI B */ 27 .cpu_dai = &fsi_soc_dai[FSI_PORT_B],
37 .codec_dai = &da7210_dai, 28 .codec_dai = &da7210_dai,
38 .init = fsi_da7210_init, 29 .init = fsi_da7210_init,
39}; 30};
@@ -56,7 +47,7 @@ static int __init fsi_da7210_sound_init(void)
56{ 47{
57 int ret; 48 int ret;
58 49
59 fsi_da7210_snd_device = platform_device_alloc("soc-audio", -1); 50 fsi_da7210_snd_device = platform_device_alloc("soc-audio", FSI_PORT_B);
60 if (!fsi_da7210_snd_device) 51 if (!fsi_da7210_snd_device)
61 return -ENOMEM; 52 return -ENOMEM;
62 53
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index ec4acac49eb..58c6bec642d 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -12,21 +12,12 @@
12 * published by the Free Software Foundation. 12 * published by the Free Software Foundation.
13 */ 13 */
14 14
15#include <linux/init.h>
16#include <linux/module.h>
17#include <linux/platform_device.h>
18#include <linux/delay.h> 15#include <linux/delay.h>
19#include <linux/list.h>
20#include <linux/pm_runtime.h> 16#include <linux/pm_runtime.h>
21#include <linux/io.h> 17#include <linux/io.h>
22#include <linux/slab.h> 18#include <linux/slab.h>
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/initval.h>
26#include <sound/soc.h> 19#include <sound/soc.h>
27#include <sound/pcm_params.h>
28#include <sound/sh_fsi.h> 20#include <sound/sh_fsi.h>
29#include <asm/atomic.h>
30 21
31#define DO_FMT 0x0000 22#define DO_FMT 0x0000
32#define DOFF_CTL 0x0004 23#define DOFF_CTL 0x0004
@@ -39,9 +30,11 @@
39#define DIDT 0x0020 30#define DIDT 0x0020
40#define DODT 0x0024 31#define DODT 0x0024
41#define MUTE_ST 0x0028 32#define MUTE_ST 0x0028
42#define REG_END MUTE_ST 33#define OUT_SEL 0x0030
43 34#define REG_END OUT_SEL
44 35
36#define A_MST_CTLR 0x0180
37#define B_MST_CTLR 0x01A0
45#define CPU_INT_ST 0x01F4 38#define CPU_INT_ST 0x01F4
46#define CPU_IEMSK 0x01F8 39#define CPU_IEMSK 0x01F8
47#define CPU_IMSK 0x01FC 40#define CPU_IMSK 0x01FC
@@ -52,18 +45,18 @@
52#define CLK_RST 0x0210 45#define CLK_RST 0x0210
53#define SOFT_RST 0x0214 46#define SOFT_RST 0x0214
54#define FIFO_SZ 0x0218 47#define FIFO_SZ 0x0218
55#define MREG_START CPU_INT_ST 48#define MREG_START A_MST_CTLR
56#define MREG_END FIFO_SZ 49#define MREG_END FIFO_SZ
57 50
58/* DO_FMT */ 51/* DO_FMT */
59/* DI_FMT */ 52/* DI_FMT */
60#define CR_FMT(param) ((param) << 4) 53#define CR_MONO (0x0 << 4)
61# define CR_MONO 0x0 54#define CR_MONO_D (0x1 << 4)
62# define CR_MONO_D 0x1 55#define CR_PCM (0x2 << 4)
63# define CR_PCM 0x2 56#define CR_I2S (0x3 << 4)
64# define CR_I2S 0x3 57#define CR_TDM (0x4 << 4)
65# define CR_TDM 0x4 58#define CR_TDM_D (0x5 << 4)
66# define CR_TDM_D 0x5 59#define CR_SPDIF 0x00100120
67 60
68/* DOFF_CTL */ 61/* DOFF_CTL */
69/* DIFF_CTL */ 62/* DIFF_CTL */
@@ -75,6 +68,14 @@
75#define ERR_UNDER 0x00000001 68#define ERR_UNDER 0x00000001
76#define ST_ERR (ERR_OVER | ERR_UNDER) 69#define ST_ERR (ERR_OVER | ERR_UNDER)
77 70
71/* CKG1 */
72#define ACKMD_MASK 0x00007000
73#define BPFMD_MASK 0x00000700
74
75/* A/B MST_CTLR */
76#define BP (1 << 4) /* Fix the signal of Biphase output */
77#define SE (1 << 0) /* Fix the master clock */
78
78/* CLK_RST */ 79/* CLK_RST */
79#define B_CLK 0x00000010 80#define B_CLK 0x00000010
80#define A_CLK 0x00000001 81#define A_CLK 0x00000001
@@ -119,9 +120,13 @@ struct fsi_priv {
119 int period_len; 120 int period_len;
120 int buffer_len; 121 int buffer_len;
121 int periods; 122 int periods;
123
124 u32 mst_ctrl;
122}; 125};
123 126
124struct fsi_regs { 127struct fsi_core {
128 int ver;
129
125 u32 int_st; 130 u32 int_st;
126 u32 iemsk; 131 u32 iemsk;
127 u32 imsk; 132 u32 imsk;
@@ -132,7 +137,7 @@ struct fsi_master {
132 int irq; 137 int irq;
133 struct fsi_priv fsia; 138 struct fsi_priv fsia;
134 struct fsi_priv fsib; 139 struct fsi_priv fsib;
135 struct fsi_regs *regs; 140 struct fsi_core *core;
136 struct sh_fsi_platform_info *info; 141 struct sh_fsi_platform_info *info;
137 spinlock_t lock; 142 spinlock_t lock;
138}; 143};
@@ -169,24 +174,30 @@ static void __fsi_reg_mask_set(u32 reg, u32 mask, u32 data)
169 174
170static void fsi_reg_write(struct fsi_priv *fsi, u32 reg, u32 data) 175static void fsi_reg_write(struct fsi_priv *fsi, u32 reg, u32 data)
171{ 176{
172 if (reg > REG_END) 177 if (reg > REG_END) {
178 pr_err("fsi: register access err (%s)\n", __func__);
173 return; 179 return;
180 }
174 181
175 __fsi_reg_write((u32)(fsi->base + reg), data); 182 __fsi_reg_write((u32)(fsi->base + reg), data);
176} 183}
177 184
178static u32 fsi_reg_read(struct fsi_priv *fsi, u32 reg) 185static u32 fsi_reg_read(struct fsi_priv *fsi, u32 reg)
179{ 186{
180 if (reg > REG_END) 187 if (reg > REG_END) {
188 pr_err("fsi: register access err (%s)\n", __func__);
181 return 0; 189 return 0;
190 }
182 191
183 return __fsi_reg_read((u32)(fsi->base + reg)); 192 return __fsi_reg_read((u32)(fsi->base + reg));
184} 193}
185 194
186static void fsi_reg_mask_set(struct fsi_priv *fsi, u32 reg, u32 mask, u32 data) 195static void fsi_reg_mask_set(struct fsi_priv *fsi, u32 reg, u32 mask, u32 data)
187{ 196{
188 if (reg > REG_END) 197 if (reg > REG_END) {
198 pr_err("fsi: register access err (%s)\n", __func__);
189 return; 199 return;
200 }
190 201
191 __fsi_reg_mask_set((u32)(fsi->base + reg), mask, data); 202 __fsi_reg_mask_set((u32)(fsi->base + reg), mask, data);
192} 203}
@@ -196,8 +207,10 @@ static void fsi_master_write(struct fsi_master *master, u32 reg, u32 data)
196 unsigned long flags; 207 unsigned long flags;
197 208
198 if ((reg < MREG_START) || 209 if ((reg < MREG_START) ||
199 (reg > MREG_END)) 210 (reg > MREG_END)) {
211 pr_err("fsi: register access err (%s)\n", __func__);
200 return; 212 return;
213 }
201 214
202 spin_lock_irqsave(&master->lock, flags); 215 spin_lock_irqsave(&master->lock, flags);
203 __fsi_reg_write((u32)(master->base + reg), data); 216 __fsi_reg_write((u32)(master->base + reg), data);
@@ -210,8 +223,10 @@ static u32 fsi_master_read(struct fsi_master *master, u32 reg)
210 unsigned long flags; 223 unsigned long flags;
211 224
212 if ((reg < MREG_START) || 225 if ((reg < MREG_START) ||
213 (reg > MREG_END)) 226 (reg > MREG_END)) {
227 pr_err("fsi: register access err (%s)\n", __func__);
214 return 0; 228 return 0;
229 }
215 230
216 spin_lock_irqsave(&master->lock, flags); 231 spin_lock_irqsave(&master->lock, flags);
217 ret = __fsi_reg_read((u32)(master->base + reg)); 232 ret = __fsi_reg_read((u32)(master->base + reg));
@@ -226,8 +241,10 @@ static void fsi_master_mask_set(struct fsi_master *master,
226 unsigned long flags; 241 unsigned long flags;
227 242
228 if ((reg < MREG_START) || 243 if ((reg < MREG_START) ||
229 (reg > MREG_END)) 244 (reg > MREG_END)) {
245 pr_err("fsi: register access err (%s)\n", __func__);
230 return; 246 return;
247 }
231 248
232 spin_lock_irqsave(&master->lock, flags); 249 spin_lock_irqsave(&master->lock, flags);
233 __fsi_reg_mask_set((u32)(master->base + reg), mask, data); 250 __fsi_reg_mask_set((u32)(master->base + reg), mask, data);
@@ -349,8 +366,8 @@ static void fsi_irq_enable(struct fsi_priv *fsi, int is_play)
349 u32 data = fsi_port_ab_io_bit(fsi, is_play); 366 u32 data = fsi_port_ab_io_bit(fsi, is_play);
350 struct fsi_master *master = fsi_get_master(fsi); 367 struct fsi_master *master = fsi_get_master(fsi);
351 368
352 fsi_master_mask_set(master, master->regs->imsk, data, data); 369 fsi_master_mask_set(master, master->core->imsk, data, data);
353 fsi_master_mask_set(master, master->regs->iemsk, data, data); 370 fsi_master_mask_set(master, master->core->iemsk, data, data);
354} 371}
355 372
356static void fsi_irq_disable(struct fsi_priv *fsi, int is_play) 373static void fsi_irq_disable(struct fsi_priv *fsi, int is_play)
@@ -358,18 +375,18 @@ static void fsi_irq_disable(struct fsi_priv *fsi, int is_play)
358 u32 data = fsi_port_ab_io_bit(fsi, is_play); 375 u32 data = fsi_port_ab_io_bit(fsi, is_play);
359 struct fsi_master *master = fsi_get_master(fsi); 376 struct fsi_master *master = fsi_get_master(fsi);
360 377
361 fsi_master_mask_set(master, master->regs->imsk, data, 0); 378 fsi_master_mask_set(master, master->core->imsk, data, 0);
362 fsi_master_mask_set(master, master->regs->iemsk, data, 0); 379 fsi_master_mask_set(master, master->core->iemsk, data, 0);
363} 380}
364 381
365static u32 fsi_irq_get_status(struct fsi_master *master) 382static u32 fsi_irq_get_status(struct fsi_master *master)
366{ 383{
367 return fsi_master_read(master, master->regs->int_st); 384 return fsi_master_read(master, master->core->int_st);
368} 385}
369 386
370static void fsi_irq_clear_all_status(struct fsi_master *master) 387static void fsi_irq_clear_all_status(struct fsi_master *master)
371{ 388{
372 fsi_master_write(master, master->regs->int_st, 0x0000000); 389 fsi_master_write(master, master->core->int_st, 0);
373} 390}
374 391
375static void fsi_irq_clear_status(struct fsi_priv *fsi) 392static void fsi_irq_clear_status(struct fsi_priv *fsi)
@@ -381,7 +398,30 @@ static void fsi_irq_clear_status(struct fsi_priv *fsi)
381 data |= fsi_port_ab_io_bit(fsi, 1); 398 data |= fsi_port_ab_io_bit(fsi, 1);
382 399
383 /* clear interrupt factor */ 400 /* clear interrupt factor */
384 fsi_master_mask_set(master, master->regs->int_st, data, 0); 401 fsi_master_mask_set(master, master->core->int_st, data, 0);
402}
403
404/************************************************************************
405
406
407 SPDIF master clock function
408
409These functions are used later FSI2
410************************************************************************/
411static void fsi_spdif_clk_ctrl(struct fsi_priv *fsi, int enable)
412{
413 struct fsi_master *master = fsi_get_master(fsi);
414 u32 val = BP | SE;
415
416 if (master->core->ver < 2) {
417 pr_err("fsi: register access err (%s)\n", __func__);
418 return;
419 }
420
421 if (enable)
422 fsi_master_mask_set(master, fsi->mst_ctrl, val, val);
423 else
424 fsi_master_mask_set(master, fsi->mst_ctrl, val, 0);
385} 425}
386 426
387/************************************************************************ 427/************************************************************************
@@ -662,8 +702,8 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
662 struct snd_soc_dai *dai) 702 struct snd_soc_dai *dai)
663{ 703{
664 struct fsi_priv *fsi = fsi_get_priv(substream); 704 struct fsi_priv *fsi = fsi_get_priv(substream);
665 const char *msg;
666 u32 flags = fsi_get_info_flags(fsi); 705 u32 flags = fsi_get_info_flags(fsi);
706 struct fsi_master *master = fsi_get_master(fsi);
667 u32 fmt; 707 u32 fmt;
668 u32 reg; 708 u32 reg;
669 u32 data; 709 u32 data;
@@ -700,36 +740,40 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
700 fmt = is_play ? SH_FSI_GET_OFMT(flags) : SH_FSI_GET_IFMT(flags); 740 fmt = is_play ? SH_FSI_GET_OFMT(flags) : SH_FSI_GET_IFMT(flags);
701 switch (fmt) { 741 switch (fmt) {
702 case SH_FSI_FMT_MONO: 742 case SH_FSI_FMT_MONO:
703 msg = "MONO"; 743 data = CR_MONO;
704 data = CR_FMT(CR_MONO);
705 fsi->chan = 1; 744 fsi->chan = 1;
706 break; 745 break;
707 case SH_FSI_FMT_MONO_DELAY: 746 case SH_FSI_FMT_MONO_DELAY:
708 msg = "MONO Delay"; 747 data = CR_MONO_D;
709 data = CR_FMT(CR_MONO_D);
710 fsi->chan = 1; 748 fsi->chan = 1;
711 break; 749 break;
712 case SH_FSI_FMT_PCM: 750 case SH_FSI_FMT_PCM:
713 msg = "PCM"; 751 data = CR_PCM;
714 data = CR_FMT(CR_PCM);
715 fsi->chan = 2; 752 fsi->chan = 2;
716 break; 753 break;
717 case SH_FSI_FMT_I2S: 754 case SH_FSI_FMT_I2S:
718 msg = "I2S"; 755 data = CR_I2S;
719 data = CR_FMT(CR_I2S);
720 fsi->chan = 2; 756 fsi->chan = 2;
721 break; 757 break;
722 case SH_FSI_FMT_TDM: 758 case SH_FSI_FMT_TDM:
723 msg = "TDM";
724 fsi->chan = is_play ? 759 fsi->chan = is_play ?
725 SH_FSI_GET_CH_O(flags) : SH_FSI_GET_CH_I(flags); 760 SH_FSI_GET_CH_O(flags) : SH_FSI_GET_CH_I(flags);
726 data = CR_FMT(CR_TDM) | (fsi->chan - 1); 761 data = CR_TDM | (fsi->chan - 1);
727 break; 762 break;
728 case SH_FSI_FMT_TDM_DELAY: 763 case SH_FSI_FMT_TDM_DELAY:
729 msg = "TDM Delay";
730 fsi->chan = is_play ? 764 fsi->chan = is_play ?
731 SH_FSI_GET_CH_O(flags) : SH_FSI_GET_CH_I(flags); 765 SH_FSI_GET_CH_O(flags) : SH_FSI_GET_CH_I(flags);
732 data = CR_FMT(CR_TDM_D) | (fsi->chan - 1); 766 data = CR_TDM_D | (fsi->chan - 1);
767 break;
768 case SH_FSI_FMT_SPDIF:
769 if (master->core->ver < 2) {
770 dev_err(dai->dev, "This FSI can not use SPDIF\n");
771 return -EINVAL;
772 }
773 data = CR_SPDIF;
774 fsi->chan = 2;
775 fsi_spdif_clk_ctrl(fsi, 1);
776 fsi_reg_mask_set(fsi, OUT_SEL, 0x0010, 0x0010);
733 break; 777 break;
734 default: 778 default:
735 dev_err(dai->dev, "unknown format.\n"); 779 dev_err(dai->dev, "unknown format.\n");
@@ -737,12 +781,6 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
737 } 781 }
738 fsi_reg_write(fsi, reg, data); 782 fsi_reg_write(fsi, reg, data);
739 783
740 /*
741 * clear clk reset if master mode
742 */
743 if (is_master)
744 fsi_clk_ctrl(fsi, 1);
745
746 /* irq clear */ 784 /* irq clear */
747 fsi_irq_disable(fsi, is_play); 785 fsi_irq_disable(fsi, is_play);
748 fsi_irq_clear_status(fsi); 786 fsi_irq_clear_status(fsi);
@@ -789,10 +827,93 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
789 return ret; 827 return ret;
790} 828}
791 829
830static int fsi_dai_hw_params(struct snd_pcm_substream *substream,
831 struct snd_pcm_hw_params *params,
832 struct snd_soc_dai *dai)
833{
834 struct fsi_priv *fsi = fsi_get_priv(substream);
835 struct fsi_master *master = fsi_get_master(fsi);
836 int (*set_rate)(int is_porta, int rate) = master->info->set_rate;
837 int fsi_ver = master->core->ver;
838 int is_play = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
839 int ret;
840
841 /* if slave mode, set_rate is not needed */
842 if (!fsi_is_master_mode(fsi, is_play))
843 return 0;
844
845 /* it is error if no set_rate */
846 if (!set_rate)
847 return -EIO;
848
849 ret = set_rate(fsi_is_port_a(fsi), params_rate(params));
850 if (ret > 0) {
851 u32 data = 0;
852
853 switch (ret & SH_FSI_ACKMD_MASK) {
854 default:
855 /* FALL THROUGH */
856 case SH_FSI_ACKMD_512:
857 data |= (0x0 << 12);
858 break;
859 case SH_FSI_ACKMD_256:
860 data |= (0x1 << 12);
861 break;
862 case SH_FSI_ACKMD_128:
863 data |= (0x2 << 12);
864 break;
865 case SH_FSI_ACKMD_64:
866 data |= (0x3 << 12);
867 break;
868 case SH_FSI_ACKMD_32:
869 if (fsi_ver < 2)
870 dev_err(dai->dev, "unsupported ACKMD\n");
871 else
872 data |= (0x4 << 12);
873 break;
874 }
875
876 switch (ret & SH_FSI_BPFMD_MASK) {
877 default:
878 /* FALL THROUGH */
879 case SH_FSI_BPFMD_32:
880 data |= (0x0 << 8);
881 break;
882 case SH_FSI_BPFMD_64:
883 data |= (0x1 << 8);
884 break;
885 case SH_FSI_BPFMD_128:
886 data |= (0x2 << 8);
887 break;
888 case SH_FSI_BPFMD_256:
889 data |= (0x3 << 8);
890 break;
891 case SH_FSI_BPFMD_512:
892 data |= (0x4 << 8);
893 break;
894 case SH_FSI_BPFMD_16:
895 if (fsi_ver < 2)
896 dev_err(dai->dev, "unsupported ACKMD\n");
897 else
898 data |= (0x7 << 8);
899 break;
900 }
901
902 fsi_reg_mask_set(fsi, CKG1, (ACKMD_MASK | BPFMD_MASK) , data);
903 udelay(10);
904 fsi_clk_ctrl(fsi, 1);
905 ret = 0;
906 }
907
908 return ret;
909
910}
911
792static struct snd_soc_dai_ops fsi_dai_ops = { 912static struct snd_soc_dai_ops fsi_dai_ops = {
793 .startup = fsi_dai_startup, 913 .startup = fsi_dai_startup,
794 .shutdown = fsi_dai_shutdown, 914 .shutdown = fsi_dai_shutdown,
795 .trigger = fsi_dai_trigger, 915 .trigger = fsi_dai_trigger,
916 .hw_params = fsi_dai_hw_params,
796}; 917};
797 918
798/************************************************************************ 919/************************************************************************
@@ -965,11 +1086,6 @@ static int fsi_probe(struct platform_device *pdev)
965 unsigned int irq; 1086 unsigned int irq;
966 int ret; 1087 int ret;
967 1088
968 if (0 != pdev->id) {
969 dev_err(&pdev->dev, "current fsi support id 0 only now\n");
970 return -ENODEV;
971 }
972
973 id_entry = pdev->id_entry; 1089 id_entry = pdev->id_entry;
974 if (!id_entry) { 1090 if (!id_entry) {
975 dev_err(&pdev->dev, "unknown fsi device\n"); 1091 dev_err(&pdev->dev, "unknown fsi device\n");
@@ -998,14 +1114,21 @@ static int fsi_probe(struct platform_device *pdev)
998 goto exit_kfree; 1114 goto exit_kfree;
999 } 1115 }
1000 1116
1117 /* master setting */
1001 master->irq = irq; 1118 master->irq = irq;
1002 master->info = pdev->dev.platform_data; 1119 master->info = pdev->dev.platform_data;
1120 master->core = (struct fsi_core *)id_entry->driver_data;
1121 spin_lock_init(&master->lock);
1122
1123 /* FSI A setting */
1003 master->fsia.base = master->base; 1124 master->fsia.base = master->base;
1004 master->fsia.master = master; 1125 master->fsia.master = master;
1126 master->fsia.mst_ctrl = A_MST_CTLR;
1127
1128 /* FSI B setting */
1005 master->fsib.base = master->base + 0x40; 1129 master->fsib.base = master->base + 0x40;
1006 master->fsib.master = master; 1130 master->fsib.master = master;
1007 master->regs = (struct fsi_regs *)id_entry->driver_data; 1131 master->fsib.mst_ctrl = B_MST_CTLR;
1008 spin_lock_init(&master->lock);
1009 1132
1010 pm_runtime_enable(&pdev->dev); 1133 pm_runtime_enable(&pdev->dev);
1011 pm_runtime_resume(&pdev->dev); 1134 pm_runtime_resume(&pdev->dev);
@@ -1085,21 +1208,27 @@ static struct dev_pm_ops fsi_pm_ops = {
1085 .runtime_resume = fsi_runtime_nop, 1208 .runtime_resume = fsi_runtime_nop,
1086}; 1209};
1087 1210
1088static struct fsi_regs fsi_regs = { 1211static struct fsi_core fsi1_core = {
1212 .ver = 1,
1213
1214 /* Interrupt */
1089 .int_st = INT_ST, 1215 .int_st = INT_ST,
1090 .iemsk = IEMSK, 1216 .iemsk = IEMSK,
1091 .imsk = IMSK, 1217 .imsk = IMSK,
1092}; 1218};
1093 1219
1094static struct fsi_regs fsi2_regs = { 1220static struct fsi_core fsi2_core = {
1221 .ver = 2,
1222
1223 /* Interrupt */
1095 .int_st = CPU_INT_ST, 1224 .int_st = CPU_INT_ST,
1096 .iemsk = CPU_IEMSK, 1225 .iemsk = CPU_IEMSK,
1097 .imsk = CPU_IMSK, 1226 .imsk = CPU_IMSK,
1098}; 1227};
1099 1228
1100static struct platform_device_id fsi_id_table[] = { 1229static struct platform_device_id fsi_id_table[] = {
1101 { "sh_fsi", (kernel_ulong_t)&fsi_regs }, 1230 { "sh_fsi", (kernel_ulong_t)&fsi1_core },
1102 { "sh_fsi2", (kernel_ulong_t)&fsi2_regs }, 1231 { "sh_fsi2", (kernel_ulong_t)&fsi2_core },
1103}; 1232};
1104 1233
1105static struct platform_driver fsi_driver = { 1234static struct platform_driver fsi_driver = {
diff --git a/sound/soc/sh/migor.c b/sound/soc/sh/migor.c
index b823a5c9b9b..87e2b7fcbf1 100644
--- a/sound/soc/sh/migor.c
+++ b/sound/soc/sh/migor.c
@@ -12,6 +12,7 @@
12#include <linux/firmware.h> 12#include <linux/firmware.h>
13#include <linux/module.h> 13#include <linux/module.h>
14 14
15#include <asm/clkdev.h>
15#include <asm/clock.h> 16#include <asm/clock.h>
16 17
17#include <cpu/sh7722.h> 18#include <cpu/sh7722.h>
@@ -40,12 +41,12 @@ static struct clk_ops siumckb_clk_ops = {
40}; 41};
41 42
42static struct clk siumckb_clk = { 43static struct clk siumckb_clk = {
43 .name = "siumckb_clk",
44 .id = -1,
45 .ops = &siumckb_clk_ops, 44 .ops = &siumckb_clk_ops,
46 .rate = 0, /* initialised at run-time */ 45 .rate = 0, /* initialised at run-time */
47}; 46};
48 47
48static struct clk_lookup *siumckb_lookup;
49
49static int migor_hw_params(struct snd_pcm_substream *substream, 50static int migor_hw_params(struct snd_pcm_substream *substream,
50 struct snd_pcm_hw_params *params) 51 struct snd_pcm_hw_params *params)
51{ 52{
@@ -180,6 +181,13 @@ static int __init migor_init(void)
180 if (ret < 0) 181 if (ret < 0)
181 return ret; 182 return ret;
182 183
184 siumckb_lookup = clkdev_alloc(&siumckb_clk, "siumckb_clk", NULL);
185 if (!siumckb_lookup) {
186 ret = -ENOMEM;
187 goto eclkdevalloc;
188 }
189 clkdev_add(siumckb_lookup);
190
183 /* Port number used on this machine: port B */ 191 /* Port number used on this machine: port B */
184 migor_snd_device = platform_device_alloc("soc-audio", 1); 192 migor_snd_device = platform_device_alloc("soc-audio", 1);
185 if (!migor_snd_device) { 193 if (!migor_snd_device) {
@@ -200,12 +208,15 @@ static int __init migor_init(void)
200epdevadd: 208epdevadd:
201 platform_device_put(migor_snd_device); 209 platform_device_put(migor_snd_device);
202epdevalloc: 210epdevalloc:
211 clkdev_drop(siumckb_lookup);
212eclkdevalloc:
203 clk_unregister(&siumckb_clk); 213 clk_unregister(&siumckb_clk);
204 return ret; 214 return ret;
205} 215}
206 216
207static void __exit migor_exit(void) 217static void __exit migor_exit(void)
208{ 218{
219 clkdev_drop(siumckb_lookup);
209 clk_unregister(&siumckb_clk); 220 clk_unregister(&siumckb_clk);
210 platform_device_unregister(migor_snd_device); 221 platform_device_unregister(migor_snd_device);
211} 222}
diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c
index 472af38188c..f6b0d2829ea 100644
--- a/sound/soc/soc-cache.c
+++ b/sound/soc/soc-cache.c
@@ -203,8 +203,9 @@ static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg,
203 data[1] = (value >> 8) & 0xff; 203 data[1] = (value >> 8) & 0xff;
204 data[2] = value & 0xff; 204 data[2] = value & 0xff;
205 205
206 if (!snd_soc_codec_volatile_register(codec, reg)) 206 if (!snd_soc_codec_volatile_register(codec, reg)
207 reg_cache[reg] = value; 207 && reg < codec->reg_cache_size)
208 reg_cache[reg] = value;
208 209
209 if (codec->cache_only) { 210 if (codec->cache_only) {
210 codec->cache_sync = 1; 211 codec->cache_sync = 1;
@@ -340,7 +341,7 @@ static unsigned int snd_soc_16_8_read_i2c(struct snd_soc_codec *codec,
340static unsigned int snd_soc_16_8_read(struct snd_soc_codec *codec, 341static unsigned int snd_soc_16_8_read(struct snd_soc_codec *codec,
341 unsigned int reg) 342 unsigned int reg)
342{ 343{
343 u16 *cache = codec->reg_cache; 344 u8 *cache = codec->reg_cache;
344 345
345 reg &= 0xff; 346 reg &= 0xff;
346 if (reg >= codec->reg_cache_size) 347 if (reg >= codec->reg_cache_size)
@@ -351,7 +352,7 @@ static unsigned int snd_soc_16_8_read(struct snd_soc_codec *codec,
351static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg, 352static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg,
352 unsigned int value) 353 unsigned int value)
353{ 354{
354 u16 *cache = codec->reg_cache; 355 u8 *cache = codec->reg_cache;
355 u8 data[3]; 356 u8 data[3];
356 int ret; 357 int ret;
357 358
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 998569d6033..acc91daa1c5 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -84,7 +84,7 @@ static int run_delayed_work(struct delayed_work *dwork)
84/* codec register dump */ 84/* codec register dump */
85static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf) 85static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf)
86{ 86{
87 int i, step = 1, count = 0; 87 int ret, i, step = 1, count = 0;
88 88
89 if (!codec->reg_cache_size) 89 if (!codec->reg_cache_size)
90 return 0; 90 return 0;
@@ -101,12 +101,24 @@ static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf)
101 if (count >= PAGE_SIZE - 1) 101 if (count >= PAGE_SIZE - 1)
102 break; 102 break;
103 103
104 if (codec->display_register) 104 if (codec->display_register) {
105 count += codec->display_register(codec, buf + count, 105 count += codec->display_register(codec, buf + count,
106 PAGE_SIZE - count, i); 106 PAGE_SIZE - count, i);
107 else 107 } else {
108 count += snprintf(buf + count, PAGE_SIZE - count, 108 /* If the read fails it's almost certainly due to
109 "%4x", codec->read(codec, i)); 109 * the register being volatile and the device being
110 * powered off.
111 */
112 ret = codec->read(codec, i);
113 if (ret >= 0)
114 count += snprintf(buf + count,
115 PAGE_SIZE - count,
116 "%4x", ret);
117 else
118 count += snprintf(buf + count,
119 PAGE_SIZE - count,
120 "<no data: %d>", ret);
121 }
110 122
111 if (count >= PAGE_SIZE - 1) 123 if (count >= PAGE_SIZE - 1)
112 break; 124 break;
@@ -239,7 +251,7 @@ static void soc_init_codec_debugfs(struct snd_soc_codec *codec)
239 printk(KERN_WARNING 251 printk(KERN_WARNING
240 "ASoC: Failed to create codec register debugfs file\n"); 252 "ASoC: Failed to create codec register debugfs file\n");
241 253
242 codec->debugfs_pop_time = debugfs_create_u32("dapm_pop_time", 0744, 254 codec->debugfs_pop_time = debugfs_create_u32("dapm_pop_time", 0644,
243 codec->debugfs_codec_root, 255 codec->debugfs_codec_root,
244 &codec->pop_time); 256 &codec->pop_time);
245 if (!codec->debugfs_pop_time) 257 if (!codec->debugfs_pop_time)
@@ -1307,7 +1319,7 @@ cpu_dai_err:
1307} 1319}
1308 1320
1309/* 1321/*
1310 * Attempt to initialise any uninitalised cards. Must be called with 1322 * Attempt to initialise any uninitialised cards. Must be called with
1311 * client_mutex. 1323 * client_mutex.
1312 */ 1324 */
1313static void snd_soc_instantiate_cards(void) 1325static void snd_soc_instantiate_cards(void)
@@ -2353,6 +2365,99 @@ int snd_soc_limit_volume(struct snd_soc_codec *codec,
2353EXPORT_SYMBOL_GPL(snd_soc_limit_volume); 2365EXPORT_SYMBOL_GPL(snd_soc_limit_volume);
2354 2366
2355/** 2367/**
2368 * snd_soc_info_volsw_2r_sx - double with tlv and variable data size
2369 * mixer info callback
2370 * @kcontrol: mixer control
2371 * @uinfo: control element information
2372 *
2373 * Returns 0 for success.
2374 */
2375int snd_soc_info_volsw_2r_sx(struct snd_kcontrol *kcontrol,
2376 struct snd_ctl_elem_info *uinfo)
2377{
2378 struct soc_mixer_control *mc =
2379 (struct soc_mixer_control *)kcontrol->private_value;
2380 int max = mc->max;
2381 int min = mc->min;
2382
2383 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2384 uinfo->count = 2;
2385 uinfo->value.integer.min = 0;
2386 uinfo->value.integer.max = max-min;
2387
2388 return 0;
2389}
2390EXPORT_SYMBOL_GPL(snd_soc_info_volsw_2r_sx);
2391
2392/**
2393 * snd_soc_get_volsw_2r_sx - double with tlv and variable data size
2394 * mixer get callback
2395 * @kcontrol: mixer control
2396 * @uinfo: control element information
2397 *
2398 * Returns 0 for success.
2399 */
2400int snd_soc_get_volsw_2r_sx(struct snd_kcontrol *kcontrol,
2401 struct snd_ctl_elem_value *ucontrol)
2402{
2403 struct soc_mixer_control *mc =
2404 (struct soc_mixer_control *)kcontrol->private_value;
2405 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2406 unsigned int mask = (1<<mc->shift)-1;
2407 int min = mc->min;
2408 int val = snd_soc_read(codec, mc->reg) & mask;
2409 int valr = snd_soc_read(codec, mc->rreg) & mask;
2410
2411 ucontrol->value.integer.value[0] = ((val & 0xff)-min) & mask;
2412 ucontrol->value.integer.value[1] = ((valr & 0xff)-min) & mask;
2413 return 0;
2414}
2415EXPORT_SYMBOL_GPL(snd_soc_get_volsw_2r_sx);
2416
2417/**
2418 * snd_soc_put_volsw_2r_sx - double with tlv and variable data size
2419 * mixer put callback
2420 * @kcontrol: mixer control
2421 * @uinfo: control element information
2422 *
2423 * Returns 0 for success.
2424 */
2425int snd_soc_put_volsw_2r_sx(struct snd_kcontrol *kcontrol,
2426 struct snd_ctl_elem_value *ucontrol)
2427{
2428 struct soc_mixer_control *mc =
2429 (struct soc_mixer_control *)kcontrol->private_value;
2430 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2431 unsigned int mask = (1<<mc->shift)-1;
2432 int min = mc->min;
2433 int ret;
2434 unsigned int val, valr, oval, ovalr;
2435
2436 val = ((ucontrol->value.integer.value[0]+min) & 0xff);
2437 val &= mask;
2438 valr = ((ucontrol->value.integer.value[1]+min) & 0xff);
2439 valr &= mask;
2440
2441 oval = snd_soc_read(codec, mc->reg) & mask;
2442 ovalr = snd_soc_read(codec, mc->rreg) & mask;
2443
2444 ret = 0;
2445 if (oval != val) {
2446 ret = snd_soc_write(codec, mc->reg, val);
2447 if (ret < 0)
2448 return ret;
2449 }
2450 if (ovalr != valr) {
2451 ret = snd_soc_write(codec, mc->rreg, valr);
2452 if (ret < 0)
2453 return ret;
2454 }
2455
2456 return 0;
2457}
2458EXPORT_SYMBOL_GPL(snd_soc_put_volsw_2r_sx);
2459
2460/**
2356 * snd_soc_dai_set_sysclk - configure DAI system or master clock. 2461 * snd_soc_dai_set_sysclk - configure DAI system or master clock.
2357 * @dai: DAI 2462 * @dai: DAI
2358 * @clk_id: DAI specific clock ID 2463 * @clk_id: DAI specific clock ID
diff --git a/sound/sound_core.c b/sound/sound_core.c
index 7c2d677a2df..cb61317df50 100644
--- a/sound/sound_core.c
+++ b/sound/sound_core.c
@@ -576,8 +576,6 @@ static int soundcore_open(struct inode *inode, struct file *file)
576 struct sound_unit *s; 576 struct sound_unit *s;
577 const struct file_operations *new_fops = NULL; 577 const struct file_operations *new_fops = NULL;
578 578
579 lock_kernel ();
580
581 chain=unit&0x0F; 579 chain=unit&0x0F;
582 if(chain==4 || chain==5) /* dsp/audio/dsp16 */ 580 if(chain==4 || chain==5) /* dsp/audio/dsp16 */
583 { 581 {
@@ -630,18 +628,19 @@ static int soundcore_open(struct inode *inode, struct file *file)
630 const struct file_operations *old_fops = file->f_op; 628 const struct file_operations *old_fops = file->f_op;
631 file->f_op = new_fops; 629 file->f_op = new_fops;
632 spin_unlock(&sound_loader_lock); 630 spin_unlock(&sound_loader_lock);
633 if(file->f_op->open) 631
632 if (file->f_op->open)
634 err = file->f_op->open(inode,file); 633 err = file->f_op->open(inode,file);
634
635 if (err) { 635 if (err) {
636 fops_put(file->f_op); 636 fops_put(file->f_op);
637 file->f_op = fops_get(old_fops); 637 file->f_op = fops_get(old_fops);
638 } 638 }
639
639 fops_put(old_fops); 640 fops_put(old_fops);
640 unlock_kernel();
641 return err; 641 return err;
642 } 642 }
643 spin_unlock(&sound_loader_lock); 643 spin_unlock(&sound_loader_lock);
644 unlock_kernel();
645 return -ENODEV; 644 return -ENODEV;
646} 645}
647 646
diff --git a/sound/sparc/amd7930.c b/sound/sparc/amd7930.c
index 71221fd2094..f8bcfc30f80 100644
--- a/sound/sparc/amd7930.c
+++ b/sound/sparc/amd7930.c
@@ -336,7 +336,7 @@ struct snd_amd7930 {
336 int pgain; 336 int pgain;
337 int mgain; 337 int mgain;
338 338
339 struct of_device *op; 339 struct platform_device *op;
340 unsigned int irq; 340 unsigned int irq;
341 struct snd_amd7930 *next; 341 struct snd_amd7930 *next;
342}; 342};
@@ -906,7 +906,7 @@ static int __devinit snd_amd7930_mixer(struct snd_amd7930 *amd)
906 906
907static int snd_amd7930_free(struct snd_amd7930 *amd) 907static int snd_amd7930_free(struct snd_amd7930 *amd)
908{ 908{
909 struct of_device *op = amd->op; 909 struct platform_device *op = amd->op;
910 910
911 amd7930_idle(amd); 911 amd7930_idle(amd);
912 912
@@ -934,7 +934,7 @@ static struct snd_device_ops snd_amd7930_dev_ops = {
934}; 934};
935 935
936static int __devinit snd_amd7930_create(struct snd_card *card, 936static int __devinit snd_amd7930_create(struct snd_card *card,
937 struct of_device *op, 937 struct platform_device *op,
938 int irq, int dev, 938 int irq, int dev,
939 struct snd_amd7930 **ramd) 939 struct snd_amd7930 **ramd)
940{ 940{
@@ -1002,7 +1002,7 @@ static int __devinit snd_amd7930_create(struct snd_card *card,
1002 return 0; 1002 return 0;
1003} 1003}
1004 1004
1005static int __devinit amd7930_sbus_probe(struct of_device *op, const struct of_device_id *match) 1005static int __devinit amd7930_sbus_probe(struct platform_device *op, const struct of_device_id *match)
1006{ 1006{
1007 struct resource *rp = &op->resource[0]; 1007 struct resource *rp = &op->resource[0];
1008 static int dev_num; 1008 static int dev_num;
@@ -1010,7 +1010,7 @@ static int __devinit amd7930_sbus_probe(struct of_device *op, const struct of_de
1010 struct snd_amd7930 *amd; 1010 struct snd_amd7930 *amd;
1011 int err, irq; 1011 int err, irq;
1012 1012
1013 irq = op->irqs[0]; 1013 irq = op->archdata.irqs[0];
1014 1014
1015 if (dev_num >= SNDRV_CARDS) 1015 if (dev_num >= SNDRV_CARDS)
1016 return -ENODEV; 1016 return -ENODEV;
@@ -1075,7 +1075,7 @@ static struct of_platform_driver amd7930_sbus_driver = {
1075 1075
1076static int __init amd7930_init(void) 1076static int __init amd7930_init(void)
1077{ 1077{
1078 return of_register_driver(&amd7930_sbus_driver, &of_bus_type); 1078 return of_register_platform_driver(&amd7930_sbus_driver);
1079} 1079}
1080 1080
1081static void __exit amd7930_exit(void) 1081static void __exit amd7930_exit(void)
@@ -1092,7 +1092,7 @@ static void __exit amd7930_exit(void)
1092 1092
1093 amd7930_list = NULL; 1093 amd7930_list = NULL;
1094 1094
1095 of_unregister_driver(&amd7930_sbus_driver); 1095 of_unregister_platform_driver(&amd7930_sbus_driver);
1096} 1096}
1097 1097
1098module_init(amd7930_init); 1098module_init(amd7930_init);
diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c
index fb4c6f2f29e..c276086c3b5 100644
--- a/sound/sparc/cs4231.c
+++ b/sound/sparc/cs4231.c
@@ -111,7 +111,7 @@ struct snd_cs4231 {
111 struct mutex mce_mutex; /* mutex for mce register */ 111 struct mutex mce_mutex; /* mutex for mce register */
112 struct mutex open_mutex; /* mutex for ALSA open/close */ 112 struct mutex open_mutex; /* mutex for ALSA open/close */
113 113
114 struct of_device *op; 114 struct platform_device *op;
115 unsigned int irq[2]; 115 unsigned int irq[2];
116 unsigned int regs_size; 116 unsigned int regs_size;
117 struct snd_cs4231 *next; 117 struct snd_cs4231 *next;
@@ -1771,7 +1771,7 @@ static unsigned int sbus_dma_addr(struct cs4231_dma_control *dma_cont)
1771 1771
1772static int snd_cs4231_sbus_free(struct snd_cs4231 *chip) 1772static int snd_cs4231_sbus_free(struct snd_cs4231 *chip)
1773{ 1773{
1774 struct of_device *op = chip->op; 1774 struct platform_device *op = chip->op;
1775 1775
1776 if (chip->irq[0]) 1776 if (chip->irq[0])
1777 free_irq(chip->irq[0], chip); 1777 free_irq(chip->irq[0], chip);
@@ -1794,7 +1794,7 @@ static struct snd_device_ops snd_cs4231_sbus_dev_ops = {
1794}; 1794};
1795 1795
1796static int __devinit snd_cs4231_sbus_create(struct snd_card *card, 1796static int __devinit snd_cs4231_sbus_create(struct snd_card *card,
1797 struct of_device *op, 1797 struct platform_device *op,
1798 int dev) 1798 int dev)
1799{ 1799{
1800 struct snd_cs4231 *chip = card->private_data; 1800 struct snd_cs4231 *chip = card->private_data;
@@ -1832,14 +1832,14 @@ static int __devinit snd_cs4231_sbus_create(struct snd_card *card,
1832 chip->c_dma.request = sbus_dma_request; 1832 chip->c_dma.request = sbus_dma_request;
1833 chip->c_dma.address = sbus_dma_addr; 1833 chip->c_dma.address = sbus_dma_addr;
1834 1834
1835 if (request_irq(op->irqs[0], snd_cs4231_sbus_interrupt, 1835 if (request_irq(op->archdata.irqs[0], snd_cs4231_sbus_interrupt,
1836 IRQF_SHARED, "cs4231", chip)) { 1836 IRQF_SHARED, "cs4231", chip)) {
1837 snd_printdd("cs4231-%d: Unable to grab SBUS IRQ %d\n", 1837 snd_printdd("cs4231-%d: Unable to grab SBUS IRQ %d\n",
1838 dev, op->irqs[0]); 1838 dev, op->archdata.irqs[0]);
1839 snd_cs4231_sbus_free(chip); 1839 snd_cs4231_sbus_free(chip);
1840 return -EBUSY; 1840 return -EBUSY;
1841 } 1841 }
1842 chip->irq[0] = op->irqs[0]; 1842 chip->irq[0] = op->archdata.irqs[0];
1843 1843
1844 if (snd_cs4231_probe(chip) < 0) { 1844 if (snd_cs4231_probe(chip) < 0) {
1845 snd_cs4231_sbus_free(chip); 1845 snd_cs4231_sbus_free(chip);
@@ -1856,7 +1856,7 @@ static int __devinit snd_cs4231_sbus_create(struct snd_card *card,
1856 return 0; 1856 return 0;
1857} 1857}
1858 1858
1859static int __devinit cs4231_sbus_probe(struct of_device *op, const struct of_device_id *match) 1859static int __devinit cs4231_sbus_probe(struct platform_device *op, const struct of_device_id *match)
1860{ 1860{
1861 struct resource *rp = &op->resource[0]; 1861 struct resource *rp = &op->resource[0];
1862 struct snd_card *card; 1862 struct snd_card *card;
@@ -1870,7 +1870,7 @@ static int __devinit cs4231_sbus_probe(struct of_device *op, const struct of_dev
1870 card->shortname, 1870 card->shortname,
1871 rp->flags & 0xffL, 1871 rp->flags & 0xffL,
1872 (unsigned long long)rp->start, 1872 (unsigned long long)rp->start,
1873 op->irqs[0]); 1873 op->archdata.irqs[0]);
1874 1874
1875 err = snd_cs4231_sbus_create(card, op, dev); 1875 err = snd_cs4231_sbus_create(card, op, dev);
1876 if (err < 0) { 1876 if (err < 0) {
@@ -1931,7 +1931,7 @@ static unsigned int _ebus_dma_addr(struct cs4231_dma_control *dma_cont)
1931 1931
1932static int snd_cs4231_ebus_free(struct snd_cs4231 *chip) 1932static int snd_cs4231_ebus_free(struct snd_cs4231 *chip)
1933{ 1933{
1934 struct of_device *op = chip->op; 1934 struct platform_device *op = chip->op;
1935 1935
1936 if (chip->c_dma.ebus_info.regs) { 1936 if (chip->c_dma.ebus_info.regs) {
1937 ebus_dma_unregister(&chip->c_dma.ebus_info); 1937 ebus_dma_unregister(&chip->c_dma.ebus_info);
@@ -1960,7 +1960,7 @@ static struct snd_device_ops snd_cs4231_ebus_dev_ops = {
1960}; 1960};
1961 1961
1962static int __devinit snd_cs4231_ebus_create(struct snd_card *card, 1962static int __devinit snd_cs4231_ebus_create(struct snd_card *card,
1963 struct of_device *op, 1963 struct platform_device *op,
1964 int dev) 1964 int dev)
1965{ 1965{
1966 struct snd_cs4231 *chip = card->private_data; 1966 struct snd_cs4231 *chip = card->private_data;
@@ -1979,12 +1979,12 @@ static int __devinit snd_cs4231_ebus_create(struct snd_card *card,
1979 chip->c_dma.ebus_info.flags = EBUS_DMA_FLAG_USE_EBDMA_HANDLER; 1979 chip->c_dma.ebus_info.flags = EBUS_DMA_FLAG_USE_EBDMA_HANDLER;
1980 chip->c_dma.ebus_info.callback = snd_cs4231_ebus_capture_callback; 1980 chip->c_dma.ebus_info.callback = snd_cs4231_ebus_capture_callback;
1981 chip->c_dma.ebus_info.client_cookie = chip; 1981 chip->c_dma.ebus_info.client_cookie = chip;
1982 chip->c_dma.ebus_info.irq = op->irqs[0]; 1982 chip->c_dma.ebus_info.irq = op->archdata.irqs[0];
1983 strcpy(chip->p_dma.ebus_info.name, "cs4231(play)"); 1983 strcpy(chip->p_dma.ebus_info.name, "cs4231(play)");
1984 chip->p_dma.ebus_info.flags = EBUS_DMA_FLAG_USE_EBDMA_HANDLER; 1984 chip->p_dma.ebus_info.flags = EBUS_DMA_FLAG_USE_EBDMA_HANDLER;
1985 chip->p_dma.ebus_info.callback = snd_cs4231_ebus_play_callback; 1985 chip->p_dma.ebus_info.callback = snd_cs4231_ebus_play_callback;
1986 chip->p_dma.ebus_info.client_cookie = chip; 1986 chip->p_dma.ebus_info.client_cookie = chip;
1987 chip->p_dma.ebus_info.irq = op->irqs[1]; 1987 chip->p_dma.ebus_info.irq = op->archdata.irqs[1];
1988 1988
1989 chip->p_dma.prepare = _ebus_dma_prepare; 1989 chip->p_dma.prepare = _ebus_dma_prepare;
1990 chip->p_dma.enable = _ebus_dma_enable; 1990 chip->p_dma.enable = _ebus_dma_enable;
@@ -2048,7 +2048,7 @@ static int __devinit snd_cs4231_ebus_create(struct snd_card *card,
2048 return 0; 2048 return 0;
2049} 2049}
2050 2050
2051static int __devinit cs4231_ebus_probe(struct of_device *op, const struct of_device_id *match) 2051static int __devinit cs4231_ebus_probe(struct platform_device *op, const struct of_device_id *match)
2052{ 2052{
2053 struct snd_card *card; 2053 struct snd_card *card;
2054 int err; 2054 int err;
@@ -2060,7 +2060,7 @@ static int __devinit cs4231_ebus_probe(struct of_device *op, const struct of_dev
2060 sprintf(card->longname, "%s at 0x%llx, irq %d", 2060 sprintf(card->longname, "%s at 0x%llx, irq %d",
2061 card->shortname, 2061 card->shortname,
2062 op->resource[0].start, 2062 op->resource[0].start,
2063 op->irqs[0]); 2063 op->archdata.irqs[0]);
2064 2064
2065 err = snd_cs4231_ebus_create(card, op, dev); 2065 err = snd_cs4231_ebus_create(card, op, dev);
2066 if (err < 0) { 2066 if (err < 0) {
@@ -2072,7 +2072,7 @@ static int __devinit cs4231_ebus_probe(struct of_device *op, const struct of_dev
2072} 2072}
2073#endif 2073#endif
2074 2074
2075static int __devinit cs4231_probe(struct of_device *op, const struct of_device_id *match) 2075static int __devinit cs4231_probe(struct platform_device *op, const struct of_device_id *match)
2076{ 2076{
2077#ifdef EBUS_SUPPORT 2077#ifdef EBUS_SUPPORT
2078 if (!strcmp(op->dev.of_node->parent->name, "ebus")) 2078 if (!strcmp(op->dev.of_node->parent->name, "ebus"))
@@ -2086,7 +2086,7 @@ static int __devinit cs4231_probe(struct of_device *op, const struct of_device_i
2086 return -ENODEV; 2086 return -ENODEV;
2087} 2087}
2088 2088
2089static int __devexit cs4231_remove(struct of_device *op) 2089static int __devexit cs4231_remove(struct platform_device *op)
2090{ 2090{
2091 struct snd_cs4231 *chip = dev_get_drvdata(&op->dev); 2091 struct snd_cs4231 *chip = dev_get_drvdata(&op->dev);
2092 2092
@@ -2120,12 +2120,12 @@ static struct of_platform_driver cs4231_driver = {
2120 2120
2121static int __init cs4231_init(void) 2121static int __init cs4231_init(void)
2122{ 2122{
2123 return of_register_driver(&cs4231_driver, &of_bus_type); 2123 return of_register_platform_driver(&cs4231_driver);
2124} 2124}
2125 2125
2126static void __exit cs4231_exit(void) 2126static void __exit cs4231_exit(void)
2127{ 2127{
2128 of_unregister_driver(&cs4231_driver); 2128 of_unregister_platform_driver(&cs4231_driver);
2129} 2129}
2130 2130
2131module_init(cs4231_init); 2131module_init(cs4231_init);
diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c
index 1557bf132e7..39cd5d69d05 100644
--- a/sound/sparc/dbri.c
+++ b/sound/sparc/dbri.c
@@ -299,7 +299,7 @@ struct dbri_streaminfo {
299/* This structure holds the information for both chips (DBRI & CS4215) */ 299/* This structure holds the information for both chips (DBRI & CS4215) */
300struct snd_dbri { 300struct snd_dbri {
301 int regs_size, irq; /* Needed for unload */ 301 int regs_size, irq; /* Needed for unload */
302 struct of_device *op; /* OF device info */ 302 struct platform_device *op; /* OF device info */
303 spinlock_t lock; 303 spinlock_t lock;
304 304
305 struct dbri_dma *dma; /* Pointer to our DMA block */ 305 struct dbri_dma *dma; /* Pointer to our DMA block */
@@ -2523,7 +2523,7 @@ static void __devinit snd_dbri_proc(struct snd_card *card)
2523static void snd_dbri_free(struct snd_dbri *dbri); 2523static void snd_dbri_free(struct snd_dbri *dbri);
2524 2524
2525static int __devinit snd_dbri_create(struct snd_card *card, 2525static int __devinit snd_dbri_create(struct snd_card *card,
2526 struct of_device *op, 2526 struct platform_device *op,
2527 int irq, int dev) 2527 int irq, int dev)
2528{ 2528{
2529 struct snd_dbri *dbri = card->private_data; 2529 struct snd_dbri *dbri = card->private_data;
@@ -2592,7 +2592,7 @@ static void snd_dbri_free(struct snd_dbri *dbri)
2592 (void *)dbri->dma, dbri->dma_dvma); 2592 (void *)dbri->dma, dbri->dma_dvma);
2593} 2593}
2594 2594
2595static int __devinit dbri_probe(struct of_device *op, const struct of_device_id *match) 2595static int __devinit dbri_probe(struct platform_device *op, const struct of_device_id *match)
2596{ 2596{
2597 struct snd_dbri *dbri; 2597 struct snd_dbri *dbri;
2598 struct resource *rp; 2598 struct resource *rp;
@@ -2608,7 +2608,7 @@ static int __devinit dbri_probe(struct of_device *op, const struct of_device_id
2608 return -ENOENT; 2608 return -ENOENT;
2609 } 2609 }
2610 2610
2611 irq = op->irqs[0]; 2611 irq = op->archdata.irqs[0];
2612 if (irq <= 0) { 2612 if (irq <= 0) {
2613 printk(KERN_ERR "DBRI-%d: No IRQ.\n", dev); 2613 printk(KERN_ERR "DBRI-%d: No IRQ.\n", dev);
2614 return -ENODEV; 2614 return -ENODEV;
@@ -2662,7 +2662,7 @@ _err:
2662 return err; 2662 return err;
2663} 2663}
2664 2664
2665static int __devexit dbri_remove(struct of_device *op) 2665static int __devexit dbri_remove(struct platform_device *op)
2666{ 2666{
2667 struct snd_card *card = dev_get_drvdata(&op->dev); 2667 struct snd_card *card = dev_get_drvdata(&op->dev);
2668 2668
@@ -2699,12 +2699,12 @@ static struct of_platform_driver dbri_sbus_driver = {
2699/* Probe for the dbri chip and then attach the driver. */ 2699/* Probe for the dbri chip and then attach the driver. */
2700static int __init dbri_init(void) 2700static int __init dbri_init(void)
2701{ 2701{
2702 return of_register_driver(&dbri_sbus_driver, &of_bus_type); 2702 return of_register_platform_driver(&dbri_sbus_driver);
2703} 2703}
2704 2704
2705static void __exit dbri_exit(void) 2705static void __exit dbri_exit(void)
2706{ 2706{
2707 of_unregister_driver(&dbri_sbus_driver); 2707 of_unregister_platform_driver(&dbri_sbus_driver);
2708} 2708}
2709 2709
2710module_init(dbri_init); 2710module_init(dbri_init);
diff --git a/sound/synth/emux/emux_hwdep.c b/sound/synth/emux/emux_hwdep.c
index ff0b2a8fd25..5ae1eae9f6d 100644
--- a/sound/synth/emux/emux_hwdep.c
+++ b/sound/synth/emux/emux_hwdep.c
@@ -128,6 +128,9 @@ snd_emux_init_hwdep(struct snd_emux *emu)
128 strcpy(hw->name, SNDRV_EMUX_HWDEP_NAME); 128 strcpy(hw->name, SNDRV_EMUX_HWDEP_NAME);
129 hw->iface = SNDRV_HWDEP_IFACE_EMUX_WAVETABLE; 129 hw->iface = SNDRV_HWDEP_IFACE_EMUX_WAVETABLE;
130 hw->ops.ioctl = snd_emux_hwdep_ioctl; 130 hw->ops.ioctl = snd_emux_hwdep_ioctl;
131 /* The ioctl parameter types are compatible between 32- and
132 * 64-bit architectures, so use the same function. */
133 hw->ops.ioctl_compat = snd_emux_hwdep_ioctl;
131 hw->exclusive = 1; 134 hw->exclusive = 1;
132 hw->private_data = emu; 135 hw->private_data = emu;
133 if ((err = snd_card_register(emu->card)) < 0) 136 if ((err = snd_card_register(emu->card)) < 0)
diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig
index 44d6d2ec964..112984f4080 100644
--- a/sound/usb/Kconfig
+++ b/sound/usb/Kconfig
@@ -65,6 +65,7 @@ config SND_USB_CAIAQ
65 * Native Instruments Guitar Rig Session I/O 65 * Native Instruments Guitar Rig Session I/O
66 * Native Instruments Guitar Rig mobile 66 * Native Instruments Guitar Rig mobile
67 * Native Instruments Traktor Kontrol X1 67 * Native Instruments Traktor Kontrol X1
68 * Native Instruments Traktor Kontrol S4
68 69
69 To compile this driver as a module, choose M here: the module 70 To compile this driver as a module, choose M here: the module
70 will be called snd-usb-caiaq. 71 will be called snd-usb-caiaq.
@@ -82,6 +83,7 @@ config SND_USB_CAIAQ_INPUT
82 * Native Instruments Kore Controller 83 * Native Instruments Kore Controller
83 * Native Instruments Kore Controller 2 84 * Native Instruments Kore Controller 2
84 * Native Instruments Audio Kontrol 1 85 * Native Instruments Audio Kontrol 1
86 * Native Instruments Traktor Kontrol S4
85 87
86config SND_USB_US122L 88config SND_USB_US122L
87 tristate "Tascam US-122L USB driver" 89 tristate "Tascam US-122L USB driver"
diff --git a/sound/usb/caiaq/audio.c b/sound/usb/caiaq/audio.c
index 4328cad6c3a..68b97477577 100644
--- a/sound/usb/caiaq/audio.c
+++ b/sound/usb/caiaq/audio.c
@@ -111,7 +111,7 @@ static int stream_start(struct snd_usb_caiaqdev *dev)
111 memset(dev->sub_capture, 0, sizeof(dev->sub_capture)); 111 memset(dev->sub_capture, 0, sizeof(dev->sub_capture));
112 dev->input_panic = 0; 112 dev->input_panic = 0;
113 dev->output_panic = 0; 113 dev->output_panic = 0;
114 dev->first_packet = 1; 114 dev->first_packet = 4;
115 dev->streaming = 1; 115 dev->streaming = 1;
116 dev->warned = 0; 116 dev->warned = 0;
117 117
@@ -169,7 +169,7 @@ static int snd_usb_caiaq_substream_close(struct snd_pcm_substream *substream)
169} 169}
170 170
171static int snd_usb_caiaq_pcm_hw_params(struct snd_pcm_substream *sub, 171static int snd_usb_caiaq_pcm_hw_params(struct snd_pcm_substream *sub,
172 struct snd_pcm_hw_params *hw_params) 172 struct snd_pcm_hw_params *hw_params)
173{ 173{
174 debug("%s(%p)\n", __func__, sub); 174 debug("%s(%p)\n", __func__, sub);
175 return snd_pcm_lib_malloc_pages(sub, params_buffer_bytes(hw_params)); 175 return snd_pcm_lib_malloc_pages(sub, params_buffer_bytes(hw_params));
@@ -189,7 +189,7 @@ static int snd_usb_caiaq_pcm_hw_free(struct snd_pcm_substream *sub)
189#endif 189#endif
190 190
191static unsigned int rates[] = { 5512, 8000, 11025, 16000, 22050, 32000, 44100, 191static unsigned int rates[] = { 5512, 8000, 11025, 16000, 22050, 32000, 44100,
192 48000, 64000, 88200, 96000, 176400, 192000 }; 192 48000, 64000, 88200, 96000, 176400, 192000 };
193 193
194static int snd_usb_caiaq_pcm_prepare(struct snd_pcm_substream *substream) 194static int snd_usb_caiaq_pcm_prepare(struct snd_pcm_substream *substream)
195{ 195{
@@ -201,12 +201,39 @@ static int snd_usb_caiaq_pcm_prepare(struct snd_pcm_substream *substream)
201 debug("%s(%p)\n", __func__, substream); 201 debug("%s(%p)\n", __func__, substream);
202 202
203 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 203 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
204 dev->period_out_count[index] = BYTES_PER_SAMPLE + 1; 204 int out_pos;
205 dev->audio_out_buf_pos[index] = BYTES_PER_SAMPLE + 1; 205
206 switch (dev->spec.data_alignment) {
207 case 0:
208 case 2:
209 out_pos = BYTES_PER_SAMPLE + 1;
210 break;
211 case 3:
212 default:
213 out_pos = 0;
214 break;
215 }
216
217 dev->period_out_count[index] = out_pos;
218 dev->audio_out_buf_pos[index] = out_pos;
206 } else { 219 } else {
207 int in_pos = (dev->spec.data_alignment == 2) ? 0 : 2; 220 int in_pos;
208 dev->period_in_count[index] = BYTES_PER_SAMPLE + in_pos; 221
209 dev->audio_in_buf_pos[index] = BYTES_PER_SAMPLE + in_pos; 222 switch (dev->spec.data_alignment) {
223 case 0:
224 in_pos = BYTES_PER_SAMPLE + 2;
225 break;
226 case 2:
227 in_pos = BYTES_PER_SAMPLE;
228 break;
229 case 3:
230 default:
231 in_pos = 0;
232 break;
233 }
234
235 dev->period_in_count[index] = in_pos;
236 dev->audio_in_buf_pos[index] = in_pos;
210 } 237 }
211 238
212 if (dev->streaming) 239 if (dev->streaming)
@@ -221,7 +248,7 @@ static int snd_usb_caiaq_pcm_prepare(struct snd_pcm_substream *substream)
221 snd_pcm_limit_hw_rates(runtime); 248 snd_pcm_limit_hw_rates(runtime);
222 249
223 bytes_per_sample = BYTES_PER_SAMPLE; 250 bytes_per_sample = BYTES_PER_SAMPLE;
224 if (dev->spec.data_alignment == 2) 251 if (dev->spec.data_alignment >= 2)
225 bytes_per_sample++; 252 bytes_per_sample++;
226 253
227 bpp = ((runtime->rate / 8000) + CLOCK_DRIFT_TOLERANCE) 254 bpp = ((runtime->rate / 8000) + CLOCK_DRIFT_TOLERANCE)
@@ -253,6 +280,8 @@ static int snd_usb_caiaq_pcm_trigger(struct snd_pcm_substream *sub, int cmd)
253{ 280{
254 struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(sub); 281 struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(sub);
255 282
283 debug("%s(%p) cmd %d\n", __func__, sub, cmd);
284
256 switch (cmd) { 285 switch (cmd) {
257 case SNDRV_PCM_TRIGGER_START: 286 case SNDRV_PCM_TRIGGER_START:
258 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 287 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
@@ -402,6 +431,61 @@ static void read_in_urb_mode2(struct snd_usb_caiaqdev *dev,
402 } 431 }
403} 432}
404 433
434static void read_in_urb_mode3(struct snd_usb_caiaqdev *dev,
435 const struct urb *urb,
436 const struct usb_iso_packet_descriptor *iso)
437{
438 unsigned char *usb_buf = urb->transfer_buffer + iso->offset;
439 int stream, i;
440
441 /* paranoia check */
442 if (iso->actual_length % (BYTES_PER_SAMPLE_USB * CHANNELS_PER_STREAM))
443 return;
444
445 for (i = 0; i < iso->actual_length;) {
446 for (stream = 0; stream < dev->n_streams; stream++) {
447 struct snd_pcm_substream *sub = dev->sub_capture[stream];
448 char *audio_buf = NULL;
449 int c, n, sz = 0;
450
451 if (sub && !dev->input_panic) {
452 struct snd_pcm_runtime *rt = sub->runtime;
453 audio_buf = rt->dma_area;
454 sz = frames_to_bytes(rt, rt->buffer_size);
455 }
456
457 for (c = 0; c < CHANNELS_PER_STREAM; c++) {
458 /* 3 audio data bytes, followed by 1 check byte */
459 if (audio_buf) {
460 for (n = 0; n < BYTES_PER_SAMPLE; n++) {
461 audio_buf[dev->audio_in_buf_pos[stream]++] = usb_buf[i+n];
462
463 if (dev->audio_in_buf_pos[stream] == sz)
464 dev->audio_in_buf_pos[stream] = 0;
465 }
466
467 dev->period_in_count[stream] += BYTES_PER_SAMPLE;
468 }
469
470 i += BYTES_PER_SAMPLE;
471
472 if (usb_buf[i] != ((stream << 1) | c) &&
473 !dev->first_packet) {
474 if (!dev->input_panic)
475 printk(" EXPECTED: %02x got %02x, c %d, stream %d, i %d\n",
476 ((stream << 1) | c), usb_buf[i], c, stream, i);
477 dev->input_panic = 1;
478 }
479
480 i++;
481 }
482 }
483 }
484
485 if (dev->first_packet > 0)
486 dev->first_packet--;
487}
488
405static void read_in_urb(struct snd_usb_caiaqdev *dev, 489static void read_in_urb(struct snd_usb_caiaqdev *dev,
406 const struct urb *urb, 490 const struct urb *urb,
407 const struct usb_iso_packet_descriptor *iso) 491 const struct usb_iso_packet_descriptor *iso)
@@ -419,6 +503,9 @@ static void read_in_urb(struct snd_usb_caiaqdev *dev,
419 case 2: 503 case 2:
420 read_in_urb_mode2(dev, urb, iso); 504 read_in_urb_mode2(dev, urb, iso);
421 break; 505 break;
506 case 3:
507 read_in_urb_mode3(dev, urb, iso);
508 break;
422 } 509 }
423 510
424 if ((dev->input_panic || dev->output_panic) && !dev->warned) { 511 if ((dev->input_panic || dev->output_panic) && !dev->warned) {
@@ -429,9 +516,9 @@ static void read_in_urb(struct snd_usb_caiaqdev *dev,
429 } 516 }
430} 517}
431 518
432static void fill_out_urb(struct snd_usb_caiaqdev *dev, 519static void fill_out_urb_mode_0(struct snd_usb_caiaqdev *dev,
433 struct urb *urb, 520 struct urb *urb,
434 const struct usb_iso_packet_descriptor *iso) 521 const struct usb_iso_packet_descriptor *iso)
435{ 522{
436 unsigned char *usb_buf = urb->transfer_buffer + iso->offset; 523 unsigned char *usb_buf = urb->transfer_buffer + iso->offset;
437 struct snd_pcm_substream *sub; 524 struct snd_pcm_substream *sub;
@@ -457,9 +544,67 @@ static void fill_out_urb(struct snd_usb_caiaqdev *dev,
457 /* fill in the check bytes */ 544 /* fill in the check bytes */
458 if (dev->spec.data_alignment == 2 && 545 if (dev->spec.data_alignment == 2 &&
459 i % (dev->n_streams * BYTES_PER_SAMPLE_USB) == 546 i % (dev->n_streams * BYTES_PER_SAMPLE_USB) ==
460 (dev->n_streams * CHANNELS_PER_STREAM)) 547 (dev->n_streams * CHANNELS_PER_STREAM))
461 for (stream = 0; stream < dev->n_streams; stream++, i++) 548 for (stream = 0; stream < dev->n_streams; stream++, i++)
462 usb_buf[i] = MAKE_CHECKBYTE(dev, stream, i); 549 usb_buf[i] = MAKE_CHECKBYTE(dev, stream, i);
550 }
551}
552
553static void fill_out_urb_mode_3(struct snd_usb_caiaqdev *dev,
554 struct urb *urb,
555 const struct usb_iso_packet_descriptor *iso)
556{
557 unsigned char *usb_buf = urb->transfer_buffer + iso->offset;
558 int stream, i;
559
560 for (i = 0; i < iso->length;) {
561 for (stream = 0; stream < dev->n_streams; stream++) {
562 struct snd_pcm_substream *sub = dev->sub_playback[stream];
563 char *audio_buf = NULL;
564 int c, n, sz = 0;
565
566 if (sub) {
567 struct snd_pcm_runtime *rt = sub->runtime;
568 audio_buf = rt->dma_area;
569 sz = frames_to_bytes(rt, rt->buffer_size);
570 }
571
572 for (c = 0; c < CHANNELS_PER_STREAM; c++) {
573 for (n = 0; n < BYTES_PER_SAMPLE; n++) {
574 if (audio_buf) {
575 usb_buf[i+n] = audio_buf[dev->audio_out_buf_pos[stream]++];
576
577 if (dev->audio_out_buf_pos[stream] == sz)
578 dev->audio_out_buf_pos[stream] = 0;
579 } else {
580 usb_buf[i+n] = 0;
581 }
582 }
583
584 if (audio_buf)
585 dev->period_out_count[stream] += BYTES_PER_SAMPLE;
586
587 i += BYTES_PER_SAMPLE;
588
589 /* fill in the check byte pattern */
590 usb_buf[i++] = (stream << 1) | c;
591 }
592 }
593 }
594}
595
596static inline void fill_out_urb(struct snd_usb_caiaqdev *dev,
597 struct urb *urb,
598 const struct usb_iso_packet_descriptor *iso)
599{
600 switch (dev->spec.data_alignment) {
601 case 0:
602 case 2:
603 fill_out_urb_mode_0(dev, urb, iso);
604 break;
605 case 3:
606 fill_out_urb_mode_3(dev, urb, iso);
607 break;
463 } 608 }
464} 609}
465 610
diff --git a/sound/usb/caiaq/control.c b/sound/usb/caiaq/control.c
index 91c804cd278..00e5d0a469e 100644
--- a/sound/usb/caiaq/control.c
+++ b/sound/usb/caiaq/control.c
@@ -55,6 +55,10 @@ static int control_info(struct snd_kcontrol *kcontrol,
55 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): 55 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
56 maxval = 127; 56 maxval = 127;
57 break; 57 break;
58
59 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4):
60 maxval = 31;
61 break;
58 } 62 }
59 63
60 if (is_intval) { 64 if (is_intval) {
@@ -93,6 +97,7 @@ static int control_put(struct snd_kcontrol *kcontrol,
93 struct snd_usb_audio *chip = snd_kcontrol_chip(kcontrol); 97 struct snd_usb_audio *chip = snd_kcontrol_chip(kcontrol);
94 struct snd_usb_caiaqdev *dev = caiaqdev(chip->card); 98 struct snd_usb_caiaqdev *dev = caiaqdev(chip->card);
95 int pos = kcontrol->private_value; 99 int pos = kcontrol->private_value;
100 int v = ucontrol->value.integer.value[0];
96 unsigned char cmd = EP1_CMD_WRITE_IO; 101 unsigned char cmd = EP1_CMD_WRITE_IO;
97 102
98 if (dev->chip.usb_id == 103 if (dev->chip.usb_id ==
@@ -100,12 +105,27 @@ static int control_put(struct snd_kcontrol *kcontrol,
100 cmd = EP1_CMD_DIMM_LEDS; 105 cmd = EP1_CMD_DIMM_LEDS;
101 106
102 if (pos & CNT_INTVAL) { 107 if (pos & CNT_INTVAL) {
103 dev->control_state[pos & ~CNT_INTVAL] 108 int i = pos & ~CNT_INTVAL;
104 = ucontrol->value.integer.value[0]; 109
105 snd_usb_caiaq_send_command(dev, cmd, 110 dev->control_state[i] = v;
106 dev->control_state, sizeof(dev->control_state)); 111
112 if (dev->chip.usb_id ==
113 USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4)) {
114 int actual_len;
115
116 dev->ep8_out_buf[0] = i;
117 dev->ep8_out_buf[1] = v;
118
119 usb_bulk_msg(dev->chip.dev,
120 usb_sndbulkpipe(dev->chip.dev, 8),
121 dev->ep8_out_buf, sizeof(dev->ep8_out_buf),
122 &actual_len, 200);
123 } else {
124 snd_usb_caiaq_send_command(dev, cmd,
125 dev->control_state, sizeof(dev->control_state));
126 }
107 } else { 127 } else {
108 if (ucontrol->value.integer.value[0]) 128 if (v)
109 dev->control_state[pos / 8] |= 1 << (pos % 8); 129 dev->control_state[pos / 8] |= 1 << (pos % 8);
110 else 130 else
111 dev->control_state[pos / 8] &= ~(1 << (pos % 8)); 131 dev->control_state[pos / 8] &= ~(1 << (pos % 8));
@@ -296,6 +316,179 @@ static struct caiaq_controller kontrolx1_controller[] = {
296 { "LED Deck B: SYNC", 8 | CNT_INTVAL }, 316 { "LED Deck B: SYNC", 8 | CNT_INTVAL },
297}; 317};
298 318
319static struct caiaq_controller kontrols4_controller[] = {
320 { "LED: Master: Quant", 10 | CNT_INTVAL },
321 { "LED: Master: Headphone", 11 | CNT_INTVAL },
322 { "LED: Master: Master", 12 | CNT_INTVAL },
323 { "LED: Master: Snap", 14 | CNT_INTVAL },
324 { "LED: Master: Warning", 15 | CNT_INTVAL },
325 { "LED: Master: Master button", 112 | CNT_INTVAL },
326 { "LED: Master: Snap button", 113 | CNT_INTVAL },
327 { "LED: Master: Rec", 118 | CNT_INTVAL },
328 { "LED: Master: Size", 119 | CNT_INTVAL },
329 { "LED: Master: Quant button", 120 | CNT_INTVAL },
330 { "LED: Master: Browser button", 121 | CNT_INTVAL },
331 { "LED: Master: Play button", 126 | CNT_INTVAL },
332 { "LED: Master: Undo button", 127 | CNT_INTVAL },
333
334 { "LED: Channel A: >", 4 | CNT_INTVAL },
335 { "LED: Channel A: <", 5 | CNT_INTVAL },
336 { "LED: Channel A: Meter 1", 97 | CNT_INTVAL },
337 { "LED: Channel A: Meter 2", 98 | CNT_INTVAL },
338 { "LED: Channel A: Meter 3", 99 | CNT_INTVAL },
339 { "LED: Channel A: Meter 4", 100 | CNT_INTVAL },
340 { "LED: Channel A: Meter 5", 101 | CNT_INTVAL },
341 { "LED: Channel A: Meter 6", 102 | CNT_INTVAL },
342 { "LED: Channel A: Meter clip", 103 | CNT_INTVAL },
343 { "LED: Channel A: Active", 114 | CNT_INTVAL },
344 { "LED: Channel A: Cue", 116 | CNT_INTVAL },
345 { "LED: Channel A: FX1", 149 | CNT_INTVAL },
346 { "LED: Channel A: FX2", 148 | CNT_INTVAL },
347
348 { "LED: Channel B: >", 2 | CNT_INTVAL },
349 { "LED: Channel B: <", 3 | CNT_INTVAL },
350 { "LED: Channel B: Meter 1", 89 | CNT_INTVAL },
351 { "LED: Channel B: Meter 2", 90 | CNT_INTVAL },
352 { "LED: Channel B: Meter 3", 91 | CNT_INTVAL },
353 { "LED: Channel B: Meter 4", 92 | CNT_INTVAL },
354 { "LED: Channel B: Meter 5", 93 | CNT_INTVAL },
355 { "LED: Channel B: Meter 6", 94 | CNT_INTVAL },
356 { "LED: Channel B: Meter clip", 95 | CNT_INTVAL },
357 { "LED: Channel B: Active", 122 | CNT_INTVAL },
358 { "LED: Channel B: Cue", 125 | CNT_INTVAL },
359 { "LED: Channel B: FX1", 147 | CNT_INTVAL },
360 { "LED: Channel B: FX2", 146 | CNT_INTVAL },
361
362 { "LED: Channel C: >", 6 | CNT_INTVAL },
363 { "LED: Channel C: <", 7 | CNT_INTVAL },
364 { "LED: Channel C: Meter 1", 105 | CNT_INTVAL },
365 { "LED: Channel C: Meter 2", 106 | CNT_INTVAL },
366 { "LED: Channel C: Meter 3", 107 | CNT_INTVAL },
367 { "LED: Channel C: Meter 4", 108 | CNT_INTVAL },
368 { "LED: Channel C: Meter 5", 109 | CNT_INTVAL },
369 { "LED: Channel C: Meter 6", 110 | CNT_INTVAL },
370 { "LED: Channel C: Meter clip", 111 | CNT_INTVAL },
371 { "LED: Channel C: Active", 115 | CNT_INTVAL },
372 { "LED: Channel C: Cue", 117 | CNT_INTVAL },
373 { "LED: Channel C: FX1", 151 | CNT_INTVAL },
374 { "LED: Channel C: FX2", 150 | CNT_INTVAL },
375
376 { "LED: Channel D: >", 0 | CNT_INTVAL },
377 { "LED: Channel D: <", 1 | CNT_INTVAL },
378 { "LED: Channel D: Meter 1", 81 | CNT_INTVAL },
379 { "LED: Channel D: Meter 2", 82 | CNT_INTVAL },
380 { "LED: Channel D: Meter 3", 83 | CNT_INTVAL },
381 { "LED: Channel D: Meter 4", 84 | CNT_INTVAL },
382 { "LED: Channel D: Meter 5", 85 | CNT_INTVAL },
383 { "LED: Channel D: Meter 6", 86 | CNT_INTVAL },
384 { "LED: Channel D: Meter clip", 87 | CNT_INTVAL },
385 { "LED: Channel D: Active", 123 | CNT_INTVAL },
386 { "LED: Channel D: Cue", 124 | CNT_INTVAL },
387 { "LED: Channel D: FX1", 145 | CNT_INTVAL },
388 { "LED: Channel D: FX2", 144 | CNT_INTVAL },
389
390 { "LED: Deck A: 1 (blue)", 22 | CNT_INTVAL },
391 { "LED: Deck A: 1 (green)", 23 | CNT_INTVAL },
392 { "LED: Deck A: 2 (blue)", 20 | CNT_INTVAL },
393 { "LED: Deck A: 2 (green)", 21 | CNT_INTVAL },
394 { "LED: Deck A: 3 (blue)", 18 | CNT_INTVAL },
395 { "LED: Deck A: 3 (green)", 19 | CNT_INTVAL },
396 { "LED: Deck A: 4 (blue)", 16 | CNT_INTVAL },
397 { "LED: Deck A: 4 (green)", 17 | CNT_INTVAL },
398 { "LED: Deck A: Load", 44 | CNT_INTVAL },
399 { "LED: Deck A: Deck C button", 45 | CNT_INTVAL },
400 { "LED: Deck A: In", 47 | CNT_INTVAL },
401 { "LED: Deck A: Out", 46 | CNT_INTVAL },
402 { "LED: Deck A: Shift", 24 | CNT_INTVAL },
403 { "LED: Deck A: Sync", 27 | CNT_INTVAL },
404 { "LED: Deck A: Cue", 26 | CNT_INTVAL },
405 { "LED: Deck A: Play", 25 | CNT_INTVAL },
406 { "LED: Deck A: Tempo up", 33 | CNT_INTVAL },
407 { "LED: Deck A: Tempo down", 32 | CNT_INTVAL },
408 { "LED: Deck A: Master", 34 | CNT_INTVAL },
409 { "LED: Deck A: Keylock", 35 | CNT_INTVAL },
410 { "LED: Deck A: Deck A", 37 | CNT_INTVAL },
411 { "LED: Deck A: Deck C", 36 | CNT_INTVAL },
412 { "LED: Deck A: Samples", 38 | CNT_INTVAL },
413 { "LED: Deck A: On Air", 39 | CNT_INTVAL },
414 { "LED: Deck A: Sample 1", 31 | CNT_INTVAL },
415 { "LED: Deck A: Sample 2", 30 | CNT_INTVAL },
416 { "LED: Deck A: Sample 3", 29 | CNT_INTVAL },
417 { "LED: Deck A: Sample 4", 28 | CNT_INTVAL },
418 { "LED: Deck A: Digit 1 - A", 55 | CNT_INTVAL },
419 { "LED: Deck A: Digit 1 - B", 54 | CNT_INTVAL },
420 { "LED: Deck A: Digit 1 - C", 53 | CNT_INTVAL },
421 { "LED: Deck A: Digit 1 - D", 52 | CNT_INTVAL },
422 { "LED: Deck A: Digit 1 - E", 51 | CNT_INTVAL },
423 { "LED: Deck A: Digit 1 - F", 50 | CNT_INTVAL },
424 { "LED: Deck A: Digit 1 - G", 49 | CNT_INTVAL },
425 { "LED: Deck A: Digit 1 - dot", 48 | CNT_INTVAL },
426 { "LED: Deck A: Digit 2 - A", 63 | CNT_INTVAL },
427 { "LED: Deck A: Digit 2 - B", 62 | CNT_INTVAL },
428 { "LED: Deck A: Digit 2 - C", 61 | CNT_INTVAL },
429 { "LED: Deck A: Digit 2 - D", 60 | CNT_INTVAL },
430 { "LED: Deck A: Digit 2 - E", 59 | CNT_INTVAL },
431 { "LED: Deck A: Digit 2 - F", 58 | CNT_INTVAL },
432 { "LED: Deck A: Digit 2 - G", 57 | CNT_INTVAL },
433 { "LED: Deck A: Digit 2 - dot", 56 | CNT_INTVAL },
434
435 { "LED: Deck B: 1 (blue)", 78 | CNT_INTVAL },
436 { "LED: Deck B: 1 (green)", 79 | CNT_INTVAL },
437 { "LED: Deck B: 2 (blue)", 76 | CNT_INTVAL },
438 { "LED: Deck B: 2 (green)", 77 | CNT_INTVAL },
439 { "LED: Deck B: 3 (blue)", 74 | CNT_INTVAL },
440 { "LED: Deck B: 3 (green)", 75 | CNT_INTVAL },
441 { "LED: Deck B: 4 (blue)", 72 | CNT_INTVAL },
442 { "LED: Deck B: 4 (green)", 73 | CNT_INTVAL },
443 { "LED: Deck B: Load", 180 | CNT_INTVAL },
444 { "LED: Deck B: Deck D button", 181 | CNT_INTVAL },
445 { "LED: Deck B: In", 183 | CNT_INTVAL },
446 { "LED: Deck B: Out", 182 | CNT_INTVAL },
447 { "LED: Deck B: Shift", 64 | CNT_INTVAL },
448 { "LED: Deck B: Sync", 67 | CNT_INTVAL },
449 { "LED: Deck B: Cue", 66 | CNT_INTVAL },
450 { "LED: Deck B: Play", 65 | CNT_INTVAL },
451 { "LED: Deck B: Tempo up", 185 | CNT_INTVAL },
452 { "LED: Deck B: Tempo down", 184 | CNT_INTVAL },
453 { "LED: Deck B: Master", 186 | CNT_INTVAL },
454 { "LED: Deck B: Keylock", 187 | CNT_INTVAL },
455 { "LED: Deck B: Deck B", 189 | CNT_INTVAL },
456 { "LED: Deck B: Deck D", 188 | CNT_INTVAL },
457 { "LED: Deck B: Samples", 190 | CNT_INTVAL },
458 { "LED: Deck B: On Air", 191 | CNT_INTVAL },
459 { "LED: Deck B: Sample 1", 71 | CNT_INTVAL },
460 { "LED: Deck B: Sample 2", 70 | CNT_INTVAL },
461 { "LED: Deck B: Sample 3", 69 | CNT_INTVAL },
462 { "LED: Deck B: Sample 4", 68 | CNT_INTVAL },
463 { "LED: Deck B: Digit 1 - A", 175 | CNT_INTVAL },
464 { "LED: Deck B: Digit 1 - B", 174 | CNT_INTVAL },
465 { "LED: Deck B: Digit 1 - C", 173 | CNT_INTVAL },
466 { "LED: Deck B: Digit 1 - D", 172 | CNT_INTVAL },
467 { "LED: Deck B: Digit 1 - E", 171 | CNT_INTVAL },
468 { "LED: Deck B: Digit 1 - F", 170 | CNT_INTVAL },
469 { "LED: Deck B: Digit 1 - G", 169 | CNT_INTVAL },
470 { "LED: Deck B: Digit 1 - dot", 168 | CNT_INTVAL },
471 { "LED: Deck B: Digit 2 - A", 167 | CNT_INTVAL },
472 { "LED: Deck B: Digit 2 - B", 166 | CNT_INTVAL },
473 { "LED: Deck B: Digit 2 - C", 165 | CNT_INTVAL },
474 { "LED: Deck B: Digit 2 - D", 164 | CNT_INTVAL },
475 { "LED: Deck B: Digit 2 - E", 163 | CNT_INTVAL },
476 { "LED: Deck B: Digit 2 - F", 162 | CNT_INTVAL },
477 { "LED: Deck B: Digit 2 - G", 161 | CNT_INTVAL },
478 { "LED: Deck B: Digit 2 - dot", 160 | CNT_INTVAL },
479
480 { "LED: FX1: dry/wet", 153 | CNT_INTVAL },
481 { "LED: FX1: 1", 154 | CNT_INTVAL },
482 { "LED: FX1: 2", 155 | CNT_INTVAL },
483 { "LED: FX1: 3", 156 | CNT_INTVAL },
484 { "LED: FX1: Mode", 157 | CNT_INTVAL },
485 { "LED: FX2: dry/wet", 129 | CNT_INTVAL },
486 { "LED: FX2: 1", 130 | CNT_INTVAL },
487 { "LED: FX2: 2", 131 | CNT_INTVAL },
488 { "LED: FX2: 3", 132 | CNT_INTVAL },
489 { "LED: FX2: Mode", 133 | CNT_INTVAL },
490};
491
299static int __devinit add_controls(struct caiaq_controller *c, int num, 492static int __devinit add_controls(struct caiaq_controller *c, int num,
300 struct snd_usb_caiaqdev *dev) 493 struct snd_usb_caiaqdev *dev)
301{ 494{
@@ -354,6 +547,11 @@ int __devinit snd_usb_caiaq_control_init(struct snd_usb_caiaqdev *dev)
354 ret = add_controls(kontrolx1_controller, 547 ret = add_controls(kontrolx1_controller,
355 ARRAY_SIZE(kontrolx1_controller), dev); 548 ARRAY_SIZE(kontrolx1_controller), dev);
356 break; 549 break;
550
551 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4):
552 ret = add_controls(kontrols4_controller,
553 ARRAY_SIZE(kontrols4_controller), dev);
554 break;
357 } 555 }
358 556
359 return ret; 557 return ret;
diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c
index cdfb856bddd..6480c3283c0 100644
--- a/sound/usb/caiaq/device.c
+++ b/sound/usb/caiaq/device.c
@@ -36,7 +36,7 @@
36#include "input.h" 36#include "input.h"
37 37
38MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>"); 38MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
39MODULE_DESCRIPTION("caiaq USB audio, version 1.3.21"); 39MODULE_DESCRIPTION("caiaq USB audio");
40MODULE_LICENSE("GPL"); 40MODULE_LICENSE("GPL");
41MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2}," 41MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2},"
42 "{Native Instruments, RigKontrol3}," 42 "{Native Instruments, RigKontrol3},"
@@ -48,7 +48,8 @@ MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2},"
48 "{Native Instruments, Audio 8 DJ}," 48 "{Native Instruments, Audio 8 DJ},"
49 "{Native Instruments, Session I/O}," 49 "{Native Instruments, Session I/O},"
50 "{Native Instruments, GuitarRig mobile}" 50 "{Native Instruments, GuitarRig mobile}"
51 "{Native Instruments, Traktor Kontrol X1}"); 51 "{Native Instruments, Traktor Kontrol X1}"
52 "{Native Instruments, Traktor Kontrol S4}");
52 53
53static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */ 54static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */
54static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */ 55static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */
@@ -134,6 +135,11 @@ static struct usb_device_id snd_usb_id_table[] = {
134 .idVendor = USB_VID_NATIVEINSTRUMENTS, 135 .idVendor = USB_VID_NATIVEINSTRUMENTS,
135 .idProduct = USB_PID_TRAKTORKONTROLX1 136 .idProduct = USB_PID_TRAKTORKONTROLX1
136 }, 137 },
138 {
139 .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
140 .idVendor = USB_VID_NATIVEINSTRUMENTS,
141 .idProduct = USB_PID_TRAKTORKONTROLS4
142 },
137 { /* terminator */ } 143 { /* terminator */ }
138}; 144};
139 145
diff --git a/sound/usb/caiaq/device.h b/sound/usb/caiaq/device.h
index f1117ecc84f..e3d8a3efb35 100644
--- a/sound/usb/caiaq/device.h
+++ b/sound/usb/caiaq/device.h
@@ -16,6 +16,7 @@
16#define USB_PID_SESSIONIO 0x1915 16#define USB_PID_SESSIONIO 0x1915
17#define USB_PID_GUITARRIGMOBILE 0x0d8d 17#define USB_PID_GUITARRIGMOBILE 0x0d8d
18#define USB_PID_TRAKTORKONTROLX1 0x2305 18#define USB_PID_TRAKTORKONTROLX1 0x2305
19#define USB_PID_TRAKTORKONTROLS4 0xbaff
19 20
20#define EP1_BUFSIZE 64 21#define EP1_BUFSIZE 64
21#define EP4_BUFSIZE 512 22#define EP4_BUFSIZE 512
@@ -99,13 +100,14 @@ struct snd_usb_caiaqdev {
99 struct snd_pcm_substream *sub_capture[MAX_STREAMS]; 100 struct snd_pcm_substream *sub_capture[MAX_STREAMS];
100 101
101 /* Controls */ 102 /* Controls */
102 unsigned char control_state[64]; 103 unsigned char control_state[256];
104 unsigned char ep8_out_buf[2];
103 105
104 /* Linux input */ 106 /* Linux input */
105#ifdef CONFIG_SND_USB_CAIAQ_INPUT 107#ifdef CONFIG_SND_USB_CAIAQ_INPUT
106 struct input_dev *input_dev; 108 struct input_dev *input_dev;
107 char phys[64]; /* physical device path */ 109 char phys[64]; /* physical device path */
108 unsigned short keycode[64]; 110 unsigned short keycode[128];
109 struct urb *ep4_in_urb; 111 struct urb *ep4_in_urb;
110 unsigned char ep4_in_buf[EP4_BUFSIZE]; 112 unsigned char ep4_in_buf[EP4_BUFSIZE];
111#endif 113#endif
diff --git a/sound/usb/caiaq/input.c b/sound/usb/caiaq/input.c
index dcb620796d9..4432ef7a70a 100644
--- a/sound/usb/caiaq/input.c
+++ b/sound/usb/caiaq/input.c
@@ -67,7 +67,12 @@ static unsigned short keycode_kore[] = {
67 KEY_BRL_DOT5 67 KEY_BRL_DOT5
68}; 68};
69 69
70#define KONTROLX1_INPUTS 40 70#define KONTROLX1_INPUTS (40)
71#define KONTROLS4_BUTTONS (12 * 8)
72#define KONTROLS4_AXIS (46)
73
74#define KONTROLS4_BUTTON(X) ((X) + BTN_MISC)
75#define KONTROLS4_ABS(X) ((X) + ABS_HAT0X)
71 76
72#define DEG90 (range / 2) 77#define DEG90 (range / 2)
73#define DEG180 (range) 78#define DEG180 (range)
@@ -139,6 +144,13 @@ static unsigned int decode_erp(unsigned char a, unsigned char b)
139#undef HIGH_PEAK 144#undef HIGH_PEAK
140#undef LOW_PEAK 145#undef LOW_PEAK
141 146
147static inline void snd_caiaq_input_report_abs(struct snd_usb_caiaqdev *dev,
148 int axis, const unsigned char *buf,
149 int offset)
150{
151 input_report_abs(dev->input_dev, axis,
152 (buf[offset * 2] << 8) | buf[offset * 2 + 1]);
153}
142 154
143static void snd_caiaq_input_read_analog(struct snd_usb_caiaqdev *dev, 155static void snd_caiaq_input_read_analog(struct snd_usb_caiaqdev *dev,
144 const unsigned char *buf, 156 const unsigned char *buf,
@@ -148,36 +160,30 @@ static void snd_caiaq_input_read_analog(struct snd_usb_caiaqdev *dev,
148 160
149 switch (dev->chip.usb_id) { 161 switch (dev->chip.usb_id) {
150 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2): 162 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2):
151 input_report_abs(input_dev, ABS_X, (buf[4] << 8) | buf[5]); 163 snd_caiaq_input_report_abs(dev, ABS_X, buf, 2);
152 input_report_abs(input_dev, ABS_Y, (buf[0] << 8) | buf[1]); 164 snd_caiaq_input_report_abs(dev, ABS_Y, buf, 0);
153 input_report_abs(input_dev, ABS_Z, (buf[2] << 8) | buf[3]); 165 snd_caiaq_input_report_abs(dev, ABS_Z, buf, 1);
154 input_sync(input_dev);
155 break; 166 break;
156 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3): 167 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3):
157 input_report_abs(input_dev, ABS_X, (buf[0] << 8) | buf[1]);
158 input_report_abs(input_dev, ABS_Y, (buf[2] << 8) | buf[3]);
159 input_report_abs(input_dev, ABS_Z, (buf[4] << 8) | buf[5]);
160 input_sync(input_dev);
161 break;
162 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER): 168 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER):
163 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2): 169 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2):
164 input_report_abs(input_dev, ABS_X, (buf[0] << 8) | buf[1]); 170 snd_caiaq_input_report_abs(dev, ABS_X, buf, 0);
165 input_report_abs(input_dev, ABS_Y, (buf[2] << 8) | buf[3]); 171 snd_caiaq_input_report_abs(dev, ABS_Y, buf, 1);
166 input_report_abs(input_dev, ABS_Z, (buf[4] << 8) | buf[5]); 172 snd_caiaq_input_report_abs(dev, ABS_Z, buf, 2);
167 input_sync(input_dev);
168 break; 173 break;
169 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): 174 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
170 input_report_abs(input_dev, ABS_HAT0X, (buf[8] << 8) | buf[9]); 175 snd_caiaq_input_report_abs(dev, ABS_HAT0X, buf, 4);
171 input_report_abs(input_dev, ABS_HAT0Y, (buf[4] << 8) | buf[5]); 176 snd_caiaq_input_report_abs(dev, ABS_HAT0Y, buf, 2);
172 input_report_abs(input_dev, ABS_HAT1X, (buf[12] << 8) | buf[13]); 177 snd_caiaq_input_report_abs(dev, ABS_HAT1X, buf, 6);
173 input_report_abs(input_dev, ABS_HAT1Y, (buf[2] << 8) | buf[3]); 178 snd_caiaq_input_report_abs(dev, ABS_HAT1Y, buf, 1);
174 input_report_abs(input_dev, ABS_HAT2X, (buf[14] << 8) | buf[15]); 179 snd_caiaq_input_report_abs(dev, ABS_HAT2X, buf, 7);
175 input_report_abs(input_dev, ABS_HAT2Y, (buf[0] << 8) | buf[1]); 180 snd_caiaq_input_report_abs(dev, ABS_HAT2Y, buf, 0);
176 input_report_abs(input_dev, ABS_HAT3X, (buf[10] << 8) | buf[11]); 181 snd_caiaq_input_report_abs(dev, ABS_HAT3X, buf, 5);
177 input_report_abs(input_dev, ABS_HAT3Y, (buf[6] << 8) | buf[7]); 182 snd_caiaq_input_report_abs(dev, ABS_HAT3Y, buf, 3);
178 input_sync(input_dev);
179 break; 183 break;
180 } 184 }
185
186 input_sync(input_dev);
181} 187}
182 188
183static void snd_caiaq_input_read_erp(struct snd_usb_caiaqdev *dev, 189static void snd_caiaq_input_read_erp(struct snd_usb_caiaqdev *dev,
@@ -250,6 +256,150 @@ static void snd_caiaq_input_read_io(struct snd_usb_caiaqdev *dev,
250 input_sync(input_dev); 256 input_sync(input_dev);
251} 257}
252 258
259#define TKS4_MSGBLOCK_SIZE 16
260
261static void snd_usb_caiaq_tks4_dispatch(struct snd_usb_caiaqdev *dev,
262 const unsigned char *buf,
263 unsigned int len)
264{
265 while (len) {
266 unsigned int i, block_id = (buf[0] << 8) | buf[1];
267
268 switch (block_id) {
269 case 0:
270 /* buttons */
271 for (i = 0; i < KONTROLS4_BUTTONS; i++)
272 input_report_key(dev->input_dev, KONTROLS4_BUTTON(i),
273 (buf[4 + (i / 8)] >> (i % 8)) & 1);
274 break;
275
276 case 1:
277 /* left wheel */
278 input_report_abs(dev->input_dev, KONTROLS4_ABS(36), buf[9] | ((buf[8] & 0x3) << 8));
279 /* right wheel */
280 input_report_abs(dev->input_dev, KONTROLS4_ABS(37), buf[13] | ((buf[12] & 0x3) << 8));
281
282 /* rotary encoders */
283 input_report_abs(dev->input_dev, KONTROLS4_ABS(38), buf[3] & 0xf);
284 input_report_abs(dev->input_dev, KONTROLS4_ABS(39), buf[4] >> 4);
285 input_report_abs(dev->input_dev, KONTROLS4_ABS(40), buf[4] & 0xf);
286 input_report_abs(dev->input_dev, KONTROLS4_ABS(41), buf[5] >> 4);
287 input_report_abs(dev->input_dev, KONTROLS4_ABS(42), buf[5] & 0xf);
288 input_report_abs(dev->input_dev, KONTROLS4_ABS(43), buf[6] >> 4);
289 input_report_abs(dev->input_dev, KONTROLS4_ABS(44), buf[6] & 0xf);
290 input_report_abs(dev->input_dev, KONTROLS4_ABS(45), buf[7] >> 4);
291 input_report_abs(dev->input_dev, KONTROLS4_ABS(46), buf[7] & 0xf);
292
293 break;
294 case 2:
295 /* Volume Fader Channel D */
296 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(0), buf, 1);
297 /* Volume Fader Channel B */
298 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(1), buf, 2);
299 /* Volume Fader Channel A */
300 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(2), buf, 3);
301 /* Volume Fader Channel C */
302 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(3), buf, 4);
303 /* Loop Volume */
304 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(4), buf, 6);
305 /* Crossfader */
306 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(7), buf, 7);
307
308 break;
309
310 case 3:
311 /* Tempo Fader R */
312 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(6), buf, 3);
313 /* Tempo Fader L */
314 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(5), buf, 4);
315 /* Mic Volume */
316 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(8), buf, 6);
317 /* Cue Mix */
318 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(9), buf, 7);
319
320 break;
321
322 case 4:
323 /* Wheel distance sensor L */
324 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(10), buf, 1);
325 /* Wheel distance sensor R */
326 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(11), buf, 2);
327 /* Channel D EQ - Filter */
328 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(12), buf, 3);
329 /* Channel D EQ - Low */
330 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(13), buf, 4);
331 /* Channel D EQ - Mid */
332 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(14), buf, 5);
333 /* Channel D EQ - Hi */
334 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(15), buf, 6);
335 /* FX2 - dry/wet */
336 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(16), buf, 7);
337
338 break;
339
340 case 5:
341 /* FX2 - 1 */
342 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(17), buf, 1);
343 /* FX2 - 2 */
344 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(18), buf, 2);
345 /* FX2 - 3 */
346 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(19), buf, 3);
347 /* Channel B EQ - Filter */
348 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(20), buf, 4);
349 /* Channel B EQ - Low */
350 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(21), buf, 5);
351 /* Channel B EQ - Mid */
352 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(22), buf, 6);
353 /* Channel B EQ - Hi */
354 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(23), buf, 7);
355
356 break;
357
358 case 6:
359 /* Channel A EQ - Filter */
360 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(24), buf, 1);
361 /* Channel A EQ - Low */
362 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(25), buf, 2);
363 /* Channel A EQ - Mid */
364 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(26), buf, 3);
365 /* Channel A EQ - Hi */
366 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(27), buf, 4);
367 /* Channel C EQ - Filter */
368 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(28), buf, 5);
369 /* Channel C EQ - Low */
370 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(29), buf, 6);
371 /* Channel C EQ - Mid */
372 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(30), buf, 7);
373
374 break;
375
376 case 7:
377 /* Channel C EQ - Hi */
378 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(31), buf, 1);
379 /* FX1 - wet/dry */
380 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(32), buf, 2);
381 /* FX1 - 1 */
382 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(33), buf, 3);
383 /* FX1 - 2 */
384 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(34), buf, 4);
385 /* FX1 - 3 */
386 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(35), buf, 5);
387
388 break;
389
390 default:
391 debug("%s(): bogus block (id %d)\n",
392 __func__, block_id);
393 return;
394 }
395
396 len -= TKS4_MSGBLOCK_SIZE;
397 buf += TKS4_MSGBLOCK_SIZE;
398 }
399
400 input_sync(dev->input_dev);
401}
402
253static void snd_usb_caiaq_ep4_reply_dispatch(struct urb *urb) 403static void snd_usb_caiaq_ep4_reply_dispatch(struct urb *urb)
254{ 404{
255 struct snd_usb_caiaqdev *dev = urb->context; 405 struct snd_usb_caiaqdev *dev = urb->context;
@@ -259,11 +409,11 @@ static void snd_usb_caiaq_ep4_reply_dispatch(struct urb *urb)
259 if (urb->status || !dev || urb != dev->ep4_in_urb) 409 if (urb->status || !dev || urb != dev->ep4_in_urb)
260 return; 410 return;
261 411
262 if (urb->actual_length < 24)
263 goto requeue;
264
265 switch (dev->chip.usb_id) { 412 switch (dev->chip.usb_id) {
266 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): 413 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
414 if (urb->actual_length < 24)
415 goto requeue;
416
267 if (buf[0] & 0x3) 417 if (buf[0] & 0x3)
268 snd_caiaq_input_read_io(dev, buf + 1, 7); 418 snd_caiaq_input_read_io(dev, buf + 1, 7);
269 419
@@ -271,6 +421,10 @@ static void snd_usb_caiaq_ep4_reply_dispatch(struct urb *urb)
271 snd_caiaq_input_read_analog(dev, buf + 8, 16); 421 snd_caiaq_input_read_analog(dev, buf + 8, 16);
272 422
273 break; 423 break;
424
425 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4):
426 snd_usb_caiaq_tks4_dispatch(dev, buf, urb->actual_length);
427 break;
274 } 428 }
275 429
276requeue: 430requeue:
@@ -289,6 +443,7 @@ static int snd_usb_caiaq_input_open(struct input_dev *idev)
289 443
290 switch (dev->chip.usb_id) { 444 switch (dev->chip.usb_id) {
291 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): 445 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
446 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4):
292 if (usb_submit_urb(dev->ep4_in_urb, GFP_KERNEL) != 0) 447 if (usb_submit_urb(dev->ep4_in_urb, GFP_KERNEL) != 0)
293 return -EIO; 448 return -EIO;
294 break; 449 break;
@@ -306,6 +461,7 @@ static void snd_usb_caiaq_input_close(struct input_dev *idev)
306 461
307 switch (dev->chip.usb_id) { 462 switch (dev->chip.usb_id) {
308 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): 463 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
464 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4):
309 usb_kill_urb(dev->ep4_in_urb); 465 usb_kill_urb(dev->ep4_in_urb);
310 break; 466 break;
311 } 467 }
@@ -456,6 +612,46 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev)
456 snd_usb_caiaq_set_auto_msg(dev, 1, 10, 5); 612 snd_usb_caiaq_set_auto_msg(dev, 1, 10, 5);
457 613
458 break; 614 break;
615
616 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4):
617 input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
618 BUILD_BUG_ON(sizeof(dev->keycode) < KONTROLS4_BUTTONS);
619 for (i = 0; i < KONTROLS4_BUTTONS; i++)
620 dev->keycode[i] = KONTROLS4_BUTTON(i);
621 input->keycodemax = KONTROLS4_BUTTONS;
622
623 for (i = 0; i < KONTROLS4_AXIS; i++) {
624 int axis = KONTROLS4_ABS(i);
625 input->absbit[BIT_WORD(axis)] |= BIT_MASK(axis);
626 }
627
628 /* 36 analog potentiometers and faders */
629 for (i = 0; i < 36; i++)
630 input_set_abs_params(input, KONTROLS4_ABS(i), 0, 0xfff, 0, 10);
631
632 /* 2 encoder wheels */
633 input_set_abs_params(input, KONTROLS4_ABS(36), 0, 0x3ff, 0, 1);
634 input_set_abs_params(input, KONTROLS4_ABS(37), 0, 0x3ff, 0, 1);
635
636 /* 9 rotary encoders */
637 for (i = 0; i < 9; i++)
638 input_set_abs_params(input, KONTROLS4_ABS(38+i), 0, 0xf, 0, 1);
639
640 dev->ep4_in_urb = usb_alloc_urb(0, GFP_KERNEL);
641 if (!dev->ep4_in_urb) {
642 ret = -ENOMEM;
643 goto exit_free_idev;
644 }
645
646 usb_fill_bulk_urb(dev->ep4_in_urb, usb_dev,
647 usb_rcvbulkpipe(usb_dev, 0x4),
648 dev->ep4_in_buf, EP4_BUFSIZE,
649 snd_usb_caiaq_ep4_reply_dispatch, dev);
650
651 snd_usb_caiaq_set_auto_msg(dev, 1, 10, 5);
652
653 break;
654
459 default: 655 default:
460 /* no input methods supported on this device */ 656 /* no input methods supported on this device */
461 goto exit_free_idev; 657 goto exit_free_idev;
diff --git a/sound/usb/card.c b/sound/usb/card.c
index 7a8ac1d81be..800f7cb4f25 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -126,7 +126,7 @@ static void snd_usb_stream_disconnect(struct list_head *head)
126 for (idx = 0; idx < 2; idx++) { 126 for (idx = 0; idx < 2; idx++) {
127 subs = &as->substream[idx]; 127 subs = &as->substream[idx];
128 if (!subs->num_formats) 128 if (!subs->num_formats)
129 return; 129 continue;
130 snd_usb_release_substream_urbs(subs, 1); 130 snd_usb_release_substream_urbs(subs, 1);
131 subs->interface = -1; 131 subs->interface = -1;
132 } 132 }
@@ -216,8 +216,13 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
216 } 216 }
217 217
218 switch (protocol) { 218 switch (protocol) {
219 default:
220 snd_printdd(KERN_WARNING "unknown interface protocol %#02x, assuming v1\n",
221 protocol);
222 /* fall through */
223
219 case UAC_VERSION_1: { 224 case UAC_VERSION_1: {
220 struct uac_ac_header_descriptor_v1 *h1 = control_header; 225 struct uac1_ac_header_descriptor *h1 = control_header;
221 226
222 if (!h1->bInCollection) { 227 if (!h1->bInCollection) {
223 snd_printk(KERN_INFO "skipping empty audio interface (v1)\n"); 228 snd_printk(KERN_INFO "skipping empty audio interface (v1)\n");
@@ -253,10 +258,6 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
253 258
254 break; 259 break;
255 } 260 }
256
257 default:
258 snd_printk(KERN_ERR "unknown protocol version 0x%02x\n", protocol);
259 return -EINVAL;
260 } 261 }
261 262
262 return 0; 263 return 0;
@@ -299,9 +300,13 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx,
299 300
300 *rchip = NULL; 301 *rchip = NULL;
301 302
302 if (snd_usb_get_speed(dev) != USB_SPEED_LOW && 303 switch (snd_usb_get_speed(dev)) {
303 snd_usb_get_speed(dev) != USB_SPEED_FULL && 304 case USB_SPEED_LOW:
304 snd_usb_get_speed(dev) != USB_SPEED_HIGH) { 305 case USB_SPEED_FULL:
306 case USB_SPEED_HIGH:
307 case USB_SPEED_SUPER:
308 break;
309 default:
305 snd_printk(KERN_ERR "unknown device speed %d\n", snd_usb_get_speed(dev)); 310 snd_printk(KERN_ERR "unknown device speed %d\n", snd_usb_get_speed(dev));
306 return -ENXIO; 311 return -ENXIO;
307 } 312 }
@@ -377,11 +382,22 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx,
377 if (len < sizeof(card->longname)) 382 if (len < sizeof(card->longname))
378 usb_make_path(dev, card->longname + len, sizeof(card->longname) - len); 383 usb_make_path(dev, card->longname + len, sizeof(card->longname) - len);
379 384
380 strlcat(card->longname, 385 switch (snd_usb_get_speed(dev)) {
381 snd_usb_get_speed(dev) == USB_SPEED_LOW ? ", low speed" : 386 case USB_SPEED_LOW:
382 snd_usb_get_speed(dev) == USB_SPEED_FULL ? ", full speed" : 387 strlcat(card->longname, ", low speed", sizeof(card->longname));
383 ", high speed", 388 break;
384 sizeof(card->longname)); 389 case USB_SPEED_FULL:
390 strlcat(card->longname, ", full speed", sizeof(card->longname));
391 break;
392 case USB_SPEED_HIGH:
393 strlcat(card->longname, ", high speed", sizeof(card->longname));
394 break;
395 case USB_SPEED_SUPER:
396 strlcat(card->longname, ", super speed", sizeof(card->longname));
397 break;
398 default:
399 break;
400 }
385 401
386 snd_usb_audio_create_proc(chip); 402 snd_usb_audio_create_proc(chip);
387 403
@@ -465,7 +481,13 @@ static void *snd_usb_audio_probe(struct usb_device *dev,
465 goto __error; 481 goto __error;
466 } 482 }
467 483
468 chip->ctrl_intf = alts; 484 /*
485 * For devices with more than one control interface, we assume the
486 * first contains the audio controls. We might need a more specific
487 * check here in the future.
488 */
489 if (!chip->ctrl_intf)
490 chip->ctrl_intf = alts;
469 491
470 if (err > 0) { 492 if (err > 0) {
471 /* create normal USB audio interfaces */ 493 /* create normal USB audio interfaces */
diff --git a/sound/usb/clock.c b/sound/usb/clock.c
index b5855114667..7754a103454 100644
--- a/sound/usb/clock.c
+++ b/sound/usb/clock.c
@@ -19,33 +19,19 @@
19 19
20#include <linux/bitops.h> 20#include <linux/bitops.h>
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/list.h>
23#include <linux/slab.h>
24#include <linux/string.h> 22#include <linux/string.h>
25#include <linux/usb.h> 23#include <linux/usb.h>
26#include <linux/moduleparam.h>
27#include <linux/mutex.h>
28#include <linux/usb/audio.h> 24#include <linux/usb/audio.h>
29#include <linux/usb/audio-v2.h> 25#include <linux/usb/audio-v2.h>
30 26
31#include <sound/core.h> 27#include <sound/core.h>
32#include <sound/info.h> 28#include <sound/info.h>
33#include <sound/pcm.h> 29#include <sound/pcm.h>
34#include <sound/pcm_params.h>
35#include <sound/initval.h>
36 30
37#include "usbaudio.h" 31#include "usbaudio.h"
38#include "card.h" 32#include "card.h"
39#include "midi.h"
40#include "mixer.h"
41#include "proc.h"
42#include "quirks.h"
43#include "endpoint.h"
44#include "helper.h" 33#include "helper.h"
45#include "debug.h" 34#include "clock.h"
46#include "pcm.h"
47#include "urb.h"
48#include "format.h"
49 35
50static struct uac_clock_source_descriptor * 36static struct uac_clock_source_descriptor *
51 snd_usb_find_clock_source(struct usb_host_interface *ctrl_iface, 37 snd_usb_find_clock_source(struct usb_host_interface *ctrl_iface,
@@ -134,10 +120,7 @@ static bool uac_clock_source_is_valid(struct snd_usb_audio *chip, int source_id)
134 return !!data; 120 return !!data;
135} 121}
136 122
137/* Try to find the clock source ID of a given clock entity */
138
139static int __uac_clock_find_source(struct snd_usb_audio *chip, 123static int __uac_clock_find_source(struct snd_usb_audio *chip,
140 struct usb_host_interface *host_iface,
141 int entity_id, unsigned long *visited) 124 int entity_id, unsigned long *visited)
142{ 125{
143 struct uac_clock_source_descriptor *source; 126 struct uac_clock_source_descriptor *source;
@@ -154,11 +137,11 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip,
154 } 137 }
155 138
156 /* first, see if the ID we're looking for is a clock source already */ 139 /* first, see if the ID we're looking for is a clock source already */
157 source = snd_usb_find_clock_source(host_iface, entity_id); 140 source = snd_usb_find_clock_source(chip->ctrl_intf, entity_id);
158 if (source) 141 if (source)
159 return source->bClockID; 142 return source->bClockID;
160 143
161 selector = snd_usb_find_clock_selector(host_iface, entity_id); 144 selector = snd_usb_find_clock_selector(chip->ctrl_intf, entity_id);
162 if (selector) { 145 if (selector) {
163 int ret; 146 int ret;
164 147
@@ -168,6 +151,8 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip,
168 if (ret < 0) 151 if (ret < 0)
169 return ret; 152 return ret;
170 153
154 /* Selector values are one-based */
155
171 if (ret > selector->bNrInPins || ret < 1) { 156 if (ret > selector->bNrInPins || ret < 1) {
172 printk(KERN_ERR 157 printk(KERN_ERR
173 "%s(): selector reported illegal value, id %d, ret %d\n", 158 "%s(): selector reported illegal value, id %d, ret %d\n",
@@ -176,27 +161,35 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip,
176 return -EINVAL; 161 return -EINVAL;
177 } 162 }
178 163
179 return __uac_clock_find_source(chip, host_iface, 164 return __uac_clock_find_source(chip, selector->baCSourceID[ret-1],
180 selector->baCSourceID[ret-1],
181 visited); 165 visited);
182 } 166 }
183 167
184 /* FIXME: multipliers only act as pass-thru element for now */ 168 /* FIXME: multipliers only act as pass-thru element for now */
185 multiplier = snd_usb_find_clock_multiplier(host_iface, entity_id); 169 multiplier = snd_usb_find_clock_multiplier(chip->ctrl_intf, entity_id);
186 if (multiplier) 170 if (multiplier)
187 return __uac_clock_find_source(chip, host_iface, 171 return __uac_clock_find_source(chip, multiplier->bCSourceID,
188 multiplier->bCSourceID, visited); 172 visited);
189 173
190 return -EINVAL; 174 return -EINVAL;
191} 175}
192 176
193int snd_usb_clock_find_source(struct snd_usb_audio *chip, 177/*
194 struct usb_host_interface *host_iface, 178 * For all kinds of sample rate settings and other device queries,
195 int entity_id) 179 * the clock source (end-leaf) must be used. However, clock selectors,
180 * clock multipliers and sample rate converters may be specified as
181 * clock source input to terminal. This functions walks the clock path
182 * to its end and tries to find the source.
183 *
184 * The 'visited' bitfield is used internally to detect recursive loops.
185 *
186 * Returns the clock source UnitID (>=0) on success, or an error.
187 */
188int snd_usb_clock_find_source(struct snd_usb_audio *chip, int entity_id)
196{ 189{
197 DECLARE_BITMAP(visited, 256); 190 DECLARE_BITMAP(visited, 256);
198 memset(visited, 0, sizeof(visited)); 191 memset(visited, 0, sizeof(visited));
199 return __uac_clock_find_source(chip, host_iface, entity_id, visited); 192 return __uac_clock_find_source(chip, entity_id, visited);
200} 193}
201 194
202static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface, 195static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface,
@@ -211,11 +204,8 @@ static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface,
211 ep = get_endpoint(alts, 0)->bEndpointAddress; 204 ep = get_endpoint(alts, 0)->bEndpointAddress;
212 205
213 /* if endpoint doesn't have sampling rate control, bail out */ 206 /* if endpoint doesn't have sampling rate control, bail out */
214 if (!(fmt->attributes & UAC_EP_CS_ATTR_SAMPLE_RATE)) { 207 if (!(fmt->attributes & UAC_EP_CS_ATTR_SAMPLE_RATE))
215 snd_printk(KERN_WARNING "%d:%d:%d: endpoint lacks sample rate attribute bit, cannot set.\n",
216 dev->devnum, iface, fmt->altsetting);
217 return 0; 208 return 0;
218 }
219 209
220 data[0] = rate; 210 data[0] = rate;
221 data[1] = rate >> 8; 211 data[1] = rate >> 8;
@@ -254,12 +244,13 @@ static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface,
254 struct usb_device *dev = chip->dev; 244 struct usb_device *dev = chip->dev;
255 unsigned char data[4]; 245 unsigned char data[4];
256 int err, crate; 246 int err, crate;
257 int clock = snd_usb_clock_find_source(chip, chip->ctrl_intf, fmt->clock); 247 int clock = snd_usb_clock_find_source(chip, fmt->clock);
258 248
259 if (clock < 0) 249 if (clock < 0)
260 return clock; 250 return clock;
261 251
262 if (!uac_clock_source_is_valid(chip, clock)) { 252 if (!uac_clock_source_is_valid(chip, clock)) {
253 /* TODO: should we try to find valid clock setups by ourself? */
263 snd_printk(KERN_ERR "%d:%d:%d: clock source %d is not valid, cannot use\n", 254 snd_printk(KERN_ERR "%d:%d:%d: clock source %d is not valid, cannot use\n",
264 dev->devnum, iface, fmt->altsetting, clock); 255 dev->devnum, iface, fmt->altsetting, clock);
265 return -ENXIO; 256 return -ENXIO;
@@ -304,12 +295,11 @@ int snd_usb_init_sample_rate(struct snd_usb_audio *chip, int iface,
304 295
305 switch (altsd->bInterfaceProtocol) { 296 switch (altsd->bInterfaceProtocol) {
306 case UAC_VERSION_1: 297 case UAC_VERSION_1:
298 default:
307 return set_sample_rate_v1(chip, iface, alts, fmt, rate); 299 return set_sample_rate_v1(chip, iface, alts, fmt, rate);
308 300
309 case UAC_VERSION_2: 301 case UAC_VERSION_2:
310 return set_sample_rate_v2(chip, iface, alts, fmt, rate); 302 return set_sample_rate_v2(chip, iface, alts, fmt, rate);
311 } 303 }
312
313 return -EINVAL;
314} 304}
315 305
diff --git a/sound/usb/clock.h b/sound/usb/clock.h
index beb253684e2..46630936d31 100644
--- a/sound/usb/clock.h
+++ b/sound/usb/clock.h
@@ -5,8 +5,6 @@ int snd_usb_init_sample_rate(struct snd_usb_audio *chip, int iface,
5 struct usb_host_interface *alts, 5 struct usb_host_interface *alts,
6 struct audioformat *fmt, int rate); 6 struct audioformat *fmt, int rate);
7 7
8int snd_usb_clock_find_source(struct snd_usb_audio *chip, 8int snd_usb_clock_find_source(struct snd_usb_audio *chip, int entity_id);
9 struct usb_host_interface *host_iface,
10 int entity_id);
11 9
12#endif /* __USBAUDIO_CLOCK_H */ 10#endif /* __USBAUDIO_CLOCK_H */
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
index 6f6596cf2b1..b0ef9f50189 100644
--- a/sound/usb/endpoint.c
+++ b/sound/usb/endpoint.c
@@ -33,6 +33,7 @@
33#include "pcm.h" 33#include "pcm.h"
34#include "helper.h" 34#include "helper.h"
35#include "format.h" 35#include "format.h"
36#include "clock.h"
36 37
37/* 38/*
38 * free a substream 39 * free a substream
@@ -274,8 +275,14 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
274 275
275 /* get audio formats */ 276 /* get audio formats */
276 switch (protocol) { 277 switch (protocol) {
278 default:
279 snd_printdd(KERN_WARNING "%d:%u:%d: unknown interface protocol %#02x, assuming v1\n",
280 dev->devnum, iface_no, altno, protocol);
281 protocol = UAC_VERSION_1;
282 /* fall through */
283
277 case UAC_VERSION_1: { 284 case UAC_VERSION_1: {
278 struct uac_as_header_descriptor_v1 *as = 285 struct uac1_as_header_descriptor *as =
279 snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL); 286 snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL);
280 287
281 if (!as) { 288 if (!as) {
@@ -297,7 +304,7 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
297 case UAC_VERSION_2: { 304 case UAC_VERSION_2: {
298 struct uac2_input_terminal_descriptor *input_term; 305 struct uac2_input_terminal_descriptor *input_term;
299 struct uac2_output_terminal_descriptor *output_term; 306 struct uac2_output_terminal_descriptor *output_term;
300 struct uac_as_header_descriptor_v2 *as = 307 struct uac2_as_header_descriptor *as =
301 snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL); 308 snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL);
302 309
303 if (!as) { 310 if (!as) {
@@ -335,11 +342,6 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
335 dev->devnum, iface_no, altno, as->bTerminalLink); 342 dev->devnum, iface_no, altno, as->bTerminalLink);
336 continue; 343 continue;
337 } 344 }
338
339 default:
340 snd_printk(KERN_ERR "%d:%u:%d : unknown interface protocol %04x\n",
341 dev->devnum, iface_no, altno, protocol);
342 continue;
343 } 345 }
344 346
345 /* get format type */ 347 /* get format type */
@@ -403,8 +405,6 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
403 break; 405 break;
404 case USB_ID(0x041e, 0x3020): /* Creative SB Audigy 2 NX */ 406 case USB_ID(0x041e, 0x3020): /* Creative SB Audigy 2 NX */
405 case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */ 407 case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
406 case USB_ID(0x0763, 0x2080): /* M-Audio Fast Track Ultra 8 */
407 case USB_ID(0x0763, 0x2081): /* M-Audio Fast Track Ultra 8R */
408 /* doesn't set the sample rate attribute, but supports it */ 408 /* doesn't set the sample rate attribute, but supports it */
409 fp->attributes |= UAC_EP_CS_ATTR_SAMPLE_RATE; 409 fp->attributes |= UAC_EP_CS_ATTR_SAMPLE_RATE;
410 break; 410 break;
diff --git a/sound/usb/format.c b/sound/usb/format.c
index 30364aba79c..69148212aa7 100644
--- a/sound/usb/format.c
+++ b/sound/usb/format.c
@@ -49,7 +49,8 @@ static u64 parse_audio_format_i_type(struct snd_usb_audio *chip,
49 u64 pcm_formats; 49 u64 pcm_formats;
50 50
51 switch (protocol) { 51 switch (protocol) {
52 case UAC_VERSION_1: { 52 case UAC_VERSION_1:
53 default: {
53 struct uac_format_type_i_discrete_descriptor *fmt = _fmt; 54 struct uac_format_type_i_discrete_descriptor *fmt = _fmt;
54 sample_width = fmt->bBitResolution; 55 sample_width = fmt->bBitResolution;
55 sample_bytes = fmt->bSubframeSize; 56 sample_bytes = fmt->bSubframeSize;
@@ -64,9 +65,6 @@ static u64 parse_audio_format_i_type(struct snd_usb_audio *chip,
64 format <<= 1; 65 format <<= 1;
65 break; 66 break;
66 } 67 }
67
68 default:
69 return -EINVAL;
70 } 68 }
71 69
72 pcm_formats = 0; 70 pcm_formats = 0;
@@ -264,13 +262,12 @@ static int parse_uac2_sample_rate_range(struct audioformat *fp, int nr_triplets,
264 * on the audioformat table (audio class v2). 262 * on the audioformat table (audio class v2).
265 */ 263 */
266static int parse_audio_format_rates_v2(struct snd_usb_audio *chip, 264static int parse_audio_format_rates_v2(struct snd_usb_audio *chip,
267 struct audioformat *fp, 265 struct audioformat *fp)
268 struct usb_host_interface *iface)
269{ 266{
270 struct usb_device *dev = chip->dev; 267 struct usb_device *dev = chip->dev;
271 unsigned char tmp[2], *data; 268 unsigned char tmp[2], *data;
272 int nr_triplets, data_size, ret = 0; 269 int nr_triplets, data_size, ret = 0;
273 int clock = snd_usb_clock_find_source(chip, chip->ctrl_intf, fp->clock); 270 int clock = snd_usb_clock_find_source(chip, fp->clock);
274 271
275 if (clock < 0) { 272 if (clock < 0) {
276 snd_printk(KERN_ERR "%s(): unable to find clock source (clock %d)\n", 273 snd_printk(KERN_ERR "%s(): unable to find clock source (clock %d)\n",
@@ -385,13 +382,17 @@ static int parse_audio_format_i(struct snd_usb_audio *chip,
385 * audio class v2 uses class specific EP0 range requests for that. 382 * audio class v2 uses class specific EP0 range requests for that.
386 */ 383 */
387 switch (protocol) { 384 switch (protocol) {
385 default:
386 snd_printdd(KERN_WARNING "%d:%u:%d : invalid protocol version %d, assuming v1\n",
387 chip->dev->devnum, fp->iface, fp->altsetting, protocol);
388 /* fall through */
388 case UAC_VERSION_1: 389 case UAC_VERSION_1:
389 fp->channels = fmt->bNrChannels; 390 fp->channels = fmt->bNrChannels;
390 ret = parse_audio_format_rates_v1(chip, fp, (unsigned char *) fmt, 7); 391 ret = parse_audio_format_rates_v1(chip, fp, (unsigned char *) fmt, 7);
391 break; 392 break;
392 case UAC_VERSION_2: 393 case UAC_VERSION_2:
393 /* fp->channels is already set in this case */ 394 /* fp->channels is already set in this case */
394 ret = parse_audio_format_rates_v2(chip, fp, iface); 395 ret = parse_audio_format_rates_v2(chip, fp);
395 break; 396 break;
396 } 397 }
397 398
@@ -435,6 +436,10 @@ static int parse_audio_format_ii(struct snd_usb_audio *chip,
435 fp->channels = 1; 436 fp->channels = 1;
436 437
437 switch (protocol) { 438 switch (protocol) {
439 default:
440 snd_printdd(KERN_WARNING "%d:%u:%d : invalid protocol version %d, assuming v1\n",
441 chip->dev->devnum, fp->iface, fp->altsetting, protocol);
442 /* fall through */
438 case UAC_VERSION_1: { 443 case UAC_VERSION_1: {
439 struct uac_format_type_ii_discrete_descriptor *fmt = _fmt; 444 struct uac_format_type_ii_discrete_descriptor *fmt = _fmt;
440 brate = le16_to_cpu(fmt->wMaxBitRate); 445 brate = le16_to_cpu(fmt->wMaxBitRate);
@@ -450,7 +455,7 @@ static int parse_audio_format_ii(struct snd_usb_audio *chip,
450 framesize = le16_to_cpu(fmt->wSamplesPerFrame); 455 framesize = le16_to_cpu(fmt->wSamplesPerFrame);
451 snd_printd(KERN_INFO "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize); 456 snd_printd(KERN_INFO "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize);
452 fp->frame_size = framesize; 457 fp->frame_size = framesize;
453 ret = parse_audio_format_rates_v2(chip, fp, iface); 458 ret = parse_audio_format_rates_v2(chip, fp);
454 break; 459 break;
455 } 460 }
456 } 461 }
diff --git a/sound/usb/helper.c b/sound/usb/helper.c
index d48d6f8f6ac..f280c1903c2 100644
--- a/sound/usb/helper.c
+++ b/sound/usb/helper.c
@@ -103,11 +103,16 @@ int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe, __u8 request,
103unsigned char snd_usb_parse_datainterval(struct snd_usb_audio *chip, 103unsigned char snd_usb_parse_datainterval(struct snd_usb_audio *chip,
104 struct usb_host_interface *alts) 104 struct usb_host_interface *alts)
105{ 105{
106 if (snd_usb_get_speed(chip->dev) == USB_SPEED_HIGH && 106 switch (snd_usb_get_speed(chip->dev)) {
107 get_endpoint(alts, 0)->bInterval >= 1 && 107 case USB_SPEED_HIGH:
108 get_endpoint(alts, 0)->bInterval <= 4) 108 case USB_SPEED_SUPER:
109 return get_endpoint(alts, 0)->bInterval - 1; 109 if (get_endpoint(alts, 0)->bInterval >= 1 &&
110 else 110 get_endpoint(alts, 0)->bInterval <= 4)
111 return 0; 111 return get_endpoint(alts, 0)->bInterval - 1;
112 break;
113 default:
114 break;
115 }
116 return 0;
112} 117}
113 118
diff --git a/sound/usb/midi.c b/sound/usb/midi.c
index 46785643c66..156cd0716c4 100644
--- a/sound/usb/midi.c
+++ b/sound/usb/midi.c
@@ -434,7 +434,7 @@ static void snd_usbmidi_maudio_broken_running_status_input(
434 u8 cin = buffer[i] & 0x0f; 434 u8 cin = buffer[i] & 0x0f;
435 struct usbmidi_in_port *port = &ep->ports[cable]; 435 struct usbmidi_in_port *port = &ep->ports[cable];
436 int length; 436 int length;
437 437
438 length = snd_usbmidi_cin_length[cin]; 438 length = snd_usbmidi_cin_length[cin];
439 if (cin == 0xf && buffer[i + 1] >= 0xf8) 439 if (cin == 0xf && buffer[i + 1] >= 0xf8)
440 ; /* realtime msg: no running status change */ 440 ; /* realtime msg: no running status change */
@@ -628,13 +628,13 @@ static struct usb_protocol_ops snd_usbmidi_standard_ops = {
628 628
629static struct usb_protocol_ops snd_usbmidi_midiman_ops = { 629static struct usb_protocol_ops snd_usbmidi_midiman_ops = {
630 .input = snd_usbmidi_midiman_input, 630 .input = snd_usbmidi_midiman_input,
631 .output = snd_usbmidi_standard_output, 631 .output = snd_usbmidi_standard_output,
632 .output_packet = snd_usbmidi_output_midiman_packet, 632 .output_packet = snd_usbmidi_output_midiman_packet,
633}; 633};
634 634
635static struct usb_protocol_ops snd_usbmidi_maudio_broken_running_status_ops = { 635static struct usb_protocol_ops snd_usbmidi_maudio_broken_running_status_ops = {
636 .input = snd_usbmidi_maudio_broken_running_status_input, 636 .input = snd_usbmidi_maudio_broken_running_status_input,
637 .output = snd_usbmidi_standard_output, 637 .output = snd_usbmidi_standard_output,
638 .output_packet = snd_usbmidi_output_standard_packet, 638 .output_packet = snd_usbmidi_output_standard_packet,
639}; 639};
640 640
@@ -834,7 +834,14 @@ static void snd_usbmidi_us122l_output(struct snd_usb_midi_out_endpoint *ep,
834 834
835 if (!ep->ports[0].active) 835 if (!ep->ports[0].active)
836 return; 836 return;
837 count = snd_usb_get_speed(ep->umidi->dev) == USB_SPEED_HIGH ? 1 : 2; 837 switch (snd_usb_get_speed(ep->umidi->dev)) {
838 case USB_SPEED_HIGH:
839 case USB_SPEED_SUPER:
840 count = 1;
841 break;
842 default:
843 count = 2;
844 }
838 count = snd_rawmidi_transmit(ep->ports[0].substream, 845 count = snd_rawmidi_transmit(ep->ports[0].substream,
839 urb->transfer_buffer, 846 urb->transfer_buffer,
840 count); 847 count);
@@ -1248,7 +1255,7 @@ static void snd_usbmidi_out_endpoint_delete(struct snd_usb_midi_out_endpoint *ep
1248 */ 1255 */
1249static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi* umidi, 1256static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi* umidi,
1250 struct snd_usb_midi_endpoint_info* ep_info, 1257 struct snd_usb_midi_endpoint_info* ep_info,
1251 struct snd_usb_midi_endpoint* rep) 1258 struct snd_usb_midi_endpoint* rep)
1252{ 1259{
1253 struct snd_usb_midi_out_endpoint* ep; 1260 struct snd_usb_midi_out_endpoint* ep;
1254 unsigned int i; 1261 unsigned int i;
@@ -1398,7 +1405,7 @@ static void snd_usbmidi_rawmidi_free(struct snd_rawmidi *rmidi)
1398} 1405}
1399 1406
1400static struct snd_rawmidi_substream *snd_usbmidi_find_substream(struct snd_usb_midi* umidi, 1407static struct snd_rawmidi_substream *snd_usbmidi_find_substream(struct snd_usb_midi* umidi,
1401 int stream, int number) 1408 int stream, int number)
1402{ 1409{
1403 struct list_head* list; 1410 struct list_head* list;
1404 1411
@@ -1811,7 +1818,7 @@ static int snd_usbmidi_detect_endpoints(struct snd_usb_midi* umidi,
1811 snd_usbmidi_switch_roland_altsetting(umidi); 1818 snd_usbmidi_switch_roland_altsetting(umidi);
1812 1819
1813 if (endpoint[0].out_ep || endpoint[0].in_ep) 1820 if (endpoint[0].out_ep || endpoint[0].in_ep)
1814 return 0; 1821 return 0;
1815 1822
1816 intf = umidi->iface; 1823 intf = umidi->iface;
1817 if (!intf || intf->num_altsetting < 1) 1824 if (!intf || intf->num_altsetting < 1)
@@ -1849,7 +1856,7 @@ static int snd_usbmidi_detect_per_port_endpoints(struct snd_usb_midi* umidi,
1849 struct snd_usb_midi_endpoint_info* endpoints) 1856 struct snd_usb_midi_endpoint_info* endpoints)
1850{ 1857{
1851 int err, i; 1858 int err, i;
1852 1859
1853 err = snd_usbmidi_detect_endpoints(umidi, endpoints, MIDI_MAX_ENDPOINTS); 1860 err = snd_usbmidi_detect_endpoints(umidi, endpoints, MIDI_MAX_ENDPOINTS);
1854 for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) { 1861 for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
1855 if (endpoints[i].out_ep) 1862 if (endpoints[i].out_ep)
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index 736d134cc03..f2d74d654b3 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -26,6 +26,22 @@
26 * 26 *
27 */ 27 */
28 28
29/*
30 * TODOs, for both the mixer and the streaming interfaces:
31 *
32 * - support for UAC2 effect units
33 * - support for graphical equalizers
34 * - RANGE and MEM set commands (UAC2)
35 * - RANGE and MEM interrupt dispatchers (UAC2)
36 * - audio channel clustering (UAC2)
37 * - audio sample rate converter units (UAC2)
38 * - proper handling of clock multipliers (UAC2)
39 * - dispatch clock change notifications (UAC2)
40 * - stop PCM streams which use a clock that became invalid
41 * - stop PCM streams which use a clock selector that has changed
42 * - parse available sample rates again when clock sources changed
43 */
44
29#include <linux/bitops.h> 45#include <linux/bitops.h>
30#include <linux/init.h> 46#include <linux/init.h>
31#include <linux/list.h> 47#include <linux/list.h>
@@ -275,28 +291,28 @@ static int get_abs_value(struct usb_mixer_elem_info *cval, int val)
275 291
276static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret) 292static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret)
277{ 293{
294 struct snd_usb_audio *chip = cval->mixer->chip;
278 unsigned char buf[2]; 295 unsigned char buf[2];
279 int val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1; 296 int val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1;
280 int timeout = 10; 297 int timeout = 10;
281 298
282 while (timeout-- > 0) { 299 while (timeout-- > 0) {
283 if (snd_usb_ctl_msg(cval->mixer->chip->dev, 300 if (snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), request,
284 usb_rcvctrlpipe(cval->mixer->chip->dev, 0),
285 request,
286 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, 301 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
287 validx, cval->mixer->ctrlif | (cval->id << 8), 302 validx, snd_usb_ctrl_intf(chip) | (cval->id << 8),
288 buf, val_len, 100) >= val_len) { 303 buf, val_len, 100) >= val_len) {
289 *value_ret = convert_signed_value(cval, snd_usb_combine_bytes(buf, val_len)); 304 *value_ret = convert_signed_value(cval, snd_usb_combine_bytes(buf, val_len));
290 return 0; 305 return 0;
291 } 306 }
292 } 307 }
293 snd_printdd(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n", 308 snd_printdd(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n",
294 request, validx, cval->mixer->ctrlif | (cval->id << 8), cval->val_type); 309 request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type);
295 return -EINVAL; 310 return -EINVAL;
296} 311}
297 312
298static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret) 313static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret)
299{ 314{
315 struct snd_usb_audio *chip = cval->mixer->chip;
300 unsigned char buf[2 + 3*sizeof(__u16)]; /* enough space for one range */ 316 unsigned char buf[2 + 3*sizeof(__u16)]; /* enough space for one range */
301 unsigned char *val; 317 unsigned char *val;
302 int ret, size; 318 int ret, size;
@@ -312,16 +328,14 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int v
312 328
313 memset(buf, 0, sizeof(buf)); 329 memset(buf, 0, sizeof(buf));
314 330
315 ret = snd_usb_ctl_msg(cval->mixer->chip->dev, 331 ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest,
316 usb_rcvctrlpipe(cval->mixer->chip->dev, 0),
317 bRequest,
318 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, 332 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
319 validx, cval->mixer->ctrlif | (cval->id << 8), 333 validx, snd_usb_ctrl_intf(chip) | (cval->id << 8),
320 buf, size, 1000); 334 buf, size, 1000);
321 335
322 if (ret < 0) { 336 if (ret < 0) {
323 snd_printk(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n", 337 snd_printk(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n",
324 request, validx, cval->mixer->ctrlif | (cval->id << 8), cval->val_type); 338 request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type);
325 return ret; 339 return ret;
326 } 340 }
327 341
@@ -397,6 +411,7 @@ static int get_cur_mix_value(struct usb_mixer_elem_info *cval,
397int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval, 411int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
398 int request, int validx, int value_set) 412 int request, int validx, int value_set)
399{ 413{
414 struct snd_usb_audio *chip = cval->mixer->chip;
400 unsigned char buf[2]; 415 unsigned char buf[2];
401 int val_len, timeout = 10; 416 int val_len, timeout = 10;
402 417
@@ -419,15 +434,14 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
419 buf[0] = value_set & 0xff; 434 buf[0] = value_set & 0xff;
420 buf[1] = (value_set >> 8) & 0xff; 435 buf[1] = (value_set >> 8) & 0xff;
421 while (timeout-- > 0) 436 while (timeout-- > 0)
422 if (snd_usb_ctl_msg(cval->mixer->chip->dev, 437 if (snd_usb_ctl_msg(chip->dev,
423 usb_sndctrlpipe(cval->mixer->chip->dev, 0), 438 usb_sndctrlpipe(chip->dev, 0), request,
424 request,
425 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, 439 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
426 validx, cval->mixer->ctrlif | (cval->id << 8), 440 validx, snd_usb_ctrl_intf(chip) | (cval->id << 8),
427 buf, val_len, 100) >= 0) 441 buf, val_len, 100) >= 0)
428 return 0; 442 return 0;
429 snd_printdd(KERN_ERR "cannot set ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d, data = %#x/%#x\n", 443 snd_printdd(KERN_ERR "cannot set ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d, data = %#x/%#x\n",
430 request, validx, cval->mixer->ctrlif | (cval->id << 8), cval->val_type, buf[0], buf[1]); 444 request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type, buf[0], buf[1]);
431 return -EINVAL; 445 return -EINVAL;
432} 446}
433 447
@@ -582,9 +596,9 @@ static int get_term_name(struct mixer_build *state, struct usb_audio_term *iterm
582 switch (iterm->type >> 16) { 596 switch (iterm->type >> 16) {
583 case UAC_SELECTOR_UNIT: 597 case UAC_SELECTOR_UNIT:
584 strcpy(name, "Selector"); return 8; 598 strcpy(name, "Selector"); return 8;
585 case UAC_PROCESSING_UNIT_V1: 599 case UAC1_PROCESSING_UNIT:
586 strcpy(name, "Process Unit"); return 12; 600 strcpy(name, "Process Unit"); return 12;
587 case UAC_EXTENSION_UNIT_V1: 601 case UAC1_EXTENSION_UNIT:
588 strcpy(name, "Ext Unit"); return 8; 602 strcpy(name, "Ext Unit"); return 8;
589 case UAC_MIXER_UNIT: 603 case UAC_MIXER_UNIT:
590 strcpy(name, "Mixer"); return 5; 604 strcpy(name, "Mixer"); return 5;
@@ -672,8 +686,8 @@ static int check_input_term(struct mixer_build *state, int id, struct usb_audio_
672 term->name = uac_selector_unit_iSelector(d); 686 term->name = uac_selector_unit_iSelector(d);
673 return 0; 687 return 0;
674 } 688 }
675 case UAC_PROCESSING_UNIT_V1: 689 case UAC1_PROCESSING_UNIT:
676 case UAC_EXTENSION_UNIT_V1: { 690 case UAC1_EXTENSION_UNIT: {
677 struct uac_processing_unit_descriptor *d = p1; 691 struct uac_processing_unit_descriptor *d = p1;
678 if (d->bNrInPins) { 692 if (d->bNrInPins) {
679 id = d->baSourceID[0]; 693 id = d->baSourceID[0];
@@ -767,7 +781,7 @@ static int get_min_max(struct usb_mixer_elem_info *cval, int default_min)
767 if (get_ctl_value(cval, UAC_GET_MAX, (cval->control << 8) | minchn, &cval->max) < 0 || 781 if (get_ctl_value(cval, UAC_GET_MAX, (cval->control << 8) | minchn, &cval->max) < 0 ||
768 get_ctl_value(cval, UAC_GET_MIN, (cval->control << 8) | minchn, &cval->min) < 0) { 782 get_ctl_value(cval, UAC_GET_MIN, (cval->control << 8) | minchn, &cval->min) < 0) {
769 snd_printd(KERN_ERR "%d:%d: cannot get min/max values for control %d (id %d)\n", 783 snd_printd(KERN_ERR "%d:%d: cannot get min/max values for control %d (id %d)\n",
770 cval->id, cval->mixer->ctrlif, cval->control, cval->id); 784 cval->id, snd_usb_ctrl_intf(cval->mixer->chip), cval->control, cval->id);
771 return -EINVAL; 785 return -EINVAL;
772 } 786 }
773 if (get_ctl_value(cval, UAC_GET_RES, (cval->control << 8) | minchn, &cval->res) < 0) { 787 if (get_ctl_value(cval, UAC_GET_RES, (cval->control << 8) | minchn, &cval->res) < 0) {
@@ -1199,14 +1213,6 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void
1199 } 1213 }
1200 } else { /* UAC_VERSION_2 */ 1214 } else { /* UAC_VERSION_2 */
1201 for (i = 0; i < 30/2; i++) { 1215 for (i = 0; i < 30/2; i++) {
1202 /* From the USB Audio spec v2.0:
1203 bmaControls() is a (ch+1)-element array of 4-byte bitmaps,
1204 each containing a set of bit pairs. If a Control is present,
1205 it must be Host readable. If a certain Control is not
1206 present then the bit pair must be set to 0b00.
1207 If a Control is present but read-only, the bit pair must be
1208 set to 0b01. If a Control is also Host programmable, the bit
1209 pair must be set to 0b11. The value 0b10 is not allowed. */
1210 unsigned int ch_bits = 0; 1216 unsigned int ch_bits = 0;
1211 unsigned int ch_read_only = 0; 1217 unsigned int ch_read_only = 0;
1212 1218
@@ -1634,9 +1640,10 @@ static int mixer_ctl_selector_info(struct snd_kcontrol *kcontrol, struct snd_ctl
1634 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 1640 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1635 uinfo->count = 1; 1641 uinfo->count = 1;
1636 uinfo->value.enumerated.items = cval->max; 1642 uinfo->value.enumerated.items = cval->max;
1637 if ((int)uinfo->value.enumerated.item >= cval->max) 1643 if (uinfo->value.enumerated.item >= cval->max)
1638 uinfo->value.enumerated.item = cval->max - 1; 1644 uinfo->value.enumerated.item = cval->max - 1;
1639 strcpy(uinfo->value.enumerated.name, itemlist[uinfo->value.enumerated.item]); 1645 strlcpy(uinfo->value.enumerated.name, itemlist[uinfo->value.enumerated.item],
1646 sizeof(uinfo->value.enumerated.name));
1640 return 0; 1647 return 0;
1641} 1648}
1642 1649
@@ -1855,13 +1862,13 @@ static int parse_audio_unit(struct mixer_build *state, int unitid)
1855 return parse_audio_selector_unit(state, unitid, p1); 1862 return parse_audio_selector_unit(state, unitid, p1);
1856 case UAC_FEATURE_UNIT: 1863 case UAC_FEATURE_UNIT:
1857 return parse_audio_feature_unit(state, unitid, p1); 1864 return parse_audio_feature_unit(state, unitid, p1);
1858 case UAC_PROCESSING_UNIT_V1: 1865 case UAC1_PROCESSING_UNIT:
1859 /* UAC2_EFFECT_UNIT has the same value */ 1866 /* UAC2_EFFECT_UNIT has the same value */
1860 if (state->mixer->protocol == UAC_VERSION_1) 1867 if (state->mixer->protocol == UAC_VERSION_1)
1861 return parse_audio_processing_unit(state, unitid, p1); 1868 return parse_audio_processing_unit(state, unitid, p1);
1862 else 1869 else
1863 return 0; /* FIXME - effect units not implemented yet */ 1870 return 0; /* FIXME - effect units not implemented yet */
1864 case UAC_EXTENSION_UNIT_V1: 1871 case UAC1_EXTENSION_UNIT:
1865 /* UAC2_PROCESSING_UNIT_V2 has the same value */ 1872 /* UAC2_PROCESSING_UNIT_V2 has the same value */
1866 if (state->mixer->protocol == UAC_VERSION_1) 1873 if (state->mixer->protocol == UAC_VERSION_1)
1867 return parse_audio_extension_unit(state, unitid, p1); 1874 return parse_audio_extension_unit(state, unitid, p1);
@@ -1905,7 +1912,7 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
1905 struct usb_host_interface *hostif; 1912 struct usb_host_interface *hostif;
1906 void *p; 1913 void *p;
1907 1914
1908 hostif = &usb_ifnum_to_if(mixer->chip->dev, mixer->ctrlif)->altsetting[0]; 1915 hostif = mixer->chip->ctrl_intf;
1909 memset(&state, 0, sizeof(state)); 1916 memset(&state, 0, sizeof(state));
1910 state.chip = mixer->chip; 1917 state.chip = mixer->chip;
1911 state.mixer = mixer; 1918 state.mixer = mixer;
@@ -1925,7 +1932,7 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
1925 p = NULL; 1932 p = NULL;
1926 while ((p = snd_usb_find_csint_desc(hostif->extra, hostif->extralen, p, UAC_OUTPUT_TERMINAL)) != NULL) { 1933 while ((p = snd_usb_find_csint_desc(hostif->extra, hostif->extralen, p, UAC_OUTPUT_TERMINAL)) != NULL) {
1927 if (mixer->protocol == UAC_VERSION_1) { 1934 if (mixer->protocol == UAC_VERSION_1) {
1928 struct uac_output_terminal_descriptor_v1 *desc = p; 1935 struct uac1_output_terminal_descriptor *desc = p;
1929 1936
1930 if (desc->bLength < sizeof(*desc)) 1937 if (desc->bLength < sizeof(*desc))
1931 continue; /* invalid descriptor? */ 1938 continue; /* invalid descriptor? */
@@ -1997,7 +2004,7 @@ static void snd_usb_mixer_proc_read(struct snd_info_entry *entry,
1997 list_for_each_entry(mixer, &chip->mixer_list, list) { 2004 list_for_each_entry(mixer, &chip->mixer_list, list) {
1998 snd_iprintf(buffer, 2005 snd_iprintf(buffer,
1999 "USB Mixer: usb_id=0x%08x, ctrlif=%i, ctlerr=%i\n", 2006 "USB Mixer: usb_id=0x%08x, ctrlif=%i, ctlerr=%i\n",
2000 chip->usb_id, mixer->ctrlif, 2007 chip->usb_id, snd_usb_ctrl_intf(chip),
2001 mixer->ignore_ctl_error); 2008 mixer->ignore_ctl_error);
2002 snd_iprintf(buffer, "Card: %s\n", chip->card->longname); 2009 snd_iprintf(buffer, "Card: %s\n", chip->card->longname);
2003 for (unitid = 0; unitid < MAX_ID_ELEMS; unitid++) { 2010 for (unitid = 0; unitid < MAX_ID_ELEMS; unitid++) {
@@ -2115,7 +2122,7 @@ static int snd_usb_mixer_status_create(struct usb_mixer_interface *mixer)
2115 int buffer_length; 2122 int buffer_length;
2116 unsigned int epnum; 2123 unsigned int epnum;
2117 2124
2118 hostif = &usb_ifnum_to_if(mixer->chip->dev, mixer->ctrlif)->altsetting[0]; 2125 hostif = mixer->chip->ctrl_intf;
2119 /* we need one interrupt input endpoint */ 2126 /* we need one interrupt input endpoint */
2120 if (get_iface_desc(hostif)->bNumEndpoints < 1) 2127 if (get_iface_desc(hostif)->bNumEndpoints < 1)
2121 return 0; 2128 return 0;
@@ -2158,7 +2165,6 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
2158 if (!mixer) 2165 if (!mixer)
2159 return -ENOMEM; 2166 return -ENOMEM;
2160 mixer->chip = chip; 2167 mixer->chip = chip;
2161 mixer->ctrlif = ctrlif;
2162 mixer->ignore_ctl_error = ignore_error; 2168 mixer->ignore_ctl_error = ignore_error;
2163 mixer->id_elems = kcalloc(MAX_ID_ELEMS, sizeof(*mixer->id_elems), 2169 mixer->id_elems = kcalloc(MAX_ID_ELEMS, sizeof(*mixer->id_elems),
2164 GFP_KERNEL); 2170 GFP_KERNEL);
@@ -2168,7 +2174,15 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
2168 } 2174 }
2169 2175
2170 host_iface = &usb_ifnum_to_if(chip->dev, ctrlif)->altsetting[0]; 2176 host_iface = &usb_ifnum_to_if(chip->dev, ctrlif)->altsetting[0];
2171 mixer->protocol = get_iface_desc(host_iface)->bInterfaceProtocol; 2177 switch (get_iface_desc(host_iface)->bInterfaceProtocol) {
2178 case UAC_VERSION_1:
2179 default:
2180 mixer->protocol = UAC_VERSION_1;
2181 break;
2182 case UAC_VERSION_2:
2183 mixer->protocol = UAC_VERSION_2;
2184 break;
2185 }
2172 2186
2173 if ((err = snd_usb_mixer_controls(mixer)) < 0 || 2187 if ((err = snd_usb_mixer_controls(mixer)) < 0 ||
2174 (err = snd_usb_mixer_status_create(mixer)) < 0) 2188 (err = snd_usb_mixer_status_create(mixer)) < 0)
diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h
index a7cf1007fbb..26c636c5c93 100644
--- a/sound/usb/mixer.h
+++ b/sound/usb/mixer.h
@@ -3,7 +3,6 @@
3 3
4struct usb_mixer_interface { 4struct usb_mixer_interface {
5 struct snd_usb_audio *chip; 5 struct snd_usb_audio *chip;
6 unsigned int ctrlif;
7 struct list_head list; 6 struct list_head list;
8 unsigned int ignore_ctl_error; 7 unsigned int ignore_ctl_error;
9 struct urb *urb; 8 struct urb *urb;
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index 456829882f4..f49756c1b83 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -173,13 +173,12 @@ int snd_usb_init_pitch(struct snd_usb_audio *chip, int iface,
173 173
174 switch (altsd->bInterfaceProtocol) { 174 switch (altsd->bInterfaceProtocol) {
175 case UAC_VERSION_1: 175 case UAC_VERSION_1:
176 default:
176 return init_pitch_v1(chip, iface, alts, fmt); 177 return init_pitch_v1(chip, iface, alts, fmt);
177 178
178 case UAC_VERSION_2: 179 case UAC_VERSION_2:
179 return init_pitch_v2(chip, iface, alts, fmt); 180 return init_pitch_v2(chip, iface, alts, fmt);
180 } 181 }
181
182 return -EINVAL;
183} 182}
184 183
185/* 184/*
@@ -467,7 +466,7 @@ static int hw_check_valid_format(struct snd_usb_substream *subs,
467 return 0; 466 return 0;
468 } 467 }
469 /* check whether the period time is >= the data packet interval */ 468 /* check whether the period time is >= the data packet interval */
470 if (snd_usb_get_speed(subs->dev) == USB_SPEED_HIGH) { 469 if (snd_usb_get_speed(subs->dev) != USB_SPEED_FULL) {
471 ptime = 125 * (1 << fp->datainterval); 470 ptime = 125 * (1 << fp->datainterval);
472 if (ptime > pt->max || (ptime == pt->max && pt->openmax)) { 471 if (ptime > pt->max || (ptime == pt->max && pt->openmax)) {
473 hwc_debug(" > check: ptime %u > max %u\n", ptime, pt->max); 472 hwc_debug(" > check: ptime %u > max %u\n", ptime, pt->max);
@@ -636,7 +635,7 @@ static int hw_rule_period_time(struct snd_pcm_hw_params *params,
636 min_datainterval = min(min_datainterval, fp->datainterval); 635 min_datainterval = min(min_datainterval, fp->datainterval);
637 } 636 }
638 if (min_datainterval == 0xff) { 637 if (min_datainterval == 0xff) {
639 hwc_debug(" --> get emtpy\n"); 638 hwc_debug(" --> get empty\n");
640 it->empty = 1; 639 it->empty = 1;
641 return -EINVAL; 640 return -EINVAL;
642 } 641 }
@@ -735,7 +734,7 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre
735 } 734 }
736 735
737 param_period_time_if_needed = SNDRV_PCM_HW_PARAM_PERIOD_TIME; 736 param_period_time_if_needed = SNDRV_PCM_HW_PARAM_PERIOD_TIME;
738 if (snd_usb_get_speed(subs->dev) != USB_SPEED_HIGH) 737 if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL)
739 /* full speed devices have fixed data packet interval */ 738 /* full speed devices have fixed data packet interval */
740 ptmin = 1000; 739 ptmin = 1000;
741 if (ptmin == 1000) 740 if (ptmin == 1000)
diff --git a/sound/usb/pcm.h b/sound/usb/pcm.h
index 1c931b68f3b..ed3e283f618 100644
--- a/sound/usb/pcm.h
+++ b/sound/usb/pcm.h
@@ -7,8 +7,5 @@ int snd_usb_init_pitch(struct snd_usb_audio *chip, int iface,
7 struct usb_host_interface *alts, 7 struct usb_host_interface *alts,
8 struct audioformat *fmt); 8 struct audioformat *fmt);
9 9
10int snd_usb_init_sample_rate(struct snd_usb_audio *chip, int iface,
11 struct usb_host_interface *alts,
12 struct audioformat *fmt, int rate);
13 10
14#endif /* __USBAUDIO_PCM_H */ 11#endif /* __USBAUDIO_PCM_H */
diff --git a/sound/usb/proc.c b/sound/usb/proc.c
index f5e3f356b95..3c650ab3c91 100644
--- a/sound/usb/proc.c
+++ b/sound/usb/proc.c
@@ -107,7 +107,7 @@ static void proc_dump_substream_formats(struct snd_usb_substream *subs, struct s
107 } 107 }
108 snd_iprintf(buffer, "\n"); 108 snd_iprintf(buffer, "\n");
109 } 109 }
110 if (snd_usb_get_speed(subs->dev) == USB_SPEED_HIGH) 110 if (snd_usb_get_speed(subs->dev) != USB_SPEED_FULL)
111 snd_iprintf(buffer, " Data packet interval: %d us\n", 111 snd_iprintf(buffer, " Data packet interval: %d us\n",
112 125 * (1 << fp->datainterval)); 112 125 * (1 << fp->datainterval));
113 // snd_iprintf(buffer, " Max Packet Size = %d\n", fp->maxpacksize); 113 // snd_iprintf(buffer, " Max Packet Size = %d\n", fp->maxpacksize);
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
index f8797f61a24..682e3e06b07 100644
--- a/sound/usb/quirks-table.h
+++ b/sound/usb/quirks-table.h
@@ -240,9 +240,21 @@ YAMAHA_DEVICE(0x104f, NULL),
240YAMAHA_DEVICE(0x1050, NULL), 240YAMAHA_DEVICE(0x1050, NULL),
241YAMAHA_DEVICE(0x1051, NULL), 241YAMAHA_DEVICE(0x1051, NULL),
242YAMAHA_DEVICE(0x1052, NULL), 242YAMAHA_DEVICE(0x1052, NULL),
243YAMAHA_INTERFACE(0x1053, 0, NULL),
244YAMAHA_INTERFACE(0x1054, 0, NULL),
245YAMAHA_DEVICE(0x1055, NULL),
246YAMAHA_DEVICE(0x1056, NULL),
247YAMAHA_DEVICE(0x1057, NULL),
248YAMAHA_DEVICE(0x1058, NULL),
249YAMAHA_DEVICE(0x1059, NULL),
250YAMAHA_DEVICE(0x105a, NULL),
251YAMAHA_DEVICE(0x105b, NULL),
252YAMAHA_DEVICE(0x105c, NULL),
253YAMAHA_DEVICE(0x105d, NULL),
243YAMAHA_DEVICE(0x2000, "DGP-7"), 254YAMAHA_DEVICE(0x2000, "DGP-7"),
244YAMAHA_DEVICE(0x2001, "DGP-5"), 255YAMAHA_DEVICE(0x2001, "DGP-5"),
245YAMAHA_DEVICE(0x2002, NULL), 256YAMAHA_DEVICE(0x2002, NULL),
257YAMAHA_DEVICE(0x2003, NULL),
246YAMAHA_DEVICE(0x5000, "CS1D"), 258YAMAHA_DEVICE(0x5000, "CS1D"),
247YAMAHA_DEVICE(0x5001, "DSP1D"), 259YAMAHA_DEVICE(0x5001, "DSP1D"),
248YAMAHA_DEVICE(0x5002, "DME32"), 260YAMAHA_DEVICE(0x5002, "DME32"),
@@ -1136,11 +1148,34 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1136 } 1148 }
1137}, 1149},
1138{ 1150{
1151 /* has ID 0x0066 when not in "Advanced Driver" mode */
1152 USB_DEVICE(0x0582, 0x0064),
1153 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1154 /* .vendor_name = "EDIROL", */
1155 /* .product_name = "PCR-1", */
1156 .ifnum = QUIRK_ANY_INTERFACE,
1157 .type = QUIRK_COMPOSITE,
1158 .data = (const struct snd_usb_audio_quirk[]) {
1159 {
1160 .ifnum = 1,
1161 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1162 },
1163 {
1164 .ifnum = 2,
1165 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1166 },
1167 {
1168 .ifnum = -1
1169 }
1170 }
1171 }
1172},
1173{
1139 /* has ID 0x0067 when not in "Advanced Driver" mode */ 1174 /* has ID 0x0067 when not in "Advanced Driver" mode */
1140 USB_DEVICE(0x0582, 0x0065), 1175 USB_DEVICE(0x0582, 0x0065),
1141 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { 1176 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1142 .vendor_name = "EDIROL", 1177 /* .vendor_name = "EDIROL", */
1143 .product_name = "PCR-1", 1178 /* .product_name = "PCR-1", */
1144 .ifnum = 0, 1179 .ifnum = 0,
1145 .type = QUIRK_MIDI_FIXED_ENDPOINT, 1180 .type = QUIRK_MIDI_FIXED_ENDPOINT,
1146 .data = & (const struct snd_usb_midi_endpoint_info) { 1181 .data = & (const struct snd_usb_midi_endpoint_info) {
@@ -1525,6 +1560,50 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1525 } 1560 }
1526 } 1561 }
1527}, 1562},
1563{
1564 /* has ID 0x0110 when not in Advanced Driver mode */
1565 USB_DEVICE_VENDOR_SPEC(0x0582, 0x010f),
1566 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1567 /* .vendor_name = "Roland", */
1568 /* .product_name = "A-PRO", */
1569 .ifnum = 1,
1570 .type = QUIRK_MIDI_FIXED_ENDPOINT,
1571 .data = & (const struct snd_usb_midi_endpoint_info) {
1572 .out_cables = 0x0003,
1573 .in_cables = 0x0007
1574 }
1575 }
1576},
1577{
1578 USB_DEVICE(0x0582, 0x0113),
1579 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1580 /* .vendor_name = "BOSS", */
1581 /* .product_name = "ME-25", */
1582 .ifnum = QUIRK_ANY_INTERFACE,
1583 .type = QUIRK_COMPOSITE,
1584 .data = (const struct snd_usb_audio_quirk[]) {
1585 {
1586 .ifnum = 0,
1587 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1588 },
1589 {
1590 .ifnum = 1,
1591 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1592 },
1593 {
1594 .ifnum = 2,
1595 .type = QUIRK_MIDI_FIXED_ENDPOINT,
1596 .data = & (const struct snd_usb_midi_endpoint_info) {
1597 .out_cables = 0x0001,
1598 .in_cables = 0x0001
1599 }
1600 },
1601 {
1602 .ifnum = -1
1603 }
1604 }
1605 }
1606},
1528 1607
1529/* Guillemot devices */ 1608/* Guillemot devices */
1530{ 1609{
@@ -1830,7 +1909,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1830 USB_DEVICE(0x0763, 0x2080), 1909 USB_DEVICE(0x0763, 0x2080),
1831 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { 1910 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1832 /* .vendor_name = "M-Audio", */ 1911 /* .vendor_name = "M-Audio", */
1833 /* .product_name = "Fast Track Ultra 8", */ 1912 /* .product_name = "Fast Track Ultra", */
1834 .ifnum = QUIRK_ANY_INTERFACE, 1913 .ifnum = QUIRK_ANY_INTERFACE,
1835 .type = QUIRK_COMPOSITE, 1914 .type = QUIRK_COMPOSITE,
1836 .data = & (const struct snd_usb_audio_quirk[]) { 1915 .data = & (const struct snd_usb_audio_quirk[]) {
@@ -1840,11 +1919,51 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1840 }, 1919 },
1841 { 1920 {
1842 .ifnum = 1, 1921 .ifnum = 1,
1843 .type = QUIRK_AUDIO_STANDARD_INTERFACE 1922 .type = QUIRK_AUDIO_FIXED_ENDPOINT,
1923 .data = & (const struct audioformat) {
1924 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
1925 .channels = 8,
1926 .iface = 1,
1927 .altsetting = 1,
1928 .altset_idx = 1,
1929 .attributes = UAC_EP_CS_ATTR_SAMPLE_RATE,
1930 .endpoint = 0x01,
1931 .ep_attr = 0x09,
1932 .rates = SNDRV_PCM_RATE_44100 |
1933 SNDRV_PCM_RATE_48000 |
1934 SNDRV_PCM_RATE_88200 |
1935 SNDRV_PCM_RATE_96000,
1936 .rate_min = 44100,
1937 .rate_max = 96000,
1938 .nr_rates = 4,
1939 .rate_table = (unsigned int[]) {
1940 44100, 48000, 88200, 96000
1941 }
1942 }
1844 }, 1943 },
1845 { 1944 {
1846 .ifnum = 2, 1945 .ifnum = 2,
1847 .type = QUIRK_AUDIO_STANDARD_INTERFACE 1946 .type = QUIRK_AUDIO_FIXED_ENDPOINT,
1947 .data = & (const struct audioformat) {
1948 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
1949 .channels = 8,
1950 .iface = 2,
1951 .altsetting = 1,
1952 .altset_idx = 1,
1953 .attributes = UAC_EP_CS_ATTR_SAMPLE_RATE,
1954 .endpoint = 0x81,
1955 .ep_attr = 0x05,
1956 .rates = SNDRV_PCM_RATE_44100 |
1957 SNDRV_PCM_RATE_48000 |
1958 SNDRV_PCM_RATE_88200 |
1959 SNDRV_PCM_RATE_96000,
1960 .rate_min = 44100,
1961 .rate_max = 96000,
1962 .nr_rates = 4,
1963 .rate_table = (unsigned int[]) {
1964 44100, 48000, 88200, 96000
1965 }
1966 }
1848 }, 1967 },
1849 /* interface 3 (MIDI) is standard compliant */ 1968 /* interface 3 (MIDI) is standard compliant */
1850 { 1969 {
@@ -1867,11 +1986,51 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1867 }, 1986 },
1868 { 1987 {
1869 .ifnum = 1, 1988 .ifnum = 1,
1870 .type = QUIRK_AUDIO_STANDARD_INTERFACE 1989 .type = QUIRK_AUDIO_FIXED_ENDPOINT,
1990 .data = & (const struct audioformat) {
1991 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
1992 .channels = 8,
1993 .iface = 1,
1994 .altsetting = 1,
1995 .altset_idx = 1,
1996 .attributes = UAC_EP_CS_ATTR_SAMPLE_RATE,
1997 .endpoint = 0x01,
1998 .ep_attr = 0x09,
1999 .rates = SNDRV_PCM_RATE_44100 |
2000 SNDRV_PCM_RATE_48000 |
2001 SNDRV_PCM_RATE_88200 |
2002 SNDRV_PCM_RATE_96000,
2003 .rate_min = 44100,
2004 .rate_max = 96000,
2005 .nr_rates = 4,
2006 .rate_table = (unsigned int[]) {
2007 44100, 48000, 88200, 96000
2008 }
2009 }
1871 }, 2010 },
1872 { 2011 {
1873 .ifnum = 2, 2012 .ifnum = 2,
1874 .type = QUIRK_AUDIO_STANDARD_INTERFACE 2013 .type = QUIRK_AUDIO_FIXED_ENDPOINT,
2014 .data = & (const struct audioformat) {
2015 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
2016 .channels = 8,
2017 .iface = 2,
2018 .altsetting = 1,
2019 .altset_idx = 1,
2020 .attributes = UAC_EP_CS_ATTR_SAMPLE_RATE,
2021 .endpoint = 0x81,
2022 .ep_attr = 0x05,
2023 .rates = SNDRV_PCM_RATE_44100 |
2024 SNDRV_PCM_RATE_48000 |
2025 SNDRV_PCM_RATE_88200 |
2026 SNDRV_PCM_RATE_96000,
2027 .rate_min = 44100,
2028 .rate_max = 96000,
2029 .nr_rates = 4,
2030 .rate_table = (unsigned int[]) {
2031 44100, 48000, 88200, 96000
2032 }
2033 }
1875 }, 2034 },
1876 /* interface 3 (MIDI) is standard compliant */ 2035 /* interface 3 (MIDI) is standard compliant */
1877 { 2036 {
@@ -2152,7 +2311,21 @@ YAMAHA_DEVICE(0x7010, "UB99"),
2152 } 2311 }
2153}, 2312},
2154{ 2313{
2155 USB_DEVICE_VENDOR_SPEC(0x2040, 0x7201), 2314 USB_DEVICE_VENDOR_SPEC(0x2040, 0x7240),
2315 .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
2316 USB_DEVICE_ID_MATCH_INT_CLASS |
2317 USB_DEVICE_ID_MATCH_INT_SUBCLASS,
2318 .bInterfaceClass = USB_CLASS_AUDIO,
2319 .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
2320 .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
2321 .vendor_name = "Hauppauge",
2322 .product_name = "HVR-850",
2323 .ifnum = QUIRK_ANY_INTERFACE,
2324 .type = QUIRK_AUDIO_ALIGN_TRANSFER,
2325 }
2326},
2327{
2328 USB_DEVICE_VENDOR_SPEC(0x2040, 0x7210),
2156 .match_flags = USB_DEVICE_ID_MATCH_DEVICE | 2329 .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
2157 USB_DEVICE_ID_MATCH_INT_CLASS | 2330 USB_DEVICE_ID_MATCH_INT_CLASS |
2158 USB_DEVICE_ID_MATCH_INT_SUBCLASS, 2331 USB_DEVICE_ID_MATCH_INT_SUBCLASS,
@@ -2166,7 +2339,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
2166 } 2339 }
2167}, 2340},
2168{ 2341{
2169 USB_DEVICE_VENDOR_SPEC(0x2040, 0x7202), 2342 USB_DEVICE_VENDOR_SPEC(0x2040, 0x7217),
2170 .match_flags = USB_DEVICE_ID_MATCH_DEVICE | 2343 .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
2171 USB_DEVICE_ID_MATCH_INT_CLASS | 2344 USB_DEVICE_ID_MATCH_INT_CLASS |
2172 USB_DEVICE_ID_MATCH_INT_SUBCLASS, 2345 USB_DEVICE_ID_MATCH_INT_SUBCLASS,
@@ -2180,7 +2353,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
2180 } 2353 }
2181}, 2354},
2182{ 2355{
2183 USB_DEVICE_VENDOR_SPEC(0x2040, 0x7203), 2356 USB_DEVICE_VENDOR_SPEC(0x2040, 0x721b),
2184 .match_flags = USB_DEVICE_ID_MATCH_DEVICE | 2357 .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
2185 USB_DEVICE_ID_MATCH_INT_CLASS | 2358 USB_DEVICE_ID_MATCH_INT_CLASS |
2186 USB_DEVICE_ID_MATCH_INT_SUBCLASS, 2359 USB_DEVICE_ID_MATCH_INT_SUBCLASS,
@@ -2194,7 +2367,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
2194 } 2367 }
2195}, 2368},
2196{ 2369{
2197 USB_DEVICE_VENDOR_SPEC(0x2040, 0x7204), 2370 USB_DEVICE_VENDOR_SPEC(0x2040, 0x721e),
2198 .match_flags = USB_DEVICE_ID_MATCH_DEVICE | 2371 .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
2199 USB_DEVICE_ID_MATCH_INT_CLASS | 2372 USB_DEVICE_ID_MATCH_INT_CLASS |
2200 USB_DEVICE_ID_MATCH_INT_SUBCLASS, 2373 USB_DEVICE_ID_MATCH_INT_SUBCLASS,
@@ -2208,7 +2381,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
2208 } 2381 }
2209}, 2382},
2210{ 2383{
2211 USB_DEVICE_VENDOR_SPEC(0x2040, 0x7205), 2384 USB_DEVICE_VENDOR_SPEC(0x2040, 0x721f),
2212 .match_flags = USB_DEVICE_ID_MATCH_DEVICE | 2385 .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
2213 USB_DEVICE_ID_MATCH_INT_CLASS | 2386 USB_DEVICE_ID_MATCH_INT_CLASS |
2214 USB_DEVICE_ID_MATCH_INT_SUBCLASS, 2387 USB_DEVICE_ID_MATCH_INT_SUBCLASS,
@@ -2222,7 +2395,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
2222 } 2395 }
2223}, 2396},
2224{ 2397{
2225 USB_DEVICE_VENDOR_SPEC(0x2040, 0x7250), 2398 USB_DEVICE_VENDOR_SPEC(0x2040, 0x7280),
2226 .match_flags = USB_DEVICE_ID_MATCH_DEVICE | 2399 .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
2227 USB_DEVICE_ID_MATCH_INT_CLASS | 2400 USB_DEVICE_ID_MATCH_INT_CLASS |
2228 USB_DEVICE_ID_MATCH_INT_SUBCLASS, 2401 USB_DEVICE_ID_MATCH_INT_SUBCLASS,
@@ -2236,7 +2409,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
2236 } 2409 }
2237}, 2410},
2238{ 2411{
2239 USB_DEVICE_VENDOR_SPEC(0x2040, 0x7230), 2412 USB_DEVICE_VENDOR_SPEC(0x0fd9, 0x0008),
2240 .match_flags = USB_DEVICE_ID_MATCH_DEVICE | 2413 .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
2241 USB_DEVICE_ID_MATCH_INT_CLASS | 2414 USB_DEVICE_ID_MATCH_INT_CLASS |
2242 USB_DEVICE_ID_MATCH_INT_SUBCLASS, 2415 USB_DEVICE_ID_MATCH_INT_SUBCLASS,
@@ -2244,7 +2417,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
2244 .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL, 2417 .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
2245 .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { 2418 .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
2246 .vendor_name = "Hauppauge", 2419 .vendor_name = "Hauppauge",
2247 .product_name = "HVR-850", 2420 .product_name = "HVR-950Q",
2248 .ifnum = QUIRK_ANY_INTERFACE, 2421 .ifnum = QUIRK_ANY_INTERFACE,
2249 .type = QUIRK_AUDIO_ALIGN_TRANSFER, 2422 .type = QUIRK_AUDIO_ALIGN_TRANSFER,
2250 } 2423 }
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index b45e54c09ba..9a9da09586a 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -32,6 +32,7 @@
32#include "helper.h" 32#include "helper.h"
33#include "endpoint.h" 33#include "endpoint.h"
34#include "pcm.h" 34#include "pcm.h"
35#include "clock.h"
35 36
36/* 37/*
37 * handle the quirks for the contained interfaces 38 * handle the quirks for the contained interfaces
diff --git a/sound/usb/urb.c b/sound/usb/urb.c
index de607d4411a..8deeaad10f1 100644
--- a/sound/usb/urb.c
+++ b/sound/usb/urb.c
@@ -244,7 +244,7 @@ int snd_usb_init_substream_urbs(struct snd_usb_substream *subs,
244 else 244 else
245 subs->curpacksize = maxsize; 245 subs->curpacksize = maxsize;
246 246
247 if (snd_usb_get_speed(subs->dev) == USB_SPEED_HIGH) 247 if (snd_usb_get_speed(subs->dev) != USB_SPEED_FULL)
248 packs_per_ms = 8 >> subs->datainterval; 248 packs_per_ms = 8 >> subs->datainterval;
249 else 249 else
250 packs_per_ms = 1; 250 packs_per_ms = 1;
diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c
index 2a528e56afd..3146a816068 100644
--- a/sound/usb/usx2y/usx2yhwdeppcm.c
+++ b/sound/usb/usx2y/usx2yhwdeppcm.c
@@ -54,7 +54,7 @@
54#include <linux/gfp.h> 54#include <linux/gfp.h>
55#include "usbusx2yaudio.c" 55#include "usbusx2yaudio.c"
56 56
57#if defined(USX2Y_NRPACKS_VARIABLE) || (!defined(USX2Y_NRPACKS_VARIABLE) && USX2Y_NRPACKS == 1) 57#if defined(USX2Y_NRPACKS_VARIABLE) || USX2Y_NRPACKS == 1
58 58
59#include <sound/hwdep.h> 59#include <sound/hwdep.h>
60 60