aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/aoa/codecs/onyx.c1
-rw-r--r--sound/aoa/codecs/tas.c1
-rw-r--r--sound/aoa/codecs/toonie.c1
-rw-r--r--sound/aoa/core/gpio-pmf.c10
-rw-r--r--sound/aoa/fabrics/layout.c3
-rw-r--r--sound/aoa/soundbus/core.c8
-rw-r--r--sound/aoa/soundbus/i2sbus/control.c3
-rw-r--r--sound/aoa/soundbus/i2sbus/core.c9
-rw-r--r--sound/aoa/soundbus/i2sbus/pcm.c1
-rw-r--r--sound/aoa/soundbus/sysfs.c4
-rw-r--r--sound/arm/aaci.c7
-rw-r--r--sound/arm/pxa2xx-pcm-lib.c1
-rw-r--r--sound/atmel/Kconfig2
-rw-r--r--sound/atmel/ac97c.c355
-rw-r--r--sound/core/control.c5
-rw-r--r--sound/core/control_compat.c1
-rw-r--r--sound/core/hrtimer.c1
-rw-r--r--sound/core/info.c75
-rw-r--r--sound/core/jack.c1
-rw-r--r--sound/core/misc.c1
-rw-r--r--sound/core/oss/mixer_oss.c5
-rw-r--r--sound/core/oss/pcm_oss.c5
-rw-r--r--sound/core/oss/route.c1
-rw-r--r--sound/core/pcm.c3
-rw-r--r--sound/core/pcm_compat.c1
-rw-r--r--sound/core/pcm_lib.c19
-rw-r--r--sound/core/pcm_memory.c1
-rw-r--r--sound/core/pcm_native.c109
-rw-r--r--sound/core/rawmidi.c5
-rw-r--r--sound/core/seq/oss/seq_oss_init.c1
-rw-r--r--sound/core/seq/oss/seq_oss_midi.c1
-rw-r--r--sound/core/seq/oss/seq_oss_readq.c1
-rw-r--r--sound/core/seq/oss/seq_oss_synth.c1
-rw-r--r--sound/core/seq/oss/seq_oss_timer.c1
-rw-r--r--sound/core/seq/oss/seq_oss_writeq.c1
-rw-r--r--sound/core/seq/seq_clientmgr.c6
-rw-r--r--sound/core/seq/seq_compat.c1
-rw-r--r--sound/core/seq/seq_system.c1
-rw-r--r--sound/core/sound.c73
-rw-r--r--sound/core/timer.c11
-rw-r--r--sound/drivers/ml403-ac97cr.c1
-rw-r--r--sound/drivers/mtpav.c1
-rw-r--r--sound/drivers/mts64.c1
-rw-r--r--sound/drivers/opl3/opl3_oss.c1
-rw-r--r--sound/drivers/opl3/opl3_synth.c1
-rw-r--r--sound/drivers/opl4/opl4_lib.c1
-rw-r--r--sound/drivers/opl4/opl4_proc.c83
-rw-r--r--sound/drivers/pcsp/pcsp.h2
-rw-r--r--sound/drivers/pcsp/pcsp_input.c4
-rw-r--r--sound/drivers/pcsp/pcsp_lib.c13
-rw-r--r--sound/drivers/portman2x4.c1
-rw-r--r--sound/drivers/vx/vx_hwdep.c1
-rw-r--r--sound/i2c/i2c.c18
-rw-r--r--sound/i2c/other/ak4113.c2
-rw-r--r--sound/i2c/other/tea575x-tuner.c1
-rw-r--r--sound/isa/Kconfig16
-rw-r--r--sound/isa/cmi8330.c1
-rw-r--r--sound/isa/cs423x/cs4236.c1
-rw-r--r--sound/isa/es1688/es1688.c225
-rw-r--r--sound/isa/es1688/es1688_lib.c47
-rw-r--r--sound/isa/es18xx.c1
-rw-r--r--sound/isa/gus/gus_mem_proc.c48
-rw-r--r--sound/isa/gus/gusextreme.c26
-rw-r--r--sound/isa/gus/interwave.c1
-rw-r--r--sound/isa/msnd/msnd_midi.c1
-rw-r--r--sound/isa/opl3sa2.c1
-rw-r--r--sound/isa/opti9xx/miro.c1
-rw-r--r--sound/isa/opti9xx/opti92x-ad1848.c1
-rw-r--r--sound/isa/sb/Makefile2
-rw-r--r--sound/isa/sb/emu8000_pcm.c1
-rw-r--r--sound/isa/sb/es968.c248
-rw-r--r--sound/isa/sb/sb16.c1
-rw-r--r--sound/isa/sb/sb8.c1
-rw-r--r--sound/isa/wavefront/wavefront.c1
-rw-r--r--sound/isa/wavefront/wavefront_fx.c1
-rw-r--r--sound/isa/wavefront/wavefront_synth.c1
-rw-r--r--sound/mips/au1x00.c1
-rw-r--r--sound/mips/hal2.c1
-rw-r--r--sound/mips/sgio2audio.c2
-rw-r--r--sound/oss/ad1848.c1
-rw-r--r--sound/oss/dmabuf.c1
-rw-r--r--sound/oss/dmasound/dmasound_atari.c5
-rw-r--r--sound/oss/dmasound/dmasound_paula.c51
-rw-r--r--sound/oss/kahlua.c1
-rw-r--r--sound/oss/mpu401.c1
-rw-r--r--sound/oss/msnd.c1
-rw-r--r--sound/oss/msnd_pinnacle.c2
-rw-r--r--sound/oss/opl3.c1
-rw-r--r--sound/oss/sb_card.c1
-rw-r--r--sound/oss/sb_common.c1
-rw-r--r--sound/oss/sb_midi.c1
-rw-r--r--sound/oss/sb_mixer.c2
-rw-r--r--sound/oss/soundcard.c1
-rw-r--r--sound/oss/uart401.c1
-rw-r--r--sound/oss/v_midi.c1
-rw-r--r--sound/oss/vidc.c5
-rw-r--r--sound/oss/vwsnd.c1
-rw-r--r--sound/oss/waveartist.c1
-rw-r--r--sound/pci/Kconfig32
-rw-r--r--sound/pci/Makefile1
-rw-r--r--sound/pci/ac97/ac97_patch.c2
-rw-r--r--sound/pci/ac97/ac97_proc.c1
-rw-r--r--sound/pci/als4000.c1
-rw-r--r--sound/pci/asihpi/Makefile5
-rw-r--r--sound/pci/asihpi/asihpi.c3002
-rw-r--r--sound/pci/asihpi/hpi.h2007
-rw-r--r--sound/pci/asihpi/hpi6000.c1838
-rw-r--r--sound/pci/asihpi/hpi6000.h70
-rw-r--r--sound/pci/asihpi/hpi6205.c2326
-rw-r--r--sound/pci/asihpi/hpi6205.h93
-rw-r--r--sound/pci/asihpi/hpi_internal.h1646
-rw-r--r--sound/pci/asihpi/hpicmn.c631
-rw-r--r--sound/pci/asihpi/hpicmn.h64
-rw-r--r--sound/pci/asihpi/hpidebug.c225
-rw-r--r--sound/pci/asihpi/hpidebug.h385
-rw-r--r--sound/pci/asihpi/hpidspcd.c172
-rw-r--r--sound/pci/asihpi/hpidspcd.h104
-rw-r--r--sound/pci/asihpi/hpifunc.c3877
-rw-r--r--sound/pci/asihpi/hpimsginit.c130
-rw-r--r--sound/pci/asihpi/hpimsginit.h40
-rw-r--r--sound/pci/asihpi/hpimsgx.c907
-rw-r--r--sound/pci/asihpi/hpimsgx.h36
-rw-r--r--sound/pci/asihpi/hpioctl.c484
-rw-r--r--sound/pci/asihpi/hpioctl.h38
-rw-r--r--sound/pci/asihpi/hpios.c91
-rw-r--r--sound/pci/asihpi/hpios.h169
-rw-r--r--sound/pci/asihpi/hpipcida.h37
-rw-r--r--sound/pci/aw2/aw2-alsa.c11
-rw-r--r--sound/pci/aw2/aw2-saa7146.c1
-rw-r--r--sound/pci/ca0106/ca0106_mixer.c1
-rw-r--r--sound/pci/ca0106/ca0106_proc.c1
-rw-r--r--sound/pci/cmipci.c14
-rw-r--r--sound/pci/cs4281.c40
-rw-r--r--sound/pci/cs46xx/cs46xx_lib.c19
-rw-r--r--sound/pci/cs5530.c1
-rw-r--r--sound/pci/cs5535audio/cs5535audio_pcm.c1
-rw-r--r--sound/pci/cs5535audio/cs5535audio_pm.c1
-rw-r--r--sound/pci/ctxfi/ctatc.c1
-rw-r--r--sound/pci/ctxfi/ctpcm.c1
-rw-r--r--sound/pci/echoaudio/darla20.c2
-rw-r--r--sound/pci/echoaudio/darla24.c2
-rw-r--r--sound/pci/echoaudio/echo3g.c2
-rw-r--r--sound/pci/echoaudio/echoaudio.c5
-rw-r--r--sound/pci/echoaudio/gina20.c2
-rw-r--r--sound/pci/echoaudio/gina24.c2
-rw-r--r--sound/pci/echoaudio/indigo.c2
-rw-r--r--sound/pci/echoaudio/indigodj.c2
-rw-r--r--sound/pci/echoaudio/indigodjx.c2
-rw-r--r--sound/pci/echoaudio/indigoio.c2
-rw-r--r--sound/pci/echoaudio/indigoiox.c2
-rw-r--r--sound/pci/echoaudio/layla20.c2
-rw-r--r--sound/pci/echoaudio/layla24.c2
-rw-r--r--sound/pci/echoaudio/mia.c2
-rw-r--r--sound/pci/echoaudio/mona.c2
-rw-r--r--sound/pci/emu10k1/emu10k1_main.c2
-rw-r--r--sound/pci/emu10k1/emufx.c36
-rw-r--r--sound/pci/emu10k1/emuproc.c51
-rw-r--r--sound/pci/emu10k1/memory.c1
-rw-r--r--sound/pci/es1968.c129
-rw-r--r--sound/pci/hda/Kconfig1
-rw-r--r--sound/pci/hda/hda_beep.c1
-rw-r--r--sound/pci/hda/hda_codec.c76
-rw-r--r--sound/pci/hda/hda_codec.h3
-rw-r--r--sound/pci/hda/hda_eld.c1
-rw-r--r--sound/pci/hda/hda_intel.c124
-rw-r--r--sound/pci/hda/hda_local.h2
-rw-r--r--sound/pci/hda/patch_analog.c38
-rw-r--r--sound/pci/hda/patch_cirrus.c2
-rw-r--r--sound/pci/hda/patch_conexant.c186
-rw-r--r--sound/pci/hda/patch_hdmi.c10
-rw-r--r--sound/pci/hda/patch_intelhdmi.c21
-rw-r--r--sound/pci/hda/patch_nvhdmi.c15
-rw-r--r--sound/pci/hda/patch_realtek.c653
-rw-r--r--sound/pci/hda/patch_sigmatel.c29
-rw-r--r--sound/pci/hda/patch_via.c41
-rw-r--r--sound/pci/ice1712/ak4xxx.c1
-rw-r--r--sound/pci/ice1712/amp.c1
-rw-r--r--sound/pci/ice1712/aureon.c89
-rw-r--r--sound/pci/ice1712/maya44.c6
-rw-r--r--sound/pci/ice1712/vt1720_mobo.c1
-rw-r--r--sound/pci/ice1712/wtm.c1
-rw-r--r--sound/pci/lx6464es/lx6464es.c1
-rw-r--r--sound/pci/maestro3.c148
-rw-r--r--sound/pci/mixart/mixart.c80
-rw-r--r--sound/pci/mixart/mixart_hwdep.c1
-rw-r--r--sound/pci/oxygen/oxygen_lib.c1
-rw-r--r--sound/pci/oxygen/xonar_cs43xx.c3
-rw-r--r--sound/pci/rme32.c2
-rw-r--r--sound/pci/rme96.c1
-rw-r--r--sound/pci/rme9652/hdsp.c1
-rw-r--r--sound/pci/rme9652/rme9652.c1
-rw-r--r--sound/pci/sis7019.c1
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf.c12
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf.h1
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf_core.c1
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c1
-rw-r--r--sound/pcmcia/vx/vxpocket.c11
-rw-r--r--sound/pcmcia/vx/vxpocket.h1
-rw-r--r--sound/ppc/burgundy.c1
-rw-r--r--sound/ppc/keywest.c1
-rw-r--r--sound/ppc/snd_ps3.c2
-rw-r--r--sound/ppc/tumbler.c12
-rw-r--r--sound/sh/sh_dac_audio.c1
-rw-r--r--sound/soc/au1x/psc-ac97.c1
-rw-r--r--sound/soc/au1x/psc-i2s.c1
-rw-r--r--sound/soc/blackfin/bf5xx-ac97-pcm.c2
-rw-r--r--sound/soc/blackfin/bf5xx-ac97.c1
-rw-r--r--sound/soc/blackfin/bf5xx-i2s-pcm.c2
-rw-r--r--sound/soc/blackfin/bf5xx-tdm-pcm.c2
-rw-r--r--sound/soc/codecs/ac97.c1
-rw-r--r--sound/soc/codecs/ad1836.c1
-rw-r--r--sound/soc/codecs/ad1980.c1
-rw-r--r--sound/soc/codecs/ad73311.c1
-rw-r--r--sound/soc/codecs/ads117x.c1
-rw-r--r--sound/soc/codecs/ak4104.c1
-rw-r--r--sound/soc/codecs/ak4535.c1
-rw-r--r--sound/soc/codecs/ak4642.c1
-rw-r--r--sound/soc/codecs/ak4671.c1
-rw-r--r--sound/soc/codecs/cs4270.c1
-rw-r--r--sound/soc/codecs/cx20442.c1
-rw-r--r--sound/soc/codecs/da7210.c1
-rw-r--r--sound/soc/codecs/pcm3008.c1
-rw-r--r--sound/soc/codecs/ssm2602.c1
-rw-r--r--sound/soc/codecs/stac9766.c1
-rw-r--r--sound/soc/codecs/tlv320aic23.c1
-rw-r--r--sound/soc/codecs/tlv320aic26.c1
-rw-r--r--sound/soc/codecs/tlv320aic3x.c1
-rw-r--r--sound/soc/codecs/tlv320dac33.c1
-rw-r--r--sound/soc/codecs/tpa6130a2.c1
-rw-r--r--sound/soc/codecs/twl4030.c1
-rw-r--r--sound/soc/codecs/uda134x.c1
-rw-r--r--sound/soc/codecs/wm2000.c1
-rw-r--r--sound/soc/codecs/wm8350.c1
-rw-r--r--sound/soc/codecs/wm8400.c1
-rw-r--r--sound/soc/codecs/wm8510.c1
-rw-r--r--sound/soc/codecs/wm8523.c1
-rw-r--r--sound/soc/codecs/wm8580.c1
-rw-r--r--sound/soc/codecs/wm8711.c1
-rw-r--r--sound/soc/codecs/wm8727.c1
-rw-r--r--sound/soc/codecs/wm8728.c1
-rw-r--r--sound/soc/codecs/wm8731.c1
-rw-r--r--sound/soc/codecs/wm8750.c1
-rw-r--r--sound/soc/codecs/wm8753.c1
-rw-r--r--sound/soc/codecs/wm8776.c1
-rw-r--r--sound/soc/codecs/wm8900.c1
-rw-r--r--sound/soc/codecs/wm8903.c1
-rw-r--r--sound/soc/codecs/wm8904.c1
-rw-r--r--sound/soc/codecs/wm8940.c1
-rw-r--r--sound/soc/codecs/wm8955.c1
-rw-r--r--sound/soc/codecs/wm8960.c1
-rw-r--r--sound/soc/codecs/wm8961.c1
-rw-r--r--sound/soc/codecs/wm8971.c1
-rw-r--r--sound/soc/codecs/wm8974.c1
-rw-r--r--sound/soc/codecs/wm8978.c1
-rw-r--r--sound/soc/codecs/wm8988.c1
-rw-r--r--sound/soc/codecs/wm8990.c1
-rw-r--r--sound/soc/codecs/wm8993.c1
-rw-r--r--sound/soc/codecs/wm8994.c1
-rw-r--r--sound/soc/codecs/wm9081.c1
-rw-r--r--sound/soc/codecs/wm9705.c1
-rw-r--r--sound/soc/codecs/wm9712.c1
-rw-r--r--sound/soc/codecs/wm9713.c1
-rw-r--r--sound/soc/davinci/davinci-i2s.c1
-rw-r--r--sound/soc/davinci/davinci-mcasp.c1
-rw-r--r--sound/soc/fsl/fsl_dma.c1
-rw-r--r--sound/soc/fsl/fsl_ssi.c1
-rw-r--r--sound/soc/fsl/mpc5200_dma.c7
-rw-r--r--sound/soc/fsl/mpc5200_psc_ac97.c2
-rw-r--r--sound/soc/fsl/mpc5200_psc_i2s.c4
-rw-r--r--sound/soc/fsl/mpc8610_hpcd.c11
-rw-r--r--sound/soc/fsl/soc-of-simple.c1
-rw-r--r--sound/soc/imx/imx-pcm-dma-mx2.c8
-rw-r--r--sound/soc/imx/imx-pcm-fiq.c1
-rw-r--r--sound/soc/imx/imx-ssi.c1
-rw-r--r--sound/soc/omap/mcpdm.c1
-rw-r--r--sound/soc/omap/omap-pcm.c1
-rw-r--r--sound/soc/pxa/Kconfig1
-rw-r--r--sound/soc/pxa/pxa-ssp.c136
-rw-r--r--sound/soc/s6000/s6000-i2s.c1
-rw-r--r--sound/soc/sh/dma-sh7760.c1
-rw-r--r--sound/soc/sh/fsi.c1
-rw-r--r--sound/soc/sh/siu.h3
-rw-r--r--sound/soc/sh/siu_dai.c3
-rw-r--r--sound/soc/sh/siu_pcm.c10
-rw-r--r--sound/soc/soc-core.c1
-rw-r--r--sound/soc/soc-dapm.c1
-rw-r--r--sound/soc/txx9/txx9aclc-ac97.c2
-rw-r--r--sound/soc/txx9/txx9aclc-generic.c1
-rw-r--r--sound/soc/txx9/txx9aclc.c8
-rw-r--r--sound/sound_firmware.c1
-rw-r--r--sound/sparc/amd7930.c7
-rw-r--r--sound/sparc/cs4231.c14
-rw-r--r--sound/sparc/dbri.c10
-rw-r--r--sound/synth/emux/emux_proc.c1
-rw-r--r--sound/usb/Kconfig4
-rw-r--r--sound/usb/Makefile26
-rw-r--r--sound/usb/caiaq/audio.c1
-rw-r--r--sound/usb/caiaq/control.c99
-rw-r--r--sound/usb/caiaq/device.c17
-rw-r--r--sound/usb/caiaq/device.h24
-rw-r--r--sound/usb/caiaq/input.c163
-rw-r--r--sound/usb/caiaq/midi.c1
-rw-r--r--sound/usb/card.c652
-rw-r--r--sound/usb/card.h105
-rw-r--r--sound/usb/debug.h15
-rw-r--r--sound/usb/endpoint.c394
-rw-r--r--sound/usb/endpoint.h11
-rw-r--r--sound/usb/format.c432
-rw-r--r--sound/usb/format.h9
-rw-r--r--sound/usb/helper.c113
-rw-r--r--sound/usb/helper.h32
-rw-r--r--sound/usb/midi.c (renamed from sound/usb/usbmidi.c)151
-rw-r--r--sound/usb/midi.h50
-rw-r--r--sound/usb/misc/Makefile2
-rw-r--r--sound/usb/misc/ua101.c (renamed from sound/usb/ua101.c)19
-rw-r--r--sound/usb/mixer.c (renamed from sound/usb/usbmixer.c)933
-rw-r--r--sound/usb/mixer.h55
-rw-r--r--sound/usb/mixer_maps.c (renamed from sound/usb/usbmixer_maps.c)4
-rw-r--r--sound/usb/mixer_quirks.c412
-rw-r--r--sound/usb/mixer_quirks.h13
-rw-r--r--sound/usb/pcm.c958
-rw-r--r--sound/usb/pcm.h14
-rw-r--r--sound/usb/proc.c168
-rw-r--r--sound/usb/proc.h8
-rw-r--r--sound/usb/quirks-table.h (renamed from sound/usb/usbquirks.h)79
-rw-r--r--sound/usb/quirks.c595
-rw-r--r--sound/usb/quirks.h23
-rw-r--r--sound/usb/urb.c995
-rw-r--r--sound/usb/urb.h21
-rw-r--r--sound/usb/usbaudio.c4050
-rw-r--r--sound/usb/usbaudio.h94
-rw-r--r--sound/usb/usx2y/us122l.c2
-rw-r--r--sound/usb/usx2y/usX2Yhwdep.c1
-rw-r--r--sound/usb/usx2y/usb_stream.c1
-rw-r--r--sound/usb/usx2y/usbusx2y.c1
-rw-r--r--sound/usb/usx2y/usbusx2y.h1
-rw-r--r--sound/usb/usx2y/usbusx2yaudio.c1
-rw-r--r--sound/usb/usx2y/usx2yhwdeppcm.c1
338 files changed, 26787 insertions, 6189 deletions
diff --git a/sound/aoa/codecs/onyx.c b/sound/aoa/codecs/onyx.c
index 84bb07d39a7f..91852e49910e 100644
--- a/sound/aoa/codecs/onyx.c
+++ b/sound/aoa/codecs/onyx.c
@@ -33,6 +33,7 @@
33 */ 33 */
34#include <linux/delay.h> 34#include <linux/delay.h>
35#include <linux/module.h> 35#include <linux/module.h>
36#include <linux/slab.h>
36MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>"); 37MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
37MODULE_LICENSE("GPL"); 38MODULE_LICENSE("GPL");
38MODULE_DESCRIPTION("pcm3052 (onyx) codec driver for snd-aoa"); 39MODULE_DESCRIPTION("pcm3052 (onyx) codec driver for snd-aoa");
diff --git a/sound/aoa/codecs/tas.c b/sound/aoa/codecs/tas.c
index 1dd66ddffcaf..fd2188c3df2b 100644
--- a/sound/aoa/codecs/tas.c
+++ b/sound/aoa/codecs/tas.c
@@ -66,6 +66,7 @@
66#include <linux/delay.h> 66#include <linux/delay.h>
67#include <linux/module.h> 67#include <linux/module.h>
68#include <linux/mutex.h> 68#include <linux/mutex.h>
69#include <linux/slab.h>
69 70
70MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>"); 71MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
71MODULE_LICENSE("GPL"); 72MODULE_LICENSE("GPL");
diff --git a/sound/aoa/codecs/toonie.c b/sound/aoa/codecs/toonie.c
index f13827e17562..69d2cb601f2a 100644
--- a/sound/aoa/codecs/toonie.c
+++ b/sound/aoa/codecs/toonie.c
@@ -11,6 +11,7 @@
11 */ 11 */
12#include <linux/delay.h> 12#include <linux/delay.h>
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/slab.h>
14MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>"); 15MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
15MODULE_LICENSE("GPL"); 16MODULE_LICENSE("GPL");
16MODULE_DESCRIPTION("toonie codec driver for snd-aoa"); 17MODULE_DESCRIPTION("toonie codec driver for snd-aoa");
diff --git a/sound/aoa/core/gpio-pmf.c b/sound/aoa/core/gpio-pmf.c
index 1dd0c28d1fb7..7e267c9379bc 100644
--- a/sound/aoa/core/gpio-pmf.c
+++ b/sound/aoa/core/gpio-pmf.c
@@ -6,6 +6,7 @@
6 * GPL v2, can be found in COPYING. 6 * GPL v2, can be found in COPYING.
7 */ 7 */
8 8
9#include <linux/slab.h>
9#include <asm/pmac_feature.h> 10#include <asm/pmac_feature.h>
10#include <asm/pmac_pfunc.h> 11#include <asm/pmac_pfunc.h>
11#include "../aoa.h" 12#include "../aoa.h"
@@ -115,12 +116,9 @@ static void pmf_gpio_exit(struct gpio_runtime *rt)
115 mutex_destroy(&rt->line_in_notify.mutex); 116 mutex_destroy(&rt->line_in_notify.mutex);
116 mutex_destroy(&rt->line_out_notify.mutex); 117 mutex_destroy(&rt->line_out_notify.mutex);
117 118
118 if (rt->headphone_notify.gpio_private) 119 kfree(rt->headphone_notify.gpio_private);
119 kfree(rt->headphone_notify.gpio_private); 120 kfree(rt->line_in_notify.gpio_private);
120 if (rt->line_in_notify.gpio_private) 121 kfree(rt->line_out_notify.gpio_private);
121 kfree(rt->line_in_notify.gpio_private);
122 if (rt->line_out_notify.gpio_private)
123 kfree(rt->line_out_notify.gpio_private);
124} 122}
125 123
126static void pmf_handle_notify_irq(void *data) 124static void pmf_handle_notify_irq(void *data)
diff --git a/sound/aoa/fabrics/layout.c b/sound/aoa/fabrics/layout.c
index 7a437da05646..3fd1a7e24928 100644
--- a/sound/aoa/fabrics/layout.c
+++ b/sound/aoa/fabrics/layout.c
@@ -12,6 +12,7 @@
12#include <asm/prom.h> 12#include <asm/prom.h>
13#include <linux/list.h> 13#include <linux/list.h>
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/slab.h>
15#include "../aoa.h" 16#include "../aoa.h"
16#include "../soundbus/soundbus.h" 17#include "../soundbus/soundbus.h"
17 18
@@ -991,7 +992,7 @@ static int aoa_fabric_layout_probe(struct soundbus_dev *sdev)
991 return -ENODEV; 992 return -ENODEV;
992 993
993 /* by breaking out we keep a reference */ 994 /* by breaking out we keep a reference */
994 while ((sound = of_get_next_child(sdev->ofdev.node, sound))) { 995 while ((sound = of_get_next_child(sdev->ofdev.dev.of_node, sound))) {
995 if (sound->type && strcasecmp(sound->type, "soundchip") == 0) 996 if (sound->type && strcasecmp(sound->type, "soundchip") == 0)
996 break; 997 break;
997 } 998 }
diff --git a/sound/aoa/soundbus/core.c b/sound/aoa/soundbus/core.c
index fa8ab2815a98..99ca7120e269 100644
--- a/sound/aoa/soundbus/core.c
+++ b/sound/aoa/soundbus/core.c
@@ -74,11 +74,11 @@ static int soundbus_uevent(struct device *dev, struct kobj_uevent_env *env)
74 of = &soundbus_dev->ofdev; 74 of = &soundbus_dev->ofdev;
75 75
76 /* stuff we want to pass to /sbin/hotplug */ 76 /* stuff we want to pass to /sbin/hotplug */
77 retval = add_uevent_var(env, "OF_NAME=%s", of->node->name); 77 retval = add_uevent_var(env, "OF_NAME=%s", of->dev.of_node->name);
78 if (retval) 78 if (retval)
79 return retval; 79 return retval;
80 80
81 retval = add_uevent_var(env, "OF_TYPE=%s", of->node->type); 81 retval = add_uevent_var(env, "OF_TYPE=%s", of->dev.of_node->type);
82 if (retval) 82 if (retval)
83 return retval; 83 return retval;
84 84
@@ -86,7 +86,7 @@ static int soundbus_uevent(struct device *dev, struct kobj_uevent_env *env)
86 * it's not really legal to split it out with commas. We split it 86 * it's not really legal to split it out with commas. We split it
87 * up using a number of environment variables instead. */ 87 * up using a number of environment variables instead. */
88 88
89 compat = of_get_property(of->node, "compatible", &cplen); 89 compat = of_get_property(of->dev.of_node, "compatible", &cplen);
90 while (compat && cplen > 0) { 90 while (compat && cplen > 0) {
91 int tmp = env->buflen; 91 int tmp = env->buflen;
92 retval = add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat); 92 retval = add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat);
@@ -169,7 +169,7 @@ int soundbus_add_one(struct soundbus_dev *dev)
169 169
170 /* sanity checks */ 170 /* sanity checks */
171 if (!dev->attach_codec || 171 if (!dev->attach_codec ||
172 !dev->ofdev.node || 172 !dev->ofdev.dev.of_node ||
173 dev->pcmname || 173 dev->pcmname ||
174 dev->pcmid != -1) { 174 dev->pcmid != -1) {
175 printk(KERN_ERR "soundbus: adding device failed sanity check!\n"); 175 printk(KERN_ERR "soundbus: adding device failed sanity check!\n");
diff --git a/sound/aoa/soundbus/i2sbus/control.c b/sound/aoa/soundbus/i2sbus/control.c
index 87beb4ad4d63..4dc9b49c02cf 100644
--- a/sound/aoa/soundbus/i2sbus/control.c
+++ b/sound/aoa/soundbus/i2sbus/control.c
@@ -8,6 +8,7 @@
8 8
9#include <linux/kernel.h> 9#include <linux/kernel.h>
10#include <linux/delay.h> 10#include <linux/delay.h>
11#include <linux/slab.h>
11 12
12#include <asm/io.h> 13#include <asm/io.h>
13#include <asm/prom.h> 14#include <asm/prom.h>
@@ -41,7 +42,7 @@ int i2sbus_control_add_dev(struct i2sbus_control *c,
41{ 42{
42 struct device_node *np; 43 struct device_node *np;
43 44
44 np = i2sdev->sound.ofdev.node; 45 np = i2sdev->sound.ofdev.dev.of_node;
45 i2sdev->enable = pmf_find_function(np, "enable"); 46 i2sdev->enable = pmf_find_function(np, "enable");
46 i2sdev->cell_enable = pmf_find_function(np, "cell-enable"); 47 i2sdev->cell_enable = pmf_find_function(np, "cell-enable");
47 i2sdev->clock_enable = pmf_find_function(np, "clock-enable"); 48 i2sdev->clock_enable = pmf_find_function(np, "clock-enable");
diff --git a/sound/aoa/soundbus/i2sbus/core.c b/sound/aoa/soundbus/i2sbus/core.c
index 4e3b819d4993..678933721735 100644
--- a/sound/aoa/soundbus/i2sbus/core.c
+++ b/sound/aoa/soundbus/i2sbus/core.c
@@ -7,6 +7,7 @@
7 */ 7 */
8 8
9#include <linux/module.h> 9#include <linux/module.h>
10#include <linux/slab.h>
10#include <linux/pci.h> 11#include <linux/pci.h>
11#include <linux/interrupt.h> 12#include <linux/interrupt.h>
12#include <linux/dma-mapping.h> 13#include <linux/dma-mapping.h>
@@ -220,9 +221,9 @@ static int i2sbus_add_dev(struct macio_dev *macio,
220 221
221 mutex_init(&dev->lock); 222 mutex_init(&dev->lock);
222 spin_lock_init(&dev->low_lock); 223 spin_lock_init(&dev->low_lock);
223 dev->sound.ofdev.node = np; 224 dev->sound.ofdev.archdata.dma_mask = macio->ofdev.archdata.dma_mask;
224 dev->sound.ofdev.dma_mask = macio->ofdev.dma_mask; 225 dev->sound.ofdev.dev.of_node = np;
225 dev->sound.ofdev.dev.dma_mask = &dev->sound.ofdev.dma_mask; 226 dev->sound.ofdev.dev.dma_mask = &dev->sound.ofdev.archdata.dma_mask;
226 dev->sound.ofdev.dev.parent = &macio->ofdev.dev; 227 dev->sound.ofdev.dev.parent = &macio->ofdev.dev;
227 dev->sound.ofdev.dev.release = i2sbus_release_dev; 228 dev->sound.ofdev.dev.release = i2sbus_release_dev;
228 dev->sound.attach_codec = i2sbus_attach_codec; 229 dev->sound.attach_codec = i2sbus_attach_codec;
@@ -345,7 +346,7 @@ static int i2sbus_probe(struct macio_dev* dev, const struct of_device_id *match)
345 return -ENODEV; 346 return -ENODEV;
346 } 347 }
347 348
348 while ((np = of_get_next_child(dev->ofdev.node, np))) { 349 while ((np = of_get_next_child(dev->ofdev.dev.of_node, np))) {
349 if (of_device_is_compatible(np, "i2sbus") || 350 if (of_device_is_compatible(np, "i2sbus") ||
350 of_device_is_compatible(np, "i2s-modem")) { 351 of_device_is_compatible(np, "i2s-modem")) {
351 got += i2sbus_add_dev(dev, control, np); 352 got += i2sbus_add_dev(dev, control, np);
diff --git a/sound/aoa/soundbus/i2sbus/pcm.c b/sound/aoa/soundbus/i2sbus/pcm.c
index 59bacd365733..be838993926d 100644
--- a/sound/aoa/soundbus/i2sbus/pcm.c
+++ b/sound/aoa/soundbus/i2sbus/pcm.c
@@ -8,6 +8,7 @@
8 8
9#include <asm/io.h> 9#include <asm/io.h>
10#include <linux/delay.h> 10#include <linux/delay.h>
11#include <linux/slab.h>
11#include <sound/core.h> 12#include <sound/core.h>
12#include <asm/macio.h> 13#include <asm/macio.h>
13#include <linux/pci.h> 14#include <linux/pci.h>
diff --git a/sound/aoa/soundbus/sysfs.c b/sound/aoa/soundbus/sysfs.c
index f580942b5c09..6496e754f00a 100644
--- a/sound/aoa/soundbus/sysfs.c
+++ b/sound/aoa/soundbus/sysfs.c
@@ -9,7 +9,7 @@ field##_show (struct device *dev, struct device_attribute *attr, \
9 char *buf) \ 9 char *buf) \
10{ \ 10{ \
11 struct soundbus_dev *mdev = to_soundbus_device (dev); \ 11 struct soundbus_dev *mdev = to_soundbus_device (dev); \
12 return sprintf (buf, format_string, mdev->ofdev.node->field); \ 12 return sprintf (buf, format_string, mdev->ofdev.dev.of_node->field); \
13} 13}
14 14
15static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, 15static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
@@ -25,7 +25,7 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
25 length = strlen(buf); 25 length = strlen(buf);
26 } else { 26 } else {
27 length = sprintf(buf, "of:N%sT%s\n", 27 length = sprintf(buf, "of:N%sT%s\n",
28 of->node->name, of->node->type); 28 of->dev.of_node->name, of->dev.of_node->type);
29 } 29 }
30 30
31 return length; 31 return length;
diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c
index 656e474dca47..91acc9a243ec 100644
--- a/sound/arm/aaci.c
+++ b/sound/arm/aaci.c
@@ -863,7 +863,6 @@ static int __devinit aaci_probe_ac97(struct aaci *aaci)
863 struct snd_ac97 *ac97; 863 struct snd_ac97 *ac97;
864 int ret; 864 int ret;
865 865
866 writel(0, aaci->base + AC97_POWERDOWN);
867 /* 866 /*
868 * Assert AACIRESET for 2us 867 * Assert AACIRESET for 2us
869 */ 868 */
@@ -1047,7 +1046,11 @@ static int __devinit aaci_probe(struct amba_device *dev, struct amba_id *id)
1047 1046
1048 writel(0x1fff, aaci->base + AACI_INTCLR); 1047 writel(0x1fff, aaci->base + AACI_INTCLR);
1049 writel(aaci->maincr, aaci->base + AACI_MAINCR); 1048 writel(aaci->maincr, aaci->base + AACI_MAINCR);
1050 1049 /*
1050 * Fix: ac97 read back fail errors by reading
1051 * from any arbitrary aaci register.
1052 */
1053 readl(aaci->base + AACI_CSCH1);
1051 ret = aaci_probe_ac97(aaci); 1054 ret = aaci_probe_ac97(aaci);
1052 if (ret) 1055 if (ret)
1053 goto out; 1056 goto out;
diff --git a/sound/arm/pxa2xx-pcm-lib.c b/sound/arm/pxa2xx-pcm-lib.c
index fd51fa8b06a1..8808b82311b1 100644
--- a/sound/arm/pxa2xx-pcm-lib.c
+++ b/sound/arm/pxa2xx-pcm-lib.c
@@ -4,6 +4,7 @@
4 * published by the Free Software Foundation. 4 * published by the Free Software Foundation.
5 */ 5 */
6 6
7#include <linux/slab.h>
7#include <linux/module.h> 8#include <linux/module.h>
8#include <linux/dma-mapping.h> 9#include <linux/dma-mapping.h>
9 10
diff --git a/sound/atmel/Kconfig b/sound/atmel/Kconfig
index 6c228a91940d..94de43a096f1 100644
--- a/sound/atmel/Kconfig
+++ b/sound/atmel/Kconfig
@@ -12,7 +12,7 @@ config SND_ATMEL_AC97C
12 tristate "Atmel AC97 Controller (AC97C) driver" 12 tristate "Atmel AC97 Controller (AC97C) driver"
13 select SND_PCM 13 select SND_PCM
14 select SND_AC97_CODEC 14 select SND_AC97_CODEC
15 depends on DW_DMAC && AVR32 15 depends on (DW_DMAC && AVR32) || ARCH_AT91
16 help 16 help
17 ALSA sound driver for the Atmel AC97 controller. 17 ALSA sound driver for the Atmel AC97 controller.
18 18
diff --git a/sound/atmel/ac97c.c b/sound/atmel/ac97c.c
index 0c0f8771656a..428121a7e705 100644
--- a/sound/atmel/ac97c.c
+++ b/sound/atmel/ac97c.c
@@ -13,6 +13,7 @@
13#include <linux/device.h> 13#include <linux/device.h>
14#include <linux/dmaengine.h> 14#include <linux/dmaengine.h>
15#include <linux/dma-mapping.h> 15#include <linux/dma-mapping.h>
16#include <linux/atmel_pdc.h>
16#include <linux/init.h> 17#include <linux/init.h>
17#include <linux/interrupt.h> 18#include <linux/interrupt.h>
18#include <linux/module.h> 19#include <linux/module.h>
@@ -31,6 +32,10 @@
31 32
32#include <linux/dw_dmac.h> 33#include <linux/dw_dmac.h>
33 34
35#include <mach/cpu.h>
36#include <mach/hardware.h>
37#include <mach/gpio.h>
38
34#include "ac97c.h" 39#include "ac97c.h"
35 40
36enum { 41enum {
@@ -63,6 +68,7 @@ struct atmel_ac97c {
63 u64 cur_format; 68 u64 cur_format;
64 unsigned int cur_rate; 69 unsigned int cur_rate;
65 unsigned long flags; 70 unsigned long flags;
71 int playback_period, capture_period;
66 /* Serialize access to opened variable */ 72 /* Serialize access to opened variable */
67 spinlock_t lock; 73 spinlock_t lock;
68 void __iomem *regs; 74 void __iomem *regs;
@@ -242,10 +248,12 @@ static int atmel_ac97c_playback_hw_params(struct snd_pcm_substream *substream,
242 if (retval < 0) 248 if (retval < 0)
243 return retval; 249 return retval;
244 /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */ 250 /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */
245 if (retval == 1) 251 if (cpu_is_at32ap7000()) {
246 if (test_and_clear_bit(DMA_TX_READY, &chip->flags)) 252 /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */
247 dw_dma_cyclic_free(chip->dma.tx_chan); 253 if (retval == 1)
248 254 if (test_and_clear_bit(DMA_TX_READY, &chip->flags))
255 dw_dma_cyclic_free(chip->dma.tx_chan);
256 }
249 /* Set restrictions to params. */ 257 /* Set restrictions to params. */
250 mutex_lock(&opened_mutex); 258 mutex_lock(&opened_mutex);
251 chip->cur_rate = params_rate(hw_params); 259 chip->cur_rate = params_rate(hw_params);
@@ -266,9 +274,14 @@ static int atmel_ac97c_capture_hw_params(struct snd_pcm_substream *substream,
266 if (retval < 0) 274 if (retval < 0)
267 return retval; 275 return retval;
268 /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */ 276 /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */
269 if (retval == 1) 277 if (cpu_is_at32ap7000()) {
270 if (test_and_clear_bit(DMA_RX_READY, &chip->flags)) 278 if (retval < 0)
271 dw_dma_cyclic_free(chip->dma.rx_chan); 279 return retval;
280 /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */
281 if (retval == 1)
282 if (test_and_clear_bit(DMA_RX_READY, &chip->flags))
283 dw_dma_cyclic_free(chip->dma.rx_chan);
284 }
272 285
273 /* Set restrictions to params. */ 286 /* Set restrictions to params. */
274 mutex_lock(&opened_mutex); 287 mutex_lock(&opened_mutex);
@@ -282,16 +295,20 @@ static int atmel_ac97c_capture_hw_params(struct snd_pcm_substream *substream,
282static int atmel_ac97c_playback_hw_free(struct snd_pcm_substream *substream) 295static int atmel_ac97c_playback_hw_free(struct snd_pcm_substream *substream)
283{ 296{
284 struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); 297 struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
285 if (test_and_clear_bit(DMA_TX_READY, &chip->flags)) 298 if (cpu_is_at32ap7000()) {
286 dw_dma_cyclic_free(chip->dma.tx_chan); 299 if (test_and_clear_bit(DMA_TX_READY, &chip->flags))
300 dw_dma_cyclic_free(chip->dma.tx_chan);
301 }
287 return snd_pcm_lib_free_pages(substream); 302 return snd_pcm_lib_free_pages(substream);
288} 303}
289 304
290static int atmel_ac97c_capture_hw_free(struct snd_pcm_substream *substream) 305static int atmel_ac97c_capture_hw_free(struct snd_pcm_substream *substream)
291{ 306{
292 struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); 307 struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
293 if (test_and_clear_bit(DMA_RX_READY, &chip->flags)) 308 if (cpu_is_at32ap7000()) {
294 dw_dma_cyclic_free(chip->dma.rx_chan); 309 if (test_and_clear_bit(DMA_RX_READY, &chip->flags))
310 dw_dma_cyclic_free(chip->dma.rx_chan);
311 }
295 return snd_pcm_lib_free_pages(substream); 312 return snd_pcm_lib_free_pages(substream);
296} 313}
297 314
@@ -299,9 +316,11 @@ static int atmel_ac97c_playback_prepare(struct snd_pcm_substream *substream)
299{ 316{
300 struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); 317 struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
301 struct snd_pcm_runtime *runtime = substream->runtime; 318 struct snd_pcm_runtime *runtime = substream->runtime;
319 int block_size = frames_to_bytes(runtime, runtime->period_size);
302 unsigned long word = ac97c_readl(chip, OCA); 320 unsigned long word = ac97c_readl(chip, OCA);
303 int retval; 321 int retval;
304 322
323 chip->playback_period = 0;
305 word &= ~(AC97C_CH_MASK(PCM_LEFT) | AC97C_CH_MASK(PCM_RIGHT)); 324 word &= ~(AC97C_CH_MASK(PCM_LEFT) | AC97C_CH_MASK(PCM_RIGHT));
306 325
307 /* assign channels to AC97C channel A */ 326 /* assign channels to AC97C channel A */
@@ -320,11 +339,16 @@ static int atmel_ac97c_playback_prepare(struct snd_pcm_substream *substream)
320 ac97c_writel(chip, OCA, word); 339 ac97c_writel(chip, OCA, word);
321 340
322 /* configure sample format and size */ 341 /* configure sample format and size */
323 word = AC97C_CMR_DMAEN | AC97C_CMR_SIZE_16; 342 word = ac97c_readl(chip, CAMR);
343 if (chip->opened <= 1)
344 word = AC97C_CMR_DMAEN | AC97C_CMR_SIZE_16;
345 else
346 word |= AC97C_CMR_DMAEN | AC97C_CMR_SIZE_16;
324 347
325 switch (runtime->format) { 348 switch (runtime->format) {
326 case SNDRV_PCM_FORMAT_S16_LE: 349 case SNDRV_PCM_FORMAT_S16_LE:
327 word |= AC97C_CMR_CEM_LITTLE; 350 if (cpu_is_at32ap7000())
351 word |= AC97C_CMR_CEM_LITTLE;
328 break; 352 break;
329 case SNDRV_PCM_FORMAT_S16_BE: /* fall through */ 353 case SNDRV_PCM_FORMAT_S16_BE: /* fall through */
330 word &= ~(AC97C_CMR_CEM_LITTLE); 354 word &= ~(AC97C_CMR_CEM_LITTLE);
@@ -363,9 +387,18 @@ static int atmel_ac97c_playback_prepare(struct snd_pcm_substream *substream)
363 dev_dbg(&chip->pdev->dev, "could not set rate %d Hz\n", 387 dev_dbg(&chip->pdev->dev, "could not set rate %d Hz\n",
364 runtime->rate); 388 runtime->rate);
365 389
366 if (!test_bit(DMA_TX_READY, &chip->flags)) 390 if (cpu_is_at32ap7000()) {
367 retval = atmel_ac97c_prepare_dma(chip, substream, 391 if (!test_bit(DMA_TX_READY, &chip->flags))
368 DMA_TO_DEVICE); 392 retval = atmel_ac97c_prepare_dma(chip, substream,
393 DMA_TO_DEVICE);
394 } else {
395 /* Initialize and start the PDC */
396 writel(runtime->dma_addr, chip->regs + ATMEL_PDC_TPR);
397 writel(block_size / 2, chip->regs + ATMEL_PDC_TCR);
398 writel(runtime->dma_addr + block_size,
399 chip->regs + ATMEL_PDC_TNPR);
400 writel(block_size / 2, chip->regs + ATMEL_PDC_TNCR);
401 }
369 402
370 return retval; 403 return retval;
371} 404}
@@ -374,9 +407,11 @@ static int atmel_ac97c_capture_prepare(struct snd_pcm_substream *substream)
374{ 407{
375 struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); 408 struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
376 struct snd_pcm_runtime *runtime = substream->runtime; 409 struct snd_pcm_runtime *runtime = substream->runtime;
410 int block_size = frames_to_bytes(runtime, runtime->period_size);
377 unsigned long word = ac97c_readl(chip, ICA); 411 unsigned long word = ac97c_readl(chip, ICA);
378 int retval; 412 int retval;
379 413
414 chip->capture_period = 0;
380 word &= ~(AC97C_CH_MASK(PCM_LEFT) | AC97C_CH_MASK(PCM_RIGHT)); 415 word &= ~(AC97C_CH_MASK(PCM_LEFT) | AC97C_CH_MASK(PCM_RIGHT));
381 416
382 /* assign channels to AC97C channel A */ 417 /* assign channels to AC97C channel A */
@@ -395,11 +430,16 @@ static int atmel_ac97c_capture_prepare(struct snd_pcm_substream *substream)
395 ac97c_writel(chip, ICA, word); 430 ac97c_writel(chip, ICA, word);
396 431
397 /* configure sample format and size */ 432 /* configure sample format and size */
398 word = AC97C_CMR_DMAEN | AC97C_CMR_SIZE_16; 433 word = ac97c_readl(chip, CAMR);
434 if (chip->opened <= 1)
435 word = AC97C_CMR_DMAEN | AC97C_CMR_SIZE_16;
436 else
437 word |= AC97C_CMR_DMAEN | AC97C_CMR_SIZE_16;
399 438
400 switch (runtime->format) { 439 switch (runtime->format) {
401 case SNDRV_PCM_FORMAT_S16_LE: 440 case SNDRV_PCM_FORMAT_S16_LE:
402 word |= AC97C_CMR_CEM_LITTLE; 441 if (cpu_is_at32ap7000())
442 word |= AC97C_CMR_CEM_LITTLE;
403 break; 443 break;
404 case SNDRV_PCM_FORMAT_S16_BE: /* fall through */ 444 case SNDRV_PCM_FORMAT_S16_BE: /* fall through */
405 word &= ~(AC97C_CMR_CEM_LITTLE); 445 word &= ~(AC97C_CMR_CEM_LITTLE);
@@ -438,9 +478,18 @@ static int atmel_ac97c_capture_prepare(struct snd_pcm_substream *substream)
438 dev_dbg(&chip->pdev->dev, "could not set rate %d Hz\n", 478 dev_dbg(&chip->pdev->dev, "could not set rate %d Hz\n",
439 runtime->rate); 479 runtime->rate);
440 480
441 if (!test_bit(DMA_RX_READY, &chip->flags)) 481 if (cpu_is_at32ap7000()) {
442 retval = atmel_ac97c_prepare_dma(chip, substream, 482 if (!test_bit(DMA_RX_READY, &chip->flags))
443 DMA_FROM_DEVICE); 483 retval = atmel_ac97c_prepare_dma(chip, substream,
484 DMA_FROM_DEVICE);
485 } else {
486 /* Initialize and start the PDC */
487 writel(runtime->dma_addr, chip->regs + ATMEL_PDC_RPR);
488 writel(block_size / 2, chip->regs + ATMEL_PDC_RCR);
489 writel(runtime->dma_addr + block_size,
490 chip->regs + ATMEL_PDC_RNPR);
491 writel(block_size / 2, chip->regs + ATMEL_PDC_RNCR);
492 }
444 493
445 return retval; 494 return retval;
446} 495}
@@ -449,7 +498,7 @@ static int
449atmel_ac97c_playback_trigger(struct snd_pcm_substream *substream, int cmd) 498atmel_ac97c_playback_trigger(struct snd_pcm_substream *substream, int cmd)
450{ 499{
451 struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); 500 struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
452 unsigned long camr; 501 unsigned long camr, ptcr = 0;
453 int retval = 0; 502 int retval = 0;
454 503
455 camr = ac97c_readl(chip, CAMR); 504 camr = ac97c_readl(chip, CAMR);
@@ -458,15 +507,22 @@ atmel_ac97c_playback_trigger(struct snd_pcm_substream *substream, int cmd)
458 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */ 507 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */
459 case SNDRV_PCM_TRIGGER_RESUME: /* fall through */ 508 case SNDRV_PCM_TRIGGER_RESUME: /* fall through */
460 case SNDRV_PCM_TRIGGER_START: 509 case SNDRV_PCM_TRIGGER_START:
461 retval = dw_dma_cyclic_start(chip->dma.tx_chan); 510 if (cpu_is_at32ap7000()) {
462 if (retval) 511 retval = dw_dma_cyclic_start(chip->dma.tx_chan);
463 goto out; 512 if (retval)
464 camr |= AC97C_CMR_CENA; 513 goto out;
514 } else {
515 ptcr = ATMEL_PDC_TXTEN;
516 }
517 camr |= AC97C_CMR_CENA | AC97C_CSR_ENDTX;
465 break; 518 break;
466 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* fall through */ 519 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* fall through */
467 case SNDRV_PCM_TRIGGER_SUSPEND: /* fall through */ 520 case SNDRV_PCM_TRIGGER_SUSPEND: /* fall through */
468 case SNDRV_PCM_TRIGGER_STOP: 521 case SNDRV_PCM_TRIGGER_STOP:
469 dw_dma_cyclic_stop(chip->dma.tx_chan); 522 if (cpu_is_at32ap7000())
523 dw_dma_cyclic_stop(chip->dma.tx_chan);
524 else
525 ptcr |= ATMEL_PDC_TXTDIS;
470 if (chip->opened <= 1) 526 if (chip->opened <= 1)
471 camr &= ~AC97C_CMR_CENA; 527 camr &= ~AC97C_CMR_CENA;
472 break; 528 break;
@@ -476,6 +532,8 @@ atmel_ac97c_playback_trigger(struct snd_pcm_substream *substream, int cmd)
476 } 532 }
477 533
478 ac97c_writel(chip, CAMR, camr); 534 ac97c_writel(chip, CAMR, camr);
535 if (!cpu_is_at32ap7000())
536 writel(ptcr, chip->regs + ATMEL_PDC_PTCR);
479out: 537out:
480 return retval; 538 return retval;
481} 539}
@@ -484,24 +542,32 @@ static int
484atmel_ac97c_capture_trigger(struct snd_pcm_substream *substream, int cmd) 542atmel_ac97c_capture_trigger(struct snd_pcm_substream *substream, int cmd)
485{ 543{
486 struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); 544 struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
487 unsigned long camr; 545 unsigned long camr, ptcr = 0;
488 int retval = 0; 546 int retval = 0;
489 547
490 camr = ac97c_readl(chip, CAMR); 548 camr = ac97c_readl(chip, CAMR);
549 ptcr = readl(chip->regs + ATMEL_PDC_PTSR);
491 550
492 switch (cmd) { 551 switch (cmd) {
493 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */ 552 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */
494 case SNDRV_PCM_TRIGGER_RESUME: /* fall through */ 553 case SNDRV_PCM_TRIGGER_RESUME: /* fall through */
495 case SNDRV_PCM_TRIGGER_START: 554 case SNDRV_PCM_TRIGGER_START:
496 retval = dw_dma_cyclic_start(chip->dma.rx_chan); 555 if (cpu_is_at32ap7000()) {
497 if (retval) 556 retval = dw_dma_cyclic_start(chip->dma.rx_chan);
498 goto out; 557 if (retval)
499 camr |= AC97C_CMR_CENA; 558 goto out;
559 } else {
560 ptcr = ATMEL_PDC_RXTEN;
561 }
562 camr |= AC97C_CMR_CENA | AC97C_CSR_ENDRX;
500 break; 563 break;
501 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* fall through */ 564 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* fall through */
502 case SNDRV_PCM_TRIGGER_SUSPEND: /* fall through */ 565 case SNDRV_PCM_TRIGGER_SUSPEND: /* fall through */
503 case SNDRV_PCM_TRIGGER_STOP: 566 case SNDRV_PCM_TRIGGER_STOP:
504 dw_dma_cyclic_stop(chip->dma.rx_chan); 567 if (cpu_is_at32ap7000())
568 dw_dma_cyclic_stop(chip->dma.rx_chan);
569 else
570 ptcr |= (ATMEL_PDC_RXTDIS);
505 if (chip->opened <= 1) 571 if (chip->opened <= 1)
506 camr &= ~AC97C_CMR_CENA; 572 camr &= ~AC97C_CMR_CENA;
507 break; 573 break;
@@ -511,6 +577,8 @@ atmel_ac97c_capture_trigger(struct snd_pcm_substream *substream, int cmd)
511 } 577 }
512 578
513 ac97c_writel(chip, CAMR, camr); 579 ac97c_writel(chip, CAMR, camr);
580 if (!cpu_is_at32ap7000())
581 writel(ptcr, chip->regs + ATMEL_PDC_PTCR);
514out: 582out:
515 return retval; 583 return retval;
516} 584}
@@ -523,7 +591,10 @@ atmel_ac97c_playback_pointer(struct snd_pcm_substream *substream)
523 snd_pcm_uframes_t frames; 591 snd_pcm_uframes_t frames;
524 unsigned long bytes; 592 unsigned long bytes;
525 593
526 bytes = dw_dma_get_src_addr(chip->dma.tx_chan); 594 if (cpu_is_at32ap7000())
595 bytes = dw_dma_get_src_addr(chip->dma.tx_chan);
596 else
597 bytes = readl(chip->regs + ATMEL_PDC_TPR);
527 bytes -= runtime->dma_addr; 598 bytes -= runtime->dma_addr;
528 599
529 frames = bytes_to_frames(runtime, bytes); 600 frames = bytes_to_frames(runtime, bytes);
@@ -540,7 +611,10 @@ atmel_ac97c_capture_pointer(struct snd_pcm_substream *substream)
540 snd_pcm_uframes_t frames; 611 snd_pcm_uframes_t frames;
541 unsigned long bytes; 612 unsigned long bytes;
542 613
543 bytes = dw_dma_get_dst_addr(chip->dma.rx_chan); 614 if (cpu_is_at32ap7000())
615 bytes = dw_dma_get_dst_addr(chip->dma.rx_chan);
616 else
617 bytes = readl(chip->regs + ATMEL_PDC_RPR);
544 bytes -= runtime->dma_addr; 618 bytes -= runtime->dma_addr;
545 619
546 frames = bytes_to_frames(runtime, bytes); 620 frames = bytes_to_frames(runtime, bytes);
@@ -578,8 +652,11 @@ static irqreturn_t atmel_ac97c_interrupt(int irq, void *dev)
578 u32 sr = ac97c_readl(chip, SR); 652 u32 sr = ac97c_readl(chip, SR);
579 u32 casr = ac97c_readl(chip, CASR); 653 u32 casr = ac97c_readl(chip, CASR);
580 u32 cosr = ac97c_readl(chip, COSR); 654 u32 cosr = ac97c_readl(chip, COSR);
655 u32 camr = ac97c_readl(chip, CAMR);
581 656
582 if (sr & AC97C_SR_CAEVT) { 657 if (sr & AC97C_SR_CAEVT) {
658 struct snd_pcm_runtime *runtime;
659 int offset, next_period, block_size;
583 dev_info(&chip->pdev->dev, "channel A event%s%s%s%s%s%s\n", 660 dev_info(&chip->pdev->dev, "channel A event%s%s%s%s%s%s\n",
584 casr & AC97C_CSR_OVRUN ? " OVRUN" : "", 661 casr & AC97C_CSR_OVRUN ? " OVRUN" : "",
585 casr & AC97C_CSR_RXRDY ? " RXRDY" : "", 662 casr & AC97C_CSR_RXRDY ? " RXRDY" : "",
@@ -587,6 +664,50 @@ static irqreturn_t atmel_ac97c_interrupt(int irq, void *dev)
587 casr & AC97C_CSR_TXEMPTY ? " TXEMPTY" : "", 664 casr & AC97C_CSR_TXEMPTY ? " TXEMPTY" : "",
588 casr & AC97C_CSR_TXRDY ? " TXRDY" : "", 665 casr & AC97C_CSR_TXRDY ? " TXRDY" : "",
589 !casr ? " NONE" : ""); 666 !casr ? " NONE" : "");
667 if (!cpu_is_at32ap7000()) {
668 if ((casr & camr) & AC97C_CSR_ENDTX) {
669 runtime = chip->playback_substream->runtime;
670 block_size = frames_to_bytes(runtime,
671 runtime->period_size);
672 chip->playback_period++;
673
674 if (chip->playback_period == runtime->periods)
675 chip->playback_period = 0;
676 next_period = chip->playback_period + 1;
677 if (next_period == runtime->periods)
678 next_period = 0;
679
680 offset = block_size * next_period;
681
682 writel(runtime->dma_addr + offset,
683 chip->regs + ATMEL_PDC_TNPR);
684 writel(block_size / 2,
685 chip->regs + ATMEL_PDC_TNCR);
686
687 snd_pcm_period_elapsed(
688 chip->playback_substream);
689 }
690 if ((casr & camr) & AC97C_CSR_ENDRX) {
691 runtime = chip->capture_substream->runtime;
692 block_size = frames_to_bytes(runtime,
693 runtime->period_size);
694 chip->capture_period++;
695
696 if (chip->capture_period == runtime->periods)
697 chip->capture_period = 0;
698 next_period = chip->capture_period + 1;
699 if (next_period == runtime->periods)
700 next_period = 0;
701
702 offset = block_size * next_period;
703
704 writel(runtime->dma_addr + offset,
705 chip->regs + ATMEL_PDC_RNPR);
706 writel(block_size / 2,
707 chip->regs + ATMEL_PDC_RNCR);
708 snd_pcm_period_elapsed(chip->capture_substream);
709 }
710 }
590 retval = IRQ_HANDLED; 711 retval = IRQ_HANDLED;
591 } 712 }
592 713
@@ -608,15 +729,50 @@ static irqreturn_t atmel_ac97c_interrupt(int irq, void *dev)
608 return retval; 729 return retval;
609} 730}
610 731
732static struct ac97_pcm at91_ac97_pcm_defs[] __devinitdata = {
733 /* Playback */
734 {
735 .exclusive = 1,
736 .r = { {
737 .slots = ((1 << AC97_SLOT_PCM_LEFT)
738 | (1 << AC97_SLOT_PCM_RIGHT)),
739 } },
740 },
741 /* PCM in */
742 {
743 .stream = 1,
744 .exclusive = 1,
745 .r = { {
746 .slots = ((1 << AC97_SLOT_PCM_LEFT)
747 | (1 << AC97_SLOT_PCM_RIGHT)),
748 } }
749 },
750 /* Mic in */
751 {
752 .stream = 1,
753 .exclusive = 1,
754 .r = { {
755 .slots = (1<<AC97_SLOT_MIC),
756 } }
757 },
758};
759
611static int __devinit atmel_ac97c_pcm_new(struct atmel_ac97c *chip) 760static int __devinit atmel_ac97c_pcm_new(struct atmel_ac97c *chip)
612{ 761{
613 struct snd_pcm *pcm; 762 struct snd_pcm *pcm;
614 struct snd_pcm_hardware hw = atmel_ac97c_hw; 763 struct snd_pcm_hardware hw = atmel_ac97c_hw;
615 int capture, playback, retval; 764 int capture, playback, retval, err;
616 765
617 capture = test_bit(DMA_RX_CHAN_PRESENT, &chip->flags); 766 capture = test_bit(DMA_RX_CHAN_PRESENT, &chip->flags);
618 playback = test_bit(DMA_TX_CHAN_PRESENT, &chip->flags); 767 playback = test_bit(DMA_TX_CHAN_PRESENT, &chip->flags);
619 768
769 if (!cpu_is_at32ap7000()) {
770 err = snd_ac97_pcm_assign(chip->ac97_bus,
771 ARRAY_SIZE(at91_ac97_pcm_defs),
772 at91_ac97_pcm_defs);
773 if (err)
774 return err;
775 }
620 retval = snd_pcm_new(chip->card, chip->card->shortname, 776 retval = snd_pcm_new(chip->card, chip->card->shortname,
621 chip->pdev->id, playback, capture, &pcm); 777 chip->pdev->id, playback, capture, &pcm);
622 if (retval) 778 if (retval)
@@ -775,7 +931,12 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev)
775 return -ENXIO; 931 return -ENXIO;
776 } 932 }
777 933
778 pclk = clk_get(&pdev->dev, "pclk"); 934 if (cpu_is_at32ap7000()) {
935 pclk = clk_get(&pdev->dev, "pclk");
936 } else {
937 pclk = clk_get(&pdev->dev, "ac97_clk");
938 }
939
779 if (IS_ERR(pclk)) { 940 if (IS_ERR(pclk)) {
780 dev_dbg(&pdev->dev, "no peripheral clock\n"); 941 dev_dbg(&pdev->dev, "no peripheral clock\n");
781 return PTR_ERR(pclk); 942 return PTR_ERR(pclk);
@@ -844,43 +1005,52 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev)
844 goto err_ac97_bus; 1005 goto err_ac97_bus;
845 } 1006 }
846 1007
847 if (pdata->rx_dws.dma_dev) { 1008 if (cpu_is_at32ap7000()) {
848 struct dw_dma_slave *dws = &pdata->rx_dws; 1009 if (pdata->rx_dws.dma_dev) {
849 dma_cap_mask_t mask; 1010 struct dw_dma_slave *dws = &pdata->rx_dws;
1011 dma_cap_mask_t mask;
850 1012
851 dws->rx_reg = regs->start + AC97C_CARHR + 2; 1013 dws->rx_reg = regs->start + AC97C_CARHR + 2;
852 1014
853 dma_cap_zero(mask); 1015 dma_cap_zero(mask);
854 dma_cap_set(DMA_SLAVE, mask); 1016 dma_cap_set(DMA_SLAVE, mask);
855 1017
856 chip->dma.rx_chan = dma_request_channel(mask, filter, dws); 1018 chip->dma.rx_chan = dma_request_channel(mask, filter,
1019 dws);
857 1020
858 dev_info(&chip->pdev->dev, "using %s for DMA RX\n", 1021 dev_info(&chip->pdev->dev, "using %s for DMA RX\n",
859 dev_name(&chip->dma.rx_chan->dev->device)); 1022 dev_name(&chip->dma.rx_chan->dev->device));
860 set_bit(DMA_RX_CHAN_PRESENT, &chip->flags); 1023 set_bit(DMA_RX_CHAN_PRESENT, &chip->flags);
861 } 1024 }
862 1025
863 if (pdata->tx_dws.dma_dev) { 1026 if (pdata->tx_dws.dma_dev) {
864 struct dw_dma_slave *dws = &pdata->tx_dws; 1027 struct dw_dma_slave *dws = &pdata->tx_dws;
865 dma_cap_mask_t mask; 1028 dma_cap_mask_t mask;
866 1029
867 dws->tx_reg = regs->start + AC97C_CATHR + 2; 1030 dws->tx_reg = regs->start + AC97C_CATHR + 2;
868 1031
869 dma_cap_zero(mask); 1032 dma_cap_zero(mask);
870 dma_cap_set(DMA_SLAVE, mask); 1033 dma_cap_set(DMA_SLAVE, mask);
871 1034
872 chip->dma.tx_chan = dma_request_channel(mask, filter, dws); 1035 chip->dma.tx_chan = dma_request_channel(mask, filter,
1036 dws);
873 1037
874 dev_info(&chip->pdev->dev, "using %s for DMA TX\n", 1038 dev_info(&chip->pdev->dev, "using %s for DMA TX\n",
875 dev_name(&chip->dma.tx_chan->dev->device)); 1039 dev_name(&chip->dma.tx_chan->dev->device));
876 set_bit(DMA_TX_CHAN_PRESENT, &chip->flags); 1040 set_bit(DMA_TX_CHAN_PRESENT, &chip->flags);
877 } 1041 }
878 1042
879 if (!test_bit(DMA_RX_CHAN_PRESENT, &chip->flags) && 1043 if (!test_bit(DMA_RX_CHAN_PRESENT, &chip->flags) &&
880 !test_bit(DMA_TX_CHAN_PRESENT, &chip->flags)) { 1044 !test_bit(DMA_TX_CHAN_PRESENT, &chip->flags)) {
881 dev_dbg(&pdev->dev, "DMA not available\n"); 1045 dev_dbg(&pdev->dev, "DMA not available\n");
882 retval = -ENODEV; 1046 retval = -ENODEV;
883 goto err_dma; 1047 goto err_dma;
1048 }
1049 } else {
1050 /* Just pretend that we have DMA channel(for at91 i is actually
1051 * the PDC) */
1052 set_bit(DMA_RX_CHAN_PRESENT, &chip->flags);
1053 set_bit(DMA_TX_CHAN_PRESENT, &chip->flags);
884 } 1054 }
885 1055
886 retval = atmel_ac97c_pcm_new(chip); 1056 retval = atmel_ac97c_pcm_new(chip);
@@ -897,20 +1067,22 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev)
897 1067
898 platform_set_drvdata(pdev, card); 1068 platform_set_drvdata(pdev, card);
899 1069
900 dev_info(&pdev->dev, "Atmel AC97 controller at 0x%p\n", 1070 dev_info(&pdev->dev, "Atmel AC97 controller at 0x%p, irq = %d\n",
901 chip->regs); 1071 chip->regs, irq);
902 1072
903 return 0; 1073 return 0;
904 1074
905err_dma: 1075err_dma:
906 if (test_bit(DMA_RX_CHAN_PRESENT, &chip->flags)) 1076 if (cpu_is_at32ap7000()) {
907 dma_release_channel(chip->dma.rx_chan); 1077 if (test_bit(DMA_RX_CHAN_PRESENT, &chip->flags))
908 if (test_bit(DMA_TX_CHAN_PRESENT, &chip->flags)) 1078 dma_release_channel(chip->dma.rx_chan);
909 dma_release_channel(chip->dma.tx_chan); 1079 if (test_bit(DMA_TX_CHAN_PRESENT, &chip->flags))
910 clear_bit(DMA_RX_CHAN_PRESENT, &chip->flags); 1080 dma_release_channel(chip->dma.tx_chan);
911 clear_bit(DMA_TX_CHAN_PRESENT, &chip->flags); 1081 clear_bit(DMA_RX_CHAN_PRESENT, &chip->flags);
912 chip->dma.rx_chan = NULL; 1082 clear_bit(DMA_TX_CHAN_PRESENT, &chip->flags);
913 chip->dma.tx_chan = NULL; 1083 chip->dma.rx_chan = NULL;
1084 chip->dma.tx_chan = NULL;
1085 }
914err_ac97_bus: 1086err_ac97_bus:
915 snd_card_set_dev(card, NULL); 1087 snd_card_set_dev(card, NULL);
916 1088
@@ -934,10 +1106,12 @@ static int atmel_ac97c_suspend(struct platform_device *pdev, pm_message_t msg)
934 struct snd_card *card = platform_get_drvdata(pdev); 1106 struct snd_card *card = platform_get_drvdata(pdev);
935 struct atmel_ac97c *chip = card->private_data; 1107 struct atmel_ac97c *chip = card->private_data;
936 1108
937 if (test_bit(DMA_RX_READY, &chip->flags)) 1109 if (cpu_is_at32ap7000()) {
938 dw_dma_cyclic_stop(chip->dma.rx_chan); 1110 if (test_bit(DMA_RX_READY, &chip->flags))
939 if (test_bit(DMA_TX_READY, &chip->flags)) 1111 dw_dma_cyclic_stop(chip->dma.rx_chan);
940 dw_dma_cyclic_stop(chip->dma.tx_chan); 1112 if (test_bit(DMA_TX_READY, &chip->flags))
1113 dw_dma_cyclic_stop(chip->dma.tx_chan);
1114 }
941 clk_disable(chip->pclk); 1115 clk_disable(chip->pclk);
942 1116
943 return 0; 1117 return 0;
@@ -949,11 +1123,12 @@ static int atmel_ac97c_resume(struct platform_device *pdev)
949 struct atmel_ac97c *chip = card->private_data; 1123 struct atmel_ac97c *chip = card->private_data;
950 1124
951 clk_enable(chip->pclk); 1125 clk_enable(chip->pclk);
952 if (test_bit(DMA_RX_READY, &chip->flags)) 1126 if (cpu_is_at32ap7000()) {
953 dw_dma_cyclic_start(chip->dma.rx_chan); 1127 if (test_bit(DMA_RX_READY, &chip->flags))
954 if (test_bit(DMA_TX_READY, &chip->flags)) 1128 dw_dma_cyclic_start(chip->dma.rx_chan);
955 dw_dma_cyclic_start(chip->dma.tx_chan); 1129 if (test_bit(DMA_TX_READY, &chip->flags))
956 1130 dw_dma_cyclic_start(chip->dma.tx_chan);
1131 }
957 return 0; 1132 return 0;
958} 1133}
959#else 1134#else
@@ -978,14 +1153,16 @@ static int __devexit atmel_ac97c_remove(struct platform_device *pdev)
978 iounmap(chip->regs); 1153 iounmap(chip->regs);
979 free_irq(chip->irq, chip); 1154 free_irq(chip->irq, chip);
980 1155
981 if (test_bit(DMA_RX_CHAN_PRESENT, &chip->flags)) 1156 if (cpu_is_at32ap7000()) {
982 dma_release_channel(chip->dma.rx_chan); 1157 if (test_bit(DMA_RX_CHAN_PRESENT, &chip->flags))
983 if (test_bit(DMA_TX_CHAN_PRESENT, &chip->flags)) 1158 dma_release_channel(chip->dma.rx_chan);
984 dma_release_channel(chip->dma.tx_chan); 1159 if (test_bit(DMA_TX_CHAN_PRESENT, &chip->flags))
985 clear_bit(DMA_RX_CHAN_PRESENT, &chip->flags); 1160 dma_release_channel(chip->dma.tx_chan);
986 clear_bit(DMA_TX_CHAN_PRESENT, &chip->flags); 1161 clear_bit(DMA_RX_CHAN_PRESENT, &chip->flags);
987 chip->dma.rx_chan = NULL; 1162 clear_bit(DMA_TX_CHAN_PRESENT, &chip->flags);
988 chip->dma.tx_chan = NULL; 1163 chip->dma.rx_chan = NULL;
1164 chip->dma.tx_chan = NULL;
1165 }
989 1166
990 snd_card_set_dev(card, NULL); 1167 snd_card_set_dev(card, NULL);
991 snd_card_free(card); 1168 snd_card_free(card);
diff --git a/sound/core/control.c b/sound/core/control.c
index 439ce64f9d82..070aab490191 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -50,6 +50,10 @@ static int snd_ctl_open(struct inode *inode, struct file *file)
50 struct snd_ctl_file *ctl; 50 struct snd_ctl_file *ctl;
51 int err; 51 int err;
52 52
53 err = nonseekable_open(inode, file);
54 if (err < 0)
55 return err;
56
53 card = snd_lookup_minor_data(iminor(inode), SNDRV_DEVICE_TYPE_CONTROL); 57 card = snd_lookup_minor_data(iminor(inode), SNDRV_DEVICE_TYPE_CONTROL);
54 if (!card) { 58 if (!card) {
55 err = -ENODEV; 59 err = -ENODEV;
@@ -1388,6 +1392,7 @@ static const struct file_operations snd_ctl_f_ops =
1388 .read = snd_ctl_read, 1392 .read = snd_ctl_read,
1389 .open = snd_ctl_open, 1393 .open = snd_ctl_open,
1390 .release = snd_ctl_release, 1394 .release = snd_ctl_release,
1395 .llseek = no_llseek,
1391 .poll = snd_ctl_poll, 1396 .poll = snd_ctl_poll,
1392 .unlocked_ioctl = snd_ctl_ioctl, 1397 .unlocked_ioctl = snd_ctl_ioctl,
1393 .compat_ioctl = snd_ctl_ioctl_compat, 1398 .compat_ioctl = snd_ctl_ioctl_compat,
diff --git a/sound/core/control_compat.c b/sound/core/control_compat.c
index 368dc9c4aef8..426874429a5e 100644
--- a/sound/core/control_compat.c
+++ b/sound/core/control_compat.c
@@ -21,6 +21,7 @@
21/* this file included from control.c */ 21/* this file included from control.c */
22 22
23#include <linux/compat.h> 23#include <linux/compat.h>
24#include <linux/slab.h>
24 25
25struct snd_ctl_elem_list32 { 26struct snd_ctl_elem_list32 {
26 u32 offset; 27 u32 offset;
diff --git a/sound/core/hrtimer.c b/sound/core/hrtimer.c
index 7f4d744ae40a..7730575bfadd 100644
--- a/sound/core/hrtimer.c
+++ b/sound/core/hrtimer.c
@@ -19,6 +19,7 @@
19 */ 19 */
20 20
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/slab.h>
22#include <linux/module.h> 23#include <linux/module.h>
23#include <linux/moduleparam.h> 24#include <linux/moduleparam.h>
24#include <linux/hrtimer.h> 25#include <linux/hrtimer.h>
diff --git a/sound/core/info.c b/sound/core/info.c
index d749a0d394a7..b70564ed8b37 100644
--- a/sound/core/info.c
+++ b/sound/core/info.c
@@ -22,6 +22,7 @@
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/time.h> 23#include <linux/time.h>
24#include <linux/mm.h> 24#include <linux/mm.h>
25#include <linux/slab.h>
25#include <linux/smp_lock.h> 26#include <linux/smp_lock.h>
26#include <linux/string.h> 27#include <linux/string.h>
27#include <sound/core.h> 28#include <sound/core.h>
@@ -163,40 +164,44 @@ static loff_t snd_info_entry_llseek(struct file *file, loff_t offset, int orig)
163{ 164{
164 struct snd_info_private_data *data; 165 struct snd_info_private_data *data;
165 struct snd_info_entry *entry; 166 struct snd_info_entry *entry;
166 loff_t ret; 167 loff_t ret = -EINVAL, size;
167 168
168 data = file->private_data; 169 data = file->private_data;
169 entry = data->entry; 170 entry = data->entry;
170 lock_kernel(); 171 mutex_lock(&entry->access);
171 switch (entry->content) { 172 if (entry->content == SNDRV_INFO_CONTENT_DATA &&
172 case SNDRV_INFO_CONTENT_TEXT: 173 entry->c.ops->llseek) {
173 switch (orig) { 174 offset = entry->c.ops->llseek(entry,
174 case SEEK_SET: 175 data->file_private_data,
175 file->f_pos = offset; 176 file, offset, orig);
176 ret = file->f_pos; 177 goto out;
177 goto out; 178 }
178 case SEEK_CUR: 179 if (entry->content == SNDRV_INFO_CONTENT_DATA)
179 file->f_pos += offset; 180 size = entry->size;
180 ret = file->f_pos; 181 else
181 goto out; 182 size = 0;
182 case SEEK_END: 183 switch (orig) {
183 default: 184 case SEEK_SET:
184 ret = -EINVAL;
185 goto out;
186 }
187 break; 185 break;
188 case SNDRV_INFO_CONTENT_DATA: 186 case SEEK_CUR:
189 if (entry->c.ops->llseek) { 187 offset += file->f_pos;
190 ret = entry->c.ops->llseek(entry, 188 break;
191 data->file_private_data, 189 case SEEK_END:
192 file, offset, orig); 190 if (!size)
193 goto out; 191 goto out;
194 } 192 offset += size;
195 break; 193 break;
196 } 194 default:
197 ret = -ENXIO; 195 goto out;
198out: 196 }
199 unlock_kernel(); 197 if (offset < 0)
198 goto out;
199 if (size && offset > size)
200 offset = size;
201 file->f_pos = offset;
202 ret = offset;
203 out:
204 mutex_unlock(&entry->access);
200 return ret; 205 return ret;
201} 206}
202 207
@@ -231,10 +236,15 @@ static ssize_t snd_info_entry_read(struct file *file, char __user *buffer,
231 return -EFAULT; 236 return -EFAULT;
232 break; 237 break;
233 case SNDRV_INFO_CONTENT_DATA: 238 case SNDRV_INFO_CONTENT_DATA:
234 if (entry->c.ops->read) 239 if (pos >= entry->size)
240 return 0;
241 if (entry->c.ops->read) {
242 size = entry->size - pos;
243 size = min(count, size);
235 size = entry->c.ops->read(entry, 244 size = entry->c.ops->read(entry,
236 data->file_private_data, 245 data->file_private_data,
237 file, buffer, count, pos); 246 file, buffer, size, pos);
247 }
238 break; 248 break;
239 } 249 }
240 if ((ssize_t) size > 0) 250 if ((ssize_t) size > 0)
@@ -281,10 +291,13 @@ static ssize_t snd_info_entry_write(struct file *file, const char __user *buffer
281 size = count; 291 size = count;
282 break; 292 break;
283 case SNDRV_INFO_CONTENT_DATA: 293 case SNDRV_INFO_CONTENT_DATA:
284 if (entry->c.ops->write) 294 if (entry->c.ops->write && count > 0) {
295 size_t maxsize = entry->size - pos;
296 count = min(count, maxsize);
285 size = entry->c.ops->write(entry, 297 size = entry->c.ops->write(entry,
286 data->file_private_data, 298 data->file_private_data,
287 file, buffer, count, pos); 299 file, buffer, count, pos);
300 }
288 break; 301 break;
289 } 302 }
290 if ((ssize_t) size > 0) 303 if ((ssize_t) size > 0)
diff --git a/sound/core/jack.c b/sound/core/jack.c
index 3813e7b04d05..4902ae568730 100644
--- a/sound/core/jack.c
+++ b/sound/core/jack.c
@@ -20,6 +20,7 @@
20 */ 20 */
21 21
22#include <linux/input.h> 22#include <linux/input.h>
23#include <linux/slab.h>
23#include <sound/jack.h> 24#include <sound/jack.h>
24#include <sound/core.h> 25#include <sound/core.h>
25 26
diff --git a/sound/core/misc.c b/sound/core/misc.c
index 3da4f92427d8..2c41825c836e 100644
--- a/sound/core/misc.c
+++ b/sound/core/misc.c
@@ -21,6 +21,7 @@
21 21
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/time.h> 23#include <linux/time.h>
24#include <linux/slab.h>
24#include <linux/ioport.h> 25#include <linux/ioport.h>
25#include <sound/core.h> 26#include <sound/core.h>
26 27
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c
index 54e2eb56e4c2..f50ebf20df96 100644
--- a/sound/core/oss/mixer_oss.c
+++ b/sound/core/oss/mixer_oss.c
@@ -43,6 +43,10 @@ static int snd_mixer_oss_open(struct inode *inode, struct file *file)
43 struct snd_mixer_oss_file *fmixer; 43 struct snd_mixer_oss_file *fmixer;
44 int err; 44 int err;
45 45
46 err = nonseekable_open(inode, file);
47 if (err < 0)
48 return err;
49
46 card = snd_lookup_oss_minor_data(iminor(inode), 50 card = snd_lookup_oss_minor_data(iminor(inode),
47 SNDRV_OSS_DEVICE_TYPE_MIXER); 51 SNDRV_OSS_DEVICE_TYPE_MIXER);
48 if (card == NULL) 52 if (card == NULL)
@@ -397,6 +401,7 @@ static const struct file_operations snd_mixer_oss_f_ops =
397 .owner = THIS_MODULE, 401 .owner = THIS_MODULE,
398 .open = snd_mixer_oss_open, 402 .open = snd_mixer_oss_open,
399 .release = snd_mixer_oss_release, 403 .release = snd_mixer_oss_release,
404 .llseek = no_llseek,
400 .unlocked_ioctl = snd_mixer_oss_ioctl, 405 .unlocked_ioctl = snd_mixer_oss_ioctl,
401 .compat_ioctl = snd_mixer_oss_ioctl_compat, 406 .compat_ioctl = snd_mixer_oss_ioctl_compat,
402}; 407};
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index 82d4e3329b3d..5c8c7dff8ede 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -2379,6 +2379,10 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file)
2379 int nonblock; 2379 int nonblock;
2380 wait_queue_t wait; 2380 wait_queue_t wait;
2381 2381
2382 err = nonseekable_open(inode, file);
2383 if (err < 0)
2384 return err;
2385
2382 pcm = snd_lookup_oss_minor_data(iminor(inode), 2386 pcm = snd_lookup_oss_minor_data(iminor(inode),
2383 SNDRV_OSS_DEVICE_TYPE_PCM); 2387 SNDRV_OSS_DEVICE_TYPE_PCM);
2384 if (pcm == NULL) { 2388 if (pcm == NULL) {
@@ -2977,6 +2981,7 @@ static const struct file_operations snd_pcm_oss_f_reg =
2977 .write = snd_pcm_oss_write, 2981 .write = snd_pcm_oss_write,
2978 .open = snd_pcm_oss_open, 2982 .open = snd_pcm_oss_open,
2979 .release = snd_pcm_oss_release, 2983 .release = snd_pcm_oss_release,
2984 .llseek = no_llseek,
2980 .poll = snd_pcm_oss_poll, 2985 .poll = snd_pcm_oss_poll,
2981 .unlocked_ioctl = snd_pcm_oss_ioctl, 2986 .unlocked_ioctl = snd_pcm_oss_ioctl,
2982 .compat_ioctl = snd_pcm_oss_ioctl_compat, 2987 .compat_ioctl = snd_pcm_oss_ioctl_compat,
diff --git a/sound/core/oss/route.c b/sound/core/oss/route.c
index 0dcc2870d537..bbe25d8c450a 100644
--- a/sound/core/oss/route.c
+++ b/sound/core/oss/route.c
@@ -19,7 +19,6 @@
19 * 19 *
20 */ 20 */
21 21
22#include <linux/slab.h>
23#include <linux/time.h> 22#include <linux/time.h>
24#include <sound/core.h> 23#include <sound/core.h>
25#include <sound/pcm.h> 24#include <sound/pcm.h>
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 0d428d0896db..cbe815dfbdc8 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -648,9 +648,6 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)
648 substream->number = idx; 648 substream->number = idx;
649 substream->stream = stream; 649 substream->stream = stream;
650 sprintf(substream->name, "subdevice #%i", idx); 650 sprintf(substream->name, "subdevice #%i", idx);
651 snprintf(substream->latency_id, sizeof(substream->latency_id),
652 "ALSA-PCM%d-%d%c%d", pcm->card->number, pcm->device,
653 (stream ? 'c' : 'p'), idx);
654 substream->buffer_bytes_max = UINT_MAX; 651 substream->buffer_bytes_max = UINT_MAX;
655 if (prev == NULL) 652 if (prev == NULL)
656 pstr->substream = substream; 653 pstr->substream = substream;
diff --git a/sound/core/pcm_compat.c b/sound/core/pcm_compat.c
index 08bfed594a83..5fb2e28e796f 100644
--- a/sound/core/pcm_compat.c
+++ b/sound/core/pcm_compat.c
@@ -21,6 +21,7 @@
21/* This file included from pcm_native.c */ 21/* This file included from pcm_native.c */
22 22
23#include <linux/compat.h> 23#include <linux/compat.h>
24#include <linux/slab.h>
24 25
25static int snd_pcm_ioctl_delay_compat(struct snd_pcm_substream *substream, 26static int snd_pcm_ioctl_delay_compat(struct snd_pcm_substream *substream,
26 s32 __user *src) 27 s32 __user *src)
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index b546ac2660f9..e9d98be190c5 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -148,6 +148,9 @@ static void pcm_debug_name(struct snd_pcm_substream *substream,
148 148
149#define xrun_debug(substream, mask) \ 149#define xrun_debug(substream, mask) \
150 ((substream)->pstr->xrun_debug & (mask)) 150 ((substream)->pstr->xrun_debug & (mask))
151#else
152#define xrun_debug(substream, mask) 0
153#endif
151 154
152#define dump_stack_on_xrun(substream) do { \ 155#define dump_stack_on_xrun(substream) do { \
153 if (xrun_debug(substream, XRUN_DEBUG_STACK)) \ 156 if (xrun_debug(substream, XRUN_DEBUG_STACK)) \
@@ -169,6 +172,7 @@ static void xrun(struct snd_pcm_substream *substream)
169 } 172 }
170} 173}
171 174
175#ifdef CONFIG_SND_PCM_XRUN_DEBUG
172#define hw_ptr_error(substream, fmt, args...) \ 176#define hw_ptr_error(substream, fmt, args...) \
173 do { \ 177 do { \
174 if (xrun_debug(substream, XRUN_DEBUG_BASIC)) { \ 178 if (xrun_debug(substream, XRUN_DEBUG_BASIC)) { \
@@ -255,8 +259,6 @@ static void xrun_log_show(struct snd_pcm_substream *substream)
255 259
256#else /* ! CONFIG_SND_PCM_XRUN_DEBUG */ 260#else /* ! CONFIG_SND_PCM_XRUN_DEBUG */
257 261
258#define xrun_debug(substream, mask) 0
259#define xrun(substream) do { } while (0)
260#define hw_ptr_error(substream, fmt, args...) do { } while (0) 262#define hw_ptr_error(substream, fmt, args...) do { } while (0)
261#define xrun_log(substream, pos) do { } while (0) 263#define xrun_log(substream, pos) do { } while (0)
262#define xrun_log_show(substream) do { } while (0) 264#define xrun_log_show(substream) do { } while (0)
@@ -343,7 +345,9 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
343 new_hw_ptr = hw_base + pos; 345 new_hw_ptr = hw_base + pos;
344 } 346 }
345 __delta: 347 __delta:
346 delta = (new_hw_ptr - old_hw_ptr) % runtime->boundary; 348 delta = new_hw_ptr - old_hw_ptr;
349 if (delta < 0)
350 delta += runtime->boundary;
347 if (xrun_debug(substream, in_interrupt ? 351 if (xrun_debug(substream, in_interrupt ?
348 XRUN_DEBUG_PERIODUPDATE : XRUN_DEBUG_HWPTRUPDATE)) { 352 XRUN_DEBUG_PERIODUPDATE : XRUN_DEBUG_HWPTRUPDATE)) {
349 char name[16]; 353 char name[16];
@@ -437,8 +441,13 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
437 snd_pcm_playback_silence(substream, new_hw_ptr); 441 snd_pcm_playback_silence(substream, new_hw_ptr);
438 442
439 if (in_interrupt) { 443 if (in_interrupt) {
440 runtime->hw_ptr_interrupt = new_hw_ptr - 444 delta = new_hw_ptr - runtime->hw_ptr_interrupt;
441 (new_hw_ptr % runtime->period_size); 445 if (delta < 0)
446 delta += runtime->boundary;
447 delta -= (snd_pcm_uframes_t)delta % runtime->period_size;
448 runtime->hw_ptr_interrupt += delta;
449 if (runtime->hw_ptr_interrupt >= runtime->boundary)
450 runtime->hw_ptr_interrupt -= runtime->boundary;
442 } 451 }
443 runtime->hw_ptr_base = hw_base; 452 runtime->hw_ptr_base = hw_base;
444 runtime->status->hw_ptr = new_hw_ptr; 453 runtime->status->hw_ptr = new_hw_ptr;
diff --git a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c
index d6d49d6651f9..917e4055ee30 100644
--- a/sound/core/pcm_memory.c
+++ b/sound/core/pcm_memory.c
@@ -22,6 +22,7 @@
22#include <asm/io.h> 22#include <asm/io.h>
23#include <linux/time.h> 23#include <linux/time.h>
24#include <linux/init.h> 24#include <linux/init.h>
25#include <linux/slab.h>
25#include <linux/moduleparam.h> 26#include <linux/moduleparam.h>
26#include <linux/vmalloc.h> 27#include <linux/vmalloc.h>
27#include <sound/core.h> 28#include <sound/core.h>
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 872887624030..303ac04ff6e4 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -27,7 +27,6 @@
27#include <linux/pm_qos_params.h> 27#include <linux/pm_qos_params.h>
28#include <linux/uio.h> 28#include <linux/uio.h>
29#include <linux/dma-mapping.h> 29#include <linux/dma-mapping.h>
30#include <linux/math64.h>
31#include <sound/core.h> 30#include <sound/core.h>
32#include <sound/control.h> 31#include <sound/control.h>
33#include <sound/info.h> 32#include <sound/info.h>
@@ -36,6 +35,9 @@
36#include <sound/timer.h> 35#include <sound/timer.h>
37#include <sound/minors.h> 36#include <sound/minors.h>
38#include <asm/io.h> 37#include <asm/io.h>
38#if defined(CONFIG_MIPS) && defined(CONFIG_DMA_NONCOHERENT)
39#include <dma-coherence.h>
40#endif
39 41
40/* 42/*
41 * Compatibility 43 * Compatibility
@@ -367,38 +369,6 @@ static int period_to_usecs(struct snd_pcm_runtime *runtime)
367 return usecs; 369 return usecs;
368} 370}
369 371
370static int calc_boundary(struct snd_pcm_runtime *runtime)
371{
372 u_int64_t boundary;
373
374 boundary = (u_int64_t)runtime->buffer_size *
375 (u_int64_t)runtime->period_size;
376#if BITS_PER_LONG < 64
377 /* try to find lowest common multiple for buffer and period */
378 if (boundary > LONG_MAX - runtime->buffer_size) {
379 u_int32_t remainder = -1;
380 u_int32_t divident = runtime->buffer_size;
381 u_int32_t divisor = runtime->period_size;
382 while (remainder) {
383 remainder = divident % divisor;
384 if (remainder) {
385 divident = divisor;
386 divisor = remainder;
387 }
388 }
389 boundary = div_u64(boundary, divisor);
390 if (boundary > LONG_MAX - runtime->buffer_size)
391 return -ERANGE;
392 }
393#endif
394 if (boundary == 0)
395 return -ERANGE;
396 runtime->boundary = boundary;
397 while (runtime->boundary * 2 <= LONG_MAX - runtime->buffer_size)
398 runtime->boundary *= 2;
399 return 0;
400}
401
402static int snd_pcm_hw_params(struct snd_pcm_substream *substream, 372static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
403 struct snd_pcm_hw_params *params) 373 struct snd_pcm_hw_params *params)
404{ 374{
@@ -474,18 +444,20 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
474 runtime->stop_threshold = runtime->buffer_size; 444 runtime->stop_threshold = runtime->buffer_size;
475 runtime->silence_threshold = 0; 445 runtime->silence_threshold = 0;
476 runtime->silence_size = 0; 446 runtime->silence_size = 0;
477 err = calc_boundary(runtime); 447 runtime->boundary = runtime->buffer_size;
478 if (err < 0) 448 while (runtime->boundary * 2 <= LONG_MAX - runtime->buffer_size)
479 goto _error; 449 runtime->boundary *= 2;
480 450
481 snd_pcm_timer_resolution_change(substream); 451 snd_pcm_timer_resolution_change(substream);
482 runtime->status->state = SNDRV_PCM_STATE_SETUP; 452 runtime->status->state = SNDRV_PCM_STATE_SETUP;
483 453
484 pm_qos_remove_requirement(PM_QOS_CPU_DMA_LATENCY, 454 if (substream->latency_pm_qos_req) {
485 substream->latency_id); 455 pm_qos_remove_request(substream->latency_pm_qos_req);
456 substream->latency_pm_qos_req = NULL;
457 }
486 if ((usecs = period_to_usecs(runtime)) >= 0) 458 if ((usecs = period_to_usecs(runtime)) >= 0)
487 pm_qos_add_requirement(PM_QOS_CPU_DMA_LATENCY, 459 substream->latency_pm_qos_req = pm_qos_add_request(
488 substream->latency_id, usecs); 460 PM_QOS_CPU_DMA_LATENCY, usecs);
489 return 0; 461 return 0;
490 _error: 462 _error:
491 /* hardware might be unuseable from this time, 463 /* hardware might be unuseable from this time,
@@ -540,8 +512,8 @@ static int snd_pcm_hw_free(struct snd_pcm_substream *substream)
540 if (substream->ops->hw_free) 512 if (substream->ops->hw_free)
541 result = substream->ops->hw_free(substream); 513 result = substream->ops->hw_free(substream);
542 runtime->status->state = SNDRV_PCM_STATE_OPEN; 514 runtime->status->state = SNDRV_PCM_STATE_OPEN;
543 pm_qos_remove_requirement(PM_QOS_CPU_DMA_LATENCY, 515 pm_qos_remove_request(substream->latency_pm_qos_req);
544 substream->latency_id); 516 substream->latency_pm_qos_req = NULL;
545 return result; 517 return result;
546} 518}
547 519
@@ -2107,7 +2079,9 @@ static int snd_pcm_open_file(struct file *file,
2107static int snd_pcm_playback_open(struct inode *inode, struct file *file) 2079static int snd_pcm_playback_open(struct inode *inode, struct file *file)
2108{ 2080{
2109 struct snd_pcm *pcm; 2081 struct snd_pcm *pcm;
2110 2082 int err = nonseekable_open(inode, file);
2083 if (err < 0)
2084 return err;
2111 pcm = snd_lookup_minor_data(iminor(inode), 2085 pcm = snd_lookup_minor_data(iminor(inode),
2112 SNDRV_DEVICE_TYPE_PCM_PLAYBACK); 2086 SNDRV_DEVICE_TYPE_PCM_PLAYBACK);
2113 return snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_PLAYBACK); 2087 return snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_PLAYBACK);
@@ -2116,7 +2090,9 @@ static int snd_pcm_playback_open(struct inode *inode, struct file *file)
2116static int snd_pcm_capture_open(struct inode *inode, struct file *file) 2090static int snd_pcm_capture_open(struct inode *inode, struct file *file)
2117{ 2091{
2118 struct snd_pcm *pcm; 2092 struct snd_pcm *pcm;
2119 2093 int err = nonseekable_open(inode, file);
2094 if (err < 0)
2095 return err;
2120 pcm = snd_lookup_minor_data(iminor(inode), 2096 pcm = snd_lookup_minor_data(iminor(inode),
2121 SNDRV_DEVICE_TYPE_PCM_CAPTURE); 2097 SNDRV_DEVICE_TYPE_PCM_CAPTURE);
2122 return snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_CAPTURE); 2098 return snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_CAPTURE);
@@ -3184,6 +3160,10 @@ static int snd_pcm_default_mmap(struct snd_pcm_substream *substream,
3184 substream->runtime->dma_area, 3160 substream->runtime->dma_area,
3185 substream->runtime->dma_addr, 3161 substream->runtime->dma_addr,
3186 area->vm_end - area->vm_start); 3162 area->vm_end - area->vm_start);
3163#elif defined(CONFIG_MIPS) && defined(CONFIG_DMA_NONCOHERENT)
3164 if (substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV &&
3165 !plat_device_is_coherent(substream->dma_buffer.dev.dev))
3166 area->vm_page_prot = pgprot_noncached(area->vm_page_prot);
3187#endif /* ARCH_HAS_DMA_MMAP_COHERENT */ 3167#endif /* ARCH_HAS_DMA_MMAP_COHERENT */
3188 /* mmap with fault handler */ 3168 /* mmap with fault handler */
3189 area->vm_ops = &snd_pcm_vm_ops_data_fault; 3169 area->vm_ops = &snd_pcm_vm_ops_data_fault;
@@ -3303,18 +3283,13 @@ static int snd_pcm_fasync(int fd, struct file * file, int on)
3303 struct snd_pcm_file * pcm_file; 3283 struct snd_pcm_file * pcm_file;
3304 struct snd_pcm_substream *substream; 3284 struct snd_pcm_substream *substream;
3305 struct snd_pcm_runtime *runtime; 3285 struct snd_pcm_runtime *runtime;
3306 int err = -ENXIO;
3307 3286
3308 lock_kernel();
3309 pcm_file = file->private_data; 3287 pcm_file = file->private_data;
3310 substream = pcm_file->substream; 3288 substream = pcm_file->substream;
3311 if (PCM_RUNTIME_CHECK(substream)) 3289 if (PCM_RUNTIME_CHECK(substream))
3312 goto out; 3290 return -ENXIO;
3313 runtime = substream->runtime; 3291 runtime = substream->runtime;
3314 err = fasync_helper(fd, file, on, &runtime->fasync); 3292 return fasync_helper(fd, file, on, &runtime->fasync);
3315out:
3316 unlock_kernel();
3317 return err;
3318} 3293}
3319 3294
3320/* 3295/*
@@ -3434,14 +3409,28 @@ out:
3434#endif /* CONFIG_SND_SUPPORT_OLD_API */ 3409#endif /* CONFIG_SND_SUPPORT_OLD_API */
3435 3410
3436#ifndef CONFIG_MMU 3411#ifndef CONFIG_MMU
3437unsigned long dummy_get_unmapped_area(struct file *file, unsigned long addr, 3412static unsigned long snd_pcm_get_unmapped_area(struct file *file,
3438 unsigned long len, unsigned long pgoff, 3413 unsigned long addr,
3439 unsigned long flags) 3414 unsigned long len,
3440{ 3415 unsigned long pgoff,
3441 return 0; 3416 unsigned long flags)
3417{
3418 struct snd_pcm_file *pcm_file = file->private_data;
3419 struct snd_pcm_substream *substream = pcm_file->substream;
3420 struct snd_pcm_runtime *runtime = substream->runtime;
3421 unsigned long offset = pgoff << PAGE_SHIFT;
3422
3423 switch (offset) {
3424 case SNDRV_PCM_MMAP_OFFSET_STATUS:
3425 return (unsigned long)runtime->status;
3426 case SNDRV_PCM_MMAP_OFFSET_CONTROL:
3427 return (unsigned long)runtime->control;
3428 default:
3429 return (unsigned long)runtime->dma_area + offset;
3430 }
3442} 3431}
3443#else 3432#else
3444# define dummy_get_unmapped_area NULL 3433# define snd_pcm_get_unmapped_area NULL
3445#endif 3434#endif
3446 3435
3447/* 3436/*
@@ -3455,12 +3444,13 @@ const struct file_operations snd_pcm_f_ops[2] = {
3455 .aio_write = snd_pcm_aio_write, 3444 .aio_write = snd_pcm_aio_write,
3456 .open = snd_pcm_playback_open, 3445 .open = snd_pcm_playback_open,
3457 .release = snd_pcm_release, 3446 .release = snd_pcm_release,
3447 .llseek = no_llseek,
3458 .poll = snd_pcm_playback_poll, 3448 .poll = snd_pcm_playback_poll,
3459 .unlocked_ioctl = snd_pcm_playback_ioctl, 3449 .unlocked_ioctl = snd_pcm_playback_ioctl,
3460 .compat_ioctl = snd_pcm_ioctl_compat, 3450 .compat_ioctl = snd_pcm_ioctl_compat,
3461 .mmap = snd_pcm_mmap, 3451 .mmap = snd_pcm_mmap,
3462 .fasync = snd_pcm_fasync, 3452 .fasync = snd_pcm_fasync,
3463 .get_unmapped_area = dummy_get_unmapped_area, 3453 .get_unmapped_area = snd_pcm_get_unmapped_area,
3464 }, 3454 },
3465 { 3455 {
3466 .owner = THIS_MODULE, 3456 .owner = THIS_MODULE,
@@ -3468,11 +3458,12 @@ const struct file_operations snd_pcm_f_ops[2] = {
3468 .aio_read = snd_pcm_aio_read, 3458 .aio_read = snd_pcm_aio_read,
3469 .open = snd_pcm_capture_open, 3459 .open = snd_pcm_capture_open,
3470 .release = snd_pcm_release, 3460 .release = snd_pcm_release,
3461 .llseek = no_llseek,
3471 .poll = snd_pcm_capture_poll, 3462 .poll = snd_pcm_capture_poll,
3472 .unlocked_ioctl = snd_pcm_capture_ioctl, 3463 .unlocked_ioctl = snd_pcm_capture_ioctl,
3473 .compat_ioctl = snd_pcm_ioctl_compat, 3464 .compat_ioctl = snd_pcm_ioctl_compat,
3474 .mmap = snd_pcm_mmap, 3465 .mmap = snd_pcm_mmap,
3475 .fasync = snd_pcm_fasync, 3466 .fasync = snd_pcm_fasync,
3476 .get_unmapped_area = dummy_get_unmapped_area, 3467 .get_unmapped_area = snd_pcm_get_unmapped_area,
3477 } 3468 }
3478}; 3469};
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index 0f5a194695d9..eb68326c37d4 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -376,6 +376,10 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
376 if ((file->f_flags & O_APPEND) && !(file->f_flags & O_NONBLOCK)) 376 if ((file->f_flags & O_APPEND) && !(file->f_flags & O_NONBLOCK))
377 return -EINVAL; /* invalid combination */ 377 return -EINVAL; /* invalid combination */
378 378
379 err = nonseekable_open(inode, file);
380 if (err < 0)
381 return err;
382
379 if (maj == snd_major) { 383 if (maj == snd_major) {
380 rmidi = snd_lookup_minor_data(iminor(inode), 384 rmidi = snd_lookup_minor_data(iminor(inode),
381 SNDRV_DEVICE_TYPE_RAWMIDI); 385 SNDRV_DEVICE_TYPE_RAWMIDI);
@@ -1391,6 +1395,7 @@ static const struct file_operations snd_rawmidi_f_ops =
1391 .write = snd_rawmidi_write, 1395 .write = snd_rawmidi_write,
1392 .open = snd_rawmidi_open, 1396 .open = snd_rawmidi_open,
1393 .release = snd_rawmidi_release, 1397 .release = snd_rawmidi_release,
1398 .llseek = no_llseek,
1394 .poll = snd_rawmidi_poll, 1399 .poll = snd_rawmidi_poll,
1395 .unlocked_ioctl = snd_rawmidi_ioctl, 1400 .unlocked_ioctl = snd_rawmidi_ioctl,
1396 .compat_ioctl = snd_rawmidi_ioctl_compat, 1401 .compat_ioctl = snd_rawmidi_ioctl_compat,
diff --git a/sound/core/seq/oss/seq_oss_init.c b/sound/core/seq/oss/seq_oss_init.c
index d0d721c22eac..685712276ac9 100644
--- a/sound/core/seq/oss/seq_oss_init.c
+++ b/sound/core/seq/oss/seq_oss_init.c
@@ -29,6 +29,7 @@
29#include "seq_oss_event.h" 29#include "seq_oss_event.h"
30#include <linux/init.h> 30#include <linux/init.h>
31#include <linux/moduleparam.h> 31#include <linux/moduleparam.h>
32#include <linux/slab.h>
32 33
33/* 34/*
34 * common variables 35 * common variables
diff --git a/sound/core/seq/oss/seq_oss_midi.c b/sound/core/seq/oss/seq_oss_midi.c
index 9dfb2f77be60..677dc84590c7 100644
--- a/sound/core/seq/oss/seq_oss_midi.c
+++ b/sound/core/seq/oss/seq_oss_midi.c
@@ -28,6 +28,7 @@
28#include <sound/seq_midi_event.h> 28#include <sound/seq_midi_event.h>
29#include "../seq_lock.h" 29#include "../seq_lock.h"
30#include <linux/init.h> 30#include <linux/init.h>
31#include <linux/slab.h>
31 32
32 33
33/* 34/*
diff --git a/sound/core/seq/oss/seq_oss_readq.c b/sound/core/seq/oss/seq_oss_readq.c
index f5de79f29f1e..73661c4ab82a 100644
--- a/sound/core/seq/oss/seq_oss_readq.c
+++ b/sound/core/seq/oss/seq_oss_readq.c
@@ -25,6 +25,7 @@
25#include <sound/seq_oss_legacy.h> 25#include <sound/seq_oss_legacy.h>
26#include "../seq_lock.h" 26#include "../seq_lock.h"
27#include <linux/wait.h> 27#include <linux/wait.h>
28#include <linux/slab.h>
28 29
29/* 30/*
30 * constants 31 * constants
diff --git a/sound/core/seq/oss/seq_oss_synth.c b/sound/core/seq/oss/seq_oss_synth.c
index 945a27c34a9d..ee44ab9593c0 100644
--- a/sound/core/seq/oss/seq_oss_synth.c
+++ b/sound/core/seq/oss/seq_oss_synth.c
@@ -24,6 +24,7 @@
24#include "seq_oss_midi.h" 24#include "seq_oss_midi.h"
25#include "../seq_lock.h" 25#include "../seq_lock.h"
26#include <linux/init.h> 26#include <linux/init.h>
27#include <linux/slab.h>
27 28
28/* 29/*
29 * constants 30 * constants
diff --git a/sound/core/seq/oss/seq_oss_timer.c b/sound/core/seq/oss/seq_oss_timer.c
index c440fdacec93..ab59cbfbcaf2 100644
--- a/sound/core/seq/oss/seq_oss_timer.c
+++ b/sound/core/seq/oss/seq_oss_timer.c
@@ -23,6 +23,7 @@
23#include "seq_oss_timer.h" 23#include "seq_oss_timer.h"
24#include "seq_oss_event.h" 24#include "seq_oss_event.h"
25#include <sound/seq_oss_legacy.h> 25#include <sound/seq_oss_legacy.h>
26#include <linux/slab.h>
26 27
27/* 28/*
28 */ 29 */
diff --git a/sound/core/seq/oss/seq_oss_writeq.c b/sound/core/seq/oss/seq_oss_writeq.c
index 217424858191..d50338bbc21f 100644
--- a/sound/core/seq/oss/seq_oss_writeq.c
+++ b/sound/core/seq/oss/seq_oss_writeq.c
@@ -27,6 +27,7 @@
27#include "../seq_lock.h" 27#include "../seq_lock.h"
28#include "../seq_clientmgr.h" 28#include "../seq_clientmgr.h"
29#include <linux/wait.h> 29#include <linux/wait.h>
30#include <linux/slab.h>
30 31
31 32
32/* 33/*
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
index 48eca9ff9ee7..99a485f13648 100644
--- a/sound/core/seq/seq_clientmgr.c
+++ b/sound/core/seq/seq_clientmgr.c
@@ -318,6 +318,11 @@ static int snd_seq_open(struct inode *inode, struct file *file)
318 int c, mode; /* client id */ 318 int c, mode; /* client id */
319 struct snd_seq_client *client; 319 struct snd_seq_client *client;
320 struct snd_seq_user_client *user; 320 struct snd_seq_user_client *user;
321 int err;
322
323 err = nonseekable_open(inode, file);
324 if (err < 0)
325 return err;
321 326
322 if (mutex_lock_interruptible(&register_mutex)) 327 if (mutex_lock_interruptible(&register_mutex))
323 return -ERESTARTSYS; 328 return -ERESTARTSYS;
@@ -2550,6 +2555,7 @@ static const struct file_operations snd_seq_f_ops =
2550 .write = snd_seq_write, 2555 .write = snd_seq_write,
2551 .open = snd_seq_open, 2556 .open = snd_seq_open,
2552 .release = snd_seq_release, 2557 .release = snd_seq_release,
2558 .llseek = no_llseek,
2553 .poll = snd_seq_poll, 2559 .poll = snd_seq_poll,
2554 .unlocked_ioctl = snd_seq_ioctl, 2560 .unlocked_ioctl = snd_seq_ioctl,
2555 .compat_ioctl = snd_seq_ioctl_compat, 2561 .compat_ioctl = snd_seq_ioctl_compat,
diff --git a/sound/core/seq/seq_compat.c b/sound/core/seq/seq_compat.c
index c956fe462569..81f7c109dc46 100644
--- a/sound/core/seq/seq_compat.c
+++ b/sound/core/seq/seq_compat.c
@@ -21,6 +21,7 @@
21/* This file included from seq.c */ 21/* This file included from seq.c */
22 22
23#include <linux/compat.h> 23#include <linux/compat.h>
24#include <linux/slab.h>
24 25
25struct snd_seq_port_info32 { 26struct snd_seq_port_info32 {
26 struct snd_seq_addr addr; /* client/port numbers */ 27 struct snd_seq_addr addr; /* client/port numbers */
diff --git a/sound/core/seq/seq_system.c b/sound/core/seq/seq_system.c
index 77884e62b648..c38b90cf3cb0 100644
--- a/sound/core/seq/seq_system.c
+++ b/sound/core/seq/seq_system.c
@@ -20,6 +20,7 @@
20 */ 20 */
21 21
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/slab.h>
23#include <sound/core.h> 24#include <sound/core.h>
24#include "seq_system.h" 25#include "seq_system.h"
25#include "seq_timer.h" 26#include "seq_timer.h"
diff --git a/sound/core/sound.c b/sound/core/sound.c
index 563d1967a0ad..ac42af42b787 100644
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -120,7 +120,29 @@ void *snd_lookup_minor_data(unsigned int minor, int type)
120 120
121EXPORT_SYMBOL(snd_lookup_minor_data); 121EXPORT_SYMBOL(snd_lookup_minor_data);
122 122
123static int __snd_open(struct inode *inode, struct file *file) 123#ifdef CONFIG_MODULES
124static struct snd_minor *autoload_device(unsigned int minor)
125{
126 int dev;
127 mutex_unlock(&sound_mutex); /* release lock temporarily */
128 dev = SNDRV_MINOR_DEVICE(minor);
129 if (dev == SNDRV_MINOR_CONTROL) {
130 /* /dev/aloadC? */
131 int card = SNDRV_MINOR_CARD(minor);
132 if (snd_cards[card] == NULL)
133 snd_request_card(card);
134 } else if (dev == SNDRV_MINOR_GLOBAL) {
135 /* /dev/aloadSEQ */
136 snd_request_other(minor);
137 }
138 mutex_lock(&sound_mutex); /* reacuire lock */
139 return snd_minors[minor];
140}
141#else /* !CONFIG_MODULES */
142#define autoload_device(minor) NULL
143#endif /* CONFIG_MODULES */
144
145static int snd_open(struct inode *inode, struct file *file)
124{ 146{
125 unsigned int minor = iminor(inode); 147 unsigned int minor = iminor(inode);
126 struct snd_minor *mptr = NULL; 148 struct snd_minor *mptr = NULL;
@@ -129,55 +151,36 @@ static int __snd_open(struct inode *inode, struct file *file)
129 151
130 if (minor >= ARRAY_SIZE(snd_minors)) 152 if (minor >= ARRAY_SIZE(snd_minors))
131 return -ENODEV; 153 return -ENODEV;
154 mutex_lock(&sound_mutex);
132 mptr = snd_minors[minor]; 155 mptr = snd_minors[minor];
133 if (mptr == NULL) { 156 if (mptr == NULL) {
134#ifdef CONFIG_MODULES 157 mptr = autoload_device(minor);
135 int dev = SNDRV_MINOR_DEVICE(minor); 158 if (!mptr) {
136 if (dev == SNDRV_MINOR_CONTROL) { 159 mutex_unlock(&sound_mutex);
137 /* /dev/aloadC? */
138 int card = SNDRV_MINOR_CARD(minor);
139 if (snd_cards[card] == NULL)
140 snd_request_card(card);
141 } else if (dev == SNDRV_MINOR_GLOBAL) {
142 /* /dev/aloadSEQ */
143 snd_request_other(minor);
144 }
145#ifndef CONFIG_SND_DYNAMIC_MINORS
146 /* /dev/snd/{controlC?,seq} */
147 mptr = snd_minors[minor];
148 if (mptr == NULL)
149#endif
150#endif
151 return -ENODEV; 160 return -ENODEV;
161 }
152 } 162 }
153 old_fops = file->f_op; 163 old_fops = file->f_op;
154 file->f_op = fops_get(mptr->f_ops); 164 file->f_op = fops_get(mptr->f_ops);
155 if (file->f_op == NULL) { 165 if (file->f_op == NULL) {
156 file->f_op = old_fops; 166 file->f_op = old_fops;
157 return -ENODEV; 167 err = -ENODEV;
158 } 168 }
159 if (file->f_op->open) 169 mutex_unlock(&sound_mutex);
170 if (err < 0)
171 return err;
172
173 if (file->f_op->open) {
160 err = file->f_op->open(inode, file); 174 err = file->f_op->open(inode, file);
161 if (err) { 175 if (err) {
162 fops_put(file->f_op); 176 fops_put(file->f_op);
163 file->f_op = fops_get(old_fops); 177 file->f_op = fops_get(old_fops);
178 }
164 } 179 }
165 fops_put(old_fops); 180 fops_put(old_fops);
166 return err; 181 return err;
167} 182}
168 183
169
170/* BKL pushdown: nasty #ifdef avoidance wrapper */
171static int snd_open(struct inode *inode, struct file *file)
172{
173 int ret;
174
175 lock_kernel();
176 ret = __snd_open(inode, file);
177 unlock_kernel();
178 return ret;
179}
180
181static const struct file_operations snd_fops = 184static const struct file_operations snd_fops =
182{ 185{
183 .owner = THIS_MODULE, 186 .owner = THIS_MODULE,
diff --git a/sound/core/timer.c b/sound/core/timer.c
index 73943651caed..13afb60999b9 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -1160,6 +1160,7 @@ static void snd_timer_user_ccallback(struct snd_timer_instance *timeri,
1160{ 1160{
1161 struct snd_timer_user *tu = timeri->callback_data; 1161 struct snd_timer_user *tu = timeri->callback_data;
1162 struct snd_timer_tread r1; 1162 struct snd_timer_tread r1;
1163 unsigned long flags;
1163 1164
1164 if (event >= SNDRV_TIMER_EVENT_START && 1165 if (event >= SNDRV_TIMER_EVENT_START &&
1165 event <= SNDRV_TIMER_EVENT_PAUSE) 1166 event <= SNDRV_TIMER_EVENT_PAUSE)
@@ -1169,9 +1170,9 @@ static void snd_timer_user_ccallback(struct snd_timer_instance *timeri,
1169 r1.event = event; 1170 r1.event = event;
1170 r1.tstamp = *tstamp; 1171 r1.tstamp = *tstamp;
1171 r1.val = resolution; 1172 r1.val = resolution;
1172 spin_lock(&tu->qlock); 1173 spin_lock_irqsave(&tu->qlock, flags);
1173 snd_timer_user_append_to_tqueue(tu, &r1); 1174 snd_timer_user_append_to_tqueue(tu, &r1);
1174 spin_unlock(&tu->qlock); 1175 spin_unlock_irqrestore(&tu->qlock, flags);
1175 kill_fasync(&tu->fasync, SIGIO, POLL_IN); 1176 kill_fasync(&tu->fasync, SIGIO, POLL_IN);
1176 wake_up(&tu->qchange_sleep); 1177 wake_up(&tu->qchange_sleep);
1177} 1178}
@@ -1237,6 +1238,11 @@ static void snd_timer_user_tinterrupt(struct snd_timer_instance *timeri,
1237static int snd_timer_user_open(struct inode *inode, struct file *file) 1238static int snd_timer_user_open(struct inode *inode, struct file *file)
1238{ 1239{
1239 struct snd_timer_user *tu; 1240 struct snd_timer_user *tu;
1241 int err;
1242
1243 err = nonseekable_open(inode, file);
1244 if (err < 0)
1245 return err;
1240 1246
1241 tu = kzalloc(sizeof(*tu), GFP_KERNEL); 1247 tu = kzalloc(sizeof(*tu), GFP_KERNEL);
1242 if (tu == NULL) 1248 if (tu == NULL)
@@ -1921,6 +1927,7 @@ static const struct file_operations snd_timer_f_ops =
1921 .read = snd_timer_user_read, 1927 .read = snd_timer_user_read,
1922 .open = snd_timer_user_open, 1928 .open = snd_timer_user_open,
1923 .release = snd_timer_user_release, 1929 .release = snd_timer_user_release,
1930 .llseek = no_llseek,
1924 .poll = snd_timer_user_poll, 1931 .poll = snd_timer_user_poll,
1925 .unlocked_ioctl = snd_timer_user_ioctl, 1932 .unlocked_ioctl = snd_timer_user_ioctl,
1926 .compat_ioctl = snd_timer_user_ioctl_compat, 1933 .compat_ioctl = snd_timer_user_ioctl_compat,
diff --git a/sound/drivers/ml403-ac97cr.c b/sound/drivers/ml403-ac97cr.c
index 1950ffce2b54..a1282c1c0591 100644
--- a/sound/drivers/ml403-ac97cr.c
+++ b/sound/drivers/ml403-ac97cr.c
@@ -39,6 +39,7 @@
39#include <linux/platform_device.h> 39#include <linux/platform_device.h>
40 40
41#include <linux/ioport.h> 41#include <linux/ioport.h>
42#include <linux/slab.h>
42#include <linux/io.h> 43#include <linux/io.h>
43#include <linux/interrupt.h> 44#include <linux/interrupt.h>
44 45
diff --git a/sound/drivers/mtpav.c b/sound/drivers/mtpav.c
index 2f8f295d6b0c..da03597fc893 100644
--- a/sound/drivers/mtpav.c
+++ b/sound/drivers/mtpav.c
@@ -54,7 +54,6 @@
54#include <linux/interrupt.h> 54#include <linux/interrupt.h>
55#include <linux/err.h> 55#include <linux/err.h>
56#include <linux/platform_device.h> 56#include <linux/platform_device.h>
57#include <linux/slab.h>
58#include <linux/ioport.h> 57#include <linux/ioport.h>
59#include <linux/moduleparam.h> 58#include <linux/moduleparam.h>
60#include <sound/core.h> 59#include <sound/core.h>
diff --git a/sound/drivers/mts64.c b/sound/drivers/mts64.c
index 9284829bf927..8539ab0a0893 100644
--- a/sound/drivers/mts64.c
+++ b/sound/drivers/mts64.c
@@ -23,6 +23,7 @@
23#include <linux/parport.h> 23#include <linux/parport.h>
24#include <linux/spinlock.h> 24#include <linux/spinlock.h>
25#include <linux/delay.h> 25#include <linux/delay.h>
26#include <linux/slab.h>
26#include <sound/core.h> 27#include <sound/core.h>
27#include <sound/initval.h> 28#include <sound/initval.h>
28#include <sound/rawmidi.h> 29#include <sound/rawmidi.h>
diff --git a/sound/drivers/opl3/opl3_oss.c b/sound/drivers/opl3/opl3_oss.c
index a54b1dc5cc78..ade3ca52422e 100644
--- a/sound/drivers/opl3/opl3_oss.c
+++ b/sound/drivers/opl3/opl3_oss.c
@@ -19,7 +19,6 @@
19 */ 19 */
20 20
21#include "opl3_voice.h" 21#include "opl3_voice.h"
22#include <linux/slab.h>
23 22
24static int snd_opl3_open_seq_oss(struct snd_seq_oss_arg *arg, void *closure); 23static int snd_opl3_open_seq_oss(struct snd_seq_oss_arg *arg, void *closure);
25static int snd_opl3_close_seq_oss(struct snd_seq_oss_arg *arg); 24static int snd_opl3_close_seq_oss(struct snd_seq_oss_arg *arg);
diff --git a/sound/drivers/opl3/opl3_synth.c b/sound/drivers/opl3/opl3_synth.c
index 6d57b6441dec..301acb6b9cf9 100644
--- a/sound/drivers/opl3/opl3_synth.c
+++ b/sound/drivers/opl3/opl3_synth.c
@@ -19,6 +19,7 @@
19 * 19 *
20 */ 20 */
21 21
22#include <linux/slab.h>
22#include <sound/opl3.h> 23#include <sound/opl3.h>
23#include <sound/asound_fm.h> 24#include <sound/asound_fm.h>
24 25
diff --git a/sound/drivers/opl4/opl4_lib.c b/sound/drivers/opl4/opl4_lib.c
index 01997f24c895..f07e38da59b8 100644
--- a/sound/drivers/opl4/opl4_lib.c
+++ b/sound/drivers/opl4/opl4_lib.c
@@ -20,6 +20,7 @@
20#include "opl4_local.h" 20#include "opl4_local.h"
21#include <sound/initval.h> 21#include <sound/initval.h>
22#include <linux/ioport.h> 22#include <linux/ioport.h>
23#include <linux/slab.h>
23#include <linux/init.h> 24#include <linux/init.h>
24#include <asm/io.h> 25#include <asm/io.h>
25 26
diff --git a/sound/drivers/opl4/opl4_proc.c b/sound/drivers/opl4/opl4_proc.c
index 1679300b7583..df850b8830a5 100644
--- a/sound/drivers/opl4/opl4_proc.c
+++ b/sound/drivers/opl4/opl4_proc.c
@@ -49,77 +49,45 @@ static int snd_opl4_mem_proc_release(struct snd_info_entry *entry,
49 return 0; 49 return 0;
50} 50}
51 51
52static long snd_opl4_mem_proc_read(struct snd_info_entry *entry, void *file_private_data, 52static ssize_t snd_opl4_mem_proc_read(struct snd_info_entry *entry,
53 struct file *file, char __user *_buf, 53 void *file_private_data,
54 unsigned long count, unsigned long pos) 54 struct file *file, char __user *_buf,
55 size_t count, loff_t pos)
55{ 56{
56 struct snd_opl4 *opl4 = entry->private_data; 57 struct snd_opl4 *opl4 = entry->private_data;
57 long size;
58 char* buf; 58 char* buf;
59 59
60 size = count; 60 buf = vmalloc(count);
61 if (pos + size > entry->size) 61 if (!buf)
62 size = entry->size - pos; 62 return -ENOMEM;
63 if (size > 0) { 63 snd_opl4_read_memory(opl4, buf, pos, count);
64 buf = vmalloc(size); 64 if (copy_to_user(_buf, buf, count)) {
65 if (!buf)
66 return -ENOMEM;
67 snd_opl4_read_memory(opl4, buf, pos, size);
68 if (copy_to_user(_buf, buf, size)) {
69 vfree(buf);
70 return -EFAULT;
71 }
72 vfree(buf); 65 vfree(buf);
73 return size; 66 return -EFAULT;
74 } 67 }
75 return 0; 68 vfree(buf);
69 return count;
76} 70}
77 71
78static long snd_opl4_mem_proc_write(struct snd_info_entry *entry, void *file_private_data, 72static ssize_t snd_opl4_mem_proc_write(struct snd_info_entry *entry,
79 struct file *file, const char __user *_buf, 73 void *file_private_data,
80 unsigned long count, unsigned long pos) 74 struct file *file,
75 const char __user *_buf,
76 size_t count, loff_t pos)
81{ 77{
82 struct snd_opl4 *opl4 = entry->private_data; 78 struct snd_opl4 *opl4 = entry->private_data;
83 long size;
84 char *buf; 79 char *buf;
85 80
86 size = count; 81 buf = vmalloc(count);
87 if (pos + size > entry->size) 82 if (!buf)
88 size = entry->size - pos; 83 return -ENOMEM;
89 if (size > 0) { 84 if (copy_from_user(buf, _buf, count)) {
90 buf = vmalloc(size);
91 if (!buf)
92 return -ENOMEM;
93 if (copy_from_user(buf, _buf, size)) {
94 vfree(buf);
95 return -EFAULT;
96 }
97 snd_opl4_write_memory(opl4, buf, pos, size);
98 vfree(buf); 85 vfree(buf);
99 return size; 86 return -EFAULT;
100 }
101 return 0;
102}
103
104static long long snd_opl4_mem_proc_llseek(struct snd_info_entry *entry, void *file_private_data,
105 struct file *file, long long offset, int orig)
106{
107 switch (orig) {
108 case SEEK_SET:
109 file->f_pos = offset;
110 break;
111 case SEEK_CUR:
112 file->f_pos += offset;
113 break;
114 case SEEK_END: /* offset is negative */
115 file->f_pos = entry->size + offset;
116 break;
117 default:
118 return -EINVAL;
119 } 87 }
120 if (file->f_pos > entry->size) 88 snd_opl4_write_memory(opl4, buf, pos, count);
121 file->f_pos = entry->size; 89 vfree(buf);
122 return file->f_pos; 90 return count;
123} 91}
124 92
125static struct snd_info_entry_ops snd_opl4_mem_proc_ops = { 93static struct snd_info_entry_ops snd_opl4_mem_proc_ops = {
@@ -127,7 +95,6 @@ static struct snd_info_entry_ops snd_opl4_mem_proc_ops = {
127 .release = snd_opl4_mem_proc_release, 95 .release = snd_opl4_mem_proc_release,
128 .read = snd_opl4_mem_proc_read, 96 .read = snd_opl4_mem_proc_read,
129 .write = snd_opl4_mem_proc_write, 97 .write = snd_opl4_mem_proc_write,
130 .llseek = snd_opl4_mem_proc_llseek,
131}; 98};
132 99
133int snd_opl4_create_proc(struct snd_opl4 *opl4) 100int snd_opl4_create_proc(struct snd_opl4 *opl4)
diff --git a/sound/drivers/pcsp/pcsp.h b/sound/drivers/pcsp/pcsp.h
index 1e123077923d..4ff6c8cc5077 100644
--- a/sound/drivers/pcsp/pcsp.h
+++ b/sound/drivers/pcsp/pcsp.h
@@ -16,7 +16,7 @@
16#include <asm/i8253.h> 16#include <asm/i8253.h>
17#else 17#else
18#include <asm/8253pit.h> 18#include <asm/8253pit.h>
19static DEFINE_SPINLOCK(i8253_lock); 19static DEFINE_RAW_SPINLOCK(i8253_lock);
20#endif 20#endif
21 21
22#define PCSP_SOUND_VERSION 0x400 /* read 4.00 */ 22#define PCSP_SOUND_VERSION 0x400 /* read 4.00 */
diff --git a/sound/drivers/pcsp/pcsp_input.c b/sound/drivers/pcsp/pcsp_input.c
index 0444cdeb4bec..b5e2b54c2604 100644
--- a/sound/drivers/pcsp/pcsp_input.c
+++ b/sound/drivers/pcsp/pcsp_input.c
@@ -21,7 +21,7 @@ static void pcspkr_do_sound(unsigned int count)
21{ 21{
22 unsigned long flags; 22 unsigned long flags;
23 23
24 spin_lock_irqsave(&i8253_lock, flags); 24 raw_spin_lock_irqsave(&i8253_lock, flags);
25 25
26 if (count) { 26 if (count) {
27 /* set command for counter 2, 2 byte write */ 27 /* set command for counter 2, 2 byte write */
@@ -36,7 +36,7 @@ static void pcspkr_do_sound(unsigned int count)
36 outb(inb_p(0x61) & 0xFC, 0x61); 36 outb(inb_p(0x61) & 0xFC, 0x61);
37 } 37 }
38 38
39 spin_unlock_irqrestore(&i8253_lock, flags); 39 raw_spin_unlock_irqrestore(&i8253_lock, flags);
40} 40}
41 41
42void pcspkr_stop_sound(void) 42void pcspkr_stop_sound(void)
diff --git a/sound/drivers/pcsp/pcsp_lib.c b/sound/drivers/pcsp/pcsp_lib.c
index e1145ac6e908..ce9e7d170c0d 100644
--- a/sound/drivers/pcsp/pcsp_lib.c
+++ b/sound/drivers/pcsp/pcsp_lib.c
@@ -7,6 +7,7 @@
7 */ 7 */
8 8
9#include <linux/module.h> 9#include <linux/module.h>
10#include <linux/gfp.h>
10#include <linux/moduleparam.h> 11#include <linux/moduleparam.h>
11#include <linux/interrupt.h> 12#include <linux/interrupt.h>
12#include <sound/pcm.h> 13#include <sound/pcm.h>
@@ -65,7 +66,7 @@ static u64 pcsp_timer_update(struct snd_pcsp *chip)
65 timer_cnt = val * CUR_DIV() / 256; 66 timer_cnt = val * CUR_DIV() / 256;
66 67
67 if (timer_cnt && chip->enable) { 68 if (timer_cnt && chip->enable) {
68 spin_lock_irqsave(&i8253_lock, flags); 69 raw_spin_lock_irqsave(&i8253_lock, flags);
69 if (!nforce_wa) { 70 if (!nforce_wa) {
70 outb_p(chip->val61, 0x61); 71 outb_p(chip->val61, 0x61);
71 outb_p(timer_cnt, 0x42); 72 outb_p(timer_cnt, 0x42);
@@ -74,7 +75,7 @@ static u64 pcsp_timer_update(struct snd_pcsp *chip)
74 outb(chip->val61 ^ 2, 0x61); 75 outb(chip->val61 ^ 2, 0x61);
75 chip->thalf = 1; 76 chip->thalf = 1;
76 } 77 }
77 spin_unlock_irqrestore(&i8253_lock, flags); 78 raw_spin_unlock_irqrestore(&i8253_lock, flags);
78 } 79 }
79 80
80 chip->ns_rem = PCSP_PERIOD_NS(); 81 chip->ns_rem = PCSP_PERIOD_NS();
@@ -158,10 +159,10 @@ static int pcsp_start_playing(struct snd_pcsp *chip)
158 return -EIO; 159 return -EIO;
159 } 160 }
160 161
161 spin_lock(&i8253_lock); 162 raw_spin_lock(&i8253_lock);
162 chip->val61 = inb(0x61) | 0x03; 163 chip->val61 = inb(0x61) | 0x03;
163 outb_p(0x92, 0x43); /* binary, mode 1, LSB only, ch 2 */ 164 outb_p(0x92, 0x43); /* binary, mode 1, LSB only, ch 2 */
164 spin_unlock(&i8253_lock); 165 raw_spin_unlock(&i8253_lock);
165 atomic_set(&chip->timer_active, 1); 166 atomic_set(&chip->timer_active, 1);
166 chip->thalf = 0; 167 chip->thalf = 0;
167 168
@@ -178,11 +179,11 @@ static void pcsp_stop_playing(struct snd_pcsp *chip)
178 return; 179 return;
179 180
180 atomic_set(&chip->timer_active, 0); 181 atomic_set(&chip->timer_active, 0);
181 spin_lock(&i8253_lock); 182 raw_spin_lock(&i8253_lock);
182 /* restore the timer */ 183 /* restore the timer */
183 outb_p(0xb6, 0x43); /* binary, mode 3, LSB/MSB, ch 2 */ 184 outb_p(0xb6, 0x43); /* binary, mode 3, LSB/MSB, ch 2 */
184 outb(chip->val61 & 0xFC, 0x61); 185 outb(chip->val61 & 0xFC, 0x61);
185 spin_unlock(&i8253_lock); 186 raw_spin_unlock(&i8253_lock);
186} 187}
187 188
188/* 189/*
diff --git a/sound/drivers/portman2x4.c b/sound/drivers/portman2x4.c
index 60158e2e0eaf..f2b0ba22d9ce 100644
--- a/sound/drivers/portman2x4.c
+++ b/sound/drivers/portman2x4.c
@@ -42,6 +42,7 @@
42#include <linux/parport.h> 42#include <linux/parport.h>
43#include <linux/spinlock.h> 43#include <linux/spinlock.h>
44#include <linux/delay.h> 44#include <linux/delay.h>
45#include <linux/slab.h>
45#include <sound/core.h> 46#include <sound/core.h>
46#include <sound/initval.h> 47#include <sound/initval.h>
47#include <sound/rawmidi.h> 48#include <sound/rawmidi.h>
diff --git a/sound/drivers/vx/vx_hwdep.c b/sound/drivers/vx/vx_hwdep.c
index 46df8817c18f..f7a6fbd313e3 100644
--- a/sound/drivers/vx/vx_hwdep.c
+++ b/sound/drivers/vx/vx_hwdep.c
@@ -22,6 +22,7 @@
22 22
23#include <linux/device.h> 23#include <linux/device.h>
24#include <linux/firmware.h> 24#include <linux/firmware.h>
25#include <linux/slab.h>
25#include <linux/vmalloc.h> 26#include <linux/vmalloc.h>
26#include <sound/core.h> 27#include <sound/core.h>
27#include <sound/hwdep.h> 28#include <sound/hwdep.h>
diff --git a/sound/i2c/i2c.c b/sound/i2c/i2c.c
index 5c0c77dd01c3..eb7c7d05a7c1 100644
--- a/sound/i2c/i2c.c
+++ b/sound/i2c/i2c.c
@@ -98,7 +98,8 @@ int snd_i2c_bus_create(struct snd_card *card, const char *name,
98 bus->master = master; 98 bus->master = master;
99 } 99 }
100 strlcpy(bus->name, name, sizeof(bus->name)); 100 strlcpy(bus->name, name, sizeof(bus->name));
101 if ((err = snd_device_new(card, SNDRV_DEV_BUS, bus, &ops)) < 0) { 101 err = snd_device_new(card, SNDRV_DEV_BUS, bus, &ops);
102 if (err < 0) {
102 snd_i2c_bus_free(bus); 103 snd_i2c_bus_free(bus);
103 return err; 104 return err;
104 } 105 }
@@ -246,7 +247,8 @@ static int snd_i2c_bit_sendbyte(struct snd_i2c_bus *bus, unsigned char data)
246 247
247 for (i = 7; i >= 0; i--) 248 for (i = 7; i >= 0; i--)
248 snd_i2c_bit_send(bus, !!(data & (1 << i))); 249 snd_i2c_bit_send(bus, !!(data & (1 << i)));
249 if ((err = snd_i2c_bit_ack(bus)) < 0) 250 err = snd_i2c_bit_ack(bus);
251 if (err < 0)
250 return err; 252 return err;
251 return 0; 253 return 0;
252} 254}
@@ -278,12 +280,14 @@ static int snd_i2c_bit_sendbytes(struct snd_i2c_device *device,
278 if (device->flags & SND_I2C_DEVICE_ADDRTEN) 280 if (device->flags & SND_I2C_DEVICE_ADDRTEN)
279 return -EIO; /* not yet implemented */ 281 return -EIO; /* not yet implemented */
280 snd_i2c_bit_start(bus); 282 snd_i2c_bit_start(bus);
281 if ((err = snd_i2c_bit_sendbyte(bus, device->addr << 1)) < 0) { 283 err = snd_i2c_bit_sendbyte(bus, device->addr << 1);
284 if (err < 0) {
282 snd_i2c_bit_hw_stop(bus); 285 snd_i2c_bit_hw_stop(bus);
283 return err; 286 return err;
284 } 287 }
285 while (count-- > 0) { 288 while (count-- > 0) {
286 if ((err = snd_i2c_bit_sendbyte(bus, *bytes++)) < 0) { 289 err = snd_i2c_bit_sendbyte(bus, *bytes++);
290 if (err < 0) {
287 snd_i2c_bit_hw_stop(bus); 291 snd_i2c_bit_hw_stop(bus);
288 return err; 292 return err;
289 } 293 }
@@ -302,12 +306,14 @@ static int snd_i2c_bit_readbytes(struct snd_i2c_device *device,
302 if (device->flags & SND_I2C_DEVICE_ADDRTEN) 306 if (device->flags & SND_I2C_DEVICE_ADDRTEN)
303 return -EIO; /* not yet implemented */ 307 return -EIO; /* not yet implemented */
304 snd_i2c_bit_start(bus); 308 snd_i2c_bit_start(bus);
305 if ((err = snd_i2c_bit_sendbyte(bus, (device->addr << 1) | 1)) < 0) { 309 err = snd_i2c_bit_sendbyte(bus, (device->addr << 1) | 1);
310 if (err < 0) {
306 snd_i2c_bit_hw_stop(bus); 311 snd_i2c_bit_hw_stop(bus);
307 return err; 312 return err;
308 } 313 }
309 while (count-- > 0) { 314 while (count-- > 0) {
310 if ((err = snd_i2c_bit_readbyte(bus, count == 0)) < 0) { 315 err = snd_i2c_bit_readbyte(bus, count == 0);
316 if (err < 0) {
311 snd_i2c_bit_hw_stop(bus); 317 snd_i2c_bit_hw_stop(bus);
312 return err; 318 return err;
313 } 319 }
diff --git a/sound/i2c/other/ak4113.c b/sound/i2c/other/ak4113.c
index fff62cc8607c..971a84a4fa77 100644
--- a/sound/i2c/other/ak4113.c
+++ b/sound/i2c/other/ak4113.c
@@ -70,7 +70,7 @@ static int snd_ak4113_dev_free(struct snd_device *device)
70} 70}
71 71
72int snd_ak4113_create(struct snd_card *card, ak4113_read_t *read, 72int snd_ak4113_create(struct snd_card *card, ak4113_read_t *read,
73 ak4113_write_t *write, const unsigned char pgm[5], 73 ak4113_write_t *write, const unsigned char *pgm,
74 void *private_data, struct ak4113 **r_ak4113) 74 void *private_data, struct ak4113 **r_ak4113)
75{ 75{
76 struct ak4113 *chip; 76 struct ak4113 *chip;
diff --git a/sound/i2c/other/tea575x-tuner.c b/sound/i2c/other/tea575x-tuner.c
index c4c6ef73f9bf..ee538f1ae846 100644
--- a/sound/i2c/other/tea575x-tuner.c
+++ b/sound/i2c/other/tea575x-tuner.c
@@ -24,6 +24,7 @@
24#include <linux/delay.h> 24#include <linux/delay.h>
25#include <linux/interrupt.h> 25#include <linux/interrupt.h>
26#include <linux/init.h> 26#include <linux/init.h>
27#include <linux/slab.h>
27#include <linux/version.h> 28#include <linux/version.h>
28#include <sound/core.h> 29#include <sound/core.h>
29#include <sound/tea575x-tuner.h> 30#include <sound/tea575x-tuner.h>
diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig
index 755a0a5f0e3f..c6990c680796 100644
--- a/sound/isa/Kconfig
+++ b/sound/isa/Kconfig
@@ -128,26 +128,14 @@ config SND_CS4236
128 To compile this driver as a module, choose M here: the module 128 To compile this driver as a module, choose M here: the module
129 will be called snd-cs4236. 129 will be called snd-cs4236.
130 130
131config SND_ES968
132 tristate "Generic ESS ES968 driver"
133 depends on PNP
134 select ISAPNP
135 select SND_MPU401_UART
136 select SND_SB8_DSP
137 help
138 Say Y here to include support for ESS AudioDrive ES968 chips.
139
140 To compile this driver as a module, choose M here: the module
141 will be called snd-es968.
142
143config SND_ES1688 131config SND_ES1688
144 tristate "Generic ESS ES688/ES1688 driver" 132 tristate "Generic ESS ES688/ES1688 and ES968 PnP driver"
145 select SND_OPL3_LIB 133 select SND_OPL3_LIB
146 select SND_MPU401_UART 134 select SND_MPU401_UART
147 select SND_PCM 135 select SND_PCM
148 help 136 help
149 Say Y here to include support for ESS AudioDrive ES688 or 137 Say Y here to include support for ESS AudioDrive ES688 or
150 ES1688 chips. 138 ES1688 chips. Also, this module support cards with ES968 PnP chip.
151 139
152 To compile this driver as a module, choose M here: the module 140 To compile this driver as a module, choose M here: the module
153 will be called snd-es1688. 141 will be called snd-es1688.
diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c
index 8246aae32ab4..fe79a169acb5 100644
--- a/sound/isa/cmi8330.c
+++ b/sound/isa/cmi8330.c
@@ -46,7 +46,6 @@
46#include <linux/init.h> 46#include <linux/init.h>
47#include <linux/err.h> 47#include <linux/err.h>
48#include <linux/isa.h> 48#include <linux/isa.h>
49#include <linux/slab.h>
50#include <linux/pnp.h> 49#include <linux/pnp.h>
51#include <linux/moduleparam.h> 50#include <linux/moduleparam.h>
52#include <sound/core.h> 51#include <sound/core.h>
diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c
index cc15d1d65a22..999dc1e0fdbd 100644
--- a/sound/isa/cs423x/cs4236.c
+++ b/sound/isa/cs423x/cs4236.c
@@ -22,7 +22,6 @@
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/err.h> 23#include <linux/err.h>
24#include <linux/isa.h> 24#include <linux/isa.h>
25#include <linux/slab.h>
26#include <linux/pnp.h> 25#include <linux/pnp.h>
27#include <linux/moduleparam.h> 26#include <linux/moduleparam.h>
28#include <sound/core.h> 27#include <sound/core.h>
diff --git a/sound/isa/es1688/es1688.c b/sound/isa/es1688/es1688.c
index 07df201ed8fa..0cde8131a575 100644
--- a/sound/isa/es1688/es1688.c
+++ b/sound/isa/es1688/es1688.c
@@ -22,6 +22,7 @@
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/err.h> 23#include <linux/err.h>
24#include <linux/isa.h> 24#include <linux/isa.h>
25#include <linux/isapnp.h>
25#include <linux/time.h> 26#include <linux/time.h>
26#include <linux/wait.h> 27#include <linux/wait.h>
27#include <linux/moduleparam.h> 28#include <linux/moduleparam.h>
@@ -45,8 +46,13 @@ MODULE_SUPPORTED_DEVICE("{{ESS,ES688 PnP AudioDrive,pnp:ESS0100},"
45 "{ESS,ES688 AudioDrive,pnp:ESS6881}," 46 "{ESS,ES688 AudioDrive,pnp:ESS6881},"
46 "{ESS,ES1688 AudioDrive,pnp:ESS1681}}"); 47 "{ESS,ES1688 AudioDrive,pnp:ESS1681}}");
47 48
49MODULE_ALIAS("snd_es968");
50
48static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ 51static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
49static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ 52static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
53#ifdef CONFIG_PNP
54static int isapnp[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP;
55#endif
50static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ 56static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
51static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240,0x260 */ 57static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240,0x260 */
52static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* Usually 0x388 */ 58static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* Usually 0x388 */
@@ -60,6 +66,10 @@ MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard.");
60module_param_array(id, charp, NULL, 0444); 66module_param_array(id, charp, NULL, 0444);
61MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard."); 67MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard.");
62module_param_array(enable, bool, NULL, 0444); 68module_param_array(enable, bool, NULL, 0444);
69#ifdef CONFIG_PNP
70module_param_array(isapnp, bool, NULL, 0444);
71MODULE_PARM_DESC(isapnp, "PnP detection for specified soundcard.");
72#endif
63MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard."); 73MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
64module_param_array(port, long, NULL, 0444); 74module_param_array(port, long, NULL, 0444);
65MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver."); 75MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
@@ -74,14 +84,21 @@ MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " CRD_NAME " driver.");
74module_param_array(dma8, int, NULL, 0444); 84module_param_array(dma8, int, NULL, 0444);
75MODULE_PARM_DESC(dma8, "8-bit DMA # for " CRD_NAME " driver."); 85MODULE_PARM_DESC(dma8, "8-bit DMA # for " CRD_NAME " driver.");
76 86
87#ifdef CONFIG_PNP
88#define is_isapnp_selected(dev) isapnp[dev]
89#else
90#define is_isapnp_selected(dev) 0
91#endif
92
77static int __devinit snd_es1688_match(struct device *dev, unsigned int n) 93static int __devinit snd_es1688_match(struct device *dev, unsigned int n)
78{ 94{
79 return enable[n]; 95 return enable[n] && !is_isapnp_selected(n);
80} 96}
81 97
82static int __devinit snd_es1688_legacy_create(struct snd_card *card, 98static int __devinit snd_es1688_legacy_create(struct snd_card *card,
83 struct device *dev, unsigned int n, struct snd_es1688 **rchip) 99 struct device *dev, unsigned int n)
84{ 100{
101 struct snd_es1688 *chip = card->private_data;
85 static long possible_ports[] = {0x220, 0x240, 0x260}; 102 static long possible_ports[] = {0x220, 0x240, 0x260};
86 static int possible_irqs[] = {5, 9, 10, 7, -1}; 103 static int possible_irqs[] = {5, 9, 10, 7, -1};
87 static int possible_dmas[] = {1, 3, 0, -1}; 104 static int possible_dmas[] = {1, 3, 0, -1};
@@ -104,47 +121,39 @@ static int __devinit snd_es1688_legacy_create(struct snd_card *card,
104 } 121 }
105 122
106 if (port[n] != SNDRV_AUTO_PORT) 123 if (port[n] != SNDRV_AUTO_PORT)
107 return snd_es1688_create(card, port[n], mpu_port[n], irq[n], 124 return snd_es1688_create(card, chip, port[n], mpu_port[n],
108 mpu_irq[n], dma8[n], ES1688_HW_AUTO, rchip); 125 irq[n], mpu_irq[n], dma8[n], ES1688_HW_AUTO);
109 126
110 i = 0; 127 i = 0;
111 do { 128 do {
112 port[n] = possible_ports[i]; 129 port[n] = possible_ports[i];
113 error = snd_es1688_create(card, port[n], mpu_port[n], irq[n], 130 error = snd_es1688_create(card, chip, port[n], mpu_port[n],
114 mpu_irq[n], dma8[n], ES1688_HW_AUTO, rchip); 131 irq[n], mpu_irq[n], dma8[n], ES1688_HW_AUTO);
115 } while (error < 0 && ++i < ARRAY_SIZE(possible_ports)); 132 } while (error < 0 && ++i < ARRAY_SIZE(possible_ports));
116 133
117 return error; 134 return error;
118} 135}
119 136
120static int __devinit snd_es1688_probe(struct device *dev, unsigned int n) 137static int __devinit snd_es1688_probe(struct snd_card *card, unsigned int n)
121{ 138{
122 struct snd_card *card; 139 struct snd_es1688 *chip = card->private_data;
123 struct snd_es1688 *chip;
124 struct snd_opl3 *opl3; 140 struct snd_opl3 *opl3;
125 struct snd_pcm *pcm; 141 struct snd_pcm *pcm;
126 int error; 142 int error;
127 143
128 error = snd_card_create(index[n], id[n], THIS_MODULE, 0, &card); 144 error = snd_es1688_pcm(card, chip, 0, &pcm);
129 if (error < 0) 145 if (error < 0)
130 return error; 146 return error;
131 147
132 error = snd_es1688_legacy_create(card, dev, n, &chip); 148 error = snd_es1688_mixer(card, chip);
133 if (error < 0)
134 goto out;
135
136 error = snd_es1688_pcm(chip, 0, &pcm);
137 if (error < 0) 149 if (error < 0)
138 goto out; 150 return error;
139
140 error = snd_es1688_mixer(chip);
141 if (error < 0)
142 goto out;
143 151
144 strcpy(card->driver, "ES1688"); 152 strlcpy(card->driver, "ES1688", sizeof(card->driver));
145 strcpy(card->shortname, pcm->name); 153 strlcpy(card->shortname, pcm->name, sizeof(card->shortname));
146 sprintf(card->longname, "%s at 0x%lx, irq %i, dma %i", pcm->name, 154 snprintf(card->longname, sizeof(card->longname),
147 chip->port, chip->irq, chip->dma8); 155 "%s at 0x%lx, irq %i, dma %i", pcm->name, chip->port,
156 chip->irq, chip->dma8);
148 157
149 if (fm_port[n] == SNDRV_AUTO_PORT) 158 if (fm_port[n] == SNDRV_AUTO_PORT)
150 fm_port[n] = port[n]; /* share the same port */ 159 fm_port[n] = port[n]; /* share the same port */
@@ -152,12 +161,12 @@ static int __devinit snd_es1688_probe(struct device *dev, unsigned int n)
152 if (fm_port[n] > 0) { 161 if (fm_port[n] > 0) {
153 if (snd_opl3_create(card, fm_port[n], fm_port[n] + 2, 162 if (snd_opl3_create(card, fm_port[n], fm_port[n] + 2,
154 OPL3_HW_OPL3, 0, &opl3) < 0) 163 OPL3_HW_OPL3, 0, &opl3) < 0)
155 dev_warn(dev, 164 dev_warn(card->dev,
156 "opl3 not detected at 0x%lx\n", fm_port[n]); 165 "opl3 not detected at 0x%lx\n", fm_port[n]);
157 else { 166 else {
158 error = snd_opl3_hwdep_new(opl3, 0, 1, NULL); 167 error = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
159 if (error < 0) 168 if (error < 0)
160 goto out; 169 return error;
161 } 170 }
162 } 171 }
163 172
@@ -167,23 +176,41 @@ static int __devinit snd_es1688_probe(struct device *dev, unsigned int n)
167 chip->mpu_port, 0, 176 chip->mpu_port, 0,
168 mpu_irq[n], IRQF_DISABLED, NULL); 177 mpu_irq[n], IRQF_DISABLED, NULL);
169 if (error < 0) 178 if (error < 0)
170 goto out; 179 return error;
171 } 180 }
172 181
182 return snd_card_register(card);
183}
184
185static int __devinit snd_es1688_isa_probe(struct device *dev, unsigned int n)
186{
187 struct snd_card *card;
188 int error;
189
190 error = snd_card_create(index[n], id[n], THIS_MODULE,
191 sizeof(struct snd_es1688), &card);
192 if (error < 0)
193 return error;
194
195 error = snd_es1688_legacy_create(card, dev, n);
196 if (error < 0)
197 goto out;
198
173 snd_card_set_dev(card, dev); 199 snd_card_set_dev(card, dev);
174 200
175 error = snd_card_register(card); 201 error = snd_es1688_probe(card, n);
176 if (error < 0) 202 if (error < 0)
177 goto out; 203 goto out;
178 204
179 dev_set_drvdata(dev, card); 205 dev_set_drvdata(dev, card);
180 return 0;
181 206
182out: snd_card_free(card); 207 return 0;
208out:
209 snd_card_free(card);
183 return error; 210 return error;
184} 211}
185 212
186static int __devexit snd_es1688_remove(struct device *dev, unsigned int n) 213static int __devexit snd_es1688_isa_remove(struct device *dev, unsigned int n)
187{ 214{
188 snd_card_free(dev_get_drvdata(dev)); 215 snd_card_free(dev_get_drvdata(dev));
189 dev_set_drvdata(dev, NULL); 216 dev_set_drvdata(dev, NULL);
@@ -192,8 +219,8 @@ static int __devexit snd_es1688_remove(struct device *dev, unsigned int n)
192 219
193static struct isa_driver snd_es1688_driver = { 220static struct isa_driver snd_es1688_driver = {
194 .match = snd_es1688_match, 221 .match = snd_es1688_match,
195 .probe = snd_es1688_probe, 222 .probe = snd_es1688_isa_probe,
196 .remove = __devexit_p(snd_es1688_remove), 223 .remove = __devexit_p(snd_es1688_isa_remove),
197#if 0 /* FIXME */ 224#if 0 /* FIXME */
198 .suspend = snd_es1688_suspend, 225 .suspend = snd_es1688_suspend,
199 .resume = snd_es1688_resume, 226 .resume = snd_es1688_resume,
@@ -203,14 +230,142 @@ static struct isa_driver snd_es1688_driver = {
203 } 230 }
204}; 231};
205 232
233static int snd_es968_pnp_is_probed;
234
235#ifdef CONFIG_PNP
236static int __devinit snd_card_es968_pnp(struct snd_card *card, unsigned int n,
237 struct pnp_card_link *pcard,
238 const struct pnp_card_device_id *pid)
239{
240 struct snd_es1688 *chip = card->private_data;
241 struct pnp_dev *pdev;
242 int error;
243
244 pdev = pnp_request_card_device(pcard, pid->devs[0].id, NULL);
245 if (pdev == NULL)
246 return -ENODEV;
247
248 error = pnp_activate_dev(pdev);
249 if (error < 0) {
250 snd_printk(KERN_ERR "ES968 pnp configure failure\n");
251 return error;
252 }
253 port[n] = pnp_port_start(pdev, 0);
254 dma8[n] = pnp_dma(pdev, 0);
255 irq[n] = pnp_irq(pdev, 0);
256
257 return snd_es1688_create(card, chip, port[n], mpu_port[n], irq[n],
258 mpu_irq[n], dma8[n], ES1688_HW_AUTO);
259}
260
261static int __devinit snd_es968_pnp_detect(struct pnp_card_link *pcard,
262 const struct pnp_card_device_id *pid)
263{
264 struct snd_card *card;
265 static unsigned int dev;
266 int error;
267 struct snd_es1688 *chip;
268
269 if (snd_es968_pnp_is_probed)
270 return -EBUSY;
271 for ( ; dev < SNDRV_CARDS; dev++) {
272 if (enable[dev] && isapnp[dev])
273 break;
274 }
275 if (dev == SNDRV_CARDS)
276 return -ENODEV;
277
278 error = snd_card_create(index[dev], id[dev], THIS_MODULE,
279 sizeof(struct snd_es1688), &card);
280 if (error < 0)
281 return error;
282 chip = card->private_data;
283
284 error = snd_card_es968_pnp(card, dev, pcard, pid);
285 if (error < 0) {
286 snd_card_free(card);
287 return error;
288 }
289 snd_card_set_dev(card, &pcard->card->dev);
290 error = snd_es1688_probe(card, dev);
291 if (error < 0)
292 return error;
293 pnp_set_card_drvdata(pcard, card);
294 snd_es968_pnp_is_probed = 1;
295 return 0;
296}
297
298static void __devexit snd_es968_pnp_remove(struct pnp_card_link * pcard)
299{
300 snd_card_free(pnp_get_card_drvdata(pcard));
301 pnp_set_card_drvdata(pcard, NULL);
302 snd_es968_pnp_is_probed = 0;
303}
304
305#ifdef CONFIG_PM
306static int snd_es968_pnp_suspend(struct pnp_card_link *pcard,
307 pm_message_t state)
308{
309 struct snd_card *card = pnp_get_card_drvdata(pcard);
310 struct snd_es1688 *chip = card->private_data;
311
312 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
313 snd_pcm_suspend_all(chip->pcm);
314 return 0;
315}
316
317static int snd_es968_pnp_resume(struct pnp_card_link *pcard)
318{
319 struct snd_card *card = pnp_get_card_drvdata(pcard);
320 struct snd_es1688 *chip = card->private_data;
321
322 snd_es1688_reset(chip);
323 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
324 return 0;
325}
326#endif
327
328static struct pnp_card_device_id snd_es968_pnpids[] = {
329 { .id = "ESS0968", .devs = { { "@@@0968" }, } },
330 { .id = "ESS0968", .devs = { { "ESS0968" }, } },
331 { .id = "", } /* end */
332};
333
334MODULE_DEVICE_TABLE(pnp_card, snd_es968_pnpids);
335
336static struct pnp_card_driver es968_pnpc_driver = {
337 .flags = PNP_DRIVER_RES_DISABLE,
338 .name = DEV_NAME " PnP",
339 .id_table = snd_es968_pnpids,
340 .probe = snd_es968_pnp_detect,
341 .remove = __devexit_p(snd_es968_pnp_remove),
342#ifdef CONFIG_PM
343 .suspend = snd_es968_pnp_suspend,
344 .resume = snd_es968_pnp_resume,
345#endif
346};
347#endif
348
206static int __init alsa_card_es1688_init(void) 349static int __init alsa_card_es1688_init(void)
207{ 350{
351#ifdef CONFIG_PNP
352 pnp_register_card_driver(&es968_pnpc_driver);
353 if (snd_es968_pnp_is_probed)
354 return 0;
355 pnp_unregister_card_driver(&es968_pnpc_driver);
356#endif
208 return isa_register_driver(&snd_es1688_driver, SNDRV_CARDS); 357 return isa_register_driver(&snd_es1688_driver, SNDRV_CARDS);
209} 358}
210 359
211static void __exit alsa_card_es1688_exit(void) 360static void __exit alsa_card_es1688_exit(void)
212{ 361{
213 isa_unregister_driver(&snd_es1688_driver); 362 if (!snd_es968_pnp_is_probed) {
363 isa_unregister_driver(&snd_es1688_driver);
364 return;
365 }
366#ifdef CONFIG_PNP
367 pnp_unregister_card_driver(&es968_pnpc_driver);
368#endif
214} 369}
215 370
216module_init(alsa_card_es1688_init); 371module_init(alsa_card_es1688_init);
diff --git a/sound/isa/es1688/es1688_lib.c b/sound/isa/es1688/es1688_lib.c
index c76bb00c9d15..07676200496a 100644
--- a/sound/isa/es1688/es1688_lib.c
+++ b/sound/isa/es1688/es1688_lib.c
@@ -99,7 +99,7 @@ static unsigned char snd_es1688_mixer_read(struct snd_es1688 *chip, unsigned cha
99 return result; 99 return result;
100} 100}
101 101
102static int snd_es1688_reset(struct snd_es1688 *chip) 102int snd_es1688_reset(struct snd_es1688 *chip)
103{ 103{
104 int i; 104 int i;
105 105
@@ -115,6 +115,7 @@ static int snd_es1688_reset(struct snd_es1688 *chip)
115 snd_es1688_dsp_command(chip, 0xc6); /* enable extended mode */ 115 snd_es1688_dsp_command(chip, 0xc6); /* enable extended mode */
116 return 0; 116 return 0;
117} 117}
118EXPORT_SYMBOL(snd_es1688_reset);
118 119
119static int snd_es1688_probe(struct snd_es1688 *chip) 120static int snd_es1688_probe(struct snd_es1688 *chip)
120{ 121{
@@ -620,7 +621,6 @@ static int snd_es1688_free(struct snd_es1688 *chip)
620 disable_dma(chip->dma8); 621 disable_dma(chip->dma8);
621 free_dma(chip->dma8); 622 free_dma(chip->dma8);
622 } 623 }
623 kfree(chip);
624 return 0; 624 return 0;
625} 625}
626 626
@@ -638,23 +638,20 @@ static const char *snd_es1688_chip_id(struct snd_es1688 *chip)
638} 638}
639 639
640int snd_es1688_create(struct snd_card *card, 640int snd_es1688_create(struct snd_card *card,
641 struct snd_es1688 *chip,
641 unsigned long port, 642 unsigned long port,
642 unsigned long mpu_port, 643 unsigned long mpu_port,
643 int irq, 644 int irq,
644 int mpu_irq, 645 int mpu_irq,
645 int dma8, 646 int dma8,
646 unsigned short hardware, 647 unsigned short hardware)
647 struct snd_es1688 **rchip)
648{ 648{
649 static struct snd_device_ops ops = { 649 static struct snd_device_ops ops = {
650 .dev_free = snd_es1688_dev_free, 650 .dev_free = snd_es1688_dev_free,
651 }; 651 };
652 652
653 struct snd_es1688 *chip;
654 int err; 653 int err;
655 654
656 *rchip = NULL;
657 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
658 if (chip == NULL) 655 if (chip == NULL)
659 return -ENOMEM; 656 return -ENOMEM;
660 chip->irq = -1; 657 chip->irq = -1;
@@ -662,25 +659,21 @@ int snd_es1688_create(struct snd_card *card,
662 659
663 if ((chip->res_port = request_region(port + 4, 12, "ES1688")) == NULL) { 660 if ((chip->res_port = request_region(port + 4, 12, "ES1688")) == NULL) {
664 snd_printk(KERN_ERR "es1688: can't grab port 0x%lx\n", port + 4); 661 snd_printk(KERN_ERR "es1688: can't grab port 0x%lx\n", port + 4);
665 snd_es1688_free(chip);
666 return -EBUSY; 662 return -EBUSY;
667 } 663 }
668 if (request_irq(irq, snd_es1688_interrupt, IRQF_DISABLED, "ES1688", (void *) chip)) { 664 if (request_irq(irq, snd_es1688_interrupt, IRQF_DISABLED, "ES1688", (void *) chip)) {
669 snd_printk(KERN_ERR "es1688: can't grab IRQ %d\n", irq); 665 snd_printk(KERN_ERR "es1688: can't grab IRQ %d\n", irq);
670 snd_es1688_free(chip);
671 return -EBUSY; 666 return -EBUSY;
672 } 667 }
673 chip->irq = irq; 668 chip->irq = irq;
674 if (request_dma(dma8, "ES1688")) { 669 if (request_dma(dma8, "ES1688")) {
675 snd_printk(KERN_ERR "es1688: can't grab DMA8 %d\n", dma8); 670 snd_printk(KERN_ERR "es1688: can't grab DMA8 %d\n", dma8);
676 snd_es1688_free(chip);
677 return -EBUSY; 671 return -EBUSY;
678 } 672 }
679 chip->dma8 = dma8; 673 chip->dma8 = dma8;
680 674
681 spin_lock_init(&chip->reg_lock); 675 spin_lock_init(&chip->reg_lock);
682 spin_lock_init(&chip->mixer_lock); 676 spin_lock_init(&chip->mixer_lock);
683 chip->card = card;
684 chip->port = port; 677 chip->port = port;
685 mpu_port &= ~0x000f; 678 mpu_port &= ~0x000f;
686 if (mpu_port < 0x300 || mpu_port > 0x330) 679 if (mpu_port < 0x300 || mpu_port > 0x330)
@@ -689,23 +682,16 @@ int snd_es1688_create(struct snd_card *card,
689 chip->mpu_irq = mpu_irq; 682 chip->mpu_irq = mpu_irq;
690 chip->hardware = hardware; 683 chip->hardware = hardware;
691 684
692 if ((err = snd_es1688_probe(chip)) < 0) { 685 err = snd_es1688_probe(chip);
693 snd_es1688_free(chip); 686 if (err < 0)
694 return err; 687 return err;
695 }
696 if ((err = snd_es1688_init(chip, 1)) < 0) {
697 snd_es1688_free(chip);
698 return err;
699 }
700 688
701 /* Register device */ 689 err = snd_es1688_init(chip, 1);
702 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { 690 if (err < 0)
703 snd_es1688_free(chip);
704 return err; 691 return err;
705 }
706 692
707 *rchip = chip; 693 /* Register device */
708 return 0; 694 return snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
709} 695}
710 696
711static struct snd_pcm_ops snd_es1688_playback_ops = { 697static struct snd_pcm_ops snd_es1688_playback_ops = {
@@ -730,12 +716,14 @@ static struct snd_pcm_ops snd_es1688_capture_ops = {
730 .pointer = snd_es1688_capture_pointer, 716 .pointer = snd_es1688_capture_pointer,
731}; 717};
732 718
733int snd_es1688_pcm(struct snd_es1688 * chip, int device, struct snd_pcm ** rpcm) 719int snd_es1688_pcm(struct snd_card *card, struct snd_es1688 *chip,
720 int device, struct snd_pcm **rpcm)
734{ 721{
735 struct snd_pcm *pcm; 722 struct snd_pcm *pcm;
736 int err; 723 int err;
737 724
738 if ((err = snd_pcm_new(chip->card, "ESx688", device, 1, 1, &pcm)) < 0) 725 err = snd_pcm_new(card, "ESx688", device, 1, 1, &pcm);
726 if (err < 0)
739 return err; 727 return err;
740 728
741 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_es1688_playback_ops); 729 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_es1688_playback_ops);
@@ -1009,18 +997,15 @@ static unsigned char snd_es1688_init_table[][2] = {
1009 { ES1688_REC_DEV, 0x17 } 997 { ES1688_REC_DEV, 0x17 }
1010}; 998};
1011 999
1012int snd_es1688_mixer(struct snd_es1688 *chip) 1000int snd_es1688_mixer(struct snd_card *card, struct snd_es1688 *chip)
1013{ 1001{
1014 struct snd_card *card;
1015 unsigned int idx; 1002 unsigned int idx;
1016 int err; 1003 int err;
1017 unsigned char reg, val; 1004 unsigned char reg, val;
1018 1005
1019 if (snd_BUG_ON(!chip || !chip->card)) 1006 if (snd_BUG_ON(!chip || !card))
1020 return -EINVAL; 1007 return -EINVAL;
1021 1008
1022 card = chip->card;
1023
1024 strcpy(card->mixername, snd_es1688_chip_id(chip)); 1009 strcpy(card->mixername, snd_es1688_chip_id(chip));
1025 1010
1026 for (idx = 0; idx < ARRAY_SIZE(snd_es1688_controls); idx++) { 1011 for (idx = 0; idx < ARRAY_SIZE(snd_es1688_controls); idx++) {
diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c
index 9a43baae7250..fb4d6b34bbca 100644
--- a/sound/isa/es18xx.c
+++ b/sound/isa/es18xx.c
@@ -80,7 +80,6 @@
80#include <linux/init.h> 80#include <linux/init.h>
81#include <linux/err.h> 81#include <linux/err.h>
82#include <linux/isa.h> 82#include <linux/isa.h>
83#include <linux/slab.h>
84#include <linux/pnp.h> 83#include <linux/pnp.h>
85#include <linux/isapnp.h> 84#include <linux/isapnp.h>
86#include <linux/moduleparam.h> 85#include <linux/moduleparam.h>
diff --git a/sound/isa/gus/gus_mem_proc.c b/sound/isa/gus/gus_mem_proc.c
index 2803e227aec9..2ccb3fadd7be 100644
--- a/sound/isa/gus/gus_mem_proc.c
+++ b/sound/isa/gus/gus_mem_proc.c
@@ -31,52 +31,21 @@ struct gus_proc_private {
31 struct snd_gus_card * gus; 31 struct snd_gus_card * gus;
32}; 32};
33 33
34static long snd_gf1_mem_proc_dump(struct snd_info_entry *entry, void *file_private_data, 34static ssize_t snd_gf1_mem_proc_dump(struct snd_info_entry *entry,
35 struct file *file, char __user *buf, 35 void *file_private_data,
36 unsigned long count, unsigned long pos) 36 struct file *file, char __user *buf,
37 size_t count, loff_t pos)
37{ 38{
38 long size;
39 struct gus_proc_private *priv = entry->private_data; 39 struct gus_proc_private *priv = entry->private_data;
40 struct snd_gus_card *gus = priv->gus; 40 struct snd_gus_card *gus = priv->gus;
41 int err; 41 int err;
42 42
43 size = count; 43 err = snd_gus_dram_read(gus, buf, pos, count, priv->rom);
44 if (pos + size > priv->size) 44 if (err < 0)
45 size = (long)priv->size - pos; 45 return err;
46 if (size > 0) { 46 return count;
47 if ((err = snd_gus_dram_read(gus, buf, pos, size, priv->rom)) < 0)
48 return err;
49 return size;
50 }
51 return 0;
52} 47}
53 48
54static long long snd_gf1_mem_proc_llseek(struct snd_info_entry *entry,
55 void *private_file_data,
56 struct file *file,
57 long long offset,
58 int orig)
59{
60 struct gus_proc_private *priv = entry->private_data;
61
62 switch (orig) {
63 case SEEK_SET:
64 file->f_pos = offset;
65 break;
66 case SEEK_CUR:
67 file->f_pos += offset;
68 break;
69 case SEEK_END: /* offset is negative */
70 file->f_pos = priv->size + offset;
71 break;
72 default:
73 return -EINVAL;
74 }
75 if (file->f_pos > priv->size)
76 file->f_pos = priv->size;
77 return file->f_pos;
78}
79
80static void snd_gf1_mem_proc_free(struct snd_info_entry *entry) 49static void snd_gf1_mem_proc_free(struct snd_info_entry *entry)
81{ 50{
82 struct gus_proc_private *priv = entry->private_data; 51 struct gus_proc_private *priv = entry->private_data;
@@ -85,7 +54,6 @@ static void snd_gf1_mem_proc_free(struct snd_info_entry *entry)
85 54
86static struct snd_info_entry_ops snd_gf1_mem_proc_ops = { 55static struct snd_info_entry_ops snd_gf1_mem_proc_ops = {
87 .read = snd_gf1_mem_proc_dump, 56 .read = snd_gf1_mem_proc_dump,
88 .llseek = snd_gf1_mem_proc_llseek,
89}; 57};
90 58
91int snd_gf1_mem_proc_init(struct snd_gus_card * gus) 59int snd_gf1_mem_proc_init(struct snd_gus_card * gus)
diff --git a/sound/isa/gus/gusextreme.c b/sound/isa/gus/gusextreme.c
index 65e4b18581a6..008e8e5bfa37 100644
--- a/sound/isa/gus/gusextreme.c
+++ b/sound/isa/gus/gusextreme.c
@@ -95,7 +95,7 @@ static int __devinit snd_gusextreme_match(struct device *dev, unsigned int n)
95} 95}
96 96
97static int __devinit snd_gusextreme_es1688_create(struct snd_card *card, 97static int __devinit snd_gusextreme_es1688_create(struct snd_card *card,
98 struct device *dev, unsigned int n, struct snd_es1688 **rchip) 98 struct snd_es1688 *chip, struct device *dev, unsigned int n)
99{ 99{
100 static long possible_ports[] = {0x220, 0x240, 0x260}; 100 static long possible_ports[] = {0x220, 0x240, 0x260};
101 static int possible_irqs[] = {5, 9, 10, 7, -1}; 101 static int possible_irqs[] = {5, 9, 10, 7, -1};
@@ -119,14 +119,14 @@ static int __devinit snd_gusextreme_es1688_create(struct snd_card *card,
119 } 119 }
120 120
121 if (port[n] != SNDRV_AUTO_PORT) 121 if (port[n] != SNDRV_AUTO_PORT)
122 return snd_es1688_create(card, port[n], mpu_port[n], irq[n], 122 return snd_es1688_create(card, chip, port[n], mpu_port[n],
123 mpu_irq[n], dma8[n], ES1688_HW_1688, rchip); 123 irq[n], mpu_irq[n], dma8[n], ES1688_HW_1688);
124 124
125 i = 0; 125 i = 0;
126 do { 126 do {
127 port[n] = possible_ports[i]; 127 port[n] = possible_ports[i];
128 error = snd_es1688_create(card, port[n], mpu_port[n], irq[n], 128 error = snd_es1688_create(card, chip, port[n], mpu_port[n],
129 mpu_irq[n], dma8[n], ES1688_HW_1688, rchip); 129 irq[n], mpu_irq[n], dma8[n], ES1688_HW_1688);
130 } while (error < 0 && ++i < ARRAY_SIZE(possible_ports)); 130 } while (error < 0 && ++i < ARRAY_SIZE(possible_ports));
131 131
132 return error; 132 return error;
@@ -206,9 +206,8 @@ static int __devinit snd_gusextreme_detect(struct snd_gus_card *gus,
206 return 0; 206 return 0;
207} 207}
208 208
209static int __devinit snd_gusextreme_mixer(struct snd_es1688 *chip) 209static int __devinit snd_gusextreme_mixer(struct snd_card *card)
210{ 210{
211 struct snd_card *card = chip->card;
212 struct snd_ctl_elem_id id1, id2; 211 struct snd_ctl_elem_id id1, id2;
213 int error; 212 int error;
214 213
@@ -241,17 +240,20 @@ static int __devinit snd_gusextreme_probe(struct device *dev, unsigned int n)
241 struct snd_opl3 *opl3; 240 struct snd_opl3 *opl3;
242 int error; 241 int error;
243 242
244 error = snd_card_create(index[n], id[n], THIS_MODULE, 0, &card); 243 error = snd_card_create(index[n], id[n], THIS_MODULE,
244 sizeof(struct snd_es1688), &card);
245 if (error < 0) 245 if (error < 0)
246 return error; 246 return error;
247 247
248 es1688 = card->private_data;
249
248 if (mpu_port[n] == SNDRV_AUTO_PORT) 250 if (mpu_port[n] == SNDRV_AUTO_PORT)
249 mpu_port[n] = 0; 251 mpu_port[n] = 0;
250 252
251 if (mpu_irq[n] > 15) 253 if (mpu_irq[n] > 15)
252 mpu_irq[n] = -1; 254 mpu_irq[n] = -1;
253 255
254 error = snd_gusextreme_es1688_create(card, dev, n, &es1688); 256 error = snd_gusextreme_es1688_create(card, es1688, dev, n);
255 if (error < 0) 257 if (error < 0)
256 goto out; 258 goto out;
257 259
@@ -280,11 +282,11 @@ static int __devinit snd_gusextreme_probe(struct device *dev, unsigned int n)
280 } 282 }
281 gus->codec_flag = 1; 283 gus->codec_flag = 1;
282 284
283 error = snd_es1688_pcm(es1688, 0, NULL); 285 error = snd_es1688_pcm(card, es1688, 0, NULL);
284 if (error < 0) 286 if (error < 0)
285 goto out; 287 goto out;
286 288
287 error = snd_es1688_mixer(es1688); 289 error = snd_es1688_mixer(card, es1688);
288 if (error < 0) 290 if (error < 0)
289 goto out; 291 goto out;
290 292
@@ -300,7 +302,7 @@ static int __devinit snd_gusextreme_probe(struct device *dev, unsigned int n)
300 if (error < 0) 302 if (error < 0)
301 goto out; 303 goto out;
302 304
303 error = snd_gusextreme_mixer(es1688); 305 error = snd_gusextreme_mixer(card);
304 if (error < 0) 306 if (error < 0)
305 goto out; 307 goto out;
306 308
diff --git a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c
index 534a6eced2b8..c7b80e4730fc 100644
--- a/sound/isa/gus/interwave.c
+++ b/sound/isa/gus/interwave.c
@@ -26,7 +26,6 @@
26#include <linux/err.h> 26#include <linux/err.h>
27#include <linux/isa.h> 27#include <linux/isa.h>
28#include <linux/delay.h> 28#include <linux/delay.h>
29#include <linux/slab.h>
30#include <linux/pnp.h> 29#include <linux/pnp.h>
31#include <linux/moduleparam.h> 30#include <linux/moduleparam.h>
32#include <asm/dma.h> 31#include <asm/dma.h>
diff --git a/sound/isa/msnd/msnd_midi.c b/sound/isa/msnd/msnd_midi.c
index 4be562b2cf21..787495674235 100644
--- a/sound/isa/msnd/msnd_midi.c
+++ b/sound/isa/msnd/msnd_midi.c
@@ -25,6 +25,7 @@
25 */ 25 */
26 26
27#include <linux/io.h> 27#include <linux/io.h>
28#include <linux/slab.h>
28#include <linux/delay.h> 29#include <linux/delay.h>
29#include <linux/ioport.h> 30#include <linux/ioport.h>
30#include <linux/errno.h> 31#include <linux/errno.h>
diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c
index 0481a55334b9..265abcce9dba 100644
--- a/sound/isa/opl3sa2.c
+++ b/sound/isa/opl3sa2.c
@@ -24,7 +24,6 @@
24#include <linux/isa.h> 24#include <linux/isa.h>
25#include <linux/interrupt.h> 25#include <linux/interrupt.h>
26#include <linux/pm.h> 26#include <linux/pm.h>
27#include <linux/slab.h>
28#include <linux/pnp.h> 27#include <linux/pnp.h>
29#include <linux/moduleparam.h> 28#include <linux/moduleparam.h>
30#include <sound/core.h> 29#include <sound/core.h>
diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c
index 5913717c1be6..8c24102d0d93 100644
--- a/sound/isa/opti9xx/miro.c
+++ b/sound/isa/opti9xx/miro.c
@@ -27,7 +27,6 @@
27#include <linux/isa.h> 27#include <linux/isa.h>
28#include <linux/pnp.h> 28#include <linux/pnp.h>
29#include <linux/delay.h> 29#include <linux/delay.h>
30#include <linux/slab.h>
31#include <linux/ioport.h> 30#include <linux/ioport.h>
32#include <linux/moduleparam.h> 31#include <linux/moduleparam.h>
33#include <asm/io.h> 32#include <asm/io.h>
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c
index 4d2d0405bdc7..c35dc68930dc 100644
--- a/sound/isa/opti9xx/opti92x-ad1848.c
+++ b/sound/isa/opti9xx/opti92x-ad1848.c
@@ -27,7 +27,6 @@
27#include <linux/err.h> 27#include <linux/err.h>
28#include <linux/isa.h> 28#include <linux/isa.h>
29#include <linux/delay.h> 29#include <linux/delay.h>
30#include <linux/slab.h>
31#include <linux/pnp.h> 30#include <linux/pnp.h>
32#include <linux/moduleparam.h> 31#include <linux/moduleparam.h>
33#include <asm/io.h> 32#include <asm/io.h>
diff --git a/sound/isa/sb/Makefile b/sound/isa/sb/Makefile
index af3669681788..08b9fb974658 100644
--- a/sound/isa/sb/Makefile
+++ b/sound/isa/sb/Makefile
@@ -11,7 +11,6 @@ snd-sb8-objs := sb8.o
11snd-sb16-objs := sb16.o 11snd-sb16-objs := sb16.o
12snd-sbawe-objs := sbawe.o emu8000.o 12snd-sbawe-objs := sbawe.o emu8000.o
13snd-emu8000-synth-objs := emu8000_synth.o emu8000_callback.o emu8000_patch.o emu8000_pcm.o 13snd-emu8000-synth-objs := emu8000_synth.o emu8000_callback.o emu8000_patch.o emu8000_pcm.o
14snd-es968-objs := es968.o
15snd-jazz16-objs := jazz16.o 14snd-jazz16-objs := jazz16.o
16 15
17# Toplevel Module Dependency 16# Toplevel Module Dependency
@@ -21,7 +20,6 @@ obj-$(CONFIG_SND_SB8_DSP) += snd-sb8-dsp.o
21obj-$(CONFIG_SND_SB8) += snd-sb8.o 20obj-$(CONFIG_SND_SB8) += snd-sb8.o
22obj-$(CONFIG_SND_SB16) += snd-sb16.o 21obj-$(CONFIG_SND_SB16) += snd-sb16.o
23obj-$(CONFIG_SND_SBAWE) += snd-sbawe.o 22obj-$(CONFIG_SND_SBAWE) += snd-sbawe.o
24obj-$(CONFIG_SND_ES968) += snd-es968.o
25obj-$(CONFIG_SND_JAZZ16) += snd-jazz16.o 23obj-$(CONFIG_SND_JAZZ16) += snd-jazz16.o
26ifeq ($(CONFIG_SND_SB16_CSP),y) 24ifeq ($(CONFIG_SND_SB16_CSP),y)
27 obj-$(CONFIG_SND_SB16) += snd-sb16-csp.o 25 obj-$(CONFIG_SND_SB16) += snd-sb16-csp.o
diff --git a/sound/isa/sb/emu8000_pcm.c b/sound/isa/sb/emu8000_pcm.c
index 91dc3d83e2cf..ccedbfed061a 100644
--- a/sound/isa/sb/emu8000_pcm.c
+++ b/sound/isa/sb/emu8000_pcm.c
@@ -20,6 +20,7 @@
20 20
21#include "emu8000_local.h" 21#include "emu8000_local.h"
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/slab.h>
23#include <sound/initval.h> 24#include <sound/initval.h>
24#include <sound/pcm.h> 25#include <sound/pcm.h>
25 26
diff --git a/sound/isa/sb/es968.c b/sound/isa/sb/es968.c
deleted file mode 100644
index cafc3a7316a8..000000000000
--- a/sound/isa/sb/es968.c
+++ /dev/null
@@ -1,248 +0,0 @@
1
2/*
3 card-es968.c - driver for ESS AudioDrive ES968 based soundcards.
4 Copyright (C) 1999 by Massimo Piccioni <dafastidio@libero.it>
5
6 Thanks to Pierfrancesco 'qM2' Passerini.
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#include <linux/init.h>
24#include <linux/time.h>
25#include <linux/pnp.h>
26#include <linux/moduleparam.h>
27#include <sound/core.h>
28#include <sound/initval.h>
29#include <sound/sb.h>
30
31#define PFX "es968: "
32
33MODULE_AUTHOR("Massimo Piccioni <dafastidio@libero.it>");
34MODULE_DESCRIPTION("ESS AudioDrive ES968");
35MODULE_LICENSE("GPL");
36MODULE_SUPPORTED_DEVICE("{{ESS,AudioDrive ES968}}");
37
38static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
39static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
40static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */
41static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
42static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* Pnp setup */
43static int dma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* PnP setup */
44
45module_param_array(index, int, NULL, 0444);
46MODULE_PARM_DESC(index, "Index value for es968 based soundcard.");
47module_param_array(id, charp, NULL, 0444);
48MODULE_PARM_DESC(id, "ID string for es968 based soundcard.");
49module_param_array(enable, bool, NULL, 0444);
50MODULE_PARM_DESC(enable, "Enable es968 based soundcard.");
51
52struct snd_card_es968 {
53 struct pnp_dev *dev;
54 struct snd_sb *chip;
55};
56
57static struct pnp_card_device_id snd_es968_pnpids[] = {
58 { .id = "ESS0968", .devs = { { "@@@0968" }, } },
59 { .id = "", } /* end */
60};
61
62MODULE_DEVICE_TABLE(pnp_card, snd_es968_pnpids);
63
64#define DRIVER_NAME "snd-card-es968"
65
66static irqreturn_t snd_card_es968_interrupt(int irq, void *dev_id)
67{
68 struct snd_sb *chip = dev_id;
69
70 if (chip->open & SB_OPEN_PCM) {
71 return snd_sb8dsp_interrupt(chip);
72 } else {
73 return snd_sb8dsp_midi_interrupt(chip);
74 }
75}
76
77static int __devinit snd_card_es968_pnp(int dev, struct snd_card_es968 *acard,
78 struct pnp_card_link *card,
79 const struct pnp_card_device_id *id)
80{
81 struct pnp_dev *pdev;
82 int err;
83
84 acard->dev = pnp_request_card_device(card, id->devs[0].id, NULL);
85 if (acard->dev == NULL)
86 return -ENODEV;
87
88 pdev = acard->dev;
89
90 err = pnp_activate_dev(pdev);
91 if (err < 0) {
92 snd_printk(KERN_ERR PFX "AUDIO pnp configure failure\n");
93 return err;
94 }
95 port[dev] = pnp_port_start(pdev, 0);
96 dma8[dev] = pnp_dma(pdev, 1);
97 irq[dev] = pnp_irq(pdev, 0);
98
99 return 0;
100}
101
102static int __devinit snd_card_es968_probe(int dev,
103 struct pnp_card_link *pcard,
104 const struct pnp_card_device_id *pid)
105{
106 int error;
107 struct snd_sb *chip;
108 struct snd_card *card;
109 struct snd_card_es968 *acard;
110
111 error = snd_card_create(index[dev], id[dev], THIS_MODULE,
112 sizeof(struct snd_card_es968), &card);
113 if (error < 0)
114 return error;
115 acard = card->private_data;
116 if ((error = snd_card_es968_pnp(dev, acard, pcard, pid))) {
117 snd_card_free(card);
118 return error;
119 }
120 snd_card_set_dev(card, &pcard->card->dev);
121
122 if ((error = snd_sbdsp_create(card, port[dev],
123 irq[dev],
124 snd_card_es968_interrupt,
125 dma8[dev],
126 -1,
127 SB_HW_AUTO, &chip)) < 0) {
128 snd_card_free(card);
129 return error;
130 }
131 acard->chip = chip;
132
133 if ((error = snd_sb8dsp_pcm(chip, 0, NULL)) < 0) {
134 snd_card_free(card);
135 return error;
136 }
137
138 if ((error = snd_sbmixer_new(chip)) < 0) {
139 snd_card_free(card);
140 return error;
141 }
142
143 if ((error = snd_sb8dsp_midi(chip, 0, NULL)) < 0) {
144 snd_card_free(card);
145 return error;
146 }
147
148 strcpy(card->driver, "ES968");
149 strcpy(card->shortname, "ESS ES968");
150 sprintf(card->longname, "%s soundcard, %s at 0x%lx, irq %d, dma %d",
151 card->shortname, chip->name, chip->port, irq[dev], dma8[dev]);
152
153 if ((error = snd_card_register(card)) < 0) {
154 snd_card_free(card);
155 return error;
156 }
157 pnp_set_card_drvdata(pcard, card);
158 return 0;
159}
160
161static unsigned int __devinitdata es968_devices;
162
163static int __devinit snd_es968_pnp_detect(struct pnp_card_link *card,
164 const struct pnp_card_device_id *id)
165{
166 static int dev;
167 int res;
168
169 for ( ; dev < SNDRV_CARDS; dev++) {
170 if (!enable[dev])
171 continue;
172 res = snd_card_es968_probe(dev, card, id);
173 if (res < 0)
174 return res;
175 dev++;
176 es968_devices++;
177 return 0;
178 }
179 return -ENODEV;
180}
181
182static void __devexit snd_es968_pnp_remove(struct pnp_card_link * pcard)
183{
184 snd_card_free(pnp_get_card_drvdata(pcard));
185 pnp_set_card_drvdata(pcard, NULL);
186}
187
188#ifdef CONFIG_PM
189static int snd_es968_pnp_suspend(struct pnp_card_link *pcard, pm_message_t state)
190{
191 struct snd_card *card = pnp_get_card_drvdata(pcard);
192 struct snd_card_es968 *acard = card->private_data;
193 struct snd_sb *chip = acard->chip;
194
195 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
196 snd_pcm_suspend_all(chip->pcm);
197 snd_sbmixer_suspend(chip);
198 return 0;
199}
200
201static int snd_es968_pnp_resume(struct pnp_card_link *pcard)
202{
203 struct snd_card *card = pnp_get_card_drvdata(pcard);
204 struct snd_card_es968 *acard = card->private_data;
205 struct snd_sb *chip = acard->chip;
206
207 snd_sbdsp_reset(chip);
208 snd_sbmixer_resume(chip);
209 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
210 return 0;
211}
212#endif
213
214static struct pnp_card_driver es968_pnpc_driver = {
215 .flags = PNP_DRIVER_RES_DISABLE,
216 .name = "es968",
217 .id_table = snd_es968_pnpids,
218 .probe = snd_es968_pnp_detect,
219 .remove = __devexit_p(snd_es968_pnp_remove),
220#ifdef CONFIG_PM
221 .suspend = snd_es968_pnp_suspend,
222 .resume = snd_es968_pnp_resume,
223#endif
224};
225
226static int __init alsa_card_es968_init(void)
227{
228 int err = pnp_register_card_driver(&es968_pnpc_driver);
229 if (err)
230 return err;
231
232 if (!es968_devices) {
233 pnp_unregister_card_driver(&es968_pnpc_driver);
234#ifdef MODULE
235 snd_printk(KERN_ERR "no ES968 based soundcards found\n");
236#endif
237 return -ENODEV;
238 }
239 return 0;
240}
241
242static void __exit alsa_card_es968_exit(void)
243{
244 pnp_unregister_card_driver(&es968_pnpc_driver);
245}
246
247module_init(alsa_card_es968_init)
248module_exit(alsa_card_es968_exit)
diff --git a/sound/isa/sb/sb16.c b/sound/isa/sb/sb16.c
index 519c36346dec..4d1c5a300ff8 100644
--- a/sound/isa/sb/sb16.c
+++ b/sound/isa/sb/sb16.c
@@ -21,7 +21,6 @@
21 21
22#include <asm/dma.h> 22#include <asm/dma.h>
23#include <linux/init.h> 23#include <linux/init.h>
24#include <linux/slab.h>
25#include <linux/pnp.h> 24#include <linux/pnp.h>
26#include <linux/err.h> 25#include <linux/err.h>
27#include <linux/isa.h> 26#include <linux/isa.h>
diff --git a/sound/isa/sb/sb8.c b/sound/isa/sb/sb8.c
index 3cd57ee54660..81284a8fa0ce 100644
--- a/sound/isa/sb/sb8.c
+++ b/sound/isa/sb/sb8.c
@@ -22,7 +22,6 @@
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/err.h> 23#include <linux/err.h>
24#include <linux/isa.h> 24#include <linux/isa.h>
25#include <linux/slab.h>
26#include <linux/ioport.h> 25#include <linux/ioport.h>
27#include <linux/moduleparam.h> 26#include <linux/moduleparam.h>
28#include <sound/core.h> 27#include <sound/core.h>
diff --git a/sound/isa/wavefront/wavefront.c b/sound/isa/wavefront/wavefront.c
index a34ae7b1f7d0..711670e4a425 100644
--- a/sound/isa/wavefront/wavefront.c
+++ b/sound/isa/wavefront/wavefront.c
@@ -21,7 +21,6 @@
21 21
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/interrupt.h> 23#include <linux/interrupt.h>
24#include <linux/slab.h>
25#include <linux/err.h> 24#include <linux/err.h>
26#include <linux/isa.h> 25#include <linux/isa.h>
27#include <linux/pnp.h> 26#include <linux/pnp.h>
diff --git a/sound/isa/wavefront/wavefront_fx.c b/sound/isa/wavefront/wavefront_fx.c
index 2bb1cee09255..657e2d6c01ac 100644
--- a/sound/isa/wavefront/wavefront_fx.c
+++ b/sound/isa/wavefront/wavefront_fx.c
@@ -20,6 +20,7 @@
20#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/time.h> 21#include <linux/time.h>
22#include <linux/wait.h> 22#include <linux/wait.h>
23#include <linux/slab.h>
23#include <linux/firmware.h> 24#include <linux/firmware.h>
24#include <sound/core.h> 25#include <sound/core.h>
25#include <sound/snd_wavefront.h> 26#include <sound/snd_wavefront.h>
diff --git a/sound/isa/wavefront/wavefront_synth.c b/sound/isa/wavefront/wavefront_synth.c
index 5d4ff48c4345..4fb7b19ff393 100644
--- a/sound/isa/wavefront/wavefront_synth.c
+++ b/sound/isa/wavefront/wavefront_synth.c
@@ -28,6 +28,7 @@
28#include <linux/wait.h> 28#include <linux/wait.h>
29#include <linux/firmware.h> 29#include <linux/firmware.h>
30#include <linux/moduleparam.h> 30#include <linux/moduleparam.h>
31#include <linux/slab.h>
31#include <sound/core.h> 32#include <sound/core.h>
32#include <sound/snd_wavefront.h> 33#include <sound/snd_wavefront.h>
33#include <sound/initval.h> 34#include <sound/initval.h>
diff --git a/sound/mips/au1x00.c b/sound/mips/au1x00.c
index 3e763d6a5d67..446cf9748664 100644
--- a/sound/mips/au1x00.c
+++ b/sound/mips/au1x00.c
@@ -516,6 +516,7 @@ get the interrupt driven case to work efficiently */
516 break; 516 break;
517 if (i == 0x5000) { 517 if (i == 0x5000) {
518 printk(KERN_ERR "au1000 AC97: AC97 command read timeout\n"); 518 printk(KERN_ERR "au1000 AC97: AC97 command read timeout\n");
519 spin_unlock(&au1000->ac97_lock);
519 return 0; 520 return 0;
520 } 521 }
521 522
diff --git a/sound/mips/hal2.c b/sound/mips/hal2.c
index 9a88cdfd952a..453d343550a8 100644
--- a/sound/mips/hal2.c
+++ b/sound/mips/hal2.c
@@ -25,6 +25,7 @@
25#include <linux/dma-mapping.h> 25#include <linux/dma-mapping.h>
26#include <linux/platform_device.h> 26#include <linux/platform_device.h>
27#include <linux/io.h> 27#include <linux/io.h>
28#include <linux/slab.h>
28 29
29#include <asm/sgi/hpc3.h> 30#include <asm/sgi/hpc3.h>
30#include <asm/sgi/ip22.h> 31#include <asm/sgi/ip22.h>
diff --git a/sound/mips/sgio2audio.c b/sound/mips/sgio2audio.c
index 6aff217379d9..717604c00f0a 100644
--- a/sound/mips/sgio2audio.c
+++ b/sound/mips/sgio2audio.c
@@ -25,11 +25,11 @@
25#include <linux/init.h> 25#include <linux/init.h>
26#include <linux/delay.h> 26#include <linux/delay.h>
27#include <linux/spinlock.h> 27#include <linux/spinlock.h>
28#include <linux/gfp.h>
29#include <linux/interrupt.h> 28#include <linux/interrupt.h>
30#include <linux/dma-mapping.h> 29#include <linux/dma-mapping.h>
31#include <linux/platform_device.h> 30#include <linux/platform_device.h>
32#include <linux/io.h> 31#include <linux/io.h>
32#include <linux/slab.h>
33 33
34#include <asm/ip32/ip32_ints.h> 34#include <asm/ip32/ip32_ints.h>
35#include <asm/ip32/mace.h> 35#include <asm/ip32/mace.h>
diff --git a/sound/oss/ad1848.c b/sound/oss/ad1848.c
index d12bd98a37ba..24793c5b65ac 100644
--- a/sound/oss/ad1848.c
+++ b/sound/oss/ad1848.c
@@ -45,6 +45,7 @@
45#include <linux/interrupt.h> 45#include <linux/interrupt.h>
46#include <linux/module.h> 46#include <linux/module.h>
47#include <linux/stddef.h> 47#include <linux/stddef.h>
48#include <linux/slab.h>
48#include <linux/isapnp.h> 49#include <linux/isapnp.h>
49#include <linux/pnp.h> 50#include <linux/pnp.h>
50#include <linux/spinlock.h> 51#include <linux/spinlock.h>
diff --git a/sound/oss/dmabuf.c b/sound/oss/dmabuf.c
index 1bfcf7e88546..bcc3e8e07122 100644
--- a/sound/oss/dmabuf.c
+++ b/sound/oss/dmabuf.c
@@ -26,6 +26,7 @@
26#define SAMPLE_ROUNDUP 0 26#define SAMPLE_ROUNDUP 0
27 27
28#include <linux/mm.h> 28#include <linux/mm.h>
29#include <linux/gfp.h>
29#include "sound_config.h" 30#include "sound_config.h"
30 31
31#define DMAP_FREE_ON_CLOSE 0 32#define DMAP_FREE_ON_CLOSE 0
diff --git a/sound/oss/dmasound/dmasound_atari.c b/sound/oss/dmasound/dmasound_atari.c
index 1f4774123064..13c214466d3b 100644
--- a/sound/oss/dmasound/dmasound_atari.c
+++ b/sound/oss/dmasound/dmasound_atari.c
@@ -1277,7 +1277,7 @@ static irqreturn_t AtaInterrupt(int irq, void *dummy)
1277 * (almost) like on the TT. 1277 * (almost) like on the TT.
1278 */ 1278 */
1279 write_sq_ignore_int = 0; 1279 write_sq_ignore_int = 0;
1280 return IRQ_HANDLED; 1280 goto out;
1281 } 1281 }
1282 1282
1283 if (!write_sq.active) { 1283 if (!write_sq.active) {
@@ -1285,7 +1285,7 @@ static irqreturn_t AtaInterrupt(int irq, void *dummy)
1285 * the sq variables, so better don't do anything here. 1285 * the sq variables, so better don't do anything here.
1286 */ 1286 */
1287 WAKE_UP(write_sq.sync_queue); 1287 WAKE_UP(write_sq.sync_queue);
1288 return IRQ_HANDLED; 1288 goto out;
1289 } 1289 }
1290 1290
1291 /* Probably ;) one frame is finished. Well, in fact it may be that a 1291 /* Probably ;) one frame is finished. Well, in fact it may be that a
@@ -1322,6 +1322,7 @@ static irqreturn_t AtaInterrupt(int irq, void *dummy)
1322 /* We are not playing after AtaPlay(), so there 1322 /* We are not playing after AtaPlay(), so there
1323 is nothing to play any more. Wake up a process 1323 is nothing to play any more. Wake up a process
1324 waiting for audio output to drain. */ 1324 waiting for audio output to drain. */
1325out:
1325 spin_unlock(&dmasound.lock); 1326 spin_unlock(&dmasound.lock);
1326 return IRQ_HANDLED; 1327 return IRQ_HANDLED;
1327} 1328}
diff --git a/sound/oss/dmasound/dmasound_paula.c b/sound/oss/dmasound/dmasound_paula.c
index bb14e4c67e89..87910e992133 100644
--- a/sound/oss/dmasound/dmasound_paula.c
+++ b/sound/oss/dmasound/dmasound_paula.c
@@ -21,6 +21,7 @@
21#include <linux/ioport.h> 21#include <linux/ioport.h>
22#include <linux/soundcard.h> 22#include <linux/soundcard.h>
23#include <linux/interrupt.h> 23#include <linux/interrupt.h>
24#include <linux/platform_device.h>
24 25
25#include <asm/uaccess.h> 26#include <asm/uaccess.h>
26#include <asm/setup.h> 27#include <asm/setup.h>
@@ -710,31 +711,41 @@ static MACHINE machAmiga = {
710/*** Config & Setup **********************************************************/ 711/*** Config & Setup **********************************************************/
711 712
712 713
713static int __init dmasound_paula_init(void) 714static int __init amiga_audio_probe(struct platform_device *pdev)
714{ 715{
715 int err; 716 dmasound.mach = machAmiga;
716 717 dmasound.mach.default_hard = def_hard ;
717 if (MACH_IS_AMIGA && AMIGAHW_PRESENT(AMI_AUDIO)) { 718 dmasound.mach.default_soft = def_soft ;
718 if (!request_mem_region(CUSTOM_PHYSADDR+0xa0, 0x40, 719 return dmasound_init();
719 "dmasound [Paula]"))
720 return -EBUSY;
721 dmasound.mach = machAmiga;
722 dmasound.mach.default_hard = def_hard ;
723 dmasound.mach.default_soft = def_soft ;
724 err = dmasound_init();
725 if (err)
726 release_mem_region(CUSTOM_PHYSADDR+0xa0, 0x40);
727 return err;
728 } else
729 return -ENODEV;
730} 720}
731 721
732static void __exit dmasound_paula_cleanup(void) 722static int __exit amiga_audio_remove(struct platform_device *pdev)
733{ 723{
734 dmasound_deinit(); 724 dmasound_deinit();
735 release_mem_region(CUSTOM_PHYSADDR+0xa0, 0x40); 725 return 0;
726}
727
728static struct platform_driver amiga_audio_driver = {
729 .remove = __exit_p(amiga_audio_remove),
730 .driver = {
731 .name = "amiga-audio",
732 .owner = THIS_MODULE,
733 },
734};
735
736static int __init amiga_audio_init(void)
737{
738 return platform_driver_probe(&amiga_audio_driver, amiga_audio_probe);
736} 739}
737 740
738module_init(dmasound_paula_init); 741module_init(amiga_audio_init);
739module_exit(dmasound_paula_cleanup); 742
743static void __exit amiga_audio_exit(void)
744{
745 platform_driver_unregister(&amiga_audio_driver);
746}
747
748module_exit(amiga_audio_exit);
749
740MODULE_LICENSE("GPL"); 750MODULE_LICENSE("GPL");
751MODULE_ALIAS("platform:amiga-audio");
diff --git a/sound/oss/kahlua.c b/sound/oss/kahlua.c
index 24d152ccf80d..52d06a334e8f 100644
--- a/sound/oss/kahlua.c
+++ b/sound/oss/kahlua.c
@@ -31,6 +31,7 @@
31#include <linux/init.h> 31#include <linux/init.h>
32#include <linux/module.h> 32#include <linux/module.h>
33#include <linux/pci.h> 33#include <linux/pci.h>
34#include <linux/slab.h>
34 35
35#include "sound_config.h" 36#include "sound_config.h"
36 37
diff --git a/sound/oss/mpu401.c b/sound/oss/mpu401.c
index 0af9d24feb8f..25e4609f8339 100644
--- a/sound/oss/mpu401.c
+++ b/sound/oss/mpu401.c
@@ -19,6 +19,7 @@
19 */ 19 */
20 20
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/slab.h>
22#include <linux/init.h> 23#include <linux/init.h>
23#include <linux/interrupt.h> 24#include <linux/interrupt.h>
24#include <linux/spinlock.h> 25#include <linux/spinlock.h>
diff --git a/sound/oss/msnd.c b/sound/oss/msnd.c
index 21eb6dce46df..c0cc951ba97d 100644
--- a/sound/oss/msnd.c
+++ b/sound/oss/msnd.c
@@ -24,7 +24,6 @@
24 24
25#include <linux/module.h> 25#include <linux/module.h>
26#include <linux/kernel.h> 26#include <linux/kernel.h>
27#include <linux/slab.h>
28#include <linux/vmalloc.h> 27#include <linux/vmalloc.h>
29#include <linux/types.h> 28#include <linux/types.h>
30#include <linux/delay.h> 29#include <linux/delay.h>
diff --git a/sound/oss/msnd_pinnacle.c b/sound/oss/msnd_pinnacle.c
index bf27e008f465..a1e3f9671bea 100644
--- a/sound/oss/msnd_pinnacle.c
+++ b/sound/oss/msnd_pinnacle.c
@@ -35,12 +35,12 @@
35 35
36#include <linux/kernel.h> 36#include <linux/kernel.h>
37#include <linux/module.h> 37#include <linux/module.h>
38#include <linux/slab.h>
39#include <linux/types.h> 38#include <linux/types.h>
40#include <linux/delay.h> 39#include <linux/delay.h>
41#include <linux/init.h> 40#include <linux/init.h>
42#include <linux/interrupt.h> 41#include <linux/interrupt.h>
43#include <linux/smp_lock.h> 42#include <linux/smp_lock.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>
46#include "sound_config.h" 46#include "sound_config.h"
diff --git a/sound/oss/opl3.c b/sound/oss/opl3.c
index 7781c13c1476..938c48c43585 100644
--- a/sound/oss/opl3.c
+++ b/sound/oss/opl3.c
@@ -24,6 +24,7 @@
24 */ 24 */
25 25
26#include <linux/init.h> 26#include <linux/init.h>
27#include <linux/slab.h>
27#include <linux/module.h> 28#include <linux/module.h>
28#include <linux/delay.h> 29#include <linux/delay.h>
29 30
diff --git a/sound/oss/sb_card.c b/sound/oss/sb_card.c
index 7de18b58f2cd..84ef4d06c1c2 100644
--- a/sound/oss/sb_card.c
+++ b/sound/oss/sb_card.c
@@ -24,6 +24,7 @@
24 24
25#include <linux/module.h> 25#include <linux/module.h>
26#include <linux/moduleparam.h> 26#include <linux/moduleparam.h>
27#include <linux/slab.h>
27#include <linux/init.h> 28#include <linux/init.h>
28#include "sound_config.h" 29#include "sound_config.h"
29#include "sb_mixer.h" 30#include "sb_mixer.h"
diff --git a/sound/oss/sb_common.c b/sound/oss/sb_common.c
index ce4db49291f7..7d42c5418d1b 100644
--- a/sound/oss/sb_common.c
+++ b/sound/oss/sb_common.c
@@ -31,6 +31,7 @@
31#include <linux/module.h> 31#include <linux/module.h>
32#include <linux/delay.h> 32#include <linux/delay.h>
33#include <linux/spinlock.h> 33#include <linux/spinlock.h>
34#include <linux/slab.h>
34 35
35#include "sound_config.h" 36#include "sound_config.h"
36#include "sound_firmware.h" 37#include "sound_firmware.h"
diff --git a/sound/oss/sb_midi.c b/sound/oss/sb_midi.c
index 8b796704e112..f139028e85c0 100644
--- a/sound/oss/sb_midi.c
+++ b/sound/oss/sb_midi.c
@@ -12,6 +12,7 @@
12 */ 12 */
13 13
14#include <linux/spinlock.h> 14#include <linux/spinlock.h>
15#include <linux/slab.h>
15 16
16#include "sound_config.h" 17#include "sound_config.h"
17 18
diff --git a/sound/oss/sb_mixer.c b/sound/oss/sb_mixer.c
index fad1a4f25ad6..2039d31b7e22 100644
--- a/sound/oss/sb_mixer.c
+++ b/sound/oss/sb_mixer.c
@@ -16,6 +16,8 @@
16 * Stanislav Voronyi <stas@esc.kharkov.com> : Support for AWE 3DSE device (Jun 7 1999) 16 * Stanislav Voronyi <stas@esc.kharkov.com> : Support for AWE 3DSE device (Jun 7 1999)
17 */ 17 */
18 18
19#include <linux/slab.h>
20
19#include "sound_config.h" 21#include "sound_config.h"
20 22
21#define __SB_MIXER_C__ 23#define __SB_MIXER_C__
diff --git a/sound/oss/soundcard.c b/sound/oss/soundcard.c
index fde7c12fe5da..2d9c51312622 100644
--- a/sound/oss/soundcard.c
+++ b/sound/oss/soundcard.c
@@ -36,7 +36,6 @@
36#include <asm/dma.h> 36#include <asm/dma.h>
37#include <asm/io.h> 37#include <asm/io.h>
38#include <linux/wait.h> 38#include <linux/wait.h>
39#include <linux/slab.h>
40#include <linux/ioport.h> 39#include <linux/ioport.h>
41#include <linux/major.h> 40#include <linux/major.h>
42#include <linux/delay.h> 41#include <linux/delay.h>
diff --git a/sound/oss/uart401.c b/sound/oss/uart401.c
index a446b826d5fc..8e514a676a0d 100644
--- a/sound/oss/uart401.c
+++ b/sound/oss/uart401.c
@@ -24,6 +24,7 @@
24#include <linux/init.h> 24#include <linux/init.h>
25#include <linux/interrupt.h> 25#include <linux/interrupt.h>
26#include <linux/module.h> 26#include <linux/module.h>
27#include <linux/slab.h>
27#include <linux/spinlock.h> 28#include <linux/spinlock.h>
28#include "sound_config.h" 29#include "sound_config.h"
29 30
diff --git a/sound/oss/v_midi.c b/sound/oss/v_midi.c
index 103940fd5b4f..f0b4151d9b17 100644
--- a/sound/oss/v_midi.c
+++ b/sound/oss/v_midi.c
@@ -21,6 +21,7 @@
21 21
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/slab.h>
24#include <linux/spinlock.h> 25#include <linux/spinlock.h>
25#include "sound_config.h" 26#include "sound_config.h"
26 27
diff --git a/sound/oss/vidc.c b/sound/oss/vidc.c
index 725fef0f59a3..ac39a531df19 100644
--- a/sound/oss/vidc.c
+++ b/sound/oss/vidc.c
@@ -17,6 +17,7 @@
17 * We currently support a mixer device, but it is currently non-functional. 17 * We currently support a mixer device, but it is currently non-functional.
18 */ 18 */
19 19
20#include <linux/gfp.h>
20#include <linux/init.h> 21#include <linux/init.h>
21#include <linux/module.h> 22#include <linux/module.h>
22#include <linux/kernel.h> 23#include <linux/kernel.h>
@@ -363,13 +364,13 @@ static void vidc_audio_trigger(int dev, int enable_bits)
363 struct audio_operations *adev = audio_devs[dev]; 364 struct audio_operations *adev = audio_devs[dev];
364 365
365 if (enable_bits & PCM_ENABLE_OUTPUT) { 366 if (enable_bits & PCM_ENABLE_OUTPUT) {
366 if (!(adev->flags & DMA_ACTIVE)) { 367 if (!(adev->dmap_out->flags & DMA_ACTIVE)) {
367 unsigned long flags; 368 unsigned long flags;
368 369
369 local_irq_save(flags); 370 local_irq_save(flags);
370 371
371 /* prevent recusion */ 372 /* prevent recusion */
372 adev->flags |= DMA_ACTIVE; 373 adev->dmap_out->flags |= DMA_ACTIVE;
373 374
374 dma_interrupt = vidc_audio_dma_interrupt; 375 dma_interrupt = vidc_audio_dma_interrupt;
375 vidc_sound_dma_irq(0, NULL); 376 vidc_sound_dma_irq(0, NULL);
diff --git a/sound/oss/vwsnd.c b/sound/oss/vwsnd.c
index 6713110bdc75..20b3b325aa80 100644
--- a/sound/oss/vwsnd.c
+++ b/sound/oss/vwsnd.c
@@ -149,6 +149,7 @@
149#include <linux/wait.h> 149#include <linux/wait.h>
150#include <linux/interrupt.h> 150#include <linux/interrupt.h>
151#include <linux/mutex.h> 151#include <linux/mutex.h>
152#include <linux/slab.h>
152 153
153#include <asm/visws/cobalt.h> 154#include <asm/visws/cobalt.h>
154 155
diff --git a/sound/oss/waveartist.c b/sound/oss/waveartist.c
index 2c63bb9da74a..e688dde6bbde 100644
--- a/sound/oss/waveartist.c
+++ b/sound/oss/waveartist.c
@@ -35,6 +35,7 @@
35 35
36#include <linux/module.h> 36#include <linux/module.h>
37#include <linux/init.h> 37#include <linux/init.h>
38#include <linux/slab.h>
38#include <linux/sched.h> 39#include <linux/sched.h>
39#include <linux/interrupt.h> 40#include <linux/interrupt.h>
40#include <linux/delay.h> 41#include <linux/delay.h>
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index 1298c68d6bf0..e7a8cd058efb 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -58,6 +58,18 @@ config SND_ALI5451
58 To compile this driver as a module, choose M here: the module 58 To compile this driver as a module, choose M here: the module
59 will be called snd-ali5451. 59 will be called snd-ali5451.
60 60
61config SND_ASIHPI
62 tristate "AudioScience ASIxxxx"
63 depends on X86
64 select FW_LOADER
65 select SND_PCM
66 select SND_HWDEP
67 help
68 Say Y here to include support for AudioScience ASI sound cards.
69
70 To compile this driver as a module, choose M here: the module
71 will be called snd-asihpi.
72
61config SND_ATIIXP 73config SND_ATIIXP
62 tristate "ATI IXP AC97 Controller" 74 tristate "ATI IXP AC97 Controller"
63 select SND_AC97_CODEC 75 select SND_AC97_CODEC
@@ -501,6 +513,16 @@ config SND_ES1968
501 To compile this driver as a module, choose M here: the module 513 To compile this driver as a module, choose M here: the module
502 will be called snd-es1968. 514 will be called snd-es1968.
503 515
516config SND_ES1968_INPUT
517 bool "Enable input device for es1968 volume buttons"
518 depends on SND_ES1968
519 depends on INPUT=y || INPUT=SND_ES1968
520 help
521 If you say Y here, you will get an input device which reports
522 keypresses for the volume buttons connected to the es1968 chip.
523 If you say N the buttons will directly control the master volume.
524 It is recommended to say Y.
525
504config SND_FM801 526config SND_FM801
505 tristate "ForteMedia FM801" 527 tristate "ForteMedia FM801"
506 select SND_OPL3_LIB 528 select SND_OPL3_LIB
@@ -655,6 +677,16 @@ config SND_MAESTRO3
655 To compile this driver as a module, choose M here: the module 677 To compile this driver as a module, choose M here: the module
656 will be called snd-maestro3. 678 will be called snd-maestro3.
657 679
680config SND_MAESTRO3_INPUT
681 bool "Enable input device for maestro3 volume buttons"
682 depends on SND_MAESTRO3
683 depends on INPUT=y || INPUT=SND_MAESTRO3
684 help
685 If you say Y here, you will get an input device which reports
686 keypresses for the volume buttons connected to the maestro3 chip.
687 If you say N the buttons will directly control the master volume.
688 It is recommended to say Y.
689
658config SND_MIXART 690config SND_MIXART
659 tristate "Digigram miXart" 691 tristate "Digigram miXart"
660 select SND_HWDEP 692 select SND_HWDEP
diff --git a/sound/pci/Makefile b/sound/pci/Makefile
index ecfc609d2b9f..9cf4348ec137 100644
--- a/sound/pci/Makefile
+++ b/sound/pci/Makefile
@@ -57,6 +57,7 @@ obj-$(CONFIG_SND_VIA82XX_MODEM) += snd-via82xx-modem.o
57obj-$(CONFIG_SND) += \ 57obj-$(CONFIG_SND) += \
58 ac97/ \ 58 ac97/ \
59 ali5451/ \ 59 ali5451/ \
60 asihpi/ \
60 au88x0/ \ 61 au88x0/ \
61 aw2/ \ 62 aw2/ \
62 ctxfi/ \ 63 ctxfi/ \
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
index 1caf5e3c1f6a..e68c98ef4041 100644
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -1852,12 +1852,14 @@ static unsigned int ad1981_jacks_blacklist[] = {
1852 0x10140523, /* Thinkpad R40 */ 1852 0x10140523, /* Thinkpad R40 */
1853 0x10140534, /* Thinkpad X31 */ 1853 0x10140534, /* Thinkpad X31 */
1854 0x10140537, /* Thinkpad T41p */ 1854 0x10140537, /* Thinkpad T41p */
1855 0x1014053e, /* Thinkpad R40e */
1855 0x10140554, /* Thinkpad T42p/R50p */ 1856 0x10140554, /* Thinkpad T42p/R50p */
1856 0x10140567, /* Thinkpad T43p 2668-G7U */ 1857 0x10140567, /* Thinkpad T43p 2668-G7U */
1857 0x10140581, /* Thinkpad X41-2527 */ 1858 0x10140581, /* Thinkpad X41-2527 */
1858 0x10280160, /* Dell Dimension 2400 */ 1859 0x10280160, /* Dell Dimension 2400 */
1859 0x104380b0, /* Asus A7V8X-MX */ 1860 0x104380b0, /* Asus A7V8X-MX */
1860 0x11790241, /* Toshiba Satellite A-15 S127 */ 1861 0x11790241, /* Toshiba Satellite A-15 S127 */
1862 0x1179ff10, /* Toshiba P500 */
1861 0x144dc01a, /* Samsung NP-X20C004/SEG */ 1863 0x144dc01a, /* Samsung NP-X20C004/SEG */
1862 0 /* end */ 1864 0 /* end */
1863}; 1865};
diff --git a/sound/pci/ac97/ac97_proc.c b/sound/pci/ac97/ac97_proc.c
index 73b17d526c8b..6320bf084e47 100644
--- a/sound/pci/ac97/ac97_proc.c
+++ b/sound/pci/ac97/ac97_proc.c
@@ -22,7 +22,6 @@
22 * 22 *
23 */ 23 */
24 24
25#include <linux/slab.h>
26#include <linux/mutex.h> 25#include <linux/mutex.h>
27 26
28#include <sound/core.h> 27#include <sound/core.h>
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c
index d75cf7b06426..6cf1de8042e8 100644
--- a/sound/pci/als4000.c
+++ b/sound/pci/als4000.c
@@ -68,7 +68,6 @@
68#include <asm/io.h> 68#include <asm/io.h>
69#include <linux/init.h> 69#include <linux/init.h>
70#include <linux/pci.h> 70#include <linux/pci.h>
71#include <linux/slab.h>
72#include <linux/gameport.h> 71#include <linux/gameport.h>
73#include <linux/moduleparam.h> 72#include <linux/moduleparam.h>
74#include <linux/dma-mapping.h> 73#include <linux/dma-mapping.h>
diff --git a/sound/pci/asihpi/Makefile b/sound/pci/asihpi/Makefile
new file mode 100644
index 000000000000..391830a4556c
--- /dev/null
+++ b/sound/pci/asihpi/Makefile
@@ -0,0 +1,5 @@
1snd-asihpi-objs := asihpi.o hpioctl.o hpimsginit.o\
2 hpicmn.o hpifunc.o hpidebug.o hpidspcd.o\
3 hpios.o hpi6000.o hpi6205.o hpimsgx.o
4
5obj-$(CONFIG_SND_ASIHPI) += snd-asihpi.o
diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c
new file mode 100644
index 000000000000..f74c7372b3d1
--- /dev/null
+++ b/sound/pci/asihpi/asihpi.c
@@ -0,0 +1,3002 @@
1/*
2 * Asihpi soundcard
3 * Copyright (c) by AudioScience Inc <alsa@audioscience.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 *
19 * The following is not a condition of use, merely a request:
20 * If you modify this program, particularly if you fix errors, AudioScience Inc
21 * would appreciate it if you grant us the right to use those modifications
22 * for any purpose including commercial applications.
23 */
24/* >0: print Hw params, timer vars. >1: print stream write/copy sizes */
25#define REALLY_VERBOSE_LOGGING 0
26
27#if REALLY_VERBOSE_LOGGING
28#define VPRINTK1 snd_printd
29#else
30#define VPRINTK1(...)
31#endif
32
33#if REALLY_VERBOSE_LOGGING > 1
34#define VPRINTK2 snd_printd
35#else
36#define VPRINTK2(...)
37#endif
38
39#ifndef ASI_STYLE_NAMES
40/* not sure how ALSA style name should look */
41#define ASI_STYLE_NAMES 1
42#endif
43
44#include "hpi_internal.h"
45#include "hpimsginit.h"
46#include "hpioctl.h"
47
48#include <linux/pci.h>
49#include <linux/init.h>
50#include <linux/jiffies.h>
51#include <linux/slab.h>
52#include <linux/time.h>
53#include <linux/wait.h>
54#include <sound/core.h>
55#include <sound/control.h>
56#include <sound/pcm.h>
57#include <sound/pcm_params.h>
58#include <sound/info.h>
59#include <sound/initval.h>
60#include <sound/tlv.h>
61#include <sound/hwdep.h>
62
63
64MODULE_LICENSE("GPL");
65MODULE_AUTHOR("AudioScience inc. <support@audioscience.com>");
66MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx");
67
68static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* index 0-MAX */
69static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
70static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
71static int enable_hpi_hwdep = 1;
72
73module_param_array(index, int, NULL, S_IRUGO);
74MODULE_PARM_DESC(index, "ALSA index value for AudioScience soundcard.");
75
76module_param_array(id, charp, NULL, S_IRUGO);
77MODULE_PARM_DESC(id, "ALSA ID string for AudioScience soundcard.");
78
79module_param_array(enable, bool, NULL, S_IRUGO);
80MODULE_PARM_DESC(enable, "ALSA enable AudioScience soundcard.");
81
82module_param(enable_hpi_hwdep, bool, S_IRUGO|S_IWUSR);
83MODULE_PARM_DESC(enable_hpi_hwdep,
84 "ALSA enable HPI hwdep for AudioScience soundcard ");
85
86/* identify driver */
87#ifdef KERNEL_ALSA_BUILD
88static char *build_info = "built using headers from kernel source";
89module_param(build_info, charp, S_IRUGO);
90MODULE_PARM_DESC(build_info, "built using headers from kernel source");
91#else
92static char *build_info = "built within ALSA source";
93module_param(build_info, charp, S_IRUGO);
94MODULE_PARM_DESC(build_info, "built within ALSA source");
95#endif
96
97/* set to 1 to dump every control from adapter to log */
98static const int mixer_dump;
99
100#define DEFAULT_SAMPLERATE 44100
101static int adapter_fs = DEFAULT_SAMPLERATE;
102
103static struct hpi_hsubsys *ss; /* handle to HPI audio subsystem */
104
105/* defaults */
106#define PERIODS_MIN 2
107#define PERIOD_BYTES_MIN 2304
108#define BUFFER_BYTES_MAX (512 * 1024)
109
110/*#define TIMER_MILLISECONDS 20
111#define FORCE_TIMER_JIFFIES ((TIMER_MILLISECONDS * HZ + 999)/1000)
112*/
113
114#define MAX_CLOCKSOURCES (HPI_SAMPLECLOCK_SOURCE_LAST + 1 + 7)
115
116struct clk_source {
117 int source;
118 int index;
119 char *name;
120};
121
122struct clk_cache {
123 int count;
124 int has_local;
125 struct clk_source s[MAX_CLOCKSOURCES];
126};
127
128/* Per card data */
129struct snd_card_asihpi {
130 struct snd_card *card;
131 struct pci_dev *pci;
132 u16 adapter_index;
133 u32 serial_number;
134 u16 type;
135 u16 version;
136 u16 num_outstreams;
137 u16 num_instreams;
138
139 u32 h_mixer;
140 struct clk_cache cc;
141
142 u16 support_mmap;
143 u16 support_grouping;
144 u16 support_mrx;
145 u16 update_interval_frames;
146 u16 in_max_chans;
147 u16 out_max_chans;
148};
149
150/* Per stream data */
151struct snd_card_asihpi_pcm {
152 struct timer_list timer;
153 unsigned int respawn_timer;
154 unsigned int hpi_buffer_attached;
155 unsigned int pcm_size;
156 unsigned int pcm_count;
157 unsigned int bytes_per_sec;
158 unsigned int pcm_irq_pos; /* IRQ position */
159 unsigned int pcm_buf_pos; /* position in buffer */
160 struct snd_pcm_substream *substream;
161 u32 h_stream;
162 struct hpi_format format;
163};
164
165/* universal stream verbs work with out or in stream handles */
166
167/* Functions to allow driver to give a buffer to HPI for busmastering */
168
169static u16 hpi_stream_host_buffer_attach(
170 struct hpi_hsubsys *hS,
171 u32 h_stream, /* handle to outstream. */
172 u32 size_in_bytes, /* size in bytes of bus mastering buffer */
173 u32 pci_address
174)
175{
176 struct hpi_message hm;
177 struct hpi_response hr;
178 unsigned int obj = hpi_handle_object(h_stream);
179
180 if (!h_stream)
181 return HPI_ERROR_INVALID_OBJ;
182 hpi_init_message_response(&hm, &hr, obj,
183 obj == HPI_OBJ_OSTREAM ?
184 HPI_OSTREAM_HOSTBUFFER_ALLOC :
185 HPI_ISTREAM_HOSTBUFFER_ALLOC);
186
187 hpi_handle_to_indexes(h_stream, &hm.adapter_index,
188 &hm.obj_index);
189
190 hm.u.d.u.buffer.buffer_size = size_in_bytes;
191 hm.u.d.u.buffer.pci_address = pci_address;
192 hm.u.d.u.buffer.command = HPI_BUFFER_CMD_INTERNAL_GRANTADAPTER;
193 hpi_send_recv(&hm, &hr);
194 return hr.error;
195}
196
197static u16 hpi_stream_host_buffer_detach(
198 struct hpi_hsubsys *hS,
199 u32 h_stream
200)
201{
202 struct hpi_message hm;
203 struct hpi_response hr;
204 unsigned int obj = hpi_handle_object(h_stream);
205
206 if (!h_stream)
207 return HPI_ERROR_INVALID_OBJ;
208
209 hpi_init_message_response(&hm, &hr, obj,
210 obj == HPI_OBJ_OSTREAM ?
211 HPI_OSTREAM_HOSTBUFFER_FREE :
212 HPI_ISTREAM_HOSTBUFFER_FREE);
213
214 hpi_handle_to_indexes(h_stream, &hm.adapter_index,
215 &hm.obj_index);
216 hm.u.d.u.buffer.command = HPI_BUFFER_CMD_INTERNAL_REVOKEADAPTER;
217 hpi_send_recv(&hm, &hr);
218 return hr.error;
219}
220
221static inline u16 hpi_stream_start(struct hpi_hsubsys *hS, u32 h_stream)
222{
223 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
224 return hpi_outstream_start(hS, h_stream);
225 else
226 return hpi_instream_start(hS, h_stream);
227}
228
229static inline u16 hpi_stream_stop(struct hpi_hsubsys *hS, u32 h_stream)
230{
231 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
232 return hpi_outstream_stop(hS, h_stream);
233 else
234 return hpi_instream_stop(hS, h_stream);
235}
236
237static inline u16 hpi_stream_get_info_ex(
238 struct hpi_hsubsys *hS,
239 u32 h_stream,
240 u16 *pw_state,
241 u32 *pbuffer_size,
242 u32 *pdata_in_buffer,
243 u32 *psample_count,
244 u32 *pauxiliary_data
245)
246{
247 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
248 return hpi_outstream_get_info_ex(hS, h_stream, pw_state,
249 pbuffer_size, pdata_in_buffer,
250 psample_count, pauxiliary_data);
251 else
252 return hpi_instream_get_info_ex(hS, h_stream, pw_state,
253 pbuffer_size, pdata_in_buffer,
254 psample_count, pauxiliary_data);
255}
256
257static inline u16 hpi_stream_group_add(struct hpi_hsubsys *hS,
258 u32 h_master,
259 u32 h_stream)
260{
261 if (hpi_handle_object(h_master) == HPI_OBJ_OSTREAM)
262 return hpi_outstream_group_add(hS, h_master, h_stream);
263 else
264 return hpi_instream_group_add(hS, h_master, h_stream);
265}
266
267static inline u16 hpi_stream_group_reset(struct hpi_hsubsys *hS,
268 u32 h_stream)
269{
270 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
271 return hpi_outstream_group_reset(hS, h_stream);
272 else
273 return hpi_instream_group_reset(hS, h_stream);
274}
275
276static inline u16 hpi_stream_group_get_map(struct hpi_hsubsys *hS,
277 u32 h_stream, u32 *mo, u32 *mi)
278{
279 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
280 return hpi_outstream_group_get_map(hS, h_stream, mo, mi);
281 else
282 return hpi_instream_group_get_map(hS, h_stream, mo, mi);
283}
284
285static u16 handle_error(u16 err, int line, char *filename)
286{
287 if (err)
288 printk(KERN_WARNING
289 "in file %s, line %d: HPI error %d\n",
290 filename, line, err);
291 return err;
292}
293
294#define hpi_handle_error(x) handle_error(x, __LINE__, __FILE__)
295
296/***************************** GENERAL PCM ****************/
297#if REALLY_VERBOSE_LOGGING
298static void print_hwparams(struct snd_pcm_hw_params *p)
299{
300 snd_printd("HWPARAMS \n");
301 snd_printd("samplerate %d \n", params_rate(p));
302 snd_printd("channels %d \n", params_channels(p));
303 snd_printd("format %d \n", params_format(p));
304 snd_printd("subformat %d \n", params_subformat(p));
305 snd_printd("buffer bytes %d \n", params_buffer_bytes(p));
306 snd_printd("period bytes %d \n", params_period_bytes(p));
307 snd_printd("access %d \n", params_access(p));
308 snd_printd("period_size %d \n", params_period_size(p));
309 snd_printd("periods %d \n", params_periods(p));
310 snd_printd("buffer_size %d \n", params_buffer_size(p));
311}
312#else
313#define print_hwparams(x)
314#endif
315
316static snd_pcm_format_t hpi_to_alsa_formats[] = {
317 -1, /* INVALID */
318 SNDRV_PCM_FORMAT_U8, /* HPI_FORMAT_PCM8_UNSIGNED 1 */
319 SNDRV_PCM_FORMAT_S16, /* HPI_FORMAT_PCM16_SIGNED 2 */
320 -1, /* HPI_FORMAT_MPEG_L1 3 */
321 SNDRV_PCM_FORMAT_MPEG, /* HPI_FORMAT_MPEG_L2 4 */
322 SNDRV_PCM_FORMAT_MPEG, /* HPI_FORMAT_MPEG_L3 5 */
323 -1, /* HPI_FORMAT_DOLBY_AC2 6 */
324 -1, /* HPI_FORMAT_DOLBY_AC3 7 */
325 SNDRV_PCM_FORMAT_S16_BE,/* HPI_FORMAT_PCM16_BIGENDIAN 8 */
326 -1, /* HPI_FORMAT_AA_TAGIT1_HITS 9 */
327 -1, /* HPI_FORMAT_AA_TAGIT1_INSERTS 10 */
328 SNDRV_PCM_FORMAT_S32, /* HPI_FORMAT_PCM32_SIGNED 11 */
329 -1, /* HPI_FORMAT_RAW_BITSTREAM 12 */
330 -1, /* HPI_FORMAT_AA_TAGIT1_HITS_EX1 13 */
331 SNDRV_PCM_FORMAT_FLOAT, /* HPI_FORMAT_PCM32_FLOAT 14 */
332#if 1
333 /* ALSA can't handle 3 byte sample size together with power-of-2
334 * constraint on buffer_bytes, so disable this format
335 */
336 -1
337#else
338 /* SNDRV_PCM_FORMAT_S24_3LE */ /* { HPI_FORMAT_PCM24_SIGNED 15 */
339#endif
340};
341
342
343static int snd_card_asihpi_format_alsa2hpi(snd_pcm_format_t alsa_format,
344 u16 *hpi_format)
345{
346 u16 format;
347
348 for (format = HPI_FORMAT_PCM8_UNSIGNED;
349 format <= HPI_FORMAT_PCM24_SIGNED; format++) {
350 if (hpi_to_alsa_formats[format] == alsa_format) {
351 *hpi_format = format;
352 return 0;
353 }
354 }
355
356 snd_printd(KERN_WARNING "failed match for alsa format %d\n",
357 alsa_format);
358 *hpi_format = 0;
359 return -EINVAL;
360}
361
362static void snd_card_asihpi_pcm_samplerates(struct snd_card_asihpi *asihpi,
363 struct snd_pcm_hardware *pcmhw)
364{
365 u16 err;
366 u32 h_control;
367 u32 sample_rate;
368 int idx;
369 unsigned int rate_min = 200000;
370 unsigned int rate_max = 0;
371 unsigned int rates = 0;
372
373 if (asihpi->support_mrx) {
374 rates |= SNDRV_PCM_RATE_CONTINUOUS;
375 rates |= SNDRV_PCM_RATE_8000_96000;
376 rate_min = 8000;
377 rate_max = 100000;
378 } else {
379 /* on cards without SRC,
380 valid rates are determined by sampleclock */
381 err = hpi_mixer_get_control(ss, asihpi->h_mixer,
382 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
383 HPI_CONTROL_SAMPLECLOCK, &h_control);
384 if (err) {
385 snd_printk(KERN_ERR
386 "no local sampleclock, err %d\n", err);
387 }
388
389 for (idx = 0; idx < 100; idx++) {
390 if (hpi_sample_clock_query_local_rate(ss,
391 h_control, idx, &sample_rate)) {
392 if (!idx)
393 snd_printk(KERN_ERR
394 "local rate query failed\n");
395
396 break;
397 }
398
399 rate_min = min(rate_min, sample_rate);
400 rate_max = max(rate_max, sample_rate);
401
402 switch (sample_rate) {
403 case 5512:
404 rates |= SNDRV_PCM_RATE_5512;
405 break;
406 case 8000:
407 rates |= SNDRV_PCM_RATE_8000;
408 break;
409 case 11025:
410 rates |= SNDRV_PCM_RATE_11025;
411 break;
412 case 16000:
413 rates |= SNDRV_PCM_RATE_16000;
414 break;
415 case 22050:
416 rates |= SNDRV_PCM_RATE_22050;
417 break;
418 case 32000:
419 rates |= SNDRV_PCM_RATE_32000;
420 break;
421 case 44100:
422 rates |= SNDRV_PCM_RATE_44100;
423 break;
424 case 48000:
425 rates |= SNDRV_PCM_RATE_48000;
426 break;
427 case 64000:
428 rates |= SNDRV_PCM_RATE_64000;
429 break;
430 case 88200:
431 rates |= SNDRV_PCM_RATE_88200;
432 break;
433 case 96000:
434 rates |= SNDRV_PCM_RATE_96000;
435 break;
436 case 176400:
437 rates |= SNDRV_PCM_RATE_176400;
438 break;
439 case 192000:
440 rates |= SNDRV_PCM_RATE_192000;
441 break;
442 default: /* some other rate */
443 rates |= SNDRV_PCM_RATE_KNOT;
444 }
445 }
446 }
447
448 /* printk(KERN_INFO "Supported rates %X %d %d\n",
449 rates, rate_min, rate_max); */
450 pcmhw->rates = rates;
451 pcmhw->rate_min = rate_min;
452 pcmhw->rate_max = rate_max;
453}
454
455static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream,
456 struct snd_pcm_hw_params *params)
457{
458 struct snd_pcm_runtime *runtime = substream->runtime;
459 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
460 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
461 int err;
462 u16 format;
463 unsigned int bytes_per_sec;
464
465 print_hwparams(params);
466 err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
467 if (err < 0)
468 return err;
469 err = snd_card_asihpi_format_alsa2hpi(params_format(params), &format);
470 if (err)
471 return err;
472
473 VPRINTK1(KERN_INFO "format %d, %d chans, %d_hz\n",
474 format, params_channels(params),
475 params_rate(params));
476
477 hpi_handle_error(hpi_format_create(&dpcm->format,
478 params_channels(params),
479 format, params_rate(params), 0, 0));
480
481 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
482 if (hpi_instream_reset(ss, dpcm->h_stream) != 0)
483 return -EINVAL;
484
485 if (hpi_instream_set_format(ss,
486 dpcm->h_stream, &dpcm->format) != 0)
487 return -EINVAL;
488 }
489
490 dpcm->hpi_buffer_attached = 0;
491 if (card->support_mmap) {
492
493 err = hpi_stream_host_buffer_attach(ss, dpcm->h_stream,
494 params_buffer_bytes(params), runtime->dma_addr);
495 if (err == 0) {
496 snd_printd(KERN_INFO
497 "stream_host_buffer_attach succeeded %u %lu\n",
498 params_buffer_bytes(params),
499 (unsigned long)runtime->dma_addr);
500 } else {
501 snd_printd(KERN_INFO
502 "stream_host_buffer_attach error %d\n",
503 err);
504 return -ENOMEM;
505 }
506
507 err = hpi_stream_get_info_ex(ss, dpcm->h_stream, NULL,
508 &dpcm->hpi_buffer_attached,
509 NULL, NULL, NULL);
510
511 snd_printd(KERN_INFO "stream_host_buffer_attach status 0x%x\n",
512 dpcm->hpi_buffer_attached);
513 }
514 bytes_per_sec = params_rate(params) * params_channels(params);
515 bytes_per_sec *= snd_pcm_format_width(params_format(params));
516 bytes_per_sec /= 8;
517 if (bytes_per_sec <= 0)
518 return -EINVAL;
519
520 dpcm->bytes_per_sec = bytes_per_sec;
521 dpcm->pcm_size = params_buffer_bytes(params);
522 dpcm->pcm_count = params_period_bytes(params);
523 snd_printd(KERN_INFO "pcm_size=%d, pcm_count=%d, bps=%d\n",
524 dpcm->pcm_size, dpcm->pcm_count, bytes_per_sec);
525
526 dpcm->pcm_irq_pos = 0;
527 dpcm->pcm_buf_pos = 0;
528 return 0;
529}
530
531static void snd_card_asihpi_pcm_timer_start(struct snd_pcm_substream *
532 substream)
533{
534 struct snd_pcm_runtime *runtime = substream->runtime;
535 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
536 int expiry;
537
538 expiry = (dpcm->pcm_count * HZ / dpcm->bytes_per_sec);
539 /* wait longer the first time, for samples to propagate */
540 expiry = max(expiry, 20);
541 dpcm->timer.expires = jiffies + expiry;
542 dpcm->respawn_timer = 1;
543 add_timer(&dpcm->timer);
544}
545
546static void snd_card_asihpi_pcm_timer_stop(struct snd_pcm_substream *substream)
547{
548 struct snd_pcm_runtime *runtime = substream->runtime;
549 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
550
551 dpcm->respawn_timer = 0;
552 del_timer(&dpcm->timer);
553}
554
555static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,
556 int cmd)
557{
558 struct snd_card_asihpi_pcm *dpcm = substream->runtime->private_data;
559 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
560 struct snd_pcm_substream *s;
561 u16 e;
562
563 snd_printd("trigger %dstream %d\n",
564 substream->stream, substream->number);
565 switch (cmd) {
566 case SNDRV_PCM_TRIGGER_START:
567 snd_pcm_group_for_each_entry(s, substream) {
568 struct snd_card_asihpi_pcm *ds;
569 ds = s->runtime->private_data;
570
571 if (snd_pcm_substream_chip(s) != card)
572 continue;
573
574 if ((s->stream == SNDRV_PCM_STREAM_PLAYBACK) &&
575 (card->support_mmap)) {
576 /* How do I know how much valid data is present
577 * in buffer? Just guessing 2 periods, but if
578 * buffer is bigger it may contain even more
579 * data??
580 */
581 unsigned int preload = ds->pcm_count * 2;
582 VPRINTK2("preload %d\n", preload);
583 hpi_handle_error(hpi_outstream_write_buf(
584 ss, ds->h_stream,
585 &s->runtime->dma_area[0],
586 preload,
587 &ds->format));
588 }
589
590 if (card->support_grouping) {
591 VPRINTK1("\t_group %dstream %d\n", s->stream,
592 s->number);
593 e = hpi_stream_group_add(ss,
594 dpcm->h_stream,
595 ds->h_stream);
596 if (!e) {
597 snd_pcm_trigger_done(s, substream);
598 } else {
599 hpi_handle_error(e);
600 break;
601 }
602 } else
603 break;
604 }
605 snd_printd("start\n");
606 /* start the master stream */
607 snd_card_asihpi_pcm_timer_start(substream);
608 hpi_handle_error(hpi_stream_start(ss, dpcm->h_stream));
609 break;
610
611 case SNDRV_PCM_TRIGGER_STOP:
612 snd_card_asihpi_pcm_timer_stop(substream);
613 snd_pcm_group_for_each_entry(s, substream) {
614 if (snd_pcm_substream_chip(s) != card)
615 continue;
616
617 /*? workaround linked streams don't
618 transition to SETUP 20070706*/
619 s->runtime->status->state = SNDRV_PCM_STATE_SETUP;
620
621 if (card->support_grouping) {
622 VPRINTK1("\t_group %dstream %d\n", s->stream,
623 s->number);
624 snd_pcm_trigger_done(s, substream);
625 } else
626 break;
627 }
628 snd_printd("stop\n");
629
630 /* _prepare and _hwparams reset the stream */
631 hpi_handle_error(hpi_stream_stop(ss, dpcm->h_stream));
632 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
633 hpi_handle_error(
634 hpi_outstream_reset(ss, dpcm->h_stream));
635
636 if (card->support_grouping)
637 hpi_handle_error(hpi_stream_group_reset(ss,
638 dpcm->h_stream));
639 break;
640
641 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
642 snd_printd("pause release\n");
643 hpi_handle_error(hpi_stream_start(ss, dpcm->h_stream));
644 snd_card_asihpi_pcm_timer_start(substream);
645 break;
646 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
647 snd_printd("pause\n");
648 snd_card_asihpi_pcm_timer_stop(substream);
649 hpi_handle_error(hpi_stream_stop(ss, dpcm->h_stream));
650 break;
651 default:
652 snd_printd("\tINVALID\n");
653 return -EINVAL;
654 }
655
656 return 0;
657}
658
659static int
660snd_card_asihpi_hw_free(struct snd_pcm_substream *substream)
661{
662 struct snd_pcm_runtime *runtime = substream->runtime;
663 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
664 if (dpcm->hpi_buffer_attached)
665 hpi_stream_host_buffer_detach(ss, dpcm->h_stream);
666
667 snd_pcm_lib_free_pages(substream);
668 return 0;
669}
670
671static void snd_card_asihpi_runtime_free(struct snd_pcm_runtime *runtime)
672{
673 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
674 kfree(dpcm);
675}
676
677/*algorithm outline
678 Without linking degenerates to getting single stream pos etc
679 Without mmap 2nd loop degenerates to snd_pcm_period_elapsed
680*/
681/*
682buf_pos=get_buf_pos(s);
683for_each_linked_stream(s) {
684 buf_pos=get_buf_pos(s);
685 min_buf_pos = modulo_min(min_buf_pos, buf_pos, pcm_size)
686 new_data = min(new_data, calc_new_data(buf_pos,irq_pos)
687}
688timer.expires = jiffies + predict_next_period_ready(min_buf_pos);
689for_each_linked_stream(s) {
690 s->buf_pos = min_buf_pos;
691 if (new_data > pcm_count) {
692 if (mmap) {
693 irq_pos = (irq_pos + pcm_count) % pcm_size;
694 if (playback) {
695 write(pcm_count);
696 } else {
697 read(pcm_count);
698 }
699 }
700 snd_pcm_period_elapsed(s);
701 }
702}
703*/
704
705/** Minimum of 2 modulo values. Works correctly when the difference between
706* the values is less than half the modulus
707*/
708static inline unsigned int modulo_min(unsigned int a, unsigned int b,
709 unsigned long int modulus)
710{
711 unsigned int result;
712 if (((a-b) % modulus) < (modulus/2))
713 result = b;
714 else
715 result = a;
716
717 return result;
718}
719
720/** Timer function, equivalent to interrupt service routine for cards
721*/
722static void snd_card_asihpi_timer_function(unsigned long data)
723{
724 struct snd_card_asihpi_pcm *dpcm = (struct snd_card_asihpi_pcm *)data;
725 struct snd_card_asihpi *card = snd_pcm_substream_chip(dpcm->substream);
726 struct snd_pcm_runtime *runtime;
727 struct snd_pcm_substream *s;
728 unsigned int newdata = 0;
729 unsigned int buf_pos, min_buf_pos = 0;
730 unsigned int remdata, xfercount, next_jiffies;
731 int first = 1;
732 u16 state;
733 u32 buffer_size, data_avail, samples_played, aux;
734
735 /* find minimum newdata and buffer pos in group */
736 snd_pcm_group_for_each_entry(s, dpcm->substream) {
737 struct snd_card_asihpi_pcm *ds = s->runtime->private_data;
738 runtime = s->runtime;
739
740 if (snd_pcm_substream_chip(s) != card)
741 continue;
742
743 hpi_handle_error(hpi_stream_get_info_ex(ss,
744 ds->h_stream, &state,
745 &buffer_size, &data_avail,
746 &samples_played, &aux));
747
748 /* number of bytes in on-card buffer */
749 runtime->delay = aux;
750
751 if (state == HPI_STATE_DRAINED) {
752 snd_printd(KERN_WARNING "outstream %d drained\n",
753 s->number);
754 snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN);
755 return;
756 }
757
758 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
759 buf_pos = frames_to_bytes(runtime, samples_played);
760 } else {
761 buf_pos = data_avail + ds->pcm_irq_pos;
762 }
763
764 if (first) {
765 /* can't statically init min when wrap is involved */
766 min_buf_pos = buf_pos;
767 newdata = (buf_pos - ds->pcm_irq_pos) % ds->pcm_size;
768 first = 0;
769 } else {
770 min_buf_pos =
771 modulo_min(min_buf_pos, buf_pos, UINT_MAX+1L);
772 newdata = min(
773 (buf_pos - ds->pcm_irq_pos) % ds->pcm_size,
774 newdata);
775 }
776
777 VPRINTK1("PB timer hw_ptr x%04lX, appl_ptr x%04lX\n",
778 (unsigned long)frames_to_bytes(runtime,
779 runtime->status->hw_ptr),
780 (unsigned long)frames_to_bytes(runtime,
781 runtime->control->appl_ptr));
782 VPRINTK1("%d S=%d, irq=%04X, pos=x%04X, left=x%04X,"
783 " aux=x%04X space=x%04X\n", s->number,
784 state, ds->pcm_irq_pos, buf_pos, (int)data_avail,
785 (int)aux, buffer_size-data_avail);
786 }
787
788 remdata = newdata % dpcm->pcm_count;
789 xfercount = newdata - remdata; /* a multiple of pcm_count */
790 next_jiffies = ((dpcm->pcm_count-remdata) * HZ / dpcm->bytes_per_sec)+1;
791 next_jiffies = max(next_jiffies, 2U * HZ / 1000U);
792 dpcm->timer.expires = jiffies + next_jiffies;
793 VPRINTK1("jif %d buf pos x%04X newdata x%04X xc x%04X\n",
794 next_jiffies, min_buf_pos, newdata, xfercount);
795
796 snd_pcm_group_for_each_entry(s, dpcm->substream) {
797 struct snd_card_asihpi_pcm *ds = s->runtime->private_data;
798 ds->pcm_buf_pos = min_buf_pos;
799
800 if (xfercount) {
801 if (card->support_mmap) {
802 ds->pcm_irq_pos = ds->pcm_irq_pos + xfercount;
803 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
804 VPRINTK2("write OS%d x%04x\n",
805 s->number,
806 ds->pcm_count);
807 hpi_handle_error(
808 hpi_outstream_write_buf(
809 ss, ds->h_stream,
810 &s->runtime->
811 dma_area[0],
812 xfercount,
813 &ds->format));
814 } else {
815 VPRINTK2("read IS%d x%04x\n",
816 s->number,
817 dpcm->pcm_count);
818 hpi_handle_error(
819 hpi_instream_read_buf(
820 ss, ds->h_stream,
821 NULL, xfercount));
822 }
823 } /* else R/W will be handled by read/write callbacks */
824 snd_pcm_period_elapsed(s);
825 }
826 }
827
828 if (dpcm->respawn_timer)
829 add_timer(&dpcm->timer);
830}
831
832/***************************** PLAYBACK OPS ****************/
833static int snd_card_asihpi_playback_ioctl(struct snd_pcm_substream *substream,
834 unsigned int cmd, void *arg)
835{
836 /* snd_printd(KERN_INFO "Playback ioctl %d\n", cmd); */
837 return snd_pcm_lib_ioctl(substream, cmd, arg);
838}
839
840static int snd_card_asihpi_playback_prepare(struct snd_pcm_substream *
841 substream)
842{
843 struct snd_pcm_runtime *runtime = substream->runtime;
844 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
845
846 snd_printd(KERN_INFO "playback prepare %d\n", substream->number);
847
848 hpi_handle_error(hpi_outstream_reset(ss, dpcm->h_stream));
849 dpcm->pcm_irq_pos = 0;
850 dpcm->pcm_buf_pos = 0;
851
852 return 0;
853}
854
855static snd_pcm_uframes_t
856snd_card_asihpi_playback_pointer(struct snd_pcm_substream *substream)
857{
858 struct snd_pcm_runtime *runtime = substream->runtime;
859 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
860 snd_pcm_uframes_t ptr;
861
862 u32 samples_played;
863 u16 err;
864
865 if (!snd_pcm_stream_linked(substream)) {
866 /* NOTE, can use samples played for playback position here and
867 * in timer fn because it LAGS the actual read pointer, and is a
868 * better representation of actual playout position
869 */
870 err = hpi_outstream_get_info_ex(ss, dpcm->h_stream, NULL,
871 NULL, NULL,
872 &samples_played, NULL);
873 hpi_handle_error(err);
874
875 dpcm->pcm_buf_pos = frames_to_bytes(runtime, samples_played);
876 }
877 /* else must return most conservative value found in timer func
878 * by looping over all streams
879 */
880
881 ptr = bytes_to_frames(runtime, dpcm->pcm_buf_pos % dpcm->pcm_size);
882 VPRINTK2("playback_pointer=%04ld\n", (unsigned long)ptr);
883 return ptr;
884}
885
886static void snd_card_asihpi_playback_format(struct snd_card_asihpi *asihpi,
887 u32 h_stream,
888 struct snd_pcm_hardware *pcmhw)
889{
890 struct hpi_format hpi_format;
891 u16 format;
892 u16 err;
893 u32 h_control;
894 u32 sample_rate = 48000;
895
896 /* on cards without SRC, must query at valid rate,
897 * maybe set by external sync
898 */
899 err = hpi_mixer_get_control(ss, asihpi->h_mixer,
900 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
901 HPI_CONTROL_SAMPLECLOCK, &h_control);
902
903 if (!err)
904 err = hpi_sample_clock_get_sample_rate(ss, h_control,
905 &sample_rate);
906
907 for (format = HPI_FORMAT_PCM8_UNSIGNED;
908 format <= HPI_FORMAT_PCM24_SIGNED; format++) {
909 err = hpi_format_create(&hpi_format,
910 2, format, sample_rate, 128000, 0);
911 if (!err)
912 err = hpi_outstream_query_format(ss, h_stream,
913 &hpi_format);
914 if (!err && (hpi_to_alsa_formats[format] != -1))
915 pcmhw->formats |=
916 (1ULL << hpi_to_alsa_formats[format]);
917 }
918}
919
920static struct snd_pcm_hardware snd_card_asihpi_playback = {
921 .channels_min = 1,
922 .channels_max = 2,
923 .buffer_bytes_max = BUFFER_BYTES_MAX,
924 .period_bytes_min = PERIOD_BYTES_MIN,
925 .period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN,
926 .periods_min = PERIODS_MIN,
927 .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN,
928 .fifo_size = 0,
929};
930
931static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream)
932{
933 struct snd_pcm_runtime *runtime = substream->runtime;
934 struct snd_card_asihpi_pcm *dpcm;
935 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
936 int err;
937
938 dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
939 if (dpcm == NULL)
940 return -ENOMEM;
941
942 err =
943 hpi_outstream_open(ss, card->adapter_index,
944 substream->number, &dpcm->h_stream);
945 hpi_handle_error(err);
946 if (err)
947 kfree(dpcm);
948 if (err == HPI_ERROR_OBJ_ALREADY_OPEN)
949 return -EBUSY;
950 if (err)
951 return -EIO;
952
953 /*? also check ASI5000 samplerate source
954 If external, only support external rate.
955 If internal and other stream playing, cant switch
956 */
957
958 init_timer(&dpcm->timer);
959 dpcm->timer.data = (unsigned long) dpcm;
960 dpcm->timer.function = snd_card_asihpi_timer_function;
961 dpcm->substream = substream;
962 runtime->private_data = dpcm;
963 runtime->private_free = snd_card_asihpi_runtime_free;
964
965 snd_card_asihpi_playback.channels_max = card->out_max_chans;
966 /*?snd_card_asihpi_playback.period_bytes_min =
967 card->out_max_chans * 4096; */
968
969 snd_card_asihpi_playback_format(card, dpcm->h_stream,
970 &snd_card_asihpi_playback);
971
972 snd_card_asihpi_pcm_samplerates(card, &snd_card_asihpi_playback);
973
974 snd_card_asihpi_playback.info = SNDRV_PCM_INFO_INTERLEAVED |
975 SNDRV_PCM_INFO_DOUBLE |
976 SNDRV_PCM_INFO_BATCH |
977 SNDRV_PCM_INFO_BLOCK_TRANSFER |
978 SNDRV_PCM_INFO_PAUSE;
979
980 if (card->support_mmap)
981 snd_card_asihpi_playback.info |= SNDRV_PCM_INFO_MMAP |
982 SNDRV_PCM_INFO_MMAP_VALID;
983
984 if (card->support_grouping)
985 snd_card_asihpi_playback.info |= SNDRV_PCM_INFO_SYNC_START;
986
987 /* struct is copied, so can create initializer dynamically */
988 runtime->hw = snd_card_asihpi_playback;
989
990 if (card->support_mmap)
991 err = snd_pcm_hw_constraint_pow2(runtime, 0,
992 SNDRV_PCM_HW_PARAM_BUFFER_BYTES);
993 if (err < 0)
994 return err;
995
996 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
997 card->update_interval_frames);
998 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
999 card->update_interval_frames * 4, UINT_MAX);
1000
1001 snd_pcm_set_sync(substream);
1002
1003 snd_printd(KERN_INFO "playback open\n");
1004
1005 return 0;
1006}
1007
1008static int snd_card_asihpi_playback_close(struct snd_pcm_substream *substream)
1009{
1010 struct snd_pcm_runtime *runtime = substream->runtime;
1011 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1012
1013 hpi_handle_error(hpi_outstream_close(ss, dpcm->h_stream));
1014 snd_printd(KERN_INFO "playback close\n");
1015
1016 return 0;
1017}
1018
1019static int snd_card_asihpi_playback_copy(struct snd_pcm_substream *substream,
1020 int channel,
1021 snd_pcm_uframes_t pos,
1022 void __user *src,
1023 snd_pcm_uframes_t count)
1024{
1025 struct snd_pcm_runtime *runtime = substream->runtime;
1026 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1027 unsigned int len;
1028
1029 len = frames_to_bytes(runtime, count);
1030
1031 if (copy_from_user(runtime->dma_area, src, len))
1032 return -EFAULT;
1033
1034 VPRINTK2(KERN_DEBUG "playback copy%d %u bytes\n",
1035 substream->number, len);
1036
1037 hpi_handle_error(hpi_outstream_write_buf(ss, dpcm->h_stream,
1038 runtime->dma_area, len, &dpcm->format));
1039
1040 return 0;
1041}
1042
1043static int snd_card_asihpi_playback_silence(struct snd_pcm_substream *
1044 substream, int channel,
1045 snd_pcm_uframes_t pos,
1046 snd_pcm_uframes_t count)
1047{
1048 unsigned int len;
1049 struct snd_pcm_runtime *runtime = substream->runtime;
1050 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1051
1052 len = frames_to_bytes(runtime, count);
1053 snd_printd(KERN_INFO "playback silence %u bytes\n", len);
1054
1055 memset(runtime->dma_area, 0, len);
1056 hpi_handle_error(hpi_outstream_write_buf(ss, dpcm->h_stream,
1057 runtime->dma_area, len, &dpcm->format));
1058 return 0;
1059}
1060
1061static struct snd_pcm_ops snd_card_asihpi_playback_ops = {
1062 .open = snd_card_asihpi_playback_open,
1063 .close = snd_card_asihpi_playback_close,
1064 .ioctl = snd_card_asihpi_playback_ioctl,
1065 .hw_params = snd_card_asihpi_pcm_hw_params,
1066 .hw_free = snd_card_asihpi_hw_free,
1067 .prepare = snd_card_asihpi_playback_prepare,
1068 .trigger = snd_card_asihpi_trigger,
1069 .pointer = snd_card_asihpi_playback_pointer,
1070 .copy = snd_card_asihpi_playback_copy,
1071 .silence = snd_card_asihpi_playback_silence,
1072};
1073
1074static struct snd_pcm_ops snd_card_asihpi_playback_mmap_ops = {
1075 .open = snd_card_asihpi_playback_open,
1076 .close = snd_card_asihpi_playback_close,
1077 .ioctl = snd_card_asihpi_playback_ioctl,
1078 .hw_params = snd_card_asihpi_pcm_hw_params,
1079 .hw_free = snd_card_asihpi_hw_free,
1080 .prepare = snd_card_asihpi_playback_prepare,
1081 .trigger = snd_card_asihpi_trigger,
1082 .pointer = snd_card_asihpi_playback_pointer,
1083};
1084
1085/***************************** CAPTURE OPS ****************/
1086static snd_pcm_uframes_t
1087snd_card_asihpi_capture_pointer(struct snd_pcm_substream *substream)
1088{
1089 struct snd_pcm_runtime *runtime = substream->runtime;
1090 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1091
1092 VPRINTK2("capture pointer %d=%d\n",
1093 substream->number, dpcm->pcm_buf_pos);
1094 /* NOTE Unlike playback can't use actual dwSamplesPlayed
1095 for the capture position, because those samples aren't yet in
1096 the local buffer available for reading.
1097 */
1098 return bytes_to_frames(runtime, dpcm->pcm_buf_pos % dpcm->pcm_size);
1099}
1100
1101static int snd_card_asihpi_capture_ioctl(struct snd_pcm_substream *substream,
1102 unsigned int cmd, void *arg)
1103{
1104 return snd_pcm_lib_ioctl(substream, cmd, arg);
1105}
1106
1107static int snd_card_asihpi_capture_prepare(struct snd_pcm_substream *substream)
1108{
1109 struct snd_pcm_runtime *runtime = substream->runtime;
1110 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1111
1112 hpi_handle_error(hpi_instream_reset(ss, dpcm->h_stream));
1113 dpcm->pcm_irq_pos = 0;
1114 dpcm->pcm_buf_pos = 0;
1115
1116 snd_printd("capture prepare %d\n", substream->number);
1117 return 0;
1118}
1119
1120
1121
1122static void snd_card_asihpi_capture_format(struct snd_card_asihpi *asihpi,
1123 u32 h_stream,
1124 struct snd_pcm_hardware *pcmhw)
1125{
1126 struct hpi_format hpi_format;
1127 u16 format;
1128 u16 err;
1129 u32 h_control;
1130 u32 sample_rate = 48000;
1131
1132 /* on cards without SRC, must query at valid rate,
1133 maybe set by external sync */
1134 err = hpi_mixer_get_control(ss, asihpi->h_mixer,
1135 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
1136 HPI_CONTROL_SAMPLECLOCK, &h_control);
1137
1138 if (!err)
1139 err = hpi_sample_clock_get_sample_rate(ss, h_control,
1140 &sample_rate);
1141
1142 for (format = HPI_FORMAT_PCM8_UNSIGNED;
1143 format <= HPI_FORMAT_PCM24_SIGNED; format++) {
1144
1145 err = hpi_format_create(&hpi_format, 2, format,
1146 sample_rate, 128000, 0);
1147 if (!err)
1148 err = hpi_instream_query_format(ss, h_stream,
1149 &hpi_format);
1150 if (!err)
1151 pcmhw->formats |=
1152 (1ULL << hpi_to_alsa_formats[format]);
1153 }
1154}
1155
1156
1157static struct snd_pcm_hardware snd_card_asihpi_capture = {
1158 .channels_min = 1,
1159 .channels_max = 2,
1160 .buffer_bytes_max = BUFFER_BYTES_MAX,
1161 .period_bytes_min = PERIOD_BYTES_MIN,
1162 .period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN,
1163 .periods_min = PERIODS_MIN,
1164 .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN,
1165 .fifo_size = 0,
1166};
1167
1168static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream)
1169{
1170 struct snd_pcm_runtime *runtime = substream->runtime;
1171 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
1172 struct snd_card_asihpi_pcm *dpcm;
1173 int err;
1174
1175 dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
1176 if (dpcm == NULL)
1177 return -ENOMEM;
1178
1179 snd_printd("hpi_instream_open adapter %d stream %d\n",
1180 card->adapter_index, substream->number);
1181
1182 err = hpi_handle_error(
1183 hpi_instream_open(ss, card->adapter_index,
1184 substream->number, &dpcm->h_stream));
1185 if (err)
1186 kfree(dpcm);
1187 if (err == HPI_ERROR_OBJ_ALREADY_OPEN)
1188 return -EBUSY;
1189 if (err)
1190 return -EIO;
1191
1192
1193 init_timer(&dpcm->timer);
1194 dpcm->timer.data = (unsigned long) dpcm;
1195 dpcm->timer.function = snd_card_asihpi_timer_function;
1196 dpcm->substream = substream;
1197 runtime->private_data = dpcm;
1198 runtime->private_free = snd_card_asihpi_runtime_free;
1199
1200 snd_card_asihpi_capture.channels_max = card->in_max_chans;
1201 snd_card_asihpi_capture_format(card, dpcm->h_stream,
1202 &snd_card_asihpi_capture);
1203 snd_card_asihpi_pcm_samplerates(card, &snd_card_asihpi_capture);
1204 snd_card_asihpi_capture.info = SNDRV_PCM_INFO_INTERLEAVED;
1205
1206 if (card->support_mmap)
1207 snd_card_asihpi_capture.info |= SNDRV_PCM_INFO_MMAP |
1208 SNDRV_PCM_INFO_MMAP_VALID;
1209
1210 runtime->hw = snd_card_asihpi_capture;
1211
1212 if (card->support_mmap)
1213 err = snd_pcm_hw_constraint_pow2(runtime, 0,
1214 SNDRV_PCM_HW_PARAM_BUFFER_BYTES);
1215 if (err < 0)
1216 return err;
1217
1218 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
1219 card->update_interval_frames);
1220 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
1221 card->update_interval_frames * 2, UINT_MAX);
1222
1223 snd_pcm_set_sync(substream);
1224
1225 return 0;
1226}
1227
1228static int snd_card_asihpi_capture_close(struct snd_pcm_substream *substream)
1229{
1230 struct snd_card_asihpi_pcm *dpcm = substream->runtime->private_data;
1231
1232 hpi_handle_error(hpi_instream_close(ss, dpcm->h_stream));
1233 return 0;
1234}
1235
1236static int snd_card_asihpi_capture_copy(struct snd_pcm_substream *substream,
1237 int channel, snd_pcm_uframes_t pos,
1238 void __user *dst, snd_pcm_uframes_t count)
1239{
1240 struct snd_pcm_runtime *runtime = substream->runtime;
1241 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1242 u32 data_size;
1243
1244 data_size = frames_to_bytes(runtime, count);
1245
1246 VPRINTK2("capture copy%d %d bytes\n", substream->number, data_size);
1247 hpi_handle_error(hpi_instream_read_buf(ss, dpcm->h_stream,
1248 runtime->dma_area, data_size));
1249
1250 /* Used by capture_pointer */
1251 dpcm->pcm_irq_pos = dpcm->pcm_irq_pos + data_size;
1252
1253 if (copy_to_user(dst, runtime->dma_area, data_size))
1254 return -EFAULT;
1255
1256 return 0;
1257}
1258
1259static struct snd_pcm_ops snd_card_asihpi_capture_mmap_ops = {
1260 .open = snd_card_asihpi_capture_open,
1261 .close = snd_card_asihpi_capture_close,
1262 .ioctl = snd_card_asihpi_capture_ioctl,
1263 .hw_params = snd_card_asihpi_pcm_hw_params,
1264 .hw_free = snd_card_asihpi_hw_free,
1265 .prepare = snd_card_asihpi_capture_prepare,
1266 .trigger = snd_card_asihpi_trigger,
1267 .pointer = snd_card_asihpi_capture_pointer,
1268};
1269
1270static struct snd_pcm_ops snd_card_asihpi_capture_ops = {
1271 .open = snd_card_asihpi_capture_open,
1272 .close = snd_card_asihpi_capture_close,
1273 .ioctl = snd_card_asihpi_capture_ioctl,
1274 .hw_params = snd_card_asihpi_pcm_hw_params,
1275 .hw_free = snd_card_asihpi_hw_free,
1276 .prepare = snd_card_asihpi_capture_prepare,
1277 .trigger = snd_card_asihpi_trigger,
1278 .pointer = snd_card_asihpi_capture_pointer,
1279 .copy = snd_card_asihpi_capture_copy
1280};
1281
1282static int __devinit snd_card_asihpi_pcm_new(struct snd_card_asihpi *asihpi,
1283 int device, int substreams)
1284{
1285 struct snd_pcm *pcm;
1286 int err;
1287
1288 err = snd_pcm_new(asihpi->card, "asihpi PCM", device,
1289 asihpi->num_outstreams, asihpi->num_instreams,
1290 &pcm);
1291 if (err < 0)
1292 return err;
1293 /* pointer to ops struct is stored, dont change ops afterwards! */
1294 if (asihpi->support_mmap) {
1295 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
1296 &snd_card_asihpi_playback_mmap_ops);
1297 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
1298 &snd_card_asihpi_capture_mmap_ops);
1299 } else {
1300 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
1301 &snd_card_asihpi_playback_ops);
1302 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
1303 &snd_card_asihpi_capture_ops);
1304 }
1305
1306 pcm->private_data = asihpi;
1307 pcm->info_flags = 0;
1308 strcpy(pcm->name, "asihpi PCM");
1309
1310 /*? do we want to emulate MMAP for non-BBM cards?
1311 Jack doesn't work with ALSAs MMAP emulation - WHY NOT? */
1312 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1313 snd_dma_pci_data(asihpi->pci),
1314 64*1024, BUFFER_BYTES_MAX);
1315
1316 return 0;
1317}
1318
1319/***************************** MIXER CONTROLS ****************/
1320struct hpi_control {
1321 u32 h_control;
1322 u16 control_type;
1323 u16 src_node_type;
1324 u16 src_node_index;
1325 u16 dst_node_type;
1326 u16 dst_node_index;
1327 u16 band;
1328 char name[44]; /* copied to snd_ctl_elem_id.name[44]; */
1329};
1330
1331static char *asihpi_tuner_band_names[] =
1332{
1333 "invalid",
1334 "AM",
1335 "FM mono",
1336 "TV NTSC-M",
1337 "FM stereo",
1338 "AUX",
1339 "TV PAL BG",
1340 "TV PAL I",
1341 "TV PAL DK",
1342 "TV SECAM",
1343};
1344
1345compile_time_assert(
1346 (ARRAY_SIZE(asihpi_tuner_band_names) ==
1347 (HPI_TUNER_BAND_LAST+1)),
1348 assert_tuner_band_names_size);
1349
1350#if ASI_STYLE_NAMES
1351static char *asihpi_src_names[] =
1352{
1353 "no source",
1354 "outstream",
1355 "line_in",
1356 "aes_in",
1357 "tuner",
1358 "RF",
1359 "clock",
1360 "bitstr",
1361 "mic",
1362 "cobranet",
1363 "analog_in",
1364 "adapter",
1365};
1366#else
1367static char *asihpi_src_names[] =
1368{
1369 "no source",
1370 "PCM playback",
1371 "line in",
1372 "digital in",
1373 "tuner",
1374 "RF",
1375 "clock",
1376 "bitstream",
1377 "mic",
1378 "cobranet in",
1379 "analog in",
1380 "adapter",
1381};
1382#endif
1383
1384compile_time_assert(
1385 (ARRAY_SIZE(asihpi_src_names) ==
1386 (HPI_SOURCENODE_LAST_INDEX-HPI_SOURCENODE_BASE+1)),
1387 assert_src_names_size);
1388
1389#if ASI_STYLE_NAMES
1390static char *asihpi_dst_names[] =
1391{
1392 "no destination",
1393 "instream",
1394 "line_out",
1395 "aes_out",
1396 "RF",
1397 "speaker" ,
1398 "cobranet",
1399 "analog_out",
1400};
1401#else
1402static char *asihpi_dst_names[] =
1403{
1404 "no destination",
1405 "PCM capture",
1406 "line out",
1407 "digital out",
1408 "RF",
1409 "speaker",
1410 "cobranet out",
1411 "analog out"
1412};
1413#endif
1414
1415compile_time_assert(
1416 (ARRAY_SIZE(asihpi_dst_names) ==
1417 (HPI_DESTNODE_LAST_INDEX-HPI_DESTNODE_BASE+1)),
1418 assert_dst_names_size);
1419
1420static inline int ctl_add(struct snd_card *card, struct snd_kcontrol_new *ctl,
1421 struct snd_card_asihpi *asihpi)
1422{
1423 int err;
1424
1425 err = snd_ctl_add(card, snd_ctl_new1(ctl, asihpi));
1426 if (err < 0)
1427 return err;
1428 else if (mixer_dump)
1429 snd_printk(KERN_INFO "added %s(%d)\n", ctl->name, ctl->index);
1430
1431 return 0;
1432}
1433
1434/* Convert HPI control name and location into ALSA control name */
1435static void asihpi_ctl_init(struct snd_kcontrol_new *snd_control,
1436 struct hpi_control *hpi_ctl,
1437 char *name)
1438{
1439 memset(snd_control, 0, sizeof(*snd_control));
1440 snd_control->name = hpi_ctl->name;
1441 snd_control->private_value = hpi_ctl->h_control;
1442 snd_control->iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1443 snd_control->index = 0;
1444
1445 if (hpi_ctl->src_node_type && hpi_ctl->dst_node_type)
1446 sprintf(hpi_ctl->name, "%s%d to %s%d %s",
1447 asihpi_src_names[hpi_ctl->src_node_type],
1448 hpi_ctl->src_node_index,
1449 asihpi_dst_names[hpi_ctl->dst_node_type],
1450 hpi_ctl->dst_node_index,
1451 name);
1452 else if (hpi_ctl->dst_node_type) {
1453 sprintf(hpi_ctl->name, "%s%d %s",
1454 asihpi_dst_names[hpi_ctl->dst_node_type],
1455 hpi_ctl->dst_node_index,
1456 name);
1457 } else {
1458 sprintf(hpi_ctl->name, "%s%d %s",
1459 asihpi_src_names[hpi_ctl->src_node_type],
1460 hpi_ctl->src_node_index,
1461 name);
1462 }
1463}
1464
1465/*------------------------------------------------------------
1466 Volume controls
1467 ------------------------------------------------------------*/
1468#define VOL_STEP_mB 1
1469static int snd_asihpi_volume_info(struct snd_kcontrol *kcontrol,
1470 struct snd_ctl_elem_info *uinfo)
1471{
1472 u32 h_control = kcontrol->private_value;
1473 u16 err;
1474 /* native gains are in millibels */
1475 short min_gain_mB;
1476 short max_gain_mB;
1477 short step_gain_mB;
1478
1479 err = hpi_volume_query_range(ss, h_control,
1480 &min_gain_mB, &max_gain_mB, &step_gain_mB);
1481 if (err) {
1482 max_gain_mB = 0;
1483 min_gain_mB = -10000;
1484 step_gain_mB = VOL_STEP_mB;
1485 }
1486
1487 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1488 uinfo->count = 2;
1489 uinfo->value.integer.min = min_gain_mB / VOL_STEP_mB;
1490 uinfo->value.integer.max = max_gain_mB / VOL_STEP_mB;
1491 uinfo->value.integer.step = step_gain_mB / VOL_STEP_mB;
1492 return 0;
1493}
1494
1495static int snd_asihpi_volume_get(struct snd_kcontrol *kcontrol,
1496 struct snd_ctl_elem_value *ucontrol)
1497{
1498 u32 h_control = kcontrol->private_value;
1499 short an_gain_mB[HPI_MAX_CHANNELS];
1500
1501 hpi_handle_error(hpi_volume_get_gain(ss, h_control, an_gain_mB));
1502 ucontrol->value.integer.value[0] = an_gain_mB[0] / VOL_STEP_mB;
1503 ucontrol->value.integer.value[1] = an_gain_mB[1] / VOL_STEP_mB;
1504
1505 return 0;
1506}
1507
1508static int snd_asihpi_volume_put(struct snd_kcontrol *kcontrol,
1509 struct snd_ctl_elem_value *ucontrol)
1510{
1511 int change;
1512 u32 h_control = kcontrol->private_value;
1513 short an_gain_mB[HPI_MAX_CHANNELS];
1514
1515 an_gain_mB[0] =
1516 (ucontrol->value.integer.value[0]) * VOL_STEP_mB;
1517 an_gain_mB[1] =
1518 (ucontrol->value.integer.value[1]) * VOL_STEP_mB;
1519 /* change = asihpi->mixer_volume[addr][0] != left ||
1520 asihpi->mixer_volume[addr][1] != right;
1521 */
1522 change = 1;
1523 hpi_handle_error(hpi_volume_set_gain(ss, h_control, an_gain_mB));
1524 return change;
1525}
1526
1527static const DECLARE_TLV_DB_SCALE(db_scale_100, -10000, VOL_STEP_mB, 0);
1528
1529static int __devinit snd_asihpi_volume_add(struct snd_card_asihpi *asihpi,
1530 struct hpi_control *hpi_ctl)
1531{
1532 struct snd_card *card = asihpi->card;
1533 struct snd_kcontrol_new snd_control;
1534
1535 asihpi_ctl_init(&snd_control, hpi_ctl, "volume");
1536 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
1537 SNDRV_CTL_ELEM_ACCESS_TLV_READ;
1538 snd_control.info = snd_asihpi_volume_info;
1539 snd_control.get = snd_asihpi_volume_get;
1540 snd_control.put = snd_asihpi_volume_put;
1541 snd_control.tlv.p = db_scale_100;
1542
1543 return ctl_add(card, &snd_control, asihpi);
1544}
1545
1546/*------------------------------------------------------------
1547 Level controls
1548 ------------------------------------------------------------*/
1549static int snd_asihpi_level_info(struct snd_kcontrol *kcontrol,
1550 struct snd_ctl_elem_info *uinfo)
1551{
1552 u32 h_control = kcontrol->private_value;
1553 u16 err;
1554 short min_gain_mB;
1555 short max_gain_mB;
1556 short step_gain_mB;
1557
1558 err =
1559 hpi_level_query_range(ss, h_control, &min_gain_mB,
1560 &max_gain_mB, &step_gain_mB);
1561 if (err) {
1562 max_gain_mB = 2400;
1563 min_gain_mB = -1000;
1564 step_gain_mB = 100;
1565 }
1566
1567 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1568 uinfo->count = 2;
1569 uinfo->value.integer.min = min_gain_mB / HPI_UNITS_PER_dB;
1570 uinfo->value.integer.max = max_gain_mB / HPI_UNITS_PER_dB;
1571 uinfo->value.integer.step = step_gain_mB / HPI_UNITS_PER_dB;
1572 return 0;
1573}
1574
1575static int snd_asihpi_level_get(struct snd_kcontrol *kcontrol,
1576 struct snd_ctl_elem_value *ucontrol)
1577{
1578 u32 h_control = kcontrol->private_value;
1579 short an_gain_mB[HPI_MAX_CHANNELS];
1580
1581 hpi_handle_error(hpi_level_get_gain(ss, h_control, an_gain_mB));
1582 ucontrol->value.integer.value[0] =
1583 an_gain_mB[0] / HPI_UNITS_PER_dB;
1584 ucontrol->value.integer.value[1] =
1585 an_gain_mB[1] / HPI_UNITS_PER_dB;
1586
1587 return 0;
1588}
1589
1590static int snd_asihpi_level_put(struct snd_kcontrol *kcontrol,
1591 struct snd_ctl_elem_value *ucontrol)
1592{
1593 int change;
1594 u32 h_control = kcontrol->private_value;
1595 short an_gain_mB[HPI_MAX_CHANNELS];
1596
1597 an_gain_mB[0] =
1598 (ucontrol->value.integer.value[0]) * HPI_UNITS_PER_dB;
1599 an_gain_mB[1] =
1600 (ucontrol->value.integer.value[1]) * HPI_UNITS_PER_dB;
1601 /* change = asihpi->mixer_level[addr][0] != left ||
1602 asihpi->mixer_level[addr][1] != right;
1603 */
1604 change = 1;
1605 hpi_handle_error(hpi_level_set_gain(ss, h_control, an_gain_mB));
1606 return change;
1607}
1608
1609static const DECLARE_TLV_DB_SCALE(db_scale_level, -1000, 100, 0);
1610
1611static int __devinit snd_asihpi_level_add(struct snd_card_asihpi *asihpi,
1612 struct hpi_control *hpi_ctl)
1613{
1614 struct snd_card *card = asihpi->card;
1615 struct snd_kcontrol_new snd_control;
1616
1617 /* can't use 'volume' cos some nodes have volume as well */
1618 asihpi_ctl_init(&snd_control, hpi_ctl, "level");
1619 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
1620 SNDRV_CTL_ELEM_ACCESS_TLV_READ;
1621 snd_control.info = snd_asihpi_level_info;
1622 snd_control.get = snd_asihpi_level_get;
1623 snd_control.put = snd_asihpi_level_put;
1624 snd_control.tlv.p = db_scale_level;
1625
1626 return ctl_add(card, &snd_control, asihpi);
1627}
1628
1629/*------------------------------------------------------------
1630 AESEBU controls
1631 ------------------------------------------------------------*/
1632
1633/* AESEBU format */
1634static char *asihpi_aesebu_format_names[] =
1635{
1636 "N/A",
1637 "S/PDIF",
1638 "AES/EBU",
1639};
1640
1641static int snd_asihpi_aesebu_format_info(struct snd_kcontrol *kcontrol,
1642 struct snd_ctl_elem_info *uinfo)
1643{
1644 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1645 uinfo->count = 1;
1646 uinfo->value.enumerated.items = 3;
1647
1648 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1649 uinfo->value.enumerated.item =
1650 uinfo->value.enumerated.items - 1;
1651
1652 strcpy(uinfo->value.enumerated.name,
1653 asihpi_aesebu_format_names[uinfo->value.enumerated.item]);
1654
1655 return 0;
1656}
1657
1658static int snd_asihpi_aesebu_format_get(struct snd_kcontrol *kcontrol,
1659 struct snd_ctl_elem_value *ucontrol,
1660 u16 (*func)(const struct hpi_hsubsys *, u32, u16 *))
1661{
1662 u32 h_control = kcontrol->private_value;
1663 u16 source, err;
1664
1665 err = func(ss, h_control, &source);
1666
1667 /* default to N/A */
1668 ucontrol->value.enumerated.item[0] = 0;
1669 /* return success but set the control to N/A */
1670 if (err)
1671 return 0;
1672 if (source == HPI_AESEBU_FORMAT_SPDIF)
1673 ucontrol->value.enumerated.item[0] = 1;
1674 if (source == HPI_AESEBU_FORMAT_AESEBU)
1675 ucontrol->value.enumerated.item[0] = 2;
1676
1677 return 0;
1678}
1679
1680static int snd_asihpi_aesebu_format_put(struct snd_kcontrol *kcontrol,
1681 struct snd_ctl_elem_value *ucontrol,
1682 u16 (*func)(const struct hpi_hsubsys *, u32, u16))
1683{
1684 u32 h_control = kcontrol->private_value;
1685
1686 /* default to S/PDIF */
1687 u16 source = HPI_AESEBU_FORMAT_SPDIF;
1688
1689 if (ucontrol->value.enumerated.item[0] == 1)
1690 source = HPI_AESEBU_FORMAT_SPDIF;
1691 if (ucontrol->value.enumerated.item[0] == 2)
1692 source = HPI_AESEBU_FORMAT_AESEBU;
1693
1694 if (func(ss, h_control, source) != 0)
1695 return -EINVAL;
1696
1697 return 1;
1698}
1699
1700static int snd_asihpi_aesebu_rx_format_get(struct snd_kcontrol *kcontrol,
1701 struct snd_ctl_elem_value *ucontrol) {
1702 return snd_asihpi_aesebu_format_get(kcontrol, ucontrol,
1703 HPI_AESEBU__receiver_get_format);
1704}
1705
1706static int snd_asihpi_aesebu_rx_format_put(struct snd_kcontrol *kcontrol,
1707 struct snd_ctl_elem_value *ucontrol) {
1708 return snd_asihpi_aesebu_format_put(kcontrol, ucontrol,
1709 HPI_AESEBU__receiver_set_format);
1710}
1711
1712static int snd_asihpi_aesebu_rxstatus_info(struct snd_kcontrol *kcontrol,
1713 struct snd_ctl_elem_info *uinfo)
1714{
1715 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1716 uinfo->count = 1;
1717
1718 uinfo->value.integer.min = 0;
1719 uinfo->value.integer.max = 0X1F;
1720 uinfo->value.integer.step = 1;
1721
1722 return 0;
1723}
1724
1725static int snd_asihpi_aesebu_rxstatus_get(struct snd_kcontrol *kcontrol,
1726 struct snd_ctl_elem_value *ucontrol) {
1727
1728 u32 h_control = kcontrol->private_value;
1729 u16 status;
1730
1731 hpi_handle_error(HPI_AESEBU__receiver_get_error_status(
1732 ss, h_control, &status));
1733 ucontrol->value.integer.value[0] = status;
1734 return 0;
1735}
1736
1737static int __devinit snd_asihpi_aesebu_rx_add(struct snd_card_asihpi *asihpi,
1738 struct hpi_control *hpi_ctl)
1739{
1740 struct snd_card *card = asihpi->card;
1741 struct snd_kcontrol_new snd_control;
1742
1743 asihpi_ctl_init(&snd_control, hpi_ctl, "format");
1744 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
1745 snd_control.info = snd_asihpi_aesebu_format_info;
1746 snd_control.get = snd_asihpi_aesebu_rx_format_get;
1747 snd_control.put = snd_asihpi_aesebu_rx_format_put;
1748
1749
1750 if (ctl_add(card, &snd_control, asihpi) < 0)
1751 return -EINVAL;
1752
1753 asihpi_ctl_init(&snd_control, hpi_ctl, "status");
1754 snd_control.access =
1755 SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ;
1756 snd_control.info = snd_asihpi_aesebu_rxstatus_info;
1757 snd_control.get = snd_asihpi_aesebu_rxstatus_get;
1758
1759 return ctl_add(card, &snd_control, asihpi);
1760}
1761
1762static int snd_asihpi_aesebu_tx_format_get(struct snd_kcontrol *kcontrol,
1763 struct snd_ctl_elem_value *ucontrol) {
1764 return snd_asihpi_aesebu_format_get(kcontrol, ucontrol,
1765 HPI_AESEBU__transmitter_get_format);
1766}
1767
1768static int snd_asihpi_aesebu_tx_format_put(struct snd_kcontrol *kcontrol,
1769 struct snd_ctl_elem_value *ucontrol) {
1770 return snd_asihpi_aesebu_format_put(kcontrol, ucontrol,
1771 HPI_AESEBU__transmitter_set_format);
1772}
1773
1774
1775static int __devinit snd_asihpi_aesebu_tx_add(struct snd_card_asihpi *asihpi,
1776 struct hpi_control *hpi_ctl)
1777{
1778 struct snd_card *card = asihpi->card;
1779 struct snd_kcontrol_new snd_control;
1780
1781 asihpi_ctl_init(&snd_control, hpi_ctl, "format");
1782 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
1783 snd_control.info = snd_asihpi_aesebu_format_info;
1784 snd_control.get = snd_asihpi_aesebu_tx_format_get;
1785 snd_control.put = snd_asihpi_aesebu_tx_format_put;
1786
1787 return ctl_add(card, &snd_control, asihpi);
1788}
1789
1790/*------------------------------------------------------------
1791 Tuner controls
1792 ------------------------------------------------------------*/
1793
1794/* Gain */
1795
1796static int snd_asihpi_tuner_gain_info(struct snd_kcontrol *kcontrol,
1797 struct snd_ctl_elem_info *uinfo)
1798{
1799 u32 h_control = kcontrol->private_value;
1800 u16 err;
1801 short idx;
1802 u16 gain_range[3];
1803
1804 for (idx = 0; idx < 3; idx++) {
1805 err = hpi_tuner_query_gain(ss, h_control,
1806 idx, &gain_range[idx]);
1807 if (err != 0)
1808 return err;
1809 }
1810
1811 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1812 uinfo->count = 1;
1813 uinfo->value.integer.min = ((int)gain_range[0]) / HPI_UNITS_PER_dB;
1814 uinfo->value.integer.max = ((int)gain_range[1]) / HPI_UNITS_PER_dB;
1815 uinfo->value.integer.step = ((int) gain_range[2]) / HPI_UNITS_PER_dB;
1816 return 0;
1817}
1818
1819static int snd_asihpi_tuner_gain_get(struct snd_kcontrol *kcontrol,
1820 struct snd_ctl_elem_value *ucontrol)
1821{
1822 /*
1823 struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
1824 */
1825 u32 h_control = kcontrol->private_value;
1826 short gain;
1827
1828 hpi_handle_error(hpi_tuner_get_gain(ss, h_control, &gain));
1829 ucontrol->value.integer.value[0] = gain / HPI_UNITS_PER_dB;
1830
1831 return 0;
1832}
1833
1834static int snd_asihpi_tuner_gain_put(struct snd_kcontrol *kcontrol,
1835 struct snd_ctl_elem_value *ucontrol)
1836{
1837 /*
1838 struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
1839 */
1840 u32 h_control = kcontrol->private_value;
1841 short gain;
1842
1843 gain = (ucontrol->value.integer.value[0]) * HPI_UNITS_PER_dB;
1844 hpi_handle_error(hpi_tuner_set_gain(ss, h_control, gain));
1845
1846 return 1;
1847}
1848
1849/* Band */
1850
1851static int asihpi_tuner_band_query(struct snd_kcontrol *kcontrol,
1852 u16 *band_list, u32 len) {
1853 u32 h_control = kcontrol->private_value;
1854 u16 err = 0;
1855 u32 i;
1856
1857 for (i = 0; i < len; i++) {
1858 err = hpi_tuner_query_band(ss,
1859 h_control, i, &band_list[i]);
1860 if (err != 0)
1861 break;
1862 }
1863
1864 if (err && (err != HPI_ERROR_INVALID_OBJ_INDEX))
1865 return -EIO;
1866
1867 return i;
1868}
1869
1870static int snd_asihpi_tuner_band_info(struct snd_kcontrol *kcontrol,
1871 struct snd_ctl_elem_info *uinfo)
1872{
1873 u16 tuner_bands[HPI_TUNER_BAND_LAST];
1874 int num_bands = 0;
1875
1876 num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1877 HPI_TUNER_BAND_LAST);
1878
1879 if (num_bands < 0)
1880 return num_bands;
1881
1882 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1883 uinfo->count = 1;
1884 uinfo->value.enumerated.items = num_bands;
1885
1886 if (num_bands > 0) {
1887 if (uinfo->value.enumerated.item >=
1888 uinfo->value.enumerated.items)
1889 uinfo->value.enumerated.item =
1890 uinfo->value.enumerated.items - 1;
1891
1892 strcpy(uinfo->value.enumerated.name,
1893 asihpi_tuner_band_names[
1894 tuner_bands[uinfo->value.enumerated.item]]);
1895
1896 }
1897 return 0;
1898}
1899
1900static int snd_asihpi_tuner_band_get(struct snd_kcontrol *kcontrol,
1901 struct snd_ctl_elem_value *ucontrol)
1902{
1903 u32 h_control = kcontrol->private_value;
1904 /*
1905 struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
1906 */
1907 u16 band, idx;
1908 u16 tuner_bands[HPI_TUNER_BAND_LAST];
1909 u32 num_bands = 0;
1910
1911 num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1912 HPI_TUNER_BAND_LAST);
1913
1914 hpi_handle_error(hpi_tuner_get_band(ss, h_control, &band));
1915
1916 ucontrol->value.enumerated.item[0] = -1;
1917 for (idx = 0; idx < HPI_TUNER_BAND_LAST; idx++)
1918 if (tuner_bands[idx] == band) {
1919 ucontrol->value.enumerated.item[0] = idx;
1920 break;
1921 }
1922
1923 return 0;
1924}
1925
1926static int snd_asihpi_tuner_band_put(struct snd_kcontrol *kcontrol,
1927 struct snd_ctl_elem_value *ucontrol)
1928{
1929 /*
1930 struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
1931 */
1932 u32 h_control = kcontrol->private_value;
1933 u16 band;
1934 u16 tuner_bands[HPI_TUNER_BAND_LAST];
1935 u32 num_bands = 0;
1936
1937 num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1938 HPI_TUNER_BAND_LAST);
1939
1940 band = tuner_bands[ucontrol->value.enumerated.item[0]];
1941 hpi_handle_error(hpi_tuner_set_band(ss, h_control, band));
1942
1943 return 1;
1944}
1945
1946/* Freq */
1947
1948static int snd_asihpi_tuner_freq_info(struct snd_kcontrol *kcontrol,
1949 struct snd_ctl_elem_info *uinfo)
1950{
1951 u32 h_control = kcontrol->private_value;
1952 u16 err;
1953 u16 tuner_bands[HPI_TUNER_BAND_LAST];
1954 u16 num_bands = 0, band_iter, idx;
1955 u32 freq_range[3], temp_freq_range[3];
1956
1957 num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1958 HPI_TUNER_BAND_LAST);
1959
1960 freq_range[0] = INT_MAX;
1961 freq_range[1] = 0;
1962 freq_range[2] = INT_MAX;
1963
1964 for (band_iter = 0; band_iter < num_bands; band_iter++) {
1965 for (idx = 0; idx < 3; idx++) {
1966 err = hpi_tuner_query_frequency(ss, h_control,
1967 idx, tuner_bands[band_iter],
1968 &temp_freq_range[idx]);
1969 if (err != 0)
1970 return err;
1971 }
1972
1973 /* skip band with bogus stepping */
1974 if (temp_freq_range[2] <= 0)
1975 continue;
1976
1977 if (temp_freq_range[0] < freq_range[0])
1978 freq_range[0] = temp_freq_range[0];
1979 if (temp_freq_range[1] > freq_range[1])
1980 freq_range[1] = temp_freq_range[1];
1981 if (temp_freq_range[2] < freq_range[2])
1982 freq_range[2] = temp_freq_range[2];
1983 }
1984
1985 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1986 uinfo->count = 1;
1987 uinfo->value.integer.min = ((int)freq_range[0]);
1988 uinfo->value.integer.max = ((int)freq_range[1]);
1989 uinfo->value.integer.step = ((int)freq_range[2]);
1990 return 0;
1991}
1992
1993static int snd_asihpi_tuner_freq_get(struct snd_kcontrol *kcontrol,
1994 struct snd_ctl_elem_value *ucontrol)
1995{
1996 u32 h_control = kcontrol->private_value;
1997 u32 freq;
1998
1999 hpi_handle_error(hpi_tuner_get_frequency(ss, h_control, &freq));
2000 ucontrol->value.integer.value[0] = freq;
2001
2002 return 0;
2003}
2004
2005static int snd_asihpi_tuner_freq_put(struct snd_kcontrol *kcontrol,
2006 struct snd_ctl_elem_value *ucontrol)
2007{
2008 u32 h_control = kcontrol->private_value;
2009 u32 freq;
2010
2011 freq = ucontrol->value.integer.value[0];
2012 hpi_handle_error(hpi_tuner_set_frequency(ss, h_control, freq));
2013
2014 return 1;
2015}
2016
2017/* Tuner control group initializer */
2018static int __devinit snd_asihpi_tuner_add(struct snd_card_asihpi *asihpi,
2019 struct hpi_control *hpi_ctl)
2020{
2021 struct snd_card *card = asihpi->card;
2022 struct snd_kcontrol_new snd_control;
2023
2024 snd_control.private_value = hpi_ctl->h_control;
2025 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
2026
2027 if (!hpi_tuner_get_gain(ss, hpi_ctl->h_control, NULL)) {
2028 asihpi_ctl_init(&snd_control, hpi_ctl, "gain");
2029 snd_control.info = snd_asihpi_tuner_gain_info;
2030 snd_control.get = snd_asihpi_tuner_gain_get;
2031 snd_control.put = snd_asihpi_tuner_gain_put;
2032
2033 if (ctl_add(card, &snd_control, asihpi) < 0)
2034 return -EINVAL;
2035 }
2036
2037 asihpi_ctl_init(&snd_control, hpi_ctl, "band");
2038 snd_control.info = snd_asihpi_tuner_band_info;
2039 snd_control.get = snd_asihpi_tuner_band_get;
2040 snd_control.put = snd_asihpi_tuner_band_put;
2041
2042 if (ctl_add(card, &snd_control, asihpi) < 0)
2043 return -EINVAL;
2044
2045 asihpi_ctl_init(&snd_control, hpi_ctl, "freq");
2046 snd_control.info = snd_asihpi_tuner_freq_info;
2047 snd_control.get = snd_asihpi_tuner_freq_get;
2048 snd_control.put = snd_asihpi_tuner_freq_put;
2049
2050 return ctl_add(card, &snd_control, asihpi);
2051}
2052
2053/*------------------------------------------------------------
2054 Meter controls
2055 ------------------------------------------------------------*/
2056static int snd_asihpi_meter_info(struct snd_kcontrol *kcontrol,
2057 struct snd_ctl_elem_info *uinfo)
2058{
2059 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2060 uinfo->count = HPI_MAX_CHANNELS;
2061 uinfo->value.integer.min = 0;
2062 uinfo->value.integer.max = 0x7FFFFFFF;
2063 return 0;
2064}
2065
2066/* linear values for 10dB steps */
2067static int log2lin[] = {
2068 0x7FFFFFFF, /* 0dB */
2069 679093956,
2070 214748365,
2071 67909396,
2072 21474837,
2073 6790940,
2074 2147484, /* -60dB */
2075 679094,
2076 214748, /* -80 */
2077 67909,
2078 21475, /* -100 */
2079 6791,
2080 2147,
2081 679,
2082 214,
2083 68,
2084 21,
2085 7,
2086 2
2087};
2088
2089static int snd_asihpi_meter_get(struct snd_kcontrol *kcontrol,
2090 struct snd_ctl_elem_value *ucontrol)
2091{
2092 u32 h_control = kcontrol->private_value;
2093 short an_gain_mB[HPI_MAX_CHANNELS], i;
2094 u16 err;
2095
2096 err = hpi_meter_get_peak(ss, h_control, an_gain_mB);
2097
2098 for (i = 0; i < HPI_MAX_CHANNELS; i++) {
2099 if (err) {
2100 ucontrol->value.integer.value[i] = 0;
2101 } else if (an_gain_mB[i] >= 0) {
2102 ucontrol->value.integer.value[i] =
2103 an_gain_mB[i] << 16;
2104 } else {
2105 /* -ve is log value in millibels < -60dB,
2106 * convert to (roughly!) linear,
2107 */
2108 ucontrol->value.integer.value[i] =
2109 log2lin[an_gain_mB[i] / -1000];
2110 }
2111 }
2112 return 0;
2113}
2114
2115static int __devinit snd_asihpi_meter_add(struct snd_card_asihpi *asihpi,
2116 struct hpi_control *hpi_ctl, int subidx)
2117{
2118 struct snd_card *card = asihpi->card;
2119 struct snd_kcontrol_new snd_control;
2120
2121 asihpi_ctl_init(&snd_control, hpi_ctl, "meter");
2122 snd_control.access =
2123 SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ;
2124 snd_control.info = snd_asihpi_meter_info;
2125 snd_control.get = snd_asihpi_meter_get;
2126
2127 snd_control.index = subidx;
2128
2129 return ctl_add(card, &snd_control, asihpi);
2130}
2131
2132/*------------------------------------------------------------
2133 Multiplexer controls
2134 ------------------------------------------------------------*/
2135static int snd_card_asihpi_mux_count_sources(struct snd_kcontrol *snd_control)
2136{
2137 u32 h_control = snd_control->private_value;
2138 struct hpi_control hpi_ctl;
2139 int s, err;
2140 for (s = 0; s < 32; s++) {
2141 err = hpi_multiplexer_query_source(ss, h_control, s,
2142 &hpi_ctl.
2143 src_node_type,
2144 &hpi_ctl.
2145 src_node_index);
2146 if (err)
2147 break;
2148 }
2149 return s;
2150}
2151
2152static int snd_asihpi_mux_info(struct snd_kcontrol *kcontrol,
2153 struct snd_ctl_elem_info *uinfo)
2154{
2155 int err;
2156 u16 src_node_type, src_node_index;
2157 u32 h_control = kcontrol->private_value;
2158
2159 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2160 uinfo->count = 1;
2161 uinfo->value.enumerated.items =
2162 snd_card_asihpi_mux_count_sources(kcontrol);
2163
2164 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2165 uinfo->value.enumerated.item =
2166 uinfo->value.enumerated.items - 1;
2167
2168 err =
2169 hpi_multiplexer_query_source(ss, h_control,
2170 uinfo->value.enumerated.item,
2171 &src_node_type, &src_node_index);
2172
2173 sprintf(uinfo->value.enumerated.name, "%s %d",
2174 asihpi_src_names[src_node_type - HPI_SOURCENODE_BASE],
2175 src_node_index);
2176 return 0;
2177}
2178
2179static int snd_asihpi_mux_get(struct snd_kcontrol *kcontrol,
2180 struct snd_ctl_elem_value *ucontrol)
2181{
2182 u32 h_control = kcontrol->private_value;
2183 u16 source_type, source_index;
2184 u16 src_node_type, src_node_index;
2185 int s;
2186
2187 hpi_handle_error(hpi_multiplexer_get_source(ss, h_control,
2188 &source_type, &source_index));
2189 /* Should cache this search result! */
2190 for (s = 0; s < 256; s++) {
2191 if (hpi_multiplexer_query_source(ss, h_control, s,
2192 &src_node_type, &src_node_index))
2193 break;
2194
2195 if ((source_type == src_node_type)
2196 && (source_index == src_node_index)) {
2197 ucontrol->value.enumerated.item[0] = s;
2198 return 0;
2199 }
2200 }
2201 snd_printd(KERN_WARNING
2202 "control %x failed to match mux source %hu %hu\n",
2203 h_control, source_type, source_index);
2204 ucontrol->value.enumerated.item[0] = 0;
2205 return 0;
2206}
2207
2208static int snd_asihpi_mux_put(struct snd_kcontrol *kcontrol,
2209 struct snd_ctl_elem_value *ucontrol)
2210{
2211 int change;
2212 u32 h_control = kcontrol->private_value;
2213 u16 source_type, source_index;
2214 u16 e;
2215
2216 change = 1;
2217
2218 e = hpi_multiplexer_query_source(ss, h_control,
2219 ucontrol->value.enumerated.item[0],
2220 &source_type, &source_index);
2221 if (!e)
2222 hpi_handle_error(
2223 hpi_multiplexer_set_source(ss, h_control,
2224 source_type, source_index));
2225 return change;
2226}
2227
2228
2229static int __devinit snd_asihpi_mux_add(struct snd_card_asihpi *asihpi,
2230 struct hpi_control *hpi_ctl)
2231{
2232 struct snd_card *card = asihpi->card;
2233 struct snd_kcontrol_new snd_control;
2234
2235#if ASI_STYLE_NAMES
2236 asihpi_ctl_init(&snd_control, hpi_ctl, "multiplexer");
2237#else
2238 asihpi_ctl_init(&snd_control, hpi_ctl, "route");
2239#endif
2240 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
2241 snd_control.info = snd_asihpi_mux_info;
2242 snd_control.get = snd_asihpi_mux_get;
2243 snd_control.put = snd_asihpi_mux_put;
2244
2245 return ctl_add(card, &snd_control, asihpi);
2246
2247}
2248
2249/*------------------------------------------------------------
2250 Channel mode controls
2251 ------------------------------------------------------------*/
2252static int snd_asihpi_cmode_info(struct snd_kcontrol *kcontrol,
2253 struct snd_ctl_elem_info *uinfo)
2254{
2255 static char *mode_names[HPI_CHANNEL_MODE_LAST] = {
2256 "normal", "swap",
2257 "from_left", "from_right",
2258 "to_left", "to_right"
2259 };
2260
2261 u32 h_control = kcontrol->private_value;
2262 u16 mode;
2263 int i;
2264
2265 /* HPI channel mode values can be from 1 to 6
2266 Some adapters only support a contiguous subset
2267 */
2268 for (i = 0; i < HPI_CHANNEL_MODE_LAST; i++)
2269 if (hpi_channel_mode_query_mode(
2270 ss, h_control, i, &mode))
2271 break;
2272
2273 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2274 uinfo->count = 1;
2275 uinfo->value.enumerated.items = i;
2276
2277 if (uinfo->value.enumerated.item >= i)
2278 uinfo->value.enumerated.item = i - 1;
2279
2280 strcpy(uinfo->value.enumerated.name,
2281 mode_names[uinfo->value.enumerated.item]);
2282
2283 return 0;
2284}
2285
2286static int snd_asihpi_cmode_get(struct snd_kcontrol *kcontrol,
2287 struct snd_ctl_elem_value *ucontrol)
2288{
2289 u32 h_control = kcontrol->private_value;
2290 u16 mode;
2291
2292 if (hpi_channel_mode_get(ss, h_control, &mode))
2293 mode = 1;
2294
2295 ucontrol->value.enumerated.item[0] = mode - 1;
2296
2297 return 0;
2298}
2299
2300static int snd_asihpi_cmode_put(struct snd_kcontrol *kcontrol,
2301 struct snd_ctl_elem_value *ucontrol)
2302{
2303 int change;
2304 u32 h_control = kcontrol->private_value;
2305
2306 change = 1;
2307
2308 hpi_handle_error(hpi_channel_mode_set(ss, h_control,
2309 ucontrol->value.enumerated.item[0] + 1));
2310 return change;
2311}
2312
2313
2314static int __devinit snd_asihpi_cmode_add(struct snd_card_asihpi *asihpi,
2315 struct hpi_control *hpi_ctl)
2316{
2317 struct snd_card *card = asihpi->card;
2318 struct snd_kcontrol_new snd_control;
2319
2320 asihpi_ctl_init(&snd_control, hpi_ctl, "channel mode");
2321 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
2322 snd_control.info = snd_asihpi_cmode_info;
2323 snd_control.get = snd_asihpi_cmode_get;
2324 snd_control.put = snd_asihpi_cmode_put;
2325
2326 return ctl_add(card, &snd_control, asihpi);
2327}
2328
2329/*------------------------------------------------------------
2330 Sampleclock source controls
2331 ------------------------------------------------------------*/
2332
2333static char *sampleclock_sources[MAX_CLOCKSOURCES] =
2334 { "N/A", "local PLL", "AES/EBU sync", "word external", "word header",
2335 "SMPTE", "AES/EBU in1", "auto", "network", "invalid",
2336 "prev module",
2337 "AES/EBU in2", "AES/EBU in3", "AES/EBU in4", "AES/EBU in5",
2338 "AES/EBU in6", "AES/EBU in7", "AES/EBU in8"};
2339
2340
2341
2342static int snd_asihpi_clksrc_info(struct snd_kcontrol *kcontrol,
2343 struct snd_ctl_elem_info *uinfo)
2344{
2345 struct snd_card_asihpi *asihpi =
2346 (struct snd_card_asihpi *)(kcontrol->private_data);
2347 struct clk_cache *clkcache = &asihpi->cc;
2348 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2349 uinfo->count = 1;
2350 uinfo->value.enumerated.items = clkcache->count;
2351
2352 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2353 uinfo->value.enumerated.item =
2354 uinfo->value.enumerated.items - 1;
2355
2356 strcpy(uinfo->value.enumerated.name,
2357 clkcache->s[uinfo->value.enumerated.item].name);
2358 return 0;
2359}
2360
2361static int snd_asihpi_clksrc_get(struct snd_kcontrol *kcontrol,
2362 struct snd_ctl_elem_value *ucontrol)
2363{
2364 struct snd_card_asihpi *asihpi =
2365 (struct snd_card_asihpi *)(kcontrol->private_data);
2366 struct clk_cache *clkcache = &asihpi->cc;
2367 u32 h_control = kcontrol->private_value;
2368 u16 source, srcindex = 0;
2369 int i;
2370
2371 ucontrol->value.enumerated.item[0] = 0;
2372 if (hpi_sample_clock_get_source(ss, h_control, &source))
2373 source = 0;
2374
2375 if (source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT)
2376 if (hpi_sample_clock_get_source_index(ss, h_control, &srcindex))
2377 srcindex = 0;
2378
2379 for (i = 0; i < clkcache->count; i++)
2380 if ((clkcache->s[i].source == source) &&
2381 (clkcache->s[i].index == srcindex))
2382 break;
2383
2384 ucontrol->value.enumerated.item[0] = i;
2385
2386 return 0;
2387}
2388
2389static int snd_asihpi_clksrc_put(struct snd_kcontrol *kcontrol,
2390 struct snd_ctl_elem_value *ucontrol)
2391{
2392 struct snd_card_asihpi *asihpi =
2393 (struct snd_card_asihpi *)(kcontrol->private_data);
2394 struct clk_cache *clkcache = &asihpi->cc;
2395 int change, item;
2396 u32 h_control = kcontrol->private_value;
2397
2398 change = 1;
2399 item = ucontrol->value.enumerated.item[0];
2400 if (item >= clkcache->count)
2401 item = clkcache->count-1;
2402
2403 hpi_handle_error(hpi_sample_clock_set_source(ss,
2404 h_control, clkcache->s[item].source));
2405
2406 if (clkcache->s[item].source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT)
2407 hpi_handle_error(hpi_sample_clock_set_source_index(ss,
2408 h_control, clkcache->s[item].index));
2409 return change;
2410}
2411
2412/*------------------------------------------------------------
2413 Clkrate controls
2414 ------------------------------------------------------------*/
2415/* Need to change this to enumerated control with list of rates */
2416static int snd_asihpi_clklocal_info(struct snd_kcontrol *kcontrol,
2417 struct snd_ctl_elem_info *uinfo)
2418{
2419 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2420 uinfo->count = 1;
2421 uinfo->value.integer.min = 8000;
2422 uinfo->value.integer.max = 192000;
2423 uinfo->value.integer.step = 100;
2424
2425 return 0;
2426}
2427
2428static int snd_asihpi_clklocal_get(struct snd_kcontrol *kcontrol,
2429 struct snd_ctl_elem_value *ucontrol)
2430{
2431 u32 h_control = kcontrol->private_value;
2432 u32 rate;
2433 u16 e;
2434
2435 e = hpi_sample_clock_get_local_rate(ss, h_control, &rate);
2436 if (!e)
2437 ucontrol->value.integer.value[0] = rate;
2438 else
2439 ucontrol->value.integer.value[0] = 0;
2440 return 0;
2441}
2442
2443static int snd_asihpi_clklocal_put(struct snd_kcontrol *kcontrol,
2444 struct snd_ctl_elem_value *ucontrol)
2445{
2446 int change;
2447 u32 h_control = kcontrol->private_value;
2448
2449 /* change = asihpi->mixer_clkrate[addr][0] != left ||
2450 asihpi->mixer_clkrate[addr][1] != right;
2451 */
2452 change = 1;
2453 hpi_handle_error(hpi_sample_clock_set_local_rate(ss, h_control,
2454 ucontrol->value.integer.value[0]));
2455 return change;
2456}
2457
2458static int snd_asihpi_clkrate_info(struct snd_kcontrol *kcontrol,
2459 struct snd_ctl_elem_info *uinfo)
2460{
2461 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2462 uinfo->count = 1;
2463 uinfo->value.integer.min = 8000;
2464 uinfo->value.integer.max = 192000;
2465 uinfo->value.integer.step = 100;
2466
2467 return 0;
2468}
2469
2470static int snd_asihpi_clkrate_get(struct snd_kcontrol *kcontrol,
2471 struct snd_ctl_elem_value *ucontrol)
2472{
2473 u32 h_control = kcontrol->private_value;
2474 u32 rate;
2475 u16 e;
2476
2477 e = hpi_sample_clock_get_sample_rate(ss, h_control, &rate);
2478 if (!e)
2479 ucontrol->value.integer.value[0] = rate;
2480 else
2481 ucontrol->value.integer.value[0] = 0;
2482 return 0;
2483}
2484
2485static int __devinit snd_asihpi_sampleclock_add(struct snd_card_asihpi *asihpi,
2486 struct hpi_control *hpi_ctl)
2487{
2488 struct snd_card *card = asihpi->card;
2489 struct snd_kcontrol_new snd_control;
2490
2491 struct clk_cache *clkcache = &asihpi->cc;
2492 u32 hSC = hpi_ctl->h_control;
2493 int has_aes_in = 0;
2494 int i, j;
2495 u16 source;
2496
2497 snd_control.private_value = hpi_ctl->h_control;
2498
2499 clkcache->has_local = 0;
2500
2501 for (i = 0; i <= HPI_SAMPLECLOCK_SOURCE_LAST; i++) {
2502 if (hpi_sample_clock_query_source(ss, hSC,
2503 i, &source))
2504 break;
2505 clkcache->s[i].source = source;
2506 clkcache->s[i].index = 0;
2507 clkcache->s[i].name = sampleclock_sources[source];
2508 if (source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT)
2509 has_aes_in = 1;
2510 if (source == HPI_SAMPLECLOCK_SOURCE_LOCAL)
2511 clkcache->has_local = 1;
2512 }
2513 if (has_aes_in)
2514 /* already will have picked up index 0 above */
2515 for (j = 1; j < 8; j++) {
2516 if (hpi_sample_clock_query_source_index(ss, hSC,
2517 j, HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT,
2518 &source))
2519 break;
2520 clkcache->s[i].source =
2521 HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT;
2522 clkcache->s[i].index = j;
2523 clkcache->s[i].name = sampleclock_sources[
2524 j+HPI_SAMPLECLOCK_SOURCE_LAST];
2525 i++;
2526 }
2527 clkcache->count = i;
2528
2529 asihpi_ctl_init(&snd_control, hpi_ctl, "source");
2530 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE ;
2531 snd_control.info = snd_asihpi_clksrc_info;
2532 snd_control.get = snd_asihpi_clksrc_get;
2533 snd_control.put = snd_asihpi_clksrc_put;
2534 if (ctl_add(card, &snd_control, asihpi) < 0)
2535 return -EINVAL;
2536
2537
2538 if (clkcache->has_local) {
2539 asihpi_ctl_init(&snd_control, hpi_ctl, "local_rate");
2540 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE ;
2541 snd_control.info = snd_asihpi_clklocal_info;
2542 snd_control.get = snd_asihpi_clklocal_get;
2543 snd_control.put = snd_asihpi_clklocal_put;
2544
2545
2546 if (ctl_add(card, &snd_control, asihpi) < 0)
2547 return -EINVAL;
2548 }
2549
2550 asihpi_ctl_init(&snd_control, hpi_ctl, "rate");
2551 snd_control.access =
2552 SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ;
2553 snd_control.info = snd_asihpi_clkrate_info;
2554 snd_control.get = snd_asihpi_clkrate_get;
2555
2556 return ctl_add(card, &snd_control, asihpi);
2557}
2558/*------------------------------------------------------------
2559 Mixer
2560 ------------------------------------------------------------*/
2561
2562static int __devinit snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi)
2563{
2564 struct snd_card *card = asihpi->card;
2565 unsigned int idx = 0;
2566 unsigned int subindex = 0;
2567 int err;
2568 struct hpi_control hpi_ctl, prev_ctl;
2569
2570 if (snd_BUG_ON(!asihpi))
2571 return -EINVAL;
2572 strcpy(card->mixername, "asihpi mixer");
2573
2574 err =
2575 hpi_mixer_open(ss, asihpi->adapter_index,
2576 &asihpi->h_mixer);
2577 hpi_handle_error(err);
2578 if (err)
2579 return -err;
2580
2581 for (idx = 0; idx < 2000; idx++) {
2582 err = hpi_mixer_get_control_by_index(
2583 ss, asihpi->h_mixer,
2584 idx,
2585 &hpi_ctl.src_node_type,
2586 &hpi_ctl.src_node_index,
2587 &hpi_ctl.dst_node_type,
2588 &hpi_ctl.dst_node_index,
2589 &hpi_ctl.control_type,
2590 &hpi_ctl.h_control);
2591 if (err) {
2592 if (err == HPI_ERROR_CONTROL_DISABLED) {
2593 if (mixer_dump)
2594 snd_printk(KERN_INFO
2595 "disabled HPI control(%d)\n",
2596 idx);
2597 continue;
2598 } else
2599 break;
2600
2601 }
2602
2603 hpi_ctl.src_node_type -= HPI_SOURCENODE_BASE;
2604 hpi_ctl.dst_node_type -= HPI_DESTNODE_BASE;
2605
2606 /* ASI50xx in SSX mode has multiple meters on the same node.
2607 Use subindex to create distinct ALSA controls
2608 for any duplicated controls.
2609 */
2610 if ((hpi_ctl.control_type == prev_ctl.control_type) &&
2611 (hpi_ctl.src_node_type == prev_ctl.src_node_type) &&
2612 (hpi_ctl.src_node_index == prev_ctl.src_node_index) &&
2613 (hpi_ctl.dst_node_type == prev_ctl.dst_node_type) &&
2614 (hpi_ctl.dst_node_index == prev_ctl.dst_node_index))
2615 subindex++;
2616 else
2617 subindex = 0;
2618
2619 prev_ctl = hpi_ctl;
2620
2621 switch (hpi_ctl.control_type) {
2622 case HPI_CONTROL_VOLUME:
2623 err = snd_asihpi_volume_add(asihpi, &hpi_ctl);
2624 break;
2625 case HPI_CONTROL_LEVEL:
2626 err = snd_asihpi_level_add(asihpi, &hpi_ctl);
2627 break;
2628 case HPI_CONTROL_MULTIPLEXER:
2629 err = snd_asihpi_mux_add(asihpi, &hpi_ctl);
2630 break;
2631 case HPI_CONTROL_CHANNEL_MODE:
2632 err = snd_asihpi_cmode_add(asihpi, &hpi_ctl);
2633 break;
2634 case HPI_CONTROL_METER:
2635 err = snd_asihpi_meter_add(asihpi, &hpi_ctl, subindex);
2636 break;
2637 case HPI_CONTROL_SAMPLECLOCK:
2638 err = snd_asihpi_sampleclock_add(
2639 asihpi, &hpi_ctl);
2640 break;
2641 case HPI_CONTROL_CONNECTION: /* ignore these */
2642 continue;
2643 case HPI_CONTROL_TUNER:
2644 err = snd_asihpi_tuner_add(asihpi, &hpi_ctl);
2645 break;
2646 case HPI_CONTROL_AESEBU_TRANSMITTER:
2647 err = snd_asihpi_aesebu_tx_add(asihpi, &hpi_ctl);
2648 break;
2649 case HPI_CONTROL_AESEBU_RECEIVER:
2650 err = snd_asihpi_aesebu_rx_add(asihpi, &hpi_ctl);
2651 break;
2652 case HPI_CONTROL_VOX:
2653 case HPI_CONTROL_BITSTREAM:
2654 case HPI_CONTROL_MICROPHONE:
2655 case HPI_CONTROL_PARAMETRIC_EQ:
2656 case HPI_CONTROL_COMPANDER:
2657 default:
2658 if (mixer_dump)
2659 snd_printk(KERN_INFO
2660 "untranslated HPI control"
2661 "(%d) %d %d %d %d %d\n",
2662 idx,
2663 hpi_ctl.control_type,
2664 hpi_ctl.src_node_type,
2665 hpi_ctl.src_node_index,
2666 hpi_ctl.dst_node_type,
2667 hpi_ctl.dst_node_index);
2668 continue;
2669 };
2670 if (err < 0)
2671 return err;
2672 }
2673 if (HPI_ERROR_INVALID_OBJ_INDEX != err)
2674 hpi_handle_error(err);
2675
2676 snd_printk(KERN_INFO "%d mixer controls found\n", idx);
2677
2678 return 0;
2679}
2680
2681/*------------------------------------------------------------
2682 /proc interface
2683 ------------------------------------------------------------*/
2684
2685static void
2686snd_asihpi_proc_read(struct snd_info_entry *entry,
2687 struct snd_info_buffer *buffer)
2688{
2689 struct snd_card_asihpi *asihpi = entry->private_data;
2690 u16 version;
2691 u32 h_control;
2692 u32 rate = 0;
2693 u16 source = 0;
2694 int err;
2695
2696 snd_iprintf(buffer, "ASIHPI driver proc file\n");
2697 snd_iprintf(buffer,
2698 "adapter ID=%4X\n_index=%d\n"
2699 "num_outstreams=%d\n_num_instreams=%d\n",
2700 asihpi->type, asihpi->adapter_index,
2701 asihpi->num_outstreams, asihpi->num_instreams);
2702
2703 version = asihpi->version;
2704 snd_iprintf(buffer,
2705 "serial#=%d\n_hw version %c%d\nDSP code version %03d\n",
2706 asihpi->serial_number, ((version >> 3) & 0xf) + 'A',
2707 version & 0x7,
2708 ((version >> 13) * 100) + ((version >> 7) & 0x3f));
2709
2710 err = hpi_mixer_get_control(ss, asihpi->h_mixer,
2711 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
2712 HPI_CONTROL_SAMPLECLOCK, &h_control);
2713
2714 if (!err) {
2715 err = hpi_sample_clock_get_sample_rate(ss,
2716 h_control, &rate);
2717 err += hpi_sample_clock_get_source(ss, h_control, &source);
2718
2719 if (!err)
2720 snd_iprintf(buffer, "sample_clock=%d_hz, source %s\n",
2721 rate, sampleclock_sources[source]);
2722 }
2723
2724}
2725
2726
2727static void __devinit snd_asihpi_proc_init(struct snd_card_asihpi *asihpi)
2728{
2729 struct snd_info_entry *entry;
2730
2731 if (!snd_card_proc_new(asihpi->card, "info", &entry))
2732 snd_info_set_text_ops(entry, asihpi, snd_asihpi_proc_read);
2733}
2734
2735/*------------------------------------------------------------
2736 HWDEP
2737 ------------------------------------------------------------*/
2738
2739static int snd_asihpi_hpi_open(struct snd_hwdep *hw, struct file *file)
2740{
2741 if (enable_hpi_hwdep)
2742 return 0;
2743 else
2744 return -ENODEV;
2745
2746}
2747
2748static int snd_asihpi_hpi_release(struct snd_hwdep *hw, struct file *file)
2749{
2750 if (enable_hpi_hwdep)
2751 return asihpi_hpi_release(file);
2752 else
2753 return -ENODEV;
2754}
2755
2756static int snd_asihpi_hpi_ioctl(struct snd_hwdep *hw, struct file *file,
2757 unsigned int cmd, unsigned long arg)
2758{
2759 if (enable_hpi_hwdep)
2760 return asihpi_hpi_ioctl(file, cmd, arg);
2761 else
2762 return -ENODEV;
2763}
2764
2765
2766/* results in /dev/snd/hwC#D0 file for each card with index #
2767 also /proc/asound/hwdep will contain '#-00: asihpi (HPI) for each card'
2768*/
2769static int __devinit snd_asihpi_hpi_new(struct snd_card_asihpi *asihpi,
2770 int device, struct snd_hwdep **rhwdep)
2771{
2772 struct snd_hwdep *hw;
2773 int err;
2774
2775 if (rhwdep)
2776 *rhwdep = NULL;
2777 err = snd_hwdep_new(asihpi->card, "HPI", device, &hw);
2778 if (err < 0)
2779 return err;
2780 strcpy(hw->name, "asihpi (HPI)");
2781 hw->iface = SNDRV_HWDEP_IFACE_LAST;
2782 hw->ops.open = snd_asihpi_hpi_open;
2783 hw->ops.ioctl = snd_asihpi_hpi_ioctl;
2784 hw->ops.release = snd_asihpi_hpi_release;
2785 hw->private_data = asihpi;
2786 if (rhwdep)
2787 *rhwdep = hw;
2788 return 0;
2789}
2790
2791/*------------------------------------------------------------
2792 CARD
2793 ------------------------------------------------------------*/
2794static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev,
2795 const struct pci_device_id *pci_id)
2796{
2797 int err;
2798
2799 u16 version;
2800 int pcm_substreams;
2801
2802 struct hpi_adapter *hpi_card;
2803 struct snd_card *card;
2804 struct snd_card_asihpi *asihpi;
2805
2806 u32 h_control;
2807 u32 h_stream;
2808
2809 static int dev;
2810 if (dev >= SNDRV_CARDS)
2811 return -ENODEV;
2812
2813 /* Should this be enable[hpi_card->index] ? */
2814 if (!enable[dev]) {
2815 dev++;
2816 return -ENOENT;
2817 }
2818
2819 err = asihpi_adapter_probe(pci_dev, pci_id);
2820 if (err < 0)
2821 return err;
2822
2823 hpi_card = pci_get_drvdata(pci_dev);
2824 /* first try to give the card the same index as its hardware index */
2825 err = snd_card_create(hpi_card->index,
2826 id[hpi_card->index], THIS_MODULE,
2827 sizeof(struct snd_card_asihpi),
2828 &card);
2829 if (err < 0) {
2830 /* if that fails, try the default index==next available */
2831 err =
2832 snd_card_create(index[dev], id[dev],
2833 THIS_MODULE,
2834 sizeof(struct snd_card_asihpi),
2835 &card);
2836 if (err < 0)
2837 return err;
2838 snd_printk(KERN_WARNING
2839 "**** WARNING **** adapter index %d->ALSA index %d\n",
2840 hpi_card->index, card->number);
2841 }
2842
2843 asihpi = (struct snd_card_asihpi *) card->private_data;
2844 asihpi->card = card;
2845 asihpi->pci = hpi_card->pci;
2846 asihpi->adapter_index = hpi_card->index;
2847 hpi_handle_error(hpi_adapter_get_info(ss,
2848 asihpi->adapter_index,
2849 &asihpi->num_outstreams,
2850 &asihpi->num_instreams,
2851 &asihpi->version,
2852 &asihpi->serial_number, &asihpi->type));
2853
2854 version = asihpi->version;
2855 snd_printk(KERN_INFO "adapter ID=%4X index=%d num_outstreams=%d "
2856 "num_instreams=%d S/N=%d\n"
2857 "hw version %c%d DSP code version %03d\n",
2858 asihpi->type, asihpi->adapter_index,
2859 asihpi->num_outstreams,
2860 asihpi->num_instreams, asihpi->serial_number,
2861 ((version >> 3) & 0xf) + 'A',
2862 version & 0x7,
2863 ((version >> 13) * 100) + ((version >> 7) & 0x3f));
2864
2865 pcm_substreams = asihpi->num_outstreams;
2866 if (pcm_substreams < asihpi->num_instreams)
2867 pcm_substreams = asihpi->num_instreams;
2868
2869 err = hpi_adapter_get_property(ss, asihpi->adapter_index,
2870 HPI_ADAPTER_PROPERTY_CAPS1,
2871 NULL, &asihpi->support_grouping);
2872 if (err)
2873 asihpi->support_grouping = 0;
2874
2875 err = hpi_adapter_get_property(ss, asihpi->adapter_index,
2876 HPI_ADAPTER_PROPERTY_CAPS2,
2877 &asihpi->support_mrx, NULL);
2878 if (err)
2879 asihpi->support_mrx = 0;
2880
2881 err = hpi_adapter_get_property(ss, asihpi->adapter_index,
2882 HPI_ADAPTER_PROPERTY_INTERVAL,
2883 NULL, &asihpi->update_interval_frames);
2884 if (err)
2885 asihpi->update_interval_frames = 512;
2886
2887 hpi_handle_error(hpi_instream_open(ss, asihpi->adapter_index,
2888 0, &h_stream));
2889
2890 err = hpi_instream_host_buffer_free(ss, h_stream);
2891 asihpi->support_mmap = (!err);
2892
2893 hpi_handle_error(hpi_instream_close(ss, h_stream));
2894
2895 err = hpi_adapter_get_property(ss, asihpi->adapter_index,
2896 HPI_ADAPTER_PROPERTY_CURCHANNELS,
2897 &asihpi->in_max_chans, &asihpi->out_max_chans);
2898 if (err) {
2899 asihpi->in_max_chans = 2;
2900 asihpi->out_max_chans = 2;
2901 }
2902
2903 snd_printk(KERN_INFO "supports mmap:%d grouping:%d mrx:%d\n",
2904 asihpi->support_mmap,
2905 asihpi->support_grouping,
2906 asihpi->support_mrx
2907 );
2908
2909
2910 err = snd_card_asihpi_pcm_new(asihpi, 0, pcm_substreams);
2911 if (err < 0) {
2912 snd_printk(KERN_ERR "pcm_new failed\n");
2913 goto __nodev;
2914 }
2915 err = snd_card_asihpi_mixer_new(asihpi);
2916 if (err < 0) {
2917 snd_printk(KERN_ERR "mixer_new failed\n");
2918 goto __nodev;
2919 }
2920
2921 err = hpi_mixer_get_control(ss, asihpi->h_mixer,
2922 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
2923 HPI_CONTROL_SAMPLECLOCK, &h_control);
2924
2925 if (!err)
2926 err = hpi_sample_clock_set_local_rate(
2927 ss, h_control, adapter_fs);
2928
2929 snd_asihpi_proc_init(asihpi);
2930
2931 /* always create, can be enabled or disabled dynamically
2932 by enable_hwdep module param*/
2933 snd_asihpi_hpi_new(asihpi, 0, NULL);
2934
2935 if (asihpi->support_mmap)
2936 strcpy(card->driver, "ASIHPI-MMAP");
2937 else
2938 strcpy(card->driver, "ASIHPI");
2939
2940 sprintf(card->shortname, "AudioScience ASI%4X", asihpi->type);
2941 sprintf(card->longname, "%s %i",
2942 card->shortname, asihpi->adapter_index);
2943 err = snd_card_register(card);
2944 if (!err) {
2945 hpi_card->snd_card_asihpi = card;
2946 dev++;
2947 return 0;
2948 }
2949__nodev:
2950 snd_card_free(card);
2951 snd_printk(KERN_ERR "snd_asihpi_probe error %d\n", err);
2952 return err;
2953
2954}
2955
2956static void __devexit snd_asihpi_remove(struct pci_dev *pci_dev)
2957{
2958 struct hpi_adapter *hpi_card = pci_get_drvdata(pci_dev);
2959
2960 snd_card_free(hpi_card->snd_card_asihpi);
2961 hpi_card->snd_card_asihpi = NULL;
2962 asihpi_adapter_remove(pci_dev);
2963}
2964
2965static DEFINE_PCI_DEVICE_TABLE(asihpi_pci_tbl) = {
2966 {HPI_PCI_VENDOR_ID_TI, HPI_PCI_DEV_ID_DSP6205,
2967 HPI_PCI_VENDOR_ID_AUDIOSCIENCE, PCI_ANY_ID, 0, 0,
2968 (kernel_ulong_t)HPI_6205},
2969 {HPI_PCI_VENDOR_ID_TI, HPI_PCI_DEV_ID_PCI2040,
2970 HPI_PCI_VENDOR_ID_AUDIOSCIENCE, PCI_ANY_ID, 0, 0,
2971 (kernel_ulong_t)HPI_6000},
2972 {0,}
2973};
2974MODULE_DEVICE_TABLE(pci, asihpi_pci_tbl);
2975
2976static struct pci_driver driver = {
2977 .name = "asihpi",
2978 .id_table = asihpi_pci_tbl,
2979 .probe = snd_asihpi_probe,
2980 .remove = __devexit_p(snd_asihpi_remove),
2981#ifdef CONFIG_PM
2982/* .suspend = snd_asihpi_suspend,
2983 .resume = snd_asihpi_resume, */
2984#endif
2985};
2986
2987static int __init snd_asihpi_init(void)
2988{
2989 asihpi_init();
2990 return pci_register_driver(&driver);
2991}
2992
2993static void __exit snd_asihpi_exit(void)
2994{
2995
2996 pci_unregister_driver(&driver);
2997 asihpi_exit();
2998}
2999
3000module_init(snd_asihpi_init)
3001module_exit(snd_asihpi_exit)
3002
diff --git a/sound/pci/asihpi/hpi.h b/sound/pci/asihpi/hpi.h
new file mode 100644
index 000000000000..0173bbe62b67
--- /dev/null
+++ b/sound/pci/asihpi/hpi.h
@@ -0,0 +1,2007 @@
1/******************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
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, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19*/
20/** \file hpi.h
21
22 AudioScience Hardware Programming Interface (HPI)
23 public API definition.
24
25 The HPI is a low-level hardware abstraction layer to all
26 AudioScience digital audio adapters
27*/
28/*
29 You must define one operating system that the HPI is to be compiled under
30 HPI_OS_WIN32_USER 32bit Windows
31 HPI_OS_DSP_C6000 DSP TI C6000 (automatically set)
32 HPI_OS_WDM Windows WDM kernel driver
33 HPI_OS_LINUX Linux userspace
34 HPI_OS_LINUX_KERNEL Linux kernel (automatically set)
35
36(C) Copyright AudioScience Inc. 1998-2010
37******************************************************************************/
38#ifndef _HPI_H_
39#define _HPI_H_
40/* HPI Version
41If HPI_VER_MINOR is odd then its a development release not intended for the
42public. If HPI_VER_MINOR is even then is a release version
43i.e 3.05.02 is a development version
44*/
45#define HPI_VERSION_CONSTRUCTOR(maj, min, rel) \
46 ((maj << 16) + (min << 8) + rel)
47
48#define HPI_VER_MAJOR(v) ((int)(v >> 16))
49#define HPI_VER_MINOR(v) ((int)((v >> 8) & 0xFF))
50#define HPI_VER_RELEASE(v) ((int)(v & 0xFF))
51
52/* Use single digits for versions less that 10 to avoid octal. */
53#define HPI_VER HPI_VERSION_CONSTRUCTOR(4L, 3, 25)
54
55/* Library version as documented in hpi-api-versions.txt */
56#define HPI_LIB_VER HPI_VERSION_CONSTRUCTOR(9, 0, 0)
57
58#include <linux/types.h>
59#define HPI_EXCLUDE_DEPRECATED
60
61/******************************************************************************/
62/******************************************************************************/
63/******** HPI API DEFINITIONS *****/
64/******************************************************************************/
65/******************************************************************************/
66/*******************************************/
67/** Audio format types
68\ingroup stream
69*/
70enum HPI_FORMATS {
71/** Used internally on adapter. */
72 HPI_FORMAT_MIXER_NATIVE = 0,
73/** 8-bit unsigned PCM. Windows equivalent is WAVE_FORMAT_PCM. */
74 HPI_FORMAT_PCM8_UNSIGNED = 1,
75/** 16-bit signed PCM. Windows equivalent is WAVE_FORMAT_PCM. */
76 HPI_FORMAT_PCM16_SIGNED = 2,
77/** MPEG-1 Layer-1. */
78 HPI_FORMAT_MPEG_L1 = 3,
79/** MPEG-1 Layer-2.
80
81Windows equivalent is WAVE_FORMAT_MPEG.
82
83The following table shows what combinations of mode and bitrate are possible:
84
85<table border=1 cellspacing=0 cellpadding=5>
86<tr>
87<td><p><b>Bitrate (kbs)</b></p>
88<td><p><b>Mono</b></p>
89<td><p><b>Stereo,<br>Joint Stereo or<br>Dual Channel</b></p>
90
91<tr><td>32<td>X<td>_
92<tr><td>40<td>_<td>_
93<tr><td>48<td>X<td>_
94<tr><td>56<td>X<td>_
95<tr><td>64<td>X<td>X
96<tr><td>80<td>X<td>_
97<tr><td>96<td>X<td>X
98<tr><td>112<td>X<td>X
99<tr><td>128<td>X<td>X
100<tr><td>160<td>X<td>X
101<tr><td>192<td>X<td>X
102<tr><td>224<td>_<td>X
103<tr><td>256<td>-<td>X
104<tr><td>320<td>-<td>X
105<tr><td>384<td>_<td>X
106</table>
107*/
108 HPI_FORMAT_MPEG_L2 = 4,
109/** MPEG-1 Layer-3.
110Windows equivalent is WAVE_FORMAT_MPEG.
111
112The following table shows what combinations of mode and bitrate are possible:
113
114<table border=1 cellspacing=0 cellpadding=5>
115<tr>
116<td><p><b>Bitrate (kbs)</b></p>
117<td><p><b>Mono<br>Stereo @ 8,<br>11.025 and<br>12kHz*</b></p>
118<td><p><b>Mono<br>Stereo @ 16,<br>22.050 and<br>24kHz*</b></p>
119<td><p><b>Mono<br>Stereo @ 32,<br>44.1 and<br>48kHz</b></p>
120
121<tr><td>16<td>X<td>X<td>_
122<tr><td>24<td>X<td>X<td>_
123<tr><td>32<td>X<td>X<td>X
124<tr><td>40<td>X<td>X<td>X
125<tr><td>48<td>X<td>X<td>X
126<tr><td>56<td>X<td>X<td>X
127<tr><td>64<td>X<td>X<td>X
128<tr><td>80<td>_<td>X<td>X
129<tr><td>96<td>_<td>X<td>X
130<tr><td>112<td>_<td>X<td>X
131<tr><td>128<td>_<td>X<td>X
132<tr><td>144<td>_<td>X<td>_
133<tr><td>160<td>_<td>X<td>X
134<tr><td>192<td>_<td>_<td>X
135<tr><td>224<td>_<td>_<td>X
136<tr><td>256<td>-<td>_<td>X
137<tr><td>320<td>-<td>_<td>X
138</table>
139\b * Available on the ASI6000 series only
140*/
141 HPI_FORMAT_MPEG_L3 = 5,
142/** Dolby AC-2. */
143 HPI_FORMAT_DOLBY_AC2 = 6,
144/** Dolbt AC-3. */
145 HPI_FORMAT_DOLBY_AC3 = 7,
146/** 16-bit PCM big-endian. */
147 HPI_FORMAT_PCM16_BIGENDIAN = 8,
148/** TAGIT-1 algorithm - hits. */
149 HPI_FORMAT_AA_TAGIT1_HITS = 9,
150/** TAGIT-1 algorithm - inserts. */
151 HPI_FORMAT_AA_TAGIT1_INSERTS = 10,
152/** 32-bit signed PCM. Windows equivalent is WAVE_FORMAT_PCM.
153Each sample is a 32bit word. The most significant 24 bits contain a 24-bit
154sample and the least significant 8 bits are set to 0.
155*/
156 HPI_FORMAT_PCM32_SIGNED = 11,
157/** Raw bitstream - unknown format. */
158 HPI_FORMAT_RAW_BITSTREAM = 12,
159/** TAGIT-1 algorithm hits - extended. */
160 HPI_FORMAT_AA_TAGIT1_HITS_EX1 = 13,
161/** 32-bit PCM as an IEEE float. Windows equivalent is WAVE_FORMAT_IEEE_FLOAT.
162Each sample is a 32bit word in IEEE754 floating point format.
163The range is +1.0 to -1.0, which corresponds to digital fullscale.
164*/
165 HPI_FORMAT_PCM32_FLOAT = 14,
166/** 24-bit PCM signed. Windows equivalent is WAVE_FORMAT_PCM. */
167 HPI_FORMAT_PCM24_SIGNED = 15,
168/** OEM format 1 - private. */
169 HPI_FORMAT_OEM1 = 16,
170/** OEM format 2 - private. */
171 HPI_FORMAT_OEM2 = 17,
172/** Undefined format. */
173 HPI_FORMAT_UNDEFINED = 0xffff
174};
175
176/******************************************* in/out Stream states */
177/*******************************************/
178/** Stream States
179\ingroup stream
180*/
181enum HPI_STREAM_STATES {
182 /** State stopped - stream is stopped. */
183 HPI_STATE_STOPPED = 1,
184 /** State playing - stream is playing audio. */
185 HPI_STATE_PLAYING = 2,
186 /** State recording - stream is recording. */
187 HPI_STATE_RECORDING = 3,
188 /** State drained - playing stream ran out of data to play. */
189 HPI_STATE_DRAINED = 4,
190 /** State generate sine - to be implemented. */
191 HPI_STATE_SINEGEN = 5,
192 /** State wait - used for inter-card sync to mean waiting for all
193 cards to be ready. */
194 HPI_STATE_WAIT = 6
195};
196/******************************************* mixer source node types */
197/** Source node types
198\ingroup mixer
199*/
200enum HPI_SOURCENODES {
201 /** This define can be used instead of 0 to indicate
202 that there is no valid source node. A control that
203 exists on a destination node can be searched for using a source
204 node value of either 0, or HPI_SOURCENODE_NONE */
205 HPI_SOURCENODE_NONE = 100,
206 /** \deprecated Use HPI_SOURCENODE_NONE instead. */
207 HPI_SOURCENODE_BASE = 100,
208 /** Out Stream (Play) node. */
209 HPI_SOURCENODE_OSTREAM = 101,
210 /** Line in node - could be analog, AES/EBU or network. */
211 HPI_SOURCENODE_LINEIN = 102,
212 HPI_SOURCENODE_AESEBU_IN = 103, /**< AES/EBU input node. */
213 HPI_SOURCENODE_TUNER = 104, /**< tuner node. */
214 HPI_SOURCENODE_RF = 105, /**< RF input node. */
215 HPI_SOURCENODE_CLOCK_SOURCE = 106, /**< clock source node. */
216 HPI_SOURCENODE_RAW_BITSTREAM = 107, /**< raw bitstream node. */
217 HPI_SOURCENODE_MICROPHONE = 108, /**< microphone node. */
218 /** Cobranet input node -
219 Audio samples come from the Cobranet network and into the device. */
220 HPI_SOURCENODE_COBRANET = 109,
221 HPI_SOURCENODE_ANALOG = 110, /**< analog input node. */
222 HPI_SOURCENODE_ADAPTER = 111, /**< adapter node. */
223 /* !!!Update this AND hpidebug.h if you add a new sourcenode type!!! */
224 HPI_SOURCENODE_LAST_INDEX = 111 /**< largest ID */
225 /* AX6 max sourcenode types = 15 */
226};
227
228/******************************************* mixer dest node types */
229/** Destination node types
230\ingroup mixer
231*/
232enum HPI_DESTNODES {
233 /** This define can be used instead of 0 to indicate
234 that there is no valid destination node. A control that
235 exists on a source node can be searched for using a destination
236 node value of either 0, or HPI_DESTNODE_NONE */
237 HPI_DESTNODE_NONE = 200,
238 /** \deprecated Use HPI_DESTNODE_NONE instead. */
239 HPI_DESTNODE_BASE = 200,
240 /** In Stream (Record) node. */
241 HPI_DESTNODE_ISTREAM = 201,
242 HPI_DESTNODE_LINEOUT = 202, /**< line out node. */
243 HPI_DESTNODE_AESEBU_OUT = 203, /**< AES/EBU output node. */
244 HPI_DESTNODE_RF = 204, /**< RF output node. */
245 HPI_DESTNODE_SPEAKER = 205, /**< speaker output node. */
246 /** Cobranet output node -
247 Audio samples from the device are sent out on the Cobranet network.*/
248 HPI_DESTNODE_COBRANET = 206,
249 HPI_DESTNODE_ANALOG = 207, /**< analog output node. */
250
251 /* !!!Update this AND hpidebug.h if you add a new destnode type!!! */
252 HPI_DESTNODE_LAST_INDEX = 207 /**< largest ID */
253 /* AX6 max destnode types = 15 */
254};
255
256/*******************************************/
257/** Mixer control types
258\ingroup mixer
259*/
260enum HPI_CONTROLS {
261 HPI_CONTROL_GENERIC = 0, /**< generic control. */
262 HPI_CONTROL_CONNECTION = 1, /**< A connection between nodes. */
263 HPI_CONTROL_VOLUME = 2, /**< volume control - works in dB_fs. */
264 HPI_CONTROL_METER = 3, /**< peak meter control. */
265 HPI_CONTROL_MUTE = 4, /*mute control - not used at present. */
266 HPI_CONTROL_MULTIPLEXER = 5, /**< multiplexer control. */
267
268 HPI_CONTROL_AESEBU_TRANSMITTER = 6, /**< AES/EBU transmitter control. */
269 HPI_CONTROL_AESEBUTX = HPI_CONTROL_AESEBU_TRANSMITTER,
270
271 HPI_CONTROL_AESEBU_RECEIVER = 7, /**< AES/EBU receiver control. */
272 HPI_CONTROL_AESEBURX = HPI_CONTROL_AESEBU_RECEIVER,
273
274 HPI_CONTROL_LEVEL = 8, /**< level/trim control - works in d_bu. */
275 HPI_CONTROL_TUNER = 9, /**< tuner control. */
276/* HPI_CONTROL_ONOFFSWITCH = 10 */
277 HPI_CONTROL_VOX = 11, /**< vox control. */
278/* HPI_CONTROL_AES18_TRANSMITTER = 12 */
279/* HPI_CONTROL_AES18_RECEIVER = 13 */
280/* HPI_CONTROL_AES18_BLOCKGENERATOR = 14 */
281 HPI_CONTROL_CHANNEL_MODE = 15, /**< channel mode control. */
282
283 HPI_CONTROL_BITSTREAM = 16, /**< bitstream control. */
284 HPI_CONTROL_SAMPLECLOCK = 17, /**< sample clock control. */
285 HPI_CONTROL_MICROPHONE = 18, /**< microphone control. */
286 HPI_CONTROL_PARAMETRIC_EQ = 19, /**< parametric EQ control. */
287 HPI_CONTROL_EQUALIZER = HPI_CONTROL_PARAMETRIC_EQ,
288
289 HPI_CONTROL_COMPANDER = 20, /**< compander control. */
290 HPI_CONTROL_COBRANET = 21, /**< cobranet control. */
291 HPI_CONTROL_TONEDETECTOR = 22, /**< tone detector control. */
292 HPI_CONTROL_SILENCEDETECTOR = 23, /**< silence detector control. */
293 HPI_CONTROL_PAD = 24, /**< tuner PAD control. */
294 HPI_CONTROL_SRC = 25, /**< samplerate converter control. */
295 HPI_CONTROL_UNIVERSAL = 26, /**< universal control. */
296
297/* !!! Update this AND hpidebug.h if you add a new control type!!!*/
298 HPI_CONTROL_LAST_INDEX = 26 /**<highest control type ID */
299/* WARNING types 256 or greater impact bit packing in all AX6 DSP code */
300};
301
302/* Shorthand names that match attribute names */
303
304/******************************************* ADAPTER ATTRIBUTES ****/
305
306/** Adapter properties
307These are used in HPI_AdapterSetProperty() and HPI_AdapterGetProperty()
308\ingroup adapter
309*/
310enum HPI_ADAPTER_PROPERTIES {
311/** \internal Used in dwProperty field of HPI_AdapterSetProperty() and
312HPI_AdapterGetProperty(). This errata applies to all ASI6000 cards with both
313analog and digital outputs. The CS4224 A/D+D/A has a one sample delay between
314left and right channels on both its input (ADC) and output (DAC).
315More details are available in Cirrus Logic errata ER284B2.
316PDF available from www.cirrus.com, released by Cirrus in 2001.
317*/
318 HPI_ADAPTER_PROPERTY_ERRATA_1 = 1,
319
320/** Adapter grouping property
321Indicates whether the adapter supports the grouping API (for ASIO and SSX2)
322*/
323 HPI_ADAPTER_PROPERTY_GROUPING = 2,
324
325/** Driver SSX2 property
326Tells the kernel driver to turn on SSX2 stream mapping.
327This feature is not used by the DSP. In fact the call is completely processed
328by the driver and is not passed on to the DSP at all.
329*/
330 HPI_ADAPTER_PROPERTY_ENABLE_SSX2 = 3,
331
332/** Adapter SSX2 property
333Indicates the state of the adapter's SSX2 setting. This setting is stored in
334non-volatile memory on the adapter. A typical call sequence would be to use
335HPI_ADAPTER_PROPERTY_SSX2_SETTING to set SSX2 on the adapter and then to reload
336the driver. The driver would query HPI_ADAPTER_PROPERTY_SSX2_SETTING during startup
337and if SSX2 is set, it would then call HPI_ADAPTER_PROPERTY_ENABLE_SSX2 to enable
338SSX2 stream mapping within the kernel level of the driver.
339*/
340 HPI_ADAPTER_PROPERTY_SSX2_SETTING = 4,
341
342/** Base number for readonly properties */
343 HPI_ADAPTER_PROPERTY_READONLYBASE = 256,
344
345/** Readonly adapter latency property.
346This property returns in the input and output latency in samples.
347Property 1 is the estimated input latency
348in samples, while Property 2 is that output latency in samples.
349*/
350 HPI_ADAPTER_PROPERTY_LATENCY = 256,
351
352/** Readonly adapter granularity property.
353The granulariy is the smallest size chunk of stereo samples that is processed by
354the adapter.
355This property returns the record granularity in samples in Property 1.
356Property 2 returns the play granularity.
357*/
358 HPI_ADAPTER_PROPERTY_GRANULARITY = 257,
359
360/** Readonly adapter number of current channels property.
361Property 1 is the number of record channels per record device.
362Property 2 is the number of play channels per playback device.*/
363 HPI_ADAPTER_PROPERTY_CURCHANNELS = 258,
364
365/** Readonly adapter software version.
366The SOFTWARE_VERSION property returns the version of the software running
367on the adapter as Major.Minor.Release.
368Property 1 contains Major in bits 15..8 and Minor in bits 7..0.
369Property 2 contains Release in bits 7..0. */
370 HPI_ADAPTER_PROPERTY_SOFTWARE_VERSION = 259,
371
372/** Readonly adapter MAC address MSBs.
373The MAC_ADDRESS_MSB property returns
374the most significant 32 bits of the MAC address.
375Property 1 contains bits 47..32 of the MAC address.
376Property 2 contains bits 31..16 of the MAC address. */
377 HPI_ADAPTER_PROPERTY_MAC_ADDRESS_MSB = 260,
378
379/** Readonly adapter MAC address LSBs
380The MAC_ADDRESS_LSB property returns
381the least significant 16 bits of the MAC address.
382Property 1 contains bits 15..0 of the MAC address. */
383 HPI_ADAPTER_PROPERTY_MAC_ADDRESS_LSB = 261,
384
385/** Readonly extended adapter type number
386The EXTENDED_ADAPTER_TYPE property returns the 4 digits of an extended
387adapter type, i.e ASI8920-0022, 0022 is the extended type.
388The digits are returned as ASCII characters rather than the hex digits that
389are returned for the main type
390Property 1 returns the 1st two (left most) digits, i.e "00"
391in the example above, the upper byte being the left most digit.
392Property 2 returns the 2nd two digits, i.e "22" in the example above*/
393 HPI_ADAPTER_PROPERTY_EXTENDED_ADAPTER_TYPE = 262,
394
395/** Readonly debug log buffer information */
396 HPI_ADAPTER_PROPERTY_LOGTABLEN = 263,
397 HPI_ADAPTER_PROPERTY_LOGTABBEG = 264,
398
399/** Readonly adapter IP address
400For 192.168.1.101
401Property 1 returns the 1st two (left most) digits, i.e 192*256 + 168
402in the example above, the upper byte being the left most digit.
403Property 2 returns the 2nd two digits, i.e 1*256 + 101 in the example above, */
404 HPI_ADAPTER_PROPERTY_IP_ADDRESS = 265,
405
406/** Readonly adapter buffer processed count. Returns a buffer processed count
407that is incremented every time all buffers for all streams are updated. This
408is useful for checking completion of all stream operations across the adapter
409when using grouped streams.
410*/
411 HPI_ADAPTER_PROPERTY_BUFFER_UPDATE_COUNT = 266,
412
413/** Readonly mixer and stream intervals
414
415These intervals are measured in mixer frames.
416To convert to time, divide by the adapter samplerate.
417
418The mixer interval is the number of frames processed in one mixer iteration.
419The stream update interval is the interval at which streams check for and
420process data, and BBM host buffer counters are updated.
421
422Property 1 is the mixer interval in mixer frames.
423Property 2 is the stream update interval in mixer frames.
424*/
425 HPI_ADAPTER_PROPERTY_INTERVAL = 267,
426/** Adapter capabilities 1
427Property 1 - adapter can do multichannel (SSX1)
428Property 2 - adapter can do stream grouping (supports SSX2)
429*/
430 HPI_ADAPTER_PROPERTY_CAPS1 = 268,
431/** Adapter capabilities 2
432Property 1 - adapter can do samplerate conversion (MRX)
433Property 2 - adapter can do timestretch (TSX)
434*/
435 HPI_ADAPTER_PROPERTY_CAPS2 = 269
436};
437
438/** Adapter mode commands
439
440Used in wQueryOrSet field of HPI_AdapterSetModeEx().
441\ingroup adapter
442*/
443enum HPI_ADAPTER_MODE_CMDS {
444 HPI_ADAPTER_MODE_SET = 0,
445 HPI_ADAPTER_MODE_QUERY = 1
446};
447
448/** Adapter Modes
449 These are used by HPI_AdapterSetModeEx()
450
451\warning - more than 16 possible modes breaks
452a bitmask in the Windows WAVE DLL
453\ingroup adapter
454*/
455enum HPI_ADAPTER_MODES {
456/** 4 outstream mode.
457- ASI6114: 1 instream
458- ASI6044: 4 instreams
459- ASI6012: 1 instream
460- ASI6102: no instreams
461- ASI6022, ASI6122: 2 instreams
462- ASI5111, ASI5101: 2 instreams
463- ASI652x, ASI662x: 2 instreams
464- ASI654x, ASI664x: 4 instreams
465*/
466 HPI_ADAPTER_MODE_4OSTREAM = 1,
467
468/** 6 outstream mode.
469- ASI6012: 1 instream,
470- ASI6022, ASI6122: 2 instreams
471- ASI652x, ASI662x: 4 instreams
472*/
473 HPI_ADAPTER_MODE_6OSTREAM = 2,
474
475/** 8 outstream mode.
476- ASI6114: 8 instreams
477- ASI6118: 8 instreams
478- ASI6585: 8 instreams
479*/
480 HPI_ADAPTER_MODE_8OSTREAM = 3,
481
482/** 16 outstream mode.
483- ASI6416 16 instreams
484- ASI6518, ASI6618 16 instreams
485- ASI6118 16 mono out and in streams
486*/
487 HPI_ADAPTER_MODE_16OSTREAM = 4,
488
489/** one outstream mode.
490- ASI5111 1 outstream, 1 instream
491*/
492 HPI_ADAPTER_MODE_1OSTREAM = 5,
493
494/** ASI504X mode 1. 12 outstream, 4 instream 0 to 48kHz sample rates
495 (see ASI504X datasheet for more info).
496*/
497 HPI_ADAPTER_MODE_1 = 6,
498
499/** ASI504X mode 2. 4 outstreams, 4 instreams at 0 to 192kHz sample rates
500 (see ASI504X datasheet for more info).
501*/
502 HPI_ADAPTER_MODE_2 = 7,
503
504/** ASI504X mode 3. 4 outstreams, 4 instreams at 0 to 192kHz sample rates
505 (see ASI504X datasheet for more info).
506*/
507 HPI_ADAPTER_MODE_3 = 8,
508
509/** ASI504X multichannel mode.
510 2 outstreams -> 4 line outs = 1 to 8 channel streams),
511 4 lineins -> 1 instream (1 to 8 channel streams) at 0-48kHz.
512 For more info see the SSX Specification.
513*/
514 HPI_ADAPTER_MODE_MULTICHANNEL = 9,
515
516/** 12 outstream mode.
517- ASI6514, ASI6614: 2 instreams
518- ASI6540,ASI6544: 8 instreams
519- ASI6640,ASI6644: 8 instreams
520*/
521 HPI_ADAPTER_MODE_12OSTREAM = 10,
522
523/** 9 outstream mode.
524- ASI6044: 8 instreams
525*/
526 HPI_ADAPTER_MODE_9OSTREAM = 11,
527
528/** mono mode.
529- ASI6416: 16 outstreams/instreams
530- ASI5402: 2 outstreams/instreams
531*/
532 HPI_ADAPTER_MODE_MONO = 12,
533
534/** Low latency mode.
535- ASI6416/ASI6316: 1 16 channel outstream and instream
536*/
537 HPI_ADAPTER_MODE_LOW_LATENCY = 13
538};
539
540/* Note, adapters can have more than one capability -
541encoding as bitfield is recommended. */
542#define HPI_CAPABILITY_NONE (0)
543#define HPI_CAPABILITY_MPEG_LAYER3 (1)
544
545/* Set this equal to maximum capability index,
546Must not be greater than 32 - see axnvdef.h */
547#define HPI_CAPABILITY_MAX 1
548/* #define HPI_CAPABILITY_AAC 2 */
549
550/******************************************* STREAM ATTRIBUTES ****/
551
552/** MPEG Ancillary Data modes
553
554The mode for the ancillary data insertion or extraction to operate in.
555\ingroup stream
556*/
557enum HPI_MPEG_ANC_MODES {
558 /** the MPEG frames have energy information stored in them (5 bytes per stereo frame, 3 per mono) */
559 HPI_MPEG_ANC_HASENERGY = 0,
560 /** the entire ancillary data field is taken up by data from the Anc data buffer
561 On encode, the encoder will insert the energy bytes before filling the remainder
562 of the ancillary data space with data from the ancillary data buffer.
563 */
564 HPI_MPEG_ANC_RAW = 1
565};
566
567/** Ancillary Data Alignment
568\ingroup instream
569*/
570enum HPI_ISTREAM_MPEG_ANC_ALIGNS {
571 /** data is packed against the end of data, then padded to the end of frame */
572 HPI_MPEG_ANC_ALIGN_LEFT = 0,
573 /** data is packed against the end of the frame */
574 HPI_MPEG_ANC_ALIGN_RIGHT = 1
575};
576
577/** MPEG modes
578MPEG modes - can be used optionally for HPI_FormatCreate()
579parameter dwAttributes.
580
581Using any mode setting other than HPI_MPEG_MODE_DEFAULT
582with single channel format will return an error.
583\ingroup stream
584*/
585enum HPI_MPEG_MODES {
586/** Causes the MPEG-1 Layer II bitstream to be recorded
587in single_channel mode when the number of channels is 1 and in stereo when the
588number of channels is 2. */
589 HPI_MPEG_MODE_DEFAULT = 0,
590 /** Standard stereo without joint-stereo compression */
591 HPI_MPEG_MODE_STEREO = 1,
592 /** Joint stereo */
593 HPI_MPEG_MODE_JOINTSTEREO = 2,
594 /** Left and Right channels are completely independent */
595 HPI_MPEG_MODE_DUALCHANNEL = 3
596};
597/******************************************* MIXER ATTRIBUTES ****/
598
599/* \defgroup mixer_flags Mixer flags for HPI_MIXER_GET_CONTROL_MULTIPLE_VALUES
600{
601*/
602#define HPI_MIXER_GET_CONTROL_MULTIPLE_CHANGED (0)
603#define HPI_MIXER_GET_CONTROL_MULTIPLE_RESET (1)
604/*}*/
605
606/** Commands used by HPI_MixerStore()
607\ingroup mixer
608*/
609enum HPI_MIXER_STORE_COMMAND {
610/** Save all mixer control settings. */
611 HPI_MIXER_STORE_SAVE = 1,
612/** Restore all controls from saved. */
613 HPI_MIXER_STORE_RESTORE = 2,
614/** Delete saved control settings. */
615 HPI_MIXER_STORE_DELETE = 3,
616/** Enable auto storage of some control settings. */
617 HPI_MIXER_STORE_ENABLE = 4,
618/** Disable auto storage of some control settings. */
619 HPI_MIXER_STORE_DISABLE = 5,
620/** Save the attributes of a single control. */
621 HPI_MIXER_STORE_SAVE_SINGLE = 6
622};
623
624/************************************* CONTROL ATTRIBUTE VALUES ****/
625/** Used by mixer plugin enable functions
626
627E.g. HPI_ParametricEQ_SetState()
628\ingroup mixer
629*/
630enum HPI_SWITCH_STATES {
631 HPI_SWITCH_OFF = 0, /**< turn the mixer plugin on. */
632 HPI_SWITCH_ON = 1 /**< turn the mixer plugin off. */
633};
634
635/* Volume control special gain values */
636/** volumes units are 100ths of a dB
637\ingroup volume
638*/
639#define HPI_UNITS_PER_dB 100
640/** turns volume control OFF or MUTE
641\ingroup volume
642*/
643#define HPI_GAIN_OFF (-100 * HPI_UNITS_PER_dB)
644
645/** value returned for no signal
646\ingroup meter
647*/
648#define HPI_METER_MINIMUM (-150 * HPI_UNITS_PER_dB)
649
650/** autofade profiles
651\ingroup volume
652*/
653enum HPI_VOLUME_AUTOFADES {
654/** log fade - dB attenuation changes linearly over time */
655 HPI_VOLUME_AUTOFADE_LOG = 2,
656/** linear fade - amplitude changes linearly */
657 HPI_VOLUME_AUTOFADE_LINEAR = 3
658};
659
660/** The physical encoding format of the AESEBU I/O.
661
662Used in HPI_AESEBU_Transmitter_SetFormat(), HPI_AESEBU_Receiver_SetFormat()
663along with related Get and Query functions
664\ingroup aestx
665*/
666enum HPI_AESEBU_FORMATS {
667/** AES/EBU physical format - AES/EBU balanced "professional" */
668 HPI_AESEBU_FORMAT_AESEBU = 1,
669/** AES/EBU physical format - S/PDIF unbalanced "consumer" */
670 HPI_AESEBU_FORMAT_SPDIF = 2
671};
672
673/** AES/EBU error status bits
674
675Returned by HPI_AESEBU_Receiver_GetErrorStatus()
676\ingroup aesrx
677*/
678enum HPI_AESEBU_ERRORS {
679/** bit0: 1 when PLL is not locked */
680 HPI_AESEBU_ERROR_NOT_LOCKED = 0x01,
681/** bit1: 1 when signal quality is poor */
682 HPI_AESEBU_ERROR_POOR_QUALITY = 0x02,
683/** bit2: 1 when there is a parity error */
684 HPI_AESEBU_ERROR_PARITY_ERROR = 0x04,
685/** bit3: 1 when there is a bi-phase coding violation */
686 HPI_AESEBU_ERROR_BIPHASE_VIOLATION = 0x08,
687/** bit4: 1 when the validity bit is high */
688 HPI_AESEBU_ERROR_VALIDITY = 0x10,
689/** bit5: 1 when the CRC error bit is high */
690 HPI_AESEBU_ERROR_CRC = 0x20
691};
692
693/** \addtogroup pad
694\{
695*/
696/** The text string containing the station/channel combination. */
697#define HPI_PAD_CHANNEL_NAME_LEN 16
698/** The text string containing the artist. */
699#define HPI_PAD_ARTIST_LEN 64
700/** The text string containing the title. */
701#define HPI_PAD_TITLE_LEN 64
702/** The text string containing the comment. */
703#define HPI_PAD_COMMENT_LEN 256
704/** The PTY when the tuner has not recieved any PTY. */
705#define HPI_PAD_PROGRAM_TYPE_INVALID 0xffff
706/** \} */
707
708/** Data types for PTY string translation.
709\ingroup rds
710*/
711enum eHPI_RDS_type {
712 HPI_RDS_DATATYPE_RDS = 0, /**< RDS bitstream.*/
713 HPI_RDS_DATATYPE_RBDS = 1 /**< RBDS bitstream.*/
714};
715
716/** Tuner bands
717
718Used for HPI_Tuner_SetBand(),HPI_Tuner_GetBand()
719\ingroup tuner
720*/
721enum HPI_TUNER_BAND {
722 HPI_TUNER_BAND_AM = 1, /**< AM band */
723 HPI_TUNER_BAND_FM = 2, /**< FM band (mono) */
724 HPI_TUNER_BAND_TV_NTSC_M = 3, /**< NTSC-M TV band*/
725 HPI_TUNER_BAND_TV = 3, /* use TV_NTSC_M */
726 HPI_TUNER_BAND_FM_STEREO = 4, /**< FM band (stereo) */
727 HPI_TUNER_BAND_AUX = 5, /**< auxiliary input */
728 HPI_TUNER_BAND_TV_PAL_BG = 6, /**< PAL-B/G TV band*/
729 HPI_TUNER_BAND_TV_PAL_I = 7, /**< PAL-I TV band*/
730 HPI_TUNER_BAND_TV_PAL_DK = 8, /**< PAL-D/K TV band*/
731 HPI_TUNER_BAND_TV_SECAM_L = 9, /**< SECAM-L TV band*/
732 HPI_TUNER_BAND_LAST = 9 /**< the index of the last tuner band. */
733};
734
735/** Tuner mode attributes
736
737Used by HPI_Tuner_SetMode(), HPI_Tuner_GetMode()
738\ingroup tuner
739
740*/
741enum HPI_TUNER_MODES {
742 HPI_TUNER_MODE_RSS = 1, /**< control RSS */
743 HPI_TUNER_MODE_RDS = 2 /**< control RBDS/RDS */
744};
745
746/** Tuner mode attribute values
747
748Used by HPI_Tuner_SetMode(), HPI_Tuner_GetMode()
749\ingroup tuner
750*/
751enum HPI_TUNER_MODE_VALUES {
752/* RSS attribute values */
753 HPI_TUNER_MODE_RSS_DISABLE = 0, /**< RSS disable */
754 HPI_TUNER_MODE_RSS_ENABLE = 1, /**< RSS enable */
755
756/* RDS mode attributes */
757 HPI_TUNER_MODE_RDS_DISABLE = 0, /**< RDS - disabled */
758 HPI_TUNER_MODE_RDS_RDS = 1, /**< RDS - RDS mode */
759 HPI_TUNER_MODE_RDS_RBDS = 2 /**< RDS - RBDS mode */
760};
761
762/** Tuner Level settings
763\ingroup tuner
764*/
765enum HPI_TUNER_LEVEL {
766 HPI_TUNER_LEVEL_AVERAGE = 0,
767 HPI_TUNER_LEVEL_RAW = 1
768};
769
770/** Tuner Status Bits
771
772These bitfield values are returned by a call to HPI_Tuner_GetStatus().
773Multiple fields are returned from a single call.
774\ingroup tuner
775*/
776enum HPI_TUNER_STATUS_BITS {
777 HPI_TUNER_VIDEO_COLOR_PRESENT = 0x0001, /**< video color is present. */
778 HPI_TUNER_VIDEO_IS_60HZ = 0x0020, /**< 60 hz video detected. */
779 HPI_TUNER_VIDEO_HORZ_SYNC_MISSING = 0x0040, /**< video HSYNC is missing. */
780 HPI_TUNER_VIDEO_STATUS_VALID = 0x0100, /**< video status is valid. */
781 HPI_TUNER_PLL_LOCKED = 0x1000, /**< the tuner's PLL is locked. */
782 HPI_TUNER_FM_STEREO = 0x2000, /**< tuner reports back FM stereo. */
783 HPI_TUNER_DIGITAL = 0x0200, /**< tuner reports digital programming. */
784 HPI_TUNER_MULTIPROGRAM = 0x0400 /**< tuner reports multiple programs. */
785};
786
787/** Channel Modes
788Used for HPI_ChannelModeSet/Get()
789\ingroup channelmode
790*/
791enum HPI_CHANNEL_MODES {
792/** Left channel out = left channel in, Right channel out = right channel in. */
793 HPI_CHANNEL_MODE_NORMAL = 1,
794/** Left channel out = right channel in, Right channel out = left channel in. */
795 HPI_CHANNEL_MODE_SWAP = 2,
796/** Left channel out = left channel in, Right channel out = left channel in. */
797 HPI_CHANNEL_MODE_LEFT_TO_STEREO = 3,
798/** Left channel out = right channel in, Right channel out = right channel in.*/
799 HPI_CHANNEL_MODE_RIGHT_TO_STEREO = 4,
800/** Left channel out = (left channel in + right channel in)/2,
801 Right channel out = mute. */
802 HPI_CHANNEL_MODE_STEREO_TO_LEFT = 5,
803/** Left channel out = mute,
804 Right channel out = (right channel in + left channel in)/2. */
805 HPI_CHANNEL_MODE_STEREO_TO_RIGHT = 6,
806 HPI_CHANNEL_MODE_LAST = 6
807};
808
809/** SampleClock source values
810\ingroup sampleclock
811*/
812enum HPI_SAMPLECLOCK_SOURCES {
813/** The sampleclock output is derived from its local samplerate generator.
814 The local samplerate may be set using HPI_SampleClock_SetLocalRate(). */
815 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.*/
819 HPI_SAMPLECLOCK_SOURCE_AESEBU_SYNC = 2,
820/** From external wordclock connector */
821 HPI_SAMPLECLOCK_SOURCE_WORD = 3,
822/** Board-to-board header */
823 HPI_SAMPLECLOCK_SOURCE_WORD_HEADER = 4,
824/** FUTURE - SMPTE clock. */
825 HPI_SAMPLECLOCK_SOURCE_SMPTE = 5,
826/** One of the aesebu inputs */
827 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 */
833 HPI_SAMPLECLOCK_SOURCE_NETWORK = 8,
834/** From previous adjacent module (ASI2416 only)*/
835 HPI_SAMPLECLOCK_SOURCE_PREV_MODULE = 10,
836/*! Update this if you add a new clock source.*/
837 HPI_SAMPLECLOCK_SOURCE_LAST = 10
838};
839
840/** Equalizer filter types. Used by HPI_ParametricEQ_SetBand()
841\ingroup parmeq
842*/
843enum HPI_FILTER_TYPE {
844 HPI_FILTER_TYPE_BYPASS = 0, /**< filter is turned off */
845
846 HPI_FILTER_TYPE_LOWSHELF = 1, /**< EQ low shelf */
847 HPI_FILTER_TYPE_HIGHSHELF = 2, /**< EQ high shelf */
848 HPI_FILTER_TYPE_EQ_BAND = 3, /**< EQ gain */
849
850 HPI_FILTER_TYPE_LOWPASS = 4, /**< standard low pass */
851 HPI_FILTER_TYPE_HIGHPASS = 5, /**< standard high pass */
852 HPI_FILTER_TYPE_BANDPASS = 6, /**< standard band pass */
853 HPI_FILTER_TYPE_BANDSTOP = 7 /**< standard band stop/notch */
854};
855
856/** Async Event sources
857\ingroup async
858*/
859enum ASYNC_EVENT_SOURCES {
860 HPI_ASYNC_EVENT_GPIO = 1, /**< GPIO event. */
861 HPI_ASYNC_EVENT_SILENCE = 2, /**< silence event detected. */
862 HPI_ASYNC_EVENT_TONE = 3 /**< tone event detected. */
863};
864/*******************************************/
865/** HPI Error codes
866
867Almost all HPI functions return an error code
868A return value of zero means there was no error.
869Otherwise one of these error codes is returned.
870Error codes can be converted to a descriptive string using HPI_GetErrorText()
871
872\note When a new error code is added HPI_GetErrorText() MUST be updated.
873\note Codes 1-100 are reserved for driver use
874\ingroup utility
875*/
876enum HPI_ERROR_CODES {
877 /** Message type does not exist. */
878 HPI_ERROR_INVALID_TYPE = 100,
879 /** Object type does not exist. */
880 HPI_ERROR_INVALID_OBJ = 101,
881 /** Function does not exist. */
882 HPI_ERROR_INVALID_FUNC = 102,
883 /** The specified object (adapter/Stream) does not exist. */
884 HPI_ERROR_INVALID_OBJ_INDEX = 103,
885 /** Trying to access an object that has not been opened yet. */
886 HPI_ERROR_OBJ_NOT_OPEN = 104,
887 /** Trying to open an already open object. */
888 HPI_ERROR_OBJ_ALREADY_OPEN = 105,
889 /** PCI, ISA resource not valid. */
890 HPI_ERROR_INVALID_RESOURCE = 106,
891 /** GetInfo call from SubSysFindAdapters failed. */
892 HPI_ERROR_SUBSYSFINDADAPTERS_GETINFO = 107,
893 /** Default response was never updated with actual error code. */
894 HPI_ERROR_INVALID_RESPONSE = 108,
895 /** wSize field of response was not updated,
896 indicating that the message was not processed. */
897 HPI_ERROR_PROCESSING_MESSAGE = 109,
898 /** The network did not respond in a timely manner. */
899 HPI_ERROR_NETWORK_TIMEOUT = 110,
900 /** An HPI handle is invalid (uninitialised?). */
901 HPI_ERROR_INVALID_HANDLE = 111,
902 /** A function or attribute has not been implemented yet. */
903 HPI_ERROR_UNIMPLEMENTED = 112,
904 /** There are too many clients attempting to access a network resource. */
905 HPI_ERROR_NETWORK_TOO_MANY_CLIENTS = 113,
906 /** Response buffer passed to HPI_Message was smaller than returned response */
907 HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL = 114,
908 /** The returned response did not match the sent message */
909 HPI_ERROR_RESPONSE_MISMATCH = 115,
910
911 /** Too many adapters.*/
912 HPI_ERROR_TOO_MANY_ADAPTERS = 200,
913 /** Bad adpater. */
914 HPI_ERROR_BAD_ADAPTER = 201,
915 /** Adapter number out of range or not set properly. */
916 HPI_ERROR_BAD_ADAPTER_NUMBER = 202,
917 /** 2 adapters with the same adapter number. */
918 HPI_DUPLICATE_ADAPTER_NUMBER = 203,
919 /** DSP code failed to bootload. */
920 HPI_ERROR_DSP_BOOTLOAD = 204,
921 /** Adapter failed DSP code self test. */
922 HPI_ERROR_DSP_SELFTEST = 205,
923 /** Couldn't find or open the DSP code file. */
924 HPI_ERROR_DSP_FILE_NOT_FOUND = 206,
925 /** Internal DSP hardware error. */
926 HPI_ERROR_DSP_HARDWARE = 207,
927 /** Could not allocate memory in DOS. */
928 HPI_ERROR_DOS_MEMORY_ALLOC = 208,
929 /** Could not allocate memory */
930 HPI_ERROR_MEMORY_ALLOC = 208,
931 /** Failed to correctly load/config PLD .*/
932 HPI_ERROR_PLD_LOAD = 209,
933 /** Unexpected end of file, block length too big etc. */
934 HPI_ERROR_DSP_FILE_FORMAT = 210,
935
936 /** Found but could not open DSP code file. */
937 HPI_ERROR_DSP_FILE_ACCESS_DENIED = 211,
938 /** First DSP code section header not found in DSP file. */
939 HPI_ERROR_DSP_FILE_NO_HEADER = 212,
940 /** File read operation on DSP code file failed. */
941 HPI_ERROR_DSP_FILE_READ_ERROR = 213,
942 /** DSP code for adapter family not found. */
943 HPI_ERROR_DSP_SECTION_NOT_FOUND = 214,
944 /** Other OS specific error opening DSP file. */
945 HPI_ERROR_DSP_FILE_OTHER_ERROR = 215,
946 /** Sharing violation opening DSP code file. */
947 HPI_ERROR_DSP_FILE_SHARING_VIOLATION = 216,
948 /** DSP code section header had size == 0. */
949 HPI_ERROR_DSP_FILE_NULL_HEADER = 217,
950
951 /** Base number for flash errors. */
952 HPI_ERROR_FLASH = 220,
953
954 /** Flash has bad checksum */
955 HPI_ERROR_BAD_CHECKSUM = (HPI_ERROR_FLASH + 1),
956 HPI_ERROR_BAD_SEQUENCE = (HPI_ERROR_FLASH + 2),
957 HPI_ERROR_FLASH_ERASE = (HPI_ERROR_FLASH + 3),
958 HPI_ERROR_FLASH_PROGRAM = (HPI_ERROR_FLASH + 4),
959 HPI_ERROR_FLASH_VERIFY = (HPI_ERROR_FLASH + 5),
960 HPI_ERROR_FLASH_TYPE = (HPI_ERROR_FLASH + 6),
961 HPI_ERROR_FLASH_START = (HPI_ERROR_FLASH + 7),
962
963 /** Reserved for OEMs. */
964 HPI_ERROR_RESERVED_1 = 290,
965
966 /** Stream does not exist. */
967 HPI_ERROR_INVALID_STREAM = 300,
968 /** Invalid compression format. */
969 HPI_ERROR_INVALID_FORMAT = 301,
970 /** Invalid format samplerate */
971 HPI_ERROR_INVALID_SAMPLERATE = 302,
972 /** Invalid format number of channels. */
973 HPI_ERROR_INVALID_CHANNELS = 303,
974 /** Invalid format bitrate. */
975 HPI_ERROR_INVALID_BITRATE = 304,
976 /** Invalid datasize used for stream read/write. */
977 HPI_ERROR_INVALID_DATASIZE = 305,
978 /** Stream buffer is full during stream write. */
979 HPI_ERROR_BUFFER_FULL = 306,
980 /** Stream buffer is empty during stream read. */
981 HPI_ERROR_BUFFER_EMPTY = 307,
982 /** Invalid datasize used for stream read/write. */
983 HPI_ERROR_INVALID_DATA_TRANSFER = 308,
984 /** Packet ordering error for stream read/write. */
985 HPI_ERROR_INVALID_PACKET_ORDER = 309,
986
987 /** Object can't do requested operation in its current
988 state, eg set format, change rec mux state while recording.*/
989 HPI_ERROR_INVALID_OPERATION = 310,
990
991 /** Where an SRG is shared amongst streams, an incompatible samplerate is one
992 that is different to any currently playing or recording stream. */
993 HPI_ERROR_INCOMPATIBLE_SAMPLERATE = 311,
994 /** Adapter mode is illegal.*/
995 HPI_ERROR_BAD_ADAPTER_MODE = 312,
996
997 /** There have been too many attempts to set the adapter's
998 capabilities (using bad keys), the card should be returned
999 to ASI if further capabilities updates are required */
1000 HPI_ERROR_TOO_MANY_CAPABILITY_CHANGE_ATTEMPTS = 313,
1001 /** Streams on different adapters cannot be grouped. */
1002 HPI_ERROR_NO_INTERADAPTER_GROUPS = 314,
1003 /** Streams on different DSPs cannot be grouped. */
1004 HPI_ERROR_NO_INTERDSP_GROUPS = 315,
1005
1006 /** Invalid mixer node for this adapter. */
1007 HPI_ERROR_INVALID_NODE = 400,
1008 /** Invalid control. */
1009 HPI_ERROR_INVALID_CONTROL = 401,
1010 /** Invalid control value was passed. */
1011 HPI_ERROR_INVALID_CONTROL_VALUE = 402,
1012 /** Control attribute not supported by this control. */
1013 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE = 403,
1014 /** Control is disabled. */
1015 HPI_ERROR_CONTROL_DISABLED = 404,
1016 /** I2C transaction failed due to a missing ACK. */
1017 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
1021 reset and cannot be accessed at this time. */
1022 HPI_ERROR_CONTROL_NOT_READY = 407,
1023
1024 /** Non volatile memory */
1025 HPI_ERROR_NVMEM_BUSY = 450,
1026 HPI_ERROR_NVMEM_FULL = 451,
1027 HPI_ERROR_NVMEM_FAIL = 452,
1028
1029 /** I2C */
1030 HPI_ERROR_I2C_MISSING_ACK = HPI_ERROR_CONTROL_I2C_MISSING_ACK,
1031 HPI_ERROR_I2C_BAD_ADR = 460,
1032
1033 /** Entity errors */
1034 HPI_ERROR_ENTITY_TYPE_MISMATCH = 470,
1035 HPI_ERROR_ENTITY_ITEM_COUNT = 471,
1036 HPI_ERROR_ENTITY_TYPE_INVALID = 472,
1037 HPI_ERROR_ENTITY_ROLE_INVALID = 473,
1038
1039 /* AES18 specific errors were 500..507 */
1040
1041 /** custom error to use for debugging */
1042 HPI_ERROR_CUSTOM = 600,
1043
1044 /** hpioct32.c can't obtain mutex */
1045 HPI_ERROR_MUTEX_TIMEOUT = 700,
1046
1047 /** errors from HPI backends have values >= this */
1048 HPI_ERROR_BACKEND_BASE = 900,
1049
1050 /** indicates a cached u16 value is invalid. */
1051 HPI_ERROR_ILLEGAL_CACHE_VALUE = 0xffff
1052};
1053
1054/** \defgroup maximums HPI maximum values
1055\{
1056*/
1057/** Maximum number of adapters per HPI sub-system
1058 WARNING: modifying this value changes the response structure size.*/
1059#define HPI_MAX_ADAPTERS 20
1060/** Maximum number of in or out streams per adapter */
1061#define HPI_MAX_STREAMS 16
1062#define HPI_MAX_CHANNELS 2 /* per stream */
1063#define HPI_MAX_NODES 8 /* per mixer ? */
1064#define HPI_MAX_CONTROLS 4 /* per node ? */
1065/** maximum number of ancillary bytes per MPEG frame */
1066#define HPI_MAX_ANC_BYTES_PER_FRAME (64)
1067#define HPI_STRING_LEN 16
1068
1069/** Velocity units */
1070#define HPI_OSTREAM_VELOCITY_UNITS 4096
1071/** OutStream timescale units */
1072#define HPI_OSTREAM_TIMESCALE_UNITS 10000
1073/** OutStream timescale passthrough - turns timescaling on in passthough mode */
1074#define HPI_OSTREAM_TIMESCALE_PASSTHROUGH 99999
1075
1076/**\}*/
1077
1078/* ////////////////////////////////////////////////////////////////////// */
1079/* STRUCTURES */
1080#ifndef DISABLE_PRAGMA_PACK1
1081#pragma pack(push, 1)
1082#endif
1083
1084/** Structure containing sample format information.
1085 See also HPI_FormatCreate().
1086 */
1087struct hpi_format {
1088 u32 sample_rate;
1089 /**< 11025, 32000, 44100 ... */
1090 u32 bit_rate; /**< for MPEG */
1091 u32 attributes;
1092 /**< Stereo/JointStereo/Mono */
1093 u16 mode_legacy;
1094 /**< Legacy ancillary mode or idle bit */
1095 u16 unused; /**< unused */
1096 u16 channels; /**< 1,2..., (or ancillary mode or idle bit */
1097 u16 format; /**< HPI_FORMAT_PCM16, _MPEG etc. see #HPI_FORMATS. */
1098};
1099
1100struct hpi_anc_frame {
1101 u32 valid_bits_in_this_frame;
1102 u8 b_data[HPI_MAX_ANC_BYTES_PER_FRAME];
1103};
1104
1105/** An object for containing a single async event.
1106*/
1107struct hpi_async_event {
1108 u16 event_type; /**< type of event. \sa async_event */
1109 u16 sequence; /**< sequence number, allows lost event detection */
1110 u32 state; /**< new state */
1111 u32 h_object; /**< handle to the object returning the event. */
1112 union {
1113 struct {
1114 u16 index; /**< GPIO bit index. */
1115 } gpio;
1116 struct {
1117 u16 node_index; /**< what node is the control on ? */
1118 u16 node_type; /**< what type of node is the control on ? */
1119 } control;
1120 } u;
1121};
1122
1123/*/////////////////////////////////////////////////////////////////////////// */
1124/* Public HPI Entity related definitions */
1125
1126struct hpi_entity;
1127
1128enum e_entity_type {
1129 entity_type_null,
1130 entity_type_sequence, /* sequence of potentially heterogeneous TLV entities */
1131
1132 entity_type_reference, /* refers to a TLV entity or NULL */
1133
1134 entity_type_int, /* 32 bit */
1135 entity_type_float, /* ieee754 binary 32 bit encoding */
1136 entity_type_double,
1137
1138 entity_type_cstring,
1139 entity_type_octet,
1140 entity_type_ip4_address,
1141 entity_type_ip6_address,
1142 entity_type_mac_address,
1143
1144 LAST_ENTITY_TYPE
1145};
1146
1147enum e_entity_role {
1148 entity_role_null,
1149 entity_role_value,
1150 entity_role_classname,
1151
1152 entity_role_units,
1153 entity_role_flags,
1154 entity_role_range,
1155
1156 entity_role_mapping,
1157 entity_role_enum,
1158
1159 entity_role_instance_of,
1160 entity_role_depends_on,
1161 entity_role_member_of_group,
1162 entity_role_value_constraint,
1163 entity_role_parameter_port,
1164
1165 entity_role_block,
1166 entity_role_node_group,
1167 entity_role_audio_port,
1168 entity_role_clock_port,
1169 LAST_ENTITY_ROLE
1170};
1171
1172/* skip host side function declarations for
1173 DSP compile and documentation extraction */
1174
1175struct hpi_hsubsys {
1176 int not_really_used;
1177};
1178
1179#ifndef DISABLE_PRAGMA_PACK1
1180#pragma pack(pop)
1181#endif
1182
1183/*////////////////////////////////////////////////////////////////////////// */
1184/* HPI FUNCTIONS */
1185
1186/*/////////////////////////// */
1187/* DATA and FORMAT and STREAM */
1188
1189u16 hpi_stream_estimate_buffer_size(struct hpi_format *pF,
1190 u32 host_polling_rate_in_milli_seconds, u32 *recommended_buffer_size);
1191
1192/*/////////// */
1193/* SUB SYSTEM */
1194struct hpi_hsubsys *hpi_subsys_create(void
1195 );
1196
1197void hpi_subsys_free(const struct hpi_hsubsys *ph_subsys);
1198
1199u16 hpi_subsys_get_version(const struct hpi_hsubsys *ph_subsys,
1200 u32 *pversion);
1201
1202u16 hpi_subsys_get_version_ex(const struct hpi_hsubsys *ph_subsys,
1203 u32 *pversion_ex);
1204
1205u16 hpi_subsys_get_info(const struct hpi_hsubsys *ph_subsys, u32 *pversion,
1206 u16 *pw_num_adapters, u16 aw_adapter_list[], u16 list_length);
1207
1208u16 hpi_subsys_find_adapters(const struct hpi_hsubsys *ph_subsys,
1209 u16 *pw_num_adapters, u16 aw_adapter_list[], u16 list_length);
1210
1211u16 hpi_subsys_get_num_adapters(const struct hpi_hsubsys *ph_subsys,
1212 int *pn_num_adapters);
1213
1214u16 hpi_subsys_get_adapter(const struct hpi_hsubsys *ph_subsys, int iterator,
1215 u32 *padapter_index, u16 *pw_adapter_type);
1216
1217u16 hpi_subsys_ssx2_bypass(const struct hpi_hsubsys *ph_subsys, u16 bypass);
1218
1219u16 hpi_subsys_set_host_network_interface(const struct hpi_hsubsys *ph_subsys,
1220 const char *sz_interface);
1221
1222/*///////// */
1223/* ADAPTER */
1224
1225u16 hpi_adapter_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index);
1226
1227u16 hpi_adapter_close(const struct hpi_hsubsys *ph_subsys, u16 adapter_index);
1228
1229u16 hpi_adapter_get_info(const struct hpi_hsubsys *ph_subsys,
1230 u16 adapter_index, u16 *pw_num_outstreams, u16 *pw_num_instreams,
1231 u16 *pw_version, u32 *pserial_number, u16 *pw_adapter_type);
1232
1233u16 hpi_adapter_get_module_by_index(const struct hpi_hsubsys *ph_subsys,
1234 u16 adapter_index, u16 module_index, u16 *pw_num_outputs,
1235 u16 *pw_num_inputs, u16 *pw_version, u32 *pserial_number,
1236 u16 *pw_module_type, u32 *ph_module);
1237
1238u16 hpi_adapter_set_mode(const struct hpi_hsubsys *ph_subsys,
1239 u16 adapter_index, u32 adapter_mode);
1240
1241u16 hpi_adapter_set_mode_ex(const struct hpi_hsubsys *ph_subsys,
1242 u16 adapter_index, u32 adapter_mode, u16 query_or_set);
1243
1244u16 hpi_adapter_get_mode(const struct hpi_hsubsys *ph_subsys,
1245 u16 adapter_index, u32 *padapter_mode);
1246
1247u16 hpi_adapter_get_assert(const struct hpi_hsubsys *ph_subsys,
1248 u16 adapter_index, u16 *assert_present, char *psz_assert,
1249 u16 *pw_line_number);
1250
1251u16 hpi_adapter_get_assert_ex(const struct hpi_hsubsys *ph_subsys,
1252 u16 adapter_index, u16 *assert_present, char *psz_assert,
1253 u32 *pline_number, u16 *pw_assert_on_dsp);
1254
1255u16 hpi_adapter_test_assert(const struct hpi_hsubsys *ph_subsys,
1256 u16 adapter_index, u16 assert_id);
1257
1258u16 hpi_adapter_enable_capability(const struct hpi_hsubsys *ph_subsys,
1259 u16 adapter_index, u16 capability, u32 key);
1260
1261u16 hpi_adapter_self_test(const struct hpi_hsubsys *ph_subsys,
1262 u16 adapter_index);
1263
1264u16 hpi_adapter_debug_read(const struct hpi_hsubsys *ph_subsys,
1265 u16 adapter_index, u32 dsp_address, char *p_bytes, int *count_bytes);
1266
1267u16 hpi_adapter_set_property(const struct hpi_hsubsys *ph_subsys,
1268 u16 adapter_index, u16 property, u16 paramter1, u16 paramter2);
1269
1270u16 hpi_adapter_get_property(const struct hpi_hsubsys *ph_subsys,
1271 u16 adapter_index, u16 property, u16 *pw_paramter1,
1272 u16 *pw_paramter2);
1273
1274u16 hpi_adapter_enumerate_property(const struct hpi_hsubsys *ph_subsys,
1275 u16 adapter_index, u16 index, u16 what_to_enumerate,
1276 u16 property_index, u32 *psetting);
1277
1278/*////////////// */
1279/* NonVol Memory */
1280u16 hpi_nv_memory_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
1281 u32 *ph_nv_memory, u16 *pw_size_in_bytes);
1282
1283u16 hpi_nv_memory_read_byte(const struct hpi_hsubsys *ph_subsys,
1284 u32 h_nv_memory, u16 index, u16 *pw_data);
1285
1286u16 hpi_nv_memory_write_byte(const struct hpi_hsubsys *ph_subsys,
1287 u32 h_nv_memory, u16 index, u16 data);
1288
1289/*////////////// */
1290/* Digital I/O */
1291u16 hpi_gpio_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
1292 u32 *ph_gpio, u16 *pw_number_input_bits, u16 *pw_number_output_bits);
1293
1294u16 hpi_gpio_read_bit(const struct hpi_hsubsys *ph_subsys, u32 h_gpio,
1295 u16 bit_index, u16 *pw_bit_data);
1296
1297u16 hpi_gpio_read_all_bits(const struct hpi_hsubsys *ph_subsys, u32 h_gpio,
1298 u16 aw_all_bit_data[4]
1299 );
1300
1301u16 hpi_gpio_write_bit(const struct hpi_hsubsys *ph_subsys, u32 h_gpio,
1302 u16 bit_index, u16 bit_data);
1303
1304u16 hpi_gpio_write_status(const struct hpi_hsubsys *ph_subsys, u32 h_gpio,
1305 u16 aw_all_bit_data[4]
1306 );
1307
1308/**********************/
1309/* Async Event Object */
1310/**********************/
1311u16 hpi_async_event_open(const struct hpi_hsubsys *ph_subsys,
1312 u16 adapter_index, u32 *ph_async);
1313
1314u16 hpi_async_event_close(const struct hpi_hsubsys *ph_subsys, u32 h_async);
1315
1316u16 hpi_async_event_wait(const struct hpi_hsubsys *ph_subsys, u32 h_async,
1317 u16 maximum_events, struct hpi_async_event *p_events,
1318 u16 *pw_number_returned);
1319
1320u16 hpi_async_event_get_count(const struct hpi_hsubsys *ph_subsys,
1321 u32 h_async, u16 *pw_count);
1322
1323u16 hpi_async_event_get(const struct hpi_hsubsys *ph_subsys, u32 h_async,
1324 u16 maximum_events, struct hpi_async_event *p_events,
1325 u16 *pw_number_returned);
1326
1327/*/////////// */
1328/* WATCH-DOG */
1329u16 hpi_watchdog_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
1330 u32 *ph_watchdog);
1331
1332u16 hpi_watchdog_set_time(const struct hpi_hsubsys *ph_subsys, u32 h_watchdog,
1333 u32 time_millisec);
1334
1335u16 hpi_watchdog_ping(const struct hpi_hsubsys *ph_subsys, u32 h_watchdog);
1336
1337/**************/
1338/* OUT STREAM */
1339/**************/
1340u16 hpi_outstream_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
1341 u16 outstream_index, u32 *ph_outstream);
1342
1343u16 hpi_outstream_close(const struct hpi_hsubsys *ph_subsys, u32 h_outstream);
1344
1345u16 hpi_outstream_get_info_ex(const struct hpi_hsubsys *ph_subsys,
1346 u32 h_outstream, u16 *pw_state, u32 *pbuffer_size, u32 *pdata_to_play,
1347 u32 *psamples_played, u32 *pauxiliary_data_to_play);
1348
1349u16 hpi_outstream_write_buf(const struct hpi_hsubsys *ph_subsys,
1350 u32 h_outstream, const u8 *pb_write_buf, u32 bytes_to_write,
1351 const struct hpi_format *p_format);
1352
1353u16 hpi_outstream_start(const struct hpi_hsubsys *ph_subsys, u32 h_outstream);
1354
1355u16 hpi_outstream_wait_start(const struct hpi_hsubsys *ph_subsys,
1356 u32 h_outstream);
1357
1358u16 hpi_outstream_stop(const struct hpi_hsubsys *ph_subsys, u32 h_outstream);
1359
1360u16 hpi_outstream_sinegen(const struct hpi_hsubsys *ph_subsys,
1361 u32 h_outstream);
1362
1363u16 hpi_outstream_reset(const struct hpi_hsubsys *ph_subsys, u32 h_outstream);
1364
1365u16 hpi_outstream_query_format(const struct hpi_hsubsys *ph_subsys,
1366 u32 h_outstream, struct hpi_format *p_format);
1367
1368u16 hpi_outstream_set_format(const struct hpi_hsubsys *ph_subsys,
1369 u32 h_outstream, struct hpi_format *p_format);
1370
1371u16 hpi_outstream_set_punch_in_out(const struct hpi_hsubsys *ph_subsys,
1372 u32 h_outstream, u32 punch_in_sample, u32 punch_out_sample);
1373
1374u16 hpi_outstream_set_velocity(const struct hpi_hsubsys *ph_subsys,
1375 u32 h_outstream, short velocity);
1376
1377u16 hpi_outstream_ancillary_reset(const struct hpi_hsubsys *ph_subsys,
1378 u32 h_outstream, u16 mode);
1379
1380u16 hpi_outstream_ancillary_get_info(const struct hpi_hsubsys *ph_subsys,
1381 u32 h_outstream, u32 *pframes_available);
1382
1383u16 hpi_outstream_ancillary_read(const struct hpi_hsubsys *ph_subsys,
1384 u32 h_outstream, struct hpi_anc_frame *p_anc_frame_buffer,
1385 u32 anc_frame_buffer_size_in_bytes,
1386 u32 number_of_ancillary_frames_to_read);
1387
1388u16 hpi_outstream_set_time_scale(const struct hpi_hsubsys *ph_subsys,
1389 u32 h_outstream, u32 time_scaleX10000);
1390
1391u16 hpi_outstream_host_buffer_allocate(const struct hpi_hsubsys *ph_subsys,
1392 u32 h_outstream, u32 size_in_bytes);
1393
1394u16 hpi_outstream_host_buffer_free(const struct hpi_hsubsys *ph_subsys,
1395 u32 h_outstream);
1396
1397u16 hpi_outstream_group_add(const struct hpi_hsubsys *ph_subsys,
1398 u32 h_outstream, u32 h_stream);
1399
1400u16 hpi_outstream_group_get_map(const struct hpi_hsubsys *ph_subsys,
1401 u32 h_outstream, u32 *poutstream_map, u32 *pinstream_map);
1402
1403u16 hpi_outstream_group_reset(const struct hpi_hsubsys *ph_subsys,
1404 u32 h_outstream);
1405
1406/*////////// */
1407/* IN_STREAM */
1408u16 hpi_instream_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
1409 u16 instream_index, u32 *ph_instream);
1410
1411u16 hpi_instream_close(const struct hpi_hsubsys *ph_subsys, u32 h_instream);
1412
1413u16 hpi_instream_query_format(const struct hpi_hsubsys *ph_subsys,
1414 u32 h_instream, const struct hpi_format *p_format);
1415
1416u16 hpi_instream_set_format(const struct hpi_hsubsys *ph_subsys,
1417 u32 h_instream, const struct hpi_format *p_format);
1418
1419u16 hpi_instream_read_buf(const struct hpi_hsubsys *ph_subsys, u32 h_instream,
1420 u8 *pb_read_buf, u32 bytes_to_read);
1421
1422u16 hpi_instream_start(const struct hpi_hsubsys *ph_subsys, u32 h_instream);
1423
1424u16 hpi_instream_wait_start(const struct hpi_hsubsys *ph_subsys,
1425 u32 h_instream);
1426
1427u16 hpi_instream_stop(const struct hpi_hsubsys *ph_subsys, u32 h_instream);
1428
1429u16 hpi_instream_reset(const struct hpi_hsubsys *ph_subsys, u32 h_instream);
1430
1431u16 hpi_instream_get_info_ex(const struct hpi_hsubsys *ph_subsys,
1432 u32 h_instream, u16 *pw_state, u32 *pbuffer_size, u32 *pdata_recorded,
1433 u32 *psamples_recorded, u32 *pauxiliary_data_recorded);
1434
1435u16 hpi_instream_ancillary_reset(const struct hpi_hsubsys *ph_subsys,
1436 u32 h_instream, u16 bytes_per_frame, u16 mode, u16 alignment,
1437 u16 idle_bit);
1438
1439u16 hpi_instream_ancillary_get_info(const struct hpi_hsubsys *ph_subsys,
1440 u32 h_instream, u32 *pframe_space);
1441
1442u16 hpi_instream_ancillary_write(const struct hpi_hsubsys *ph_subsys,
1443 u32 h_instream, const struct hpi_anc_frame *p_anc_frame_buffer,
1444 u32 anc_frame_buffer_size_in_bytes,
1445 u32 number_of_ancillary_frames_to_write);
1446
1447u16 hpi_instream_host_buffer_allocate(const struct hpi_hsubsys *ph_subsys,
1448 u32 h_instream, u32 size_in_bytes);
1449
1450u16 hpi_instream_host_buffer_free(const struct hpi_hsubsys *ph_subsys,
1451 u32 h_instream);
1452
1453u16 hpi_instream_group_add(const struct hpi_hsubsys *ph_subsys,
1454 u32 h_instream, u32 h_stream);
1455
1456u16 hpi_instream_group_get_map(const struct hpi_hsubsys *ph_subsys,
1457 u32 h_instream, u32 *poutstream_map, u32 *pinstream_map);
1458
1459u16 hpi_instream_group_reset(const struct hpi_hsubsys *ph_subsys,
1460 u32 h_instream);
1461
1462/*********/
1463/* MIXER */
1464/*********/
1465u16 hpi_mixer_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
1466 u32 *ph_mixer);
1467
1468u16 hpi_mixer_close(const struct hpi_hsubsys *ph_subsys, u32 h_mixer);
1469
1470u16 hpi_mixer_get_control(const struct hpi_hsubsys *ph_subsys, u32 h_mixer,
1471 u16 src_node_type, u16 src_node_type_index, u16 dst_node_type,
1472 u16 dst_node_type_index, u16 control_type, u32 *ph_control);
1473
1474u16 hpi_mixer_get_control_by_index(const struct hpi_hsubsys *ph_subsys,
1475 u32 h_mixer, u16 control_index, u16 *pw_src_node_type,
1476 u16 *pw_src_node_index, u16 *pw_dst_node_type, u16 *pw_dst_node_index,
1477 u16 *pw_control_type, u32 *ph_control);
1478
1479u16 hpi_mixer_store(const struct hpi_hsubsys *ph_subsys, u32 h_mixer,
1480 enum HPI_MIXER_STORE_COMMAND command, u16 index);
1481/*************************/
1482/* mixer CONTROLS */
1483/*************************/
1484/*************************/
1485/* volume control */
1486/*************************/
1487u16 hpi_volume_set_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1488 short an_gain0_01dB[HPI_MAX_CHANNELS]
1489 );
1490
1491u16 hpi_volume_get_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1492 short an_gain0_01dB_out[HPI_MAX_CHANNELS]
1493 );
1494
1495#define hpi_volume_get_range hpi_volume_query_range
1496u16 hpi_volume_query_range(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1497 short *min_gain_01dB, short *max_gain_01dB, short *step_gain_01dB);
1498
1499u16 hpi_volume_query_channels(const struct hpi_hsubsys *ph_subsys,
1500 const u32 h_volume, u32 *p_channels);
1501
1502u16 hpi_volume_auto_fade(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1503 short an_stop_gain0_01dB[HPI_MAX_CHANNELS], u32 duration_ms);
1504
1505u16 hpi_volume_auto_fade_profile(const struct hpi_hsubsys *ph_subsys,
1506 u32 h_control, short an_stop_gain0_01dB[HPI_MAX_CHANNELS],
1507 u32 duration_ms, u16 profile);
1508
1509/*************************/
1510/* level control */
1511/*************************/
1512u16 hpi_level_query_range(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1513 short *min_gain_01dB, short *max_gain_01dB, short *step_gain_01dB);
1514
1515u16 hpi_level_set_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1516 short an_gain0_01dB[HPI_MAX_CHANNELS]
1517 );
1518
1519u16 hpi_level_get_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1520 short an_gain0_01dB_out[HPI_MAX_CHANNELS]
1521 );
1522
1523/*************************/
1524/* meter control */
1525/*************************/
1526u16 hpi_meter_query_channels(const struct hpi_hsubsys *ph_subsys,
1527 const u32 h_meter, u32 *p_channels);
1528
1529u16 hpi_meter_get_peak(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1530 short an_peak0_01dB_out[HPI_MAX_CHANNELS]
1531 );
1532
1533u16 hpi_meter_get_rms(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1534 short an_peak0_01dB_out[HPI_MAX_CHANNELS]
1535 );
1536
1537u16 hpi_meter_set_peak_ballistics(const struct hpi_hsubsys *ph_subsys,
1538 u32 h_control, u16 attack, u16 decay);
1539
1540u16 hpi_meter_set_rms_ballistics(const struct hpi_hsubsys *ph_subsys,
1541 u32 h_control, u16 attack, u16 decay);
1542
1543u16 hpi_meter_get_peak_ballistics(const struct hpi_hsubsys *ph_subsys,
1544 u32 h_control, u16 *attack, u16 *decay);
1545
1546u16 hpi_meter_get_rms_ballistics(const struct hpi_hsubsys *ph_subsys,
1547 u32 h_control, u16 *attack, u16 *decay);
1548
1549/*************************/
1550/* channel mode control */
1551/*************************/
1552u16 hpi_channel_mode_query_mode(const struct hpi_hsubsys *ph_subsys,
1553 const u32 h_mode, const u32 index, u16 *pw_mode);
1554
1555u16 hpi_channel_mode_set(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1556 u16 mode);
1557
1558u16 hpi_channel_mode_get(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1559 u16 *mode);
1560
1561/*************************/
1562/* Tuner control */
1563/*************************/
1564u16 hpi_tuner_query_band(const struct hpi_hsubsys *ph_subsys,
1565 const u32 h_tuner, const u32 index, u16 *pw_band);
1566
1567u16 hpi_tuner_set_band(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1568 u16 band);
1569
1570u16 hpi_tuner_get_band(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1571 u16 *pw_band);
1572
1573u16 hpi_tuner_query_frequency(const struct hpi_hsubsys *ph_subsys,
1574 const u32 h_tuner, const u32 index, const u16 band, u32 *pfreq);
1575
1576u16 hpi_tuner_set_frequency(const struct hpi_hsubsys *ph_subsys,
1577 u32 h_control, u32 freq_ink_hz);
1578
1579u16 hpi_tuner_get_frequency(const struct hpi_hsubsys *ph_subsys,
1580 u32 h_control, u32 *pw_freq_ink_hz);
1581
1582u16 hpi_tuner_getRF_level(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1583 short *pw_level);
1584
1585u16 hpi_tuner_get_rawRF_level(const struct hpi_hsubsys *ph_subsys,
1586 u32 h_control, short *pw_level);
1587
1588u16 hpi_tuner_query_gain(const struct hpi_hsubsys *ph_subsys,
1589 const u32 h_tuner, const u32 index, u16 *pw_gain);
1590
1591u16 hpi_tuner_set_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1592 short gain);
1593
1594u16 hpi_tuner_get_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1595 short *pn_gain);
1596
1597u16 hpi_tuner_get_status(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1598 u16 *pw_status_mask, u16 *pw_status);
1599
1600u16 hpi_tuner_set_mode(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1601 u32 mode, u32 value);
1602
1603u16 hpi_tuner_get_mode(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1604 u32 mode, u32 *pn_value);
1605
1606u16 hpi_tuner_getRDS(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1607 char *p_rds_data);
1608
1609u16 hpi_tuner_query_deemphasis(const struct hpi_hsubsys *ph_subsys,
1610 const u32 h_tuner, const u32 index, const u16 band, u32 *pdeemphasis);
1611
1612u16 hpi_tuner_set_deemphasis(const struct hpi_hsubsys *ph_subsys,
1613 u32 h_control, u32 deemphasis);
1614u16 hpi_tuner_get_deemphasis(const struct hpi_hsubsys *ph_subsys,
1615 u32 h_control, u32 *pdeemphasis);
1616
1617u16 hpi_tuner_query_program(const struct hpi_hsubsys *ph_subsys,
1618 const u32 h_tuner, u32 *pbitmap_program);
1619
1620u16 hpi_tuner_set_program(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1621 u32 program);
1622
1623u16 hpi_tuner_get_program(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1624 u32 *pprogram);
1625
1626u16 hpi_tuner_get_hd_radio_dsp_version(const struct hpi_hsubsys *ph_subsys,
1627 u32 h_control, char *psz_dsp_version, const u32 string_size);
1628
1629u16 hpi_tuner_get_hd_radio_sdk_version(const struct hpi_hsubsys *ph_subsys,
1630 u32 h_control, char *psz_sdk_version, const u32 string_size);
1631
1632u16 hpi_tuner_get_hd_radio_signal_quality(const struct hpi_hsubsys *ph_subsys,
1633 u32 h_control, u32 *pquality);
1634
1635u16 hpi_tuner_get_hd_radio_signal_blend(const struct hpi_hsubsys *ph_subsys,
1636 u32 h_control, u32 *pblend);
1637
1638u16 hpi_tuner_set_hd_radio_signal_blend(const struct hpi_hsubsys *ph_subsys,
1639 u32 h_control, const u32 blend);
1640
1641/****************************/
1642/* PADs control */
1643/****************************/
1644
1645u16 HPI_PAD__get_channel_name(const struct hpi_hsubsys *ph_subsys,
1646 u32 h_control, char *psz_string, const u32 string_length);
1647
1648u16 HPI_PAD__get_artist(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1649 char *psz_string, const u32 string_length);
1650
1651u16 HPI_PAD__get_title(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1652 char *psz_string, const u32 string_length);
1653
1654u16 HPI_PAD__get_comment(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1655 char *psz_string, const u32 string_length);
1656
1657u16 HPI_PAD__get_program_type(const struct hpi_hsubsys *ph_subsys,
1658 u32 h_control, u32 *ppTY);
1659
1660u16 HPI_PAD__get_rdsPI(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1661 u32 *ppI);
1662
1663u16 HPI_PAD__get_program_type_string(const struct hpi_hsubsys *ph_subsys,
1664 u32 h_control, const u32 data_type, const u32 pTY, char *psz_string,
1665 const u32 string_length);
1666
1667/****************************/
1668/* AES/EBU Receiver control */
1669/****************************/
1670u16 HPI_AESEBU__receiver_query_format(const struct hpi_hsubsys *ph_subsys,
1671 const u32 h_aes_rx, const u32 index, u16 *pw_format);
1672
1673u16 HPI_AESEBU__receiver_set_format(const struct hpi_hsubsys *ph_subsys,
1674 u32 h_control, u16 source);
1675
1676u16 HPI_AESEBU__receiver_get_format(const struct hpi_hsubsys *ph_subsys,
1677 u32 h_control, u16 *pw_source);
1678
1679u16 HPI_AESEBU__receiver_get_sample_rate(const struct hpi_hsubsys *ph_subsys,
1680 u32 h_control, u32 *psample_rate);
1681
1682u16 HPI_AESEBU__receiver_get_user_data(const struct hpi_hsubsys *ph_subsys,
1683 u32 h_control, u16 index, u16 *pw_data);
1684
1685u16 HPI_AESEBU__receiver_get_channel_status(const struct hpi_hsubsys
1686 *ph_subsys, u32 h_control, u16 index, u16 *pw_data);
1687
1688u16 HPI_AESEBU__receiver_get_error_status(const struct hpi_hsubsys *ph_subsys,
1689 u32 h_control, u16 *pw_error_data);
1690
1691/*******************************/
1692/* AES/EBU Transmitter control */
1693/*******************************/
1694u16 HPI_AESEBU__transmitter_set_sample_rate(const struct hpi_hsubsys
1695 *ph_subsys, u32 h_control, u32 sample_rate);
1696
1697u16 HPI_AESEBU__transmitter_set_user_data(const struct hpi_hsubsys *ph_subsys,
1698 u32 h_control, u16 index, u16 data);
1699
1700u16 HPI_AESEBU__transmitter_set_channel_status(const struct hpi_hsubsys
1701 *ph_subsys, u32 h_control, u16 index, u16 data);
1702
1703u16 HPI_AESEBU__transmitter_get_channel_status(const struct hpi_hsubsys
1704 *ph_subsys, u32 h_control, u16 index, u16 *pw_data);
1705
1706u16 HPI_AESEBU__transmitter_query_format(const struct hpi_hsubsys *ph_subsys,
1707 const u32 h_aes_tx, const u32 index, u16 *pw_format);
1708
1709u16 HPI_AESEBU__transmitter_set_format(const struct hpi_hsubsys *ph_subsys,
1710 u32 h_control, u16 output_format);
1711
1712u16 HPI_AESEBU__transmitter_get_format(const struct hpi_hsubsys *ph_subsys,
1713 u32 h_control, u16 *pw_output_format);
1714
1715/***********************/
1716/* multiplexer control */
1717/***********************/
1718u16 hpi_multiplexer_set_source(const struct hpi_hsubsys *ph_subsys,
1719 u32 h_control, u16 source_node_type, u16 source_node_index);
1720
1721u16 hpi_multiplexer_get_source(const struct hpi_hsubsys *ph_subsys,
1722 u32 h_control, u16 *source_node_type, u16 *source_node_index);
1723
1724u16 hpi_multiplexer_query_source(const struct hpi_hsubsys *ph_subsys,
1725 u32 h_control, u16 index, u16 *source_node_type,
1726 u16 *source_node_index);
1727
1728/***************/
1729/* VOX control */
1730/***************/
1731u16 hpi_vox_set_threshold(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1732 short an_gain0_01dB);
1733
1734u16 hpi_vox_get_threshold(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1735 short *an_gain0_01dB);
1736
1737/*********************/
1738/* Bitstream control */
1739/*********************/
1740u16 hpi_bitstream_set_clock_edge(const struct hpi_hsubsys *ph_subsys,
1741 u32 h_control, u16 edge_type);
1742
1743u16 hpi_bitstream_set_data_polarity(const struct hpi_hsubsys *ph_subsys,
1744 u32 h_control, u16 polarity);
1745
1746u16 hpi_bitstream_get_activity(const struct hpi_hsubsys *ph_subsys,
1747 u32 h_control, u16 *pw_clk_activity, u16 *pw_data_activity);
1748
1749/***********************/
1750/* SampleClock control */
1751/***********************/
1752
1753u16 hpi_sample_clock_query_source(const struct hpi_hsubsys *ph_subsys,
1754 const u32 h_clock, const u32 index, u16 *pw_source);
1755
1756u16 hpi_sample_clock_set_source(const struct hpi_hsubsys *ph_subsys,
1757 u32 h_control, u16 source);
1758
1759u16 hpi_sample_clock_get_source(const struct hpi_hsubsys *ph_subsys,
1760 u32 h_control, u16 *pw_source);
1761
1762u16 hpi_sample_clock_query_source_index(const struct hpi_hsubsys *ph_subsys,
1763 const u32 h_clock, const u32 index, const u32 source,
1764 u16 *pw_source_index);
1765
1766u16 hpi_sample_clock_set_source_index(const struct hpi_hsubsys *ph_subsys,
1767 u32 h_control, u16 source_index);
1768
1769u16 hpi_sample_clock_get_source_index(const struct hpi_hsubsys *ph_subsys,
1770 u32 h_control, u16 *pw_source_index);
1771
1772u16 hpi_sample_clock_get_sample_rate(const struct hpi_hsubsys *ph_subsys,
1773 u32 h_control, u32 *psample_rate);
1774
1775u16 hpi_sample_clock_query_local_rate(const struct hpi_hsubsys *ph_subsys,
1776 const u32 h_clock, const u32 index, u32 *psource);
1777
1778u16 hpi_sample_clock_set_local_rate(const struct hpi_hsubsys *ph_subsys,
1779 u32 h_control, u32 sample_rate);
1780
1781u16 hpi_sample_clock_get_local_rate(const struct hpi_hsubsys *ph_subsys,
1782 u32 h_control, u32 *psample_rate);
1783
1784u16 hpi_sample_clock_set_auto(const struct hpi_hsubsys *ph_subsys,
1785 u32 h_control, u32 enable);
1786
1787u16 hpi_sample_clock_get_auto(const struct hpi_hsubsys *ph_subsys,
1788 u32 h_control, u32 *penable);
1789
1790u16 hpi_sample_clock_set_local_rate_lock(const struct hpi_hsubsys *ph_subsys,
1791 u32 h_control, u32 lock);
1792
1793u16 hpi_sample_clock_get_local_rate_lock(const struct hpi_hsubsys *ph_subsys,
1794 u32 h_control, u32 *plock);
1795
1796/***********************/
1797/* Microphone control */
1798/***********************/
1799u16 hpi_microphone_set_phantom_power(const struct hpi_hsubsys *ph_subsys,
1800 u32 h_control, u16 on_off);
1801
1802u16 hpi_microphone_get_phantom_power(const struct hpi_hsubsys *ph_subsys,
1803 u32 h_control, u16 *pw_on_off);
1804
1805/*******************************
1806 Parametric Equalizer control
1807*******************************/
1808u16 hpi_parametricEQ__get_info(const struct hpi_hsubsys *ph_subsys,
1809 u32 h_control, u16 *pw_number_of_bands, u16 *pw_enabled);
1810
1811u16 hpi_parametricEQ__set_state(const struct hpi_hsubsys *ph_subsys,
1812 u32 h_control, u16 on_off);
1813
1814u16 hpi_parametricEQ__set_band(const struct hpi_hsubsys *ph_subsys,
1815 u32 h_control, u16 index, u16 type, u32 frequency_hz, short q100,
1816 short gain0_01dB);
1817
1818u16 hpi_parametricEQ__get_band(const struct hpi_hsubsys *ph_subsys,
1819 u32 h_control, u16 index, u16 *pn_type, u32 *pfrequency_hz,
1820 short *pnQ100, short *pn_gain0_01dB);
1821
1822u16 hpi_parametricEQ__get_coeffs(const struct hpi_hsubsys *ph_subsys,
1823 u32 h_control, u16 index, short coeffs[5]
1824 );
1825
1826/*******************************
1827 Compressor Expander control
1828*******************************/
1829
1830u16 hpi_compander_set(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1831 u16 attack, u16 decay, short ratio100, short threshold0_01dB,
1832 short makeup_gain0_01dB);
1833
1834u16 hpi_compander_get(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1835 u16 *pw_attack, u16 *pw_decay, short *pw_ratio100,
1836 short *pn_threshold0_01dB, short *pn_makeup_gain0_01dB);
1837
1838/*******************************
1839 Cobranet HMI control
1840*******************************/
1841u16 hpi_cobranet_hmi_write(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1842 u32 hmi_address, u32 byte_count, u8 *pb_data);
1843
1844u16 hpi_cobranet_hmi_read(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1845 u32 hmi_address, u32 max_byte_count, u32 *pbyte_count, u8 *pb_data);
1846
1847u16 hpi_cobranet_hmi_get_status(const struct hpi_hsubsys *ph_subsys,
1848 u32 h_control, u32 *pstatus, u32 *preadable_size,
1849 u32 *pwriteable_size);
1850
1851/*Read the current IP address
1852*/
1853u16 hpi_cobranet_getI_paddress(const struct hpi_hsubsys *ph_subsys,
1854 u32 h_control, u32 *pi_paddress);
1855
1856/* Write the current IP address
1857*/
1858u16 hpi_cobranet_setI_paddress(const struct hpi_hsubsys *ph_subsys,
1859 u32 h_control, u32 i_paddress);
1860
1861/* Read the static IP address
1862*/
1863u16 hpi_cobranet_get_staticI_paddress(const struct hpi_hsubsys *ph_subsys,
1864 u32 h_control, u32 *pi_paddress);
1865
1866/* Write the static IP address
1867*/
1868u16 hpi_cobranet_set_staticI_paddress(const struct hpi_hsubsys *ph_subsys,
1869 u32 h_control, u32 i_paddress);
1870
1871/* Read the MAC address
1872*/
1873u16 hpi_cobranet_getMA_caddress(const struct hpi_hsubsys *ph_subsys,
1874 u32 h_control, u32 *pmAC_MS_bs, u32 *pmAC_LS_bs);
1875
1876/*******************************
1877 Tone Detector control
1878*******************************/
1879u16 hpi_tone_detector_get_state(const struct hpi_hsubsys *ph_subsys, u32 hC,
1880 u32 *state);
1881
1882u16 hpi_tone_detector_set_enable(const struct hpi_hsubsys *ph_subsys, u32 hC,
1883 u32 enable);
1884
1885u16 hpi_tone_detector_get_enable(const struct hpi_hsubsys *ph_subsys, u32 hC,
1886 u32 *enable);
1887
1888u16 hpi_tone_detector_set_event_enable(const struct hpi_hsubsys *ph_subsys,
1889 u32 hC, u32 event_enable);
1890
1891u16 hpi_tone_detector_get_event_enable(const struct hpi_hsubsys *ph_subsys,
1892 u32 hC, u32 *event_enable);
1893
1894u16 hpi_tone_detector_set_threshold(const struct hpi_hsubsys *ph_subsys,
1895 u32 hC, int threshold);
1896
1897u16 hpi_tone_detector_get_threshold(const struct hpi_hsubsys *ph_subsys,
1898 u32 hC, int *threshold);
1899
1900u16 hpi_tone_detector_get_frequency(const struct hpi_hsubsys *ph_subsys,
1901 u32 hC, u32 index, u32 *frequency);
1902
1903/*******************************
1904 Silence Detector control
1905*******************************/
1906u16 hpi_silence_detector_get_state(const struct hpi_hsubsys *ph_subsys,
1907 u32 hC, u32 *state);
1908
1909u16 hpi_silence_detector_set_enable(const struct hpi_hsubsys *ph_subsys,
1910 u32 hC, u32 enable);
1911
1912u16 hpi_silence_detector_get_enable(const struct hpi_hsubsys *ph_subsys,
1913 u32 hC, u32 *enable);
1914
1915u16 hpi_silence_detector_set_event_enable(const struct hpi_hsubsys *ph_subsys,
1916 u32 hC, u32 event_enable);
1917
1918u16 hpi_silence_detector_get_event_enable(const struct hpi_hsubsys *ph_subsys,
1919 u32 hC, u32 *event_enable);
1920
1921u16 hpi_silence_detector_set_delay(const struct hpi_hsubsys *ph_subsys,
1922 u32 hC, u32 delay);
1923
1924u16 hpi_silence_detector_get_delay(const struct hpi_hsubsys *ph_subsys,
1925 u32 hC, u32 *delay);
1926
1927u16 hpi_silence_detector_set_threshold(const struct hpi_hsubsys *ph_subsys,
1928 u32 hC, int threshold);
1929
1930u16 hpi_silence_detector_get_threshold(const struct hpi_hsubsys *ph_subsys,
1931 u32 hC, int *threshold);
1932
1933/*******************************
1934 Universal control
1935*******************************/
1936u16 hpi_entity_find_next(struct hpi_entity *container_entity,
1937 enum e_entity_type type, enum e_entity_role role, int recursive_flag,
1938 struct hpi_entity **current_match);
1939
1940u16 hpi_entity_copy_value_from(struct hpi_entity *entity,
1941 enum e_entity_type type, size_t item_count, void *value_dst_p);
1942
1943u16 hpi_entity_unpack(struct hpi_entity *entity, enum e_entity_type *type,
1944 size_t *items, enum e_entity_role *role, void **value);
1945
1946u16 hpi_entity_alloc_and_pack(const enum e_entity_type type,
1947 const size_t item_count, const enum e_entity_role role, void *value,
1948 struct hpi_entity **entity);
1949
1950void hpi_entity_free(struct hpi_entity *entity);
1951
1952u16 hpi_universal_info(const struct hpi_hsubsys *ph_subsys, u32 hC,
1953 struct hpi_entity **info);
1954
1955u16 hpi_universal_get(const struct hpi_hsubsys *ph_subsys, u32 hC,
1956 struct hpi_entity **value);
1957
1958u16 hpi_universal_set(const struct hpi_hsubsys *ph_subsys, u32 hC,
1959 struct hpi_entity *value);
1960
1961/*/////////// */
1962/* DSP CLOCK */
1963/*/////////// */
1964u16 hpi_clock_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
1965 u32 *ph_dsp_clock);
1966
1967u16 hpi_clock_set_time(const struct hpi_hsubsys *ph_subsys, u32 h_clock,
1968 u16 hour, u16 minute, u16 second, u16 milli_second);
1969
1970u16 hpi_clock_get_time(const struct hpi_hsubsys *ph_subsys, u32 h_clock,
1971 u16 *pw_hour, u16 *pw_minute, u16 *pw_second, u16 *pw_milli_second);
1972
1973/*/////////// */
1974/* PROFILE */
1975/*/////////// */
1976u16 hpi_profile_open_all(const struct hpi_hsubsys *ph_subsys,
1977 u16 adapter_index, u16 profile_index, u32 *ph_profile,
1978 u16 *pw_max_profiles);
1979
1980u16 hpi_profile_get(const struct hpi_hsubsys *ph_subsys, u32 h_profile,
1981 u16 index, u16 *pw_seconds, u32 *pmicro_seconds, u32 *pcall_count,
1982 u32 *pmax_micro_seconds, u32 *pmin_micro_seconds);
1983
1984u16 hpi_profile_start_all(const struct hpi_hsubsys *ph_subsys, u32 h_profile);
1985
1986u16 hpi_profile_stop_all(const struct hpi_hsubsys *ph_subsys, u32 h_profile);
1987
1988u16 hpi_profile_get_name(const struct hpi_hsubsys *ph_subsys, u32 h_profile,
1989 u16 index, char *sz_profile_name, u16 profile_name_length);
1990
1991u16 hpi_profile_get_utilization(const struct hpi_hsubsys *ph_subsys,
1992 u32 h_profile, u32 *putilization);
1993
1994/*//////////////////// */
1995/* UTILITY functions */
1996
1997u16 hpi_format_create(struct hpi_format *p_format, u16 channels, u16 format,
1998 u32 sample_rate, u32 bit_rate, u32 attributes);
1999
2000/* Until it's verified, this function is for Windows OSs only */
2001
2002#endif /*_H_HPI_ */
2003/*
2004///////////////////////////////////////////////////////////////////////////////
2005// See CVS for history. Last complete set in rev 1.146
2006////////////////////////////////////////////////////////////////////////////////
2007*/
diff --git a/sound/pci/asihpi/hpi6000.c b/sound/pci/asihpi/hpi6000.c
new file mode 100644
index 000000000000..12dab5e4892c
--- /dev/null
+++ b/sound/pci/asihpi/hpi6000.c
@@ -0,0 +1,1838 @@
1/******************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
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, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19 Hardware Programming Interface (HPI) for AudioScience ASI6200 series adapters.
20 These PCI bus adapters are based on the TI C6711 DSP.
21
22 Exported functions:
23 void HPI_6000(struct hpi_message *phm, struct hpi_response *phr)
24
25 #defines
26 HIDE_PCI_ASSERTS to show the PCI asserts
27 PROFILE_DSP2 get profile data from DSP2 if present (instead of DSP 1)
28
29(C) Copyright AudioScience Inc. 1998-2003
30*******************************************************************************/
31#define SOURCEFILE_NAME "hpi6000.c"
32
33#include "hpi_internal.h"
34#include "hpimsginit.h"
35#include "hpidebug.h"
36#include "hpi6000.h"
37#include "hpidspcd.h"
38#include "hpicmn.h"
39
40#define HPI_HIF_BASE (0x00000200) /* start of C67xx internal RAM */
41#define HPI_HIF_ADDR(member) \
42 (HPI_HIF_BASE + offsetof(struct hpi_hif_6000, member))
43#define HPI_HIF_ERROR_MASK 0x4000
44
45/* HPI6000 specific error codes */
46
47#define HPI6000_ERROR_BASE 900
48#define HPI6000_ERROR_MSG_RESP_IDLE_TIMEOUT 901
49#define HPI6000_ERROR_MSG_RESP_SEND_MSG_ACK 902
50#define HPI6000_ERROR_MSG_RESP_GET_RESP_ACK 903
51#define HPI6000_ERROR_MSG_GET_ADR 904
52#define HPI6000_ERROR_RESP_GET_ADR 905
53#define HPI6000_ERROR_MSG_RESP_BLOCKWRITE32 906
54#define HPI6000_ERROR_MSG_RESP_BLOCKREAD32 907
55#define HPI6000_ERROR_MSG_INVALID_DSP_INDEX 908
56#define HPI6000_ERROR_CONTROL_CACHE_PARAMS 909
57
58#define HPI6000_ERROR_SEND_DATA_IDLE_TIMEOUT 911
59#define HPI6000_ERROR_SEND_DATA_ACK 912
60#define HPI6000_ERROR_SEND_DATA_ADR 913
61#define HPI6000_ERROR_SEND_DATA_TIMEOUT 914
62#define HPI6000_ERROR_SEND_DATA_CMD 915
63#define HPI6000_ERROR_SEND_DATA_WRITE 916
64#define HPI6000_ERROR_SEND_DATA_IDLECMD 917
65#define HPI6000_ERROR_SEND_DATA_VERIFY 918
66
67#define HPI6000_ERROR_GET_DATA_IDLE_TIMEOUT 921
68#define HPI6000_ERROR_GET_DATA_ACK 922
69#define HPI6000_ERROR_GET_DATA_CMD 923
70#define HPI6000_ERROR_GET_DATA_READ 924
71#define HPI6000_ERROR_GET_DATA_IDLECMD 925
72
73#define HPI6000_ERROR_CONTROL_CACHE_ADDRLEN 951
74#define HPI6000_ERROR_CONTROL_CACHE_READ 952
75#define HPI6000_ERROR_CONTROL_CACHE_FLUSH 953
76
77#define HPI6000_ERROR_MSG_RESP_GETRESPCMD 961
78#define HPI6000_ERROR_MSG_RESP_IDLECMD 962
79#define HPI6000_ERROR_MSG_RESP_BLOCKVERIFY32 963
80
81/* adapter init errors */
82#define HPI6000_ERROR_UNHANDLED_SUBSYS_ID 930
83
84/* can't access PCI2040 */
85#define HPI6000_ERROR_INIT_PCI2040 931
86/* can't access DSP HPI i/f */
87#define HPI6000_ERROR_INIT_DSPHPI 932
88/* can't access internal DSP memory */
89#define HPI6000_ERROR_INIT_DSPINTMEM 933
90/* can't access SDRAM - test#1 */
91#define HPI6000_ERROR_INIT_SDRAM1 934
92/* can't access SDRAM - test#2 */
93#define HPI6000_ERROR_INIT_SDRAM2 935
94
95#define HPI6000_ERROR_INIT_VERIFY 938
96
97#define HPI6000_ERROR_INIT_NOACK 939
98
99#define HPI6000_ERROR_INIT_PLDTEST1 941
100#define HPI6000_ERROR_INIT_PLDTEST2 942
101
102/* local defines */
103
104#define HIDE_PCI_ASSERTS
105#define PROFILE_DSP2
106
107/* for PCI2040 i/f chip */
108/* HPI CSR registers */
109/* word offsets from CSR base */
110/* use when io addresses defined as u32 * */
111
112#define INTERRUPT_EVENT_SET 0
113#define INTERRUPT_EVENT_CLEAR 1
114#define INTERRUPT_MASK_SET 2
115#define INTERRUPT_MASK_CLEAR 3
116#define HPI_ERROR_REPORT 4
117#define HPI_RESET 5
118#define HPI_DATA_WIDTH 6
119
120#define MAX_DSPS 2
121/* HPI registers, spaced 8K bytes = 2K words apart */
122#define DSP_SPACING 0x800
123
124#define CONTROL 0x0000
125#define ADDRESS 0x0200
126#define DATA_AUTOINC 0x0400
127#define DATA 0x0600
128
129#define TIMEOUT 500000
130
131struct dsp_obj {
132 __iomem u32 *prHPI_control;
133 __iomem u32 *prHPI_address;
134 __iomem u32 *prHPI_data;
135 __iomem u32 *prHPI_data_auto_inc;
136 char c_dsp_rev; /*A, B */
137 u32 control_cache_address_on_dsp;
138 u32 control_cache_length_on_dsp;
139 struct hpi_adapter_obj *pa_parent_adapter;
140};
141
142struct hpi_hw_obj {
143 __iomem u32 *dw2040_HPICSR;
144 __iomem u32 *dw2040_HPIDSP;
145
146 u16 num_dsp;
147 struct dsp_obj ado[MAX_DSPS];
148
149 u32 message_buffer_address_on_dsp;
150 u32 response_buffer_address_on_dsp;
151 u32 pCI2040HPI_error_count;
152
153 struct hpi_control_cache_single control_cache[HPI_NMIXER_CONTROLS];
154 struct hpi_control_cache *p_cache;
155};
156
157static u16 hpi6000_dsp_block_write32(struct hpi_adapter_obj *pao,
158 u16 dsp_index, u32 hpi_address, u32 *source, u32 count);
159static u16 hpi6000_dsp_block_read32(struct hpi_adapter_obj *pao,
160 u16 dsp_index, u32 hpi_address, u32 *dest, u32 count);
161
162static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
163 u32 *pos_error_code);
164static short hpi6000_check_PCI2040_error_flag(struct hpi_adapter_obj *pao,
165 u16 read_or_write);
166#define H6READ 1
167#define H6WRITE 0
168
169static short hpi6000_update_control_cache(struct hpi_adapter_obj *pao,
170 struct hpi_message *phm);
171static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao,
172 u16 dsp_index, struct hpi_message *phm, struct hpi_response *phr);
173
174static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
175 struct hpi_response *phr);
176
177static short hpi6000_wait_dsp_ack(struct hpi_adapter_obj *pao, u16 dsp_index,
178 u32 ack_value);
179
180static short hpi6000_send_host_command(struct hpi_adapter_obj *pao,
181 u16 dsp_index, u32 host_cmd);
182
183static void hpi6000_send_dsp_interrupt(struct dsp_obj *pdo);
184
185static short hpi6000_send_data(struct hpi_adapter_obj *pao, u16 dsp_index,
186 struct hpi_message *phm, struct hpi_response *phr);
187
188static short hpi6000_get_data(struct hpi_adapter_obj *pao, u16 dsp_index,
189 struct hpi_message *phm, struct hpi_response *phr);
190
191static void hpi_write_word(struct dsp_obj *pdo, u32 address, u32 data);
192
193static u32 hpi_read_word(struct dsp_obj *pdo, u32 address);
194
195static void hpi_write_block(struct dsp_obj *pdo, u32 address, u32 *pdata,
196 u32 length);
197
198static void hpi_read_block(struct dsp_obj *pdo, u32 address, u32 *pdata,
199 u32 length);
200
201static void subsys_create_adapter(struct hpi_message *phm,
202 struct hpi_response *phr);
203
204static void subsys_delete_adapter(struct hpi_message *phm,
205 struct hpi_response *phr);
206
207static void adapter_get_asserts(struct hpi_adapter_obj *pao,
208 struct hpi_message *phm, struct hpi_response *phr);
209
210static short create_adapter_obj(struct hpi_adapter_obj *pao,
211 u32 *pos_error_code);
212
213/* local globals */
214
215static u16 gw_pci_read_asserts; /* used to count PCI2040 errors */
216static u16 gw_pci_write_asserts; /* used to count PCI2040 errors */
217
218static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
219{
220
221 switch (phm->function) {
222 case HPI_SUBSYS_OPEN:
223 case HPI_SUBSYS_CLOSE:
224 case HPI_SUBSYS_GET_INFO:
225 case HPI_SUBSYS_DRIVER_UNLOAD:
226 case HPI_SUBSYS_DRIVER_LOAD:
227 case HPI_SUBSYS_FIND_ADAPTERS:
228 /* messages that should not get here */
229 phr->error = HPI_ERROR_UNIMPLEMENTED;
230 break;
231 case HPI_SUBSYS_CREATE_ADAPTER:
232 subsys_create_adapter(phm, phr);
233 break;
234 case HPI_SUBSYS_DELETE_ADAPTER:
235 subsys_delete_adapter(phm, phr);
236 break;
237 default:
238 phr->error = HPI_ERROR_INVALID_FUNC;
239 break;
240 }
241}
242
243static void control_message(struct hpi_adapter_obj *pao,
244 struct hpi_message *phm, struct hpi_response *phr)
245{
246
247 switch (phm->function) {
248 case HPI_CONTROL_GET_STATE:
249 if (pao->has_control_cache) {
250 u16 err;
251 err = hpi6000_update_control_cache(pao, phm);
252
253 if (err) {
254 phr->error = err;
255 break;
256 }
257
258 if (hpi_check_control_cache(((struct hpi_hw_obj *)
259 pao->priv)->p_cache, phm,
260 phr))
261 break;
262 }
263 hw_message(pao, phm, phr);
264 break;
265 case HPI_CONTROL_GET_INFO:
266 hw_message(pao, phm, phr);
267 break;
268 case HPI_CONTROL_SET_STATE:
269 hw_message(pao, phm, phr);
270 hpi_sync_control_cache(((struct hpi_hw_obj *)pao->priv)->
271 p_cache, phm, phr);
272 break;
273 default:
274 phr->error = HPI_ERROR_INVALID_FUNC;
275 break;
276 }
277}
278
279static void adapter_message(struct hpi_adapter_obj *pao,
280 struct hpi_message *phm, struct hpi_response *phr)
281{
282 switch (phm->function) {
283 case HPI_ADAPTER_GET_INFO:
284 hw_message(pao, phm, phr);
285 break;
286 case HPI_ADAPTER_GET_ASSERT:
287 adapter_get_asserts(pao, phm, phr);
288 break;
289 case HPI_ADAPTER_OPEN:
290 case HPI_ADAPTER_CLOSE:
291 case HPI_ADAPTER_TEST_ASSERT:
292 case HPI_ADAPTER_SELFTEST:
293 case HPI_ADAPTER_GET_MODE:
294 case HPI_ADAPTER_SET_MODE:
295 case HPI_ADAPTER_FIND_OBJECT:
296 case HPI_ADAPTER_GET_PROPERTY:
297 case HPI_ADAPTER_SET_PROPERTY:
298 case HPI_ADAPTER_ENUM_PROPERTY:
299 hw_message(pao, phm, phr);
300 break;
301 default:
302 phr->error = HPI_ERROR_INVALID_FUNC;
303 break;
304 }
305}
306
307static void outstream_message(struct hpi_adapter_obj *pao,
308 struct hpi_message *phm, struct hpi_response *phr)
309{
310 switch (phm->function) {
311 case HPI_OSTREAM_HOSTBUFFER_ALLOC:
312 case HPI_OSTREAM_HOSTBUFFER_FREE:
313 /* Don't let these messages go to the HW function because
314 * they're called without allocating the spinlock.
315 * For the HPI6000 adapters the HW would return
316 * HPI_ERROR_INVALID_FUNC anyway.
317 */
318 phr->error = HPI_ERROR_INVALID_FUNC;
319 break;
320 default:
321 hw_message(pao, phm, phr);
322 return;
323 }
324}
325
326static void instream_message(struct hpi_adapter_obj *pao,
327 struct hpi_message *phm, struct hpi_response *phr)
328{
329
330 switch (phm->function) {
331 case HPI_ISTREAM_HOSTBUFFER_ALLOC:
332 case HPI_ISTREAM_HOSTBUFFER_FREE:
333 /* Don't let these messages go to the HW function because
334 * they're called without allocating the spinlock.
335 * For the HPI6000 adapters the HW would return
336 * HPI_ERROR_INVALID_FUNC anyway.
337 */
338 phr->error = HPI_ERROR_INVALID_FUNC;
339 break;
340 default:
341 hw_message(pao, phm, phr);
342 return;
343 }
344}
345
346/************************************************************************/
347/** HPI_6000()
348 * Entry point from HPIMAN
349 * All calls to the HPI start here
350 */
351void HPI_6000(struct hpi_message *phm, struct hpi_response *phr)
352{
353 struct hpi_adapter_obj *pao = NULL;
354
355 /* subsytem messages get executed by every HPI. */
356 /* All other messages are ignored unless the adapter index matches */
357 /* an adapter in the HPI */
358 HPI_DEBUG_LOG(DEBUG, "O %d,F %x\n", phm->object, phm->function);
359
360 /* if Dsp has crashed then do not communicate with it any more */
361 if (phm->object != HPI_OBJ_SUBSYSTEM) {
362 pao = hpi_find_adapter(phm->adapter_index);
363 if (!pao) {
364 HPI_DEBUG_LOG(DEBUG,
365 " %d,%d refused, for another HPI?\n",
366 phm->object, phm->function);
367 return;
368 }
369
370 if (pao->dsp_crashed >= 10) {
371 hpi_init_response(phr, phm->object, phm->function,
372 HPI_ERROR_DSP_HARDWARE);
373 HPI_DEBUG_LOG(DEBUG, " %d,%d dsp crashed.\n",
374 phm->object, phm->function);
375 return;
376 }
377 }
378 /* Init default response including the size field */
379 if (phm->function != HPI_SUBSYS_CREATE_ADAPTER)
380 hpi_init_response(phr, phm->object, phm->function,
381 HPI_ERROR_PROCESSING_MESSAGE);
382
383 switch (phm->type) {
384 case HPI_TYPE_MESSAGE:
385 switch (phm->object) {
386 case HPI_OBJ_SUBSYSTEM:
387 subsys_message(phm, phr);
388 break;
389
390 case HPI_OBJ_ADAPTER:
391 phr->size =
392 sizeof(struct hpi_response_header) +
393 sizeof(struct hpi_adapter_res);
394 adapter_message(pao, phm, phr);
395 break;
396
397 case HPI_OBJ_CONTROL:
398 control_message(pao, phm, phr);
399 break;
400
401 case HPI_OBJ_OSTREAM:
402 outstream_message(pao, phm, phr);
403 break;
404
405 case HPI_OBJ_ISTREAM:
406 instream_message(pao, phm, phr);
407 break;
408
409 default:
410 hw_message(pao, phm, phr);
411 break;
412 }
413 break;
414
415 default:
416 phr->error = HPI_ERROR_INVALID_TYPE;
417 break;
418 }
419}
420
421/************************************************************************/
422/* SUBSYSTEM */
423
424/* create an adapter object and initialise it based on resource information
425 * passed in in the message
426 * NOTE - you cannot use this function AND the FindAdapters function at the
427 * same time, the application must use only one of them to get the adapters
428 */
429static void subsys_create_adapter(struct hpi_message *phm,
430 struct hpi_response *phr)
431{
432 /* create temp adapter obj, because we don't know what index yet */
433 struct hpi_adapter_obj ao;
434 struct hpi_adapter_obj *pao;
435 u32 os_error_code;
436 short error = 0;
437 u32 dsp_index = 0;
438
439 HPI_DEBUG_LOG(VERBOSE, "subsys_create_adapter\n");
440
441 memset(&ao, 0, sizeof(ao));
442
443 /* this HPI only creates adapters for TI/PCI2040 based devices */
444 if (phm->u.s.resource.bus_type != HPI_BUS_PCI)
445 return;
446 if (phm->u.s.resource.r.pci->vendor_id != HPI_PCI_VENDOR_ID_TI)
447 return;
448 if (phm->u.s.resource.r.pci->device_id != HPI_PCI_DEV_ID_PCI2040)
449 return;
450
451 ao.priv = kzalloc(sizeof(struct hpi_hw_obj), GFP_KERNEL);
452 if (!ao.priv) {
453 HPI_DEBUG_LOG(ERROR, "cant get mem for adapter object\n");
454 phr->error = HPI_ERROR_MEMORY_ALLOC;
455 return;
456 }
457
458 /* create the adapter object based on the resource information */
459 /*? memcpy(&ao.Pci,&phm->u.s.Resource.r.Pci,sizeof(ao.Pci)); */
460 ao.pci = *phm->u.s.resource.r.pci;
461
462 error = create_adapter_obj(&ao, &os_error_code);
463 if (!error)
464 error = hpi_add_adapter(&ao);
465 if (error) {
466 phr->u.s.data = os_error_code;
467 kfree(ao.priv);
468 phr->error = error;
469 return;
470 }
471 /* need to update paParentAdapter */
472 pao = hpi_find_adapter(ao.index);
473 if (!pao) {
474 /* We just added this adapter, why can't we find it!? */
475 HPI_DEBUG_LOG(ERROR, "lost adapter after boot\n");
476 phr->error = 950;
477 return;
478 }
479
480 for (dsp_index = 0; dsp_index < MAX_DSPS; dsp_index++) {
481 struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv;
482 phw->ado[dsp_index].pa_parent_adapter = pao;
483 }
484
485 phr->u.s.aw_adapter_list[ao.index] = ao.adapter_type;
486 phr->u.s.adapter_index = ao.index;
487 phr->u.s.num_adapters++;
488 phr->error = 0;
489}
490
491static void subsys_delete_adapter(struct hpi_message *phm,
492 struct hpi_response *phr)
493{
494 struct hpi_adapter_obj *pao = NULL;
495 struct hpi_hw_obj *phw;
496
497 pao = hpi_find_adapter(phm->adapter_index);
498 if (!pao)
499 return;
500
501 phw = (struct hpi_hw_obj *)pao->priv;
502
503 if (pao->has_control_cache)
504 hpi_free_control_cache(phw->p_cache);
505
506 hpi_delete_adapter(pao);
507 kfree(phw);
508
509 phr->error = 0;
510}
511
512/* this routine is called from SubSysFindAdapter and SubSysCreateAdapter */
513static short create_adapter_obj(struct hpi_adapter_obj *pao,
514 u32 *pos_error_code)
515{
516 short boot_error = 0;
517 u32 dsp_index = 0;
518 u32 control_cache_size = 0;
519 u32 control_cache_count = 0;
520 struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv;
521
522 /* init error reporting */
523 pao->dsp_crashed = 0;
524
525 /* The PCI2040 has the following address map */
526 /* BAR0 - 4K = HPI control and status registers on PCI2040 (HPI CSR) */
527 /* BAR1 - 32K = HPI registers on DSP */
528 phw->dw2040_HPICSR = pao->pci.ap_mem_base[0];
529 phw->dw2040_HPIDSP = pao->pci.ap_mem_base[1];
530 HPI_DEBUG_LOG(VERBOSE, "csr %p, dsp %p\n", phw->dw2040_HPICSR,
531 phw->dw2040_HPIDSP);
532
533 /* set addresses for the possible DSP HPI interfaces */
534 for (dsp_index = 0; dsp_index < MAX_DSPS; dsp_index++) {
535 phw->ado[dsp_index].prHPI_control =
536 phw->dw2040_HPIDSP + (CONTROL +
537 DSP_SPACING * dsp_index);
538
539 phw->ado[dsp_index].prHPI_address =
540 phw->dw2040_HPIDSP + (ADDRESS +
541 DSP_SPACING * dsp_index);
542 phw->ado[dsp_index].prHPI_data =
543 phw->dw2040_HPIDSP + (DATA + DSP_SPACING * dsp_index);
544
545 phw->ado[dsp_index].prHPI_data_auto_inc =
546 phw->dw2040_HPIDSP + (DATA_AUTOINC +
547 DSP_SPACING * dsp_index);
548
549 HPI_DEBUG_LOG(VERBOSE, "ctl %p, adr %p, dat %p, dat++ %p\n",
550 phw->ado[dsp_index].prHPI_control,
551 phw->ado[dsp_index].prHPI_address,
552 phw->ado[dsp_index].prHPI_data,
553 phw->ado[dsp_index].prHPI_data_auto_inc);
554
555 phw->ado[dsp_index].pa_parent_adapter = pao;
556 }
557
558 phw->pCI2040HPI_error_count = 0;
559 pao->has_control_cache = 0;
560
561 /* Set the default number of DSPs on this card */
562 /* This is (conditionally) adjusted after bootloading */
563 /* of the first DSP in the bootload section. */
564 phw->num_dsp = 1;
565
566 boot_error = hpi6000_adapter_boot_load_dsp(pao, pos_error_code);
567 if (boot_error)
568 return boot_error;
569
570 HPI_DEBUG_LOG(INFO, "bootload DSP OK\n");
571
572 phw->message_buffer_address_on_dsp = 0L;
573 phw->response_buffer_address_on_dsp = 0L;
574
575 /* get info about the adapter by asking the adapter */
576 /* send a HPI_ADAPTER_GET_INFO message */
577 {
578 struct hpi_message hM;
579 struct hpi_response hR0; /* response from DSP 0 */
580 struct hpi_response hR1; /* response from DSP 1 */
581 u16 error = 0;
582
583 HPI_DEBUG_LOG(VERBOSE, "send ADAPTER_GET_INFO\n");
584 memset(&hM, 0, sizeof(hM));
585 hM.type = HPI_TYPE_MESSAGE;
586 hM.size = sizeof(struct hpi_message);
587 hM.object = HPI_OBJ_ADAPTER;
588 hM.function = HPI_ADAPTER_GET_INFO;
589 hM.adapter_index = 0;
590 memset(&hR0, 0, sizeof(hR0));
591 memset(&hR1, 0, sizeof(hR1));
592 hR0.size = sizeof(hR0);
593 hR1.size = sizeof(hR1);
594
595 error = hpi6000_message_response_sequence(pao, 0, &hM, &hR0);
596 if (hR0.error) {
597 HPI_DEBUG_LOG(DEBUG, "message error %d\n", hR0.error);
598 return hR0.error;
599 }
600 if (phw->num_dsp == 2) {
601 error = hpi6000_message_response_sequence(pao, 1, &hM,
602 &hR1);
603 if (error)
604 return error;
605 }
606 pao->adapter_type = hR0.u.a.adapter_type;
607 pao->index = hR0.u.a.adapter_index;
608 }
609
610 memset(&phw->control_cache[0], 0,
611 sizeof(struct hpi_control_cache_single) *
612 HPI_NMIXER_CONTROLS);
613 /* Read the control cache length to figure out if it is turned on */
614 control_cache_size =
615 hpi_read_word(&phw->ado[0],
616 HPI_HIF_ADDR(control_cache_size_in_bytes));
617 if (control_cache_size) {
618 control_cache_count =
619 hpi_read_word(&phw->ado[0],
620 HPI_HIF_ADDR(control_cache_count));
621 pao->has_control_cache = 1;
622
623 phw->p_cache =
624 hpi_alloc_control_cache(control_cache_count,
625 control_cache_size, (struct hpi_control_cache_info *)
626 &phw->control_cache[0]
627 );
628 } else
629 pao->has_control_cache = 0;
630
631 HPI_DEBUG_LOG(DEBUG, "get adapter info ASI%04X index %d\n",
632 pao->adapter_type, pao->index);
633 pao->open = 0; /* upon creation the adapter is closed */
634 return 0;
635}
636
637/************************************************************************/
638/* ADAPTER */
639
640static void adapter_get_asserts(struct hpi_adapter_obj *pao,
641 struct hpi_message *phm, struct hpi_response *phr)
642{
643#ifndef HIDE_PCI_ASSERTS
644 /* if we have PCI2040 asserts then collect them */
645 if ((gw_pci_read_asserts > 0) || (gw_pci_write_asserts > 0)) {
646 phr->u.a.serial_number =
647 gw_pci_read_asserts * 100 + gw_pci_write_asserts;
648 phr->u.a.adapter_index = 1; /* assert count */
649 phr->u.a.adapter_type = -1; /* "dsp index" */
650 strcpy(phr->u.a.sz_adapter_assert, "PCI2040 error");
651 gw_pci_read_asserts = 0;
652 gw_pci_write_asserts = 0;
653 phr->error = 0;
654 } else
655#endif
656 hw_message(pao, phm, phr); /*get DSP asserts */
657
658 return;
659}
660
661/************************************************************************/
662/* LOW-LEVEL */
663
664static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
665 u32 *pos_error_code)
666{
667 struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv;
668 short error;
669 u32 timeout;
670 u32 read = 0;
671 u32 i = 0;
672 u32 data = 0;
673 u32 j = 0;
674 u32 test_addr = 0x80000000;
675 u32 test_data = 0x00000001;
676 u32 dw2040_reset = 0;
677 u32 dsp_index = 0;
678 u32 endian = 0;
679 u32 adapter_info = 0;
680 u32 delay = 0;
681
682 struct dsp_code dsp_code;
683 u16 boot_load_family = 0;
684
685 /* NOTE don't use wAdapterType in this routine. It is not setup yet */
686
687 switch (pao->pci.subsys_device_id) {
688 case 0x5100:
689 case 0x5110: /* ASI5100 revB or higher with C6711D */
690 case 0x6100:
691 case 0x6200:
692 boot_load_family = HPI_ADAPTER_FAMILY_ASI(0x6200);
693 break;
694 default:
695 return HPI6000_ERROR_UNHANDLED_SUBSYS_ID;
696 }
697
698 /* reset all DSPs, indicate two DSPs are present
699 * set RST3-=1 to disconnect HAD8 to set DSP in little endian mode
700 */
701 endian = 0;
702 dw2040_reset = 0x0003000F;
703 iowrite32(dw2040_reset, phw->dw2040_HPICSR + HPI_RESET);
704
705 /* read back register to make sure PCI2040 chip is functioning
706 * note that bits 4..15 are read-only and so should always return zero,
707 * even though we wrote 1 to them
708 */
709 for (i = 0; i < 1000; i++)
710 delay = ioread32(phw->dw2040_HPICSR + HPI_RESET);
711 if (delay != dw2040_reset) {
712 HPI_DEBUG_LOG(ERROR, "INIT_PCI2040 %x %x\n", dw2040_reset,
713 delay);
714 return HPI6000_ERROR_INIT_PCI2040;
715 }
716
717 /* Indicate that DSP#0,1 is a C6X */
718 iowrite32(0x00000003, phw->dw2040_HPICSR + HPI_DATA_WIDTH);
719 /* set Bit30 and 29 - which will prevent Target aborts from being
720 * issued upon HPI or GP error
721 */
722 iowrite32(0x60000000, phw->dw2040_HPICSR + INTERRUPT_MASK_SET);
723
724 /* isolate DSP HAD8 line from PCI2040 so that
725 * Little endian can be set by pullup
726 */
727 dw2040_reset = dw2040_reset & (~(endian << 3));
728 iowrite32(dw2040_reset, phw->dw2040_HPICSR + HPI_RESET);
729
730 phw->ado[0].c_dsp_rev = 'B'; /* revB */
731 phw->ado[1].c_dsp_rev = 'B'; /* revB */
732
733 /*Take both DSPs out of reset, setting HAD8 to the correct Endian */
734 dw2040_reset = dw2040_reset & (~0x00000001); /* start DSP 0 */
735 iowrite32(dw2040_reset, phw->dw2040_HPICSR + HPI_RESET);
736 dw2040_reset = dw2040_reset & (~0x00000002); /* start DSP 1 */
737 iowrite32(dw2040_reset, phw->dw2040_HPICSR + HPI_RESET);
738
739 /* set HAD8 back to PCI2040, now that DSP set to little endian mode */
740 dw2040_reset = dw2040_reset & (~0x00000008);
741 iowrite32(dw2040_reset, phw->dw2040_HPICSR + HPI_RESET);
742 /*delay to allow DSP to get going */
743 for (i = 0; i < 100; i++)
744 delay = ioread32(phw->dw2040_HPICSR + HPI_RESET);
745
746 /* loop through all DSPs, downloading DSP code */
747 for (dsp_index = 0; dsp_index < phw->num_dsp; dsp_index++) {
748 struct dsp_obj *pdo = &phw->ado[dsp_index];
749
750 /* configure DSP so that we download code into the SRAM */
751 /* set control reg for little endian, HWOB=1 */
752 iowrite32(0x00010001, pdo->prHPI_control);
753
754 /* test access to the HPI address register (HPIA) */
755 test_data = 0x00000001;
756 for (j = 0; j < 32; j++) {
757 iowrite32(test_data, pdo->prHPI_address);
758 data = ioread32(pdo->prHPI_address);
759 if (data != test_data) {
760 HPI_DEBUG_LOG(ERROR, "INIT_DSPHPI %x %x %x\n",
761 test_data, data, dsp_index);
762 return HPI6000_ERROR_INIT_DSPHPI;
763 }
764 test_data = test_data << 1;
765 }
766
767/* if C6713 the setup PLL to generate 225MHz from 25MHz.
768* Since the PLLDIV1 read is sometimes wrong, even on a C6713,
769* we're going to do this unconditionally
770*/
771/* PLLDIV1 should have a value of 8000 after reset */
772/*
773 if (HpiReadWord(pdo,0x01B7C118) == 0x8000)
774*/
775 {
776 /* C6713 datasheet says we cannot program PLL from HPI,
777 * and indeed if we try to set the PLL multiply from the
778 * HPI, the PLL does not seem to lock,
779 * so we enable the PLL and use the default of x 7
780 */
781 /* bypass PLL */
782 hpi_write_word(pdo, 0x01B7C100, 0x0000);
783 for (i = 0; i < 100; i++)
784 delay = ioread32(phw->dw2040_HPICSR +
785 HPI_RESET);
786
787 /* ** use default of PLL x7 ** */
788 /* EMIF = 225/3=75MHz */
789 hpi_write_word(pdo, 0x01B7C120, 0x8002);
790 /* peri = 225/2 */
791 hpi_write_word(pdo, 0x01B7C11C, 0x8001);
792 /* cpu = 225/1 */
793 hpi_write_word(pdo, 0x01B7C118, 0x8000);
794 /* ~200us delay */
795 for (i = 0; i < 2000; i++)
796 delay = ioread32(phw->dw2040_HPICSR +
797 HPI_RESET);
798 /* PLL not bypassed */
799 hpi_write_word(pdo, 0x01B7C100, 0x0001);
800 /* ~200us delay */
801 for (i = 0; i < 2000; i++)
802 delay = ioread32(phw->dw2040_HPICSR +
803 HPI_RESET);
804 }
805
806 /* test r/w to internal DSP memory
807 * C6711 has L2 cache mapped to 0x0 when reset
808 *
809 * revB - because of bug 3.0.1 last HPI read
810 * (before HPI address issued) must be non-autoinc
811 */
812 /* test each bit in the 32bit word */
813 for (i = 0; i < 100; i++) {
814 test_addr = 0x00000000;
815 test_data = 0x00000001;
816 for (j = 0; j < 32; j++) {
817 hpi_write_word(pdo, test_addr + i, test_data);
818 data = hpi_read_word(pdo, test_addr + i);
819 if (data != test_data) {
820 HPI_DEBUG_LOG(ERROR,
821 "DSP mem %x %x %x %x\n",
822 test_addr + i, test_data,
823 data, dsp_index);
824
825 return HPI6000_ERROR_INIT_DSPINTMEM;
826 }
827 test_data = test_data << 1;
828 }
829 }
830
831 /* memory map of ASI6200
832 00000000-0000FFFF 16Kx32 internal program
833 01800000-019FFFFF Internal peripheral
834 80000000-807FFFFF CE0 2Mx32 SDRAM running @ 100MHz
835 90000000-9000FFFF CE1 Async peripherals:
836
837 EMIF config
838 ------------
839 Global EMIF control
840 0 -
841 1 -
842 2 -
843 3 CLK2EN = 1 CLKOUT2 enabled
844 4 CLK1EN = 0 CLKOUT1 disabled
845 5 EKEN = 1 <--!! C6713 specific, enables ECLKOUT
846 6 -
847 7 NOHOLD = 1 external HOLD disabled
848 8 HOLDA = 0 HOLDA output is low
849 9 HOLD = 0 HOLD input is low
850 10 ARDY = 1 ARDY input is high
851 11 BUSREQ = 0 BUSREQ output is low
852 12,13 Reserved = 1
853 */
854 hpi_write_word(pdo, 0x01800000, 0x34A8);
855
856 /* EMIF CE0 setup - 2Mx32 Sync DRAM
857 31..28 Wr setup
858 27..22 Wr strobe
859 21..20 Wr hold
860 19..16 Rd setup
861 15..14 -
862 13..8 Rd strobe
863 7..4 MTYPE 0011 Sync DRAM 32bits
864 3 Wr hold MSB
865 2..0 Rd hold
866 */
867 hpi_write_word(pdo, 0x01800008, 0x00000030);
868
869 /* EMIF SDRAM Extension
870 31-21 0
871 20 WR2RD = 0
872 19-18 WR2DEAC = 1
873 17 WR2WR = 0
874 16-15 R2WDQM = 2
875 14-12 RD2WR = 4
876 11-10 RD2DEAC = 1
877 9 RD2RD = 1
878 8-7 THZP = 10b
879 6-5 TWR = 2-1 = 01b (tWR = 10ns)
880 4 TRRD = 0b = 2 ECLK (tRRD = 14ns)
881 3-1 TRAS = 5-1 = 100b (Tras=42ns = 5 ECLK)
882 1 CAS latency = 3 ECLK
883 (for Micron 2M32-7 operating at 100Mhz)
884 */
885
886 /* need to use this else DSP code crashes */
887 hpi_write_word(pdo, 0x01800020, 0x001BDF29);
888
889 /* EMIF SDRAM control - set up for a 2Mx32 SDRAM (512x32x4 bank)
890 31 - -
891 30 SDBSZ 1 4 bank
892 29..28 SDRSZ 00 11 row address pins
893 27..26 SDCSZ 01 8 column address pins
894 25 RFEN 1 refersh enabled
895 24 INIT 1 init SDRAM
896 23..20 TRCD 0001
897 19..16 TRP 0001
898 15..12 TRC 0110
899 11..0 - -
900 */
901 /* need to use this else DSP code crashes */
902 hpi_write_word(pdo, 0x01800018, 0x47117000);
903
904 /* EMIF SDRAM Refresh Timing */
905 hpi_write_word(pdo, 0x0180001C, 0x00000410);
906
907 /*MIF CE1 setup - Async peripherals
908 @100MHz bus speed, each cycle is 10ns,
909 31..28 Wr setup = 1
910 27..22 Wr strobe = 3 30ns
911 21..20 Wr hold = 1
912 19..16 Rd setup =1
913 15..14 Ta = 2
914 13..8 Rd strobe = 3 30ns
915 7..4 MTYPE 0010 Async 32bits
916 3 Wr hold MSB =0
917 2..0 Rd hold = 1
918 */
919 {
920 u32 cE1 =
921 (1L << 28) | (3L << 22) | (1L << 20) | (1L <<
922 16) | (2L << 14) | (3L << 8) | (2L << 4) | 1L;
923 hpi_write_word(pdo, 0x01800004, cE1);
924 }
925
926 /* delay a little to allow SDRAM and DSP to "get going" */
927
928 for (i = 0; i < 1000; i++)
929 delay = ioread32(phw->dw2040_HPICSR + HPI_RESET);
930
931 /* test access to SDRAM */
932 {
933 test_addr = 0x80000000;
934 test_data = 0x00000001;
935 /* test each bit in the 32bit word */
936 for (j = 0; j < 32; j++) {
937 hpi_write_word(pdo, test_addr, test_data);
938 data = hpi_read_word(pdo, test_addr);
939 if (data != test_data) {
940 HPI_DEBUG_LOG(ERROR,
941 "DSP dram %x %x %x %x\n",
942 test_addr, test_data, data,
943 dsp_index);
944
945 return HPI6000_ERROR_INIT_SDRAM1;
946 }
947 test_data = test_data << 1;
948 }
949 /* test every Nth address in the DRAM */
950#define DRAM_SIZE_WORDS 0x200000 /*2_mx32 */
951#define DRAM_INC 1024
952 test_addr = 0x80000000;
953 test_data = 0x0;
954 for (i = 0; i < DRAM_SIZE_WORDS; i = i + DRAM_INC) {
955 hpi_write_word(pdo, test_addr + i, test_data);
956 test_data++;
957 }
958 test_addr = 0x80000000;
959 test_data = 0x0;
960 for (i = 0; i < DRAM_SIZE_WORDS; i = i + DRAM_INC) {
961 data = hpi_read_word(pdo, test_addr + i);
962 if (data != test_data) {
963 HPI_DEBUG_LOG(ERROR,
964 "DSP dram %x %x %x %x\n",
965 test_addr + i, test_data,
966 data, dsp_index);
967 return HPI6000_ERROR_INIT_SDRAM2;
968 }
969 test_data++;
970 }
971
972 }
973
974 /* write the DSP code down into the DSPs memory */
975 /*HpiDspCode_Open(nBootLoadFamily,&DspCode,pdwOsErrorCode); */
976 dsp_code.ps_dev = pao->pci.p_os_data;
977
978 error = hpi_dsp_code_open(boot_load_family, &dsp_code,
979 pos_error_code);
980
981 if (error)
982 return error;
983
984 while (1) {
985 u32 length;
986 u32 address;
987 u32 type;
988 u32 *pcode;
989
990 error = hpi_dsp_code_read_word(&dsp_code, &length);
991 if (error)
992 break;
993 if (length == 0xFFFFFFFF)
994 break; /* end of code */
995
996 error = hpi_dsp_code_read_word(&dsp_code, &address);
997 if (error)
998 break;
999 error = hpi_dsp_code_read_word(&dsp_code, &type);
1000 if (error)
1001 break;
1002 error = hpi_dsp_code_read_block(length, &dsp_code,
1003 &pcode);
1004 if (error)
1005 break;
1006 error = hpi6000_dsp_block_write32(pao, (u16)dsp_index,
1007 address, pcode, length);
1008 if (error)
1009 break;
1010 }
1011
1012 if (error) {
1013 hpi_dsp_code_close(&dsp_code);
1014 return error;
1015 }
1016 /* verify that code was written correctly */
1017 /* this time through, assume no errors in DSP code file/array */
1018 hpi_dsp_code_rewind(&dsp_code);
1019 while (1) {
1020 u32 length;
1021 u32 address;
1022 u32 type;
1023 u32 *pcode;
1024
1025 hpi_dsp_code_read_word(&dsp_code, &length);
1026 if (length == 0xFFFFFFFF)
1027 break; /* end of code */
1028
1029 hpi_dsp_code_read_word(&dsp_code, &address);
1030 hpi_dsp_code_read_word(&dsp_code, &type);
1031 hpi_dsp_code_read_block(length, &dsp_code, &pcode);
1032
1033 for (i = 0; i < length; i++) {
1034 data = hpi_read_word(pdo, address);
1035 if (data != *pcode) {
1036 error = HPI6000_ERROR_INIT_VERIFY;
1037 HPI_DEBUG_LOG(ERROR,
1038 "DSP verify %x %x %x %x\n",
1039 address, *pcode, data,
1040 dsp_index);
1041 break;
1042 }
1043 pcode++;
1044 address += 4;
1045 }
1046 if (error)
1047 break;
1048 }
1049 hpi_dsp_code_close(&dsp_code);
1050 if (error)
1051 return error;
1052
1053 /* zero out the hostmailbox */
1054 {
1055 u32 address = HPI_HIF_ADDR(host_cmd);
1056 for (i = 0; i < 4; i++) {
1057 hpi_write_word(pdo, address, 0);
1058 address += 4;
1059 }
1060 }
1061 /* write the DSP number into the hostmailbox */
1062 /* structure before starting the DSP */
1063 hpi_write_word(pdo, HPI_HIF_ADDR(dsp_number), dsp_index);
1064
1065 /* write the DSP adapter Info into the */
1066 /* hostmailbox before starting the DSP */
1067 if (dsp_index > 0)
1068 hpi_write_word(pdo, HPI_HIF_ADDR(adapter_info),
1069 adapter_info);
1070
1071 /* step 3. Start code by sending interrupt */
1072 iowrite32(0x00030003, pdo->prHPI_control);
1073 for (i = 0; i < 10000; i++)
1074 delay = ioread32(phw->dw2040_HPICSR + HPI_RESET);
1075
1076 /* wait for a non-zero value in hostcmd -
1077 * indicating initialization is complete
1078 *
1079 * Init could take a while if DSP checks SDRAM memory
1080 * Was 200000. Increased to 2000000 for ASI8801 so we
1081 * don't get 938 errors.
1082 */
1083 timeout = 2000000;
1084 while (timeout) {
1085 do {
1086 read = hpi_read_word(pdo,
1087 HPI_HIF_ADDR(host_cmd));
1088 } while (--timeout
1089 && hpi6000_check_PCI2040_error_flag(pao,
1090 H6READ));
1091
1092 if (read)
1093 break;
1094 /* The following is a workaround for bug #94:
1095 * Bluescreen on install and subsequent boots on a
1096 * DELL PowerEdge 600SC PC with 1.8GHz P4 and
1097 * ServerWorks chipset. Without this delay the system
1098 * locks up with a bluescreen (NOT GPF or pagefault).
1099 */
1100 else
1101 hpios_delay_micro_seconds(1000);
1102 }
1103 if (timeout == 0)
1104 return HPI6000_ERROR_INIT_NOACK;
1105
1106 /* read the DSP adapter Info from the */
1107 /* hostmailbox structure after starting the DSP */
1108 if (dsp_index == 0) {
1109 /*u32 dwTestData=0; */
1110 u32 mask = 0;
1111
1112 adapter_info =
1113 hpi_read_word(pdo,
1114 HPI_HIF_ADDR(adapter_info));
1115 if (HPI_ADAPTER_FAMILY_ASI
1116 (HPI_HIF_ADAPTER_INFO_EXTRACT_ADAPTER
1117 (adapter_info)) ==
1118 HPI_ADAPTER_FAMILY_ASI(0x6200))
1119 /* all 6200 cards have this many DSPs */
1120 phw->num_dsp = 2;
1121
1122 /* test that the PLD is programmed */
1123 /* and we can read/write 24bits */
1124#define PLD_BASE_ADDRESS 0x90000000L /*for ASI6100/6200/8800 */
1125
1126 switch (boot_load_family) {
1127 case HPI_ADAPTER_FAMILY_ASI(0x6200):
1128 /* ASI6100/6200 has 24bit path to FPGA */
1129 mask = 0xFFFFFF00L;
1130 /* ASI5100 uses AX6 code, */
1131 /* but has no PLD r/w register to test */
1132 if (HPI_ADAPTER_FAMILY_ASI(pao->pci.
1133 subsys_device_id) ==
1134 HPI_ADAPTER_FAMILY_ASI(0x5100))
1135 mask = 0x00000000L;
1136 break;
1137 case HPI_ADAPTER_FAMILY_ASI(0x8800):
1138 /* ASI8800 has 16bit path to FPGA */
1139 mask = 0xFFFF0000L;
1140 break;
1141 }
1142 test_data = 0xAAAAAA00L & mask;
1143 /* write to 24 bit Debug register (D31-D8) */
1144 hpi_write_word(pdo, PLD_BASE_ADDRESS + 4L, test_data);
1145 read = hpi_read_word(pdo,
1146 PLD_BASE_ADDRESS + 4L) & mask;
1147 if (read != test_data) {
1148 HPI_DEBUG_LOG(ERROR, "PLD %x %x\n", test_data,
1149 read);
1150 return HPI6000_ERROR_INIT_PLDTEST1;
1151 }
1152 test_data = 0x55555500L & mask;
1153 hpi_write_word(pdo, PLD_BASE_ADDRESS + 4L, test_data);
1154 read = hpi_read_word(pdo,
1155 PLD_BASE_ADDRESS + 4L) & mask;
1156 if (read != test_data) {
1157 HPI_DEBUG_LOG(ERROR, "PLD %x %x\n", test_data,
1158 read);
1159 return HPI6000_ERROR_INIT_PLDTEST2;
1160 }
1161 }
1162 } /* for numDSP */
1163 return 0;
1164}
1165
1166#define PCI_TIMEOUT 100
1167
1168static int hpi_set_address(struct dsp_obj *pdo, u32 address)
1169{
1170 u32 timeout = PCI_TIMEOUT;
1171
1172 do {
1173 iowrite32(address, pdo->prHPI_address);
1174 } while (hpi6000_check_PCI2040_error_flag(pdo->pa_parent_adapter,
1175 H6WRITE)
1176 && --timeout);
1177
1178 if (timeout)
1179 return 0;
1180
1181 return 1;
1182}
1183
1184/* write one word to the HPI port */
1185static void hpi_write_word(struct dsp_obj *pdo, u32 address, u32 data)
1186{
1187 if (hpi_set_address(pdo, address))
1188 return;
1189 iowrite32(data, pdo->prHPI_data);
1190}
1191
1192/* read one word from the HPI port */
1193static u32 hpi_read_word(struct dsp_obj *pdo, u32 address)
1194{
1195 u32 data = 0;
1196
1197 if (hpi_set_address(pdo, address))
1198 return 0; /*? no way to return error */
1199
1200 /* take care of errata in revB DSP (2.0.1) */
1201 data = ioread32(pdo->prHPI_data);
1202 return data;
1203}
1204
1205/* write a block of 32bit words to the DSP HPI port using auto-inc mode */
1206static void hpi_write_block(struct dsp_obj *pdo, u32 address, u32 *pdata,
1207 u32 length)
1208{
1209 u16 length16 = length - 1;
1210
1211 if (length == 0)
1212 return;
1213
1214 if (hpi_set_address(pdo, address))
1215 return;
1216
1217 iowrite32_rep(pdo->prHPI_data_auto_inc, pdata, length16);
1218
1219 /* take care of errata in revB DSP (2.0.1) */
1220 /* must end with non auto-inc */
1221 iowrite32(*(pdata + length - 1), pdo->prHPI_data);
1222}
1223
1224/** read a block of 32bit words from the DSP HPI port using auto-inc mode
1225 */
1226static void hpi_read_block(struct dsp_obj *pdo, u32 address, u32 *pdata,
1227 u32 length)
1228{
1229 u16 length16 = length - 1;
1230
1231 if (length == 0)
1232 return;
1233
1234 if (hpi_set_address(pdo, address))
1235 return;
1236
1237 ioread32_rep(pdo->prHPI_data_auto_inc, pdata, length16);
1238
1239 /* take care of errata in revB DSP (2.0.1) */
1240 /* must end with non auto-inc */
1241 *(pdata + length - 1) = ioread32(pdo->prHPI_data);
1242}
1243
1244static u16 hpi6000_dsp_block_write32(struct hpi_adapter_obj *pao,
1245 u16 dsp_index, u32 hpi_address, u32 *source, u32 count)
1246{
1247 struct dsp_obj *pdo =
1248 &(*(struct hpi_hw_obj *)pao->priv).ado[dsp_index];
1249 u32 time_out = PCI_TIMEOUT;
1250 int c6711_burst_size = 128;
1251 u32 local_hpi_address = hpi_address;
1252 int local_count = count;
1253 int xfer_size;
1254 u32 *pdata = source;
1255
1256 while (local_count) {
1257 if (local_count > c6711_burst_size)
1258 xfer_size = c6711_burst_size;
1259 else
1260 xfer_size = local_count;
1261
1262 time_out = PCI_TIMEOUT;
1263 do {
1264 hpi_write_block(pdo, local_hpi_address, pdata,
1265 xfer_size);
1266 } while (hpi6000_check_PCI2040_error_flag(pao, H6WRITE)
1267 && --time_out);
1268
1269 if (!time_out)
1270 break;
1271 pdata += xfer_size;
1272 local_hpi_address += sizeof(u32) * xfer_size;
1273 local_count -= xfer_size;
1274 }
1275
1276 if (time_out)
1277 return 0;
1278 else
1279 return 1;
1280}
1281
1282static u16 hpi6000_dsp_block_read32(struct hpi_adapter_obj *pao,
1283 u16 dsp_index, u32 hpi_address, u32 *dest, u32 count)
1284{
1285 struct dsp_obj *pdo =
1286 &(*(struct hpi_hw_obj *)pao->priv).ado[dsp_index];
1287 u32 time_out = PCI_TIMEOUT;
1288 int c6711_burst_size = 16;
1289 u32 local_hpi_address = hpi_address;
1290 int local_count = count;
1291 int xfer_size;
1292 u32 *pdata = dest;
1293 u32 loop_count = 0;
1294
1295 while (local_count) {
1296 if (local_count > c6711_burst_size)
1297 xfer_size = c6711_burst_size;
1298 else
1299 xfer_size = local_count;
1300
1301 time_out = PCI_TIMEOUT;
1302 do {
1303 hpi_read_block(pdo, local_hpi_address, pdata,
1304 xfer_size);
1305 } while (hpi6000_check_PCI2040_error_flag(pao, H6READ)
1306 && --time_out);
1307 if (!time_out)
1308 break;
1309
1310 pdata += xfer_size;
1311 local_hpi_address += sizeof(u32) * xfer_size;
1312 local_count -= xfer_size;
1313 loop_count++;
1314 }
1315
1316 if (time_out)
1317 return 0;
1318 else
1319 return 1;
1320}
1321
1322static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao,
1323 u16 dsp_index, struct hpi_message *phm, struct hpi_response *phr)
1324{
1325 struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv;
1326 struct dsp_obj *pdo = &phw->ado[dsp_index];
1327 u32 timeout;
1328 u16 ack;
1329 u32 address;
1330 u32 length;
1331 u32 *p_data;
1332 u16 error = 0;
1333
1334 /* does the DSP we are referencing exist? */
1335 if (dsp_index >= phw->num_dsp)
1336 return HPI6000_ERROR_MSG_INVALID_DSP_INDEX;
1337
1338 ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_IDLE);
1339 if (ack & HPI_HIF_ERROR_MASK) {
1340 pao->dsp_crashed++;
1341 return HPI6000_ERROR_MSG_RESP_IDLE_TIMEOUT;
1342 }
1343 pao->dsp_crashed = 0;
1344
1345 /* send the message */
1346
1347 /* get the address and size */
1348 if (phw->message_buffer_address_on_dsp == 0) {
1349 timeout = TIMEOUT;
1350 do {
1351 address =
1352 hpi_read_word(pdo,
1353 HPI_HIF_ADDR(message_buffer_address));
1354 phw->message_buffer_address_on_dsp = address;
1355 } while (hpi6000_check_PCI2040_error_flag(pao, H6READ)
1356 && --timeout);
1357 if (!timeout)
1358 return HPI6000_ERROR_MSG_GET_ADR;
1359 } else
1360 address = phw->message_buffer_address_on_dsp;
1361
1362 /* dwLength = sizeof(struct hpi_message); */
1363 length = phm->size;
1364
1365 /* send it */
1366 p_data = (u32 *)phm;
1367 if (hpi6000_dsp_block_write32(pao, dsp_index, address, p_data,
1368 (u16)length / 4))
1369 return HPI6000_ERROR_MSG_RESP_BLOCKWRITE32;
1370
1371 if (hpi6000_send_host_command(pao, dsp_index, HPI_HIF_GET_RESP))
1372 return HPI6000_ERROR_MSG_RESP_GETRESPCMD;
1373 hpi6000_send_dsp_interrupt(pdo);
1374
1375 ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_GET_RESP);
1376 if (ack & HPI_HIF_ERROR_MASK)
1377 return HPI6000_ERROR_MSG_RESP_GET_RESP_ACK;
1378
1379 /* get the address and size */
1380 if (phw->response_buffer_address_on_dsp == 0) {
1381 timeout = TIMEOUT;
1382 do {
1383 address =
1384 hpi_read_word(pdo,
1385 HPI_HIF_ADDR(response_buffer_address));
1386 } while (hpi6000_check_PCI2040_error_flag(pao, H6READ)
1387 && --timeout);
1388 phw->response_buffer_address_on_dsp = address;
1389
1390 if (!timeout)
1391 return HPI6000_ERROR_RESP_GET_ADR;
1392 } else
1393 address = phw->response_buffer_address_on_dsp;
1394
1395 /* read the length of the response back from the DSP */
1396 timeout = TIMEOUT;
1397 do {
1398 length = hpi_read_word(pdo, HPI_HIF_ADDR(length));
1399 } while (hpi6000_check_PCI2040_error_flag(pao, H6READ) && --timeout);
1400 if (!timeout)
1401 length = sizeof(struct hpi_response);
1402
1403 /* get it */
1404 p_data = (u32 *)phr;
1405 if (hpi6000_dsp_block_read32(pao, dsp_index, address, p_data,
1406 (u16)length / 4))
1407 return HPI6000_ERROR_MSG_RESP_BLOCKREAD32;
1408
1409 /* set i/f back to idle */
1410 if (hpi6000_send_host_command(pao, dsp_index, HPI_HIF_IDLE))
1411 return HPI6000_ERROR_MSG_RESP_IDLECMD;
1412 hpi6000_send_dsp_interrupt(pdo);
1413
1414 error = hpi_validate_response(phm, phr);
1415 return error;
1416}
1417
1418/* have to set up the below defines to match stuff in the MAP file */
1419
1420#define MSG_ADDRESS (HPI_HIF_BASE+0x18)
1421#define MSG_LENGTH 11
1422#define RESP_ADDRESS (HPI_HIF_BASE+0x44)
1423#define RESP_LENGTH 16
1424#define QUEUE_START (HPI_HIF_BASE+0x88)
1425#define QUEUE_SIZE 0x8000
1426
1427static short hpi6000_send_data_check_adr(u32 address, u32 length_in_dwords)
1428{
1429/*#define CHECKING // comment this line in to enable checking */
1430#ifdef CHECKING
1431 if (address < (u32)MSG_ADDRESS)
1432 return 0;
1433 if (address > (u32)(QUEUE_START + QUEUE_SIZE))
1434 return 0;
1435 if ((address + (length_in_dwords << 2)) >
1436 (u32)(QUEUE_START + QUEUE_SIZE))
1437 return 0;
1438#else
1439 (void)address;
1440 (void)length_in_dwords;
1441 return 1;
1442#endif
1443}
1444
1445static short hpi6000_send_data(struct hpi_adapter_obj *pao, u16 dsp_index,
1446 struct hpi_message *phm, struct hpi_response *phr)
1447{
1448 struct dsp_obj *pdo =
1449 &(*(struct hpi_hw_obj *)pao->priv).ado[dsp_index];
1450 u32 data_sent = 0;
1451 u16 ack;
1452 u32 length, address;
1453 u32 *p_data = (u32 *)phm->u.d.u.data.pb_data;
1454 u16 time_out = 8;
1455
1456 (void)phr;
1457
1458 /* round dwDataSize down to nearest 4 bytes */
1459 while ((data_sent < (phm->u.d.u.data.data_size & ~3L))
1460 && --time_out) {
1461 ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_IDLE);
1462 if (ack & HPI_HIF_ERROR_MASK)
1463 return HPI6000_ERROR_SEND_DATA_IDLE_TIMEOUT;
1464
1465 if (hpi6000_send_host_command(pao, dsp_index,
1466 HPI_HIF_SEND_DATA))
1467 return HPI6000_ERROR_SEND_DATA_CMD;
1468
1469 hpi6000_send_dsp_interrupt(pdo);
1470
1471 ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_SEND_DATA);
1472
1473 if (ack & HPI_HIF_ERROR_MASK)
1474 return HPI6000_ERROR_SEND_DATA_ACK;
1475
1476 do {
1477 /* get the address and size */
1478 address = hpi_read_word(pdo, HPI_HIF_ADDR(address));
1479 /* DSP returns number of DWORDS */
1480 length = hpi_read_word(pdo, HPI_HIF_ADDR(length));
1481 } while (hpi6000_check_PCI2040_error_flag(pao, H6READ));
1482
1483 if (!hpi6000_send_data_check_adr(address, length))
1484 return HPI6000_ERROR_SEND_DATA_ADR;
1485
1486 /* send the data. break data into 512 DWORD blocks (2K bytes)
1487 * and send using block write. 2Kbytes is the max as this is the
1488 * memory window given to the HPI data register by the PCI2040
1489 */
1490
1491 {
1492 u32 len = length;
1493 u32 blk_len = 512;
1494 while (len) {
1495 if (len < blk_len)
1496 blk_len = len;
1497 if (hpi6000_dsp_block_write32(pao, dsp_index,
1498 address, p_data, blk_len))
1499 return HPI6000_ERROR_SEND_DATA_WRITE;
1500 address += blk_len * 4;
1501 p_data += blk_len;
1502 len -= blk_len;
1503 }
1504 }
1505
1506 if (hpi6000_send_host_command(pao, dsp_index, HPI_HIF_IDLE))
1507 return HPI6000_ERROR_SEND_DATA_IDLECMD;
1508
1509 hpi6000_send_dsp_interrupt(pdo);
1510
1511 data_sent += length * 4;
1512 }
1513 if (!time_out)
1514 return HPI6000_ERROR_SEND_DATA_TIMEOUT;
1515 return 0;
1516}
1517
1518static short hpi6000_get_data(struct hpi_adapter_obj *pao, u16 dsp_index,
1519 struct hpi_message *phm, struct hpi_response *phr)
1520{
1521 struct dsp_obj *pdo =
1522 &(*(struct hpi_hw_obj *)pao->priv).ado[dsp_index];
1523 u32 data_got = 0;
1524 u16 ack;
1525 u32 length, address;
1526 u32 *p_data = (u32 *)phm->u.d.u.data.pb_data;
1527
1528 (void)phr; /* this parameter not used! */
1529
1530 /* round dwDataSize down to nearest 4 bytes */
1531 while (data_got < (phm->u.d.u.data.data_size & ~3L)) {
1532 ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_IDLE);
1533 if (ack & HPI_HIF_ERROR_MASK)
1534 return HPI6000_ERROR_GET_DATA_IDLE_TIMEOUT;
1535
1536 if (hpi6000_send_host_command(pao, dsp_index,
1537 HPI_HIF_GET_DATA))
1538 return HPI6000_ERROR_GET_DATA_CMD;
1539 hpi6000_send_dsp_interrupt(pdo);
1540
1541 ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_GET_DATA);
1542
1543 if (ack & HPI_HIF_ERROR_MASK)
1544 return HPI6000_ERROR_GET_DATA_ACK;
1545
1546 /* get the address and size */
1547 do {
1548 address = hpi_read_word(pdo, HPI_HIF_ADDR(address));
1549 length = hpi_read_word(pdo, HPI_HIF_ADDR(length));
1550 } while (hpi6000_check_PCI2040_error_flag(pao, H6READ));
1551
1552 /* read the data */
1553 {
1554 u32 len = length;
1555 u32 blk_len = 512;
1556 while (len) {
1557 if (len < blk_len)
1558 blk_len = len;
1559 if (hpi6000_dsp_block_read32(pao, dsp_index,
1560 address, p_data, blk_len))
1561 return HPI6000_ERROR_GET_DATA_READ;
1562 address += blk_len * 4;
1563 p_data += blk_len;
1564 len -= blk_len;
1565 }
1566 }
1567
1568 if (hpi6000_send_host_command(pao, dsp_index, HPI_HIF_IDLE))
1569 return HPI6000_ERROR_GET_DATA_IDLECMD;
1570 hpi6000_send_dsp_interrupt(pdo);
1571
1572 data_got += length * 4;
1573 }
1574 return 0;
1575}
1576
1577static void hpi6000_send_dsp_interrupt(struct dsp_obj *pdo)
1578{
1579 iowrite32(0x00030003, pdo->prHPI_control); /* DSPINT */
1580}
1581
1582static short hpi6000_send_host_command(struct hpi_adapter_obj *pao,
1583 u16 dsp_index, u32 host_cmd)
1584{
1585 struct dsp_obj *pdo =
1586 &(*(struct hpi_hw_obj *)pao->priv).ado[dsp_index];
1587 u32 timeout = TIMEOUT;
1588
1589 /* set command */
1590 do {
1591 hpi_write_word(pdo, HPI_HIF_ADDR(host_cmd), host_cmd);
1592 /* flush the FIFO */
1593 hpi_set_address(pdo, HPI_HIF_ADDR(host_cmd));
1594 } while (hpi6000_check_PCI2040_error_flag(pao, H6WRITE) && --timeout);
1595
1596 /* reset the interrupt bit */
1597 iowrite32(0x00040004, pdo->prHPI_control);
1598
1599 if (timeout)
1600 return 0;
1601 else
1602 return 1;
1603}
1604
1605/* if the PCI2040 has recorded an HPI timeout, reset the error and return 1 */
1606static short hpi6000_check_PCI2040_error_flag(struct hpi_adapter_obj *pao,
1607 u16 read_or_write)
1608{
1609 u32 hPI_error;
1610
1611 struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv;
1612
1613 /* read the error bits from the PCI2040 */
1614 hPI_error = ioread32(phw->dw2040_HPICSR + HPI_ERROR_REPORT);
1615 if (hPI_error) {
1616 /* reset the error flag */
1617 iowrite32(0L, phw->dw2040_HPICSR + HPI_ERROR_REPORT);
1618 phw->pCI2040HPI_error_count++;
1619 if (read_or_write == 1)
1620 gw_pci_read_asserts++; /************* inc global */
1621 else
1622 gw_pci_write_asserts++;
1623 return 1;
1624 } else
1625 return 0;
1626}
1627
1628static short hpi6000_wait_dsp_ack(struct hpi_adapter_obj *pao, u16 dsp_index,
1629 u32 ack_value)
1630{
1631 struct dsp_obj *pdo =
1632 &(*(struct hpi_hw_obj *)pao->priv).ado[dsp_index];
1633 u32 ack = 0L;
1634 u32 timeout;
1635 u32 hPIC = 0L;
1636
1637 /* wait for host interrupt to signal ack is ready */
1638 timeout = TIMEOUT;
1639 while (--timeout) {
1640 hPIC = ioread32(pdo->prHPI_control);
1641 if (hPIC & 0x04) /* 0x04 = HINT from DSP */
1642 break;
1643 }
1644 if (timeout == 0)
1645 return HPI_HIF_ERROR_MASK;
1646
1647 /* wait for dwAckValue */
1648 timeout = TIMEOUT;
1649 while (--timeout) {
1650 /* read the ack mailbox */
1651 ack = hpi_read_word(pdo, HPI_HIF_ADDR(dsp_ack));
1652 if (ack == ack_value)
1653 break;
1654 if ((ack & HPI_HIF_ERROR_MASK)
1655 && !hpi6000_check_PCI2040_error_flag(pao, H6READ))
1656 break;
1657 /*for (i=0;i<1000;i++) */
1658 /* dwPause=i+1; */
1659 }
1660 if (ack & HPI_HIF_ERROR_MASK)
1661 /* indicates bad read from DSP -
1662 typically 0xffffff is read for some reason */
1663 ack = HPI_HIF_ERROR_MASK;
1664
1665 if (timeout == 0)
1666 ack = HPI_HIF_ERROR_MASK;
1667 return (short)ack;
1668}
1669
1670static short hpi6000_update_control_cache(struct hpi_adapter_obj *pao,
1671 struct hpi_message *phm)
1672{
1673 const u16 dsp_index = 0;
1674 struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv;
1675 struct dsp_obj *pdo = &phw->ado[dsp_index];
1676 u32 timeout;
1677 u32 cache_dirty_flag;
1678 u16 err;
1679
1680 hpios_dsplock_lock(pao);
1681
1682 timeout = TIMEOUT;
1683 do {
1684 cache_dirty_flag =
1685 hpi_read_word((struct dsp_obj *)pdo,
1686 HPI_HIF_ADDR(control_cache_is_dirty));
1687 } while (hpi6000_check_PCI2040_error_flag(pao, H6READ) && --timeout);
1688 if (!timeout) {
1689 err = HPI6000_ERROR_CONTROL_CACHE_PARAMS;
1690 goto unlock;
1691 }
1692
1693 if (cache_dirty_flag) {
1694 /* read the cached controls */
1695 u32 address;
1696 u32 length;
1697
1698 timeout = TIMEOUT;
1699 if (pdo->control_cache_address_on_dsp == 0) {
1700 do {
1701 address =
1702 hpi_read_word((struct dsp_obj *)pdo,
1703 HPI_HIF_ADDR(control_cache_address));
1704
1705 length = hpi_read_word((struct dsp_obj *)pdo,
1706 HPI_HIF_ADDR
1707 (control_cache_size_in_bytes));
1708 } while (hpi6000_check_PCI2040_error_flag(pao, H6READ)
1709 && --timeout);
1710 if (!timeout) {
1711 err = HPI6000_ERROR_CONTROL_CACHE_ADDRLEN;
1712 goto unlock;
1713 }
1714 pdo->control_cache_address_on_dsp = address;
1715 pdo->control_cache_length_on_dsp = length;
1716 } else {
1717 address = pdo->control_cache_address_on_dsp;
1718 length = pdo->control_cache_length_on_dsp;
1719 }
1720
1721 if (hpi6000_dsp_block_read32(pao, dsp_index, address,
1722 (u32 *)&phw->control_cache[0],
1723 length / sizeof(u32))) {
1724 err = HPI6000_ERROR_CONTROL_CACHE_READ;
1725 goto unlock;
1726 }
1727 do {
1728 hpi_write_word((struct dsp_obj *)pdo,
1729 HPI_HIF_ADDR(control_cache_is_dirty), 0);
1730 /* flush the FIFO */
1731 hpi_set_address(pdo, HPI_HIF_ADDR(host_cmd));
1732 } while (hpi6000_check_PCI2040_error_flag(pao, H6WRITE)
1733 && --timeout);
1734 if (!timeout) {
1735 err = HPI6000_ERROR_CONTROL_CACHE_FLUSH;
1736 goto unlock;
1737 }
1738
1739 }
1740 err = 0;
1741
1742unlock:
1743 hpios_dsplock_unlock(pao);
1744 return err;
1745}
1746
1747/** Get dsp index for multi DSP adapters only */
1748static u16 get_dsp_index(struct hpi_adapter_obj *pao, struct hpi_message *phm)
1749{
1750 u16 ret = 0;
1751 switch (phm->object) {
1752 case HPI_OBJ_ISTREAM:
1753 if (phm->obj_index < 2)
1754 ret = 1;
1755 break;
1756 case HPI_OBJ_PROFILE:
1757 ret = phm->obj_index;
1758 break;
1759 default:
1760 break;
1761 }
1762 return ret;
1763}
1764
1765/** Complete transaction with DSP
1766
1767Send message, get response, send or get stream data if any.
1768*/
1769static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
1770 struct hpi_response *phr)
1771{
1772 u16 error = 0;
1773 u16 dsp_index = 0;
1774 u16 num_dsp = ((struct hpi_hw_obj *)pao->priv)->num_dsp;
1775
1776 if (num_dsp < 2)
1777 dsp_index = 0;
1778 else {
1779 dsp_index = get_dsp_index(pao, phm);
1780
1781 /* is this checked on the DSP anyway? */
1782 if ((phm->function == HPI_ISTREAM_GROUP_ADD)
1783 || (phm->function == HPI_OSTREAM_GROUP_ADD)) {
1784 struct hpi_message hm;
1785 u16 add_index;
1786 hm.obj_index = phm->u.d.u.stream.stream_index;
1787 hm.object = phm->u.d.u.stream.object_type;
1788 add_index = get_dsp_index(pao, &hm);
1789 if (add_index != dsp_index) {
1790 phr->error = HPI_ERROR_NO_INTERDSP_GROUPS;
1791 return;
1792 }
1793 }
1794 }
1795
1796 hpios_dsplock_lock(pao);
1797 error = hpi6000_message_response_sequence(pao, dsp_index, phm, phr);
1798
1799 /* maybe an error response */
1800 if (error) {
1801 /* something failed in the HPI/DSP interface */
1802 phr->error = error;
1803 /* just the header of the response is valid */
1804 phr->size = sizeof(struct hpi_response_header);
1805 goto err;
1806 }
1807
1808 if (phr->error != 0) /* something failed in the DSP */
1809 goto err;
1810
1811 switch (phm->function) {
1812 case HPI_OSTREAM_WRITE:
1813 case HPI_ISTREAM_ANC_WRITE:
1814 error = hpi6000_send_data(pao, dsp_index, phm, phr);
1815 break;
1816 case HPI_ISTREAM_READ:
1817 case HPI_OSTREAM_ANC_READ:
1818 error = hpi6000_get_data(pao, dsp_index, phm, phr);
1819 break;
1820 case HPI_ADAPTER_GET_ASSERT:
1821 phr->u.a.adapter_index = 0; /* dsp 0 default */
1822 if (num_dsp == 2) {
1823 if (!phr->u.a.adapter_type) {
1824 /* no assert from dsp 0, check dsp 1 */
1825 error = hpi6000_message_response_sequence(pao,
1826 1, phm, phr);
1827 phr->u.a.adapter_index = 1;
1828 }
1829 }
1830 }
1831
1832 if (error)
1833 phr->error = error;
1834
1835err:
1836 hpios_dsplock_unlock(pao);
1837 return;
1838}
diff --git a/sound/pci/asihpi/hpi6000.h b/sound/pci/asihpi/hpi6000.h
new file mode 100644
index 000000000000..4c7d507c0ecd
--- /dev/null
+++ b/sound/pci/asihpi/hpi6000.h
@@ -0,0 +1,70 @@
1/*****************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
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, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19Public declarations for DSP Proramming Interface to TI C6701
20
21Shared between hpi6000.c and DSP code
22
23(C) Copyright AudioScience Inc. 1998-2003
24******************************************************************************/
25
26#ifndef _HPI6000_H_
27#define _HPI6000_H_
28
29#define HPI_NMIXER_CONTROLS 200
30
31/*
32 * Control caching is always supported in the HPI code.
33 * The DSP should make sure that dwControlCacheSizeInBytes is initialized to 0
34 * during boot to make it in-active.
35 */
36struct hpi_hif_6000 {
37 u32 host_cmd;
38 u32 dsp_ack;
39 u32 address;
40 u32 length;
41 u32 message_buffer_address;
42 u32 response_buffer_address;
43 u32 dsp_number;
44 u32 adapter_info;
45 u32 control_cache_is_dirty;
46 u32 control_cache_address;
47 u32 control_cache_size_in_bytes;
48 u32 control_cache_count;
49};
50
51#define HPI_HIF_PACK_ADAPTER_INFO(adapter, version_major, version_minor) \
52 ((adapter << 16) | (version_major << 8) | version_minor)
53#define HPI_HIF_ADAPTER_INFO_EXTRACT_ADAPTER(adapterinfo) \
54 ((adapterinfo >> 16) & 0xffff)
55#define HPI_HIF_ADAPTER_INFO_EXTRACT_HWVERSION_MAJOR(adapterinfo) \
56 ((adapterinfo >> 8) & 0xff)
57#define HPI_HIF_ADAPTER_INFO_EXTRACT_HWVERSION_MINOR(adapterinfo) \
58 (adapterinfo & 0xff)
59
60/* Command/status exchanged between host and DSP */
61#define HPI_HIF_IDLE 0
62#define HPI_HIF_SEND_MSG 1
63#define HPI_HIF_GET_RESP 2
64#define HPI_HIF_DATA_MASK 0x10
65#define HPI_HIF_SEND_DATA 0x13
66#define HPI_HIF_GET_DATA 0x14
67#define HPI_HIF_SEND_DONE 5
68#define HPI_HIF_RESET 9
69
70#endif /* _HPI6000_H_ */
diff --git a/sound/pci/asihpi/hpi6205.c b/sound/pci/asihpi/hpi6205.c
new file mode 100644
index 000000000000..e89991ea3543
--- /dev/null
+++ b/sound/pci/asihpi/hpi6205.c
@@ -0,0 +1,2326 @@
1/******************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
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, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19 Hardware Programming Interface (HPI) for AudioScience
20 ASI50xx, AS51xx, ASI6xxx, ASI87xx ASI89xx series adapters.
21 These PCI and PCIe bus adapters are based on a
22 TMS320C6205 PCI bus mastering DSP,
23 and (except ASI50xx) TI TMS320C6xxx floating point DSP
24
25 Exported function:
26 void HPI_6205(struct hpi_message *phm, struct hpi_response *phr)
27
28(C) Copyright AudioScience Inc. 1998-2010
29*******************************************************************************/
30#define SOURCEFILE_NAME "hpi6205.c"
31
32#include "hpi_internal.h"
33#include "hpimsginit.h"
34#include "hpidebug.h"
35#include "hpi6205.h"
36#include "hpidspcd.h"
37#include "hpicmn.h"
38
39/*****************************************************************************/
40/* HPI6205 specific error codes */
41#define HPI6205_ERROR_BASE 1000
42/*#define HPI6205_ERROR_MEM_ALLOC 1001 */
43#define HPI6205_ERROR_6205_NO_IRQ 1002
44#define HPI6205_ERROR_6205_INIT_FAILED 1003
45/*#define HPI6205_ERROR_MISSING_DSPCODE 1004 */
46#define HPI6205_ERROR_UNKNOWN_PCI_DEVICE 1005
47#define HPI6205_ERROR_6205_REG 1006
48#define HPI6205_ERROR_6205_DSPPAGE 1007
49#define HPI6205_ERROR_BAD_DSPINDEX 1008
50#define HPI6205_ERROR_C6713_HPIC 1009
51#define HPI6205_ERROR_C6713_HPIA 1010
52#define HPI6205_ERROR_C6713_PLL 1011
53#define HPI6205_ERROR_DSP_INTMEM 1012
54#define HPI6205_ERROR_DSP_EXTMEM 1013
55#define HPI6205_ERROR_DSP_PLD 1014
56#define HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT 1015
57#define HPI6205_ERROR_MSG_RESP_TIMEOUT 1016
58#define HPI6205_ERROR_6205_EEPROM 1017
59#define HPI6205_ERROR_DSP_EMIF 1018
60
61#define hpi6205_error(dsp_index, err) (err)
62/*****************************************************************************/
63/* for C6205 PCI i/f */
64/* Host Status Register (HSR) bitfields */
65#define C6205_HSR_INTSRC 0x01
66#define C6205_HSR_INTAVAL 0x02
67#define C6205_HSR_INTAM 0x04
68#define C6205_HSR_CFGERR 0x08
69#define C6205_HSR_EEREAD 0x10
70/* Host-to-DSP Control Register (HDCR) bitfields */
71#define C6205_HDCR_WARMRESET 0x01
72#define C6205_HDCR_DSPINT 0x02
73#define C6205_HDCR_PCIBOOT 0x04
74/* DSP Page Register (DSPP) bitfields, */
75/* defines 4 Mbyte page that BAR0 points to */
76#define C6205_DSPP_MAP1 0x400
77
78/* BAR0 maps to prefetchable 4 Mbyte memory block set by DSPP.
79 * BAR1 maps to non-prefetchable 8 Mbyte memory block
80 * of DSP memory mapped registers (starting at 0x01800000).
81 * 0x01800000 is hardcoded in the PCI i/f, so that only the offset from this
82 * needs to be added to the BAR1 base address set in the PCI config reg
83 */
84#define C6205_BAR1_PCI_IO_OFFSET (0x027FFF0L)
85#define C6205_BAR1_HSR (C6205_BAR1_PCI_IO_OFFSET)
86#define C6205_BAR1_HDCR (C6205_BAR1_PCI_IO_OFFSET+4)
87#define C6205_BAR1_DSPP (C6205_BAR1_PCI_IO_OFFSET+8)
88
89/* used to control LED (revA) and reset C6713 (revB) */
90#define C6205_BAR0_TIMER1_CTL (0x01980000L)
91
92/* For first 6713 in CE1 space, using DA17,16,2 */
93#define HPICL_ADDR 0x01400000L
94#define HPICH_ADDR 0x01400004L
95#define HPIAL_ADDR 0x01410000L
96#define HPIAH_ADDR 0x01410004L
97#define HPIDIL_ADDR 0x01420000L
98#define HPIDIH_ADDR 0x01420004L
99#define HPIDL_ADDR 0x01430000L
100#define HPIDH_ADDR 0x01430004L
101
102#define C6713_EMIF_GCTL 0x01800000
103#define C6713_EMIF_CE1 0x01800004
104#define C6713_EMIF_CE0 0x01800008
105#define C6713_EMIF_CE2 0x01800010
106#define C6713_EMIF_CE3 0x01800014
107#define C6713_EMIF_SDRAMCTL 0x01800018
108#define C6713_EMIF_SDRAMTIMING 0x0180001C
109#define C6713_EMIF_SDRAMEXT 0x01800020
110
111struct hpi_hw_obj {
112 /* PCI registers */
113 __iomem u32 *prHSR;
114 __iomem u32 *prHDCR;
115 __iomem u32 *prDSPP;
116
117 u32 dsp_page;
118
119 struct consistent_dma_area h_locked_mem;
120 struct bus_master_interface *p_interface_buffer;
121
122 u16 flag_outstream_just_reset[HPI_MAX_STREAMS];
123 /* a non-NULL handle means there is an HPI allocated buffer */
124 struct consistent_dma_area instream_host_buffers[HPI_MAX_STREAMS];
125 struct consistent_dma_area outstream_host_buffers[HPI_MAX_STREAMS];
126 /* non-zero size means a buffer exists, may be external */
127 u32 instream_host_buffer_size[HPI_MAX_STREAMS];
128 u32 outstream_host_buffer_size[HPI_MAX_STREAMS];
129
130 struct consistent_dma_area h_control_cache;
131 struct consistent_dma_area h_async_event_buffer;
132/* struct hpi_control_cache_single *pControlCache; */
133 struct hpi_async_event *p_async_event_buffer;
134 struct hpi_control_cache *p_cache;
135};
136
137/*****************************************************************************/
138/* local prototypes */
139
140#define check_before_bbm_copy(status, p_bbm_data, l_first_write, l_second_write)
141
142static int wait_dsp_ack(struct hpi_hw_obj *phw, int state, int timeout_us);
143
144static void send_dsp_command(struct hpi_hw_obj *phw, int cmd);
145
146static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
147 u32 *pos_error_code);
148
149static u16 message_response_sequence(struct hpi_adapter_obj *pao,
150 struct hpi_message *phm, struct hpi_response *phr);
151
152static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
153 struct hpi_response *phr);
154
155#define HPI6205_TIMEOUT 1000000
156
157static void subsys_create_adapter(struct hpi_message *phm,
158 struct hpi_response *phr);
159static void subsys_delete_adapter(struct hpi_message *phm,
160 struct hpi_response *phr);
161
162static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
163 u32 *pos_error_code);
164
165static void delete_adapter_obj(struct hpi_adapter_obj *pao);
166
167static void outstream_host_buffer_allocate(struct hpi_adapter_obj *pao,
168 struct hpi_message *phm, struct hpi_response *phr);
169
170static void outstream_host_buffer_get_info(struct hpi_adapter_obj *pao,
171 struct hpi_message *phm, struct hpi_response *phr);
172
173static void outstream_host_buffer_free(struct hpi_adapter_obj *pao,
174 struct hpi_message *phm, struct hpi_response *phr);
175static void outstream_write(struct hpi_adapter_obj *pao,
176 struct hpi_message *phm, struct hpi_response *phr);
177
178static void outstream_get_info(struct hpi_adapter_obj *pao,
179 struct hpi_message *phm, struct hpi_response *phr);
180
181static void outstream_start(struct hpi_adapter_obj *pao,
182 struct hpi_message *phm, struct hpi_response *phr);
183
184static void outstream_open(struct hpi_adapter_obj *pao,
185 struct hpi_message *phm, struct hpi_response *phr);
186
187static void outstream_reset(struct hpi_adapter_obj *pao,
188 struct hpi_message *phm, struct hpi_response *phr);
189
190static void instream_host_buffer_allocate(struct hpi_adapter_obj *pao,
191 struct hpi_message *phm, struct hpi_response *phr);
192
193static void instream_host_buffer_get_info(struct hpi_adapter_obj *pao,
194 struct hpi_message *phm, struct hpi_response *phr);
195
196static void instream_host_buffer_free(struct hpi_adapter_obj *pao,
197 struct hpi_message *phm, struct hpi_response *phr);
198
199static void instream_read(struct hpi_adapter_obj *pao,
200 struct hpi_message *phm, struct hpi_response *phr);
201
202static void instream_get_info(struct hpi_adapter_obj *pao,
203 struct hpi_message *phm, struct hpi_response *phr);
204
205static void instream_start(struct hpi_adapter_obj *pao,
206 struct hpi_message *phm, struct hpi_response *phr);
207
208static u32 boot_loader_read_mem32(struct hpi_adapter_obj *pao, int dsp_index,
209 u32 address);
210
211static u16 boot_loader_write_mem32(struct hpi_adapter_obj *pao, int dsp_index,
212 u32 address, u32 data);
213
214static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao,
215 int dsp_index);
216
217static u16 boot_loader_test_memory(struct hpi_adapter_obj *pao, int dsp_index,
218 u32 address, u32 length);
219
220static u16 boot_loader_test_internal_memory(struct hpi_adapter_obj *pao,
221 int dsp_index);
222
223static u16 boot_loader_test_external_memory(struct hpi_adapter_obj *pao,
224 int dsp_index);
225
226static u16 boot_loader_test_pld(struct hpi_adapter_obj *pao, int dsp_index);
227
228/*****************************************************************************/
229
230static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
231{
232
233 switch (phm->function) {
234 case HPI_SUBSYS_OPEN:
235 case HPI_SUBSYS_CLOSE:
236 case HPI_SUBSYS_GET_INFO:
237 case HPI_SUBSYS_DRIVER_UNLOAD:
238 case HPI_SUBSYS_DRIVER_LOAD:
239 case HPI_SUBSYS_FIND_ADAPTERS:
240 /* messages that should not get here */
241 phr->error = HPI_ERROR_UNIMPLEMENTED;
242 break;
243 case HPI_SUBSYS_CREATE_ADAPTER:
244 subsys_create_adapter(phm, phr);
245 break;
246 case HPI_SUBSYS_DELETE_ADAPTER:
247 subsys_delete_adapter(phm, phr);
248 break;
249 default:
250 phr->error = HPI_ERROR_INVALID_FUNC;
251 break;
252 }
253}
254
255static void control_message(struct hpi_adapter_obj *pao,
256 struct hpi_message *phm, struct hpi_response *phr)
257{
258
259 struct hpi_hw_obj *phw = pao->priv;
260
261 switch (phm->function) {
262 case HPI_CONTROL_GET_STATE:
263 if (pao->has_control_cache) {
264 rmb(); /* make sure we see updates DM_aed from DSP */
265 if (hpi_check_control_cache(phw->p_cache, phm, phr))
266 break;
267 }
268 hw_message(pao, phm, phr);
269 break;
270 case HPI_CONTROL_GET_INFO:
271 hw_message(pao, phm, phr);
272 break;
273 case HPI_CONTROL_SET_STATE:
274 hw_message(pao, phm, phr);
275 if (pao->has_control_cache)
276 hpi_sync_control_cache(phw->p_cache, phm, phr);
277 break;
278 default:
279 phr->error = HPI_ERROR_INVALID_FUNC;
280 break;
281 }
282}
283
284static void adapter_message(struct hpi_adapter_obj *pao,
285 struct hpi_message *phm, struct hpi_response *phr)
286{
287 switch (phm->function) {
288 default:
289 hw_message(pao, phm, phr);
290 break;
291 }
292}
293
294static void outstream_message(struct hpi_adapter_obj *pao,
295 struct hpi_message *phm, struct hpi_response *phr)
296{
297
298 if (phm->obj_index >= HPI_MAX_STREAMS) {
299 phr->error = HPI_ERROR_INVALID_STREAM;
300 HPI_DEBUG_LOG(WARNING,
301 "message referencing invalid stream %d "
302 "on adapter index %d\n", phm->obj_index,
303 phm->adapter_index);
304 return;
305 }
306
307 switch (phm->function) {
308 case HPI_OSTREAM_WRITE:
309 outstream_write(pao, phm, phr);
310 break;
311 case HPI_OSTREAM_GET_INFO:
312 outstream_get_info(pao, phm, phr);
313 break;
314 case HPI_OSTREAM_HOSTBUFFER_ALLOC:
315 outstream_host_buffer_allocate(pao, phm, phr);
316 break;
317 case HPI_OSTREAM_HOSTBUFFER_GET_INFO:
318 outstream_host_buffer_get_info(pao, phm, phr);
319 break;
320 case HPI_OSTREAM_HOSTBUFFER_FREE:
321 outstream_host_buffer_free(pao, phm, phr);
322 break;
323 case HPI_OSTREAM_START:
324 outstream_start(pao, phm, phr);
325 break;
326 case HPI_OSTREAM_OPEN:
327 outstream_open(pao, phm, phr);
328 break;
329 case HPI_OSTREAM_RESET:
330 outstream_reset(pao, phm, phr);
331 break;
332 default:
333 hw_message(pao, phm, phr);
334 break;
335 }
336}
337
338static void instream_message(struct hpi_adapter_obj *pao,
339 struct hpi_message *phm, struct hpi_response *phr)
340{
341
342 if (phm->obj_index >= HPI_MAX_STREAMS) {
343 phr->error = HPI_ERROR_INVALID_STREAM;
344 HPI_DEBUG_LOG(WARNING,
345 "message referencing invalid stream %d "
346 "on adapter index %d\n", phm->obj_index,
347 phm->adapter_index);
348 return;
349 }
350
351 switch (phm->function) {
352 case HPI_ISTREAM_READ:
353 instream_read(pao, phm, phr);
354 break;
355 case HPI_ISTREAM_GET_INFO:
356 instream_get_info(pao, phm, phr);
357 break;
358 case HPI_ISTREAM_HOSTBUFFER_ALLOC:
359 instream_host_buffer_allocate(pao, phm, phr);
360 break;
361 case HPI_ISTREAM_HOSTBUFFER_GET_INFO:
362 instream_host_buffer_get_info(pao, phm, phr);
363 break;
364 case HPI_ISTREAM_HOSTBUFFER_FREE:
365 instream_host_buffer_free(pao, phm, phr);
366 break;
367 case HPI_ISTREAM_START:
368 instream_start(pao, phm, phr);
369 break;
370 default:
371 hw_message(pao, phm, phr);
372 break;
373 }
374}
375
376/*****************************************************************************/
377/** Entry point to this HPI backend
378 * All calls to the HPI start here
379 */
380void HPI_6205(struct hpi_message *phm, struct hpi_response *phr)
381{
382 struct hpi_adapter_obj *pao = NULL;
383
384 /* subsytem messages are processed by every HPI.
385 * All other messages are ignored unless the adapter index matches
386 * an adapter in the HPI
387 */
388 HPI_DEBUG_LOG(DEBUG, "HPI obj=%d, func=%d\n", phm->object,
389 phm->function);
390
391 /* if Dsp has crashed then do not communicate with it any more */
392 if (phm->object != HPI_OBJ_SUBSYSTEM) {
393 pao = hpi_find_adapter(phm->adapter_index);
394 if (!pao) {
395 HPI_DEBUG_LOG(DEBUG,
396 " %d,%d refused, for another HPI?\n",
397 phm->object, phm->function);
398 return;
399 }
400
401 if ((pao->dsp_crashed >= 10)
402 && (phm->function != HPI_ADAPTER_DEBUG_READ)) {
403 /* allow last resort debug read even after crash */
404 hpi_init_response(phr, phm->object, phm->function,
405 HPI_ERROR_DSP_HARDWARE);
406 HPI_DEBUG_LOG(WARNING, " %d,%d dsp crashed.\n",
407 phm->object, phm->function);
408 return;
409 }
410 }
411
412 /* Init default response */
413 if (phm->function != HPI_SUBSYS_CREATE_ADAPTER)
414 hpi_init_response(phr, phm->object, phm->function,
415 HPI_ERROR_PROCESSING_MESSAGE);
416
417 HPI_DEBUG_LOG(VERBOSE, "start of switch\n");
418 switch (phm->type) {
419 case HPI_TYPE_MESSAGE:
420 switch (phm->object) {
421 case HPI_OBJ_SUBSYSTEM:
422 subsys_message(phm, phr);
423 break;
424
425 case HPI_OBJ_ADAPTER:
426 phr->size =
427 sizeof(struct hpi_response_header) +
428 sizeof(struct hpi_adapter_res);
429 adapter_message(pao, phm, phr);
430 break;
431
432 case HPI_OBJ_CONTROLEX:
433 case HPI_OBJ_CONTROL:
434 control_message(pao, phm, phr);
435 break;
436
437 case HPI_OBJ_OSTREAM:
438 outstream_message(pao, phm, phr);
439 break;
440
441 case HPI_OBJ_ISTREAM:
442 instream_message(pao, phm, phr);
443 break;
444
445 default:
446 hw_message(pao, phm, phr);
447 break;
448 }
449 break;
450
451 default:
452 phr->error = HPI_ERROR_INVALID_TYPE;
453 break;
454 }
455}
456
457/*****************************************************************************/
458/* SUBSYSTEM */
459
460/** Create an adapter object and initialise it based on resource information
461 * passed in in the message
462 * *** NOTE - you cannot use this function AND the FindAdapters function at the
463 * same time, the application must use only one of them to get the adapters ***
464 */
465static void subsys_create_adapter(struct hpi_message *phm,
466 struct hpi_response *phr)
467{
468 /* create temp adapter obj, because we don't know what index yet */
469 struct hpi_adapter_obj ao;
470 u32 os_error_code;
471 u16 err;
472
473 HPI_DEBUG_LOG(DEBUG, " subsys_create_adapter\n");
474
475 memset(&ao, 0, sizeof(ao));
476
477 /* this HPI only creates adapters for TI/PCI devices */
478 if (phm->u.s.resource.bus_type != HPI_BUS_PCI)
479 return;
480 if (phm->u.s.resource.r.pci->vendor_id != HPI_PCI_VENDOR_ID_TI)
481 return;
482 if (phm->u.s.resource.r.pci->device_id != HPI_PCI_DEV_ID_DSP6205)
483 return;
484
485 ao.priv = kzalloc(sizeof(struct hpi_hw_obj), GFP_KERNEL);
486 if (!ao.priv) {
487 HPI_DEBUG_LOG(ERROR, "cant get mem for adapter object\n");
488 phr->error = HPI_ERROR_MEMORY_ALLOC;
489 return;
490 }
491
492 ao.pci = *phm->u.s.resource.r.pci;
493 err = create_adapter_obj(&ao, &os_error_code);
494 if (!err)
495 err = hpi_add_adapter(&ao);
496 if (err) {
497 phr->u.s.data = os_error_code;
498 delete_adapter_obj(&ao);
499 phr->error = err;
500 return;
501 }
502
503 phr->u.s.aw_adapter_list[ao.index] = ao.adapter_type;
504 phr->u.s.adapter_index = ao.index;
505 phr->u.s.num_adapters++;
506 phr->error = 0;
507}
508
509/** delete an adapter - required by WDM driver */
510static void subsys_delete_adapter(struct hpi_message *phm,
511 struct hpi_response *phr)
512{
513 struct hpi_adapter_obj *pao;
514 struct hpi_hw_obj *phw;
515
516 pao = hpi_find_adapter(phm->adapter_index);
517 if (!pao) {
518 phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
519 return;
520 }
521 phw = (struct hpi_hw_obj *)pao->priv;
522 /* reset adapter h/w */
523 /* Reset C6713 #1 */
524 boot_loader_write_mem32(pao, 0, C6205_BAR0_TIMER1_CTL, 0);
525 /* reset C6205 */
526 iowrite32(C6205_HDCR_WARMRESET, phw->prHDCR);
527
528 delete_adapter_obj(pao);
529 phr->error = 0;
530}
531
532/** Create adapter object
533 allocate buffers, bootload DSPs, initialise control cache
534*/
535static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
536 u32 *pos_error_code)
537{
538 struct hpi_hw_obj *phw = pao->priv;
539 struct bus_master_interface *interface;
540 u32 phys_addr;
541#ifndef HPI6205_NO_HSR_POLL
542 u32 time_out = HPI6205_TIMEOUT;
543 u32 temp1;
544#endif
545 int i;
546 u16 err;
547
548 /* init error reporting */
549 pao->dsp_crashed = 0;
550
551 for (i = 0; i < HPI_MAX_STREAMS; i++)
552 phw->flag_outstream_just_reset[i] = 1;
553
554 /* The C6205 memory area 1 is 8Mbyte window into DSP registers */
555 phw->prHSR =
556 pao->pci.ap_mem_base[1] +
557 C6205_BAR1_HSR / sizeof(*pao->pci.ap_mem_base[1]);
558 phw->prHDCR =
559 pao->pci.ap_mem_base[1] +
560 C6205_BAR1_HDCR / sizeof(*pao->pci.ap_mem_base[1]);
561 phw->prDSPP =
562 pao->pci.ap_mem_base[1] +
563 C6205_BAR1_DSPP / sizeof(*pao->pci.ap_mem_base[1]);
564
565 pao->has_control_cache = 0;
566
567 if (hpios_locked_mem_alloc(&phw->h_locked_mem,
568 sizeof(struct bus_master_interface),
569 pao->pci.p_os_data))
570 phw->p_interface_buffer = NULL;
571 else if (hpios_locked_mem_get_virt_addr(&phw->h_locked_mem,
572 (void *)&phw->p_interface_buffer))
573 phw->p_interface_buffer = NULL;
574
575 HPI_DEBUG_LOG(DEBUG, "interface buffer address %p\n",
576 phw->p_interface_buffer);
577
578 if (phw->p_interface_buffer) {
579 memset((void *)phw->p_interface_buffer, 0,
580 sizeof(struct bus_master_interface));
581 phw->p_interface_buffer->dsp_ack = H620_HIF_UNKNOWN;
582 }
583
584 err = adapter_boot_load_dsp(pao, pos_error_code);
585 if (err)
586 /* no need to clean up as SubSysCreateAdapter */
587 /* calls DeleteAdapter on error. */
588 return err;
589
590 HPI_DEBUG_LOG(INFO, "load DSP code OK\n");
591
592 /* allow boot load even if mem alloc wont work */
593 if (!phw->p_interface_buffer)
594 return hpi6205_error(0, HPI_ERROR_MEMORY_ALLOC);
595
596 interface = phw->p_interface_buffer;
597
598#ifndef HPI6205_NO_HSR_POLL
599 /* wait for first interrupt indicating the DSP init is done */
600 time_out = HPI6205_TIMEOUT * 10;
601 temp1 = 0;
602 while (((temp1 & C6205_HSR_INTSRC) == 0) && --time_out)
603 temp1 = ioread32(phw->prHSR);
604
605 if (temp1 & C6205_HSR_INTSRC)
606 HPI_DEBUG_LOG(INFO,
607 "interrupt confirming DSP code running OK\n");
608 else {
609 HPI_DEBUG_LOG(ERROR,
610 "timed out waiting for interrupt "
611 "confirming DSP code running\n");
612 return hpi6205_error(0, HPI6205_ERROR_6205_NO_IRQ);
613 }
614
615 /* reset the interrupt */
616 iowrite32(C6205_HSR_INTSRC, phw->prHSR);
617#endif
618
619 /* make sure the DSP has started ok */
620 if (!wait_dsp_ack(phw, H620_HIF_RESET, HPI6205_TIMEOUT * 10)) {
621 HPI_DEBUG_LOG(ERROR, "timed out waiting reset state \n");
622 return hpi6205_error(0, HPI6205_ERROR_6205_INIT_FAILED);
623 }
624 /* Note that *pao, *phw are zeroed after allocation,
625 * so pointers and flags are NULL by default.
626 * Allocate bus mastering control cache buffer and tell the DSP about it
627 */
628 if (interface->control_cache.number_of_controls) {
629 void *p_control_cache_virtual;
630
631 err = hpios_locked_mem_alloc(&phw->h_control_cache,
632 interface->control_cache.size_in_bytes,
633 pao->pci.p_os_data);
634 if (!err)
635 err = hpios_locked_mem_get_virt_addr(&phw->
636 h_control_cache, &p_control_cache_virtual);
637 if (!err) {
638 memset(p_control_cache_virtual, 0,
639 interface->control_cache.size_in_bytes);
640
641 phw->p_cache =
642 hpi_alloc_control_cache(interface->
643 control_cache.number_of_controls,
644 interface->control_cache.size_in_bytes,
645 (struct hpi_control_cache_info *)
646 p_control_cache_virtual);
647 }
648 if (!err) {
649 err = hpios_locked_mem_get_phys_addr(&phw->
650 h_control_cache, &phys_addr);
651 interface->control_cache.physical_address32 =
652 phys_addr;
653 }
654
655 if (!err)
656 pao->has_control_cache = 1;
657 else {
658 if (hpios_locked_mem_valid(&phw->h_control_cache))
659 hpios_locked_mem_free(&phw->h_control_cache);
660 pao->has_control_cache = 0;
661 }
662 }
663 /* allocate bus mastering async buffer and tell the DSP about it */
664 if (interface->async_buffer.b.size) {
665 err = hpios_locked_mem_alloc(&phw->h_async_event_buffer,
666 interface->async_buffer.b.size *
667 sizeof(struct hpi_async_event), pao->pci.p_os_data);
668 if (!err)
669 err = hpios_locked_mem_get_virt_addr
670 (&phw->h_async_event_buffer, (void *)
671 &phw->p_async_event_buffer);
672 if (!err)
673 memset((void *)phw->p_async_event_buffer, 0,
674 interface->async_buffer.b.size *
675 sizeof(struct hpi_async_event));
676 if (!err) {
677 err = hpios_locked_mem_get_phys_addr
678 (&phw->h_async_event_buffer, &phys_addr);
679 interface->async_buffer.physical_address32 =
680 phys_addr;
681 }
682 if (err) {
683 if (hpios_locked_mem_valid(&phw->
684 h_async_event_buffer)) {
685 hpios_locked_mem_free
686 (&phw->h_async_event_buffer);
687 phw->p_async_event_buffer = NULL;
688 }
689 }
690 }
691 send_dsp_command(phw, H620_HIF_IDLE);
692
693 {
694 struct hpi_message hM;
695 struct hpi_response hR;
696 u32 max_streams;
697
698 HPI_DEBUG_LOG(VERBOSE, "init ADAPTER_GET_INFO\n");
699 memset(&hM, 0, sizeof(hM));
700 hM.type = HPI_TYPE_MESSAGE;
701 hM.size = sizeof(hM);
702 hM.object = HPI_OBJ_ADAPTER;
703 hM.function = HPI_ADAPTER_GET_INFO;
704 hM.adapter_index = 0;
705 memset(&hR, 0, sizeof(hR));
706 hR.size = sizeof(hR);
707
708 err = message_response_sequence(pao, &hM, &hR);
709 if (err) {
710 HPI_DEBUG_LOG(ERROR, "message transport error %d\n",
711 err);
712 return err;
713 }
714 if (hR.error)
715 return hR.error;
716
717 pao->adapter_type = hR.u.a.adapter_type;
718 pao->index = hR.u.a.adapter_index;
719
720 max_streams = hR.u.a.num_outstreams + hR.u.a.num_instreams;
721
722 hpios_locked_mem_prepare((max_streams * 6) / 10, max_streams,
723 65536, pao->pci.p_os_data);
724
725 HPI_DEBUG_LOG(VERBOSE,
726 "got adapter info type %x index %d serial %d\n",
727 hR.u.a.adapter_type, hR.u.a.adapter_index,
728 hR.u.a.serial_number);
729 }
730
731 pao->open = 0; /* upon creation the adapter is closed */
732
733 HPI_DEBUG_LOG(INFO, "bootload DSP OK\n");
734 return 0;
735}
736
737/** Free memory areas allocated by adapter
738 * this routine is called from SubSysDeleteAdapter,
739 * and SubSysCreateAdapter if duplicate index
740*/
741static void delete_adapter_obj(struct hpi_adapter_obj *pao)
742{
743 struct hpi_hw_obj *phw;
744 int i;
745
746 phw = pao->priv;
747
748 if (hpios_locked_mem_valid(&phw->h_async_event_buffer)) {
749 hpios_locked_mem_free(&phw->h_async_event_buffer);
750 phw->p_async_event_buffer = NULL;
751 }
752
753 if (hpios_locked_mem_valid(&phw->h_control_cache)) {
754 hpios_locked_mem_free(&phw->h_control_cache);
755 hpi_free_control_cache(phw->p_cache);
756 }
757
758 if (hpios_locked_mem_valid(&phw->h_locked_mem)) {
759 hpios_locked_mem_free(&phw->h_locked_mem);
760 phw->p_interface_buffer = NULL;
761 }
762
763 for (i = 0; i < HPI_MAX_STREAMS; i++)
764 if (hpios_locked_mem_valid(&phw->instream_host_buffers[i])) {
765 hpios_locked_mem_free(&phw->instream_host_buffers[i]);
766 /*?phw->InStreamHostBuffers[i] = NULL; */
767 phw->instream_host_buffer_size[i] = 0;
768 }
769
770 for (i = 0; i < HPI_MAX_STREAMS; i++)
771 if (hpios_locked_mem_valid(&phw->outstream_host_buffers[i])) {
772 hpios_locked_mem_free(&phw->outstream_host_buffers
773 [i]);
774 phw->outstream_host_buffer_size[i] = 0;
775 }
776
777 hpios_locked_mem_unprepare(pao->pci.p_os_data);
778
779 hpi_delete_adapter(pao);
780 kfree(phw);
781}
782
783/*****************************************************************************/
784/* OutStream Host buffer functions */
785
786/** Allocate or attach buffer for busmastering
787*/
788static void outstream_host_buffer_allocate(struct hpi_adapter_obj *pao,
789 struct hpi_message *phm, struct hpi_response *phr)
790{
791 u16 err = 0;
792 u32 command = phm->u.d.u.buffer.command;
793 struct hpi_hw_obj *phw = pao->priv;
794 struct bus_master_interface *interface = phw->p_interface_buffer;
795
796 hpi_init_response(phr, phm->object, phm->function, 0);
797
798 if (command == HPI_BUFFER_CMD_EXTERNAL
799 || command == HPI_BUFFER_CMD_INTERNAL_ALLOC) {
800 /* ALLOC phase, allocate a buffer with power of 2 size,
801 get its bus address for PCI bus mastering
802 */
803 phm->u.d.u.buffer.buffer_size =
804 roundup_pow_of_two(phm->u.d.u.buffer.buffer_size);
805 /* return old size and allocated size,
806 so caller can detect change */
807 phr->u.d.u.stream_info.data_available =
808 phw->outstream_host_buffer_size[phm->obj_index];
809 phr->u.d.u.stream_info.buffer_size =
810 phm->u.d.u.buffer.buffer_size;
811
812 if (phw->outstream_host_buffer_size[phm->obj_index] ==
813 phm->u.d.u.buffer.buffer_size) {
814 /* Same size, no action required */
815 return;
816 }
817
818 if (hpios_locked_mem_valid(&phw->outstream_host_buffers[phm->
819 obj_index]))
820 hpios_locked_mem_free(&phw->outstream_host_buffers
821 [phm->obj_index]);
822
823 err = hpios_locked_mem_alloc(&phw->outstream_host_buffers
824 [phm->obj_index], phm->u.d.u.buffer.buffer_size,
825 pao->pci.p_os_data);
826
827 if (err) {
828 phr->error = HPI_ERROR_INVALID_DATASIZE;
829 phw->outstream_host_buffer_size[phm->obj_index] = 0;
830 return;
831 }
832
833 err = hpios_locked_mem_get_phys_addr
834 (&phw->outstream_host_buffers[phm->obj_index],
835 &phm->u.d.u.buffer.pci_address);
836 /* get the phys addr into msg for single call alloc caller
837 * needs to do this for split alloc (or use the same message)
838 * return the phy address for split alloc in the respose too
839 */
840 phr->u.d.u.stream_info.auxiliary_data_available =
841 phm->u.d.u.buffer.pci_address;
842
843 if (err) {
844 hpios_locked_mem_free(&phw->outstream_host_buffers
845 [phm->obj_index]);
846 phw->outstream_host_buffer_size[phm->obj_index] = 0;
847 phr->error = HPI_ERROR_MEMORY_ALLOC;
848 return;
849 }
850 }
851
852 if (command == HPI_BUFFER_CMD_EXTERNAL
853 || command == HPI_BUFFER_CMD_INTERNAL_GRANTADAPTER) {
854 /* GRANT phase. Set up the BBM status, tell the DSP about
855 the buffer so it can start using BBM.
856 */
857 struct hpi_hostbuffer_status *status;
858
859 if (phm->u.d.u.buffer.buffer_size & (phm->u.d.u.buffer.
860 buffer_size - 1)) {
861 HPI_DEBUG_LOG(ERROR,
862 "buffer size must be 2^N not %d\n",
863 phm->u.d.u.buffer.buffer_size);
864 phr->error = HPI_ERROR_INVALID_DATASIZE;
865 return;
866 }
867 phw->outstream_host_buffer_size[phm->obj_index] =
868 phm->u.d.u.buffer.buffer_size;
869 status = &interface->outstream_host_buffer_status[phm->
870 obj_index];
871 status->samples_processed = 0;
872 status->stream_state = HPI_STATE_STOPPED;
873 status->dSP_index = 0;
874 status->host_index = status->dSP_index;
875 status->size_in_bytes = phm->u.d.u.buffer.buffer_size;
876
877 hw_message(pao, phm, phr);
878
879 if (phr->error
880 && hpios_locked_mem_valid(&phw->
881 outstream_host_buffers[phm->obj_index])) {
882 hpios_locked_mem_free(&phw->outstream_host_buffers
883 [phm->obj_index]);
884 phw->outstream_host_buffer_size[phm->obj_index] = 0;
885 }
886 }
887}
888
889static void outstream_host_buffer_get_info(struct hpi_adapter_obj *pao,
890 struct hpi_message *phm, struct hpi_response *phr)
891{
892 struct hpi_hw_obj *phw = pao->priv;
893 struct bus_master_interface *interface = phw->p_interface_buffer;
894 struct hpi_hostbuffer_status *status;
895 u8 *p_bbm_data;
896
897 if (hpios_locked_mem_valid(&phw->outstream_host_buffers[phm->
898 obj_index])) {
899 if (hpios_locked_mem_get_virt_addr(&phw->
900 outstream_host_buffers[phm->obj_index],
901 (void *)&p_bbm_data)) {
902 phr->error = HPI_ERROR_INVALID_OPERATION;
903 return;
904 }
905 status = &interface->outstream_host_buffer_status[phm->
906 obj_index];
907 hpi_init_response(phr, HPI_OBJ_OSTREAM,
908 HPI_OSTREAM_HOSTBUFFER_GET_INFO, 0);
909 phr->u.d.u.hostbuffer_info.p_buffer = p_bbm_data;
910 phr->u.d.u.hostbuffer_info.p_status = status;
911 } else {
912 hpi_init_response(phr, HPI_OBJ_OSTREAM,
913 HPI_OSTREAM_HOSTBUFFER_GET_INFO,
914 HPI_ERROR_INVALID_OPERATION);
915 }
916}
917
918static void outstream_host_buffer_free(struct hpi_adapter_obj *pao,
919 struct hpi_message *phm, struct hpi_response *phr)
920{
921 struct hpi_hw_obj *phw = pao->priv;
922 u32 command = phm->u.d.u.buffer.command;
923
924 if (phw->outstream_host_buffer_size[phm->obj_index]) {
925 if (command == HPI_BUFFER_CMD_EXTERNAL
926 || command == HPI_BUFFER_CMD_INTERNAL_REVOKEADAPTER) {
927 phw->outstream_host_buffer_size[phm->obj_index] = 0;
928 hw_message(pao, phm, phr);
929 /* Tell adapter to stop using the host buffer. */
930 }
931 if (command == HPI_BUFFER_CMD_EXTERNAL
932 || command == HPI_BUFFER_CMD_INTERNAL_FREE)
933 hpios_locked_mem_free(&phw->outstream_host_buffers
934 [phm->obj_index]);
935 }
936 /* Should HPI_ERROR_INVALID_OPERATION be returned
937 if no host buffer is allocated? */
938 else
939 hpi_init_response(phr, HPI_OBJ_OSTREAM,
940 HPI_OSTREAM_HOSTBUFFER_FREE, 0);
941
942}
943
944static long outstream_get_space_available(struct hpi_hostbuffer_status
945 *status)
946{
947 return status->size_in_bytes - ((long)(status->host_index) -
948 (long)(status->dSP_index));
949}
950
951static void outstream_write(struct hpi_adapter_obj *pao,
952 struct hpi_message *phm, struct hpi_response *phr)
953{
954 struct hpi_hw_obj *phw = pao->priv;
955 struct bus_master_interface *interface = phw->p_interface_buffer;
956 struct hpi_hostbuffer_status *status;
957 long space_available;
958
959 if (!phw->outstream_host_buffer_size[phm->obj_index]) {
960 /* there is no BBM buffer, write via message */
961 hw_message(pao, phm, phr);
962 return;
963 }
964
965 hpi_init_response(phr, phm->object, phm->function, 0);
966 status = &interface->outstream_host_buffer_status[phm->obj_index];
967
968 if (phw->flag_outstream_just_reset[phm->obj_index]) {
969 /* First OutStremWrite() call following reset will write data to the
970 adapter's buffers, reducing delay before stream can start. The DSP
971 takes care of setting the stream data format using format information
972 embedded in phm.
973 */
974 int partial_write = 0;
975 unsigned int original_size = 0;
976
977 phw->flag_outstream_just_reset[phm->obj_index] = 0;
978
979 /* Send the first buffer to the DSP the old way. */
980 /* Limit size of first transfer - */
981 /* expect that this will not usually be triggered. */
982 if (phm->u.d.u.data.data_size > HPI6205_SIZEOF_DATA) {
983 partial_write = 1;
984 original_size = phm->u.d.u.data.data_size;
985 phm->u.d.u.data.data_size = HPI6205_SIZEOF_DATA;
986 }
987 /* write it */
988 phm->function = HPI_OSTREAM_WRITE;
989 hw_message(pao, phm, phr);
990 /* update status information that the DSP would typically
991 * update (and will update next time the DSP
992 * buffer update task reads data from the host BBM buffer)
993 */
994 status->auxiliary_data_available = phm->u.d.u.data.data_size;
995 status->host_index += phm->u.d.u.data.data_size;
996 status->dSP_index += phm->u.d.u.data.data_size;
997
998 /* if we did a full write, we can return from here. */
999 if (!partial_write)
1000 return;
1001
1002 /* tweak buffer parameters and let the rest of the */
1003 /* buffer land in internal BBM buffer */
1004 phm->u.d.u.data.data_size =
1005 original_size - HPI6205_SIZEOF_DATA;
1006 phm->u.d.u.data.pb_data += HPI6205_SIZEOF_DATA;
1007 }
1008
1009 space_available = outstream_get_space_available(status);
1010 if (space_available < (long)phm->u.d.u.data.data_size) {
1011 phr->error = HPI_ERROR_INVALID_DATASIZE;
1012 return;
1013 }
1014
1015 /* HostBuffers is used to indicate host buffer is internally allocated.
1016 otherwise, assumed external, data written externally */
1017 if (phm->u.d.u.data.pb_data
1018 && hpios_locked_mem_valid(&phw->outstream_host_buffers[phm->
1019 obj_index])) {
1020 u8 *p_bbm_data;
1021 long l_first_write;
1022 u8 *p_app_data = (u8 *)phm->u.d.u.data.pb_data;
1023
1024 if (hpios_locked_mem_get_virt_addr(&phw->
1025 outstream_host_buffers[phm->obj_index],
1026 (void *)&p_bbm_data)) {
1027 phr->error = HPI_ERROR_INVALID_OPERATION;
1028 return;
1029 }
1030
1031 /* either all data,
1032 or enough to fit from current to end of BBM buffer */
1033 l_first_write =
1034 min(phm->u.d.u.data.data_size,
1035 status->size_in_bytes -
1036 (status->host_index & (status->size_in_bytes - 1)));
1037
1038 memcpy(p_bbm_data +
1039 (status->host_index & (status->size_in_bytes - 1)),
1040 p_app_data, l_first_write);
1041 /* remaining data if any */
1042 memcpy(p_bbm_data, p_app_data + l_first_write,
1043 phm->u.d.u.data.data_size - l_first_write);
1044 }
1045 status->host_index += phm->u.d.u.data.data_size;
1046}
1047
1048static void outstream_get_info(struct hpi_adapter_obj *pao,
1049 struct hpi_message *phm, struct hpi_response *phr)
1050{
1051 struct hpi_hw_obj *phw = pao->priv;
1052 struct bus_master_interface *interface = phw->p_interface_buffer;
1053 struct hpi_hostbuffer_status *status;
1054
1055 if (!phw->outstream_host_buffer_size[phm->obj_index]) {
1056 hw_message(pao, phm, phr);
1057 return;
1058 }
1059
1060 hpi_init_response(phr, phm->object, phm->function, 0);
1061
1062 status = &interface->outstream_host_buffer_status[phm->obj_index];
1063
1064 phr->u.d.u.stream_info.state = (u16)status->stream_state;
1065 phr->u.d.u.stream_info.samples_transferred =
1066 status->samples_processed;
1067 phr->u.d.u.stream_info.buffer_size = status->size_in_bytes;
1068 phr->u.d.u.stream_info.data_available =
1069 status->size_in_bytes - outstream_get_space_available(status);
1070 phr->u.d.u.stream_info.auxiliary_data_available =
1071 status->auxiliary_data_available;
1072}
1073
1074static void outstream_start(struct hpi_adapter_obj *pao,
1075 struct hpi_message *phm, struct hpi_response *phr)
1076{
1077 hw_message(pao, phm, phr);
1078}
1079
1080static void outstream_reset(struct hpi_adapter_obj *pao,
1081 struct hpi_message *phm, struct hpi_response *phr)
1082{
1083 struct hpi_hw_obj *phw = pao->priv;
1084 phw->flag_outstream_just_reset[phm->obj_index] = 1;
1085 hw_message(pao, phm, phr);
1086}
1087
1088static void outstream_open(struct hpi_adapter_obj *pao,
1089 struct hpi_message *phm, struct hpi_response *phr)
1090{
1091 outstream_reset(pao, phm, phr);
1092}
1093
1094/*****************************************************************************/
1095/* InStream Host buffer functions */
1096
1097static void instream_host_buffer_allocate(struct hpi_adapter_obj *pao,
1098 struct hpi_message *phm, struct hpi_response *phr)
1099{
1100 u16 err = 0;
1101 u32 command = phm->u.d.u.buffer.command;
1102 struct hpi_hw_obj *phw = pao->priv;
1103 struct bus_master_interface *interface = phw->p_interface_buffer;
1104
1105 hpi_init_response(phr, phm->object, phm->function, 0);
1106
1107 if (command == HPI_BUFFER_CMD_EXTERNAL
1108 || command == HPI_BUFFER_CMD_INTERNAL_ALLOC) {
1109
1110 phm->u.d.u.buffer.buffer_size =
1111 roundup_pow_of_two(phm->u.d.u.buffer.buffer_size);
1112 phr->u.d.u.stream_info.data_available =
1113 phw->instream_host_buffer_size[phm->obj_index];
1114 phr->u.d.u.stream_info.buffer_size =
1115 phm->u.d.u.buffer.buffer_size;
1116
1117 if (phw->instream_host_buffer_size[phm->obj_index] ==
1118 phm->u.d.u.buffer.buffer_size) {
1119 /* Same size, no action required */
1120 return;
1121 }
1122
1123 if (hpios_locked_mem_valid(&phw->instream_host_buffers[phm->
1124 obj_index]))
1125 hpios_locked_mem_free(&phw->instream_host_buffers
1126 [phm->obj_index]);
1127
1128 err = hpios_locked_mem_alloc(&phw->instream_host_buffers[phm->
1129 obj_index], phm->u.d.u.buffer.buffer_size,
1130 pao->pci.p_os_data);
1131
1132 if (err) {
1133 phr->error = HPI_ERROR_INVALID_DATASIZE;
1134 phw->instream_host_buffer_size[phm->obj_index] = 0;
1135 return;
1136 }
1137
1138 err = hpios_locked_mem_get_phys_addr
1139 (&phw->instream_host_buffers[phm->obj_index],
1140 &phm->u.d.u.buffer.pci_address);
1141 /* get the phys addr into msg for single call alloc. Caller
1142 needs to do this for split alloc so return the phy address */
1143 phr->u.d.u.stream_info.auxiliary_data_available =
1144 phm->u.d.u.buffer.pci_address;
1145 if (err) {
1146 hpios_locked_mem_free(&phw->instream_host_buffers
1147 [phm->obj_index]);
1148 phw->instream_host_buffer_size[phm->obj_index] = 0;
1149 phr->error = HPI_ERROR_MEMORY_ALLOC;
1150 return;
1151 }
1152 }
1153
1154 if (command == HPI_BUFFER_CMD_EXTERNAL
1155 || command == HPI_BUFFER_CMD_INTERNAL_GRANTADAPTER) {
1156 struct hpi_hostbuffer_status *status;
1157
1158 if (phm->u.d.u.buffer.buffer_size & (phm->u.d.u.buffer.
1159 buffer_size - 1)) {
1160 HPI_DEBUG_LOG(ERROR,
1161 "buffer size must be 2^N not %d\n",
1162 phm->u.d.u.buffer.buffer_size);
1163 phr->error = HPI_ERROR_INVALID_DATASIZE;
1164 return;
1165 }
1166
1167 phw->instream_host_buffer_size[phm->obj_index] =
1168 phm->u.d.u.buffer.buffer_size;
1169 status = &interface->instream_host_buffer_status[phm->
1170 obj_index];
1171 status->samples_processed = 0;
1172 status->stream_state = HPI_STATE_STOPPED;
1173 status->dSP_index = 0;
1174 status->host_index = status->dSP_index;
1175 status->size_in_bytes = phm->u.d.u.buffer.buffer_size;
1176
1177 hw_message(pao, phm, phr);
1178 if (phr->error
1179 && hpios_locked_mem_valid(&phw->
1180 instream_host_buffers[phm->obj_index])) {
1181 hpios_locked_mem_free(&phw->instream_host_buffers
1182 [phm->obj_index]);
1183 phw->instream_host_buffer_size[phm->obj_index] = 0;
1184 }
1185 }
1186}
1187
1188static void instream_host_buffer_get_info(struct hpi_adapter_obj *pao,
1189 struct hpi_message *phm, struct hpi_response *phr)
1190{
1191 struct hpi_hw_obj *phw = pao->priv;
1192 struct bus_master_interface *interface = phw->p_interface_buffer;
1193 struct hpi_hostbuffer_status *status;
1194 u8 *p_bbm_data;
1195
1196 if (hpios_locked_mem_valid(&phw->instream_host_buffers[phm->
1197 obj_index])) {
1198 if (hpios_locked_mem_get_virt_addr(&phw->
1199 instream_host_buffers[phm->obj_index],
1200 (void *)&p_bbm_data)) {
1201 phr->error = HPI_ERROR_INVALID_OPERATION;
1202 return;
1203 }
1204 status = &interface->instream_host_buffer_status[phm->
1205 obj_index];
1206 hpi_init_response(phr, HPI_OBJ_ISTREAM,
1207 HPI_ISTREAM_HOSTBUFFER_GET_INFO, 0);
1208 phr->u.d.u.hostbuffer_info.p_buffer = p_bbm_data;
1209 phr->u.d.u.hostbuffer_info.p_status = status;
1210 } else {
1211 hpi_init_response(phr, HPI_OBJ_ISTREAM,
1212 HPI_ISTREAM_HOSTBUFFER_GET_INFO,
1213 HPI_ERROR_INVALID_OPERATION);
1214 }
1215}
1216
1217static void instream_host_buffer_free(struct hpi_adapter_obj *pao,
1218 struct hpi_message *phm, struct hpi_response *phr)
1219{
1220 struct hpi_hw_obj *phw = pao->priv;
1221 u32 command = phm->u.d.u.buffer.command;
1222
1223 if (phw->instream_host_buffer_size[phm->obj_index]) {
1224 if (command == HPI_BUFFER_CMD_EXTERNAL
1225 || command == HPI_BUFFER_CMD_INTERNAL_REVOKEADAPTER) {
1226 phw->instream_host_buffer_size[phm->obj_index] = 0;
1227 hw_message(pao, phm, phr);
1228 }
1229
1230 if (command == HPI_BUFFER_CMD_EXTERNAL
1231 || command == HPI_BUFFER_CMD_INTERNAL_FREE)
1232 hpios_locked_mem_free(&phw->instream_host_buffers
1233 [phm->obj_index]);
1234
1235 } else {
1236 /* Should HPI_ERROR_INVALID_OPERATION be returned
1237 if no host buffer is allocated? */
1238 hpi_init_response(phr, HPI_OBJ_ISTREAM,
1239 HPI_ISTREAM_HOSTBUFFER_FREE, 0);
1240
1241 }
1242
1243}
1244
1245static void instream_start(struct hpi_adapter_obj *pao,
1246 struct hpi_message *phm, struct hpi_response *phr)
1247{
1248 hw_message(pao, phm, phr);
1249}
1250
1251static long instream_get_bytes_available(struct hpi_hostbuffer_status *status)
1252{
1253 return (long)(status->dSP_index) - (long)(status->host_index);
1254}
1255
1256static void instream_read(struct hpi_adapter_obj *pao,
1257 struct hpi_message *phm, struct hpi_response *phr)
1258{
1259 struct hpi_hw_obj *phw = pao->priv;
1260 struct bus_master_interface *interface = phw->p_interface_buffer;
1261 struct hpi_hostbuffer_status *status;
1262 long data_available;
1263 u8 *p_bbm_data;
1264 long l_first_read;
1265 u8 *p_app_data = (u8 *)phm->u.d.u.data.pb_data;
1266
1267 if (!phw->instream_host_buffer_size[phm->obj_index]) {
1268 hw_message(pao, phm, phr);
1269 return;
1270 }
1271 hpi_init_response(phr, phm->object, phm->function, 0);
1272
1273 status = &interface->instream_host_buffer_status[phm->obj_index];
1274 data_available = instream_get_bytes_available(status);
1275 if (data_available < (long)phm->u.d.u.data.data_size) {
1276 phr->error = HPI_ERROR_INVALID_DATASIZE;
1277 return;
1278 }
1279
1280 if (hpios_locked_mem_valid(&phw->instream_host_buffers[phm->
1281 obj_index])) {
1282 if (hpios_locked_mem_get_virt_addr(&phw->
1283 instream_host_buffers[phm->obj_index],
1284 (void *)&p_bbm_data)) {
1285 phr->error = HPI_ERROR_INVALID_OPERATION;
1286 return;
1287 }
1288
1289 /* either all data,
1290 or enough to fit from current to end of BBM buffer */
1291 l_first_read =
1292 min(phm->u.d.u.data.data_size,
1293 status->size_in_bytes -
1294 (status->host_index & (status->size_in_bytes - 1)));
1295
1296 memcpy(p_app_data,
1297 p_bbm_data +
1298 (status->host_index & (status->size_in_bytes - 1)),
1299 l_first_read);
1300 /* remaining data if any */
1301 memcpy(p_app_data + l_first_read, p_bbm_data,
1302 phm->u.d.u.data.data_size - l_first_read);
1303 }
1304 status->host_index += phm->u.d.u.data.data_size;
1305}
1306
1307static void instream_get_info(struct hpi_adapter_obj *pao,
1308 struct hpi_message *phm, struct hpi_response *phr)
1309{
1310 struct hpi_hw_obj *phw = pao->priv;
1311 struct bus_master_interface *interface = phw->p_interface_buffer;
1312 struct hpi_hostbuffer_status *status;
1313 if (!phw->instream_host_buffer_size[phm->obj_index]) {
1314 hw_message(pao, phm, phr);
1315 return;
1316 }
1317
1318 status = &interface->instream_host_buffer_status[phm->obj_index];
1319
1320 hpi_init_response(phr, phm->object, phm->function, 0);
1321
1322 phr->u.d.u.stream_info.state = (u16)status->stream_state;
1323 phr->u.d.u.stream_info.samples_transferred =
1324 status->samples_processed;
1325 phr->u.d.u.stream_info.buffer_size = status->size_in_bytes;
1326 phr->u.d.u.stream_info.data_available =
1327 instream_get_bytes_available(status);
1328 phr->u.d.u.stream_info.auxiliary_data_available =
1329 status->auxiliary_data_available;
1330}
1331
1332/*****************************************************************************/
1333/* LOW-LEVEL */
1334#define HPI6205_MAX_FILES_TO_LOAD 2
1335
1336static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
1337 u32 *pos_error_code)
1338{
1339 struct hpi_hw_obj *phw = pao->priv;
1340 struct dsp_code dsp_code;
1341 u16 boot_code_id[HPI6205_MAX_FILES_TO_LOAD];
1342 u16 firmware_id = pao->pci.subsys_device_id;
1343 u32 temp;
1344 int dsp = 0, i = 0;
1345 u16 err = 0;
1346
1347 boot_code_id[0] = HPI_ADAPTER_ASI(0x6205);
1348
1349 /* special cases where firmware_id != subsys ID */
1350 switch (firmware_id) {
1351 case HPI_ADAPTER_FAMILY_ASI(0x5000):
1352 boot_code_id[0] = firmware_id;
1353 firmware_id = 0;
1354 break;
1355 case HPI_ADAPTER_FAMILY_ASI(0x5300):
1356 case HPI_ADAPTER_FAMILY_ASI(0x5400):
1357 case HPI_ADAPTER_FAMILY_ASI(0x6300):
1358 firmware_id = HPI_ADAPTER_FAMILY_ASI(0x6400);
1359 break;
1360 case HPI_ADAPTER_FAMILY_ASI(0x5600):
1361 case HPI_ADAPTER_FAMILY_ASI(0x6500):
1362 firmware_id = HPI_ADAPTER_FAMILY_ASI(0x6600);
1363 break;
1364 case HPI_ADAPTER_FAMILY_ASI(0x8800):
1365 firmware_id = HPI_ADAPTER_FAMILY_ASI(0x8900);
1366 break;
1367 }
1368 boot_code_id[1] = firmware_id;
1369
1370 /* reset DSP by writing a 1 to the WARMRESET bit */
1371 temp = C6205_HDCR_WARMRESET;
1372 iowrite32(temp, phw->prHDCR);
1373 hpios_delay_micro_seconds(1000);
1374
1375 /* check that PCI i/f was configured by EEPROM */
1376 temp = ioread32(phw->prHSR);
1377 if ((temp & (C6205_HSR_CFGERR | C6205_HSR_EEREAD)) !=
1378 C6205_HSR_EEREAD)
1379 return hpi6205_error(0, HPI6205_ERROR_6205_EEPROM);
1380 temp |= 0x04;
1381 /* disable PINTA interrupt */
1382 iowrite32(temp, phw->prHSR);
1383
1384 /* check control register reports PCI boot mode */
1385 temp = ioread32(phw->prHDCR);
1386 if (!(temp & C6205_HDCR_PCIBOOT))
1387 return hpi6205_error(0, HPI6205_ERROR_6205_REG);
1388
1389 /* try writing a couple of numbers to the DSP page register */
1390 /* and reading them back. */
1391 temp = 1;
1392 iowrite32(temp, phw->prDSPP);
1393 if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
1394 return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE);
1395 temp = 2;
1396 iowrite32(temp, phw->prDSPP);
1397 if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
1398 return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE);
1399 temp = 3;
1400 iowrite32(temp, phw->prDSPP);
1401 if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
1402 return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE);
1403 /* reset DSP page to the correct number */
1404 temp = 0;
1405 iowrite32(temp, phw->prDSPP);
1406 if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
1407 return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE);
1408 phw->dsp_page = 0;
1409
1410 /* release 6713 from reset before 6205 is bootloaded.
1411 This ensures that the EMIF is inactive,
1412 and the 6713 HPI gets the correct bootmode etc
1413 */
1414 if (boot_code_id[1] != 0) {
1415 /* DSP 1 is a C6713 */
1416 /* CLKX0 <- '1' release the C6205 bootmode pulldowns */
1417 boot_loader_write_mem32(pao, 0, (0x018C0024L), 0x00002202);
1418 hpios_delay_micro_seconds(100);
1419 /* Reset the 6713 #1 - revB */
1420 boot_loader_write_mem32(pao, 0, C6205_BAR0_TIMER1_CTL, 0);
1421
1422 /* dummy read every 4 words for 6205 advisory 1.4.4 */
1423 boot_loader_read_mem32(pao, 0, 0);
1424
1425 hpios_delay_micro_seconds(100);
1426 /* Release C6713 from reset - revB */
1427 boot_loader_write_mem32(pao, 0, C6205_BAR0_TIMER1_CTL, 4);
1428 hpios_delay_micro_seconds(100);
1429 }
1430
1431 for (dsp = 0; dsp < HPI6205_MAX_FILES_TO_LOAD; dsp++) {
1432 /* is there a DSP to load? */
1433 if (boot_code_id[dsp] == 0)
1434 continue;
1435
1436 err = boot_loader_config_emif(pao, dsp);
1437 if (err)
1438 return err;
1439
1440 err = boot_loader_test_internal_memory(pao, dsp);
1441 if (err)
1442 return err;
1443
1444 err = boot_loader_test_external_memory(pao, dsp);
1445 if (err)
1446 return err;
1447
1448 err = boot_loader_test_pld(pao, dsp);
1449 if (err)
1450 return err;
1451
1452 /* write the DSP code down into the DSPs memory */
1453 dsp_code.ps_dev = pao->pci.p_os_data;
1454 err = hpi_dsp_code_open(boot_code_id[dsp], &dsp_code,
1455 pos_error_code);
1456 if (err)
1457 return err;
1458
1459 while (1) {
1460 u32 length;
1461 u32 address;
1462 u32 type;
1463 u32 *pcode;
1464
1465 err = hpi_dsp_code_read_word(&dsp_code, &length);
1466 if (err)
1467 break;
1468 if (length == 0xFFFFFFFF)
1469 break; /* end of code */
1470
1471 err = hpi_dsp_code_read_word(&dsp_code, &address);
1472 if (err)
1473 break;
1474 err = hpi_dsp_code_read_word(&dsp_code, &type);
1475 if (err)
1476 break;
1477 err = hpi_dsp_code_read_block(length, &dsp_code,
1478 &pcode);
1479 if (err)
1480 break;
1481 for (i = 0; i < (int)length; i++) {
1482 err = boot_loader_write_mem32(pao, dsp,
1483 address, *pcode);
1484 if (err)
1485 break;
1486 /* dummy read every 4 words */
1487 /* for 6205 advisory 1.4.4 */
1488 if (i % 4 == 0)
1489 boot_loader_read_mem32(pao, dsp,
1490 address);
1491 pcode++;
1492 address += 4;
1493 }
1494
1495 }
1496 if (err) {
1497 hpi_dsp_code_close(&dsp_code);
1498 return err;
1499 }
1500
1501 /* verify code */
1502 hpi_dsp_code_rewind(&dsp_code);
1503 while (1) {
1504 u32 length = 0;
1505 u32 address = 0;
1506 u32 type = 0;
1507 u32 *pcode = NULL;
1508 u32 data = 0;
1509
1510 hpi_dsp_code_read_word(&dsp_code, &length);
1511 if (length == 0xFFFFFFFF)
1512 break; /* end of code */
1513
1514 hpi_dsp_code_read_word(&dsp_code, &address);
1515 hpi_dsp_code_read_word(&dsp_code, &type);
1516 hpi_dsp_code_read_block(length, &dsp_code, &pcode);
1517
1518 for (i = 0; i < (int)length; i++) {
1519 data = boot_loader_read_mem32(pao, dsp,
1520 address);
1521 if (data != *pcode) {
1522 err = 0;
1523 break;
1524 }
1525 pcode++;
1526 address += 4;
1527 }
1528 if (err)
1529 break;
1530 }
1531 hpi_dsp_code_close(&dsp_code);
1532 if (err)
1533 return err;
1534 }
1535
1536 /* After bootloading all DSPs, start DSP0 running
1537 * The DSP0 code will handle starting and synchronizing with its slaves
1538 */
1539 if (phw->p_interface_buffer) {
1540 /* we need to tell the card the physical PCI address */
1541 u32 physicalPC_iaddress;
1542 struct bus_master_interface *interface =
1543 phw->p_interface_buffer;
1544 u32 host_mailbox_address_on_dsp;
1545 u32 physicalPC_iaddress_verify = 0;
1546 int time_out = 10;
1547 /* set ack so we know when DSP is ready to go */
1548 /* (dwDspAck will be changed to HIF_RESET) */
1549 interface->dsp_ack = H620_HIF_UNKNOWN;
1550 wmb(); /* ensure ack is written before dsp writes back */
1551
1552 err = hpios_locked_mem_get_phys_addr(&phw->h_locked_mem,
1553 &physicalPC_iaddress);
1554
1555 /* locate the host mailbox on the DSP. */
1556 host_mailbox_address_on_dsp = 0x80000000;
1557 while ((physicalPC_iaddress != physicalPC_iaddress_verify)
1558 && time_out--) {
1559 err = boot_loader_write_mem32(pao, 0,
1560 host_mailbox_address_on_dsp,
1561 physicalPC_iaddress);
1562 physicalPC_iaddress_verify =
1563 boot_loader_read_mem32(pao, 0,
1564 host_mailbox_address_on_dsp);
1565 }
1566 }
1567 HPI_DEBUG_LOG(DEBUG, "starting DS_ps running\n");
1568 /* enable interrupts */
1569 temp = ioread32(phw->prHSR);
1570 temp &= ~(u32)C6205_HSR_INTAM;
1571 iowrite32(temp, phw->prHSR);
1572
1573 /* start code running... */
1574 temp = ioread32(phw->prHDCR);
1575 temp |= (u32)C6205_HDCR_DSPINT;
1576 iowrite32(temp, phw->prHDCR);
1577
1578 /* give the DSP 10ms to start up */
1579 hpios_delay_micro_seconds(10000);
1580 return err;
1581
1582}
1583
1584/*****************************************************************************/
1585/* Bootloader utility functions */
1586
1587static u32 boot_loader_read_mem32(struct hpi_adapter_obj *pao, int dsp_index,
1588 u32 address)
1589{
1590 struct hpi_hw_obj *phw = pao->priv;
1591 u32 data = 0;
1592 __iomem u32 *p_data;
1593
1594 if (dsp_index == 0) {
1595 /* DSP 0 is always C6205 */
1596 if ((address >= 0x01800000) & (address < 0x02000000)) {
1597 /* BAR1 register access */
1598 p_data = pao->pci.ap_mem_base[1] +
1599 (address & 0x007fffff) /
1600 sizeof(*pao->pci.ap_mem_base[1]);
1601 /* HPI_DEBUG_LOG(WARNING,
1602 "BAR1 access %08x\n", dwAddress); */
1603 } else {
1604 u32 dw4M_page = address >> 22L;
1605 if (dw4M_page != phw->dsp_page) {
1606 phw->dsp_page = dw4M_page;
1607 /* *INDENT OFF* */
1608 iowrite32(phw->dsp_page, phw->prDSPP);
1609 /* *INDENT-ON* */
1610 }
1611 address &= 0x3fffff; /* address within 4M page */
1612 /* BAR0 memory access */
1613 p_data = pao->pci.ap_mem_base[0] +
1614 address / sizeof(u32);
1615 }
1616 data = ioread32(p_data);
1617 } else if (dsp_index == 1) {
1618 /* DSP 1 is a C6713 */
1619 u32 lsb;
1620 boot_loader_write_mem32(pao, 0, HPIAL_ADDR, address);
1621 boot_loader_write_mem32(pao, 0, HPIAH_ADDR, address >> 16);
1622 lsb = boot_loader_read_mem32(pao, 0, HPIDL_ADDR);
1623 data = boot_loader_read_mem32(pao, 0, HPIDH_ADDR);
1624 data = (data << 16) | (lsb & 0xFFFF);
1625 }
1626 return data;
1627}
1628
1629static u16 boot_loader_write_mem32(struct hpi_adapter_obj *pao, int dsp_index,
1630 u32 address, u32 data)
1631{
1632 struct hpi_hw_obj *phw = pao->priv;
1633 u16 err = 0;
1634 __iomem u32 *p_data;
1635 /* u32 dwVerifyData=0; */
1636
1637 if (dsp_index == 0) {
1638 /* DSP 0 is always C6205 */
1639 if ((address >= 0x01800000) & (address < 0x02000000)) {
1640 /* BAR1 - DSP register access using */
1641 /* Non-prefetchable PCI access */
1642 p_data = pao->pci.ap_mem_base[1] +
1643 (address & 0x007fffff) /
1644 sizeof(*pao->pci.ap_mem_base[1]);
1645 } else {
1646 /* BAR0 access - all of DSP memory using */
1647 /* pre-fetchable PCI access */
1648 u32 dw4M_page = address >> 22L;
1649 if (dw4M_page != phw->dsp_page) {
1650 phw->dsp_page = dw4M_page;
1651 /* *INDENT-OFF* */
1652 iowrite32(phw->dsp_page, phw->prDSPP);
1653 /* *INDENT-ON* */
1654 }
1655 address &= 0x3fffff; /* address within 4M page */
1656 p_data = pao->pci.ap_mem_base[0] +
1657 address / sizeof(u32);
1658 }
1659 iowrite32(data, p_data);
1660 } else if (dsp_index == 1) {
1661 /* DSP 1 is a C6713 */
1662 boot_loader_write_mem32(pao, 0, HPIAL_ADDR, address);
1663 boot_loader_write_mem32(pao, 0, HPIAH_ADDR, address >> 16);
1664
1665 /* dummy read every 4 words for 6205 advisory 1.4.4 */
1666 boot_loader_read_mem32(pao, 0, 0);
1667
1668 boot_loader_write_mem32(pao, 0, HPIDL_ADDR, data);
1669 boot_loader_write_mem32(pao, 0, HPIDH_ADDR, data >> 16);
1670
1671 /* dummy read every 4 words for 6205 advisory 1.4.4 */
1672 boot_loader_read_mem32(pao, 0, 0);
1673 } else
1674 err = hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX);
1675 return err;
1676}
1677
1678static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index)
1679{
1680 u16 err = 0;
1681
1682 if (dsp_index == 0) {
1683 u32 setting;
1684
1685 /* DSP 0 is always C6205 */
1686
1687 /* Set the EMIF */
1688 /* memory map of C6205 */
1689 /* 00000000-0000FFFF 16Kx32 internal program */
1690 /* 00400000-00BFFFFF CE0 2Mx32 SDRAM running @ 100MHz */
1691
1692 /* EMIF config */
1693 /*------------ */
1694 /* Global EMIF control */
1695 boot_loader_write_mem32(pao, dsp_index, 0x01800000, 0x3779);
1696#define WS_OFS 28
1697#define WST_OFS 22
1698#define WH_OFS 20
1699#define RS_OFS 16
1700#define RST_OFS 8
1701#define MTYPE_OFS 4
1702#define RH_OFS 0
1703
1704 /* EMIF CE0 setup - 2Mx32 Sync DRAM on ASI5000 cards only */
1705 setting = 0x00000030;
1706 boot_loader_write_mem32(pao, dsp_index, 0x01800008, setting);
1707 if (setting != boot_loader_read_mem32(pao, dsp_index,
1708 0x01800008))
1709 return hpi6205_error(dsp_index,
1710 HPI6205_ERROR_DSP_EMIF);
1711
1712 /* EMIF CE1 setup - 32 bit async. This is 6713 #1 HPI, */
1713 /* which occupies D15..0. 6713 starts at 27MHz, so need */
1714 /* plenty of wait states. See dsn8701.rtf, and 6713 errata. */
1715 /* WST should be 71, but 63 is max possible */
1716 setting =
1717 (1L << WS_OFS) | (63L << WST_OFS) | (1L << WH_OFS) |
1718 (1L << RS_OFS) | (63L << RST_OFS) | (1L << RH_OFS) |
1719 (2L << MTYPE_OFS);
1720 boot_loader_write_mem32(pao, dsp_index, 0x01800004, setting);
1721 if (setting != boot_loader_read_mem32(pao, dsp_index,
1722 0x01800004))
1723 return hpi6205_error(dsp_index,
1724 HPI6205_ERROR_DSP_EMIF);
1725
1726 /* EMIF CE2 setup - 32 bit async. This is 6713 #2 HPI, */
1727 /* which occupies D15..0. 6713 starts at 27MHz, so need */
1728 /* plenty of wait states */
1729 setting =
1730 (1L << WS_OFS) | (28L << WST_OFS) | (1L << WH_OFS) |
1731 (1L << RS_OFS) | (63L << RST_OFS) | (1L << RH_OFS) |
1732 (2L << MTYPE_OFS);
1733 boot_loader_write_mem32(pao, dsp_index, 0x01800010, setting);
1734 if (setting != boot_loader_read_mem32(pao, dsp_index,
1735 0x01800010))
1736 return hpi6205_error(dsp_index,
1737 HPI6205_ERROR_DSP_EMIF);
1738
1739 /* EMIF CE3 setup - 32 bit async. */
1740 /* This is the PLD on the ASI5000 cards only */
1741 setting =
1742 (1L << WS_OFS) | (10L << WST_OFS) | (1L << WH_OFS) |
1743 (1L << RS_OFS) | (10L << RST_OFS) | (1L << RH_OFS) |
1744 (2L << MTYPE_OFS);
1745 boot_loader_write_mem32(pao, dsp_index, 0x01800014, setting);
1746 if (setting != boot_loader_read_mem32(pao, dsp_index,
1747 0x01800014))
1748 return hpi6205_error(dsp_index,
1749 HPI6205_ERROR_DSP_EMIF);
1750
1751 /* set EMIF SDRAM control for 2Mx32 SDRAM (512x32x4 bank) */
1752 /* need to use this else DSP code crashes? */
1753 boot_loader_write_mem32(pao, dsp_index, 0x01800018,
1754 0x07117000);
1755
1756 /* EMIF SDRAM Refresh Timing */
1757 /* EMIF SDRAM timing (orig = 0x410, emulator = 0x61a) */
1758 boot_loader_write_mem32(pao, dsp_index, 0x0180001C,
1759 0x00000410);
1760
1761 } else if (dsp_index == 1) {
1762 /* test access to the C6713s HPI registers */
1763 u32 write_data = 0, read_data = 0, i = 0;
1764
1765 /* Set up HPIC for little endian, by setiing HPIC:HWOB=1 */
1766 write_data = 1;
1767 boot_loader_write_mem32(pao, 0, HPICL_ADDR, write_data);
1768 boot_loader_write_mem32(pao, 0, HPICH_ADDR, write_data);
1769 /* C67 HPI is on lower 16bits of 32bit EMIF */
1770 read_data =
1771 0xFFF7 & boot_loader_read_mem32(pao, 0, HPICL_ADDR);
1772 if (write_data != read_data) {
1773 err = hpi6205_error(dsp_index,
1774 HPI6205_ERROR_C6713_HPIC);
1775 HPI_DEBUG_LOG(ERROR, "HPICL %x %x\n", write_data,
1776 read_data);
1777
1778 return err;
1779 }
1780 /* HPIA - walking ones test */
1781 write_data = 1;
1782 for (i = 0; i < 32; i++) {
1783 boot_loader_write_mem32(pao, 0, HPIAL_ADDR,
1784 write_data);
1785 boot_loader_write_mem32(pao, 0, HPIAH_ADDR,
1786 (write_data >> 16));
1787 read_data =
1788 0xFFFF & boot_loader_read_mem32(pao, 0,
1789 HPIAL_ADDR);
1790 read_data =
1791 read_data | ((0xFFFF &
1792 boot_loader_read_mem32(pao, 0,
1793 HPIAH_ADDR))
1794 << 16);
1795 if (read_data != write_data) {
1796 err = hpi6205_error(dsp_index,
1797 HPI6205_ERROR_C6713_HPIA);
1798 HPI_DEBUG_LOG(ERROR, "HPIA %x %x\n",
1799 write_data, read_data);
1800 return err;
1801 }
1802 write_data = write_data << 1;
1803 }
1804
1805 /* setup C67x PLL
1806 * ** C6713 datasheet says we cannot program PLL from HPI,
1807 * and indeed if we try to set the PLL multiply from the HPI,
1808 * the PLL does not seem to lock, so we enable the PLL and
1809 * use the default multiply of x 7, which for a 27MHz clock
1810 * gives a DSP speed of 189MHz
1811 */
1812 /* bypass PLL */
1813 boot_loader_write_mem32(pao, dsp_index, 0x01B7C100, 0x0000);
1814 hpios_delay_micro_seconds(1000);
1815 /* EMIF = 189/3=63MHz */
1816 boot_loader_write_mem32(pao, dsp_index, 0x01B7C120, 0x8002);
1817 /* peri = 189/2 */
1818 boot_loader_write_mem32(pao, dsp_index, 0x01B7C11C, 0x8001);
1819 /* cpu = 189/1 */
1820 boot_loader_write_mem32(pao, dsp_index, 0x01B7C118, 0x8000);
1821 hpios_delay_micro_seconds(1000);
1822 /* ** SGT test to take GPO3 high when we start the PLL */
1823 /* and low when the delay is completed */
1824 /* FSX0 <- '1' (GPO3) */
1825 boot_loader_write_mem32(pao, 0, (0x018C0024L), 0x00002A0A);
1826 /* PLL not bypassed */
1827 boot_loader_write_mem32(pao, dsp_index, 0x01B7C100, 0x0001);
1828 hpios_delay_micro_seconds(1000);
1829 /* FSX0 <- '0' (GPO3) */
1830 boot_loader_write_mem32(pao, 0, (0x018C0024L), 0x00002A02);
1831
1832 /* 6205 EMIF CE1 resetup - 32 bit async. */
1833 /* Now 6713 #1 is running at 189MHz can reduce waitstates */
1834 boot_loader_write_mem32(pao, 0, 0x01800004, /* CE1 */
1835 (1L << WS_OFS) | (8L << WST_OFS) | (1L << WH_OFS) |
1836 (1L << RS_OFS) | (12L << RST_OFS) | (1L << RH_OFS) |
1837 (2L << MTYPE_OFS));
1838
1839 hpios_delay_micro_seconds(1000);
1840
1841 /* check that we can read one of the PLL registers */
1842 /* PLL should not be bypassed! */
1843 if ((boot_loader_read_mem32(pao, dsp_index, 0x01B7C100) & 0xF)
1844 != 0x0001) {
1845 err = hpi6205_error(dsp_index,
1846 HPI6205_ERROR_C6713_PLL);
1847 return err;
1848 }
1849 /* setup C67x EMIF (note this is the only use of
1850 BAR1 via BootLoader_WriteMem32) */
1851 boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_GCTL,
1852 0x000034A8);
1853 boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_CE0,
1854 0x00000030);
1855 boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_SDRAMEXT,
1856 0x001BDF29);
1857 boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_SDRAMCTL,
1858 0x47117000);
1859 boot_loader_write_mem32(pao, dsp_index,
1860 C6713_EMIF_SDRAMTIMING, 0x00000410);
1861
1862 hpios_delay_micro_seconds(1000);
1863 } else if (dsp_index == 2) {
1864 /* DSP 2 is a C6713 */
1865
1866 } else
1867 err = hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX);
1868 return err;
1869}
1870
1871static u16 boot_loader_test_memory(struct hpi_adapter_obj *pao, int dsp_index,
1872 u32 start_address, u32 length)
1873{
1874 u32 i = 0, j = 0;
1875 u32 test_addr = 0;
1876 u32 test_data = 0, data = 0;
1877
1878 length = 1000;
1879
1880 /* for 1st word, test each bit in the 32bit word, */
1881 /* dwLength specifies number of 32bit words to test */
1882 /*for(i=0; i<dwLength; i++) */
1883 i = 0;
1884 {
1885 test_addr = start_address + i * 4;
1886 test_data = 0x00000001;
1887 for (j = 0; j < 32; j++) {
1888 boot_loader_write_mem32(pao, dsp_index, test_addr,
1889 test_data);
1890 data = boot_loader_read_mem32(pao, dsp_index,
1891 test_addr);
1892 if (data != test_data) {
1893 HPI_DEBUG_LOG(VERBOSE,
1894 "memtest error details "
1895 "%08x %08x %08x %i\n", test_addr,
1896 test_data, data, dsp_index);
1897 return 1; /* error */
1898 }
1899 test_data = test_data << 1;
1900 } /* for(j) */
1901 } /* for(i) */
1902
1903 /* for the next 100 locations test each location, leaving it as zero */
1904 /* write a zero to the next word in memory before we read */
1905 /* the previous write to make sure every memory location is unique */
1906 for (i = 0; i < 100; i++) {
1907 test_addr = start_address + i * 4;
1908 test_data = 0xA5A55A5A;
1909 boot_loader_write_mem32(pao, dsp_index, test_addr, test_data);
1910 boot_loader_write_mem32(pao, dsp_index, test_addr + 4, 0);
1911 data = boot_loader_read_mem32(pao, dsp_index, test_addr);
1912 if (data != test_data) {
1913 HPI_DEBUG_LOG(VERBOSE,
1914 "memtest error details "
1915 "%08x %08x %08x %i\n", test_addr, test_data,
1916 data, dsp_index);
1917 return 1; /* error */
1918 }
1919 /* leave location as zero */
1920 boot_loader_write_mem32(pao, dsp_index, test_addr, 0x0);
1921 }
1922
1923 /* zero out entire memory block */
1924 for (i = 0; i < length; i++) {
1925 test_addr = start_address + i * 4;
1926 boot_loader_write_mem32(pao, dsp_index, test_addr, 0x0);
1927 }
1928 return 0;
1929}
1930
1931static u16 boot_loader_test_internal_memory(struct hpi_adapter_obj *pao,
1932 int dsp_index)
1933{
1934 int err = 0;
1935 if (dsp_index == 0) {
1936 /* DSP 0 is a C6205 */
1937 /* 64K prog mem */
1938 err = boot_loader_test_memory(pao, dsp_index, 0x00000000,
1939 0x10000);
1940 if (!err)
1941 /* 64K data mem */
1942 err = boot_loader_test_memory(pao, dsp_index,
1943 0x80000000, 0x10000);
1944 } else if ((dsp_index == 1) || (dsp_index == 2)) {
1945 /* DSP 1&2 are a C6713 */
1946 /* 192K internal mem */
1947 err = boot_loader_test_memory(pao, dsp_index, 0x00000000,
1948 0x30000);
1949 if (!err)
1950 /* 64K internal mem / L2 cache */
1951 err = boot_loader_test_memory(pao, dsp_index,
1952 0x00030000, 0x10000);
1953 } else
1954 return hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX);
1955
1956 if (err)
1957 return hpi6205_error(dsp_index, HPI6205_ERROR_DSP_INTMEM);
1958 else
1959 return 0;
1960}
1961
1962static u16 boot_loader_test_external_memory(struct hpi_adapter_obj *pao,
1963 int dsp_index)
1964{
1965 u32 dRAM_start_address = 0;
1966 u32 dRAM_size = 0;
1967
1968 if (dsp_index == 0) {
1969 /* only test for SDRAM if an ASI5000 card */
1970 if (pao->pci.subsys_device_id == 0x5000) {
1971 /* DSP 0 is always C6205 */
1972 dRAM_start_address = 0x00400000;
1973 dRAM_size = 0x200000;
1974 /*dwDRAMinc=1024; */
1975 } else
1976 return 0;
1977 } else if ((dsp_index == 1) || (dsp_index == 2)) {
1978 /* DSP 1 is a C6713 */
1979 dRAM_start_address = 0x80000000;
1980 dRAM_size = 0x200000;
1981 /*dwDRAMinc=1024; */
1982 } else
1983 return hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX);
1984
1985 if (boot_loader_test_memory(pao, dsp_index, dRAM_start_address,
1986 dRAM_size))
1987 return hpi6205_error(dsp_index, HPI6205_ERROR_DSP_EXTMEM);
1988 return 0;
1989}
1990
1991static u16 boot_loader_test_pld(struct hpi_adapter_obj *pao, int dsp_index)
1992{
1993 u32 data = 0;
1994 if (dsp_index == 0) {
1995 /* only test for DSP0 PLD on ASI5000 card */
1996 if (pao->pci.subsys_device_id == 0x5000) {
1997 /* PLD is located at CE3=0x03000000 */
1998 data = boot_loader_read_mem32(pao, dsp_index,
1999 0x03000008);
2000 if ((data & 0xF) != 0x5)
2001 return hpi6205_error(dsp_index,
2002 HPI6205_ERROR_DSP_PLD);
2003 data = boot_loader_read_mem32(pao, dsp_index,
2004 0x0300000C);
2005 if ((data & 0xF) != 0xA)
2006 return hpi6205_error(dsp_index,
2007 HPI6205_ERROR_DSP_PLD);
2008 }
2009 } else if (dsp_index == 1) {
2010 /* DSP 1 is a C6713 */
2011 if (pao->pci.subsys_device_id == 0x8700) {
2012 /* PLD is located at CE1=0x90000000 */
2013 data = boot_loader_read_mem32(pao, dsp_index,
2014 0x90000010);
2015 if ((data & 0xFF) != 0xAA)
2016 return hpi6205_error(dsp_index,
2017 HPI6205_ERROR_DSP_PLD);
2018 /* 8713 - LED on */
2019 boot_loader_write_mem32(pao, dsp_index, 0x90000000,
2020 0x02);
2021 }
2022 }
2023 return 0;
2024}
2025
2026/** Transfer data to or from DSP
2027 nOperation = H620_H620_HIF_SEND_DATA or H620_HIF_GET_DATA
2028*/
2029static short hpi6205_transfer_data(struct hpi_adapter_obj *pao, u8 *p_data,
2030 u32 data_size, int operation)
2031{
2032 struct hpi_hw_obj *phw = pao->priv;
2033 u32 data_transferred = 0;
2034 u16 err = 0;
2035#ifndef HPI6205_NO_HSR_POLL
2036 u32 time_out;
2037#endif
2038 u32 temp2;
2039 struct bus_master_interface *interface = phw->p_interface_buffer;
2040
2041 if (!p_data)
2042 return HPI_ERROR_INVALID_DATA_TRANSFER;
2043
2044 data_size &= ~3L; /* round data_size down to nearest 4 bytes */
2045
2046 /* make sure state is IDLE */
2047 if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT))
2048 return HPI_ERROR_DSP_HARDWARE;
2049
2050 while (data_transferred < data_size) {
2051 u32 this_copy = data_size - data_transferred;
2052
2053 if (this_copy > HPI6205_SIZEOF_DATA)
2054 this_copy = HPI6205_SIZEOF_DATA;
2055
2056 if (operation == H620_HIF_SEND_DATA)
2057 memcpy((void *)&interface->u.b_data[0],
2058 &p_data[data_transferred], this_copy);
2059
2060 interface->transfer_size_in_bytes = this_copy;
2061
2062#ifdef HPI6205_NO_HSR_POLL
2063 /* DSP must change this back to nOperation */
2064 interface->dsp_ack = H620_HIF_IDLE;
2065#endif
2066
2067 send_dsp_command(phw, operation);
2068
2069#ifdef HPI6205_NO_HSR_POLL
2070 temp2 = wait_dsp_ack(phw, operation, HPI6205_TIMEOUT);
2071 HPI_DEBUG_LOG(DEBUG, "spun %d times for data xfer of %d\n",
2072 HPI6205_TIMEOUT - temp2, this_copy);
2073
2074 if (!temp2) {
2075 /* timed out */
2076 HPI_DEBUG_LOG(ERROR,
2077 "timed out waiting for " "state %d got %d\n",
2078 operation, interface->dsp_ack);
2079
2080 break;
2081 }
2082#else
2083 /* spin waiting on the result */
2084 time_out = HPI6205_TIMEOUT;
2085 temp2 = 0;
2086 while ((temp2 == 0) && time_out--) {
2087 /* give 16k bus mastering transfer time to happen */
2088 /*(16k / 132Mbytes/s = 122usec) */
2089 hpios_delay_micro_seconds(20);
2090 temp2 = ioread32(phw->prHSR);
2091 temp2 &= C6205_HSR_INTSRC;
2092 }
2093 HPI_DEBUG_LOG(DEBUG, "spun %d times for data xfer of %d\n",
2094 HPI6205_TIMEOUT - time_out, this_copy);
2095 if (temp2 == C6205_HSR_INTSRC) {
2096 HPI_DEBUG_LOG(VERBOSE,
2097 "interrupt from HIF <data> OK\n");
2098 /*
2099 if(interface->dwDspAck != nOperation) {
2100 HPI_DEBUG_LOG(DEBUG("interface->dwDspAck=%d,
2101 expected %d \n",
2102 interface->dwDspAck,nOperation);
2103 }
2104 */
2105 }
2106/* need to handle this differently... */
2107 else {
2108 HPI_DEBUG_LOG(ERROR,
2109 "interrupt from HIF <data> BAD\n");
2110 err = HPI_ERROR_DSP_HARDWARE;
2111 }
2112
2113 /* reset the interrupt from the DSP */
2114 iowrite32(C6205_HSR_INTSRC, phw->prHSR);
2115#endif
2116 if (operation == H620_HIF_GET_DATA)
2117 memcpy(&p_data[data_transferred],
2118 (void *)&interface->u.b_data[0], this_copy);
2119
2120 data_transferred += this_copy;
2121 }
2122 if (interface->dsp_ack != operation)
2123 HPI_DEBUG_LOG(DEBUG, "interface->dsp_ack=%d, expected %d\n",
2124 interface->dsp_ack, operation);
2125 /* err=HPI_ERROR_DSP_HARDWARE; */
2126
2127 send_dsp_command(phw, H620_HIF_IDLE);
2128
2129 return err;
2130}
2131
2132/* wait for up to timeout_us microseconds for the DSP
2133 to signal state by DMA into dwDspAck
2134*/
2135static int wait_dsp_ack(struct hpi_hw_obj *phw, int state, int timeout_us)
2136{
2137 struct bus_master_interface *interface = phw->p_interface_buffer;
2138 int t = timeout_us / 4;
2139
2140 rmb(); /* ensure interface->dsp_ack is up to date */
2141 while ((interface->dsp_ack != state) && --t) {
2142 hpios_delay_micro_seconds(4);
2143 rmb(); /* DSP changes dsp_ack by DMA */
2144 }
2145
2146 /*HPI_DEBUG_LOG(VERBOSE, "Spun %d for %d\n", timeout_us/4-t, state); */
2147 return t * 4;
2148}
2149
2150/* set the busmaster interface to cmd, then interrupt the DSP */
2151static void send_dsp_command(struct hpi_hw_obj *phw, int cmd)
2152{
2153 struct bus_master_interface *interface = phw->p_interface_buffer;
2154
2155 u32 r;
2156
2157 interface->host_cmd = cmd;
2158 wmb(); /* DSP gets state by DMA, make sure it is written to memory */
2159 /* before we interrupt the DSP */
2160 r = ioread32(phw->prHDCR);
2161 r |= (u32)C6205_HDCR_DSPINT;
2162 iowrite32(r, phw->prHDCR);
2163 r &= ~(u32)C6205_HDCR_DSPINT;
2164 iowrite32(r, phw->prHDCR);
2165}
2166
2167static unsigned int message_count;
2168
2169static u16 message_response_sequence(struct hpi_adapter_obj *pao,
2170 struct hpi_message *phm, struct hpi_response *phr)
2171{
2172#ifndef HPI6205_NO_HSR_POLL
2173 u32 temp2;
2174#endif
2175 u32 time_out, time_out2;
2176 struct hpi_hw_obj *phw = pao->priv;
2177 struct bus_master_interface *interface = phw->p_interface_buffer;
2178 u16 err = 0;
2179
2180 message_count++;
2181 /* Assume buffer of type struct bus_master_interface
2182 is allocated "noncacheable" */
2183
2184 if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT)) {
2185 HPI_DEBUG_LOG(DEBUG, "timeout waiting for idle\n");
2186 return hpi6205_error(0, HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT);
2187 }
2188 interface->u.message_buffer = *phm;
2189 /* signal we want a response */
2190 send_dsp_command(phw, H620_HIF_GET_RESP);
2191
2192 time_out2 = wait_dsp_ack(phw, H620_HIF_GET_RESP, HPI6205_TIMEOUT);
2193
2194 if (time_out2 == 0) {
2195 HPI_DEBUG_LOG(ERROR,
2196 "(%u) timed out waiting for " "GET_RESP state [%x]\n",
2197 message_count, interface->dsp_ack);
2198 } else {
2199 HPI_DEBUG_LOG(VERBOSE,
2200 "(%u) transition to GET_RESP after %u\n",
2201 message_count, HPI6205_TIMEOUT - time_out2);
2202 }
2203 /* spin waiting on HIF interrupt flag (end of msg process) */
2204 time_out = HPI6205_TIMEOUT;
2205
2206#ifndef HPI6205_NO_HSR_POLL
2207 temp2 = 0;
2208 while ((temp2 == 0) && --time_out) {
2209 temp2 = ioread32(phw->prHSR);
2210 temp2 &= C6205_HSR_INTSRC;
2211 hpios_delay_micro_seconds(1);
2212 }
2213 if (temp2 == C6205_HSR_INTSRC) {
2214 rmb(); /* ensure we see latest value for dsp_ack */
2215 if ((interface->dsp_ack != H620_HIF_GET_RESP)) {
2216 HPI_DEBUG_LOG(DEBUG,
2217 "(%u)interface->dsp_ack(0x%x) != "
2218 "H620_HIF_GET_RESP, t=%u\n", message_count,
2219 interface->dsp_ack,
2220 HPI6205_TIMEOUT - time_out);
2221 } else {
2222 HPI_DEBUG_LOG(VERBOSE,
2223 "(%u)int with GET_RESP after %u\n",
2224 message_count, HPI6205_TIMEOUT - time_out);
2225 }
2226
2227 } else {
2228 /* can we do anything else in response to the error ? */
2229 HPI_DEBUG_LOG(ERROR,
2230 "interrupt from HIF module BAD (function %x)\n",
2231 phm->function);
2232 }
2233
2234 /* reset the interrupt from the DSP */
2235 iowrite32(C6205_HSR_INTSRC, phw->prHSR);
2236#endif
2237
2238 /* read the result */
2239 if (time_out != 0)
2240 *phr = interface->u.response_buffer;
2241
2242 /* set interface back to idle */
2243 send_dsp_command(phw, H620_HIF_IDLE);
2244
2245 if ((time_out == 0) || (time_out2 == 0)) {
2246 HPI_DEBUG_LOG(DEBUG, "something timed out!\n");
2247 return hpi6205_error(0, HPI6205_ERROR_MSG_RESP_TIMEOUT);
2248 }
2249 /* special case for adapter close - */
2250 /* wait for the DSP to indicate it is idle */
2251 if (phm->function == HPI_ADAPTER_CLOSE) {
2252 if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT)) {
2253 HPI_DEBUG_LOG(DEBUG,
2254 "timeout waiting for idle "
2255 "(on adapter_close)\n");
2256 return hpi6205_error(0,
2257 HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT);
2258 }
2259 }
2260 err = hpi_validate_response(phm, phr);
2261 return err;
2262}
2263
2264static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
2265 struct hpi_response *phr)
2266{
2267
2268 u16 err = 0;
2269
2270 hpios_dsplock_lock(pao);
2271
2272 err = message_response_sequence(pao, phm, phr);
2273
2274 /* maybe an error response */
2275 if (err) {
2276 /* something failed in the HPI/DSP interface */
2277 phr->error = err;
2278 pao->dsp_crashed++;
2279
2280 /* just the header of the response is valid */
2281 phr->size = sizeof(struct hpi_response_header);
2282 goto err;
2283 } else
2284 pao->dsp_crashed = 0;
2285
2286 if (phr->error != 0) /* something failed in the DSP */
2287 goto err;
2288
2289 switch (phm->function) {
2290 case HPI_OSTREAM_WRITE:
2291 case HPI_ISTREAM_ANC_WRITE:
2292 err = hpi6205_transfer_data(pao, phm->u.d.u.data.pb_data,
2293 phm->u.d.u.data.data_size, H620_HIF_SEND_DATA);
2294 break;
2295
2296 case HPI_ISTREAM_READ:
2297 case HPI_OSTREAM_ANC_READ:
2298 err = hpi6205_transfer_data(pao, phm->u.d.u.data.pb_data,
2299 phm->u.d.u.data.data_size, H620_HIF_GET_DATA);
2300 break;
2301
2302 case HPI_CONTROL_SET_STATE:
2303 if (phm->object == HPI_OBJ_CONTROLEX
2304 && phm->u.cx.attribute == HPI_COBRANET_SET_DATA)
2305 err = hpi6205_transfer_data(pao,
2306 phm->u.cx.u.cobranet_bigdata.pb_data,
2307 phm->u.cx.u.cobranet_bigdata.byte_count,
2308 H620_HIF_SEND_DATA);
2309 break;
2310
2311 case HPI_CONTROL_GET_STATE:
2312 if (phm->object == HPI_OBJ_CONTROLEX
2313 && phm->u.cx.attribute == HPI_COBRANET_GET_DATA)
2314 err = hpi6205_transfer_data(pao,
2315 phm->u.cx.u.cobranet_bigdata.pb_data,
2316 phr->u.cx.u.cobranet_data.byte_count,
2317 H620_HIF_GET_DATA);
2318 break;
2319 }
2320 phr->error = err;
2321
2322err:
2323 hpios_dsplock_unlock(pao);
2324
2325 return;
2326}
diff --git a/sound/pci/asihpi/hpi6205.h b/sound/pci/asihpi/hpi6205.h
new file mode 100644
index 000000000000..1adae0857cda
--- /dev/null
+++ b/sound/pci/asihpi/hpi6205.h
@@ -0,0 +1,93 @@
1/*****************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
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, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19Host Interface module for an ASI6205 based
20bus mastering PCI adapter.
21
22Copyright AudioScience, Inc., 2003
23******************************************************************************/
24
25#ifndef _HPI6205_H_
26#define _HPI6205_H_
27
28/* transitional conditional compile shared between host and DSP */
29/* #define HPI6205_NO_HSR_POLL */
30
31#include "hpi_internal.h"
32
33/***********************************************************
34 Defines used for basic messaging
35************************************************************/
36#define H620_HIF_RESET 0
37#define H620_HIF_IDLE 1
38#define H620_HIF_GET_RESP 2
39#define H620_HIF_DATA_DONE 3
40#define H620_HIF_DATA_MASK 0x10
41#define H620_HIF_SEND_DATA 0x14
42#define H620_HIF_GET_DATA 0x15
43#define H620_HIF_UNKNOWN 0x0000ffff
44
45/***********************************************************
46 Types used for mixer control caching
47************************************************************/
48
49#define H620_MAX_ISTREAMS 32
50#define H620_MAX_OSTREAMS 32
51#define HPI_NMIXER_CONTROLS 2048
52
53/*********************************************************************
54This is used for dynamic control cache allocation
55**********************************************************************/
56struct controlcache_6205 {
57 u32 number_of_controls;
58 u32 physical_address32;
59 u32 size_in_bytes;
60};
61
62/*********************************************************************
63This is used for dynamic allocation of async event array
64**********************************************************************/
65struct async_event_buffer_6205 {
66 u32 physical_address32;
67 u32 spare;
68 struct hpi_fifo_buffer b;
69};
70
71/***********************************************************
72The Host located memory buffer that the 6205 will bus master
73in and out of.
74************************************************************/
75#define HPI6205_SIZEOF_DATA (16*1024)
76struct bus_master_interface {
77 u32 host_cmd;
78 u32 dsp_ack;
79 u32 transfer_size_in_bytes;
80 union {
81 struct hpi_message message_buffer;
82 struct hpi_response response_buffer;
83 u8 b_data[HPI6205_SIZEOF_DATA];
84 } u;
85 struct controlcache_6205 control_cache;
86 struct async_event_buffer_6205 async_buffer;
87 struct hpi_hostbuffer_status
88 instream_host_buffer_status[H620_MAX_ISTREAMS];
89 struct hpi_hostbuffer_status
90 outstream_host_buffer_status[H620_MAX_OSTREAMS];
91};
92
93#endif
diff --git a/sound/pci/asihpi/hpi_internal.h b/sound/pci/asihpi/hpi_internal.h
new file mode 100644
index 000000000000..fdd0ce02aa68
--- /dev/null
+++ b/sound/pci/asihpi/hpi_internal.h
@@ -0,0 +1,1646 @@
1/******************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
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, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19HPI internal definitions
20
21(C) Copyright AudioScience Inc. 1996-2009
22******************************************************************************/
23
24#ifndef _HPI_INTERNAL_H_
25#define _HPI_INTERNAL_H_
26
27#include "hpi.h"
28/** maximum number of memory regions mapped to an adapter */
29#define HPI_MAX_ADAPTER_MEM_SPACES (2)
30
31/* Each OS needs its own hpios.h, or specific define as above */
32#include "hpios.h"
33
34/* physical memory allocation */
35void hpios_locked_mem_init(void
36 );
37void hpios_locked_mem_free_all(void
38 );
39#define hpios_locked_mem_prepare(a, b, c, d);
40#define hpios_locked_mem_unprepare(a)
41
42/** Allocate and map an area of locked memory for bus master DMA operations.
43
44On success, *pLockedMemeHandle is a valid handle, and 0 is returned
45On error *pLockedMemHandle marked invalid, non-zero returned.
46
47If this function succeeds, then HpiOs_LockedMem_GetVirtAddr() and
48HpiOs_LockedMem_GetPyhsAddr() will always succed on the returned handle.
49*/
50u16 hpios_locked_mem_alloc(struct consistent_dma_area *p_locked_mem_handle,
51 /**< memory handle */
52 u32 size, /**< size in bytes to allocate */
53 struct pci_dev *p_os_reference
54 /**< OS specific data required for memory allocation */
55 );
56
57/** Free mapping and memory represented by LockedMemHandle
58
59Frees any resources, then invalidates the handle.
60Returns 0 on success, 1 if handle is invalid.
61
62*/
63u16 hpios_locked_mem_free(struct consistent_dma_area *locked_mem_handle);
64
65/** Get the physical PCI address of memory represented by LockedMemHandle.
66
67If handle is invalid *pPhysicalAddr is set to zero and return 1
68*/
69u16 hpios_locked_mem_get_phys_addr(struct consistent_dma_area
70 *locked_mem_handle, u32 *p_physical_addr);
71
72/** Get the CPU address of of memory represented by LockedMemHandle.
73
74If handle is NULL *ppvVirtualAddr is set to NULL and return 1
75*/
76u16 hpios_locked_mem_get_virt_addr(struct consistent_dma_area
77 *locked_mem_handle, void **ppv_virtual_addr);
78
79/** Check that handle is valid
80i.e it represents a valid memory area
81*/
82u16 hpios_locked_mem_valid(struct consistent_dma_area *locked_mem_handle);
83
84/* timing/delay */
85void hpios_delay_micro_seconds(u32 num_micro_sec);
86
87struct hpi_message;
88struct hpi_response;
89
90typedef void hpi_handler_func(struct hpi_message *, struct hpi_response *);
91
92/* If the assert fails, compiler complains
93 something like size of array `msg' is negative.
94 Unlike linux BUILD_BUG_ON, this works outside function scope.
95*/
96#define compile_time_assert(cond, msg) \
97 typedef char ASSERT_##msg[(cond) ? 1 : -1]
98
99/*/////////////////////////////////////////////////////////////////////////// */
100/* Private HPI Entity related definitions */
101
102#define STR_SIZE_FIELD_MAX 65535U
103#define STR_TYPE_FIELD_MAX 255U
104#define STR_ROLE_FIELD_MAX 255U
105
106struct hpi_entity_str {
107 uint16_t size;
108 uint8_t type;
109 uint8_t role;
110};
111
112#if defined(_MSC_VER)
113#pragma warning(push)
114#pragma warning(disable : 4200)
115#endif
116
117struct hpi_entity {
118 struct hpi_entity_str header;
119#if ! defined(HPI_OS_DSP_C6000) || (defined(HPI_OS_DSP_C6000) && (__TI_COMPILER_VERSION__ > 6000008))
120 /* DSP C6000 compiler v6.0.8 and lower
121 do not support flexible array member */
122 uint8_t value[];
123#else
124 /* NOTE! Using sizeof(struct hpi_entity) will give erroneous results */
125#define HPI_INTERNAL_WARN_ABOUT_ENTITY_VALUE
126 uint8_t value[1];
127#endif
128};
129
130#if defined(_MSC_VER)
131#pragma warning(pop)
132#endif
133
134/******************************************* bus types */
135enum HPI_BUSES {
136 HPI_BUS_ISAPNP = 1,
137 HPI_BUS_PCI = 2,
138 HPI_BUS_USB = 3,
139 HPI_BUS_NET = 4
140};
141
142/******************************************* CONTROL ATTRIBUTES ****/
143/* (in order of control type ID */
144
145 /* This allows for 255 control types, 256 unique attributes each */
146#define HPI_CTL_ATTR(ctl, ai) (HPI_CONTROL_##ctl * 0x100 + ai)
147
148/* Get the sub-index of the attribute for a control type */
149#define HPI_CTL_ATTR_INDEX(i) (i&0xff)
150
151/* Generic control attributes. */
152
153/** Enable a control.
1540=disable, 1=enable
155\note generic to all mixer plugins?
156*/
157#define HPI_GENERIC_ENABLE HPI_CTL_ATTR(GENERIC, 1)
158
159/** Enable event generation for a control.
1600=disable, 1=enable
161\note generic to all controls that can generate events
162*/
163#define HPI_GENERIC_EVENT_ENABLE HPI_CTL_ATTR(GENERIC, 2)
164
165/* Volume Control attributes */
166#define HPI_VOLUME_GAIN HPI_CTL_ATTR(VOLUME, 1)
167#define HPI_VOLUME_AUTOFADE HPI_CTL_ATTR(VOLUME, 2)
168
169/** For HPI_ControlQuery() to get the number of channels of a volume control*/
170#define HPI_VOLUME_NUM_CHANNELS HPI_CTL_ATTR(VOLUME, 6)
171#define HPI_VOLUME_RANGE HPI_CTL_ATTR(VOLUME, 10)
172
173/** Level Control attributes */
174#define HPI_LEVEL_GAIN HPI_CTL_ATTR(LEVEL, 1)
175#define HPI_LEVEL_RANGE HPI_CTL_ATTR(LEVEL, 10)
176
177/* Meter Control attributes */
178/** return RMS signal level */
179#define HPI_METER_RMS HPI_CTL_ATTR(METER, 1)
180/** return peak signal level */
181#define HPI_METER_PEAK HPI_CTL_ATTR(METER, 2)
182/** ballistics for ALL rms meters on adapter */
183#define HPI_METER_RMS_BALLISTICS HPI_CTL_ATTR(METER, 3)
184/** ballistics for ALL peak meters on adapter */
185#define HPI_METER_PEAK_BALLISTICS HPI_CTL_ATTR(METER, 4)
186
187/** For HPI_ControlQuery() to get the number of channels of a meter control*/
188#define HPI_METER_NUM_CHANNELS HPI_CTL_ATTR(METER, 5)
189
190/* Multiplexer control attributes */
191#define HPI_MULTIPLEXER_SOURCE HPI_CTL_ATTR(MULTIPLEXER, 1)
192#define HPI_MULTIPLEXER_QUERYSOURCE HPI_CTL_ATTR(MULTIPLEXER, 2)
193
194/** AES/EBU transmitter control attributes */
195/** AESEBU or SPDIF */
196#define HPI_AESEBUTX_FORMAT HPI_CTL_ATTR(AESEBUTX, 1)
197#define HPI_AESEBUTX_SAMPLERATE HPI_CTL_ATTR(AESEBUTX, 3)
198#define HPI_AESEBUTX_CHANNELSTATUS HPI_CTL_ATTR(AESEBUTX, 4)
199#define HPI_AESEBUTX_USERDATA HPI_CTL_ATTR(AESEBUTX, 5)
200
201/** AES/EBU receiver control attributes */
202#define HPI_AESEBURX_FORMAT HPI_CTL_ATTR(AESEBURX, 1)
203#define HPI_AESEBURX_ERRORSTATUS HPI_CTL_ATTR(AESEBURX, 2)
204#define HPI_AESEBURX_SAMPLERATE HPI_CTL_ATTR(AESEBURX, 3)
205#define HPI_AESEBURX_CHANNELSTATUS HPI_CTL_ATTR(AESEBURX, 4)
206#define HPI_AESEBURX_USERDATA HPI_CTL_ATTR(AESEBURX, 5)
207
208/** \defgroup tuner_defs Tuners
209\{
210*/
211/** \defgroup tuner_attrs Tuner control attributes
212\{
213*/
214#define HPI_TUNER_BAND HPI_CTL_ATTR(TUNER, 1)
215#define HPI_TUNER_FREQ HPI_CTL_ATTR(TUNER, 2)
216#define HPI_TUNER_LEVEL HPI_CTL_ATTR(TUNER, 3)
217#define HPI_TUNER_AUDIOMUTE HPI_CTL_ATTR(TUNER, 4)
218/* use TUNER_STATUS instead */
219#define HPI_TUNER_VIDEO_STATUS HPI_CTL_ATTR(TUNER, 5)
220#define HPI_TUNER_GAIN HPI_CTL_ATTR(TUNER, 6)
221#define HPI_TUNER_STATUS HPI_CTL_ATTR(TUNER, 7)
222#define HPI_TUNER_MODE HPI_CTL_ATTR(TUNER, 8)
223/** RDS data. */
224#define HPI_TUNER_RDS HPI_CTL_ATTR(TUNER, 9)
225/** Audio pre-emphasis. */
226#define HPI_TUNER_DEEMPHASIS HPI_CTL_ATTR(TUNER, 10)
227/** HD Radio tuner program control. */
228#define HPI_TUNER_PROGRAM HPI_CTL_ATTR(TUNER, 11)
229/** HD Radio tuner digital signal quality. */
230#define HPI_TUNER_HDRADIO_SIGNAL_QUALITY HPI_CTL_ATTR(TUNER, 12)
231/** HD Radio SDK firmware version. */
232#define HPI_TUNER_HDRADIO_SDK_VERSION HPI_CTL_ATTR(TUNER, 13)
233/** HD Radio DSP firmware version. */
234#define HPI_TUNER_HDRADIO_DSP_VERSION HPI_CTL_ATTR(TUNER, 14)
235/** HD Radio signal blend (force analog, or automatic). */
236#define HPI_TUNER_HDRADIO_BLEND HPI_CTL_ATTR(TUNER, 15)
237
238/** \} */
239
240/** \defgroup pads_attrs Tuner PADs control attributes
241\{
242*/
243/** The text string containing the station/channel combination. */
244#define HPI_PAD_CHANNEL_NAME HPI_CTL_ATTR(PAD, 1)
245/** The text string containing the artist. */
246#define HPI_PAD_ARTIST HPI_CTL_ATTR(PAD, 2)
247/** The text string containing the title. */
248#define HPI_PAD_TITLE HPI_CTL_ATTR(PAD, 3)
249/** The text string containing the comment. */
250#define HPI_PAD_COMMENT HPI_CTL_ATTR(PAD, 4)
251/** The integer containing the PTY code. */
252#define HPI_PAD_PROGRAM_TYPE HPI_CTL_ATTR(PAD, 5)
253/** The integer containing the program identification. */
254#define HPI_PAD_PROGRAM_ID HPI_CTL_ATTR(PAD, 6)
255/** The integer containing whether traffic information is supported.
256Contains either 1 or 0. */
257#define HPI_PAD_TA_SUPPORT HPI_CTL_ATTR(PAD, 7)
258/** The integer containing whether traffic announcement is in progress.
259Contains either 1 or 0. */
260#define HPI_PAD_TA_ACTIVE HPI_CTL_ATTR(PAD, 8)
261/** \} */
262/** \} */
263
264/* VOX control attributes */
265#define HPI_VOX_THRESHOLD HPI_CTL_ATTR(VOX, 1)
266
267/*?? channel mode used hpi_multiplexer_source attribute == 1 */
268#define HPI_CHANNEL_MODE_MODE HPI_CTL_ATTR(CHANNEL_MODE, 1)
269
270/** \defgroup channel_modes Channel Modes
271Used for HPI_ChannelModeSet/Get()
272\{
273*/
274/** Left channel out = left channel in, Right channel out = right channel in. */
275#define HPI_CHANNEL_MODE_NORMAL 1
276/** Left channel out = right channel in, Right channel out = left channel in. */
277#define HPI_CHANNEL_MODE_SWAP 2
278/** Left channel out = left channel in, Right channel out = left channel in. */
279#define HPI_CHANNEL_MODE_LEFT_TO_STEREO 3
280/** Left channel out = right channel in, Right channel out = right channel in.*/
281#define HPI_CHANNEL_MODE_RIGHT_TO_STEREO 4
282/** Left channel out = (left channel in + right channel in)/2,
283 Right channel out = mute. */
284#define HPI_CHANNEL_MODE_STEREO_TO_LEFT 5
285/** Left channel out = mute,
286 Right channel out = (right channel in + left channel in)/2. */
287#define HPI_CHANNEL_MODE_STEREO_TO_RIGHT 6
288#define HPI_CHANNEL_MODE_LAST 6
289/** \} */
290
291/* Bitstream control set attributes */
292#define HPI_BITSTREAM_DATA_POLARITY HPI_CTL_ATTR(BITSTREAM, 1)
293#define HPI_BITSTREAM_CLOCK_EDGE HPI_CTL_ATTR(BITSTREAM, 2)
294#define HPI_BITSTREAM_CLOCK_SOURCE HPI_CTL_ATTR(BITSTREAM, 3)
295
296#define HPI_POLARITY_POSITIVE 0
297#define HPI_POLARITY_NEGATIVE 1
298
299/* Bitstream control get attributes */
300#define HPI_BITSTREAM_ACTIVITY 1
301
302/* SampleClock control attributes */
303#define HPI_SAMPLECLOCK_SOURCE HPI_CTL_ATTR(SAMPLECLOCK, 1)
304#define HPI_SAMPLECLOCK_SAMPLERATE HPI_CTL_ATTR(SAMPLECLOCK, 2)
305#define HPI_SAMPLECLOCK_SOURCE_INDEX HPI_CTL_ATTR(SAMPLECLOCK, 3)
306#define HPI_SAMPLECLOCK_LOCAL_SAMPLERATE\
307 HPI_CTL_ATTR(SAMPLECLOCK, 4)
308#define HPI_SAMPLECLOCK_AUTO HPI_CTL_ATTR(SAMPLECLOCK, 5)
309#define HPI_SAMPLECLOCK_LOCAL_LOCK HPI_CTL_ATTR(SAMPLECLOCK, 6)
310
311/* Microphone control attributes */
312#define HPI_MICROPHONE_PHANTOM_POWER HPI_CTL_ATTR(MICROPHONE, 1)
313
314/** Equalizer control attributes
315*/
316/** Used to get number of filters in an EQ. (Can't set) */
317#define HPI_EQUALIZER_NUM_FILTERS HPI_CTL_ATTR(EQUALIZER, 1)
318/** Set/get the filter by type, freq, Q, gain */
319#define HPI_EQUALIZER_FILTER HPI_CTL_ATTR(EQUALIZER, 2)
320/** Get the biquad coefficients */
321#define HPI_EQUALIZER_COEFFICIENTS HPI_CTL_ATTR(EQUALIZER, 3)
322
323#define HPI_COMPANDER_PARAMS HPI_CTL_ATTR(COMPANDER, 1)
324
325/* 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)
331#define HPI_COBRANET_GET HPI_CTL_ATTR(COBRANET, 2)
332#define HPI_COBRANET_SET_DATA HPI_CTL_ATTR(COBRANET, 3)
333#define HPI_COBRANET_GET_DATA HPI_CTL_ATTR(COBRANET, 4)
334#define HPI_COBRANET_GET_STATUS HPI_CTL_ATTR(COBRANET, 5)
335#define HPI_COBRANET_SEND_PACKET HPI_CTL_ATTR(COBRANET, 6)
336#define HPI_COBRANET_GET_PACKET HPI_CTL_ATTR(COBRANET, 7)
337
338/*------------------------------------------------------------
339 Cobranet Chip Bridge - copied from HMI.H
340------------------------------------------------------------*/
341#define HPI_COBRANET_HMI_cobra_bridge 0x20000
342#define HPI_COBRANET_HMI_cobra_bridge_tx_pkt_buf \
343 (HPI_COBRANET_HMI_cobra_bridge + 0x1000)
344#define HPI_COBRANET_HMI_cobra_bridge_rx_pkt_buf \
345 (HPI_COBRANET_HMI_cobra_bridge + 0x2000)
346#define HPI_COBRANET_HMI_cobra_if_table1 0x110000
347#define HPI_COBRANET_HMI_cobra_if_phy_address \
348 (HPI_COBRANET_HMI_cobra_if_table1 + 0xd)
349#define HPI_COBRANET_HMI_cobra_protocolIP 0x72000
350#define HPI_COBRANET_HMI_cobra_ip_mon_currentIP \
351 (HPI_COBRANET_HMI_cobra_protocolIP + 0x0)
352#define HPI_COBRANET_HMI_cobra_ip_mon_staticIP \
353 (HPI_COBRANET_HMI_cobra_protocolIP + 0x2)
354#define HPI_COBRANET_HMI_cobra_sys 0x100000
355#define HPI_COBRANET_HMI_cobra_sys_desc \
356 (HPI_COBRANET_HMI_cobra_sys + 0x0)
357#define HPI_COBRANET_HMI_cobra_sys_objectID \
358 (HPI_COBRANET_HMI_cobra_sys + 0x100)
359#define HPI_COBRANET_HMI_cobra_sys_contact \
360 (HPI_COBRANET_HMI_cobra_sys + 0x200)
361#define HPI_COBRANET_HMI_cobra_sys_name \
362 (HPI_COBRANET_HMI_cobra_sys + 0x300)
363#define HPI_COBRANET_HMI_cobra_sys_location \
364 (HPI_COBRANET_HMI_cobra_sys + 0x400)
365
366/*------------------------------------------------------------
367 Cobranet Chip Status bits
368------------------------------------------------------------*/
369#define HPI_COBRANET_HMI_STATUS_RXPACKET 2
370#define HPI_COBRANET_HMI_STATUS_TXPACKET 3
371
372/*------------------------------------------------------------
373 Ethernet header size
374------------------------------------------------------------*/
375#define HPI_ETHERNET_HEADER_SIZE (16)
376
377/* These defines are used to fill in protocol information for an Ethernet packet
378 sent using HMI on CS18102 */
379/** ID supplied by Cirrius for ASI packets. */
380#define HPI_ETHERNET_PACKET_ID 0x85
381/** Simple packet - no special routing required */
382#define HPI_ETHERNET_PACKET_V1 0x01
383/** This packet must make its way to the host across the HPI interface */
384#define HPI_ETHERNET_PACKET_HOSTED_VIA_HMI 0x20
385/** This packet must make its way to the host across the HPI interface */
386#define HPI_ETHERNET_PACKET_HOSTED_VIA_HMI_V1 0x21
387/** This packet must make its way to the host across the HPI interface */
388#define HPI_ETHERNET_PACKET_HOSTED_VIA_HPI 0x40
389/** This packet must make its way to the host across the HPI interface */
390#define HPI_ETHERNET_PACKET_HOSTED_VIA_HPI_V1 0x41
391
392#define HPI_ETHERNET_UDP_PORT (44600) /*!< UDP messaging port */
393
394/** Base network time out is set to 100 milli-seconds. */
395#define HPI_ETHERNET_TIMEOUT_MS (100)
396
397/** \defgroup tonedet_attr Tonedetector attributes
398\{
399Used by HPI_ToneDetector_Set() and HPI_ToneDetector_Get()
400*/
401
402/** Set the threshold level of a tonedetector,
403Threshold is a -ve number in units of dB/100,
404*/
405#define HPI_TONEDETECTOR_THRESHOLD HPI_CTL_ATTR(TONEDETECTOR, 1)
406
407/** Get the current state of tonedetection
408The result is a bitmap of detected tones. pairs of bits represent the left
409and right channels, with left channel in LSB.
410The lowest frequency detector state is in the LSB
411*/
412#define HPI_TONEDETECTOR_STATE HPI_CTL_ATTR(TONEDETECTOR, 2)
413
414/** Get the frequency of a tonedetector band.
415*/
416#define HPI_TONEDETECTOR_FREQUENCY HPI_CTL_ATTR(TONEDETECTOR, 3)
417
418/**\}*/
419
420/** \defgroup silencedet_attr SilenceDetector attributes
421\{
422*/
423
424/** Get the current state of tonedetection
425The result is a bitmap with 1s for silent channels. Left channel is in LSB
426*/
427#define HPI_SILENCEDETECTOR_STATE \
428 HPI_CTL_ATTR(SILENCEDETECTOR, 2)
429
430/** Set the threshold level of a SilenceDetector,
431Threshold is a -ve number in units of dB/100,
432*/
433#define HPI_SILENCEDETECTOR_THRESHOLD \
434 HPI_CTL_ATTR(SILENCEDETECTOR, 1)
435
436/** get/set the silence time before the detector triggers
437*/
438#define HPI_SILENCEDETECTOR_DELAY \
439 HPI_CTL_ATTR(SILENCEDETECTOR, 3)
440
441/**\}*/
442
443/* Locked memory buffer alloc/free phases */
444/** use one message to allocate or free physical memory */
445#define HPI_BUFFER_CMD_EXTERNAL 0
446/** alloc physical memory */
447#define HPI_BUFFER_CMD_INTERNAL_ALLOC 1
448/** send physical memory address to adapter */
449#define HPI_BUFFER_CMD_INTERNAL_GRANTADAPTER 2
450/** notify adapter to stop using physical buffer */
451#define HPI_BUFFER_CMD_INTERNAL_REVOKEADAPTER 3
452/** free physical buffer */
453#define HPI_BUFFER_CMD_INTERNAL_FREE 4
454
455/******************************************* CONTROLX ATTRIBUTES ****/
456/* NOTE: All controlx attributes must be unique, unlike control attributes */
457
458/*****************************************************************************/
459/*****************************************************************************/
460/******** HPI LOW LEVEL MESSAGES *******/
461/*****************************************************************************/
462/*****************************************************************************/
463/** Pnp ids */
464/** "ASI" - actual is "ASX" - need to change */
465#define HPI_ID_ISAPNP_AUDIOSCIENCE 0x0669
466/** PCI vendor ID that AudioScience uses */
467#define HPI_PCI_VENDOR_ID_AUDIOSCIENCE 0x175C
468/** PCI vendor ID that the DSP56301 has */
469#define HPI_PCI_VENDOR_ID_MOTOROLA 0x1057
470/** PCI vendor ID that TI uses */
471#define HPI_PCI_VENDOR_ID_TI 0x104C
472
473#define HPI_PCI_DEV_ID_PCI2040 0xAC60
474/** TI's C6205 PCI interface has this ID */
475#define HPI_PCI_DEV_ID_DSP6205 0xA106
476
477#define HPI_USB_VENDOR_ID_AUDIOSCIENCE 0x1257
478#define HPI_USB_W2K_TAG 0x57495341 /* "ASIW" */
479#define HPI_USB_LINUX_TAG 0x4C495341 /* "ASIL" */
480
481/** First 2 hex digits define the adapter family */
482#define HPI_ADAPTER_FAMILY_MASK 0xff00
483#define HPI_MODULE_FAMILY_MASK 0xfff0
484
485#define HPI_ADAPTER_FAMILY_ASI(f) (f & HPI_ADAPTER_FAMILY_MASK)
486#define HPI_MODULE_FAMILY_ASI(f) (f & HPI_MODULE_FAMILY_MASK)
487#define HPI_ADAPTER_ASI(f) (f)
488
489/******************************************* message types */
490#define HPI_TYPE_MESSAGE 1
491#define HPI_TYPE_RESPONSE 2
492#define HPI_TYPE_DATA 3
493#define HPI_TYPE_SSX2BYPASS_MESSAGE 4
494
495/******************************************* object types */
496#define HPI_OBJ_SUBSYSTEM 1
497#define HPI_OBJ_ADAPTER 2
498#define HPI_OBJ_OSTREAM 3
499#define HPI_OBJ_ISTREAM 4
500#define HPI_OBJ_MIXER 5
501#define HPI_OBJ_NODE 6
502#define HPI_OBJ_CONTROL 7
503#define HPI_OBJ_NVMEMORY 8
504#define HPI_OBJ_GPIO 9
505#define HPI_OBJ_WATCHDOG 10
506#define HPI_OBJ_CLOCK 11
507#define HPI_OBJ_PROFILE 12
508#define HPI_OBJ_CONTROLEX 13
509#define HPI_OBJ_ASYNCEVENT 14
510
511#define HPI_OBJ_MAXINDEX 14
512
513/******************************************* methods/functions */
514
515#define HPI_OBJ_FUNCTION_SPACING 0x100
516#define HPI_MAKE_INDEX(obj, index) (obj * HPI_OBJ_FUNCTION_SPACING + index)
517#define HPI_EXTRACT_INDEX(fn) (fn & 0xff)
518
519/* SUB-SYSTEM */
520#define HPI_SUBSYS_OPEN HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 1)
521#define HPI_SUBSYS_GET_VERSION HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 2)
522#define HPI_SUBSYS_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 3)
523#define HPI_SUBSYS_FIND_ADAPTERS HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 4)
524#define HPI_SUBSYS_CREATE_ADAPTER HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 5)
525#define HPI_SUBSYS_CLOSE HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 6)
526#define HPI_SUBSYS_DELETE_ADAPTER HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 7)
527#define HPI_SUBSYS_DRIVER_LOAD HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 8)
528#define HPI_SUBSYS_DRIVER_UNLOAD HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 9)
529#define HPI_SUBSYS_READ_PORT_8 HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 10)
530#define HPI_SUBSYS_WRITE_PORT_8 HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 11)
531#define HPI_SUBSYS_GET_NUM_ADAPTERS HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 12)
532#define HPI_SUBSYS_GET_ADAPTER HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 13)
533#define HPI_SUBSYS_SET_NETWORK_INTERFACE HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 14)
534#define HPI_SUBSYS_FUNCTION_COUNT 14
535/* ADAPTER */
536#define HPI_ADAPTER_OPEN HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 1)
537#define HPI_ADAPTER_CLOSE HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 2)
538#define HPI_ADAPTER_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 3)
539#define HPI_ADAPTER_GET_ASSERT HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 4)
540#define HPI_ADAPTER_TEST_ASSERT HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 5)
541#define HPI_ADAPTER_SET_MODE HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 6)
542#define HPI_ADAPTER_GET_MODE HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 7)
543#define HPI_ADAPTER_ENABLE_CAPABILITY HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 8)
544#define HPI_ADAPTER_SELFTEST HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 9)
545#define HPI_ADAPTER_FIND_OBJECT HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 10)
546#define HPI_ADAPTER_QUERY_FLASH HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 11)
547#define HPI_ADAPTER_START_FLASH HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 12)
548#define HPI_ADAPTER_PROGRAM_FLASH HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 13)
549#define HPI_ADAPTER_SET_PROPERTY HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 14)
550#define HPI_ADAPTER_GET_PROPERTY HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 15)
551#define HPI_ADAPTER_ENUM_PROPERTY HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 16)
552#define HPI_ADAPTER_MODULE_INFO HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 17)
553#define HPI_ADAPTER_DEBUG_READ HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 18)
554#define HPI_ADAPTER_FUNCTION_COUNT 18
555/* OUTPUT STREAM */
556#define HPI_OSTREAM_OPEN HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 1)
557#define HPI_OSTREAM_CLOSE HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 2)
558#define HPI_OSTREAM_WRITE HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 3)
559#define HPI_OSTREAM_START HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 4)
560#define HPI_OSTREAM_STOP HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 5)
561#define HPI_OSTREAM_RESET HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 6)
562#define HPI_OSTREAM_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 7)
563#define HPI_OSTREAM_QUERY_FORMAT HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 8)
564#define HPI_OSTREAM_DATA HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 9)
565#define HPI_OSTREAM_SET_VELOCITY HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 10)
566#define HPI_OSTREAM_SET_PUNCHINOUT HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 11)
567#define HPI_OSTREAM_SINEGEN HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 12)
568#define HPI_OSTREAM_ANC_RESET HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 13)
569#define HPI_OSTREAM_ANC_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 14)
570#define HPI_OSTREAM_ANC_READ HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 15)
571#define HPI_OSTREAM_SET_TIMESCALE HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 16)
572#define HPI_OSTREAM_SET_FORMAT HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 17)
573#define HPI_OSTREAM_HOSTBUFFER_ALLOC HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 18)
574#define HPI_OSTREAM_HOSTBUFFER_FREE HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 19)
575#define HPI_OSTREAM_GROUP_ADD HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 20)
576#define HPI_OSTREAM_GROUP_GETMAP HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 21)
577#define HPI_OSTREAM_GROUP_RESET HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 22)
578#define HPI_OSTREAM_HOSTBUFFER_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 23)
579#define HPI_OSTREAM_WAIT_START HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 24)
580#define HPI_OSTREAM_FUNCTION_COUNT 24
581/* INPUT STREAM */
582#define HPI_ISTREAM_OPEN HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 1)
583#define HPI_ISTREAM_CLOSE HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 2)
584#define HPI_ISTREAM_SET_FORMAT HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 3)
585#define HPI_ISTREAM_READ HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 4)
586#define HPI_ISTREAM_START HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 5)
587#define HPI_ISTREAM_STOP HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 6)
588#define HPI_ISTREAM_RESET HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 7)
589#define HPI_ISTREAM_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 8)
590#define HPI_ISTREAM_QUERY_FORMAT HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 9)
591#define HPI_ISTREAM_ANC_RESET HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 10)
592#define HPI_ISTREAM_ANC_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 11)
593#define HPI_ISTREAM_ANC_WRITE HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 12)
594#define HPI_ISTREAM_HOSTBUFFER_ALLOC HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 13)
595#define HPI_ISTREAM_HOSTBUFFER_FREE HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 14)
596#define HPI_ISTREAM_GROUP_ADD HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 15)
597#define HPI_ISTREAM_GROUP_GETMAP HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 16)
598#define HPI_ISTREAM_GROUP_RESET HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 17)
599#define HPI_ISTREAM_HOSTBUFFER_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 18)
600#define HPI_ISTREAM_WAIT_START HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 19)
601#define HPI_ISTREAM_FUNCTION_COUNT 19
602/* MIXER */
603/* NOTE:
604 GET_NODE_INFO, SET_CONNECTION, GET_CONNECTIONS are not currently used */
605#define HPI_MIXER_OPEN HPI_MAKE_INDEX(HPI_OBJ_MIXER, 1)
606#define HPI_MIXER_CLOSE HPI_MAKE_INDEX(HPI_OBJ_MIXER, 2)
607#define HPI_MIXER_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_MIXER, 3)
608#define HPI_MIXER_GET_NODE_INFO HPI_MAKE_INDEX(HPI_OBJ_MIXER, 4)
609#define HPI_MIXER_GET_CONTROL HPI_MAKE_INDEX(HPI_OBJ_MIXER, 5)
610#define HPI_MIXER_SET_CONNECTION HPI_MAKE_INDEX(HPI_OBJ_MIXER, 6)
611#define HPI_MIXER_GET_CONNECTIONS HPI_MAKE_INDEX(HPI_OBJ_MIXER, 7)
612#define HPI_MIXER_GET_CONTROL_BY_INDEX HPI_MAKE_INDEX(HPI_OBJ_MIXER, 8)
613#define HPI_MIXER_GET_CONTROL_ARRAY_BY_INDEX HPI_MAKE_INDEX(HPI_OBJ_MIXER, 9)
614#define HPI_MIXER_GET_CONTROL_MULTIPLE_VALUES HPI_MAKE_INDEX(HPI_OBJ_MIXER, 10)
615#define HPI_MIXER_STORE HPI_MAKE_INDEX(HPI_OBJ_MIXER, 11)
616#define HPI_MIXER_FUNCTION_COUNT 11
617/* MIXER CONTROLS */
618#define HPI_CONTROL_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_CONTROL, 1)
619#define HPI_CONTROL_GET_STATE HPI_MAKE_INDEX(HPI_OBJ_CONTROL, 2)
620#define HPI_CONTROL_SET_STATE HPI_MAKE_INDEX(HPI_OBJ_CONTROL, 3)
621#define HPI_CONTROL_FUNCTION_COUNT 3
622/* NONVOL MEMORY */
623#define HPI_NVMEMORY_OPEN HPI_MAKE_INDEX(HPI_OBJ_NVMEMORY, 1)
624#define HPI_NVMEMORY_READ_BYTE HPI_MAKE_INDEX(HPI_OBJ_NVMEMORY, 2)
625#define HPI_NVMEMORY_WRITE_BYTE HPI_MAKE_INDEX(HPI_OBJ_NVMEMORY, 3)
626#define HPI_NVMEMORY_FUNCTION_COUNT 3
627/* GPIO */
628#define HPI_GPIO_OPEN HPI_MAKE_INDEX(HPI_OBJ_GPIO, 1)
629#define HPI_GPIO_READ_BIT HPI_MAKE_INDEX(HPI_OBJ_GPIO, 2)
630#define HPI_GPIO_WRITE_BIT HPI_MAKE_INDEX(HPI_OBJ_GPIO, 3)
631#define HPI_GPIO_READ_ALL HPI_MAKE_INDEX(HPI_OBJ_GPIO, 4)
632#define HPI_GPIO_WRITE_STATUS HPI_MAKE_INDEX(HPI_OBJ_GPIO, 5)
633#define HPI_GPIO_FUNCTION_COUNT 5
634/* ASYNC EVENT */
635#define HPI_ASYNCEVENT_OPEN HPI_MAKE_INDEX(HPI_OBJ_ASYNCEVENT, 1)
636#define HPI_ASYNCEVENT_CLOSE HPI_MAKE_INDEX(HPI_OBJ_ASYNCEVENT, 2)
637#define HPI_ASYNCEVENT_WAIT HPI_MAKE_INDEX(HPI_OBJ_ASYNCEVENT, 3)
638#define HPI_ASYNCEVENT_GETCOUNT HPI_MAKE_INDEX(HPI_OBJ_ASYNCEVENT, 4)
639#define HPI_ASYNCEVENT_GET HPI_MAKE_INDEX(HPI_OBJ_ASYNCEVENT, 5)
640#define HPI_ASYNCEVENT_SENDEVENTS HPI_MAKE_INDEX(HPI_OBJ_ASYNCEVENT, 6)
641#define HPI_ASYNCEVENT_FUNCTION_COUNT 6
642/* WATCH-DOG */
643#define HPI_WATCHDOG_OPEN HPI_MAKE_INDEX(HPI_OBJ_WATCHDOG, 1)
644#define HPI_WATCHDOG_SET_TIME HPI_MAKE_INDEX(HPI_OBJ_WATCHDOG, 2)
645#define HPI_WATCHDOG_PING HPI_MAKE_INDEX(HPI_OBJ_WATCHDOG, 3)
646/* CLOCK */
647#define HPI_CLOCK_OPEN HPI_MAKE_INDEX(HPI_OBJ_CLOCK, 1)
648#define HPI_CLOCK_SET_TIME HPI_MAKE_INDEX(HPI_OBJ_CLOCK, 2)
649#define HPI_CLOCK_GET_TIME HPI_MAKE_INDEX(HPI_OBJ_CLOCK, 3)
650/* PROFILE */
651#define HPI_PROFILE_OPEN_ALL HPI_MAKE_INDEX(HPI_OBJ_PROFILE, 1)
652#define HPI_PROFILE_START_ALL HPI_MAKE_INDEX(HPI_OBJ_PROFILE, 2)
653#define HPI_PROFILE_STOP_ALL HPI_MAKE_INDEX(HPI_OBJ_PROFILE, 3)
654#define HPI_PROFILE_GET HPI_MAKE_INDEX(HPI_OBJ_PROFILE, 4)
655#define HPI_PROFILE_GET_IDLECOUNT HPI_MAKE_INDEX(HPI_OBJ_PROFILE, 5)
656#define HPI_PROFILE_GET_NAME HPI_MAKE_INDEX(HPI_OBJ_PROFILE, 6)
657#define HPI_PROFILE_GET_UTILIZATION HPI_MAKE_INDEX(HPI_OBJ_PROFILE, 7)
658#define HPI_PROFILE_FUNCTION_COUNT 7
659/* ////////////////////////////////////////////////////////////////////// */
660/* PRIVATE ATTRIBUTES */
661
662/* ////////////////////////////////////////////////////////////////////// */
663/* STRUCTURES */
664#ifndef DISABLE_PRAGMA_PACK1
665#pragma pack(push, 1)
666#endif
667
668/** PCI bus resource */
669struct hpi_pci {
670 u32 __iomem *ap_mem_base[HPI_MAX_ADAPTER_MEM_SPACES];
671 struct pci_dev *p_os_data;
672
673#ifndef HPI64BIT /* keep structure size constant */
674 u32 padding[HPI_MAX_ADAPTER_MEM_SPACES + 1];
675#endif
676 u16 vendor_id;
677 u16 device_id;
678 u16 subsys_vendor_id;
679 u16 subsys_device_id;
680 u16 bus_number;
681 u16 device_number;
682 u32 interrupt;
683};
684
685struct hpi_resource {
686 union {
687 const struct hpi_pci *pci;
688 const char *net_if;
689 } r;
690#ifndef HPI64BIT /* keep structure size constant */
691 u32 pad_to64;
692#endif
693 u16 bus_type; /* HPI_BUS_PNPISA, _PCI, _USB etc */
694 u16 padding;
695
696};
697
698/** Format info used inside struct hpi_message
699 Not the same as public API struct hpi_format */
700struct hpi_msg_format {
701 u32 sample_rate;
702 /**< 11025, 32000, 44100 ... */
703 u32 bit_rate; /**< for MPEG */
704 u32 attributes;
705 /**< Stereo/JointStereo/Mono */
706 u16 channels; /**< 1,2..., (or ancillary mode or idle bit */
707 u16 format; /**< HPI_FORMAT_PCM16, _MPEG etc. see \ref HPI_FORMATS. */
708};
709
710/** Buffer+format structure.
711 Must be kept 7 * 32 bits to match public struct hpi_datastruct */
712struct hpi_msg_data {
713 struct hpi_msg_format format;
714 u8 *pb_data;
715#ifndef HPI64BIT
716 u32 padding;
717#endif
718 u32 data_size;
719};
720
721/** struct hpi_datastructure used up to 3.04 driver */
722struct hpi_data_legacy32 {
723 struct hpi_format format;
724 u32 pb_data;
725 u32 data_size;
726};
727
728#ifdef HPI64BIT
729/* Compatibility version of struct hpi_data*/
730struct hpi_data_compat32 {
731 struct hpi_msg_format format;
732 u32 pb_data;
733 u32 padding;
734 u32 data_size;
735};
736#endif
737
738struct hpi_buffer {
739 /** placehoder for backward compatability (see dwBufferSize) */
740 struct hpi_msg_format reserved;
741 u32 command; /**< HPI_BUFFER_CMD_xxx*/
742 u32 pci_address; /**< PCI physical address of buffer for DSP DMA */
743 u32 buffer_size; /**< must line up with data_size of HPI_DATA*/
744};
745
746/*/////////////////////////////////////////////////////////////////////////// */
747/* This is used for background buffer bus mastering stream buffers. */
748struct hpi_hostbuffer_status {
749 u32 samples_processed;
750 u32 auxiliary_data_available;
751 u32 stream_state;
752 /* DSP index in to the host bus master buffer. */
753 u32 dSP_index;
754 /* Host index in to the host bus master buffer. */
755 u32 host_index;
756 u32 size_in_bytes;
757};
758
759struct hpi_streamid {
760 u16 object_type;
761 /**< Type of object, HPI_OBJ_OSTREAM or HPI_OBJ_ISTREAM. */
762 u16 stream_index; /**< outstream or instream index. */
763};
764
765struct hpi_punchinout {
766 u32 punch_in_sample;
767 u32 punch_out_sample;
768};
769
770struct hpi_subsys_msg {
771 struct hpi_resource resource;
772};
773
774struct hpi_subsys_res {
775 u32 version;
776 u32 data; /* used to return extended version */
777 u16 num_adapters; /* number of adapters */
778 u16 adapter_index;
779 u16 aw_adapter_list[HPI_MAX_ADAPTERS];
780};
781
782struct hpi_adapter_msg {
783 u32 adapter_mode; /* adapter mode */
784 u16 assert_id; /* assert number for "test assert" call
785 object_index for find object call
786 query_or_set for hpi_adapter_set_mode_ex() */
787 u16 object_type; /* for adapter find object call */
788};
789
790union hpi_adapterx_msg {
791 struct hpi_adapter_msg adapter;
792 struct {
793 u32 offset;
794 } query_flash;
795 struct {
796 u32 offset;
797 u32 length;
798 u32 key;
799 } start_flash;
800 struct {
801 u32 checksum;
802 u16 sequence;
803 u16 length;
804 u16 offset; /**< offset from start of msg to data */
805 u16 unused;
806 } program_flash;
807 struct {
808 u16 property;
809 u16 parameter1;
810 u16 parameter2;
811 } property_set;
812 struct {
813 u16 index;
814 u16 what;
815 u16 property_index;
816 } property_enum;
817 struct {
818 u16 index;
819 } module_info;
820 struct {
821 u32 dsp_address;
822 u32 count_bytes;
823 } debug_read;
824};
825
826struct hpi_adapter_res {
827 u32 serial_number;
828 u16 adapter_type;
829 u16 adapter_index; /* is this needed? also used for dsp_index */
830 u16 num_instreams;
831 u16 num_outstreams;
832 u16 num_mixers;
833 u16 version;
834 u8 sz_adapter_assert[HPI_STRING_LEN];
835};
836
837union hpi_adapterx_res {
838 struct hpi_adapter_res adapter;
839 struct {
840 u32 checksum;
841 u32 length;
842 u32 version;
843 } query_flash;
844 struct {
845 u16 sequence;
846 } program_flash;
847 struct {
848 u16 parameter1;
849 u16 parameter2;
850 } property_get;
851};
852
853struct hpi_stream_msg {
854 union {
855 struct hpi_msg_data data;
856 struct hpi_data_legacy32 data32;
857 u16 velocity;
858 struct hpi_punchinout pio;
859 u32 time_scale;
860 struct hpi_buffer buffer;
861 struct hpi_streamid stream;
862 } u;
863};
864
865struct hpi_stream_res {
866 union {
867 struct {
868 /* size of hardware buffer */
869 u32 buffer_size;
870 /* OutStream - data to play,
871 InStream - data recorded */
872 u32 data_available;
873 /* OutStream - samples played,
874 InStream - samples recorded */
875 u32 samples_transferred;
876 /* Adapter - OutStream - data to play,
877 InStream - data recorded */
878 u32 auxiliary_data_available;
879 u16 state; /* HPI_STATE_PLAYING, _STATE_STOPPED */
880 u16 padding;
881 } stream_info;
882 struct {
883 u32 buffer_size;
884 u32 data_available;
885 u32 samples_transfered;
886 u16 state;
887 u16 outstream_index;
888 u16 instream_index;
889 u16 padding;
890 u32 auxiliary_data_available;
891 } legacy_stream_info;
892 struct {
893 /* bitmap of grouped OutStreams */
894 u32 outstream_group_map;
895 /* bitmap of grouped InStreams */
896 u32 instream_group_map;
897 } group_info;
898 struct {
899 /* pointer to the buffer */
900 u8 *p_buffer;
901 /* pointer to the hostbuffer status */
902 struct hpi_hostbuffer_status *p_status;
903 } hostbuffer_info;
904 } u;
905};
906
907struct hpi_mixer_msg {
908 u16 control_index;
909 u16 control_type; /* = HPI_CONTROL_METER _VOLUME etc */
910 u16 padding1; /* maintain alignment of subsequent fields */
911 u16 node_type1; /* = HPI_SOURCENODE_LINEIN etc */
912 u16 node_index1; /* = 0..N */
913 u16 node_type2;
914 u16 node_index2;
915 u16 padding2; /* round to 4 bytes */
916};
917
918struct hpi_mixer_res {
919 u16 src_node_type; /* = HPI_SOURCENODE_LINEIN etc */
920 u16 src_node_index; /* = 0..N */
921 u16 dst_node_type;
922 u16 dst_node_index;
923 /* Also controlType for MixerGetControlByIndex */
924 u16 control_index;
925 /* may indicate which DSP the control is located on */
926 u16 dsp_index;
927};
928
929union hpi_mixerx_msg {
930 struct {
931 u16 starting_index;
932 u16 flags;
933 u32 length_in_bytes; /* length in bytes of p_data */
934 u32 p_data; /* pointer to a data array */
935 } gcabi;
936 struct {
937 u16 command;
938 u16 index;
939 } store; /* for HPI_MIXER_STORE message */
940};
941
942union hpi_mixerx_res {
943 struct {
944 u32 bytes_returned; /* size of items returned */
945 u32 p_data; /* pointer to data array */
946 u16 more_to_do; /* indicates if there is more to do */
947 } gcabi;
948};
949
950struct hpi_control_msg {
951 u16 attribute; /* control attribute or property */
952 u16 saved_index;
953 u32 param1; /* generic parameter 1 */
954 u32 param2; /* generic parameter 2 */
955 short an_log_value[HPI_MAX_CHANNELS];
956};
957
958struct hpi_control_union_msg {
959 u16 attribute; /* control attribute or property */
960 u16 saved_index; /* only used in ctrl save/restore */
961 union {
962 struct {
963 u32 param1; /* generic parameter 1 */
964 u32 param2; /* generic parameter 2 */
965 short an_log_value[HPI_MAX_CHANNELS];
966 } old;
967 union {
968 u32 frequency;
969 u32 gain;
970 u32 band;
971 u32 deemphasis;
972 u32 program;
973 struct {
974 u32 mode;
975 u32 value;
976 } mode;
977 u32 blend;
978 } tuner;
979 } u;
980};
981
982struct hpi_control_res {
983 /* Could make union. dwParam, anLogValue never used in same response */
984 u32 param1;
985 u32 param2;
986 short an_log_value[HPI_MAX_CHANNELS];
987};
988
989union hpi_control_union_res {
990 struct {
991 u32 param1;
992 u32 param2;
993 short an_log_value[HPI_MAX_CHANNELS];
994 } old;
995 union {
996 u32 band;
997 u32 frequency;
998 u32 gain;
999 u32 level;
1000 u32 deemphasis;
1001 struct {
1002 u32 data[2];
1003 u32 bLER;
1004 } rds;
1005 } tuner;
1006 struct {
1007 char sz_data[8];
1008 u32 remaining_chars;
1009 } chars8;
1010 char c_data12[12];
1011};
1012
1013/* HPI_CONTROLX_STRUCTURES */
1014
1015/* Message */
1016
1017/** Used for all HMI variables where max length <= 8 bytes
1018*/
1019struct hpi_controlx_msg_cobranet_data {
1020 u32 hmi_address;
1021 u32 byte_count;
1022 u32 data[2];
1023};
1024
1025/** Used for string data, and for packet bridge
1026*/
1027struct hpi_controlx_msg_cobranet_bigdata {
1028 u32 hmi_address;
1029 u32 byte_count;
1030 u8 *pb_data;
1031#ifndef HPI64BIT
1032 u32 padding;
1033#endif
1034};
1035
1036/** Used for PADS control reading of string fields.
1037*/
1038struct hpi_controlx_msg_pad_data {
1039 u32 field;
1040 u32 byte_count;
1041 u8 *pb_data;
1042#ifndef HPI64BIT
1043 u32 padding;
1044#endif
1045};
1046
1047/** Used for generic data
1048*/
1049
1050struct hpi_controlx_msg_generic {
1051 u32 param1;
1052 u32 param2;
1053};
1054
1055struct hpi_controlx_msg {
1056 u16 attribute; /* control attribute or property */
1057 u16 saved_index;
1058 union {
1059 struct hpi_controlx_msg_cobranet_data cobranet_data;
1060 struct hpi_controlx_msg_cobranet_bigdata cobranet_bigdata;
1061 struct hpi_controlx_msg_generic generic;
1062 struct hpi_controlx_msg_pad_data pad_data;
1063 /*struct param_value universal_value; */
1064 /* nothing extra to send for status read */
1065 } u;
1066};
1067
1068/* Response */
1069/**
1070*/
1071struct hpi_controlx_res_cobranet_data {
1072 u32 byte_count;
1073 u32 data[2];
1074};
1075
1076struct hpi_controlx_res_cobranet_bigdata {
1077 u32 byte_count;
1078};
1079
1080struct hpi_controlx_res_cobranet_status {
1081 u32 status;
1082 u32 readable_size;
1083 u32 writeable_size;
1084};
1085
1086struct hpi_controlx_res_generic {
1087 u32 param1;
1088 u32 param2;
1089};
1090
1091struct hpi_controlx_res {
1092 union {
1093 struct hpi_controlx_res_cobranet_bigdata cobranet_bigdata;
1094 struct hpi_controlx_res_cobranet_data cobranet_data;
1095 struct hpi_controlx_res_cobranet_status cobranet_status;
1096 struct hpi_controlx_res_generic generic;
1097 /*struct param_info universal_info; */
1098 /*struct param_value universal_value; */
1099 } u;
1100};
1101
1102struct hpi_nvmemory_msg {
1103 u16 address;
1104 u16 data;
1105};
1106
1107struct hpi_nvmemory_res {
1108 u16 size_in_bytes;
1109 u16 data;
1110};
1111
1112struct hpi_gpio_msg {
1113 u16 bit_index;
1114 u16 bit_data;
1115};
1116
1117struct hpi_gpio_res {
1118 u16 number_input_bits;
1119 u16 number_output_bits;
1120 u16 bit_data[4];
1121};
1122
1123struct hpi_async_msg {
1124 u32 events;
1125 u16 maximum_events;
1126 u16 padding;
1127};
1128
1129struct hpi_async_res {
1130 union {
1131 struct {
1132 u16 count;
1133 } count;
1134 struct {
1135 u32 events;
1136 u16 number_returned;
1137 u16 padding;
1138 } get;
1139 struct hpi_async_event event;
1140 } u;
1141};
1142
1143struct hpi_watchdog_msg {
1144 u32 time_ms;
1145};
1146
1147struct hpi_watchdog_res {
1148 u32 time_ms;
1149};
1150
1151struct hpi_clock_msg {
1152 u16 hours;
1153 u16 minutes;
1154 u16 seconds;
1155 u16 milli_seconds;
1156};
1157
1158struct hpi_clock_res {
1159 u16 size_in_bytes;
1160 u16 hours;
1161 u16 minutes;
1162 u16 seconds;
1163 u16 milli_seconds;
1164 u16 padding;
1165};
1166
1167struct hpi_profile_msg {
1168 u16 bin_index;
1169 u16 padding;
1170};
1171
1172struct hpi_profile_res_open {
1173 u16 max_profiles;
1174};
1175
1176struct hpi_profile_res_time {
1177 u32 micro_seconds;
1178 u32 call_count;
1179 u32 max_micro_seconds;
1180 u32 min_micro_seconds;
1181 u16 seconds;
1182};
1183
1184struct hpi_profile_res_name {
1185 u8 sz_name[32];
1186};
1187
1188struct hpi_profile_res {
1189 union {
1190 struct hpi_profile_res_open o;
1191 struct hpi_profile_res_time t;
1192 struct hpi_profile_res_name n;
1193 } u;
1194};
1195
1196struct hpi_message_header {
1197 u16 size; /* total size in bytes */
1198 u8 type; /* HPI_TYPE_MESSAGE */
1199 u8 version; /* message version */
1200 u16 object; /* HPI_OBJ_* */
1201 u16 function; /* HPI_SUBSYS_xxx, HPI_ADAPTER_xxx */
1202 u16 adapter_index; /* the adapter index */
1203 u16 obj_index; /* */
1204};
1205
1206struct hpi_message {
1207 /* following fields must match HPI_MESSAGE_HEADER */
1208 u16 size; /* total size in bytes */
1209 u8 type; /* HPI_TYPE_MESSAGE */
1210 u8 version; /* message version */
1211 u16 object; /* HPI_OBJ_* */
1212 u16 function; /* HPI_SUBSYS_xxx, HPI_ADAPTER_xxx */
1213 u16 adapter_index; /* the adapter index */
1214 u16 obj_index; /* */
1215 union {
1216 struct hpi_subsys_msg s;
1217 struct hpi_adapter_msg a;
1218 union hpi_adapterx_msg ax;
1219 struct hpi_stream_msg d;
1220 struct hpi_mixer_msg m;
1221 union hpi_mixerx_msg mx; /* extended mixer; */
1222 struct hpi_control_msg c; /* mixer control; */
1223 /* identical to struct hpi_control_msg,
1224 but field naming is improved */
1225 struct hpi_control_union_msg cu;
1226 struct hpi_controlx_msg cx; /* extended mixer control; */
1227 struct hpi_nvmemory_msg n;
1228 struct hpi_gpio_msg l; /* digital i/o */
1229 struct hpi_watchdog_msg w;
1230 struct hpi_clock_msg t; /* dsp time */
1231 struct hpi_profile_msg p;
1232 struct hpi_async_msg as;
1233 char fixed_size[32];
1234 } u;
1235};
1236
1237#define HPI_MESSAGE_SIZE_BY_OBJECT { \
1238 sizeof(struct hpi_message_header) , /* default, no object type 0 */ \
1239 sizeof(struct hpi_message_header) + sizeof(struct hpi_subsys_msg),\
1240 sizeof(struct hpi_message_header) + sizeof(union hpi_adapterx_msg),\
1241 sizeof(struct hpi_message_header) + sizeof(struct hpi_stream_msg),\
1242 sizeof(struct hpi_message_header) + sizeof(struct hpi_stream_msg),\
1243 sizeof(struct hpi_message_header) + sizeof(struct hpi_mixer_msg),\
1244 sizeof(struct hpi_message_header) , /* no node message */ \
1245 sizeof(struct hpi_message_header) + sizeof(struct hpi_control_msg),\
1246 sizeof(struct hpi_message_header) + sizeof(struct hpi_nvmemory_msg),\
1247 sizeof(struct hpi_message_header) + sizeof(struct hpi_gpio_msg),\
1248 sizeof(struct hpi_message_header) + sizeof(struct hpi_watchdog_msg),\
1249 sizeof(struct hpi_message_header) + sizeof(struct hpi_clock_msg),\
1250 sizeof(struct hpi_message_header) + sizeof(struct hpi_profile_msg),\
1251 sizeof(struct hpi_message_header) + sizeof(struct hpi_controlx_msg),\
1252 sizeof(struct hpi_message_header) + sizeof(struct hpi_async_msg) \
1253}
1254
1255struct hpi_response_header {
1256 u16 size;
1257 u8 type; /* HPI_TYPE_RESPONSE */
1258 u8 version; /* response version */
1259 u16 object; /* HPI_OBJ_* */
1260 u16 function; /* HPI_SUBSYS_xxx, HPI_ADAPTER_xxx */
1261 u16 error; /* HPI_ERROR_xxx */
1262 u16 specific_error; /* adapter specific error */
1263};
1264
1265struct hpi_response {
1266/* following fields must match HPI_RESPONSE_HEADER */
1267 u16 size;
1268 u8 type; /* HPI_TYPE_RESPONSE */
1269 u8 version; /* response version */
1270 u16 object; /* HPI_OBJ_* */
1271 u16 function; /* HPI_SUBSYS_xxx, HPI_ADAPTER_xxx */
1272 u16 error; /* HPI_ERROR_xxx */
1273 u16 specific_error; /* adapter specific error */
1274 union {
1275 struct hpi_subsys_res s;
1276 struct hpi_adapter_res a;
1277 union hpi_adapterx_res ax;
1278 struct hpi_stream_res d;
1279 struct hpi_mixer_res m;
1280 union hpi_mixerx_res mx; /* extended mixer; */
1281 struct hpi_control_res c; /* mixer control; */
1282 /* identical to hpi_control_res, but field naming is improved */
1283 union hpi_control_union_res cu;
1284 struct hpi_controlx_res cx; /* extended mixer control; */
1285 struct hpi_nvmemory_res n;
1286 struct hpi_gpio_res l; /* digital i/o */
1287 struct hpi_watchdog_res w;
1288 struct hpi_clock_res t; /* dsp time */
1289 struct hpi_profile_res p;
1290 struct hpi_async_res as;
1291 u8 bytes[52];
1292 } u;
1293};
1294
1295#define HPI_RESPONSE_SIZE_BY_OBJECT { \
1296 sizeof(struct hpi_response_header) ,/* default, no object type 0 */ \
1297 sizeof(struct hpi_response_header) + sizeof(struct hpi_subsys_res),\
1298 sizeof(struct hpi_response_header) + sizeof(union hpi_adapterx_res),\
1299 sizeof(struct hpi_response_header) + sizeof(struct hpi_stream_res),\
1300 sizeof(struct hpi_response_header) + sizeof(struct hpi_stream_res),\
1301 sizeof(struct hpi_response_header) + sizeof(struct hpi_mixer_res),\
1302 sizeof(struct hpi_response_header) , /* no node response */ \
1303 sizeof(struct hpi_response_header) + sizeof(struct hpi_control_res),\
1304 sizeof(struct hpi_response_header) + sizeof(struct hpi_nvmemory_res),\
1305 sizeof(struct hpi_response_header) + sizeof(struct hpi_gpio_res),\
1306 sizeof(struct hpi_response_header) + sizeof(struct hpi_watchdog_res),\
1307 sizeof(struct hpi_response_header) + sizeof(struct hpi_clock_res),\
1308 sizeof(struct hpi_response_header) + sizeof(struct hpi_profile_res),\
1309 sizeof(struct hpi_response_header) + sizeof(struct hpi_controlx_res),\
1310 sizeof(struct hpi_response_header) + sizeof(struct hpi_async_res) \
1311}
1312
1313/*********************** version 1 message/response *****************************/
1314#define HPINET_ETHERNET_DATA_SIZE (1500)
1315#define HPINET_IP_HDR_SIZE (20)
1316#define HPINET_IP_DATA_SIZE (HPINET_ETHERNET_DATA_SIZE - HPINET_IP_HDR_SIZE)
1317#define HPINET_UDP_HDR_SIZE (8)
1318#define HPINET_UDP_DATA_SIZE (HPINET_IP_DATA_SIZE - HPINET_UDP_HDR_SIZE)
1319#define HPINET_ASI_HDR_SIZE (2)
1320#define HPINET_ASI_DATA_SIZE (HPINET_UDP_DATA_SIZE - HPINET_ASI_HDR_SIZE)
1321
1322#define HPI_MAX_PAYLOAD_SIZE (HPINET_ASI_DATA_SIZE - 2)
1323
1324/* New style message/response, but still V0 compatible */
1325struct hpi_msg_adapter_get_info {
1326 struct hpi_message_header h;
1327};
1328
1329struct hpi_res_adapter_get_info {
1330 struct hpi_response_header h; /*v0 */
1331 struct hpi_adapter_res p;
1332};
1333
1334/* padding is so these are same size as v0 hpi_message */
1335struct hpi_msg_adapter_query_flash {
1336 struct hpi_message_header h;
1337 u32 offset;
1338 u8 pad_to_version0_size[sizeof(struct hpi_message) - /* V0 res */
1339 sizeof(struct hpi_message_header) - 1 * sizeof(u32)];
1340};
1341
1342/* padding is so these are same size as v0 hpi_response */
1343struct hpi_res_adapter_query_flash {
1344 struct hpi_response_header h;
1345 u32 checksum;
1346 u32 length;
1347 u32 version;
1348 u8 pad_to_version0_size[sizeof(struct hpi_response) - /* V0 res */
1349 sizeof(struct hpi_response_header) - 3 * sizeof(u32)];
1350};
1351
1352struct hpi_msg_adapter_start_flash {
1353 struct hpi_message_header h;
1354 u32 offset;
1355 u32 length;
1356 u32 key;
1357 u8 pad_to_version0_size[sizeof(struct hpi_message) - /* V0 res */
1358 sizeof(struct hpi_message_header) - 3 * sizeof(u32)];
1359};
1360
1361struct hpi_res_adapter_start_flash {
1362 struct hpi_response_header h;
1363 u8 pad_to_version0_size[sizeof(struct hpi_response) - /* V0 res */
1364 sizeof(struct hpi_response_header)];
1365};
1366
1367struct hpi_msg_adapter_program_flash_payload {
1368 u32 checksum;
1369 u16 sequence;
1370 u16 length;
1371 u16 offset; /**< offset from start of msg to data */
1372 u16 unused;
1373 /* ensure sizeof(header + payload) == sizeof(hpi_message_V0)
1374 because old firmware expects data after message of this size */
1375 u8 pad_to_version0_size[sizeof(struct hpi_message) - /* V0 message */
1376 sizeof(struct hpi_message_header) - sizeof(u32) -
1377 4 * sizeof(u16)];
1378};
1379
1380struct hpi_msg_adapter_program_flash {
1381 struct hpi_message_header h;
1382 struct hpi_msg_adapter_program_flash_payload p;
1383 u32 data[256];
1384};
1385
1386struct hpi_res_adapter_program_flash {
1387 struct hpi_response_header h;
1388 u16 sequence;
1389 u8 pad_to_version0_size[sizeof(struct hpi_response) - /* V0 res */
1390 sizeof(struct hpi_response_header) - sizeof(u16)];
1391};
1392
1393#if 1
1394#define hpi_message_header_v1 hpi_message_header
1395#define hpi_response_header_v1 hpi_response_header
1396#else
1397/* V1 headers in Addition to v0 headers */
1398struct hpi_message_header_v1 {
1399 struct hpi_message_header h0;
1400/* struct {
1401} h1; */
1402};
1403
1404struct hpi_response_header_v1 {
1405 struct hpi_response_header h0;
1406 struct {
1407 u16 adapter_index; /* the adapter index */
1408 u16 obj_index; /* object index */
1409 } h1;
1410};
1411#endif
1412
1413/* STRV HPI Packet */
1414struct hpi_msg_strv {
1415 struct hpi_message_header h;
1416 struct hpi_entity strv;
1417};
1418
1419struct hpi_res_strv {
1420 struct hpi_response_header h;
1421 struct hpi_entity strv;
1422};
1423#define MIN_STRV_PACKET_SIZE sizeof(struct hpi_res_strv)
1424
1425struct hpi_msg_payload_v0 {
1426 struct hpi_message_header h;
1427 union {
1428 struct hpi_subsys_msg s;
1429 struct hpi_adapter_msg a;
1430 union hpi_adapterx_msg ax;
1431 struct hpi_stream_msg d;
1432 struct hpi_mixer_msg m;
1433 union hpi_mixerx_msg mx;
1434 struct hpi_control_msg c;
1435 struct hpi_control_union_msg cu;
1436 struct hpi_controlx_msg cx;
1437 struct hpi_nvmemory_msg n;
1438 struct hpi_gpio_msg l;
1439 struct hpi_watchdog_msg w;
1440 struct hpi_clock_msg t;
1441 struct hpi_profile_msg p;
1442 struct hpi_async_msg as;
1443 } u;
1444};
1445
1446struct hpi_res_payload_v0 {
1447 struct hpi_response_header h;
1448 union {
1449 struct hpi_subsys_res s;
1450 struct hpi_adapter_res a;
1451 union hpi_adapterx_res ax;
1452 struct hpi_stream_res d;
1453 struct hpi_mixer_res m;
1454 union hpi_mixerx_res mx;
1455 struct hpi_control_res c;
1456 union hpi_control_union_res cu;
1457 struct hpi_controlx_res cx;
1458 struct hpi_nvmemory_res n;
1459 struct hpi_gpio_res l;
1460 struct hpi_watchdog_res w;
1461 struct hpi_clock_res t;
1462 struct hpi_profile_res p;
1463 struct hpi_async_res as;
1464 } u;
1465};
1466
1467union hpi_message_buffer_v1 {
1468 struct hpi_message m0; /* version 0 */
1469 struct hpi_message_header_v1 h;
1470 unsigned char buf[HPI_MAX_PAYLOAD_SIZE];
1471};
1472
1473union hpi_response_buffer_v1 {
1474 struct hpi_response r0; /* version 0 */
1475 struct hpi_response_header_v1 h;
1476 unsigned char buf[HPI_MAX_PAYLOAD_SIZE];
1477};
1478
1479compile_time_assert((sizeof(union hpi_message_buffer_v1) <=
1480 HPI_MAX_PAYLOAD_SIZE), message_buffer_ok);
1481compile_time_assert((sizeof(union hpi_response_buffer_v1) <=
1482 HPI_MAX_PAYLOAD_SIZE), response_buffer_ok);
1483
1484/*////////////////////////////////////////////////////////////////////////// */
1485/* declarations for compact control calls */
1486struct hpi_control_defn {
1487 u8 type;
1488 u8 channels;
1489 u8 src_node_type;
1490 u8 src_node_index;
1491 u8 dest_node_type;
1492 u8 dest_node_index;
1493};
1494
1495/*////////////////////////////////////////////////////////////////////////// */
1496/* declarations for control caching (internal to HPI<->DSP interaction) */
1497
1498/** A compact representation of (part of) a controls state.
1499Used for efficient transfer of the control state
1500between DSP and host or across a network
1501*/
1502struct hpi_control_cache_info {
1503 /** one of HPI_CONTROL_* */
1504 u8 control_type;
1505 /** The total size of cached information in 32-bit words. */
1506 u8 size_in32bit_words;
1507 /** The original index of the control on the DSP */
1508 u16 control_index;
1509};
1510
1511struct hpi_control_cache_single {
1512 struct hpi_control_cache_info i;
1513 union {
1514 struct { /* volume */
1515 u16 an_log[2];
1516 } v;
1517 struct { /* peak meter */
1518 u16 an_log_peak[2];
1519 u16 an_logRMS[2];
1520 } p;
1521 struct { /* channel mode */
1522 u16 mode;
1523 } m;
1524 struct { /* multiplexer */
1525 u16 source_node_type;
1526 u16 source_node_index;
1527 } x;
1528 struct { /* level/trim */
1529 u16 an_log[2];
1530 } l;
1531 struct { /* tuner - partial caching.
1532 some attributes go to the DSP. */
1533 u32 freq_ink_hz;
1534 u16 band;
1535 u16 level;
1536 } t;
1537 struct { /* AESEBU rx status */
1538 u32 error_status;
1539 u32 source;
1540 } aes3rx;
1541 struct { /* AESEBU tx */
1542 u32 format;
1543 } aes3tx;
1544 struct { /* tone detector */
1545 u16 state;
1546 } tone;
1547 struct { /* silence detector */
1548 u32 state;
1549 u32 count;
1550 } silence;
1551 struct { /* sample clock */
1552 u16 source;
1553 u16 source_index;
1554 u32 sample_rate;
1555 } clk;
1556 struct { /* microphone control */
1557 u16 state;
1558 } phantom_power;
1559 struct { /* generic control */
1560 u32 dw1;
1561 u32 dw2;
1562 } g;
1563 } u;
1564};
1565
1566struct hpi_control_cache_pad {
1567 struct hpi_control_cache_info i;
1568 u32 field_valid_flags;
1569 u8 c_channel[8];
1570 u8 c_artist[40];
1571 u8 c_title[40];
1572 u8 c_comment[200];
1573 u32 pTY;
1574 u32 pI;
1575 u32 traffic_supported;
1576 u32 traffic_anouncement;
1577};
1578
1579/*/////////////////////////////////////////////////////////////////////////// */
1580/* declarations for 2^N sized FIFO buffer (internal to HPI<->DSP interaction) */
1581struct hpi_fifo_buffer {
1582 u32 size;
1583 u32 dSP_index;
1584 u32 host_index;
1585};
1586
1587#ifndef DISABLE_PRAGMA_PACK1
1588#pragma pack(pop)
1589#endif
1590
1591/* skip host side function declarations for DSP
1592 compile and documentation extraction */
1593
1594char hpi_handle_object(const u32 handle);
1595
1596void hpi_handle_to_indexes(const u32 handle, u16 *pw_adapter_index,
1597 u16 *pw_object_index);
1598
1599u32 hpi_indexes_to_handle(const char c_object, const u16 adapter_index,
1600 const u16 object_index);
1601
1602/*////////////////////////////////////////////////////////////////////////// */
1603
1604/* main HPI entry point */
1605hpi_handler_func hpi_send_recv;
1606
1607/* UDP message */
1608void hpi_send_recvUDP(struct hpi_message *phm, struct hpi_response *phr,
1609 const unsigned int timeout);
1610
1611/* used in PnP OS/driver */
1612u16 hpi_subsys_create_adapter(const struct hpi_hsubsys *ph_subsys,
1613 const struct hpi_resource *p_resource, u16 *pw_adapter_index);
1614
1615u16 hpi_subsys_delete_adapter(const struct hpi_hsubsys *ph_subsys,
1616 u16 adapter_index);
1617
1618u16 hpi_outstream_host_buffer_get_info(const struct hpi_hsubsys *ph_subsys,
1619 u32 h_outstream, u8 **pp_buffer,
1620 struct hpi_hostbuffer_status **pp_status);
1621
1622u16 hpi_instream_host_buffer_get_info(const struct hpi_hsubsys *ph_subsys,
1623 u32 h_instream, u8 **pp_buffer,
1624 struct hpi_hostbuffer_status **pp_status);
1625
1626u16 hpi_adapter_restart(u16 adapter_index);
1627
1628/*
1629The following 3 functions were last declared in header files for
1630driver 3.10. HPI_ControlQuery() used to be the recommended way
1631of getting a volume range. Declared here for binary asihpi32.dll
1632compatibility.
1633*/
1634
1635void hpi_format_to_msg(struct hpi_msg_format *pMF,
1636 const struct hpi_format *pF);
1637void hpi_stream_response_to_legacy(struct hpi_stream_res *pSR);
1638
1639/*////////////////////////////////////////////////////////////////////////// */
1640/* declarations for individual HPI entry points */
1641hpi_handler_func HPI_1000;
1642hpi_handler_func HPI_6000;
1643hpi_handler_func HPI_6205;
1644hpi_handler_func HPI_COMMON;
1645
1646#endif /* _HPI_INTERNAL_H_ */
diff --git a/sound/pci/asihpi/hpicmn.c b/sound/pci/asihpi/hpicmn.c
new file mode 100644
index 000000000000..fcd64539d9ef
--- /dev/null
+++ b/sound/pci/asihpi/hpicmn.c
@@ -0,0 +1,631 @@
1/******************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
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, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19\file hpicmn.c
20
21 Common functions used by hpixxxx.c modules
22
23(C) Copyright AudioScience Inc. 1998-2003
24*******************************************************************************/
25#define SOURCEFILE_NAME "hpicmn.c"
26
27#include "hpi_internal.h"
28#include "hpidebug.h"
29#include "hpicmn.h"
30
31struct hpi_adapters_list {
32 struct hpios_spinlock list_lock;
33 struct hpi_adapter_obj adapter[HPI_MAX_ADAPTERS];
34 u16 gw_num_adapters;
35};
36
37static struct hpi_adapters_list adapters;
38
39/**
40* Given an HPI Message that was sent out and a response that was received,
41* validate that the response has the correct fields filled in,
42* i.e ObjectType, Function etc
43**/
44u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr)
45{
46 u16 error = 0;
47
48 if ((phr->type != HPI_TYPE_RESPONSE)
49 || (phr->object != phm->object)
50 || (phr->function != phm->function))
51 error = HPI_ERROR_INVALID_RESPONSE;
52
53 return error;
54}
55
56u16 hpi_add_adapter(struct hpi_adapter_obj *pao)
57{
58 u16 retval = 0;
59 /*HPI_ASSERT(pao->wAdapterType); */
60
61 hpios_alistlock_lock(&adapters);
62
63 if (pao->index >= HPI_MAX_ADAPTERS) {
64 retval = HPI_ERROR_BAD_ADAPTER_NUMBER;
65 goto unlock;
66 }
67
68 if (adapters.adapter[pao->index].adapter_type) {
69 {
70 retval = HPI_DUPLICATE_ADAPTER_NUMBER;
71 goto unlock;
72 }
73 }
74 adapters.adapter[pao->index] = *pao;
75 hpios_dsplock_init(&adapters.adapter[pao->index]);
76 adapters.gw_num_adapters++;
77
78unlock:
79 hpios_alistlock_un_lock(&adapters);
80 return retval;
81}
82
83void hpi_delete_adapter(struct hpi_adapter_obj *pao)
84{
85 memset(pao, 0, sizeof(struct hpi_adapter_obj));
86
87 hpios_alistlock_lock(&adapters);
88 adapters.gw_num_adapters--; /* dec the number of adapters */
89 hpios_alistlock_un_lock(&adapters);
90}
91
92/**
93* FindAdapter returns a pointer to the struct hpi_adapter_obj with
94* index wAdapterIndex in an HPI_ADAPTERS_LIST structure.
95*
96*/
97struct hpi_adapter_obj *hpi_find_adapter(u16 adapter_index)
98{
99 struct hpi_adapter_obj *pao = NULL;
100
101 if (adapter_index >= HPI_MAX_ADAPTERS) {
102 HPI_DEBUG_LOG(VERBOSE, "find_adapter invalid index %d ",
103 adapter_index);
104 return NULL;
105 }
106
107 pao = &adapters.adapter[adapter_index];
108 if (pao->adapter_type != 0) {
109 /*
110 HPI_DEBUG_LOG(VERBOSE, "Found adapter index %d\n",
111 wAdapterIndex);
112 */
113 return pao;
114 } else {
115 /*
116 HPI_DEBUG_LOG(VERBOSE, "No adapter index %d\n",
117 wAdapterIndex);
118 */
119 return NULL;
120 }
121}
122
123/**
124*
125* wipe an HPI_ADAPTERS_LIST structure.
126*
127**/
128static void wipe_adapter_list(void
129 )
130{
131 memset(&adapters, 0, sizeof(adapters));
132}
133
134/**
135* SubSysGetAdapters fills awAdapterList in an struct hpi_response structure
136* with all adapters in the given HPI_ADAPTERS_LIST.
137*
138*/
139static void subsys_get_adapters(struct hpi_response *phr)
140{
141 /* fill in the response adapter array with the position */
142 /* identified by the adapter number/index of the adapters in */
143 /* this HPI */
144 /* i.e. if we have an A120 with it's jumper set to */
145 /* Adapter Number 2 then put an Adapter type A120 in the */
146 /* array in position 1 */
147 /* NOTE: AdapterNumber is 1..N, Index is 0..N-1 */
148
149 /* input: NONE */
150 /* output: wNumAdapters */
151 /* awAdapter[] */
152 /* */
153
154 short i;
155 struct hpi_adapter_obj *pao = NULL;
156
157 HPI_DEBUG_LOG(VERBOSE, "subsys_get_adapters\n");
158
159 /* for each adapter, place it's type in the position of the array */
160 /* corresponding to it's adapter number */
161 for (i = 0; i < adapters.gw_num_adapters; i++) {
162 pao = &adapters.adapter[i];
163 if (phr->u.s.aw_adapter_list[pao->index] != 0) {
164 phr->error = HPI_DUPLICATE_ADAPTER_NUMBER;
165 phr->specific_error = pao->index;
166 return;
167 }
168 phr->u.s.aw_adapter_list[pao->index] = pao->adapter_type;
169 }
170
171 phr->u.s.num_adapters = adapters.gw_num_adapters;
172 phr->error = 0; /* the function completed OK; */
173}
174
175static unsigned int control_cache_alloc_check(struct hpi_control_cache *pC)
176{
177 unsigned int i;
178 int cached = 0;
179 if (!pC)
180 return 0;
181 if ((!pC->init) && (pC->p_cache != NULL) && (pC->control_count)
182 && (pC->cache_size_in_bytes)
183 ) {
184 u32 *p_master_cache;
185 pC->init = 1;
186
187 p_master_cache = (u32 *)pC->p_cache;
188 HPI_DEBUG_LOG(VERBOSE, "check %d controls\n",
189 pC->control_count);
190 for (i = 0; i < pC->control_count; i++) {
191 struct hpi_control_cache_info *info =
192 (struct hpi_control_cache_info *)
193 p_master_cache;
194
195 if (info->control_type) {
196 pC->p_info[i] = info;
197 cached++;
198 } else
199 pC->p_info[i] = NULL;
200
201 if (info->size_in32bit_words)
202 p_master_cache += info->size_in32bit_words;
203 else
204 p_master_cache +=
205 sizeof(struct
206 hpi_control_cache_single) /
207 sizeof(u32);
208
209 HPI_DEBUG_LOG(VERBOSE,
210 "cached %d, pinfo %p index %d type %d\n",
211 cached, pC->p_info[i], info->control_index,
212 info->control_type);
213 }
214 /*
215 We didn't find anything to cache, so try again later !
216 */
217 if (!cached)
218 pC->init = 0;
219 }
220 return pC->init;
221}
222
223/** Find a control.
224*/
225static short find_control(struct hpi_message *phm,
226 struct hpi_control_cache *p_cache, struct hpi_control_cache_info **pI,
227 u16 *pw_control_index)
228{
229 *pw_control_index = phm->obj_index;
230
231 if (!control_cache_alloc_check(p_cache)) {
232 HPI_DEBUG_LOG(VERBOSE,
233 "control_cache_alloc_check() failed. adap%d ci%d\n",
234 phm->adapter_index, *pw_control_index);
235 return 0;
236 }
237
238 *pI = p_cache->p_info[*pw_control_index];
239 if (!*pI) {
240 HPI_DEBUG_LOG(VERBOSE, "uncached adap %d, control %d\n",
241 phm->adapter_index, *pw_control_index);
242 return 0;
243 } else {
244 HPI_DEBUG_LOG(VERBOSE, "find_control() type %d\n",
245 (*pI)->control_type);
246 }
247 return 1;
248}
249
250/** Used by the kernel driver to figure out if a buffer needs mapping.
251 */
252short hpi_check_buffer_mapping(struct hpi_control_cache *p_cache,
253 struct hpi_message *phm, void **p, unsigned int *pN)
254{
255 *pN = 0;
256 *p = NULL;
257 if ((phm->function == HPI_CONTROL_GET_STATE)
258 && (phm->object == HPI_OBJ_CONTROLEX)
259 ) {
260 u16 control_index;
261 struct hpi_control_cache_info *pI;
262
263 if (!find_control(phm, p_cache, &pI, &control_index))
264 return 0;
265 }
266 return 0;
267}
268
269/* allow unified treatment of several string fields within struct */
270#define HPICMN_PAD_OFS_AND_SIZE(m) {\
271 offsetof(struct hpi_control_cache_pad, m), \
272 sizeof(((struct hpi_control_cache_pad *)(NULL))->m) }
273
274struct pad_ofs_size {
275 unsigned int offset;
276 unsigned int field_size;
277};
278
279static struct pad_ofs_size pad_desc[] = {
280 HPICMN_PAD_OFS_AND_SIZE(c_channel), /* HPI_PAD_CHANNEL_NAME */
281 HPICMN_PAD_OFS_AND_SIZE(c_artist), /* HPI_PAD_ARTIST */
282 HPICMN_PAD_OFS_AND_SIZE(c_title), /* HPI_PAD_TITLE */
283 HPICMN_PAD_OFS_AND_SIZE(c_comment), /* HPI_PAD_COMMENT */
284};
285
286/** CheckControlCache checks the cache and fills the struct hpi_response
287 * accordingly. It returns one if a cache hit occurred, zero otherwise.
288 */
289short hpi_check_control_cache(struct hpi_control_cache *p_cache,
290 struct hpi_message *phm, struct hpi_response *phr)
291{
292 short found = 1;
293 u16 control_index;
294 struct hpi_control_cache_info *pI;
295 struct hpi_control_cache_single *pC;
296 struct hpi_control_cache_pad *p_pad;
297
298 if (!find_control(phm, p_cache, &pI, &control_index))
299 return 0;
300
301 phr->error = 0;
302
303 /* pC is the default cached control strucure. May be cast to
304 something else in the following switch statement.
305 */
306 pC = (struct hpi_control_cache_single *)pI;
307 p_pad = (struct hpi_control_cache_pad *)pI;
308
309 switch (pI->control_type) {
310
311 case HPI_CONTROL_METER:
312 if (phm->u.c.attribute == HPI_METER_PEAK) {
313 phr->u.c.an_log_value[0] = pC->u.p.an_log_peak[0];
314 phr->u.c.an_log_value[1] = pC->u.p.an_log_peak[1];
315 } else if (phm->u.c.attribute == HPI_METER_RMS) {
316 phr->u.c.an_log_value[0] = pC->u.p.an_logRMS[0];
317 phr->u.c.an_log_value[1] = pC->u.p.an_logRMS[1];
318 } else
319 found = 0;
320 break;
321 case HPI_CONTROL_VOLUME:
322 if (phm->u.c.attribute == HPI_VOLUME_GAIN) {
323 phr->u.c.an_log_value[0] = pC->u.v.an_log[0];
324 phr->u.c.an_log_value[1] = pC->u.v.an_log[1];
325 } else
326 found = 0;
327 break;
328 case HPI_CONTROL_MULTIPLEXER:
329 if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) {
330 phr->u.c.param1 = pC->u.x.source_node_type;
331 phr->u.c.param2 = pC->u.x.source_node_index;
332 } else {
333 found = 0;
334 }
335 break;
336 case HPI_CONTROL_CHANNEL_MODE:
337 if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE)
338 phr->u.c.param1 = pC->u.m.mode;
339 else
340 found = 0;
341 break;
342 case HPI_CONTROL_LEVEL:
343 if (phm->u.c.attribute == HPI_LEVEL_GAIN) {
344 phr->u.c.an_log_value[0] = pC->u.l.an_log[0];
345 phr->u.c.an_log_value[1] = pC->u.l.an_log[1];
346 } else
347 found = 0;
348 break;
349 case HPI_CONTROL_TUNER:
350 if (phm->u.c.attribute == HPI_TUNER_FREQ)
351 phr->u.c.param1 = pC->u.t.freq_ink_hz;
352 else if (phm->u.c.attribute == HPI_TUNER_BAND)
353 phr->u.c.param1 = pC->u.t.band;
354 else if ((phm->u.c.attribute == HPI_TUNER_LEVEL)
355 && (phm->u.c.param1 == HPI_TUNER_LEVEL_AVERAGE))
356 phr->u.c.param1 = pC->u.t.level;
357 else
358 found = 0;
359 break;
360 case HPI_CONTROL_AESEBU_RECEIVER:
361 if (phm->u.c.attribute == HPI_AESEBURX_ERRORSTATUS)
362 phr->u.c.param1 = pC->u.aes3rx.error_status;
363 else if (phm->u.c.attribute == HPI_AESEBURX_FORMAT)
364 phr->u.c.param1 = pC->u.aes3rx.source;
365 else
366 found = 0;
367 break;
368 case HPI_CONTROL_AESEBU_TRANSMITTER:
369 if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT)
370 phr->u.c.param1 = pC->u.aes3tx.format;
371 else
372 found = 0;
373 break;
374 case HPI_CONTROL_TONEDETECTOR:
375 if (phm->u.c.attribute == HPI_TONEDETECTOR_STATE)
376 phr->u.c.param1 = pC->u.tone.state;
377 else
378 found = 0;
379 break;
380 case HPI_CONTROL_SILENCEDETECTOR:
381 if (phm->u.c.attribute == HPI_SILENCEDETECTOR_STATE) {
382 phr->u.c.param1 = pC->u.silence.state;
383 phr->u.c.param2 = pC->u.silence.count;
384 } else
385 found = 0;
386 break;
387 case HPI_CONTROL_MICROPHONE:
388 if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER)
389 phr->u.c.param1 = pC->u.phantom_power.state;
390 else
391 found = 0;
392 break;
393 case HPI_CONTROL_SAMPLECLOCK:
394 if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE)
395 phr->u.c.param1 = pC->u.clk.source;
396 else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE_INDEX) {
397 if (pC->u.clk.source_index ==
398 HPI_ERROR_ILLEGAL_CACHE_VALUE) {
399 phr->u.c.param1 = 0;
400 phr->error = HPI_ERROR_INVALID_OPERATION;
401 } else
402 phr->u.c.param1 = pC->u.clk.source_index;
403 } else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SAMPLERATE)
404 phr->u.c.param1 = pC->u.clk.sample_rate;
405 else
406 found = 0;
407 break;
408 case HPI_CONTROL_PAD:
409
410 if (!(p_pad->field_valid_flags & (1 <<
411 HPI_CTL_ATTR_INDEX(phm->u.c.
412 attribute)))) {
413 phr->error = HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
414 break;
415 }
416
417 if (phm->u.c.attribute == HPI_PAD_PROGRAM_ID)
418 phr->u.c.param1 = p_pad->pI;
419 else if (phm->u.c.attribute == HPI_PAD_PROGRAM_TYPE)
420 phr->u.c.param1 = p_pad->pTY;
421 else {
422 unsigned int index =
423 HPI_CTL_ATTR_INDEX(phm->u.c.attribute) - 1;
424 unsigned int offset = phm->u.c.param1;
425 unsigned int pad_string_len, field_size;
426 char *pad_string;
427 unsigned int tocopy;
428
429 HPI_DEBUG_LOG(VERBOSE, "PADS HPI_PADS_ %d\n",
430 phm->u.c.attribute);
431
432 if (index > ARRAY_SIZE(pad_desc) - 1) {
433 phr->error =
434 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
435 break;
436 }
437
438 pad_string = ((char *)p_pad) + pad_desc[index].offset;
439 field_size = pad_desc[index].field_size;
440 /* Ensure null terminator */
441 pad_string[field_size - 1] = 0;
442
443 pad_string_len = strlen(pad_string) + 1;
444
445 if (offset > pad_string_len) {
446 phr->error = HPI_ERROR_INVALID_CONTROL_VALUE;
447 break;
448 }
449
450 tocopy = pad_string_len - offset;
451 if (tocopy > sizeof(phr->u.cu.chars8.sz_data))
452 tocopy = sizeof(phr->u.cu.chars8.sz_data);
453
454 HPI_DEBUG_LOG(VERBOSE,
455 "PADS memcpy(%d), offset %d \n", tocopy,
456 offset);
457 memcpy(phr->u.cu.chars8.sz_data, &pad_string[offset],
458 tocopy);
459
460 phr->u.cu.chars8.remaining_chars =
461 pad_string_len - offset - tocopy;
462 }
463 break;
464 default:
465 found = 0;
466 break;
467 }
468
469 if (found)
470 HPI_DEBUG_LOG(VERBOSE,
471 "cached adap %d, ctl %d, type %d, attr %d\n",
472 phm->adapter_index, pI->control_index,
473 pI->control_type, phm->u.c.attribute);
474 else
475 HPI_DEBUG_LOG(VERBOSE,
476 "uncached adap %d, ctl %d, ctl type %d\n",
477 phm->adapter_index, pI->control_index,
478 pI->control_type);
479
480 if (found)
481 phr->size =
482 sizeof(struct hpi_response_header) +
483 sizeof(struct hpi_control_res);
484
485 return found;
486}
487
488/** Updates the cache with Set values.
489
490Only update if no error.
491Volume and Level return the limited values in the response, so use these
492Multiplexer does so use sent values
493*/
494void hpi_sync_control_cache(struct hpi_control_cache *p_cache,
495 struct hpi_message *phm, struct hpi_response *phr)
496{
497 u16 control_index;
498 struct hpi_control_cache_single *pC;
499 struct hpi_control_cache_info *pI;
500
501 if (phr->error)
502 return;
503
504 if (!find_control(phm, p_cache, &pI, &control_index))
505 return;
506
507 /* pC is the default cached control strucure.
508 May be cast to something else in the following switch statement.
509 */
510 pC = (struct hpi_control_cache_single *)pI;
511
512 switch (pI->control_type) {
513 case HPI_CONTROL_VOLUME:
514 if (phm->u.c.attribute == HPI_VOLUME_GAIN) {
515 pC->u.v.an_log[0] = phr->u.c.an_log_value[0];
516 pC->u.v.an_log[1] = phr->u.c.an_log_value[1];
517 }
518 break;
519 case HPI_CONTROL_MULTIPLEXER:
520 /* mux does not return its setting on Set command. */
521 if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) {
522 pC->u.x.source_node_type = (u16)phm->u.c.param1;
523 pC->u.x.source_node_index = (u16)phm->u.c.param2;
524 }
525 break;
526 case HPI_CONTROL_CHANNEL_MODE:
527 /* mode does not return its setting on Set command. */
528 if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE)
529 pC->u.m.mode = (u16)phm->u.c.param1;
530 break;
531 case HPI_CONTROL_LEVEL:
532 if (phm->u.c.attribute == HPI_LEVEL_GAIN) {
533 pC->u.v.an_log[0] = phr->u.c.an_log_value[0];
534 pC->u.v.an_log[1] = phr->u.c.an_log_value[1];
535 }
536 break;
537 case HPI_CONTROL_MICROPHONE:
538 if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER)
539 pC->u.phantom_power.state = (u16)phm->u.c.param1;
540 break;
541 case HPI_CONTROL_AESEBU_TRANSMITTER:
542 if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT)
543 pC->u.aes3tx.format = phm->u.c.param1;
544 break;
545 case HPI_CONTROL_AESEBU_RECEIVER:
546 if (phm->u.c.attribute == HPI_AESEBURX_FORMAT)
547 pC->u.aes3rx.source = phm->u.c.param1;
548 break;
549 case HPI_CONTROL_SAMPLECLOCK:
550 if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE)
551 pC->u.clk.source = (u16)phm->u.c.param1;
552 else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE_INDEX)
553 pC->u.clk.source_index = (u16)phm->u.c.param1;
554 else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SAMPLERATE)
555 pC->u.clk.sample_rate = phm->u.c.param1;
556 break;
557 default:
558 break;
559 }
560}
561
562struct hpi_control_cache *hpi_alloc_control_cache(const u32
563 number_of_controls, const u32 size_in_bytes,
564 struct hpi_control_cache_info *pDSP_control_buffer)
565{
566 struct hpi_control_cache *p_cache =
567 kmalloc(sizeof(*p_cache), GFP_KERNEL);
568 p_cache->cache_size_in_bytes = size_in_bytes;
569 p_cache->control_count = number_of_controls;
570 p_cache->p_cache =
571 (struct hpi_control_cache_single *)pDSP_control_buffer;
572 p_cache->init = 0;
573 p_cache->p_info =
574 kmalloc(sizeof(*p_cache->p_info) * p_cache->control_count,
575 GFP_KERNEL);
576 return p_cache;
577}
578
579void hpi_free_control_cache(struct hpi_control_cache *p_cache)
580{
581 if (p_cache->init) {
582 kfree(p_cache->p_info);
583 p_cache->p_info = NULL;
584 p_cache->init = 0;
585 kfree(p_cache);
586 }
587}
588
589static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
590{
591
592 switch (phm->function) {
593 case HPI_SUBSYS_OPEN:
594 case HPI_SUBSYS_CLOSE:
595 case HPI_SUBSYS_DRIVER_UNLOAD:
596 phr->error = 0;
597 break;
598 case HPI_SUBSYS_DRIVER_LOAD:
599 wipe_adapter_list();
600 hpios_alistlock_init(&adapters);
601 phr->error = 0;
602 break;
603 case HPI_SUBSYS_GET_INFO:
604 subsys_get_adapters(phr);
605 break;
606 case HPI_SUBSYS_CREATE_ADAPTER:
607 case HPI_SUBSYS_DELETE_ADAPTER:
608 phr->error = 0;
609 break;
610 default:
611 phr->error = HPI_ERROR_INVALID_FUNC;
612 break;
613 }
614}
615
616void HPI_COMMON(struct hpi_message *phm, struct hpi_response *phr)
617{
618 switch (phm->type) {
619 case HPI_TYPE_MESSAGE:
620 switch (phm->object) {
621 case HPI_OBJ_SUBSYSTEM:
622 subsys_message(phm, phr);
623 break;
624 }
625 break;
626
627 default:
628 phr->error = HPI_ERROR_INVALID_TYPE;
629 break;
630 }
631}
diff --git a/sound/pci/asihpi/hpicmn.h b/sound/pci/asihpi/hpicmn.h
new file mode 100644
index 000000000000..6229022f56cb
--- /dev/null
+++ b/sound/pci/asihpi/hpicmn.h
@@ -0,0 +1,64 @@
1/**
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
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, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19*/
20
21struct hpi_adapter_obj {
22 struct hpi_pci pci; /* PCI info - bus#,dev#,address etc */
23 u16 adapter_type; /* ASI6701 etc */
24 u16 index; /* */
25 u16 open; /* =1 when adapter open */
26 u16 mixer_open;
27
28 struct hpios_spinlock dsp_lock;
29
30 u16 dsp_crashed;
31 u16 has_control_cache;
32 void *priv;
33};
34
35struct hpi_control_cache {
36 u32 init; /**< indicates whether the
37 structures are initialized */
38 u32 control_count;
39 u32 cache_size_in_bytes;
40 struct hpi_control_cache_info
41 **p_info; /**< pointer to allocated memory of
42 lookup pointers. */
43 struct hpi_control_cache_single
44 *p_cache; /**< pointer to DSP's control cache. */
45};
46
47struct hpi_adapter_obj *hpi_find_adapter(u16 adapter_index);
48u16 hpi_add_adapter(struct hpi_adapter_obj *pao);
49
50void hpi_delete_adapter(struct hpi_adapter_obj *pao);
51
52short hpi_check_control_cache(struct hpi_control_cache *pC,
53 struct hpi_message *phm, struct hpi_response *phr);
54struct hpi_control_cache *hpi_alloc_control_cache(const u32
55 number_of_controls, const u32 size_in_bytes,
56 struct hpi_control_cache_info
57 *pDSP_control_buffer);
58void hpi_free_control_cache(struct hpi_control_cache *p_cache);
59
60void hpi_sync_control_cache(struct hpi_control_cache *pC,
61 struct hpi_message *phm, struct hpi_response *phr);
62u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr);
63short hpi_check_buffer_mapping(struct hpi_control_cache *p_cache,
64 struct hpi_message *phm, void **p, unsigned int *pN);
diff --git a/sound/pci/asihpi/hpidebug.c b/sound/pci/asihpi/hpidebug.c
new file mode 100644
index 000000000000..4cd85a401b34
--- /dev/null
+++ b/sound/pci/asihpi/hpidebug.c
@@ -0,0 +1,225 @@
1/************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
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, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19Debug macro translation.
20
21************************************************************************/
22
23#include "hpi_internal.h"
24#include "hpidebug.h"
25
26/* Debug level; 0 quiet; 1 informative, 2 debug, 3 verbose debug. */
27int hpi_debug_level = HPI_DEBUG_LEVEL_DEFAULT;
28
29void hpi_debug_init(void)
30{
31 printk(KERN_INFO "debug start\n");
32}
33
34int hpi_debug_level_set(int level)
35{
36 int old_level;
37
38 old_level = hpi_debug_level;
39 hpi_debug_level = level;
40 return old_level;
41}
42
43int hpi_debug_level_get(void)
44{
45 return hpi_debug_level;
46}
47
48#ifdef HPIOS_DEBUG_PRINT
49/* implies OS has no printf-like function */
50#include <stdarg.h>
51
52void hpi_debug_printf(char *fmt, ...)
53{
54 va_list arglist;
55 char buffer[128];
56
57 va_start(arglist, fmt);
58
59 if (buffer[0])
60 HPIOS_DEBUG_PRINT(buffer);
61 va_end(arglist);
62}
63#endif
64
65struct treenode {
66 void *array;
67 unsigned int num_elements;
68};
69
70#define make_treenode_from_array(nodename, array) \
71static void *tmp_strarray_##nodename[] = array; \
72static struct treenode nodename = { \
73 &tmp_strarray_##nodename, \
74 ARRAY_SIZE(tmp_strarray_##nodename) \
75};
76
77#define get_treenode_elem(node_ptr, idx, type) \
78 (&(*((type *)(node_ptr)->array)[idx]))
79
80make_treenode_from_array(hpi_control_type_strings, HPI_CONTROL_TYPE_STRINGS)
81
82 make_treenode_from_array(hpi_subsys_strings, HPI_SUBSYS_STRINGS)
83 make_treenode_from_array(hpi_adapter_strings, HPI_ADAPTER_STRINGS)
84 make_treenode_from_array(hpi_istream_strings, HPI_ISTREAM_STRINGS)
85 make_treenode_from_array(hpi_ostream_strings, HPI_OSTREAM_STRINGS)
86 make_treenode_from_array(hpi_mixer_strings, HPI_MIXER_STRINGS)
87 make_treenode_from_array(hpi_node_strings,
88 {
89 "NODE is invalid object"})
90
91 make_treenode_from_array(hpi_control_strings, HPI_CONTROL_STRINGS)
92 make_treenode_from_array(hpi_nvmemory_strings, HPI_OBJ_STRINGS)
93 make_treenode_from_array(hpi_digitalio_strings, HPI_DIGITALIO_STRINGS)
94 make_treenode_from_array(hpi_watchdog_strings, HPI_WATCHDOG_STRINGS)
95 make_treenode_from_array(hpi_clock_strings, HPI_CLOCK_STRINGS)
96 make_treenode_from_array(hpi_profile_strings, HPI_PROFILE_STRINGS)
97 make_treenode_from_array(hpi_asyncevent_strings, HPI_ASYNCEVENT_STRINGS)
98#define HPI_FUNCTION_STRINGS \
99{ \
100 &hpi_subsys_strings,\
101 &hpi_adapter_strings,\
102 &hpi_ostream_strings,\
103 &hpi_istream_strings,\
104 &hpi_mixer_strings,\
105 &hpi_node_strings,\
106 &hpi_control_strings,\
107 &hpi_nvmemory_strings,\
108 &hpi_digitalio_strings,\
109 &hpi_watchdog_strings,\
110 &hpi_clock_strings,\
111 &hpi_profile_strings,\
112 &hpi_control_strings, \
113 &hpi_asyncevent_strings \
114};
115 make_treenode_from_array(hpi_function_strings, HPI_FUNCTION_STRINGS)
116
117 compile_time_assert(HPI_OBJ_MAXINDEX == 14, obj_list_doesnt_match);
118
119static char *hpi_function_string(unsigned int function)
120{
121 unsigned int object;
122 struct treenode *tmp;
123
124 object = function / HPI_OBJ_FUNCTION_SPACING;
125 function = function - object * HPI_OBJ_FUNCTION_SPACING;
126
127 if (object == 0 || object == HPI_OBJ_NODE
128 || object > hpi_function_strings.num_elements)
129 return "invalid object";
130
131 tmp = get_treenode_elem(&hpi_function_strings, object - 1,
132 struct treenode *);
133
134 if (function == 0 || function > tmp->num_elements)
135 return "invalid function";
136
137 return get_treenode_elem(tmp, function - 1, char *);
138}
139
140void hpi_debug_message(struct hpi_message *phm, char *sz_fileline)
141{
142 if (phm) {
143 if ((phm->object <= HPI_OBJ_MAXINDEX) && phm->object) {
144 u16 index = 0;
145 u16 attrib = 0;
146 int is_control = 0;
147
148 index = phm->obj_index;
149 switch (phm->object) {
150 case HPI_OBJ_ADAPTER:
151 case HPI_OBJ_PROFILE:
152 break;
153 case HPI_OBJ_MIXER:
154 if (phm->function ==
155 HPI_MIXER_GET_CONTROL_BY_INDEX)
156 index = phm->u.m.control_index;
157 break;
158 case HPI_OBJ_OSTREAM:
159 case HPI_OBJ_ISTREAM:
160 break;
161
162 case HPI_OBJ_CONTROLEX:
163 case HPI_OBJ_CONTROL:
164 if (phm->version == 1)
165 attrib = HPI_CTL_ATTR(UNIVERSAL, 1);
166 else
167 attrib = phm->u.c.attribute;
168 is_control = 1;
169 break;
170 default:
171 break;
172 }
173
174 if (is_control && (attrib & 0xFF00)) {
175 int control_type = (attrib & 0xFF00) >> 8;
176 int attr_index = HPI_CTL_ATTR_INDEX(attrib);
177 /* note the KERN facility level
178 is in szFileline already */
179 printk("%s adapter %d %s "
180 "ctrl_index x%04x %s %d\n",
181 sz_fileline, phm->adapter_index,
182 hpi_function_string(phm->function),
183 index,
184 get_treenode_elem
185 (&hpi_control_type_strings,
186 control_type, char *),
187 attr_index);
188
189 } else
190 printk("%s adapter %d %s "
191 "idx x%04x attr x%04x \n",
192 sz_fileline, phm->adapter_index,
193 hpi_function_string(phm->function),
194 index, attrib);
195 } else {
196 printk("adap=%d, invalid obj=%d, func=0x%x\n",
197 phm->adapter_index, phm->object,
198 phm->function);
199 }
200 } else
201 printk(KERN_ERR
202 "NULL message pointer to hpi_debug_message!\n");
203}
204
205void hpi_debug_data(u16 *pdata, u32 len)
206{
207 u32 i;
208 int j;
209 int k;
210 int lines;
211 int cols = 8;
212
213 lines = (len + cols - 1) / cols;
214 if (lines > 8)
215 lines = 8;
216
217 for (i = 0, j = 0; j < lines; j++) {
218 printk(KERN_DEBUG "%p:", (pdata + i));
219
220 for (k = 0; k < cols && i < len; i++, k++)
221 printk("%s%04x", k == 0 ? "" : " ", pdata[i]);
222
223 printk("\n");
224 }
225}
diff --git a/sound/pci/asihpi/hpidebug.h b/sound/pci/asihpi/hpidebug.h
new file mode 100644
index 000000000000..44dccadcc25b
--- /dev/null
+++ b/sound/pci/asihpi/hpidebug.h
@@ -0,0 +1,385 @@
1/*****************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
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, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19Debug macros.
20
21*****************************************************************************/
22
23#ifndef _HPIDEBUG_H
24#define _HPIDEBUG_H
25
26#include "hpi_internal.h"
27
28/* Define debugging levels. */
29enum { HPI_DEBUG_LEVEL_ERROR = 0, /* always log errors */
30 HPI_DEBUG_LEVEL_WARNING = 1,
31 HPI_DEBUG_LEVEL_NOTICE = 2,
32 HPI_DEBUG_LEVEL_INFO = 3,
33 HPI_DEBUG_LEVEL_DEBUG = 4,
34 HPI_DEBUG_LEVEL_VERBOSE = 5 /* same printk level as DEBUG */
35};
36
37#define HPI_DEBUG_LEVEL_DEFAULT HPI_DEBUG_LEVEL_NOTICE
38
39/* an OS can define an extra flag string that is appended to
40 the start of each message, eg see hpios_linux.h */
41
42#ifdef SOURCEFILE_NAME
43#define FILE_LINE SOURCEFILE_NAME ":" __stringify(__LINE__) " "
44#else
45#define FILE_LINE __FILE__ ":" __stringify(__LINE__) " "
46#endif
47
48#if defined(HPI_DEBUG) && defined(_WINDOWS)
49#define HPI_DEBUGBREAK() debug_break()
50#else
51#define HPI_DEBUGBREAK()
52#endif
53
54#define HPI_DEBUG_ASSERT(expression) \
55 do { \
56 if (!(expression)) {\
57 printk(KERN_ERR FILE_LINE\
58 "ASSERT " __stringify(expression));\
59 HPI_DEBUGBREAK();\
60 } \
61 } while (0)
62
63#define HPI_DEBUG_LOG(level, ...) \
64 do { \
65 if (hpi_debug_level >= HPI_DEBUG_LEVEL_##level) { \
66 printk(HPI_DEBUG_FLAG_##level \
67 FILE_LINE __VA_ARGS__); \
68 } \
69 } while (0)
70
71void hpi_debug_init(void);
72int hpi_debug_level_set(int level);
73int hpi_debug_level_get(void);
74/* needed by Linux driver for dynamic debug level changes */
75extern int hpi_debug_level;
76
77void hpi_debug_message(struct hpi_message *phm, char *sz_fileline);
78
79void hpi_debug_data(u16 *pdata, u32 len);
80
81#define HPI_DEBUG_DATA(pdata, len) \
82 do { \
83 if (hpi_debug_level >= HPI_DEBUG_LEVEL_VERBOSE) \
84 hpi_debug_data(pdata, len); \
85 } while (0)
86
87#define HPI_DEBUG_MESSAGE(level, phm) \
88 do { \
89 if (hpi_debug_level >= HPI_DEBUG_LEVEL_##level) { \
90 hpi_debug_message(phm,HPI_DEBUG_FLAG_##level \
91 FILE_LINE __stringify(level));\
92 } \
93 } while (0)
94
95#define HPI_DEBUG_RESPONSE(phr) \
96 do { \
97 if ((hpi_debug_level >= HPI_DEBUG_LEVEL_DEBUG) && (phr->error))\
98 HPI_DEBUG_LOG(ERROR, \
99 "HPI response - error# %d\n", \
100 phr->error); \
101 else if (hpi_debug_level >= HPI_DEBUG_LEVEL_VERBOSE) \
102 HPI_DEBUG_LOG(VERBOSE, "HPI response OK\n");\
103 } while (0)
104
105#ifndef compile_time_assert
106#define compile_time_assert(cond, msg) \
107 typedef char msg[(cond) ? 1 : -1]
108#endif
109
110 /* check that size is exactly some number */
111#define function_count_check(sym, size) \
112 compile_time_assert((sym##_FUNCTION_COUNT) == (size),\
113 strings_match_defs_##sym)
114
115/* These strings should be generated using a macro which defines
116 the corresponding symbol values. */
117#define HPI_OBJ_STRINGS \
118{ \
119 "HPI_OBJ_SUBSYSTEM", \
120 "HPI_OBJ_ADAPTER", \
121 "HPI_OBJ_OSTREAM", \
122 "HPI_OBJ_ISTREAM", \
123 "HPI_OBJ_MIXER", \
124 "HPI_OBJ_NODE", \
125 "HPI_OBJ_CONTROL", \
126 "HPI_OBJ_NVMEMORY", \
127 "HPI_OBJ_DIGITALIO", \
128 "HPI_OBJ_WATCHDOG", \
129 "HPI_OBJ_CLOCK", \
130 "HPI_OBJ_PROFILE", \
131 "HPI_OBJ_CONTROLEX" \
132}
133
134#define HPI_SUBSYS_STRINGS \
135{ \
136 "HPI_SUBSYS_OPEN", \
137 "HPI_SUBSYS_GET_VERSION", \
138 "HPI_SUBSYS_GET_INFO", \
139 "HPI_SUBSYS_FIND_ADAPTERS", \
140 "HPI_SUBSYS_CREATE_ADAPTER",\
141 "HPI_SUBSYS_CLOSE", \
142 "HPI_SUBSYS_DELETE_ADAPTER", \
143 "HPI_SUBSYS_DRIVER_LOAD", \
144 "HPI_SUBSYS_DRIVER_UNLOAD", \
145 "HPI_SUBSYS_READ_PORT_8", \
146 "HPI_SUBSYS_WRITE_PORT_8", \
147 "HPI_SUBSYS_GET_NUM_ADAPTERS",\
148 "HPI_SUBSYS_GET_ADAPTER", \
149 "HPI_SUBSYS_SET_NETWORK_INTERFACE"\
150}
151function_count_check(HPI_SUBSYS, 14);
152
153#define HPI_ADAPTER_STRINGS \
154{ \
155 "HPI_ADAPTER_OPEN", \
156 "HPI_ADAPTER_CLOSE", \
157 "HPI_ADAPTER_GET_INFO", \
158 "HPI_ADAPTER_GET_ASSERT", \
159 "HPI_ADAPTER_TEST_ASSERT", \
160 "HPI_ADAPTER_SET_MODE", \
161 "HPI_ADAPTER_GET_MODE", \
162 "HPI_ADAPTER_ENABLE_CAPABILITY",\
163 "HPI_ADAPTER_SELFTEST", \
164 "HPI_ADAPTER_FIND_OBJECT", \
165 "HPI_ADAPTER_QUERY_FLASH", \
166 "HPI_ADAPTER_START_FLASH", \
167 "HPI_ADAPTER_PROGRAM_FLASH", \
168 "HPI_ADAPTER_SET_PROPERTY", \
169 "HPI_ADAPTER_GET_PROPERTY", \
170 "HPI_ADAPTER_ENUM_PROPERTY", \
171 "HPI_ADAPTER_MODULE_INFO", \
172 "HPI_ADAPTER_DEBUG_READ" \
173}
174
175function_count_check(HPI_ADAPTER, 18);
176
177#define HPI_OSTREAM_STRINGS \
178{ \
179 "HPI_OSTREAM_OPEN", \
180 "HPI_OSTREAM_CLOSE", \
181 "HPI_OSTREAM_WRITE", \
182 "HPI_OSTREAM_START", \
183 "HPI_OSTREAM_STOP", \
184 "HPI_OSTREAM_RESET", \
185 "HPI_OSTREAM_GET_INFO", \
186 "HPI_OSTREAM_QUERY_FORMAT", \
187 "HPI_OSTREAM_DATA", \
188 "HPI_OSTREAM_SET_VELOCITY", \
189 "HPI_OSTREAM_SET_PUNCHINOUT", \
190 "HPI_OSTREAM_SINEGEN", \
191 "HPI_OSTREAM_ANC_RESET", \
192 "HPI_OSTREAM_ANC_GET_INFO", \
193 "HPI_OSTREAM_ANC_READ", \
194 "HPI_OSTREAM_SET_TIMESCALE",\
195 "HPI_OSTREAM_SET_FORMAT", \
196 "HPI_OSTREAM_HOSTBUFFER_ALLOC", \
197 "HPI_OSTREAM_HOSTBUFFER_FREE", \
198 "HPI_OSTREAM_GROUP_ADD",\
199 "HPI_OSTREAM_GROUP_GETMAP", \
200 "HPI_OSTREAM_GROUP_RESET", \
201 "HPI_OSTREAM_HOSTBUFFER_GET_INFO", \
202 "HPI_OSTREAM_WAIT_START", \
203}
204function_count_check(HPI_OSTREAM, 24);
205
206#define HPI_ISTREAM_STRINGS \
207{ \
208 "HPI_ISTREAM_OPEN", \
209 "HPI_ISTREAM_CLOSE", \
210 "HPI_ISTREAM_SET_FORMAT", \
211 "HPI_ISTREAM_READ", \
212 "HPI_ISTREAM_START", \
213 "HPI_ISTREAM_STOP", \
214 "HPI_ISTREAM_RESET", \
215 "HPI_ISTREAM_GET_INFO", \
216 "HPI_ISTREAM_QUERY_FORMAT", \
217 "HPI_ISTREAM_ANC_RESET", \
218 "HPI_ISTREAM_ANC_GET_INFO", \
219 "HPI_ISTREAM_ANC_WRITE", \
220 "HPI_ISTREAM_HOSTBUFFER_ALLOC",\
221 "HPI_ISTREAM_HOSTBUFFER_FREE", \
222 "HPI_ISTREAM_GROUP_ADD", \
223 "HPI_ISTREAM_GROUP_GETMAP", \
224 "HPI_ISTREAM_GROUP_RESET", \
225 "HPI_ISTREAM_HOSTBUFFER_GET_INFO", \
226 "HPI_ISTREAM_WAIT_START", \
227}
228function_count_check(HPI_ISTREAM, 19);
229
230#define HPI_MIXER_STRINGS \
231{ \
232 "HPI_MIXER_OPEN", \
233 "HPI_MIXER_CLOSE", \
234 "HPI_MIXER_GET_INFO", \
235 "HPI_MIXER_GET_NODE_INFO", \
236 "HPI_MIXER_GET_CONTROL", \
237 "HPI_MIXER_SET_CONNECTION", \
238 "HPI_MIXER_GET_CONNECTIONS", \
239 "HPI_MIXER_GET_CONTROL_BY_INDEX", \
240 "HPI_MIXER_GET_CONTROL_ARRAY_BY_INDEX", \
241 "HPI_MIXER_GET_CONTROL_MULTIPLE_VALUES", \
242 "HPI_MIXER_STORE", \
243}
244function_count_check(HPI_MIXER, 11);
245
246#define HPI_CONTROL_STRINGS \
247{ \
248 "HPI_CONTROL_GET_INFO", \
249 "HPI_CONTROL_GET_STATE", \
250 "HPI_CONTROL_SET_STATE" \
251}
252function_count_check(HPI_CONTROL, 3);
253
254#define HPI_NVMEMORY_STRINGS \
255{ \
256 "HPI_NVMEMORY_OPEN", \
257 "HPI_NVMEMORY_READ_BYTE", \
258 "HPI_NVMEMORY_WRITE_BYTE" \
259}
260function_count_check(HPI_NVMEMORY, 3);
261
262#define HPI_DIGITALIO_STRINGS \
263{ \
264 "HPI_GPIO_OPEN", \
265 "HPI_GPIO_READ_BIT", \
266 "HPI_GPIO_WRITE_BIT", \
267 "HPI_GPIO_READ_ALL", \
268 "HPI_GPIO_WRITE_STATUS"\
269}
270function_count_check(HPI_GPIO, 5);
271
272#define HPI_WATCHDOG_STRINGS \
273{ \
274 "HPI_WATCHDOG_OPEN", \
275 "HPI_WATCHDOG_SET_TIME", \
276 "HPI_WATCHDOG_PING" \
277}
278
279#define HPI_CLOCK_STRINGS \
280{ \
281 "HPI_CLOCK_OPEN", \
282 "HPI_CLOCK_SET_TIME", \
283 "HPI_CLOCK_GET_TIME" \
284}
285
286#define HPI_PROFILE_STRINGS \
287{ \
288 "HPI_PROFILE_OPEN_ALL", \
289 "HPI_PROFILE_START_ALL", \
290 "HPI_PROFILE_STOP_ALL", \
291 "HPI_PROFILE_GET", \
292 "HPI_PROFILE_GET_IDLECOUNT", \
293 "HPI_PROFILE_GET_NAME", \
294 "HPI_PROFILE_GET_UTILIZATION" \
295}
296function_count_check(HPI_PROFILE, 7);
297
298#define HPI_ASYNCEVENT_STRINGS \
299{ \
300 "HPI_ASYNCEVENT_OPEN",\
301 "HPI_ASYNCEVENT_CLOSE ",\
302 "HPI_ASYNCEVENT_WAIT",\
303 "HPI_ASYNCEVENT_GETCOUNT",\
304 "HPI_ASYNCEVENT_GET",\
305 "HPI_ASYNCEVENT_SENDEVENTS"\
306}
307function_count_check(HPI_ASYNCEVENT, 6);
308
309#define HPI_CONTROL_TYPE_STRINGS \
310{ \
311 "null control", \
312 "HPI_CONTROL_CONNECTION", \
313 "HPI_CONTROL_VOLUME", \
314 "HPI_CONTROL_METER", \
315 "HPI_CONTROL_MUTE", \
316 "HPI_CONTROL_MULTIPLEXER", \
317 "HPI_CONTROL_AESEBU_TRANSMITTER", \
318 "HPI_CONTROL_AESEBU_RECEIVER", \
319 "HPI_CONTROL_LEVEL", \
320 "HPI_CONTROL_TUNER", \
321 "HPI_CONTROL_ONOFFSWITCH", \
322 "HPI_CONTROL_VOX", \
323 "HPI_CONTROL_AES18_TRANSMITTER", \
324 "HPI_CONTROL_AES18_RECEIVER", \
325 "HPI_CONTROL_AES18_BLOCKGENERATOR", \
326 "HPI_CONTROL_CHANNEL_MODE", \
327 "HPI_CONTROL_BITSTREAM", \
328 "HPI_CONTROL_SAMPLECLOCK", \
329 "HPI_CONTROL_MICROPHONE", \
330 "HPI_CONTROL_PARAMETRIC_EQ", \
331 "HPI_CONTROL_COMPANDER", \
332 "HPI_CONTROL_COBRANET", \
333 "HPI_CONTROL_TONE_DETECT", \
334 "HPI_CONTROL_SILENCE_DETECT", \
335 "HPI_CONTROL_PAD", \
336 "HPI_CONTROL_SRC" ,\
337 "HPI_CONTROL_UNIVERSAL" \
338}
339
340compile_time_assert((HPI_CONTROL_LAST_INDEX + 1 == 27),
341 controltype_strings_match_defs);
342
343#define HPI_SOURCENODE_STRINGS \
344{ \
345 "no source", \
346 "HPI_SOURCENODE_OSTREAM", \
347 "HPI_SOURCENODE_LINEIN", \
348 "HPI_SOURCENODE_AESEBU_IN", \
349 "HPI_SOURCENODE_TUNER", \
350 "HPI_SOURCENODE_RF", \
351 "HPI_SOURCENODE_CLOCK_SOURCE", \
352 "HPI_SOURCENODE_RAW_BITSTREAM", \
353 "HPI_SOURCENODE_MICROPHONE", \
354 "HPI_SOURCENODE_COBRANET", \
355 "HPI_SOURCENODE_ANALOG", \
356 "HPI_SOURCENODE_ADAPTER" \
357}
358
359compile_time_assert((HPI_SOURCENODE_LAST_INDEX - HPI_SOURCENODE_BASE + 1) ==
360 (12), sourcenode_strings_match_defs);
361
362#define HPI_DESTNODE_STRINGS \
363{ \
364 "no destination", \
365 "HPI_DESTNODE_ISTREAM", \
366 "HPI_DESTNODE_LINEOUT", \
367 "HPI_DESTNODE_AESEBU_OUT", \
368 "HPI_DESTNODE_RF", \
369 "HPI_DESTNODE_SPEAKER", \
370 "HPI_DESTNODE_COBRANET", \
371 "HPI_DESTNODE_ANALOG" \
372}
373compile_time_assert((HPI_DESTNODE_LAST_INDEX - HPI_DESTNODE_BASE + 1) == (8),
374 destnode_strings_match_defs);
375
376#define HPI_CONTROL_CHANNEL_MODE_STRINGS \
377{ \
378 "XXX HPI_CHANNEL_MODE_ERROR XXX", \
379 "HPI_CHANNEL_MODE_NORMAL", \
380 "HPI_CHANNEL_MODE_SWAP", \
381 "HPI_CHANNEL_MODE_LEFT_ONLY", \
382 "HPI_CHANNEL_MODE_RIGHT_ONLY" \
383}
384
385#endif /* _HPIDEBUG_H */
diff --git a/sound/pci/asihpi/hpidspcd.c b/sound/pci/asihpi/hpidspcd.c
new file mode 100644
index 000000000000..9b10d9a5c255
--- /dev/null
+++ b/sound/pci/asihpi/hpidspcd.c
@@ -0,0 +1,172 @@
1/***********************************************************************/
2/*!
3
4 AudioScience HPI driver
5 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of version 2 of the GNU General Public License as
9 published by the Free Software Foundation;
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20\file
21Functions for reading DSP code to load into DSP
22
23(Linux only:) If DSPCODE_FIRMWARE_LOADER is defined, code is read using
24hotplug firmware loader from individual dsp code files
25
26If neither of the above is defined, code is read from linked arrays.
27DSPCODE_ARRAY is defined.
28
29HPI_INCLUDE_**** must be defined
30and the appropriate hzz?????.c or hex?????.c linked in
31
32 */
33/***********************************************************************/
34#define SOURCEFILE_NAME "hpidspcd.c"
35#include "hpidspcd.h"
36#include "hpidebug.h"
37
38/**
39 Header structure for binary dsp code file (see asidsp.doc)
40 This structure must match that used in s2bin.c for generation of asidsp.bin
41 */
42
43#ifndef DISABLE_PRAGMA_PACK1
44#pragma pack(push, 1)
45#endif
46
47struct code_header {
48 u32 size;
49 char type[4];
50 u32 adapter;
51 u32 version;
52 u32 crc;
53};
54
55#ifndef DISABLE_PRAGMA_PACK1
56#pragma pack(pop)
57#endif
58
59#define HPI_VER_DECIMAL ((int)(HPI_VER_MAJOR(HPI_VER) * 10000 + \
60 HPI_VER_MINOR(HPI_VER) * 100 + HPI_VER_RELEASE(HPI_VER)))
61
62/***********************************************************************/
63#include "linux/pci.h"
64/*-------------------------------------------------------------------*/
65short hpi_dsp_code_open(u32 adapter, struct dsp_code *ps_dsp_code,
66 u32 *pos_error_code)
67{
68 const struct firmware *ps_firmware = ps_dsp_code->ps_firmware;
69 struct code_header header;
70 char fw_name[20];
71 int err;
72
73 sprintf(fw_name, "asihpi/dsp%04x.bin", adapter);
74 HPI_DEBUG_LOG(INFO, "requesting firmware for %s\n", fw_name);
75
76 err = request_firmware(&ps_firmware, fw_name,
77 &ps_dsp_code->ps_dev->dev);
78 if (err != 0) {
79 HPI_DEBUG_LOG(ERROR, "%d, request_firmware failed for %s\n",
80 err, fw_name);
81 goto error1;
82 }
83 if (ps_firmware->size < sizeof(header)) {
84 HPI_DEBUG_LOG(ERROR, "header size too small %s\n", fw_name);
85 goto error2;
86 }
87 memcpy(&header, ps_firmware->data, sizeof(header));
88 if (header.adapter != adapter) {
89 HPI_DEBUG_LOG(ERROR, "adapter type incorrect %4x != %4x\n",
90 header.adapter, adapter);
91 goto error2;
92 }
93 if (header.size != ps_firmware->size) {
94 HPI_DEBUG_LOG(ERROR, "code size wrong %d != %ld\n",
95 header.size, (unsigned long)ps_firmware->size);
96 goto error2;
97 }
98
99 if (header.version / 10000 != HPI_VER_DECIMAL / 10000) {
100 HPI_DEBUG_LOG(ERROR,
101 "firmware major version mismatch "
102 "DSP image %d != driver %d\n", header.version,
103 HPI_VER_DECIMAL);
104 goto error2;
105 }
106
107 if (header.version != HPI_VER_DECIMAL) {
108 HPI_DEBUG_LOG(WARNING,
109 "version mismatch DSP image %d != driver %d\n",
110 header.version, HPI_VER_DECIMAL);
111 /* goto error2; still allow driver to load */
112 }
113
114 HPI_DEBUG_LOG(INFO, "dsp code %s opened\n", fw_name);
115 ps_dsp_code->ps_firmware = ps_firmware;
116 ps_dsp_code->block_length = header.size / sizeof(u32);
117 ps_dsp_code->word_count = sizeof(header) / sizeof(u32);
118 ps_dsp_code->version = header.version;
119 ps_dsp_code->crc = header.crc;
120 return 0;
121
122error2:
123 release_firmware(ps_firmware);
124error1:
125 ps_dsp_code->ps_firmware = NULL;
126 ps_dsp_code->block_length = 0;
127 return HPI_ERROR_DSP_FILE_NOT_FOUND;
128}
129
130/*-------------------------------------------------------------------*/
131void hpi_dsp_code_close(struct dsp_code *ps_dsp_code)
132{
133 if (ps_dsp_code->ps_firmware != NULL) {
134 HPI_DEBUG_LOG(DEBUG, "dsp code closed\n");
135 release_firmware(ps_dsp_code->ps_firmware);
136 ps_dsp_code->ps_firmware = NULL;
137 }
138}
139
140/*-------------------------------------------------------------------*/
141void hpi_dsp_code_rewind(struct dsp_code *ps_dsp_code)
142{
143 /* Go back to start of data, after header */
144 ps_dsp_code->word_count = sizeof(struct code_header) / sizeof(u32);
145}
146
147/*-------------------------------------------------------------------*/
148short hpi_dsp_code_read_word(struct dsp_code *ps_dsp_code, u32 *pword)
149{
150 if (ps_dsp_code->word_count + 1 > ps_dsp_code->block_length)
151 return (HPI_ERROR_DSP_FILE_FORMAT);
152
153 *pword = ((u32 *)(ps_dsp_code->ps_firmware->data))[ps_dsp_code->
154 word_count];
155 ps_dsp_code->word_count++;
156 return 0;
157}
158
159/*-------------------------------------------------------------------*/
160short hpi_dsp_code_read_block(size_t words_requested,
161 struct dsp_code *ps_dsp_code, u32 **ppblock)
162{
163 if (ps_dsp_code->word_count + words_requested >
164 ps_dsp_code->block_length)
165 return HPI_ERROR_DSP_FILE_FORMAT;
166
167 *ppblock =
168 ((u32 *)(ps_dsp_code->ps_firmware->data)) +
169 ps_dsp_code->word_count;
170 ps_dsp_code->word_count += words_requested;
171 return 0;
172}
diff --git a/sound/pci/asihpi/hpidspcd.h b/sound/pci/asihpi/hpidspcd.h
new file mode 100644
index 000000000000..d7c240398225
--- /dev/null
+++ b/sound/pci/asihpi/hpidspcd.h
@@ -0,0 +1,104 @@
1/***********************************************************************/
2/**
3
4 AudioScience HPI driver
5 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of version 2 of the GNU General Public License as
9 published by the Free Software Foundation;
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20\file
21Functions for reading DSP code to load into DSP
22
23 hpi_dspcode_defines HPI DSP code loading method
24Define exactly one of these to select how the DSP code is supplied to
25the adapter.
26
27End users writing applications that use the HPI interface do not have to
28use any of the below defines; they are only necessary for building drivers
29
30HPI_DSPCODE_FILE:
31DSP code is supplied as a file that is opened and read from by the driver.
32
33HPI_DSPCODE_FIRMWARE:
34DSP code is read using the hotplug firmware loader module.
35 Only valid when compiling the HPI kernel driver under Linux.
36*/
37/***********************************************************************/
38#ifndef _HPIDSPCD_H_
39#define _HPIDSPCD_H_
40
41#include "hpi_internal.h"
42
43#ifndef DISABLE_PRAGMA_PACK1
44#pragma pack(push, 1)
45#endif
46
47/** Descriptor for dspcode from firmware loader */
48struct dsp_code {
49 /** Firmware descriptor */
50 const struct firmware *ps_firmware;
51 struct pci_dev *ps_dev;
52 /** Expected number of words in the whole dsp code,INCL header */
53 long int block_length;
54 /** Number of words read so far */
55 long int word_count;
56 /** Version read from dsp code file */
57 u32 version;
58 /** CRC read from dsp code file */
59 u32 crc;
60};
61
62#ifndef DISABLE_PRAGMA_PACK1
63#pragma pack(pop)
64#endif
65
66/** Prepare *psDspCode to refer to the requuested adapter.
67 Searches the file, or selects the appropriate linked array
68
69\return 0 for success, or error code if requested code is not available
70*/
71short hpi_dsp_code_open(
72 /** Code identifier, usually adapter family */
73 u32 adapter,
74 /** Pointer to DSP code control structure */
75 struct dsp_code *ps_dsp_code,
76 /** Pointer to dword to receive OS specific error code */
77 u32 *pos_error_code);
78
79/** Close the DSP code file */
80void hpi_dsp_code_close(struct dsp_code *ps_dsp_code);
81
82/** Rewind to the beginning of the DSP code file (for verify) */
83void hpi_dsp_code_rewind(struct dsp_code *ps_dsp_code);
84
85/** Read one word from the dsp code file
86 \return 0 for success, or error code if eof, or block length exceeded
87*/
88short hpi_dsp_code_read_word(struct dsp_code *ps_dsp_code,
89 /**< DSP code descriptor */
90 u32 *pword /**< where to store the read word */
91 );
92
93/** Get a block of dsp code into an internal buffer, and provide a pointer to
94that buffer. (If dsp code is already an array in memory, it is referenced,
95not copied.)
96
97\return Error if requested number of words are not available
98*/
99short hpi_dsp_code_read_block(size_t words_requested,
100 struct dsp_code *ps_dsp_code,
101 /* Pointer to store (Pointer to code buffer) */
102 u32 **ppblock);
103
104#endif
diff --git a/sound/pci/asihpi/hpifunc.c b/sound/pci/asihpi/hpifunc.c
new file mode 100644
index 000000000000..298eef3e20e9
--- /dev/null
+++ b/sound/pci/asihpi/hpifunc.c
@@ -0,0 +1,3877 @@
1
2#include "hpi_internal.h"
3#include "hpimsginit.h"
4
5#include "hpidebug.h"
6
7struct hpi_handle {
8 unsigned int obj_index:12;
9 unsigned int obj_type:4;
10 unsigned int adapter_index:14;
11 unsigned int spare:1;
12 unsigned int read_only:1;
13};
14
15union handle_word {
16 struct hpi_handle h;
17 u32 w;
18};
19
20u32 hpi_indexes_to_handle(const char c_object, const u16 adapter_index,
21 const u16 object_index)
22{
23 union handle_word handle;
24
25 handle.h.adapter_index = adapter_index;
26 handle.h.spare = 0;
27 handle.h.read_only = 0;
28 handle.h.obj_type = c_object;
29 handle.h.obj_index = object_index;
30 return handle.w;
31}
32
33void hpi_handle_to_indexes(const u32 handle, u16 *pw_adapter_index,
34 u16 *pw_object_index)
35{
36 union handle_word uhandle;
37 uhandle.w = handle;
38
39 if (pw_adapter_index)
40 *pw_adapter_index = (u16)uhandle.h.adapter_index;
41 if (pw_object_index)
42 *pw_object_index = (u16)uhandle.h.obj_index;
43}
44
45char hpi_handle_object(const u32 handle)
46{
47 union handle_word uhandle;
48 uhandle.w = handle;
49 return (char)uhandle.h.obj_type;
50}
51
52#define u32TOINDEX(h, i1) \
53do {\
54 if (h == 0) \
55 return HPI_ERROR_INVALID_OBJ; \
56 else \
57 hpi_handle_to_indexes(h, i1, NULL); \
58} while (0)
59
60#define u32TOINDEXES(h, i1, i2) \
61do {\
62 if (h == 0) \
63 return HPI_ERROR_INVALID_OBJ; \
64 else \
65 hpi_handle_to_indexes(h, i1, i2);\
66} while (0)
67
68void hpi_format_to_msg(struct hpi_msg_format *pMF,
69 const struct hpi_format *pF)
70{
71 pMF->sample_rate = pF->sample_rate;
72 pMF->bit_rate = pF->bit_rate;
73 pMF->attributes = pF->attributes;
74 pMF->channels = pF->channels;
75 pMF->format = pF->format;
76}
77
78static void hpi_msg_to_format(struct hpi_format *pF,
79 struct hpi_msg_format *pMF)
80{
81 pF->sample_rate = pMF->sample_rate;
82 pF->bit_rate = pMF->bit_rate;
83 pF->attributes = pMF->attributes;
84 pF->channels = pMF->channels;
85 pF->format = pMF->format;
86 pF->mode_legacy = 0;
87 pF->unused = 0;
88}
89
90void hpi_stream_response_to_legacy(struct hpi_stream_res *pSR)
91{
92 pSR->u.legacy_stream_info.auxiliary_data_available =
93 pSR->u.stream_info.auxiliary_data_available;
94 pSR->u.legacy_stream_info.state = pSR->u.stream_info.state;
95}
96
97static struct hpi_hsubsys gh_subsys;
98
99struct hpi_hsubsys *hpi_subsys_create(void
100 )
101{
102 struct hpi_message hm;
103 struct hpi_response hr;
104
105 memset(&gh_subsys, 0, sizeof(struct hpi_hsubsys));
106
107 {
108 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
109 HPI_SUBSYS_OPEN);
110 hpi_send_recv(&hm, &hr);
111
112 if (hr.error == 0)
113 return &gh_subsys;
114
115 }
116 return NULL;
117}
118
119void hpi_subsys_free(const struct hpi_hsubsys *ph_subsys)
120{
121 struct hpi_message hm;
122 struct hpi_response hr;
123
124 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
125 HPI_SUBSYS_CLOSE);
126 hpi_send_recv(&hm, &hr);
127
128}
129
130u16 hpi_subsys_get_version(const struct hpi_hsubsys *ph_subsys, u32 *pversion)
131{
132 struct hpi_message hm;
133 struct hpi_response hr;
134
135 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
136 HPI_SUBSYS_GET_VERSION);
137 hpi_send_recv(&hm, &hr);
138 *pversion = hr.u.s.version;
139 return hr.error;
140}
141
142u16 hpi_subsys_get_version_ex(const struct hpi_hsubsys *ph_subsys,
143 u32 *pversion_ex)
144{
145 struct hpi_message hm;
146 struct hpi_response hr;
147
148 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
149 HPI_SUBSYS_GET_VERSION);
150 hpi_send_recv(&hm, &hr);
151 *pversion_ex = hr.u.s.data;
152 return hr.error;
153}
154
155u16 hpi_subsys_get_info(const struct hpi_hsubsys *ph_subsys, u32 *pversion,
156 u16 *pw_num_adapters, u16 aw_adapter_list[], u16 list_length)
157{
158 struct hpi_message hm;
159 struct hpi_response hr;
160 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
161 HPI_SUBSYS_GET_INFO);
162
163 hpi_send_recv(&hm, &hr);
164
165 *pversion = hr.u.s.version;
166 if (list_length > HPI_MAX_ADAPTERS)
167 memcpy(aw_adapter_list, &hr.u.s.aw_adapter_list,
168 HPI_MAX_ADAPTERS);
169 else
170 memcpy(aw_adapter_list, &hr.u.s.aw_adapter_list, list_length);
171 *pw_num_adapters = hr.u.s.num_adapters;
172 return hr.error;
173}
174
175u16 hpi_subsys_find_adapters(const struct hpi_hsubsys *ph_subsys,
176 u16 *pw_num_adapters, u16 aw_adapter_list[], u16 list_length)
177{
178 struct hpi_message hm;
179 struct hpi_response hr;
180 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
181 HPI_SUBSYS_FIND_ADAPTERS);
182
183 hpi_send_recv(&hm, &hr);
184
185 if (list_length > HPI_MAX_ADAPTERS) {
186 memcpy(aw_adapter_list, &hr.u.s.aw_adapter_list,
187 HPI_MAX_ADAPTERS * sizeof(u16));
188 memset(&aw_adapter_list[HPI_MAX_ADAPTERS], 0,
189 (list_length - HPI_MAX_ADAPTERS) * sizeof(u16));
190 } else
191 memcpy(aw_adapter_list, &hr.u.s.aw_adapter_list,
192 list_length * sizeof(u16));
193 *pw_num_adapters = hr.u.s.num_adapters;
194
195 return hr.error;
196}
197
198u16 hpi_subsys_create_adapter(const struct hpi_hsubsys *ph_subsys,
199 const struct hpi_resource *p_resource, u16 *pw_adapter_index)
200{
201 struct hpi_message hm;
202 struct hpi_response hr;
203
204 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
205 HPI_SUBSYS_CREATE_ADAPTER);
206 hm.u.s.resource = *p_resource;
207
208 hpi_send_recv(&hm, &hr);
209
210 *pw_adapter_index = hr.u.s.adapter_index;
211 return hr.error;
212}
213
214u16 hpi_subsys_delete_adapter(const struct hpi_hsubsys *ph_subsys,
215 u16 adapter_index)
216{
217 struct hpi_message hm;
218 struct hpi_response hr;
219 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
220 HPI_SUBSYS_DELETE_ADAPTER);
221 hm.adapter_index = adapter_index;
222 hpi_send_recv(&hm, &hr);
223 return hr.error;
224}
225
226u16 hpi_subsys_get_num_adapters(const struct hpi_hsubsys *ph_subsys,
227 int *pn_num_adapters)
228{
229 struct hpi_message hm;
230 struct hpi_response hr;
231 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
232 HPI_SUBSYS_GET_NUM_ADAPTERS);
233 hpi_send_recv(&hm, &hr);
234 *pn_num_adapters = (int)hr.u.s.num_adapters;
235 return hr.error;
236}
237
238u16 hpi_subsys_get_adapter(const struct hpi_hsubsys *ph_subsys, int iterator,
239 u32 *padapter_index, u16 *pw_adapter_type)
240{
241 struct hpi_message hm;
242 struct hpi_response hr;
243 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
244 HPI_SUBSYS_GET_ADAPTER);
245 hm.adapter_index = (u16)iterator;
246 hpi_send_recv(&hm, &hr);
247 *padapter_index = (int)hr.u.s.adapter_index;
248 *pw_adapter_type = hr.u.s.aw_adapter_list[0];
249 return hr.error;
250}
251
252u16 hpi_subsys_set_host_network_interface(const struct hpi_hsubsys *ph_subsys,
253 const char *sz_interface)
254{
255 struct hpi_message hm;
256 struct hpi_response hr;
257 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
258 HPI_SUBSYS_SET_NETWORK_INTERFACE);
259 if (sz_interface == NULL)
260 return HPI_ERROR_INVALID_RESOURCE;
261 hm.u.s.resource.r.net_if = sz_interface;
262 hpi_send_recv(&hm, &hr);
263 return hr.error;
264}
265
266u16 hpi_adapter_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index)
267{
268 struct hpi_message hm;
269 struct hpi_response hr;
270 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
271 HPI_ADAPTER_OPEN);
272 hm.adapter_index = adapter_index;
273
274 hpi_send_recv(&hm, &hr);
275
276 return hr.error;
277
278}
279
280u16 hpi_adapter_close(const struct hpi_hsubsys *ph_subsys, u16 adapter_index)
281{
282 struct hpi_message hm;
283 struct hpi_response hr;
284 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
285 HPI_ADAPTER_CLOSE);
286 hm.adapter_index = adapter_index;
287
288 hpi_send_recv(&hm, &hr);
289
290 return hr.error;
291}
292
293u16 hpi_adapter_set_mode(const struct hpi_hsubsys *ph_subsys,
294 u16 adapter_index, u32 adapter_mode)
295{
296 return hpi_adapter_set_mode_ex(ph_subsys, adapter_index, adapter_mode,
297 HPI_ADAPTER_MODE_SET);
298}
299
300u16 hpi_adapter_set_mode_ex(const struct hpi_hsubsys *ph_subsys,
301 u16 adapter_index, u32 adapter_mode, u16 query_or_set)
302{
303 struct hpi_message hm;
304 struct hpi_response hr;
305 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
306 HPI_ADAPTER_SET_MODE);
307 hm.adapter_index = adapter_index;
308 hm.u.a.adapter_mode = adapter_mode;
309 hm.u.a.assert_id = query_or_set;
310 hpi_send_recv(&hm, &hr);
311 return hr.error;
312}
313
314u16 hpi_adapter_get_mode(const struct hpi_hsubsys *ph_subsys,
315 u16 adapter_index, u32 *padapter_mode)
316{
317 struct hpi_message hm;
318 struct hpi_response hr;
319 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
320 HPI_ADAPTER_GET_MODE);
321 hm.adapter_index = adapter_index;
322 hpi_send_recv(&hm, &hr);
323 if (padapter_mode)
324 *padapter_mode = hr.u.a.serial_number;
325 return hr.error;
326}
327
328u16 hpi_adapter_get_info(const struct hpi_hsubsys *ph_subsys,
329 u16 adapter_index, u16 *pw_num_outstreams, u16 *pw_num_instreams,
330 u16 *pw_version, u32 *pserial_number, u16 *pw_adapter_type)
331{
332 struct hpi_message hm;
333 struct hpi_response hr;
334 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
335 HPI_ADAPTER_GET_INFO);
336 hm.adapter_index = adapter_index;
337
338 hpi_send_recv(&hm, &hr);
339
340 *pw_adapter_type = hr.u.a.adapter_type;
341 *pw_num_outstreams = hr.u.a.num_outstreams;
342 *pw_num_instreams = hr.u.a.num_instreams;
343 *pw_version = hr.u.a.version;
344 *pserial_number = hr.u.a.serial_number;
345 return hr.error;
346}
347
348u16 hpi_adapter_get_module_by_index(const struct hpi_hsubsys *ph_subsys,
349 u16 adapter_index, u16 module_index, u16 *pw_num_outputs,
350 u16 *pw_num_inputs, u16 *pw_version, u32 *pserial_number,
351 u16 *pw_module_type, u32 *ph_module)
352{
353 struct hpi_message hm;
354 struct hpi_response hr;
355
356 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
357 HPI_ADAPTER_MODULE_INFO);
358 hm.adapter_index = adapter_index;
359 hm.u.ax.module_info.index = module_index;
360
361 hpi_send_recv(&hm, &hr);
362
363 *pw_module_type = hr.u.a.adapter_type;
364 *pw_num_outputs = hr.u.a.num_outstreams;
365 *pw_num_inputs = hr.u.a.num_instreams;
366 *pw_version = hr.u.a.version;
367 *pserial_number = hr.u.a.serial_number;
368 *ph_module = 0;
369
370 return hr.error;
371}
372
373u16 hpi_adapter_get_assert(const struct hpi_hsubsys *ph_subsys,
374 u16 adapter_index, u16 *assert_present, char *psz_assert,
375 u16 *pw_line_number)
376{
377 struct hpi_message hm;
378 struct hpi_response hr;
379 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
380 HPI_ADAPTER_GET_ASSERT);
381 hm.adapter_index = adapter_index;
382 hpi_send_recv(&hm, &hr);
383
384 *assert_present = 0;
385
386 if (!hr.error) {
387
388 *pw_line_number = (u16)hr.u.a.serial_number;
389 if (*pw_line_number) {
390
391 int i;
392 char *src = (char *)hr.u.a.sz_adapter_assert;
393 char *dst = psz_assert;
394
395 *assert_present = 1;
396
397 for (i = 0; i < HPI_STRING_LEN; i++) {
398 char c;
399 c = *src++;
400 *dst++ = c;
401 if (c == 0)
402 break;
403 }
404
405 }
406 }
407 return hr.error;
408}
409
410u16 hpi_adapter_get_assert_ex(const struct hpi_hsubsys *ph_subsys,
411 u16 adapter_index, u16 *assert_present, char *psz_assert,
412 u32 *pline_number, u16 *pw_assert_on_dsp)
413{
414 struct hpi_message hm;
415 struct hpi_response hr;
416 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
417 HPI_ADAPTER_GET_ASSERT);
418 hm.adapter_index = adapter_index;
419
420 hpi_send_recv(&hm, &hr);
421
422 *assert_present = 0;
423
424 if (!hr.error) {
425
426 *pline_number = hr.u.a.serial_number;
427
428 *assert_present = hr.u.a.adapter_type;
429
430 *pw_assert_on_dsp = hr.u.a.adapter_index;
431
432 if (!*assert_present && *pline_number)
433
434 *assert_present = 1;
435
436 if (*assert_present) {
437
438 int i;
439 char *src = (char *)hr.u.a.sz_adapter_assert;
440 char *dst = psz_assert;
441
442 for (i = 0; i < HPI_STRING_LEN; i++) {
443 char c;
444 c = *src++;
445 *dst++ = c;
446 if (c == 0)
447 break;
448 }
449
450 } else {
451 *psz_assert = 0;
452 }
453 }
454 return hr.error;
455}
456
457u16 hpi_adapter_test_assert(const struct hpi_hsubsys *ph_subsys,
458 u16 adapter_index, u16 assert_id)
459{
460 struct hpi_message hm;
461 struct hpi_response hr;
462 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
463 HPI_ADAPTER_TEST_ASSERT);
464 hm.adapter_index = adapter_index;
465 hm.u.a.assert_id = assert_id;
466
467 hpi_send_recv(&hm, &hr);
468
469 return hr.error;
470}
471
472u16 hpi_adapter_enable_capability(const struct hpi_hsubsys *ph_subsys,
473 u16 adapter_index, u16 capability, u32 key)
474{
475 struct hpi_message hm;
476 struct hpi_response hr;
477 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
478 HPI_ADAPTER_ENABLE_CAPABILITY);
479 hm.adapter_index = adapter_index;
480 hm.u.a.assert_id = capability;
481 hm.u.a.adapter_mode = key;
482
483 hpi_send_recv(&hm, &hr);
484
485 return hr.error;
486}
487
488u16 hpi_adapter_self_test(const struct hpi_hsubsys *ph_subsys,
489 u16 adapter_index)
490{
491 struct hpi_message hm;
492 struct hpi_response hr;
493 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
494 HPI_ADAPTER_SELFTEST);
495 hm.adapter_index = adapter_index;
496 hpi_send_recv(&hm, &hr);
497 return hr.error;
498}
499
500u16 hpi_adapter_debug_read(const struct hpi_hsubsys *ph_subsys,
501 u16 adapter_index, u32 dsp_address, char *p_buffer, int *count_bytes)
502{
503 struct hpi_message hm;
504 struct hpi_response hr;
505 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
506 HPI_ADAPTER_DEBUG_READ);
507
508 hr.size = sizeof(hr);
509
510 hm.adapter_index = adapter_index;
511 hm.u.ax.debug_read.dsp_address = dsp_address;
512
513 if (*count_bytes > sizeof(hr.u.bytes))
514 *count_bytes = sizeof(hr.u.bytes);
515
516 hm.u.ax.debug_read.count_bytes = *count_bytes;
517
518 hpi_send_recv(&hm, &hr);
519
520 if (!hr.error) {
521 *count_bytes = hr.size - 12;
522 memcpy(p_buffer, &hr.u.bytes, *count_bytes);
523 } else
524 *count_bytes = 0;
525 return hr.error;
526}
527
528u16 hpi_adapter_set_property(const struct hpi_hsubsys *ph_subsys,
529 u16 adapter_index, u16 property, u16 parameter1, u16 parameter2)
530{
531 struct hpi_message hm;
532 struct hpi_response hr;
533 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
534 HPI_ADAPTER_SET_PROPERTY);
535 hm.adapter_index = adapter_index;
536 hm.u.ax.property_set.property = property;
537 hm.u.ax.property_set.parameter1 = parameter1;
538 hm.u.ax.property_set.parameter2 = parameter2;
539
540 hpi_send_recv(&hm, &hr);
541
542 return hr.error;
543}
544
545u16 hpi_adapter_get_property(const struct hpi_hsubsys *ph_subsys,
546 u16 adapter_index, u16 property, u16 *pw_parameter1,
547 u16 *pw_parameter2)
548{
549 struct hpi_message hm;
550 struct hpi_response hr;
551 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
552 HPI_ADAPTER_GET_PROPERTY);
553 hm.adapter_index = adapter_index;
554 hm.u.ax.property_set.property = property;
555
556 hpi_send_recv(&hm, &hr);
557 if (!hr.error) {
558 if (pw_parameter1)
559 *pw_parameter1 = hr.u.ax.property_get.parameter1;
560 if (pw_parameter2)
561 *pw_parameter2 = hr.u.ax.property_get.parameter2;
562 }
563
564 return hr.error;
565}
566
567u16 hpi_adapter_enumerate_property(const struct hpi_hsubsys *ph_subsys,
568 u16 adapter_index, u16 index, u16 what_to_enumerate,
569 u16 property_index, u32 *psetting)
570{
571 return 0;
572}
573
574u16 hpi_format_create(struct hpi_format *p_format, u16 channels, u16 format,
575 u32 sample_rate, u32 bit_rate, u32 attributes)
576{
577 u16 error = 0;
578 struct hpi_msg_format fmt;
579
580 switch (channels) {
581 case 1:
582 case 2:
583 case 4:
584 case 6:
585 case 8:
586 case 16:
587 break;
588 default:
589 error = HPI_ERROR_INVALID_CHANNELS;
590 return error;
591 }
592 fmt.channels = channels;
593
594 switch (format) {
595 case HPI_FORMAT_PCM16_SIGNED:
596 case HPI_FORMAT_PCM24_SIGNED:
597 case HPI_FORMAT_PCM32_SIGNED:
598 case HPI_FORMAT_PCM32_FLOAT:
599 case HPI_FORMAT_PCM16_BIGENDIAN:
600 case HPI_FORMAT_PCM8_UNSIGNED:
601 case HPI_FORMAT_MPEG_L1:
602 case HPI_FORMAT_MPEG_L2:
603 case HPI_FORMAT_MPEG_L3:
604 case HPI_FORMAT_DOLBY_AC2:
605 case HPI_FORMAT_AA_TAGIT1_HITS:
606 case HPI_FORMAT_AA_TAGIT1_INSERTS:
607 case HPI_FORMAT_RAW_BITSTREAM:
608 case HPI_FORMAT_AA_TAGIT1_HITS_EX1:
609 case HPI_FORMAT_OEM1:
610 case HPI_FORMAT_OEM2:
611 break;
612 default:
613 error = HPI_ERROR_INVALID_FORMAT;
614 return error;
615 }
616 fmt.format = format;
617
618 if (sample_rate < 8000L) {
619 error = HPI_ERROR_INCOMPATIBLE_SAMPLERATE;
620 sample_rate = 8000L;
621 }
622 if (sample_rate > 200000L) {
623 error = HPI_ERROR_INCOMPATIBLE_SAMPLERATE;
624 sample_rate = 200000L;
625 }
626 fmt.sample_rate = sample_rate;
627
628 switch (format) {
629 case HPI_FORMAT_MPEG_L1:
630 case HPI_FORMAT_MPEG_L2:
631 case HPI_FORMAT_MPEG_L3:
632 fmt.bit_rate = bit_rate;
633 break;
634 case HPI_FORMAT_PCM16_SIGNED:
635 case HPI_FORMAT_PCM16_BIGENDIAN:
636 fmt.bit_rate = channels * sample_rate * 2;
637 break;
638 case HPI_FORMAT_PCM32_SIGNED:
639 case HPI_FORMAT_PCM32_FLOAT:
640 fmt.bit_rate = channels * sample_rate * 4;
641 break;
642 case HPI_FORMAT_PCM8_UNSIGNED:
643 fmt.bit_rate = channels * sample_rate;
644 break;
645 default:
646 fmt.bit_rate = 0;
647 }
648
649 switch (format) {
650 case HPI_FORMAT_MPEG_L2:
651 if ((channels == 1)
652 && (attributes != HPI_MPEG_MODE_DEFAULT)) {
653 attributes = HPI_MPEG_MODE_DEFAULT;
654 error = HPI_ERROR_INVALID_FORMAT;
655 } else if (attributes > HPI_MPEG_MODE_DUALCHANNEL) {
656 attributes = HPI_MPEG_MODE_DEFAULT;
657 error = HPI_ERROR_INVALID_FORMAT;
658 }
659 fmt.attributes = attributes;
660 break;
661 default:
662 fmt.attributes = attributes;
663 }
664
665 hpi_msg_to_format(p_format, &fmt);
666 return error;
667}
668
669u16 hpi_stream_estimate_buffer_size(struct hpi_format *p_format,
670 u32 host_polling_rate_in_milli_seconds, u32 *recommended_buffer_size)
671{
672
673 u32 bytes_per_second;
674 u32 size;
675 u16 channels;
676 struct hpi_format *pF = p_format;
677
678 channels = pF->channels;
679
680 switch (pF->format) {
681 case HPI_FORMAT_PCM16_BIGENDIAN:
682 case HPI_FORMAT_PCM16_SIGNED:
683 bytes_per_second = pF->sample_rate * 2L * channels;
684 break;
685 case HPI_FORMAT_PCM24_SIGNED:
686 bytes_per_second = pF->sample_rate * 3L * channels;
687 break;
688 case HPI_FORMAT_PCM32_SIGNED:
689 case HPI_FORMAT_PCM32_FLOAT:
690 bytes_per_second = pF->sample_rate * 4L * channels;
691 break;
692 case HPI_FORMAT_PCM8_UNSIGNED:
693 bytes_per_second = pF->sample_rate * 1L * channels;
694 break;
695 case HPI_FORMAT_MPEG_L1:
696 case HPI_FORMAT_MPEG_L2:
697 case HPI_FORMAT_MPEG_L3:
698 bytes_per_second = pF->bit_rate / 8L;
699 break;
700 case HPI_FORMAT_DOLBY_AC2:
701
702 bytes_per_second = 256000L / 8L;
703 break;
704 default:
705 return HPI_ERROR_INVALID_FORMAT;
706 }
707 size = (bytes_per_second * host_polling_rate_in_milli_seconds * 2) /
708 1000L;
709
710 *recommended_buffer_size =
711 roundup_pow_of_two(((size + 4095L) & ~4095L));
712 return 0;
713}
714
715u16 hpi_outstream_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
716 u16 outstream_index, u32 *ph_outstream)
717{
718 struct hpi_message hm;
719 struct hpi_response hr;
720 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
721 HPI_OSTREAM_OPEN);
722 hm.adapter_index = adapter_index;
723 hm.obj_index = outstream_index;
724
725 hpi_send_recv(&hm, &hr);
726
727 if (hr.error == 0)
728 *ph_outstream =
729 hpi_indexes_to_handle(HPI_OBJ_OSTREAM, adapter_index,
730 outstream_index);
731 else
732 *ph_outstream = 0;
733 return hr.error;
734}
735
736u16 hpi_outstream_close(const struct hpi_hsubsys *ph_subsys, u32 h_outstream)
737{
738 struct hpi_message hm;
739 struct hpi_response hr;
740
741 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
742 HPI_OSTREAM_HOSTBUFFER_FREE);
743 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
744 hpi_send_recv(&hm, &hr);
745
746 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
747 HPI_OSTREAM_GROUP_RESET);
748 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
749 hpi_send_recv(&hm, &hr);
750
751 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
752 HPI_OSTREAM_CLOSE);
753 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
754 hpi_send_recv(&hm, &hr);
755
756 return hr.error;
757}
758
759u16 hpi_outstream_get_info_ex(const struct hpi_hsubsys *ph_subsys,
760 u32 h_outstream, u16 *pw_state, u32 *pbuffer_size, u32 *pdata_to_play,
761 u32 *psamples_played, u32 *pauxiliary_data_to_play)
762{
763 struct hpi_message hm;
764 struct hpi_response hr;
765 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
766 HPI_OSTREAM_GET_INFO);
767 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
768
769 hpi_send_recv(&hm, &hr);
770
771 if (pw_state)
772 *pw_state = hr.u.d.u.stream_info.state;
773 if (pbuffer_size)
774 *pbuffer_size = hr.u.d.u.stream_info.buffer_size;
775 if (pdata_to_play)
776 *pdata_to_play = hr.u.d.u.stream_info.data_available;
777 if (psamples_played)
778 *psamples_played = hr.u.d.u.stream_info.samples_transferred;
779 if (pauxiliary_data_to_play)
780 *pauxiliary_data_to_play =
781 hr.u.d.u.stream_info.auxiliary_data_available;
782 return hr.error;
783}
784
785u16 hpi_outstream_write_buf(const struct hpi_hsubsys *ph_subsys,
786 u32 h_outstream, const u8 *pb_data, u32 bytes_to_write,
787 const struct hpi_format *p_format)
788{
789 struct hpi_message hm;
790 struct hpi_response hr;
791 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
792 HPI_OSTREAM_WRITE);
793 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
794 hm.u.d.u.data.pb_data = (u8 *)pb_data;
795 hm.u.d.u.data.data_size = bytes_to_write;
796
797 hpi_format_to_msg(&hm.u.d.u.data.format, p_format);
798
799 hpi_send_recv(&hm, &hr);
800
801 return hr.error;
802}
803
804u16 hpi_outstream_start(const struct hpi_hsubsys *ph_subsys, u32 h_outstream)
805{
806 struct hpi_message hm;
807 struct hpi_response hr;
808 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
809 HPI_OSTREAM_START);
810 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
811
812 hpi_send_recv(&hm, &hr);
813
814 return hr.error;
815}
816
817u16 hpi_outstream_wait_start(const struct hpi_hsubsys *ph_subsys,
818 u32 h_outstream)
819{
820 struct hpi_message hm;
821 struct hpi_response hr;
822 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
823 HPI_OSTREAM_WAIT_START);
824 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
825
826 hpi_send_recv(&hm, &hr);
827
828 return hr.error;
829}
830
831u16 hpi_outstream_stop(const struct hpi_hsubsys *ph_subsys, u32 h_outstream)
832{
833 struct hpi_message hm;
834 struct hpi_response hr;
835 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
836 HPI_OSTREAM_STOP);
837 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
838
839 hpi_send_recv(&hm, &hr);
840
841 return hr.error;
842}
843
844u16 hpi_outstream_sinegen(const struct hpi_hsubsys *ph_subsys,
845 u32 h_outstream)
846{
847 struct hpi_message hm;
848 struct hpi_response hr;
849 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
850 HPI_OSTREAM_SINEGEN);
851 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
852
853 hpi_send_recv(&hm, &hr);
854
855 return hr.error;
856}
857
858u16 hpi_outstream_reset(const struct hpi_hsubsys *ph_subsys, u32 h_outstream)
859{
860 struct hpi_message hm;
861 struct hpi_response hr;
862 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
863 HPI_OSTREAM_RESET);
864 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
865
866 hpi_send_recv(&hm, &hr);
867
868 return hr.error;
869}
870
871u16 hpi_outstream_query_format(const struct hpi_hsubsys *ph_subsys,
872 u32 h_outstream, struct hpi_format *p_format)
873{
874 struct hpi_message hm;
875 struct hpi_response hr;
876
877 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
878 HPI_OSTREAM_QUERY_FORMAT);
879 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
880
881 hpi_format_to_msg(&hm.u.d.u.data.format, p_format);
882
883 hpi_send_recv(&hm, &hr);
884
885 return hr.error;
886}
887
888u16 hpi_outstream_set_format(const struct hpi_hsubsys *ph_subsys,
889 u32 h_outstream, struct hpi_format *p_format)
890{
891 struct hpi_message hm;
892 struct hpi_response hr;
893
894 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
895 HPI_OSTREAM_SET_FORMAT);
896 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
897
898 hpi_format_to_msg(&hm.u.d.u.data.format, p_format);
899
900 hpi_send_recv(&hm, &hr);
901
902 return hr.error;
903}
904
905u16 hpi_outstream_set_velocity(const struct hpi_hsubsys *ph_subsys,
906 u32 h_outstream, short velocity)
907{
908 struct hpi_message hm;
909 struct hpi_response hr;
910
911 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
912 HPI_OSTREAM_SET_VELOCITY);
913 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
914 hm.u.d.u.velocity = velocity;
915
916 hpi_send_recv(&hm, &hr);
917
918 return hr.error;
919}
920
921u16 hpi_outstream_set_punch_in_out(const struct hpi_hsubsys *ph_subsys,
922 u32 h_outstream, u32 punch_in_sample, u32 punch_out_sample)
923{
924 struct hpi_message hm;
925 struct hpi_response hr;
926
927 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
928 HPI_OSTREAM_SET_PUNCHINOUT);
929 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
930
931 hm.u.d.u.pio.punch_in_sample = punch_in_sample;
932 hm.u.d.u.pio.punch_out_sample = punch_out_sample;
933
934 hpi_send_recv(&hm, &hr);
935
936 return hr.error;
937}
938
939u16 hpi_outstream_ancillary_reset(const struct hpi_hsubsys *ph_subsys,
940 u32 h_outstream, u16 mode)
941{
942 struct hpi_message hm;
943 struct hpi_response hr;
944
945 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
946 HPI_OSTREAM_ANC_RESET);
947 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
948 hm.u.d.u.data.format.channels = mode;
949 hpi_send_recv(&hm, &hr);
950 return hr.error;
951}
952
953u16 hpi_outstream_ancillary_get_info(const struct hpi_hsubsys *ph_subsys,
954 u32 h_outstream, u32 *pframes_available)
955{
956 struct hpi_message hm;
957 struct hpi_response hr;
958
959 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
960 HPI_OSTREAM_ANC_GET_INFO);
961 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
962 hpi_send_recv(&hm, &hr);
963 if (hr.error == 0) {
964 if (pframes_available)
965 *pframes_available =
966 hr.u.d.u.stream_info.data_available /
967 sizeof(struct hpi_anc_frame);
968 }
969 return hr.error;
970}
971
972u16 hpi_outstream_ancillary_read(const struct hpi_hsubsys *ph_subsys,
973 u32 h_outstream, struct hpi_anc_frame *p_anc_frame_buffer,
974 u32 anc_frame_buffer_size_in_bytes,
975 u32 number_of_ancillary_frames_to_read)
976{
977 struct hpi_message hm;
978 struct hpi_response hr;
979 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
980 HPI_OSTREAM_ANC_READ);
981 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
982 hm.u.d.u.data.pb_data = (u8 *)p_anc_frame_buffer;
983 hm.u.d.u.data.data_size =
984 number_of_ancillary_frames_to_read *
985 sizeof(struct hpi_anc_frame);
986 if (hm.u.d.u.data.data_size <= anc_frame_buffer_size_in_bytes)
987 hpi_send_recv(&hm, &hr);
988 else
989 hr.error = HPI_ERROR_INVALID_DATA_TRANSFER;
990 return hr.error;
991}
992
993u16 hpi_outstream_set_time_scale(const struct hpi_hsubsys *ph_subsys,
994 u32 h_outstream, u32 time_scale)
995{
996 struct hpi_message hm;
997 struct hpi_response hr;
998
999 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
1000 HPI_OSTREAM_SET_TIMESCALE);
1001 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
1002
1003 hm.u.d.u.time_scale = time_scale;
1004
1005 hpi_send_recv(&hm, &hr);
1006
1007 return hr.error;
1008}
1009
1010u16 hpi_outstream_host_buffer_allocate(const struct hpi_hsubsys *ph_subsys,
1011 u32 h_outstream, u32 size_in_bytes)
1012{
1013 struct hpi_message hm;
1014 struct hpi_response hr;
1015
1016 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
1017 HPI_OSTREAM_HOSTBUFFER_ALLOC);
1018 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
1019 hm.u.d.u.data.data_size = size_in_bytes;
1020 hpi_send_recv(&hm, &hr);
1021 return hr.error;
1022}
1023
1024u16 hpi_outstream_host_buffer_get_info(const struct hpi_hsubsys *ph_subsys,
1025 u32 h_outstream, u8 **pp_buffer,
1026 struct hpi_hostbuffer_status **pp_status)
1027{
1028 struct hpi_message hm;
1029 struct hpi_response hr;
1030
1031 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
1032 HPI_OSTREAM_HOSTBUFFER_GET_INFO);
1033 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
1034 hpi_send_recv(&hm, &hr);
1035
1036 if (hr.error == 0) {
1037 if (pp_buffer)
1038 *pp_buffer = hr.u.d.u.hostbuffer_info.p_buffer;
1039 if (pp_status)
1040 *pp_status = hr.u.d.u.hostbuffer_info.p_status;
1041 }
1042 return hr.error;
1043}
1044
1045u16 hpi_outstream_host_buffer_free(const struct hpi_hsubsys *ph_subsys,
1046 u32 h_outstream)
1047{
1048 struct hpi_message hm;
1049 struct hpi_response hr;
1050
1051 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
1052 HPI_OSTREAM_HOSTBUFFER_FREE);
1053 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
1054 hpi_send_recv(&hm, &hr);
1055 return hr.error;
1056}
1057
1058u16 hpi_outstream_group_add(const struct hpi_hsubsys *ph_subsys,
1059 u32 h_outstream, u32 h_stream)
1060{
1061 struct hpi_message hm;
1062 struct hpi_response hr;
1063 u16 adapter;
1064 char c_obj_type;
1065
1066 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
1067 HPI_OSTREAM_GROUP_ADD);
1068 hr.error = 0;
1069 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
1070 c_obj_type = hpi_handle_object(h_stream);
1071 switch (c_obj_type) {
1072 case HPI_OBJ_OSTREAM:
1073 hm.u.d.u.stream.object_type = HPI_OBJ_OSTREAM;
1074 u32TOINDEXES(h_stream, &adapter,
1075 &hm.u.d.u.stream.stream_index);
1076 break;
1077 case HPI_OBJ_ISTREAM:
1078 hm.u.d.u.stream.object_type = HPI_OBJ_ISTREAM;
1079 u32TOINDEXES(h_stream, &adapter,
1080 &hm.u.d.u.stream.stream_index);
1081 break;
1082 default:
1083 return HPI_ERROR_INVALID_STREAM;
1084 }
1085 if (adapter != hm.adapter_index)
1086 return HPI_ERROR_NO_INTERADAPTER_GROUPS;
1087
1088 hpi_send_recv(&hm, &hr);
1089 return hr.error;
1090}
1091
1092u16 hpi_outstream_group_get_map(const struct hpi_hsubsys *ph_subsys,
1093 u32 h_outstream, u32 *poutstream_map, u32 *pinstream_map)
1094{
1095 struct hpi_message hm;
1096 struct hpi_response hr;
1097
1098 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
1099 HPI_OSTREAM_GROUP_GETMAP);
1100 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
1101 hpi_send_recv(&hm, &hr);
1102
1103 if (poutstream_map)
1104 *poutstream_map = hr.u.d.u.group_info.outstream_group_map;
1105 if (pinstream_map)
1106 *pinstream_map = hr.u.d.u.group_info.instream_group_map;
1107
1108 return hr.error;
1109}
1110
1111u16 hpi_outstream_group_reset(const struct hpi_hsubsys *ph_subsys,
1112 u32 h_outstream)
1113{
1114 struct hpi_message hm;
1115 struct hpi_response hr;
1116
1117 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
1118 HPI_OSTREAM_GROUP_RESET);
1119 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
1120 hpi_send_recv(&hm, &hr);
1121 return hr.error;
1122}
1123
1124u16 hpi_instream_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
1125 u16 instream_index, u32 *ph_instream)
1126{
1127 struct hpi_message hm;
1128 struct hpi_response hr;
1129
1130 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1131 HPI_ISTREAM_OPEN);
1132 hm.adapter_index = adapter_index;
1133 hm.obj_index = instream_index;
1134
1135 hpi_send_recv(&hm, &hr);
1136
1137 if (hr.error == 0)
1138 *ph_instream =
1139 hpi_indexes_to_handle(HPI_OBJ_ISTREAM, adapter_index,
1140 instream_index);
1141 else
1142 *ph_instream = 0;
1143
1144 return hr.error;
1145}
1146
1147u16 hpi_instream_close(const struct hpi_hsubsys *ph_subsys, u32 h_instream)
1148{
1149 struct hpi_message hm;
1150 struct hpi_response hr;
1151
1152 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1153 HPI_ISTREAM_HOSTBUFFER_FREE);
1154 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1155 hpi_send_recv(&hm, &hr);
1156
1157 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1158 HPI_ISTREAM_GROUP_RESET);
1159 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1160 hpi_send_recv(&hm, &hr);
1161
1162 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1163 HPI_ISTREAM_CLOSE);
1164 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1165 hpi_send_recv(&hm, &hr);
1166
1167 return hr.error;
1168}
1169
1170u16 hpi_instream_query_format(const struct hpi_hsubsys *ph_subsys,
1171 u32 h_instream, const struct hpi_format *p_format)
1172{
1173 struct hpi_message hm;
1174 struct hpi_response hr;
1175
1176 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1177 HPI_ISTREAM_QUERY_FORMAT);
1178 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1179 hpi_format_to_msg(&hm.u.d.u.data.format, p_format);
1180
1181 hpi_send_recv(&hm, &hr);
1182
1183 return hr.error;
1184}
1185
1186u16 hpi_instream_set_format(const struct hpi_hsubsys *ph_subsys,
1187 u32 h_instream, const struct hpi_format *p_format)
1188{
1189 struct hpi_message hm;
1190 struct hpi_response hr;
1191
1192 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1193 HPI_ISTREAM_SET_FORMAT);
1194 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1195 hpi_format_to_msg(&hm.u.d.u.data.format, p_format);
1196
1197 hpi_send_recv(&hm, &hr);
1198
1199 return hr.error;
1200}
1201
1202u16 hpi_instream_read_buf(const struct hpi_hsubsys *ph_subsys, u32 h_instream,
1203 u8 *pb_data, u32 bytes_to_read)
1204{
1205 struct hpi_message hm;
1206 struct hpi_response hr;
1207
1208 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1209 HPI_ISTREAM_READ);
1210 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1211 hm.u.d.u.data.data_size = bytes_to_read;
1212 hm.u.d.u.data.pb_data = pb_data;
1213
1214 hpi_send_recv(&hm, &hr);
1215
1216 return hr.error;
1217}
1218
1219u16 hpi_instream_start(const struct hpi_hsubsys *ph_subsys, u32 h_instream)
1220{
1221 struct hpi_message hm;
1222 struct hpi_response hr;
1223
1224 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1225 HPI_ISTREAM_START);
1226 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1227
1228 hpi_send_recv(&hm, &hr);
1229
1230 return hr.error;
1231}
1232
1233u16 hpi_instream_wait_start(const struct hpi_hsubsys *ph_subsys,
1234 u32 h_instream)
1235{
1236 struct hpi_message hm;
1237 struct hpi_response hr;
1238
1239 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1240 HPI_ISTREAM_WAIT_START);
1241 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1242
1243 hpi_send_recv(&hm, &hr);
1244
1245 return hr.error;
1246}
1247
1248u16 hpi_instream_stop(const struct hpi_hsubsys *ph_subsys, u32 h_instream)
1249{
1250 struct hpi_message hm;
1251 struct hpi_response hr;
1252
1253 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1254 HPI_ISTREAM_STOP);
1255 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1256
1257 hpi_send_recv(&hm, &hr);
1258
1259 return hr.error;
1260}
1261
1262u16 hpi_instream_reset(const struct hpi_hsubsys *ph_subsys, u32 h_instream)
1263{
1264 struct hpi_message hm;
1265 struct hpi_response hr;
1266
1267 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1268 HPI_ISTREAM_RESET);
1269 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1270
1271 hpi_send_recv(&hm, &hr);
1272
1273 return hr.error;
1274}
1275
1276u16 hpi_instream_get_info_ex(const struct hpi_hsubsys *ph_subsys,
1277 u32 h_instream, u16 *pw_state, u32 *pbuffer_size, u32 *pdata_recorded,
1278 u32 *psamples_recorded, u32 *pauxiliary_data_recorded)
1279{
1280 struct hpi_message hm;
1281 struct hpi_response hr;
1282 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1283 HPI_ISTREAM_GET_INFO);
1284 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1285
1286 hpi_send_recv(&hm, &hr);
1287
1288 if (pw_state)
1289 *pw_state = hr.u.d.u.stream_info.state;
1290 if (pbuffer_size)
1291 *pbuffer_size = hr.u.d.u.stream_info.buffer_size;
1292 if (pdata_recorded)
1293 *pdata_recorded = hr.u.d.u.stream_info.data_available;
1294 if (psamples_recorded)
1295 *psamples_recorded = hr.u.d.u.stream_info.samples_transferred;
1296 if (pauxiliary_data_recorded)
1297 *pauxiliary_data_recorded =
1298 hr.u.d.u.stream_info.auxiliary_data_available;
1299 return hr.error;
1300}
1301
1302u16 hpi_instream_ancillary_reset(const struct hpi_hsubsys *ph_subsys,
1303 u32 h_instream, u16 bytes_per_frame, u16 mode, u16 alignment,
1304 u16 idle_bit)
1305{
1306 struct hpi_message hm;
1307 struct hpi_response hr;
1308 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1309 HPI_ISTREAM_ANC_RESET);
1310 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1311 hm.u.d.u.data.format.attributes = bytes_per_frame;
1312 hm.u.d.u.data.format.format = (mode << 8) | (alignment & 0xff);
1313 hm.u.d.u.data.format.channels = idle_bit;
1314 hpi_send_recv(&hm, &hr);
1315 return hr.error;
1316}
1317
1318u16 hpi_instream_ancillary_get_info(const struct hpi_hsubsys *ph_subsys,
1319 u32 h_instream, u32 *pframe_space)
1320{
1321 struct hpi_message hm;
1322 struct hpi_response hr;
1323 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1324 HPI_ISTREAM_ANC_GET_INFO);
1325 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1326 hpi_send_recv(&hm, &hr);
1327 if (pframe_space)
1328 *pframe_space =
1329 (hr.u.d.u.stream_info.buffer_size -
1330 hr.u.d.u.stream_info.data_available) /
1331 sizeof(struct hpi_anc_frame);
1332 return hr.error;
1333}
1334
1335u16 hpi_instream_ancillary_write(const struct hpi_hsubsys *ph_subsys,
1336 u32 h_instream, const struct hpi_anc_frame *p_anc_frame_buffer,
1337 u32 anc_frame_buffer_size_in_bytes,
1338 u32 number_of_ancillary_frames_to_write)
1339{
1340 struct hpi_message hm;
1341 struct hpi_response hr;
1342
1343 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1344 HPI_ISTREAM_ANC_WRITE);
1345 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1346 hm.u.d.u.data.pb_data = (u8 *)p_anc_frame_buffer;
1347 hm.u.d.u.data.data_size =
1348 number_of_ancillary_frames_to_write *
1349 sizeof(struct hpi_anc_frame);
1350 if (hm.u.d.u.data.data_size <= anc_frame_buffer_size_in_bytes)
1351 hpi_send_recv(&hm, &hr);
1352 else
1353 hr.error = HPI_ERROR_INVALID_DATA_TRANSFER;
1354 return hr.error;
1355}
1356
1357u16 hpi_instream_host_buffer_allocate(const struct hpi_hsubsys *ph_subsys,
1358 u32 h_instream, u32 size_in_bytes)
1359{
1360
1361 struct hpi_message hm;
1362 struct hpi_response hr;
1363
1364 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1365 HPI_ISTREAM_HOSTBUFFER_ALLOC);
1366 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1367 hm.u.d.u.data.data_size = size_in_bytes;
1368 hpi_send_recv(&hm, &hr);
1369 return hr.error;
1370}
1371
1372u16 hpi_instream_host_buffer_get_info(const struct hpi_hsubsys *ph_subsys,
1373 u32 h_instream, u8 **pp_buffer,
1374 struct hpi_hostbuffer_status **pp_status)
1375{
1376 struct hpi_message hm;
1377 struct hpi_response hr;
1378
1379 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1380 HPI_ISTREAM_HOSTBUFFER_GET_INFO);
1381 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1382 hpi_send_recv(&hm, &hr);
1383
1384 if (hr.error == 0) {
1385 if (pp_buffer)
1386 *pp_buffer = hr.u.d.u.hostbuffer_info.p_buffer;
1387 if (pp_status)
1388 *pp_status = hr.u.d.u.hostbuffer_info.p_status;
1389 }
1390 return hr.error;
1391}
1392
1393u16 hpi_instream_host_buffer_free(const struct hpi_hsubsys *ph_subsys,
1394 u32 h_instream)
1395{
1396
1397 struct hpi_message hm;
1398 struct hpi_response hr;
1399
1400 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1401 HPI_ISTREAM_HOSTBUFFER_FREE);
1402 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1403 hpi_send_recv(&hm, &hr);
1404 return hr.error;
1405}
1406
1407u16 hpi_instream_group_add(const struct hpi_hsubsys *ph_subsys,
1408 u32 h_instream, u32 h_stream)
1409{
1410 struct hpi_message hm;
1411 struct hpi_response hr;
1412 u16 adapter;
1413 char c_obj_type;
1414
1415 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1416 HPI_ISTREAM_GROUP_ADD);
1417 hr.error = 0;
1418 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1419 c_obj_type = hpi_handle_object(h_stream);
1420
1421 switch (c_obj_type) {
1422 case HPI_OBJ_OSTREAM:
1423 hm.u.d.u.stream.object_type = HPI_OBJ_OSTREAM;
1424 u32TOINDEXES(h_stream, &adapter,
1425 &hm.u.d.u.stream.stream_index);
1426 break;
1427 case HPI_OBJ_ISTREAM:
1428 hm.u.d.u.stream.object_type = HPI_OBJ_ISTREAM;
1429 u32TOINDEXES(h_stream, &adapter,
1430 &hm.u.d.u.stream.stream_index);
1431 break;
1432 default:
1433 return HPI_ERROR_INVALID_STREAM;
1434 }
1435
1436 if (adapter != hm.adapter_index)
1437 return HPI_ERROR_NO_INTERADAPTER_GROUPS;
1438
1439 hpi_send_recv(&hm, &hr);
1440 return hr.error;
1441}
1442
1443u16 hpi_instream_group_get_map(const struct hpi_hsubsys *ph_subsys,
1444 u32 h_instream, u32 *poutstream_map, u32 *pinstream_map)
1445{
1446 struct hpi_message hm;
1447 struct hpi_response hr;
1448
1449 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1450 HPI_ISTREAM_HOSTBUFFER_FREE);
1451 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1452 hpi_send_recv(&hm, &hr);
1453
1454 if (poutstream_map)
1455 *poutstream_map = hr.u.d.u.group_info.outstream_group_map;
1456 if (pinstream_map)
1457 *pinstream_map = hr.u.d.u.group_info.instream_group_map;
1458
1459 return hr.error;
1460}
1461
1462u16 hpi_instream_group_reset(const struct hpi_hsubsys *ph_subsys,
1463 u32 h_instream)
1464{
1465 struct hpi_message hm;
1466 struct hpi_response hr;
1467
1468 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1469 HPI_ISTREAM_GROUP_RESET);
1470 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1471 hpi_send_recv(&hm, &hr);
1472 return hr.error;
1473}
1474
1475u16 hpi_mixer_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
1476 u32 *ph_mixer)
1477{
1478 struct hpi_message hm;
1479 struct hpi_response hr;
1480 hpi_init_message_response(&hm, &hr, HPI_OBJ_MIXER, HPI_MIXER_OPEN);
1481 hm.adapter_index = adapter_index;
1482
1483 hpi_send_recv(&hm, &hr);
1484
1485 if (hr.error == 0)
1486 *ph_mixer =
1487 hpi_indexes_to_handle(HPI_OBJ_MIXER, adapter_index,
1488 0);
1489 else
1490 *ph_mixer = 0;
1491 return hr.error;
1492}
1493
1494u16 hpi_mixer_close(const struct hpi_hsubsys *ph_subsys, u32 h_mixer)
1495{
1496 struct hpi_message hm;
1497 struct hpi_response hr;
1498 hpi_init_message_response(&hm, &hr, HPI_OBJ_MIXER, HPI_MIXER_CLOSE);
1499 u32TOINDEX(h_mixer, &hm.adapter_index);
1500 hpi_send_recv(&hm, &hr);
1501 return hr.error;
1502}
1503
1504u16 hpi_mixer_get_control(const struct hpi_hsubsys *ph_subsys, u32 h_mixer,
1505 u16 src_node_type, u16 src_node_type_index, u16 dst_node_type,
1506 u16 dst_node_type_index, u16 control_type, u32 *ph_control)
1507{
1508 struct hpi_message hm;
1509 struct hpi_response hr;
1510 hpi_init_message_response(&hm, &hr, HPI_OBJ_MIXER,
1511 HPI_MIXER_GET_CONTROL);
1512 u32TOINDEX(h_mixer, &hm.adapter_index);
1513 hm.u.m.node_type1 = src_node_type;
1514 hm.u.m.node_index1 = src_node_type_index;
1515 hm.u.m.node_type2 = dst_node_type;
1516 hm.u.m.node_index2 = dst_node_type_index;
1517 hm.u.m.control_type = control_type;
1518
1519 hpi_send_recv(&hm, &hr);
1520
1521 if (hr.error == 0)
1522 *ph_control =
1523 hpi_indexes_to_handle(HPI_OBJ_CONTROL,
1524 hm.adapter_index, hr.u.m.control_index);
1525 else
1526 *ph_control = 0;
1527 return hr.error;
1528}
1529
1530u16 hpi_mixer_get_control_by_index(const struct hpi_hsubsys *ph_subsys,
1531 u32 h_mixer, u16 control_index, u16 *pw_src_node_type,
1532 u16 *pw_src_node_index, u16 *pw_dst_node_type, u16 *pw_dst_node_index,
1533 u16 *pw_control_type, u32 *ph_control)
1534{
1535 struct hpi_message hm;
1536 struct hpi_response hr;
1537 hpi_init_message_response(&hm, &hr, HPI_OBJ_MIXER,
1538 HPI_MIXER_GET_CONTROL_BY_INDEX);
1539 u32TOINDEX(h_mixer, &hm.adapter_index);
1540 hm.u.m.control_index = control_index;
1541 hpi_send_recv(&hm, &hr);
1542
1543 if (pw_src_node_type) {
1544 *pw_src_node_type =
1545 hr.u.m.src_node_type + HPI_SOURCENODE_NONE;
1546 *pw_src_node_index = hr.u.m.src_node_index;
1547 *pw_dst_node_type = hr.u.m.dst_node_type + HPI_DESTNODE_NONE;
1548 *pw_dst_node_index = hr.u.m.dst_node_index;
1549 }
1550 if (pw_control_type)
1551 *pw_control_type = hr.u.m.control_index;
1552
1553 if (ph_control) {
1554 if (hr.error == 0)
1555 *ph_control =
1556 hpi_indexes_to_handle(HPI_OBJ_CONTROL,
1557 hm.adapter_index, control_index);
1558 else
1559 *ph_control = 0;
1560 }
1561 return hr.error;
1562}
1563
1564u16 hpi_mixer_store(const struct hpi_hsubsys *ph_subsys, u32 h_mixer,
1565 enum HPI_MIXER_STORE_COMMAND command, u16 index)
1566{
1567 struct hpi_message hm;
1568 struct hpi_response hr;
1569 hpi_init_message_response(&hm, &hr, HPI_OBJ_MIXER, HPI_MIXER_STORE);
1570 u32TOINDEX(h_mixer, &hm.adapter_index);
1571 hm.u.mx.store.command = command;
1572 hm.u.mx.store.index = index;
1573 hpi_send_recv(&hm, &hr);
1574 return hr.error;
1575}
1576
1577static
1578u16 hpi_control_param_set(const struct hpi_hsubsys *ph_subsys,
1579 const u32 h_control, const u16 attrib, const u32 param1,
1580 const u32 param2)
1581{
1582 struct hpi_message hm;
1583 struct hpi_response hr;
1584 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
1585 HPI_CONTROL_SET_STATE);
1586 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
1587 hm.u.c.attribute = attrib;
1588 hm.u.c.param1 = param1;
1589 hm.u.c.param2 = param2;
1590 hpi_send_recv(&hm, &hr);
1591 return hr.error;
1592}
1593
1594static
1595u16 hpi_control_param_get(const struct hpi_hsubsys *ph_subsys,
1596 const u32 h_control, const u16 attrib, u32 param1, u32 param2,
1597 u32 *pparam1, u32 *pparam2)
1598{
1599 struct hpi_message hm;
1600 struct hpi_response hr;
1601 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
1602 HPI_CONTROL_GET_STATE);
1603 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
1604 hm.u.c.attribute = attrib;
1605 hm.u.c.param1 = param1;
1606 hm.u.c.param2 = param2;
1607 hpi_send_recv(&hm, &hr);
1608 if (pparam1)
1609 *pparam1 = hr.u.c.param1;
1610 if (pparam2)
1611 *pparam2 = hr.u.c.param2;
1612
1613 return hr.error;
1614}
1615
1616#define hpi_control_param1_get(s, h, a, p1) \
1617 hpi_control_param_get(s, h, a, 0, 0, p1, NULL)
1618#define hpi_control_param2_get(s, h, a, p1, p2) \
1619 hpi_control_param_get(s, h, a, 0, 0, p1, p2)
1620#define hpi_control_ex_param1_get(s, h, a, p1) \
1621 hpi_control_ex_param_get(s, h, a, 0, 0, p1, NULL)
1622#define hpi_control_ex_param2_get(s, h, a, p1, p2) \
1623 hpi_control_ex_param_get(s, h, a, 0, 0, p1, p2)
1624
1625static
1626u16 hpi_control_query(const struct hpi_hsubsys *ph_subsys,
1627 const u32 h_control, const u16 attrib, const u32 index,
1628 const u32 param, u32 *psetting)
1629{
1630 struct hpi_message hm;
1631 struct hpi_response hr;
1632 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
1633 HPI_CONTROL_GET_INFO);
1634 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
1635
1636 hm.u.c.attribute = attrib;
1637 hm.u.c.param1 = index;
1638 hm.u.c.param2 = param;
1639
1640 hpi_send_recv(&hm, &hr);
1641 *psetting = hr.u.c.param1;
1642
1643 return hr.error;
1644}
1645
1646static u16 hpi_control_get_string(const struct hpi_hsubsys *ph_subsys,
1647 const u32 h_control, const u16 attribute, char *psz_string,
1648 const u32 string_length)
1649{
1650 unsigned int sub_string_index = 0, j = 0;
1651 char c = 0;
1652 unsigned int n = 0;
1653 u16 hE = 0;
1654
1655 if ((string_length < 1) || (string_length > 256))
1656 return HPI_ERROR_INVALID_CONTROL_VALUE;
1657 for (sub_string_index = 0; sub_string_index < string_length;
1658 sub_string_index += 8) {
1659 struct hpi_message hm;
1660 struct hpi_response hr;
1661
1662 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
1663 HPI_CONTROL_GET_STATE);
1664 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
1665 hm.u.c.attribute = attribute;
1666 hm.u.c.param1 = sub_string_index;
1667 hm.u.c.param2 = 0;
1668 hpi_send_recv(&hm, &hr);
1669
1670 if (sub_string_index == 0
1671 && (hr.u.cu.chars8.remaining_chars + 8) >
1672 string_length)
1673 return HPI_ERROR_INVALID_CONTROL_VALUE;
1674
1675 if (hr.error) {
1676 hE = hr.error;
1677 break;
1678 }
1679 for (j = 0; j < 8; j++) {
1680 c = hr.u.cu.chars8.sz_data[j];
1681 psz_string[sub_string_index + j] = c;
1682 n++;
1683 if (n >= string_length) {
1684 psz_string[string_length - 1] = 0;
1685 hE = HPI_ERROR_INVALID_CONTROL_VALUE;
1686 break;
1687 }
1688 if (c == 0)
1689 break;
1690 }
1691
1692 if ((hr.u.cu.chars8.remaining_chars == 0)
1693 && ((sub_string_index + j) < string_length)
1694 && (c != 0)) {
1695 c = 0;
1696 psz_string[sub_string_index + j] = c;
1697 }
1698 if (c == 0)
1699 break;
1700 }
1701 return hE;
1702}
1703
1704u16 HPI_AESEBU__receiver_query_format(const struct hpi_hsubsys *ph_subsys,
1705 const u32 h_aes_rx, const u32 index, u16 *pw_format)
1706{
1707 u32 qr;
1708 u16 err;
1709
1710 err = hpi_control_query(ph_subsys, h_aes_rx, HPI_AESEBURX_FORMAT,
1711 index, 0, &qr);
1712 *pw_format = (u16)qr;
1713 return err;
1714}
1715
1716u16 HPI_AESEBU__receiver_set_format(const struct hpi_hsubsys *ph_subsys,
1717 u32 h_control, u16 format)
1718{
1719 return hpi_control_param_set(ph_subsys, h_control,
1720 HPI_AESEBURX_FORMAT, format, 0);
1721}
1722
1723u16 HPI_AESEBU__receiver_get_format(const struct hpi_hsubsys *ph_subsys,
1724 u32 h_control, u16 *pw_format)
1725{
1726 u16 err;
1727 u32 param;
1728
1729 err = hpi_control_param1_get(ph_subsys, h_control,
1730 HPI_AESEBURX_FORMAT, &param);
1731 if (!err && pw_format)
1732 *pw_format = (u16)param;
1733
1734 return err;
1735}
1736
1737u16 HPI_AESEBU__receiver_get_sample_rate(const struct hpi_hsubsys *ph_subsys,
1738 u32 h_control, u32 *psample_rate)
1739{
1740 return hpi_control_param1_get(ph_subsys, h_control,
1741 HPI_AESEBURX_SAMPLERATE, psample_rate);
1742}
1743
1744u16 HPI_AESEBU__receiver_get_user_data(const struct hpi_hsubsys *ph_subsys,
1745 u32 h_control, u16 index, u16 *pw_data)
1746{
1747 struct hpi_message hm;
1748 struct hpi_response hr;
1749 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
1750 HPI_CONTROL_GET_STATE);
1751 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
1752 hm.u.c.attribute = HPI_AESEBURX_USERDATA;
1753 hm.u.c.param1 = index;
1754
1755 hpi_send_recv(&hm, &hr);
1756
1757 if (pw_data)
1758 *pw_data = (u16)hr.u.c.param2;
1759 return hr.error;
1760}
1761
1762u16 HPI_AESEBU__receiver_get_channel_status(const struct hpi_hsubsys
1763 *ph_subsys, u32 h_control, u16 index, u16 *pw_data)
1764{
1765 struct hpi_message hm;
1766 struct hpi_response hr;
1767 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
1768 HPI_CONTROL_GET_STATE);
1769 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
1770 hm.u.c.attribute = HPI_AESEBURX_CHANNELSTATUS;
1771 hm.u.c.param1 = index;
1772
1773 hpi_send_recv(&hm, &hr);
1774
1775 if (pw_data)
1776 *pw_data = (u16)hr.u.c.param2;
1777 return hr.error;
1778}
1779
1780u16 HPI_AESEBU__receiver_get_error_status(const struct hpi_hsubsys *ph_subsys,
1781 u32 h_control, u16 *pw_error_data)
1782{
1783 u32 error_data = 0;
1784 u16 error = 0;
1785
1786 error = hpi_control_param1_get(ph_subsys, h_control,
1787 HPI_AESEBURX_ERRORSTATUS, &error_data);
1788 if (pw_error_data)
1789 *pw_error_data = (u16)error_data;
1790 return error;
1791}
1792
1793u16 HPI_AESEBU__transmitter_set_sample_rate(const struct hpi_hsubsys
1794 *ph_subsys, u32 h_control, u32 sample_rate)
1795{
1796 return hpi_control_param_set(ph_subsys, h_control,
1797 HPI_AESEBUTX_SAMPLERATE, sample_rate, 0);
1798}
1799
1800u16 HPI_AESEBU__transmitter_set_user_data(const struct hpi_hsubsys *ph_subsys,
1801 u32 h_control, u16 index, u16 data)
1802{
1803 return hpi_control_param_set(ph_subsys, h_control,
1804 HPI_AESEBUTX_USERDATA, index, data);
1805}
1806
1807u16 HPI_AESEBU__transmitter_set_channel_status(const struct hpi_hsubsys
1808 *ph_subsys, u32 h_control, u16 index, u16 data)
1809{
1810 return hpi_control_param_set(ph_subsys, h_control,
1811 HPI_AESEBUTX_CHANNELSTATUS, index, data);
1812}
1813
1814u16 HPI_AESEBU__transmitter_get_channel_status(const struct hpi_hsubsys
1815 *ph_subsys, u32 h_control, u16 index, u16 *pw_data)
1816{
1817 return HPI_ERROR_INVALID_OPERATION;
1818}
1819
1820u16 HPI_AESEBU__transmitter_query_format(const struct hpi_hsubsys *ph_subsys,
1821 const u32 h_aes_tx, const u32 index, u16 *pw_format)
1822{
1823 u32 qr;
1824 u16 err;
1825
1826 err = hpi_control_query(ph_subsys, h_aes_tx, HPI_AESEBUTX_FORMAT,
1827 index, 0, &qr);
1828 *pw_format = (u16)qr;
1829 return err;
1830}
1831
1832u16 HPI_AESEBU__transmitter_set_format(const struct hpi_hsubsys *ph_subsys,
1833 u32 h_control, u16 output_format)
1834{
1835 return hpi_control_param_set(ph_subsys, h_control,
1836 HPI_AESEBUTX_FORMAT, output_format, 0);
1837}
1838
1839u16 HPI_AESEBU__transmitter_get_format(const struct hpi_hsubsys *ph_subsys,
1840 u32 h_control, u16 *pw_output_format)
1841{
1842 u16 err;
1843 u32 param;
1844
1845 err = hpi_control_param1_get(ph_subsys, h_control,
1846 HPI_AESEBUTX_FORMAT, &param);
1847 if (!err && pw_output_format)
1848 *pw_output_format = (u16)param;
1849
1850 return err;
1851}
1852
1853u16 hpi_bitstream_set_clock_edge(const struct hpi_hsubsys *ph_subsys,
1854 u32 h_control, u16 edge_type)
1855{
1856 return hpi_control_param_set(ph_subsys, h_control,
1857 HPI_BITSTREAM_CLOCK_EDGE, edge_type, 0);
1858}
1859
1860u16 hpi_bitstream_set_data_polarity(const struct hpi_hsubsys *ph_subsys,
1861 u32 h_control, u16 polarity)
1862{
1863 return hpi_control_param_set(ph_subsys, h_control,
1864 HPI_BITSTREAM_DATA_POLARITY, polarity, 0);
1865}
1866
1867u16 hpi_bitstream_get_activity(const struct hpi_hsubsys *ph_subsys,
1868 u32 h_control, u16 *pw_clk_activity, u16 *pw_data_activity)
1869{
1870 struct hpi_message hm;
1871 struct hpi_response hr;
1872 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
1873 HPI_CONTROL_GET_STATE);
1874 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
1875 hm.u.c.attribute = HPI_BITSTREAM_ACTIVITY;
1876 hpi_send_recv(&hm, &hr);
1877 if (pw_clk_activity)
1878 *pw_clk_activity = (u16)hr.u.c.param1;
1879 if (pw_data_activity)
1880 *pw_data_activity = (u16)hr.u.c.param2;
1881 return hr.error;
1882}
1883
1884u16 hpi_channel_mode_query_mode(const struct hpi_hsubsys *ph_subsys,
1885 const u32 h_mode, const u32 index, u16 *pw_mode)
1886{
1887 u32 qr;
1888 u16 err;
1889
1890 err = hpi_control_query(ph_subsys, h_mode, HPI_CHANNEL_MODE_MODE,
1891 index, 0, &qr);
1892 *pw_mode = (u16)qr;
1893 return err;
1894}
1895
1896u16 hpi_channel_mode_set(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1897 u16 mode)
1898{
1899 return hpi_control_param_set(ph_subsys, h_control,
1900 HPI_CHANNEL_MODE_MODE, mode, 0);
1901}
1902
1903u16 hpi_channel_mode_get(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1904 u16 *mode)
1905{
1906 u32 mode32 = 0;
1907 u16 error = hpi_control_param1_get(ph_subsys, h_control,
1908 HPI_CHANNEL_MODE_MODE, &mode32);
1909 if (mode)
1910 *mode = (u16)mode32;
1911 return error;
1912}
1913
1914u16 hpi_cobranet_hmi_write(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1915 u32 hmi_address, u32 byte_count, u8 *pb_data)
1916{
1917 struct hpi_message hm;
1918 struct hpi_response hr;
1919 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX,
1920 HPI_CONTROL_SET_STATE);
1921 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
1922
1923 hm.u.cx.u.cobranet_data.byte_count = byte_count;
1924 hm.u.cx.u.cobranet_data.hmi_address = hmi_address;
1925
1926 if (byte_count <= 8) {
1927 memcpy(hm.u.cx.u.cobranet_data.data, pb_data, byte_count);
1928 hm.u.cx.attribute = HPI_COBRANET_SET;
1929 } else {
1930 hm.u.cx.u.cobranet_bigdata.pb_data = pb_data;
1931 hm.u.cx.attribute = HPI_COBRANET_SET_DATA;
1932 }
1933
1934 hpi_send_recv(&hm, &hr);
1935
1936 return hr.error;
1937}
1938
1939u16 hpi_cobranet_hmi_read(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1940 u32 hmi_address, u32 max_byte_count, u32 *pbyte_count, u8 *pb_data)
1941{
1942 struct hpi_message hm;
1943 struct hpi_response hr;
1944 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX,
1945 HPI_CONTROL_GET_STATE);
1946 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
1947
1948 hm.u.cx.u.cobranet_data.byte_count = max_byte_count;
1949 hm.u.cx.u.cobranet_data.hmi_address = hmi_address;
1950
1951 if (max_byte_count <= 8) {
1952 hm.u.cx.attribute = HPI_COBRANET_GET;
1953 } else {
1954 hm.u.cx.u.cobranet_bigdata.pb_data = pb_data;
1955 hm.u.cx.attribute = HPI_COBRANET_GET_DATA;
1956 }
1957
1958 hpi_send_recv(&hm, &hr);
1959 if (!hr.error && pb_data) {
1960
1961 *pbyte_count = hr.u.cx.u.cobranet_data.byte_count;
1962
1963 if (*pbyte_count < max_byte_count)
1964 max_byte_count = *pbyte_count;
1965
1966 if (hm.u.cx.attribute == HPI_COBRANET_GET) {
1967 memcpy(pb_data, hr.u.cx.u.cobranet_data.data,
1968 max_byte_count);
1969 } else {
1970
1971 }
1972
1973 }
1974 return hr.error;
1975}
1976
1977u16 hpi_cobranet_hmi_get_status(const struct hpi_hsubsys *ph_subsys,
1978 u32 h_control, u32 *pstatus, u32 *preadable_size,
1979 u32 *pwriteable_size)
1980{
1981 struct hpi_message hm;
1982 struct hpi_response hr;
1983 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX,
1984 HPI_CONTROL_GET_STATE);
1985 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
1986
1987 hm.u.cx.attribute = HPI_COBRANET_GET_STATUS;
1988
1989 hpi_send_recv(&hm, &hr);
1990 if (!hr.error) {
1991 if (pstatus)
1992 *pstatus = hr.u.cx.u.cobranet_status.status;
1993 if (preadable_size)
1994 *preadable_size =
1995 hr.u.cx.u.cobranet_status.readable_size;
1996 if (pwriteable_size)
1997 *pwriteable_size =
1998 hr.u.cx.u.cobranet_status.writeable_size;
1999 }
2000 return hr.error;
2001}
2002
2003u16 hpi_cobranet_getI_paddress(const struct hpi_hsubsys *ph_subsys,
2004 u32 h_control, u32 *pi_paddress)
2005{
2006 u32 byte_count;
2007 u32 iP;
2008 u16 error;
2009 error = hpi_cobranet_hmi_read(ph_subsys, h_control,
2010 HPI_COBRANET_HMI_cobra_ip_mon_currentIP, 4, &byte_count,
2011 (u8 *)&iP);
2012
2013 *pi_paddress =
2014 ((iP & 0xff000000) >> 8) | ((iP & 0x00ff0000) << 8) | ((iP &
2015 0x0000ff00) >> 8) | ((iP & 0x000000ff) << 8);
2016
2017 if (error)
2018 *pi_paddress = 0;
2019
2020 return error;
2021
2022}
2023
2024u16 hpi_cobranet_setI_paddress(const struct hpi_hsubsys *ph_subsys,
2025 u32 h_control, u32 i_paddress)
2026{
2027 u32 iP;
2028 u16 error;
2029
2030 iP = ((i_paddress & 0xff000000) >> 8) | ((i_paddress & 0x00ff0000) <<
2031 8) | ((i_paddress & 0x0000ff00) >> 8) | ((i_paddress &
2032 0x000000ff) << 8);
2033
2034 error = hpi_cobranet_hmi_write(ph_subsys, h_control,
2035 HPI_COBRANET_HMI_cobra_ip_mon_currentIP, 4, (u8 *)&iP);
2036
2037 return error;
2038
2039}
2040
2041u16 hpi_cobranet_get_staticI_paddress(const struct hpi_hsubsys *ph_subsys,
2042 u32 h_control, u32 *pi_paddress)
2043{
2044 u32 byte_count;
2045 u32 iP;
2046 u16 error;
2047 error = hpi_cobranet_hmi_read(ph_subsys, h_control,
2048 HPI_COBRANET_HMI_cobra_ip_mon_staticIP, 4, &byte_count,
2049 (u8 *)&iP);
2050
2051 *pi_paddress =
2052 ((iP & 0xff000000) >> 8) | ((iP & 0x00ff0000) << 8) | ((iP &
2053 0x0000ff00) >> 8) | ((iP & 0x000000ff) << 8);
2054
2055 if (error)
2056 *pi_paddress = 0;
2057
2058 return error;
2059
2060}
2061
2062u16 hpi_cobranet_set_staticI_paddress(const struct hpi_hsubsys *ph_subsys,
2063 u32 h_control, u32 i_paddress)
2064{
2065 u32 iP;
2066 u16 error;
2067
2068 iP = ((i_paddress & 0xff000000) >> 8) | ((i_paddress & 0x00ff0000) <<
2069 8) | ((i_paddress & 0x0000ff00) >> 8) | ((i_paddress &
2070 0x000000ff) << 8);
2071
2072 error = hpi_cobranet_hmi_write(ph_subsys, h_control,
2073 HPI_COBRANET_HMI_cobra_ip_mon_staticIP, 4, (u8 *)&iP);
2074
2075 return error;
2076
2077}
2078
2079u16 hpi_cobranet_getMA_caddress(const struct hpi_hsubsys *ph_subsys,
2080 u32 h_control, u32 *pmAC_MS_bs, u32 *pmAC_LS_bs)
2081{
2082 u32 byte_count;
2083 u16 error;
2084 u32 mAC;
2085 error = hpi_cobranet_hmi_read(ph_subsys, h_control,
2086 HPI_COBRANET_HMI_cobra_if_phy_address, 4, &byte_count,
2087 (u8 *)&mAC);
2088 *pmAC_MS_bs =
2089 ((mAC & 0xff000000) >> 8) | ((mAC & 0x00ff0000) << 8) | ((mAC
2090 & 0x0000ff00) >> 8) | ((mAC & 0x000000ff) << 8);
2091 error += hpi_cobranet_hmi_read(ph_subsys, h_control,
2092 HPI_COBRANET_HMI_cobra_if_phy_address + 1, 4, &byte_count,
2093 (u8 *)&mAC);
2094 *pmAC_LS_bs =
2095 ((mAC & 0xff000000) >> 8) | ((mAC & 0x00ff0000) << 8) | ((mAC
2096 & 0x0000ff00) >> 8) | ((mAC & 0x000000ff) << 8);
2097
2098 if (error) {
2099 *pmAC_MS_bs = 0;
2100 *pmAC_LS_bs = 0;
2101 }
2102
2103 return error;
2104}
2105
2106u16 hpi_compander_set(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2107 u16 attack, u16 decay, short ratio100, short threshold0_01dB,
2108 short makeup_gain0_01dB)
2109{
2110 struct hpi_message hm;
2111 struct hpi_response hr;
2112 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2113 HPI_CONTROL_SET_STATE);
2114 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
2115
2116 hm.u.c.param1 = attack + ((u32)ratio100 << 16);
2117 hm.u.c.param2 = (decay & 0xFFFFL);
2118 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
2122 hpi_send_recv(&hm, &hr);
2123
2124 return hr.error;
2125}
2126
2127u16 hpi_compander_get(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2128 u16 *pw_attack, u16 *pw_decay, short *pw_ratio100,
2129 short *pn_threshold0_01dB, short *pn_makeup_gain0_01dB)
2130{
2131 struct hpi_message hm;
2132 struct hpi_response hr;
2133 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2134 HPI_CONTROL_GET_STATE);
2135 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
2136 hm.u.c.attribute = HPI_COMPANDER_PARAMS;
2137
2138 hpi_send_recv(&hm, &hr);
2139
2140 if (pw_attack)
2141 *pw_attack = (short)(hr.u.c.param1 & 0xFFFF);
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
2147 if (pn_threshold0_01dB)
2148 *pn_threshold0_01dB = hr.u.c.an_log_value[0];
2149 if (pn_makeup_gain0_01dB)
2150 *pn_makeup_gain0_01dB = hr.u.c.an_log_value[1];
2151
2152 return hr.error;
2153}
2154
2155u16 hpi_level_query_range(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2156 short *min_gain_01dB, short *max_gain_01dB, short *step_gain_01dB)
2157{
2158 struct hpi_message hm;
2159 struct hpi_response hr;
2160 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2161 HPI_CONTROL_GET_STATE);
2162 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
2163 hm.u.c.attribute = HPI_LEVEL_RANGE;
2164
2165 hpi_send_recv(&hm, &hr);
2166 if (hr.error) {
2167 hr.u.c.an_log_value[0] = 0;
2168 hr.u.c.an_log_value[1] = 0;
2169 hr.u.c.param1 = 0;
2170 }
2171 if (min_gain_01dB)
2172 *min_gain_01dB = hr.u.c.an_log_value[0];
2173 if (max_gain_01dB)
2174 *max_gain_01dB = hr.u.c.an_log_value[1];
2175 if (step_gain_01dB)
2176 *step_gain_01dB = (short)hr.u.c.param1;
2177 return hr.error;
2178}
2179
2180u16 hpi_level_set_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2181 short an_gain0_01dB[HPI_MAX_CHANNELS]
2182 )
2183{
2184 struct hpi_message hm;
2185 struct hpi_response hr;
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}
2198
2199u16 hpi_level_get_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2200 short an_gain0_01dB[HPI_MAX_CHANNELS]
2201 )
2202{
2203 struct hpi_message hm;
2204 struct hpi_response hr;
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}
2216
2217u16 hpi_meter_query_channels(const struct hpi_hsubsys *ph_subsys,
2218 const u32 h_meter, u32 *p_channels)
2219{
2220 return hpi_control_query(ph_subsys, h_meter, HPI_METER_NUM_CHANNELS,
2221 0, 0, p_channels);
2222}
2223
2224u16 hpi_meter_get_peak(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2225 short an_peakdB[HPI_MAX_CHANNELS]
2226 )
2227{
2228 short i = 0;
2229
2230 struct hpi_message hm;
2231 struct hpi_response hr;
2232
2233 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2234 HPI_CONTROL_GET_STATE);
2235 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
2236 hm.obj_index = hm.obj_index;
2237 hm.u.c.attribute = HPI_METER_PEAK;
2238
2239 hpi_send_recv(&hm, &hr);
2240
2241 if (!hr.error)
2242 memcpy(an_peakdB, hr.u.c.an_log_value,
2243 sizeof(short) * HPI_MAX_CHANNELS);
2244 else
2245 for (i = 0; i < HPI_MAX_CHANNELS; i++)
2246 an_peakdB[i] = HPI_METER_MINIMUM;
2247 return hr.error;
2248}
2249
2250u16 hpi_meter_get_rms(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2251 short an_rmsdB[HPI_MAX_CHANNELS]
2252 )
2253{
2254 short i = 0;
2255
2256 struct hpi_message hm;
2257 struct hpi_response hr;
2258
2259 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2260 HPI_CONTROL_GET_STATE);
2261 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
2262 hm.u.c.attribute = HPI_METER_RMS;
2263
2264 hpi_send_recv(&hm, &hr);
2265
2266 if (!hr.error)
2267 memcpy(an_rmsdB, hr.u.c.an_log_value,
2268 sizeof(short) * HPI_MAX_CHANNELS);
2269 else
2270 for (i = 0; i < HPI_MAX_CHANNELS; i++)
2271 an_rmsdB[i] = HPI_METER_MINIMUM;
2272
2273 return hr.error;
2274}
2275
2276u16 hpi_meter_set_rms_ballistics(const struct hpi_hsubsys *ph_subsys,
2277 u32 h_control, u16 attack, u16 decay)
2278{
2279 return hpi_control_param_set(ph_subsys, h_control,
2280 HPI_METER_RMS_BALLISTICS, attack, decay);
2281}
2282
2283u16 hpi_meter_get_rms_ballistics(const struct hpi_hsubsys *ph_subsys,
2284 u32 h_control, u16 *pn_attack, u16 *pn_decay)
2285{
2286 u32 attack;
2287 u32 decay;
2288 u16 error;
2289
2290 error = hpi_control_param2_get(ph_subsys, h_control,
2291 HPI_METER_RMS_BALLISTICS, &attack, &decay);
2292
2293 if (pn_attack)
2294 *pn_attack = (unsigned short)attack;
2295 if (pn_decay)
2296 *pn_decay = (unsigned short)decay;
2297
2298 return error;
2299}
2300
2301u16 hpi_meter_set_peak_ballistics(const struct hpi_hsubsys *ph_subsys,
2302 u32 h_control, u16 attack, u16 decay)
2303{
2304 return hpi_control_param_set(ph_subsys, h_control,
2305 HPI_METER_PEAK_BALLISTICS, attack, decay);
2306}
2307
2308u16 hpi_meter_get_peak_ballistics(const struct hpi_hsubsys *ph_subsys,
2309 u32 h_control, u16 *pn_attack, u16 *pn_decay)
2310{
2311 u32 attack;
2312 u32 decay;
2313 u16 error;
2314
2315 error = hpi_control_param2_get(ph_subsys, h_control,
2316 HPI_METER_PEAK_BALLISTICS, &attack, &decay);
2317
2318 if (pn_attack)
2319 *pn_attack = (short)attack;
2320 if (pn_decay)
2321 *pn_decay = (short)decay;
2322
2323 return error;
2324}
2325
2326u16 hpi_microphone_set_phantom_power(const struct hpi_hsubsys *ph_subsys,
2327 u32 h_control, u16 on_off)
2328{
2329 return hpi_control_param_set(ph_subsys, h_control,
2330 HPI_MICROPHONE_PHANTOM_POWER, (u32)on_off, 0);
2331}
2332
2333u16 hpi_microphone_get_phantom_power(const struct hpi_hsubsys *ph_subsys,
2334 u32 h_control, u16 *pw_on_off)
2335{
2336 u16 error = 0;
2337 u32 on_off = 0;
2338 error = hpi_control_param1_get(ph_subsys, h_control,
2339 HPI_MICROPHONE_PHANTOM_POWER, &on_off);
2340 if (pw_on_off)
2341 *pw_on_off = (u16)on_off;
2342 return error;
2343}
2344
2345u16 hpi_multiplexer_set_source(const struct hpi_hsubsys *ph_subsys,
2346 u32 h_control, u16 source_node_type, u16 source_node_index)
2347{
2348 return hpi_control_param_set(ph_subsys, h_control,
2349 HPI_MULTIPLEXER_SOURCE, source_node_type, source_node_index);
2350}
2351
2352u16 hpi_multiplexer_get_source(const struct hpi_hsubsys *ph_subsys,
2353 u32 h_control, u16 *source_node_type, u16 *source_node_index)
2354{
2355 u32 node, index;
2356 u16 error = hpi_control_param2_get(ph_subsys, h_control,
2357 HPI_MULTIPLEXER_SOURCE, &node,
2358 &index);
2359 if (source_node_type)
2360 *source_node_type = (u16)node;
2361 if (source_node_index)
2362 *source_node_index = (u16)index;
2363 return error;
2364}
2365
2366u16 hpi_multiplexer_query_source(const struct hpi_hsubsys *ph_subsys,
2367 u32 h_control, u16 index, u16 *source_node_type,
2368 u16 *source_node_index)
2369{
2370 struct hpi_message hm;
2371 struct hpi_response hr;
2372 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2373 HPI_CONTROL_GET_STATE);
2374 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
2375 hm.u.c.attribute = HPI_MULTIPLEXER_QUERYSOURCE;
2376 hm.u.c.param1 = index;
2377
2378 hpi_send_recv(&hm, &hr);
2379
2380 if (source_node_type)
2381 *source_node_type = (u16)hr.u.c.param1;
2382 if (source_node_index)
2383 *source_node_index = (u16)hr.u.c.param2;
2384 return hr.error;
2385}
2386
2387u16 hpi_parametricEQ__get_info(const struct hpi_hsubsys *ph_subsys,
2388 u32 h_control, u16 *pw_number_of_bands, u16 *pw_on_off)
2389{
2390 u32 oB = 0;
2391 u32 oO = 0;
2392 u16 error = 0;
2393
2394 error = hpi_control_param2_get(ph_subsys, h_control,
2395 HPI_EQUALIZER_NUM_FILTERS, &oO, &oB);
2396 if (pw_number_of_bands)
2397 *pw_number_of_bands = (u16)oB;
2398 if (pw_on_off)
2399 *pw_on_off = (u16)oO;
2400 return error;
2401}
2402
2403u16 hpi_parametricEQ__set_state(const struct hpi_hsubsys *ph_subsys,
2404 u32 h_control, u16 on_off)
2405{
2406 return hpi_control_param_set(ph_subsys, h_control,
2407 HPI_EQUALIZER_NUM_FILTERS, on_off, 0);
2408}
2409
2410u16 hpi_parametricEQ__get_band(const struct hpi_hsubsys *ph_subsys,
2411 u32 h_control, u16 index, u16 *pn_type, u32 *pfrequency_hz,
2412 short *pnQ100, short *pn_gain0_01dB)
2413{
2414 struct hpi_message hm;
2415 struct hpi_response hr;
2416 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2417 HPI_CONTROL_GET_STATE);
2418 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
2419 hm.u.c.attribute = HPI_EQUALIZER_FILTER;
2420 hm.u.c.param2 = index;
2421
2422 hpi_send_recv(&hm, &hr);
2423
2424 if (pfrequency_hz)
2425 *pfrequency_hz = hr.u.c.param1;
2426 if (pn_type)
2427 *pn_type = (u16)(hr.u.c.param2 >> 16);
2428 if (pnQ100)
2429 *pnQ100 = hr.u.c.an_log_value[1];
2430 if (pn_gain0_01dB)
2431 *pn_gain0_01dB = hr.u.c.an_log_value[0];
2432
2433 return hr.error;
2434}
2435
2436u16 hpi_parametricEQ__set_band(const struct hpi_hsubsys *ph_subsys,
2437 u32 h_control, u16 index, u16 type, u32 frequency_hz, short q100,
2438 short gain0_01dB)
2439{
2440 struct hpi_message hm;
2441 struct hpi_response hr;
2442 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2443 HPI_CONTROL_SET_STATE);
2444 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
2445
2446 hm.u.c.param1 = frequency_hz;
2447 hm.u.c.param2 = (index & 0xFFFFL) + ((u32)type << 16);
2448 hm.u.c.an_log_value[0] = gain0_01dB;
2449 hm.u.c.an_log_value[1] = q100;
2450 hm.u.c.attribute = HPI_EQUALIZER_FILTER;
2451
2452 hpi_send_recv(&hm, &hr);
2453
2454 return hr.error;
2455}
2456
2457u16 hpi_parametricEQ__get_coeffs(const struct hpi_hsubsys *ph_subsys,
2458 u32 h_control, u16 index, short coeffs[5]
2459 )
2460{
2461 struct hpi_message hm;
2462 struct hpi_response hr;
2463 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2464 HPI_CONTROL_GET_STATE);
2465 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
2466 hm.u.c.attribute = HPI_EQUALIZER_COEFFICIENTS;
2467 hm.u.c.param2 = index;
2468
2469 hpi_send_recv(&hm, &hr);
2470
2471 coeffs[0] = (short)hr.u.c.an_log_value[0];
2472 coeffs[1] = (short)hr.u.c.an_log_value[1];
2473 coeffs[2] = (short)hr.u.c.param1;
2474 coeffs[3] = (short)(hr.u.c.param1 >> 16);
2475 coeffs[4] = (short)hr.u.c.param2;
2476
2477 return hr.error;
2478}
2479
2480u16 hpi_sample_clock_query_source(const struct hpi_hsubsys *ph_subsys,
2481 const u32 h_clock, const u32 index, u16 *pw_source)
2482{
2483 u32 qr;
2484 u16 err;
2485
2486 err = hpi_control_query(ph_subsys, h_clock, HPI_SAMPLECLOCK_SOURCE,
2487 index, 0, &qr);
2488 *pw_source = (u16)qr;
2489 return err;
2490}
2491
2492u16 hpi_sample_clock_set_source(const struct hpi_hsubsys *ph_subsys,
2493 u32 h_control, u16 source)
2494{
2495 return hpi_control_param_set(ph_subsys, h_control,
2496 HPI_SAMPLECLOCK_SOURCE, source, 0);
2497}
2498
2499u16 hpi_sample_clock_get_source(const struct hpi_hsubsys *ph_subsys,
2500 u32 h_control, u16 *pw_source)
2501{
2502 u16 error = 0;
2503 u32 source = 0;
2504 error = hpi_control_param1_get(ph_subsys, h_control,
2505 HPI_SAMPLECLOCK_SOURCE, &source);
2506 if (!error)
2507 if (pw_source)
2508 *pw_source = (u16)source;
2509 return error;
2510}
2511
2512u16 hpi_sample_clock_query_source_index(const struct hpi_hsubsys *ph_subsys,
2513 const u32 h_clock, const u32 index, const u32 source,
2514 u16 *pw_source_index)
2515{
2516 u32 qr;
2517 u16 err;
2518
2519 err = hpi_control_query(ph_subsys, h_clock,
2520 HPI_SAMPLECLOCK_SOURCE_INDEX, index, source, &qr);
2521 *pw_source_index = (u16)qr;
2522 return err;
2523}
2524
2525u16 hpi_sample_clock_set_source_index(const struct hpi_hsubsys *ph_subsys,
2526 u32 h_control, u16 source_index)
2527{
2528 return hpi_control_param_set(ph_subsys, h_control,
2529 HPI_SAMPLECLOCK_SOURCE_INDEX, source_index, 0);
2530}
2531
2532u16 hpi_sample_clock_get_source_index(const struct hpi_hsubsys *ph_subsys,
2533 u32 h_control, u16 *pw_source_index)
2534{
2535 u16 error = 0;
2536 u32 source_index = 0;
2537 error = hpi_control_param1_get(ph_subsys, h_control,
2538 HPI_SAMPLECLOCK_SOURCE_INDEX, &source_index);
2539 if (!error)
2540 if (pw_source_index)
2541 *pw_source_index = (u16)source_index;
2542 return error;
2543}
2544
2545u16 hpi_sample_clock_query_local_rate(const struct hpi_hsubsys *ph_subsys,
2546 const u32 h_clock, const u32 index, u32 *prate)
2547{
2548 u16 err;
2549 err = hpi_control_query(ph_subsys, h_clock,
2550 HPI_SAMPLECLOCK_LOCAL_SAMPLERATE, index, 0, prate);
2551
2552 return err;
2553}
2554
2555u16 hpi_sample_clock_set_local_rate(const struct hpi_hsubsys *ph_subsys,
2556 u32 h_control, u32 sample_rate)
2557{
2558 return hpi_control_param_set(ph_subsys, h_control,
2559 HPI_SAMPLECLOCK_LOCAL_SAMPLERATE, sample_rate, 0);
2560}
2561
2562u16 hpi_sample_clock_get_local_rate(const struct hpi_hsubsys *ph_subsys,
2563 u32 h_control, u32 *psample_rate)
2564{
2565 u16 error = 0;
2566 u32 sample_rate = 0;
2567 error = hpi_control_param1_get(ph_subsys, h_control,
2568 HPI_SAMPLECLOCK_LOCAL_SAMPLERATE, &sample_rate);
2569 if (!error)
2570 if (psample_rate)
2571 *psample_rate = sample_rate;
2572 return error;
2573}
2574
2575u16 hpi_sample_clock_get_sample_rate(const struct hpi_hsubsys *ph_subsys,
2576 u32 h_control, u32 *psample_rate)
2577{
2578 u16 error = 0;
2579 u32 sample_rate = 0;
2580 error = hpi_control_param1_get(ph_subsys, h_control,
2581 HPI_SAMPLECLOCK_SAMPLERATE, &sample_rate);
2582 if (!error)
2583 if (psample_rate)
2584 *psample_rate = sample_rate;
2585 return error;
2586}
2587
2588u16 hpi_sample_clock_set_auto(const struct hpi_hsubsys *ph_subsys,
2589 u32 h_control, u32 enable)
2590{
2591 return hpi_control_param_set(ph_subsys, h_control,
2592 HPI_SAMPLECLOCK_AUTO, enable, 0);
2593}
2594
2595u16 hpi_sample_clock_get_auto(const struct hpi_hsubsys *ph_subsys,
2596 u32 h_control, u32 *penable)
2597{
2598 return hpi_control_param1_get(ph_subsys, h_control,
2599 HPI_SAMPLECLOCK_AUTO, penable);
2600}
2601
2602u16 hpi_sample_clock_set_local_rate_lock(const struct hpi_hsubsys *ph_subsys,
2603 u32 h_control, u32 lock)
2604{
2605 return hpi_control_param_set(ph_subsys, h_control,
2606 HPI_SAMPLECLOCK_LOCAL_LOCK, lock, 0);
2607}
2608
2609u16 hpi_sample_clock_get_local_rate_lock(const struct hpi_hsubsys *ph_subsys,
2610 u32 h_control, u32 *plock)
2611{
2612 return hpi_control_param1_get(ph_subsys, h_control,
2613 HPI_SAMPLECLOCK_LOCAL_LOCK, plock);
2614}
2615
2616u16 hpi_tone_detector_get_frequency(const struct hpi_hsubsys *ph_subsys,
2617 u32 h_control, u32 index, u32 *frequency)
2618{
2619 return hpi_control_param_get(ph_subsys, h_control,
2620 HPI_TONEDETECTOR_FREQUENCY, index, 0, frequency, NULL);
2621}
2622
2623u16 hpi_tone_detector_get_state(const struct hpi_hsubsys *ph_subsys,
2624 u32 h_control, u32 *state)
2625{
2626 return hpi_control_param_get(ph_subsys, h_control,
2627 HPI_TONEDETECTOR_STATE, 0, 0, (u32 *)state, NULL);
2628}
2629
2630u16 hpi_tone_detector_set_enable(const struct hpi_hsubsys *ph_subsys,
2631 u32 h_control, u32 enable)
2632{
2633 return hpi_control_param_set(ph_subsys, h_control, HPI_GENERIC_ENABLE,
2634 (u32)enable, 0);
2635}
2636
2637u16 hpi_tone_detector_get_enable(const struct hpi_hsubsys *ph_subsys,
2638 u32 h_control, u32 *enable)
2639{
2640 return hpi_control_param_get(ph_subsys, h_control, HPI_GENERIC_ENABLE,
2641 0, 0, (u32 *)enable, NULL);
2642}
2643
2644u16 hpi_tone_detector_set_event_enable(const struct hpi_hsubsys *ph_subsys,
2645 u32 h_control, u32 event_enable)
2646{
2647 return hpi_control_param_set(ph_subsys, h_control,
2648 HPI_GENERIC_EVENT_ENABLE, (u32)event_enable, 0);
2649}
2650
2651u16 hpi_tone_detector_get_event_enable(const struct hpi_hsubsys *ph_subsys,
2652 u32 h_control, u32 *event_enable)
2653{
2654 return hpi_control_param_get(ph_subsys, h_control,
2655 HPI_GENERIC_EVENT_ENABLE, 0, 0, (u32 *)event_enable, NULL);
2656}
2657
2658u16 hpi_tone_detector_set_threshold(const struct hpi_hsubsys *ph_subsys,
2659 u32 h_control, int threshold)
2660{
2661 return hpi_control_param_set(ph_subsys, h_control,
2662 HPI_TONEDETECTOR_THRESHOLD, (u32)threshold, 0);
2663}
2664
2665u16 hpi_tone_detector_get_threshold(const struct hpi_hsubsys *ph_subsys,
2666 u32 h_control, int *threshold)
2667{
2668 return hpi_control_param_get(ph_subsys, h_control,
2669 HPI_TONEDETECTOR_THRESHOLD, 0, 0, (u32 *)threshold, NULL);
2670}
2671
2672u16 hpi_silence_detector_get_state(const struct hpi_hsubsys *ph_subsys,
2673 u32 h_control, u32 *state)
2674{
2675 return hpi_control_param_get(ph_subsys, h_control,
2676 HPI_SILENCEDETECTOR_STATE, 0, 0, (u32 *)state, NULL);
2677}
2678
2679u16 hpi_silence_detector_set_enable(const struct hpi_hsubsys *ph_subsys,
2680 u32 h_control, u32 enable)
2681{
2682 return hpi_control_param_set(ph_subsys, h_control, HPI_GENERIC_ENABLE,
2683 (u32)enable, 0);
2684}
2685
2686u16 hpi_silence_detector_get_enable(const struct hpi_hsubsys *ph_subsys,
2687 u32 h_control, u32 *enable)
2688{
2689 return hpi_control_param_get(ph_subsys, h_control, HPI_GENERIC_ENABLE,
2690 0, 0, (u32 *)enable, NULL);
2691}
2692
2693u16 hpi_silence_detector_set_event_enable(const struct hpi_hsubsys *ph_subsys,
2694 u32 h_control, u32 event_enable)
2695{
2696 return hpi_control_param_set(ph_subsys, h_control,
2697 HPI_GENERIC_EVENT_ENABLE, (u32)event_enable, 0);
2698}
2699
2700u16 hpi_silence_detector_get_event_enable(const struct hpi_hsubsys *ph_subsys,
2701 u32 h_control, u32 *event_enable)
2702{
2703 return hpi_control_param_get(ph_subsys, h_control,
2704 HPI_GENERIC_EVENT_ENABLE, 0, 0, (u32 *)event_enable, NULL);
2705}
2706
2707u16 hpi_silence_detector_set_delay(const struct hpi_hsubsys *ph_subsys,
2708 u32 h_control, u32 delay)
2709{
2710 return hpi_control_param_set(ph_subsys, h_control,
2711 HPI_SILENCEDETECTOR_DELAY, (u32)delay, 0);
2712}
2713
2714u16 hpi_silence_detector_get_delay(const struct hpi_hsubsys *ph_subsys,
2715 u32 h_control, u32 *delay)
2716{
2717 return hpi_control_param_get(ph_subsys, h_control,
2718 HPI_SILENCEDETECTOR_DELAY, 0, 0, (u32 *)delay, NULL);
2719}
2720
2721u16 hpi_silence_detector_set_threshold(const struct hpi_hsubsys *ph_subsys,
2722 u32 h_control, int threshold)
2723{
2724 return hpi_control_param_set(ph_subsys, h_control,
2725 HPI_SILENCEDETECTOR_THRESHOLD, (u32)threshold, 0);
2726}
2727
2728u16 hpi_silence_detector_get_threshold(const struct hpi_hsubsys *ph_subsys,
2729 u32 h_control, int *threshold)
2730{
2731 return hpi_control_param_get(ph_subsys, h_control,
2732 HPI_SILENCEDETECTOR_THRESHOLD, 0, 0, (u32 *)threshold, NULL);
2733}
2734
2735u16 hpi_tuner_query_band(const struct hpi_hsubsys *ph_subsys,
2736 const u32 h_tuner, const u32 index, u16 *pw_band)
2737{
2738 u32 qr;
2739 u16 err;
2740
2741 err = hpi_control_query(ph_subsys, h_tuner, HPI_TUNER_BAND, index, 0,
2742 &qr);
2743 *pw_band = (u16)qr;
2744 return err;
2745}
2746
2747u16 hpi_tuner_set_band(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2748 u16 band)
2749{
2750 return hpi_control_param_set(ph_subsys, h_control, HPI_TUNER_BAND,
2751 band, 0);
2752}
2753
2754u16 hpi_tuner_get_band(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2755 u16 *pw_band)
2756{
2757 u32 band = 0;
2758 u16 error = 0;
2759
2760 error = hpi_control_param1_get(ph_subsys, h_control, HPI_TUNER_BAND,
2761 &band);
2762 if (pw_band)
2763 *pw_band = (u16)band;
2764 return error;
2765}
2766
2767u16 hpi_tuner_query_frequency(const struct hpi_hsubsys *ph_subsys,
2768 const u32 h_tuner, const u32 index, const u16 band, u32 *pfreq)
2769{
2770 return hpi_control_query(ph_subsys, h_tuner, HPI_TUNER_FREQ, index,
2771 band, pfreq);
2772}
2773
2774u16 hpi_tuner_set_frequency(const struct hpi_hsubsys *ph_subsys,
2775 u32 h_control, u32 freq_ink_hz)
2776{
2777 return hpi_control_param_set(ph_subsys, h_control, HPI_TUNER_FREQ,
2778 freq_ink_hz, 0);
2779}
2780
2781u16 hpi_tuner_get_frequency(const struct hpi_hsubsys *ph_subsys,
2782 u32 h_control, u32 *pw_freq_ink_hz)
2783{
2784 return hpi_control_param1_get(ph_subsys, h_control, HPI_TUNER_FREQ,
2785 pw_freq_ink_hz);
2786}
2787
2788u16 hpi_tuner_query_gain(const struct hpi_hsubsys *ph_subsys,
2789 const u32 h_tuner, const u32 index, u16 *pw_gain)
2790{
2791 u32 qr;
2792 u16 err;
2793
2794 err = hpi_control_query(ph_subsys, h_tuner, HPI_TUNER_BAND, index, 0,
2795 &qr);
2796 *pw_gain = (u16)qr;
2797 return err;
2798}
2799
2800u16 hpi_tuner_set_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2801 short gain)
2802{
2803 return hpi_control_param_set(ph_subsys, h_control, HPI_TUNER_GAIN,
2804 gain, 0);
2805}
2806
2807u16 hpi_tuner_get_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2808 short *pn_gain)
2809{
2810 u32 gain = 0;
2811 u16 error = 0;
2812
2813 error = hpi_control_param1_get(ph_subsys, h_control, HPI_TUNER_GAIN,
2814 &gain);
2815 if (pn_gain)
2816 *pn_gain = (u16)gain;
2817 return error;
2818}
2819
2820u16 hpi_tuner_getRF_level(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2821 short *pw_level)
2822{
2823 struct hpi_message hm;
2824 struct hpi_response hr;
2825 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2826 HPI_CONTROL_GET_STATE);
2827 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
2828 hm.u.c.attribute = HPI_TUNER_LEVEL;
2829 hm.u.c.param1 = HPI_TUNER_LEVEL_AVERAGE;
2830 hpi_send_recv(&hm, &hr);
2831 if (pw_level)
2832 *pw_level = (short)hr.u.c.param1;
2833 return hr.error;
2834}
2835
2836u16 hpi_tuner_get_rawRF_level(const struct hpi_hsubsys *ph_subsys,
2837 u32 h_control, short *pw_level)
2838{
2839 struct hpi_message hm;
2840 struct hpi_response hr;
2841 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2842 HPI_CONTROL_GET_STATE);
2843 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
2844 hm.u.c.attribute = HPI_TUNER_LEVEL;
2845 hm.u.c.param1 = HPI_TUNER_LEVEL_RAW;
2846 hpi_send_recv(&hm, &hr);
2847 if (pw_level)
2848 *pw_level = (short)hr.u.c.param1;
2849 return hr.error;
2850}
2851
2852u16 hpi_tuner_query_deemphasis(const struct hpi_hsubsys *ph_subsys,
2853 const u32 h_tuner, const u32 index, const u16 band, u32 *pdeemphasis)
2854{
2855 return hpi_control_query(ph_subsys, h_tuner, HPI_TUNER_DEEMPHASIS,
2856 index, band, pdeemphasis);
2857}
2858
2859u16 hpi_tuner_set_deemphasis(const struct hpi_hsubsys *ph_subsys,
2860 u32 h_control, u32 deemphasis)
2861{
2862 return hpi_control_param_set(ph_subsys, h_control,
2863 HPI_TUNER_DEEMPHASIS, deemphasis, 0);
2864}
2865
2866u16 hpi_tuner_get_deemphasis(const struct hpi_hsubsys *ph_subsys,
2867 u32 h_control, u32 *pdeemphasis)
2868{
2869 return hpi_control_param1_get(ph_subsys, h_control,
2870 HPI_TUNER_DEEMPHASIS, pdeemphasis);
2871}
2872
2873u16 hpi_tuner_query_program(const struct hpi_hsubsys *ph_subsys,
2874 const u32 h_tuner, u32 *pbitmap_program)
2875{
2876 return hpi_control_query(ph_subsys, h_tuner, HPI_TUNER_PROGRAM, 0, 0,
2877 pbitmap_program);
2878}
2879
2880u16 hpi_tuner_set_program(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2881 u32 program)
2882{
2883 return hpi_control_param_set(ph_subsys, h_control, HPI_TUNER_PROGRAM,
2884 program, 0);
2885}
2886
2887u16 hpi_tuner_get_program(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2888 u32 *pprogram)
2889{
2890 return hpi_control_param1_get(ph_subsys, h_control, HPI_TUNER_PROGRAM,
2891 pprogram);
2892}
2893
2894u16 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)
2896{
2897 return hpi_control_get_string(ph_subsys, h_control,
2898 HPI_TUNER_HDRADIO_DSP_VERSION, psz_dsp_version, string_size);
2899}
2900
2901u16 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)
2903{
2904 return hpi_control_get_string(ph_subsys, h_control,
2905 HPI_TUNER_HDRADIO_SDK_VERSION, psz_sdk_version, string_size);
2906}
2907
2908u16 hpi_tuner_get_status(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2909 u16 *pw_status_mask, u16 *pw_status)
2910{
2911 u32 status = 0;
2912 u16 error = 0;
2913
2914 error = hpi_control_param1_get(ph_subsys, h_control, HPI_TUNER_STATUS,
2915 &status);
2916 if (pw_status) {
2917 if (!error) {
2918 *pw_status_mask = (u16)(status >> 16);
2919 *pw_status = (u16)(status & 0xFFFF);
2920 } else {
2921 *pw_status_mask = 0;
2922 *pw_status = 0;
2923 }
2924 }
2925 return error;
2926}
2927
2928u16 hpi_tuner_set_mode(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2929 u32 mode, u32 value)
2930{
2931 return hpi_control_param_set(ph_subsys, h_control, HPI_TUNER_MODE,
2932 mode, value);
2933}
2934
2935u16 hpi_tuner_get_mode(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2936 u32 mode, u32 *pn_value)
2937{
2938 return hpi_control_param_get(ph_subsys, h_control, HPI_TUNER_MODE,
2939 mode, 0, pn_value, NULL);
2940}
2941
2942u16 hpi_tuner_get_hd_radio_signal_quality(const struct hpi_hsubsys *ph_subsys,
2943 u32 h_control, u32 *pquality)
2944{
2945 return hpi_control_param_get(ph_subsys, h_control,
2946 HPI_TUNER_HDRADIO_SIGNAL_QUALITY, 0, 0, pquality, NULL);
2947}
2948
2949u16 hpi_tuner_get_hd_radio_signal_blend(const struct hpi_hsubsys *ph_subsys,
2950 u32 h_control, u32 *pblend)
2951{
2952 return hpi_control_param_get(ph_subsys, h_control,
2953 HPI_TUNER_HDRADIO_BLEND, 0, 0, pblend, NULL);
2954}
2955
2956u16 hpi_tuner_set_hd_radio_signal_blend(const struct hpi_hsubsys *ph_subsys,
2957 u32 h_control, const u32 blend)
2958{
2959 return hpi_control_param_set(ph_subsys, h_control,
2960 HPI_TUNER_HDRADIO_BLEND, blend, 0);
2961}
2962
2963u16 hpi_tuner_getRDS(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2964 char *p_data)
2965{
2966 struct hpi_message hm;
2967 struct hpi_response hr;
2968 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2969 HPI_CONTROL_GET_STATE);
2970 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
2971 hm.u.c.attribute = HPI_TUNER_RDS;
2972 hpi_send_recv(&hm, &hr);
2973 if (p_data) {
2974 *(u32 *)&p_data[0] = hr.u.cu.tuner.rds.data[0];
2975 *(u32 *)&p_data[4] = hr.u.cu.tuner.rds.data[1];
2976 *(u32 *)&p_data[8] = hr.u.cu.tuner.rds.bLER;
2977 }
2978 return hr.error;
2979}
2980
2981u16 HPI_PAD__get_channel_name(const struct hpi_hsubsys *ph_subsys,
2982 u32 h_control, char *psz_string, const u32 data_length)
2983{
2984 return hpi_control_get_string(ph_subsys, h_control,
2985 HPI_PAD_CHANNEL_NAME, psz_string, data_length);
2986}
2987
2988u16 HPI_PAD__get_artist(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2989 char *psz_string, const u32 data_length)
2990{
2991 return hpi_control_get_string(ph_subsys, h_control, HPI_PAD_ARTIST,
2992 psz_string, data_length);
2993}
2994
2995u16 HPI_PAD__get_title(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2996 char *psz_string, const u32 data_length)
2997{
2998 return hpi_control_get_string(ph_subsys, h_control, HPI_PAD_TITLE,
2999 psz_string, data_length);
3000}
3001
3002u16 HPI_PAD__get_comment(const struct hpi_hsubsys *ph_subsys, u32 h_control,
3003 char *psz_string, const u32 data_length)
3004{
3005 return hpi_control_get_string(ph_subsys, h_control, HPI_PAD_COMMENT,
3006 psz_string, data_length);
3007}
3008
3009u16 HPI_PAD__get_program_type(const struct hpi_hsubsys *ph_subsys,
3010 u32 h_control, u32 *ppTY)
3011{
3012 return hpi_control_param_get(ph_subsys, h_control,
3013 HPI_PAD_PROGRAM_TYPE, 0, 0, ppTY, NULL);
3014}
3015
3016u16 HPI_PAD__get_rdsPI(const struct hpi_hsubsys *ph_subsys, u32 h_control,
3017 u32 *ppI)
3018{
3019 return hpi_control_param_get(ph_subsys, h_control, HPI_PAD_PROGRAM_ID,
3020 0, 0, ppI, NULL);
3021}
3022
3023u16 hpi_volume_query_channels(const struct hpi_hsubsys *ph_subsys,
3024 const u32 h_volume, u32 *p_channels)
3025{
3026 return hpi_control_query(ph_subsys, h_volume, HPI_VOLUME_NUM_CHANNELS,
3027 0, 0, p_channels);
3028}
3029
3030u16 hpi_volume_set_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control,
3031 short an_log_gain[HPI_MAX_CHANNELS]
3032 )
3033{
3034 struct hpi_message hm;
3035 struct hpi_response hr;
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}
3047
3048u16 hpi_volume_get_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control,
3049 short an_log_gain[HPI_MAX_CHANNELS]
3050 )
3051{
3052 struct hpi_message hm;
3053 struct hpi_response hr;
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}
3065
3066u16 hpi_volume_query_range(const struct hpi_hsubsys *ph_subsys, u32 h_control,
3067 short *min_gain_01dB, short *max_gain_01dB, short *step_gain_01dB)
3068{
3069 struct hpi_message hm;
3070 struct hpi_response hr;
3071 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
3072 HPI_CONTROL_GET_STATE);
3073 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
3074 hm.u.c.attribute = HPI_VOLUME_RANGE;
3075
3076 hpi_send_recv(&hm, &hr);
3077 if (hr.error) {
3078 hr.u.c.an_log_value[0] = 0;
3079 hr.u.c.an_log_value[1] = 0;
3080 hr.u.c.param1 = 0;
3081 }
3082 if (min_gain_01dB)
3083 *min_gain_01dB = hr.u.c.an_log_value[0];
3084 if (max_gain_01dB)
3085 *max_gain_01dB = hr.u.c.an_log_value[1];
3086 if (step_gain_01dB)
3087 *step_gain_01dB = (short)hr.u.c.param1;
3088 return hr.error;
3089}
3090
3091u16 hpi_volume_auto_fade_profile(const struct hpi_hsubsys *ph_subsys,
3092 u32 h_control, short an_stop_gain0_01dB[HPI_MAX_CHANNELS],
3093 u32 duration_ms, u16 profile)
3094{
3095 struct hpi_message hm;
3096 struct hpi_response hr;
3097 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
3098 HPI_CONTROL_SET_STATE);
3099 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
3100
3101 memcpy(hm.u.c.an_log_value, an_stop_gain0_01dB,
3102 sizeof(short) * HPI_MAX_CHANNELS);
3103
3104 hm.u.c.attribute = HPI_VOLUME_AUTOFADE;
3105 hm.u.c.param1 = duration_ms;
3106 hm.u.c.param2 = profile;
3107
3108 hpi_send_recv(&hm, &hr);
3109
3110 return hr.error;
3111}
3112
3113u16 hpi_volume_auto_fade(const struct hpi_hsubsys *ph_subsys, u32 h_control,
3114 short an_stop_gain0_01dB[HPI_MAX_CHANNELS], u32 duration_ms)
3115{
3116 return hpi_volume_auto_fade_profile(ph_subsys, h_control,
3117 an_stop_gain0_01dB, duration_ms, HPI_VOLUME_AUTOFADE_LOG);
3118}
3119
3120u16 hpi_vox_set_threshold(const struct hpi_hsubsys *ph_subsys, u32 h_control,
3121 short an_gain0_01dB)
3122{
3123 struct hpi_message hm;
3124 struct hpi_response hr;
3125 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
3126 HPI_CONTROL_SET_STATE);
3127 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
3128 hm.u.c.attribute = HPI_VOX_THRESHOLD;
3129
3130 hm.u.c.an_log_value[0] = an_gain0_01dB;
3131
3132 hpi_send_recv(&hm, &hr);
3133
3134 return hr.error;
3135}
3136
3137u16 hpi_vox_get_threshold(const struct hpi_hsubsys *ph_subsys, u32 h_control,
3138 short *an_gain0_01dB)
3139{
3140 struct hpi_message hm;
3141 struct hpi_response hr;
3142 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
3143 HPI_CONTROL_GET_STATE);
3144 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
3145 hm.u.c.attribute = HPI_VOX_THRESHOLD;
3146
3147 hpi_send_recv(&hm, &hr);
3148
3149 *an_gain0_01dB = hr.u.c.an_log_value[0];
3150
3151 return hr.error;
3152}
3153
3154static size_t strv_packet_size = MIN_STRV_PACKET_SIZE;
3155
3156static size_t entity_type_to_size[LAST_ENTITY_TYPE] = {
3157 0,
3158 sizeof(struct hpi_entity),
3159 sizeof(void *),
3160
3161 sizeof(int),
3162 sizeof(float),
3163 sizeof(double),
3164
3165 sizeof(char),
3166 sizeof(char),
3167
3168 4 * sizeof(char),
3169 16 * sizeof(char),
3170 6 * sizeof(char),
3171};
3172
3173inline size_t hpi_entity_size(struct hpi_entity *entity_ptr)
3174{
3175 return entity_ptr->header.size;
3176}
3177
3178inline size_t hpi_entity_header_size(struct hpi_entity *entity_ptr)
3179{
3180 return sizeof(entity_ptr->header);
3181}
3182
3183inline size_t hpi_entity_value_size(struct hpi_entity *entity_ptr)
3184{
3185 return hpi_entity_size(entity_ptr) -
3186 hpi_entity_header_size(entity_ptr);
3187}
3188
3189inline size_t hpi_entity_item_count(struct hpi_entity *entity_ptr)
3190{
3191 return hpi_entity_value_size(entity_ptr) /
3192 entity_type_to_size[entity_ptr->header.type];
3193}
3194
3195inline struct hpi_entity *hpi_entity_ptr_to_next(struct hpi_entity
3196 *entity_ptr)
3197{
3198 return (void *)(((uint8_t *) entity_ptr) +
3199 hpi_entity_size(entity_ptr));
3200}
3201
3202inline u16 hpi_entity_check_type(const enum e_entity_type t)
3203{
3204 if (t >= 0 && t < STR_TYPE_FIELD_MAX)
3205 return 0;
3206 return HPI_ERROR_ENTITY_TYPE_INVALID;
3207}
3208
3209inline u16 hpi_entity_check_role(const enum e_entity_role r)
3210{
3211 if (r >= 0 && r < STR_ROLE_FIELD_MAX)
3212 return 0;
3213 return HPI_ERROR_ENTITY_ROLE_INVALID;
3214}
3215
3216static u16 hpi_entity_get_next(struct hpi_entity *entity, int recursive_flag,
3217 void *guard_p, struct hpi_entity **next)
3218{
3219 HPI_DEBUG_ASSERT(entity != NULL);
3220 HPI_DEBUG_ASSERT(next != NULL);
3221 HPI_DEBUG_ASSERT(hpi_entity_size(entity) != 0);
3222
3223 if (guard_p <= (void *)entity) {
3224 *next = NULL;
3225 return 0;
3226 }
3227
3228 if (recursive_flag && entity->header.type == entity_type_sequence)
3229 *next = (struct hpi_entity *)entity->value;
3230 else
3231 *next = (struct hpi_entity *)hpi_entity_ptr_to_next(entity);
3232
3233 if (guard_p <= (void *)*next) {
3234 *next = NULL;
3235 return 0;
3236 }
3237
3238 HPI_DEBUG_ASSERT(guard_p >= (void *)hpi_entity_ptr_to_next(*next));
3239 return 0;
3240}
3241
3242u16 hpi_entity_find_next(struct hpi_entity *container_entity,
3243 enum e_entity_type type, enum e_entity_role role, int recursive_flag,
3244 struct hpi_entity **current_match)
3245{
3246 struct hpi_entity *tmp = NULL;
3247 void *guard_p = NULL;
3248
3249 HPI_DEBUG_ASSERT(container_entity != NULL);
3250 guard_p = hpi_entity_ptr_to_next(container_entity);
3251
3252 if (*current_match != NULL)
3253 hpi_entity_get_next(*current_match, recursive_flag, guard_p,
3254 &tmp);
3255 else
3256 hpi_entity_get_next(container_entity, 1, guard_p, &tmp);
3257
3258 while (tmp) {
3259 u16 err;
3260
3261 HPI_DEBUG_ASSERT((void *)tmp >= (void *)container_entity);
3262
3263 if ((!type || tmp->header.type == type) && (!role
3264 || tmp->header.role == role)) {
3265 *current_match = tmp;
3266 return 0;
3267 }
3268
3269 err = hpi_entity_get_next(tmp, recursive_flag, guard_p,
3270 current_match);
3271 if (err)
3272 return err;
3273
3274 tmp = *current_match;
3275 }
3276
3277 *current_match = NULL;
3278 return 0;
3279}
3280
3281void hpi_entity_free(struct hpi_entity *entity)
3282{
3283 kfree(entity);
3284}
3285
3286static u16 hpi_entity_alloc_and_copy(struct hpi_entity *src,
3287 struct hpi_entity **dst)
3288{
3289 size_t buf_size;
3290 HPI_DEBUG_ASSERT(dst != NULL);
3291 HPI_DEBUG_ASSERT(src != NULL);
3292
3293 buf_size = hpi_entity_size(src);
3294 *dst = kmalloc(buf_size, GFP_KERNEL);
3295 if (*dst == NULL)
3296 return HPI_ERROR_MEMORY_ALLOC;
3297 memcpy(*dst, src, buf_size);
3298 return 0;
3299}
3300
3301u16 hpi_universal_info(const struct hpi_hsubsys *ph_subsys, u32 hC,
3302 struct hpi_entity **info)
3303{
3304 struct hpi_msg_strv hm;
3305 struct hpi_res_strv *phr;
3306 u16 hpi_err;
3307 int remaining_attempts = 2;
3308 size_t resp_packet_size = 1024;
3309
3310 *info = NULL;
3311
3312 while (remaining_attempts--) {
3313 phr = kmalloc(resp_packet_size, GFP_KERNEL);
3314 HPI_DEBUG_ASSERT(phr != NULL);
3315
3316 hpi_init_message_responseV1(&hm.h, (u16)sizeof(hm), &phr->h,
3317 (u16)resp_packet_size, HPI_OBJ_CONTROL,
3318 HPI_CONTROL_GET_INFO);
3319 u32TOINDEXES(hC, &hm.h.adapter_index, &hm.h.obj_index);
3320
3321 hm.strv.header.size = sizeof(hm.strv);
3322 phr->strv.header.size = resp_packet_size - sizeof(phr->h);
3323
3324 hpi_send_recv((struct hpi_message *)&hm.h,
3325 (struct hpi_response *)&phr->h);
3326 if (phr->h.error == HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL) {
3327
3328 HPI_DEBUG_ASSERT(phr->h.specific_error >
3329 MIN_STRV_PACKET_SIZE
3330 && phr->h.specific_error < 1500);
3331 resp_packet_size = phr->h.specific_error;
3332 } else {
3333 remaining_attempts = 0;
3334 if (!phr->h.error)
3335 hpi_entity_alloc_and_copy(&phr->strv, info);
3336 }
3337
3338 hpi_err = phr->h.error;
3339 kfree(phr);
3340 }
3341
3342 return hpi_err;
3343}
3344
3345u16 hpi_universal_get(const struct hpi_hsubsys *ph_subsys, u32 hC,
3346 struct hpi_entity **value)
3347{
3348 struct hpi_msg_strv hm;
3349 struct hpi_res_strv *phr;
3350 u16 hpi_err;
3351 int remaining_attempts = 2;
3352
3353 *value = NULL;
3354
3355 while (remaining_attempts--) {
3356 phr = kmalloc(strv_packet_size, GFP_KERNEL);
3357 if (!phr)
3358 return HPI_ERROR_MEMORY_ALLOC;
3359
3360 hpi_init_message_responseV1(&hm.h, (u16)sizeof(hm), &phr->h,
3361 (u16)strv_packet_size, HPI_OBJ_CONTROL,
3362 HPI_CONTROL_GET_STATE);
3363 u32TOINDEXES(hC, &hm.h.adapter_index, &hm.h.obj_index);
3364
3365 hm.strv.header.size = sizeof(hm.strv);
3366 phr->strv.header.size = strv_packet_size - sizeof(phr->h);
3367
3368 hpi_send_recv((struct hpi_message *)&hm.h,
3369 (struct hpi_response *)&phr->h);
3370 if (phr->h.error == HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL) {
3371
3372 HPI_DEBUG_ASSERT(phr->h.specific_error >
3373 MIN_STRV_PACKET_SIZE
3374 && phr->h.specific_error < 1000);
3375 strv_packet_size = phr->h.specific_error;
3376 } else {
3377 remaining_attempts = 0;
3378 if (!phr->h.error)
3379 hpi_entity_alloc_and_copy(&phr->strv, value);
3380 }
3381
3382 hpi_err = phr->h.error;
3383 kfree(phr);
3384 }
3385
3386 return hpi_err;
3387}
3388
3389u16 hpi_universal_set(const struct hpi_hsubsys *ph_subsys, u32 hC,
3390 struct hpi_entity *value)
3391{
3392 struct hpi_msg_strv *phm;
3393 struct hpi_res_strv hr;
3394
3395 phm = kmalloc(sizeof(phm->h) + value->header.size, GFP_KERNEL);
3396 HPI_DEBUG_ASSERT(phm != NULL);
3397
3398 hpi_init_message_responseV1(&phm->h,
3399 sizeof(phm->h) + value->header.size, &hr.h, sizeof(hr),
3400 HPI_OBJ_CONTROL, HPI_CONTROL_SET_STATE);
3401 u32TOINDEXES(hC, &phm->h.adapter_index, &phm->h.obj_index);
3402 hr.strv.header.size = sizeof(hr.strv);
3403
3404 memcpy(&phm->strv, value, value->header.size);
3405 hpi_send_recv((struct hpi_message *)&phm->h,
3406 (struct hpi_response *)&hr.h);
3407
3408 return hr.h.error;
3409}
3410
3411u16 hpi_entity_alloc_and_pack(const enum e_entity_type type,
3412 const size_t item_count, const enum e_entity_role role, void *value,
3413 struct hpi_entity **entity)
3414{
3415 size_t bytes_to_copy, total_size;
3416 u16 hE = 0;
3417 *entity = NULL;
3418
3419 hE = hpi_entity_check_type(type);
3420 if (hE)
3421 return hE;
3422
3423 HPI_DEBUG_ASSERT(role > entity_role_null && type < LAST_ENTITY_TYPE);
3424
3425 bytes_to_copy = entity_type_to_size[type] * item_count;
3426 total_size = hpi_entity_header_size(*entity) + bytes_to_copy;
3427
3428 HPI_DEBUG_ASSERT(total_size >= hpi_entity_header_size(*entity)
3429 && total_size < STR_SIZE_FIELD_MAX);
3430
3431 *entity = kmalloc(total_size, GFP_KERNEL);
3432 if (*entity == NULL)
3433 return HPI_ERROR_MEMORY_ALLOC;
3434 memcpy((*entity)->value, value, bytes_to_copy);
3435 (*entity)->header.size =
3436 hpi_entity_header_size(*entity) + bytes_to_copy;
3437 (*entity)->header.type = type;
3438 (*entity)->header.role = role;
3439 return 0;
3440}
3441
3442u16 hpi_entity_copy_value_from(struct hpi_entity *entity,
3443 enum e_entity_type type, size_t item_count, void *value_dst_p)
3444{
3445 size_t bytes_to_copy;
3446
3447 if (entity->header.type != type)
3448 return HPI_ERROR_ENTITY_TYPE_MISMATCH;
3449
3450 if (hpi_entity_item_count(entity) != item_count)
3451 return HPI_ERROR_ENTITY_ITEM_COUNT;
3452
3453 bytes_to_copy = entity_type_to_size[type] * item_count;
3454 memcpy(value_dst_p, entity->value, bytes_to_copy);
3455 return 0;
3456}
3457
3458u16 hpi_entity_unpack(struct hpi_entity *entity, enum e_entity_type *type,
3459 size_t *item_count, enum e_entity_role *role, void **value)
3460{
3461 u16 err = 0;
3462 HPI_DEBUG_ASSERT(entity != NULL);
3463
3464 if (type)
3465 *type = entity->header.type;
3466
3467 if (role)
3468 *role = entity->header.role;
3469
3470 if (value)
3471 *value = entity->value;
3472
3473 if (item_count != NULL) {
3474 if (entity->header.type == entity_type_sequence) {
3475 void *guard_p = hpi_entity_ptr_to_next(entity);
3476 struct hpi_entity *next = NULL;
3477 void *contents = entity->value;
3478
3479 *item_count = 0;
3480 while (contents < guard_p) {
3481 (*item_count)++;
3482 err = hpi_entity_get_next(contents, 0,
3483 guard_p, &next);
3484 if (next == NULL || err)
3485 break;
3486 contents = next;
3487 }
3488 } else {
3489 *item_count = hpi_entity_item_count(entity);
3490 }
3491 }
3492 return err;
3493}
3494
3495u16 hpi_gpio_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
3496 u32 *ph_gpio, u16 *pw_number_input_bits, u16 *pw_number_output_bits)
3497{
3498 struct hpi_message hm;
3499 struct hpi_response hr;
3500 hpi_init_message_response(&hm, &hr, HPI_OBJ_GPIO, HPI_GPIO_OPEN);
3501 hm.adapter_index = adapter_index;
3502
3503 hpi_send_recv(&hm, &hr);
3504
3505 if (hr.error == 0) {
3506 *ph_gpio =
3507 hpi_indexes_to_handle(HPI_OBJ_GPIO, adapter_index, 0);
3508 if (pw_number_input_bits)
3509 *pw_number_input_bits = hr.u.l.number_input_bits;
3510 if (pw_number_output_bits)
3511 *pw_number_output_bits = hr.u.l.number_output_bits;
3512 } else
3513 *ph_gpio = 0;
3514 return hr.error;
3515}
3516
3517u16 hpi_gpio_read_bit(const struct hpi_hsubsys *ph_subsys, u32 h_gpio,
3518 u16 bit_index, u16 *pw_bit_data)
3519{
3520 struct hpi_message hm;
3521 struct hpi_response hr;
3522 hpi_init_message_response(&hm, &hr, HPI_OBJ_GPIO, HPI_GPIO_READ_BIT);
3523 u32TOINDEX(h_gpio, &hm.adapter_index);
3524 hm.u.l.bit_index = bit_index;
3525
3526 hpi_send_recv(&hm, &hr);
3527
3528 *pw_bit_data = hr.u.l.bit_data[0];
3529 return hr.error;
3530}
3531
3532u16 hpi_gpio_read_all_bits(const struct hpi_hsubsys *ph_subsys, u32 h_gpio,
3533 u16 aw_all_bit_data[4]
3534 )
3535{
3536 struct hpi_message hm;
3537 struct hpi_response hr;
3538 hpi_init_message_response(&hm, &hr, HPI_OBJ_GPIO, HPI_GPIO_READ_ALL);
3539 u32TOINDEX(h_gpio, &hm.adapter_index);
3540
3541 hpi_send_recv(&hm, &hr);
3542
3543 if (aw_all_bit_data) {
3544 aw_all_bit_data[0] = hr.u.l.bit_data[0];
3545 aw_all_bit_data[1] = hr.u.l.bit_data[1];
3546 aw_all_bit_data[2] = hr.u.l.bit_data[2];
3547 aw_all_bit_data[3] = hr.u.l.bit_data[3];
3548 }
3549 return hr.error;
3550}
3551
3552u16 hpi_gpio_write_bit(const struct hpi_hsubsys *ph_subsys, u32 h_gpio,
3553 u16 bit_index, u16 bit_data)
3554{
3555 struct hpi_message hm;
3556 struct hpi_response hr;
3557 hpi_init_message_response(&hm, &hr, HPI_OBJ_GPIO, HPI_GPIO_WRITE_BIT);
3558 u32TOINDEX(h_gpio, &hm.adapter_index);
3559 hm.u.l.bit_index = bit_index;
3560 hm.u.l.bit_data = bit_data;
3561
3562 hpi_send_recv(&hm, &hr);
3563
3564 return hr.error;
3565}
3566
3567u16 hpi_gpio_write_status(const struct hpi_hsubsys *ph_subsys, u32 h_gpio,
3568 u16 aw_all_bit_data[4]
3569 )
3570{
3571 struct hpi_message hm;
3572 struct hpi_response hr;
3573 hpi_init_message_response(&hm, &hr, HPI_OBJ_GPIO,
3574 HPI_GPIO_WRITE_STATUS);
3575 u32TOINDEX(h_gpio, &hm.adapter_index);
3576
3577 hpi_send_recv(&hm, &hr);
3578
3579 if (aw_all_bit_data) {
3580 aw_all_bit_data[0] = hr.u.l.bit_data[0];
3581 aw_all_bit_data[1] = hr.u.l.bit_data[1];
3582 aw_all_bit_data[2] = hr.u.l.bit_data[2];
3583 aw_all_bit_data[3] = hr.u.l.bit_data[3];
3584 }
3585 return hr.error;
3586}
3587
3588u16 hpi_async_event_open(const struct hpi_hsubsys *ph_subsys,
3589 u16 adapter_index, u32 *ph_async)
3590{
3591 struct hpi_message hm;
3592 struct hpi_response hr;
3593 hpi_init_message_response(&hm, &hr, HPI_OBJ_ASYNCEVENT,
3594 HPI_ASYNCEVENT_OPEN);
3595 hm.adapter_index = adapter_index;
3596
3597 hpi_send_recv(&hm, &hr);
3598
3599 if (hr.error == 0)
3600
3601 *ph_async =
3602 hpi_indexes_to_handle(HPI_OBJ_ASYNCEVENT,
3603 adapter_index, 0);
3604 else
3605 *ph_async = 0;
3606 return hr.error;
3607
3608}
3609
3610u16 hpi_async_event_close(const struct hpi_hsubsys *ph_subsys, u32 h_async)
3611{
3612 struct hpi_message hm;
3613 struct hpi_response hr;
3614 hpi_init_message_response(&hm, &hr, HPI_OBJ_ASYNCEVENT,
3615 HPI_ASYNCEVENT_OPEN);
3616 u32TOINDEX(h_async, &hm.adapter_index);
3617
3618 hpi_send_recv(&hm, &hr);
3619
3620 return hr.error;
3621}
3622
3623u16 hpi_async_event_wait(const struct hpi_hsubsys *ph_subsys, u32 h_async,
3624 u16 maximum_events, struct hpi_async_event *p_events,
3625 u16 *pw_number_returned)
3626{
3627 return 0;
3628}
3629
3630u16 hpi_async_event_get_count(const struct hpi_hsubsys *ph_subsys,
3631 u32 h_async, u16 *pw_count)
3632{
3633 struct hpi_message hm;
3634 struct hpi_response hr;
3635 hpi_init_message_response(&hm, &hr, HPI_OBJ_ASYNCEVENT,
3636 HPI_ASYNCEVENT_GETCOUNT);
3637 u32TOINDEX(h_async, &hm.adapter_index);
3638
3639 hpi_send_recv(&hm, &hr);
3640
3641 if (hr.error == 0)
3642 if (pw_count)
3643 *pw_count = hr.u.as.u.count.count;
3644
3645 return hr.error;
3646}
3647
3648u16 hpi_async_event_get(const struct hpi_hsubsys *ph_subsys, u32 h_async,
3649 u16 maximum_events, struct hpi_async_event *p_events,
3650 u16 *pw_number_returned)
3651{
3652 struct hpi_message hm;
3653 struct hpi_response hr;
3654 hpi_init_message_response(&hm, &hr, HPI_OBJ_ASYNCEVENT,
3655 HPI_ASYNCEVENT_GET);
3656 u32TOINDEX(h_async, &hm.adapter_index);
3657
3658 hpi_send_recv(&hm, &hr);
3659 if (!hr.error) {
3660 memcpy(p_events, &hr.u.as.u.event,
3661 sizeof(struct hpi_async_event));
3662 *pw_number_returned = 1;
3663 }
3664
3665 return hr.error;
3666}
3667
3668u16 hpi_nv_memory_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
3669 u32 *ph_nv_memory, u16 *pw_size_in_bytes)
3670{
3671 struct hpi_message hm;
3672 struct hpi_response hr;
3673 hpi_init_message_response(&hm, &hr, HPI_OBJ_NVMEMORY,
3674 HPI_NVMEMORY_OPEN);
3675 hm.adapter_index = adapter_index;
3676
3677 hpi_send_recv(&hm, &hr);
3678
3679 if (hr.error == 0) {
3680 *ph_nv_memory =
3681 hpi_indexes_to_handle(HPI_OBJ_NVMEMORY, adapter_index,
3682 0);
3683 if (pw_size_in_bytes)
3684 *pw_size_in_bytes = hr.u.n.size_in_bytes;
3685 } else
3686 *ph_nv_memory = 0;
3687 return hr.error;
3688}
3689
3690u16 hpi_nv_memory_read_byte(const struct hpi_hsubsys *ph_subsys,
3691 u32 h_nv_memory, u16 index, u16 *pw_data)
3692{
3693 struct hpi_message hm;
3694 struct hpi_response hr;
3695 hpi_init_message_response(&hm, &hr, HPI_OBJ_NVMEMORY,
3696 HPI_NVMEMORY_READ_BYTE);
3697 u32TOINDEX(h_nv_memory, &hm.adapter_index);
3698 hm.u.n.address = index;
3699
3700 hpi_send_recv(&hm, &hr);
3701
3702 *pw_data = hr.u.n.data;
3703 return hr.error;
3704}
3705
3706u16 hpi_nv_memory_write_byte(const struct hpi_hsubsys *ph_subsys,
3707 u32 h_nv_memory, u16 index, u16 data)
3708{
3709 struct hpi_message hm;
3710 struct hpi_response hr;
3711 hpi_init_message_response(&hm, &hr, HPI_OBJ_NVMEMORY,
3712 HPI_NVMEMORY_WRITE_BYTE);
3713 u32TOINDEX(h_nv_memory, &hm.adapter_index);
3714 hm.u.n.address = index;
3715 hm.u.n.data = data;
3716
3717 hpi_send_recv(&hm, &hr);
3718
3719 return hr.error;
3720}
3721
3722u16 hpi_profile_open_all(const struct hpi_hsubsys *ph_subsys,
3723 u16 adapter_index, u16 profile_index, u32 *ph_profile,
3724 u16 *pw_max_profiles)
3725{
3726 struct hpi_message hm;
3727 struct hpi_response hr;
3728 hpi_init_message_response(&hm, &hr, HPI_OBJ_PROFILE,
3729 HPI_PROFILE_OPEN_ALL);
3730 hm.adapter_index = adapter_index;
3731 hm.obj_index = profile_index;
3732 hpi_send_recv(&hm, &hr);
3733
3734 *pw_max_profiles = hr.u.p.u.o.max_profiles;
3735 if (hr.error == 0)
3736 *ph_profile =
3737 hpi_indexes_to_handle(HPI_OBJ_PROFILE, adapter_index,
3738 profile_index);
3739 else
3740 *ph_profile = 0;
3741 return hr.error;
3742}
3743
3744u16 hpi_profile_get(const struct hpi_hsubsys *ph_subsys, u32 h_profile,
3745 u16 bin_index, u16 *pw_seconds, u32 *pmicro_seconds, u32 *pcall_count,
3746 u32 *pmax_micro_seconds, u32 *pmin_micro_seconds)
3747{
3748 struct hpi_message hm;
3749 struct hpi_response hr;
3750 hpi_init_message_response(&hm, &hr, HPI_OBJ_PROFILE, HPI_PROFILE_GET);
3751 u32TOINDEXES(h_profile, &hm.adapter_index, &hm.obj_index);
3752 hm.u.p.bin_index = bin_index;
3753 hpi_send_recv(&hm, &hr);
3754 if (pw_seconds)
3755 *pw_seconds = hr.u.p.u.t.seconds;
3756 if (pmicro_seconds)
3757 *pmicro_seconds = hr.u.p.u.t.micro_seconds;
3758 if (pcall_count)
3759 *pcall_count = hr.u.p.u.t.call_count;
3760 if (pmax_micro_seconds)
3761 *pmax_micro_seconds = hr.u.p.u.t.max_micro_seconds;
3762 if (pmin_micro_seconds)
3763 *pmin_micro_seconds = hr.u.p.u.t.min_micro_seconds;
3764 return hr.error;
3765}
3766
3767u16 hpi_profile_get_utilization(const struct hpi_hsubsys *ph_subsys,
3768 u32 h_profile, u32 *putilization)
3769{
3770 struct hpi_message hm;
3771 struct hpi_response hr;
3772 hpi_init_message_response(&hm, &hr, HPI_OBJ_PROFILE,
3773 HPI_PROFILE_GET_UTILIZATION);
3774 u32TOINDEXES(h_profile, &hm.adapter_index, &hm.obj_index);
3775 hpi_send_recv(&hm, &hr);
3776 if (hr.error) {
3777 if (putilization)
3778 *putilization = 0;
3779 } else {
3780 if (putilization)
3781 *putilization = hr.u.p.u.t.call_count;
3782 }
3783 return hr.error;
3784}
3785
3786u16 hpi_profile_get_name(const struct hpi_hsubsys *ph_subsys, u32 h_profile,
3787 u16 bin_index, char *sz_name, u16 name_length)
3788{
3789 struct hpi_message hm;
3790 struct hpi_response hr;
3791 hpi_init_message_response(&hm, &hr, HPI_OBJ_PROFILE,
3792 HPI_PROFILE_GET_NAME);
3793 u32TOINDEXES(h_profile, &hm.adapter_index, &hm.obj_index);
3794 hm.u.p.bin_index = bin_index;
3795 hpi_send_recv(&hm, &hr);
3796 if (hr.error) {
3797 if (sz_name)
3798 strcpy(sz_name, "??");
3799 } else {
3800 if (sz_name)
3801 memcpy(sz_name, (char *)hr.u.p.u.n.sz_name,
3802 name_length);
3803 }
3804 return hr.error;
3805}
3806
3807u16 hpi_profile_start_all(const struct hpi_hsubsys *ph_subsys, u32 h_profile)
3808{
3809 struct hpi_message hm;
3810 struct hpi_response hr;
3811 hpi_init_message_response(&hm, &hr, HPI_OBJ_PROFILE,
3812 HPI_PROFILE_START_ALL);
3813 u32TOINDEXES(h_profile, &hm.adapter_index, &hm.obj_index);
3814 hpi_send_recv(&hm, &hr);
3815
3816 return hr.error;
3817}
3818
3819u16 hpi_profile_stop_all(const struct hpi_hsubsys *ph_subsys, u32 h_profile)
3820{
3821 struct hpi_message hm;
3822 struct hpi_response hr;
3823 hpi_init_message_response(&hm, &hr, HPI_OBJ_PROFILE,
3824 HPI_PROFILE_STOP_ALL);
3825 u32TOINDEXES(h_profile, &hm.adapter_index, &hm.obj_index);
3826 hpi_send_recv(&hm, &hr);
3827
3828 return hr.error;
3829}
3830
3831u16 hpi_watchdog_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
3832 u32 *ph_watchdog)
3833{
3834 struct hpi_message hm;
3835 struct hpi_response hr;
3836 hpi_init_message_response(&hm, &hr, HPI_OBJ_WATCHDOG,
3837 HPI_WATCHDOG_OPEN);
3838 hm.adapter_index = adapter_index;
3839
3840 hpi_send_recv(&hm, &hr);
3841
3842 if (hr.error == 0)
3843 *ph_watchdog =
3844 hpi_indexes_to_handle(HPI_OBJ_WATCHDOG, adapter_index,
3845 0);
3846 else
3847 *ph_watchdog = 0;
3848 return hr.error;
3849}
3850
3851u16 hpi_watchdog_set_time(const struct hpi_hsubsys *ph_subsys, u32 h_watchdog,
3852 u32 time_millisec)
3853{
3854 struct hpi_message hm;
3855 struct hpi_response hr;
3856 hpi_init_message_response(&hm, &hr, HPI_OBJ_WATCHDOG,
3857 HPI_WATCHDOG_SET_TIME);
3858 u32TOINDEX(h_watchdog, &hm.adapter_index);
3859 hm.u.w.time_ms = time_millisec;
3860
3861 hpi_send_recv(&hm, &hr);
3862
3863 return hr.error;
3864}
3865
3866u16 hpi_watchdog_ping(const struct hpi_hsubsys *ph_subsys, u32 h_watchdog)
3867{
3868 struct hpi_message hm;
3869 struct hpi_response hr;
3870 hpi_init_message_response(&hm, &hr, HPI_OBJ_WATCHDOG,
3871 HPI_WATCHDOG_PING);
3872 u32TOINDEX(h_watchdog, &hm.adapter_index);
3873
3874 hpi_send_recv(&hm, &hr);
3875
3876 return hr.error;
3877}
diff --git a/sound/pci/asihpi/hpimsginit.c b/sound/pci/asihpi/hpimsginit.c
new file mode 100644
index 000000000000..8e1d099ed7e4
--- /dev/null
+++ b/sound/pci/asihpi/hpimsginit.c
@@ -0,0 +1,130 @@
1/******************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
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, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19 Hardware Programming Interface (HPI) Utility functions.
20
21 (C) Copyright AudioScience Inc. 2007
22*******************************************************************************/
23
24#include "hpi_internal.h"
25#include "hpimsginit.h"
26
27/* The actual message size for each object type */
28static u16 msg_size[HPI_OBJ_MAXINDEX + 1] = HPI_MESSAGE_SIZE_BY_OBJECT;
29/* The actual response size for each object type */
30static u16 res_size[HPI_OBJ_MAXINDEX + 1] = HPI_RESPONSE_SIZE_BY_OBJECT;
31/* Flag to enable alternate message type for SSX2 bypass. */
32static u16 gwSSX2_bypass;
33
34/** \internal
35 * Used by ASIO driver to disable SSX2 for a single process
36 * \param phSubSys Pointer to HPI subsystem handle.
37 * \param wBypass New bypass setting 0 = off, nonzero = on
38 * \return Previous bypass setting.
39 */
40u16 hpi_subsys_ssx2_bypass(const struct hpi_hsubsys *ph_subsys, u16 bypass)
41{
42 u16 old_value = gwSSX2_bypass;
43
44 gwSSX2_bypass = bypass;
45
46 return old_value;
47}
48
49/** \internal
50 * initialize the HPI message structure
51 */
52static void hpi_init_message(struct hpi_message *phm, u16 object,
53 u16 function)
54{
55 memset(phm, 0, sizeof(*phm));
56 if ((object > 0) && (object <= HPI_OBJ_MAXINDEX))
57 phm->size = msg_size[object];
58 else
59 phm->size = sizeof(*phm);
60
61 if (gwSSX2_bypass)
62 phm->type = HPI_TYPE_SSX2BYPASS_MESSAGE;
63 else
64 phm->type = HPI_TYPE_MESSAGE;
65 phm->object = object;
66 phm->function = function;
67 phm->version = 0;
68 /* Expect adapter index to be set by caller */
69}
70
71/** \internal
72 * initialize the HPI response structure
73 */
74void hpi_init_response(struct hpi_response *phr, u16 object, u16 function,
75 u16 error)
76{
77 memset(phr, 0, sizeof(*phr));
78 phr->type = HPI_TYPE_RESPONSE;
79 if ((object > 0) && (object <= HPI_OBJ_MAXINDEX))
80 phr->size = res_size[object];
81 else
82 phr->size = sizeof(*phr);
83 phr->object = object;
84 phr->function = function;
85 phr->error = error;
86 phr->specific_error = 0;
87 phr->version = 0;
88}
89
90void hpi_init_message_response(struct hpi_message *phm,
91 struct hpi_response *phr, u16 object, u16 function)
92{
93 hpi_init_message(phm, object, function);
94 /* default error return if the response is
95 not filled in by the callee */
96 hpi_init_response(phr, object, function,
97 HPI_ERROR_PROCESSING_MESSAGE);
98}
99
100static void hpi_init_messageV1(struct hpi_message_header *phm, u16 size,
101 u16 object, u16 function)
102{
103 memset(phm, 0, sizeof(*phm));
104 if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) {
105 phm->size = size;
106 phm->type = HPI_TYPE_MESSAGE;
107 phm->object = object;
108 phm->function = function;
109 phm->version = 1;
110 /* Expect adapter index to be set by caller */
111 }
112}
113
114void hpi_init_responseV1(struct hpi_response_header *phr, u16 size,
115 u16 object, u16 function)
116{
117 memset(phr, 0, sizeof(*phr));
118 phr->size = size;
119 phr->version = 1;
120 phr->type = HPI_TYPE_RESPONSE;
121 phr->error = HPI_ERROR_PROCESSING_MESSAGE;
122}
123
124void hpi_init_message_responseV1(struct hpi_message_header *phm, u16 msg_size,
125 struct hpi_response_header *phr, u16 res_size, u16 object,
126 u16 function)
127{
128 hpi_init_messageV1(phm, msg_size, object, function);
129 hpi_init_responseV1(phr, res_size, object, function);
130}
diff --git a/sound/pci/asihpi/hpimsginit.h b/sound/pci/asihpi/hpimsginit.h
new file mode 100644
index 000000000000..864ad020c9b3
--- /dev/null
+++ b/sound/pci/asihpi/hpimsginit.h
@@ -0,0 +1,40 @@
1/******************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
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, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19 Hardware Programming Interface (HPI) Utility functions
20
21 (C) Copyright AudioScience Inc. 2007
22*******************************************************************************/
23/* Initialise response headers, or msg/response pairs.
24Note that it is valid to just init a response e.g. when a lower level is preparing
25a response to a message.
26However, when sending a message, a matching response buffer always must be prepared
27*/
28
29void hpi_init_response(struct hpi_response *phr, u16 object, u16 function,
30 u16 error);
31
32void hpi_init_message_response(struct hpi_message *phm,
33 struct hpi_response *phr, u16 object, u16 function);
34
35void hpi_init_responseV1(struct hpi_response_header *phr, u16 size,
36 u16 object, u16 function);
37
38void hpi_init_message_responseV1(struct hpi_message_header *phm, u16 msg_size,
39 struct hpi_response_header *phr, u16 res_size, u16 object,
40 u16 function);
diff --git a/sound/pci/asihpi/hpimsgx.c b/sound/pci/asihpi/hpimsgx.c
new file mode 100644
index 000000000000..2ee90dc3d897
--- /dev/null
+++ b/sound/pci/asihpi/hpimsgx.c
@@ -0,0 +1,907 @@
1/******************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
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, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19Extended Message Function With Response Cacheing
20
21(C) Copyright AudioScience Inc. 2002
22*****************************************************************************/
23#define SOURCEFILE_NAME "hpimsgx.c"
24#include "hpi_internal.h"
25#include "hpimsginit.h"
26#include "hpimsgx.h"
27#include "hpidebug.h"
28
29static struct pci_device_id asihpi_pci_tbl[] = {
30#include "hpipcida.h"
31};
32
33static struct hpios_spinlock msgx_lock;
34
35static hpi_handler_func *hpi_entry_points[HPI_MAX_ADAPTERS];
36
37static hpi_handler_func *hpi_lookup_entry_point_function(const struct hpi_pci
38 *pci_info)
39{
40
41 int i;
42
43 for (i = 0; asihpi_pci_tbl[i].vendor != 0; i++) {
44 if (asihpi_pci_tbl[i].vendor != PCI_ANY_ID
45 && asihpi_pci_tbl[i].vendor != pci_info->vendor_id)
46 continue;
47 if (asihpi_pci_tbl[i].device != PCI_ANY_ID
48 && asihpi_pci_tbl[i].device != pci_info->device_id)
49 continue;
50 if (asihpi_pci_tbl[i].subvendor != PCI_ANY_ID
51 && asihpi_pci_tbl[i].subvendor !=
52 pci_info->subsys_vendor_id)
53 continue;
54 if (asihpi_pci_tbl[i].subdevice != PCI_ANY_ID
55 && asihpi_pci_tbl[i].subdevice !=
56 pci_info->subsys_device_id)
57 continue;
58
59 HPI_DEBUG_LOG(DEBUG, " %x,%lu\n", i,
60 asihpi_pci_tbl[i].driver_data);
61 return (hpi_handler_func *) asihpi_pci_tbl[i].driver_data;
62 }
63
64 return NULL;
65}
66
67static inline void hw_entry_point(struct hpi_message *phm,
68 struct hpi_response *phr)
69{
70
71 hpi_handler_func *ep;
72
73 if (phm->adapter_index < HPI_MAX_ADAPTERS) {
74 ep = (hpi_handler_func *) hpi_entry_points[phm->
75 adapter_index];
76 if (ep) {
77 HPI_DEBUG_MESSAGE(DEBUG, phm);
78 ep(phm, phr);
79 HPI_DEBUG_RESPONSE(phr);
80 return;
81 }
82 }
83 hpi_init_response(phr, phm->object, phm->function,
84 HPI_ERROR_PROCESSING_MESSAGE);
85}
86
87static void adapter_open(struct hpi_message *phm, struct hpi_response *phr);
88static void adapter_close(struct hpi_message *phm, struct hpi_response *phr);
89
90static void mixer_open(struct hpi_message *phm, struct hpi_response *phr);
91static void mixer_close(struct hpi_message *phm, struct hpi_response *phr);
92
93static void outstream_open(struct hpi_message *phm, struct hpi_response *phr,
94 void *h_owner);
95static void outstream_close(struct hpi_message *phm, struct hpi_response *phr,
96 void *h_owner);
97static void instream_open(struct hpi_message *phm, struct hpi_response *phr,
98 void *h_owner);
99static void instream_close(struct hpi_message *phm, struct hpi_response *phr,
100 void *h_owner);
101
102static void HPIMSGX__reset(u16 adapter_index);
103static u16 HPIMSGX__init(struct hpi_message *phm, struct hpi_response *phr);
104static void HPIMSGX__cleanup(u16 adapter_index, void *h_owner);
105
106#ifndef DISABLE_PRAGMA_PACK1
107#pragma pack(push, 1)
108#endif
109
110struct hpi_subsys_response {
111 struct hpi_response_header h;
112 struct hpi_subsys_res s;
113};
114
115struct hpi_adapter_response {
116 struct hpi_response_header h;
117 struct hpi_adapter_res a;
118};
119
120struct hpi_mixer_response {
121 struct hpi_response_header h;
122 struct hpi_mixer_res m;
123};
124
125struct hpi_stream_response {
126 struct hpi_response_header h;
127 struct hpi_stream_res d;
128};
129
130struct adapter_info {
131 u16 type;
132 u16 num_instreams;
133 u16 num_outstreams;
134};
135
136struct asi_open_state {
137 int open_flag;
138 void *h_owner;
139};
140
141#ifndef DISABLE_PRAGMA_PACK1
142#pragma pack(pop)
143#endif
144
145/* Globals */
146static struct hpi_adapter_response rESP_HPI_ADAPTER_OPEN[HPI_MAX_ADAPTERS];
147
148static struct hpi_stream_response
149 rESP_HPI_OSTREAM_OPEN[HPI_MAX_ADAPTERS][HPI_MAX_STREAMS];
150
151static struct hpi_stream_response
152 rESP_HPI_ISTREAM_OPEN[HPI_MAX_ADAPTERS][HPI_MAX_STREAMS];
153
154static struct hpi_mixer_response rESP_HPI_MIXER_OPEN[HPI_MAX_ADAPTERS];
155
156static struct hpi_subsys_response gRESP_HPI_SUBSYS_FIND_ADAPTERS;
157
158static struct adapter_info aDAPTER_INFO[HPI_MAX_ADAPTERS];
159
160/* use these to keep track of opens from user mode apps/DLLs */
161static struct asi_open_state
162 outstream_user_open[HPI_MAX_ADAPTERS][HPI_MAX_STREAMS];
163
164static struct asi_open_state
165 instream_user_open[HPI_MAX_ADAPTERS][HPI_MAX_STREAMS];
166
167static void subsys_message(struct hpi_message *phm, struct hpi_response *phr,
168 void *h_owner)
169{
170 switch (phm->function) {
171 case HPI_SUBSYS_GET_VERSION:
172 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM,
173 HPI_SUBSYS_GET_VERSION, 0);
174 phr->u.s.version = HPI_VER >> 8; /* return major.minor */
175 phr->u.s.data = HPI_VER; /* return major.minor.release */
176 break;
177 case HPI_SUBSYS_OPEN:
178 /*do not propagate the message down the chain */
179 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, HPI_SUBSYS_OPEN, 0);
180 break;
181 case HPI_SUBSYS_CLOSE:
182 /*do not propagate the message down the chain */
183 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, HPI_SUBSYS_CLOSE,
184 0);
185 HPIMSGX__cleanup(HPIMSGX_ALLADAPTERS, h_owner);
186 break;
187 case HPI_SUBSYS_DRIVER_LOAD:
188 /* Initialize this module's internal state */
189 hpios_msgxlock_init(&msgx_lock);
190 memset(&hpi_entry_points, 0, sizeof(hpi_entry_points));
191 hpios_locked_mem_init();
192 /* Init subsys_findadapters response to no-adapters */
193 HPIMSGX__reset(HPIMSGX_ALLADAPTERS);
194 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM,
195 HPI_SUBSYS_DRIVER_LOAD, 0);
196 /* individual HPIs dont implement driver load */
197 HPI_COMMON(phm, phr);
198 break;
199 case HPI_SUBSYS_DRIVER_UNLOAD:
200 HPI_COMMON(phm, phr);
201 HPIMSGX__cleanup(HPIMSGX_ALLADAPTERS, h_owner);
202 hpios_locked_mem_free_all();
203 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM,
204 HPI_SUBSYS_DRIVER_UNLOAD, 0);
205 return;
206
207 case HPI_SUBSYS_GET_INFO:
208 HPI_COMMON(phm, phr);
209 break;
210
211 case HPI_SUBSYS_FIND_ADAPTERS:
212 memcpy(phr, &gRESP_HPI_SUBSYS_FIND_ADAPTERS,
213 sizeof(gRESP_HPI_SUBSYS_FIND_ADAPTERS));
214 break;
215 case HPI_SUBSYS_GET_NUM_ADAPTERS:
216 memcpy(phr, &gRESP_HPI_SUBSYS_FIND_ADAPTERS,
217 sizeof(gRESP_HPI_SUBSYS_FIND_ADAPTERS));
218 phr->function = HPI_SUBSYS_GET_NUM_ADAPTERS;
219 break;
220 case HPI_SUBSYS_GET_ADAPTER:
221 {
222 int count = phm->adapter_index;
223 int index = 0;
224 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM,
225 HPI_SUBSYS_GET_ADAPTER, 0);
226
227 /* This is complicated by the fact that we want to
228 * "skip" 0's in the adapter list.
229 * First, make sure we are pointing to a
230 * non-zero adapter type.
231 */
232 while (gRESP_HPI_SUBSYS_FIND_ADAPTERS.
233 s.aw_adapter_list[index] == 0) {
234 index++;
235 if (index >= HPI_MAX_ADAPTERS)
236 break;
237 }
238 while (count) {
239 /* move on to the next adapter */
240 index++;
241 if (index >= HPI_MAX_ADAPTERS)
242 break;
243 while (gRESP_HPI_SUBSYS_FIND_ADAPTERS.
244 s.aw_adapter_list[index] == 0) {
245 index++;
246 if (index >= HPI_MAX_ADAPTERS)
247 break;
248 }
249 count--;
250 }
251
252 if (index < HPI_MAX_ADAPTERS) {
253 phr->u.s.adapter_index = (u16)index;
254 phr->u.s.aw_adapter_list[0] =
255 gRESP_HPI_SUBSYS_FIND_ADAPTERS.
256 s.aw_adapter_list[index];
257 } else {
258 phr->u.s.adapter_index = 0;
259 phr->u.s.aw_adapter_list[0] = 0;
260 phr->error = HPI_ERROR_BAD_ADAPTER_NUMBER;
261 }
262 break;
263 }
264 case HPI_SUBSYS_CREATE_ADAPTER:
265 HPIMSGX__init(phm, phr);
266 break;
267 case HPI_SUBSYS_DELETE_ADAPTER:
268 HPIMSGX__cleanup(phm->adapter_index, h_owner);
269 {
270 struct hpi_message hm;
271 struct hpi_response hr;
272 /* call to HPI_ADAPTER_CLOSE */
273 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
274 HPI_ADAPTER_CLOSE);
275 hm.adapter_index = phm->adapter_index;
276 hw_entry_point(&hm, &hr);
277 }
278 hw_entry_point(phm, phr);
279 gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.
280 aw_adapter_list[phm->adapter_index]
281 = 0;
282 hpi_entry_points[phm->adapter_index] = NULL;
283 break;
284 default:
285 hw_entry_point(phm, phr);
286 break;
287 }
288}
289
290static void adapter_message(struct hpi_message *phm, struct hpi_response *phr,
291 void *h_owner)
292{
293 switch (phm->function) {
294 case HPI_ADAPTER_OPEN:
295 adapter_open(phm, phr);
296 break;
297 case HPI_ADAPTER_CLOSE:
298 adapter_close(phm, phr);
299 break;
300 default:
301 hw_entry_point(phm, phr);
302 break;
303 }
304}
305
306static void mixer_message(struct hpi_message *phm, struct hpi_response *phr)
307{
308 switch (phm->function) {
309 case HPI_MIXER_OPEN:
310 mixer_open(phm, phr);
311 break;
312 case HPI_MIXER_CLOSE:
313 mixer_close(phm, phr);
314 break;
315 default:
316 hw_entry_point(phm, phr);
317 break;
318 }
319}
320
321static void outstream_message(struct hpi_message *phm,
322 struct hpi_response *phr, void *h_owner)
323{
324 if (phm->obj_index >= aDAPTER_INFO[phm->adapter_index].num_outstreams) {
325 hpi_init_response(phr, HPI_OBJ_OSTREAM, phm->function,
326 HPI_ERROR_INVALID_OBJ_INDEX);
327 return;
328 }
329
330 switch (phm->function) {
331 case HPI_OSTREAM_OPEN:
332 outstream_open(phm, phr, h_owner);
333 break;
334 case HPI_OSTREAM_CLOSE:
335 outstream_close(phm, phr, h_owner);
336 break;
337 default:
338 hw_entry_point(phm, phr);
339 break;
340 }
341}
342
343static void instream_message(struct hpi_message *phm,
344 struct hpi_response *phr, void *h_owner)
345{
346 if (phm->obj_index >= aDAPTER_INFO[phm->adapter_index].num_instreams) {
347 hpi_init_response(phr, HPI_OBJ_ISTREAM, phm->function,
348 HPI_ERROR_INVALID_OBJ_INDEX);
349 return;
350 }
351
352 switch (phm->function) {
353 case HPI_ISTREAM_OPEN:
354 instream_open(phm, phr, h_owner);
355 break;
356 case HPI_ISTREAM_CLOSE:
357 instream_close(phm, phr, h_owner);
358 break;
359 default:
360 hw_entry_point(phm, phr);
361 break;
362 }
363}
364
365/* NOTE: HPI_Message() must be defined in the driver as a wrapper for
366 * HPI_MessageEx so that functions in hpifunc.c compile.
367 */
368void hpi_send_recv_ex(struct hpi_message *phm, struct hpi_response *phr,
369 void *h_owner)
370{
371 HPI_DEBUG_MESSAGE(DEBUG, phm);
372
373 if (phm->type != HPI_TYPE_MESSAGE) {
374 hpi_init_response(phr, phm->object, phm->function,
375 HPI_ERROR_INVALID_TYPE);
376 return;
377 }
378
379 if (phm->adapter_index >= HPI_MAX_ADAPTERS
380 && phm->adapter_index != HPIMSGX_ALLADAPTERS) {
381 hpi_init_response(phr, phm->object, phm->function,
382 HPI_ERROR_BAD_ADAPTER_NUMBER);
383 return;
384 }
385
386 switch (phm->object) {
387 case HPI_OBJ_SUBSYSTEM:
388 subsys_message(phm, phr, h_owner);
389 break;
390
391 case HPI_OBJ_ADAPTER:
392 adapter_message(phm, phr, h_owner);
393 break;
394
395 case HPI_OBJ_MIXER:
396 mixer_message(phm, phr);
397 break;
398
399 case HPI_OBJ_OSTREAM:
400 outstream_message(phm, phr, h_owner);
401 break;
402
403 case HPI_OBJ_ISTREAM:
404 instream_message(phm, phr, h_owner);
405 break;
406
407 default:
408 hw_entry_point(phm, phr);
409 break;
410 }
411 HPI_DEBUG_RESPONSE(phr);
412#if 1
413 if (phr->error >= HPI_ERROR_BACKEND_BASE) {
414 void *ep = NULL;
415 char *ep_name;
416
417 HPI_DEBUG_MESSAGE(ERROR, phm);
418
419 if (phm->adapter_index < HPI_MAX_ADAPTERS)
420 ep = hpi_entry_points[phm->adapter_index];
421
422 /* Don't need this? Have adapter index in debug info
423 Know at driver load time index->backend mapping */
424 if (ep == HPI_6000)
425 ep_name = "HPI_6000";
426 else if (ep == HPI_6205)
427 ep_name = "HPI_6205";
428 else
429 ep_name = "unknown";
430
431 HPI_DEBUG_LOG(ERROR, "HPI %s response - error# %d\n", ep_name,
432 phr->error);
433
434 if (hpi_debug_level >= HPI_DEBUG_LEVEL_VERBOSE)
435 hpi_debug_data((u16 *)phm,
436 sizeof(*phm) / sizeof(u16));
437 }
438#endif
439}
440
441static void adapter_open(struct hpi_message *phm, struct hpi_response *phr)
442{
443 HPI_DEBUG_LOG(VERBOSE, "adapter_open\n");
444 memcpy(phr, &rESP_HPI_ADAPTER_OPEN[phm->adapter_index],
445 sizeof(rESP_HPI_ADAPTER_OPEN[0]));
446}
447
448static void adapter_close(struct hpi_message *phm, struct hpi_response *phr)
449{
450 HPI_DEBUG_LOG(VERBOSE, "adapter_close\n");
451 hpi_init_response(phr, HPI_OBJ_ADAPTER, HPI_ADAPTER_CLOSE, 0);
452}
453
454static void mixer_open(struct hpi_message *phm, struct hpi_response *phr)
455{
456 memcpy(phr, &rESP_HPI_MIXER_OPEN[phm->adapter_index],
457 sizeof(rESP_HPI_MIXER_OPEN[0]));
458}
459
460static void mixer_close(struct hpi_message *phm, struct hpi_response *phr)
461{
462 hpi_init_response(phr, HPI_OBJ_MIXER, HPI_MIXER_CLOSE, 0);
463}
464
465static void instream_open(struct hpi_message *phm, struct hpi_response *phr,
466 void *h_owner)
467{
468
469 struct hpi_message hm;
470 struct hpi_response hr;
471
472 hpi_init_response(phr, HPI_OBJ_ISTREAM, HPI_ISTREAM_OPEN, 0);
473
474 hpios_msgxlock_lock(&msgx_lock);
475
476 if (instream_user_open[phm->adapter_index][phm->obj_index].open_flag)
477 phr->error = HPI_ERROR_OBJ_ALREADY_OPEN;
478 else if (rESP_HPI_ISTREAM_OPEN[phm->adapter_index]
479 [phm->obj_index].h.error)
480 memcpy(phr,
481 &rESP_HPI_ISTREAM_OPEN[phm->adapter_index][phm->
482 obj_index],
483 sizeof(rESP_HPI_ISTREAM_OPEN[0][0]));
484 else {
485 instream_user_open[phm->adapter_index][phm->
486 obj_index].open_flag = 1;
487 hpios_msgxlock_un_lock(&msgx_lock);
488
489 /* issue a reset */
490 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
491 HPI_ISTREAM_RESET);
492 hm.adapter_index = phm->adapter_index;
493 hm.obj_index = phm->obj_index;
494 hw_entry_point(&hm, &hr);
495
496 hpios_msgxlock_lock(&msgx_lock);
497 if (hr.error) {
498 instream_user_open[phm->adapter_index][phm->
499 obj_index].open_flag = 0;
500 phr->error = hr.error;
501 } else {
502 instream_user_open[phm->adapter_index][phm->
503 obj_index].open_flag = 1;
504 instream_user_open[phm->adapter_index][phm->
505 obj_index].h_owner = h_owner;
506 memcpy(phr,
507 &rESP_HPI_ISTREAM_OPEN[phm->adapter_index]
508 [phm->obj_index],
509 sizeof(rESP_HPI_ISTREAM_OPEN[0][0]));
510 }
511 }
512 hpios_msgxlock_un_lock(&msgx_lock);
513}
514
515static void instream_close(struct hpi_message *phm, struct hpi_response *phr,
516 void *h_owner)
517{
518
519 struct hpi_message hm;
520 struct hpi_response hr;
521
522 hpi_init_response(phr, HPI_OBJ_ISTREAM, HPI_ISTREAM_CLOSE, 0);
523
524 hpios_msgxlock_lock(&msgx_lock);
525 if (h_owner ==
526 instream_user_open[phm->adapter_index][phm->
527 obj_index].h_owner) {
528 /* HPI_DEBUG_LOG(INFO,"closing adapter %d "
529 "instream %d owned by %p\n",
530 phm->wAdapterIndex, phm->wObjIndex, hOwner); */
531 instream_user_open[phm->adapter_index][phm->
532 obj_index].h_owner = NULL;
533 hpios_msgxlock_un_lock(&msgx_lock);
534 /* issue a reset */
535 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
536 HPI_ISTREAM_RESET);
537 hm.adapter_index = phm->adapter_index;
538 hm.obj_index = phm->obj_index;
539 hw_entry_point(&hm, &hr);
540 hpios_msgxlock_lock(&msgx_lock);
541 if (hr.error) {
542 instream_user_open[phm->adapter_index][phm->
543 obj_index].h_owner = h_owner;
544 phr->error = hr.error;
545 } else {
546 instream_user_open[phm->adapter_index][phm->
547 obj_index].open_flag = 0;
548 instream_user_open[phm->adapter_index][phm->
549 obj_index].h_owner = NULL;
550 }
551 } else {
552 HPI_DEBUG_LOG(WARNING,
553 "%p trying to close %d instream %d owned by %p\n",
554 h_owner, phm->adapter_index, phm->obj_index,
555 instream_user_open[phm->adapter_index][phm->
556 obj_index].h_owner);
557 phr->error = HPI_ERROR_OBJ_NOT_OPEN;
558 }
559 hpios_msgxlock_un_lock(&msgx_lock);
560}
561
562static void outstream_open(struct hpi_message *phm, struct hpi_response *phr,
563 void *h_owner)
564{
565
566 struct hpi_message hm;
567 struct hpi_response hr;
568
569 hpi_init_response(phr, HPI_OBJ_OSTREAM, HPI_OSTREAM_OPEN, 0);
570
571 hpios_msgxlock_lock(&msgx_lock);
572
573 if (outstream_user_open[phm->adapter_index][phm->obj_index].open_flag)
574 phr->error = HPI_ERROR_OBJ_ALREADY_OPEN;
575 else if (rESP_HPI_OSTREAM_OPEN[phm->adapter_index]
576 [phm->obj_index].h.error)
577 memcpy(phr,
578 &rESP_HPI_OSTREAM_OPEN[phm->adapter_index][phm->
579 obj_index],
580 sizeof(rESP_HPI_OSTREAM_OPEN[0][0]));
581 else {
582 outstream_user_open[phm->adapter_index][phm->
583 obj_index].open_flag = 1;
584 hpios_msgxlock_un_lock(&msgx_lock);
585
586 /* issue a reset */
587 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
588 HPI_OSTREAM_RESET);
589 hm.adapter_index = phm->adapter_index;
590 hm.obj_index = phm->obj_index;
591 hw_entry_point(&hm, &hr);
592
593 hpios_msgxlock_lock(&msgx_lock);
594 if (hr.error) {
595 outstream_user_open[phm->adapter_index][phm->
596 obj_index].open_flag = 0;
597 phr->error = hr.error;
598 } else {
599 outstream_user_open[phm->adapter_index][phm->
600 obj_index].open_flag = 1;
601 outstream_user_open[phm->adapter_index][phm->
602 obj_index].h_owner = h_owner;
603 memcpy(phr,
604 &rESP_HPI_OSTREAM_OPEN[phm->adapter_index]
605 [phm->obj_index],
606 sizeof(rESP_HPI_OSTREAM_OPEN[0][0]));
607 }
608 }
609 hpios_msgxlock_un_lock(&msgx_lock);
610}
611
612static void outstream_close(struct hpi_message *phm, struct hpi_response *phr,
613 void *h_owner)
614{
615
616 struct hpi_message hm;
617 struct hpi_response hr;
618
619 hpi_init_response(phr, HPI_OBJ_OSTREAM, HPI_OSTREAM_CLOSE, 0);
620
621 hpios_msgxlock_lock(&msgx_lock);
622
623 if (h_owner ==
624 outstream_user_open[phm->adapter_index][phm->
625 obj_index].h_owner) {
626 /* HPI_DEBUG_LOG(INFO,"closing adapter %d "
627 "outstream %d owned by %p\n",
628 phm->wAdapterIndex, phm->wObjIndex, hOwner); */
629 outstream_user_open[phm->adapter_index][phm->
630 obj_index].h_owner = NULL;
631 hpios_msgxlock_un_lock(&msgx_lock);
632 /* issue a reset */
633 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
634 HPI_OSTREAM_RESET);
635 hm.adapter_index = phm->adapter_index;
636 hm.obj_index = phm->obj_index;
637 hw_entry_point(&hm, &hr);
638 hpios_msgxlock_lock(&msgx_lock);
639 if (hr.error) {
640 outstream_user_open[phm->adapter_index][phm->
641 obj_index].h_owner = h_owner;
642 phr->error = hr.error;
643 } else {
644 outstream_user_open[phm->adapter_index][phm->
645 obj_index].open_flag = 0;
646 outstream_user_open[phm->adapter_index][phm->
647 obj_index].h_owner = NULL;
648 }
649 } else {
650 HPI_DEBUG_LOG(WARNING,
651 "%p trying to close %d outstream %d owned by %p\n",
652 h_owner, phm->adapter_index, phm->obj_index,
653 outstream_user_open[phm->adapter_index][phm->
654 obj_index].h_owner);
655 phr->error = HPI_ERROR_OBJ_NOT_OPEN;
656 }
657 hpios_msgxlock_un_lock(&msgx_lock);
658}
659
660static u16 adapter_prepare(u16 adapter)
661{
662 struct hpi_message hm;
663 struct hpi_response hr;
664
665 /* Open the adapter and streams */
666 u16 i;
667
668 /* call to HPI_ADAPTER_OPEN */
669 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
670 HPI_ADAPTER_OPEN);
671 hm.adapter_index = adapter;
672 hw_entry_point(&hm, &hr);
673 memcpy(&rESP_HPI_ADAPTER_OPEN[adapter], &hr,
674 sizeof(rESP_HPI_ADAPTER_OPEN[0]));
675 if (hr.error)
676 return hr.error;
677
678 /* call to HPI_ADAPTER_GET_INFO */
679 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
680 HPI_ADAPTER_GET_INFO);
681 hm.adapter_index = adapter;
682 hw_entry_point(&hm, &hr);
683 if (hr.error)
684 return hr.error;
685
686 aDAPTER_INFO[adapter].num_outstreams = hr.u.a.num_outstreams;
687 aDAPTER_INFO[adapter].num_instreams = hr.u.a.num_instreams;
688 aDAPTER_INFO[adapter].type = hr.u.a.adapter_type;
689
690 gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.aw_adapter_list[adapter] =
691 hr.u.a.adapter_type;
692 gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.num_adapters++;
693 if (gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.num_adapters > HPI_MAX_ADAPTERS)
694 gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.num_adapters =
695 HPI_MAX_ADAPTERS;
696
697 /* call to HPI_OSTREAM_OPEN */
698 for (i = 0; i < aDAPTER_INFO[adapter].num_outstreams; i++) {
699 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
700 HPI_OSTREAM_OPEN);
701 hm.adapter_index = adapter;
702 hm.obj_index = i;
703 hw_entry_point(&hm, &hr);
704 memcpy(&rESP_HPI_OSTREAM_OPEN[adapter][i], &hr,
705 sizeof(rESP_HPI_OSTREAM_OPEN[0][0]));
706 outstream_user_open[adapter][i].open_flag = 0;
707 outstream_user_open[adapter][i].h_owner = NULL;
708 }
709
710 /* call to HPI_ISTREAM_OPEN */
711 for (i = 0; i < aDAPTER_INFO[adapter].num_instreams; i++) {
712 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
713 HPI_ISTREAM_OPEN);
714 hm.adapter_index = adapter;
715 hm.obj_index = i;
716 hw_entry_point(&hm, &hr);
717 memcpy(&rESP_HPI_ISTREAM_OPEN[adapter][i], &hr,
718 sizeof(rESP_HPI_ISTREAM_OPEN[0][0]));
719 instream_user_open[adapter][i].open_flag = 0;
720 instream_user_open[adapter][i].h_owner = NULL;
721 }
722
723 /* call to HPI_MIXER_OPEN */
724 hpi_init_message_response(&hm, &hr, HPI_OBJ_MIXER, HPI_MIXER_OPEN);
725 hm.adapter_index = adapter;
726 hw_entry_point(&hm, &hr);
727 memcpy(&rESP_HPI_MIXER_OPEN[adapter], &hr,
728 sizeof(rESP_HPI_MIXER_OPEN[0]));
729
730 return gRESP_HPI_SUBSYS_FIND_ADAPTERS.h.error;
731}
732
733static void HPIMSGX__reset(u16 adapter_index)
734{
735 int i;
736 u16 adapter;
737 struct hpi_response hr;
738
739 if (adapter_index == HPIMSGX_ALLADAPTERS) {
740 /* reset all responses to contain errors */
741 hpi_init_response(&hr, HPI_OBJ_SUBSYSTEM,
742 HPI_SUBSYS_FIND_ADAPTERS, 0);
743 memcpy(&gRESP_HPI_SUBSYS_FIND_ADAPTERS, &hr,
744 sizeof(&gRESP_HPI_SUBSYS_FIND_ADAPTERS));
745
746 for (adapter = 0; adapter < HPI_MAX_ADAPTERS; adapter++) {
747
748 hpi_init_response(&hr, HPI_OBJ_ADAPTER,
749 HPI_ADAPTER_OPEN, HPI_ERROR_BAD_ADAPTER);
750 memcpy(&rESP_HPI_ADAPTER_OPEN[adapter], &hr,
751 sizeof(rESP_HPI_ADAPTER_OPEN[adapter]));
752
753 hpi_init_response(&hr, HPI_OBJ_MIXER, HPI_MIXER_OPEN,
754 HPI_ERROR_INVALID_OBJ);
755 memcpy(&rESP_HPI_MIXER_OPEN[adapter], &hr,
756 sizeof(rESP_HPI_MIXER_OPEN[adapter]));
757
758 for (i = 0; i < HPI_MAX_STREAMS; i++) {
759 hpi_init_response(&hr, HPI_OBJ_OSTREAM,
760 HPI_OSTREAM_OPEN,
761 HPI_ERROR_INVALID_OBJ);
762 memcpy(&rESP_HPI_OSTREAM_OPEN[adapter][i],
763 &hr,
764 sizeof(rESP_HPI_OSTREAM_OPEN[adapter]
765 [i]));
766 hpi_init_response(&hr, HPI_OBJ_ISTREAM,
767 HPI_ISTREAM_OPEN,
768 HPI_ERROR_INVALID_OBJ);
769 memcpy(&rESP_HPI_ISTREAM_OPEN[adapter][i],
770 &hr,
771 sizeof(rESP_HPI_ISTREAM_OPEN[adapter]
772 [i]));
773 }
774 }
775 } else if (adapter_index < HPI_MAX_ADAPTERS) {
776 rESP_HPI_ADAPTER_OPEN[adapter_index].h.error =
777 HPI_ERROR_BAD_ADAPTER;
778 rESP_HPI_MIXER_OPEN[adapter_index].h.error =
779 HPI_ERROR_INVALID_OBJ;
780 for (i = 0; i < HPI_MAX_STREAMS; i++) {
781 rESP_HPI_OSTREAM_OPEN[adapter_index][i].h.error =
782 HPI_ERROR_INVALID_OBJ;
783 rESP_HPI_ISTREAM_OPEN[adapter_index][i].h.error =
784 HPI_ERROR_INVALID_OBJ;
785 }
786 if (gRESP_HPI_SUBSYS_FIND_ADAPTERS.
787 s.aw_adapter_list[adapter_index]) {
788 gRESP_HPI_SUBSYS_FIND_ADAPTERS.
789 s.aw_adapter_list[adapter_index] = 0;
790 gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.num_adapters--;
791 }
792 }
793}
794
795static u16 HPIMSGX__init(struct hpi_message *phm,
796 /* HPI_SUBSYS_CREATE_ADAPTER structure with */
797 /* resource list or NULL=find all */
798 struct hpi_response *phr
799 /* response from HPI_ADAPTER_GET_INFO */
800 )
801{
802 hpi_handler_func *entry_point_func;
803 struct hpi_response hr;
804
805 if (gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.num_adapters >= HPI_MAX_ADAPTERS)
806 return HPI_ERROR_BAD_ADAPTER_NUMBER;
807
808 /* Init response here so we can pass in previous adapter list */
809 hpi_init_response(&hr, phm->object, phm->function,
810 HPI_ERROR_INVALID_OBJ);
811 memcpy(hr.u.s.aw_adapter_list,
812 gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.aw_adapter_list,
813 sizeof(gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.aw_adapter_list));
814
815 entry_point_func =
816 hpi_lookup_entry_point_function(phm->u.s.resource.r.pci);
817
818 if (entry_point_func) {
819 HPI_DEBUG_MESSAGE(DEBUG, phm);
820 entry_point_func(phm, &hr);
821 } else {
822 phr->error = HPI_ERROR_PROCESSING_MESSAGE;
823 return phr->error;
824 }
825 if (hr.error == 0) {
826 /* the adapter was created succesfully
827 save the mapping for future use */
828 hpi_entry_points[hr.u.s.adapter_index] = entry_point_func;
829 /* prepare adapter (pre-open streams etc.) */
830 HPI_DEBUG_LOG(DEBUG,
831 "HPI_SUBSYS_CREATE_ADAPTER successful,"
832 " preparing adapter\n");
833 adapter_prepare(hr.u.s.adapter_index);
834 }
835 memcpy(phr, &hr, hr.size);
836 return phr->error;
837}
838
839static void HPIMSGX__cleanup(u16 adapter_index, void *h_owner)
840{
841 int i, adapter, adapter_limit;
842
843 if (!h_owner)
844 return;
845
846 if (adapter_index == HPIMSGX_ALLADAPTERS) {
847 adapter = 0;
848 adapter_limit = HPI_MAX_ADAPTERS;
849 } else {
850 adapter = adapter_index;
851 adapter_limit = adapter + 1;
852 }
853
854 for (; adapter < adapter_limit; adapter++) {
855 /* printk(KERN_INFO "Cleanup adapter #%d\n",wAdapter); */
856 for (i = 0; i < HPI_MAX_STREAMS; i++) {
857 if (h_owner ==
858 outstream_user_open[adapter][i].h_owner) {
859 struct hpi_message hm;
860 struct hpi_response hr;
861
862 HPI_DEBUG_LOG(DEBUG,
863 "close adapter %d ostream %d\n",
864 adapter, i);
865
866 hpi_init_message_response(&hm, &hr,
867 HPI_OBJ_OSTREAM, HPI_OSTREAM_RESET);
868 hm.adapter_index = (u16)adapter;
869 hm.obj_index = (u16)i;
870 hw_entry_point(&hm, &hr);
871
872 hm.function = HPI_OSTREAM_HOSTBUFFER_FREE;
873 hw_entry_point(&hm, &hr);
874
875 hm.function = HPI_OSTREAM_GROUP_RESET;
876 hw_entry_point(&hm, &hr);
877
878 outstream_user_open[adapter][i].open_flag = 0;
879 outstream_user_open[adapter][i].h_owner =
880 NULL;
881 }
882 if (h_owner == instream_user_open[adapter][i].h_owner) {
883 struct hpi_message hm;
884 struct hpi_response hr;
885
886 HPI_DEBUG_LOG(DEBUG,
887 "close adapter %d istream %d\n",
888 adapter, i);
889
890 hpi_init_message_response(&hm, &hr,
891 HPI_OBJ_ISTREAM, HPI_ISTREAM_RESET);
892 hm.adapter_index = (u16)adapter;
893 hm.obj_index = (u16)i;
894 hw_entry_point(&hm, &hr);
895
896 hm.function = HPI_ISTREAM_HOSTBUFFER_FREE;
897 hw_entry_point(&hm, &hr);
898
899 hm.function = HPI_ISTREAM_GROUP_RESET;
900 hw_entry_point(&hm, &hr);
901
902 instream_user_open[adapter][i].open_flag = 0;
903 instream_user_open[adapter][i].h_owner = NULL;
904 }
905 }
906 }
907}
diff --git a/sound/pci/asihpi/hpimsgx.h b/sound/pci/asihpi/hpimsgx.h
new file mode 100644
index 000000000000..fd49e7542a88
--- /dev/null
+++ b/sound/pci/asihpi/hpimsgx.h
@@ -0,0 +1,36 @@
1/******************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
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, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19 HPI Extended Message Handler Functions
20
21(C) Copyright AudioScience Inc. 1997-2003
22******************************************************************************/
23
24#ifndef _HPIMSGX_H_
25#define _HPIMSGX_H_
26
27#include "hpi_internal.h"
28
29#define HPIMSGX_ALLADAPTERS (0xFFFF)
30
31void hpi_send_recv_ex(struct hpi_message *phm, struct hpi_response *phr,
32 void *h_owner);
33
34#define HPI_MESSAGE_LOWER_LAYER hpi_send_recv_ex
35
36#endif /* _HPIMSGX_H_ */
diff --git a/sound/pci/asihpi/hpioctl.c b/sound/pci/asihpi/hpioctl.c
new file mode 100644
index 000000000000..7396ac54e99f
--- /dev/null
+++ b/sound/pci/asihpi/hpioctl.c
@@ -0,0 +1,484 @@
1/*******************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
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, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19Common Linux HPI ioctl and module probe/remove functions
20*******************************************************************************/
21#define SOURCEFILE_NAME "hpioctl.c"
22
23#include "hpi_internal.h"
24#include "hpimsginit.h"
25#include "hpidebug.h"
26#include "hpimsgx.h"
27#include "hpioctl.h"
28
29#include <linux/fs.h>
30#include <linux/slab.h>
31#include <linux/moduleparam.h>
32#include <asm/uaccess.h>
33#include <linux/stringify.h>
34
35#ifdef MODULE_FIRMWARE
36MODULE_FIRMWARE("asihpi/dsp5000.bin");
37MODULE_FIRMWARE("asihpi/dsp6200.bin");
38MODULE_FIRMWARE("asihpi/dsp6205.bin");
39MODULE_FIRMWARE("asihpi/dsp6400.bin");
40MODULE_FIRMWARE("asihpi/dsp6600.bin");
41MODULE_FIRMWARE("asihpi/dsp8700.bin");
42MODULE_FIRMWARE("asihpi/dsp8900.bin");
43#endif
44
45static int prealloc_stream_buf;
46module_param(prealloc_stream_buf, int, S_IRUGO);
47MODULE_PARM_DESC(prealloc_stream_buf,
48 "preallocate size for per-adapter stream buffer");
49
50/* Allow the debug level to be changed after module load.
51 E.g. echo 2 > /sys/module/asihpi/parameters/hpiDebugLevel
52*/
53module_param(hpi_debug_level, int, S_IRUGO | S_IWUSR);
54MODULE_PARM_DESC(hpi_debug_level, "debug verbosity 0..5");
55
56/* List of adapters found */
57static struct hpi_adapter adapters[HPI_MAX_ADAPTERS];
58
59/* Wrapper function to HPI_Message to enable dumping of the
60 message and response types.
61*/
62static void hpi_send_recv_f(struct hpi_message *phm, struct hpi_response *phr,
63 struct file *file)
64{
65 int adapter = phm->adapter_index;
66
67 if ((adapter >= HPI_MAX_ADAPTERS || adapter < 0)
68 && (phm->object != HPI_OBJ_SUBSYSTEM))
69 phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
70 else
71 hpi_send_recv_ex(phm, phr, file);
72}
73
74/* This is called from hpifunc.c functions, called by ALSA
75 * (or other kernel process) In this case there is no file descriptor
76 * available for the message cache code
77 */
78void hpi_send_recv(struct hpi_message *phm, struct hpi_response *phr)
79{
80 hpi_send_recv_f(phm, phr, HOWNER_KERNEL);
81}
82
83EXPORT_SYMBOL(hpi_send_recv);
84/* for radio-asihpi */
85
86int asihpi_hpi_release(struct file *file)
87{
88 struct hpi_message hm;
89 struct hpi_response hr;
90
91/* HPI_DEBUG_LOG(INFO,"hpi_release file %p, pid %d\n", file, current->pid); */
92 /* close the subsystem just in case the application forgot to. */
93 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
94 HPI_SUBSYS_CLOSE);
95 hpi_send_recv_ex(&hm, &hr, file);
96 return 0;
97}
98
99long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
100{
101 struct hpi_ioctl_linux __user *phpi_ioctl_data;
102 void __user *puhm;
103 void __user *puhr;
104 union hpi_message_buffer_v1 *hm;
105 union hpi_response_buffer_v1 *hr;
106 u16 res_max_size;
107 u32 uncopied_bytes;
108 struct hpi_adapter *pa = NULL;
109 int err = 0;
110
111 if (cmd != HPI_IOCTL_LINUX)
112 return -EINVAL;
113
114 hm = kmalloc(sizeof(*hm), GFP_KERNEL);
115 hr = kmalloc(sizeof(*hr), GFP_KERNEL);
116 if (!hm || !hr) {
117 err = -ENOMEM;
118 goto out;
119 }
120
121 phpi_ioctl_data = (struct hpi_ioctl_linux __user *)arg;
122
123 /* Read the message and response pointers from user space. */
124 get_user(puhm, &phpi_ioctl_data->phm);
125 get_user(puhr, &phpi_ioctl_data->phr);
126
127 /* Now read the message size and data from user space. */
128 get_user(hm->h.size, (u16 __user *)puhm);
129 if (hm->h.size > sizeof(*hm))
130 hm->h.size = sizeof(*hm);
131
132 /*printk(KERN_INFO "message size %d\n", hm->h.wSize); */
133
134 uncopied_bytes = copy_from_user(hm, puhm, hm->h.size);
135 if (uncopied_bytes) {
136 HPI_DEBUG_LOG(ERROR, "uncopied bytes %d\n", uncopied_bytes);
137 err = -EFAULT;
138 goto out;
139 }
140
141 get_user(res_max_size, (u16 __user *)puhr);
142 /* printk(KERN_INFO "user response size %d\n", res_max_size); */
143 if (res_max_size < sizeof(struct hpi_response_header)) {
144 HPI_DEBUG_LOG(WARNING, "small res size %d\n", res_max_size);
145 err = -EFAULT;
146 goto out;
147 }
148
149 pa = &adapters[hm->h.adapter_index];
150 hr->h.size = 0;
151 if (hm->h.object == HPI_OBJ_SUBSYSTEM) {
152 switch (hm->h.function) {
153 case HPI_SUBSYS_CREATE_ADAPTER:
154 case HPI_SUBSYS_DELETE_ADAPTER:
155 /* Application must not use these functions! */
156 hr->h.size = sizeof(hr->h);
157 hr->h.error = HPI_ERROR_INVALID_OPERATION;
158 hr->h.function = hm->h.function;
159 uncopied_bytes = copy_to_user(puhr, hr, hr->h.size);
160 if (uncopied_bytes)
161 err = -EFAULT;
162 else
163 err = 0;
164 goto out;
165
166 default:
167 hpi_send_recv_f(&hm->m0, &hr->r0, file);
168 }
169 } else {
170 u16 __user *ptr = NULL;
171 u32 size = 0;
172
173 /* -1=no data 0=read from user mem, 1=write to user mem */
174 int wrflag = -1;
175 u32 adapter = hm->h.adapter_index;
176
177 if ((hm->h.adapter_index > HPI_MAX_ADAPTERS) || (!pa->type)) {
178 hpi_init_response(&hr->r0, HPI_OBJ_ADAPTER,
179 HPI_ADAPTER_OPEN,
180 HPI_ERROR_BAD_ADAPTER_NUMBER);
181
182 uncopied_bytes =
183 copy_to_user(puhr, hr, sizeof(hr->h));
184 if (uncopied_bytes)
185 err = -EFAULT;
186 else
187 err = 0;
188 goto out;
189 }
190
191 if (mutex_lock_interruptible(&adapters[adapter].mutex)) {
192 err = -EINTR;
193 goto out;
194 }
195
196 /* Dig out any pointers embedded in the message. */
197 switch (hm->h.function) {
198 case HPI_OSTREAM_WRITE:
199 case HPI_ISTREAM_READ:{
200 /* Yes, sparse, this is correct. */
201 ptr = (u16 __user *)hm->m0.u.d.u.data.pb_data;
202 size = hm->m0.u.d.u.data.data_size;
203
204 /* Allocate buffer according to application request.
205 ?Is it better to alloc/free for the duration
206 of the transaction?
207 */
208 if (pa->buffer_size < size) {
209 HPI_DEBUG_LOG(DEBUG,
210 "realloc adapter %d stream "
211 "buffer from %zd to %d\n",
212 hm->h.adapter_index,
213 pa->buffer_size, size);
214 if (pa->p_buffer) {
215 pa->buffer_size = 0;
216 vfree(pa->p_buffer);
217 }
218 pa->p_buffer = vmalloc(size);
219 if (pa->p_buffer)
220 pa->buffer_size = size;
221 else {
222 HPI_DEBUG_LOG(ERROR,
223 "HPI could not allocate "
224 "stream buffer size %d\n",
225 size);
226
227 mutex_unlock(&adapters
228 [adapter].mutex);
229 err = -EINVAL;
230 goto out;
231 }
232 }
233
234 hm->m0.u.d.u.data.pb_data = pa->p_buffer;
235 if (hm->h.function == HPI_ISTREAM_READ)
236 /* from card, WRITE to user mem */
237 wrflag = 1;
238 else
239 wrflag = 0;
240 break;
241 }
242
243 default:
244 size = 0;
245 break;
246 }
247
248 if (size && (wrflag == 0)) {
249 uncopied_bytes =
250 copy_from_user(pa->p_buffer, ptr, size);
251 if (uncopied_bytes)
252 HPI_DEBUG_LOG(WARNING,
253 "missed %d of %d "
254 "bytes from user\n", uncopied_bytes,
255 size);
256 }
257
258 hpi_send_recv_f(&hm->m0, &hr->r0, file);
259
260 if (size && (wrflag == 1)) {
261 uncopied_bytes =
262 copy_to_user(ptr, pa->p_buffer, size);
263 if (uncopied_bytes)
264 HPI_DEBUG_LOG(WARNING,
265 "missed %d of %d " "bytes to user\n",
266 uncopied_bytes, size);
267 }
268
269 mutex_unlock(&adapters[adapter].mutex);
270 }
271
272 /* on return response size must be set */
273 /*printk(KERN_INFO "response size %d\n", hr->h.wSize); */
274
275 if (!hr->h.size) {
276 HPI_DEBUG_LOG(ERROR, "response zero size\n");
277 err = -EFAULT;
278 goto out;
279 }
280
281 if (hr->h.size > res_max_size) {
282 HPI_DEBUG_LOG(ERROR, "response too big %d %d\n", hr->h.size,
283 res_max_size);
284 /*HPI_DEBUG_MESSAGE(ERROR, hm); */
285 err = -EFAULT;
286 goto out;
287 }
288
289 uncopied_bytes = copy_to_user(puhr, hr, hr->h.size);
290 if (uncopied_bytes) {
291 HPI_DEBUG_LOG(ERROR, "uncopied bytes %d\n", uncopied_bytes);
292 err = -EFAULT;
293 goto out;
294 }
295
296out:
297 kfree(hm);
298 kfree(hr);
299 return err;
300}
301
302int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev,
303 const struct pci_device_id *pci_id)
304{
305 int err, idx, nm;
306 unsigned int memlen;
307 struct hpi_message hm;
308 struct hpi_response hr;
309 struct hpi_adapter adapter;
310 struct hpi_pci pci;
311
312 memset(&adapter, 0, sizeof(adapter));
313
314 printk(KERN_DEBUG "probe PCI device (%04x:%04x,%04x:%04x,%04x)\n",
315 pci_dev->vendor, pci_dev->device, pci_dev->subsystem_vendor,
316 pci_dev->subsystem_device, pci_dev->devfn);
317
318 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
319 HPI_SUBSYS_CREATE_ADAPTER);
320 hpi_init_response(&hr, HPI_OBJ_SUBSYSTEM, HPI_SUBSYS_CREATE_ADAPTER,
321 HPI_ERROR_PROCESSING_MESSAGE);
322
323 hm.adapter_index = -1; /* an invalid index */
324
325 /* fill in HPI_PCI information from kernel provided information */
326 adapter.pci = pci_dev;
327
328 nm = HPI_MAX_ADAPTER_MEM_SPACES;
329
330 for (idx = 0; idx < nm; idx++) {
331 HPI_DEBUG_LOG(INFO, "resource %d %s %08llx-%08llx %04llx\n",
332 idx, pci_dev->resource[idx].name,
333 (unsigned long long)pci_resource_start(pci_dev, idx),
334 (unsigned long long)pci_resource_end(pci_dev, idx),
335 (unsigned long long)pci_resource_flags(pci_dev, idx));
336
337 if (pci_resource_flags(pci_dev, idx) & IORESOURCE_MEM) {
338 memlen = pci_resource_len(pci_dev, idx);
339 adapter.ap_remapped_mem_base[idx] =
340 ioremap(pci_resource_start(pci_dev, idx),
341 memlen);
342 if (!adapter.ap_remapped_mem_base[idx]) {
343 HPI_DEBUG_LOG(ERROR,
344 "ioremap failed, aborting\n");
345 /* unmap previously mapped pci mem space */
346 goto err;
347 }
348 }
349
350 pci.ap_mem_base[idx] = adapter.ap_remapped_mem_base[idx];
351 }
352
353 /* could replace Pci with direct pointer to pci_dev for linux
354 Instead wrap accessor functions for IDs etc.
355 Would it work for windows?
356 */
357 pci.bus_number = pci_dev->bus->number;
358 pci.vendor_id = (u16)pci_dev->vendor;
359 pci.device_id = (u16)pci_dev->device;
360 pci.subsys_vendor_id = (u16)(pci_dev->subsystem_vendor & 0xffff);
361 pci.subsys_device_id = (u16)(pci_dev->subsystem_device & 0xffff);
362 pci.device_number = pci_dev->devfn;
363 pci.interrupt = pci_dev->irq;
364 pci.p_os_data = pci_dev;
365
366 hm.u.s.resource.bus_type = HPI_BUS_PCI;
367 hm.u.s.resource.r.pci = &pci;
368
369 /* call CreateAdapterObject on the relevant hpi module */
370 hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL);
371 if (hr.error)
372 goto err;
373
374 if (prealloc_stream_buf) {
375 adapter.p_buffer = vmalloc(prealloc_stream_buf);
376 if (!adapter.p_buffer) {
377 HPI_DEBUG_LOG(ERROR,
378 "HPI could not allocate "
379 "kernel buffer size %d\n",
380 prealloc_stream_buf);
381 goto err;
382 }
383 }
384
385 adapter.index = hr.u.s.adapter_index;
386 adapter.type = hr.u.s.aw_adapter_list[adapter.index];
387 hm.adapter_index = adapter.index;
388
389 err = hpi_adapter_open(NULL, adapter.index);
390 if (err)
391 goto err;
392
393 adapter.snd_card_asihpi = NULL;
394 /* WARNING can't init mutex in 'adapter'
395 * and then copy it to adapters[] ?!?!
396 */
397 adapters[hr.u.s.adapter_index] = adapter;
398 mutex_init(&adapters[adapter.index].mutex);
399 pci_set_drvdata(pci_dev, &adapters[adapter.index]);
400
401 printk(KERN_INFO "probe found adapter ASI%04X HPI index #%d.\n",
402 adapter.type, adapter.index);
403
404 return 0;
405
406err:
407 for (idx = 0; idx < HPI_MAX_ADAPTER_MEM_SPACES; idx++) {
408 if (adapter.ap_remapped_mem_base[idx]) {
409 iounmap(adapter.ap_remapped_mem_base[idx]);
410 adapter.ap_remapped_mem_base[idx] = NULL;
411 }
412 }
413
414 if (adapter.p_buffer) {
415 adapter.buffer_size = 0;
416 vfree(adapter.p_buffer);
417 }
418
419 HPI_DEBUG_LOG(ERROR, "adapter_probe failed\n");
420 return -ENODEV;
421}
422
423void __devexit asihpi_adapter_remove(struct pci_dev *pci_dev)
424{
425 int idx;
426 struct hpi_message hm;
427 struct hpi_response hr;
428 struct hpi_adapter *pa;
429 pa = (struct hpi_adapter *)pci_get_drvdata(pci_dev);
430
431 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
432 HPI_SUBSYS_DELETE_ADAPTER);
433 hm.adapter_index = pa->index;
434 hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL);
435
436 /* unmap PCI memory space, mapped during device init. */
437 for (idx = 0; idx < HPI_MAX_ADAPTER_MEM_SPACES; idx++) {
438 if (pa->ap_remapped_mem_base[idx]) {
439 iounmap(pa->ap_remapped_mem_base[idx]);
440 pa->ap_remapped_mem_base[idx] = NULL;
441 }
442 }
443
444 if (pa->p_buffer) {
445 pa->buffer_size = 0;
446 vfree(pa->p_buffer);
447 }
448
449 pci_set_drvdata(pci_dev, NULL);
450 /*
451 printk(KERN_INFO "PCI device (%04x:%04x,%04x:%04x,%04x),"
452 " HPI index # %d, removed.\n",
453 pci_dev->vendor, pci_dev->device,
454 pci_dev->subsystem_vendor,
455 pci_dev->subsystem_device, pci_dev->devfn,
456 pa->index);
457 */
458}
459
460void __init asihpi_init(void)
461{
462 struct hpi_message hm;
463 struct hpi_response hr;
464
465 memset(adapters, 0, sizeof(adapters));
466
467 printk(KERN_INFO "ASIHPI driver %d.%02d.%02d\n",
468 HPI_VER_MAJOR(HPI_VER), HPI_VER_MINOR(HPI_VER),
469 HPI_VER_RELEASE(HPI_VER));
470
471 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
472 HPI_SUBSYS_DRIVER_LOAD);
473 hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL);
474}
475
476void asihpi_exit(void)
477{
478 struct hpi_message hm;
479 struct hpi_response hr;
480
481 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
482 HPI_SUBSYS_DRIVER_UNLOAD);
483 hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL);
484}
diff --git a/sound/pci/asihpi/hpioctl.h b/sound/pci/asihpi/hpioctl.h
new file mode 100644
index 000000000000..847f72f03fe1
--- /dev/null
+++ b/sound/pci/asihpi/hpioctl.h
@@ -0,0 +1,38 @@
1/*******************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
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, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19Linux HPI ioctl, and shared module init functions
20*******************************************************************************/
21
22int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev,
23 const struct pci_device_id *pci_id);
24void __devexit asihpi_adapter_remove(struct pci_dev *pci_dev);
25void __init asihpi_init(void);
26void __exit asihpi_exit(void);
27
28int asihpi_hpi_release(struct file *file);
29
30long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
31
32/* This is called from hpifunc.c functions, called by ALSA
33 * (or other kernel process) In this case there is no file descriptor
34 * available for the message cache code
35 */
36void hpi_send_recv(struct hpi_message *phm, struct hpi_response *phr);
37
38#define HOWNER_KERNEL ((void *)-1)
diff --git a/sound/pci/asihpi/hpios.c b/sound/pci/asihpi/hpios.c
new file mode 100644
index 000000000000..742ee12a9e17
--- /dev/null
+++ b/sound/pci/asihpi/hpios.c
@@ -0,0 +1,91 @@
1/******************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
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, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19HPI Operating System function implementation for Linux
20
21(C) Copyright AudioScience Inc. 1997-2003
22******************************************************************************/
23#define SOURCEFILE_NAME "hpios.c"
24#include "hpi_internal.h"
25#include "hpidebug.h"
26#include <linux/delay.h>
27#include <linux/sched.h>
28
29void hpios_delay_micro_seconds(u32 num_micro_sec)
30{
31 if ((usecs_to_jiffies(num_micro_sec) > 1) && !in_interrupt()) {
32 /* MUST NOT SCHEDULE IN INTERRUPT CONTEXT! */
33 schedule_timeout_uninterruptible(usecs_to_jiffies
34 (num_micro_sec));
35 } else if (num_micro_sec <= 2000)
36 udelay(num_micro_sec);
37 else
38 mdelay(num_micro_sec / 1000);
39
40}
41
42void hpios_locked_mem_init(void)
43{
44}
45
46/** Allocated an area of locked memory for bus master DMA operations.
47
48On error, return -ENOMEM, and *pMemArea.size = 0
49*/
50u16 hpios_locked_mem_alloc(struct consistent_dma_area *p_mem_area, u32 size,
51 struct pci_dev *pdev)
52{
53 /*?? any benefit in using managed dmam_alloc_coherent? */
54 p_mem_area->vaddr =
55 dma_alloc_coherent(&pdev->dev, size, &p_mem_area->dma_handle,
56 GFP_DMA32 | GFP_KERNEL);
57
58 if (p_mem_area->vaddr) {
59 HPI_DEBUG_LOG(DEBUG, "allocated %d bytes, dma 0x%x vma %p\n",
60 size, (unsigned int)p_mem_area->dma_handle,
61 p_mem_area->vaddr);
62 p_mem_area->pdev = &pdev->dev;
63 p_mem_area->size = size;
64 return 0;
65 } else {
66 HPI_DEBUG_LOG(WARNING,
67 "failed to allocate %d bytes locked memory\n", size);
68 p_mem_area->size = 0;
69 return -ENOMEM;
70 }
71}
72
73u16 hpios_locked_mem_free(struct consistent_dma_area *p_mem_area)
74{
75 if (p_mem_area->size) {
76 dma_free_coherent(p_mem_area->pdev, p_mem_area->size,
77 p_mem_area->vaddr, p_mem_area->dma_handle);
78 HPI_DEBUG_LOG(DEBUG, "freed %lu bytes, dma 0x%x vma %p\n",
79 (unsigned long)p_mem_area->size,
80 (unsigned int)p_mem_area->dma_handle,
81 p_mem_area->vaddr);
82 p_mem_area->size = 0;
83 return 0;
84 } else {
85 return 1;
86 }
87}
88
89void hpios_locked_mem_free_all(void)
90{
91}
diff --git a/sound/pci/asihpi/hpios.h b/sound/pci/asihpi/hpios.h
new file mode 100644
index 000000000000..370f39b43f85
--- /dev/null
+++ b/sound/pci/asihpi/hpios.h
@@ -0,0 +1,169 @@
1/******************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
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, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19HPI Operating System Specific macros for Linux Kernel driver
20
21(C) Copyright AudioScience Inc. 1997-2003
22******************************************************************************/
23#ifndef _HPIOS_H_
24#define _HPIOS_H_
25
26#undef HPI_OS_LINUX_KERNEL
27#define HPI_OS_LINUX_KERNEL
28
29#define HPI_OS_DEFINED
30#define HPI_KERNEL_MODE
31
32#define HPI_REASSIGN_DUPLICATE_ADAPTER_IDX
33
34#include <linux/io.h>
35#include <asm/system.h>
36#include <linux/ioctl.h>
37#include <linux/kernel.h>
38#include <linux/string.h>
39#include <linux/device.h>
40#include <linux/firmware.h>
41#include <linux/interrupt.h>
42#include <linux/pci.h>
43
44#define HPI_NO_OS_FILE_OPS
45
46#ifdef CONFIG_64BIT
47#define HPI64BIT
48#endif
49
50/** Details of a memory area allocated with pci_alloc_consistent
51Need all info for parameters to pci_free_consistent
52*/
53struct consistent_dma_area {
54 struct device *pdev;
55 /* looks like dma-mapping dma_devres ?! */
56 size_t size;
57 void *vaddr;
58 dma_addr_t dma_handle;
59};
60
61static inline u16 hpios_locked_mem_get_phys_addr(struct consistent_dma_area
62 *locked_mem_handle, u32 *p_physical_addr)
63{
64 *p_physical_addr = locked_mem_handle->dma_handle;
65 return 0;
66}
67
68static inline u16 hpios_locked_mem_get_virt_addr(struct consistent_dma_area
69 *locked_mem_handle, void **pp_virtual_addr)
70{
71 *pp_virtual_addr = locked_mem_handle->vaddr;
72 return 0;
73}
74
75static inline u16 hpios_locked_mem_valid(struct consistent_dma_area
76 *locked_mem_handle)
77{
78 return locked_mem_handle->size != 0;
79}
80
81struct hpi_ioctl_linux {
82 void __user *phm;
83 void __user *phr;
84};
85
86/* Conflict?: H is already used by a number of drivers hid, bluetooth hci,
87 and some sound drivers sb16, hdsp, emu10k. AFAIK 0xFC is ununsed command
88*/
89#define HPI_IOCTL_LINUX _IOWR('H', 0xFC, struct hpi_ioctl_linux)
90
91#define HPI_DEBUG_FLAG_ERROR KERN_ERR
92#define HPI_DEBUG_FLAG_WARNING KERN_WARNING
93#define HPI_DEBUG_FLAG_NOTICE KERN_NOTICE
94#define HPI_DEBUG_FLAG_INFO KERN_INFO
95#define HPI_DEBUG_FLAG_DEBUG KERN_DEBUG
96#define HPI_DEBUG_FLAG_VERBOSE KERN_DEBUG /* kernel has no verbose */
97
98#include <linux/spinlock.h>
99
100#define HPI_LOCKING
101
102struct hpios_spinlock {
103 spinlock_t lock; /* SEE hpios_spinlock */
104 int lock_context;
105};
106
107/* The reason for all this evilness is that ALSA calls some of a drivers
108 * operators in atomic context, and some not. But all our functions channel
109 * through the HPI_Message conduit, so we can't handle the different context
110 * per function
111 */
112#define IN_LOCK_BH 1
113#define IN_LOCK_IRQ 0
114static inline void cond_lock(struct hpios_spinlock *l)
115{
116 if (irqs_disabled()) {
117 /* NO bh or isr can execute on this processor,
118 so ordinary lock will do
119 */
120 spin_lock(&((l)->lock));
121 l->lock_context = IN_LOCK_IRQ;
122 } else {
123 spin_lock_bh(&((l)->lock));
124 l->lock_context = IN_LOCK_BH;
125 }
126}
127
128static inline void cond_unlock(struct hpios_spinlock *l)
129{
130 if (l->lock_context == IN_LOCK_BH)
131 spin_unlock_bh(&((l)->lock));
132 else
133 spin_unlock(&((l)->lock));
134}
135
136#define hpios_msgxlock_init(obj) spin_lock_init(&(obj)->lock)
137#define hpios_msgxlock_lock(obj) cond_lock(obj)
138#define hpios_msgxlock_un_lock(obj) cond_unlock(obj)
139
140#define hpios_dsplock_init(obj) spin_lock_init(&(obj)->dsp_lock.lock)
141#define hpios_dsplock_lock(obj) cond_lock(&(obj)->dsp_lock)
142#define hpios_dsplock_unlock(obj) cond_unlock(&(obj)->dsp_lock)
143
144#ifdef CONFIG_SND_DEBUG
145#define HPI_DEBUG
146#endif
147
148#define HPI_ALIST_LOCKING
149#define hpios_alistlock_init(obj) spin_lock_init(&((obj)->list_lock.lock))
150#define hpios_alistlock_lock(obj) spin_lock(&((obj)->list_lock.lock))
151#define hpios_alistlock_un_lock(obj) spin_unlock(&((obj)->list_lock.lock))
152
153struct hpi_adapter {
154 /* mutex prevents contention for one card
155 between multiple user programs (via ioctl) */
156 struct mutex mutex;
157 u16 index;
158 u16 type;
159
160 /* ALSA card structure */
161 void *snd_card_asihpi;
162
163 char *p_buffer;
164 size_t buffer_size;
165 struct pci_dev *pci;
166 void __iomem *ap_remapped_mem_base[HPI_MAX_ADAPTER_MEM_SPACES];
167};
168
169#endif
diff --git a/sound/pci/asihpi/hpipcida.h b/sound/pci/asihpi/hpipcida.h
new file mode 100644
index 000000000000..bb30868ce1a3
--- /dev/null
+++ b/sound/pci/asihpi/hpipcida.h
@@ -0,0 +1,37 @@
1/******************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
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, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19 Array initializer for PCI card IDs
20
21(C) Copyright AudioScience Inc. 1998-2003
22*******************************************************************************/
23
24/*NOTE: when adding new lines to this header file
25 they MUST be grouped by HPI entry point.
26*/
27
28{
29HPI_PCI_VENDOR_ID_TI, HPI_PCI_DEV_ID_DSP6205,
30 HPI_PCI_VENDOR_ID_AUDIOSCIENCE, PCI_ANY_ID, 0, 0,
31 (kernel_ulong_t) HPI_6205}
32, {
33HPI_PCI_VENDOR_ID_TI, HPI_PCI_DEV_ID_PCI2040,
34 HPI_PCI_VENDOR_ID_AUDIOSCIENCE, PCI_ANY_ID, 0, 0,
35 (kernel_ulong_t) HPI_6000}
36, {
370}
diff --git a/sound/pci/aw2/aw2-alsa.c b/sound/pci/aw2/aw2-alsa.c
index 67921f93a41e..c15002242d98 100644
--- a/sound/pci/aw2/aw2-alsa.c
+++ b/sound/pci/aw2/aw2-alsa.c
@@ -26,7 +26,7 @@
26#include <linux/slab.h> 26#include <linux/slab.h>
27#include <linux/interrupt.h> 27#include <linux/interrupt.h>
28#include <linux/delay.h> 28#include <linux/delay.h>
29#include <asm/io.h> 29#include <linux/io.h>
30#include <sound/core.h> 30#include <sound/core.h>
31#include <sound/initval.h> 31#include <sound/initval.h>
32#include <sound/pcm.h> 32#include <sound/pcm.h>
@@ -44,9 +44,6 @@ MODULE_LICENSE("GPL");
44/********************************* 44/*********************************
45 * DEFINES 45 * DEFINES
46 ********************************/ 46 ********************************/
47#define PCI_VENDOR_ID_SAA7146 0x1131
48#define PCI_DEVICE_ID_SAA7146 0x7146
49
50#define CTL_ROUTE_ANALOG 0 47#define CTL_ROUTE_ANALOG 0
51#define CTL_ROUTE_DIGITAL 1 48#define CTL_ROUTE_DIGITAL 1
52 49
@@ -165,7 +162,7 @@ module_param_array(enable, bool, NULL, 0444);
165MODULE_PARM_DESC(enable, "Enable Audiowerk2 soundcard."); 162MODULE_PARM_DESC(enable, "Enable Audiowerk2 soundcard.");
166 163
167static DEFINE_PCI_DEVICE_TABLE(snd_aw2_ids) = { 164static DEFINE_PCI_DEVICE_TABLE(snd_aw2_ids) = {
168 {PCI_VENDOR_ID_SAA7146, PCI_DEVICE_ID_SAA7146, 0, 0, 165 {PCI_VENDOR_ID_PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7146, 0, 0,
169 0, 0, 0}, 166 0, 0, 0},
170 {0} 167 {0}
171}; 168};
@@ -419,7 +416,7 @@ static int snd_aw2_pcm_playback_open(struct snd_pcm_substream *substream)
419{ 416{
420 struct snd_pcm_runtime *runtime = substream->runtime; 417 struct snd_pcm_runtime *runtime = substream->runtime;
421 418
422 snd_printdd(KERN_DEBUG "aw2: Playback_open \n"); 419 snd_printdd(KERN_DEBUG "aw2: Playback_open\n");
423 runtime->hw = snd_aw2_playback_hw; 420 runtime->hw = snd_aw2_playback_hw;
424 return 0; 421 return 0;
425} 422}
@@ -435,7 +432,7 @@ static int snd_aw2_pcm_capture_open(struct snd_pcm_substream *substream)
435{ 432{
436 struct snd_pcm_runtime *runtime = substream->runtime; 433 struct snd_pcm_runtime *runtime = substream->runtime;
437 434
438 snd_printdd(KERN_DEBUG "aw2: Capture_open \n"); 435 snd_printdd(KERN_DEBUG "aw2: Capture_open\n");
439 runtime->hw = snd_aw2_capture_hw; 436 runtime->hw = snd_aw2_capture_hw;
440 return 0; 437 return 0;
441} 438}
diff --git a/sound/pci/aw2/aw2-saa7146.c b/sound/pci/aw2/aw2-saa7146.c
index 296123ab74f7..8afd8b5d1ac7 100644
--- a/sound/pci/aw2/aw2-saa7146.c
+++ b/sound/pci/aw2/aw2-saa7146.c
@@ -25,7 +25,6 @@
25 25
26#include <linux/init.h> 26#include <linux/init.h>
27#include <linux/pci.h> 27#include <linux/pci.h>
28#include <linux/slab.h>
29#include <linux/interrupt.h> 28#include <linux/interrupt.h>
30#include <linux/delay.h> 29#include <linux/delay.h>
31#include <asm/system.h> 30#include <asm/system.h>
diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c
index 8f443a9d61ec..85fd315d9999 100644
--- a/sound/pci/ca0106/ca0106_mixer.c
+++ b/sound/pci/ca0106/ca0106_mixer.c
@@ -63,7 +63,6 @@
63#include <linux/delay.h> 63#include <linux/delay.h>
64#include <linux/init.h> 64#include <linux/init.h>
65#include <linux/interrupt.h> 65#include <linux/interrupt.h>
66#include <linux/slab.h>
67#include <linux/moduleparam.h> 66#include <linux/moduleparam.h>
68#include <sound/core.h> 67#include <sound/core.h>
69#include <sound/initval.h> 68#include <sound/initval.h>
diff --git a/sound/pci/ca0106/ca0106_proc.c b/sound/pci/ca0106/ca0106_proc.c
index 0470461cc03e..ba96428c9f4c 100644
--- a/sound/pci/ca0106/ca0106_proc.c
+++ b/sound/pci/ca0106/ca0106_proc.c
@@ -63,7 +63,6 @@
63#include <linux/delay.h> 63#include <linux/delay.h>
64#include <linux/init.h> 64#include <linux/init.h>
65#include <linux/interrupt.h> 65#include <linux/interrupt.h>
66#include <linux/slab.h>
67#include <linux/moduleparam.h> 66#include <linux/moduleparam.h>
68#include <sound/core.h> 67#include <sound/core.h>
69#include <sound/initval.h> 68#include <sound/initval.h>
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c
index 1ded64e05643..329968edca9b 100644
--- a/sound/pci/cmipci.c
+++ b/sound/pci/cmipci.c
@@ -941,13 +941,21 @@ static snd_pcm_uframes_t snd_cmipci_pcm_pointer(struct cmipci *cm, struct cmipci
941 struct snd_pcm_substream *substream) 941 struct snd_pcm_substream *substream)
942{ 942{
943 size_t ptr; 943 size_t ptr;
944 unsigned int reg; 944 unsigned int reg, rem, tries;
945
945 if (!rec->running) 946 if (!rec->running)
946 return 0; 947 return 0;
947#if 1 // this seems better.. 948#if 1 // this seems better..
948 reg = rec->ch ? CM_REG_CH1_FRAME2 : CM_REG_CH0_FRAME2; 949 reg = rec->ch ? CM_REG_CH1_FRAME2 : CM_REG_CH0_FRAME2;
949 ptr = rec->dma_size - (snd_cmipci_read_w(cm, reg) + 1); 950 for (tries = 0; tries < 3; tries++) {
950 ptr >>= rec->shift; 951 rem = snd_cmipci_read_w(cm, reg);
952 if (rem < rec->dma_size)
953 goto ok;
954 }
955 printk(KERN_ERR "cmipci: invalid PCM pointer: %#x\n", rem);
956 return SNDRV_PCM_POS_XRUN;
957ok:
958 ptr = (rec->dma_size - (rem + 1)) >> rec->shift;
951#else 959#else
952 reg = rec->ch ? CM_REG_CH1_FRAME1 : CM_REG_CH0_FRAME1; 960 reg = rec->ch ? CM_REG_CH1_FRAME1 : CM_REG_CH0_FRAME1;
953 ptr = snd_cmipci_read(cm, reg) - rec->offset; 961 ptr = snd_cmipci_read(cm, reg) - rec->offset;
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c
index 9edc65059e3e..6772070ed492 100644
--- a/sound/pci/cs4281.c
+++ b/sound/pci/cs4281.c
@@ -1139,40 +1139,28 @@ static void snd_cs4281_proc_read(struct snd_info_entry *entry,
1139 snd_iprintf(buffer, "Spurious end IRQs : %u\n", chip->spurious_dtc_irq); 1139 snd_iprintf(buffer, "Spurious end IRQs : %u\n", chip->spurious_dtc_irq);
1140} 1140}
1141 1141
1142static long snd_cs4281_BA0_read(struct snd_info_entry *entry, 1142static ssize_t snd_cs4281_BA0_read(struct snd_info_entry *entry,
1143 void *file_private_data, 1143 void *file_private_data,
1144 struct file *file, char __user *buf, 1144 struct file *file, char __user *buf,
1145 unsigned long count, unsigned long pos) 1145 size_t count, loff_t pos)
1146{ 1146{
1147 long size;
1148 struct cs4281 *chip = entry->private_data; 1147 struct cs4281 *chip = entry->private_data;
1149 1148
1150 size = count; 1149 if (copy_to_user_fromio(buf, chip->ba0 + pos, count))
1151 if (pos + size > CS4281_BA0_SIZE) 1150 return -EFAULT;
1152 size = (long)CS4281_BA0_SIZE - pos; 1151 return count;
1153 if (size > 0) {
1154 if (copy_to_user_fromio(buf, chip->ba0 + pos, size))
1155 return -EFAULT;
1156 }
1157 return size;
1158} 1152}
1159 1153
1160static long snd_cs4281_BA1_read(struct snd_info_entry *entry, 1154static ssize_t snd_cs4281_BA1_read(struct snd_info_entry *entry,
1161 void *file_private_data, 1155 void *file_private_data,
1162 struct file *file, char __user *buf, 1156 struct file *file, char __user *buf,
1163 unsigned long count, unsigned long pos) 1157 size_t count, loff_t pos)
1164{ 1158{
1165 long size;
1166 struct cs4281 *chip = entry->private_data; 1159 struct cs4281 *chip = entry->private_data;
1167 1160
1168 size = count; 1161 if (copy_to_user_fromio(buf, chip->ba1 + pos, count))
1169 if (pos + size > CS4281_BA1_SIZE) 1162 return -EFAULT;
1170 size = (long)CS4281_BA1_SIZE - pos; 1163 return count;
1171 if (size > 0) {
1172 if (copy_to_user_fromio(buf, chip->ba1 + pos, size))
1173 return -EFAULT;
1174 }
1175 return size;
1176} 1164}
1177 1165
1178static struct snd_info_entry_ops snd_cs4281_proc_ops_BA0 = { 1166static struct snd_info_entry_ops snd_cs4281_proc_ops_BA0 = {
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
index 3f99a5e8528c..aad37082cb6e 100644
--- a/sound/pci/cs46xx/cs46xx_lib.c
+++ b/sound/pci/cs46xx/cs46xx_lib.c
@@ -2657,21 +2657,16 @@ static inline void snd_cs46xx_remove_gameport(struct snd_cs46xx *chip) { }
2657 * proc interface 2657 * proc interface
2658 */ 2658 */
2659 2659
2660static long snd_cs46xx_io_read(struct snd_info_entry *entry, void *file_private_data, 2660static ssize_t snd_cs46xx_io_read(struct snd_info_entry *entry,
2661 struct file *file, char __user *buf, 2661 void *file_private_data,
2662 unsigned long count, unsigned long pos) 2662 struct file *file, char __user *buf,
2663 size_t count, loff_t pos)
2663{ 2664{
2664 long size;
2665 struct snd_cs46xx_region *region = entry->private_data; 2665 struct snd_cs46xx_region *region = entry->private_data;
2666 2666
2667 size = count; 2667 if (copy_to_user_fromio(buf, region->remap_addr + pos, count))
2668 if (pos + (size_t)size > region->size) 2668 return -EFAULT;
2669 size = region->size - pos; 2669 return count;
2670 if (size > 0) {
2671 if (copy_to_user_fromio(buf, region->remap_addr + pos, size))
2672 return -EFAULT;
2673 }
2674 return size;
2675} 2670}
2676 2671
2677static struct snd_info_entry_ops snd_cs46xx_proc_io_ops = { 2672static struct snd_info_entry_ops snd_cs46xx_proc_io_ops = {
diff --git a/sound/pci/cs5530.c b/sound/pci/cs5530.c
index 207479a641cf..bc07e275d4d4 100644
--- a/sound/pci/cs5530.c
+++ b/sound/pci/cs5530.c
@@ -39,6 +39,7 @@
39#include <linux/delay.h> 39#include <linux/delay.h>
40#include <linux/moduleparam.h> 40#include <linux/moduleparam.h>
41#include <linux/pci.h> 41#include <linux/pci.h>
42#include <linux/slab.h>
42#include <sound/core.h> 43#include <sound/core.h>
43#include <sound/sb.h> 44#include <sound/sb.h>
44#include <sound/initval.h> 45#include <sound/initval.h>
diff --git a/sound/pci/cs5535audio/cs5535audio_pcm.c b/sound/pci/cs5535audio/cs5535audio_pcm.c
index 0f48a871f17b..f16bc8aad6ed 100644
--- a/sound/pci/cs5535audio/cs5535audio_pcm.c
+++ b/sound/pci/cs5535audio/cs5535audio_pcm.c
@@ -23,7 +23,6 @@
23 */ 23 */
24 24
25#include <linux/init.h> 25#include <linux/init.h>
26#include <linux/slab.h>
27#include <linux/pci.h> 26#include <linux/pci.h>
28#include <sound/core.h> 27#include <sound/core.h>
29#include <sound/control.h> 28#include <sound/control.h>
diff --git a/sound/pci/cs5535audio/cs5535audio_pm.c b/sound/pci/cs5535audio/cs5535audio_pm.c
index 564c33b60953..a3301cc4ab82 100644
--- a/sound/pci/cs5535audio/cs5535audio_pm.c
+++ b/sound/pci/cs5535audio/cs5535audio_pm.c
@@ -19,7 +19,6 @@
19 */ 19 */
20 20
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/slab.h>
23#include <linux/pci.h> 22#include <linux/pci.h>
24#include <linux/delay.h> 23#include <linux/delay.h>
25#include <sound/core.h> 24#include <sound/core.h>
diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c
index 480cb1e905b6..1bff80cde0a2 100644
--- a/sound/pci/ctxfi/ctatc.c
+++ b/sound/pci/ctxfi/ctatc.c
@@ -24,6 +24,7 @@
24#include "ctdaio.h" 24#include "ctdaio.h"
25#include "cttimer.h" 25#include "cttimer.h"
26#include <linux/delay.h> 26#include <linux/delay.h>
27#include <linux/slab.h>
27#include <sound/pcm.h> 28#include <sound/pcm.h>
28#include <sound/control.h> 29#include <sound/control.h>
29#include <sound/asoundef.h> 30#include <sound/asoundef.h>
diff --git a/sound/pci/ctxfi/ctpcm.c b/sound/pci/ctxfi/ctpcm.c
index d0dc227fbdd3..85ab43e89212 100644
--- a/sound/pci/ctxfi/ctpcm.c
+++ b/sound/pci/ctxfi/ctpcm.c
@@ -17,6 +17,7 @@
17 17
18#include "ctpcm.h" 18#include "ctpcm.h"
19#include "cttimer.h" 19#include "cttimer.h"
20#include <linux/slab.h>
20#include <sound/pcm.h> 21#include <sound/pcm.h>
21 22
22/* Hardware descriptions for playback */ 23/* Hardware descriptions for playback */
diff --git a/sound/pci/echoaudio/darla20.c b/sound/pci/echoaudio/darla20.c
index a65bafe0800f..fe7ad64dccd7 100644
--- a/sound/pci/echoaudio/darla20.c
+++ b/sound/pci/echoaudio/darla20.c
@@ -40,9 +40,9 @@
40#include <linux/init.h> 40#include <linux/init.h>
41#include <linux/interrupt.h> 41#include <linux/interrupt.h>
42#include <linux/pci.h> 42#include <linux/pci.h>
43#include <linux/slab.h>
44#include <linux/moduleparam.h> 43#include <linux/moduleparam.h>
45#include <linux/firmware.h> 44#include <linux/firmware.h>
45#include <linux/slab.h>
46#include <sound/core.h> 46#include <sound/core.h>
47#include <sound/info.h> 47#include <sound/info.h>
48#include <sound/control.h> 48#include <sound/control.h>
diff --git a/sound/pci/echoaudio/darla24.c b/sound/pci/echoaudio/darla24.c
index 0a6c50bcd758..d1fd34b1a8e3 100644
--- a/sound/pci/echoaudio/darla24.c
+++ b/sound/pci/echoaudio/darla24.c
@@ -44,9 +44,9 @@
44#include <linux/init.h> 44#include <linux/init.h>
45#include <linux/interrupt.h> 45#include <linux/interrupt.h>
46#include <linux/pci.h> 46#include <linux/pci.h>
47#include <linux/slab.h>
48#include <linux/moduleparam.h> 47#include <linux/moduleparam.h>
49#include <linux/firmware.h> 48#include <linux/firmware.h>
49#include <linux/slab.h>
50#include <sound/core.h> 50#include <sound/core.h>
51#include <sound/info.h> 51#include <sound/info.h>
52#include <sound/control.h> 52#include <sound/control.h>
diff --git a/sound/pci/echoaudio/echo3g.c b/sound/pci/echoaudio/echo3g.c
index f5142796989b..1dffdc54416d 100644
--- a/sound/pci/echoaudio/echo3g.c
+++ b/sound/pci/echoaudio/echo3g.c
@@ -51,9 +51,9 @@
51#include <linux/init.h> 51#include <linux/init.h>
52#include <linux/interrupt.h> 52#include <linux/interrupt.h>
53#include <linux/pci.h> 53#include <linux/pci.h>
54#include <linux/slab.h>
55#include <linux/moduleparam.h> 54#include <linux/moduleparam.h>
56#include <linux/firmware.h> 55#include <linux/firmware.h>
56#include <linux/slab.h>
57#include <sound/core.h> 57#include <sound/core.h>
58#include <sound/info.h> 58#include <sound/info.h>
59#include <sound/control.h> 59#include <sound/control.h>
diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c
index 8dab82d7d19d..668a5ec04499 100644
--- a/sound/pci/echoaudio/echoaudio.c
+++ b/sound/pci/echoaudio/echoaudio.c
@@ -2184,10 +2184,9 @@ static int __devinit snd_echo_probe(struct pci_dev *pci,
2184 goto ctl_error; 2184 goto ctl_error;
2185#endif 2185#endif
2186 2186
2187 if ((err = snd_card_register(card)) < 0) { 2187 err = snd_card_register(card);
2188 snd_card_free(card); 2188 if (err < 0)
2189 goto ctl_error; 2189 goto ctl_error;
2190 }
2191 snd_printk(KERN_INFO "Card registered: %s\n", card->longname); 2190 snd_printk(KERN_INFO "Card registered: %s\n", card->longname);
2192 2191
2193 pci_set_drvdata(pci, chip); 2192 pci_set_drvdata(pci, chip);
diff --git a/sound/pci/echoaudio/gina20.c b/sound/pci/echoaudio/gina20.c
index 2364f8a1bc21..050e54aa693f 100644
--- a/sound/pci/echoaudio/gina20.c
+++ b/sound/pci/echoaudio/gina20.c
@@ -44,9 +44,9 @@
44#include <linux/init.h> 44#include <linux/init.h>
45#include <linux/interrupt.h> 45#include <linux/interrupt.h>
46#include <linux/pci.h> 46#include <linux/pci.h>
47#include <linux/slab.h>
48#include <linux/moduleparam.h> 47#include <linux/moduleparam.h>
49#include <linux/firmware.h> 48#include <linux/firmware.h>
49#include <linux/slab.h>
50#include <sound/core.h> 50#include <sound/core.h>
51#include <sound/info.h> 51#include <sound/info.h>
52#include <sound/control.h> 52#include <sound/control.h>
diff --git a/sound/pci/echoaudio/gina24.c b/sound/pci/echoaudio/gina24.c
index 616b55825a19..5748fc6d29d6 100644
--- a/sound/pci/echoaudio/gina24.c
+++ b/sound/pci/echoaudio/gina24.c
@@ -50,9 +50,9 @@
50#include <linux/init.h> 50#include <linux/init.h>
51#include <linux/interrupt.h> 51#include <linux/interrupt.h>
52#include <linux/pci.h> 52#include <linux/pci.h>
53#include <linux/slab.h>
54#include <linux/moduleparam.h> 53#include <linux/moduleparam.h>
55#include <linux/firmware.h> 54#include <linux/firmware.h>
55#include <linux/slab.h>
56#include <sound/core.h> 56#include <sound/core.h>
57#include <sound/info.h> 57#include <sound/info.h>
58#include <sound/control.h> 58#include <sound/control.h>
diff --git a/sound/pci/echoaudio/indigo.c b/sound/pci/echoaudio/indigo.c
index 776175c0bdad..4ae5e35cb5f1 100644
--- a/sound/pci/echoaudio/indigo.c
+++ b/sound/pci/echoaudio/indigo.c
@@ -42,9 +42,9 @@
42#include <linux/init.h> 42#include <linux/init.h>
43#include <linux/interrupt.h> 43#include <linux/interrupt.h>
44#include <linux/pci.h> 44#include <linux/pci.h>
45#include <linux/slab.h>
46#include <linux/moduleparam.h> 45#include <linux/moduleparam.h>
47#include <linux/firmware.h> 46#include <linux/firmware.h>
47#include <linux/slab.h>
48#include <sound/core.h> 48#include <sound/core.h>
49#include <sound/info.h> 49#include <sound/info.h>
50#include <sound/control.h> 50#include <sound/control.h>
diff --git a/sound/pci/echoaudio/indigodj.c b/sound/pci/echoaudio/indigodj.c
index 8816b0bd2ba6..3550715bab1c 100644
--- a/sound/pci/echoaudio/indigodj.c
+++ b/sound/pci/echoaudio/indigodj.c
@@ -42,9 +42,9 @@
42#include <linux/init.h> 42#include <linux/init.h>
43#include <linux/interrupt.h> 43#include <linux/interrupt.h>
44#include <linux/pci.h> 44#include <linux/pci.h>
45#include <linux/slab.h>
46#include <linux/moduleparam.h> 45#include <linux/moduleparam.h>
47#include <linux/firmware.h> 46#include <linux/firmware.h>
47#include <linux/slab.h>
48#include <sound/core.h> 48#include <sound/core.h>
49#include <sound/info.h> 49#include <sound/info.h>
50#include <sound/control.h> 50#include <sound/control.h>
diff --git a/sound/pci/echoaudio/indigodjx.c b/sound/pci/echoaudio/indigodjx.c
index b1e3652f2f48..19b191fd0120 100644
--- a/sound/pci/echoaudio/indigodjx.c
+++ b/sound/pci/echoaudio/indigodjx.c
@@ -42,10 +42,10 @@
42#include <linux/init.h> 42#include <linux/init.h>
43#include <linux/interrupt.h> 43#include <linux/interrupt.h>
44#include <linux/pci.h> 44#include <linux/pci.h>
45#include <linux/slab.h>
46#include <linux/moduleparam.h> 45#include <linux/moduleparam.h>
47#include <linux/firmware.h> 46#include <linux/firmware.h>
48#include <linux/io.h> 47#include <linux/io.h>
48#include <linux/slab.h>
49#include <sound/core.h> 49#include <sound/core.h>
50#include <sound/info.h> 50#include <sound/info.h>
51#include <sound/control.h> 51#include <sound/control.h>
diff --git a/sound/pci/echoaudio/indigoio.c b/sound/pci/echoaudio/indigoio.c
index 1035125336d6..a9fcedf317a4 100644
--- a/sound/pci/echoaudio/indigoio.c
+++ b/sound/pci/echoaudio/indigoio.c
@@ -43,9 +43,9 @@
43#include <linux/init.h> 43#include <linux/init.h>
44#include <linux/interrupt.h> 44#include <linux/interrupt.h>
45#include <linux/pci.h> 45#include <linux/pci.h>
46#include <linux/slab.h>
47#include <linux/moduleparam.h> 46#include <linux/moduleparam.h>
48#include <linux/firmware.h> 47#include <linux/firmware.h>
48#include <linux/slab.h>
49#include <sound/core.h> 49#include <sound/core.h>
50#include <sound/info.h> 50#include <sound/info.h>
51#include <sound/control.h> 51#include <sound/control.h>
diff --git a/sound/pci/echoaudio/indigoiox.c b/sound/pci/echoaudio/indigoiox.c
index 60b7cb2753cf..bcdfac63212c 100644
--- a/sound/pci/echoaudio/indigoiox.c
+++ b/sound/pci/echoaudio/indigoiox.c
@@ -43,10 +43,10 @@
43#include <linux/init.h> 43#include <linux/init.h>
44#include <linux/interrupt.h> 44#include <linux/interrupt.h>
45#include <linux/pci.h> 45#include <linux/pci.h>
46#include <linux/slab.h>
47#include <linux/moduleparam.h> 46#include <linux/moduleparam.h>
48#include <linux/firmware.h> 47#include <linux/firmware.h>
49#include <linux/io.h> 48#include <linux/io.h>
49#include <linux/slab.h>
50#include <sound/core.h> 50#include <sound/core.h>
51#include <sound/info.h> 51#include <sound/info.h>
52#include <sound/control.h> 52#include <sound/control.h>
diff --git a/sound/pci/echoaudio/layla20.c b/sound/pci/echoaudio/layla20.c
index 8c3f5c5b5301..d3a98c5dac86 100644
--- a/sound/pci/echoaudio/layla20.c
+++ b/sound/pci/echoaudio/layla20.c
@@ -49,9 +49,9 @@
49#include <linux/init.h> 49#include <linux/init.h>
50#include <linux/interrupt.h> 50#include <linux/interrupt.h>
51#include <linux/pci.h> 51#include <linux/pci.h>
52#include <linux/slab.h>
53#include <linux/moduleparam.h> 52#include <linux/moduleparam.h>
54#include <linux/firmware.h> 53#include <linux/firmware.h>
54#include <linux/slab.h>
55#include <sound/core.h> 55#include <sound/core.h>
56#include <sound/info.h> 56#include <sound/info.h>
57#include <sound/control.h> 57#include <sound/control.h>
diff --git a/sound/pci/echoaudio/layla24.c b/sound/pci/echoaudio/layla24.c
index ed1cc0abc2b8..2a1dca6dce17 100644
--- a/sound/pci/echoaudio/layla24.c
+++ b/sound/pci/echoaudio/layla24.c
@@ -51,9 +51,9 @@
51#include <linux/init.h> 51#include <linux/init.h>
52#include <linux/interrupt.h> 52#include <linux/interrupt.h>
53#include <linux/pci.h> 53#include <linux/pci.h>
54#include <linux/slab.h>
55#include <linux/moduleparam.h> 54#include <linux/moduleparam.h>
56#include <linux/firmware.h> 55#include <linux/firmware.h>
56#include <linux/slab.h>
57#include <sound/core.h> 57#include <sound/core.h>
58#include <sound/info.h> 58#include <sound/info.h>
59#include <sound/control.h> 59#include <sound/control.h>
diff --git a/sound/pci/echoaudio/mia.c b/sound/pci/echoaudio/mia.c
index cc2bbfc65327..9cdf14cfdd74 100644
--- a/sound/pci/echoaudio/mia.c
+++ b/sound/pci/echoaudio/mia.c
@@ -50,9 +50,9 @@
50#include <linux/init.h> 50#include <linux/init.h>
51#include <linux/interrupt.h> 51#include <linux/interrupt.h>
52#include <linux/pci.h> 52#include <linux/pci.h>
53#include <linux/slab.h>
54#include <linux/moduleparam.h> 53#include <linux/moduleparam.h>
55#include <linux/firmware.h> 54#include <linux/firmware.h>
55#include <linux/slab.h>
56#include <sound/core.h> 56#include <sound/core.h>
57#include <sound/info.h> 57#include <sound/info.h>
58#include <sound/control.h> 58#include <sound/control.h>
diff --git a/sound/pci/echoaudio/mona.c b/sound/pci/echoaudio/mona.c
index 3e7e01824b40..1047be405ebe 100644
--- a/sound/pci/echoaudio/mona.c
+++ b/sound/pci/echoaudio/mona.c
@@ -48,9 +48,9 @@
48#include <linux/init.h> 48#include <linux/init.h>
49#include <linux/interrupt.h> 49#include <linux/interrupt.h>
50#include <linux/pci.h> 50#include <linux/pci.h>
51#include <linux/slab.h>
52#include <linux/moduleparam.h> 51#include <linux/moduleparam.h>
53#include <linux/firmware.h> 52#include <linux/firmware.h>
53#include <linux/slab.h>
54#include <sound/core.h> 54#include <sound/core.h>
55#include <sound/info.h> 55#include <sound/info.h>
56#include <sound/control.h> 56#include <sound/control.h>
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
index f18bd6207c50..66c7fb3ced3e 100644
--- a/sound/pci/emu10k1/emu10k1_main.c
+++ b/sound/pci/emu10k1/emu10k1_main.c
@@ -1787,7 +1787,7 @@ int __devinit snd_emu10k1_create(struct snd_card *card,
1787 else if (subsystem) 1787 else if (subsystem)
1788 snd_printdd("Sound card name = %s, " 1788 snd_printdd("Sound card name = %s, "
1789 "vendor = 0x%x, device = 0x%x, subsystem = 0x%x. " 1789 "vendor = 0x%x, device = 0x%x, subsystem = 0x%x. "
1790 "Forced to subsytem = 0x%x\n", c->name, 1790 "Forced to subsystem = 0x%x\n", c->name,
1791 pci->vendor, pci->device, emu->serial, c->subsystem); 1791 pci->vendor, pci->device, emu->serial, c->subsystem);
1792 else 1792 else
1793 snd_printdd("Sound card name = %s, " 1793 snd_printdd("Sound card name = %s, "
diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c
index 4b302d86f5f2..7a9401462c1c 100644
--- a/sound/pci/emu10k1/emufx.c
+++ b/sound/pci/emu10k1/emufx.c
@@ -35,6 +35,7 @@
35#include <linux/vmalloc.h> 35#include <linux/vmalloc.h>
36#include <linux/init.h> 36#include <linux/init.h>
37#include <linux/mutex.h> 37#include <linux/mutex.h>
38#include <linux/moduleparam.h>
38 39
39#include <sound/core.h> 40#include <sound/core.h>
40#include <sound/tlv.h> 41#include <sound/tlv.h>
@@ -50,6 +51,10 @@
50#define EMU10K1_CENTER_LFE_FROM_FRONT 51#define EMU10K1_CENTER_LFE_FROM_FRONT
51#endif 52#endif
52 53
54static bool high_res_gpr_volume;
55module_param(high_res_gpr_volume, bool, 0444);
56MODULE_PARM_DESC(high_res_gpr_volume, "GPR mixer controls use 31-bit range.");
57
53/* 58/*
54 * Tables 59 * Tables
55 */ 60 */
@@ -296,6 +301,7 @@ static const u32 db_table[101] = {
296 301
297/* EMU10k1/EMU10k2 DSP control db gain */ 302/* EMU10k1/EMU10k2 DSP control db gain */
298static const DECLARE_TLV_DB_SCALE(snd_emu10k1_db_scale1, -4000, 40, 1); 303static const DECLARE_TLV_DB_SCALE(snd_emu10k1_db_scale1, -4000, 40, 1);
304static const DECLARE_TLV_DB_LINEAR(snd_emu10k1_db_linear, TLV_DB_GAIN_MUTE, 0);
299 305
300static const u32 onoff_table[2] = { 306static const u32 onoff_table[2] = {
301 0x00000000, 0x00000001 307 0x00000000, 0x00000001
@@ -1072,10 +1078,17 @@ snd_emu10k1_init_mono_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
1072 strcpy(ctl->id.name, name); 1078 strcpy(ctl->id.name, name);
1073 ctl->vcount = ctl->count = 1; 1079 ctl->vcount = ctl->count = 1;
1074 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval; 1080 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1075 ctl->min = 0; 1081 if (high_res_gpr_volume) {
1076 ctl->max = 100; 1082 ctl->min = 0;
1077 ctl->tlv = snd_emu10k1_db_scale1; 1083 ctl->max = 0x7fffffff;
1078 ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100; 1084 ctl->tlv = snd_emu10k1_db_linear;
1085 ctl->translation = EMU10K1_GPR_TRANSLATION_NONE;
1086 } else {
1087 ctl->min = 0;
1088 ctl->max = 100;
1089 ctl->tlv = snd_emu10k1_db_scale1;
1090 ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;
1091 }
1079} 1092}
1080 1093
1081static void __devinit 1094static void __devinit
@@ -1087,10 +1100,17 @@ snd_emu10k1_init_stereo_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
1087 ctl->vcount = ctl->count = 2; 1100 ctl->vcount = ctl->count = 2;
1088 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval; 1101 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1089 ctl->gpr[1] = gpr + 1; ctl->value[1] = defval; 1102 ctl->gpr[1] = gpr + 1; ctl->value[1] = defval;
1090 ctl->min = 0; 1103 if (high_res_gpr_volume) {
1091 ctl->max = 100; 1104 ctl->min = 0;
1092 ctl->tlv = snd_emu10k1_db_scale1; 1105 ctl->max = 0x7fffffff;
1093 ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100; 1106 ctl->tlv = snd_emu10k1_db_linear;
1107 ctl->translation = EMU10K1_GPR_TRANSLATION_NONE;
1108 } else {
1109 ctl->min = 0;
1110 ctl->max = 100;
1111 ctl->tlv = snd_emu10k1_db_scale1;
1112 ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;
1113 }
1094} 1114}
1095 1115
1096static void __devinit 1116static void __devinit
diff --git a/sound/pci/emu10k1/emuproc.c b/sound/pci/emu10k1/emuproc.c
index baa7cd508cd8..bc38dd4d071f 100644
--- a/sound/pci/emu10k1/emuproc.c
+++ b/sound/pci/emu10k1/emuproc.c
@@ -341,15 +341,17 @@ static void snd_emu10k1_proc_acode_read(struct snd_info_entry *entry,
341#define TOTAL_SIZE_CODE (0x200*8) 341#define TOTAL_SIZE_CODE (0x200*8)
342#define A_TOTAL_SIZE_CODE (0x400*8) 342#define A_TOTAL_SIZE_CODE (0x400*8)
343 343
344static long snd_emu10k1_fx8010_read(struct snd_info_entry *entry, 344static ssize_t snd_emu10k1_fx8010_read(struct snd_info_entry *entry,
345 void *file_private_data, 345 void *file_private_data,
346 struct file *file, char __user *buf, 346 struct file *file, char __user *buf,
347 unsigned long count, unsigned long pos) 347 size_t count, loff_t pos)
348{ 348{
349 long size;
350 struct snd_emu10k1 *emu = entry->private_data; 349 struct snd_emu10k1 *emu = entry->private_data;
351 unsigned int offset; 350 unsigned int offset;
352 int tram_addr = 0; 351 int tram_addr = 0;
352 unsigned int *tmp;
353 long res;
354 unsigned int idx;
353 355
354 if (!strcmp(entry->name, "fx8010_tram_addr")) { 356 if (!strcmp(entry->name, "fx8010_tram_addr")) {
355 offset = TANKMEMADDRREGBASE; 357 offset = TANKMEMADDRREGBASE;
@@ -361,30 +363,25 @@ static long snd_emu10k1_fx8010_read(struct snd_info_entry *entry,
361 } else { 363 } else {
362 offset = emu->audigy ? A_FXGPREGBASE : FXGPREGBASE; 364 offset = emu->audigy ? A_FXGPREGBASE : FXGPREGBASE;
363 } 365 }
364 size = count; 366
365 if (pos + size > entry->size) 367 tmp = kmalloc(count + 8, GFP_KERNEL);
366 size = (long)entry->size - pos; 368 if (!tmp)
367 if (size > 0) { 369 return -ENOMEM;
368 unsigned int *tmp; 370 for (idx = 0; idx < ((pos & 3) + count + 3) >> 2; idx++) {
369 long res; 371 unsigned int val;
370 unsigned int idx; 372 val = snd_emu10k1_ptr_read(emu, offset + idx + (pos >> 2), 0);
371 if ((tmp = kmalloc(size + 8, GFP_KERNEL)) == NULL) 373 if (tram_addr && emu->audigy) {
372 return -ENOMEM; 374 val >>= 11;
373 for (idx = 0; idx < ((pos & 3) + size + 3) >> 2; idx++) 375 val |= snd_emu10k1_ptr_read(emu, 0x100 + idx + (pos >> 2), 0) << 20;
374 if (tram_addr && emu->audigy) {
375 tmp[idx] = snd_emu10k1_ptr_read(emu, offset + idx + (pos >> 2), 0) >> 11;
376 tmp[idx] |= snd_emu10k1_ptr_read(emu, 0x100 + idx + (pos >> 2), 0) << 20;
377 } else
378 tmp[idx] = snd_emu10k1_ptr_read(emu, offset + idx + (pos >> 2), 0);
379 if (copy_to_user(buf, ((char *)tmp) + (pos & 3), size))
380 res = -EFAULT;
381 else {
382 res = size;
383 } 376 }
384 kfree(tmp); 377 tmp[idx] = val;
385 return res;
386 } 378 }
387 return 0; 379 if (copy_to_user(buf, ((char *)tmp) + (pos & 3), count))
380 res = -EFAULT;
381 else
382 res = count;
383 kfree(tmp);
384 return res;
388} 385}
389 386
390static void snd_emu10k1_proc_voices_read(struct snd_info_entry *entry, 387static void snd_emu10k1_proc_voices_read(struct snd_info_entry *entry,
diff --git a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c
index 6a47672f930a..ffb1ddb8dc28 100644
--- a/sound/pci/emu10k1/memory.c
+++ b/sound/pci/emu10k1/memory.c
@@ -22,6 +22,7 @@
22 */ 22 */
23 23
24#include <linux/pci.h> 24#include <linux/pci.h>
25#include <linux/gfp.h>
25#include <linux/time.h> 26#include <linux/time.h>
26#include <linux/mutex.h> 27#include <linux/mutex.h>
27 28
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index ecaea9fb48ec..23a58f0d6cb9 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -104,6 +104,7 @@
104#include <linux/gameport.h> 104#include <linux/gameport.h>
105#include <linux/moduleparam.h> 105#include <linux/moduleparam.h>
106#include <linux/mutex.h> 106#include <linux/mutex.h>
107#include <linux/input.h>
107 108
108#include <sound/core.h> 109#include <sound/core.h>
109#include <sound/pcm.h> 110#include <sound/pcm.h>
@@ -517,14 +518,9 @@ struct es1968 {
517 518
518 /* ALSA Stuff */ 519 /* ALSA Stuff */
519 struct snd_ac97 *ac97; 520 struct snd_ac97 *ac97;
520 struct snd_kcontrol *master_switch; /* for h/w volume control */
521 struct snd_kcontrol *master_volume;
522
523 struct snd_rawmidi *rmidi; 521 struct snd_rawmidi *rmidi;
524 522
525 spinlock_t reg_lock; 523 spinlock_t reg_lock;
526 spinlock_t ac97_lock;
527 struct tasklet_struct hwvol_tq;
528 unsigned int in_suspend; 524 unsigned int in_suspend;
529 525
530 /* Maestro Stuff */ 526 /* Maestro Stuff */
@@ -547,6 +543,16 @@ struct es1968 {
547#ifdef SUPPORT_JOYSTICK 543#ifdef SUPPORT_JOYSTICK
548 struct gameport *gameport; 544 struct gameport *gameport;
549#endif 545#endif
546
547#ifdef CONFIG_SND_ES1968_INPUT
548 struct input_dev *input_dev;
549 char phys[64]; /* physical device path */
550#else
551 struct snd_kcontrol *master_switch; /* for h/w volume control */
552 struct snd_kcontrol *master_volume;
553 spinlock_t ac97_lock;
554 struct tasklet_struct hwvol_tq;
555#endif
550}; 556};
551 557
552static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id); 558static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id);
@@ -632,28 +638,38 @@ static int snd_es1968_ac97_wait_poll(struct es1968 *chip)
632static void snd_es1968_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val) 638static void snd_es1968_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val)
633{ 639{
634 struct es1968 *chip = ac97->private_data; 640 struct es1968 *chip = ac97->private_data;
641#ifndef CONFIG_SND_ES1968_INPUT
635 unsigned long flags; 642 unsigned long flags;
643#endif
636 644
637 snd_es1968_ac97_wait(chip); 645 snd_es1968_ac97_wait(chip);
638 646
639 /* Write the bus */ 647 /* Write the bus */
648#ifndef CONFIG_SND_ES1968_INPUT
640 spin_lock_irqsave(&chip->ac97_lock, flags); 649 spin_lock_irqsave(&chip->ac97_lock, flags);
650#endif
641 outw(val, chip->io_port + ESM_AC97_DATA); 651 outw(val, chip->io_port + ESM_AC97_DATA);
642 /*msleep(1);*/ 652 /*msleep(1);*/
643 outb(reg, chip->io_port + ESM_AC97_INDEX); 653 outb(reg, chip->io_port + ESM_AC97_INDEX);
644 /*msleep(1);*/ 654 /*msleep(1);*/
655#ifndef CONFIG_SND_ES1968_INPUT
645 spin_unlock_irqrestore(&chip->ac97_lock, flags); 656 spin_unlock_irqrestore(&chip->ac97_lock, flags);
657#endif
646} 658}
647 659
648static unsigned short snd_es1968_ac97_read(struct snd_ac97 *ac97, unsigned short reg) 660static unsigned short snd_es1968_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
649{ 661{
650 u16 data = 0; 662 u16 data = 0;
651 struct es1968 *chip = ac97->private_data; 663 struct es1968 *chip = ac97->private_data;
664#ifndef CONFIG_SND_ES1968_INPUT
652 unsigned long flags; 665 unsigned long flags;
666#endif
653 667
654 snd_es1968_ac97_wait(chip); 668 snd_es1968_ac97_wait(chip);
655 669
670#ifndef CONFIG_SND_ES1968_INPUT
656 spin_lock_irqsave(&chip->ac97_lock, flags); 671 spin_lock_irqsave(&chip->ac97_lock, flags);
672#endif
657 outb(reg | 0x80, chip->io_port + ESM_AC97_INDEX); 673 outb(reg | 0x80, chip->io_port + ESM_AC97_INDEX);
658 /*msleep(1);*/ 674 /*msleep(1);*/
659 675
@@ -661,7 +677,9 @@ static unsigned short snd_es1968_ac97_read(struct snd_ac97 *ac97, unsigned short
661 data = inw(chip->io_port + ESM_AC97_DATA); 677 data = inw(chip->io_port + ESM_AC97_DATA);
662 /*msleep(1);*/ 678 /*msleep(1);*/
663 } 679 }
680#ifndef CONFIG_SND_ES1968_INPUT
664 spin_unlock_irqrestore(&chip->ac97_lock, flags); 681 spin_unlock_irqrestore(&chip->ac97_lock, flags);
682#endif
665 683
666 return data; 684 return data;
667} 685}
@@ -1874,13 +1892,17 @@ static void snd_es1968_update_pcm(struct es1968 *chip, struct esschan *es)
1874 } 1892 }
1875} 1893}
1876 1894
1877/* 1895/* The hardware volume works by incrementing / decrementing 2 counters
1878 */ 1896 (without wrap around) in response to volume button presses and then
1897 generating an interrupt. The pair of counters is stored in bits 1-3 and 5-7
1898 of a byte wide register. The meaning of bits 0 and 4 is unknown. */
1879static void es1968_update_hw_volume(unsigned long private_data) 1899static void es1968_update_hw_volume(unsigned long private_data)
1880{ 1900{
1881 struct es1968 *chip = (struct es1968 *) private_data; 1901 struct es1968 *chip = (struct es1968 *) private_data;
1882 int x, val; 1902 int x, val;
1903#ifndef CONFIG_SND_ES1968_INPUT
1883 unsigned long flags; 1904 unsigned long flags;
1905#endif
1884 1906
1885 /* Figure out which volume control button was pushed, 1907 /* Figure out which volume control button was pushed,
1886 based on differences from the default register 1908 based on differences from the default register
@@ -1895,6 +1917,7 @@ static void es1968_update_hw_volume(unsigned long private_data)
1895 if (chip->in_suspend) 1917 if (chip->in_suspend)
1896 return; 1918 return;
1897 1919
1920#ifndef CONFIG_SND_ES1968_INPUT
1898 if (! chip->master_switch || ! chip->master_volume) 1921 if (! chip->master_switch || ! chip->master_volume)
1899 return; 1922 return;
1900 1923
@@ -1937,6 +1960,35 @@ static void es1968_update_hw_volume(unsigned long private_data)
1937 break; 1960 break;
1938 } 1961 }
1939 spin_unlock_irqrestore(&chip->ac97_lock, flags); 1962 spin_unlock_irqrestore(&chip->ac97_lock, flags);
1963#else
1964 if (!chip->input_dev)
1965 return;
1966
1967 val = 0;
1968 switch (x) {
1969 case 0x88:
1970 /* The counters have not changed, yet we've received a HV
1971 interrupt. According to tests run by various people this
1972 happens when pressing the mute button. */
1973 val = KEY_MUTE;
1974 break;
1975 case 0xaa:
1976 /* counters increased by 1 -> volume up */
1977 val = KEY_VOLUMEUP;
1978 break;
1979 case 0x66:
1980 /* counters decreased by 1 -> volume down */
1981 val = KEY_VOLUMEDOWN;
1982 break;
1983 }
1984
1985 if (val) {
1986 input_report_key(chip->input_dev, val, 1);
1987 input_sync(chip->input_dev);
1988 input_report_key(chip->input_dev, val, 0);
1989 input_sync(chip->input_dev);
1990 }
1991#endif
1940} 1992}
1941 1993
1942/* 1994/*
@@ -1953,7 +2005,11 @@ static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id)
1953 outw(inw(chip->io_port + 4) & 1, chip->io_port + 4); 2005 outw(inw(chip->io_port + 4) & 1, chip->io_port + 4);
1954 2006
1955 if (event & ESM_HWVOL_IRQ) 2007 if (event & ESM_HWVOL_IRQ)
2008#ifdef CONFIG_SND_ES1968_INPUT
2009 es1968_update_hw_volume((unsigned long)chip);
2010#else
1956 tasklet_schedule(&chip->hwvol_tq); /* we'll do this later */ 2011 tasklet_schedule(&chip->hwvol_tq); /* we'll do this later */
2012#endif
1957 2013
1958 /* else ack 'em all, i imagine */ 2014 /* else ack 'em all, i imagine */
1959 outb(0xFF, chip->io_port + 0x1A); 2015 outb(0xFF, chip->io_port + 0x1A);
@@ -1993,7 +2049,9 @@ snd_es1968_mixer(struct es1968 *chip)
1993{ 2049{
1994 struct snd_ac97_bus *pbus; 2050 struct snd_ac97_bus *pbus;
1995 struct snd_ac97_template ac97; 2051 struct snd_ac97_template ac97;
2052#ifndef CONFIG_SND_ES1968_INPUT
1996 struct snd_ctl_elem_id elem_id; 2053 struct snd_ctl_elem_id elem_id;
2054#endif
1997 int err; 2055 int err;
1998 static struct snd_ac97_bus_ops ops = { 2056 static struct snd_ac97_bus_ops ops = {
1999 .write = snd_es1968_ac97_write, 2057 .write = snd_es1968_ac97_write,
@@ -2009,6 +2067,7 @@ snd_es1968_mixer(struct es1968 *chip)
2009 if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97)) < 0) 2067 if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97)) < 0)
2010 return err; 2068 return err;
2011 2069
2070#ifndef CONFIG_SND_ES1968_INPUT
2012 /* attach master switch / volumes for h/w volume control */ 2071 /* attach master switch / volumes for h/w volume control */
2013 memset(&elem_id, 0, sizeof(elem_id)); 2072 memset(&elem_id, 0, sizeof(elem_id));
2014 elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; 2073 elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
@@ -2018,6 +2077,7 @@ snd_es1968_mixer(struct es1968 *chip)
2018 elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; 2077 elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2019 strcpy(elem_id.name, "Master Playback Volume"); 2078 strcpy(elem_id.name, "Master Playback Volume");
2020 chip->master_volume = snd_ctl_find_id(chip->card, &elem_id); 2079 chip->master_volume = snd_ctl_find_id(chip->card, &elem_id);
2080#endif
2021 2081
2022 return 0; 2082 return 0;
2023} 2083}
@@ -2341,6 +2401,7 @@ static void snd_es1968_start_irq(struct es1968 *chip)
2341 w = ESM_HIRQ_DSIE | ESM_HIRQ_HW_VOLUME; 2401 w = ESM_HIRQ_DSIE | ESM_HIRQ_HW_VOLUME;
2342 if (chip->rmidi) 2402 if (chip->rmidi)
2343 w |= ESM_HIRQ_MPU401; 2403 w |= ESM_HIRQ_MPU401;
2404 outb(w, chip->io_port + 0x1A);
2344 outw(w, chip->io_port + ESM_PORT_HOST_IRQ); 2405 outw(w, chip->io_port + ESM_PORT_HOST_IRQ);
2345} 2406}
2346 2407
@@ -2474,8 +2535,49 @@ static inline int snd_es1968_create_gameport(struct es1968 *chip, int dev) { ret
2474static inline void snd_es1968_free_gameport(struct es1968 *chip) { } 2535static inline void snd_es1968_free_gameport(struct es1968 *chip) { }
2475#endif 2536#endif
2476 2537
2538#ifdef CONFIG_SND_ES1968_INPUT
2539static int __devinit snd_es1968_input_register(struct es1968 *chip)
2540{
2541 struct input_dev *input_dev;
2542 int err;
2543
2544 input_dev = input_allocate_device();
2545 if (!input_dev)
2546 return -ENOMEM;
2547
2548 snprintf(chip->phys, sizeof(chip->phys), "pci-%s/input0",
2549 pci_name(chip->pci));
2550
2551 input_dev->name = chip->card->driver;
2552 input_dev->phys = chip->phys;
2553 input_dev->id.bustype = BUS_PCI;
2554 input_dev->id.vendor = chip->pci->vendor;
2555 input_dev->id.product = chip->pci->device;
2556 input_dev->dev.parent = &chip->pci->dev;
2557
2558 __set_bit(EV_KEY, input_dev->evbit);
2559 __set_bit(KEY_MUTE, input_dev->keybit);
2560 __set_bit(KEY_VOLUMEDOWN, input_dev->keybit);
2561 __set_bit(KEY_VOLUMEUP, input_dev->keybit);
2562
2563 err = input_register_device(input_dev);
2564 if (err) {
2565 input_free_device(input_dev);
2566 return err;
2567 }
2568
2569 chip->input_dev = input_dev;
2570 return 0;
2571}
2572#endif /* CONFIG_SND_ES1968_INPUT */
2573
2477static int snd_es1968_free(struct es1968 *chip) 2574static int snd_es1968_free(struct es1968 *chip)
2478{ 2575{
2576#ifdef CONFIG_SND_ES1968_INPUT
2577 if (chip->input_dev)
2578 input_unregister_device(chip->input_dev);
2579#endif
2580
2479 if (chip->io_port) { 2581 if (chip->io_port) {
2480 if (chip->irq >= 0) 2582 if (chip->irq >= 0)
2481 synchronize_irq(chip->irq); 2583 synchronize_irq(chip->irq);
@@ -2486,8 +2588,6 @@ static int snd_es1968_free(struct es1968 *chip)
2486 if (chip->irq >= 0) 2588 if (chip->irq >= 0)
2487 free_irq(chip->irq, chip); 2589 free_irq(chip->irq, chip);
2488 snd_es1968_free_gameport(chip); 2590 snd_es1968_free_gameport(chip);
2489 chip->master_switch = NULL;
2490 chip->master_volume = NULL;
2491 pci_release_regions(chip->pci); 2591 pci_release_regions(chip->pci);
2492 pci_disable_device(chip->pci); 2592 pci_disable_device(chip->pci);
2493 kfree(chip); 2593 kfree(chip);
@@ -2558,9 +2658,11 @@ static int __devinit snd_es1968_create(struct snd_card *card,
2558 spin_lock_init(&chip->substream_lock); 2658 spin_lock_init(&chip->substream_lock);
2559 INIT_LIST_HEAD(&chip->buf_list); 2659 INIT_LIST_HEAD(&chip->buf_list);
2560 INIT_LIST_HEAD(&chip->substream_list); 2660 INIT_LIST_HEAD(&chip->substream_list);
2561 spin_lock_init(&chip->ac97_lock);
2562 mutex_init(&chip->memory_mutex); 2661 mutex_init(&chip->memory_mutex);
2662#ifndef CONFIG_SND_ES1968_INPUT
2663 spin_lock_init(&chip->ac97_lock);
2563 tasklet_init(&chip->hwvol_tq, es1968_update_hw_volume, (unsigned long)chip); 2664 tasklet_init(&chip->hwvol_tq, es1968_update_hw_volume, (unsigned long)chip);
2665#endif
2564 chip->card = card; 2666 chip->card = card;
2565 chip->pci = pci; 2667 chip->pci = pci;
2566 chip->irq = -1; 2668 chip->irq = -1;
@@ -2713,6 +2815,13 @@ static int __devinit snd_es1968_probe(struct pci_dev *pci,
2713 2815
2714 snd_es1968_create_gameport(chip, dev); 2816 snd_es1968_create_gameport(chip, dev);
2715 2817
2818#ifdef CONFIG_SND_ES1968_INPUT
2819 err = snd_es1968_input_register(chip);
2820 if (err)
2821 snd_printk(KERN_WARNING "Input device registration "
2822 "failed with error %i", err);
2823#endif
2824
2716 snd_es1968_start_irq(chip); 2825 snd_es1968_start_irq(chip);
2717 2826
2718 chip->clock = clock[dev]; 2827 chip->clock = clock[dev];
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig
index 567348b05b5a..9194c3c1d04a 100644
--- a/sound/pci/hda/Kconfig
+++ b/sound/pci/hda/Kconfig
@@ -145,6 +145,7 @@ config SND_HDA_CODEC_NVHDMI
145 145
146config SND_HDA_CODEC_INTELHDMI 146config SND_HDA_CODEC_INTELHDMI
147 bool "Build INTEL HDMI HD-audio codec support" 147 bool "Build INTEL HDMI HD-audio codec support"
148 select SND_DYNAMIC_MINORS
148 default y 149 default y
149 help 150 help
150 Say Y here to include INTEL HDMI HD-audio codec support in 151 Say Y here to include INTEL HDMI HD-audio codec support in
diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c
index e4581a42ace5..29714c818b53 100644
--- a/sound/pci/hda/hda_beep.c
+++ b/sound/pci/hda/hda_beep.c
@@ -21,6 +21,7 @@
21 21
22#include <linux/input.h> 22#include <linux/input.h>
23#include <linux/pci.h> 23#include <linux/pci.h>
24#include <linux/slab.h>
24#include <linux/workqueue.h> 25#include <linux/workqueue.h>
25#include <sound/core.h> 26#include <sound/core.h>
26#include "hda_beep.h" 27#include "hda_beep.h"
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 0e76ac2b2ace..a3d638c8c1fd 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -1209,8 +1209,7 @@ static void free_hda_cache(struct hda_cache_rec *cache)
1209} 1209}
1210 1210
1211/* query the hash. allocate an entry if not found. */ 1211/* query the hash. allocate an entry if not found. */
1212static struct hda_cache_head *get_alloc_hash(struct hda_cache_rec *cache, 1212static struct hda_cache_head *get_hash(struct hda_cache_rec *cache, u32 key)
1213 u32 key)
1214{ 1213{
1215 u16 idx = key % (u16)ARRAY_SIZE(cache->hash); 1214 u16 idx = key % (u16)ARRAY_SIZE(cache->hash);
1216 u16 cur = cache->hash[idx]; 1215 u16 cur = cache->hash[idx];
@@ -1222,17 +1221,27 @@ static struct hda_cache_head *get_alloc_hash(struct hda_cache_rec *cache,
1222 return info; 1221 return info;
1223 cur = info->next; 1222 cur = info->next;
1224 } 1223 }
1224 return NULL;
1225}
1225 1226
1226 /* add a new hash entry */ 1227/* query the hash. allocate an entry if not found. */
1227 info = snd_array_new(&cache->buf); 1228static struct hda_cache_head *get_alloc_hash(struct hda_cache_rec *cache,
1228 if (!info) 1229 u32 key)
1229 return NULL; 1230{
1230 cur = snd_array_index(&cache->buf, info); 1231 struct hda_cache_head *info = get_hash(cache, key);
1231 info->key = key; 1232 if (!info) {
1232 info->val = 0; 1233 u16 idx, cur;
1233 info->next = cache->hash[idx]; 1234 /* add a new hash entry */
1234 cache->hash[idx] = cur; 1235 info = snd_array_new(&cache->buf);
1235 1236 if (!info)
1237 return NULL;
1238 cur = snd_array_index(&cache->buf, info);
1239 info->key = key;
1240 info->val = 0;
1241 idx = key % (u16)ARRAY_SIZE(cache->hash);
1242 info->next = cache->hash[idx];
1243 cache->hash[idx] = cur;
1244 }
1236 return info; 1245 return info;
1237} 1246}
1238 1247
@@ -1461,6 +1470,8 @@ int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch,
1461 info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, idx)); 1470 info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, idx));
1462 if (!info) 1471 if (!info)
1463 return 0; 1472 return 0;
1473 if (snd_BUG_ON(mask & ~0xff))
1474 mask &= 0xff;
1464 val &= mask; 1475 val &= mask;
1465 val |= get_vol_mute(codec, info, nid, ch, direction, idx) & ~mask; 1476 val |= get_vol_mute(codec, info, nid, ch, direction, idx) & ~mask;
1466 if (info->vol[ch] == val) 1477 if (info->vol[ch] == val)
@@ -1486,6 +1497,9 @@ int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid,
1486 int direction, int idx, int mask, int val) 1497 int direction, int idx, int mask, int val)
1487{ 1498{
1488 int ch, ret = 0; 1499 int ch, ret = 0;
1500
1501 if (snd_BUG_ON(mask & ~0xff))
1502 mask &= 0xff;
1489 for (ch = 0; ch < 2; ch++) 1503 for (ch = 0; ch < 2; ch++)
1490 ret |= snd_hda_codec_amp_update(codec, nid, ch, direction, 1504 ret |= snd_hda_codec_amp_update(codec, nid, ch, direction,
1491 idx, mask, val); 1505 idx, mask, val);
@@ -2717,6 +2731,41 @@ int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid,
2717EXPORT_SYMBOL_HDA(snd_hda_codec_write_cache); 2731EXPORT_SYMBOL_HDA(snd_hda_codec_write_cache);
2718 2732
2719/** 2733/**
2734 * snd_hda_codec_update_cache - check cache and write the cmd only when needed
2735 * @codec: the HDA codec
2736 * @nid: NID to send the command
2737 * @direct: direct flag
2738 * @verb: the verb to send
2739 * @parm: the parameter for the verb
2740 *
2741 * This function works like snd_hda_codec_write_cache(), but it doesn't send
2742 * command if the parameter is already identical with the cached value.
2743 * If not, it sends the command and refreshes the cache.
2744 *
2745 * Returns 0 if successful, or a negative error code.
2746 */
2747int snd_hda_codec_update_cache(struct hda_codec *codec, hda_nid_t nid,
2748 int direct, unsigned int verb, unsigned int parm)
2749{
2750 struct hda_cache_head *c;
2751 u32 key;
2752
2753 /* parm may contain the verb stuff for get/set amp */
2754 verb = verb | (parm >> 8);
2755 parm &= 0xff;
2756 key = build_cmd_cache_key(nid, verb);
2757 mutex_lock(&codec->bus->cmd_mutex);
2758 c = get_hash(&codec->cmd_cache, key);
2759 if (c && c->val == parm) {
2760 mutex_unlock(&codec->bus->cmd_mutex);
2761 return 0;
2762 }
2763 mutex_unlock(&codec->bus->cmd_mutex);
2764 return snd_hda_codec_write_cache(codec, nid, direct, verb, parm);
2765}
2766EXPORT_SYMBOL_HDA(snd_hda_codec_update_cache);
2767
2768/**
2720 * snd_hda_codec_resume_cache - Resume the all commands from the cache 2769 * snd_hda_codec_resume_cache - Resume the all commands from the cache
2721 * @codec: HD-audio codec 2770 * @codec: HD-audio codec
2722 * 2771 *
@@ -4218,7 +4267,8 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
4218 break; 4267 break;
4219 case AC_JACK_MIC_IN: { 4268 case AC_JACK_MIC_IN: {
4220 int preferred, alt; 4269 int preferred, alt;
4221 if (loc == AC_JACK_LOC_FRONT) { 4270 if (loc == AC_JACK_LOC_FRONT ||
4271 (loc & 0x30) == AC_JACK_LOC_INTERNAL) {
4222 preferred = AUTO_PIN_FRONT_MIC; 4272 preferred = AUTO_PIN_FRONT_MIC;
4223 alt = AUTO_PIN_MIC; 4273 alt = AUTO_PIN_MIC;
4224 } else { 4274 } else {
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index b75da47571e6..49e939e7e5cd 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -885,9 +885,12 @@ int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid,
885 int direct, unsigned int verb, unsigned int parm); 885 int direct, unsigned int verb, unsigned int parm);
886void snd_hda_sequence_write_cache(struct hda_codec *codec, 886void snd_hda_sequence_write_cache(struct hda_codec *codec,
887 const struct hda_verb *seq); 887 const struct hda_verb *seq);
888int snd_hda_codec_update_cache(struct hda_codec *codec, hda_nid_t nid,
889 int direct, unsigned int verb, unsigned int parm);
888void snd_hda_codec_resume_cache(struct hda_codec *codec); 890void snd_hda_codec_resume_cache(struct hda_codec *codec);
889#else 891#else
890#define snd_hda_codec_write_cache snd_hda_codec_write 892#define snd_hda_codec_write_cache snd_hda_codec_write
893#define snd_hda_codec_update_cache snd_hda_codec_write
891#define snd_hda_sequence_write_cache snd_hda_sequence_write 894#define snd_hda_sequence_write_cache snd_hda_sequence_write
892#endif 895#endif
893 896
diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c
index dcd22446cfc7..d8da18a9e98b 100644
--- a/sound/pci/hda/hda_eld.c
+++ b/sound/pci/hda/hda_eld.c
@@ -22,6 +22,7 @@
22 */ 22 */
23 23
24#include <linux/init.h> 24#include <linux/init.h>
25#include <linux/slab.h>
25#include <sound/core.h> 26#include <sound/core.h>
26#include <asm/unaligned.h> 27#include <asm/unaligned.h>
27#include "hda_codec.h" 28#include "hda_codec.h"
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 8b2915631cc3..dc79564fea30 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -84,7 +84,7 @@ module_param_array(bdl_pos_adj, int, NULL, 0644);
84MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset."); 84MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset.");
85module_param_array(probe_mask, int, NULL, 0444); 85module_param_array(probe_mask, int, NULL, 0444);
86MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1)."); 86MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1).");
87module_param_array(probe_only, bool, NULL, 0444); 87module_param_array(probe_only, int, NULL, 0444);
88MODULE_PARM_DESC(probe_only, "Only probing and no codec initialization."); 88MODULE_PARM_DESC(probe_only, "Only probing and no codec initialization.");
89module_param(single_cmd, bool, 0444); 89module_param(single_cmd, bool, 0444);
90MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs " 90MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs "
@@ -174,7 +174,7 @@ MODULE_DESCRIPTION("Intel HDA driver");
174#define ICH6_GSTS_FSTS (1 << 1) /* flush status */ 174#define ICH6_GSTS_FSTS (1 << 1) /* flush status */
175#define ICH6_REG_INTCTL 0x20 175#define ICH6_REG_INTCTL 0x20
176#define ICH6_REG_INTSTS 0x24 176#define ICH6_REG_INTSTS 0x24
177#define ICH6_REG_WALCLK 0x30 177#define ICH6_REG_WALLCLK 0x30 /* 24Mhz source */
178#define ICH6_REG_SYNC 0x34 178#define ICH6_REG_SYNC 0x34
179#define ICH6_REG_CORBLBASE 0x40 179#define ICH6_REG_CORBLBASE 0x40
180#define ICH6_REG_CORBUBASE 0x44 180#define ICH6_REG_CORBUBASE 0x44
@@ -340,8 +340,8 @@ struct azx_dev {
340 unsigned int period_bytes; /* size of the period in bytes */ 340 unsigned int period_bytes; /* size of the period in bytes */
341 unsigned int frags; /* number for period in the play buffer */ 341 unsigned int frags; /* number for period in the play buffer */
342 unsigned int fifo_size; /* FIFO size */ 342 unsigned int fifo_size; /* FIFO size */
343 unsigned long start_jiffies; /* start + minimum jiffies */ 343 unsigned long start_wallclk; /* start + minimum wallclk */
344 unsigned long min_jiffies; /* minimum jiffies before position is valid */ 344 unsigned long period_wallclk; /* wallclk for period */
345 345
346 void __iomem *sd_addr; /* stream descriptor pointer */ 346 void __iomem *sd_addr; /* stream descriptor pointer */
347 347
@@ -361,7 +361,6 @@ struct azx_dev {
361 unsigned int opened :1; 361 unsigned int opened :1;
362 unsigned int running :1; 362 unsigned int running :1;
363 unsigned int irq_pending :1; 363 unsigned int irq_pending :1;
364 unsigned int start_flag: 1; /* stream full start flag */
365 /* 364 /*
366 * For VIA: 365 * For VIA:
367 * A flag to ensure DMA position is 0 366 * A flag to ensure DMA position is 0
@@ -425,7 +424,7 @@ struct azx {
425 struct snd_dma_buffer posbuf; 424 struct snd_dma_buffer posbuf;
426 425
427 /* flags */ 426 /* flags */
428 int position_fix; 427 int position_fix[2]; /* for both playback/capture streams */
429 int poll_count; 428 int poll_count;
430 unsigned int running :1; 429 unsigned int running :1;
431 unsigned int initialized :1; 430 unsigned int initialized :1;
@@ -858,10 +857,13 @@ static void azx_power_notify(struct hda_bus *bus);
858#endif 857#endif
859 858
860/* reset codec link */ 859/* reset codec link */
861static int azx_reset(struct azx *chip) 860static int azx_reset(struct azx *chip, int full_reset)
862{ 861{
863 int count; 862 int count;
864 863
864 if (!full_reset)
865 goto __skip;
866
865 /* clear STATESTS */ 867 /* clear STATESTS */
866 azx_writeb(chip, STATESTS, STATESTS_INT_MASK); 868 azx_writeb(chip, STATESTS, STATESTS_INT_MASK);
867 869
@@ -887,6 +889,7 @@ static int azx_reset(struct azx *chip)
887 /* Brent Chartrand said to wait >= 540us for codecs to initialize */ 889 /* Brent Chartrand said to wait >= 540us for codecs to initialize */
888 msleep(1); 890 msleep(1);
889 891
892 __skip:
890 /* check to see if controller is ready */ 893 /* check to see if controller is ready */
891 if (!azx_readb(chip, GCTL)) { 894 if (!azx_readb(chip, GCTL)) {
892 snd_printd(SFX "azx_reset: controller not ready!\n"); 895 snd_printd(SFX "azx_reset: controller not ready!\n");
@@ -998,13 +1001,13 @@ static void azx_stream_stop(struct azx *chip, struct azx_dev *azx_dev)
998/* 1001/*
999 * reset and start the controller registers 1002 * reset and start the controller registers
1000 */ 1003 */
1001static void azx_init_chip(struct azx *chip) 1004static void azx_init_chip(struct azx *chip, int full_reset)
1002{ 1005{
1003 if (chip->initialized) 1006 if (chip->initialized)
1004 return; 1007 return;
1005 1008
1006 /* reset controller */ 1009 /* reset controller */
1007 azx_reset(chip); 1010 azx_reset(chip, full_reset);
1008 1011
1009 /* initialize interrupts */ 1012 /* initialize interrupts */
1010 azx_int_clear(chip); 1013 azx_int_clear(chip);
@@ -1094,6 +1097,7 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id)
1094 struct azx *chip = dev_id; 1097 struct azx *chip = dev_id;
1095 struct azx_dev *azx_dev; 1098 struct azx_dev *azx_dev;
1096 u32 status; 1099 u32 status;
1100 u8 sd_status;
1097 int i, ok; 1101 int i, ok;
1098 1102
1099 spin_lock(&chip->reg_lock); 1103 spin_lock(&chip->reg_lock);
@@ -1107,8 +1111,10 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id)
1107 for (i = 0; i < chip->num_streams; i++) { 1111 for (i = 0; i < chip->num_streams; i++) {
1108 azx_dev = &chip->azx_dev[i]; 1112 azx_dev = &chip->azx_dev[i];
1109 if (status & azx_dev->sd_int_sta_mask) { 1113 if (status & azx_dev->sd_int_sta_mask) {
1114 sd_status = azx_sd_readb(azx_dev, SD_STS);
1110 azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK); 1115 azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK);
1111 if (!azx_dev->substream || !azx_dev->running) 1116 if (!azx_dev->substream || !azx_dev->running ||
1117 !(sd_status & SD_INT_COMPLETE))
1112 continue; 1118 continue;
1113 /* check whether this IRQ is really acceptable */ 1119 /* check whether this IRQ is really acceptable */
1114 ok = azx_position_ok(chip, azx_dev); 1120 ok = azx_position_ok(chip, azx_dev);
@@ -1302,8 +1308,10 @@ static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev)
1302 azx_sd_writel(azx_dev, SD_BDLPU, upper_32_bits(azx_dev->bdl.addr)); 1308 azx_sd_writel(azx_dev, SD_BDLPU, upper_32_bits(azx_dev->bdl.addr));
1303 1309
1304 /* enable the position buffer */ 1310 /* enable the position buffer */
1305 if (chip->position_fix == POS_FIX_POSBUF || 1311 if (chip->position_fix[0] == POS_FIX_POSBUF ||
1306 chip->position_fix == POS_FIX_AUTO || 1312 chip->position_fix[0] == POS_FIX_AUTO ||
1313 chip->position_fix[1] == POS_FIX_POSBUF ||
1314 chip->position_fix[1] == POS_FIX_AUTO ||
1307 chip->via_dmapos_patch) { 1315 chip->via_dmapos_patch) {
1308 if (!(azx_readl(chip, DPLBASE) & ICH6_DPLBASE_ENABLE)) 1316 if (!(azx_readl(chip, DPLBASE) & ICH6_DPLBASE_ENABLE))
1309 azx_writel(chip, DPLBASE, 1317 azx_writel(chip, DPLBASE,
@@ -1348,7 +1356,7 @@ static void azx_bus_reset(struct hda_bus *bus)
1348 1356
1349 bus->in_reset = 1; 1357 bus->in_reset = 1;
1350 azx_stop_chip(chip); 1358 azx_stop_chip(chip);
1351 azx_init_chip(chip); 1359 azx_init_chip(chip, 1);
1352#ifdef CONFIG_PM 1360#ifdef CONFIG_PM
1353 if (chip->initialized) { 1361 if (chip->initialized) {
1354 int i; 1362 int i;
@@ -1422,7 +1430,7 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model)
1422 * get back to the sanity state. 1430 * get back to the sanity state.
1423 */ 1431 */
1424 azx_stop_chip(chip); 1432 azx_stop_chip(chip);
1425 azx_init_chip(chip); 1433 azx_init_chip(chip, 1);
1426 } 1434 }
1427 } 1435 }
1428 } 1436 }
@@ -1670,8 +1678,9 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
1670 return err; 1678 return err;
1671 } 1679 }
1672 1680
1673 azx_dev->min_jiffies = (runtime->period_size * HZ) / 1681 /* wallclk has 24Mhz clock source */
1674 (runtime->rate * 2); 1682 azx_dev->period_wallclk = (((runtime->period_size * 24000) /
1683 runtime->rate) * 1000);
1675 azx_setup_controller(chip, azx_dev); 1684 azx_setup_controller(chip, azx_dev);
1676 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 1685 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1677 azx_dev->fifo_size = azx_sd_readw(azx_dev, SD_FIFOSIZE) + 1; 1686 azx_dev->fifo_size = azx_sd_readw(azx_dev, SD_FIFOSIZE) + 1;
@@ -1725,14 +1734,15 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
1725 if (s->pcm->card != substream->pcm->card) 1734 if (s->pcm->card != substream->pcm->card)
1726 continue; 1735 continue;
1727 azx_dev = get_azx_dev(s); 1736 azx_dev = get_azx_dev(s);
1728 if (rstart) { 1737 if (start) {
1729 azx_dev->start_flag = 1; 1738 azx_dev->start_wallclk = azx_readl(chip, WALLCLK);
1730 azx_dev->start_jiffies = jiffies + azx_dev->min_jiffies; 1739 if (!rstart)
1731 } 1740 azx_dev->start_wallclk -=
1732 if (start) 1741 azx_dev->period_wallclk;
1733 azx_stream_start(chip, azx_dev); 1742 azx_stream_start(chip, azx_dev);
1734 else 1743 } else {
1735 azx_stream_stop(chip, azx_dev); 1744 azx_stream_stop(chip, azx_dev);
1745 }
1736 azx_dev->running = start; 1746 azx_dev->running = start;
1737 } 1747 }
1738 spin_unlock(&chip->reg_lock); 1748 spin_unlock(&chip->reg_lock);
@@ -1843,13 +1853,16 @@ static unsigned int azx_get_position(struct azx *chip,
1843 1853
1844 if (chip->via_dmapos_patch) 1854 if (chip->via_dmapos_patch)
1845 pos = azx_via_get_position(chip, azx_dev); 1855 pos = azx_via_get_position(chip, azx_dev);
1846 else if (chip->position_fix == POS_FIX_POSBUF || 1856 else {
1847 chip->position_fix == POS_FIX_AUTO) { 1857 int stream = azx_dev->substream->stream;
1848 /* use the position buffer */ 1858 if (chip->position_fix[stream] == POS_FIX_POSBUF ||
1849 pos = le32_to_cpu(*azx_dev->posbuf); 1859 chip->position_fix[stream] == POS_FIX_AUTO) {
1850 } else { 1860 /* use the position buffer */
1851 /* read LPIB */ 1861 pos = le32_to_cpu(*azx_dev->posbuf);
1852 pos = azx_sd_readl(azx_dev, SD_LPIB); 1862 } else {
1863 /* read LPIB */
1864 pos = azx_sd_readl(azx_dev, SD_LPIB);
1865 }
1853 } 1866 }
1854 if (pos >= azx_dev->bufsize) 1867 if (pos >= azx_dev->bufsize)
1855 pos = 0; 1868 pos = 0;
@@ -1876,32 +1889,35 @@ static snd_pcm_uframes_t azx_pcm_pointer(struct snd_pcm_substream *substream)
1876 */ 1889 */
1877static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev) 1890static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev)
1878{ 1891{
1892 u32 wallclk;
1879 unsigned int pos; 1893 unsigned int pos;
1894 int stream;
1880 1895
1881 if (azx_dev->start_flag && 1896 wallclk = azx_readl(chip, WALLCLK) - azx_dev->start_wallclk;
1882 time_before_eq(jiffies, azx_dev->start_jiffies)) 1897 if (wallclk < (azx_dev->period_wallclk * 2) / 3)
1883 return -1; /* bogus (too early) interrupt */ 1898 return -1; /* bogus (too early) interrupt */
1884 azx_dev->start_flag = 0;
1885 1899
1900 stream = azx_dev->substream->stream;
1886 pos = azx_get_position(chip, azx_dev); 1901 pos = azx_get_position(chip, azx_dev);
1887 if (chip->position_fix == POS_FIX_AUTO) { 1902 if (chip->position_fix[stream] == POS_FIX_AUTO) {
1888 if (!pos) { 1903 if (!pos) {
1889 printk(KERN_WARNING 1904 printk(KERN_WARNING
1890 "hda-intel: Invalid position buffer, " 1905 "hda-intel: Invalid position buffer, "
1891 "using LPIB read method instead.\n"); 1906 "using LPIB read method instead.\n");
1892 chip->position_fix = POS_FIX_LPIB; 1907 chip->position_fix[stream] = POS_FIX_LPIB;
1893 pos = azx_get_position(chip, azx_dev); 1908 pos = azx_get_position(chip, azx_dev);
1894 } else 1909 } else
1895 chip->position_fix = POS_FIX_POSBUF; 1910 chip->position_fix[stream] = POS_FIX_POSBUF;
1896 } 1911 }
1897 1912
1898 if (!bdl_pos_adj[chip->dev_index])
1899 return 1; /* no delayed ack */
1900 if (WARN_ONCE(!azx_dev->period_bytes, 1913 if (WARN_ONCE(!azx_dev->period_bytes,
1901 "hda-intel: zero azx_dev->period_bytes")) 1914 "hda-intel: zero azx_dev->period_bytes"))
1902 return 0; /* this shouldn't happen! */ 1915 return -1; /* this shouldn't happen! */
1903 if (pos % azx_dev->period_bytes > azx_dev->period_bytes / 2) 1916 if (wallclk <= azx_dev->period_wallclk &&
1904 return 0; /* NG - it's below the period boundary */ 1917 pos % azx_dev->period_bytes > azx_dev->period_bytes / 2)
1918 /* NG - it's below the first next period boundary */
1919 return bdl_pos_adj[chip->dev_index] ? 0 : -1;
1920 azx_dev->start_wallclk = wallclk;
1905 return 1; /* OK, it's fine */ 1921 return 1; /* OK, it's fine */
1906} 1922}
1907 1923
@@ -1911,7 +1927,7 @@ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev)
1911static void azx_irq_pending_work(struct work_struct *work) 1927static void azx_irq_pending_work(struct work_struct *work)
1912{ 1928{
1913 struct azx *chip = container_of(work, struct azx, irq_pending_work); 1929 struct azx *chip = container_of(work, struct azx, irq_pending_work);
1914 int i, pending; 1930 int i, pending, ok;
1915 1931
1916 if (!chip->irq_pending_warned) { 1932 if (!chip->irq_pending_warned) {
1917 printk(KERN_WARNING 1933 printk(KERN_WARNING
@@ -1930,11 +1946,14 @@ static void azx_irq_pending_work(struct work_struct *work)
1930 !azx_dev->substream || 1946 !azx_dev->substream ||
1931 !azx_dev->running) 1947 !azx_dev->running)
1932 continue; 1948 continue;
1933 if (azx_position_ok(chip, azx_dev)) { 1949 ok = azx_position_ok(chip, azx_dev);
1950 if (ok > 0) {
1934 azx_dev->irq_pending = 0; 1951 azx_dev->irq_pending = 0;
1935 spin_unlock(&chip->reg_lock); 1952 spin_unlock(&chip->reg_lock);
1936 snd_pcm_period_elapsed(azx_dev->substream); 1953 snd_pcm_period_elapsed(azx_dev->substream);
1937 spin_lock(&chip->reg_lock); 1954 spin_lock(&chip->reg_lock);
1955 } else if (ok < 0) {
1956 pending = 0; /* too early */
1938 } else 1957 } else
1939 pending++; 1958 pending++;
1940 } 1959 }
@@ -2112,7 +2131,7 @@ static void azx_power_notify(struct hda_bus *bus)
2112 } 2131 }
2113 } 2132 }
2114 if (power_on) 2133 if (power_on)
2115 azx_init_chip(chip); 2134 azx_init_chip(chip, 1);
2116 else if (chip->running && power_save_controller && 2135 else if (chip->running && power_save_controller &&
2117 !bus->power_keep_link_on) 2136 !bus->power_keep_link_on)
2118 azx_stop_chip(chip); 2137 azx_stop_chip(chip);
@@ -2182,7 +2201,7 @@ static int azx_resume(struct pci_dev *pci)
2182 azx_init_pci(chip); 2201 azx_init_pci(chip);
2183 2202
2184 if (snd_hda_codecs_inuse(chip->bus)) 2203 if (snd_hda_codecs_inuse(chip->bus))
2185 azx_init_chip(chip); 2204 azx_init_chip(chip, 1);
2186 2205
2187 snd_hda_resume(chip->bus); 2206 snd_hda_resume(chip->bus);
2188 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 2207 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
@@ -2263,14 +2282,21 @@ static int azx_dev_free(struct snd_device *device)
2263 * white/black-listing for position_fix 2282 * white/black-listing for position_fix
2264 */ 2283 */
2265static struct snd_pci_quirk position_fix_list[] __devinitdata = { 2284static struct snd_pci_quirk position_fix_list[] __devinitdata = {
2285 SND_PCI_QUIRK(0x1025, 0x009f, "Acer Aspire 5110", POS_FIX_LPIB),
2266 SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB), 2286 SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB),
2267 SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB), 2287 SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB),
2268 SND_PCI_QUIRK(0x1028, 0x01f6, "Dell Latitude 131L", POS_FIX_LPIB), 2288 SND_PCI_QUIRK(0x1028, 0x01f6, "Dell Latitude 131L", POS_FIX_LPIB),
2269 SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB), 2289 SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB),
2270 SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB),
2271 SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB), 2290 SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB),
2291 SND_PCI_QUIRK(0x104d, 0x9069, "Sony VPCS11V9E", POS_FIX_LPIB),
2292 SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB),
2293 SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba A100-259", POS_FIX_LPIB),
2294 SND_PCI_QUIRK(0x1297, 0x3166, "Shuttle", POS_FIX_LPIB),
2295 SND_PCI_QUIRK(0x1458, 0xa022, "ga-ma770-ud3", POS_FIX_LPIB),
2272 SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB), 2296 SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB),
2273 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar Microtech", POS_FIX_LPIB), 2297 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar Microtech", POS_FIX_LPIB),
2298 SND_PCI_QUIRK(0x1565, 0x8218, "Biostar Microtech", POS_FIX_LPIB),
2299 SND_PCI_QUIRK(0x8086, 0x2503, "DG965OT AAD63733-203", POS_FIX_LPIB),
2274 SND_PCI_QUIRK(0x8086, 0xd601, "eMachines T5212", POS_FIX_LPIB), 2300 SND_PCI_QUIRK(0x8086, 0xd601, "eMachines T5212", POS_FIX_LPIB),
2275 {} 2301 {}
2276}; 2302};
@@ -2361,6 +2387,7 @@ static struct snd_pci_quirk msi_black_list[] __devinitdata = {
2361 SND_PCI_QUIRK(0x1043, 0x81f6, "ASUS", 0), /* nvidia */ 2387 SND_PCI_QUIRK(0x1043, 0x81f6, "ASUS", 0), /* nvidia */
2362 SND_PCI_QUIRK(0x1043, 0x822d, "ASUS", 0), /* Athlon64 X2 + nvidia MCP55 */ 2388 SND_PCI_QUIRK(0x1043, 0x822d, "ASUS", 0), /* Athlon64 X2 + nvidia MCP55 */
2363 SND_PCI_QUIRK(0x1849, 0x0888, "ASRock", 0), /* Athlon64 X2 + nvidia */ 2389 SND_PCI_QUIRK(0x1849, 0x0888, "ASRock", 0), /* Athlon64 X2 + nvidia */
2390 SND_PCI_QUIRK(0xa0a0, 0x0575, "Aopen MZ915-M", 0), /* ICH6 */
2364 {} 2391 {}
2365}; 2392};
2366 2393
@@ -2427,7 +2454,8 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
2427 chip->dev_index = dev; 2454 chip->dev_index = dev;
2428 INIT_WORK(&chip->irq_pending_work, azx_irq_pending_work); 2455 INIT_WORK(&chip->irq_pending_work, azx_irq_pending_work);
2429 2456
2430 chip->position_fix = check_position_fix(chip, position_fix[dev]); 2457 chip->position_fix[0] = chip->position_fix[1] =
2458 check_position_fix(chip, position_fix[dev]);
2431 check_probe_mask(chip, dev); 2459 check_probe_mask(chip, dev);
2432 2460
2433 chip->single_cmd = single_cmd; 2461 chip->single_cmd = single_cmd;
@@ -2573,7 +2601,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
2573 2601
2574 /* initialize chip */ 2602 /* initialize chip */
2575 azx_init_pci(chip); 2603 azx_init_pci(chip);
2576 azx_init_chip(chip); 2604 azx_init_chip(chip, (probe_only[dev] & 2) == 0);
2577 2605
2578 /* codec detection */ 2606 /* codec detection */
2579 if (!chip->codec_mask) { 2607 if (!chip->codec_mask) {
@@ -2662,7 +2690,7 @@ static int __devinit azx_probe(struct pci_dev *pci,
2662 goto out_free; 2690 goto out_free;
2663 } 2691 }
2664#endif 2692#endif
2665 if (!probe_only[dev]) { 2693 if ((probe_only[dev] & 1) == 0) {
2666 err = azx_codec_configure(chip); 2694 err = azx_codec_configure(chip);
2667 if (err < 0) 2695 if (err < 0)
2668 goto out_free; 2696 goto out_free;
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 7cee364976ff..7a97f126f6f7 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -361,7 +361,7 @@ struct hda_bus_unsolicited {
361}; 361};
362 362
363/* 363/*
364 * Helper for automatic ping configuration 364 * Helper for automatic pin configuration
365 */ 365 */
366 366
367enum { 367enum {
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index e6d1bdff1b6e..afbe314a5bf3 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -71,9 +71,10 @@ struct ad198x_spec {
71 struct hda_input_mux private_imux; 71 struct hda_input_mux private_imux;
72 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; 72 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
73 73
74 unsigned int jack_present :1; 74 unsigned int jack_present: 1;
75 unsigned int inv_jack_detect:1; /* inverted jack-detection */ 75 unsigned int inv_jack_detect: 1;/* inverted jack-detection */
76 unsigned int inv_eapd:1; /* inverted EAPD implementation */ 76 unsigned int inv_eapd: 1; /* inverted EAPD implementation */
77 unsigned int analog_beep: 1; /* analog beep input present */
77 78
78#ifdef CONFIG_SND_HDA_POWER_SAVE 79#ifdef CONFIG_SND_HDA_POWER_SAVE
79 struct hda_loopback_check loopback; 80 struct hda_loopback_check loopback;
@@ -165,6 +166,12 @@ static struct snd_kcontrol_new ad_beep_mixer[] = {
165 { } /* end */ 166 { } /* end */
166}; 167};
167 168
169static struct snd_kcontrol_new ad_beep2_mixer[] = {
170 HDA_CODEC_VOLUME("Digital Beep Playback Volume", 0, 0, HDA_OUTPUT),
171 HDA_CODEC_MUTE_BEEP("Digital Beep Playback Switch", 0, 0, HDA_OUTPUT),
172 { } /* end */
173};
174
168#define set_beep_amp(spec, nid, idx, dir) \ 175#define set_beep_amp(spec, nid, idx, dir) \
169 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir)) /* mono */ 176 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir)) /* mono */
170#else 177#else
@@ -203,7 +210,8 @@ static int ad198x_build_controls(struct hda_codec *codec)
203#ifdef CONFIG_SND_HDA_INPUT_BEEP 210#ifdef CONFIG_SND_HDA_INPUT_BEEP
204 if (spec->beep_amp) { 211 if (spec->beep_amp) {
205 struct snd_kcontrol_new *knew; 212 struct snd_kcontrol_new *knew;
206 for (knew = ad_beep_mixer; knew->name; knew++) { 213 knew = spec->analog_beep ? ad_beep2_mixer : ad_beep_mixer;
214 for ( ; knew->name; knew++) {
207 struct snd_kcontrol *kctl; 215 struct snd_kcontrol *kctl;
208 kctl = snd_ctl_new1(knew, codec); 216 kctl = snd_ctl_new1(knew, codec);
209 if (!kctl) 217 if (!kctl)
@@ -519,14 +527,6 @@ static int ad198x_suspend(struct hda_codec *codec, pm_message_t state)
519 ad198x_power_eapd(codec); 527 ad198x_power_eapd(codec);
520 return 0; 528 return 0;
521} 529}
522
523static int ad198x_resume(struct hda_codec *codec)
524{
525 ad198x_init(codec);
526 snd_hda_codec_resume_amp(codec);
527 snd_hda_codec_resume_cache(codec);
528 return 0;
529}
530#endif 530#endif
531 531
532static struct hda_codec_ops ad198x_patch_ops = { 532static struct hda_codec_ops ad198x_patch_ops = {
@@ -539,7 +539,6 @@ static struct hda_codec_ops ad198x_patch_ops = {
539#endif 539#endif
540#ifdef SND_HDA_NEEDS_RESUME 540#ifdef SND_HDA_NEEDS_RESUME
541 .suspend = ad198x_suspend, 541 .suspend = ad198x_suspend,
542 .resume = ad198x_resume,
543#endif 542#endif
544 .reboot_notify = ad198x_shutup, 543 .reboot_notify = ad198x_shutup,
545}; 544};
@@ -1896,6 +1895,14 @@ static int patch_ad1981(struct hda_codec *codec)
1896 case AD1981_THINKPAD: 1895 case AD1981_THINKPAD:
1897 spec->mixers[0] = ad1981_thinkpad_mixers; 1896 spec->mixers[0] = ad1981_thinkpad_mixers;
1898 spec->input_mux = &ad1981_thinkpad_capture_source; 1897 spec->input_mux = &ad1981_thinkpad_capture_source;
1898 /* set the upper-limit for mixer amp to 0dB for avoiding the
1899 * possible damage by overloading
1900 */
1901 snd_hda_override_amp_caps(codec, 0x11, HDA_INPUT,
1902 (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
1903 (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
1904 (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
1905 (1 << AC_AMPCAP_MUTE_SHIFT));
1899 break; 1906 break;
1900 case AD1981_TOSHIBA: 1907 case AD1981_TOSHIBA:
1901 spec->mixers[0] = ad1981_hp_mixers; 1908 spec->mixers[0] = ad1981_hp_mixers;
@@ -3482,6 +3489,8 @@ static struct snd_kcontrol_new ad1984_thinkpad_mixers[] = {
3482 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT), 3489 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3483 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x20, 0x01, HDA_INPUT), 3490 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
3484 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT), 3491 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
3492 HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x03, HDA_INPUT),
3493 HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x03, HDA_INPUT),
3485 HDA_CODEC_VOLUME("Docking Mic Playback Volume", 0x20, 0x04, HDA_INPUT), 3494 HDA_CODEC_VOLUME("Docking Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
3486 HDA_CODEC_MUTE("Docking Mic Playback Switch", 0x20, 0x04, HDA_INPUT), 3495 HDA_CODEC_MUTE("Docking Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
3487 HDA_CODEC_VOLUME("Mic Boost", 0x14, 0x0, HDA_INPUT), 3496 HDA_CODEC_VOLUME("Mic Boost", 0x14, 0x0, HDA_INPUT),
@@ -3523,6 +3532,8 @@ static struct hda_verb ad1984_thinkpad_init_verbs[] = {
3523 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3532 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3524 /* docking mic boost */ 3533 /* docking mic boost */
3525 {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3534 {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3535 /* Analog PC Beeper - allow firmware/ACPI beeps */
3536 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3) | 0x1a},
3526 /* Analog mixer - docking mic; mute as default */ 3537 /* Analog mixer - docking mic; mute as default */
3527 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 3538 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3528 /* enable EAPD bit */ 3539 /* enable EAPD bit */
@@ -3655,6 +3666,7 @@ static int patch_ad1984(struct hda_codec *codec)
3655 spec->input_mux = &ad1984_thinkpad_capture_source; 3666 spec->input_mux = &ad1984_thinkpad_capture_source;
3656 spec->mixers[0] = ad1984_thinkpad_mixers; 3667 spec->mixers[0] = ad1984_thinkpad_mixers;
3657 spec->init_verbs[spec->num_init_verbs++] = ad1984_thinkpad_init_verbs; 3668 spec->init_verbs[spec->num_init_verbs++] = ad1984_thinkpad_init_verbs;
3669 spec->analog_beep = 1;
3658 break; 3670 break;
3659 case AD1984_DELL_DESKTOP: 3671 case AD1984_DELL_DESKTOP:
3660 spec->multiout.dig_out_nid = 0; 3672 spec->multiout.dig_out_nid = 0;
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index 7de782a5b8f4..350ee8ac4153 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -766,7 +766,7 @@ static int build_input(struct hda_codec *codec)
766 for (n = 0; n < AUTO_PIN_LAST; n++) { 766 for (n = 0; n < AUTO_PIN_LAST; n++) {
767 if (!spec->adc_nid[n]) 767 if (!spec->adc_nid[n])
768 continue; 768 continue;
769 err = snd_hda_add_nid(codec, kctl, 0, spec->adc_nid[i]); 769 err = snd_hda_add_nid(codec, kctl, 0, spec->adc_nid[n]);
770 if (err < 0) 770 if (err < 0)
771 return err; 771 return err;
772 } 772 }
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 194a28c54992..2bf2cb5da956 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -115,6 +115,7 @@ struct conexant_spec {
115 unsigned int port_d_mode; 115 unsigned int port_d_mode;
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 119
119 unsigned int ext_mic_present; 120 unsigned int ext_mic_present;
120 unsigned int recording; 121 unsigned int recording;
@@ -1195,10 +1196,12 @@ static int patch_cxt5045(struct hda_codec *codec)
1195 1196
1196 switch (codec->subsystem_id >> 16) { 1197 switch (codec->subsystem_id >> 16) {
1197 case 0x103c: 1198 case 0x103c:
1199 case 0x1631:
1198 case 0x1734: 1200 case 0x1734:
1199 /* HP & Fujitsu-Siemens laptops have really bad sound over 0dB 1201 case 0x17aa:
1200 * on NID 0x17. Fix max PCM level to 0 dB 1202 /* HP, Packard Bell, Fujitsu-Siemens & Lenovo laptops have
1201 * (originally it has 0x2b steps with 0dB offset 0x14) 1203 * really bad sound over 0dB on NID 0x17. Fix max PCM level to
1204 * 0 dB (originally it has 0x2b steps with 0dB offset 0x14)
1202 */ 1205 */
1203 snd_hda_override_amp_caps(codec, 0x17, HDA_INPUT, 1206 snd_hda_override_amp_caps(codec, 0x17, HDA_INPUT,
1204 (0x14 << AC_AMPCAP_OFFSET_SHIFT) | 1207 (0x14 << AC_AMPCAP_OFFSET_SHIFT) |
@@ -1591,6 +1594,21 @@ static int patch_cxt5047(struct hda_codec *codec)
1591#endif 1594#endif
1592 } 1595 }
1593 spec->vmaster_nid = 0x13; 1596 spec->vmaster_nid = 0x13;
1597
1598 switch (codec->subsystem_id >> 16) {
1599 case 0x103c:
1600 /* HP laptops have really bad sound over 0 dB on NID 0x10.
1601 * Fix max PCM level to 0 dB (originally it has 0x1e steps
1602 * with 0 dB offset 0x17)
1603 */
1604 snd_hda_override_amp_caps(codec, 0x10, HDA_INPUT,
1605 (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
1606 (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
1607 (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
1608 (1 << AC_AMPCAP_MUTE_SHIFT));
1609 break;
1610 }
1611
1594 return 0; 1612 return 0;
1595} 1613}
1596 1614
@@ -1767,6 +1785,7 @@ static struct hda_verb cxt5051_init_verbs[] = {
1767 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44}, 1785 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
1768 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44}, 1786 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
1769 /* SPDIF route: PCM */ 1787 /* SPDIF route: PCM */
1788 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1770 {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0}, 1789 {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0},
1771 /* EAPD */ 1790 /* EAPD */
1772 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ 1791 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
@@ -1823,6 +1842,7 @@ static struct hda_verb cxt5051_lenovo_x200_init_verbs[] = {
1823 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44}, 1842 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
1824 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44}, 1843 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
1825 /* SPDIF route: PCM */ 1844 /* SPDIF route: PCM */
1845 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* needed for W500 Advanced Mini Dock 250410 */
1826 {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0}, 1846 {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0},
1827 /* EAPD */ 1847 /* EAPD */
1828 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ 1848 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
@@ -1894,7 +1914,7 @@ enum {
1894 CXT5051_LAPTOP, /* Laptops w/ EAPD support */ 1914 CXT5051_LAPTOP, /* Laptops w/ EAPD support */
1895 CXT5051_HP, /* no docking */ 1915 CXT5051_HP, /* no docking */
1896 CXT5051_HP_DV6736, /* HP without mic switch */ 1916 CXT5051_HP_DV6736, /* HP without mic switch */
1897 CXT5051_LENOVO_X200, /* Lenovo X200 laptop */ 1917 CXT5051_LENOVO_X200, /* Lenovo X200 laptop, also used for Advanced Mini Dock 250410 */
1898 CXT5051_F700, /* HP Compaq Presario F700 */ 1918 CXT5051_F700, /* HP Compaq Presario F700 */
1899 CXT5051_TOSHIBA, /* Toshiba M300 & co */ 1919 CXT5051_TOSHIBA, /* Toshiba M300 & co */
1900 CXT5051_MODELS 1920 CXT5051_MODELS
@@ -2016,6 +2036,9 @@ static void cxt5066_update_speaker(struct hda_codec *codec)
2016 /* Port D (HP/LO) */ 2036 /* Port D (HP/LO) */
2017 pinctl = ((spec->hp_present & 2) && spec->cur_eapd) 2037 pinctl = ((spec->hp_present & 2) && spec->cur_eapd)
2018 ? spec->port_d_mode : 0; 2038 ? spec->port_d_mode : 0;
2039 /* Mute if Port A is connected on Thinkpad */
2040 if (spec->thinkpad && (spec->hp_present & 1))
2041 pinctl = 0;
2019 snd_hda_codec_write(codec, 0x1c, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 2042 snd_hda_codec_write(codec, 0x1c, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
2020 pinctl); 2043 pinctl);
2021 2044
@@ -2196,6 +2219,50 @@ static void cxt5066_ideapad_automic(struct hda_codec *codec)
2196 } 2219 }
2197} 2220}
2198 2221
2222/* toggle input of built-in digital mic and mic jack appropriately
2223 order is: external mic -> dock mic -> interal mic */
2224static void cxt5066_thinkpad_automic(struct hda_codec *codec)
2225{
2226 unsigned int ext_present, dock_present;
2227
2228 static struct hda_verb ext_mic_present[] = {
2229 {0x14, AC_VERB_SET_CONNECT_SEL, 0},
2230 {0x17, AC_VERB_SET_CONNECT_SEL, 1},
2231 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2232 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2233 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2234 {}
2235 };
2236 static struct hda_verb dock_mic_present[] = {
2237 {0x14, AC_VERB_SET_CONNECT_SEL, 0},
2238 {0x17, AC_VERB_SET_CONNECT_SEL, 0},
2239 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2240 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2241 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2242 {}
2243 };
2244 static struct hda_verb ext_mic_absent[] = {
2245 {0x14, AC_VERB_SET_CONNECT_SEL, 2},
2246 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2247 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2248 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2249 {}
2250 };
2251
2252 ext_present = snd_hda_jack_detect(codec, 0x1b);
2253 dock_present = snd_hda_jack_detect(codec, 0x1a);
2254 if (ext_present) {
2255 snd_printdd("CXT5066: external microphone detected\n");
2256 snd_hda_sequence_write(codec, ext_mic_present);
2257 } else if (dock_present) {
2258 snd_printdd("CXT5066: dock microphone detected\n");
2259 snd_hda_sequence_write(codec, dock_mic_present);
2260 } else {
2261 snd_printdd("CXT5066: external microphone absent\n");
2262 snd_hda_sequence_write(codec, ext_mic_absent);
2263 }
2264}
2265
2199/* mute internal speaker if HP is plugged */ 2266/* mute internal speaker if HP is plugged */
2200static void cxt5066_hp_automute(struct hda_codec *codec) 2267static void cxt5066_hp_automute(struct hda_codec *codec)
2201{ 2268{
@@ -2208,7 +2275,8 @@ static void cxt5066_hp_automute(struct hda_codec *codec)
2208 /* Port D */ 2275 /* Port D */
2209 portD = snd_hda_jack_detect(codec, 0x1c); 2276 portD = snd_hda_jack_detect(codec, 0x1c);
2210 2277
2211 spec->hp_present = !!(portA | portD); 2278 spec->hp_present = !!(portA);
2279 spec->hp_present |= portD ? 2 : 0;
2212 snd_printdd("CXT5066: hp automute portA=%x portD=%x present=%d\n", 2280 snd_printdd("CXT5066: hp automute portA=%x portD=%x present=%d\n",
2213 portA, portD, spec->hp_present); 2281 portA, portD, spec->hp_present);
2214 cxt5066_update_speaker(codec); 2282 cxt5066_update_speaker(codec);
@@ -2259,6 +2327,20 @@ static void cxt5066_ideapad_event(struct hda_codec *codec, unsigned int res)
2259 } 2327 }
2260} 2328}
2261 2329
2330/* unsolicited event for jack sensing */
2331static void cxt5066_thinkpad_event(struct hda_codec *codec, unsigned int res)
2332{
2333 snd_printdd("CXT5066_thinkpad: unsol event %x (%x)\n", res, res >> 26);
2334 switch (res >> 26) {
2335 case CONEXANT_HP_EVENT:
2336 cxt5066_hp_automute(codec);
2337 break;
2338 case CONEXANT_MIC_EVENT:
2339 cxt5066_thinkpad_automic(codec);
2340 break;
2341 }
2342}
2343
2262static const struct hda_input_mux cxt5066_analog_mic_boost = { 2344static const struct hda_input_mux cxt5066_analog_mic_boost = {
2263 .num_items = 5, 2345 .num_items = 5,
2264 .items = { 2346 .items = {
@@ -2277,7 +2359,7 @@ static void cxt5066_set_mic_boost(struct hda_codec *codec)
2277 AC_VERB_SET_AMP_GAIN_MUTE, 2359 AC_VERB_SET_AMP_GAIN_MUTE,
2278 AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_OUTPUT | 2360 AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_OUTPUT |
2279 cxt5066_analog_mic_boost.items[spec->mic_boost].index); 2361 cxt5066_analog_mic_boost.items[spec->mic_boost].index);
2280 if (spec->ideapad) { 2362 if (spec->ideapad || spec->thinkpad) {
2281 /* adjust the internal mic as well...it is not through 0x17 */ 2363 /* adjust the internal mic as well...it is not through 0x17 */
2282 snd_hda_codec_write_cache(codec, 0x23, 0, 2364 snd_hda_codec_write_cache(codec, 0x23, 0,
2283 AC_VERB_SET_AMP_GAIN_MUTE, 2365 AC_VERB_SET_AMP_GAIN_MUTE,
@@ -2765,6 +2847,64 @@ static struct hda_verb cxt5066_init_verbs_ideapad[] = {
2765 { } /* end */ 2847 { } /* end */
2766}; 2848};
2767 2849
2850static struct hda_verb cxt5066_init_verbs_thinkpad[] = {
2851 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */
2852 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port E */
2853
2854 /* Port G: internal speakers */
2855 {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2856 {0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2857
2858 /* Port A: HP, Amp */
2859 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2860 {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2861
2862 /* Port B: Mic Dock */
2863 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2864
2865 /* Port C: Mic */
2866 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2867
2868 /* Port D: HP Dock, Amp */
2869 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2870 {0x1c, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2871
2872 /* DAC1 */
2873 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2874
2875 /* Node 14 connections: 0x17 0x18 0x23 0x24 0x27 */
2876 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x50},
2877 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2878 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2) | 0x50},
2879 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2880 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2881 {0x14, AC_VERB_SET_CONNECT_SEL, 2}, /* default to internal mic */
2882
2883 /* Audio input selector */
2884 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x2},
2885 {0x17, AC_VERB_SET_CONNECT_SEL, 1}, /* route ext mic */
2886
2887 /* SPDIF route: PCM */
2888 {0x20, AC_VERB_SET_CONNECT_SEL, 0x0},
2889 {0x22, AC_VERB_SET_CONNECT_SEL, 0x0},
2890
2891 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2892 {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2893
2894 /* internal microphone */
2895 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* enable int mic */
2896
2897 /* EAPD */
2898 {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
2899
2900 /* enable unsolicited events for Port A, B, C and D */
2901 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
2902 {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
2903 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
2904 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
2905 { } /* end */
2906};
2907
2768static struct hda_verb cxt5066_init_verbs_portd_lo[] = { 2908static struct hda_verb cxt5066_init_verbs_portd_lo[] = {
2769 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2909 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2770 { } /* end */ 2910 { } /* end */
@@ -2783,6 +2923,8 @@ static int cxt5066_init(struct hda_codec *codec)
2783 cxt5066_vostro_automic(codec); 2923 cxt5066_vostro_automic(codec);
2784 else if (spec->ideapad) 2924 else if (spec->ideapad)
2785 cxt5066_ideapad_automic(codec); 2925 cxt5066_ideapad_automic(codec);
2926 else if (spec->thinkpad)
2927 cxt5066_thinkpad_automic(codec);
2786 } 2928 }
2787 cxt5066_set_mic_boost(codec); 2929 cxt5066_set_mic_boost(codec);
2788 return 0; 2930 return 0;
@@ -2804,20 +2946,22 @@ static int cxt5066_olpc_init(struct hda_codec *codec)
2804} 2946}
2805 2947
2806enum { 2948enum {
2807 CXT5066_LAPTOP, /* Laptops w/ EAPD support */ 2949 CXT5066_LAPTOP, /* Laptops w/ EAPD support */
2808 CXT5066_DELL_LAPTOP, /* Dell Laptop */ 2950 CXT5066_DELL_LAPTOP, /* Dell Laptop */
2809 CXT5066_OLPC_XO_1_5, /* OLPC XO 1.5 */ 2951 CXT5066_OLPC_XO_1_5, /* OLPC XO 1.5 */
2810 CXT5066_DELL_VOSTO, /* Dell Vostro 1015i */ 2952 CXT5066_DELL_VOSTO, /* Dell Vostro 1015i */
2811 CXT5066_IDEAPAD, /* Lenovo IdeaPad U150 */ 2953 CXT5066_IDEAPAD, /* Lenovo IdeaPad U150 */
2954 CXT5066_THINKPAD, /* Lenovo ThinkPad T410s, others? */
2812 CXT5066_MODELS 2955 CXT5066_MODELS
2813}; 2956};
2814 2957
2815static const char *cxt5066_models[CXT5066_MODELS] = { 2958static const char *cxt5066_models[CXT5066_MODELS] = {
2816 [CXT5066_LAPTOP] = "laptop", 2959 [CXT5066_LAPTOP] = "laptop",
2817 [CXT5066_DELL_LAPTOP] = "dell-laptop", 2960 [CXT5066_DELL_LAPTOP] = "dell-laptop",
2818 [CXT5066_OLPC_XO_1_5] = "olpc-xo-1_5", 2961 [CXT5066_OLPC_XO_1_5] = "olpc-xo-1_5",
2819 [CXT5066_DELL_VOSTO] = "dell-vostro", 2962 [CXT5066_DELL_VOSTO] = "dell-vostro",
2820 [CXT5066_IDEAPAD] = "ideapad", 2963 [CXT5066_IDEAPAD] = "ideapad",
2964 [CXT5066_THINKPAD] = "thinkpad",
2821}; 2965};
2822 2966
2823static struct snd_pci_quirk cxt5066_cfg_tbl[] = { 2967static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
@@ -2827,7 +2971,14 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
2827 CXT5066_DELL_LAPTOP), 2971 CXT5066_DELL_LAPTOP),
2828 SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5), 2972 SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5),
2829 SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTO), 2973 SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTO),
2974 SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD),
2975 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),
2977 SND_PCI_QUIRK(0x17aa, 0x21b2, "Thinkpad X100e", CXT5066_IDEAPAD),
2978 SND_PCI_QUIRK(0x17aa, 0x21b3, "Thinkpad Edge 13 (197)", CXT5066_IDEAPAD),
2979 SND_PCI_QUIRK(0x17aa, 0x21b4, "Thinkpad Edge", CXT5066_IDEAPAD),
2830 SND_PCI_QUIRK(0x17aa, 0x3a0d, "ideapad", CXT5066_IDEAPAD), 2980 SND_PCI_QUIRK(0x17aa, 0x3a0d, "ideapad", CXT5066_IDEAPAD),
2981 SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD),
2831 {} 2982 {}
2832}; 2983};
2833 2984
@@ -2935,6 +3086,22 @@ static int patch_cxt5066(struct hda_codec *codec)
2935 /* input source automatically selected */ 3086 /* input source automatically selected */
2936 spec->input_mux = NULL; 3087 spec->input_mux = NULL;
2937 break; 3088 break;
3089 case CXT5066_THINKPAD:
3090 codec->patch_ops.init = cxt5066_init;
3091 codec->patch_ops.unsol_event = cxt5066_thinkpad_event;
3092 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
3093 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
3094 spec->init_verbs[0] = cxt5066_init_verbs_thinkpad;
3095 spec->thinkpad = 1;
3096 spec->port_d_mode = PIN_OUT;
3097 spec->mic_boost = 2; /* default 20dB gain */
3098
3099 /* no S/PDIF out */
3100 spec->multiout.dig_out_nid = 0;
3101
3102 /* input source automatically selected */
3103 spec->input_mux = NULL;
3104 break;
2938 } 3105 }
2939 3106
2940 return 0; 3107 return 0;
@@ -2954,6 +3121,8 @@ static struct hda_codec_preset snd_hda_preset_conexant[] = {
2954 .patch = patch_cxt5066 }, 3121 .patch = patch_cxt5066 },
2955 { .id = 0x14f15067, .name = "CX20583 (Pebble HSF)", 3122 { .id = 0x14f15067, .name = "CX20583 (Pebble HSF)",
2956 .patch = patch_cxt5066 }, 3123 .patch = patch_cxt5066 },
3124 { .id = 0x14f15069, .name = "CX20585",
3125 .patch = patch_cxt5066 },
2957 {} /* terminator */ 3126 {} /* terminator */
2958}; 3127};
2959 3128
@@ -2962,6 +3131,7 @@ MODULE_ALIAS("snd-hda-codec-id:14f15047");
2962MODULE_ALIAS("snd-hda-codec-id:14f15051"); 3131MODULE_ALIAS("snd-hda-codec-id:14f15051");
2963MODULE_ALIAS("snd-hda-codec-id:14f15066"); 3132MODULE_ALIAS("snd-hda-codec-id:14f15066");
2964MODULE_ALIAS("snd-hda-codec-id:14f15067"); 3133MODULE_ALIAS("snd-hda-codec-id:14f15067");
3134MODULE_ALIAS("snd-hda-codec-id:14f15069");
2965 3135
2966MODULE_LICENSE("GPL"); 3136MODULE_LICENSE("GPL");
2967MODULE_DESCRIPTION("Conexant HD-audio codec"); 3137MODULE_DESCRIPTION("Conexant HD-audio codec");
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 2c2bafbf0258..86067ee78632 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -766,7 +766,7 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
766 if (spec->num_pins >= MAX_HDMI_PINS) { 766 if (spec->num_pins >= MAX_HDMI_PINS) {
767 snd_printk(KERN_WARNING 767 snd_printk(KERN_WARNING
768 "HDMI: no space for pin %d\n", pin_nid); 768 "HDMI: no space for pin %d\n", pin_nid);
769 return -EINVAL; 769 return -E2BIG;
770 } 770 }
771 771
772 hdmi_present_sense(codec, pin_nid, &spec->sink_eld[spec->num_pins]); 772 hdmi_present_sense(codec, pin_nid, &spec->sink_eld[spec->num_pins]);
@@ -788,7 +788,7 @@ static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t nid)
788 if (spec->num_cvts >= MAX_HDMI_CVTS) { 788 if (spec->num_cvts >= MAX_HDMI_CVTS) {
789 snd_printk(KERN_WARNING 789 snd_printk(KERN_WARNING
790 "HDMI: no space for converter %d\n", nid); 790 "HDMI: no space for converter %d\n", nid);
791 return -EINVAL; 791 return -E2BIG;
792 } 792 }
793 793
794 spec->cvt[spec->num_cvts] = nid; 794 spec->cvt[spec->num_cvts] = nid;
@@ -820,15 +820,13 @@ static int hdmi_parse_codec(struct hda_codec *codec)
820 820
821 switch (type) { 821 switch (type) {
822 case AC_WID_AUD_OUT: 822 case AC_WID_AUD_OUT:
823 if (hdmi_add_cvt(codec, nid) < 0) 823 hdmi_add_cvt(codec, nid);
824 return -EINVAL;
825 break; 824 break;
826 case AC_WID_PIN: 825 case AC_WID_PIN:
827 caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP); 826 caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
828 if (!(caps & (AC_PINCAP_HDMI | AC_PINCAP_DP))) 827 if (!(caps & (AC_PINCAP_HDMI | AC_PINCAP_DP)))
829 continue; 828 continue;
830 if (hdmi_add_pin(codec, nid) < 0) 829 hdmi_add_pin(codec, nid);
831 return -EINVAL;
832 break; 830 break;
833 } 831 }
834 } 832 }
diff --git a/sound/pci/hda/patch_intelhdmi.c b/sound/pci/hda/patch_intelhdmi.c
index 88d035104cc5..b81d23e42ace 100644
--- a/sound/pci/hda/patch_intelhdmi.c
+++ b/sound/pci/hda/patch_intelhdmi.c
@@ -40,7 +40,7 @@
40 * 40 *
41 * The HDA correspondence of pipes/ports are converter/pin nodes. 41 * The HDA correspondence of pipes/ports are converter/pin nodes.
42 */ 42 */
43#define MAX_HDMI_CVTS 2 43#define MAX_HDMI_CVTS 3
44#define MAX_HDMI_PINS 3 44#define MAX_HDMI_PINS 3
45 45
46#include "patch_hdmi.c" 46#include "patch_hdmi.c"
@@ -48,6 +48,7 @@
48static char *intel_hdmi_pcm_names[MAX_HDMI_CVTS] = { 48static char *intel_hdmi_pcm_names[MAX_HDMI_CVTS] = {
49 "INTEL HDMI 0", 49 "INTEL HDMI 0",
50 "INTEL HDMI 1", 50 "INTEL HDMI 1",
51 "INTEL HDMI 2",
51}; 52};
52 53
53/* 54/*
@@ -185,14 +186,15 @@ static int patch_intel_hdmi(struct hda_codec *codec)
185} 186}
186 187
187static struct hda_codec_preset snd_hda_preset_intelhdmi[] = { 188static struct hda_codec_preset snd_hda_preset_intelhdmi[] = {
188 { .id = 0x808629fb, .name = "G45 DEVCL", .patch = patch_intel_hdmi }, 189{ .id = 0x808629fb, .name = "Crestline HDMI", .patch = patch_intel_hdmi },
189 { .id = 0x80862801, .name = "G45 DEVBLC", .patch = patch_intel_hdmi }, 190{ .id = 0x80862801, .name = "Bearlake HDMI", .patch = patch_intel_hdmi },
190 { .id = 0x80862802, .name = "G45 DEVCTG", .patch = patch_intel_hdmi }, 191{ .id = 0x80862802, .name = "Cantiga HDMI", .patch = patch_intel_hdmi },
191 { .id = 0x80862803, .name = "G45 DEVELK", .patch = patch_intel_hdmi }, 192{ .id = 0x80862803, .name = "Eaglelake HDMI", .patch = patch_intel_hdmi },
192 { .id = 0x80862804, .name = "G45 DEVIBX", .patch = patch_intel_hdmi }, 193{ .id = 0x80862804, .name = "IbexPeak HDMI", .patch = patch_intel_hdmi },
193 { .id = 0x80860054, .name = "Q57 DEVIBX", .patch = patch_intel_hdmi }, 194{ .id = 0x80860054, .name = "IbexPeak HDMI", .patch = patch_intel_hdmi },
194 { .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_intel_hdmi }, 195{ .id = 0x80862805, .name = "CougarPoint HDMI", .patch = patch_intel_hdmi },
195 {} /* terminator */ 196{ .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_intel_hdmi },
197{} /* terminator */
196}; 198};
197 199
198MODULE_ALIAS("snd-hda-codec-id:808629fb"); 200MODULE_ALIAS("snd-hda-codec-id:808629fb");
@@ -200,6 +202,7 @@ MODULE_ALIAS("snd-hda-codec-id:80862801");
200MODULE_ALIAS("snd-hda-codec-id:80862802"); 202MODULE_ALIAS("snd-hda-codec-id:80862802");
201MODULE_ALIAS("snd-hda-codec-id:80862803"); 203MODULE_ALIAS("snd-hda-codec-id:80862803");
202MODULE_ALIAS("snd-hda-codec-id:80862804"); 204MODULE_ALIAS("snd-hda-codec-id:80862804");
205MODULE_ALIAS("snd-hda-codec-id:80862805");
203MODULE_ALIAS("snd-hda-codec-id:80860054"); 206MODULE_ALIAS("snd-hda-codec-id:80860054");
204MODULE_ALIAS("snd-hda-codec-id:10951392"); 207MODULE_ALIAS("snd-hda-codec-id:10951392");
205 208
diff --git a/sound/pci/hda/patch_nvhdmi.c b/sound/pci/hda/patch_nvhdmi.c
index 70669a246902..3c10c0b149f4 100644
--- a/sound/pci/hda/patch_nvhdmi.c
+++ b/sound/pci/hda/patch_nvhdmi.c
@@ -538,8 +538,6 @@ static int patch_nvhdmi_2ch(struct hda_codec *codec)
538 * patch entries 538 * patch entries
539 */ 539 */
540static struct hda_codec_preset snd_hda_preset_nvhdmi[] = { 540static struct hda_codec_preset snd_hda_preset_nvhdmi[] = {
541 { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch },
542 { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch },
543 { .id = 0x10de0002, .name = "MCP77/78 HDMI", 541 { .id = 0x10de0002, .name = "MCP77/78 HDMI",
544 .patch = patch_nvhdmi_8ch_7x }, 542 .patch = patch_nvhdmi_8ch_7x },
545 { .id = 0x10de0003, .name = "MCP77/78 HDMI", 543 { .id = 0x10de0003, .name = "MCP77/78 HDMI",
@@ -550,12 +548,16 @@ static struct hda_codec_preset snd_hda_preset_nvhdmi[] = {
550 .patch = patch_nvhdmi_8ch_7x }, 548 .patch = patch_nvhdmi_8ch_7x },
551 { .id = 0x10de0007, .name = "MCP79/7A HDMI", 549 { .id = 0x10de0007, .name = "MCP79/7A HDMI",
552 .patch = patch_nvhdmi_8ch_7x }, 550 .patch = patch_nvhdmi_8ch_7x },
553 { .id = 0x10de000c, .name = "MCP89 HDMI", 551 { .id = 0x10de000a, .name = "GT220 HDMI",
554 .patch = patch_nvhdmi_8ch_89 }, 552 .patch = patch_nvhdmi_8ch_89 },
555 { .id = 0x10de000b, .name = "GT21x HDMI", 553 { .id = 0x10de000b, .name = "GT21x HDMI",
556 .patch = patch_nvhdmi_8ch_89 }, 554 .patch = patch_nvhdmi_8ch_89 },
555 { .id = 0x10de000c, .name = "MCP89 HDMI",
556 .patch = patch_nvhdmi_8ch_89 },
557 { .id = 0x10de000d, .name = "GT240 HDMI", 557 { .id = 0x10de000d, .name = "GT240 HDMI",
558 .patch = patch_nvhdmi_8ch_89 }, 558 .patch = patch_nvhdmi_8ch_89 },
559 { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch },
560 { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch },
559 {} /* terminator */ 561 {} /* terminator */
560}; 562};
561 563
@@ -564,11 +566,12 @@ MODULE_ALIAS("snd-hda-codec-id:10de0003");
564MODULE_ALIAS("snd-hda-codec-id:10de0005"); 566MODULE_ALIAS("snd-hda-codec-id:10de0005");
565MODULE_ALIAS("snd-hda-codec-id:10de0006"); 567MODULE_ALIAS("snd-hda-codec-id:10de0006");
566MODULE_ALIAS("snd-hda-codec-id:10de0007"); 568MODULE_ALIAS("snd-hda-codec-id:10de0007");
567MODULE_ALIAS("snd-hda-codec-id:10de0067"); 569MODULE_ALIAS("snd-hda-codec-id:10de000a");
568MODULE_ALIAS("snd-hda-codec-id:10de8001");
569MODULE_ALIAS("snd-hda-codec-id:10de000c");
570MODULE_ALIAS("snd-hda-codec-id:10de000b"); 570MODULE_ALIAS("snd-hda-codec-id:10de000b");
571MODULE_ALIAS("snd-hda-codec-id:10de000c");
571MODULE_ALIAS("snd-hda-codec-id:10de000d"); 572MODULE_ALIAS("snd-hda-codec-id:10de000d");
573MODULE_ALIAS("snd-hda-codec-id:10de0067");
574MODULE_ALIAS("snd-hda-codec-id:10de8001");
572 575
573MODULE_LICENSE("GPL"); 576MODULE_LICENSE("GPL");
574MODULE_DESCRIPTION("NVIDIA HDMI HD-audio codec"); 577MODULE_DESCRIPTION("NVIDIA HDMI HD-audio codec");
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 4ec57633af88..17d4548cc353 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -230,6 +230,7 @@ enum {
230 ALC888_ACER_ASPIRE_7730G, 230 ALC888_ACER_ASPIRE_7730G,
231 ALC883_MEDION, 231 ALC883_MEDION,
232 ALC883_MEDION_MD2, 232 ALC883_MEDION_MD2,
233 ALC883_MEDION_WIM2160,
233 ALC883_LAPTOP_EAPD, 234 ALC883_LAPTOP_EAPD,
234 ALC883_LENOVO_101E_2ch, 235 ALC883_LENOVO_101E_2ch,
235 ALC883_LENOVO_NB0763, 236 ALC883_LENOVO_NB0763,
@@ -275,6 +276,18 @@ struct alc_mic_route {
275 276
276#define MUX_IDX_UNDEF ((unsigned char)-1) 277#define MUX_IDX_UNDEF ((unsigned char)-1)
277 278
279struct alc_customize_define {
280 unsigned int sku_cfg;
281 unsigned char port_connectivity;
282 unsigned char check_sum;
283 unsigned char customization;
284 unsigned char external_amp;
285 unsigned int enable_pcbeep:1;
286 unsigned int platform_type:1;
287 unsigned int swap:1;
288 unsigned int override:1;
289};
290
278struct alc_spec { 291struct alc_spec {
279 /* codec parameterization */ 292 /* codec parameterization */
280 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ 293 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
@@ -332,6 +345,7 @@ struct alc_spec {
332 345
333 /* dynamic controls, init_verbs and input_mux */ 346 /* dynamic controls, init_verbs and input_mux */
334 struct auto_pin_cfg autocfg; 347 struct auto_pin_cfg autocfg;
348 struct alc_customize_define cdefine;
335 struct snd_array kctls; 349 struct snd_array kctls;
336 struct hda_input_mux private_imux[3]; 350 struct hda_input_mux private_imux[3];
337 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; 351 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
@@ -1247,6 +1261,62 @@ static void alc_init_auto_mic(struct hda_codec *codec)
1247 spec->unsol_event = alc_sku_unsol_event; 1261 spec->unsol_event = alc_sku_unsol_event;
1248} 1262}
1249 1263
1264static int alc_auto_parse_customize_define(struct hda_codec *codec)
1265{
1266 unsigned int ass, tmp, i;
1267 unsigned nid = 0;
1268 struct alc_spec *spec = codec->spec;
1269
1270 ass = codec->subsystem_id & 0xffff;
1271 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
1272 goto do_sku;
1273
1274 nid = 0x1d;
1275 if (codec->vendor_id == 0x10ec0260)
1276 nid = 0x17;
1277 ass = snd_hda_codec_get_pincfg(codec, nid);
1278
1279 if (!(ass & 1)) {
1280 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
1281 codec->chip_name, ass);
1282 return -1;
1283 }
1284
1285 /* check sum */
1286 tmp = 0;
1287 for (i = 1; i < 16; i++) {
1288 if ((ass >> i) & 1)
1289 tmp++;
1290 }
1291 if (((ass >> 16) & 0xf) != tmp)
1292 return -1;
1293
1294 spec->cdefine.port_connectivity = ass >> 30;
1295 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
1296 spec->cdefine.check_sum = (ass >> 16) & 0xf;
1297 spec->cdefine.customization = ass >> 8;
1298do_sku:
1299 spec->cdefine.sku_cfg = ass;
1300 spec->cdefine.external_amp = (ass & 0x38) >> 3;
1301 spec->cdefine.platform_type = (ass & 0x4) >> 2;
1302 spec->cdefine.swap = (ass & 0x2) >> 1;
1303 spec->cdefine.override = ass & 0x1;
1304
1305 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
1306 nid, spec->cdefine.sku_cfg);
1307 snd_printd("SKU: port_connectivity=0x%x\n",
1308 spec->cdefine.port_connectivity);
1309 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
1310 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
1311 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
1312 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
1313 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
1314 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
1315 snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
1316
1317 return 0;
1318}
1319
1250/* check subsystem ID and set up device-specific initialization; 1320/* check subsystem ID and set up device-specific initialization;
1251 * return 1 if initialized, 0 if invalid SSID 1321 * return 1 if initialized, 0 if invalid SSID
1252 */ 1322 */
@@ -1389,22 +1459,31 @@ struct alc_fixup {
1389 1459
1390static void alc_pick_fixup(struct hda_codec *codec, 1460static void alc_pick_fixup(struct hda_codec *codec,
1391 const struct snd_pci_quirk *quirk, 1461 const struct snd_pci_quirk *quirk,
1392 const struct alc_fixup *fix) 1462 const struct alc_fixup *fix,
1463 int pre_init)
1393{ 1464{
1394 const struct alc_pincfg *cfg; 1465 const struct alc_pincfg *cfg;
1395 1466
1396 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk); 1467 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1397 if (!quirk) 1468 if (!quirk)
1398 return; 1469 return;
1399
1400 fix += quirk->value; 1470 fix += quirk->value;
1401 cfg = fix->pins; 1471 cfg = fix->pins;
1402 if (cfg) { 1472 if (pre_init && cfg) {
1473#ifdef CONFIG_SND_DEBUG_VERBOSE
1474 snd_printdd(KERN_INFO "hda_codec: %s: Apply pincfg for %s\n",
1475 codec->chip_name, quirk->name);
1476#endif
1403 for (; cfg->nid; cfg++) 1477 for (; cfg->nid; cfg++)
1404 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val); 1478 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
1405 } 1479 }
1406 if (fix->verbs) 1480 if (!pre_init && fix->verbs) {
1481#ifdef CONFIG_SND_DEBUG_VERBOSE
1482 snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-verbs for %s\n",
1483 codec->chip_name, quirk->name);
1484#endif
1407 add_verb(codec->spec, fix->verbs); 1485 add_verb(codec->spec, fix->verbs);
1486 }
1408} 1487}
1409 1488
1410static int alc_read_coef_idx(struct hda_codec *codec, 1489static int alc_read_coef_idx(struct hda_codec *codec,
@@ -1621,6 +1700,11 @@ static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1621 */ 1700 */
1622 1701
1623static struct hda_verb alc888_acer_aspire_6530g_verbs[] = { 1702static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
1703/* Route to built-in subwoofer as well as speakers */
1704 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1705 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1706 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1707 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1624/* Bias voltage on for external mic port */ 1708/* Bias voltage on for external mic port */
1625 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80}, 1709 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
1626/* Front Mic: set to PIN_IN (empty by default) */ 1710/* Front Mic: set to PIN_IN (empty by default) */
@@ -1632,10 +1716,12 @@ static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
1632/* Enable speaker output */ 1716/* Enable speaker output */
1633 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1717 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1634 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1718 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1719 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
1635/* Enable headphone output */ 1720/* Enable headphone output */
1636 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP}, 1721 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
1637 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1722 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1638 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 1723 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1724 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
1639 { } 1725 { }
1640}; 1726};
1641 1727
@@ -2532,8 +2618,6 @@ static int alc_build_controls(struct hda_codec *codec)
2532 return err; 2618 return err;
2533 } 2619 }
2534 2620
2535 alc_free_kctls(codec); /* no longer needed */
2536
2537 /* assign Capture Source enums to NID */ 2621 /* assign Capture Source enums to NID */
2538 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source"); 2622 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
2539 if (!kctl) 2623 if (!kctl)
@@ -2602,6 +2686,9 @@ static int alc_build_controls(struct hda_codec *codec)
2602 } 2686 }
2603 } 2687 }
2604 } 2688 }
2689
2690 alc_free_kctls(codec); /* no longer needed */
2691
2605 return 0; 2692 return 0;
2606} 2693}
2607 2694
@@ -3397,6 +3484,10 @@ static int alc_init(struct hda_codec *codec)
3397 if (spec->init_hook) 3484 if (spec->init_hook)
3398 spec->init_hook(codec); 3485 spec->init_hook(codec);
3399 3486
3487#ifdef CONFIG_SND_HDA_POWER_SAVE
3488 if (codec->patch_ops.check_power_status)
3489 codec->patch_ops.check_power_status(codec, 0x01);
3490#endif
3400 return 0; 3491 return 0;
3401} 3492}
3402 3493
@@ -3757,6 +3848,10 @@ static int alc_resume(struct hda_codec *codec)
3757 codec->patch_ops.init(codec); 3848 codec->patch_ops.init(codec);
3758 snd_hda_codec_resume_amp(codec); 3849 snd_hda_codec_resume_amp(codec);
3759 snd_hda_codec_resume_cache(codec); 3850 snd_hda_codec_resume_cache(codec);
3851#ifdef CONFIG_SND_HDA_POWER_SAVE
3852 if (codec->patch_ops.check_power_status)
3853 codec->patch_ops.check_power_status(codec, 0x01);
3854#endif
3760 return 0; 3855 return 0;
3761} 3856}
3762#endif 3857#endif
@@ -3779,6 +3874,17 @@ static struct hda_codec_ops alc_patch_ops = {
3779 .reboot_notify = alc_shutup, 3874 .reboot_notify = alc_shutup,
3780}; 3875};
3781 3876
3877/* replace the codec chip_name with the given string */
3878static int alc_codec_rename(struct hda_codec *codec, const char *name)
3879{
3880 kfree(codec->chip_name);
3881 codec->chip_name = kstrdup(name, GFP_KERNEL);
3882 if (!codec->chip_name) {
3883 alc_free(codec);
3884 return -ENOMEM;
3885 }
3886 return 0;
3887}
3782 3888
3783/* 3889/*
3784 * Test configuration for debugging 3890 * Test configuration for debugging
@@ -4125,7 +4231,7 @@ static struct snd_pci_quirk alc880_cfg_tbl[] = {
4125 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG), 4231 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
4126 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734), 4232 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
4127 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU), 4233 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
4128 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL), 4234 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
4129 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU), 4235 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
4130 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW), 4236 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
4131 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG), 4237 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
@@ -4800,6 +4906,25 @@ static void alc880_auto_init_analog_input(struct hda_codec *codec)
4800 } 4906 }
4801} 4907}
4802 4908
4909static void alc880_auto_init_input_src(struct hda_codec *codec)
4910{
4911 struct alc_spec *spec = codec->spec;
4912 int c;
4913
4914 for (c = 0; c < spec->num_adc_nids; c++) {
4915 unsigned int mux_idx;
4916 const struct hda_input_mux *imux;
4917 mux_idx = c >= spec->num_mux_defs ? 0 : c;
4918 imux = &spec->input_mux[mux_idx];
4919 if (!imux->num_items && mux_idx > 0)
4920 imux = &spec->input_mux[0];
4921 if (imux)
4922 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
4923 AC_VERB_SET_CONNECT_SEL,
4924 imux->items[0].index);
4925 }
4926}
4927
4803/* parse the BIOS configuration and set up the alc_spec */ 4928/* parse the BIOS configuration and set up the alc_spec */
4804/* return 1 if successful, 0 if the proper config is not found, 4929/* return 1 if successful, 0 if the proper config is not found,
4805 * or a negative error code 4930 * or a negative error code
@@ -4878,6 +5003,7 @@ static void alc880_auto_init(struct hda_codec *codec)
4878 alc880_auto_init_multi_out(codec); 5003 alc880_auto_init_multi_out(codec);
4879 alc880_auto_init_extra_out(codec); 5004 alc880_auto_init_extra_out(codec);
4880 alc880_auto_init_analog_input(codec); 5005 alc880_auto_init_analog_input(codec);
5006 alc880_auto_init_input_src(codec);
4881 if (spec->unsol_event) 5007 if (spec->unsol_event)
4882 alc_inithook(codec); 5008 alc_inithook(codec);
4883} 5009}
@@ -4983,6 +5109,70 @@ static void set_capture_mixer(struct hda_codec *codec)
4983 } 5109 }
4984} 5110}
4985 5111
5112/* fill adc_nids (and capsrc_nids) containing all active input pins */
5113static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids,
5114 int num_nids)
5115{
5116 struct alc_spec *spec = codec->spec;
5117 int n;
5118 hda_nid_t fallback_adc = 0, fallback_cap = 0;
5119
5120 for (n = 0; n < num_nids; n++) {
5121 hda_nid_t adc, cap;
5122 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
5123 int nconns, i, j;
5124
5125 adc = nids[n];
5126 if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN)
5127 continue;
5128 cap = adc;
5129 nconns = snd_hda_get_connections(codec, cap, conn,
5130 ARRAY_SIZE(conn));
5131 if (nconns == 1) {
5132 cap = conn[0];
5133 nconns = snd_hda_get_connections(codec, cap, conn,
5134 ARRAY_SIZE(conn));
5135 }
5136 if (nconns <= 0)
5137 continue;
5138 if (!fallback_adc) {
5139 fallback_adc = adc;
5140 fallback_cap = cap;
5141 }
5142 for (i = 0; i < AUTO_PIN_LAST; i++) {
5143 hda_nid_t nid = spec->autocfg.input_pins[i];
5144 if (!nid)
5145 continue;
5146 for (j = 0; j < nconns; j++) {
5147 if (conn[j] == nid)
5148 break;
5149 }
5150 if (j >= nconns)
5151 break;
5152 }
5153 if (i >= AUTO_PIN_LAST) {
5154 int num_adcs = spec->num_adc_nids;
5155 spec->private_adc_nids[num_adcs] = adc;
5156 spec->private_capsrc_nids[num_adcs] = cap;
5157 spec->num_adc_nids++;
5158 spec->adc_nids = spec->private_adc_nids;
5159 if (adc != cap)
5160 spec->capsrc_nids = spec->private_capsrc_nids;
5161 }
5162 }
5163 if (!spec->num_adc_nids) {
5164 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
5165 " using fallback 0x%x\n",
5166 codec->chip_name, fallback_adc);
5167 spec->private_adc_nids[0] = fallback_adc;
5168 spec->adc_nids = spec->private_adc_nids;
5169 if (fallback_adc != fallback_cap) {
5170 spec->private_capsrc_nids[0] = fallback_cap;
5171 spec->capsrc_nids = spec->private_adc_nids;
5172 }
5173 }
5174}
5175
4986#ifdef CONFIG_SND_HDA_INPUT_BEEP 5176#ifdef CONFIG_SND_HDA_INPUT_BEEP
4987#define set_beep_amp(spec, nid, idx, dir) \ 5177#define set_beep_amp(spec, nid, idx, dir) \
4988 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir)) 5178 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
@@ -6325,6 +6515,8 @@ static void alc260_auto_init_analog_input(struct hda_codec *codec)
6325 } 6515 }
6326} 6516}
6327 6517
6518#define alc260_auto_init_input_src alc880_auto_init_input_src
6519
6328/* 6520/*
6329 * generic initialization of ADC, input mixers and output mixers 6521 * generic initialization of ADC, input mixers and output mixers
6330 */ 6522 */
@@ -6411,6 +6603,7 @@ static void alc260_auto_init(struct hda_codec *codec)
6411 struct alc_spec *spec = codec->spec; 6603 struct alc_spec *spec = codec->spec;
6412 alc260_auto_init_multi_out(codec); 6604 alc260_auto_init_multi_out(codec);
6413 alc260_auto_init_analog_input(codec); 6605 alc260_auto_init_analog_input(codec);
6606 alc260_auto_init_input_src(codec);
6414 if (spec->unsol_event) 6607 if (spec->unsol_event)
6415 alc_inithook(codec); 6608 alc_inithook(codec);
6416} 6609}
@@ -6832,6 +7025,14 @@ static struct hda_input_mux alc889A_mb31_capture_source = {
6832 }, 7025 },
6833}; 7026};
6834 7027
7028static struct hda_input_mux alc889A_imac91_capture_source = {
7029 .num_items = 2,
7030 .items = {
7031 { "Mic", 0x01 },
7032 { "Line", 0x2 }, /* Not sure! */
7033 },
7034};
7035
6835/* 7036/*
6836 * 2ch mode 7037 * 2ch mode
6837 */ 7038 */
@@ -7293,15 +7494,8 @@ static struct snd_kcontrol_new alc885_macmini3_mixer[] = {
7293}; 7494};
7294 7495
7295static struct snd_kcontrol_new alc885_imac91_mixer[] = { 7496static struct snd_kcontrol_new alc885_imac91_mixer[] = {
7296 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 7497 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7297 HDA_BIND_MUTE ("Line-Out Playback Switch", 0x0c, 0x02, HDA_INPUT), 7498 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
7298 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
7299 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7300 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7301 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7302 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
7303 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
7304 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
7305 { } /* end */ 7499 { } /* end */
7306}; 7500};
7307 7501
@@ -7802,61 +7996,56 @@ static struct hda_verb alc885_mbp3_init_verbs[] = {
7802 7996
7803/* iMac 9,1 */ 7997/* iMac 9,1 */
7804static struct hda_verb alc885_imac91_init_verbs[] = { 7998static struct hda_verb alc885_imac91_init_verbs[] = {
7805 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */ 7999 /* Internal Speaker Pin (0x0c) */
7806 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8000 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
7807 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8001 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7808 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8002 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7809 /* Rear mixer */ 8003 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
7810 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8004 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7811 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8005 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
7812 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8006 /* HP Pin: Rear */
7813 /* HP Pin: output 0 (0x0c) */
7814 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8007 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7815 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8008 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7816 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 8009 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7817 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8010 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
7818 /* Internal Speakers: output 0 (0x0d) */ 8011 /* Line in Rear */
7819 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8012 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
7820 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8013 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7821 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7822 /* Mic (rear) pin: input vref at 80% */
7823 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7824 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7825 /* Front Mic pin: input vref at 80% */ 8014 /* Front Mic pin: input vref at 80% */
7826 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8015 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7827 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8016 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7828 /* Line In pin: use output 1 when in LineOut mode */ 8017 /* Rear mixer */
7829 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 8018 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7830 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8019 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7831 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, 8020 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7832 8021 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
7833 /* FIXME: use matrix-type input source selection */ 8022 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7834 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 8023 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7835 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 8024 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8025 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
7836 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8026 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7837 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8027 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7838 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8028 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7839 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8029 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7840 /* Input mixer2 */ 8030 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
7841 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8031 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7842 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8032 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7843 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8033 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7844 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8034 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7845 /* Input mixer3 */ 8035 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
7846 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8036 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7847 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8037 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7848 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8038 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7849 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8039 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7850 /* ADC1: mute amp left and right */ 8040 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
7851 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8041 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7852 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 8042 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7853 /* ADC2: mute amp left and right */ 8043 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
7854 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8044 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7855 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 8045 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7856 /* ADC3: mute amp left and right */ 8046 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
7857 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8047 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7858 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 8048 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7859
7860 { } 8049 { }
7861}; 8050};
7862 8051
@@ -7925,7 +8114,7 @@ static void alc885_imac91_setup(struct hda_codec *codec)
7925 struct alc_spec *spec = codec->spec; 8114 struct alc_spec *spec = codec->spec;
7926 8115
7927 spec->autocfg.hp_pins[0] = 0x14; 8116 spec->autocfg.hp_pins[0] = 0x14;
7928 spec->autocfg.speaker_pins[0] = 0x15; 8117 spec->autocfg.speaker_pins[0] = 0x18;
7929 spec->autocfg.speaker_pins[1] = 0x1a; 8118 spec->autocfg.speaker_pins[1] = 0x1a;
7930} 8119}
7931 8120
@@ -8383,6 +8572,42 @@ static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
8383 { } /* end */ 8572 { } /* end */
8384}; 8573};
8385 8574
8575static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
8576 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8577 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8578 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8579 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
8580 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
8581 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
8582 { } /* end */
8583};
8584
8585static struct hda_verb alc883_medion_wim2160_verbs[] = {
8586 /* Unmute front mixer */
8587 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8588 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8589
8590 /* Set speaker pin to front mixer */
8591 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8592
8593 /* Init headphone pin */
8594 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8595 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8596 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8597 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8598
8599 { } /* end */
8600};
8601
8602/* toggle speaker-output according to the hp-jack state */
8603static void alc883_medion_wim2160_setup(struct hda_codec *codec)
8604{
8605 struct alc_spec *spec = codec->spec;
8606
8607 spec->autocfg.hp_pins[0] = 0x1a;
8608 spec->autocfg.speaker_pins[0] = 0x15;
8609}
8610
8386static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = { 8611static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
8387 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8612 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8388 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8613 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
@@ -8397,9 +8622,7 @@ static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
8397 8622
8398static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = { 8623static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
8399 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8624 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8400 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8401 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 8625 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8402 HDA_BIND_MUTE("LFE Playback Switch", 0x0f, 2, HDA_INPUT),
8403 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8626 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8404 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8627 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8405 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8628 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
@@ -9094,6 +9317,7 @@ static const char *alc882_models[ALC882_MODEL_LAST] = {
9094 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g", 9317 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
9095 [ALC883_MEDION] = "medion", 9318 [ALC883_MEDION] = "medion",
9096 [ALC883_MEDION_MD2] = "medion-md2", 9319 [ALC883_MEDION_MD2] = "medion-md2",
9320 [ALC883_MEDION_WIM2160] = "medion-wim2160",
9097 [ALC883_LAPTOP_EAPD] = "laptop-eapd", 9321 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
9098 [ALC883_LENOVO_101E_2ch] = "lenovo-101e", 9322 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
9099 [ALC883_LENOVO_NB0763] = "lenovo-nb0763", 9323 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
@@ -9210,6 +9434,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = {
9210 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG), 9434 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
9211 9435
9212 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG), 9436 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
9437 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
9213 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720), 9438 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
9214 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720), 9439 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
9215 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R), 9440 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
@@ -9398,14 +9623,14 @@ static struct alc_config_preset alc882_presets[] = {
9398 .init_hook = alc885_imac24_init_hook, 9623 .init_hook = alc885_imac24_init_hook,
9399 }, 9624 },
9400 [ALC885_IMAC91] = { 9625 [ALC885_IMAC91] = {
9401 .mixers = { alc885_imac91_mixer, alc882_chmode_mixer }, 9626 .mixers = {alc885_imac91_mixer},
9402 .init_verbs = { alc885_imac91_init_verbs, 9627 .init_verbs = { alc885_imac91_init_verbs,
9403 alc880_gpio1_init_verbs }, 9628 alc880_gpio1_init_verbs },
9404 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9629 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9405 .dac_nids = alc882_dac_nids, 9630 .dac_nids = alc882_dac_nids,
9406 .channel_mode = alc885_mbp_4ch_modes, 9631 .channel_mode = alc885_mba21_ch_modes,
9407 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes), 9632 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
9408 .input_mux = &alc882_capture_source, 9633 .input_mux = &alc889A_imac91_capture_source,
9409 .dig_out_nid = ALC882_DIGOUT_NID, 9634 .dig_out_nid = ALC882_DIGOUT_NID,
9410 .dig_in_nid = ALC882_DIGIN_NID, 9635 .dig_in_nid = ALC882_DIGIN_NID,
9411 .unsol_event = alc_automute_amp_unsol_event, 9636 .unsol_event = alc_automute_amp_unsol_event,
@@ -9748,6 +9973,21 @@ static struct alc_config_preset alc882_presets[] = {
9748 .setup = alc883_medion_md2_setup, 9973 .setup = alc883_medion_md2_setup,
9749 .init_hook = alc_automute_amp, 9974 .init_hook = alc_automute_amp,
9750 }, 9975 },
9976 [ALC883_MEDION_WIM2160] = {
9977 .mixers = { alc883_medion_wim2160_mixer },
9978 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
9979 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9980 .dac_nids = alc883_dac_nids,
9981 .dig_out_nid = ALC883_DIGOUT_NID,
9982 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
9983 .adc_nids = alc883_adc_nids,
9984 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9985 .channel_mode = alc883_3ST_2ch_modes,
9986 .input_mux = &alc883_capture_source,
9987 .unsol_event = alc_automute_amp_unsol_event,
9988 .setup = alc883_medion_wim2160_setup,
9989 .init_hook = alc_automute_amp,
9990 },
9751 [ALC883_LAPTOP_EAPD] = { 9991 [ALC883_LAPTOP_EAPD] = {
9752 .mixers = { alc883_base_mixer }, 9992 .mixers = { alc883_base_mixer },
9753 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs }, 9993 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
@@ -10033,19 +10273,20 @@ static int alc882_auto_create_input_ctls(struct hda_codec *codec,
10033 10273
10034static void alc882_auto_set_output_and_unmute(struct hda_codec *codec, 10274static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
10035 hda_nid_t nid, int pin_type, 10275 hda_nid_t nid, int pin_type,
10036 int dac_idx) 10276 hda_nid_t dac)
10037{ 10277{
10038 /* set as output */
10039 struct alc_spec *spec = codec->spec;
10040 int idx; 10278 int idx;
10041 10279
10280 /* set as output */
10042 alc_set_pin_output(codec, nid, pin_type); 10281 alc_set_pin_output(codec, nid, pin_type);
10043 if (spec->multiout.dac_nids[dac_idx] == 0x25) 10282
10283 if (dac == 0x25)
10044 idx = 4; 10284 idx = 4;
10285 else if (dac >= 0x02 && dac <= 0x05)
10286 idx = dac - 2;
10045 else 10287 else
10046 idx = spec->multiout.dac_nids[dac_idx] - 2; 10288 return;
10047 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx); 10289 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
10048
10049} 10290}
10050 10291
10051static void alc882_auto_init_multi_out(struct hda_codec *codec) 10292static void alc882_auto_init_multi_out(struct hda_codec *codec)
@@ -10058,22 +10299,29 @@ static void alc882_auto_init_multi_out(struct hda_codec *codec)
10058 int pin_type = get_pin_type(spec->autocfg.line_out_type); 10299 int pin_type = get_pin_type(spec->autocfg.line_out_type);
10059 if (nid) 10300 if (nid)
10060 alc882_auto_set_output_and_unmute(codec, nid, pin_type, 10301 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
10061 i); 10302 spec->multiout.dac_nids[i]);
10062 } 10303 }
10063} 10304}
10064 10305
10065static void alc882_auto_init_hp_out(struct hda_codec *codec) 10306static void alc882_auto_init_hp_out(struct hda_codec *codec)
10066{ 10307{
10067 struct alc_spec *spec = codec->spec; 10308 struct alc_spec *spec = codec->spec;
10068 hda_nid_t pin; 10309 hda_nid_t pin, dac;
10069 10310
10070 pin = spec->autocfg.hp_pins[0]; 10311 pin = spec->autocfg.hp_pins[0];
10071 if (pin) /* connect to front */ 10312 if (pin) {
10072 /* use dac 0 */ 10313 dac = spec->multiout.hp_nid;
10073 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 10314 if (!dac)
10315 dac = spec->multiout.dac_nids[0]; /* to front */
10316 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
10317 }
10074 pin = spec->autocfg.speaker_pins[0]; 10318 pin = spec->autocfg.speaker_pins[0];
10075 if (pin) 10319 if (pin) {
10076 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); 10320 dac = spec->multiout.extra_out_nid[0];
10321 if (!dac)
10322 dac = spec->multiout.dac_nids[0]; /* to front */
10323 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
10324 }
10077} 10325}
10078 10326
10079static void alc882_auto_init_analog_input(struct hda_codec *codec) 10327static void alc882_auto_init_analog_input(struct hda_codec *codec)
@@ -10189,15 +10437,15 @@ static int alc882_parse_auto_config(struct hda_codec *codec)
10189 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg); 10437 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
10190 if (err < 0) 10438 if (err < 0)
10191 return err; 10439 return err;
10440 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
10441 "Headphone");
10442 if (err < 0)
10443 return err;
10192 err = alc880_auto_create_extra_out(spec, 10444 err = alc880_auto_create_extra_out(spec,
10193 spec->autocfg.speaker_pins[0], 10445 spec->autocfg.speaker_pins[0],
10194 "Speaker"); 10446 "Speaker");
10195 if (err < 0) 10447 if (err < 0)
10196 return err; 10448 return err;
10197 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
10198 "Headphone");
10199 if (err < 0)
10200 return err;
10201 err = alc882_auto_create_input_ctls(codec, &spec->autocfg); 10449 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
10202 if (err < 0) 10450 if (err < 0)
10203 return err; 10451 return err;
@@ -10267,6 +10515,8 @@ static int patch_alc882(struct hda_codec *codec)
10267 10515
10268 codec->spec = spec; 10516 codec->spec = spec;
10269 10517
10518 alc_auto_parse_customize_define(codec);
10519
10270 switch (codec->vendor_id) { 10520 switch (codec->vendor_id) {
10271 case 0x10ec0882: 10521 case 0x10ec0882:
10272 case 0x10ec0885: 10522 case 0x10ec0885:
@@ -10291,7 +10541,8 @@ static int patch_alc882(struct hda_codec *codec)
10291 board_config = ALC882_AUTO; 10541 board_config = ALC882_AUTO;
10292 } 10542 }
10293 10543
10294 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups); 10544 if (board_config == ALC882_AUTO)
10545 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 1);
10295 10546
10296 if (board_config == ALC882_AUTO) { 10547 if (board_config == ALC882_AUTO) {
10297 /* automatic parse from the BIOS config */ 10548 /* automatic parse from the BIOS config */
@@ -10325,9 +10576,6 @@ static int patch_alc882(struct hda_codec *codec)
10325 spec->stream_digital_playback = &alc882_pcm_digital_playback; 10576 spec->stream_digital_playback = &alc882_pcm_digital_playback;
10326 spec->stream_digital_capture = &alc882_pcm_digital_capture; 10577 spec->stream_digital_capture = &alc882_pcm_digital_capture;
10327 10578
10328 if (codec->vendor_id == 0x10ec0888)
10329 spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */
10330
10331 if (!spec->adc_nids && spec->input_mux) { 10579 if (!spec->adc_nids && spec->input_mux) {
10332 int i, j; 10580 int i, j;
10333 spec->num_adc_nids = 0; 10581 spec->num_adc_nids = 0;
@@ -10362,7 +10610,12 @@ static int patch_alc882(struct hda_codec *codec)
10362 } 10610 }
10363 10611
10364 set_capture_mixer(codec); 10612 set_capture_mixer(codec);
10365 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 10613
10614 if (spec->cdefine.enable_pcbeep)
10615 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
10616
10617 if (board_config == ALC882_AUTO)
10618 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 0);
10366 10619
10367 spec->vmaster_nid = 0x0c; 10620 spec->vmaster_nid = 0x0c;
10368 10621
@@ -12146,6 +12399,7 @@ static int patch_alc262(struct hda_codec *codec)
12146 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80); 12399 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
12147 } 12400 }
12148#endif 12401#endif
12402 alc_auto_parse_customize_define(codec);
12149 12403
12150 alc_fix_pll_init(codec, 0x20, 0x0a, 10); 12404 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
12151 12405
@@ -12224,7 +12478,7 @@ static int patch_alc262(struct hda_codec *codec)
12224 } 12478 }
12225 if (!spec->cap_mixer && !spec->no_analog) 12479 if (!spec->cap_mixer && !spec->no_analog)
12226 set_capture_mixer(codec); 12480 set_capture_mixer(codec);
12227 if (!spec->no_analog) 12481 if (!spec->no_analog && spec->cdefine.enable_pcbeep)
12228 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 12482 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
12229 12483
12230 spec->vmaster_nid = 0x0c; 12484 spec->vmaster_nid = 0x0c;
@@ -12455,11 +12709,11 @@ static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
12455 unsigned char bits; 12709 unsigned char bits;
12456 12710
12457 present = snd_hda_jack_detect(codec, 0x15); 12711 present = snd_hda_jack_detect(codec, 0x15);
12458 bits = present ? AMP_IN_MUTE(0) : 0; 12712 bits = present ? HDA_AMP_MUTE : 0;
12459 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0, 12713 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
12460 AMP_IN_MUTE(0), bits); 12714 HDA_AMP_MUTE, bits);
12461 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1, 12715 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
12462 AMP_IN_MUTE(0), bits); 12716 HDA_AMP_MUTE, bits);
12463} 12717}
12464 12718
12465static void alc268_acer_lc_unsol_event(struct hda_codec *codec, 12719static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
@@ -12744,6 +12998,7 @@ static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
12744 dac = 0x02; 12998 dac = 0x02;
12745 break; 12999 break;
12746 case 0x15: 13000 case 0x15:
13001 case 0x21: /* ALC269vb has this pin, too */
12747 dac = 0x03; 13002 dac = 0x03;
12748 break; 13003 break;
12749 default: 13004 default:
@@ -13329,9 +13584,9 @@ static hda_nid_t alc269vb_capsrc_nids[1] = {
13329 0x22, 13584 0x22,
13330}; 13585};
13331 13586
13332/* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24), 13587static hda_nid_t alc269_adc_candidates[] = {
13333 * not a mux! 13588 0x08, 0x09, 0x07,
13334 */ 13589};
13335 13590
13336#define alc269_modes alc260_modes 13591#define alc269_modes alc260_modes
13337#define alc269_capture_source alc880_lg_lw_capture_source 13592#define alc269_capture_source alc880_lg_lw_capture_source
@@ -13478,11 +13733,11 @@ static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
13478 unsigned char bits; 13733 unsigned char bits;
13479 13734
13480 present = snd_hda_jack_detect(codec, 0x15); 13735 present = snd_hda_jack_detect(codec, 0x15);
13481 bits = present ? AMP_IN_MUTE(0) : 0; 13736 bits = present ? HDA_AMP_MUTE : 0;
13482 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 13737 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
13483 AMP_IN_MUTE(0), bits); 13738 HDA_AMP_MUTE, bits);
13484 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 13739 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
13485 AMP_IN_MUTE(0), bits); 13740 HDA_AMP_MUTE, bits);
13486 13741
13487 snd_hda_codec_write(codec, 0x20, 0, 13742 snd_hda_codec_write(codec, 0x20, 0,
13488 AC_VERB_SET_COEF_INDEX, 0x0c); 13743 AC_VERB_SET_COEF_INDEX, 0x0c);
@@ -13507,11 +13762,11 @@ static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
13507 /* Check port replicator headphone socket */ 13762 /* Check port replicator headphone socket */
13508 present |= snd_hda_jack_detect(codec, 0x1a); 13763 present |= snd_hda_jack_detect(codec, 0x1a);
13509 13764
13510 bits = present ? AMP_IN_MUTE(0) : 0; 13765 bits = present ? HDA_AMP_MUTE : 0;
13511 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 13766 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
13512 AMP_IN_MUTE(0), bits); 13767 HDA_AMP_MUTE, bits);
13513 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 13768 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
13514 AMP_IN_MUTE(0), bits); 13769 HDA_AMP_MUTE, bits);
13515 13770
13516 snd_hda_codec_write(codec, 0x20, 0, 13771 snd_hda_codec_write(codec, 0x20, 0,
13517 AC_VERB_SET_COEF_INDEX, 0x0c); 13772 AC_VERB_SET_COEF_INDEX, 0x0c);
@@ -13642,11 +13897,11 @@ static void alc269_speaker_automute(struct hda_codec *codec)
13642 unsigned char bits; 13897 unsigned char bits;
13643 13898
13644 present = snd_hda_jack_detect(codec, nid); 13899 present = snd_hda_jack_detect(codec, nid);
13645 bits = present ? AMP_IN_MUTE(0) : 0; 13900 bits = present ? HDA_AMP_MUTE : 0;
13646 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 13901 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
13647 AMP_IN_MUTE(0), bits); 13902 HDA_AMP_MUTE, bits);
13648 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 13903 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
13649 AMP_IN_MUTE(0), bits); 13904 HDA_AMP_MUTE, bits);
13650} 13905}
13651 13906
13652/* unsolicited event for HP jack sensing */ 13907/* unsolicited event for HP jack sensing */
@@ -13663,19 +13918,19 @@ static void alc269_laptop_unsol_event(struct hda_codec *codec,
13663 } 13918 }
13664} 13919}
13665 13920
13666static void alc269_laptop_dmic_setup(struct hda_codec *codec) 13921static void alc269_laptop_amic_setup(struct hda_codec *codec)
13667{ 13922{
13668 struct alc_spec *spec = codec->spec; 13923 struct alc_spec *spec = codec->spec;
13669 spec->autocfg.hp_pins[0] = 0x15; 13924 spec->autocfg.hp_pins[0] = 0x15;
13670 spec->autocfg.speaker_pins[0] = 0x14; 13925 spec->autocfg.speaker_pins[0] = 0x14;
13671 spec->ext_mic.pin = 0x18; 13926 spec->ext_mic.pin = 0x18;
13672 spec->ext_mic.mux_idx = 0; 13927 spec->ext_mic.mux_idx = 0;
13673 spec->int_mic.pin = 0x12; 13928 spec->int_mic.pin = 0x19;
13674 spec->int_mic.mux_idx = 5; 13929 spec->int_mic.mux_idx = 1;
13675 spec->auto_mic = 1; 13930 spec->auto_mic = 1;
13676} 13931}
13677 13932
13678static void alc269vb_laptop_dmic_setup(struct hda_codec *codec) 13933static void alc269_laptop_dmic_setup(struct hda_codec *codec)
13679{ 13934{
13680 struct alc_spec *spec = codec->spec; 13935 struct alc_spec *spec = codec->spec;
13681 spec->autocfg.hp_pins[0] = 0x15; 13936 spec->autocfg.hp_pins[0] = 0x15;
@@ -13683,14 +13938,14 @@ static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
13683 spec->ext_mic.pin = 0x18; 13938 spec->ext_mic.pin = 0x18;
13684 spec->ext_mic.mux_idx = 0; 13939 spec->ext_mic.mux_idx = 0;
13685 spec->int_mic.pin = 0x12; 13940 spec->int_mic.pin = 0x12;
13686 spec->int_mic.mux_idx = 6; 13941 spec->int_mic.mux_idx = 5;
13687 spec->auto_mic = 1; 13942 spec->auto_mic = 1;
13688} 13943}
13689 13944
13690static void alc269_laptop_amic_setup(struct hda_codec *codec) 13945static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
13691{ 13946{
13692 struct alc_spec *spec = codec->spec; 13947 struct alc_spec *spec = codec->spec;
13693 spec->autocfg.hp_pins[0] = 0x15; 13948 spec->autocfg.hp_pins[0] = 0x21;
13694 spec->autocfg.speaker_pins[0] = 0x14; 13949 spec->autocfg.speaker_pins[0] = 0x14;
13695 spec->ext_mic.pin = 0x18; 13950 spec->ext_mic.pin = 0x18;
13696 spec->ext_mic.mux_idx = 0; 13951 spec->ext_mic.mux_idx = 0;
@@ -13699,6 +13954,18 @@ static void alc269_laptop_amic_setup(struct hda_codec *codec)
13699 spec->auto_mic = 1; 13954 spec->auto_mic = 1;
13700} 13955}
13701 13956
13957static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
13958{
13959 struct alc_spec *spec = codec->spec;
13960 spec->autocfg.hp_pins[0] = 0x21;
13961 spec->autocfg.speaker_pins[0] = 0x14;
13962 spec->ext_mic.pin = 0x18;
13963 spec->ext_mic.mux_idx = 0;
13964 spec->int_mic.pin = 0x12;
13965 spec->int_mic.mux_idx = 6;
13966 spec->auto_mic = 1;
13967}
13968
13702static void alc269_laptop_inithook(struct hda_codec *codec) 13969static void alc269_laptop_inithook(struct hda_codec *codec)
13703{ 13970{
13704 alc269_speaker_automute(codec); 13971 alc269_speaker_automute(codec);
@@ -13830,6 +14097,35 @@ static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
13830 /* NID is set in alc_build_pcms */ 14097 /* NID is set in alc_build_pcms */
13831}; 14098};
13832 14099
14100#ifdef CONFIG_SND_HDA_POWER_SAVE
14101static int alc269_mic2_for_mute_led(struct hda_codec *codec)
14102{
14103 switch (codec->subsystem_id) {
14104 case 0x103c1586:
14105 return 1;
14106 }
14107 return 0;
14108}
14109
14110static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14111{
14112 /* update mute-LED according to the speaker mute state */
14113 if (nid == 0x01 || nid == 0x14) {
14114 int pinval;
14115 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14116 HDA_AMP_MUTE)
14117 pinval = 0x24;
14118 else
14119 pinval = 0x20;
14120 /* mic2 vref pin is used for mute LED control */
14121 snd_hda_codec_update_cache(codec, 0x19, 0,
14122 AC_VERB_SET_PIN_WIDGET_CONTROL,
14123 pinval);
14124 }
14125 return alc_check_power_status(codec, nid);
14126}
14127#endif /* CONFIG_SND_HDA_POWER_SAVE */
14128
13833/* 14129/*
13834 * BIOS auto configuration 14130 * BIOS auto configuration
13835 */ 14131 */
@@ -13838,7 +14134,6 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
13838 struct alc_spec *spec = codec->spec; 14134 struct alc_spec *spec = codec->spec;
13839 int err; 14135 int err;
13840 static hda_nid_t alc269_ignore[] = { 0x1d, 0 }; 14136 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
13841 hda_nid_t real_capsrc_nids;
13842 14137
13843 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 14138 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13844 alc269_ignore); 14139 alc269_ignore);
@@ -13862,18 +14157,19 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
13862 14157
13863 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010) { 14158 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010) {
13864 add_verb(spec, alc269vb_init_verbs); 14159 add_verb(spec, alc269vb_init_verbs);
13865 real_capsrc_nids = alc269vb_capsrc_nids[0];
13866 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21); 14160 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
13867 } else { 14161 } else {
13868 add_verb(spec, alc269_init_verbs); 14162 add_verb(spec, alc269_init_verbs);
13869 real_capsrc_nids = alc269_capsrc_nids[0];
13870 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 14163 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
13871 } 14164 }
13872 14165
13873 spec->num_mux_defs = 1; 14166 spec->num_mux_defs = 1;
13874 spec->input_mux = &spec->private_imux[0]; 14167 spec->input_mux = &spec->private_imux[0];
14168 fillup_priv_adc_nids(codec, alc269_adc_candidates,
14169 sizeof(alc269_adc_candidates));
14170
13875 /* set default input source */ 14171 /* set default input source */
13876 snd_hda_codec_write_cache(codec, real_capsrc_nids, 14172 snd_hda_codec_write_cache(codec, spec->capsrc_nids[0],
13877 0, AC_VERB_SET_CONNECT_SEL, 14173 0, AC_VERB_SET_CONNECT_SEL,
13878 spec->input_mux->items[0].index); 14174 spec->input_mux->items[0].index);
13879 14175
@@ -13903,6 +14199,27 @@ static void alc269_auto_init(struct hda_codec *codec)
13903 alc_inithook(codec); 14199 alc_inithook(codec);
13904} 14200}
13905 14201
14202enum {
14203 ALC269_FIXUP_SONY_VAIO,
14204};
14205
14206static const struct hda_verb alc269_sony_vaio_fixup_verbs[] = {
14207 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14208 {}
14209};
14210
14211static const struct alc_fixup alc269_fixups[] = {
14212 [ALC269_FIXUP_SONY_VAIO] = {
14213 .verbs = alc269_sony_vaio_fixup_verbs
14214 },
14215};
14216
14217static struct snd_pci_quirk alc269_fixup_tbl[] = {
14218 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
14219 {}
14220};
14221
14222
13906/* 14223/*
13907 * configuration and preset 14224 * configuration and preset
13908 */ 14225 */
@@ -13962,7 +14279,7 @@ static struct snd_pci_quirk alc269_cfg_tbl[] = {
13962 ALC269_DMIC), 14279 ALC269_DMIC),
13963 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC), 14280 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
13964 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC), 14281 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
13965 SND_PCI_QUIRK(0x104d, 0x9071, "SONY XTB", ALC269_DMIC), 14282 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
13966 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK), 14283 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
13967 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC), 14284 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
13968 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU), 14285 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
@@ -14036,7 +14353,7 @@ static struct alc_config_preset alc269_presets[] = {
14036 .num_channel_mode = ARRAY_SIZE(alc269_modes), 14353 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14037 .channel_mode = alc269_modes, 14354 .channel_mode = alc269_modes,
14038 .unsol_event = alc269_laptop_unsol_event, 14355 .unsol_event = alc269_laptop_unsol_event,
14039 .setup = alc269_laptop_amic_setup, 14356 .setup = alc269vb_laptop_amic_setup,
14040 .init_hook = alc269_laptop_inithook, 14357 .init_hook = alc269_laptop_inithook,
14041 }, 14358 },
14042 [ALC269VB_DMIC] = { 14359 [ALC269VB_DMIC] = {
@@ -14094,17 +14411,17 @@ static int patch_alc269(struct hda_codec *codec)
14094 14411
14095 codec->spec = spec; 14412 codec->spec = spec;
14096 14413
14097 alc_fix_pll_init(codec, 0x20, 0x04, 15); 14414 alc_auto_parse_customize_define(codec);
14098 14415
14099 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010){ 14416 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010){
14100 kfree(codec->chip_name); 14417 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
14101 codec->chip_name = kstrdup("ALC259", GFP_KERNEL); 14418 spec->cdefine.platform_type == 1)
14102 if (!codec->chip_name) { 14419 alc_codec_rename(codec, "ALC271X");
14103 alc_free(codec); 14420 else
14104 return -ENOMEM; 14421 alc_codec_rename(codec, "ALC259");
14105 }
14106 is_alc269vb = 1; 14422 is_alc269vb = 1;
14107 } 14423 } else
14424 alc_fix_pll_init(codec, 0x20, 0x04, 15);
14108 14425
14109 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST, 14426 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
14110 alc269_models, 14427 alc269_models,
@@ -14116,6 +14433,9 @@ static int patch_alc269(struct hda_codec *codec)
14116 board_config = ALC269_AUTO; 14433 board_config = ALC269_AUTO;
14117 } 14434 }
14118 14435
14436 if (board_config == ALC269_AUTO)
14437 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 1);
14438
14119 if (board_config == ALC269_AUTO) { 14439 if (board_config == ALC269_AUTO) {
14120 /* automatic parse from the BIOS config */ 14440 /* automatic parse from the BIOS config */
14121 err = alc269_parse_auto_config(codec); 14441 err = alc269_parse_auto_config(codec);
@@ -14152,19 +14472,25 @@ static int patch_alc269(struct hda_codec *codec)
14152 spec->stream_digital_playback = &alc269_pcm_digital_playback; 14472 spec->stream_digital_playback = &alc269_pcm_digital_playback;
14153 spec->stream_digital_capture = &alc269_pcm_digital_capture; 14473 spec->stream_digital_capture = &alc269_pcm_digital_capture;
14154 14474
14155 if (!is_alc269vb) { 14475 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
14156 spec->adc_nids = alc269_adc_nids; 14476 if (!is_alc269vb) {
14157 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids); 14477 spec->adc_nids = alc269_adc_nids;
14158 spec->capsrc_nids = alc269_capsrc_nids; 14478 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
14159 } else { 14479 spec->capsrc_nids = alc269_capsrc_nids;
14160 spec->adc_nids = alc269vb_adc_nids; 14480 } else {
14161 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids); 14481 spec->adc_nids = alc269vb_adc_nids;
14162 spec->capsrc_nids = alc269vb_capsrc_nids; 14482 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
14483 spec->capsrc_nids = alc269vb_capsrc_nids;
14484 }
14163 } 14485 }
14164 14486
14165 if (!spec->cap_mixer) 14487 if (!spec->cap_mixer)
14166 set_capture_mixer(codec); 14488 set_capture_mixer(codec);
14167 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); 14489 if (spec->cdefine.enable_pcbeep)
14490 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
14491
14492 if (board_config == ALC269_AUTO)
14493 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 0);
14168 14494
14169 spec->vmaster_nid = 0x02; 14495 spec->vmaster_nid = 0x02;
14170 14496
@@ -14174,6 +14500,8 @@ static int patch_alc269(struct hda_codec *codec)
14174#ifdef CONFIG_SND_HDA_POWER_SAVE 14500#ifdef CONFIG_SND_HDA_POWER_SAVE
14175 if (!spec->loopback.amplist) 14501 if (!spec->loopback.amplist)
14176 spec->loopback.amplist = alc269_loopbacks; 14502 spec->loopback.amplist = alc269_loopbacks;
14503 if (alc269_mic2_for_mute_led(codec))
14504 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
14177#endif 14505#endif
14178 14506
14179 return 0; 14507 return 0;
@@ -15254,7 +15582,8 @@ static int patch_alc861(struct hda_codec *codec)
15254 board_config = ALC861_AUTO; 15582 board_config = ALC861_AUTO;
15255 } 15583 }
15256 15584
15257 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups); 15585 if (board_config == ALC861_AUTO)
15586 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 1);
15258 15587
15259 if (board_config == ALC861_AUTO) { 15588 if (board_config == ALC861_AUTO) {
15260 /* automatic parse from the BIOS config */ 15589 /* automatic parse from the BIOS config */
@@ -15291,6 +15620,9 @@ static int patch_alc861(struct hda_codec *codec)
15291 15620
15292 spec->vmaster_nid = 0x03; 15621 spec->vmaster_nid = 0x03;
15293 15622
15623 if (board_config == ALC861_AUTO)
15624 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 0);
15625
15294 codec->patch_ops = alc_patch_ops; 15626 codec->patch_ops = alc_patch_ops;
15295 if (board_config == ALC861_AUTO) { 15627 if (board_config == ALC861_AUTO) {
15296 spec->init_hook = alc861_auto_init; 15628 spec->init_hook = alc861_auto_init;
@@ -16225,7 +16557,8 @@ static int patch_alc861vd(struct hda_codec *codec)
16225 board_config = ALC861VD_AUTO; 16557 board_config = ALC861VD_AUTO;
16226 } 16558 }
16227 16559
16228 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups); 16560 if (board_config == ALC861VD_AUTO)
16561 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 1);
16229 16562
16230 if (board_config == ALC861VD_AUTO) { 16563 if (board_config == ALC861VD_AUTO) {
16231 /* automatic parse from the BIOS config */ 16564 /* automatic parse from the BIOS config */
@@ -16273,6 +16606,9 @@ static int patch_alc861vd(struct hda_codec *codec)
16273 16606
16274 spec->vmaster_nid = 0x02; 16607 spec->vmaster_nid = 0x02;
16275 16608
16609 if (board_config == ALC861VD_AUTO)
16610 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 0);
16611
16276 codec->patch_ops = alc_patch_ops; 16612 codec->patch_ops = alc_patch_ops;
16277 16613
16278 if (board_config == ALC861VD_AUTO) 16614 if (board_config == ALC861VD_AUTO)
@@ -17111,9 +17447,9 @@ static void alc663_m51va_speaker_automute(struct hda_codec *codec)
17111 present = snd_hda_jack_detect(codec, 0x21); 17447 present = snd_hda_jack_detect(codec, 0x21);
17112 bits = present ? HDA_AMP_MUTE : 0; 17448 bits = present ? HDA_AMP_MUTE : 0;
17113 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 17449 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
17114 AMP_IN_MUTE(0), bits); 17450 HDA_AMP_MUTE, bits);
17115 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 17451 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
17116 AMP_IN_MUTE(0), bits); 17452 HDA_AMP_MUTE, bits);
17117} 17453}
17118 17454
17119static void alc663_21jd_two_speaker_automute(struct hda_codec *codec) 17455static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
@@ -17124,13 +17460,13 @@ static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
17124 present = snd_hda_jack_detect(codec, 0x21); 17460 present = snd_hda_jack_detect(codec, 0x21);
17125 bits = present ? HDA_AMP_MUTE : 0; 17461 bits = present ? HDA_AMP_MUTE : 0;
17126 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 17462 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
17127 AMP_IN_MUTE(0), bits); 17463 HDA_AMP_MUTE, bits);
17128 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 17464 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
17129 AMP_IN_MUTE(0), bits); 17465 HDA_AMP_MUTE, bits);
17130 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0, 17466 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
17131 AMP_IN_MUTE(0), bits); 17467 HDA_AMP_MUTE, bits);
17132 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1, 17468 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
17133 AMP_IN_MUTE(0), bits); 17469 HDA_AMP_MUTE, bits);
17134} 17470}
17135 17471
17136static void alc663_15jd_two_speaker_automute(struct hda_codec *codec) 17472static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
@@ -17141,13 +17477,13 @@ static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
17141 present = snd_hda_jack_detect(codec, 0x15); 17477 present = snd_hda_jack_detect(codec, 0x15);
17142 bits = present ? HDA_AMP_MUTE : 0; 17478 bits = present ? HDA_AMP_MUTE : 0;
17143 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 17479 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
17144 AMP_IN_MUTE(0), bits); 17480 HDA_AMP_MUTE, bits);
17145 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 17481 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
17146 AMP_IN_MUTE(0), bits); 17482 HDA_AMP_MUTE, bits);
17147 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0, 17483 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
17148 AMP_IN_MUTE(0), bits); 17484 HDA_AMP_MUTE, bits);
17149 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1, 17485 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
17150 AMP_IN_MUTE(0), bits); 17486 HDA_AMP_MUTE, bits);
17151} 17487}
17152 17488
17153static void alc662_f5z_speaker_automute(struct hda_codec *codec) 17489static void alc662_f5z_speaker_automute(struct hda_codec *codec)
@@ -17186,14 +17522,14 @@ static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
17186 17522
17187 if (present1 || present2) { 17523 if (present1 || present2) {
17188 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 17524 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
17189 AMP_IN_MUTE(0), AMP_IN_MUTE(0)); 17525 HDA_AMP_MUTE, HDA_AMP_MUTE);
17190 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 17526 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
17191 AMP_IN_MUTE(0), AMP_IN_MUTE(0)); 17527 HDA_AMP_MUTE, HDA_AMP_MUTE);
17192 } else { 17528 } else {
17193 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 17529 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
17194 AMP_IN_MUTE(0), 0); 17530 HDA_AMP_MUTE, 0);
17195 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 17531 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
17196 AMP_IN_MUTE(0), 0); 17532 HDA_AMP_MUTE, 0);
17197 } 17533 }
17198} 17534}
17199 17535
@@ -17659,7 +17995,6 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = {
17659 ALC662_3ST_6ch_DIG), 17995 ALC662_3ST_6ch_DIG),
17660 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x", 17996 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
17661 ALC663_ASUS_H13), 17997 ALC663_ASUS_H13),
17662 SND_PCI_QUIRK(0x8086, 0xd604, "Intel mobo", ALC662_3ST_2ch_DIG),
17663 {} 17998 {}
17664}; 17999};
17665 18000
@@ -18314,16 +18649,16 @@ static int patch_alc662(struct hda_codec *codec)
18314 18649
18315 codec->spec = spec; 18650 codec->spec = spec;
18316 18651
18652 alc_auto_parse_customize_define(codec);
18653
18317 alc_fix_pll_init(codec, 0x20, 0x04, 15); 18654 alc_fix_pll_init(codec, 0x20, 0x04, 15);
18318 18655
18319 if (alc_read_coef_idx(codec, 0)==0x8020){ 18656 if (alc_read_coef_idx(codec, 0) == 0x8020)
18320 kfree(codec->chip_name); 18657 alc_codec_rename(codec, "ALC661");
18321 codec->chip_name = kstrdup("ALC661", GFP_KERNEL); 18658 else if ((alc_read_coef_idx(codec, 0) & (1 << 14)) &&
18322 if (!codec->chip_name) { 18659 codec->bus->pci->subsystem_vendor == 0x1025 &&
18323 alc_free(codec); 18660 spec->cdefine.platform_type == 1)
18324 return -ENOMEM; 18661 alc_codec_rename(codec, "ALC272X");
18325 }
18326 }
18327 18662
18328 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST, 18663 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
18329 alc662_models, 18664 alc662_models,
@@ -18373,18 +18708,20 @@ static int patch_alc662(struct hda_codec *codec)
18373 if (!spec->cap_mixer) 18708 if (!spec->cap_mixer)
18374 set_capture_mixer(codec); 18709 set_capture_mixer(codec);
18375 18710
18376 switch (codec->vendor_id) { 18711 if (spec->cdefine.enable_pcbeep) {
18377 case 0x10ec0662: 18712 switch (codec->vendor_id) {
18378 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 18713 case 0x10ec0662:
18379 break; 18714 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
18380 case 0x10ec0272: 18715 break;
18381 case 0x10ec0663: 18716 case 0x10ec0272:
18382 case 0x10ec0665: 18717 case 0x10ec0663:
18383 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); 18718 case 0x10ec0665:
18384 break; 18719 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
18385 case 0x10ec0273: 18720 break;
18386 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT); 18721 case 0x10ec0273:
18387 break; 18722 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
18723 break;
18724 }
18388 } 18725 }
18389 spec->vmaster_nid = 0x02; 18726 spec->vmaster_nid = 0x02;
18390 18727
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 8c416bb18a57..f1e7babd6920 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -104,6 +104,7 @@ enum {
104 STAC_DELL_M4_2, 104 STAC_DELL_M4_2,
105 STAC_DELL_M4_3, 105 STAC_DELL_M4_3,
106 STAC_HP_M4, 106 STAC_HP_M4,
107 STAC_HP_DV4,
107 STAC_HP_DV5, 108 STAC_HP_DV5,
108 STAC_HP_HDX, 109 STAC_HP_HDX,
109 STAC_HP_DV4_1222NR, 110 STAC_HP_DV4_1222NR,
@@ -1544,11 +1545,9 @@ static unsigned int alienware_m17x_pin_configs[13] = {
1544 0x904601b0, 1545 0x904601b0,
1545}; 1546};
1546 1547
1547static unsigned int intel_dg45id_pin_configs[14] = { 1548static unsigned int intel_dg45id_pin_configs[13] = {
1548 0x02214230, 0x02A19240, 0x01013214, 0x01014210, 1549 0x02214230, 0x02A19240, 0x01013214, 0x01014210,
1549 0x01A19250, 0x01011212, 0x01016211, 0x40f000f0, 1550 0x01A19250, 0x01011212, 0x01016211
1550 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x014510A0,
1551 0x074510B0, 0x40f000f0
1552}; 1551};
1553 1552
1554static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = { 1553static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = {
@@ -1607,6 +1606,10 @@ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = {
1607 "Dell Studio 1555", STAC_DELL_M6_DMIC), 1606 "Dell Studio 1555", STAC_DELL_M6_DMIC),
1608 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02bd, 1607 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02bd,
1609 "Dell Studio 1557", STAC_DELL_M6_DMIC), 1608 "Dell Studio 1557", STAC_DELL_M6_DMIC),
1609 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02fe,
1610 "Dell Studio XPS 1645", STAC_DELL_M6_BOTH),
1611 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0413,
1612 "Dell Studio 1558", STAC_DELL_M6_BOTH),
1610 {} /* terminator */ 1613 {} /* terminator */
1611}; 1614};
1612 1615
@@ -1689,6 +1692,7 @@ static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = {
1689 [STAC_DELL_M4_2] = dell_m4_2_pin_configs, 1692 [STAC_DELL_M4_2] = dell_m4_2_pin_configs,
1690 [STAC_DELL_M4_3] = dell_m4_3_pin_configs, 1693 [STAC_DELL_M4_3] = dell_m4_3_pin_configs,
1691 [STAC_HP_M4] = NULL, 1694 [STAC_HP_M4] = NULL,
1695 [STAC_HP_DV4] = NULL,
1692 [STAC_HP_DV5] = NULL, 1696 [STAC_HP_DV5] = NULL,
1693 [STAC_HP_HDX] = NULL, 1697 [STAC_HP_HDX] = NULL,
1694 [STAC_HP_DV4_1222NR] = NULL, 1698 [STAC_HP_DV4_1222NR] = NULL,
@@ -1701,6 +1705,7 @@ static const char *stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = {
1701 [STAC_DELL_M4_2] = "dell-m4-2", 1705 [STAC_DELL_M4_2] = "dell-m4-2",
1702 [STAC_DELL_M4_3] = "dell-m4-3", 1706 [STAC_DELL_M4_3] = "dell-m4-3",
1703 [STAC_HP_M4] = "hp-m4", 1707 [STAC_HP_M4] = "hp-m4",
1708 [STAC_HP_DV4] = "hp-dv4",
1704 [STAC_HP_DV5] = "hp-dv5", 1709 [STAC_HP_DV5] = "hp-dv5",
1705 [STAC_HP_HDX] = "hp-hdx", 1710 [STAC_HP_HDX] = "hp-hdx",
1706 [STAC_HP_DV4_1222NR] = "hp-dv4-1222nr", 1711 [STAC_HP_DV4_1222NR] = "hp-dv4-1222nr",
@@ -1719,7 +1724,7 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = {
1719 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3080, 1724 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3080,
1720 "HP", STAC_HP_DV5), 1725 "HP", STAC_HP_DV5),
1721 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x30f0, 1726 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x30f0,
1722 "HP dv4-7", STAC_HP_DV5), 1727 "HP dv4-7", STAC_HP_DV4),
1723 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3600, 1728 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3600,
1724 "HP dv4-7", STAC_HP_DV5), 1729 "HP dv4-7", STAC_HP_DV5),
1725 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3610, 1730 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3610,
@@ -1730,6 +1735,8 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = {
1730 "HP HDX", STAC_HP_HDX), /* HDX16 */ 1735 "HP HDX", STAC_HP_HDX), /* HDX16 */
1731 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3620, 1736 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3620,
1732 "HP dv6", STAC_HP_DV5), 1737 "HP dv6", STAC_HP_DV5),
1738 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3061,
1739 "HP dv6", STAC_HP_DV5), /* HP dv6-1110ax */
1733 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x7010, 1740 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x7010,
1734 "HP", STAC_HP_DV5), 1741 "HP", STAC_HP_DV5),
1735 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233, 1742 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233,
@@ -2071,12 +2078,12 @@ static struct snd_pci_quirk stac927x_cfg_tbl[] = {
2071 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2000, 2078 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2000,
2072 "Intel D965", STAC_D965_3ST), 2079 "Intel D965", STAC_D965_3ST),
2073 /* Dell 3 stack systems */ 2080 /* Dell 3 stack systems */
2074 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f7, "Dell XPS M1730", STAC_DELL_3ST),
2075 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01dd, "Dell Dimension E520", STAC_DELL_3ST), 2081 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01dd, "Dell Dimension E520", STAC_DELL_3ST),
2076 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ed, "Dell ", STAC_DELL_3ST), 2082 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ed, "Dell ", STAC_DELL_3ST),
2077 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f4, "Dell ", STAC_DELL_3ST), 2083 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f4, "Dell ", STAC_DELL_3ST),
2078 /* Dell 3 stack systems with verb table in BIOS */ 2084 /* Dell 3 stack systems with verb table in BIOS */
2079 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f3, "Dell Inspiron 1420", STAC_DELL_BIOS), 2085 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f3, "Dell Inspiron 1420", STAC_DELL_BIOS),
2086 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f7, "Dell XPS M1730", STAC_DELL_BIOS),
2080 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0227, "Dell Vostro 1400 ", STAC_DELL_BIOS), 2087 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0227, "Dell Vostro 1400 ", STAC_DELL_BIOS),
2081 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022e, "Dell ", STAC_DELL_BIOS), 2088 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022e, "Dell ", STAC_DELL_BIOS),
2082 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022f, "Dell Inspiron 1525", STAC_DELL_BIOS), 2089 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022f, "Dell Inspiron 1525", STAC_DELL_BIOS),
@@ -4762,6 +4769,9 @@ static void set_hp_led_gpio(struct hda_codec *codec)
4762 struct sigmatel_spec *spec = codec->spec; 4769 struct sigmatel_spec *spec = codec->spec;
4763 unsigned int gpio; 4770 unsigned int gpio;
4764 4771
4772 if (spec->gpio_led)
4773 return;
4774
4765 gpio = snd_hda_param_read(codec, codec->afg, AC_PAR_GPIO_CAP); 4775 gpio = snd_hda_param_read(codec, codec->afg, AC_PAR_GPIO_CAP);
4766 gpio &= AC_GPIO_IO_COUNT; 4776 gpio &= AC_GPIO_IO_COUNT;
4767 if (gpio > 3) 4777 if (gpio > 3)
@@ -5671,6 +5681,9 @@ again:
5671 spec->num_smuxes = 1; 5681 spec->num_smuxes = 1;
5672 spec->num_dmuxes = 1; 5682 spec->num_dmuxes = 1;
5673 /* fallthrough */ 5683 /* fallthrough */
5684 case STAC_HP_DV4:
5685 spec->gpio_led = 0x01;
5686 /* fallthrough */
5674 case STAC_HP_DV5: 5687 case STAC_HP_DV5:
5675 snd_hda_codec_set_pincfg(codec, 0x0d, 0x90170010); 5688 snd_hda_codec_set_pincfg(codec, 0x0d, 0x90170010);
5676 stac92xx_auto_set_pinctl(codec, 0x0d, AC_PINCTL_OUT_EN); 5689 stac92xx_auto_set_pinctl(codec, 0x0d, AC_PINCTL_OUT_EN);
@@ -5684,6 +5697,7 @@ again:
5684 spec->num_dmics = 1; 5697 spec->num_dmics = 1;
5685 spec->num_dmuxes = 1; 5698 spec->num_dmuxes = 1;
5686 spec->num_smuxes = 1; 5699 spec->num_smuxes = 1;
5700 spec->gpio_led = 0x08;
5687 break; 5701 break;
5688 } 5702 }
5689 5703
@@ -5740,7 +5754,8 @@ again:
5740 } 5754 }
5741 5755
5742 /* enable bass on HP dv7 */ 5756 /* enable bass on HP dv7 */
5743 if (spec->board_config == STAC_HP_DV5) { 5757 if (spec->board_config == STAC_HP_DV4 ||
5758 spec->board_config == STAC_HP_DV5) {
5744 unsigned int cap; 5759 unsigned int cap;
5745 cap = snd_hda_param_read(codec, 0x1, AC_PAR_GPIO_CAP); 5760 cap = snd_hda_param_read(codec, 0x1, AC_PAR_GPIO_CAP);
5746 cap &= AC_GPIO_IO_COUNT; 5761 cap &= AC_GPIO_IO_COUNT;
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index 9ddc37300f6b..73453814e098 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -476,7 +476,7 @@ static struct snd_kcontrol_new *via_clone_control(struct via_spec *spec,
476 knew->name = kstrdup(tmpl->name, GFP_KERNEL); 476 knew->name = kstrdup(tmpl->name, GFP_KERNEL);
477 if (!knew->name) 477 if (!knew->name)
478 return NULL; 478 return NULL;
479 return 0; 479 return knew;
480} 480}
481 481
482static void via_free_kctls(struct hda_codec *codec) 482static void via_free_kctls(struct hda_codec *codec)
@@ -1215,14 +1215,13 @@ static struct snd_kcontrol_new via_hp_mixer[2] = {
1215 }, 1215 },
1216}; 1216};
1217 1217
1218static int via_hp_build(struct via_spec *spec) 1218static int via_hp_build(struct hda_codec *codec)
1219{ 1219{
1220 struct via_spec *spec = codec->spec;
1220 struct snd_kcontrol_new *knew; 1221 struct snd_kcontrol_new *knew;
1221 hda_nid_t nid; 1222 hda_nid_t nid;
1222 1223 int nums;
1223 knew = via_clone_control(spec, &via_hp_mixer[0]); 1224 hda_nid_t conn[HDA_MAX_CONNECTIONS];
1224 if (knew == NULL)
1225 return -ENOMEM;
1226 1225
1227 switch (spec->codec_type) { 1226 switch (spec->codec_type) {
1228 case VT1718S: 1227 case VT1718S:
@@ -1239,6 +1238,14 @@ static int via_hp_build(struct via_spec *spec)
1239 break; 1238 break;
1240 } 1239 }
1241 1240
1241 nums = snd_hda_get_connections(codec, nid, conn, HDA_MAX_CONNECTIONS);
1242 if (nums <= 1)
1243 return 0;
1244
1245 knew = via_clone_control(spec, &via_hp_mixer[0]);
1246 if (knew == NULL)
1247 return -ENOMEM;
1248
1242 knew->subdevice = HDA_SUBDEV_NID_FLAG | nid; 1249 knew->subdevice = HDA_SUBDEV_NID_FLAG | nid;
1243 knew->private_value = nid; 1250 knew->private_value = nid;
1244 1251
@@ -2561,7 +2568,7 @@ static int vt1708_parse_auto_config(struct hda_codec *codec)
2561 spec->input_mux = &spec->private_imux[0]; 2568 spec->input_mux = &spec->private_imux[0];
2562 2569
2563 if (spec->hp_mux) 2570 if (spec->hp_mux)
2564 via_hp_build(spec); 2571 via_hp_build(codec);
2565 2572
2566 via_smart51_build(spec); 2573 via_smart51_build(spec);
2567 return 1; 2574 return 1;
@@ -3087,7 +3094,7 @@ static int vt1709_parse_auto_config(struct hda_codec *codec)
3087 spec->input_mux = &spec->private_imux[0]; 3094 spec->input_mux = &spec->private_imux[0];
3088 3095
3089 if (spec->hp_mux) 3096 if (spec->hp_mux)
3090 via_hp_build(spec); 3097 via_hp_build(codec);
3091 3098
3092 via_smart51_build(spec); 3099 via_smart51_build(spec);
3093 return 1; 3100 return 1;
@@ -3654,7 +3661,7 @@ static int vt1708B_parse_auto_config(struct hda_codec *codec)
3654 spec->input_mux = &spec->private_imux[0]; 3661 spec->input_mux = &spec->private_imux[0];
3655 3662
3656 if (spec->hp_mux) 3663 if (spec->hp_mux)
3657 via_hp_build(spec); 3664 via_hp_build(codec);
3658 3665
3659 via_smart51_build(spec); 3666 via_smart51_build(spec);
3660 return 1; 3667 return 1;
@@ -4140,7 +4147,7 @@ static int vt1708S_parse_auto_config(struct hda_codec *codec)
4140 spec->input_mux = &spec->private_imux[0]; 4147 spec->input_mux = &spec->private_imux[0];
4141 4148
4142 if (spec->hp_mux) 4149 if (spec->hp_mux)
4143 via_hp_build(spec); 4150 via_hp_build(codec);
4144 4151
4145 via_smart51_build(spec); 4152 via_smart51_build(spec);
4146 return 1; 4153 return 1;
@@ -4510,7 +4517,7 @@ static int vt1702_parse_auto_config(struct hda_codec *codec)
4510 spec->input_mux = &spec->private_imux[0]; 4517 spec->input_mux = &spec->private_imux[0];
4511 4518
4512 if (spec->hp_mux) 4519 if (spec->hp_mux)
4513 via_hp_build(spec); 4520 via_hp_build(codec);
4514 4521
4515 return 1; 4522 return 1;
4516} 4523}
@@ -4930,7 +4937,7 @@ static int vt1718S_parse_auto_config(struct hda_codec *codec)
4930 spec->input_mux = &spec->private_imux[0]; 4937 spec->input_mux = &spec->private_imux[0];
4931 4938
4932 if (spec->hp_mux) 4939 if (spec->hp_mux)
4933 via_hp_build(spec); 4940 via_hp_build(codec);
4934 4941
4935 via_smart51_build(spec); 4942 via_smart51_build(spec);
4936 4943
@@ -5425,7 +5432,7 @@ static int vt1716S_parse_auto_config(struct hda_codec *codec)
5425 spec->input_mux = &spec->private_imux[0]; 5432 spec->input_mux = &spec->private_imux[0];
5426 5433
5427 if (spec->hp_mux) 5434 if (spec->hp_mux)
5428 via_hp_build(spec); 5435 via_hp_build(codec);
5429 5436
5430 via_smart51_build(spec); 5437 via_smart51_build(spec);
5431 5438
@@ -5781,7 +5788,7 @@ static int vt2002P_parse_auto_config(struct hda_codec *codec)
5781 spec->input_mux = &spec->private_imux[0]; 5788 spec->input_mux = &spec->private_imux[0];
5782 5789
5783 if (spec->hp_mux) 5790 if (spec->hp_mux)
5784 via_hp_build(spec); 5791 via_hp_build(codec);
5785 5792
5786 return 1; 5793 return 1;
5787} 5794}
@@ -6000,12 +6007,12 @@ static int vt1812_auto_create_multi_out_ctls(struct via_spec *spec,
6000 6007
6001 /* Line-Out: PortE */ 6008 /* Line-Out: PortE */
6002 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 6009 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
6003 "Master Front Playback Volume", 6010 "Front Playback Volume",
6004 HDA_COMPOSE_AMP_VAL(0x8, 3, 0, HDA_OUTPUT)); 6011 HDA_COMPOSE_AMP_VAL(0x8, 3, 0, HDA_OUTPUT));
6005 if (err < 0) 6012 if (err < 0)
6006 return err; 6013 return err;
6007 err = via_add_control(spec, VIA_CTL_WIDGET_BIND_PIN_MUTE, 6014 err = via_add_control(spec, VIA_CTL_WIDGET_BIND_PIN_MUTE,
6008 "Master Front Playback Switch", 6015 "Front Playback Switch",
6009 HDA_COMPOSE_AMP_VAL(0x28, 3, 0, HDA_OUTPUT)); 6016 HDA_COMPOSE_AMP_VAL(0x28, 3, 0, HDA_OUTPUT));
6010 if (err < 0) 6017 if (err < 0)
6011 return err; 6018 return err;
@@ -6130,7 +6137,7 @@ static int vt1812_parse_auto_config(struct hda_codec *codec)
6130 spec->input_mux = &spec->private_imux[0]; 6137 spec->input_mux = &spec->private_imux[0];
6131 6138
6132 if (spec->hp_mux) 6139 if (spec->hp_mux)
6133 via_hp_build(spec); 6140 via_hp_build(codec);
6134 6141
6135 return 1; 6142 return 1;
6136} 6143}
diff --git a/sound/pci/ice1712/ak4xxx.c b/sound/pci/ice1712/ak4xxx.c
index 03391da8c8c7..90d560c3df13 100644
--- a/sound/pci/ice1712/ak4xxx.c
+++ b/sound/pci/ice1712/ak4xxx.c
@@ -24,6 +24,7 @@
24#include <asm/io.h> 24#include <asm/io.h>
25#include <linux/delay.h> 25#include <linux/delay.h>
26#include <linux/interrupt.h> 26#include <linux/interrupt.h>
27#include <linux/slab.h>
27#include <linux/init.h> 28#include <linux/init.h>
28#include <sound/core.h> 29#include <sound/core.h>
29#include <sound/initval.h> 30#include <sound/initval.h>
diff --git a/sound/pci/ice1712/amp.c b/sound/pci/ice1712/amp.c
index 6da21a2bcade..e328cfb7620c 100644
--- a/sound/pci/ice1712/amp.c
+++ b/sound/pci/ice1712/amp.c
@@ -25,7 +25,6 @@
25#include <linux/delay.h> 25#include <linux/delay.h>
26#include <linux/interrupt.h> 26#include <linux/interrupt.h>
27#include <linux/init.h> 27#include <linux/init.h>
28#include <linux/slab.h>
29#include <sound/core.h> 28#include <sound/core.h>
30 29
31#include "ice1712.h" 30#include "ice1712.h"
diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c
index 9e66f6d306f8..2f6252266a02 100644
--- a/sound/pci/ice1712/aureon.c
+++ b/sound/pci/ice1712/aureon.c
@@ -1956,11 +1956,10 @@ static int __devinit aureon_add_controls(struct snd_ice1712 *ice)
1956 return 0; 1956 return 0;
1957} 1957}
1958 1958
1959
1960/* 1959/*
1961 * initialize the chip 1960 * reset the chip
1962 */ 1961 */
1963static int __devinit aureon_init(struct snd_ice1712 *ice) 1962static int aureon_reset(struct snd_ice1712 *ice)
1964{ 1963{
1965 static const unsigned short wm_inits_aureon[] = { 1964 static const unsigned short wm_inits_aureon[] = {
1966 /* These come first to reduce init pop noise */ 1965 /* These come first to reduce init pop noise */
@@ -2047,30 +2046,10 @@ static int __devinit aureon_init(struct snd_ice1712 *ice)
2047 0x0605, /* slave, 24bit, MSB on second OSCLK, SDOUT for right channel when OLRCK is high */ 2046 0x0605, /* slave, 24bit, MSB on second OSCLK, SDOUT for right channel when OLRCK is high */
2048 (unsigned short)-1 2047 (unsigned short)-1
2049 }; 2048 };
2050 struct aureon_spec *spec;
2051 unsigned int tmp; 2049 unsigned int tmp;
2052 const unsigned short *p; 2050 const unsigned short *p;
2053 int err, i; 2051 int err;
2054 2052 struct aureon_spec *spec = ice->spec;
2055 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2056 if (!spec)
2057 return -ENOMEM;
2058 ice->spec = spec;
2059
2060 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY) {
2061 ice->num_total_dacs = 6;
2062 ice->num_total_adcs = 2;
2063 } else {
2064 /* aureon 7.1 and prodigy 7.1 */
2065 ice->num_total_dacs = 8;
2066 ice->num_total_adcs = 2;
2067 }
2068
2069 /* to remeber the register values of CS8415 */
2070 ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
2071 if (!ice->akm)
2072 return -ENOMEM;
2073 ice->akm_codecs = 1;
2074 2053
2075 err = aureon_ac97_init(ice); 2054 err = aureon_ac97_init(ice);
2076 if (err != 0) 2055 if (err != 0)
@@ -2118,6 +2097,61 @@ static int __devinit aureon_init(struct snd_ice1712 *ice)
2118 /* initialize PCA9554 pin directions & set default input */ 2097 /* initialize PCA9554 pin directions & set default input */
2119 aureon_pca9554_write(ice, PCA9554_DIR, 0x00); 2098 aureon_pca9554_write(ice, PCA9554_DIR, 0x00);
2120 aureon_pca9554_write(ice, PCA9554_OUT, 0x00); /* internal AUX */ 2099 aureon_pca9554_write(ice, PCA9554_OUT, 0x00); /* internal AUX */
2100 return 0;
2101}
2102
2103/*
2104 * suspend/resume
2105 */
2106#ifdef CONFIG_PM
2107static int aureon_resume(struct snd_ice1712 *ice)
2108{
2109 struct aureon_spec *spec = ice->spec;
2110 int err, i;
2111
2112 err = aureon_reset(ice);
2113 if (err != 0)
2114 return err;
2115
2116 /* workaround for poking volume with alsamixer after resume:
2117 * just set stored volume again */
2118 for (i = 0; i < ice->num_total_dacs; i++)
2119 wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]);
2120 return 0;
2121}
2122#endif
2123
2124/*
2125 * initialize the chip
2126 */
2127static int __devinit aureon_init(struct snd_ice1712 *ice)
2128{
2129 struct aureon_spec *spec;
2130 int i, err;
2131
2132 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2133 if (!spec)
2134 return -ENOMEM;
2135 ice->spec = spec;
2136
2137 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY) {
2138 ice->num_total_dacs = 6;
2139 ice->num_total_adcs = 2;
2140 } else {
2141 /* aureon 7.1 and prodigy 7.1 */
2142 ice->num_total_dacs = 8;
2143 ice->num_total_adcs = 2;
2144 }
2145
2146 /* to remeber the register values of CS8415 */
2147 ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
2148 if (!ice->akm)
2149 return -ENOMEM;
2150 ice->akm_codecs = 1;
2151
2152 err = aureon_reset(ice);
2153 if (err != 0)
2154 return err;
2121 2155
2122 spec->master[0] = WM_VOL_MUTE; 2156 spec->master[0] = WM_VOL_MUTE;
2123 spec->master[1] = WM_VOL_MUTE; 2157 spec->master[1] = WM_VOL_MUTE;
@@ -2126,6 +2160,11 @@ static int __devinit aureon_init(struct snd_ice1712 *ice)
2126 wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]); 2160 wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]);
2127 } 2161 }
2128 2162
2163#ifdef CONFIG_PM
2164 ice->pm_resume = aureon_resume;
2165 ice->pm_suspend_enabled = 1;
2166#endif
2167
2129 return 0; 2168 return 0;
2130} 2169}
2131 2170
diff --git a/sound/pci/ice1712/maya44.c b/sound/pci/ice1712/maya44.c
index 3e1c20ae2f1c..726fd4b92e19 100644
--- a/sound/pci/ice1712/maya44.c
+++ b/sound/pci/ice1712/maya44.c
@@ -347,7 +347,7 @@ static int maya_gpio_sw_put(struct snd_kcontrol *kcontrol,
347 347
348/* known working input slots (0-4) */ 348/* known working input slots (0-4) */
349#define MAYA_LINE_IN 1 /* in-2 */ 349#define MAYA_LINE_IN 1 /* in-2 */
350#define MAYA_MIC_IN 4 /* in-5 */ 350#define MAYA_MIC_IN 3 /* in-4 */
351 351
352static void wm8776_select_input(struct snd_maya44 *chip, int idx, int line) 352static void wm8776_select_input(struct snd_maya44 *chip, int idx, int line)
353{ 353{
@@ -393,8 +393,8 @@ static int maya_rec_src_put(struct snd_kcontrol *kcontrol,
393 int changed; 393 int changed;
394 394
395 mutex_lock(&chip->mutex); 395 mutex_lock(&chip->mutex);
396 changed = maya_set_gpio_bits(chip->ice, GPIO_MIC_RELAY, 396 changed = maya_set_gpio_bits(chip->ice, 1 << GPIO_MIC_RELAY,
397 sel ? GPIO_MIC_RELAY : 0); 397 sel ? (1 << GPIO_MIC_RELAY) : 0);
398 wm8776_select_input(chip, 0, sel ? MAYA_MIC_IN : MAYA_LINE_IN); 398 wm8776_select_input(chip, 0, sel ? MAYA_MIC_IN : MAYA_LINE_IN);
399 mutex_unlock(&chip->mutex); 399 mutex_unlock(&chip->mutex);
400 return changed; 400 return changed;
diff --git a/sound/pci/ice1712/vt1720_mobo.c b/sound/pci/ice1712/vt1720_mobo.c
index 7f9674b641c0..4c551e147c08 100644
--- a/sound/pci/ice1712/vt1720_mobo.c
+++ b/sound/pci/ice1712/vt1720_mobo.c
@@ -25,7 +25,6 @@
25#include <linux/delay.h> 25#include <linux/delay.h>
26#include <linux/interrupt.h> 26#include <linux/interrupt.h>
27#include <linux/init.h> 27#include <linux/init.h>
28#include <linux/slab.h>
29#include <sound/core.h> 28#include <sound/core.h>
30 29
31#include "ice1712.h" 30#include "ice1712.h"
diff --git a/sound/pci/ice1712/wtm.c b/sound/pci/ice1712/wtm.c
index 5af9e84456d1..e618f789026e 100644
--- a/sound/pci/ice1712/wtm.c
+++ b/sound/pci/ice1712/wtm.c
@@ -29,7 +29,6 @@
29#include <linux/delay.h> 29#include <linux/delay.h>
30#include <linux/interrupt.h> 30#include <linux/interrupt.h>
31#include <linux/init.h> 31#include <linux/init.h>
32#include <linux/slab.h>
33#include <sound/core.h> 32#include <sound/core.h>
34 33
35#include "ice1712.h" 34#include "ice1712.h"
diff --git a/sound/pci/lx6464es/lx6464es.c b/sound/pci/lx6464es/lx6464es.c
index 0cca56038cd9..ef9af3f4ace2 100644
--- a/sound/pci/lx6464es/lx6464es.c
+++ b/sound/pci/lx6464es/lx6464es.c
@@ -26,6 +26,7 @@
26#include <linux/init.h> 26#include <linux/init.h>
27#include <linux/pci.h> 27#include <linux/pci.h>
28#include <linux/delay.h> 28#include <linux/delay.h>
29#include <linux/slab.h>
29 30
30#include <sound/initval.h> 31#include <sound/initval.h>
31#include <sound/control.h> 32#include <sound/control.h>
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index b64e78139d63..3c40d726b46e 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -41,6 +41,7 @@
41#include <linux/vmalloc.h> 41#include <linux/vmalloc.h>
42#include <linux/moduleparam.h> 42#include <linux/moduleparam.h>
43#include <linux/firmware.h> 43#include <linux/firmware.h>
44#include <linux/input.h>
44#include <sound/core.h> 45#include <sound/core.h>
45#include <sound/info.h> 46#include <sound/info.h>
46#include <sound/control.h> 47#include <sound/control.h>
@@ -844,11 +845,18 @@ struct snd_m3 {
844 struct m3_dma *substreams; 845 struct m3_dma *substreams;
845 846
846 spinlock_t reg_lock; 847 spinlock_t reg_lock;
847 spinlock_t ac97_lock;
848 848
849#ifdef CONFIG_SND_MAESTRO3_INPUT
850 struct input_dev *input_dev;
851 char phys[64]; /* physical device path */
852#else
853 spinlock_t ac97_lock;
849 struct snd_kcontrol *master_switch; 854 struct snd_kcontrol *master_switch;
850 struct snd_kcontrol *master_volume; 855 struct snd_kcontrol *master_volume;
851 struct tasklet_struct hwvol_tq; 856 struct tasklet_struct hwvol_tq;
857#endif
858
859 unsigned int in_suspend;
852 860
853#ifdef CONFIG_PM 861#ifdef CONFIG_PM
854 u16 *suspend_mem; 862 u16 *suspend_mem;
@@ -884,6 +892,7 @@ static DEFINE_PCI_DEVICE_TABLE(snd_m3_ids) = {
884MODULE_DEVICE_TABLE(pci, snd_m3_ids); 892MODULE_DEVICE_TABLE(pci, snd_m3_ids);
885 893
886static struct snd_pci_quirk m3_amp_quirk_list[] __devinitdata = { 894static struct snd_pci_quirk m3_amp_quirk_list[] __devinitdata = {
895 SND_PCI_QUIRK(0x0E11, 0x0094, "Compaq Evo N600c", 0x0c),
887 SND_PCI_QUIRK(0x10f7, 0x833e, "Panasonic CF-28", 0x0d), 896 SND_PCI_QUIRK(0x10f7, 0x833e, "Panasonic CF-28", 0x0d),
888 SND_PCI_QUIRK(0x10f7, 0x833d, "Panasonic CF-72", 0x0d), 897 SND_PCI_QUIRK(0x10f7, 0x833d, "Panasonic CF-72", 0x0d),
889 SND_PCI_QUIRK(0x1033, 0x80f1, "NEC LM800J/7", 0x03), 898 SND_PCI_QUIRK(0x1033, 0x80f1, "NEC LM800J/7", 0x03),
@@ -1596,23 +1605,43 @@ static void snd_m3_update_ptr(struct snd_m3 *chip, struct m3_dma *s)
1596 } 1605 }
1597} 1606}
1598 1607
1608/* The m3's hardware volume works by incrementing / decrementing 2 counters
1609 (without wrap around) in response to volume button presses and then
1610 generating an interrupt. The pair of counters is stored in bits 1-3 and 5-7
1611 of a byte wide register. The meaning of bits 0 and 4 is unknown. */
1599static void snd_m3_update_hw_volume(unsigned long private_data) 1612static void snd_m3_update_hw_volume(unsigned long private_data)
1600{ 1613{
1601 struct snd_m3 *chip = (struct snd_m3 *) private_data; 1614 struct snd_m3 *chip = (struct snd_m3 *) private_data;
1602 int x, val; 1615 int x, val;
1616#ifndef CONFIG_SND_MAESTRO3_INPUT
1603 unsigned long flags; 1617 unsigned long flags;
1618#endif
1604 1619
1605 /* Figure out which volume control button was pushed, 1620 /* Figure out which volume control button was pushed,
1606 based on differences from the default register 1621 based on differences from the default register
1607 values. */ 1622 values. */
1608 x = inb(chip->iobase + SHADOW_MIX_REG_VOICE) & 0xee; 1623 x = inb(chip->iobase + SHADOW_MIX_REG_VOICE) & 0xee;
1609 1624
1610 /* Reset the volume control registers. */ 1625 /* Reset the volume counters to 4. Tests on the allegro integrated
1626 into a Compaq N600C laptop, have revealed that:
1627 1) Writing any value will result in the 2 counters being reset to
1628 4 so writing 0x88 is not strictly necessary
1629 2) Writing to any of the 4 involved registers will reset all 4
1630 of them (and reading them always returns the same value for all
1631 of them)
1632 It could be that a maestro deviates from this, so leave the code
1633 as is. */
1611 outb(0x88, chip->iobase + SHADOW_MIX_REG_VOICE); 1634 outb(0x88, chip->iobase + SHADOW_MIX_REG_VOICE);
1612 outb(0x88, chip->iobase + HW_VOL_COUNTER_VOICE); 1635 outb(0x88, chip->iobase + HW_VOL_COUNTER_VOICE);
1613 outb(0x88, chip->iobase + SHADOW_MIX_REG_MASTER); 1636 outb(0x88, chip->iobase + SHADOW_MIX_REG_MASTER);
1614 outb(0x88, chip->iobase + HW_VOL_COUNTER_MASTER); 1637 outb(0x88, chip->iobase + HW_VOL_COUNTER_MASTER);
1615 1638
1639 /* Ignore spurious HV interrupts during suspend / resume, this avoids
1640 mistaking them for a mute button press. */
1641 if (chip->in_suspend)
1642 return;
1643
1644#ifndef CONFIG_SND_MAESTRO3_INPUT
1616 if (!chip->master_switch || !chip->master_volume) 1645 if (!chip->master_switch || !chip->master_volume)
1617 return; 1646 return;
1618 1647
@@ -1622,7 +1651,9 @@ static void snd_m3_update_hw_volume(unsigned long private_data)
1622 val = chip->ac97->regs[AC97_MASTER_VOL]; 1651 val = chip->ac97->regs[AC97_MASTER_VOL];
1623 switch (x) { 1652 switch (x) {
1624 case 0x88: 1653 case 0x88:
1625 /* mute */ 1654 /* The counters have not changed, yet we've received a HV
1655 interrupt. According to tests run by various people this
1656 happens when pressing the mute button. */
1626 val ^= 0x8000; 1657 val ^= 0x8000;
1627 chip->ac97->regs[AC97_MASTER_VOL] = val; 1658 chip->ac97->regs[AC97_MASTER_VOL] = val;
1628 outw(val, chip->iobase + CODEC_DATA); 1659 outw(val, chip->iobase + CODEC_DATA);
@@ -1631,7 +1662,7 @@ static void snd_m3_update_hw_volume(unsigned long private_data)
1631 &chip->master_switch->id); 1662 &chip->master_switch->id);
1632 break; 1663 break;
1633 case 0xaa: 1664 case 0xaa:
1634 /* volume up */ 1665 /* counters increased by 1 -> volume up */
1635 if ((val & 0x7f) > 0) 1666 if ((val & 0x7f) > 0)
1636 val--; 1667 val--;
1637 if ((val & 0x7f00) > 0) 1668 if ((val & 0x7f00) > 0)
@@ -1643,7 +1674,7 @@ static void snd_m3_update_hw_volume(unsigned long private_data)
1643 &chip->master_volume->id); 1674 &chip->master_volume->id);
1644 break; 1675 break;
1645 case 0x66: 1676 case 0x66:
1646 /* volume down */ 1677 /* counters decreased by 1 -> volume down */
1647 if ((val & 0x7f) < 0x1f) 1678 if ((val & 0x7f) < 0x1f)
1648 val++; 1679 val++;
1649 if ((val & 0x7f00) < 0x1f00) 1680 if ((val & 0x7f00) < 0x1f00)
@@ -1656,6 +1687,35 @@ static void snd_m3_update_hw_volume(unsigned long private_data)
1656 break; 1687 break;
1657 } 1688 }
1658 spin_unlock_irqrestore(&chip->ac97_lock, flags); 1689 spin_unlock_irqrestore(&chip->ac97_lock, flags);
1690#else
1691 if (!chip->input_dev)
1692 return;
1693
1694 val = 0;
1695 switch (x) {
1696 case 0x88:
1697 /* The counters have not changed, yet we've received a HV
1698 interrupt. According to tests run by various people this
1699 happens when pressing the mute button. */
1700 val = KEY_MUTE;
1701 break;
1702 case 0xaa:
1703 /* counters increased by 1 -> volume up */
1704 val = KEY_VOLUMEUP;
1705 break;
1706 case 0x66:
1707 /* counters decreased by 1 -> volume down */
1708 val = KEY_VOLUMEDOWN;
1709 break;
1710 }
1711
1712 if (val) {
1713 input_report_key(chip->input_dev, val, 1);
1714 input_sync(chip->input_dev);
1715 input_report_key(chip->input_dev, val, 0);
1716 input_sync(chip->input_dev);
1717 }
1718#endif
1659} 1719}
1660 1720
1661static irqreturn_t snd_m3_interrupt(int irq, void *dev_id) 1721static irqreturn_t snd_m3_interrupt(int irq, void *dev_id)
@@ -1670,7 +1730,11 @@ static irqreturn_t snd_m3_interrupt(int irq, void *dev_id)
1670 return IRQ_NONE; 1730 return IRQ_NONE;
1671 1731
1672 if (status & HV_INT_PENDING) 1732 if (status & HV_INT_PENDING)
1733#ifdef CONFIG_SND_MAESTRO3_INPUT
1734 snd_m3_update_hw_volume((unsigned long)chip);
1735#else
1673 tasklet_schedule(&chip->hwvol_tq); 1736 tasklet_schedule(&chip->hwvol_tq);
1737#endif
1674 1738
1675 /* 1739 /*
1676 * ack an assp int if its running 1740 * ack an assp int if its running
@@ -1936,18 +2000,24 @@ static unsigned short
1936snd_m3_ac97_read(struct snd_ac97 *ac97, unsigned short reg) 2000snd_m3_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
1937{ 2001{
1938 struct snd_m3 *chip = ac97->private_data; 2002 struct snd_m3 *chip = ac97->private_data;
2003#ifndef CONFIG_SND_MAESTRO3_INPUT
1939 unsigned long flags; 2004 unsigned long flags;
2005#endif
1940 unsigned short data = 0xffff; 2006 unsigned short data = 0xffff;
1941 2007
1942 if (snd_m3_ac97_wait(chip)) 2008 if (snd_m3_ac97_wait(chip))
1943 goto fail; 2009 goto fail;
2010#ifndef CONFIG_SND_MAESTRO3_INPUT
1944 spin_lock_irqsave(&chip->ac97_lock, flags); 2011 spin_lock_irqsave(&chip->ac97_lock, flags);
2012#endif
1945 snd_m3_outb(chip, 0x80 | (reg & 0x7f), CODEC_COMMAND); 2013 snd_m3_outb(chip, 0x80 | (reg & 0x7f), CODEC_COMMAND);
1946 if (snd_m3_ac97_wait(chip)) 2014 if (snd_m3_ac97_wait(chip))
1947 goto fail_unlock; 2015 goto fail_unlock;
1948 data = snd_m3_inw(chip, CODEC_DATA); 2016 data = snd_m3_inw(chip, CODEC_DATA);
1949fail_unlock: 2017fail_unlock:
2018#ifndef CONFIG_SND_MAESTRO3_INPUT
1950 spin_unlock_irqrestore(&chip->ac97_lock, flags); 2019 spin_unlock_irqrestore(&chip->ac97_lock, flags);
2020#endif
1951fail: 2021fail:
1952 return data; 2022 return data;
1953} 2023}
@@ -1956,14 +2026,20 @@ static void
1956snd_m3_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val) 2026snd_m3_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val)
1957{ 2027{
1958 struct snd_m3 *chip = ac97->private_data; 2028 struct snd_m3 *chip = ac97->private_data;
2029#ifndef CONFIG_SND_MAESTRO3_INPUT
1959 unsigned long flags; 2030 unsigned long flags;
2031#endif
1960 2032
1961 if (snd_m3_ac97_wait(chip)) 2033 if (snd_m3_ac97_wait(chip))
1962 return; 2034 return;
2035#ifndef CONFIG_SND_MAESTRO3_INPUT
1963 spin_lock_irqsave(&chip->ac97_lock, flags); 2036 spin_lock_irqsave(&chip->ac97_lock, flags);
2037#endif
1964 snd_m3_outw(chip, val, CODEC_DATA); 2038 snd_m3_outw(chip, val, CODEC_DATA);
1965 snd_m3_outb(chip, reg & 0x7f, CODEC_COMMAND); 2039 snd_m3_outb(chip, reg & 0x7f, CODEC_COMMAND);
2040#ifndef CONFIG_SND_MAESTRO3_INPUT
1966 spin_unlock_irqrestore(&chip->ac97_lock, flags); 2041 spin_unlock_irqrestore(&chip->ac97_lock, flags);
2042#endif
1967} 2043}
1968 2044
1969 2045
@@ -2070,7 +2146,9 @@ static int __devinit snd_m3_mixer(struct snd_m3 *chip)
2070{ 2146{
2071 struct snd_ac97_bus *pbus; 2147 struct snd_ac97_bus *pbus;
2072 struct snd_ac97_template ac97; 2148 struct snd_ac97_template ac97;
2149#ifndef CONFIG_SND_MAESTRO3_INPUT
2073 struct snd_ctl_elem_id elem_id; 2150 struct snd_ctl_elem_id elem_id;
2151#endif
2074 int err; 2152 int err;
2075 static struct snd_ac97_bus_ops ops = { 2153 static struct snd_ac97_bus_ops ops = {
2076 .write = snd_m3_ac97_write, 2154 .write = snd_m3_ac97_write,
@@ -2090,6 +2168,7 @@ static int __devinit snd_m3_mixer(struct snd_m3 *chip)
2090 schedule_timeout_uninterruptible(msecs_to_jiffies(100)); 2168 schedule_timeout_uninterruptible(msecs_to_jiffies(100));
2091 snd_ac97_write(chip->ac97, AC97_PCM, 0); 2169 snd_ac97_write(chip->ac97, AC97_PCM, 0);
2092 2170
2171#ifndef CONFIG_SND_MAESTRO3_INPUT
2093 memset(&elem_id, 0, sizeof(elem_id)); 2172 memset(&elem_id, 0, sizeof(elem_id));
2094 elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; 2173 elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2095 strcpy(elem_id.name, "Master Playback Switch"); 2174 strcpy(elem_id.name, "Master Playback Switch");
@@ -2098,6 +2177,7 @@ static int __devinit snd_m3_mixer(struct snd_m3 *chip)
2098 elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; 2177 elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2099 strcpy(elem_id.name, "Master Playback Volume"); 2178 strcpy(elem_id.name, "Master Playback Volume");
2100 chip->master_volume = snd_ctl_find_id(chip->card, &elem_id); 2179 chip->master_volume = snd_ctl_find_id(chip->card, &elem_id);
2180#endif
2101 2181
2102 return 0; 2182 return 0;
2103} 2183}
@@ -2363,6 +2443,7 @@ snd_m3_enable_ints(struct snd_m3 *chip)
2363 val = ASSP_INT_ENABLE /*| MPU401_INT_ENABLE*/; 2443 val = ASSP_INT_ENABLE /*| MPU401_INT_ENABLE*/;
2364 if (chip->hv_config & HV_CTRL_ENABLE) 2444 if (chip->hv_config & HV_CTRL_ENABLE)
2365 val |= HV_INT_ENABLE; 2445 val |= HV_INT_ENABLE;
2446 outb(val, chip->iobase + HOST_INT_STATUS);
2366 outw(val, io + HOST_INT_CTRL); 2447 outw(val, io + HOST_INT_CTRL);
2367 outb(inb(io + ASSP_CONTROL_C) | ASSP_HOST_INT_ENABLE, 2448 outb(inb(io + ASSP_CONTROL_C) | ASSP_HOST_INT_ENABLE,
2368 io + ASSP_CONTROL_C); 2449 io + ASSP_CONTROL_C);
@@ -2377,6 +2458,11 @@ static int snd_m3_free(struct snd_m3 *chip)
2377 struct m3_dma *s; 2458 struct m3_dma *s;
2378 int i; 2459 int i;
2379 2460
2461#ifdef CONFIG_SND_MAESTRO3_INPUT
2462 if (chip->input_dev)
2463 input_unregister_device(chip->input_dev);
2464#endif
2465
2380 if (chip->substreams) { 2466 if (chip->substreams) {
2381 spin_lock_irq(&chip->reg_lock); 2467 spin_lock_irq(&chip->reg_lock);
2382 for (i = 0; i < chip->num_substreams; i++) { 2468 for (i = 0; i < chip->num_substreams; i++) {
@@ -2424,6 +2510,7 @@ static int m3_suspend(struct pci_dev *pci, pm_message_t state)
2424 if (chip->suspend_mem == NULL) 2510 if (chip->suspend_mem == NULL)
2425 return 0; 2511 return 0;
2426 2512
2513 chip->in_suspend = 1;
2427 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); 2514 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
2428 snd_pcm_suspend_all(chip->pcm); 2515 snd_pcm_suspend_all(chip->pcm);
2429 snd_ac97_suspend(chip->ac97); 2516 snd_ac97_suspend(chip->ac97);
@@ -2497,10 +2584,46 @@ static int m3_resume(struct pci_dev *pci)
2497 snd_m3_hv_init(chip); 2584 snd_m3_hv_init(chip);
2498 2585
2499 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 2586 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
2587 chip->in_suspend = 0;
2500 return 0; 2588 return 0;
2501} 2589}
2502#endif /* CONFIG_PM */ 2590#endif /* CONFIG_PM */
2503 2591
2592#ifdef CONFIG_SND_MAESTRO3_INPUT
2593static int __devinit snd_m3_input_register(struct snd_m3 *chip)
2594{
2595 struct input_dev *input_dev;
2596 int err;
2597
2598 input_dev = input_allocate_device();
2599 if (!input_dev)
2600 return -ENOMEM;
2601
2602 snprintf(chip->phys, sizeof(chip->phys), "pci-%s/input0",
2603 pci_name(chip->pci));
2604
2605 input_dev->name = chip->card->driver;
2606 input_dev->phys = chip->phys;
2607 input_dev->id.bustype = BUS_PCI;
2608 input_dev->id.vendor = chip->pci->vendor;
2609 input_dev->id.product = chip->pci->device;
2610 input_dev->dev.parent = &chip->pci->dev;
2611
2612 __set_bit(EV_KEY, input_dev->evbit);
2613 __set_bit(KEY_MUTE, input_dev->keybit);
2614 __set_bit(KEY_VOLUMEDOWN, input_dev->keybit);
2615 __set_bit(KEY_VOLUMEUP, input_dev->keybit);
2616
2617 err = input_register_device(input_dev);
2618 if (err) {
2619 input_free_device(input_dev);
2620 return err;
2621 }
2622
2623 chip->input_dev = input_dev;
2624 return 0;
2625}
2626#endif /* CONFIG_INPUT */
2504 2627
2505/* 2628/*
2506 */ 2629 */
@@ -2544,7 +2667,9 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci,
2544 } 2667 }
2545 2668
2546 spin_lock_init(&chip->reg_lock); 2669 spin_lock_init(&chip->reg_lock);
2670#ifndef CONFIG_SND_MAESTRO3_INPUT
2547 spin_lock_init(&chip->ac97_lock); 2671 spin_lock_init(&chip->ac97_lock);
2672#endif
2548 2673
2549 switch (pci->device) { 2674 switch (pci->device) {
2550 case PCI_DEVICE_ID_ESS_ALLEGRO: 2675 case PCI_DEVICE_ID_ESS_ALLEGRO:
@@ -2627,7 +2752,9 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci,
2627 2752
2628 snd_m3_hv_init(chip); 2753 snd_m3_hv_init(chip);
2629 2754
2755#ifndef CONFIG_SND_MAESTRO3_INPUT
2630 tasklet_init(&chip->hwvol_tq, snd_m3_update_hw_volume, (unsigned long)chip); 2756 tasklet_init(&chip->hwvol_tq, snd_m3_update_hw_volume, (unsigned long)chip);
2757#endif
2631 2758
2632 if (request_irq(pci->irq, snd_m3_interrupt, IRQF_SHARED, 2759 if (request_irq(pci->irq, snd_m3_interrupt, IRQF_SHARED,
2633 card->driver, chip)) { 2760 card->driver, chip)) {
@@ -2659,7 +2786,16 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci,
2659 2786
2660 if ((err = snd_m3_pcm(chip, 0)) < 0) 2787 if ((err = snd_m3_pcm(chip, 0)) < 0)
2661 return err; 2788 return err;
2662 2789
2790#ifdef CONFIG_SND_MAESTRO3_INPUT
2791 if (chip->hv_config & HV_CTRL_ENABLE) {
2792 err = snd_m3_input_register(chip);
2793 if (err)
2794 snd_printk(KERN_WARNING "Input device registration "
2795 "failed with error %i", err);
2796 }
2797#endif
2798
2663 snd_m3_enable_ints(chip); 2799 snd_m3_enable_ints(chip);
2664 snd_m3_assp_continue(chip); 2800 snd_m3_assp_continue(chip);
2665 2801
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c
index 7e8e7da592a9..6c3fd4d1c49d 100644
--- a/sound/pci/mixart/mixart.c
+++ b/sound/pci/mixart/mixart.c
@@ -27,6 +27,7 @@
27#include <linux/dma-mapping.h> 27#include <linux/dma-mapping.h>
28#include <linux/moduleparam.h> 28#include <linux/moduleparam.h>
29#include <linux/mutex.h> 29#include <linux/mutex.h>
30#include <linux/slab.h>
30 31
31#include <sound/core.h> 32#include <sound/core.h>
32#include <sound/initval.h> 33#include <sound/initval.h>
@@ -1101,73 +1102,19 @@ static int snd_mixart_free(struct mixart_mgr *mgr)
1101/* 1102/*
1102 * proc interface 1103 * proc interface
1103 */ 1104 */
1104static long long snd_mixart_BA0_llseek(struct snd_info_entry *entry,
1105 void *private_file_data,
1106 struct file *file,
1107 long long offset,
1108 int orig)
1109{
1110 offset = offset & ~3; /* 4 bytes aligned */
1111
1112 switch(orig) {
1113 case SEEK_SET:
1114 file->f_pos = offset;
1115 break;
1116 case SEEK_CUR:
1117 file->f_pos += offset;
1118 break;
1119 case SEEK_END: /* offset is negative */
1120 file->f_pos = MIXART_BA0_SIZE + offset;
1121 break;
1122 default:
1123 return -EINVAL;
1124 }
1125 if(file->f_pos > MIXART_BA0_SIZE)
1126 file->f_pos = MIXART_BA0_SIZE;
1127 return file->f_pos;
1128}
1129
1130static long long snd_mixart_BA1_llseek(struct snd_info_entry *entry,
1131 void *private_file_data,
1132 struct file *file,
1133 long long offset,
1134 int orig)
1135{
1136 offset = offset & ~3; /* 4 bytes aligned */
1137
1138 switch(orig) {
1139 case SEEK_SET:
1140 file->f_pos = offset;
1141 break;
1142 case SEEK_CUR:
1143 file->f_pos += offset;
1144 break;
1145 case SEEK_END: /* offset is negative */
1146 file->f_pos = MIXART_BA1_SIZE + offset;
1147 break;
1148 default:
1149 return -EINVAL;
1150 }
1151 if(file->f_pos > MIXART_BA1_SIZE)
1152 file->f_pos = MIXART_BA1_SIZE;
1153 return file->f_pos;
1154}
1155 1105
1156/* 1106/*
1157 mixart_BA0 proc interface for BAR 0 - read callback 1107 mixart_BA0 proc interface for BAR 0 - read callback
1158 */ 1108 */
1159static long snd_mixart_BA0_read(struct snd_info_entry *entry, void *file_private_data, 1109static ssize_t snd_mixart_BA0_read(struct snd_info_entry *entry,
1160 struct file *file, char __user *buf, 1110 void *file_private_data,
1161 unsigned long count, unsigned long pos) 1111 struct file *file, char __user *buf,
1112 size_t count, loff_t pos)
1162{ 1113{
1163 struct mixart_mgr *mgr = entry->private_data; 1114 struct mixart_mgr *mgr = entry->private_data;
1164 1115
1165 count = count & ~3; /* make sure the read size is a multiple of 4 bytes */ 1116 count = count & ~3; /* make sure the read size is a multiple of 4 bytes */
1166 if(count <= 0) 1117 if (copy_to_user_fromio(buf, MIXART_MEM(mgr, pos), count))
1167 return 0;
1168 if(pos + count > MIXART_BA0_SIZE)
1169 count = (long)(MIXART_BA0_SIZE - pos);
1170 if(copy_to_user_fromio(buf, MIXART_MEM( mgr, pos ), count))
1171 return -EFAULT; 1118 return -EFAULT;
1172 return count; 1119 return count;
1173} 1120}
@@ -1175,30 +1122,25 @@ static long snd_mixart_BA0_read(struct snd_info_entry *entry, void *file_private
1175/* 1122/*
1176 mixart_BA1 proc interface for BAR 1 - read callback 1123 mixart_BA1 proc interface for BAR 1 - read callback
1177 */ 1124 */
1178static long snd_mixart_BA1_read(struct snd_info_entry *entry, void *file_private_data, 1125static ssize_t snd_mixart_BA1_read(struct snd_info_entry *entry,
1179 struct file *file, char __user *buf, 1126 void *file_private_data,
1180 unsigned long count, unsigned long pos) 1127 struct file *file, char __user *buf,
1128 size_t count, loff_t pos)
1181{ 1129{
1182 struct mixart_mgr *mgr = entry->private_data; 1130 struct mixart_mgr *mgr = entry->private_data;
1183 1131
1184 count = count & ~3; /* make sure the read size is a multiple of 4 bytes */ 1132 count = count & ~3; /* make sure the read size is a multiple of 4 bytes */
1185 if(count <= 0) 1133 if (copy_to_user_fromio(buf, MIXART_REG(mgr, pos), count))
1186 return 0;
1187 if(pos + count > MIXART_BA1_SIZE)
1188 count = (long)(MIXART_BA1_SIZE - pos);
1189 if(copy_to_user_fromio(buf, MIXART_REG( mgr, pos ), count))
1190 return -EFAULT; 1134 return -EFAULT;
1191 return count; 1135 return count;
1192} 1136}
1193 1137
1194static struct snd_info_entry_ops snd_mixart_proc_ops_BA0 = { 1138static struct snd_info_entry_ops snd_mixart_proc_ops_BA0 = {
1195 .read = snd_mixart_BA0_read, 1139 .read = snd_mixart_BA0_read,
1196 .llseek = snd_mixart_BA0_llseek
1197}; 1140};
1198 1141
1199static struct snd_info_entry_ops snd_mixart_proc_ops_BA1 = { 1142static struct snd_info_entry_ops snd_mixart_proc_ops_BA1 = {
1200 .read = snd_mixart_BA1_read, 1143 .read = snd_mixart_BA1_read,
1201 .llseek = snd_mixart_BA1_llseek
1202}; 1144};
1203 1145
1204 1146
diff --git a/sound/pci/mixart/mixart_hwdep.c b/sound/pci/mixart/mixart_hwdep.c
index 4cf4cd8c939c..bf2696aa5d49 100644
--- a/sound/pci/mixart/mixart_hwdep.c
+++ b/sound/pci/mixart/mixart_hwdep.c
@@ -24,6 +24,7 @@
24#include <linux/pci.h> 24#include <linux/pci.h>
25#include <linux/firmware.h> 25#include <linux/firmware.h>
26#include <linux/vmalloc.h> 26#include <linux/vmalloc.h>
27#include <linux/slab.h>
27#include <asm/io.h> 28#include <asm/io.h>
28#include <sound/core.h> 29#include <sound/core.h>
29#include "mixart.h" 30#include "mixart.h"
diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c
index 9c5e6450eebb..fad03d64e3ad 100644
--- a/sound/pci/oxygen/oxygen_lib.c
+++ b/sound/pci/oxygen/oxygen_lib.c
@@ -21,6 +21,7 @@
21#include <linux/interrupt.h> 21#include <linux/interrupt.h>
22#include <linux/mutex.h> 22#include <linux/mutex.h>
23#include <linux/pci.h> 23#include <linux/pci.h>
24#include <linux/slab.h>
24#include <sound/ac97_codec.h> 25#include <sound/ac97_codec.h>
25#include <sound/asoundef.h> 26#include <sound/asoundef.h>
26#include <sound/core.h> 27#include <sound/core.h>
diff --git a/sound/pci/oxygen/xonar_cs43xx.c b/sound/pci/oxygen/xonar_cs43xx.c
index 16c226bfcd2b..7c4986b27f2b 100644
--- a/sound/pci/oxygen/xonar_cs43xx.c
+++ b/sound/pci/oxygen/xonar_cs43xx.c
@@ -56,6 +56,7 @@
56#include <sound/pcm_params.h> 56#include <sound/pcm_params.h>
57#include <sound/tlv.h> 57#include <sound/tlv.h>
58#include "xonar.h" 58#include "xonar.h"
59#include "cm9780.h"
59#include "cs4398.h" 60#include "cs4398.h"
60#include "cs4362a.h" 61#include "cs4362a.h"
61 62
@@ -172,6 +173,8 @@ static void xonar_d1_init(struct oxygen *chip)
172 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, 173 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA,
173 GPIO_D1_FRONT_PANEL | GPIO_D1_INPUT_ROUTE); 174 GPIO_D1_FRONT_PANEL | GPIO_D1_INPUT_ROUTE);
174 175
176 oxygen_ac97_set_bits(chip, 0, CM9780_JACK, CM9780_FMIC2MIC);
177
175 xonar_init_cs53x1(chip); 178 xonar_init_cs53x1(chip);
176 xonar_enable_output(chip); 179 xonar_enable_output(chip);
177 180
diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c
index d5e1c6eb7b7b..3c04524de37c 100644
--- a/sound/pci/rme32.c
+++ b/sound/pci/rme32.c
@@ -70,10 +70,10 @@
70 70
71 71
72#include <linux/delay.h> 72#include <linux/delay.h>
73#include <linux/gfp.h>
73#include <linux/init.h> 74#include <linux/init.h>
74#include <linux/interrupt.h> 75#include <linux/interrupt.h>
75#include <linux/pci.h> 76#include <linux/pci.h>
76#include <linux/slab.h>
77#include <linux/moduleparam.h> 77#include <linux/moduleparam.h>
78 78
79#include <sound/core.h> 79#include <sound/core.h>
diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c
index 9d5252bc870c..d19dc052c391 100644
--- a/sound/pci/rme96.c
+++ b/sound/pci/rme96.c
@@ -27,7 +27,6 @@
27#include <linux/init.h> 27#include <linux/init.h>
28#include <linux/interrupt.h> 28#include <linux/interrupt.h>
29#include <linux/pci.h> 29#include <linux/pci.h>
30#include <linux/slab.h>
31#include <linux/moduleparam.h> 30#include <linux/moduleparam.h>
32 31
33#include <sound/core.h> 32#include <sound/core.h>
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 52c6eb57cc3f..b92adef8e81e 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -24,7 +24,6 @@
24#include <linux/init.h> 24#include <linux/init.h>
25#include <linux/delay.h> 25#include <linux/delay.h>
26#include <linux/interrupt.h> 26#include <linux/interrupt.h>
27#include <linux/slab.h>
28#include <linux/pci.h> 27#include <linux/pci.h>
29#include <linux/firmware.h> 28#include <linux/firmware.h>
30#include <linux/moduleparam.h> 29#include <linux/moduleparam.h>
diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c
index 44a3e2d8c556..c492af5b25f3 100644
--- a/sound/pci/rme9652/rme9652.c
+++ b/sound/pci/rme9652/rme9652.c
@@ -24,7 +24,6 @@
24#include <linux/init.h> 24#include <linux/init.h>
25#include <linux/interrupt.h> 25#include <linux/interrupt.h>
26#include <linux/pci.h> 26#include <linux/pci.h>
27#include <linux/slab.h>
28#include <linux/moduleparam.h> 27#include <linux/moduleparam.h>
29 28
30#include <sound/core.h> 29#include <sound/core.h>
diff --git a/sound/pci/sis7019.c b/sound/pci/sis7019.c
index 7e3e8fbc90fe..9cc1b5aa0148 100644
--- a/sound/pci/sis7019.c
+++ b/sound/pci/sis7019.c
@@ -24,6 +24,7 @@
24#include <linux/init.h> 24#include <linux/init.h>
25#include <linux/pci.h> 25#include <linux/pci.h>
26#include <linux/time.h> 26#include <linux/time.h>
27#include <linux/slab.h>
27#include <linux/moduleparam.h> 28#include <linux/moduleparam.h>
28#include <linux/interrupt.h> 29#include <linux/interrupt.h>
29#include <linux/delay.h> 30#include <linux/delay.h>
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.c b/sound/pcmcia/pdaudiocf/pdaudiocf.c
index edaa729126bb..df110df52a8b 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf.c
@@ -142,12 +142,7 @@ static int snd_pdacf_probe(struct pcmcia_device *link)
142 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; 142 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
143 link->io.NumPorts1 = 16; 143 link->io.NumPorts1 = 16;
144 144
145 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_FORCED_PULSE; 145 link->conf.Attributes = CONF_ENABLE_IRQ | CONF_ENABLE_PULSE_IRQ;
146 /* FIXME: This driver should be updated to allow for dynamic IRQ sharing */
147 /* link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_FORCED_PULSE; */
148
149 link->irq.Handler = pdacf_interrupt;
150 link->conf.Attributes = CONF_ENABLE_IRQ;
151 link->conf.IntType = INT_MEMORY_AND_IO; 146 link->conf.IntType = INT_MEMORY_AND_IO;
152 link->conf.ConfigIndex = 1; 147 link->conf.ConfigIndex = 1;
153 link->conf.Present = PRESENT_OPTION; 148 link->conf.Present = PRESENT_OPTION;
@@ -228,7 +223,7 @@ static int pdacf_config(struct pcmcia_device *link)
228 if (ret) 223 if (ret)
229 goto failed; 224 goto failed;
230 225
231 ret = pcmcia_request_irq(link, &link->irq); 226 ret = pcmcia_request_exclusive_irq(link, pdacf_interrupt);
232 if (ret) 227 if (ret)
233 goto failed; 228 goto failed;
234 229
@@ -236,10 +231,9 @@ static int pdacf_config(struct pcmcia_device *link)
236 if (ret) 231 if (ret)
237 goto failed; 232 goto failed;
238 233
239 if (snd_pdacf_assign_resources(pdacf, link->io.BasePort1, link->irq.AssignedIRQ) < 0) 234 if (snd_pdacf_assign_resources(pdacf, link->io.BasePort1, link->irq) < 0)
240 goto failed; 235 goto failed;
241 236
242 link->dev_node = &pdacf->node;
243 return 0; 237 return 0;
244 238
245failed: 239failed:
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.h b/sound/pcmcia/pdaudiocf/pdaudiocf.h
index b0601838112d..a0a7ec64222a 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf.h
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf.h
@@ -117,7 +117,6 @@ struct snd_pdacf {
117 117
118 /* pcmcia stuff */ 118 /* pcmcia stuff */
119 struct pcmcia_device *p_dev; 119 struct pcmcia_device *p_dev;
120 dev_node_t node;
121}; 120};
122 121
123static inline void pdacf_reg_write(struct snd_pdacf *chip, unsigned char reg, unsigned short val) 122static inline void pdacf_reg_write(struct snd_pdacf *chip, unsigned char reg, unsigned short val)
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf_core.c b/sound/pcmcia/pdaudiocf/pdaudiocf_core.c
index 5d2afa0b0ce4..9dce0bde5c05 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf_core.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf_core.c
@@ -19,6 +19,7 @@
19 */ 19 */
20 20
21#include <linux/delay.h> 21#include <linux/delay.h>
22#include <linux/slab.h>
22#include <sound/core.h> 23#include <sound/core.h>
23#include <sound/info.h> 24#include <sound/info.h>
24#include "pdaudiocf.h" 25#include "pdaudiocf.h"
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c b/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c
index 0d668f471620..43f995a3f960 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c
@@ -20,7 +20,6 @@
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */ 21 */
22 22
23#include <linux/slab.h>
24#include <linux/delay.h> 23#include <linux/delay.h>
25#include <sound/core.h> 24#include <sound/core.h>
26#include <sound/asoundef.h> 25#include <sound/asoundef.h>
diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c
index 7be3b3357045..624b47a85f0a 100644
--- a/sound/pcmcia/vx/vxpocket.c
+++ b/sound/pcmcia/vx/vxpocket.c
@@ -21,6 +21,7 @@
21 21
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/moduleparam.h> 23#include <linux/moduleparam.h>
24#include <linux/slab.h>
24#include <sound/core.h> 25#include <sound/core.h>
25#include "vxpocket.h" 26#include "vxpocket.h"
26#include <pcmcia/ciscode.h> 27#include <pcmcia/ciscode.h>
@@ -161,10 +162,6 @@ static int snd_vxpocket_new(struct snd_card *card, int ibl,
161 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; 162 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
162 link->io.NumPorts1 = 16; 163 link->io.NumPorts1 = 16;
163 164
164 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
165
166 link->irq.Handler = &snd_vx_irq_handler;
167
168 link->conf.Attributes = CONF_ENABLE_IRQ; 165 link->conf.Attributes = CONF_ENABLE_IRQ;
169 link->conf.IntType = INT_MEMORY_AND_IO; 166 link->conf.IntType = INT_MEMORY_AND_IO;
170 link->conf.ConfigIndex = 1; 167 link->conf.ConfigIndex = 1;
@@ -214,7 +211,6 @@ static int snd_vxpocket_assign_resources(struct vx_core *chip, int port, int irq
214static int vxpocket_config(struct pcmcia_device *link) 211static int vxpocket_config(struct pcmcia_device *link)
215{ 212{
216 struct vx_core *chip = link->priv; 213 struct vx_core *chip = link->priv;
217 struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip;
218 int ret; 214 int ret;
219 215
220 snd_printdd(KERN_DEBUG "vxpocket_config called\n"); 216 snd_printdd(KERN_DEBUG "vxpocket_config called\n");
@@ -234,7 +230,7 @@ static int vxpocket_config(struct pcmcia_device *link)
234 if (ret) 230 if (ret)
235 goto failed; 231 goto failed;
236 232
237 ret = pcmcia_request_irq(link, &link->irq); 233 ret = pcmcia_request_exclusive_irq(link, snd_vx_irq_handler);
238 if (ret) 234 if (ret)
239 goto failed; 235 goto failed;
240 236
@@ -245,10 +241,9 @@ static int vxpocket_config(struct pcmcia_device *link)
245 chip->dev = &link->dev; 241 chip->dev = &link->dev;
246 snd_card_set_dev(chip->card, chip->dev); 242 snd_card_set_dev(chip->card, chip->dev);
247 243
248 if (snd_vxpocket_assign_resources(chip, link->io.BasePort1, link->irq.AssignedIRQ) < 0) 244 if (snd_vxpocket_assign_resources(chip, link->io.BasePort1, link->irq) < 0)
249 goto failed; 245 goto failed;
250 246
251 link->dev_node = &vxp->node;
252 return 0; 247 return 0;
253 248
254failed: 249failed:
diff --git a/sound/pcmcia/vx/vxpocket.h b/sound/pcmcia/vx/vxpocket.h
index 27ea002294c0..ea4df16a28ef 100644
--- a/sound/pcmcia/vx/vxpocket.h
+++ b/sound/pcmcia/vx/vxpocket.h
@@ -43,7 +43,6 @@ struct snd_vxpocket {
43 43
44 /* pcmcia stuff */ 44 /* pcmcia stuff */
45 struct pcmcia_device *p_dev; 45 struct pcmcia_device *p_dev;
46 dev_node_t node;
47}; 46};
48 47
49extern struct snd_vx_ops snd_vxpocket_ops; 48extern struct snd_vx_ops snd_vxpocket_ops;
diff --git a/sound/ppc/burgundy.c b/sound/ppc/burgundy.c
index 1f72e1c786bf..00e2d5166d0a 100644
--- a/sound/ppc/burgundy.c
+++ b/sound/ppc/burgundy.c
@@ -21,7 +21,6 @@
21 21
22#include <asm/io.h> 22#include <asm/io.h>
23#include <linux/init.h> 23#include <linux/init.h>
24#include <linux/slab.h>
25#include <linux/delay.h> 24#include <linux/delay.h>
26#include <sound/core.h> 25#include <sound/core.h>
27#include "pmac.h" 26#include "pmac.h"
diff --git a/sound/ppc/keywest.c b/sound/ppc/keywest.c
index d06f780bd7e8..8f064c7ce745 100644
--- a/sound/ppc/keywest.c
+++ b/sound/ppc/keywest.c
@@ -22,7 +22,6 @@
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/i2c.h> 23#include <linux/i2c.h>
24#include <linux/delay.h> 24#include <linux/delay.h>
25#include <linux/slab.h>
26#include <sound/core.h> 25#include <sound/core.h>
27#include "pmac.h" 26#include "pmac.h"
28 27
diff --git a/sound/ppc/snd_ps3.c b/sound/ppc/snd_ps3.c
index 53c81a547613..2f12da4da561 100644
--- a/sound/ppc/snd_ps3.c
+++ b/sound/ppc/snd_ps3.c
@@ -20,10 +20,10 @@
20 20
21#include <linux/dma-mapping.h> 21#include <linux/dma-mapping.h>
22#include <linux/dmapool.h> 22#include <linux/dmapool.h>
23#include <linux/gfp.h>
23#include <linux/init.h> 24#include <linux/init.h>
24#include <linux/interrupt.h> 25#include <linux/interrupt.h>
25#include <linux/io.h> 26#include <linux/io.h>
26#include <linux/slab.h>
27 27
28#include <sound/asound.h> 28#include <sound/asound.h>
29#include <sound/control.h> 29#include <sound/control.h>
diff --git a/sound/ppc/tumbler.c b/sound/ppc/tumbler.c
index 789f44f4ac78..20afdf9772ee 100644
--- a/sound/ppc/tumbler.c
+++ b/sound/ppc/tumbler.c
@@ -30,6 +30,7 @@
30#include <linux/kmod.h> 30#include <linux/kmod.h>
31#include <linux/slab.h> 31#include <linux/slab.h>
32#include <linux/interrupt.h> 32#include <linux/interrupt.h>
33#include <linux/string.h>
33#include <sound/core.h> 34#include <sound/core.h>
34#include <asm/io.h> 35#include <asm/io.h>
35#include <asm/irq.h> 36#include <asm/irq.h>
@@ -46,6 +47,8 @@
46#define DBG(fmt...) 47#define DBG(fmt...)
47#endif 48#endif
48 49
50#define IS_G4DA (of_machine_is_compatible("PowerMac3,4"))
51
49/* i2c address for tumbler */ 52/* i2c address for tumbler */
50#define TAS_I2C_ADDR 0x34 53#define TAS_I2C_ADDR 0x34
51 54
@@ -243,6 +246,7 @@ static int tumbler_set_master_volume(struct pmac_tumbler *mix)
243 snd_printk(KERN_ERR "failed to set volume \n"); 246 snd_printk(KERN_ERR "failed to set volume \n");
244 return -EINVAL; 247 return -EINVAL;
245 } 248 }
249 DBG("(I) succeeded to set volume (%u, %u)\n", left_vol, right_vol);
246 return 0; 250 return 0;
247} 251}
248 252
@@ -353,6 +357,7 @@ static int tumbler_set_drc(struct pmac_tumbler *mix)
353 snd_printk(KERN_ERR "failed to set DRC\n"); 357 snd_printk(KERN_ERR "failed to set DRC\n");
354 return -EINVAL; 358 return -EINVAL;
355 } 359 }
360 DBG("(I) succeeded to set DRC (%u, %u)\n", val[0], val[1]);
356 return 0; 361 return 0;
357} 362}
358 363
@@ -389,6 +394,7 @@ static int snapper_set_drc(struct pmac_tumbler *mix)
389 snd_printk(KERN_ERR "failed to set DRC\n"); 394 snd_printk(KERN_ERR "failed to set DRC\n");
390 return -EINVAL; 395 return -EINVAL;
391 } 396 }
397 DBG("(I) succeeded to set DRC (%u, %u)\n", val[0], val[1]);
392 return 0; 398 return 0;
393} 399}
394 400
@@ -1134,7 +1140,8 @@ static long tumbler_find_device(const char *device, const char *platform,
1134 gp->inactive_val = (*base) ? 0x4 : 0x5; 1140 gp->inactive_val = (*base) ? 0x4 : 0x5;
1135 } else { 1141 } else {
1136 const u32 *prop = NULL; 1142 const u32 *prop = NULL;
1137 gp->active_state = 0; 1143 gp->active_state = IS_G4DA
1144 && !strncmp(device, "keywest-gpio1", 13);
1138 gp->active_val = 0x4; 1145 gp->active_val = 0x4;
1139 gp->inactive_val = 0x5; 1146 gp->inactive_val = 0x5;
1140 /* Here are some crude hacks to extract the GPIO polarity and 1147 /* Here are some crude hacks to extract the GPIO polarity and
@@ -1312,6 +1319,9 @@ static int __devinit tumbler_init(struct snd_pmac *chip)
1312 if (irq <= NO_IRQ) 1319 if (irq <= NO_IRQ)
1313 irq = tumbler_find_device("line-output-detect", 1320 irq = tumbler_find_device("line-output-detect",
1314 NULL, &mix->line_detect, 1); 1321 NULL, &mix->line_detect, 1);
1322 if (IS_G4DA && irq <= NO_IRQ)
1323 irq = tumbler_find_device("keywest-gpio16",
1324 NULL, &mix->line_detect, 1);
1315 mix->lineout_irq = irq; 1325 mix->lineout_irq = irq;
1316 1326
1317 tumbler_reset_audio(chip); 1327 tumbler_reset_audio(chip);
diff --git a/sound/sh/sh_dac_audio.c b/sound/sh/sh_dac_audio.c
index 76d9ad27d91c..68e0dee4ff05 100644
--- a/sound/sh/sh_dac_audio.c
+++ b/sound/sh/sh_dac_audio.c
@@ -26,6 +26,7 @@
26#include <linux/interrupt.h> 26#include <linux/interrupt.h>
27#include <linux/io.h> 27#include <linux/io.h>
28#include <linux/platform_device.h> 28#include <linux/platform_device.h>
29#include <linux/slab.h>
29#include <sound/core.h> 30#include <sound/core.h>
30#include <sound/initval.h> 31#include <sound/initval.h>
31#include <sound/pcm.h> 32#include <sound/pcm.h>
diff --git a/sound/soc/au1x/psc-ac97.c b/sound/soc/au1x/psc-ac97.c
index 340311d7fed5..a61ccd2d505f 100644
--- a/sound/soc/au1x/psc-ac97.c
+++ b/sound/soc/au1x/psc-ac97.c
@@ -17,6 +17,7 @@
17 17
18#include <linux/init.h> 18#include <linux/init.h>
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/slab.h>
20#include <linux/device.h> 21#include <linux/device.h>
21#include <linux/delay.h> 22#include <linux/delay.h>
22#include <linux/mutex.h> 23#include <linux/mutex.h>
diff --git a/sound/soc/au1x/psc-i2s.c b/sound/soc/au1x/psc-i2s.c
index 0cf2ca61c776..495be6e71931 100644
--- a/sound/soc/au1x/psc-i2s.c
+++ b/sound/soc/au1x/psc-i2s.c
@@ -18,6 +18,7 @@
18 18
19#include <linux/init.h> 19#include <linux/init.h>
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/slab.h>
21#include <linux/suspend.h> 22#include <linux/suspend.h>
22#include <sound/core.h> 23#include <sound/core.h>
23#include <sound/pcm.h> 24#include <sound/pcm.h>
diff --git a/sound/soc/blackfin/bf5xx-ac97-pcm.c b/sound/soc/blackfin/bf5xx-ac97-pcm.c
index 67cbfe7283da..5e7aacf3bb5a 100644
--- a/sound/soc/blackfin/bf5xx-ac97-pcm.c
+++ b/sound/soc/blackfin/bf5xx-ac97-pcm.c
@@ -29,8 +29,8 @@
29#include <linux/module.h> 29#include <linux/module.h>
30#include <linux/init.h> 30#include <linux/init.h>
31#include <linux/platform_device.h> 31#include <linux/platform_device.h>
32#include <linux/slab.h>
33#include <linux/dma-mapping.h> 32#include <linux/dma-mapping.h>
33#include <linux/gfp.h>
34 34
35#include <sound/core.h> 35#include <sound/core.h>
36#include <sound/pcm.h> 36#include <sound/pcm.h>
diff --git a/sound/soc/blackfin/bf5xx-ac97.c b/sound/soc/blackfin/bf5xx-ac97.c
index e69322978739..523b7fc33f4e 100644
--- a/sound/soc/blackfin/bf5xx-ac97.c
+++ b/sound/soc/blackfin/bf5xx-ac97.c
@@ -16,6 +16,7 @@
16#include <linux/interrupt.h> 16#include <linux/interrupt.h>
17#include <linux/wait.h> 17#include <linux/wait.h>
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/slab.h>
19 20
20#include <sound/core.h> 21#include <sound/core.h>
21#include <sound/pcm.h> 22#include <sound/pcm.h>
diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.c b/sound/soc/blackfin/bf5xx-i2s-pcm.c
index c6c6a4a7d948..1d2a1adf2575 100644
--- a/sound/soc/blackfin/bf5xx-i2s-pcm.c
+++ b/sound/soc/blackfin/bf5xx-i2s-pcm.c
@@ -29,8 +29,8 @@
29#include <linux/module.h> 29#include <linux/module.h>
30#include <linux/init.h> 30#include <linux/init.h>
31#include <linux/platform_device.h> 31#include <linux/platform_device.h>
32#include <linux/slab.h>
33#include <linux/dma-mapping.h> 32#include <linux/dma-mapping.h>
33#include <linux/gfp.h>
34 34
35#include <sound/core.h> 35#include <sound/core.h>
36#include <sound/pcm.h> 36#include <sound/pcm.h>
diff --git a/sound/soc/blackfin/bf5xx-tdm-pcm.c b/sound/soc/blackfin/bf5xx-tdm-pcm.c
index 5e03bb2f3cd7..6bac1ac1a315 100644
--- a/sound/soc/blackfin/bf5xx-tdm-pcm.c
+++ b/sound/soc/blackfin/bf5xx-tdm-pcm.c
@@ -29,8 +29,8 @@
29#include <linux/module.h> 29#include <linux/module.h>
30#include <linux/init.h> 30#include <linux/init.h>
31#include <linux/platform_device.h> 31#include <linux/platform_device.h>
32#include <linux/slab.h>
33#include <linux/dma-mapping.h> 32#include <linux/dma-mapping.h>
33#include <linux/gfp.h>
34 34
35#include <sound/core.h> 35#include <sound/core.h>
36#include <sound/pcm.h> 36#include <sound/pcm.h>
diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c
index bcfa53271673..1f5e57a4bb7a 100644
--- a/sound/soc/codecs/ac97.c
+++ b/sound/soc/codecs/ac97.c
@@ -13,6 +13,7 @@
13 */ 13 */
14 14
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/slab.h>
16#include <linux/kernel.h> 17#include <linux/kernel.h>
17#include <linux/device.h> 18#include <linux/device.h>
18#include <sound/core.h> 19#include <sound/core.h>
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c
index 48e1272892f9..217538423225 100644
--- a/sound/soc/codecs/ad1836.c
+++ b/sound/soc/codecs/ad1836.c
@@ -17,6 +17,7 @@
17 */ 17 */
18 18
19#include <linux/init.h> 19#include <linux/init.h>
20#include <linux/slab.h>
20#include <linux/module.h> 21#include <linux/module.h>
21#include <linux/kernel.h> 22#include <linux/kernel.h>
22#include <linux/device.h> 23#include <linux/device.h>
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
index 39c0f7584e65..042072738cdc 100644
--- a/sound/soc/codecs/ad1980.c
+++ b/sound/soc/codecs/ad1980.c
@@ -12,6 +12,7 @@
12 */ 12 */
13 13
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/slab.h>
15#include <linux/module.h> 16#include <linux/module.h>
16#include <linux/kernel.h> 17#include <linux/kernel.h>
17#include <linux/device.h> 18#include <linux/device.h>
diff --git a/sound/soc/codecs/ad73311.c b/sound/soc/codecs/ad73311.c
index d2fcc601722c..475807bea2c2 100644
--- a/sound/soc/codecs/ad73311.c
+++ b/sound/soc/codecs/ad73311.c
@@ -11,6 +11,7 @@
11 */ 11 */
12 12
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/slab.h>
14#include <linux/module.h> 15#include <linux/module.h>
15#include <linux/kernel.h> 16#include <linux/kernel.h>
16#include <linux/device.h> 17#include <linux/device.h>
diff --git a/sound/soc/codecs/ads117x.c b/sound/soc/codecs/ads117x.c
index cc96411ca3e6..f8e75edb27b7 100644
--- a/sound/soc/codecs/ads117x.c
+++ b/sound/soc/codecs/ads117x.c
@@ -11,6 +11,7 @@
11 */ 11 */
12 12
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/slab.h>
14#include <linux/init.h> 15#include <linux/init.h>
15#include <linux/device.h> 16#include <linux/device.h>
16#include <sound/core.h> 17#include <sound/core.h>
diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c
index 962d74682122..192aebda3029 100644
--- a/sound/soc/codecs/ak4104.c
+++ b/sound/soc/codecs/ak4104.c
@@ -10,6 +10,7 @@
10 */ 10 */
11 11
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/slab.h>
13#include <sound/core.h> 14#include <sound/core.h>
14#include <sound/soc.h> 15#include <sound/soc.h>
15#include <sound/initval.h> 16#include <sound/initval.h>
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c
index b5917df0d2a8..d4253675b2d3 100644
--- a/sound/soc/codecs/ak4535.c
+++ b/sound/soc/codecs/ak4535.c
@@ -19,6 +19,7 @@
19#include <linux/pm.h> 19#include <linux/pm.h>
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/slab.h>
22#include <sound/core.h> 23#include <sound/core.h>
23#include <sound/pcm.h> 24#include <sound/pcm.h>
24#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
index 1254a7ac561e..7528a54102b5 100644
--- a/sound/soc/codecs/ak4642.c
+++ b/sound/soc/codecs/ak4642.c
@@ -29,6 +29,7 @@
29#include <linux/pm.h> 29#include <linux/pm.h>
30#include <linux/i2c.h> 30#include <linux/i2c.h>
31#include <linux/platform_device.h> 31#include <linux/platform_device.h>
32#include <linux/slab.h>
32#include <sound/core.h> 33#include <sound/core.h>
33#include <sound/pcm.h> 34#include <sound/pcm.h>
34#include <sound/pcm_params.h> 35#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c
index 18fd4475413c..87566932a3b1 100644
--- a/sound/soc/codecs/ak4671.c
+++ b/sound/soc/codecs/ak4671.c
@@ -15,6 +15,7 @@
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/i2c.h> 16#include <linux/i2c.h>
17#include <linux/delay.h> 17#include <linux/delay.h>
18#include <linux/slab.h>
18#include <sound/soc.h> 19#include <sound/soc.h>
19#include <sound/soc-dapm.h> 20#include <sound/soc-dapm.h>
20#include <sound/initval.h> 21#include <sound/initval.h>
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index a7f09f33c560..30d949239def 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -23,6 +23,7 @@
23 23
24#include <linux/module.h> 24#include <linux/module.h>
25#include <linux/platform_device.h> 25#include <linux/platform_device.h>
26#include <linux/slab.h>
26#include <sound/core.h> 27#include <sound/core.h>
27#include <sound/soc.h> 28#include <sound/soc.h>
28#include <sound/initval.h> 29#include <sound/initval.h>
diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c
index 203e51f91489..f07a415c753f 100644
--- a/sound/soc/codecs/cx20442.c
+++ b/sound/soc/codecs/cx20442.c
@@ -14,6 +14,7 @@
14 */ 14 */
15 15
16#include <linux/tty.h> 16#include <linux/tty.h>
17#include <linux/slab.h>
17 18
18#include <sound/core.h> 19#include <sound/core.h>
19#include <sound/initval.h> 20#include <sound/initval.h>
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c
index b9cbaeb09e05..75af2d6e0e78 100644
--- a/sound/soc/codecs/da7210.c
+++ b/sound/soc/codecs/da7210.c
@@ -23,6 +23,7 @@
23#include <linux/pm.h> 23#include <linux/pm.h>
24#include <linux/i2c.h> 24#include <linux/i2c.h>
25#include <linux/platform_device.h> 25#include <linux/platform_device.h>
26#include <linux/slab.h>
26#include <sound/core.h> 27#include <sound/core.h>
27#include <sound/pcm.h> 28#include <sound/pcm.h>
28#include <sound/pcm_params.h> 29#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/pcm3008.c b/sound/soc/codecs/pcm3008.c
index 2afcd0a8669d..5a5f187a2657 100644
--- a/sound/soc/codecs/pcm3008.c
+++ b/sound/soc/codecs/pcm3008.c
@@ -19,6 +19,7 @@
19#include <linux/kernel.h> 19#include <linux/kernel.h>
20#include <linux/device.h> 20#include <linux/device.h>
21#include <linux/gpio.h> 21#include <linux/gpio.h>
22#include <linux/slab.h>
22#include <sound/core.h> 23#include <sound/core.h>
23#include <sound/pcm.h> 24#include <sound/pcm.h>
24#include <sound/initval.h> 25#include <sound/initval.h>
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c
index f18c8b2d96d4..b47ed4f6ab20 100644
--- a/sound/soc/codecs/ssm2602.c
+++ b/sound/soc/codecs/ssm2602.c
@@ -33,6 +33,7 @@
33#include <linux/pm.h> 33#include <linux/pm.h>
34#include <linux/i2c.h> 34#include <linux/i2c.h>
35#include <linux/platform_device.h> 35#include <linux/platform_device.h>
36#include <linux/slab.h>
36#include <sound/core.h> 37#include <sound/core.h>
37#include <sound/pcm.h> 38#include <sound/pcm.h>
38#include <sound/pcm_params.h> 39#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c
index e90fe295c655..ee86568545c2 100644
--- a/sound/soc/codecs/stac9766.c
+++ b/sound/soc/codecs/stac9766.c
@@ -15,6 +15,7 @@
15 */ 15 */
16 16
17#include <linux/init.h> 17#include <linux/init.h>
18#include <linux/slab.h>
18#include <linux/module.h> 19#include <linux/module.h>
19#include <linux/device.h> 20#include <linux/device.h>
20#include <sound/core.h> 21#include <sound/core.h>
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index 40bcbbad07ff..b0bae3508b29 100644
--- a/sound/soc/codecs/tlv320aic23.c
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -25,6 +25,7 @@
25#include <linux/pm.h> 25#include <linux/pm.h>
26#include <linux/i2c.h> 26#include <linux/i2c.h>
27#include <linux/platform_device.h> 27#include <linux/platform_device.h>
28#include <linux/slab.h>
28#include <sound/core.h> 29#include <sound/core.h>
29#include <sound/pcm.h> 30#include <sound/pcm.h>
30#include <sound/pcm_params.h> 31#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c
index 5856f7aae4d9..f0e00fd4b435 100644
--- a/sound/soc/codecs/tlv320aic26.c
+++ b/sound/soc/codecs/tlv320aic26.c
@@ -13,6 +13,7 @@
13#include <linux/device.h> 13#include <linux/device.h>
14#include <linux/sysfs.h> 14#include <linux/sysfs.h>
15#include <linux/spi/spi.h> 15#include <linux/spi/spi.h>
16#include <linux/slab.h>
16#include <sound/core.h> 17#include <sound/core.h>
17#include <sound/pcm.h> 18#include <sound/pcm.h>
18#include <sound/pcm_params.h> 19#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index eafa164a8f86..71a69908ccf6 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -41,6 +41,7 @@
41#include <linux/gpio.h> 41#include <linux/gpio.h>
42#include <linux/regulator/consumer.h> 42#include <linux/regulator/consumer.h>
43#include <linux/platform_device.h> 43#include <linux/platform_device.h>
44#include <linux/slab.h>
44#include <sound/core.h> 45#include <sound/core.h>
45#include <sound/pcm.h> 46#include <sound/pcm.h>
46#include <sound/pcm_params.h> 47#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
index bcf6d934499a..65adc77eada1 100644
--- a/sound/soc/codecs/tlv320dac33.c
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -31,6 +31,7 @@
31#include <linux/interrupt.h> 31#include <linux/interrupt.h>
32#include <linux/gpio.h> 32#include <linux/gpio.h>
33#include <linux/regulator/consumer.h> 33#include <linux/regulator/consumer.h>
34#include <linux/slab.h>
34#include <sound/core.h> 35#include <sound/core.h>
35#include <sound/pcm.h> 36#include <sound/pcm.h>
36#include <sound/pcm_params.h> 37#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
index 20ac67700395..99b70e5978a2 100644
--- a/sound/soc/codecs/tpa6130a2.c
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -26,6 +26,7 @@
26#include <linux/i2c.h> 26#include <linux/i2c.h>
27#include <linux/gpio.h> 27#include <linux/gpio.h>
28#include <linux/regulator/consumer.h> 28#include <linux/regulator/consumer.h>
29#include <linux/slab.h>
29#include <sound/tpa6130a2-plat.h> 30#include <sound/tpa6130a2-plat.h>
30#include <sound/soc.h> 31#include <sound/soc.h>
31#include <sound/soc-dapm.h> 32#include <sound/soc-dapm.h>
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index 6a34f562b563..b4fcdb01fc49 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -27,6 +27,7 @@
27#include <linux/i2c.h> 27#include <linux/i2c.h>
28#include <linux/platform_device.h> 28#include <linux/platform_device.h>
29#include <linux/i2c/twl.h> 29#include <linux/i2c/twl.h>
30#include <linux/slab.h>
30#include <sound/core.h> 31#include <sound/core.h>
31#include <sound/pcm.h> 32#include <sound/pcm.h>
32#include <sound/pcm_params.h> 33#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c
index 2f4d7287fa3c..28aac53c97bb 100644
--- a/sound/soc/codecs/uda134x.c
+++ b/sound/soc/codecs/uda134x.c
@@ -15,6 +15,7 @@
15 15
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/delay.h> 17#include <linux/delay.h>
18#include <linux/slab.h>
18#include <sound/pcm.h> 19#include <sound/pcm.h>
19#include <sound/pcm_params.h> 20#include <sound/pcm_params.h>
20#include <sound/soc.h> 21#include <sound/soc.h>
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c
index 8de866618bf4..002e289d1255 100644
--- a/sound/soc/codecs/wm2000.c
+++ b/sound/soc/codecs/wm2000.c
@@ -31,6 +31,7 @@
31#include <linux/i2c.h> 31#include <linux/i2c.h>
32#include <linux/platform_device.h> 32#include <linux/platform_device.h>
33#include <linux/debugfs.h> 33#include <linux/debugfs.h>
34#include <linux/slab.h>
34#include <sound/core.h> 35#include <sound/core.h>
35#include <sound/pcm.h> 36#include <sound/pcm.h>
36#include <sound/pcm_params.h> 37#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
index c342c2c9fb49..0221ca79b3ae 100644
--- a/sound/soc/codecs/wm8350.c
+++ b/sound/soc/codecs/wm8350.c
@@ -13,6 +13,7 @@
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/moduleparam.h> 14#include <linux/moduleparam.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/slab.h>
16#include <linux/delay.h> 17#include <linux/delay.h>
17#include <linux/pm.h> 18#include <linux/pm.h>
18#include <linux/platform_device.h> 19#include <linux/platform_device.h>
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c
index 535db3bff866..8f294066b0ed 100644
--- a/sound/soc/codecs/wm8400.c
+++ b/sound/soc/codecs/wm8400.c
@@ -14,6 +14,7 @@
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/moduleparam.h> 15#include <linux/moduleparam.h>
16#include <linux/kernel.h> 16#include <linux/kernel.h>
17#include <linux/slab.h>
17#include <linux/init.h> 18#include <linux/init.h>
18#include <linux/delay.h> 19#include <linux/delay.h>
19#include <linux/pm.h> 20#include <linux/pm.h>
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c
index d3527001b178..0f7bcb61071a 100644
--- a/sound/soc/codecs/wm8510.c
+++ b/sound/soc/codecs/wm8510.c
@@ -19,6 +19,7 @@
19#include <linux/i2c.h> 19#include <linux/i2c.h>
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/spi/spi.h> 21#include <linux/spi/spi.h>
22#include <linux/slab.h>
22#include <sound/core.h> 23#include <sound/core.h>
23#include <sound/pcm.h> 24#include <sound/pcm.h>
24#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c
index 2cdffb0b2a80..37242a7d3077 100644
--- a/sound/soc/codecs/wm8523.c
+++ b/sound/soc/codecs/wm8523.c
@@ -19,6 +19,7 @@
19#include <linux/i2c.h> 19#include <linux/i2c.h>
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/regulator/consumer.h> 21#include <linux/regulator/consumer.h>
22#include <linux/slab.h>
22#include <sound/core.h> 23#include <sound/core.h>
23#include <sound/pcm.h> 24#include <sound/pcm.h>
24#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c
index 94b3f4c4d64e..c3571ee5c11b 100644
--- a/sound/soc/codecs/wm8580.c
+++ b/sound/soc/codecs/wm8580.c
@@ -25,6 +25,7 @@
25#include <linux/i2c.h> 25#include <linux/i2c.h>
26#include <linux/platform_device.h> 26#include <linux/platform_device.h>
27#include <linux/regulator/consumer.h> 27#include <linux/regulator/consumer.h>
28#include <linux/slab.h>
28 29
29#include <sound/core.h> 30#include <sound/core.h>
30#include <sound/pcm.h> 31#include <sound/pcm.h>
diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c
index 5acd35bdfd53..effb14eee7d4 100644
--- a/sound/soc/codecs/wm8711.c
+++ b/sound/soc/codecs/wm8711.c
@@ -20,6 +20,7 @@
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/spi/spi.h> 22#include <linux/spi/spi.h>
23#include <linux/slab.h>
23#include <sound/core.h> 24#include <sound/core.h>
24#include <sound/pcm.h> 25#include <sound/pcm.h>
25#include <sound/pcm_params.h> 26#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/wm8727.c b/sound/soc/codecs/wm8727.c
index 63a254e293ca..1072621e93fd 100644
--- a/sound/soc/codecs/wm8727.c
+++ b/sound/soc/codecs/wm8727.c
@@ -13,6 +13,7 @@
13 */ 13 */
14 14
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/slab.h>
16#include <linux/module.h> 17#include <linux/module.h>
17#include <linux/kernel.h> 18#include <linux/kernel.h>
18#include <linux/device.h> 19#include <linux/device.h>
diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c
index bf56a58d0916..34be2d2b69ef 100644
--- a/sound/soc/codecs/wm8728.c
+++ b/sound/soc/codecs/wm8728.c
@@ -18,6 +18,7 @@
18#include <linux/i2c.h> 18#include <linux/i2c.h>
19#include <linux/platform_device.h> 19#include <linux/platform_device.h>
20#include <linux/spi/spi.h> 20#include <linux/spi/spi.h>
21#include <linux/slab.h>
21#include <sound/core.h> 22#include <sound/core.h>
22#include <sound/pcm.h> 23#include <sound/pcm.h>
23#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index e17c714196f2..0ab9b6355297 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -18,6 +18,7 @@
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/pm.h> 19#include <linux/pm.h>
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include <linux/slab.h>
21#include <linux/platform_device.h> 22#include <linux/platform_device.h>
22#include <linux/regulator/consumer.h> 23#include <linux/regulator/consumer.h>
23#include <linux/spi/spi.h> 24#include <linux/spi/spi.h>
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
index 60d7cf88bf1d..9407e193fcc3 100644
--- a/sound/soc/codecs/wm8750.c
+++ b/sound/soc/codecs/wm8750.c
@@ -20,6 +20,7 @@
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/spi/spi.h> 22#include <linux/spi/spi.h>
23#include <linux/slab.h>
23#include <sound/core.h> 24#include <sound/core.h>
24#include <sound/pcm.h> 25#include <sound/pcm.h>
25#include <sound/pcm_params.h> 26#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index f9e56a1dfde1..b59f349c5218 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -40,6 +40,7 @@
40#include <linux/i2c.h> 40#include <linux/i2c.h>
41#include <linux/platform_device.h> 41#include <linux/platform_device.h>
42#include <linux/spi/spi.h> 42#include <linux/spi/spi.h>
43#include <linux/slab.h>
43#include <sound/core.h> 44#include <sound/core.h>
44#include <sound/pcm.h> 45#include <sound/pcm.h>
45#include <sound/pcm_params.h> 46#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c
index 694600969d67..7e4a627b4c7e 100644
--- a/sound/soc/codecs/wm8776.c
+++ b/sound/soc/codecs/wm8776.c
@@ -20,6 +20,7 @@
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/spi/spi.h> 22#include <linux/spi/spi.h>
23#include <linux/slab.h>
23#include <sound/core.h> 24#include <sound/core.h>
24#include <sound/pcm.h> 25#include <sound/pcm.h>
25#include <sound/pcm_params.h> 26#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c
index 19a6b25988c8..5da17a704e5a 100644
--- a/sound/soc/codecs/wm8900.c
+++ b/sound/soc/codecs/wm8900.c
@@ -24,6 +24,7 @@
24#include <linux/pm.h> 24#include <linux/pm.h>
25#include <linux/i2c.h> 25#include <linux/i2c.h>
26#include <linux/platform_device.h> 26#include <linux/platform_device.h>
27#include <linux/slab.h>
27#include <sound/core.h> 28#include <sound/core.h>
28#include <sound/pcm.h> 29#include <sound/pcm.h>
29#include <sound/pcm_params.h> 30#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index 05b28cf0f96f..bf08282d5ee5 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -22,6 +22,7 @@
22#include <linux/pm.h> 22#include <linux/pm.h>
23#include <linux/i2c.h> 23#include <linux/i2c.h>
24#include <linux/platform_device.h> 24#include <linux/platform_device.h>
25#include <linux/slab.h>
25#include <sound/core.h> 26#include <sound/core.h>
26#include <sound/jack.h> 27#include <sound/jack.h>
27#include <sound/pcm.h> 28#include <sound/pcm.h>
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index a022ca7e7585..87f14f8675fa 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -19,6 +19,7 @@
19#include <linux/i2c.h> 19#include <linux/i2c.h>
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/regulator/consumer.h> 21#include <linux/regulator/consumer.h>
22#include <linux/slab.h>
22#include <sound/core.h> 23#include <sound/core.h>
23#include <sound/pcm.h> 24#include <sound/pcm.h>
24#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c
index e313ab5de85a..e3c4bbfaae27 100644
--- a/sound/soc/codecs/wm8940.c
+++ b/sound/soc/codecs/wm8940.c
@@ -30,6 +30,7 @@
30#include <linux/i2c.h> 30#include <linux/i2c.h>
31#include <linux/platform_device.h> 31#include <linux/platform_device.h>
32#include <linux/spi/spi.h> 32#include <linux/spi/spi.h>
33#include <linux/slab.h>
33#include <sound/core.h> 34#include <sound/core.h>
34#include <sound/pcm.h> 35#include <sound/pcm.h>
35#include <sound/pcm_params.h> 36#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c
index 5f0bde56cf0d..fedb76452f1b 100644
--- a/sound/soc/codecs/wm8955.c
+++ b/sound/soc/codecs/wm8955.c
@@ -18,6 +18,7 @@
18#include <linux/i2c.h> 18#include <linux/i2c.h>
19#include <linux/platform_device.h> 19#include <linux/platform_device.h>
20#include <linux/regulator/consumer.h> 20#include <linux/regulator/consumer.h>
21#include <linux/slab.h>
21#include <sound/core.h> 22#include <sound/core.h>
22#include <sound/pcm.h> 23#include <sound/pcm.h>
23#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index 518c84e623ab..7233cc68435a 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -15,6 +15,7 @@
15#include <linux/pm.h> 15#include <linux/pm.h>
16#include <linux/i2c.h> 16#include <linux/i2c.h>
17#include <linux/platform_device.h> 17#include <linux/platform_device.h>
18#include <linux/slab.h>
18#include <sound/core.h> 19#include <sound/core.h>
19#include <sound/pcm.h> 20#include <sound/pcm.h>
20#include <sound/pcm_params.h> 21#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c
index bab393feb945..5b9a756242f1 100644
--- a/sound/soc/codecs/wm8961.c
+++ b/sound/soc/codecs/wm8961.c
@@ -18,6 +18,7 @@
18#include <linux/pm.h> 18#include <linux/pm.h>
19#include <linux/i2c.h> 19#include <linux/i2c.h>
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/slab.h>
21#include <sound/core.h> 22#include <sound/core.h>
22#include <sound/pcm.h> 23#include <sound/pcm.h>
23#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c
index 95c9ec3862d5..a99620f335d2 100644
--- a/sound/soc/codecs/wm8971.c
+++ b/sound/soc/codecs/wm8971.c
@@ -20,6 +20,7 @@
20#include <linux/pm.h> 20#include <linux/pm.h>
21#include <linux/i2c.h> 21#include <linux/i2c.h>
22#include <linux/platform_device.h> 22#include <linux/platform_device.h>
23#include <linux/slab.h>
23#include <sound/core.h> 24#include <sound/core.h>
24#include <sound/pcm.h> 25#include <sound/pcm.h>
25#include <sound/pcm_params.h> 26#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c
index 44841fec5545..a2c4b2f37cca 100644
--- a/sound/soc/codecs/wm8974.c
+++ b/sound/soc/codecs/wm8974.c
@@ -18,6 +18,7 @@
18#include <linux/pm.h> 18#include <linux/pm.h>
19#include <linux/i2c.h> 19#include <linux/i2c.h>
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/slab.h>
21#include <sound/core.h> 22#include <sound/core.h>
22#include <sound/pcm.h> 23#include <sound/pcm.h>
23#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c
index 6866a6a80fec..51d5f433215c 100644
--- a/sound/soc/codecs/wm8978.c
+++ b/sound/soc/codecs/wm8978.c
@@ -19,6 +19,7 @@
19#include <linux/pm.h> 19#include <linux/pm.h>
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/slab.h>
22#include <sound/core.h> 23#include <sound/core.h>
23#include <sound/pcm.h> 24#include <sound/pcm.h>
24#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c
index 563cf898dafc..0417dae32e6f 100644
--- a/sound/soc/codecs/wm8988.c
+++ b/sound/soc/codecs/wm8988.c
@@ -19,6 +19,7 @@
19#include <linux/i2c.h> 19#include <linux/i2c.h>
20#include <linux/spi/spi.h> 20#include <linux/spi/spi.h>
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/slab.h>
22#include <sound/core.h> 23#include <sound/core.h>
23#include <sound/pcm.h> 24#include <sound/pcm.h>
24#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index 731bc0775f44..dd8d909788c1 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -18,6 +18,7 @@
18#include <linux/pm.h> 18#include <linux/pm.h>
19#include <linux/i2c.h> 19#include <linux/i2c.h>
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/slab.h>
21#include <sound/core.h> 22#include <sound/core.h>
22#include <sound/pcm.h> 23#include <sound/pcm.h>
23#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c
index e739c5008b1b..d8d300c6175f 100644
--- a/sound/soc/codecs/wm8993.c
+++ b/sound/soc/codecs/wm8993.c
@@ -18,6 +18,7 @@
18#include <linux/i2c.h> 18#include <linux/i2c.h>
19#include <linux/regulator/consumer.h> 19#include <linux/regulator/consumer.h>
20#include <linux/spi/spi.h> 20#include <linux/spi/spi.h>
21#include <linux/slab.h>
21#include <sound/core.h> 22#include <sound/core.h>
22#include <sound/pcm.h> 23#include <sound/pcm.h>
23#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index dda356591fdb..e84a1177f350 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -19,6 +19,7 @@
19#include <linux/i2c.h> 19#include <linux/i2c.h>
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/regulator/consumer.h> 21#include <linux/regulator/consumer.h>
22#include <linux/slab.h>
22#include <sound/core.h> 23#include <sound/core.h>
23#include <sound/pcm.h> 24#include <sound/pcm.h>
24#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c
index 87a87487d3f9..13186fb4dcb4 100644
--- a/sound/soc/codecs/wm9081.c
+++ b/sound/soc/codecs/wm9081.c
@@ -18,6 +18,7 @@
18#include <linux/pm.h> 18#include <linux/pm.h>
19#include <linux/i2c.h> 19#include <linux/i2c.h>
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/slab.h>
21#include <sound/core.h> 22#include <sound/core.h>
22#include <sound/pcm.h> 23#include <sound/pcm.h>
23#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c
index ec54c6da9856..8793341849d1 100644
--- a/sound/soc/codecs/wm9705.c
+++ b/sound/soc/codecs/wm9705.c
@@ -10,6 +10,7 @@
10 */ 10 */
11 11
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/slab.h>
13#include <linux/module.h> 14#include <linux/module.h>
14#include <linux/kernel.h> 15#include <linux/kernel.h>
15#include <linux/device.h> 16#include <linux/device.h>
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index dd4b6ce01ceb..28790a2ffe8d 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -11,6 +11,7 @@
11 */ 11 */
12 12
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/slab.h>
14#include <linux/module.h> 15#include <linux/module.h>
15#include <linux/kernel.h> 16#include <linux/kernel.h>
16#include <linux/device.h> 17#include <linux/device.h>
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index 6a30b844a671..34e0c91092fa 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -16,6 +16,7 @@
16 */ 16 */
17 17
18#include <linux/init.h> 18#include <linux/init.h>
19#include <linux/slab.h>
19#include <linux/module.h> 20#include <linux/module.h>
20#include <linux/device.h> 21#include <linux/device.h>
21#include <sound/core.h> 22#include <sound/core.h>
diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c
index 4aad7ecc90a2..adadcd3aa1b1 100644
--- a/sound/soc/davinci/davinci-i2s.c
+++ b/sound/soc/davinci/davinci-i2s.c
@@ -12,6 +12,7 @@
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/device.h> 14#include <linux/device.h>
15#include <linux/slab.h>
15#include <linux/delay.h> 16#include <linux/delay.h>
16#include <linux/io.h> 17#include <linux/io.h>
17#include <linux/clk.h> 18#include <linux/clk.h>
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index c056bfbe0340..79f0f4ad242c 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -18,6 +18,7 @@
18#include <linux/init.h> 18#include <linux/init.h>
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/device.h> 20#include <linux/device.h>
21#include <linux/slab.h>
21#include <linux/delay.h> 22#include <linux/delay.h>
22#include <linux/io.h> 23#include <linux/io.h>
23#include <linux/clk.h> 24#include <linux/clk.h>
diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c
index b1a3a278819f..410c7496a18d 100644
--- a/sound/soc/fsl/fsl_dma.c
+++ b/sound/soc/fsl/fsl_dma.c
@@ -19,6 +19,7 @@
19#include <linux/dma-mapping.h> 19#include <linux/dma-mapping.h>
20#include <linux/interrupt.h> 20#include <linux/interrupt.h>
21#include <linux/delay.h> 21#include <linux/delay.h>
22#include <linux/gfp.h>
22 23
23#include <sound/core.h> 24#include <sound/core.h>
24#include <sound/pcm.h> 25#include <sound/pcm.h>
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 93f0f38a32c9..762c1b8e8e4e 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -14,6 +14,7 @@
14#include <linux/interrupt.h> 14#include <linux/interrupt.h>
15#include <linux/device.h> 15#include <linux/device.h>
16#include <linux/delay.h> 16#include <linux/delay.h>
17#include <linux/slab.h>
17 18
18#include <sound/core.h> 19#include <sound/core.h>
19#include <sound/pcm.h> 20#include <sound/pcm.h>
diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c
index 30ed568afb2e..1d4e7164e80a 100644
--- a/sound/soc/fsl/mpc5200_dma.c
+++ b/sound/soc/fsl/mpc5200_dma.c
@@ -8,6 +8,7 @@
8 8
9#include <linux/module.h> 9#include <linux/module.h>
10#include <linux/of_device.h> 10#include <linux/of_device.h>
11#include <linux/slab.h>
11 12
12#include <sound/soc.h> 13#include <sound/soc.h>
13 14
@@ -379,8 +380,8 @@ int mpc5200_audio_dma_create(struct of_device *op)
379 int ret; 380 int ret;
380 381
381 /* Fetch the registers and IRQ of the PSC */ 382 /* Fetch the registers and IRQ of the PSC */
382 irq = irq_of_parse_and_map(op->node, 0); 383 irq = irq_of_parse_and_map(op->dev.of_node, 0);
383 if (of_address_to_resource(op->node, 0, &res)) { 384 if (of_address_to_resource(op->dev.of_node, 0, &res)) {
384 dev_err(&op->dev, "Missing reg property\n"); 385 dev_err(&op->dev, "Missing reg property\n");
385 return -ENODEV; 386 return -ENODEV;
386 } 387 }
@@ -398,7 +399,7 @@ int mpc5200_audio_dma_create(struct of_device *op)
398 } 399 }
399 400
400 /* Get the PSC ID */ 401 /* Get the PSC ID */
401 prop = of_get_property(op->node, "cell-index", &size); 402 prop = of_get_property(op->dev.of_node, "cell-index", &size);
402 if (!prop || size < sizeof *prop) { 403 if (!prop || size < sizeof *prop) {
403 ret = -ENODEV; 404 ret = -ENODEV;
404 goto out_free; 405 goto out_free;
diff --git a/sound/soc/fsl/mpc5200_psc_ac97.c b/sound/soc/fsl/mpc5200_psc_ac97.c
index 3dbc7f7cd7b9..e2ee220bfb7e 100644
--- a/sound/soc/fsl/mpc5200_psc_ac97.c
+++ b/sound/soc/fsl/mpc5200_psc_ac97.c
@@ -317,12 +317,12 @@ static struct of_device_id psc_ac97_match[] __devinitdata = {
317MODULE_DEVICE_TABLE(of, psc_ac97_match); 317MODULE_DEVICE_TABLE(of, psc_ac97_match);
318 318
319static struct of_platform_driver psc_ac97_driver = { 319static struct of_platform_driver psc_ac97_driver = {
320 .match_table = psc_ac97_match,
321 .probe = psc_ac97_of_probe, 320 .probe = psc_ac97_of_probe,
322 .remove = __devexit_p(psc_ac97_of_remove), 321 .remove = __devexit_p(psc_ac97_of_remove),
323 .driver = { 322 .driver = {
324 .name = "mpc5200-psc-ac97", 323 .name = "mpc5200-psc-ac97",
325 .owner = THIS_MODULE, 324 .owner = THIS_MODULE,
325 .of_match_table = psc_ac97_match,
326 }, 326 },
327}; 327};
328 328
diff --git a/sound/soc/fsl/mpc5200_psc_i2s.c b/sound/soc/fsl/mpc5200_psc_i2s.c
index ce8de90fb94a..4f455bd6851f 100644
--- a/sound/soc/fsl/mpc5200_psc_i2s.c
+++ b/sound/soc/fsl/mpc5200_psc_i2s.c
@@ -181,7 +181,7 @@ static int __devinit psc_i2s_of_probe(struct of_device *op,
181 181
182 /* Check for the codec handle. If it is not present then we 182 /* Check for the codec handle. If it is not present then we
183 * are done */ 183 * are done */
184 if (!of_get_property(op->node, "codec-handle", NULL)) 184 if (!of_get_property(op->dev.of_node, "codec-handle", NULL))
185 return 0; 185 return 0;
186 186
187 /* Due to errata in the dma mode; need to line up enabling 187 /* Due to errata in the dma mode; need to line up enabling
@@ -220,12 +220,12 @@ static struct of_device_id psc_i2s_match[] __devinitdata = {
220MODULE_DEVICE_TABLE(of, psc_i2s_match); 220MODULE_DEVICE_TABLE(of, psc_i2s_match);
221 221
222static struct of_platform_driver psc_i2s_driver = { 222static struct of_platform_driver psc_i2s_driver = {
223 .match_table = psc_i2s_match,
224 .probe = psc_i2s_of_probe, 223 .probe = psc_i2s_of_probe,
225 .remove = __devexit_p(psc_i2s_of_remove), 224 .remove = __devexit_p(psc_i2s_of_remove),
226 .driver = { 225 .driver = {
227 .name = "mpc5200-psc-i2s", 226 .name = "mpc5200-psc-i2s",
228 .owner = THIS_MODULE, 227 .owner = THIS_MODULE,
228 .of_match_table = psc_i2s_match,
229 }, 229 },
230}; 230};
231 231
diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c
index ef67d1cdffe7..6a2764ee8203 100644
--- a/sound/soc/fsl/mpc8610_hpcd.c
+++ b/sound/soc/fsl/mpc8610_hpcd.c
@@ -9,6 +9,7 @@
9 * express or implied. 9 * express or implied.
10 */ 10 */
11 11
12#include <linux/slab.h>
12#include <linux/module.h> 13#include <linux/module.h>
13#include <linux/interrupt.h> 14#include <linux/interrupt.h>
14#include <linux/of_device.h> 15#include <linux/of_device.h>
@@ -202,7 +203,7 @@ static struct snd_soc_ops mpc8610_hpcd_ops = {
202static int mpc8610_hpcd_probe(struct of_device *ofdev, 203static int mpc8610_hpcd_probe(struct of_device *ofdev,
203 const struct of_device_id *match) 204 const struct of_device_id *match)
204{ 205{
205 struct device_node *np = ofdev->node; 206 struct device_node *np = ofdev->dev.of_node;
206 struct device_node *codec_np = NULL; 207 struct device_node *codec_np = NULL;
207 struct device_node *guts_np = NULL; 208 struct device_node *guts_np = NULL;
208 struct device_node *dma_np = NULL; 209 struct device_node *dma_np = NULL;
@@ -579,9 +580,11 @@ static struct of_device_id mpc8610_hpcd_match[] = {
579MODULE_DEVICE_TABLE(of, mpc8610_hpcd_match); 580MODULE_DEVICE_TABLE(of, mpc8610_hpcd_match);
580 581
581static struct of_platform_driver mpc8610_hpcd_of_driver = { 582static struct of_platform_driver mpc8610_hpcd_of_driver = {
582 .owner = THIS_MODULE, 583 .driver = {
583 .name = "mpc8610_hpcd", 584 .name = "mpc8610_hpcd",
584 .match_table = mpc8610_hpcd_match, 585 .owner = THIS_MODULE,
586 .of_match_table = mpc8610_hpcd_match,
587 },
585 .probe = mpc8610_hpcd_probe, 588 .probe = mpc8610_hpcd_probe,
586 .remove = mpc8610_hpcd_remove, 589 .remove = mpc8610_hpcd_remove,
587}; 590};
diff --git a/sound/soc/fsl/soc-of-simple.c b/sound/soc/fsl/soc-of-simple.c
index 8bc5cd9e972f..3bc13fd89096 100644
--- a/sound/soc/fsl/soc-of-simple.c
+++ b/sound/soc/fsl/soc-of-simple.c
@@ -12,6 +12,7 @@
12#include <linux/bitops.h> 12#include <linux/bitops.h>
13#include <linux/platform_device.h> 13#include <linux/platform_device.h>
14#include <linux/of.h> 14#include <linux/of.h>
15#include <linux/slab.h>
15#include <sound/core.h> 16#include <sound/core.h>
16#include <sound/pcm.h> 17#include <sound/pcm.h>
17#include <sound/pcm_params.h> 18#include <sound/pcm_params.h>
diff --git a/sound/soc/imx/imx-pcm-dma-mx2.c b/sound/soc/imx/imx-pcm-dma-mx2.c
index 93272966b848..05f19c9284f4 100644
--- a/sound/soc/imx/imx-pcm-dma-mx2.c
+++ b/sound/soc/imx/imx-pcm-dma-mx2.c
@@ -19,6 +19,7 @@
19#include <linux/interrupt.h> 19#include <linux/interrupt.h>
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/slab.h>
22 23
23#include <sound/core.h> 24#include <sound/core.h>
24#include <sound/initval.h> 25#include <sound/initval.h>
@@ -72,7 +73,8 @@ static void snd_imx_dma_err_callback(int channel, void *data, int err)
72{ 73{
73 struct snd_pcm_substream *substream = data; 74 struct snd_pcm_substream *substream = data;
74 struct snd_soc_pcm_runtime *rtd = substream->private_data; 75 struct snd_soc_pcm_runtime *rtd = substream->private_data;
75 struct imx_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data; 76 struct imx_pcm_dma_params *dma_params =
77 snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
76 struct snd_pcm_runtime *runtime = substream->runtime; 78 struct snd_pcm_runtime *runtime = substream->runtime;
77 struct imx_pcm_runtime_data *iprtd = runtime->private_data; 79 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
78 int ret; 80 int ret;
@@ -101,7 +103,7 @@ static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream)
101 struct imx_pcm_runtime_data *iprtd = runtime->private_data; 103 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
102 int ret; 104 int ret;
103 105
104 dma_params = snd_soc_get_dma_data(rtd->dai->cpu_dai, substream); 106 dma_params = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
105 107
106 iprtd->dma = imx_dma_request_by_prio(DRV_NAME, DMA_PRIO_HIGH); 108 iprtd->dma = imx_dma_request_by_prio(DRV_NAME, DMA_PRIO_HIGH);
107 if (iprtd->dma < 0) { 109 if (iprtd->dma < 0) {
@@ -211,7 +213,7 @@ static int snd_imx_pcm_prepare(struct snd_pcm_substream *substream)
211 struct imx_pcm_runtime_data *iprtd = runtime->private_data; 213 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
212 int err; 214 int err;
213 215
214 dma_params = snd_soc_get_dma_data(rtd->dai->cpu_dai, substream); 216 dma_params = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
215 217
216 iprtd->substream = substream; 218 iprtd->substream = substream;
217 iprtd->buf = (unsigned int *)substream->dma_buffer.area; 219 iprtd->buf = (unsigned int *)substream->dma_buffer.area;
diff --git a/sound/soc/imx/imx-pcm-fiq.c b/sound/soc/imx/imx-pcm-fiq.c
index ecec332121f2..6b518e07eea9 100644
--- a/sound/soc/imx/imx-pcm-fiq.c
+++ b/sound/soc/imx/imx-pcm-fiq.c
@@ -19,6 +19,7 @@
19#include <linux/interrupt.h> 19#include <linux/interrupt.h>
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/slab.h>
22 23
23#include <sound/core.h> 24#include <sound/core.h>
24#include <sound/initval.h> 25#include <sound/initval.h>
diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c
index 1bf9dc88babf..80b4fee2442b 100644
--- a/sound/soc/imx/imx-ssi.c
+++ b/sound/soc/imx/imx-ssi.c
@@ -39,6 +39,7 @@
39#include <linux/interrupt.h> 39#include <linux/interrupt.h>
40#include <linux/module.h> 40#include <linux/module.h>
41#include <linux/platform_device.h> 41#include <linux/platform_device.h>
42#include <linux/slab.h>
42 43
43#include <sound/core.h> 44#include <sound/core.h>
44#include <sound/initval.h> 45#include <sound/initval.h>
diff --git a/sound/soc/omap/mcpdm.c b/sound/soc/omap/mcpdm.c
index 479d3b6306d7..90b8bf71c893 100644
--- a/sound/soc/omap/mcpdm.c
+++ b/sound/soc/omap/mcpdm.c
@@ -25,6 +25,7 @@
25#include <linux/device.h> 25#include <linux/device.h>
26#include <linux/platform_device.h> 26#include <linux/platform_device.h>
27#include <linux/wait.h> 27#include <linux/wait.h>
28#include <linux/slab.h>
28#include <linux/interrupt.h> 29#include <linux/interrupt.h>
29#include <linux/err.h> 30#include <linux/err.h>
30#include <linux/clk.h> 31#include <linux/clk.h>
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c
index 39456447132c..1e521904ea64 100644
--- a/sound/soc/omap/omap-pcm.c
+++ b/sound/soc/omap/omap-pcm.c
@@ -23,6 +23,7 @@
23 */ 23 */
24 24
25#include <linux/dma-mapping.h> 25#include <linux/dma-mapping.h>
26#include <linux/slab.h>
26#include <sound/core.h> 27#include <sound/core.h>
27#include <sound/pcm.h> 28#include <sound/pcm.h>
28#include <sound/pcm_params.h> 29#include <sound/pcm_params.h>
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig
index 495a36fba360..e30c8325f35e 100644
--- a/sound/soc/pxa/Kconfig
+++ b/sound/soc/pxa/Kconfig
@@ -23,6 +23,7 @@ config SND_PXA2XX_SOC_I2S
23 23
24config SND_PXA_SOC_SSP 24config SND_PXA_SOC_SSP
25 tristate 25 tristate
26 select PXA_SSP
26 27
27config SND_PXA2XX_SOC_CORGI 28config SND_PXA2XX_SOC_CORGI
28 tristate "SoC Audio support for Sharp Zaurus SL-C7x0" 29 tristate "SoC Audio support for Sharp Zaurus SL-C7x0"
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
index 6959c5199160..a1fd23e0e3d0 100644
--- a/sound/soc/pxa/pxa-ssp.c
+++ b/sound/soc/pxa/pxa-ssp.c
@@ -16,6 +16,7 @@
16 16
17#include <linux/init.h> 17#include <linux/init.h>
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/slab.h>
19#include <linux/platform_device.h> 20#include <linux/platform_device.h>
20#include <linux/clk.h> 21#include <linux/clk.h>
21#include <linux/io.h> 22#include <linux/io.h>
@@ -31,9 +32,8 @@
31 32
32#include <mach/hardware.h> 33#include <mach/hardware.h>
33#include <mach/dma.h> 34#include <mach/dma.h>
34#include <mach/regs-ssp.h>
35#include <mach/audio.h> 35#include <mach/audio.h>
36#include <mach/ssp.h> 36#include <plat/ssp.h>
37 37
38#include "pxa2xx-pcm.h" 38#include "pxa2xx-pcm.h"
39#include "pxa-ssp.h" 39#include "pxa-ssp.h"
@@ -56,15 +56,15 @@ struct ssp_priv {
56static void dump_registers(struct ssp_device *ssp) 56static void dump_registers(struct ssp_device *ssp)
57{ 57{
58 dev_dbg(&ssp->pdev->dev, "SSCR0 0x%08x SSCR1 0x%08x SSTO 0x%08x\n", 58 dev_dbg(&ssp->pdev->dev, "SSCR0 0x%08x SSCR1 0x%08x SSTO 0x%08x\n",
59 ssp_read_reg(ssp, SSCR0), ssp_read_reg(ssp, SSCR1), 59 pxa_ssp_read_reg(ssp, SSCR0), pxa_ssp_read_reg(ssp, SSCR1),
60 ssp_read_reg(ssp, SSTO)); 60 pxa_ssp_read_reg(ssp, SSTO));
61 61
62 dev_dbg(&ssp->pdev->dev, "SSPSP 0x%08x SSSR 0x%08x SSACD 0x%08x\n", 62 dev_dbg(&ssp->pdev->dev, "SSPSP 0x%08x SSSR 0x%08x SSACD 0x%08x\n",
63 ssp_read_reg(ssp, SSPSP), ssp_read_reg(ssp, SSSR), 63 pxa_ssp_read_reg(ssp, SSPSP), pxa_ssp_read_reg(ssp, SSSR),
64 ssp_read_reg(ssp, SSACD)); 64 pxa_ssp_read_reg(ssp, SSACD));
65} 65}
66 66
67static void ssp_enable(struct ssp_device *ssp) 67static void pxa_ssp_enable(struct ssp_device *ssp)
68{ 68{
69 uint32_t sscr0; 69 uint32_t sscr0;
70 70
@@ -72,7 +72,7 @@ static void ssp_enable(struct ssp_device *ssp)
72 __raw_writel(sscr0, ssp->mmio_base + SSCR0); 72 __raw_writel(sscr0, ssp->mmio_base + SSCR0);
73} 73}
74 74
75static void ssp_disable(struct ssp_device *ssp) 75static void pxa_ssp_disable(struct ssp_device *ssp)
76{ 76{
77 uint32_t sscr0; 77 uint32_t sscr0;
78 78
@@ -86,7 +86,7 @@ struct pxa2xx_pcm_dma_data {
86}; 86};
87 87
88static struct pxa2xx_pcm_dma_params * 88static struct pxa2xx_pcm_dma_params *
89ssp_get_dma_params(struct ssp_device *ssp, int width4, int out) 89pxa_ssp_get_dma_params(struct ssp_device *ssp, int width4, int out)
90{ 90{
91 struct pxa2xx_pcm_dma_data *dma; 91 struct pxa2xx_pcm_dma_data *dma;
92 92
@@ -118,7 +118,7 @@ static int pxa_ssp_startup(struct snd_pcm_substream *substream,
118 118
119 if (!cpu_dai->active) { 119 if (!cpu_dai->active) {
120 clk_enable(ssp->clk); 120 clk_enable(ssp->clk);
121 ssp_disable(ssp); 121 pxa_ssp_disable(ssp);
122 } 122 }
123 123
124 kfree(snd_soc_dai_get_dma_data(cpu_dai, substream)); 124 kfree(snd_soc_dai_get_dma_data(cpu_dai, substream));
@@ -136,7 +136,7 @@ static void pxa_ssp_shutdown(struct snd_pcm_substream *substream,
136 struct ssp_device *ssp = priv->ssp; 136 struct ssp_device *ssp = priv->ssp;
137 137
138 if (!cpu_dai->active) { 138 if (!cpu_dai->active) {
139 ssp_disable(ssp); 139 pxa_ssp_disable(ssp);
140 clk_disable(ssp->clk); 140 clk_disable(ssp->clk);
141 } 141 }
142 142
@@ -159,7 +159,7 @@ static int pxa_ssp_suspend(struct snd_soc_dai *cpu_dai)
159 priv->to = __raw_readl(ssp->mmio_base + SSTO); 159 priv->to = __raw_readl(ssp->mmio_base + SSTO);
160 priv->psp = __raw_readl(ssp->mmio_base + SSPSP); 160 priv->psp = __raw_readl(ssp->mmio_base + SSPSP);
161 161
162 ssp_disable(ssp); 162 pxa_ssp_disable(ssp);
163 clk_disable(ssp->clk); 163 clk_disable(ssp->clk);
164 return 0; 164 return 0;
165} 165}
@@ -179,7 +179,7 @@ static int pxa_ssp_resume(struct snd_soc_dai *cpu_dai)
179 __raw_writel(priv->psp, ssp->mmio_base + SSPSP); 179 __raw_writel(priv->psp, ssp->mmio_base + SSPSP);
180 180
181 if (cpu_dai->active) 181 if (cpu_dai->active)
182 ssp_enable(ssp); 182 pxa_ssp_enable(ssp);
183 else 183 else
184 clk_disable(ssp->clk); 184 clk_disable(ssp->clk);
185 185
@@ -195,9 +195,9 @@ static int pxa_ssp_resume(struct snd_soc_dai *cpu_dai)
195 * ssp_set_clkdiv - set SSP clock divider 195 * ssp_set_clkdiv - set SSP clock divider
196 * @div: serial clock rate divider 196 * @div: serial clock rate divider
197 */ 197 */
198static void ssp_set_scr(struct ssp_device *ssp, u32 div) 198static void pxa_ssp_set_scr(struct ssp_device *ssp, u32 div)
199{ 199{
200 u32 sscr0 = ssp_read_reg(ssp, SSCR0); 200 u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0);
201 201
202 if (cpu_is_pxa25x() && ssp->type == PXA25x_SSP) { 202 if (cpu_is_pxa25x() && ssp->type == PXA25x_SSP) {
203 sscr0 &= ~0x0000ff00; 203 sscr0 &= ~0x0000ff00;
@@ -206,15 +206,15 @@ static void ssp_set_scr(struct ssp_device *ssp, u32 div)
206 sscr0 &= ~0x000fff00; 206 sscr0 &= ~0x000fff00;
207 sscr0 |= (div - 1) << 8; /* 1..4096 */ 207 sscr0 |= (div - 1) << 8; /* 1..4096 */
208 } 208 }
209 ssp_write_reg(ssp, SSCR0, sscr0); 209 pxa_ssp_write_reg(ssp, SSCR0, sscr0);
210} 210}
211 211
212/** 212/**
213 * ssp_get_clkdiv - get SSP clock divider 213 * pxa_ssp_get_clkdiv - get SSP clock divider
214 */ 214 */
215static u32 ssp_get_scr(struct ssp_device *ssp) 215static u32 pxa_ssp_get_scr(struct ssp_device *ssp)
216{ 216{
217 u32 sscr0 = ssp_read_reg(ssp, SSCR0); 217 u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0);
218 u32 div; 218 u32 div;
219 219
220 if (cpu_is_pxa25x() && ssp->type == PXA25x_SSP) 220 if (cpu_is_pxa25x() && ssp->type == PXA25x_SSP)
@@ -234,7 +234,7 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
234 struct ssp_device *ssp = priv->ssp; 234 struct ssp_device *ssp = priv->ssp;
235 int val; 235 int val;
236 236
237 u32 sscr0 = ssp_read_reg(ssp, SSCR0) & 237 u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0) &
238 ~(SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ACS); 238 ~(SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ACS);
239 239
240 dev_dbg(&ssp->pdev->dev, 240 dev_dbg(&ssp->pdev->dev,
@@ -262,7 +262,7 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
262 break; 262 break;
263 case PXA_SSP_CLK_AUDIO: 263 case PXA_SSP_CLK_AUDIO:
264 priv->sysclk = 0; 264 priv->sysclk = 0;
265 ssp_set_scr(ssp, 1); 265 pxa_ssp_set_scr(ssp, 1);
266 sscr0 |= SSCR0_ACS; 266 sscr0 |= SSCR0_ACS;
267 break; 267 break;
268 default: 268 default:
@@ -273,8 +273,8 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
273 * on PXA2xx. On PXA3xx it must be enabled when doing so. */ 273 * on PXA2xx. On PXA3xx it must be enabled when doing so. */
274 if (!cpu_is_pxa3xx()) 274 if (!cpu_is_pxa3xx())
275 clk_disable(ssp->clk); 275 clk_disable(ssp->clk);
276 val = ssp_read_reg(ssp, SSCR0) | sscr0; 276 val = pxa_ssp_read_reg(ssp, SSCR0) | sscr0;
277 ssp_write_reg(ssp, SSCR0, val); 277 pxa_ssp_write_reg(ssp, SSCR0, val);
278 if (!cpu_is_pxa3xx()) 278 if (!cpu_is_pxa3xx())
279 clk_enable(ssp->clk); 279 clk_enable(ssp->clk);
280 280
@@ -293,11 +293,11 @@ static int pxa_ssp_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
293 293
294 switch (div_id) { 294 switch (div_id) {
295 case PXA_SSP_AUDIO_DIV_ACDS: 295 case PXA_SSP_AUDIO_DIV_ACDS:
296 val = (ssp_read_reg(ssp, SSACD) & ~0x7) | SSACD_ACDS(div); 296 val = (pxa_ssp_read_reg(ssp, SSACD) & ~0x7) | SSACD_ACDS(div);
297 ssp_write_reg(ssp, SSACD, val); 297 pxa_ssp_write_reg(ssp, SSACD, val);
298 break; 298 break;
299 case PXA_SSP_AUDIO_DIV_SCDB: 299 case PXA_SSP_AUDIO_DIV_SCDB:
300 val = ssp_read_reg(ssp, SSACD); 300 val = pxa_ssp_read_reg(ssp, SSACD);
301 val &= ~SSACD_SCDB; 301 val &= ~SSACD_SCDB;
302#if defined(CONFIG_PXA3xx) 302#if defined(CONFIG_PXA3xx)
303 if (cpu_is_pxa3xx()) 303 if (cpu_is_pxa3xx())
@@ -320,10 +320,10 @@ static int pxa_ssp_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
320 default: 320 default:
321 return -EINVAL; 321 return -EINVAL;
322 } 322 }
323 ssp_write_reg(ssp, SSACD, val); 323 pxa_ssp_write_reg(ssp, SSACD, val);
324 break; 324 break;
325 case PXA_SSP_DIV_SCR: 325 case PXA_SSP_DIV_SCR:
326 ssp_set_scr(ssp, div); 326 pxa_ssp_set_scr(ssp, div);
327 break; 327 break;
328 default: 328 default:
329 return -ENODEV; 329 return -ENODEV;
@@ -340,11 +340,11 @@ static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id,
340{ 340{
341 struct ssp_priv *priv = cpu_dai->private_data; 341 struct ssp_priv *priv = cpu_dai->private_data;
342 struct ssp_device *ssp = priv->ssp; 342 struct ssp_device *ssp = priv->ssp;
343 u32 ssacd = ssp_read_reg(ssp, SSACD) & ~0x70; 343 u32 ssacd = pxa_ssp_read_reg(ssp, SSACD) & ~0x70;
344 344
345#if defined(CONFIG_PXA3xx) 345#if defined(CONFIG_PXA3xx)
346 if (cpu_is_pxa3xx()) 346 if (cpu_is_pxa3xx())
347 ssp_write_reg(ssp, SSACDD, 0); 347 pxa_ssp_write_reg(ssp, SSACDD, 0);
348#endif 348#endif
349 349
350 switch (freq_out) { 350 switch (freq_out) {
@@ -382,7 +382,7 @@ static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id,
382 val = tmp; 382 val = tmp;
383 383
384 val = (val << 16) | 64; 384 val = (val << 16) | 64;
385 ssp_write_reg(ssp, SSACDD, val); 385 pxa_ssp_write_reg(ssp, SSACDD, val);
386 386
387 ssacd |= (0x6 << 4); 387 ssacd |= (0x6 << 4);
388 388
@@ -396,7 +396,7 @@ static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id,
396 return -EINVAL; 396 return -EINVAL;
397 } 397 }
398 398
399 ssp_write_reg(ssp, SSACD, ssacd); 399 pxa_ssp_write_reg(ssp, SSACD, ssacd);
400 400
401 return 0; 401 return 0;
402} 402}
@@ -411,7 +411,7 @@ static int pxa_ssp_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai,
411 struct ssp_device *ssp = priv->ssp; 411 struct ssp_device *ssp = priv->ssp;
412 u32 sscr0; 412 u32 sscr0;
413 413
414 sscr0 = ssp_read_reg(ssp, SSCR0); 414 sscr0 = pxa_ssp_read_reg(ssp, SSCR0);
415 sscr0 &= ~(SSCR0_MOD | SSCR0_SlotsPerFrm(8) | SSCR0_EDSS | SSCR0_DSS); 415 sscr0 &= ~(SSCR0_MOD | SSCR0_SlotsPerFrm(8) | SSCR0_EDSS | SSCR0_DSS);
416 416
417 /* set slot width */ 417 /* set slot width */
@@ -428,10 +428,10 @@ static int pxa_ssp_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai,
428 sscr0 |= SSCR0_SlotsPerFrm(slots); 428 sscr0 |= SSCR0_SlotsPerFrm(slots);
429 429
430 /* set active slot mask */ 430 /* set active slot mask */
431 ssp_write_reg(ssp, SSTSA, tx_mask); 431 pxa_ssp_write_reg(ssp, SSTSA, tx_mask);
432 ssp_write_reg(ssp, SSRSA, rx_mask); 432 pxa_ssp_write_reg(ssp, SSRSA, rx_mask);
433 } 433 }
434 ssp_write_reg(ssp, SSCR0, sscr0); 434 pxa_ssp_write_reg(ssp, SSCR0, sscr0);
435 435
436 return 0; 436 return 0;
437} 437}
@@ -446,12 +446,12 @@ static int pxa_ssp_set_dai_tristate(struct snd_soc_dai *cpu_dai,
446 struct ssp_device *ssp = priv->ssp; 446 struct ssp_device *ssp = priv->ssp;
447 u32 sscr1; 447 u32 sscr1;
448 448
449 sscr1 = ssp_read_reg(ssp, SSCR1); 449 sscr1 = pxa_ssp_read_reg(ssp, SSCR1);
450 if (tristate) 450 if (tristate)
451 sscr1 &= ~SSCR1_TTE; 451 sscr1 &= ~SSCR1_TTE;
452 else 452 else
453 sscr1 |= SSCR1_TTE; 453 sscr1 |= SSCR1_TTE;
454 ssp_write_reg(ssp, SSCR1, sscr1); 454 pxa_ssp_write_reg(ssp, SSCR1, sscr1);
455 455
456 return 0; 456 return 0;
457} 457}
@@ -475,14 +475,14 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
475 return 0; 475 return 0;
476 476
477 /* we can only change the settings if the port is not in use */ 477 /* we can only change the settings if the port is not in use */
478 if (ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) { 478 if (pxa_ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) {
479 dev_err(&ssp->pdev->dev, 479 dev_err(&ssp->pdev->dev,
480 "can't change hardware dai format: stream is in use"); 480 "can't change hardware dai format: stream is in use");
481 return -EINVAL; 481 return -EINVAL;
482 } 482 }
483 483
484 /* reset port settings */ 484 /* reset port settings */
485 sscr0 = ssp_read_reg(ssp, SSCR0) & 485 sscr0 = pxa_ssp_read_reg(ssp, SSCR0) &
486 (SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ACS); 486 (SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ACS);
487 sscr1 = SSCR1_RxTresh(8) | SSCR1_TxTresh(7); 487 sscr1 = SSCR1_RxTresh(8) | SSCR1_TxTresh(7);
488 sspsp = 0; 488 sspsp = 0;
@@ -534,9 +534,9 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
534 return -EINVAL; 534 return -EINVAL;
535 } 535 }
536 536
537 ssp_write_reg(ssp, SSCR0, sscr0); 537 pxa_ssp_write_reg(ssp, SSCR0, sscr0);
538 ssp_write_reg(ssp, SSCR1, sscr1); 538 pxa_ssp_write_reg(ssp, SSCR1, sscr1);
539 ssp_write_reg(ssp, SSPSP, sspsp); 539 pxa_ssp_write_reg(ssp, SSPSP, sspsp);
540 540
541 dump_registers(ssp); 541 dump_registers(ssp);
542 542
@@ -565,7 +565,7 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
565 u32 sscr0; 565 u32 sscr0;
566 u32 sspsp; 566 u32 sspsp;
567 int width = snd_pcm_format_physical_width(params_format(params)); 567 int width = snd_pcm_format_physical_width(params_format(params));
568 int ttsa = ssp_read_reg(ssp, SSTSA) & 0xf; 568 int ttsa = pxa_ssp_read_reg(ssp, SSTSA) & 0xf;
569 struct pxa2xx_pcm_dma_params *dma_data; 569 struct pxa2xx_pcm_dma_params *dma_data;
570 570
571 dma_data = snd_soc_dai_get_dma_data(dai, substream); 571 dma_data = snd_soc_dai_get_dma_data(dai, substream);
@@ -577,22 +577,22 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
577 * to force 16-bit frame width on the wire (for S16_LE), even 577 * to force 16-bit frame width on the wire (for S16_LE), even
578 * with two channels. Use 16-bit DMA transfers for this case. 578 * with two channels. Use 16-bit DMA transfers for this case.
579 */ 579 */
580 dma_data = ssp_get_dma_params(ssp, 580 dma_data = pxa_ssp_get_dma_params(ssp,
581 ((chn == 2) && (ttsa != 1)) || (width == 32), 581 ((chn == 2) && (ttsa != 1)) || (width == 32),
582 substream->stream == SNDRV_PCM_STREAM_PLAYBACK); 582 substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
583 583
584 snd_soc_dai_set_dma_data(dai, substream, dma_data); 584 snd_soc_dai_set_dma_data(dai, substream, dma_data);
585 585
586 /* we can only change the settings if the port is not in use */ 586 /* we can only change the settings if the port is not in use */
587 if (ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) 587 if (pxa_ssp_read_reg(ssp, SSCR0) & SSCR0_SSE)
588 return 0; 588 return 0;
589 589
590 /* clear selected SSP bits */ 590 /* clear selected SSP bits */
591 sscr0 = ssp_read_reg(ssp, SSCR0) & ~(SSCR0_DSS | SSCR0_EDSS); 591 sscr0 = pxa_ssp_read_reg(ssp, SSCR0) & ~(SSCR0_DSS | SSCR0_EDSS);
592 ssp_write_reg(ssp, SSCR0, sscr0); 592 pxa_ssp_write_reg(ssp, SSCR0, sscr0);
593 593
594 /* bit size */ 594 /* bit size */
595 sscr0 = ssp_read_reg(ssp, SSCR0); 595 sscr0 = pxa_ssp_read_reg(ssp, SSCR0);
596 switch (params_format(params)) { 596 switch (params_format(params)) {
597 case SNDRV_PCM_FORMAT_S16_LE: 597 case SNDRV_PCM_FORMAT_S16_LE:
598#ifdef CONFIG_PXA3xx 598#ifdef CONFIG_PXA3xx
@@ -608,13 +608,13 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
608 sscr0 |= (SSCR0_EDSS | SSCR0_DataSize(16)); 608 sscr0 |= (SSCR0_EDSS | SSCR0_DataSize(16));
609 break; 609 break;
610 } 610 }
611 ssp_write_reg(ssp, SSCR0, sscr0); 611 pxa_ssp_write_reg(ssp, SSCR0, sscr0);
612 612
613 switch (priv->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 613 switch (priv->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
614 case SND_SOC_DAIFMT_I2S: 614 case SND_SOC_DAIFMT_I2S:
615 sspsp = ssp_read_reg(ssp, SSPSP); 615 sspsp = pxa_ssp_read_reg(ssp, SSPSP);
616 616
617 if ((ssp_get_scr(ssp) == 4) && (width == 16)) { 617 if ((pxa_ssp_get_scr(ssp) == 4) && (width == 16)) {
618 /* This is a special case where the bitclk is 64fs 618 /* This is a special case where the bitclk is 64fs
619 * and we're not dealing with 2*32 bits of audio 619 * and we're not dealing with 2*32 bits of audio
620 * samples. 620 * samples.
@@ -648,7 +648,7 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
648 sspsp |= SSPSP_DMYSTRT(1); 648 sspsp |= SSPSP_DMYSTRT(1);
649 } 649 }
650 650
651 ssp_write_reg(ssp, SSPSP, sspsp); 651 pxa_ssp_write_reg(ssp, SSPSP, sspsp);
652 break; 652 break;
653 default: 653 default:
654 break; 654 break;
@@ -679,45 +679,45 @@ static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd,
679 679
680 switch (cmd) { 680 switch (cmd) {
681 case SNDRV_PCM_TRIGGER_RESUME: 681 case SNDRV_PCM_TRIGGER_RESUME:
682 ssp_enable(ssp); 682 pxa_ssp_enable(ssp);
683 break; 683 break;
684 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 684 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
685 val = ssp_read_reg(ssp, SSCR1); 685 val = pxa_ssp_read_reg(ssp, SSCR1);
686 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 686 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
687 val |= SSCR1_TSRE; 687 val |= SSCR1_TSRE;
688 else 688 else
689 val |= SSCR1_RSRE; 689 val |= SSCR1_RSRE;
690 ssp_write_reg(ssp, SSCR1, val); 690 pxa_ssp_write_reg(ssp, SSCR1, val);
691 val = ssp_read_reg(ssp, SSSR); 691 val = pxa_ssp_read_reg(ssp, SSSR);
692 ssp_write_reg(ssp, SSSR, val); 692 pxa_ssp_write_reg(ssp, SSSR, val);
693 break; 693 break;
694 case SNDRV_PCM_TRIGGER_START: 694 case SNDRV_PCM_TRIGGER_START:
695 val = ssp_read_reg(ssp, SSCR1); 695 val = pxa_ssp_read_reg(ssp, SSCR1);
696 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 696 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
697 val |= SSCR1_TSRE; 697 val |= SSCR1_TSRE;
698 else 698 else
699 val |= SSCR1_RSRE; 699 val |= SSCR1_RSRE;
700 ssp_write_reg(ssp, SSCR1, val); 700 pxa_ssp_write_reg(ssp, SSCR1, val);
701 ssp_enable(ssp); 701 pxa_ssp_enable(ssp);
702 break; 702 break;
703 case SNDRV_PCM_TRIGGER_STOP: 703 case SNDRV_PCM_TRIGGER_STOP:
704 val = ssp_read_reg(ssp, SSCR1); 704 val = pxa_ssp_read_reg(ssp, SSCR1);
705 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 705 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
706 val &= ~SSCR1_TSRE; 706 val &= ~SSCR1_TSRE;
707 else 707 else
708 val &= ~SSCR1_RSRE; 708 val &= ~SSCR1_RSRE;
709 ssp_write_reg(ssp, SSCR1, val); 709 pxa_ssp_write_reg(ssp, SSCR1, val);
710 break; 710 break;
711 case SNDRV_PCM_TRIGGER_SUSPEND: 711 case SNDRV_PCM_TRIGGER_SUSPEND:
712 ssp_disable(ssp); 712 pxa_ssp_disable(ssp);
713 break; 713 break;
714 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 714 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
715 val = ssp_read_reg(ssp, SSCR1); 715 val = pxa_ssp_read_reg(ssp, SSCR1);
716 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 716 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
717 val &= ~SSCR1_TSRE; 717 val &= ~SSCR1_TSRE;
718 else 718 else
719 val &= ~SSCR1_RSRE; 719 val &= ~SSCR1_RSRE;
720 ssp_write_reg(ssp, SSCR1, val); 720 pxa_ssp_write_reg(ssp, SSCR1, val);
721 break; 721 break;
722 722
723 default: 723 default:
@@ -739,7 +739,7 @@ static int pxa_ssp_probe(struct platform_device *pdev,
739 if (!priv) 739 if (!priv)
740 return -ENOMEM; 740 return -ENOMEM;
741 741
742 priv->ssp = ssp_request(dai->id + 1, "SoC audio"); 742 priv->ssp = pxa_ssp_request(dai->id + 1, "SoC audio");
743 if (priv->ssp == NULL) { 743 if (priv->ssp == NULL) {
744 ret = -ENODEV; 744 ret = -ENODEV;
745 goto err_priv; 745 goto err_priv;
@@ -759,7 +759,7 @@ static void pxa_ssp_remove(struct platform_device *pdev,
759 struct snd_soc_dai *dai) 759 struct snd_soc_dai *dai)
760{ 760{
761 struct ssp_priv *priv = dai->private_data; 761 struct ssp_priv *priv = dai->private_data;
762 ssp_free(priv->ssp); 762 pxa_ssp_free(priv->ssp);
763} 763}
764 764
765#define PXA_SSP_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ 765#define PXA_SSP_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
diff --git a/sound/soc/s6000/s6000-i2s.c b/sound/soc/s6000/s6000-i2s.c
index fa23854c5f3a..5b9ac1759bd2 100644
--- a/sound/soc/s6000/s6000-i2s.c
+++ b/sound/soc/s6000/s6000-i2s.c
@@ -16,6 +16,7 @@
16#include <linux/clk.h> 16#include <linux/clk.h>
17#include <linux/interrupt.h> 17#include <linux/interrupt.h>
18#include <linux/io.h> 18#include <linux/io.h>
19#include <linux/slab.h>
19 20
20#include <sound/core.h> 21#include <sound/core.h>
21#include <sound/pcm.h> 22#include <sound/pcm.h>
diff --git a/sound/soc/sh/dma-sh7760.c b/sound/soc/sh/dma-sh7760.c
index baddb1242c71..0d8bdf07729c 100644
--- a/sound/soc/sh/dma-sh7760.c
+++ b/sound/soc/sh/dma-sh7760.c
@@ -13,6 +13,7 @@
13 */ 13 */
14 14
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/gfp.h>
16#include <linux/init.h> 17#include <linux/init.h>
17#include <linux/platform_device.h> 18#include <linux/platform_device.h>
18#include <linux/dma-mapping.h> 19#include <linux/dma-mapping.h>
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index f14bbb0410c1..3396a0db06ba 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -19,6 +19,7 @@
19#include <linux/list.h> 19#include <linux/list.h>
20#include <linux/pm_runtime.h> 20#include <linux/pm_runtime.h>
21#include <linux/io.h> 21#include <linux/io.h>
22#include <linux/slab.h>
22#include <sound/core.h> 23#include <sound/core.h>
23#include <sound/pcm.h> 24#include <sound/pcm.h>
24#include <sound/initval.h> 25#include <sound/initval.h>
diff --git a/sound/soc/sh/siu.h b/sound/soc/sh/siu.h
index c0bfab8fed3d..492b1cae24cc 100644
--- a/sound/soc/sh/siu.h
+++ b/sound/soc/sh/siu.h
@@ -71,8 +71,7 @@ struct siu_firmware {
71#include <linux/dmaengine.h> 71#include <linux/dmaengine.h>
72#include <linux/interrupt.h> 72#include <linux/interrupt.h>
73#include <linux/io.h> 73#include <linux/io.h>
74 74#include <linux/sh_dma.h>
75#include <asm/dmaengine.h>
76 75
77#include <sound/core.h> 76#include <sound/core.h>
78#include <sound/pcm.h> 77#include <sound/pcm.h>
diff --git a/sound/soc/sh/siu_dai.c b/sound/soc/sh/siu_dai.c
index 5452d19607e1..eeed5edd722b 100644
--- a/sound/soc/sh/siu_dai.c
+++ b/sound/soc/sh/siu_dai.c
@@ -22,6 +22,7 @@
22#include <linux/delay.h> 22#include <linux/delay.h>
23#include <linux/firmware.h> 23#include <linux/firmware.h>
24#include <linux/pm_runtime.h> 24#include <linux/pm_runtime.h>
25#include <linux/slab.h>
25 26
26#include <asm/clock.h> 27#include <asm/clock.h>
27#include <asm/siu.h> 28#include <asm/siu.h>
@@ -587,6 +588,8 @@ static int siu_dai_prepare(struct snd_pcm_substream *substream,
587 ret = siu_dai_spbstart(port_info); 588 ret = siu_dai_spbstart(port_info);
588 if (ret < 0) 589 if (ret < 0)
589 goto fail; 590 goto fail;
591 } else {
592 ret = 0;
590 } 593 }
591 594
592 port_info->play_cap |= self; 595 port_info->play_cap |= self;
diff --git a/sound/soc/sh/siu_pcm.c b/sound/soc/sh/siu_pcm.c
index ba7f8d05d977..36170be15aa7 100644
--- a/sound/soc/sh/siu_pcm.c
+++ b/sound/soc/sh/siu_pcm.c
@@ -24,7 +24,6 @@
24#include <linux/interrupt.h> 24#include <linux/interrupt.h>
25#include <linux/module.h> 25#include <linux/module.h>
26#include <linux/platform_device.h> 26#include <linux/platform_device.h>
27#include <linux/slab.h>
28 27
29#include <sound/control.h> 28#include <sound/control.h>
30#include <sound/core.h> 29#include <sound/core.h>
@@ -32,7 +31,6 @@
32#include <sound/pcm_params.h> 31#include <sound/pcm_params.h>
33#include <sound/soc-dai.h> 32#include <sound/soc-dai.h>
34 33
35#include <asm/dmaengine.h>
36#include <asm/siu.h> 34#include <asm/siu.h>
37 35
38#include "siu.h" 36#include "siu.h"
@@ -359,13 +357,13 @@ static int siu_pcm_open(struct snd_pcm_substream *ss)
359 if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK) { 357 if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK) {
360 siu_stream = &port_info->playback; 358 siu_stream = &port_info->playback;
361 param = &siu_stream->param; 359 param = &siu_stream->param;
362 param->slave_id = port ? SHDMA_SLAVE_SIUB_TX : 360 param->slave_id = port ? pdata->dma_slave_tx_b :
363 SHDMA_SLAVE_SIUA_TX; 361 pdata->dma_slave_tx_a;
364 } else { 362 } else {
365 siu_stream = &port_info->capture; 363 siu_stream = &port_info->capture;
366 param = &siu_stream->param; 364 param = &siu_stream->param;
367 param->slave_id = port ? SHDMA_SLAVE_SIUB_RX : 365 param->slave_id = port ? pdata->dma_slave_rx_b :
368 SHDMA_SLAVE_SIUA_RX; 366 pdata->dma_slave_rx_a;
369 } 367 }
370 368
371 param->dma_dev = pdata->dma_dev; 369 param->dma_dev = pdata->dma_dev;
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 6220bc1ee427..254dd1c6914d 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -28,6 +28,7 @@
28#include <linux/bitops.h> 28#include <linux/bitops.h>
29#include <linux/debugfs.h> 29#include <linux/debugfs.h>
30#include <linux/platform_device.h> 30#include <linux/platform_device.h>
31#include <linux/slab.h>
31#include <sound/ac97_codec.h> 32#include <sound/ac97_codec.h>
32#include <sound/core.h> 33#include <sound/core.h>
33#include <sound/pcm.h> 34#include <sound/pcm.h>
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index fefb6c44fc81..03cb7c05ebec 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -38,6 +38,7 @@
38#include <linux/platform_device.h> 38#include <linux/platform_device.h>
39#include <linux/jiffies.h> 39#include <linux/jiffies.h>
40#include <linux/debugfs.h> 40#include <linux/debugfs.h>
41#include <linux/slab.h>
41#include <sound/core.h> 42#include <sound/core.h>
42#include <sound/pcm.h> 43#include <sound/pcm.h>
43#include <sound/pcm_params.h> 44#include <sound/pcm_params.h>
diff --git a/sound/soc/txx9/txx9aclc-ac97.c b/sound/soc/txx9/txx9aclc-ac97.c
index 0f83bdb9b16f..0ec20b68e8cb 100644
--- a/sound/soc/txx9/txx9aclc-ac97.c
+++ b/sound/soc/txx9/txx9aclc-ac97.c
@@ -16,6 +16,7 @@
16#include <linux/delay.h> 16#include <linux/delay.h>
17#include <linux/interrupt.h> 17#include <linux/interrupt.h>
18#include <linux/io.h> 18#include <linux/io.h>
19#include <linux/gfp.h>
19#include <sound/core.h> 20#include <sound/core.h>
20#include <sound/pcm.h> 21#include <sound/pcm.h>
21#include <sound/soc.h> 22#include <sound/soc.h>
@@ -253,3 +254,4 @@ module_exit(txx9aclc_ac97_exit);
253MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>"); 254MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
254MODULE_DESCRIPTION("TXx9 ACLC AC97 driver"); 255MODULE_DESCRIPTION("TXx9 ACLC AC97 driver");
255MODULE_LICENSE("GPL"); 256MODULE_LICENSE("GPL");
257MODULE_ALIAS("platform:txx9aclc-ac97");
diff --git a/sound/soc/txx9/txx9aclc-generic.c b/sound/soc/txx9/txx9aclc-generic.c
index 3175de9a92cb..95b17f731aec 100644
--- a/sound/soc/txx9/txx9aclc-generic.c
+++ b/sound/soc/txx9/txx9aclc-generic.c
@@ -96,3 +96,4 @@ module_exit(txx9aclc_generic_exit);
96MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>"); 96MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
97MODULE_DESCRIPTION("Generic TXx9 ACLC ALSA SoC audio driver"); 97MODULE_DESCRIPTION("Generic TXx9 ACLC ALSA SoC audio driver");
98MODULE_LICENSE("GPL"); 98MODULE_LICENSE("GPL");
99MODULE_ALIAS("platform:txx9aclc-generic");
diff --git a/sound/soc/txx9/txx9aclc.c b/sound/soc/txx9/txx9aclc.c
index efed64b8b026..0e3452303ea6 100644
--- a/sound/soc/txx9/txx9aclc.c
+++ b/sound/soc/txx9/txx9aclc.c
@@ -15,6 +15,7 @@
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/platform_device.h> 16#include <linux/platform_device.h>
17#include <linux/scatterlist.h> 17#include <linux/scatterlist.h>
18#include <linux/slab.h>
18#include <sound/core.h> 19#include <sound/core.h>
19#include <sound/pcm.h> 20#include <sound/pcm.h>
20#include <sound/pcm_params.h> 21#include <sound/pcm_params.h>
@@ -159,7 +160,7 @@ static void txx9aclc_dma_tasklet(unsigned long data)
159 void __iomem *base = drvdata->base; 160 void __iomem *base = drvdata->base;
160 161
161 spin_unlock_irqrestore(&dmadata->dma_lock, flags); 162 spin_unlock_irqrestore(&dmadata->dma_lock, flags);
162 chan->device->device_terminate_all(chan); 163 chan->device->device_control(chan, DMA_TERMINATE_ALL, 0);
163 /* first time */ 164 /* first time */
164 for (i = 0; i < NR_DMA_CHAIN; i++) { 165 for (i = 0; i < NR_DMA_CHAIN; i++) {
165 desc = txx9aclc_dma_submit(dmadata, 166 desc = txx9aclc_dma_submit(dmadata,
@@ -267,7 +268,7 @@ static int txx9aclc_pcm_close(struct snd_pcm_substream *substream)
267 struct dma_chan *chan = dmadata->dma_chan; 268 struct dma_chan *chan = dmadata->dma_chan;
268 269
269 dmadata->frag_count = -1; 270 dmadata->frag_count = -1;
270 chan->device->device_terminate_all(chan); 271 chan->device->device_control(chan, DMA_TERMINATE_ALL, 0);
271 return 0; 272 return 0;
272} 273}
273 274
@@ -396,7 +397,8 @@ static int txx9aclc_pcm_remove(struct platform_device *pdev)
396 struct dma_chan *chan = dmadata->dma_chan; 397 struct dma_chan *chan = dmadata->dma_chan;
397 if (chan) { 398 if (chan) {
398 dmadata->frag_count = -1; 399 dmadata->frag_count = -1;
399 chan->device->device_terminate_all(chan); 400 chan->device->device_control(chan,
401 DMA_TERMINATE_ALL, 0);
400 dma_release_channel(chan); 402 dma_release_channel(chan);
401 } 403 }
402 dev->dmadata[i].dma_chan = NULL; 404 dev->dmadata[i].dma_chan = NULL;
diff --git a/sound/sound_firmware.c b/sound/sound_firmware.c
index 96deaefaa897..340a0bc5303e 100644
--- a/sound/sound_firmware.c
+++ b/sound/sound_firmware.c
@@ -2,7 +2,6 @@
2#include <linux/module.h> 2#include <linux/module.h>
3#include <linux/fs.h> 3#include <linux/fs.h>
4#include <linux/mm.h> 4#include <linux/mm.h>
5#include <linux/slab.h>
6#include <linux/sched.h> 5#include <linux/sched.h>
7#include <asm/uaccess.h> 6#include <asm/uaccess.h>
8#include "oss/sound_firmware.h" 7#include "oss/sound_firmware.h"
diff --git a/sound/sparc/amd7930.c b/sound/sparc/amd7930.c
index 574af56ba8a6..71221fd20944 100644
--- a/sound/sparc/amd7930.c
+++ b/sound/sparc/amd7930.c
@@ -1065,8 +1065,11 @@ static const struct of_device_id amd7930_match[] = {
1065}; 1065};
1066 1066
1067static struct of_platform_driver amd7930_sbus_driver = { 1067static struct of_platform_driver amd7930_sbus_driver = {
1068 .name = "audio", 1068 .driver = {
1069 .match_table = amd7930_match, 1069 .name = "audio",
1070 .owner = THIS_MODULE,
1071 .of_match_table = amd7930_match,
1072 },
1070 .probe = amd7930_sbus_probe, 1073 .probe = amd7930_sbus_probe,
1071}; 1074};
1072 1075
diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c
index 8d13d933087d..fb4c6f2f29e5 100644
--- a/sound/sparc/cs4231.c
+++ b/sound/sparc/cs4231.c
@@ -10,7 +10,6 @@
10 10
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/kernel.h> 12#include <linux/kernel.h>
13#include <linux/slab.h>
14#include <linux/delay.h> 13#include <linux/delay.h>
15#include <linux/init.h> 14#include <linux/init.h>
16#include <linux/interrupt.h> 15#include <linux/interrupt.h>
@@ -2076,12 +2075,12 @@ static int __devinit cs4231_ebus_probe(struct of_device *op, const struct of_dev
2076static int __devinit cs4231_probe(struct of_device *op, const struct of_device_id *match) 2075static int __devinit cs4231_probe(struct of_device *op, const struct of_device_id *match)
2077{ 2076{
2078#ifdef EBUS_SUPPORT 2077#ifdef EBUS_SUPPORT
2079 if (!strcmp(op->node->parent->name, "ebus")) 2078 if (!strcmp(op->dev.of_node->parent->name, "ebus"))
2080 return cs4231_ebus_probe(op, match); 2079 return cs4231_ebus_probe(op, match);
2081#endif 2080#endif
2082#ifdef SBUS_SUPPORT 2081#ifdef SBUS_SUPPORT
2083 if (!strcmp(op->node->parent->name, "sbus") || 2082 if (!strcmp(op->dev.of_node->parent->name, "sbus") ||
2084 !strcmp(op->node->parent->name, "sbi")) 2083 !strcmp(op->dev.of_node->parent->name, "sbi"))
2085 return cs4231_sbus_probe(op, match); 2084 return cs4231_sbus_probe(op, match);
2086#endif 2085#endif
2087 return -ENODEV; 2086 return -ENODEV;
@@ -2110,8 +2109,11 @@ static const struct of_device_id cs4231_match[] = {
2110MODULE_DEVICE_TABLE(of, cs4231_match); 2109MODULE_DEVICE_TABLE(of, cs4231_match);
2111 2110
2112static struct of_platform_driver cs4231_driver = { 2111static struct of_platform_driver cs4231_driver = {
2113 .name = "audio", 2112 .driver = {
2114 .match_table = cs4231_match, 2113 .name = "audio",
2114 .owner = THIS_MODULE,
2115 .of_match_table = cs4231_match,
2116 },
2115 .probe = cs4231_probe, 2117 .probe = cs4231_probe,
2116 .remove = __devexit_p(cs4231_remove), 2118 .remove = __devexit_p(cs4231_remove),
2117}; 2119};
diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c
index 1d2e51b3f918..1557bf132e73 100644
--- a/sound/sparc/dbri.c
+++ b/sound/sparc/dbri.c
@@ -58,6 +58,7 @@
58#include <linux/irq.h> 58#include <linux/irq.h>
59#include <linux/io.h> 59#include <linux/io.h>
60#include <linux/dma-mapping.h> 60#include <linux/dma-mapping.h>
61#include <linux/gfp.h>
61 62
62#include <sound/core.h> 63#include <sound/core.h>
63#include <sound/pcm.h> 64#include <sound/pcm.h>
@@ -2650,7 +2651,7 @@ static int __devinit dbri_probe(struct of_device *op, const struct of_device_id
2650 2651
2651 printk(KERN_INFO "audio%d at %p (irq %d) is DBRI(%c)+CS4215(%d)\n", 2652 printk(KERN_INFO "audio%d at %p (irq %d) is DBRI(%c)+CS4215(%d)\n",
2652 dev, dbri->regs, 2653 dev, dbri->regs,
2653 dbri->irq, op->node->name[9], dbri->mm.version); 2654 dbri->irq, op->dev.of_node->name[9], dbri->mm.version);
2654 dev++; 2655 dev++;
2655 2656
2656 return 0; 2657 return 0;
@@ -2686,8 +2687,11 @@ static const struct of_device_id dbri_match[] = {
2686MODULE_DEVICE_TABLE(of, dbri_match); 2687MODULE_DEVICE_TABLE(of, dbri_match);
2687 2688
2688static struct of_platform_driver dbri_sbus_driver = { 2689static struct of_platform_driver dbri_sbus_driver = {
2689 .name = "dbri", 2690 .driver = {
2690 .match_table = dbri_match, 2691 .name = "dbri",
2692 .owner = THIS_MODULE,
2693 .of_match_table = dbri_match,
2694 },
2691 .probe = dbri_probe, 2695 .probe = dbri_probe,
2692 .remove = __devexit_p(dbri_remove), 2696 .remove = __devexit_p(dbri_remove),
2693}; 2697};
diff --git a/sound/synth/emux/emux_proc.c b/sound/synth/emux/emux_proc.c
index 687e6a13689e..58a32a10d115 100644
--- a/sound/synth/emux/emux_proc.c
+++ b/sound/synth/emux/emux_proc.c
@@ -19,7 +19,6 @@
19 */ 19 */
20 20
21#include <linux/wait.h> 21#include <linux/wait.h>
22#include <linux/slab.h>
23#include <sound/core.h> 22#include <sound/core.h>
24#include <sound/emux_synth.h> 23#include <sound/emux_synth.h>
25#include <sound/info.h> 24#include <sound/info.h>
diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig
index c570ae3e6d55..44d6d2ec964f 100644
--- a/sound/usb/Kconfig
+++ b/sound/usb/Kconfig
@@ -22,8 +22,7 @@ config SND_USB_AUDIO
22 will be called snd-usb-audio. 22 will be called snd-usb-audio.
23 23
24config SND_USB_UA101 24config SND_USB_UA101
25 tristate "Edirol UA-101/UA-1000 driver (EXPERIMENTAL)" 25 tristate "Edirol UA-101/UA-1000 driver"
26 depends on EXPERIMENTAL
27 select SND_PCM 26 select SND_PCM
28 select SND_RAWMIDI 27 select SND_RAWMIDI
29 help 28 help
@@ -65,6 +64,7 @@ config SND_USB_CAIAQ
65 * Native Instruments Audio 8 DJ 64 * Native Instruments Audio 8 DJ
66 * Native Instruments Guitar Rig Session I/O 65 * Native Instruments Guitar Rig Session I/O
67 * Native Instruments Guitar Rig mobile 66 * Native Instruments Guitar Rig mobile
67 * Native Instruments Traktor Kontrol X1
68 68
69 To compile this driver as a module, choose M here: the module 69 To compile this driver as a module, choose M here: the module
70 will be called snd-usb-caiaq. 70 will be called snd-usb-caiaq.
diff --git a/sound/usb/Makefile b/sound/usb/Makefile
index 5bf64aef9558..e7ac7f493a8f 100644
--- a/sound/usb/Makefile
+++ b/sound/usb/Makefile
@@ -2,14 +2,24 @@
2# Makefile for ALSA 2# Makefile for ALSA
3# 3#
4 4
5snd-usb-audio-objs := usbaudio.o usbmixer.o 5snd-usb-audio-objs := card.o \
6snd-usb-lib-objs := usbmidi.o 6 mixer.o \
7snd-ua101-objs := ua101.o 7 mixer_quirks.o \
8 proc.o \
9 quirks.o \
10 format.o \
11 endpoint.o \
12 urb.o \
13 pcm.o \
14 helper.o
15
16snd-usbmidi-lib-objs := midi.o
8 17
9# Toplevel Module Dependency 18# Toplevel Module Dependency
10obj-$(CONFIG_SND_USB_AUDIO) += snd-usb-audio.o snd-usb-lib.o 19obj-$(CONFIG_SND_USB_AUDIO) += snd-usb-audio.o snd-usbmidi-lib.o
11obj-$(CONFIG_SND_USB_UA101) += snd-ua101.o snd-usb-lib.o 20
12obj-$(CONFIG_SND_USB_USX2Y) += snd-usb-lib.o 21obj-$(CONFIG_SND_USB_UA101) += snd-usbmidi-lib.o
13obj-$(CONFIG_SND_USB_US122L) += snd-usb-lib.o 22obj-$(CONFIG_SND_USB_USX2Y) += snd-usbmidi-lib.o
23obj-$(CONFIG_SND_USB_US122L) += snd-usbmidi-lib.o
14 24
15obj-$(CONFIG_SND) += usx2y/ caiaq/ 25obj-$(CONFIG_SND) += misc/ usx2y/ caiaq/
diff --git a/sound/usb/caiaq/audio.c b/sound/usb/caiaq/audio.c
index 86b2c3b92df5..4328cad6c3a2 100644
--- a/sound/usb/caiaq/audio.c
+++ b/sound/usb/caiaq/audio.c
@@ -17,6 +17,7 @@
17*/ 17*/
18 18
19#include <linux/spinlock.h> 19#include <linux/spinlock.h>
20#include <linux/slab.h>
20#include <linux/init.h> 21#include <linux/init.h>
21#include <linux/usb.h> 22#include <linux/usb.h>
22#include <sound/core.h> 23#include <sound/core.h>
diff --git a/sound/usb/caiaq/control.c b/sound/usb/caiaq/control.c
index 537102ba6b9d..91c804cd2782 100644
--- a/sound/usb/caiaq/control.c
+++ b/sound/usb/caiaq/control.c
@@ -35,33 +35,32 @@ static int control_info(struct snd_kcontrol *kcontrol,
35 struct snd_usb_caiaqdev *dev = caiaqdev(chip->card); 35 struct snd_usb_caiaqdev *dev = caiaqdev(chip->card);
36 int pos = kcontrol->private_value; 36 int pos = kcontrol->private_value;
37 int is_intval = pos & CNT_INTVAL; 37 int is_intval = pos & CNT_INTVAL;
38 unsigned int id = dev->chip.usb_id; 38 int maxval = 63;
39 39
40 uinfo->count = 1; 40 uinfo->count = 1;
41 pos &= ~CNT_INTVAL; 41 pos &= ~CNT_INTVAL;
42 42
43 if (id == USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ) 43 switch (dev->chip.usb_id) {
44 && (pos == 0)) { 44 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ):
45 /* current input mode of A8DJ */ 45 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ):
46 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 46 if (pos == 0) {
47 uinfo->value.integer.min = 0; 47 /* current input mode of A8DJ and A4DJ */
48 uinfo->value.integer.max = 2; 48 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
49 return 0; 49 uinfo->value.integer.min = 0;
50 } 50 uinfo->value.integer.max = 2;
51 return 0;
52 }
53 break;
51 54
52 if (id == USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ) 55 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
53 && (pos == 0)) { 56 maxval = 127;
54 /* current input mode of A4DJ */ 57 break;
55 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
56 uinfo->value.integer.min = 0;
57 uinfo->value.integer.max = 1;
58 return 0;
59 } 58 }
60 59
61 if (is_intval) { 60 if (is_intval) {
62 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 61 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
63 uinfo->value.integer.min = 0; 62 uinfo->value.integer.min = 0;
64 uinfo->value.integer.max = 64; 63 uinfo->value.integer.max = maxval;
65 } else { 64 } else {
66 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 65 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
67 uinfo->value.integer.min = 0; 66 uinfo->value.integer.min = 0;
@@ -78,14 +77,6 @@ static int control_get(struct snd_kcontrol *kcontrol,
78 struct snd_usb_caiaqdev *dev = caiaqdev(chip->card); 77 struct snd_usb_caiaqdev *dev = caiaqdev(chip->card);
79 int pos = kcontrol->private_value; 78 int pos = kcontrol->private_value;
80 79
81 if (dev->chip.usb_id ==
82 USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ)) {
83 /* A4DJ has only one control */
84 /* do not expose hardware input mode 0 */
85 ucontrol->value.integer.value[0] = dev->control_state[0] - 1;
86 return 0;
87 }
88
89 if (pos & CNT_INTVAL) 80 if (pos & CNT_INTVAL)
90 ucontrol->value.integer.value[0] 81 ucontrol->value.integer.value[0]
91 = dev->control_state[pos & ~CNT_INTVAL]; 82 = dev->control_state[pos & ~CNT_INTVAL];
@@ -102,21 +93,16 @@ static int control_put(struct snd_kcontrol *kcontrol,
102 struct snd_usb_audio *chip = snd_kcontrol_chip(kcontrol); 93 struct snd_usb_audio *chip = snd_kcontrol_chip(kcontrol);
103 struct snd_usb_caiaqdev *dev = caiaqdev(chip->card); 94 struct snd_usb_caiaqdev *dev = caiaqdev(chip->card);
104 int pos = kcontrol->private_value; 95 int pos = kcontrol->private_value;
96 unsigned char cmd = EP1_CMD_WRITE_IO;
105 97
106 if (dev->chip.usb_id == 98 if (dev->chip.usb_id ==
107 USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ)) { 99 USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1))
108 /* A4DJ has only one control */ 100 cmd = EP1_CMD_DIMM_LEDS;
109 /* do not expose hardware input mode 0 */
110 dev->control_state[0] = ucontrol->value.integer.value[0] + 1;
111 snd_usb_caiaq_send_command(dev, EP1_CMD_WRITE_IO,
112 dev->control_state, sizeof(dev->control_state));
113 return 1;
114 }
115 101
116 if (pos & CNT_INTVAL) { 102 if (pos & CNT_INTVAL) {
117 dev->control_state[pos & ~CNT_INTVAL] 103 dev->control_state[pos & ~CNT_INTVAL]
118 = ucontrol->value.integer.value[0]; 104 = ucontrol->value.integer.value[0];
119 snd_usb_caiaq_send_command(dev, EP1_CMD_WRITE_IO, 105 snd_usb_caiaq_send_command(dev, cmd,
120 dev->control_state, sizeof(dev->control_state)); 106 dev->control_state, sizeof(dev->control_state));
121 } else { 107 } else {
122 if (ucontrol->value.integer.value[0]) 108 if (ucontrol->value.integer.value[0])
@@ -124,7 +110,7 @@ static int control_put(struct snd_kcontrol *kcontrol,
124 else 110 else
125 dev->control_state[pos / 8] &= ~(1 << (pos % 8)); 111 dev->control_state[pos / 8] &= ~(1 << (pos % 8));
126 112
127 snd_usb_caiaq_send_command(dev, EP1_CMD_WRITE_IO, 113 snd_usb_caiaq_send_command(dev, cmd,
128 dev->control_state, sizeof(dev->control_state)); 114 dev->control_state, sizeof(dev->control_state));
129 } 115 }
130 116
@@ -273,6 +259,43 @@ static struct caiaq_controller a4dj_controller[] = {
273 { "Current input mode", 0 | CNT_INTVAL } 259 { "Current input mode", 0 | CNT_INTVAL }
274}; 260};
275 261
262static struct caiaq_controller kontrolx1_controller[] = {
263 { "LED FX A: ON", 7 | CNT_INTVAL },
264 { "LED FX A: 1", 6 | CNT_INTVAL },
265 { "LED FX A: 2", 5 | CNT_INTVAL },
266 { "LED FX A: 3", 4 | CNT_INTVAL },
267 { "LED FX B: ON", 3 | CNT_INTVAL },
268 { "LED FX B: 1", 2 | CNT_INTVAL },
269 { "LED FX B: 2", 1 | CNT_INTVAL },
270 { "LED FX B: 3", 0 | CNT_INTVAL },
271
272 { "LED Hotcue", 28 | CNT_INTVAL },
273 { "LED Shift (white)", 29 | CNT_INTVAL },
274 { "LED Shift (green)", 30 | CNT_INTVAL },
275
276 { "LED Deck A: FX1", 24 | CNT_INTVAL },
277 { "LED Deck A: FX2", 25 | CNT_INTVAL },
278 { "LED Deck A: IN", 17 | CNT_INTVAL },
279 { "LED Deck A: OUT", 16 | CNT_INTVAL },
280 { "LED Deck A: < BEAT", 19 | CNT_INTVAL },
281 { "LED Deck A: BEAT >", 18 | CNT_INTVAL },
282 { "LED Deck A: CUE/ABS", 21 | CNT_INTVAL },
283 { "LED Deck A: CUP/REL", 20 | CNT_INTVAL },
284 { "LED Deck A: PLAY", 23 | CNT_INTVAL },
285 { "LED Deck A: SYNC", 22 | CNT_INTVAL },
286
287 { "LED Deck B: FX1", 26 | CNT_INTVAL },
288 { "LED Deck B: FX2", 27 | CNT_INTVAL },
289 { "LED Deck B: IN", 15 | CNT_INTVAL },
290 { "LED Deck B: OUT", 14 | CNT_INTVAL },
291 { "LED Deck B: < BEAT", 13 | CNT_INTVAL },
292 { "LED Deck B: BEAT >", 12 | CNT_INTVAL },
293 { "LED Deck B: CUE/ABS", 11 | CNT_INTVAL },
294 { "LED Deck B: CUP/REL", 10 | CNT_INTVAL },
295 { "LED Deck B: PLAY", 9 | CNT_INTVAL },
296 { "LED Deck B: SYNC", 8 | CNT_INTVAL },
297};
298
276static int __devinit add_controls(struct caiaq_controller *c, int num, 299static int __devinit add_controls(struct caiaq_controller *c, int num,
277 struct snd_usb_caiaqdev *dev) 300 struct snd_usb_caiaqdev *dev)
278{ 301{
@@ -321,10 +344,16 @@ int __devinit snd_usb_caiaq_control_init(struct snd_usb_caiaqdev *dev)
321 ret = add_controls(a8dj_controller, 344 ret = add_controls(a8dj_controller,
322 ARRAY_SIZE(a8dj_controller), dev); 345 ARRAY_SIZE(a8dj_controller), dev);
323 break; 346 break;
347
324 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ): 348 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ):
325 ret = add_controls(a4dj_controller, 349 ret = add_controls(a4dj_controller,
326 ARRAY_SIZE(a4dj_controller), dev); 350 ARRAY_SIZE(a4dj_controller), dev);
327 break; 351 break;
352
353 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
354 ret = add_controls(kontrolx1_controller,
355 ARRAY_SIZE(kontrolx1_controller), dev);
356 break;
328 } 357 }
329 358
330 return ret; 359 return ret;
diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c
index a3f02dd97440..cdfb856bddd2 100644
--- a/sound/usb/caiaq/device.c
+++ b/sound/usb/caiaq/device.c
@@ -23,6 +23,7 @@
23#include <linux/interrupt.h> 23#include <linux/interrupt.h>
24#include <linux/module.h> 24#include <linux/module.h>
25#include <linux/init.h> 25#include <linux/init.h>
26#include <linux/gfp.h>
26#include <linux/usb.h> 27#include <linux/usb.h>
27#include <sound/initval.h> 28#include <sound/initval.h>
28#include <sound/core.h> 29#include <sound/core.h>
@@ -35,7 +36,7 @@
35#include "input.h" 36#include "input.h"
36 37
37MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>"); 38MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
38MODULE_DESCRIPTION("caiaq USB audio, version 1.3.20"); 39MODULE_DESCRIPTION("caiaq USB audio, version 1.3.21");
39MODULE_LICENSE("GPL"); 40MODULE_LICENSE("GPL");
40MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2}," 41MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2},"
41 "{Native Instruments, RigKontrol3}," 42 "{Native Instruments, RigKontrol3},"
@@ -46,7 +47,8 @@ MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2},"
46 "{Native Instruments, Audio 4 DJ}," 47 "{Native Instruments, Audio 4 DJ},"
47 "{Native Instruments, Audio 8 DJ}," 48 "{Native Instruments, Audio 8 DJ},"
48 "{Native Instruments, Session I/O}," 49 "{Native Instruments, Session I/O},"
49 "{Native Instruments, GuitarRig mobile}"); 50 "{Native Instruments, GuitarRig mobile}"
51 "{Native Instruments, Traktor Kontrol X1}");
50 52
51static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */ 53static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */
52static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */ 54static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */
@@ -127,6 +129,11 @@ static struct usb_device_id snd_usb_id_table[] = {
127 .idVendor = USB_VID_NATIVEINSTRUMENTS, 129 .idVendor = USB_VID_NATIVEINSTRUMENTS,
128 .idProduct = USB_PID_AUDIO2DJ 130 .idProduct = USB_PID_AUDIO2DJ
129 }, 131 },
132 {
133 .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
134 .idVendor = USB_VID_NATIVEINSTRUMENTS,
135 .idProduct = USB_PID_TRAKTORKONTROLX1
136 },
130 { /* terminator */ } 137 { /* terminator */ }
131}; 138};
132 139
@@ -313,12 +320,6 @@ static void __devinit setup_card(struct snd_usb_caiaqdev *dev)
313 } 320 }
314 321
315 break; 322 break;
316 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ):
317 /* Audio 4 DJ - default input mode to phono */
318 dev->control_state[0] = 2;
319 snd_usb_caiaq_send_command(dev, EP1_CMD_WRITE_IO,
320 dev->control_state, 1);
321 break;
322 } 323 }
323 324
324 if (dev->spec.num_analog_audio_out + 325 if (dev->spec.num_analog_audio_out +
diff --git a/sound/usb/caiaq/device.h b/sound/usb/caiaq/device.h
index 44e3edf88bef..f1117ecc84fd 100644
--- a/sound/usb/caiaq/device.h
+++ b/sound/usb/caiaq/device.h
@@ -5,18 +5,20 @@
5 5
6#define USB_VID_NATIVEINSTRUMENTS 0x17cc 6#define USB_VID_NATIVEINSTRUMENTS 0x17cc
7 7
8#define USB_PID_RIGKONTROL2 0x1969 8#define USB_PID_RIGKONTROL2 0x1969
9#define USB_PID_RIGKONTROL3 0x1940 9#define USB_PID_RIGKONTROL3 0x1940
10#define USB_PID_KORECONTROLLER 0x4711 10#define USB_PID_KORECONTROLLER 0x4711
11#define USB_PID_KORECONTROLLER2 0x4712 11#define USB_PID_KORECONTROLLER2 0x4712
12#define USB_PID_AK1 0x0815 12#define USB_PID_AK1 0x0815
13#define USB_PID_AUDIO2DJ 0x041c 13#define USB_PID_AUDIO2DJ 0x041c
14#define USB_PID_AUDIO4DJ 0x0839 14#define USB_PID_AUDIO4DJ 0x0839
15#define USB_PID_AUDIO8DJ 0x1978 15#define USB_PID_AUDIO8DJ 0x1978
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 19
19#define EP1_BUFSIZE 64 20#define EP1_BUFSIZE 64
21#define EP4_BUFSIZE 512
20#define CAIAQ_USB_STR_LEN 0xff 22#define CAIAQ_USB_STR_LEN 0xff
21#define MAX_STREAMS 32 23#define MAX_STREAMS 32
22 24
@@ -104,6 +106,8 @@ struct snd_usb_caiaqdev {
104 struct input_dev *input_dev; 106 struct input_dev *input_dev;
105 char phys[64]; /* physical device path */ 107 char phys[64]; /* physical device path */
106 unsigned short keycode[64]; 108 unsigned short keycode[64];
109 struct urb *ep4_in_urb;
110 unsigned char ep4_in_buf[EP4_BUFSIZE];
107#endif 111#endif
108 112
109 /* ALSA */ 113 /* ALSA */
diff --git a/sound/usb/caiaq/input.c b/sound/usb/caiaq/input.c
index a48d309bd94c..dcb620796d9e 100644
--- a/sound/usb/caiaq/input.c
+++ b/sound/usb/caiaq/input.c
@@ -16,9 +16,11 @@
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17*/ 17*/
18 18
19#include <linux/gfp.h>
19#include <linux/init.h> 20#include <linux/init.h>
20#include <linux/usb.h> 21#include <linux/usb.h>
21#include <linux/usb/input.h> 22#include <linux/usb/input.h>
23#include <sound/core.h>
22#include <sound/pcm.h> 24#include <sound/pcm.h>
23 25
24#include "device.h" 26#include "device.h"
@@ -65,6 +67,8 @@ static unsigned short keycode_kore[] = {
65 KEY_BRL_DOT5 67 KEY_BRL_DOT5
66}; 68};
67 69
70#define KONTROLX1_INPUTS 40
71
68#define DEG90 (range / 2) 72#define DEG90 (range / 2)
69#define DEG180 (range) 73#define DEG180 (range)
70#define DEG270 (DEG90 + DEG180) 74#define DEG270 (DEG90 + DEG180)
@@ -162,6 +166,17 @@ static void snd_caiaq_input_read_analog(struct snd_usb_caiaqdev *dev,
162 input_report_abs(input_dev, ABS_Z, (buf[4] << 8) | buf[5]); 166 input_report_abs(input_dev, ABS_Z, (buf[4] << 8) | buf[5]);
163 input_sync(input_dev); 167 input_sync(input_dev);
164 break; 168 break;
169 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
170 input_report_abs(input_dev, ABS_HAT0X, (buf[8] << 8) | buf[9]);
171 input_report_abs(input_dev, ABS_HAT0Y, (buf[4] << 8) | buf[5]);
172 input_report_abs(input_dev, ABS_HAT1X, (buf[12] << 8) | buf[13]);
173 input_report_abs(input_dev, ABS_HAT1Y, (buf[2] << 8) | buf[3]);
174 input_report_abs(input_dev, ABS_HAT2X, (buf[14] << 8) | buf[15]);
175 input_report_abs(input_dev, ABS_HAT2Y, (buf[0] << 8) | buf[1]);
176 input_report_abs(input_dev, ABS_HAT3X, (buf[10] << 8) | buf[11]);
177 input_report_abs(input_dev, ABS_HAT3Y, (buf[6] << 8) | buf[7]);
178 input_sync(input_dev);
179 break;
165 } 180 }
166} 181}
167 182
@@ -201,7 +216,7 @@ static void snd_caiaq_input_read_erp(struct snd_usb_caiaqdev *dev,
201} 216}
202 217
203static void snd_caiaq_input_read_io(struct snd_usb_caiaqdev *dev, 218static void snd_caiaq_input_read_io(struct snd_usb_caiaqdev *dev,
204 char *buf, unsigned int len) 219 unsigned char *buf, unsigned int len)
205{ 220{
206 struct input_dev *input_dev = dev->input_dev; 221 struct input_dev *input_dev = dev->input_dev;
207 unsigned short *keycode = input_dev->keycode; 222 unsigned short *keycode = input_dev->keycode;
@@ -218,15 +233,84 @@ static void snd_caiaq_input_read_io(struct snd_usb_caiaqdev *dev,
218 input_report_key(input_dev, keycode[i], 233 input_report_key(input_dev, keycode[i],
219 buf[i / 8] & (1 << (i % 8))); 234 buf[i / 8] & (1 << (i % 8)));
220 235
221 if (dev->chip.usb_id == 236 switch (dev->chip.usb_id) {
222 USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER) || 237 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER):
223 dev->chip.usb_id == 238 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2):
224 USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2))
225 input_report_abs(dev->input_dev, ABS_MISC, 255 - buf[4]); 239 input_report_abs(dev->input_dev, ABS_MISC, 255 - buf[4]);
240 break;
241 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
242 /* rotary encoders */
243 input_report_abs(dev->input_dev, ABS_X, buf[5] & 0xf);
244 input_report_abs(dev->input_dev, ABS_Y, buf[5] >> 4);
245 input_report_abs(dev->input_dev, ABS_Z, buf[6] & 0xf);
246 input_report_abs(dev->input_dev, ABS_MISC, buf[6] >> 4);
247 break;
248 }
226 249
227 input_sync(input_dev); 250 input_sync(input_dev);
228} 251}
229 252
253static void snd_usb_caiaq_ep4_reply_dispatch(struct urb *urb)
254{
255 struct snd_usb_caiaqdev *dev = urb->context;
256 unsigned char *buf = urb->transfer_buffer;
257 int ret;
258
259 if (urb->status || !dev || urb != dev->ep4_in_urb)
260 return;
261
262 if (urb->actual_length < 24)
263 goto requeue;
264
265 switch (dev->chip.usb_id) {
266 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
267 if (buf[0] & 0x3)
268 snd_caiaq_input_read_io(dev, buf + 1, 7);
269
270 if (buf[0] & 0x4)
271 snd_caiaq_input_read_analog(dev, buf + 8, 16);
272
273 break;
274 }
275
276requeue:
277 dev->ep4_in_urb->actual_length = 0;
278 ret = usb_submit_urb(dev->ep4_in_urb, GFP_ATOMIC);
279 if (ret < 0)
280 log("unable to submit urb. OOM!?\n");
281}
282
283static int snd_usb_caiaq_input_open(struct input_dev *idev)
284{
285 struct snd_usb_caiaqdev *dev = input_get_drvdata(idev);
286
287 if (!dev)
288 return -EINVAL;
289
290 switch (dev->chip.usb_id) {
291 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
292 if (usb_submit_urb(dev->ep4_in_urb, GFP_KERNEL) != 0)
293 return -EIO;
294 break;
295 }
296
297 return 0;
298}
299
300static void snd_usb_caiaq_input_close(struct input_dev *idev)
301{
302 struct snd_usb_caiaqdev *dev = input_get_drvdata(idev);
303
304 if (!dev)
305 return;
306
307 switch (dev->chip.usb_id) {
308 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
309 usb_kill_urb(dev->ep4_in_urb);
310 break;
311 }
312}
313
230void snd_usb_caiaq_input_dispatch(struct snd_usb_caiaqdev *dev, 314void snd_usb_caiaq_input_dispatch(struct snd_usb_caiaqdev *dev,
231 char *buf, 315 char *buf,
232 unsigned int len) 316 unsigned int len)
@@ -251,7 +335,7 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev)
251{ 335{
252 struct usb_device *usb_dev = dev->chip.dev; 336 struct usb_device *usb_dev = dev->chip.dev;
253 struct input_dev *input; 337 struct input_dev *input;
254 int i, ret; 338 int i, ret = 0;
255 339
256 input = input_allocate_device(); 340 input = input_allocate_device();
257 if (!input) 341 if (!input)
@@ -265,7 +349,9 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev)
265 usb_to_input_id(usb_dev, &input->id); 349 usb_to_input_id(usb_dev, &input->id);
266 input->dev.parent = &usb_dev->dev; 350 input->dev.parent = &usb_dev->dev;
267 351
268 switch (dev->chip.usb_id) { 352 input_set_drvdata(input, dev);
353
354 switch (dev->chip.usb_id) {
269 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2): 355 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2):
270 input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); 356 input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
271 input->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) | 357 input->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) |
@@ -326,25 +412,72 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev)
326 input_set_abs_params(input, ABS_MISC, 0, 255, 0, 1); 412 input_set_abs_params(input, ABS_MISC, 0, 255, 0, 1);
327 snd_usb_caiaq_set_auto_msg(dev, 1, 10, 5); 413 snd_usb_caiaq_set_auto_msg(dev, 1, 10, 5);
328 break; 414 break;
415 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
416 input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
417 input->absbit[0] = BIT_MASK(ABS_HAT0X) | BIT_MASK(ABS_HAT0Y) |
418 BIT_MASK(ABS_HAT1X) | BIT_MASK(ABS_HAT1Y) |
419 BIT_MASK(ABS_HAT2X) | BIT_MASK(ABS_HAT2Y) |
420 BIT_MASK(ABS_HAT3X) | BIT_MASK(ABS_HAT3Y) |
421 BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) |
422 BIT_MASK(ABS_Z);
423 input->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC);
424 BUILD_BUG_ON(sizeof(dev->keycode) < KONTROLX1_INPUTS);
425 for (i = 0; i < KONTROLX1_INPUTS; i++)
426 dev->keycode[i] = BTN_MISC + i;
427 input->keycodemax = KONTROLX1_INPUTS;
428
429 /* analog potentiometers */
430 input_set_abs_params(input, ABS_HAT0X, 0, 4096, 0, 10);
431 input_set_abs_params(input, ABS_HAT0Y, 0, 4096, 0, 10);
432 input_set_abs_params(input, ABS_HAT1X, 0, 4096, 0, 10);
433 input_set_abs_params(input, ABS_HAT1Y, 0, 4096, 0, 10);
434 input_set_abs_params(input, ABS_HAT2X, 0, 4096, 0, 10);
435 input_set_abs_params(input, ABS_HAT2Y, 0, 4096, 0, 10);
436 input_set_abs_params(input, ABS_HAT3X, 0, 4096, 0, 10);
437 input_set_abs_params(input, ABS_HAT3Y, 0, 4096, 0, 10);
438
439 /* rotary encoders */
440 input_set_abs_params(input, ABS_X, 0, 0xf, 0, 1);
441 input_set_abs_params(input, ABS_Y, 0, 0xf, 0, 1);
442 input_set_abs_params(input, ABS_Z, 0, 0xf, 0, 1);
443 input_set_abs_params(input, ABS_MISC, 0, 0xf, 0, 1);
444
445 dev->ep4_in_urb = usb_alloc_urb(0, GFP_KERNEL);
446 if (!dev->ep4_in_urb) {
447 ret = -ENOMEM;
448 goto exit_free_idev;
449 }
450
451 usb_fill_bulk_urb(dev->ep4_in_urb, usb_dev,
452 usb_rcvbulkpipe(usb_dev, 0x4),
453 dev->ep4_in_buf, EP4_BUFSIZE,
454 snd_usb_caiaq_ep4_reply_dispatch, dev);
455
456 snd_usb_caiaq_set_auto_msg(dev, 1, 10, 5);
457
458 break;
329 default: 459 default:
330 /* no input methods supported on this device */ 460 /* no input methods supported on this device */
331 input_free_device(input); 461 goto exit_free_idev;
332 return 0;
333 } 462 }
334 463
464 input->open = snd_usb_caiaq_input_open;
465 input->close = snd_usb_caiaq_input_close;
335 input->keycode = dev->keycode; 466 input->keycode = dev->keycode;
336 input->keycodesize = sizeof(unsigned short); 467 input->keycodesize = sizeof(unsigned short);
337 for (i = 0; i < input->keycodemax; i++) 468 for (i = 0; i < input->keycodemax; i++)
338 __set_bit(dev->keycode[i], input->keybit); 469 __set_bit(dev->keycode[i], input->keybit);
339 470
340 ret = input_register_device(input); 471 ret = input_register_device(input);
341 if (ret < 0) { 472 if (ret < 0)
342 input_free_device(input); 473 goto exit_free_idev;
343 return ret;
344 }
345 474
346 dev->input_dev = input; 475 dev->input_dev = input;
347 return 0; 476 return 0;
477
478exit_free_idev:
479 input_free_device(input);
480 return ret;
348} 481}
349 482
350void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *dev) 483void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *dev)
@@ -352,6 +485,10 @@ void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *dev)
352 if (!dev || !dev->input_dev) 485 if (!dev || !dev->input_dev)
353 return; 486 return;
354 487
488 usb_kill_urb(dev->ep4_in_urb);
489 usb_free_urb(dev->ep4_in_urb);
490 dev->ep4_in_urb = NULL;
491
355 input_unregister_device(dev->input_dev); 492 input_unregister_device(dev->input_dev);
356 dev->input_dev = NULL; 493 dev->input_dev = NULL;
357} 494}
diff --git a/sound/usb/caiaq/midi.c b/sound/usb/caiaq/midi.c
index 538e8c00d31a..2f218c77fff2 100644
--- a/sound/usb/caiaq/midi.c
+++ b/sound/usb/caiaq/midi.c
@@ -17,6 +17,7 @@
17*/ 17*/
18 18
19#include <linux/usb.h> 19#include <linux/usb.h>
20#include <linux/gfp.h>
20#include <sound/rawmidi.h> 21#include <sound/rawmidi.h>
21#include <sound/core.h> 22#include <sound/core.h>
22#include <sound/pcm.h> 23#include <sound/pcm.h>
diff --git a/sound/usb/card.c b/sound/usb/card.c
new file mode 100644
index 000000000000..da1346bd4856
--- /dev/null
+++ b/sound/usb/card.c
@@ -0,0 +1,652 @@
1/*
2 * (Tentative) USB Audio Driver for ALSA
3 *
4 * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
5 *
6 * Many codes borrowed from audio.c by
7 * Alan Cox (alan@lxorguk.ukuu.org.uk)
8 * Thomas Sailer (sailer@ife.ee.ethz.ch)
9 *
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25 *
26 * NOTES:
27 *
28 * - async unlink should be used for avoiding the sleep inside lock.
29 * 2.4.22 usb-uhci seems buggy for async unlinking and results in
30 * oops. in such a cse, pass async_unlink=0 option.
31 * - the linked URBs would be preferred but not used so far because of
32 * the instability of unlinking.
33 * - type II is not supported properly. there is no device which supports
34 * this type *correctly*. SB extigy looks as if it supports, but it's
35 * indeed an AC3 stream packed in SPDIF frames (i.e. no real AC3 stream).
36 */
37
38
39#include <linux/bitops.h>
40#include <linux/init.h>
41#include <linux/list.h>
42#include <linux/slab.h>
43#include <linux/string.h>
44#include <linux/usb.h>
45#include <linux/moduleparam.h>
46#include <linux/mutex.h>
47#include <linux/usb/audio.h>
48#include <linux/usb/audio-v2.h>
49
50#include <sound/core.h>
51#include <sound/info.h>
52#include <sound/pcm.h>
53#include <sound/pcm_params.h>
54#include <sound/initval.h>
55
56#include "usbaudio.h"
57#include "card.h"
58#include "midi.h"
59#include "mixer.h"
60#include "proc.h"
61#include "quirks.h"
62#include "endpoint.h"
63#include "helper.h"
64#include "debug.h"
65#include "pcm.h"
66#include "urb.h"
67#include "format.h"
68
69MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
70MODULE_DESCRIPTION("USB Audio");
71MODULE_LICENSE("GPL");
72MODULE_SUPPORTED_DEVICE("{{Generic,USB Audio}}");
73
74
75static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
76static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
77static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */
78/* Vendor/product IDs for this card */
79static int vid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 };
80static int pid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 };
81static int nrpacks = 8; /* max. number of packets per urb */
82static int async_unlink = 1;
83static int device_setup[SNDRV_CARDS]; /* device parameter for this card */
84static int ignore_ctl_error;
85
86module_param_array(index, int, NULL, 0444);
87MODULE_PARM_DESC(index, "Index value for the USB audio adapter.");
88module_param_array(id, charp, NULL, 0444);
89MODULE_PARM_DESC(id, "ID string for the USB audio adapter.");
90module_param_array(enable, bool, NULL, 0444);
91MODULE_PARM_DESC(enable, "Enable USB audio adapter.");
92module_param_array(vid, int, NULL, 0444);
93MODULE_PARM_DESC(vid, "Vendor ID for the USB audio device.");
94module_param_array(pid, int, NULL, 0444);
95MODULE_PARM_DESC(pid, "Product ID for the USB audio device.");
96module_param(nrpacks, int, 0644);
97MODULE_PARM_DESC(nrpacks, "Max. number of packets per URB.");
98module_param(async_unlink, bool, 0444);
99MODULE_PARM_DESC(async_unlink, "Use async unlink mode.");
100module_param_array(device_setup, int, NULL, 0444);
101MODULE_PARM_DESC(device_setup, "Specific device setup (if needed).");
102module_param(ignore_ctl_error, bool, 0444);
103MODULE_PARM_DESC(ignore_ctl_error,
104 "Ignore errors from USB controller for mixer interfaces.");
105
106/*
107 * we keep the snd_usb_audio_t instances by ourselves for merging
108 * the all interfaces on the same card as one sound device.
109 */
110
111static DEFINE_MUTEX(register_mutex);
112static struct snd_usb_audio *usb_chip[SNDRV_CARDS];
113static struct usb_driver usb_audio_driver;
114
115/*
116 * disconnect streams
117 * called from snd_usb_audio_disconnect()
118 */
119static void snd_usb_stream_disconnect(struct list_head *head)
120{
121 int idx;
122 struct snd_usb_stream *as;
123 struct snd_usb_substream *subs;
124
125 as = list_entry(head, struct snd_usb_stream, list);
126 for (idx = 0; idx < 2; idx++) {
127 subs = &as->substream[idx];
128 if (!subs->num_formats)
129 return;
130 snd_usb_release_substream_urbs(subs, 1);
131 subs->interface = -1;
132 }
133}
134
135static int snd_usb_create_stream(struct snd_usb_audio *chip, int ctrlif, int interface)
136{
137 struct usb_device *dev = chip->dev;
138 struct usb_host_interface *alts;
139 struct usb_interface_descriptor *altsd;
140 struct usb_interface *iface = usb_ifnum_to_if(dev, interface);
141
142 if (!iface) {
143 snd_printk(KERN_ERR "%d:%u:%d : does not exist\n",
144 dev->devnum, ctrlif, interface);
145 return -EINVAL;
146 }
147
148 if (usb_interface_claimed(iface)) {
149 snd_printdd(KERN_INFO "%d:%d:%d: skipping, already claimed\n",
150 dev->devnum, ctrlif, interface);
151 return -EINVAL;
152 }
153
154 alts = &iface->altsetting[0];
155 altsd = get_iface_desc(alts);
156 if ((altsd->bInterfaceClass == USB_CLASS_AUDIO ||
157 altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC) &&
158 altsd->bInterfaceSubClass == USB_SUBCLASS_MIDISTREAMING) {
159 int err = snd_usbmidi_create(chip->card, iface,
160 &chip->midi_list, NULL);
161 if (err < 0) {
162 snd_printk(KERN_ERR "%d:%u:%d: cannot create sequencer device\n",
163 dev->devnum, ctrlif, interface);
164 return -EINVAL;
165 }
166 usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L);
167
168 return 0;
169 }
170
171 if ((altsd->bInterfaceClass != USB_CLASS_AUDIO &&
172 altsd->bInterfaceClass != USB_CLASS_VENDOR_SPEC) ||
173 altsd->bInterfaceSubClass != USB_SUBCLASS_AUDIOSTREAMING) {
174 snd_printdd(KERN_ERR "%d:%u:%d: skipping non-supported interface %d\n",
175 dev->devnum, ctrlif, interface, altsd->bInterfaceClass);
176 /* skip non-supported classes */
177 return -EINVAL;
178 }
179
180 if (snd_usb_get_speed(dev) == USB_SPEED_LOW) {
181 snd_printk(KERN_ERR "low speed audio streaming not supported\n");
182 return -EINVAL;
183 }
184
185 if (! snd_usb_parse_audio_endpoints(chip, interface)) {
186 usb_set_interface(dev, interface, 0); /* reset the current interface */
187 usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L);
188 return -EINVAL;
189 }
190
191 return 0;
192}
193
194/*
195 * parse audio control descriptor and create pcm/midi streams
196 */
197static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
198{
199 struct usb_device *dev = chip->dev;
200 struct usb_host_interface *host_iface;
201 struct usb_interface_descriptor *altsd;
202 void *control_header;
203 int i, protocol;
204
205 /* find audiocontrol interface */
206 host_iface = &usb_ifnum_to_if(dev, ctrlif)->altsetting[0];
207 control_header = snd_usb_find_csint_desc(host_iface->extra,
208 host_iface->extralen,
209 NULL, UAC_HEADER);
210 altsd = get_iface_desc(host_iface);
211 protocol = altsd->bInterfaceProtocol;
212
213 if (!control_header) {
214 snd_printk(KERN_ERR "cannot find UAC_HEADER\n");
215 return -EINVAL;
216 }
217
218 switch (protocol) {
219 case UAC_VERSION_1: {
220 struct uac_ac_header_descriptor_v1 *h1 = control_header;
221
222 if (!h1->bInCollection) {
223 snd_printk(KERN_INFO "skipping empty audio interface (v1)\n");
224 return -EINVAL;
225 }
226
227 if (h1->bLength < sizeof(*h1) + h1->bInCollection) {
228 snd_printk(KERN_ERR "invalid UAC_HEADER (v1)\n");
229 return -EINVAL;
230 }
231
232 for (i = 0; i < h1->bInCollection; i++)
233 snd_usb_create_stream(chip, ctrlif, h1->baInterfaceNr[i]);
234
235 break;
236 }
237
238 case UAC_VERSION_2: {
239 struct uac_clock_source_descriptor *cs;
240 struct usb_interface_assoc_descriptor *assoc =
241 usb_ifnum_to_if(dev, ctrlif)->intf_assoc;
242
243 if (!assoc) {
244 snd_printk(KERN_ERR "Audio class v2 interfaces need an interface association\n");
245 return -EINVAL;
246 }
247
248 /* FIXME: for now, we expect there is at least one clock source
249 * descriptor and we always take the first one.
250 * We should properly support devices with multiple clock sources,
251 * clock selectors and sample rate conversion units. */
252
253 cs = snd_usb_find_csint_desc(host_iface->extra, host_iface->extralen,
254 NULL, UAC2_CLOCK_SOURCE);
255
256 if (!cs) {
257 snd_printk(KERN_ERR "CLOCK_SOURCE descriptor not found\n");
258 return -EINVAL;
259 }
260
261 chip->clock_id = cs->bClockID;
262
263 for (i = 0; i < assoc->bInterfaceCount; i++) {
264 int intf = assoc->bFirstInterface + i;
265
266 if (intf != ctrlif)
267 snd_usb_create_stream(chip, ctrlif, intf);
268 }
269
270 break;
271 }
272
273 default:
274 snd_printk(KERN_ERR "unknown protocol version 0x%02x\n", protocol);
275 return -EINVAL;
276 }
277
278 return 0;
279}
280
281/*
282 * free the chip instance
283 *
284 * here we have to do not much, since pcm and controls are already freed
285 *
286 */
287
288static int snd_usb_audio_free(struct snd_usb_audio *chip)
289{
290 kfree(chip);
291 return 0;
292}
293
294static int snd_usb_audio_dev_free(struct snd_device *device)
295{
296 struct snd_usb_audio *chip = device->device_data;
297 return snd_usb_audio_free(chip);
298}
299
300
301/*
302 * create a chip instance and set its names.
303 */
304static int snd_usb_audio_create(struct usb_device *dev, int idx,
305 const struct snd_usb_audio_quirk *quirk,
306 struct snd_usb_audio **rchip)
307{
308 struct snd_card *card;
309 struct snd_usb_audio *chip;
310 int err, len;
311 char component[14];
312 static struct snd_device_ops ops = {
313 .dev_free = snd_usb_audio_dev_free,
314 };
315
316 *rchip = NULL;
317
318 if (snd_usb_get_speed(dev) != USB_SPEED_LOW &&
319 snd_usb_get_speed(dev) != USB_SPEED_FULL &&
320 snd_usb_get_speed(dev) != USB_SPEED_HIGH) {
321 snd_printk(KERN_ERR "unknown device speed %d\n", snd_usb_get_speed(dev));
322 return -ENXIO;
323 }
324
325 err = snd_card_create(index[idx], id[idx], THIS_MODULE, 0, &card);
326 if (err < 0) {
327 snd_printk(KERN_ERR "cannot create card instance %d\n", idx);
328 return err;
329 }
330
331 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
332 if (! chip) {
333 snd_card_free(card);
334 return -ENOMEM;
335 }
336
337 chip->index = idx;
338 chip->dev = dev;
339 chip->card = card;
340 chip->setup = device_setup[idx];
341 chip->nrpacks = nrpacks;
342 chip->async_unlink = async_unlink;
343
344 chip->usb_id = USB_ID(le16_to_cpu(dev->descriptor.idVendor),
345 le16_to_cpu(dev->descriptor.idProduct));
346 INIT_LIST_HEAD(&chip->pcm_list);
347 INIT_LIST_HEAD(&chip->midi_list);
348 INIT_LIST_HEAD(&chip->mixer_list);
349
350 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
351 snd_usb_audio_free(chip);
352 snd_card_free(card);
353 return err;
354 }
355
356 strcpy(card->driver, "USB-Audio");
357 sprintf(component, "USB%04x:%04x",
358 USB_ID_VENDOR(chip->usb_id), USB_ID_PRODUCT(chip->usb_id));
359 snd_component_add(card, component);
360
361 /* retrieve the device string as shortname */
362 if (quirk && quirk->product_name) {
363 strlcpy(card->shortname, quirk->product_name, sizeof(card->shortname));
364 } else {
365 if (!dev->descriptor.iProduct ||
366 usb_string(dev, dev->descriptor.iProduct,
367 card->shortname, sizeof(card->shortname)) <= 0) {
368 /* no name available from anywhere, so use ID */
369 sprintf(card->shortname, "USB Device %#04x:%#04x",
370 USB_ID_VENDOR(chip->usb_id),
371 USB_ID_PRODUCT(chip->usb_id));
372 }
373 }
374
375 /* retrieve the vendor and device strings as longname */
376 if (quirk && quirk->vendor_name) {
377 len = strlcpy(card->longname, quirk->vendor_name, sizeof(card->longname));
378 } else {
379 if (dev->descriptor.iManufacturer)
380 len = usb_string(dev, dev->descriptor.iManufacturer,
381 card->longname, sizeof(card->longname));
382 else
383 len = 0;
384 /* we don't really care if there isn't any vendor string */
385 }
386 if (len > 0)
387 strlcat(card->longname, " ", sizeof(card->longname));
388
389 strlcat(card->longname, card->shortname, sizeof(card->longname));
390
391 len = strlcat(card->longname, " at ", sizeof(card->longname));
392
393 if (len < sizeof(card->longname))
394 usb_make_path(dev, card->longname + len, sizeof(card->longname) - len);
395
396 strlcat(card->longname,
397 snd_usb_get_speed(dev) == USB_SPEED_LOW ? ", low speed" :
398 snd_usb_get_speed(dev) == USB_SPEED_FULL ? ", full speed" :
399 ", high speed",
400 sizeof(card->longname));
401
402 snd_usb_audio_create_proc(chip);
403
404 *rchip = chip;
405 return 0;
406}
407
408/*
409 * probe the active usb device
410 *
411 * note that this can be called multiple times per a device, when it
412 * includes multiple audio control interfaces.
413 *
414 * thus we check the usb device pointer and creates the card instance
415 * only at the first time. the successive calls of this function will
416 * append the pcm interface to the corresponding card.
417 */
418static void *snd_usb_audio_probe(struct usb_device *dev,
419 struct usb_interface *intf,
420 const struct usb_device_id *usb_id)
421{
422 const struct snd_usb_audio_quirk *quirk = (const struct snd_usb_audio_quirk *)usb_id->driver_info;
423 int i, err;
424 struct snd_usb_audio *chip;
425 struct usb_host_interface *alts;
426 int ifnum;
427 u32 id;
428
429 alts = &intf->altsetting[0];
430 ifnum = get_iface_desc(alts)->bInterfaceNumber;
431 id = USB_ID(le16_to_cpu(dev->descriptor.idVendor),
432 le16_to_cpu(dev->descriptor.idProduct));
433 if (quirk && quirk->ifnum >= 0 && ifnum != quirk->ifnum)
434 goto __err_val;
435
436 if (snd_usb_apply_boot_quirk(dev, intf, quirk) < 0)
437 goto __err_val;
438
439 /*
440 * found a config. now register to ALSA
441 */
442
443 /* check whether it's already registered */
444 chip = NULL;
445 mutex_lock(&register_mutex);
446 for (i = 0; i < SNDRV_CARDS; i++) {
447 if (usb_chip[i] && usb_chip[i]->dev == dev) {
448 if (usb_chip[i]->shutdown) {
449 snd_printk(KERN_ERR "USB device is in the shutdown state, cannot create a card instance\n");
450 goto __error;
451 }
452 chip = usb_chip[i];
453 break;
454 }
455 }
456 if (! chip) {
457 /* it's a fresh one.
458 * now look for an empty slot and create a new card instance
459 */
460 for (i = 0; i < SNDRV_CARDS; i++)
461 if (enable[i] && ! usb_chip[i] &&
462 (vid[i] == -1 || vid[i] == USB_ID_VENDOR(id)) &&
463 (pid[i] == -1 || pid[i] == USB_ID_PRODUCT(id))) {
464 if (snd_usb_audio_create(dev, i, quirk, &chip) < 0) {
465 goto __error;
466 }
467 snd_card_set_dev(chip->card, &intf->dev);
468 break;
469 }
470 if (!chip) {
471 printk(KERN_ERR "no available usb audio device\n");
472 goto __error;
473 }
474 }
475
476 chip->txfr_quirk = 0;
477 err = 1; /* continue */
478 if (quirk && quirk->ifnum != QUIRK_NO_INTERFACE) {
479 /* need some special handlings */
480 if ((err = snd_usb_create_quirk(chip, intf, &usb_audio_driver, quirk)) < 0)
481 goto __error;
482 }
483
484 if (err > 0) {
485 /* create normal USB audio interfaces */
486 if (snd_usb_create_streams(chip, ifnum) < 0 ||
487 snd_usb_create_mixer(chip, ifnum, ignore_ctl_error) < 0) {
488 goto __error;
489 }
490 }
491
492 /* we are allowed to call snd_card_register() many times */
493 if (snd_card_register(chip->card) < 0) {
494 goto __error;
495 }
496
497 usb_chip[chip->index] = chip;
498 chip->num_interfaces++;
499 mutex_unlock(&register_mutex);
500 return chip;
501
502 __error:
503 if (chip && !chip->num_interfaces)
504 snd_card_free(chip->card);
505 mutex_unlock(&register_mutex);
506 __err_val:
507 return NULL;
508}
509
510/*
511 * we need to take care of counter, since disconnection can be called also
512 * many times as well as usb_audio_probe().
513 */
514static void snd_usb_audio_disconnect(struct usb_device *dev, void *ptr)
515{
516 struct snd_usb_audio *chip;
517 struct snd_card *card;
518 struct list_head *p;
519
520 if (ptr == (void *)-1L)
521 return;
522
523 chip = ptr;
524 card = chip->card;
525 mutex_lock(&register_mutex);
526 chip->shutdown = 1;
527 chip->num_interfaces--;
528 if (chip->num_interfaces <= 0) {
529 snd_card_disconnect(card);
530 /* release the pcm resources */
531 list_for_each(p, &chip->pcm_list) {
532 snd_usb_stream_disconnect(p);
533 }
534 /* release the midi resources */
535 list_for_each(p, &chip->midi_list) {
536 snd_usbmidi_disconnect(p);
537 }
538 /* release mixer resources */
539 list_for_each(p, &chip->mixer_list) {
540 snd_usb_mixer_disconnect(p);
541 }
542 usb_chip[chip->index] = NULL;
543 mutex_unlock(&register_mutex);
544 snd_card_free_when_closed(card);
545 } else {
546 mutex_unlock(&register_mutex);
547 }
548}
549
550/*
551 * new 2.5 USB kernel API
552 */
553static int usb_audio_probe(struct usb_interface *intf,
554 const struct usb_device_id *id)
555{
556 void *chip;
557 chip = snd_usb_audio_probe(interface_to_usbdev(intf), intf, id);
558 if (chip) {
559 usb_set_intfdata(intf, chip);
560 return 0;
561 } else
562 return -EIO;
563}
564
565static void usb_audio_disconnect(struct usb_interface *intf)
566{
567 snd_usb_audio_disconnect(interface_to_usbdev(intf),
568 usb_get_intfdata(intf));
569}
570
571#ifdef CONFIG_PM
572static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message)
573{
574 struct snd_usb_audio *chip = usb_get_intfdata(intf);
575 struct list_head *p;
576 struct snd_usb_stream *as;
577
578 if (chip == (void *)-1L)
579 return 0;
580
581 snd_power_change_state(chip->card, SNDRV_CTL_POWER_D3hot);
582 if (!chip->num_suspended_intf++) {
583 list_for_each(p, &chip->pcm_list) {
584 as = list_entry(p, struct snd_usb_stream, list);
585 snd_pcm_suspend_all(as->pcm);
586 }
587 }
588
589 return 0;
590}
591
592static int usb_audio_resume(struct usb_interface *intf)
593{
594 struct snd_usb_audio *chip = usb_get_intfdata(intf);
595
596 if (chip == (void *)-1L)
597 return 0;
598 if (--chip->num_suspended_intf)
599 return 0;
600 /*
601 * ALSA leaves material resumption to user space
602 * we just notify
603 */
604
605 snd_power_change_state(chip->card, SNDRV_CTL_POWER_D0);
606
607 return 0;
608}
609#else
610#define usb_audio_suspend NULL
611#define usb_audio_resume NULL
612#endif /* CONFIG_PM */
613
614static struct usb_device_id usb_audio_ids [] = {
615#include "quirks-table.h"
616 { .match_flags = (USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS),
617 .bInterfaceClass = USB_CLASS_AUDIO,
618 .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL },
619 { } /* Terminating entry */
620};
621
622MODULE_DEVICE_TABLE (usb, usb_audio_ids);
623
624/*
625 * entry point for linux usb interface
626 */
627
628static struct usb_driver usb_audio_driver = {
629 .name = "snd-usb-audio",
630 .probe = usb_audio_probe,
631 .disconnect = usb_audio_disconnect,
632 .suspend = usb_audio_suspend,
633 .resume = usb_audio_resume,
634 .id_table = usb_audio_ids,
635};
636
637static int __init snd_usb_audio_init(void)
638{
639 if (nrpacks < 1 || nrpacks > MAX_PACKS) {
640 printk(KERN_WARNING "invalid nrpacks value.\n");
641 return -EINVAL;
642 }
643 return usb_register(&usb_audio_driver);
644}
645
646static void __exit snd_usb_audio_cleanup(void)
647{
648 usb_deregister(&usb_audio_driver);
649}
650
651module_init(snd_usb_audio_init);
652module_exit(snd_usb_audio_cleanup);
diff --git a/sound/usb/card.h b/sound/usb/card.h
new file mode 100644
index 000000000000..ed92420c1095
--- /dev/null
+++ b/sound/usb/card.h
@@ -0,0 +1,105 @@
1#ifndef __USBAUDIO_CARD_H
2#define __USBAUDIO_CARD_H
3
4#define MAX_PACKS 20
5#define MAX_PACKS_HS (MAX_PACKS * 8) /* in high speed mode */
6#define MAX_URBS 8
7#define SYNC_URBS 4 /* always four urbs for sync */
8#define MAX_QUEUE 24 /* try not to exceed this queue length, in ms */
9
10struct audioformat {
11 struct list_head list;
12 u64 formats; /* ALSA format bits */
13 unsigned int channels; /* # channels */
14 unsigned int fmt_type; /* USB audio format type (1-3) */
15 unsigned int frame_size; /* samples per frame for non-audio */
16 int iface; /* interface number */
17 unsigned char altsetting; /* corresponding alternate setting */
18 unsigned char altset_idx; /* array index of altenate setting */
19 unsigned char attributes; /* corresponding attributes of cs endpoint */
20 unsigned char endpoint; /* endpoint */
21 unsigned char ep_attr; /* endpoint attributes */
22 unsigned char datainterval; /* log_2 of data packet interval */
23 unsigned int maxpacksize; /* max. packet size */
24 unsigned int rates; /* rate bitmasks */
25 unsigned int rate_min, rate_max; /* min/max rates */
26 unsigned int nr_rates; /* number of rate table entries */
27 unsigned int *rate_table; /* rate table */
28};
29
30struct snd_usb_substream;
31
32struct snd_urb_ctx {
33 struct urb *urb;
34 unsigned int buffer_size; /* size of data buffer, if data URB */
35 struct snd_usb_substream *subs;
36 int index; /* index for urb array */
37 int packets; /* number of packets per urb */
38};
39
40struct snd_urb_ops {
41 int (*prepare)(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime, struct urb *u);
42 int (*retire)(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime, struct urb *u);
43 int (*prepare_sync)(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime, struct urb *u);
44 int (*retire_sync)(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime, struct urb *u);
45};
46
47struct snd_usb_substream {
48 struct snd_usb_stream *stream;
49 struct usb_device *dev;
50 struct snd_pcm_substream *pcm_substream;
51 int direction; /* playback or capture */
52 int interface; /* current interface */
53 int endpoint; /* assigned endpoint */
54 struct audioformat *cur_audiofmt; /* current audioformat pointer (for hw_params callback) */
55 unsigned int cur_rate; /* current rate (for hw_params callback) */
56 unsigned int period_bytes; /* current period bytes (for hw_params callback) */
57 unsigned int altset_idx; /* USB data format: index of alternate setting */
58 unsigned int datapipe; /* the data i/o pipe */
59 unsigned int syncpipe; /* 1 - async out or adaptive in */
60 unsigned int datainterval; /* log_2 of data packet interval */
61 unsigned int syncinterval; /* P for adaptive mode, 0 otherwise */
62 unsigned int freqn; /* nominal sampling rate in fs/fps in Q16.16 format */
63 unsigned int freqm; /* momentary sampling rate in fs/fps in Q16.16 format */
64 unsigned int freqmax; /* maximum sampling rate, used for buffer management */
65 unsigned int phase; /* phase accumulator */
66 unsigned int maxpacksize; /* max packet size in bytes */
67 unsigned int maxframesize; /* max packet size in frames */
68 unsigned int curpacksize; /* current packet size in bytes (for capture) */
69 unsigned int curframesize; /* current packet size in frames (for capture) */
70 unsigned int fill_max: 1; /* fill max packet size always */
71 unsigned int txfr_quirk:1; /* allow sub-frame alignment */
72 unsigned int fmt_type; /* USB audio format type (1-3) */
73
74 unsigned int running: 1; /* running status */
75
76 unsigned int hwptr_done; /* processed byte position in the buffer */
77 unsigned int transfer_done; /* processed frames since last period update */
78 unsigned long active_mask; /* bitmask of active urbs */
79 unsigned long unlink_mask; /* bitmask of unlinked urbs */
80
81 unsigned int nurbs; /* # urbs */
82 struct snd_urb_ctx dataurb[MAX_URBS]; /* data urb table */
83 struct snd_urb_ctx syncurb[SYNC_URBS]; /* sync urb table */
84 char *syncbuf; /* sync buffer for all sync URBs */
85 dma_addr_t sync_dma; /* DMA address of syncbuf */
86
87 u64 formats; /* format bitmasks (all or'ed) */
88 unsigned int num_formats; /* number of supported audio formats (list) */
89 struct list_head fmt_list; /* format list */
90 struct snd_pcm_hw_constraint_list rate_list; /* limited rates */
91 spinlock_t lock;
92
93 struct snd_urb_ops ops; /* callbacks (must be filled at init) */
94};
95
96struct snd_usb_stream {
97 struct snd_usb_audio *chip;
98 struct snd_pcm *pcm;
99 int pcm_index;
100 unsigned int fmt_type; /* USB audio format type (1-3) */
101 struct snd_usb_substream substream[2];
102 struct list_head list;
103};
104
105#endif /* __USBAUDIO_CARD_H */
diff --git a/sound/usb/debug.h b/sound/usb/debug.h
new file mode 100644
index 000000000000..343ec2d9ee66
--- /dev/null
+++ b/sound/usb/debug.h
@@ -0,0 +1,15 @@
1#ifndef __USBAUDIO_DEBUG_H
2#define __USBAUDIO_DEBUG_H
3
4/*
5 * h/w constraints
6 */
7
8#ifdef HW_CONST_DEBUG
9#define hwc_debug(fmt, args...) printk(KERN_DEBUG fmt, ##args)
10#else
11#define hwc_debug(fmt, args...) /**/
12#endif
13
14#endif /* __USBAUDIO_DEBUG_H */
15
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
new file mode 100644
index 000000000000..28ee1ce3971a
--- /dev/null
+++ b/sound/usb/endpoint.c
@@ -0,0 +1,394 @@
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 as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15 *
16 */
17
18#include <linux/init.h>
19#include <linux/slab.h>
20#include <linux/usb.h>
21#include <linux/usb/audio.h>
22#include <linux/usb/audio-v2.h>
23
24#include <sound/core.h>
25#include <sound/pcm.h>
26
27#include "usbaudio.h"
28#include "card.h"
29#include "proc.h"
30#include "quirks.h"
31#include "endpoint.h"
32#include "urb.h"
33#include "pcm.h"
34#include "helper.h"
35#include "format.h"
36
37/*
38 * free a substream
39 */
40static void free_substream(struct snd_usb_substream *subs)
41{
42 struct list_head *p, *n;
43
44 if (!subs->num_formats)
45 return; /* not initialized */
46 list_for_each_safe(p, n, &subs->fmt_list) {
47 struct audioformat *fp = list_entry(p, struct audioformat, list);
48 kfree(fp->rate_table);
49 kfree(fp);
50 }
51 kfree(subs->rate_list.list);
52}
53
54
55/*
56 * free a usb stream instance
57 */
58static void snd_usb_audio_stream_free(struct snd_usb_stream *stream)
59{
60 free_substream(&stream->substream[0]);
61 free_substream(&stream->substream[1]);
62 list_del(&stream->list);
63 kfree(stream);
64}
65
66static void snd_usb_audio_pcm_free(struct snd_pcm *pcm)
67{
68 struct snd_usb_stream *stream = pcm->private_data;
69 if (stream) {
70 stream->pcm = NULL;
71 snd_usb_audio_stream_free(stream);
72 }
73}
74
75
76/*
77 * add this endpoint to the chip instance.
78 * if a stream with the same endpoint already exists, append to it.
79 * if not, create a new pcm stream.
80 */
81int snd_usb_add_audio_endpoint(struct snd_usb_audio *chip, int stream, struct audioformat *fp)
82{
83 struct list_head *p;
84 struct snd_usb_stream *as;
85 struct snd_usb_substream *subs;
86 struct snd_pcm *pcm;
87 int err;
88
89 list_for_each(p, &chip->pcm_list) {
90 as = list_entry(p, struct snd_usb_stream, list);
91 if (as->fmt_type != fp->fmt_type)
92 continue;
93 subs = &as->substream[stream];
94 if (!subs->endpoint)
95 continue;
96 if (subs->endpoint == fp->endpoint) {
97 list_add_tail(&fp->list, &subs->fmt_list);
98 subs->num_formats++;
99 subs->formats |= fp->formats;
100 return 0;
101 }
102 }
103 /* look for an empty stream */
104 list_for_each(p, &chip->pcm_list) {
105 as = list_entry(p, struct snd_usb_stream, list);
106 if (as->fmt_type != fp->fmt_type)
107 continue;
108 subs = &as->substream[stream];
109 if (subs->endpoint)
110 continue;
111 err = snd_pcm_new_stream(as->pcm, stream, 1);
112 if (err < 0)
113 return err;
114 snd_usb_init_substream(as, stream, fp);
115 return 0;
116 }
117
118 /* create a new pcm */
119 as = kzalloc(sizeof(*as), GFP_KERNEL);
120 if (!as)
121 return -ENOMEM;
122 as->pcm_index = chip->pcm_devs;
123 as->chip = chip;
124 as->fmt_type = fp->fmt_type;
125 err = snd_pcm_new(chip->card, "USB Audio", chip->pcm_devs,
126 stream == SNDRV_PCM_STREAM_PLAYBACK ? 1 : 0,
127 stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1,
128 &pcm);
129 if (err < 0) {
130 kfree(as);
131 return err;
132 }
133 as->pcm = pcm;
134 pcm->private_data = as;
135 pcm->private_free = snd_usb_audio_pcm_free;
136 pcm->info_flags = 0;
137 if (chip->pcm_devs > 0)
138 sprintf(pcm->name, "USB Audio #%d", chip->pcm_devs);
139 else
140 strcpy(pcm->name, "USB Audio");
141
142 snd_usb_init_substream(as, stream, fp);
143
144 list_add(&as->list, &chip->pcm_list);
145 chip->pcm_devs++;
146
147 snd_usb_proc_pcm_format_add(as);
148
149 return 0;
150}
151
152static int parse_uac_endpoint_attributes(struct snd_usb_audio *chip,
153 struct usb_host_interface *alts,
154 int protocol, int iface_no)
155{
156 /* parsed with a v1 header here. that's ok as we only look at the
157 * header first which is the same for both versions */
158 struct uac_iso_endpoint_descriptor *csep;
159 struct usb_interface_descriptor *altsd = get_iface_desc(alts);
160 int attributes = 0;
161
162 csep = snd_usb_find_desc(alts->endpoint[0].extra, alts->endpoint[0].extralen, NULL, USB_DT_CS_ENDPOINT);
163
164 /* Creamware Noah has this descriptor after the 2nd endpoint */
165 if (!csep && altsd->bNumEndpoints >= 2)
166 csep = snd_usb_find_desc(alts->endpoint[1].extra, alts->endpoint[1].extralen, NULL, USB_DT_CS_ENDPOINT);
167
168 if (!csep || csep->bLength < 7 ||
169 csep->bDescriptorSubtype != UAC_EP_GENERAL) {
170 snd_printk(KERN_WARNING "%d:%u:%d : no or invalid"
171 " class specific endpoint descriptor\n",
172 chip->dev->devnum, iface_no,
173 altsd->bAlternateSetting);
174 return 0;
175 }
176
177 if (protocol == UAC_VERSION_1) {
178 attributes = csep->bmAttributes;
179 } else {
180 struct uac2_iso_endpoint_descriptor *csep2 =
181 (struct uac2_iso_endpoint_descriptor *) csep;
182
183 attributes = csep->bmAttributes & UAC_EP_CS_ATTR_FILL_MAX;
184
185 /* emulate the endpoint attributes of a v1 device */
186 if (csep2->bmControls & UAC2_CONTROL_PITCH)
187 attributes |= UAC_EP_CS_ATTR_PITCH_CONTROL;
188 }
189
190 return attributes;
191}
192
193int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
194{
195 struct usb_device *dev;
196 struct usb_interface *iface;
197 struct usb_host_interface *alts;
198 struct usb_interface_descriptor *altsd;
199 int i, altno, err, stream;
200 int format = 0, num_channels = 0;
201 struct audioformat *fp = NULL;
202 int num, protocol;
203 struct uac_format_type_i_continuous_descriptor *fmt;
204
205 dev = chip->dev;
206
207 /* parse the interface's altsettings */
208 iface = usb_ifnum_to_if(dev, iface_no);
209
210 num = iface->num_altsetting;
211
212 /*
213 * Dallas DS4201 workaround: It presents 5 altsettings, but the last
214 * one misses syncpipe, and does not produce any sound.
215 */
216 if (chip->usb_id == USB_ID(0x04fa, 0x4201))
217 num = 4;
218
219 for (i = 0; i < num; i++) {
220 alts = &iface->altsetting[i];
221 altsd = get_iface_desc(alts);
222 protocol = altsd->bInterfaceProtocol;
223 /* skip invalid one */
224 if ((altsd->bInterfaceClass != USB_CLASS_AUDIO &&
225 altsd->bInterfaceClass != USB_CLASS_VENDOR_SPEC) ||
226 (altsd->bInterfaceSubClass != USB_SUBCLASS_AUDIOSTREAMING &&
227 altsd->bInterfaceSubClass != USB_SUBCLASS_VENDOR_SPEC) ||
228 altsd->bNumEndpoints < 1 ||
229 le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) == 0)
230 continue;
231 /* must be isochronous */
232 if ((get_endpoint(alts, 0)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) !=
233 USB_ENDPOINT_XFER_ISOC)
234 continue;
235 /* check direction */
236 stream = (get_endpoint(alts, 0)->bEndpointAddress & USB_DIR_IN) ?
237 SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
238 altno = altsd->bAlternateSetting;
239
240 if (snd_usb_apply_interface_quirk(chip, iface_no, altno))
241 continue;
242
243 /* get audio formats */
244 switch (protocol) {
245 case UAC_VERSION_1: {
246 struct uac_as_header_descriptor_v1 *as =
247 snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL);
248
249 if (!as) {
250 snd_printk(KERN_ERR "%d:%u:%d : UAC_AS_GENERAL descriptor not found\n",
251 dev->devnum, iface_no, altno);
252 continue;
253 }
254
255 if (as->bLength < sizeof(*as)) {
256 snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_AS_GENERAL desc\n",
257 dev->devnum, iface_no, altno);
258 continue;
259 }
260
261 format = le16_to_cpu(as->wFormatTag); /* remember the format value */
262 break;
263 }
264
265 case UAC_VERSION_2: {
266 struct uac_as_header_descriptor_v2 *as =
267 snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL);
268
269 if (!as) {
270 snd_printk(KERN_ERR "%d:%u:%d : UAC_AS_GENERAL descriptor not found\n",
271 dev->devnum, iface_no, altno);
272 continue;
273 }
274
275 if (as->bLength < sizeof(*as)) {
276 snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_AS_GENERAL desc\n",
277 dev->devnum, iface_no, altno);
278 continue;
279 }
280
281 num_channels = as->bNrChannels;
282 format = le32_to_cpu(as->bmFormats);
283
284 break;
285 }
286
287 default:
288 snd_printk(KERN_ERR "%d:%u:%d : unknown interface protocol %04x\n",
289 dev->devnum, iface_no, altno, protocol);
290 continue;
291 }
292
293 /* get format type */
294 fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_FORMAT_TYPE);
295 if (!fmt) {
296 snd_printk(KERN_ERR "%d:%u:%d : no UAC_FORMAT_TYPE desc\n",
297 dev->devnum, iface_no, altno);
298 continue;
299 }
300 if (((protocol == UAC_VERSION_1) && (fmt->bLength < 8)) ||
301 ((protocol == UAC_VERSION_2) && (fmt->bLength != 6))) {
302 snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n",
303 dev->devnum, iface_no, altno);
304 continue;
305 }
306
307 /*
308 * Blue Microphones workaround: The last altsetting is identical
309 * with the previous one, except for a larger packet size, but
310 * is actually a mislabeled two-channel setting; ignore it.
311 */
312 if (fmt->bNrChannels == 1 &&
313 fmt->bSubframeSize == 2 &&
314 altno == 2 && num == 3 &&
315 fp && fp->altsetting == 1 && fp->channels == 1 &&
316 fp->formats == SNDRV_PCM_FMTBIT_S16_LE &&
317 protocol == UAC_VERSION_1 &&
318 le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) ==
319 fp->maxpacksize * 2)
320 continue;
321
322 fp = kzalloc(sizeof(*fp), GFP_KERNEL);
323 if (! fp) {
324 snd_printk(KERN_ERR "cannot malloc\n");
325 return -ENOMEM;
326 }
327
328 fp->iface = iface_no;
329 fp->altsetting = altno;
330 fp->altset_idx = i;
331 fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress;
332 fp->ep_attr = get_endpoint(alts, 0)->bmAttributes;
333 fp->datainterval = snd_usb_parse_datainterval(chip, alts);
334 fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
335 /* num_channels is only set for v2 interfaces */
336 fp->channels = num_channels;
337 if (snd_usb_get_speed(dev) == USB_SPEED_HIGH)
338 fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1)
339 * (fp->maxpacksize & 0x7ff);
340 fp->attributes = parse_uac_endpoint_attributes(chip, alts, protocol, iface_no);
341
342 /* some quirks for attributes here */
343
344 switch (chip->usb_id) {
345 case USB_ID(0x0a92, 0x0053): /* AudioTrak Optoplay */
346 /* Optoplay sets the sample rate attribute although
347 * it seems not supporting it in fact.
348 */
349 fp->attributes &= ~UAC_EP_CS_ATTR_SAMPLE_RATE;
350 break;
351 case USB_ID(0x041e, 0x3020): /* Creative SB Audigy 2 NX */
352 case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
353 case USB_ID(0x0763, 0x2080): /* M-Audio Fast Track Ultra 8 */
354 case USB_ID(0x0763, 0x2081): /* M-Audio Fast Track Ultra 8R */
355 /* doesn't set the sample rate attribute, but supports it */
356 fp->attributes |= UAC_EP_CS_ATTR_SAMPLE_RATE;
357 break;
358 case USB_ID(0x047f, 0x0ca1): /* plantronics headset */
359 case USB_ID(0x077d, 0x07af): /* Griffin iMic (note that there is
360 an older model 77d:223) */
361 /*
362 * plantronics headset and Griffin iMic have set adaptive-in
363 * although it's really not...
364 */
365 fp->ep_attr &= ~USB_ENDPOINT_SYNCTYPE;
366 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
367 fp->ep_attr |= USB_ENDPOINT_SYNC_ADAPTIVE;
368 else
369 fp->ep_attr |= USB_ENDPOINT_SYNC_SYNC;
370 break;
371 }
372
373 /* ok, let's parse further... */
374 if (snd_usb_parse_audio_format(chip, fp, format, fmt, stream, alts) < 0) {
375 kfree(fp->rate_table);
376 kfree(fp);
377 continue;
378 }
379
380 snd_printdd(KERN_INFO "%d:%u:%d: add audio endpoint %#x\n", dev->devnum, iface_no, altno, fp->endpoint);
381 err = snd_usb_add_audio_endpoint(chip, stream, fp);
382 if (err < 0) {
383 kfree(fp->rate_table);
384 kfree(fp);
385 return err;
386 }
387 /* try to set the interface... */
388 usb_set_interface(chip->dev, iface_no, altno);
389 snd_usb_init_pitch(chip, iface_no, alts, fp);
390 snd_usb_init_sample_rate(chip, iface_no, alts, fp, fp->rate_max);
391 }
392 return 0;
393}
394
diff --git a/sound/usb/endpoint.h b/sound/usb/endpoint.h
new file mode 100644
index 000000000000..64dd0db023b2
--- /dev/null
+++ b/sound/usb/endpoint.h
@@ -0,0 +1,11 @@
1#ifndef __USBAUDIO_ENDPOINT_H
2#define __USBAUDIO_ENDPOINT_H
3
4int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip,
5 int iface_no);
6
7int snd_usb_add_audio_endpoint(struct snd_usb_audio *chip,
8 int stream,
9 struct audioformat *fp);
10
11#endif /* __USBAUDIO_ENDPOINT_H */
diff --git a/sound/usb/format.c b/sound/usb/format.c
new file mode 100644
index 000000000000..fe29d61de19b
--- /dev/null
+++ b/sound/usb/format.c
@@ -0,0 +1,432 @@
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 as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15 *
16 */
17
18#include <linux/init.h>
19#include <linux/slab.h>
20#include <linux/usb.h>
21#include <linux/usb/audio.h>
22#include <linux/usb/audio-v2.h>
23
24#include <sound/core.h>
25#include <sound/pcm.h>
26
27#include "usbaudio.h"
28#include "card.h"
29#include "quirks.h"
30#include "helper.h"
31#include "debug.h"
32
33/*
34 * parse the audio format type I descriptor
35 * and returns the corresponding pcm format
36 *
37 * @dev: usb device
38 * @fp: audioformat record
39 * @format: the format tag (wFormatTag)
40 * @fmt: the format type descriptor
41 */
42static u64 parse_audio_format_i_type(struct snd_usb_audio *chip,
43 struct audioformat *fp,
44 int format, void *_fmt,
45 int protocol)
46{
47 int sample_width, sample_bytes;
48 u64 pcm_formats;
49
50 switch (protocol) {
51 case UAC_VERSION_1: {
52 struct uac_format_type_i_discrete_descriptor *fmt = _fmt;
53 sample_width = fmt->bBitResolution;
54 sample_bytes = fmt->bSubframeSize;
55 format = 1 << format;
56 break;
57 }
58
59 case UAC_VERSION_2: {
60 struct uac_format_type_i_ext_descriptor *fmt = _fmt;
61 sample_width = fmt->bBitResolution;
62 sample_bytes = fmt->bSubslotSize;
63 format <<= 1;
64 break;
65 }
66
67 default:
68 return -EINVAL;
69 }
70
71 pcm_formats = 0;
72
73 if (format == 0 || format == (1 << UAC_FORMAT_TYPE_I_UNDEFINED)) {
74 /* some devices don't define this correctly... */
75 snd_printdd(KERN_INFO "%d:%u:%d : format type 0 is detected, processed as PCM\n",
76 chip->dev->devnum, fp->iface, fp->altsetting);
77 format = 1 << UAC_FORMAT_TYPE_I_PCM;
78 }
79 if (format & (1 << UAC_FORMAT_TYPE_I_PCM)) {
80 if (sample_width > sample_bytes * 8) {
81 snd_printk(KERN_INFO "%d:%u:%d : sample bitwidth %d in over sample bytes %d\n",
82 chip->dev->devnum, fp->iface, fp->altsetting,
83 sample_width, sample_bytes);
84 }
85 /* check the format byte size */
86 switch (sample_bytes) {
87 case 1:
88 pcm_formats |= SNDRV_PCM_FMTBIT_S8;
89 break;
90 case 2:
91 if (snd_usb_is_big_endian_format(chip, fp))
92 pcm_formats |= SNDRV_PCM_FMTBIT_S16_BE; /* grrr, big endian!! */
93 else
94 pcm_formats |= SNDRV_PCM_FMTBIT_S16_LE;
95 break;
96 case 3:
97 if (snd_usb_is_big_endian_format(chip, fp))
98 pcm_formats |= SNDRV_PCM_FMTBIT_S24_3BE; /* grrr, big endian!! */
99 else
100 pcm_formats |= SNDRV_PCM_FMTBIT_S24_3LE;
101 break;
102 case 4:
103 pcm_formats |= SNDRV_PCM_FMTBIT_S32_LE;
104 break;
105 default:
106 snd_printk(KERN_INFO "%d:%u:%d : unsupported sample bitwidth %d in %d bytes\n",
107 chip->dev->devnum, fp->iface, fp->altsetting,
108 sample_width, sample_bytes);
109 break;
110 }
111 }
112 if (format & (1 << UAC_FORMAT_TYPE_I_PCM8)) {
113 /* Dallas DS4201 workaround: it advertises U8 format, but really
114 supports S8. */
115 if (chip->usb_id == USB_ID(0x04fa, 0x4201))
116 pcm_formats |= SNDRV_PCM_FMTBIT_S8;
117 else
118 pcm_formats |= SNDRV_PCM_FMTBIT_U8;
119 }
120 if (format & (1 << UAC_FORMAT_TYPE_I_IEEE_FLOAT)) {
121 pcm_formats |= SNDRV_PCM_FMTBIT_FLOAT_LE;
122 }
123 if (format & (1 << UAC_FORMAT_TYPE_I_ALAW)) {
124 pcm_formats |= SNDRV_PCM_FMTBIT_A_LAW;
125 }
126 if (format & (1 << UAC_FORMAT_TYPE_I_MULAW)) {
127 pcm_formats |= SNDRV_PCM_FMTBIT_MU_LAW;
128 }
129 if (format & ~0x3f) {
130 snd_printk(KERN_INFO "%d:%u:%d : unsupported format bits %#x\n",
131 chip->dev->devnum, fp->iface, fp->altsetting, format);
132 }
133 return pcm_formats;
134}
135
136
137/*
138 * parse the format descriptor and stores the possible sample rates
139 * on the audioformat table (audio class v1).
140 *
141 * @dev: usb device
142 * @fp: audioformat record
143 * @fmt: the format descriptor
144 * @offset: the start offset of descriptor pointing the rate type
145 * (7 for type I and II, 8 for type II)
146 */
147static int parse_audio_format_rates_v1(struct snd_usb_audio *chip, struct audioformat *fp,
148 unsigned char *fmt, int offset)
149{
150 int nr_rates = fmt[offset];
151
152 if (fmt[0] < offset + 1 + 3 * (nr_rates ? nr_rates : 2)) {
153 snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n",
154 chip->dev->devnum, fp->iface, fp->altsetting);
155 return -1;
156 }
157
158 if (nr_rates) {
159 /*
160 * build the rate table and bitmap flags
161 */
162 int r, idx;
163
164 fp->rate_table = kmalloc(sizeof(int) * nr_rates, GFP_KERNEL);
165 if (fp->rate_table == NULL) {
166 snd_printk(KERN_ERR "cannot malloc\n");
167 return -1;
168 }
169
170 fp->nr_rates = 0;
171 fp->rate_min = fp->rate_max = 0;
172 for (r = 0, idx = offset + 1; r < nr_rates; r++, idx += 3) {
173 unsigned int rate = combine_triple(&fmt[idx]);
174 if (!rate)
175 continue;
176 /* C-Media CM6501 mislabels its 96 kHz altsetting */
177 if (rate == 48000 && nr_rates == 1 &&
178 (chip->usb_id == USB_ID(0x0d8c, 0x0201) ||
179 chip->usb_id == USB_ID(0x0d8c, 0x0102)) &&
180 fp->altsetting == 5 && fp->maxpacksize == 392)
181 rate = 96000;
182 /* Creative VF0470 Live Cam reports 16 kHz instead of 8kHz */
183 if (rate == 16000 && chip->usb_id == USB_ID(0x041e, 0x4068))
184 rate = 8000;
185
186 fp->rate_table[fp->nr_rates] = rate;
187 if (!fp->rate_min || rate < fp->rate_min)
188 fp->rate_min = rate;
189 if (!fp->rate_max || rate > fp->rate_max)
190 fp->rate_max = rate;
191 fp->rates |= snd_pcm_rate_to_rate_bit(rate);
192 fp->nr_rates++;
193 }
194 if (!fp->nr_rates) {
195 hwc_debug("All rates were zero. Skipping format!\n");
196 return -1;
197 }
198 } else {
199 /* continuous rates */
200 fp->rates = SNDRV_PCM_RATE_CONTINUOUS;
201 fp->rate_min = combine_triple(&fmt[offset + 1]);
202 fp->rate_max = combine_triple(&fmt[offset + 4]);
203 }
204 return 0;
205}
206
207/*
208 * parse the format descriptor and stores the possible sample rates
209 * on the audioformat table (audio class v2).
210 */
211static int parse_audio_format_rates_v2(struct snd_usb_audio *chip,
212 struct audioformat *fp,
213 struct usb_host_interface *iface)
214{
215 struct usb_device *dev = chip->dev;
216 unsigned char tmp[2], *data;
217 int i, nr_rates, data_size, ret = 0;
218
219 /* get the number of sample rates first by only fetching 2 bytes */
220 ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_RANGE,
221 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
222 UAC2_CS_CONTROL_SAM_FREQ << 8, chip->clock_id << 8,
223 tmp, sizeof(tmp), 1000);
224
225 if (ret < 0) {
226 snd_printk(KERN_ERR "unable to retrieve number of sample rates\n");
227 goto err;
228 }
229
230 nr_rates = (tmp[1] << 8) | tmp[0];
231 data_size = 2 + 12 * nr_rates;
232 data = kzalloc(data_size, GFP_KERNEL);
233 if (!data) {
234 ret = -ENOMEM;
235 goto err;
236 }
237
238 /* now get the full information */
239 ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_RANGE,
240 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
241 UAC2_CS_CONTROL_SAM_FREQ << 8, chip->clock_id << 8,
242 data, data_size, 1000);
243
244 if (ret < 0) {
245 snd_printk(KERN_ERR "unable to retrieve sample rate range\n");
246 ret = -EINVAL;
247 goto err_free;
248 }
249
250 fp->rate_table = kmalloc(sizeof(int) * nr_rates, GFP_KERNEL);
251 if (!fp->rate_table) {
252 ret = -ENOMEM;
253 goto err_free;
254 }
255
256 fp->nr_rates = 0;
257 fp->rate_min = fp->rate_max = 0;
258
259 for (i = 0; i < nr_rates; i++) {
260 int rate = combine_quad(&data[2 + 12 * i]);
261
262 fp->rate_table[fp->nr_rates] = rate;
263 if (!fp->rate_min || rate < fp->rate_min)
264 fp->rate_min = rate;
265 if (!fp->rate_max || rate > fp->rate_max)
266 fp->rate_max = rate;
267 fp->rates |= snd_pcm_rate_to_rate_bit(rate);
268 fp->nr_rates++;
269 }
270
271err_free:
272 kfree(data);
273err:
274 return ret;
275}
276
277/*
278 * parse the format type I and III descriptors
279 */
280static int parse_audio_format_i(struct snd_usb_audio *chip,
281 struct audioformat *fp, int format,
282 struct uac_format_type_i_continuous_descriptor *fmt,
283 struct usb_host_interface *iface)
284{
285 struct usb_interface_descriptor *altsd = get_iface_desc(iface);
286 int protocol = altsd->bInterfaceProtocol;
287 int pcm_format, ret;
288
289 if (fmt->bFormatType == UAC_FORMAT_TYPE_III) {
290 /* FIXME: the format type is really IECxxx
291 * but we give normal PCM format to get the existing
292 * apps working...
293 */
294 switch (chip->usb_id) {
295
296 case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
297 if (chip->setup == 0x00 &&
298 fp->altsetting == 6)
299 pcm_format = SNDRV_PCM_FORMAT_S16_BE;
300 else
301 pcm_format = SNDRV_PCM_FORMAT_S16_LE;
302 break;
303 default:
304 pcm_format = SNDRV_PCM_FORMAT_S16_LE;
305 }
306 fp->formats = 1uLL << pcm_format;
307 } else {
308 fp->formats = parse_audio_format_i_type(chip, fp, format,
309 fmt, protocol);
310 if (!fp->formats)
311 return -1;
312 }
313
314 /* gather possible sample rates */
315 /* audio class v1 reports possible sample rates as part of the
316 * proprietary class specific descriptor.
317 * audio class v2 uses class specific EP0 range requests for that.
318 */
319 switch (protocol) {
320 case UAC_VERSION_1:
321 fp->channels = fmt->bNrChannels;
322 ret = parse_audio_format_rates_v1(chip, fp, (unsigned char *) fmt, 7);
323 break;
324 case UAC_VERSION_2:
325 /* fp->channels is already set in this case */
326 ret = parse_audio_format_rates_v2(chip, fp, iface);
327 break;
328 }
329
330 if (fp->channels < 1) {
331 snd_printk(KERN_ERR "%d:%u:%d : invalid channels %d\n",
332 chip->dev->devnum, fp->iface, fp->altsetting, fp->channels);
333 return -1;
334 }
335
336 return ret;
337}
338
339/*
340 * parse the format type II descriptor
341 */
342static int parse_audio_format_ii(struct snd_usb_audio *chip,
343 struct audioformat *fp,
344 int format, void *_fmt,
345 struct usb_host_interface *iface)
346{
347 int brate, framesize, ret;
348 struct usb_interface_descriptor *altsd = get_iface_desc(iface);
349 int protocol = altsd->bInterfaceProtocol;
350
351 switch (format) {
352 case UAC_FORMAT_TYPE_II_AC3:
353 /* FIXME: there is no AC3 format defined yet */
354 // fp->formats = SNDRV_PCM_FMTBIT_AC3;
355 fp->formats = SNDRV_PCM_FMTBIT_U8; /* temporary hack to receive byte streams */
356 break;
357 case UAC_FORMAT_TYPE_II_MPEG:
358 fp->formats = SNDRV_PCM_FMTBIT_MPEG;
359 break;
360 default:
361 snd_printd(KERN_INFO "%d:%u:%d : unknown format tag %#x is detected. processed as MPEG.\n",
362 chip->dev->devnum, fp->iface, fp->altsetting, format);
363 fp->formats = SNDRV_PCM_FMTBIT_MPEG;
364 break;
365 }
366
367 fp->channels = 1;
368
369 switch (protocol) {
370 case UAC_VERSION_1: {
371 struct uac_format_type_ii_discrete_descriptor *fmt = _fmt;
372 brate = le16_to_cpu(fmt->wMaxBitRate);
373 framesize = le16_to_cpu(fmt->wSamplesPerFrame);
374 snd_printd(KERN_INFO "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize);
375 fp->frame_size = framesize;
376 ret = parse_audio_format_rates_v1(chip, fp, _fmt, 8); /* fmt[8..] sample rates */
377 break;
378 }
379 case UAC_VERSION_2: {
380 struct uac_format_type_ii_ext_descriptor *fmt = _fmt;
381 brate = le16_to_cpu(fmt->wMaxBitRate);
382 framesize = le16_to_cpu(fmt->wSamplesPerFrame);
383 snd_printd(KERN_INFO "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize);
384 fp->frame_size = framesize;
385 ret = parse_audio_format_rates_v2(chip, fp, iface);
386 break;
387 }
388 }
389
390 return ret;
391}
392
393int snd_usb_parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp,
394 int format, struct uac_format_type_i_continuous_descriptor *fmt,
395 int stream, struct usb_host_interface *iface)
396{
397 int err;
398
399 switch (fmt->bFormatType) {
400 case UAC_FORMAT_TYPE_I:
401 case UAC_FORMAT_TYPE_III:
402 err = parse_audio_format_i(chip, fp, format, fmt, iface);
403 break;
404 case UAC_FORMAT_TYPE_II:
405 err = parse_audio_format_ii(chip, fp, format, fmt, iface);
406 break;
407 default:
408 snd_printd(KERN_INFO "%d:%u:%d : format type %d is not supported yet\n",
409 chip->dev->devnum, fp->iface, fp->altsetting,
410 fmt->bFormatType);
411 return -ENOTSUPP;
412 }
413 fp->fmt_type = fmt->bFormatType;
414 if (err < 0)
415 return err;
416#if 1
417 /* FIXME: temporary hack for extigy/audigy 2 nx/zs */
418 /* extigy apparently supports sample rates other than 48k
419 * but not in ordinary way. so we enable only 48k atm.
420 */
421 if (chip->usb_id == USB_ID(0x041e, 0x3000) ||
422 chip->usb_id == USB_ID(0x041e, 0x3020) ||
423 chip->usb_id == USB_ID(0x041e, 0x3061)) {
424 if (fmt->bFormatType == UAC_FORMAT_TYPE_I &&
425 fp->rates != SNDRV_PCM_RATE_48000 &&
426 fp->rates != SNDRV_PCM_RATE_96000)
427 return -ENOTSUPP;
428 }
429#endif
430 return 0;
431}
432
diff --git a/sound/usb/format.h b/sound/usb/format.h
new file mode 100644
index 000000000000..387924f0af85
--- /dev/null
+++ b/sound/usb/format.h
@@ -0,0 +1,9 @@
1#ifndef __USBAUDIO_FORMAT_H
2#define __USBAUDIO_FORMAT_H
3
4int snd_usb_parse_audio_format(struct snd_usb_audio *chip,
5 struct audioformat *fp, int format,
6 struct uac_format_type_i_continuous_descriptor *fmt,
7 int stream, struct usb_host_interface *iface);
8
9#endif /* __USBAUDIO_FORMAT_H */
diff --git a/sound/usb/helper.c b/sound/usb/helper.c
new file mode 100644
index 000000000000..d48d6f8f6ac9
--- /dev/null
+++ b/sound/usb/helper.c
@@ -0,0 +1,113 @@
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 as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15 *
16 */
17
18#include <linux/init.h>
19#include <linux/slab.h>
20#include <linux/usb.h>
21
22#include "usbaudio.h"
23#include "helper.h"
24
25/*
26 * combine bytes and get an integer value
27 */
28unsigned int snd_usb_combine_bytes(unsigned char *bytes, int size)
29{
30 switch (size) {
31 case 1: return *bytes;
32 case 2: return combine_word(bytes);
33 case 3: return combine_triple(bytes);
34 case 4: return combine_quad(bytes);
35 default: return 0;
36 }
37}
38
39/*
40 * parse descriptor buffer and return the pointer starting the given
41 * descriptor type.
42 */
43void *snd_usb_find_desc(void *descstart, int desclen, void *after, u8 dtype)
44{
45 u8 *p, *end, *next;
46
47 p = descstart;
48 end = p + desclen;
49 for (; p < end;) {
50 if (p[0] < 2)
51 return NULL;
52 next = p + p[0];
53 if (next > end)
54 return NULL;
55 if (p[1] == dtype && (!after || (void *)p > after)) {
56 return p;
57 }
58 p = next;
59 }
60 return NULL;
61}
62
63/*
64 * find a class-specified interface descriptor with the given subtype.
65 */
66void *snd_usb_find_csint_desc(void *buffer, int buflen, void *after, u8 dsubtype)
67{
68 unsigned char *p = after;
69
70 while ((p = snd_usb_find_desc(buffer, buflen, p,
71 USB_DT_CS_INTERFACE)) != NULL) {
72 if (p[0] >= 3 && p[2] == dsubtype)
73 return p;
74 }
75 return NULL;
76}
77
78/*
79 * Wrapper for usb_control_msg().
80 * Allocates a temp buffer to prevent dmaing from/to the stack.
81 */
82int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe, __u8 request,
83 __u8 requesttype, __u16 value, __u16 index, void *data,
84 __u16 size, int timeout)
85{
86 int err;
87 void *buf = NULL;
88
89 if (size > 0) {
90 buf = kmemdup(data, size, GFP_KERNEL);
91 if (!buf)
92 return -ENOMEM;
93 }
94 err = usb_control_msg(dev, pipe, request, requesttype,
95 value, index, buf, size, timeout);
96 if (size > 0) {
97 memcpy(data, buf, size);
98 kfree(buf);
99 }
100 return err;
101}
102
103unsigned char snd_usb_parse_datainterval(struct snd_usb_audio *chip,
104 struct usb_host_interface *alts)
105{
106 if (snd_usb_get_speed(chip->dev) == USB_SPEED_HIGH &&
107 get_endpoint(alts, 0)->bInterval >= 1 &&
108 get_endpoint(alts, 0)->bInterval <= 4)
109 return get_endpoint(alts, 0)->bInterval - 1;
110 else
111 return 0;
112}
113
diff --git a/sound/usb/helper.h b/sound/usb/helper.h
new file mode 100644
index 000000000000..a6b0e51b3a9a
--- /dev/null
+++ b/sound/usb/helper.h
@@ -0,0 +1,32 @@
1#ifndef __USBAUDIO_HELPER_H
2#define __USBAUDIO_HELPER_H
3
4unsigned int snd_usb_combine_bytes(unsigned char *bytes, int size);
5
6void *snd_usb_find_desc(void *descstart, int desclen, void *after, u8 dtype);
7void *snd_usb_find_csint_desc(void *descstart, int desclen, void *after, u8 dsubtype);
8
9int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe,
10 __u8 request, __u8 requesttype, __u16 value, __u16 index,
11 void *data, __u16 size, int timeout);
12
13unsigned char snd_usb_parse_datainterval(struct snd_usb_audio *chip,
14 struct usb_host_interface *alts);
15
16/*
17 * retrieve usb_interface descriptor from the host interface
18 * (conditional for compatibility with the older API)
19 */
20#ifndef get_iface_desc
21#define get_iface_desc(iface) (&(iface)->desc)
22#define get_endpoint(alt,ep) (&(alt)->endpoint[ep].desc)
23#define get_ep_desc(ep) (&(ep)->desc)
24#define get_cfg_desc(cfg) (&(cfg)->desc)
25#endif
26
27#ifndef snd_usb_get_speed
28#define snd_usb_get_speed(dev) ((dev)->speed)
29#endif
30
31
32#endif /* __USBAUDIO_HELPER_H */
diff --git a/sound/usb/usbmidi.c b/sound/usb/midi.c
index 2c59afd99611..46785643c66d 100644
--- a/sound/usb/usbmidi.c
+++ b/sound/usb/midi.c
@@ -53,7 +53,8 @@
53#include <sound/rawmidi.h> 53#include <sound/rawmidi.h>
54#include <sound/asequencer.h> 54#include <sound/asequencer.h>
55#include "usbaudio.h" 55#include "usbaudio.h"
56 56#include "midi.h"
57#include "helper.h"
57 58
58/* 59/*
59 * define this to log all USB packets 60 * define this to log all USB packets
@@ -644,6 +645,105 @@ static struct usb_protocol_ops snd_usbmidi_cme_ops = {
644}; 645};
645 646
646/* 647/*
648 * AKAI MPD16 protocol:
649 *
650 * For control port (endpoint 1):
651 * ==============================
652 * One or more chunks consisting of first byte of (0x10 | msg_len) and then a
653 * SysEx message (msg_len=9 bytes long).
654 *
655 * For data port (endpoint 2):
656 * ===========================
657 * One or more chunks consisting of first byte of (0x20 | msg_len) and then a
658 * MIDI message (msg_len bytes long)
659 *
660 * Messages sent: Active Sense, Note On, Poly Pressure, Control Change.
661 */
662static void snd_usbmidi_akai_input(struct snd_usb_midi_in_endpoint *ep,
663 uint8_t *buffer, int buffer_length)
664{
665 unsigned int pos = 0;
666 unsigned int len = (unsigned int)buffer_length;
667 while (pos < len) {
668 unsigned int port = (buffer[pos] >> 4) - 1;
669 unsigned int msg_len = buffer[pos] & 0x0f;
670 pos++;
671 if (pos + msg_len <= len && port < 2)
672 snd_usbmidi_input_data(ep, 0, &buffer[pos], msg_len);
673 pos += msg_len;
674 }
675}
676
677#define MAX_AKAI_SYSEX_LEN 9
678
679static void snd_usbmidi_akai_output(struct snd_usb_midi_out_endpoint *ep,
680 struct urb *urb)
681{
682 uint8_t *msg;
683 int pos, end, count, buf_end;
684 uint8_t tmp[MAX_AKAI_SYSEX_LEN];
685 struct snd_rawmidi_substream *substream = ep->ports[0].substream;
686
687 if (!ep->ports[0].active)
688 return;
689
690 msg = urb->transfer_buffer + urb->transfer_buffer_length;
691 buf_end = ep->max_transfer - MAX_AKAI_SYSEX_LEN - 1;
692
693 /* only try adding more data when there's space for at least 1 SysEx */
694 while (urb->transfer_buffer_length < buf_end) {
695 count = snd_rawmidi_transmit_peek(substream,
696 tmp, MAX_AKAI_SYSEX_LEN);
697 if (!count) {
698 ep->ports[0].active = 0;
699 return;
700 }
701 /* try to skip non-SysEx data */
702 for (pos = 0; pos < count && tmp[pos] != 0xF0; pos++)
703 ;
704
705 if (pos > 0) {
706 snd_rawmidi_transmit_ack(substream, pos);
707 continue;
708 }
709
710 /* look for the start or end marker */
711 for (end = 1; end < count && tmp[end] < 0xF0; end++)
712 ;
713
714 /* next SysEx started before the end of current one */
715 if (end < count && tmp[end] == 0xF0) {
716 /* it's incomplete - drop it */
717 snd_rawmidi_transmit_ack(substream, end);
718 continue;
719 }
720 /* SysEx complete */
721 if (end < count && tmp[end] == 0xF7) {
722 /* queue it, ack it, and get the next one */
723 count = end + 1;
724 msg[0] = 0x10 | count;
725 memcpy(&msg[1], tmp, count);
726 snd_rawmidi_transmit_ack(substream, count);
727 urb->transfer_buffer_length += count + 1;
728 msg += count + 1;
729 continue;
730 }
731 /* less than 9 bytes and no end byte - wait for more */
732 if (count < MAX_AKAI_SYSEX_LEN) {
733 ep->ports[0].active = 0;
734 return;
735 }
736 /* 9 bytes and no end marker in sight - malformed, skip it */
737 snd_rawmidi_transmit_ack(substream, count);
738 }
739}
740
741static struct usb_protocol_ops snd_usbmidi_akai_ops = {
742 .input = snd_usbmidi_akai_input,
743 .output = snd_usbmidi_akai_output,
744};
745
746/*
647 * Novation USB MIDI protocol: number of data bytes is in the first byte 747 * Novation USB MIDI protocol: number of data bytes is in the first byte
648 * (when receiving) (+1!) or in the second byte (when sending); data begins 748 * (when receiving) (+1!) or in the second byte (when sending); data begins
649 * at the third byte. 749 * at the third byte.
@@ -986,6 +1086,8 @@ static void snd_usbmidi_output_drain(struct snd_rawmidi_substream *substream)
986 DEFINE_WAIT(wait); 1086 DEFINE_WAIT(wait);
987 long timeout = msecs_to_jiffies(50); 1087 long timeout = msecs_to_jiffies(50);
988 1088
1089 if (ep->umidi->disconnected)
1090 return;
989 /* 1091 /*
990 * The substream buffer is empty, but some data might still be in the 1092 * The substream buffer is empty, but some data might still be in the
991 * currently active URBs, so we have to wait for those to complete. 1093 * currently active URBs, so we have to wait for those to complete.
@@ -1045,8 +1147,8 @@ static struct snd_rawmidi_ops snd_usbmidi_input_ops = {
1045static void free_urb_and_buffer(struct snd_usb_midi *umidi, struct urb *urb, 1147static void free_urb_and_buffer(struct snd_usb_midi *umidi, struct urb *urb,
1046 unsigned int buffer_length) 1148 unsigned int buffer_length)
1047{ 1149{
1048 usb_buffer_free(umidi->dev, buffer_length, 1150 usb_free_coherent(umidi->dev, buffer_length,
1049 urb->transfer_buffer, urb->transfer_dma); 1151 urb->transfer_buffer, urb->transfer_dma);
1050 usb_free_urb(urb); 1152 usb_free_urb(urb);
1051} 1153}
1052 1154
@@ -1097,8 +1199,8 @@ static int snd_usbmidi_in_endpoint_create(struct snd_usb_midi* umidi,
1097 pipe = usb_rcvbulkpipe(umidi->dev, ep_info->in_ep); 1199 pipe = usb_rcvbulkpipe(umidi->dev, ep_info->in_ep);
1098 length = usb_maxpacket(umidi->dev, pipe, 0); 1200 length = usb_maxpacket(umidi->dev, pipe, 0);
1099 for (i = 0; i < INPUT_URBS; ++i) { 1201 for (i = 0; i < INPUT_URBS; ++i) {
1100 buffer = usb_buffer_alloc(umidi->dev, length, GFP_KERNEL, 1202 buffer = usb_alloc_coherent(umidi->dev, length, GFP_KERNEL,
1101 &ep->urbs[i]->transfer_dma); 1203 &ep->urbs[i]->transfer_dma);
1102 if (!buffer) { 1204 if (!buffer) {
1103 snd_usbmidi_in_endpoint_delete(ep); 1205 snd_usbmidi_in_endpoint_delete(ep);
1104 return -ENOMEM; 1206 return -ENOMEM;
@@ -1123,14 +1225,21 @@ static int snd_usbmidi_in_endpoint_create(struct snd_usb_midi* umidi,
1123 * Frees an output endpoint. 1225 * Frees an output endpoint.
1124 * May be called when ep hasn't been initialized completely. 1226 * May be called when ep hasn't been initialized completely.
1125 */ 1227 */
1126static void snd_usbmidi_out_endpoint_delete(struct snd_usb_midi_out_endpoint* ep) 1228static void snd_usbmidi_out_endpoint_clear(struct snd_usb_midi_out_endpoint *ep)
1127{ 1229{
1128 unsigned int i; 1230 unsigned int i;
1129 1231
1130 for (i = 0; i < OUTPUT_URBS; ++i) 1232 for (i = 0; i < OUTPUT_URBS; ++i)
1131 if (ep->urbs[i].urb) 1233 if (ep->urbs[i].urb) {
1132 free_urb_and_buffer(ep->umidi, ep->urbs[i].urb, 1234 free_urb_and_buffer(ep->umidi, ep->urbs[i].urb,
1133 ep->max_transfer); 1235 ep->max_transfer);
1236 ep->urbs[i].urb = NULL;
1237 }
1238}
1239
1240static void snd_usbmidi_out_endpoint_delete(struct snd_usb_midi_out_endpoint *ep)
1241{
1242 snd_usbmidi_out_endpoint_clear(ep);
1134 kfree(ep); 1243 kfree(ep);
1135} 1244}
1136 1245
@@ -1181,9 +1290,9 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi* umidi,
1181 break; 1290 break;
1182 } 1291 }
1183 for (i = 0; i < OUTPUT_URBS; ++i) { 1292 for (i = 0; i < OUTPUT_URBS; ++i) {
1184 buffer = usb_buffer_alloc(umidi->dev, 1293 buffer = usb_alloc_coherent(umidi->dev,
1185 ep->max_transfer, GFP_KERNEL, 1294 ep->max_transfer, GFP_KERNEL,
1186 &ep->urbs[i].urb->transfer_dma); 1295 &ep->urbs[i].urb->transfer_dma);
1187 if (!buffer) { 1296 if (!buffer) {
1188 snd_usbmidi_out_endpoint_delete(ep); 1297 snd_usbmidi_out_endpoint_delete(ep);
1189 return -ENOMEM; 1298 return -ENOMEM;
@@ -1262,15 +1371,18 @@ void snd_usbmidi_disconnect(struct list_head* p)
1262 usb_kill_urb(ep->out->urbs[j].urb); 1371 usb_kill_urb(ep->out->urbs[j].urb);
1263 if (umidi->usb_protocol_ops->finish_out_endpoint) 1372 if (umidi->usb_protocol_ops->finish_out_endpoint)
1264 umidi->usb_protocol_ops->finish_out_endpoint(ep->out); 1373 umidi->usb_protocol_ops->finish_out_endpoint(ep->out);
1374 ep->out->active_urbs = 0;
1375 if (ep->out->drain_urbs) {
1376 ep->out->drain_urbs = 0;
1377 wake_up(&ep->out->drain_wait);
1378 }
1265 } 1379 }
1266 if (ep->in) 1380 if (ep->in)
1267 for (j = 0; j < INPUT_URBS; ++j) 1381 for (j = 0; j < INPUT_URBS; ++j)
1268 usb_kill_urb(ep->in->urbs[j]); 1382 usb_kill_urb(ep->in->urbs[j]);
1269 /* free endpoints here; later call can result in Oops */ 1383 /* free endpoints here; later call can result in Oops */
1270 if (ep->out) { 1384 if (ep->out)
1271 snd_usbmidi_out_endpoint_delete(ep->out); 1385 snd_usbmidi_out_endpoint_clear(ep->out);
1272 ep->out = NULL;
1273 }
1274 if (ep->in) { 1386 if (ep->in) {
1275 snd_usbmidi_in_endpoint_delete(ep->in); 1387 snd_usbmidi_in_endpoint_delete(ep->in);
1276 ep->in = NULL; 1388 ep->in = NULL;
@@ -1421,6 +1533,11 @@ static struct port_info {
1421 EXTERNAL_PORT(0x086a, 0x0001, 8, "%s Broadcast"), 1533 EXTERNAL_PORT(0x086a, 0x0001, 8, "%s Broadcast"),
1422 EXTERNAL_PORT(0x086a, 0x0002, 8, "%s Broadcast"), 1534 EXTERNAL_PORT(0x086a, 0x0002, 8, "%s Broadcast"),
1423 EXTERNAL_PORT(0x086a, 0x0003, 4, "%s Broadcast"), 1535 EXTERNAL_PORT(0x086a, 0x0003, 4, "%s Broadcast"),
1536 /* Akai MPD16 */
1537 CONTROL_PORT(0x09e8, 0x0062, 0, "%s Control"),
1538 PORT_INFO(0x09e8, 0x0062, 1, "%s MIDI", 0,
1539 SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC |
1540 SNDRV_SEQ_PORT_TYPE_HARDWARE),
1424 /* Access Music Virus TI */ 1541 /* Access Music Virus TI */
1425 EXTERNAL_PORT(0x133e, 0x0815, 0, "%s MIDI"), 1542 EXTERNAL_PORT(0x133e, 0x0815, 0, "%s MIDI"),
1426 PORT_INFO(0x133e, 0x0815, 1, "%s Synth", 0, 1543 PORT_INFO(0x133e, 0x0815, 1, "%s Synth", 0,
@@ -2022,6 +2139,12 @@ int snd_usbmidi_create(struct snd_card *card,
2022 umidi->usb_protocol_ops = &snd_usbmidi_cme_ops; 2139 umidi->usb_protocol_ops = &snd_usbmidi_cme_ops;
2023 err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); 2140 err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
2024 break; 2141 break;
2142 case QUIRK_MIDI_AKAI:
2143 umidi->usb_protocol_ops = &snd_usbmidi_akai_ops;
2144 err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
2145 /* endpoint 1 is input-only */
2146 endpoints[1].out_cables = 0;
2147 break;
2025 default: 2148 default:
2026 snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type); 2149 snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type);
2027 err = -ENXIO; 2150 err = -ENXIO;
diff --git a/sound/usb/midi.h b/sound/usb/midi.h
new file mode 100644
index 000000000000..2fca80b744c0
--- /dev/null
+++ b/sound/usb/midi.h
@@ -0,0 +1,50 @@
1#ifndef __USBMIDI_H
2#define __USBMIDI_H
3
4/* maximum number of endpoints per interface */
5#define MIDI_MAX_ENDPOINTS 2
6
7/* data for QUIRK_MIDI_FIXED_ENDPOINT */
8struct snd_usb_midi_endpoint_info {
9 int8_t out_ep; /* ep number, 0 autodetect */
10 uint8_t out_interval; /* interval for interrupt endpoints */
11 int8_t in_ep;
12 uint8_t in_interval;
13 uint16_t out_cables; /* bitmask */
14 uint16_t in_cables; /* bitmask */
15};
16
17/* for QUIRK_MIDI_YAMAHA, data is NULL */
18
19/* for QUIRK_MIDI_MIDIMAN, data points to a snd_usb_midi_endpoint_info
20 * structure (out_cables and in_cables only) */
21
22/* for QUIRK_COMPOSITE, data points to an array of snd_usb_audio_quirk
23 * structures, terminated with .ifnum = -1 */
24
25/* for QUIRK_AUDIO_FIXED_ENDPOINT, data points to an audioformat structure */
26
27/* for QUIRK_AUDIO/MIDI_STANDARD_INTERFACE, data is NULL */
28
29/* for QUIRK_AUDIO_EDIROL_UA700_UA25/UA1000, data is NULL */
30
31/* for QUIRK_IGNORE_INTERFACE, data is NULL */
32
33/* for QUIRK_MIDI_NOVATION and _RAW, data is NULL */
34
35/* for QUIRK_MIDI_EMAGIC, data points to a snd_usb_midi_endpoint_info
36 * structure (out_cables and in_cables only) */
37
38/* for QUIRK_MIDI_CME, data is NULL */
39
40/* for QUIRK_MIDI_AKAI, data is NULL */
41
42int snd_usbmidi_create(struct snd_card *card,
43 struct usb_interface *iface,
44 struct list_head *midi_list,
45 const struct snd_usb_audio_quirk *quirk);
46void snd_usbmidi_input_stop(struct list_head* p);
47void snd_usbmidi_input_start(struct list_head* p);
48void snd_usbmidi_disconnect(struct list_head *p);
49
50#endif /* __USBMIDI_H */
diff --git a/sound/usb/misc/Makefile b/sound/usb/misc/Makefile
new file mode 100644
index 000000000000..ccefd8158936
--- /dev/null
+++ b/sound/usb/misc/Makefile
@@ -0,0 +1,2 @@
1snd-ua101-objs := ua101.o
2obj-$(CONFIG_SND_USB_UA101) += snd-ua101.o
diff --git a/sound/usb/ua101.c b/sound/usb/misc/ua101.c
index 3d458d3b9962..fb5d68fa7ff4 100644
--- a/sound/usb/ua101.c
+++ b/sound/usb/misc/ua101.c
@@ -23,7 +23,8 @@
23#include <sound/initval.h> 23#include <sound/initval.h>
24#include <sound/pcm.h> 24#include <sound/pcm.h>
25#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
26#include "usbaudio.h" 26#include "../usbaudio.h"
27#include "../midi.h"
27 28
28MODULE_DESCRIPTION("Edirol UA-101/1000 driver"); 29MODULE_DESCRIPTION("Edirol UA-101/1000 driver");
29MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); 30MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
@@ -41,7 +42,7 @@ MODULE_SUPPORTED_DEVICE("{{Edirol,UA-101},{Edirol,UA-1000}}");
41/* 42/*
42 * This magic value optimizes memory usage efficiency for the UA-101's packet 43 * This magic value optimizes memory usage efficiency for the UA-101's packet
43 * sizes at all sample rates, taking into account the stupid cache pool sizes 44 * sizes at all sample rates, taking into account the stupid cache pool sizes
44 * that usb_buffer_alloc() uses. 45 * that usb_alloc_coherent() uses.
45 */ 46 */
46#define DEFAULT_QUEUE_LENGTH 21 47#define DEFAULT_QUEUE_LENGTH 21
47 48
@@ -1056,7 +1057,7 @@ static int alloc_stream_buffers(struct ua101 *ua, struct ua101_stream *stream)
1056 (unsigned int)MAX_QUEUE_LENGTH); 1057 (unsigned int)MAX_QUEUE_LENGTH);
1057 1058
1058 /* 1059 /*
1059 * The cache pool sizes used by usb_buffer_alloc() (128, 512, 2048) are 1060 * The cache pool sizes used by usb_alloc_coherent() (128, 512, 2048) are
1060 * quite bad when used with the packet sizes of this device (e.g. 280, 1061 * quite bad when used with the packet sizes of this device (e.g. 280,
1061 * 520, 624). Therefore, we allocate and subdivide entire pages, using 1062 * 520, 624). Therefore, we allocate and subdivide entire pages, using
1062 * a smaller buffer only for the last chunk. 1063 * a smaller buffer only for the last chunk.
@@ -1067,8 +1068,8 @@ static int alloc_stream_buffers(struct ua101 *ua, struct ua101_stream *stream)
1067 packets = min(remaining_packets, packets_per_page); 1068 packets = min(remaining_packets, packets_per_page);
1068 size = packets * stream->max_packet_bytes; 1069 size = packets * stream->max_packet_bytes;
1069 stream->buffers[i].addr = 1070 stream->buffers[i].addr =
1070 usb_buffer_alloc(ua->dev, size, GFP_KERNEL, 1071 usb_alloc_coherent(ua->dev, size, GFP_KERNEL,
1071 &stream->buffers[i].dma); 1072 &stream->buffers[i].dma);
1072 if (!stream->buffers[i].addr) 1073 if (!stream->buffers[i].addr)
1073 return -ENOMEM; 1074 return -ENOMEM;
1074 stream->buffers[i].size = size; 1075 stream->buffers[i].size = size;
@@ -1088,10 +1089,10 @@ static void free_stream_buffers(struct ua101 *ua, struct ua101_stream *stream)
1088 unsigned int i; 1089 unsigned int i;
1089 1090
1090 for (i = 0; i < ARRAY_SIZE(stream->buffers); ++i) 1091 for (i = 0; i < ARRAY_SIZE(stream->buffers); ++i)
1091 usb_buffer_free(ua->dev, 1092 usb_free_coherent(ua->dev,
1092 stream->buffers[i].size, 1093 stream->buffers[i].size,
1093 stream->buffers[i].addr, 1094 stream->buffers[i].addr,
1094 stream->buffers[i].dma); 1095 stream->buffers[i].dma);
1095} 1096}
1096 1097
1097static int alloc_stream_urbs(struct ua101 *ua, struct ua101_stream *stream, 1098static int alloc_stream_urbs(struct ua101 *ua, struct ua101_stream *stream,
diff --git a/sound/usb/usbmixer.c b/sound/usb/mixer.c
index 8e8f871b74ca..03ce971e0027 100644
--- a/sound/usb/usbmixer.c
+++ b/sound/usb/mixer.c
@@ -33,6 +33,7 @@
33#include <linux/string.h> 33#include <linux/string.h>
34#include <linux/usb.h> 34#include <linux/usb.h>
35#include <linux/usb/audio.h> 35#include <linux/usb/audio.h>
36#include <linux/usb/audio-v2.h>
36 37
37#include <sound/core.h> 38#include <sound/core.h>
38#include <sound/control.h> 39#include <sound/control.h>
@@ -41,60 +42,12 @@
41#include <sound/tlv.h> 42#include <sound/tlv.h>
42 43
43#include "usbaudio.h" 44#include "usbaudio.h"
44 45#include "mixer.h"
45/* 46#include "helper.h"
46 */ 47#include "mixer_quirks.h"
47
48/* ignore error from controls - for debugging */
49/* #define IGNORE_CTL_ERROR */
50
51/*
52 * Sound Blaster remote control configuration
53 *
54 * format of remote control data:
55 * Extigy: xx 00
56 * Audigy 2 NX: 06 80 xx 00 00 00
57 * Live! 24-bit: 06 80 xx yy 22 83
58 */
59static const struct rc_config {
60 u32 usb_id;
61 u8 offset;
62 u8 length;
63 u8 packet_length;
64 u8 min_packet_length; /* minimum accepted length of the URB result */
65 u8 mute_mixer_id;
66 u32 mute_code;
67} rc_configs[] = {
68 { USB_ID(0x041e, 0x3000), 0, 1, 2, 1, 18, 0x0013 }, /* Extigy */
69 { USB_ID(0x041e, 0x3020), 2, 1, 6, 6, 18, 0x0013 }, /* Audigy 2 NX */
70 { USB_ID(0x041e, 0x3040), 2, 2, 6, 6, 2, 0x6e91 }, /* Live! 24-bit */
71 { USB_ID(0x041e, 0x3048), 2, 2, 6, 6, 2, 0x6e91 }, /* Toshiba SB0500 */
72};
73 48
74#define MAX_ID_ELEMS 256 49#define MAX_ID_ELEMS 256
75 50
76struct usb_mixer_interface {
77 struct snd_usb_audio *chip;
78 unsigned int ctrlif;
79 struct list_head list;
80 unsigned int ignore_ctl_error;
81 struct urb *urb;
82 /* array[MAX_ID_ELEMS], indexed by unit id */
83 struct usb_mixer_elem_info **id_elems;
84
85 /* Sound Blaster remote control stuff */
86 const struct rc_config *rc_cfg;
87 u32 rc_code;
88 wait_queue_head_t rc_waitq;
89 struct urb *rc_urb;
90 struct usb_ctrlrequest *rc_setup_packet;
91 u8 rc_buffer[6];
92
93 u8 audigy2nx_leds[3];
94 u8 xonar_u1_status;
95};
96
97
98struct usb_audio_term { 51struct usb_audio_term {
99 int id; 52 int id;
100 int type; 53 int type;
@@ -116,39 +69,6 @@ struct mixer_build {
116 const struct usbmix_selector_map *selector_map; 69 const struct usbmix_selector_map *selector_map;
117}; 70};
118 71
119#define MAX_CHANNELS 10 /* max logical channels */
120
121struct usb_mixer_elem_info {
122 struct usb_mixer_interface *mixer;
123 struct usb_mixer_elem_info *next_id_elem; /* list of controls with same id */
124 struct snd_ctl_elem_id *elem_id;
125 unsigned int id;
126 unsigned int control; /* CS or ICN (high byte) */
127 unsigned int cmask; /* channel mask bitmap: 0 = master */
128 int channels;
129 int val_type;
130 int min, max, res;
131 int dBmin, dBmax;
132 int cached;
133 int cache_val[MAX_CHANNELS];
134 u8 initialized;
135};
136
137
138enum {
139 USB_FEATURE_NONE = 0,
140 USB_FEATURE_MUTE = 1,
141 USB_FEATURE_VOLUME,
142 USB_FEATURE_BASS,
143 USB_FEATURE_MID,
144 USB_FEATURE_TREBLE,
145 USB_FEATURE_GEQ,
146 USB_FEATURE_AGC,
147 USB_FEATURE_DELAY,
148 USB_FEATURE_BASSBOOST,
149 USB_FEATURE_LOUDNESS
150};
151
152enum { 72enum {
153 USB_MIXER_BOOLEAN, 73 USB_MIXER_BOOLEAN,
154 USB_MIXER_INV_BOOLEAN, 74 USB_MIXER_INV_BOOLEAN,
@@ -213,7 +133,7 @@ enum {
213 * if the mixer topology is too complicated and the parsed names are 133 * if the mixer topology is too complicated and the parsed names are
214 * ambiguous, add the entries in usbmixer_maps.c. 134 * ambiguous, add the entries in usbmixer_maps.c.
215 */ 135 */
216#include "usbmixer_maps.c" 136#include "mixer_maps.c"
217 137
218static const struct usbmix_name_map * 138static const struct usbmix_name_map *
219find_map(struct mixer_build *state, int unitid, int control) 139find_map(struct mixer_build *state, int unitid, int control)
@@ -278,6 +198,7 @@ static int check_mapped_selector_name(struct mixer_build *state, int unitid,
278 198
279/* 199/*
280 * find an audio control unit with the given unit id 200 * find an audio control unit with the given unit id
201 * this doesn't return any clock related units, so they need to be handled elsewhere
281 */ 202 */
282static void *find_audio_control_unit(struct mixer_build *state, unsigned char unit) 203static void *find_audio_control_unit(struct mixer_build *state, unsigned char unit)
283{ 204{
@@ -286,7 +207,7 @@ static void *find_audio_control_unit(struct mixer_build *state, unsigned char un
286 p = NULL; 207 p = NULL;
287 while ((p = snd_usb_find_desc(state->buffer, state->buflen, p, 208 while ((p = snd_usb_find_desc(state->buffer, state->buflen, p,
288 USB_DT_CS_INTERFACE)) != NULL) { 209 USB_DT_CS_INTERFACE)) != NULL) {
289 if (p[0] >= 4 && p[2] >= UAC_INPUT_TERMINAL && p[2] <= UAC_EXTENSION_UNIT_V1 && p[3] == unit) 210 if (p[0] >= 4 && p[2] >= UAC_INPUT_TERMINAL && p[2] <= UAC2_EXTENSION_UNIT_V2 && p[3] == unit)
290 return p; 211 return p;
291 } 212 }
292 return NULL; 213 return NULL;
@@ -383,7 +304,7 @@ static int get_abs_value(struct usb_mixer_elem_info *cval, int val)
383 * retrieve a mixer value 304 * retrieve a mixer value
384 */ 305 */
385 306
386static int get_ctl_value(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret) 307static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret)
387{ 308{
388 unsigned char buf[2]; 309 unsigned char buf[2];
389 int val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1; 310 int val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1;
@@ -405,6 +326,58 @@ static int get_ctl_value(struct usb_mixer_elem_info *cval, int request, int vali
405 return -EINVAL; 326 return -EINVAL;
406} 327}
407 328
329static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret)
330{
331 unsigned char buf[14]; /* enough space for one range of 4 bytes */
332 unsigned char *val;
333 int ret;
334 __u8 bRequest;
335
336 bRequest = (request == UAC_GET_CUR) ?
337 UAC2_CS_CUR : UAC2_CS_RANGE;
338
339 ret = snd_usb_ctl_msg(cval->mixer->chip->dev,
340 usb_rcvctrlpipe(cval->mixer->chip->dev, 0),
341 bRequest,
342 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
343 validx, cval->mixer->ctrlif | (cval->id << 8),
344 buf, sizeof(buf), 1000);
345
346 if (ret < 0) {
347 snd_printdd(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n",
348 request, validx, cval->mixer->ctrlif | (cval->id << 8), cval->val_type);
349 return ret;
350 }
351
352 switch (request) {
353 case UAC_GET_CUR:
354 val = buf;
355 break;
356 case UAC_GET_MIN:
357 val = buf + sizeof(__u16);
358 break;
359 case UAC_GET_MAX:
360 val = buf + sizeof(__u16) * 2;
361 break;
362 case UAC_GET_RES:
363 val = buf + sizeof(__u16) * 3;
364 break;
365 default:
366 return -EINVAL;
367 }
368
369 *value_ret = convert_signed_value(cval, snd_usb_combine_bytes(val, sizeof(__u16)));
370
371 return 0;
372}
373
374static int get_ctl_value(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret)
375{
376 return (cval->mixer->protocol == UAC_VERSION_1) ?
377 get_ctl_value_v1(cval, request, validx, value_ret) :
378 get_ctl_value_v2(cval, request, validx, value_ret);
379}
380
408static int get_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int *value) 381static int get_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int *value)
409{ 382{
410 return get_ctl_value(cval, UAC_GET_CUR, validx, value); 383 return get_ctl_value(cval, UAC_GET_CUR, validx, value);
@@ -429,8 +402,7 @@ static int get_cur_mix_value(struct usb_mixer_elem_info *cval,
429 err = get_cur_mix_raw(cval, channel, value); 402 err = get_cur_mix_raw(cval, channel, value);
430 if (err < 0) { 403 if (err < 0) {
431 if (!cval->mixer->ignore_ctl_error) 404 if (!cval->mixer->ignore_ctl_error)
432 snd_printd(KERN_ERR "cannot get current value for " 405 snd_printd(KERN_ERR "cannot get current value for control %d ch %d: err = %d\n",
433 "control %d ch %d: err = %d\n",
434 cval->control, channel, err); 406 cval->control, channel, err);
435 return err; 407 return err;
436 } 408 }
@@ -444,11 +416,26 @@ static int get_cur_mix_value(struct usb_mixer_elem_info *cval,
444 * set a mixer value 416 * set a mixer value
445 */ 417 */
446 418
447static int set_ctl_value(struct usb_mixer_elem_info *cval, int request, int validx, int value_set) 419int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
420 int request, int validx, int value_set)
448{ 421{
449 unsigned char buf[2]; 422 unsigned char buf[2];
450 int val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1; 423 int val_len, timeout = 10;
451 int timeout = 10; 424
425 if (cval->mixer->protocol == UAC_VERSION_1) {
426 val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1;
427 } else { /* UAC_VERSION_2 */
428 /* audio class v2 controls are always 2 bytes in size */
429 val_len = sizeof(__u16);
430
431 /* FIXME */
432 if (request != UAC_SET_CUR) {
433 snd_printdd(KERN_WARNING "RANGE setting not yet supported\n");
434 return -EINVAL;
435 }
436
437 request = UAC2_CS_CUR;
438 }
452 439
453 value_set = convert_bytes_value(cval, value_set); 440 value_set = convert_bytes_value(cval, value_set);
454 buf[0] = value_set & 0xff; 441 buf[0] = value_set & 0xff;
@@ -468,14 +455,14 @@ static int set_ctl_value(struct usb_mixer_elem_info *cval, int request, int vali
468 455
469static int set_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int value) 456static int set_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int value)
470{ 457{
471 return set_ctl_value(cval, UAC_SET_CUR, validx, value); 458 return snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR, validx, value);
472} 459}
473 460
474static int set_cur_mix_value(struct usb_mixer_elem_info *cval, int channel, 461static int set_cur_mix_value(struct usb_mixer_elem_info *cval, int channel,
475 int index, int value) 462 int index, int value)
476{ 463{
477 int err; 464 int err;
478 err = set_ctl_value(cval, UAC_SET_CUR, (cval->control << 8) | channel, 465 err = snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR, (cval->control << 8) | channel,
479 value); 466 value);
480 if (err < 0) 467 if (err < 0)
481 return err; 468 return err;
@@ -644,46 +631,65 @@ static int get_term_name(struct mixer_build *state, struct usb_audio_term *iterm
644 */ 631 */
645static int check_input_term(struct mixer_build *state, int id, struct usb_audio_term *term) 632static int check_input_term(struct mixer_build *state, int id, struct usb_audio_term *term)
646{ 633{
647 unsigned char *p1; 634 void *p1;
648 635
649 memset(term, 0, sizeof(*term)); 636 memset(term, 0, sizeof(*term));
650 while ((p1 = find_audio_control_unit(state, id)) != NULL) { 637 while ((p1 = find_audio_control_unit(state, id)) != NULL) {
638 unsigned char *hdr = p1;
651 term->id = id; 639 term->id = id;
652 switch (p1[2]) { 640 switch (hdr[2]) {
653 case UAC_INPUT_TERMINAL: 641 case UAC_INPUT_TERMINAL:
654 term->type = combine_word(p1 + 4); 642 if (state->mixer->protocol == UAC_VERSION_1) {
655 term->channels = p1[7]; 643 struct uac_input_terminal_descriptor *d = p1;
656 term->chconfig = combine_word(p1 + 8); 644 term->type = le16_to_cpu(d->wTerminalType);
657 term->name = p1[11]; 645 term->channels = d->bNrChannels;
646 term->chconfig = le16_to_cpu(d->wChannelConfig);
647 term->name = d->iTerminal;
648 } else { /* UAC_VERSION_2 */
649 struct uac2_input_terminal_descriptor *d = p1;
650 term->type = le16_to_cpu(d->wTerminalType);
651 term->channels = d->bNrChannels;
652 term->chconfig = le32_to_cpu(d->bmChannelConfig);
653 term->name = d->iTerminal;
654 }
658 return 0; 655 return 0;
659 case UAC_FEATURE_UNIT: 656 case UAC_FEATURE_UNIT: {
660 id = p1[4]; 657 /* the header is the same for v1 and v2 */
658 struct uac_feature_unit_descriptor *d = p1;
659 id = d->bSourceID;
661 break; /* continue to parse */ 660 break; /* continue to parse */
662 case UAC_MIXER_UNIT: 661 }
663 term->type = p1[2] << 16; /* virtual type */ 662 case UAC_MIXER_UNIT: {
664 term->channels = p1[5 + p1[4]]; 663 struct uac_mixer_unit_descriptor *d = p1;
665 term->chconfig = combine_word(p1 + 6 + p1[4]); 664 term->type = d->bDescriptorSubtype << 16; /* virtual type */
666 term->name = p1[p1[0] - 1]; 665 term->channels = uac_mixer_unit_bNrChannels(d);
666 term->chconfig = uac_mixer_unit_wChannelConfig(d, state->mixer->protocol);
667 term->name = uac_mixer_unit_iMixer(d);
667 return 0; 668 return 0;
668 case UAC_SELECTOR_UNIT: 669 }
670 case UAC_SELECTOR_UNIT: {
671 struct uac_selector_unit_descriptor *d = p1;
669 /* call recursively to retrieve the channel info */ 672 /* call recursively to retrieve the channel info */
670 if (check_input_term(state, p1[5], term) < 0) 673 if (check_input_term(state, d->baSourceID[0], term) < 0)
671 return -ENODEV; 674 return -ENODEV;
672 term->type = p1[2] << 16; /* virtual type */ 675 term->type = d->bDescriptorSubtype << 16; /* virtual type */
673 term->id = id; 676 term->id = id;
674 term->name = p1[9 + p1[0] - 1]; 677 term->name = uac_selector_unit_iSelector(d);
675 return 0; 678 return 0;
679 }
676 case UAC_PROCESSING_UNIT_V1: 680 case UAC_PROCESSING_UNIT_V1:
677 case UAC_EXTENSION_UNIT_V1: 681 case UAC_EXTENSION_UNIT_V1: {
678 if (p1[6] == 1) { 682 struct uac_processing_unit_descriptor *d = p1;
679 id = p1[7]; 683 if (d->bNrInPins) {
684 id = d->baSourceID[0];
680 break; /* continue to parse */ 685 break; /* continue to parse */
681 } 686 }
682 term->type = p1[2] << 16; /* virtual type */ 687 term->type = d->bDescriptorSubtype << 16; /* virtual type */
683 term->channels = p1[7 + p1[6]]; 688 term->channels = uac_processing_unit_bNrChannels(d);
684 term->chconfig = combine_word(p1 + 8 + p1[6]); 689 term->chconfig = uac_processing_unit_wChannelConfig(d, state->mixer->protocol);
685 term->name = p1[12 + p1[6] + p1[11 + p1[6]]]; 690 term->name = uac_processing_unit_iProcessing(d, state->mixer->protocol);
686 return 0; 691 return 0;
692 }
687 default: 693 default:
688 return -ENODEV; 694 return -ENODEV;
689 } 695 }
@@ -764,7 +770,8 @@ static int get_min_max(struct usb_mixer_elem_info *cval, int default_min)
764 int last_valid_res = cval->res; 770 int last_valid_res = cval->res;
765 771
766 while (cval->res > 1) { 772 while (cval->res > 1) {
767 if (set_ctl_value(cval, UAC_SET_RES, (cval->control << 8) | minchn, cval->res / 2) < 0) 773 if (snd_usb_mixer_set_ctl_value(cval, UAC_SET_RES,
774 (cval->control << 8) | minchn, cval->res / 2) < 0)
768 break; 775 break;
769 cval->res /= 2; 776 cval->res /= 2;
770 } 777 }
@@ -929,6 +936,15 @@ static struct snd_kcontrol_new usb_feature_unit_ctl = {
929 .put = mixer_ctl_feature_put, 936 .put = mixer_ctl_feature_put,
930}; 937};
931 938
939/* the read-only variant */
940static struct snd_kcontrol_new usb_feature_unit_ctl_ro = {
941 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
942 .name = "", /* will be filled later manually */
943 .info = mixer_ctl_feature_info,
944 .get = mixer_ctl_feature_get,
945 .put = NULL,
946};
947
932 948
933/* 949/*
934 * build a feature control 950 * build a feature control
@@ -939,20 +955,22 @@ static size_t append_ctl_name(struct snd_kcontrol *kctl, const char *str)
939 return strlcat(kctl->id.name, str, sizeof(kctl->id.name)); 955 return strlcat(kctl->id.name, str, sizeof(kctl->id.name));
940} 956}
941 957
942static void build_feature_ctl(struct mixer_build *state, unsigned char *desc, 958static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
943 unsigned int ctl_mask, int control, 959 unsigned int ctl_mask, int control,
944 struct usb_audio_term *iterm, int unitid) 960 struct usb_audio_term *iterm, int unitid,
961 int read_only)
945{ 962{
963 struct uac_feature_unit_descriptor *desc = raw_desc;
946 unsigned int len = 0; 964 unsigned int len = 0;
947 int mapped_name = 0; 965 int mapped_name = 0;
948 int nameid = desc[desc[0] - 1]; 966 int nameid = uac_feature_unit_iFeature(desc);
949 struct snd_kcontrol *kctl; 967 struct snd_kcontrol *kctl;
950 struct usb_mixer_elem_info *cval; 968 struct usb_mixer_elem_info *cval;
951 const struct usbmix_name_map *map; 969 const struct usbmix_name_map *map;
952 970
953 control++; /* change from zero-based to 1-based value */ 971 control++; /* change from zero-based to 1-based value */
954 972
955 if (control == USB_FEATURE_GEQ) { 973 if (control == UAC_GRAPHIC_EQUALIZER_CONTROL) {
956 /* FIXME: not supported yet */ 974 /* FIXME: not supported yet */
957 return; 975 return;
958 } 976 }
@@ -984,7 +1002,11 @@ static void build_feature_ctl(struct mixer_build *state, unsigned char *desc,
984 /* get min/max values */ 1002 /* get min/max values */
985 get_min_max(cval, 0); 1003 get_min_max(cval, 0);
986 1004
987 kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval); 1005 if (read_only)
1006 kctl = snd_ctl_new1(&usb_feature_unit_ctl_ro, cval);
1007 else
1008 kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval);
1009
988 if (! kctl) { 1010 if (! kctl) {
989 snd_printk(KERN_ERR "cannot malloc kcontrol\n"); 1011 snd_printk(KERN_ERR "cannot malloc kcontrol\n");
990 kfree(cval); 1012 kfree(cval);
@@ -999,8 +1021,8 @@ static void build_feature_ctl(struct mixer_build *state, unsigned char *desc,
999 kctl->id.name, sizeof(kctl->id.name)); 1021 kctl->id.name, sizeof(kctl->id.name));
1000 1022
1001 switch (control) { 1023 switch (control) {
1002 case USB_FEATURE_MUTE: 1024 case UAC_MUTE_CONTROL:
1003 case USB_FEATURE_VOLUME: 1025 case UAC_VOLUME_CONTROL:
1004 /* determine the control name. the rule is: 1026 /* determine the control name. the rule is:
1005 * - if a name id is given in descriptor, use it. 1027 * - if a name id is given in descriptor, use it.
1006 * - if the connected input can be determined, then use the name 1028 * - if the connected input can be determined, then use the name
@@ -1027,9 +1049,9 @@ static void build_feature_ctl(struct mixer_build *state, unsigned char *desc,
1027 len = append_ctl_name(kctl, " Playback"); 1049 len = append_ctl_name(kctl, " Playback");
1028 } 1050 }
1029 } 1051 }
1030 append_ctl_name(kctl, control == USB_FEATURE_MUTE ? 1052 append_ctl_name(kctl, control == UAC_MUTE_CONTROL ?
1031 " Switch" : " Volume"); 1053 " Switch" : " Volume");
1032 if (control == USB_FEATURE_VOLUME) { 1054 if (control == UAC_VOLUME_CONTROL) {
1033 kctl->tlv.c = mixer_vol_tlv; 1055 kctl->tlv.c = mixer_vol_tlv;
1034 kctl->vd[0].access |= 1056 kctl->vd[0].access |=
1035 SNDRV_CTL_ELEM_ACCESS_TLV_READ | 1057 SNDRV_CTL_ELEM_ACCESS_TLV_READ |
@@ -1094,49 +1116,92 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void
1094 struct usb_audio_term iterm; 1116 struct usb_audio_term iterm;
1095 unsigned int master_bits, first_ch_bits; 1117 unsigned int master_bits, first_ch_bits;
1096 int err, csize; 1118 int err, csize;
1097 struct uac_feature_unit_descriptor *ftr = _ftr; 1119 struct uac_feature_unit_descriptor *hdr = _ftr;
1120 __u8 *bmaControls;
1098 1121
1099 if (ftr->bLength < 7 || ! (csize = ftr->bControlSize) || ftr->bLength < 7 + csize) { 1122 if (state->mixer->protocol == UAC_VERSION_1) {
1123 csize = hdr->bControlSize;
1124 channels = (hdr->bLength - 7) / csize - 1;
1125 bmaControls = hdr->bmaControls;
1126 } else {
1127 struct uac2_feature_unit_descriptor *ftr = _ftr;
1128 csize = 4;
1129 channels = (hdr->bLength - 6) / 4 - 1;
1130 bmaControls = ftr->bmaControls;
1131 }
1132
1133 if (hdr->bLength < 7 || !csize || hdr->bLength < 7 + csize) {
1100 snd_printk(KERN_ERR "usbaudio: unit %u: invalid UAC_FEATURE_UNIT descriptor\n", unitid); 1134 snd_printk(KERN_ERR "usbaudio: unit %u: invalid UAC_FEATURE_UNIT descriptor\n", unitid);
1101 return -EINVAL; 1135 return -EINVAL;
1102 } 1136 }
1103 1137
1104 /* parse the source unit */ 1138 /* parse the source unit */
1105 if ((err = parse_audio_unit(state, ftr->bSourceID)) < 0) 1139 if ((err = parse_audio_unit(state, hdr->bSourceID)) < 0)
1106 return err; 1140 return err;
1107 1141
1108 /* determine the input source type and name */ 1142 /* determine the input source type and name */
1109 if (check_input_term(state, ftr->bSourceID, &iterm) < 0) 1143 if (check_input_term(state, hdr->bSourceID, &iterm) < 0)
1110 return -EINVAL; 1144 return -EINVAL;
1111 1145
1112 channels = (ftr->bLength - 7) / csize - 1; 1146 master_bits = snd_usb_combine_bytes(bmaControls, csize);
1113
1114 master_bits = snd_usb_combine_bytes(ftr->controls, csize);
1115 /* master configuration quirks */ 1147 /* master configuration quirks */
1116 switch (state->chip->usb_id) { 1148 switch (state->chip->usb_id) {
1117 case USB_ID(0x08bb, 0x2702): 1149 case USB_ID(0x08bb, 0x2702):
1118 snd_printk(KERN_INFO 1150 snd_printk(KERN_INFO
1119 "usbmixer: master volume quirk for PCM2702 chip\n"); 1151 "usbmixer: master volume quirk for PCM2702 chip\n");
1120 /* disable non-functional volume control */ 1152 /* disable non-functional volume control */
1121 master_bits &= ~(1 << (USB_FEATURE_VOLUME - 1)); 1153 master_bits &= ~UAC_FU_VOLUME;
1122 break; 1154 break;
1123 } 1155 }
1124 if (channels > 0) 1156 if (channels > 0)
1125 first_ch_bits = snd_usb_combine_bytes(ftr->controls + csize, csize); 1157 first_ch_bits = snd_usb_combine_bytes(bmaControls + csize, csize);
1126 else 1158 else
1127 first_ch_bits = 0; 1159 first_ch_bits = 0;
1128 /* check all control types */ 1160
1129 for (i = 0; i < 10; i++) { 1161 if (state->mixer->protocol == UAC_VERSION_1) {
1130 unsigned int ch_bits = 0; 1162 /* check all control types */
1131 for (j = 0; j < channels; j++) { 1163 for (i = 0; i < 10; i++) {
1132 unsigned int mask = snd_usb_combine_bytes(ftr->controls + csize * (j+1), csize); 1164 unsigned int ch_bits = 0;
1133 if (mask & (1 << i)) 1165 for (j = 0; j < channels; j++) {
1134 ch_bits |= (1 << j); 1166 unsigned int mask = snd_usb_combine_bytes(bmaControls + csize * (j+1), csize);
1167 if (mask & (1 << i))
1168 ch_bits |= (1 << j);
1169 }
1170 /* audio class v1 controls are never read-only */
1171 if (ch_bits & 1) /* the first channel must be set (for ease of programming) */
1172 build_feature_ctl(state, _ftr, ch_bits, i, &iterm, unitid, 0);
1173 if (master_bits & (1 << i))
1174 build_feature_ctl(state, _ftr, 0, i, &iterm, unitid, 0);
1175 }
1176 } else { /* UAC_VERSION_2 */
1177 for (i = 0; i < 30/2; i++) {
1178 /* From the USB Audio spec v2.0:
1179 bmaControls() is a (ch+1)-element array of 4-byte bitmaps,
1180 each containing a set of bit pairs. If a Control is present,
1181 it must be Host readable. If a certain Control is not
1182 present then the bit pair must be set to 0b00.
1183 If a Control is present but read-only, the bit pair must be
1184 set to 0b01. If a Control is also Host programmable, the bit
1185 pair must be set to 0b11. The value 0b10 is not allowed. */
1186 unsigned int ch_bits = 0;
1187 unsigned int ch_read_only = 0;
1188
1189 for (j = 0; j < channels; j++) {
1190 unsigned int mask = snd_usb_combine_bytes(bmaControls + csize * (j+1), csize);
1191 if (mask & (1 << (i * 2))) {
1192 ch_bits |= (1 << j);
1193 if (~mask & (1 << ((i * 2) + 1)))
1194 ch_read_only |= (1 << j);
1195 }
1196 }
1197
1198 /* FIXME: the whole unit is read-only if any of the channels is marked read-only */
1199 if (ch_bits & 1) /* the first channel must be set (for ease of programming) */
1200 build_feature_ctl(state, _ftr, ch_bits, i, &iterm, unitid, !!ch_read_only);
1201 if (master_bits & (1 << i * 2))
1202 build_feature_ctl(state, _ftr, 0, i, &iterm, unitid,
1203 ~master_bits & (1 << ((i * 2) + 1)));
1135 } 1204 }
1136 if (ch_bits & 1) /* the first channel must be set (for ease of programming) */
1137 build_feature_ctl(state, _ftr, ch_bits, i, &iterm, unitid);
1138 if (master_bits & (1 << i))
1139 build_feature_ctl(state, _ftr, 0, i, &iterm, unitid);
1140 } 1205 }
1141 1206
1142 return 0; 1207 return 0;
@@ -1154,13 +1219,13 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void
1154 * input channel number (zero based) is given in control field instead. 1219 * input channel number (zero based) is given in control field instead.
1155 */ 1220 */
1156 1221
1157static void build_mixer_unit_ctl(struct mixer_build *state, unsigned char *desc, 1222static void build_mixer_unit_ctl(struct mixer_build *state,
1223 struct uac_mixer_unit_descriptor *desc,
1158 int in_pin, int in_ch, int unitid, 1224 int in_pin, int in_ch, int unitid,
1159 struct usb_audio_term *iterm) 1225 struct usb_audio_term *iterm)
1160{ 1226{
1161 struct usb_mixer_elem_info *cval; 1227 struct usb_mixer_elem_info *cval;
1162 unsigned int input_pins = desc[4]; 1228 unsigned int num_outs = uac_mixer_unit_bNrChannels(desc);
1163 unsigned int num_outs = desc[5 + input_pins];
1164 unsigned int i, len; 1229 unsigned int i, len;
1165 struct snd_kcontrol *kctl; 1230 struct snd_kcontrol *kctl;
1166 const struct usbmix_name_map *map; 1231 const struct usbmix_name_map *map;
@@ -1178,7 +1243,7 @@ static void build_mixer_unit_ctl(struct mixer_build *state, unsigned char *desc,
1178 cval->control = in_ch + 1; /* based on 1 */ 1243 cval->control = in_ch + 1; /* based on 1 */
1179 cval->val_type = USB_MIXER_S16; 1244 cval->val_type = USB_MIXER_S16;
1180 for (i = 0; i < num_outs; i++) { 1245 for (i = 0; i < num_outs; i++) {
1181 if (check_matrix_bitmap(desc + 9 + input_pins, in_ch, i, num_outs)) { 1246 if (check_matrix_bitmap(uac_mixer_unit_bmControls(desc, state->mixer->protocol), in_ch, i, num_outs)) {
1182 cval->cmask |= (1 << i); 1247 cval->cmask |= (1 << i);
1183 cval->channels++; 1248 cval->channels++;
1184 } 1249 }
@@ -1211,18 +1276,19 @@ static void build_mixer_unit_ctl(struct mixer_build *state, unsigned char *desc,
1211/* 1276/*
1212 * parse a mixer unit 1277 * parse a mixer unit
1213 */ 1278 */
1214static int parse_audio_mixer_unit(struct mixer_build *state, int unitid, unsigned char *desc) 1279static int parse_audio_mixer_unit(struct mixer_build *state, int unitid, void *raw_desc)
1215{ 1280{
1281 struct uac_mixer_unit_descriptor *desc = raw_desc;
1216 struct usb_audio_term iterm; 1282 struct usb_audio_term iterm;
1217 int input_pins, num_ins, num_outs; 1283 int input_pins, num_ins, num_outs;
1218 int pin, ich, err; 1284 int pin, ich, err;
1219 1285
1220 if (desc[0] < 11 || ! (input_pins = desc[4]) || ! (num_outs = desc[5 + input_pins])) { 1286 if (desc->bLength < 11 || ! (input_pins = desc->bNrInPins) || ! (num_outs = uac_mixer_unit_bNrChannels(desc))) {
1221 snd_printk(KERN_ERR "invalid MIXER UNIT descriptor %d\n", unitid); 1287 snd_printk(KERN_ERR "invalid MIXER UNIT descriptor %d\n", unitid);
1222 return -EINVAL; 1288 return -EINVAL;
1223 } 1289 }
1224 /* no bmControls field (e.g. Maya44) -> ignore */ 1290 /* no bmControls field (e.g. Maya44) -> ignore */
1225 if (desc[0] <= 10 + input_pins) { 1291 if (desc->bLength <= 10 + input_pins) {
1226 snd_printdd(KERN_INFO "MU %d has no bmControls field\n", unitid); 1292 snd_printdd(KERN_INFO "MU %d has no bmControls field\n", unitid);
1227 return 0; 1293 return 0;
1228 } 1294 }
@@ -1230,10 +1296,10 @@ static int parse_audio_mixer_unit(struct mixer_build *state, int unitid, unsigne
1230 num_ins = 0; 1296 num_ins = 0;
1231 ich = 0; 1297 ich = 0;
1232 for (pin = 0; pin < input_pins; pin++) { 1298 for (pin = 0; pin < input_pins; pin++) {
1233 err = parse_audio_unit(state, desc[5 + pin]); 1299 err = parse_audio_unit(state, desc->baSourceID[pin]);
1234 if (err < 0) 1300 if (err < 0)
1235 return err; 1301 return err;
1236 err = check_input_term(state, desc[5 + pin], &iterm); 1302 err = check_input_term(state, desc->baSourceID[pin], &iterm);
1237 if (err < 0) 1303 if (err < 0)
1238 return err; 1304 return err;
1239 num_ins += iterm.channels; 1305 num_ins += iterm.channels;
@@ -1241,7 +1307,7 @@ static int parse_audio_mixer_unit(struct mixer_build *state, int unitid, unsigne
1241 int och, ich_has_controls = 0; 1307 int och, ich_has_controls = 0;
1242 1308
1243 for (och = 0; och < num_outs; ++och) { 1309 for (och = 0; och < num_outs; ++och) {
1244 if (check_matrix_bitmap(desc + 9 + input_pins, 1310 if (check_matrix_bitmap(uac_mixer_unit_bmControls(desc, state->mixer->protocol),
1245 ich, och, num_outs)) { 1311 ich, och, num_outs)) {
1246 ich_has_controls = 1; 1312 ich_has_controls = 1;
1247 break; 1313 break;
@@ -1377,8 +1443,8 @@ static struct procunit_info procunits[] = {
1377 * predefined data for extension units 1443 * predefined data for extension units
1378 */ 1444 */
1379static struct procunit_value_info clock_rate_xu_info[] = { 1445static struct procunit_value_info clock_rate_xu_info[] = {
1380 { USB_XU_CLOCK_RATE_SELECTOR, "Selector", USB_MIXER_U8, 0 }, 1446 { USB_XU_CLOCK_RATE_SELECTOR, "Selector", USB_MIXER_U8, 0 },
1381 { 0 } 1447 { 0 }
1382}; 1448};
1383static struct procunit_value_info clock_source_xu_info[] = { 1449static struct procunit_value_info clock_source_xu_info[] = {
1384 { USB_XU_CLOCK_SOURCE_SELECTOR, "External", USB_MIXER_BOOLEAN }, 1450 { USB_XU_CLOCK_SOURCE_SELECTOR, "External", USB_MIXER_BOOLEAN },
@@ -1402,9 +1468,10 @@ static struct procunit_info extunits[] = {
1402/* 1468/*
1403 * build a processing/extension unit 1469 * build a processing/extension unit
1404 */ 1470 */
1405static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned char *dsc, struct procunit_info *list, char *name) 1471static int build_audio_procunit(struct mixer_build *state, int unitid, void *raw_desc, struct procunit_info *list, char *name)
1406{ 1472{
1407 int num_ins = dsc[6]; 1473 struct uac_processing_unit_descriptor *desc = raw_desc;
1474 int num_ins = desc->bNrInPins;
1408 struct usb_mixer_elem_info *cval; 1475 struct usb_mixer_elem_info *cval;
1409 struct snd_kcontrol *kctl; 1476 struct snd_kcontrol *kctl;
1410 int i, err, nameid, type, len; 1477 int i, err, nameid, type, len;
@@ -1419,17 +1486,18 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned
1419 0, NULL, default_value_info 1486 0, NULL, default_value_info
1420 }; 1487 };
1421 1488
1422 if (dsc[0] < 13 || dsc[0] < 13 + num_ins || dsc[0] < num_ins + dsc[11 + num_ins]) { 1489 if (desc->bLength < 13 || desc->bLength < 13 + num_ins ||
1490 desc->bLength < num_ins + uac_processing_unit_bControlSize(desc, state->mixer->protocol)) {
1423 snd_printk(KERN_ERR "invalid %s descriptor (id %d)\n", name, unitid); 1491 snd_printk(KERN_ERR "invalid %s descriptor (id %d)\n", name, unitid);
1424 return -EINVAL; 1492 return -EINVAL;
1425 } 1493 }
1426 1494
1427 for (i = 0; i < num_ins; i++) { 1495 for (i = 0; i < num_ins; i++) {
1428 if ((err = parse_audio_unit(state, dsc[7 + i])) < 0) 1496 if ((err = parse_audio_unit(state, desc->baSourceID[i])) < 0)
1429 return err; 1497 return err;
1430 } 1498 }
1431 1499
1432 type = combine_word(&dsc[4]); 1500 type = le16_to_cpu(desc->wProcessType);
1433 for (info = list; info && info->type; info++) 1501 for (info = list; info && info->type; info++)
1434 if (info->type == type) 1502 if (info->type == type)
1435 break; 1503 break;
@@ -1437,8 +1505,9 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned
1437 info = &default_info; 1505 info = &default_info;
1438 1506
1439 for (valinfo = info->values; valinfo->control; valinfo++) { 1507 for (valinfo = info->values; valinfo->control; valinfo++) {
1440 /* FIXME: bitmap might be longer than 8bit */ 1508 __u8 *controls = uac_processing_unit_bmControls(desc, state->mixer->protocol);
1441 if (! (dsc[12 + num_ins] & (1 << (valinfo->control - 1)))) 1509
1510 if (! (controls[valinfo->control / 8] & (1 << ((valinfo->control % 8) - 1))))
1442 continue; 1511 continue;
1443 map = find_map(state, unitid, valinfo->control); 1512 map = find_map(state, unitid, valinfo->control);
1444 if (check_ignored_ctl(map)) 1513 if (check_ignored_ctl(map))
@@ -1456,9 +1525,10 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned
1456 1525
1457 /* get min/max values */ 1526 /* get min/max values */
1458 if (type == USB_PROC_UPDOWN && cval->control == USB_PROC_UPDOWN_MODE_SEL) { 1527 if (type == USB_PROC_UPDOWN && cval->control == USB_PROC_UPDOWN_MODE_SEL) {
1528 __u8 *control_spec = uac_processing_unit_specific(desc, state->mixer->protocol);
1459 /* FIXME: hard-coded */ 1529 /* FIXME: hard-coded */
1460 cval->min = 1; 1530 cval->min = 1;
1461 cval->max = dsc[15]; 1531 cval->max = control_spec[0];
1462 cval->res = 1; 1532 cval->res = 1;
1463 cval->initialized = 1; 1533 cval->initialized = 1;
1464 } else { 1534 } else {
@@ -1488,7 +1558,7 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned
1488 else if (info->name) 1558 else if (info->name)
1489 strlcpy(kctl->id.name, info->name, sizeof(kctl->id.name)); 1559 strlcpy(kctl->id.name, info->name, sizeof(kctl->id.name));
1490 else { 1560 else {
1491 nameid = dsc[12 + num_ins + dsc[11 + num_ins]]; 1561 nameid = uac_processing_unit_iProcessing(desc, state->mixer->protocol);
1492 len = 0; 1562 len = 0;
1493 if (nameid) 1563 if (nameid)
1494 len = snd_usb_copy_string_desc(state, nameid, kctl->id.name, sizeof(kctl->id.name)); 1564 len = snd_usb_copy_string_desc(state, nameid, kctl->id.name, sizeof(kctl->id.name));
@@ -1507,14 +1577,16 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned
1507} 1577}
1508 1578
1509 1579
1510static int parse_audio_processing_unit(struct mixer_build *state, int unitid, unsigned char *desc) 1580static int parse_audio_processing_unit(struct mixer_build *state, int unitid, void *raw_desc)
1511{ 1581{
1512 return build_audio_procunit(state, unitid, desc, procunits, "Processing Unit"); 1582 return build_audio_procunit(state, unitid, raw_desc, procunits, "Processing Unit");
1513} 1583}
1514 1584
1515static int parse_audio_extension_unit(struct mixer_build *state, int unitid, unsigned char *desc) 1585static int parse_audio_extension_unit(struct mixer_build *state, int unitid, void *raw_desc)
1516{ 1586{
1517 return build_audio_procunit(state, unitid, desc, extunits, "Extension Unit"); 1587 /* Note that we parse extension units with processing unit descriptors.
1588 * That's ok as the layout is the same */
1589 return build_audio_procunit(state, unitid, raw_desc, extunits, "Extension Unit");
1518} 1590}
1519 1591
1520 1592
@@ -1616,9 +1688,9 @@ static void usb_mixer_selector_elem_free(struct snd_kcontrol *kctl)
1616/* 1688/*
1617 * parse a selector unit 1689 * parse a selector unit
1618 */ 1690 */
1619static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsigned char *desc) 1691static int parse_audio_selector_unit(struct mixer_build *state, int unitid, void *raw_desc)
1620{ 1692{
1621 unsigned int num_ins = desc[4]; 1693 struct uac_selector_unit_descriptor *desc = raw_desc;
1622 unsigned int i, nameid, len; 1694 unsigned int i, nameid, len;
1623 int err; 1695 int err;
1624 struct usb_mixer_elem_info *cval; 1696 struct usb_mixer_elem_info *cval;
@@ -1626,17 +1698,17 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsi
1626 const struct usbmix_name_map *map; 1698 const struct usbmix_name_map *map;
1627 char **namelist; 1699 char **namelist;
1628 1700
1629 if (! num_ins || desc[0] < 5 + num_ins) { 1701 if (!desc->bNrInPins || desc->bLength < 5 + desc->bNrInPins) {
1630 snd_printk(KERN_ERR "invalid SELECTOR UNIT descriptor %d\n", unitid); 1702 snd_printk(KERN_ERR "invalid SELECTOR UNIT descriptor %d\n", unitid);
1631 return -EINVAL; 1703 return -EINVAL;
1632 } 1704 }
1633 1705
1634 for (i = 0; i < num_ins; i++) { 1706 for (i = 0; i < desc->bNrInPins; i++) {
1635 if ((err = parse_audio_unit(state, desc[5 + i])) < 0) 1707 if ((err = parse_audio_unit(state, desc->baSourceID[i])) < 0)
1636 return err; 1708 return err;
1637 } 1709 }
1638 1710
1639 if (num_ins == 1) /* only one ? nonsense! */ 1711 if (desc->bNrInPins == 1) /* only one ? nonsense! */
1640 return 0; 1712 return 0;
1641 1713
1642 map = find_map(state, unitid, 0); 1714 map = find_map(state, unitid, 0);
@@ -1653,18 +1725,18 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsi
1653 cval->val_type = USB_MIXER_U8; 1725 cval->val_type = USB_MIXER_U8;
1654 cval->channels = 1; 1726 cval->channels = 1;
1655 cval->min = 1; 1727 cval->min = 1;
1656 cval->max = num_ins; 1728 cval->max = desc->bNrInPins;
1657 cval->res = 1; 1729 cval->res = 1;
1658 cval->initialized = 1; 1730 cval->initialized = 1;
1659 1731
1660 namelist = kmalloc(sizeof(char *) * num_ins, GFP_KERNEL); 1732 namelist = kmalloc(sizeof(char *) * desc->bNrInPins, GFP_KERNEL);
1661 if (! namelist) { 1733 if (! namelist) {
1662 snd_printk(KERN_ERR "cannot malloc\n"); 1734 snd_printk(KERN_ERR "cannot malloc\n");
1663 kfree(cval); 1735 kfree(cval);
1664 return -ENOMEM; 1736 return -ENOMEM;
1665 } 1737 }
1666#define MAX_ITEM_NAME_LEN 64 1738#define MAX_ITEM_NAME_LEN 64
1667 for (i = 0; i < num_ins; i++) { 1739 for (i = 0; i < desc->bNrInPins; i++) {
1668 struct usb_audio_term iterm; 1740 struct usb_audio_term iterm;
1669 len = 0; 1741 len = 0;
1670 namelist[i] = kmalloc(MAX_ITEM_NAME_LEN, GFP_KERNEL); 1742 namelist[i] = kmalloc(MAX_ITEM_NAME_LEN, GFP_KERNEL);
@@ -1678,7 +1750,7 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsi
1678 } 1750 }
1679 len = check_mapped_selector_name(state, unitid, i, namelist[i], 1751 len = check_mapped_selector_name(state, unitid, i, namelist[i],
1680 MAX_ITEM_NAME_LEN); 1752 MAX_ITEM_NAME_LEN);
1681 if (! len && check_input_term(state, desc[5 + i], &iterm) >= 0) 1753 if (! len && check_input_term(state, desc->baSourceID[i], &iterm) >= 0)
1682 len = get_term_name(state, &iterm, namelist[i], MAX_ITEM_NAME_LEN, 0); 1754 len = get_term_name(state, &iterm, namelist[i], MAX_ITEM_NAME_LEN, 0);
1683 if (! len) 1755 if (! len)
1684 sprintf(namelist[i], "Input %d", i); 1756 sprintf(namelist[i], "Input %d", i);
@@ -1694,7 +1766,7 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsi
1694 kctl->private_value = (unsigned long)namelist; 1766 kctl->private_value = (unsigned long)namelist;
1695 kctl->private_free = usb_mixer_selector_elem_free; 1767 kctl->private_free = usb_mixer_selector_elem_free;
1696 1768
1697 nameid = desc[desc[0] - 1]; 1769 nameid = uac_selector_unit_iSelector(desc);
1698 len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name)); 1770 len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name));
1699 if (len) 1771 if (len)
1700 ; 1772 ;
@@ -1713,7 +1785,7 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsi
1713 } 1785 }
1714 1786
1715 snd_printdd(KERN_INFO "[%d] SU [%s] items = %d\n", 1787 snd_printdd(KERN_INFO "[%d] SU [%s] items = %d\n",
1716 cval->id, kctl->id.name, num_ins); 1788 cval->id, kctl->id.name, desc->bNrInPins);
1717 if ((err = add_control_to_empty(state, kctl)) < 0) 1789 if ((err = add_control_to_empty(state, kctl)) < 0)
1718 return err; 1790 return err;
1719 1791
@@ -1748,9 +1820,17 @@ static int parse_audio_unit(struct mixer_build *state, int unitid)
1748 case UAC_FEATURE_UNIT: 1820 case UAC_FEATURE_UNIT:
1749 return parse_audio_feature_unit(state, unitid, p1); 1821 return parse_audio_feature_unit(state, unitid, p1);
1750 case UAC_PROCESSING_UNIT_V1: 1822 case UAC_PROCESSING_UNIT_V1:
1751 return parse_audio_processing_unit(state, unitid, p1); 1823 /* UAC2_EFFECT_UNIT has the same value */
1824 if (state->mixer->protocol == UAC_VERSION_1)
1825 return parse_audio_processing_unit(state, unitid, p1);
1826 else
1827 return 0; /* FIXME - effect units not implemented yet */
1752 case UAC_EXTENSION_UNIT_V1: 1828 case UAC_EXTENSION_UNIT_V1:
1753 return parse_audio_extension_unit(state, unitid, p1); 1829 /* UAC2_PROCESSING_UNIT_V2 has the same value */
1830 if (state->mixer->protocol == UAC_VERSION_1)
1831 return parse_audio_extension_unit(state, unitid, p1);
1832 else /* UAC_VERSION_2 */
1833 return parse_audio_processing_unit(state, unitid, p1);
1754 default: 1834 default:
1755 snd_printk(KERN_ERR "usbaudio: unit %u: unexpected type 0x%02x\n", unitid, p1[2]); 1835 snd_printk(KERN_ERR "usbaudio: unit %u: unexpected type 0x%02x\n", unitid, p1[2]);
1756 return -EINVAL; 1836 return -EINVAL;
@@ -1783,11 +1863,11 @@ static int snd_usb_mixer_dev_free(struct snd_device *device)
1783 */ 1863 */
1784static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer) 1864static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
1785{ 1865{
1786 struct uac_output_terminal_descriptor_v1 *desc;
1787 struct mixer_build state; 1866 struct mixer_build state;
1788 int err; 1867 int err;
1789 const struct usbmix_ctl_map *map; 1868 const struct usbmix_ctl_map *map;
1790 struct usb_host_interface *hostif; 1869 struct usb_host_interface *hostif;
1870 void *p;
1791 1871
1792 hostif = &usb_ifnum_to_if(mixer->chip->dev, mixer->ctrlif)->altsetting[0]; 1872 hostif = &usb_ifnum_to_if(mixer->chip->dev, mixer->ctrlif)->altsetting[0];
1793 memset(&state, 0, sizeof(state)); 1873 memset(&state, 0, sizeof(state));
@@ -1806,23 +1886,39 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
1806 } 1886 }
1807 } 1887 }
1808 1888
1809 desc = NULL; 1889 p = NULL;
1810 while ((desc = snd_usb_find_csint_desc(hostif->extra, hostif->extralen, desc, UAC_OUTPUT_TERMINAL)) != NULL) { 1890 while ((p = snd_usb_find_csint_desc(hostif->extra, hostif->extralen, p, UAC_OUTPUT_TERMINAL)) != NULL) {
1811 if (desc->bLength < 9) 1891 if (mixer->protocol == UAC_VERSION_1) {
1812 continue; /* invalid descriptor? */ 1892 struct uac_output_terminal_descriptor_v1 *desc = p;
1813 set_bit(desc->bTerminalID, state.unitbitmap); /* mark terminal ID as visited */ 1893
1814 state.oterm.id = desc->bTerminalID; 1894 if (desc->bLength < sizeof(*desc))
1815 state.oterm.type = le16_to_cpu(desc->wTerminalType); 1895 continue; /* invalid descriptor? */
1816 state.oterm.name = desc->iTerminal; 1896 set_bit(desc->bTerminalID, state.unitbitmap); /* mark terminal ID as visited */
1817 err = parse_audio_unit(&state, desc->bSourceID); 1897 state.oterm.id = desc->bTerminalID;
1818 if (err < 0) 1898 state.oterm.type = le16_to_cpu(desc->wTerminalType);
1819 return err; 1899 state.oterm.name = desc->iTerminal;
1900 err = parse_audio_unit(&state, desc->bSourceID);
1901 if (err < 0)
1902 return err;
1903 } else { /* UAC_VERSION_2 */
1904 struct uac2_output_terminal_descriptor *desc = p;
1905
1906 if (desc->bLength < sizeof(*desc))
1907 continue; /* invalid descriptor? */
1908 set_bit(desc->bTerminalID, state.unitbitmap); /* mark terminal ID as visited */
1909 state.oterm.id = desc->bTerminalID;
1910 state.oterm.type = le16_to_cpu(desc->wTerminalType);
1911 state.oterm.name = desc->iTerminal;
1912 err = parse_audio_unit(&state, desc->bSourceID);
1913 if (err < 0)
1914 return err;
1915 }
1820 } 1916 }
1917
1821 return 0; 1918 return 0;
1822} 1919}
1823 1920
1824static void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer, 1921void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer, int unitid)
1825 int unitid)
1826{ 1922{
1827 struct usb_mixer_elem_info *info; 1923 struct usb_mixer_elem_info *info;
1828 1924
@@ -1871,54 +1967,98 @@ static void snd_usb_mixer_proc_read(struct snd_info_entry *entry,
1871 } 1967 }
1872} 1968}
1873 1969
1874static void snd_usb_mixer_memory_change(struct usb_mixer_interface *mixer, 1970static void snd_usb_mixer_interrupt_v2(struct usb_mixer_interface *mixer,
1875 int unitid) 1971 int attribute, int value, int index)
1876{ 1972{
1877 if (!mixer->rc_cfg) 1973 struct usb_mixer_elem_info *info;
1974 __u8 unitid = (index >> 8) & 0xff;
1975 __u8 control = (value >> 8) & 0xff;
1976 __u8 channel = value & 0xff;
1977
1978 if (channel >= MAX_CHANNELS) {
1979 snd_printk(KERN_DEBUG "%s(): bogus channel number %d\n",
1980 __func__, channel);
1878 return; 1981 return;
1879 /* unit ids specific to Extigy/Audigy 2 NX: */ 1982 }
1880 switch (unitid) { 1983
1881 case 0: /* remote control */ 1984 for (info = mixer->id_elems[unitid]; info; info = info->next_id_elem) {
1882 mixer->rc_urb->dev = mixer->chip->dev; 1985 if (info->control != control)
1883 usb_submit_urb(mixer->rc_urb, GFP_ATOMIC); 1986 continue;
1884 break; 1987
1885 case 4: /* digital in jack */ 1988 switch (attribute) {
1886 case 7: /* line in jacks */ 1989 case UAC2_CS_CUR:
1887 case 19: /* speaker out jacks */ 1990 /* invalidate cache, so the value is read from the device */
1888 case 20: /* headphones out jack */ 1991 if (channel)
1889 break; 1992 info->cached &= ~(1 << channel);
1890 /* live24ext: 4 = line-in jack */ 1993 else /* master channel */
1891 case 3: /* hp-out jack (may actuate Mute) */ 1994 info->cached = 0;
1892 if (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) || 1995
1893 mixer->chip->usb_id == USB_ID(0x041e, 0x3048)) 1996 snd_ctl_notify(mixer->chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
1894 snd_usb_mixer_notify_id(mixer, mixer->rc_cfg->mute_mixer_id); 1997 info->elem_id);
1895 break; 1998 break;
1896 default: 1999
1897 snd_printd(KERN_DEBUG "memory change in unknown unit %d\n", unitid); 2000 case UAC2_CS_RANGE:
1898 break; 2001 /* TODO */
2002 break;
2003
2004 case UAC2_CS_MEM:
2005 /* TODO */
2006 break;
2007
2008 default:
2009 snd_printk(KERN_DEBUG "unknown attribute %d in interrupt\n",
2010 attribute);
2011 break;
2012 } /* switch */
1899 } 2013 }
1900} 2014}
1901 2015
1902static void snd_usb_mixer_status_complete(struct urb *urb) 2016static void snd_usb_mixer_interrupt(struct urb *urb)
1903{ 2017{
1904 struct usb_mixer_interface *mixer = urb->context; 2018 struct usb_mixer_interface *mixer = urb->context;
2019 int len = urb->actual_length;
2020
2021 if (urb->status != 0)
2022 goto requeue;
1905 2023
1906 if (urb->status == 0) { 2024 if (mixer->protocol == UAC_VERSION_1) {
1907 u8 *buf = urb->transfer_buffer; 2025 struct uac1_status_word *status;
1908 int i;
1909 2026
1910 for (i = urb->actual_length; i >= 2; buf += 2, i -= 2) { 2027 for (status = urb->transfer_buffer;
2028 len >= sizeof(*status);
2029 len -= sizeof(*status), status++) {
1911 snd_printd(KERN_DEBUG "status interrupt: %02x %02x\n", 2030 snd_printd(KERN_DEBUG "status interrupt: %02x %02x\n",
1912 buf[0], buf[1]); 2031 status->bStatusType,
2032 status->bOriginator);
2033
1913 /* ignore any notifications not from the control interface */ 2034 /* ignore any notifications not from the control interface */
1914 if ((buf[0] & 0x0f) != 0) 2035 if ((status->bStatusType & UAC1_STATUS_TYPE_ORIG_MASK) !=
2036 UAC1_STATUS_TYPE_ORIG_AUDIO_CONTROL_IF)
1915 continue; 2037 continue;
1916 if (!(buf[0] & 0x40)) 2038
1917 snd_usb_mixer_notify_id(mixer, buf[1]); 2039 if (status->bStatusType & UAC1_STATUS_TYPE_MEM_CHANGED)
2040 snd_usb_mixer_rc_memory_change(mixer, status->bOriginator);
1918 else 2041 else
1919 snd_usb_mixer_memory_change(mixer, buf[1]); 2042 snd_usb_mixer_notify_id(mixer, status->bOriginator);
2043 }
2044 } else { /* UAC_VERSION_2 */
2045 struct uac2_interrupt_data_msg *msg;
2046
2047 for (msg = urb->transfer_buffer;
2048 len >= sizeof(*msg);
2049 len -= sizeof(*msg), msg++) {
2050 /* drop vendor specific and endpoint requests */
2051 if ((msg->bInfo & UAC2_INTERRUPT_DATA_MSG_VENDOR) ||
2052 (msg->bInfo & UAC2_INTERRUPT_DATA_MSG_EP))
2053 continue;
2054
2055 snd_usb_mixer_interrupt_v2(mixer, msg->bAttribute,
2056 le16_to_cpu(msg->wValue),
2057 le16_to_cpu(msg->wIndex));
1920 } 2058 }
1921 } 2059 }
2060
2061requeue:
1922 if (urb->status != -ENOENT && urb->status != -ECONNRESET) { 2062 if (urb->status != -ENOENT && urb->status != -ECONNRESET) {
1923 urb->dev = mixer->chip->dev; 2063 urb->dev = mixer->chip->dev;
1924 usb_submit_urb(urb, GFP_ATOMIC); 2064 usb_submit_urb(urb, GFP_ATOMIC);
@@ -1955,301 +2095,11 @@ static int snd_usb_mixer_status_create(struct usb_mixer_interface *mixer)
1955 usb_fill_int_urb(mixer->urb, mixer->chip->dev, 2095 usb_fill_int_urb(mixer->urb, mixer->chip->dev,
1956 usb_rcvintpipe(mixer->chip->dev, epnum), 2096 usb_rcvintpipe(mixer->chip->dev, epnum),
1957 transfer_buffer, buffer_length, 2097 transfer_buffer, buffer_length,
1958 snd_usb_mixer_status_complete, mixer, ep->bInterval); 2098 snd_usb_mixer_interrupt, mixer, ep->bInterval);
1959 usb_submit_urb(mixer->urb, GFP_KERNEL); 2099 usb_submit_urb(mixer->urb, GFP_KERNEL);
1960 return 0; 2100 return 0;
1961} 2101}
1962 2102
1963static void snd_usb_soundblaster_remote_complete(struct urb *urb)
1964{
1965 struct usb_mixer_interface *mixer = urb->context;
1966 const struct rc_config *rc = mixer->rc_cfg;
1967 u32 code;
1968
1969 if (urb->status < 0 || urb->actual_length < rc->min_packet_length)
1970 return;
1971
1972 code = mixer->rc_buffer[rc->offset];
1973 if (rc->length == 2)
1974 code |= mixer->rc_buffer[rc->offset + 1] << 8;
1975
1976 /* the Mute button actually changes the mixer control */
1977 if (code == rc->mute_code)
1978 snd_usb_mixer_notify_id(mixer, rc->mute_mixer_id);
1979 mixer->rc_code = code;
1980 wmb();
1981 wake_up(&mixer->rc_waitq);
1982}
1983
1984static long snd_usb_sbrc_hwdep_read(struct snd_hwdep *hw, char __user *buf,
1985 long count, loff_t *offset)
1986{
1987 struct usb_mixer_interface *mixer = hw->private_data;
1988 int err;
1989 u32 rc_code;
1990
1991 if (count != 1 && count != 4)
1992 return -EINVAL;
1993 err = wait_event_interruptible(mixer->rc_waitq,
1994 (rc_code = xchg(&mixer->rc_code, 0)) != 0);
1995 if (err == 0) {
1996 if (count == 1)
1997 err = put_user(rc_code, buf);
1998 else
1999 err = put_user(rc_code, (u32 __user *)buf);
2000 }
2001 return err < 0 ? err : count;
2002}
2003
2004static unsigned int snd_usb_sbrc_hwdep_poll(struct snd_hwdep *hw, struct file *file,
2005 poll_table *wait)
2006{
2007 struct usb_mixer_interface *mixer = hw->private_data;
2008
2009 poll_wait(file, &mixer->rc_waitq, wait);
2010 return mixer->rc_code ? POLLIN | POLLRDNORM : 0;
2011}
2012
2013static int snd_usb_soundblaster_remote_init(struct usb_mixer_interface *mixer)
2014{
2015 struct snd_hwdep *hwdep;
2016 int err, len, i;
2017
2018 for (i = 0; i < ARRAY_SIZE(rc_configs); ++i)
2019 if (rc_configs[i].usb_id == mixer->chip->usb_id)
2020 break;
2021 if (i >= ARRAY_SIZE(rc_configs))
2022 return 0;
2023 mixer->rc_cfg = &rc_configs[i];
2024
2025 len = mixer->rc_cfg->packet_length;
2026
2027 init_waitqueue_head(&mixer->rc_waitq);
2028 err = snd_hwdep_new(mixer->chip->card, "SB remote control", 0, &hwdep);
2029 if (err < 0)
2030 return err;
2031 snprintf(hwdep->name, sizeof(hwdep->name),
2032 "%s remote control", mixer->chip->card->shortname);
2033 hwdep->iface = SNDRV_HWDEP_IFACE_SB_RC;
2034 hwdep->private_data = mixer;
2035 hwdep->ops.read = snd_usb_sbrc_hwdep_read;
2036 hwdep->ops.poll = snd_usb_sbrc_hwdep_poll;
2037 hwdep->exclusive = 1;
2038
2039 mixer->rc_urb = usb_alloc_urb(0, GFP_KERNEL);
2040 if (!mixer->rc_urb)
2041 return -ENOMEM;
2042 mixer->rc_setup_packet = kmalloc(sizeof(*mixer->rc_setup_packet), GFP_KERNEL);
2043 if (!mixer->rc_setup_packet) {
2044 usb_free_urb(mixer->rc_urb);
2045 mixer->rc_urb = NULL;
2046 return -ENOMEM;
2047 }
2048 mixer->rc_setup_packet->bRequestType =
2049 USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
2050 mixer->rc_setup_packet->bRequest = UAC_GET_MEM;
2051 mixer->rc_setup_packet->wValue = cpu_to_le16(0);
2052 mixer->rc_setup_packet->wIndex = cpu_to_le16(0);
2053 mixer->rc_setup_packet->wLength = cpu_to_le16(len);
2054 usb_fill_control_urb(mixer->rc_urb, mixer->chip->dev,
2055 usb_rcvctrlpipe(mixer->chip->dev, 0),
2056 (u8*)mixer->rc_setup_packet, mixer->rc_buffer, len,
2057 snd_usb_soundblaster_remote_complete, mixer);
2058 return 0;
2059}
2060
2061#define snd_audigy2nx_led_info snd_ctl_boolean_mono_info
2062
2063static int snd_audigy2nx_led_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
2064{
2065 struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
2066 int index = kcontrol->private_value;
2067
2068 ucontrol->value.integer.value[0] = mixer->audigy2nx_leds[index];
2069 return 0;
2070}
2071
2072static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
2073{
2074 struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
2075 int index = kcontrol->private_value;
2076 int value = ucontrol->value.integer.value[0];
2077 int err, changed;
2078
2079 if (value > 1)
2080 return -EINVAL;
2081 changed = value != mixer->audigy2nx_leds[index];
2082 err = snd_usb_ctl_msg(mixer->chip->dev,
2083 usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
2084 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
2085 value, index + 2, NULL, 0, 100);
2086 if (err < 0)
2087 return err;
2088 mixer->audigy2nx_leds[index] = value;
2089 return changed;
2090}
2091
2092static struct snd_kcontrol_new snd_audigy2nx_controls[] = {
2093 {
2094 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2095 .name = "CMSS LED Switch",
2096 .info = snd_audigy2nx_led_info,
2097 .get = snd_audigy2nx_led_get,
2098 .put = snd_audigy2nx_led_put,
2099 .private_value = 0,
2100 },
2101 {
2102 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2103 .name = "Power LED Switch",
2104 .info = snd_audigy2nx_led_info,
2105 .get = snd_audigy2nx_led_get,
2106 .put = snd_audigy2nx_led_put,
2107 .private_value = 1,
2108 },
2109 {
2110 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2111 .name = "Dolby Digital LED Switch",
2112 .info = snd_audigy2nx_led_info,
2113 .get = snd_audigy2nx_led_get,
2114 .put = snd_audigy2nx_led_put,
2115 .private_value = 2,
2116 },
2117};
2118
2119static int snd_audigy2nx_controls_create(struct usb_mixer_interface *mixer)
2120{
2121 int i, err;
2122
2123 for (i = 0; i < ARRAY_SIZE(snd_audigy2nx_controls); ++i) {
2124 if (i > 1 && /* Live24ext has 2 LEDs only */
2125 (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
2126 mixer->chip->usb_id == USB_ID(0x041e, 0x3048)))
2127 break;
2128 err = snd_ctl_add(mixer->chip->card,
2129 snd_ctl_new1(&snd_audigy2nx_controls[i], mixer));
2130 if (err < 0)
2131 return err;
2132 }
2133 mixer->audigy2nx_leds[1] = 1; /* Power LED is on by default */
2134 return 0;
2135}
2136
2137static void snd_audigy2nx_proc_read(struct snd_info_entry *entry,
2138 struct snd_info_buffer *buffer)
2139{
2140 static const struct sb_jack {
2141 int unitid;
2142 const char *name;
2143 } jacks_audigy2nx[] = {
2144 {4, "dig in "},
2145 {7, "line in"},
2146 {19, "spk out"},
2147 {20, "hph out"},
2148 {-1, NULL}
2149 }, jacks_live24ext[] = {
2150 {4, "line in"}, /* &1=Line, &2=Mic*/
2151 {3, "hph out"}, /* headphones */
2152 {0, "RC "}, /* last command, 6 bytes see rc_config above */
2153 {-1, NULL}
2154 };
2155 const struct sb_jack *jacks;
2156 struct usb_mixer_interface *mixer = entry->private_data;
2157 int i, err;
2158 u8 buf[3];
2159
2160 snd_iprintf(buffer, "%s jacks\n\n", mixer->chip->card->shortname);
2161 if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020))
2162 jacks = jacks_audigy2nx;
2163 else if (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
2164 mixer->chip->usb_id == USB_ID(0x041e, 0x3048))
2165 jacks = jacks_live24ext;
2166 else
2167 return;
2168
2169 for (i = 0; jacks[i].name; ++i) {
2170 snd_iprintf(buffer, "%s: ", jacks[i].name);
2171 err = snd_usb_ctl_msg(mixer->chip->dev,
2172 usb_rcvctrlpipe(mixer->chip->dev, 0),
2173 UAC_GET_MEM, USB_DIR_IN | USB_TYPE_CLASS |
2174 USB_RECIP_INTERFACE, 0,
2175 jacks[i].unitid << 8, buf, 3, 100);
2176 if (err == 3 && (buf[0] == 3 || buf[0] == 6))
2177 snd_iprintf(buffer, "%02x %02x\n", buf[1], buf[2]);
2178 else
2179 snd_iprintf(buffer, "?\n");
2180 }
2181}
2182
2183static int snd_xonar_u1_switch_get(struct snd_kcontrol *kcontrol,
2184 struct snd_ctl_elem_value *ucontrol)
2185{
2186 struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
2187
2188 ucontrol->value.integer.value[0] = !!(mixer->xonar_u1_status & 0x02);
2189 return 0;
2190}
2191
2192static int snd_xonar_u1_switch_put(struct snd_kcontrol *kcontrol,
2193 struct snd_ctl_elem_value *ucontrol)
2194{
2195 struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
2196 u8 old_status, new_status;
2197 int err, changed;
2198
2199 old_status = mixer->xonar_u1_status;
2200 if (ucontrol->value.integer.value[0])
2201 new_status = old_status | 0x02;
2202 else
2203 new_status = old_status & ~0x02;
2204 changed = new_status != old_status;
2205 err = snd_usb_ctl_msg(mixer->chip->dev,
2206 usb_sndctrlpipe(mixer->chip->dev, 0), 0x08,
2207 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
2208 50, 0, &new_status, 1, 100);
2209 if (err < 0)
2210 return err;
2211 mixer->xonar_u1_status = new_status;
2212 return changed;
2213}
2214
2215static struct snd_kcontrol_new snd_xonar_u1_output_switch = {
2216 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2217 .name = "Digital Playback Switch",
2218 .info = snd_ctl_boolean_mono_info,
2219 .get = snd_xonar_u1_switch_get,
2220 .put = snd_xonar_u1_switch_put,
2221};
2222
2223static int snd_xonar_u1_controls_create(struct usb_mixer_interface *mixer)
2224{
2225 int err;
2226
2227 err = snd_ctl_add(mixer->chip->card,
2228 snd_ctl_new1(&snd_xonar_u1_output_switch, mixer));
2229 if (err < 0)
2230 return err;
2231 mixer->xonar_u1_status = 0x05;
2232 return 0;
2233}
2234
2235void snd_emuusb_set_samplerate(struct snd_usb_audio *chip,
2236 unsigned char samplerate_id)
2237{
2238 struct usb_mixer_interface *mixer;
2239 struct usb_mixer_elem_info *cval;
2240 int unitid = 12; /* SamleRate ExtensionUnit ID */
2241
2242 list_for_each_entry(mixer, &chip->mixer_list, list) {
2243 cval = mixer->id_elems[unitid];
2244 if (cval) {
2245 set_cur_ctl_value(cval, cval->control << 8,
2246 samplerate_id);
2247 snd_usb_mixer_notify_id(mixer, unitid);
2248 }
2249 break;
2250 }
2251}
2252
2253int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif, 2103int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
2254 int ignore_error) 2104 int ignore_error)
2255{ 2105{
@@ -2259,7 +2109,7 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
2259 struct usb_mixer_interface *mixer; 2109 struct usb_mixer_interface *mixer;
2260 struct snd_info_entry *entry; 2110 struct snd_info_entry *entry;
2261 struct usb_host_interface *host_iface; 2111 struct usb_host_interface *host_iface;
2262 int err, protocol; 2112 int err;
2263 2113
2264 strcpy(chip->card->mixername, "USB Mixer"); 2114 strcpy(chip->card->mixername, "USB Mixer");
2265 2115
@@ -2277,38 +2127,13 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
2277 } 2127 }
2278 2128
2279 host_iface = &usb_ifnum_to_if(chip->dev, ctrlif)->altsetting[0]; 2129 host_iface = &usb_ifnum_to_if(chip->dev, ctrlif)->altsetting[0];
2280 protocol = host_iface->desc.bInterfaceProtocol; 2130 mixer->protocol = get_iface_desc(host_iface)->bInterfaceProtocol;
2281
2282 /* FIXME! */
2283 if (protocol != UAC_VERSION_1) {
2284 snd_printk(KERN_WARNING "mixer interface protocol 0x%02x not yet supported\n",
2285 protocol);
2286 return 0;
2287 }
2288 2131
2289 if ((err = snd_usb_mixer_controls(mixer)) < 0 || 2132 if ((err = snd_usb_mixer_controls(mixer)) < 0 ||
2290 (err = snd_usb_mixer_status_create(mixer)) < 0) 2133 (err = snd_usb_mixer_status_create(mixer)) < 0)
2291 goto _error; 2134 goto _error;
2292 2135
2293 if ((err = snd_usb_soundblaster_remote_init(mixer)) < 0) 2136 snd_usb_mixer_apply_create_quirk(mixer);
2294 goto _error;
2295
2296 if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020) ||
2297 mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
2298 mixer->chip->usb_id == USB_ID(0x041e, 0x3048)) {
2299 if ((err = snd_audigy2nx_controls_create(mixer)) < 0)
2300 goto _error;
2301 if (!snd_card_proc_new(chip->card, "audigy2nx", &entry))
2302 snd_info_set_text_ops(entry, mixer,
2303 snd_audigy2nx_proc_read);
2304 }
2305
2306 if (mixer->chip->usb_id == USB_ID(0x0b05, 0x1739) ||
2307 mixer->chip->usb_id == USB_ID(0x0b05, 0x1743)) {
2308 err = snd_xonar_u1_controls_create(mixer);
2309 if (err < 0)
2310 goto _error;
2311 }
2312 2137
2313 err = snd_device_new(chip->card, SNDRV_DEV_LOWLEVEL, mixer, &dev_ops); 2138 err = snd_device_new(chip->card, SNDRV_DEV_LOWLEVEL, mixer, &dev_ops);
2314 if (err < 0) 2139 if (err < 0)
@@ -2329,7 +2154,7 @@ _error:
2329void snd_usb_mixer_disconnect(struct list_head *p) 2154void snd_usb_mixer_disconnect(struct list_head *p)
2330{ 2155{
2331 struct usb_mixer_interface *mixer; 2156 struct usb_mixer_interface *mixer;
2332 2157
2333 mixer = list_entry(p, struct usb_mixer_interface, list); 2158 mixer = list_entry(p, struct usb_mixer_interface, list);
2334 usb_kill_urb(mixer->urb); 2159 usb_kill_urb(mixer->urb);
2335 usb_kill_urb(mixer->rc_urb); 2160 usb_kill_urb(mixer->rc_urb);
diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h
new file mode 100644
index 000000000000..130123854a6c
--- /dev/null
+++ b/sound/usb/mixer.h
@@ -0,0 +1,55 @@
1#ifndef __USBMIXER_H
2#define __USBMIXER_H
3
4struct usb_mixer_interface {
5 struct snd_usb_audio *chip;
6 unsigned int ctrlif;
7 struct list_head list;
8 unsigned int ignore_ctl_error;
9 struct urb *urb;
10 /* array[MAX_ID_ELEMS], indexed by unit id */
11 struct usb_mixer_elem_info **id_elems;
12
13 /* the usb audio specification version this interface complies to */
14 int protocol;
15
16 /* Sound Blaster remote control stuff */
17 const struct rc_config *rc_cfg;
18 u32 rc_code;
19 wait_queue_head_t rc_waitq;
20 struct urb *rc_urb;
21 struct usb_ctrlrequest *rc_setup_packet;
22 u8 rc_buffer[6];
23
24 u8 audigy2nx_leds[3];
25 u8 xonar_u1_status;
26};
27
28#define MAX_CHANNELS 10 /* max logical channels */
29
30struct usb_mixer_elem_info {
31 struct usb_mixer_interface *mixer;
32 struct usb_mixer_elem_info *next_id_elem; /* list of controls with same id */
33 struct snd_ctl_elem_id *elem_id;
34 unsigned int id;
35 unsigned int control; /* CS or ICN (high byte) */
36 unsigned int cmask; /* channel mask bitmap: 0 = master */
37 int channels;
38 int val_type;
39 int min, max, res;
40 int dBmin, dBmax;
41 int cached;
42 int cache_val[MAX_CHANNELS];
43 u8 initialized;
44};
45
46int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
47 int ignore_error);
48void snd_usb_mixer_disconnect(struct list_head *p);
49
50void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer, int unitid);
51
52int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
53 int request, int validx, int value_set);
54
55#endif /* __USBMIXER_H */
diff --git a/sound/usb/usbmixer_maps.c b/sound/usb/mixer_maps.c
index 79e903a60862..d93fc89beba8 100644
--- a/sound/usb/usbmixer_maps.c
+++ b/sound/usb/mixer_maps.c
@@ -85,8 +85,8 @@ static struct usbmix_name_map extigy_map[] = {
85 /* 16: MU (w/o controls) */ 85 /* 16: MU (w/o controls) */
86 { 17, NULL, 1 }, /* DISABLED: PU-switch (any effect?) */ 86 { 17, NULL, 1 }, /* DISABLED: PU-switch (any effect?) */
87 { 17, "Channel Routing", 2 }, /* PU: mode select */ 87 { 17, "Channel Routing", 2 }, /* PU: mode select */
88 { 18, "Tone Control - Bass", USB_FEATURE_BASS }, /* FU */ 88 { 18, "Tone Control - Bass", UAC_BASS_CONTROL }, /* FU */
89 { 18, "Tone Control - Treble", USB_FEATURE_TREBLE }, /* FU */ 89 { 18, "Tone Control - Treble", UAC_TREBLE_CONTROL }, /* FU */
90 { 18, "Master Playback" }, /* FU; others */ 90 { 18, "Master Playback" }, /* FU; others */
91 /* 19: OT speaker */ 91 /* 19: OT speaker */
92 /* 20: OT headphone */ 92 /* 20: OT headphone */
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
new file mode 100644
index 000000000000..e7df1e5e3f2e
--- /dev/null
+++ b/sound/usb/mixer_quirks.c
@@ -0,0 +1,412 @@
1/*
2 * USB Audio Driver for ALSA
3 *
4 * Quirks and vendor-specific extensions for mixer interfaces
5 *
6 * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
7 *
8 * Many codes borrowed from audio.c by
9 * Alan Cox (alan@lxorguk.ukuu.org.uk)
10 * Thomas Sailer (sailer@ife.ee.ethz.ch)
11 *
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 */
27
28#include <linux/init.h>
29#include <linux/slab.h>
30#include <linux/usb.h>
31#include <linux/usb/audio.h>
32
33#include <sound/core.h>
34#include <sound/control.h>
35#include <sound/hwdep.h>
36#include <sound/info.h>
37
38#include "usbaudio.h"
39#include "mixer.h"
40#include "mixer_quirks.h"
41#include "helper.h"
42
43/*
44 * Sound Blaster remote control configuration
45 *
46 * format of remote control data:
47 * Extigy: xx 00
48 * Audigy 2 NX: 06 80 xx 00 00 00
49 * Live! 24-bit: 06 80 xx yy 22 83
50 */
51static const struct rc_config {
52 u32 usb_id;
53 u8 offset;
54 u8 length;
55 u8 packet_length;
56 u8 min_packet_length; /* minimum accepted length of the URB result */
57 u8 mute_mixer_id;
58 u32 mute_code;
59} rc_configs[] = {
60 { USB_ID(0x041e, 0x3000), 0, 1, 2, 1, 18, 0x0013 }, /* Extigy */
61 { USB_ID(0x041e, 0x3020), 2, 1, 6, 6, 18, 0x0013 }, /* Audigy 2 NX */
62 { USB_ID(0x041e, 0x3040), 2, 2, 6, 6, 2, 0x6e91 }, /* Live! 24-bit */
63 { USB_ID(0x041e, 0x3048), 2, 2, 6, 6, 2, 0x6e91 }, /* Toshiba SB0500 */
64};
65
66static void snd_usb_soundblaster_remote_complete(struct urb *urb)
67{
68 struct usb_mixer_interface *mixer = urb->context;
69 const struct rc_config *rc = mixer->rc_cfg;
70 u32 code;
71
72 if (urb->status < 0 || urb->actual_length < rc->min_packet_length)
73 return;
74
75 code = mixer->rc_buffer[rc->offset];
76 if (rc->length == 2)
77 code |= mixer->rc_buffer[rc->offset + 1] << 8;
78
79 /* the Mute button actually changes the mixer control */
80 if (code == rc->mute_code)
81 snd_usb_mixer_notify_id(mixer, rc->mute_mixer_id);
82 mixer->rc_code = code;
83 wmb();
84 wake_up(&mixer->rc_waitq);
85}
86
87static long snd_usb_sbrc_hwdep_read(struct snd_hwdep *hw, char __user *buf,
88 long count, loff_t *offset)
89{
90 struct usb_mixer_interface *mixer = hw->private_data;
91 int err;
92 u32 rc_code;
93
94 if (count != 1 && count != 4)
95 return -EINVAL;
96 err = wait_event_interruptible(mixer->rc_waitq,
97 (rc_code = xchg(&mixer->rc_code, 0)) != 0);
98 if (err == 0) {
99 if (count == 1)
100 err = put_user(rc_code, buf);
101 else
102 err = put_user(rc_code, (u32 __user *)buf);
103 }
104 return err < 0 ? err : count;
105}
106
107static unsigned int snd_usb_sbrc_hwdep_poll(struct snd_hwdep *hw, struct file *file,
108 poll_table *wait)
109{
110 struct usb_mixer_interface *mixer = hw->private_data;
111
112 poll_wait(file, &mixer->rc_waitq, wait);
113 return mixer->rc_code ? POLLIN | POLLRDNORM : 0;
114}
115
116static int snd_usb_soundblaster_remote_init(struct usb_mixer_interface *mixer)
117{
118 struct snd_hwdep *hwdep;
119 int err, len, i;
120
121 for (i = 0; i < ARRAY_SIZE(rc_configs); ++i)
122 if (rc_configs[i].usb_id == mixer->chip->usb_id)
123 break;
124 if (i >= ARRAY_SIZE(rc_configs))
125 return 0;
126 mixer->rc_cfg = &rc_configs[i];
127
128 len = mixer->rc_cfg->packet_length;
129
130 init_waitqueue_head(&mixer->rc_waitq);
131 err = snd_hwdep_new(mixer->chip->card, "SB remote control", 0, &hwdep);
132 if (err < 0)
133 return err;
134 snprintf(hwdep->name, sizeof(hwdep->name),
135 "%s remote control", mixer->chip->card->shortname);
136 hwdep->iface = SNDRV_HWDEP_IFACE_SB_RC;
137 hwdep->private_data = mixer;
138 hwdep->ops.read = snd_usb_sbrc_hwdep_read;
139 hwdep->ops.poll = snd_usb_sbrc_hwdep_poll;
140 hwdep->exclusive = 1;
141
142 mixer->rc_urb = usb_alloc_urb(0, GFP_KERNEL);
143 if (!mixer->rc_urb)
144 return -ENOMEM;
145 mixer->rc_setup_packet = kmalloc(sizeof(*mixer->rc_setup_packet), GFP_KERNEL);
146 if (!mixer->rc_setup_packet) {
147 usb_free_urb(mixer->rc_urb);
148 mixer->rc_urb = NULL;
149 return -ENOMEM;
150 }
151 mixer->rc_setup_packet->bRequestType =
152 USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
153 mixer->rc_setup_packet->bRequest = UAC_GET_MEM;
154 mixer->rc_setup_packet->wValue = cpu_to_le16(0);
155 mixer->rc_setup_packet->wIndex = cpu_to_le16(0);
156 mixer->rc_setup_packet->wLength = cpu_to_le16(len);
157 usb_fill_control_urb(mixer->rc_urb, mixer->chip->dev,
158 usb_rcvctrlpipe(mixer->chip->dev, 0),
159 (u8*)mixer->rc_setup_packet, mixer->rc_buffer, len,
160 snd_usb_soundblaster_remote_complete, mixer);
161 return 0;
162}
163
164#define snd_audigy2nx_led_info snd_ctl_boolean_mono_info
165
166static int snd_audigy2nx_led_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
167{
168 struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
169 int index = kcontrol->private_value;
170
171 ucontrol->value.integer.value[0] = mixer->audigy2nx_leds[index];
172 return 0;
173}
174
175static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
176{
177 struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
178 int index = kcontrol->private_value;
179 int value = ucontrol->value.integer.value[0];
180 int err, changed;
181
182 if (value > 1)
183 return -EINVAL;
184 changed = value != mixer->audigy2nx_leds[index];
185 err = snd_usb_ctl_msg(mixer->chip->dev,
186 usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
187 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
188 value, index + 2, NULL, 0, 100);
189 if (err < 0)
190 return err;
191 mixer->audigy2nx_leds[index] = value;
192 return changed;
193}
194
195static struct snd_kcontrol_new snd_audigy2nx_controls[] = {
196 {
197 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
198 .name = "CMSS LED Switch",
199 .info = snd_audigy2nx_led_info,
200 .get = snd_audigy2nx_led_get,
201 .put = snd_audigy2nx_led_put,
202 .private_value = 0,
203 },
204 {
205 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
206 .name = "Power LED Switch",
207 .info = snd_audigy2nx_led_info,
208 .get = snd_audigy2nx_led_get,
209 .put = snd_audigy2nx_led_put,
210 .private_value = 1,
211 },
212 {
213 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
214 .name = "Dolby Digital LED Switch",
215 .info = snd_audigy2nx_led_info,
216 .get = snd_audigy2nx_led_get,
217 .put = snd_audigy2nx_led_put,
218 .private_value = 2,
219 },
220};
221
222static int snd_audigy2nx_controls_create(struct usb_mixer_interface *mixer)
223{
224 int i, err;
225
226 for (i = 0; i < ARRAY_SIZE(snd_audigy2nx_controls); ++i) {
227 if (i > 1 && /* Live24ext has 2 LEDs only */
228 (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
229 mixer->chip->usb_id == USB_ID(0x041e, 0x3048)))
230 break;
231 err = snd_ctl_add(mixer->chip->card,
232 snd_ctl_new1(&snd_audigy2nx_controls[i], mixer));
233 if (err < 0)
234 return err;
235 }
236 mixer->audigy2nx_leds[1] = 1; /* Power LED is on by default */
237 return 0;
238}
239
240static void snd_audigy2nx_proc_read(struct snd_info_entry *entry,
241 struct snd_info_buffer *buffer)
242{
243 static const struct sb_jack {
244 int unitid;
245 const char *name;
246 } jacks_audigy2nx[] = {
247 {4, "dig in "},
248 {7, "line in"},
249 {19, "spk out"},
250 {20, "hph out"},
251 {-1, NULL}
252 }, jacks_live24ext[] = {
253 {4, "line in"}, /* &1=Line, &2=Mic*/
254 {3, "hph out"}, /* headphones */
255 {0, "RC "}, /* last command, 6 bytes see rc_config above */
256 {-1, NULL}
257 };
258 const struct sb_jack *jacks;
259 struct usb_mixer_interface *mixer = entry->private_data;
260 int i, err;
261 u8 buf[3];
262
263 snd_iprintf(buffer, "%s jacks\n\n", mixer->chip->card->shortname);
264 if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020))
265 jacks = jacks_audigy2nx;
266 else if (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
267 mixer->chip->usb_id == USB_ID(0x041e, 0x3048))
268 jacks = jacks_live24ext;
269 else
270 return;
271
272 for (i = 0; jacks[i].name; ++i) {
273 snd_iprintf(buffer, "%s: ", jacks[i].name);
274 err = snd_usb_ctl_msg(mixer->chip->dev,
275 usb_rcvctrlpipe(mixer->chip->dev, 0),
276 UAC_GET_MEM, USB_DIR_IN | USB_TYPE_CLASS |
277 USB_RECIP_INTERFACE, 0,
278 jacks[i].unitid << 8, buf, 3, 100);
279 if (err == 3 && (buf[0] == 3 || buf[0] == 6))
280 snd_iprintf(buffer, "%02x %02x\n", buf[1], buf[2]);
281 else
282 snd_iprintf(buffer, "?\n");
283 }
284}
285
286static int snd_xonar_u1_switch_get(struct snd_kcontrol *kcontrol,
287 struct snd_ctl_elem_value *ucontrol)
288{
289 struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
290
291 ucontrol->value.integer.value[0] = !!(mixer->xonar_u1_status & 0x02);
292 return 0;
293}
294
295static int snd_xonar_u1_switch_put(struct snd_kcontrol *kcontrol,
296 struct snd_ctl_elem_value *ucontrol)
297{
298 struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
299 u8 old_status, new_status;
300 int err, changed;
301
302 old_status = mixer->xonar_u1_status;
303 if (ucontrol->value.integer.value[0])
304 new_status = old_status | 0x02;
305 else
306 new_status = old_status & ~0x02;
307 changed = new_status != old_status;
308 err = snd_usb_ctl_msg(mixer->chip->dev,
309 usb_sndctrlpipe(mixer->chip->dev, 0), 0x08,
310 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
311 50, 0, &new_status, 1, 100);
312 if (err < 0)
313 return err;
314 mixer->xonar_u1_status = new_status;
315 return changed;
316}
317
318static struct snd_kcontrol_new snd_xonar_u1_output_switch = {
319 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
320 .name = "Digital Playback Switch",
321 .info = snd_ctl_boolean_mono_info,
322 .get = snd_xonar_u1_switch_get,
323 .put = snd_xonar_u1_switch_put,
324};
325
326static int snd_xonar_u1_controls_create(struct usb_mixer_interface *mixer)
327{
328 int err;
329
330 err = snd_ctl_add(mixer->chip->card,
331 snd_ctl_new1(&snd_xonar_u1_output_switch, mixer));
332 if (err < 0)
333 return err;
334 mixer->xonar_u1_status = 0x05;
335 return 0;
336}
337
338void snd_emuusb_set_samplerate(struct snd_usb_audio *chip,
339 unsigned char samplerate_id)
340{
341 struct usb_mixer_interface *mixer;
342 struct usb_mixer_elem_info *cval;
343 int unitid = 12; /* SamleRate ExtensionUnit ID */
344
345 list_for_each_entry(mixer, &chip->mixer_list, list) {
346 cval = mixer->id_elems[unitid];
347 if (cval) {
348 snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR,
349 cval->control << 8,
350 samplerate_id);
351 snd_usb_mixer_notify_id(mixer, unitid);
352 }
353 break;
354 }
355}
356
357int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
358{
359 int err;
360 struct snd_info_entry *entry;
361
362 if ((err = snd_usb_soundblaster_remote_init(mixer)) < 0)
363 return err;
364
365 if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020) ||
366 mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
367 mixer->chip->usb_id == USB_ID(0x041e, 0x3048)) {
368 if ((err = snd_audigy2nx_controls_create(mixer)) < 0)
369 return err;
370 if (!snd_card_proc_new(mixer->chip->card, "audigy2nx", &entry))
371 snd_info_set_text_ops(entry, mixer,
372 snd_audigy2nx_proc_read);
373 }
374
375 if (mixer->chip->usb_id == USB_ID(0x0b05, 0x1739) ||
376 mixer->chip->usb_id == USB_ID(0x0b05, 0x1743)) {
377 err = snd_xonar_u1_controls_create(mixer);
378 if (err < 0)
379 return err;
380 }
381
382 return 0;
383}
384
385void snd_usb_mixer_rc_memory_change(struct usb_mixer_interface *mixer,
386 int unitid)
387{
388 if (!mixer->rc_cfg)
389 return;
390 /* unit ids specific to Extigy/Audigy 2 NX: */
391 switch (unitid) {
392 case 0: /* remote control */
393 mixer->rc_urb->dev = mixer->chip->dev;
394 usb_submit_urb(mixer->rc_urb, GFP_ATOMIC);
395 break;
396 case 4: /* digital in jack */
397 case 7: /* line in jacks */
398 case 19: /* speaker out jacks */
399 case 20: /* headphones out jack */
400 break;
401 /* live24ext: 4 = line-in jack */
402 case 3: /* hp-out jack (may actuate Mute) */
403 if (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
404 mixer->chip->usb_id == USB_ID(0x041e, 0x3048))
405 snd_usb_mixer_notify_id(mixer, mixer->rc_cfg->mute_mixer_id);
406 break;
407 default:
408 snd_printd(KERN_DEBUG "memory change in unknown unit %d\n", unitid);
409 break;
410 }
411}
412
diff --git a/sound/usb/mixer_quirks.h b/sound/usb/mixer_quirks.h
new file mode 100644
index 000000000000..bdbfab093816
--- /dev/null
+++ b/sound/usb/mixer_quirks.h
@@ -0,0 +1,13 @@
1#ifndef SND_USB_MIXER_QUIRKS_H
2#define SND_USB_MIXER_QUIRKS_H
3
4int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer);
5
6void snd_emuusb_set_samplerate(struct snd_usb_audio *chip,
7 unsigned char samplerate_id);
8
9void snd_usb_mixer_rc_memory_change(struct usb_mixer_interface *mixer,
10 int unitid);
11
12#endif /* SND_USB_MIXER_QUIRKS_H */
13
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
new file mode 100644
index 000000000000..056587de7be4
--- /dev/null
+++ b/sound/usb/pcm.c
@@ -0,0 +1,958 @@
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 as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15 */
16
17#include <linux/init.h>
18#include <linux/slab.h>
19#include <linux/usb.h>
20#include <linux/usb/audio.h>
21#include <linux/usb/audio-v2.h>
22
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26
27#include "usbaudio.h"
28#include "card.h"
29#include "quirks.h"
30#include "debug.h"
31#include "urb.h"
32#include "helper.h"
33#include "pcm.h"
34
35/*
36 * return the current pcm pointer. just based on the hwptr_done value.
37 */
38static snd_pcm_uframes_t snd_usb_pcm_pointer(struct snd_pcm_substream *substream)
39{
40 struct snd_usb_substream *subs;
41 unsigned int hwptr_done;
42
43 subs = (struct snd_usb_substream *)substream->runtime->private_data;
44 spin_lock(&subs->lock);
45 hwptr_done = subs->hwptr_done;
46 spin_unlock(&subs->lock);
47 return hwptr_done / (substream->runtime->frame_bits >> 3);
48}
49
50/*
51 * find a matching audio format
52 */
53static struct audioformat *find_format(struct snd_usb_substream *subs, unsigned int format,
54 unsigned int rate, unsigned int channels)
55{
56 struct list_head *p;
57 struct audioformat *found = NULL;
58 int cur_attr = 0, attr;
59
60 list_for_each(p, &subs->fmt_list) {
61 struct audioformat *fp;
62 fp = list_entry(p, struct audioformat, list);
63 if (!(fp->formats & (1uLL << format)))
64 continue;
65 if (fp->channels != channels)
66 continue;
67 if (rate < fp->rate_min || rate > fp->rate_max)
68 continue;
69 if (! (fp->rates & SNDRV_PCM_RATE_CONTINUOUS)) {
70 unsigned int i;
71 for (i = 0; i < fp->nr_rates; i++)
72 if (fp->rate_table[i] == rate)
73 break;
74 if (i >= fp->nr_rates)
75 continue;
76 }
77 attr = fp->ep_attr & USB_ENDPOINT_SYNCTYPE;
78 if (! found) {
79 found = fp;
80 cur_attr = attr;
81 continue;
82 }
83 /* avoid async out and adaptive in if the other method
84 * supports the same format.
85 * this is a workaround for the case like
86 * M-audio audiophile USB.
87 */
88 if (attr != cur_attr) {
89 if ((attr == USB_ENDPOINT_SYNC_ASYNC &&
90 subs->direction == SNDRV_PCM_STREAM_PLAYBACK) ||
91 (attr == USB_ENDPOINT_SYNC_ADAPTIVE &&
92 subs->direction == SNDRV_PCM_STREAM_CAPTURE))
93 continue;
94 if ((cur_attr == USB_ENDPOINT_SYNC_ASYNC &&
95 subs->direction == SNDRV_PCM_STREAM_PLAYBACK) ||
96 (cur_attr == USB_ENDPOINT_SYNC_ADAPTIVE &&
97 subs->direction == SNDRV_PCM_STREAM_CAPTURE)) {
98 found = fp;
99 cur_attr = attr;
100 continue;
101 }
102 }
103 /* find the format with the largest max. packet size */
104 if (fp->maxpacksize > found->maxpacksize) {
105 found = fp;
106 cur_attr = attr;
107 }
108 }
109 return found;
110}
111
112static int init_pitch_v1(struct snd_usb_audio *chip, int iface,
113 struct usb_host_interface *alts,
114 struct audioformat *fmt)
115{
116 struct usb_device *dev = chip->dev;
117 unsigned int ep;
118 unsigned char data[1];
119 int err;
120
121 ep = get_endpoint(alts, 0)->bEndpointAddress;
122
123 data[0] = 1;
124 if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR,
125 USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT,
126 UAC_EP_CS_ATTR_PITCH_CONTROL << 8, ep,
127 data, sizeof(data), 1000)) < 0) {
128 snd_printk(KERN_ERR "%d:%d:%d: cannot set enable PITCH\n",
129 dev->devnum, iface, ep);
130 return err;
131 }
132
133 return 0;
134}
135
136static int init_pitch_v2(struct snd_usb_audio *chip, int iface,
137 struct usb_host_interface *alts,
138 struct audioformat *fmt)
139{
140 struct usb_device *dev = chip->dev;
141 unsigned char data[1];
142 unsigned int ep;
143 int err;
144
145 ep = get_endpoint(alts, 0)->bEndpointAddress;
146
147 data[0] = 1;
148 if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC2_CS_CUR,
149 USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_OUT,
150 UAC2_EP_CS_PITCH << 8, 0,
151 data, sizeof(data), 1000)) < 0) {
152 snd_printk(KERN_ERR "%d:%d:%d: cannot set enable PITCH (v2)\n",
153 dev->devnum, iface, fmt->altsetting);
154 return err;
155 }
156
157 return 0;
158}
159
160/*
161 * initialize the pitch control and sample rate
162 */
163int snd_usb_init_pitch(struct snd_usb_audio *chip, int iface,
164 struct usb_host_interface *alts,
165 struct audioformat *fmt)
166{
167 struct usb_interface_descriptor *altsd = get_iface_desc(alts);
168
169 /* if endpoint doesn't have pitch control, bail out */
170 if (!(fmt->attributes & UAC_EP_CS_ATTR_PITCH_CONTROL))
171 return 0;
172
173 switch (altsd->bInterfaceProtocol) {
174 case UAC_VERSION_1:
175 return init_pitch_v1(chip, iface, alts, fmt);
176
177 case UAC_VERSION_2:
178 return init_pitch_v2(chip, iface, alts, fmt);
179 }
180
181 return -EINVAL;
182}
183
184static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface,
185 struct usb_host_interface *alts,
186 struct audioformat *fmt, int rate)
187{
188 struct usb_device *dev = chip->dev;
189 unsigned int ep;
190 unsigned char data[3];
191 int err, crate;
192
193 ep = get_endpoint(alts, 0)->bEndpointAddress;
194 /* if endpoint doesn't have sampling rate control, bail out */
195 if (!(fmt->attributes & UAC_EP_CS_ATTR_SAMPLE_RATE)) {
196 snd_printk(KERN_WARNING "%d:%d:%d: endpoint lacks sample rate attribute bit, cannot set.\n",
197 dev->devnum, iface, fmt->altsetting);
198 return 0;
199 }
200
201 data[0] = rate;
202 data[1] = rate >> 8;
203 data[2] = rate >> 16;
204 if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR,
205 USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT,
206 UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep,
207 data, sizeof(data), 1000)) < 0) {
208 snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d to ep %#x\n",
209 dev->devnum, iface, fmt->altsetting, rate, ep);
210 return err;
211 }
212 if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC_GET_CUR,
213 USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_IN,
214 UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep,
215 data, sizeof(data), 1000)) < 0) {
216 snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq at ep %#x\n",
217 dev->devnum, iface, fmt->altsetting, ep);
218 return 0; /* some devices don't support reading */
219 }
220 crate = data[0] | (data[1] << 8) | (data[2] << 16);
221 if (crate != rate) {
222 snd_printd(KERN_WARNING "current rate %d is different from the runtime rate %d\n", crate, rate);
223 // runtime->rate = crate;
224 }
225
226 return 0;
227}
228
229static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface,
230 struct usb_host_interface *alts,
231 struct audioformat *fmt, int rate)
232{
233 struct usb_device *dev = chip->dev;
234 unsigned char data[4];
235 int err, crate;
236
237 data[0] = rate;
238 data[1] = rate >> 8;
239 data[2] = rate >> 16;
240 data[3] = rate >> 24;
241 if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC2_CS_CUR,
242 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
243 UAC2_CS_CONTROL_SAM_FREQ << 8, chip->clock_id << 8,
244 data, sizeof(data), 1000)) < 0) {
245 snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d (v2)\n",
246 dev->devnum, iface, fmt->altsetting, rate);
247 return err;
248 }
249 if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR,
250 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
251 UAC2_CS_CONTROL_SAM_FREQ << 8, chip->clock_id << 8,
252 data, sizeof(data), 1000)) < 0) {
253 snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq (v2)\n",
254 dev->devnum, iface, fmt->altsetting);
255 return err;
256 }
257 crate = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
258 if (crate != rate)
259 snd_printd(KERN_WARNING "current rate %d is different from the runtime rate %d\n", crate, rate);
260
261 return 0;
262}
263
264int snd_usb_init_sample_rate(struct snd_usb_audio *chip, int iface,
265 struct usb_host_interface *alts,
266 struct audioformat *fmt, int rate)
267{
268 struct usb_interface_descriptor *altsd = get_iface_desc(alts);
269
270 switch (altsd->bInterfaceProtocol) {
271 case UAC_VERSION_1:
272 return set_sample_rate_v1(chip, iface, alts, fmt, rate);
273
274 case UAC_VERSION_2:
275 return set_sample_rate_v2(chip, iface, alts, fmt, rate);
276 }
277
278 return -EINVAL;
279}
280
281/*
282 * find a matching format and set up the interface
283 */
284static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
285{
286 struct usb_device *dev = subs->dev;
287 struct usb_host_interface *alts;
288 struct usb_interface_descriptor *altsd;
289 struct usb_interface *iface;
290 unsigned int ep, attr;
291 int is_playback = subs->direction == SNDRV_PCM_STREAM_PLAYBACK;
292 int err;
293
294 iface = usb_ifnum_to_if(dev, fmt->iface);
295 if (WARN_ON(!iface))
296 return -EINVAL;
297 alts = &iface->altsetting[fmt->altset_idx];
298 altsd = get_iface_desc(alts);
299 if (WARN_ON(altsd->bAlternateSetting != fmt->altsetting))
300 return -EINVAL;
301
302 if (fmt == subs->cur_audiofmt)
303 return 0;
304
305 /* close the old interface */
306 if (subs->interface >= 0 && subs->interface != fmt->iface) {
307 if (usb_set_interface(subs->dev, subs->interface, 0) < 0) {
308 snd_printk(KERN_ERR "%d:%d:%d: return to setting 0 failed\n",
309 dev->devnum, fmt->iface, fmt->altsetting);
310 return -EIO;
311 }
312 subs->interface = -1;
313 subs->altset_idx = 0;
314 }
315
316 /* set interface */
317 if (subs->interface != fmt->iface || subs->altset_idx != fmt->altset_idx) {
318 if (usb_set_interface(dev, fmt->iface, fmt->altsetting) < 0) {
319 snd_printk(KERN_ERR "%d:%d:%d: usb_set_interface failed\n",
320 dev->devnum, fmt->iface, fmt->altsetting);
321 return -EIO;
322 }
323 snd_printdd(KERN_INFO "setting usb interface %d:%d\n", fmt->iface, fmt->altsetting);
324 subs->interface = fmt->iface;
325 subs->altset_idx = fmt->altset_idx;
326 }
327
328 /* create a data pipe */
329 ep = fmt->endpoint & USB_ENDPOINT_NUMBER_MASK;
330 if (is_playback)
331 subs->datapipe = usb_sndisocpipe(dev, ep);
332 else
333 subs->datapipe = usb_rcvisocpipe(dev, ep);
334 subs->datainterval = fmt->datainterval;
335 subs->syncpipe = subs->syncinterval = 0;
336 subs->maxpacksize = fmt->maxpacksize;
337 subs->fill_max = 0;
338
339 /* we need a sync pipe in async OUT or adaptive IN mode */
340 /* check the number of EP, since some devices have broken
341 * descriptors which fool us. if it has only one EP,
342 * assume it as adaptive-out or sync-in.
343 */
344 attr = fmt->ep_attr & USB_ENDPOINT_SYNCTYPE;
345 if (((is_playback && attr == USB_ENDPOINT_SYNC_ASYNC) ||
346 (! is_playback && attr == USB_ENDPOINT_SYNC_ADAPTIVE)) &&
347 altsd->bNumEndpoints >= 2) {
348 /* check sync-pipe endpoint */
349 /* ... and check descriptor size before accessing bSynchAddress
350 because there is a version of the SB Audigy 2 NX firmware lacking
351 the audio fields in the endpoint descriptors */
352 if ((get_endpoint(alts, 1)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != 0x01 ||
353 (get_endpoint(alts, 1)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE &&
354 get_endpoint(alts, 1)->bSynchAddress != 0)) {
355 snd_printk(KERN_ERR "%d:%d:%d : invalid synch pipe\n",
356 dev->devnum, fmt->iface, fmt->altsetting);
357 return -EINVAL;
358 }
359 ep = get_endpoint(alts, 1)->bEndpointAddress;
360 if (get_endpoint(alts, 0)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE &&
361 (( is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress | USB_DIR_IN)) ||
362 (!is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress & ~USB_DIR_IN)))) {
363 snd_printk(KERN_ERR "%d:%d:%d : invalid synch pipe\n",
364 dev->devnum, fmt->iface, fmt->altsetting);
365 return -EINVAL;
366 }
367 ep &= USB_ENDPOINT_NUMBER_MASK;
368 if (is_playback)
369 subs->syncpipe = usb_rcvisocpipe(dev, ep);
370 else
371 subs->syncpipe = usb_sndisocpipe(dev, ep);
372 if (get_endpoint(alts, 1)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE &&
373 get_endpoint(alts, 1)->bRefresh >= 1 &&
374 get_endpoint(alts, 1)->bRefresh <= 9)
375 subs->syncinterval = get_endpoint(alts, 1)->bRefresh;
376 else if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL)
377 subs->syncinterval = 1;
378 else if (get_endpoint(alts, 1)->bInterval >= 1 &&
379 get_endpoint(alts, 1)->bInterval <= 16)
380 subs->syncinterval = get_endpoint(alts, 1)->bInterval - 1;
381 else
382 subs->syncinterval = 3;
383 }
384
385 /* always fill max packet size */
386 if (fmt->attributes & UAC_EP_CS_ATTR_FILL_MAX)
387 subs->fill_max = 1;
388
389 if ((err = snd_usb_init_pitch(subs->stream->chip, subs->interface, alts, fmt)) < 0)
390 return err;
391
392 subs->cur_audiofmt = fmt;
393
394 snd_usb_set_format_quirk(subs, fmt);
395
396#if 0
397 printk(KERN_DEBUG
398 "setting done: format = %d, rate = %d..%d, channels = %d\n",
399 fmt->format, fmt->rate_min, fmt->rate_max, fmt->channels);
400 printk(KERN_DEBUG
401 " datapipe = 0x%0x, syncpipe = 0x%0x\n",
402 subs->datapipe, subs->syncpipe);
403#endif
404
405 return 0;
406}
407
408/*
409 * hw_params callback
410 *
411 * allocate a buffer and set the given audio format.
412 *
413 * so far we use a physically linear buffer although packetize transfer
414 * doesn't need a continuous area.
415 * if sg buffer is supported on the later version of alsa, we'll follow
416 * that.
417 */
418static int snd_usb_hw_params(struct snd_pcm_substream *substream,
419 struct snd_pcm_hw_params *hw_params)
420{
421 struct snd_usb_substream *subs = substream->runtime->private_data;
422 struct audioformat *fmt;
423 unsigned int channels, rate, format;
424 int ret, changed;
425
426 ret = snd_pcm_lib_alloc_vmalloc_buffer(substream,
427 params_buffer_bytes(hw_params));
428 if (ret < 0)
429 return ret;
430
431 format = params_format(hw_params);
432 rate = params_rate(hw_params);
433 channels = params_channels(hw_params);
434 fmt = find_format(subs, format, rate, channels);
435 if (!fmt) {
436 snd_printd(KERN_DEBUG "cannot set format: format = %#x, rate = %d, channels = %d\n",
437 format, rate, channels);
438 return -EINVAL;
439 }
440
441 changed = subs->cur_audiofmt != fmt ||
442 subs->period_bytes != params_period_bytes(hw_params) ||
443 subs->cur_rate != rate;
444 if ((ret = set_format(subs, fmt)) < 0)
445 return ret;
446
447 if (subs->cur_rate != rate) {
448 struct usb_host_interface *alts;
449 struct usb_interface *iface;
450 iface = usb_ifnum_to_if(subs->dev, fmt->iface);
451 alts = &iface->altsetting[fmt->altset_idx];
452 ret = snd_usb_init_sample_rate(subs->stream->chip, subs->interface, alts, fmt, rate);
453 if (ret < 0)
454 return ret;
455 subs->cur_rate = rate;
456 }
457
458 if (changed) {
459 /* format changed */
460 snd_usb_release_substream_urbs(subs, 0);
461 /* influenced: period_bytes, channels, rate, format, */
462 ret = snd_usb_init_substream_urbs(subs, params_period_bytes(hw_params),
463 params_rate(hw_params),
464 snd_pcm_format_physical_width(params_format(hw_params)) *
465 params_channels(hw_params));
466 }
467
468 return ret;
469}
470
471/*
472 * hw_free callback
473 *
474 * reset the audio format and release the buffer
475 */
476static int snd_usb_hw_free(struct snd_pcm_substream *substream)
477{
478 struct snd_usb_substream *subs = substream->runtime->private_data;
479
480 subs->cur_audiofmt = NULL;
481 subs->cur_rate = 0;
482 subs->period_bytes = 0;
483 if (!subs->stream->chip->shutdown)
484 snd_usb_release_substream_urbs(subs, 0);
485 return snd_pcm_lib_free_vmalloc_buffer(substream);
486}
487
488/*
489 * prepare callback
490 *
491 * only a few subtle things...
492 */
493static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
494{
495 struct snd_pcm_runtime *runtime = substream->runtime;
496 struct snd_usb_substream *subs = runtime->private_data;
497
498 if (! subs->cur_audiofmt) {
499 snd_printk(KERN_ERR "usbaudio: no format is specified!\n");
500 return -ENXIO;
501 }
502
503 /* some unit conversions in runtime */
504 subs->maxframesize = bytes_to_frames(runtime, subs->maxpacksize);
505 subs->curframesize = bytes_to_frames(runtime, subs->curpacksize);
506
507 /* reset the pointer */
508 subs->hwptr_done = 0;
509 subs->transfer_done = 0;
510 subs->phase = 0;
511 runtime->delay = 0;
512
513 return snd_usb_substream_prepare(subs, runtime);
514}
515
516static struct snd_pcm_hardware snd_usb_hardware =
517{
518 .info = SNDRV_PCM_INFO_MMAP |
519 SNDRV_PCM_INFO_MMAP_VALID |
520 SNDRV_PCM_INFO_BATCH |
521 SNDRV_PCM_INFO_INTERLEAVED |
522 SNDRV_PCM_INFO_BLOCK_TRANSFER |
523 SNDRV_PCM_INFO_PAUSE,
524 .buffer_bytes_max = 1024 * 1024,
525 .period_bytes_min = 64,
526 .period_bytes_max = 512 * 1024,
527 .periods_min = 2,
528 .periods_max = 1024,
529};
530
531static int hw_check_valid_format(struct snd_usb_substream *subs,
532 struct snd_pcm_hw_params *params,
533 struct audioformat *fp)
534{
535 struct snd_interval *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
536 struct snd_interval *ct = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
537 struct snd_mask *fmts = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
538 struct snd_interval *pt = hw_param_interval(params, SNDRV_PCM_HW_PARAM_PERIOD_TIME);
539 struct snd_mask check_fmts;
540 unsigned int ptime;
541
542 /* check the format */
543 snd_mask_none(&check_fmts);
544 check_fmts.bits[0] = (u32)fp->formats;
545 check_fmts.bits[1] = (u32)(fp->formats >> 32);
546 snd_mask_intersect(&check_fmts, fmts);
547 if (snd_mask_empty(&check_fmts)) {
548 hwc_debug(" > check: no supported format %d\n", fp->format);
549 return 0;
550 }
551 /* check the channels */
552 if (fp->channels < ct->min || fp->channels > ct->max) {
553 hwc_debug(" > check: no valid channels %d (%d/%d)\n", fp->channels, ct->min, ct->max);
554 return 0;
555 }
556 /* check the rate is within the range */
557 if (fp->rate_min > it->max || (fp->rate_min == it->max && it->openmax)) {
558 hwc_debug(" > check: rate_min %d > max %d\n", fp->rate_min, it->max);
559 return 0;
560 }
561 if (fp->rate_max < it->min || (fp->rate_max == it->min && it->openmin)) {
562 hwc_debug(" > check: rate_max %d < min %d\n", fp->rate_max, it->min);
563 return 0;
564 }
565 /* check whether the period time is >= the data packet interval */
566 if (snd_usb_get_speed(subs->dev) == USB_SPEED_HIGH) {
567 ptime = 125 * (1 << fp->datainterval);
568 if (ptime > pt->max || (ptime == pt->max && pt->openmax)) {
569 hwc_debug(" > check: ptime %u > max %u\n", ptime, pt->max);
570 return 0;
571 }
572 }
573 return 1;
574}
575
576static int hw_rule_rate(struct snd_pcm_hw_params *params,
577 struct snd_pcm_hw_rule *rule)
578{
579 struct snd_usb_substream *subs = rule->private;
580 struct list_head *p;
581 struct snd_interval *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
582 unsigned int rmin, rmax;
583 int changed;
584
585 hwc_debug("hw_rule_rate: (%d,%d)\n", it->min, it->max);
586 changed = 0;
587 rmin = rmax = 0;
588 list_for_each(p, &subs->fmt_list) {
589 struct audioformat *fp;
590 fp = list_entry(p, struct audioformat, list);
591 if (!hw_check_valid_format(subs, params, fp))
592 continue;
593 if (changed++) {
594 if (rmin > fp->rate_min)
595 rmin = fp->rate_min;
596 if (rmax < fp->rate_max)
597 rmax = fp->rate_max;
598 } else {
599 rmin = fp->rate_min;
600 rmax = fp->rate_max;
601 }
602 }
603
604 if (!changed) {
605 hwc_debug(" --> get empty\n");
606 it->empty = 1;
607 return -EINVAL;
608 }
609
610 changed = 0;
611 if (it->min < rmin) {
612 it->min = rmin;
613 it->openmin = 0;
614 changed = 1;
615 }
616 if (it->max > rmax) {
617 it->max = rmax;
618 it->openmax = 0;
619 changed = 1;
620 }
621 if (snd_interval_checkempty(it)) {
622 it->empty = 1;
623 return -EINVAL;
624 }
625 hwc_debug(" --> (%d, %d) (changed = %d)\n", it->min, it->max, changed);
626 return changed;
627}
628
629
630static int hw_rule_channels(struct snd_pcm_hw_params *params,
631 struct snd_pcm_hw_rule *rule)
632{
633 struct snd_usb_substream *subs = rule->private;
634 struct list_head *p;
635 struct snd_interval *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
636 unsigned int rmin, rmax;
637 int changed;
638
639 hwc_debug("hw_rule_channels: (%d,%d)\n", it->min, it->max);
640 changed = 0;
641 rmin = rmax = 0;
642 list_for_each(p, &subs->fmt_list) {
643 struct audioformat *fp;
644 fp = list_entry(p, struct audioformat, list);
645 if (!hw_check_valid_format(subs, params, fp))
646 continue;
647 if (changed++) {
648 if (rmin > fp->channels)
649 rmin = fp->channels;
650 if (rmax < fp->channels)
651 rmax = fp->channels;
652 } else {
653 rmin = fp->channels;
654 rmax = fp->channels;
655 }
656 }
657
658 if (!changed) {
659 hwc_debug(" --> get empty\n");
660 it->empty = 1;
661 return -EINVAL;
662 }
663
664 changed = 0;
665 if (it->min < rmin) {
666 it->min = rmin;
667 it->openmin = 0;
668 changed = 1;
669 }
670 if (it->max > rmax) {
671 it->max = rmax;
672 it->openmax = 0;
673 changed = 1;
674 }
675 if (snd_interval_checkempty(it)) {
676 it->empty = 1;
677 return -EINVAL;
678 }
679 hwc_debug(" --> (%d, %d) (changed = %d)\n", it->min, it->max, changed);
680 return changed;
681}
682
683static int hw_rule_format(struct snd_pcm_hw_params *params,
684 struct snd_pcm_hw_rule *rule)
685{
686 struct snd_usb_substream *subs = rule->private;
687 struct list_head *p;
688 struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
689 u64 fbits;
690 u32 oldbits[2];
691 int changed;
692
693 hwc_debug("hw_rule_format: %x:%x\n", fmt->bits[0], fmt->bits[1]);
694 fbits = 0;
695 list_for_each(p, &subs->fmt_list) {
696 struct audioformat *fp;
697 fp = list_entry(p, struct audioformat, list);
698 if (!hw_check_valid_format(subs, params, fp))
699 continue;
700 fbits |= fp->formats;
701 }
702
703 oldbits[0] = fmt->bits[0];
704 oldbits[1] = fmt->bits[1];
705 fmt->bits[0] &= (u32)fbits;
706 fmt->bits[1] &= (u32)(fbits >> 32);
707 if (!fmt->bits[0] && !fmt->bits[1]) {
708 hwc_debug(" --> get empty\n");
709 return -EINVAL;
710 }
711 changed = (oldbits[0] != fmt->bits[0] || oldbits[1] != fmt->bits[1]);
712 hwc_debug(" --> %x:%x (changed = %d)\n", fmt->bits[0], fmt->bits[1], changed);
713 return changed;
714}
715
716static int hw_rule_period_time(struct snd_pcm_hw_params *params,
717 struct snd_pcm_hw_rule *rule)
718{
719 struct snd_usb_substream *subs = rule->private;
720 struct audioformat *fp;
721 struct snd_interval *it;
722 unsigned char min_datainterval;
723 unsigned int pmin;
724 int changed;
725
726 it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_PERIOD_TIME);
727 hwc_debug("hw_rule_period_time: (%u,%u)\n", it->min, it->max);
728 min_datainterval = 0xff;
729 list_for_each_entry(fp, &subs->fmt_list, list) {
730 if (!hw_check_valid_format(subs, params, fp))
731 continue;
732 min_datainterval = min(min_datainterval, fp->datainterval);
733 }
734 if (min_datainterval == 0xff) {
735 hwc_debug(" --> get emtpy\n");
736 it->empty = 1;
737 return -EINVAL;
738 }
739 pmin = 125 * (1 << min_datainterval);
740 changed = 0;
741 if (it->min < pmin) {
742 it->min = pmin;
743 it->openmin = 0;
744 changed = 1;
745 }
746 if (snd_interval_checkempty(it)) {
747 it->empty = 1;
748 return -EINVAL;
749 }
750 hwc_debug(" --> (%u,%u) (changed = %d)\n", it->min, it->max, changed);
751 return changed;
752}
753
754/*
755 * If the device supports unusual bit rates, does the request meet these?
756 */
757static int snd_usb_pcm_check_knot(struct snd_pcm_runtime *runtime,
758 struct snd_usb_substream *subs)
759{
760 struct audioformat *fp;
761 int count = 0, needs_knot = 0;
762 int err;
763
764 list_for_each_entry(fp, &subs->fmt_list, list) {
765 if (fp->rates & SNDRV_PCM_RATE_CONTINUOUS)
766 return 0;
767 count += fp->nr_rates;
768 if (fp->rates & SNDRV_PCM_RATE_KNOT)
769 needs_knot = 1;
770 }
771 if (!needs_knot)
772 return 0;
773
774 subs->rate_list.count = count;
775 subs->rate_list.list = kmalloc(sizeof(int) * count, GFP_KERNEL);
776 subs->rate_list.mask = 0;
777 count = 0;
778 list_for_each_entry(fp, &subs->fmt_list, list) {
779 int i;
780 for (i = 0; i < fp->nr_rates; i++)
781 subs->rate_list.list[count++] = fp->rate_table[i];
782 }
783 err = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
784 &subs->rate_list);
785 if (err < 0)
786 return err;
787
788 return 0;
789}
790
791
792/*
793 * set up the runtime hardware information.
794 */
795
796static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substream *subs)
797{
798 struct list_head *p;
799 unsigned int pt, ptmin;
800 int param_period_time_if_needed;
801 int err;
802
803 runtime->hw.formats = subs->formats;
804
805 runtime->hw.rate_min = 0x7fffffff;
806 runtime->hw.rate_max = 0;
807 runtime->hw.channels_min = 256;
808 runtime->hw.channels_max = 0;
809 runtime->hw.rates = 0;
810 ptmin = UINT_MAX;
811 /* check min/max rates and channels */
812 list_for_each(p, &subs->fmt_list) {
813 struct audioformat *fp;
814 fp = list_entry(p, struct audioformat, list);
815 runtime->hw.rates |= fp->rates;
816 if (runtime->hw.rate_min > fp->rate_min)
817 runtime->hw.rate_min = fp->rate_min;
818 if (runtime->hw.rate_max < fp->rate_max)
819 runtime->hw.rate_max = fp->rate_max;
820 if (runtime->hw.channels_min > fp->channels)
821 runtime->hw.channels_min = fp->channels;
822 if (runtime->hw.channels_max < fp->channels)
823 runtime->hw.channels_max = fp->channels;
824 if (fp->fmt_type == UAC_FORMAT_TYPE_II && fp->frame_size > 0) {
825 /* FIXME: there might be more than one audio formats... */
826 runtime->hw.period_bytes_min = runtime->hw.period_bytes_max =
827 fp->frame_size;
828 }
829 pt = 125 * (1 << fp->datainterval);
830 ptmin = min(ptmin, pt);
831 }
832
833 param_period_time_if_needed = SNDRV_PCM_HW_PARAM_PERIOD_TIME;
834 if (snd_usb_get_speed(subs->dev) != USB_SPEED_HIGH)
835 /* full speed devices have fixed data packet interval */
836 ptmin = 1000;
837 if (ptmin == 1000)
838 /* if period time doesn't go below 1 ms, no rules needed */
839 param_period_time_if_needed = -1;
840 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME,
841 ptmin, UINT_MAX);
842
843 if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
844 hw_rule_rate, subs,
845 SNDRV_PCM_HW_PARAM_FORMAT,
846 SNDRV_PCM_HW_PARAM_CHANNELS,
847 param_period_time_if_needed,
848 -1)) < 0)
849 return err;
850 if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
851 hw_rule_channels, subs,
852 SNDRV_PCM_HW_PARAM_FORMAT,
853 SNDRV_PCM_HW_PARAM_RATE,
854 param_period_time_if_needed,
855 -1)) < 0)
856 return err;
857 if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT,
858 hw_rule_format, subs,
859 SNDRV_PCM_HW_PARAM_RATE,
860 SNDRV_PCM_HW_PARAM_CHANNELS,
861 param_period_time_if_needed,
862 -1)) < 0)
863 return err;
864 if (param_period_time_if_needed >= 0) {
865 err = snd_pcm_hw_rule_add(runtime, 0,
866 SNDRV_PCM_HW_PARAM_PERIOD_TIME,
867 hw_rule_period_time, subs,
868 SNDRV_PCM_HW_PARAM_FORMAT,
869 SNDRV_PCM_HW_PARAM_CHANNELS,
870 SNDRV_PCM_HW_PARAM_RATE,
871 -1);
872 if (err < 0)
873 return err;
874 }
875 if ((err = snd_usb_pcm_check_knot(runtime, subs)) < 0)
876 return err;
877 return 0;
878}
879
880static int snd_usb_pcm_open(struct snd_pcm_substream *substream, int direction)
881{
882 struct snd_usb_stream *as = snd_pcm_substream_chip(substream);
883 struct snd_pcm_runtime *runtime = substream->runtime;
884 struct snd_usb_substream *subs = &as->substream[direction];
885
886 subs->interface = -1;
887 subs->altset_idx = 0;
888 runtime->hw = snd_usb_hardware;
889 runtime->private_data = subs;
890 subs->pcm_substream = substream;
891 return setup_hw_info(runtime, subs);
892}
893
894static int snd_usb_pcm_close(struct snd_pcm_substream *substream, int direction)
895{
896 struct snd_usb_stream *as = snd_pcm_substream_chip(substream);
897 struct snd_usb_substream *subs = &as->substream[direction];
898
899 if (!as->chip->shutdown && subs->interface >= 0) {
900 usb_set_interface(subs->dev, subs->interface, 0);
901 subs->interface = -1;
902 }
903 subs->pcm_substream = NULL;
904 return 0;
905}
906
907static int snd_usb_playback_open(struct snd_pcm_substream *substream)
908{
909 return snd_usb_pcm_open(substream, SNDRV_PCM_STREAM_PLAYBACK);
910}
911
912static int snd_usb_playback_close(struct snd_pcm_substream *substream)
913{
914 return snd_usb_pcm_close(substream, SNDRV_PCM_STREAM_PLAYBACK);
915}
916
917static int snd_usb_capture_open(struct snd_pcm_substream *substream)
918{
919 return snd_usb_pcm_open(substream, SNDRV_PCM_STREAM_CAPTURE);
920}
921
922static int snd_usb_capture_close(struct snd_pcm_substream *substream)
923{
924 return snd_usb_pcm_close(substream, SNDRV_PCM_STREAM_CAPTURE);
925}
926
927static struct snd_pcm_ops snd_usb_playback_ops = {
928 .open = snd_usb_playback_open,
929 .close = snd_usb_playback_close,
930 .ioctl = snd_pcm_lib_ioctl,
931 .hw_params = snd_usb_hw_params,
932 .hw_free = snd_usb_hw_free,
933 .prepare = snd_usb_pcm_prepare,
934 .trigger = snd_usb_substream_playback_trigger,
935 .pointer = snd_usb_pcm_pointer,
936 .page = snd_pcm_lib_get_vmalloc_page,
937 .mmap = snd_pcm_lib_mmap_vmalloc,
938};
939
940static struct snd_pcm_ops snd_usb_capture_ops = {
941 .open = snd_usb_capture_open,
942 .close = snd_usb_capture_close,
943 .ioctl = snd_pcm_lib_ioctl,
944 .hw_params = snd_usb_hw_params,
945 .hw_free = snd_usb_hw_free,
946 .prepare = snd_usb_pcm_prepare,
947 .trigger = snd_usb_substream_capture_trigger,
948 .pointer = snd_usb_pcm_pointer,
949 .page = snd_pcm_lib_get_vmalloc_page,
950 .mmap = snd_pcm_lib_mmap_vmalloc,
951};
952
953void snd_usb_set_pcm_ops(struct snd_pcm *pcm, int stream)
954{
955 snd_pcm_set_ops(pcm, stream,
956 stream == SNDRV_PCM_STREAM_PLAYBACK ?
957 &snd_usb_playback_ops : &snd_usb_capture_ops);
958}
diff --git a/sound/usb/pcm.h b/sound/usb/pcm.h
new file mode 100644
index 000000000000..1c931b68f3b5
--- /dev/null
+++ b/sound/usb/pcm.h
@@ -0,0 +1,14 @@
1#ifndef __USBAUDIO_PCM_H
2#define __USBAUDIO_PCM_H
3
4void snd_usb_set_pcm_ops(struct snd_pcm *pcm, int stream);
5
6int snd_usb_init_pitch(struct snd_usb_audio *chip, int iface,
7 struct usb_host_interface *alts,
8 struct audioformat *fmt);
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
14#endif /* __USBAUDIO_PCM_H */
diff --git a/sound/usb/proc.c b/sound/usb/proc.c
new file mode 100644
index 000000000000..f5e3f356b95f
--- /dev/null
+++ b/sound/usb/proc.c
@@ -0,0 +1,168 @@
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 as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15 *
16 */
17
18#include <linux/init.h>
19#include <linux/usb.h>
20
21#include <sound/core.h>
22#include <sound/info.h>
23#include <sound/pcm.h>
24
25#include "usbaudio.h"
26#include "helper.h"
27#include "card.h"
28#include "proc.h"
29
30/* convert our full speed USB rate into sampling rate in Hz */
31static inline unsigned get_full_speed_hz(unsigned int usb_rate)
32{
33 return (usb_rate * 125 + (1 << 12)) >> 13;
34}
35
36/* convert our high speed USB rate into sampling rate in Hz */
37static inline unsigned get_high_speed_hz(unsigned int usb_rate)
38{
39 return (usb_rate * 125 + (1 << 9)) >> 10;
40}
41
42/*
43 * common proc files to show the usb device info
44 */
45static void proc_audio_usbbus_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
46{
47 struct snd_usb_audio *chip = entry->private_data;
48 if (!chip->shutdown)
49 snd_iprintf(buffer, "%03d/%03d\n", chip->dev->bus->busnum, chip->dev->devnum);
50}
51
52static void proc_audio_usbid_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
53{
54 struct snd_usb_audio *chip = entry->private_data;
55 if (!chip->shutdown)
56 snd_iprintf(buffer, "%04x:%04x\n",
57 USB_ID_VENDOR(chip->usb_id),
58 USB_ID_PRODUCT(chip->usb_id));
59}
60
61void snd_usb_audio_create_proc(struct snd_usb_audio *chip)
62{
63 struct snd_info_entry *entry;
64 if (!snd_card_proc_new(chip->card, "usbbus", &entry))
65 snd_info_set_text_ops(entry, chip, proc_audio_usbbus_read);
66 if (!snd_card_proc_new(chip->card, "usbid", &entry))
67 snd_info_set_text_ops(entry, chip, proc_audio_usbid_read);
68}
69
70/*
71 * proc interface for list the supported pcm formats
72 */
73static void proc_dump_substream_formats(struct snd_usb_substream *subs, struct snd_info_buffer *buffer)
74{
75 struct list_head *p;
76 static char *sync_types[4] = {
77 "NONE", "ASYNC", "ADAPTIVE", "SYNC"
78 };
79
80 list_for_each(p, &subs->fmt_list) {
81 struct audioformat *fp;
82 snd_pcm_format_t fmt;
83 fp = list_entry(p, struct audioformat, list);
84 snd_iprintf(buffer, " Interface %d\n", fp->iface);
85 snd_iprintf(buffer, " Altset %d\n", fp->altsetting);
86 snd_iprintf(buffer, " Format:");
87 for (fmt = 0; fmt <= SNDRV_PCM_FORMAT_LAST; ++fmt)
88 if (fp->formats & (1uLL << fmt))
89 snd_iprintf(buffer, " %s",
90 snd_pcm_format_name(fmt));
91 snd_iprintf(buffer, "\n");
92 snd_iprintf(buffer, " Channels: %d\n", fp->channels);
93 snd_iprintf(buffer, " Endpoint: %d %s (%s)\n",
94 fp->endpoint & USB_ENDPOINT_NUMBER_MASK,
95 fp->endpoint & USB_DIR_IN ? "IN" : "OUT",
96 sync_types[(fp->ep_attr & USB_ENDPOINT_SYNCTYPE) >> 2]);
97 if (fp->rates & SNDRV_PCM_RATE_CONTINUOUS) {
98 snd_iprintf(buffer, " Rates: %d - %d (continuous)\n",
99 fp->rate_min, fp->rate_max);
100 } else {
101 unsigned int i;
102 snd_iprintf(buffer, " Rates: ");
103 for (i = 0; i < fp->nr_rates; i++) {
104 if (i > 0)
105 snd_iprintf(buffer, ", ");
106 snd_iprintf(buffer, "%d", fp->rate_table[i]);
107 }
108 snd_iprintf(buffer, "\n");
109 }
110 if (snd_usb_get_speed(subs->dev) == USB_SPEED_HIGH)
111 snd_iprintf(buffer, " Data packet interval: %d us\n",
112 125 * (1 << fp->datainterval));
113 // snd_iprintf(buffer, " Max Packet Size = %d\n", fp->maxpacksize);
114 // snd_iprintf(buffer, " EP Attribute = %#x\n", fp->attributes);
115 }
116}
117
118static void proc_dump_substream_status(struct snd_usb_substream *subs, struct snd_info_buffer *buffer)
119{
120 if (subs->running) {
121 unsigned int i;
122 snd_iprintf(buffer, " Status: Running\n");
123 snd_iprintf(buffer, " Interface = %d\n", subs->interface);
124 snd_iprintf(buffer, " Altset = %d\n", subs->altset_idx);
125 snd_iprintf(buffer, " URBs = %d [ ", subs->nurbs);
126 for (i = 0; i < subs->nurbs; i++)
127 snd_iprintf(buffer, "%d ", subs->dataurb[i].packets);
128 snd_iprintf(buffer, "]\n");
129 snd_iprintf(buffer, " Packet Size = %d\n", subs->curpacksize);
130 snd_iprintf(buffer, " Momentary freq = %u Hz (%#x.%04x)\n",
131 snd_usb_get_speed(subs->dev) == USB_SPEED_FULL
132 ? get_full_speed_hz(subs->freqm)
133 : get_high_speed_hz(subs->freqm),
134 subs->freqm >> 16, subs->freqm & 0xffff);
135 } else {
136 snd_iprintf(buffer, " Status: Stop\n");
137 }
138}
139
140static void proc_pcm_format_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
141{
142 struct snd_usb_stream *stream = entry->private_data;
143
144 snd_iprintf(buffer, "%s : %s\n", stream->chip->card->longname, stream->pcm->name);
145
146 if (stream->substream[SNDRV_PCM_STREAM_PLAYBACK].num_formats) {
147 snd_iprintf(buffer, "\nPlayback:\n");
148 proc_dump_substream_status(&stream->substream[SNDRV_PCM_STREAM_PLAYBACK], buffer);
149 proc_dump_substream_formats(&stream->substream[SNDRV_PCM_STREAM_PLAYBACK], buffer);
150 }
151 if (stream->substream[SNDRV_PCM_STREAM_CAPTURE].num_formats) {
152 snd_iprintf(buffer, "\nCapture:\n");
153 proc_dump_substream_status(&stream->substream[SNDRV_PCM_STREAM_CAPTURE], buffer);
154 proc_dump_substream_formats(&stream->substream[SNDRV_PCM_STREAM_CAPTURE], buffer);
155 }
156}
157
158void snd_usb_proc_pcm_format_add(struct snd_usb_stream *stream)
159{
160 struct snd_info_entry *entry;
161 char name[32];
162 struct snd_card *card = stream->chip->card;
163
164 sprintf(name, "stream%d", stream->pcm_index);
165 if (!snd_card_proc_new(card, name, &entry))
166 snd_info_set_text_ops(entry, stream, proc_pcm_format_read);
167}
168
diff --git a/sound/usb/proc.h b/sound/usb/proc.h
new file mode 100644
index 000000000000..a45b765e4cf1
--- /dev/null
+++ b/sound/usb/proc.h
@@ -0,0 +1,8 @@
1#ifndef __USBAUDIO_PROC_H
2#define __USBAUDIO_PROC_H
3
4void snd_usb_audio_create_proc(struct snd_usb_audio *chip);
5void snd_usb_proc_pcm_format_add(struct snd_usb_stream *stream);
6
7#endif /* __USBAUDIO_PROC_H */
8
diff --git a/sound/usb/usbquirks.h b/sound/usb/quirks-table.h
index 2b426c1fd0e8..f8797f61a24b 100644
--- a/sound/usb/usbquirks.h
+++ b/sound/usb/quirks-table.h
@@ -279,7 +279,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
279 .ifnum = 0, 279 .ifnum = 0,
280 .type = QUIRK_AUDIO_FIXED_ENDPOINT, 280 .type = QUIRK_AUDIO_FIXED_ENDPOINT,
281 .data = & (const struct audioformat) { 281 .data = & (const struct audioformat) {
282 .format = SNDRV_PCM_FORMAT_S16_LE, 282 .formats = SNDRV_PCM_FMTBIT_S16_LE,
283 .channels = 4, 283 .channels = 4,
284 .iface = 0, 284 .iface = 0,
285 .altsetting = 1, 285 .altsetting = 1,
@@ -296,7 +296,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
296 .ifnum = 1, 296 .ifnum = 1,
297 .type = QUIRK_AUDIO_FIXED_ENDPOINT, 297 .type = QUIRK_AUDIO_FIXED_ENDPOINT,
298 .data = & (const struct audioformat) { 298 .data = & (const struct audioformat) {
299 .format = SNDRV_PCM_FORMAT_S16_LE, 299 .formats = SNDRV_PCM_FMTBIT_S16_LE,
300 .channels = 2, 300 .channels = 2,
301 .iface = 1, 301 .iface = 1,
302 .altsetting = 1, 302 .altsetting = 1,
@@ -580,7 +580,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
580 .ifnum = 0, 580 .ifnum = 0,
581 .type = QUIRK_AUDIO_FIXED_ENDPOINT, 581 .type = QUIRK_AUDIO_FIXED_ENDPOINT,
582 .data = & (const struct audioformat) { 582 .data = & (const struct audioformat) {
583 .format = SNDRV_PCM_FORMAT_S24_3LE, 583 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
584 .channels = 2, 584 .channels = 2,
585 .iface = 0, 585 .iface = 0,
586 .altsetting = 1, 586 .altsetting = 1,
@@ -597,7 +597,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
597 .ifnum = 1, 597 .ifnum = 1,
598 .type = QUIRK_AUDIO_FIXED_ENDPOINT, 598 .type = QUIRK_AUDIO_FIXED_ENDPOINT,
599 .data = & (const struct audioformat) { 599 .data = & (const struct audioformat) {
600 .format = SNDRV_PCM_FORMAT_S24_3LE, 600 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
601 .channels = 2, 601 .channels = 2,
602 .iface = 1, 602 .iface = 1,
603 .altsetting = 1, 603 .altsetting = 1,
@@ -793,7 +793,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
793 .ifnum = 1, 793 .ifnum = 1,
794 .type = QUIRK_AUDIO_FIXED_ENDPOINT, 794 .type = QUIRK_AUDIO_FIXED_ENDPOINT,
795 .data = & (const struct audioformat) { 795 .data = & (const struct audioformat) {
796 .format = SNDRV_PCM_FORMAT_S24_3LE, 796 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
797 .channels = 2, 797 .channels = 2,
798 .iface = 1, 798 .iface = 1,
799 .altsetting = 1, 799 .altsetting = 1,
@@ -810,7 +810,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
810 .ifnum = 2, 810 .ifnum = 2,
811 .type = QUIRK_AUDIO_FIXED_ENDPOINT, 811 .type = QUIRK_AUDIO_FIXED_ENDPOINT,
812 .data = & (const struct audioformat) { 812 .data = & (const struct audioformat) {
813 .format = SNDRV_PCM_FORMAT_S24_3LE, 813 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
814 .channels = 2, 814 .channels = 2,
815 .iface = 2, 815 .iface = 2,
816 .altsetting = 1, 816 .altsetting = 1,
@@ -1826,6 +1826,60 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1826 } 1826 }
1827 } 1827 }
1828}, 1828},
1829{
1830 USB_DEVICE(0x0763, 0x2080),
1831 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1832 /* .vendor_name = "M-Audio", */
1833 /* .product_name = "Fast Track Ultra 8", */
1834 .ifnum = QUIRK_ANY_INTERFACE,
1835 .type = QUIRK_COMPOSITE,
1836 .data = & (const struct snd_usb_audio_quirk[]) {
1837 {
1838 .ifnum = 0,
1839 .type = QUIRK_IGNORE_INTERFACE
1840 },
1841 {
1842 .ifnum = 1,
1843 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1844 },
1845 {
1846 .ifnum = 2,
1847 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1848 },
1849 /* interface 3 (MIDI) is standard compliant */
1850 {
1851 .ifnum = -1
1852 }
1853 }
1854 }
1855},
1856{
1857 USB_DEVICE(0x0763, 0x2081),
1858 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1859 /* .vendor_name = "M-Audio", */
1860 /* .product_name = "Fast Track Ultra 8R", */
1861 .ifnum = QUIRK_ANY_INTERFACE,
1862 .type = QUIRK_COMPOSITE,
1863 .data = & (const struct snd_usb_audio_quirk[]) {
1864 {
1865 .ifnum = 0,
1866 .type = QUIRK_IGNORE_INTERFACE
1867 },
1868 {
1869 .ifnum = 1,
1870 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1871 },
1872 {
1873 .ifnum = 2,
1874 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1875 },
1876 /* interface 3 (MIDI) is standard compliant */
1877 {
1878 .ifnum = -1
1879 }
1880 }
1881 }
1882},
1829 1883
1830/* Casio devices */ 1884/* Casio devices */
1831{ 1885{
@@ -1919,6 +1973,17 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1919 } 1973 }
1920}, 1974},
1921 1975
1976/* AKAI devices */
1977{
1978 USB_DEVICE(0x09e8, 0x0062),
1979 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1980 .vendor_name = "AKAI",
1981 .product_name = "MPD16",
1982 .ifnum = 0,
1983 .type = QUIRK_MIDI_AKAI,
1984 }
1985},
1986
1922/* TerraTec devices */ 1987/* TerraTec devices */
1923{ 1988{
1924 USB_DEVICE_VENDOR_SPEC(0x0ccd, 0x0012), 1989 USB_DEVICE_VENDOR_SPEC(0x0ccd, 0x0012),
@@ -2203,7 +2268,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
2203 .ifnum = 1, 2268 .ifnum = 1,
2204 .type = QUIRK_AUDIO_FIXED_ENDPOINT, 2269 .type = QUIRK_AUDIO_FIXED_ENDPOINT,
2205 .data = &(const struct audioformat) { 2270 .data = &(const struct audioformat) {
2206 .format = SNDRV_PCM_FORMAT_S24_3BE, 2271 .formats = SNDRV_PCM_FMTBIT_S24_3BE,
2207 .channels = 2, 2272 .channels = 2,
2208 .iface = 1, 2273 .iface = 1,
2209 .altsetting = 1, 2274 .altsetting = 1,
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
new file mode 100644
index 000000000000..b45e54c09ba2
--- /dev/null
+++ b/sound/usb/quirks.c
@@ -0,0 +1,595 @@
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 as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15 */
16
17#include <linux/init.h>
18#include <linux/slab.h>
19#include <linux/usb.h>
20#include <linux/usb/audio.h>
21
22#include <sound/core.h>
23#include <sound/info.h>
24#include <sound/pcm.h>
25
26#include "usbaudio.h"
27#include "card.h"
28#include "mixer.h"
29#include "mixer_quirks.h"
30#include "midi.h"
31#include "quirks.h"
32#include "helper.h"
33#include "endpoint.h"
34#include "pcm.h"
35
36/*
37 * handle the quirks for the contained interfaces
38 */
39static int create_composite_quirk(struct snd_usb_audio *chip,
40 struct usb_interface *iface,
41 struct usb_driver *driver,
42 const struct snd_usb_audio_quirk *quirk)
43{
44 int probed_ifnum = get_iface_desc(iface->altsetting)->bInterfaceNumber;
45 int err;
46
47 for (quirk = quirk->data; quirk->ifnum >= 0; ++quirk) {
48 iface = usb_ifnum_to_if(chip->dev, quirk->ifnum);
49 if (!iface)
50 continue;
51 if (quirk->ifnum != probed_ifnum &&
52 usb_interface_claimed(iface))
53 continue;
54 err = snd_usb_create_quirk(chip, iface, driver, quirk);
55 if (err < 0)
56 return err;
57 if (quirk->ifnum != probed_ifnum)
58 usb_driver_claim_interface(driver, iface, (void *)-1L);
59 }
60 return 0;
61}
62
63static int ignore_interface_quirk(struct snd_usb_audio *chip,
64 struct usb_interface *iface,
65 struct usb_driver *driver,
66 const struct snd_usb_audio_quirk *quirk)
67{
68 return 0;
69}
70
71
72/*
73 * Allow alignment on audio sub-slot (channel samples) rather than
74 * on audio slots (audio frames)
75 */
76static int create_align_transfer_quirk(struct snd_usb_audio *chip,
77 struct usb_interface *iface,
78 struct usb_driver *driver,
79 const struct snd_usb_audio_quirk *quirk)
80{
81 chip->txfr_quirk = 1;
82 return 1; /* Continue with creating streams and mixer */
83}
84
85static int create_any_midi_quirk(struct snd_usb_audio *chip,
86 struct usb_interface *intf,
87 struct usb_driver *driver,
88 const struct snd_usb_audio_quirk *quirk)
89{
90 return snd_usbmidi_create(chip->card, intf, &chip->midi_list, quirk);
91}
92
93/*
94 * create a stream for an interface with proper descriptors
95 */
96static int create_standard_audio_quirk(struct snd_usb_audio *chip,
97 struct usb_interface *iface,
98 struct usb_driver *driver,
99 const struct snd_usb_audio_quirk *quirk)
100{
101 struct usb_host_interface *alts;
102 struct usb_interface_descriptor *altsd;
103 int err;
104
105 alts = &iface->altsetting[0];
106 altsd = get_iface_desc(alts);
107 err = snd_usb_parse_audio_endpoints(chip, altsd->bInterfaceNumber);
108 if (err < 0) {
109 snd_printk(KERN_ERR "cannot setup if %d: error %d\n",
110 altsd->bInterfaceNumber, err);
111 return err;
112 }
113 /* reset the current interface */
114 usb_set_interface(chip->dev, altsd->bInterfaceNumber, 0);
115 return 0;
116}
117
118/*
119 * create a stream for an endpoint/altsetting without proper descriptors
120 */
121static int create_fixed_stream_quirk(struct snd_usb_audio *chip,
122 struct usb_interface *iface,
123 struct usb_driver *driver,
124 const struct snd_usb_audio_quirk *quirk)
125{
126 struct audioformat *fp;
127 struct usb_host_interface *alts;
128 int stream, err;
129 unsigned *rate_table = NULL;
130
131 fp = kmemdup(quirk->data, sizeof(*fp), GFP_KERNEL);
132 if (! fp) {
133 snd_printk(KERN_ERR "cannot memdup\n");
134 return -ENOMEM;
135 }
136 if (fp->nr_rates > 0) {
137 rate_table = kmalloc(sizeof(int) * fp->nr_rates, GFP_KERNEL);
138 if (!rate_table) {
139 kfree(fp);
140 return -ENOMEM;
141 }
142 memcpy(rate_table, fp->rate_table, sizeof(int) * fp->nr_rates);
143 fp->rate_table = rate_table;
144 }
145
146 stream = (fp->endpoint & USB_DIR_IN)
147 ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
148 err = snd_usb_add_audio_endpoint(chip, stream, fp);
149 if (err < 0) {
150 kfree(fp);
151 kfree(rate_table);
152 return err;
153 }
154 if (fp->iface != get_iface_desc(&iface->altsetting[0])->bInterfaceNumber ||
155 fp->altset_idx >= iface->num_altsetting) {
156 kfree(fp);
157 kfree(rate_table);
158 return -EINVAL;
159 }
160 alts = &iface->altsetting[fp->altset_idx];
161 fp->datainterval = snd_usb_parse_datainterval(chip, alts);
162 fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
163 usb_set_interface(chip->dev, fp->iface, 0);
164 snd_usb_init_pitch(chip, fp->iface, alts, fp);
165 snd_usb_init_sample_rate(chip, fp->iface, alts, fp, fp->rate_max);
166 return 0;
167}
168
169/*
170 * Create a stream for an Edirol UA-700/UA-25/UA-4FX interface.
171 * The only way to detect the sample rate is by looking at wMaxPacketSize.
172 */
173static int create_uaxx_quirk(struct snd_usb_audio *chip,
174 struct usb_interface *iface,
175 struct usb_driver *driver,
176 const struct snd_usb_audio_quirk *quirk)
177{
178 static const struct audioformat ua_format = {
179 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
180 .channels = 2,
181 .fmt_type = UAC_FORMAT_TYPE_I,
182 .altsetting = 1,
183 .altset_idx = 1,
184 .rates = SNDRV_PCM_RATE_CONTINUOUS,
185 };
186 struct usb_host_interface *alts;
187 struct usb_interface_descriptor *altsd;
188 struct audioformat *fp;
189 int stream, err;
190
191 /* both PCM and MIDI interfaces have 2 or more altsettings */
192 if (iface->num_altsetting < 2)
193 return -ENXIO;
194 alts = &iface->altsetting[1];
195 altsd = get_iface_desc(alts);
196
197 if (altsd->bNumEndpoints == 2) {
198 static const struct snd_usb_midi_endpoint_info ua700_ep = {
199 .out_cables = 0x0003,
200 .in_cables = 0x0003
201 };
202 static const struct snd_usb_audio_quirk ua700_quirk = {
203 .type = QUIRK_MIDI_FIXED_ENDPOINT,
204 .data = &ua700_ep
205 };
206 static const struct snd_usb_midi_endpoint_info uaxx_ep = {
207 .out_cables = 0x0001,
208 .in_cables = 0x0001
209 };
210 static const struct snd_usb_audio_quirk uaxx_quirk = {
211 .type = QUIRK_MIDI_FIXED_ENDPOINT,
212 .data = &uaxx_ep
213 };
214 const struct snd_usb_audio_quirk *quirk =
215 chip->usb_id == USB_ID(0x0582, 0x002b)
216 ? &ua700_quirk : &uaxx_quirk;
217 return snd_usbmidi_create(chip->card, iface,
218 &chip->midi_list, quirk);
219 }
220
221 if (altsd->bNumEndpoints != 1)
222 return -ENXIO;
223
224 fp = kmalloc(sizeof(*fp), GFP_KERNEL);
225 if (!fp)
226 return -ENOMEM;
227 memcpy(fp, &ua_format, sizeof(*fp));
228
229 fp->iface = altsd->bInterfaceNumber;
230 fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress;
231 fp->ep_attr = get_endpoint(alts, 0)->bmAttributes;
232 fp->datainterval = 0;
233 fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
234
235 switch (fp->maxpacksize) {
236 case 0x120:
237 fp->rate_max = fp->rate_min = 44100;
238 break;
239 case 0x138:
240 case 0x140:
241 fp->rate_max = fp->rate_min = 48000;
242 break;
243 case 0x258:
244 case 0x260:
245 fp->rate_max = fp->rate_min = 96000;
246 break;
247 default:
248 snd_printk(KERN_ERR "unknown sample rate\n");
249 kfree(fp);
250 return -ENXIO;
251 }
252
253 stream = (fp->endpoint & USB_DIR_IN)
254 ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
255 err = snd_usb_add_audio_endpoint(chip, stream, fp);
256 if (err < 0) {
257 kfree(fp);
258 return err;
259 }
260 usb_set_interface(chip->dev, fp->iface, 0);
261 return 0;
262}
263
264/*
265 * audio-interface quirks
266 *
267 * returns zero if no standard audio/MIDI parsing is needed.
268 * returns a postive value if standard audio/midi interfaces are parsed
269 * after this.
270 * returns a negative value at error.
271 */
272int snd_usb_create_quirk(struct snd_usb_audio *chip,
273 struct usb_interface *iface,
274 struct usb_driver *driver,
275 const struct snd_usb_audio_quirk *quirk)
276{
277 typedef int (*quirk_func_t)(struct snd_usb_audio *,
278 struct usb_interface *,
279 struct usb_driver *,
280 const struct snd_usb_audio_quirk *);
281 static const quirk_func_t quirk_funcs[] = {
282 [QUIRK_IGNORE_INTERFACE] = ignore_interface_quirk,
283 [QUIRK_COMPOSITE] = create_composite_quirk,
284 [QUIRK_MIDI_STANDARD_INTERFACE] = create_any_midi_quirk,
285 [QUIRK_MIDI_FIXED_ENDPOINT] = create_any_midi_quirk,
286 [QUIRK_MIDI_YAMAHA] = create_any_midi_quirk,
287 [QUIRK_MIDI_MIDIMAN] = create_any_midi_quirk,
288 [QUIRK_MIDI_NOVATION] = create_any_midi_quirk,
289 [QUIRK_MIDI_FASTLANE] = create_any_midi_quirk,
290 [QUIRK_MIDI_EMAGIC] = create_any_midi_quirk,
291 [QUIRK_MIDI_CME] = create_any_midi_quirk,
292 [QUIRK_MIDI_AKAI] = create_any_midi_quirk,
293 [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk,
294 [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk,
295 [QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk,
296 [QUIRK_AUDIO_ALIGN_TRANSFER] = create_align_transfer_quirk
297 };
298
299 if (quirk->type < QUIRK_TYPE_COUNT) {
300 return quirk_funcs[quirk->type](chip, iface, driver, quirk);
301 } else {
302 snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type);
303 return -ENXIO;
304 }
305}
306
307/*
308 * boot quirks
309 */
310
311#define EXTIGY_FIRMWARE_SIZE_OLD 794
312#define EXTIGY_FIRMWARE_SIZE_NEW 483
313
314static int snd_usb_extigy_boot_quirk(struct usb_device *dev, struct usb_interface *intf)
315{
316 struct usb_host_config *config = dev->actconfig;
317 int err;
318
319 if (le16_to_cpu(get_cfg_desc(config)->wTotalLength) == EXTIGY_FIRMWARE_SIZE_OLD ||
320 le16_to_cpu(get_cfg_desc(config)->wTotalLength) == EXTIGY_FIRMWARE_SIZE_NEW) {
321 snd_printdd("sending Extigy boot sequence...\n");
322 /* Send message to force it to reconnect with full interface. */
323 err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev,0),
324 0x10, 0x43, 0x0001, 0x000a, NULL, 0, 1000);
325 if (err < 0) snd_printdd("error sending boot message: %d\n", err);
326 err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
327 &dev->descriptor, sizeof(dev->descriptor));
328 config = dev->actconfig;
329 if (err < 0) snd_printdd("error usb_get_descriptor: %d\n", err);
330 err = usb_reset_configuration(dev);
331 if (err < 0) snd_printdd("error usb_reset_configuration: %d\n", err);
332 snd_printdd("extigy_boot: new boot length = %d\n",
333 le16_to_cpu(get_cfg_desc(config)->wTotalLength));
334 return -ENODEV; /* quit this anyway */
335 }
336 return 0;
337}
338
339static int snd_usb_audigy2nx_boot_quirk(struct usb_device *dev)
340{
341 u8 buf = 1;
342
343 snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), 0x2a,
344 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_OTHER,
345 0, 0, &buf, 1, 1000);
346 if (buf == 0) {
347 snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), 0x29,
348 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
349 1, 2000, NULL, 0, 1000);
350 return -ENODEV;
351 }
352 return 0;
353}
354
355/*
356 * C-Media CM106/CM106+ have four 16-bit internal registers that are nicely
357 * documented in the device's data sheet.
358 */
359static int snd_usb_cm106_write_int_reg(struct usb_device *dev, int reg, u16 value)
360{
361 u8 buf[4];
362 buf[0] = 0x20;
363 buf[1] = value & 0xff;
364 buf[2] = (value >> 8) & 0xff;
365 buf[3] = reg;
366 return snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), USB_REQ_SET_CONFIGURATION,
367 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_ENDPOINT,
368 0, 0, &buf, 4, 1000);
369}
370
371static int snd_usb_cm106_boot_quirk(struct usb_device *dev)
372{
373 /*
374 * Enable line-out driver mode, set headphone source to front
375 * channels, enable stereo mic.
376 */
377 return snd_usb_cm106_write_int_reg(dev, 2, 0x8004);
378}
379
380/*
381 * C-Media CM6206 is based on CM106 with two additional
382 * registers that are not documented in the data sheet.
383 * Values here are chosen based on sniffing USB traffic
384 * under Windows.
385 */
386static int snd_usb_cm6206_boot_quirk(struct usb_device *dev)
387{
388 int err, reg;
389 int val[] = {0x200c, 0x3000, 0xf800, 0x143f, 0x0000, 0x3000};
390
391 for (reg = 0; reg < ARRAY_SIZE(val); reg++) {
392 err = snd_usb_cm106_write_int_reg(dev, reg, val[reg]);
393 if (err < 0)
394 return err;
395 }
396
397 return err;
398}
399
400/*
401 * This call will put the synth in "USB send" mode, i.e it will send MIDI
402 * messages through USB (this is disabled at startup). The synth will
403 * acknowledge by sending a sysex on endpoint 0x85 and by displaying a USB
404 * sign on its LCD. Values here are chosen based on sniffing USB traffic
405 * under Windows.
406 */
407static int snd_usb_accessmusic_boot_quirk(struct usb_device *dev)
408{
409 int err, actual_length;
410
411 /* "midi send" enable */
412 static const u8 seq[] = { 0x4e, 0x73, 0x52, 0x01 };
413
414 void *buf = kmemdup(seq, ARRAY_SIZE(seq), GFP_KERNEL);
415 if (!buf)
416 return -ENOMEM;
417 err = usb_interrupt_msg(dev, usb_sndintpipe(dev, 0x05), buf,
418 ARRAY_SIZE(seq), &actual_length, 1000);
419 kfree(buf);
420 if (err < 0)
421 return err;
422
423 return 0;
424}
425
426/*
427 * Setup quirks
428 */
429#define AUDIOPHILE_SET 0x01 /* if set, parse device_setup */
430#define AUDIOPHILE_SET_DTS 0x02 /* if set, enable DTS Digital Output */
431#define AUDIOPHILE_SET_96K 0x04 /* 48-96KHz rate if set, 8-48KHz otherwise */
432#define AUDIOPHILE_SET_24B 0x08 /* 24bits sample if set, 16bits otherwise */
433#define AUDIOPHILE_SET_DI 0x10 /* if set, enable Digital Input */
434#define AUDIOPHILE_SET_MASK 0x1F /* bit mask for setup value */
435#define AUDIOPHILE_SET_24B_48K_DI 0x19 /* value for 24bits+48KHz+Digital Input */
436#define AUDIOPHILE_SET_24B_48K_NOTDI 0x09 /* value for 24bits+48KHz+No Digital Input */
437#define AUDIOPHILE_SET_16B_48K_DI 0x11 /* value for 16bits+48KHz+Digital Input */
438#define AUDIOPHILE_SET_16B_48K_NOTDI 0x01 /* value for 16bits+48KHz+No Digital Input */
439
440static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip,
441 int iface,
442 int altno)
443{
444 /* Reset ALL ifaces to 0 altsetting.
445 * Call it for every possible altsetting of every interface.
446 */
447 usb_set_interface(chip->dev, iface, 0);
448
449 if (chip->setup & AUDIOPHILE_SET) {
450 if ((chip->setup & AUDIOPHILE_SET_DTS)
451 && altno != 6)
452 return 1; /* skip this altsetting */
453 if ((chip->setup & AUDIOPHILE_SET_96K)
454 && altno != 1)
455 return 1; /* skip this altsetting */
456 if ((chip->setup & AUDIOPHILE_SET_MASK) ==
457 AUDIOPHILE_SET_24B_48K_DI && altno != 2)
458 return 1; /* skip this altsetting */
459 if ((chip->setup & AUDIOPHILE_SET_MASK) ==
460 AUDIOPHILE_SET_24B_48K_NOTDI && altno != 3)
461 return 1; /* skip this altsetting */
462 if ((chip->setup & AUDIOPHILE_SET_MASK) ==
463 AUDIOPHILE_SET_16B_48K_DI && altno != 4)
464 return 1; /* skip this altsetting */
465 if ((chip->setup & AUDIOPHILE_SET_MASK) ==
466 AUDIOPHILE_SET_16B_48K_NOTDI && altno != 5)
467 return 1; /* skip this altsetting */
468 }
469
470 return 0; /* keep this altsetting */
471}
472
473int snd_usb_apply_interface_quirk(struct snd_usb_audio *chip,
474 int iface,
475 int altno)
476{
477 /* audiophile usb: skip altsets incompatible with device_setup */
478 if (chip->usb_id == USB_ID(0x0763, 0x2003))
479 return audiophile_skip_setting_quirk(chip, iface, altno);
480
481 return 0;
482}
483
484int snd_usb_apply_boot_quirk(struct usb_device *dev,
485 struct usb_interface *intf,
486 const struct snd_usb_audio_quirk *quirk)
487{
488 u32 id = USB_ID(le16_to_cpu(dev->descriptor.idVendor),
489 le16_to_cpu(dev->descriptor.idProduct));
490
491 /* SB Extigy needs special boot-up sequence */
492 /* if more models come, this will go to the quirk list. */
493 if (id == USB_ID(0x041e, 0x3000))
494 return snd_usb_extigy_boot_quirk(dev, intf);
495
496 /* SB Audigy 2 NX needs its own boot-up magic, too */
497 if (id == USB_ID(0x041e, 0x3020))
498 return snd_usb_audigy2nx_boot_quirk(dev);
499
500 /* C-Media CM106 / Turtle Beach Audio Advantage Roadie */
501 if (id == USB_ID(0x10f5, 0x0200))
502 return snd_usb_cm106_boot_quirk(dev);
503
504 /* C-Media CM6206 / CM106-Like Sound Device */
505 if (id == USB_ID(0x0d8c, 0x0102))
506 return snd_usb_cm6206_boot_quirk(dev);
507
508 /* Access Music VirusTI Desktop */
509 if (id == USB_ID(0x133e, 0x0815))
510 return snd_usb_accessmusic_boot_quirk(dev);
511
512 return 0;
513}
514
515/*
516 * check if the device uses big-endian samples
517 */
518int snd_usb_is_big_endian_format(struct snd_usb_audio *chip, struct audioformat *fp)
519{
520 switch (chip->usb_id) {
521 case USB_ID(0x0763, 0x2001): /* M-Audio Quattro: captured data only */
522 if (fp->endpoint & USB_DIR_IN)
523 return 1;
524 break;
525 case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
526 if (chip->setup == 0x00 ||
527 fp->altsetting==1 || fp->altsetting==2 || fp->altsetting==3)
528 return 1;
529 }
530 return 0;
531}
532
533/*
534 * For E-Mu 0404USB/0202USB/TrackerPre sample rate should be set for device,
535 * not for interface.
536 */
537
538enum {
539 EMU_QUIRK_SR_44100HZ = 0,
540 EMU_QUIRK_SR_48000HZ,
541 EMU_QUIRK_SR_88200HZ,
542 EMU_QUIRK_SR_96000HZ,
543 EMU_QUIRK_SR_176400HZ,
544 EMU_QUIRK_SR_192000HZ
545};
546
547static void set_format_emu_quirk(struct snd_usb_substream *subs,
548 struct audioformat *fmt)
549{
550 unsigned char emu_samplerate_id = 0;
551
552 /* When capture is active
553 * sample rate shouldn't be changed
554 * by playback substream
555 */
556 if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) {
557 if (subs->stream->substream[SNDRV_PCM_STREAM_CAPTURE].interface != -1)
558 return;
559 }
560
561 switch (fmt->rate_min) {
562 case 48000:
563 emu_samplerate_id = EMU_QUIRK_SR_48000HZ;
564 break;
565 case 88200:
566 emu_samplerate_id = EMU_QUIRK_SR_88200HZ;
567 break;
568 case 96000:
569 emu_samplerate_id = EMU_QUIRK_SR_96000HZ;
570 break;
571 case 176400:
572 emu_samplerate_id = EMU_QUIRK_SR_176400HZ;
573 break;
574 case 192000:
575 emu_samplerate_id = EMU_QUIRK_SR_192000HZ;
576 break;
577 default:
578 emu_samplerate_id = EMU_QUIRK_SR_44100HZ;
579 break;
580 }
581 snd_emuusb_set_samplerate(subs->stream->chip, emu_samplerate_id);
582}
583
584void snd_usb_set_format_quirk(struct snd_usb_substream *subs,
585 struct audioformat *fmt)
586{
587 switch (subs->stream->chip->usb_id) {
588 case USB_ID(0x041e, 0x3f02): /* E-Mu 0202 USB */
589 case USB_ID(0x041e, 0x3f04): /* E-Mu 0404 USB */
590 case USB_ID(0x041e, 0x3f0a): /* E-Mu Tracker Pre */
591 set_format_emu_quirk(subs, fmt);
592 break;
593 }
594}
595
diff --git a/sound/usb/quirks.h b/sound/usb/quirks.h
new file mode 100644
index 000000000000..03e5e94098cd
--- /dev/null
+++ b/sound/usb/quirks.h
@@ -0,0 +1,23 @@
1#ifndef __USBAUDIO_QUIRKS_H
2#define __USBAUDIO_QUIRKS_H
3
4int snd_usb_create_quirk(struct snd_usb_audio *chip,
5 struct usb_interface *iface,
6 struct usb_driver *driver,
7 const struct snd_usb_audio_quirk *quirk);
8
9int snd_usb_apply_interface_quirk(struct snd_usb_audio *chip,
10 int iface,
11 int altno);
12
13int snd_usb_apply_boot_quirk(struct usb_device *dev,
14 struct usb_interface *intf,
15 const struct snd_usb_audio_quirk *quirk);
16
17void snd_usb_set_format_quirk(struct snd_usb_substream *subs,
18 struct audioformat *fmt);
19
20int snd_usb_is_big_endian_format(struct snd_usb_audio *chip,
21 struct audioformat *fp);
22
23#endif /* __USBAUDIO_QUIRKS_H */
diff --git a/sound/usb/urb.c b/sound/usb/urb.c
new file mode 100644
index 000000000000..de607d4411ac
--- /dev/null
+++ b/sound/usb/urb.c
@@ -0,0 +1,995 @@
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 as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15 *
16 */
17
18#include <linux/gfp.h>
19#include <linux/init.h>
20#include <linux/usb.h>
21#include <linux/usb/audio.h>
22
23#include <sound/core.h>
24#include <sound/pcm.h>
25
26#include "usbaudio.h"
27#include "helper.h"
28#include "card.h"
29#include "urb.h"
30#include "pcm.h"
31
32/*
33 * convert a sampling rate into our full speed format (fs/1000 in Q16.16)
34 * this will overflow at approx 524 kHz
35 */
36static inline unsigned get_usb_full_speed_rate(unsigned int rate)
37{
38 return ((rate << 13) + 62) / 125;
39}
40
41/*
42 * convert a sampling rate into USB high speed format (fs/8000 in Q16.16)
43 * this will overflow at approx 4 MHz
44 */
45static inline unsigned get_usb_high_speed_rate(unsigned int rate)
46{
47 return ((rate << 10) + 62) / 125;
48}
49
50/*
51 * unlink active urbs.
52 */
53static int deactivate_urbs(struct snd_usb_substream *subs, int force, int can_sleep)
54{
55 struct snd_usb_audio *chip = subs->stream->chip;
56 unsigned int i;
57 int async;
58
59 subs->running = 0;
60
61 if (!force && subs->stream->chip->shutdown) /* to be sure... */
62 return -EBADFD;
63
64 async = !can_sleep && chip->async_unlink;
65
66 if (!async && in_interrupt())
67 return 0;
68
69 for (i = 0; i < subs->nurbs; i++) {
70 if (test_bit(i, &subs->active_mask)) {
71 if (!test_and_set_bit(i, &subs->unlink_mask)) {
72 struct urb *u = subs->dataurb[i].urb;
73 if (async)
74 usb_unlink_urb(u);
75 else
76 usb_kill_urb(u);
77 }
78 }
79 }
80 if (subs->syncpipe) {
81 for (i = 0; i < SYNC_URBS; i++) {
82 if (test_bit(i+16, &subs->active_mask)) {
83 if (!test_and_set_bit(i+16, &subs->unlink_mask)) {
84 struct urb *u = subs->syncurb[i].urb;
85 if (async)
86 usb_unlink_urb(u);
87 else
88 usb_kill_urb(u);
89 }
90 }
91 }
92 }
93 return 0;
94}
95
96
97/*
98 * release a urb data
99 */
100static void release_urb_ctx(struct snd_urb_ctx *u)
101{
102 if (u->urb) {
103 if (u->buffer_size)
104 usb_free_coherent(u->subs->dev, u->buffer_size,
105 u->urb->transfer_buffer,
106 u->urb->transfer_dma);
107 usb_free_urb(u->urb);
108 u->urb = NULL;
109 }
110}
111
112/*
113 * wait until all urbs are processed.
114 */
115static int wait_clear_urbs(struct snd_usb_substream *subs)
116{
117 unsigned long end_time = jiffies + msecs_to_jiffies(1000);
118 unsigned int i;
119 int alive;
120
121 do {
122 alive = 0;
123 for (i = 0; i < subs->nurbs; i++) {
124 if (test_bit(i, &subs->active_mask))
125 alive++;
126 }
127 if (subs->syncpipe) {
128 for (i = 0; i < SYNC_URBS; i++) {
129 if (test_bit(i + 16, &subs->active_mask))
130 alive++;
131 }
132 }
133 if (! alive)
134 break;
135 schedule_timeout_uninterruptible(1);
136 } while (time_before(jiffies, end_time));
137 if (alive)
138 snd_printk(KERN_ERR "timeout: still %d active urbs..\n", alive);
139 return 0;
140}
141
142/*
143 * release a substream
144 */
145void snd_usb_release_substream_urbs(struct snd_usb_substream *subs, int force)
146{
147 int i;
148
149 /* stop urbs (to be sure) */
150 deactivate_urbs(subs, force, 1);
151 wait_clear_urbs(subs);
152
153 for (i = 0; i < MAX_URBS; i++)
154 release_urb_ctx(&subs->dataurb[i]);
155 for (i = 0; i < SYNC_URBS; i++)
156 release_urb_ctx(&subs->syncurb[i]);
157 usb_free_coherent(subs->dev, SYNC_URBS * 4,
158 subs->syncbuf, subs->sync_dma);
159 subs->syncbuf = NULL;
160 subs->nurbs = 0;
161}
162
163/*
164 * complete callback from data urb
165 */
166static void snd_complete_urb(struct urb *urb)
167{
168 struct snd_urb_ctx *ctx = urb->context;
169 struct snd_usb_substream *subs = ctx->subs;
170 struct snd_pcm_substream *substream = ctx->subs->pcm_substream;
171 int err = 0;
172
173 if ((subs->running && subs->ops.retire(subs, substream->runtime, urb)) ||
174 !subs->running || /* can be stopped during retire callback */
175 (err = subs->ops.prepare(subs, substream->runtime, urb)) < 0 ||
176 (err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
177 clear_bit(ctx->index, &subs->active_mask);
178 if (err < 0) {
179 snd_printd(KERN_ERR "cannot submit urb (err = %d)\n", err);
180 snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
181 }
182 }
183}
184
185
186/*
187 * complete callback from sync urb
188 */
189static void snd_complete_sync_urb(struct urb *urb)
190{
191 struct snd_urb_ctx *ctx = urb->context;
192 struct snd_usb_substream *subs = ctx->subs;
193 struct snd_pcm_substream *substream = ctx->subs->pcm_substream;
194 int err = 0;
195
196 if ((subs->running && subs->ops.retire_sync(subs, substream->runtime, urb)) ||
197 !subs->running || /* can be stopped during retire callback */
198 (err = subs->ops.prepare_sync(subs, substream->runtime, urb)) < 0 ||
199 (err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
200 clear_bit(ctx->index + 16, &subs->active_mask);
201 if (err < 0) {
202 snd_printd(KERN_ERR "cannot submit sync urb (err = %d)\n", err);
203 snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
204 }
205 }
206}
207
208
209/*
210 * initialize a substream for plaback/capture
211 */
212int snd_usb_init_substream_urbs(struct snd_usb_substream *subs,
213 unsigned int period_bytes,
214 unsigned int rate,
215 unsigned int frame_bits)
216{
217 unsigned int maxsize, i;
218 int is_playback = subs->direction == SNDRV_PCM_STREAM_PLAYBACK;
219 unsigned int urb_packs, total_packs, packs_per_ms;
220 struct snd_usb_audio *chip = subs->stream->chip;
221
222 /* calculate the frequency in 16.16 format */
223 if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL)
224 subs->freqn = get_usb_full_speed_rate(rate);
225 else
226 subs->freqn = get_usb_high_speed_rate(rate);
227 subs->freqm = subs->freqn;
228 /* calculate max. frequency */
229 if (subs->maxpacksize) {
230 /* whatever fits into a max. size packet */
231 maxsize = subs->maxpacksize;
232 subs->freqmax = (maxsize / (frame_bits >> 3))
233 << (16 - subs->datainterval);
234 } else {
235 /* no max. packet size: just take 25% higher than nominal */
236 subs->freqmax = subs->freqn + (subs->freqn >> 2);
237 maxsize = ((subs->freqmax + 0xffff) * (frame_bits >> 3))
238 >> (16 - subs->datainterval);
239 }
240 subs->phase = 0;
241
242 if (subs->fill_max)
243 subs->curpacksize = subs->maxpacksize;
244 else
245 subs->curpacksize = maxsize;
246
247 if (snd_usb_get_speed(subs->dev) == USB_SPEED_HIGH)
248 packs_per_ms = 8 >> subs->datainterval;
249 else
250 packs_per_ms = 1;
251
252 if (is_playback) {
253 urb_packs = max(chip->nrpacks, 1);
254 urb_packs = min(urb_packs, (unsigned int)MAX_PACKS);
255 } else
256 urb_packs = 1;
257 urb_packs *= packs_per_ms;
258 if (subs->syncpipe)
259 urb_packs = min(urb_packs, 1U << subs->syncinterval);
260
261 /* decide how many packets to be used */
262 if (is_playback) {
263 unsigned int minsize, maxpacks;
264 /* determine how small a packet can be */
265 minsize = (subs->freqn >> (16 - subs->datainterval))
266 * (frame_bits >> 3);
267 /* with sync from device, assume it can be 12% lower */
268 if (subs->syncpipe)
269 minsize -= minsize >> 3;
270 minsize = max(minsize, 1u);
271 total_packs = (period_bytes + minsize - 1) / minsize;
272 /* we need at least two URBs for queueing */
273 if (total_packs < 2) {
274 total_packs = 2;
275 } else {
276 /* and we don't want too long a queue either */
277 maxpacks = max(MAX_QUEUE * packs_per_ms, urb_packs * 2);
278 total_packs = min(total_packs, maxpacks);
279 }
280 } else {
281 while (urb_packs > 1 && urb_packs * maxsize >= period_bytes)
282 urb_packs >>= 1;
283 total_packs = MAX_URBS * urb_packs;
284 }
285 subs->nurbs = (total_packs + urb_packs - 1) / urb_packs;
286 if (subs->nurbs > MAX_URBS) {
287 /* too much... */
288 subs->nurbs = MAX_URBS;
289 total_packs = MAX_URBS * urb_packs;
290 } else if (subs->nurbs < 2) {
291 /* too little - we need at least two packets
292 * to ensure contiguous playback/capture
293 */
294 subs->nurbs = 2;
295 }
296
297 /* allocate and initialize data urbs */
298 for (i = 0; i < subs->nurbs; i++) {
299 struct snd_urb_ctx *u = &subs->dataurb[i];
300 u->index = i;
301 u->subs = subs;
302 u->packets = (i + 1) * total_packs / subs->nurbs
303 - i * total_packs / subs->nurbs;
304 u->buffer_size = maxsize * u->packets;
305 if (subs->fmt_type == UAC_FORMAT_TYPE_II)
306 u->packets++; /* for transfer delimiter */
307 u->urb = usb_alloc_urb(u->packets, GFP_KERNEL);
308 if (!u->urb)
309 goto out_of_memory;
310 u->urb->transfer_buffer =
311 usb_alloc_coherent(subs->dev, u->buffer_size,
312 GFP_KERNEL, &u->urb->transfer_dma);
313 if (!u->urb->transfer_buffer)
314 goto out_of_memory;
315 u->urb->pipe = subs->datapipe;
316 u->urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
317 u->urb->interval = 1 << subs->datainterval;
318 u->urb->context = u;
319 u->urb->complete = snd_complete_urb;
320 }
321
322 if (subs->syncpipe) {
323 /* allocate and initialize sync urbs */
324 subs->syncbuf = usb_alloc_coherent(subs->dev, SYNC_URBS * 4,
325 GFP_KERNEL, &subs->sync_dma);
326 if (!subs->syncbuf)
327 goto out_of_memory;
328 for (i = 0; i < SYNC_URBS; i++) {
329 struct snd_urb_ctx *u = &subs->syncurb[i];
330 u->index = i;
331 u->subs = subs;
332 u->packets = 1;
333 u->urb = usb_alloc_urb(1, GFP_KERNEL);
334 if (!u->urb)
335 goto out_of_memory;
336 u->urb->transfer_buffer = subs->syncbuf + i * 4;
337 u->urb->transfer_dma = subs->sync_dma + i * 4;
338 u->urb->transfer_buffer_length = 4;
339 u->urb->pipe = subs->syncpipe;
340 u->urb->transfer_flags = URB_ISO_ASAP |
341 URB_NO_TRANSFER_DMA_MAP;
342 u->urb->number_of_packets = 1;
343 u->urb->interval = 1 << subs->syncinterval;
344 u->urb->context = u;
345 u->urb->complete = snd_complete_sync_urb;
346 }
347 }
348 return 0;
349
350out_of_memory:
351 snd_usb_release_substream_urbs(subs, 0);
352 return -ENOMEM;
353}
354
355/*
356 * prepare urb for full speed capture sync pipe
357 *
358 * fill the length and offset of each urb descriptor.
359 * the fixed 10.14 frequency is passed through the pipe.
360 */
361static int prepare_capture_sync_urb(struct snd_usb_substream *subs,
362 struct snd_pcm_runtime *runtime,
363 struct urb *urb)
364{
365 unsigned char *cp = urb->transfer_buffer;
366 struct snd_urb_ctx *ctx = urb->context;
367
368 urb->dev = ctx->subs->dev; /* we need to set this at each time */
369 urb->iso_frame_desc[0].length = 3;
370 urb->iso_frame_desc[0].offset = 0;
371 cp[0] = subs->freqn >> 2;
372 cp[1] = subs->freqn >> 10;
373 cp[2] = subs->freqn >> 18;
374 return 0;
375}
376
377/*
378 * prepare urb for high speed capture sync pipe
379 *
380 * fill the length and offset of each urb descriptor.
381 * the fixed 12.13 frequency is passed as 16.16 through the pipe.
382 */
383static int prepare_capture_sync_urb_hs(struct snd_usb_substream *subs,
384 struct snd_pcm_runtime *runtime,
385 struct urb *urb)
386{
387 unsigned char *cp = urb->transfer_buffer;
388 struct snd_urb_ctx *ctx = urb->context;
389
390 urb->dev = ctx->subs->dev; /* we need to set this at each time */
391 urb->iso_frame_desc[0].length = 4;
392 urb->iso_frame_desc[0].offset = 0;
393 cp[0] = subs->freqn;
394 cp[1] = subs->freqn >> 8;
395 cp[2] = subs->freqn >> 16;
396 cp[3] = subs->freqn >> 24;
397 return 0;
398}
399
400/*
401 * process after capture sync complete
402 * - nothing to do
403 */
404static int retire_capture_sync_urb(struct snd_usb_substream *subs,
405 struct snd_pcm_runtime *runtime,
406 struct urb *urb)
407{
408 return 0;
409}
410
411/*
412 * prepare urb for capture data pipe
413 *
414 * fill the offset and length of each descriptor.
415 *
416 * we use a temporary buffer to write the captured data.
417 * since the length of written data is determined by host, we cannot
418 * write onto the pcm buffer directly... the data is thus copied
419 * later at complete callback to the global buffer.
420 */
421static int prepare_capture_urb(struct snd_usb_substream *subs,
422 struct snd_pcm_runtime *runtime,
423 struct urb *urb)
424{
425 int i, offs;
426 struct snd_urb_ctx *ctx = urb->context;
427
428 offs = 0;
429 urb->dev = ctx->subs->dev; /* we need to set this at each time */
430 for (i = 0; i < ctx->packets; i++) {
431 urb->iso_frame_desc[i].offset = offs;
432 urb->iso_frame_desc[i].length = subs->curpacksize;
433 offs += subs->curpacksize;
434 }
435 urb->transfer_buffer_length = offs;
436 urb->number_of_packets = ctx->packets;
437 return 0;
438}
439
440/*
441 * process after capture complete
442 *
443 * copy the data from each desctiptor to the pcm buffer, and
444 * update the current position.
445 */
446static int retire_capture_urb(struct snd_usb_substream *subs,
447 struct snd_pcm_runtime *runtime,
448 struct urb *urb)
449{
450 unsigned long flags;
451 unsigned char *cp;
452 int i;
453 unsigned int stride, frames, bytes, oldptr;
454 int period_elapsed = 0;
455
456 stride = runtime->frame_bits >> 3;
457
458 for (i = 0; i < urb->number_of_packets; i++) {
459 cp = (unsigned char *)urb->transfer_buffer + urb->iso_frame_desc[i].offset;
460 if (urb->iso_frame_desc[i].status) {
461 snd_printd(KERN_ERR "frame %d active: %d\n", i, urb->iso_frame_desc[i].status);
462 // continue;
463 }
464 bytes = urb->iso_frame_desc[i].actual_length;
465 frames = bytes / stride;
466 if (!subs->txfr_quirk)
467 bytes = frames * stride;
468 if (bytes % (runtime->sample_bits >> 3) != 0) {
469#ifdef CONFIG_SND_DEBUG_VERBOSE
470 int oldbytes = bytes;
471#endif
472 bytes = frames * stride;
473 snd_printdd(KERN_ERR "Corrected urb data len. %d->%d\n",
474 oldbytes, bytes);
475 }
476 /* update the current pointer */
477 spin_lock_irqsave(&subs->lock, flags);
478 oldptr = subs->hwptr_done;
479 subs->hwptr_done += bytes;
480 if (subs->hwptr_done >= runtime->buffer_size * stride)
481 subs->hwptr_done -= runtime->buffer_size * stride;
482 frames = (bytes + (oldptr % stride)) / stride;
483 subs->transfer_done += frames;
484 if (subs->transfer_done >= runtime->period_size) {
485 subs->transfer_done -= runtime->period_size;
486 period_elapsed = 1;
487 }
488 spin_unlock_irqrestore(&subs->lock, flags);
489 /* copy a data chunk */
490 if (oldptr + bytes > runtime->buffer_size * stride) {
491 unsigned int bytes1 =
492 runtime->buffer_size * stride - oldptr;
493 memcpy(runtime->dma_area + oldptr, cp, bytes1);
494 memcpy(runtime->dma_area, cp + bytes1, bytes - bytes1);
495 } else {
496 memcpy(runtime->dma_area + oldptr, cp, bytes);
497 }
498 }
499 if (period_elapsed)
500 snd_pcm_period_elapsed(subs->pcm_substream);
501 return 0;
502}
503
504/*
505 * Process after capture complete when paused. Nothing to do.
506 */
507static int retire_paused_capture_urb(struct snd_usb_substream *subs,
508 struct snd_pcm_runtime *runtime,
509 struct urb *urb)
510{
511 return 0;
512}
513
514
515/*
516 * prepare urb for full speed playback sync pipe
517 *
518 * set up the offset and length to receive the current frequency.
519 */
520
521static int prepare_playback_sync_urb(struct snd_usb_substream *subs,
522 struct snd_pcm_runtime *runtime,
523 struct urb *urb)
524{
525 struct snd_urb_ctx *ctx = urb->context;
526
527 urb->dev = ctx->subs->dev; /* we need to set this at each time */
528 urb->iso_frame_desc[0].length = 3;
529 urb->iso_frame_desc[0].offset = 0;
530 return 0;
531}
532
533/*
534 * prepare urb for high speed playback sync pipe
535 *
536 * set up the offset and length to receive the current frequency.
537 */
538
539static int prepare_playback_sync_urb_hs(struct snd_usb_substream *subs,
540 struct snd_pcm_runtime *runtime,
541 struct urb *urb)
542{
543 struct snd_urb_ctx *ctx = urb->context;
544
545 urb->dev = ctx->subs->dev; /* we need to set this at each time */
546 urb->iso_frame_desc[0].length = 4;
547 urb->iso_frame_desc[0].offset = 0;
548 return 0;
549}
550
551/*
552 * process after full speed playback sync complete
553 *
554 * retrieve the current 10.14 frequency from pipe, and set it.
555 * the value is referred in prepare_playback_urb().
556 */
557static int retire_playback_sync_urb(struct snd_usb_substream *subs,
558 struct snd_pcm_runtime *runtime,
559 struct urb *urb)
560{
561 unsigned int f;
562 unsigned long flags;
563
564 if (urb->iso_frame_desc[0].status == 0 &&
565 urb->iso_frame_desc[0].actual_length == 3) {
566 f = combine_triple((u8*)urb->transfer_buffer) << 2;
567 if (f >= subs->freqn - subs->freqn / 8 && f <= subs->freqmax) {
568 spin_lock_irqsave(&subs->lock, flags);
569 subs->freqm = f;
570 spin_unlock_irqrestore(&subs->lock, flags);
571 }
572 }
573
574 return 0;
575}
576
577/*
578 * process after high speed playback sync complete
579 *
580 * retrieve the current 12.13 frequency from pipe, and set it.
581 * the value is referred in prepare_playback_urb().
582 */
583static int retire_playback_sync_urb_hs(struct snd_usb_substream *subs,
584 struct snd_pcm_runtime *runtime,
585 struct urb *urb)
586{
587 unsigned int f;
588 unsigned long flags;
589
590 if (urb->iso_frame_desc[0].status == 0 &&
591 urb->iso_frame_desc[0].actual_length == 4) {
592 f = combine_quad((u8*)urb->transfer_buffer) & 0x0fffffff;
593 if (f >= subs->freqn - subs->freqn / 8 && f <= subs->freqmax) {
594 spin_lock_irqsave(&subs->lock, flags);
595 subs->freqm = f;
596 spin_unlock_irqrestore(&subs->lock, flags);
597 }
598 }
599
600 return 0;
601}
602
603/*
604 * process after E-Mu 0202/0404/Tracker Pre high speed playback sync complete
605 *
606 * These devices return the number of samples per packet instead of the number
607 * of samples per microframe.
608 */
609static int retire_playback_sync_urb_hs_emu(struct snd_usb_substream *subs,
610 struct snd_pcm_runtime *runtime,
611 struct urb *urb)
612{
613 unsigned int f;
614 unsigned long flags;
615
616 if (urb->iso_frame_desc[0].status == 0 &&
617 urb->iso_frame_desc[0].actual_length == 4) {
618 f = combine_quad((u8*)urb->transfer_buffer) & 0x0fffffff;
619 f >>= subs->datainterval;
620 if (f >= subs->freqn - subs->freqn / 8 && f <= subs->freqmax) {
621 spin_lock_irqsave(&subs->lock, flags);
622 subs->freqm = f;
623 spin_unlock_irqrestore(&subs->lock, flags);
624 }
625 }
626
627 return 0;
628}
629
630/* determine the number of frames in the next packet */
631static int snd_usb_audio_next_packet_size(struct snd_usb_substream *subs)
632{
633 if (subs->fill_max)
634 return subs->maxframesize;
635 else {
636 subs->phase = (subs->phase & 0xffff)
637 + (subs->freqm << subs->datainterval);
638 return min(subs->phase >> 16, subs->maxframesize);
639 }
640}
641
642/*
643 * Prepare urb for streaming before playback starts or when paused.
644 *
645 * We don't have any data, so we send silence.
646 */
647static int prepare_nodata_playback_urb(struct snd_usb_substream *subs,
648 struct snd_pcm_runtime *runtime,
649 struct urb *urb)
650{
651 unsigned int i, offs, counts;
652 struct snd_urb_ctx *ctx = urb->context;
653 int stride = runtime->frame_bits >> 3;
654
655 offs = 0;
656 urb->dev = ctx->subs->dev;
657 for (i = 0; i < ctx->packets; ++i) {
658 counts = snd_usb_audio_next_packet_size(subs);
659 urb->iso_frame_desc[i].offset = offs * stride;
660 urb->iso_frame_desc[i].length = counts * stride;
661 offs += counts;
662 }
663 urb->number_of_packets = ctx->packets;
664 urb->transfer_buffer_length = offs * stride;
665 memset(urb->transfer_buffer,
666 runtime->format == SNDRV_PCM_FORMAT_U8 ? 0x80 : 0,
667 offs * stride);
668 return 0;
669}
670
671/*
672 * prepare urb for playback data pipe
673 *
674 * Since a URB can handle only a single linear buffer, we must use double
675 * buffering when the data to be transferred overflows the buffer boundary.
676 * To avoid inconsistencies when updating hwptr_done, we use double buffering
677 * for all URBs.
678 */
679static int prepare_playback_urb(struct snd_usb_substream *subs,
680 struct snd_pcm_runtime *runtime,
681 struct urb *urb)
682{
683 int i, stride;
684 unsigned int counts, frames, bytes;
685 unsigned long flags;
686 int period_elapsed = 0;
687 struct snd_urb_ctx *ctx = urb->context;
688
689 stride = runtime->frame_bits >> 3;
690
691 frames = 0;
692 urb->dev = ctx->subs->dev; /* we need to set this at each time */
693 urb->number_of_packets = 0;
694 spin_lock_irqsave(&subs->lock, flags);
695 for (i = 0; i < ctx->packets; i++) {
696 counts = snd_usb_audio_next_packet_size(subs);
697 /* set up descriptor */
698 urb->iso_frame_desc[i].offset = frames * stride;
699 urb->iso_frame_desc[i].length = counts * stride;
700 frames += counts;
701 urb->number_of_packets++;
702 subs->transfer_done += counts;
703 if (subs->transfer_done >= runtime->period_size) {
704 subs->transfer_done -= runtime->period_size;
705 period_elapsed = 1;
706 if (subs->fmt_type == UAC_FORMAT_TYPE_II) {
707 if (subs->transfer_done > 0) {
708 /* FIXME: fill-max mode is not
709 * supported yet */
710 frames -= subs->transfer_done;
711 counts -= subs->transfer_done;
712 urb->iso_frame_desc[i].length =
713 counts * stride;
714 subs->transfer_done = 0;
715 }
716 i++;
717 if (i < ctx->packets) {
718 /* add a transfer delimiter */
719 urb->iso_frame_desc[i].offset =
720 frames * stride;
721 urb->iso_frame_desc[i].length = 0;
722 urb->number_of_packets++;
723 }
724 break;
725 }
726 }
727 if (period_elapsed) /* finish at the period boundary */
728 break;
729 }
730 bytes = frames * stride;
731 if (subs->hwptr_done + bytes > runtime->buffer_size * stride) {
732 /* err, the transferred area goes over buffer boundary. */
733 unsigned int bytes1 =
734 runtime->buffer_size * stride - subs->hwptr_done;
735 memcpy(urb->transfer_buffer,
736 runtime->dma_area + subs->hwptr_done, bytes1);
737 memcpy(urb->transfer_buffer + bytes1,
738 runtime->dma_area, bytes - bytes1);
739 } else {
740 memcpy(urb->transfer_buffer,
741 runtime->dma_area + subs->hwptr_done, bytes);
742 }
743 subs->hwptr_done += bytes;
744 if (subs->hwptr_done >= runtime->buffer_size * stride)
745 subs->hwptr_done -= runtime->buffer_size * stride;
746 runtime->delay += frames;
747 spin_unlock_irqrestore(&subs->lock, flags);
748 urb->transfer_buffer_length = bytes;
749 if (period_elapsed)
750 snd_pcm_period_elapsed(subs->pcm_substream);
751 return 0;
752}
753
754/*
755 * process after playback data complete
756 * - decrease the delay count again
757 */
758static int retire_playback_urb(struct snd_usb_substream *subs,
759 struct snd_pcm_runtime *runtime,
760 struct urb *urb)
761{
762 unsigned long flags;
763 int stride = runtime->frame_bits >> 3;
764 int processed = urb->transfer_buffer_length / stride;
765
766 spin_lock_irqsave(&subs->lock, flags);
767 if (processed > runtime->delay)
768 runtime->delay = 0;
769 else
770 runtime->delay -= processed;
771 spin_unlock_irqrestore(&subs->lock, flags);
772 return 0;
773}
774
775static const char *usb_error_string(int err)
776{
777 switch (err) {
778 case -ENODEV:
779 return "no device";
780 case -ENOENT:
781 return "endpoint not enabled";
782 case -EPIPE:
783 return "endpoint stalled";
784 case -ENOSPC:
785 return "not enough bandwidth";
786 case -ESHUTDOWN:
787 return "device disabled";
788 case -EHOSTUNREACH:
789 return "device suspended";
790 case -EINVAL:
791 case -EAGAIN:
792 case -EFBIG:
793 case -EMSGSIZE:
794 return "internal error";
795 default:
796 return "unknown error";
797 }
798}
799
800/*
801 * set up and start data/sync urbs
802 */
803static int start_urbs(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime)
804{
805 unsigned int i;
806 int err;
807
808 if (subs->stream->chip->shutdown)
809 return -EBADFD;
810
811 for (i = 0; i < subs->nurbs; i++) {
812 if (snd_BUG_ON(!subs->dataurb[i].urb))
813 return -EINVAL;
814 if (subs->ops.prepare(subs, runtime, subs->dataurb[i].urb) < 0) {
815 snd_printk(KERN_ERR "cannot prepare datapipe for urb %d\n", i);
816 goto __error;
817 }
818 }
819 if (subs->syncpipe) {
820 for (i = 0; i < SYNC_URBS; i++) {
821 if (snd_BUG_ON(!subs->syncurb[i].urb))
822 return -EINVAL;
823 if (subs->ops.prepare_sync(subs, runtime, subs->syncurb[i].urb) < 0) {
824 snd_printk(KERN_ERR "cannot prepare syncpipe for urb %d\n", i);
825 goto __error;
826 }
827 }
828 }
829
830 subs->active_mask = 0;
831 subs->unlink_mask = 0;
832 subs->running = 1;
833 for (i = 0; i < subs->nurbs; i++) {
834 err = usb_submit_urb(subs->dataurb[i].urb, GFP_ATOMIC);
835 if (err < 0) {
836 snd_printk(KERN_ERR "cannot submit datapipe "
837 "for urb %d, error %d: %s\n",
838 i, err, usb_error_string(err));
839 goto __error;
840 }
841 set_bit(i, &subs->active_mask);
842 }
843 if (subs->syncpipe) {
844 for (i = 0; i < SYNC_URBS; i++) {
845 err = usb_submit_urb(subs->syncurb[i].urb, GFP_ATOMIC);
846 if (err < 0) {
847 snd_printk(KERN_ERR "cannot submit syncpipe "
848 "for urb %d, error %d: %s\n",
849 i, err, usb_error_string(err));
850 goto __error;
851 }
852 set_bit(i + 16, &subs->active_mask);
853 }
854 }
855 return 0;
856
857 __error:
858 // snd_pcm_stop(subs->pcm_substream, SNDRV_PCM_STATE_XRUN);
859 deactivate_urbs(subs, 0, 0);
860 return -EPIPE;
861}
862
863
864/*
865 */
866static struct snd_urb_ops audio_urb_ops[2] = {
867 {
868 .prepare = prepare_nodata_playback_urb,
869 .retire = retire_playback_urb,
870 .prepare_sync = prepare_playback_sync_urb,
871 .retire_sync = retire_playback_sync_urb,
872 },
873 {
874 .prepare = prepare_capture_urb,
875 .retire = retire_capture_urb,
876 .prepare_sync = prepare_capture_sync_urb,
877 .retire_sync = retire_capture_sync_urb,
878 },
879};
880
881static struct snd_urb_ops audio_urb_ops_high_speed[2] = {
882 {
883 .prepare = prepare_nodata_playback_urb,
884 .retire = retire_playback_urb,
885 .prepare_sync = prepare_playback_sync_urb_hs,
886 .retire_sync = retire_playback_sync_urb_hs,
887 },
888 {
889 .prepare = prepare_capture_urb,
890 .retire = retire_capture_urb,
891 .prepare_sync = prepare_capture_sync_urb_hs,
892 .retire_sync = retire_capture_sync_urb,
893 },
894};
895
896/*
897 * initialize the substream instance.
898 */
899
900void snd_usb_init_substream(struct snd_usb_stream *as,
901 int stream, struct audioformat *fp)
902{
903 struct snd_usb_substream *subs = &as->substream[stream];
904
905 INIT_LIST_HEAD(&subs->fmt_list);
906 spin_lock_init(&subs->lock);
907
908 subs->stream = as;
909 subs->direction = stream;
910 subs->dev = as->chip->dev;
911 subs->txfr_quirk = as->chip->txfr_quirk;
912 if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) {
913 subs->ops = audio_urb_ops[stream];
914 } else {
915 subs->ops = audio_urb_ops_high_speed[stream];
916 switch (as->chip->usb_id) {
917 case USB_ID(0x041e, 0x3f02): /* E-Mu 0202 USB */
918 case USB_ID(0x041e, 0x3f04): /* E-Mu 0404 USB */
919 case USB_ID(0x041e, 0x3f0a): /* E-Mu Tracker Pre */
920 subs->ops.retire_sync = retire_playback_sync_urb_hs_emu;
921 break;
922 case USB_ID(0x0763, 0x2080): /* M-Audio Fast Track Ultra 8 */
923 case USB_ID(0x0763, 0x2081): /* M-Audio Fast Track Ultra 8R */
924 subs->ops.prepare_sync = prepare_playback_sync_urb;
925 subs->ops.retire_sync = retire_playback_sync_urb;
926 break;
927 }
928 }
929
930 snd_usb_set_pcm_ops(as->pcm, stream);
931
932 list_add_tail(&fp->list, &subs->fmt_list);
933 subs->formats |= fp->formats;
934 subs->endpoint = fp->endpoint;
935 subs->num_formats++;
936 subs->fmt_type = fp->fmt_type;
937}
938
939int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substream, int cmd)
940{
941 struct snd_usb_substream *subs = substream->runtime->private_data;
942
943 switch (cmd) {
944 case SNDRV_PCM_TRIGGER_START:
945 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
946 subs->ops.prepare = prepare_playback_urb;
947 return 0;
948 case SNDRV_PCM_TRIGGER_STOP:
949 return deactivate_urbs(subs, 0, 0);
950 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
951 subs->ops.prepare = prepare_nodata_playback_urb;
952 return 0;
953 }
954
955 return -EINVAL;
956}
957
958int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream, int cmd)
959{
960 struct snd_usb_substream *subs = substream->runtime->private_data;
961
962 switch (cmd) {
963 case SNDRV_PCM_TRIGGER_START:
964 subs->ops.retire = retire_capture_urb;
965 return start_urbs(subs, substream->runtime);
966 case SNDRV_PCM_TRIGGER_STOP:
967 return deactivate_urbs(subs, 0, 0);
968 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
969 subs->ops.retire = retire_paused_capture_urb;
970 return 0;
971 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
972 subs->ops.retire = retire_capture_urb;
973 return 0;
974 }
975
976 return -EINVAL;
977}
978
979int snd_usb_substream_prepare(struct snd_usb_substream *subs,
980 struct snd_pcm_runtime *runtime)
981{
982 /* clear urbs (to be sure) */
983 deactivate_urbs(subs, 0, 1);
984 wait_clear_urbs(subs);
985
986 /* for playback, submit the URBs now; otherwise, the first hwptr_done
987 * updates for all URBs would happen at the same time when starting */
988 if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) {
989 subs->ops.prepare = prepare_nodata_playback_urb;
990 return start_urbs(subs, runtime);
991 }
992
993 return 0;
994}
995
diff --git a/sound/usb/urb.h b/sound/usb/urb.h
new file mode 100644
index 000000000000..888da38079cf
--- /dev/null
+++ b/sound/usb/urb.h
@@ -0,0 +1,21 @@
1#ifndef __USBAUDIO_URB_H
2#define __USBAUDIO_URB_H
3
4void snd_usb_init_substream(struct snd_usb_stream *as,
5 int stream,
6 struct audioformat *fp);
7
8int snd_usb_init_substream_urbs(struct snd_usb_substream *subs,
9 unsigned int period_bytes,
10 unsigned int rate,
11 unsigned int frame_bits);
12
13void snd_usb_release_substream_urbs(struct snd_usb_substream *subs, int force);
14
15int snd_usb_substream_prepare(struct snd_usb_substream *subs,
16 struct snd_pcm_runtime *runtime);
17
18int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substream, int cmd);
19int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream, int cmd);
20
21#endif /* __USBAUDIO_URB_H */
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
deleted file mode 100644
index 11b0826b8fe6..000000000000
--- a/sound/usb/usbaudio.c
+++ /dev/null
@@ -1,4050 +0,0 @@
1/*
2 * (Tentative) USB Audio Driver for ALSA
3 *
4 * Main and PCM part
5 *
6 * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
7 *
8 * Many codes borrowed from audio.c by
9 * Alan Cox (alan@lxorguk.ukuu.org.uk)
10 * Thomas Sailer (sailer@ife.ee.ethz.ch)
11 *
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 *
27 *
28 * NOTES:
29 *
30 * - async unlink should be used for avoiding the sleep inside lock.
31 * 2.4.22 usb-uhci seems buggy for async unlinking and results in
32 * oops. in such a cse, pass async_unlink=0 option.
33 * - the linked URBs would be preferred but not used so far because of
34 * the instability of unlinking.
35 * - type II is not supported properly. there is no device which supports
36 * this type *correctly*. SB extigy looks as if it supports, but it's
37 * indeed an AC3 stream packed in SPDIF frames (i.e. no real AC3 stream).
38 */
39
40
41#include <linux/bitops.h>
42#include <linux/init.h>
43#include <linux/list.h>
44#include <linux/slab.h>
45#include <linux/string.h>
46#include <linux/usb.h>
47#include <linux/moduleparam.h>
48#include <linux/mutex.h>
49#include <linux/usb/audio.h>
50#include <linux/usb/ch9.h>
51
52#include <sound/core.h>
53#include <sound/info.h>
54#include <sound/pcm.h>
55#include <sound/pcm_params.h>
56#include <sound/initval.h>
57
58#include "usbaudio.h"
59
60
61MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
62MODULE_DESCRIPTION("USB Audio");
63MODULE_LICENSE("GPL");
64MODULE_SUPPORTED_DEVICE("{{Generic,USB Audio}}");
65
66
67static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
68static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
69static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */
70/* Vendor/product IDs for this card */
71static int vid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 };
72static int pid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 };
73static int nrpacks = 8; /* max. number of packets per urb */
74static int async_unlink = 1;
75static int device_setup[SNDRV_CARDS]; /* device parameter for this card*/
76static int ignore_ctl_error;
77
78module_param_array(index, int, NULL, 0444);
79MODULE_PARM_DESC(index, "Index value for the USB audio adapter.");
80module_param_array(id, charp, NULL, 0444);
81MODULE_PARM_DESC(id, "ID string for the USB audio adapter.");
82module_param_array(enable, bool, NULL, 0444);
83MODULE_PARM_DESC(enable, "Enable USB audio adapter.");
84module_param_array(vid, int, NULL, 0444);
85MODULE_PARM_DESC(vid, "Vendor ID for the USB audio device.");
86module_param_array(pid, int, NULL, 0444);
87MODULE_PARM_DESC(pid, "Product ID for the USB audio device.");
88module_param(nrpacks, int, 0644);
89MODULE_PARM_DESC(nrpacks, "Max. number of packets per URB.");
90module_param(async_unlink, bool, 0444);
91MODULE_PARM_DESC(async_unlink, "Use async unlink mode.");
92module_param_array(device_setup, int, NULL, 0444);
93MODULE_PARM_DESC(device_setup, "Specific device setup (if needed).");
94module_param(ignore_ctl_error, bool, 0444);
95MODULE_PARM_DESC(ignore_ctl_error,
96 "Ignore errors from USB controller for mixer interfaces.");
97
98/*
99 * debug the h/w constraints
100 */
101/* #define HW_CONST_DEBUG */
102
103
104/*
105 *
106 */
107
108#define MAX_PACKS 20
109#define MAX_PACKS_HS (MAX_PACKS * 8) /* in high speed mode */
110#define MAX_URBS 8
111#define SYNC_URBS 4 /* always four urbs for sync */
112#define MAX_QUEUE 24 /* try not to exceed this queue length, in ms */
113
114struct audioformat {
115 struct list_head list;
116 snd_pcm_format_t format; /* format type */
117 unsigned int channels; /* # channels */
118 unsigned int fmt_type; /* USB audio format type (1-3) */
119 unsigned int frame_size; /* samples per frame for non-audio */
120 int iface; /* interface number */
121 unsigned char altsetting; /* corresponding alternate setting */
122 unsigned char altset_idx; /* array index of altenate setting */
123 unsigned char attributes; /* corresponding attributes of cs endpoint */
124 unsigned char endpoint; /* endpoint */
125 unsigned char ep_attr; /* endpoint attributes */
126 unsigned char datainterval; /* log_2 of data packet interval */
127 unsigned int maxpacksize; /* max. packet size */
128 unsigned int rates; /* rate bitmasks */
129 unsigned int rate_min, rate_max; /* min/max rates */
130 unsigned int nr_rates; /* number of rate table entries */
131 unsigned int *rate_table; /* rate table */
132};
133
134struct snd_usb_substream;
135
136struct snd_urb_ctx {
137 struct urb *urb;
138 unsigned int buffer_size; /* size of data buffer, if data URB */
139 struct snd_usb_substream *subs;
140 int index; /* index for urb array */
141 int packets; /* number of packets per urb */
142};
143
144struct snd_urb_ops {
145 int (*prepare)(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime, struct urb *u);
146 int (*retire)(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime, struct urb *u);
147 int (*prepare_sync)(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime, struct urb *u);
148 int (*retire_sync)(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime, struct urb *u);
149};
150
151struct snd_usb_substream {
152 struct snd_usb_stream *stream;
153 struct usb_device *dev;
154 struct snd_pcm_substream *pcm_substream;
155 int direction; /* playback or capture */
156 int interface; /* current interface */
157 int endpoint; /* assigned endpoint */
158 struct audioformat *cur_audiofmt; /* current audioformat pointer (for hw_params callback) */
159 unsigned int cur_rate; /* current rate (for hw_params callback) */
160 unsigned int period_bytes; /* current period bytes (for hw_params callback) */
161 unsigned int format; /* USB data format */
162 unsigned int datapipe; /* the data i/o pipe */
163 unsigned int syncpipe; /* 1 - async out or adaptive in */
164 unsigned int datainterval; /* log_2 of data packet interval */
165 unsigned int syncinterval; /* P for adaptive mode, 0 otherwise */
166 unsigned int freqn; /* nominal sampling rate in fs/fps in Q16.16 format */
167 unsigned int freqm; /* momentary sampling rate in fs/fps in Q16.16 format */
168 unsigned int freqmax; /* maximum sampling rate, used for buffer management */
169 unsigned int phase; /* phase accumulator */
170 unsigned int maxpacksize; /* max packet size in bytes */
171 unsigned int maxframesize; /* max packet size in frames */
172 unsigned int curpacksize; /* current packet size in bytes (for capture) */
173 unsigned int curframesize; /* current packet size in frames (for capture) */
174 unsigned int fill_max: 1; /* fill max packet size always */
175 unsigned int txfr_quirk:1; /* allow sub-frame alignment */
176 unsigned int fmt_type; /* USB audio format type (1-3) */
177
178 unsigned int running: 1; /* running status */
179
180 unsigned int hwptr_done; /* processed byte position in the buffer */
181 unsigned int transfer_done; /* processed frames since last period update */
182 unsigned long active_mask; /* bitmask of active urbs */
183 unsigned long unlink_mask; /* bitmask of unlinked urbs */
184
185 unsigned int nurbs; /* # urbs */
186 struct snd_urb_ctx dataurb[MAX_URBS]; /* data urb table */
187 struct snd_urb_ctx syncurb[SYNC_URBS]; /* sync urb table */
188 char *syncbuf; /* sync buffer for all sync URBs */
189 dma_addr_t sync_dma; /* DMA address of syncbuf */
190
191 u64 formats; /* format bitmasks (all or'ed) */
192 unsigned int num_formats; /* number of supported audio formats (list) */
193 struct list_head fmt_list; /* format list */
194 struct snd_pcm_hw_constraint_list rate_list; /* limited rates */
195 spinlock_t lock;
196
197 struct snd_urb_ops ops; /* callbacks (must be filled at init) */
198};
199
200
201struct snd_usb_stream {
202 struct snd_usb_audio *chip;
203 struct snd_pcm *pcm;
204 int pcm_index;
205 unsigned int fmt_type; /* USB audio format type (1-3) */
206 struct snd_usb_substream substream[2];
207 struct list_head list;
208};
209
210
211/*
212 * we keep the snd_usb_audio_t instances by ourselves for merging
213 * the all interfaces on the same card as one sound device.
214 */
215
216static DEFINE_MUTEX(register_mutex);
217static struct snd_usb_audio *usb_chip[SNDRV_CARDS];
218
219
220/*
221 * convert a sampling rate into our full speed format (fs/1000 in Q16.16)
222 * this will overflow at approx 524 kHz
223 */
224static inline unsigned get_usb_full_speed_rate(unsigned int rate)
225{
226 return ((rate << 13) + 62) / 125;
227}
228
229/*
230 * convert a sampling rate into USB high speed format (fs/8000 in Q16.16)
231 * this will overflow at approx 4 MHz
232 */
233static inline unsigned get_usb_high_speed_rate(unsigned int rate)
234{
235 return ((rate << 10) + 62) / 125;
236}
237
238/* convert our full speed USB rate into sampling rate in Hz */
239static inline unsigned get_full_speed_hz(unsigned int usb_rate)
240{
241 return (usb_rate * 125 + (1 << 12)) >> 13;
242}
243
244/* convert our high speed USB rate into sampling rate in Hz */
245static inline unsigned get_high_speed_hz(unsigned int usb_rate)
246{
247 return (usb_rate * 125 + (1 << 9)) >> 10;
248}
249
250
251/*
252 * prepare urb for full speed capture sync pipe
253 *
254 * fill the length and offset of each urb descriptor.
255 * the fixed 10.14 frequency is passed through the pipe.
256 */
257static int prepare_capture_sync_urb(struct snd_usb_substream *subs,
258 struct snd_pcm_runtime *runtime,
259 struct urb *urb)
260{
261 unsigned char *cp = urb->transfer_buffer;
262 struct snd_urb_ctx *ctx = urb->context;
263
264 urb->dev = ctx->subs->dev; /* we need to set this at each time */
265 urb->iso_frame_desc[0].length = 3;
266 urb->iso_frame_desc[0].offset = 0;
267 cp[0] = subs->freqn >> 2;
268 cp[1] = subs->freqn >> 10;
269 cp[2] = subs->freqn >> 18;
270 return 0;
271}
272
273/*
274 * prepare urb for high speed capture sync pipe
275 *
276 * fill the length and offset of each urb descriptor.
277 * the fixed 12.13 frequency is passed as 16.16 through the pipe.
278 */
279static int prepare_capture_sync_urb_hs(struct snd_usb_substream *subs,
280 struct snd_pcm_runtime *runtime,
281 struct urb *urb)
282{
283 unsigned char *cp = urb->transfer_buffer;
284 struct snd_urb_ctx *ctx = urb->context;
285
286 urb->dev = ctx->subs->dev; /* we need to set this at each time */
287 urb->iso_frame_desc[0].length = 4;
288 urb->iso_frame_desc[0].offset = 0;
289 cp[0] = subs->freqn;
290 cp[1] = subs->freqn >> 8;
291 cp[2] = subs->freqn >> 16;
292 cp[3] = subs->freqn >> 24;
293 return 0;
294}
295
296/*
297 * process after capture sync complete
298 * - nothing to do
299 */
300static int retire_capture_sync_urb(struct snd_usb_substream *subs,
301 struct snd_pcm_runtime *runtime,
302 struct urb *urb)
303{
304 return 0;
305}
306
307/*
308 * prepare urb for capture data pipe
309 *
310 * fill the offset and length of each descriptor.
311 *
312 * we use a temporary buffer to write the captured data.
313 * since the length of written data is determined by host, we cannot
314 * write onto the pcm buffer directly... the data is thus copied
315 * later at complete callback to the global buffer.
316 */
317static int prepare_capture_urb(struct snd_usb_substream *subs,
318 struct snd_pcm_runtime *runtime,
319 struct urb *urb)
320{
321 int i, offs;
322 struct snd_urb_ctx *ctx = urb->context;
323
324 offs = 0;
325 urb->dev = ctx->subs->dev; /* we need to set this at each time */
326 for (i = 0; i < ctx->packets; i++) {
327 urb->iso_frame_desc[i].offset = offs;
328 urb->iso_frame_desc[i].length = subs->curpacksize;
329 offs += subs->curpacksize;
330 }
331 urb->transfer_buffer_length = offs;
332 urb->number_of_packets = ctx->packets;
333 return 0;
334}
335
336/*
337 * process after capture complete
338 *
339 * copy the data from each desctiptor to the pcm buffer, and
340 * update the current position.
341 */
342static int retire_capture_urb(struct snd_usb_substream *subs,
343 struct snd_pcm_runtime *runtime,
344 struct urb *urb)
345{
346 unsigned long flags;
347 unsigned char *cp;
348 int i;
349 unsigned int stride, frames, bytes, oldptr;
350 int period_elapsed = 0;
351
352 stride = runtime->frame_bits >> 3;
353
354 for (i = 0; i < urb->number_of_packets; i++) {
355 cp = (unsigned char *)urb->transfer_buffer + urb->iso_frame_desc[i].offset;
356 if (urb->iso_frame_desc[i].status) {
357 snd_printd(KERN_ERR "frame %d active: %d\n", i, urb->iso_frame_desc[i].status);
358 // continue;
359 }
360 bytes = urb->iso_frame_desc[i].actual_length;
361 frames = bytes / stride;
362 if (!subs->txfr_quirk)
363 bytes = frames * stride;
364 if (bytes % (runtime->sample_bits >> 3) != 0) {
365#ifdef CONFIG_SND_DEBUG_VERBOSE
366 int oldbytes = bytes;
367#endif
368 bytes = frames * stride;
369 snd_printdd(KERN_ERR "Corrected urb data len. %d->%d\n",
370 oldbytes, bytes);
371 }
372 /* update the current pointer */
373 spin_lock_irqsave(&subs->lock, flags);
374 oldptr = subs->hwptr_done;
375 subs->hwptr_done += bytes;
376 if (subs->hwptr_done >= runtime->buffer_size * stride)
377 subs->hwptr_done -= runtime->buffer_size * stride;
378 frames = (bytes + (oldptr % stride)) / stride;
379 subs->transfer_done += frames;
380 if (subs->transfer_done >= runtime->period_size) {
381 subs->transfer_done -= runtime->period_size;
382 period_elapsed = 1;
383 }
384 spin_unlock_irqrestore(&subs->lock, flags);
385 /* copy a data chunk */
386 if (oldptr + bytes > runtime->buffer_size * stride) {
387 unsigned int bytes1 =
388 runtime->buffer_size * stride - oldptr;
389 memcpy(runtime->dma_area + oldptr, cp, bytes1);
390 memcpy(runtime->dma_area, cp + bytes1, bytes - bytes1);
391 } else {
392 memcpy(runtime->dma_area + oldptr, cp, bytes);
393 }
394 }
395 if (period_elapsed)
396 snd_pcm_period_elapsed(subs->pcm_substream);
397 return 0;
398}
399
400/*
401 * Process after capture complete when paused. Nothing to do.
402 */
403static int retire_paused_capture_urb(struct snd_usb_substream *subs,
404 struct snd_pcm_runtime *runtime,
405 struct urb *urb)
406{
407 return 0;
408}
409
410
411/*
412 * prepare urb for full speed playback sync pipe
413 *
414 * set up the offset and length to receive the current frequency.
415 */
416
417static int prepare_playback_sync_urb(struct snd_usb_substream *subs,
418 struct snd_pcm_runtime *runtime,
419 struct urb *urb)
420{
421 struct snd_urb_ctx *ctx = urb->context;
422
423 urb->dev = ctx->subs->dev; /* we need to set this at each time */
424 urb->iso_frame_desc[0].length = 3;
425 urb->iso_frame_desc[0].offset = 0;
426 return 0;
427}
428
429/*
430 * prepare urb for high speed playback sync pipe
431 *
432 * set up the offset and length to receive the current frequency.
433 */
434
435static int prepare_playback_sync_urb_hs(struct snd_usb_substream *subs,
436 struct snd_pcm_runtime *runtime,
437 struct urb *urb)
438{
439 struct snd_urb_ctx *ctx = urb->context;
440
441 urb->dev = ctx->subs->dev; /* we need to set this at each time */
442 urb->iso_frame_desc[0].length = 4;
443 urb->iso_frame_desc[0].offset = 0;
444 return 0;
445}
446
447/*
448 * process after full speed playback sync complete
449 *
450 * retrieve the current 10.14 frequency from pipe, and set it.
451 * the value is referred in prepare_playback_urb().
452 */
453static int retire_playback_sync_urb(struct snd_usb_substream *subs,
454 struct snd_pcm_runtime *runtime,
455 struct urb *urb)
456{
457 unsigned int f;
458 unsigned long flags;
459
460 if (urb->iso_frame_desc[0].status == 0 &&
461 urb->iso_frame_desc[0].actual_length == 3) {
462 f = combine_triple((u8*)urb->transfer_buffer) << 2;
463 if (f >= subs->freqn - subs->freqn / 8 && f <= subs->freqmax) {
464 spin_lock_irqsave(&subs->lock, flags);
465 subs->freqm = f;
466 spin_unlock_irqrestore(&subs->lock, flags);
467 }
468 }
469
470 return 0;
471}
472
473/*
474 * process after high speed playback sync complete
475 *
476 * retrieve the current 12.13 frequency from pipe, and set it.
477 * the value is referred in prepare_playback_urb().
478 */
479static int retire_playback_sync_urb_hs(struct snd_usb_substream *subs,
480 struct snd_pcm_runtime *runtime,
481 struct urb *urb)
482{
483 unsigned int f;
484 unsigned long flags;
485
486 if (urb->iso_frame_desc[0].status == 0 &&
487 urb->iso_frame_desc[0].actual_length == 4) {
488 f = combine_quad((u8*)urb->transfer_buffer) & 0x0fffffff;
489 if (f >= subs->freqn - subs->freqn / 8 && f <= subs->freqmax) {
490 spin_lock_irqsave(&subs->lock, flags);
491 subs->freqm = f;
492 spin_unlock_irqrestore(&subs->lock, flags);
493 }
494 }
495
496 return 0;
497}
498
499/*
500 * process after E-Mu 0202/0404/Tracker Pre high speed playback sync complete
501 *
502 * These devices return the number of samples per packet instead of the number
503 * of samples per microframe.
504 */
505static int retire_playback_sync_urb_hs_emu(struct snd_usb_substream *subs,
506 struct snd_pcm_runtime *runtime,
507 struct urb *urb)
508{
509 unsigned int f;
510 unsigned long flags;
511
512 if (urb->iso_frame_desc[0].status == 0 &&
513 urb->iso_frame_desc[0].actual_length == 4) {
514 f = combine_quad((u8*)urb->transfer_buffer) & 0x0fffffff;
515 f >>= subs->datainterval;
516 if (f >= subs->freqn - subs->freqn / 8 && f <= subs->freqmax) {
517 spin_lock_irqsave(&subs->lock, flags);
518 subs->freqm = f;
519 spin_unlock_irqrestore(&subs->lock, flags);
520 }
521 }
522
523 return 0;
524}
525
526/* determine the number of frames in the next packet */
527static int snd_usb_audio_next_packet_size(struct snd_usb_substream *subs)
528{
529 if (subs->fill_max)
530 return subs->maxframesize;
531 else {
532 subs->phase = (subs->phase & 0xffff)
533 + (subs->freqm << subs->datainterval);
534 return min(subs->phase >> 16, subs->maxframesize);
535 }
536}
537
538/*
539 * Prepare urb for streaming before playback starts or when paused.
540 *
541 * We don't have any data, so we send silence.
542 */
543static int prepare_nodata_playback_urb(struct snd_usb_substream *subs,
544 struct snd_pcm_runtime *runtime,
545 struct urb *urb)
546{
547 unsigned int i, offs, counts;
548 struct snd_urb_ctx *ctx = urb->context;
549 int stride = runtime->frame_bits >> 3;
550
551 offs = 0;
552 urb->dev = ctx->subs->dev;
553 for (i = 0; i < ctx->packets; ++i) {
554 counts = snd_usb_audio_next_packet_size(subs);
555 urb->iso_frame_desc[i].offset = offs * stride;
556 urb->iso_frame_desc[i].length = counts * stride;
557 offs += counts;
558 }
559 urb->number_of_packets = ctx->packets;
560 urb->transfer_buffer_length = offs * stride;
561 memset(urb->transfer_buffer,
562 subs->cur_audiofmt->format == SNDRV_PCM_FORMAT_U8 ? 0x80 : 0,
563 offs * stride);
564 return 0;
565}
566
567/*
568 * prepare urb for playback data pipe
569 *
570 * Since a URB can handle only a single linear buffer, we must use double
571 * buffering when the data to be transferred overflows the buffer boundary.
572 * To avoid inconsistencies when updating hwptr_done, we use double buffering
573 * for all URBs.
574 */
575static int prepare_playback_urb(struct snd_usb_substream *subs,
576 struct snd_pcm_runtime *runtime,
577 struct urb *urb)
578{
579 int i, stride;
580 unsigned int counts, frames, bytes;
581 unsigned long flags;
582 int period_elapsed = 0;
583 struct snd_urb_ctx *ctx = urb->context;
584
585 stride = runtime->frame_bits >> 3;
586
587 frames = 0;
588 urb->dev = ctx->subs->dev; /* we need to set this at each time */
589 urb->number_of_packets = 0;
590 spin_lock_irqsave(&subs->lock, flags);
591 for (i = 0; i < ctx->packets; i++) {
592 counts = snd_usb_audio_next_packet_size(subs);
593 /* set up descriptor */
594 urb->iso_frame_desc[i].offset = frames * stride;
595 urb->iso_frame_desc[i].length = counts * stride;
596 frames += counts;
597 urb->number_of_packets++;
598 subs->transfer_done += counts;
599 if (subs->transfer_done >= runtime->period_size) {
600 subs->transfer_done -= runtime->period_size;
601 period_elapsed = 1;
602 if (subs->fmt_type == UAC_FORMAT_TYPE_II) {
603 if (subs->transfer_done > 0) {
604 /* FIXME: fill-max mode is not
605 * supported yet */
606 frames -= subs->transfer_done;
607 counts -= subs->transfer_done;
608 urb->iso_frame_desc[i].length =
609 counts * stride;
610 subs->transfer_done = 0;
611 }
612 i++;
613 if (i < ctx->packets) {
614 /* add a transfer delimiter */
615 urb->iso_frame_desc[i].offset =
616 frames * stride;
617 urb->iso_frame_desc[i].length = 0;
618 urb->number_of_packets++;
619 }
620 break;
621 }
622 }
623 if (period_elapsed) /* finish at the period boundary */
624 break;
625 }
626 bytes = frames * stride;
627 if (subs->hwptr_done + bytes > runtime->buffer_size * stride) {
628 /* err, the transferred area goes over buffer boundary. */
629 unsigned int bytes1 =
630 runtime->buffer_size * stride - subs->hwptr_done;
631 memcpy(urb->transfer_buffer,
632 runtime->dma_area + subs->hwptr_done, bytes1);
633 memcpy(urb->transfer_buffer + bytes1,
634 runtime->dma_area, bytes - bytes1);
635 } else {
636 memcpy(urb->transfer_buffer,
637 runtime->dma_area + subs->hwptr_done, bytes);
638 }
639 subs->hwptr_done += bytes;
640 if (subs->hwptr_done >= runtime->buffer_size * stride)
641 subs->hwptr_done -= runtime->buffer_size * stride;
642 runtime->delay += frames;
643 spin_unlock_irqrestore(&subs->lock, flags);
644 urb->transfer_buffer_length = bytes;
645 if (period_elapsed)
646 snd_pcm_period_elapsed(subs->pcm_substream);
647 return 0;
648}
649
650/*
651 * process after playback data complete
652 * - decrease the delay count again
653 */
654static int retire_playback_urb(struct snd_usb_substream *subs,
655 struct snd_pcm_runtime *runtime,
656 struct urb *urb)
657{
658 unsigned long flags;
659 int stride = runtime->frame_bits >> 3;
660 int processed = urb->transfer_buffer_length / stride;
661
662 spin_lock_irqsave(&subs->lock, flags);
663 if (processed > runtime->delay)
664 runtime->delay = 0;
665 else
666 runtime->delay -= processed;
667 spin_unlock_irqrestore(&subs->lock, flags);
668 return 0;
669}
670
671
672/*
673 */
674static struct snd_urb_ops audio_urb_ops[2] = {
675 {
676 .prepare = prepare_nodata_playback_urb,
677 .retire = retire_playback_urb,
678 .prepare_sync = prepare_playback_sync_urb,
679 .retire_sync = retire_playback_sync_urb,
680 },
681 {
682 .prepare = prepare_capture_urb,
683 .retire = retire_capture_urb,
684 .prepare_sync = prepare_capture_sync_urb,
685 .retire_sync = retire_capture_sync_urb,
686 },
687};
688
689static struct snd_urb_ops audio_urb_ops_high_speed[2] = {
690 {
691 .prepare = prepare_nodata_playback_urb,
692 .retire = retire_playback_urb,
693 .prepare_sync = prepare_playback_sync_urb_hs,
694 .retire_sync = retire_playback_sync_urb_hs,
695 },
696 {
697 .prepare = prepare_capture_urb,
698 .retire = retire_capture_urb,
699 .prepare_sync = prepare_capture_sync_urb_hs,
700 .retire_sync = retire_capture_sync_urb,
701 },
702};
703
704/*
705 * complete callback from data urb
706 */
707static void snd_complete_urb(struct urb *urb)
708{
709 struct snd_urb_ctx *ctx = urb->context;
710 struct snd_usb_substream *subs = ctx->subs;
711 struct snd_pcm_substream *substream = ctx->subs->pcm_substream;
712 int err = 0;
713
714 if ((subs->running && subs->ops.retire(subs, substream->runtime, urb)) ||
715 !subs->running || /* can be stopped during retire callback */
716 (err = subs->ops.prepare(subs, substream->runtime, urb)) < 0 ||
717 (err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
718 clear_bit(ctx->index, &subs->active_mask);
719 if (err < 0) {
720 snd_printd(KERN_ERR "cannot submit urb (err = %d)\n", err);
721 snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
722 }
723 }
724}
725
726
727/*
728 * complete callback from sync urb
729 */
730static void snd_complete_sync_urb(struct urb *urb)
731{
732 struct snd_urb_ctx *ctx = urb->context;
733 struct snd_usb_substream *subs = ctx->subs;
734 struct snd_pcm_substream *substream = ctx->subs->pcm_substream;
735 int err = 0;
736
737 if ((subs->running && subs->ops.retire_sync(subs, substream->runtime, urb)) ||
738 !subs->running || /* can be stopped during retire callback */
739 (err = subs->ops.prepare_sync(subs, substream->runtime, urb)) < 0 ||
740 (err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
741 clear_bit(ctx->index + 16, &subs->active_mask);
742 if (err < 0) {
743 snd_printd(KERN_ERR "cannot submit sync urb (err = %d)\n", err);
744 snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
745 }
746 }
747}
748
749
750/*
751 * unlink active urbs.
752 */
753static int deactivate_urbs(struct snd_usb_substream *subs, int force, int can_sleep)
754{
755 unsigned int i;
756 int async;
757
758 subs->running = 0;
759
760 if (!force && subs->stream->chip->shutdown) /* to be sure... */
761 return -EBADFD;
762
763 async = !can_sleep && async_unlink;
764
765 if (!async && in_interrupt())
766 return 0;
767
768 for (i = 0; i < subs->nurbs; i++) {
769 if (test_bit(i, &subs->active_mask)) {
770 if (!test_and_set_bit(i, &subs->unlink_mask)) {
771 struct urb *u = subs->dataurb[i].urb;
772 if (async)
773 usb_unlink_urb(u);
774 else
775 usb_kill_urb(u);
776 }
777 }
778 }
779 if (subs->syncpipe) {
780 for (i = 0; i < SYNC_URBS; i++) {
781 if (test_bit(i+16, &subs->active_mask)) {
782 if (!test_and_set_bit(i+16, &subs->unlink_mask)) {
783 struct urb *u = subs->syncurb[i].urb;
784 if (async)
785 usb_unlink_urb(u);
786 else
787 usb_kill_urb(u);
788 }
789 }
790 }
791 }
792 return 0;
793}
794
795
796static const char *usb_error_string(int err)
797{
798 switch (err) {
799 case -ENODEV:
800 return "no device";
801 case -ENOENT:
802 return "endpoint not enabled";
803 case -EPIPE:
804 return "endpoint stalled";
805 case -ENOSPC:
806 return "not enough bandwidth";
807 case -ESHUTDOWN:
808 return "device disabled";
809 case -EHOSTUNREACH:
810 return "device suspended";
811 case -EINVAL:
812 case -EAGAIN:
813 case -EFBIG:
814 case -EMSGSIZE:
815 return "internal error";
816 default:
817 return "unknown error";
818 }
819}
820
821/*
822 * set up and start data/sync urbs
823 */
824static int start_urbs(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime)
825{
826 unsigned int i;
827 int err;
828
829 if (subs->stream->chip->shutdown)
830 return -EBADFD;
831
832 for (i = 0; i < subs->nurbs; i++) {
833 if (snd_BUG_ON(!subs->dataurb[i].urb))
834 return -EINVAL;
835 if (subs->ops.prepare(subs, runtime, subs->dataurb[i].urb) < 0) {
836 snd_printk(KERN_ERR "cannot prepare datapipe for urb %d\n", i);
837 goto __error;
838 }
839 }
840 if (subs->syncpipe) {
841 for (i = 0; i < SYNC_URBS; i++) {
842 if (snd_BUG_ON(!subs->syncurb[i].urb))
843 return -EINVAL;
844 if (subs->ops.prepare_sync(subs, runtime, subs->syncurb[i].urb) < 0) {
845 snd_printk(KERN_ERR "cannot prepare syncpipe for urb %d\n", i);
846 goto __error;
847 }
848 }
849 }
850
851 subs->active_mask = 0;
852 subs->unlink_mask = 0;
853 subs->running = 1;
854 for (i = 0; i < subs->nurbs; i++) {
855 err = usb_submit_urb(subs->dataurb[i].urb, GFP_ATOMIC);
856 if (err < 0) {
857 snd_printk(KERN_ERR "cannot submit datapipe "
858 "for urb %d, error %d: %s\n",
859 i, err, usb_error_string(err));
860 goto __error;
861 }
862 set_bit(i, &subs->active_mask);
863 }
864 if (subs->syncpipe) {
865 for (i = 0; i < SYNC_URBS; i++) {
866 err = usb_submit_urb(subs->syncurb[i].urb, GFP_ATOMIC);
867 if (err < 0) {
868 snd_printk(KERN_ERR "cannot submit syncpipe "
869 "for urb %d, error %d: %s\n",
870 i, err, usb_error_string(err));
871 goto __error;
872 }
873 set_bit(i + 16, &subs->active_mask);
874 }
875 }
876 return 0;
877
878 __error:
879 // snd_pcm_stop(subs->pcm_substream, SNDRV_PCM_STATE_XRUN);
880 deactivate_urbs(subs, 0, 0);
881 return -EPIPE;
882}
883
884
885/*
886 * wait until all urbs are processed.
887 */
888static int wait_clear_urbs(struct snd_usb_substream *subs)
889{
890 unsigned long end_time = jiffies + msecs_to_jiffies(1000);
891 unsigned int i;
892 int alive;
893
894 do {
895 alive = 0;
896 for (i = 0; i < subs->nurbs; i++) {
897 if (test_bit(i, &subs->active_mask))
898 alive++;
899 }
900 if (subs->syncpipe) {
901 for (i = 0; i < SYNC_URBS; i++) {
902 if (test_bit(i + 16, &subs->active_mask))
903 alive++;
904 }
905 }
906 if (! alive)
907 break;
908 schedule_timeout_uninterruptible(1);
909 } while (time_before(jiffies, end_time));
910 if (alive)
911 snd_printk(KERN_ERR "timeout: still %d active urbs..\n", alive);
912 return 0;
913}
914
915
916/*
917 * return the current pcm pointer. just based on the hwptr_done value.
918 */
919static snd_pcm_uframes_t snd_usb_pcm_pointer(struct snd_pcm_substream *substream)
920{
921 struct snd_usb_substream *subs;
922 unsigned int hwptr_done;
923
924 subs = (struct snd_usb_substream *)substream->runtime->private_data;
925 spin_lock(&subs->lock);
926 hwptr_done = subs->hwptr_done;
927 spin_unlock(&subs->lock);
928 return hwptr_done / (substream->runtime->frame_bits >> 3);
929}
930
931
932/*
933 * start/stop playback substream
934 */
935static int snd_usb_pcm_playback_trigger(struct snd_pcm_substream *substream,
936 int cmd)
937{
938 struct snd_usb_substream *subs = substream->runtime->private_data;
939
940 switch (cmd) {
941 case SNDRV_PCM_TRIGGER_START:
942 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
943 subs->ops.prepare = prepare_playback_urb;
944 return 0;
945 case SNDRV_PCM_TRIGGER_STOP:
946 return deactivate_urbs(subs, 0, 0);
947 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
948 subs->ops.prepare = prepare_nodata_playback_urb;
949 return 0;
950 default:
951 return -EINVAL;
952 }
953}
954
955/*
956 * start/stop capture substream
957 */
958static int snd_usb_pcm_capture_trigger(struct snd_pcm_substream *substream,
959 int cmd)
960{
961 struct snd_usb_substream *subs = substream->runtime->private_data;
962
963 switch (cmd) {
964 case SNDRV_PCM_TRIGGER_START:
965 subs->ops.retire = retire_capture_urb;
966 return start_urbs(subs, substream->runtime);
967 case SNDRV_PCM_TRIGGER_STOP:
968 return deactivate_urbs(subs, 0, 0);
969 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
970 subs->ops.retire = retire_paused_capture_urb;
971 return 0;
972 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
973 subs->ops.retire = retire_capture_urb;
974 return 0;
975 default:
976 return -EINVAL;
977 }
978}
979
980
981/*
982 * release a urb data
983 */
984static void release_urb_ctx(struct snd_urb_ctx *u)
985{
986 if (u->urb) {
987 if (u->buffer_size)
988 usb_buffer_free(u->subs->dev, u->buffer_size,
989 u->urb->transfer_buffer,
990 u->urb->transfer_dma);
991 usb_free_urb(u->urb);
992 u->urb = NULL;
993 }
994}
995
996/*
997 * release a substream
998 */
999static void release_substream_urbs(struct snd_usb_substream *subs, int force)
1000{
1001 int i;
1002
1003 /* stop urbs (to be sure) */
1004 deactivate_urbs(subs, force, 1);
1005 wait_clear_urbs(subs);
1006
1007 for (i = 0; i < MAX_URBS; i++)
1008 release_urb_ctx(&subs->dataurb[i]);
1009 for (i = 0; i < SYNC_URBS; i++)
1010 release_urb_ctx(&subs->syncurb[i]);
1011 usb_buffer_free(subs->dev, SYNC_URBS * 4,
1012 subs->syncbuf, subs->sync_dma);
1013 subs->syncbuf = NULL;
1014 subs->nurbs = 0;
1015}
1016
1017/*
1018 * initialize a substream for plaback/capture
1019 */
1020static int init_substream_urbs(struct snd_usb_substream *subs, unsigned int period_bytes,
1021 unsigned int rate, unsigned int frame_bits)
1022{
1023 unsigned int maxsize, i;
1024 int is_playback = subs->direction == SNDRV_PCM_STREAM_PLAYBACK;
1025 unsigned int urb_packs, total_packs, packs_per_ms;
1026
1027 /* calculate the frequency in 16.16 format */
1028 if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL)
1029 subs->freqn = get_usb_full_speed_rate(rate);
1030 else
1031 subs->freqn = get_usb_high_speed_rate(rate);
1032 subs->freqm = subs->freqn;
1033 /* calculate max. frequency */
1034 if (subs->maxpacksize) {
1035 /* whatever fits into a max. size packet */
1036 maxsize = subs->maxpacksize;
1037 subs->freqmax = (maxsize / (frame_bits >> 3))
1038 << (16 - subs->datainterval);
1039 } else {
1040 /* no max. packet size: just take 25% higher than nominal */
1041 subs->freqmax = subs->freqn + (subs->freqn >> 2);
1042 maxsize = ((subs->freqmax + 0xffff) * (frame_bits >> 3))
1043 >> (16 - subs->datainterval);
1044 }
1045 subs->phase = 0;
1046
1047 if (subs->fill_max)
1048 subs->curpacksize = subs->maxpacksize;
1049 else
1050 subs->curpacksize = maxsize;
1051
1052 if (snd_usb_get_speed(subs->dev) == USB_SPEED_HIGH)
1053 packs_per_ms = 8 >> subs->datainterval;
1054 else
1055 packs_per_ms = 1;
1056
1057 if (is_playback) {
1058 urb_packs = max(nrpacks, 1);
1059 urb_packs = min(urb_packs, (unsigned int)MAX_PACKS);
1060 } else
1061 urb_packs = 1;
1062 urb_packs *= packs_per_ms;
1063 if (subs->syncpipe)
1064 urb_packs = min(urb_packs, 1U << subs->syncinterval);
1065
1066 /* decide how many packets to be used */
1067 if (is_playback) {
1068 unsigned int minsize, maxpacks;
1069 /* determine how small a packet can be */
1070 minsize = (subs->freqn >> (16 - subs->datainterval))
1071 * (frame_bits >> 3);
1072 /* with sync from device, assume it can be 12% lower */
1073 if (subs->syncpipe)
1074 minsize -= minsize >> 3;
1075 minsize = max(minsize, 1u);
1076 total_packs = (period_bytes + minsize - 1) / minsize;
1077 /* we need at least two URBs for queueing */
1078 if (total_packs < 2) {
1079 total_packs = 2;
1080 } else {
1081 /* and we don't want too long a queue either */
1082 maxpacks = max(MAX_QUEUE * packs_per_ms, urb_packs * 2);
1083 total_packs = min(total_packs, maxpacks);
1084 }
1085 } else {
1086 while (urb_packs > 1 && urb_packs * maxsize >= period_bytes)
1087 urb_packs >>= 1;
1088 total_packs = MAX_URBS * urb_packs;
1089 }
1090 subs->nurbs = (total_packs + urb_packs - 1) / urb_packs;
1091 if (subs->nurbs > MAX_URBS) {
1092 /* too much... */
1093 subs->nurbs = MAX_URBS;
1094 total_packs = MAX_URBS * urb_packs;
1095 } else if (subs->nurbs < 2) {
1096 /* too little - we need at least two packets
1097 * to ensure contiguous playback/capture
1098 */
1099 subs->nurbs = 2;
1100 }
1101
1102 /* allocate and initialize data urbs */
1103 for (i = 0; i < subs->nurbs; i++) {
1104 struct snd_urb_ctx *u = &subs->dataurb[i];
1105 u->index = i;
1106 u->subs = subs;
1107 u->packets = (i + 1) * total_packs / subs->nurbs
1108 - i * total_packs / subs->nurbs;
1109 u->buffer_size = maxsize * u->packets;
1110 if (subs->fmt_type == UAC_FORMAT_TYPE_II)
1111 u->packets++; /* for transfer delimiter */
1112 u->urb = usb_alloc_urb(u->packets, GFP_KERNEL);
1113 if (!u->urb)
1114 goto out_of_memory;
1115 u->urb->transfer_buffer =
1116 usb_buffer_alloc(subs->dev, u->buffer_size, GFP_KERNEL,
1117 &u->urb->transfer_dma);
1118 if (!u->urb->transfer_buffer)
1119 goto out_of_memory;
1120 u->urb->pipe = subs->datapipe;
1121 u->urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
1122 u->urb->interval = 1 << subs->datainterval;
1123 u->urb->context = u;
1124 u->urb->complete = snd_complete_urb;
1125 }
1126
1127 if (subs->syncpipe) {
1128 /* allocate and initialize sync urbs */
1129 subs->syncbuf = usb_buffer_alloc(subs->dev, SYNC_URBS * 4,
1130 GFP_KERNEL, &subs->sync_dma);
1131 if (!subs->syncbuf)
1132 goto out_of_memory;
1133 for (i = 0; i < SYNC_URBS; i++) {
1134 struct snd_urb_ctx *u = &subs->syncurb[i];
1135 u->index = i;
1136 u->subs = subs;
1137 u->packets = 1;
1138 u->urb = usb_alloc_urb(1, GFP_KERNEL);
1139 if (!u->urb)
1140 goto out_of_memory;
1141 u->urb->transfer_buffer = subs->syncbuf + i * 4;
1142 u->urb->transfer_dma = subs->sync_dma + i * 4;
1143 u->urb->transfer_buffer_length = 4;
1144 u->urb->pipe = subs->syncpipe;
1145 u->urb->transfer_flags = URB_ISO_ASAP |
1146 URB_NO_TRANSFER_DMA_MAP;
1147 u->urb->number_of_packets = 1;
1148 u->urb->interval = 1 << subs->syncinterval;
1149 u->urb->context = u;
1150 u->urb->complete = snd_complete_sync_urb;
1151 }
1152 }
1153 return 0;
1154
1155out_of_memory:
1156 release_substream_urbs(subs, 0);
1157 return -ENOMEM;
1158}
1159
1160
1161/*
1162 * find a matching audio format
1163 */
1164static struct audioformat *find_format(struct snd_usb_substream *subs, unsigned int format,
1165 unsigned int rate, unsigned int channels)
1166{
1167 struct list_head *p;
1168 struct audioformat *found = NULL;
1169 int cur_attr = 0, attr;
1170
1171 list_for_each(p, &subs->fmt_list) {
1172 struct audioformat *fp;
1173 fp = list_entry(p, struct audioformat, list);
1174 if (fp->format != format || fp->channels != channels)
1175 continue;
1176 if (rate < fp->rate_min || rate > fp->rate_max)
1177 continue;
1178 if (! (fp->rates & SNDRV_PCM_RATE_CONTINUOUS)) {
1179 unsigned int i;
1180 for (i = 0; i < fp->nr_rates; i++)
1181 if (fp->rate_table[i] == rate)
1182 break;
1183 if (i >= fp->nr_rates)
1184 continue;
1185 }
1186 attr = fp->ep_attr & USB_ENDPOINT_SYNCTYPE;
1187 if (! found) {
1188 found = fp;
1189 cur_attr = attr;
1190 continue;
1191 }
1192 /* avoid async out and adaptive in if the other method
1193 * supports the same format.
1194 * this is a workaround for the case like
1195 * M-audio audiophile USB.
1196 */
1197 if (attr != cur_attr) {
1198 if ((attr == USB_ENDPOINT_SYNC_ASYNC &&
1199 subs->direction == SNDRV_PCM_STREAM_PLAYBACK) ||
1200 (attr == USB_ENDPOINT_SYNC_ADAPTIVE &&
1201 subs->direction == SNDRV_PCM_STREAM_CAPTURE))
1202 continue;
1203 if ((cur_attr == USB_ENDPOINT_SYNC_ASYNC &&
1204 subs->direction == SNDRV_PCM_STREAM_PLAYBACK) ||
1205 (cur_attr == USB_ENDPOINT_SYNC_ADAPTIVE &&
1206 subs->direction == SNDRV_PCM_STREAM_CAPTURE)) {
1207 found = fp;
1208 cur_attr = attr;
1209 continue;
1210 }
1211 }
1212 /* find the format with the largest max. packet size */
1213 if (fp->maxpacksize > found->maxpacksize) {
1214 found = fp;
1215 cur_attr = attr;
1216 }
1217 }
1218 return found;
1219}
1220
1221
1222/*
1223 * initialize the picth control and sample rate
1224 */
1225static int init_usb_pitch(struct usb_device *dev, int iface,
1226 struct usb_host_interface *alts,
1227 struct audioformat *fmt)
1228{
1229 unsigned int ep;
1230 unsigned char data[1];
1231 int err;
1232
1233 ep = get_endpoint(alts, 0)->bEndpointAddress;
1234 /* if endpoint has pitch control, enable it */
1235 if (fmt->attributes & UAC_EP_CS_ATTR_PITCH_CONTROL) {
1236 data[0] = 1;
1237 if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR,
1238 USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT,
1239 UAC_EP_CS_ATTR_PITCH_CONTROL << 8, ep, data, 1, 1000)) < 0) {
1240 snd_printk(KERN_ERR "%d:%d:%d: cannot set enable PITCH\n",
1241 dev->devnum, iface, ep);
1242 return err;
1243 }
1244 }
1245 return 0;
1246}
1247
1248static int init_usb_sample_rate(struct usb_device *dev, int iface,
1249 struct usb_host_interface *alts,
1250 struct audioformat *fmt, int rate)
1251{
1252 unsigned int ep;
1253 unsigned char data[3];
1254 int err;
1255
1256 ep = get_endpoint(alts, 0)->bEndpointAddress;
1257 /* if endpoint has sampling rate control, set it */
1258 if (fmt->attributes & UAC_EP_CS_ATTR_SAMPLE_RATE) {
1259 int crate;
1260 data[0] = rate;
1261 data[1] = rate >> 8;
1262 data[2] = rate >> 16;
1263 if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR,
1264 USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT,
1265 UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep, data, 3, 1000)) < 0) {
1266 snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d to ep %#x\n",
1267 dev->devnum, iface, fmt->altsetting, rate, ep);
1268 return err;
1269 }
1270 if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC_GET_CUR,
1271 USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_IN,
1272 UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep, data, 3, 1000)) < 0) {
1273 snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq at ep %#x\n",
1274 dev->devnum, iface, fmt->altsetting, ep);
1275 return 0; /* some devices don't support reading */
1276 }
1277 crate = data[0] | (data[1] << 8) | (data[2] << 16);
1278 if (crate != rate) {
1279 snd_printd(KERN_WARNING "current rate %d is different from the runtime rate %d\n", crate, rate);
1280 // runtime->rate = crate;
1281 }
1282 }
1283 return 0;
1284}
1285
1286/*
1287 * For E-Mu 0404USB/0202USB/TrackerPre sample rate should be set for device,
1288 * not for interface.
1289 */
1290static void set_format_emu_quirk(struct snd_usb_substream *subs,
1291 struct audioformat *fmt)
1292{
1293 unsigned char emu_samplerate_id = 0;
1294
1295 /* When capture is active
1296 * sample rate shouldn't be changed
1297 * by playback substream
1298 */
1299 if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) {
1300 if (subs->stream->substream[SNDRV_PCM_STREAM_CAPTURE].interface != -1)
1301 return;
1302 }
1303
1304 switch (fmt->rate_min) {
1305 case 48000:
1306 emu_samplerate_id = EMU_QUIRK_SR_48000HZ;
1307 break;
1308 case 88200:
1309 emu_samplerate_id = EMU_QUIRK_SR_88200HZ;
1310 break;
1311 case 96000:
1312 emu_samplerate_id = EMU_QUIRK_SR_96000HZ;
1313 break;
1314 case 176400:
1315 emu_samplerate_id = EMU_QUIRK_SR_176400HZ;
1316 break;
1317 case 192000:
1318 emu_samplerate_id = EMU_QUIRK_SR_192000HZ;
1319 break;
1320 default:
1321 emu_samplerate_id = EMU_QUIRK_SR_44100HZ;
1322 break;
1323 }
1324 snd_emuusb_set_samplerate(subs->stream->chip, emu_samplerate_id);
1325}
1326
1327/*
1328 * find a matching format and set up the interface
1329 */
1330static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
1331{
1332 struct usb_device *dev = subs->dev;
1333 struct usb_host_interface *alts;
1334 struct usb_interface_descriptor *altsd;
1335 struct usb_interface *iface;
1336 unsigned int ep, attr;
1337 int is_playback = subs->direction == SNDRV_PCM_STREAM_PLAYBACK;
1338 int err;
1339
1340 iface = usb_ifnum_to_if(dev, fmt->iface);
1341 if (WARN_ON(!iface))
1342 return -EINVAL;
1343 alts = &iface->altsetting[fmt->altset_idx];
1344 altsd = get_iface_desc(alts);
1345 if (WARN_ON(altsd->bAlternateSetting != fmt->altsetting))
1346 return -EINVAL;
1347
1348 if (fmt == subs->cur_audiofmt)
1349 return 0;
1350
1351 /* close the old interface */
1352 if (subs->interface >= 0 && subs->interface != fmt->iface) {
1353 if (usb_set_interface(subs->dev, subs->interface, 0) < 0) {
1354 snd_printk(KERN_ERR "%d:%d:%d: return to setting 0 failed\n",
1355 dev->devnum, fmt->iface, fmt->altsetting);
1356 return -EIO;
1357 }
1358 subs->interface = -1;
1359 subs->format = 0;
1360 }
1361
1362 /* set interface */
1363 if (subs->interface != fmt->iface || subs->format != fmt->altset_idx) {
1364 if (usb_set_interface(dev, fmt->iface, fmt->altsetting) < 0) {
1365 snd_printk(KERN_ERR "%d:%d:%d: usb_set_interface failed\n",
1366 dev->devnum, fmt->iface, fmt->altsetting);
1367 return -EIO;
1368 }
1369 snd_printdd(KERN_INFO "setting usb interface %d:%d\n", fmt->iface, fmt->altsetting);
1370 subs->interface = fmt->iface;
1371 subs->format = fmt->altset_idx;
1372 }
1373
1374 /* create a data pipe */
1375 ep = fmt->endpoint & USB_ENDPOINT_NUMBER_MASK;
1376 if (is_playback)
1377 subs->datapipe = usb_sndisocpipe(dev, ep);
1378 else
1379 subs->datapipe = usb_rcvisocpipe(dev, ep);
1380 subs->datainterval = fmt->datainterval;
1381 subs->syncpipe = subs->syncinterval = 0;
1382 subs->maxpacksize = fmt->maxpacksize;
1383 subs->fill_max = 0;
1384
1385 /* we need a sync pipe in async OUT or adaptive IN mode */
1386 /* check the number of EP, since some devices have broken
1387 * descriptors which fool us. if it has only one EP,
1388 * assume it as adaptive-out or sync-in.
1389 */
1390 attr = fmt->ep_attr & USB_ENDPOINT_SYNCTYPE;
1391 if (((is_playback && attr == USB_ENDPOINT_SYNC_ASYNC) ||
1392 (! is_playback && attr == USB_ENDPOINT_SYNC_ADAPTIVE)) &&
1393 altsd->bNumEndpoints >= 2) {
1394 /* check sync-pipe endpoint */
1395 /* ... and check descriptor size before accessing bSynchAddress
1396 because there is a version of the SB Audigy 2 NX firmware lacking
1397 the audio fields in the endpoint descriptors */
1398 if ((get_endpoint(alts, 1)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != 0x01 ||
1399 (get_endpoint(alts, 1)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE &&
1400 get_endpoint(alts, 1)->bSynchAddress != 0)) {
1401 snd_printk(KERN_ERR "%d:%d:%d : invalid synch pipe\n",
1402 dev->devnum, fmt->iface, fmt->altsetting);
1403 return -EINVAL;
1404 }
1405 ep = get_endpoint(alts, 1)->bEndpointAddress;
1406 if (get_endpoint(alts, 0)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE &&
1407 (( is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress | USB_DIR_IN)) ||
1408 (!is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress & ~USB_DIR_IN)))) {
1409 snd_printk(KERN_ERR "%d:%d:%d : invalid synch pipe\n",
1410 dev->devnum, fmt->iface, fmt->altsetting);
1411 return -EINVAL;
1412 }
1413 ep &= USB_ENDPOINT_NUMBER_MASK;
1414 if (is_playback)
1415 subs->syncpipe = usb_rcvisocpipe(dev, ep);
1416 else
1417 subs->syncpipe = usb_sndisocpipe(dev, ep);
1418 if (get_endpoint(alts, 1)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE &&
1419 get_endpoint(alts, 1)->bRefresh >= 1 &&
1420 get_endpoint(alts, 1)->bRefresh <= 9)
1421 subs->syncinterval = get_endpoint(alts, 1)->bRefresh;
1422 else if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL)
1423 subs->syncinterval = 1;
1424 else if (get_endpoint(alts, 1)->bInterval >= 1 &&
1425 get_endpoint(alts, 1)->bInterval <= 16)
1426 subs->syncinterval = get_endpoint(alts, 1)->bInterval - 1;
1427 else
1428 subs->syncinterval = 3;
1429 }
1430
1431 /* always fill max packet size */
1432 if (fmt->attributes & UAC_EP_CS_ATTR_FILL_MAX)
1433 subs->fill_max = 1;
1434
1435 if ((err = init_usb_pitch(dev, subs->interface, alts, fmt)) < 0)
1436 return err;
1437
1438 subs->cur_audiofmt = fmt;
1439
1440 switch (subs->stream->chip->usb_id) {
1441 case USB_ID(0x041e, 0x3f02): /* E-Mu 0202 USB */
1442 case USB_ID(0x041e, 0x3f04): /* E-Mu 0404 USB */
1443 case USB_ID(0x041e, 0x3f0a): /* E-Mu Tracker Pre */
1444 set_format_emu_quirk(subs, fmt);
1445 break;
1446 }
1447
1448#if 0
1449 printk(KERN_DEBUG
1450 "setting done: format = %d, rate = %d..%d, channels = %d\n",
1451 fmt->format, fmt->rate_min, fmt->rate_max, fmt->channels);
1452 printk(KERN_DEBUG
1453 " datapipe = 0x%0x, syncpipe = 0x%0x\n",
1454 subs->datapipe, subs->syncpipe);
1455#endif
1456
1457 return 0;
1458}
1459
1460/*
1461 * hw_params callback
1462 *
1463 * allocate a buffer and set the given audio format.
1464 *
1465 * so far we use a physically linear buffer although packetize transfer
1466 * doesn't need a continuous area.
1467 * if sg buffer is supported on the later version of alsa, we'll follow
1468 * that.
1469 */
1470static int snd_usb_hw_params(struct snd_pcm_substream *substream,
1471 struct snd_pcm_hw_params *hw_params)
1472{
1473 struct snd_usb_substream *subs = substream->runtime->private_data;
1474 struct audioformat *fmt;
1475 unsigned int channels, rate, format;
1476 int ret, changed;
1477
1478 ret = snd_pcm_lib_alloc_vmalloc_buffer(substream,
1479 params_buffer_bytes(hw_params));
1480 if (ret < 0)
1481 return ret;
1482
1483 format = params_format(hw_params);
1484 rate = params_rate(hw_params);
1485 channels = params_channels(hw_params);
1486 fmt = find_format(subs, format, rate, channels);
1487 if (!fmt) {
1488 snd_printd(KERN_DEBUG "cannot set format: format = %#x, rate = %d, channels = %d\n",
1489 format, rate, channels);
1490 return -EINVAL;
1491 }
1492
1493 changed = subs->cur_audiofmt != fmt ||
1494 subs->period_bytes != params_period_bytes(hw_params) ||
1495 subs->cur_rate != rate;
1496 if ((ret = set_format(subs, fmt)) < 0)
1497 return ret;
1498
1499 if (subs->cur_rate != rate) {
1500 struct usb_host_interface *alts;
1501 struct usb_interface *iface;
1502 iface = usb_ifnum_to_if(subs->dev, fmt->iface);
1503 alts = &iface->altsetting[fmt->altset_idx];
1504 ret = init_usb_sample_rate(subs->dev, subs->interface, alts, fmt, rate);
1505 if (ret < 0)
1506 return ret;
1507 subs->cur_rate = rate;
1508 }
1509
1510 if (changed) {
1511 /* format changed */
1512 release_substream_urbs(subs, 0);
1513 /* influenced: period_bytes, channels, rate, format, */
1514 ret = init_substream_urbs(subs, params_period_bytes(hw_params),
1515 params_rate(hw_params),
1516 snd_pcm_format_physical_width(params_format(hw_params)) * params_channels(hw_params));
1517 }
1518
1519 return ret;
1520}
1521
1522/*
1523 * hw_free callback
1524 *
1525 * reset the audio format and release the buffer
1526 */
1527static int snd_usb_hw_free(struct snd_pcm_substream *substream)
1528{
1529 struct snd_usb_substream *subs = substream->runtime->private_data;
1530
1531 subs->cur_audiofmt = NULL;
1532 subs->cur_rate = 0;
1533 subs->period_bytes = 0;
1534 if (!subs->stream->chip->shutdown)
1535 release_substream_urbs(subs, 0);
1536 return snd_pcm_lib_free_vmalloc_buffer(substream);
1537}
1538
1539/*
1540 * prepare callback
1541 *
1542 * only a few subtle things...
1543 */
1544static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
1545{
1546 struct snd_pcm_runtime *runtime = substream->runtime;
1547 struct snd_usb_substream *subs = runtime->private_data;
1548
1549 if (! subs->cur_audiofmt) {
1550 snd_printk(KERN_ERR "usbaudio: no format is specified!\n");
1551 return -ENXIO;
1552 }
1553
1554 /* some unit conversions in runtime */
1555 subs->maxframesize = bytes_to_frames(runtime, subs->maxpacksize);
1556 subs->curframesize = bytes_to_frames(runtime, subs->curpacksize);
1557
1558 /* reset the pointer */
1559 subs->hwptr_done = 0;
1560 subs->transfer_done = 0;
1561 subs->phase = 0;
1562 runtime->delay = 0;
1563
1564 /* clear urbs (to be sure) */
1565 deactivate_urbs(subs, 0, 1);
1566 wait_clear_urbs(subs);
1567
1568 /* for playback, submit the URBs now; otherwise, the first hwptr_done
1569 * updates for all URBs would happen at the same time when starting */
1570 if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) {
1571 subs->ops.prepare = prepare_nodata_playback_urb;
1572 return start_urbs(subs, runtime);
1573 } else
1574 return 0;
1575}
1576
1577static struct snd_pcm_hardware snd_usb_hardware =
1578{
1579 .info = SNDRV_PCM_INFO_MMAP |
1580 SNDRV_PCM_INFO_MMAP_VALID |
1581 SNDRV_PCM_INFO_BATCH |
1582 SNDRV_PCM_INFO_INTERLEAVED |
1583 SNDRV_PCM_INFO_BLOCK_TRANSFER |
1584 SNDRV_PCM_INFO_PAUSE,
1585 .buffer_bytes_max = 1024 * 1024,
1586 .period_bytes_min = 64,
1587 .period_bytes_max = 512 * 1024,
1588 .periods_min = 2,
1589 .periods_max = 1024,
1590};
1591
1592/*
1593 * h/w constraints
1594 */
1595
1596#ifdef HW_CONST_DEBUG
1597#define hwc_debug(fmt, args...) printk(KERN_DEBUG fmt, ##args)
1598#else
1599#define hwc_debug(fmt, args...) /**/
1600#endif
1601
1602static int hw_check_valid_format(struct snd_usb_substream *subs,
1603 struct snd_pcm_hw_params *params,
1604 struct audioformat *fp)
1605{
1606 struct snd_interval *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
1607 struct snd_interval *ct = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
1608 struct snd_mask *fmts = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
1609 struct snd_interval *pt = hw_param_interval(params, SNDRV_PCM_HW_PARAM_PERIOD_TIME);
1610 unsigned int ptime;
1611
1612 /* check the format */
1613 if (!snd_mask_test(fmts, fp->format)) {
1614 hwc_debug(" > check: no supported format %d\n", fp->format);
1615 return 0;
1616 }
1617 /* check the channels */
1618 if (fp->channels < ct->min || fp->channels > ct->max) {
1619 hwc_debug(" > check: no valid channels %d (%d/%d)\n", fp->channels, ct->min, ct->max);
1620 return 0;
1621 }
1622 /* check the rate is within the range */
1623 if (fp->rate_min > it->max || (fp->rate_min == it->max && it->openmax)) {
1624 hwc_debug(" > check: rate_min %d > max %d\n", fp->rate_min, it->max);
1625 return 0;
1626 }
1627 if (fp->rate_max < it->min || (fp->rate_max == it->min && it->openmin)) {
1628 hwc_debug(" > check: rate_max %d < min %d\n", fp->rate_max, it->min);
1629 return 0;
1630 }
1631 /* check whether the period time is >= the data packet interval */
1632 if (snd_usb_get_speed(subs->dev) == USB_SPEED_HIGH) {
1633 ptime = 125 * (1 << fp->datainterval);
1634 if (ptime > pt->max || (ptime == pt->max && pt->openmax)) {
1635 hwc_debug(" > check: ptime %u > max %u\n", ptime, pt->max);
1636 return 0;
1637 }
1638 }
1639 return 1;
1640}
1641
1642static int hw_rule_rate(struct snd_pcm_hw_params *params,
1643 struct snd_pcm_hw_rule *rule)
1644{
1645 struct snd_usb_substream *subs = rule->private;
1646 struct list_head *p;
1647 struct snd_interval *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
1648 unsigned int rmin, rmax;
1649 int changed;
1650
1651 hwc_debug("hw_rule_rate: (%d,%d)\n", it->min, it->max);
1652 changed = 0;
1653 rmin = rmax = 0;
1654 list_for_each(p, &subs->fmt_list) {
1655 struct audioformat *fp;
1656 fp = list_entry(p, struct audioformat, list);
1657 if (!hw_check_valid_format(subs, params, fp))
1658 continue;
1659 if (changed++) {
1660 if (rmin > fp->rate_min)
1661 rmin = fp->rate_min;
1662 if (rmax < fp->rate_max)
1663 rmax = fp->rate_max;
1664 } else {
1665 rmin = fp->rate_min;
1666 rmax = fp->rate_max;
1667 }
1668 }
1669
1670 if (!changed) {
1671 hwc_debug(" --> get empty\n");
1672 it->empty = 1;
1673 return -EINVAL;
1674 }
1675
1676 changed = 0;
1677 if (it->min < rmin) {
1678 it->min = rmin;
1679 it->openmin = 0;
1680 changed = 1;
1681 }
1682 if (it->max > rmax) {
1683 it->max = rmax;
1684 it->openmax = 0;
1685 changed = 1;
1686 }
1687 if (snd_interval_checkempty(it)) {
1688 it->empty = 1;
1689 return -EINVAL;
1690 }
1691 hwc_debug(" --> (%d, %d) (changed = %d)\n", it->min, it->max, changed);
1692 return changed;
1693}
1694
1695
1696static int hw_rule_channels(struct snd_pcm_hw_params *params,
1697 struct snd_pcm_hw_rule *rule)
1698{
1699 struct snd_usb_substream *subs = rule->private;
1700 struct list_head *p;
1701 struct snd_interval *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
1702 unsigned int rmin, rmax;
1703 int changed;
1704
1705 hwc_debug("hw_rule_channels: (%d,%d)\n", it->min, it->max);
1706 changed = 0;
1707 rmin = rmax = 0;
1708 list_for_each(p, &subs->fmt_list) {
1709 struct audioformat *fp;
1710 fp = list_entry(p, struct audioformat, list);
1711 if (!hw_check_valid_format(subs, params, fp))
1712 continue;
1713 if (changed++) {
1714 if (rmin > fp->channels)
1715 rmin = fp->channels;
1716 if (rmax < fp->channels)
1717 rmax = fp->channels;
1718 } else {
1719 rmin = fp->channels;
1720 rmax = fp->channels;
1721 }
1722 }
1723
1724 if (!changed) {
1725 hwc_debug(" --> get empty\n");
1726 it->empty = 1;
1727 return -EINVAL;
1728 }
1729
1730 changed = 0;
1731 if (it->min < rmin) {
1732 it->min = rmin;
1733 it->openmin = 0;
1734 changed = 1;
1735 }
1736 if (it->max > rmax) {
1737 it->max = rmax;
1738 it->openmax = 0;
1739 changed = 1;
1740 }
1741 if (snd_interval_checkempty(it)) {
1742 it->empty = 1;
1743 return -EINVAL;
1744 }
1745 hwc_debug(" --> (%d, %d) (changed = %d)\n", it->min, it->max, changed);
1746 return changed;
1747}
1748
1749static int hw_rule_format(struct snd_pcm_hw_params *params,
1750 struct snd_pcm_hw_rule *rule)
1751{
1752 struct snd_usb_substream *subs = rule->private;
1753 struct list_head *p;
1754 struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
1755 u64 fbits;
1756 u32 oldbits[2];
1757 int changed;
1758
1759 hwc_debug("hw_rule_format: %x:%x\n", fmt->bits[0], fmt->bits[1]);
1760 fbits = 0;
1761 list_for_each(p, &subs->fmt_list) {
1762 struct audioformat *fp;
1763 fp = list_entry(p, struct audioformat, list);
1764 if (!hw_check_valid_format(subs, params, fp))
1765 continue;
1766 fbits |= (1ULL << fp->format);
1767 }
1768
1769 oldbits[0] = fmt->bits[0];
1770 oldbits[1] = fmt->bits[1];
1771 fmt->bits[0] &= (u32)fbits;
1772 fmt->bits[1] &= (u32)(fbits >> 32);
1773 if (!fmt->bits[0] && !fmt->bits[1]) {
1774 hwc_debug(" --> get empty\n");
1775 return -EINVAL;
1776 }
1777 changed = (oldbits[0] != fmt->bits[0] || oldbits[1] != fmt->bits[1]);
1778 hwc_debug(" --> %x:%x (changed = %d)\n", fmt->bits[0], fmt->bits[1], changed);
1779 return changed;
1780}
1781
1782static int hw_rule_period_time(struct snd_pcm_hw_params *params,
1783 struct snd_pcm_hw_rule *rule)
1784{
1785 struct snd_usb_substream *subs = rule->private;
1786 struct audioformat *fp;
1787 struct snd_interval *it;
1788 unsigned char min_datainterval;
1789 unsigned int pmin;
1790 int changed;
1791
1792 it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_PERIOD_TIME);
1793 hwc_debug("hw_rule_period_time: (%u,%u)\n", it->min, it->max);
1794 min_datainterval = 0xff;
1795 list_for_each_entry(fp, &subs->fmt_list, list) {
1796 if (!hw_check_valid_format(subs, params, fp))
1797 continue;
1798 min_datainterval = min(min_datainterval, fp->datainterval);
1799 }
1800 if (min_datainterval == 0xff) {
1801 hwc_debug(" --> get emtpy\n");
1802 it->empty = 1;
1803 return -EINVAL;
1804 }
1805 pmin = 125 * (1 << min_datainterval);
1806 changed = 0;
1807 if (it->min < pmin) {
1808 it->min = pmin;
1809 it->openmin = 0;
1810 changed = 1;
1811 }
1812 if (snd_interval_checkempty(it)) {
1813 it->empty = 1;
1814 return -EINVAL;
1815 }
1816 hwc_debug(" --> (%u,%u) (changed = %d)\n", it->min, it->max, changed);
1817 return changed;
1818}
1819
1820/*
1821 * If the device supports unusual bit rates, does the request meet these?
1822 */
1823static int snd_usb_pcm_check_knot(struct snd_pcm_runtime *runtime,
1824 struct snd_usb_substream *subs)
1825{
1826 struct audioformat *fp;
1827 int count = 0, needs_knot = 0;
1828 int err;
1829
1830 list_for_each_entry(fp, &subs->fmt_list, list) {
1831 if (fp->rates & SNDRV_PCM_RATE_CONTINUOUS)
1832 return 0;
1833 count += fp->nr_rates;
1834 if (fp->rates & SNDRV_PCM_RATE_KNOT)
1835 needs_knot = 1;
1836 }
1837 if (!needs_knot)
1838 return 0;
1839
1840 subs->rate_list.count = count;
1841 subs->rate_list.list = kmalloc(sizeof(int) * count, GFP_KERNEL);
1842 subs->rate_list.mask = 0;
1843 count = 0;
1844 list_for_each_entry(fp, &subs->fmt_list, list) {
1845 int i;
1846 for (i = 0; i < fp->nr_rates; i++)
1847 subs->rate_list.list[count++] = fp->rate_table[i];
1848 }
1849 err = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
1850 &subs->rate_list);
1851 if (err < 0)
1852 return err;
1853
1854 return 0;
1855}
1856
1857
1858/*
1859 * set up the runtime hardware information.
1860 */
1861
1862static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substream *subs)
1863{
1864 struct list_head *p;
1865 unsigned int pt, ptmin;
1866 int param_period_time_if_needed;
1867 int err;
1868
1869 runtime->hw.formats = subs->formats;
1870
1871 runtime->hw.rate_min = 0x7fffffff;
1872 runtime->hw.rate_max = 0;
1873 runtime->hw.channels_min = 256;
1874 runtime->hw.channels_max = 0;
1875 runtime->hw.rates = 0;
1876 ptmin = UINT_MAX;
1877 /* check min/max rates and channels */
1878 list_for_each(p, &subs->fmt_list) {
1879 struct audioformat *fp;
1880 fp = list_entry(p, struct audioformat, list);
1881 runtime->hw.rates |= fp->rates;
1882 if (runtime->hw.rate_min > fp->rate_min)
1883 runtime->hw.rate_min = fp->rate_min;
1884 if (runtime->hw.rate_max < fp->rate_max)
1885 runtime->hw.rate_max = fp->rate_max;
1886 if (runtime->hw.channels_min > fp->channels)
1887 runtime->hw.channels_min = fp->channels;
1888 if (runtime->hw.channels_max < fp->channels)
1889 runtime->hw.channels_max = fp->channels;
1890 if (fp->fmt_type == UAC_FORMAT_TYPE_II && fp->frame_size > 0) {
1891 /* FIXME: there might be more than one audio formats... */
1892 runtime->hw.period_bytes_min = runtime->hw.period_bytes_max =
1893 fp->frame_size;
1894 }
1895 pt = 125 * (1 << fp->datainterval);
1896 ptmin = min(ptmin, pt);
1897 }
1898
1899 param_period_time_if_needed = SNDRV_PCM_HW_PARAM_PERIOD_TIME;
1900 if (snd_usb_get_speed(subs->dev) != USB_SPEED_HIGH)
1901 /* full speed devices have fixed data packet interval */
1902 ptmin = 1000;
1903 if (ptmin == 1000)
1904 /* if period time doesn't go below 1 ms, no rules needed */
1905 param_period_time_if_needed = -1;
1906 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME,
1907 ptmin, UINT_MAX);
1908
1909 if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
1910 hw_rule_rate, subs,
1911 SNDRV_PCM_HW_PARAM_FORMAT,
1912 SNDRV_PCM_HW_PARAM_CHANNELS,
1913 param_period_time_if_needed,
1914 -1)) < 0)
1915 return err;
1916 if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
1917 hw_rule_channels, subs,
1918 SNDRV_PCM_HW_PARAM_FORMAT,
1919 SNDRV_PCM_HW_PARAM_RATE,
1920 param_period_time_if_needed,
1921 -1)) < 0)
1922 return err;
1923 if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT,
1924 hw_rule_format, subs,
1925 SNDRV_PCM_HW_PARAM_RATE,
1926 SNDRV_PCM_HW_PARAM_CHANNELS,
1927 param_period_time_if_needed,
1928 -1)) < 0)
1929 return err;
1930 if (param_period_time_if_needed >= 0) {
1931 err = snd_pcm_hw_rule_add(runtime, 0,
1932 SNDRV_PCM_HW_PARAM_PERIOD_TIME,
1933 hw_rule_period_time, subs,
1934 SNDRV_PCM_HW_PARAM_FORMAT,
1935 SNDRV_PCM_HW_PARAM_CHANNELS,
1936 SNDRV_PCM_HW_PARAM_RATE,
1937 -1);
1938 if (err < 0)
1939 return err;
1940 }
1941 if ((err = snd_usb_pcm_check_knot(runtime, subs)) < 0)
1942 return err;
1943 return 0;
1944}
1945
1946static int snd_usb_pcm_open(struct snd_pcm_substream *substream, int direction)
1947{
1948 struct snd_usb_stream *as = snd_pcm_substream_chip(substream);
1949 struct snd_pcm_runtime *runtime = substream->runtime;
1950 struct snd_usb_substream *subs = &as->substream[direction];
1951
1952 subs->interface = -1;
1953 subs->format = 0;
1954 runtime->hw = snd_usb_hardware;
1955 runtime->private_data = subs;
1956 subs->pcm_substream = substream;
1957 return setup_hw_info(runtime, subs);
1958}
1959
1960static int snd_usb_pcm_close(struct snd_pcm_substream *substream, int direction)
1961{
1962 struct snd_usb_stream *as = snd_pcm_substream_chip(substream);
1963 struct snd_usb_substream *subs = &as->substream[direction];
1964
1965 if (!as->chip->shutdown && subs->interface >= 0) {
1966 usb_set_interface(subs->dev, subs->interface, 0);
1967 subs->interface = -1;
1968 }
1969 subs->pcm_substream = NULL;
1970 return 0;
1971}
1972
1973static int snd_usb_playback_open(struct snd_pcm_substream *substream)
1974{
1975 return snd_usb_pcm_open(substream, SNDRV_PCM_STREAM_PLAYBACK);
1976}
1977
1978static int snd_usb_playback_close(struct snd_pcm_substream *substream)
1979{
1980 return snd_usb_pcm_close(substream, SNDRV_PCM_STREAM_PLAYBACK);
1981}
1982
1983static int snd_usb_capture_open(struct snd_pcm_substream *substream)
1984{
1985 return snd_usb_pcm_open(substream, SNDRV_PCM_STREAM_CAPTURE);
1986}
1987
1988static int snd_usb_capture_close(struct snd_pcm_substream *substream)
1989{
1990 return snd_usb_pcm_close(substream, SNDRV_PCM_STREAM_CAPTURE);
1991}
1992
1993static struct snd_pcm_ops snd_usb_playback_ops = {
1994 .open = snd_usb_playback_open,
1995 .close = snd_usb_playback_close,
1996 .ioctl = snd_pcm_lib_ioctl,
1997 .hw_params = snd_usb_hw_params,
1998 .hw_free = snd_usb_hw_free,
1999 .prepare = snd_usb_pcm_prepare,
2000 .trigger = snd_usb_pcm_playback_trigger,
2001 .pointer = snd_usb_pcm_pointer,
2002 .page = snd_pcm_lib_get_vmalloc_page,
2003 .mmap = snd_pcm_lib_mmap_vmalloc,
2004};
2005
2006static struct snd_pcm_ops snd_usb_capture_ops = {
2007 .open = snd_usb_capture_open,
2008 .close = snd_usb_capture_close,
2009 .ioctl = snd_pcm_lib_ioctl,
2010 .hw_params = snd_usb_hw_params,
2011 .hw_free = snd_usb_hw_free,
2012 .prepare = snd_usb_pcm_prepare,
2013 .trigger = snd_usb_pcm_capture_trigger,
2014 .pointer = snd_usb_pcm_pointer,
2015 .page = snd_pcm_lib_get_vmalloc_page,
2016 .mmap = snd_pcm_lib_mmap_vmalloc,
2017};
2018
2019
2020
2021/*
2022 * helper functions
2023 */
2024
2025/*
2026 * combine bytes and get an integer value
2027 */
2028unsigned int snd_usb_combine_bytes(unsigned char *bytes, int size)
2029{
2030 switch (size) {
2031 case 1: return *bytes;
2032 case 2: return combine_word(bytes);
2033 case 3: return combine_triple(bytes);
2034 case 4: return combine_quad(bytes);
2035 default: return 0;
2036 }
2037}
2038
2039/*
2040 * parse descriptor buffer and return the pointer starting the given
2041 * descriptor type.
2042 */
2043void *snd_usb_find_desc(void *descstart, int desclen, void *after, u8 dtype)
2044{
2045 u8 *p, *end, *next;
2046
2047 p = descstart;
2048 end = p + desclen;
2049 for (; p < end;) {
2050 if (p[0] < 2)
2051 return NULL;
2052 next = p + p[0];
2053 if (next > end)
2054 return NULL;
2055 if (p[1] == dtype && (!after || (void *)p > after)) {
2056 return p;
2057 }
2058 p = next;
2059 }
2060 return NULL;
2061}
2062
2063/*
2064 * find a class-specified interface descriptor with the given subtype.
2065 */
2066void *snd_usb_find_csint_desc(void *buffer, int buflen, void *after, u8 dsubtype)
2067{
2068 unsigned char *p = after;
2069
2070 while ((p = snd_usb_find_desc(buffer, buflen, p,
2071 USB_DT_CS_INTERFACE)) != NULL) {
2072 if (p[0] >= 3 && p[2] == dsubtype)
2073 return p;
2074 }
2075 return NULL;
2076}
2077
2078/*
2079 * Wrapper for usb_control_msg().
2080 * Allocates a temp buffer to prevent dmaing from/to the stack.
2081 */
2082int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe, __u8 request,
2083 __u8 requesttype, __u16 value, __u16 index, void *data,
2084 __u16 size, int timeout)
2085{
2086 int err;
2087 void *buf = NULL;
2088
2089 if (size > 0) {
2090 buf = kmemdup(data, size, GFP_KERNEL);
2091 if (!buf)
2092 return -ENOMEM;
2093 }
2094 err = usb_control_msg(dev, pipe, request, requesttype,
2095 value, index, buf, size, timeout);
2096 if (size > 0) {
2097 memcpy(data, buf, size);
2098 kfree(buf);
2099 }
2100 return err;
2101}
2102
2103
2104/*
2105 * entry point for linux usb interface
2106 */
2107
2108static int usb_audio_probe(struct usb_interface *intf,
2109 const struct usb_device_id *id);
2110static void usb_audio_disconnect(struct usb_interface *intf);
2111
2112#ifdef CONFIG_PM
2113static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message);
2114static int usb_audio_resume(struct usb_interface *intf);
2115#else
2116#define usb_audio_suspend NULL
2117#define usb_audio_resume NULL
2118#endif
2119
2120static struct usb_device_id usb_audio_ids [] = {
2121#include "usbquirks.h"
2122 { .match_flags = (USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS),
2123 .bInterfaceClass = USB_CLASS_AUDIO,
2124 .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL },
2125 { } /* Terminating entry */
2126};
2127
2128MODULE_DEVICE_TABLE (usb, usb_audio_ids);
2129
2130static struct usb_driver usb_audio_driver = {
2131 .name = "snd-usb-audio",
2132 .probe = usb_audio_probe,
2133 .disconnect = usb_audio_disconnect,
2134 .suspend = usb_audio_suspend,
2135 .resume = usb_audio_resume,
2136 .id_table = usb_audio_ids,
2137};
2138
2139
2140#if defined(CONFIG_PROC_FS) && defined(CONFIG_SND_VERBOSE_PROCFS)
2141
2142/*
2143 * proc interface for list the supported pcm formats
2144 */
2145static void proc_dump_substream_formats(struct snd_usb_substream *subs, struct snd_info_buffer *buffer)
2146{
2147 struct list_head *p;
2148 static char *sync_types[4] = {
2149 "NONE", "ASYNC", "ADAPTIVE", "SYNC"
2150 };
2151
2152 list_for_each(p, &subs->fmt_list) {
2153 struct audioformat *fp;
2154 fp = list_entry(p, struct audioformat, list);
2155 snd_iprintf(buffer, " Interface %d\n", fp->iface);
2156 snd_iprintf(buffer, " Altset %d\n", fp->altsetting);
2157 snd_iprintf(buffer, " Format: %s\n",
2158 snd_pcm_format_name(fp->format));
2159 snd_iprintf(buffer, " Channels: %d\n", fp->channels);
2160 snd_iprintf(buffer, " Endpoint: %d %s (%s)\n",
2161 fp->endpoint & USB_ENDPOINT_NUMBER_MASK,
2162 fp->endpoint & USB_DIR_IN ? "IN" : "OUT",
2163 sync_types[(fp->ep_attr & USB_ENDPOINT_SYNCTYPE) >> 2]);
2164 if (fp->rates & SNDRV_PCM_RATE_CONTINUOUS) {
2165 snd_iprintf(buffer, " Rates: %d - %d (continuous)\n",
2166 fp->rate_min, fp->rate_max);
2167 } else {
2168 unsigned int i;
2169 snd_iprintf(buffer, " Rates: ");
2170 for (i = 0; i < fp->nr_rates; i++) {
2171 if (i > 0)
2172 snd_iprintf(buffer, ", ");
2173 snd_iprintf(buffer, "%d", fp->rate_table[i]);
2174 }
2175 snd_iprintf(buffer, "\n");
2176 }
2177 if (snd_usb_get_speed(subs->dev) == USB_SPEED_HIGH)
2178 snd_iprintf(buffer, " Data packet interval: %d us\n",
2179 125 * (1 << fp->datainterval));
2180 // snd_iprintf(buffer, " Max Packet Size = %d\n", fp->maxpacksize);
2181 // snd_iprintf(buffer, " EP Attribute = %#x\n", fp->attributes);
2182 }
2183}
2184
2185static void proc_dump_substream_status(struct snd_usb_substream *subs, struct snd_info_buffer *buffer)
2186{
2187 if (subs->running) {
2188 unsigned int i;
2189 snd_iprintf(buffer, " Status: Running\n");
2190 snd_iprintf(buffer, " Interface = %d\n", subs->interface);
2191 snd_iprintf(buffer, " Altset = %d\n", subs->format);
2192 snd_iprintf(buffer, " URBs = %d [ ", subs->nurbs);
2193 for (i = 0; i < subs->nurbs; i++)
2194 snd_iprintf(buffer, "%d ", subs->dataurb[i].packets);
2195 snd_iprintf(buffer, "]\n");
2196 snd_iprintf(buffer, " Packet Size = %d\n", subs->curpacksize);
2197 snd_iprintf(buffer, " Momentary freq = %u Hz (%#x.%04x)\n",
2198 snd_usb_get_speed(subs->dev) == USB_SPEED_FULL
2199 ? get_full_speed_hz(subs->freqm)
2200 : get_high_speed_hz(subs->freqm),
2201 subs->freqm >> 16, subs->freqm & 0xffff);
2202 } else {
2203 snd_iprintf(buffer, " Status: Stop\n");
2204 }
2205}
2206
2207static void proc_pcm_format_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
2208{
2209 struct snd_usb_stream *stream = entry->private_data;
2210
2211 snd_iprintf(buffer, "%s : %s\n", stream->chip->card->longname, stream->pcm->name);
2212
2213 if (stream->substream[SNDRV_PCM_STREAM_PLAYBACK].num_formats) {
2214 snd_iprintf(buffer, "\nPlayback:\n");
2215 proc_dump_substream_status(&stream->substream[SNDRV_PCM_STREAM_PLAYBACK], buffer);
2216 proc_dump_substream_formats(&stream->substream[SNDRV_PCM_STREAM_PLAYBACK], buffer);
2217 }
2218 if (stream->substream[SNDRV_PCM_STREAM_CAPTURE].num_formats) {
2219 snd_iprintf(buffer, "\nCapture:\n");
2220 proc_dump_substream_status(&stream->substream[SNDRV_PCM_STREAM_CAPTURE], buffer);
2221 proc_dump_substream_formats(&stream->substream[SNDRV_PCM_STREAM_CAPTURE], buffer);
2222 }
2223}
2224
2225static void proc_pcm_format_add(struct snd_usb_stream *stream)
2226{
2227 struct snd_info_entry *entry;
2228 char name[32];
2229 struct snd_card *card = stream->chip->card;
2230
2231 sprintf(name, "stream%d", stream->pcm_index);
2232 if (!snd_card_proc_new(card, name, &entry))
2233 snd_info_set_text_ops(entry, stream, proc_pcm_format_read);
2234}
2235
2236#else
2237
2238static inline void proc_pcm_format_add(struct snd_usb_stream *stream)
2239{
2240}
2241
2242#endif
2243
2244/*
2245 * initialize the substream instance.
2246 */
2247
2248static void init_substream(struct snd_usb_stream *as, int stream, struct audioformat *fp)
2249{
2250 struct snd_usb_substream *subs = &as->substream[stream];
2251
2252 INIT_LIST_HEAD(&subs->fmt_list);
2253 spin_lock_init(&subs->lock);
2254
2255 subs->stream = as;
2256 subs->direction = stream;
2257 subs->dev = as->chip->dev;
2258 subs->txfr_quirk = as->chip->txfr_quirk;
2259 if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) {
2260 subs->ops = audio_urb_ops[stream];
2261 } else {
2262 subs->ops = audio_urb_ops_high_speed[stream];
2263 switch (as->chip->usb_id) {
2264 case USB_ID(0x041e, 0x3f02): /* E-Mu 0202 USB */
2265 case USB_ID(0x041e, 0x3f04): /* E-Mu 0404 USB */
2266 case USB_ID(0x041e, 0x3f0a): /* E-Mu Tracker Pre */
2267 subs->ops.retire_sync = retire_playback_sync_urb_hs_emu;
2268 break;
2269 }
2270 }
2271 snd_pcm_set_ops(as->pcm, stream,
2272 stream == SNDRV_PCM_STREAM_PLAYBACK ?
2273 &snd_usb_playback_ops : &snd_usb_capture_ops);
2274
2275 list_add_tail(&fp->list, &subs->fmt_list);
2276 subs->formats |= 1ULL << fp->format;
2277 subs->endpoint = fp->endpoint;
2278 subs->num_formats++;
2279 subs->fmt_type = fp->fmt_type;
2280}
2281
2282
2283/*
2284 * free a substream
2285 */
2286static void free_substream(struct snd_usb_substream *subs)
2287{
2288 struct list_head *p, *n;
2289
2290 if (!subs->num_formats)
2291 return; /* not initialized */
2292 list_for_each_safe(p, n, &subs->fmt_list) {
2293 struct audioformat *fp = list_entry(p, struct audioformat, list);
2294 kfree(fp->rate_table);
2295 kfree(fp);
2296 }
2297 kfree(subs->rate_list.list);
2298}
2299
2300
2301/*
2302 * free a usb stream instance
2303 */
2304static void snd_usb_audio_stream_free(struct snd_usb_stream *stream)
2305{
2306 free_substream(&stream->substream[0]);
2307 free_substream(&stream->substream[1]);
2308 list_del(&stream->list);
2309 kfree(stream);
2310}
2311
2312static void snd_usb_audio_pcm_free(struct snd_pcm *pcm)
2313{
2314 struct snd_usb_stream *stream = pcm->private_data;
2315 if (stream) {
2316 stream->pcm = NULL;
2317 snd_usb_audio_stream_free(stream);
2318 }
2319}
2320
2321
2322/*
2323 * add this endpoint to the chip instance.
2324 * if a stream with the same endpoint already exists, append to it.
2325 * if not, create a new pcm stream.
2326 */
2327static int add_audio_endpoint(struct snd_usb_audio *chip, int stream, struct audioformat *fp)
2328{
2329 struct list_head *p;
2330 struct snd_usb_stream *as;
2331 struct snd_usb_substream *subs;
2332 struct snd_pcm *pcm;
2333 int err;
2334
2335 list_for_each(p, &chip->pcm_list) {
2336 as = list_entry(p, struct snd_usb_stream, list);
2337 if (as->fmt_type != fp->fmt_type)
2338 continue;
2339 subs = &as->substream[stream];
2340 if (!subs->endpoint)
2341 continue;
2342 if (subs->endpoint == fp->endpoint) {
2343 list_add_tail(&fp->list, &subs->fmt_list);
2344 subs->num_formats++;
2345 subs->formats |= 1ULL << fp->format;
2346 return 0;
2347 }
2348 }
2349 /* look for an empty stream */
2350 list_for_each(p, &chip->pcm_list) {
2351 as = list_entry(p, struct snd_usb_stream, list);
2352 if (as->fmt_type != fp->fmt_type)
2353 continue;
2354 subs = &as->substream[stream];
2355 if (subs->endpoint)
2356 continue;
2357 err = snd_pcm_new_stream(as->pcm, stream, 1);
2358 if (err < 0)
2359 return err;
2360 init_substream(as, stream, fp);
2361 return 0;
2362 }
2363
2364 /* create a new pcm */
2365 as = kzalloc(sizeof(*as), GFP_KERNEL);
2366 if (!as)
2367 return -ENOMEM;
2368 as->pcm_index = chip->pcm_devs;
2369 as->chip = chip;
2370 as->fmt_type = fp->fmt_type;
2371 err = snd_pcm_new(chip->card, "USB Audio", chip->pcm_devs,
2372 stream == SNDRV_PCM_STREAM_PLAYBACK ? 1 : 0,
2373 stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1,
2374 &pcm);
2375 if (err < 0) {
2376 kfree(as);
2377 return err;
2378 }
2379 as->pcm = pcm;
2380 pcm->private_data = as;
2381 pcm->private_free = snd_usb_audio_pcm_free;
2382 pcm->info_flags = 0;
2383 if (chip->pcm_devs > 0)
2384 sprintf(pcm->name, "USB Audio #%d", chip->pcm_devs);
2385 else
2386 strcpy(pcm->name, "USB Audio");
2387
2388 init_substream(as, stream, fp);
2389
2390 list_add(&as->list, &chip->pcm_list);
2391 chip->pcm_devs++;
2392
2393 proc_pcm_format_add(as);
2394
2395 return 0;
2396}
2397
2398
2399/*
2400 * check if the device uses big-endian samples
2401 */
2402static int is_big_endian_format(struct snd_usb_audio *chip, struct audioformat *fp)
2403{
2404 switch (chip->usb_id) {
2405 case USB_ID(0x0763, 0x2001): /* M-Audio Quattro: captured data only */
2406 if (fp->endpoint & USB_DIR_IN)
2407 return 1;
2408 break;
2409 case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
2410 if (device_setup[chip->index] == 0x00 ||
2411 fp->altsetting==1 || fp->altsetting==2 || fp->altsetting==3)
2412 return 1;
2413 }
2414 return 0;
2415}
2416
2417/*
2418 * parse the audio format type I descriptor
2419 * and returns the corresponding pcm format
2420 *
2421 * @dev: usb device
2422 * @fp: audioformat record
2423 * @format: the format tag (wFormatTag)
2424 * @fmt: the format type descriptor
2425 */
2426static int parse_audio_format_i_type(struct snd_usb_audio *chip,
2427 struct audioformat *fp,
2428 int format, void *_fmt,
2429 int protocol)
2430{
2431 int pcm_format, i;
2432 int sample_width, sample_bytes;
2433
2434 switch (protocol) {
2435 case UAC_VERSION_1: {
2436 struct uac_format_type_i_discrete_descriptor *fmt = _fmt;
2437 sample_width = fmt->bBitResolution;
2438 sample_bytes = fmt->bSubframeSize;
2439 break;
2440 }
2441
2442 case UAC_VERSION_2: {
2443 struct uac_format_type_i_ext_descriptor *fmt = _fmt;
2444 sample_width = fmt->bBitResolution;
2445 sample_bytes = fmt->bSubslotSize;
2446
2447 /*
2448 * FIXME
2449 * USB audio class v2 devices specify a bitmap of possible
2450 * audio formats rather than one fix value. For now, we just
2451 * pick one of them and report that as the only possible
2452 * value for this setting.
2453 * The bit allocation map is in fact compatible to the
2454 * wFormatTag of the v1 AS streaming descriptors, which is why
2455 * we can simply map the matrix.
2456 */
2457
2458 for (i = 0; i < 5; i++)
2459 if (format & (1UL << i)) {
2460 format = i + 1;
2461 break;
2462 }
2463
2464 break;
2465 }
2466
2467 default:
2468 return -EINVAL;
2469 }
2470
2471 /* FIXME: correct endianess and sign? */
2472 pcm_format = -1;
2473
2474 switch (format) {
2475 case UAC_FORMAT_TYPE_I_UNDEFINED: /* some devices don't define this correctly... */
2476 snd_printdd(KERN_INFO "%d:%u:%d : format type 0 is detected, processed as PCM\n",
2477 chip->dev->devnum, fp->iface, fp->altsetting);
2478 /* fall-through */
2479 case UAC_FORMAT_TYPE_I_PCM:
2480 if (sample_width > sample_bytes * 8) {
2481 snd_printk(KERN_INFO "%d:%u:%d : sample bitwidth %d in over sample bytes %d\n",
2482 chip->dev->devnum, fp->iface, fp->altsetting,
2483 sample_width, sample_bytes);
2484 }
2485 /* check the format byte size */
2486 switch (sample_bytes) {
2487 case 1:
2488 pcm_format = SNDRV_PCM_FORMAT_S8;
2489 break;
2490 case 2:
2491 if (is_big_endian_format(chip, fp))
2492 pcm_format = SNDRV_PCM_FORMAT_S16_BE; /* grrr, big endian!! */
2493 else
2494 pcm_format = SNDRV_PCM_FORMAT_S16_LE;
2495 break;
2496 case 3:
2497 if (is_big_endian_format(chip, fp))
2498 pcm_format = SNDRV_PCM_FORMAT_S24_3BE; /* grrr, big endian!! */
2499 else
2500 pcm_format = SNDRV_PCM_FORMAT_S24_3LE;
2501 break;
2502 case 4:
2503 pcm_format = SNDRV_PCM_FORMAT_S32_LE;
2504 break;
2505 default:
2506 snd_printk(KERN_INFO "%d:%u:%d : unsupported sample bitwidth %d in %d bytes\n",
2507 chip->dev->devnum, fp->iface, fp->altsetting,
2508 sample_width, sample_bytes);
2509 break;
2510 }
2511 break;
2512 case UAC_FORMAT_TYPE_I_PCM8:
2513 pcm_format = SNDRV_PCM_FORMAT_U8;
2514
2515 /* Dallas DS4201 workaround: it advertises U8 format, but really
2516 supports S8. */
2517 if (chip->usb_id == USB_ID(0x04fa, 0x4201))
2518 pcm_format = SNDRV_PCM_FORMAT_S8;
2519 break;
2520 case UAC_FORMAT_TYPE_I_IEEE_FLOAT:
2521 pcm_format = SNDRV_PCM_FORMAT_FLOAT_LE;
2522 break;
2523 case UAC_FORMAT_TYPE_I_ALAW:
2524 pcm_format = SNDRV_PCM_FORMAT_A_LAW;
2525 break;
2526 case UAC_FORMAT_TYPE_I_MULAW:
2527 pcm_format = SNDRV_PCM_FORMAT_MU_LAW;
2528 break;
2529 default:
2530 snd_printk(KERN_INFO "%d:%u:%d : unsupported format type %d\n",
2531 chip->dev->devnum, fp->iface, fp->altsetting, format);
2532 break;
2533 }
2534 return pcm_format;
2535}
2536
2537
2538/*
2539 * parse the format descriptor and stores the possible sample rates
2540 * on the audioformat table (audio class v1).
2541 *
2542 * @dev: usb device
2543 * @fp: audioformat record
2544 * @fmt: the format descriptor
2545 * @offset: the start offset of descriptor pointing the rate type
2546 * (7 for type I and II, 8 for type II)
2547 */
2548static int parse_audio_format_rates_v1(struct snd_usb_audio *chip, struct audioformat *fp,
2549 unsigned char *fmt, int offset)
2550{
2551 int nr_rates = fmt[offset];
2552
2553 if (fmt[0] < offset + 1 + 3 * (nr_rates ? nr_rates : 2)) {
2554 snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n",
2555 chip->dev->devnum, fp->iface, fp->altsetting);
2556 return -1;
2557 }
2558
2559 if (nr_rates) {
2560 /*
2561 * build the rate table and bitmap flags
2562 */
2563 int r, idx;
2564
2565 fp->rate_table = kmalloc(sizeof(int) * nr_rates, GFP_KERNEL);
2566 if (fp->rate_table == NULL) {
2567 snd_printk(KERN_ERR "cannot malloc\n");
2568 return -1;
2569 }
2570
2571 fp->nr_rates = 0;
2572 fp->rate_min = fp->rate_max = 0;
2573 for (r = 0, idx = offset + 1; r < nr_rates; r++, idx += 3) {
2574 unsigned int rate = combine_triple(&fmt[idx]);
2575 if (!rate)
2576 continue;
2577 /* C-Media CM6501 mislabels its 96 kHz altsetting */
2578 if (rate == 48000 && nr_rates == 1 &&
2579 (chip->usb_id == USB_ID(0x0d8c, 0x0201) ||
2580 chip->usb_id == USB_ID(0x0d8c, 0x0102)) &&
2581 fp->altsetting == 5 && fp->maxpacksize == 392)
2582 rate = 96000;
2583 /* Creative VF0470 Live Cam reports 16 kHz instead of 8kHz */
2584 if (rate == 16000 && chip->usb_id == USB_ID(0x041e, 0x4068))
2585 rate = 8000;
2586 fp->rate_table[fp->nr_rates] = rate;
2587 if (!fp->rate_min || rate < fp->rate_min)
2588 fp->rate_min = rate;
2589 if (!fp->rate_max || rate > fp->rate_max)
2590 fp->rate_max = rate;
2591 fp->rates |= snd_pcm_rate_to_rate_bit(rate);
2592 fp->nr_rates++;
2593 }
2594 if (!fp->nr_rates) {
2595 hwc_debug("All rates were zero. Skipping format!\n");
2596 return -1;
2597 }
2598 } else {
2599 /* continuous rates */
2600 fp->rates = SNDRV_PCM_RATE_CONTINUOUS;
2601 fp->rate_min = combine_triple(&fmt[offset + 1]);
2602 fp->rate_max = combine_triple(&fmt[offset + 4]);
2603 }
2604 return 0;
2605}
2606
2607/*
2608 * parse the format descriptor and stores the possible sample rates
2609 * on the audioformat table (audio class v2).
2610 */
2611static int parse_audio_format_rates_v2(struct snd_usb_audio *chip,
2612 struct audioformat *fp,
2613 struct usb_host_interface *iface)
2614{
2615 struct usb_device *dev = chip->dev;
2616 unsigned char tmp[2], *data;
2617 int i, nr_rates, data_size, ret = 0;
2618
2619 /* get the number of sample rates first by only fetching 2 bytes */
2620 ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_RANGE,
2621 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
2622 0x0100, chip->clock_id << 8, tmp, sizeof(tmp), 1000);
2623
2624 if (ret < 0) {
2625 snd_printk(KERN_ERR "unable to retrieve number of sample rates\n");
2626 goto err;
2627 }
2628
2629 nr_rates = (tmp[1] << 8) | tmp[0];
2630 data_size = 2 + 12 * nr_rates;
2631 data = kzalloc(data_size, GFP_KERNEL);
2632 if (!data) {
2633 ret = -ENOMEM;
2634 goto err;
2635 }
2636
2637 /* now get the full information */
2638 ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_RANGE,
2639 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
2640 0x0100, chip->clock_id << 8, data, data_size, 1000);
2641
2642 if (ret < 0) {
2643 snd_printk(KERN_ERR "unable to retrieve sample rate range\n");
2644 ret = -EINVAL;
2645 goto err_free;
2646 }
2647
2648 fp->rate_table = kmalloc(sizeof(int) * nr_rates, GFP_KERNEL);
2649 if (!fp->rate_table) {
2650 ret = -ENOMEM;
2651 goto err_free;
2652 }
2653
2654 fp->nr_rates = 0;
2655 fp->rate_min = fp->rate_max = 0;
2656
2657 for (i = 0; i < nr_rates; i++) {
2658 int rate = combine_quad(&data[2 + 12 * i]);
2659
2660 fp->rate_table[fp->nr_rates] = rate;
2661 if (!fp->rate_min || rate < fp->rate_min)
2662 fp->rate_min = rate;
2663 if (!fp->rate_max || rate > fp->rate_max)
2664 fp->rate_max = rate;
2665 fp->rates |= snd_pcm_rate_to_rate_bit(rate);
2666 fp->nr_rates++;
2667 }
2668
2669err_free:
2670 kfree(data);
2671err:
2672 return ret;
2673}
2674
2675/*
2676 * parse the format type I and III descriptors
2677 */
2678static int parse_audio_format_i(struct snd_usb_audio *chip,
2679 struct audioformat *fp,
2680 int format, void *_fmt,
2681 struct usb_host_interface *iface)
2682{
2683 struct usb_interface_descriptor *altsd = get_iface_desc(iface);
2684 struct uac_format_type_i_discrete_descriptor *fmt = _fmt;
2685 int protocol = altsd->bInterfaceProtocol;
2686 int pcm_format, ret;
2687
2688 if (fmt->bFormatType == UAC_FORMAT_TYPE_III) {
2689 /* FIXME: the format type is really IECxxx
2690 * but we give normal PCM format to get the existing
2691 * apps working...
2692 */
2693 switch (chip->usb_id) {
2694
2695 case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
2696 if (device_setup[chip->index] == 0x00 &&
2697 fp->altsetting == 6)
2698 pcm_format = SNDRV_PCM_FORMAT_S16_BE;
2699 else
2700 pcm_format = SNDRV_PCM_FORMAT_S16_LE;
2701 break;
2702 default:
2703 pcm_format = SNDRV_PCM_FORMAT_S16_LE;
2704 }
2705 } else {
2706 pcm_format = parse_audio_format_i_type(chip, fp, format, fmt, protocol);
2707 if (pcm_format < 0)
2708 return -1;
2709 }
2710
2711 fp->format = pcm_format;
2712
2713 /* gather possible sample rates */
2714 /* audio class v1 reports possible sample rates as part of the
2715 * proprietary class specific descriptor.
2716 * audio class v2 uses class specific EP0 range requests for that.
2717 */
2718 switch (protocol) {
2719 case UAC_VERSION_1:
2720 fp->channels = fmt->bNrChannels;
2721 ret = parse_audio_format_rates_v1(chip, fp, _fmt, 7);
2722 break;
2723 case UAC_VERSION_2:
2724 /* fp->channels is already set in this case */
2725 ret = parse_audio_format_rates_v2(chip, fp, iface);
2726 break;
2727 }
2728
2729 if (fp->channels < 1) {
2730 snd_printk(KERN_ERR "%d:%u:%d : invalid channels %d\n",
2731 chip->dev->devnum, fp->iface, fp->altsetting, fp->channels);
2732 return -1;
2733 }
2734
2735 return ret;
2736}
2737
2738/*
2739 * parse the format type II descriptor
2740 */
2741static int parse_audio_format_ii(struct snd_usb_audio *chip,
2742 struct audioformat *fp,
2743 int format, void *_fmt,
2744 struct usb_host_interface *iface)
2745{
2746 int brate, framesize, ret;
2747 struct usb_interface_descriptor *altsd = get_iface_desc(iface);
2748 int protocol = altsd->bInterfaceProtocol;
2749
2750 switch (format) {
2751 case UAC_FORMAT_TYPE_II_AC3:
2752 /* FIXME: there is no AC3 format defined yet */
2753 // fp->format = SNDRV_PCM_FORMAT_AC3;
2754 fp->format = SNDRV_PCM_FORMAT_U8; /* temporarily hack to receive byte streams */
2755 break;
2756 case UAC_FORMAT_TYPE_II_MPEG:
2757 fp->format = SNDRV_PCM_FORMAT_MPEG;
2758 break;
2759 default:
2760 snd_printd(KERN_INFO "%d:%u:%d : unknown format tag %#x is detected. processed as MPEG.\n",
2761 chip->dev->devnum, fp->iface, fp->altsetting, format);
2762 fp->format = SNDRV_PCM_FORMAT_MPEG;
2763 break;
2764 }
2765
2766 fp->channels = 1;
2767
2768 switch (protocol) {
2769 case UAC_VERSION_1: {
2770 struct uac_format_type_ii_discrete_descriptor *fmt = _fmt;
2771 brate = le16_to_cpu(fmt->wMaxBitRate);
2772 framesize = le16_to_cpu(fmt->wSamplesPerFrame);
2773 snd_printd(KERN_INFO "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize);
2774 fp->frame_size = framesize;
2775 ret = parse_audio_format_rates_v1(chip, fp, _fmt, 8); /* fmt[8..] sample rates */
2776 break;
2777 }
2778 case UAC_VERSION_2: {
2779 struct uac_format_type_ii_ext_descriptor *fmt = _fmt;
2780 brate = le16_to_cpu(fmt->wMaxBitRate);
2781 framesize = le16_to_cpu(fmt->wSamplesPerFrame);
2782 snd_printd(KERN_INFO "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize);
2783 fp->frame_size = framesize;
2784 ret = parse_audio_format_rates_v2(chip, fp, iface);
2785 break;
2786 }
2787 }
2788
2789 return ret;
2790}
2791
2792static int parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp,
2793 int format, unsigned char *fmt, int stream,
2794 struct usb_host_interface *iface)
2795{
2796 int err;
2797
2798 switch (fmt[3]) {
2799 case UAC_FORMAT_TYPE_I:
2800 case UAC_FORMAT_TYPE_III:
2801 err = parse_audio_format_i(chip, fp, format, fmt, iface);
2802 break;
2803 case UAC_FORMAT_TYPE_II:
2804 err = parse_audio_format_ii(chip, fp, format, fmt, iface);
2805 break;
2806 default:
2807 snd_printd(KERN_INFO "%d:%u:%d : format type %d is not supported yet\n",
2808 chip->dev->devnum, fp->iface, fp->altsetting, fmt[3]);
2809 return -1;
2810 }
2811 fp->fmt_type = fmt[3];
2812 if (err < 0)
2813 return err;
2814#if 1
2815 /* FIXME: temporary hack for extigy/audigy 2 nx/zs */
2816 /* extigy apparently supports sample rates other than 48k
2817 * but not in ordinary way. so we enable only 48k atm.
2818 */
2819 if (chip->usb_id == USB_ID(0x041e, 0x3000) ||
2820 chip->usb_id == USB_ID(0x041e, 0x3020) ||
2821 chip->usb_id == USB_ID(0x041e, 0x3061)) {
2822 if (fmt[3] == UAC_FORMAT_TYPE_I &&
2823 fp->rates != SNDRV_PCM_RATE_48000 &&
2824 fp->rates != SNDRV_PCM_RATE_96000)
2825 return -1;
2826 }
2827#endif
2828 return 0;
2829}
2830
2831static unsigned char parse_datainterval(struct snd_usb_audio *chip,
2832 struct usb_host_interface *alts)
2833{
2834 if (snd_usb_get_speed(chip->dev) == USB_SPEED_HIGH &&
2835 get_endpoint(alts, 0)->bInterval >= 1 &&
2836 get_endpoint(alts, 0)->bInterval <= 4)
2837 return get_endpoint(alts, 0)->bInterval - 1;
2838 else
2839 return 0;
2840}
2841
2842static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip,
2843 int iface, int altno);
2844static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
2845{
2846 struct usb_device *dev;
2847 struct usb_interface *iface;
2848 struct usb_host_interface *alts;
2849 struct usb_interface_descriptor *altsd;
2850 int i, altno, err, stream;
2851 int format = 0, num_channels = 0;
2852 struct audioformat *fp = NULL;
2853 unsigned char *fmt, *csep;
2854 int num, protocol;
2855
2856 dev = chip->dev;
2857
2858 /* parse the interface's altsettings */
2859 iface = usb_ifnum_to_if(dev, iface_no);
2860
2861 num = iface->num_altsetting;
2862
2863 /*
2864 * Dallas DS4201 workaround: It presents 5 altsettings, but the last
2865 * one misses syncpipe, and does not produce any sound.
2866 */
2867 if (chip->usb_id == USB_ID(0x04fa, 0x4201))
2868 num = 4;
2869
2870 for (i = 0; i < num; i++) {
2871 alts = &iface->altsetting[i];
2872 altsd = get_iface_desc(alts);
2873 protocol = altsd->bInterfaceProtocol;
2874 /* skip invalid one */
2875 if ((altsd->bInterfaceClass != USB_CLASS_AUDIO &&
2876 altsd->bInterfaceClass != USB_CLASS_VENDOR_SPEC) ||
2877 (altsd->bInterfaceSubClass != USB_SUBCLASS_AUDIOSTREAMING &&
2878 altsd->bInterfaceSubClass != USB_SUBCLASS_VENDOR_SPEC) ||
2879 altsd->bNumEndpoints < 1 ||
2880 le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) == 0)
2881 continue;
2882 /* must be isochronous */
2883 if ((get_endpoint(alts, 0)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) !=
2884 USB_ENDPOINT_XFER_ISOC)
2885 continue;
2886 /* check direction */
2887 stream = (get_endpoint(alts, 0)->bEndpointAddress & USB_DIR_IN) ?
2888 SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
2889 altno = altsd->bAlternateSetting;
2890
2891 /* audiophile usb: skip altsets incompatible with device_setup
2892 */
2893 if (chip->usb_id == USB_ID(0x0763, 0x2003) &&
2894 audiophile_skip_setting_quirk(chip, iface_no, altno))
2895 continue;
2896
2897 /* get audio formats */
2898 switch (protocol) {
2899 case UAC_VERSION_1: {
2900 struct uac_as_header_descriptor_v1 *as =
2901 snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL);
2902
2903 if (!as) {
2904 snd_printk(KERN_ERR "%d:%u:%d : UAC_AS_GENERAL descriptor not found\n",
2905 dev->devnum, iface_no, altno);
2906 continue;
2907 }
2908
2909 if (as->bLength < sizeof(*as)) {
2910 snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_AS_GENERAL desc\n",
2911 dev->devnum, iface_no, altno);
2912 continue;
2913 }
2914
2915 format = le16_to_cpu(as->wFormatTag); /* remember the format value */
2916 break;
2917 }
2918
2919 case UAC_VERSION_2: {
2920 struct uac_as_header_descriptor_v2 *as =
2921 snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL);
2922
2923 if (!as) {
2924 snd_printk(KERN_ERR "%d:%u:%d : UAC_AS_GENERAL descriptor not found\n",
2925 dev->devnum, iface_no, altno);
2926 continue;
2927 }
2928
2929 if (as->bLength < sizeof(*as)) {
2930 snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_AS_GENERAL desc\n",
2931 dev->devnum, iface_no, altno);
2932 continue;
2933 }
2934
2935 num_channels = as->bNrChannels;
2936 format = le32_to_cpu(as->bmFormats);
2937
2938 break;
2939 }
2940
2941 default:
2942 snd_printk(KERN_ERR "%d:%u:%d : unknown interface protocol %04x\n",
2943 dev->devnum, iface_no, altno, protocol);
2944 continue;
2945 }
2946
2947 /* get format type */
2948 fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_FORMAT_TYPE);
2949 if (!fmt) {
2950 snd_printk(KERN_ERR "%d:%u:%d : no UAC_FORMAT_TYPE desc\n",
2951 dev->devnum, iface_no, altno);
2952 continue;
2953 }
2954 if (((protocol == UAC_VERSION_1) && (fmt[0] < 8)) ||
2955 ((protocol == UAC_VERSION_2) && (fmt[0] != 6))) {
2956 snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n",
2957 dev->devnum, iface_no, altno);
2958 continue;
2959 }
2960
2961 /*
2962 * Blue Microphones workaround: The last altsetting is identical
2963 * with the previous one, except for a larger packet size, but
2964 * is actually a mislabeled two-channel setting; ignore it.
2965 */
2966 if (fmt[4] == 1 && fmt[5] == 2 && altno == 2 && num == 3 &&
2967 fp && fp->altsetting == 1 && fp->channels == 1 &&
2968 fp->format == SNDRV_PCM_FORMAT_S16_LE &&
2969 protocol == UAC_VERSION_1 &&
2970 le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) ==
2971 fp->maxpacksize * 2)
2972 continue;
2973
2974 csep = snd_usb_find_desc(alts->endpoint[0].extra, alts->endpoint[0].extralen, NULL, USB_DT_CS_ENDPOINT);
2975 /* Creamware Noah has this descriptor after the 2nd endpoint */
2976 if (!csep && altsd->bNumEndpoints >= 2)
2977 csep = snd_usb_find_desc(alts->endpoint[1].extra, alts->endpoint[1].extralen, NULL, USB_DT_CS_ENDPOINT);
2978 if (!csep || csep[0] < 7 || csep[2] != UAC_EP_GENERAL) {
2979 snd_printk(KERN_WARNING "%d:%u:%d : no or invalid"
2980 " class specific endpoint descriptor\n",
2981 dev->devnum, iface_no, altno);
2982 csep = NULL;
2983 }
2984
2985 fp = kzalloc(sizeof(*fp), GFP_KERNEL);
2986 if (! fp) {
2987 snd_printk(KERN_ERR "cannot malloc\n");
2988 return -ENOMEM;
2989 }
2990
2991 fp->iface = iface_no;
2992 fp->altsetting = altno;
2993 fp->altset_idx = i;
2994 fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress;
2995 fp->ep_attr = get_endpoint(alts, 0)->bmAttributes;
2996 fp->datainterval = parse_datainterval(chip, alts);
2997 fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
2998 /* num_channels is only set for v2 interfaces */
2999 fp->channels = num_channels;
3000 if (snd_usb_get_speed(dev) == USB_SPEED_HIGH)
3001 fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1)
3002 * (fp->maxpacksize & 0x7ff);
3003 fp->attributes = csep ? csep[3] : 0;
3004
3005 /* some quirks for attributes here */
3006
3007 switch (chip->usb_id) {
3008 case USB_ID(0x0a92, 0x0053): /* AudioTrak Optoplay */
3009 /* Optoplay sets the sample rate attribute although
3010 * it seems not supporting it in fact.
3011 */
3012 fp->attributes &= ~UAC_EP_CS_ATTR_SAMPLE_RATE;
3013 break;
3014 case USB_ID(0x041e, 0x3020): /* Creative SB Audigy 2 NX */
3015 case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
3016 /* doesn't set the sample rate attribute, but supports it */
3017 fp->attributes |= UAC_EP_CS_ATTR_SAMPLE_RATE;
3018 break;
3019 case USB_ID(0x047f, 0x0ca1): /* plantronics headset */
3020 case USB_ID(0x077d, 0x07af): /* Griffin iMic (note that there is
3021 an older model 77d:223) */
3022 /*
3023 * plantronics headset and Griffin iMic have set adaptive-in
3024 * although it's really not...
3025 */
3026 fp->ep_attr &= ~USB_ENDPOINT_SYNCTYPE;
3027 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
3028 fp->ep_attr |= USB_ENDPOINT_SYNC_ADAPTIVE;
3029 else
3030 fp->ep_attr |= USB_ENDPOINT_SYNC_SYNC;
3031 break;
3032 }
3033
3034 /* ok, let's parse further... */
3035 if (parse_audio_format(chip, fp, format, fmt, stream, alts) < 0) {
3036 kfree(fp->rate_table);
3037 kfree(fp);
3038 continue;
3039 }
3040
3041 snd_printdd(KERN_INFO "%d:%u:%d: add audio endpoint %#x\n", dev->devnum, iface_no, altno, fp->endpoint);
3042 err = add_audio_endpoint(chip, stream, fp);
3043 if (err < 0) {
3044 kfree(fp->rate_table);
3045 kfree(fp);
3046 return err;
3047 }
3048 /* try to set the interface... */
3049 usb_set_interface(chip->dev, iface_no, altno);
3050 init_usb_pitch(chip->dev, iface_no, alts, fp);
3051 init_usb_sample_rate(chip->dev, iface_no, alts, fp, fp->rate_max);
3052 }
3053 return 0;
3054}
3055
3056
3057/*
3058 * disconnect streams
3059 * called from snd_usb_audio_disconnect()
3060 */
3061static void snd_usb_stream_disconnect(struct list_head *head)
3062{
3063 int idx;
3064 struct snd_usb_stream *as;
3065 struct snd_usb_substream *subs;
3066
3067 as = list_entry(head, struct snd_usb_stream, list);
3068 for (idx = 0; idx < 2; idx++) {
3069 subs = &as->substream[idx];
3070 if (!subs->num_formats)
3071 return;
3072 release_substream_urbs(subs, 1);
3073 subs->interface = -1;
3074 }
3075}
3076
3077static int snd_usb_create_stream(struct snd_usb_audio *chip, int ctrlif, int interface)
3078{
3079 struct usb_device *dev = chip->dev;
3080 struct usb_host_interface *alts;
3081 struct usb_interface_descriptor *altsd;
3082 struct usb_interface *iface = usb_ifnum_to_if(dev, interface);
3083
3084 if (!iface) {
3085 snd_printk(KERN_ERR "%d:%u:%d : does not exist\n",
3086 dev->devnum, ctrlif, interface);
3087 return -EINVAL;
3088 }
3089
3090 if (usb_interface_claimed(iface)) {
3091 snd_printdd(KERN_INFO "%d:%d:%d: skipping, already claimed\n",
3092 dev->devnum, ctrlif, interface);
3093 return -EINVAL;
3094 }
3095
3096 alts = &iface->altsetting[0];
3097 altsd = get_iface_desc(alts);
3098 if ((altsd->bInterfaceClass == USB_CLASS_AUDIO ||
3099 altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC) &&
3100 altsd->bInterfaceSubClass == USB_SUBCLASS_MIDISTREAMING) {
3101 int err = snd_usbmidi_create(chip->card, iface,
3102 &chip->midi_list, NULL);
3103 if (err < 0) {
3104 snd_printk(KERN_ERR "%d:%u:%d: cannot create sequencer device\n",
3105 dev->devnum, ctrlif, interface);
3106 return -EINVAL;
3107 }
3108 usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L);
3109
3110 return 0;
3111 }
3112
3113 if ((altsd->bInterfaceClass != USB_CLASS_AUDIO &&
3114 altsd->bInterfaceClass != USB_CLASS_VENDOR_SPEC) ||
3115 altsd->bInterfaceSubClass != USB_SUBCLASS_AUDIOSTREAMING) {
3116 snd_printdd(KERN_ERR "%d:%u:%d: skipping non-supported interface %d\n",
3117 dev->devnum, ctrlif, interface, altsd->bInterfaceClass);
3118 /* skip non-supported classes */
3119 return -EINVAL;
3120 }
3121
3122 if (snd_usb_get_speed(dev) == USB_SPEED_LOW) {
3123 snd_printk(KERN_ERR "low speed audio streaming not supported\n");
3124 return -EINVAL;
3125 }
3126
3127 if (! parse_audio_endpoints(chip, interface)) {
3128 usb_set_interface(dev, interface, 0); /* reset the current interface */
3129 usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L);
3130 return -EINVAL;
3131 }
3132
3133 return 0;
3134}
3135
3136/*
3137 * parse audio control descriptor and create pcm/midi streams
3138 */
3139static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
3140{
3141 struct usb_device *dev = chip->dev;
3142 struct usb_host_interface *host_iface;
3143 struct usb_interface_descriptor *altsd;
3144 void *control_header;
3145 int i, protocol;
3146
3147 /* find audiocontrol interface */
3148 host_iface = &usb_ifnum_to_if(dev, ctrlif)->altsetting[0];
3149 control_header = snd_usb_find_csint_desc(host_iface->extra,
3150 host_iface->extralen,
3151 NULL, UAC_HEADER);
3152 altsd = get_iface_desc(host_iface);
3153 protocol = altsd->bInterfaceProtocol;
3154
3155 if (!control_header) {
3156 snd_printk(KERN_ERR "cannot find UAC_HEADER\n");
3157 return -EINVAL;
3158 }
3159
3160 switch (protocol) {
3161 case UAC_VERSION_1: {
3162 struct uac_ac_header_descriptor_v1 *h1 = control_header;
3163
3164 if (!h1->bInCollection) {
3165 snd_printk(KERN_INFO "skipping empty audio interface (v1)\n");
3166 return -EINVAL;
3167 }
3168
3169 if (h1->bLength < sizeof(*h1) + h1->bInCollection) {
3170 snd_printk(KERN_ERR "invalid UAC_HEADER (v1)\n");
3171 return -EINVAL;
3172 }
3173
3174 for (i = 0; i < h1->bInCollection; i++)
3175 snd_usb_create_stream(chip, ctrlif, h1->baInterfaceNr[i]);
3176
3177 break;
3178 }
3179
3180 case UAC_VERSION_2: {
3181 struct uac_clock_source_descriptor *cs;
3182 struct usb_interface_assoc_descriptor *assoc =
3183 usb_ifnum_to_if(dev, ctrlif)->intf_assoc;
3184
3185 if (!assoc) {
3186 snd_printk(KERN_ERR "Audio class v2 interfaces need an interface association\n");
3187 return -EINVAL;
3188 }
3189
3190 /* FIXME: for now, we expect there is at least one clock source
3191 * descriptor and we always take the first one.
3192 * We should properly support devices with multiple clock sources,
3193 * clock selectors and sample rate conversion units. */
3194
3195 cs = snd_usb_find_csint_desc(host_iface->extra, host_iface->extralen,
3196 NULL, UAC_CLOCK_SOURCE);
3197
3198 if (!cs) {
3199 snd_printk(KERN_ERR "CLOCK_SOURCE descriptor not found\n");
3200 return -EINVAL;
3201 }
3202
3203 chip->clock_id = cs->bClockID;
3204
3205 for (i = 0; i < assoc->bInterfaceCount; i++) {
3206 int intf = assoc->bFirstInterface + i;
3207
3208 if (intf != ctrlif)
3209 snd_usb_create_stream(chip, ctrlif, intf);
3210 }
3211
3212 break;
3213 }
3214
3215 default:
3216 snd_printk(KERN_ERR "unknown protocol version 0x%02x\n", protocol);
3217 return -EINVAL;
3218 }
3219
3220 return 0;
3221}
3222
3223/*
3224 * create a stream for an endpoint/altsetting without proper descriptors
3225 */
3226static int create_fixed_stream_quirk(struct snd_usb_audio *chip,
3227 struct usb_interface *iface,
3228 const struct snd_usb_audio_quirk *quirk)
3229{
3230 struct audioformat *fp;
3231 struct usb_host_interface *alts;
3232 int stream, err;
3233 unsigned *rate_table = NULL;
3234
3235 fp = kmemdup(quirk->data, sizeof(*fp), GFP_KERNEL);
3236 if (! fp) {
3237 snd_printk(KERN_ERR "cannot memdup\n");
3238 return -ENOMEM;
3239 }
3240 if (fp->nr_rates > 0) {
3241 rate_table = kmalloc(sizeof(int) * fp->nr_rates, GFP_KERNEL);
3242 if (!rate_table) {
3243 kfree(fp);
3244 return -ENOMEM;
3245 }
3246 memcpy(rate_table, fp->rate_table, sizeof(int) * fp->nr_rates);
3247 fp->rate_table = rate_table;
3248 }
3249
3250 stream = (fp->endpoint & USB_DIR_IN)
3251 ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
3252 err = add_audio_endpoint(chip, stream, fp);
3253 if (err < 0) {
3254 kfree(fp);
3255 kfree(rate_table);
3256 return err;
3257 }
3258 if (fp->iface != get_iface_desc(&iface->altsetting[0])->bInterfaceNumber ||
3259 fp->altset_idx >= iface->num_altsetting) {
3260 kfree(fp);
3261 kfree(rate_table);
3262 return -EINVAL;
3263 }
3264 alts = &iface->altsetting[fp->altset_idx];
3265 fp->datainterval = parse_datainterval(chip, alts);
3266 fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
3267 usb_set_interface(chip->dev, fp->iface, 0);
3268 init_usb_pitch(chip->dev, fp->iface, alts, fp);
3269 init_usb_sample_rate(chip->dev, fp->iface, alts, fp, fp->rate_max);
3270 return 0;
3271}
3272
3273/*
3274 * create a stream for an interface with proper descriptors
3275 */
3276static int create_standard_audio_quirk(struct snd_usb_audio *chip,
3277 struct usb_interface *iface,
3278 const struct snd_usb_audio_quirk *quirk)
3279{
3280 struct usb_host_interface *alts;
3281 struct usb_interface_descriptor *altsd;
3282 int err;
3283
3284 alts = &iface->altsetting[0];
3285 altsd = get_iface_desc(alts);
3286 err = parse_audio_endpoints(chip, altsd->bInterfaceNumber);
3287 if (err < 0) {
3288 snd_printk(KERN_ERR "cannot setup if %d: error %d\n",
3289 altsd->bInterfaceNumber, err);
3290 return err;
3291 }
3292 /* reset the current interface */
3293 usb_set_interface(chip->dev, altsd->bInterfaceNumber, 0);
3294 return 0;
3295}
3296
3297/*
3298 * Create a stream for an Edirol UA-700/UA-25/UA-4FX interface.
3299 * The only way to detect the sample rate is by looking at wMaxPacketSize.
3300 */
3301static int create_uaxx_quirk(struct snd_usb_audio *chip,
3302 struct usb_interface *iface,
3303 const struct snd_usb_audio_quirk *quirk)
3304{
3305 static const struct audioformat ua_format = {
3306 .format = SNDRV_PCM_FORMAT_S24_3LE,
3307 .channels = 2,
3308 .fmt_type = UAC_FORMAT_TYPE_I,
3309 .altsetting = 1,
3310 .altset_idx = 1,
3311 .rates = SNDRV_PCM_RATE_CONTINUOUS,
3312 };
3313 struct usb_host_interface *alts;
3314 struct usb_interface_descriptor *altsd;
3315 struct audioformat *fp;
3316 int stream, err;
3317
3318 /* both PCM and MIDI interfaces have 2 or more altsettings */
3319 if (iface->num_altsetting < 2)
3320 return -ENXIO;
3321 alts = &iface->altsetting[1];
3322 altsd = get_iface_desc(alts);
3323
3324 if (altsd->bNumEndpoints == 2) {
3325 static const struct snd_usb_midi_endpoint_info ua700_ep = {
3326 .out_cables = 0x0003,
3327 .in_cables = 0x0003
3328 };
3329 static const struct snd_usb_audio_quirk ua700_quirk = {
3330 .type = QUIRK_MIDI_FIXED_ENDPOINT,
3331 .data = &ua700_ep
3332 };
3333 static const struct snd_usb_midi_endpoint_info uaxx_ep = {
3334 .out_cables = 0x0001,
3335 .in_cables = 0x0001
3336 };
3337 static const struct snd_usb_audio_quirk uaxx_quirk = {
3338 .type = QUIRK_MIDI_FIXED_ENDPOINT,
3339 .data = &uaxx_ep
3340 };
3341 const struct snd_usb_audio_quirk *quirk =
3342 chip->usb_id == USB_ID(0x0582, 0x002b)
3343 ? &ua700_quirk : &uaxx_quirk;
3344 return snd_usbmidi_create(chip->card, iface,
3345 &chip->midi_list, quirk);
3346 }
3347
3348 if (altsd->bNumEndpoints != 1)
3349 return -ENXIO;
3350
3351 fp = kmalloc(sizeof(*fp), GFP_KERNEL);
3352 if (!fp)
3353 return -ENOMEM;
3354 memcpy(fp, &ua_format, sizeof(*fp));
3355
3356 fp->iface = altsd->bInterfaceNumber;
3357 fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress;
3358 fp->ep_attr = get_endpoint(alts, 0)->bmAttributes;
3359 fp->datainterval = 0;
3360 fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
3361
3362 switch (fp->maxpacksize) {
3363 case 0x120:
3364 fp->rate_max = fp->rate_min = 44100;
3365 break;
3366 case 0x138:
3367 case 0x140:
3368 fp->rate_max = fp->rate_min = 48000;
3369 break;
3370 case 0x258:
3371 case 0x260:
3372 fp->rate_max = fp->rate_min = 96000;
3373 break;
3374 default:
3375 snd_printk(KERN_ERR "unknown sample rate\n");
3376 kfree(fp);
3377 return -ENXIO;
3378 }
3379
3380 stream = (fp->endpoint & USB_DIR_IN)
3381 ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
3382 err = add_audio_endpoint(chip, stream, fp);
3383 if (err < 0) {
3384 kfree(fp);
3385 return err;
3386 }
3387 usb_set_interface(chip->dev, fp->iface, 0);
3388 return 0;
3389}
3390
3391static int snd_usb_create_quirk(struct snd_usb_audio *chip,
3392 struct usb_interface *iface,
3393 const struct snd_usb_audio_quirk *quirk);
3394
3395/*
3396 * handle the quirks for the contained interfaces
3397 */
3398static int create_composite_quirk(struct snd_usb_audio *chip,
3399 struct usb_interface *iface,
3400 const struct snd_usb_audio_quirk *quirk)
3401{
3402 int probed_ifnum = get_iface_desc(iface->altsetting)->bInterfaceNumber;
3403 int err;
3404
3405 for (quirk = quirk->data; quirk->ifnum >= 0; ++quirk) {
3406 iface = usb_ifnum_to_if(chip->dev, quirk->ifnum);
3407 if (!iface)
3408 continue;
3409 if (quirk->ifnum != probed_ifnum &&
3410 usb_interface_claimed(iface))
3411 continue;
3412 err = snd_usb_create_quirk(chip, iface, quirk);
3413 if (err < 0)
3414 return err;
3415 if (quirk->ifnum != probed_ifnum)
3416 usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L);
3417 }
3418 return 0;
3419}
3420
3421static int ignore_interface_quirk(struct snd_usb_audio *chip,
3422 struct usb_interface *iface,
3423 const struct snd_usb_audio_quirk *quirk)
3424{
3425 return 0;
3426}
3427
3428/*
3429 * Allow alignment on audio sub-slot (channel samples) rather than
3430 * on audio slots (audio frames)
3431 */
3432static int create_align_transfer_quirk(struct snd_usb_audio *chip,
3433 struct usb_interface *iface,
3434 const struct snd_usb_audio_quirk *quirk)
3435{
3436 chip->txfr_quirk = 1;
3437 return 1; /* Continue with creating streams and mixer */
3438}
3439
3440
3441/*
3442 * boot quirks
3443 */
3444
3445#define EXTIGY_FIRMWARE_SIZE_OLD 794
3446#define EXTIGY_FIRMWARE_SIZE_NEW 483
3447
3448static int snd_usb_extigy_boot_quirk(struct usb_device *dev, struct usb_interface *intf)
3449{
3450 struct usb_host_config *config = dev->actconfig;
3451 int err;
3452
3453 if (le16_to_cpu(get_cfg_desc(config)->wTotalLength) == EXTIGY_FIRMWARE_SIZE_OLD ||
3454 le16_to_cpu(get_cfg_desc(config)->wTotalLength) == EXTIGY_FIRMWARE_SIZE_NEW) {
3455 snd_printdd("sending Extigy boot sequence...\n");
3456 /* Send message to force it to reconnect with full interface. */
3457 err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev,0),
3458 0x10, 0x43, 0x0001, 0x000a, NULL, 0, 1000);
3459 if (err < 0) snd_printdd("error sending boot message: %d\n", err);
3460 err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
3461 &dev->descriptor, sizeof(dev->descriptor));
3462 config = dev->actconfig;
3463 if (err < 0) snd_printdd("error usb_get_descriptor: %d\n", err);
3464 err = usb_reset_configuration(dev);
3465 if (err < 0) snd_printdd("error usb_reset_configuration: %d\n", err);
3466 snd_printdd("extigy_boot: new boot length = %d\n",
3467 le16_to_cpu(get_cfg_desc(config)->wTotalLength));
3468 return -ENODEV; /* quit this anyway */
3469 }
3470 return 0;
3471}
3472
3473static int snd_usb_audigy2nx_boot_quirk(struct usb_device *dev)
3474{
3475 u8 buf = 1;
3476
3477 snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), 0x2a,
3478 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_OTHER,
3479 0, 0, &buf, 1, 1000);
3480 if (buf == 0) {
3481 snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), 0x29,
3482 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
3483 1, 2000, NULL, 0, 1000);
3484 return -ENODEV;
3485 }
3486 return 0;
3487}
3488
3489/*
3490 * C-Media CM106/CM106+ have four 16-bit internal registers that are nicely
3491 * documented in the device's data sheet.
3492 */
3493static int snd_usb_cm106_write_int_reg(struct usb_device *dev, int reg, u16 value)
3494{
3495 u8 buf[4];
3496 buf[0] = 0x20;
3497 buf[1] = value & 0xff;
3498 buf[2] = (value >> 8) & 0xff;
3499 buf[3] = reg;
3500 return snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), USB_REQ_SET_CONFIGURATION,
3501 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_ENDPOINT,
3502 0, 0, &buf, 4, 1000);
3503}
3504
3505static int snd_usb_cm106_boot_quirk(struct usb_device *dev)
3506{
3507 /*
3508 * Enable line-out driver mode, set headphone source to front
3509 * channels, enable stereo mic.
3510 */
3511 return snd_usb_cm106_write_int_reg(dev, 2, 0x8004);
3512}
3513
3514/*
3515 * C-Media CM6206 is based on CM106 with two additional
3516 * registers that are not documented in the data sheet.
3517 * Values here are chosen based on sniffing USB traffic
3518 * under Windows.
3519 */
3520static int snd_usb_cm6206_boot_quirk(struct usb_device *dev)
3521{
3522 int err, reg;
3523 int val[] = {0x200c, 0x3000, 0xf800, 0x143f, 0x0000, 0x3000};
3524
3525 for (reg = 0; reg < ARRAY_SIZE(val); reg++) {
3526 err = snd_usb_cm106_write_int_reg(dev, reg, val[reg]);
3527 if (err < 0)
3528 return err;
3529 }
3530
3531 return err;
3532}
3533
3534/*
3535 * This call will put the synth in "USB send" mode, i.e it will send MIDI
3536 * messages through USB (this is disabled at startup). The synth will
3537 * acknowledge by sending a sysex on endpoint 0x85 and by displaying a USB
3538 * sign on its LCD. Values here are chosen based on sniffing USB traffic
3539 * under Windows.
3540 */
3541static int snd_usb_accessmusic_boot_quirk(struct usb_device *dev)
3542{
3543 int err, actual_length;
3544
3545 /* "midi send" enable */
3546 static const u8 seq[] = { 0x4e, 0x73, 0x52, 0x01 };
3547
3548 void *buf = kmemdup(seq, ARRAY_SIZE(seq), GFP_KERNEL);
3549 if (!buf)
3550 return -ENOMEM;
3551 err = usb_interrupt_msg(dev, usb_sndintpipe(dev, 0x05), buf,
3552 ARRAY_SIZE(seq), &actual_length, 1000);
3553 kfree(buf);
3554 if (err < 0)
3555 return err;
3556
3557 return 0;
3558}
3559
3560/*
3561 * Setup quirks
3562 */
3563#define AUDIOPHILE_SET 0x01 /* if set, parse device_setup */
3564#define AUDIOPHILE_SET_DTS 0x02 /* if set, enable DTS Digital Output */
3565#define AUDIOPHILE_SET_96K 0x04 /* 48-96KHz rate if set, 8-48KHz otherwise */
3566#define AUDIOPHILE_SET_24B 0x08 /* 24bits sample if set, 16bits otherwise */
3567#define AUDIOPHILE_SET_DI 0x10 /* if set, enable Digital Input */
3568#define AUDIOPHILE_SET_MASK 0x1F /* bit mask for setup value */
3569#define AUDIOPHILE_SET_24B_48K_DI 0x19 /* value for 24bits+48KHz+Digital Input */
3570#define AUDIOPHILE_SET_24B_48K_NOTDI 0x09 /* value for 24bits+48KHz+No Digital Input */
3571#define AUDIOPHILE_SET_16B_48K_DI 0x11 /* value for 16bits+48KHz+Digital Input */
3572#define AUDIOPHILE_SET_16B_48K_NOTDI 0x01 /* value for 16bits+48KHz+No Digital Input */
3573
3574static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip,
3575 int iface, int altno)
3576{
3577 /* Reset ALL ifaces to 0 altsetting.
3578 * Call it for every possible altsetting of every interface.
3579 */
3580 usb_set_interface(chip->dev, iface, 0);
3581
3582 if (device_setup[chip->index] & AUDIOPHILE_SET) {
3583 if ((device_setup[chip->index] & AUDIOPHILE_SET_DTS)
3584 && altno != 6)
3585 return 1; /* skip this altsetting */
3586 if ((device_setup[chip->index] & AUDIOPHILE_SET_96K)
3587 && altno != 1)
3588 return 1; /* skip this altsetting */
3589 if ((device_setup[chip->index] & AUDIOPHILE_SET_MASK) ==
3590 AUDIOPHILE_SET_24B_48K_DI && altno != 2)
3591 return 1; /* skip this altsetting */
3592 if ((device_setup[chip->index] & AUDIOPHILE_SET_MASK) ==
3593 AUDIOPHILE_SET_24B_48K_NOTDI && altno != 3)
3594 return 1; /* skip this altsetting */
3595 if ((device_setup[chip->index] & AUDIOPHILE_SET_MASK) ==
3596 AUDIOPHILE_SET_16B_48K_DI && altno != 4)
3597 return 1; /* skip this altsetting */
3598 if ((device_setup[chip->index] & AUDIOPHILE_SET_MASK) ==
3599 AUDIOPHILE_SET_16B_48K_NOTDI && altno != 5)
3600 return 1; /* skip this altsetting */
3601 }
3602 return 0; /* keep this altsetting */
3603}
3604
3605static int create_any_midi_quirk(struct snd_usb_audio *chip,
3606 struct usb_interface *intf,
3607 const struct snd_usb_audio_quirk *quirk)
3608{
3609 return snd_usbmidi_create(chip->card, intf, &chip->midi_list, quirk);
3610}
3611
3612/*
3613 * audio-interface quirks
3614 *
3615 * returns zero if no standard audio/MIDI parsing is needed.
3616 * returns a postive value if standard audio/midi interfaces are parsed
3617 * after this.
3618 * returns a negative value at error.
3619 */
3620static int snd_usb_create_quirk(struct snd_usb_audio *chip,
3621 struct usb_interface *iface,
3622 const struct snd_usb_audio_quirk *quirk)
3623{
3624 typedef int (*quirk_func_t)(struct snd_usb_audio *, struct usb_interface *,
3625 const struct snd_usb_audio_quirk *);
3626 static const quirk_func_t quirk_funcs[] = {
3627 [QUIRK_IGNORE_INTERFACE] = ignore_interface_quirk,
3628 [QUIRK_COMPOSITE] = create_composite_quirk,
3629 [QUIRK_MIDI_STANDARD_INTERFACE] = create_any_midi_quirk,
3630 [QUIRK_MIDI_FIXED_ENDPOINT] = create_any_midi_quirk,
3631 [QUIRK_MIDI_YAMAHA] = create_any_midi_quirk,
3632 [QUIRK_MIDI_MIDIMAN] = create_any_midi_quirk,
3633 [QUIRK_MIDI_NOVATION] = create_any_midi_quirk,
3634 [QUIRK_MIDI_FASTLANE] = create_any_midi_quirk,
3635 [QUIRK_MIDI_EMAGIC] = create_any_midi_quirk,
3636 [QUIRK_MIDI_CME] = create_any_midi_quirk,
3637 [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk,
3638 [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk,
3639 [QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk,
3640 [QUIRK_AUDIO_ALIGN_TRANSFER] = create_align_transfer_quirk
3641 };
3642
3643 if (quirk->type < QUIRK_TYPE_COUNT) {
3644 return quirk_funcs[quirk->type](chip, iface, quirk);
3645 } else {
3646 snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type);
3647 return -ENXIO;
3648 }
3649}
3650
3651
3652/*
3653 * common proc files to show the usb device info
3654 */
3655static void proc_audio_usbbus_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
3656{
3657 struct snd_usb_audio *chip = entry->private_data;
3658 if (!chip->shutdown)
3659 snd_iprintf(buffer, "%03d/%03d\n", chip->dev->bus->busnum, chip->dev->devnum);
3660}
3661
3662static void proc_audio_usbid_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
3663{
3664 struct snd_usb_audio *chip = entry->private_data;
3665 if (!chip->shutdown)
3666 snd_iprintf(buffer, "%04x:%04x\n",
3667 USB_ID_VENDOR(chip->usb_id),
3668 USB_ID_PRODUCT(chip->usb_id));
3669}
3670
3671static void snd_usb_audio_create_proc(struct snd_usb_audio *chip)
3672{
3673 struct snd_info_entry *entry;
3674 if (!snd_card_proc_new(chip->card, "usbbus", &entry))
3675 snd_info_set_text_ops(entry, chip, proc_audio_usbbus_read);
3676 if (!snd_card_proc_new(chip->card, "usbid", &entry))
3677 snd_info_set_text_ops(entry, chip, proc_audio_usbid_read);
3678}
3679
3680/*
3681 * free the chip instance
3682 *
3683 * here we have to do not much, since pcm and controls are already freed
3684 *
3685 */
3686
3687static int snd_usb_audio_free(struct snd_usb_audio *chip)
3688{
3689 kfree(chip);
3690 return 0;
3691}
3692
3693static int snd_usb_audio_dev_free(struct snd_device *device)
3694{
3695 struct snd_usb_audio *chip = device->device_data;
3696 return snd_usb_audio_free(chip);
3697}
3698
3699
3700/*
3701 * create a chip instance and set its names.
3702 */
3703static int snd_usb_audio_create(struct usb_device *dev, int idx,
3704 const struct snd_usb_audio_quirk *quirk,
3705 struct snd_usb_audio **rchip)
3706{
3707 struct snd_card *card;
3708 struct snd_usb_audio *chip;
3709 int err, len;
3710 char component[14];
3711 static struct snd_device_ops ops = {
3712 .dev_free = snd_usb_audio_dev_free,
3713 };
3714
3715 *rchip = NULL;
3716
3717 if (snd_usb_get_speed(dev) != USB_SPEED_LOW &&
3718 snd_usb_get_speed(dev) != USB_SPEED_FULL &&
3719 snd_usb_get_speed(dev) != USB_SPEED_HIGH) {
3720 snd_printk(KERN_ERR "unknown device speed %d\n", snd_usb_get_speed(dev));
3721 return -ENXIO;
3722 }
3723
3724 err = snd_card_create(index[idx], id[idx], THIS_MODULE, 0, &card);
3725 if (err < 0) {
3726 snd_printk(KERN_ERR "cannot create card instance %d\n", idx);
3727 return err;
3728 }
3729
3730 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
3731 if (! chip) {
3732 snd_card_free(card);
3733 return -ENOMEM;
3734 }
3735
3736 chip->index = idx;
3737 chip->dev = dev;
3738 chip->card = card;
3739 chip->usb_id = USB_ID(le16_to_cpu(dev->descriptor.idVendor),
3740 le16_to_cpu(dev->descriptor.idProduct));
3741 INIT_LIST_HEAD(&chip->pcm_list);
3742 INIT_LIST_HEAD(&chip->midi_list);
3743 INIT_LIST_HEAD(&chip->mixer_list);
3744
3745 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
3746 snd_usb_audio_free(chip);
3747 snd_card_free(card);
3748 return err;
3749 }
3750
3751 strcpy(card->driver, "USB-Audio");
3752 sprintf(component, "USB%04x:%04x",
3753 USB_ID_VENDOR(chip->usb_id), USB_ID_PRODUCT(chip->usb_id));
3754 snd_component_add(card, component);
3755
3756 /* retrieve the device string as shortname */
3757 if (quirk && quirk->product_name) {
3758 strlcpy(card->shortname, quirk->product_name, sizeof(card->shortname));
3759 } else {
3760 if (!dev->descriptor.iProduct ||
3761 usb_string(dev, dev->descriptor.iProduct,
3762 card->shortname, sizeof(card->shortname)) <= 0) {
3763 /* no name available from anywhere, so use ID */
3764 sprintf(card->shortname, "USB Device %#04x:%#04x",
3765 USB_ID_VENDOR(chip->usb_id),
3766 USB_ID_PRODUCT(chip->usb_id));
3767 }
3768 }
3769
3770 /* retrieve the vendor and device strings as longname */
3771 if (quirk && quirk->vendor_name) {
3772 len = strlcpy(card->longname, quirk->vendor_name, sizeof(card->longname));
3773 } else {
3774 if (dev->descriptor.iManufacturer)
3775 len = usb_string(dev, dev->descriptor.iManufacturer,
3776 card->longname, sizeof(card->longname));
3777 else
3778 len = 0;
3779 /* we don't really care if there isn't any vendor string */
3780 }
3781 if (len > 0)
3782 strlcat(card->longname, " ", sizeof(card->longname));
3783
3784 strlcat(card->longname, card->shortname, sizeof(card->longname));
3785
3786 len = strlcat(card->longname, " at ", sizeof(card->longname));
3787
3788 if (len < sizeof(card->longname))
3789 usb_make_path(dev, card->longname + len, sizeof(card->longname) - len);
3790
3791 strlcat(card->longname,
3792 snd_usb_get_speed(dev) == USB_SPEED_LOW ? ", low speed" :
3793 snd_usb_get_speed(dev) == USB_SPEED_FULL ? ", full speed" :
3794 ", high speed",
3795 sizeof(card->longname));
3796
3797 snd_usb_audio_create_proc(chip);
3798
3799 *rchip = chip;
3800 return 0;
3801}
3802
3803
3804/*
3805 * probe the active usb device
3806 *
3807 * note that this can be called multiple times per a device, when it
3808 * includes multiple audio control interfaces.
3809 *
3810 * thus we check the usb device pointer and creates the card instance
3811 * only at the first time. the successive calls of this function will
3812 * append the pcm interface to the corresponding card.
3813 */
3814static void *snd_usb_audio_probe(struct usb_device *dev,
3815 struct usb_interface *intf,
3816 const struct usb_device_id *usb_id)
3817{
3818 const struct snd_usb_audio_quirk *quirk = (const struct snd_usb_audio_quirk *)usb_id->driver_info;
3819 int i, err;
3820 struct snd_usb_audio *chip;
3821 struct usb_host_interface *alts;
3822 int ifnum;
3823 u32 id;
3824
3825 alts = &intf->altsetting[0];
3826 ifnum = get_iface_desc(alts)->bInterfaceNumber;
3827 id = USB_ID(le16_to_cpu(dev->descriptor.idVendor),
3828 le16_to_cpu(dev->descriptor.idProduct));
3829 if (quirk && quirk->ifnum >= 0 && ifnum != quirk->ifnum)
3830 goto __err_val;
3831
3832 /* SB Extigy needs special boot-up sequence */
3833 /* if more models come, this will go to the quirk list. */
3834 if (id == USB_ID(0x041e, 0x3000)) {
3835 if (snd_usb_extigy_boot_quirk(dev, intf) < 0)
3836 goto __err_val;
3837 }
3838 /* SB Audigy 2 NX needs its own boot-up magic, too */
3839 if (id == USB_ID(0x041e, 0x3020)) {
3840 if (snd_usb_audigy2nx_boot_quirk(dev) < 0)
3841 goto __err_val;
3842 }
3843
3844 /* C-Media CM106 / Turtle Beach Audio Advantage Roadie */
3845 if (id == USB_ID(0x10f5, 0x0200)) {
3846 if (snd_usb_cm106_boot_quirk(dev) < 0)
3847 goto __err_val;
3848 }
3849
3850 /* C-Media CM6206 / CM106-Like Sound Device */
3851 if (id == USB_ID(0x0d8c, 0x0102)) {
3852 if (snd_usb_cm6206_boot_quirk(dev) < 0)
3853 goto __err_val;
3854 }
3855
3856 /* Access Music VirusTI Desktop */
3857 if (id == USB_ID(0x133e, 0x0815)) {
3858 if (snd_usb_accessmusic_boot_quirk(dev) < 0)
3859 goto __err_val;
3860 }
3861
3862 /*
3863 * found a config. now register to ALSA
3864 */
3865
3866 /* check whether it's already registered */
3867 chip = NULL;
3868 mutex_lock(&register_mutex);
3869 for (i = 0; i < SNDRV_CARDS; i++) {
3870 if (usb_chip[i] && usb_chip[i]->dev == dev) {
3871 if (usb_chip[i]->shutdown) {
3872 snd_printk(KERN_ERR "USB device is in the shutdown state, cannot create a card instance\n");
3873 goto __error;
3874 }
3875 chip = usb_chip[i];
3876 break;
3877 }
3878 }
3879 if (! chip) {
3880 /* it's a fresh one.
3881 * now look for an empty slot and create a new card instance
3882 */
3883 for (i = 0; i < SNDRV_CARDS; i++)
3884 if (enable[i] && ! usb_chip[i] &&
3885 (vid[i] == -1 || vid[i] == USB_ID_VENDOR(id)) &&
3886 (pid[i] == -1 || pid[i] == USB_ID_PRODUCT(id))) {
3887 if (snd_usb_audio_create(dev, i, quirk, &chip) < 0) {
3888 goto __error;
3889 }
3890 snd_card_set_dev(chip->card, &intf->dev);
3891 break;
3892 }
3893 if (!chip) {
3894 printk(KERN_ERR "no available usb audio device\n");
3895 goto __error;
3896 }
3897 }
3898
3899 chip->txfr_quirk = 0;
3900 err = 1; /* continue */
3901 if (quirk && quirk->ifnum != QUIRK_NO_INTERFACE) {
3902 /* need some special handlings */
3903 if ((err = snd_usb_create_quirk(chip, intf, quirk)) < 0)
3904 goto __error;
3905 }
3906
3907 if (err > 0) {
3908 /* create normal USB audio interfaces */
3909 if (snd_usb_create_streams(chip, ifnum) < 0 ||
3910 snd_usb_create_mixer(chip, ifnum, ignore_ctl_error) < 0) {
3911 goto __error;
3912 }
3913 }
3914
3915 /* we are allowed to call snd_card_register() many times */
3916 if (snd_card_register(chip->card) < 0) {
3917 goto __error;
3918 }
3919
3920 usb_chip[chip->index] = chip;
3921 chip->num_interfaces++;
3922 mutex_unlock(&register_mutex);
3923 return chip;
3924
3925 __error:
3926 if (chip && !chip->num_interfaces)
3927 snd_card_free(chip->card);
3928 mutex_unlock(&register_mutex);
3929 __err_val:
3930 return NULL;
3931}
3932
3933/*
3934 * we need to take care of counter, since disconnection can be called also
3935 * many times as well as usb_audio_probe().
3936 */
3937static void snd_usb_audio_disconnect(struct usb_device *dev, void *ptr)
3938{
3939 struct snd_usb_audio *chip;
3940 struct snd_card *card;
3941 struct list_head *p;
3942
3943 if (ptr == (void *)-1L)
3944 return;
3945
3946 chip = ptr;
3947 card = chip->card;
3948 mutex_lock(&register_mutex);
3949 chip->shutdown = 1;
3950 chip->num_interfaces--;
3951 if (chip->num_interfaces <= 0) {
3952 snd_card_disconnect(card);
3953 /* release the pcm resources */
3954 list_for_each(p, &chip->pcm_list) {
3955 snd_usb_stream_disconnect(p);
3956 }
3957 /* release the midi resources */
3958 list_for_each(p, &chip->midi_list) {
3959 snd_usbmidi_disconnect(p);
3960 }
3961 /* release mixer resources */
3962 list_for_each(p, &chip->mixer_list) {
3963 snd_usb_mixer_disconnect(p);
3964 }
3965 usb_chip[chip->index] = NULL;
3966 mutex_unlock(&register_mutex);
3967 snd_card_free_when_closed(card);
3968 } else {
3969 mutex_unlock(&register_mutex);
3970 }
3971}
3972
3973/*
3974 * new 2.5 USB kernel API
3975 */
3976static int usb_audio_probe(struct usb_interface *intf,
3977 const struct usb_device_id *id)
3978{
3979 void *chip;
3980 chip = snd_usb_audio_probe(interface_to_usbdev(intf), intf, id);
3981 if (chip) {
3982 usb_set_intfdata(intf, chip);
3983 return 0;
3984 } else
3985 return -EIO;
3986}
3987
3988static void usb_audio_disconnect(struct usb_interface *intf)
3989{
3990 snd_usb_audio_disconnect(interface_to_usbdev(intf),
3991 usb_get_intfdata(intf));
3992}
3993
3994#ifdef CONFIG_PM
3995static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message)
3996{
3997 struct snd_usb_audio *chip = usb_get_intfdata(intf);
3998 struct list_head *p;
3999 struct snd_usb_stream *as;
4000
4001 if (chip == (void *)-1L)
4002 return 0;
4003
4004 snd_power_change_state(chip->card, SNDRV_CTL_POWER_D3hot);
4005 if (!chip->num_suspended_intf++) {
4006 list_for_each(p, &chip->pcm_list) {
4007 as = list_entry(p, struct snd_usb_stream, list);
4008 snd_pcm_suspend_all(as->pcm);
4009 }
4010 }
4011
4012 return 0;
4013}
4014
4015static int usb_audio_resume(struct usb_interface *intf)
4016{
4017 struct snd_usb_audio *chip = usb_get_intfdata(intf);
4018
4019 if (chip == (void *)-1L)
4020 return 0;
4021 if (--chip->num_suspended_intf)
4022 return 0;
4023 /*
4024 * ALSA leaves material resumption to user space
4025 * we just notify
4026 */
4027
4028 snd_power_change_state(chip->card, SNDRV_CTL_POWER_D0);
4029
4030 return 0;
4031}
4032#endif /* CONFIG_PM */
4033
4034static int __init snd_usb_audio_init(void)
4035{
4036 if (nrpacks < 1 || nrpacks > MAX_PACKS) {
4037 printk(KERN_WARNING "invalid nrpacks value.\n");
4038 return -EINVAL;
4039 }
4040 return usb_register(&usb_audio_driver);
4041}
4042
4043
4044static void __exit snd_usb_audio_cleanup(void)
4045{
4046 usb_deregister(&usb_audio_driver);
4047}
4048
4049module_init(snd_usb_audio_init);
4050module_exit(snd_usb_audio_cleanup);
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
index 42c299cbf63a..06ebf24d3a4d 100644
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -21,15 +21,13 @@
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */ 22 */
23 23
24/* maximum number of endpoints per interface */
25#define MIDI_MAX_ENDPOINTS 2
26
27/* handling of USB vendor/product ID pairs as 32-bit numbers */ 24/* handling of USB vendor/product ID pairs as 32-bit numbers */
28#define USB_ID(vendor, product) (((vendor) << 16) | (product)) 25#define USB_ID(vendor, product) (((vendor) << 16) | (product))
29#define USB_ID_VENDOR(id) ((id) >> 16) 26#define USB_ID_VENDOR(id) ((id) >> 16)
30#define USB_ID_PRODUCT(id) ((u16)(id)) 27#define USB_ID_PRODUCT(id) ((u16)(id))
31 28
32/* 29/*
30 *
33 */ 31 */
34 32
35struct snd_usb_audio { 33struct snd_usb_audio {
@@ -51,6 +49,10 @@ struct snd_usb_audio {
51 struct list_head midi_list; /* list of midi interfaces */ 49 struct list_head midi_list; /* list of midi interfaces */
52 50
53 struct list_head mixer_list; /* list of mixer interfaces */ 51 struct list_head mixer_list; /* list of mixer interfaces */
52
53 int setup; /* from the 'device_setup' module param */
54 int nrpacks; /* from the 'nrpacks' module param */
55 int async_unlink; /* from the 'async_unlink' module param */
54}; 56};
55 57
56/* 58/*
@@ -72,6 +74,7 @@ enum quirk_type {
72 QUIRK_MIDI_FASTLANE, 74 QUIRK_MIDI_FASTLANE,
73 QUIRK_MIDI_EMAGIC, 75 QUIRK_MIDI_EMAGIC,
74 QUIRK_MIDI_CME, 76 QUIRK_MIDI_CME,
77 QUIRK_MIDI_AKAI,
75 QUIRK_MIDI_US122L, 78 QUIRK_MIDI_US122L,
76 QUIRK_AUDIO_STANDARD_INTERFACE, 79 QUIRK_AUDIO_STANDARD_INTERFACE,
77 QUIRK_AUDIO_FIXED_ENDPOINT, 80 QUIRK_AUDIO_FIXED_ENDPOINT,
@@ -89,93 +92,8 @@ struct snd_usb_audio_quirk {
89 const void *data; 92 const void *data;
90}; 93};
91 94
92/* data for QUIRK_MIDI_FIXED_ENDPOINT */
93struct snd_usb_midi_endpoint_info {
94 int8_t out_ep; /* ep number, 0 autodetect */
95 uint8_t out_interval; /* interval for interrupt endpoints */
96 int8_t in_ep;
97 uint8_t in_interval;
98 uint16_t out_cables; /* bitmask */
99 uint16_t in_cables; /* bitmask */
100};
101
102/* for QUIRK_MIDI_YAMAHA, data is NULL */
103
104/* for QUIRK_MIDI_MIDIMAN, data points to a snd_usb_midi_endpoint_info
105 * structure (out_cables and in_cables only) */
106
107/* for QUIRK_COMPOSITE, data points to an array of snd_usb_audio_quirk
108 * structures, terminated with .ifnum = -1 */
109
110/* for QUIRK_AUDIO_FIXED_ENDPOINT, data points to an audioformat structure */
111
112/* for QUIRK_AUDIO/MIDI_STANDARD_INTERFACE, data is NULL */
113
114/* for QUIRK_AUDIO_EDIROL_UAXX, data is NULL */
115
116/* for QUIRK_IGNORE_INTERFACE, data is NULL */
117
118/* for QUIRK_MIDI_NOVATION and _RAW, data is NULL */
119
120/* for QUIRK_MIDI_EMAGIC, data points to a snd_usb_midi_endpoint_info
121 * structure (out_cables and in_cables only) */
122
123/* for QUIRK_MIDI_CME, data is NULL */
124
125/*
126 */
127
128/*E-mu USB samplerate control quirk*/
129enum {
130 EMU_QUIRK_SR_44100HZ = 0,
131 EMU_QUIRK_SR_48000HZ,
132 EMU_QUIRK_SR_88200HZ,
133 EMU_QUIRK_SR_96000HZ,
134 EMU_QUIRK_SR_176400HZ,
135 EMU_QUIRK_SR_192000HZ
136};
137
138#define combine_word(s) ((*(s)) | ((unsigned int)(s)[1] << 8)) 95#define combine_word(s) ((*(s)) | ((unsigned int)(s)[1] << 8))
139#define combine_triple(s) (combine_word(s) | ((unsigned int)(s)[2] << 16)) 96#define combine_triple(s) (combine_word(s) | ((unsigned int)(s)[2] << 16))
140#define combine_quad(s) (combine_triple(s) | ((unsigned int)(s)[3] << 24)) 97#define combine_quad(s) (combine_triple(s) | ((unsigned int)(s)[3] << 24))
141 98
142unsigned int snd_usb_combine_bytes(unsigned char *bytes, int size);
143
144void *snd_usb_find_desc(void *descstart, int desclen, void *after, u8 dtype);
145void *snd_usb_find_csint_desc(void *descstart, int desclen, void *after, u8 dsubtype);
146
147int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe,
148 __u8 request, __u8 requesttype, __u16 value, __u16 index,
149 void *data, __u16 size, int timeout);
150
151int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
152 int ignore_error);
153void snd_usb_mixer_disconnect(struct list_head *p);
154
155int snd_usbmidi_create(struct snd_card *card,
156 struct usb_interface *iface,
157 struct list_head *midi_list,
158 const struct snd_usb_audio_quirk *quirk);
159void snd_usbmidi_input_stop(struct list_head* p);
160void snd_usbmidi_input_start(struct list_head* p);
161void snd_usbmidi_disconnect(struct list_head *p);
162
163void snd_emuusb_set_samplerate(struct snd_usb_audio *chip,
164 unsigned char samplerate_id);
165
166/*
167 * retrieve usb_interface descriptor from the host interface
168 * (conditional for compatibility with the older API)
169 */
170#ifndef get_iface_desc
171#define get_iface_desc(iface) (&(iface)->desc)
172#define get_endpoint(alt,ep) (&(alt)->endpoint[ep].desc)
173#define get_ep_desc(ep) (&(ep)->desc)
174#define get_cfg_desc(cfg) (&(cfg)->desc)
175#endif
176
177#ifndef snd_usb_get_speed
178#define snd_usb_get_speed(dev) ((dev)->speed)
179#endif
180
181#endif /* __USBAUDIO_H */ 99#endif /* __USBAUDIO_H */
diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c
index 44deb21b1777..6ef68e42138e 100644
--- a/sound/usb/usx2y/us122l.c
+++ b/sound/usb/usx2y/us122l.c
@@ -16,6 +16,7 @@
16 * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 16 * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */ 17 */
18 18
19#include <linux/slab.h>
19#include <linux/usb.h> 20#include <linux/usb.h>
20#include <linux/usb/audio.h> 21#include <linux/usb/audio.h>
21#include <sound/core.h> 22#include <sound/core.h>
@@ -25,6 +26,7 @@
25#define MODNAME "US122L" 26#define MODNAME "US122L"
26#include "usb_stream.c" 27#include "usb_stream.c"
27#include "../usbaudio.h" 28#include "../usbaudio.h"
29#include "../midi.h"
28#include "us122l.h" 30#include "us122l.h"
29 31
30MODULE_AUTHOR("Karsten Wiese <fzu@wemgehoertderstaat.de>"); 32MODULE_AUTHOR("Karsten Wiese <fzu@wemgehoertderstaat.de>");
diff --git a/sound/usb/usx2y/usX2Yhwdep.c b/sound/usb/usx2y/usX2Yhwdep.c
index 1879b72c40f8..04aafb43a13c 100644
--- a/sound/usb/usx2y/usX2Yhwdep.c
+++ b/sound/usb/usx2y/usX2Yhwdep.c
@@ -21,6 +21,7 @@
21 */ 21 */
22 22
23#include <linux/interrupt.h> 23#include <linux/interrupt.h>
24#include <linux/slab.h>
24#include <linux/usb.h> 25#include <linux/usb.h>
25#include <sound/core.h> 26#include <sound/core.h>
26#include <sound/memalloc.h> 27#include <sound/memalloc.h>
diff --git a/sound/usb/usx2y/usb_stream.c b/sound/usb/usx2y/usb_stream.c
index 12ae0340adc0..c400ade3ff08 100644
--- a/sound/usb/usx2y/usb_stream.c
+++ b/sound/usb/usx2y/usb_stream.c
@@ -17,6 +17,7 @@
17 */ 17 */
18 18
19#include <linux/usb.h> 19#include <linux/usb.h>
20#include <linux/gfp.h>
20 21
21#include "usb_stream.h" 22#include "usb_stream.h"
22 23
diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c
index c42350eed2eb..cbd37f2c76d0 100644
--- a/sound/usb/usx2y/usbusx2y.c
+++ b/sound/usb/usx2y/usbusx2y.c
@@ -133,6 +133,7 @@
133#include <linux/init.h> 133#include <linux/init.h>
134#include <linux/module.h> 134#include <linux/module.h>
135#include <linux/moduleparam.h> 135#include <linux/moduleparam.h>
136#include <linux/slab.h>
136#include <linux/interrupt.h> 137#include <linux/interrupt.h>
137#include <linux/usb.h> 138#include <linux/usb.h>
138#include <sound/core.h> 139#include <sound/core.h>
diff --git a/sound/usb/usx2y/usbusx2y.h b/sound/usb/usx2y/usbusx2y.h
index 1d174cea352b..e43c0a86441a 100644
--- a/sound/usb/usx2y/usbusx2y.h
+++ b/sound/usb/usx2y/usbusx2y.h
@@ -1,6 +1,7 @@
1#ifndef USBUSX2Y_H 1#ifndef USBUSX2Y_H
2#define USBUSX2Y_H 2#define USBUSX2Y_H
3#include "../usbaudio.h" 3#include "../usbaudio.h"
4#include "../midi.h"
4#include "usbus428ctldefs.h" 5#include "usbus428ctldefs.h"
5 6
6#define NRURBS 2 7#define NRURBS 2
diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c
index 74a67a85aa81..5d37d1ccf813 100644
--- a/sound/usb/usx2y/usbusx2yaudio.c
+++ b/sound/usb/usx2y/usbusx2yaudio.c
@@ -32,6 +32,7 @@
32 32
33 33
34#include <linux/interrupt.h> 34#include <linux/interrupt.h>
35#include <linux/slab.h>
35#include <linux/usb.h> 36#include <linux/usb.h>
36#include <sound/core.h> 37#include <sound/core.h>
37#include <sound/info.h> 38#include <sound/info.h>
diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c
index 9ed6c3956ca7..2a528e56afd5 100644
--- a/sound/usb/usx2y/usx2yhwdeppcm.c
+++ b/sound/usb/usx2y/usx2yhwdeppcm.c
@@ -51,6 +51,7 @@
51*/ 51*/
52 52
53#include <linux/delay.h> 53#include <linux/delay.h>
54#include <linux/gfp.h>
54#include "usbusx2yaudio.c" 55#include "usbusx2yaudio.c"
55 56
56#if defined(USX2Y_NRPACKS_VARIABLE) || (!defined(USX2Y_NRPACKS_VARIABLE) && USX2Y_NRPACKS == 1) 57#if defined(USX2Y_NRPACKS_VARIABLE) || (!defined(USX2Y_NRPACKS_VARIABLE) && USX2Y_NRPACKS == 1)