aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /sound
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'sound')
-rw-r--r--sound/Kconfig6
-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.c1
-rw-r--r--sound/aoa/fabrics/layout.c3
-rw-r--r--sound/aoa/soundbus/i2sbus/control.c1
-rw-r--r--sound/aoa/soundbus/i2sbus/core.c1
-rw-r--r--sound/aoa/soundbus/i2sbus/pcm.c1
-rw-r--r--sound/arm/Makefile2
-rw-r--r--sound/arm/aaci.c210
-rw-r--r--sound/arm/aaci.h2
-rw-r--r--sound/arm/devdma.c80
-rw-r--r--sound/arm/devdma.h3
-rw-r--r--sound/arm/pxa2xx-ac97-lib.c68
-rw-r--r--sound/arm/pxa2xx-ac97.c2
-rw-r--r--sound/arm/pxa2xx-pcm-lib.c2
-rw-r--r--sound/core/Kconfig1
-rw-r--r--sound/core/control.c16
-rw-r--r--sound/core/control_compat.c1
-rw-r--r--sound/core/hrtimer.c16
-rw-r--r--sound/core/info.c1
-rw-r--r--sound/core/isadma.c10
-rw-r--r--sound/core/jack.c1
-rw-r--r--sound/core/misc.c33
-rw-r--r--sound/core/oss/mixer_oss.c4
-rw-r--r--sound/core/oss/pcm_oss.c31
-rw-r--r--sound/core/oss/route.c1
-rw-r--r--sound/core/pcm.c11
-rw-r--r--sound/core/pcm_compat.c1
-rw-r--r--sound/core/pcm_lib.c451
-rw-r--r--sound/core/pcm_memory.c56
-rw-r--r--sound/core/pcm_native.c165
-rw-r--r--sound/core/pcm_timer.c17
-rw-r--r--sound/core/rawmidi.c19
-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.c2
-rw-r--r--sound/core/seq/seq_compat.c1
-rw-r--r--sound/core/seq/seq_system.c1
-rw-r--r--sound/core/seq/seq_timer.c27
-rw-r--r--sound/core/sound.c4
-rw-r--r--sound/core/sound_oss.c2
-rw-r--r--sound/core/timer.c7
-rw-r--r--sound/drivers/dummy.c290
-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/pcsp/pcsp.c32
-rw-r--r--sound/drivers/pcsp/pcsp.h2
-rw-r--r--sound/drivers/pcsp/pcsp_lib.c1
-rw-r--r--sound/drivers/pcsp/pcsp_mixer.c35
-rw-r--r--sound/drivers/portman2x4.c1
-rw-r--r--sound/drivers/vx/vx_hwdep.c1
-rw-r--r--sound/drivers/vx/vx_pcm.c61
-rw-r--r--sound/i2c/cs8427.c15
-rw-r--r--sound/i2c/other/Makefile3
-rw-r--r--sound/i2c/other/ak4113.c639
-rw-r--r--sound/i2c/other/ak4xxx-adda.c136
-rw-r--r--sound/i2c/other/tea575x-tuner.c3
-rw-r--r--sound/isa/Kconfig49
-rw-r--r--sound/isa/Makefile2
-rw-r--r--sound/isa/als100.c121
-rw-r--r--sound/isa/cmi8330.c5
-rw-r--r--sound/isa/cs423x/cs4236.c16
-rw-r--r--sound/isa/cs423x/cs4236_lib.c241
-rw-r--r--sound/isa/dt019x.c321
-rw-r--r--sound/isa/es1688/es1688_lib.c2
-rw-r--r--sound/isa/es18xx.c222
-rw-r--r--sound/isa/gus/gus_mem.c3
-rw-r--r--sound/isa/gus/interwave.c1
-rw-r--r--sound/isa/msnd/msnd_midi.c3
-rw-r--r--sound/isa/opl3sa2.c1
-rw-r--r--sound/isa/opti9xx/miro.c786
-rw-r--r--sound/isa/opti9xx/miro.h73
-rw-r--r--sound/isa/opti9xx/opti92x-ad1848.c437
-rw-r--r--sound/isa/sb/Makefile2
-rw-r--r--sound/isa/sb/emu8000.c11
-rw-r--r--sound/isa/sb/emu8000_pcm.c1
-rw-r--r--sound/isa/sb/es968.c2
-rw-r--r--sound/isa/sb/jazz16.c405
-rw-r--r--sound/isa/sb/sb16.c1
-rw-r--r--sound/isa/sb/sb8.c1
-rw-r--r--sound/isa/sb/sb8_main.c118
-rw-r--r--sound/isa/sb/sb_common.c3
-rw-r--r--sound/isa/sb/sb_mixer.c333
-rw-r--r--sound/isa/sscape.c727
-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/isa/wss/wss_lib.c163
-rw-r--r--sound/mips/hal2.c1
-rw-r--r--sound/mips/sgio2audio.c36
-rw-r--r--sound/oss/Kconfig14
-rw-r--r--sound/oss/Makefile1
-rw-r--r--sound/oss/ad1848.c1
-rw-r--r--sound/oss/au1550_ac97.c16
-rw-r--r--sound/oss/audio.c2
-rw-r--r--sound/oss/coproc.h2
-rw-r--r--sound/oss/dev_table.c16
-rw-r--r--sound/oss/dmabuf.c1
-rw-r--r--sound/oss/dmasound/dmasound_paula.c2
-rw-r--r--sound/oss/kahlua.c3
-rw-r--r--sound/oss/midi_synth.c2
-rw-r--r--sound/oss/mpu401.c3
-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/pss.c6
-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/sequencer.c2
-rw-r--r--sound/oss/sh_dac_audio.c3
-rw-r--r--sound/oss/sound_config.h2
-rw-r--r--sound/oss/soundcard.c40
-rw-r--r--sound/oss/sscape.c1480
-rw-r--r--sound/oss/uart401.c1
-rw-r--r--sound/oss/v_midi.c1
-rw-r--r--sound/oss/v_midi.h5
-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/Kconfig2
-rw-r--r--sound/pci/ac97/ac97_codec.c18
-rw-r--r--sound/pci/ac97/ac97_id.h2
-rw-r--r--sound/pci/ac97/ac97_patch.c32
-rw-r--r--sound/pci/ac97/ac97_proc.c1
-rw-r--r--sound/pci/ad1889.c2
-rw-r--r--sound/pci/ali5451/ali5451.c2
-rw-r--r--sound/pci/als300.c2
-rw-r--r--sound/pci/als4000.c3
-rw-r--r--sound/pci/atiixp.c3
-rw-r--r--sound/pci/atiixp_modem.c2
-rw-r--r--sound/pci/au88x0/au8810.c2
-rw-r--r--sound/pci/au88x0/au8820.c2
-rw-r--r--sound/pci/au88x0/au8830.c2
-rw-r--r--sound/pci/aw2/aw2-alsa.c2
-rw-r--r--sound/pci/aw2/aw2-saa7146.c1
-rw-r--r--sound/pci/azt3328.c6
-rw-r--r--sound/pci/bt87x.c4
-rw-r--r--sound/pci/ca0106/ca0106_main.c2
-rw-r--r--sound/pci/ca0106/ca0106_mixer.c5
-rw-r--r--sound/pci/ca0106/ca0106_proc.c7
-rw-r--r--sound/pci/cmipci.c22
-rw-r--r--sound/pci/cs4281.c2
-rw-r--r--sound/pci/cs46xx/cs46xx.c2
-rw-r--r--sound/pci/cs46xx/cs46xx_lib.c22
-rw-r--r--sound/pci/cs46xx/dsp_spos.c42
-rw-r--r--sound/pci/cs46xx/dsp_spos.h4
-rw-r--r--sound/pci/cs46xx/dsp_spos_scb_lib.c33
-rw-r--r--sound/pci/cs46xx/imgs/cwcdma.asp9
-rw-r--r--sound/pci/cs5530.c3
-rw-r--r--sound/pci/cs5535audio/Makefile2
-rw-r--r--sound/pci/cs5535audio/cs5535audio.c3
-rw-r--r--sound/pci/cs5535audio/cs5535audio.h4
-rw-r--r--sound/pci/cs5535audio/cs5535audio_olpc.c26
-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.c41
-rw-r--r--sound/pci/ctxfi/ctatc.h2
-rw-r--r--sound/pci/ctxfi/ctpcm.c1
-rw-r--r--sound/pci/ctxfi/ctvmem.c38
-rw-r--r--sound/pci/ctxfi/ctvmem.h8
-rw-r--r--sound/pci/ctxfi/xfi.c7
-rw-r--r--sound/pci/echoaudio/darla20.c4
-rw-r--r--sound/pci/echoaudio/darla20_dsp.c12
-rw-r--r--sound/pci/echoaudio/darla24.c4
-rw-r--r--sound/pci/echoaudio/darla24_dsp.c12
-rw-r--r--sound/pci/echoaudio/echo3g.c4
-rw-r--r--sound/pci/echoaudio/echo3g_dsp.c28
-rw-r--r--sound/pci/echoaudio/echoaudio.c210
-rw-r--r--sound/pci/echoaudio/echoaudio.h11
-rw-r--r--sound/pci/echoaudio/echoaudio_3g.c5
-rw-r--r--sound/pci/echoaudio/echoaudio_dsp.c157
-rw-r--r--sound/pci/echoaudio/gina20.c4
-rw-r--r--sound/pci/echoaudio/gina20_dsp.c15
-rw-r--r--sound/pci/echoaudio/gina24.c4
-rw-r--r--sound/pci/echoaudio/gina24_dsp.c38
-rw-r--r--sound/pci/echoaudio/indigo.c4
-rw-r--r--sound/pci/echoaudio/indigo_dsp.c12
-rw-r--r--sound/pci/echoaudio/indigo_express_dsp.c1
-rw-r--r--sound/pci/echoaudio/indigodj.c4
-rw-r--r--sound/pci/echoaudio/indigodj_dsp.c12
-rw-r--r--sound/pci/echoaudio/indigodjx.c4
-rw-r--r--sound/pci/echoaudio/indigodjx_dsp.c13
-rw-r--r--sound/pci/echoaudio/indigoio.c4
-rw-r--r--sound/pci/echoaudio/indigoio_dsp.c12
-rw-r--r--sound/pci/echoaudio/indigoiox.c4
-rw-r--r--sound/pci/echoaudio/indigoiox_dsp.c13
-rw-r--r--sound/pci/echoaudio/layla20.c4
-rw-r--r--sound/pci/echoaudio/layla20_dsp.c20
-rw-r--r--sound/pci/echoaudio/layla24.c4
-rw-r--r--sound/pci/echoaudio/layla24_dsp.c37
-rw-r--r--sound/pci/echoaudio/mia.c4
-rw-r--r--sound/pci/echoaudio/mia_dsp.c12
-rw-r--r--sound/pci/echoaudio/mona.c4
-rw-r--r--sound/pci/echoaudio/mona_dsp.c61
-rw-r--r--sound/pci/emu10k1/emu10k1.c2
-rw-r--r--sound/pci/emu10k1/emu10k1x.c7
-rw-r--r--sound/pci/emu10k1/emumixer.c4
-rw-r--r--sound/pci/emu10k1/emuproc.c4
-rw-r--r--sound/pci/emu10k1/io.c2
-rw-r--r--sound/pci/emu10k1/memory.c1
-rw-r--r--sound/pci/ens1370.c2
-rw-r--r--sound/pci/es1938.c4
-rw-r--r--sound/pci/es1968.c2
-rw-r--r--sound/pci/fm801.c42
-rw-r--r--sound/pci/hda/Kconfig15
-rw-r--r--sound/pci/hda/Makefile4
-rw-r--r--sound/pci/hda/hda_beep.c121
-rw-r--r--sound/pci/hda/hda_beep.h10
-rw-r--r--sound/pci/hda/hda_codec.c745
-rw-r--r--sound/pci/hda/hda_codec.h22
-rw-r--r--sound/pci/hda/hda_eld.c27
-rw-r--r--sound/pci/hda/hda_generic.c18
-rw-r--r--sound/pci/hda/hda_hwdep.c105
-rw-r--r--sound/pci/hda/hda_intel.c185
-rw-r--r--sound/pci/hda/hda_local.h77
-rw-r--r--sound/pci/hda/hda_proc.c90
-rw-r--r--sound/pci/hda/patch_analog.c210
-rw-r--r--sound/pci/hda/patch_ca0110.c4
-rw-r--r--sound/pci/hda/patch_cirrus.c65
-rw-r--r--sound/pci/hda/patch_cmedia.c17
-rw-r--r--sound/pci/hda/patch_conexant.c775
-rw-r--r--sound/pci/hda/patch_hdmi.c849
-rw-r--r--sound/pci/hda/patch_intelhdmi.c637
-rw-r--r--sound/pci/hda/patch_nvhdmi.c278
-rw-r--r--sound/pci/hda/patch_realtek.c2185
-rw-r--r--sound/pci/hda/patch_si3054.c1
-rw-r--r--sound/pci/hda/patch_sigmatel.c493
-rw-r--r--sound/pci/hda/patch_via.c3638
-rw-r--r--sound/pci/ice1712/Makefile2
-rw-r--r--sound/pci/ice1712/ak4xxx.c1
-rw-r--r--sound/pci/ice1712/amp.c1
-rw-r--r--sound/pci/ice1712/aureon.c43
-rw-r--r--sound/pci/ice1712/ice1712.c23
-rw-r--r--sound/pci/ice1712/ice1712.h14
-rw-r--r--sound/pci/ice1712/ice1724.c105
-rw-r--r--sound/pci/ice1712/juli.c58
-rw-r--r--sound/pci/ice1712/maya44.c6
-rw-r--r--sound/pci/ice1712/quartet.c1130
-rw-r--r--sound/pci/ice1712/quartet.h10
-rw-r--r--sound/pci/ice1712/vt1720_mobo.c1
-rw-r--r--sound/pci/ice1712/wtm.c1
-rw-r--r--sound/pci/intel8x0.c8
-rw-r--r--sound/pci/intel8x0m.c2
-rw-r--r--sound/pci/korg1212/korg1212.c2
-rw-r--r--sound/pci/lx6464es/lx6464es.c3
-rw-r--r--sound/pci/maestro3.c11
-rw-r--r--sound/pci/mixart/mixart.c27
-rw-r--r--sound/pci/mixart/mixart_hwdep.c1
-rw-r--r--sound/pci/nm256/nm256.c2
-rw-r--r--sound/pci/oxygen/Makefile3
-rw-r--r--sound/pci/oxygen/cs2000.h83
-rw-r--r--sound/pci/oxygen/hifier.c63
-rw-r--r--sound/pci/oxygen/oxygen.c250
-rw-r--r--sound/pci/oxygen/oxygen.h5
-rw-r--r--sound/pci/oxygen/oxygen_lib.c30
-rw-r--r--sound/pci/oxygen/oxygen_mixer.c52
-rw-r--r--sound/pci/oxygen/oxygen_pcm.c19
-rw-r--r--sound/pci/oxygen/virtuoso.c1110
-rw-r--r--sound/pci/oxygen/wm8766.h73
-rw-r--r--sound/pci/oxygen/wm8776.h177
-rw-r--r--sound/pci/oxygen/xonar.h52
-rw-r--r--sound/pci/oxygen/xonar_cs43xx.c437
-rw-r--r--sound/pci/oxygen/xonar_hdmi.c128
-rw-r--r--sound/pci/oxygen/xonar_lib.c132
-rw-r--r--sound/pci/oxygen/xonar_pcm179x.c1115
-rw-r--r--sound/pci/oxygen/xonar_wm87x6.c1021
-rw-r--r--sound/pci/pcxhr/pcxhr.c2
-rw-r--r--sound/pci/riptide/riptide.c12
-rw-r--r--sound/pci/rme32.c4
-rw-r--r--sound/pci/rme96.c3
-rw-r--r--sound/pci/rme9652/hdsp.c3
-rw-r--r--sound/pci/rme9652/hdspm.c8
-rw-r--r--sound/pci/rme9652/rme9652.c3
-rw-r--r--sound/pci/sis7019.c3
-rw-r--r--sound/pci/sonicvibes.c2
-rw-r--r--sound/pci/trident/trident.c2
-rw-r--r--sound/pci/via82xx.c8
-rw-r--r--sound/pci/via82xx_modem.c2
-rw-r--r--sound/pci/vx222/vx222.c2
-rw-r--r--sound/pci/ymfpci/ymfpci.c2
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf.c9
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf_core.c1
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c53
-rw-r--r--sound/pcmcia/vx/vxpocket.c7
-rw-r--r--sound/ppc/awacs.c36
-rw-r--r--sound/ppc/burgundy.c13
-rw-r--r--sound/ppc/keywest.c1
-rw-r--r--sound/ppc/pmac.c18
-rw-r--r--sound/ppc/snd_ps3.c2
-rw-r--r--sound/ppc/tumbler.c2
-rw-r--r--sound/sh/Kconfig8
-rw-r--r--sound/sh/Makefile2
-rw-r--r--sound/sh/sh_dac_audio.c454
-rw-r--r--sound/soc/Makefile2
-rw-r--r--sound/soc/atmel/atmel-pcm.c2
-rw-r--r--sound/soc/atmel/atmel_ssc_dai.c6
-rw-r--r--sound/soc/atmel/playpaq_wm8510.c2
-rw-r--r--sound/soc/atmel/sam9g20_wm8731.c2
-rw-r--r--sound/soc/au1x/Kconfig10
-rw-r--r--sound/soc/au1x/Makefile4
-rw-r--r--sound/soc/au1x/db1200.c141
-rw-r--r--sound/soc/au1x/dbdma2.c129
-rw-r--r--sound/soc/au1x/psc-ac97.c244
-rw-r--r--sound/soc/au1x/psc-i2s.c190
-rw-r--r--sound/soc/au1x/psc.h7
-rw-r--r--sound/soc/au1x/sample-ac97.c144
-rw-r--r--sound/soc/blackfin/bf5xx-ac97-pcm.c10
-rw-r--r--sound/soc/blackfin/bf5xx-ac97.c1
-rw-r--r--sound/soc/blackfin/bf5xx-ad1836.c7
-rw-r--r--sound/soc/blackfin/bf5xx-ad1938.c9
-rw-r--r--sound/soc/blackfin/bf5xx-i2s-pcm.c5
-rw-r--r--sound/soc/blackfin/bf5xx-i2s.c15
-rw-r--r--sound/soc/blackfin/bf5xx-tdm-pcm.c14
-rw-r--r--sound/soc/blackfin/bf5xx-tdm.c45
-rw-r--r--sound/soc/blackfin/bf5xx-tdm.h11
-rw-r--r--sound/soc/codecs/Kconfig49
-rw-r--r--sound/soc/codecs/Makefile28
-rw-r--r--sound/soc/codecs/ac97.c13
-rw-r--r--sound/soc/codecs/ad1836.c109
-rw-r--r--sound/soc/codecs/ad1836.h1
-rw-r--r--sound/soc/codecs/ad1938.c241
-rw-r--r--sound/soc/codecs/ad1980.c6
-rw-r--r--sound/soc/codecs/ad73311.c9
-rw-r--r--sound/soc/codecs/ads117x.c124
-rw-r--r--sound/soc/codecs/ads117x.h13
-rw-r--r--sound/soc/codecs/ak4104.c19
-rw-r--r--sound/soc/codecs/ak4535.c10
-rw-r--r--sound/soc/codecs/ak4642.c12
-rw-r--r--sound/soc/codecs/ak4671.c816
-rw-r--r--sound/soc/codecs/ak4671.h156
-rw-r--r--sound/soc/codecs/cs4270.c114
-rw-r--r--sound/soc/codecs/cx20442.c13
-rw-r--r--sound/soc/codecs/da7210.c590
-rw-r--r--sound/soc/codecs/da7210.h24
-rw-r--r--sound/soc/codecs/pcm3008.c10
-rw-r--r--sound/soc/codecs/ssm2602.c10
-rw-r--r--sound/soc/codecs/stac9766.c22
-rw-r--r--sound/soc/codecs/tlv320aic23.c14
-rw-r--r--sound/soc/codecs/tlv320aic26.c12
-rw-r--r--sound/soc/codecs/tlv320aic3x.c87
-rw-r--r--sound/soc/codecs/tlv320dac33.c1423
-rw-r--r--sound/soc/codecs/tlv320dac33.h267
-rw-r--r--sound/soc/codecs/tpa6130a2.c531
-rw-r--r--sound/soc/codecs/tpa6130a2.h61
-rw-r--r--sound/soc/codecs/twl4030.c490
-rw-r--r--sound/soc/codecs/twl4030.h242
-rw-r--r--sound/soc/codecs/uda134x.c14
-rw-r--r--sound/soc/codecs/uda1380.c11
-rw-r--r--sound/soc/codecs/wm2000.c888
-rw-r--r--sound/soc/codecs/wm2000.h79
-rw-r--r--sound/soc/codecs/wm8350.c66
-rw-r--r--sound/soc/codecs/wm8400.c33
-rw-r--r--sound/soc/codecs/wm8510.c29
-rw-r--r--sound/soc/codecs/wm8523.c27
-rw-r--r--sound/soc/codecs/wm8580.c31
-rw-r--r--sound/soc/codecs/wm8711.c634
-rw-r--r--sound/soc/codecs/wm8711.h42
-rw-r--r--sound/soc/codecs/wm8727.c168
-rw-r--r--sound/soc/codecs/wm8727.h21
-rw-r--r--sound/soc/codecs/wm8728.c11
-rw-r--r--sound/soc/codecs/wm8731.c98
-rw-r--r--sound/soc/codecs/wm8750.c10
-rw-r--r--sound/soc/codecs/wm8753.c58
-rw-r--r--sound/soc/codecs/wm8776.c46
-rw-r--r--sound/soc/codecs/wm8900.c37
-rw-r--r--sound/soc/codecs/wm8903.c38
-rw-r--r--sound/soc/codecs/wm8904.c2657
-rw-r--r--sound/soc/codecs/wm8904.h1681
-rw-r--r--sound/soc/codecs/wm8940.c43
-rw-r--r--sound/soc/codecs/wm8955.c1152
-rw-r--r--sound/soc/codecs/wm8955.h489
-rw-r--r--sound/soc/codecs/wm8960.c31
-rw-r--r--sound/soc/codecs/wm8961.c31
-rw-r--r--sound/soc/codecs/wm8971.c12
-rw-r--r--sound/soc/codecs/wm8974.c65
-rw-r--r--sound/soc/codecs/wm8974.h12
-rw-r--r--sound/soc/codecs/wm8978.c1150
-rw-r--r--sound/soc/codecs/wm8978.h86
-rw-r--r--sound/soc/codecs/wm8988.c45
-rw-r--r--sound/soc/codecs/wm8990.c25
-rw-r--r--sound/soc/codecs/wm8993.c361
-rw-r--r--sound/soc/codecs/wm8994.c3874
-rw-r--r--sound/soc/codecs/wm8994.h26
-rw-r--r--sound/soc/codecs/wm9081.c28
-rw-r--r--sound/soc/codecs/wm9705.c8
-rw-r--r--sound/soc/codecs/wm9712.c11
-rw-r--r--sound/soc/codecs/wm9713.c91
-rw-r--r--sound/soc/codecs/wm_hubs.c222
-rw-r--r--sound/soc/codecs/wm_hubs.h12
-rw-r--r--sound/soc/davinci/Kconfig4
-rw-r--r--sound/soc/davinci/davinci-evm.c7
-rw-r--r--sound/soc/davinci/davinci-i2s.c87
-rw-r--r--sound/soc/davinci/davinci-mcasp.c37
-rw-r--r--sound/soc/davinci/davinci-mcasp.h6
-rw-r--r--sound/soc/davinci/davinci-pcm.c573
-rw-r--r--sound/soc/davinci/davinci-pcm.h2
-rw-r--r--sound/soc/fsl/efika-audio-fabric.c2
-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.c124
-rw-r--r--sound/soc/fsl/mpc5200_dma.h24
-rw-r--r--sound/soc/fsl/mpc5200_psc_ac97.c39
-rw-r--r--sound/soc/fsl/mpc8610_hpcd.c1
-rw-r--r--sound/soc/fsl/pcm030-audio-fabric.c2
-rw-r--r--sound/soc/fsl/soc-of-simple.c1
-rw-r--r--sound/soc/imx/Kconfig20
-rw-r--r--sound/soc/imx/Makefile14
-rw-r--r--sound/soc/imx/imx-pcm-dma-mx2.c331
-rw-r--r--sound/soc/imx/imx-pcm-fiq.c301
-rw-r--r--sound/soc/imx/imx-ssi.c763
-rw-r--r--sound/soc/imx/imx-ssi.h237
-rw-r--r--sound/soc/imx/mx1_mx2-pcm.c488
-rw-r--r--sound/soc/imx/mx1_mx2-pcm.h26
-rw-r--r--sound/soc/imx/mx27vis_wm8974.c317
-rw-r--r--sound/soc/imx/mxc-ssi.c860
-rw-r--r--sound/soc/imx/mxc-ssi.h238
-rw-r--r--sound/soc/imx/phycore-ac97.c90
-rw-r--r--sound/soc/omap/Kconfig34
-rw-r--r--sound/soc/omap/Makefile10
-rw-r--r--sound/soc/omap/am3517evm.c202
-rw-r--r--sound/soc/omap/ams-delta.c8
-rw-r--r--sound/soc/omap/igep0020.c148
-rw-r--r--sound/soc/omap/mcpdm.c485
-rw-r--r--sound/soc/omap/mcpdm.h151
-rw-r--r--sound/soc/omap/n810.c2
-rw-r--r--sound/soc/omap/omap-mcbsp.c219
-rw-r--r--sound/soc/omap/omap-mcbsp.h4
-rw-r--r--sound/soc/omap/omap-mcpdm.c252
-rw-r--r--sound/soc/omap/omap-mcpdm.h29
-rw-r--r--sound/soc/omap/omap-pcm.c39
-rw-r--r--sound/soc/omap/omap-pcm.h4
-rw-r--r--sound/soc/omap/omap2evm.c2
-rw-r--r--sound/soc/omap/omap3beagle.c8
-rw-r--r--sound/soc/omap/omap3evm.c9
-rw-r--r--sound/soc/omap/omap3pandora.c67
-rw-r--r--sound/soc/omap/osk5912.c2
-rw-r--r--sound/soc/omap/overo.c6
-rw-r--r--sound/soc/omap/sdp3430.c8
-rw-r--r--sound/soc/omap/zoom2.c2
-rw-r--r--sound/soc/pxa/Kconfig12
-rw-r--r--sound/soc/pxa/Makefile2
-rw-r--r--sound/soc/pxa/magician.c2
-rw-r--r--sound/soc/pxa/pxa-ssp.c141
-rw-r--r--sound/soc/pxa/pxa2xx-ac97.c17
-rw-r--r--sound/soc/pxa/pxa2xx-i2s.c7
-rw-r--r--sound/soc/pxa/pxa2xx-pcm.c4
-rw-r--r--sound/soc/pxa/raumfeld.c354
-rw-r--r--sound/soc/pxa/zylonite.c5
-rw-r--r--sound/soc/s3c24xx/Kconfig34
-rw-r--r--sound/soc/s3c24xx/Makefile13
-rw-r--r--sound/soc/s3c24xx/jive_wm8750.c2
-rw-r--r--sound/soc/s3c24xx/ln2440sbc_alc650.c6
-rw-r--r--sound/soc/s3c24xx/neo1973_gta02_wm8753.c10
-rw-r--r--sound/soc/s3c24xx/neo1973_wm8753.c11
-rw-r--r--sound/soc/s3c24xx/s3c-ac97.c521
-rw-r--r--sound/soc/s3c24xx/s3c-ac97.h23
-rw-r--r--sound/soc/s3c24xx/s3c-dma.c (renamed from sound/soc/s3c24xx/s3c24xx-pcm.c)90
-rw-r--r--sound/soc/s3c24xx/s3c-dma.h (renamed from sound/soc/s3c24xx/s3c24xx-pcm.h)8
-rw-r--r--sound/soc/s3c24xx/s3c-i2s-v2.c46
-rw-r--r--sound/soc/s3c24xx/s3c-i2s-v2.h4
-rw-r--r--sound/soc/s3c24xx/s3c-pcm.c554
-rw-r--r--sound/soc/s3c24xx/s3c-pcm.h123
-rw-r--r--sound/soc/s3c24xx/s3c2412-i2s.c7
-rw-r--r--sound/soc/s3c24xx/s3c2443-ac97.c433
-rw-r--r--sound/soc/s3c24xx/s3c24xx-ac97.h25
-rw-r--r--sound/soc/s3c24xx/s3c24xx-i2s.c27
-rw-r--r--sound/soc/s3c24xx/s3c24xx_simtec.c6
-rw-r--r--sound/soc/s3c24xx/s3c24xx_simtec.h2
-rw-r--r--sound/soc/s3c24xx/s3c24xx_simtec_hermes.c2
-rw-r--r--sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c2
-rw-r--r--sound/soc/s3c24xx/s3c24xx_uda134x.c2
-rw-r--r--sound/soc/s3c24xx/s3c64xx-i2s.c146
-rw-r--r--sound/soc/s3c24xx/s3c64xx-i2s.h1
-rw-r--r--sound/soc/s3c24xx/smdk2443_wm9710.c6
-rw-r--r--sound/soc/s3c24xx/smdk64xx_wm8580.c268
-rw-r--r--sound/soc/s3c24xx/smdk_wm9713.c94
-rw-r--r--sound/soc/s6000/s6000-i2s.c4
-rw-r--r--sound/soc/s6000/s6000-pcm.c46
-rw-r--r--sound/soc/sh/Kconfig25
-rw-r--r--sound/soc/sh/Makefile6
-rw-r--r--sound/soc/sh/dma-sh7760.c1
-rw-r--r--sound/soc/sh/fsi-ak4642.c30
-rw-r--r--sound/soc/sh/fsi-da7210.c83
-rw-r--r--sound/soc/sh/fsi.c483
-rw-r--r--sound/soc/sh/migor.c218
-rw-r--r--sound/soc/sh/siu.h193
-rw-r--r--sound/soc/sh/siu_dai.c848
-rw-r--r--sound/soc/sh/siu_pcm.c615
-rw-r--r--sound/soc/soc-cache.c257
-rw-r--r--sound/soc/soc-core.c629
-rw-r--r--sound/soc/soc-dapm.c278
-rw-r--r--sound/soc/soc-jack.c6
-rw-r--r--sound/soc/soc-utils.c74
-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.c1
-rw-r--r--sound/sound_core.c4
-rw-r--r--sound/sound_firmware.c1
-rw-r--r--sound/sparc/cs4231.c1
-rw-r--r--sound/sparc/dbri.c1
-rw-r--r--sound/synth/emux/emux_proc.c1
-rw-r--r--sound/synth/emux/soundfont.c2
-rw-r--r--sound/usb/Kconfig12
-rw-r--r--sound/usb/Makefile2
-rw-r--r--sound/usb/caiaq/audio.c1
-rw-r--r--sound/usb/caiaq/device.c1
-rw-r--r--sound/usb/caiaq/midi.c1
-rw-r--r--sound/usb/caiaq/midi.h2
-rw-r--r--sound/usb/ua101.c1387
-rw-r--r--sound/usb/usbaudio.c928
-rw-r--r--sound/usb/usbaudio.h116
-rw-r--r--sound/usb/usbmidi.c262
-rw-r--r--sound/usb/usbmixer.c371
-rw-r--r--sound/usb/usbmixer_maps.c46
-rw-r--r--sound/usb/usbquirks.h286
-rw-r--r--sound/usb/usx2y/us122l.c158
-rw-r--r--sound/usb/usx2y/us122l.h6
-rw-r--r--sound/usb/usx2y/usX2Yhwdep.c9
-rw-r--r--sound/usb/usx2y/usb_stream.c1
-rw-r--r--sound/usb/usx2y/usbusx2y.c29
-rw-r--r--sound/usb/usx2y/usbusx2y.h6
-rw-r--r--sound/usb/usx2y/usbusx2yaudio.c35
-rw-r--r--sound/usb/usx2y/usx2yhwdeppcm.c9
535 files changed, 49684 insertions, 14880 deletions
diff --git a/sound/Kconfig b/sound/Kconfig
index 439e15c8faa3..fcad760f5691 100644
--- a/sound/Kconfig
+++ b/sound/Kconfig
@@ -1,6 +1,3 @@
1# sound/Config.in
2#
3
4menuconfig SOUND 1menuconfig SOUND
5 tristate "Sound card support" 2 tristate "Sound card support"
6 depends on HAS_IOMEM 3 depends on HAS_IOMEM
@@ -58,7 +55,7 @@ config SOUND_OSS_CORE_PRECLAIM
58 Please read Documentation/feature-removal-schedule.txt for 55 Please read Documentation/feature-removal-schedule.txt for
59 details. 56 details.
60 57
61 If unusre, say Y. 58 If unsure, say Y.
62 59
63source "sound/oss/dmasound/Kconfig" 60source "sound/oss/dmasound/Kconfig"
64 61
@@ -136,4 +133,3 @@ config AC97_BUS
136 sound subsystem and other function drivers completely unrelated to 133 sound subsystem and other function drivers completely unrelated to
137 sound although they're sharing the AC97 bus. Concerned drivers 134 sound although they're sharing the AC97 bus. Concerned drivers
138 should "select" this. 135 should "select" this.
139
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..6776d1c12b63 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"
diff --git a/sound/aoa/fabrics/layout.c b/sound/aoa/fabrics/layout.c
index 586965f9605f..1cd9b301df03 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
@@ -768,7 +769,7 @@ static int check_codec(struct aoa_codec *codec,
768 "required property %s not present\n", propname); 769 "required property %s not present\n", propname);
769 return -ENODEV; 770 return -ENODEV;
770 } 771 }
771 if (*ref != codec->node->linux_phandle) { 772 if (*ref != codec->node->phandle) {
772 printk(KERN_INFO "snd-aoa-fabric-layout: " 773 printk(KERN_INFO "snd-aoa-fabric-layout: "
773 "%s doesn't match!\n", propname); 774 "%s doesn't match!\n", propname);
774 return -ENODEV; 775 return -ENODEV;
diff --git a/sound/aoa/soundbus/i2sbus/control.c b/sound/aoa/soundbus/i2sbus/control.c
index 87beb4ad4d63..47f854c2001f 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>
diff --git a/sound/aoa/soundbus/i2sbus/core.c b/sound/aoa/soundbus/i2sbus/core.c
index 4e3b819d4993..9d6f3b176ed1 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>
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/arm/Makefile b/sound/arm/Makefile
index 5a549ed6c8aa..8c0c851d4641 100644
--- a/sound/arm/Makefile
+++ b/sound/arm/Makefile
@@ -3,7 +3,7 @@
3# 3#
4 4
5obj-$(CONFIG_SND_ARMAACI) += snd-aaci.o 5obj-$(CONFIG_SND_ARMAACI) += snd-aaci.o
6snd-aaci-objs := aaci.o devdma.o 6snd-aaci-objs := aaci.o
7 7
8obj-$(CONFIG_SND_PXA2XX_PCM) += snd-pxa2xx-pcm.o 8obj-$(CONFIG_SND_PXA2XX_PCM) += snd-pxa2xx-pcm.o
9snd-pxa2xx-pcm-objs := pxa2xx-pcm.o 9snd-pxa2xx-pcm-objs := pxa2xx-pcm.o
diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c
index 6c160a038b23..91acc9a243ec 100644
--- a/sound/arm/aaci.c
+++ b/sound/arm/aaci.c
@@ -18,10 +18,7 @@
18#include <linux/interrupt.h> 18#include <linux/interrupt.h>
19#include <linux/err.h> 19#include <linux/err.h>
20#include <linux/amba/bus.h> 20#include <linux/amba/bus.h>
21 21#include <linux/io.h>
22#include <asm/io.h>
23#include <asm/irq.h>
24#include <asm/sizes.h>
25 22
26#include <sound/core.h> 23#include <sound/core.h>
27#include <sound/initval.h> 24#include <sound/initval.h>
@@ -30,7 +27,6 @@
30#include <sound/pcm_params.h> 27#include <sound/pcm_params.h>
31 28
32#include "aaci.h" 29#include "aaci.h"
33#include "devdma.h"
34 30
35#define DRIVER_NAME "aaci-pl041" 31#define DRIVER_NAME "aaci-pl041"
36 32
@@ -176,14 +172,15 @@ static unsigned short aaci_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
176 return v; 172 return v;
177} 173}
178 174
179static inline void aaci_chan_wait_ready(struct aaci_runtime *aacirun) 175static inline void
176aaci_chan_wait_ready(struct aaci_runtime *aacirun, unsigned long mask)
180{ 177{
181 u32 val; 178 u32 val;
182 int timeout = 5000; 179 int timeout = 5000;
183 180
184 do { 181 do {
185 val = readl(aacirun->base + AACI_SR); 182 val = readl(aacirun->base + AACI_SR);
186 } while (val & (SR_TXB|SR_RXB) && timeout--); 183 } while (val & mask && timeout--);
187} 184}
188 185
189 186
@@ -212,8 +209,10 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask)
212 writel(0, aacirun->base + AACI_IE); 209 writel(0, aacirun->base + AACI_IE);
213 return; 210 return;
214 } 211 }
215 ptr = aacirun->ptr;
216 212
213 spin_lock(&aacirun->lock);
214
215 ptr = aacirun->ptr;
217 do { 216 do {
218 unsigned int len = aacirun->fifosz; 217 unsigned int len = aacirun->fifosz;
219 u32 val; 218 u32 val;
@@ -221,9 +220,9 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask)
221 if (aacirun->bytes <= 0) { 220 if (aacirun->bytes <= 0) {
222 aacirun->bytes += aacirun->period; 221 aacirun->bytes += aacirun->period;
223 aacirun->ptr = ptr; 222 aacirun->ptr = ptr;
224 spin_unlock(&aaci->lock); 223 spin_unlock(&aacirun->lock);
225 snd_pcm_period_elapsed(aacirun->substream); 224 snd_pcm_period_elapsed(aacirun->substream);
226 spin_lock(&aaci->lock); 225 spin_lock(&aacirun->lock);
227 } 226 }
228 if (!(aacirun->cr & CR_EN)) 227 if (!(aacirun->cr & CR_EN))
229 break; 228 break;
@@ -249,7 +248,10 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask)
249 ptr = aacirun->start; 248 ptr = aacirun->start;
250 } 249 }
251 } while(1); 250 } while(1);
251
252 aacirun->ptr = ptr; 252 aacirun->ptr = ptr;
253
254 spin_unlock(&aacirun->lock);
253 } 255 }
254 256
255 if (mask & ISR_URINTR) { 257 if (mask & ISR_URINTR) {
@@ -267,6 +269,8 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask)
267 return; 269 return;
268 } 270 }
269 271
272 spin_lock(&aacirun->lock);
273
270 ptr = aacirun->ptr; 274 ptr = aacirun->ptr;
271 do { 275 do {
272 unsigned int len = aacirun->fifosz; 276 unsigned int len = aacirun->fifosz;
@@ -275,9 +279,9 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask)
275 if (aacirun->bytes <= 0) { 279 if (aacirun->bytes <= 0) {
276 aacirun->bytes += aacirun->period; 280 aacirun->bytes += aacirun->period;
277 aacirun->ptr = ptr; 281 aacirun->ptr = ptr;
278 spin_unlock(&aaci->lock); 282 spin_unlock(&aacirun->lock);
279 snd_pcm_period_elapsed(aacirun->substream); 283 snd_pcm_period_elapsed(aacirun->substream);
280 spin_lock(&aaci->lock); 284 spin_lock(&aacirun->lock);
281 } 285 }
282 if (!(aacirun->cr & CR_EN)) 286 if (!(aacirun->cr & CR_EN))
283 break; 287 break;
@@ -305,6 +309,8 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask)
305 } while (1); 309 } while (1);
306 310
307 aacirun->ptr = ptr; 311 aacirun->ptr = ptr;
312
313 spin_unlock(&aacirun->lock);
308 } 314 }
309} 315}
310 316
@@ -314,7 +320,6 @@ static irqreturn_t aaci_irq(int irq, void *devid)
314 u32 mask; 320 u32 mask;
315 int i; 321 int i;
316 322
317 spin_lock(&aaci->lock);
318 mask = readl(aaci->base + AACI_ALLINTS); 323 mask = readl(aaci->base + AACI_ALLINTS);
319 if (mask) { 324 if (mask) {
320 u32 m = mask; 325 u32 m = mask;
@@ -324,7 +329,6 @@ static irqreturn_t aaci_irq(int irq, void *devid)
324 } 329 }
325 } 330 }
326 } 331 }
327 spin_unlock(&aaci->lock);
328 332
329 return mask ? IRQ_HANDLED : IRQ_NONE; 333 return mask ? IRQ_HANDLED : IRQ_NONE;
330} 334}
@@ -334,63 +338,6 @@ static irqreturn_t aaci_irq(int irq, void *devid)
334/* 338/*
335 * ALSA support. 339 * ALSA support.
336 */ 340 */
337
338struct aaci_stream {
339 unsigned char codec_idx;
340 unsigned char rate_idx;
341};
342
343static struct aaci_stream aaci_streams[] = {
344 [ACSTREAM_FRONT] = {
345 .codec_idx = 0,
346 .rate_idx = AC97_RATES_FRONT_DAC,
347 },
348 [ACSTREAM_SURROUND] = {
349 .codec_idx = 0,
350 .rate_idx = AC97_RATES_SURR_DAC,
351 },
352 [ACSTREAM_LFE] = {
353 .codec_idx = 0,
354 .rate_idx = AC97_RATES_LFE_DAC,
355 },
356};
357
358static inline unsigned int aaci_rate_mask(struct aaci *aaci, int streamid)
359{
360 struct aaci_stream *s = aaci_streams + streamid;
361 return aaci->ac97_bus->codec[s->codec_idx]->rates[s->rate_idx];
362}
363
364static unsigned int rate_list[] = {
365 5512, 8000, 11025, 16000, 22050, 32000, 44100,
366 48000, 64000, 88200, 96000, 176400, 192000
367};
368
369/*
370 * Double-rate rule: we can support double rate iff channels == 2
371 * (unimplemented)
372 */
373static int
374aaci_rule_rate_by_channels(struct snd_pcm_hw_params *p, struct snd_pcm_hw_rule *rule)
375{
376 struct aaci *aaci = rule->private;
377 unsigned int rate_mask = SNDRV_PCM_RATE_8000_48000|SNDRV_PCM_RATE_5512;
378 struct snd_interval *c = hw_param_interval(p, SNDRV_PCM_HW_PARAM_CHANNELS);
379
380 switch (c->max) {
381 case 6:
382 rate_mask &= aaci_rate_mask(aaci, ACSTREAM_LFE);
383 case 4:
384 rate_mask &= aaci_rate_mask(aaci, ACSTREAM_SURROUND);
385 case 2:
386 rate_mask &= aaci_rate_mask(aaci, ACSTREAM_FRONT);
387 }
388
389 return snd_interval_list(hw_param_interval(p, rule->var),
390 ARRAY_SIZE(rate_list), rate_list,
391 rate_mask);
392}
393
394static struct snd_pcm_hardware aaci_hw_info = { 341static struct snd_pcm_hardware aaci_hw_info = {
395 .info = SNDRV_PCM_INFO_MMAP | 342 .info = SNDRV_PCM_INFO_MMAP |
396 SNDRV_PCM_INFO_MMAP_VALID | 343 SNDRV_PCM_INFO_MMAP_VALID |
@@ -404,10 +351,7 @@ static struct snd_pcm_hardware aaci_hw_info = {
404 */ 351 */
405 .formats = SNDRV_PCM_FMTBIT_S16_LE, 352 .formats = SNDRV_PCM_FMTBIT_S16_LE,
406 353
407 /* should this be continuous or knot? */ 354 /* rates are setup from the AC'97 codec */
408 .rates = SNDRV_PCM_RATE_CONTINUOUS,
409 .rate_max = 48000,
410 .rate_min = 4000,
411 .channels_min = 2, 355 .channels_min = 2,
412 .channels_max = 6, 356 .channels_max = 6,
413 .buffer_bytes_max = 64 * 1024, 357 .buffer_bytes_max = 64 * 1024,
@@ -427,6 +371,12 @@ static int __aaci_pcm_open(struct aaci *aaci,
427 aacirun->substream = substream; 371 aacirun->substream = substream;
428 runtime->private_data = aacirun; 372 runtime->private_data = aacirun;
429 runtime->hw = aaci_hw_info; 373 runtime->hw = aaci_hw_info;
374 runtime->hw.rates = aacirun->pcm->rates;
375 snd_pcm_limit_hw_rates(runtime);
376
377 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
378 aacirun->pcm->r[1].slots)
379 snd_ac97_pcm_double_rate_rules(runtime);
430 380
431 /* 381 /*
432 * FIXME: ALSA specifies fifo_size in bytes. If we're in normal 382 * FIXME: ALSA specifies fifo_size in bytes. If we're in normal
@@ -437,17 +387,6 @@ static int __aaci_pcm_open(struct aaci *aaci,
437 */ 387 */
438 runtime->hw.fifo_size = aaci->fifosize * 2; 388 runtime->hw.fifo_size = aaci->fifosize * 2;
439 389
440 /*
441 * Add rule describing hardware rate dependency
442 * on the number of channels.
443 */
444 ret = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
445 aaci_rule_rate_by_channels, aaci,
446 SNDRV_PCM_HW_PARAM_CHANNELS,
447 SNDRV_PCM_HW_PARAM_RATE, -1);
448 if (ret)
449 goto out;
450
451 ret = request_irq(aaci->dev->irq[0], aaci_irq, IRQF_SHARED|IRQF_DISABLED, 390 ret = request_irq(aaci->dev->irq[0], aaci_irq, IRQF_SHARED|IRQF_DISABLED,
452 DRIVER_NAME, aaci); 391 DRIVER_NAME, aaci);
453 if (ret) 392 if (ret)
@@ -492,7 +431,7 @@ static int aaci_pcm_hw_free(struct snd_pcm_substream *substream)
492 /* 431 /*
493 * Clear out the DMA and any allocated buffers. 432 * Clear out the DMA and any allocated buffers.
494 */ 433 */
495 devdma_hw_free(NULL, substream); 434 snd_pcm_lib_free_pages(substream);
496 435
497 return 0; 436 return 0;
498} 437}
@@ -502,6 +441,7 @@ static int aaci_pcm_hw_params(struct snd_pcm_substream *substream,
502 struct snd_pcm_hw_params *params) 441 struct snd_pcm_hw_params *params)
503{ 442{
504 int err; 443 int err;
444 struct aaci *aaci = substream->private_data;
505 445
506 aaci_pcm_hw_free(substream); 446 aaci_pcm_hw_free(substream);
507 if (aacirun->pcm_open) { 447 if (aacirun->pcm_open) {
@@ -509,26 +449,24 @@ static int aaci_pcm_hw_params(struct snd_pcm_substream *substream,
509 aacirun->pcm_open = 0; 449 aacirun->pcm_open = 0;
510 } 450 }
511 451
512 err = devdma_hw_alloc(NULL, substream, 452 err = snd_pcm_lib_malloc_pages(substream,
513 params_buffer_bytes(params)); 453 params_buffer_bytes(params));
514 if (err < 0) 454 if (err >= 0) {
515 goto out; 455 unsigned int rate = params_rate(params);
456 int dbl = rate > 48000;
516 457
517 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 458 err = snd_ac97_pcm_open(aacirun->pcm, rate,
518 err = snd_ac97_pcm_open(aacirun->pcm, params_rate(params),
519 params_channels(params), 459 params_channels(params),
520 aacirun->pcm->r[0].slots); 460 aacirun->pcm->r[dbl].slots);
521 else
522 err = snd_ac97_pcm_open(aacirun->pcm, params_rate(params),
523 params_channels(params),
524 aacirun->pcm->r[0].slots);
525 461
526 if (err) 462 aacirun->pcm_open = err == 0;
527 goto out; 463 aacirun->cr = CR_FEN | CR_COMPACT | CR_SZ16;
464 aacirun->fifosz = aaci->fifosize * 4;
528 465
529 aacirun->pcm_open = 1; 466 if (aacirun->cr & CR_COMPACT)
467 aacirun->fifosz >>= 1;
468 }
530 469
531 out:
532 return err; 470 return err;
533} 471}
534 472
@@ -537,8 +475,8 @@ static int aaci_pcm_prepare(struct snd_pcm_substream *substream)
537 struct snd_pcm_runtime *runtime = substream->runtime; 475 struct snd_pcm_runtime *runtime = substream->runtime;
538 struct aaci_runtime *aacirun = runtime->private_data; 476 struct aaci_runtime *aacirun = runtime->private_data;
539 477
540 aacirun->start = (void *)runtime->dma_area; 478 aacirun->start = runtime->dma_area;
541 aacirun->end = aacirun->start + runtime->dma_bytes; 479 aacirun->end = aacirun->start + snd_pcm_lib_buffer_bytes(substream);
542 aacirun->ptr = aacirun->start; 480 aacirun->ptr = aacirun->start;
543 aacirun->period = 481 aacirun->period =
544 aacirun->bytes = frames_to_bytes(runtime, runtime->period_size); 482 aacirun->bytes = frames_to_bytes(runtime, runtime->period_size);
@@ -555,11 +493,6 @@ static snd_pcm_uframes_t aaci_pcm_pointer(struct snd_pcm_substream *substream)
555 return bytes_to_frames(runtime, bytes); 493 return bytes_to_frames(runtime, bytes);
556} 494}
557 495
558static int aaci_pcm_mmap(struct snd_pcm_substream *substream, struct vm_area_struct *vma)
559{
560 return devdma_mmap(NULL, substream, vma);
561}
562
563 496
564/* 497/*
565 * Playback specific ALSA stuff 498 * Playback specific ALSA stuff
@@ -628,7 +561,6 @@ static int aaci_pcm_open(struct snd_pcm_substream *substream)
628static int aaci_pcm_playback_hw_params(struct snd_pcm_substream *substream, 561static int aaci_pcm_playback_hw_params(struct snd_pcm_substream *substream,
629 struct snd_pcm_hw_params *params) 562 struct snd_pcm_hw_params *params)
630{ 563{
631 struct aaci *aaci = substream->private_data;
632 struct aaci_runtime *aacirun = substream->runtime->private_data; 564 struct aaci_runtime *aacirun = substream->runtime->private_data;
633 unsigned int channels = params_channels(params); 565 unsigned int channels = params_channels(params);
634 int ret; 566 int ret;
@@ -642,14 +574,9 @@ static int aaci_pcm_playback_hw_params(struct snd_pcm_substream *substream,
642 * Enable FIFO, compact mode, 16 bits per sample. 574 * Enable FIFO, compact mode, 16 bits per sample.
643 * FIXME: double rate slots? 575 * FIXME: double rate slots?
644 */ 576 */
645 if (ret >= 0) { 577 if (ret >= 0)
646 aacirun->cr = CR_FEN | CR_COMPACT | CR_SZ16;
647 aacirun->cr |= channels_to_txmask[channels]; 578 aacirun->cr |= channels_to_txmask[channels];
648 579
649 aacirun->fifosz = aaci->fifosize * 4;
650 if (aacirun->cr & CR_COMPACT)
651 aacirun->fifosz >>= 1;
652 }
653 return ret; 580 return ret;
654} 581}
655 582
@@ -661,7 +588,7 @@ static void aaci_pcm_playback_stop(struct aaci_runtime *aacirun)
661 ie &= ~(IE_URIE|IE_TXIE); 588 ie &= ~(IE_URIE|IE_TXIE);
662 writel(ie, aacirun->base + AACI_IE); 589 writel(ie, aacirun->base + AACI_IE);
663 aacirun->cr &= ~CR_EN; 590 aacirun->cr &= ~CR_EN;
664 aaci_chan_wait_ready(aacirun); 591 aaci_chan_wait_ready(aacirun, SR_TXB);
665 writel(aacirun->cr, aacirun->base + AACI_TXCR); 592 writel(aacirun->cr, aacirun->base + AACI_TXCR);
666} 593}
667 594
@@ -669,7 +596,7 @@ static void aaci_pcm_playback_start(struct aaci_runtime *aacirun)
669{ 596{
670 u32 ie; 597 u32 ie;
671 598
672 aaci_chan_wait_ready(aacirun); 599 aaci_chan_wait_ready(aacirun, SR_TXB);
673 aacirun->cr |= CR_EN; 600 aacirun->cr |= CR_EN;
674 601
675 ie = readl(aacirun->base + AACI_IE); 602 ie = readl(aacirun->base + AACI_IE);
@@ -680,12 +607,12 @@ static void aaci_pcm_playback_start(struct aaci_runtime *aacirun)
680 607
681static int aaci_pcm_playback_trigger(struct snd_pcm_substream *substream, int cmd) 608static int aaci_pcm_playback_trigger(struct snd_pcm_substream *substream, int cmd)
682{ 609{
683 struct aaci *aaci = substream->private_data;
684 struct aaci_runtime *aacirun = substream->runtime->private_data; 610 struct aaci_runtime *aacirun = substream->runtime->private_data;
685 unsigned long flags; 611 unsigned long flags;
686 int ret = 0; 612 int ret = 0;
687 613
688 spin_lock_irqsave(&aaci->lock, flags); 614 spin_lock_irqsave(&aacirun->lock, flags);
615
689 switch (cmd) { 616 switch (cmd) {
690 case SNDRV_PCM_TRIGGER_START: 617 case SNDRV_PCM_TRIGGER_START:
691 aaci_pcm_playback_start(aacirun); 618 aaci_pcm_playback_start(aacirun);
@@ -712,7 +639,8 @@ static int aaci_pcm_playback_trigger(struct snd_pcm_substream *substream, int cm
712 default: 639 default:
713 ret = -EINVAL; 640 ret = -EINVAL;
714 } 641 }
715 spin_unlock_irqrestore(&aaci->lock, flags); 642
643 spin_unlock_irqrestore(&aacirun->lock, flags);
716 644
717 return ret; 645 return ret;
718} 646}
@@ -726,29 +654,19 @@ static struct snd_pcm_ops aaci_playback_ops = {
726 .prepare = aaci_pcm_prepare, 654 .prepare = aaci_pcm_prepare,
727 .trigger = aaci_pcm_playback_trigger, 655 .trigger = aaci_pcm_playback_trigger,
728 .pointer = aaci_pcm_pointer, 656 .pointer = aaci_pcm_pointer,
729 .mmap = aaci_pcm_mmap,
730}; 657};
731 658
732static int aaci_pcm_capture_hw_params(struct snd_pcm_substream *substream, 659static int aaci_pcm_capture_hw_params(struct snd_pcm_substream *substream,
733 struct snd_pcm_hw_params *params) 660 struct snd_pcm_hw_params *params)
734{ 661{
735 struct aaci *aaci = substream->private_data;
736 struct aaci_runtime *aacirun = substream->runtime->private_data; 662 struct aaci_runtime *aacirun = substream->runtime->private_data;
737 int ret; 663 int ret;
738 664
739 ret = aaci_pcm_hw_params(substream, aacirun, params); 665 ret = aaci_pcm_hw_params(substream, aacirun, params);
740 666 if (ret >= 0)
741 if (ret >= 0) {
742 aacirun->cr = CR_FEN | CR_COMPACT | CR_SZ16;
743
744 /* Line in record: slot 3 and 4 */ 667 /* Line in record: slot 3 and 4 */
745 aacirun->cr |= CR_SL3 | CR_SL4; 668 aacirun->cr |= CR_SL3 | CR_SL4;
746 669
747 aacirun->fifosz = aaci->fifosize * 4;
748
749 if (aacirun->cr & CR_COMPACT)
750 aacirun->fifosz >>= 1;
751 }
752 return ret; 670 return ret;
753} 671}
754 672
@@ -756,7 +674,7 @@ static void aaci_pcm_capture_stop(struct aaci_runtime *aacirun)
756{ 674{
757 u32 ie; 675 u32 ie;
758 676
759 aaci_chan_wait_ready(aacirun); 677 aaci_chan_wait_ready(aacirun, SR_RXB);
760 678
761 ie = readl(aacirun->base + AACI_IE); 679 ie = readl(aacirun->base + AACI_IE);
762 ie &= ~(IE_ORIE | IE_RXIE); 680 ie &= ~(IE_ORIE | IE_RXIE);
@@ -771,7 +689,7 @@ static void aaci_pcm_capture_start(struct aaci_runtime *aacirun)
771{ 689{
772 u32 ie; 690 u32 ie;
773 691
774 aaci_chan_wait_ready(aacirun); 692 aaci_chan_wait_ready(aacirun, SR_RXB);
775 693
776#ifdef DEBUG 694#ifdef DEBUG
777 /* RX Timeout value: bits 28:17 in RXCR */ 695 /* RX Timeout value: bits 28:17 in RXCR */
@@ -788,12 +706,11 @@ static void aaci_pcm_capture_start(struct aaci_runtime *aacirun)
788 706
789static int aaci_pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd) 707static int aaci_pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd)
790{ 708{
791 struct aaci *aaci = substream->private_data;
792 struct aaci_runtime *aacirun = substream->runtime->private_data; 709 struct aaci_runtime *aacirun = substream->runtime->private_data;
793 unsigned long flags; 710 unsigned long flags;
794 int ret = 0; 711 int ret = 0;
795 712
796 spin_lock_irqsave(&aaci->lock, flags); 713 spin_lock_irqsave(&aacirun->lock, flags);
797 714
798 switch (cmd) { 715 switch (cmd) {
799 case SNDRV_PCM_TRIGGER_START: 716 case SNDRV_PCM_TRIGGER_START:
@@ -822,7 +739,7 @@ static int aaci_pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd
822 ret = -EINVAL; 739 ret = -EINVAL;
823 } 740 }
824 741
825 spin_unlock_irqrestore(&aaci->lock, flags); 742 spin_unlock_irqrestore(&aacirun->lock, flags);
826 743
827 return ret; 744 return ret;
828} 745}
@@ -854,7 +771,6 @@ static struct snd_pcm_ops aaci_capture_ops = {
854 .prepare = aaci_pcm_capture_prepare, 771 .prepare = aaci_pcm_capture_prepare,
855 .trigger = aaci_pcm_capture_trigger, 772 .trigger = aaci_pcm_capture_trigger,
856 .pointer = aaci_pcm_pointer, 773 .pointer = aaci_pcm_pointer,
857 .mmap = aaci_pcm_mmap,
858}; 774};
859 775
860/* 776/*
@@ -906,6 +822,12 @@ static struct ac97_pcm ac97_defs[] __devinitdata = {
906 (1 << AC97_SLOT_PCM_SRIGHT) | 822 (1 << AC97_SLOT_PCM_SRIGHT) |
907 (1 << AC97_SLOT_LFE), 823 (1 << AC97_SLOT_LFE),
908 }, 824 },
825 [1] = {
826 .slots = (1 << AC97_SLOT_PCM_LEFT) |
827 (1 << AC97_SLOT_PCM_RIGHT) |
828 (1 << AC97_SLOT_PCM_LEFT_0) |
829 (1 << AC97_SLOT_PCM_RIGHT_0),
830 },
909 }, 831 },
910 }, 832 },
911 [1] = { /* PCM in */ 833 [1] = { /* PCM in */
@@ -941,7 +863,6 @@ static int __devinit aaci_probe_ac97(struct aaci *aaci)
941 struct snd_ac97 *ac97; 863 struct snd_ac97 *ac97;
942 int ret; 864 int ret;
943 865
944 writel(0, aaci->base + AC97_POWERDOWN);
945 /* 866 /*
946 * Assert AACIRESET for 2us 867 * Assert AACIRESET for 2us
947 */ 868 */
@@ -1018,7 +939,6 @@ static struct aaci * __devinit aaci_init_card(struct amba_device *dev)
1018 939
1019 aaci = card->private_data; 940 aaci = card->private_data;
1020 mutex_init(&aaci->ac97_sem); 941 mutex_init(&aaci->ac97_sem);
1021 spin_lock_init(&aaci->lock);
1022 aaci->card = card; 942 aaci->card = card;
1023 aaci->dev = dev; 943 aaci->dev = dev;
1024 944
@@ -1044,6 +964,8 @@ static int __devinit aaci_init_pcm(struct aaci *aaci)
1044 964
1045 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &aaci_playback_ops); 965 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &aaci_playback_ops);
1046 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &aaci_capture_ops); 966 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &aaci_capture_ops);
967 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
968 NULL, 0, 64 * 1024);
1047 } 969 }
1048 970
1049 return ret; 971 return ret;
@@ -1103,12 +1025,14 @@ static int __devinit aaci_probe(struct amba_device *dev, struct amba_id *id)
1103 /* 1025 /*
1104 * Playback uses AACI channel 0 1026 * Playback uses AACI channel 0
1105 */ 1027 */
1028 spin_lock_init(&aaci->playback.lock);
1106 aaci->playback.base = aaci->base + AACI_CSCH1; 1029 aaci->playback.base = aaci->base + AACI_CSCH1;
1107 aaci->playback.fifo = aaci->base + AACI_DR1; 1030 aaci->playback.fifo = aaci->base + AACI_DR1;
1108 1031
1109 /* 1032 /*
1110 * Capture uses AACI channel 0 1033 * Capture uses AACI channel 0
1111 */ 1034 */
1035 spin_lock_init(&aaci->capture.lock);
1112 aaci->capture.base = aaci->base + AACI_CSCH1; 1036 aaci->capture.base = aaci->base + AACI_CSCH1;
1113 aaci->capture.fifo = aaci->base + AACI_DR1; 1037 aaci->capture.fifo = aaci->base + AACI_DR1;
1114 1038
@@ -1122,7 +1046,11 @@ static int __devinit aaci_probe(struct amba_device *dev, struct amba_id *id)
1122 1046
1123 writel(0x1fff, aaci->base + AACI_INTCLR); 1047 writel(0x1fff, aaci->base + AACI_INTCLR);
1124 writel(aaci->maincr, aaci->base + AACI_MAINCR); 1048 writel(aaci->maincr, aaci->base + AACI_MAINCR);
1125 1049 /*
1050 * Fix: ac97 read back fail errors by reading
1051 * from any arbitrary aaci register.
1052 */
1053 readl(aaci->base + AACI_CSCH1);
1126 ret = aaci_probe_ac97(aaci); 1054 ret = aaci_probe_ac97(aaci);
1127 if (ret) 1055 if (ret)
1128 goto out; 1056 goto out;
diff --git a/sound/arm/aaci.h b/sound/arm/aaci.h
index 924f69c1c44c..6a4a2eebdda1 100644
--- a/sound/arm/aaci.h
+++ b/sound/arm/aaci.h
@@ -202,6 +202,7 @@
202struct aaci_runtime { 202struct aaci_runtime {
203 void __iomem *base; 203 void __iomem *base;
204 void __iomem *fifo; 204 void __iomem *fifo;
205 spinlock_t lock;
205 206
206 struct ac97_pcm *pcm; 207 struct ac97_pcm *pcm;
207 int pcm_open; 208 int pcm_open;
@@ -232,7 +233,6 @@ struct aaci {
232 struct snd_ac97 *ac97; 233 struct snd_ac97 *ac97;
233 234
234 u32 maincr; 235 u32 maincr;
235 spinlock_t lock;
236 236
237 struct aaci_runtime playback; 237 struct aaci_runtime playback;
238 struct aaci_runtime capture; 238 struct aaci_runtime capture;
diff --git a/sound/arm/devdma.c b/sound/arm/devdma.c
deleted file mode 100644
index 9d1e6665b546..000000000000
--- a/sound/arm/devdma.c
+++ /dev/null
@@ -1,80 +0,0 @@
1/*
2 * linux/sound/arm/devdma.c
3 *
4 * Copyright (C) 2003-2004 Russell King, All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * ARM DMA shim for ALSA.
11 */
12#include <linux/device.h>
13#include <linux/dma-mapping.h>
14
15#include <sound/core.h>
16#include <sound/pcm.h>
17
18#include "devdma.h"
19
20void devdma_hw_free(struct device *dev, struct snd_pcm_substream *substream)
21{
22 struct snd_pcm_runtime *runtime = substream->runtime;
23 struct snd_dma_buffer *buf = runtime->dma_buffer_p;
24
25 if (runtime->dma_area == NULL)
26 return;
27
28 if (buf != &substream->dma_buffer) {
29 dma_free_coherent(buf->dev.dev, buf->bytes, buf->area, buf->addr);
30 kfree(runtime->dma_buffer_p);
31 }
32
33 snd_pcm_set_runtime_buffer(substream, NULL);
34}
35
36int devdma_hw_alloc(struct device *dev, struct snd_pcm_substream *substream, size_t size)
37{
38 struct snd_pcm_runtime *runtime = substream->runtime;
39 struct snd_dma_buffer *buf = runtime->dma_buffer_p;
40 int ret = 0;
41
42 if (buf) {
43 if (buf->bytes >= size)
44 goto out;
45 devdma_hw_free(dev, substream);
46 }
47
48 if (substream->dma_buffer.area != NULL && substream->dma_buffer.bytes >= size) {
49 buf = &substream->dma_buffer;
50 } else {
51 buf = kmalloc(sizeof(struct snd_dma_buffer), GFP_KERNEL);
52 if (!buf)
53 goto nomem;
54
55 buf->dev.type = SNDRV_DMA_TYPE_DEV;
56 buf->dev.dev = dev;
57 buf->area = dma_alloc_coherent(dev, size, &buf->addr, GFP_KERNEL);
58 buf->bytes = size;
59 buf->private_data = NULL;
60
61 if (!buf->area)
62 goto free;
63 }
64 snd_pcm_set_runtime_buffer(substream, buf);
65 ret = 1;
66 out:
67 runtime->dma_bytes = size;
68 return ret;
69
70 free:
71 kfree(buf);
72 nomem:
73 return -ENOMEM;
74}
75
76int devdma_mmap(struct device *dev, struct snd_pcm_substream *substream, struct vm_area_struct *vma)
77{
78 struct snd_pcm_runtime *runtime = substream->runtime;
79 return dma_mmap_coherent(dev, vma, runtime->dma_area, runtime->dma_addr, runtime->dma_bytes);
80}
diff --git a/sound/arm/devdma.h b/sound/arm/devdma.h
deleted file mode 100644
index d025329c8a0f..000000000000
--- a/sound/arm/devdma.h
+++ /dev/null
@@ -1,3 +0,0 @@
1void devdma_hw_free(struct device *dev, struct snd_pcm_substream *substream);
2int devdma_hw_alloc(struct device *dev, struct snd_pcm_substream *substream, size_t size);
3int devdma_mmap(struct device *dev, struct snd_pcm_substream *substream, struct vm_area_struct *vma);
diff --git a/sound/arm/pxa2xx-ac97-lib.c b/sound/arm/pxa2xx-ac97-lib.c
index 6fdca97186e7..88eec3847df2 100644
--- a/sound/arm/pxa2xx-ac97-lib.c
+++ b/sound/arm/pxa2xx-ac97-lib.c
@@ -22,7 +22,6 @@
22 22
23#include <asm/irq.h> 23#include <asm/irq.h>
24#include <mach/regs-ac97.h> 24#include <mach/regs-ac97.h>
25#include <mach/pxa2xx-gpio.h>
26#include <mach/audio.h> 25#include <mach/audio.h>
27 26
28static DEFINE_MUTEX(car_mutex); 27static DEFINE_MUTEX(car_mutex);
@@ -32,6 +31,8 @@ static struct clk *ac97_clk;
32static struct clk *ac97conf_clk; 31static struct clk *ac97conf_clk;
33static int reset_gpio; 32static int reset_gpio;
34 33
34extern void pxa27x_assert_ac97reset(int reset_gpio, int on);
35
35/* 36/*
36 * Beware PXA27x bugs: 37 * Beware PXA27x bugs:
37 * 38 *
@@ -42,45 +43,6 @@ static int reset_gpio;
42 * 1 jiffy timeout if interrupt never comes). 43 * 1 jiffy timeout if interrupt never comes).
43 */ 44 */
44 45
45enum {
46 RESETGPIO_FORCE_HIGH,
47 RESETGPIO_FORCE_LOW,
48 RESETGPIO_NORMAL_ALTFUNC
49};
50
51/**
52 * set_resetgpio_mode - computes and sets the AC97_RESET gpio mode on PXA
53 * @mode: chosen action
54 *
55 * As the PXA27x CPUs suffer from a AC97 bug, a manual control of the reset line
56 * must be done to insure proper work of AC97 reset line. This function
57 * computes the correct gpio_mode for further use by reset functions, and
58 * applied the change through pxa_gpio_mode.
59 */
60static void set_resetgpio_mode(int resetgpio_action)
61{
62 int mode = 0;
63
64 if (reset_gpio)
65 switch (resetgpio_action) {
66 case RESETGPIO_NORMAL_ALTFUNC:
67 if (reset_gpio == 113)
68 mode = 113 | GPIO_ALT_FN_2_OUT;
69 if (reset_gpio == 95)
70 mode = 95 | GPIO_ALT_FN_1_OUT;
71 break;
72 case RESETGPIO_FORCE_LOW:
73 mode = reset_gpio | GPIO_OUT | GPIO_DFLT_LOW;
74 break;
75 case RESETGPIO_FORCE_HIGH:
76 mode = reset_gpio | GPIO_OUT | GPIO_DFLT_HIGH;
77 break;
78 };
79
80 if (mode)
81 pxa_gpio_mode(mode);
82}
83
84unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg) 46unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
85{ 47{
86 unsigned short val = -1; 48 unsigned short val = -1;
@@ -174,12 +136,11 @@ static inline void pxa_ac97_warm_pxa27x(void)
174{ 136{
175 gsr_bits = 0; 137 gsr_bits = 0;
176 138
177 /* warm reset broken on Bulverde, 139 /* warm reset broken on Bulverde, so manually keep AC97 reset high */
178 so manually keep AC97 reset high */ 140 pxa27x_assert_ac97reset(reset_gpio, 1);
179 set_resetgpio_mode(RESETGPIO_FORCE_HIGH);
180 udelay(10); 141 udelay(10);
181 GCR |= GCR_WARM_RST; 142 GCR |= GCR_WARM_RST;
182 set_resetgpio_mode(RESETGPIO_NORMAL_ALTFUNC); 143 pxa27x_assert_ac97reset(reset_gpio, 0);
183 udelay(500); 144 udelay(500);
184} 145}
185 146
@@ -345,16 +306,6 @@ EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_suspend);
345 306
346int pxa2xx_ac97_hw_resume(void) 307int pxa2xx_ac97_hw_resume(void)
347{ 308{
348 if (cpu_is_pxa25x() || cpu_is_pxa27x()) {
349 pxa_gpio_mode(GPIO31_SYNC_AC97_MD);
350 pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD);
351 pxa_gpio_mode(GPIO28_BITCLK_AC97_MD);
352 pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD);
353 }
354 if (cpu_is_pxa27x()) {
355 /* Use GPIO 113 or 95 as AC97 Reset on Bulverde */
356 set_resetgpio_mode(RESETGPIO_NORMAL_ALTFUNC);
357 }
358 clk_enable(ac97_clk); 309 clk_enable(ac97_clk);
359 return 0; 310 return 0;
360} 311}
@@ -386,16 +337,9 @@ int __devinit pxa2xx_ac97_hw_probe(struct platform_device *dev)
386 reset_gpio = 113; 337 reset_gpio = 113;
387 } 338 }
388 339
389 if (cpu_is_pxa25x() || cpu_is_pxa27x()) {
390 pxa_gpio_mode(GPIO31_SYNC_AC97_MD);
391 pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD);
392 pxa_gpio_mode(GPIO28_BITCLK_AC97_MD);
393 pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD);
394 }
395
396 if (cpu_is_pxa27x()) { 340 if (cpu_is_pxa27x()) {
397 /* Use GPIO 113 as AC97 Reset on Bulverde */ 341 /* Use GPIO 113 as AC97 Reset on Bulverde */
398 set_resetgpio_mode(RESETGPIO_NORMAL_ALTFUNC); 342 pxa27x_assert_ac97reset(reset_gpio, 0);
399 ac97conf_clk = clk_get(&dev->dev, "AC97CONFCLK"); 343 ac97conf_clk = clk_get(&dev->dev, "AC97CONFCLK");
400 if (IS_ERR(ac97conf_clk)) { 344 if (IS_ERR(ac97conf_clk)) {
401 ret = PTR_ERR(ac97conf_clk); 345 ret = PTR_ERR(ac97conf_clk);
diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c
index b4b48afb6de6..5d9411839cd7 100644
--- a/sound/arm/pxa2xx-ac97.c
+++ b/sound/arm/pxa2xx-ac97.c
@@ -159,7 +159,7 @@ static int pxa2xx_ac97_resume(struct device *dev)
159 return ret; 159 return ret;
160} 160}
161 161
162static struct dev_pm_ops pxa2xx_ac97_pm_ops = { 162static const struct dev_pm_ops pxa2xx_ac97_pm_ops = {
163 .suspend = pxa2xx_ac97_suspend, 163 .suspend = pxa2xx_ac97_suspend,
164 .resume = pxa2xx_ac97_resume, 164 .resume = pxa2xx_ac97_resume,
165}; 165};
diff --git a/sound/arm/pxa2xx-pcm-lib.c b/sound/arm/pxa2xx-pcm-lib.c
index 743ac6a29065..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
@@ -205,6 +206,7 @@ int __pxa2xx_pcm_open(struct snd_pcm_substream *substream)
205 if (!rtd->dma_desc_array) 206 if (!rtd->dma_desc_array)
206 goto err1; 207 goto err1;
207 208
209 rtd->dma_ch = -1;
208 runtime->private_data = rtd; 210 runtime->private_data = rtd;
209 return 0; 211 return 0;
210 212
diff --git a/sound/core/Kconfig b/sound/core/Kconfig
index c15682a2f9db..475455c76610 100644
--- a/sound/core/Kconfig
+++ b/sound/core/Kconfig
@@ -5,6 +5,7 @@ config SND_TIMER
5config SND_PCM 5config SND_PCM
6 tristate 6 tristate
7 select SND_TIMER 7 select SND_TIMER
8 select GCD
8 9
9config SND_HWDEP 10config SND_HWDEP
10 tristate 11 tristate
diff --git a/sound/core/control.c b/sound/core/control.c
index a8b7fabe645e..439ce64f9d82 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -75,7 +75,7 @@ static int snd_ctl_open(struct inode *inode, struct file *file)
75 ctl->card = card; 75 ctl->card = card;
76 ctl->prefer_pcm_subdevice = -1; 76 ctl->prefer_pcm_subdevice = -1;
77 ctl->prefer_rawmidi_subdevice = -1; 77 ctl->prefer_rawmidi_subdevice = -1;
78 ctl->pid = current->pid; 78 ctl->pid = get_pid(task_pid(current));
79 file->private_data = ctl; 79 file->private_data = ctl;
80 write_lock_irqsave(&card->ctl_files_rwlock, flags); 80 write_lock_irqsave(&card->ctl_files_rwlock, flags);
81 list_add_tail(&ctl->list, &card->ctl_files); 81 list_add_tail(&ctl->list, &card->ctl_files);
@@ -125,6 +125,7 @@ static int snd_ctl_release(struct inode *inode, struct file *file)
125 control->vd[idx].owner = NULL; 125 control->vd[idx].owner = NULL;
126 up_write(&card->controls_rwsem); 126 up_write(&card->controls_rwsem);
127 snd_ctl_empty_read_queue(ctl); 127 snd_ctl_empty_read_queue(ctl);
128 put_pid(ctl->pid);
128 kfree(ctl); 129 kfree(ctl);
129 module_put(card->module); 130 module_put(card->module);
130 snd_card_file_remove(card, file); 131 snd_card_file_remove(card, file);
@@ -236,8 +237,9 @@ struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new *ncontrol,
236 access = ncontrol->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE : 237 access = ncontrol->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE :
237 (ncontrol->access & (SNDRV_CTL_ELEM_ACCESS_READWRITE| 238 (ncontrol->access & (SNDRV_CTL_ELEM_ACCESS_READWRITE|
238 SNDRV_CTL_ELEM_ACCESS_INACTIVE| 239 SNDRV_CTL_ELEM_ACCESS_INACTIVE|
239 SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE| 240 SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE|
240 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK)); 241 SNDRV_CTL_ELEM_ACCESS_TLV_COMMAND|
242 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK));
241 kctl.info = ncontrol->info; 243 kctl.info = ncontrol->info;
242 kctl.get = ncontrol->get; 244 kctl.get = ncontrol->get;
243 kctl.put = ncontrol->put; 245 kctl.put = ncontrol->put;
@@ -672,7 +674,7 @@ static int snd_ctl_elem_info(struct snd_ctl_file *ctl,
672 info->access |= SNDRV_CTL_ELEM_ACCESS_LOCK; 674 info->access |= SNDRV_CTL_ELEM_ACCESS_LOCK;
673 if (vd->owner == ctl) 675 if (vd->owner == ctl)
674 info->access |= SNDRV_CTL_ELEM_ACCESS_OWNER; 676 info->access |= SNDRV_CTL_ELEM_ACCESS_OWNER;
675 info->owner = vd->owner_pid; 677 info->owner = pid_vnr(vd->owner->pid);
676 } else { 678 } else {
677 info->owner = -1; 679 info->owner = -1;
678 } 680 }
@@ -827,7 +829,6 @@ static int snd_ctl_elem_lock(struct snd_ctl_file *file,
827 result = -EBUSY; 829 result = -EBUSY;
828 else { 830 else {
829 vd->owner = file; 831 vd->owner = file;
830 vd->owner_pid = current->pid;
831 result = 0; 832 result = 0;
832 } 833 }
833 } 834 }
@@ -858,7 +859,6 @@ static int snd_ctl_elem_unlock(struct snd_ctl_file *file,
858 result = -EPERM; 859 result = -EPERM;
859 else { 860 else {
860 vd->owner = NULL; 861 vd->owner = NULL;
861 vd->owner_pid = 0;
862 result = 0; 862 result = 0;
863 } 863 }
864 } 864 }
@@ -1100,7 +1100,7 @@ static int snd_ctl_tlv_ioctl(struct snd_ctl_file *file,
1100 1100
1101 if (copy_from_user(&tlv, _tlv, sizeof(tlv))) 1101 if (copy_from_user(&tlv, _tlv, sizeof(tlv)))
1102 return -EFAULT; 1102 return -EFAULT;
1103 if (tlv.length < sizeof(unsigned int) * 3) 1103 if (tlv.length < sizeof(unsigned int) * 2)
1104 return -EINVAL; 1104 return -EINVAL;
1105 down_read(&card->controls_rwsem); 1105 down_read(&card->controls_rwsem);
1106 kctl = snd_ctl_find_numid(card, tlv.numid); 1106 kctl = snd_ctl_find_numid(card, tlv.numid);
@@ -1120,7 +1120,7 @@ static int snd_ctl_tlv_ioctl(struct snd_ctl_file *file,
1120 goto __kctl_end; 1120 goto __kctl_end;
1121 } 1121 }
1122 if (vd->access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) { 1122 if (vd->access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) {
1123 if (file && vd->owner != NULL && vd->owner != file) { 1123 if (vd->owner != NULL && vd->owner != file) {
1124 err = -EPERM; 1124 err = -EPERM;
1125 goto __kctl_end; 1125 goto __kctl_end;
1126 } 1126 }
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 34c7d48f5061..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>
@@ -37,14 +38,22 @@ static unsigned int resolution;
37struct snd_hrtimer { 38struct snd_hrtimer {
38 struct snd_timer *timer; 39 struct snd_timer *timer;
39 struct hrtimer hrt; 40 struct hrtimer hrt;
41 atomic_t running;
40}; 42};
41 43
42static enum hrtimer_restart snd_hrtimer_callback(struct hrtimer *hrt) 44static enum hrtimer_restart snd_hrtimer_callback(struct hrtimer *hrt)
43{ 45{
44 struct snd_hrtimer *stime = container_of(hrt, struct snd_hrtimer, hrt); 46 struct snd_hrtimer *stime = container_of(hrt, struct snd_hrtimer, hrt);
45 struct snd_timer *t = stime->timer; 47 struct snd_timer *t = stime->timer;
48
49 if (!atomic_read(&stime->running))
50 return HRTIMER_NORESTART;
51
46 hrtimer_forward_now(hrt, ns_to_ktime(t->sticks * resolution)); 52 hrtimer_forward_now(hrt, ns_to_ktime(t->sticks * resolution));
47 snd_timer_interrupt(stime->timer, t->sticks); 53 snd_timer_interrupt(stime->timer, t->sticks);
54
55 if (!atomic_read(&stime->running))
56 return HRTIMER_NORESTART;
48 return HRTIMER_RESTART; 57 return HRTIMER_RESTART;
49} 58}
50 59
@@ -58,6 +67,7 @@ static int snd_hrtimer_open(struct snd_timer *t)
58 hrtimer_init(&stime->hrt, CLOCK_MONOTONIC, HRTIMER_MODE_REL); 67 hrtimer_init(&stime->hrt, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
59 stime->timer = t; 68 stime->timer = t;
60 stime->hrt.function = snd_hrtimer_callback; 69 stime->hrt.function = snd_hrtimer_callback;
70 atomic_set(&stime->running, 0);
61 t->private_data = stime; 71 t->private_data = stime;
62 return 0; 72 return 0;
63} 73}
@@ -78,16 +88,18 @@ static int snd_hrtimer_start(struct snd_timer *t)
78{ 88{
79 struct snd_hrtimer *stime = t->private_data; 89 struct snd_hrtimer *stime = t->private_data;
80 90
91 atomic_set(&stime->running, 0);
92 hrtimer_cancel(&stime->hrt);
81 hrtimer_start(&stime->hrt, ns_to_ktime(t->sticks * resolution), 93 hrtimer_start(&stime->hrt, ns_to_ktime(t->sticks * resolution),
82 HRTIMER_MODE_REL); 94 HRTIMER_MODE_REL);
95 atomic_set(&stime->running, 1);
83 return 0; 96 return 0;
84} 97}
85 98
86static int snd_hrtimer_stop(struct snd_timer *t) 99static int snd_hrtimer_stop(struct snd_timer *t)
87{ 100{
88 struct snd_hrtimer *stime = t->private_data; 101 struct snd_hrtimer *stime = t->private_data;
89 102 atomic_set(&stime->running, 0);
90 hrtimer_cancel(&stime->hrt);
91 return 0; 103 return 0;
92} 104}
93 105
diff --git a/sound/core/info.c b/sound/core/info.c
index d749a0d394a7..cc4a53d4b7f8 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>
diff --git a/sound/core/isadma.c b/sound/core/isadma.c
index 79f0f16af339..950e19ba91fc 100644
--- a/sound/core/isadma.c
+++ b/sound/core/isadma.c
@@ -85,16 +85,24 @@ EXPORT_SYMBOL(snd_dma_disable);
85unsigned int snd_dma_pointer(unsigned long dma, unsigned int size) 85unsigned int snd_dma_pointer(unsigned long dma, unsigned int size)
86{ 86{
87 unsigned long flags; 87 unsigned long flags;
88 unsigned int result; 88 unsigned int result, result1;
89 89
90 flags = claim_dma_lock(); 90 flags = claim_dma_lock();
91 clear_dma_ff(dma); 91 clear_dma_ff(dma);
92 if (!isa_dma_bridge_buggy) 92 if (!isa_dma_bridge_buggy)
93 disable_dma(dma); 93 disable_dma(dma);
94 result = get_dma_residue(dma); 94 result = get_dma_residue(dma);
95 /*
96 * HACK - read the counter again and choose higher value in order to
97 * avoid reading during counter lower byte roll over if the
98 * isa_dma_bridge_buggy is set.
99 */
100 result1 = get_dma_residue(dma);
95 if (!isa_dma_bridge_buggy) 101 if (!isa_dma_bridge_buggy)
96 enable_dma(dma); 102 enable_dma(dma);
97 release_dma_lock(flags); 103 release_dma_lock(flags);
104 if (unlikely(result < result1))
105 result = result1;
98#ifdef CONFIG_SND_DEBUG 106#ifdef CONFIG_SND_DEBUG
99 if (result > size) 107 if (result > size)
100 snd_printk(KERN_ERR "pointer (0x%x) for DMA #%ld is greater than transfer size (0x%x)\n", result, dma, size); 108 snd_printk(KERN_ERR "pointer (0x%x) for DMA #%ld is greater than transfer size (0x%x)\n", result, dma, size);
diff --git a/sound/core/jack.c b/sound/core/jack.c
index f705eec7372a..14b8a4ee690d 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 23a032c6d487..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
@@ -101,8 +102,9 @@ EXPORT_SYMBOL_GPL(__snd_printk);
101#ifdef CONFIG_PCI 102#ifdef CONFIG_PCI
102#include <linux/pci.h> 103#include <linux/pci.h>
103/** 104/**
104 * snd_pci_quirk_lookup - look up a PCI SSID quirk list 105 * snd_pci_quirk_lookup_id - look up a PCI SSID quirk list
105 * @pci: pci_dev handle 106 * @vendor: PCI SSV id
107 * @device: PCI SSD id
106 * @list: quirk list, terminated by a null entry 108 * @list: quirk list, terminated by a null entry
107 * 109 *
108 * Look through the given quirk list and finds a matching entry 110 * Look through the given quirk list and finds a matching entry
@@ -112,18 +114,39 @@ EXPORT_SYMBOL_GPL(__snd_printk);
112 * Returns the matched entry pointer, or NULL if nothing matched. 114 * Returns the matched entry pointer, or NULL if nothing matched.
113 */ 115 */
114const struct snd_pci_quirk * 116const struct snd_pci_quirk *
115snd_pci_quirk_lookup(struct pci_dev *pci, const struct snd_pci_quirk *list) 117snd_pci_quirk_lookup_id(u16 vendor, u16 device,
118 const struct snd_pci_quirk *list)
116{ 119{
117 const struct snd_pci_quirk *q; 120 const struct snd_pci_quirk *q;
118 121
119 for (q = list; q->subvendor; q++) { 122 for (q = list; q->subvendor; q++) {
120 if (q->subvendor != pci->subsystem_vendor) 123 if (q->subvendor != vendor)
121 continue; 124 continue;
122 if (!q->subdevice || 125 if (!q->subdevice ||
123 (pci->subsystem_device & q->subdevice_mask) == q->subdevice) 126 (device & q->subdevice_mask) == q->subdevice)
124 return q; 127 return q;
125 } 128 }
126 return NULL; 129 return NULL;
127} 130}
131EXPORT_SYMBOL(snd_pci_quirk_lookup_id);
132
133/**
134 * snd_pci_quirk_lookup - look up a PCI SSID quirk list
135 * @pci: pci_dev handle
136 * @list: quirk list, terminated by a null entry
137 *
138 * Look through the given quirk list and finds a matching entry
139 * with the same PCI SSID. When subdevice is 0, all subdevice
140 * values may match.
141 *
142 * Returns the matched entry pointer, or NULL if nothing matched.
143 */
144const struct snd_pci_quirk *
145snd_pci_quirk_lookup(struct pci_dev *pci, const struct snd_pci_quirk *list)
146{
147 return snd_pci_quirk_lookup_id(pci->subsystem_vendor,
148 pci->subsystem_device,
149 list);
150}
128EXPORT_SYMBOL(snd_pci_quirk_lookup); 151EXPORT_SYMBOL(snd_pci_quirk_lookup);
129#endif 152#endif
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c
index 772423889eb3..54e2eb56e4c2 100644
--- a/sound/core/oss/mixer_oss.c
+++ b/sound/core/oss/mixer_oss.c
@@ -1251,7 +1251,9 @@ static void snd_mixer_oss_build(struct snd_mixer_oss *mixer)
1251 { SOUND_MIXER_SYNTH, "FM", 0 }, /* fallback */ 1251 { SOUND_MIXER_SYNTH, "FM", 0 }, /* fallback */
1252 { SOUND_MIXER_SYNTH, "Music", 0 }, /* fallback */ 1252 { SOUND_MIXER_SYNTH, "Music", 0 }, /* fallback */
1253 { SOUND_MIXER_PCM, "PCM", 0 }, 1253 { SOUND_MIXER_PCM, "PCM", 0 },
1254 { SOUND_MIXER_SPEAKER, "PC Speaker", 0 }, 1254 { SOUND_MIXER_SPEAKER, "Beep", 0 },
1255 { SOUND_MIXER_SPEAKER, "PC Speaker", 0 }, /* fallback */
1256 { SOUND_MIXER_SPEAKER, "Speaker", 0 }, /* fallback */
1255 { SOUND_MIXER_LINE, "Line", 0 }, 1257 { SOUND_MIXER_LINE, "Line", 0 },
1256 { SOUND_MIXER_MIC, "Mic", 0 }, 1258 { SOUND_MIXER_MIC, "Mic", 0 },
1257 { SOUND_MIXER_CD, "CD", 0 }, 1259 { SOUND_MIXER_CD, "CD", 0 },
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index d9c96353121a..82d4e3329b3d 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -632,6 +632,12 @@ static long snd_pcm_alsa_frames(struct snd_pcm_substream *substream, long bytes)
632 return bytes_to_frames(runtime, (buffer_size * bytes) / runtime->oss.buffer_bytes); 632 return bytes_to_frames(runtime, (buffer_size * bytes) / runtime->oss.buffer_bytes);
633} 633}
634 634
635static inline
636snd_pcm_uframes_t get_hw_ptr_period(struct snd_pcm_runtime *runtime)
637{
638 return runtime->hw_ptr_interrupt;
639}
640
635/* define extended formats in the recent OSS versions (if any) */ 641/* define extended formats in the recent OSS versions (if any) */
636/* linear formats */ 642/* linear formats */
637#define AFMT_S32_LE 0x00001000 643#define AFMT_S32_LE 0x00001000
@@ -1102,7 +1108,7 @@ static int snd_pcm_oss_prepare(struct snd_pcm_substream *substream)
1102 return err; 1108 return err;
1103 } 1109 }
1104 runtime->oss.prepare = 0; 1110 runtime->oss.prepare = 0;
1105 runtime->oss.prev_hw_ptr_interrupt = 0; 1111 runtime->oss.prev_hw_ptr_period = 0;
1106 runtime->oss.period_ptr = 0; 1112 runtime->oss.period_ptr = 0;
1107 runtime->oss.buffer_used = 0; 1113 runtime->oss.buffer_used = 0;
1108 1114
@@ -1950,7 +1956,8 @@ static int snd_pcm_oss_get_caps(struct snd_pcm_oss_file *pcm_oss_file)
1950 return result; 1956 return result;
1951} 1957}
1952 1958
1953static void snd_pcm_oss_simulate_fill(struct snd_pcm_substream *substream, snd_pcm_uframes_t hw_ptr) 1959static void snd_pcm_oss_simulate_fill(struct snd_pcm_substream *substream,
1960 snd_pcm_uframes_t hw_ptr)
1954{ 1961{
1955 struct snd_pcm_runtime *runtime = substream->runtime; 1962 struct snd_pcm_runtime *runtime = substream->runtime;
1956 snd_pcm_uframes_t appl_ptr; 1963 snd_pcm_uframes_t appl_ptr;
@@ -1986,7 +1993,8 @@ static int snd_pcm_oss_set_trigger(struct snd_pcm_oss_file *pcm_oss_file, int tr
1986 if (runtime->oss.trigger) 1993 if (runtime->oss.trigger)
1987 goto _skip1; 1994 goto _skip1;
1988 if (atomic_read(&psubstream->mmap_count)) 1995 if (atomic_read(&psubstream->mmap_count))
1989 snd_pcm_oss_simulate_fill(psubstream, runtime->hw_ptr_interrupt); 1996 snd_pcm_oss_simulate_fill(psubstream,
1997 get_hw_ptr_period(runtime));
1990 runtime->oss.trigger = 1; 1998 runtime->oss.trigger = 1;
1991 runtime->start_threshold = 1; 1999 runtime->start_threshold = 1;
1992 cmd = SNDRV_PCM_IOCTL_START; 2000 cmd = SNDRV_PCM_IOCTL_START;
@@ -2105,11 +2113,12 @@ static int snd_pcm_oss_get_ptr(struct snd_pcm_oss_file *pcm_oss_file, int stream
2105 info.ptr = snd_pcm_oss_bytes(substream, runtime->status->hw_ptr % runtime->buffer_size); 2113 info.ptr = snd_pcm_oss_bytes(substream, runtime->status->hw_ptr % runtime->buffer_size);
2106 if (atomic_read(&substream->mmap_count)) { 2114 if (atomic_read(&substream->mmap_count)) {
2107 snd_pcm_sframes_t n; 2115 snd_pcm_sframes_t n;
2108 n = (delay = runtime->hw_ptr_interrupt) - runtime->oss.prev_hw_ptr_interrupt; 2116 delay = get_hw_ptr_period(runtime);
2117 n = delay - runtime->oss.prev_hw_ptr_period;
2109 if (n < 0) 2118 if (n < 0)
2110 n += runtime->boundary; 2119 n += runtime->boundary;
2111 info.blocks = n / runtime->period_size; 2120 info.blocks = n / runtime->period_size;
2112 runtime->oss.prev_hw_ptr_interrupt = delay; 2121 runtime->oss.prev_hw_ptr_period = delay;
2113 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 2122 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
2114 snd_pcm_oss_simulate_fill(substream, delay); 2123 snd_pcm_oss_simulate_fill(substream, delay);
2115 info.bytes = snd_pcm_oss_bytes(substream, runtime->status->hw_ptr) & INT_MAX; 2124 info.bytes = snd_pcm_oss_bytes(substream, runtime->status->hw_ptr) & INT_MAX;
@@ -2673,18 +2682,22 @@ static int snd_pcm_oss_playback_ready(struct snd_pcm_substream *substream)
2673{ 2682{
2674 struct snd_pcm_runtime *runtime = substream->runtime; 2683 struct snd_pcm_runtime *runtime = substream->runtime;
2675 if (atomic_read(&substream->mmap_count)) 2684 if (atomic_read(&substream->mmap_count))
2676 return runtime->oss.prev_hw_ptr_interrupt != runtime->hw_ptr_interrupt; 2685 return runtime->oss.prev_hw_ptr_period !=
2686 get_hw_ptr_period(runtime);
2677 else 2687 else
2678 return snd_pcm_playback_avail(runtime) >= runtime->oss.period_frames; 2688 return snd_pcm_playback_avail(runtime) >=
2689 runtime->oss.period_frames;
2679} 2690}
2680 2691
2681static int snd_pcm_oss_capture_ready(struct snd_pcm_substream *substream) 2692static int snd_pcm_oss_capture_ready(struct snd_pcm_substream *substream)
2682{ 2693{
2683 struct snd_pcm_runtime *runtime = substream->runtime; 2694 struct snd_pcm_runtime *runtime = substream->runtime;
2684 if (atomic_read(&substream->mmap_count)) 2695 if (atomic_read(&substream->mmap_count))
2685 return runtime->oss.prev_hw_ptr_interrupt != runtime->hw_ptr_interrupt; 2696 return runtime->oss.prev_hw_ptr_period !=
2697 get_hw_ptr_period(runtime);
2686 else 2698 else
2687 return snd_pcm_capture_avail(runtime) >= runtime->oss.period_frames; 2699 return snd_pcm_capture_avail(runtime) >=
2700 runtime->oss.period_frames;
2688} 2701}
2689 2702
2690static unsigned int snd_pcm_oss_poll(struct file *file, poll_table * wait) 2703static unsigned int snd_pcm_oss_poll(struct file *file, poll_table * wait)
diff --git a/sound/core/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 c69c60b2a48a..0d428d0896db 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -435,6 +435,7 @@ static void snd_pcm_substream_proc_status_read(struct snd_info_entry *entry,
435 return; 435 return;
436 } 436 }
437 snd_iprintf(buffer, "state: %s\n", snd_pcm_state_name(status.state)); 437 snd_iprintf(buffer, "state: %s\n", snd_pcm_state_name(status.state));
438 snd_iprintf(buffer, "owner_pid : %d\n", pid_vnr(substream->pid));
438 snd_iprintf(buffer, "trigger_time: %ld.%09ld\n", 439 snd_iprintf(buffer, "trigger_time: %ld.%09ld\n",
439 status.trigger_tstamp.tv_sec, status.trigger_tstamp.tv_nsec); 440 status.trigger_tstamp.tv_sec, status.trigger_tstamp.tv_nsec);
440 snd_iprintf(buffer, "tstamp : %ld.%09ld\n", 441 snd_iprintf(buffer, "tstamp : %ld.%09ld\n",
@@ -809,7 +810,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
809 card = pcm->card; 810 card = pcm->card;
810 read_lock(&card->ctl_files_rwlock); 811 read_lock(&card->ctl_files_rwlock);
811 list_for_each_entry(kctl, &card->ctl_files, list) { 812 list_for_each_entry(kctl, &card->ctl_files, list) {
812 if (kctl->pid == current->pid) { 813 if (kctl->pid == task_pid(current)) {
813 prefer_subdevice = kctl->prefer_pcm_subdevice; 814 prefer_subdevice = kctl->prefer_pcm_subdevice;
814 if (prefer_subdevice != -1) 815 if (prefer_subdevice != -1)
815 break; 816 break;
@@ -893,6 +894,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
893 memset((void*)runtime->control, 0, size); 894 memset((void*)runtime->control, 0, size);
894 895
895 init_waitqueue_head(&runtime->sleep); 896 init_waitqueue_head(&runtime->sleep);
897 init_waitqueue_head(&runtime->tsleep);
896 898
897 runtime->status->state = SNDRV_PCM_STATE_OPEN; 899 runtime->status->state = SNDRV_PCM_STATE_OPEN;
898 900
@@ -900,6 +902,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
900 substream->private_data = pcm->private_data; 902 substream->private_data = pcm->private_data;
901 substream->ref_count = 1; 903 substream->ref_count = 1;
902 substream->f_flags = file->f_flags; 904 substream->f_flags = file->f_flags;
905 substream->pid = get_pid(task_pid(current));
903 pstr->substream_opened++; 906 pstr->substream_opened++;
904 *rsubstream = substream; 907 *rsubstream = substream;
905 return 0; 908 return 0;
@@ -919,8 +922,14 @@ void snd_pcm_detach_substream(struct snd_pcm_substream *substream)
919 snd_free_pages((void*)runtime->control, 922 snd_free_pages((void*)runtime->control,
920 PAGE_ALIGN(sizeof(struct snd_pcm_mmap_control))); 923 PAGE_ALIGN(sizeof(struct snd_pcm_mmap_control)));
921 kfree(runtime->hw_constraints.rules); 924 kfree(runtime->hw_constraints.rules);
925#ifdef CONFIG_SND_PCM_XRUN_DEBUG
926 if (runtime->hwptr_log)
927 kfree(runtime->hwptr_log);
928#endif
922 kfree(runtime); 929 kfree(runtime);
923 substream->runtime = NULL; 930 substream->runtime = NULL;
931 put_pid(substream->pid);
932 substream->pid = NULL;
924 substream->pstr->substream_opened--; 933 substream->pstr->substream_opened--;
925} 934}
926 935
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 30f410832a25..a2ff86189d2a 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -126,17 +126,6 @@ void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_ufram
126 } 126 }
127} 127}
128 128
129#ifdef CONFIG_SND_PCM_XRUN_DEBUG
130#define xrun_debug(substream, mask) ((substream)->pstr->xrun_debug & (mask))
131#else
132#define xrun_debug(substream, mask) 0
133#endif
134
135#define dump_stack_on_xrun(substream) do { \
136 if (xrun_debug(substream, 2)) \
137 dump_stack(); \
138 } while (0)
139
140static void pcm_debug_name(struct snd_pcm_substream *substream, 129static void pcm_debug_name(struct snd_pcm_substream *substream,
141 char *name, size_t len) 130 char *name, size_t len)
142{ 131{
@@ -147,6 +136,27 @@ static void pcm_debug_name(struct snd_pcm_substream *substream,
147 substream->number); 136 substream->number);
148} 137}
149 138
139#define XRUN_DEBUG_BASIC (1<<0)
140#define XRUN_DEBUG_STACK (1<<1) /* dump also stack */
141#define XRUN_DEBUG_JIFFIESCHECK (1<<2) /* do jiffies check */
142#define XRUN_DEBUG_PERIODUPDATE (1<<3) /* full period update info */
143#define XRUN_DEBUG_HWPTRUPDATE (1<<4) /* full hwptr update info */
144#define XRUN_DEBUG_LOG (1<<5) /* show last 10 positions on err */
145#define XRUN_DEBUG_LOGONCE (1<<6) /* do above only once */
146
147#ifdef CONFIG_SND_PCM_XRUN_DEBUG
148
149#define xrun_debug(substream, mask) \
150 ((substream)->pstr->xrun_debug & (mask))
151#else
152#define xrun_debug(substream, mask) 0
153#endif
154
155#define dump_stack_on_xrun(substream) do { \
156 if (xrun_debug(substream, XRUN_DEBUG_STACK)) \
157 dump_stack(); \
158 } while (0)
159
150static void xrun(struct snd_pcm_substream *substream) 160static void xrun(struct snd_pcm_substream *substream)
151{ 161{
152 struct snd_pcm_runtime *runtime = substream->runtime; 162 struct snd_pcm_runtime *runtime = substream->runtime;
@@ -154,7 +164,7 @@ static void xrun(struct snd_pcm_substream *substream)
154 if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE) 164 if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE)
155 snd_pcm_gettime(runtime, (struct timespec *)&runtime->status->tstamp); 165 snd_pcm_gettime(runtime, (struct timespec *)&runtime->status->tstamp);
156 snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); 166 snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
157 if (xrun_debug(substream, 1)) { 167 if (xrun_debug(substream, XRUN_DEBUG_BASIC)) {
158 char name[16]; 168 char name[16];
159 pcm_debug_name(substream, name, sizeof(name)); 169 pcm_debug_name(substream, name, sizeof(name));
160 snd_printd(KERN_DEBUG "XRUN: %s\n", name); 170 snd_printd(KERN_DEBUG "XRUN: %s\n", name);
@@ -162,32 +172,101 @@ static void xrun(struct snd_pcm_substream *substream)
162 } 172 }
163} 173}
164 174
165static snd_pcm_uframes_t 175#ifdef CONFIG_SND_PCM_XRUN_DEBUG
166snd_pcm_update_hw_ptr_pos(struct snd_pcm_substream *substream, 176#define hw_ptr_error(substream, fmt, args...) \
167 struct snd_pcm_runtime *runtime) 177 do { \
168{ 178 if (xrun_debug(substream, XRUN_DEBUG_BASIC)) { \
179 xrun_log_show(substream); \
180 if (printk_ratelimit()) { \
181 snd_printd("PCM: " fmt, ##args); \
182 } \
183 dump_stack_on_xrun(substream); \
184 } \
185 } while (0)
186
187#define XRUN_LOG_CNT 10
188
189struct hwptr_log_entry {
190 unsigned long jiffies;
169 snd_pcm_uframes_t pos; 191 snd_pcm_uframes_t pos;
192 snd_pcm_uframes_t period_size;
193 snd_pcm_uframes_t buffer_size;
194 snd_pcm_uframes_t old_hw_ptr;
195 snd_pcm_uframes_t hw_ptr_base;
196};
170 197
171 pos = substream->ops->pointer(substream); 198struct snd_pcm_hwptr_log {
172 if (pos == SNDRV_PCM_POS_XRUN) 199 unsigned int idx;
173 return pos; /* XRUN */ 200 unsigned int hit: 1;
174 if (pos >= runtime->buffer_size) { 201 struct hwptr_log_entry entries[XRUN_LOG_CNT];
175 if (printk_ratelimit()) { 202};
176 char name[16]; 203
177 pcm_debug_name(substream, name, sizeof(name)); 204static void xrun_log(struct snd_pcm_substream *substream,
178 snd_printd(KERN_ERR "BUG: %s, pos = 0x%lx, " 205 snd_pcm_uframes_t pos)
179 "buffer size = 0x%lx, period size = 0x%lx\n", 206{
180 name, pos, runtime->buffer_size, 207 struct snd_pcm_runtime *runtime = substream->runtime;
181 runtime->period_size); 208 struct snd_pcm_hwptr_log *log = runtime->hwptr_log;
182 } 209 struct hwptr_log_entry *entry;
183 pos = 0; 210
211 if (log == NULL) {
212 log = kzalloc(sizeof(*log), GFP_ATOMIC);
213 if (log == NULL)
214 return;
215 runtime->hwptr_log = log;
216 } else {
217 if (xrun_debug(substream, XRUN_DEBUG_LOGONCE) && log->hit)
218 return;
184 } 219 }
185 pos -= pos % runtime->min_align; 220 entry = &log->entries[log->idx];
186 return pos; 221 entry->jiffies = jiffies;
222 entry->pos = pos;
223 entry->period_size = runtime->period_size;
224 entry->buffer_size = runtime->buffer_size;;
225 entry->old_hw_ptr = runtime->status->hw_ptr;
226 entry->hw_ptr_base = runtime->hw_ptr_base;
227 log->idx = (log->idx + 1) % XRUN_LOG_CNT;
187} 228}
188 229
189static int snd_pcm_update_hw_ptr_post(struct snd_pcm_substream *substream, 230static void xrun_log_show(struct snd_pcm_substream *substream)
190 struct snd_pcm_runtime *runtime) 231{
232 struct snd_pcm_hwptr_log *log = substream->runtime->hwptr_log;
233 struct hwptr_log_entry *entry;
234 char name[16];
235 unsigned int idx;
236 int cnt;
237
238 if (log == NULL)
239 return;
240 if (xrun_debug(substream, XRUN_DEBUG_LOGONCE) && log->hit)
241 return;
242 pcm_debug_name(substream, name, sizeof(name));
243 for (cnt = 0, idx = log->idx; cnt < XRUN_LOG_CNT; cnt++) {
244 entry = &log->entries[idx];
245 if (entry->period_size == 0)
246 break;
247 snd_printd("hwptr log: %s: j=%lu, pos=%ld/%ld/%ld, "
248 "hwptr=%ld/%ld\n",
249 name, entry->jiffies, (unsigned long)entry->pos,
250 (unsigned long)entry->period_size,
251 (unsigned long)entry->buffer_size,
252 (unsigned long)entry->old_hw_ptr,
253 (unsigned long)entry->hw_ptr_base);
254 idx++;
255 idx %= XRUN_LOG_CNT;
256 }
257 log->hit = 1;
258}
259
260#else /* ! CONFIG_SND_PCM_XRUN_DEBUG */
261
262#define hw_ptr_error(substream, fmt, args...) do { } while (0)
263#define xrun_log(substream, pos) do { } while (0)
264#define xrun_log_show(substream) do { } while (0)
265
266#endif
267
268int snd_pcm_update_state(struct snd_pcm_substream *substream,
269 struct snd_pcm_runtime *runtime)
191{ 270{
192 snd_pcm_uframes_t avail; 271 snd_pcm_uframes_t avail;
193 272
@@ -209,88 +288,94 @@ static int snd_pcm_update_hw_ptr_post(struct snd_pcm_substream *substream,
209 } 288 }
210 } 289 }
211 if (avail >= runtime->control->avail_min) 290 if (avail >= runtime->control->avail_min)
212 wake_up(&runtime->sleep); 291 wake_up(runtime->twake ? &runtime->tsleep : &runtime->sleep);
213 return 0; 292 return 0;
214} 293}
215 294
216#define hw_ptr_error(substream, fmt, args...) \ 295static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
217 do { \ 296 unsigned int in_interrupt)
218 if (xrun_debug(substream, 1)) { \
219 if (printk_ratelimit()) { \
220 snd_printd("PCM: " fmt, ##args); \
221 } \
222 dump_stack_on_xrun(substream); \
223 } \
224 } while (0)
225
226static int snd_pcm_update_hw_ptr_interrupt(struct snd_pcm_substream *substream)
227{ 297{
228 struct snd_pcm_runtime *runtime = substream->runtime; 298 struct snd_pcm_runtime *runtime = substream->runtime;
229 snd_pcm_uframes_t pos; 299 snd_pcm_uframes_t pos;
230 snd_pcm_uframes_t old_hw_ptr, new_hw_ptr, hw_ptr_interrupt, hw_base; 300 snd_pcm_uframes_t old_hw_ptr, new_hw_ptr, hw_base;
231 snd_pcm_sframes_t hdelta, delta; 301 snd_pcm_sframes_t hdelta, delta;
232 unsigned long jdelta; 302 unsigned long jdelta;
233 303
234 old_hw_ptr = runtime->status->hw_ptr; 304 old_hw_ptr = runtime->status->hw_ptr;
235 pos = snd_pcm_update_hw_ptr_pos(substream, runtime); 305 pos = substream->ops->pointer(substream);
236 if (pos == SNDRV_PCM_POS_XRUN) { 306 if (pos == SNDRV_PCM_POS_XRUN) {
237 xrun(substream); 307 xrun(substream);
238 return -EPIPE; 308 return -EPIPE;
239 } 309 }
240 if (xrun_debug(substream, 8)) { 310 if (pos >= runtime->buffer_size) {
241 char name[16]; 311 if (printk_ratelimit()) {
242 pcm_debug_name(substream, name, sizeof(name)); 312 char name[16];
243 snd_printd("period_update: %s: pos=0x%x/0x%x/0x%x, " 313 pcm_debug_name(substream, name, sizeof(name));
244 "hwptr=0x%lx, hw_base=0x%lx, hw_intr=0x%lx\n", 314 xrun_log_show(substream);
245 name, (unsigned int)pos, 315 snd_printd(KERN_ERR "BUG: %s, pos = %ld, "
246 (unsigned int)runtime->period_size, 316 "buffer size = %ld, period size = %ld\n",
247 (unsigned int)runtime->buffer_size, 317 name, pos, runtime->buffer_size,
248 (unsigned long)old_hw_ptr, 318 runtime->period_size);
249 (unsigned long)runtime->hw_ptr_base, 319 }
250 (unsigned long)runtime->hw_ptr_interrupt); 320 pos = 0;
251 } 321 }
322 pos -= pos % runtime->min_align;
323 if (xrun_debug(substream, XRUN_DEBUG_LOG))
324 xrun_log(substream, pos);
252 hw_base = runtime->hw_ptr_base; 325 hw_base = runtime->hw_ptr_base;
253 new_hw_ptr = hw_base + pos; 326 new_hw_ptr = hw_base + pos;
254 hw_ptr_interrupt = runtime->hw_ptr_interrupt + runtime->period_size; 327 if (in_interrupt) {
255 delta = new_hw_ptr - hw_ptr_interrupt; 328 /* we know that one period was processed */
256 if (hw_ptr_interrupt >= runtime->boundary) { 329 /* delta = "expected next hw_ptr" for in_interrupt != 0 */
257 hw_ptr_interrupt -= runtime->boundary; 330 delta = runtime->hw_ptr_interrupt + runtime->period_size;
258 if (hw_base < runtime->boundary / 2) 331 if (delta > new_hw_ptr) {
259 /* hw_base was already lapped; recalc delta */
260 delta = new_hw_ptr - hw_ptr_interrupt;
261 }
262 if (delta < 0) {
263 if (runtime->periods == 1 || new_hw_ptr < old_hw_ptr)
264 delta += runtime->buffer_size;
265 if (delta < 0) {
266 hw_ptr_error(substream,
267 "Unexpected hw_pointer value "
268 "(stream=%i, pos=%ld, intr_ptr=%ld)\n",
269 substream->stream, (long)pos,
270 (long)hw_ptr_interrupt);
271#if 1
272 /* simply skipping the hwptr update seems more
273 * robust in some cases, e.g. on VMware with
274 * inaccurate timer source
275 */
276 return 0; /* skip this update */
277#else
278 /* rebase to interrupt position */
279 hw_base = new_hw_ptr = hw_ptr_interrupt;
280 /* align hw_base to buffer_size */
281 hw_base -= hw_base % runtime->buffer_size;
282 delta = 0;
283#endif
284 } else {
285 hw_base += runtime->buffer_size; 332 hw_base += runtime->buffer_size;
286 if (hw_base >= runtime->boundary) 333 if (hw_base >= runtime->boundary)
287 hw_base = 0; 334 hw_base = 0;
288 new_hw_ptr = hw_base + pos; 335 new_hw_ptr = hw_base + pos;
336 goto __delta;
289 } 337 }
290 } 338 }
339 /* new_hw_ptr might be lower than old_hw_ptr in case when */
340 /* pointer crosses the end of the ring buffer */
341 if (new_hw_ptr < old_hw_ptr) {
342 hw_base += runtime->buffer_size;
343 if (hw_base >= runtime->boundary)
344 hw_base = 0;
345 new_hw_ptr = hw_base + pos;
346 }
347 __delta:
348 delta = (new_hw_ptr - old_hw_ptr) % runtime->boundary;
349 if (xrun_debug(substream, in_interrupt ?
350 XRUN_DEBUG_PERIODUPDATE : XRUN_DEBUG_HWPTRUPDATE)) {
351 char name[16];
352 pcm_debug_name(substream, name, sizeof(name));
353 snd_printd("%s_update: %s: pos=%u/%u/%u, "
354 "hwptr=%ld/%ld/%ld/%ld\n",
355 in_interrupt ? "period" : "hwptr",
356 name,
357 (unsigned int)pos,
358 (unsigned int)runtime->period_size,
359 (unsigned int)runtime->buffer_size,
360 (unsigned long)delta,
361 (unsigned long)old_hw_ptr,
362 (unsigned long)new_hw_ptr,
363 (unsigned long)runtime->hw_ptr_base);
364 }
365 /* something must be really wrong */
366 if (delta >= runtime->buffer_size + runtime->period_size) {
367 hw_ptr_error(substream,
368 "Unexpected hw_pointer value %s"
369 "(stream=%i, pos=%ld, new_hw_ptr=%ld, "
370 "old_hw_ptr=%ld)\n",
371 in_interrupt ? "[Q] " : "[P]",
372 substream->stream, (long)pos,
373 (long)new_hw_ptr, (long)old_hw_ptr);
374 return 0;
375 }
291 376
292 /* Do jiffies check only in xrun_debug mode */ 377 /* Do jiffies check only in xrun_debug mode */
293 if (!xrun_debug(substream, 4)) 378 if (!xrun_debug(substream, XRUN_DEBUG_JIFFIESCHECK))
294 goto no_jiffies_check; 379 goto no_jiffies_check;
295 380
296 /* Skip the jiffies check for hardwares with BATCH flag. 381 /* Skip the jiffies check for hardwares with BATCH flag.
@@ -299,7 +384,7 @@ static int snd_pcm_update_hw_ptr_interrupt(struct snd_pcm_substream *substream)
299 */ 384 */
300 if (runtime->hw.info & SNDRV_PCM_INFO_BATCH) 385 if (runtime->hw.info & SNDRV_PCM_INFO_BATCH)
301 goto no_jiffies_check; 386 goto no_jiffies_check;
302 hdelta = new_hw_ptr - old_hw_ptr; 387 hdelta = delta;
303 if (hdelta < runtime->delay) 388 if (hdelta < runtime->delay)
304 goto no_jiffies_check; 389 goto no_jiffies_check;
305 hdelta -= runtime->delay; 390 hdelta -= runtime->delay;
@@ -308,130 +393,68 @@ static int snd_pcm_update_hw_ptr_interrupt(struct snd_pcm_substream *substream)
308 delta = jdelta / 393 delta = jdelta /
309 (((runtime->period_size * HZ) / runtime->rate) 394 (((runtime->period_size * HZ) / runtime->rate)
310 + HZ/100); 395 + HZ/100);
396 /* move new_hw_ptr according jiffies not pos variable */
397 new_hw_ptr = old_hw_ptr;
398 hw_base = delta;
399 /* use loop to avoid checks for delta overflows */
400 /* the delta value is small or zero in most cases */
401 while (delta > 0) {
402 new_hw_ptr += runtime->period_size;
403 if (new_hw_ptr >= runtime->boundary)
404 new_hw_ptr -= runtime->boundary;
405 delta--;
406 }
407 /* align hw_base to buffer_size */
311 hw_ptr_error(substream, 408 hw_ptr_error(substream,
312 "hw_ptr skipping! [Q] " 409 "hw_ptr skipping! %s"
313 "(pos=%ld, delta=%ld, period=%ld, " 410 "(pos=%ld, delta=%ld, period=%ld, "
314 "jdelta=%lu/%lu/%lu)\n", 411 "jdelta=%lu/%lu/%lu, hw_ptr=%ld/%ld)\n",
412 in_interrupt ? "[Q] " : "",
315 (long)pos, (long)hdelta, 413 (long)pos, (long)hdelta,
316 (long)runtime->period_size, jdelta, 414 (long)runtime->period_size, jdelta,
317 ((hdelta * HZ) / runtime->rate), delta); 415 ((hdelta * HZ) / runtime->rate), hw_base,
318 hw_ptr_interrupt = runtime->hw_ptr_interrupt + 416 (unsigned long)old_hw_ptr,
319 runtime->period_size * delta; 417 (unsigned long)new_hw_ptr);
320 if (hw_ptr_interrupt >= runtime->boundary) 418 /* reset values to proper state */
321 hw_ptr_interrupt -= runtime->boundary;
322 /* rebase to interrupt position */
323 hw_base = new_hw_ptr = hw_ptr_interrupt;
324 /* align hw_base to buffer_size */
325 hw_base -= hw_base % runtime->buffer_size;
326 delta = 0; 419 delta = 0;
420 hw_base = new_hw_ptr - (new_hw_ptr % runtime->buffer_size);
327 } 421 }
328 no_jiffies_check: 422 no_jiffies_check:
329 if (delta > runtime->period_size + runtime->period_size / 2) { 423 if (delta > runtime->period_size + runtime->period_size / 2) {
330 hw_ptr_error(substream, 424 hw_ptr_error(substream,
331 "Lost interrupts? " 425 "Lost interrupts? %s"
332 "(stream=%i, delta=%ld, intr_ptr=%ld)\n", 426 "(stream=%i, delta=%ld, new_hw_ptr=%ld, "
427 "old_hw_ptr=%ld)\n",
428 in_interrupt ? "[Q] " : "",
333 substream->stream, (long)delta, 429 substream->stream, (long)delta,
334 (long)hw_ptr_interrupt); 430 (long)new_hw_ptr,
335 /* rebase hw_ptr_interrupt */ 431 (long)old_hw_ptr);
336 hw_ptr_interrupt =
337 new_hw_ptr - new_hw_ptr % runtime->period_size;
338 } 432 }
339 runtime->hw_ptr_interrupt = hw_ptr_interrupt; 433
434 if (runtime->status->hw_ptr == new_hw_ptr)
435 return 0;
340 436
341 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && 437 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
342 runtime->silence_size > 0) 438 runtime->silence_size > 0)
343 snd_pcm_playback_silence(substream, new_hw_ptr); 439 snd_pcm_playback_silence(substream, new_hw_ptr);
344 440
345 if (runtime->status->hw_ptr == new_hw_ptr) 441 if (in_interrupt) {
346 return 0; 442 runtime->hw_ptr_interrupt = new_hw_ptr -
347 443 (new_hw_ptr % runtime->period_size);
444 }
348 runtime->hw_ptr_base = hw_base; 445 runtime->hw_ptr_base = hw_base;
349 runtime->status->hw_ptr = new_hw_ptr; 446 runtime->status->hw_ptr = new_hw_ptr;
350 runtime->hw_ptr_jiffies = jiffies; 447 runtime->hw_ptr_jiffies = jiffies;
351 if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE) 448 if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE)
352 snd_pcm_gettime(runtime, (struct timespec *)&runtime->status->tstamp); 449 snd_pcm_gettime(runtime, (struct timespec *)&runtime->status->tstamp);
353 450
354 return snd_pcm_update_hw_ptr_post(substream, runtime); 451 return snd_pcm_update_state(substream, runtime);
355} 452}
356 453
357/* CAUTION: call it with irq disabled */ 454/* CAUTION: call it with irq disabled */
358int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream) 455int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream)
359{ 456{
360 struct snd_pcm_runtime *runtime = substream->runtime; 457 return snd_pcm_update_hw_ptr0(substream, 0);
361 snd_pcm_uframes_t pos;
362 snd_pcm_uframes_t old_hw_ptr, new_hw_ptr, hw_base;
363 snd_pcm_sframes_t delta;
364 unsigned long jdelta;
365
366 old_hw_ptr = runtime->status->hw_ptr;
367 pos = snd_pcm_update_hw_ptr_pos(substream, runtime);
368 if (pos == SNDRV_PCM_POS_XRUN) {
369 xrun(substream);
370 return -EPIPE;
371 }
372 if (xrun_debug(substream, 16)) {
373 char name[16];
374 pcm_debug_name(substream, name, sizeof(name));
375 snd_printd("hw_update: %s: pos=0x%x/0x%x/0x%x, "
376 "hwptr=0x%lx, hw_base=0x%lx, hw_intr=0x%lx\n",
377 name, (unsigned int)pos,
378 (unsigned int)runtime->period_size,
379 (unsigned int)runtime->buffer_size,
380 (unsigned long)old_hw_ptr,
381 (unsigned long)runtime->hw_ptr_base,
382 (unsigned long)runtime->hw_ptr_interrupt);
383 }
384
385 hw_base = runtime->hw_ptr_base;
386 new_hw_ptr = hw_base + pos;
387
388 delta = new_hw_ptr - old_hw_ptr;
389 jdelta = jiffies - runtime->hw_ptr_jiffies;
390 if (delta < 0) {
391 delta += runtime->buffer_size;
392 if (delta < 0) {
393 hw_ptr_error(substream,
394 "Unexpected hw_pointer value [2] "
395 "(stream=%i, pos=%ld, old_ptr=%ld, jdelta=%li)\n",
396 substream->stream, (long)pos,
397 (long)old_hw_ptr, jdelta);
398 return 0;
399 }
400 hw_base += runtime->buffer_size;
401 if (hw_base >= runtime->boundary)
402 hw_base = 0;
403 new_hw_ptr = hw_base + pos;
404 }
405 /* Do jiffies check only in xrun_debug mode */
406 if (!xrun_debug(substream, 4))
407 goto no_jiffies_check;
408 if (delta < runtime->delay)
409 goto no_jiffies_check;
410 delta -= runtime->delay;
411 if (((delta * HZ) / runtime->rate) > jdelta + HZ/100) {
412 hw_ptr_error(substream,
413 "hw_ptr skipping! "
414 "(pos=%ld, delta=%ld, period=%ld, jdelta=%lu/%lu)\n",
415 (long)pos, (long)delta,
416 (long)runtime->period_size, jdelta,
417 ((delta * HZ) / runtime->rate));
418 return 0;
419 }
420 no_jiffies_check:
421 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
422 runtime->silence_size > 0)
423 snd_pcm_playback_silence(substream, new_hw_ptr);
424
425 if (runtime->status->hw_ptr == new_hw_ptr)
426 return 0;
427
428 runtime->hw_ptr_base = hw_base;
429 runtime->status->hw_ptr = new_hw_ptr;
430 runtime->hw_ptr_jiffies = jiffies;
431 if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE)
432 snd_pcm_gettime(runtime, (struct timespec *)&runtime->status->tstamp);
433
434 return snd_pcm_update_hw_ptr_post(substream, runtime);
435} 458}
436 459
437/** 460/**
@@ -745,10 +768,13 @@ int snd_interval_ratnum(struct snd_interval *i,
745 unsigned int rats_count, struct snd_ratnum *rats, 768 unsigned int rats_count, struct snd_ratnum *rats,
746 unsigned int *nump, unsigned int *denp) 769 unsigned int *nump, unsigned int *denp)
747{ 770{
748 unsigned int best_num, best_diff, best_den; 771 unsigned int best_num, best_den;
772 int best_diff;
749 unsigned int k; 773 unsigned int k;
750 struct snd_interval t; 774 struct snd_interval t;
751 int err; 775 int err;
776 unsigned int result_num, result_den;
777 int result_diff;
752 778
753 best_num = best_den = best_diff = 0; 779 best_num = best_den = best_diff = 0;
754 for (k = 0; k < rats_count; ++k) { 780 for (k = 0; k < rats_count; ++k) {
@@ -758,7 +784,7 @@ int snd_interval_ratnum(struct snd_interval *i,
758 int diff; 784 int diff;
759 if (q == 0) 785 if (q == 0)
760 q = 1; 786 q = 1;
761 den = div_down(num, q); 787 den = div_up(num, q);
762 if (den < rats[k].den_min) 788 if (den < rats[k].den_min)
763 continue; 789 continue;
764 if (den > rats[k].den_max) 790 if (den > rats[k].den_max)
@@ -770,6 +796,8 @@ int snd_interval_ratnum(struct snd_interval *i,
770 den -= r; 796 den -= r;
771 } 797 }
772 diff = num - q * den; 798 diff = num - q * den;
799 if (diff < 0)
800 diff = -diff;
773 if (best_num == 0 || 801 if (best_num == 0 ||
774 diff * best_den < best_diff * den) { 802 diff * best_den < best_diff * den) {
775 best_diff = diff; 803 best_diff = diff;
@@ -784,6 +812,9 @@ int snd_interval_ratnum(struct snd_interval *i,
784 t.min = div_down(best_num, best_den); 812 t.min = div_down(best_num, best_den);
785 t.openmin = !!(best_num % best_den); 813 t.openmin = !!(best_num % best_den);
786 814
815 result_num = best_num;
816 result_diff = best_diff;
817 result_den = best_den;
787 best_num = best_den = best_diff = 0; 818 best_num = best_den = best_diff = 0;
788 for (k = 0; k < rats_count; ++k) { 819 for (k = 0; k < rats_count; ++k) {
789 unsigned int num = rats[k].num; 820 unsigned int num = rats[k].num;
@@ -794,7 +825,7 @@ int snd_interval_ratnum(struct snd_interval *i,
794 i->empty = 1; 825 i->empty = 1;
795 return -EINVAL; 826 return -EINVAL;
796 } 827 }
797 den = div_up(num, q); 828 den = div_down(num, q);
798 if (den > rats[k].den_max) 829 if (den > rats[k].den_max)
799 continue; 830 continue;
800 if (den < rats[k].den_min) 831 if (den < rats[k].den_min)
@@ -806,6 +837,8 @@ int snd_interval_ratnum(struct snd_interval *i,
806 den += rats[k].den_step - r; 837 den += rats[k].den_step - r;
807 } 838 }
808 diff = q * den - num; 839 diff = q * den - num;
840 if (diff < 0)
841 diff = -diff;
809 if (best_num == 0 || 842 if (best_num == 0 ||
810 diff * best_den < best_diff * den) { 843 diff * best_den < best_diff * den) {
811 best_diff = diff; 844 best_diff = diff;
@@ -825,10 +858,14 @@ int snd_interval_ratnum(struct snd_interval *i,
825 return err; 858 return err;
826 859
827 if (snd_interval_single(i)) { 860 if (snd_interval_single(i)) {
861 if (best_diff * result_den < result_diff * best_den) {
862 result_num = best_num;
863 result_den = best_den;
864 }
828 if (nump) 865 if (nump)
829 *nump = best_num; 866 *nump = result_num;
830 if (denp) 867 if (denp)
831 *denp = best_den; 868 *denp = result_den;
832 } 869 }
833 return err; 870 return err;
834} 871}
@@ -1643,7 +1680,7 @@ void snd_pcm_period_elapsed(struct snd_pcm_substream *substream)
1643 1680
1644 snd_pcm_stream_lock_irqsave(substream, flags); 1681 snd_pcm_stream_lock_irqsave(substream, flags);
1645 if (!snd_pcm_running(substream) || 1682 if (!snd_pcm_running(substream) ||
1646 snd_pcm_update_hw_ptr_interrupt(substream) < 0) 1683 snd_pcm_update_hw_ptr0(substream, 1) < 0)
1647 goto _end; 1684 goto _end;
1648 1685
1649 if (substream->timer_running) 1686 if (substream->timer_running)
@@ -1674,7 +1711,7 @@ static int wait_for_avail_min(struct snd_pcm_substream *substream,
1674 long tout; 1711 long tout;
1675 1712
1676 init_waitqueue_entry(&wait, current); 1713 init_waitqueue_entry(&wait, current);
1677 add_wait_queue(&runtime->sleep, &wait); 1714 add_wait_queue(&runtime->tsleep, &wait);
1678 for (;;) { 1715 for (;;) {
1679 if (signal_pending(current)) { 1716 if (signal_pending(current)) {
1680 err = -ERESTARTSYS; 1717 err = -ERESTARTSYS;
@@ -1717,7 +1754,7 @@ static int wait_for_avail_min(struct snd_pcm_substream *substream,
1717 break; 1754 break;
1718 } 1755 }
1719 _endloop: 1756 _endloop:
1720 remove_wait_queue(&runtime->sleep, &wait); 1757 remove_wait_queue(&runtime->tsleep, &wait);
1721 *availp = avail; 1758 *availp = avail;
1722 return err; 1759 return err;
1723} 1760}
@@ -1776,6 +1813,7 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream,
1776 goto _end_unlock; 1813 goto _end_unlock;
1777 } 1814 }
1778 1815
1816 runtime->twake = 1;
1779 while (size > 0) { 1817 while (size > 0) {
1780 snd_pcm_uframes_t frames, appl_ptr, appl_ofs; 1818 snd_pcm_uframes_t frames, appl_ptr, appl_ofs;
1781 snd_pcm_uframes_t avail; 1819 snd_pcm_uframes_t avail;
@@ -1797,15 +1835,17 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream,
1797 if (frames > cont) 1835 if (frames > cont)
1798 frames = cont; 1836 frames = cont;
1799 if (snd_BUG_ON(!frames)) { 1837 if (snd_BUG_ON(!frames)) {
1838 runtime->twake = 0;
1800 snd_pcm_stream_unlock_irq(substream); 1839 snd_pcm_stream_unlock_irq(substream);
1801 return -EINVAL; 1840 return -EINVAL;
1802 } 1841 }
1803 appl_ptr = runtime->control->appl_ptr; 1842 appl_ptr = runtime->control->appl_ptr;
1804 appl_ofs = appl_ptr % runtime->buffer_size; 1843 appl_ofs = appl_ptr % runtime->buffer_size;
1805 snd_pcm_stream_unlock_irq(substream); 1844 snd_pcm_stream_unlock_irq(substream);
1806 if ((err = transfer(substream, appl_ofs, data, offset, frames)) < 0) 1845 err = transfer(substream, appl_ofs, data, offset, frames);
1807 goto _end;
1808 snd_pcm_stream_lock_irq(substream); 1846 snd_pcm_stream_lock_irq(substream);
1847 if (err < 0)
1848 goto _end_unlock;
1809 switch (runtime->status->state) { 1849 switch (runtime->status->state) {
1810 case SNDRV_PCM_STATE_XRUN: 1850 case SNDRV_PCM_STATE_XRUN:
1811 err = -EPIPE; 1851 err = -EPIPE;
@@ -1834,8 +1874,10 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream,
1834 } 1874 }
1835 } 1875 }
1836 _end_unlock: 1876 _end_unlock:
1877 runtime->twake = 0;
1878 if (xfer > 0 && err >= 0)
1879 snd_pcm_update_state(substream, runtime);
1837 snd_pcm_stream_unlock_irq(substream); 1880 snd_pcm_stream_unlock_irq(substream);
1838 _end:
1839 return xfer > 0 ? (snd_pcm_sframes_t)xfer : err; 1881 return xfer > 0 ? (snd_pcm_sframes_t)xfer : err;
1840} 1882}
1841 1883
@@ -1993,6 +2035,7 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream,
1993 goto _end_unlock; 2035 goto _end_unlock;
1994 } 2036 }
1995 2037
2038 runtime->twake = 1;
1996 while (size > 0) { 2039 while (size > 0) {
1997 snd_pcm_uframes_t frames, appl_ptr, appl_ofs; 2040 snd_pcm_uframes_t frames, appl_ptr, appl_ofs;
1998 snd_pcm_uframes_t avail; 2041 snd_pcm_uframes_t avail;
@@ -2021,15 +2064,17 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream,
2021 if (frames > cont) 2064 if (frames > cont)
2022 frames = cont; 2065 frames = cont;
2023 if (snd_BUG_ON(!frames)) { 2066 if (snd_BUG_ON(!frames)) {
2067 runtime->twake = 0;
2024 snd_pcm_stream_unlock_irq(substream); 2068 snd_pcm_stream_unlock_irq(substream);
2025 return -EINVAL; 2069 return -EINVAL;
2026 } 2070 }
2027 appl_ptr = runtime->control->appl_ptr; 2071 appl_ptr = runtime->control->appl_ptr;
2028 appl_ofs = appl_ptr % runtime->buffer_size; 2072 appl_ofs = appl_ptr % runtime->buffer_size;
2029 snd_pcm_stream_unlock_irq(substream); 2073 snd_pcm_stream_unlock_irq(substream);
2030 if ((err = transfer(substream, appl_ofs, data, offset, frames)) < 0) 2074 err = transfer(substream, appl_ofs, data, offset, frames);
2031 goto _end;
2032 snd_pcm_stream_lock_irq(substream); 2075 snd_pcm_stream_lock_irq(substream);
2076 if (err < 0)
2077 goto _end_unlock;
2033 switch (runtime->status->state) { 2078 switch (runtime->status->state) {
2034 case SNDRV_PCM_STATE_XRUN: 2079 case SNDRV_PCM_STATE_XRUN:
2035 err = -EPIPE; 2080 err = -EPIPE;
@@ -2052,8 +2097,10 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream,
2052 xfer += frames; 2097 xfer += frames;
2053 } 2098 }
2054 _end_unlock: 2099 _end_unlock:
2100 runtime->twake = 0;
2101 if (xfer > 0 && err >= 0)
2102 snd_pcm_update_state(substream, runtime);
2055 snd_pcm_stream_unlock_irq(substream); 2103 snd_pcm_stream_unlock_irq(substream);
2056 _end:
2057 return xfer > 0 ? (snd_pcm_sframes_t)xfer : err; 2104 return xfer > 0 ? (snd_pcm_sframes_t)xfer : err;
2058} 2105}
2059 2106
diff --git a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c
index caa7796bc2f5..917e4055ee30 100644
--- a/sound/core/pcm_memory.c
+++ b/sound/core/pcm_memory.c
@@ -22,7 +22,9 @@
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>
27#include <linux/vmalloc.h>
26#include <sound/core.h> 28#include <sound/core.h>
27#include <sound/pcm.h> 29#include <sound/pcm.h>
28#include <sound/info.h> 30#include <sound/info.h>
@@ -434,3 +436,57 @@ int snd_pcm_lib_free_pages(struct snd_pcm_substream *substream)
434} 436}
435 437
436EXPORT_SYMBOL(snd_pcm_lib_free_pages); 438EXPORT_SYMBOL(snd_pcm_lib_free_pages);
439
440int _snd_pcm_lib_alloc_vmalloc_buffer(struct snd_pcm_substream *substream,
441 size_t size, gfp_t gfp_flags)
442{
443 struct snd_pcm_runtime *runtime;
444
445 if (PCM_RUNTIME_CHECK(substream))
446 return -EINVAL;
447 runtime = substream->runtime;
448 if (runtime->dma_area) {
449 if (runtime->dma_bytes >= size)
450 return 0; /* already large enough */
451 vfree(runtime->dma_area);
452 }
453 runtime->dma_area = __vmalloc(size, gfp_flags, PAGE_KERNEL);
454 if (!runtime->dma_area)
455 return -ENOMEM;
456 runtime->dma_bytes = size;
457 return 1;
458}
459EXPORT_SYMBOL(_snd_pcm_lib_alloc_vmalloc_buffer);
460
461/**
462 * snd_pcm_lib_free_vmalloc_buffer - free vmalloc buffer
463 * @substream: the substream with a buffer allocated by
464 * snd_pcm_lib_alloc_vmalloc_buffer()
465 */
466int snd_pcm_lib_free_vmalloc_buffer(struct snd_pcm_substream *substream)
467{
468 struct snd_pcm_runtime *runtime;
469
470 if (PCM_RUNTIME_CHECK(substream))
471 return -EINVAL;
472 runtime = substream->runtime;
473 vfree(runtime->dma_area);
474 runtime->dma_area = NULL;
475 return 0;
476}
477EXPORT_SYMBOL(snd_pcm_lib_free_vmalloc_buffer);
478
479/**
480 * snd_pcm_lib_get_vmalloc_page - map vmalloc buffer offset to page struct
481 * @substream: the substream with a buffer allocated by
482 * snd_pcm_lib_alloc_vmalloc_buffer()
483 * @offset: offset in the buffer
484 *
485 * This function is to be used as the page callback in the PCM ops.
486 */
487struct page *snd_pcm_lib_get_vmalloc_page(struct snd_pcm_substream *substream,
488 unsigned long offset)
489{
490 return vmalloc_to_page(substream->runtime->dma_area + offset);
491}
492EXPORT_SYMBOL(snd_pcm_lib_get_vmalloc_page);
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index ab73edf2c89a..20b5982c996b 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -26,6 +26,8 @@
26#include <linux/time.h> 26#include <linux/time.h>
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>
30#include <linux/math64.h>
29#include <sound/core.h> 31#include <sound/core.h>
30#include <sound/control.h> 32#include <sound/control.h>
31#include <sound/info.h> 33#include <sound/info.h>
@@ -34,6 +36,9 @@
34#include <sound/timer.h> 36#include <sound/timer.h>
35#include <sound/minors.h> 37#include <sound/minors.h>
36#include <asm/io.h> 38#include <asm/io.h>
39#if defined(CONFIG_MIPS) && defined(CONFIG_DMA_NONCOHERENT)
40#include <dma-coherence.h>
41#endif
37 42
38/* 43/*
39 * Compatibility 44 * Compatibility
@@ -314,10 +319,10 @@ int snd_pcm_hw_refine(struct snd_pcm_substream *substream,
314 if (!params->info) 319 if (!params->info)
315 params->info = hw->info & ~SNDRV_PCM_INFO_FIFO_IN_FRAMES; 320 params->info = hw->info & ~SNDRV_PCM_INFO_FIFO_IN_FRAMES;
316 if (!params->fifo_size) { 321 if (!params->fifo_size) {
317 if (snd_mask_min(&params->masks[SNDRV_PCM_HW_PARAM_FORMAT]) == 322 m = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
318 snd_mask_max(&params->masks[SNDRV_PCM_HW_PARAM_FORMAT]) && 323 i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
319 snd_mask_min(&params->masks[SNDRV_PCM_HW_PARAM_CHANNELS]) == 324 if (snd_mask_min(m) == snd_mask_max(m) &&
320 snd_mask_max(&params->masks[SNDRV_PCM_HW_PARAM_CHANNELS])) { 325 snd_interval_min(i) == snd_interval_max(i)) {
321 changed = substream->ops->ioctl(substream, 326 changed = substream->ops->ioctl(substream,
322 SNDRV_PCM_IOCTL1_FIFO_SIZE, params); 327 SNDRV_PCM_IOCTL1_FIFO_SIZE, params);
323 if (changed < 0) 328 if (changed < 0)
@@ -365,6 +370,38 @@ static int period_to_usecs(struct snd_pcm_runtime *runtime)
365 return usecs; 370 return usecs;
366} 371}
367 372
373static int calc_boundary(struct snd_pcm_runtime *runtime)
374{
375 u_int64_t boundary;
376
377 boundary = (u_int64_t)runtime->buffer_size *
378 (u_int64_t)runtime->period_size;
379#if BITS_PER_LONG < 64
380 /* try to find lowest common multiple for buffer and period */
381 if (boundary > LONG_MAX - runtime->buffer_size) {
382 u_int32_t remainder = -1;
383 u_int32_t divident = runtime->buffer_size;
384 u_int32_t divisor = runtime->period_size;
385 while (remainder) {
386 remainder = divident % divisor;
387 if (remainder) {
388 divident = divisor;
389 divisor = remainder;
390 }
391 }
392 boundary = div_u64(boundary, divisor);
393 if (boundary > LONG_MAX - runtime->buffer_size)
394 return -ERANGE;
395 }
396#endif
397 if (boundary == 0)
398 return -ERANGE;
399 runtime->boundary = boundary;
400 while (runtime->boundary * 2 <= LONG_MAX - runtime->buffer_size)
401 runtime->boundary *= 2;
402 return 0;
403}
404
368static int snd_pcm_hw_params(struct snd_pcm_substream *substream, 405static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
369 struct snd_pcm_hw_params *params) 406 struct snd_pcm_hw_params *params)
370{ 407{
@@ -440,9 +477,9 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
440 runtime->stop_threshold = runtime->buffer_size; 477 runtime->stop_threshold = runtime->buffer_size;
441 runtime->silence_threshold = 0; 478 runtime->silence_threshold = 0;
442 runtime->silence_size = 0; 479 runtime->silence_size = 0;
443 runtime->boundary = runtime->buffer_size; 480 err = calc_boundary(runtime);
444 while (runtime->boundary * 2 <= LONG_MAX - runtime->buffer_size) 481 if (err < 0)
445 runtime->boundary *= 2; 482 goto _error;
446 483
447 snd_pcm_timer_resolution_change(substream); 484 snd_pcm_timer_resolution_change(substream);
448 runtime->status->state = SNDRV_PCM_STATE_SETUP; 485 runtime->status->state = SNDRV_PCM_STATE_SETUP;
@@ -515,6 +552,7 @@ static int snd_pcm_sw_params(struct snd_pcm_substream *substream,
515 struct snd_pcm_sw_params *params) 552 struct snd_pcm_sw_params *params)
516{ 553{
517 struct snd_pcm_runtime *runtime; 554 struct snd_pcm_runtime *runtime;
555 int err;
518 556
519 if (PCM_RUNTIME_CHECK(substream)) 557 if (PCM_RUNTIME_CHECK(substream))
520 return -ENXIO; 558 return -ENXIO;
@@ -539,6 +577,7 @@ static int snd_pcm_sw_params(struct snd_pcm_substream *substream,
539 if (params->silence_threshold > runtime->buffer_size) 577 if (params->silence_threshold > runtime->buffer_size)
540 return -EINVAL; 578 return -EINVAL;
541 } 579 }
580 err = 0;
542 snd_pcm_stream_lock_irq(substream); 581 snd_pcm_stream_lock_irq(substream);
543 runtime->tstamp_mode = params->tstamp_mode; 582 runtime->tstamp_mode = params->tstamp_mode;
544 runtime->period_step = params->period_step; 583 runtime->period_step = params->period_step;
@@ -552,10 +591,10 @@ static int snd_pcm_sw_params(struct snd_pcm_substream *substream,
552 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && 591 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
553 runtime->silence_size > 0) 592 runtime->silence_size > 0)
554 snd_pcm_playback_silence(substream, ULONG_MAX); 593 snd_pcm_playback_silence(substream, ULONG_MAX);
555 wake_up(&runtime->sleep); 594 err = snd_pcm_update_state(substream, runtime);
556 } 595 }
557 snd_pcm_stream_unlock_irq(substream); 596 snd_pcm_stream_unlock_irq(substream);
558 return 0; 597 return err;
559} 598}
560 599
561static int snd_pcm_sw_params_user(struct snd_pcm_substream *substream, 600static int snd_pcm_sw_params_user(struct snd_pcm_substream *substream,
@@ -916,6 +955,7 @@ static void snd_pcm_post_stop(struct snd_pcm_substream *substream, int state)
916 runtime->status->state = state; 955 runtime->status->state = state;
917 } 956 }
918 wake_up(&runtime->sleep); 957 wake_up(&runtime->sleep);
958 wake_up(&runtime->tsleep);
919} 959}
920 960
921static struct action_ops snd_pcm_action_stop = { 961static struct action_ops snd_pcm_action_stop = {
@@ -1001,6 +1041,7 @@ static void snd_pcm_post_pause(struct snd_pcm_substream *substream, int push)
1001 SNDRV_TIMER_EVENT_MPAUSE, 1041 SNDRV_TIMER_EVENT_MPAUSE,
1002 &runtime->trigger_tstamp); 1042 &runtime->trigger_tstamp);
1003 wake_up(&runtime->sleep); 1043 wake_up(&runtime->sleep);
1044 wake_up(&runtime->tsleep);
1004 } else { 1045 } else {
1005 runtime->status->state = SNDRV_PCM_STATE_RUNNING; 1046 runtime->status->state = SNDRV_PCM_STATE_RUNNING;
1006 if (substream->timer) 1047 if (substream->timer)
@@ -1058,6 +1099,7 @@ static void snd_pcm_post_suspend(struct snd_pcm_substream *substream, int state)
1058 runtime->status->suspended_state = runtime->status->state; 1099 runtime->status->suspended_state = runtime->status->state;
1059 runtime->status->state = SNDRV_PCM_STATE_SUSPENDED; 1100 runtime->status->state = SNDRV_PCM_STATE_SUSPENDED;
1060 wake_up(&runtime->sleep); 1101 wake_up(&runtime->sleep);
1102 wake_up(&runtime->tsleep);
1061} 1103}
1062 1104
1063static struct action_ops snd_pcm_action_suspend = { 1105static struct action_ops snd_pcm_action_suspend = {
@@ -1917,13 +1959,13 @@ int snd_pcm_hw_constraints_complete(struct snd_pcm_substream *substream)
1917 1959
1918 err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_RATE, 1960 err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_RATE,
1919 hw->rate_min, hw->rate_max); 1961 hw->rate_min, hw->rate_max);
1920 if (err < 0) 1962 if (err < 0)
1921 return err; 1963 return err;
1922 1964
1923 err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 1965 err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
1924 hw->period_bytes_min, hw->period_bytes_max); 1966 hw->period_bytes_min, hw->period_bytes_max);
1925 if (err < 0) 1967 if (err < 0)
1926 return err; 1968 return err;
1927 1969
1928 err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIODS, 1970 err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIODS,
1929 hw->periods_min, hw->periods_max); 1971 hw->periods_min, hw->periods_max);
@@ -3061,6 +3103,27 @@ static int snd_pcm_mmap_control(struct snd_pcm_substream *substream, struct file
3061} 3103}
3062#endif /* coherent mmap */ 3104#endif /* coherent mmap */
3063 3105
3106static inline struct page *
3107snd_pcm_default_page_ops(struct snd_pcm_substream *substream, unsigned long ofs)
3108{
3109 void *vaddr = substream->runtime->dma_area + ofs;
3110#if defined(CONFIG_MIPS) && defined(CONFIG_DMA_NONCOHERENT)
3111 if (substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV)
3112 return virt_to_page(CAC_ADDR(vaddr));
3113#endif
3114#if defined(CONFIG_PPC32) && defined(CONFIG_NOT_COHERENT_CACHE)
3115 if (substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV) {
3116 dma_addr_t addr = substream->runtime->dma_addr + ofs;
3117 addr -= get_dma_offset(substream->dma_buffer.dev.dev);
3118 /* assume dma_handle set via pfn_to_phys() in
3119 * mm/dma-noncoherent.c
3120 */
3121 return pfn_to_page(addr >> PAGE_SHIFT);
3122 }
3123#endif
3124 return virt_to_page(vaddr);
3125}
3126
3064/* 3127/*
3065 * fault callback for mmapping a RAM page 3128 * fault callback for mmapping a RAM page
3066 */ 3129 */
@@ -3071,7 +3134,6 @@ static int snd_pcm_mmap_data_fault(struct vm_area_struct *area,
3071 struct snd_pcm_runtime *runtime; 3134 struct snd_pcm_runtime *runtime;
3072 unsigned long offset; 3135 unsigned long offset;
3073 struct page * page; 3136 struct page * page;
3074 void *vaddr;
3075 size_t dma_bytes; 3137 size_t dma_bytes;
3076 3138
3077 if (substream == NULL) 3139 if (substream == NULL)
@@ -3081,36 +3143,57 @@ static int snd_pcm_mmap_data_fault(struct vm_area_struct *area,
3081 dma_bytes = PAGE_ALIGN(runtime->dma_bytes); 3143 dma_bytes = PAGE_ALIGN(runtime->dma_bytes);
3082 if (offset > dma_bytes - PAGE_SIZE) 3144 if (offset > dma_bytes - PAGE_SIZE)
3083 return VM_FAULT_SIGBUS; 3145 return VM_FAULT_SIGBUS;
3084 if (substream->ops->page) { 3146 if (substream->ops->page)
3085 page = substream->ops->page(substream, offset); 3147 page = substream->ops->page(substream, offset);
3086 if (!page) 3148 else
3087 return VM_FAULT_SIGBUS; 3149 page = snd_pcm_default_page_ops(substream, offset);
3088 } else { 3150 if (!page)
3089 vaddr = runtime->dma_area + offset; 3151 return VM_FAULT_SIGBUS;
3090 page = virt_to_page(vaddr);
3091 }
3092 get_page(page); 3152 get_page(page);
3093 vmf->page = page; 3153 vmf->page = page;
3094 return 0; 3154 return 0;
3095} 3155}
3096 3156
3097static const struct vm_operations_struct snd_pcm_vm_ops_data = 3157static const struct vm_operations_struct snd_pcm_vm_ops_data = {
3098{ 3158 .open = snd_pcm_mmap_data_open,
3159 .close = snd_pcm_mmap_data_close,
3160};
3161
3162static const struct vm_operations_struct snd_pcm_vm_ops_data_fault = {
3099 .open = snd_pcm_mmap_data_open, 3163 .open = snd_pcm_mmap_data_open,
3100 .close = snd_pcm_mmap_data_close, 3164 .close = snd_pcm_mmap_data_close,
3101 .fault = snd_pcm_mmap_data_fault, 3165 .fault = snd_pcm_mmap_data_fault,
3102}; 3166};
3103 3167
3168#ifndef ARCH_HAS_DMA_MMAP_COHERENT
3169/* This should be defined / handled globally! */
3170#ifdef CONFIG_ARM
3171#define ARCH_HAS_DMA_MMAP_COHERENT
3172#endif
3173#endif
3174
3104/* 3175/*
3105 * mmap the DMA buffer on RAM 3176 * mmap the DMA buffer on RAM
3106 */ 3177 */
3107static int snd_pcm_default_mmap(struct snd_pcm_substream *substream, 3178static int snd_pcm_default_mmap(struct snd_pcm_substream *substream,
3108 struct vm_area_struct *area) 3179 struct vm_area_struct *area)
3109{ 3180{
3110 area->vm_ops = &snd_pcm_vm_ops_data;
3111 area->vm_private_data = substream;
3112 area->vm_flags |= VM_RESERVED; 3181 area->vm_flags |= VM_RESERVED;
3113 atomic_inc(&substream->mmap_count); 3182#ifdef ARCH_HAS_DMA_MMAP_COHERENT
3183 if (!substream->ops->page &&
3184 substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV)
3185 return dma_mmap_coherent(substream->dma_buffer.dev.dev,
3186 area,
3187 substream->runtime->dma_area,
3188 substream->runtime->dma_addr,
3189 area->vm_end - area->vm_start);
3190#elif defined(CONFIG_MIPS) && defined(CONFIG_DMA_NONCOHERENT)
3191 if (substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV &&
3192 !plat_device_is_coherent(substream->dma_buffer.dev.dev))
3193 area->vm_page_prot = pgprot_noncached(area->vm_page_prot);
3194#endif /* ARCH_HAS_DMA_MMAP_COHERENT */
3195 /* mmap with fault handler */
3196 area->vm_ops = &snd_pcm_vm_ops_data_fault;
3114 return 0; 3197 return 0;
3115} 3198}
3116 3199
@@ -3118,23 +3201,13 @@ static int snd_pcm_default_mmap(struct snd_pcm_substream *substream,
3118 * mmap the DMA buffer on I/O memory area 3201 * mmap the DMA buffer on I/O memory area
3119 */ 3202 */
3120#if SNDRV_PCM_INFO_MMAP_IOMEM 3203#if SNDRV_PCM_INFO_MMAP_IOMEM
3121static const struct vm_operations_struct snd_pcm_vm_ops_data_mmio =
3122{
3123 .open = snd_pcm_mmap_data_open,
3124 .close = snd_pcm_mmap_data_close,
3125};
3126
3127int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, 3204int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream,
3128 struct vm_area_struct *area) 3205 struct vm_area_struct *area)
3129{ 3206{
3130 long size; 3207 long size;
3131 unsigned long offset; 3208 unsigned long offset;
3132 3209
3133#ifdef pgprot_noncached
3134 area->vm_page_prot = pgprot_noncached(area->vm_page_prot); 3210 area->vm_page_prot = pgprot_noncached(area->vm_page_prot);
3135#endif
3136 area->vm_ops = &snd_pcm_vm_ops_data_mmio;
3137 area->vm_private_data = substream;
3138 area->vm_flags |= VM_IO; 3211 area->vm_flags |= VM_IO;
3139 size = area->vm_end - area->vm_start; 3212 size = area->vm_end - area->vm_start;
3140 offset = area->vm_pgoff << PAGE_SHIFT; 3213 offset = area->vm_pgoff << PAGE_SHIFT;
@@ -3142,13 +3215,21 @@ int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream,
3142 (substream->runtime->dma_addr + offset) >> PAGE_SHIFT, 3215 (substream->runtime->dma_addr + offset) >> PAGE_SHIFT,
3143 size, area->vm_page_prot)) 3216 size, area->vm_page_prot))
3144 return -EAGAIN; 3217 return -EAGAIN;
3145 atomic_inc(&substream->mmap_count);
3146 return 0; 3218 return 0;
3147} 3219}
3148 3220
3149EXPORT_SYMBOL(snd_pcm_lib_mmap_iomem); 3221EXPORT_SYMBOL(snd_pcm_lib_mmap_iomem);
3150#endif /* SNDRV_PCM_INFO_MMAP */ 3222#endif /* SNDRV_PCM_INFO_MMAP */
3151 3223
3224/* mmap callback with pgprot_noncached */
3225int snd_pcm_lib_mmap_noncached(struct snd_pcm_substream *substream,
3226 struct vm_area_struct *area)
3227{
3228 area->vm_page_prot = pgprot_noncached(area->vm_page_prot);
3229 return snd_pcm_default_mmap(substream, area);
3230}
3231EXPORT_SYMBOL(snd_pcm_lib_mmap_noncached);
3232
3152/* 3233/*
3153 * mmap DMA buffer 3234 * mmap DMA buffer
3154 */ 3235 */
@@ -3159,6 +3240,7 @@ int snd_pcm_mmap_data(struct snd_pcm_substream *substream, struct file *file,
3159 long size; 3240 long size;
3160 unsigned long offset; 3241 unsigned long offset;
3161 size_t dma_bytes; 3242 size_t dma_bytes;
3243 int err;
3162 3244
3163 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 3245 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
3164 if (!(area->vm_flags & (VM_WRITE|VM_READ))) 3246 if (!(area->vm_flags & (VM_WRITE|VM_READ)))
@@ -3183,10 +3265,15 @@ int snd_pcm_mmap_data(struct snd_pcm_substream *substream, struct file *file,
3183 if (offset > dma_bytes - size) 3265 if (offset > dma_bytes - size)
3184 return -EINVAL; 3266 return -EINVAL;
3185 3267
3268 area->vm_ops = &snd_pcm_vm_ops_data;
3269 area->vm_private_data = substream;
3186 if (substream->ops->mmap) 3270 if (substream->ops->mmap)
3187 return substream->ops->mmap(substream, area); 3271 err = substream->ops->mmap(substream, area);
3188 else 3272 else
3189 return snd_pcm_default_mmap(substream, area); 3273 err = snd_pcm_default_mmap(substream, area);
3274 if (!err)
3275 atomic_inc(&substream->mmap_count);
3276 return err;
3190} 3277}
3191 3278
3192EXPORT_SYMBOL(snd_pcm_mmap_data); 3279EXPORT_SYMBOL(snd_pcm_mmap_data);
diff --git a/sound/core/pcm_timer.c b/sound/core/pcm_timer.c
index ca8068b63d6c..b01d9481d632 100644
--- a/sound/core/pcm_timer.c
+++ b/sound/core/pcm_timer.c
@@ -20,6 +20,7 @@
20 */ 20 */
21 21
22#include <linux/time.h> 22#include <linux/time.h>
23#include <linux/gcd.h>
23#include <sound/core.h> 24#include <sound/core.h>
24#include <sound/pcm.h> 25#include <sound/pcm.h>
25#include <sound/timer.h> 26#include <sound/timer.h>
@@ -28,22 +29,6 @@
28 * Timer functions 29 * Timer functions
29 */ 30 */
30 31
31/* Greatest common divisor */
32static unsigned long gcd(unsigned long a, unsigned long b)
33{
34 unsigned long r;
35 if (a < b) {
36 r = a;
37 a = b;
38 b = r;
39 }
40 while ((r = a % b) != 0) {
41 a = b;
42 b = r;
43 }
44 return b;
45}
46
47void snd_pcm_timer_resolution_change(struct snd_pcm_substream *substream) 32void snd_pcm_timer_resolution_change(struct snd_pcm_substream *substream)
48{ 33{
49 unsigned long rate, mult, fsize, l, post; 34 unsigned long rate, mult, fsize, l, post;
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index 70d6f25ba526..0f5a194695d9 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -242,8 +242,6 @@ static int assign_substream(struct snd_rawmidi *rmidi, int subdevice,
242 return -ENXIO; 242 return -ENXIO;
243 if (subdevice >= 0 && subdevice >= s->substream_count) 243 if (subdevice >= 0 && subdevice >= s->substream_count)
244 return -ENODEV; 244 return -ENODEV;
245 if (s->substream_opened >= s->substream_count)
246 return -EAGAIN;
247 245
248 list_for_each_entry(substream, &s->substreams, list) { 246 list_for_each_entry(substream, &s->substreams, list) {
249 if (substream->opened) { 247 if (substream->opened) {
@@ -280,9 +278,10 @@ static int open_substream(struct snd_rawmidi *rmidi,
280 substream->active_sensing = 0; 278 substream->active_sensing = 0;
281 if (mode & SNDRV_RAWMIDI_LFLG_APPEND) 279 if (mode & SNDRV_RAWMIDI_LFLG_APPEND)
282 substream->append = 1; 280 substream->append = 1;
281 substream->pid = get_pid(task_pid(current));
282 rmidi->streams[substream->stream].substream_opened++;
283 } 283 }
284 substream->use_count++; 284 substream->use_count++;
285 rmidi->streams[substream->stream].substream_opened++;
286 return 0; 285 return 0;
287} 286}
288 287
@@ -413,7 +412,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
413 subdevice = -1; 412 subdevice = -1;
414 read_lock(&card->ctl_files_rwlock); 413 read_lock(&card->ctl_files_rwlock);
415 list_for_each_entry(kctl, &card->ctl_files, list) { 414 list_for_each_entry(kctl, &card->ctl_files, list) {
416 if (kctl->pid == current->pid) { 415 if (kctl->pid == task_pid(current)) {
417 subdevice = kctl->prefer_rawmidi_subdevice; 416 subdevice = kctl->prefer_rawmidi_subdevice;
418 if (subdevice != -1) 417 if (subdevice != -1)
419 break; 418 break;
@@ -466,7 +465,6 @@ static void close_substream(struct snd_rawmidi *rmidi,
466 struct snd_rawmidi_substream *substream, 465 struct snd_rawmidi_substream *substream,
467 int cleanup) 466 int cleanup)
468{ 467{
469 rmidi->streams[substream->stream].substream_opened--;
470 if (--substream->use_count) 468 if (--substream->use_count)
471 return; 469 return;
472 470
@@ -491,6 +489,9 @@ static void close_substream(struct snd_rawmidi *rmidi,
491 snd_rawmidi_runtime_free(substream); 489 snd_rawmidi_runtime_free(substream);
492 substream->opened = 0; 490 substream->opened = 0;
493 substream->append = 0; 491 substream->append = 0;
492 put_pid(substream->pid);
493 substream->pid = NULL;
494 rmidi->streams[substream->stream].substream_opened--;
494} 495}
495 496
496static void rawmidi_release_priv(struct snd_rawmidi_file *rfile) 497static void rawmidi_release_priv(struct snd_rawmidi_file *rfile)
@@ -1256,7 +1257,7 @@ static ssize_t snd_rawmidi_write(struct file *file, const char __user *buf,
1256 break; 1257 break;
1257 count -= count1; 1258 count -= count1;
1258 } 1259 }
1259 if (file->f_flags & O_SYNC) { 1260 if (file->f_flags & O_DSYNC) {
1260 spin_lock_irq(&runtime->lock); 1261 spin_lock_irq(&runtime->lock);
1261 while (runtime->avail != runtime->buffer_size) { 1262 while (runtime->avail != runtime->buffer_size) {
1262 wait_queue_t wait; 1263 wait_queue_t wait;
@@ -1338,6 +1339,9 @@ static void snd_rawmidi_proc_info_read(struct snd_info_entry *entry,
1338 substream->number, 1339 substream->number,
1339 (unsigned long) substream->bytes); 1340 (unsigned long) substream->bytes);
1340 if (substream->opened) { 1341 if (substream->opened) {
1342 snd_iprintf(buffer,
1343 " Owner PID : %d\n",
1344 pid_vnr(substream->pid));
1341 runtime = substream->runtime; 1345 runtime = substream->runtime;
1342 snd_iprintf(buffer, 1346 snd_iprintf(buffer,
1343 " Mode : %s\n" 1347 " Mode : %s\n"
@@ -1359,6 +1363,9 @@ static void snd_rawmidi_proc_info_read(struct snd_info_entry *entry,
1359 substream->number, 1363 substream->number,
1360 (unsigned long) substream->bytes); 1364 (unsigned long) substream->bytes);
1361 if (substream->opened) { 1365 if (substream->opened) {
1366 snd_iprintf(buffer,
1367 " Owner PID : %d\n",
1368 pid_vnr(substream->pid));
1362 runtime = substream->runtime; 1369 runtime = substream->runtime;
1363 snd_iprintf(buffer, 1370 snd_iprintf(buffer,
1364 " Buffer size : %lu\n" 1371 " Buffer size : %lu\n"
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 8ca2be339f3b..48eca9ff9ee7 100644
--- a/sound/core/seq/seq_clientmgr.c
+++ b/sound/core/seq/seq_clientmgr.c
@@ -2190,7 +2190,7 @@ static int snd_seq_do_ioctl(struct snd_seq_client *client, unsigned int cmd,
2190 if (p->cmd == cmd) 2190 if (p->cmd == cmd)
2191 return p->func(client, arg); 2191 return p->func(client, arg);
2192 } 2192 }
2193 snd_printd("seq unknown ioctl() 0x%x (type='%c', number=0x%2x)\n", 2193 snd_printd("seq unknown ioctl() 0x%x (type='%c', number=0x%02x)\n",
2194 cmd, _IOC_TYPE(cmd), _IOC_NR(cmd)); 2194 cmd, _IOC_TYPE(cmd), _IOC_NR(cmd));
2195 return -ENOTTY; 2195 return -ENOTTY;
2196} 2196}
diff --git a/sound/core/seq/seq_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/seq/seq_timer.c b/sound/core/seq/seq_timer.c
index f745c317d6af..160b1bd0cd62 100644
--- a/sound/core/seq/seq_timer.c
+++ b/sound/core/seq/seq_timer.c
@@ -33,22 +33,21 @@
33 33
34#define SKEW_BASE 0x10000 /* 16bit shift */ 34#define SKEW_BASE 0x10000 /* 16bit shift */
35 35
36static void snd_seq_timer_set_tick_resolution(struct snd_seq_timer_tick *tick, 36static void snd_seq_timer_set_tick_resolution(struct snd_seq_timer *tmr)
37 int tempo, int ppq)
38{ 37{
39 if (tempo < 1000000) 38 if (tmr->tempo < 1000000)
40 tick->resolution = (tempo * 1000) / ppq; 39 tmr->tick.resolution = (tmr->tempo * 1000) / tmr->ppq;
41 else { 40 else {
42 /* might overflow.. */ 41 /* might overflow.. */
43 unsigned int s; 42 unsigned int s;
44 s = tempo % ppq; 43 s = tmr->tempo % tmr->ppq;
45 s = (s * 1000) / ppq; 44 s = (s * 1000) / tmr->ppq;
46 tick->resolution = (tempo / ppq) * 1000; 45 tmr->tick.resolution = (tmr->tempo / tmr->ppq) * 1000;
47 tick->resolution += s; 46 tmr->tick.resolution += s;
48 } 47 }
49 if (tick->resolution <= 0) 48 if (tmr->tick.resolution <= 0)
50 tick->resolution = 1; 49 tmr->tick.resolution = 1;
51 snd_seq_timer_update_tick(tick, 0); 50 snd_seq_timer_update_tick(&tmr->tick, 0);
52} 51}
53 52
54/* create new timer (constructor) */ 53/* create new timer (constructor) */
@@ -96,7 +95,7 @@ void snd_seq_timer_defaults(struct snd_seq_timer * tmr)
96 /* setup defaults */ 95 /* setup defaults */
97 tmr->ppq = 96; /* 96 PPQ */ 96 tmr->ppq = 96; /* 96 PPQ */
98 tmr->tempo = 500000; /* 120 BPM */ 97 tmr->tempo = 500000; /* 120 BPM */
99 snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq); 98 snd_seq_timer_set_tick_resolution(tmr);
100 tmr->running = 0; 99 tmr->running = 0;
101 100
102 tmr->type = SNDRV_SEQ_TIMER_ALSA; 101 tmr->type = SNDRV_SEQ_TIMER_ALSA;
@@ -180,7 +179,7 @@ int snd_seq_timer_set_tempo(struct snd_seq_timer * tmr, int tempo)
180 spin_lock_irqsave(&tmr->lock, flags); 179 spin_lock_irqsave(&tmr->lock, flags);
181 if ((unsigned int)tempo != tmr->tempo) { 180 if ((unsigned int)tempo != tmr->tempo) {
182 tmr->tempo = tempo; 181 tmr->tempo = tempo;
183 snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq); 182 snd_seq_timer_set_tick_resolution(tmr);
184 } 183 }
185 spin_unlock_irqrestore(&tmr->lock, flags); 184 spin_unlock_irqrestore(&tmr->lock, flags);
186 return 0; 185 return 0;
@@ -205,7 +204,7 @@ int snd_seq_timer_set_ppq(struct snd_seq_timer * tmr, int ppq)
205 } 204 }
206 205
207 tmr->ppq = ppq; 206 tmr->ppq = ppq;
208 snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq); 207 snd_seq_timer_set_tick_resolution(tmr);
209 spin_unlock_irqrestore(&tmr->lock, flags); 208 spin_unlock_irqrestore(&tmr->lock, flags);
210 return 0; 209 return 0;
211} 210}
diff --git a/sound/core/sound.c b/sound/core/sound.c
index 7872a02f6ca9..563d1967a0ad 100644
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -468,5 +468,5 @@ static void __exit alsa_sound_exit(void)
468 unregister_chrdev(major, "alsa"); 468 unregister_chrdev(major, "alsa");
469} 469}
470 470
471module_init(alsa_sound_init) 471subsys_initcall(alsa_sound_init);
472module_exit(alsa_sound_exit) 472module_exit(alsa_sound_exit);
diff --git a/sound/core/sound_oss.c b/sound/core/sound_oss.c
index 7fe12264ff80..0c164e5e4322 100644
--- a/sound/core/sound_oss.c
+++ b/sound/core/sound_oss.c
@@ -93,7 +93,7 @@ static int snd_oss_kernel_minor(int type, struct snd_card *card, int dev)
93 default: 93 default:
94 return -EINVAL; 94 return -EINVAL;
95 } 95 }
96 if (snd_BUG_ON(minor < 0 || minor >= SNDRV_OSS_MINORS)) 96 if (minor < 0 || minor >= SNDRV_OSS_MINORS)
97 return -EINVAL; 97 return -EINVAL;
98 return minor; 98 return minor;
99} 99}
diff --git a/sound/core/timer.c b/sound/core/timer.c
index 8f8b17ac074d..5040c7b862fe 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -393,7 +393,7 @@ static void snd_timer_notify1(struct snd_timer_instance *ti, int event)
393 event == SNDRV_TIMER_EVENT_CONTINUE) 393 event == SNDRV_TIMER_EVENT_CONTINUE)
394 resolution = snd_timer_resolution(ti); 394 resolution = snd_timer_resolution(ti);
395 if (ti->ccallback) 395 if (ti->ccallback)
396 ti->ccallback(ti, SNDRV_TIMER_EVENT_START, &tstamp, resolution); 396 ti->ccallback(ti, event, &tstamp, resolution);
397 if (ti->flags & SNDRV_TIMER_IFLG_SLAVE) 397 if (ti->flags & SNDRV_TIMER_IFLG_SLAVE)
398 return; 398 return;
399 timer = ti->timer; 399 timer = ti->timer;
@@ -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}
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c
index 252e04ce602f..7f41990ed68b 100644
--- a/sound/drivers/dummy.c
+++ b/sound/drivers/dummy.c
@@ -45,109 +45,23 @@ MODULE_SUPPORTED_DEVICE("{{ALSA,Dummy soundcard}}");
45#define MAX_PCM_SUBSTREAMS 128 45#define MAX_PCM_SUBSTREAMS 128
46#define MAX_MIDI_DEVICES 2 46#define MAX_MIDI_DEVICES 2
47 47
48#if 0 /* emu10k1 emulation */
49#define MAX_BUFFER_SIZE (128 * 1024)
50static int emu10k1_playback_constraints(struct snd_pcm_runtime *runtime)
51{
52 int err;
53 err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
54 if (err < 0)
55 return err;
56 err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 256, UINT_MAX);
57 if (err < 0)
58 return err;
59 return 0;
60}
61#define add_playback_constraints emu10k1_playback_constraints
62#endif
63
64#if 0 /* RME9652 emulation */
65#define MAX_BUFFER_SIZE (26 * 64 * 1024)
66#define USE_FORMATS SNDRV_PCM_FMTBIT_S32_LE
67#define USE_CHANNELS_MIN 26
68#define USE_CHANNELS_MAX 26
69#define USE_PERIODS_MIN 2
70#define USE_PERIODS_MAX 2
71#endif
72
73#if 0 /* ICE1712 emulation */
74#define MAX_BUFFER_SIZE (256 * 1024)
75#define USE_FORMATS SNDRV_PCM_FMTBIT_S32_LE
76#define USE_CHANNELS_MIN 10
77#define USE_CHANNELS_MAX 10
78#define USE_PERIODS_MIN 1
79#define USE_PERIODS_MAX 1024
80#endif
81
82#if 0 /* UDA1341 emulation */
83#define MAX_BUFFER_SIZE (16380)
84#define USE_FORMATS SNDRV_PCM_FMTBIT_S16_LE
85#define USE_CHANNELS_MIN 2
86#define USE_CHANNELS_MAX 2
87#define USE_PERIODS_MIN 2
88#define USE_PERIODS_MAX 255
89#endif
90
91#if 0 /* simple AC97 bridge (intel8x0) with 48kHz AC97 only codec */
92#define USE_FORMATS SNDRV_PCM_FMTBIT_S16_LE
93#define USE_CHANNELS_MIN 2
94#define USE_CHANNELS_MAX 2
95#define USE_RATE SNDRV_PCM_RATE_48000
96#define USE_RATE_MIN 48000
97#define USE_RATE_MAX 48000
98#endif
99
100#if 0 /* CA0106 */
101#define USE_FORMATS SNDRV_PCM_FMTBIT_S16_LE
102#define USE_CHANNELS_MIN 2
103#define USE_CHANNELS_MAX 2
104#define USE_RATE (SNDRV_PCM_RATE_48000|SNDRV_PCM_RATE_96000|SNDRV_PCM_RATE_192000)
105#define USE_RATE_MIN 48000
106#define USE_RATE_MAX 192000
107#define MAX_BUFFER_SIZE ((65536-64)*8)
108#define MAX_PERIOD_SIZE (65536-64)
109#define USE_PERIODS_MIN 2
110#define USE_PERIODS_MAX 8
111#endif
112
113
114/* defaults */ 48/* defaults */
115#ifndef MAX_BUFFER_SIZE
116#define MAX_BUFFER_SIZE (64*1024) 49#define MAX_BUFFER_SIZE (64*1024)
117#endif 50#define MIN_PERIOD_SIZE 64
118#ifndef MAX_PERIOD_SIZE
119#define MAX_PERIOD_SIZE MAX_BUFFER_SIZE 51#define MAX_PERIOD_SIZE MAX_BUFFER_SIZE
120#endif
121#ifndef USE_FORMATS
122#define USE_FORMATS (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE) 52#define USE_FORMATS (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE)
123#endif
124#ifndef USE_RATE
125#define USE_RATE SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000 53#define USE_RATE SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000
126#define USE_RATE_MIN 5500 54#define USE_RATE_MIN 5500
127#define USE_RATE_MAX 48000 55#define USE_RATE_MAX 48000
128#endif
129#ifndef USE_CHANNELS_MIN
130#define USE_CHANNELS_MIN 1 56#define USE_CHANNELS_MIN 1
131#endif
132#ifndef USE_CHANNELS_MAX
133#define USE_CHANNELS_MAX 2 57#define USE_CHANNELS_MAX 2
134#endif
135#ifndef USE_PERIODS_MIN
136#define USE_PERIODS_MIN 1 58#define USE_PERIODS_MIN 1
137#endif
138#ifndef USE_PERIODS_MAX
139#define USE_PERIODS_MAX 1024 59#define USE_PERIODS_MAX 1024
140#endif
141#ifndef add_playback_constraints
142#define add_playback_constraints(x) 0
143#endif
144#ifndef add_capture_constraints
145#define add_capture_constraints(x) 0
146#endif
147 60
148static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ 61static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
149static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ 62static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
150static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0}; 63static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0};
64static char *model[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = NULL};
151static int pcm_devs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; 65static int pcm_devs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
152static int pcm_substreams[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 8}; 66static int pcm_substreams[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 8};
153//static int midi_devs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2}; 67//static int midi_devs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
@@ -162,6 +76,8 @@ module_param_array(id, charp, NULL, 0444);
162MODULE_PARM_DESC(id, "ID string for dummy soundcard."); 76MODULE_PARM_DESC(id, "ID string for dummy soundcard.");
163module_param_array(enable, bool, NULL, 0444); 77module_param_array(enable, bool, NULL, 0444);
164MODULE_PARM_DESC(enable, "Enable this dummy soundcard."); 78MODULE_PARM_DESC(enable, "Enable this dummy soundcard.");
79module_param_array(model, charp, NULL, 0444);
80MODULE_PARM_DESC(model, "Soundcard model.");
165module_param_array(pcm_devs, int, NULL, 0444); 81module_param_array(pcm_devs, int, NULL, 0444);
166MODULE_PARM_DESC(pcm_devs, "PCM devices # (0-4) for dummy driver."); 82MODULE_PARM_DESC(pcm_devs, "PCM devices # (0-4) for dummy driver.");
167module_param_array(pcm_substreams, int, NULL, 0444); 83module_param_array(pcm_substreams, int, NULL, 0444);
@@ -193,9 +109,28 @@ struct dummy_timer_ops {
193 snd_pcm_uframes_t (*pointer)(struct snd_pcm_substream *); 109 snd_pcm_uframes_t (*pointer)(struct snd_pcm_substream *);
194}; 110};
195 111
112struct dummy_model {
113 const char *name;
114 int (*playback_constraints)(struct snd_pcm_runtime *runtime);
115 int (*capture_constraints)(struct snd_pcm_runtime *runtime);
116 u64 formats;
117 size_t buffer_bytes_max;
118 size_t period_bytes_min;
119 size_t period_bytes_max;
120 unsigned int periods_min;
121 unsigned int periods_max;
122 unsigned int rates;
123 unsigned int rate_min;
124 unsigned int rate_max;
125 unsigned int channels_min;
126 unsigned int channels_max;
127};
128
196struct snd_dummy { 129struct snd_dummy {
197 struct snd_card *card; 130 struct snd_card *card;
131 struct dummy_model *model;
198 struct snd_pcm *pcm; 132 struct snd_pcm *pcm;
133 struct snd_pcm_hardware pcm_hw;
199 spinlock_t mixer_lock; 134 spinlock_t mixer_lock;
200 int mixer_volume[MIXER_ADDR_LAST+1][2]; 135 int mixer_volume[MIXER_ADDR_LAST+1][2];
201 int capture_source[MIXER_ADDR_LAST+1][2]; 136 int capture_source[MIXER_ADDR_LAST+1][2];
@@ -203,6 +138,92 @@ struct snd_dummy {
203}; 138};
204 139
205/* 140/*
141 * card models
142 */
143
144static int emu10k1_playback_constraints(struct snd_pcm_runtime *runtime)
145{
146 int err;
147 err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
148 if (err < 0)
149 return err;
150 err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 256, UINT_MAX);
151 if (err < 0)
152 return err;
153 return 0;
154}
155
156struct dummy_model model_emu10k1 = {
157 .name = "emu10k1",
158 .playback_constraints = emu10k1_playback_constraints,
159 .buffer_bytes_max = 128 * 1024,
160};
161
162struct dummy_model model_rme9652 = {
163 .name = "rme9652",
164 .buffer_bytes_max = 26 * 64 * 1024,
165 .formats = SNDRV_PCM_FMTBIT_S32_LE,
166 .channels_min = 26,
167 .channels_max = 26,
168 .periods_min = 2,
169 .periods_max = 2,
170};
171
172struct dummy_model model_ice1712 = {
173 .name = "ice1712",
174 .buffer_bytes_max = 256 * 1024,
175 .formats = SNDRV_PCM_FMTBIT_S32_LE,
176 .channels_min = 10,
177 .channels_max = 10,
178 .periods_min = 1,
179 .periods_max = 1024,
180};
181
182struct dummy_model model_uda1341 = {
183 .name = "uda1341",
184 .buffer_bytes_max = 16380,
185 .formats = SNDRV_PCM_FMTBIT_S16_LE,
186 .channels_min = 2,
187 .channels_max = 2,
188 .periods_min = 2,
189 .periods_max = 255,
190};
191
192struct dummy_model model_ac97 = {
193 .name = "ac97",
194 .formats = SNDRV_PCM_FMTBIT_S16_LE,
195 .channels_min = 2,
196 .channels_max = 2,
197 .rates = SNDRV_PCM_RATE_48000,
198 .rate_min = 48000,
199 .rate_max = 48000,
200};
201
202struct dummy_model model_ca0106 = {
203 .name = "ca0106",
204 .formats = SNDRV_PCM_FMTBIT_S16_LE,
205 .buffer_bytes_max = ((65536-64)*8),
206 .period_bytes_max = (65536-64),
207 .periods_min = 2,
208 .periods_max = 8,
209 .channels_min = 2,
210 .channels_max = 2,
211 .rates = SNDRV_PCM_RATE_48000|SNDRV_PCM_RATE_96000|SNDRV_PCM_RATE_192000,
212 .rate_min = 48000,
213 .rate_max = 192000,
214};
215
216struct dummy_model *dummy_models[] = {
217 &model_emu10k1,
218 &model_rme9652,
219 &model_ice1712,
220 &model_uda1341,
221 &model_ac97,
222 &model_ca0106,
223 NULL
224};
225
226/*
206 * system timer interface 227 * system timer interface
207 */ 228 */
208 229
@@ -509,7 +530,7 @@ static struct snd_pcm_hardware dummy_pcm_hardware = {
509 .channels_min = USE_CHANNELS_MIN, 530 .channels_min = USE_CHANNELS_MIN,
510 .channels_max = USE_CHANNELS_MAX, 531 .channels_max = USE_CHANNELS_MAX,
511 .buffer_bytes_max = MAX_BUFFER_SIZE, 532 .buffer_bytes_max = MAX_BUFFER_SIZE,
512 .period_bytes_min = 64, 533 .period_bytes_min = MIN_PERIOD_SIZE,
513 .period_bytes_max = MAX_PERIOD_SIZE, 534 .period_bytes_max = MAX_PERIOD_SIZE,
514 .periods_min = USE_PERIODS_MIN, 535 .periods_min = USE_PERIODS_MIN,
515 .periods_max = USE_PERIODS_MAX, 536 .periods_max = USE_PERIODS_MAX,
@@ -538,6 +559,7 @@ static int dummy_pcm_hw_free(struct snd_pcm_substream *substream)
538static int dummy_pcm_open(struct snd_pcm_substream *substream) 559static int dummy_pcm_open(struct snd_pcm_substream *substream)
539{ 560{
540 struct snd_dummy *dummy = snd_pcm_substream_chip(substream); 561 struct snd_dummy *dummy = snd_pcm_substream_chip(substream);
562 struct dummy_model *model = dummy->model;
541 struct snd_pcm_runtime *runtime = substream->runtime; 563 struct snd_pcm_runtime *runtime = substream->runtime;
542 int err; 564 int err;
543 565
@@ -551,7 +573,7 @@ static int dummy_pcm_open(struct snd_pcm_substream *substream)
551 if (err < 0) 573 if (err < 0)
552 return err; 574 return err;
553 575
554 runtime->hw = dummy_pcm_hardware; 576 runtime->hw = dummy->pcm_hw;
555 if (substream->pcm->device & 1) { 577 if (substream->pcm->device & 1) {
556 runtime->hw.info &= ~SNDRV_PCM_INFO_INTERLEAVED; 578 runtime->hw.info &= ~SNDRV_PCM_INFO_INTERLEAVED;
557 runtime->hw.info |= SNDRV_PCM_INFO_NONINTERLEAVED; 579 runtime->hw.info |= SNDRV_PCM_INFO_NONINTERLEAVED;
@@ -560,10 +582,16 @@ static int dummy_pcm_open(struct snd_pcm_substream *substream)
560 runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP | 582 runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP |
561 SNDRV_PCM_INFO_MMAP_VALID); 583 SNDRV_PCM_INFO_MMAP_VALID);
562 584
563 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 585 if (model == NULL)
564 err = add_playback_constraints(substream->runtime); 586 return 0;
565 else 587
566 err = add_capture_constraints(substream->runtime); 588 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
589 if (model->playback_constraints)
590 err = model->playback_constraints(substream->runtime);
591 } else {
592 if (model->capture_constraints)
593 err = model->capture_constraints(substream->runtime);
594 }
567 if (err < 0) { 595 if (err < 0) {
568 dummy->timer_ops->free(substream); 596 dummy->timer_ops->free(substream);
569 return err; 597 return err;
@@ -823,17 +851,19 @@ static int __devinit snd_card_dummy_new_mixer(struct snd_dummy *dummy)
823/* 851/*
824 * proc interface 852 * proc interface
825 */ 853 */
826static void print_formats(struct snd_info_buffer *buffer) 854static void print_formats(struct snd_dummy *dummy,
855 struct snd_info_buffer *buffer)
827{ 856{
828 int i; 857 int i;
829 858
830 for (i = 0; i < SNDRV_PCM_FORMAT_LAST; i++) { 859 for (i = 0; i < SNDRV_PCM_FORMAT_LAST; i++) {
831 if (dummy_pcm_hardware.formats & (1ULL << i)) 860 if (dummy->pcm_hw.formats & (1ULL << i))
832 snd_iprintf(buffer, " %s", snd_pcm_format_name(i)); 861 snd_iprintf(buffer, " %s", snd_pcm_format_name(i));
833 } 862 }
834} 863}
835 864
836static void print_rates(struct snd_info_buffer *buffer) 865static void print_rates(struct snd_dummy *dummy,
866 struct snd_info_buffer *buffer)
837{ 867{
838 static int rates[] = { 868 static int rates[] = {
839 5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000, 869 5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000,
@@ -841,19 +871,19 @@ static void print_rates(struct snd_info_buffer *buffer)
841 }; 871 };
842 int i; 872 int i;
843 873
844 if (dummy_pcm_hardware.rates & SNDRV_PCM_RATE_CONTINUOUS) 874 if (dummy->pcm_hw.rates & SNDRV_PCM_RATE_CONTINUOUS)
845 snd_iprintf(buffer, " continuous"); 875 snd_iprintf(buffer, " continuous");
846 if (dummy_pcm_hardware.rates & SNDRV_PCM_RATE_KNOT) 876 if (dummy->pcm_hw.rates & SNDRV_PCM_RATE_KNOT)
847 snd_iprintf(buffer, " knot"); 877 snd_iprintf(buffer, " knot");
848 for (i = 0; i < ARRAY_SIZE(rates); i++) 878 for (i = 0; i < ARRAY_SIZE(rates); i++)
849 if (dummy_pcm_hardware.rates & (1 << i)) 879 if (dummy->pcm_hw.rates & (1 << i))
850 snd_iprintf(buffer, " %d", rates[i]); 880 snd_iprintf(buffer, " %d", rates[i]);
851} 881}
852 882
853#define get_dummy_int_ptr(ofs) \ 883#define get_dummy_int_ptr(dummy, ofs) \
854 (unsigned int *)((char *)&dummy_pcm_hardware + (ofs)) 884 (unsigned int *)((char *)&((dummy)->pcm_hw) + (ofs))
855#define get_dummy_ll_ptr(ofs) \ 885#define get_dummy_ll_ptr(dummy, ofs) \
856 (unsigned long long *)((char *)&dummy_pcm_hardware + (ofs)) 886 (unsigned long long *)((char *)&((dummy)->pcm_hw) + (ofs))
857 887
858struct dummy_hw_field { 888struct dummy_hw_field {
859 const char *name; 889 const char *name;
@@ -884,20 +914,21 @@ static struct dummy_hw_field fields[] = {
884static void dummy_proc_read(struct snd_info_entry *entry, 914static void dummy_proc_read(struct snd_info_entry *entry,
885 struct snd_info_buffer *buffer) 915 struct snd_info_buffer *buffer)
886{ 916{
917 struct snd_dummy *dummy = entry->private_data;
887 int i; 918 int i;
888 919
889 for (i = 0; i < ARRAY_SIZE(fields); i++) { 920 for (i = 0; i < ARRAY_SIZE(fields); i++) {
890 snd_iprintf(buffer, "%s ", fields[i].name); 921 snd_iprintf(buffer, "%s ", fields[i].name);
891 if (fields[i].size == sizeof(int)) 922 if (fields[i].size == sizeof(int))
892 snd_iprintf(buffer, fields[i].format, 923 snd_iprintf(buffer, fields[i].format,
893 *get_dummy_int_ptr(fields[i].offset)); 924 *get_dummy_int_ptr(dummy, fields[i].offset));
894 else 925 else
895 snd_iprintf(buffer, fields[i].format, 926 snd_iprintf(buffer, fields[i].format,
896 *get_dummy_ll_ptr(fields[i].offset)); 927 *get_dummy_ll_ptr(dummy, fields[i].offset));
897 if (!strcmp(fields[i].name, "formats")) 928 if (!strcmp(fields[i].name, "formats"))
898 print_formats(buffer); 929 print_formats(dummy, buffer);
899 else if (!strcmp(fields[i].name, "rates")) 930 else if (!strcmp(fields[i].name, "rates"))
900 print_rates(buffer); 931 print_rates(dummy, buffer);
901 snd_iprintf(buffer, "\n"); 932 snd_iprintf(buffer, "\n");
902 } 933 }
903} 934}
@@ -905,6 +936,7 @@ static void dummy_proc_read(struct snd_info_entry *entry,
905static void dummy_proc_write(struct snd_info_entry *entry, 936static void dummy_proc_write(struct snd_info_entry *entry,
906 struct snd_info_buffer *buffer) 937 struct snd_info_buffer *buffer)
907{ 938{
939 struct snd_dummy *dummy = entry->private_data;
908 char line[64]; 940 char line[64];
909 941
910 while (!snd_info_get_line(buffer, line, sizeof(line))) { 942 while (!snd_info_get_line(buffer, line, sizeof(line))) {
@@ -924,9 +956,9 @@ static void dummy_proc_write(struct snd_info_entry *entry,
924 if (strict_strtoull(item, 0, &val)) 956 if (strict_strtoull(item, 0, &val))
925 continue; 957 continue;
926 if (fields[i].size == sizeof(int)) 958 if (fields[i].size == sizeof(int))
927 *get_dummy_int_ptr(fields[i].offset) = val; 959 *get_dummy_int_ptr(dummy, fields[i].offset) = val;
928 else 960 else
929 *get_dummy_ll_ptr(fields[i].offset) = val; 961 *get_dummy_ll_ptr(dummy, fields[i].offset) = val;
930 } 962 }
931} 963}
932 964
@@ -938,6 +970,7 @@ static void __devinit dummy_proc_init(struct snd_dummy *chip)
938 snd_info_set_text_ops(entry, chip, dummy_proc_read); 970 snd_info_set_text_ops(entry, chip, dummy_proc_read);
939 entry->c.text.write = dummy_proc_write; 971 entry->c.text.write = dummy_proc_write;
940 entry->mode |= S_IWUSR; 972 entry->mode |= S_IWUSR;
973 entry->private_data = chip;
941 } 974 }
942} 975}
943#else 976#else
@@ -948,6 +981,7 @@ static int __devinit snd_dummy_probe(struct platform_device *devptr)
948{ 981{
949 struct snd_card *card; 982 struct snd_card *card;
950 struct snd_dummy *dummy; 983 struct snd_dummy *dummy;
984 struct dummy_model *m = NULL, **mdl;
951 int idx, err; 985 int idx, err;
952 int dev = devptr->id; 986 int dev = devptr->id;
953 987
@@ -957,6 +991,15 @@ static int __devinit snd_dummy_probe(struct platform_device *devptr)
957 return err; 991 return err;
958 dummy = card->private_data; 992 dummy = card->private_data;
959 dummy->card = card; 993 dummy->card = card;
994 for (mdl = dummy_models; *mdl && model[dev]; mdl++) {
995 if (strcmp(model[dev], (*mdl)->name) == 0) {
996 printk(KERN_INFO
997 "snd-dummy: Using model '%s' for card %i\n",
998 (*mdl)->name, card->number);
999 m = dummy->model = *mdl;
1000 break;
1001 }
1002 }
960 for (idx = 0; idx < MAX_PCM_DEVICES && idx < pcm_devs[dev]; idx++) { 1003 for (idx = 0; idx < MAX_PCM_DEVICES && idx < pcm_devs[dev]; idx++) {
961 if (pcm_substreams[dev] < 1) 1004 if (pcm_substreams[dev] < 1)
962 pcm_substreams[dev] = 1; 1005 pcm_substreams[dev] = 1;
@@ -966,6 +1009,33 @@ static int __devinit snd_dummy_probe(struct platform_device *devptr)
966 if (err < 0) 1009 if (err < 0)
967 goto __nodev; 1010 goto __nodev;
968 } 1011 }
1012
1013 dummy->pcm_hw = dummy_pcm_hardware;
1014 if (m) {
1015 if (m->formats)
1016 dummy->pcm_hw.formats = m->formats;
1017 if (m->buffer_bytes_max)
1018 dummy->pcm_hw.buffer_bytes_max = m->buffer_bytes_max;
1019 if (m->period_bytes_min)
1020 dummy->pcm_hw.period_bytes_min = m->period_bytes_min;
1021 if (m->period_bytes_max)
1022 dummy->pcm_hw.period_bytes_max = m->period_bytes_max;
1023 if (m->periods_min)
1024 dummy->pcm_hw.periods_min = m->periods_min;
1025 if (m->periods_max)
1026 dummy->pcm_hw.periods_max = m->periods_max;
1027 if (m->rates)
1028 dummy->pcm_hw.rates = m->rates;
1029 if (m->rate_min)
1030 dummy->pcm_hw.rate_min = m->rate_min;
1031 if (m->rate_max)
1032 dummy->pcm_hw.rate_max = m->rate_max;
1033 if (m->channels_min)
1034 dummy->pcm_hw.channels_min = m->channels_min;
1035 if (m->channels_max)
1036 dummy->pcm_hw.channels_max = m->channels_max;
1037 }
1038
969 err = snd_card_dummy_new_mixer(dummy); 1039 err = snd_card_dummy_new_mixer(dummy);
970 if (err < 0) 1040 if (err < 0)
971 goto __nodev; 1041 goto __nodev;
diff --git a/sound/drivers/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/pcsp/pcsp.c b/sound/drivers/pcsp/pcsp.c
index b60cef257b58..f165c77d6273 100644
--- a/sound/drivers/pcsp/pcsp.c
+++ b/sound/drivers/pcsp/pcsp.c
@@ -26,6 +26,7 @@ MODULE_ALIAS("platform:pcspkr");
26static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */ 26static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
27static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */ 27static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
28static int enable = SNDRV_DEFAULT_ENABLE1; /* Enable this card */ 28static int enable = SNDRV_DEFAULT_ENABLE1; /* Enable this card */
29static int nopcm; /* Disable PCM capability of the driver */
29 30
30module_param(index, int, 0444); 31module_param(index, int, 0444);
31MODULE_PARM_DESC(index, "Index value for pcsp soundcard."); 32MODULE_PARM_DESC(index, "Index value for pcsp soundcard.");
@@ -33,6 +34,8 @@ module_param(id, charp, 0444);
33MODULE_PARM_DESC(id, "ID string for pcsp soundcard."); 34MODULE_PARM_DESC(id, "ID string for pcsp soundcard.");
34module_param(enable, bool, 0444); 35module_param(enable, bool, 0444);
35MODULE_PARM_DESC(enable, "Enable PC-Speaker sound."); 36MODULE_PARM_DESC(enable, "Enable PC-Speaker sound.");
37module_param(nopcm, bool, 0444);
38MODULE_PARM_DESC(nopcm, "Disable PC-Speaker PCM sound. Only beeps remain.");
36 39
37struct snd_pcsp pcsp_chip; 40struct snd_pcsp pcsp_chip;
38 41
@@ -43,13 +46,16 @@ static int __devinit snd_pcsp_create(struct snd_card *card)
43 int err; 46 int err;
44 int div, min_div, order; 47 int div, min_div, order;
45 48
46 hrtimer_get_res(CLOCK_MONOTONIC, &tp); 49 if (!nopcm) {
47 if (tp.tv_sec || tp.tv_nsec > PCSP_MAX_PERIOD_NS) { 50 hrtimer_get_res(CLOCK_MONOTONIC, &tp);
48 printk(KERN_ERR "PCSP: Timer resolution is not sufficient " 51 if (tp.tv_sec || tp.tv_nsec > PCSP_MAX_PERIOD_NS) {
49 "(%linS)\n", tp.tv_nsec); 52 printk(KERN_ERR "PCSP: Timer resolution is not sufficient "
50 printk(KERN_ERR "PCSP: Make sure you have HPET and ACPI " 53 "(%linS)\n", tp.tv_nsec);
51 "enabled.\n"); 54 printk(KERN_ERR "PCSP: Make sure you have HPET and ACPI "
52 return -EIO; 55 "enabled.\n");
56 printk(KERN_ERR "PCSP: Turned into nopcm mode.\n");
57 nopcm = 1;
58 }
53 } 59 }
54 60
55 if (loops_per_jiffy >= PCSP_MIN_LPJ && tp.tv_nsec <= PCSP_MIN_PERIOD_NS) 61 if (loops_per_jiffy >= PCSP_MIN_LPJ && tp.tv_nsec <= PCSP_MIN_PERIOD_NS)
@@ -107,12 +113,14 @@ static int __devinit snd_card_pcsp_probe(int devnum, struct device *dev)
107 snd_card_free(card); 113 snd_card_free(card);
108 return err; 114 return err;
109 } 115 }
110 err = snd_pcsp_new_pcm(&pcsp_chip); 116 if (!nopcm) {
111 if (err < 0) { 117 err = snd_pcsp_new_pcm(&pcsp_chip);
112 snd_card_free(card); 118 if (err < 0) {
113 return err; 119 snd_card_free(card);
120 return err;
121 }
114 } 122 }
115 err = snd_pcsp_new_mixer(&pcsp_chip); 123 err = snd_pcsp_new_mixer(&pcsp_chip, nopcm);
116 if (err < 0) { 124 if (err < 0) {
117 snd_card_free(card); 125 snd_card_free(card);
118 return err; 126 return err;
diff --git a/sound/drivers/pcsp/pcsp.h b/sound/drivers/pcsp/pcsp.h
index 174dd2ff0f22..1e123077923d 100644
--- a/sound/drivers/pcsp/pcsp.h
+++ b/sound/drivers/pcsp/pcsp.h
@@ -83,6 +83,6 @@ extern enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle);
83extern void pcsp_sync_stop(struct snd_pcsp *chip); 83extern void pcsp_sync_stop(struct snd_pcsp *chip);
84 84
85extern int snd_pcsp_new_pcm(struct snd_pcsp *chip); 85extern int snd_pcsp_new_pcm(struct snd_pcsp *chip);
86extern int snd_pcsp_new_mixer(struct snd_pcsp *chip); 86extern int snd_pcsp_new_mixer(struct snd_pcsp *chip, int nopcm);
87 87
88#endif 88#endif
diff --git a/sound/drivers/pcsp/pcsp_lib.c b/sound/drivers/pcsp/pcsp_lib.c
index e1145ac6e908..d77ffa9a9387 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>
diff --git a/sound/drivers/pcsp/pcsp_mixer.c b/sound/drivers/pcsp/pcsp_mixer.c
index 903bc846763f..6f633f4f3b96 100644
--- a/sound/drivers/pcsp/pcsp_mixer.c
+++ b/sound/drivers/pcsp/pcsp_mixer.c
@@ -119,24 +119,43 @@ static int pcsp_pcspkr_put(struct snd_kcontrol *kcontrol,
119 .put = pcsp_##ctl_type##_put, \ 119 .put = pcsp_##ctl_type##_put, \
120} 120}
121 121
122static struct snd_kcontrol_new __devinitdata snd_pcsp_controls[] = { 122static struct snd_kcontrol_new __devinitdata snd_pcsp_controls_pcm[] = {
123 PCSP_MIXER_CONTROL(enable, "Master Playback Switch"), 123 PCSP_MIXER_CONTROL(enable, "Master Playback Switch"),
124 PCSP_MIXER_CONTROL(treble, "BaseFRQ Playback Volume"), 124 PCSP_MIXER_CONTROL(treble, "BaseFRQ Playback Volume"),
125 PCSP_MIXER_CONTROL(pcspkr, "PC Speaker Playback Switch"),
126}; 125};
127 126
128int __devinit snd_pcsp_new_mixer(struct snd_pcsp *chip) 127static struct snd_kcontrol_new __devinitdata snd_pcsp_controls_spkr[] = {
128 PCSP_MIXER_CONTROL(pcspkr, "Beep Playback Switch"),
129};
130
131static int __devinit snd_pcsp_ctls_add(struct snd_pcsp *chip,
132 struct snd_kcontrol_new *ctls, int num)
129{ 133{
130 struct snd_card *card = chip->card;
131 int i, err; 134 int i, err;
135 struct snd_card *card = chip->card;
136 for (i = 0; i < num; i++) {
137 err = snd_ctl_add(card, snd_ctl_new1(ctls + i, chip));
138 if (err < 0)
139 return err;
140 }
141 return 0;
142}
143
144int __devinit snd_pcsp_new_mixer(struct snd_pcsp *chip, int nopcm)
145{
146 int err;
147 struct snd_card *card = chip->card;
132 148
133 for (i = 0; i < ARRAY_SIZE(snd_pcsp_controls); i++) { 149 if (!nopcm) {
134 err = snd_ctl_add(card, 150 err = snd_pcsp_ctls_add(chip, snd_pcsp_controls_pcm,
135 snd_ctl_new1(snd_pcsp_controls + i, 151 ARRAY_SIZE(snd_pcsp_controls_pcm));
136 chip));
137 if (err < 0) 152 if (err < 0)
138 return err; 153 return err;
139 } 154 }
155 err = snd_pcsp_ctls_add(chip, snd_pcsp_controls_spkr,
156 ARRAY_SIZE(snd_pcsp_controls_spkr));
157 if (err < 0)
158 return err;
140 159
141 strcpy(card->mixername, "PC-Speaker"); 160 strcpy(card->mixername, "PC-Speaker");
142 161
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/drivers/vx/vx_pcm.c b/sound/drivers/vx/vx_pcm.c
index 6644d0034fba..35a2f71a6af5 100644
--- a/sound/drivers/vx/vx_pcm.c
+++ b/sound/drivers/vx/vx_pcm.c
@@ -46,7 +46,6 @@
46 */ 46 */
47 47
48#include <linux/slab.h> 48#include <linux/slab.h>
49#include <linux/vmalloc.h>
50#include <linux/delay.h> 49#include <linux/delay.h>
51#include <sound/core.h> 50#include <sound/core.h>
52#include <sound/asoundef.h> 51#include <sound/asoundef.h>
@@ -56,55 +55,6 @@
56 55
57 56
58/* 57/*
59 * we use a vmalloc'ed (sg-)buffer
60 */
61
62/* get the physical page pointer on the given offset */
63static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs,
64 unsigned long offset)
65{
66 void *pageptr = subs->runtime->dma_area + offset;
67 return vmalloc_to_page(pageptr);
68}
69
70/*
71 * allocate a buffer via vmalloc_32().
72 * called from hw_params
73 * NOTE: this may be called not only once per pcm open!
74 */
75static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, size_t size)
76{
77 struct snd_pcm_runtime *runtime = subs->runtime;
78 if (runtime->dma_area) {
79 /* already allocated */
80 if (runtime->dma_bytes >= size)
81 return 0; /* already enough large */
82 vfree(runtime->dma_area);
83 }
84 runtime->dma_area = vmalloc_32(size);
85 if (! runtime->dma_area)
86 return -ENOMEM;
87 memset(runtime->dma_area, 0, size);
88 runtime->dma_bytes = size;
89 return 1; /* changed */
90}
91
92/*
93 * free the buffer.
94 * called from hw_free callback
95 * NOTE: this may be called not only once per pcm open!
96 */
97static int snd_pcm_free_vmalloc_buffer(struct snd_pcm_substream *subs)
98{
99 struct snd_pcm_runtime *runtime = subs->runtime;
100
101 vfree(runtime->dma_area);
102 runtime->dma_area = NULL;
103 return 0;
104}
105
106
107/*
108 * read three pending pcm bytes via inb() 58 * read three pending pcm bytes via inb()
109 */ 59 */
110static void vx_pcm_read_per_bytes(struct vx_core *chip, struct snd_pcm_runtime *runtime, 60static void vx_pcm_read_per_bytes(struct vx_core *chip, struct snd_pcm_runtime *runtime,
@@ -865,7 +815,8 @@ static snd_pcm_uframes_t vx_pcm_playback_pointer(struct snd_pcm_substream *subs)
865static int vx_pcm_hw_params(struct snd_pcm_substream *subs, 815static int vx_pcm_hw_params(struct snd_pcm_substream *subs,
866 struct snd_pcm_hw_params *hw_params) 816 struct snd_pcm_hw_params *hw_params)
867{ 817{
868 return snd_pcm_alloc_vmalloc_buffer(subs, params_buffer_bytes(hw_params)); 818 return snd_pcm_lib_alloc_vmalloc_32_buffer
819 (subs, params_buffer_bytes(hw_params));
869} 820}
870 821
871/* 822/*
@@ -873,7 +824,7 @@ static int vx_pcm_hw_params(struct snd_pcm_substream *subs,
873 */ 824 */
874static int vx_pcm_hw_free(struct snd_pcm_substream *subs) 825static int vx_pcm_hw_free(struct snd_pcm_substream *subs)
875{ 826{
876 return snd_pcm_free_vmalloc_buffer(subs); 827 return snd_pcm_lib_free_vmalloc_buffer(subs);
877} 828}
878 829
879/* 830/*
@@ -953,7 +904,8 @@ static struct snd_pcm_ops vx_pcm_playback_ops = {
953 .prepare = vx_pcm_prepare, 904 .prepare = vx_pcm_prepare,
954 .trigger = vx_pcm_trigger, 905 .trigger = vx_pcm_trigger,
955 .pointer = vx_pcm_playback_pointer, 906 .pointer = vx_pcm_playback_pointer,
956 .page = snd_pcm_get_vmalloc_page, 907 .page = snd_pcm_lib_get_vmalloc_page,
908 .mmap = snd_pcm_lib_mmap_vmalloc,
957}; 909};
958 910
959 911
@@ -1173,7 +1125,8 @@ static struct snd_pcm_ops vx_pcm_capture_ops = {
1173 .prepare = vx_pcm_prepare, 1125 .prepare = vx_pcm_prepare,
1174 .trigger = vx_pcm_trigger, 1126 .trigger = vx_pcm_trigger,
1175 .pointer = vx_pcm_capture_pointer, 1127 .pointer = vx_pcm_capture_pointer,
1176 .page = snd_pcm_get_vmalloc_page, 1128 .page = snd_pcm_lib_get_vmalloc_page,
1129 .mmap = snd_pcm_lib_mmap_vmalloc,
1177}; 1130};
1178 1131
1179 1132
diff --git a/sound/i2c/cs8427.c b/sound/i2c/cs8427.c
index 020a5d512472..04ae8704cdcd 100644
--- a/sound/i2c/cs8427.c
+++ b/sound/i2c/cs8427.c
@@ -23,6 +23,7 @@
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/delay.h> 24#include <linux/delay.h>
25#include <linux/init.h> 25#include <linux/init.h>
26#include <linux/bitrev.h>
26#include <asm/unaligned.h> 27#include <asm/unaligned.h>
27#include <sound/core.h> 28#include <sound/core.h>
28#include <sound/control.h> 29#include <sound/control.h>
@@ -55,18 +56,6 @@ struct cs8427 {
55 struct cs8427_stream capture; 56 struct cs8427_stream capture;
56}; 57};
57 58
58static unsigned char swapbits(unsigned char val)
59{
60 int bit;
61 unsigned char res = 0;
62 for (bit = 0; bit < 8; bit++) {
63 res <<= 1;
64 res |= val & 1;
65 val >>= 1;
66 }
67 return res;
68}
69
70int snd_cs8427_reg_write(struct snd_i2c_device *device, unsigned char reg, 59int snd_cs8427_reg_write(struct snd_i2c_device *device, unsigned char reg,
71 unsigned char val) 60 unsigned char val)
72{ 61{
@@ -149,7 +138,7 @@ static int snd_cs8427_send_corudata(struct snd_i2c_device *device,
149 } 138 }
150 data[0] = CS8427_REG_AUTOINC | CS8427_REG_CORU_DATABUF; 139 data[0] = CS8427_REG_AUTOINC | CS8427_REG_CORU_DATABUF;
151 for (idx = 0; idx < count; idx++) 140 for (idx = 0; idx < count; idx++)
152 data[idx + 1] = swapbits(ndata[idx]); 141 data[idx + 1] = bitrev8(ndata[idx]);
153 if (snd_i2c_sendbytes(device, data, count + 1) != count + 1) 142 if (snd_i2c_sendbytes(device, data, count + 1) != count + 1)
154 return -EIO; 143 return -EIO;
155 return 1; 144 return 1;
diff --git a/sound/i2c/other/Makefile b/sound/i2c/other/Makefile
index 703d954238f4..2dad40f3f622 100644
--- a/sound/i2c/other/Makefile
+++ b/sound/i2c/other/Makefile
@@ -5,6 +5,7 @@
5 5
6snd-ak4114-objs := ak4114.o 6snd-ak4114-objs := ak4114.o
7snd-ak4117-objs := ak4117.o 7snd-ak4117-objs := ak4117.o
8snd-ak4113-objs := ak4113.o
8snd-ak4xxx-adda-objs := ak4xxx-adda.o 9snd-ak4xxx-adda-objs := ak4xxx-adda.o
9snd-pt2258-objs := pt2258.o 10snd-pt2258-objs := pt2258.o
10snd-tea575x-tuner-objs := tea575x-tuner.o 11snd-tea575x-tuner-objs := tea575x-tuner.o
@@ -12,5 +13,5 @@ snd-tea575x-tuner-objs := tea575x-tuner.o
12# Module Dependency 13# Module Dependency
13obj-$(CONFIG_SND_PDAUDIOCF) += snd-ak4117.o 14obj-$(CONFIG_SND_PDAUDIOCF) += snd-ak4117.o
14obj-$(CONFIG_SND_ICE1712) += snd-ak4xxx-adda.o 15obj-$(CONFIG_SND_ICE1712) += snd-ak4xxx-adda.o
15obj-$(CONFIG_SND_ICE1724) += snd-ak4114.o snd-ak4xxx-adda.o snd-pt2258.o 16obj-$(CONFIG_SND_ICE1724) += snd-ak4114.o snd-ak4113.o snd-ak4xxx-adda.o snd-pt2258.o
16obj-$(CONFIG_SND_FM801_TEA575X) += snd-tea575x-tuner.o 17obj-$(CONFIG_SND_FM801_TEA575X) += snd-tea575x-tuner.o
diff --git a/sound/i2c/other/ak4113.c b/sound/i2c/other/ak4113.c
new file mode 100644
index 000000000000..971a84a4fa77
--- /dev/null
+++ b/sound/i2c/other/ak4113.c
@@ -0,0 +1,639 @@
1/*
2 * Routines for control of the AK4113 via I2C/4-wire serial interface
3 * IEC958 (S/PDIF) receiver by Asahi Kasei
4 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
5 * Copyright (c) by Pavel Hofman <pavel.hofman@ivitera.com>
6 *
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 */
23
24#include <linux/slab.h>
25#include <linux/delay.h>
26#include <sound/core.h>
27#include <sound/control.h>
28#include <sound/pcm.h>
29#include <sound/ak4113.h>
30#include <sound/asoundef.h>
31#include <sound/info.h>
32
33MODULE_AUTHOR("Pavel Hofman <pavel.hofman@ivitera.com>");
34MODULE_DESCRIPTION("AK4113 IEC958 (S/PDIF) receiver by Asahi Kasei");
35MODULE_LICENSE("GPL");
36
37#define AK4113_ADDR 0x00 /* fixed address */
38
39static void ak4113_stats(struct work_struct *work);
40static void ak4113_init_regs(struct ak4113 *chip);
41
42
43static void reg_write(struct ak4113 *ak4113, unsigned char reg,
44 unsigned char val)
45{
46 ak4113->write(ak4113->private_data, reg, val);
47 if (reg < sizeof(ak4113->regmap))
48 ak4113->regmap[reg] = val;
49}
50
51static inline unsigned char reg_read(struct ak4113 *ak4113, unsigned char reg)
52{
53 return ak4113->read(ak4113->private_data, reg);
54}
55
56static void snd_ak4113_free(struct ak4113 *chip)
57{
58 chip->init = 1; /* don't schedule new work */
59 mb();
60 cancel_delayed_work(&chip->work);
61 flush_scheduled_work();
62 kfree(chip);
63}
64
65static int snd_ak4113_dev_free(struct snd_device *device)
66{
67 struct ak4113 *chip = device->device_data;
68 snd_ak4113_free(chip);
69 return 0;
70}
71
72int snd_ak4113_create(struct snd_card *card, ak4113_read_t *read,
73 ak4113_write_t *write, const unsigned char *pgm,
74 void *private_data, struct ak4113 **r_ak4113)
75{
76 struct ak4113 *chip;
77 int err = 0;
78 unsigned char reg;
79 static struct snd_device_ops ops = {
80 .dev_free = snd_ak4113_dev_free,
81 };
82
83 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
84 if (chip == NULL)
85 return -ENOMEM;
86 spin_lock_init(&chip->lock);
87 chip->card = card;
88 chip->read = read;
89 chip->write = write;
90 chip->private_data = private_data;
91 INIT_DELAYED_WORK(&chip->work, ak4113_stats);
92
93 for (reg = 0; reg < AK4113_WRITABLE_REGS ; reg++)
94 chip->regmap[reg] = pgm[reg];
95 ak4113_init_regs(chip);
96
97 chip->rcs0 = reg_read(chip, AK4113_REG_RCS0) & ~(AK4113_QINT |
98 AK4113_CINT | AK4113_STC);
99 chip->rcs1 = reg_read(chip, AK4113_REG_RCS1);
100 chip->rcs2 = reg_read(chip, AK4113_REG_RCS2);
101 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
102 if (err < 0)
103 goto __fail;
104
105 if (r_ak4113)
106 *r_ak4113 = chip;
107 return 0;
108
109__fail:
110 snd_ak4113_free(chip);
111 return err < 0 ? err : -EIO;
112}
113EXPORT_SYMBOL_GPL(snd_ak4113_create);
114
115void snd_ak4113_reg_write(struct ak4113 *chip, unsigned char reg,
116 unsigned char mask, unsigned char val)
117{
118 if (reg >= AK4113_WRITABLE_REGS)
119 return;
120 reg_write(chip, reg, (chip->regmap[reg] & ~mask) | val);
121}
122EXPORT_SYMBOL_GPL(snd_ak4113_reg_write);
123
124static void ak4113_init_regs(struct ak4113 *chip)
125{
126 unsigned char old = chip->regmap[AK4113_REG_PWRDN], reg;
127
128 /* bring the chip to reset state and powerdown state */
129 reg_write(chip, AK4113_REG_PWRDN, old & ~(AK4113_RST|AK4113_PWN));
130 udelay(200);
131 /* release reset, but leave powerdown */
132 reg_write(chip, AK4113_REG_PWRDN, (old | AK4113_RST) & ~AK4113_PWN);
133 udelay(200);
134 for (reg = 1; reg < AK4113_WRITABLE_REGS; reg++)
135 reg_write(chip, reg, chip->regmap[reg]);
136 /* release powerdown, everything is initialized now */
137 reg_write(chip, AK4113_REG_PWRDN, old | AK4113_RST | AK4113_PWN);
138}
139
140void snd_ak4113_reinit(struct ak4113 *chip)
141{
142 chip->init = 1;
143 mb();
144 flush_scheduled_work();
145 ak4113_init_regs(chip);
146 /* bring up statistics / event queing */
147 chip->init = 0;
148 if (chip->kctls[0])
149 schedule_delayed_work(&chip->work, HZ / 10);
150}
151EXPORT_SYMBOL_GPL(snd_ak4113_reinit);
152
153static unsigned int external_rate(unsigned char rcs1)
154{
155 switch (rcs1 & (AK4113_FS0|AK4113_FS1|AK4113_FS2|AK4113_FS3)) {
156 case AK4113_FS_8000HZ:
157 return 8000;
158 case AK4113_FS_11025HZ:
159 return 11025;
160 case AK4113_FS_16000HZ:
161 return 16000;
162 case AK4113_FS_22050HZ:
163 return 22050;
164 case AK4113_FS_24000HZ:
165 return 24000;
166 case AK4113_FS_32000HZ:
167 return 32000;
168 case AK4113_FS_44100HZ:
169 return 44100;
170 case AK4113_FS_48000HZ:
171 return 48000;
172 case AK4113_FS_64000HZ:
173 return 64000;
174 case AK4113_FS_88200HZ:
175 return 88200;
176 case AK4113_FS_96000HZ:
177 return 96000;
178 case AK4113_FS_176400HZ:
179 return 176400;
180 case AK4113_FS_192000HZ:
181 return 192000;
182 default:
183 return 0;
184 }
185}
186
187static int snd_ak4113_in_error_info(struct snd_kcontrol *kcontrol,
188 struct snd_ctl_elem_info *uinfo)
189{
190 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
191 uinfo->count = 1;
192 uinfo->value.integer.min = 0;
193 uinfo->value.integer.max = LONG_MAX;
194 return 0;
195}
196
197static int snd_ak4113_in_error_get(struct snd_kcontrol *kcontrol,
198 struct snd_ctl_elem_value *ucontrol)
199{
200 struct ak4113 *chip = snd_kcontrol_chip(kcontrol);
201 long *ptr;
202
203 spin_lock_irq(&chip->lock);
204 ptr = (long *)(((char *)chip) + kcontrol->private_value);
205 ucontrol->value.integer.value[0] = *ptr;
206 *ptr = 0;
207 spin_unlock_irq(&chip->lock);
208 return 0;
209}
210
211#define snd_ak4113_in_bit_info snd_ctl_boolean_mono_info
212
213static int snd_ak4113_in_bit_get(struct snd_kcontrol *kcontrol,
214 struct snd_ctl_elem_value *ucontrol)
215{
216 struct ak4113 *chip = snd_kcontrol_chip(kcontrol);
217 unsigned char reg = kcontrol->private_value & 0xff;
218 unsigned char bit = (kcontrol->private_value >> 8) & 0xff;
219 unsigned char inv = (kcontrol->private_value >> 31) & 1;
220
221 ucontrol->value.integer.value[0] =
222 ((reg_read(chip, reg) & (1 << bit)) ? 1 : 0) ^ inv;
223 return 0;
224}
225
226static int snd_ak4113_rx_info(struct snd_kcontrol *kcontrol,
227 struct snd_ctl_elem_info *uinfo)
228{
229 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
230 uinfo->count = 1;
231 uinfo->value.integer.min = 0;
232 uinfo->value.integer.max = 5;
233 return 0;
234}
235
236static int snd_ak4113_rx_get(struct snd_kcontrol *kcontrol,
237 struct snd_ctl_elem_value *ucontrol)
238{
239 struct ak4113 *chip = snd_kcontrol_chip(kcontrol);
240
241 ucontrol->value.integer.value[0] =
242 (AK4113_IPS(chip->regmap[AK4113_REG_IO1]));
243 return 0;
244}
245
246static int snd_ak4113_rx_put(struct snd_kcontrol *kcontrol,
247 struct snd_ctl_elem_value *ucontrol)
248{
249 struct ak4113 *chip = snd_kcontrol_chip(kcontrol);
250 int change;
251 u8 old_val;
252
253 spin_lock_irq(&chip->lock);
254 old_val = chip->regmap[AK4113_REG_IO1];
255 change = ucontrol->value.integer.value[0] != AK4113_IPS(old_val);
256 if (change)
257 reg_write(chip, AK4113_REG_IO1,
258 (old_val & (~AK4113_IPS(0xff))) |
259 (AK4113_IPS(ucontrol->value.integer.value[0])));
260 spin_unlock_irq(&chip->lock);
261 return change;
262}
263
264static int snd_ak4113_rate_info(struct snd_kcontrol *kcontrol,
265 struct snd_ctl_elem_info *uinfo)
266{
267 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
268 uinfo->count = 1;
269 uinfo->value.integer.min = 0;
270 uinfo->value.integer.max = 192000;
271 return 0;
272}
273
274static int snd_ak4113_rate_get(struct snd_kcontrol *kcontrol,
275 struct snd_ctl_elem_value *ucontrol)
276{
277 struct ak4113 *chip = snd_kcontrol_chip(kcontrol);
278
279 ucontrol->value.integer.value[0] = external_rate(reg_read(chip,
280 AK4113_REG_RCS1));
281 return 0;
282}
283
284static int snd_ak4113_spdif_info(struct snd_kcontrol *kcontrol,
285 struct snd_ctl_elem_info *uinfo)
286{
287 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
288 uinfo->count = 1;
289 return 0;
290}
291
292static int snd_ak4113_spdif_get(struct snd_kcontrol *kcontrol,
293 struct snd_ctl_elem_value *ucontrol)
294{
295 struct ak4113 *chip = snd_kcontrol_chip(kcontrol);
296 unsigned i;
297
298 for (i = 0; i < AK4113_REG_RXCSB_SIZE; i++)
299 ucontrol->value.iec958.status[i] = reg_read(chip,
300 AK4113_REG_RXCSB0 + i);
301 return 0;
302}
303
304static int snd_ak4113_spdif_mask_info(struct snd_kcontrol *kcontrol,
305 struct snd_ctl_elem_info *uinfo)
306{
307 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
308 uinfo->count = 1;
309 return 0;
310}
311
312static int snd_ak4113_spdif_mask_get(struct snd_kcontrol *kcontrol,
313 struct snd_ctl_elem_value *ucontrol)
314{
315 memset(ucontrol->value.iec958.status, 0xff, AK4113_REG_RXCSB_SIZE);
316 return 0;
317}
318
319static int snd_ak4113_spdif_pinfo(struct snd_kcontrol *kcontrol,
320 struct snd_ctl_elem_info *uinfo)
321{
322 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
323 uinfo->value.integer.min = 0;
324 uinfo->value.integer.max = 0xffff;
325 uinfo->count = 4;
326 return 0;
327}
328
329static int snd_ak4113_spdif_pget(struct snd_kcontrol *kcontrol,
330 struct snd_ctl_elem_value *ucontrol)
331{
332 struct ak4113 *chip = snd_kcontrol_chip(kcontrol);
333 unsigned short tmp;
334
335 ucontrol->value.integer.value[0] = 0xf8f2;
336 ucontrol->value.integer.value[1] = 0x4e1f;
337 tmp = reg_read(chip, AK4113_REG_Pc0) |
338 (reg_read(chip, AK4113_REG_Pc1) << 8);
339 ucontrol->value.integer.value[2] = tmp;
340 tmp = reg_read(chip, AK4113_REG_Pd0) |
341 (reg_read(chip, AK4113_REG_Pd1) << 8);
342 ucontrol->value.integer.value[3] = tmp;
343 return 0;
344}
345
346static int snd_ak4113_spdif_qinfo(struct snd_kcontrol *kcontrol,
347 struct snd_ctl_elem_info *uinfo)
348{
349 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
350 uinfo->count = AK4113_REG_QSUB_SIZE;
351 return 0;
352}
353
354static int snd_ak4113_spdif_qget(struct snd_kcontrol *kcontrol,
355 struct snd_ctl_elem_value *ucontrol)
356{
357 struct ak4113 *chip = snd_kcontrol_chip(kcontrol);
358 unsigned i;
359
360 for (i = 0; i < AK4113_REG_QSUB_SIZE; i++)
361 ucontrol->value.bytes.data[i] = reg_read(chip,
362 AK4113_REG_QSUB_ADDR + i);
363 return 0;
364}
365
366/* Don't forget to change AK4113_CONTROLS define!!! */
367static struct snd_kcontrol_new snd_ak4113_iec958_controls[] = {
368{
369 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
370 .name = "IEC958 Parity Errors",
371 .access = SNDRV_CTL_ELEM_ACCESS_READ |
372 SNDRV_CTL_ELEM_ACCESS_VOLATILE,
373 .info = snd_ak4113_in_error_info,
374 .get = snd_ak4113_in_error_get,
375 .private_value = offsetof(struct ak4113, parity_errors),
376},
377{
378 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
379 .name = "IEC958 V-Bit Errors",
380 .access = SNDRV_CTL_ELEM_ACCESS_READ |
381 SNDRV_CTL_ELEM_ACCESS_VOLATILE,
382 .info = snd_ak4113_in_error_info,
383 .get = snd_ak4113_in_error_get,
384 .private_value = offsetof(struct ak4113, v_bit_errors),
385},
386{
387 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
388 .name = "IEC958 C-CRC Errors",
389 .access = SNDRV_CTL_ELEM_ACCESS_READ |
390 SNDRV_CTL_ELEM_ACCESS_VOLATILE,
391 .info = snd_ak4113_in_error_info,
392 .get = snd_ak4113_in_error_get,
393 .private_value = offsetof(struct ak4113, ccrc_errors),
394},
395{
396 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
397 .name = "IEC958 Q-CRC Errors",
398 .access = SNDRV_CTL_ELEM_ACCESS_READ |
399 SNDRV_CTL_ELEM_ACCESS_VOLATILE,
400 .info = snd_ak4113_in_error_info,
401 .get = snd_ak4113_in_error_get,
402 .private_value = offsetof(struct ak4113, qcrc_errors),
403},
404{
405 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
406 .name = "IEC958 External Rate",
407 .access = SNDRV_CTL_ELEM_ACCESS_READ |
408 SNDRV_CTL_ELEM_ACCESS_VOLATILE,
409 .info = snd_ak4113_rate_info,
410 .get = snd_ak4113_rate_get,
411},
412{
413 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
414 .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, MASK),
415 .access = SNDRV_CTL_ELEM_ACCESS_READ,
416 .info = snd_ak4113_spdif_mask_info,
417 .get = snd_ak4113_spdif_mask_get,
418},
419{
420 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
421 .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, DEFAULT),
422 .access = SNDRV_CTL_ELEM_ACCESS_READ |
423 SNDRV_CTL_ELEM_ACCESS_VOLATILE,
424 .info = snd_ak4113_spdif_info,
425 .get = snd_ak4113_spdif_get,
426},
427{
428 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
429 .name = "IEC958 Preample Capture Default",
430 .access = SNDRV_CTL_ELEM_ACCESS_READ |
431 SNDRV_CTL_ELEM_ACCESS_VOLATILE,
432 .info = snd_ak4113_spdif_pinfo,
433 .get = snd_ak4113_spdif_pget,
434},
435{
436 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
437 .name = "IEC958 Q-subcode Capture Default",
438 .access = SNDRV_CTL_ELEM_ACCESS_READ |
439 SNDRV_CTL_ELEM_ACCESS_VOLATILE,
440 .info = snd_ak4113_spdif_qinfo,
441 .get = snd_ak4113_spdif_qget,
442},
443{
444 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
445 .name = "IEC958 Audio",
446 .access = SNDRV_CTL_ELEM_ACCESS_READ |
447 SNDRV_CTL_ELEM_ACCESS_VOLATILE,
448 .info = snd_ak4113_in_bit_info,
449 .get = snd_ak4113_in_bit_get,
450 .private_value = (1<<31) | (1<<8) | AK4113_REG_RCS0,
451},
452{
453 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
454 .name = "IEC958 Non-PCM Bitstream",
455 .access = SNDRV_CTL_ELEM_ACCESS_READ |
456 SNDRV_CTL_ELEM_ACCESS_VOLATILE,
457 .info = snd_ak4113_in_bit_info,
458 .get = snd_ak4113_in_bit_get,
459 .private_value = (0<<8) | AK4113_REG_RCS1,
460},
461{
462 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
463 .name = "IEC958 DTS Bitstream",
464 .access = SNDRV_CTL_ELEM_ACCESS_READ |
465 SNDRV_CTL_ELEM_ACCESS_VOLATILE,
466 .info = snd_ak4113_in_bit_info,
467 .get = snd_ak4113_in_bit_get,
468 .private_value = (1<<8) | AK4113_REG_RCS1,
469},
470{
471 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
472 .name = "AK4113 Input Select",
473 .access = SNDRV_CTL_ELEM_ACCESS_READ |
474 SNDRV_CTL_ELEM_ACCESS_WRITE,
475 .info = snd_ak4113_rx_info,
476 .get = snd_ak4113_rx_get,
477 .put = snd_ak4113_rx_put,
478}
479};
480
481static void snd_ak4113_proc_regs_read(struct snd_info_entry *entry,
482 struct snd_info_buffer *buffer)
483{
484 struct ak4113 *ak4113 = entry->private_data;
485 int reg, val;
486 /* all ak4113 registers 0x00 - 0x1c */
487 for (reg = 0; reg < 0x1d; reg++) {
488 val = reg_read(ak4113, reg);
489 snd_iprintf(buffer, "0x%02x = 0x%02x\n", reg, val);
490 }
491}
492
493static void snd_ak4113_proc_init(struct ak4113 *ak4113)
494{
495 struct snd_info_entry *entry;
496 if (!snd_card_proc_new(ak4113->card, "ak4113", &entry))
497 snd_info_set_text_ops(entry, ak4113, snd_ak4113_proc_regs_read);
498}
499
500int snd_ak4113_build(struct ak4113 *ak4113,
501 struct snd_pcm_substream *cap_substream)
502{
503 struct snd_kcontrol *kctl;
504 unsigned int idx;
505 int err;
506
507 if (snd_BUG_ON(!cap_substream))
508 return -EINVAL;
509 ak4113->substream = cap_substream;
510 for (idx = 0; idx < AK4113_CONTROLS; idx++) {
511 kctl = snd_ctl_new1(&snd_ak4113_iec958_controls[idx], ak4113);
512 if (kctl == NULL)
513 return -ENOMEM;
514 kctl->id.device = cap_substream->pcm->device;
515 kctl->id.subdevice = cap_substream->number;
516 err = snd_ctl_add(ak4113->card, kctl);
517 if (err < 0)
518 return err;
519 ak4113->kctls[idx] = kctl;
520 }
521 snd_ak4113_proc_init(ak4113);
522 /* trigger workq */
523 schedule_delayed_work(&ak4113->work, HZ / 10);
524 return 0;
525}
526EXPORT_SYMBOL_GPL(snd_ak4113_build);
527
528int snd_ak4113_external_rate(struct ak4113 *ak4113)
529{
530 unsigned char rcs1;
531
532 rcs1 = reg_read(ak4113, AK4113_REG_RCS1);
533 return external_rate(rcs1);
534}
535EXPORT_SYMBOL_GPL(snd_ak4113_external_rate);
536
537int snd_ak4113_check_rate_and_errors(struct ak4113 *ak4113, unsigned int flags)
538{
539 struct snd_pcm_runtime *runtime =
540 ak4113->substream ? ak4113->substream->runtime : NULL;
541 unsigned long _flags;
542 int res = 0;
543 unsigned char rcs0, rcs1, rcs2;
544 unsigned char c0, c1;
545
546 rcs1 = reg_read(ak4113, AK4113_REG_RCS1);
547 if (flags & AK4113_CHECK_NO_STAT)
548 goto __rate;
549 rcs0 = reg_read(ak4113, AK4113_REG_RCS0);
550 rcs2 = reg_read(ak4113, AK4113_REG_RCS2);
551 spin_lock_irqsave(&ak4113->lock, _flags);
552 if (rcs0 & AK4113_PAR)
553 ak4113->parity_errors++;
554 if (rcs0 & AK4113_V)
555 ak4113->v_bit_errors++;
556 if (rcs2 & AK4113_CCRC)
557 ak4113->ccrc_errors++;
558 if (rcs2 & AK4113_QCRC)
559 ak4113->qcrc_errors++;
560 c0 = (ak4113->rcs0 & (AK4113_QINT | AK4113_CINT | AK4113_STC |
561 AK4113_AUDION | AK4113_AUTO | AK4113_UNLCK)) ^
562 (rcs0 & (AK4113_QINT | AK4113_CINT | AK4113_STC |
563 AK4113_AUDION | AK4113_AUTO | AK4113_UNLCK));
564 c1 = (ak4113->rcs1 & (AK4113_DTSCD | AK4113_NPCM | AK4113_PEM |
565 AK4113_DAT | 0xf0)) ^
566 (rcs1 & (AK4113_DTSCD | AK4113_NPCM | AK4113_PEM |
567 AK4113_DAT | 0xf0));
568 ak4113->rcs0 = rcs0 & ~(AK4113_QINT | AK4113_CINT | AK4113_STC);
569 ak4113->rcs1 = rcs1;
570 ak4113->rcs2 = rcs2;
571 spin_unlock_irqrestore(&ak4113->lock, _flags);
572
573 if (rcs0 & AK4113_PAR)
574 snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE,
575 &ak4113->kctls[0]->id);
576 if (rcs0 & AK4113_V)
577 snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE,
578 &ak4113->kctls[1]->id);
579 if (rcs2 & AK4113_CCRC)
580 snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE,
581 &ak4113->kctls[2]->id);
582 if (rcs2 & AK4113_QCRC)
583 snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE,
584 &ak4113->kctls[3]->id);
585
586 /* rate change */
587 if (c1 & 0xf0)
588 snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE,
589 &ak4113->kctls[4]->id);
590
591 if ((c1 & AK4113_PEM) | (c0 & AK4113_CINT))
592 snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE,
593 &ak4113->kctls[6]->id);
594 if (c0 & AK4113_QINT)
595 snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE,
596 &ak4113->kctls[8]->id);
597
598 if (c0 & AK4113_AUDION)
599 snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE,
600 &ak4113->kctls[9]->id);
601 if (c1 & AK4113_NPCM)
602 snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE,
603 &ak4113->kctls[10]->id);
604 if (c1 & AK4113_DTSCD)
605 snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE,
606 &ak4113->kctls[11]->id);
607
608 if (ak4113->change_callback && (c0 | c1) != 0)
609 ak4113->change_callback(ak4113, c0, c1);
610
611__rate:
612 /* compare rate */
613 res = external_rate(rcs1);
614 if (!(flags & AK4113_CHECK_NO_RATE) && runtime &&
615 (runtime->rate != res)) {
616 snd_pcm_stream_lock_irqsave(ak4113->substream, _flags);
617 if (snd_pcm_running(ak4113->substream)) {
618 /*printk(KERN_DEBUG "rate changed (%i <- %i)\n",
619 * runtime->rate, res); */
620 snd_pcm_stop(ak4113->substream,
621 SNDRV_PCM_STATE_DRAINING);
622 wake_up(&runtime->sleep);
623 res = 1;
624 }
625 snd_pcm_stream_unlock_irqrestore(ak4113->substream, _flags);
626 }
627 return res;
628}
629EXPORT_SYMBOL_GPL(snd_ak4113_check_rate_and_errors);
630
631static void ak4113_stats(struct work_struct *work)
632{
633 struct ak4113 *chip = container_of(work, struct ak4113, work.work);
634
635 if (!chip->init)
636 snd_ak4113_check_rate_and_errors(chip, chip->check_flags);
637
638 schedule_delayed_work(&chip->work, HZ / 10);
639}
diff --git a/sound/i2c/other/ak4xxx-adda.c b/sound/i2c/other/ak4xxx-adda.c
index ee47abab764e..1adb8a3c2b62 100644
--- a/sound/i2c/other/ak4xxx-adda.c
+++ b/sound/i2c/other/ak4xxx-adda.c
@@ -19,7 +19,7 @@
19 * along with this program; if not, write to the Free Software 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 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 * 21 *
22 */ 22 */
23 23
24#include <asm/io.h> 24#include <asm/io.h>
25#include <linux/delay.h> 25#include <linux/delay.h>
@@ -29,6 +29,7 @@
29#include <sound/control.h> 29#include <sound/control.h>
30#include <sound/tlv.h> 30#include <sound/tlv.h>
31#include <sound/ak4xxx-adda.h> 31#include <sound/ak4xxx-adda.h>
32#include <sound/info.h>
32 33
33MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, Takashi Iwai <tiwai@suse.de>"); 34MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, Takashi Iwai <tiwai@suse.de>");
34MODULE_DESCRIPTION("Routines for control of AK452x / AK43xx AD/DA converters"); 35MODULE_DESCRIPTION("Routines for control of AK452x / AK43xx AD/DA converters");
@@ -52,26 +53,21 @@ EXPORT_SYMBOL(snd_akm4xxx_write);
52static void ak4524_reset(struct snd_akm4xxx *ak, int state) 53static void ak4524_reset(struct snd_akm4xxx *ak, int state)
53{ 54{
54 unsigned int chip; 55 unsigned int chip;
55 unsigned char reg, maxreg; 56 unsigned char reg;
56 57
57 if (ak->type == SND_AK4528)
58 maxreg = 0x06;
59 else
60 maxreg = 0x08;
61 for (chip = 0; chip < ak->num_dacs/2; chip++) { 58 for (chip = 0; chip < ak->num_dacs/2; chip++) {
62 snd_akm4xxx_write(ak, chip, 0x01, state ? 0x00 : 0x03); 59 snd_akm4xxx_write(ak, chip, 0x01, state ? 0x00 : 0x03);
63 if (state) 60 if (state)
64 continue; 61 continue;
65 /* DAC volumes */ 62 /* DAC volumes */
66 for (reg = 0x04; reg < maxreg; reg++) 63 for (reg = 0x04; reg < ak->total_regs; reg++)
67 snd_akm4xxx_write(ak, chip, reg, 64 snd_akm4xxx_write(ak, chip, reg,
68 snd_akm4xxx_get(ak, chip, reg)); 65 snd_akm4xxx_get(ak, chip, reg));
69 } 66 }
70} 67}
71 68
72/* reset procedure for AK4355 and AK4358 */ 69/* reset procedure for AK4355 and AK4358 */
73static void ak435X_reset(struct snd_akm4xxx *ak, int state, 70static void ak435X_reset(struct snd_akm4xxx *ak, int state)
74 unsigned char total_regs)
75{ 71{
76 unsigned char reg; 72 unsigned char reg;
77 73
@@ -79,7 +75,7 @@ static void ak435X_reset(struct snd_akm4xxx *ak, int state,
79 snd_akm4xxx_write(ak, 0, 0x01, 0x02); /* reset and soft-mute */ 75 snd_akm4xxx_write(ak, 0, 0x01, 0x02); /* reset and soft-mute */
80 return; 76 return;
81 } 77 }
82 for (reg = 0x00; reg < total_regs; reg++) 78 for (reg = 0x00; reg < ak->total_regs; reg++)
83 if (reg != 0x01) 79 if (reg != 0x01)
84 snd_akm4xxx_write(ak, 0, reg, 80 snd_akm4xxx_write(ak, 0, reg,
85 snd_akm4xxx_get(ak, 0, reg)); 81 snd_akm4xxx_get(ak, 0, reg));
@@ -91,12 +87,11 @@ static void ak4381_reset(struct snd_akm4xxx *ak, int state)
91{ 87{
92 unsigned int chip; 88 unsigned int chip;
93 unsigned char reg; 89 unsigned char reg;
94
95 for (chip = 0; chip < ak->num_dacs/2; chip++) { 90 for (chip = 0; chip < ak->num_dacs/2; chip++) {
96 snd_akm4xxx_write(ak, chip, 0x00, state ? 0x0c : 0x0f); 91 snd_akm4xxx_write(ak, chip, 0x00, state ? 0x0c : 0x0f);
97 if (state) 92 if (state)
98 continue; 93 continue;
99 for (reg = 0x01; reg < 0x05; reg++) 94 for (reg = 0x01; reg < ak->total_regs; reg++)
100 snd_akm4xxx_write(ak, chip, reg, 95 snd_akm4xxx_write(ak, chip, reg,
101 snd_akm4xxx_get(ak, chip, reg)); 96 snd_akm4xxx_get(ak, chip, reg));
102 } 97 }
@@ -113,16 +108,17 @@ void snd_akm4xxx_reset(struct snd_akm4xxx *ak, int state)
113 switch (ak->type) { 108 switch (ak->type) {
114 case SND_AK4524: 109 case SND_AK4524:
115 case SND_AK4528: 110 case SND_AK4528:
111 case SND_AK4620:
116 ak4524_reset(ak, state); 112 ak4524_reset(ak, state);
117 break; 113 break;
118 case SND_AK4529: 114 case SND_AK4529:
119 /* FIXME: needed for ak4529? */ 115 /* FIXME: needed for ak4529? */
120 break; 116 break;
121 case SND_AK4355: 117 case SND_AK4355:
122 ak435X_reset(ak, state, 0x0b); 118 ak435X_reset(ak, state);
123 break; 119 break;
124 case SND_AK4358: 120 case SND_AK4358:
125 ak435X_reset(ak, state, 0x10); 121 ak435X_reset(ak, state);
126 break; 122 break;
127 case SND_AK4381: 123 case SND_AK4381:
128 ak4381_reset(ak, state); 124 ak4381_reset(ak, state);
@@ -139,7 +135,7 @@ EXPORT_SYMBOL(snd_akm4xxx_reset);
139 * Volume conversion table for non-linear volumes 135 * Volume conversion table for non-linear volumes
140 * from -63.5dB (mute) to 0dB step 0.5dB 136 * from -63.5dB (mute) to 0dB step 0.5dB
141 * 137 *
142 * Used for AK4524 input/ouput attenuation, AK4528, and 138 * Used for AK4524/AK4620 input/ouput attenuation, AK4528, and
143 * AK5365 input attenuation 139 * AK5365 input attenuation
144 */ 140 */
145static const unsigned char vol_cvt_datt[128] = { 141static const unsigned char vol_cvt_datt[128] = {
@@ -259,8 +255,22 @@ void snd_akm4xxx_init(struct snd_akm4xxx *ak)
259 0x00, 0x0f, /* 0: power-up, un-reset */ 255 0x00, 0x0f, /* 0: power-up, un-reset */
260 0xff, 0xff 256 0xff, 0xff
261 }; 257 };
258 static const unsigned char inits_ak4620[] = {
259 0x00, 0x07, /* 0: normal */
260 0x01, 0x00, /* 0: reset */
261 0x01, 0x02, /* 1: RSTAD */
262 0x01, 0x03, /* 1: RSTDA */
263 0x01, 0x0f, /* 1: normal */
264 0x02, 0x60, /* 2: 24bit I2S */
265 0x03, 0x01, /* 3: deemphasis off */
266 0x04, 0x00, /* 4: LIN muted */
267 0x05, 0x00, /* 5: RIN muted */
268 0x06, 0x00, /* 6: LOUT muted */
269 0x07, 0x00, /* 7: ROUT muted */
270 0xff, 0xff
271 };
262 272
263 int chip, num_chips; 273 int chip;
264 const unsigned char *ptr, *inits; 274 const unsigned char *ptr, *inits;
265 unsigned char reg, data; 275 unsigned char reg, data;
266 276
@@ -270,42 +280,64 @@ void snd_akm4xxx_init(struct snd_akm4xxx *ak)
270 switch (ak->type) { 280 switch (ak->type) {
271 case SND_AK4524: 281 case SND_AK4524:
272 inits = inits_ak4524; 282 inits = inits_ak4524;
273 num_chips = ak->num_dacs / 2; 283 ak->num_chips = ak->num_dacs / 2;
284 ak->name = "ak4524";
285 ak->total_regs = 0x08;
274 break; 286 break;
275 case SND_AK4528: 287 case SND_AK4528:
276 inits = inits_ak4528; 288 inits = inits_ak4528;
277 num_chips = ak->num_dacs / 2; 289 ak->num_chips = ak->num_dacs / 2;
290 ak->name = "ak4528";
291 ak->total_regs = 0x06;
278 break; 292 break;
279 case SND_AK4529: 293 case SND_AK4529:
280 inits = inits_ak4529; 294 inits = inits_ak4529;
281 num_chips = 1; 295 ak->num_chips = 1;
296 ak->name = "ak4529";
297 ak->total_regs = 0x0d;
282 break; 298 break;
283 case SND_AK4355: 299 case SND_AK4355:
284 inits = inits_ak4355; 300 inits = inits_ak4355;
285 num_chips = 1; 301 ak->num_chips = 1;
302 ak->name = "ak4355";
303 ak->total_regs = 0x0b;
286 break; 304 break;
287 case SND_AK4358: 305 case SND_AK4358:
288 inits = inits_ak4358; 306 inits = inits_ak4358;
289 num_chips = 1; 307 ak->num_chips = 1;
308 ak->name = "ak4358";
309 ak->total_regs = 0x10;
290 break; 310 break;
291 case SND_AK4381: 311 case SND_AK4381:
292 inits = inits_ak4381; 312 inits = inits_ak4381;
293 num_chips = ak->num_dacs / 2; 313 ak->num_chips = ak->num_dacs / 2;
314 ak->name = "ak4381";
315 ak->total_regs = 0x05;
294 break; 316 break;
295 case SND_AK5365: 317 case SND_AK5365:
296 /* FIXME: any init sequence? */ 318 /* FIXME: any init sequence? */
319 ak->num_chips = 1;
320 ak->name = "ak5365";
321 ak->total_regs = 0x08;
297 return; 322 return;
323 case SND_AK4620:
324 inits = inits_ak4620;
325 ak->num_chips = ak->num_dacs / 2;
326 ak->name = "ak4620";
327 ak->total_regs = 0x08;
328 break;
298 default: 329 default:
299 snd_BUG(); 330 snd_BUG();
300 return; 331 return;
301 } 332 }
302 333
303 for (chip = 0; chip < num_chips; chip++) { 334 for (chip = 0; chip < ak->num_chips; chip++) {
304 ptr = inits; 335 ptr = inits;
305 while (*ptr != 0xff) { 336 while (*ptr != 0xff) {
306 reg = *ptr++; 337 reg = *ptr++;
307 data = *ptr++; 338 data = *ptr++;
308 snd_akm4xxx_write(ak, chip, reg, data); 339 snd_akm4xxx_write(ak, chip, reg, data);
340 udelay(10);
309 } 341 }
310 } 342 }
311} 343}
@@ -688,6 +720,12 @@ static int build_dac_controls(struct snd_akm4xxx *ak)
688 AK_COMPOSE(idx/2, (idx%2) + 3, 0, 255); 720 AK_COMPOSE(idx/2, (idx%2) + 3, 0, 255);
689 knew.tlv.p = db_scale_linear; 721 knew.tlv.p = db_scale_linear;
690 break; 722 break;
723 case SND_AK4620:
724 /* register 6 & 7 */
725 knew.private_value =
726 AK_COMPOSE(idx/2, (idx%2) + 6, 0, 255);
727 knew.tlv.p = db_scale_linear;
728 break;
691 default: 729 default:
692 return -EINVAL; 730 return -EINVAL;
693 } 731 }
@@ -704,10 +742,12 @@ static int build_dac_controls(struct snd_akm4xxx *ak)
704 742
705static int build_adc_controls(struct snd_akm4xxx *ak) 743static int build_adc_controls(struct snd_akm4xxx *ak)
706{ 744{
707 int idx, err, mixer_ch, num_stereo; 745 int idx, err, mixer_ch, num_stereo, max_steps;
708 struct snd_kcontrol_new knew; 746 struct snd_kcontrol_new knew;
709 747
710 mixer_ch = 0; 748 mixer_ch = 0;
749 if (ak->type == SND_AK4528)
750 return 0; /* no controls */
711 for (idx = 0; idx < ak->num_adcs;) { 751 for (idx = 0; idx < ak->num_adcs;) {
712 memset(&knew, 0, sizeof(knew)); 752 memset(&knew, 0, sizeof(knew));
713 if (! ak->adc_info || ! ak->adc_info[mixer_ch].name) { 753 if (! ak->adc_info || ! ak->adc_info[mixer_ch].name) {
@@ -733,13 +773,12 @@ static int build_adc_controls(struct snd_akm4xxx *ak)
733 } 773 }
734 /* register 4 & 5 */ 774 /* register 4 & 5 */
735 if (ak->type == SND_AK5365) 775 if (ak->type == SND_AK5365)
736 knew.private_value = 776 max_steps = 152;
737 AK_COMPOSE(idx/2, (idx%2) + 4, 0, 151) |
738 AK_VOL_CVT | AK_IPGA;
739 else 777 else
740 knew.private_value = 778 max_steps = 164;
741 AK_COMPOSE(idx/2, (idx%2) + 4, 0, 163) | 779 knew.private_value =
742 AK_VOL_CVT | AK_IPGA; 780 AK_COMPOSE(idx/2, (idx%2) + 4, 0, max_steps) |
781 AK_VOL_CVT | AK_IPGA;
743 knew.tlv.p = db_scale_vol_datt; 782 knew.tlv.p = db_scale_vol_datt;
744 err = snd_ctl_add(ak->card, snd_ctl_new1(&knew, ak)); 783 err = snd_ctl_add(ak->card, snd_ctl_new1(&knew, ak));
745 if (err < 0) 784 if (err < 0)
@@ -808,6 +847,7 @@ static int build_deemphasis(struct snd_akm4xxx *ak, int num_emphs)
808 switch (ak->type) { 847 switch (ak->type) {
809 case SND_AK4524: 848 case SND_AK4524:
810 case SND_AK4528: 849 case SND_AK4528:
850 case SND_AK4620:
811 /* register 3 */ 851 /* register 3 */
812 knew.private_value = AK_COMPOSE(idx, 3, 0, 0); 852 knew.private_value = AK_COMPOSE(idx, 3, 0, 0);
813 break; 853 break;
@@ -834,6 +874,35 @@ static int build_deemphasis(struct snd_akm4xxx *ak, int num_emphs)
834 return 0; 874 return 0;
835} 875}
836 876
877#ifdef CONFIG_PROC_FS
878static void proc_regs_read(struct snd_info_entry *entry,
879 struct snd_info_buffer *buffer)
880{
881 struct snd_akm4xxx *ak = (struct snd_akm4xxx *)entry->private_data;
882 int reg, val, chip;
883 for (chip = 0; chip < ak->num_chips; chip++) {
884 for (reg = 0; reg < ak->total_regs; reg++) {
885 val = snd_akm4xxx_get(ak, chip, reg);
886 snd_iprintf(buffer, "chip %d: 0x%02x = 0x%02x\n", chip,
887 reg, val);
888 }
889 }
890}
891
892static int proc_init(struct snd_akm4xxx *ak)
893{
894 struct snd_info_entry *entry;
895 int err;
896 err = snd_card_proc_new(ak->card, ak->name, &entry);
897 if (err < 0)
898 return err;
899 snd_info_set_text_ops(entry, ak, proc_regs_read);
900 return 0;
901}
902#else /* !CONFIG_PROC_FS */
903static int proc_init(struct snd_akm4xxx *ak) {}
904#endif
905
837int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak) 906int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak)
838{ 907{
839 int err, num_emphs; 908 int err, num_emphs;
@@ -845,18 +914,21 @@ int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak)
845 err = build_adc_controls(ak); 914 err = build_adc_controls(ak);
846 if (err < 0) 915 if (err < 0)
847 return err; 916 return err;
848
849 if (ak->type == SND_AK4355 || ak->type == SND_AK4358) 917 if (ak->type == SND_AK4355 || ak->type == SND_AK4358)
850 num_emphs = 1; 918 num_emphs = 1;
919 else if (ak->type == SND_AK4620)
920 num_emphs = 0;
851 else 921 else
852 num_emphs = ak->num_dacs / 2; 922 num_emphs = ak->num_dacs / 2;
853 err = build_deemphasis(ak, num_emphs); 923 err = build_deemphasis(ak, num_emphs);
854 if (err < 0) 924 if (err < 0)
855 return err; 925 return err;
926 err = proc_init(ak);
927 if (err < 0)
928 return err;
856 929
857 return 0; 930 return 0;
858} 931}
859
860EXPORT_SYMBOL(snd_akm4xxx_build_controls); 932EXPORT_SYMBOL(snd_akm4xxx_build_controls);
861 933
862static int __init alsa_akm4xxx_module_init(void) 934static int __init alsa_akm4xxx_module_init(void)
diff --git a/sound/i2c/other/tea575x-tuner.c b/sound/i2c/other/tea575x-tuner.c
index d31c373e076d..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>
@@ -225,7 +226,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
225 case V4L2_CID_AUDIO_MUTE: 226 case V4L2_CID_AUDIO_MUTE:
226 if (tea->ops->mute) { 227 if (tea->ops->mute) {
227 tea->ops->mute(tea, ctrl->value); 228 tea->ops->mute(tea, ctrl->value);
228 tea->mute = 1; 229 tea->mute = ctrl->value;
229 return 0; 230 return 0;
230 } 231 }
231 } 232 }
diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig
index 51a7e3777e17..755a0a5f0e3f 100644
--- a/sound/isa/Kconfig
+++ b/sound/isa/Kconfig
@@ -63,15 +63,16 @@ config SND_AD1848
63 will be called snd-ad1848. 63 will be called snd-ad1848.
64 64
65config SND_ALS100 65config SND_ALS100
66 tristate "Avance Logic ALS100/ALS120" 66 tristate "Diamond Tech. DT-019x and Avance Logic ALSxxx"
67 depends on PNP 67 depends on PNP
68 select ISAPNP 68 select ISAPNP
69 select SND_OPL3_LIB 69 select SND_OPL3_LIB
70 select SND_MPU401_UART 70 select SND_MPU401_UART
71 select SND_SB16_DSP 71 select SND_SB16_DSP
72 help 72 help
73 Say Y here to include support for soundcards based on Avance 73 Say Y here to include support for soundcards based on the
74 Logic ALS100, ALS110, ALS120 and ALS200 chips. 74 Diamond Technologies DT-019X or Avance Logic chips: ALS007,
75 ALS100, ALS110, ALS120 and ALS200 chips.
75 76
76 To compile this driver as a module, choose M here: the module 77 To compile this driver as a module, choose M here: the module
77 will be called snd-als100. 78 will be called snd-als100.
@@ -127,20 +128,6 @@ config SND_CS4236
127 To compile this driver as a module, choose M here: the module 128 To compile this driver as a module, choose M here: the module
128 will be called snd-cs4236. 129 will be called snd-cs4236.
129 130
130config SND_DT019X
131 tristate "Diamond Technologies DT-019X, Avance Logic ALS-007"
132 depends on PNP
133 select ISAPNP
134 select SND_OPL3_LIB
135 select SND_MPU401_UART
136 select SND_SB16_DSP
137 help
138 Say Y here to include support for soundcards based on the
139 Diamond Technologies DT-019X or Avance Logic ALS-007 chips.
140
141 To compile this driver as a module, choose M here: the module
142 will be called snd-dt019x.
143
144config SND_ES968 131config SND_ES968
145 tristate "Generic ESS ES968 driver" 132 tristate "Generic ESS ES968 driver"
146 depends on PNP 133 depends on PNP
@@ -252,6 +239,22 @@ config SND_INTERWAVE_STB
252 To compile this driver as a module, choose M here: the module 239 To compile this driver as a module, choose M here: the module
253 will be called snd-interwave-stb. 240 will be called snd-interwave-stb.
254 241
242config SND_JAZZ16
243 tristate "Media Vision Jazz16 card and compatibles"
244 select SND_OPL3_LIB
245 select SND_MPU401_UART
246 select SND_SB8_DSP
247 help
248 Say Y here to include support for soundcards based on the
249 Media Vision Jazz16 chipset: digital chip MVD1216 (Jazz16),
250 codec MVA416 (CS4216) and mixer MVA514 (ICS2514).
251 Media Vision's Jazz16 cards were sold under names Pro Sonic 16,
252 Premium 3-D and Pro 3-D. There were also OEMs cards with the
253 Jazz16 chipset.
254
255 To compile this driver as a module, choose M here: the module
256 will be called snd-jazz16.
257
255config SND_OPL3SA2 258config SND_OPL3SA2
256 tristate "Yamaha OPL3-SA2/SA3" 259 tristate "Yamaha OPL3-SA2/SA3"
257 select SND_OPL3_LIB 260 select SND_OPL3_LIB
@@ -372,15 +375,21 @@ config SND_SGALAXY
372 375
373config SND_SSCAPE 376config SND_SSCAPE
374 tristate "Ensoniq SoundScape driver" 377 tristate "Ensoniq SoundScape driver"
375 select SND_HWDEP
376 select SND_MPU401_UART 378 select SND_MPU401_UART
377 select SND_WSS_LIB 379 select SND_WSS_LIB
380 select FW_LOADER
378 help 381 help
379 Say Y here to include support for Ensoniq SoundScape 382 Say Y here to include support for Ensoniq SoundScape
380 soundcards. 383 and Ensoniq OEM soundcards.
381 384
382 The PCM audio is supported on SoundScape Classic, Elite, PnP 385 The PCM audio is supported on SoundScape Classic, Elite, PnP
383 and VIVO cards. The MIDI support is very experimental. 386 and VIVO cards. The supported OEM cards are SPEA Media FX and
387 Reveal SC-600.
388 The MIDI support is very experimental and requires binary
389 firmware files called "scope.cod" and "sndscape.co?" where the
390 ? is digit 0, 1, 2, 3 or 4. The firmware files can be found
391 in DOS or Windows driver packages. One has to put the firmware
392 files into the /lib/firmware directory.
384 393
385 To compile this driver as a module, choose M here: the module 394 To compile this driver as a module, choose M here: the module
386 will be called snd-sscape. 395 will be called snd-sscape.
diff --git a/sound/isa/Makefile b/sound/isa/Makefile
index b906b9a1a81e..c73d30c4f462 100644
--- a/sound/isa/Makefile
+++ b/sound/isa/Makefile
@@ -7,7 +7,6 @@ snd-adlib-objs := adlib.o
7snd-als100-objs := als100.o 7snd-als100-objs := als100.o
8snd-azt2320-objs := azt2320.o 8snd-azt2320-objs := azt2320.o
9snd-cmi8330-objs := cmi8330.o 9snd-cmi8330-objs := cmi8330.o
10snd-dt019x-objs := dt019x.o
11snd-es18xx-objs := es18xx.o 10snd-es18xx-objs := es18xx.o
12snd-opl3sa2-objs := opl3sa2.o 11snd-opl3sa2-objs := opl3sa2.o
13snd-sc6000-objs := sc6000.o 12snd-sc6000-objs := sc6000.o
@@ -19,7 +18,6 @@ obj-$(CONFIG_SND_ADLIB) += snd-adlib.o
19obj-$(CONFIG_SND_ALS100) += snd-als100.o 18obj-$(CONFIG_SND_ALS100) += snd-als100.o
20obj-$(CONFIG_SND_AZT2320) += snd-azt2320.o 19obj-$(CONFIG_SND_AZT2320) += snd-azt2320.o
21obj-$(CONFIG_SND_CMI8330) += snd-cmi8330.o 20obj-$(CONFIG_SND_CMI8330) += snd-cmi8330.o
22obj-$(CONFIG_SND_DT019X) += snd-dt019x.o
23obj-$(CONFIG_SND_ES18XX) += snd-es18xx.o 21obj-$(CONFIG_SND_ES18XX) += snd-es18xx.o
24obj-$(CONFIG_SND_OPL3SA2) += snd-opl3sa2.o 22obj-$(CONFIG_SND_OPL3SA2) += snd-opl3sa2.o
25obj-$(CONFIG_SND_SC6000) += snd-sc6000.o 23obj-$(CONFIG_SND_SC6000) += snd-sc6000.o
diff --git a/sound/isa/als100.c b/sound/isa/als100.c
index 5fd52e4d7079..20becc89f6f6 100644
--- a/sound/isa/als100.c
+++ b/sound/isa/als100.c
@@ -2,9 +2,13 @@
2/* 2/*
3 card-als100.c - driver for Avance Logic ALS100 based soundcards. 3 card-als100.c - driver for Avance Logic ALS100 based soundcards.
4 Copyright (C) 1999-2000 by Massimo Piccioni <dafastidio@libero.it> 4 Copyright (C) 1999-2000 by Massimo Piccioni <dafastidio@libero.it>
5 Copyright (C) 1999-2002 by Massimo Piccioni <dafastidio@libero.it>
5 6
6 Thanks to Pierfrancesco 'qM2' Passerini. 7 Thanks to Pierfrancesco 'qM2' Passerini.
7 8
9 Generalised for soundcards based on DT-0196 and ALS-007 chips
10 by Jonathan Woithe <jwoithe@physics.adelaide.edu.au>: June 2002.
11
8 This program is free software; you can redistribute it and/or modify 12 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by 13 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or 14 the Free Software Foundation; either version 2 of the License, or
@@ -33,10 +37,10 @@
33 37
34#define PFX "als100: " 38#define PFX "als100: "
35 39
36MODULE_AUTHOR("Massimo Piccioni <dafastidio@libero.it>"); 40MODULE_DESCRIPTION("Avance Logic ALS007/ALS1X0");
37MODULE_DESCRIPTION("Avance Logic ALS1X0"); 41MODULE_SUPPORTED_DEVICE("{{Diamond Technologies DT-019X},"
38MODULE_LICENSE("GPL"); 42 "{Avance Logic ALS-007}}"
39MODULE_SUPPORTED_DEVICE("{{Avance Logic,ALS100 - PRO16PNP}," 43 "{{Avance Logic,ALS100 - PRO16PNP},"
40 "{Avance Logic,ALS110}," 44 "{Avance Logic,ALS110},"
41 "{Avance Logic,ALS120}," 45 "{Avance Logic,ALS120},"
42 "{Avance Logic,ALS200}," 46 "{Avance Logic,ALS200},"
@@ -45,9 +49,12 @@ MODULE_SUPPORTED_DEVICE("{{Avance Logic,ALS100 - PRO16PNP},"
45 "{Avance Logic,ALS120}," 49 "{Avance Logic,ALS120},"
46 "{RTL,RTL3000}}"); 50 "{RTL,RTL3000}}");
47 51
52MODULE_AUTHOR("Massimo Piccioni <dafastidio@libero.it>");
53MODULE_LICENSE("GPL");
54
48static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ 55static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
49static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ 56static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
50static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */ 57static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
51static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */ 58static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
52static long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */ 59static long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
53static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */ 60static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
@@ -57,14 +64,15 @@ static int dma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* PnP setup */
57static int dma16[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* PnP setup */ 64static int dma16[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* PnP setup */
58 65
59module_param_array(index, int, NULL, 0444); 66module_param_array(index, int, NULL, 0444);
60MODULE_PARM_DESC(index, "Index value for als100 based soundcard."); 67MODULE_PARM_DESC(index, "Index value for Avance Logic based soundcard.");
61module_param_array(id, charp, NULL, 0444); 68module_param_array(id, charp, NULL, 0444);
62MODULE_PARM_DESC(id, "ID string for als100 based soundcard."); 69MODULE_PARM_DESC(id, "ID string for Avance Logic based soundcard.");
63module_param_array(enable, bool, NULL, 0444); 70module_param_array(enable, bool, NULL, 0444);
64MODULE_PARM_DESC(enable, "Enable als100 based soundcard."); 71MODULE_PARM_DESC(enable, "Enable Avance Logic based soundcard.");
72
73MODULE_ALIAS("snd-dt019x");
65 74
66struct snd_card_als100 { 75struct snd_card_als100 {
67 int dev_no;
68 struct pnp_dev *dev; 76 struct pnp_dev *dev;
69 struct pnp_dev *devmpu; 77 struct pnp_dev *devmpu;
70 struct pnp_dev *devopl; 78 struct pnp_dev *devopl;
@@ -72,25 +80,43 @@ struct snd_card_als100 {
72}; 80};
73 81
74static struct pnp_card_device_id snd_als100_pnpids[] = { 82static struct pnp_card_device_id snd_als100_pnpids[] = {
83 /* DT197A30 */
84 { .id = "RWB1688",
85 .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" } },
86 .driver_data = SB_HW_DT019X },
87 /* DT0196 / ALS-007 */
88 { .id = "ALS0007",
89 .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" } },
90 .driver_data = SB_HW_DT019X },
75 /* ALS100 - PRO16PNP */ 91 /* ALS100 - PRO16PNP */
76 { .id = "ALS0001", .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" } } }, 92 { .id = "ALS0001",
93 .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" } },
94 .driver_data = SB_HW_ALS100 },
77 /* ALS110 - MF1000 - Digimate 3D Sound */ 95 /* ALS110 - MF1000 - Digimate 3D Sound */
78 { .id = "ALS0110", .devs = { { "@@@1001" }, { "@X@1001" }, { "@H@1001" } } }, 96 { .id = "ALS0110",
97 .devs = { { "@@@1001" }, { "@X@1001" }, { "@H@1001" } },
98 .driver_data = SB_HW_ALS100 },
79 /* ALS120 */ 99 /* ALS120 */
80 { .id = "ALS0120", .devs = { { "@@@2001" }, { "@X@2001" }, { "@H@2001" } } }, 100 { .id = "ALS0120",
101 .devs = { { "@@@2001" }, { "@X@2001" }, { "@H@2001" } },
102 .driver_data = SB_HW_ALS100 },
81 /* ALS200 */ 103 /* ALS200 */
82 { .id = "ALS0200", .devs = { { "@@@0020" }, { "@X@0020" }, { "@H@0001" } } }, 104 { .id = "ALS0200",
105 .devs = { { "@@@0020" }, { "@X@0020" }, { "@H@0001" } },
106 .driver_data = SB_HW_ALS100 },
83 /* ALS200 OEM */ 107 /* ALS200 OEM */
84 { .id = "ALS0200", .devs = { { "@@@0020" }, { "@X@0020" }, { "@H@0020" } } }, 108 { .id = "ALS0200",
109 .devs = { { "@@@0020" }, { "@X@0020" }, { "@H@0020" } },
110 .driver_data = SB_HW_ALS100 },
85 /* RTL3000 */ 111 /* RTL3000 */
86 { .id = "RTL3000", .devs = { { "@@@2001" }, { "@X@2001" }, { "@H@2001" } } }, 112 { .id = "RTL3000",
87 { .id = "", } /* end */ 113 .devs = { { "@@@2001" }, { "@X@2001" }, { "@H@2001" } },
114 .driver_data = SB_HW_ALS100 },
115 { .id = "" } /* end */
88}; 116};
89 117
90MODULE_DEVICE_TABLE(pnp_card, snd_als100_pnpids); 118MODULE_DEVICE_TABLE(pnp_card, snd_als100_pnpids);
91 119
92#define DRIVER_NAME "snd-card-als100"
93
94static int __devinit snd_card_als100_pnp(int dev, struct snd_card_als100 *acard, 120static int __devinit snd_card_als100_pnp(int dev, struct snd_card_als100 *acard,
95 struct pnp_card_link *card, 121 struct pnp_card_link *card,
96 const struct pnp_card_device_id *id) 122 const struct pnp_card_device_id *id)
@@ -113,8 +139,12 @@ static int __devinit snd_card_als100_pnp(int dev, struct snd_card_als100 *acard,
113 return err; 139 return err;
114 } 140 }
115 port[dev] = pnp_port_start(pdev, 0); 141 port[dev] = pnp_port_start(pdev, 0);
116 dma8[dev] = pnp_dma(pdev, 1); 142 if (id->driver_data == SB_HW_DT019X)
117 dma16[dev] = pnp_dma(pdev, 0); 143 dma8[dev] = pnp_dma(pdev, 0);
144 else {
145 dma8[dev] = pnp_dma(pdev, 1);
146 dma16[dev] = pnp_dma(pdev, 0);
147 }
118 irq[dev] = pnp_irq(pdev, 0); 148 irq[dev] = pnp_irq(pdev, 0);
119 149
120 pdev = acard->devmpu; 150 pdev = acard->devmpu;
@@ -175,22 +205,33 @@ static int __devinit snd_card_als100_probe(int dev,
175 } 205 }
176 snd_card_set_dev(card, &pcard->card->dev); 206 snd_card_set_dev(card, &pcard->card->dev);
177 207
178 if ((error = snd_sbdsp_create(card, port[dev], 208 if (pid->driver_data == SB_HW_DT019X)
179 irq[dev], 209 dma16[dev] = -1;
180 snd_sb16dsp_interrupt, 210
181 dma8[dev], 211 error = snd_sbdsp_create(card, port[dev], irq[dev],
182 dma16[dev], 212 snd_sb16dsp_interrupt,
183 SB_HW_ALS100, &chip)) < 0) { 213 dma8[dev], dma16[dev],
214 pid->driver_data,
215 &chip);
216 if (error < 0) {
184 snd_card_free(card); 217 snd_card_free(card);
185 return error; 218 return error;
186 } 219 }
187 acard->chip = chip; 220 acard->chip = chip;
188 221
189 strcpy(card->driver, "ALS100"); 222 if (pid->driver_data == SB_HW_DT019X) {
190 strcpy(card->shortname, "Avance Logic ALS100"); 223 strcpy(card->driver, "DT-019X");
191 sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d&%d", 224 strcpy(card->shortname, "Diamond Tech. DT-019X");
192 card->shortname, chip->name, chip->port, 225 sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d",
193 irq[dev], dma8[dev], dma16[dev]); 226 card->shortname, chip->name, chip->port,
227 irq[dev], dma8[dev]);
228 } else {
229 strcpy(card->driver, "ALS100");
230 strcpy(card->shortname, "Avance Logic ALS100");
231 sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d&%d",
232 card->shortname, chip->name, chip->port,
233 irq[dev], dma8[dev], dma16[dev]);
234 }
194 235
195 if ((error = snd_sb16dsp_pcm(chip, 0, NULL)) < 0) { 236 if ((error = snd_sb16dsp_pcm(chip, 0, NULL)) < 0) {
196 snd_card_free(card); 237 snd_card_free(card);
@@ -203,9 +244,19 @@ static int __devinit snd_card_als100_probe(int dev,
203 } 244 }
204 245
205 if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) { 246 if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) {
206 if (snd_mpu401_uart_new(card, 0, MPU401_HW_ALS100, 247 int mpu_type = MPU401_HW_ALS100;
248
249 if (mpu_irq[dev] == SNDRV_AUTO_IRQ)
250 mpu_irq[dev] = -1;
251
252 if (pid->driver_data == SB_HW_DT019X)
253 mpu_type = MPU401_HW_MPU401;
254
255 if (snd_mpu401_uart_new(card, 0,
256 mpu_type,
207 mpu_port[dev], 0, 257 mpu_port[dev], 0,
208 mpu_irq[dev], IRQF_DISABLED, 258 mpu_irq[dev],
259 mpu_irq[dev] >= 0 ? IRQF_DISABLED : 0,
209 NULL) < 0) 260 NULL) < 0)
210 snd_printk(KERN_ERR PFX "no MPU-401 device at 0x%lx\n", mpu_port[dev]); 261 snd_printk(KERN_ERR PFX "no MPU-401 device at 0x%lx\n", mpu_port[dev]);
211 } 262 }
@@ -291,7 +342,7 @@ static int snd_als100_pnp_resume(struct pnp_card_link *pcard)
291 342
292static struct pnp_card_driver als100_pnpc_driver = { 343static struct pnp_card_driver als100_pnpc_driver = {
293 .flags = PNP_DRIVER_RES_DISABLE, 344 .flags = PNP_DRIVER_RES_DISABLE,
294 .name = "als100", 345 .name = "als100",
295 .id_table = snd_als100_pnpids, 346 .id_table = snd_als100_pnpids,
296 .probe = snd_als100_pnp_detect, 347 .probe = snd_als100_pnp_detect,
297 .remove = __devexit_p(snd_als100_pnp_remove), 348 .remove = __devexit_p(snd_als100_pnp_remove),
@@ -312,7 +363,7 @@ static int __init alsa_card_als100_init(void)
312 if (!als100_devices) { 363 if (!als100_devices) {
313 pnp_unregister_card_driver(&als100_pnpc_driver); 364 pnp_unregister_card_driver(&als100_pnpc_driver);
314#ifdef MODULE 365#ifdef MODULE
315 snd_printk(KERN_ERR "no ALS100 based soundcards found\n"); 366 snd_printk(KERN_ERR "no Avance Logic based soundcards found\n");
316#endif 367#endif
317 return -ENODEV; 368 return -ENODEV;
318 } 369 }
diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c
index 02f79d252718..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>
@@ -237,7 +236,7 @@ WSS_DOUBLE("Wavetable Capture Volume", 0,
237 CMI8330_WAVGAIN, CMI8330_WAVGAIN, 4, 0, 15, 0), 236 CMI8330_WAVGAIN, CMI8330_WAVGAIN, 4, 0, 15, 0),
238WSS_SINGLE("3D Control - Switch", 0, 237WSS_SINGLE("3D Control - Switch", 0,
239 CMI8330_RMUX3D, 5, 1, 1), 238 CMI8330_RMUX3D, 5, 1, 1),
240WSS_SINGLE("PC Speaker Playback Volume", 0, 239WSS_SINGLE("Beep Playback Volume", 0,
241 CMI8330_OUTPUTVOL, 3, 3, 0), 240 CMI8330_OUTPUTVOL, 3, 3, 0),
242WSS_DOUBLE("FM Playback Switch", 0, 241WSS_DOUBLE("FM Playback Switch", 0,
243 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1), 242 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
@@ -262,7 +261,7 @@ SB_DOUBLE("SB Line Playback Switch", SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 4, 3,
262SB_DOUBLE("SB Line Playback Volume", SB_DSP4_LINE_DEV, (SB_DSP4_LINE_DEV + 1), 3, 3, 31), 261SB_DOUBLE("SB Line Playback Volume", SB_DSP4_LINE_DEV, (SB_DSP4_LINE_DEV + 1), 3, 3, 31),
263SB_SINGLE("SB Mic Playback Switch", SB_DSP4_OUTPUT_SW, 0, 1), 262SB_SINGLE("SB Mic Playback Switch", SB_DSP4_OUTPUT_SW, 0, 1),
264SB_SINGLE("SB Mic Playback Volume", SB_DSP4_MIC_DEV, 3, 31), 263SB_SINGLE("SB Mic Playback Volume", SB_DSP4_MIC_DEV, 3, 31),
265SB_SINGLE("SB PC Speaker Volume", SB_DSP4_SPEAKER_DEV, 6, 3), 264SB_SINGLE("SB Beep Volume", SB_DSP4_SPEAKER_DEV, 6, 3),
266SB_DOUBLE("SB Capture Volume", SB_DSP4_IGAIN_DEV, (SB_DSP4_IGAIN_DEV + 1), 6, 6, 3), 265SB_DOUBLE("SB Capture Volume", SB_DSP4_IGAIN_DEV, (SB_DSP4_IGAIN_DEV + 1), 6, 6, 3),
267SB_DOUBLE("SB Playback Volume", SB_DSP4_OGAIN_DEV, (SB_DSP4_OGAIN_DEV + 1), 6, 6, 3), 266SB_DOUBLE("SB Playback Volume", SB_DSP4_OGAIN_DEV, (SB_DSP4_OGAIN_DEV + 1), 6, 6, 3),
268SB_SINGLE("SB Mic Auto Gain", SB_DSP4_MIC_AGC, 0, 1), 267SB_SINGLE("SB Mic Auto Gain", SB_DSP4_MIC_AGC, 0, 1),
diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c
index a076a6ce8071..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>
@@ -177,7 +176,7 @@ static struct pnp_card_device_id snd_cs423x_pnpids[] = {
177 { .id = "CSC0437", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } }, 176 { .id = "CSC0437", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } },
178 /* Digital PC 5000 Onboard - CS4236B */ 177 /* Digital PC 5000 Onboard - CS4236B */
179 { .id = "CSC0735", .devs = { { "CSC0000" }, { "CSC0010" } } }, 178 { .id = "CSC0735", .devs = { { "CSC0000" }, { "CSC0010" } } },
180 /* some uknown CS4236B */ 179 /* some unknown CS4236B */
181 { .id = "CSC0b35", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } }, 180 { .id = "CSC0b35", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } },
182 /* Intel PR440FX Onboard sound */ 181 /* Intel PR440FX Onboard sound */
183 { .id = "CSC0b36", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } }, 182 { .id = "CSC0b36", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } },
@@ -394,21 +393,15 @@ static int __devinit snd_cs423x_probe(struct snd_card *card, int dev)
394 return -EBUSY; 393 return -EBUSY;
395 } 394 }
396 395
397 err = snd_wss_create(card, port[dev], cport[dev], 396 err = snd_cs4236_create(card, port[dev], cport[dev],
398 irq[dev], 397 irq[dev],
399 dma1[dev], dma2[dev], 398 dma1[dev], dma2[dev],
400 WSS_HW_DETECT3, 0, &chip); 399 WSS_HW_DETECT3, 0, &chip);
401 if (err < 0) 400 if (err < 0)
402 return err; 401 return err;
402
403 acard->chip = chip;
403 if (chip->hardware & WSS_HW_CS4236B_MASK) { 404 if (chip->hardware & WSS_HW_CS4236B_MASK) {
404 snd_wss_free(chip);
405 err = snd_cs4236_create(card,
406 port[dev], cport[dev],
407 irq[dev], dma1[dev], dma2[dev],
408 WSS_HW_DETECT, 0, &chip);
409 if (err < 0)
410 return err;
411 acard->chip = chip;
412 405
413 err = snd_cs4236_pcm(chip, 0, &pcm); 406 err = snd_cs4236_pcm(chip, 0, &pcm);
414 if (err < 0) 407 if (err < 0)
@@ -418,7 +411,6 @@ static int __devinit snd_cs423x_probe(struct snd_card *card, int dev)
418 if (err < 0) 411 if (err < 0)
419 return err; 412 return err;
420 } else { 413 } else {
421 acard->chip = chip;
422 err = snd_wss_pcm(chip, 0, &pcm); 414 err = snd_wss_pcm(chip, 0, &pcm);
423 if (err < 0) 415 if (err < 0)
424 return err; 416 return err;
diff --git a/sound/isa/cs423x/cs4236_lib.c b/sound/isa/cs423x/cs4236_lib.c
index 38835f31298b..c5adca300632 100644
--- a/sound/isa/cs423x/cs4236_lib.c
+++ b/sound/isa/cs423x/cs4236_lib.c
@@ -87,6 +87,8 @@
87#include <sound/core.h> 87#include <sound/core.h>
88#include <sound/wss.h> 88#include <sound/wss.h>
89#include <sound/asoundef.h> 89#include <sound/asoundef.h>
90#include <sound/initval.h>
91#include <sound/tlv.h>
90 92
91/* 93/*
92 * 94 *
@@ -264,7 +266,10 @@ static void snd_cs4236_resume(struct snd_wss *chip)
264} 266}
265 267
266#endif /* CONFIG_PM */ 268#endif /* CONFIG_PM */
267 269/*
270 * This function does no fail if the chip is not CS4236B or compatible.
271 * It just an equivalent to the snd_wss_create() then.
272 */
268int snd_cs4236_create(struct snd_card *card, 273int snd_cs4236_create(struct snd_card *card,
269 unsigned long port, 274 unsigned long port,
270 unsigned long cport, 275 unsigned long cport,
@@ -281,21 +286,17 @@ int snd_cs4236_create(struct snd_card *card,
281 *rchip = NULL; 286 *rchip = NULL;
282 if (hardware == WSS_HW_DETECT) 287 if (hardware == WSS_HW_DETECT)
283 hardware = WSS_HW_DETECT3; 288 hardware = WSS_HW_DETECT3;
284 if (cport < 0x100) { 289
285 snd_printk(KERN_ERR "please, specify control port "
286 "for CS4236+ chips\n");
287 return -ENODEV;
288 }
289 err = snd_wss_create(card, port, cport, 290 err = snd_wss_create(card, port, cport,
290 irq, dma1, dma2, hardware, hwshare, &chip); 291 irq, dma1, dma2, hardware, hwshare, &chip);
291 if (err < 0) 292 if (err < 0)
292 return err; 293 return err;
293 294
294 if (!(chip->hardware & WSS_HW_CS4236B_MASK)) { 295 if ((chip->hardware & WSS_HW_CS4236B_MASK) == 0) {
295 snd_printk(KERN_ERR "CS4236+: MODE3 and extended registers " 296 snd_printd("chip is not CS4236+, hardware=0x%x\n",
296 "not available, hardware=0x%x\n", chip->hardware); 297 chip->hardware);
297 snd_device_free(card, chip); 298 *rchip = chip;
298 return -ENODEV; 299 return 0;
299 } 300 }
300#if 0 301#if 0
301 { 302 {
@@ -308,9 +309,16 @@ int snd_cs4236_create(struct snd_card *card,
308 idx, snd_cs4236_ctrl_in(chip, idx)); 309 idx, snd_cs4236_ctrl_in(chip, idx));
309 } 310 }
310#endif 311#endif
312 if (cport < 0x100 || cport == SNDRV_AUTO_PORT) {
313 snd_printk(KERN_ERR "please, specify control port "
314 "for CS4236+ chips\n");
315 snd_device_free(card, chip);
316 return -ENODEV;
317 }
311 ver1 = snd_cs4236_ctrl_in(chip, 1); 318 ver1 = snd_cs4236_ctrl_in(chip, 1);
312 ver2 = snd_cs4236_ext_in(chip, CS4236_VERSION); 319 ver2 = snd_cs4236_ext_in(chip, CS4236_VERSION);
313 snd_printdd("CS4236: [0x%lx] C1 (version) = 0x%x, ext = 0x%x\n", cport, ver1, ver2); 320 snd_printdd("CS4236: [0x%lx] C1 (version) = 0x%x, ext = 0x%x\n",
321 cport, ver1, ver2);
314 if (ver1 != ver2) { 322 if (ver1 != ver2) {
315 snd_printk(KERN_ERR "CS4236+ chip detected, but " 323 snd_printk(KERN_ERR "CS4236+ chip detected, but "
316 "control port 0x%lx is not valid\n", cport); 324 "control port 0x%lx is not valid\n", cport);
@@ -321,13 +329,17 @@ int snd_cs4236_create(struct snd_card *card,
321 snd_cs4236_ctrl_out(chip, 2, 0xff); 329 snd_cs4236_ctrl_out(chip, 2, 0xff);
322 snd_cs4236_ctrl_out(chip, 3, 0x00); 330 snd_cs4236_ctrl_out(chip, 3, 0x00);
323 snd_cs4236_ctrl_out(chip, 4, 0x80); 331 snd_cs4236_ctrl_out(chip, 4, 0x80);
324 snd_cs4236_ctrl_out(chip, 5, ((IEC958_AES1_CON_PCM_CODER & 3) << 6) | IEC958_AES0_CON_EMPHASIS_NONE); 332 reg = ((IEC958_AES1_CON_PCM_CODER & 3) << 6) |
333 IEC958_AES0_CON_EMPHASIS_NONE;
334 snd_cs4236_ctrl_out(chip, 5, reg);
325 snd_cs4236_ctrl_out(chip, 6, IEC958_AES1_CON_PCM_CODER >> 2); 335 snd_cs4236_ctrl_out(chip, 6, IEC958_AES1_CON_PCM_CODER >> 2);
326 snd_cs4236_ctrl_out(chip, 7, 0x00); 336 snd_cs4236_ctrl_out(chip, 7, 0x00);
327 /* 0x8c for C8 is valid for Turtle Beach Malibu - the IEC-958 output */ 337 /*
328 /* is working with this setup, other hardware should have */ 338 * 0x8c for C8 is valid for Turtle Beach Malibu - the IEC-958
329 /* different signal paths and this value should be selectable */ 339 * output is working with this setup, other hardware should
330 /* in the future */ 340 * have different signal paths and this value should be
341 * selectable in the future
342 */
331 snd_cs4236_ctrl_out(chip, 8, 0x8c); 343 snd_cs4236_ctrl_out(chip, 8, 0x8c);
332 chip->rate_constraint = snd_cs4236_xrate; 344 chip->rate_constraint = snd_cs4236_xrate;
333 chip->set_playback_format = snd_cs4236_playback_format; 345 chip->set_playback_format = snd_cs4236_playback_format;
@@ -339,9 +351,10 @@ int snd_cs4236_create(struct snd_card *card,
339 351
340 /* initialize extended registers */ 352 /* initialize extended registers */
341 for (reg = 0; reg < sizeof(snd_cs4236_ext_map); reg++) 353 for (reg = 0; reg < sizeof(snd_cs4236_ext_map); reg++)
342 snd_cs4236_ext_out(chip, CS4236_I23VAL(reg), snd_cs4236_ext_map[reg]); 354 snd_cs4236_ext_out(chip, CS4236_I23VAL(reg),
355 snd_cs4236_ext_map[reg]);
343 356
344 /* initialize compatible but more featured registers */ 357 /* initialize compatible but more featured registers */
345 snd_wss_out(chip, CS4231_LEFT_INPUT, 0x40); 358 snd_wss_out(chip, CS4231_LEFT_INPUT, 0x40);
346 snd_wss_out(chip, CS4231_RIGHT_INPUT, 0x40); 359 snd_wss_out(chip, CS4231_RIGHT_INPUT, 0x40);
347 snd_wss_out(chip, CS4231_AUX1_LEFT_INPUT, 0xff); 360 snd_wss_out(chip, CS4231_AUX1_LEFT_INPUT, 0xff);
@@ -387,6 +400,14 @@ int snd_cs4236_pcm(struct snd_wss *chip, int device, struct snd_pcm **rpcm)
387 .get = snd_cs4236_get_single, .put = snd_cs4236_put_single, \ 400 .get = snd_cs4236_get_single, .put = snd_cs4236_put_single, \
388 .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) } 401 .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) }
389 402
403#define CS4236_SINGLE_TLV(xname, xindex, reg, shift, mask, invert, xtlv) \
404{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
405 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
406 .info = snd_cs4236_info_single, \
407 .get = snd_cs4236_get_single, .put = snd_cs4236_put_single, \
408 .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24), \
409 .tlv = { .p = (xtlv) } }
410
390static int snd_cs4236_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 411static int snd_cs4236_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
391{ 412{
392 int mask = (kcontrol->private_value >> 16) & 0xff; 413 int mask = (kcontrol->private_value >> 16) & 0xff;
@@ -490,6 +511,16 @@ static int snd_cs4236_put_singlec(struct snd_kcontrol *kcontrol, struct snd_ctl_
490 .get = snd_cs4236_get_double, .put = snd_cs4236_put_double, \ 511 .get = snd_cs4236_get_double, .put = snd_cs4236_put_double, \
491 .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) } 512 .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) }
492 513
514#define CS4236_DOUBLE_TLV(xname, xindex, left_reg, right_reg, shift_left, \
515 shift_right, mask, invert, xtlv) \
516{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
517 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
518 .info = snd_cs4236_info_double, \
519 .get = snd_cs4236_get_double, .put = snd_cs4236_put_double, \
520 .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | \
521 (shift_right << 19) | (mask << 24) | (invert << 22), \
522 .tlv = { .p = (xtlv) } }
523
493static int snd_cs4236_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 524static int snd_cs4236_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
494{ 525{
495 int mask = (kcontrol->private_value >> 24) & 0xff; 526 int mask = (kcontrol->private_value >> 24) & 0xff;
@@ -560,12 +591,23 @@ static int snd_cs4236_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_e
560 return change; 591 return change;
561} 592}
562 593
563#define CS4236_DOUBLE1(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert) \ 594#define CS4236_DOUBLE1(xname, xindex, left_reg, right_reg, shift_left, \
595 shift_right, mask, invert) \
564{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ 596{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
565 .info = snd_cs4236_info_double, \ 597 .info = snd_cs4236_info_double, \
566 .get = snd_cs4236_get_double1, .put = snd_cs4236_put_double1, \ 598 .get = snd_cs4236_get_double1, .put = snd_cs4236_put_double1, \
567 .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) } 599 .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) }
568 600
601#define CS4236_DOUBLE1_TLV(xname, xindex, left_reg, right_reg, shift_left, \
602 shift_right, mask, invert, xtlv) \
603{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
604 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
605 .info = snd_cs4236_info_double, \
606 .get = snd_cs4236_get_double1, .put = snd_cs4236_put_double1, \
607 .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | \
608 (shift_right << 19) | (mask << 24) | (invert << 22), \
609 .tlv = { .p = (xtlv) } }
610
569static int snd_cs4236_get_double1(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 611static int snd_cs4236_get_double1(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
570{ 612{
571 struct snd_wss *chip = snd_kcontrol_chip(kcontrol); 613 struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
@@ -619,16 +661,18 @@ static int snd_cs4236_put_double1(struct snd_kcontrol *kcontrol, struct snd_ctl_
619 return change; 661 return change;
620} 662}
621 663
622#define CS4236_MASTER_DIGITAL(xname, xindex) \ 664#define CS4236_MASTER_DIGITAL(xname, xindex, xtlv) \
623{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ 665{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
666 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
624 .info = snd_cs4236_info_double, \ 667 .info = snd_cs4236_info_double, \
625 .get = snd_cs4236_get_master_digital, .put = snd_cs4236_put_master_digital, \ 668 .get = snd_cs4236_get_master_digital, .put = snd_cs4236_put_master_digital, \
626 .private_value = 71 << 24 } 669 .private_value = 71 << 24, \
670 .tlv = { .p = (xtlv) } }
627 671
628static inline int snd_cs4236_mixer_master_digital_invert_volume(int vol) 672static inline int snd_cs4236_mixer_master_digital_invert_volume(int vol)
629{ 673{
630 return (vol < 64) ? 63 - vol : 64 + (71 - vol); 674 return (vol < 64) ? 63 - vol : 64 + (71 - vol);
631} 675}
632 676
633static int snd_cs4236_get_master_digital(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 677static int snd_cs4236_get_master_digital(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
634{ 678{
@@ -661,11 +705,13 @@ static int snd_cs4236_put_master_digital(struct snd_kcontrol *kcontrol, struct s
661 return change; 705 return change;
662} 706}
663 707
664#define CS4235_OUTPUT_ACCU(xname, xindex) \ 708#define CS4235_OUTPUT_ACCU(xname, xindex, xtlv) \
665{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ 709{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
710 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
666 .info = snd_cs4236_info_double, \ 711 .info = snd_cs4236_info_double, \
667 .get = snd_cs4235_get_output_accu, .put = snd_cs4235_put_output_accu, \ 712 .get = snd_cs4235_get_output_accu, .put = snd_cs4235_put_output_accu, \
668 .private_value = 3 << 24 } 713 .private_value = 3 << 24, \
714 .tlv = { .p = (xtlv) } }
669 715
670static inline int snd_cs4235_mixer_output_accu_get_volume(int vol) 716static inline int snd_cs4235_mixer_output_accu_get_volume(int vol)
671{ 717{
@@ -720,41 +766,56 @@ static int snd_cs4235_put_output_accu(struct snd_kcontrol *kcontrol, struct snd_
720 return change; 766 return change;
721} 767}
722 768
769static const DECLARE_TLV_DB_SCALE(db_scale_7bit, -9450, 150, 0);
770static const DECLARE_TLV_DB_SCALE(db_scale_6bit, -9450, 150, 0);
771static const DECLARE_TLV_DB_SCALE(db_scale_6bit_12db_max, -8250, 150, 0);
772static const DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0);
773static const DECLARE_TLV_DB_SCALE(db_scale_5bit_22db_max, -2400, 150, 0);
774static const DECLARE_TLV_DB_SCALE(db_scale_4bit, -4500, 300, 0);
775static const DECLARE_TLV_DB_SCALE(db_scale_2bit, -1800, 600, 0);
776static const DECLARE_TLV_DB_SCALE(db_scale_rec_gain, 0, 150, 0);
777
723static struct snd_kcontrol_new snd_cs4236_controls[] = { 778static struct snd_kcontrol_new snd_cs4236_controls[] = {
724 779
725CS4236_DOUBLE("Master Digital Playback Switch", 0, 780CS4236_DOUBLE("Master Digital Playback Switch", 0,
726 CS4236_LEFT_MASTER, CS4236_RIGHT_MASTER, 7, 7, 1, 1), 781 CS4236_LEFT_MASTER, CS4236_RIGHT_MASTER, 7, 7, 1, 1),
727CS4236_DOUBLE("Master Digital Capture Switch", 0, 782CS4236_DOUBLE("Master Digital Capture Switch", 0,
728 CS4236_DAC_MUTE, CS4236_DAC_MUTE, 7, 6, 1, 1), 783 CS4236_DAC_MUTE, CS4236_DAC_MUTE, 7, 6, 1, 1),
729CS4236_MASTER_DIGITAL("Master Digital Volume", 0), 784CS4236_MASTER_DIGITAL("Master Digital Volume", 0, db_scale_7bit),
730 785
731CS4236_DOUBLE("Capture Boost Volume", 0, 786CS4236_DOUBLE_TLV("Capture Boost Volume", 0,
732 CS4236_LEFT_MIX_CTRL, CS4236_RIGHT_MIX_CTRL, 5, 5, 3, 1), 787 CS4236_LEFT_MIX_CTRL, CS4236_RIGHT_MIX_CTRL, 5, 5, 3, 1,
788 db_scale_2bit),
733 789
734WSS_DOUBLE("PCM Playback Switch", 0, 790WSS_DOUBLE("PCM Playback Switch", 0,
735 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1), 791 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1),
736WSS_DOUBLE("PCM Playback Volume", 0, 792WSS_DOUBLE_TLV("PCM Playback Volume", 0,
737 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1), 793 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1,
794 db_scale_6bit),
738 795
739CS4236_DOUBLE("DSP Playback Switch", 0, 796CS4236_DOUBLE("DSP Playback Switch", 0,
740 CS4236_LEFT_DSP, CS4236_RIGHT_DSP, 7, 7, 1, 1), 797 CS4236_LEFT_DSP, CS4236_RIGHT_DSP, 7, 7, 1, 1),
741CS4236_DOUBLE("DSP Playback Volume", 0, 798CS4236_DOUBLE_TLV("DSP Playback Volume", 0,
742 CS4236_LEFT_DSP, CS4236_RIGHT_DSP, 0, 0, 63, 1), 799 CS4236_LEFT_DSP, CS4236_RIGHT_DSP, 0, 0, 63, 1,
800 db_scale_6bit),
743 801
744CS4236_DOUBLE("FM Playback Switch", 0, 802CS4236_DOUBLE("FM Playback Switch", 0,
745 CS4236_LEFT_FM, CS4236_RIGHT_FM, 7, 7, 1, 1), 803 CS4236_LEFT_FM, CS4236_RIGHT_FM, 7, 7, 1, 1),
746CS4236_DOUBLE("FM Playback Volume", 0, 804CS4236_DOUBLE_TLV("FM Playback Volume", 0,
747 CS4236_LEFT_FM, CS4236_RIGHT_FM, 0, 0, 63, 1), 805 CS4236_LEFT_FM, CS4236_RIGHT_FM, 0, 0, 63, 1,
806 db_scale_6bit),
748 807
749CS4236_DOUBLE("Wavetable Playback Switch", 0, 808CS4236_DOUBLE("Wavetable Playback Switch", 0,
750 CS4236_LEFT_WAVE, CS4236_RIGHT_WAVE, 7, 7, 1, 1), 809 CS4236_LEFT_WAVE, CS4236_RIGHT_WAVE, 7, 7, 1, 1),
751CS4236_DOUBLE("Wavetable Playback Volume", 0, 810CS4236_DOUBLE_TLV("Wavetable Playback Volume", 0,
752 CS4236_LEFT_WAVE, CS4236_RIGHT_WAVE, 0, 0, 63, 1), 811 CS4236_LEFT_WAVE, CS4236_RIGHT_WAVE, 0, 0, 63, 1,
812 db_scale_6bit_12db_max),
753 813
754WSS_DOUBLE("Synth Playback Switch", 0, 814WSS_DOUBLE("Synth Playback Switch", 0,
755 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1), 815 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1),
756WSS_DOUBLE("Synth Volume", 0, 816WSS_DOUBLE_TLV("Synth Volume", 0,
757 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 1), 817 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 1,
818 db_scale_5bit_12db_max),
758WSS_DOUBLE("Synth Capture Switch", 0, 819WSS_DOUBLE("Synth Capture Switch", 0,
759 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 6, 6, 1, 1), 820 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 6, 6, 1, 1),
760WSS_DOUBLE("Synth Capture Bypass", 0, 821WSS_DOUBLE("Synth Capture Bypass", 0,
@@ -764,14 +825,16 @@ CS4236_DOUBLE("Mic Playback Switch", 0,
764 CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 6, 6, 1, 1), 825 CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 6, 6, 1, 1),
765CS4236_DOUBLE("Mic Capture Switch", 0, 826CS4236_DOUBLE("Mic Capture Switch", 0,
766 CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 7, 7, 1, 1), 827 CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 7, 7, 1, 1),
767CS4236_DOUBLE("Mic Volume", 0, CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 0, 0, 31, 1), 828CS4236_DOUBLE_TLV("Mic Volume", 0, CS4236_LEFT_MIC, CS4236_RIGHT_MIC,
768CS4236_DOUBLE("Mic Playback Boost", 0, 829 0, 0, 31, 1, db_scale_5bit_22db_max),
830CS4236_DOUBLE("Mic Playback Boost (+20dB)", 0,
769 CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 5, 5, 1, 0), 831 CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 5, 5, 1, 0),
770 832
771WSS_DOUBLE("Line Playback Switch", 0, 833WSS_DOUBLE("Line Playback Switch", 0,
772 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1), 834 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1),
773WSS_DOUBLE("Line Volume", 0, 835WSS_DOUBLE_TLV("Line Volume", 0,
774 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1), 836 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1,
837 db_scale_5bit_12db_max),
775WSS_DOUBLE("Line Capture Switch", 0, 838WSS_DOUBLE("Line Capture Switch", 0,
776 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 6, 6, 1, 1), 839 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 6, 6, 1, 1),
777WSS_DOUBLE("Line Capture Bypass", 0, 840WSS_DOUBLE("Line Capture Bypass", 0,
@@ -779,57 +842,63 @@ WSS_DOUBLE("Line Capture Bypass", 0,
779 842
780WSS_DOUBLE("CD Playback Switch", 0, 843WSS_DOUBLE("CD Playback Switch", 0,
781 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1), 844 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
782WSS_DOUBLE("CD Volume", 0, 845WSS_DOUBLE_TLV("CD Volume", 0,
783 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1), 846 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1,
847 db_scale_5bit_12db_max),
784WSS_DOUBLE("CD Capture Switch", 0, 848WSS_DOUBLE("CD Capture Switch", 0,
785 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 6, 6, 1, 1), 849 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 6, 6, 1, 1),
786 850
787CS4236_DOUBLE1("Mono Output Playback Switch", 0, 851CS4236_DOUBLE1("Mono Output Playback Switch", 0,
788 CS4231_MONO_CTRL, CS4236_RIGHT_MIX_CTRL, 6, 7, 1, 1), 852 CS4231_MONO_CTRL, CS4236_RIGHT_MIX_CTRL, 6, 7, 1, 1),
789CS4236_DOUBLE1("Mono Playback Switch", 0, 853CS4236_DOUBLE1("Beep Playback Switch", 0,
790 CS4231_MONO_CTRL, CS4236_LEFT_MIX_CTRL, 7, 7, 1, 1), 854 CS4231_MONO_CTRL, CS4236_LEFT_MIX_CTRL, 7, 7, 1, 1),
791WSS_SINGLE("Mono Playback Volume", 0, CS4231_MONO_CTRL, 0, 15, 1), 855WSS_SINGLE_TLV("Beep Playback Volume", 0, CS4231_MONO_CTRL, 0, 15, 1,
792WSS_SINGLE("Mono Playback Bypass", 0, CS4231_MONO_CTRL, 5, 1, 0), 856 db_scale_4bit),
857WSS_SINGLE("Beep Bypass Playback Switch", 0, CS4231_MONO_CTRL, 5, 1, 0),
793 858
794WSS_DOUBLE("Capture Volume", 0, 859WSS_DOUBLE_TLV("Capture Volume", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT,
795 CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 0, 0, 15, 0), 860 0, 0, 15, 0, db_scale_rec_gain),
796WSS_DOUBLE("Analog Loopback Capture Switch", 0, 861WSS_DOUBLE("Analog Loopback Capture Switch", 0,
797 CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 7, 7, 1, 0), 862 CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 7, 7, 1, 0),
798 863
799WSS_SINGLE("Digital Loopback Playback Switch", 0, CS4231_LOOPBACK, 0, 1, 0), 864WSS_SINGLE("Loopback Digital Playback Switch", 0, CS4231_LOOPBACK, 0, 1, 0),
800CS4236_DOUBLE1("Digital Loopback Playback Volume", 0, 865CS4236_DOUBLE1_TLV("Loopback Digital Playback Volume", 0,
801 CS4231_LOOPBACK, CS4236_RIGHT_LOOPBACK, 2, 0, 63, 1) 866 CS4231_LOOPBACK, CS4236_RIGHT_LOOPBACK, 2, 0, 63, 1,
867 db_scale_6bit),
802}; 868};
803 869
870static const DECLARE_TLV_DB_SCALE(db_scale_5bit_6db_max, -5600, 200, 0);
871static const DECLARE_TLV_DB_SCALE(db_scale_2bit_16db_max, -2400, 800, 0);
872
804static struct snd_kcontrol_new snd_cs4235_controls[] = { 873static struct snd_kcontrol_new snd_cs4235_controls[] = {
805 874
806WSS_DOUBLE("Master Switch", 0, 875WSS_DOUBLE("Master Playback Switch", 0,
807 CS4235_LEFT_MASTER, CS4235_RIGHT_MASTER, 7, 7, 1, 1), 876 CS4235_LEFT_MASTER, CS4235_RIGHT_MASTER, 7, 7, 1, 1),
808WSS_DOUBLE("Master Volume", 0, 877WSS_DOUBLE_TLV("Master Playback Volume", 0,
809 CS4235_LEFT_MASTER, CS4235_RIGHT_MASTER, 0, 0, 31, 1), 878 CS4235_LEFT_MASTER, CS4235_RIGHT_MASTER, 0, 0, 31, 1,
810 879 db_scale_5bit_6db_max),
811CS4235_OUTPUT_ACCU("Playback Volume", 0),
812 880
813CS4236_DOUBLE("Master Digital Playback Switch", 0, 881CS4235_OUTPUT_ACCU("Playback Volume", 0, db_scale_2bit_16db_max),
814 CS4236_LEFT_MASTER, CS4236_RIGHT_MASTER, 7, 7, 1, 1),
815CS4236_DOUBLE("Master Digital Capture Switch", 0,
816 CS4236_DAC_MUTE, CS4236_DAC_MUTE, 7, 6, 1, 1),
817CS4236_MASTER_DIGITAL("Master Digital Volume", 0),
818 882
819WSS_DOUBLE("Master Digital Playback Switch", 1, 883WSS_DOUBLE("Synth Playback Switch", 1,
820 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1), 884 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1),
821WSS_DOUBLE("Master Digital Capture Switch", 1, 885WSS_DOUBLE("Synth Capture Switch", 1,
822 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 6, 6, 1, 1), 886 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 6, 6, 1, 1),
823WSS_DOUBLE("Master Digital Volume", 1, 887WSS_DOUBLE_TLV("Synth Volume", 1,
824 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 1), 888 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 1,
889 db_scale_5bit_12db_max),
825 890
826CS4236_DOUBLE("Capture Volume", 0, 891CS4236_DOUBLE_TLV("Capture Volume", 0,
827 CS4236_LEFT_MIX_CTRL, CS4236_RIGHT_MIX_CTRL, 5, 5, 3, 1), 892 CS4236_LEFT_MIX_CTRL, CS4236_RIGHT_MIX_CTRL, 5, 5, 3, 1,
893 db_scale_2bit),
828 894
829WSS_DOUBLE("PCM Switch", 0, 895WSS_DOUBLE("PCM Playback Switch", 0,
830 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1), 896 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1),
831WSS_DOUBLE("PCM Volume", 0, 897WSS_DOUBLE("PCM Capture Switch", 0,
832 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1), 898 CS4236_DAC_MUTE, CS4236_DAC_MUTE, 7, 6, 1, 1),
899WSS_DOUBLE_TLV("PCM Volume", 0,
900 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1,
901 db_scale_6bit),
833 902
834CS4236_DOUBLE("DSP Switch", 0, CS4236_LEFT_DSP, CS4236_RIGHT_DSP, 7, 7, 1, 1), 903CS4236_DOUBLE("DSP Switch", 0, CS4236_LEFT_DSP, CS4236_RIGHT_DSP, 7, 7, 1, 1),
835 904
@@ -842,29 +911,29 @@ CS4236_DOUBLE("Mic Capture Switch", 0,
842 CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 7, 7, 1, 1), 911 CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 7, 7, 1, 1),
843CS4236_DOUBLE("Mic Playback Switch", 0, 912CS4236_DOUBLE("Mic Playback Switch", 0,
844 CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 6, 6, 1, 1), 913 CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 6, 6, 1, 1),
845CS4236_SINGLE("Mic Volume", 0, CS4236_LEFT_MIC, 0, 31, 1), 914CS4236_SINGLE_TLV("Mic Volume", 0, CS4236_LEFT_MIC, 0, 31, 1,
846CS4236_SINGLE("Mic Playback Boost", 0, CS4236_LEFT_MIC, 5, 1, 0), 915 db_scale_5bit_22db_max),
916CS4236_SINGLE("Mic Boost (+20dB)", 0, CS4236_LEFT_MIC, 5, 1, 0),
847 917
848WSS_DOUBLE("Aux Playback Switch", 0, 918WSS_DOUBLE("Line Playback Switch", 0,
849 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1), 919 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1),
850WSS_DOUBLE("Aux Capture Switch", 0, 920WSS_DOUBLE("Line Capture Switch", 0,
851 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 6, 6, 1, 1), 921 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 6, 6, 1, 1),
852WSS_DOUBLE("Aux Volume", 0, 922WSS_DOUBLE_TLV("Line Volume", 0,
853 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1), 923 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1,
924 db_scale_5bit_12db_max),
854 925
855WSS_DOUBLE("Aux Playback Switch", 1, 926WSS_DOUBLE("CD Playback Switch", 1,
856 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1), 927 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
857WSS_DOUBLE("Aux Capture Switch", 1, 928WSS_DOUBLE("CD Capture Switch", 1,
858 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 6, 6, 1, 1), 929 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 6, 6, 1, 1),
859WSS_DOUBLE("Aux Volume", 1, 930WSS_DOUBLE_TLV("CD Volume", 1,
860 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1), 931 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1,
861 932 db_scale_5bit_12db_max),
862CS4236_DOUBLE1("Master Mono Switch", 0,
863 CS4231_MONO_CTRL, CS4236_RIGHT_MIX_CTRL, 6, 7, 1, 1),
864 933
865CS4236_DOUBLE1("Mono Switch", 0, 934CS4236_DOUBLE1("Beep Playback Switch", 0,
866 CS4231_MONO_CTRL, CS4236_LEFT_MIX_CTRL, 7, 7, 1, 1), 935 CS4231_MONO_CTRL, CS4236_LEFT_MIX_CTRL, 7, 7, 1, 1),
867WSS_SINGLE("Mono Volume", 0, CS4231_MONO_CTRL, 0, 15, 1), 936WSS_SINGLE("Beep Playback Volume", 0, CS4231_MONO_CTRL, 0, 15, 1),
868 937
869WSS_DOUBLE("Analog Loopback Switch", 0, 938WSS_DOUBLE("Analog Loopback Switch", 0,
870 CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 7, 7, 1, 0), 939 CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 7, 7, 1, 0),
diff --git a/sound/isa/dt019x.c b/sound/isa/dt019x.c
deleted file mode 100644
index 80f5b1af9be8..000000000000
--- a/sound/isa/dt019x.c
+++ /dev/null
@@ -1,321 +0,0 @@
1
2/*
3 dt019x.c - driver for Diamond Technologies DT-0197H based soundcards.
4 Copyright (C) 1999, 2002 by Massimo Piccioni <dafastidio@libero.it>
5
6 Generalised for soundcards based on DT-0196 and ALS-007 chips
7 by Jonathan Woithe <jwoithe@physics.adelaide.edu.au>: June 2002.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22*/
23
24#include <linux/init.h>
25#include <linux/wait.h>
26#include <linux/pnp.h>
27#include <linux/moduleparam.h>
28#include <sound/core.h>
29#include <sound/initval.h>
30#include <sound/mpu401.h>
31#include <sound/opl3.h>
32#include <sound/sb.h>
33
34#define PFX "dt019x: "
35
36MODULE_AUTHOR("Massimo Piccioni <dafastidio@libero.it>");
37MODULE_DESCRIPTION("Diamond Technologies DT-019X / Avance Logic ALS-007");
38MODULE_LICENSE("GPL");
39MODULE_SUPPORTED_DEVICE("{{Diamond Technologies DT-019X},"
40 "{Avance Logic ALS-007}}");
41
42static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
43static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
44static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
45static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
46static long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
47static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
48static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* PnP setup */
49static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* PnP setup */
50static int dma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* PnP setup */
51
52module_param_array(index, int, NULL, 0444);
53MODULE_PARM_DESC(index, "Index value for DT-019X based soundcard.");
54module_param_array(id, charp, NULL, 0444);
55MODULE_PARM_DESC(id, "ID string for DT-019X based soundcard.");
56module_param_array(enable, bool, NULL, 0444);
57MODULE_PARM_DESC(enable, "Enable DT-019X based soundcard.");
58
59struct snd_card_dt019x {
60 struct pnp_dev *dev;
61 struct pnp_dev *devmpu;
62 struct pnp_dev *devopl;
63 struct snd_sb *chip;
64};
65
66static struct pnp_card_device_id snd_dt019x_pnpids[] = {
67 /* DT197A30 */
68 { .id = "RWB1688", .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" }, } },
69 /* DT0196 / ALS-007 */
70 { .id = "ALS0007", .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" }, } },
71 { .id = "", }
72};
73
74MODULE_DEVICE_TABLE(pnp_card, snd_dt019x_pnpids);
75
76
77#define DRIVER_NAME "snd-card-dt019x"
78
79
80static int __devinit snd_card_dt019x_pnp(int dev, struct snd_card_dt019x *acard,
81 struct pnp_card_link *card,
82 const struct pnp_card_device_id *pid)
83{
84 struct pnp_dev *pdev;
85 int err;
86
87 acard->dev = pnp_request_card_device(card, pid->devs[0].id, NULL);
88 if (acard->dev == NULL)
89 return -ENODEV;
90
91 acard->devmpu = pnp_request_card_device(card, pid->devs[1].id, NULL);
92 acard->devopl = pnp_request_card_device(card, pid->devs[2].id, NULL);
93
94 pdev = acard->dev;
95
96 err = pnp_activate_dev(pdev);
97 if (err < 0) {
98 snd_printk(KERN_ERR PFX "DT-019X AUDIO pnp configure failure\n");
99 return err;
100 }
101
102 port[dev] = pnp_port_start(pdev, 0);
103 dma8[dev] = pnp_dma(pdev, 0);
104 irq[dev] = pnp_irq(pdev, 0);
105 snd_printdd("dt019x: found audio interface: port=0x%lx, irq=0x%x, dma=0x%x\n",
106 port[dev],irq[dev],dma8[dev]);
107
108 pdev = acard->devmpu;
109 if (pdev != NULL) {
110 err = pnp_activate_dev(pdev);
111 if (err < 0) {
112 pnp_release_card_device(pdev);
113 snd_printk(KERN_ERR PFX "DT-019X MPU401 pnp configure failure, skipping\n");
114 goto __mpu_error;
115 }
116 mpu_port[dev] = pnp_port_start(pdev, 0);
117 mpu_irq[dev] = pnp_irq(pdev, 0);
118 snd_printdd("dt019x: found MPU-401: port=0x%lx, irq=0x%x\n",
119 mpu_port[dev],mpu_irq[dev]);
120 } else {
121 __mpu_error:
122 acard->devmpu = NULL;
123 mpu_port[dev] = -1;
124 }
125
126 pdev = acard->devopl;
127 if (pdev != NULL) {
128 err = pnp_activate_dev(pdev);
129 if (err < 0) {
130 pnp_release_card_device(pdev);
131 snd_printk(KERN_ERR PFX "DT-019X OPL3 pnp configure failure, skipping\n");
132 goto __fm_error;
133 }
134 fm_port[dev] = pnp_port_start(pdev, 0);
135 snd_printdd("dt019x: found OPL3 synth: port=0x%lx\n",fm_port[dev]);
136 } else {
137 __fm_error:
138 acard->devopl = NULL;
139 fm_port[dev] = -1;
140 }
141
142 return 0;
143}
144
145static int __devinit snd_card_dt019x_probe(int dev, struct pnp_card_link *pcard, const struct pnp_card_device_id *pid)
146{
147 int error;
148 struct snd_sb *chip;
149 struct snd_card *card;
150 struct snd_card_dt019x *acard;
151 struct snd_opl3 *opl3;
152
153 error = snd_card_create(index[dev], id[dev], THIS_MODULE,
154 sizeof(struct snd_card_dt019x), &card);
155 if (error < 0)
156 return error;
157 acard = card->private_data;
158
159 snd_card_set_dev(card, &pcard->card->dev);
160 if ((error = snd_card_dt019x_pnp(dev, acard, pcard, pid))) {
161 snd_card_free(card);
162 return error;
163 }
164
165 if ((error = snd_sbdsp_create(card, port[dev],
166 irq[dev],
167 snd_sb16dsp_interrupt,
168 dma8[dev],
169 -1,
170 SB_HW_DT019X,
171 &chip)) < 0) {
172 snd_card_free(card);
173 return error;
174 }
175 acard->chip = chip;
176
177 strcpy(card->driver, "DT-019X");
178 strcpy(card->shortname, "Diamond Tech. DT-019X");
179 sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d",
180 card->shortname, chip->name, chip->port,
181 irq[dev], dma8[dev]);
182
183 if ((error = snd_sb16dsp_pcm(chip, 0, NULL)) < 0) {
184 snd_card_free(card);
185 return error;
186 }
187 if ((error = snd_sbmixer_new(chip)) < 0) {
188 snd_card_free(card);
189 return error;
190 }
191
192 if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) {
193 if (mpu_irq[dev] == SNDRV_AUTO_IRQ)
194 mpu_irq[dev] = -1;
195 if (snd_mpu401_uart_new(card, 0,
196/* MPU401_HW_SB,*/
197 MPU401_HW_MPU401,
198 mpu_port[dev], 0,
199 mpu_irq[dev],
200 mpu_irq[dev] >= 0 ? IRQF_DISABLED : 0,
201 NULL) < 0)
202 snd_printk(KERN_ERR PFX "no MPU-401 device at 0x%lx ?\n", mpu_port[dev]);
203 }
204
205 if (fm_port[dev] > 0 && fm_port[dev] != SNDRV_AUTO_PORT) {
206 if (snd_opl3_create(card,
207 fm_port[dev],
208 fm_port[dev] + 2,
209 OPL3_HW_AUTO, 0, &opl3) < 0) {
210 snd_printk(KERN_ERR PFX "no OPL device at 0x%lx-0x%lx ?\n",
211 fm_port[dev], fm_port[dev] + 2);
212 } else {
213 if ((error = snd_opl3_timer_new(opl3, 0, 1)) < 0) {
214 snd_card_free(card);
215 return error;
216 }
217 if ((error = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
218 snd_card_free(card);
219 return error;
220 }
221 }
222 }
223
224 if ((error = snd_card_register(card)) < 0) {
225 snd_card_free(card);
226 return error;
227 }
228 pnp_set_card_drvdata(pcard, card);
229 return 0;
230}
231
232static unsigned int __devinitdata dt019x_devices;
233
234static int __devinit snd_dt019x_pnp_probe(struct pnp_card_link *card,
235 const struct pnp_card_device_id *pid)
236{
237 static int dev;
238 int res;
239
240 for ( ; dev < SNDRV_CARDS; dev++) {
241 if (!enable[dev])
242 continue;
243 res = snd_card_dt019x_probe(dev, card, pid);
244 if (res < 0)
245 return res;
246 dev++;
247 dt019x_devices++;
248 return 0;
249 }
250 return -ENODEV;
251}
252
253static void __devexit snd_dt019x_pnp_remove(struct pnp_card_link * pcard)
254{
255 snd_card_free(pnp_get_card_drvdata(pcard));
256 pnp_set_card_drvdata(pcard, NULL);
257}
258
259#ifdef CONFIG_PM
260static int snd_dt019x_pnp_suspend(struct pnp_card_link *pcard, pm_message_t state)
261{
262 struct snd_card *card = pnp_get_card_drvdata(pcard);
263 struct snd_card_dt019x *acard = card->private_data;
264 struct snd_sb *chip = acard->chip;
265
266 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
267 snd_pcm_suspend_all(chip->pcm);
268 snd_sbmixer_suspend(chip);
269 return 0;
270}
271
272static int snd_dt019x_pnp_resume(struct pnp_card_link *pcard)
273{
274 struct snd_card *card = pnp_get_card_drvdata(pcard);
275 struct snd_card_dt019x *acard = card->private_data;
276 struct snd_sb *chip = acard->chip;
277
278 snd_sbdsp_reset(chip);
279 snd_sbmixer_resume(chip);
280 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
281 return 0;
282}
283#endif
284
285static struct pnp_card_driver dt019x_pnpc_driver = {
286 .flags = PNP_DRIVER_RES_DISABLE,
287 .name = "dt019x",
288 .id_table = snd_dt019x_pnpids,
289 .probe = snd_dt019x_pnp_probe,
290 .remove = __devexit_p(snd_dt019x_pnp_remove),
291#ifdef CONFIG_PM
292 .suspend = snd_dt019x_pnp_suspend,
293 .resume = snd_dt019x_pnp_resume,
294#endif
295};
296
297static int __init alsa_card_dt019x_init(void)
298{
299 int err;
300
301 err = pnp_register_card_driver(&dt019x_pnpc_driver);
302 if (err)
303 return err;
304
305 if (!dt019x_devices) {
306 pnp_unregister_card_driver(&dt019x_pnpc_driver);
307#ifdef MODULE
308 snd_printk(KERN_ERR "no DT-019X / ALS-007 based soundcards found\n");
309#endif
310 return -ENODEV;
311 }
312 return 0;
313}
314
315static void __exit alsa_card_dt019x_exit(void)
316{
317 pnp_unregister_card_driver(&dt019x_pnpc_driver);
318}
319
320module_init(alsa_card_dt019x_init)
321module_exit(alsa_card_dt019x_exit)
diff --git a/sound/isa/es1688/es1688_lib.c b/sound/isa/es1688/es1688_lib.c
index 4c6e14f87f2d..c76bb00c9d15 100644
--- a/sound/isa/es1688/es1688_lib.c
+++ b/sound/isa/es1688/es1688_lib.c
@@ -982,7 +982,7 @@ ES1688_DOUBLE("CD Playback Volume", 0, ES1688_CD_DEV, ES1688_CD_DEV, 4, 0, 15, 0
982ES1688_DOUBLE("FM Playback Volume", 0, ES1688_FM_DEV, ES1688_FM_DEV, 4, 0, 15, 0), 982ES1688_DOUBLE("FM Playback Volume", 0, ES1688_FM_DEV, ES1688_FM_DEV, 4, 0, 15, 0),
983ES1688_DOUBLE("Mic Playback Volume", 0, ES1688_MIC_DEV, ES1688_MIC_DEV, 4, 0, 15, 0), 983ES1688_DOUBLE("Mic Playback Volume", 0, ES1688_MIC_DEV, ES1688_MIC_DEV, 4, 0, 15, 0),
984ES1688_DOUBLE("Aux Playback Volume", 0, ES1688_AUX_DEV, ES1688_AUX_DEV, 4, 0, 15, 0), 984ES1688_DOUBLE("Aux Playback Volume", 0, ES1688_AUX_DEV, ES1688_AUX_DEV, 4, 0, 15, 0),
985ES1688_SINGLE("PC Speaker Playback Volume", 0, ES1688_SPEAKER_DEV, 0, 7, 0), 985ES1688_SINGLE("Beep Playback Volume", 0, ES1688_SPEAKER_DEV, 0, 7, 0),
986ES1688_DOUBLE("Capture Volume", 0, ES1688_RECLEV_DEV, ES1688_RECLEV_DEV, 4, 0, 15, 0), 986ES1688_DOUBLE("Capture Volume", 0, ES1688_RECLEV_DEV, ES1688_RECLEV_DEV, 4, 0, 15, 0),
987ES1688_SINGLE("Capture Switch", 0, ES1688_REC_DEV, 4, 1, 1), 987ES1688_SINGLE("Capture Switch", 0, ES1688_REC_DEV, 4, 1, 1),
988{ 988{
diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c
index 8cfbff73a835..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>
@@ -102,8 +101,6 @@
102 101
103struct snd_es18xx { 102struct snd_es18xx {
104 unsigned long port; /* port of ESS chip */ 103 unsigned long port; /* port of ESS chip */
105 unsigned long mpu_port; /* MPU-401 port of ESS chip */
106 unsigned long fm_port; /* FM port */
107 unsigned long ctrl_port; /* Control port of ESS chip */ 104 unsigned long ctrl_port; /* Control port of ESS chip */
108 struct resource *res_port; 105 struct resource *res_port;
109 struct resource *res_mpu_port; 106 struct resource *res_mpu_port;
@@ -116,12 +113,9 @@ struct snd_es18xx {
116 unsigned short audio2_vol; /* volume level of audio2 */ 113 unsigned short audio2_vol; /* volume level of audio2 */
117 114
118 unsigned short active; /* active channel mask */ 115 unsigned short active; /* active channel mask */
119 unsigned int dma1_size;
120 unsigned int dma2_size;
121 unsigned int dma1_shift; 116 unsigned int dma1_shift;
122 unsigned int dma2_shift; 117 unsigned int dma2_shift;
123 118
124 struct snd_card *card;
125 struct snd_pcm *pcm; 119 struct snd_pcm *pcm;
126 struct snd_pcm_substream *playback_a_substream; 120 struct snd_pcm_substream *playback_a_substream;
127 struct snd_pcm_substream *capture_a_substream; 121 struct snd_pcm_substream *capture_a_substream;
@@ -136,14 +130,9 @@ struct snd_es18xx {
136 130
137 spinlock_t reg_lock; 131 spinlock_t reg_lock;
138 spinlock_t mixer_lock; 132 spinlock_t mixer_lock;
139 spinlock_t ctrl_lock;
140#ifdef CONFIG_PM 133#ifdef CONFIG_PM
141 unsigned char pm_reg; 134 unsigned char pm_reg;
142#endif 135#endif
143};
144
145struct snd_audiodrive {
146 struct snd_es18xx *chip;
147#ifdef CONFIG_PNP 136#ifdef CONFIG_PNP
148 struct pnp_dev *dev; 137 struct pnp_dev *dev;
149 struct pnp_dev *devc; 138 struct pnp_dev *devc;
@@ -359,7 +348,7 @@ static inline int snd_es18xx_mixer_writable(struct snd_es18xx *chip, unsigned ch
359} 348}
360 349
361 350
362static int snd_es18xx_reset(struct snd_es18xx *chip) 351static int __devinit snd_es18xx_reset(struct snd_es18xx *chip)
363{ 352{
364 int i; 353 int i;
365 outb(0x03, chip->port + 0x06); 354 outb(0x03, chip->port + 0x06);
@@ -495,8 +484,6 @@ static int snd_es18xx_playback1_prepare(struct snd_es18xx *chip,
495 unsigned int size = snd_pcm_lib_buffer_bytes(substream); 484 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
496 unsigned int count = snd_pcm_lib_period_bytes(substream); 485 unsigned int count = snd_pcm_lib_period_bytes(substream);
497 486
498 chip->dma2_size = size;
499
500 snd_es18xx_rate_set(chip, substream, DAC2); 487 snd_es18xx_rate_set(chip, substream, DAC2);
501 488
502 /* Transfer Count Reload */ 489 /* Transfer Count Reload */
@@ -596,8 +583,6 @@ static int snd_es18xx_capture_prepare(struct snd_pcm_substream *substream)
596 unsigned int size = snd_pcm_lib_buffer_bytes(substream); 583 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
597 unsigned int count = snd_pcm_lib_period_bytes(substream); 584 unsigned int count = snd_pcm_lib_period_bytes(substream);
598 585
599 chip->dma1_size = size;
600
601 snd_es18xx_reset_fifo(chip); 586 snd_es18xx_reset_fifo(chip);
602 587
603 /* Set stereo/mono */ 588 /* Set stereo/mono */
@@ -664,8 +649,6 @@ static int snd_es18xx_playback2_prepare(struct snd_es18xx *chip,
664 unsigned int size = snd_pcm_lib_buffer_bytes(substream); 649 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
665 unsigned int count = snd_pcm_lib_period_bytes(substream); 650 unsigned int count = snd_pcm_lib_period_bytes(substream);
666 651
667 chip->dma1_size = size;
668
669 snd_es18xx_reset_fifo(chip); 652 snd_es18xx_reset_fifo(chip);
670 653
671 /* Set stereo/mono */ 654 /* Set stereo/mono */
@@ -755,7 +738,8 @@ static int snd_es18xx_playback_trigger(struct snd_pcm_substream *substream,
755 738
756static irqreturn_t snd_es18xx_interrupt(int irq, void *dev_id) 739static irqreturn_t snd_es18xx_interrupt(int irq, void *dev_id)
757{ 740{
758 struct snd_es18xx *chip = dev_id; 741 struct snd_card *card = dev_id;
742 struct snd_es18xx *chip = card->private_data;
759 unsigned char status; 743 unsigned char status;
760 744
761 if (chip->caps & ES18XX_CONTROL) { 745 if (chip->caps & ES18XX_CONTROL) {
@@ -805,12 +789,16 @@ static irqreturn_t snd_es18xx_interrupt(int irq, void *dev_id)
805 int split = 0; 789 int split = 0;
806 if (chip->caps & ES18XX_HWV) { 790 if (chip->caps & ES18XX_HWV) {
807 split = snd_es18xx_mixer_read(chip, 0x64) & 0x80; 791 split = snd_es18xx_mixer_read(chip, 0x64) & 0x80;
808 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->hw_switch->id); 792 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
809 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->hw_volume->id); 793 &chip->hw_switch->id);
794 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
795 &chip->hw_volume->id);
810 } 796 }
811 if (!split) { 797 if (!split) {
812 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->master_switch->id); 798 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
813 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->master_volume->id); 799 &chip->master_switch->id);
800 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
801 &chip->master_volume->id);
814 } 802 }
815 /* ack interrupt */ 803 /* ack interrupt */
816 snd_es18xx_mixer_write(chip, 0x66, 0x00); 804 snd_es18xx_mixer_write(chip, 0x66, 0x00);
@@ -821,17 +809,18 @@ static irqreturn_t snd_es18xx_interrupt(int irq, void *dev_id)
821static snd_pcm_uframes_t snd_es18xx_playback_pointer(struct snd_pcm_substream *substream) 809static snd_pcm_uframes_t snd_es18xx_playback_pointer(struct snd_pcm_substream *substream)
822{ 810{
823 struct snd_es18xx *chip = snd_pcm_substream_chip(substream); 811 struct snd_es18xx *chip = snd_pcm_substream_chip(substream);
812 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
824 int pos; 813 int pos;
825 814
826 if (substream->number == 0 && (chip->caps & ES18XX_PCM2)) { 815 if (substream->number == 0 && (chip->caps & ES18XX_PCM2)) {
827 if (!(chip->active & DAC2)) 816 if (!(chip->active & DAC2))
828 return 0; 817 return 0;
829 pos = snd_dma_pointer(chip->dma2, chip->dma2_size); 818 pos = snd_dma_pointer(chip->dma2, size);
830 return pos >> chip->dma2_shift; 819 return pos >> chip->dma2_shift;
831 } else { 820 } else {
832 if (!(chip->active & DAC1)) 821 if (!(chip->active & DAC1))
833 return 0; 822 return 0;
834 pos = snd_dma_pointer(chip->dma1, chip->dma1_size); 823 pos = snd_dma_pointer(chip->dma1, size);
835 return pos >> chip->dma1_shift; 824 return pos >> chip->dma1_shift;
836 } 825 }
837} 826}
@@ -839,11 +828,12 @@ static snd_pcm_uframes_t snd_es18xx_playback_pointer(struct snd_pcm_substream *s
839static snd_pcm_uframes_t snd_es18xx_capture_pointer(struct snd_pcm_substream *substream) 828static snd_pcm_uframes_t snd_es18xx_capture_pointer(struct snd_pcm_substream *substream)
840{ 829{
841 struct snd_es18xx *chip = snd_pcm_substream_chip(substream); 830 struct snd_es18xx *chip = snd_pcm_substream_chip(substream);
831 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
842 int pos; 832 int pos;
843 833
844 if (!(chip->active & ADC1)) 834 if (!(chip->active & ADC1))
845 return 0; 835 return 0;
846 pos = snd_dma_pointer(chip->dma1, chip->dma1_size); 836 pos = snd_dma_pointer(chip->dma1, size);
847 return pos >> chip->dma1_shift; 837 return pos >> chip->dma1_shift;
848} 838}
849 839
@@ -974,9 +964,6 @@ static int snd_es18xx_capture_close(struct snd_pcm_substream *substream)
974 964
975static int snd_es18xx_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 965static int snd_es18xx_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
976{ 966{
977 static char *texts4Source[4] = {
978 "Mic", "CD", "Line", "Master"
979 };
980 static char *texts5Source[5] = { 967 static char *texts5Source[5] = {
981 "Mic", "CD", "Line", "Master", "Mix" 968 "Mic", "CD", "Line", "Master", "Mix"
982 }; 969 };
@@ -994,7 +981,8 @@ static int snd_es18xx_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_ele
994 uinfo->value.enumerated.items = 4; 981 uinfo->value.enumerated.items = 4;
995 if (uinfo->value.enumerated.item > 3) 982 if (uinfo->value.enumerated.item > 3)
996 uinfo->value.enumerated.item = 3; 983 uinfo->value.enumerated.item = 3;
997 strcpy(uinfo->value.enumerated.name, texts4Source[uinfo->value.enumerated.item]); 984 strcpy(uinfo->value.enumerated.name,
985 texts5Source[uinfo->value.enumerated.item]);
998 break; 986 break;
999 case 0x1887: 987 case 0x1887:
1000 case 0x1888: 988 case 0x1888:
@@ -1313,7 +1301,7 @@ ES18XX_DOUBLE("Aux Capture Volume", 0, 0x6c, 0x6c, 4, 0, 15, 0)
1313 * The chipset specific mixer controls 1301 * The chipset specific mixer controls
1314 */ 1302 */
1315static struct snd_kcontrol_new snd_es18xx_opt_speaker = 1303static struct snd_kcontrol_new snd_es18xx_opt_speaker =
1316 ES18XX_SINGLE("PC Speaker Playback Volume", 0, 0x3c, 0, 7, 0); 1304 ES18XX_SINGLE("Beep Playback Volume", 0, 0x3c, 0, 7, 0);
1317 1305
1318static struct snd_kcontrol_new snd_es18xx_opt_1869[] = { 1306static struct snd_kcontrol_new snd_es18xx_opt_1869[] = {
1319ES18XX_SINGLE("Capture Switch", 0, 0x1c, 4, 1, 1), 1307ES18XX_SINGLE("Capture Switch", 0, 0x1c, 4, 1, 1),
@@ -1378,11 +1366,9 @@ ES18XX_SINGLE("Hardware Master Volume Split", 0, 0x64, 7, 1, 0),
1378static int __devinit snd_es18xx_config_read(struct snd_es18xx *chip, unsigned char reg) 1366static int __devinit snd_es18xx_config_read(struct snd_es18xx *chip, unsigned char reg)
1379{ 1367{
1380 int data; 1368 int data;
1381 unsigned long flags; 1369
1382 spin_lock_irqsave(&chip->ctrl_lock, flags);
1383 outb(reg, chip->ctrl_port); 1370 outb(reg, chip->ctrl_port);
1384 data = inb(chip->ctrl_port + 1); 1371 data = inb(chip->ctrl_port + 1);
1385 spin_unlock_irqrestore(&chip->ctrl_lock, flags);
1386 return data; 1372 return data;
1387} 1373}
1388 1374
@@ -1398,7 +1384,9 @@ static void __devinit snd_es18xx_config_write(struct snd_es18xx *chip,
1398#endif 1384#endif
1399} 1385}
1400 1386
1401static int __devinit snd_es18xx_initialize(struct snd_es18xx *chip) 1387static int __devinit snd_es18xx_initialize(struct snd_es18xx *chip,
1388 unsigned long mpu_port,
1389 unsigned long fm_port)
1402{ 1390{
1403 int mask = 0; 1391 int mask = 0;
1404 1392
@@ -1412,15 +1400,15 @@ static int __devinit snd_es18xx_initialize(struct snd_es18xx *chip)
1412 if (chip->caps & ES18XX_CONTROL) { 1400 if (chip->caps & ES18XX_CONTROL) {
1413 /* Hardware volume IRQ */ 1401 /* Hardware volume IRQ */
1414 snd_es18xx_config_write(chip, 0x27, chip->irq); 1402 snd_es18xx_config_write(chip, 0x27, chip->irq);
1415 if (chip->fm_port > 0 && chip->fm_port != SNDRV_AUTO_PORT) { 1403 if (fm_port > 0 && fm_port != SNDRV_AUTO_PORT) {
1416 /* FM I/O */ 1404 /* FM I/O */
1417 snd_es18xx_config_write(chip, 0x62, chip->fm_port >> 8); 1405 snd_es18xx_config_write(chip, 0x62, fm_port >> 8);
1418 snd_es18xx_config_write(chip, 0x63, chip->fm_port & 0xff); 1406 snd_es18xx_config_write(chip, 0x63, fm_port & 0xff);
1419 } 1407 }
1420 if (chip->mpu_port > 0 && chip->mpu_port != SNDRV_AUTO_PORT) { 1408 if (mpu_port > 0 && mpu_port != SNDRV_AUTO_PORT) {
1421 /* MPU-401 I/O */ 1409 /* MPU-401 I/O */
1422 snd_es18xx_config_write(chip, 0x64, chip->mpu_port >> 8); 1410 snd_es18xx_config_write(chip, 0x64, mpu_port >> 8);
1423 snd_es18xx_config_write(chip, 0x65, chip->mpu_port & 0xff); 1411 snd_es18xx_config_write(chip, 0x65, mpu_port & 0xff);
1424 /* MPU-401 IRQ */ 1412 /* MPU-401 IRQ */
1425 snd_es18xx_config_write(chip, 0x28, chip->irq); 1413 snd_es18xx_config_write(chip, 0x28, chip->irq);
1426 } 1414 }
@@ -1507,11 +1495,12 @@ static int __devinit snd_es18xx_initialize(struct snd_es18xx *chip)
1507 snd_es18xx_mixer_write(chip, 0x7A, 0x68); 1495 snd_es18xx_mixer_write(chip, 0x7A, 0x68);
1508 /* Enable and set hardware volume interrupt */ 1496 /* Enable and set hardware volume interrupt */
1509 snd_es18xx_mixer_write(chip, 0x64, 0x06); 1497 snd_es18xx_mixer_write(chip, 0x64, 0x06);
1510 if (chip->mpu_port > 0 && chip->mpu_port != SNDRV_AUTO_PORT) { 1498 if (mpu_port > 0 && mpu_port != SNDRV_AUTO_PORT) {
1511 /* MPU401 share irq with audio 1499 /* MPU401 share irq with audio
1512 Joystick enabled 1500 Joystick enabled
1513 FM enabled */ 1501 FM enabled */
1514 snd_es18xx_mixer_write(chip, 0x40, 0x43 | (chip->mpu_port & 0xf0) >> 1); 1502 snd_es18xx_mixer_write(chip, 0x40,
1503 0x43 | (mpu_port & 0xf0) >> 1);
1515 } 1504 }
1516 snd_es18xx_mixer_write(chip, 0x7f, ((irqmask + 1) << 1) | 0x01); 1505 snd_es18xx_mixer_write(chip, 0x7f, ((irqmask + 1) << 1) | 0x01);
1517 } 1506 }
@@ -1629,7 +1618,9 @@ static int __devinit snd_es18xx_identify(struct snd_es18xx *chip)
1629 return 0; 1618 return 0;
1630} 1619}
1631 1620
1632static int __devinit snd_es18xx_probe(struct snd_es18xx *chip) 1621static int __devinit snd_es18xx_probe(struct snd_es18xx *chip,
1622 unsigned long mpu_port,
1623 unsigned long fm_port)
1633{ 1624{
1634 if (snd_es18xx_identify(chip) < 0) { 1625 if (snd_es18xx_identify(chip) < 0) {
1635 snd_printk(KERN_ERR PFX "[0x%lx] ESS chip not found\n", chip->port); 1626 snd_printk(KERN_ERR PFX "[0x%lx] ESS chip not found\n", chip->port);
@@ -1650,8 +1641,6 @@ static int __devinit snd_es18xx_probe(struct snd_es18xx *chip)
1650 chip->caps = ES18XX_PCM2 | ES18XX_SPATIALIZER | ES18XX_RECMIX | ES18XX_NEW_RATE | ES18XX_AUXB | ES18XX_I2S | ES18XX_CONTROL | ES18XX_HWV; 1641 chip->caps = ES18XX_PCM2 | ES18XX_SPATIALIZER | ES18XX_RECMIX | ES18XX_NEW_RATE | ES18XX_AUXB | ES18XX_I2S | ES18XX_CONTROL | ES18XX_HWV;
1651 break; 1642 break;
1652 case 0x1887: 1643 case 0x1887:
1653 chip->caps = ES18XX_PCM2 | ES18XX_RECMIX | ES18XX_AUXB | ES18XX_DUPLEX_SAME;
1654 break;
1655 case 0x1888: 1644 case 0x1888:
1656 chip->caps = ES18XX_PCM2 | ES18XX_RECMIX | ES18XX_AUXB | ES18XX_DUPLEX_SAME; 1645 chip->caps = ES18XX_PCM2 | ES18XX_RECMIX | ES18XX_AUXB | ES18XX_DUPLEX_SAME;
1657 break; 1646 break;
@@ -1666,7 +1655,7 @@ static int __devinit snd_es18xx_probe(struct snd_es18xx *chip)
1666 if (chip->dma1 == chip->dma2) 1655 if (chip->dma1 == chip->dma2)
1667 chip->caps &= ~(ES18XX_PCM2 | ES18XX_DUPLEX_SAME); 1656 chip->caps &= ~(ES18XX_PCM2 | ES18XX_DUPLEX_SAME);
1668 1657
1669 return snd_es18xx_initialize(chip); 1658 return snd_es18xx_initialize(chip, mpu_port, fm_port);
1670} 1659}
1671 1660
1672static struct snd_pcm_ops snd_es18xx_playback_ops = { 1661static struct snd_pcm_ops snd_es18xx_playback_ops = {
@@ -1691,8 +1680,10 @@ static struct snd_pcm_ops snd_es18xx_capture_ops = {
1691 .pointer = snd_es18xx_capture_pointer, 1680 .pointer = snd_es18xx_capture_pointer,
1692}; 1681};
1693 1682
1694static int __devinit snd_es18xx_pcm(struct snd_es18xx *chip, int device, struct snd_pcm ** rpcm) 1683static int __devinit snd_es18xx_pcm(struct snd_card *card, int device,
1684 struct snd_pcm **rpcm)
1695{ 1685{
1686 struct snd_es18xx *chip = card->private_data;
1696 struct snd_pcm *pcm; 1687 struct snd_pcm *pcm;
1697 char str[16]; 1688 char str[16];
1698 int err; 1689 int err;
@@ -1701,9 +1692,9 @@ static int __devinit snd_es18xx_pcm(struct snd_es18xx *chip, int device, struct
1701 *rpcm = NULL; 1692 *rpcm = NULL;
1702 sprintf(str, "ES%x", chip->version); 1693 sprintf(str, "ES%x", chip->version);
1703 if (chip->caps & ES18XX_PCM2) 1694 if (chip->caps & ES18XX_PCM2)
1704 err = snd_pcm_new(chip->card, str, device, 2, 1, &pcm); 1695 err = snd_pcm_new(card, str, device, 2, 1, &pcm);
1705 else 1696 else
1706 err = snd_pcm_new(chip->card, str, device, 1, 1, &pcm); 1697 err = snd_pcm_new(card, str, device, 1, 1, &pcm);
1707 if (err < 0) 1698 if (err < 0)
1708 return err; 1699 return err;
1709 1700
@@ -1734,10 +1725,9 @@ static int __devinit snd_es18xx_pcm(struct snd_es18xx *chip, int device, struct
1734#ifdef CONFIG_PM 1725#ifdef CONFIG_PM
1735static int snd_es18xx_suspend(struct snd_card *card, pm_message_t state) 1726static int snd_es18xx_suspend(struct snd_card *card, pm_message_t state)
1736{ 1727{
1737 struct snd_audiodrive *acard = card->private_data; 1728 struct snd_es18xx *chip = card->private_data;
1738 struct snd_es18xx *chip = acard->chip;
1739 1729
1740 snd_power_change_state(chip->card, SNDRV_CTL_POWER_D3hot); 1730 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
1741 1731
1742 snd_pcm_suspend_all(chip->pcm); 1732 snd_pcm_suspend_all(chip->pcm);
1743 1733
@@ -1752,24 +1742,25 @@ static int snd_es18xx_suspend(struct snd_card *card, pm_message_t state)
1752 1742
1753static int snd_es18xx_resume(struct snd_card *card) 1743static int snd_es18xx_resume(struct snd_card *card)
1754{ 1744{
1755 struct snd_audiodrive *acard = card->private_data; 1745 struct snd_es18xx *chip = card->private_data;
1756 struct snd_es18xx *chip = acard->chip;
1757 1746
1758 /* restore PM register, we won't wake till (not 0x07) i/o activity though */ 1747 /* restore PM register, we won't wake till (not 0x07) i/o activity though */
1759 snd_es18xx_write(chip, ES18XX_PM, chip->pm_reg ^= ES18XX_PM_FM); 1748 snd_es18xx_write(chip, ES18XX_PM, chip->pm_reg ^= ES18XX_PM_FM);
1760 1749
1761 snd_power_change_state(chip->card, SNDRV_CTL_POWER_D0); 1750 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
1762 return 0; 1751 return 0;
1763} 1752}
1764#endif /* CONFIG_PM */ 1753#endif /* CONFIG_PM */
1765 1754
1766static int snd_es18xx_free(struct snd_es18xx *chip) 1755static int snd_es18xx_free(struct snd_card *card)
1767{ 1756{
1757 struct snd_es18xx *chip = card->private_data;
1758
1768 release_and_free_resource(chip->res_port); 1759 release_and_free_resource(chip->res_port);
1769 release_and_free_resource(chip->res_ctrl_port); 1760 release_and_free_resource(chip->res_ctrl_port);
1770 release_and_free_resource(chip->res_mpu_port); 1761 release_and_free_resource(chip->res_mpu_port);
1771 if (chip->irq >= 0) 1762 if (chip->irq >= 0)
1772 free_irq(chip->irq, (void *) chip); 1763 free_irq(chip->irq, (void *) card);
1773 if (chip->dma1 >= 0) { 1764 if (chip->dma1 >= 0) {
1774 disable_dma(chip->dma1); 1765 disable_dma(chip->dma1);
1775 free_dma(chip->dma1); 1766 free_dma(chip->dma1);
@@ -1778,93 +1769,82 @@ static int snd_es18xx_free(struct snd_es18xx *chip)
1778 disable_dma(chip->dma2); 1769 disable_dma(chip->dma2);
1779 free_dma(chip->dma2); 1770 free_dma(chip->dma2);
1780 } 1771 }
1781 kfree(chip);
1782 return 0; 1772 return 0;
1783} 1773}
1784 1774
1785static int snd_es18xx_dev_free(struct snd_device *device) 1775static int snd_es18xx_dev_free(struct snd_device *device)
1786{ 1776{
1787 struct snd_es18xx *chip = device->device_data; 1777 return snd_es18xx_free(device->card);
1788 return snd_es18xx_free(chip);
1789} 1778}
1790 1779
1791static int __devinit snd_es18xx_new_device(struct snd_card *card, 1780static int __devinit snd_es18xx_new_device(struct snd_card *card,
1792 unsigned long port, 1781 unsigned long port,
1793 unsigned long mpu_port, 1782 unsigned long mpu_port,
1794 unsigned long fm_port, 1783 unsigned long fm_port,
1795 int irq, int dma1, int dma2, 1784 int irq, int dma1, int dma2)
1796 struct snd_es18xx ** rchip)
1797{ 1785{
1798 struct snd_es18xx *chip; 1786 struct snd_es18xx *chip = card->private_data;
1799 static struct snd_device_ops ops = { 1787 static struct snd_device_ops ops = {
1800 .dev_free = snd_es18xx_dev_free, 1788 .dev_free = snd_es18xx_dev_free,
1801 }; 1789 };
1802 int err; 1790 int err;
1803 1791
1804 *rchip = NULL;
1805 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
1806 if (chip == NULL)
1807 return -ENOMEM;
1808 spin_lock_init(&chip->reg_lock); 1792 spin_lock_init(&chip->reg_lock);
1809 spin_lock_init(&chip->mixer_lock); 1793 spin_lock_init(&chip->mixer_lock);
1810 spin_lock_init(&chip->ctrl_lock);
1811 chip->card = card;
1812 chip->port = port; 1794 chip->port = port;
1813 chip->mpu_port = mpu_port;
1814 chip->fm_port = fm_port;
1815 chip->irq = -1; 1795 chip->irq = -1;
1816 chip->dma1 = -1; 1796 chip->dma1 = -1;
1817 chip->dma2 = -1; 1797 chip->dma2 = -1;
1818 chip->audio2_vol = 0x00; 1798 chip->audio2_vol = 0x00;
1819 chip->active = 0; 1799 chip->active = 0;
1820 1800
1821 if ((chip->res_port = request_region(port, 16, "ES18xx")) == NULL) { 1801 chip->res_port = request_region(port, 16, "ES18xx");
1822 snd_es18xx_free(chip); 1802 if (chip->res_port == NULL) {
1803 snd_es18xx_free(card);
1823 snd_printk(KERN_ERR PFX "unable to grap ports 0x%lx-0x%lx\n", port, port + 16 - 1); 1804 snd_printk(KERN_ERR PFX "unable to grap ports 0x%lx-0x%lx\n", port, port + 16 - 1);
1824 return -EBUSY; 1805 return -EBUSY;
1825 } 1806 }
1826 1807
1827 if (request_irq(irq, snd_es18xx_interrupt, IRQF_DISABLED, "ES18xx", (void *) chip)) { 1808 if (request_irq(irq, snd_es18xx_interrupt, IRQF_DISABLED, "ES18xx",
1828 snd_es18xx_free(chip); 1809 (void *) card)) {
1810 snd_es18xx_free(card);
1829 snd_printk(KERN_ERR PFX "unable to grap IRQ %d\n", irq); 1811 snd_printk(KERN_ERR PFX "unable to grap IRQ %d\n", irq);
1830 return -EBUSY; 1812 return -EBUSY;
1831 } 1813 }
1832 chip->irq = irq; 1814 chip->irq = irq;
1833 1815
1834 if (request_dma(dma1, "ES18xx DMA 1")) { 1816 if (request_dma(dma1, "ES18xx DMA 1")) {
1835 snd_es18xx_free(chip); 1817 snd_es18xx_free(card);
1836 snd_printk(KERN_ERR PFX "unable to grap DMA1 %d\n", dma1); 1818 snd_printk(KERN_ERR PFX "unable to grap DMA1 %d\n", dma1);
1837 return -EBUSY; 1819 return -EBUSY;
1838 } 1820 }
1839 chip->dma1 = dma1; 1821 chip->dma1 = dma1;
1840 1822
1841 if (dma2 != dma1 && request_dma(dma2, "ES18xx DMA 2")) { 1823 if (dma2 != dma1 && request_dma(dma2, "ES18xx DMA 2")) {
1842 snd_es18xx_free(chip); 1824 snd_es18xx_free(card);
1843 snd_printk(KERN_ERR PFX "unable to grap DMA2 %d\n", dma2); 1825 snd_printk(KERN_ERR PFX "unable to grap DMA2 %d\n", dma2);
1844 return -EBUSY; 1826 return -EBUSY;
1845 } 1827 }
1846 chip->dma2 = dma2; 1828 chip->dma2 = dma2;
1847 1829
1848 if (snd_es18xx_probe(chip) < 0) { 1830 if (snd_es18xx_probe(chip, mpu_port, fm_port) < 0) {
1849 snd_es18xx_free(chip); 1831 snd_es18xx_free(card);
1850 return -ENODEV; 1832 return -ENODEV;
1851 } 1833 }
1852 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { 1834 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
1853 snd_es18xx_free(chip); 1835 if (err < 0) {
1836 snd_es18xx_free(card);
1854 return err; 1837 return err;
1855 } 1838 }
1856 *rchip = chip;
1857 return 0; 1839 return 0;
1858} 1840}
1859 1841
1860static int __devinit snd_es18xx_mixer(struct snd_es18xx *chip) 1842static int __devinit snd_es18xx_mixer(struct snd_card *card)
1861{ 1843{
1862 struct snd_card *card; 1844 struct snd_es18xx *chip = card->private_data;
1863 int err; 1845 int err;
1864 unsigned int idx; 1846 unsigned int idx;
1865 1847
1866 card = chip->card;
1867
1868 strcpy(card->mixername, chip->pcm->name); 1848 strcpy(card->mixername, chip->pcm->name);
1869 1849
1870 for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_base_controls); idx++) { 1850 for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_base_controls); idx++) {
@@ -1986,7 +1966,7 @@ static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
1986static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ 1966static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
1987static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */ 1967static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */
1988#ifdef CONFIG_PNP 1968#ifdef CONFIG_PNP
1989static int isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; 1969static int isapnp[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP;
1990#endif 1970#endif
1991static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240,0x260,0x280 */ 1971static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240,0x260,0x280 */
1992#ifndef CONFIG_PNP 1972#ifndef CONFIG_PNP
@@ -2063,11 +2043,11 @@ static int __devinit snd_audiodrive_pnp_init_main(int dev, struct pnp_dev *pdev)
2063 return 0; 2043 return 0;
2064} 2044}
2065 2045
2066static int __devinit snd_audiodrive_pnp(int dev, struct snd_audiodrive *acard, 2046static int __devinit snd_audiodrive_pnp(int dev, struct snd_es18xx *chip,
2067 struct pnp_dev *pdev) 2047 struct pnp_dev *pdev)
2068{ 2048{
2069 acard->dev = pdev; 2049 chip->dev = pdev;
2070 if (snd_audiodrive_pnp_init_main(dev, acard->dev) < 0) 2050 if (snd_audiodrive_pnp_init_main(dev, chip->dev) < 0)
2071 return -EBUSY; 2051 return -EBUSY;
2072 return 0; 2052 return 0;
2073} 2053}
@@ -2093,26 +2073,26 @@ static struct pnp_card_device_id snd_audiodrive_pnpids[] = {
2093 2073
2094MODULE_DEVICE_TABLE(pnp_card, snd_audiodrive_pnpids); 2074MODULE_DEVICE_TABLE(pnp_card, snd_audiodrive_pnpids);
2095 2075
2096static int __devinit snd_audiodrive_pnpc(int dev, struct snd_audiodrive *acard, 2076static int __devinit snd_audiodrive_pnpc(int dev, struct snd_es18xx *chip,
2097 struct pnp_card_link *card, 2077 struct pnp_card_link *card,
2098 const struct pnp_card_device_id *id) 2078 const struct pnp_card_device_id *id)
2099{ 2079{
2100 acard->dev = pnp_request_card_device(card, id->devs[0].id, NULL); 2080 chip->dev = pnp_request_card_device(card, id->devs[0].id, NULL);
2101 if (acard->dev == NULL) 2081 if (chip->dev == NULL)
2102 return -EBUSY; 2082 return -EBUSY;
2103 2083
2104 acard->devc = pnp_request_card_device(card, id->devs[1].id, NULL); 2084 chip->devc = pnp_request_card_device(card, id->devs[1].id, NULL);
2105 if (acard->devc == NULL) 2085 if (chip->devc == NULL)
2106 return -EBUSY; 2086 return -EBUSY;
2107 2087
2108 /* Control port initialization */ 2088 /* Control port initialization */
2109 if (pnp_activate_dev(acard->devc) < 0) { 2089 if (pnp_activate_dev(chip->devc) < 0) {
2110 snd_printk(KERN_ERR PFX "PnP control configure failure (out of resources?)\n"); 2090 snd_printk(KERN_ERR PFX "PnP control configure failure (out of resources?)\n");
2111 return -EAGAIN; 2091 return -EAGAIN;
2112 } 2092 }
2113 snd_printdd("pnp: port=0x%llx\n", 2093 snd_printdd("pnp: port=0x%llx\n",
2114 (unsigned long long)pnp_port_start(acard->devc, 0)); 2094 (unsigned long long)pnp_port_start(chip->devc, 0));
2115 if (snd_audiodrive_pnp_init_main(dev, acard->dev) < 0) 2095 if (snd_audiodrive_pnp_init_main(dev, chip->dev) < 0)
2116 return -EBUSY; 2096 return -EBUSY;
2117 2097
2118 return 0; 2098 return 0;
@@ -2128,24 +2108,20 @@ static int __devinit snd_audiodrive_pnpc(int dev, struct snd_audiodrive *acard,
2128static int snd_es18xx_card_new(int dev, struct snd_card **cardp) 2108static int snd_es18xx_card_new(int dev, struct snd_card **cardp)
2129{ 2109{
2130 return snd_card_create(index[dev], id[dev], THIS_MODULE, 2110 return snd_card_create(index[dev], id[dev], THIS_MODULE,
2131 sizeof(struct snd_audiodrive), cardp); 2111 sizeof(struct snd_es18xx), cardp);
2132} 2112}
2133 2113
2134static int __devinit snd_audiodrive_probe(struct snd_card *card, int dev) 2114static int __devinit snd_audiodrive_probe(struct snd_card *card, int dev)
2135{ 2115{
2136 struct snd_audiodrive *acard = card->private_data; 2116 struct snd_es18xx *chip = card->private_data;
2137 struct snd_es18xx *chip;
2138 struct snd_opl3 *opl3; 2117 struct snd_opl3 *opl3;
2139 int err; 2118 int err;
2140 2119
2141 if ((err = snd_es18xx_new_device(card, 2120 err = snd_es18xx_new_device(card,
2142 port[dev], 2121 port[dev], mpu_port[dev], fm_port[dev],
2143 mpu_port[dev], 2122 irq[dev], dma1[dev], dma2[dev]);
2144 fm_port[dev], 2123 if (err < 0)
2145 irq[dev], dma1[dev], dma2[dev],
2146 &chip)) < 0)
2147 return err; 2124 return err;
2148 acard->chip = chip;
2149 2125
2150 sprintf(card->driver, "ES%x", chip->version); 2126 sprintf(card->driver, "ES%x", chip->version);
2151 2127
@@ -2161,26 +2137,32 @@ static int __devinit snd_audiodrive_probe(struct snd_card *card, int dev)
2161 chip->port, 2137 chip->port,
2162 irq[dev], dma1[dev]); 2138 irq[dev], dma1[dev]);
2163 2139
2164 if ((err = snd_es18xx_pcm(chip, 0, NULL)) < 0) 2140 err = snd_es18xx_pcm(card, 0, NULL);
2141 if (err < 0)
2165 return err; 2142 return err;
2166 2143
2167 if ((err = snd_es18xx_mixer(chip)) < 0) 2144 err = snd_es18xx_mixer(card);
2145 if (err < 0)
2168 return err; 2146 return err;
2169 2147
2170 if (fm_port[dev] > 0 && fm_port[dev] != SNDRV_AUTO_PORT) { 2148 if (fm_port[dev] > 0 && fm_port[dev] != SNDRV_AUTO_PORT) {
2171 if (snd_opl3_create(card, chip->fm_port, chip->fm_port + 2, OPL3_HW_OPL3, 0, &opl3) < 0) { 2149 if (snd_opl3_create(card, fm_port[dev], fm_port[dev] + 2,
2172 snd_printk(KERN_WARNING PFX "opl3 not detected at 0x%lx\n", chip->fm_port); 2150 OPL3_HW_OPL3, 0, &opl3) < 0) {
2151 snd_printk(KERN_WARNING PFX
2152 "opl3 not detected at 0x%lx\n",
2153 fm_port[dev]);
2173 } else { 2154 } else {
2174 if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) 2155 err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
2156 if (err < 0)
2175 return err; 2157 return err;
2176 } 2158 }
2177 } 2159 }
2178 2160
2179 if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) { 2161 if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) {
2180 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_ES18XX, 2162 err = snd_mpu401_uart_new(card, 0, MPU401_HW_ES18XX,
2181 chip->mpu_port, 0, 2163 mpu_port[dev], 0,
2182 irq[dev], 0, 2164 irq[dev], 0, &chip->rmidi);
2183 &chip->rmidi)) < 0) 2165 if (err < 0)
2184 return err; 2166 return err;
2185 } 2167 }
2186 2168
diff --git a/sound/isa/gus/gus_mem.c b/sound/isa/gus/gus_mem.c
index 661205c4dcea..af888a022fc0 100644
--- a/sound/isa/gus/gus_mem.c
+++ b/sound/isa/gus/gus_mem.c
@@ -127,7 +127,8 @@ static struct snd_gf1_mem_block *snd_gf1_mem_share(struct snd_gf1_mem * alloc,
127 !share_id[2] && !share_id[3]) 127 !share_id[2] && !share_id[3])
128 return NULL; 128 return NULL;
129 for (block = alloc->first; block; block = block->next) 129 for (block = alloc->first; block; block = block->next)
130 if (!memcmp(share_id, block->share_id, sizeof(share_id))) 130 if (!memcmp(share_id, block->share_id,
131 sizeof(block->share_id)))
131 return block; 132 return block;
132 return NULL; 133 return NULL;
133} 134}
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 cb9aa4c4edd0..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>
@@ -162,7 +163,7 @@ int snd_msndmidi_new(struct snd_card *card, int device)
162 err = snd_rawmidi_new(card, "MSND-MIDI", device, 1, 1, &rmidi); 163 err = snd_rawmidi_new(card, "MSND-MIDI", device, 1, 1, &rmidi);
163 if (err < 0) 164 if (err < 0)
164 return err; 165 return err;
165 mpu = kcalloc(1, sizeof(*mpu), GFP_KERNEL); 166 mpu = kzalloc(sizeof(*mpu), GFP_KERNEL);
166 if (mpu == NULL) { 167 if (mpu == NULL) {
167 snd_device_free(card, rmidi); 168 snd_device_free(card, rmidi);
168 return -ENOMEM; 169 return -ENOMEM;
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 02e30d7c6a93..8c24102d0d93 100644
--- a/sound/isa/opti9xx/miro.c
+++ b/sound/isa/opti9xx/miro.c
@@ -25,8 +25,8 @@
25#include <linux/init.h> 25#include <linux/init.h>
26#include <linux/err.h> 26#include <linux/err.h>
27#include <linux/isa.h> 27#include <linux/isa.h>
28#include <linux/pnp.h>
28#include <linux/delay.h> 29#include <linux/delay.h>
29#include <linux/slab.h>
30#include <linux/ioport.h> 30#include <linux/ioport.h>
31#include <linux/moduleparam.h> 31#include <linux/moduleparam.h>
32#include <asm/io.h> 32#include <asm/io.h>
@@ -40,7 +40,7 @@
40#define SNDRV_LEGACY_FIND_FREE_IRQ 40#define SNDRV_LEGACY_FIND_FREE_IRQ
41#define SNDRV_LEGACY_FIND_FREE_DMA 41#define SNDRV_LEGACY_FIND_FREE_DMA
42#include <sound/initval.h> 42#include <sound/initval.h>
43#include "miro.h" 43#include <sound/aci.h>
44 44
45MODULE_AUTHOR("Martin Langer <martin-langer@gmx.de>"); 45MODULE_AUTHOR("Martin Langer <martin-langer@gmx.de>");
46MODULE_LICENSE("GPL"); 46MODULE_LICENSE("GPL");
@@ -60,6 +60,9 @@ static int dma1 = SNDRV_DEFAULT_DMA1; /* 0,1,3 */
60static int dma2 = SNDRV_DEFAULT_DMA1; /* 0,1,3 */ 60static int dma2 = SNDRV_DEFAULT_DMA1; /* 0,1,3 */
61static int wss; 61static int wss;
62static int ide; 62static int ide;
63#ifdef CONFIG_PNP
64static int isapnp = 1; /* Enable ISA PnP detection */
65#endif
63 66
64module_param(index, int, 0444); 67module_param(index, int, 0444);
65MODULE_PARM_DESC(index, "Index value for miro soundcard."); 68MODULE_PARM_DESC(index, "Index value for miro soundcard.");
@@ -83,6 +86,10 @@ module_param(wss, int, 0444);
83MODULE_PARM_DESC(wss, "wss mode"); 86MODULE_PARM_DESC(wss, "wss mode");
84module_param(ide, int, 0444); 87module_param(ide, int, 0444);
85MODULE_PARM_DESC(ide, "enable ide port"); 88MODULE_PARM_DESC(ide, "enable ide port");
89#ifdef CONFIG_PNP
90module_param(isapnp, bool, 0444);
91MODULE_PARM_DESC(isapnp, "Enable ISA PnP detection for specified soundcard.");
92#endif
86 93
87#define OPTi9XX_HW_DETECT 0 94#define OPTi9XX_HW_DETECT 0
88#define OPTi9XX_HW_82C928 1 95#define OPTi9XX_HW_82C928 1
@@ -96,7 +103,6 @@ MODULE_PARM_DESC(ide, "enable ide port");
96 103
97#define OPTi9XX_MC_REG(n) n 104#define OPTi9XX_MC_REG(n) n
98 105
99
100struct snd_miro { 106struct snd_miro {
101 unsigned short hardware; 107 unsigned short hardware;
102 unsigned char password; 108 unsigned char password;
@@ -110,7 +116,6 @@ struct snd_miro {
110 unsigned long pwd_reg; 116 unsigned long pwd_reg;
111 117
112 spinlock_t lock; 118 spinlock_t lock;
113 struct snd_card *card;
114 struct snd_pcm *pcm; 119 struct snd_pcm *pcm;
115 120
116 long wss_base; 121 long wss_base;
@@ -118,42 +123,48 @@ struct snd_miro {
118 int dma1; 123 int dma1;
119 int dma2; 124 int dma2;
120 125
121 long fm_port;
122
123 long mpu_port; 126 long mpu_port;
124 int mpu_irq; 127 int mpu_irq;
125 128
126 unsigned long aci_port; 129 struct snd_miro_aci *aci;
127 int aci_vendor;
128 int aci_product;
129 int aci_version;
130 int aci_amp;
131 int aci_preamp;
132 int aci_solomode;
133
134 struct mutex aci_mutex;
135}; 130};
136 131
137static void snd_miro_proc_init(struct snd_miro * miro); 132static struct snd_miro_aci aci_device;
138 133
139static char * snd_opti9xx_names[] = { 134static char * snd_opti9xx_names[] = {
140 "unkown", 135 "unknown",
141 "82C928", "82C929", 136 "82C928", "82C929",
142 "82C924", "82C925", 137 "82C924", "82C925",
143 "82C930", "82C931", "82C933" 138 "82C930", "82C931", "82C933"
144}; 139};
145 140
141static int snd_miro_pnp_is_probed;
142
143#ifdef CONFIG_PNP
144
145static struct pnp_card_device_id snd_miro_pnpids[] = {
146 /* PCM20 and PCM12 in PnP mode */
147 { .id = "MIR0924",
148 .devs = { { "MIR0000" }, { "MIR0002" }, { "MIR0005" } }, },
149 { .id = "" }
150};
151
152MODULE_DEVICE_TABLE(pnp_card, snd_miro_pnpids);
153
154#endif /* CONFIG_PNP */
155
146/* 156/*
147 * ACI control 157 * ACI control
148 */ 158 */
149 159
150static int aci_busy_wait(struct snd_miro * miro) 160static int aci_busy_wait(struct snd_miro_aci *aci)
151{ 161{
152 long timeout; 162 long timeout;
153 unsigned char byte; 163 unsigned char byte;
154 164
155 for (timeout = 1; timeout <= ACI_MINTIME+30; timeout++) { 165 for (timeout = 1; timeout <= ACI_MINTIME + 30; timeout++) {
156 if (((byte=inb(miro->aci_port + ACI_REG_BUSY)) & 1) == 0) { 166 byte = inb(aci->aci_port + ACI_REG_BUSY);
167 if ((byte & 1) == 0) {
157 if (timeout >= ACI_MINTIME) 168 if (timeout >= ACI_MINTIME)
158 snd_printd("aci ready in round %ld.\n", 169 snd_printd("aci ready in round %ld.\n",
159 timeout-ACI_MINTIME); 170 timeout-ACI_MINTIME);
@@ -179,10 +190,10 @@ static int aci_busy_wait(struct snd_miro * miro)
179 return -EBUSY; 190 return -EBUSY;
180} 191}
181 192
182static inline int aci_write(struct snd_miro * miro, unsigned char byte) 193static inline int aci_write(struct snd_miro_aci *aci, unsigned char byte)
183{ 194{
184 if (aci_busy_wait(miro) >= 0) { 195 if (aci_busy_wait(aci) >= 0) {
185 outb(byte, miro->aci_port + ACI_REG_COMMAND); 196 outb(byte, aci->aci_port + ACI_REG_COMMAND);
186 return 0; 197 return 0;
187 } else { 198 } else {
188 snd_printk(KERN_ERR "aci busy, aci_write(0x%x) stopped.\n", byte); 199 snd_printk(KERN_ERR "aci busy, aci_write(0x%x) stopped.\n", byte);
@@ -190,12 +201,12 @@ static inline int aci_write(struct snd_miro * miro, unsigned char byte)
190 } 201 }
191} 202}
192 203
193static inline int aci_read(struct snd_miro * miro) 204static inline int aci_read(struct snd_miro_aci *aci)
194{ 205{
195 unsigned char byte; 206 unsigned char byte;
196 207
197 if (aci_busy_wait(miro) >= 0) { 208 if (aci_busy_wait(aci) >= 0) {
198 byte=inb(miro->aci_port + ACI_REG_STATUS); 209 byte = inb(aci->aci_port + ACI_REG_STATUS);
199 return byte; 210 return byte;
200 } else { 211 } else {
201 snd_printk(KERN_ERR "aci busy, aci_read() stopped.\n"); 212 snd_printk(KERN_ERR "aci busy, aci_read() stopped.\n");
@@ -203,39 +214,49 @@ static inline int aci_read(struct snd_miro * miro)
203 } 214 }
204} 215}
205 216
206static int aci_cmd(struct snd_miro * miro, int write1, int write2, int write3) 217int snd_aci_cmd(struct snd_miro_aci *aci, int write1, int write2, int write3)
207{ 218{
208 int write[] = {write1, write2, write3}; 219 int write[] = {write1, write2, write3};
209 int value, i; 220 int value, i;
210 221
211 if (mutex_lock_interruptible(&miro->aci_mutex)) 222 if (mutex_lock_interruptible(&aci->aci_mutex))
212 return -EINTR; 223 return -EINTR;
213 224
214 for (i=0; i<3; i++) { 225 for (i=0; i<3; i++) {
215 if (write[i]< 0 || write[i] > 255) 226 if (write[i]< 0 || write[i] > 255)
216 break; 227 break;
217 else { 228 else {
218 value = aci_write(miro, write[i]); 229 value = aci_write(aci, write[i]);
219 if (value < 0) 230 if (value < 0)
220 goto out; 231 goto out;
221 } 232 }
222 } 233 }
223 234
224 value = aci_read(miro); 235 value = aci_read(aci);
225 236
226out: mutex_unlock(&miro->aci_mutex); 237out: mutex_unlock(&aci->aci_mutex);
227 return value; 238 return value;
228} 239}
240EXPORT_SYMBOL(snd_aci_cmd);
241
242static int aci_getvalue(struct snd_miro_aci *aci, unsigned char index)
243{
244 return snd_aci_cmd(aci, ACI_STATUS, index, -1);
245}
229 246
230static int aci_getvalue(struct snd_miro * miro, unsigned char index) 247static int aci_setvalue(struct snd_miro_aci *aci, unsigned char index,
248 int value)
231{ 249{
232 return aci_cmd(miro, ACI_STATUS, index, -1); 250 return snd_aci_cmd(aci, index, value, -1);
233} 251}
234 252
235static int aci_setvalue(struct snd_miro * miro, unsigned char index, int value) 253struct snd_miro_aci *snd_aci_get_aci(void)
236{ 254{
237 return aci_cmd(miro, index, value, -1); 255 if (aci_device.aci_port == 0)
256 return NULL;
257 return &aci_device;
238} 258}
259EXPORT_SYMBOL(snd_aci_get_aci);
239 260
240/* 261/*
241 * MIXER part 262 * MIXER part
@@ -249,8 +270,10 @@ static int snd_miro_get_capture(struct snd_kcontrol *kcontrol,
249 struct snd_miro *miro = snd_kcontrol_chip(kcontrol); 270 struct snd_miro *miro = snd_kcontrol_chip(kcontrol);
250 int value; 271 int value;
251 272
252 if ((value = aci_getvalue(miro, ACI_S_GENERAL)) < 0) { 273 value = aci_getvalue(miro->aci, ACI_S_GENERAL);
253 snd_printk(KERN_ERR "snd_miro_get_capture() failed: %d\n", value); 274 if (value < 0) {
275 snd_printk(KERN_ERR "snd_miro_get_capture() failed: %d\n",
276 value);
254 return value; 277 return value;
255 } 278 }
256 279
@@ -267,13 +290,15 @@ static int snd_miro_put_capture(struct snd_kcontrol *kcontrol,
267 290
268 value = !(ucontrol->value.integer.value[0]); 291 value = !(ucontrol->value.integer.value[0]);
269 292
270 if ((error = aci_setvalue(miro, ACI_SET_SOLOMODE, value)) < 0) { 293 error = aci_setvalue(miro->aci, ACI_SET_SOLOMODE, value);
271 snd_printk(KERN_ERR "snd_miro_put_capture() failed: %d\n", error); 294 if (error < 0) {
295 snd_printk(KERN_ERR "snd_miro_put_capture() failed: %d\n",
296 error);
272 return error; 297 return error;
273 } 298 }
274 299
275 change = (value != miro->aci_solomode); 300 change = (value != miro->aci->aci_solomode);
276 miro->aci_solomode = value; 301 miro->aci->aci_solomode = value;
277 302
278 return change; 303 return change;
279} 304}
@@ -295,7 +320,7 @@ static int snd_miro_get_preamp(struct snd_kcontrol *kcontrol,
295 struct snd_miro *miro = snd_kcontrol_chip(kcontrol); 320 struct snd_miro *miro = snd_kcontrol_chip(kcontrol);
296 int value; 321 int value;
297 322
298 if (miro->aci_version <= 176) { 323 if (miro->aci->aci_version <= 176) {
299 324
300 /* 325 /*
301 OSS says it's not readable with versions < 176. 326 OSS says it's not readable with versions < 176.
@@ -303,12 +328,14 @@ static int snd_miro_get_preamp(struct snd_kcontrol *kcontrol,
303 which is a PCM12 with aci_version = 176. 328 which is a PCM12 with aci_version = 176.
304 */ 329 */
305 330
306 ucontrol->value.integer.value[0] = miro->aci_preamp; 331 ucontrol->value.integer.value[0] = miro->aci->aci_preamp;
307 return 0; 332 return 0;
308 } 333 }
309 334
310 if ((value = aci_getvalue(miro, ACI_GET_PREAMP)) < 0) { 335 value = aci_getvalue(miro->aci, ACI_GET_PREAMP);
311 snd_printk(KERN_ERR "snd_miro_get_preamp() failed: %d\n", value); 336 if (value < 0) {
337 snd_printk(KERN_ERR "snd_miro_get_preamp() failed: %d\n",
338 value);
312 return value; 339 return value;
313 } 340 }
314 341
@@ -325,13 +352,15 @@ static int snd_miro_put_preamp(struct snd_kcontrol *kcontrol,
325 352
326 value = ucontrol->value.integer.value[0]; 353 value = ucontrol->value.integer.value[0];
327 354
328 if ((error = aci_setvalue(miro, ACI_SET_PREAMP, value)) < 0) { 355 error = aci_setvalue(miro->aci, ACI_SET_PREAMP, value);
329 snd_printk(KERN_ERR "snd_miro_put_preamp() failed: %d\n", error); 356 if (error < 0) {
357 snd_printk(KERN_ERR "snd_miro_put_preamp() failed: %d\n",
358 error);
330 return error; 359 return error;
331 } 360 }
332 361
333 change = (value != miro->aci_preamp); 362 change = (value != miro->aci->aci_preamp);
334 miro->aci_preamp = value; 363 miro->aci->aci_preamp = value;
335 364
336 return change; 365 return change;
337} 366}
@@ -342,7 +371,7 @@ static int snd_miro_get_amp(struct snd_kcontrol *kcontrol,
342 struct snd_ctl_elem_value *ucontrol) 371 struct snd_ctl_elem_value *ucontrol)
343{ 372{
344 struct snd_miro *miro = snd_kcontrol_chip(kcontrol); 373 struct snd_miro *miro = snd_kcontrol_chip(kcontrol);
345 ucontrol->value.integer.value[0] = miro->aci_amp; 374 ucontrol->value.integer.value[0] = miro->aci->aci_amp;
346 375
347 return 0; 376 return 0;
348} 377}
@@ -355,13 +384,14 @@ static int snd_miro_put_amp(struct snd_kcontrol *kcontrol,
355 384
356 value = ucontrol->value.integer.value[0]; 385 value = ucontrol->value.integer.value[0];
357 386
358 if ((error = aci_setvalue(miro, ACI_SET_POWERAMP, value)) < 0) { 387 error = aci_setvalue(miro->aci, ACI_SET_POWERAMP, value);
388 if (error < 0) {
359 snd_printk(KERN_ERR "snd_miro_put_amp() to %d failed: %d\n", value, error); 389 snd_printk(KERN_ERR "snd_miro_put_amp() to %d failed: %d\n", value, error);
360 return error; 390 return error;
361 } 391 }
362 392
363 change = (value != miro->aci_amp); 393 change = (value != miro->aci->aci_amp);
364 miro->aci_amp = value; 394 miro->aci->aci_amp = value;
365 395
366 return change; 396 return change;
367} 397}
@@ -410,12 +440,14 @@ static int snd_miro_get_double(struct snd_kcontrol *kcontrol,
410 int right_reg = kcontrol->private_value & 0xff; 440 int right_reg = kcontrol->private_value & 0xff;
411 int left_reg = right_reg + 1; 441 int left_reg = right_reg + 1;
412 442
413 if ((right_val = aci_getvalue(miro, right_reg)) < 0) { 443 right_val = aci_getvalue(miro->aci, right_reg);
444 if (right_val < 0) {
414 snd_printk(KERN_ERR "aci_getvalue(%d) failed: %d\n", right_reg, right_val); 445 snd_printk(KERN_ERR "aci_getvalue(%d) failed: %d\n", right_reg, right_val);
415 return right_val; 446 return right_val;
416 } 447 }
417 448
418 if ((left_val = aci_getvalue(miro, left_reg)) < 0) { 449 left_val = aci_getvalue(miro->aci, left_reg);
450 if (left_val < 0) {
419 snd_printk(KERN_ERR "aci_getvalue(%d) failed: %d\n", left_reg, left_val); 451 snd_printk(KERN_ERR "aci_getvalue(%d) failed: %d\n", left_reg, left_val);
420 return left_val; 452 return left_val;
421 } 453 }
@@ -451,6 +483,7 @@ static int snd_miro_put_double(struct snd_kcontrol *kcontrol,
451 struct snd_ctl_elem_value *ucontrol) 483 struct snd_ctl_elem_value *ucontrol)
452{ 484{
453 struct snd_miro *miro = snd_kcontrol_chip(kcontrol); 485 struct snd_miro *miro = snd_kcontrol_chip(kcontrol);
486 struct snd_miro_aci *aci = miro->aci;
454 int left, right, left_old, right_old; 487 int left, right, left_old, right_old;
455 int setreg_left, setreg_right, getreg_left, getreg_right; 488 int setreg_left, setreg_right, getreg_left, getreg_right;
456 int change, error; 489 int change, error;
@@ -459,21 +492,21 @@ static int snd_miro_put_double(struct snd_kcontrol *kcontrol,
459 right = ucontrol->value.integer.value[1]; 492 right = ucontrol->value.integer.value[1];
460 493
461 setreg_right = (kcontrol->private_value >> 8) & 0xff; 494 setreg_right = (kcontrol->private_value >> 8) & 0xff;
462 if (setreg_right == ACI_SET_MASTER) { 495 setreg_left = setreg_right + 8;
463 setreg_left = setreg_right + 1; 496 if (setreg_right == ACI_SET_MASTER)
464 } else { 497 setreg_left -= 7;
465 setreg_left = setreg_right + 8;
466 }
467 498
468 getreg_right = kcontrol->private_value & 0xff; 499 getreg_right = kcontrol->private_value & 0xff;
469 getreg_left = getreg_right + 1; 500 getreg_left = getreg_right + 1;
470 501
471 if ((left_old = aci_getvalue(miro, getreg_left)) < 0) { 502 left_old = aci_getvalue(aci, getreg_left);
503 if (left_old < 0) {
472 snd_printk(KERN_ERR "aci_getvalue(%d) failed: %d\n", getreg_left, left_old); 504 snd_printk(KERN_ERR "aci_getvalue(%d) failed: %d\n", getreg_left, left_old);
473 return left_old; 505 return left_old;
474 } 506 }
475 507
476 if ((right_old = aci_getvalue(miro, getreg_right)) < 0) { 508 right_old = aci_getvalue(aci, getreg_right);
509 if (right_old < 0) {
477 snd_printk(KERN_ERR "aci_getvalue(%d) failed: %d\n", getreg_right, right_old); 510 snd_printk(KERN_ERR "aci_getvalue(%d) failed: %d\n", getreg_right, right_old);
478 return right_old; 511 return right_old;
479 } 512 }
@@ -492,13 +525,15 @@ static int snd_miro_put_double(struct snd_kcontrol *kcontrol,
492 right_old = 0x80 - right_old; 525 right_old = 0x80 - right_old;
493 526
494 if (left >= 0) { 527 if (left >= 0) {
495 if ((error = aci_setvalue(miro, setreg_left, left)) < 0) { 528 error = aci_setvalue(aci, setreg_left, left);
529 if (error < 0) {
496 snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n", 530 snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n",
497 left, error); 531 left, error);
498 return error; 532 return error;
499 } 533 }
500 } else { 534 } else {
501 if ((error = aci_setvalue(miro, setreg_left, 0x80 - left)) < 0) { 535 error = aci_setvalue(aci, setreg_left, 0x80 - left);
536 if (error < 0) {
502 snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n", 537 snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n",
503 0x80 - left, error); 538 0x80 - left, error);
504 return error; 539 return error;
@@ -506,13 +541,15 @@ static int snd_miro_put_double(struct snd_kcontrol *kcontrol,
506 } 541 }
507 542
508 if (right >= 0) { 543 if (right >= 0) {
509 if ((error = aci_setvalue(miro, setreg_right, right)) < 0) { 544 error = aci_setvalue(aci, setreg_right, right);
545 if (error < 0) {
510 snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n", 546 snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n",
511 right, error); 547 right, error);
512 return error; 548 return error;
513 } 549 }
514 } else { 550 } else {
515 if ((error = aci_setvalue(miro, setreg_right, 0x80 - right)) < 0) { 551 error = aci_setvalue(aci, setreg_right, 0x80 - right);
552 if (error < 0) {
516 snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n", 553 snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n",
517 0x80 - right, error); 554 0x80 - right, error);
518 return error; 555 return error;
@@ -530,12 +567,14 @@ static int snd_miro_put_double(struct snd_kcontrol *kcontrol,
530 left_old = 0x20 - left_old; 567 left_old = 0x20 - left_old;
531 right_old = 0x20 - right_old; 568 right_old = 0x20 - right_old;
532 569
533 if ((error = aci_setvalue(miro, setreg_left, 0x20 - left)) < 0) { 570 error = aci_setvalue(aci, setreg_left, 0x20 - left);
571 if (error < 0) {
534 snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n", 572 snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n",
535 0x20 - left, error); 573 0x20 - left, error);
536 return error; 574 return error;
537 } 575 }
538 if ((error = aci_setvalue(miro, setreg_right, 0x20 - right)) < 0) { 576 error = aci_setvalue(aci, setreg_right, 0x20 - right);
577 if (error < 0) {
539 snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n", 578 snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n",
540 0x20 - right, error); 579 0x20 - right, error);
541 return error; 580 return error;
@@ -633,11 +672,13 @@ static unsigned char aci_init_values[][2] __devinitdata = {
633static int __devinit snd_set_aci_init_values(struct snd_miro *miro) 672static int __devinit snd_set_aci_init_values(struct snd_miro *miro)
634{ 673{
635 int idx, error; 674 int idx, error;
675 struct snd_miro_aci *aci = miro->aci;
636 676
637 /* enable WSS on PCM1 */ 677 /* enable WSS on PCM1 */
638 678
639 if ((miro->aci_product == 'A') && wss) { 679 if ((aci->aci_product == 'A') && wss) {
640 if ((error = aci_setvalue(miro, ACI_SET_WSS, wss)) < 0) { 680 error = aci_setvalue(aci, ACI_SET_WSS, wss);
681 if (error < 0) {
641 snd_printk(KERN_ERR "enabling WSS mode failed\n"); 682 snd_printk(KERN_ERR "enabling WSS mode failed\n");
642 return error; 683 return error;
643 } 684 }
@@ -646,7 +687,8 @@ static int __devinit snd_set_aci_init_values(struct snd_miro *miro)
646 /* enable IDE port */ 687 /* enable IDE port */
647 688
648 if (ide) { 689 if (ide) {
649 if ((error = aci_setvalue(miro, ACI_SET_IDE, ide)) < 0) { 690 error = aci_setvalue(aci, ACI_SET_IDE, ide);
691 if (error < 0) {
650 snd_printk(KERN_ERR "enabling IDE port failed\n"); 692 snd_printk(KERN_ERR "enabling IDE port failed\n");
651 return error; 693 return error;
652 } 694 }
@@ -654,32 +696,31 @@ static int __devinit snd_set_aci_init_values(struct snd_miro *miro)
654 696
655 /* set common aci values */ 697 /* set common aci values */
656 698
657 for (idx = 0; idx < ARRAY_SIZE(aci_init_values); idx++) 699 for (idx = 0; idx < ARRAY_SIZE(aci_init_values); idx++) {
658 if ((error = aci_setvalue(miro, aci_init_values[idx][0], 700 error = aci_setvalue(aci, aci_init_values[idx][0],
659 aci_init_values[idx][1])) < 0) { 701 aci_init_values[idx][1]);
702 if (error < 0) {
660 snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n", 703 snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n",
661 aci_init_values[idx][0], error); 704 aci_init_values[idx][0], error);
662 return error; 705 return error;
663 } 706 }
664 707 }
665 miro->aci_amp = 0; 708 aci->aci_amp = 0;
666 miro->aci_preamp = 0; 709 aci->aci_preamp = 0;
667 miro->aci_solomode = 1; 710 aci->aci_solomode = 1;
668 711
669 return 0; 712 return 0;
670} 713}
671 714
672static int __devinit snd_miro_mixer(struct snd_miro *miro) 715static int __devinit snd_miro_mixer(struct snd_card *card,
716 struct snd_miro *miro)
673{ 717{
674 struct snd_card *card;
675 unsigned int idx; 718 unsigned int idx;
676 int err; 719 int err;
677 720
678 if (snd_BUG_ON(!miro || !miro->card)) 721 if (snd_BUG_ON(!miro || !card))
679 return -EINVAL; 722 return -EINVAL;
680 723
681 card = miro->card;
682
683 switch (miro->hardware) { 724 switch (miro->hardware) {
684 case OPTi9XX_HW_82C924: 725 case OPTi9XX_HW_82C924:
685 strcpy(card->mixername, "ACI & OPTi924"); 726 strcpy(card->mixername, "ACI & OPTi924");
@@ -697,7 +738,8 @@ static int __devinit snd_miro_mixer(struct snd_miro *miro)
697 return err; 738 return err;
698 } 739 }
699 740
700 if ((miro->aci_product == 'A') || (miro->aci_product == 'B')) { 741 if ((miro->aci->aci_product == 'A') ||
742 (miro->aci->aci_product == 'B')) {
701 /* PCM1/PCM12 with power-amp and Line 2 */ 743 /* PCM1/PCM12 with power-amp and Line 2 */
702 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_line_control[0], miro))) < 0) 744 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_line_control[0], miro))) < 0)
703 return err; 745 return err;
@@ -705,16 +747,17 @@ static int __devinit snd_miro_mixer(struct snd_miro *miro)
705 return err; 747 return err;
706 } 748 }
707 749
708 if ((miro->aci_product == 'B') || (miro->aci_product == 'C')) { 750 if ((miro->aci->aci_product == 'B') ||
751 (miro->aci->aci_product == 'C')) {
709 /* PCM12/PCM20 with mic-preamp */ 752 /* PCM12/PCM20 with mic-preamp */
710 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_preamp_control[0], miro))) < 0) 753 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_preamp_control[0], miro))) < 0)
711 return err; 754 return err;
712 if (miro->aci_version >= 176) 755 if (miro->aci->aci_version >= 176)
713 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_capture_control[0], miro))) < 0) 756 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_capture_control[0], miro))) < 0)
714 return err; 757 return err;
715 } 758 }
716 759
717 if (miro->aci_product == 'C') { 760 if (miro->aci->aci_product == 'C') {
718 /* PCM20 with radio and 7 band equalizer */ 761 /* PCM20 with radio and 7 band equalizer */
719 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_radio_control[0], miro))) < 0) 762 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_radio_control[0], miro))) < 0)
720 return err; 763 return err;
@@ -757,21 +800,26 @@ static int __devinit snd_miro_init(struct snd_miro *chip,
757 chip->irq = -1; 800 chip->irq = -1;
758 chip->dma1 = -1; 801 chip->dma1 = -1;
759 chip->dma2 = -1; 802 chip->dma2 = -1;
760 chip->fm_port = -1;
761 chip->mpu_port = -1; 803 chip->mpu_port = -1;
762 chip->mpu_irq = -1; 804 chip->mpu_irq = -1;
763 805
806 chip->pwd_reg = 3;
807
808#ifdef CONFIG_PNP
809 if (isapnp && chip->mc_base)
810 /* PnP resource gives the least 10 bits */
811 chip->mc_base |= 0xc00;
812 else
813#endif
814 chip->mc_base = 0xf8c;
815
764 switch (hardware) { 816 switch (hardware) {
765 case OPTi9XX_HW_82C929: 817 case OPTi9XX_HW_82C929:
766 chip->mc_base = 0xf8c;
767 chip->password = 0xe3; 818 chip->password = 0xe3;
768 chip->pwd_reg = 3;
769 break; 819 break;
770 820
771 case OPTi9XX_HW_82C924: 821 case OPTi9XX_HW_82C924:
772 chip->mc_base = 0xf8c;
773 chip->password = 0xe5; 822 chip->password = 0xe5;
774 chip->pwd_reg = 3;
775 break; 823 break;
776 824
777 default: 825 default:
@@ -853,14 +901,15 @@ static void snd_miro_proc_read(struct snd_info_entry * entry,
853 struct snd_info_buffer *buffer) 901 struct snd_info_buffer *buffer)
854{ 902{
855 struct snd_miro *miro = (struct snd_miro *) entry->private_data; 903 struct snd_miro *miro = (struct snd_miro *) entry->private_data;
904 struct snd_miro_aci *aci = miro->aci;
856 char* model = "unknown"; 905 char* model = "unknown";
857 906
858 /* miroSOUND PCM1 pro, early PCM12 */ 907 /* miroSOUND PCM1 pro, early PCM12 */
859 908
860 if ((miro->hardware == OPTi9XX_HW_82C929) && 909 if ((miro->hardware == OPTi9XX_HW_82C929) &&
861 (miro->aci_vendor == 'm') && 910 (aci->aci_vendor == 'm') &&
862 (miro->aci_product == 'A')) { 911 (aci->aci_product == 'A')) {
863 switch(miro->aci_version) { 912 switch (aci->aci_version) {
864 case 3: 913 case 3:
865 model = "miroSOUND PCM1 pro"; 914 model = "miroSOUND PCM1 pro";
866 break; 915 break;
@@ -873,9 +922,9 @@ static void snd_miro_proc_read(struct snd_info_entry * entry,
873 /* miroSOUND PCM12, PCM12 (Rev. E), PCM12 pnp */ 922 /* miroSOUND PCM12, PCM12 (Rev. E), PCM12 pnp */
874 923
875 if ((miro->hardware == OPTi9XX_HW_82C924) && 924 if ((miro->hardware == OPTi9XX_HW_82C924) &&
876 (miro->aci_vendor == 'm') && 925 (aci->aci_vendor == 'm') &&
877 (miro->aci_product == 'B')) { 926 (aci->aci_product == 'B')) {
878 switch(miro->aci_version) { 927 switch (aci->aci_version) {
879 case 4: 928 case 4:
880 model = "miroSOUND PCM12"; 929 model = "miroSOUND PCM12";
881 break; 930 break;
@@ -891,9 +940,9 @@ static void snd_miro_proc_read(struct snd_info_entry * entry,
891 /* miroSOUND PCM20 radio */ 940 /* miroSOUND PCM20 radio */
892 941
893 if ((miro->hardware == OPTi9XX_HW_82C924) && 942 if ((miro->hardware == OPTi9XX_HW_82C924) &&
894 (miro->aci_vendor == 'm') && 943 (aci->aci_vendor == 'm') &&
895 (miro->aci_product == 'C')) { 944 (aci->aci_product == 'C')) {
896 switch(miro->aci_version) { 945 switch (aci->aci_version) {
897 case 7: 946 case 7:
898 model = "miroSOUND PCM20 radio (Rev. E)"; 947 model = "miroSOUND PCM20 radio (Rev. E)";
899 break; 948 break;
@@ -917,17 +966,17 @@ static void snd_miro_proc_read(struct snd_info_entry * entry,
917 966
918 snd_iprintf(buffer, "ACI information:\n"); 967 snd_iprintf(buffer, "ACI information:\n");
919 snd_iprintf(buffer, " vendor : "); 968 snd_iprintf(buffer, " vendor : ");
920 switch(miro->aci_vendor) { 969 switch (aci->aci_vendor) {
921 case 'm': 970 case 'm':
922 snd_iprintf(buffer, "Miro\n"); 971 snd_iprintf(buffer, "Miro\n");
923 break; 972 break;
924 default: 973 default:
925 snd_iprintf(buffer, "unknown (0x%x)\n", miro->aci_vendor); 974 snd_iprintf(buffer, "unknown (0x%x)\n", aci->aci_vendor);
926 break; 975 break;
927 } 976 }
928 977
929 snd_iprintf(buffer, " product : "); 978 snd_iprintf(buffer, " product : ");
930 switch(miro->aci_product) { 979 switch (aci->aci_product) {
931 case 'A': 980 case 'A':
932 snd_iprintf(buffer, "miroSOUND PCM1 pro / (early) PCM12\n"); 981 snd_iprintf(buffer, "miroSOUND PCM1 pro / (early) PCM12\n");
933 break; 982 break;
@@ -938,26 +987,27 @@ static void snd_miro_proc_read(struct snd_info_entry * entry,
938 snd_iprintf(buffer, "miroSOUND PCM20 radio\n"); 987 snd_iprintf(buffer, "miroSOUND PCM20 radio\n");
939 break; 988 break;
940 default: 989 default:
941 snd_iprintf(buffer, "unknown (0x%x)\n", miro->aci_product); 990 snd_iprintf(buffer, "unknown (0x%x)\n", aci->aci_product);
942 break; 991 break;
943 } 992 }
944 993
945 snd_iprintf(buffer, " firmware: %d (0x%x)\n", 994 snd_iprintf(buffer, " firmware: %d (0x%x)\n",
946 miro->aci_version, miro->aci_version); 995 aci->aci_version, aci->aci_version);
947 snd_iprintf(buffer, " port : 0x%lx-0x%lx\n", 996 snd_iprintf(buffer, " port : 0x%lx-0x%lx\n",
948 miro->aci_port, miro->aci_port+2); 997 aci->aci_port, aci->aci_port+2);
949 snd_iprintf(buffer, " wss : 0x%x\n", wss); 998 snd_iprintf(buffer, " wss : 0x%x\n", wss);
950 snd_iprintf(buffer, " ide : 0x%x\n", ide); 999 snd_iprintf(buffer, " ide : 0x%x\n", ide);
951 snd_iprintf(buffer, " solomode: 0x%x\n", miro->aci_solomode); 1000 snd_iprintf(buffer, " solomode: 0x%x\n", aci->aci_solomode);
952 snd_iprintf(buffer, " amp : 0x%x\n", miro->aci_amp); 1001 snd_iprintf(buffer, " amp : 0x%x\n", aci->aci_amp);
953 snd_iprintf(buffer, " preamp : 0x%x\n", miro->aci_preamp); 1002 snd_iprintf(buffer, " preamp : 0x%x\n", aci->aci_preamp);
954} 1003}
955 1004
956static void __devinit snd_miro_proc_init(struct snd_miro * miro) 1005static void __devinit snd_miro_proc_init(struct snd_card *card,
1006 struct snd_miro *miro)
957{ 1007{
958 struct snd_info_entry *entry; 1008 struct snd_info_entry *entry;
959 1009
960 if (! snd_card_proc_new(miro->card, "miro", &entry)) 1010 if (!snd_card_proc_new(card, "miro", &entry))
961 snd_info_set_text_ops(entry, miro, snd_miro_proc_read); 1011 snd_info_set_text_ops(entry, miro, snd_miro_proc_read);
962} 1012}
963 1013
@@ -974,37 +1024,40 @@ static int __devinit snd_miro_configure(struct snd_miro *chip)
974 unsigned char mpu_irq_bits; 1024 unsigned char mpu_irq_bits;
975 unsigned long flags; 1025 unsigned long flags;
976 1026
1027 snd_miro_write_mask(chip, OPTi9XX_MC_REG(1), 0x80, 0x80);
1028 snd_miro_write_mask(chip, OPTi9XX_MC_REG(2), 0x20, 0x20); /* OPL4 */
1029 snd_miro_write_mask(chip, OPTi9XX_MC_REG(5), 0x02, 0x02);
1030
977 switch (chip->hardware) { 1031 switch (chip->hardware) {
978 case OPTi9XX_HW_82C924: 1032 case OPTi9XX_HW_82C924:
979 snd_miro_write_mask(chip, OPTi9XX_MC_REG(6), 0x02, 0x02); 1033 snd_miro_write_mask(chip, OPTi9XX_MC_REG(6), 0x02, 0x02);
980 snd_miro_write_mask(chip, OPTi9XX_MC_REG(1), 0x80, 0x80);
981 snd_miro_write_mask(chip, OPTi9XX_MC_REG(2), 0x20, 0x20); /* OPL4 */
982 snd_miro_write_mask(chip, OPTi9XX_MC_REG(3), 0xf0, 0xff); 1034 snd_miro_write_mask(chip, OPTi9XX_MC_REG(3), 0xf0, 0xff);
983 snd_miro_write_mask(chip, OPTi9XX_MC_REG(5), 0x02, 0x02);
984 break; 1035 break;
985 case OPTi9XX_HW_82C929: 1036 case OPTi9XX_HW_82C929:
986 /* untested init commands for OPTi929 */ 1037 /* untested init commands for OPTi929 */
987 snd_miro_write_mask(chip, OPTi9XX_MC_REG(1), 0x80, 0x80);
988 snd_miro_write_mask(chip, OPTi9XX_MC_REG(2), 0x20, 0x20); /* OPL4 */
989 snd_miro_write_mask(chip, OPTi9XX_MC_REG(4), 0x00, 0x0c); 1038 snd_miro_write_mask(chip, OPTi9XX_MC_REG(4), 0x00, 0x0c);
990 snd_miro_write_mask(chip, OPTi9XX_MC_REG(5), 0x02, 0x02);
991 break; 1039 break;
992 default: 1040 default:
993 snd_printk(KERN_ERR "chip %d not supported\n", chip->hardware); 1041 snd_printk(KERN_ERR "chip %d not supported\n", chip->hardware);
994 return -EINVAL; 1042 return -EINVAL;
995 } 1043 }
996 1044
997 switch (chip->wss_base) { 1045 /* PnP resource says it decodes only 10 bits of address */
998 case 0x530: 1046 switch (chip->wss_base & 0x3ff) {
1047 case 0x130:
1048 chip->wss_base = 0x530;
999 wss_base_bits = 0x00; 1049 wss_base_bits = 0x00;
1000 break; 1050 break;
1001 case 0x604: 1051 case 0x204:
1052 chip->wss_base = 0x604;
1002 wss_base_bits = 0x03; 1053 wss_base_bits = 0x03;
1003 break; 1054 break;
1004 case 0xe80: 1055 case 0x280:
1056 chip->wss_base = 0xe80;
1005 wss_base_bits = 0x01; 1057 wss_base_bits = 0x01;
1006 break; 1058 break;
1007 case 0xf40: 1059 case 0x340:
1060 chip->wss_base = 0xf40;
1008 wss_base_bits = 0x02; 1061 wss_base_bits = 0x02;
1009 break; 1062 break;
1010 default: 1063 default:
@@ -1122,75 +1175,92 @@ __skip_mpu:
1122 return 0; 1175 return 0;
1123} 1176}
1124 1177
1178static int __devinit snd_miro_opti_check(struct snd_miro *chip)
1179{
1180 unsigned char value;
1181
1182 chip->res_mc_base = request_region(chip->mc_base, chip->mc_base_size,
1183 "OPTi9xx MC");
1184 if (chip->res_mc_base == NULL)
1185 return -ENOMEM;
1186
1187 value = snd_miro_read(chip, OPTi9XX_MC_REG(1));
1188 if (value != 0xff && value != inb(chip->mc_base + OPTi9XX_MC_REG(1)))
1189 if (value == snd_miro_read(chip, OPTi9XX_MC_REG(1)))
1190 return 0;
1191
1192 release_and_free_resource(chip->res_mc_base);
1193 chip->res_mc_base = NULL;
1194
1195 return -ENODEV;
1196}
1197
1125static int __devinit snd_card_miro_detect(struct snd_card *card, 1198static int __devinit snd_card_miro_detect(struct snd_card *card,
1126 struct snd_miro *chip) 1199 struct snd_miro *chip)
1127{ 1200{
1128 int i, err; 1201 int i, err;
1129 unsigned char value;
1130 1202
1131 for (i = OPTi9XX_HW_82C929; i <= OPTi9XX_HW_82C924; i++) { 1203 for (i = OPTi9XX_HW_82C929; i <= OPTi9XX_HW_82C924; i++) {
1132 1204
1133 if ((err = snd_miro_init(chip, i)) < 0) 1205 if ((err = snd_miro_init(chip, i)) < 0)
1134 return err; 1206 return err;
1135 1207
1136 if ((chip->res_mc_base = request_region(chip->mc_base, chip->mc_base_size, "OPTi9xx MC")) == NULL) 1208 err = snd_miro_opti_check(chip);
1137 continue; 1209 if (err == 0)
1138 1210 return 1;
1139 value = snd_miro_read(chip, OPTi9XX_MC_REG(1));
1140 if ((value != 0xff) && (value != inb(chip->mc_base + 1)))
1141 if (value == snd_miro_read(chip, OPTi9XX_MC_REG(1)))
1142 return 1;
1143
1144 release_and_free_resource(chip->res_mc_base);
1145 chip->res_mc_base = NULL;
1146
1147 } 1211 }
1148 1212
1149 return -ENODEV; 1213 return -ENODEV;
1150} 1214}
1151 1215
1152static int __devinit snd_card_miro_aci_detect(struct snd_card *card, 1216static int __devinit snd_card_miro_aci_detect(struct snd_card *card,
1153 struct snd_miro * miro) 1217 struct snd_miro *miro)
1154{ 1218{
1155 unsigned char regval; 1219 unsigned char regval;
1156 int i; 1220 int i;
1221 struct snd_miro_aci *aci = &aci_device;
1222
1223 miro->aci = aci;
1157 1224
1158 mutex_init(&miro->aci_mutex); 1225 mutex_init(&aci->aci_mutex);
1159 1226
1160 /* get ACI port from OPTi9xx MC 4 */ 1227 /* get ACI port from OPTi9xx MC 4 */
1161 1228
1162 miro->mc_base = 0xf8c;
1163 regval=inb(miro->mc_base + 4); 1229 regval=inb(miro->mc_base + 4);
1164 miro->aci_port = (regval & 0x10) ? 0x344: 0x354; 1230 aci->aci_port = (regval & 0x10) ? 0x344 : 0x354;
1165 1231
1166 if ((miro->res_aci_port = request_region(miro->aci_port, 3, "miro aci")) == NULL) { 1232 miro->res_aci_port = request_region(aci->aci_port, 3, "miro aci");
1233 if (miro->res_aci_port == NULL) {
1167 snd_printk(KERN_ERR "aci i/o area 0x%lx-0x%lx already used.\n", 1234 snd_printk(KERN_ERR "aci i/o area 0x%lx-0x%lx already used.\n",
1168 miro->aci_port, miro->aci_port+2); 1235 aci->aci_port, aci->aci_port+2);
1169 return -ENOMEM; 1236 return -ENOMEM;
1170 } 1237 }
1171 1238
1172 /* force ACI into a known state */ 1239 /* force ACI into a known state */
1173 for (i = 0; i < 3; i++) 1240 for (i = 0; i < 3; i++)
1174 if (aci_cmd(miro, ACI_ERROR_OP, -1, -1) < 0) { 1241 if (snd_aci_cmd(aci, ACI_ERROR_OP, -1, -1) < 0) {
1175 snd_printk(KERN_ERR "can't force aci into known state.\n"); 1242 snd_printk(KERN_ERR "can't force aci into known state.\n");
1176 return -ENXIO; 1243 return -ENXIO;
1177 } 1244 }
1178 1245
1179 if ((miro->aci_vendor=aci_cmd(miro, ACI_READ_IDCODE, -1, -1)) < 0 || 1246 aci->aci_vendor = snd_aci_cmd(aci, ACI_READ_IDCODE, -1, -1);
1180 (miro->aci_product=aci_cmd(miro, ACI_READ_IDCODE, -1, -1)) < 0) { 1247 aci->aci_product = snd_aci_cmd(aci, ACI_READ_IDCODE, -1, -1);
1181 snd_printk(KERN_ERR "can't read aci id on 0x%lx.\n", miro->aci_port); 1248 if (aci->aci_vendor < 0 || aci->aci_product < 0) {
1249 snd_printk(KERN_ERR "can't read aci id on 0x%lx.\n",
1250 aci->aci_port);
1182 return -ENXIO; 1251 return -ENXIO;
1183 } 1252 }
1184 1253
1185 if ((miro->aci_version=aci_cmd(miro, ACI_READ_VERSION, -1, -1)) < 0) { 1254 aci->aci_version = snd_aci_cmd(aci, ACI_READ_VERSION, -1, -1);
1255 if (aci->aci_version < 0) {
1186 snd_printk(KERN_ERR "can't read aci version on 0x%lx.\n", 1256 snd_printk(KERN_ERR "can't read aci version on 0x%lx.\n",
1187 miro->aci_port); 1257 aci->aci_port);
1188 return -ENXIO; 1258 return -ENXIO;
1189 } 1259 }
1190 1260
1191 if (aci_cmd(miro, ACI_INIT, -1, -1) < 0 || 1261 if (snd_aci_cmd(aci, ACI_INIT, -1, -1) < 0 ||
1192 aci_cmd(miro, ACI_ERROR_OP, ACI_ERROR_OP, ACI_ERROR_OP) < 0 || 1262 snd_aci_cmd(aci, ACI_ERROR_OP, ACI_ERROR_OP, ACI_ERROR_OP) < 0 ||
1193 aci_cmd(miro, ACI_ERROR_OP, ACI_ERROR_OP, ACI_ERROR_OP) < 0) { 1263 snd_aci_cmd(aci, ACI_ERROR_OP, ACI_ERROR_OP, ACI_ERROR_OP) < 0) {
1194 snd_printk(KERN_ERR "can't initialize aci.\n"); 1264 snd_printk(KERN_ERR "can't initialize aci.\n");
1195 return -ENXIO; 1265 return -ENXIO;
1196 } 1266 }
@@ -1201,157 +1271,80 @@ static int __devinit snd_card_miro_aci_detect(struct snd_card *card,
1201static void snd_card_miro_free(struct snd_card *card) 1271static void snd_card_miro_free(struct snd_card *card)
1202{ 1272{
1203 struct snd_miro *miro = card->private_data; 1273 struct snd_miro *miro = card->private_data;
1204 1274
1205 release_and_free_resource(miro->res_aci_port); 1275 release_and_free_resource(miro->res_aci_port);
1276 if (miro->aci)
1277 miro->aci->aci_port = 0;
1206 release_and_free_resource(miro->res_mc_base); 1278 release_and_free_resource(miro->res_mc_base);
1207} 1279}
1208 1280
1209static int __devinit snd_miro_match(struct device *devptr, unsigned int n) 1281static int __devinit snd_miro_probe(struct snd_card *card)
1210{
1211 return 1;
1212}
1213
1214static int __devinit snd_miro_probe(struct device *devptr, unsigned int n)
1215{ 1282{
1216 static long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1};
1217 static long possible_mpu_ports[] = {0x330, 0x300, 0x310, 0x320, -1};
1218 static int possible_irqs[] = {11, 9, 10, 7, -1};
1219 static int possible_mpu_irqs[] = {10, 5, 9, 7, -1};
1220 static int possible_dma1s[] = {3, 1, 0, -1};
1221 static int possible_dma2s[][2] = {{1,-1}, {0,-1}, {-1,-1}, {0,-1}};
1222
1223 int error; 1283 int error;
1224 struct snd_miro *miro; 1284 struct snd_miro *miro = card->private_data;
1225 struct snd_wss *codec; 1285 struct snd_wss *codec;
1226 struct snd_timer *timer; 1286 struct snd_timer *timer;
1227 struct snd_card *card;
1228 struct snd_pcm *pcm; 1287 struct snd_pcm *pcm;
1229 struct snd_rawmidi *rmidi; 1288 struct snd_rawmidi *rmidi;
1230 1289
1231 error = snd_card_create(index, id, THIS_MODULE, 1290 if (!miro->res_mc_base) {
1232 sizeof(struct snd_miro), &card); 1291 miro->res_mc_base = request_region(miro->mc_base,
1233 if (error < 0) 1292 miro->mc_base_size,
1234 return error; 1293 "miro (OPTi9xx MC)");
1235 1294 if (miro->res_mc_base == NULL) {
1236 card->private_free = snd_card_miro_free; 1295 snd_printk(KERN_ERR "request for OPTI9xx MC failed\n");
1237 miro = card->private_data; 1296 return -ENOMEM;
1238 miro->card = card; 1297 }
1239
1240 if ((error = snd_card_miro_aci_detect(card, miro)) < 0) {
1241 snd_card_free(card);
1242 snd_printk(KERN_ERR "unable to detect aci chip\n");
1243 return -ENODEV;
1244 } 1298 }
1245 1299
1246 /* init proc interface */ 1300 error = snd_card_miro_aci_detect(card, miro);
1247 snd_miro_proc_init(miro); 1301 if (error < 0) {
1248
1249 if ((error = snd_card_miro_detect(card, miro)) < 0) {
1250 snd_card_free(card); 1302 snd_card_free(card);
1251 snd_printk(KERN_ERR "unable to detect OPTi9xx chip\n"); 1303 snd_printk(KERN_ERR "unable to detect aci chip\n");
1252 return -ENODEV; 1304 return -ENODEV;
1253 } 1305 }
1254 1306
1255 if (! miro->res_mc_base &&
1256 (miro->res_mc_base = request_region(miro->mc_base, miro->mc_base_size,
1257 "miro (OPTi9xx MC)")) == NULL) {
1258 snd_card_free(card);
1259 snd_printk(KERN_ERR "request for OPTI9xx MC failed\n");
1260 return -ENOMEM;
1261 }
1262
1263 miro->wss_base = port; 1307 miro->wss_base = port;
1264 miro->fm_port = fm_port;
1265 miro->mpu_port = mpu_port; 1308 miro->mpu_port = mpu_port;
1266 miro->irq = irq; 1309 miro->irq = irq;
1267 miro->mpu_irq = mpu_irq; 1310 miro->mpu_irq = mpu_irq;
1268 miro->dma1 = dma1; 1311 miro->dma1 = dma1;
1269 miro->dma2 = dma2; 1312 miro->dma2 = dma2;
1270 1313
1271 if (miro->wss_base == SNDRV_AUTO_PORT) { 1314 /* init proc interface */
1272 if ((miro->wss_base = snd_legacy_find_free_ioport(possible_ports, 4)) < 0) { 1315 snd_miro_proc_init(card, miro);
1273 snd_card_free(card);
1274 snd_printk(KERN_ERR "unable to find a free WSS port\n");
1275 return -EBUSY;
1276 }
1277 }
1278
1279 if (miro->mpu_port == SNDRV_AUTO_PORT) {
1280 if ((miro->mpu_port = snd_legacy_find_free_ioport(possible_mpu_ports, 2)) < 0) {
1281 snd_card_free(card);
1282 snd_printk(KERN_ERR "unable to find a free MPU401 port\n");
1283 return -EBUSY;
1284 }
1285 }
1286 if (miro->irq == SNDRV_AUTO_IRQ) {
1287 if ((miro->irq = snd_legacy_find_free_irq(possible_irqs)) < 0) {
1288 snd_card_free(card);
1289 snd_printk(KERN_ERR "unable to find a free IRQ\n");
1290 return -EBUSY;
1291 }
1292 }
1293 if (miro->mpu_irq == SNDRV_AUTO_IRQ) {
1294 if ((miro->mpu_irq = snd_legacy_find_free_irq(possible_mpu_irqs)) < 0) {
1295 snd_card_free(card);
1296 snd_printk(KERN_ERR "unable to find a free MPU401 IRQ\n");
1297 return -EBUSY;
1298 }
1299 }
1300 if (miro->dma1 == SNDRV_AUTO_DMA) {
1301 if ((miro->dma1 = snd_legacy_find_free_dma(possible_dma1s)) < 0) {
1302 snd_card_free(card);
1303 snd_printk(KERN_ERR "unable to find a free DMA1\n");
1304 return -EBUSY;
1305 }
1306 }
1307 if (miro->dma2 == SNDRV_AUTO_DMA) {
1308 if ((miro->dma2 = snd_legacy_find_free_dma(possible_dma2s[miro->dma1 % 4])) < 0) {
1309 snd_card_free(card);
1310 snd_printk(KERN_ERR "unable to find a free DMA2\n");
1311 return -EBUSY;
1312 }
1313 }
1314 1316
1315 error = snd_miro_configure(miro); 1317 error = snd_miro_configure(miro);
1316 if (error) { 1318 if (error)
1317 snd_card_free(card);
1318 return error; 1319 return error;
1319 }
1320 1320
1321 error = snd_wss_create(card, miro->wss_base + 4, -1, 1321 error = snd_wss_create(card, miro->wss_base + 4, -1,
1322 miro->irq, miro->dma1, miro->dma2, 1322 miro->irq, miro->dma1, miro->dma2,
1323 WSS_HW_AD1845, 0, &codec); 1323 WSS_HW_DETECT, 0, &codec);
1324 if (error < 0) { 1324 if (error < 0)
1325 snd_card_free(card);
1326 return error; 1325 return error;
1327 }
1328 1326
1329 error = snd_wss_pcm(codec, 0, &pcm); 1327 error = snd_wss_pcm(codec, 0, &pcm);
1330 if (error < 0) { 1328 if (error < 0)
1331 snd_card_free(card);
1332 return error; 1329 return error;
1333 } 1330
1334 error = snd_wss_mixer(codec); 1331 error = snd_wss_mixer(codec);
1335 if (error < 0) { 1332 if (error < 0)
1336 snd_card_free(card);
1337 return error; 1333 return error;
1338 } 1334
1339 error = snd_wss_timer(codec, 0, &timer); 1335 error = snd_wss_timer(codec, 0, &timer);
1340 if (error < 0) { 1336 if (error < 0)
1341 snd_card_free(card);
1342 return error; 1337 return error;
1343 }
1344 1338
1345 miro->pcm = pcm; 1339 miro->pcm = pcm;
1346 1340
1347 if ((error = snd_miro_mixer(miro)) < 0) { 1341 error = snd_miro_mixer(card, miro);
1348 snd_card_free(card); 1342 if (error < 0)
1349 return error; 1343 return error;
1350 }
1351 1344
1352 if (miro->aci_vendor == 'm') { 1345 if (miro->aci->aci_vendor == 'm') {
1353 /* It looks like a miro sound card. */ 1346 /* It looks like a miro sound card. */
1354 switch (miro->aci_product) { 1347 switch (miro->aci->aci_product) {
1355 case 'A': 1348 case 'A':
1356 sprintf(card->shortname, 1349 sprintf(card->shortname,
1357 "miroSOUND PCM1 pro / PCM12"); 1350 "miroSOUND PCM1 pro / PCM12");
@@ -1380,30 +1373,131 @@ static int __devinit snd_miro_probe(struct device *devptr, unsigned int n)
1380 card->shortname, miro->name, pcm->name, miro->wss_base + 4, 1373 card->shortname, miro->name, pcm->name, miro->wss_base + 4,
1381 miro->irq, miro->dma1, miro->dma2); 1374 miro->irq, miro->dma1, miro->dma2);
1382 1375
1383 if (miro->mpu_port <= 0 || miro->mpu_port == SNDRV_AUTO_PORT) 1376 if (mpu_port <= 0 || mpu_port == SNDRV_AUTO_PORT)
1384 rmidi = NULL; 1377 rmidi = NULL;
1385 else 1378 else {
1386 if ((error = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, 1379 error = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
1387 miro->mpu_port, 0, miro->mpu_irq, IRQF_DISABLED, 1380 mpu_port, 0, miro->mpu_irq, IRQF_DISABLED,
1388 &rmidi))) 1381 &rmidi);
1389 snd_printk(KERN_WARNING "no MPU-401 device at 0x%lx?\n", miro->mpu_port); 1382 if (error < 0)
1383 snd_printk(KERN_WARNING "no MPU-401 device at 0x%lx?\n",
1384 mpu_port);
1385 }
1390 1386
1391 if (miro->fm_port > 0 && miro->fm_port != SNDRV_AUTO_PORT) { 1387 if (fm_port > 0 && fm_port != SNDRV_AUTO_PORT) {
1392 struct snd_opl3 *opl3 = NULL; 1388 struct snd_opl3 *opl3 = NULL;
1393 struct snd_opl4 *opl4; 1389 struct snd_opl4 *opl4;
1394 if (snd_opl4_create(card, miro->fm_port, miro->fm_port - 8, 1390
1391 if (snd_opl4_create(card, fm_port, fm_port - 8,
1395 2, &opl3, &opl4) < 0) 1392 2, &opl3, &opl4) < 0)
1396 snd_printk(KERN_WARNING "no OPL4 device at 0x%lx\n", miro->fm_port); 1393 snd_printk(KERN_WARNING "no OPL4 device at 0x%lx\n",
1394 fm_port);
1397 } 1395 }
1398 1396
1399 if ((error = snd_set_aci_init_values(miro)) < 0) { 1397 error = snd_set_aci_init_values(miro);
1400 snd_card_free(card); 1398 if (error < 0)
1401 return error; 1399 return error;
1400
1401 return snd_card_register(card);
1402}
1403
1404static int __devinit snd_miro_isa_match(struct device *devptr, unsigned int n)
1405{
1406#ifdef CONFIG_PNP
1407 if (snd_miro_pnp_is_probed)
1408 return 0;
1409 if (isapnp)
1410 return 0;
1411#endif
1412 return 1;
1413}
1414
1415static int __devinit snd_miro_isa_probe(struct device *devptr, unsigned int n)
1416{
1417 static long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1};
1418 static long possible_mpu_ports[] = {0x330, 0x300, 0x310, 0x320, -1};
1419 static int possible_irqs[] = {11, 9, 10, 7, -1};
1420 static int possible_mpu_irqs[] = {10, 5, 9, 7, -1};
1421 static int possible_dma1s[] = {3, 1, 0, -1};
1422 static int possible_dma2s[][2] = { {1, -1}, {0, -1}, {-1, -1},
1423 {0, -1} };
1424
1425 int error;
1426 struct snd_miro *miro;
1427 struct snd_card *card;
1428
1429 error = snd_card_create(index, id, THIS_MODULE,
1430 sizeof(struct snd_miro), &card);
1431 if (error < 0)
1432 return error;
1433
1434 card->private_free = snd_card_miro_free;
1435 miro = card->private_data;
1436
1437 error = snd_card_miro_detect(card, miro);
1438 if (error < 0) {
1439 snd_card_free(card);
1440 snd_printk(KERN_ERR "unable to detect OPTi9xx chip\n");
1441 return -ENODEV;
1442 }
1443
1444 if (port == SNDRV_AUTO_PORT) {
1445 port = snd_legacy_find_free_ioport(possible_ports, 4);
1446 if (port < 0) {
1447 snd_card_free(card);
1448 snd_printk(KERN_ERR "unable to find a free WSS port\n");
1449 return -EBUSY;
1450 }
1451 }
1452
1453 if (mpu_port == SNDRV_AUTO_PORT) {
1454 mpu_port = snd_legacy_find_free_ioport(possible_mpu_ports, 2);
1455 if (mpu_port < 0) {
1456 snd_card_free(card);
1457 snd_printk(KERN_ERR
1458 "unable to find a free MPU401 port\n");
1459 return -EBUSY;
1460 }
1461 }
1462
1463 if (irq == SNDRV_AUTO_IRQ) {
1464 irq = snd_legacy_find_free_irq(possible_irqs);
1465 if (irq < 0) {
1466 snd_card_free(card);
1467 snd_printk(KERN_ERR "unable to find a free IRQ\n");
1468 return -EBUSY;
1469 }
1470 }
1471 if (mpu_irq == SNDRV_AUTO_IRQ) {
1472 mpu_irq = snd_legacy_find_free_irq(possible_mpu_irqs);
1473 if (mpu_irq < 0) {
1474 snd_card_free(card);
1475 snd_printk(KERN_ERR
1476 "unable to find a free MPU401 IRQ\n");
1477 return -EBUSY;
1478 }
1479 }
1480 if (dma1 == SNDRV_AUTO_DMA) {
1481 dma1 = snd_legacy_find_free_dma(possible_dma1s);
1482 if (dma1 < 0) {
1483 snd_card_free(card);
1484 snd_printk(KERN_ERR "unable to find a free DMA1\n");
1485 return -EBUSY;
1486 }
1487 }
1488 if (dma2 == SNDRV_AUTO_DMA) {
1489 dma2 = snd_legacy_find_free_dma(possible_dma2s[dma1 % 4]);
1490 if (dma2 < 0) {
1491 snd_card_free(card);
1492 snd_printk(KERN_ERR "unable to find a free DMA2\n");
1493 return -EBUSY;
1494 }
1402 } 1495 }
1403 1496
1404 snd_card_set_dev(card, devptr); 1497 snd_card_set_dev(card, devptr);
1405 1498
1406 if ((error = snd_card_register(card))) { 1499 error = snd_miro_probe(card);
1500 if (error < 0) {
1407 snd_card_free(card); 1501 snd_card_free(card);
1408 return error; 1502 return error;
1409 } 1503 }
@@ -1412,7 +1506,8 @@ static int __devinit snd_miro_probe(struct device *devptr, unsigned int n)
1412 return 0; 1506 return 0;
1413} 1507}
1414 1508
1415static int __devexit snd_miro_remove(struct device *devptr, unsigned int dev) 1509static int __devexit snd_miro_isa_remove(struct device *devptr,
1510 unsigned int dev)
1416{ 1511{
1417 snd_card_free(dev_get_drvdata(devptr)); 1512 snd_card_free(dev_get_drvdata(devptr));
1418 dev_set_drvdata(devptr, NULL); 1513 dev_set_drvdata(devptr, NULL);
@@ -1422,23 +1517,164 @@ static int __devexit snd_miro_remove(struct device *devptr, unsigned int dev)
1422#define DEV_NAME "miro" 1517#define DEV_NAME "miro"
1423 1518
1424static struct isa_driver snd_miro_driver = { 1519static struct isa_driver snd_miro_driver = {
1425 .match = snd_miro_match, 1520 .match = snd_miro_isa_match,
1426 .probe = snd_miro_probe, 1521 .probe = snd_miro_isa_probe,
1427 .remove = __devexit_p(snd_miro_remove), 1522 .remove = __devexit_p(snd_miro_isa_remove),
1428 /* FIXME: suspend/resume */ 1523 /* FIXME: suspend/resume */
1429 .driver = { 1524 .driver = {
1430 .name = DEV_NAME 1525 .name = DEV_NAME
1431 }, 1526 },
1432}; 1527};
1433 1528
1529#ifdef CONFIG_PNP
1530
1531static int __devinit snd_card_miro_pnp(struct snd_miro *chip,
1532 struct pnp_card_link *card,
1533 const struct pnp_card_device_id *pid)
1534{
1535 struct pnp_dev *pdev;
1536 int err;
1537 struct pnp_dev *devmpu;
1538 struct pnp_dev *devmc;
1539
1540 pdev = pnp_request_card_device(card, pid->devs[0].id, NULL);
1541 if (pdev == NULL)
1542 return -EBUSY;
1543
1544 devmpu = pnp_request_card_device(card, pid->devs[1].id, NULL);
1545 if (devmpu == NULL)
1546 return -EBUSY;
1547
1548 devmc = pnp_request_card_device(card, pid->devs[2].id, NULL);
1549 if (devmc == NULL)
1550 return -EBUSY;
1551
1552 err = pnp_activate_dev(pdev);
1553 if (err < 0) {
1554 snd_printk(KERN_ERR "AUDIO pnp configure failure: %d\n", err);
1555 return err;
1556 }
1557
1558 err = pnp_activate_dev(devmc);
1559 if (err < 0) {
1560 snd_printk(KERN_ERR "MC pnp configure failure: %d\n",
1561 err);
1562 return err;
1563 }
1564
1565 port = pnp_port_start(pdev, 1);
1566 fm_port = pnp_port_start(pdev, 2) + 8;
1567
1568 /*
1569 * The MC(0) is never accessed and the miroSOUND PCM20 card does not
1570 * include it in the PnP resource range. OPTI93x include it.
1571 */
1572 chip->mc_base = pnp_port_start(devmc, 0) - 1;
1573 chip->mc_base_size = pnp_port_len(devmc, 0) + 1;
1574
1575 irq = pnp_irq(pdev, 0);
1576 dma1 = pnp_dma(pdev, 0);
1577 dma2 = pnp_dma(pdev, 1);
1578
1579 if (mpu_port > 0) {
1580 err = pnp_activate_dev(devmpu);
1581 if (err < 0) {
1582 snd_printk(KERN_ERR "MPU401 pnp configure failure\n");
1583 mpu_port = -1;
1584 return err;
1585 }
1586 mpu_port = pnp_port_start(devmpu, 0);
1587 mpu_irq = pnp_irq(devmpu, 0);
1588 }
1589 return 0;
1590}
1591
1592static int __devinit snd_miro_pnp_probe(struct pnp_card_link *pcard,
1593 const struct pnp_card_device_id *pid)
1594{
1595 struct snd_card *card;
1596 int err;
1597 struct snd_miro *miro;
1598
1599 if (snd_miro_pnp_is_probed)
1600 return -EBUSY;
1601 if (!isapnp)
1602 return -ENODEV;
1603 err = snd_card_create(index, id, THIS_MODULE,
1604 sizeof(struct snd_miro), &card);
1605 if (err < 0)
1606 return err;
1607
1608 card->private_free = snd_card_miro_free;
1609 miro = card->private_data;
1610
1611 err = snd_card_miro_pnp(miro, pcard, pid);
1612 if (err) {
1613 snd_card_free(card);
1614 return err;
1615 }
1616
1617 /* only miroSOUND PCM20 and PCM12 == OPTi924 */
1618 err = snd_miro_init(miro, OPTi9XX_HW_82C924);
1619 if (err) {
1620 snd_card_free(card);
1621 return err;
1622 }
1623
1624 err = snd_miro_opti_check(miro);
1625 if (err) {
1626 snd_printk(KERN_ERR "OPTI chip not found\n");
1627 snd_card_free(card);
1628 return err;
1629 }
1630
1631 snd_card_set_dev(card, &pcard->card->dev);
1632 err = snd_miro_probe(card);
1633 if (err < 0) {
1634 snd_card_free(card);
1635 return err;
1636 }
1637 pnp_set_card_drvdata(pcard, card);
1638 snd_miro_pnp_is_probed = 1;
1639 return 0;
1640}
1641
1642static void __devexit snd_miro_pnp_remove(struct pnp_card_link * pcard)
1643{
1644 snd_card_free(pnp_get_card_drvdata(pcard));
1645 pnp_set_card_drvdata(pcard, NULL);
1646 snd_miro_pnp_is_probed = 0;
1647}
1648
1649static struct pnp_card_driver miro_pnpc_driver = {
1650 .flags = PNP_DRIVER_RES_DISABLE,
1651 .name = "miro",
1652 .id_table = snd_miro_pnpids,
1653 .probe = snd_miro_pnp_probe,
1654 .remove = __devexit_p(snd_miro_pnp_remove),
1655};
1656#endif
1657
1434static int __init alsa_card_miro_init(void) 1658static int __init alsa_card_miro_init(void)
1435{ 1659{
1660#ifdef CONFIG_PNP
1661 pnp_register_card_driver(&miro_pnpc_driver);
1662 if (snd_miro_pnp_is_probed)
1663 return 0;
1664 pnp_unregister_card_driver(&miro_pnpc_driver);
1665#endif
1436 return isa_register_driver(&snd_miro_driver, 1); 1666 return isa_register_driver(&snd_miro_driver, 1);
1437} 1667}
1438 1668
1439static void __exit alsa_card_miro_exit(void) 1669static void __exit alsa_card_miro_exit(void)
1440{ 1670{
1441 isa_unregister_driver(&snd_miro_driver); 1671 if (!snd_miro_pnp_is_probed) {
1672 isa_unregister_driver(&snd_miro_driver);
1673 return;
1674 }
1675#ifdef CONFIG_PNP
1676 pnp_unregister_card_driver(&miro_pnpc_driver);
1677#endif
1442} 1678}
1443 1679
1444module_init(alsa_card_miro_init) 1680module_init(alsa_card_miro_init)
diff --git a/sound/isa/opti9xx/miro.h b/sound/isa/opti9xx/miro.h
deleted file mode 100644
index 6e1385b8e07e..000000000000
--- a/sound/isa/opti9xx/miro.h
+++ /dev/null
@@ -1,73 +0,0 @@
1#ifndef _MIRO_H_
2#define _MIRO_H_
3
4#define ACI_REG_COMMAND 0 /* write register offset */
5#define ACI_REG_STATUS 1 /* read register offset */
6#define ACI_REG_BUSY 2 /* busy register offset */
7#define ACI_REG_RDS 2 /* PCM20: RDS register offset */
8#define ACI_MINTIME 500 /* ACI time out limit */
9
10#define ACI_SET_MUTE 0x0d
11#define ACI_SET_POWERAMP 0x0f
12#define ACI_SET_TUNERMUTE 0xa3
13#define ACI_SET_TUNERMONO 0xa4
14#define ACI_SET_IDE 0xd0
15#define ACI_SET_WSS 0xd1
16#define ACI_SET_SOLOMODE 0xd2
17#define ACI_SET_PREAMP 0x03
18#define ACI_GET_PREAMP 0x21
19#define ACI_WRITE_TUNE 0xa7
20#define ACI_READ_TUNERSTEREO 0xa8
21#define ACI_READ_TUNERSTATION 0xa9
22#define ACI_READ_VERSION 0xf1
23#define ACI_READ_IDCODE 0xf2
24#define ACI_INIT 0xff
25#define ACI_STATUS 0xf0
26#define ACI_S_GENERAL 0x00
27#define ACI_ERROR_OP 0xdf
28
29/* ACI Mixer */
30
31/* These are the values for the right channel GET registers.
32 Add an offset of 0x01 for the left channel register.
33 (left=right+0x01) */
34
35#define ACI_GET_MASTER 0x03
36#define ACI_GET_MIC 0x05
37#define ACI_GET_LINE 0x07
38#define ACI_GET_CD 0x09
39#define ACI_GET_SYNTH 0x0b
40#define ACI_GET_PCM 0x0d
41#define ACI_GET_LINE1 0x10 /* Radio on PCM20 */
42#define ACI_GET_LINE2 0x12
43
44#define ACI_GET_EQ1 0x22 /* from Bass ... */
45#define ACI_GET_EQ2 0x24
46#define ACI_GET_EQ3 0x26
47#define ACI_GET_EQ4 0x28
48#define ACI_GET_EQ5 0x2a
49#define ACI_GET_EQ6 0x2c
50#define ACI_GET_EQ7 0x2e /* ... to Treble */
51
52/* And these are the values for the right channel SET registers.
53 For left channel access you have to add an offset of 0x08.
54 MASTER is an exception, which needs an offset of 0x01 */
55
56#define ACI_SET_MASTER 0x00
57#define ACI_SET_MIC 0x30
58#define ACI_SET_LINE 0x31
59#define ACI_SET_CD 0x34
60#define ACI_SET_SYNTH 0x33
61#define ACI_SET_PCM 0x32
62#define ACI_SET_LINE1 0x35 /* Radio on PCM20 */
63#define ACI_SET_LINE2 0x36
64
65#define ACI_SET_EQ1 0x40 /* from Bass ... */
66#define ACI_SET_EQ2 0x41
67#define ACI_SET_EQ3 0x42
68#define ACI_SET_EQ4 0x43
69#define ACI_SET_EQ5 0x44
70#define ACI_SET_EQ6 0x45
71#define ACI_SET_EQ7 0x46 /* ... to Treble */
72
73#endif /* _MIRO_H_ */
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c
index 5cd555325b9d..c35dc68930dc 100644
--- a/sound/isa/opti9xx/opti92x-ad1848.c
+++ b/sound/isa/opti9xx/opti92x-ad1848.c
@@ -27,12 +27,12 @@
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>
34#include <asm/dma.h> 33#include <asm/dma.h>
35#include <sound/core.h> 34#include <sound/core.h>
35#include <sound/tlv.h>
36#include <sound/wss.h> 36#include <sound/wss.h>
37#include <sound/mpu401.h> 37#include <sound/mpu401.h>
38#include <sound/opl3.h> 38#include <sound/opl3.h>
@@ -135,6 +135,8 @@ struct snd_opti9xx {
135 unsigned long mc_base_size; 135 unsigned long mc_base_size;
136#ifdef OPTi93X 136#ifdef OPTi93X
137 unsigned long mc_indir_index; 137 unsigned long mc_indir_index;
138 unsigned long mc_indir_size;
139 struct resource *res_mc_indir;
138 struct snd_wss *codec; 140 struct snd_wss *codec;
139#endif /* OPTi93X */ 141#endif /* OPTi93X */
140 unsigned long pwd_reg; 142 unsigned long pwd_reg;
@@ -143,18 +145,6 @@ struct snd_opti9xx {
143 145
144 long wss_base; 146 long wss_base;
145 int irq; 147 int irq;
146 int dma1;
147 int dma2;
148
149 long fm_port;
150
151 long mpu_port;
152 int mpu_irq;
153
154#ifdef CONFIG_PNP
155 struct pnp_dev *dev;
156 struct pnp_dev *devmpu;
157#endif /* CONFIG_PNP */
158}; 148};
159 149
160static int snd_opti9xx_pnp_is_probed; 150static int snd_opti9xx_pnp_is_probed;
@@ -164,12 +154,17 @@ static int snd_opti9xx_pnp_is_probed;
164static struct pnp_card_device_id snd_opti9xx_pnpids[] = { 154static struct pnp_card_device_id snd_opti9xx_pnpids[] = {
165#ifndef OPTi93X 155#ifndef OPTi93X
166 /* OPTi 82C924 */ 156 /* OPTi 82C924 */
167 { .id = "OPT0924", .devs = { { "OPT0000" }, { "OPT0002" } }, .driver_data = 0x0924 }, 157 { .id = "OPT0924",
158 .devs = { { "OPT0000" }, { "OPT0002" }, { "OPT0005" } },
159 .driver_data = 0x0924 },
168 /* OPTi 82C925 */ 160 /* OPTi 82C925 */
169 { .id = "OPT0925", .devs = { { "OPT9250" }, { "OPT0002" } }, .driver_data = 0x0925 }, 161 { .id = "OPT0925",
162 .devs = { { "OPT9250" }, { "OPT0002" }, { "OPT0005" } },
163 .driver_data = 0x0925 },
170#else 164#else
171 /* OPTi 82C931/3 */ 165 /* OPTi 82C931/3 */
172 { .id = "OPT0931", .devs = { { "OPT9310" }, { "OPT0002" } }, .driver_data = 0x0931 }, 166 { .id = "OPT0931", .devs = { { "OPT9310" }, { "OPT0002" } },
167 .driver_data = 0x0931 },
173#endif /* OPTi93X */ 168#endif /* OPTi93X */
174 { .id = "" } 169 { .id = "" }
175}; 170};
@@ -185,7 +180,7 @@ MODULE_DEVICE_TABLE(pnp_card, snd_opti9xx_pnpids);
185#endif 180#endif
186 181
187static char * snd_opti9xx_names[] = { 182static char * snd_opti9xx_names[] = {
188 "unkown", 183 "unknown",
189 "82C928", "82C929", 184 "82C928", "82C929",
190 "82C924", "82C925", 185 "82C924", "82C925",
191 "82C930", "82C931", "82C933" 186 "82C930", "82C931", "82C933"
@@ -212,30 +207,35 @@ static int __devinit snd_opti9xx_init(struct snd_opti9xx *chip,
212 chip->hardware = hardware; 207 chip->hardware = hardware;
213 strcpy(chip->name, snd_opti9xx_names[hardware]); 208 strcpy(chip->name, snd_opti9xx_names[hardware]);
214 209
215 chip->mc_base_size = opti9xx_mc_size[hardware];
216
217 spin_lock_init(&chip->lock); 210 spin_lock_init(&chip->lock);
218 211
219 chip->wss_base = -1;
220 chip->irq = -1; 212 chip->irq = -1;
221 chip->dma1 = -1; 213
222 chip->dma2 = -1; 214#ifndef OPTi93X
223 chip->fm_port = -1; 215#ifdef CONFIG_PNP
224 chip->mpu_port = -1; 216 if (isapnp && chip->mc_base)
225 chip->mpu_irq = -1; 217 /* PnP resource gives the least 10 bits */
218 chip->mc_base |= 0xc00;
219 else
220#endif /* CONFIG_PNP */
221 {
222 chip->mc_base = 0xf8c;
223 chip->mc_base_size = opti9xx_mc_size[hardware];
224 }
225#else
226 chip->mc_base_size = opti9xx_mc_size[hardware];
227#endif
226 228
227 switch (hardware) { 229 switch (hardware) {
228#ifndef OPTi93X 230#ifndef OPTi93X
229 case OPTi9XX_HW_82C928: 231 case OPTi9XX_HW_82C928:
230 case OPTi9XX_HW_82C929: 232 case OPTi9XX_HW_82C929:
231 chip->mc_base = 0xf8c;
232 chip->password = (hardware == OPTi9XX_HW_82C928) ? 0xe2 : 0xe3; 233 chip->password = (hardware == OPTi9XX_HW_82C928) ? 0xe2 : 0xe3;
233 chip->pwd_reg = 3; 234 chip->pwd_reg = 3;
234 break; 235 break;
235 236
236 case OPTi9XX_HW_82C924: 237 case OPTi9XX_HW_82C924:
237 case OPTi9XX_HW_82C925: 238 case OPTi9XX_HW_82C925:
238 chip->mc_base = 0xf8c;
239 chip->password = 0xe5; 239 chip->password = 0xe5;
240 chip->pwd_reg = 3; 240 chip->pwd_reg = 3;
241 break; 241 break;
@@ -245,7 +245,10 @@ static int __devinit snd_opti9xx_init(struct snd_opti9xx *chip,
245 case OPTi9XX_HW_82C931: 245 case OPTi9XX_HW_82C931:
246 case OPTi9XX_HW_82C933: 246 case OPTi9XX_HW_82C933:
247 chip->mc_base = (hardware == OPTi9XX_HW_82C930) ? 0xf8f : 0xf8d; 247 chip->mc_base = (hardware == OPTi9XX_HW_82C930) ? 0xf8f : 0xf8d;
248 chip->mc_indir_index = 0xe0e; 248 if (!chip->mc_indir_index) {
249 chip->mc_indir_index = 0xe0e;
250 chip->mc_indir_size = 2;
251 }
249 chip->password = 0xe4; 252 chip->password = 0xe4;
250 chip->pwd_reg = 0; 253 chip->pwd_reg = 0;
251 break; 254 break;
@@ -300,7 +303,7 @@ static unsigned char snd_opti9xx_read(struct snd_opti9xx *chip,
300 spin_unlock_irqrestore(&chip->lock, flags); 303 spin_unlock_irqrestore(&chip->lock, flags);
301 return retval; 304 return retval;
302} 305}
303 306
304static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg, 307static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg,
305 unsigned char value) 308 unsigned char value)
306{ 309{
@@ -348,7 +351,10 @@ static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg,
348 (snd_opti9xx_read(chip, reg) & ~(mask)) | ((value) & (mask))) 351 (snd_opti9xx_read(chip, reg) & ~(mask)) | ((value) & (mask)))
349 352
350 353
351static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip) 354static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip,
355 long port,
356 int irq, int dma1, int dma2,
357 long mpu_port, int mpu_irq)
352{ 358{
353 unsigned char wss_base_bits; 359 unsigned char wss_base_bits;
354 unsigned char irq_bits; 360 unsigned char irq_bits;
@@ -359,16 +365,23 @@ static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip)
359 switch (chip->hardware) { 365 switch (chip->hardware) {
360#ifndef OPTi93X 366#ifndef OPTi93X
361 case OPTi9XX_HW_82C924: 367 case OPTi9XX_HW_82C924:
368 /* opti 929 mode (?), OPL3 clock output, audio enable */
362 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(4), 0xf0, 0xfc); 369 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(4), 0xf0, 0xfc);
370 /* enable wave audio */
363 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(6), 0x02, 0x02); 371 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(6), 0x02, 0x02);
364 372
365 case OPTi9XX_HW_82C925: 373 case OPTi9XX_HW_82C925:
374 /* enable WSS mode */
366 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), 0x80, 0x80); 375 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), 0x80, 0x80);
376 /* OPL3 FM synthesis */
367 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(2), 0x00, 0x20); 377 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(2), 0x00, 0x20);
378 /* disable Sound Blaster IRQ and DMA */
368 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(3), 0xf0, 0xff); 379 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(3), 0xf0, 0xff);
369#ifdef CS4231 380#ifdef CS4231
381 /* cs4231/4248 fix enabled */
370 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x02, 0x02); 382 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x02, 0x02);
371#else 383#else
384 /* cs4231/4248 fix disabled */
372 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x00, 0x02); 385 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x00, 0x02);
373#endif /* CS4231 */ 386#endif /* CS4231 */
374 break; 387 break;
@@ -416,28 +429,32 @@ static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip)
416 return -EINVAL; 429 return -EINVAL;
417 } 430 }
418 431
419 switch (chip->wss_base) { 432 /* PnP resource says it decodes only 10 bits of address */
420 case 0x530: 433 switch (port & 0x3ff) {
434 case 0x130:
435 chip->wss_base = 0x530;
421 wss_base_bits = 0x00; 436 wss_base_bits = 0x00;
422 break; 437 break;
423 case 0x604: 438 case 0x204:
439 chip->wss_base = 0x604;
424 wss_base_bits = 0x03; 440 wss_base_bits = 0x03;
425 break; 441 break;
426 case 0xe80: 442 case 0x280:
443 chip->wss_base = 0xe80;
427 wss_base_bits = 0x01; 444 wss_base_bits = 0x01;
428 break; 445 break;
429 case 0xf40: 446 case 0x340:
447 chip->wss_base = 0xf40;
430 wss_base_bits = 0x02; 448 wss_base_bits = 0x02;
431 break; 449 break;
432 default: 450 default:
433 snd_printk(KERN_WARNING "WSS port 0x%lx not valid\n", 451 snd_printk(KERN_WARNING "WSS port 0x%lx not valid\n", port);
434 chip->wss_base);
435 goto __skip_base; 452 goto __skip_base;
436 } 453 }
437 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), wss_base_bits << 4, 0x30); 454 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), wss_base_bits << 4, 0x30);
438 455
439__skip_base: 456__skip_base:
440 switch (chip->irq) { 457 switch (irq) {
441//#ifdef OPTi93X 458//#ifdef OPTi93X
442 case 5: 459 case 5:
443 irq_bits = 0x05; 460 irq_bits = 0x05;
@@ -456,11 +473,11 @@ __skip_base:
456 irq_bits = 0x04; 473 irq_bits = 0x04;
457 break; 474 break;
458 default: 475 default:
459 snd_printk(KERN_WARNING "WSS irq # %d not valid\n", chip->irq); 476 snd_printk(KERN_WARNING "WSS irq # %d not valid\n", irq);
460 goto __skip_resources; 477 goto __skip_resources;
461 } 478 }
462 479
463 switch (chip->dma1) { 480 switch (dma1) {
464 case 0: 481 case 0:
465 dma_bits = 0x01; 482 dma_bits = 0x01;
466 break; 483 break;
@@ -471,24 +488,22 @@ __skip_base:
471 dma_bits = 0x03; 488 dma_bits = 0x03;
472 break; 489 break;
473 default: 490 default:
474 snd_printk(KERN_WARNING "WSS dma1 # %d not valid\n", 491 snd_printk(KERN_WARNING "WSS dma1 # %d not valid\n", dma1);
475 chip->dma1);
476 goto __skip_resources; 492 goto __skip_resources;
477 } 493 }
478 494
479#if defined(CS4231) || defined(OPTi93X) 495#if defined(CS4231) || defined(OPTi93X)
480 if (chip->dma1 == chip->dma2) { 496 if (dma1 == dma2) {
481 snd_printk(KERN_ERR "don't want to share dmas\n"); 497 snd_printk(KERN_ERR "don't want to share dmas\n");
482 return -EBUSY; 498 return -EBUSY;
483 } 499 }
484 500
485 switch (chip->dma2) { 501 switch (dma2) {
486 case 0: 502 case 0:
487 case 1: 503 case 1:
488 break; 504 break;
489 default: 505 default:
490 snd_printk(KERN_WARNING "WSS dma2 # %d not valid\n", 506 snd_printk(KERN_WARNING "WSS dma2 # %d not valid\n", dma2);
491 chip->dma2);
492 goto __skip_resources; 507 goto __skip_resources;
493 } 508 }
494 dma_bits |= 0x04; 509 dma_bits |= 0x04;
@@ -502,7 +517,7 @@ __skip_base:
502 517
503__skip_resources: 518__skip_resources:
504 if (chip->hardware > OPTi9XX_HW_82C928) { 519 if (chip->hardware > OPTi9XX_HW_82C928) {
505 switch (chip->mpu_port) { 520 switch (mpu_port) {
506 case 0: 521 case 0:
507 case -1: 522 case -1:
508 break; 523 break;
@@ -520,12 +535,11 @@ __skip_resources:
520 break; 535 break;
521 default: 536 default:
522 snd_printk(KERN_WARNING 537 snd_printk(KERN_WARNING
523 "MPU-401 port 0x%lx not valid\n", 538 "MPU-401 port 0x%lx not valid\n", mpu_port);
524 chip->mpu_port);
525 goto __skip_mpu; 539 goto __skip_mpu;
526 } 540 }
527 541
528 switch (chip->mpu_irq) { 542 switch (mpu_irq) {
529 case 5: 543 case 5:
530 mpu_irq_bits = 0x02; 544 mpu_irq_bits = 0x02;
531 break; 545 break;
@@ -540,12 +554,12 @@ __skip_resources:
540 break; 554 break;
541 default: 555 default:
542 snd_printk(KERN_WARNING "MPU-401 irq # %d not valid\n", 556 snd_printk(KERN_WARNING "MPU-401 irq # %d not valid\n",
543 chip->mpu_irq); 557 mpu_irq);
544 goto __skip_mpu; 558 goto __skip_mpu;
545 } 559 }
546 560
547 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(6), 561 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(6),
548 (chip->mpu_port <= 0) ? 0x00 : 562 (mpu_port <= 0) ? 0x00 :
549 0x80 | mpu_port_bits << 5 | mpu_irq_bits << 3, 563 0x80 | mpu_port_bits << 5 | mpu_irq_bits << 3,
550 0xf8); 564 0xf8);
551 } 565 }
@@ -556,12 +570,102 @@ __skip_mpu:
556 570
557#ifdef OPTi93X 571#ifdef OPTi93X
558 572
573static const DECLARE_TLV_DB_SCALE(db_scale_5bit_3db_step, -9300, 300, 0);
574static const DECLARE_TLV_DB_SCALE(db_scale_5bit, -4650, 150, 0);
575static const DECLARE_TLV_DB_SCALE(db_scale_4bit_12db_max, -3300, 300, 0);
576
577static struct snd_kcontrol_new snd_opti93x_controls[] = {
578WSS_DOUBLE("Master Playback Switch", 0,
579 OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 7, 7, 1, 1),
580WSS_DOUBLE_TLV("Master Playback Volume", 0,
581 OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 1, 1, 31, 1,
582 db_scale_5bit_3db_step),
583WSS_DOUBLE_TLV("PCM Playback Volume", 0,
584 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 31, 1,
585 db_scale_5bit),
586WSS_DOUBLE_TLV("FM Playback Volume", 0,
587 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 1, 1, 15, 1,
588 db_scale_4bit_12db_max),
589WSS_DOUBLE("Line Playback Switch", 0,
590 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1),
591WSS_DOUBLE_TLV("Line Playback Volume", 0,
592 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 15, 1,
593 db_scale_4bit_12db_max),
594WSS_DOUBLE("Mic Playback Switch", 0,
595 OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 7, 7, 1, 1),
596WSS_DOUBLE_TLV("Mic Playback Volume", 0,
597 OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 1, 1, 15, 1,
598 db_scale_4bit_12db_max),
599WSS_DOUBLE_TLV("CD Playback Volume", 0,
600 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 1, 1, 15, 1,
601 db_scale_4bit_12db_max),
602WSS_DOUBLE("Aux Playback Switch", 0,
603 OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 7, 7, 1, 1),
604WSS_DOUBLE_TLV("Aux Playback Volume", 0,
605 OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 1, 1, 15, 1,
606 db_scale_4bit_12db_max),
607};
608
609static int __devinit snd_opti93x_mixer(struct snd_wss *chip)
610{
611 struct snd_card *card;
612 unsigned int idx;
613 struct snd_ctl_elem_id id1, id2;
614 int err;
615
616 if (snd_BUG_ON(!chip || !chip->pcm))
617 return -EINVAL;
618
619 card = chip->card;
620
621 strcpy(card->mixername, chip->pcm->name);
622
623 memset(&id1, 0, sizeof(id1));
624 memset(&id2, 0, sizeof(id2));
625 id1.iface = id2.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
626 /* reassign AUX0 switch to CD */
627 strcpy(id1.name, "Aux Playback Switch");
628 strcpy(id2.name, "CD Playback Switch");
629 err = snd_ctl_rename_id(card, &id1, &id2);
630 if (err < 0) {
631 snd_printk(KERN_ERR "Cannot rename opti93x control\n");
632 return err;
633 }
634 /* reassign AUX1 switch to FM */
635 strcpy(id1.name, "Aux Playback Switch"); id1.index = 1;
636 strcpy(id2.name, "FM Playback Switch");
637 err = snd_ctl_rename_id(card, &id1, &id2);
638 if (err < 0) {
639 snd_printk(KERN_ERR "Cannot rename opti93x control\n");
640 return err;
641 }
642 /* remove AUX1 volume */
643 strcpy(id1.name, "Aux Playback Volume"); id1.index = 1;
644 snd_ctl_remove_id(card, &id1);
645
646 /* Replace WSS volume controls with OPTi93x volume controls */
647 id1.index = 0;
648 for (idx = 0; idx < ARRAY_SIZE(snd_opti93x_controls); idx++) {
649 strcpy(id1.name, snd_opti93x_controls[idx].name);
650 snd_ctl_remove_id(card, &id1);
651
652 err = snd_ctl_add(card,
653 snd_ctl_new1(&snd_opti93x_controls[idx], chip));
654 if (err < 0)
655 return err;
656 }
657 return 0;
658}
659
559static irqreturn_t snd_opti93x_interrupt(int irq, void *dev_id) 660static irqreturn_t snd_opti93x_interrupt(int irq, void *dev_id)
560{ 661{
561 struct snd_wss *codec = dev_id; 662 struct snd_opti9xx *chip = dev_id;
562 struct snd_opti9xx *chip = codec->card->private_data; 663 struct snd_wss *codec = chip->codec;
563 unsigned char status; 664 unsigned char status;
564 665
666 if (!codec)
667 return IRQ_HANDLED;
668
565 status = snd_opti9xx_read(chip, OPTi9XX_MC_REG(11)); 669 status = snd_opti9xx_read(chip, OPTi9XX_MC_REG(11));
566 if ((status & OPTi93X_IRQ_PLAYBACK) && codec->playback_substream) 670 if ((status & OPTi93X_IRQ_PLAYBACK) && codec->playback_substream)
567 snd_pcm_period_elapsed(codec->playback_substream); 671 snd_pcm_period_elapsed(codec->playback_substream);
@@ -575,57 +679,69 @@ static irqreturn_t snd_opti93x_interrupt(int irq, void *dev_id)
575 679
576#endif /* OPTi93X */ 680#endif /* OPTi93X */
577 681
578static int __devinit snd_card_opti9xx_detect(struct snd_card *card, 682static int __devinit snd_opti9xx_read_check(struct snd_opti9xx *chip)
579 struct snd_opti9xx *chip)
580{ 683{
581 int i, err; 684 unsigned char value;
685#ifdef OPTi93X
686 unsigned long flags;
687#endif
582 688
689 chip->res_mc_base = request_region(chip->mc_base, chip->mc_base_size,
690 "OPTi9xx MC");
691 if (chip->res_mc_base == NULL)
692 return -EBUSY;
583#ifndef OPTi93X 693#ifndef OPTi93X
584 for (i = OPTi9XX_HW_82C928; i < OPTi9XX_HW_82C930; i++) { 694 value = snd_opti9xx_read(chip, OPTi9XX_MC_REG(1));
585 unsigned char value; 695 if (value != 0xff && value != inb(chip->mc_base + OPTi9XX_MC_REG(1)))
696 if (value == snd_opti9xx_read(chip, OPTi9XX_MC_REG(1)))
697 return 0;
698#else /* OPTi93X */
699 chip->res_mc_indir = request_region(chip->mc_indir_index,
700 chip->mc_indir_size,
701 "OPTi93x MC");
702 if (chip->res_mc_indir == NULL)
703 return -EBUSY;
586 704
587 if ((err = snd_opti9xx_init(chip, i)) < 0) 705 spin_lock_irqsave(&chip->lock, flags);
588 return err; 706 outb(chip->password, chip->mc_base + chip->pwd_reg);
707 outb(((chip->mc_indir_index & 0x1f0) >> 4), chip->mc_base);
708 spin_unlock_irqrestore(&chip->lock, flags);
589 709
590 if ((chip->res_mc_base = request_region(chip->mc_base, chip->mc_base_size, "OPTi9xx MC")) == NULL) 710 value = snd_opti9xx_read(chip, OPTi9XX_MC_REG(7));
591 continue; 711 snd_opti9xx_write(chip, OPTi9XX_MC_REG(7), 0xff - value);
712 if (snd_opti9xx_read(chip, OPTi9XX_MC_REG(7)) == 0xff - value)
713 return 0;
592 714
593 value = snd_opti9xx_read(chip, OPTi9XX_MC_REG(1)); 715 release_and_free_resource(chip->res_mc_indir);
594 if ((value != 0xff) && (value != inb(chip->mc_base + 1))) 716 chip->res_mc_indir = NULL;
595 if (value == snd_opti9xx_read(chip, OPTi9XX_MC_REG(1))) 717#endif /* OPTi93X */
596 return 1; 718 release_and_free_resource(chip->res_mc_base);
719 chip->res_mc_base = NULL;
597 720
598 release_and_free_resource(chip->res_mc_base); 721 return -ENODEV;
599 chip->res_mc_base = NULL; 722}
600 723
601 } 724static int __devinit snd_card_opti9xx_detect(struct snd_card *card,
602#else /* OPTi93X */ 725 struct snd_opti9xx *chip)
603 for (i = OPTi9XX_HW_82C931; i >= OPTi9XX_HW_82C930; i--) { 726{
604 unsigned long flags; 727 int i, err;
605 unsigned char value;
606 728
607 if ((err = snd_opti9xx_init(chip, i)) < 0) 729#ifndef OPTi93X
730 for (i = OPTi9XX_HW_82C928; i < OPTi9XX_HW_82C930; i++) {
731#else
732 for (i = OPTi9XX_HW_82C931; i >= OPTi9XX_HW_82C930; i--) {
733#endif
734 err = snd_opti9xx_init(chip, i);
735 if (err < 0)
608 return err; 736 return err;
609 737
610 if ((chip->res_mc_base = request_region(chip->mc_base, chip->mc_base_size, "OPTi9xx MC")) == NULL) 738 err = snd_opti9xx_read_check(chip);
611 continue; 739 if (err == 0)
612
613 spin_lock_irqsave(&chip->lock, flags);
614 outb(chip->password, chip->mc_base + chip->pwd_reg);
615 outb(((chip->mc_indir_index & (1 << 8)) >> 4) |
616 ((chip->mc_indir_index & 0xf0) >> 4), chip->mc_base);
617 spin_unlock_irqrestore(&chip->lock, flags);
618
619 value = snd_opti9xx_read(chip, OPTi9XX_MC_REG(7));
620 snd_opti9xx_write(chip, OPTi9XX_MC_REG(7), 0xff - value);
621 if (snd_opti9xx_read(chip, OPTi9XX_MC_REG(7)) == 0xff - value)
622 return 1; 740 return 1;
623 741#ifdef OPTi93X
624 release_and_free_resource(chip->res_mc_base); 742 chip->mc_indir_index = 0;
625 chip->res_mc_base = NULL; 743#endif
626 } 744 }
627#endif /* OPTi93X */
628
629 return -ENODEV; 745 return -ENODEV;
630} 746}
631 747
@@ -636,15 +752,15 @@ static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip,
636{ 752{
637 struct pnp_dev *pdev; 753 struct pnp_dev *pdev;
638 int err; 754 int err;
755 struct pnp_dev *devmpu;
756#ifndef OPTi93X
757 struct pnp_dev *devmc;
758#endif
639 759
640 chip->dev = pnp_request_card_device(card, pid->devs[0].id, NULL); 760 pdev = pnp_request_card_device(card, pid->devs[0].id, NULL);
641 if (chip->dev == NULL) 761 if (pdev == NULL)
642 return -EBUSY; 762 return -EBUSY;
643 763
644 chip->devmpu = pnp_request_card_device(card, pid->devs[1].id, NULL);
645
646 pdev = chip->dev;
647
648 err = pnp_activate_dev(pdev); 764 err = pnp_activate_dev(pdev);
649 if (err < 0) { 765 if (err < 0) {
650 snd_printk(KERN_ERR "AUDIO pnp configure failure: %d\n", err); 766 snd_printk(KERN_ERR "AUDIO pnp configure failure: %d\n", err);
@@ -654,10 +770,27 @@ static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip,
654#ifdef OPTi93X 770#ifdef OPTi93X
655 port = pnp_port_start(pdev, 0) - 4; 771 port = pnp_port_start(pdev, 0) - 4;
656 fm_port = pnp_port_start(pdev, 1) + 8; 772 fm_port = pnp_port_start(pdev, 1) + 8;
773 chip->mc_indir_index = pnp_port_start(pdev, 3) + 2;
774 chip->mc_indir_size = pnp_port_len(pdev, 3) - 2;
657#else 775#else
658 if (pid->driver_data != 0x0924) 776 devmc = pnp_request_card_device(card, pid->devs[2].id, NULL);
659 port = pnp_port_start(pdev, 1); 777 if (devmc == NULL)
778 return -EBUSY;
779
780 err = pnp_activate_dev(devmc);
781 if (err < 0) {
782 snd_printk(KERN_ERR "MC pnp configure failure: %d\n", err);
783 return err;
784 }
785
786 port = pnp_port_start(pdev, 1);
660 fm_port = pnp_port_start(pdev, 2) + 8; 787 fm_port = pnp_port_start(pdev, 2) + 8;
788 /*
789 * The MC(0) is never accessed and card does not
790 * include it in the PnP resource range. OPTI93x include it.
791 */
792 chip->mc_base = pnp_port_start(devmc, 0) - 1;
793 chip->mc_base_size = pnp_port_len(devmc, 0) + 1;
661#endif /* OPTi93X */ 794#endif /* OPTi93X */
662 irq = pnp_irq(pdev, 0); 795 irq = pnp_irq(pdev, 0);
663 dma1 = pnp_dma(pdev, 0); 796 dma1 = pnp_dma(pdev, 0);
@@ -665,16 +798,16 @@ static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip,
665 dma2 = pnp_dma(pdev, 1); 798 dma2 = pnp_dma(pdev, 1);
666#endif /* CS4231 || OPTi93X */ 799#endif /* CS4231 || OPTi93X */
667 800
668 pdev = chip->devmpu; 801 devmpu = pnp_request_card_device(card, pid->devs[1].id, NULL);
669 if (pdev && mpu_port > 0) { 802
670 err = pnp_activate_dev(pdev); 803 if (devmpu && mpu_port > 0) {
804 err = pnp_activate_dev(devmpu);
671 if (err < 0) { 805 if (err < 0) {
672 snd_printk(KERN_ERR "AUDIO pnp configure failure\n"); 806 snd_printk(KERN_ERR "MPU401 pnp configure failure\n");
673 mpu_port = -1; 807 mpu_port = -1;
674 chip->devmpu = NULL;
675 } else { 808 } else {
676 mpu_port = pnp_port_start(pdev, 0); 809 mpu_port = pnp_port_start(devmpu, 0);
677 mpu_irq = pnp_irq(pdev, 0); 810 mpu_irq = pnp_irq(devmpu, 0);
678 } 811 }
679 } 812 }
680 return pid->driver_data; 813 return pid->driver_data;
@@ -684,14 +817,14 @@ static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip,
684static void snd_card_opti9xx_free(struct snd_card *card) 817static void snd_card_opti9xx_free(struct snd_card *card)
685{ 818{
686 struct snd_opti9xx *chip = card->private_data; 819 struct snd_opti9xx *chip = card->private_data;
687 820
688 if (chip) { 821 if (chip) {
689#ifdef OPTi93X 822#ifdef OPTi93X
690 struct snd_wss *codec = chip->codec; 823 if (chip->irq > 0) {
691 if (codec && codec->irq > 0) { 824 disable_irq(chip->irq);
692 disable_irq(codec->irq); 825 free_irq(chip->irq, chip);
693 free_irq(codec->irq, codec);
694 } 826 }
827 release_and_free_resource(chip->res_mc_indir);
695#endif 828#endif
696 release_and_free_resource(chip->res_mc_base); 829 release_and_free_resource(chip->res_mc_base);
697 } 830 }
@@ -701,6 +834,7 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card)
701{ 834{
702 static long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1}; 835 static long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1};
703 int error; 836 int error;
837 int xdma2;
704 struct snd_opti9xx *chip = card->private_data; 838 struct snd_opti9xx *chip = card->private_data;
705 struct snd_wss *codec; 839 struct snd_wss *codec;
706#ifdef CS4231 840#ifdef CS4231
@@ -710,36 +844,25 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card)
710 struct snd_rawmidi *rmidi; 844 struct snd_rawmidi *rmidi;
711 struct snd_hwdep *synth; 845 struct snd_hwdep *synth;
712 846
713 if (! chip->res_mc_base &&
714 (chip->res_mc_base = request_region(chip->mc_base, chip->mc_base_size,
715 "OPTi9xx MC")) == NULL)
716 return -ENOMEM;
717
718 chip->wss_base = port;
719 chip->fm_port = fm_port;
720 chip->mpu_port = mpu_port;
721 chip->irq = irq;
722 chip->mpu_irq = mpu_irq;
723 chip->dma1 = dma1;
724#if defined(CS4231) || defined(OPTi93X) 847#if defined(CS4231) || defined(OPTi93X)
725 chip->dma2 = dma2; 848 xdma2 = dma2;
726#else 849#else
727 chip->dma2 = -1; 850 xdma2 = -1;
728#endif 851#endif
729 852
730 if (chip->wss_base == SNDRV_AUTO_PORT) { 853 if (port == SNDRV_AUTO_PORT) {
731 chip->wss_base = snd_legacy_find_free_ioport(possible_ports, 4); 854 port = snd_legacy_find_free_ioport(possible_ports, 4);
732 if (chip->wss_base < 0) { 855 if (port < 0) {
733 snd_printk(KERN_ERR "unable to find a free WSS port\n"); 856 snd_printk(KERN_ERR "unable to find a free WSS port\n");
734 return -EBUSY; 857 return -EBUSY;
735 } 858 }
736 } 859 }
737 error = snd_opti9xx_configure(chip); 860 error = snd_opti9xx_configure(chip, port, irq, dma1, xdma2,
861 mpu_port, mpu_irq);
738 if (error) 862 if (error)
739 return error; 863 return error;
740 864
741 error = snd_wss_create(card, chip->wss_base + 4, -1, 865 error = snd_wss_create(card, chip->wss_base + 4, -1, irq, dma1, xdma2,
742 chip->irq, chip->dma1, chip->dma2,
743#ifdef OPTi93X 866#ifdef OPTi93X
744 WSS_HW_OPTI93X, WSS_HWSHARE_IRQ, 867 WSS_HW_OPTI93X, WSS_HWSHARE_IRQ,
745#else 868#else
@@ -757,41 +880,47 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card)
757 error = snd_wss_mixer(codec); 880 error = snd_wss_mixer(codec);
758 if (error < 0) 881 if (error < 0)
759 return error; 882 return error;
883#ifdef OPTi93X
884 error = snd_opti93x_mixer(codec);
885 if (error < 0)
886 return error;
887#endif
760#ifdef CS4231 888#ifdef CS4231
761 error = snd_wss_timer(codec, 0, &timer); 889 error = snd_wss_timer(codec, 0, &timer);
762 if (error < 0) 890 if (error < 0)
763 return error; 891 return error;
764#endif 892#endif
765#ifdef OPTi93X 893#ifdef OPTi93X
766 error = request_irq(chip->irq, snd_opti93x_interrupt, 894 error = request_irq(irq, snd_opti93x_interrupt,
767 IRQF_DISABLED, DEV_NAME" - WSS", codec); 895 IRQF_DISABLED, DEV_NAME" - WSS", chip);
768 if (error < 0) { 896 if (error < 0) {
769 snd_printk(KERN_ERR "opti9xx: can't grab IRQ %d\n", chip->irq); 897 snd_printk(KERN_ERR "opti9xx: can't grab IRQ %d\n", irq);
770 return error; 898 return error;
771 } 899 }
772#endif 900#endif
901 chip->irq = irq;
773 strcpy(card->driver, chip->name); 902 strcpy(card->driver, chip->name);
774 sprintf(card->shortname, "OPTi %s", card->driver); 903 sprintf(card->shortname, "OPTi %s", card->driver);
775#if defined(CS4231) || defined(OPTi93X) 904#if defined(CS4231) || defined(OPTi93X)
776 sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d&%d", 905 sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d&%d",
777 card->shortname, pcm->name, chip->wss_base + 4, 906 card->shortname, pcm->name,
778 chip->irq, chip->dma1, chip->dma2); 907 chip->wss_base + 4, irq, dma1, xdma2);
779#else 908#else
780 sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d", 909 sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d",
781 card->shortname, pcm->name, chip->wss_base + 4, 910 card->shortname, pcm->name, chip->wss_base + 4, irq, dma1);
782 chip->irq, chip->dma1);
783#endif /* CS4231 || OPTi93X */ 911#endif /* CS4231 || OPTi93X */
784 912
785 if (chip->mpu_port <= 0 || chip->mpu_port == SNDRV_AUTO_PORT) 913 if (mpu_port <= 0 || mpu_port == SNDRV_AUTO_PORT)
786 rmidi = NULL; 914 rmidi = NULL;
787 else 915 else {
788 if ((error = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, 916 error = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
789 chip->mpu_port, 0, chip->mpu_irq, IRQF_DISABLED, 917 mpu_port, 0, mpu_irq, IRQF_DISABLED, &rmidi);
790 &rmidi))) 918 if (error)
791 snd_printk(KERN_WARNING "no MPU-401 device at 0x%lx?\n", 919 snd_printk(KERN_WARNING "no MPU-401 device at 0x%lx?\n",
792 chip->mpu_port); 920 mpu_port);
921 }
793 922
794 if (chip->fm_port > 0 && chip->fm_port != SNDRV_AUTO_PORT) { 923 if (fm_port > 0 && fm_port != SNDRV_AUTO_PORT) {
795 struct snd_opl3 *opl3 = NULL; 924 struct snd_opl3 *opl3 = NULL;
796#ifndef OPTi93X 925#ifndef OPTi93X
797 if (chip->hardware == OPTi9XX_HW_82C928 || 926 if (chip->hardware == OPTi9XX_HW_82C928 ||
@@ -801,9 +930,7 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card)
801 /* assume we have an OPL4 */ 930 /* assume we have an OPL4 */
802 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(2), 931 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(2),
803 0x20, 0x20); 932 0x20, 0x20);
804 if (snd_opl4_create(card, 933 if (snd_opl4_create(card, fm_port, fm_port - 8,
805 chip->fm_port,
806 chip->fm_port - 8,
807 2, &opl3, &opl4) < 0) { 934 2, &opl3, &opl4) < 0) {
808 /* no luck, use OPL3 instead */ 935 /* no luck, use OPL3 instead */
809 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(2), 936 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(2),
@@ -811,12 +938,10 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card)
811 } 938 }
812 } 939 }
813#endif /* !OPTi93X */ 940#endif /* !OPTi93X */
814 if (!opl3 && snd_opl3_create(card, 941 if (!opl3 && snd_opl3_create(card, fm_port, fm_port + 2,
815 chip->fm_port,
816 chip->fm_port + 2,
817 OPL3_HW_AUTO, 0, &opl3) < 0) { 942 OPL3_HW_AUTO, 0, &opl3) < 0) {
818 snd_printk(KERN_WARNING "no OPL device at 0x%lx-0x%lx\n", 943 snd_printk(KERN_WARNING "no OPL device at 0x%lx-0x%lx\n",
819 chip->fm_port, chip->fm_port + 4 - 1); 944 fm_port, fm_port + 4 - 1);
820 } 945 }
821 if (opl3) { 946 if (opl3) {
822 error = snd_opl3_hwdep_new(opl3, 0, 1, &synth); 947 error = snd_opl3_hwdep_new(opl3, 0, 1, &synth);
@@ -976,8 +1101,12 @@ static int __devinit snd_opti9xx_pnp_probe(struct pnp_card_link *pcard,
976 snd_card_free(card); 1101 snd_card_free(card);
977 return error; 1102 return error;
978 } 1103 }
979 if (hw <= OPTi9XX_HW_82C930) 1104 error = snd_opti9xx_read_check(chip);
980 chip->mc_base -= 0x80; 1105 if (error) {
1106 snd_printk(KERN_ERR "OPTI chip not found\n");
1107 snd_card_free(card);
1108 return error;
1109 }
981 snd_card_set_dev(card, &pcard->card->dev); 1110 snd_card_set_dev(card, &pcard->card->dev);
982 if ((error = snd_opti9xx_probe(card)) < 0) { 1111 if ((error = snd_opti9xx_probe(card)) < 0) {
983 snd_card_free(card); 1112 snd_card_free(card);
diff --git a/sound/isa/sb/Makefile b/sound/isa/sb/Makefile
index faeffceb01b7..af3669681788 100644
--- a/sound/isa/sb/Makefile
+++ b/sound/isa/sb/Makefile
@@ -12,6 +12,7 @@ snd-sb16-objs := sb16.o
12snd-sbawe-objs := sbawe.o emu8000.o 12snd-sbawe-objs := sbawe.o emu8000.o
13snd-emu8000-synth-objs := emu8000_synth.o emu8000_callback.o emu8000_patch.o emu8000_pcm.o 13snd-emu8000-synth-objs := emu8000_synth.o emu8000_callback.o emu8000_patch.o emu8000_pcm.o
14snd-es968-objs := es968.o 14snd-es968-objs := es968.o
15snd-jazz16-objs := jazz16.o
15 16
16# Toplevel Module Dependency 17# Toplevel Module Dependency
17obj-$(CONFIG_SND_SB_COMMON) += snd-sb-common.o 18obj-$(CONFIG_SND_SB_COMMON) += snd-sb-common.o
@@ -21,6 +22,7 @@ obj-$(CONFIG_SND_SB8) += snd-sb8.o
21obj-$(CONFIG_SND_SB16) += snd-sb16.o 22obj-$(CONFIG_SND_SB16) += snd-sb16.o
22obj-$(CONFIG_SND_SBAWE) += snd-sbawe.o 23obj-$(CONFIG_SND_SBAWE) += snd-sbawe.o
23obj-$(CONFIG_SND_ES968) += snd-es968.o 24obj-$(CONFIG_SND_ES968) += snd-es968.o
25obj-$(CONFIG_SND_JAZZ16) += snd-jazz16.o
24ifeq ($(CONFIG_SND_SB16_CSP),y) 26ifeq ($(CONFIG_SND_SB16_CSP),y)
25 obj-$(CONFIG_SND_SB16) += snd-sb16-csp.o 27 obj-$(CONFIG_SND_SB16) += snd-sb16-csp.o
26 obj-$(CONFIG_SND_SBAWE) += snd-sb16-csp.o 28 obj-$(CONFIG_SND_SBAWE) += snd-sb16-csp.o
diff --git a/sound/isa/sb/emu8000.c b/sound/isa/sb/emu8000.c
index 96678d5d3834..0c40951b6523 100644
--- a/sound/isa/sb/emu8000.c
+++ b/sound/isa/sb/emu8000.c
@@ -377,12 +377,13 @@ init_arrays(struct snd_emu8000 *emu)
377static void __devinit 377static void __devinit
378size_dram(struct snd_emu8000 *emu) 378size_dram(struct snd_emu8000 *emu)
379{ 379{
380 int i, size; 380 int i, size, detected_size;
381 381
382 if (emu->dram_checked) 382 if (emu->dram_checked)
383 return; 383 return;
384 384
385 size = 0; 385 size = 0;
386 detected_size = 0;
386 387
387 /* write out a magic number */ 388 /* write out a magic number */
388 snd_emu8000_dma_chan(emu, 0, EMU8000_RAM_WRITE); 389 snd_emu8000_dma_chan(emu, 0, EMU8000_RAM_WRITE);
@@ -414,7 +415,9 @@ size_dram(struct snd_emu8000 *emu)
414 /*snd_emu8000_read_wait(emu);*/ 415 /*snd_emu8000_read_wait(emu);*/
415 EMU8000_SMLD_READ(emu); /* discard stale data */ 416 EMU8000_SMLD_READ(emu); /* discard stale data */
416 if (EMU8000_SMLD_READ(emu) != UNIQUE_ID2) 417 if (EMU8000_SMLD_READ(emu) != UNIQUE_ID2)
417 break; /* we must have wrapped around */ 418 break; /* no memory at this address */
419
420 detected_size = size;
418 421
419 snd_emu8000_read_wait(emu); 422 snd_emu8000_read_wait(emu);
420 423
@@ -442,9 +445,9 @@ size_dram(struct snd_emu8000 *emu)
442 snd_emu8000_dma_chan(emu, 1, EMU8000_RAM_CLOSE); 445 snd_emu8000_dma_chan(emu, 1, EMU8000_RAM_CLOSE);
443 446
444 snd_printdd("EMU8000 [0x%lx]: %d Kb on-board memory detected\n", 447 snd_printdd("EMU8000 [0x%lx]: %d Kb on-board memory detected\n",
445 emu->port1, size/1024); 448 emu->port1, detected_size/1024);
446 449
447 emu->mem_size = size; 450 emu->mem_size = detected_size;
448 emu->dram_checked = 1; 451 emu->dram_checked = 1;
449} 452}
450 453
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
index cafc3a7316a8..ff18286fef9d 100644
--- a/sound/isa/sb/es968.c
+++ b/sound/isa/sb/es968.c
@@ -93,7 +93,7 @@ static int __devinit snd_card_es968_pnp(int dev, struct snd_card_es968 *acard,
93 return err; 93 return err;
94 } 94 }
95 port[dev] = pnp_port_start(pdev, 0); 95 port[dev] = pnp_port_start(pdev, 0);
96 dma8[dev] = pnp_dma(pdev, 1); 96 dma8[dev] = pnp_dma(pdev, 0);
97 irq[dev] = pnp_irq(pdev, 0); 97 irq[dev] = pnp_irq(pdev, 0);
98 98
99 return 0; 99 return 0;
diff --git a/sound/isa/sb/jazz16.c b/sound/isa/sb/jazz16.c
new file mode 100644
index 000000000000..8ccbcddf08e1
--- /dev/null
+++ b/sound/isa/sb/jazz16.c
@@ -0,0 +1,405 @@
1
2/*
3 * jazz16.c - driver for Media Vision Jazz16 based soundcards.
4 * Copyright (C) 2009 Krzysztof Helt <krzysztof.h1@wp.pl>
5 * Based on patches posted by Rask Ingemann Lambertsen and Rene Herman.
6 * Based on OSS Sound Blaster driver.
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file COPYING in the main directory of this archive for
10 * more details.
11 *
12 */
13
14#include <linux/init.h>
15#include <linux/module.h>
16#include <linux/io.h>
17#include <linux/delay.h>
18#include <asm/dma.h>
19#include <linux/isa.h>
20#include <sound/core.h>
21#include <sound/mpu401.h>
22#include <sound/opl3.h>
23#include <sound/sb.h>
24#define SNDRV_LEGACY_FIND_FREE_IRQ
25#define SNDRV_LEGACY_FIND_FREE_DMA
26#include <sound/initval.h>
27
28#define PFX "jazz16: "
29
30MODULE_DESCRIPTION("Media Vision Jazz16");
31MODULE_SUPPORTED_DEVICE("{{Media Vision ??? },"
32 "{RTL,RTL3000}}");
33
34MODULE_AUTHOR("Krzysztof Helt <krzysztof.h1@wp.pl>");
35MODULE_LICENSE("GPL");
36
37static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
38static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
39static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
40static unsigned long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
41static unsigned long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
42static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
43static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
44static int dma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;
45static int dma16[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;
46
47module_param_array(index, int, NULL, 0444);
48MODULE_PARM_DESC(index, "Index value for Media Vision Jazz16 based soundcard.");
49module_param_array(id, charp, NULL, 0444);
50MODULE_PARM_DESC(id, "ID string for Media Vision Jazz16 based soundcard.");
51module_param_array(enable, bool, NULL, 0444);
52MODULE_PARM_DESC(enable, "Enable Media Vision Jazz16 based soundcard.");
53module_param_array(port, long, NULL, 0444);
54MODULE_PARM_DESC(port, "Port # for jazz16 driver.");
55module_param_array(mpu_port, long, NULL, 0444);
56MODULE_PARM_DESC(mpu_port, "MPU-401 port # for jazz16 driver.");
57module_param_array(irq, int, NULL, 0444);
58MODULE_PARM_DESC(irq, "IRQ # for jazz16 driver.");
59module_param_array(mpu_irq, int, NULL, 0444);
60MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for jazz16 driver.");
61module_param_array(dma8, int, NULL, 0444);
62MODULE_PARM_DESC(dma8, "DMA8 # for jazz16 driver.");
63module_param_array(dma16, int, NULL, 0444);
64MODULE_PARM_DESC(dma16, "DMA16 # for jazz16 driver.");
65
66#define SB_JAZZ16_WAKEUP 0xaf
67#define SB_JAZZ16_SET_PORTS 0x50
68#define SB_DSP_GET_JAZZ_BRD_REV 0xfa
69#define SB_JAZZ16_SET_DMAINTR 0xfb
70#define SB_DSP_GET_JAZZ_MODEL 0xfe
71
72struct snd_card_jazz16 {
73 struct snd_sb *chip;
74};
75
76static irqreturn_t jazz16_interrupt(int irq, void *chip)
77{
78 return snd_sb8dsp_interrupt(chip);
79}
80
81static int __devinit jazz16_configure_ports(unsigned long port,
82 unsigned long mpu_port, int idx)
83{
84 unsigned char val;
85
86 if (!request_region(0x201, 1, "jazz16 config")) {
87 snd_printk(KERN_ERR "config port region is already in use.\n");
88 return -EBUSY;
89 }
90 outb(SB_JAZZ16_WAKEUP - idx, 0x201);
91 udelay(100);
92 outb(SB_JAZZ16_SET_PORTS + idx, 0x201);
93 udelay(100);
94 val = port & 0x70;
95 val |= (mpu_port & 0x30) >> 4;
96 outb(val, 0x201);
97
98 release_region(0x201, 1);
99 return 0;
100}
101
102static int __devinit jazz16_detect_board(unsigned long port,
103 unsigned long mpu_port)
104{
105 int err;
106 int val;
107 struct snd_sb chip;
108
109 if (!request_region(port, 0x10, "jazz16")) {
110 snd_printk(KERN_ERR "I/O port region is already in use.\n");
111 return -EBUSY;
112 }
113 /* just to call snd_sbdsp_command/reset/get_byte() */
114 chip.port = port;
115
116 err = snd_sbdsp_reset(&chip);
117 if (err < 0)
118 for (val = 0; val < 4; val++) {
119 err = jazz16_configure_ports(port, mpu_port, val);
120 if (err < 0)
121 break;
122
123 err = snd_sbdsp_reset(&chip);
124 if (!err)
125 break;
126 }
127 if (err < 0) {
128 err = -ENODEV;
129 goto err_unmap;
130 }
131 if (!snd_sbdsp_command(&chip, SB_DSP_GET_JAZZ_BRD_REV)) {
132 err = -EBUSY;
133 goto err_unmap;
134 }
135 val = snd_sbdsp_get_byte(&chip);
136 if (val >= 0x30)
137 snd_sbdsp_get_byte(&chip);
138
139 if ((val & 0xf0) != 0x10) {
140 err = -ENODEV;
141 goto err_unmap;
142 }
143 if (!snd_sbdsp_command(&chip, SB_DSP_GET_JAZZ_MODEL)) {
144 err = -EBUSY;
145 goto err_unmap;
146 }
147 snd_sbdsp_get_byte(&chip);
148 err = snd_sbdsp_get_byte(&chip);
149 snd_printd("Media Vision Jazz16 board detected: rev 0x%x, model 0x%x\n",
150 val, err);
151
152 err = 0;
153
154err_unmap:
155 release_region(port, 0x10);
156 return err;
157}
158
159static int __devinit jazz16_configure_board(struct snd_sb *chip, int mpu_irq)
160{
161 static unsigned char jazz_irq_bits[] = { 0, 0, 2, 3, 0, 1, 0, 4,
162 0, 2, 5, 0, 0, 0, 0, 6 };
163 static unsigned char jazz_dma_bits[] = { 0, 1, 0, 2, 0, 3, 0, 4 };
164
165 if (jazz_dma_bits[chip->dma8] == 0 ||
166 jazz_dma_bits[chip->dma16] == 0 ||
167 jazz_irq_bits[chip->irq] == 0)
168 return -EINVAL;
169
170 if (!snd_sbdsp_command(chip, SB_JAZZ16_SET_DMAINTR))
171 return -EBUSY;
172
173 if (!snd_sbdsp_command(chip,
174 jazz_dma_bits[chip->dma8] |
175 (jazz_dma_bits[chip->dma16] << 4)))
176 return -EBUSY;
177
178 if (!snd_sbdsp_command(chip,
179 jazz_irq_bits[chip->irq] |
180 (jazz_irq_bits[mpu_irq] << 4)))
181 return -EBUSY;
182
183 return 0;
184}
185
186static int __devinit snd_jazz16_match(struct device *devptr, unsigned int dev)
187{
188 if (!enable[dev])
189 return 0;
190 if (port[dev] == SNDRV_AUTO_PORT) {
191 snd_printk(KERN_ERR "please specify port\n");
192 return 0;
193 } else if (port[dev] == 0x200 || (port[dev] & ~0x270)) {
194 snd_printk(KERN_ERR "incorrect port specified\n");
195 return 0;
196 }
197 if (dma8[dev] != SNDRV_AUTO_DMA &&
198 dma8[dev] != 1 && dma8[dev] != 3) {
199 snd_printk(KERN_ERR "dma8 must be 1 or 3\n");
200 return 0;
201 }
202 if (dma16[dev] != SNDRV_AUTO_DMA &&
203 dma16[dev] != 5 && dma16[dev] != 7) {
204 snd_printk(KERN_ERR "dma16 must be 5 or 7\n");
205 return 0;
206 }
207 if (mpu_port[dev] != SNDRV_AUTO_PORT &&
208 (mpu_port[dev] & ~0x030) != 0x300) {
209 snd_printk(KERN_ERR "incorrect mpu_port specified\n");
210 return 0;
211 }
212 if (mpu_irq[dev] != SNDRV_AUTO_DMA &&
213 mpu_irq[dev] != 2 && mpu_irq[dev] != 3 &&
214 mpu_irq[dev] != 5 && mpu_irq[dev] != 7) {
215 snd_printk(KERN_ERR "mpu_irq must be 2, 3, 5 or 7\n");
216 return 0;
217 }
218 return 1;
219}
220
221static int __devinit snd_jazz16_probe(struct device *devptr, unsigned int dev)
222{
223 struct snd_card *card;
224 struct snd_card_jazz16 *jazz16;
225 struct snd_sb *chip;
226 struct snd_opl3 *opl3;
227 static int possible_irqs[] = {2, 3, 5, 7, 9, 10, 15, -1};
228 static int possible_dmas8[] = {1, 3, -1};
229 static int possible_dmas16[] = {5, 7, -1};
230 int err, xirq, xdma8, xdma16, xmpu_port, xmpu_irq;
231
232 err = snd_card_create(index[dev], id[dev], THIS_MODULE,
233 sizeof(struct snd_card_jazz16), &card);
234 if (err < 0)
235 return err;
236
237 jazz16 = card->private_data;
238
239 xirq = irq[dev];
240 if (xirq == SNDRV_AUTO_IRQ) {
241 xirq = snd_legacy_find_free_irq(possible_irqs);
242 if (xirq < 0) {
243 snd_printk(KERN_ERR "unable to find a free IRQ\n");
244 err = -EBUSY;
245 goto err_free;
246 }
247 }
248 xdma8 = dma8[dev];
249 if (xdma8 == SNDRV_AUTO_DMA) {
250 xdma8 = snd_legacy_find_free_dma(possible_dmas8);
251 if (xdma8 < 0) {
252 snd_printk(KERN_ERR "unable to find a free DMA8\n");
253 err = -EBUSY;
254 goto err_free;
255 }
256 }
257 xdma16 = dma16[dev];
258 if (xdma16 == SNDRV_AUTO_DMA) {
259 xdma16 = snd_legacy_find_free_dma(possible_dmas16);
260 if (xdma16 < 0) {
261 snd_printk(KERN_ERR "unable to find a free DMA16\n");
262 err = -EBUSY;
263 goto err_free;
264 }
265 }
266
267 xmpu_port = mpu_port[dev];
268 if (xmpu_port == SNDRV_AUTO_PORT)
269 xmpu_port = 0;
270 err = jazz16_detect_board(port[dev], xmpu_port);
271 if (err < 0) {
272 printk(KERN_ERR "Media Vision Jazz16 board not detected\n");
273 goto err_free;
274 }
275 err = snd_sbdsp_create(card, port[dev], irq[dev],
276 jazz16_interrupt,
277 dma8[dev], dma16[dev],
278 SB_HW_JAZZ16,
279 &chip);
280 if (err < 0)
281 goto err_free;
282
283 xmpu_irq = mpu_irq[dev];
284 if (xmpu_irq == SNDRV_AUTO_IRQ || mpu_port[dev] == SNDRV_AUTO_PORT)
285 xmpu_irq = 0;
286 err = jazz16_configure_board(chip, xmpu_irq);
287 if (err < 0) {
288 printk(KERN_ERR "Media Vision Jazz16 configuration failed\n");
289 goto err_free;
290 }
291
292 jazz16->chip = chip;
293
294 strcpy(card->driver, "jazz16");
295 strcpy(card->shortname, "Media Vision Jazz16");
296 sprintf(card->longname,
297 "Media Vision Jazz16 at 0x%lx, irq %d, dma8 %d, dma16 %d",
298 port[dev], xirq, xdma8, xdma16);
299
300 err = snd_sb8dsp_pcm(chip, 0, NULL);
301 if (err < 0)
302 goto err_free;
303 err = snd_sbmixer_new(chip);
304 if (err < 0)
305 goto err_free;
306
307 err = snd_opl3_create(card, chip->port, chip->port + 2,
308 OPL3_HW_AUTO, 1, &opl3);
309 if (err < 0)
310 snd_printk(KERN_WARNING "no OPL device at 0x%lx-0x%lx\n",
311 chip->port, chip->port + 2);
312 else {
313 err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
314 if (err < 0)
315 goto err_free;
316 }
317 if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) {
318 if (mpu_irq[dev] == SNDRV_AUTO_IRQ)
319 mpu_irq[dev] = -1;
320
321 if (snd_mpu401_uart_new(card, 0,
322 MPU401_HW_MPU401,
323 mpu_port[dev], 0,
324 mpu_irq[dev],
325 mpu_irq[dev] >= 0 ? IRQF_DISABLED : 0,
326 NULL) < 0)
327 snd_printk(KERN_ERR "no MPU-401 device at 0x%lx\n",
328 mpu_port[dev]);
329 }
330
331 snd_card_set_dev(card, devptr);
332
333 err = snd_card_register(card);
334 if (err < 0)
335 goto err_free;
336
337 dev_set_drvdata(devptr, card);
338 return 0;
339
340err_free:
341 snd_card_free(card);
342 return err;
343}
344
345static int __devexit snd_jazz16_remove(struct device *devptr, unsigned int dev)
346{
347 struct snd_card *card = dev_get_drvdata(devptr);
348
349 dev_set_drvdata(devptr, NULL);
350 snd_card_free(card);
351 return 0;
352}
353
354#ifdef CONFIG_PM
355static int snd_jazz16_suspend(struct device *pdev, unsigned int n,
356 pm_message_t state)
357{
358 struct snd_card *card = dev_get_drvdata(pdev);
359 struct snd_card_jazz16 *acard = card->private_data;
360 struct snd_sb *chip = acard->chip;
361
362 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
363 snd_pcm_suspend_all(chip->pcm);
364 snd_sbmixer_suspend(chip);
365 return 0;
366}
367
368static int snd_jazz16_resume(struct device *pdev, unsigned int n)
369{
370 struct snd_card *card = dev_get_drvdata(pdev);
371 struct snd_card_jazz16 *acard = card->private_data;
372 struct snd_sb *chip = acard->chip;
373
374 snd_sbdsp_reset(chip);
375 snd_sbmixer_resume(chip);
376 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
377 return 0;
378}
379#endif
380
381static struct isa_driver snd_jazz16_driver = {
382 .match = snd_jazz16_match,
383 .probe = snd_jazz16_probe,
384 .remove = __devexit_p(snd_jazz16_remove),
385#ifdef CONFIG_PM
386 .suspend = snd_jazz16_suspend,
387 .resume = snd_jazz16_resume,
388#endif
389 .driver = {
390 .name = "jazz16"
391 },
392};
393
394static int __init alsa_card_jazz16_init(void)
395{
396 return isa_register_driver(&snd_jazz16_driver, SNDRV_CARDS);
397}
398
399static void __exit alsa_card_jazz16_exit(void)
400{
401 isa_unregister_driver(&snd_jazz16_driver);
402}
403
404module_init(alsa_card_jazz16_init)
405module_exit(alsa_card_jazz16_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/sb/sb8_main.c b/sound/isa/sb/sb8_main.c
index 658d55769c9c..7d84c9f34dc9 100644
--- a/sound/isa/sb/sb8_main.c
+++ b/sound/isa/sb/sb8_main.c
@@ -106,9 +106,21 @@ static int snd_sb8_playback_prepare(struct snd_pcm_substream *substream)
106 struct snd_sb *chip = snd_pcm_substream_chip(substream); 106 struct snd_sb *chip = snd_pcm_substream_chip(substream);
107 struct snd_pcm_runtime *runtime = substream->runtime; 107 struct snd_pcm_runtime *runtime = substream->runtime;
108 unsigned int mixreg, rate, size, count; 108 unsigned int mixreg, rate, size, count;
109 unsigned char format;
110 unsigned char stereo = runtime->channels > 1;
111 int dma;
109 112
110 rate = runtime->rate; 113 rate = runtime->rate;
111 switch (chip->hardware) { 114 switch (chip->hardware) {
115 case SB_HW_JAZZ16:
116 if (runtime->format == SNDRV_PCM_FORMAT_S16_LE) {
117 if (chip->mode & SB_MODE_CAPTURE_16)
118 return -EBUSY;
119 else
120 chip->mode |= SB_MODE_PLAYBACK_16;
121 }
122 chip->playback_format = SB_DSP_LO_OUTPUT_AUTO;
123 break;
112 case SB_HW_PRO: 124 case SB_HW_PRO:
113 if (runtime->channels > 1) { 125 if (runtime->channels > 1) {
114 if (snd_BUG_ON(rate != SB8_RATE(11025) && 126 if (snd_BUG_ON(rate != SB8_RATE(11025) &&
@@ -133,11 +145,21 @@ static int snd_sb8_playback_prepare(struct snd_pcm_substream *substream)
133 default: 145 default:
134 return -EINVAL; 146 return -EINVAL;
135 } 147 }
148 if (chip->mode & SB_MODE_PLAYBACK_16) {
149 format = stereo ? SB_DSP_STEREO_16BIT : SB_DSP_MONO_16BIT;
150 dma = chip->dma16;
151 } else {
152 format = stereo ? SB_DSP_STEREO_8BIT : SB_DSP_MONO_8BIT;
153 chip->mode |= SB_MODE_PLAYBACK_8;
154 dma = chip->dma8;
155 }
136 size = chip->p_dma_size = snd_pcm_lib_buffer_bytes(substream); 156 size = chip->p_dma_size = snd_pcm_lib_buffer_bytes(substream);
137 count = chip->p_period_size = snd_pcm_lib_period_bytes(substream); 157 count = chip->p_period_size = snd_pcm_lib_period_bytes(substream);
138 spin_lock_irqsave(&chip->reg_lock, flags); 158 spin_lock_irqsave(&chip->reg_lock, flags);
139 snd_sbdsp_command(chip, SB_DSP_SPEAKER_ON); 159 snd_sbdsp_command(chip, SB_DSP_SPEAKER_ON);
140 if (runtime->channels > 1) { 160 if (chip->hardware == SB_HW_JAZZ16)
161 snd_sbdsp_command(chip, format);
162 else if (stereo) {
141 /* set playback stereo mode */ 163 /* set playback stereo mode */
142 spin_lock(&chip->mixer_lock); 164 spin_lock(&chip->mixer_lock);
143 mixreg = snd_sbmixer_read(chip, SB_DSP_STEREO_SW); 165 mixreg = snd_sbmixer_read(chip, SB_DSP_STEREO_SW);
@@ -147,15 +169,14 @@ static int snd_sb8_playback_prepare(struct snd_pcm_substream *substream)
147 /* Soundblaster hardware programming reference guide, 3-23 */ 169 /* Soundblaster hardware programming reference guide, 3-23 */
148 snd_sbdsp_command(chip, SB_DSP_DMA8_EXIT); 170 snd_sbdsp_command(chip, SB_DSP_DMA8_EXIT);
149 runtime->dma_area[0] = 0x80; 171 runtime->dma_area[0] = 0x80;
150 snd_dma_program(chip->dma8, runtime->dma_addr, 1, DMA_MODE_WRITE); 172 snd_dma_program(dma, runtime->dma_addr, 1, DMA_MODE_WRITE);
151 /* force interrupt */ 173 /* force interrupt */
152 chip->mode = SB_MODE_HALT;
153 snd_sbdsp_command(chip, SB_DSP_OUTPUT); 174 snd_sbdsp_command(chip, SB_DSP_OUTPUT);
154 snd_sbdsp_command(chip, 0); 175 snd_sbdsp_command(chip, 0);
155 snd_sbdsp_command(chip, 0); 176 snd_sbdsp_command(chip, 0);
156 } 177 }
157 snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE); 178 snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE);
158 if (runtime->channels > 1) { 179 if (stereo) {
159 snd_sbdsp_command(chip, 256 - runtime->rate_den / 2); 180 snd_sbdsp_command(chip, 256 - runtime->rate_den / 2);
160 spin_lock(&chip->mixer_lock); 181 spin_lock(&chip->mixer_lock);
161 /* save output filter status and turn it off */ 182 /* save output filter status and turn it off */
@@ -168,13 +189,15 @@ static int snd_sb8_playback_prepare(struct snd_pcm_substream *substream)
168 snd_sbdsp_command(chip, 256 - runtime->rate_den); 189 snd_sbdsp_command(chip, 256 - runtime->rate_den);
169 } 190 }
170 if (chip->playback_format != SB_DSP_OUTPUT) { 191 if (chip->playback_format != SB_DSP_OUTPUT) {
192 if (chip->mode & SB_MODE_PLAYBACK_16)
193 count /= 2;
171 count--; 194 count--;
172 snd_sbdsp_command(chip, SB_DSP_BLOCK_SIZE); 195 snd_sbdsp_command(chip, SB_DSP_BLOCK_SIZE);
173 snd_sbdsp_command(chip, count & 0xff); 196 snd_sbdsp_command(chip, count & 0xff);
174 snd_sbdsp_command(chip, count >> 8); 197 snd_sbdsp_command(chip, count >> 8);
175 } 198 }
176 spin_unlock_irqrestore(&chip->reg_lock, flags); 199 spin_unlock_irqrestore(&chip->reg_lock, flags);
177 snd_dma_program(chip->dma8, runtime->dma_addr, 200 snd_dma_program(dma, runtime->dma_addr,
178 size, DMA_MODE_WRITE | DMA_AUTOINIT); 201 size, DMA_MODE_WRITE | DMA_AUTOINIT);
179 return 0; 202 return 0;
180} 203}
@@ -212,7 +235,6 @@ static int snd_sb8_playback_trigger(struct snd_pcm_substream *substream,
212 snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF); 235 snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF);
213 } 236 }
214 spin_unlock_irqrestore(&chip->reg_lock, flags); 237 spin_unlock_irqrestore(&chip->reg_lock, flags);
215 chip->mode = (cmd == SNDRV_PCM_TRIGGER_START) ? SB_MODE_PLAYBACK_8 : SB_MODE_HALT;
216 return 0; 238 return 0;
217} 239}
218 240
@@ -234,9 +256,21 @@ static int snd_sb8_capture_prepare(struct snd_pcm_substream *substream)
234 struct snd_sb *chip = snd_pcm_substream_chip(substream); 256 struct snd_sb *chip = snd_pcm_substream_chip(substream);
235 struct snd_pcm_runtime *runtime = substream->runtime; 257 struct snd_pcm_runtime *runtime = substream->runtime;
236 unsigned int mixreg, rate, size, count; 258 unsigned int mixreg, rate, size, count;
259 unsigned char format;
260 unsigned char stereo = runtime->channels > 1;
261 int dma;
237 262
238 rate = runtime->rate; 263 rate = runtime->rate;
239 switch (chip->hardware) { 264 switch (chip->hardware) {
265 case SB_HW_JAZZ16:
266 if (runtime->format == SNDRV_PCM_FORMAT_S16_LE) {
267 if (chip->mode & SB_MODE_PLAYBACK_16)
268 return -EBUSY;
269 else
270 chip->mode |= SB_MODE_CAPTURE_16;
271 }
272 chip->capture_format = SB_DSP_LO_INPUT_AUTO;
273 break;
240 case SB_HW_PRO: 274 case SB_HW_PRO:
241 if (runtime->channels > 1) { 275 if (runtime->channels > 1) {
242 if (snd_BUG_ON(rate != SB8_RATE(11025) && 276 if (snd_BUG_ON(rate != SB8_RATE(11025) &&
@@ -262,14 +296,24 @@ static int snd_sb8_capture_prepare(struct snd_pcm_substream *substream)
262 default: 296 default:
263 return -EINVAL; 297 return -EINVAL;
264 } 298 }
299 if (chip->mode & SB_MODE_CAPTURE_16) {
300 format = stereo ? SB_DSP_STEREO_16BIT : SB_DSP_MONO_16BIT;
301 dma = chip->dma16;
302 } else {
303 format = stereo ? SB_DSP_STEREO_8BIT : SB_DSP_MONO_8BIT;
304 chip->mode |= SB_MODE_CAPTURE_8;
305 dma = chip->dma8;
306 }
265 size = chip->c_dma_size = snd_pcm_lib_buffer_bytes(substream); 307 size = chip->c_dma_size = snd_pcm_lib_buffer_bytes(substream);
266 count = chip->c_period_size = snd_pcm_lib_period_bytes(substream); 308 count = chip->c_period_size = snd_pcm_lib_period_bytes(substream);
267 spin_lock_irqsave(&chip->reg_lock, flags); 309 spin_lock_irqsave(&chip->reg_lock, flags);
268 snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF); 310 snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF);
269 if (runtime->channels > 1) 311 if (chip->hardware == SB_HW_JAZZ16)
312 snd_sbdsp_command(chip, format);
313 else if (stereo)
270 snd_sbdsp_command(chip, SB_DSP_STEREO_8BIT); 314 snd_sbdsp_command(chip, SB_DSP_STEREO_8BIT);
271 snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE); 315 snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE);
272 if (runtime->channels > 1) { 316 if (stereo) {
273 snd_sbdsp_command(chip, 256 - runtime->rate_den / 2); 317 snd_sbdsp_command(chip, 256 - runtime->rate_den / 2);
274 spin_lock(&chip->mixer_lock); 318 spin_lock(&chip->mixer_lock);
275 /* save input filter status and turn it off */ 319 /* save input filter status and turn it off */
@@ -282,13 +326,15 @@ static int snd_sb8_capture_prepare(struct snd_pcm_substream *substream)
282 snd_sbdsp_command(chip, 256 - runtime->rate_den); 326 snd_sbdsp_command(chip, 256 - runtime->rate_den);
283 } 327 }
284 if (chip->capture_format != SB_DSP_INPUT) { 328 if (chip->capture_format != SB_DSP_INPUT) {
329 if (chip->mode & SB_MODE_PLAYBACK_16)
330 count /= 2;
285 count--; 331 count--;
286 snd_sbdsp_command(chip, SB_DSP_BLOCK_SIZE); 332 snd_sbdsp_command(chip, SB_DSP_BLOCK_SIZE);
287 snd_sbdsp_command(chip, count & 0xff); 333 snd_sbdsp_command(chip, count & 0xff);
288 snd_sbdsp_command(chip, count >> 8); 334 snd_sbdsp_command(chip, count >> 8);
289 } 335 }
290 spin_unlock_irqrestore(&chip->reg_lock, flags); 336 spin_unlock_irqrestore(&chip->reg_lock, flags);
291 snd_dma_program(chip->dma8, runtime->dma_addr, 337 snd_dma_program(dma, runtime->dma_addr,
292 size, DMA_MODE_READ | DMA_AUTOINIT); 338 size, DMA_MODE_READ | DMA_AUTOINIT);
293 return 0; 339 return 0;
294} 340}
@@ -328,7 +374,6 @@ static int snd_sb8_capture_trigger(struct snd_pcm_substream *substream,
328 snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF); 374 snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF);
329 } 375 }
330 spin_unlock_irqrestore(&chip->reg_lock, flags); 376 spin_unlock_irqrestore(&chip->reg_lock, flags);
331 chip->mode = (cmd == SNDRV_PCM_TRIGGER_START) ? SB_MODE_CAPTURE_8 : SB_MODE_HALT;
332 return 0; 377 return 0;
333} 378}
334 379
@@ -339,13 +384,21 @@ irqreturn_t snd_sb8dsp_interrupt(struct snd_sb *chip)
339 384
340 snd_sb_ack_8bit(chip); 385 snd_sb_ack_8bit(chip);
341 switch (chip->mode) { 386 switch (chip->mode) {
342 case SB_MODE_PLAYBACK_8: /* ok.. playback is active */ 387 case SB_MODE_PLAYBACK_16: /* ok.. playback is active */
388 if (chip->hardware != SB_HW_JAZZ16)
389 break;
390 /* fallthru */
391 case SB_MODE_PLAYBACK_8:
343 substream = chip->playback_substream; 392 substream = chip->playback_substream;
344 runtime = substream->runtime; 393 runtime = substream->runtime;
345 if (chip->playback_format == SB_DSP_OUTPUT) 394 if (chip->playback_format == SB_DSP_OUTPUT)
346 snd_sb8_playback_trigger(substream, SNDRV_PCM_TRIGGER_START); 395 snd_sb8_playback_trigger(substream, SNDRV_PCM_TRIGGER_START);
347 snd_pcm_period_elapsed(substream); 396 snd_pcm_period_elapsed(substream);
348 break; 397 break;
398 case SB_MODE_CAPTURE_16:
399 if (chip->hardware != SB_HW_JAZZ16)
400 break;
401 /* fallthru */
349 case SB_MODE_CAPTURE_8: 402 case SB_MODE_CAPTURE_8:
350 substream = chip->capture_substream; 403 substream = chip->capture_substream;
351 runtime = substream->runtime; 404 runtime = substream->runtime;
@@ -361,10 +414,15 @@ static snd_pcm_uframes_t snd_sb8_playback_pointer(struct snd_pcm_substream *subs
361{ 414{
362 struct snd_sb *chip = snd_pcm_substream_chip(substream); 415 struct snd_sb *chip = snd_pcm_substream_chip(substream);
363 size_t ptr; 416 size_t ptr;
417 int dma;
364 418
365 if (chip->mode != SB_MODE_PLAYBACK_8) 419 if (chip->mode & SB_MODE_PLAYBACK_8)
420 dma = chip->dma8;
421 else if (chip->mode & SB_MODE_PLAYBACK_16)
422 dma = chip->dma16;
423 else
366 return 0; 424 return 0;
367 ptr = snd_dma_pointer(chip->dma8, chip->p_dma_size); 425 ptr = snd_dma_pointer(dma, chip->p_dma_size);
368 return bytes_to_frames(substream->runtime, ptr); 426 return bytes_to_frames(substream->runtime, ptr);
369} 427}
370 428
@@ -372,10 +430,15 @@ static snd_pcm_uframes_t snd_sb8_capture_pointer(struct snd_pcm_substream *subst
372{ 430{
373 struct snd_sb *chip = snd_pcm_substream_chip(substream); 431 struct snd_sb *chip = snd_pcm_substream_chip(substream);
374 size_t ptr; 432 size_t ptr;
433 int dma;
375 434
376 if (chip->mode != SB_MODE_CAPTURE_8) 435 if (chip->mode & SB_MODE_CAPTURE_8)
436 dma = chip->dma8;
437 else if (chip->mode & SB_MODE_CAPTURE_16)
438 dma = chip->dma16;
439 else
377 return 0; 440 return 0;
378 ptr = snd_dma_pointer(chip->dma8, chip->c_dma_size); 441 ptr = snd_dma_pointer(dma, chip->c_dma_size);
379 return bytes_to_frames(substream->runtime, ptr); 442 return bytes_to_frames(substream->runtime, ptr);
380} 443}
381 444
@@ -446,6 +509,14 @@ static int snd_sb8_open(struct snd_pcm_substream *substream)
446 runtime->hw = snd_sb8_capture; 509 runtime->hw = snd_sb8_capture;
447 } 510 }
448 switch (chip->hardware) { 511 switch (chip->hardware) {
512 case SB_HW_JAZZ16:
513 if (chip->dma16 == 5 || chip->dma16 == 7)
514 runtime->hw.formats |= SNDRV_PCM_FMTBIT_S16_LE;
515 runtime->hw.rates |= SNDRV_PCM_RATE_8000_48000;
516 runtime->hw.rate_min = 4000;
517 runtime->hw.rate_max = 50000;
518 runtime->hw.channels_max = 2;
519 break;
449 case SB_HW_PRO: 520 case SB_HW_PRO:
450 runtime->hw.rate_max = 44100; 521 runtime->hw.rate_max = 44100;
451 runtime->hw.channels_max = 2; 522 runtime->hw.channels_max = 2;
@@ -468,6 +539,14 @@ static int snd_sb8_open(struct snd_pcm_substream *substream)
468 } 539 }
469 snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 540 snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
470 &hw_constraints_clock); 541 &hw_constraints_clock);
542 if (chip->dma8 > 3 || chip->dma16 >= 0) {
543 snd_pcm_hw_constraint_step(runtime, 0,
544 SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 2);
545 snd_pcm_hw_constraint_step(runtime, 0,
546 SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 2);
547 runtime->hw.buffer_bytes_max = 128 * 1024 * 1024;
548 runtime->hw.period_bytes_max = 128 * 1024 * 1024;
549 }
471 return 0; 550 return 0;
472} 551}
473 552
@@ -480,6 +559,10 @@ static int snd_sb8_close(struct snd_pcm_substream *substream)
480 chip->capture_substream = NULL; 559 chip->capture_substream = NULL;
481 spin_lock_irqsave(&chip->open_lock, flags); 560 spin_lock_irqsave(&chip->open_lock, flags);
482 chip->open &= ~SB_OPEN_PCM; 561 chip->open &= ~SB_OPEN_PCM;
562 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
563 chip->mode &= ~SB_MODE_PLAYBACK;
564 else
565 chip->mode &= ~SB_MODE_CAPTURE;
483 spin_unlock_irqrestore(&chip->open_lock, flags); 566 spin_unlock_irqrestore(&chip->open_lock, flags);
484 return 0; 567 return 0;
485} 568}
@@ -515,6 +598,7 @@ int snd_sb8dsp_pcm(struct snd_sb *chip, int device, struct snd_pcm ** rpcm)
515 struct snd_card *card = chip->card; 598 struct snd_card *card = chip->card;
516 struct snd_pcm *pcm; 599 struct snd_pcm *pcm;
517 int err; 600 int err;
601 size_t max_prealloc = 64 * 1024;
518 602
519 if (rpcm) 603 if (rpcm)
520 *rpcm = NULL; 604 *rpcm = NULL;
@@ -527,9 +611,11 @@ int snd_sb8dsp_pcm(struct snd_sb *chip, int device, struct snd_pcm ** rpcm)
527 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_sb8_playback_ops); 611 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_sb8_playback_ops);
528 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_sb8_capture_ops); 612 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_sb8_capture_ops);
529 613
614 if (chip->dma8 > 3 || chip->dma16 >= 0)
615 max_prealloc = 128 * 1024;
530 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, 616 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
531 snd_dma_isa_data(), 617 snd_dma_isa_data(),
532 64*1024, 64*1024); 618 64*1024, max_prealloc);
533 619
534 if (rpcm) 620 if (rpcm)
535 *rpcm = pcm; 621 *rpcm = pcm;
diff --git a/sound/isa/sb/sb_common.c b/sound/isa/sb/sb_common.c
index 27a651502251..eae6c1c0eff9 100644
--- a/sound/isa/sb/sb_common.c
+++ b/sound/isa/sb/sb_common.c
@@ -170,6 +170,9 @@ static int snd_sbdsp_probe(struct snd_sb * chip)
170 case SB_HW_CS5530: 170 case SB_HW_CS5530:
171 str = "16 (CS5530)"; 171 str = "16 (CS5530)";
172 break; 172 break;
173 case SB_HW_JAZZ16:
174 str = "Pro (Jazz16)";
175 break;
173 default: 176 default:
174 return -ENODEV; 177 return -ENODEV;
175 } 178 }
diff --git a/sound/isa/sb/sb_mixer.c b/sound/isa/sb/sb_mixer.c
index 475220bbcc96..6496822c1808 100644
--- a/sound/isa/sb/sb_mixer.c
+++ b/sound/isa/sb/sb_mixer.c
@@ -528,20 +528,11 @@ int snd_sbmixer_add_ctl(struct snd_sb *chip, const char *name, int index, int ty
528 * SB 2.0 specific mixer elements 528 * SB 2.0 specific mixer elements
529 */ 529 */
530 530
531static struct sbmix_elem snd_sb20_ctl_master_play_vol = 531static struct sbmix_elem snd_sb20_controls[] = {
532 SB_SINGLE("Master Playback Volume", SB_DSP20_MASTER_DEV, 1, 7); 532 SB_SINGLE("Master Playback Volume", SB_DSP20_MASTER_DEV, 1, 7),
533static struct sbmix_elem snd_sb20_ctl_pcm_play_vol = 533 SB_SINGLE("PCM Playback Volume", SB_DSP20_PCM_DEV, 1, 3),
534 SB_SINGLE("PCM Playback Volume", SB_DSP20_PCM_DEV, 1, 3); 534 SB_SINGLE("Synth Playback Volume", SB_DSP20_FM_DEV, 1, 7),
535static struct sbmix_elem snd_sb20_ctl_synth_play_vol = 535 SB_SINGLE("CD Playback Volume", SB_DSP20_CD_DEV, 1, 7)
536 SB_SINGLE("Synth Playback Volume", SB_DSP20_FM_DEV, 1, 7);
537static struct sbmix_elem snd_sb20_ctl_cd_play_vol =
538 SB_SINGLE("CD Playback Volume", SB_DSP20_CD_DEV, 1, 7);
539
540static struct sbmix_elem *snd_sb20_controls[] = {
541 &snd_sb20_ctl_master_play_vol,
542 &snd_sb20_ctl_pcm_play_vol,
543 &snd_sb20_ctl_synth_play_vol,
544 &snd_sb20_ctl_cd_play_vol
545}; 536};
546 537
547static unsigned char snd_sb20_init_values[][2] = { 538static unsigned char snd_sb20_init_values[][2] = {
@@ -552,41 +543,24 @@ static unsigned char snd_sb20_init_values[][2] = {
552/* 543/*
553 * SB Pro specific mixer elements 544 * SB Pro specific mixer elements
554 */ 545 */
555static struct sbmix_elem snd_sbpro_ctl_master_play_vol = 546static struct sbmix_elem snd_sbpro_controls[] = {
556 SB_DOUBLE("Master Playback Volume", SB_DSP_MASTER_DEV, SB_DSP_MASTER_DEV, 5, 1, 7); 547 SB_DOUBLE("Master Playback Volume",
557static struct sbmix_elem snd_sbpro_ctl_pcm_play_vol = 548 SB_DSP_MASTER_DEV, SB_DSP_MASTER_DEV, 5, 1, 7),
558 SB_DOUBLE("PCM Playback Volume", SB_DSP_PCM_DEV, SB_DSP_PCM_DEV, 5, 1, 7); 549 SB_DOUBLE("PCM Playback Volume",
559static struct sbmix_elem snd_sbpro_ctl_pcm_play_filter = 550 SB_DSP_PCM_DEV, SB_DSP_PCM_DEV, 5, 1, 7),
560 SB_SINGLE("PCM Playback Filter", SB_DSP_PLAYBACK_FILT, 5, 1); 551 SB_SINGLE("PCM Playback Filter", SB_DSP_PLAYBACK_FILT, 5, 1),
561static struct sbmix_elem snd_sbpro_ctl_synth_play_vol = 552 SB_DOUBLE("Synth Playback Volume",
562 SB_DOUBLE("Synth Playback Volume", SB_DSP_FM_DEV, SB_DSP_FM_DEV, 5, 1, 7); 553 SB_DSP_FM_DEV, SB_DSP_FM_DEV, 5, 1, 7),
563static struct sbmix_elem snd_sbpro_ctl_cd_play_vol = 554 SB_DOUBLE("CD Playback Volume", SB_DSP_CD_DEV, SB_DSP_CD_DEV, 5, 1, 7),
564 SB_DOUBLE("CD Playback Volume", SB_DSP_CD_DEV, SB_DSP_CD_DEV, 5, 1, 7); 555 SB_DOUBLE("Line Playback Volume",
565static struct sbmix_elem snd_sbpro_ctl_line_play_vol = 556 SB_DSP_LINE_DEV, SB_DSP_LINE_DEV, 5, 1, 7),
566 SB_DOUBLE("Line Playback Volume", SB_DSP_LINE_DEV, SB_DSP_LINE_DEV, 5, 1, 7); 557 SB_SINGLE("Mic Playback Volume", SB_DSP_MIC_DEV, 1, 3),
567static struct sbmix_elem snd_sbpro_ctl_mic_play_vol =
568 SB_SINGLE("Mic Playback Volume", SB_DSP_MIC_DEV, 1, 3);
569static struct sbmix_elem snd_sbpro_ctl_capture_source =
570 { 558 {
571 .name = "Capture Source", 559 .name = "Capture Source",
572 .type = SB_MIX_CAPTURE_PRO 560 .type = SB_MIX_CAPTURE_PRO
573 }; 561 },
574static struct sbmix_elem snd_sbpro_ctl_capture_filter = 562 SB_SINGLE("Capture Filter", SB_DSP_CAPTURE_FILT, 5, 1),
575 SB_SINGLE("Capture Filter", SB_DSP_CAPTURE_FILT, 5, 1); 563 SB_SINGLE("Capture Low-Pass Filter", SB_DSP_CAPTURE_FILT, 3, 1)
576static struct sbmix_elem snd_sbpro_ctl_capture_low_filter =
577 SB_SINGLE("Capture Low-Pass Filter", SB_DSP_CAPTURE_FILT, 3, 1);
578
579static struct sbmix_elem *snd_sbpro_controls[] = {
580 &snd_sbpro_ctl_master_play_vol,
581 &snd_sbpro_ctl_pcm_play_vol,
582 &snd_sbpro_ctl_pcm_play_filter,
583 &snd_sbpro_ctl_synth_play_vol,
584 &snd_sbpro_ctl_cd_play_vol,
585 &snd_sbpro_ctl_line_play_vol,
586 &snd_sbpro_ctl_mic_play_vol,
587 &snd_sbpro_ctl_capture_source,
588 &snd_sbpro_ctl_capture_filter,
589 &snd_sbpro_ctl_capture_low_filter
590}; 564};
591 565
592static unsigned char snd_sbpro_init_values[][2] = { 566static unsigned char snd_sbpro_init_values[][2] = {
@@ -598,68 +572,42 @@ static unsigned char snd_sbpro_init_values[][2] = {
598/* 572/*
599 * SB16 specific mixer elements 573 * SB16 specific mixer elements
600 */ 574 */
601static struct sbmix_elem snd_sb16_ctl_master_play_vol = 575static struct sbmix_elem snd_sb16_controls[] = {
602 SB_DOUBLE("Master Playback Volume", SB_DSP4_MASTER_DEV, (SB_DSP4_MASTER_DEV + 1), 3, 3, 31); 576 SB_DOUBLE("Master Playback Volume",
603static struct sbmix_elem snd_sb16_ctl_3d_enhance_switch = 577 SB_DSP4_MASTER_DEV, (SB_DSP4_MASTER_DEV + 1), 3, 3, 31),
604 SB_SINGLE("3D Enhancement Switch", SB_DSP4_3DSE, 0, 1); 578 SB_DOUBLE("PCM Playback Volume",
605static struct sbmix_elem snd_sb16_ctl_tone_bass = 579 SB_DSP4_PCM_DEV, (SB_DSP4_PCM_DEV + 1), 3, 3, 31),
606 SB_DOUBLE("Tone Control - Bass", SB_DSP4_BASS_DEV, (SB_DSP4_BASS_DEV + 1), 4, 4, 15); 580 SB16_INPUT_SW("Synth Capture Route",
607static struct sbmix_elem snd_sb16_ctl_tone_treble = 581 SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 6, 5),
608 SB_DOUBLE("Tone Control - Treble", SB_DSP4_TREBLE_DEV, (SB_DSP4_TREBLE_DEV + 1), 4, 4, 15); 582 SB_DOUBLE("Synth Playback Volume",
609static struct sbmix_elem snd_sb16_ctl_pcm_play_vol = 583 SB_DSP4_SYNTH_DEV, (SB_DSP4_SYNTH_DEV + 1), 3, 3, 31),
610 SB_DOUBLE("PCM Playback Volume", SB_DSP4_PCM_DEV, (SB_DSP4_PCM_DEV + 1), 3, 3, 31); 584 SB16_INPUT_SW("CD Capture Route",
611static struct sbmix_elem snd_sb16_ctl_synth_capture_route = 585 SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 2, 1),
612 SB16_INPUT_SW("Synth Capture Route", SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 6, 5); 586 SB_DOUBLE("CD Playback Switch",
613static struct sbmix_elem snd_sb16_ctl_synth_play_vol = 587 SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 2, 1, 1),
614 SB_DOUBLE("Synth Playback Volume", SB_DSP4_SYNTH_DEV, (SB_DSP4_SYNTH_DEV + 1), 3, 3, 31); 588 SB_DOUBLE("CD Playback Volume",
615static struct sbmix_elem snd_sb16_ctl_cd_capture_route = 589 SB_DSP4_CD_DEV, (SB_DSP4_CD_DEV + 1), 3, 3, 31),
616 SB16_INPUT_SW("CD Capture Route", SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 2, 1); 590 SB16_INPUT_SW("Mic Capture Route",
617static struct sbmix_elem snd_sb16_ctl_cd_play_switch = 591 SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 0, 0),
618 SB_DOUBLE("CD Playback Switch", SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 2, 1, 1); 592 SB_SINGLE("Mic Playback Switch", SB_DSP4_OUTPUT_SW, 0, 1),
619static struct sbmix_elem snd_sb16_ctl_cd_play_vol = 593 SB_SINGLE("Mic Playback Volume", SB_DSP4_MIC_DEV, 3, 31),
620 SB_DOUBLE("CD Playback Volume", SB_DSP4_CD_DEV, (SB_DSP4_CD_DEV + 1), 3, 3, 31); 594 SB_SINGLE("Beep Volume", SB_DSP4_SPEAKER_DEV, 6, 3),
621static struct sbmix_elem snd_sb16_ctl_line_capture_route = 595 SB_DOUBLE("Capture Volume",
622 SB16_INPUT_SW("Line Capture Route", SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 4, 3); 596 SB_DSP4_IGAIN_DEV, (SB_DSP4_IGAIN_DEV + 1), 6, 6, 3),
623static struct sbmix_elem snd_sb16_ctl_line_play_switch = 597 SB_DOUBLE("Playback Volume",
624 SB_DOUBLE("Line Playback Switch", SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 4, 3, 1); 598 SB_DSP4_OGAIN_DEV, (SB_DSP4_OGAIN_DEV + 1), 6, 6, 3),
625static struct sbmix_elem snd_sb16_ctl_line_play_vol = 599 SB16_INPUT_SW("Line Capture Route",
626 SB_DOUBLE("Line Playback Volume", SB_DSP4_LINE_DEV, (SB_DSP4_LINE_DEV + 1), 3, 3, 31); 600 SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 4, 3),
627static struct sbmix_elem snd_sb16_ctl_mic_capture_route = 601 SB_DOUBLE("Line Playback Switch",
628 SB16_INPUT_SW("Mic Capture Route", SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 0, 0); 602 SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 4, 3, 1),
629static struct sbmix_elem snd_sb16_ctl_mic_play_switch = 603 SB_DOUBLE("Line Playback Volume",
630 SB_SINGLE("Mic Playback Switch", SB_DSP4_OUTPUT_SW, 0, 1); 604 SB_DSP4_LINE_DEV, (SB_DSP4_LINE_DEV + 1), 3, 3, 31),
631static struct sbmix_elem snd_sb16_ctl_mic_play_vol = 605 SB_SINGLE("Mic Auto Gain", SB_DSP4_MIC_AGC, 0, 1),
632 SB_SINGLE("Mic Playback Volume", SB_DSP4_MIC_DEV, 3, 31); 606 SB_SINGLE("3D Enhancement Switch", SB_DSP4_3DSE, 0, 1),
633static struct sbmix_elem snd_sb16_ctl_pc_speaker_vol = 607 SB_DOUBLE("Tone Control - Bass",
634 SB_SINGLE("PC Speaker Volume", SB_DSP4_SPEAKER_DEV, 6, 3); 608 SB_DSP4_BASS_DEV, (SB_DSP4_BASS_DEV + 1), 4, 4, 15),
635static struct sbmix_elem snd_sb16_ctl_capture_vol = 609 SB_DOUBLE("Tone Control - Treble",
636 SB_DOUBLE("Capture Volume", SB_DSP4_IGAIN_DEV, (SB_DSP4_IGAIN_DEV + 1), 6, 6, 3); 610 SB_DSP4_TREBLE_DEV, (SB_DSP4_TREBLE_DEV + 1), 4, 4, 15)
637static struct sbmix_elem snd_sb16_ctl_play_vol =
638 SB_DOUBLE("Playback Volume", SB_DSP4_OGAIN_DEV, (SB_DSP4_OGAIN_DEV + 1), 6, 6, 3);
639static struct sbmix_elem snd_sb16_ctl_auto_mic_gain =
640 SB_SINGLE("Mic Auto Gain", SB_DSP4_MIC_AGC, 0, 1);
641
642static struct sbmix_elem *snd_sb16_controls[] = {
643 &snd_sb16_ctl_master_play_vol,
644 &snd_sb16_ctl_3d_enhance_switch,
645 &snd_sb16_ctl_tone_bass,
646 &snd_sb16_ctl_tone_treble,
647 &snd_sb16_ctl_pcm_play_vol,
648 &snd_sb16_ctl_synth_capture_route,
649 &snd_sb16_ctl_synth_play_vol,
650 &snd_sb16_ctl_cd_capture_route,
651 &snd_sb16_ctl_cd_play_switch,
652 &snd_sb16_ctl_cd_play_vol,
653 &snd_sb16_ctl_line_capture_route,
654 &snd_sb16_ctl_line_play_switch,
655 &snd_sb16_ctl_line_play_vol,
656 &snd_sb16_ctl_mic_capture_route,
657 &snd_sb16_ctl_mic_play_switch,
658 &snd_sb16_ctl_mic_play_vol,
659 &snd_sb16_ctl_pc_speaker_vol,
660 &snd_sb16_ctl_capture_vol,
661 &snd_sb16_ctl_play_vol,
662 &snd_sb16_ctl_auto_mic_gain
663}; 611};
664 612
665static unsigned char snd_sb16_init_values[][2] = { 613static unsigned char snd_sb16_init_values[][2] = {
@@ -678,46 +626,34 @@ static unsigned char snd_sb16_init_values[][2] = {
678/* 626/*
679 * DT019x specific mixer elements 627 * DT019x specific mixer elements
680 */ 628 */
681static struct sbmix_elem snd_dt019x_ctl_master_play_vol = 629static struct sbmix_elem snd_dt019x_controls[] = {
682 SB_DOUBLE("Master Playback Volume", SB_DT019X_MASTER_DEV, SB_DT019X_MASTER_DEV, 4,0, 15); 630 /* ALS4000 below has some parts which we might be lacking,
683static struct sbmix_elem snd_dt019x_ctl_pcm_play_vol = 631 * e.g. snd_als4000_ctl_mono_playback_switch - check it! */
684 SB_DOUBLE("PCM Playback Volume", SB_DT019X_PCM_DEV, SB_DT019X_PCM_DEV, 4,0, 15); 632 SB_DOUBLE("Master Playback Volume",
685static struct sbmix_elem snd_dt019x_ctl_synth_play_vol = 633 SB_DT019X_MASTER_DEV, SB_DT019X_MASTER_DEV, 4, 0, 15),
686 SB_DOUBLE("Synth Playback Volume", SB_DT019X_SYNTH_DEV, SB_DT019X_SYNTH_DEV, 4,0, 15); 634 SB_DOUBLE("PCM Playback Switch",
687static struct sbmix_elem snd_dt019x_ctl_cd_play_vol = 635 SB_DT019X_OUTPUT_SW2, SB_DT019X_OUTPUT_SW2, 2, 1, 1),
688 SB_DOUBLE("CD Playback Volume", SB_DT019X_CD_DEV, SB_DT019X_CD_DEV, 4,0, 15); 636 SB_DOUBLE("PCM Playback Volume",
689static struct sbmix_elem snd_dt019x_ctl_mic_play_vol = 637 SB_DT019X_PCM_DEV, SB_DT019X_PCM_DEV, 4, 0, 15),
690 SB_SINGLE("Mic Playback Volume", SB_DT019X_MIC_DEV, 4, 7); 638 SB_DOUBLE("Synth Playback Switch",
691static struct sbmix_elem snd_dt019x_ctl_pc_speaker_vol = 639 SB_DT019X_OUTPUT_SW2, SB_DT019X_OUTPUT_SW2, 4, 3, 1),
692 SB_SINGLE("PC Speaker Volume", SB_DT019X_SPKR_DEV, 0, 7); 640 SB_DOUBLE("Synth Playback Volume",
693static struct sbmix_elem snd_dt019x_ctl_line_play_vol = 641 SB_DT019X_SYNTH_DEV, SB_DT019X_SYNTH_DEV, 4, 0, 15),
694 SB_DOUBLE("Line Playback Volume", SB_DT019X_LINE_DEV, SB_DT019X_LINE_DEV, 4,0, 15); 642 SB_DOUBLE("CD Playback Switch",
695static struct sbmix_elem snd_dt019x_ctl_pcm_play_switch = 643 SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 2, 1, 1),
696 SB_DOUBLE("PCM Playback Switch", SB_DT019X_OUTPUT_SW2, SB_DT019X_OUTPUT_SW2, 2,1, 1); 644 SB_DOUBLE("CD Playback Volume",
697static struct sbmix_elem snd_dt019x_ctl_synth_play_switch = 645 SB_DT019X_CD_DEV, SB_DT019X_CD_DEV, 4, 0, 15),
698 SB_DOUBLE("Synth Playback Switch", SB_DT019X_OUTPUT_SW2, SB_DT019X_OUTPUT_SW2, 4,3, 1); 646 SB_SINGLE("Mic Playback Switch", SB_DSP4_OUTPUT_SW, 0, 1),
699static struct sbmix_elem snd_dt019x_ctl_capture_source = 647 SB_SINGLE("Mic Playback Volume", SB_DT019X_MIC_DEV, 4, 7),
648 SB_SINGLE("Beep Volume", SB_DT019X_SPKR_DEV, 0, 7),
649 SB_DOUBLE("Line Playback Switch",
650 SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 4, 3, 1),
651 SB_DOUBLE("Line Playback Volume",
652 SB_DT019X_LINE_DEV, SB_DT019X_LINE_DEV, 4, 0, 15),
700 { 653 {
701 .name = "Capture Source", 654 .name = "Capture Source",
702 .type = SB_MIX_CAPTURE_DT019X 655 .type = SB_MIX_CAPTURE_DT019X
703 }; 656 }
704
705static struct sbmix_elem *snd_dt019x_controls[] = {
706 /* ALS4000 below has some parts which we might be lacking,
707 * e.g. snd_als4000_ctl_mono_playback_switch - check it! */
708 &snd_dt019x_ctl_master_play_vol,
709 &snd_dt019x_ctl_pcm_play_vol,
710 &snd_dt019x_ctl_synth_play_vol,
711 &snd_dt019x_ctl_cd_play_vol,
712 &snd_dt019x_ctl_mic_play_vol,
713 &snd_dt019x_ctl_pc_speaker_vol,
714 &snd_dt019x_ctl_line_play_vol,
715 &snd_sb16_ctl_mic_play_switch,
716 &snd_sb16_ctl_cd_play_switch,
717 &snd_sb16_ctl_line_play_switch,
718 &snd_dt019x_ctl_pcm_play_switch,
719 &snd_dt019x_ctl_synth_play_switch,
720 &snd_dt019x_ctl_capture_source
721}; 657};
722 658
723static unsigned char snd_dt019x_init_values[][2] = { 659static unsigned char snd_dt019x_init_values[][2] = {
@@ -735,82 +671,37 @@ static unsigned char snd_dt019x_init_values[][2] = {
735/* 671/*
736 * ALS4000 specific mixer elements 672 * ALS4000 specific mixer elements
737 */ 673 */
738static struct sbmix_elem snd_als4000_ctl_master_mono_playback_switch = 674static struct sbmix_elem snd_als4000_controls[] = {
739 SB_SINGLE("Master Mono Playback Switch", SB_ALS4000_MONO_IO_CTRL, 5, 1); 675 SB_DOUBLE("PCM Playback Switch",
740static struct sbmix_elem snd_als4k_ctl_master_mono_capture_route = { 676 SB_DT019X_OUTPUT_SW2, SB_DT019X_OUTPUT_SW2, 2, 1, 1),
677 SB_DOUBLE("Synth Playback Switch",
678 SB_DT019X_OUTPUT_SW2, SB_DT019X_OUTPUT_SW2, 4, 3, 1),
679 SB_SINGLE("Mic Boost (+20dB)", SB_ALS4000_MIC_IN_GAIN, 0, 0x03),
680 SB_SINGLE("Master Mono Playback Switch", SB_ALS4000_MONO_IO_CTRL, 5, 1),
681 {
741 .name = "Master Mono Capture Route", 682 .name = "Master Mono Capture Route",
742 .type = SB_MIX_MONO_CAPTURE_ALS4K 683 .type = SB_MIX_MONO_CAPTURE_ALS4K
743 }; 684 },
744static struct sbmix_elem snd_als4000_ctl_mono_playback_switch = 685 SB_SINGLE("Mono Playback Switch", SB_DT019X_OUTPUT_SW2, 0, 1),
745 SB_SINGLE("Mono Playback Switch", SB_DT019X_OUTPUT_SW2, 0, 1); 686 SB_SINGLE("Analog Loopback Switch", SB_ALS4000_MIC_IN_GAIN, 7, 0x01),
746static struct sbmix_elem snd_als4000_ctl_mic_20db_boost = 687 SB_SINGLE("3D Control - Switch", SB_ALS4000_3D_SND_FX, 6, 0x01),
747 SB_SINGLE("Mic Boost (+20dB)", SB_ALS4000_MIC_IN_GAIN, 0, 0x03);
748static struct sbmix_elem snd_als4000_ctl_mixer_analog_loopback =
749 SB_SINGLE("Analog Loopback Switch", SB_ALS4000_MIC_IN_GAIN, 7, 0x01);
750static struct sbmix_elem snd_als4000_ctl_mixer_digital_loopback =
751 SB_SINGLE("Digital Loopback Switch", 688 SB_SINGLE("Digital Loopback Switch",
752 SB_ALS4000_CR3_CONFIGURATION, 7, 0x01); 689 SB_ALS4000_CR3_CONFIGURATION, 7, 0x01),
753/* FIXME: functionality of 3D controls might be swapped, I didn't find 690 /* FIXME: functionality of 3D controls might be swapped, I didn't find
754 * a description of how to identify what is supposed to be what */ 691 * a description of how to identify what is supposed to be what */
755static struct sbmix_elem snd_als4000_3d_control_switch = 692 SB_SINGLE("3D Control - Level", SB_ALS4000_3D_SND_FX, 0, 0x07),
756 SB_SINGLE("3D Control - Switch", SB_ALS4000_3D_SND_FX, 6, 0x01);
757static struct sbmix_elem snd_als4000_3d_control_ratio =
758 SB_SINGLE("3D Control - Level", SB_ALS4000_3D_SND_FX, 0, 0x07);
759static struct sbmix_elem snd_als4000_3d_control_freq =
760 /* FIXME: maybe there's actually some standard 3D ctrl name for it?? */ 693 /* FIXME: maybe there's actually some standard 3D ctrl name for it?? */
761 SB_SINGLE("3D Control - Freq", SB_ALS4000_3D_SND_FX, 4, 0x03); 694 SB_SINGLE("3D Control - Freq", SB_ALS4000_3D_SND_FX, 4, 0x03),
762static struct sbmix_elem snd_als4000_3d_control_delay =
763 /* FIXME: ALS4000a.pdf mentions BBD (Bucket Brigade Device) time delay, 695 /* FIXME: ALS4000a.pdf mentions BBD (Bucket Brigade Device) time delay,
764 * but what ALSA 3D attribute is that actually? "Center", "Depth", 696 * but what ALSA 3D attribute is that actually? "Center", "Depth",
765 * "Wide" or "Space" or even "Level"? Assuming "Wide" for now... */ 697 * "Wide" or "Space" or even "Level"? Assuming "Wide" for now... */
766 SB_SINGLE("3D Control - Wide", SB_ALS4000_3D_TIME_DELAY, 0, 0x0f); 698 SB_SINGLE("3D Control - Wide", SB_ALS4000_3D_TIME_DELAY, 0, 0x0f),
767static struct sbmix_elem snd_als4000_3d_control_poweroff_switch = 699 SB_SINGLE("3D PowerOff Switch", SB_ALS4000_3D_TIME_DELAY, 4, 0x01),
768 SB_SINGLE("3D PowerOff Switch", SB_ALS4000_3D_TIME_DELAY, 4, 0x01);
769static struct sbmix_elem snd_als4000_ctl_3db_freq_control_switch =
770 SB_SINGLE("Master Playback 8kHz / 20kHz LPF Switch", 700 SB_SINGLE("Master Playback 8kHz / 20kHz LPF Switch",
771 SB_ALS4000_FMDAC, 5, 0x01); 701 SB_ALS4000_FMDAC, 5, 0x01),
772#ifdef NOT_AVAILABLE 702#ifdef NOT_AVAILABLE
773static struct sbmix_elem snd_als4000_ctl_fmdac = 703 SB_SINGLE("FMDAC Switch (Option ?)", SB_ALS4000_FMDAC, 0, 0x01),
774 SB_SINGLE("FMDAC Switch (Option ?)", SB_ALS4000_FMDAC, 0, 0x01); 704 SB_SINGLE("QSound Mode", SB_ALS4000_QSOUND, 1, 0x1f),
775static struct sbmix_elem snd_als4000_ctl_qsound =
776 SB_SINGLE("QSound Mode", SB_ALS4000_QSOUND, 1, 0x1f);
777#endif
778
779static struct sbmix_elem *snd_als4000_controls[] = {
780 /* ALS4000a.PDF regs page */
781 &snd_sb16_ctl_master_play_vol, /* MX30/31 12 */
782 &snd_dt019x_ctl_pcm_play_switch, /* MX4C 16 */
783 &snd_sb16_ctl_pcm_play_vol, /* MX32/33 12 */
784 &snd_sb16_ctl_synth_capture_route, /* MX3D/3E 14 */
785 &snd_dt019x_ctl_synth_play_switch, /* MX4C 16 */
786 &snd_sb16_ctl_synth_play_vol, /* MX34/35 12/13 */
787 &snd_sb16_ctl_cd_capture_route, /* MX3D/3E 14 */
788 &snd_sb16_ctl_cd_play_switch, /* MX3C 14 */
789 &snd_sb16_ctl_cd_play_vol, /* MX36/37 13 */
790 &snd_sb16_ctl_line_capture_route, /* MX3D/3E 14 */
791 &snd_sb16_ctl_line_play_switch, /* MX3C 14 */
792 &snd_sb16_ctl_line_play_vol, /* MX38/39 13 */
793 &snd_sb16_ctl_mic_capture_route, /* MX3D/3E 14 */
794 &snd_als4000_ctl_mic_20db_boost, /* MX4D 16 */
795 &snd_sb16_ctl_mic_play_switch, /* MX3C 14 */
796 &snd_sb16_ctl_mic_play_vol, /* MX3A 13 */
797 &snd_sb16_ctl_pc_speaker_vol, /* MX3B 14 */
798 &snd_sb16_ctl_capture_vol, /* MX3F/40 15 */
799 &snd_sb16_ctl_play_vol, /* MX41/42 15 */
800 &snd_als4000_ctl_master_mono_playback_switch, /* MX4C 16 */
801 &snd_als4k_ctl_master_mono_capture_route, /* MX4B 16 */
802 &snd_als4000_ctl_mono_playback_switch, /* MX4C 16 */
803 &snd_als4000_ctl_mixer_analog_loopback, /* MX4D 16 */
804 &snd_als4000_ctl_mixer_digital_loopback, /* CR3 21 */
805 &snd_als4000_3d_control_switch, /* MX50 17 */
806 &snd_als4000_3d_control_ratio, /* MX50 17 */
807 &snd_als4000_3d_control_freq, /* MX50 17 */
808 &snd_als4000_3d_control_delay, /* MX51 18 */
809 &snd_als4000_3d_control_poweroff_switch, /* MX51 18 */
810 &snd_als4000_ctl_3db_freq_control_switch, /* MX4F 17 */
811#ifdef NOT_AVAILABLE
812 &snd_als4000_ctl_fmdac,
813 &snd_als4000_ctl_qsound,
814#endif 705#endif
815}; 706};
816 707
@@ -829,11 +720,10 @@ static unsigned char snd_als4000_init_values[][2] = {
829 { SB_ALS4000_MIC_IN_GAIN, 0 }, 720 { SB_ALS4000_MIC_IN_GAIN, 0 },
830}; 721};
831 722
832
833/* 723/*
834 */ 724 */
835static int snd_sbmixer_init(struct snd_sb *chip, 725static int snd_sbmixer_init(struct snd_sb *chip,
836 struct sbmix_elem **controls, 726 struct sbmix_elem *controls,
837 int controls_count, 727 int controls_count,
838 unsigned char map[][2], 728 unsigned char map[][2],
839 int map_count, 729 int map_count,
@@ -856,7 +746,8 @@ static int snd_sbmixer_init(struct snd_sb *chip,
856 } 746 }
857 747
858 for (idx = 0; idx < controls_count; idx++) { 748 for (idx = 0; idx < controls_count; idx++) {
859 if ((err = snd_sbmixer_add_ctl_elem(chip, controls[idx])) < 0) 749 err = snd_sbmixer_add_ctl_elem(chip, &controls[idx]);
750 if (err < 0)
860 return err; 751 return err;
861 } 752 }
862 snd_component_add(card, name); 753 snd_component_add(card, name);
@@ -888,6 +779,7 @@ int snd_sbmixer_new(struct snd_sb *chip)
888 return err; 779 return err;
889 break; 780 break;
890 case SB_HW_PRO: 781 case SB_HW_PRO:
782 case SB_HW_JAZZ16:
891 if ((err = snd_sbmixer_init(chip, 783 if ((err = snd_sbmixer_init(chip,
892 snd_sbpro_controls, 784 snd_sbpro_controls,
893 ARRAY_SIZE(snd_sbpro_controls), 785 ARRAY_SIZE(snd_sbpro_controls),
@@ -908,6 +800,15 @@ int snd_sbmixer_new(struct snd_sb *chip)
908 return err; 800 return err;
909 break; 801 break;
910 case SB_HW_ALS4000: 802 case SB_HW_ALS4000:
803 /* use only the first 16 controls from SB16 */
804 err = snd_sbmixer_init(chip,
805 snd_sb16_controls,
806 16,
807 snd_sb16_init_values,
808 ARRAY_SIZE(snd_sb16_init_values),
809 "ALS4000");
810 if (err < 0)
811 return err;
911 if ((err = snd_sbmixer_init(chip, 812 if ((err = snd_sbmixer_init(chip,
912 snd_als4000_controls, 813 snd_als4000_controls,
913 ARRAY_SIZE(snd_als4000_controls), 814 ARRAY_SIZE(snd_als4000_controls),
@@ -1029,6 +930,7 @@ void snd_sbmixer_suspend(struct snd_sb *chip)
1029 save_mixer(chip, sb20_saved_regs, ARRAY_SIZE(sb20_saved_regs)); 930 save_mixer(chip, sb20_saved_regs, ARRAY_SIZE(sb20_saved_regs));
1030 break; 931 break;
1031 case SB_HW_PRO: 932 case SB_HW_PRO:
933 case SB_HW_JAZZ16:
1032 save_mixer(chip, sbpro_saved_regs, ARRAY_SIZE(sbpro_saved_regs)); 934 save_mixer(chip, sbpro_saved_regs, ARRAY_SIZE(sbpro_saved_regs));
1033 break; 935 break;
1034 case SB_HW_16: 936 case SB_HW_16:
@@ -1055,6 +957,7 @@ void snd_sbmixer_resume(struct snd_sb *chip)
1055 restore_mixer(chip, sb20_saved_regs, ARRAY_SIZE(sb20_saved_regs)); 957 restore_mixer(chip, sb20_saved_regs, ARRAY_SIZE(sb20_saved_regs));
1056 break; 958 break;
1057 case SB_HW_PRO: 959 case SB_HW_PRO:
960 case SB_HW_JAZZ16:
1058 restore_mixer(chip, sbpro_saved_regs, ARRAY_SIZE(sbpro_saved_regs)); 961 restore_mixer(chip, sbpro_saved_regs, ARRAY_SIZE(sbpro_saved_regs));
1059 break; 962 break;
1060 case SB_HW_16: 963 case SB_HW_16:
diff --git a/sound/isa/sscape.c b/sound/isa/sscape.c
index 66187122377c..e2d5d2d3ed96 100644
--- a/sound/isa/sscape.c
+++ b/sound/isa/sscape.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Low-level ALSA driver for the ENSONIQ SoundScape PnP 2 * Low-level ALSA driver for the ENSONIQ SoundScape
3 * Copyright (c) by Chris Rankin 3 * Copyright (c) by Chris Rankin
4 * 4 *
5 * This driver was written in part using information obtained from 5 * This driver was written in part using information obtained from
@@ -25,31 +25,36 @@
25#include <linux/err.h> 25#include <linux/err.h>
26#include <linux/isa.h> 26#include <linux/isa.h>
27#include <linux/delay.h> 27#include <linux/delay.h>
28#include <linux/firmware.h>
28#include <linux/pnp.h> 29#include <linux/pnp.h>
29#include <linux/spinlock.h> 30#include <linux/spinlock.h>
30#include <linux/moduleparam.h> 31#include <linux/moduleparam.h>
31#include <asm/dma.h> 32#include <asm/dma.h>
32#include <sound/core.h> 33#include <sound/core.h>
33#include <sound/hwdep.h>
34#include <sound/wss.h> 34#include <sound/wss.h>
35#include <sound/mpu401.h> 35#include <sound/mpu401.h>
36#include <sound/initval.h> 36#include <sound/initval.h>
37 37
38#include <sound/sscape_ioctl.h>
39
40 38
41MODULE_AUTHOR("Chris Rankin"); 39MODULE_AUTHOR("Chris Rankin");
42MODULE_DESCRIPTION("ENSONIQ SoundScape PnP driver"); 40MODULE_DESCRIPTION("ENSONIQ SoundScape driver");
43MODULE_LICENSE("GPL"); 41MODULE_LICENSE("GPL");
44 42MODULE_FIRMWARE("sndscape.co0");
45static int index[SNDRV_CARDS] __devinitdata = SNDRV_DEFAULT_IDX; 43MODULE_FIRMWARE("sndscape.co1");
46static char* id[SNDRV_CARDS] __devinitdata = SNDRV_DEFAULT_STR; 44MODULE_FIRMWARE("sndscape.co2");
47static long port[SNDRV_CARDS] __devinitdata = SNDRV_DEFAULT_PORT; 45MODULE_FIRMWARE("sndscape.co3");
48static long wss_port[SNDRV_CARDS] __devinitdata = SNDRV_DEFAULT_PORT; 46MODULE_FIRMWARE("sndscape.co4");
49static int irq[SNDRV_CARDS] __devinitdata = SNDRV_DEFAULT_IRQ; 47MODULE_FIRMWARE("scope.cod");
50static int mpu_irq[SNDRV_CARDS] __devinitdata = SNDRV_DEFAULT_IRQ; 48
51static int dma[SNDRV_CARDS] __devinitdata = SNDRV_DEFAULT_DMA; 49static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
52static int dma2[SNDRV_CARDS] __devinitdata = SNDRV_DEFAULT_DMA; 50static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
51static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
52static long wss_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
53static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
54static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
55static int dma[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;
56static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;
57static bool joystick[SNDRV_CARDS];
53 58
54module_param_array(index, int, NULL, 0444); 59module_param_array(index, int, NULL, 0444);
55MODULE_PARM_DESC(index, "Index number for SoundScape soundcard"); 60MODULE_PARM_DESC(index, "Index number for SoundScape soundcard");
@@ -75,6 +80,9 @@ MODULE_PARM_DESC(dma, "DMA # for SoundScape driver.");
75module_param_array(dma2, int, NULL, 0444); 80module_param_array(dma2, int, NULL, 0444);
76MODULE_PARM_DESC(dma2, "DMA2 # for SoundScape driver."); 81MODULE_PARM_DESC(dma2, "DMA2 # for SoundScape driver.");
77 82
83module_param_array(joystick, bool, NULL, 0444);
84MODULE_PARM_DESC(joystick, "Enable gameport.");
85
78#ifdef CONFIG_PNP 86#ifdef CONFIG_PNP
79static int isa_registered; 87static int isa_registered;
80static int pnp_registered; 88static int pnp_registered;
@@ -101,14 +109,14 @@ MODULE_DEVICE_TABLE(pnp_card, sscape_pnpids);
101#define RX_READY 0x01 109#define RX_READY 0x01
102#define TX_READY 0x02 110#define TX_READY 0x02
103 111
104#define CMD_ACK 0x80 112#define CMD_ACK 0x80
105#define CMD_SET_MIDI_VOL 0x84 113#define CMD_SET_MIDI_VOL 0x84
106#define CMD_GET_MIDI_VOL 0x85 114#define CMD_GET_MIDI_VOL 0x85
107#define CMD_XXX_MIDI_VOL 0x86 115#define CMD_XXX_MIDI_VOL 0x86
108#define CMD_SET_EXTMIDI 0x8a 116#define CMD_SET_EXTMIDI 0x8a
109#define CMD_GET_EXTMIDI 0x8b 117#define CMD_GET_EXTMIDI 0x8b
110#define CMD_SET_MT32 0x8c 118#define CMD_SET_MT32 0x8c
111#define CMD_GET_MT32 0x8d 119#define CMD_GET_MT32 0x8d
112 120
113enum GA_REG { 121enum GA_REG {
114 GA_INTSTAT_REG = 0, 122 GA_INTSTAT_REG = 0,
@@ -127,7 +135,8 @@ enum GA_REG {
127 135
128 136
129enum card_type { 137enum card_type {
130 SSCAPE, 138 MEDIA_FX, /* Sequoia S-1000 */
139 SSCAPE, /* Sequoia S-2000 */
131 SSCAPE_PNP, 140 SSCAPE_PNP,
132 SSCAPE_VIVO, 141 SSCAPE_VIVO,
133}; 142};
@@ -140,16 +149,7 @@ struct soundscape {
140 struct resource *io_res; 149 struct resource *io_res;
141 struct resource *wss_res; 150 struct resource *wss_res;
142 struct snd_wss *chip; 151 struct snd_wss *chip;
143 struct snd_mpu401 *mpu;
144 struct snd_hwdep *hw;
145 152
146 /*
147 * The MIDI device won't work until we've loaded
148 * its firmware via a hardware-dependent device IOCTL
149 */
150 spinlock_t fwlock;
151 int hw_in_use;
152 unsigned long midi_usage;
153 unsigned char midi_vol; 153 unsigned char midi_vol;
154}; 154};
155 155
@@ -161,28 +161,21 @@ static inline struct soundscape *get_card_soundscape(struct snd_card *c)
161 return (struct soundscape *) (c->private_data); 161 return (struct soundscape *) (c->private_data);
162} 162}
163 163
164static inline struct soundscape *get_mpu401_soundscape(struct snd_mpu401 * mpu)
165{
166 return (struct soundscape *) (mpu->private_data);
167}
168
169static inline struct soundscape *get_hwdep_soundscape(struct snd_hwdep * hw)
170{
171 return (struct soundscape *) (hw->private_data);
172}
173
174
175/* 164/*
176 * Allocates some kernel memory that we can use for DMA. 165 * Allocates some kernel memory that we can use for DMA.
177 * I think this means that the memory has to map to 166 * I think this means that the memory has to map to
178 * contiguous pages of physical memory. 167 * contiguous pages of physical memory.
179 */ 168 */
180static struct snd_dma_buffer *get_dmabuf(struct snd_dma_buffer *buf, unsigned long size) 169static struct snd_dma_buffer *get_dmabuf(struct snd_dma_buffer *buf,
170 unsigned long size)
181{ 171{
182 if (buf) { 172 if (buf) {
183 if (snd_dma_alloc_pages_fallback(SNDRV_DMA_TYPE_DEV, snd_dma_isa_data(), 173 if (snd_dma_alloc_pages_fallback(SNDRV_DMA_TYPE_DEV,
174 snd_dma_isa_data(),
184 size, buf) < 0) { 175 size, buf) < 0) {
185 snd_printk(KERN_ERR "sscape: Failed to allocate %lu bytes for DMA\n", size); 176 snd_printk(KERN_ERR "sscape: Failed to allocate "
177 "%lu bytes for DMA\n",
178 size);
186 return NULL; 179 return NULL;
187 } 180 }
188 } 181 }
@@ -199,13 +192,13 @@ static void free_dmabuf(struct snd_dma_buffer *buf)
199 snd_dma_free_pages(buf); 192 snd_dma_free_pages(buf);
200} 193}
201 194
202
203/* 195/*
204 * This function writes to the SoundScape's control registers, 196 * This function writes to the SoundScape's control registers,
205 * but doesn't do any locking. It's up to the caller to do that. 197 * but doesn't do any locking. It's up to the caller to do that.
206 * This is why this function is "unsafe" ... 198 * This is why this function is "unsafe" ...
207 */ 199 */
208static inline void sscape_write_unsafe(unsigned io_base, enum GA_REG reg, unsigned char val) 200static inline void sscape_write_unsafe(unsigned io_base, enum GA_REG reg,
201 unsigned char val)
209{ 202{
210 outb(reg, ODIE_ADDR_IO(io_base)); 203 outb(reg, ODIE_ADDR_IO(io_base));
211 outb(val, ODIE_DATA_IO(io_base)); 204 outb(val, ODIE_DATA_IO(io_base));
@@ -215,7 +208,8 @@ static inline void sscape_write_unsafe(unsigned io_base, enum GA_REG reg, unsign
215 * Write to the SoundScape's control registers, and do the 208 * Write to the SoundScape's control registers, and do the
216 * necessary locking ... 209 * necessary locking ...
217 */ 210 */
218static void sscape_write(struct soundscape *s, enum GA_REG reg, unsigned char val) 211static void sscape_write(struct soundscape *s, enum GA_REG reg,
212 unsigned char val)
219{ 213{
220 unsigned long flags; 214 unsigned long flags;
221 215
@@ -228,7 +222,8 @@ static void sscape_write(struct soundscape *s, enum GA_REG reg, unsigned char va
228 * Read from the SoundScape's control registers, but leave any 222 * Read from the SoundScape's control registers, but leave any
229 * locking to the caller. This is why the function is "unsafe" ... 223 * locking to the caller. This is why the function is "unsafe" ...
230 */ 224 */
231static inline unsigned char sscape_read_unsafe(unsigned io_base, enum GA_REG reg) 225static inline unsigned char sscape_read_unsafe(unsigned io_base,
226 enum GA_REG reg)
232{ 227{
233 outb(reg, ODIE_ADDR_IO(io_base)); 228 outb(reg, ODIE_ADDR_IO(io_base));
234 return inb(ODIE_DATA_IO(io_base)); 229 return inb(ODIE_DATA_IO(io_base));
@@ -257,9 +252,8 @@ static inline void set_midi_mode_unsafe(unsigned io_base)
257static inline int host_read_unsafe(unsigned io_base) 252static inline int host_read_unsafe(unsigned io_base)
258{ 253{
259 int data = -1; 254 int data = -1;
260 if ((inb(HOST_CTRL_IO(io_base)) & RX_READY) != 0) { 255 if ((inb(HOST_CTRL_IO(io_base)) & RX_READY) != 0)
261 data = inb(HOST_DATA_IO(io_base)); 256 data = inb(HOST_DATA_IO(io_base));
262 }
263 257
264 return data; 258 return data;
265} 259}
@@ -301,7 +295,7 @@ static inline int host_write_unsafe(unsigned io_base, unsigned char data)
301 * Also leaves all locking-issues to the caller ... 295 * Also leaves all locking-issues to the caller ...
302 */ 296 */
303static int host_write_ctrl_unsafe(unsigned io_base, unsigned char data, 297static int host_write_ctrl_unsafe(unsigned io_base, unsigned char data,
304 unsigned timeout) 298 unsigned timeout)
305{ 299{
306 int err; 300 int err;
307 301
@@ -320,7 +314,7 @@ static int host_write_ctrl_unsafe(unsigned io_base, unsigned char data,
320 * 314 *
321 * NOTE: This check is based upon observation, not documentation. 315 * NOTE: This check is based upon observation, not documentation.
322 */ 316 */
323static inline int verify_mpu401(const struct snd_mpu401 * mpu) 317static inline int verify_mpu401(const struct snd_mpu401 *mpu)
324{ 318{
325 return ((inb(MPU401C(mpu)) & 0xc0) == 0x80); 319 return ((inb(MPU401C(mpu)) & 0xc0) == 0x80);
326} 320}
@@ -328,7 +322,7 @@ static inline int verify_mpu401(const struct snd_mpu401 * mpu)
328/* 322/*
329 * This is apparently the standard way to initailise an MPU-401 323 * This is apparently the standard way to initailise an MPU-401
330 */ 324 */
331static inline void initialise_mpu401(const struct snd_mpu401 * mpu) 325static inline void initialise_mpu401(const struct snd_mpu401 *mpu)
332{ 326{
333 outb(0, MPU401D(mpu)); 327 outb(0, MPU401D(mpu));
334} 328}
@@ -338,9 +332,10 @@ static inline void initialise_mpu401(const struct snd_mpu401 * mpu)
338 * The AD1845 detection fails if we *don't* do this, so I 332 * The AD1845 detection fails if we *don't* do this, so I
339 * think that this is a good idea ... 333 * think that this is a good idea ...
340 */ 334 */
341static inline void activate_ad1845_unsafe(unsigned io_base) 335static void activate_ad1845_unsafe(unsigned io_base)
342{ 336{
343 sscape_write_unsafe(io_base, GA_HMCTL_REG, (sscape_read_unsafe(io_base, GA_HMCTL_REG) & 0xcf) | 0x10); 337 unsigned char val = sscape_read_unsafe(io_base, GA_HMCTL_REG);
338 sscape_write_unsafe(io_base, GA_HMCTL_REG, (val & 0xcf) | 0x10);
344 sscape_write_unsafe(io_base, GA_CDCFG_REG, 0x80); 339 sscape_write_unsafe(io_base, GA_CDCFG_REG, 0x80);
345} 340}
346 341
@@ -359,24 +354,27 @@ static void soundscape_free(struct snd_card *c)
359 * Tell the SoundScape to begin a DMA tranfer using the given channel. 354 * Tell the SoundScape to begin a DMA tranfer using the given channel.
360 * All locking issues are left to the caller. 355 * All locking issues are left to the caller.
361 */ 356 */
362static inline void sscape_start_dma_unsafe(unsigned io_base, enum GA_REG reg) 357static void sscape_start_dma_unsafe(unsigned io_base, enum GA_REG reg)
363{ 358{
364 sscape_write_unsafe(io_base, reg, sscape_read_unsafe(io_base, reg) | 0x01); 359 sscape_write_unsafe(io_base, reg,
365 sscape_write_unsafe(io_base, reg, sscape_read_unsafe(io_base, reg) & 0xfe); 360 sscape_read_unsafe(io_base, reg) | 0x01);
361 sscape_write_unsafe(io_base, reg,
362 sscape_read_unsafe(io_base, reg) & 0xfe);
366} 363}
367 364
368/* 365/*
369 * Wait for a DMA transfer to complete. This is a "limited busy-wait", 366 * Wait for a DMA transfer to complete. This is a "limited busy-wait",
370 * and all locking issues are left to the caller. 367 * and all locking issues are left to the caller.
371 */ 368 */
372static int sscape_wait_dma_unsafe(unsigned io_base, enum GA_REG reg, unsigned timeout) 369static int sscape_wait_dma_unsafe(unsigned io_base, enum GA_REG reg,
370 unsigned timeout)
373{ 371{
374 while (!(sscape_read_unsafe(io_base, reg) & 0x01) && (timeout != 0)) { 372 while (!(sscape_read_unsafe(io_base, reg) & 0x01) && (timeout != 0)) {
375 udelay(100); 373 udelay(100);
376 --timeout; 374 --timeout;
377 } /* while */ 375 } /* while */
378 376
379 return (sscape_read_unsafe(io_base, reg) & 0x01); 377 return sscape_read_unsafe(io_base, reg) & 0x01;
380} 378}
381 379
382/* 380/*
@@ -392,12 +390,12 @@ static int obp_startup_ack(struct soundscape *s, unsigned timeout)
392 390
393 do { 391 do {
394 unsigned long flags; 392 unsigned long flags;
395 unsigned char x; 393 int x;
396 394
397 spin_lock_irqsave(&s->lock, flags); 395 spin_lock_irqsave(&s->lock, flags);
398 x = inb(HOST_DATA_IO(s->io_base)); 396 x = host_read_unsafe(s->io_base);
399 spin_unlock_irqrestore(&s->lock, flags); 397 spin_unlock_irqrestore(&s->lock, flags);
400 if ((x & 0xfe) == 0xfe) 398 if (x == 0xfe || x == 0xff)
401 return 1; 399 return 1;
402 400
403 msleep(10); 401 msleep(10);
@@ -419,10 +417,10 @@ static int host_startup_ack(struct soundscape *s, unsigned timeout)
419 417
420 do { 418 do {
421 unsigned long flags; 419 unsigned long flags;
422 unsigned char x; 420 int x;
423 421
424 spin_lock_irqsave(&s->lock, flags); 422 spin_lock_irqsave(&s->lock, flags);
425 x = inb(HOST_DATA_IO(s->io_base)); 423 x = host_read_unsafe(s->io_base);
426 spin_unlock_irqrestore(&s->lock, flags); 424 spin_unlock_irqrestore(&s->lock, flags);
427 if (x == 0xfe) 425 if (x == 0xfe)
428 return 1; 426 return 1;
@@ -436,15 +434,15 @@ static int host_startup_ack(struct soundscape *s, unsigned timeout)
436/* 434/*
437 * Upload a byte-stream into the SoundScape using DMA channel A. 435 * Upload a byte-stream into the SoundScape using DMA channel A.
438 */ 436 */
439static int upload_dma_data(struct soundscape *s, 437static int upload_dma_data(struct soundscape *s, const unsigned char *data,
440 const unsigned char __user *data, 438 size_t size)
441 size_t size)
442{ 439{
443 unsigned long flags; 440 unsigned long flags;
444 struct snd_dma_buffer dma; 441 struct snd_dma_buffer dma;
445 int ret; 442 int ret;
443 unsigned char val;
446 444
447 if (!get_dmabuf(&dma, PAGE_ALIGN(size))) 445 if (!get_dmabuf(&dma, PAGE_ALIGN(32 * 1024)))
448 return -ENOMEM; 446 return -ENOMEM;
449 447
450 spin_lock_irqsave(&s->lock, flags); 448 spin_lock_irqsave(&s->lock, flags);
@@ -452,70 +450,57 @@ static int upload_dma_data(struct soundscape *s,
452 /* 450 /*
453 * Reset the board ... 451 * Reset the board ...
454 */ 452 */
455 sscape_write_unsafe(s->io_base, GA_HMCTL_REG, sscape_read_unsafe(s->io_base, GA_HMCTL_REG) & 0x3f); 453 val = sscape_read_unsafe(s->io_base, GA_HMCTL_REG);
454 sscape_write_unsafe(s->io_base, GA_HMCTL_REG, val & 0x3f);
456 455
457 /* 456 /*
458 * Enable the DMA channels and configure them ... 457 * Enable the DMA channels and configure them ...
459 */ 458 */
460 sscape_write_unsafe(s->io_base, GA_DMACFG_REG, 0x50); 459 val = (s->chip->dma1 << 4) | DMA_8BIT;
461 sscape_write_unsafe(s->io_base, GA_DMAA_REG, (s->chip->dma1 << 4) | DMA_8BIT); 460 sscape_write_unsafe(s->io_base, GA_DMAA_REG, val);
462 sscape_write_unsafe(s->io_base, GA_DMAB_REG, 0x20); 461 sscape_write_unsafe(s->io_base, GA_DMAB_REG, 0x20);
463 462
464 /* 463 /*
465 * Take the board out of reset ... 464 * Take the board out of reset ...
466 */ 465 */
467 sscape_write_unsafe(s->io_base, GA_HMCTL_REG, sscape_read_unsafe(s->io_base, GA_HMCTL_REG) | 0x80); 466 val = sscape_read_unsafe(s->io_base, GA_HMCTL_REG);
467 sscape_write_unsafe(s->io_base, GA_HMCTL_REG, val | 0x80);
468 468
469 /* 469 /*
470 * Upload the user's data (firmware?) to the SoundScape 470 * Upload the firmware to the SoundScape
471 * board through the DMA channel ... 471 * board through the DMA channel ...
472 */ 472 */
473 while (size != 0) { 473 while (size != 0) {
474 unsigned long len; 474 unsigned long len;
475 475
476 /*
477 * Apparently, copying to/from userspace can sleep.
478 * We are therefore forbidden from holding any
479 * spinlocks while we copy ...
480 */
481 spin_unlock_irqrestore(&s->lock, flags);
482
483 /*
484 * Remember that the data that we want to DMA
485 * comes from USERSPACE. We have already verified
486 * the userspace pointer ...
487 */
488 len = min(size, dma.bytes); 476 len = min(size, dma.bytes);
489 len -= __copy_from_user(dma.area, data, len); 477 memcpy(dma.area, data, len);
490 data += len; 478 data += len;
491 size -= len; 479 size -= len;
492 480
493 /*
494 * Grab that spinlock again, now that we've
495 * finished copying!
496 */
497 spin_lock_irqsave(&s->lock, flags);
498
499 snd_dma_program(s->chip->dma1, dma.addr, len, DMA_MODE_WRITE); 481 snd_dma_program(s->chip->dma1, dma.addr, len, DMA_MODE_WRITE);
500 sscape_start_dma_unsafe(s->io_base, GA_DMAA_REG); 482 sscape_start_dma_unsafe(s->io_base, GA_DMAA_REG);
501 if (!sscape_wait_dma_unsafe(s->io_base, GA_DMAA_REG, 5000)) { 483 if (!sscape_wait_dma_unsafe(s->io_base, GA_DMAA_REG, 5000)) {
502 /* 484 /*
503 * Don't forget to release this spinlock we're holding ... 485 * Don't forget to release this spinlock we're holding
504 */ 486 */
505 spin_unlock_irqrestore(&s->lock, flags); 487 spin_unlock_irqrestore(&s->lock, flags);
506 488
507 snd_printk(KERN_ERR "sscape: DMA upload has timed out\n"); 489 snd_printk(KERN_ERR
490 "sscape: DMA upload has timed out\n");
508 ret = -EAGAIN; 491 ret = -EAGAIN;
509 goto _release_dma; 492 goto _release_dma;
510 } 493 }
511 } /* while */ 494 } /* while */
512 495
513 set_host_mode_unsafe(s->io_base); 496 set_host_mode_unsafe(s->io_base);
497 outb(0x0, s->io_base);
514 498
515 /* 499 /*
516 * Boot the board ... (I think) 500 * Boot the board ... (I think)
517 */ 501 */
518 sscape_write_unsafe(s->io_base, GA_HMCTL_REG, sscape_read_unsafe(s->io_base, GA_HMCTL_REG) | 0x40); 502 val = sscape_read_unsafe(s->io_base, GA_HMCTL_REG);
503 sscape_write_unsafe(s->io_base, GA_HMCTL_REG, val | 0x40);
519 spin_unlock_irqrestore(&s->lock, flags); 504 spin_unlock_irqrestore(&s->lock, flags);
520 505
521 /* 506 /*
@@ -525,10 +510,12 @@ static int upload_dma_data(struct soundscape *s,
525 */ 510 */
526 ret = 0; 511 ret = 0;
527 if (!obp_startup_ack(s, 5000)) { 512 if (!obp_startup_ack(s, 5000)) {
528 snd_printk(KERN_ERR "sscape: No response from on-board processor after upload\n"); 513 snd_printk(KERN_ERR "sscape: No response "
514 "from on-board processor after upload\n");
529 ret = -EAGAIN; 515 ret = -EAGAIN;
530 } else if (!host_startup_ack(s, 5000)) { 516 } else if (!host_startup_ack(s, 5000)) {
531 snd_printk(KERN_ERR "sscape: SoundScape failed to initialise\n"); 517 snd_printk(KERN_ERR
518 "sscape: SoundScape failed to initialise\n");
532 ret = -EAGAIN; 519 ret = -EAGAIN;
533 } 520 }
534 521
@@ -536,7 +523,7 @@ _release_dma:
536 /* 523 /*
537 * NOTE!!! We are NOT holding any spinlocks at this point !!! 524 * NOTE!!! We are NOT holding any spinlocks at this point !!!
538 */ 525 */
539 sscape_write(s, GA_DMAA_REG, (s->ic_type == IC_ODIE ? 0x70 : 0x40)); 526 sscape_write(s, GA_DMAA_REG, (s->ic_type == IC_OPUS ? 0x40 : 0x70));
540 free_dmabuf(&dma); 527 free_dmabuf(&dma);
541 528
542 return ret; 529 return ret;
@@ -546,167 +533,76 @@ _release_dma:
546 * Upload the bootblock(?) into the SoundScape. The only 533 * Upload the bootblock(?) into the SoundScape. The only
547 * purpose of this block of code seems to be to tell 534 * purpose of this block of code seems to be to tell
548 * us which version of the microcode we should be using. 535 * us which version of the microcode we should be using.
549 *
550 * NOTE: The boot-block data resides in USER-SPACE!!!
551 * However, we have already verified its memory
552 * addresses by the time we get here.
553 */ 536 */
554static int sscape_upload_bootblock(struct soundscape *sscape, struct sscape_bootblock __user *bb) 537static int sscape_upload_bootblock(struct snd_card *card)
555{ 538{
539 struct soundscape *sscape = get_card_soundscape(card);
556 unsigned long flags; 540 unsigned long flags;
541 const struct firmware *init_fw = NULL;
557 int data = 0; 542 int data = 0;
558 int ret; 543 int ret;
559 544
560 ret = upload_dma_data(sscape, bb->code, sizeof(bb->code)); 545 ret = request_firmware(&init_fw, "scope.cod", card->dev);
561 546 if (ret < 0) {
562 spin_lock_irqsave(&sscape->lock, flags); 547 snd_printk(KERN_ERR "sscape: Error loading scope.cod");
563 if (ret == 0) { 548 return ret;
564 data = host_read_ctrl_unsafe(sscape->io_base, 100);
565 }
566 set_midi_mode_unsafe(sscape->io_base);
567 spin_unlock_irqrestore(&sscape->lock, flags);
568
569 if (ret == 0) {
570 if (data < 0) {
571 snd_printk(KERN_ERR "sscape: timeout reading firmware version\n");
572 ret = -EAGAIN;
573 }
574 else if (__copy_to_user(&bb->version, &data, sizeof(bb->version))) {
575 ret = -EFAULT;
576 }
577 } 549 }
550 ret = upload_dma_data(sscape, init_fw->data, init_fw->size);
578 551
579 return ret; 552 release_firmware(init_fw);
580}
581
582/*
583 * Upload the microcode into the SoundScape. The
584 * microcode is 64K of data, and if we try to copy
585 * it into a local variable then we will SMASH THE
586 * KERNEL'S STACK! We therefore leave it in USER
587 * SPACE, and save ourselves from copying it at all.
588 */
589static int sscape_upload_microcode(struct soundscape *sscape,
590 const struct sscape_microcode __user *mc)
591{
592 unsigned long flags;
593 char __user *code;
594 int err;
595 553
596 /* 554 spin_lock_irqsave(&sscape->lock, flags);
597 * We are going to have to copy this data into a special 555 if (ret == 0)
598 * DMA-able buffer before we can upload it. We shall therefore 556 data = host_read_ctrl_unsafe(sscape->io_base, 100);
599 * just check that the data pointer is valid for now.
600 *
601 * NOTE: This buffer is 64K long! That's WAY too big to
602 * copy into a stack-temporary anyway.
603 */
604 if ( get_user(code, &mc->code) ||
605 !access_ok(VERIFY_READ, code, SSCAPE_MICROCODE_SIZE) )
606 return -EFAULT;
607 557
608 if ((err = upload_dma_data(sscape, code, SSCAPE_MICROCODE_SIZE)) == 0) { 558 if (data & 0x10)
609 snd_printk(KERN_INFO "sscape: MIDI firmware loaded\n"); 559 sscape_write_unsafe(sscape->io_base, GA_SMCFGA_REG, 0x2f);
610 }
611 560
612 spin_lock_irqsave(&sscape->lock, flags);
613 set_midi_mode_unsafe(sscape->io_base);
614 spin_unlock_irqrestore(&sscape->lock, flags); 561 spin_unlock_irqrestore(&sscape->lock, flags);
615 562
616 initialise_mpu401(sscape->mpu); 563 data &= 0xf;
564 if (ret == 0 && data > 7) {
565 snd_printk(KERN_ERR
566 "sscape: timeout reading firmware version\n");
567 ret = -EAGAIN;
568 }
617 569
618 return err; 570 return (ret == 0) ? data : ret;
619} 571}
620 572
621/* 573/*
622 * Hardware-specific device functions, to implement special 574 * Upload the microcode into the SoundScape.
623 * IOCTLs for the SoundScape card. This is how we upload
624 * the microcode into the card, for example, and so we
625 * must ensure that no two processes can open this device
626 * simultaneously, and that we can't open it at all if
627 * someone is using the MIDI device.
628 */ 575 */
629static int sscape_hw_open(struct snd_hwdep * hw, struct file *file) 576static int sscape_upload_microcode(struct snd_card *card, int version)
630{ 577{
631 register struct soundscape *sscape = get_hwdep_soundscape(hw); 578 struct soundscape *sscape = get_card_soundscape(card);
632 unsigned long flags; 579 const struct firmware *init_fw = NULL;
580 char name[14];
633 int err; 581 int err;
634 582
635 spin_lock_irqsave(&sscape->fwlock, flags); 583 snprintf(name, sizeof(name), "sndscape.co%d", version);
636 584
637 if ((sscape->midi_usage != 0) || sscape->hw_in_use) { 585 err = request_firmware(&init_fw, name, card->dev);
638 err = -EBUSY; 586 if (err < 0) {
639 } else { 587 snd_printk(KERN_ERR "sscape: Error loading sndscape.co%d",
640 sscape->hw_in_use = 1; 588 version);
641 err = 0; 589 return err;
642 } 590 }
591 err = upload_dma_data(sscape, init_fw->data, init_fw->size);
592 if (err == 0)
593 snd_printk(KERN_INFO "sscape: MIDI firmware loaded %d KBs\n",
594 init_fw->size >> 10);
643 595
644 spin_unlock_irqrestore(&sscape->fwlock, flags); 596 release_firmware(init_fw);
645 return err;
646}
647
648static int sscape_hw_release(struct snd_hwdep * hw, struct file *file)
649{
650 register struct soundscape *sscape = get_hwdep_soundscape(hw);
651 unsigned long flags;
652
653 spin_lock_irqsave(&sscape->fwlock, flags);
654 sscape->hw_in_use = 0;
655 spin_unlock_irqrestore(&sscape->fwlock, flags);
656 return 0;
657}
658
659static int sscape_hw_ioctl(struct snd_hwdep * hw, struct file *file,
660 unsigned int cmd, unsigned long arg)
661{
662 struct soundscape *sscape = get_hwdep_soundscape(hw);
663 int err = -EBUSY;
664
665 switch (cmd) {
666 case SND_SSCAPE_LOAD_BOOTB:
667 {
668 register struct sscape_bootblock __user *bb = (struct sscape_bootblock __user *) arg;
669
670 /*
671 * We are going to have to copy this data into a special
672 * DMA-able buffer before we can upload it. We shall therefore
673 * just check that the data pointer is valid for now ...
674 */
675 if ( !access_ok(VERIFY_READ, bb->code, sizeof(bb->code)) )
676 return -EFAULT;
677
678 /*
679 * Now check that we can write the firmware version number too...
680 */
681 if ( !access_ok(VERIFY_WRITE, &bb->version, sizeof(bb->version)) )
682 return -EFAULT;
683
684 err = sscape_upload_bootblock(sscape, bb);
685 }
686 break;
687
688 case SND_SSCAPE_LOAD_MCODE:
689 {
690 register const struct sscape_microcode __user *mc = (const struct sscape_microcode __user *) arg;
691
692 err = sscape_upload_microcode(sscape, mc);
693 }
694 break;
695
696 default:
697 err = -EINVAL;
698 break;
699 } /* switch */
700 597
701 return err; 598 return err;
702} 599}
703 600
704
705/* 601/*
706 * Mixer control for the SoundScape's MIDI device. 602 * Mixer control for the SoundScape's MIDI device.
707 */ 603 */
708static int sscape_midi_info(struct snd_kcontrol *ctl, 604static int sscape_midi_info(struct snd_kcontrol *ctl,
709 struct snd_ctl_elem_info *uinfo) 605 struct snd_ctl_elem_info *uinfo)
710{ 606{
711 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 607 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
712 uinfo->count = 1; 608 uinfo->count = 1;
@@ -716,7 +612,7 @@ static int sscape_midi_info(struct snd_kcontrol *ctl,
716} 612}
717 613
718static int sscape_midi_get(struct snd_kcontrol *kctl, 614static int sscape_midi_get(struct snd_kcontrol *kctl,
719 struct snd_ctl_elem_value *uctl) 615 struct snd_ctl_elem_value *uctl)
720{ 616{
721 struct snd_wss *chip = snd_kcontrol_chip(kctl); 617 struct snd_wss *chip = snd_kcontrol_chip(kctl);
722 struct snd_card *card = chip->card; 618 struct snd_card *card = chip->card;
@@ -730,16 +626,18 @@ static int sscape_midi_get(struct snd_kcontrol *kctl,
730} 626}
731 627
732static int sscape_midi_put(struct snd_kcontrol *kctl, 628static int sscape_midi_put(struct snd_kcontrol *kctl,
733 struct snd_ctl_elem_value *uctl) 629 struct snd_ctl_elem_value *uctl)
734{ 630{
735 struct snd_wss *chip = snd_kcontrol_chip(kctl); 631 struct snd_wss *chip = snd_kcontrol_chip(kctl);
736 struct snd_card *card = chip->card; 632 struct snd_card *card = chip->card;
737 register struct soundscape *s = get_card_soundscape(card); 633 struct soundscape *s = get_card_soundscape(card);
738 unsigned long flags; 634 unsigned long flags;
739 int change; 635 int change;
636 unsigned char new_val;
740 637
741 spin_lock_irqsave(&s->lock, flags); 638 spin_lock_irqsave(&s->lock, flags);
742 639
640 new_val = uctl->value.integer.value[0] & 127;
743 /* 641 /*
744 * We need to put the board into HOST mode before we 642 * We need to put the board into HOST mode before we
745 * can send any volume-changing HOST commands ... 643 * can send any volume-changing HOST commands ...
@@ -752,15 +650,16 @@ static int sscape_midi_put(struct snd_kcontrol *kctl,
752 * and then perform another volume-related command. Perhaps the 650 * and then perform another volume-related command. Perhaps the
753 * first command is an "open" and the second command is a "close"? 651 * first command is an "open" and the second command is a "close"?
754 */ 652 */
755 if (s->midi_vol == ((unsigned char) uctl->value.integer. value[0] & 127)) { 653 if (s->midi_vol == new_val) {
756 change = 0; 654 change = 0;
757 goto __skip_change; 655 goto __skip_change;
758 } 656 }
759 change = (host_write_ctrl_unsafe(s->io_base, CMD_SET_MIDI_VOL, 100) 657 change = host_write_ctrl_unsafe(s->io_base, CMD_SET_MIDI_VOL, 100)
760 && host_write_ctrl_unsafe(s->io_base, ((unsigned char) uctl->value.integer. value[0]) & 127, 100) 658 && host_write_ctrl_unsafe(s->io_base, new_val, 100)
761 && host_write_ctrl_unsafe(s->io_base, CMD_XXX_MIDI_VOL, 100)); 659 && host_write_ctrl_unsafe(s->io_base, CMD_XXX_MIDI_VOL, 100)
762 s->midi_vol = (unsigned char) uctl->value.integer.value[0] & 127; 660 && host_write_ctrl_unsafe(s->io_base, new_val, 100);
763 __skip_change: 661 s->midi_vol = new_val;
662__skip_change:
764 663
765 /* 664 /*
766 * Take the board out of HOST mode and back into MIDI mode ... 665 * Take the board out of HOST mode and back into MIDI mode ...
@@ -784,20 +683,25 @@ static struct snd_kcontrol_new midi_mixer_ctl = {
784 * These IRQs are encoded as bit patterns so that they can be 683 * These IRQs are encoded as bit patterns so that they can be
785 * written to the control registers. 684 * written to the control registers.
786 */ 685 */
787static unsigned __devinit get_irq_config(int irq) 686static unsigned __devinit get_irq_config(int sscape_type, int irq)
788{ 687{
789 static const int valid_irq[] = { 9, 5, 7, 10 }; 688 static const int valid_irq[] = { 9, 5, 7, 10 };
689 static const int old_irq[] = { 9, 7, 5, 15 };
790 unsigned cfg; 690 unsigned cfg;
791 691
792 for (cfg = 0; cfg < ARRAY_SIZE(valid_irq); ++cfg) { 692 if (sscape_type == MEDIA_FX) {
793 if (irq == valid_irq[cfg]) 693 for (cfg = 0; cfg < ARRAY_SIZE(old_irq); ++cfg)
794 return cfg; 694 if (irq == old_irq[cfg])
795 } /* for */ 695 return cfg;
696 } else {
697 for (cfg = 0; cfg < ARRAY_SIZE(valid_irq); ++cfg)
698 if (irq == valid_irq[cfg])
699 return cfg;
700 }
796 701
797 return INVALID_IRQ; 702 return INVALID_IRQ;
798} 703}
799 704
800
801/* 705/*
802 * Perform certain arcane port-checks to see whether there 706 * Perform certain arcane port-checks to see whether there
803 * is a SoundScape board lurking behind the given ports. 707 * is a SoundScape board lurking behind the given ports.
@@ -842,11 +746,38 @@ static int __devinit detect_sscape(struct soundscape *s, long wss_io)
842 if (s->type != SSCAPE_VIVO && (d & 0x9f) != 0x0e) 746 if (s->type != SSCAPE_VIVO && (d & 0x9f) != 0x0e)
843 goto _done; 747 goto _done;
844 748
845 d = sscape_read_unsafe(s->io_base, GA_HMCTL_REG) & 0x3f; 749 if (s->ic_type == IC_OPUS)
846 sscape_write_unsafe(s->io_base, GA_HMCTL_REG, d | 0xc0); 750 activate_ad1845_unsafe(s->io_base);
847 751
848 if (s->type == SSCAPE_VIVO) 752 if (s->type == SSCAPE_VIVO)
849 wss_io += 4; 753 wss_io += 4;
754
755 d = sscape_read_unsafe(s->io_base, GA_HMCTL_REG);
756 sscape_write_unsafe(s->io_base, GA_HMCTL_REG, d | 0xc0);
757
758 /* wait for WSS codec */
759 for (d = 0; d < 500; d++) {
760 if ((inb(wss_io) & 0x80) == 0)
761 break;
762 spin_unlock_irqrestore(&s->lock, flags);
763 msleep(1);
764 spin_lock_irqsave(&s->lock, flags);
765 }
766
767 if ((inb(wss_io) & 0x80) != 0)
768 goto _done;
769
770 if (inb(wss_io + 2) == 0xff)
771 goto _done;
772
773 d = sscape_read_unsafe(s->io_base, GA_HMCTL_REG) & 0x3f;
774 sscape_write_unsafe(s->io_base, GA_HMCTL_REG, d);
775
776 if ((inb(wss_io) & 0x80) != 0)
777 s->type = MEDIA_FX;
778
779 d = sscape_read_unsafe(s->io_base, GA_HMCTL_REG);
780 sscape_write_unsafe(s->io_base, GA_HMCTL_REG, d | 0xc0);
850 /* wait for WSS codec */ 781 /* wait for WSS codec */
851 for (d = 0; d < 500; d++) { 782 for (d = 0; d < 500; d++) {
852 if ((inb(wss_io) & 0x80) == 0) 783 if ((inb(wss_io) & 0x80) == 0)
@@ -855,14 +786,13 @@ static int __devinit detect_sscape(struct soundscape *s, long wss_io)
855 msleep(1); 786 msleep(1);
856 spin_lock_irqsave(&s->lock, flags); 787 spin_lock_irqsave(&s->lock, flags);
857 } 788 }
858 snd_printd(KERN_INFO "init delay = %d ms\n", d);
859 789
860 /* 790 /*
861 * SoundScape successfully detected! 791 * SoundScape successfully detected!
862 */ 792 */
863 retval = 1; 793 retval = 1;
864 794
865 _done: 795_done:
866 spin_unlock_irqrestore(&s->lock, flags); 796 spin_unlock_irqrestore(&s->lock, flags);
867 return retval; 797 return retval;
868} 798}
@@ -873,63 +803,35 @@ static int __devinit detect_sscape(struct soundscape *s, long wss_io)
873 * to crash the machine. Also check that someone isn't using the hardware 803 * to crash the machine. Also check that someone isn't using the hardware
874 * IOCTL device. 804 * IOCTL device.
875 */ 805 */
876static int mpu401_open(struct snd_mpu401 * mpu) 806static int mpu401_open(struct snd_mpu401 *mpu)
877{ 807{
878 int err;
879
880 if (!verify_mpu401(mpu)) { 808 if (!verify_mpu401(mpu)) {
881 snd_printk(KERN_ERR "sscape: MIDI disabled, please load firmware\n"); 809 snd_printk(KERN_ERR "sscape: MIDI disabled, "
882 err = -ENODEV; 810 "please load firmware\n");
883 } else { 811 return -ENODEV;
884 register struct soundscape *sscape = get_mpu401_soundscape(mpu);
885 unsigned long flags;
886
887 spin_lock_irqsave(&sscape->fwlock, flags);
888
889 if (sscape->hw_in_use || (sscape->midi_usage == ULONG_MAX)) {
890 err = -EBUSY;
891 } else {
892 ++(sscape->midi_usage);
893 err = 0;
894 }
895
896 spin_unlock_irqrestore(&sscape->fwlock, flags);
897 } 812 }
898 813
899 return err; 814 return 0;
900}
901
902static void mpu401_close(struct snd_mpu401 * mpu)
903{
904 register struct soundscape *sscape = get_mpu401_soundscape(mpu);
905 unsigned long flags;
906
907 spin_lock_irqsave(&sscape->fwlock, flags);
908 --(sscape->midi_usage);
909 spin_unlock_irqrestore(&sscape->fwlock, flags);
910} 815}
911 816
912/* 817/*
913 * Initialse an MPU-401 subdevice for MIDI support on the SoundScape. 818 * Initialse an MPU-401 subdevice for MIDI support on the SoundScape.
914 */ 819 */
915static int __devinit create_mpu401(struct snd_card *card, int devnum, unsigned long port, int irq) 820static int __devinit create_mpu401(struct snd_card *card, int devnum,
821 unsigned long port, int irq)
916{ 822{
917 struct soundscape *sscape = get_card_soundscape(card); 823 struct soundscape *sscape = get_card_soundscape(card);
918 struct snd_rawmidi *rawmidi; 824 struct snd_rawmidi *rawmidi;
919 int err; 825 int err;
920 826
921 if ((err = snd_mpu401_uart_new(card, devnum, 827 err = snd_mpu401_uart_new(card, devnum, MPU401_HW_MPU401, port,
922 MPU401_HW_MPU401, 828 MPU401_INFO_INTEGRATED, irq, IRQF_DISABLED,
923 port, MPU401_INFO_INTEGRATED, 829 &rawmidi);
924 irq, IRQF_DISABLED, 830 if (err == 0) {
925 &rawmidi)) == 0) { 831 struct snd_mpu401 *mpu = rawmidi->private_data;
926 struct snd_mpu401 *mpu = (struct snd_mpu401 *) rawmidi->private_data;
927 mpu->open_input = mpu401_open; 832 mpu->open_input = mpu401_open;
928 mpu->open_output = mpu401_open; 833 mpu->open_output = mpu401_open;
929 mpu->close_input = mpu401_close;
930 mpu->close_output = mpu401_close;
931 mpu->private_data = sscape; 834 mpu->private_data = sscape;
932 sscape->mpu = mpu;
933 835
934 initialise_mpu401(mpu); 836 initialise_mpu401(mpu);
935 } 837 }
@@ -950,32 +852,34 @@ static int __devinit create_ad1845(struct snd_card *card, unsigned port,
950 register struct soundscape *sscape = get_card_soundscape(card); 852 register struct soundscape *sscape = get_card_soundscape(card);
951 struct snd_wss *chip; 853 struct snd_wss *chip;
952 int err; 854 int err;
855 int codec_type = WSS_HW_DETECT;
953 856
954 if (sscape->type == SSCAPE_VIVO) 857 switch (sscape->type) {
955 port += 4; 858 case MEDIA_FX:
859 case SSCAPE:
860 /*
861 * There are some freak examples of early Soundscape cards
862 * with CS4231 instead of AD1848/CS4248. Unfortunately, the
863 * CS4231 works only in CS4248 compatibility mode on
864 * these cards so force it.
865 */
866 if (sscape->ic_type != IC_OPUS)
867 codec_type = WSS_HW_AD1848;
868 break;
956 869
957 if (dma1 == dma2) 870 case SSCAPE_VIVO:
958 dma2 = -1; 871 port += 4;
872 break;
873 default:
874 break;
875 }
959 876
960 err = snd_wss_create(card, port, -1, irq, dma1, dma2, 877 err = snd_wss_create(card, port, -1, irq, dma1, dma2,
961 WSS_HW_DETECT, WSS_HWSHARE_DMA1, &chip); 878 codec_type, WSS_HWSHARE_DMA1, &chip);
962 if (!err) { 879 if (!err) {
963 unsigned long flags; 880 unsigned long flags;
964 struct snd_pcm *pcm; 881 struct snd_pcm *pcm;
965 882
966/*
967 * It turns out that the PLAYBACK_ENABLE bit is set
968 * by the lowlevel driver ...
969 *
970#define AD1845_IFACE_CONFIG \
971 (CS4231_AUTOCALIB | CS4231_RECORD_ENABLE | CS4231_PLAYBACK_ENABLE)
972 snd_wss_mce_up(chip);
973 spin_lock_irqsave(&chip->reg_lock, flags);
974 snd_wss_out(chip, CS4231_IFACE_CTRL, AD1845_IFACE_CONFIG);
975 spin_unlock_irqrestore(&chip->reg_lock, flags);
976 snd_wss_mce_down(chip);
977 */
978
979 if (sscape->type != SSCAPE_VIVO) { 883 if (sscape->type != SSCAPE_VIVO) {
980 /* 884 /*
981 * The input clock frequency on the SoundScape must 885 * The input clock frequency on the SoundScape must
@@ -1022,17 +926,10 @@ static int __devinit create_ad1845(struct snd_card *card, unsigned port,
1022 } 926 }
1023 } 927 }
1024 928
1025 strcpy(card->driver, "SoundScape");
1026 strcpy(card->shortname, pcm->name);
1027 snprintf(card->longname, sizeof(card->longname),
1028 "%s at 0x%lx, IRQ %d, DMA1 %d, DMA2 %d\n",
1029 pcm->name, chip->port, chip->irq,
1030 chip->dma1, chip->dma2);
1031
1032 sscape->chip = chip; 929 sscape->chip = chip;
1033 } 930 }
1034 931
1035 _error: 932_error:
1036 return err; 933 return err;
1037} 934}
1038 935
@@ -1051,21 +948,8 @@ static int __devinit create_sscape(int dev, struct snd_card *card)
1051 struct resource *wss_res; 948 struct resource *wss_res;
1052 unsigned long flags; 949 unsigned long flags;
1053 int err; 950 int err;
1054 951 int val;
1055 /* 952 const char *name;
1056 * Check that the user didn't pass us garbage data ...
1057 */
1058 irq_cfg = get_irq_config(irq[dev]);
1059 if (irq_cfg == INVALID_IRQ) {
1060 snd_printk(KERN_ERR "sscape: Invalid IRQ %d\n", irq[dev]);
1061 return -ENXIO;
1062 }
1063
1064 mpu_irq_cfg = get_irq_config(mpu_irq[dev]);
1065 if (mpu_irq_cfg == INVALID_IRQ) {
1066 printk(KERN_ERR "sscape: Invalid IRQ %d\n", mpu_irq[dev]);
1067 return -ENXIO;
1068 }
1069 953
1070 /* 954 /*
1071 * Grab IO ports that we will need to probe so that we 955 * Grab IO ports that we will need to probe so that we
@@ -1098,41 +982,51 @@ static int __devinit create_sscape(int dev, struct snd_card *card)
1098 } 982 }
1099 983
1100 spin_lock_init(&sscape->lock); 984 spin_lock_init(&sscape->lock);
1101 spin_lock_init(&sscape->fwlock);
1102 sscape->io_res = io_res; 985 sscape->io_res = io_res;
1103 sscape->wss_res = wss_res; 986 sscape->wss_res = wss_res;
1104 sscape->io_base = port[dev]; 987 sscape->io_base = port[dev];
1105 988
1106 if (!detect_sscape(sscape, wss_port[dev])) { 989 if (!detect_sscape(sscape, wss_port[dev])) {
1107 printk(KERN_ERR "sscape: hardware not detected at 0x%x\n", sscape->io_base); 990 printk(KERN_ERR "sscape: hardware not detected at 0x%x\n",
991 sscape->io_base);
1108 err = -ENODEV; 992 err = -ENODEV;
1109 goto _release_dma; 993 goto _release_dma;
1110 } 994 }
1111 995
1112 printk(KERN_INFO "sscape: hardware detected at 0x%x, using IRQ %d, DMA %d\n", 996 switch (sscape->type) {
1113 sscape->io_base, irq[dev], dma[dev]); 997 case MEDIA_FX:
998 name = "MediaFX/SoundFX";
999 break;
1000 case SSCAPE:
1001 name = "Soundscape";
1002 break;
1003 case SSCAPE_PNP:
1004 name = "Soundscape PnP";
1005 break;
1006 case SSCAPE_VIVO:
1007 name = "Soundscape VIVO";
1008 break;
1009 default:
1010 name = "unknown Soundscape";
1011 break;
1012 }
1114 1013
1115 if (sscape->type != SSCAPE_VIVO) { 1014 printk(KERN_INFO "sscape: %s card detected at 0x%x, using IRQ %d, DMA %d\n",
1116 /* 1015 name, sscape->io_base, irq[dev], dma[dev]);
1117 * Now create the hardware-specific device so that we can 1016
1118 * load the microcode into the on-board processor. 1017 /*
1119 * We cannot use the MPU-401 MIDI system until this firmware 1018 * Check that the user didn't pass us garbage data ...
1120 * has been loaded into the card. 1019 */
1121 */ 1020 irq_cfg = get_irq_config(sscape->type, irq[dev]);
1122 err = snd_hwdep_new(card, "MC68EC000", 0, &(sscape->hw)); 1021 if (irq_cfg == INVALID_IRQ) {
1123 if (err < 0) { 1022 snd_printk(KERN_ERR "sscape: Invalid IRQ %d\n", irq[dev]);
1124 printk(KERN_ERR "sscape: Failed to create " 1023 return -ENXIO;
1125 "firmware device\n"); 1024 }
1126 goto _release_dma; 1025
1127 } 1026 mpu_irq_cfg = get_irq_config(sscape->type, mpu_irq[dev]);
1128 strlcpy(sscape->hw->name, "SoundScape M68K", 1027 if (mpu_irq_cfg == INVALID_IRQ) {
1129 sizeof(sscape->hw->name)); 1028 snd_printk(KERN_ERR "sscape: Invalid IRQ %d\n", mpu_irq[dev]);
1130 sscape->hw->name[sizeof(sscape->hw->name) - 1] = '\0'; 1029 return -ENXIO;
1131 sscape->hw->iface = SNDRV_HWDEP_IFACE_SSCAPE;
1132 sscape->hw->ops.open = sscape_hw_open;
1133 sscape->hw->ops.release = sscape_hw_release;
1134 sscape->hw->ops.ioctl = sscape_hw_ioctl;
1135 sscape->hw->private_data = sscape;
1136 } 1030 }
1137 1031
1138 /* 1032 /*
@@ -1141,9 +1035,6 @@ static int __devinit create_sscape(int dev, struct snd_card *card)
1141 */ 1035 */
1142 spin_lock_irqsave(&sscape->lock, flags); 1036 spin_lock_irqsave(&sscape->lock, flags);
1143 1037
1144 activate_ad1845_unsafe(sscape->io_base);
1145
1146 sscape_write_unsafe(sscape->io_base, GA_INTENA_REG, 0x00); /* disable */
1147 sscape_write_unsafe(sscape->io_base, GA_SMCFGA_REG, 0x2e); 1038 sscape_write_unsafe(sscape->io_base, GA_SMCFGA_REG, 0x2e);
1148 sscape_write_unsafe(sscape->io_base, GA_SMCFGB_REG, 0x00); 1039 sscape_write_unsafe(sscape->io_base, GA_SMCFGB_REG, 0x00);
1149 1040
@@ -1151,15 +1042,23 @@ static int __devinit create_sscape(int dev, struct snd_card *card)
1151 * Enable and configure the DMA channels ... 1042 * Enable and configure the DMA channels ...
1152 */ 1043 */
1153 sscape_write_unsafe(sscape->io_base, GA_DMACFG_REG, 0x50); 1044 sscape_write_unsafe(sscape->io_base, GA_DMACFG_REG, 0x50);
1154 dma_cfg = (sscape->ic_type == IC_ODIE ? 0x70 : 0x40); 1045 dma_cfg = (sscape->ic_type == IC_OPUS ? 0x40 : 0x70);
1155 sscape_write_unsafe(sscape->io_base, GA_DMAA_REG, dma_cfg); 1046 sscape_write_unsafe(sscape->io_base, GA_DMAA_REG, dma_cfg);
1156 sscape_write_unsafe(sscape->io_base, GA_DMAB_REG, 0x20); 1047 sscape_write_unsafe(sscape->io_base, GA_DMAB_REG, 0x20);
1157 1048
1158 sscape_write_unsafe(sscape->io_base, 1049 mpu_irq_cfg |= mpu_irq_cfg << 2;
1159 GA_INTCFG_REG, 0xf0 | (mpu_irq_cfg << 2) | mpu_irq_cfg); 1050 val = sscape_read_unsafe(sscape->io_base, GA_HMCTL_REG) & 0xF7;
1051 if (joystick[dev])
1052 val |= 8;
1053 sscape_write_unsafe(sscape->io_base, GA_HMCTL_REG, val | 0x10);
1054 sscape_write_unsafe(sscape->io_base, GA_INTCFG_REG, 0xf0 | mpu_irq_cfg);
1160 sscape_write_unsafe(sscape->io_base, 1055 sscape_write_unsafe(sscape->io_base,
1161 GA_CDCFG_REG, 0x09 | DMA_8BIT 1056 GA_CDCFG_REG, 0x09 | DMA_8BIT
1162 | (dma[dev] << 4) | (irq_cfg << 1)); 1057 | (dma[dev] << 4) | (irq_cfg << 1));
1058 /*
1059 * Enable the master IRQ ...
1060 */
1061 sscape_write_unsafe(sscape->io_base, GA_INTENA_REG, 0x80);
1163 1062
1164 spin_unlock_irqrestore(&sscape->lock, flags); 1063 spin_unlock_irqrestore(&sscape->lock, flags);
1165 1064
@@ -1170,32 +1069,56 @@ static int __devinit create_sscape(int dev, struct snd_card *card)
1170 err = create_ad1845(card, wss_port[dev], irq[dev], 1069 err = create_ad1845(card, wss_port[dev], irq[dev],
1171 dma[dev], dma2[dev]); 1070 dma[dev], dma2[dev]);
1172 if (err < 0) { 1071 if (err < 0) {
1173 printk(KERN_ERR "sscape: No AD1845 device at 0x%lx, IRQ %d\n", 1072 snd_printk(KERN_ERR
1174 wss_port[dev], irq[dev]); 1073 "sscape: No AD1845 device at 0x%lx, IRQ %d\n",
1074 wss_port[dev], irq[dev]);
1175 goto _release_dma; 1075 goto _release_dma;
1176 } 1076 }
1077 strcpy(card->driver, "SoundScape");
1078 strcpy(card->shortname, name);
1079 snprintf(card->longname, sizeof(card->longname),
1080 "%s at 0x%lx, IRQ %d, DMA1 %d, DMA2 %d\n",
1081 name, sscape->chip->port, sscape->chip->irq,
1082 sscape->chip->dma1, sscape->chip->dma2);
1083
1177#define MIDI_DEVNUM 0 1084#define MIDI_DEVNUM 0
1178 if (sscape->type != SSCAPE_VIVO) { 1085 if (sscape->type != SSCAPE_VIVO) {
1179 err = create_mpu401(card, MIDI_DEVNUM, port[dev], mpu_irq[dev]); 1086 err = sscape_upload_bootblock(card);
1180 if (err < 0) { 1087 if (err >= 0)
1181 printk(KERN_ERR "sscape: Failed to create " 1088 err = sscape_upload_microcode(card, err);
1182 "MPU-401 device at 0x%lx\n",
1183 port[dev]);
1184 goto _release_dma;
1185 }
1186 1089
1187 /* 1090 if (err == 0) {
1188 * Enable the master IRQ ... 1091 err = create_mpu401(card, MIDI_DEVNUM, port[dev],
1189 */ 1092 mpu_irq[dev]);
1190 sscape_write(sscape, GA_INTENA_REG, 0x80); 1093 if (err < 0) {
1094 snd_printk(KERN_ERR "sscape: Failed to create "
1095 "MPU-401 device at 0x%lx\n",
1096 port[dev]);
1097 goto _release_dma;
1098 }
1191 1099
1192 /* 1100 /*
1193 * Initialize mixer 1101 * Initialize mixer
1194 */ 1102 */
1195 sscape->midi_vol = 0; 1103 spin_lock_irqsave(&sscape->lock, flags);
1196 host_write_ctrl_unsafe(sscape->io_base, CMD_SET_MIDI_VOL, 100); 1104 sscape->midi_vol = 0;
1197 host_write_ctrl_unsafe(sscape->io_base, 0, 100); 1105 host_write_ctrl_unsafe(sscape->io_base,
1198 host_write_ctrl_unsafe(sscape->io_base, CMD_XXX_MIDI_VOL, 100); 1106 CMD_SET_MIDI_VOL, 100);
1107 host_write_ctrl_unsafe(sscape->io_base,
1108 sscape->midi_vol, 100);
1109 host_write_ctrl_unsafe(sscape->io_base,
1110 CMD_XXX_MIDI_VOL, 100);
1111 host_write_ctrl_unsafe(sscape->io_base,
1112 sscape->midi_vol, 100);
1113 host_write_ctrl_unsafe(sscape->io_base,
1114 CMD_SET_EXTMIDI, 100);
1115 host_write_ctrl_unsafe(sscape->io_base,
1116 0, 100);
1117 host_write_ctrl_unsafe(sscape->io_base, CMD_ACK, 100);
1118
1119 set_midi_mode_unsafe(sscape->io_base);
1120 spin_unlock_irqrestore(&sscape->lock, flags);
1121 }
1199 } 1122 }
1200 1123
1201 /* 1124 /*
@@ -1231,7 +1154,8 @@ static int __devinit snd_sscape_match(struct device *pdev, unsigned int i)
1231 mpu_irq[i] == SNDRV_AUTO_IRQ || 1154 mpu_irq[i] == SNDRV_AUTO_IRQ ||
1232 dma[i] == SNDRV_AUTO_DMA) { 1155 dma[i] == SNDRV_AUTO_DMA) {
1233 printk(KERN_INFO 1156 printk(KERN_INFO
1234 "sscape: insufficient parameters, need IO, IRQ, MPU-IRQ and DMA\n"); 1157 "sscape: insufficient parameters, "
1158 "need IO, IRQ, MPU-IRQ and DMA\n");
1235 return 0; 1159 return 0;
1236 } 1160 }
1237 1161
@@ -1253,13 +1177,15 @@ static int __devinit snd_sscape_probe(struct device *pdev, unsigned int dev)
1253 sscape->type = SSCAPE; 1177 sscape->type = SSCAPE;
1254 1178
1255 dma[dev] &= 0x03; 1179 dma[dev] &= 0x03;
1180 snd_card_set_dev(card, pdev);
1181
1256 ret = create_sscape(dev, card); 1182 ret = create_sscape(dev, card);
1257 if (ret < 0) 1183 if (ret < 0)
1258 goto _release_card; 1184 goto _release_card;
1259 1185
1260 snd_card_set_dev(card, pdev); 1186 ret = snd_card_register(card);
1261 if ((ret = snd_card_register(card)) < 0) { 1187 if (ret < 0) {
1262 printk(KERN_ERR "sscape: Failed to register sound card\n"); 1188 snd_printk(KERN_ERR "sscape: Failed to register sound card\n");
1263 goto _release_card; 1189 goto _release_card;
1264 } 1190 }
1265 dev_set_drvdata(pdev, card); 1191 dev_set_drvdata(pdev, card);
@@ -1311,36 +1237,20 @@ static int __devinit sscape_pnp_detect(struct pnp_card_link *pcard,
1311 * Allow this function to fail *quietly* if all the ISA PnP 1237 * Allow this function to fail *quietly* if all the ISA PnP
1312 * devices were configured using module parameters instead. 1238 * devices were configured using module parameters instead.
1313 */ 1239 */
1314 if ((idx = get_next_autoindex(idx)) >= SNDRV_CARDS) 1240 idx = get_next_autoindex(idx);
1241 if (idx >= SNDRV_CARDS)
1315 return -ENOSPC; 1242 return -ENOSPC;
1316 1243
1317 /* 1244 /*
1318 * We have found a candidate ISA PnP card. Now we
1319 * have to check that it has the devices that we
1320 * expect it to have.
1321 *
1322 * We will NOT try and autoconfigure all of the resources
1323 * needed and then activate the card as we are assuming that
1324 * has already been done at boot-time using /proc/isapnp.
1325 * We shall simply try to give each active card the resources
1326 * that it wants. This is a sensible strategy for a modular
1327 * system where unused modules are unloaded regularly.
1328 *
1329 * This strategy is utterly useless if we compile the driver
1330 * into the kernel, of course.
1331 */
1332 // printk(KERN_INFO "sscape: %s\n", card->name);
1333
1334 /*
1335 * Check that we still have room for another sound card ... 1245 * Check that we still have room for another sound card ...
1336 */ 1246 */
1337 dev = pnp_request_card_device(pcard, pid->devs[0].id, NULL); 1247 dev = pnp_request_card_device(pcard, pid->devs[0].id, NULL);
1338 if (! dev) 1248 if (!dev)
1339 return -ENODEV; 1249 return -ENODEV;
1340 1250
1341 if (!pnp_is_active(dev)) { 1251 if (!pnp_is_active(dev)) {
1342 if (pnp_activate_dev(dev) < 0) { 1252 if (pnp_activate_dev(dev) < 0) {
1343 printk(KERN_INFO "sscape: device is inactive\n"); 1253 snd_printk(KERN_INFO "sscape: device is inactive\n");
1344 return -EBUSY; 1254 return -EBUSY;
1345 } 1255 }
1346 } 1256 }
@@ -1378,14 +1288,15 @@ static int __devinit sscape_pnp_detect(struct pnp_card_link *pcard,
1378 wss_port[idx] = pnp_port_start(dev, 1); 1288 wss_port[idx] = pnp_port_start(dev, 1);
1379 dma2[idx] = pnp_dma(dev, 1); 1289 dma2[idx] = pnp_dma(dev, 1);
1380 } 1290 }
1291 snd_card_set_dev(card, &pcard->card->dev);
1381 1292
1382 ret = create_sscape(idx, card); 1293 ret = create_sscape(idx, card);
1383 if (ret < 0) 1294 if (ret < 0)
1384 goto _release_card; 1295 goto _release_card;
1385 1296
1386 snd_card_set_dev(card, &pcard->card->dev); 1297 ret = snd_card_register(card);
1387 if ((ret = snd_card_register(card)) < 0) { 1298 if (ret < 0) {
1388 printk(KERN_ERR "sscape: Failed to register sound card\n"); 1299 snd_printk(KERN_ERR "sscape: Failed to register sound card\n");
1389 goto _release_card; 1300 goto _release_card;
1390 } 1301 }
1391 1302
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/isa/wss/wss_lib.c b/sound/isa/wss/wss_lib.c
index 5d2ba1b749ab..9191b32d9130 100644
--- a/sound/isa/wss/wss_lib.c
+++ b/sound/isa/wss/wss_lib.c
@@ -1682,7 +1682,7 @@ static void snd_wss_resume(struct snd_wss *chip)
1682} 1682}
1683#endif /* CONFIG_PM */ 1683#endif /* CONFIG_PM */
1684 1684
1685int snd_wss_free(struct snd_wss *chip) 1685static int snd_wss_free(struct snd_wss *chip)
1686{ 1686{
1687 release_and_free_resource(chip->res_port); 1687 release_and_free_resource(chip->res_port);
1688 release_and_free_resource(chip->res_cport); 1688 release_and_free_resource(chip->res_cport);
@@ -1705,7 +1705,6 @@ int snd_wss_free(struct snd_wss *chip)
1705 kfree(chip); 1705 kfree(chip);
1706 return 0; 1706 return 0;
1707} 1707}
1708EXPORT_SYMBOL(snd_wss_free);
1709 1708
1710static int snd_wss_dev_free(struct snd_device *device) 1709static int snd_wss_dev_free(struct snd_device *device)
1711{ 1710{
@@ -2015,6 +2014,7 @@ static int snd_wss_info_mux(struct snd_kcontrol *kcontrol,
2015 case WSS_HW_INTERWAVE: 2014 case WSS_HW_INTERWAVE:
2016 ptexts = gusmax_texts; 2015 ptexts = gusmax_texts;
2017 break; 2016 break;
2017 case WSS_HW_OPTI93X:
2018 case WSS_HW_OPL3SA2: 2018 case WSS_HW_OPL3SA2:
2019 ptexts = opl3sa_texts; 2019 ptexts = opl3sa_texts;
2020 break; 2020 break;
@@ -2198,64 +2198,26 @@ EXPORT_SYMBOL(snd_wss_put_double);
2198static const DECLARE_TLV_DB_SCALE(db_scale_6bit, -9450, 150, 0); 2198static const DECLARE_TLV_DB_SCALE(db_scale_6bit, -9450, 150, 0);
2199static const DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0); 2199static const DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0);
2200static const DECLARE_TLV_DB_SCALE(db_scale_rec_gain, 0, 150, 0); 2200static const DECLARE_TLV_DB_SCALE(db_scale_rec_gain, 0, 150, 0);
2201 2201static const DECLARE_TLV_DB_SCALE(db_scale_4bit, -4500, 300, 0);
2202static struct snd_kcontrol_new snd_ad1848_controls[] = {
2203WSS_DOUBLE("PCM Playback Switch", 0, CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT,
2204 7, 7, 1, 1),
2205WSS_DOUBLE_TLV("PCM Playback Volume", 0,
2206 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1,
2207 db_scale_6bit),
2208WSS_DOUBLE("Aux Playback Switch", 0,
2209 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1),
2210WSS_DOUBLE_TLV("Aux Playback Volume", 0,
2211 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1,
2212 db_scale_5bit_12db_max),
2213WSS_DOUBLE("Aux Playback Switch", 1,
2214 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
2215WSS_DOUBLE_TLV("Aux Playback Volume", 1,
2216 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1,
2217 db_scale_5bit_12db_max),
2218WSS_DOUBLE_TLV("Capture Volume", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT,
2219 0, 0, 15, 0, db_scale_rec_gain),
2220{
2221 .name = "Capture Source",
2222 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2223 .info = snd_wss_info_mux,
2224 .get = snd_wss_get_mux,
2225 .put = snd_wss_put_mux,
2226},
2227WSS_SINGLE("Loopback Capture Switch", 0, CS4231_LOOPBACK, 0, 1, 0),
2228WSS_SINGLE_TLV("Loopback Capture Volume", 0, CS4231_LOOPBACK, 1, 63, 0,
2229 db_scale_6bit),
2230};
2231 2202
2232static struct snd_kcontrol_new snd_wss_controls[] = { 2203static struct snd_kcontrol_new snd_wss_controls[] = {
2233WSS_DOUBLE("PCM Playback Switch", 0, 2204WSS_DOUBLE("PCM Playback Switch", 0,
2234 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1), 2205 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1),
2235WSS_DOUBLE("PCM Playback Volume", 0, 2206WSS_DOUBLE_TLV("PCM Playback Volume", 0,
2236 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1), 2207 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1,
2237WSS_DOUBLE("Line Playback Switch", 0, 2208 db_scale_6bit),
2238 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1),
2239WSS_DOUBLE("Line Playback Volume", 0,
2240 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 1),
2241WSS_DOUBLE("Aux Playback Switch", 0, 2209WSS_DOUBLE("Aux Playback Switch", 0,
2242 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1), 2210 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1),
2243WSS_DOUBLE("Aux Playback Volume", 0, 2211WSS_DOUBLE_TLV("Aux Playback Volume", 0,
2244 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1), 2212 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1,
2213 db_scale_5bit_12db_max),
2245WSS_DOUBLE("Aux Playback Switch", 1, 2214WSS_DOUBLE("Aux Playback Switch", 1,
2246 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1), 2215 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
2247WSS_DOUBLE("Aux Playback Volume", 1, 2216WSS_DOUBLE_TLV("Aux Playback Volume", 1,
2248 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1), 2217 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1,
2249WSS_SINGLE("Mono Playback Switch", 0, 2218 db_scale_5bit_12db_max),
2250 CS4231_MONO_CTRL, 7, 1, 1), 2219WSS_DOUBLE_TLV("Capture Volume", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT,
2251WSS_SINGLE("Mono Playback Volume", 0, 2220 0, 0, 15, 0, db_scale_rec_gain),
2252 CS4231_MONO_CTRL, 0, 15, 1),
2253WSS_SINGLE("Mono Output Playback Switch", 0,
2254 CS4231_MONO_CTRL, 6, 1, 1),
2255WSS_SINGLE("Mono Output Playback Bypass", 0,
2256 CS4231_MONO_CTRL, 5, 1, 0),
2257WSS_DOUBLE("Capture Volume", 0,
2258 CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 0, 0, 15, 0),
2259{ 2221{
2260 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2222 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2261 .name = "Capture Source", 2223 .name = "Capture Source",
@@ -2263,54 +2225,26 @@ WSS_DOUBLE("Capture Volume", 0,
2263 .get = snd_wss_get_mux, 2225 .get = snd_wss_get_mux,
2264 .put = snd_wss_put_mux, 2226 .put = snd_wss_put_mux,
2265}, 2227},
2266WSS_DOUBLE("Mic Boost", 0, 2228WSS_DOUBLE("Mic Boost (+20dB)", 0,
2267 CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 5, 5, 1, 0), 2229 CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 5, 5, 1, 0),
2268WSS_SINGLE("Loopback Capture Switch", 0, 2230WSS_SINGLE("Loopback Capture Switch", 0,
2269 CS4231_LOOPBACK, 0, 1, 0), 2231 CS4231_LOOPBACK, 0, 1, 0),
2270WSS_SINGLE("Loopback Capture Volume", 0, 2232WSS_SINGLE_TLV("Loopback Capture Volume", 0, CS4231_LOOPBACK, 2, 63, 1,
2271 CS4231_LOOPBACK, 2, 63, 1) 2233 db_scale_6bit),
2272};
2273
2274static struct snd_kcontrol_new snd_opti93x_controls[] = {
2275WSS_DOUBLE("Master Playback Switch", 0,
2276 OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 7, 7, 1, 1),
2277WSS_DOUBLE("Master Playback Volume", 0,
2278 OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 1, 1, 31, 1),
2279WSS_DOUBLE("PCM Playback Switch", 0,
2280 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1),
2281WSS_DOUBLE("PCM Playback Volume", 0,
2282 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 31, 1),
2283WSS_DOUBLE("FM Playback Switch", 0,
2284 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
2285WSS_DOUBLE("FM Playback Volume", 0,
2286 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 1, 1, 15, 1),
2287WSS_DOUBLE("Line Playback Switch", 0, 2234WSS_DOUBLE("Line Playback Switch", 0,
2288 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1), 2235 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1),
2289WSS_DOUBLE("Line Playback Volume", 0, 2236WSS_DOUBLE_TLV("Line Playback Volume", 0,
2290 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 15, 1), 2237 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 1,
2291WSS_DOUBLE("Mic Playback Switch", 0, 2238 db_scale_5bit_12db_max),
2292 OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 7, 7, 1, 1), 2239WSS_SINGLE("Beep Playback Switch", 0,
2293WSS_DOUBLE("Mic Playback Volume", 0, 2240 CS4231_MONO_CTRL, 7, 1, 1),
2294 OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 1, 1, 15, 1), 2241WSS_SINGLE_TLV("Beep Playback Volume", 0,
2295WSS_DOUBLE("Mic Boost", 0, 2242 CS4231_MONO_CTRL, 0, 15, 1,
2296 CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 5, 5, 1, 0), 2243 db_scale_4bit),
2297WSS_DOUBLE("CD Playback Switch", 0, 2244WSS_SINGLE("Mono Output Playback Switch", 0,
2298 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1), 2245 CS4231_MONO_CTRL, 6, 1, 1),
2299WSS_DOUBLE("CD Playback Volume", 0, 2246WSS_SINGLE("Beep Bypass Playback Switch", 0,
2300 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 1, 1, 15, 1), 2247 CS4231_MONO_CTRL, 5, 1, 0),
2301WSS_DOUBLE("Aux Playback Switch", 0,
2302 OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 7, 7, 1, 1),
2303WSS_DOUBLE("Aux Playback Volume", 0,
2304 OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 1, 1, 15, 1),
2305WSS_DOUBLE("Capture Volume", 0,
2306 CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 0, 0, 15, 0),
2307{
2308 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2309 .name = "Capture Source",
2310 .info = snd_wss_info_mux,
2311 .get = snd_wss_get_mux,
2312 .put = snd_wss_put_mux,
2313}
2314}; 2248};
2315 2249
2316int snd_wss_mixer(struct snd_wss *chip) 2250int snd_wss_mixer(struct snd_wss *chip)
@@ -2318,6 +2252,7 @@ int snd_wss_mixer(struct snd_wss *chip)
2318 struct snd_card *card; 2252 struct snd_card *card;
2319 unsigned int idx; 2253 unsigned int idx;
2320 int err; 2254 int err;
2255 int count = ARRAY_SIZE(snd_wss_controls);
2321 2256
2322 if (snd_BUG_ON(!chip || !chip->pcm)) 2257 if (snd_BUG_ON(!chip || !chip->pcm))
2323 return -EINVAL; 2258 return -EINVAL;
@@ -2326,30 +2261,20 @@ int snd_wss_mixer(struct snd_wss *chip)
2326 2261
2327 strcpy(card->mixername, chip->pcm->name); 2262 strcpy(card->mixername, chip->pcm->name);
2328 2263
2329 if (chip->hardware == WSS_HW_OPTI93X) 2264 /* Use only the first 11 entries on AD1848 */
2330 for (idx = 0; idx < ARRAY_SIZE(snd_opti93x_controls); idx++) { 2265 if (chip->hardware & WSS_HW_AD1848_MASK)
2331 err = snd_ctl_add(card, 2266 count = 11;
2332 snd_ctl_new1(&snd_opti93x_controls[idx], 2267 /* There is no loopback on OPTI93X */
2333 chip)); 2268 else if (chip->hardware == WSS_HW_OPTI93X)
2334 if (err < 0) 2269 count = 9;
2335 return err; 2270
2336 } 2271 for (idx = 0; idx < count; idx++) {
2337 else if (chip->hardware & WSS_HW_AD1848_MASK) 2272 err = snd_ctl_add(card,
2338 for (idx = 0; idx < ARRAY_SIZE(snd_ad1848_controls); idx++) { 2273 snd_ctl_new1(&snd_wss_controls[idx],
2339 err = snd_ctl_add(card, 2274 chip));
2340 snd_ctl_new1(&snd_ad1848_controls[idx], 2275 if (err < 0)
2341 chip)); 2276 return err;
2342 if (err < 0) 2277 }
2343 return err;
2344 }
2345 else
2346 for (idx = 0; idx < ARRAY_SIZE(snd_wss_controls); idx++) {
2347 err = snd_ctl_add(card,
2348 snd_ctl_new1(&snd_wss_controls[idx],
2349 chip));
2350 if (err < 0)
2351 return err;
2352 }
2353 return 0; 2278 return 0;
2354} 2279}
2355EXPORT_SYMBOL(snd_wss_mixer); 2280EXPORT_SYMBOL(snd_wss_mixer);
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 8691f4cf6191..717604c00f0a 100644
--- a/sound/mips/sgio2audio.c
+++ b/sound/mips/sgio2audio.c
@@ -25,12 +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/vmalloc.h>
30#include <linux/interrupt.h> 28#include <linux/interrupt.h>
31#include <linux/dma-mapping.h> 29#include <linux/dma-mapping.h>
32#include <linux/platform_device.h> 30#include <linux/platform_device.h>
33#include <linux/io.h> 31#include <linux/io.h>
32#include <linux/slab.h>
34 33
35#include <asm/ip32/ip32_ints.h> 34#include <asm/ip32/ip32_ints.h>
36#include <asm/ip32/mace.h> 35#include <asm/ip32/mace.h>
@@ -603,25 +602,14 @@ static int snd_sgio2audio_pcm_close(struct snd_pcm_substream *substream)
603static int snd_sgio2audio_pcm_hw_params(struct snd_pcm_substream *substream, 602static int snd_sgio2audio_pcm_hw_params(struct snd_pcm_substream *substream,
604 struct snd_pcm_hw_params *hw_params) 603 struct snd_pcm_hw_params *hw_params)
605{ 604{
606 struct snd_pcm_runtime *runtime = substream->runtime; 605 return snd_pcm_lib_alloc_vmalloc_buffer(substream,
607 int size = params_buffer_bytes(hw_params); 606 params_buffer_bytes(hw_params));
608
609 /* alloc virtual 'dma' area */
610 if (runtime->dma_area)
611 vfree(runtime->dma_area);
612 runtime->dma_area = vmalloc(size);
613 if (runtime->dma_area == NULL)
614 return -ENOMEM;
615 runtime->dma_bytes = size;
616 return 0;
617} 607}
618 608
619/* hw_free callback */ 609/* hw_free callback */
620static int snd_sgio2audio_pcm_hw_free(struct snd_pcm_substream *substream) 610static int snd_sgio2audio_pcm_hw_free(struct snd_pcm_substream *substream)
621{ 611{
622 vfree(substream->runtime->dma_area); 612 return snd_pcm_lib_free_vmalloc_buffer(substream);
623 substream->runtime->dma_area = NULL;
624 return 0;
625} 613}
626 614
627/* prepare callback */ 615/* prepare callback */
@@ -692,13 +680,6 @@ snd_sgio2audio_pcm_pointer(struct snd_pcm_substream *substream)
692 chip->channel[chan->idx].pos); 680 chip->channel[chan->idx].pos);
693} 681}
694 682
695/* get the physical page pointer on the given offset */
696static struct page *snd_sgio2audio_page(struct snd_pcm_substream *substream,
697 unsigned long offset)
698{
699 return vmalloc_to_page(substream->runtime->dma_area + offset);
700}
701
702/* operators */ 683/* operators */
703static struct snd_pcm_ops snd_sgio2audio_playback1_ops = { 684static struct snd_pcm_ops snd_sgio2audio_playback1_ops = {
704 .open = snd_sgio2audio_playback1_open, 685 .open = snd_sgio2audio_playback1_open,
@@ -709,7 +690,8 @@ static struct snd_pcm_ops snd_sgio2audio_playback1_ops = {
709 .prepare = snd_sgio2audio_pcm_prepare, 690 .prepare = snd_sgio2audio_pcm_prepare,
710 .trigger = snd_sgio2audio_pcm_trigger, 691 .trigger = snd_sgio2audio_pcm_trigger,
711 .pointer = snd_sgio2audio_pcm_pointer, 692 .pointer = snd_sgio2audio_pcm_pointer,
712 .page = snd_sgio2audio_page, 693 .page = snd_pcm_lib_get_vmalloc_page,
694 .mmap = snd_pcm_lib_mmap_vmalloc,
713}; 695};
714 696
715static struct snd_pcm_ops snd_sgio2audio_playback2_ops = { 697static struct snd_pcm_ops snd_sgio2audio_playback2_ops = {
@@ -721,7 +703,8 @@ static struct snd_pcm_ops snd_sgio2audio_playback2_ops = {
721 .prepare = snd_sgio2audio_pcm_prepare, 703 .prepare = snd_sgio2audio_pcm_prepare,
722 .trigger = snd_sgio2audio_pcm_trigger, 704 .trigger = snd_sgio2audio_pcm_trigger,
723 .pointer = snd_sgio2audio_pcm_pointer, 705 .pointer = snd_sgio2audio_pcm_pointer,
724 .page = snd_sgio2audio_page, 706 .page = snd_pcm_lib_get_vmalloc_page,
707 .mmap = snd_pcm_lib_mmap_vmalloc,
725}; 708};
726 709
727static struct snd_pcm_ops snd_sgio2audio_capture_ops = { 710static struct snd_pcm_ops snd_sgio2audio_capture_ops = {
@@ -733,7 +716,8 @@ static struct snd_pcm_ops snd_sgio2audio_capture_ops = {
733 .prepare = snd_sgio2audio_pcm_prepare, 716 .prepare = snd_sgio2audio_pcm_prepare,
734 .trigger = snd_sgio2audio_pcm_trigger, 717 .trigger = snd_sgio2audio_pcm_trigger,
735 .pointer = snd_sgio2audio_pcm_pointer, 718 .pointer = snd_sgio2audio_pcm_pointer,
736 .page = snd_sgio2audio_page, 719 .page = snd_pcm_lib_get_vmalloc_page,
720 .mmap = snd_pcm_lib_mmap_vmalloc,
737}; 721};
738 722
739/* 723/*
diff --git a/sound/oss/Kconfig b/sound/oss/Kconfig
index bcf2a0698d54..a513651fa149 100644
--- a/sound/oss/Kconfig
+++ b/sound/oss/Kconfig
@@ -1,5 +1,3 @@
1# drivers/sound/Config.in
2#
3# 18 Apr 1998, Michael Elizabeth Chastain, <mailto:mec@shout.net> 1# 18 Apr 1998, Michael Elizabeth Chastain, <mailto:mec@shout.net>
4# More hacking for modularisation. 2# More hacking for modularisation.
5# 3#
@@ -287,18 +285,6 @@ config SOUND_DMAP
287 285
288 Say Y unless you have 16MB or more RAM or a PCI sound card. 286 Say Y unless you have 16MB or more RAM or a PCI sound card.
289 287
290config SOUND_SSCAPE
291 tristate "Ensoniq SoundScape support"
292 help
293 Answer Y if you have a sound card based on the Ensoniq SoundScape
294 chipset. Such cards are being manufactured at least by Ensoniq, Spea
295 and Reveal (Reveal makes also other cards).
296
297 If you compile the driver into the kernel, you have to add
298 "sscape=<io>,<irq>,<dma>,<mpuio>,<mpuirq>" to the kernel command
299 line.
300
301
302config SOUND_VMIDI 288config SOUND_VMIDI
303 tristate "Loopback MIDI device support" 289 tristate "Loopback MIDI device support"
304 help 290 help
diff --git a/sound/oss/Makefile b/sound/oss/Makefile
index e0ae4d4d6a5c..567b8a74178a 100644
--- a/sound/oss/Makefile
+++ b/sound/oss/Makefile
@@ -13,7 +13,6 @@ obj-$(CONFIG_SOUND_SH_DAC_AUDIO) += sh_dac_audio.o
13obj-$(CONFIG_SOUND_AEDSP16) += aedsp16.o 13obj-$(CONFIG_SOUND_AEDSP16) += aedsp16.o
14obj-$(CONFIG_SOUND_PSS) += pss.o ad1848.o mpu401.o 14obj-$(CONFIG_SOUND_PSS) += pss.o ad1848.o mpu401.o
15obj-$(CONFIG_SOUND_TRIX) += trix.o ad1848.o sb_lib.o uart401.o 15obj-$(CONFIG_SOUND_TRIX) += trix.o ad1848.o sb_lib.o uart401.o
16obj-$(CONFIG_SOUND_SSCAPE) += sscape.o ad1848.o mpu401.o
17obj-$(CONFIG_SOUND_MSS) += ad1848.o 16obj-$(CONFIG_SOUND_MSS) += ad1848.o
18obj-$(CONFIG_SOUND_PAS) += pas2.o sb.o sb_lib.o uart401.o 17obj-$(CONFIG_SOUND_PAS) += pas2.o sb.o sb_lib.o uart401.o
19obj-$(CONFIG_SOUND_SB) += sb.o sb_lib.o uart401.o 18obj-$(CONFIG_SOUND_SB) += sb.o sb_lib.o uart401.o
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/au1550_ac97.c b/sound/oss/au1550_ac97.c
index 4191acccbcdb..c1070e33b32f 100644
--- a/sound/oss/au1550_ac97.c
+++ b/sound/oss/au1550_ac97.c
@@ -614,7 +614,8 @@ start_adc(struct au1550_state *s)
614 /* Put two buffers on the ring to get things started. 614 /* Put two buffers on the ring to get things started.
615 */ 615 */
616 for (i=0; i<2; i++) { 616 for (i=0; i<2; i++) {
617 au1xxx_dbdma_put_dest(db->dmanr, db->nextIn, db->dma_fragsize); 617 au1xxx_dbdma_put_dest(db->dmanr, virt_to_phys(db->nextIn),
618 db->dma_fragsize, DDMA_FLAGS_IE);
618 619
619 db->nextIn += db->dma_fragsize; 620 db->nextIn += db->dma_fragsize;
620 if (db->nextIn >= db->rawbuf + db->dmasize) 621 if (db->nextIn >= db->rawbuf + db->dmasize)
@@ -732,8 +733,9 @@ static void dac_dma_interrupt(int irq, void *dev_id)
732 db->dma_qcount--; 733 db->dma_qcount--;
733 734
734 if (db->count >= db->fragsize) { 735 if (db->count >= db->fragsize) {
735 if (au1xxx_dbdma_put_source(db->dmanr, db->nextOut, 736 if (au1xxx_dbdma_put_source(db->dmanr,
736 db->fragsize) == 0) { 737 virt_to_phys(db->nextOut), db->fragsize,
738 DDMA_FLAGS_IE) == 0) {
737 err("qcount < 2 and no ring room!"); 739 err("qcount < 2 and no ring room!");
738 } 740 }
739 db->nextOut += db->fragsize; 741 db->nextOut += db->fragsize;
@@ -777,7 +779,8 @@ static void adc_dma_interrupt(int irq, void *dev_id)
777 779
778 /* Put a new empty buffer on the destination DMA. 780 /* Put a new empty buffer on the destination DMA.
779 */ 781 */
780 au1xxx_dbdma_put_dest(dp->dmanr, dp->nextIn, dp->dma_fragsize); 782 au1xxx_dbdma_put_dest(dp->dmanr, virt_to_phys(dp->nextIn),
783 dp->dma_fragsize, DDMA_FLAGS_IE);
781 784
782 dp->nextIn += dp->dma_fragsize; 785 dp->nextIn += dp->dma_fragsize;
783 if (dp->nextIn >= dp->rawbuf + dp->dmasize) 786 if (dp->nextIn >= dp->rawbuf + dp->dmasize)
@@ -1177,8 +1180,9 @@ au1550_write(struct file *file, const char *buffer, size_t count, loff_t * ppos)
1177 * we know the dma has stopped. 1180 * we know the dma has stopped.
1178 */ 1181 */
1179 while ((db->dma_qcount < 2) && (db->count >= db->fragsize)) { 1182 while ((db->dma_qcount < 2) && (db->count >= db->fragsize)) {
1180 if (au1xxx_dbdma_put_source(db->dmanr, db->nextOut, 1183 if (au1xxx_dbdma_put_source(db->dmanr,
1181 db->fragsize) == 0) { 1184 virt_to_phys(db->nextOut), db->fragsize,
1185 DDMA_FLAGS_IE) == 0) {
1182 err("qcount < 2 and no ring room!"); 1186 err("qcount < 2 and no ring room!");
1183 } 1187 }
1184 db->nextOut += db->fragsize; 1188 db->nextOut += db->fragsize;
diff --git a/sound/oss/audio.c b/sound/oss/audio.c
index b69c05b7ea7b..7df48a25c4ee 100644
--- a/sound/oss/audio.c
+++ b/sound/oss/audio.c
@@ -838,7 +838,7 @@ static int dma_ioctl(int dev, unsigned int cmd, void __user *arg)
838 if ((err = audio_devs[dev]->d->prepare_for_input(dev, 838 if ((err = audio_devs[dev]->d->prepare_for_input(dev,
839 dmap_in->fragment_size, dmap_in->nbufs)) < 0) { 839 dmap_in->fragment_size, dmap_in->nbufs)) < 0) {
840 spin_unlock_irqrestore(&dmap_in->lock,flags); 840 spin_unlock_irqrestore(&dmap_in->lock,flags);
841 return -err; 841 return err;
842 } 842 }
843 dmap_in->dma_mode = DMODE_INPUT; 843 dmap_in->dma_mode = DMODE_INPUT;
844 audio_devs[dev]->enable_bits |= PCM_ENABLE_INPUT; 844 audio_devs[dev]->enable_bits |= PCM_ENABLE_INPUT;
diff --git a/sound/oss/coproc.h b/sound/oss/coproc.h
index 7306346e9ac4..7bec21bbdd88 100644
--- a/sound/oss/coproc.h
+++ b/sound/oss/coproc.h
@@ -4,7 +4,7 @@
4 */ 4 */
5 5
6/* 6/*
7 * Coprocessor access types 7 * Coprocessor access types
8 */ 8 */
9#define COPR_CUSTOM 0x0001 /* Custom applications */ 9#define COPR_CUSTOM 0x0001 /* Custom applications */
10#define COPR_MIDI 0x0002 /* MIDI (MPU-401) emulation */ 10#define COPR_MIDI 0x0002 /* MIDI (MPU-401) emulation */
diff --git a/sound/oss/dev_table.c b/sound/oss/dev_table.c
index 08274c995d06..727bdb9ba2dc 100644
--- a/sound/oss/dev_table.c
+++ b/sound/oss/dev_table.c
@@ -67,14 +67,15 @@ int sound_install_audiodrv(int vers, char *name, struct audio_driver *driver,
67 return -(EBUSY); 67 return -(EBUSY);
68 } 68 }
69 d = (struct audio_driver *) (sound_mem_blocks[sound_nblocks] = vmalloc(sizeof(struct audio_driver))); 69 d = (struct audio_driver *) (sound_mem_blocks[sound_nblocks] = vmalloc(sizeof(struct audio_driver)));
70 70 sound_nblocks++;
71 if (sound_nblocks < 1024) 71 if (sound_nblocks >= MAX_MEM_BLOCKS)
72 sound_nblocks++; 72 sound_nblocks = MAX_MEM_BLOCKS - 1;
73 73
74 op = (struct audio_operations *) (sound_mem_blocks[sound_nblocks] = vmalloc(sizeof(struct audio_operations))); 74 op = (struct audio_operations *) (sound_mem_blocks[sound_nblocks] = vmalloc(sizeof(struct audio_operations)));
75 sound_nblocks++;
76 if (sound_nblocks >= MAX_MEM_BLOCKS)
77 sound_nblocks = MAX_MEM_BLOCKS - 1;
75 78
76 if (sound_nblocks < 1024)
77 sound_nblocks++;
78 if (d == NULL || op == NULL) { 79 if (d == NULL || op == NULL) {
79 printk(KERN_ERR "Sound: Can't allocate driver for (%s)\n", name); 80 printk(KERN_ERR "Sound: Can't allocate driver for (%s)\n", name);
80 sound_unload_audiodev(num); 81 sound_unload_audiodev(num);
@@ -128,9 +129,10 @@ int sound_install_mixer(int vers, char *name, struct mixer_operations *driver,
128 until you unload sound! */ 129 until you unload sound! */
129 130
130 op = (struct mixer_operations *) (sound_mem_blocks[sound_nblocks] = vmalloc(sizeof(struct mixer_operations))); 131 op = (struct mixer_operations *) (sound_mem_blocks[sound_nblocks] = vmalloc(sizeof(struct mixer_operations)));
132 sound_nblocks++;
133 if (sound_nblocks >= MAX_MEM_BLOCKS)
134 sound_nblocks = MAX_MEM_BLOCKS - 1;
131 135
132 if (sound_nblocks < 1024)
133 sound_nblocks++;
134 if (op == NULL) { 136 if (op == NULL) {
135 printk(KERN_ERR "Sound: Can't allocate mixer driver for (%s)\n", name); 137 printk(KERN_ERR "Sound: Can't allocate mixer driver for (%s)\n", name);
136 return -ENOMEM; 138 return -ENOMEM;
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_paula.c b/sound/oss/dmasound/dmasound_paula.c
index 06e9e88e4c05..bb14e4c67e89 100644
--- a/sound/oss/dmasound/dmasound_paula.c
+++ b/sound/oss/dmasound/dmasound_paula.c
@@ -657,7 +657,7 @@ static int AmiStateInfo(char *buffer, size_t space)
657 len += sprintf(buffer+len, "\tsound.volume_right = %d [0...64]\n", 657 len += sprintf(buffer+len, "\tsound.volume_right = %d [0...64]\n",
658 dmasound.volume_right); 658 dmasound.volume_right);
659 if (len >= space) { 659 if (len >= space) {
660 printk(KERN_ERR "dmasound_paula: overlowed state buffer alloc.\n") ; 660 printk(KERN_ERR "dmasound_paula: overflowed state buffer alloc.\n") ;
661 len = space ; 661 len = space ;
662 } 662 }
663 return len; 663 return len;
diff --git a/sound/oss/kahlua.c b/sound/oss/kahlua.c
index 89466b056be7..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
@@ -198,7 +199,7 @@ MODULE_LICENSE("GPL");
198 * 5530 only. The 5510/5520 decode is different. 199 * 5530 only. The 5510/5520 decode is different.
199 */ 200 */
200 201
201static struct pci_device_id id_tbl[] = { 202static DEFINE_PCI_DEVICE_TABLE(id_tbl) = {
202 { PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5530_AUDIO), 0 }, 203 { PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5530_AUDIO), 0 },
203 { } 204 { }
204}; 205};
diff --git a/sound/oss/midi_synth.c b/sound/oss/midi_synth.c
index 9e450988ed36..3bc7104c5379 100644
--- a/sound/oss/midi_synth.c
+++ b/sound/oss/midi_synth.c
@@ -426,7 +426,7 @@ midi_synth_open(int dev, int mode)
426 int err; 426 int err;
427 struct midi_input_info *inc; 427 struct midi_input_info *inc;
428 428
429 if (orig_dev < 0 || orig_dev > num_midis || midi_devs[orig_dev] == NULL) 429 if (orig_dev < 0 || orig_dev >= num_midis || midi_devs[orig_dev] == NULL)
430 return -ENXIO; 430 return -ENXIO;
431 431
432 midi2synth[orig_dev] = dev; 432 midi2synth[orig_dev] = dev;
diff --git a/sound/oss/mpu401.c b/sound/oss/mpu401.c
index 734b8f9e2f78..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>
@@ -770,7 +771,7 @@ static int mpu_synth_ioctl(int dev, unsigned int cmd, void __user *arg)
770 771
771 midi_dev = synth_devs[dev]->midi_dev; 772 midi_dev = synth_devs[dev]->midi_dev;
772 773
773 if (midi_dev < 0 || midi_dev > num_midis || midi_devs[midi_dev] == NULL) 774 if (midi_dev < 0 || midi_dev >= num_midis || midi_devs[midi_dev] == NULL)
774 return -ENXIO; 775 return -ENXIO;
775 776
776 devc = &dev_conf[midi_dev]; 777 devc = &dev_conf[midi_dev];
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/pss.c b/sound/oss/pss.c
index 83f5ee236b12..e19dd5dcc2de 100644
--- a/sound/oss/pss.c
+++ b/sound/oss/pss.c
@@ -269,7 +269,7 @@ static int pss_reset_dsp(pss_confdata * devc)
269 unsigned long i, limit = jiffies + HZ/10; 269 unsigned long i, limit = jiffies + HZ/10;
270 270
271 outw(0x2000, REG(PSS_CONTROL)); 271 outw(0x2000, REG(PSS_CONTROL));
272 for (i = 0; i < 32768 && (limit-jiffies >= 0); i++) 272 for (i = 0; i < 32768 && time_after_eq(limit, jiffies); i++)
273 inw(REG(PSS_CONTROL)); 273 inw(REG(PSS_CONTROL));
274 outw(0x0000, REG(PSS_CONTROL)); 274 outw(0x0000, REG(PSS_CONTROL));
275 return 1; 275 return 1;
@@ -369,11 +369,11 @@ static int pss_download_boot(pss_confdata * devc, unsigned char *block, int size
369 outw(0, REG(PSS_DATA)); 369 outw(0, REG(PSS_DATA));
370 370
371 limit = jiffies + HZ/10; 371 limit = jiffies + HZ/10;
372 for (i = 0; i < 32768 && (limit - jiffies >= 0); i++) 372 for (i = 0; i < 32768 && time_after_eq(limit, jiffies); i++)
373 val = inw(REG(PSS_STATUS)); 373 val = inw(REG(PSS_STATUS));
374 374
375 limit = jiffies + HZ/10; 375 limit = jiffies + HZ/10;
376 for (i = 0; i < 32768 && (limit-jiffies >= 0); i++) 376 for (i = 0; i < 32768 && time_after_eq(limit, jiffies); i++)
377 { 377 {
378 val = inw(REG(PSS_STATUS)); 378 val = inw(REG(PSS_STATUS));
379 if (val & 0x4000) 379 if (val & 0x4000)
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/sequencer.c b/sound/oss/sequencer.c
index c79874696bec..e85789e53816 100644
--- a/sound/oss/sequencer.c
+++ b/sound/oss/sequencer.c
@@ -1631,8 +1631,6 @@ unsigned long compute_finetune(unsigned long base_freq, int bend, int range,
1631 } 1631 }
1632 1632
1633 semitones = bend / 100; 1633 semitones = bend / 100;
1634 if (semitones > 99)
1635 semitones = 99;
1636 cents = bend % 100; 1634 cents = bend % 100;
1637 1635
1638 amount = (int) (semitone_tuning[semitones] * multiplier * cent_tuning[cents]) / 10000; 1636 amount = (int) (semitone_tuning[semitones] * multiplier * cent_tuning[cents]) / 10000;
diff --git a/sound/oss/sh_dac_audio.c b/sound/oss/sh_dac_audio.c
index b2ed8757542a..4153752507e3 100644
--- a/sound/oss/sh_dac_audio.c
+++ b/sound/oss/sh_dac_audio.c
@@ -164,9 +164,6 @@ static ssize_t dac_audio_write(struct file *file, const char *buf, size_t count,
164 int free; 164 int free;
165 int nbytes; 165 int nbytes;
166 166
167 if (count < 0)
168 return -EINVAL;
169
170 if (!count) { 167 if (!count) {
171 dac_audio_sync(); 168 dac_audio_sync();
172 return 0; 169 return 0;
diff --git a/sound/oss/sound_config.h b/sound/oss/sound_config.h
index 55271fbe7f49..9d35c4c65b9b 100644
--- a/sound/oss/sound_config.h
+++ b/sound/oss/sound_config.h
@@ -142,4 +142,6 @@ static inline int translate_mode(struct file *file)
142#define TIMER_ARMED 121234 142#define TIMER_ARMED 121234
143#define TIMER_NOT_ARMED 1 143#define TIMER_NOT_ARMED 1
144 144
145#define MAX_MEM_BLOCKS 1024
146
145#endif 147#endif
diff --git a/sound/oss/soundcard.c b/sound/oss/soundcard.c
index 61aaedae6b7e..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>
@@ -56,7 +55,7 @@
56/* 55/*
57 * Table for permanently allocated memory (used when unloading the module) 56 * Table for permanently allocated memory (used when unloading the module)
58 */ 57 */
59void * sound_mem_blocks[1024]; 58void * sound_mem_blocks[MAX_MEM_BLOCKS];
60int sound_nblocks = 0; 59int sound_nblocks = 0;
61 60
62/* Persistent DMA buffers */ 61/* Persistent DMA buffers */
@@ -328,11 +327,11 @@ static int sound_mixer_ioctl(int mixdev, unsigned int cmd, void __user *arg)
328 return mixer_devs[mixdev]->ioctl(mixdev, cmd, arg); 327 return mixer_devs[mixdev]->ioctl(mixdev, cmd, arg);
329} 328}
330 329
331static int sound_ioctl(struct inode *inode, struct file *file, 330static long sound_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
332 unsigned int cmd, unsigned long arg)
333{ 331{
334 int len = 0, dtype; 332 int len = 0, dtype;
335 int dev = iminor(inode); 333 int dev = iminor(file->f_dentry->d_inode);
334 long ret = -EINVAL;
336 void __user *p = (void __user *)arg; 335 void __user *p = (void __user *)arg;
337 336
338 if (_SIOC_DIR(cmd) != _SIOC_NONE && _SIOC_DIR(cmd) != 0) { 337 if (_SIOC_DIR(cmd) != _SIOC_NONE && _SIOC_DIR(cmd) != 0) {
@@ -353,6 +352,7 @@ static int sound_ioctl(struct inode *inode, struct file *file,
353 if (cmd == OSS_GETVERSION) 352 if (cmd == OSS_GETVERSION)
354 return __put_user(SOUND_VERSION, (int __user *)p); 353 return __put_user(SOUND_VERSION, (int __user *)p);
355 354
355 lock_kernel();
356 if (_IOC_TYPE(cmd) == 'M' && num_mixers > 0 && /* Mixer ioctl */ 356 if (_IOC_TYPE(cmd) == 'M' && num_mixers > 0 && /* Mixer ioctl */
357 (dev & 0x0f) != SND_DEV_CTL) { 357 (dev & 0x0f) != SND_DEV_CTL) {
358 dtype = dev & 0x0f; 358 dtype = dev & 0x0f;
@@ -360,24 +360,31 @@ static int sound_ioctl(struct inode *inode, struct file *file,
360 case SND_DEV_DSP: 360 case SND_DEV_DSP:
361 case SND_DEV_DSP16: 361 case SND_DEV_DSP16:
362 case SND_DEV_AUDIO: 362 case SND_DEV_AUDIO:
363 return sound_mixer_ioctl(audio_devs[dev >> 4]->mixer_dev, 363 ret = sound_mixer_ioctl(audio_devs[dev >> 4]->mixer_dev,
364 cmd, p); 364 cmd, p);
365 365 break;
366 default: 366 default:
367 return sound_mixer_ioctl(dev >> 4, cmd, p); 367 ret = sound_mixer_ioctl(dev >> 4, cmd, p);
368 break;
368 } 369 }
370 unlock_kernel();
371 return ret;
369 } 372 }
373
370 switch (dev & 0x0f) { 374 switch (dev & 0x0f) {
371 case SND_DEV_CTL: 375 case SND_DEV_CTL:
372 if (cmd == SOUND_MIXER_GETLEVELS) 376 if (cmd == SOUND_MIXER_GETLEVELS)
373 return get_mixer_levels(p); 377 ret = get_mixer_levels(p);
374 if (cmd == SOUND_MIXER_SETLEVELS) 378 else if (cmd == SOUND_MIXER_SETLEVELS)
375 return set_mixer_levels(p); 379 ret = set_mixer_levels(p);
376 return sound_mixer_ioctl(dev >> 4, cmd, p); 380 else
381 ret = sound_mixer_ioctl(dev >> 4, cmd, p);
382 break;
377 383
378 case SND_DEV_SEQ: 384 case SND_DEV_SEQ:
379 case SND_DEV_SEQ2: 385 case SND_DEV_SEQ2:
380 return sequencer_ioctl(dev, file, cmd, p); 386 ret = sequencer_ioctl(dev, file, cmd, p);
387 break;
381 388
382 case SND_DEV_DSP: 389 case SND_DEV_DSP:
383 case SND_DEV_DSP16: 390 case SND_DEV_DSP16:
@@ -390,7 +397,8 @@ static int sound_ioctl(struct inode *inode, struct file *file,
390 break; 397 break;
391 398
392 } 399 }
393 return -EINVAL; 400 unlock_kernel();
401 return ret;
394} 402}
395 403
396static unsigned int sound_poll(struct file *file, poll_table * wait) 404static unsigned int sound_poll(struct file *file, poll_table * wait)
@@ -490,7 +498,7 @@ const struct file_operations oss_sound_fops = {
490 .read = sound_read, 498 .read = sound_read,
491 .write = sound_write, 499 .write = sound_write,
492 .poll = sound_poll, 500 .poll = sound_poll,
493 .ioctl = sound_ioctl, 501 .unlocked_ioctl = sound_ioctl,
494 .mmap = sound_mmap, 502 .mmap = sound_mmap,
495 .open = sound_open, 503 .open = sound_open,
496 .release = sound_release, 504 .release = sound_release,
@@ -574,7 +582,7 @@ static int __init oss_init(void)
574 NULL, "%s%d", dev_list[i].name, j); 582 NULL, "%s%d", dev_list[i].name, j);
575 } 583 }
576 584
577 if (sound_nblocks >= 1024) 585 if (sound_nblocks >= MAX_MEM_BLOCKS - 1)
578 printk(KERN_ERR "Sound warning: Deallocation table was too small.\n"); 586 printk(KERN_ERR "Sound warning: Deallocation table was too small.\n");
579 587
580 return 0; 588 return 0;
diff --git a/sound/oss/sscape.c b/sound/oss/sscape.c
deleted file mode 100644
index 30c36d1f35d7..000000000000
--- a/sound/oss/sscape.c
+++ /dev/null
@@ -1,1480 +0,0 @@
1/*
2 * sound/oss/sscape.c
3 *
4 * Low level driver for Ensoniq SoundScape
5 *
6 *
7 * Copyright (C) by Hannu Savolainen 1993-1997
8 *
9 * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
10 * Version 2 (June 1991). See the "COPYING" file distributed with this software
11 * for more info.
12 *
13 *
14 * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
15 * Sergey Smitienko : ensoniq p'n'p support
16 * Christoph Hellwig : adapted to module_init/module_exit
17 * Bartlomiej Zolnierkiewicz : added __init to attach_sscape()
18 * Chris Rankin : Specify that this module owns the coprocessor
19 * Arnaldo C. de Melo : added missing restore_flags in sscape_pnp_upload_file
20 */
21
22#include <linux/init.h>
23#include <linux/module.h>
24
25#include "sound_config.h"
26#include "sound_firmware.h"
27
28#include <linux/types.h>
29#include <linux/errno.h>
30#include <linux/signal.h>
31#include <linux/fcntl.h>
32#include <linux/ctype.h>
33#include <linux/stddef.h>
34#include <linux/kmod.h>
35#include <asm/dma.h>
36#include <asm/io.h>
37#include <linux/wait.h>
38#include <linux/slab.h>
39#include <linux/ioport.h>
40#include <linux/delay.h>
41#include <linux/proc_fs.h>
42#include <linux/mm.h>
43#include <linux/spinlock.h>
44
45#include "coproc.h"
46
47#include "ad1848.h"
48#include "mpu401.h"
49
50/*
51 * I/O ports
52 */
53#define MIDI_DATA 0
54#define MIDI_CTRL 1
55#define HOST_CTRL 2
56#define TX_READY 0x02
57#define RX_READY 0x01
58#define HOST_DATA 3
59#define ODIE_ADDR 4
60#define ODIE_DATA 5
61
62/*
63 * Indirect registers
64 */
65
66#define GA_INTSTAT_REG 0
67#define GA_INTENA_REG 1
68#define GA_DMAA_REG 2
69#define GA_DMAB_REG 3
70#define GA_INTCFG_REG 4
71#define GA_DMACFG_REG 5
72#define GA_CDCFG_REG 6
73#define GA_SMCFGA_REG 7
74#define GA_SMCFGB_REG 8
75#define GA_HMCTL_REG 9
76
77/*
78 * DMA channel identifiers (A and B)
79 */
80
81#define SSCAPE_DMA_A 0
82#define SSCAPE_DMA_B 1
83
84#define PORT(name) (devc->base+name)
85
86/*
87 * Host commands recognized by the OBP microcode
88 */
89
90#define CMD_GEN_HOST_ACK 0x80
91#define CMD_GEN_MPU_ACK 0x81
92#define CMD_GET_BOARD_TYPE 0x82
93#define CMD_SET_CONTROL 0x88 /* Old firmware only */
94#define CMD_GET_CONTROL 0x89 /* Old firmware only */
95#define CTL_MASTER_VOL 0
96#define CTL_MIC_MODE 2
97#define CTL_SYNTH_VOL 4
98#define CTL_WAVE_VOL 7
99#define CMD_SET_EXTMIDI 0x8a
100#define CMD_GET_EXTMIDI 0x8b
101#define CMD_SET_MT32 0x8c
102#define CMD_GET_MT32 0x8d
103
104#define CMD_ACK 0x80
105
106#define IC_ODIE 1
107#define IC_OPUS 2
108
109typedef struct sscape_info
110{
111 int base, irq, dma;
112
113 int codec, codec_irq; /* required to setup pnp cards*/
114 int codec_type;
115 int ic_type;
116 char* raw_buf;
117 unsigned long raw_buf_phys;
118 int buffsize; /* -------------------------- */
119 spinlock_t lock;
120 int ok; /* Properly detected */
121 int failed;
122 int dma_allocated;
123 int codec_audiodev;
124 int opened;
125 int *osp;
126 int my_audiodev;
127} sscape_info;
128
129static struct sscape_info adev_info = {
130 0
131};
132
133static struct sscape_info *devc = &adev_info;
134static int sscape_mididev = -1;
135
136/* Some older cards have assigned interrupt bits differently than new ones */
137static char valid_interrupts_old[] = {
138 9, 7, 5, 15
139};
140
141static char valid_interrupts_new[] = {
142 9, 5, 7, 10
143};
144
145static char *valid_interrupts = valid_interrupts_new;
146
147/*
148 * See the bottom of the driver. This can be set by spea =0/1.
149 */
150
151#ifdef REVEAL_SPEA
152static char old_hardware = 1;
153#else
154static char old_hardware;
155#endif
156
157static void sleep(unsigned howlong)
158{
159 current->state = TASK_INTERRUPTIBLE;
160 schedule_timeout(howlong);
161}
162
163static unsigned char sscape_read(struct sscape_info *devc, int reg)
164{
165 unsigned long flags;
166 unsigned char val;
167
168 spin_lock_irqsave(&devc->lock,flags);
169 outb(reg, PORT(ODIE_ADDR));
170 val = inb(PORT(ODIE_DATA));
171 spin_unlock_irqrestore(&devc->lock,flags);
172 return val;
173}
174
175static void __sscape_write(int reg, int data)
176{
177 outb(reg, PORT(ODIE_ADDR));
178 outb(data, PORT(ODIE_DATA));
179}
180
181static void sscape_write(struct sscape_info *devc, int reg, int data)
182{
183 unsigned long flags;
184
185 spin_lock_irqsave(&devc->lock,flags);
186 __sscape_write(reg, data);
187 spin_unlock_irqrestore(&devc->lock,flags);
188}
189
190static unsigned char sscape_pnp_read_codec(sscape_info* devc, unsigned char reg)
191{
192 unsigned char res;
193 unsigned long flags;
194
195 spin_lock_irqsave(&devc->lock,flags);
196 outb( reg, devc -> codec);
197 res = inb (devc -> codec + 1);
198 spin_unlock_irqrestore(&devc->lock,flags);
199 return res;
200
201}
202
203static void sscape_pnp_write_codec(sscape_info* devc, unsigned char reg, unsigned char data)
204{
205 unsigned long flags;
206
207 spin_lock_irqsave(&devc->lock,flags);
208 outb( reg, devc -> codec);
209 outb( data, devc -> codec + 1);
210 spin_unlock_irqrestore(&devc->lock,flags);
211}
212
213static void host_open(struct sscape_info *devc)
214{
215 outb((0x00), PORT(HOST_CTRL)); /* Put the board to the host mode */
216}
217
218static void host_close(struct sscape_info *devc)
219{
220 outb((0x03), PORT(HOST_CTRL)); /* Put the board to the MIDI mode */
221}
222
223static int host_write(struct sscape_info *devc, unsigned char *data, int count)
224{
225 unsigned long flags;
226 int i, timeout_val;
227
228 spin_lock_irqsave(&devc->lock,flags);
229 /*
230 * Send the command and data bytes
231 */
232
233 for (i = 0; i < count; i++)
234 {
235 for (timeout_val = 10000; timeout_val > 0; timeout_val--)
236 if (inb(PORT(HOST_CTRL)) & TX_READY)
237 break;
238
239 if (timeout_val <= 0)
240 {
241 spin_unlock_irqrestore(&devc->lock,flags);
242 return 0;
243 }
244 outb(data[i], PORT(HOST_DATA));
245 }
246 spin_unlock_irqrestore(&devc->lock,flags);
247 return 1;
248}
249
250static int host_read(struct sscape_info *devc)
251{
252 unsigned long flags;
253 int timeout_val;
254 unsigned char data;
255
256 spin_lock_irqsave(&devc->lock,flags);
257 /*
258 * Read a byte
259 */
260
261 for (timeout_val = 10000; timeout_val > 0; timeout_val--)
262 if (inb(PORT(HOST_CTRL)) & RX_READY)
263 break;
264
265 if (timeout_val <= 0)
266 {
267 spin_unlock_irqrestore(&devc->lock,flags);
268 return -1;
269 }
270 data = inb(PORT(HOST_DATA));
271 spin_unlock_irqrestore(&devc->lock,flags);
272 return data;
273}
274
275#if 0 /* unused */
276static int host_command1(struct sscape_info *devc, int cmd)
277{
278 unsigned char buf[10];
279 buf[0] = (unsigned char) (cmd & 0xff);
280 return host_write(devc, buf, 1);
281}
282#endif /* unused */
283
284
285static int host_command2(struct sscape_info *devc, int cmd, int parm1)
286{
287 unsigned char buf[10];
288
289 buf[0] = (unsigned char) (cmd & 0xff);
290 buf[1] = (unsigned char) (parm1 & 0xff);
291
292 return host_write(devc, buf, 2);
293}
294
295static int host_command3(struct sscape_info *devc, int cmd, int parm1, int parm2)
296{
297 unsigned char buf[10];
298
299 buf[0] = (unsigned char) (cmd & 0xff);
300 buf[1] = (unsigned char) (parm1 & 0xff);
301 buf[2] = (unsigned char) (parm2 & 0xff);
302 return host_write(devc, buf, 3);
303}
304
305static void set_mt32(struct sscape_info *devc, int value)
306{
307 host_open(devc);
308 host_command2(devc, CMD_SET_MT32, value ? 1 : 0);
309 if (host_read(devc) != CMD_ACK)
310 {
311 /* printk( "SNDSCAPE: Setting MT32 mode failed\n"); */
312 }
313 host_close(devc);
314}
315
316static void set_control(struct sscape_info *devc, int ctrl, int value)
317{
318 host_open(devc);
319 host_command3(devc, CMD_SET_CONTROL, ctrl, value);
320 if (host_read(devc) != CMD_ACK)
321 {
322 /* printk( "SNDSCAPE: Setting control (%d) failed\n", ctrl); */
323 }
324 host_close(devc);
325}
326
327static void do_dma(struct sscape_info *devc, int dma_chan, unsigned long buf, int blk_size, int mode)
328{
329 unsigned char temp;
330
331 if (dma_chan != SSCAPE_DMA_A)
332 {
333 printk(KERN_WARNING "soundscape: Tried to use DMA channel != A. Why?\n");
334 return;
335 }
336 audio_devs[devc->codec_audiodev]->flags &= ~DMA_AUTOMODE;
337 DMAbuf_start_dma(devc->codec_audiodev, buf, blk_size, mode);
338 audio_devs[devc->codec_audiodev]->flags |= DMA_AUTOMODE;
339
340 temp = devc->dma << 4; /* Setup DMA channel select bits */
341 if (devc->dma <= 3)
342 temp |= 0x80; /* 8 bit DMA channel */
343
344 temp |= 1; /* Trigger DMA */
345 sscape_write(devc, GA_DMAA_REG, temp);
346 temp &= 0xfe; /* Clear DMA trigger */
347 sscape_write(devc, GA_DMAA_REG, temp);
348}
349
350static int verify_mpu(struct sscape_info *devc)
351{
352 /*
353 * The SoundScape board could be in three modes (MPU, 8250 and host).
354 * If the card is not in the MPU mode, enabling the MPU driver will
355 * cause infinite loop (the driver believes that there is always some
356 * received data in the buffer.
357 *
358 * Detect this by looking if there are more than 10 received MIDI bytes
359 * (0x00) in the buffer.
360 */
361
362 int i;
363
364 for (i = 0; i < 10; i++)
365 {
366 if (inb(devc->base + HOST_CTRL) & 0x80)
367 return 1;
368
369 if (inb(devc->base) != 0x00)
370 return 1;
371 }
372 printk(KERN_WARNING "SoundScape: The device is not in the MPU-401 mode\n");
373 return 0;
374}
375
376static int sscape_coproc_open(void *dev_info, int sub_device)
377{
378 if (sub_device == COPR_MIDI)
379 {
380 set_mt32(devc, 0);
381 if (!verify_mpu(devc))
382 return -EIO;
383 }
384 return 0;
385}
386
387static void sscape_coproc_close(void *dev_info, int sub_device)
388{
389 struct sscape_info *devc = dev_info;
390 unsigned long flags;
391
392 spin_lock_irqsave(&devc->lock,flags);
393 if (devc->dma_allocated)
394 {
395 __sscape_write(GA_DMAA_REG, 0x20); /* DMA channel disabled */
396 devc->dma_allocated = 0;
397 }
398 spin_unlock_irqrestore(&devc->lock,flags);
399 return;
400}
401
402static void sscape_coproc_reset(void *dev_info)
403{
404}
405
406static int sscape_download_boot(struct sscape_info *devc, unsigned char *block, int size, int flag)
407{
408 unsigned long flags;
409 unsigned char temp;
410 volatile int done, timeout_val;
411 static unsigned char codec_dma_bits;
412
413 if (flag & CPF_FIRST)
414 {
415 /*
416 * First block. Have to allocate DMA and to reset the board
417 * before continuing.
418 */
419
420 spin_lock_irqsave(&devc->lock,flags);
421 codec_dma_bits = sscape_read(devc, GA_CDCFG_REG);
422
423 if (devc->dma_allocated == 0)
424 devc->dma_allocated = 1;
425
426 spin_unlock_irqrestore(&devc->lock,flags);
427
428 sscape_write(devc, GA_HMCTL_REG,
429 (temp = sscape_read(devc, GA_HMCTL_REG)) & 0x3f); /*Reset */
430
431 for (timeout_val = 10000; timeout_val > 0; timeout_val--)
432 sscape_read(devc, GA_HMCTL_REG); /* Delay */
433
434 /* Take board out of reset */
435 sscape_write(devc, GA_HMCTL_REG,
436 (temp = sscape_read(devc, GA_HMCTL_REG)) | 0x80);
437 }
438 /*
439 * Transfer one code block using DMA
440 */
441 if (audio_devs[devc->codec_audiodev]->dmap_out->raw_buf == NULL)
442 {
443 printk(KERN_WARNING "soundscape: DMA buffer not available\n");
444 return 0;
445 }
446 memcpy(audio_devs[devc->codec_audiodev]->dmap_out->raw_buf, block, size);
447
448 spin_lock_irqsave(&devc->lock,flags);
449
450 /******** INTERRUPTS DISABLED NOW ********/
451
452 do_dma(devc, SSCAPE_DMA_A,
453 audio_devs[devc->codec_audiodev]->dmap_out->raw_buf_phys,
454 size, DMA_MODE_WRITE);
455
456 /*
457 * Wait until transfer completes.
458 */
459
460 done = 0;
461 timeout_val = 30;
462 while (!done && timeout_val-- > 0)
463 {
464 int resid;
465
466 if (HZ / 50)
467 sleep(HZ / 50);
468 clear_dma_ff(devc->dma);
469 if ((resid = get_dma_residue(devc->dma)) == 0)
470 done = 1;
471 }
472
473 spin_unlock_irqrestore(&devc->lock,flags);
474 if (!done)
475 return 0;
476
477 if (flag & CPF_LAST)
478 {
479 /*
480 * Take the board out of reset
481 */
482 outb((0x00), PORT(HOST_CTRL));
483 outb((0x00), PORT(MIDI_CTRL));
484
485 temp = sscape_read(devc, GA_HMCTL_REG);
486 temp |= 0x40;
487 sscape_write(devc, GA_HMCTL_REG, temp); /* Kickstart the board */
488
489 /*
490 * Wait until the ODB wakes up
491 */
492 spin_lock_irqsave(&devc->lock,flags);
493 done = 0;
494 timeout_val = 5 * HZ;
495 while (!done && timeout_val-- > 0)
496 {
497 unsigned char x;
498
499 sleep(1);
500 x = inb(PORT(HOST_DATA));
501 if (x == 0xff || x == 0xfe) /* OBP startup acknowledge */
502 {
503 DDB(printk("Soundscape: Acknowledge = %x\n", x));
504 done = 1;
505 }
506 }
507 sscape_write(devc, GA_CDCFG_REG, codec_dma_bits);
508
509 spin_unlock_irqrestore(&devc->lock,flags);
510 if (!done)
511 {
512 printk(KERN_ERR "soundscape: The OBP didn't respond after code download\n");
513 return 0;
514 }
515 spin_lock_irqsave(&devc->lock,flags);
516 done = 0;
517 timeout_val = 5 * HZ;
518 while (!done && timeout_val-- > 0)
519 {
520 sleep(1);
521 if (inb(PORT(HOST_DATA)) == 0xfe) /* Host startup acknowledge */
522 done = 1;
523 }
524 spin_unlock_irqrestore(&devc->lock,flags);
525 if (!done)
526 {
527 printk(KERN_ERR "soundscape: OBP Initialization failed.\n");
528 return 0;
529 }
530 printk(KERN_INFO "SoundScape board initialized OK\n");
531 set_control(devc, CTL_MASTER_VOL, 100);
532 set_control(devc, CTL_SYNTH_VOL, 100);
533
534#ifdef SSCAPE_DEBUG3
535 /*
536 * Temporary debugging aid. Print contents of the registers after
537 * downloading the code.
538 */
539 {
540 int i;
541
542 for (i = 0; i < 13; i++)
543 printk("I%d = %02x (new value)\n", i, sscape_read(devc, i));
544 }
545#endif
546
547 }
548 return 1;
549}
550
551static int download_boot_block(void *dev_info, copr_buffer * buf)
552{
553 if (buf->len <= 0 || buf->len > sizeof(buf->data))
554 return -EINVAL;
555
556 if (!sscape_download_boot(devc, buf->data, buf->len, buf->flags))
557 {
558 printk(KERN_ERR "soundscape: Unable to load microcode block to the OBP.\n");
559 return -EIO;
560 }
561 return 0;
562}
563
564static int sscape_coproc_ioctl(void *dev_info, unsigned int cmd, void __user *arg, int local)
565{
566 copr_buffer *buf;
567 int err;
568
569 switch (cmd)
570 {
571 case SNDCTL_COPR_RESET:
572 sscape_coproc_reset(dev_info);
573 return 0;
574
575 case SNDCTL_COPR_LOAD:
576 buf = (copr_buffer *) vmalloc(sizeof(copr_buffer));
577 if (buf == NULL)
578 return -ENOSPC;
579 if (copy_from_user(buf, arg, sizeof(copr_buffer)))
580 {
581 vfree(buf);
582 return -EFAULT;
583 }
584 err = download_boot_block(dev_info, buf);
585 vfree(buf);
586 return err;
587
588 default:
589 return -EINVAL;
590 }
591}
592
593static coproc_operations sscape_coproc_operations =
594{
595 "SoundScape M68K",
596 THIS_MODULE,
597 sscape_coproc_open,
598 sscape_coproc_close,
599 sscape_coproc_ioctl,
600 sscape_coproc_reset,
601 &adev_info
602};
603
604static struct resource *sscape_ports;
605static int sscape_is_pnp;
606
607static void __init attach_sscape(struct address_info *hw_config)
608{
609#ifndef SSCAPE_REGS
610 /*
611 * Config register values for Spea/V7 Media FX and Ensoniq S-2000.
612 * These values are card
613 * dependent. If you have another SoundScape based card, you have to
614 * find the correct values. Do the following:
615 * - Compile this driver with SSCAPE_DEBUG1 defined.
616 * - Shut down and power off your machine.
617 * - Boot with DOS so that the SSINIT.EXE program is run.
618 * - Warm boot to {Linux|SYSV|BSD} and write down the lines displayed
619 * when detecting the SoundScape.
620 * - Modify the following list to use the values printed during boot.
621 * Undefine the SSCAPE_DEBUG1
622 */
623#define SSCAPE_REGS { \
624/* I0 */ 0x00, \
625/* I1 */ 0xf0, /* Note! Ignored. Set always to 0xf0 */ \
626/* I2 */ 0x20, /* Note! Ignored. Set always to 0x20 */ \
627/* I3 */ 0x20, /* Note! Ignored. Set always to 0x20 */ \
628/* I4 */ 0xf5, /* Ignored */ \
629/* I5 */ 0x10, \
630/* I6 */ 0x00, \
631/* I7 */ 0x2e, /* I7 MEM config A. Likely to vary between models */ \
632/* I8 */ 0x00, /* I8 MEM config B. Likely to vary between models */ \
633/* I9 */ 0x40 /* Ignored */ \
634 }
635#endif
636
637 unsigned long flags;
638 static unsigned char regs[10] = SSCAPE_REGS;
639
640 int i, irq_bits = 0xff;
641
642 if (old_hardware)
643 {
644 valid_interrupts = valid_interrupts_old;
645 conf_printf("Ensoniq SoundScape (old)", hw_config);
646 }
647 else
648 conf_printf("Ensoniq SoundScape", hw_config);
649
650 for (i = 0; i < 4; i++)
651 {
652 if (hw_config->irq == valid_interrupts[i])
653 {
654 irq_bits = i;
655 break;
656 }
657 }
658 if (hw_config->irq > 15 || (regs[4] = irq_bits == 0xff))
659 {
660 printk(KERN_ERR "Invalid IRQ%d\n", hw_config->irq);
661 release_region(devc->base, 2);
662 release_region(devc->base + 2, 6);
663 if (sscape_is_pnp)
664 release_region(devc->codec, 2);
665 return;
666 }
667
668 if (!sscape_is_pnp) {
669
670 spin_lock_irqsave(&devc->lock,flags);
671 /* Host interrupt enable */
672 sscape_write(devc, 1, 0xf0); /* All interrupts enabled */
673 /* DMA A status/trigger register */
674 sscape_write(devc, 2, 0x20); /* DMA channel disabled */
675 /* DMA B status/trigger register */
676 sscape_write(devc, 3, 0x20); /* DMA channel disabled */
677 /* Host interrupt config reg */
678 sscape_write(devc, 4, 0xf0 | (irq_bits << 2) | irq_bits);
679 /* Don't destroy CD-ROM DMA config bits (0xc0) */
680 sscape_write(devc, 5, (regs[5] & 0x3f) | (sscape_read(devc, 5) & 0xc0));
681 /* CD-ROM config (WSS codec actually) */
682 sscape_write(devc, 6, regs[6]);
683 sscape_write(devc, 7, regs[7]);
684 sscape_write(devc, 8, regs[8]);
685 /* Master control reg. Don't modify CR-ROM bits. Disable SB emul */
686 sscape_write(devc, 9, (sscape_read(devc, 9) & 0xf0) | 0x08);
687 spin_unlock_irqrestore(&devc->lock,flags);
688 }
689#ifdef SSCAPE_DEBUG2
690 /*
691 * Temporary debugging aid. Print contents of the registers after
692 * changing them.
693 */
694 {
695 int i;
696
697 for (i = 0; i < 13; i++)
698 printk("I%d = %02x (new value)\n", i, sscape_read(devc, i));
699 }
700#endif
701
702 if (probe_mpu401(hw_config, sscape_ports))
703 hw_config->always_detect = 1;
704 hw_config->name = "SoundScape";
705
706 hw_config->irq *= -1; /* Negative value signals IRQ sharing */
707 attach_mpu401(hw_config, THIS_MODULE);
708 hw_config->irq *= -1; /* Restore it */
709
710 if (hw_config->slots[1] != -1) /* The MPU driver installed itself */
711 {
712 sscape_mididev = hw_config->slots[1];
713 midi_devs[hw_config->slots[1]]->coproc = &sscape_coproc_operations;
714 }
715 sscape_write(devc, GA_INTENA_REG, 0x80); /* Master IRQ enable */
716 devc->ok = 1;
717 devc->failed = 0;
718}
719
720static int detect_ga(sscape_info * devc)
721{
722 unsigned char save;
723
724 DDB(printk("Entered Soundscape detect_ga(%x)\n", devc->base));
725
726 /*
727 * First check that the address register of "ODIE" is
728 * there and that it has exactly 4 writable bits.
729 * First 4 bits
730 */
731
732 if ((save = inb(PORT(ODIE_ADDR))) & 0xf0)
733 {
734 DDB(printk("soundscape: Detect error A\n"));
735 return 0;
736 }
737 outb((0x00), PORT(ODIE_ADDR));
738 if (inb(PORT(ODIE_ADDR)) != 0x00)
739 {
740 DDB(printk("soundscape: Detect error B\n"));
741 return 0;
742 }
743 outb((0xff), PORT(ODIE_ADDR));
744 if (inb(PORT(ODIE_ADDR)) != 0x0f)
745 {
746 DDB(printk("soundscape: Detect error C\n"));
747 return 0;
748 }
749 outb((save), PORT(ODIE_ADDR));
750
751 /*
752 * Now verify that some indirect registers return zero on some bits.
753 * This may break the driver with some future revisions of "ODIE" but...
754 */
755
756 if (sscape_read(devc, 0) & 0x0c)
757 {
758 DDB(printk("soundscape: Detect error D (%x)\n", sscape_read(devc, 0)));
759 return 0;
760 }
761 if (sscape_read(devc, 1) & 0x0f)
762 {
763 DDB(printk("soundscape: Detect error E\n"));
764 return 0;
765 }
766 if (sscape_read(devc, 5) & 0x0f)
767 {
768 DDB(printk("soundscape: Detect error F\n"));
769 return 0;
770 }
771 return 1;
772}
773
774static int sscape_read_host_ctrl(sscape_info* devc)
775{
776 return host_read(devc);
777}
778
779static void sscape_write_host_ctrl2(sscape_info *devc, int a, int b)
780{
781 host_command2(devc, a, b);
782}
783
784static int sscape_alloc_dma(sscape_info *devc)
785{
786 char *start_addr, *end_addr;
787 int dma_pagesize;
788 int sz, size;
789 struct page *page;
790
791 if (devc->raw_buf != NULL) return 0; /* Already done */
792 dma_pagesize = (devc->dma < 4) ? (64 * 1024) : (128 * 1024);
793 devc->raw_buf = NULL;
794 devc->buffsize = 8192*4;
795 if (devc->buffsize > dma_pagesize) devc->buffsize = dma_pagesize;
796 start_addr = NULL;
797 /*
798 * Now loop until we get a free buffer. Try to get smaller buffer if
799 * it fails. Don't accept smaller than 8k buffer for performance
800 * reasons.
801 */
802 while (start_addr == NULL && devc->buffsize > PAGE_SIZE) {
803 for (sz = 0, size = PAGE_SIZE; size < devc->buffsize; sz++, size <<= 1);
804 devc->buffsize = PAGE_SIZE * (1 << sz);
805 start_addr = (char *) __get_free_pages(GFP_ATOMIC|GFP_DMA, sz);
806 if (start_addr == NULL) devc->buffsize /= 2;
807 }
808
809 if (start_addr == NULL) {
810 printk(KERN_ERR "sscape pnp init error: Couldn't allocate DMA buffer\n");
811 return 0;
812 } else {
813 /* make some checks */
814 end_addr = start_addr + devc->buffsize - 1;
815 /* now check if it fits into the same dma-pagesize */
816
817 if (((long) start_addr & ~(dma_pagesize - 1)) != ((long) end_addr & ~(dma_pagesize - 1))
818 || end_addr >= (char *) (MAX_DMA_ADDRESS)) {
819 printk(KERN_ERR "sscape pnp: Got invalid address 0x%lx for %db DMA-buffer\n", (long) start_addr, devc->buffsize);
820 return 0;
821 }
822 }
823 devc->raw_buf = start_addr;
824 devc->raw_buf_phys = virt_to_bus(start_addr);
825
826 for (page = virt_to_page(start_addr); page <= virt_to_page(end_addr); page++)
827 SetPageReserved(page);
828 return 1;
829}
830
831static void sscape_free_dma(sscape_info *devc)
832{
833 int sz, size;
834 unsigned long start_addr, end_addr;
835 struct page *page;
836
837 if (devc->raw_buf == NULL) return;
838 for (sz = 0, size = PAGE_SIZE; size < devc->buffsize; sz++, size <<= 1);
839 start_addr = (unsigned long) devc->raw_buf;
840 end_addr = start_addr + devc->buffsize;
841
842 for (page = virt_to_page(start_addr); page <= virt_to_page(end_addr); page++)
843 ClearPageReserved(page);
844
845 free_pages((unsigned long) devc->raw_buf, sz);
846 devc->raw_buf = NULL;
847}
848
849/* Intel version !!!!!!!!! */
850
851static int sscape_start_dma(int chan, unsigned long physaddr, int count, int dma_mode)
852{
853 unsigned long flags;
854
855 flags = claim_dma_lock();
856 disable_dma(chan);
857 clear_dma_ff(chan);
858 set_dma_mode(chan, dma_mode);
859 set_dma_addr(chan, physaddr);
860 set_dma_count(chan, count);
861 enable_dma(chan);
862 release_dma_lock(flags);
863 return 0;
864}
865
866static void sscape_pnp_start_dma(sscape_info* devc, int arg )
867{
868 int reg;
869 if (arg == 0) reg = 2;
870 else reg = 3;
871
872 sscape_write(devc, reg, sscape_read( devc, reg) | 0x01);
873 sscape_write(devc, reg, sscape_read( devc, reg) & 0xFE);
874}
875
876static int sscape_pnp_wait_dma (sscape_info* devc, int arg )
877{
878 int reg;
879 unsigned long i;
880 unsigned char d;
881
882 if (arg == 0) reg = 2;
883 else reg = 3;
884
885 sleep ( 1 );
886 i = 0;
887 do {
888 d = sscape_read(devc, reg) & 1;
889 if ( d == 1) break;
890 i++;
891 } while (i < 500000);
892 d = sscape_read(devc, reg) & 1;
893 return d;
894}
895
896static int sscape_pnp_alloc_dma(sscape_info* devc)
897{
898 /* printk(KERN_INFO "sscape: requesting dma\n"); */
899 if (request_dma(devc -> dma, "sscape")) return 0;
900 /* printk(KERN_INFO "sscape: dma channel allocated\n"); */
901 if (!sscape_alloc_dma(devc)) {
902 free_dma(devc -> dma);
903 return 0;
904 };
905 return 1;
906}
907
908static void sscape_pnp_free_dma(sscape_info* devc)
909{
910 sscape_free_dma( devc);
911 free_dma(devc -> dma );
912 /* printk(KERN_INFO "sscape: dma released\n"); */
913}
914
915static int sscape_pnp_upload_file(sscape_info* devc, char* fn)
916{
917 int done = 0;
918 int timeout_val;
919 char* data,*dt;
920 int len,l;
921 unsigned long flags;
922
923 sscape_write( devc, 9, sscape_read(devc, 9 ) & 0x3F );
924 sscape_write( devc, 2, (devc -> dma << 4) | 0x80 );
925 sscape_write( devc, 3, 0x20 );
926 sscape_write( devc, 9, sscape_read( devc, 9 ) | 0x80 );
927
928 len = mod_firmware_load(fn, &data);
929 if (len == 0) {
930 printk(KERN_ERR "sscape: file not found: %s\n", fn);
931 return 0;
932 }
933 dt = data;
934 spin_lock_irqsave(&devc->lock,flags);
935 while ( len > 0 ) {
936 if (len > devc -> buffsize) l = devc->buffsize;
937 else l = len;
938 len -= l;
939 memcpy(devc->raw_buf, dt, l); dt += l;
940 sscape_start_dma(devc->dma, devc->raw_buf_phys, l, 0x48);
941 sscape_pnp_start_dma ( devc, 0 );
942 if (sscape_pnp_wait_dma ( devc, 0 ) == 0) {
943 spin_unlock_irqrestore(&devc->lock,flags);
944 return 0;
945 }
946 }
947
948 spin_unlock_irqrestore(&devc->lock,flags);
949 vfree(data);
950
951 outb(0, devc -> base + 2);
952 outb(0, devc -> base);
953
954 sscape_write ( devc, 9, sscape_read( devc, 9 ) | 0x40);
955
956 timeout_val = 5 * HZ;
957 while (!done && timeout_val-- > 0)
958 {
959 unsigned char x;
960 sleep(1);
961 x = inb( devc -> base + 3);
962 if (x == 0xff || x == 0xfe) /* OBP startup acknowledge */
963 {
964 //printk(KERN_ERR "Soundscape: Acknowledge = %x\n", x);
965 done = 1;
966 }
967 }
968 timeout_val = 5 * HZ;
969 done = 0;
970 while (!done && timeout_val-- > 0)
971 {
972 unsigned char x;
973 sleep(1);
974 x = inb( devc -> base + 3);
975 if (x == 0xfe) /* OBP startup acknowledge */
976 {
977 //printk(KERN_ERR "Soundscape: Acknowledge = %x\n", x);
978 done = 1;
979 }
980 }
981
982 if ( !done ) printk(KERN_ERR "soundscape: OBP Initialization failed.\n");
983
984 sscape_write( devc, 2, devc->ic_type == IC_ODIE ? 0x70 : 0x40);
985 sscape_write( devc, 3, (devc -> dma << 4) + 0x80);
986 return 1;
987}
988
989static void __init sscape_pnp_init_hw(sscape_info* devc)
990{
991 unsigned char midi_irq = 0, sb_irq = 0;
992 unsigned i;
993 static char code_file_name[23] = "/sndscape/sndscape.cox";
994
995 int sscape_joystic_enable = 0x7f;
996 int sscape_mic_enable = 0;
997 int sscape_ext_midi = 0;
998
999 if ( !sscape_pnp_alloc_dma(devc) ) {
1000 printk(KERN_ERR "sscape: faild to allocate dma\n");
1001 return;
1002 }
1003
1004 for (i = 0; i < 4; i++) {
1005 if ( devc -> irq == valid_interrupts[i] )
1006 midi_irq = i;
1007 if ( devc -> codec_irq == valid_interrupts[i] )
1008 sb_irq = i;
1009 }
1010
1011 sscape_write( devc, 5, 0x50);
1012 sscape_write( devc, 7, 0x2e);
1013 sscape_write( devc, 8, 0x00);
1014
1015 sscape_write( devc, 2, devc->ic_type == IC_ODIE ? 0x70 : 0x40);
1016 sscape_write( devc, 3, ( devc -> dma << 4) | 0x80);
1017
1018 sscape_write (devc, 4, 0xF0 | (midi_irq<<2) | midi_irq);
1019
1020 i = 0x10; //sscape_read(devc, 9) & (devc->ic_type == IC_ODIE ? 0xf0 : 0xc0);
1021 if (sscape_joystic_enable) i |= 8;
1022
1023 sscape_write (devc, 9, i);
1024 sscape_write (devc, 6, 0x80);
1025 sscape_write (devc, 1, 0x80);
1026
1027 if (devc -> codec_type == 2) {
1028 sscape_pnp_write_codec( devc, 0x0C, 0x50);
1029 sscape_pnp_write_codec( devc, 0x10, sscape_pnp_read_codec( devc, 0x10) & 0x3F);
1030 sscape_pnp_write_codec( devc, 0x11, sscape_pnp_read_codec( devc, 0x11) | 0xC0);
1031 sscape_pnp_write_codec( devc, 29, 0x20);
1032 }
1033
1034 if (sscape_pnp_upload_file(devc, "/sndscape/scope.cod") == 0 ) {
1035 printk(KERN_ERR "sscape: faild to upload file /sndscape/scope.cod\n");
1036 sscape_pnp_free_dma(devc);
1037 return;
1038 }
1039
1040 i = sscape_read_host_ctrl( devc );
1041
1042 if ( (i & 0x0F) > 7 ) {
1043 printk(KERN_ERR "sscape: scope.cod faild\n");
1044 sscape_pnp_free_dma(devc);
1045 return;
1046 }
1047 if ( i & 0x10 ) sscape_write( devc, 7, 0x2F);
1048 code_file_name[21] = (char) ( i & 0x0F) + 0x30;
1049 if (sscape_pnp_upload_file( devc, code_file_name) == 0) {
1050 printk(KERN_ERR "sscape: faild to upload file %s\n", code_file_name);
1051 sscape_pnp_free_dma(devc);
1052 return;
1053 }
1054
1055 if (devc->ic_type != IC_ODIE) {
1056 sscape_pnp_write_codec( devc, 10, (sscape_pnp_read_codec(devc, 10) & 0x7f) |
1057 ( sscape_mic_enable == 0 ? 0x00 : 0x80) );
1058 }
1059 sscape_write_host_ctrl2( devc, 0x84, 0x64 ); /* MIDI volume */
1060 sscape_write_host_ctrl2( devc, 0x86, 0x64 ); /* MIDI volume?? */
1061 sscape_write_host_ctrl2( devc, 0x8A, sscape_ext_midi);
1062
1063 sscape_pnp_write_codec ( devc, 6, 0x3f ); //WAV_VOL
1064 sscape_pnp_write_codec ( devc, 7, 0x3f ); //WAV_VOL
1065 sscape_pnp_write_codec ( devc, 2, 0x1F ); //WD_CDXVOLL
1066 sscape_pnp_write_codec ( devc, 3, 0x1F ); //WD_CDXVOLR
1067
1068 if (devc -> codec_type == 1) {
1069 sscape_pnp_write_codec ( devc, 4, 0x1F );
1070 sscape_pnp_write_codec ( devc, 5, 0x1F );
1071 sscape_write_host_ctrl2( devc, 0x88, sscape_mic_enable);
1072 } else {
1073 int t;
1074 sscape_pnp_write_codec ( devc, 0x10, 0x1F << 1);
1075 sscape_pnp_write_codec ( devc, 0x11, 0xC0 | (0x1F << 1));
1076
1077 t = sscape_pnp_read_codec( devc, 0x00) & 0xDF;
1078 if ( (sscape_mic_enable == 0)) t |= 0;
1079 else t |= 0x20;
1080 sscape_pnp_write_codec ( devc, 0x00, t);
1081 t = sscape_pnp_read_codec( devc, 0x01) & 0xDF;
1082 if ( (sscape_mic_enable == 0) ) t |= 0;
1083 else t |= 0x20;
1084 sscape_pnp_write_codec ( devc, 0x01, t);
1085 sscape_pnp_write_codec ( devc, 0x40 | 29 , 0x20);
1086 outb(0, devc -> codec);
1087 }
1088 if (devc -> ic_type == IC_OPUS ) {
1089 int i = sscape_read( devc, 9 );
1090 sscape_write( devc, 9, i | 3 );
1091 sscape_write( devc, 3, 0x40);
1092
1093 if (request_region(0x228, 1, "sscape setup junk")) {
1094 outb(0, 0x228);
1095 release_region(0x228,1);
1096 }
1097 sscape_write( devc, 3, (devc -> dma << 4) | 0x80);
1098 sscape_write( devc, 9, i );
1099 }
1100
1101 host_close ( devc );
1102 sscape_pnp_free_dma(devc);
1103}
1104
1105static int __init detect_sscape_pnp(sscape_info* devc)
1106{
1107 long i, irq_bits = 0xff;
1108 unsigned int d;
1109
1110 DDB(printk("Entered detect_sscape_pnp(%x)\n", devc->base));
1111
1112 if (!request_region(devc->codec, 2, "sscape codec")) {
1113 printk(KERN_ERR "detect_sscape_pnp: port %x is not free\n", devc->codec);
1114 return 0;
1115 }
1116
1117 if ((inb(devc->base + 2) & 0x78) != 0)
1118 goto fail;
1119
1120 d = inb ( devc -> base + 4) & 0xF0;
1121 if (d & 0x80)
1122 goto fail;
1123
1124 if (d == 0) {
1125 devc->codec_type = 1;
1126 devc->ic_type = IC_ODIE;
1127 } else if ( (d & 0x60) != 0) {
1128 devc->codec_type = 2;
1129 devc->ic_type = IC_OPUS;
1130 } else if ( (d & 0x40) != 0) { /* WTF? */
1131 devc->codec_type = 2;
1132 devc->ic_type = IC_ODIE;
1133 } else
1134 goto fail;
1135
1136 sscape_is_pnp = 1;
1137
1138 outb(0xFA, devc -> base+4);
1139 if ((inb( devc -> base+4) & 0x9F) != 0x0A)
1140 goto fail;
1141 outb(0xFE, devc -> base+4);
1142 if ( (inb(devc -> base+4) & 0x9F) != 0x0E)
1143 goto fail;
1144 if ( (inb(devc -> base+5) & 0x9F) != 0x0E)
1145 goto fail;
1146
1147 if (devc->codec_type == 2) {
1148 if (devc->codec != devc->base + 8) {
1149 printk("soundscape warning: incorrect codec port specified\n");
1150 goto fail;
1151 }
1152 d = 0x10 | (sscape_read(devc, 9) & 0xCF);
1153 sscape_write(devc, 9, d);
1154 sscape_write(devc, 6, 0x80);
1155 } else {
1156 //todo: check codec is not base + 8
1157 }
1158
1159 d = (sscape_read(devc, 9) & 0x3F) | 0xC0;
1160 sscape_write(devc, 9, d);
1161
1162 for (i = 0; i < 550000; i++)
1163 if ( !(inb(devc -> codec) & 0x80) ) break;
1164
1165 d = inb(devc -> codec);
1166 if (d & 0x80)
1167 goto fail;
1168 if ( inb(devc -> codec + 2) == 0xFF)
1169 goto fail;
1170
1171 sscape_write(devc, 9, sscape_read(devc, 9) & 0x3F );
1172
1173 d = inb(devc -> codec) & 0x80;
1174 if ( d == 0) {
1175 printk(KERN_INFO "soundscape: hardware detected\n");
1176 valid_interrupts = valid_interrupts_new;
1177 } else {
1178 printk(KERN_INFO "soundscape: board looks like media fx\n");
1179 valid_interrupts = valid_interrupts_old;
1180 old_hardware = 1;
1181 }
1182
1183 sscape_write( devc, 9, 0xC0 | (sscape_read(devc, 9) & 0x3F) );
1184
1185 for (i = 0; i < 550000; i++)
1186 if ( !(inb(devc -> codec) & 0x80))
1187 break;
1188
1189 sscape_pnp_init_hw(devc);
1190
1191 for (i = 0; i < 4; i++)
1192 {
1193 if (devc->codec_irq == valid_interrupts[i]) {
1194 irq_bits = i;
1195 break;
1196 }
1197 }
1198 sscape_write(devc, GA_INTENA_REG, 0x00);
1199 sscape_write(devc, GA_DMACFG_REG, 0x50);
1200 sscape_write(devc, GA_DMAA_REG, 0x70);
1201 sscape_write(devc, GA_DMAB_REG, 0x20);
1202 sscape_write(devc, GA_INTCFG_REG, 0xf0);
1203 sscape_write(devc, GA_CDCFG_REG, 0x89 | (devc->dma << 4) | (irq_bits << 1));
1204
1205 sscape_pnp_write_codec( devc, 0, sscape_pnp_read_codec( devc, 0) | 0x20);
1206 sscape_pnp_write_codec( devc, 0, sscape_pnp_read_codec( devc, 1) | 0x20);
1207
1208 return 1;
1209fail:
1210 release_region(devc->codec, 2);
1211 return 0;
1212}
1213
1214static int __init probe_sscape(struct address_info *hw_config)
1215{
1216 devc->base = hw_config->io_base;
1217 devc->irq = hw_config->irq;
1218 devc->dma = hw_config->dma;
1219 devc->osp = hw_config->osp;
1220
1221#ifdef SSCAPE_DEBUG1
1222 /*
1223 * Temporary debugging aid. Print contents of the registers before
1224 * changing them.
1225 */
1226 {
1227 int i;
1228
1229 for (i = 0; i < 13; i++)
1230 printk("I%d = %02x (old value)\n", i, sscape_read(devc, i));
1231 }
1232#endif
1233 devc->failed = 1;
1234
1235 sscape_ports = request_region(devc->base, 2, "mpu401");
1236 if (!sscape_ports)
1237 return 0;
1238
1239 if (!request_region(devc->base + 2, 6, "SoundScape")) {
1240 release_region(devc->base, 2);
1241 return 0;
1242 }
1243
1244 if (!detect_ga(devc)) {
1245 if (detect_sscape_pnp(devc))
1246 return 1;
1247 release_region(devc->base, 2);
1248 release_region(devc->base + 2, 6);
1249 return 0;
1250 }
1251
1252 if (old_hardware) /* Check that it's really an old Spea/Reveal card. */
1253 {
1254 unsigned char tmp;
1255 int cc;
1256
1257 if (!((tmp = sscape_read(devc, GA_HMCTL_REG)) & 0xc0))
1258 {
1259 sscape_write(devc, GA_HMCTL_REG, tmp | 0x80);
1260 for (cc = 0; cc < 200000; ++cc)
1261 inb(devc->base + ODIE_ADDR);
1262 }
1263 }
1264 return 1;
1265}
1266
1267static int __init init_ss_ms_sound(struct address_info *hw_config)
1268{
1269 int i, irq_bits = 0xff;
1270 int ad_flags = 0;
1271 struct resource *ports;
1272
1273 if (devc->failed)
1274 {
1275 printk(KERN_ERR "soundscape: Card not detected\n");
1276 return 0;
1277 }
1278 if (devc->ok == 0)
1279 {
1280 printk(KERN_ERR "soundscape: Invalid initialization order.\n");
1281 return 0;
1282 }
1283 for (i = 0; i < 4; i++)
1284 {
1285 if (hw_config->irq == valid_interrupts[i])
1286 {
1287 irq_bits = i;
1288 break;
1289 }
1290 }
1291 if (irq_bits == 0xff) {
1292 printk(KERN_ERR "soundscape: Invalid MSS IRQ%d\n", hw_config->irq);
1293 return 0;
1294 }
1295
1296 if (old_hardware)
1297 ad_flags = 0x12345677; /* Tell that we may have a CS4248 chip (Spea-V7 Media FX) */
1298 else if (sscape_is_pnp)
1299 ad_flags = 0x87654321; /* Tell that we have a soundscape pnp with 1845 chip */
1300
1301 ports = request_region(hw_config->io_base, 4, "ad1848");
1302 if (!ports) {
1303 printk(KERN_ERR "soundscape: ports busy\n");
1304 return 0;
1305 }
1306
1307 if (!ad1848_detect(ports, &ad_flags, hw_config->osp)) {
1308 release_region(hw_config->io_base, 4);
1309 return 0;
1310 }
1311
1312 if (!sscape_is_pnp) /*pnp is already setup*/
1313 {
1314 /*
1315 * Setup the DMA polarity.
1316 */
1317 sscape_write(devc, GA_DMACFG_REG, 0x50);
1318
1319 /*
1320 * Take the gate-array off of the DMA channel.
1321 */
1322 sscape_write(devc, GA_DMAB_REG, 0x20);
1323
1324 /*
1325 * Init the AD1848 (CD-ROM) config reg.
1326 */
1327 sscape_write(devc, GA_CDCFG_REG, 0x89 | (hw_config->dma << 4) | (irq_bits << 1));
1328 }
1329
1330 if (hw_config->irq == devc->irq)
1331 printk(KERN_WARNING "soundscape: Warning! The WSS mode can't share IRQ with MIDI\n");
1332
1333 hw_config->slots[0] = ad1848_init(
1334 sscape_is_pnp ? "SoundScape" : "SoundScape PNP",
1335 ports,
1336 hw_config->irq,
1337 hw_config->dma,
1338 hw_config->dma,
1339 0,
1340 devc->osp,
1341 THIS_MODULE);
1342
1343
1344 if (hw_config->slots[0] != -1) /* The AD1848 driver installed itself */
1345 {
1346 audio_devs[hw_config->slots[0]]->coproc = &sscape_coproc_operations;
1347 devc->codec_audiodev = hw_config->slots[0];
1348 devc->my_audiodev = hw_config->slots[0];
1349
1350 /* Set proper routings here (what are they) */
1351 AD1848_REROUTE(SOUND_MIXER_LINE1, SOUND_MIXER_LINE);
1352 }
1353
1354#ifdef SSCAPE_DEBUG5
1355 /*
1356 * Temporary debugging aid. Print contents of the registers
1357 * after the AD1848 device has been initialized.
1358 */
1359 {
1360 int i;
1361
1362 for (i = 0; i < 13; i++)
1363 printk("I%d = %02x\n", i, sscape_read(devc, i));
1364 }
1365#endif
1366 return 1;
1367}
1368
1369static void __exit unload_sscape(struct address_info *hw_config)
1370{
1371 release_region(devc->base + 2, 6);
1372 unload_mpu401(hw_config);
1373 if (sscape_is_pnp)
1374 release_region(devc->codec, 2);
1375}
1376
1377static void __exit unload_ss_ms_sound(struct address_info *hw_config)
1378{
1379 ad1848_unload(hw_config->io_base,
1380 hw_config->irq,
1381 devc->dma,
1382 devc->dma,
1383 0);
1384 sound_unload_audiodev(hw_config->slots[0]);
1385}
1386
1387static struct address_info cfg;
1388static struct address_info cfg_mpu;
1389
1390static int __initdata spea = -1;
1391static int mss = 0;
1392static int __initdata dma = -1;
1393static int __initdata irq = -1;
1394static int __initdata io = -1;
1395static int __initdata mpu_irq = -1;
1396static int __initdata mpu_io = -1;
1397
1398module_param(dma, int, 0);
1399module_param(irq, int, 0);
1400module_param(io, int, 0);
1401module_param(spea, int, 0); /* spea=0/1 set the old_hardware */
1402module_param(mpu_irq, int, 0);
1403module_param(mpu_io, int, 0);
1404module_param(mss, int, 0);
1405
1406static int __init init_sscape(void)
1407{
1408 printk(KERN_INFO "Soundscape driver Copyright (C) by Hannu Savolainen 1993-1996\n");
1409
1410 cfg.irq = irq;
1411 cfg.dma = dma;
1412 cfg.io_base = io;
1413
1414 cfg_mpu.irq = mpu_irq;
1415 cfg_mpu.io_base = mpu_io;
1416 /* WEH - Try to get right dma channel */
1417 cfg_mpu.dma = dma;
1418
1419 devc->codec = cfg.io_base;
1420 devc->codec_irq = cfg.irq;
1421 devc->codec_type = 0;
1422 devc->ic_type = 0;
1423 devc->raw_buf = NULL;
1424 spin_lock_init(&devc->lock);
1425
1426 if (cfg.dma == -1 || cfg.irq == -1 || cfg.io_base == -1) {
1427 printk(KERN_ERR "DMA, IRQ, and IO port must be specified.\n");
1428 return -EINVAL;
1429 }
1430
1431 if (cfg_mpu.irq == -1 && cfg_mpu.io_base != -1) {
1432 printk(KERN_ERR "MPU_IRQ must be specified if MPU_IO is set.\n");
1433 return -EINVAL;
1434 }
1435
1436 if(spea != -1) {
1437 old_hardware = spea;
1438 printk(KERN_INFO "Forcing %s hardware support.\n",
1439 spea?"new":"old");
1440 }
1441 if (probe_sscape(&cfg_mpu) == 0)
1442 return -ENODEV;
1443
1444 attach_sscape(&cfg_mpu);
1445
1446 mss = init_ss_ms_sound(&cfg);
1447
1448 return 0;
1449}
1450
1451static void __exit cleanup_sscape(void)
1452{
1453 if (mss)
1454 unload_ss_ms_sound(&cfg);
1455 unload_sscape(&cfg_mpu);
1456}
1457
1458module_init(init_sscape);
1459module_exit(cleanup_sscape);
1460
1461#ifndef MODULE
1462static int __init setup_sscape(char *str)
1463{
1464 /* io, irq, dma, mpu_io, mpu_irq */
1465 int ints[6];
1466
1467 str = get_options(str, ARRAY_SIZE(ints), ints);
1468
1469 io = ints[1];
1470 irq = ints[2];
1471 dma = ints[3];
1472 mpu_io = ints[4];
1473 mpu_irq = ints[5];
1474
1475 return 1;
1476}
1477
1478__setup("sscape=", setup_sscape);
1479#endif
1480MODULE_LICENSE("GPL");
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/v_midi.h b/sound/oss/v_midi.h
index 1b86cb45c607..08e2185ee816 100644
--- a/sound/oss/v_midi.h
+++ b/sound/oss/v_midi.h
@@ -2,9 +2,9 @@ typedef struct vmidi_devc {
2 int dev; 2 int dev;
3 3
4 /* State variables */ 4 /* State variables */
5 int opened; 5 int opened;
6 spinlock_t lock; 6 spinlock_t lock;
7 7
8 /* MIDI fields */ 8 /* MIDI fields */
9 int my_mididev; 9 int my_mididev;
10 int pair_mididev; 10 int pair_mididev;
@@ -12,4 +12,3 @@ typedef struct vmidi_devc {
12 int intr_active; 12 int intr_active;
13 void (*midi_input_intr) (int dev, unsigned char data); 13 void (*midi_input_intr) (int dev, unsigned char data);
14 } vmidi_devc; 14 } vmidi_devc;
15
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 75c602b5b132..1298c68d6bf0 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -570,6 +570,7 @@ config SND_ICE1712
570 tristate "ICEnsemble ICE1712 (Envy24)" 570 tristate "ICEnsemble ICE1712 (Envy24)"
571 select SND_MPU401_UART 571 select SND_MPU401_UART
572 select SND_AC97_CODEC 572 select SND_AC97_CODEC
573 select BITREVERSE
573 help 574 help
574 Say Y here to include support for soundcards based on the 575 Say Y here to include support for soundcards based on the
575 ICE1712 (Envy24) chip. 576 ICE1712 (Envy24) chip.
@@ -788,6 +789,7 @@ config SND_VIRTUOSO
788 Say Y here to include support for sound cards based on the 789 Say Y here to include support for sound cards based on the
789 Asus AV100/AV200 chips, i.e., Xonar D1, DX, D2, D2X, 790 Asus AV100/AV200 chips, i.e., Xonar D1, DX, D2, D2X,
790 Essence ST (Deluxe), and Essence STX. 791 Essence ST (Deluxe), and Essence STX.
792 Support for the DS is experimental.
791 Support for the HDAV1.3 (Deluxe) is very experimental. 793 Support for the HDAV1.3 (Deluxe) is very experimental.
792 794
793 To compile this driver as a module, choose M here: the module 795 To compile this driver as a module, choose M here: the module
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
index 78288dbfc17a..a7630e9edf8a 100644
--- a/sound/pci/ac97/ac97_codec.c
+++ b/sound/pci/ac97/ac97_codec.c
@@ -83,6 +83,7 @@ static const struct ac97_codec_id snd_ac97_codec_id_vendors[] = {
83{ 0x4e534300, 0xffffff00, "National Semiconductor", NULL, NULL }, 83{ 0x4e534300, 0xffffff00, "National Semiconductor", NULL, NULL },
84{ 0x50534300, 0xffffff00, "Philips", NULL, NULL }, 84{ 0x50534300, 0xffffff00, "Philips", NULL, NULL },
85{ 0x53494c00, 0xffffff00, "Silicon Laboratory", NULL, NULL }, 85{ 0x53494c00, 0xffffff00, "Silicon Laboratory", NULL, NULL },
86{ 0x53544d00, 0xffffff00, "STMicroelectronics", NULL, NULL },
86{ 0x54524100, 0xffffff00, "TriTech", NULL, NULL }, 87{ 0x54524100, 0xffffff00, "TriTech", NULL, NULL },
87{ 0x54584e00, 0xffffff00, "Texas Instruments", NULL, NULL }, 88{ 0x54584e00, 0xffffff00, "Texas Instruments", NULL, NULL },
88{ 0x56494100, 0xffffff00, "VIA Technologies", NULL, NULL }, 89{ 0x56494100, 0xffffff00, "VIA Technologies", NULL, NULL },
@@ -161,6 +162,7 @@ static const struct ac97_codec_id snd_ac97_codec_ids[] = {
161{ 0x4e534350, 0xffffffff, "LM4550", patch_lm4550, NULL }, // volume wrap fix 162{ 0x4e534350, 0xffffffff, "LM4550", patch_lm4550, NULL }, // volume wrap fix
162{ 0x50534304, 0xffffffff, "UCB1400", patch_ucb1400, NULL }, 163{ 0x50534304, 0xffffffff, "UCB1400", patch_ucb1400, NULL },
163{ 0x53494c20, 0xffffffe0, "Si3036,8", mpatch_si3036, mpatch_si3036, AC97_MODEM_PATCH }, 164{ 0x53494c20, 0xffffffe0, "Si3036,8", mpatch_si3036, mpatch_si3036, AC97_MODEM_PATCH },
165{ 0x53544d02, 0xffffffff, "ST7597", NULL, NULL },
164{ 0x54524102, 0xffffffff, "TR28022", NULL, NULL }, 166{ 0x54524102, 0xffffffff, "TR28022", NULL, NULL },
165{ 0x54524103, 0xffffffff, "TR28023", NULL, NULL }, 167{ 0x54524103, 0xffffffff, "TR28023", NULL, NULL },
166{ 0x54524106, 0xffffffff, "TR28026", NULL, NULL }, 168{ 0x54524106, 0xffffffff, "TR28026", NULL, NULL },
@@ -213,6 +215,14 @@ static int snd_ac97_valid_reg(struct snd_ac97 *ac97, unsigned short reg)
213{ 215{
214 /* filter some registers for buggy codecs */ 216 /* filter some registers for buggy codecs */
215 switch (ac97->id) { 217 switch (ac97->id) {
218 case AC97_ID_ST_AC97_ID4:
219 if (reg == 0x08)
220 return 0;
221 /* fall through */
222 case AC97_ID_ST7597:
223 if (reg == 0x22 || reg == 0x7a)
224 return 1;
225 /* fall through */
216 case AC97_ID_AK4540: 226 case AC97_ID_AK4540:
217 case AC97_ID_AK4542: 227 case AC97_ID_AK4542:
218 if (reg <= 0x1c || reg == 0x20 || reg == 0x26 || reg >= 0x7c) 228 if (reg <= 0x1c || reg == 0x20 || reg == 0x26 || reg >= 0x7c)
@@ -603,8 +613,8 @@ AC97_SINGLE("Tone Control - Treble", AC97_MASTER_TONE, 0, 15, 1)
603}; 613};
604 614
605static const struct snd_kcontrol_new snd_ac97_controls_pc_beep[2] = { 615static const struct snd_kcontrol_new snd_ac97_controls_pc_beep[2] = {
606AC97_SINGLE("PC Speaker Playback Switch", AC97_PC_BEEP, 15, 1, 1), 616AC97_SINGLE("Beep Playback Switch", AC97_PC_BEEP, 15, 1, 1),
607AC97_SINGLE("PC Speaker Playback Volume", AC97_PC_BEEP, 1, 15, 1) 617AC97_SINGLE("Beep Playback Volume", AC97_PC_BEEP, 1, 15, 1)
608}; 618};
609 619
610static const struct snd_kcontrol_new snd_ac97_controls_mic_boost = 620static const struct snd_kcontrol_new snd_ac97_controls_mic_boost =
@@ -1393,7 +1403,7 @@ static int snd_ac97_mixer_build(struct snd_ac97 * ac97)
1393 } 1403 }
1394 } 1404 }
1395 1405
1396 /* build PC Speaker controls */ 1406 /* build Beep controls */
1397 if (!(ac97->flags & AC97_HAS_NO_PC_BEEP) && 1407 if (!(ac97->flags & AC97_HAS_NO_PC_BEEP) &&
1398 ((ac97->flags & AC97_HAS_PC_BEEP) || 1408 ((ac97->flags & AC97_HAS_PC_BEEP) ||
1399 snd_ac97_try_volume_mix(ac97, AC97_PC_BEEP))) { 1409 snd_ac97_try_volume_mix(ac97, AC97_PC_BEEP))) {
@@ -2122,7 +2132,7 @@ int snd_ac97_mixer(struct snd_ac97_bus *bus, struct snd_ac97_template *template,
2122 } 2132 }
2123 /* nothing should be in powerdown mode */ 2133 /* nothing should be in powerdown mode */
2124 snd_ac97_write_cache(ac97, AC97_GENERAL_PURPOSE, 0); 2134 snd_ac97_write_cache(ac97, AC97_GENERAL_PURPOSE, 0);
2125 end_time = jiffies + msecs_to_jiffies(120); 2135 end_time = jiffies + msecs_to_jiffies(5000);
2126 do { 2136 do {
2127 if ((snd_ac97_read(ac97, AC97_POWERDOWN) & 0x0f) == 0x0f) 2137 if ((snd_ac97_read(ac97, AC97_POWERDOWN) & 0x0f) == 0x0f)
2128 goto __ready_ok; 2138 goto __ready_ok;
diff --git a/sound/pci/ac97/ac97_id.h b/sound/pci/ac97/ac97_id.h
index c129492c82b3..d603147c4a96 100644
--- a/sound/pci/ac97/ac97_id.h
+++ b/sound/pci/ac97/ac97_id.h
@@ -62,3 +62,5 @@
62#define AC97_ID_CM9761_78 0x434d4978 62#define AC97_ID_CM9761_78 0x434d4978
63#define AC97_ID_CM9761_82 0x434d4982 63#define AC97_ID_CM9761_82 0x434d4982
64#define AC97_ID_CM9761_83 0x434d4983 64#define AC97_ID_CM9761_83 0x434d4983
65#define AC97_ID_ST7597 0x53544d02
66#define AC97_ID_ST_AC97_ID4 0x53544d04
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
index 7337abdbe4e3..e68c98ef4041 100644
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -544,25 +544,10 @@ static int patch_wolfson04(struct snd_ac97 * ac97)
544 return 0; 544 return 0;
545} 545}
546 546
547static int patch_wolfson_wm9705_specific(struct snd_ac97 * ac97)
548{
549 int err, i;
550 for (i = 0; i < ARRAY_SIZE(wm97xx_snd_ac97_controls); i++) {
551 if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm97xx_snd_ac97_controls[i], ac97))) < 0)
552 return err;
553 }
554 snd_ac97_write_cache(ac97, 0x72, 0x0808);
555 return 0;
556}
557
558static struct snd_ac97_build_ops patch_wolfson_wm9705_ops = {
559 .build_specific = patch_wolfson_wm9705_specific,
560};
561
562static int patch_wolfson05(struct snd_ac97 * ac97) 547static int patch_wolfson05(struct snd_ac97 * ac97)
563{ 548{
564 /* WM9705, WM9710 */ 549 /* WM9705, WM9710 */
565 ac97->build_ops = &patch_wolfson_wm9705_ops; 550 ac97->build_ops = &patch_wolfson_wm9703_ops;
566#ifdef CONFIG_TOUCHSCREEN_WM9705 551#ifdef CONFIG_TOUCHSCREEN_WM9705
567 /* WM9705 touchscreen uses AUX and VIDEO for touch */ 552 /* WM9705 touchscreen uses AUX and VIDEO for touch */
568 ac97->flags |= AC97_HAS_NO_VIDEO | AC97_HAS_NO_AUX; 553 ac97->flags |= AC97_HAS_NO_VIDEO | AC97_HAS_NO_AUX;
@@ -800,12 +785,12 @@ AC97_SINGLE("Mono Switch", AC97_MASTER_TONE, 7, 1, 1),
800AC97_SINGLE("Mono ZC Switch", AC97_MASTER_TONE, 6, 1, 0), 785AC97_SINGLE("Mono ZC Switch", AC97_MASTER_TONE, 6, 1, 0),
801AC97_SINGLE("Mono Volume", AC97_MASTER_TONE, 0, 31, 1), 786AC97_SINGLE("Mono Volume", AC97_MASTER_TONE, 0, 31, 1),
802 787
803AC97_SINGLE("PC Beep to Headphone Switch", AC97_AUX, 15, 1, 1), 788AC97_SINGLE("Beep to Headphone Switch", AC97_AUX, 15, 1, 1),
804AC97_SINGLE("PC Beep to Headphone Volume", AC97_AUX, 12, 7, 1), 789AC97_SINGLE("Beep to Headphone Volume", AC97_AUX, 12, 7, 1),
805AC97_SINGLE("PC Beep to Master Switch", AC97_AUX, 11, 1, 1), 790AC97_SINGLE("Beep to Master Switch", AC97_AUX, 11, 1, 1),
806AC97_SINGLE("PC Beep to Master Volume", AC97_AUX, 8, 7, 1), 791AC97_SINGLE("Beep to Master Volume", AC97_AUX, 8, 7, 1),
807AC97_SINGLE("PC Beep to Mono Switch", AC97_AUX, 7, 1, 1), 792AC97_SINGLE("Beep to Mono Switch", AC97_AUX, 7, 1, 1),
808AC97_SINGLE("PC Beep to Mono Volume", AC97_AUX, 4, 7, 1), 793AC97_SINGLE("Beep to Mono Volume", AC97_AUX, 4, 7, 1),
809 794
810AC97_SINGLE("Voice to Headphone Switch", AC97_PCM, 15, 1, 1), 795AC97_SINGLE("Voice to Headphone Switch", AC97_PCM, 15, 1, 1),
811AC97_SINGLE("Voice to Headphone Volume", AC97_PCM, 12, 7, 1), 796AC97_SINGLE("Voice to Headphone Volume", AC97_PCM, 12, 7, 1),
@@ -1867,11 +1852,14 @@ static unsigned int ad1981_jacks_blacklist[] = {
1867 0x10140523, /* Thinkpad R40 */ 1852 0x10140523, /* Thinkpad R40 */
1868 0x10140534, /* Thinkpad X31 */ 1853 0x10140534, /* Thinkpad X31 */
1869 0x10140537, /* Thinkpad T41p */ 1854 0x10140537, /* Thinkpad T41p */
1855 0x1014053e, /* Thinkpad R40e */
1870 0x10140554, /* Thinkpad T42p/R50p */ 1856 0x10140554, /* Thinkpad T42p/R50p */
1871 0x10140567, /* Thinkpad T43p 2668-G7U */ 1857 0x10140567, /* Thinkpad T43p 2668-G7U */
1872 0x10140581, /* Thinkpad X41-2527 */ 1858 0x10140581, /* Thinkpad X41-2527 */
1859 0x10280160, /* Dell Dimension 2400 */
1873 0x104380b0, /* Asus A7V8X-MX */ 1860 0x104380b0, /* Asus A7V8X-MX */
1874 0x11790241, /* Toshiba Satellite A-15 S127 */ 1861 0x11790241, /* Toshiba Satellite A-15 S127 */
1862 0x1179ff10, /* Toshiba P500 */
1875 0x144dc01a, /* Samsung NP-X20C004/SEG */ 1863 0x144dc01a, /* Samsung NP-X20C004/SEG */
1876 0 /* end */ 1864 0 /* end */
1877}; 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/ad1889.c b/sound/pci/ad1889.c
index 8f5098f92c37..4382d0fa6b9a 100644
--- a/sound/pci/ad1889.c
+++ b/sound/pci/ad1889.c
@@ -1048,7 +1048,7 @@ snd_ad1889_remove(struct pci_dev *pci)
1048 pci_set_drvdata(pci, NULL); 1048 pci_set_drvdata(pci, NULL);
1049} 1049}
1050 1050
1051static struct pci_device_id snd_ad1889_ids[] = { 1051static DEFINE_PCI_DEVICE_TABLE(snd_ad1889_ids) = {
1052 { PCI_DEVICE(PCI_VENDOR_ID_ANALOG_DEVICES, PCI_DEVICE_ID_AD1889JS) }, 1052 { PCI_DEVICE(PCI_VENDOR_ID_ANALOG_DEVICES, PCI_DEVICE_ID_AD1889JS) },
1053 { 0, }, 1053 { 0, },
1054}; 1054};
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c
index aaf4da68969c..5c6e322a48f0 100644
--- a/sound/pci/ali5451/ali5451.c
+++ b/sound/pci/ali5451/ali5451.c
@@ -275,7 +275,7 @@ struct snd_ali {
275#endif 275#endif
276}; 276};
277 277
278static struct pci_device_id snd_ali_ids[] = { 278static DEFINE_PCI_DEVICE_TABLE(snd_ali_ids) = {
279 {PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5451), 0, 0, 0}, 279 {PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5451), 0, 0, 0},
280 {0, } 280 {0, }
281}; 281};
diff --git a/sound/pci/als300.c b/sound/pci/als300.c
index 3aa35af7ca91..d7653cb7ac60 100644
--- a/sound/pci/als300.c
+++ b/sound/pci/als300.c
@@ -145,7 +145,7 @@ struct snd_als300_substream_data {
145 int block_counter_register; 145 int block_counter_register;
146}; 146};
147 147
148static struct pci_device_id snd_als300_ids[] = { 148static DEFINE_PCI_DEVICE_TABLE(snd_als300_ids) = {
149 { 0x4005, 0x0300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALS300 }, 149 { 0x4005, 0x0300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALS300 },
150 { 0x4005, 0x0308, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALS300_PLUS }, 150 { 0x4005, 0x0308, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALS300_PLUS },
151 { 0, } 151 { 0, }
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c
index 3dbacde1a5af..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>
@@ -117,7 +116,7 @@ struct snd_card_als4000 {
117#endif 116#endif
118}; 117};
119 118
120static struct pci_device_id snd_als4000_ids[] = { 119static DEFINE_PCI_DEVICE_TABLE(snd_als4000_ids) = {
121 { 0x4005, 0x4000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* ALS4000 */ 120 { 0x4005, 0x4000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* ALS4000 */
122 { 0, } 121 { 0, }
123}; 122};
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c
index d6752dff2a44..49d572a7b235 100644
--- a/sound/pci/atiixp.c
+++ b/sound/pci/atiixp.c
@@ -286,7 +286,7 @@ struct atiixp {
286 286
287/* 287/*
288 */ 288 */
289static struct pci_device_id snd_atiixp_ids[] = { 289static DEFINE_PCI_DEVICE_TABLE(snd_atiixp_ids) = {
290 { PCI_VDEVICE(ATI, 0x4341), 0 }, /* SB200 */ 290 { PCI_VDEVICE(ATI, 0x4341), 0 }, /* SB200 */
291 { PCI_VDEVICE(ATI, 0x4361), 0 }, /* SB300 */ 291 { PCI_VDEVICE(ATI, 0x4361), 0 }, /* SB300 */
292 { PCI_VDEVICE(ATI, 0x4370), 0 }, /* SB400 */ 292 { PCI_VDEVICE(ATI, 0x4370), 0 }, /* SB400 */
@@ -297,6 +297,7 @@ static struct pci_device_id snd_atiixp_ids[] = {
297MODULE_DEVICE_TABLE(pci, snd_atiixp_ids); 297MODULE_DEVICE_TABLE(pci, snd_atiixp_ids);
298 298
299static struct snd_pci_quirk atiixp_quirks[] __devinitdata = { 299static struct snd_pci_quirk atiixp_quirks[] __devinitdata = {
300 SND_PCI_QUIRK(0x105b, 0x0c81, "Foxconn RC4107MA-RS2", 0),
300 SND_PCI_QUIRK(0x15bd, 0x3100, "DFI RS482", 0), 301 SND_PCI_QUIRK(0x15bd, 0x3100, "DFI RS482", 0),
301 { } /* terminator */ 302 { } /* terminator */
302}; 303};
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c
index e7e147bf8eb2..91d7036b6411 100644
--- a/sound/pci/atiixp_modem.c
+++ b/sound/pci/atiixp_modem.c
@@ -261,7 +261,7 @@ struct atiixp_modem {
261 261
262/* 262/*
263 */ 263 */
264static struct pci_device_id snd_atiixp_ids[] = { 264static DEFINE_PCI_DEVICE_TABLE(snd_atiixp_ids) = {
265 { PCI_VDEVICE(ATI, 0x434d), 0 }, /* SB200 */ 265 { PCI_VDEVICE(ATI, 0x434d), 0 }, /* SB200 */
266 { PCI_VDEVICE(ATI, 0x4378), 0 }, /* SB400 */ 266 { PCI_VDEVICE(ATI, 0x4378), 0 }, /* SB400 */
267 { 0, } 267 { 0, }
diff --git a/sound/pci/au88x0/au8810.c b/sound/pci/au88x0/au8810.c
index c0e8c6b295cb..aa51cc7771dd 100644
--- a/sound/pci/au88x0/au8810.c
+++ b/sound/pci/au88x0/au8810.c
@@ -1,6 +1,6 @@
1#include "au8810.h" 1#include "au8810.h"
2#include "au88x0.h" 2#include "au88x0.h"
3static struct pci_device_id snd_vortex_ids[] = { 3static DEFINE_PCI_DEVICE_TABLE(snd_vortex_ids) = {
4 {PCI_VDEVICE(AUREAL, PCI_DEVICE_ID_AUREAL_ADVANTAGE), 1,}, 4 {PCI_VDEVICE(AUREAL, PCI_DEVICE_ID_AUREAL_ADVANTAGE), 1,},
5 {0,} 5 {0,}
6}; 6};
diff --git a/sound/pci/au88x0/au8820.c b/sound/pci/au88x0/au8820.c
index a6527330df58..2f321e7306cd 100644
--- a/sound/pci/au88x0/au8820.c
+++ b/sound/pci/au88x0/au8820.c
@@ -1,6 +1,6 @@
1#include "au8820.h" 1#include "au8820.h"
2#include "au88x0.h" 2#include "au88x0.h"
3static struct pci_device_id snd_vortex_ids[] = { 3static DEFINE_PCI_DEVICE_TABLE(snd_vortex_ids) = {
4 {PCI_VDEVICE(AUREAL, PCI_DEVICE_ID_AUREAL_VORTEX_1), 0,}, 4 {PCI_VDEVICE(AUREAL, PCI_DEVICE_ID_AUREAL_VORTEX_1), 0,},
5 {0,} 5 {0,}
6}; 6};
diff --git a/sound/pci/au88x0/au8830.c b/sound/pci/au88x0/au8830.c
index 6c702ad4352a..279b78f06d22 100644
--- a/sound/pci/au88x0/au8830.c
+++ b/sound/pci/au88x0/au8830.c
@@ -1,6 +1,6 @@
1#include "au8830.h" 1#include "au8830.h"
2#include "au88x0.h" 2#include "au88x0.h"
3static struct pci_device_id snd_vortex_ids[] = { 3static DEFINE_PCI_DEVICE_TABLE(snd_vortex_ids) = {
4 {PCI_VDEVICE(AUREAL, PCI_DEVICE_ID_AUREAL_VORTEX_2), 0,}, 4 {PCI_VDEVICE(AUREAL, PCI_DEVICE_ID_AUREAL_VORTEX_2), 0,},
5 {0,} 5 {0,}
6}; 6};
diff --git a/sound/pci/aw2/aw2-alsa.c b/sound/pci/aw2/aw2-alsa.c
index 4d34bb0d99d3..67921f93a41e 100644
--- a/sound/pci/aw2/aw2-alsa.c
+++ b/sound/pci/aw2/aw2-alsa.c
@@ -164,7 +164,7 @@ MODULE_PARM_DESC(id, "ID string for the Audiowerk2 soundcard.");
164module_param_array(enable, bool, NULL, 0444); 164module_param_array(enable, bool, NULL, 0444);
165MODULE_PARM_DESC(enable, "Enable Audiowerk2 soundcard."); 165MODULE_PARM_DESC(enable, "Enable Audiowerk2 soundcard.");
166 166
167static struct pci_device_id snd_aw2_ids[] = { 167static DEFINE_PCI_DEVICE_TABLE(snd_aw2_ids) = {
168 {PCI_VENDOR_ID_SAA7146, PCI_DEVICE_ID_SAA7146, 0, 0, 168 {PCI_VENDOR_ID_SAA7146, PCI_DEVICE_ID_SAA7146, 0, 0,
169 0, 0, 0}, 169 0, 0, 0},
170 {0} 170 {0}
diff --git a/sound/pci/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/azt3328.c b/sound/pci/azt3328.c
index 8451a0169f32..4679ed83a43b 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -350,7 +350,7 @@ struct snd_azf3328 {
350#endif 350#endif
351}; 351};
352 352
353static const struct pci_device_id snd_azf3328_ids[] = { 353static DEFINE_PCI_DEVICE_TABLE(snd_azf3328_ids) = {
354 { 0x122D, 0x50DC, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* PCI168/3328 */ 354 { 0x122D, 0x50DC, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* PCI168/3328 */
355 { 0x122D, 0x80DA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* 3328 */ 355 { 0x122D, 0x80DA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* 3328 */
356 { 0, } 356 { 0, }
@@ -830,8 +830,8 @@ static struct snd_kcontrol_new snd_azf3328_mixer_controls[] __devinitdata = {
830 AZF3328_MIXER_SWITCH("Mic Boost (+20dB)", IDX_MIXER_MIC, 6, 0), 830 AZF3328_MIXER_SWITCH("Mic Boost (+20dB)", IDX_MIXER_MIC, 6, 0),
831 AZF3328_MIXER_SWITCH("Line Playback Switch", IDX_MIXER_LINEIN, 15, 1), 831 AZF3328_MIXER_SWITCH("Line Playback Switch", IDX_MIXER_LINEIN, 15, 1),
832 AZF3328_MIXER_VOL_STEREO("Line Playback Volume", IDX_MIXER_LINEIN, 0x1f, 1), 832 AZF3328_MIXER_VOL_STEREO("Line Playback Volume", IDX_MIXER_LINEIN, 0x1f, 1),
833 AZF3328_MIXER_SWITCH("PC Speaker Playback Switch", IDX_MIXER_PCBEEP, 15, 1), 833 AZF3328_MIXER_SWITCH("Beep Playback Switch", IDX_MIXER_PCBEEP, 15, 1),
834 AZF3328_MIXER_VOL_SPECIAL("PC Speaker Playback Volume", IDX_MIXER_PCBEEP, 0x0f, 1, 1), 834 AZF3328_MIXER_VOL_SPECIAL("Beep Playback Volume", IDX_MIXER_PCBEEP, 0x0f, 1, 1),
835 AZF3328_MIXER_SWITCH("Video Playback Switch", IDX_MIXER_VIDEO, 15, 1), 835 AZF3328_MIXER_SWITCH("Video Playback Switch", IDX_MIXER_VIDEO, 15, 1),
836 AZF3328_MIXER_VOL_STEREO("Video Playback Volume", IDX_MIXER_VIDEO, 0x1f, 1), 836 AZF3328_MIXER_VOL_STEREO("Video Playback Volume", IDX_MIXER_VIDEO, 0x1f, 1),
837 AZF3328_MIXER_SWITCH("Aux Playback Switch", IDX_MIXER_AUX, 15, 1), 837 AZF3328_MIXER_SWITCH("Aux Playback Switch", IDX_MIXER_AUX, 15, 1),
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c
index 4e2b925a94cc..37e1b5df5ab8 100644
--- a/sound/pci/bt87x.c
+++ b/sound/pci/bt87x.c
@@ -795,7 +795,7 @@ fail:
795 .driver_data = SND_BT87X_BOARD_ ## id } 795 .driver_data = SND_BT87X_BOARD_ ## id }
796/* driver_data is the card id for that device */ 796/* driver_data is the card id for that device */
797 797
798static struct pci_device_id snd_bt87x_ids[] = { 798static DEFINE_PCI_DEVICE_TABLE(snd_bt87x_ids) = {
799 /* Hauppauge WinTV series */ 799 /* Hauppauge WinTV series */
800 BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0x13eb, GENERIC), 800 BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0x13eb, GENERIC),
801 /* Hauppauge WinTV series */ 801 /* Hauppauge WinTV series */
@@ -964,7 +964,7 @@ static void __devexit snd_bt87x_remove(struct pci_dev *pci)
964 964
965/* default entries for all Bt87x cards - it's not exported */ 965/* default entries for all Bt87x cards - it's not exported */
966/* driver_data is set to 0 to call detection */ 966/* driver_data is set to 0 to call detection */
967static struct pci_device_id snd_bt87x_default_ids[] __devinitdata = { 967static DEFINE_PCI_DEVICE_TABLE(snd_bt87x_default_ids) = {
968 BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, PCI_ANY_ID, PCI_ANY_ID, UNKNOWN), 968 BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, PCI_ANY_ID, PCI_ANY_ID, UNKNOWN),
969 BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, PCI_ANY_ID, PCI_ANY_ID, UNKNOWN), 969 BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, PCI_ANY_ID, PCI_ANY_ID, UNKNOWN),
970 { } 970 { }
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index 15e4138bce17..0a3d3d6e77b4 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -1875,7 +1875,7 @@ static int snd_ca0106_resume(struct pci_dev *pci)
1875#endif 1875#endif
1876 1876
1877// PCI IDs 1877// PCI IDs
1878static struct pci_device_id snd_ca0106_ids[] = { 1878static DEFINE_PCI_DEVICE_TABLE(snd_ca0106_ids) = {
1879 { PCI_VDEVICE(CREATIVE, 0x0007), 0 }, /* Audigy LS or Live 24bit */ 1879 { PCI_VDEVICE(CREATIVE, 0x0007), 0 }, /* Audigy LS or Live 24bit */
1880 { 0, } 1880 { 0, }
1881}; 1881};
diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c
index c8c6f437f5b3..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>
@@ -792,8 +791,8 @@ int __devinit snd_ca0106_mixer(struct snd_ca0106 *emu)
792 "Phone Playback Volume", 791 "Phone Playback Volume",
793 "Video Playback Switch", 792 "Video Playback Switch",
794 "Video Playback Volume", 793 "Video Playback Volume",
795 "PC Speaker Playback Switch", 794 "Beep Playback Switch",
796 "PC Speaker Playback Volume", 795 "Beep Playback Volume",
797 "Mono Output Select", 796 "Mono Output Select",
798 "Capture Source", 797 "Capture Source",
799 "Capture Switch", 798 "Capture Switch",
diff --git a/sound/pci/ca0106/ca0106_proc.c b/sound/pci/ca0106/ca0106_proc.c
index c62b7d10ec61..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>
@@ -233,7 +232,7 @@ static void snd_ca0106_proc_dump_iec958( struct snd_info_buffer *buffer, u32 val
233 snd_iprintf(buffer, "user-defined\n"); 232 snd_iprintf(buffer, "user-defined\n");
234 break; 233 break;
235 default: 234 default:
236 snd_iprintf(buffer, "unkown\n"); 235 snd_iprintf(buffer, "unknown\n");
237 break; 236 break;
238 } 237 }
239 snd_iprintf(buffer, "Sample Bits: "); 238 snd_iprintf(buffer, "Sample Bits: ");
@@ -304,7 +303,7 @@ static void snd_ca0106_proc_reg_write32(struct snd_info_entry *entry,
304 while (!snd_info_get_line(buffer, line, sizeof(line))) { 303 while (!snd_info_get_line(buffer, line, sizeof(line))) {
305 if (sscanf(line, "%x %x", &reg, &val) != 2) 304 if (sscanf(line, "%x %x", &reg, &val) != 2)
306 continue; 305 continue;
307 if ((reg < 0x40) && (reg >=0) && (val <= 0xffffffff) ) { 306 if (reg < 0x40 && val <= 0xffffffff) {
308 spin_lock_irqsave(&emu->emu_lock, flags); 307 spin_lock_irqsave(&emu->emu_lock, flags);
309 outl(val, emu->port + (reg & 0xfffffffc)); 308 outl(val, emu->port + (reg & 0xfffffffc));
310 spin_unlock_irqrestore(&emu->emu_lock, flags); 309 spin_unlock_irqrestore(&emu->emu_lock, flags);
@@ -405,7 +404,7 @@ static void snd_ca0106_proc_reg_write(struct snd_info_entry *entry,
405 while (!snd_info_get_line(buffer, line, sizeof(line))) { 404 while (!snd_info_get_line(buffer, line, sizeof(line))) {
406 if (sscanf(line, "%x %x %x", &reg, &channel_id, &val) != 3) 405 if (sscanf(line, "%x %x %x", &reg, &channel_id, &val) != 3)
407 continue; 406 continue;
408 if ((reg < 0x80) && (reg >=0) && (val <= 0xffffffff) && (channel_id >=0) && (channel_id <= 3) ) 407 if (reg < 0x80 && val <= 0xffffffff && channel_id <= 3)
409 snd_ca0106_ptr_write(emu, reg, channel_id, val); 408 snd_ca0106_ptr_write(emu, reg, channel_id, val);
410 } 409 }
411} 410}
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c
index ddcd4a9fd7e6..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;
@@ -2302,7 +2310,7 @@ static struct snd_kcontrol_new snd_cmipci_mixers[] __devinitdata = {
2302 CMIPCI_SB_VOL_MONO("Mic Playback Volume", SB_DSP4_MIC_DEV, 3, 31), 2310 CMIPCI_SB_VOL_MONO("Mic Playback Volume", SB_DSP4_MIC_DEV, 3, 31),
2303 CMIPCI_SB_SW_MONO("Mic Playback Switch", 0), 2311 CMIPCI_SB_SW_MONO("Mic Playback Switch", 0),
2304 CMIPCI_DOUBLE("Mic Capture Switch", SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 0, 0, 1, 0, 0), 2312 CMIPCI_DOUBLE("Mic Capture Switch", SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 0, 0, 1, 0, 0),
2305 CMIPCI_SB_VOL_MONO("PC Speaker Playback Volume", SB_DSP4_SPEAKER_DEV, 6, 3), 2313 CMIPCI_SB_VOL_MONO("Beep Playback Volume", SB_DSP4_SPEAKER_DEV, 6, 3),
2306 CMIPCI_MIXER_VOL_STEREO("Aux Playback Volume", CM_REG_AUX_VOL, 4, 0, 15), 2314 CMIPCI_MIXER_VOL_STEREO("Aux Playback Volume", CM_REG_AUX_VOL, 4, 0, 15),
2307 CMIPCI_MIXER_SW_STEREO("Aux Playback Switch", CM_REG_MIXER2, CM_VAUXLM_SHIFT, CM_VAUXRM_SHIFT, 0), 2315 CMIPCI_MIXER_SW_STEREO("Aux Playback Switch", CM_REG_MIXER2, CM_VAUXLM_SHIFT, CM_VAUXRM_SHIFT, 0),
2308 CMIPCI_MIXER_SW_STEREO("Aux Capture Switch", CM_REG_MIXER2, CM_RAUXLEN_SHIFT, CM_RAUXREN_SHIFT, 0), 2316 CMIPCI_MIXER_SW_STEREO("Aux Capture Switch", CM_REG_MIXER2, CM_RAUXLEN_SHIFT, CM_RAUXREN_SHIFT, 0),
@@ -2310,7 +2318,7 @@ static struct snd_kcontrol_new snd_cmipci_mixers[] __devinitdata = {
2310 CMIPCI_MIXER_VOL_MONO("Mic Capture Volume", CM_REG_MIXER2, CM_VADMIC_SHIFT, 7), 2318 CMIPCI_MIXER_VOL_MONO("Mic Capture Volume", CM_REG_MIXER2, CM_VADMIC_SHIFT, 7),
2311 CMIPCI_SB_VOL_MONO("Phone Playback Volume", CM_REG_EXTENT_IND, 5, 7), 2319 CMIPCI_SB_VOL_MONO("Phone Playback Volume", CM_REG_EXTENT_IND, 5, 7),
2312 CMIPCI_DOUBLE("Phone Playback Switch", CM_REG_EXTENT_IND, CM_REG_EXTENT_IND, 4, 4, 1, 0, 0), 2320 CMIPCI_DOUBLE("Phone Playback Switch", CM_REG_EXTENT_IND, CM_REG_EXTENT_IND, 4, 4, 1, 0, 0),
2313 CMIPCI_DOUBLE("PC Speaker Playback Switch", CM_REG_EXTENT_IND, CM_REG_EXTENT_IND, 3, 3, 1, 0, 0), 2321 CMIPCI_DOUBLE("Beep Playback Switch", CM_REG_EXTENT_IND, CM_REG_EXTENT_IND, 3, 3, 1, 0, 0),
2314 CMIPCI_DOUBLE("Mic Boost Capture Switch", CM_REG_EXTENT_IND, CM_REG_EXTENT_IND, 0, 0, 1, 0, 0), 2322 CMIPCI_DOUBLE("Mic Boost Capture Switch", CM_REG_EXTENT_IND, CM_REG_EXTENT_IND, 0, 0, 1, 0, 0),
2315}; 2323};
2316 2324
@@ -2796,7 +2804,7 @@ static inline void snd_cmipci_proc_init(struct cmipci *cm) {}
2796#endif 2804#endif
2797 2805
2798 2806
2799static struct pci_device_id snd_cmipci_ids[] = { 2807static DEFINE_PCI_DEVICE_TABLE(snd_cmipci_ids) = {
2800 {PCI_VDEVICE(CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338A), 0}, 2808 {PCI_VDEVICE(CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338A), 0},
2801 {PCI_VDEVICE(CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338B), 0}, 2809 {PCI_VDEVICE(CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338B), 0},
2802 {PCI_VDEVICE(CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8738), 0}, 2810 {PCI_VDEVICE(CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8738), 0},
@@ -3018,7 +3026,7 @@ static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pc
3018 int integrated_midi = 0; 3026 int integrated_midi = 0;
3019 char modelstr[16]; 3027 char modelstr[16];
3020 int pcm_index, pcm_spdif_index; 3028 int pcm_index, pcm_spdif_index;
3021 static struct pci_device_id intel_82437vx[] = { 3029 static DEFINE_PCI_DEVICE_TABLE(intel_82437vx) = {
3022 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437VX) }, 3030 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437VX) },
3023 { }, 3031 { },
3024 }; 3032 };
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c
index e2e0359bb056..9edc65059e3e 100644
--- a/sound/pci/cs4281.c
+++ b/sound/pci/cs4281.c
@@ -494,7 +494,7 @@ struct cs4281 {
494 494
495static irqreturn_t snd_cs4281_interrupt(int irq, void *dev_id); 495static irqreturn_t snd_cs4281_interrupt(int irq, void *dev_id);
496 496
497static struct pci_device_id snd_cs4281_ids[] = { 497static DEFINE_PCI_DEVICE_TABLE(snd_cs4281_ids) = {
498 { PCI_VDEVICE(CIRRUS, 0x6005), 0, }, /* CS4281 */ 498 { PCI_VDEVICE(CIRRUS, 0x6005), 0, }, /* CS4281 */
499 { 0, } 499 { 0, }
500}; 500};
diff --git a/sound/pci/cs46xx/cs46xx.c b/sound/pci/cs46xx/cs46xx.c
index 033aec430117..767fa7f06cd0 100644
--- a/sound/pci/cs46xx/cs46xx.c
+++ b/sound/pci/cs46xx/cs46xx.c
@@ -64,7 +64,7 @@ MODULE_PARM_DESC(thinkpad, "Force to enable Thinkpad's CLKRUN control.");
64module_param_array(mmap_valid, bool, NULL, 0444); 64module_param_array(mmap_valid, bool, NULL, 0444);
65MODULE_PARM_DESC(mmap_valid, "Support OSS mmap."); 65MODULE_PARM_DESC(mmap_valid, "Support OSS mmap.");
66 66
67static struct pci_device_id snd_cs46xx_ids[] = { 67static DEFINE_PCI_DEVICE_TABLE(snd_cs46xx_ids) = {
68 { PCI_VDEVICE(CIRRUS, 0x6001), 0, }, /* CS4280 */ 68 { PCI_VDEVICE(CIRRUS, 0x6001), 0, }, /* CS4280 */
69 { PCI_VDEVICE(CIRRUS, 0x6003), 0, }, /* CS4612 */ 69 { PCI_VDEVICE(CIRRUS, 0x6003), 0, }, /* CS4612 */
70 { PCI_VDEVICE(CIRRUS, 0x6004), 0, }, /* CS4615 */ 70 { PCI_VDEVICE(CIRRUS, 0x6004), 0, }, /* CS4615 */
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
index 1be96ead4244..3f99a5e8528c 100644
--- a/sound/pci/cs46xx/cs46xx_lib.c
+++ b/sound/pci/cs46xx/cs46xx_lib.c
@@ -2238,11 +2238,11 @@ static void snd_cs46xx_codec_reset (struct snd_ac97 * ac97)
2238 2238
2239 /* set the desired CODEC mode */ 2239 /* set the desired CODEC mode */
2240 if (ac97->num == CS46XX_PRIMARY_CODEC_INDEX) { 2240 if (ac97->num == CS46XX_PRIMARY_CODEC_INDEX) {
2241 snd_printdd("cs46xx: CODOEC1 mode %04x\n",0x0); 2241 snd_printdd("cs46xx: CODEC1 mode %04x\n", 0x0);
2242 snd_cs46xx_ac97_write(ac97,AC97_CSR_ACMODE,0x0); 2242 snd_cs46xx_ac97_write(ac97, AC97_CSR_ACMODE, 0x0);
2243 } else if (ac97->num == CS46XX_SECONDARY_CODEC_INDEX) { 2243 } else if (ac97->num == CS46XX_SECONDARY_CODEC_INDEX) {
2244 snd_printdd("cs46xx: CODOEC2 mode %04x\n",0x3); 2244 snd_printdd("cs46xx: CODEC2 mode %04x\n", 0x3);
2245 snd_cs46xx_ac97_write(ac97,AC97_CSR_ACMODE,0x3); 2245 snd_cs46xx_ac97_write(ac97, AC97_CSR_ACMODE, 0x3);
2246 } else { 2246 } else {
2247 snd_BUG(); /* should never happen ... */ 2247 snd_BUG(); /* should never happen ... */
2248 } 2248 }
@@ -2266,7 +2266,7 @@ static void snd_cs46xx_codec_reset (struct snd_ac97 * ac97)
2266 return; 2266 return;
2267 2267
2268 /* test if we can write to the record gain volume register */ 2268 /* test if we can write to the record gain volume register */
2269 snd_ac97_write_cache(ac97, AC97_REC_GAIN, 0x8a05); 2269 snd_ac97_write(ac97, AC97_REC_GAIN, 0x8a05);
2270 if ((err = snd_ac97_read(ac97, AC97_REC_GAIN)) == 0x8a05) 2270 if ((err = snd_ac97_read(ac97, AC97_REC_GAIN)) == 0x8a05)
2271 return; 2271 return;
2272 2272
@@ -3597,7 +3597,7 @@ static struct cs_card_type __devinitdata cards[] = {
3597#ifdef CONFIG_PM 3597#ifdef CONFIG_PM
3598static unsigned int saved_regs[] = { 3598static unsigned int saved_regs[] = {
3599 BA0_ACOSV, 3599 BA0_ACOSV,
3600 BA0_ASER_FADDR, 3600 /*BA0_ASER_FADDR,*/
3601 BA0_ASER_MASTER, 3601 BA0_ASER_MASTER,
3602 BA1_PVOL, 3602 BA1_PVOL,
3603 BA1_CVOL, 3603 BA1_CVOL,
@@ -3644,6 +3644,7 @@ int snd_cs46xx_resume(struct pci_dev *pci)
3644#ifdef CONFIG_SND_CS46XX_NEW_DSP 3644#ifdef CONFIG_SND_CS46XX_NEW_DSP
3645 int i; 3645 int i;
3646#endif 3646#endif
3647 unsigned int tmp;
3647 3648
3648 pci_set_power_state(pci, PCI_D0); 3649 pci_set_power_state(pci, PCI_D0);
3649 pci_restore_state(pci); 3650 pci_restore_state(pci);
@@ -3685,6 +3686,15 @@ int snd_cs46xx_resume(struct pci_dev *pci)
3685 snd_ac97_resume(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]); 3686 snd_ac97_resume(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]);
3686 snd_ac97_resume(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]); 3687 snd_ac97_resume(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]);
3687 3688
3689 /*
3690 * Stop capture DMA.
3691 */
3692 tmp = snd_cs46xx_peek(chip, BA1_CCTL);
3693 chip->capt.ctl = tmp & 0x0000ffff;
3694 snd_cs46xx_poke(chip, BA1_CCTL, tmp & 0xffff0000);
3695
3696 mdelay(5);
3697
3688 /* reset playback/capture */ 3698 /* reset playback/capture */
3689 snd_cs46xx_set_play_sample_rate(chip, 8000); 3699 snd_cs46xx_set_play_sample_rate(chip, 8000);
3690 snd_cs46xx_set_capture_sample_rate(chip, 8000); 3700 snd_cs46xx_set_capture_sample_rate(chip, 8000);
diff --git a/sound/pci/cs46xx/dsp_spos.c b/sound/pci/cs46xx/dsp_spos.c
index f4f0c8f5dad7..3e5ca8fb519f 100644
--- a/sound/pci/cs46xx/dsp_spos.c
+++ b/sound/pci/cs46xx/dsp_spos.c
@@ -298,6 +298,9 @@ void cs46xx_dsp_spos_destroy (struct snd_cs46xx * chip)
298 if (ins->scbs[i].deleted) continue; 298 if (ins->scbs[i].deleted) continue;
299 299
300 cs46xx_dsp_proc_free_scb_desc ( (ins->scbs + i) ); 300 cs46xx_dsp_proc_free_scb_desc ( (ins->scbs + i) );
301#ifdef CONFIG_PM
302 kfree(ins->scbs[i].data);
303#endif
301 } 304 }
302 305
303 kfree(ins->code.data); 306 kfree(ins->code.data);
@@ -974,13 +977,11 @@ static struct dsp_scb_descriptor * _map_scb (struct snd_cs46xx *chip, char * nam
974 977
975 index = find_free_scb_index (ins); 978 index = find_free_scb_index (ins);
976 979
980 memset(&ins->scbs[index], 0, sizeof(ins->scbs[index]));
977 strcpy(ins->scbs[index].scb_name, name); 981 strcpy(ins->scbs[index].scb_name, name);
978 ins->scbs[index].address = dest; 982 ins->scbs[index].address = dest;
979 ins->scbs[index].index = index; 983 ins->scbs[index].index = index;
980 ins->scbs[index].proc_info = NULL;
981 ins->scbs[index].ref_count = 1; 984 ins->scbs[index].ref_count = 1;
982 ins->scbs[index].deleted = 0;
983 spin_lock_init(&ins->scbs[index].lock);
984 985
985 desc = (ins->scbs + index); 986 desc = (ins->scbs + index);
986 ins->scbs[index].scb_symbol = add_symbol (chip, name, dest, SYMBOL_PARAMETER); 987 ins->scbs[index].scb_symbol = add_symbol (chip, name, dest, SYMBOL_PARAMETER);
@@ -1022,17 +1023,29 @@ _map_task_tree (struct snd_cs46xx *chip, char * name, u32 dest, u32 size)
1022 return desc; 1023 return desc;
1023} 1024}
1024 1025
1026#define SCB_BYTES (0x10 * 4)
1027
1025struct dsp_scb_descriptor * 1028struct dsp_scb_descriptor *
1026cs46xx_dsp_create_scb (struct snd_cs46xx *chip, char * name, u32 * scb_data, u32 dest) 1029cs46xx_dsp_create_scb (struct snd_cs46xx *chip, char * name, u32 * scb_data, u32 dest)
1027{ 1030{
1028 struct dsp_scb_descriptor * desc; 1031 struct dsp_scb_descriptor * desc;
1029 1032
1033#ifdef CONFIG_PM
1034 /* copy the data for resume */
1035 scb_data = kmemdup(scb_data, SCB_BYTES, GFP_KERNEL);
1036 if (!scb_data)
1037 return NULL;
1038#endif
1039
1030 desc = _map_scb (chip,name,dest); 1040 desc = _map_scb (chip,name,dest);
1031 if (desc) { 1041 if (desc) {
1032 desc->data = scb_data; 1042 desc->data = scb_data;
1033 _dsp_create_scb(chip,scb_data,dest); 1043 _dsp_create_scb(chip,scb_data,dest);
1034 } else { 1044 } else {
1035 snd_printk(KERN_ERR "dsp_spos: failed to map SCB\n"); 1045 snd_printk(KERN_ERR "dsp_spos: failed to map SCB\n");
1046#ifdef CONFIG_PM
1047 kfree(scb_data);
1048#endif
1036 } 1049 }
1037 1050
1038 return desc; 1051 return desc;
@@ -1988,7 +2001,28 @@ int cs46xx_dsp_resume(struct snd_cs46xx * chip)
1988 continue; 2001 continue;
1989 _dsp_create_scb(chip, s->data, s->address); 2002 _dsp_create_scb(chip, s->data, s->address);
1990 } 2003 }
1991 2004 for (i = 0; i < ins->nscb; i++) {
2005 struct dsp_scb_descriptor *s = &ins->scbs[i];
2006 if (s->deleted)
2007 continue;
2008 if (s->updated)
2009 cs46xx_dsp_spos_update_scb(chip, s);
2010 if (s->volume_set)
2011 cs46xx_dsp_scb_set_volume(chip, s,
2012 s->volume[0], s->volume[1]);
2013 }
2014 if (ins->spdif_status_out & DSP_SPDIF_STATUS_HW_ENABLED) {
2015 cs46xx_dsp_enable_spdif_hw(chip);
2016 snd_cs46xx_poke(chip, (ins->ref_snoop_scb->address + 2) << 2,
2017 (OUTPUT_SNOOP_BUFFER + 0x10) << 0x10);
2018 if (ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN)
2019 cs46xx_poke_via_dsp(chip, SP_SPDOUT_CSUV,
2020 ins->spdif_csuv_stream);
2021 }
2022 if (chip->dsp_spos_instance->spdif_status_in) {
2023 cs46xx_poke_via_dsp(chip, SP_ASER_COUNTDOWN, 0x80000005);
2024 cs46xx_poke_via_dsp(chip, SP_SPDIN_CONTROL, 0x800003ff);
2025 }
1992 return 0; 2026 return 0;
1993} 2027}
1994#endif 2028#endif
diff --git a/sound/pci/cs46xx/dsp_spos.h b/sound/pci/cs46xx/dsp_spos.h
index f9e169d33c03..ca47a8114c7f 100644
--- a/sound/pci/cs46xx/dsp_spos.h
+++ b/sound/pci/cs46xx/dsp_spos.h
@@ -212,6 +212,7 @@ static inline void cs46xx_dsp_spos_update_scb (struct snd_cs46xx * chip,
212 (scb->address + SCBsubListPtr) << 2, 212 (scb->address + SCBsubListPtr) << 2,
213 (scb->sub_list_ptr->address << 0x10) | 213 (scb->sub_list_ptr->address << 0x10) |
214 (scb->next_scb_ptr->address)); 214 (scb->next_scb_ptr->address));
215 scb->updated = 1;
215} 216}
216 217
217static inline void cs46xx_dsp_scb_set_volume (struct snd_cs46xx * chip, 218static inline void cs46xx_dsp_scb_set_volume (struct snd_cs46xx * chip,
@@ -222,6 +223,9 @@ static inline void cs46xx_dsp_scb_set_volume (struct snd_cs46xx * chip,
222 223
223 snd_cs46xx_poke(chip, (scb->address + SCBVolumeCtrl) << 2, val); 224 snd_cs46xx_poke(chip, (scb->address + SCBVolumeCtrl) << 2, val);
224 snd_cs46xx_poke(chip, (scb->address + SCBVolumeCtrl + 1) << 2, val); 225 snd_cs46xx_poke(chip, (scb->address + SCBVolumeCtrl + 1) << 2, val);
226 scb->volume_set = 1;
227 scb->volume[0] = left;
228 scb->volume[1] = right;
225} 229}
226#endif /* __DSP_SPOS_H__ */ 230#endif /* __DSP_SPOS_H__ */
227#endif /* CONFIG_SND_CS46XX_NEW_DSP */ 231#endif /* CONFIG_SND_CS46XX_NEW_DSP */
diff --git a/sound/pci/cs46xx/dsp_spos_scb_lib.c b/sound/pci/cs46xx/dsp_spos_scb_lib.c
index dd7c41b037b4..00b148a10239 100644
--- a/sound/pci/cs46xx/dsp_spos_scb_lib.c
+++ b/sound/pci/cs46xx/dsp_spos_scb_lib.c
@@ -115,7 +115,6 @@ static void cs46xx_dsp_proc_scb_info_read (struct snd_info_entry *entry,
115static void _dsp_unlink_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor * scb) 115static void _dsp_unlink_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor * scb)
116{ 116{
117 struct dsp_spos_instance * ins = chip->dsp_spos_instance; 117 struct dsp_spos_instance * ins = chip->dsp_spos_instance;
118 unsigned long flags;
119 118
120 if ( scb->parent_scb_ptr ) { 119 if ( scb->parent_scb_ptr ) {
121 /* unlink parent SCB */ 120 /* unlink parent SCB */
@@ -153,8 +152,6 @@ static void _dsp_unlink_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor
153 scb->next_scb_ptr = ins->the_null_scb; 152 scb->next_scb_ptr = ins->the_null_scb;
154 } 153 }
155 154
156 spin_lock_irqsave(&chip->reg_lock, flags);
157
158 /* update parent first entry in DSP RAM */ 155 /* update parent first entry in DSP RAM */
159 cs46xx_dsp_spos_update_scb(chip,scb->parent_scb_ptr); 156 cs46xx_dsp_spos_update_scb(chip,scb->parent_scb_ptr);
160 157
@@ -162,7 +159,6 @@ static void _dsp_unlink_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor
162 cs46xx_dsp_spos_update_scb(chip,scb); 159 cs46xx_dsp_spos_update_scb(chip,scb);
163 160
164 scb->parent_scb_ptr = NULL; 161 scb->parent_scb_ptr = NULL;
165 spin_unlock_irqrestore(&chip->reg_lock, flags);
166 } 162 }
167} 163}
168 164
@@ -197,9 +193,9 @@ void cs46xx_dsp_remove_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor *
197 goto _end; 193 goto _end;
198#endif 194#endif
199 195
200 spin_lock_irqsave(&scb->lock, flags); 196 spin_lock_irqsave(&chip->reg_lock, flags);
201 _dsp_unlink_scb (chip,scb); 197 _dsp_unlink_scb (chip,scb);
202 spin_unlock_irqrestore(&scb->lock, flags); 198 spin_unlock_irqrestore(&chip->reg_lock, flags);
203 199
204 cs46xx_dsp_proc_free_scb_desc(scb); 200 cs46xx_dsp_proc_free_scb_desc(scb);
205 if (snd_BUG_ON(!scb->scb_symbol)) 201 if (snd_BUG_ON(!scb->scb_symbol))
@@ -207,6 +203,10 @@ void cs46xx_dsp_remove_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor *
207 remove_symbol (chip,scb->scb_symbol); 203 remove_symbol (chip,scb->scb_symbol);
208 204
209 ins->scbs[scb->index].deleted = 1; 205 ins->scbs[scb->index].deleted = 1;
206#ifdef CONFIG_PM
207 kfree(ins->scbs[scb->index].data);
208 ins->scbs[scb->index].data = NULL;
209#endif
210 210
211 if (scb->index < ins->scb_highest_frag_index) 211 if (scb->index < ins->scb_highest_frag_index)
212 ins->scb_highest_frag_index = scb->index; 212 ins->scb_highest_frag_index = scb->index;
@@ -1508,20 +1508,17 @@ int cs46xx_dsp_pcm_unlink (struct snd_cs46xx * chip,
1508 chip->dsp_spos_instance->npcm_channels <= 0)) 1508 chip->dsp_spos_instance->npcm_channels <= 0))
1509 return -EIO; 1509 return -EIO;
1510 1510
1511 spin_lock(&pcm_channel->src_scb->lock); 1511 spin_lock_irqsave(&chip->reg_lock, flags);
1512
1513 if (pcm_channel->unlinked) { 1512 if (pcm_channel->unlinked) {
1514 spin_unlock(&pcm_channel->src_scb->lock); 1513 spin_unlock_irqrestore(&chip->reg_lock, flags);
1515 return -EIO; 1514 return -EIO;
1516 } 1515 }
1517 1516
1518 spin_lock_irqsave(&chip->reg_lock, flags);
1519 pcm_channel->unlinked = 1; 1517 pcm_channel->unlinked = 1;
1520 spin_unlock_irqrestore(&chip->reg_lock, flags);
1521 1518
1522 _dsp_unlink_scb (chip,pcm_channel->pcm_reader_scb); 1519 _dsp_unlink_scb (chip,pcm_channel->pcm_reader_scb);
1520 spin_unlock_irqrestore(&chip->reg_lock, flags);
1523 1521
1524 spin_unlock(&pcm_channel->src_scb->lock);
1525 return 0; 1522 return 0;
1526} 1523}
1527 1524
@@ -1533,10 +1530,10 @@ int cs46xx_dsp_pcm_link (struct snd_cs46xx * chip,
1533 struct dsp_scb_descriptor * src_scb = pcm_channel->src_scb; 1530 struct dsp_scb_descriptor * src_scb = pcm_channel->src_scb;
1534 unsigned long flags; 1531 unsigned long flags;
1535 1532
1536 spin_lock(&pcm_channel->src_scb->lock); 1533 spin_lock_irqsave(&chip->reg_lock, flags);
1537 1534
1538 if (pcm_channel->unlinked == 0) { 1535 if (pcm_channel->unlinked == 0) {
1539 spin_unlock(&pcm_channel->src_scb->lock); 1536 spin_unlock_irqrestore(&chip->reg_lock, flags);
1540 return -EIO; 1537 return -EIO;
1541 } 1538 }
1542 1539
@@ -1552,8 +1549,6 @@ int cs46xx_dsp_pcm_link (struct snd_cs46xx * chip,
1552 snd_BUG_ON(pcm_channel->pcm_reader_scb->parent_scb_ptr); 1549 snd_BUG_ON(pcm_channel->pcm_reader_scb->parent_scb_ptr);
1553 pcm_channel->pcm_reader_scb->parent_scb_ptr = parent_scb; 1550 pcm_channel->pcm_reader_scb->parent_scb_ptr = parent_scb;
1554 1551
1555 spin_lock_irqsave(&chip->reg_lock, flags);
1556
1557 /* update SCB entry in DSP RAM */ 1552 /* update SCB entry in DSP RAM */
1558 cs46xx_dsp_spos_update_scb(chip,pcm_channel->pcm_reader_scb); 1553 cs46xx_dsp_spos_update_scb(chip,pcm_channel->pcm_reader_scb);
1559 1554
@@ -1562,8 +1557,6 @@ int cs46xx_dsp_pcm_link (struct snd_cs46xx * chip,
1562 1557
1563 pcm_channel->unlinked = 0; 1558 pcm_channel->unlinked = 0;
1564 spin_unlock_irqrestore(&chip->reg_lock, flags); 1559 spin_unlock_irqrestore(&chip->reg_lock, flags);
1565
1566 spin_unlock(&pcm_channel->src_scb->lock);
1567 return 0; 1560 return 0;
1568} 1561}
1569 1562
@@ -1596,13 +1589,17 @@ cs46xx_add_record_source (struct snd_cs46xx *chip, struct dsp_scb_descriptor * s
1596 1589
1597int cs46xx_src_unlink(struct snd_cs46xx *chip, struct dsp_scb_descriptor * src) 1590int cs46xx_src_unlink(struct snd_cs46xx *chip, struct dsp_scb_descriptor * src)
1598{ 1591{
1592 unsigned long flags;
1593
1599 if (snd_BUG_ON(!src->parent_scb_ptr)) 1594 if (snd_BUG_ON(!src->parent_scb_ptr))
1600 return -EINVAL; 1595 return -EINVAL;
1601 1596
1602 /* mute SCB */ 1597 /* mute SCB */
1603 cs46xx_dsp_scb_set_volume (chip,src,0,0); 1598 cs46xx_dsp_scb_set_volume (chip,src,0,0);
1604 1599
1600 spin_lock_irqsave(&chip->reg_lock, flags);
1605 _dsp_unlink_scb (chip,src); 1601 _dsp_unlink_scb (chip,src);
1602 spin_unlock_irqrestore(&chip->reg_lock, flags);
1606 1603
1607 return 0; 1604 return 0;
1608} 1605}
diff --git a/sound/pci/cs46xx/imgs/cwcdma.asp b/sound/pci/cs46xx/imgs/cwcdma.asp
index 09d24c76f034..a65e1193c89a 100644
--- a/sound/pci/cs46xx/imgs/cwcdma.asp
+++ b/sound/pci/cs46xx/imgs/cwcdma.asp
@@ -26,10 +26,11 @@
26// 26//
27// 27//
28// The purpose of this code is very simple: make it possible to tranfser 28// The purpose of this code is very simple: make it possible to tranfser
29// the samples 'as they are' with no alteration from a PCMreader SCB (DMA from host) 29// the samples 'as they are' with no alteration from a PCMreader
30// to any other SCB. This is useful for AC3 throug SPDIF. SRC (source rate converters) 30// SCB (DMA from host) to any other SCB. This is useful for AC3 through SPDIF.
31// task always alters the samples in some how, however it's from 48khz -> 48khz. The 31// SRC (source rate converters) task always alters the samples in somehow,
32// alterations are not audible, but AC3 wont work. 32// however it's from 48khz -> 48khz.
33// The alterations are not audible, but AC3 wont work.
33// 34//
34// ... 35// ...
35// | 36// |
diff --git a/sound/pci/cs5530.c b/sound/pci/cs5530.c
index dc464321d0f3..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>
@@ -58,7 +59,7 @@ struct snd_cs5530 {
58 unsigned long pci_base; 59 unsigned long pci_base;
59}; 60};
60 61
61static struct pci_device_id snd_cs5530_ids[] = { 62static DEFINE_PCI_DEVICE_TABLE(snd_cs5530_ids) = {
62 {PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_AUDIO, PCI_ANY_ID, 63 {PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_AUDIO, PCI_ANY_ID,
63 PCI_ANY_ID, 0, 0}, 64 PCI_ANY_ID, 0, 0},
64 {0,} 65 {0,}
diff --git a/sound/pci/cs5535audio/Makefile b/sound/pci/cs5535audio/Makefile
index fda7a94c992f..ccc642269b9e 100644
--- a/sound/pci/cs5535audio/Makefile
+++ b/sound/pci/cs5535audio/Makefile
@@ -4,9 +4,7 @@
4 4
5snd-cs5535audio-y := cs5535audio.o cs5535audio_pcm.o 5snd-cs5535audio-y := cs5535audio.o cs5535audio_pcm.o
6snd-cs5535audio-$(CONFIG_PM) += cs5535audio_pm.o 6snd-cs5535audio-$(CONFIG_PM) += cs5535audio_pm.o
7ifdef CONFIG_MGEODE_LX
8snd-cs5535audio-$(CONFIG_OLPC) += cs5535audio_olpc.o 7snd-cs5535audio-$(CONFIG_OLPC) += cs5535audio_olpc.o
9endif
10 8
11# Toplevel Module Dependency 9# Toplevel Module Dependency
12obj-$(CONFIG_SND_CS5535AUDIO) += snd-cs5535audio.o 10obj-$(CONFIG_SND_CS5535AUDIO) += snd-cs5535audio.o
diff --git a/sound/pci/cs5535audio/cs5535audio.c b/sound/pci/cs5535audio/cs5535audio.c
index 05f56e04849b..afb803708416 100644
--- a/sound/pci/cs5535audio/cs5535audio.c
+++ b/sound/pci/cs5535audio/cs5535audio.c
@@ -66,7 +66,7 @@ MODULE_PARM_DESC(id, "ID string for " DRIVER_NAME);
66module_param_array(enable, bool, NULL, 0444); 66module_param_array(enable, bool, NULL, 0444);
67MODULE_PARM_DESC(enable, "Enable " DRIVER_NAME); 67MODULE_PARM_DESC(enable, "Enable " DRIVER_NAME);
68 68
69static struct pci_device_id snd_cs5535audio_ids[] = { 69static DEFINE_PCI_DEVICE_TABLE(snd_cs5535audio_ids) = {
70 { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_AUDIO) }, 70 { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_AUDIO) },
71 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_AUDIO) }, 71 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_AUDIO) },
72 {} 72 {}
@@ -389,6 +389,7 @@ probefail_out:
389 389
390static void __devexit snd_cs5535audio_remove(struct pci_dev *pci) 390static void __devexit snd_cs5535audio_remove(struct pci_dev *pci)
391{ 391{
392 olpc_quirks_cleanup();
392 snd_card_free(pci_get_drvdata(pci)); 393 snd_card_free(pci_get_drvdata(pci));
393 pci_set_drvdata(pci, NULL); 394 pci_set_drvdata(pci, NULL);
394} 395}
diff --git a/sound/pci/cs5535audio/cs5535audio.h b/sound/pci/cs5535audio/cs5535audio.h
index 7a298ac662e3..51966d782a3c 100644
--- a/sound/pci/cs5535audio/cs5535audio.h
+++ b/sound/pci/cs5535audio/cs5535audio.h
@@ -99,10 +99,11 @@ int snd_cs5535audio_suspend(struct pci_dev *pci, pm_message_t state);
99int snd_cs5535audio_resume(struct pci_dev *pci); 99int snd_cs5535audio_resume(struct pci_dev *pci);
100#endif 100#endif
101 101
102#if defined(CONFIG_OLPC) && defined(CONFIG_MGEODE_LX) 102#ifdef CONFIG_OLPC
103void __devinit olpc_prequirks(struct snd_card *card, 103void __devinit olpc_prequirks(struct snd_card *card,
104 struct snd_ac97_template *ac97); 104 struct snd_ac97_template *ac97);
105int __devinit olpc_quirks(struct snd_card *card, struct snd_ac97 *ac97); 105int __devinit olpc_quirks(struct snd_card *card, struct snd_ac97 *ac97);
106void __devexit olpc_quirks_cleanup(void);
106void olpc_analog_input(struct snd_ac97 *ac97, int on); 107void olpc_analog_input(struct snd_ac97 *ac97, int on);
107void olpc_mic_bias(struct snd_ac97 *ac97, int on); 108void olpc_mic_bias(struct snd_ac97 *ac97, int on);
108 109
@@ -128,6 +129,7 @@ static inline int olpc_quirks(struct snd_card *card, struct snd_ac97 *ac97)
128{ 129{
129 return 0; 130 return 0;
130} 131}
132static inline void olpc_quirks_cleanup(void) { }
131static inline void olpc_analog_input(struct snd_ac97 *ac97, int on) { } 133static inline void olpc_analog_input(struct snd_ac97 *ac97, int on) { }
132static inline void olpc_mic_bias(struct snd_ac97 *ac97, int on) { } 134static inline void olpc_mic_bias(struct snd_ac97 *ac97, int on) { }
133static inline void olpc_capture_open(struct snd_ac97 *ac97) { } 135static inline void olpc_capture_open(struct snd_ac97 *ac97) { }
diff --git a/sound/pci/cs5535audio/cs5535audio_olpc.c b/sound/pci/cs5535audio/cs5535audio_olpc.c
index 5c6814335cd7..50da49be9ae5 100644
--- a/sound/pci/cs5535audio/cs5535audio_olpc.c
+++ b/sound/pci/cs5535audio/cs5535audio_olpc.c
@@ -13,10 +13,13 @@
13#include <sound/info.h> 13#include <sound/info.h>
14#include <sound/control.h> 14#include <sound/control.h>
15#include <sound/ac97_codec.h> 15#include <sound/ac97_codec.h>
16#include <linux/gpio.h>
16 17
17#include <asm/olpc.h> 18#include <asm/olpc.h>
18#include "cs5535audio.h" 19#include "cs5535audio.h"
19 20
21#define DRV_NAME "cs5535audio-olpc"
22
20/* 23/*
21 * OLPC has an additional feature on top of the regular AD1888 codec features. 24 * OLPC has an additional feature on top of the regular AD1888 codec features.
22 * It has an Analog Input mode that is switched into (after disabling the 25 * It has an Analog Input mode that is switched into (after disabling the
@@ -38,10 +41,7 @@ void olpc_analog_input(struct snd_ac97 *ac97, int on)
38 } 41 }
39 42
40 /* set Analog Input through GPIO */ 43 /* set Analog Input through GPIO */
41 if (on) 44 gpio_set_value(OLPC_GPIO_MIC_AC, on);
42 geode_gpio_set(OLPC_GPIO_MIC_AC, GPIO_OUTPUT_VAL);
43 else
44 geode_gpio_clear(OLPC_GPIO_MIC_AC, GPIO_OUTPUT_VAL);
45} 45}
46 46
47/* 47/*
@@ -73,8 +73,7 @@ static int olpc_dc_info(struct snd_kcontrol *kctl,
73 73
74static int olpc_dc_get(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *v) 74static int olpc_dc_get(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *v)
75{ 75{
76 v->value.integer.value[0] = geode_gpio_isset(OLPC_GPIO_MIC_AC, 76 v->value.integer.value[0] = gpio_get_value(OLPC_GPIO_MIC_AC);
77 GPIO_OUTPUT_VAL);
78 return 0; 77 return 0;
79} 78}
80 79
@@ -153,6 +152,12 @@ int __devinit olpc_quirks(struct snd_card *card, struct snd_ac97 *ac97)
153 if (!machine_is_olpc()) 152 if (!machine_is_olpc())
154 return 0; 153 return 0;
155 154
155 if (gpio_request(OLPC_GPIO_MIC_AC, DRV_NAME)) {
156 printk(KERN_ERR DRV_NAME ": unable to allocate MIC GPIO\n");
157 return -EIO;
158 }
159 gpio_direction_output(OLPC_GPIO_MIC_AC, 0);
160
156 /* drop the original AD1888 HPF control */ 161 /* drop the original AD1888 HPF control */
157 memset(&elem, 0, sizeof(elem)); 162 memset(&elem, 0, sizeof(elem));
158 elem.iface = SNDRV_CTL_ELEM_IFACE_MIXER; 163 elem.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
@@ -169,11 +174,18 @@ int __devinit olpc_quirks(struct snd_card *card, struct snd_ac97 *ac97)
169 for (i = 0; i < ARRAY_SIZE(olpc_cs5535audio_ctls); i++) { 174 for (i = 0; i < ARRAY_SIZE(olpc_cs5535audio_ctls); i++) {
170 err = snd_ctl_add(card, snd_ctl_new1(&olpc_cs5535audio_ctls[i], 175 err = snd_ctl_add(card, snd_ctl_new1(&olpc_cs5535audio_ctls[i],
171 ac97->private_data)); 176 ac97->private_data));
172 if (err < 0) 177 if (err < 0) {
178 gpio_free(OLPC_GPIO_MIC_AC);
173 return err; 179 return err;
180 }
174 } 181 }
175 182
176 /* turn off the mic by default */ 183 /* turn off the mic by default */
177 olpc_mic_bias(ac97, 0); 184 olpc_mic_bias(ac97, 0);
178 return 0; 185 return 0;
179} 186}
187
188void __devexit olpc_quirks_cleanup(void)
189{
190 gpio_free(OLPC_GPIO_MIC_AC);
191}
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 75454648d50c..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>
@@ -166,18 +167,7 @@ static void ct_unmap_audio_buffer(struct ct_atc *atc, struct ct_atc_pcm *apcm)
166 167
167static unsigned long atc_get_ptp_phys(struct ct_atc *atc, int index) 168static unsigned long atc_get_ptp_phys(struct ct_atc *atc, int index)
168{ 169{
169 struct ct_vm *vm; 170 return atc->vm->get_ptp_phys(atc->vm, index);
170 void *kvirt_addr;
171 unsigned long phys_addr;
172
173 vm = atc->vm;
174 kvirt_addr = vm->get_ptp_virt(vm, index);
175 if (kvirt_addr == NULL)
176 phys_addr = (~0UL);
177 else
178 phys_addr = virt_to_phys(kvirt_addr);
179
180 return phys_addr;
181} 171}
182 172
183static unsigned int convert_format(snd_pcm_format_t snd_format) 173static unsigned int convert_format(snd_pcm_format_t snd_format)
@@ -240,7 +230,7 @@ static int select_rom(unsigned int pitch)
240 } else if (pitch == 0x02000000) { 230 } else if (pitch == 0x02000000) {
241 /* pitch == 2 */ 231 /* pitch == 2 */
242 return 3; 232 return 3;
243 } else if (pitch >= 0x0 && pitch <= 0x08000000) { 233 } else if (pitch <= 0x08000000) {
244 /* 0 <= pitch <= 8 */ 234 /* 0 <= pitch <= 8 */
245 return 0; 235 return 0;
246 } else { 236 } else {
@@ -1225,10 +1215,11 @@ static int atc_dev_free(struct snd_device *dev)
1225 return ct_atc_destroy(atc); 1215 return ct_atc_destroy(atc);
1226} 1216}
1227 1217
1228static int __devinit atc_identify_card(struct ct_atc *atc) 1218static int __devinit atc_identify_card(struct ct_atc *atc, unsigned int ssid)
1229{ 1219{
1230 const struct snd_pci_quirk *p; 1220 const struct snd_pci_quirk *p;
1231 const struct snd_pci_quirk *list; 1221 const struct snd_pci_quirk *list;
1222 u16 vendor_id, device_id;
1232 1223
1233 switch (atc->chip_type) { 1224 switch (atc->chip_type) {
1234 case ATC20K1: 1225 case ATC20K1:
@@ -1242,13 +1233,19 @@ static int __devinit atc_identify_card(struct ct_atc *atc)
1242 default: 1233 default:
1243 return -ENOENT; 1234 return -ENOENT;
1244 } 1235 }
1245 p = snd_pci_quirk_lookup(atc->pci, list); 1236 if (ssid) {
1237 vendor_id = ssid >> 16;
1238 device_id = ssid & 0xffff;
1239 } else {
1240 vendor_id = atc->pci->subsystem_vendor;
1241 device_id = atc->pci->subsystem_device;
1242 }
1243 p = snd_pci_quirk_lookup_id(vendor_id, device_id, list);
1246 if (p) { 1244 if (p) {
1247 if (p->value < 0) { 1245 if (p->value < 0) {
1248 printk(KERN_ERR "ctxfi: " 1246 printk(KERN_ERR "ctxfi: "
1249 "Device %04x:%04x is black-listed\n", 1247 "Device %04x:%04x is black-listed\n",
1250 atc->pci->subsystem_vendor, 1248 vendor_id, device_id);
1251 atc->pci->subsystem_device);
1252 return -ENOENT; 1249 return -ENOENT;
1253 } 1250 }
1254 atc->model = p->value; 1251 atc->model = p->value;
@@ -1261,8 +1258,7 @@ static int __devinit atc_identify_card(struct ct_atc *atc)
1261 atc->model_name = ct_subsys_name[atc->model]; 1258 atc->model_name = ct_subsys_name[atc->model];
1262 snd_printd("ctxfi: chip %s model %s (%04x:%04x) is found\n", 1259 snd_printd("ctxfi: chip %s model %s (%04x:%04x) is found\n",
1263 atc->chip_name, atc->model_name, 1260 atc->chip_name, atc->model_name,
1264 atc->pci->subsystem_vendor, 1261 vendor_id, device_id);
1265 atc->pci->subsystem_device);
1266 return 0; 1262 return 0;
1267} 1263}
1268 1264
@@ -1636,7 +1632,8 @@ static struct ct_atc atc_preset __devinitdata = {
1636 1632
1637int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci, 1633int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci,
1638 unsigned int rsr, unsigned int msr, 1634 unsigned int rsr, unsigned int msr,
1639 int chip_type, struct ct_atc **ratc) 1635 int chip_type, unsigned int ssid,
1636 struct ct_atc **ratc)
1640{ 1637{
1641 struct ct_atc *atc; 1638 struct ct_atc *atc;
1642 static struct snd_device_ops ops = { 1639 static struct snd_device_ops ops = {
@@ -1662,14 +1659,14 @@ int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci,
1662 mutex_init(&atc->atc_mutex); 1659 mutex_init(&atc->atc_mutex);
1663 1660
1664 /* Find card model */ 1661 /* Find card model */
1665 err = atc_identify_card(atc); 1662 err = atc_identify_card(atc, ssid);
1666 if (err < 0) { 1663 if (err < 0) {
1667 printk(KERN_ERR "ctatc: Card not recognised\n"); 1664 printk(KERN_ERR "ctatc: Card not recognised\n");
1668 goto error1; 1665 goto error1;
1669 } 1666 }
1670 1667
1671 /* Set up device virtual memory management object */ 1668 /* Set up device virtual memory management object */
1672 err = ct_vm_create(&atc->vm); 1669 err = ct_vm_create(&atc->vm, pci);
1673 if (err < 0) 1670 if (err < 0)
1674 goto error1; 1671 goto error1;
1675 1672
diff --git a/sound/pci/ctxfi/ctatc.h b/sound/pci/ctxfi/ctatc.h
index 9fd8a5708943..7167c0185d52 100644
--- a/sound/pci/ctxfi/ctatc.h
+++ b/sound/pci/ctxfi/ctatc.h
@@ -148,7 +148,7 @@ struct ct_atc {
148 148
149int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci, 149int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci,
150 unsigned int rsr, unsigned int msr, int chip_type, 150 unsigned int rsr, unsigned int msr, int chip_type,
151 struct ct_atc **ratc); 151 unsigned int subsysid, struct ct_atc **ratc);
152int __devinit ct_atc_create_alsa_devs(struct ct_atc *atc); 152int __devinit ct_atc_create_alsa_devs(struct ct_atc *atc);
153 153
154#endif /* CTATC_H */ 154#endif /* CTATC_H */
diff --git a/sound/pci/ctxfi/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/ctxfi/ctvmem.c b/sound/pci/ctxfi/ctvmem.c
index 6b78752e9503..65da6e466f80 100644
--- a/sound/pci/ctxfi/ctvmem.c
+++ b/sound/pci/ctxfi/ctvmem.c
@@ -138,7 +138,7 @@ ct_vm_map(struct ct_vm *vm, struct snd_pcm_substream *substream, int size)
138 return NULL; 138 return NULL;
139 } 139 }
140 140
141 ptp = vm->ptp[0]; 141 ptp = (unsigned long *)vm->ptp[0].area;
142 pte_start = (block->addr >> CT_PAGE_SHIFT); 142 pte_start = (block->addr >> CT_PAGE_SHIFT);
143 pages = block->size >> CT_PAGE_SHIFT; 143 pages = block->size >> CT_PAGE_SHIFT;
144 for (i = 0; i < pages; i++) { 144 for (i = 0; i < pages; i++) {
@@ -158,25 +158,25 @@ static void ct_vm_unmap(struct ct_vm *vm, struct ct_vm_block *block)
158} 158}
159 159
160/* * 160/* *
161 * return the host (kmalloced) addr of the @index-th device 161 * return the host physical addr of the @index-th device
162 * page talbe page on success, or NULL on failure. 162 * page table page on success, or ~0UL on failure.
163 * The first returned NULL indicates the termination. 163 * The first returned ~0UL indicates the termination.
164 * */ 164 * */
165static void * 165static dma_addr_t
166ct_get_ptp_virt(struct ct_vm *vm, int index) 166ct_get_ptp_phys(struct ct_vm *vm, int index)
167{ 167{
168 void *addr; 168 dma_addr_t addr;
169 169
170 addr = (index >= CT_PTP_NUM) ? NULL : vm->ptp[index]; 170 addr = (index >= CT_PTP_NUM) ? ~0UL : vm->ptp[index].addr;
171 171
172 return addr; 172 return addr;
173} 173}
174 174
175int ct_vm_create(struct ct_vm **rvm) 175int ct_vm_create(struct ct_vm **rvm, struct pci_dev *pci)
176{ 176{
177 struct ct_vm *vm; 177 struct ct_vm *vm;
178 struct ct_vm_block *block; 178 struct ct_vm_block *block;
179 int i; 179 int i, err = 0;
180 180
181 *rvm = NULL; 181 *rvm = NULL;
182 182
@@ -188,23 +188,21 @@ int ct_vm_create(struct ct_vm **rvm)
188 188
189 /* Allocate page table pages */ 189 /* Allocate page table pages */
190 for (i = 0; i < CT_PTP_NUM; i++) { 190 for (i = 0; i < CT_PTP_NUM; i++) {
191 vm->ptp[i] = kmalloc(PAGE_SIZE, GFP_KERNEL); 191 err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
192 if (!vm->ptp[i]) 192 snd_dma_pci_data(pci),
193 PAGE_SIZE, &vm->ptp[i]);
194 if (err < 0)
193 break; 195 break;
194 } 196 }
195 if (!i) { 197 if (err < 0) {
196 /* no page table pages are allocated */ 198 /* no page table pages are allocated */
197 kfree(vm); 199 ct_vm_destroy(vm);
198 return -ENOMEM; 200 return -ENOMEM;
199 } 201 }
200 vm->size = CT_ADDRS_PER_PAGE * i; 202 vm->size = CT_ADDRS_PER_PAGE * i;
201 /* Initialise remaining ptps */
202 for (; i < CT_PTP_NUM; i++)
203 vm->ptp[i] = NULL;
204
205 vm->map = ct_vm_map; 203 vm->map = ct_vm_map;
206 vm->unmap = ct_vm_unmap; 204 vm->unmap = ct_vm_unmap;
207 vm->get_ptp_virt = ct_get_ptp_virt; 205 vm->get_ptp_phys = ct_get_ptp_phys;
208 INIT_LIST_HEAD(&vm->unused); 206 INIT_LIST_HEAD(&vm->unused);
209 INIT_LIST_HEAD(&vm->used); 207 INIT_LIST_HEAD(&vm->used);
210 block = kzalloc(sizeof(*block), GFP_KERNEL); 208 block = kzalloc(sizeof(*block), GFP_KERNEL);
@@ -242,7 +240,7 @@ void ct_vm_destroy(struct ct_vm *vm)
242 240
243 /* free allocated page table pages */ 241 /* free allocated page table pages */
244 for (i = 0; i < CT_PTP_NUM; i++) 242 for (i = 0; i < CT_PTP_NUM; i++)
245 kfree(vm->ptp[i]); 243 snd_dma_free_pages(&vm->ptp[i]);
246 244
247 vm->size = 0; 245 vm->size = 0;
248 246
diff --git a/sound/pci/ctxfi/ctvmem.h b/sound/pci/ctxfi/ctvmem.h
index 01e4fd0386a3..b23adfca4de6 100644
--- a/sound/pci/ctxfi/ctvmem.h
+++ b/sound/pci/ctxfi/ctvmem.h
@@ -22,6 +22,8 @@
22 22
23#include <linux/mutex.h> 23#include <linux/mutex.h>
24#include <linux/list.h> 24#include <linux/list.h>
25#include <linux/pci.h>
26#include <sound/memalloc.h>
25 27
26/* The chip can handle the page table of 4k pages 28/* The chip can handle the page table of 4k pages
27 * (emu20k1 can handle even 8k pages, but we don't use it right now) 29 * (emu20k1 can handle even 8k pages, but we don't use it right now)
@@ -41,7 +43,7 @@ struct snd_pcm_substream;
41 43
42/* Virtual memory management object for card device */ 44/* Virtual memory management object for card device */
43struct ct_vm { 45struct ct_vm {
44 void *ptp[CT_PTP_NUM]; /* Device page table pages */ 46 struct snd_dma_buffer ptp[CT_PTP_NUM]; /* Device page table pages */
45 unsigned int size; /* Available addr space in bytes */ 47 unsigned int size; /* Available addr space in bytes */
46 struct list_head unused; /* List of unused blocks */ 48 struct list_head unused; /* List of unused blocks */
47 struct list_head used; /* List of used blocks */ 49 struct list_head used; /* List of used blocks */
@@ -52,10 +54,10 @@ struct ct_vm {
52 int size); 54 int size);
53 /* Unmap device logical addr area. */ 55 /* Unmap device logical addr area. */
54 void (*unmap)(struct ct_vm *, struct ct_vm_block *block); 56 void (*unmap)(struct ct_vm *, struct ct_vm_block *block);
55 void *(*get_ptp_virt)(struct ct_vm *vm, int index); 57 dma_addr_t (*get_ptp_phys)(struct ct_vm *vm, int index);
56}; 58};
57 59
58int ct_vm_create(struct ct_vm **rvm); 60int ct_vm_create(struct ct_vm **rvm, struct pci_dev *pci);
59void ct_vm_destroy(struct ct_vm *vm); 61void ct_vm_destroy(struct ct_vm *vm);
60 62
61#endif /* CTVMEM_H */ 63#endif /* CTVMEM_H */
diff --git a/sound/pci/ctxfi/xfi.c b/sound/pci/ctxfi/xfi.c
index 76541748e7bc..f42e7e1a1074 100644
--- a/sound/pci/ctxfi/xfi.c
+++ b/sound/pci/ctxfi/xfi.c
@@ -32,6 +32,7 @@ module_param(multiple, uint, S_IRUGO);
32static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; 32static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
33static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; 33static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
34static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; 34static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
35static unsigned int subsystem[SNDRV_CARDS];
35 36
36module_param_array(index, int, NULL, 0444); 37module_param_array(index, int, NULL, 0444);
37MODULE_PARM_DESC(index, "Index value for Creative X-Fi driver"); 38MODULE_PARM_DESC(index, "Index value for Creative X-Fi driver");
@@ -39,8 +40,10 @@ module_param_array(id, charp, NULL, 0444);
39MODULE_PARM_DESC(id, "ID string for Creative X-Fi driver"); 40MODULE_PARM_DESC(id, "ID string for Creative X-Fi driver");
40module_param_array(enable, bool, NULL, 0444); 41module_param_array(enable, bool, NULL, 0444);
41MODULE_PARM_DESC(enable, "Enable Creative X-Fi driver"); 42MODULE_PARM_DESC(enable, "Enable Creative X-Fi driver");
43module_param_array(subsystem, int, NULL, 0444);
44MODULE_PARM_DESC(subsystem, "Override subsystem ID for Creative X-Fi driver");
42 45
43static struct pci_device_id ct_pci_dev_ids[] = { 46static DEFINE_PCI_DEVICE_TABLE(ct_pci_dev_ids) = {
44 /* only X-Fi is supported, so... */ 47 /* only X-Fi is supported, so... */
45 { PCI_DEVICE(PCI_VENDOR_ID_CREATIVE, PCI_DEVICE_ID_CREATIVE_20K1), 48 { PCI_DEVICE(PCI_VENDOR_ID_CREATIVE, PCI_DEVICE_ID_CREATIVE_20K1),
46 .driver_data = ATC20K1, 49 .driver_data = ATC20K1,
@@ -85,7 +88,7 @@ ct_card_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
85 multiple = 2; 88 multiple = 2;
86 } 89 }
87 err = ct_atc_create(card, pci, reference_rate, multiple, 90 err = ct_atc_create(card, pci, reference_rate, multiple,
88 pci_id->driver_data, &atc); 91 pci_id->driver_data, subsystem[dev], &atc);
89 if (err < 0) 92 if (err < 0)
90 goto error; 93 goto error;
91 94
diff --git a/sound/pci/echoaudio/darla20.c b/sound/pci/echoaudio/darla20.c
index 8c6db3aa3c1a..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>
@@ -63,7 +63,7 @@ static const struct firmware card_fw[] = {
63 {0, "darla20_dsp.fw"} 63 {0, "darla20_dsp.fw"}
64}; 64};
65 65
66static struct pci_device_id snd_echo_ids[] = { 66static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
67 {0x1057, 0x1801, 0xECC0, 0x0010, 0, 0, 0}, /* DSP 56301 Darla20 rev.0 */ 67 {0x1057, 0x1801, 0xECC0, 0x0010, 0, 0, 0}, /* DSP 56301 Darla20 rev.0 */
68 {0,} 68 {0,}
69}; 69};
diff --git a/sound/pci/echoaudio/darla20_dsp.c b/sound/pci/echoaudio/darla20_dsp.c
index 29043301ebb8..20c7cbc89bb3 100644
--- a/sound/pci/echoaudio/darla20_dsp.c
+++ b/sound/pci/echoaudio/darla20_dsp.c
@@ -45,7 +45,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
45 chip->device_id = device_id; 45 chip->device_id = device_id;
46 chip->subdevice_id = subdevice_id; 46 chip->subdevice_id = subdevice_id;
47 chip->bad_board = TRUE; 47 chip->bad_board = TRUE;
48 chip->dsp_code_to_load = &card_fw[FW_DARLA20_DSP]; 48 chip->dsp_code_to_load = FW_DARLA20_DSP;
49 chip->spdif_status = GD_SPDIF_STATUS_UNDEF; 49 chip->spdif_status = GD_SPDIF_STATUS_UNDEF;
50 chip->clock_state = GD_CLOCK_UNDEF; 50 chip->clock_state = GD_CLOCK_UNDEF;
51 /* Since this card has no ASIC, mark it as loaded so everything 51 /* Since this card has no ASIC, mark it as loaded so everything
@@ -57,15 +57,19 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
57 return err; 57 return err;
58 chip->bad_board = FALSE; 58 chip->bad_board = FALSE;
59 59
60 if ((err = init_line_levels(chip)) < 0)
61 return err;
62
63 DE_INIT(("init_hw done\n")); 60 DE_INIT(("init_hw done\n"));
64 return err; 61 return err;
65} 62}
66 63
67 64
68 65
66static int set_mixer_defaults(struct echoaudio *chip)
67{
68 return init_line_levels(chip);
69}
70
71
72
69/* The Darla20 has no external clock sources */ 73/* The Darla20 has no external clock sources */
70static u32 detect_input_clocks(const struct echoaudio *chip) 74static u32 detect_input_clocks(const struct echoaudio *chip)
71{ 75{
diff --git a/sound/pci/echoaudio/darla24.c b/sound/pci/echoaudio/darla24.c
index 04cbf3eaf05a..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>
@@ -67,7 +67,7 @@ static const struct firmware card_fw[] = {
67 {0, "darla24_dsp.fw"} 67 {0, "darla24_dsp.fw"}
68}; 68};
69 69
70static struct pci_device_id snd_echo_ids[] = { 70static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
71 {0x1057, 0x1801, 0xECC0, 0x0040, 0, 0, 0}, /* DSP 56301 Darla24 rev.0 */ 71 {0x1057, 0x1801, 0xECC0, 0x0040, 0, 0, 0}, /* DSP 56301 Darla24 rev.0 */
72 {0x1057, 0x1801, 0xECC0, 0x0041, 0, 0, 0}, /* DSP 56301 Darla24 rev.1 */ 72 {0x1057, 0x1801, 0xECC0, 0x0041, 0, 0, 0}, /* DSP 56301 Darla24 rev.1 */
73 {0,} 73 {0,}
diff --git a/sound/pci/echoaudio/darla24_dsp.c b/sound/pci/echoaudio/darla24_dsp.c
index 60228731841f..6da6663e9176 100644
--- a/sound/pci/echoaudio/darla24_dsp.c
+++ b/sound/pci/echoaudio/darla24_dsp.c
@@ -45,7 +45,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
45 chip->device_id = device_id; 45 chip->device_id = device_id;
46 chip->subdevice_id = subdevice_id; 46 chip->subdevice_id = subdevice_id;
47 chip->bad_board = TRUE; 47 chip->bad_board = TRUE;
48 chip->dsp_code_to_load = &card_fw[FW_DARLA24_DSP]; 48 chip->dsp_code_to_load = FW_DARLA24_DSP;
49 /* Since this card has no ASIC, mark it as loaded so everything 49 /* Since this card has no ASIC, mark it as loaded so everything
50 works OK */ 50 works OK */
51 chip->asic_loaded = TRUE; 51 chip->asic_loaded = TRUE;
@@ -56,15 +56,19 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
56 return err; 56 return err;
57 chip->bad_board = FALSE; 57 chip->bad_board = FALSE;
58 58
59 if ((err = init_line_levels(chip)) < 0)
60 return err;
61
62 DE_INIT(("init_hw done\n")); 59 DE_INIT(("init_hw done\n"));
63 return err; 60 return err;
64} 61}
65 62
66 63
67 64
65static int set_mixer_defaults(struct echoaudio *chip)
66{
67 return init_line_levels(chip);
68}
69
70
71
68static u32 detect_input_clocks(const struct echoaudio *chip) 72static u32 detect_input_clocks(const struct echoaudio *chip)
69{ 73{
70 u32 clocks_from_dsp, clock_bits; 74 u32 clocks_from_dsp, clock_bits;
diff --git a/sound/pci/echoaudio/echo3g.c b/sound/pci/echoaudio/echo3g.c
index 4022e43a0053..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>
@@ -81,7 +81,7 @@ static const struct firmware card_fw[] = {
81 {0, "3g_asic.fw"} 81 {0, "3g_asic.fw"}
82}; 82};
83 83
84static struct pci_device_id snd_echo_ids[] = { 84static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
85 {0x1057, 0x3410, 0xECC0, 0x0100, 0, 0, 0}, /* Echo 3G */ 85 {0x1057, 0x3410, 0xECC0, 0x0100, 0, 0, 0}, /* Echo 3G */
86 {0,} 86 {0,}
87}; 87};
diff --git a/sound/pci/echoaudio/echo3g_dsp.c b/sound/pci/echoaudio/echo3g_dsp.c
index 57967e580571..3cdc2ee2d1dd 100644
--- a/sound/pci/echoaudio/echo3g_dsp.c
+++ b/sound/pci/echoaudio/echo3g_dsp.c
@@ -61,7 +61,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
61 chip->subdevice_id = subdevice_id; 61 chip->subdevice_id = subdevice_id;
62 chip->bad_board = TRUE; 62 chip->bad_board = TRUE;
63 chip->has_midi = TRUE; 63 chip->has_midi = TRUE;
64 chip->dsp_code_to_load = &card_fw[FW_ECHO3G_DSP]; 64 chip->dsp_code_to_load = FW_ECHO3G_DSP;
65 65
66 /* Load the DSP code and the ASIC on the PCI card and get 66 /* Load the DSP code and the ASIC on the PCI card and get
67 what type of external box is attached */ 67 what type of external box is attached */
@@ -97,20 +97,6 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
97 chip->digital_modes = ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA | 97 chip->digital_modes = ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA |
98 ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL | 98 ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL |
99 ECHOCAPS_HAS_DIGITAL_MODE_ADAT; 99 ECHOCAPS_HAS_DIGITAL_MODE_ADAT;
100 chip->digital_mode = DIGITAL_MODE_SPDIF_RCA;
101 chip->professional_spdif = FALSE;
102 chip->non_audio_spdif = FALSE;
103 chip->bad_board = FALSE;
104
105 if ((err = init_line_levels(chip)) < 0)
106 return err;
107 err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA);
108 if (err < 0)
109 return err;
110 err = set_phantom_power(chip, 0);
111 if (err < 0)
112 return err;
113 err = set_professional_spdif(chip, TRUE);
114 100
115 DE_INIT(("init_hw done\n")); 101 DE_INIT(("init_hw done\n"));
116 return err; 102 return err;
@@ -118,6 +104,18 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
118 104
119 105
120 106
107static int set_mixer_defaults(struct echoaudio *chip)
108{
109 chip->digital_mode = DIGITAL_MODE_SPDIF_RCA;
110 chip->professional_spdif = FALSE;
111 chip->non_audio_spdif = FALSE;
112 chip->bad_board = FALSE;
113 chip->phantom_power = FALSE;
114 return init_line_levels(chip);
115}
116
117
118
121static int set_phantom_power(struct echoaudio *chip, char on) 119static int set_phantom_power(struct echoaudio *chip, char on)
122{ 120{
123 u32 control_reg = le32_to_cpu(chip->comm_page->control_register); 121 u32 control_reg = le32_to_cpu(chip->comm_page->control_register);
diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c
index 1305f7ca02c3..668a5ec04499 100644
--- a/sound/pci/echoaudio/echoaudio.c
+++ b/sound/pci/echoaudio/echoaudio.c
@@ -36,22 +36,61 @@ MODULE_PARM_DESC(enable, "Enable " ECHOCARD_NAME " soundcard.");
36static unsigned int channels_list[10] = {1, 2, 4, 6, 8, 10, 12, 14, 16, 999999}; 36static unsigned int channels_list[10] = {1, 2, 4, 6, 8, 10, 12, 14, 16, 999999};
37static const DECLARE_TLV_DB_SCALE(db_scale_output_gain, -12800, 100, 1); 37static const DECLARE_TLV_DB_SCALE(db_scale_output_gain, -12800, 100, 1);
38 38
39
40
39static int get_firmware(const struct firmware **fw_entry, 41static int get_firmware(const struct firmware **fw_entry,
40 const struct firmware *frm, struct echoaudio *chip) 42 struct echoaudio *chip, const short fw_index)
41{ 43{
42 int err; 44 int err;
43 char name[30]; 45 char name[30];
44 DE_ACT(("firmware requested: %s\n", frm->data)); 46
45 snprintf(name, sizeof(name), "ea/%s", frm->data); 47#ifdef CONFIG_PM
46 if ((err = request_firmware(fw_entry, name, pci_device(chip))) < 0) 48 if (chip->fw_cache[fw_index]) {
49 DE_ACT(("firmware requested: %s is cached\n", card_fw[fw_index].data));
50 *fw_entry = chip->fw_cache[fw_index];
51 return 0;
52 }
53#endif
54
55 DE_ACT(("firmware requested: %s\n", card_fw[fw_index].data));
56 snprintf(name, sizeof(name), "ea/%s", card_fw[fw_index].data);
57 err = request_firmware(fw_entry, name, pci_device(chip));
58 if (err < 0)
47 snd_printk(KERN_ERR "get_firmware(): Firmware not available (%d)\n", err); 59 snd_printk(KERN_ERR "get_firmware(): Firmware not available (%d)\n", err);
60#ifdef CONFIG_PM
61 else
62 chip->fw_cache[fw_index] = *fw_entry;
63#endif
48 return err; 64 return err;
49} 65}
50 66
67
68
51static void free_firmware(const struct firmware *fw_entry) 69static void free_firmware(const struct firmware *fw_entry)
52{ 70{
71#ifdef CONFIG_PM
72 DE_ACT(("firmware not released (kept in cache)\n"));
73#else
53 release_firmware(fw_entry); 74 release_firmware(fw_entry);
54 DE_ACT(("firmware released\n")); 75 DE_ACT(("firmware released\n"));
76#endif
77}
78
79
80
81static void free_firmware_cache(struct echoaudio *chip)
82{
83#ifdef CONFIG_PM
84 int i;
85
86 for (i = 0; i < 8 ; i++)
87 if (chip->fw_cache[i]) {
88 release_firmware(chip->fw_cache[i]);
89 DE_ACT(("release_firmware(%d)\n", i));
90 }
91
92 DE_ACT(("firmware_cache released\n"));
93#endif
55} 94}
56 95
57 96
@@ -714,6 +753,8 @@ static int pcm_trigger(struct snd_pcm_substream *substream, int cmd)
714 753
715 spin_lock(&chip->lock); 754 spin_lock(&chip->lock);
716 switch (cmd) { 755 switch (cmd) {
756 case SNDRV_PCM_TRIGGER_RESUME:
757 DE_ACT(("pcm_trigger resume\n"));
717 case SNDRV_PCM_TRIGGER_START: 758 case SNDRV_PCM_TRIGGER_START:
718 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 759 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
719 DE_ACT(("pcm_trigger start\n")); 760 DE_ACT(("pcm_trigger start\n"));
@@ -737,6 +778,8 @@ static int pcm_trigger(struct snd_pcm_substream *substream, int cmd)
737 err = start_transport(chip, channelmask, 778 err = start_transport(chip, channelmask,
738 chip->pipe_cyclic_mask); 779 chip->pipe_cyclic_mask);
739 break; 780 break;
781 case SNDRV_PCM_TRIGGER_SUSPEND:
782 DE_ACT(("pcm_trigger suspend\n"));
740 case SNDRV_PCM_TRIGGER_STOP: 783 case SNDRV_PCM_TRIGGER_STOP:
741 DE_ACT(("pcm_trigger stop\n")); 784 DE_ACT(("pcm_trigger stop\n"));
742 for (i = 0; i < DSP_MAXPIPES; i++) { 785 for (i = 0; i < DSP_MAXPIPES; i++) {
@@ -1821,7 +1864,9 @@ static irqreturn_t snd_echo_interrupt(int irq, void *dev_id)
1821 /* The hardware doesn't tell us which substream caused the irq, 1864 /* The hardware doesn't tell us which substream caused the irq,
1822 thus we have to check all running substreams. */ 1865 thus we have to check all running substreams. */
1823 for (ss = 0; ss < DSP_MAXPIPES; ss++) { 1866 for (ss = 0; ss < DSP_MAXPIPES; ss++) {
1824 if ((substream = chip->substream[ss])) { 1867 substream = chip->substream[ss];
1868 if (substream && ((struct audiopipe *)substream->runtime->
1869 private_data)->state == PIPE_STATE_STARTED) {
1825 period = pcm_pointer(substream) / 1870 period = pcm_pointer(substream) /
1826 substream->runtime->period_size; 1871 substream->runtime->period_size;
1827 if (period != chip->last_period[ss]) { 1872 if (period != chip->last_period[ss]) {
@@ -1874,6 +1919,7 @@ static int snd_echo_free(struct echoaudio *chip)
1874 pci_disable_device(chip->pci); 1919 pci_disable_device(chip->pci);
1875 1920
1876 /* release chip data */ 1921 /* release chip data */
1922 free_firmware_cache(chip);
1877 kfree(chip); 1923 kfree(chip);
1878 DE_INIT(("Chip freed.\n")); 1924 DE_INIT(("Chip freed.\n"));
1879 return 0; 1925 return 0;
@@ -1911,18 +1957,27 @@ static __devinit int snd_echo_create(struct snd_card *card,
1911 return err; 1957 return err;
1912 pci_set_master(pci); 1958 pci_set_master(pci);
1913 1959
1914 /* allocate a chip-specific data */ 1960 /* Allocate chip if needed */
1915 chip = kzalloc(sizeof(*chip), GFP_KERNEL); 1961 if (!*rchip) {
1916 if (!chip) { 1962 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
1917 pci_disable_device(pci); 1963 if (!chip) {
1918 return -ENOMEM; 1964 pci_disable_device(pci);
1965 return -ENOMEM;
1966 }
1967 DE_INIT(("chip=%p\n", chip));
1968 spin_lock_init(&chip->lock);
1969 chip->card = card;
1970 chip->pci = pci;
1971 chip->irq = -1;
1972 atomic_set(&chip->opencount, 0);
1973 mutex_init(&chip->mode_mutex);
1974 chip->can_set_rate = 1;
1975 } else {
1976 /* If this was called from the resume function, chip is
1977 * already allocated and it contains current card settings.
1978 */
1979 chip = *rchip;
1919 } 1980 }
1920 DE_INIT(("chip=%p\n", chip));
1921
1922 spin_lock_init(&chip->lock);
1923 chip->card = card;
1924 chip->pci = pci;
1925 chip->irq = -1;
1926 1981
1927 /* PCI resource allocation */ 1982 /* PCI resource allocation */
1928 chip->dsp_registers_phys = pci_resource_start(pci, 0); 1983 chip->dsp_registers_phys = pci_resource_start(pci, 0);
@@ -1962,7 +2017,9 @@ static __devinit int snd_echo_create(struct snd_card *card,
1962 chip->comm_page = (struct comm_page *)chip->commpage_dma_buf.area; 2017 chip->comm_page = (struct comm_page *)chip->commpage_dma_buf.area;
1963 2018
1964 err = init_hw(chip, chip->pci->device, chip->pci->subsystem_device); 2019 err = init_hw(chip, chip->pci->device, chip->pci->subsystem_device);
1965 if (err) { 2020 if (err >= 0)
2021 err = set_mixer_defaults(chip);
2022 if (err < 0) {
1966 DE_INIT(("init_hw err=%d\n", err)); 2023 DE_INIT(("init_hw err=%d\n", err));
1967 snd_echo_free(chip); 2024 snd_echo_free(chip);
1968 return err; 2025 return err;
@@ -1973,9 +2030,6 @@ static __devinit int snd_echo_create(struct snd_card *card,
1973 snd_echo_free(chip); 2030 snd_echo_free(chip);
1974 return err; 2031 return err;
1975 } 2032 }
1976 atomic_set(&chip->opencount, 0);
1977 mutex_init(&chip->mode_mutex);
1978 chip->can_set_rate = 1;
1979 *rchip = chip; 2033 *rchip = chip;
1980 /* Init done ! */ 2034 /* Init done ! */
1981 return 0; 2035 return 0;
@@ -2008,6 +2062,7 @@ static int __devinit snd_echo_probe(struct pci_dev *pci,
2008 2062
2009 snd_card_set_dev(card, &pci->dev); 2063 snd_card_set_dev(card, &pci->dev);
2010 2064
2065 chip = NULL; /* Tells snd_echo_create to allocate chip */
2011 if ((err = snd_echo_create(card, pci, &chip)) < 0) { 2066 if ((err = snd_echo_create(card, pci, &chip)) < 0) {
2012 snd_card_free(card); 2067 snd_card_free(card);
2013 return err; 2068 return err;
@@ -2129,10 +2184,9 @@ static int __devinit snd_echo_probe(struct pci_dev *pci,
2129 goto ctl_error; 2184 goto ctl_error;
2130#endif 2185#endif
2131 2186
2132 if ((err = snd_card_register(card)) < 0) { 2187 err = snd_card_register(card);
2133 snd_card_free(card); 2188 if (err < 0)
2134 goto ctl_error; 2189 goto ctl_error;
2135 }
2136 snd_printk(KERN_INFO "Card registered: %s\n", card->longname); 2190 snd_printk(KERN_INFO "Card registered: %s\n", card->longname);
2137 2191
2138 pci_set_drvdata(pci, chip); 2192 pci_set_drvdata(pci, chip);
@@ -2147,6 +2201,112 @@ ctl_error:
2147 2201
2148 2202
2149 2203
2204#if defined(CONFIG_PM)
2205
2206static int snd_echo_suspend(struct pci_dev *pci, pm_message_t state)
2207{
2208 struct echoaudio *chip = pci_get_drvdata(pci);
2209
2210 DE_INIT(("suspend start\n"));
2211 snd_pcm_suspend_all(chip->analog_pcm);
2212 snd_pcm_suspend_all(chip->digital_pcm);
2213
2214#ifdef ECHOCARD_HAS_MIDI
2215 /* This call can sleep */
2216 if (chip->midi_out)
2217 snd_echo_midi_output_trigger(chip->midi_out, 0);
2218#endif
2219 spin_lock_irq(&chip->lock);
2220 if (wait_handshake(chip)) {
2221 spin_unlock_irq(&chip->lock);
2222 return -EIO;
2223 }
2224 clear_handshake(chip);
2225 if (send_vector(chip, DSP_VC_GO_COMATOSE) < 0) {
2226 spin_unlock_irq(&chip->lock);
2227 return -EIO;
2228 }
2229 spin_unlock_irq(&chip->lock);
2230
2231 chip->dsp_code = NULL;
2232 free_irq(chip->irq, chip);
2233 chip->irq = -1;
2234 pci_save_state(pci);
2235 pci_disable_device(pci);
2236
2237 DE_INIT(("suspend done\n"));
2238 return 0;
2239}
2240
2241
2242
2243static int snd_echo_resume(struct pci_dev *pci)
2244{
2245 struct echoaudio *chip = pci_get_drvdata(pci);
2246 struct comm_page *commpage, *commpage_bak;
2247 u32 pipe_alloc_mask;
2248 int err;
2249
2250 DE_INIT(("resume start\n"));
2251 pci_restore_state(pci);
2252 commpage_bak = kmalloc(sizeof(struct echoaudio), GFP_KERNEL);
2253 commpage = chip->comm_page;
2254 memcpy(commpage_bak, commpage, sizeof(struct comm_page));
2255
2256 err = init_hw(chip, chip->pci->device, chip->pci->subsystem_device);
2257 if (err < 0) {
2258 kfree(commpage_bak);
2259 DE_INIT(("resume init_hw err=%d\n", err));
2260 snd_echo_free(chip);
2261 return err;
2262 }
2263 DE_INIT(("resume init OK\n"));
2264
2265 /* Temporarily set chip->pipe_alloc_mask=0 otherwise
2266 * restore_dsp_settings() fails.
2267 */
2268 pipe_alloc_mask = chip->pipe_alloc_mask;
2269 chip->pipe_alloc_mask = 0;
2270 err = restore_dsp_rettings(chip);
2271 chip->pipe_alloc_mask = pipe_alloc_mask;
2272 if (err < 0) {
2273 kfree(commpage_bak);
2274 return err;
2275 }
2276 DE_INIT(("resume restore OK\n"));
2277
2278 memcpy(&commpage->audio_format, &commpage_bak->audio_format,
2279 sizeof(commpage->audio_format));
2280 memcpy(&commpage->sglist_addr, &commpage_bak->sglist_addr,
2281 sizeof(commpage->sglist_addr));
2282 memcpy(&commpage->midi_output, &commpage_bak->midi_output,
2283 sizeof(commpage->midi_output));
2284 kfree(commpage_bak);
2285
2286 if (request_irq(pci->irq, snd_echo_interrupt, IRQF_SHARED,
2287 ECHOCARD_NAME, chip)) {
2288 snd_echo_free(chip);
2289 snd_printk(KERN_ERR "cannot grab irq\n");
2290 return -EBUSY;
2291 }
2292 chip->irq = pci->irq;
2293 DE_INIT(("resume irq=%d\n", chip->irq));
2294
2295#ifdef ECHOCARD_HAS_MIDI
2296 if (chip->midi_input_enabled)
2297 enable_midi_input(chip, TRUE);
2298 if (chip->midi_out)
2299 snd_echo_midi_output_trigger(chip->midi_out, 1);
2300#endif
2301
2302 DE_INIT(("resume done\n"));
2303 return 0;
2304}
2305
2306#endif /* CONFIG_PM */
2307
2308
2309
2150static void __devexit snd_echo_remove(struct pci_dev *pci) 2310static void __devexit snd_echo_remove(struct pci_dev *pci)
2151{ 2311{
2152 struct echoaudio *chip; 2312 struct echoaudio *chip;
@@ -2169,6 +2329,10 @@ static struct pci_driver driver = {
2169 .id_table = snd_echo_ids, 2329 .id_table = snd_echo_ids,
2170 .probe = snd_echo_probe, 2330 .probe = snd_echo_probe,
2171 .remove = __devexit_p(snd_echo_remove), 2331 .remove = __devexit_p(snd_echo_remove),
2332#ifdef CONFIG_PM
2333 .suspend = snd_echo_suspend,
2334 .resume = snd_echo_resume,
2335#endif /* CONFIG_PM */
2172}; 2336};
2173 2337
2174 2338
diff --git a/sound/pci/echoaudio/echoaudio.h b/sound/pci/echoaudio/echoaudio.h
index f9490ae36c2e..1df974dcb5f4 100644
--- a/sound/pci/echoaudio/echoaudio.h
+++ b/sound/pci/echoaudio/echoaudio.h
@@ -442,13 +442,16 @@ struct echoaudio {
442 u16 device_id, subdevice_id; 442 u16 device_id, subdevice_id;
443 u16 *dsp_code; /* Current DSP code loaded, 443 u16 *dsp_code; /* Current DSP code loaded,
444 * NULL if nothing loaded */ 444 * NULL if nothing loaded */
445 const struct firmware *dsp_code_to_load;/* DSP code to load */ 445 short dsp_code_to_load; /* DSP code to load */
446 const struct firmware *asic_code; /* Current ASIC code */ 446 short asic_code; /* Current ASIC code */
447 u32 comm_page_phys; /* Physical address of the 447 u32 comm_page_phys; /* Physical address of the
448 * memory seen by DSP */ 448 * memory seen by DSP */
449 volatile u32 __iomem *dsp_registers; /* DSP's register base */ 449 volatile u32 __iomem *dsp_registers; /* DSP's register base */
450 u32 active_mask; /* Chs. active mask or 450 u32 active_mask; /* Chs. active mask or
451 * punks out */ 451 * punks out */
452#ifdef CONFIG_PM
453 const struct firmware *fw_cache[8]; /* Cached firmwares */
454#endif
452 455
453#ifdef ECHOCARD_HAS_MIDI 456#ifdef ECHOCARD_HAS_MIDI
454 u16 mtc_state; /* State for MIDI input parsing state machine */ 457 u16 mtc_state; /* State for MIDI input parsing state machine */
@@ -464,11 +467,13 @@ static int load_firmware(struct echoaudio *chip);
464static int wait_handshake(struct echoaudio *chip); 467static int wait_handshake(struct echoaudio *chip);
465static int send_vector(struct echoaudio *chip, u32 command); 468static int send_vector(struct echoaudio *chip, u32 command);
466static int get_firmware(const struct firmware **fw_entry, 469static int get_firmware(const struct firmware **fw_entry,
467 const struct firmware *frm, struct echoaudio *chip); 470 struct echoaudio *chip, const short fw_index);
468static void free_firmware(const struct firmware *fw_entry); 471static void free_firmware(const struct firmware *fw_entry);
469 472
470#ifdef ECHOCARD_HAS_MIDI 473#ifdef ECHOCARD_HAS_MIDI
471static int enable_midi_input(struct echoaudio *chip, char enable); 474static int enable_midi_input(struct echoaudio *chip, char enable);
475static void snd_echo_midi_output_trigger(
476 struct snd_rawmidi_substream *substream, int up);
472static int midi_service_irq(struct echoaudio *chip); 477static int midi_service_irq(struct echoaudio *chip);
473static int __devinit snd_echo_midi_create(struct snd_card *card, 478static int __devinit snd_echo_midi_create(struct snd_card *card,
474 struct echoaudio *chip); 479 struct echoaudio *chip);
diff --git a/sound/pci/echoaudio/echoaudio_3g.c b/sound/pci/echoaudio/echoaudio_3g.c
index e32a74897921..658db44ef746 100644
--- a/sound/pci/echoaudio/echoaudio_3g.c
+++ b/sound/pci/echoaudio/echoaudio_3g.c
@@ -227,12 +227,11 @@ static int load_asic(struct echoaudio *chip)
227 /* Give the DSP a few milliseconds to settle down */ 227 /* Give the DSP a few milliseconds to settle down */
228 mdelay(2); 228 mdelay(2);
229 229
230 err = load_asic_generic(chip, DSP_FNC_LOAD_3G_ASIC, 230 err = load_asic_generic(chip, DSP_FNC_LOAD_3G_ASIC, FW_3G_ASIC);
231 &card_fw[FW_3G_ASIC]);
232 if (err < 0) 231 if (err < 0)
233 return err; 232 return err;
234 233
235 chip->asic_code = &card_fw[FW_3G_ASIC]; 234 chip->asic_code = FW_3G_ASIC;
236 235
237 /* Now give the new ASIC some time to set up */ 236 /* Now give the new ASIC some time to set up */
238 msleep(1000); 237 msleep(1000);
diff --git a/sound/pci/echoaudio/echoaudio_dsp.c b/sound/pci/echoaudio/echoaudio_dsp.c
index 4df51ef5e095..64417a733220 100644
--- a/sound/pci/echoaudio/echoaudio_dsp.c
+++ b/sound/pci/echoaudio/echoaudio_dsp.c
@@ -175,15 +175,15 @@ static inline int check_asic_status(struct echoaudio *chip)
175#ifdef ECHOCARD_HAS_ASIC 175#ifdef ECHOCARD_HAS_ASIC
176 176
177/* Load ASIC code - done after the DSP is loaded */ 177/* Load ASIC code - done after the DSP is loaded */
178static int load_asic_generic(struct echoaudio *chip, u32 cmd, 178static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic)
179 const struct firmware *asic)
180{ 179{
181 const struct firmware *fw; 180 const struct firmware *fw;
182 int err; 181 int err;
183 u32 i, size; 182 u32 i, size;
184 u8 *code; 183 u8 *code;
185 184
186 if ((err = get_firmware(&fw, asic, chip)) < 0) { 185 err = get_firmware(&fw, chip, asic);
186 if (err < 0) {
187 snd_printk(KERN_WARNING "Firmware not found !\n"); 187 snd_printk(KERN_WARNING "Firmware not found !\n");
188 return err; 188 return err;
189 } 189 }
@@ -245,7 +245,8 @@ static int install_resident_loader(struct echoaudio *chip)
245 return 0; 245 return 0;
246 } 246 }
247 247
248 if ((i = get_firmware(&fw, &card_fw[FW_361_LOADER], chip)) < 0) { 248 i = get_firmware(&fw, chip, FW_361_LOADER);
249 if (i < 0) {
249 snd_printk(KERN_WARNING "Firmware not found !\n"); 250 snd_printk(KERN_WARNING "Firmware not found !\n");
250 return i; 251 return i;
251 } 252 }
@@ -485,7 +486,8 @@ static int load_firmware(struct echoaudio *chip)
485 chip->dsp_code = NULL; 486 chip->dsp_code = NULL;
486 } 487 }
487 488
488 if ((err = get_firmware(&fw, chip->dsp_code_to_load, chip)) < 0) 489 err = get_firmware(&fw, chip, chip->dsp_code_to_load);
490 if (err < 0)
489 return err; 491 return err;
490 err = load_dsp(chip, (u16 *)fw->data); 492 err = load_dsp(chip, (u16 *)fw->data);
491 free_firmware(fw); 493 free_firmware(fw);
@@ -495,9 +497,6 @@ static int load_firmware(struct echoaudio *chip)
495 if ((box_type = load_asic(chip)) < 0) 497 if ((box_type = load_asic(chip)) < 0)
496 return box_type; /* error */ 498 return box_type; /* error */
497 499
498 if ((err = restore_dsp_rettings(chip)) < 0)
499 return err;
500
501 return box_type; 500 return box_type;
502} 501}
503 502
@@ -657,51 +656,106 @@ static void get_audio_meters(struct echoaudio *chip, long *meters)
657 656
658static int restore_dsp_rettings(struct echoaudio *chip) 657static int restore_dsp_rettings(struct echoaudio *chip)
659{ 658{
660 int err; 659 int i, o, err;
661 DE_INIT(("restore_dsp_settings\n")); 660 DE_INIT(("restore_dsp_settings\n"));
662 661
663 if ((err = check_asic_status(chip)) < 0) 662 if ((err = check_asic_status(chip)) < 0)
664 return err; 663 return err;
665 664
666 /* @ Gina20/Darla20 only. Should be harmless for other cards. */ 665 /* Gina20/Darla20 only. Should be harmless for other cards. */
667 chip->comm_page->gd_clock_state = GD_CLOCK_UNDEF; 666 chip->comm_page->gd_clock_state = GD_CLOCK_UNDEF;
668 chip->comm_page->gd_spdif_status = GD_SPDIF_STATUS_UNDEF; 667 chip->comm_page->gd_spdif_status = GD_SPDIF_STATUS_UNDEF;
669 chip->comm_page->handshake = 0xffffffff; 668 chip->comm_page->handshake = 0xffffffff;
670 669
671 if ((err = set_sample_rate(chip, chip->sample_rate)) < 0) 670 /* Restore output busses */
671 for (i = 0; i < num_busses_out(chip); i++) {
672 err = set_output_gain(chip, i, chip->output_gain[i]);
673 if (err < 0)
674 return err;
675 }
676
677#ifdef ECHOCARD_HAS_VMIXER
678 for (i = 0; i < num_pipes_out(chip); i++)
679 for (o = 0; o < num_busses_out(chip); o++) {
680 err = set_vmixer_gain(chip, o, i,
681 chip->vmixer_gain[o][i]);
682 if (err < 0)
683 return err;
684 }
685 if (update_vmixer_level(chip) < 0)
686 return -EIO;
687#endif /* ECHOCARD_HAS_VMIXER */
688
689#ifdef ECHOCARD_HAS_MONITOR
690 for (o = 0; o < num_busses_out(chip); o++)
691 for (i = 0; i < num_busses_in(chip); i++) {
692 err = set_monitor_gain(chip, o, i,
693 chip->monitor_gain[o][i]);
694 if (err < 0)
695 return err;
696 }
697#endif /* ECHOCARD_HAS_MONITOR */
698
699#ifdef ECHOCARD_HAS_INPUT_GAIN
700 for (i = 0; i < num_busses_in(chip); i++) {
701 err = set_input_gain(chip, i, chip->input_gain[i]);
702 if (err < 0)
703 return err;
704 }
705#endif /* ECHOCARD_HAS_INPUT_GAIN */
706
707 err = update_output_line_level(chip);
708 if (err < 0)
672 return err; 709 return err;
673 710
674 if (chip->meters_enabled) 711 err = update_input_line_level(chip);
675 if (send_vector(chip, DSP_VC_METERS_ON) < 0) 712 if (err < 0)
676 return -EIO; 713 return err;
677 714
678#ifdef ECHOCARD_HAS_EXTERNAL_CLOCK 715 err = set_sample_rate(chip, chip->sample_rate);
679 if (set_input_clock(chip, chip->input_clock) < 0) 716 if (err < 0)
717 return err;
718
719 if (chip->meters_enabled) {
720 err = send_vector(chip, DSP_VC_METERS_ON);
721 if (err < 0)
722 return err;
723 }
724
725#ifdef ECHOCARD_HAS_DIGITAL_MODE_SWITCH
726 if (set_digital_mode(chip, chip->digital_mode) < 0)
680 return -EIO; 727 return -EIO;
681#endif 728#endif
682 729
683#ifdef ECHOCARD_HAS_OUTPUT_CLOCK_SWITCH 730#ifdef ECHOCARD_HAS_DIGITAL_IO
684 if (set_output_clock(chip, chip->output_clock) < 0) 731 if (set_professional_spdif(chip, chip->professional_spdif) < 0)
685 return -EIO; 732 return -EIO;
686#endif 733#endif
687 734
688 if (update_output_line_level(chip) < 0) 735#ifdef ECHOCARD_HAS_PHANTOM_POWER
736 if (set_phantom_power(chip, chip->phantom_power) < 0)
689 return -EIO; 737 return -EIO;
738#endif
690 739
691 if (update_input_line_level(chip) < 0) 740#ifdef ECHOCARD_HAS_EXTERNAL_CLOCK
741 /* set_input_clock() also restores automute setting */
742 if (set_input_clock(chip, chip->input_clock) < 0)
692 return -EIO; 743 return -EIO;
744#endif
693 745
694#ifdef ECHOCARD_HAS_VMIXER 746#ifdef ECHOCARD_HAS_OUTPUT_CLOCK_SWITCH
695 if (update_vmixer_level(chip) < 0) 747 if (set_output_clock(chip, chip->output_clock) < 0)
696 return -EIO; 748 return -EIO;
697#endif 749#endif
698 750
699 if (wait_handshake(chip) < 0) 751 if (wait_handshake(chip) < 0)
700 return -EIO; 752 return -EIO;
701 clear_handshake(chip); 753 clear_handshake(chip);
754 if (send_vector(chip, DSP_VC_UPDATE_FLAGS) < 0)
755 return -EIO;
702 756
703 DE_INIT(("restore_dsp_rettings done\n")); 757 DE_INIT(("restore_dsp_rettings done\n"));
704 return send_vector(chip, DSP_VC_UPDATE_FLAGS); 758 return 0;
705} 759}
706 760
707 761
@@ -918,9 +972,6 @@ static int init_dsp_comm_page(struct echoaudio *chip)
918 chip->card_name = ECHOCARD_NAME; 972 chip->card_name = ECHOCARD_NAME;
919 chip->bad_board = TRUE; /* Set TRUE until DSP loaded */ 973 chip->bad_board = TRUE; /* Set TRUE until DSP loaded */
920 chip->dsp_code = NULL; /* Current DSP code not loaded */ 974 chip->dsp_code = NULL; /* Current DSP code not loaded */
921 chip->digital_mode = DIGITAL_MODE_NONE;
922 chip->input_clock = ECHO_CLOCK_INTERNAL;
923 chip->output_clock = ECHO_CLOCK_WORD;
924 chip->asic_loaded = FALSE; 975 chip->asic_loaded = FALSE;
925 memset(chip->comm_page, 0, sizeof(struct comm_page)); 976 memset(chip->comm_page, 0, sizeof(struct comm_page));
926 977
@@ -931,7 +982,6 @@ static int init_dsp_comm_page(struct echoaudio *chip)
931 chip->comm_page->midi_out_free_count = 982 chip->comm_page->midi_out_free_count =
932 cpu_to_le32(DSP_MIDI_OUT_FIFO_SIZE); 983 cpu_to_le32(DSP_MIDI_OUT_FIFO_SIZE);
933 chip->comm_page->sample_rate = cpu_to_le32(44100); 984 chip->comm_page->sample_rate = cpu_to_le32(44100);
934 chip->sample_rate = 44100;
935 985
936 /* Set line levels so we don't blast any inputs on startup */ 986 /* Set line levels so we don't blast any inputs on startup */
937 memset(chip->comm_page->monitors, ECHOGAIN_MUTED, MONITOR_ARRAY_SIZE); 987 memset(chip->comm_page->monitors, ECHOGAIN_MUTED, MONITOR_ARRAY_SIZE);
@@ -942,50 +992,21 @@ static int init_dsp_comm_page(struct echoaudio *chip)
942 992
943 993
944 994
945/* This function initializes the several volume controls for busses and pipes. 995/* This function initializes the chip structure with default values, ie. all
946This MUST be called after the DSP is up and running ! */ 996 * muted and internal clock source. Then it copies the settings to the DSP.
997 * This MUST be called after the DSP is up and running !
998 */
947static int init_line_levels(struct echoaudio *chip) 999static int init_line_levels(struct echoaudio *chip)
948{ 1000{
949 int st, i, o;
950
951 DE_INIT(("init_line_levels\n")); 1001 DE_INIT(("init_line_levels\n"));
952 1002 memset(chip->output_gain, ECHOGAIN_MUTED, sizeof(chip->output_gain));
953 /* Mute output busses */ 1003 memset(chip->input_gain, ECHOGAIN_MUTED, sizeof(chip->input_gain));
954 for (i = 0; i < num_busses_out(chip); i++) 1004 memset(chip->monitor_gain, ECHOGAIN_MUTED, sizeof(chip->monitor_gain));
955 if ((st = set_output_gain(chip, i, ECHOGAIN_MUTED))) 1005 memset(chip->vmixer_gain, ECHOGAIN_MUTED, sizeof(chip->vmixer_gain));
956 return st; 1006 chip->input_clock = ECHO_CLOCK_INTERNAL;
957 if ((st = update_output_line_level(chip))) 1007 chip->output_clock = ECHO_CLOCK_WORD;
958 return st; 1008 chip->sample_rate = 44100;
959 1009 return restore_dsp_rettings(chip);
960#ifdef ECHOCARD_HAS_VMIXER
961 /* Mute the Vmixer */
962 for (i = 0; i < num_pipes_out(chip); i++)
963 for (o = 0; o < num_busses_out(chip); o++)
964 if ((st = set_vmixer_gain(chip, o, i, ECHOGAIN_MUTED)))
965 return st;
966 if ((st = update_vmixer_level(chip)))
967 return st;
968#endif /* ECHOCARD_HAS_VMIXER */
969
970#ifdef ECHOCARD_HAS_MONITOR
971 /* Mute the monitor mixer */
972 for (o = 0; o < num_busses_out(chip); o++)
973 for (i = 0; i < num_busses_in(chip); i++)
974 if ((st = set_monitor_gain(chip, o, i, ECHOGAIN_MUTED)))
975 return st;
976 if ((st = update_output_line_level(chip)))
977 return st;
978#endif /* ECHOCARD_HAS_MONITOR */
979
980#ifdef ECHOCARD_HAS_INPUT_GAIN
981 for (i = 0; i < num_busses_in(chip); i++)
982 if ((st = set_input_gain(chip, i, ECHOGAIN_MUTED)))
983 return st;
984 if ((st = update_input_line_level(chip)))
985 return st;
986#endif /* ECHOCARD_HAS_INPUT_GAIN */
987
988 return 0;
989} 1010}
990 1011
991 1012
diff --git a/sound/pci/echoaudio/gina20.c b/sound/pci/echoaudio/gina20.c
index c0e64b8f52a4..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>
@@ -67,7 +67,7 @@ static const struct firmware card_fw[] = {
67 {0, "gina20_dsp.fw"} 67 {0, "gina20_dsp.fw"}
68}; 68};
69 69
70static struct pci_device_id snd_echo_ids[] = { 70static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
71 {0x1057, 0x1801, 0xECC0, 0x0020, 0, 0, 0}, /* DSP 56301 Gina20 rev.0 */ 71 {0x1057, 0x1801, 0xECC0, 0x0020, 0, 0, 0}, /* DSP 56301 Gina20 rev.0 */
72 {0,} 72 {0,}
73}; 73};
diff --git a/sound/pci/echoaudio/gina20_dsp.c b/sound/pci/echoaudio/gina20_dsp.c
index 3f1e7475faea..d1615a0579d1 100644
--- a/sound/pci/echoaudio/gina20_dsp.c
+++ b/sound/pci/echoaudio/gina20_dsp.c
@@ -49,7 +49,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
49 chip->device_id = device_id; 49 chip->device_id = device_id;
50 chip->subdevice_id = subdevice_id; 50 chip->subdevice_id = subdevice_id;
51 chip->bad_board = TRUE; 51 chip->bad_board = TRUE;
52 chip->dsp_code_to_load = &card_fw[FW_GINA20_DSP]; 52 chip->dsp_code_to_load = FW_GINA20_DSP;
53 chip->spdif_status = GD_SPDIF_STATUS_UNDEF; 53 chip->spdif_status = GD_SPDIF_STATUS_UNDEF;
54 chip->clock_state = GD_CLOCK_UNDEF; 54 chip->clock_state = GD_CLOCK_UNDEF;
55 /* Since this card has no ASIC, mark it as loaded so everything 55 /* Since this card has no ASIC, mark it as loaded so everything
@@ -62,17 +62,20 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
62 return err; 62 return err;
63 chip->bad_board = FALSE; 63 chip->bad_board = FALSE;
64 64
65 if ((err = init_line_levels(chip)) < 0)
66 return err;
67
68 err = set_professional_spdif(chip, TRUE);
69
70 DE_INIT(("init_hw done\n")); 65 DE_INIT(("init_hw done\n"));
71 return err; 66 return err;
72} 67}
73 68
74 69
75 70
71static int set_mixer_defaults(struct echoaudio *chip)
72{
73 chip->professional_spdif = FALSE;
74 return init_line_levels(chip);
75}
76
77
78
76static u32 detect_input_clocks(const struct echoaudio *chip) 79static u32 detect_input_clocks(const struct echoaudio *chip)
77{ 80{
78 u32 clocks_from_dsp, clock_bits; 81 u32 clocks_from_dsp, clock_bits;
diff --git a/sound/pci/echoaudio/gina24.c b/sound/pci/echoaudio/gina24.c
index c36a78dd0b5e..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>
@@ -85,7 +85,7 @@ static const struct firmware card_fw[] = {
85 {0, "gina24_361_asic.fw"} 85 {0, "gina24_361_asic.fw"}
86}; 86};
87 87
88static struct pci_device_id snd_echo_ids[] = { 88static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
89 {0x1057, 0x1801, 0xECC0, 0x0050, 0, 0, 0}, /* DSP 56301 Gina24 rev.0 */ 89 {0x1057, 0x1801, 0xECC0, 0x0050, 0, 0, 0}, /* DSP 56301 Gina24 rev.0 */
90 {0x1057, 0x1801, 0xECC0, 0x0051, 0, 0, 0}, /* DSP 56301 Gina24 rev.1 */ 90 {0x1057, 0x1801, 0xECC0, 0x0051, 0, 0, 0}, /* DSP 56301 Gina24 rev.1 */
91 {0x1057, 0x3410, 0xECC0, 0x0050, 0, 0, 0}, /* DSP 56361 Gina24 rev.0 */ 91 {0x1057, 0x3410, 0xECC0, 0x0050, 0, 0, 0}, /* DSP 56361 Gina24 rev.0 */
diff --git a/sound/pci/echoaudio/gina24_dsp.c b/sound/pci/echoaudio/gina24_dsp.c
index 2fef37a2a5b9..98f7cfa81b5f 100644
--- a/sound/pci/echoaudio/gina24_dsp.c
+++ b/sound/pci/echoaudio/gina24_dsp.c
@@ -33,8 +33,7 @@ static int write_control_reg(struct echoaudio *chip, u32 value, char force);
33static int set_input_clock(struct echoaudio *chip, u16 clock); 33static int set_input_clock(struct echoaudio *chip, u16 clock);
34static int set_professional_spdif(struct echoaudio *chip, char prof); 34static int set_professional_spdif(struct echoaudio *chip, char prof);
35static int set_digital_mode(struct echoaudio *chip, u8 mode); 35static int set_digital_mode(struct echoaudio *chip, u8 mode);
36static int load_asic_generic(struct echoaudio *chip, u32 cmd, 36static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic);
37 const struct firmware *asic);
38static int check_asic_status(struct echoaudio *chip); 37static int check_asic_status(struct echoaudio *chip);
39 38
40 39
@@ -58,19 +57,16 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
58 ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF | 57 ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF |
59 ECHO_CLOCK_BIT_ESYNC | ECHO_CLOCK_BIT_ESYNC96 | 58 ECHO_CLOCK_BIT_ESYNC | ECHO_CLOCK_BIT_ESYNC96 |
60 ECHO_CLOCK_BIT_ADAT; 59 ECHO_CLOCK_BIT_ADAT;
61 chip->professional_spdif = FALSE;
62 chip->digital_in_automute = TRUE;
63 chip->digital_mode = DIGITAL_MODE_SPDIF_RCA;
64 60
65 /* Gina24 comes in both '301 and '361 flavors */ 61 /* Gina24 comes in both '301 and '361 flavors */
66 if (chip->device_id == DEVICE_ID_56361) { 62 if (chip->device_id == DEVICE_ID_56361) {
67 chip->dsp_code_to_load = &card_fw[FW_GINA24_361_DSP]; 63 chip->dsp_code_to_load = FW_GINA24_361_DSP;
68 chip->digital_modes = 64 chip->digital_modes =
69 ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA | 65 ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA |
70 ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL | 66 ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL |
71 ECHOCAPS_HAS_DIGITAL_MODE_ADAT; 67 ECHOCAPS_HAS_DIGITAL_MODE_ADAT;
72 } else { 68 } else {
73 chip->dsp_code_to_load = &card_fw[FW_GINA24_301_DSP]; 69 chip->dsp_code_to_load = FW_GINA24_301_DSP;
74 chip->digital_modes = 70 chip->digital_modes =
75 ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA | 71 ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA |
76 ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL | 72 ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL |
@@ -82,19 +78,22 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
82 return err; 78 return err;
83 chip->bad_board = FALSE; 79 chip->bad_board = FALSE;
84 80
85 if ((err = init_line_levels(chip)) < 0)
86 return err;
87 err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA);
88 if (err < 0)
89 return err;
90 err = set_professional_spdif(chip, TRUE);
91
92 DE_INIT(("init_hw done\n")); 81 DE_INIT(("init_hw done\n"));
93 return err; 82 return err;
94} 83}
95 84
96 85
97 86
87static int set_mixer_defaults(struct echoaudio *chip)
88{
89 chip->digital_mode = DIGITAL_MODE_SPDIF_RCA;
90 chip->professional_spdif = FALSE;
91 chip->digital_in_automute = TRUE;
92 return init_line_levels(chip);
93}
94
95
96
98static u32 detect_input_clocks(const struct echoaudio *chip) 97static u32 detect_input_clocks(const struct echoaudio *chip)
99{ 98{
100 u32 clocks_from_dsp, clock_bits; 99 u32 clocks_from_dsp, clock_bits;
@@ -125,7 +124,7 @@ static int load_asic(struct echoaudio *chip)
125{ 124{
126 u32 control_reg; 125 u32 control_reg;
127 int err; 126 int err;
128 const struct firmware *fw; 127 short asic;
129 128
130 if (chip->asic_loaded) 129 if (chip->asic_loaded)
131 return 1; 130 return 1;
@@ -135,14 +134,15 @@ static int load_asic(struct echoaudio *chip)
135 134
136 /* Pick the correct ASIC for '301 or '361 Gina24 */ 135 /* Pick the correct ASIC for '301 or '361 Gina24 */
137 if (chip->device_id == DEVICE_ID_56361) 136 if (chip->device_id == DEVICE_ID_56361)
138 fw = &card_fw[FW_GINA24_361_ASIC]; 137 asic = FW_GINA24_361_ASIC;
139 else 138 else
140 fw = &card_fw[FW_GINA24_301_ASIC]; 139 asic = FW_GINA24_301_ASIC;
141 140
142 if ((err = load_asic_generic(chip, DSP_FNC_LOAD_GINA24_ASIC, fw)) < 0) 141 err = load_asic_generic(chip, DSP_FNC_LOAD_GINA24_ASIC, asic);
142 if (err < 0)
143 return err; 143 return err;
144 144
145 chip->asic_code = fw; 145 chip->asic_code = asic;
146 146
147 /* Now give the new ASIC a little time to set up */ 147 /* Now give the new ASIC a little time to set up */
148 mdelay(10); 148 mdelay(10);
diff --git a/sound/pci/echoaudio/indigo.c b/sound/pci/echoaudio/indigo.c
index 0a58a7c1fd7c..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>
@@ -68,7 +68,7 @@ static const struct firmware card_fw[] = {
68 {0, "indigo_dsp.fw"} 68 {0, "indigo_dsp.fw"}
69}; 69};
70 70
71static struct pci_device_id snd_echo_ids[] = { 71static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
72 {0x1057, 0x3410, 0xECC0, 0x0090, 0, 0, 0}, /* Indigo */ 72 {0x1057, 0x3410, 0xECC0, 0x0090, 0, 0, 0}, /* Indigo */
73 {0,} 73 {0,}
74}; 74};
diff --git a/sound/pci/echoaudio/indigo_dsp.c b/sound/pci/echoaudio/indigo_dsp.c
index 0b2cd9c86277..5e85f14fe5a8 100644
--- a/sound/pci/echoaudio/indigo_dsp.c
+++ b/sound/pci/echoaudio/indigo_dsp.c
@@ -50,7 +50,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
50 chip->device_id = device_id; 50 chip->device_id = device_id;
51 chip->subdevice_id = subdevice_id; 51 chip->subdevice_id = subdevice_id;
52 chip->bad_board = TRUE; 52 chip->bad_board = TRUE;
53 chip->dsp_code_to_load = &card_fw[FW_INDIGO_DSP]; 53 chip->dsp_code_to_load = FW_INDIGO_DSP;
54 /* Since this card has no ASIC, mark it as loaded so everything 54 /* Since this card has no ASIC, mark it as loaded so everything
55 works OK */ 55 works OK */
56 chip->asic_loaded = TRUE; 56 chip->asic_loaded = TRUE;
@@ -60,15 +60,19 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
60 return err; 60 return err;
61 chip->bad_board = FALSE; 61 chip->bad_board = FALSE;
62 62
63 if ((err = init_line_levels(chip)) < 0)
64 return err;
65
66 DE_INIT(("init_hw done\n")); 63 DE_INIT(("init_hw done\n"));
67 return err; 64 return err;
68} 65}
69 66
70 67
71 68
69static int set_mixer_defaults(struct echoaudio *chip)
70{
71 return init_line_levels(chip);
72}
73
74
75
72static u32 detect_input_clocks(const struct echoaudio *chip) 76static u32 detect_input_clocks(const struct echoaudio *chip)
73{ 77{
74 return ECHO_CLOCK_BIT_INTERNAL; 78 return ECHO_CLOCK_BIT_INTERNAL;
diff --git a/sound/pci/echoaudio/indigo_express_dsp.c b/sound/pci/echoaudio/indigo_express_dsp.c
index 9ab625e15652..2e4ab3e34a74 100644
--- a/sound/pci/echoaudio/indigo_express_dsp.c
+++ b/sound/pci/echoaudio/indigo_express_dsp.c
@@ -61,6 +61,7 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate)
61 61
62 control_reg |= clock; 62 control_reg |= clock;
63 if (control_reg != old_control_reg) { 63 if (control_reg != old_control_reg) {
64 DE_ACT(("set_sample_rate: %d clock %d\n", rate, clock));
64 chip->comm_page->control_register = cpu_to_le32(control_reg); 65 chip->comm_page->control_register = cpu_to_le32(control_reg);
65 chip->sample_rate = rate; 66 chip->sample_rate = rate;
66 clear_handshake(chip); 67 clear_handshake(chip);
diff --git a/sound/pci/echoaudio/indigodj.c b/sound/pci/echoaudio/indigodj.c
index 2db24d29332b..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>
@@ -68,7 +68,7 @@ static const struct firmware card_fw[] = {
68 {0, "indigo_dj_dsp.fw"} 68 {0, "indigo_dj_dsp.fw"}
69}; 69};
70 70
71static struct pci_device_id snd_echo_ids[] = { 71static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
72 {0x1057, 0x3410, 0xECC0, 0x00B0, 0, 0, 0}, /* Indigo DJ*/ 72 {0x1057, 0x3410, 0xECC0, 0x00B0, 0, 0, 0}, /* Indigo DJ*/
73 {0,} 73 {0,}
74}; 74};
diff --git a/sound/pci/echoaudio/indigodj_dsp.c b/sound/pci/echoaudio/indigodj_dsp.c
index 08392916691e..68f3c8ccc1bf 100644
--- a/sound/pci/echoaudio/indigodj_dsp.c
+++ b/sound/pci/echoaudio/indigodj_dsp.c
@@ -50,7 +50,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
50 chip->device_id = device_id; 50 chip->device_id = device_id;
51 chip->subdevice_id = subdevice_id; 51 chip->subdevice_id = subdevice_id;
52 chip->bad_board = TRUE; 52 chip->bad_board = TRUE;
53 chip->dsp_code_to_load = &card_fw[FW_INDIGO_DJ_DSP]; 53 chip->dsp_code_to_load = FW_INDIGO_DJ_DSP;
54 /* Since this card has no ASIC, mark it as loaded so everything 54 /* Since this card has no ASIC, mark it as loaded so everything
55 works OK */ 55 works OK */
56 chip->asic_loaded = TRUE; 56 chip->asic_loaded = TRUE;
@@ -60,15 +60,19 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
60 return err; 60 return err;
61 chip->bad_board = FALSE; 61 chip->bad_board = FALSE;
62 62
63 if ((err = init_line_levels(chip)) < 0)
64 return err;
65
66 DE_INIT(("init_hw done\n")); 63 DE_INIT(("init_hw done\n"));
67 return err; 64 return err;
68} 65}
69 66
70 67
71 68
69static int set_mixer_defaults(struct echoaudio *chip)
70{
71 return init_line_levels(chip);
72}
73
74
75
72static u32 detect_input_clocks(const struct echoaudio *chip) 76static u32 detect_input_clocks(const struct echoaudio *chip)
73{ 77{
74 return ECHO_CLOCK_BIT_INTERNAL; 78 return ECHO_CLOCK_BIT_INTERNAL;
diff --git a/sound/pci/echoaudio/indigodjx.c b/sound/pci/echoaudio/indigodjx.c
index 2e44316530a2..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>
@@ -68,7 +68,7 @@ static const struct firmware card_fw[] = {
68 {0, "indigo_djx_dsp.fw"} 68 {0, "indigo_djx_dsp.fw"}
69}; 69};
70 70
71static struct pci_device_id snd_echo_ids[] = { 71static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
72 {0x1057, 0x3410, 0xECC0, 0x00E0, 0, 0, 0}, /* Indigo DJx*/ 72 {0x1057, 0x3410, 0xECC0, 0x00E0, 0, 0, 0}, /* Indigo DJx*/
73 {0,} 73 {0,}
74}; 74};
diff --git a/sound/pci/echoaudio/indigodjx_dsp.c b/sound/pci/echoaudio/indigodjx_dsp.c
index f591fc2ed960..bb9632c752a9 100644
--- a/sound/pci/echoaudio/indigodjx_dsp.c
+++ b/sound/pci/echoaudio/indigodjx_dsp.c
@@ -48,7 +48,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
48 chip->device_id = device_id; 48 chip->device_id = device_id;
49 chip->subdevice_id = subdevice_id; 49 chip->subdevice_id = subdevice_id;
50 chip->bad_board = TRUE; 50 chip->bad_board = TRUE;
51 chip->dsp_code_to_load = &card_fw[FW_INDIGO_DJX_DSP]; 51 chip->dsp_code_to_load = FW_INDIGO_DJX_DSP;
52 /* Since this card has no ASIC, mark it as loaded so everything 52 /* Since this card has no ASIC, mark it as loaded so everything
53 works OK */ 53 works OK */
54 chip->asic_loaded = TRUE; 54 chip->asic_loaded = TRUE;
@@ -59,10 +59,13 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
59 return err; 59 return err;
60 chip->bad_board = FALSE; 60 chip->bad_board = FALSE;
61 61
62 err = init_line_levels(chip);
63 if (err < 0)
64 return err;
65
66 DE_INIT(("init_hw done\n")); 62 DE_INIT(("init_hw done\n"));
67 return err; 63 return err;
68} 64}
65
66
67
68static int set_mixer_defaults(struct echoaudio *chip)
69{
70 return init_line_levels(chip);
71}
diff --git a/sound/pci/echoaudio/indigoio.c b/sound/pci/echoaudio/indigoio.c
index a60c0a0a89b7..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>
@@ -69,7 +69,7 @@ static const struct firmware card_fw[] = {
69 {0, "indigo_io_dsp.fw"} 69 {0, "indigo_io_dsp.fw"}
70}; 70};
71 71
72static struct pci_device_id snd_echo_ids[] = { 72static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
73 {0x1057, 0x3410, 0xECC0, 0x00A0, 0, 0, 0}, /* Indigo IO*/ 73 {0x1057, 0x3410, 0xECC0, 0x00A0, 0, 0, 0}, /* Indigo IO*/
74 {0,} 74 {0,}
75}; 75};
diff --git a/sound/pci/echoaudio/indigoio_dsp.c b/sound/pci/echoaudio/indigoio_dsp.c
index 0604c8a85223..beb9a5b69892 100644
--- a/sound/pci/echoaudio/indigoio_dsp.c
+++ b/sound/pci/echoaudio/indigoio_dsp.c
@@ -50,7 +50,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
50 chip->device_id = device_id; 50 chip->device_id = device_id;
51 chip->subdevice_id = subdevice_id; 51 chip->subdevice_id = subdevice_id;
52 chip->bad_board = TRUE; 52 chip->bad_board = TRUE;
53 chip->dsp_code_to_load = &card_fw[FW_INDIGO_IO_DSP]; 53 chip->dsp_code_to_load = FW_INDIGO_IO_DSP;
54 /* Since this card has no ASIC, mark it as loaded so everything 54 /* Since this card has no ASIC, mark it as loaded so everything
55 works OK */ 55 works OK */
56 chip->asic_loaded = TRUE; 56 chip->asic_loaded = TRUE;
@@ -60,15 +60,19 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
60 return err; 60 return err;
61 chip->bad_board = FALSE; 61 chip->bad_board = FALSE;
62 62
63 if ((err = init_line_levels(chip)) < 0)
64 return err;
65
66 DE_INIT(("init_hw done\n")); 63 DE_INIT(("init_hw done\n"));
67 return err; 64 return err;
68} 65}
69 66
70 67
71 68
69static int set_mixer_defaults(struct echoaudio *chip)
70{
71 return init_line_levels(chip);
72}
73
74
75
72static u32 detect_input_clocks(const struct echoaudio *chip) 76static u32 detect_input_clocks(const struct echoaudio *chip)
73{ 77{
74 return ECHO_CLOCK_BIT_INTERNAL; 78 return ECHO_CLOCK_BIT_INTERNAL;
diff --git a/sound/pci/echoaudio/indigoiox.c b/sound/pci/echoaudio/indigoiox.c
index eb3819f9654a..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>
@@ -69,7 +69,7 @@ static const struct firmware card_fw[] = {
69 {0, "indigo_iox_dsp.fw"} 69 {0, "indigo_iox_dsp.fw"}
70}; 70};
71 71
72static struct pci_device_id snd_echo_ids[] = { 72static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
73 {0x1057, 0x3410, 0xECC0, 0x00D0, 0, 0, 0}, /* Indigo IOx */ 73 {0x1057, 0x3410, 0xECC0, 0x00D0, 0, 0, 0}, /* Indigo IOx */
74 {0,} 74 {0,}
75}; 75};
diff --git a/sound/pci/echoaudio/indigoiox_dsp.c b/sound/pci/echoaudio/indigoiox_dsp.c
index f357521c79e6..394c6e76bcbc 100644
--- a/sound/pci/echoaudio/indigoiox_dsp.c
+++ b/sound/pci/echoaudio/indigoiox_dsp.c
@@ -48,7 +48,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
48 chip->device_id = device_id; 48 chip->device_id = device_id;
49 chip->subdevice_id = subdevice_id; 49 chip->subdevice_id = subdevice_id;
50 chip->bad_board = TRUE; 50 chip->bad_board = TRUE;
51 chip->dsp_code_to_load = &card_fw[FW_INDIGO_IOX_DSP]; 51 chip->dsp_code_to_load = FW_INDIGO_IOX_DSP;
52 /* Since this card has no ASIC, mark it as loaded so everything 52 /* Since this card has no ASIC, mark it as loaded so everything
53 works OK */ 53 works OK */
54 chip->asic_loaded = TRUE; 54 chip->asic_loaded = TRUE;
@@ -59,10 +59,13 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
59 return err; 59 return err;
60 chip->bad_board = FALSE; 60 chip->bad_board = FALSE;
61 61
62 err = init_line_levels(chip);
63 if (err < 0)
64 return err;
65
66 DE_INIT(("init_hw done\n")); 62 DE_INIT(("init_hw done\n"));
67 return err; 63 return err;
68} 64}
65
66
67
68static int set_mixer_defaults(struct echoaudio *chip)
69{
70 return init_line_levels(chip);
71}
diff --git a/sound/pci/echoaudio/layla20.c b/sound/pci/echoaudio/layla20.c
index 506194688995..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>
@@ -76,7 +76,7 @@ static const struct firmware card_fw[] = {
76 {0, "layla20_asic.fw"} 76 {0, "layla20_asic.fw"}
77}; 77};
78 78
79static struct pci_device_id snd_echo_ids[] = { 79static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
80 {0x1057, 0x1801, 0xECC0, 0x0030, 0, 0, 0}, /* DSP 56301 Layla20 rev.0 */ 80 {0x1057, 0x1801, 0xECC0, 0x0030, 0, 0, 0}, /* DSP 56301 Layla20 rev.0 */
81 {0x1057, 0x1801, 0xECC0, 0x0031, 0, 0, 0}, /* DSP 56301 Layla20 rev.1 */ 81 {0x1057, 0x1801, 0xECC0, 0x0031, 0, 0, 0}, /* DSP 56301 Layla20 rev.1 */
82 {0,} 82 {0,}
diff --git a/sound/pci/echoaudio/layla20_dsp.c b/sound/pci/echoaudio/layla20_dsp.c
index 83750e9fd7b4..53ce94605044 100644
--- a/sound/pci/echoaudio/layla20_dsp.c
+++ b/sound/pci/echoaudio/layla20_dsp.c
@@ -31,8 +31,7 @@
31 31
32static int read_dsp(struct echoaudio *chip, u32 *data); 32static int read_dsp(struct echoaudio *chip, u32 *data);
33static int set_professional_spdif(struct echoaudio *chip, char prof); 33static int set_professional_spdif(struct echoaudio *chip, char prof);
34static int load_asic_generic(struct echoaudio *chip, u32 cmd, 34static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic);
35 const struct firmware *asic);
36static int check_asic_status(struct echoaudio *chip); 35static int check_asic_status(struct echoaudio *chip);
37static int update_flags(struct echoaudio *chip); 36static int update_flags(struct echoaudio *chip);
38 37
@@ -54,7 +53,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
54 chip->subdevice_id = subdevice_id; 53 chip->subdevice_id = subdevice_id;
55 chip->bad_board = TRUE; 54 chip->bad_board = TRUE;
56 chip->has_midi = TRUE; 55 chip->has_midi = TRUE;
57 chip->dsp_code_to_load = &card_fw[FW_LAYLA20_DSP]; 56 chip->dsp_code_to_load = FW_LAYLA20_DSP;
58 chip->input_clock_types = 57 chip->input_clock_types =
59 ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF | 58 ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF |
60 ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_SUPER; 59 ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_SUPER;
@@ -65,17 +64,20 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
65 return err; 64 return err;
66 chip->bad_board = FALSE; 65 chip->bad_board = FALSE;
67 66
68 if ((err = init_line_levels(chip)) < 0)
69 return err;
70
71 err = set_professional_spdif(chip, TRUE);
72
73 DE_INIT(("init_hw done\n")); 67 DE_INIT(("init_hw done\n"));
74 return err; 68 return err;
75} 69}
76 70
77 71
78 72
73static int set_mixer_defaults(struct echoaudio *chip)
74{
75 chip->professional_spdif = FALSE;
76 return init_line_levels(chip);
77}
78
79
80
79static u32 detect_input_clocks(const struct echoaudio *chip) 81static u32 detect_input_clocks(const struct echoaudio *chip)
80{ 82{
81 u32 clocks_from_dsp, clock_bits; 83 u32 clocks_from_dsp, clock_bits;
@@ -144,7 +146,7 @@ static int load_asic(struct echoaudio *chip)
144 return 0; 146 return 0;
145 147
146 err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA_ASIC, 148 err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA_ASIC,
147 &card_fw[FW_LAYLA20_ASIC]); 149 FW_LAYLA20_ASIC);
148 if (err < 0) 150 if (err < 0)
149 return err; 151 return err;
150 152
diff --git a/sound/pci/echoaudio/layla24.c b/sound/pci/echoaudio/layla24.c
index e09e3ea7781e..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>
@@ -87,7 +87,7 @@ static const struct firmware card_fw[] = {
87 {0, "layla24_2S_asic.fw"} 87 {0, "layla24_2S_asic.fw"}
88}; 88};
89 89
90static struct pci_device_id snd_echo_ids[] = { 90static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
91 {0x1057, 0x3410, 0xECC0, 0x0060, 0, 0, 0}, /* DSP 56361 Layla24 rev.0 */ 91 {0x1057, 0x3410, 0xECC0, 0x0060, 0, 0, 0}, /* DSP 56361 Layla24 rev.0 */
92 {0,} 92 {0,}
93}; 93};
diff --git a/sound/pci/echoaudio/layla24_dsp.c b/sound/pci/echoaudio/layla24_dsp.c
index d61b5cbcccad..8c041647f285 100644
--- a/sound/pci/echoaudio/layla24_dsp.c
+++ b/sound/pci/echoaudio/layla24_dsp.c
@@ -32,8 +32,7 @@ static int write_control_reg(struct echoaudio *chip, u32 value, char force);
32static int set_input_clock(struct echoaudio *chip, u16 clock); 32static int set_input_clock(struct echoaudio *chip, u16 clock);
33static int set_professional_spdif(struct echoaudio *chip, char prof); 33static int set_professional_spdif(struct echoaudio *chip, char prof);
34static int set_digital_mode(struct echoaudio *chip, u8 mode); 34static int set_digital_mode(struct echoaudio *chip, u8 mode);
35static int load_asic_generic(struct echoaudio *chip, u32 cmd, 35static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic);
36 const struct firmware *asic);
37static int check_asic_status(struct echoaudio *chip); 36static int check_asic_status(struct echoaudio *chip);
38 37
39 38
@@ -54,7 +53,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
54 chip->subdevice_id = subdevice_id; 53 chip->subdevice_id = subdevice_id;
55 chip->bad_board = TRUE; 54 chip->bad_board = TRUE;
56 chip->has_midi = TRUE; 55 chip->has_midi = TRUE;
57 chip->dsp_code_to_load = &card_fw[FW_LAYLA24_DSP]; 56 chip->dsp_code_to_load = FW_LAYLA24_DSP;
58 chip->input_clock_types = 57 chip->input_clock_types =
59 ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF | 58 ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF |
60 ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_ADAT; 59 ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_ADAT;
@@ -62,9 +61,6 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
62 ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA | 61 ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA |
63 ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL | 62 ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL |
64 ECHOCAPS_HAS_DIGITAL_MODE_ADAT; 63 ECHOCAPS_HAS_DIGITAL_MODE_ADAT;
65 chip->digital_mode = DIGITAL_MODE_SPDIF_RCA;
66 chip->professional_spdif = FALSE;
67 chip->digital_in_automute = TRUE;
68 64
69 if ((err = load_firmware(chip)) < 0) 65 if ((err = load_firmware(chip)) < 0)
70 return err; 66 return err;
@@ -73,17 +69,22 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
73 if ((err = init_line_levels(chip)) < 0) 69 if ((err = init_line_levels(chip)) < 0)
74 return err; 70 return err;
75 71
76 err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA);
77 if (err < 0)
78 return err;
79 err = set_professional_spdif(chip, TRUE);
80
81 DE_INIT(("init_hw done\n")); 72 DE_INIT(("init_hw done\n"));
82 return err; 73 return err;
83} 74}
84 75
85 76
86 77
78static int set_mixer_defaults(struct echoaudio *chip)
79{
80 chip->digital_mode = DIGITAL_MODE_SPDIF_RCA;
81 chip->professional_spdif = FALSE;
82 chip->digital_in_automute = TRUE;
83 return init_line_levels(chip);
84}
85
86
87
87static u32 detect_input_clocks(const struct echoaudio *chip) 88static u32 detect_input_clocks(const struct echoaudio *chip)
88{ 89{
89 u32 clocks_from_dsp, clock_bits; 90 u32 clocks_from_dsp, clock_bits;
@@ -123,18 +124,18 @@ static int load_asic(struct echoaudio *chip)
123 124
124 /* Load the ASIC for the PCI card */ 125 /* Load the ASIC for the PCI card */
125 err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA24_PCI_CARD_ASIC, 126 err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA24_PCI_CARD_ASIC,
126 &card_fw[FW_LAYLA24_1_ASIC]); 127 FW_LAYLA24_1_ASIC);
127 if (err < 0) 128 if (err < 0)
128 return err; 129 return err;
129 130
130 chip->asic_code = &card_fw[FW_LAYLA24_2S_ASIC]; 131 chip->asic_code = FW_LAYLA24_2S_ASIC;
131 132
132 /* Now give the new ASIC a little time to set up */ 133 /* Now give the new ASIC a little time to set up */
133 mdelay(10); 134 mdelay(10);
134 135
135 /* Do the external one */ 136 /* Do the external one */
136 err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA24_EXTERNAL_ASIC, 137 err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA24_EXTERNAL_ASIC,
137 &card_fw[FW_LAYLA24_2S_ASIC]); 138 FW_LAYLA24_2S_ASIC);
138 if (err < 0) 139 if (err < 0)
139 return FALSE; 140 return FALSE;
140 141
@@ -299,7 +300,7 @@ static int set_input_clock(struct echoaudio *chip, u16 clock)
299/* Depending on what digital mode you want, Layla24 needs different ASICs 300/* Depending on what digital mode you want, Layla24 needs different ASICs
300loaded. This function checks the ASIC needed for the new mode and sees 301loaded. This function checks the ASIC needed for the new mode and sees
301if it matches the one already loaded. */ 302if it matches the one already loaded. */
302static int switch_asic(struct echoaudio *chip, const struct firmware *asic) 303static int switch_asic(struct echoaudio *chip, short asic)
303{ 304{
304 s8 *monitors; 305 s8 *monitors;
305 306
@@ -335,7 +336,7 @@ static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode)
335{ 336{
336 u32 control_reg; 337 u32 control_reg;
337 int err, incompatible_clock; 338 int err, incompatible_clock;
338 const struct firmware *asic; 339 short asic;
339 340
340 /* Set clock to "internal" if it's not compatible with the new mode */ 341 /* Set clock to "internal" if it's not compatible with the new mode */
341 incompatible_clock = FALSE; 342 incompatible_clock = FALSE;
@@ -344,12 +345,12 @@ static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode)
344 case DIGITAL_MODE_SPDIF_RCA: 345 case DIGITAL_MODE_SPDIF_RCA:
345 if (chip->input_clock == ECHO_CLOCK_ADAT) 346 if (chip->input_clock == ECHO_CLOCK_ADAT)
346 incompatible_clock = TRUE; 347 incompatible_clock = TRUE;
347 asic = &card_fw[FW_LAYLA24_2S_ASIC]; 348 asic = FW_LAYLA24_2S_ASIC;
348 break; 349 break;
349 case DIGITAL_MODE_ADAT: 350 case DIGITAL_MODE_ADAT:
350 if (chip->input_clock == ECHO_CLOCK_SPDIF) 351 if (chip->input_clock == ECHO_CLOCK_SPDIF)
351 incompatible_clock = TRUE; 352 incompatible_clock = TRUE;
352 asic = &card_fw[FW_LAYLA24_2A_ASIC]; 353 asic = FW_LAYLA24_2A_ASIC;
353 break; 354 break;
354 default: 355 default:
355 DE_ACT(("Digital mode not supported: %d\n", mode)); 356 DE_ACT(("Digital mode not supported: %d\n", mode));
diff --git a/sound/pci/echoaudio/mia.c b/sound/pci/echoaudio/mia.c
index f05c8c097aa8..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>
@@ -77,7 +77,7 @@ static const struct firmware card_fw[] = {
77 {0, "mia_dsp.fw"} 77 {0, "mia_dsp.fw"}
78}; 78};
79 79
80static struct pci_device_id snd_echo_ids[] = { 80static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
81 {0x1057, 0x3410, 0xECC0, 0x0080, 0, 0, 0}, /* DSP 56361 Mia rev.0 */ 81 {0x1057, 0x3410, 0xECC0, 0x0080, 0, 0, 0}, /* DSP 56361 Mia rev.0 */
82 {0x1057, 0x3410, 0xECC0, 0x0081, 0, 0, 0}, /* DSP 56361 Mia rev.1 */ 82 {0x1057, 0x3410, 0xECC0, 0x0081, 0, 0, 0}, /* DSP 56361 Mia rev.1 */
83 {0,} 83 {0,}
diff --git a/sound/pci/echoaudio/mia_dsp.c b/sound/pci/echoaudio/mia_dsp.c
index 551405114cbc..6ebfa6e7ab9e 100644
--- a/sound/pci/echoaudio/mia_dsp.c
+++ b/sound/pci/echoaudio/mia_dsp.c
@@ -53,7 +53,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
53 chip->device_id = device_id; 53 chip->device_id = device_id;
54 chip->subdevice_id = subdevice_id; 54 chip->subdevice_id = subdevice_id;
55 chip->bad_board = TRUE; 55 chip->bad_board = TRUE;
56 chip->dsp_code_to_load = &card_fw[FW_MIA_DSP]; 56 chip->dsp_code_to_load = FW_MIA_DSP;
57 /* Since this card has no ASIC, mark it as loaded so everything 57 /* Since this card has no ASIC, mark it as loaded so everything
58 works OK */ 58 works OK */
59 chip->asic_loaded = TRUE; 59 chip->asic_loaded = TRUE;
@@ -66,15 +66,19 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
66 return err; 66 return err;
67 chip->bad_board = FALSE; 67 chip->bad_board = FALSE;
68 68
69 if ((err = init_line_levels(chip)))
70 return err;
71
72 DE_INIT(("init_hw done\n")); 69 DE_INIT(("init_hw done\n"));
73 return err; 70 return err;
74} 71}
75 72
76 73
77 74
75static int set_mixer_defaults(struct echoaudio *chip)
76{
77 return init_line_levels(chip);
78}
79
80
81
78static u32 detect_input_clocks(const struct echoaudio *chip) 82static u32 detect_input_clocks(const struct echoaudio *chip)
79{ 83{
80 u32 clocks_from_dsp, clock_bits; 84 u32 clocks_from_dsp, clock_bits;
diff --git a/sound/pci/echoaudio/mona.c b/sound/pci/echoaudio/mona.c
index b05bad944901..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>
@@ -92,7 +92,7 @@ static const struct firmware card_fw[] = {
92 {0, "mona_2_asic.fw"} 92 {0, "mona_2_asic.fw"}
93}; 93};
94 94
95static struct pci_device_id snd_echo_ids[] = { 95static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
96 {0x1057, 0x1801, 0xECC0, 0x0070, 0, 0, 0}, /* DSP 56301 Mona rev.0 */ 96 {0x1057, 0x1801, 0xECC0, 0x0070, 0, 0, 0}, /* DSP 56301 Mona rev.0 */
97 {0x1057, 0x1801, 0xECC0, 0x0071, 0, 0, 0}, /* DSP 56301 Mona rev.1 */ 97 {0x1057, 0x1801, 0xECC0, 0x0071, 0, 0, 0}, /* DSP 56301 Mona rev.1 */
98 {0x1057, 0x1801, 0xECC0, 0x0072, 0, 0, 0}, /* DSP 56301 Mona rev.2 */ 98 {0x1057, 0x1801, 0xECC0, 0x0072, 0, 0, 0}, /* DSP 56301 Mona rev.2 */
diff --git a/sound/pci/echoaudio/mona_dsp.c b/sound/pci/echoaudio/mona_dsp.c
index eaa619bd2a03..6e6a7eb555b8 100644
--- a/sound/pci/echoaudio/mona_dsp.c
+++ b/sound/pci/echoaudio/mona_dsp.c
@@ -33,8 +33,7 @@ static int write_control_reg(struct echoaudio *chip, u32 value, char force);
33static int set_input_clock(struct echoaudio *chip, u16 clock); 33static int set_input_clock(struct echoaudio *chip, u16 clock);
34static int set_professional_spdif(struct echoaudio *chip, char prof); 34static int set_professional_spdif(struct echoaudio *chip, char prof);
35static int set_digital_mode(struct echoaudio *chip, u8 mode); 35static int set_digital_mode(struct echoaudio *chip, u8 mode);
36static int load_asic_generic(struct echoaudio *chip, u32 cmd, 36static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic);
37 const struct firmware *asic);
38static int check_asic_status(struct echoaudio *chip); 37static int check_asic_status(struct echoaudio *chip);
39 38
40 39
@@ -64,32 +63,30 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
64 63
65 /* Mona comes in both '301 and '361 flavors */ 64 /* Mona comes in both '301 and '361 flavors */
66 if (chip->device_id == DEVICE_ID_56361) 65 if (chip->device_id == DEVICE_ID_56361)
67 chip->dsp_code_to_load = &card_fw[FW_MONA_361_DSP]; 66 chip->dsp_code_to_load = FW_MONA_361_DSP;
68 else 67 else
69 chip->dsp_code_to_load = &card_fw[FW_MONA_301_DSP]; 68 chip->dsp_code_to_load = FW_MONA_301_DSP;
70
71 chip->digital_mode = DIGITAL_MODE_SPDIF_RCA;
72 chip->professional_spdif = FALSE;
73 chip->digital_in_automute = TRUE;
74 69
75 if ((err = load_firmware(chip)) < 0) 70 if ((err = load_firmware(chip)) < 0)
76 return err; 71 return err;
77 chip->bad_board = FALSE; 72 chip->bad_board = FALSE;
78 73
79 if ((err = init_line_levels(chip)) < 0)
80 return err;
81
82 err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA);
83 if (err < 0)
84 return err;
85 err = set_professional_spdif(chip, TRUE);
86
87 DE_INIT(("init_hw done\n")); 74 DE_INIT(("init_hw done\n"));
88 return err; 75 return err;
89} 76}
90 77
91 78
92 79
80static int set_mixer_defaults(struct echoaudio *chip)
81{
82 chip->digital_mode = DIGITAL_MODE_SPDIF_RCA;
83 chip->professional_spdif = FALSE;
84 chip->digital_in_automute = TRUE;
85 return init_line_levels(chip);
86}
87
88
89
93static u32 detect_input_clocks(const struct echoaudio *chip) 90static u32 detect_input_clocks(const struct echoaudio *chip)
94{ 91{
95 u32 clocks_from_dsp, clock_bits; 92 u32 clocks_from_dsp, clock_bits;
@@ -120,7 +117,7 @@ static int load_asic(struct echoaudio *chip)
120{ 117{
121 u32 control_reg; 118 u32 control_reg;
122 int err; 119 int err;
123 const struct firmware *asic; 120 short asic;
124 121
125 if (chip->asic_loaded) 122 if (chip->asic_loaded)
126 return 0; 123 return 0;
@@ -128,9 +125,9 @@ static int load_asic(struct echoaudio *chip)
128 mdelay(10); 125 mdelay(10);
129 126
130 if (chip->device_id == DEVICE_ID_56361) 127 if (chip->device_id == DEVICE_ID_56361)
131 asic = &card_fw[FW_MONA_361_1_ASIC48]; 128 asic = FW_MONA_361_1_ASIC48;
132 else 129 else
133 asic = &card_fw[FW_MONA_301_1_ASIC48]; 130 asic = FW_MONA_301_1_ASIC48;
134 131
135 err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_PCI_CARD_ASIC, asic); 132 err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_PCI_CARD_ASIC, asic);
136 if (err < 0) 133 if (err < 0)
@@ -141,7 +138,7 @@ static int load_asic(struct echoaudio *chip)
141 138
142 /* Do the external one */ 139 /* Do the external one */
143 err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_EXTERNAL_ASIC, 140 err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_EXTERNAL_ASIC,
144 &card_fw[FW_MONA_2_ASIC]); 141 FW_MONA_2_ASIC);
145 if (err < 0) 142 if (err < 0)
146 return err; 143 return err;
147 144
@@ -165,22 +162,22 @@ loaded. This function checks the ASIC needed for the new mode and sees
165if it matches the one already loaded. */ 162if it matches the one already loaded. */
166static int switch_asic(struct echoaudio *chip, char double_speed) 163static int switch_asic(struct echoaudio *chip, char double_speed)
167{ 164{
168 const struct firmware *asic;
169 int err; 165 int err;
166 short asic;
170 167
171 /* Check the clock detect bits to see if this is 168 /* Check the clock detect bits to see if this is
172 a single-speed clock or a double-speed clock; load 169 a single-speed clock or a double-speed clock; load
173 a new ASIC if necessary. */ 170 a new ASIC if necessary. */
174 if (chip->device_id == DEVICE_ID_56361) { 171 if (chip->device_id == DEVICE_ID_56361) {
175 if (double_speed) 172 if (double_speed)
176 asic = &card_fw[FW_MONA_361_1_ASIC96]; 173 asic = FW_MONA_361_1_ASIC96;
177 else 174 else
178 asic = &card_fw[FW_MONA_361_1_ASIC48]; 175 asic = FW_MONA_361_1_ASIC48;
179 } else { 176 } else {
180 if (double_speed) 177 if (double_speed)
181 asic = &card_fw[FW_MONA_301_1_ASIC96]; 178 asic = FW_MONA_301_1_ASIC96;
182 else 179 else
183 asic = &card_fw[FW_MONA_301_1_ASIC48]; 180 asic = FW_MONA_301_1_ASIC48;
184 } 181 }
185 182
186 if (asic != chip->asic_code) { 183 if (asic != chip->asic_code) {
@@ -200,7 +197,7 @@ static int switch_asic(struct echoaudio *chip, char double_speed)
200static int set_sample_rate(struct echoaudio *chip, u32 rate) 197static int set_sample_rate(struct echoaudio *chip, u32 rate)
201{ 198{
202 u32 control_reg, clock; 199 u32 control_reg, clock;
203 const struct firmware *asic; 200 short asic;
204 char force_write; 201 char force_write;
205 202
206 /* Only set the clock for internal mode. */ 203 /* Only set the clock for internal mode. */
@@ -218,14 +215,14 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate)
218 if (chip->digital_mode == DIGITAL_MODE_ADAT) 215 if (chip->digital_mode == DIGITAL_MODE_ADAT)
219 return -EINVAL; 216 return -EINVAL;
220 if (chip->device_id == DEVICE_ID_56361) 217 if (chip->device_id == DEVICE_ID_56361)
221 asic = &card_fw[FW_MONA_361_1_ASIC96]; 218 asic = FW_MONA_361_1_ASIC96;
222 else 219 else
223 asic = &card_fw[FW_MONA_301_1_ASIC96]; 220 asic = FW_MONA_301_1_ASIC96;
224 } else { 221 } else {
225 if (chip->device_id == DEVICE_ID_56361) 222 if (chip->device_id == DEVICE_ID_56361)
226 asic = &card_fw[FW_MONA_361_1_ASIC48]; 223 asic = FW_MONA_361_1_ASIC48;
227 else 224 else
228 asic = &card_fw[FW_MONA_301_1_ASIC48]; 225 asic = FW_MONA_301_1_ASIC48;
229 } 226 }
230 227
231 force_write = 0; 228 force_write = 0;
@@ -410,8 +407,8 @@ static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode)
410 case DIGITAL_MODE_ADAT: 407 case DIGITAL_MODE_ADAT:
411 /* If the current ASIC is the 96KHz ASIC, switch the ASIC 408 /* If the current ASIC is the 96KHz ASIC, switch the ASIC
412 and set to 48 KHz */ 409 and set to 48 KHz */
413 if (chip->asic_code == &card_fw[FW_MONA_361_1_ASIC96] || 410 if (chip->asic_code == FW_MONA_361_1_ASIC96 ||
414 chip->asic_code == &card_fw[FW_MONA_301_1_ASIC96]) { 411 chip->asic_code == FW_MONA_301_1_ASIC96) {
415 set_sample_rate(chip, 48000); 412 set_sample_rate(chip, 48000);
416 } 413 }
417 control_reg |= GML_ADAT_MODE; 414 control_reg |= GML_ADAT_MODE;
diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c
index 168af67d938e..4203782d7cb7 100644
--- a/sound/pci/emu10k1/emu10k1.c
+++ b/sound/pci/emu10k1/emu10k1.c
@@ -76,7 +76,7 @@ MODULE_PARM_DESC(subsystem, "Force card subsystem model.");
76/* 76/*
77 * Class 0401: 1102:0008 (rev 00) Subsystem: 1102:1001 -> Audigy2 Value Model:SB0400 77 * Class 0401: 1102:0008 (rev 00) Subsystem: 1102:1001 -> Audigy2 Value Model:SB0400
78 */ 78 */
79static struct pci_device_id snd_emu10k1_ids[] = { 79static DEFINE_PCI_DEVICE_TABLE(snd_emu10k1_ids) = {
80 { PCI_VDEVICE(CREATIVE, 0x0002), 0 }, /* EMU10K1 */ 80 { PCI_VDEVICE(CREATIVE, 0x0002), 0 }, /* EMU10K1 */
81 { PCI_VDEVICE(CREATIVE, 0x0004), 1 }, /* Audigy */ 81 { PCI_VDEVICE(CREATIVE, 0x0004), 1 }, /* Audigy */
82 { PCI_VDEVICE(CREATIVE, 0x0008), 1 }, /* Audigy 2 Value SB0400 */ 82 { PCI_VDEVICE(CREATIVE, 0x0008), 1 }, /* Audigy 2 Value SB0400 */
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c
index 36e08bd2b3cc..df47f738098d 100644
--- a/sound/pci/emu10k1/emu10k1x.c
+++ b/sound/pci/emu10k1/emu10k1x.c
@@ -184,7 +184,7 @@ MODULE_PARM_DESC(enable, "Enable the EMU10K1X soundcard.");
184 * The hardware has 3 channels for playback and 1 for capture. 184 * The hardware has 3 channels for playback and 1 for capture.
185 * - channel 0 is the front channel 185 * - channel 0 is the front channel
186 * - channel 1 is the rear channel 186 * - channel 1 is the rear channel
187 * - channel 2 is the center/lfe chanel 187 * - channel 2 is the center/lfe channel
188 * Volume is controlled by the AC97 for the front and rear channels by 188 * Volume is controlled by the AC97 for the front and rear channels by
189 * the PCM Playback Volume, Sigmatel Surround Playback Volume and 189 * the PCM Playback Volume, Sigmatel Surround Playback Volume and
190 * Surround Playback Volume. The Sigmatel 4-Speaker Stereo switch affects 190 * Surround Playback Volume. The Sigmatel 4-Speaker Stereo switch affects
@@ -1040,8 +1040,7 @@ static void snd_emu10k1x_proc_reg_write(struct snd_info_entry *entry,
1040 if (sscanf(line, "%x %x %x", &reg, &channel_id, &val) != 3) 1040 if (sscanf(line, "%x %x %x", &reg, &channel_id, &val) != 3)
1041 continue; 1041 continue;
1042 1042
1043 if ((reg < 0x49) && (reg >= 0) && (val <= 0xffffffff) 1043 if (reg < 0x49 && val <= 0xffffffff && channel_id <= 2)
1044 && (channel_id >= 0) && (channel_id <= 2) )
1045 snd_emu10k1x_ptr_write(emu, reg, channel_id, val); 1044 snd_emu10k1x_ptr_write(emu, reg, channel_id, val);
1046 } 1045 }
1047} 1046}
@@ -1606,7 +1605,7 @@ static void __devexit snd_emu10k1x_remove(struct pci_dev *pci)
1606} 1605}
1607 1606
1608// PCI IDs 1607// PCI IDs
1609static struct pci_device_id snd_emu10k1x_ids[] = { 1608static DEFINE_PCI_DEVICE_TABLE(snd_emu10k1x_ids) = {
1610 { PCI_VDEVICE(CREATIVE, 0x0006), 0 }, /* Dell OEM version (EMU10K1) */ 1609 { PCI_VDEVICE(CREATIVE, 0x0006), 0 }, /* Dell OEM version (EMU10K1) */
1611 { 0, } 1610 { 0, }
1612}; 1611};
diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c
index b0fb6c917c38..05afe06e353a 100644
--- a/sound/pci/emu10k1/emumixer.c
+++ b/sound/pci/emu10k1/emumixer.c
@@ -1818,8 +1818,8 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu,
1818 "Master Playback Switch", "Master Capture Switch", 1818 "Master Playback Switch", "Master Capture Switch",
1819 "Master Playback Volume", "Master Capture Volume", 1819 "Master Playback Volume", "Master Capture Volume",
1820 "Wave Master Playback Volume", "Master Playback Volume", 1820 "Wave Master Playback Volume", "Master Playback Volume",
1821 "PC Speaker Playback Switch", "PC Speaker Capture Switch", 1821 "Beep Playback Switch", "Beep Capture Switch",
1822 "PC Speaker Playback Volume", "PC Speaker Capture Volume", 1822 "Beep Playback Volume", "Beep Capture Volume",
1823 "Phone Playback Switch", "Phone Capture Switch", 1823 "Phone Playback Switch", "Phone Capture Switch",
1824 "Phone Playback Volume", "Phone Capture Volume", 1824 "Phone Playback Volume", "Phone Capture Volume",
1825 "Mic Playback Switch", "Mic Capture Switch", 1825 "Mic Playback Switch", "Mic Capture Switch",
diff --git a/sound/pci/emu10k1/emuproc.c b/sound/pci/emu10k1/emuproc.c
index 216f9748aff5..baa7cd508cd8 100644
--- a/sound/pci/emu10k1/emuproc.c
+++ b/sound/pci/emu10k1/emuproc.c
@@ -451,7 +451,7 @@ static void snd_emu_proc_io_reg_write(struct snd_info_entry *entry,
451 while (!snd_info_get_line(buffer, line, sizeof(line))) { 451 while (!snd_info_get_line(buffer, line, sizeof(line))) {
452 if (sscanf(line, "%x %x", &reg, &val) != 2) 452 if (sscanf(line, "%x %x", &reg, &val) != 2)
453 continue; 453 continue;
454 if ((reg < 0x40) && (reg >= 0) && (val <= 0xffffffff) ) { 454 if (reg < 0x40 && val <= 0xffffffff) {
455 spin_lock_irqsave(&emu->emu_lock, flags); 455 spin_lock_irqsave(&emu->emu_lock, flags);
456 outl(val, emu->port + (reg & 0xfffffffc)); 456 outl(val, emu->port + (reg & 0xfffffffc));
457 spin_unlock_irqrestore(&emu->emu_lock, flags); 457 spin_unlock_irqrestore(&emu->emu_lock, flags);
@@ -527,7 +527,7 @@ static void snd_emu_proc_ptr_reg_write(struct snd_info_entry *entry,
527 while (!snd_info_get_line(buffer, line, sizeof(line))) { 527 while (!snd_info_get_line(buffer, line, sizeof(line))) {
528 if (sscanf(line, "%x %x %x", &reg, &channel_id, &val) != 3) 528 if (sscanf(line, "%x %x %x", &reg, &channel_id, &val) != 3)
529 continue; 529 continue;
530 if ((reg < 0xa0) && (reg >= 0) && (val <= 0xffffffff) && (channel_id >= 0) && (channel_id <= 3) ) 530 if (reg < 0xa0 && val <= 0xffffffff && channel_id <= 3)
531 snd_ptr_write(emu, iobase, reg, channel_id, val); 531 snd_ptr_write(emu, iobase, reg, channel_id, val);
532 } 532 }
533} 533}
diff --git a/sound/pci/emu10k1/io.c b/sound/pci/emu10k1/io.c
index c1a5aa15af8f..5ef7080e14d0 100644
--- a/sound/pci/emu10k1/io.c
+++ b/sound/pci/emu10k1/io.c
@@ -256,7 +256,7 @@ int snd_emu1010_fpga_write(struct snd_emu10k1 * emu, u32 reg, u32 value)
256 if (reg > 0x3f) 256 if (reg > 0x3f)
257 return 1; 257 return 1;
258 reg += 0x40; /* 0x40 upwards are registers. */ 258 reg += 0x40; /* 0x40 upwards are registers. */
259 if (value < 0 || value > 0x3f) /* 0 to 0x3f are values */ 259 if (value > 0x3f) /* 0 to 0x3f are values */
260 return 1; 260 return 1;
261 spin_lock_irqsave(&emu->emu_lock, flags); 261 spin_lock_irqsave(&emu->emu_lock, flags);
262 outl(reg, emu->port + A_IOCFG); 262 outl(reg, emu->port + A_IOCFG);
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/ens1370.c b/sound/pci/ens1370.c
index 2b82c5c723e1..c7fba5379813 100644
--- a/sound/pci/ens1370.c
+++ b/sound/pci/ens1370.c
@@ -443,7 +443,7 @@ struct ensoniq {
443 443
444static irqreturn_t snd_audiopci_interrupt(int irq, void *dev_id); 444static irqreturn_t snd_audiopci_interrupt(int irq, void *dev_id);
445 445
446static struct pci_device_id snd_audiopci_ids[] = { 446static DEFINE_PCI_DEVICE_TABLE(snd_audiopci_ids) = {
447#ifdef CHIP1370 447#ifdef CHIP1370
448 { PCI_VDEVICE(ENSONIQ, 0x5000), 0, }, /* ES1370 */ 448 { PCI_VDEVICE(ENSONIQ, 0x5000), 0, }, /* ES1370 */
449#endif 449#endif
diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c
index 820318ee62c1..553b75217259 100644
--- a/sound/pci/es1938.c
+++ b/sound/pci/es1938.c
@@ -243,7 +243,7 @@ struct es1938 {
243 243
244static irqreturn_t snd_es1938_interrupt(int irq, void *dev_id); 244static irqreturn_t snd_es1938_interrupt(int irq, void *dev_id);
245 245
246static struct pci_device_id snd_es1938_ids[] = { 246static DEFINE_PCI_DEVICE_TABLE(snd_es1938_ids) = {
247 { PCI_VDEVICE(ESS, 0x1969), 0, }, /* Solo-1 */ 247 { PCI_VDEVICE(ESS, 0x1969), 0, }, /* Solo-1 */
248 { 0, } 248 { 0, }
249}; 249};
@@ -1387,7 +1387,7 @@ ES1938_DOUBLE_TLV("Aux Playback Volume", 0, 0x3a, 0x3a, 4, 0, 15, 0,
1387 db_scale_line), 1387 db_scale_line),
1388ES1938_DOUBLE_TLV("Capture Volume", 0, 0xb4, 0xb4, 4, 0, 15, 0, 1388ES1938_DOUBLE_TLV("Capture Volume", 0, 0xb4, 0xb4, 4, 0, 15, 0,
1389 db_scale_capture), 1389 db_scale_capture),
1390ES1938_SINGLE("PC Speaker Volume", 0, 0x3c, 0, 7, 0), 1390ES1938_SINGLE("Beep Volume", 0, 0x3c, 0, 7, 0),
1391ES1938_SINGLE("Record Monitor", 0, 0xa8, 3, 1, 0), 1391ES1938_SINGLE("Record Monitor", 0, 0xa8, 3, 1, 0),
1392ES1938_SINGLE("Capture Switch", 0, 0x1c, 4, 1, 1), 1392ES1938_SINGLE("Capture Switch", 0, 0x1c, 4, 1, 1),
1393{ 1393{
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index a11f453a6b6d..ecaea9fb48ec 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -551,7 +551,7 @@ struct es1968 {
551 551
552static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id); 552static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id);
553 553
554static struct pci_device_id snd_es1968_ids[] = { 554static DEFINE_PCI_DEVICE_TABLE(snd_es1968_ids) = {
555 /* Maestro 1 */ 555 /* Maestro 1 */
556 { 0x1285, 0x0100, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, TYPE_MAESTRO }, 556 { 0x1285, 0x0100, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, TYPE_MAESTRO },
557 /* Maestro 2 */ 557 /* Maestro 2 */
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
index 60cdb9e0b68d..e1baad74ea4b 100644
--- a/sound/pci/fm801.c
+++ b/sound/pci/fm801.c
@@ -55,7 +55,7 @@ static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card *
55 * 1 = MediaForte 256-PCS 55 * 1 = MediaForte 256-PCS
56 * 2 = MediaForte 256-PCPR 56 * 2 = MediaForte 256-PCPR
57 * 3 = MediaForte 64-PCR 57 * 3 = MediaForte 64-PCR
58 * 16 = setup tuner only (this is additional bit), i.e. SF-64-PCR FM card 58 * 16 = setup tuner only (this is additional bit), i.e. SF64-PCR FM card
59 * High 16-bits are video (radio) device number + 1 59 * High 16-bits are video (radio) device number + 1
60 */ 60 */
61static int tea575x_tuner[SNDRV_CARDS]; 61static int tea575x_tuner[SNDRV_CARDS];
@@ -67,7 +67,10 @@ MODULE_PARM_DESC(id, "ID string for the FM801 soundcard.");
67module_param_array(enable, bool, NULL, 0444); 67module_param_array(enable, bool, NULL, 0444);
68MODULE_PARM_DESC(enable, "Enable FM801 soundcard."); 68MODULE_PARM_DESC(enable, "Enable FM801 soundcard.");
69module_param_array(tea575x_tuner, int, NULL, 0444); 69module_param_array(tea575x_tuner, int, NULL, 0444);
70MODULE_PARM_DESC(tea575x_tuner, "Enable TEA575x tuner."); 70MODULE_PARM_DESC(tea575x_tuner, "TEA575x tuner access method (1 = SF256-PCS, 2=SF256-PCPR, 3=SF64-PCR, +16=tuner-only).");
71
72#define TUNER_ONLY (1<<4)
73#define TUNER_TYPE_MASK (~TUNER_ONLY & 0xFFFF)
71 74
72/* 75/*
73 * Direct registers 76 * Direct registers
@@ -160,7 +163,7 @@ struct fm801 {
160 unsigned int multichannel: 1, /* multichannel support */ 163 unsigned int multichannel: 1, /* multichannel support */
161 secondary: 1; /* secondary codec */ 164 secondary: 1; /* secondary codec */
162 unsigned char secondary_addr; /* address of the secondary codec */ 165 unsigned char secondary_addr; /* address of the secondary codec */
163 unsigned int tea575x_tuner; /* tuner flags */ 166 unsigned int tea575x_tuner; /* tuner access method & flags */
164 167
165 unsigned short ply_ctrl; /* playback control */ 168 unsigned short ply_ctrl; /* playback control */
166 unsigned short cap_ctrl; /* capture control */ 169 unsigned short cap_ctrl; /* capture control */
@@ -202,7 +205,7 @@ struct fm801 {
202#endif 205#endif
203}; 206};
204 207
205static struct pci_device_id snd_fm801_ids[] = { 208static DEFINE_PCI_DEVICE_TABLE(snd_fm801_ids) = {
206 { 0x1319, 0x0801, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0, }, /* FM801 */ 209 { 0x1319, 0x0801, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0, }, /* FM801 */
207 { 0x5213, 0x0510, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0, }, /* Gallant Odyssey Sound 4 */ 210 { 0x5213, 0x0510, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0, }, /* Gallant Odyssey Sound 4 */
208 { 0, } 211 { 0, }
@@ -1287,7 +1290,7 @@ static int snd_fm801_chip_init(struct fm801 *chip, int resume)
1287{ 1290{
1288 unsigned short cmdw; 1291 unsigned short cmdw;
1289 1292
1290 if (chip->tea575x_tuner & 0x0010) 1293 if (chip->tea575x_tuner & TUNER_ONLY)
1291 goto __ac97_ok; 1294 goto __ac97_ok;
1292 1295
1293 /* codec cold reset + AC'97 warm reset */ 1296 /* codec cold reset + AC'97 warm reset */
@@ -1296,11 +1299,13 @@ static int snd_fm801_chip_init(struct fm801 *chip, int resume)
1296 udelay(100); 1299 udelay(100);
1297 outw(0, FM801_REG(chip, CODEC_CTRL)); 1300 outw(0, FM801_REG(chip, CODEC_CTRL));
1298 1301
1299 if (wait_for_codec(chip, 0, AC97_RESET, msecs_to_jiffies(750)) < 0) { 1302 if (wait_for_codec(chip, 0, AC97_RESET, msecs_to_jiffies(750)) < 0)
1300 snd_printk(KERN_ERR "Primary AC'97 codec not found\n"); 1303 if (!resume) {
1301 if (! resume) 1304 snd_printk(KERN_INFO "Primary AC'97 codec not found, "
1302 return -EIO; 1305 "assume SF64-PCR (tuner-only)\n");
1303 } 1306 chip->tea575x_tuner = 3 | TUNER_ONLY;
1307 goto __ac97_ok;
1308 }
1304 1309
1305 if (chip->multichannel) { 1310 if (chip->multichannel) {
1306 if (chip->secondary_addr) { 1311 if (chip->secondary_addr) {
@@ -1414,7 +1419,7 @@ static int __devinit snd_fm801_create(struct snd_card *card,
1414 return err; 1419 return err;
1415 } 1420 }
1416 chip->port = pci_resource_start(pci, 0); 1421 chip->port = pci_resource_start(pci, 0);
1417 if ((tea575x_tuner & 0x0010) == 0) { 1422 if ((tea575x_tuner & TUNER_ONLY) == 0) {
1418 if (request_irq(pci->irq, snd_fm801_interrupt, IRQF_SHARED, 1423 if (request_irq(pci->irq, snd_fm801_interrupt, IRQF_SHARED,
1419 "FM801", chip)) { 1424 "FM801", chip)) {
1420 snd_printk(KERN_ERR "unable to grab IRQ %d\n", chip->irq); 1425 snd_printk(KERN_ERR "unable to grab IRQ %d\n", chip->irq);
@@ -1429,6 +1434,14 @@ static int __devinit snd_fm801_create(struct snd_card *card,
1429 chip->multichannel = 1; 1434 chip->multichannel = 1;
1430 1435
1431 snd_fm801_chip_init(chip, 0); 1436 snd_fm801_chip_init(chip, 0);
1437 /* init might set tuner access method */
1438 tea575x_tuner = chip->tea575x_tuner;
1439
1440 if (chip->irq >= 0 && (tea575x_tuner & TUNER_ONLY)) {
1441 pci_clear_master(pci);
1442 free_irq(chip->irq, chip);
1443 chip->irq = -1;
1444 }
1432 1445
1433 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { 1446 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
1434 snd_fm801_free(chip); 1447 snd_fm801_free(chip);
@@ -1438,12 +1451,13 @@ static int __devinit snd_fm801_create(struct snd_card *card,
1438 snd_card_set_dev(card, &pci->dev); 1451 snd_card_set_dev(card, &pci->dev);
1439 1452
1440#ifdef TEA575X_RADIO 1453#ifdef TEA575X_RADIO
1441 if (tea575x_tuner > 0 && (tea575x_tuner & 0x000f) < 4) { 1454 if ((tea575x_tuner & TUNER_TYPE_MASK) > 0 &&
1455 (tea575x_tuner & TUNER_TYPE_MASK) < 4) {
1442 chip->tea.dev_nr = tea575x_tuner >> 16; 1456 chip->tea.dev_nr = tea575x_tuner >> 16;
1443 chip->tea.card = card; 1457 chip->tea.card = card;
1444 chip->tea.freq_fixup = 10700; 1458 chip->tea.freq_fixup = 10700;
1445 chip->tea.private_data = chip; 1459 chip->tea.private_data = chip;
1446 chip->tea.ops = &snd_fm801_tea_ops[(tea575x_tuner & 0x000f) - 1]; 1460 chip->tea.ops = &snd_fm801_tea_ops[(tea575x_tuner & TUNER_TYPE_MASK) - 1];
1447 snd_tea575x_init(&chip->tea); 1461 snd_tea575x_init(&chip->tea);
1448 } 1462 }
1449#endif 1463#endif
@@ -1483,7 +1497,7 @@ static int __devinit snd_card_fm801_probe(struct pci_dev *pci,
1483 sprintf(card->longname, "%s at 0x%lx, irq %i", 1497 sprintf(card->longname, "%s at 0x%lx, irq %i",
1484 card->shortname, chip->port, chip->irq); 1498 card->shortname, chip->port, chip->irq);
1485 1499
1486 if (tea575x_tuner[dev] & 0x0010) 1500 if (chip->tea575x_tuner & TUNER_ONLY)
1487 goto __fm801_tuner_only; 1501 goto __fm801_tuner_only;
1488 1502
1489 if ((err = snd_fm801_pcm(chip, 0, NULL)) < 0) { 1503 if ((err = snd_fm801_pcm(chip, 0, NULL)) < 0) {
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig
index 55545e0818b5..567348b05b5a 100644
--- a/sound/pci/hda/Kconfig
+++ b/sound/pci/hda/Kconfig
@@ -38,9 +38,20 @@ config SND_HDA_INPUT_BEEP
38 Say Y here to build a digital beep interface for HD-audio 38 Say Y here to build a digital beep interface for HD-audio
39 driver. This interface is used to generate digital beeps. 39 driver. This interface is used to generate digital beeps.
40 40
41config SND_HDA_INPUT_BEEP_MODE
42 int "Digital beep registration mode (0=off, 1=on, 2=mute sw on/off)"
43 depends on SND_HDA_INPUT_BEEP=y
44 default "1"
45 range 0 2
46 help
47 Set 0 to disable the digital beep interface for HD-audio by default.
48 Set 1 to always enable the digital beep interface for HD-audio by
49 default. Set 2 to control the beep device registration to input
50 layer using a "Beep Switch" in mixer applications.
51
41config SND_HDA_INPUT_JACK 52config SND_HDA_INPUT_JACK
42 bool "Support jack plugging notification via input layer" 53 bool "Support jack plugging notification via input layer"
43 depends on INPUT=y || INPUT=SND_HDA_INTEL 54 depends on INPUT=y || INPUT=SND
44 select SND_JACK 55 select SND_JACK
45 help 56 help
46 Say Y here to enable the jack plugging notification via 57 Say Y here to enable the jack plugging notification via
@@ -146,7 +157,7 @@ config SND_HDA_CODEC_INTELHDMI
146 157
147config SND_HDA_ELD 158config SND_HDA_ELD
148 def_bool y 159 def_bool y
149 depends on SND_HDA_CODEC_INTELHDMI 160 depends on SND_HDA_CODEC_INTELHDMI || SND_HDA_CODEC_NVHDMI
150 161
151config SND_HDA_CODEC_CIRRUS 162config SND_HDA_CODEC_CIRRUS
152 bool "Build Cirrus Logic codec support" 163 bool "Build Cirrus Logic codec support"
diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile
index 315a1c4f8998..24bc195b02da 100644
--- a/sound/pci/hda/Makefile
+++ b/sound/pci/hda/Makefile
@@ -3,7 +3,7 @@ snd-hda-intel-objs := hda_intel.o
3snd-hda-codec-y := hda_codec.o 3snd-hda-codec-y := hda_codec.o
4snd-hda-codec-$(CONFIG_SND_HDA_GENERIC) += hda_generic.o 4snd-hda-codec-$(CONFIG_SND_HDA_GENERIC) += hda_generic.o
5snd-hda-codec-$(CONFIG_PROC_FS) += hda_proc.o 5snd-hda-codec-$(CONFIG_PROC_FS) += hda_proc.o
6# snd-hda-codec-$(CONFIG_SND_HDA_ELD) += hda_eld.o 6snd-hda-codec-$(CONFIG_SND_HDA_ELD) += hda_eld.o
7snd-hda-codec-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o 7snd-hda-codec-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o
8snd-hda-codec-$(CONFIG_SND_HDA_INPUT_BEEP) += hda_beep.o 8snd-hda-codec-$(CONFIG_SND_HDA_INPUT_BEEP) += hda_beep.o
9 9
@@ -18,7 +18,7 @@ snd-hda-codec-ca0110-objs := patch_ca0110.o
18snd-hda-codec-conexant-objs := patch_conexant.o 18snd-hda-codec-conexant-objs := patch_conexant.o
19snd-hda-codec-via-objs := patch_via.o 19snd-hda-codec-via-objs := patch_via.o
20snd-hda-codec-nvhdmi-objs := patch_nvhdmi.o 20snd-hda-codec-nvhdmi-objs := patch_nvhdmi.o
21snd-hda-codec-intelhdmi-objs := patch_intelhdmi.o hda_eld.o 21snd-hda-codec-intelhdmi-objs := patch_intelhdmi.o
22 22
23# common driver 23# common driver
24obj-$(CONFIG_SND_HDA_INTEL) := snd-hda-codec.o 24obj-$(CONFIG_SND_HDA_INTEL) := snd-hda-codec.o
diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c
index 3f51a981e604..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"
@@ -42,7 +43,7 @@ static void snd_hda_generate_beep(struct work_struct *work)
42 return; 43 return;
43 44
44 /* generate tone */ 45 /* generate tone */
45 snd_hda_codec_write_cache(codec, beep->nid, 0, 46 snd_hda_codec_write(codec, beep->nid, 0,
46 AC_VERB_SET_BEEP_CONTROL, beep->tone); 47 AC_VERB_SET_BEEP_CONTROL, beep->tone);
47} 48}
48 49
@@ -113,23 +114,25 @@ static int snd_hda_beep_event(struct input_dev *dev, unsigned int type,
113 return 0; 114 return 0;
114} 115}
115 116
116int snd_hda_attach_beep_device(struct hda_codec *codec, int nid) 117static void snd_hda_do_detach(struct hda_beep *beep)
118{
119 input_unregister_device(beep->dev);
120 beep->dev = NULL;
121 cancel_work_sync(&beep->beep_work);
122 /* turn off beep for sure */
123 snd_hda_codec_write(beep->codec, beep->nid, 0,
124 AC_VERB_SET_BEEP_CONTROL, 0);
125}
126
127static int snd_hda_do_attach(struct hda_beep *beep)
117{ 128{
118 struct input_dev *input_dev; 129 struct input_dev *input_dev;
119 struct hda_beep *beep; 130 struct hda_codec *codec = beep->codec;
120 int err; 131 int err;
121 132
122 if (!snd_hda_get_bool_hint(codec, "beep"))
123 return 0; /* disabled explicitly */
124
125 beep = kzalloc(sizeof(*beep), GFP_KERNEL);
126 if (beep == NULL)
127 return -ENOMEM;
128 snprintf(beep->phys, sizeof(beep->phys),
129 "card%d/codec#%d/beep0", codec->bus->card->number, codec->addr);
130 input_dev = input_allocate_device(); 133 input_dev = input_allocate_device();
131 if (!input_dev) { 134 if (!input_dev) {
132 kfree(beep); 135 printk(KERN_INFO "hda_beep: unable to allocate input device\n");
133 return -ENOMEM; 136 return -ENOMEM;
134 } 137 }
135 138
@@ -151,21 +154,100 @@ int snd_hda_attach_beep_device(struct hda_codec *codec, int nid)
151 err = input_register_device(input_dev); 154 err = input_register_device(input_dev);
152 if (err < 0) { 155 if (err < 0) {
153 input_free_device(input_dev); 156 input_free_device(input_dev);
154 kfree(beep); 157 printk(KERN_INFO "hda_beep: unable to register input device\n");
155 return err; 158 return err;
156 } 159 }
160 beep->dev = input_dev;
161 return 0;
162}
163
164static void snd_hda_do_register(struct work_struct *work)
165{
166 struct hda_beep *beep =
167 container_of(work, struct hda_beep, register_work);
168
169 mutex_lock(&beep->mutex);
170 if (beep->enabled && !beep->dev)
171 snd_hda_do_attach(beep);
172 mutex_unlock(&beep->mutex);
173}
174
175static void snd_hda_do_unregister(struct work_struct *work)
176{
177 struct hda_beep *beep =
178 container_of(work, struct hda_beep, unregister_work.work);
179
180 mutex_lock(&beep->mutex);
181 if (!beep->enabled && beep->dev)
182 snd_hda_do_detach(beep);
183 mutex_unlock(&beep->mutex);
184}
157 185
186int snd_hda_enable_beep_device(struct hda_codec *codec, int enable)
187{
188 struct hda_beep *beep = codec->beep;
189 enable = !!enable;
190 if (beep == NULL)
191 return 0;
192 if (beep->enabled != enable) {
193 beep->enabled = enable;
194 if (!enable) {
195 /* turn off beep */
196 snd_hda_codec_write(beep->codec, beep->nid, 0,
197 AC_VERB_SET_BEEP_CONTROL, 0);
198 }
199 if (beep->mode == HDA_BEEP_MODE_SWREG) {
200 if (enable) {
201 cancel_delayed_work(&beep->unregister_work);
202 schedule_work(&beep->register_work);
203 } else {
204 schedule_delayed_work(&beep->unregister_work,
205 HZ);
206 }
207 }
208 return 1;
209 }
210 return 0;
211}
212EXPORT_SYMBOL_HDA(snd_hda_enable_beep_device);
213
214int snd_hda_attach_beep_device(struct hda_codec *codec, int nid)
215{
216 struct hda_beep *beep;
217
218 if (!snd_hda_get_bool_hint(codec, "beep"))
219 return 0; /* disabled explicitly by hints */
220 if (codec->beep_mode == HDA_BEEP_MODE_OFF)
221 return 0; /* disabled by module option */
222
223 beep = kzalloc(sizeof(*beep), GFP_KERNEL);
224 if (beep == NULL)
225 return -ENOMEM;
226 snprintf(beep->phys, sizeof(beep->phys),
227 "card%d/codec#%d/beep0", codec->bus->card->number, codec->addr);
158 /* enable linear scale */ 228 /* enable linear scale */
159 snd_hda_codec_write(codec, nid, 0, 229 snd_hda_codec_write(codec, nid, 0,
160 AC_VERB_SET_DIGI_CONVERT_2, 0x01); 230 AC_VERB_SET_DIGI_CONVERT_2, 0x01);
161 231
162 beep->nid = nid; 232 beep->nid = nid;
163 beep->dev = input_dev;
164 beep->codec = codec; 233 beep->codec = codec;
165 beep->enabled = 1; 234 beep->mode = codec->beep_mode;
166 codec->beep = beep; 235 codec->beep = beep;
167 236
237 INIT_WORK(&beep->register_work, &snd_hda_do_register);
238 INIT_DELAYED_WORK(&beep->unregister_work, &snd_hda_do_unregister);
168 INIT_WORK(&beep->beep_work, &snd_hda_generate_beep); 239 INIT_WORK(&beep->beep_work, &snd_hda_generate_beep);
240 mutex_init(&beep->mutex);
241
242 if (beep->mode == HDA_BEEP_MODE_ON) {
243 int err = snd_hda_do_attach(beep);
244 if (err < 0) {
245 kfree(beep);
246 codec->beep = NULL;
247 return err;
248 }
249 }
250
169 return 0; 251 return 0;
170} 252}
171EXPORT_SYMBOL_HDA(snd_hda_attach_beep_device); 253EXPORT_SYMBOL_HDA(snd_hda_attach_beep_device);
@@ -174,11 +256,12 @@ void snd_hda_detach_beep_device(struct hda_codec *codec)
174{ 256{
175 struct hda_beep *beep = codec->beep; 257 struct hda_beep *beep = codec->beep;
176 if (beep) { 258 if (beep) {
177 cancel_work_sync(&beep->beep_work); 259 cancel_work_sync(&beep->register_work);
178 260 cancel_delayed_work(&beep->unregister_work);
179 input_unregister_device(beep->dev); 261 if (beep->dev)
180 kfree(beep); 262 snd_hda_do_detach(beep);
181 codec->beep = NULL; 263 codec->beep = NULL;
264 kfree(beep);
182 } 265 }
183} 266}
184EXPORT_SYMBOL_HDA(snd_hda_detach_beep_device); 267EXPORT_SYMBOL_HDA(snd_hda_detach_beep_device);
diff --git a/sound/pci/hda/hda_beep.h b/sound/pci/hda/hda_beep.h
index 0c3de787c717..f1de1bac042c 100644
--- a/sound/pci/hda/hda_beep.h
+++ b/sound/pci/hda/hda_beep.h
@@ -24,19 +24,29 @@
24 24
25#include "hda_codec.h" 25#include "hda_codec.h"
26 26
27#define HDA_BEEP_MODE_OFF 0
28#define HDA_BEEP_MODE_ON 1
29#define HDA_BEEP_MODE_SWREG 2
30
27/* beep information */ 31/* beep information */
28struct hda_beep { 32struct hda_beep {
29 struct input_dev *dev; 33 struct input_dev *dev;
30 struct hda_codec *codec; 34 struct hda_codec *codec;
35 unsigned int mode;
31 char phys[32]; 36 char phys[32];
32 int tone; 37 int tone;
33 hda_nid_t nid; 38 hda_nid_t nid;
34 unsigned int enabled:1; 39 unsigned int enabled:1;
40 unsigned int request_enable:1;
35 unsigned int linear_tone:1; /* linear tone for IDT/STAC codec */ 41 unsigned int linear_tone:1; /* linear tone for IDT/STAC codec */
42 struct work_struct register_work; /* registration work */
43 struct delayed_work unregister_work; /* unregistration work */
36 struct work_struct beep_work; /* scheduled task for beep event */ 44 struct work_struct beep_work; /* scheduled task for beep event */
45 struct mutex mutex;
37}; 46};
38 47
39#ifdef CONFIG_SND_HDA_INPUT_BEEP 48#ifdef CONFIG_SND_HDA_INPUT_BEEP
49int snd_hda_enable_beep_device(struct hda_codec *codec, int enable);
40int snd_hda_attach_beep_device(struct hda_codec *codec, int nid); 50int snd_hda_attach_beep_device(struct hda_codec *codec, int nid);
41void snd_hda_detach_beep_device(struct hda_codec *codec); 51void snd_hda_detach_beep_device(struct hda_codec *codec);
42#else 52#else
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index af989f660cca..0e76ac2b2ace 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -30,6 +30,7 @@
30#include <sound/tlv.h> 30#include <sound/tlv.h>
31#include <sound/initval.h> 31#include <sound/initval.h>
32#include "hda_local.h" 32#include "hda_local.h"
33#include "hda_beep.h"
33#include <sound/hda_hwdep.h> 34#include <sound/hda_hwdep.h>
34 35
35/* 36/*
@@ -93,6 +94,13 @@ static void hda_keep_power_on(struct hda_codec *codec);
93static inline void hda_keep_power_on(struct hda_codec *codec) {} 94static inline void hda_keep_power_on(struct hda_codec *codec) {}
94#endif 95#endif
95 96
97/**
98 * snd_hda_get_jack_location - Give a location string of the jack
99 * @cfg: pin default config value
100 *
101 * Parse the pin default config value and returns the string of the
102 * jack location, e.g. "Rear", "Front", etc.
103 */
96const char *snd_hda_get_jack_location(u32 cfg) 104const char *snd_hda_get_jack_location(u32 cfg)
97{ 105{
98 static char *bases[7] = { 106 static char *bases[7] = {
@@ -120,6 +128,13 @@ const char *snd_hda_get_jack_location(u32 cfg)
120} 128}
121EXPORT_SYMBOL_HDA(snd_hda_get_jack_location); 129EXPORT_SYMBOL_HDA(snd_hda_get_jack_location);
122 130
131/**
132 * snd_hda_get_jack_connectivity - Give a connectivity string of the jack
133 * @cfg: pin default config value
134 *
135 * Parse the pin default config value and returns the string of the
136 * jack connectivity, i.e. external or internal connection.
137 */
123const char *snd_hda_get_jack_connectivity(u32 cfg) 138const char *snd_hda_get_jack_connectivity(u32 cfg)
124{ 139{
125 static char *jack_locations[4] = { "Ext", "Int", "Sep", "Oth" }; 140 static char *jack_locations[4] = { "Ext", "Int", "Sep", "Oth" };
@@ -128,6 +143,13 @@ const char *snd_hda_get_jack_connectivity(u32 cfg)
128} 143}
129EXPORT_SYMBOL_HDA(snd_hda_get_jack_connectivity); 144EXPORT_SYMBOL_HDA(snd_hda_get_jack_connectivity);
130 145
146/**
147 * snd_hda_get_jack_type - Give a type string of the jack
148 * @cfg: pin default config value
149 *
150 * Parse the pin default config value and returns the string of the
151 * jack type, i.e. the purpose of the jack, such as Line-Out or CD.
152 */
131const char *snd_hda_get_jack_type(u32 cfg) 153const char *snd_hda_get_jack_type(u32 cfg)
132{ 154{
133 static char *jack_types[16] = { 155 static char *jack_types[16] = {
@@ -515,6 +537,7 @@ static int snd_hda_bus_dev_register(struct snd_device *device)
515 struct hda_codec *codec; 537 struct hda_codec *codec;
516 list_for_each_entry(codec, &bus->codec_list, list) { 538 list_for_each_entry(codec, &bus->codec_list, list) {
517 snd_hda_hwdep_add_sysfs(codec); 539 snd_hda_hwdep_add_sysfs(codec);
540 snd_hda_hwdep_add_power_sysfs(codec);
518 } 541 }
519 return 0; 542 return 0;
520} 543}
@@ -801,6 +824,9 @@ int snd_hda_add_pincfg(struct hda_codec *codec, struct snd_array *list,
801 struct hda_pincfg *pin; 824 struct hda_pincfg *pin;
802 unsigned int oldcfg; 825 unsigned int oldcfg;
803 826
827 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
828 return -EINVAL;
829
804 oldcfg = snd_hda_codec_get_pincfg(codec, nid); 830 oldcfg = snd_hda_codec_get_pincfg(codec, nid);
805 pin = look_up_pincfg(codec, list, nid); 831 pin = look_up_pincfg(codec, list, nid);
806 if (!pin) { 832 if (!pin) {
@@ -820,6 +846,16 @@ int snd_hda_add_pincfg(struct hda_codec *codec, struct snd_array *list,
820 return 0; 846 return 0;
821} 847}
822 848
849/**
850 * snd_hda_codec_set_pincfg - Override a pin default configuration
851 * @codec: the HDA codec
852 * @nid: NID to set the pin config
853 * @cfg: the pin default config value
854 *
855 * Override a pin default configuration value in the cache.
856 * This value can be read by snd_hda_codec_get_pincfg() in a higher
857 * priority than the real hardware value.
858 */
823int snd_hda_codec_set_pincfg(struct hda_codec *codec, 859int snd_hda_codec_set_pincfg(struct hda_codec *codec,
824 hda_nid_t nid, unsigned int cfg) 860 hda_nid_t nid, unsigned int cfg)
825{ 861{
@@ -827,7 +863,15 @@ int snd_hda_codec_set_pincfg(struct hda_codec *codec,
827} 863}
828EXPORT_SYMBOL_HDA(snd_hda_codec_set_pincfg); 864EXPORT_SYMBOL_HDA(snd_hda_codec_set_pincfg);
829 865
830/* get the current pin config value of the given pin NID */ 866/**
867 * snd_hda_codec_get_pincfg - Obtain a pin-default configuration
868 * @codec: the HDA codec
869 * @nid: NID to get the pin config
870 *
871 * Get the current pin config value of the given pin NID.
872 * If the pincfg value is cached or overridden via sysfs or driver,
873 * returns the cached value.
874 */
831unsigned int snd_hda_codec_get_pincfg(struct hda_codec *codec, hda_nid_t nid) 875unsigned int snd_hda_codec_get_pincfg(struct hda_codec *codec, hda_nid_t nid)
832{ 876{
833 struct hda_pincfg *pin; 877 struct hda_pincfg *pin;
@@ -858,6 +902,25 @@ static void restore_pincfgs(struct hda_codec *codec)
858 } 902 }
859} 903}
860 904
905/**
906 * snd_hda_shutup_pins - Shut up all pins
907 * @codec: the HDA codec
908 *
909 * Clear all pin controls to shup up before suspend for avoiding click noise.
910 * The controls aren't cached so that they can be resumed properly.
911 */
912void snd_hda_shutup_pins(struct hda_codec *codec)
913{
914 int i;
915 for (i = 0; i < codec->init_pins.used; i++) {
916 struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i);
917 /* use read here for syncing after issuing each verb */
918 snd_hda_codec_read(codec, pin->nid, 0,
919 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
920 }
921}
922EXPORT_SYMBOL_HDA(snd_hda_shutup_pins);
923
861static void init_hda_cache(struct hda_cache_rec *cache, 924static void init_hda_cache(struct hda_cache_rec *cache,
862 unsigned int record_size); 925 unsigned int record_size);
863static void free_hda_cache(struct hda_cache_rec *cache); 926static void free_hda_cache(struct hda_cache_rec *cache);
@@ -890,6 +953,7 @@ static void snd_hda_codec_free(struct hda_codec *codec)
890#endif 953#endif
891 list_del(&codec->list); 954 list_del(&codec->list);
892 snd_array_free(&codec->mixers); 955 snd_array_free(&codec->mixers);
956 snd_array_free(&codec->nids);
893 codec->bus->caddr_tbl[codec->addr] = NULL; 957 codec->bus->caddr_tbl[codec->addr] = NULL;
894 if (codec->patch_ops.free) 958 if (codec->patch_ops.free)
895 codec->patch_ops.free(codec); 959 codec->patch_ops.free(codec);
@@ -914,8 +978,9 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
914 * 978 *
915 * Returns 0 if successful, or a negative error code. 979 * Returns 0 if successful, or a negative error code.
916 */ 980 */
917int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, 981int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus,
918 struct hda_codec **codecp) 982 unsigned int codec_addr,
983 struct hda_codec **codecp)
919{ 984{
920 struct hda_codec *codec; 985 struct hda_codec *codec;
921 char component[31]; 986 char component[31];
@@ -944,7 +1009,8 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr
944 mutex_init(&codec->control_mutex); 1009 mutex_init(&codec->control_mutex);
945 init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info)); 1010 init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info));
946 init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head)); 1011 init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head));
947 snd_array_init(&codec->mixers, sizeof(struct snd_kcontrol *), 32); 1012 snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 32);
1013 snd_array_init(&codec->nids, sizeof(struct hda_nid_item), 32);
948 snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16); 1014 snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16);
949 snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16); 1015 snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16);
950 if (codec->bus->modelname) { 1016 if (codec->bus->modelname) {
@@ -1026,6 +1092,15 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr
1026} 1092}
1027EXPORT_SYMBOL_HDA(snd_hda_codec_new); 1093EXPORT_SYMBOL_HDA(snd_hda_codec_new);
1028 1094
1095/**
1096 * snd_hda_codec_configure - (Re-)configure the HD-audio codec
1097 * @codec: the HDA codec
1098 *
1099 * Start parsing of the given codec tree and (re-)initialize the whole
1100 * patch instance.
1101 *
1102 * Returns 0 if successful or a negative error code.
1103 */
1029int snd_hda_codec_configure(struct hda_codec *codec) 1104int snd_hda_codec_configure(struct hda_codec *codec)
1030{ 1105{
1031 int err; 1106 int err;
@@ -1036,11 +1111,6 @@ int snd_hda_codec_configure(struct hda_codec *codec)
1036 if (err < 0) 1111 if (err < 0)
1037 return err; 1112 return err;
1038 } 1113 }
1039 /* audio codec should override the mixer name */
1040 if (codec->afg || !*codec->bus->card->mixername)
1041 snprintf(codec->bus->card->mixername,
1042 sizeof(codec->bus->card->mixername),
1043 "%s %s", codec->vendor_name, codec->chip_name);
1044 1114
1045 if (is_generic_config(codec)) { 1115 if (is_generic_config(codec)) {
1046 err = snd_hda_parse_generic_codec(codec); 1116 err = snd_hda_parse_generic_codec(codec);
@@ -1059,6 +1129,11 @@ int snd_hda_codec_configure(struct hda_codec *codec)
1059 patched: 1129 patched:
1060 if (!err && codec->patch_ops.unsol_event) 1130 if (!err && codec->patch_ops.unsol_event)
1061 err = init_unsol_queue(codec->bus); 1131 err = init_unsol_queue(codec->bus);
1132 /* audio codec should override the mixer name */
1133 if (!err && (codec->afg || !*codec->bus->card->mixername))
1134 snprintf(codec->bus->card->mixername,
1135 sizeof(codec->bus->card->mixername),
1136 "%s %s", codec->vendor_name, codec->chip_name);
1062 return err; 1137 return err;
1063} 1138}
1064EXPORT_SYMBOL_HDA(snd_hda_codec_configure); 1139EXPORT_SYMBOL_HDA(snd_hda_codec_configure);
@@ -1088,6 +1163,11 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid,
1088} 1163}
1089EXPORT_SYMBOL_HDA(snd_hda_codec_setup_stream); 1164EXPORT_SYMBOL_HDA(snd_hda_codec_setup_stream);
1090 1165
1166/**
1167 * snd_hda_codec_cleanup_stream - clean up the codec for closing
1168 * @codec: the CODEC to clean up
1169 * @nid: the NID to clean up
1170 */
1091void snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid) 1171void snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid)
1092{ 1172{
1093 if (!nid) 1173 if (!nid)
@@ -1107,7 +1187,7 @@ EXPORT_SYMBOL_HDA(snd_hda_codec_cleanup_stream);
1107 */ 1187 */
1108 1188
1109/* FIXME: more better hash key? */ 1189/* FIXME: more better hash key? */
1110#define HDA_HASH_KEY(nid,dir,idx) (u32)((nid) + ((idx) << 16) + ((dir) << 24)) 1190#define HDA_HASH_KEY(nid, dir, idx) (u32)((nid) + ((idx) << 16) + ((dir) << 24))
1111#define HDA_HASH_PINCAP_KEY(nid) (u32)((nid) + (0x02 << 24)) 1191#define HDA_HASH_PINCAP_KEY(nid) (u32)((nid) + (0x02 << 24))
1112#define HDA_HASH_PARPCM_KEY(nid) (u32)((nid) + (0x03 << 24)) 1192#define HDA_HASH_PARPCM_KEY(nid) (u32)((nid) + (0x03 << 24))
1113#define HDA_HASH_PARSTR_KEY(nid) (u32)((nid) + (0x04 << 24)) 1193#define HDA_HASH_PARSTR_KEY(nid) (u32)((nid) + (0x04 << 24))
@@ -1163,8 +1243,17 @@ get_alloc_amp_hash(struct hda_codec *codec, u32 key)
1163 return (struct hda_amp_info *)get_alloc_hash(&codec->amp_cache, key); 1243 return (struct hda_amp_info *)get_alloc_hash(&codec->amp_cache, key);
1164} 1244}
1165 1245
1166/* 1246/**
1167 * query AMP capabilities for the given widget and direction 1247 * query_amp_caps - query AMP capabilities
1248 * @codec: the HD-auio codec
1249 * @nid: the NID to query
1250 * @direction: either #HDA_INPUT or #HDA_OUTPUT
1251 *
1252 * Query AMP capabilities for the given widget and direction.
1253 * Returns the obtained capability bits.
1254 *
1255 * When cap bits have been already read, this doesn't read again but
1256 * returns the cached value.
1168 */ 1257 */
1169u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction) 1258u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction)
1170{ 1259{
@@ -1187,6 +1276,19 @@ u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction)
1187} 1276}
1188EXPORT_SYMBOL_HDA(query_amp_caps); 1277EXPORT_SYMBOL_HDA(query_amp_caps);
1189 1278
1279/**
1280 * snd_hda_override_amp_caps - Override the AMP capabilities
1281 * @codec: the CODEC to clean up
1282 * @nid: the NID to clean up
1283 * @direction: either #HDA_INPUT or #HDA_OUTPUT
1284 * @caps: the capability bits to set
1285 *
1286 * Override the cached AMP caps bits value by the given one.
1287 * This function is useful if the driver needs to adjust the AMP ranges,
1288 * e.g. limit to 0dB, etc.
1289 *
1290 * Returns zero if successful or a negative error code.
1291 */
1190int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir, 1292int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
1191 unsigned int caps) 1293 unsigned int caps)
1192{ 1294{
@@ -1222,6 +1324,17 @@ static unsigned int read_pin_cap(struct hda_codec *codec, hda_nid_t nid)
1222 return snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP); 1324 return snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
1223} 1325}
1224 1326
1327/**
1328 * snd_hda_query_pin_caps - Query PIN capabilities
1329 * @codec: the HD-auio codec
1330 * @nid: the NID to query
1331 *
1332 * Query PIN capabilities for the given widget.
1333 * Returns the obtained capability bits.
1334 *
1335 * When cap bits have been already read, this doesn't read again but
1336 * returns the cached value.
1337 */
1225u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid) 1338u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid)
1226{ 1339{
1227 return query_caps_hash(codec, nid, HDA_HASH_PINCAP_KEY(nid), 1340 return query_caps_hash(codec, nid, HDA_HASH_PINCAP_KEY(nid),
@@ -1229,6 +1342,43 @@ u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid)
1229} 1342}
1230EXPORT_SYMBOL_HDA(snd_hda_query_pin_caps); 1343EXPORT_SYMBOL_HDA(snd_hda_query_pin_caps);
1231 1344
1345/**
1346 * snd_hda_pin_sense - execute pin sense measurement
1347 * @codec: the CODEC to sense
1348 * @nid: the pin NID to sense
1349 *
1350 * Execute necessary pin sense measurement and return its Presence Detect,
1351 * Impedance, ELD Valid etc. status bits.
1352 */
1353u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid)
1354{
1355 u32 pincap;
1356
1357 if (!codec->no_trigger_sense) {
1358 pincap = snd_hda_query_pin_caps(codec, nid);
1359 if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */
1360 snd_hda_codec_read(codec, nid, 0,
1361 AC_VERB_SET_PIN_SENSE, 0);
1362 }
1363 return snd_hda_codec_read(codec, nid, 0,
1364 AC_VERB_GET_PIN_SENSE, 0);
1365}
1366EXPORT_SYMBOL_HDA(snd_hda_pin_sense);
1367
1368/**
1369 * snd_hda_jack_detect - query pin Presence Detect status
1370 * @codec: the CODEC to sense
1371 * @nid: the pin NID to sense
1372 *
1373 * Query and return the pin's Presence Detect status.
1374 */
1375int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid)
1376{
1377 u32 sense = snd_hda_pin_sense(codec, nid);
1378 return !!(sense & AC_PINSENSE_PRESENCE);
1379}
1380EXPORT_SYMBOL_HDA(snd_hda_jack_detect);
1381
1232/* 1382/*
1233 * read the current volume to info 1383 * read the current volume to info
1234 * if the cache exists, read the cache value. 1384 * if the cache exists, read the cache value.
@@ -1269,8 +1419,15 @@ static void put_vol_mute(struct hda_codec *codec, struct hda_amp_info *info,
1269 info->vol[ch] = val; 1419 info->vol[ch] = val;
1270} 1420}
1271 1421
1272/* 1422/**
1273 * read AMP value. The volume is between 0 to 0x7f, 0x80 = mute bit. 1423 * snd_hda_codec_amp_read - Read AMP value
1424 * @codec: HD-audio codec
1425 * @nid: NID to read the AMP value
1426 * @ch: channel (left=0 or right=1)
1427 * @direction: #HDA_INPUT or #HDA_OUTPUT
1428 * @index: the index value (only for input direction)
1429 *
1430 * Read AMP value. The volume is between 0 to 0x7f, 0x80 = mute bit.
1274 */ 1431 */
1275int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch, 1432int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch,
1276 int direction, int index) 1433 int direction, int index)
@@ -1283,8 +1440,18 @@ int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch,
1283} 1440}
1284EXPORT_SYMBOL_HDA(snd_hda_codec_amp_read); 1441EXPORT_SYMBOL_HDA(snd_hda_codec_amp_read);
1285 1442
1286/* 1443/**
1287 * update the AMP value, mask = bit mask to set, val = the value 1444 * snd_hda_codec_amp_update - update the AMP value
1445 * @codec: HD-audio codec
1446 * @nid: NID to read the AMP value
1447 * @ch: channel (left=0 or right=1)
1448 * @direction: #HDA_INPUT or #HDA_OUTPUT
1449 * @idx: the index value (only for input direction)
1450 * @mask: bit mask to set
1451 * @val: the bits value to set
1452 *
1453 * Update the AMP value with a bit mask.
1454 * Returns 0 if the value is unchanged, 1 if changed.
1288 */ 1455 */
1289int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, 1456int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch,
1290 int direction, int idx, int mask, int val) 1457 int direction, int idx, int mask, int val)
@@ -1303,8 +1470,17 @@ int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch,
1303} 1470}
1304EXPORT_SYMBOL_HDA(snd_hda_codec_amp_update); 1471EXPORT_SYMBOL_HDA(snd_hda_codec_amp_update);
1305 1472
1306/* 1473/**
1307 * update the AMP stereo with the same mask and value 1474 * snd_hda_codec_amp_stereo - update the AMP stereo values
1475 * @codec: HD-audio codec
1476 * @nid: NID to read the AMP value
1477 * @direction: #HDA_INPUT or #HDA_OUTPUT
1478 * @idx: the index value (only for input direction)
1479 * @mask: bit mask to set
1480 * @val: the bits value to set
1481 *
1482 * Update the AMP values like snd_hda_codec_amp_update(), but for a
1483 * stereo widget with the same mask and value.
1308 */ 1484 */
1309int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid, 1485int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid,
1310 int direction, int idx, int mask, int val) 1486 int direction, int idx, int mask, int val)
@@ -1318,7 +1494,12 @@ int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid,
1318EXPORT_SYMBOL_HDA(snd_hda_codec_amp_stereo); 1494EXPORT_SYMBOL_HDA(snd_hda_codec_amp_stereo);
1319 1495
1320#ifdef SND_HDA_NEEDS_RESUME 1496#ifdef SND_HDA_NEEDS_RESUME
1321/* resume the all amp commands from the cache */ 1497/**
1498 * snd_hda_codec_resume_amp - Resume all AMP commands from the cache
1499 * @codec: HD-audio codec
1500 *
1501 * Resume the all amp commands from the cache.
1502 */
1322void snd_hda_codec_resume_amp(struct hda_codec *codec) 1503void snd_hda_codec_resume_amp(struct hda_codec *codec)
1323{ 1504{
1324 struct hda_amp_info *buffer = codec->amp_cache.buf.list; 1505 struct hda_amp_info *buffer = codec->amp_cache.buf.list;
@@ -1344,7 +1525,12 @@ void snd_hda_codec_resume_amp(struct hda_codec *codec)
1344EXPORT_SYMBOL_HDA(snd_hda_codec_resume_amp); 1525EXPORT_SYMBOL_HDA(snd_hda_codec_resume_amp);
1345#endif /* SND_HDA_NEEDS_RESUME */ 1526#endif /* SND_HDA_NEEDS_RESUME */
1346 1527
1347/* volume */ 1528/**
1529 * snd_hda_mixer_amp_volume_info - Info callback for a standard AMP mixer
1530 *
1531 * The control element is supposed to have the private_value field
1532 * set up via HDA_COMPOSE_AMP_VAL*() or related macros.
1533 */
1348int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, 1534int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol,
1349 struct snd_ctl_elem_info *uinfo) 1535 struct snd_ctl_elem_info *uinfo)
1350{ 1536{
@@ -1400,6 +1586,12 @@ update_amp_value(struct hda_codec *codec, hda_nid_t nid,
1400 HDA_AMP_VOLMASK, val); 1586 HDA_AMP_VOLMASK, val);
1401} 1587}
1402 1588
1589/**
1590 * snd_hda_mixer_amp_volume_get - Get callback for a standard AMP mixer volume
1591 *
1592 * The control element is supposed to have the private_value field
1593 * set up via HDA_COMPOSE_AMP_VAL*() or related macros.
1594 */
1403int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol, 1595int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol,
1404 struct snd_ctl_elem_value *ucontrol) 1596 struct snd_ctl_elem_value *ucontrol)
1405{ 1597{
@@ -1419,6 +1611,12 @@ int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol,
1419} 1611}
1420EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_volume_get); 1612EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_volume_get);
1421 1613
1614/**
1615 * snd_hda_mixer_amp_volume_put - Put callback for a standard AMP mixer volume
1616 *
1617 * The control element is supposed to have the private_value field
1618 * set up via HDA_COMPOSE_AMP_VAL*() or related macros.
1619 */
1422int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol, 1620int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol,
1423 struct snd_ctl_elem_value *ucontrol) 1621 struct snd_ctl_elem_value *ucontrol)
1424{ 1622{
@@ -1443,6 +1641,12 @@ int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol,
1443} 1641}
1444EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_volume_put); 1642EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_volume_put);
1445 1643
1644/**
1645 * snd_hda_mixer_amp_volume_put - TLV callback for a standard AMP mixer volume
1646 *
1647 * The control element is supposed to have the private_value field
1648 * set up via HDA_COMPOSE_AMP_VAL*() or related macros.
1649 */
1446int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag, 1650int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1447 unsigned int size, unsigned int __user *_tlv) 1651 unsigned int size, unsigned int __user *_tlv)
1448{ 1652{
@@ -1472,8 +1676,16 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1472} 1676}
1473EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_tlv); 1677EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_tlv);
1474 1678
1475/* 1679/**
1476 * set (static) TLV for virtual master volume; recalculated as max 0dB 1680 * snd_hda_set_vmaster_tlv - Set TLV for a virtual master control
1681 * @codec: HD-audio codec
1682 * @nid: NID of a reference widget
1683 * @dir: #HDA_INPUT or #HDA_OUTPUT
1684 * @tlv: TLV data to be stored, at least 4 elements
1685 *
1686 * Set (static) TLV data for a virtual master volume using the AMP caps
1687 * obtained from the reference NID.
1688 * The volume range is recalculated as if the max volume is 0dB.
1477 */ 1689 */
1478void snd_hda_set_vmaster_tlv(struct hda_codec *codec, hda_nid_t nid, int dir, 1690void snd_hda_set_vmaster_tlv(struct hda_codec *codec, hda_nid_t nid, int dir,
1479 unsigned int *tlv) 1691 unsigned int *tlv)
@@ -1507,6 +1719,13 @@ _snd_hda_find_mixer_ctl(struct hda_codec *codec,
1507 return snd_ctl_find_id(codec->bus->card, &id); 1719 return snd_ctl_find_id(codec->bus->card, &id);
1508} 1720}
1509 1721
1722/**
1723 * snd_hda_find_mixer_ctl - Find a mixer control element with the given name
1724 * @codec: HD-audio codec
1725 * @name: ctl id name string
1726 *
1727 * Get the control element with the given id string and IFACE_MIXER.
1728 */
1510struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec, 1729struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec,
1511 const char *name) 1730 const char *name)
1512{ 1731{
@@ -1514,31 +1733,97 @@ struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec,
1514} 1733}
1515EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl); 1734EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl);
1516 1735
1517/* Add a control element and assign to the codec */ 1736/**
1518int snd_hda_ctl_add(struct hda_codec *codec, struct snd_kcontrol *kctl) 1737 * snd_hda_ctl_add - Add a control element and assign to the codec
1738 * @codec: HD-audio codec
1739 * @nid: corresponding NID (optional)
1740 * @kctl: the control element to assign
1741 *
1742 * Add the given control element to an array inside the codec instance.
1743 * All control elements belonging to a codec are supposed to be added
1744 * by this function so that a proper clean-up works at the free or
1745 * reconfiguration time.
1746 *
1747 * If non-zero @nid is passed, the NID is assigned to the control element.
1748 * The assignment is shown in the codec proc file.
1749 *
1750 * snd_hda_ctl_add() checks the control subdev id field whether
1751 * #HDA_SUBDEV_NID_FLAG bit is set. If set (and @nid is zero), the lower
1752 * bits value is taken as the NID to assign. The #HDA_NID_ITEM_AMP bit
1753 * specifies if kctl->private_value is a HDA amplifier value.
1754 */
1755int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid,
1756 struct snd_kcontrol *kctl)
1519{ 1757{
1520 int err; 1758 int err;
1521 struct snd_kcontrol **knewp; 1759 unsigned short flags = 0;
1760 struct hda_nid_item *item;
1522 1761
1762 if (kctl->id.subdevice & HDA_SUBDEV_AMP_FLAG) {
1763 flags |= HDA_NID_ITEM_AMP;
1764 if (nid == 0)
1765 nid = get_amp_nid_(kctl->private_value);
1766 }
1767 if ((kctl->id.subdevice & HDA_SUBDEV_NID_FLAG) != 0 && nid == 0)
1768 nid = kctl->id.subdevice & 0xffff;
1769 if (kctl->id.subdevice & (HDA_SUBDEV_NID_FLAG|HDA_SUBDEV_AMP_FLAG))
1770 kctl->id.subdevice = 0;
1523 err = snd_ctl_add(codec->bus->card, kctl); 1771 err = snd_ctl_add(codec->bus->card, kctl);
1524 if (err < 0) 1772 if (err < 0)
1525 return err; 1773 return err;
1526 knewp = snd_array_new(&codec->mixers); 1774 item = snd_array_new(&codec->mixers);
1527 if (!knewp) 1775 if (!item)
1528 return -ENOMEM; 1776 return -ENOMEM;
1529 *knewp = kctl; 1777 item->kctl = kctl;
1778 item->nid = nid;
1779 item->flags = flags;
1530 return 0; 1780 return 0;
1531} 1781}
1532EXPORT_SYMBOL_HDA(snd_hda_ctl_add); 1782EXPORT_SYMBOL_HDA(snd_hda_ctl_add);
1533 1783
1534/* Clear all controls assigned to the given codec */ 1784/**
1785 * snd_hda_add_nid - Assign a NID to a control element
1786 * @codec: HD-audio codec
1787 * @nid: corresponding NID (optional)
1788 * @kctl: the control element to assign
1789 * @index: index to kctl
1790 *
1791 * Add the given control element to an array inside the codec instance.
1792 * This function is used when #snd_hda_ctl_add cannot be used for 1:1
1793 * NID:KCTL mapping - for example "Capture Source" selector.
1794 */
1795int snd_hda_add_nid(struct hda_codec *codec, struct snd_kcontrol *kctl,
1796 unsigned int index, hda_nid_t nid)
1797{
1798 struct hda_nid_item *item;
1799
1800 if (nid > 0) {
1801 item = snd_array_new(&codec->nids);
1802 if (!item)
1803 return -ENOMEM;
1804 item->kctl = kctl;
1805 item->index = index;
1806 item->nid = nid;
1807 return 0;
1808 }
1809 printk(KERN_ERR "hda-codec: no NID for mapping control %s:%d:%d\n",
1810 kctl->id.name, kctl->id.index, index);
1811 return -EINVAL;
1812}
1813EXPORT_SYMBOL_HDA(snd_hda_add_nid);
1814
1815/**
1816 * snd_hda_ctls_clear - Clear all controls assigned to the given codec
1817 * @codec: HD-audio codec
1818 */
1535void snd_hda_ctls_clear(struct hda_codec *codec) 1819void snd_hda_ctls_clear(struct hda_codec *codec)
1536{ 1820{
1537 int i; 1821 int i;
1538 struct snd_kcontrol **kctls = codec->mixers.list; 1822 struct hda_nid_item *items = codec->mixers.list;
1539 for (i = 0; i < codec->mixers.used; i++) 1823 for (i = 0; i < codec->mixers.used; i++)
1540 snd_ctl_remove(codec->bus->card, kctls[i]); 1824 snd_ctl_remove(codec->bus->card, items[i].kctl);
1541 snd_array_free(&codec->mixers); 1825 snd_array_free(&codec->mixers);
1826 snd_array_free(&codec->nids);
1542} 1827}
1543 1828
1544/* pseudo device locking 1829/* pseudo device locking
@@ -1563,6 +1848,16 @@ static void hda_unlock_devices(struct snd_card *card)
1563 spin_unlock(&card->files_lock); 1848 spin_unlock(&card->files_lock);
1564} 1849}
1565 1850
1851/**
1852 * snd_hda_codec_reset - Clear all objects assigned to the codec
1853 * @codec: HD-audio codec
1854 *
1855 * This frees the all PCM and control elements assigned to the codec, and
1856 * clears the caches and restores the pin default configurations.
1857 *
1858 * When a device is being used, it returns -EBSY. If successfully freed,
1859 * returns zero.
1860 */
1566int snd_hda_codec_reset(struct hda_codec *codec) 1861int snd_hda_codec_reset(struct hda_codec *codec)
1567{ 1862{
1568 struct snd_card *card = codec->bus->card; 1863 struct snd_card *card = codec->bus->card;
@@ -1626,7 +1921,22 @@ int snd_hda_codec_reset(struct hda_codec *codec)
1626 return 0; 1921 return 0;
1627} 1922}
1628 1923
1629/* create a virtual master control and add slaves */ 1924/**
1925 * snd_hda_add_vmaster - create a virtual master control and add slaves
1926 * @codec: HD-audio codec
1927 * @name: vmaster control name
1928 * @tlv: TLV data (optional)
1929 * @slaves: slave control names (optional)
1930 *
1931 * Create a virtual master control with the given name. The TLV data
1932 * must be either NULL or a valid data.
1933 *
1934 * @slaves is a NULL-terminated array of strings, each of which is a
1935 * slave control name. All controls with these names are assigned to
1936 * the new virtual master control.
1937 *
1938 * This function returns zero if successful or a negative error code.
1939 */
1630int snd_hda_add_vmaster(struct hda_codec *codec, char *name, 1940int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
1631 unsigned int *tlv, const char **slaves) 1941 unsigned int *tlv, const char **slaves)
1632{ 1942{
@@ -1643,10 +1953,10 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
1643 kctl = snd_ctl_make_virtual_master(name, tlv); 1953 kctl = snd_ctl_make_virtual_master(name, tlv);
1644 if (!kctl) 1954 if (!kctl)
1645 return -ENOMEM; 1955 return -ENOMEM;
1646 err = snd_hda_ctl_add(codec, kctl); 1956 err = snd_hda_ctl_add(codec, 0, kctl);
1647 if (err < 0) 1957 if (err < 0)
1648 return err; 1958 return err;
1649 1959
1650 for (s = slaves; *s; s++) { 1960 for (s = slaves; *s; s++) {
1651 struct snd_kcontrol *sctl; 1961 struct snd_kcontrol *sctl;
1652 int i = 0; 1962 int i = 0;
@@ -1668,7 +1978,12 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
1668} 1978}
1669EXPORT_SYMBOL_HDA(snd_hda_add_vmaster); 1979EXPORT_SYMBOL_HDA(snd_hda_add_vmaster);
1670 1980
1671/* switch */ 1981/**
1982 * snd_hda_mixer_amp_switch_info - Info callback for a standard AMP mixer switch
1983 *
1984 * The control element is supposed to have the private_value field
1985 * set up via HDA_COMPOSE_AMP_VAL*() or related macros.
1986 */
1672int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, 1987int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol,
1673 struct snd_ctl_elem_info *uinfo) 1988 struct snd_ctl_elem_info *uinfo)
1674{ 1989{
@@ -1682,6 +1997,12 @@ int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol,
1682} 1997}
1683EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_info); 1998EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_info);
1684 1999
2000/**
2001 * snd_hda_mixer_amp_switch_get - Get callback for a standard AMP mixer switch
2002 *
2003 * The control element is supposed to have the private_value field
2004 * set up via HDA_COMPOSE_AMP_VAL*() or related macros.
2005 */
1685int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol, 2006int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol,
1686 struct snd_ctl_elem_value *ucontrol) 2007 struct snd_ctl_elem_value *ucontrol)
1687{ 2008{
@@ -1702,6 +2023,12 @@ int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol,
1702} 2023}
1703EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_get); 2024EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_get);
1704 2025
2026/**
2027 * snd_hda_mixer_amp_switch_put - Put callback for a standard AMP mixer switch
2028 *
2029 * The control element is supposed to have the private_value field
2030 * set up via HDA_COMPOSE_AMP_VAL*() or related macros.
2031 */
1705int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, 2032int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol,
1706 struct snd_ctl_elem_value *ucontrol) 2033 struct snd_ctl_elem_value *ucontrol)
1707{ 2034{
@@ -1733,6 +2060,25 @@ int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol,
1733} 2060}
1734EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_put); 2061EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_put);
1735 2062
2063#ifdef CONFIG_SND_HDA_INPUT_BEEP
2064/**
2065 * snd_hda_mixer_amp_switch_put_beep - Put callback for a beep AMP switch
2066 *
2067 * This function calls snd_hda_enable_beep_device(), which behaves differently
2068 * depending on beep_mode option.
2069 */
2070int snd_hda_mixer_amp_switch_put_beep(struct snd_kcontrol *kcontrol,
2071 struct snd_ctl_elem_value *ucontrol)
2072{
2073 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2074 long *valp = ucontrol->value.integer.value;
2075
2076 snd_hda_enable_beep_device(codec, *valp);
2077 return snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
2078}
2079EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_put_beep);
2080#endif /* CONFIG_SND_HDA_INPUT_BEEP */
2081
1736/* 2082/*
1737 * bound volume controls 2083 * bound volume controls
1738 * 2084 *
@@ -1742,6 +2088,12 @@ EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_put);
1742#define AMP_VAL_IDX_SHIFT 19 2088#define AMP_VAL_IDX_SHIFT 19
1743#define AMP_VAL_IDX_MASK (0x0f<<19) 2089#define AMP_VAL_IDX_MASK (0x0f<<19)
1744 2090
2091/**
2092 * snd_hda_mixer_bind_switch_get - Get callback for a bound volume control
2093 *
2094 * The control element is supposed to have the private_value field
2095 * set up via HDA_BIND_MUTE*() macros.
2096 */
1745int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol, 2097int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol,
1746 struct snd_ctl_elem_value *ucontrol) 2098 struct snd_ctl_elem_value *ucontrol)
1747{ 2099{
@@ -1759,6 +2111,12 @@ int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol,
1759} 2111}
1760EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_switch_get); 2112EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_switch_get);
1761 2113
2114/**
2115 * snd_hda_mixer_bind_switch_put - Put callback for a bound volume control
2116 *
2117 * The control element is supposed to have the private_value field
2118 * set up via HDA_BIND_MUTE*() macros.
2119 */
1762int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, 2120int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol,
1763 struct snd_ctl_elem_value *ucontrol) 2121 struct snd_ctl_elem_value *ucontrol)
1764{ 2122{
@@ -1783,8 +2141,11 @@ int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol,
1783} 2141}
1784EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_switch_put); 2142EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_switch_put);
1785 2143
1786/* 2144/**
1787 * generic bound volume/swtich controls 2145 * snd_hda_mixer_bind_ctls_info - Info callback for a generic bound control
2146 *
2147 * The control element is supposed to have the private_value field
2148 * set up via HDA_BIND_VOL() or HDA_BIND_SW() macros.
1788 */ 2149 */
1789int snd_hda_mixer_bind_ctls_info(struct snd_kcontrol *kcontrol, 2150int snd_hda_mixer_bind_ctls_info(struct snd_kcontrol *kcontrol,
1790 struct snd_ctl_elem_info *uinfo) 2151 struct snd_ctl_elem_info *uinfo)
@@ -1803,6 +2164,12 @@ int snd_hda_mixer_bind_ctls_info(struct snd_kcontrol *kcontrol,
1803} 2164}
1804EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_ctls_info); 2165EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_ctls_info);
1805 2166
2167/**
2168 * snd_hda_mixer_bind_ctls_get - Get callback for a generic bound control
2169 *
2170 * The control element is supposed to have the private_value field
2171 * set up via HDA_BIND_VOL() or HDA_BIND_SW() macros.
2172 */
1806int snd_hda_mixer_bind_ctls_get(struct snd_kcontrol *kcontrol, 2173int snd_hda_mixer_bind_ctls_get(struct snd_kcontrol *kcontrol,
1807 struct snd_ctl_elem_value *ucontrol) 2174 struct snd_ctl_elem_value *ucontrol)
1808{ 2175{
@@ -1820,6 +2187,12 @@ int snd_hda_mixer_bind_ctls_get(struct snd_kcontrol *kcontrol,
1820} 2187}
1821EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_ctls_get); 2188EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_ctls_get);
1822 2189
2190/**
2191 * snd_hda_mixer_bind_ctls_put - Put callback for a generic bound control
2192 *
2193 * The control element is supposed to have the private_value field
2194 * set up via HDA_BIND_VOL() or HDA_BIND_SW() macros.
2195 */
1823int snd_hda_mixer_bind_ctls_put(struct snd_kcontrol *kcontrol, 2196int snd_hda_mixer_bind_ctls_put(struct snd_kcontrol *kcontrol,
1824 struct snd_ctl_elem_value *ucontrol) 2197 struct snd_ctl_elem_value *ucontrol)
1825{ 2198{
@@ -1843,6 +2216,12 @@ int snd_hda_mixer_bind_ctls_put(struct snd_kcontrol *kcontrol,
1843} 2216}
1844EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_ctls_put); 2217EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_ctls_put);
1845 2218
2219/**
2220 * snd_hda_mixer_bind_tlv - TLV callback for a generic bound control
2221 *
2222 * The control element is supposed to have the private_value field
2223 * set up via HDA_BIND_VOL() macro.
2224 */
1846int snd_hda_mixer_bind_tlv(struct snd_kcontrol *kcontrol, int op_flag, 2225int snd_hda_mixer_bind_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1847 unsigned int size, unsigned int __user *tlv) 2226 unsigned int size, unsigned int __user *tlv)
1848{ 2227{
@@ -2064,27 +2443,27 @@ static struct snd_kcontrol_new dig_mixes[] = {
2064 { 2443 {
2065 .access = SNDRV_CTL_ELEM_ACCESS_READ, 2444 .access = SNDRV_CTL_ELEM_ACCESS_READ,
2066 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2445 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2067 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK), 2446 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, CON_MASK),
2068 .info = snd_hda_spdif_mask_info, 2447 .info = snd_hda_spdif_mask_info,
2069 .get = snd_hda_spdif_cmask_get, 2448 .get = snd_hda_spdif_cmask_get,
2070 }, 2449 },
2071 { 2450 {
2072 .access = SNDRV_CTL_ELEM_ACCESS_READ, 2451 .access = SNDRV_CTL_ELEM_ACCESS_READ,
2073 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2452 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2074 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK), 2453 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, PRO_MASK),
2075 .info = snd_hda_spdif_mask_info, 2454 .info = snd_hda_spdif_mask_info,
2076 .get = snd_hda_spdif_pmask_get, 2455 .get = snd_hda_spdif_pmask_get,
2077 }, 2456 },
2078 { 2457 {
2079 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2458 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2080 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), 2459 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
2081 .info = snd_hda_spdif_mask_info, 2460 .info = snd_hda_spdif_mask_info,
2082 .get = snd_hda_spdif_default_get, 2461 .get = snd_hda_spdif_default_get,
2083 .put = snd_hda_spdif_default_put, 2462 .put = snd_hda_spdif_default_put,
2084 }, 2463 },
2085 { 2464 {
2086 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2465 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2087 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), 2466 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, SWITCH),
2088 .info = snd_hda_spdif_out_switch_info, 2467 .info = snd_hda_spdif_out_switch_info,
2089 .get = snd_hda_spdif_out_switch_get, 2468 .get = snd_hda_spdif_out_switch_get,
2090 .put = snd_hda_spdif_out_switch_put, 2469 .put = snd_hda_spdif_out_switch_put,
@@ -2126,7 +2505,7 @@ int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid)
2126 return -ENOMEM; 2505 return -ENOMEM;
2127 kctl->id.index = idx; 2506 kctl->id.index = idx;
2128 kctl->private_value = nid; 2507 kctl->private_value = nid;
2129 err = snd_hda_ctl_add(codec, kctl); 2508 err = snd_hda_ctl_add(codec, nid, kctl);
2130 if (err < 0) 2509 if (err < 0)
2131 return err; 2510 return err;
2132 } 2511 }
@@ -2165,14 +2544,19 @@ static struct snd_kcontrol_new spdif_share_sw = {
2165 .put = spdif_share_sw_put, 2544 .put = spdif_share_sw_put,
2166}; 2545};
2167 2546
2547/**
2548 * snd_hda_create_spdif_share_sw - create Default PCM switch
2549 * @codec: the HDA codec
2550 * @mout: multi-out instance
2551 */
2168int snd_hda_create_spdif_share_sw(struct hda_codec *codec, 2552int snd_hda_create_spdif_share_sw(struct hda_codec *codec,
2169 struct hda_multi_out *mout) 2553 struct hda_multi_out *mout)
2170{ 2554{
2171 if (!mout->dig_out_nid) 2555 if (!mout->dig_out_nid)
2172 return 0; 2556 return 0;
2173 /* ATTENTION: here mout is passed as private_data, instead of codec */ 2557 /* ATTENTION: here mout is passed as private_data, instead of codec */
2174 return snd_hda_ctl_add(codec, 2558 return snd_hda_ctl_add(codec, mout->dig_out_nid,
2175 snd_ctl_new1(&spdif_share_sw, mout)); 2559 snd_ctl_new1(&spdif_share_sw, mout));
2176} 2560}
2177EXPORT_SYMBOL_HDA(snd_hda_create_spdif_share_sw); 2561EXPORT_SYMBOL_HDA(snd_hda_create_spdif_share_sw);
2178 2562
@@ -2230,7 +2614,7 @@ static int snd_hda_spdif_in_status_get(struct snd_kcontrol *kcontrol,
2230static struct snd_kcontrol_new dig_in_ctls[] = { 2614static struct snd_kcontrol_new dig_in_ctls[] = {
2231 { 2615 {
2232 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2616 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2233 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 2617 .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, SWITCH),
2234 .info = snd_hda_spdif_in_switch_info, 2618 .info = snd_hda_spdif_in_switch_info,
2235 .get = snd_hda_spdif_in_switch_get, 2619 .get = snd_hda_spdif_in_switch_get,
2236 .put = snd_hda_spdif_in_switch_put, 2620 .put = snd_hda_spdif_in_switch_put,
@@ -2238,7 +2622,7 @@ static struct snd_kcontrol_new dig_in_ctls[] = {
2238 { 2622 {
2239 .access = SNDRV_CTL_ELEM_ACCESS_READ, 2623 .access = SNDRV_CTL_ELEM_ACCESS_READ,
2240 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2624 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2241 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,DEFAULT), 2625 .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, DEFAULT),
2242 .info = snd_hda_spdif_mask_info, 2626 .info = snd_hda_spdif_mask_info,
2243 .get = snd_hda_spdif_in_status_get, 2627 .get = snd_hda_spdif_in_status_get,
2244 }, 2628 },
@@ -2276,7 +2660,7 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid)
2276 if (!kctl) 2660 if (!kctl)
2277 return -ENOMEM; 2661 return -ENOMEM;
2278 kctl->private_value = nid; 2662 kctl->private_value = nid;
2279 err = snd_hda_ctl_add(codec, kctl); 2663 err = snd_hda_ctl_add(codec, nid, kctl);
2280 if (err < 0) 2664 if (err < 0)
2281 return err; 2665 return err;
2282 } 2666 }
@@ -2332,7 +2716,12 @@ int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid,
2332} 2716}
2333EXPORT_SYMBOL_HDA(snd_hda_codec_write_cache); 2717EXPORT_SYMBOL_HDA(snd_hda_codec_write_cache);
2334 2718
2335/* resume the all commands from the cache */ 2719/**
2720 * snd_hda_codec_resume_cache - Resume the all commands from the cache
2721 * @codec: HD-audio codec
2722 *
2723 * Execute all verbs recorded in the command caches to resume.
2724 */
2336void snd_hda_codec_resume_cache(struct hda_codec *codec) 2725void snd_hda_codec_resume_cache(struct hda_codec *codec)
2337{ 2726{
2338 struct hda_cache_head *buffer = codec->cmd_cache.buf.list; 2727 struct hda_cache_head *buffer = codec->cmd_cache.buf.list;
@@ -2382,7 +2771,8 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
2382 snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE, 2771 snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE,
2383 power_state); 2772 power_state);
2384 /* partial workaround for "azx_get_response timeout" */ 2773 /* partial workaround for "azx_get_response timeout" */
2385 if (power_state == AC_PWRST_D0) 2774 if (power_state == AC_PWRST_D0 &&
2775 (codec->vendor_id & 0xffff0000) == 0x14f10000)
2386 msleep(10); 2776 msleep(10);
2387 2777
2388 nid = codec->start_nid; 2778 nid = codec->start_nid;
@@ -2416,7 +2806,6 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
2416 if (power_state == AC_PWRST_D0) { 2806 if (power_state == AC_PWRST_D0) {
2417 unsigned long end_time; 2807 unsigned long end_time;
2418 int state; 2808 int state;
2419 msleep(10);
2420 /* wait until the codec reachs to D0 */ 2809 /* wait until the codec reachs to D0 */
2421 end_time = jiffies + msecs_to_jiffies(500); 2810 end_time = jiffies + msecs_to_jiffies(500);
2422 do { 2811 do {
@@ -2452,9 +2841,11 @@ static void hda_call_codec_suspend(struct hda_codec *codec)
2452 codec->afg ? codec->afg : codec->mfg, 2841 codec->afg ? codec->afg : codec->mfg,
2453 AC_PWRST_D3); 2842 AC_PWRST_D3);
2454#ifdef CONFIG_SND_HDA_POWER_SAVE 2843#ifdef CONFIG_SND_HDA_POWER_SAVE
2844 snd_hda_update_power_acct(codec);
2455 cancel_delayed_work(&codec->power_work); 2845 cancel_delayed_work(&codec->power_work);
2456 codec->power_on = 0; 2846 codec->power_on = 0;
2457 codec->power_transition = 0; 2847 codec->power_transition = 0;
2848 codec->power_jiffies = jiffies;
2458#endif 2849#endif
2459} 2850}
2460 2851
@@ -2495,8 +2886,8 @@ int /*__devinit*/ snd_hda_build_controls(struct hda_bus *bus)
2495 list_for_each_entry(codec, &bus->codec_list, list) { 2886 list_for_each_entry(codec, &bus->codec_list, list) {
2496 int err = snd_hda_codec_build_controls(codec); 2887 int err = snd_hda_codec_build_controls(codec);
2497 if (err < 0) { 2888 if (err < 0) {
2498 printk(KERN_ERR "hda_codec: cannot build controls" 2889 printk(KERN_ERR "hda_codec: cannot build controls "
2499 "for #%d (error %d)\n", codec->addr, err); 2890 "for #%d (error %d)\n", codec->addr, err);
2500 err = snd_hda_codec_reset(codec); 2891 err = snd_hda_codec_reset(codec);
2501 if (err < 0) { 2892 if (err < 0) {
2502 printk(KERN_ERR 2893 printk(KERN_ERR
@@ -2592,8 +2983,12 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate,
2592 val |= channels - 1; 2983 val |= channels - 1;
2593 2984
2594 switch (snd_pcm_format_width(format)) { 2985 switch (snd_pcm_format_width(format)) {
2595 case 8: val |= 0x00; break; 2986 case 8:
2596 case 16: val |= 0x10; break; 2987 val |= 0x00;
2988 break;
2989 case 16:
2990 val |= 0x10;
2991 break;
2597 case 20: 2992 case 20:
2598 case 24: 2993 case 24:
2599 case 32: 2994 case 32:
@@ -2756,8 +3151,12 @@ static int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
2756} 3151}
2757 3152
2758/** 3153/**
2759 * snd_hda_is_supported_format - check whether the given node supports 3154 * snd_hda_is_supported_format - Check the validity of the format
2760 * the format val 3155 * @codec: HD-audio codec
3156 * @nid: NID to check
3157 * @format: the HD-audio format value to check
3158 *
3159 * Check whether the given node supports the format value.
2761 * 3160 *
2762 * Returns 1 if supported, 0 if not. 3161 * Returns 1 if supported, 0 if not.
2763 */ 3162 */
@@ -2877,51 +3276,39 @@ static int set_pcm_default_values(struct hda_codec *codec,
2877 return 0; 3276 return 0;
2878} 3277}
2879 3278
3279/* global */
3280const char *snd_hda_pcm_type_name[HDA_PCM_NTYPES] = {
3281 "Audio", "SPDIF", "HDMI", "Modem"
3282};
3283
2880/* 3284/*
2881 * get the empty PCM device number to assign 3285 * get the empty PCM device number to assign
3286 *
3287 * note the max device number is limited by HDA_MAX_PCMS, currently 10
2882 */ 3288 */
2883static int get_empty_pcm_device(struct hda_bus *bus, int type) 3289static int get_empty_pcm_device(struct hda_bus *bus, int type)
2884{ 3290{
2885 static const char *dev_name[HDA_PCM_NTYPES] = { 3291 /* audio device indices; not linear to keep compatibility */
2886 "Audio", "SPDIF", "HDMI", "Modem" 3292 static int audio_idx[HDA_PCM_NTYPES][5] = {
3293 [HDA_PCM_TYPE_AUDIO] = { 0, 2, 4, 5, -1 },
3294 [HDA_PCM_TYPE_SPDIF] = { 1, -1 },
3295 [HDA_PCM_TYPE_HDMI] = { 3, 7, 8, 9, -1 },
3296 [HDA_PCM_TYPE_MODEM] = { 6, -1 },
2887 }; 3297 };
2888 /* starting device index for each PCM type */ 3298 int i;
2889 static int dev_idx[HDA_PCM_NTYPES] = { 3299
2890 [HDA_PCM_TYPE_AUDIO] = 0, 3300 if (type >= HDA_PCM_NTYPES) {
2891 [HDA_PCM_TYPE_SPDIF] = 1,
2892 [HDA_PCM_TYPE_HDMI] = 3,
2893 [HDA_PCM_TYPE_MODEM] = 6
2894 };
2895 /* normal audio device indices; not linear to keep compatibility */
2896 static int audio_idx[4] = { 0, 2, 4, 5 };
2897 int i, dev;
2898
2899 switch (type) {
2900 case HDA_PCM_TYPE_AUDIO:
2901 for (i = 0; i < ARRAY_SIZE(audio_idx); i++) {
2902 dev = audio_idx[i];
2903 if (!test_bit(dev, bus->pcm_dev_bits))
2904 goto ok;
2905 }
2906 snd_printk(KERN_WARNING "Too many audio devices\n");
2907 return -EAGAIN;
2908 case HDA_PCM_TYPE_SPDIF:
2909 case HDA_PCM_TYPE_HDMI:
2910 case HDA_PCM_TYPE_MODEM:
2911 dev = dev_idx[type];
2912 if (test_bit(dev, bus->pcm_dev_bits)) {
2913 snd_printk(KERN_WARNING "%s already defined\n",
2914 dev_name[type]);
2915 return -EAGAIN;
2916 }
2917 break;
2918 default:
2919 snd_printk(KERN_WARNING "Invalid PCM type %d\n", type); 3301 snd_printk(KERN_WARNING "Invalid PCM type %d\n", type);
2920 return -EINVAL; 3302 return -EINVAL;
2921 } 3303 }
2922 ok: 3304
2923 set_bit(dev, bus->pcm_dev_bits); 3305 for (i = 0; audio_idx[type][i] >= 0 ; i++)
2924 return dev; 3306 if (!test_and_set_bit(audio_idx[type][i], bus->pcm_dev_bits))
3307 return audio_idx[type][i];
3308
3309 snd_printk(KERN_WARNING "Too many %s devices\n",
3310 snd_hda_pcm_type_name[type]);
3311 return -EAGAIN;
2925} 3312}
2926 3313
2927/* 3314/*
@@ -2958,7 +3345,7 @@ int snd_hda_codec_build_pcms(struct hda_codec *codec)
2958 err = codec->patch_ops.build_pcms(codec); 3345 err = codec->patch_ops.build_pcms(codec);
2959 if (err < 0) { 3346 if (err < 0) {
2960 printk(KERN_ERR "hda_codec: cannot build PCMs" 3347 printk(KERN_ERR "hda_codec: cannot build PCMs"
2961 "for #%d (error %d)\n", codec->addr, err); 3348 "for #%d (error %d)\n", codec->addr, err);
2962 err = snd_hda_codec_reset(codec); 3349 err = snd_hda_codec_reset(codec);
2963 if (err < 0) { 3350 if (err < 0) {
2964 printk(KERN_ERR 3351 printk(KERN_ERR
@@ -3088,8 +3475,8 @@ EXPORT_SYMBOL_HDA(snd_hda_check_board_config);
3088 3475
3089/** 3476/**
3090 * snd_hda_check_board_codec_sid_config - compare the current codec 3477 * snd_hda_check_board_codec_sid_config - compare the current codec
3091 subsystem ID with the 3478 subsystem ID with the
3092 config table 3479 config table
3093 3480
3094 This is important for Gateway notebooks with SB450 HDA Audio 3481 This is important for Gateway notebooks with SB450 HDA Audio
3095 where the vendor ID of the PCI device is: 3482 where the vendor ID of the PCI device is:
@@ -3159,14 +3546,16 @@ EXPORT_SYMBOL_HDA(snd_hda_check_board_codec_sid_config);
3159 */ 3546 */
3160int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew) 3547int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew)
3161{ 3548{
3162 int err; 3549 int err;
3163 3550
3164 for (; knew->name; knew++) { 3551 for (; knew->name; knew++) {
3165 struct snd_kcontrol *kctl; 3552 struct snd_kcontrol *kctl;
3553 if (knew->iface == -1) /* skip this codec private value */
3554 continue;
3166 kctl = snd_ctl_new1(knew, codec); 3555 kctl = snd_ctl_new1(knew, codec);
3167 if (!kctl) 3556 if (!kctl)
3168 return -ENOMEM; 3557 return -ENOMEM;
3169 err = snd_hda_ctl_add(codec, kctl); 3558 err = snd_hda_ctl_add(codec, 0, kctl);
3170 if (err < 0) { 3559 if (err < 0) {
3171 if (!codec->addr) 3560 if (!codec->addr)
3172 return err; 3561 return err;
@@ -3174,7 +3563,7 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew)
3174 if (!kctl) 3563 if (!kctl)
3175 return -ENOMEM; 3564 return -ENOMEM;
3176 kctl->id.device = codec->addr; 3565 kctl->id.device = codec->addr;
3177 err = snd_hda_ctl_add(codec, kctl); 3566 err = snd_hda_ctl_add(codec, 0, kctl);
3178 if (err < 0) 3567 if (err < 0)
3179 return err; 3568 return err;
3180 } 3569 }
@@ -3207,8 +3596,27 @@ static void hda_keep_power_on(struct hda_codec *codec)
3207{ 3596{
3208 codec->power_count++; 3597 codec->power_count++;
3209 codec->power_on = 1; 3598 codec->power_on = 1;
3599 codec->power_jiffies = jiffies;
3600}
3601
3602/* update the power on/off account with the current jiffies */
3603void snd_hda_update_power_acct(struct hda_codec *codec)
3604{
3605 unsigned long delta = jiffies - codec->power_jiffies;
3606 if (codec->power_on)
3607 codec->power_on_acct += delta;
3608 else
3609 codec->power_off_acct += delta;
3610 codec->power_jiffies += delta;
3210} 3611}
3211 3612
3613/**
3614 * snd_hda_power_up - Power-up the codec
3615 * @codec: HD-audio codec
3616 *
3617 * Increment the power-up counter and power up the hardware really when
3618 * not turned on yet.
3619 */
3212void snd_hda_power_up(struct hda_codec *codec) 3620void snd_hda_power_up(struct hda_codec *codec)
3213{ 3621{
3214 struct hda_bus *bus = codec->bus; 3622 struct hda_bus *bus = codec->bus;
@@ -3217,7 +3625,9 @@ void snd_hda_power_up(struct hda_codec *codec)
3217 if (codec->power_on || codec->power_transition) 3625 if (codec->power_on || codec->power_transition)
3218 return; 3626 return;
3219 3627
3628 snd_hda_update_power_acct(codec);
3220 codec->power_on = 1; 3629 codec->power_on = 1;
3630 codec->power_jiffies = jiffies;
3221 if (bus->ops.pm_notify) 3631 if (bus->ops.pm_notify)
3222 bus->ops.pm_notify(bus); 3632 bus->ops.pm_notify(bus);
3223 hda_call_codec_resume(codec); 3633 hda_call_codec_resume(codec);
@@ -3229,9 +3639,13 @@ EXPORT_SYMBOL_HDA(snd_hda_power_up);
3229#define power_save(codec) \ 3639#define power_save(codec) \
3230 ((codec)->bus->power_save ? *(codec)->bus->power_save : 0) 3640 ((codec)->bus->power_save ? *(codec)->bus->power_save : 0)
3231 3641
3232#define power_save(codec) \ 3642/**
3233 ((codec)->bus->power_save ? *(codec)->bus->power_save : 0) 3643 * snd_hda_power_down - Power-down the codec
3234 3644 * @codec: HD-audio codec
3645 *
3646 * Decrement the power-up counter and schedules the power-off work if
3647 * the counter rearches to zero.
3648 */
3235void snd_hda_power_down(struct hda_codec *codec) 3649void snd_hda_power_down(struct hda_codec *codec)
3236{ 3650{
3237 --codec->power_count; 3651 --codec->power_count;
@@ -3245,6 +3659,19 @@ void snd_hda_power_down(struct hda_codec *codec)
3245} 3659}
3246EXPORT_SYMBOL_HDA(snd_hda_power_down); 3660EXPORT_SYMBOL_HDA(snd_hda_power_down);
3247 3661
3662/**
3663 * snd_hda_check_amp_list_power - Check the amp list and update the power
3664 * @codec: HD-audio codec
3665 * @check: the object containing an AMP list and the status
3666 * @nid: NID to check / update
3667 *
3668 * Check whether the given NID is in the amp list. If it's in the list,
3669 * check the current AMP status, and update the the power-status according
3670 * to the mute status.
3671 *
3672 * This function is supposed to be set or called from the check_power_status
3673 * patch ops.
3674 */
3248int snd_hda_check_amp_list_power(struct hda_codec *codec, 3675int snd_hda_check_amp_list_power(struct hda_codec *codec,
3249 struct hda_loopback_check *check, 3676 struct hda_loopback_check *check,
3250 hda_nid_t nid) 3677 hda_nid_t nid)
@@ -3286,6 +3713,10 @@ EXPORT_SYMBOL_HDA(snd_hda_check_amp_list_power);
3286/* 3713/*
3287 * Channel mode helper 3714 * Channel mode helper
3288 */ 3715 */
3716
3717/**
3718 * snd_hda_ch_mode_info - Info callback helper for the channel mode enum
3719 */
3289int snd_hda_ch_mode_info(struct hda_codec *codec, 3720int snd_hda_ch_mode_info(struct hda_codec *codec,
3290 struct snd_ctl_elem_info *uinfo, 3721 struct snd_ctl_elem_info *uinfo,
3291 const struct hda_channel_mode *chmode, 3722 const struct hda_channel_mode *chmode,
@@ -3302,6 +3733,9 @@ int snd_hda_ch_mode_info(struct hda_codec *codec,
3302} 3733}
3303EXPORT_SYMBOL_HDA(snd_hda_ch_mode_info); 3734EXPORT_SYMBOL_HDA(snd_hda_ch_mode_info);
3304 3735
3736/**
3737 * snd_hda_ch_mode_get - Get callback helper for the channel mode enum
3738 */
3305int snd_hda_ch_mode_get(struct hda_codec *codec, 3739int snd_hda_ch_mode_get(struct hda_codec *codec,
3306 struct snd_ctl_elem_value *ucontrol, 3740 struct snd_ctl_elem_value *ucontrol,
3307 const struct hda_channel_mode *chmode, 3741 const struct hda_channel_mode *chmode,
@@ -3320,6 +3754,9 @@ int snd_hda_ch_mode_get(struct hda_codec *codec,
3320} 3754}
3321EXPORT_SYMBOL_HDA(snd_hda_ch_mode_get); 3755EXPORT_SYMBOL_HDA(snd_hda_ch_mode_get);
3322 3756
3757/**
3758 * snd_hda_ch_mode_put - Put callback helper for the channel mode enum
3759 */
3323int snd_hda_ch_mode_put(struct hda_codec *codec, 3760int snd_hda_ch_mode_put(struct hda_codec *codec,
3324 struct snd_ctl_elem_value *ucontrol, 3761 struct snd_ctl_elem_value *ucontrol,
3325 const struct hda_channel_mode *chmode, 3762 const struct hda_channel_mode *chmode,
@@ -3344,6 +3781,10 @@ EXPORT_SYMBOL_HDA(snd_hda_ch_mode_put);
3344/* 3781/*
3345 * input MUX helper 3782 * input MUX helper
3346 */ 3783 */
3784
3785/**
3786 * snd_hda_input_mux_info_info - Info callback helper for the input-mux enum
3787 */
3347int snd_hda_input_mux_info(const struct hda_input_mux *imux, 3788int snd_hda_input_mux_info(const struct hda_input_mux *imux,
3348 struct snd_ctl_elem_info *uinfo) 3789 struct snd_ctl_elem_info *uinfo)
3349{ 3790{
@@ -3362,6 +3803,9 @@ int snd_hda_input_mux_info(const struct hda_input_mux *imux,
3362} 3803}
3363EXPORT_SYMBOL_HDA(snd_hda_input_mux_info); 3804EXPORT_SYMBOL_HDA(snd_hda_input_mux_info);
3364 3805
3806/**
3807 * snd_hda_input_mux_info_put - Put callback helper for the input-mux enum
3808 */
3365int snd_hda_input_mux_put(struct hda_codec *codec, 3809int snd_hda_input_mux_put(struct hda_codec *codec,
3366 const struct hda_input_mux *imux, 3810 const struct hda_input_mux *imux,
3367 struct snd_ctl_elem_value *ucontrol, 3811 struct snd_ctl_elem_value *ucontrol,
@@ -3395,7 +3839,7 @@ static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid,
3395{ 3839{
3396 /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */ 3840 /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
3397 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) 3841 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE))
3398 set_dig_out_convert(codec, nid, 3842 set_dig_out_convert(codec, nid,
3399 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff, 3843 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff,
3400 -1); 3844 -1);
3401 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format); 3845 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
@@ -3421,8 +3865,29 @@ static void cleanup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid)
3421 } 3865 }
3422} 3866}
3423 3867
3424/* 3868/**
3425 * open the digital out in the exclusive mode 3869 * snd_hda_bus_reboot_notify - call the reboot notifier of each codec
3870 * @bus: HD-audio bus
3871 */
3872void snd_hda_bus_reboot_notify(struct hda_bus *bus)
3873{
3874 struct hda_codec *codec;
3875
3876 if (!bus)
3877 return;
3878 list_for_each_entry(codec, &bus->codec_list, list) {
3879#ifdef CONFIG_SND_HDA_POWER_SAVE
3880 if (!codec->power_on)
3881 continue;
3882#endif
3883 if (codec->patch_ops.reboot_notify)
3884 codec->patch_ops.reboot_notify(codec);
3885 }
3886}
3887EXPORT_SYMBOL_HDA(snd_hda_bus_reboot_notify);
3888
3889/**
3890 * snd_hda_multi_out_dig_open - open the digital out in the exclusive mode
3426 */ 3891 */
3427int snd_hda_multi_out_dig_open(struct hda_codec *codec, 3892int snd_hda_multi_out_dig_open(struct hda_codec *codec,
3428 struct hda_multi_out *mout) 3893 struct hda_multi_out *mout)
@@ -3437,6 +3902,9 @@ int snd_hda_multi_out_dig_open(struct hda_codec *codec,
3437} 3902}
3438EXPORT_SYMBOL_HDA(snd_hda_multi_out_dig_open); 3903EXPORT_SYMBOL_HDA(snd_hda_multi_out_dig_open);
3439 3904
3905/**
3906 * snd_hda_multi_out_dig_prepare - prepare the digital out stream
3907 */
3440int snd_hda_multi_out_dig_prepare(struct hda_codec *codec, 3908int snd_hda_multi_out_dig_prepare(struct hda_codec *codec,
3441 struct hda_multi_out *mout, 3909 struct hda_multi_out *mout,
3442 unsigned int stream_tag, 3910 unsigned int stream_tag,
@@ -3450,6 +3918,9 @@ int snd_hda_multi_out_dig_prepare(struct hda_codec *codec,
3450} 3918}
3451EXPORT_SYMBOL_HDA(snd_hda_multi_out_dig_prepare); 3919EXPORT_SYMBOL_HDA(snd_hda_multi_out_dig_prepare);
3452 3920
3921/**
3922 * snd_hda_multi_out_dig_cleanup - clean-up the digital out stream
3923 */
3453int snd_hda_multi_out_dig_cleanup(struct hda_codec *codec, 3924int snd_hda_multi_out_dig_cleanup(struct hda_codec *codec,
3454 struct hda_multi_out *mout) 3925 struct hda_multi_out *mout)
3455{ 3926{
@@ -3460,8 +3931,8 @@ int snd_hda_multi_out_dig_cleanup(struct hda_codec *codec,
3460} 3931}
3461EXPORT_SYMBOL_HDA(snd_hda_multi_out_dig_cleanup); 3932EXPORT_SYMBOL_HDA(snd_hda_multi_out_dig_cleanup);
3462 3933
3463/* 3934/**
3464 * release the digital out 3935 * snd_hda_multi_out_dig_close - release the digital out stream
3465 */ 3936 */
3466int snd_hda_multi_out_dig_close(struct hda_codec *codec, 3937int snd_hda_multi_out_dig_close(struct hda_codec *codec,
3467 struct hda_multi_out *mout) 3938 struct hda_multi_out *mout)
@@ -3473,8 +3944,12 @@ int snd_hda_multi_out_dig_close(struct hda_codec *codec,
3473} 3944}
3474EXPORT_SYMBOL_HDA(snd_hda_multi_out_dig_close); 3945EXPORT_SYMBOL_HDA(snd_hda_multi_out_dig_close);
3475 3946
3476/* 3947/**
3477 * set up more restrictions for analog out 3948 * snd_hda_multi_out_analog_open - open analog outputs
3949 *
3950 * Open analog outputs and set up the hw-constraints.
3951 * If the digital outputs can be opened as slave, open the digital
3952 * outputs, too.
3478 */ 3953 */
3479int snd_hda_multi_out_analog_open(struct hda_codec *codec, 3954int snd_hda_multi_out_analog_open(struct hda_codec *codec,
3480 struct hda_multi_out *mout, 3955 struct hda_multi_out *mout,
@@ -3519,9 +3994,11 @@ int snd_hda_multi_out_analog_open(struct hda_codec *codec,
3519} 3994}
3520EXPORT_SYMBOL_HDA(snd_hda_multi_out_analog_open); 3995EXPORT_SYMBOL_HDA(snd_hda_multi_out_analog_open);
3521 3996
3522/* 3997/**
3523 * set up the i/o for analog out 3998 * snd_hda_multi_out_analog_prepare - Preapre the analog outputs.
3524 * when the digital out is available, copy the front out to digital out, too. 3999 *
4000 * Set up the i/o for analog out.
4001 * When the digital out is available, copy the front out to digital out, too.
3525 */ 4002 */
3526int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, 4003int snd_hda_multi_out_analog_prepare(struct hda_codec *codec,
3527 struct hda_multi_out *mout, 4004 struct hda_multi_out *mout,
@@ -3578,8 +4055,8 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec,
3578} 4055}
3579EXPORT_SYMBOL_HDA(snd_hda_multi_out_analog_prepare); 4056EXPORT_SYMBOL_HDA(snd_hda_multi_out_analog_prepare);
3580 4057
3581/* 4058/**
3582 * clean up the setting for analog out 4059 * snd_hda_multi_out_analog_cleanup - clean up the setting for analog out
3583 */ 4060 */
3584int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, 4061int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec,
3585 struct hda_multi_out *mout) 4062 struct hda_multi_out *mout)
@@ -3621,13 +4098,13 @@ static int is_in_nid_list(hda_nid_t nid, hda_nid_t *list)
3621/* 4098/*
3622 * Sort an associated group of pins according to their sequence numbers. 4099 * Sort an associated group of pins according to their sequence numbers.
3623 */ 4100 */
3624static void sort_pins_by_sequence(hda_nid_t * pins, short * sequences, 4101static void sort_pins_by_sequence(hda_nid_t *pins, short *sequences,
3625 int num_pins) 4102 int num_pins)
3626{ 4103{
3627 int i, j; 4104 int i, j;
3628 short seq; 4105 short seq;
3629 hda_nid_t nid; 4106 hda_nid_t nid;
3630 4107
3631 for (i = 0; i < num_pins; i++) { 4108 for (i = 0; i < num_pins; i++) {
3632 for (j = i + 1; j < num_pins; j++) { 4109 for (j = i + 1; j < num_pins; j++) {
3633 if (sequences[i] > sequences[j]) { 4110 if (sequences[i] > sequences[j]) {
@@ -3655,7 +4132,7 @@ static void sort_pins_by_sequence(hda_nid_t * pins, short * sequences,
3655 * is detected, one of speaker of HP pins is assigned as the primary 4132 * is detected, one of speaker of HP pins is assigned as the primary
3656 * output, i.e. to line_out_pins[0]. So, line_outs is always positive 4133 * output, i.e. to line_out_pins[0]. So, line_outs is always positive
3657 * if any analog output exists. 4134 * if any analog output exists.
3658 * 4135 *
3659 * The analog input pins are assigned to input_pins array. 4136 * The analog input pins are assigned to input_pins array.
3660 * The digital input/output pins are assigned to dig_in_pin and dig_out_pin, 4137 * The digital input/output pins are assigned to dig_in_pin and dig_out_pin,
3661 * respectively. 4138 * respectively.
@@ -3718,9 +4195,9 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
3718 case AC_JACK_SPEAKER: 4195 case AC_JACK_SPEAKER:
3719 seq = get_defcfg_sequence(def_conf); 4196 seq = get_defcfg_sequence(def_conf);
3720 assoc = get_defcfg_association(def_conf); 4197 assoc = get_defcfg_association(def_conf);
3721 if (! assoc) 4198 if (!assoc)
3722 continue; 4199 continue;
3723 if (! assoc_speaker) 4200 if (!assoc_speaker)
3724 assoc_speaker = assoc; 4201 assoc_speaker = assoc;
3725 else if (assoc_speaker != assoc) 4202 else if (assoc_speaker != assoc)
3726 continue; 4203 continue;
@@ -3818,7 +4295,7 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
3818 cfg->speaker_outs); 4295 cfg->speaker_outs);
3819 sort_pins_by_sequence(cfg->hp_pins, sequences_hp, 4296 sort_pins_by_sequence(cfg->hp_pins, sequences_hp,
3820 cfg->hp_outs); 4297 cfg->hp_outs);
3821 4298
3822 /* if we have only one mic, make it AUTO_PIN_MIC */ 4299 /* if we have only one mic, make it AUTO_PIN_MIC */
3823 if (!cfg->input_pins[AUTO_PIN_MIC] && 4300 if (!cfg->input_pins[AUTO_PIN_MIC] &&
3824 cfg->input_pins[AUTO_PIN_FRONT_MIC]) { 4301 cfg->input_pins[AUTO_PIN_FRONT_MIC]) {
@@ -3965,8 +4442,14 @@ EXPORT_SYMBOL_HDA(snd_hda_resume);
3965 * generic arrays 4442 * generic arrays
3966 */ 4443 */
3967 4444
3968/* get a new element from the given array 4445/**
3969 * if it exceeds the pre-allocated array size, re-allocate the array 4446 * snd_array_new - get a new element from the given array
4447 * @array: the array object
4448 *
4449 * Get a new element from the given array. If it exceeds the
4450 * pre-allocated array size, re-allocate the array.
4451 *
4452 * Returns NULL if allocation failed.
3970 */ 4453 */
3971void *snd_array_new(struct snd_array *array) 4454void *snd_array_new(struct snd_array *array)
3972{ 4455{
@@ -3990,7 +4473,10 @@ void *snd_array_new(struct snd_array *array)
3990} 4473}
3991EXPORT_SYMBOL_HDA(snd_array_new); 4474EXPORT_SYMBOL_HDA(snd_array_new);
3992 4475
3993/* free the given array elements */ 4476/**
4477 * snd_array_free - free the given array elements
4478 * @array: the array object
4479 */
3994void snd_array_free(struct snd_array *array) 4480void snd_array_free(struct snd_array *array)
3995{ 4481{
3996 kfree(array->list); 4482 kfree(array->list);
@@ -4000,7 +4486,12 @@ void snd_array_free(struct snd_array *array)
4000} 4486}
4001EXPORT_SYMBOL_HDA(snd_array_free); 4487EXPORT_SYMBOL_HDA(snd_array_free);
4002 4488
4003/* 4489/**
4490 * snd_print_pcm_rates - Print the supported PCM rates to the string buffer
4491 * @pcm: PCM caps bits
4492 * @buf: the string buffer to write
4493 * @buflen: the max buffer length
4494 *
4004 * used by hda_proc.c and hda_eld.c 4495 * used by hda_proc.c and hda_eld.c
4005 */ 4496 */
4006void snd_print_pcm_rates(int pcm, char *buf, int buflen) 4497void snd_print_pcm_rates(int pcm, char *buf, int buflen)
@@ -4019,6 +4510,14 @@ void snd_print_pcm_rates(int pcm, char *buf, int buflen)
4019} 4510}
4020EXPORT_SYMBOL_HDA(snd_print_pcm_rates); 4511EXPORT_SYMBOL_HDA(snd_print_pcm_rates);
4021 4512
4513/**
4514 * snd_print_pcm_bits - Print the supported PCM fmt bits to the string buffer
4515 * @pcm: PCM caps bits
4516 * @buf: the string buffer to write
4517 * @buflen: the max buffer length
4518 *
4519 * used by hda_proc.c and hda_eld.c
4520 */
4022void snd_print_pcm_bits(int pcm, char *buf, int buflen) 4521void snd_print_pcm_bits(int pcm, char *buf, int buflen)
4023{ 4522{
4024 static unsigned int bits[] = { 8, 16, 20, 24, 32 }; 4523 static unsigned int bits[] = { 8, 16, 20, 24, 32 };
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 99552fb5f756..b75da47571e6 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -255,9 +255,13 @@ enum {
255 * in HD-audio specification 255 * in HD-audio specification
256 */ 256 */
257#define AC_PINCAP_HDMI (1<<7) /* HDMI pin */ 257#define AC_PINCAP_HDMI (1<<7) /* HDMI pin */
258#define AC_PINCAP_DP (1<<24) /* DisplayPort pin, can
259 * coexist with AC_PINCAP_HDMI
260 */
258#define AC_PINCAP_VREF (0x37<<8) 261#define AC_PINCAP_VREF (0x37<<8)
259#define AC_PINCAP_VREF_SHIFT 8 262#define AC_PINCAP_VREF_SHIFT 8
260#define AC_PINCAP_EAPD (1<<16) /* EAPD capable */ 263#define AC_PINCAP_EAPD (1<<16) /* EAPD capable */
264#define AC_PINCAP_HBR (1<<27) /* High Bit Rate */
261/* Vref status (used in pin cap) */ 265/* Vref status (used in pin cap) */
262#define AC_PINCAP_VREF_HIZ (1<<0) /* Hi-Z */ 266#define AC_PINCAP_VREF_HIZ (1<<0) /* Hi-Z */
263#define AC_PINCAP_VREF_50 (1<<1) /* 50% */ 267#define AC_PINCAP_VREF_50 (1<<1) /* 50% */
@@ -286,6 +290,10 @@ enum {
286#define AC_PWRST_D1SUP (1<<1) 290#define AC_PWRST_D1SUP (1<<1)
287#define AC_PWRST_D2SUP (1<<2) 291#define AC_PWRST_D2SUP (1<<2)
288#define AC_PWRST_D3SUP (1<<3) 292#define AC_PWRST_D3SUP (1<<3)
293#define AC_PWRST_D3COLDSUP (1<<4)
294#define AC_PWRST_S3D3COLDSUP (1<<29)
295#define AC_PWRST_CLKSTOP (1<<30)
296#define AC_PWRST_EPSS (1U<<31)
289 297
290/* Power state values */ 298/* Power state values */
291#define AC_PWRST_SETTING (0xf<<0) 299#define AC_PWRST_SETTING (0xf<<0)
@@ -519,6 +527,9 @@ enum {
519/* max. codec address */ 527/* max. codec address */
520#define HDA_MAX_CODEC_ADDRESS 0x0f 528#define HDA_MAX_CODEC_ADDRESS 0x0f
521 529
530/* max number of PCM devics per card */
531#define HDA_MAX_PCMS 10
532
522/* 533/*
523 * generic arrays 534 * generic arrays
524 */ 535 */
@@ -631,6 +642,7 @@ struct hda_bus {
631 unsigned int rirb_error:1; /* error in codec communication */ 642 unsigned int rirb_error:1; /* error in codec communication */
632 unsigned int response_reset:1; /* controller was reset */ 643 unsigned int response_reset:1; /* controller was reset */
633 unsigned int in_reset:1; /* during reset operation */ 644 unsigned int in_reset:1; /* during reset operation */
645 unsigned int power_keep_link_on:1; /* don't power off HDA link */
634}; 646};
635 647
636/* 648/*
@@ -674,6 +686,7 @@ struct hda_codec_ops {
674#ifdef CONFIG_SND_HDA_POWER_SAVE 686#ifdef CONFIG_SND_HDA_POWER_SAVE
675 int (*check_power_status)(struct hda_codec *codec, hda_nid_t nid); 687 int (*check_power_status)(struct hda_codec *codec, hda_nid_t nid);
676#endif 688#endif
689 void (*reboot_notify)(struct hda_codec *codec);
677}; 690};
678 691
679/* record for amp information cache */ 692/* record for amp information cache */
@@ -771,6 +784,7 @@ struct hda_codec {
771 784
772 /* beep device */ 785 /* beep device */
773 struct hda_beep *beep; 786 struct hda_beep *beep;
787 unsigned int beep_mode;
774 788
775 /* widget capabilities cache */ 789 /* widget capabilities cache */
776 unsigned int num_nodes; 790 unsigned int num_nodes;
@@ -778,6 +792,7 @@ struct hda_codec {
778 u32 *wcaps; 792 u32 *wcaps;
779 793
780 struct snd_array mixers; /* list of assigned mixer elements */ 794 struct snd_array mixers; /* list of assigned mixer elements */
795 struct snd_array nids; /* list of mapped mixer elements */
781 796
782 struct hda_cache_rec amp_cache; /* cache for amp access */ 797 struct hda_cache_rec amp_cache; /* cache for amp access */
783 struct hda_cache_rec cmd_cache; /* cache for other commands */ 798 struct hda_cache_rec cmd_cache; /* cache for other commands */
@@ -806,11 +821,15 @@ struct hda_codec {
806 unsigned int pin_amp_workaround:1; /* pin out-amp takes index 821 unsigned int pin_amp_workaround:1; /* pin out-amp takes index
807 * (e.g. Conexant codecs) 822 * (e.g. Conexant codecs)
808 */ 823 */
824 unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */
809#ifdef CONFIG_SND_HDA_POWER_SAVE 825#ifdef CONFIG_SND_HDA_POWER_SAVE
810 unsigned int power_on :1; /* current (global) power-state */ 826 unsigned int power_on :1; /* current (global) power-state */
811 unsigned int power_transition :1; /* power-state in transition */ 827 unsigned int power_transition :1; /* power-state in transition */
812 int power_count; /* current (global) power refcount */ 828 int power_count; /* current (global) power refcount */
813 struct delayed_work power_work; /* delayed task for powerdown */ 829 struct delayed_work power_work; /* delayed task for powerdown */
830 unsigned long power_on_acct;
831 unsigned long power_off_acct;
832 unsigned long power_jiffies;
814#endif 833#endif
815 834
816 /* codec-specific additional proc output */ 835 /* codec-specific additional proc output */
@@ -883,6 +902,7 @@ int snd_hda_codec_set_pincfg(struct hda_codec *codec, hda_nid_t nid,
883 unsigned int cfg); 902 unsigned int cfg);
884int snd_hda_add_pincfg(struct hda_codec *codec, struct snd_array *list, 903int snd_hda_add_pincfg(struct hda_codec *codec, struct snd_array *list,
885 hda_nid_t nid, unsigned int cfg); /* for hwdep */ 904 hda_nid_t nid, unsigned int cfg); /* for hwdep */
905void snd_hda_shutup_pins(struct hda_codec *codec);
886 906
887/* 907/*
888 * Mixer 908 * Mixer
@@ -910,6 +930,7 @@ int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid,
910 * Misc 930 * Misc
911 */ 931 */
912void snd_hda_get_codec_name(struct hda_codec *codec, char *name, int namelen); 932void snd_hda_get_codec_name(struct hda_codec *codec, char *name, int namelen);
933void snd_hda_bus_reboot_notify(struct hda_bus *bus);
913 934
914/* 935/*
915 * power management 936 * power management
@@ -933,6 +954,7 @@ const char *snd_hda_get_jack_location(u32 cfg);
933void snd_hda_power_up(struct hda_codec *codec); 954void snd_hda_power_up(struct hda_codec *codec);
934void snd_hda_power_down(struct hda_codec *codec); 955void snd_hda_power_down(struct hda_codec *codec);
935#define snd_hda_codec_needs_resume(codec) codec->power_count 956#define snd_hda_codec_needs_resume(codec) codec->power_count
957void snd_hda_update_power_acct(struct hda_codec *codec);
936#else 958#else
937static inline void snd_hda_power_up(struct hda_codec *codec) {} 959static inline void snd_hda_power_up(struct hda_codec *codec) {}
938static inline void snd_hda_power_down(struct hda_codec *codec) {} 960static inline void snd_hda_power_down(struct hda_codec *codec) {}
diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c
index 9446a5abea13..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"
@@ -309,17 +310,12 @@ out_fail:
309 return -EINVAL; 310 return -EINVAL;
310} 311}
311 312
312static int hdmi_present_sense(struct hda_codec *codec, hda_nid_t nid)
313{
314 return snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_SENSE, 0);
315}
316
317static int hdmi_eld_valid(struct hda_codec *codec, hda_nid_t nid) 313static int hdmi_eld_valid(struct hda_codec *codec, hda_nid_t nid)
318{ 314{
319 int eldv; 315 int eldv;
320 int present; 316 int present;
321 317
322 present = hdmi_present_sense(codec, nid); 318 present = snd_hda_pin_sense(codec, nid);
323 eldv = (present & AC_PINSENSE_ELDV); 319 eldv = (present & AC_PINSENSE_ELDV);
324 present = (present & AC_PINSENSE_PRESENCE); 320 present = (present & AC_PINSENSE_PRESENCE);
325 321
@@ -336,6 +332,7 @@ int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid)
336 return snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_DIP_SIZE, 332 return snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_DIP_SIZE,
337 AC_DIPSIZE_ELD_BUF); 333 AC_DIPSIZE_ELD_BUF);
338} 334}
335EXPORT_SYMBOL_HDA(snd_hdmi_get_eld_size);
339 336
340int snd_hdmi_get_eld(struct hdmi_eld *eld, 337int snd_hdmi_get_eld(struct hdmi_eld *eld,
341 struct hda_codec *codec, hda_nid_t nid) 338 struct hda_codec *codec, hda_nid_t nid)
@@ -371,6 +368,7 @@ int snd_hdmi_get_eld(struct hdmi_eld *eld,
371 kfree(buf); 368 kfree(buf);
372 return ret; 369 return ret;
373} 370}
371EXPORT_SYMBOL_HDA(snd_hdmi_get_eld);
374 372
375static void hdmi_show_short_audio_desc(struct cea_sad *a) 373static void hdmi_show_short_audio_desc(struct cea_sad *a)
376{ 374{
@@ -409,6 +407,7 @@ void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen)
409 } 407 }
410 buf[j] = '\0'; /* necessary when j == 0 */ 408 buf[j] = '\0'; /* necessary when j == 0 */
411} 409}
410EXPORT_SYMBOL_HDA(snd_print_channel_allocation);
412 411
413void snd_hdmi_show_eld(struct hdmi_eld *e) 412void snd_hdmi_show_eld(struct hdmi_eld *e)
414{ 413{
@@ -427,6 +426,7 @@ void snd_hdmi_show_eld(struct hdmi_eld *e)
427 for (i = 0; i < e->sad_count; i++) 426 for (i = 0; i < e->sad_count; i++)
428 hdmi_show_short_audio_desc(e->sad + i); 427 hdmi_show_short_audio_desc(e->sad + i);
429} 428}
429EXPORT_SYMBOL_HDA(snd_hdmi_show_eld);
430 430
431#ifdef CONFIG_PROC_FS 431#ifdef CONFIG_PROC_FS
432 432
@@ -477,6 +477,8 @@ static void hdmi_print_eld_info(struct snd_info_entry *entry,
477 [4 ... 7] = "reserved" 477 [4 ... 7] = "reserved"
478 }; 478 };
479 479
480 snd_iprintf(buffer, "monitor_present\t\t%d\n", e->monitor_present);
481 snd_iprintf(buffer, "eld_valid\t\t%d\n", e->eld_valid);
480 snd_iprintf(buffer, "monitor_name\t\t%s\n", e->monitor_name); 482 snd_iprintf(buffer, "monitor_name\t\t%s\n", e->monitor_name);
481 snd_iprintf(buffer, "connection_type\t\t%s\n", 483 snd_iprintf(buffer, "connection_type\t\t%s\n",
482 eld_connection_type_names[e->conn_type]); 484 eld_connection_type_names[e->conn_type]);
@@ -518,7 +520,11 @@ static void hdmi_write_eld_info(struct snd_info_entry *entry,
518 * monitor_name manufacture_id product_id 520 * monitor_name manufacture_id product_id
519 * eld_version edid_version 521 * eld_version edid_version
520 */ 522 */
521 if (!strcmp(name, "connection_type")) 523 if (!strcmp(name, "monitor_present"))
524 e->monitor_present = val;
525 else if (!strcmp(name, "eld_valid"))
526 e->eld_valid = val;
527 else if (!strcmp(name, "connection_type"))
522 e->conn_type = val; 528 e->conn_type = val;
523 else if (!strcmp(name, "port_id")) 529 else if (!strcmp(name, "port_id"))
524 e->port_id = val; 530 e->port_id = val;
@@ -560,13 +566,14 @@ static void hdmi_write_eld_info(struct snd_info_entry *entry,
560} 566}
561 567
562 568
563int snd_hda_eld_proc_new(struct hda_codec *codec, struct hdmi_eld *eld) 569int snd_hda_eld_proc_new(struct hda_codec *codec, struct hdmi_eld *eld,
570 int index)
564{ 571{
565 char name[32]; 572 char name[32];
566 struct snd_info_entry *entry; 573 struct snd_info_entry *entry;
567 int err; 574 int err;
568 575
569 snprintf(name, sizeof(name), "eld#%d", codec->addr); 576 snprintf(name, sizeof(name), "eld#%d.%d", codec->addr, index);
570 err = snd_card_proc_new(codec->bus->card, name, &entry); 577 err = snd_card_proc_new(codec->bus->card, name, &entry);
571 if (err < 0) 578 if (err < 0)
572 return err; 579 return err;
@@ -578,6 +585,7 @@ int snd_hda_eld_proc_new(struct hda_codec *codec, struct hdmi_eld *eld)
578 585
579 return 0; 586 return 0;
580} 587}
588EXPORT_SYMBOL_HDA(snd_hda_eld_proc_new);
581 589
582void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld) 590void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld)
583{ 591{
@@ -586,5 +594,6 @@ void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld)
586 eld->proc_entry = NULL; 594 eld->proc_entry = NULL;
587 } 595 }
588} 596}
597EXPORT_SYMBOL_HDA(snd_hda_eld_proc_free);
589 598
590#endif /* CONFIG_PROC_FS */ 599#endif /* CONFIG_PROC_FS */
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index b36f6c5a92df..5ea21285ee1f 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -727,7 +727,8 @@ static int create_mixer(struct hda_codec *codec, struct hda_gnode *node,
727 if (is_loopback) 727 if (is_loopback)
728 add_input_loopback(codec, node->nid, HDA_INPUT, index); 728 add_input_loopback(codec, node->nid, HDA_INPUT, index);
729 snd_printdd("[%s] NID=0x%x, DIR=IN, IDX=0x%x\n", name, node->nid, index); 729 snd_printdd("[%s] NID=0x%x, DIR=IN, IDX=0x%x\n", name, node->nid, index);
730 err = snd_hda_ctl_add(codec, snd_ctl_new1(&knew, codec)); 730 err = snd_hda_ctl_add(codec, node->nid,
731 snd_ctl_new1(&knew, codec));
731 if (err < 0) 732 if (err < 0)
732 return err; 733 return err;
733 created = 1; 734 created = 1;
@@ -737,7 +738,8 @@ static int create_mixer(struct hda_codec *codec, struct hda_gnode *node,
737 if (is_loopback) 738 if (is_loopback)
738 add_input_loopback(codec, node->nid, HDA_OUTPUT, 0); 739 add_input_loopback(codec, node->nid, HDA_OUTPUT, 0);
739 snd_printdd("[%s] NID=0x%x, DIR=OUT\n", name, node->nid); 740 snd_printdd("[%s] NID=0x%x, DIR=OUT\n", name, node->nid);
740 err = snd_hda_ctl_add(codec, snd_ctl_new1(&knew, codec)); 741 err = snd_hda_ctl_add(codec, node->nid,
742 snd_ctl_new1(&knew, codec));
741 if (err < 0) 743 if (err < 0)
742 return err; 744 return err;
743 created = 1; 745 created = 1;
@@ -751,7 +753,8 @@ static int create_mixer(struct hda_codec *codec, struct hda_gnode *node,
751 (node->amp_in_caps & AC_AMPCAP_NUM_STEPS)) { 753 (node->amp_in_caps & AC_AMPCAP_NUM_STEPS)) {
752 knew = (struct snd_kcontrol_new)HDA_CODEC_VOLUME(name, node->nid, index, HDA_INPUT); 754 knew = (struct snd_kcontrol_new)HDA_CODEC_VOLUME(name, node->nid, index, HDA_INPUT);
753 snd_printdd("[%s] NID=0x%x, DIR=IN, IDX=0x%x\n", name, node->nid, index); 755 snd_printdd("[%s] NID=0x%x, DIR=IN, IDX=0x%x\n", name, node->nid, index);
754 err = snd_hda_ctl_add(codec, snd_ctl_new1(&knew, codec)); 756 err = snd_hda_ctl_add(codec, node->nid,
757 snd_ctl_new1(&knew, codec));
755 if (err < 0) 758 if (err < 0)
756 return err; 759 return err;
757 created = 1; 760 created = 1;
@@ -759,7 +762,8 @@ static int create_mixer(struct hda_codec *codec, struct hda_gnode *node,
759 (node->amp_out_caps & AC_AMPCAP_NUM_STEPS)) { 762 (node->amp_out_caps & AC_AMPCAP_NUM_STEPS)) {
760 knew = (struct snd_kcontrol_new)HDA_CODEC_VOLUME(name, node->nid, 0, HDA_OUTPUT); 763 knew = (struct snd_kcontrol_new)HDA_CODEC_VOLUME(name, node->nid, 0, HDA_OUTPUT);
761 snd_printdd("[%s] NID=0x%x, DIR=OUT\n", name, node->nid); 764 snd_printdd("[%s] NID=0x%x, DIR=OUT\n", name, node->nid);
762 err = snd_hda_ctl_add(codec, snd_ctl_new1(&knew, codec)); 765 err = snd_hda_ctl_add(codec, node->nid,
766 snd_ctl_new1(&knew, codec));
763 if (err < 0) 767 if (err < 0)
764 return err; 768 return err;
765 created = 1; 769 created = 1;
@@ -857,7 +861,8 @@ static int build_input_controls(struct hda_codec *codec)
857 } 861 }
858 862
859 /* create input MUX if multiple sources are available */ 863 /* create input MUX if multiple sources are available */
860 err = snd_hda_ctl_add(codec, snd_ctl_new1(&cap_sel, codec)); 864 err = snd_hda_ctl_add(codec, spec->adc_node->nid,
865 snd_ctl_new1(&cap_sel, codec));
861 if (err < 0) 866 if (err < 0)
862 return err; 867 return err;
863 868
@@ -875,7 +880,8 @@ static int build_input_controls(struct hda_codec *codec)
875 HDA_CODEC_VOLUME(name, adc_node->nid, 880 HDA_CODEC_VOLUME(name, adc_node->nid,
876 spec->input_mux.items[i].index, 881 spec->input_mux.items[i].index,
877 HDA_INPUT); 882 HDA_INPUT);
878 err = snd_hda_ctl_add(codec, snd_ctl_new1(&knew, codec)); 883 err = snd_hda_ctl_add(codec, adc_node->nid,
884 snd_ctl_new1(&knew, codec));
879 if (err < 0) 885 if (err < 0)
880 return err; 886 return err;
881 } 887 }
diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c
index cc24e6721d74..a1fc83753cc6 100644
--- a/sound/pci/hda/hda_hwdep.c
+++ b/sound/pci/hda/hda_hwdep.c
@@ -24,6 +24,7 @@
24#include <linux/compat.h> 24#include <linux/compat.h>
25#include <linux/mutex.h> 25#include <linux/mutex.h>
26#include <linux/ctype.h> 26#include <linux/ctype.h>
27#include <linux/string.h>
27#include <linux/firmware.h> 28#include <linux/firmware.h>
28#include <sound/core.h> 29#include <sound/core.h>
29#include "hda_codec.h" 30#include "hda_codec.h"
@@ -154,6 +155,44 @@ int /*__devinit*/ snd_hda_create_hwdep(struct hda_codec *codec)
154 return 0; 155 return 0;
155} 156}
156 157
158#ifdef CONFIG_SND_HDA_POWER_SAVE
159static ssize_t power_on_acct_show(struct device *dev,
160 struct device_attribute *attr,
161 char *buf)
162{
163 struct snd_hwdep *hwdep = dev_get_drvdata(dev);
164 struct hda_codec *codec = hwdep->private_data;
165 snd_hda_update_power_acct(codec);
166 return sprintf(buf, "%u\n", jiffies_to_msecs(codec->power_on_acct));
167}
168
169static ssize_t power_off_acct_show(struct device *dev,
170 struct device_attribute *attr,
171 char *buf)
172{
173 struct snd_hwdep *hwdep = dev_get_drvdata(dev);
174 struct hda_codec *codec = hwdep->private_data;
175 snd_hda_update_power_acct(codec);
176 return sprintf(buf, "%u\n", jiffies_to_msecs(codec->power_off_acct));
177}
178
179static struct device_attribute power_attrs[] = {
180 __ATTR_RO(power_on_acct),
181 __ATTR_RO(power_off_acct),
182};
183
184int snd_hda_hwdep_add_power_sysfs(struct hda_codec *codec)
185{
186 struct snd_hwdep *hwdep = codec->hwdep;
187 int i;
188
189 for (i = 0; i < ARRAY_SIZE(power_attrs); i++)
190 snd_add_device_sysfs_file(SNDRV_DEVICE_TYPE_HWDEP, hwdep->card,
191 hwdep->device, &power_attrs[i]);
192 return 0;
193}
194#endif /* CONFIG_SND_HDA_POWER_SAVE */
195
157#ifdef CONFIG_SND_HDA_RECONFIG 196#ifdef CONFIG_SND_HDA_RECONFIG
158 197
159/* 198/*
@@ -254,8 +293,11 @@ static ssize_t type##_store(struct device *dev, \
254{ \ 293{ \
255 struct snd_hwdep *hwdep = dev_get_drvdata(dev); \ 294 struct snd_hwdep *hwdep = dev_get_drvdata(dev); \
256 struct hda_codec *codec = hwdep->private_data; \ 295 struct hda_codec *codec = hwdep->private_data; \
257 char *after; \ 296 unsigned long val; \
258 codec->type = simple_strtoul(buf, &after, 0); \ 297 int err = strict_strtoul(buf, 0, &val); \
298 if (err < 0) \
299 return err; \
300 codec->type = val; \
259 return count; \ 301 return count; \
260} 302}
261 303
@@ -390,8 +432,7 @@ static int parse_hints(struct hda_codec *codec, const char *buf)
390 char *key, *val; 432 char *key, *val;
391 struct hda_hint *hint; 433 struct hda_hint *hint;
392 434
393 while (isspace(*buf)) 435 buf = skip_spaces(buf);
394 buf++;
395 if (!*buf || *buf == '#' || *buf == '\n') 436 if (!*buf || *buf == '#' || *buf == '\n')
396 return 0; 437 return 0;
397 if (*buf == '=') 438 if (*buf == '=')
@@ -406,8 +447,7 @@ static int parse_hints(struct hda_codec *codec, const char *buf)
406 return -EINVAL; 447 return -EINVAL;
407 } 448 }
408 *val++ = 0; 449 *val++ = 0;
409 while (isspace(*val)) 450 val = skip_spaces(val);
410 val++;
411 remove_trail_spaces(key); 451 remove_trail_spaces(key);
412 remove_trail_spaces(val); 452 remove_trail_spaces(val);
413 hint = get_hint(codec, key); 453 hint = get_hint(codec, key);
@@ -585,6 +625,10 @@ enum {
585 LINE_MODE_PINCFG, 625 LINE_MODE_PINCFG,
586 LINE_MODE_VERB, 626 LINE_MODE_VERB,
587 LINE_MODE_HINT, 627 LINE_MODE_HINT,
628 LINE_MODE_VENDOR_ID,
629 LINE_MODE_SUBSYSTEM_ID,
630 LINE_MODE_REVISION_ID,
631 LINE_MODE_CHIP_NAME,
588 NUM_LINE_MODES, 632 NUM_LINE_MODES,
589}; 633};
590 634
@@ -614,53 +658,71 @@ static void parse_codec_mode(char *buf, struct hda_bus *bus,
614} 658}
615 659
616/* parse the contents after the other command tags, [pincfg], [verb], 660/* parse the contents after the other command tags, [pincfg], [verb],
617 * [hint] and [model] 661 * [vendor_id], [subsystem_id], [revision_id], [chip_name], [hint] and [model]
618 * just pass to the sysfs helper (only when any codec was specified) 662 * just pass to the sysfs helper (only when any codec was specified)
619 */ 663 */
620static void parse_pincfg_mode(char *buf, struct hda_bus *bus, 664static void parse_pincfg_mode(char *buf, struct hda_bus *bus,
621 struct hda_codec **codecp) 665 struct hda_codec **codecp)
622{ 666{
623 if (!*codecp)
624 return;
625 parse_user_pin_configs(*codecp, buf); 667 parse_user_pin_configs(*codecp, buf);
626} 668}
627 669
628static void parse_verb_mode(char *buf, struct hda_bus *bus, 670static void parse_verb_mode(char *buf, struct hda_bus *bus,
629 struct hda_codec **codecp) 671 struct hda_codec **codecp)
630{ 672{
631 if (!*codecp)
632 return;
633 parse_init_verbs(*codecp, buf); 673 parse_init_verbs(*codecp, buf);
634} 674}
635 675
636static void parse_hint_mode(char *buf, struct hda_bus *bus, 676static void parse_hint_mode(char *buf, struct hda_bus *bus,
637 struct hda_codec **codecp) 677 struct hda_codec **codecp)
638{ 678{
639 if (!*codecp)
640 return;
641 parse_hints(*codecp, buf); 679 parse_hints(*codecp, buf);
642} 680}
643 681
644static void parse_model_mode(char *buf, struct hda_bus *bus, 682static void parse_model_mode(char *buf, struct hda_bus *bus,
645 struct hda_codec **codecp) 683 struct hda_codec **codecp)
646{ 684{
647 if (!*codecp)
648 return;
649 kfree((*codecp)->modelname); 685 kfree((*codecp)->modelname);
650 (*codecp)->modelname = kstrdup(buf, GFP_KERNEL); 686 (*codecp)->modelname = kstrdup(buf, GFP_KERNEL);
651} 687}
652 688
689static void parse_chip_name_mode(char *buf, struct hda_bus *bus,
690 struct hda_codec **codecp)
691{
692 kfree((*codecp)->chip_name);
693 (*codecp)->chip_name = kstrdup(buf, GFP_KERNEL);
694}
695
696#define DEFINE_PARSE_ID_MODE(name) \
697static void parse_##name##_mode(char *buf, struct hda_bus *bus, \
698 struct hda_codec **codecp) \
699{ \
700 unsigned long val; \
701 if (!strict_strtoul(buf, 0, &val)) \
702 (*codecp)->name = val; \
703}
704
705DEFINE_PARSE_ID_MODE(vendor_id);
706DEFINE_PARSE_ID_MODE(subsystem_id);
707DEFINE_PARSE_ID_MODE(revision_id);
708
709
653struct hda_patch_item { 710struct hda_patch_item {
654 const char *tag; 711 const char *tag;
655 void (*parser)(char *buf, struct hda_bus *bus, struct hda_codec **retc); 712 void (*parser)(char *buf, struct hda_bus *bus, struct hda_codec **retc);
713 int need_codec;
656}; 714};
657 715
658static struct hda_patch_item patch_items[NUM_LINE_MODES] = { 716static struct hda_patch_item patch_items[NUM_LINE_MODES] = {
659 [LINE_MODE_CODEC] = { "[codec]", parse_codec_mode }, 717 [LINE_MODE_CODEC] = { "[codec]", parse_codec_mode, 0 },
660 [LINE_MODE_MODEL] = { "[model]", parse_model_mode }, 718 [LINE_MODE_MODEL] = { "[model]", parse_model_mode, 1 },
661 [LINE_MODE_VERB] = { "[verb]", parse_verb_mode }, 719 [LINE_MODE_VERB] = { "[verb]", parse_verb_mode, 1 },
662 [LINE_MODE_PINCFG] = { "[pincfg]", parse_pincfg_mode }, 720 [LINE_MODE_PINCFG] = { "[pincfg]", parse_pincfg_mode, 1 },
663 [LINE_MODE_HINT] = { "[hint]", parse_hint_mode }, 721 [LINE_MODE_HINT] = { "[hint]", parse_hint_mode, 1 },
722 [LINE_MODE_VENDOR_ID] = { "[vendor_id]", parse_vendor_id_mode, 1 },
723 [LINE_MODE_SUBSYSTEM_ID] = { "[subsystem_id]", parse_subsystem_id_mode, 1 },
724 [LINE_MODE_REVISION_ID] = { "[revision_id]", parse_revision_id_mode, 1 },
725 [LINE_MODE_CHIP_NAME] = { "[chip_name]", parse_chip_name_mode, 1 },
664}; 726};
665 727
666/* check the line starting with '[' -- change the parser mode accodingly */ 728/* check the line starting with '[' -- change the parser mode accodingly */
@@ -743,7 +805,8 @@ int snd_hda_load_patch(struct hda_bus *bus, const char *patch)
743 continue; 805 continue;
744 if (*buf == '[') 806 if (*buf == '[')
745 line_mode = parse_line_mode(buf, bus); 807 line_mode = parse_line_mode(buf, bus);
746 else if (patch_items[line_mode].parser) 808 else if (patch_items[line_mode].parser &&
809 (codec || !patch_items[line_mode].need_codec))
747 patch_items[line_mode].parser(buf, bus, &codec); 810 patch_items[line_mode].parser(buf, bus, &codec);
748 } 811 }
749 release_firmware(fw); 812 release_firmware(fw);
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 6517f589d01d..cec68152dcb1 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -60,10 +60,14 @@ static int bdl_pos_adj[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1};
60static int probe_mask[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1}; 60static int probe_mask[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1};
61static int probe_only[SNDRV_CARDS]; 61static int probe_only[SNDRV_CARDS];
62static int single_cmd; 62static int single_cmd;
63static int enable_msi; 63static int enable_msi = -1;
64#ifdef CONFIG_SND_HDA_PATCH_LOADER 64#ifdef CONFIG_SND_HDA_PATCH_LOADER
65static char *patch[SNDRV_CARDS]; 65static char *patch[SNDRV_CARDS];
66#endif 66#endif
67#ifdef CONFIG_SND_HDA_INPUT_BEEP
68static int beep_mode[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] =
69 CONFIG_SND_HDA_INPUT_BEEP_MODE};
70#endif
67 71
68module_param_array(index, int, NULL, 0444); 72module_param_array(index, int, NULL, 0444);
69MODULE_PARM_DESC(index, "Index value for Intel HD audio interface."); 73MODULE_PARM_DESC(index, "Index value for Intel HD audio interface.");
@@ -91,6 +95,11 @@ MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)");
91module_param_array(patch, charp, NULL, 0444); 95module_param_array(patch, charp, NULL, 0444);
92MODULE_PARM_DESC(patch, "Patch file for Intel HD audio interface."); 96MODULE_PARM_DESC(patch, "Patch file for Intel HD audio interface.");
93#endif 97#endif
98#ifdef CONFIG_SND_HDA_INPUT_BEEP
99module_param_array(beep_mode, int, NULL, 0444);
100MODULE_PARM_DESC(beep_mode, "Select HDA Beep registration mode "
101 "(0=off, 1=on, 2=mute switch on/off) (default=1).");
102#endif
94 103
95#ifdef CONFIG_SND_HDA_POWER_SAVE 104#ifdef CONFIG_SND_HDA_POWER_SAVE
96static int power_save = CONFIG_SND_HDA_POWER_SAVE_DEFAULT; 105static int power_save = CONFIG_SND_HDA_POWER_SAVE_DEFAULT;
@@ -116,6 +125,7 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
116 "{Intel, ICH9}," 125 "{Intel, ICH9},"
117 "{Intel, ICH10}," 126 "{Intel, ICH10},"
118 "{Intel, PCH}," 127 "{Intel, PCH},"
128 "{Intel, CPT},"
119 "{Intel, SCH}," 129 "{Intel, SCH},"
120 "{ATI, SB450}," 130 "{ATI, SB450},"
121 "{ATI, SB600}," 131 "{ATI, SB600},"
@@ -250,8 +260,6 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
250#define AZX_MAX_FRAG 32 260#define AZX_MAX_FRAG 32
251/* max buffer size - no h/w limit, you can increase as you like */ 261/* max buffer size - no h/w limit, you can increase as you like */
252#define AZX_MAX_BUF_SIZE (1024*1024*1024) 262#define AZX_MAX_BUF_SIZE (1024*1024*1024)
253/* max number of PCM devics per card */
254#define AZX_MAX_PCMS 8
255 263
256/* RIRB int mask: overrun[2], response[0] */ 264/* RIRB int mask: overrun[2], response[0] */
257#define RIRB_INT_RESPONSE 0x01 265#define RIRB_INT_RESPONSE 0x01
@@ -259,7 +267,8 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
259#define RIRB_INT_MASK 0x05 267#define RIRB_INT_MASK 0x05
260 268
261/* STATESTS int mask: S3,SD2,SD1,SD0 */ 269/* STATESTS int mask: S3,SD2,SD1,SD0 */
262#define AZX_MAX_CODECS 4 270#define AZX_MAX_CODECS 8
271#define AZX_DEFAULT_CODECS 4
263#define STATESTS_INT_MASK ((1 << AZX_MAX_CODECS) - 1) 272#define STATESTS_INT_MASK ((1 << AZX_MAX_CODECS) - 1)
264 273
265/* SD_CTL bits */ 274/* SD_CTL bits */
@@ -347,6 +356,7 @@ struct azx_dev {
347 */ 356 */
348 unsigned char stream_tag; /* assigned stream */ 357 unsigned char stream_tag; /* assigned stream */
349 unsigned char index; /* stream index */ 358 unsigned char index; /* stream index */
359 int device; /* last device number assigned to */
350 360
351 unsigned int opened :1; 361 unsigned int opened :1;
352 unsigned int running :1; 362 unsigned int running :1;
@@ -398,12 +408,13 @@ struct azx {
398 struct azx_dev *azx_dev; 408 struct azx_dev *azx_dev;
399 409
400 /* PCM */ 410 /* PCM */
401 struct snd_pcm *pcm[AZX_MAX_PCMS]; 411 struct snd_pcm *pcm[HDA_MAX_PCMS];
402 412
403 /* HD codec */ 413 /* HD codec */
404 unsigned short codec_mask; 414 unsigned short codec_mask;
405 int codec_probe_mask; /* copied from probe_mask option */ 415 int codec_probe_mask; /* copied from probe_mask option */
406 struct hda_bus *bus; 416 struct hda_bus *bus;
417 unsigned int beep_mode;
407 418
408 /* CORB/RIRB */ 419 /* CORB/RIRB */
409 struct azx_rb corb; 420 struct azx_rb corb;
@@ -415,6 +426,7 @@ struct azx {
415 426
416 /* flags */ 427 /* flags */
417 int position_fix; 428 int position_fix;
429 int poll_count;
418 unsigned int running :1; 430 unsigned int running :1;
419 unsigned int initialized :1; 431 unsigned int initialized :1;
420 unsigned int single_cmd :1; 432 unsigned int single_cmd :1;
@@ -437,6 +449,7 @@ struct azx {
437/* driver types */ 449/* driver types */
438enum { 450enum {
439 AZX_DRIVER_ICH, 451 AZX_DRIVER_ICH,
452 AZX_DRIVER_PCH,
440 AZX_DRIVER_SCH, 453 AZX_DRIVER_SCH,
441 AZX_DRIVER_ATI, 454 AZX_DRIVER_ATI,
442 AZX_DRIVER_ATIHDMI, 455 AZX_DRIVER_ATIHDMI,
@@ -451,6 +464,7 @@ enum {
451 464
452static char *driver_short_names[] __devinitdata = { 465static char *driver_short_names[] __devinitdata = {
453 [AZX_DRIVER_ICH] = "HDA Intel", 466 [AZX_DRIVER_ICH] = "HDA Intel",
467 [AZX_DRIVER_PCH] = "HDA Intel PCH",
454 [AZX_DRIVER_SCH] = "HDA Intel MID", 468 [AZX_DRIVER_SCH] = "HDA Intel MID",
455 [AZX_DRIVER_ATI] = "HDA ATI SB", 469 [AZX_DRIVER_ATI] = "HDA ATI SB",
456 [AZX_DRIVER_ATIHDMI] = "HDA ATI HDMI", 470 [AZX_DRIVER_ATIHDMI] = "HDA ATI HDMI",
@@ -495,7 +509,7 @@ static char *driver_short_names[] __devinitdata = {
495#define get_azx_dev(substream) (substream->runtime->private_data) 509#define get_azx_dev(substream) (substream->runtime->private_data)
496 510
497static int azx_acquire_irq(struct azx *chip, int do_disconnect); 511static int azx_acquire_irq(struct azx *chip, int do_disconnect);
498 512static int azx_send_cmd(struct hda_bus *bus, unsigned int val);
499/* 513/*
500 * Interface for HD codec 514 * Interface for HD codec
501 */ 515 */
@@ -653,11 +667,12 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus,
653{ 667{
654 struct azx *chip = bus->private_data; 668 struct azx *chip = bus->private_data;
655 unsigned long timeout; 669 unsigned long timeout;
670 int do_poll = 0;
656 671
657 again: 672 again:
658 timeout = jiffies + msecs_to_jiffies(1000); 673 timeout = jiffies + msecs_to_jiffies(1000);
659 for (;;) { 674 for (;;) {
660 if (chip->polling_mode) { 675 if (chip->polling_mode || do_poll) {
661 spin_lock_irq(&chip->reg_lock); 676 spin_lock_irq(&chip->reg_lock);
662 azx_update_rirb(chip); 677 azx_update_rirb(chip);
663 spin_unlock_irq(&chip->reg_lock); 678 spin_unlock_irq(&chip->reg_lock);
@@ -665,6 +680,9 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus,
665 if (!chip->rirb.cmds[addr]) { 680 if (!chip->rirb.cmds[addr]) {
666 smp_rmb(); 681 smp_rmb();
667 bus->rirb_error = 0; 682 bus->rirb_error = 0;
683
684 if (!do_poll)
685 chip->poll_count = 0;
668 return chip->rirb.res[addr]; /* the last value */ 686 return chip->rirb.res[addr]; /* the last value */
669 } 687 }
670 if (time_after(jiffies, timeout)) 688 if (time_after(jiffies, timeout))
@@ -677,6 +695,24 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus,
677 } 695 }
678 } 696 }
679 697
698 if (!chip->polling_mode && chip->poll_count < 2) {
699 snd_printdd(SFX "azx_get_response timeout, "
700 "polling the codec once: last cmd=0x%08x\n",
701 chip->last_cmd[addr]);
702 do_poll = 1;
703 chip->poll_count++;
704 goto again;
705 }
706
707
708 if (!chip->polling_mode) {
709 snd_printk(KERN_WARNING SFX "azx_get_response timeout, "
710 "switching to polling mode: last cmd=0x%08x\n",
711 chip->last_cmd[addr]);
712 chip->polling_mode = 1;
713 goto again;
714 }
715
680 if (chip->msi) { 716 if (chip->msi) {
681 snd_printk(KERN_WARNING SFX "No response from codec, " 717 snd_printk(KERN_WARNING SFX "No response from codec, "
682 "disabling MSI: last cmd=0x%08x\n", 718 "disabling MSI: last cmd=0x%08x\n",
@@ -692,14 +728,6 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus,
692 goto again; 728 goto again;
693 } 729 }
694 730
695 if (!chip->polling_mode) {
696 snd_printk(KERN_WARNING SFX "azx_get_response timeout, "
697 "switching to polling mode: last cmd=0x%08x\n",
698 chip->last_cmd[addr]);
699 chip->polling_mode = 1;
700 goto again;
701 }
702
703 if (chip->probing) { 731 if (chip->probing) {
704 /* If this critical timeout happens during the codec probing 732 /* If this critical timeout happens during the codec probing
705 * phase, this is likely an access to a non-existing codec 733 * phase, this is likely an access to a non-existing codec
@@ -942,8 +970,8 @@ static void azx_stream_start(struct azx *chip, struct azx_dev *azx_dev)
942 azx_dev->insufficient = 1; 970 azx_dev->insufficient = 1;
943 971
944 /* enable SIE */ 972 /* enable SIE */
945 azx_writeb(chip, INTCTL, 973 azx_writel(chip, INTCTL,
946 azx_readb(chip, INTCTL) | (1 << azx_dev->index)); 974 azx_readl(chip, INTCTL) | (1 << azx_dev->index));
947 /* set DMA start and interrupt mask */ 975 /* set DMA start and interrupt mask */
948 azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) | 976 azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) |
949 SD_CTL_DMA_START | SD_INT_MASK); 977 SD_CTL_DMA_START | SD_INT_MASK);
@@ -962,8 +990,8 @@ static void azx_stream_stop(struct azx *chip, struct azx_dev *azx_dev)
962{ 990{
963 azx_stream_clear(chip, azx_dev); 991 azx_stream_clear(chip, azx_dev);
964 /* disable SIE */ 992 /* disable SIE */
965 azx_writeb(chip, INTCTL, 993 azx_writel(chip, INTCTL,
966 azx_readb(chip, INTCTL) & ~(1 << azx_dev->index)); 994 azx_readl(chip, INTCTL) & ~(1 << azx_dev->index));
967} 995}
968 996
969 997
@@ -1039,6 +1067,7 @@ static void azx_init_pci(struct azx *chip)
1039 0x01, NVIDIA_HDA_ENABLE_COHBIT); 1067 0x01, NVIDIA_HDA_ENABLE_COHBIT);
1040 break; 1068 break;
1041 case AZX_DRIVER_SCH: 1069 case AZX_DRIVER_SCH:
1070 case AZX_DRIVER_PCH:
1042 pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop); 1071 pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop);
1043 if (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) { 1072 if (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) {
1044 pci_write_config_word(chip->pci, INTEL_SCH_HDA_DEVC, 1073 pci_write_config_word(chip->pci, INTEL_SCH_HDA_DEVC,
@@ -1324,7 +1353,7 @@ static void azx_bus_reset(struct hda_bus *bus)
1324 if (chip->initialized) { 1353 if (chip->initialized) {
1325 int i; 1354 int i;
1326 1355
1327 for (i = 0; i < AZX_MAX_PCMS; i++) 1356 for (i = 0; i < HDA_MAX_PCMS; i++)
1328 snd_pcm_suspend_all(chip->pcm[i]); 1357 snd_pcm_suspend_all(chip->pcm[i]);
1329 snd_hda_suspend(chip->bus); 1358 snd_hda_suspend(chip->bus);
1330 snd_hda_resume(chip->bus); 1359 snd_hda_resume(chip->bus);
@@ -1339,6 +1368,7 @@ static void azx_bus_reset(struct hda_bus *bus)
1339 1368
1340/* number of codec slots for each chipset: 0 = default slots (i.e. 4) */ 1369/* number of codec slots for each chipset: 0 = default slots (i.e. 4) */
1341static unsigned int azx_max_codecs[AZX_NUM_DRIVERS] __devinitdata = { 1370static unsigned int azx_max_codecs[AZX_NUM_DRIVERS] __devinitdata = {
1371 [AZX_DRIVER_NVIDIA] = 8,
1342 [AZX_DRIVER_TERA] = 1, 1372 [AZX_DRIVER_TERA] = 1,
1343}; 1373};
1344 1374
@@ -1371,7 +1401,7 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model)
1371 codecs = 0; 1401 codecs = 0;
1372 max_slots = azx_max_codecs[chip->driver_type]; 1402 max_slots = azx_max_codecs[chip->driver_type];
1373 if (!max_slots) 1403 if (!max_slots)
1374 max_slots = AZX_MAX_CODECS; 1404 max_slots = AZX_DEFAULT_CODECS;
1375 1405
1376 /* First try to probe all given codec slots */ 1406 /* First try to probe all given codec slots */
1377 for (c = 0; c < max_slots; c++) { 1407 for (c = 0; c < max_slots; c++) {
@@ -1386,7 +1416,7 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model)
1386 chip->codec_mask &= ~(1 << c); 1416 chip->codec_mask &= ~(1 << c);
1387 /* More badly, accessing to a non-existing 1417 /* More badly, accessing to a non-existing
1388 * codec often screws up the controller chip, 1418 * codec often screws up the controller chip,
1389 * and distrubs the further communications. 1419 * and disturbs the further communications.
1390 * Thus if an error occurs during probing, 1420 * Thus if an error occurs during probing,
1391 * better to reset the controller chip to 1421 * better to reset the controller chip to
1392 * get back to the sanity state. 1422 * get back to the sanity state.
@@ -1404,6 +1434,7 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model)
1404 err = snd_hda_codec_new(chip->bus, c, &codec); 1434 err = snd_hda_codec_new(chip->bus, c, &codec);
1405 if (err < 0) 1435 if (err < 0)
1406 continue; 1436 continue;
1437 codec->beep_mode = chip->beep_mode;
1407 codecs++; 1438 codecs++;
1408 } 1439 }
1409 } 1440 }
@@ -1430,10 +1461,13 @@ static int __devinit azx_codec_configure(struct azx *chip)
1430 */ 1461 */
1431 1462
1432/* assign a stream for the PCM */ 1463/* assign a stream for the PCM */
1433static inline struct azx_dev *azx_assign_device(struct azx *chip, int stream) 1464static inline struct azx_dev *
1465azx_assign_device(struct azx *chip, struct snd_pcm_substream *substream)
1434{ 1466{
1435 int dev, i, nums; 1467 int dev, i, nums;
1436 if (stream == SNDRV_PCM_STREAM_PLAYBACK) { 1468 struct azx_dev *res = NULL;
1469
1470 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1437 dev = chip->playback_index_offset; 1471 dev = chip->playback_index_offset;
1438 nums = chip->playback_streams; 1472 nums = chip->playback_streams;
1439 } else { 1473 } else {
@@ -1442,10 +1476,15 @@ static inline struct azx_dev *azx_assign_device(struct azx *chip, int stream)
1442 } 1476 }
1443 for (i = 0; i < nums; i++, dev++) 1477 for (i = 0; i < nums; i++, dev++)
1444 if (!chip->azx_dev[dev].opened) { 1478 if (!chip->azx_dev[dev].opened) {
1445 chip->azx_dev[dev].opened = 1; 1479 res = &chip->azx_dev[dev];
1446 return &chip->azx_dev[dev]; 1480 if (res->device == substream->pcm->device)
1481 break;
1447 } 1482 }
1448 return NULL; 1483 if (res) {
1484 res->opened = 1;
1485 res->device = substream->pcm->device;
1486 }
1487 return res;
1449} 1488}
1450 1489
1451/* release the assigned stream */ 1490/* release the assigned stream */
@@ -1494,7 +1533,7 @@ static int azx_pcm_open(struct snd_pcm_substream *substream)
1494 int err; 1533 int err;
1495 1534
1496 mutex_lock(&chip->open_mutex); 1535 mutex_lock(&chip->open_mutex);
1497 azx_dev = azx_assign_device(chip, substream->stream); 1536 azx_dev = azx_assign_device(chip, substream);
1498 if (azx_dev == NULL) { 1537 if (azx_dev == NULL) {
1499 mutex_unlock(&chip->open_mutex); 1538 mutex_unlock(&chip->open_mutex);
1500 return -EBUSY; 1539 return -EBUSY;
@@ -1858,6 +1897,9 @@ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev)
1858 1897
1859 if (!bdl_pos_adj[chip->dev_index]) 1898 if (!bdl_pos_adj[chip->dev_index])
1860 return 1; /* no delayed ack */ 1899 return 1; /* no delayed ack */
1900 if (WARN_ONCE(!azx_dev->period_bytes,
1901 "hda-intel: zero azx_dev->period_bytes"))
1902 return 0; /* this shouldn't happen! */
1861 if (pos % azx_dev->period_bytes > azx_dev->period_bytes / 2) 1903 if (pos % azx_dev->period_bytes > azx_dev->period_bytes / 2)
1862 return 0; /* NG - it's below the period boundary */ 1904 return 0; /* NG - it's below the period boundary */
1863 return 1; /* OK, it's fine */ 1905 return 1; /* OK, it's fine */
@@ -1945,7 +1987,7 @@ azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
1945 int pcm_dev = cpcm->device; 1987 int pcm_dev = cpcm->device;
1946 int s, err; 1988 int s, err;
1947 1989
1948 if (pcm_dev >= AZX_MAX_PCMS) { 1990 if (pcm_dev >= HDA_MAX_PCMS) {
1949 snd_printk(KERN_ERR SFX "Invalid PCM device number %d\n", 1991 snd_printk(KERN_ERR SFX "Invalid PCM device number %d\n",
1950 pcm_dev); 1992 pcm_dev);
1951 return -EINVAL; 1993 return -EINVAL;
@@ -2023,7 +2065,7 @@ static int azx_acquire_irq(struct azx *chip, int do_disconnect)
2023{ 2065{
2024 if (request_irq(chip->pci->irq, azx_interrupt, 2066 if (request_irq(chip->pci->irq, azx_interrupt,
2025 chip->msi ? 0 : IRQF_SHARED, 2067 chip->msi ? 0 : IRQF_SHARED,
2026 "HDA Intel", chip)) { 2068 "hda_intel", chip)) {
2027 printk(KERN_ERR "hda-intel: unable to grab IRQ %d, " 2069 printk(KERN_ERR "hda-intel: unable to grab IRQ %d, "
2028 "disabling device\n", chip->pci->irq); 2070 "disabling device\n", chip->pci->irq);
2029 if (do_disconnect) 2071 if (do_disconnect)
@@ -2071,7 +2113,8 @@ static void azx_power_notify(struct hda_bus *bus)
2071 } 2113 }
2072 if (power_on) 2114 if (power_on)
2073 azx_init_chip(chip); 2115 azx_init_chip(chip);
2074 else if (chip->running && power_save_controller) 2116 else if (chip->running && power_save_controller &&
2117 !bus->power_keep_link_on)
2075 azx_stop_chip(chip); 2118 azx_stop_chip(chip);
2076} 2119}
2077#endif /* CONFIG_SND_HDA_POWER_SAVE */ 2120#endif /* CONFIG_SND_HDA_POWER_SAVE */
@@ -2100,7 +2143,7 @@ static int azx_suspend(struct pci_dev *pci, pm_message_t state)
2100 2143
2101 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); 2144 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
2102 azx_clear_irq_pending(chip); 2145 azx_clear_irq_pending(chip);
2103 for (i = 0; i < AZX_MAX_PCMS; i++) 2146 for (i = 0; i < HDA_MAX_PCMS; i++)
2104 snd_pcm_suspend_all(chip->pcm[i]); 2147 snd_pcm_suspend_all(chip->pcm[i]);
2105 if (chip->initialized) 2148 if (chip->initialized)
2106 snd_hda_suspend(chip->bus); 2149 snd_hda_suspend(chip->bus);
@@ -2154,6 +2197,7 @@ static int azx_resume(struct pci_dev *pci)
2154static int azx_halt(struct notifier_block *nb, unsigned long event, void *buf) 2197static int azx_halt(struct notifier_block *nb, unsigned long event, void *buf)
2155{ 2198{
2156 struct azx *chip = container_of(nb, struct azx, reboot_notifier); 2199 struct azx *chip = container_of(nb, struct azx, reboot_notifier);
2200 snd_hda_bus_reboot_notify(chip->bus);
2157 azx_stop_chip(chip); 2201 azx_stop_chip(chip);
2158 return NOTIFY_OK; 2202 return NOTIFY_OK;
2159} 2203}
@@ -2221,7 +2265,16 @@ static int azx_dev_free(struct snd_device *device)
2221static struct snd_pci_quirk position_fix_list[] __devinitdata = { 2265static struct snd_pci_quirk position_fix_list[] __devinitdata = {
2222 SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB), 2266 SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB),
2223 SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB), 2267 SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB),
2268 SND_PCI_QUIRK(0x1028, 0x01f6, "Dell Latitude 131L", POS_FIX_LPIB),
2269 SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB),
2270 SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB),
2224 SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB), 2271 SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB),
2272 SND_PCI_QUIRK(0x1458, 0xa022, "ga-ma770-ud3", POS_FIX_LPIB),
2273 SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB),
2274 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar Microtech", POS_FIX_LPIB),
2275 SND_PCI_QUIRK(0x1565, 0x8218, "Biostar Microtech", POS_FIX_LPIB),
2276 SND_PCI_QUIRK(0x8086, 0x2503, "DG965OT AAD63733-203", POS_FIX_LPIB),
2277 SND_PCI_QUIRK(0x8086, 0xd601, "eMachines T5212", POS_FIX_LPIB),
2225 {} 2278 {}
2226}; 2279};
2227 2280
@@ -2304,11 +2357,14 @@ static void __devinit check_probe_mask(struct azx *chip, int dev)
2304} 2357}
2305 2358
2306/* 2359/*
2307 * white-list for enable_msi 2360 * white/black-list for enable_msi
2308 */ 2361 */
2309static struct snd_pci_quirk msi_white_list[] __devinitdata = { 2362static struct snd_pci_quirk msi_black_list[] __devinitdata = {
2310 SND_PCI_QUIRK(0x103c, 0x30f7, "HP Pavilion dv4t-1300", 1), 2363 SND_PCI_QUIRK(0x1043, 0x81f2, "ASUS", 0), /* Athlon64 X2 + nvidia */
2311 SND_PCI_QUIRK(0x103c, 0x3607, "HP Compa CQ40", 1), 2364 SND_PCI_QUIRK(0x1043, 0x81f6, "ASUS", 0), /* nvidia */
2365 SND_PCI_QUIRK(0x1043, 0x822d, "ASUS", 0), /* Athlon64 X2 + nvidia MCP55 */
2366 SND_PCI_QUIRK(0x1849, 0x0888, "ASRock", 0), /* Athlon64 X2 + nvidia */
2367 SND_PCI_QUIRK(0xa0a0, 0x0575, "Aopen MZ915-M", 0), /* ICH6 */
2312 {} 2368 {}
2313}; 2369};
2314 2370
@@ -2316,15 +2372,24 @@ static void __devinit check_msi(struct azx *chip)
2316{ 2372{
2317 const struct snd_pci_quirk *q; 2373 const struct snd_pci_quirk *q;
2318 2374
2319 chip->msi = enable_msi; 2375 if (enable_msi >= 0) {
2320 if (chip->msi) 2376 chip->msi = !!enable_msi;
2321 return; 2377 return;
2322 q = snd_pci_quirk_lookup(chip->pci, msi_white_list); 2378 }
2379 chip->msi = 1; /* enable MSI as default */
2380 q = snd_pci_quirk_lookup(chip->pci, msi_black_list);
2323 if (q) { 2381 if (q) {
2324 printk(KERN_INFO 2382 printk(KERN_INFO
2325 "hda_intel: msi for device %04x:%04x set to %d\n", 2383 "hda_intel: msi for device %04x:%04x set to %d\n",
2326 q->subvendor, q->subdevice, q->value); 2384 q->subvendor, q->subdevice, q->value);
2327 chip->msi = q->value; 2385 chip->msi = q->value;
2386 return;
2387 }
2388
2389 /* NVidia chipsets seem to cause troubles with MSI */
2390 if (chip->driver_type == AZX_DRIVER_NVIDIA) {
2391 printk(KERN_INFO "hda_intel: Disable MSI for Nvidia chipset\n");
2392 chip->msi = 0;
2328 } 2393 }
2329} 2394}
2330 2395
@@ -2374,6 +2439,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
2374 if (bdl_pos_adj[dev] < 0) { 2439 if (bdl_pos_adj[dev] < 0) {
2375 switch (chip->driver_type) { 2440 switch (chip->driver_type) {
2376 case AZX_DRIVER_ICH: 2441 case AZX_DRIVER_ICH:
2442 case AZX_DRIVER_PCH:
2377 bdl_pos_adj[dev] = 1; 2443 bdl_pos_adj[dev] = 1;
2378 break; 2444 break;
2379 default: 2445 default:
@@ -2436,6 +2502,11 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
2436 } 2502 }
2437 } 2503 }
2438 2504
2505 /* disable 64bit DMA address for Teradici */
2506 /* it does not work with device 6549:1200 subsys e4a2:040b */
2507 if (chip->driver_type == AZX_DRIVER_TERA)
2508 gcap &= ~ICH6_GCAP_64OK;
2509
2439 /* allow 64bit DMA address if supported by H/W */ 2510 /* allow 64bit DMA address if supported by H/W */
2440 if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64))) 2511 if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64)))
2441 pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(64)); 2512 pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(64));
@@ -2578,6 +2649,10 @@ static int __devinit azx_probe(struct pci_dev *pci,
2578 goto out_free; 2649 goto out_free;
2579 card->private_data = chip; 2650 card->private_data = chip;
2580 2651
2652#ifdef CONFIG_SND_HDA_INPUT_BEEP
2653 chip->beep_mode = beep_mode[dev];
2654#endif
2655
2581 /* create codec instances */ 2656 /* create codec instances */
2582 err = azx_codec_create(chip, model[dev]); 2657 err = azx_codec_create(chip, model[dev]);
2583 if (err < 0) 2658 if (err < 0)
@@ -2630,7 +2705,7 @@ static void __devexit azx_remove(struct pci_dev *pci)
2630} 2705}
2631 2706
2632/* PCI IDs */ 2707/* PCI IDs */
2633static struct pci_device_id azx_ids[] = { 2708static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
2634 /* ICH 6..10 */ 2709 /* ICH 6..10 */
2635 { PCI_DEVICE(0x8086, 0x2668), .driver_data = AZX_DRIVER_ICH }, 2710 { PCI_DEVICE(0x8086, 0x2668), .driver_data = AZX_DRIVER_ICH },
2636 { PCI_DEVICE(0x8086, 0x27d8), .driver_data = AZX_DRIVER_ICH }, 2711 { PCI_DEVICE(0x8086, 0x27d8), .driver_data = AZX_DRIVER_ICH },
@@ -2643,6 +2718,9 @@ static struct pci_device_id azx_ids[] = {
2643 { PCI_DEVICE(0x8086, 0x3a6e), .driver_data = AZX_DRIVER_ICH }, 2718 { PCI_DEVICE(0x8086, 0x3a6e), .driver_data = AZX_DRIVER_ICH },
2644 /* PCH */ 2719 /* PCH */
2645 { PCI_DEVICE(0x8086, 0x3b56), .driver_data = AZX_DRIVER_ICH }, 2720 { PCI_DEVICE(0x8086, 0x3b56), .driver_data = AZX_DRIVER_ICH },
2721 { PCI_DEVICE(0x8086, 0x3b57), .driver_data = AZX_DRIVER_ICH },
2722 /* CPT */
2723 { PCI_DEVICE(0x8086, 0x1c20), .driver_data = AZX_DRIVER_PCH },
2646 /* SCH */ 2724 /* SCH */
2647 { PCI_DEVICE(0x8086, 0x811b), .driver_data = AZX_DRIVER_SCH }, 2725 { PCI_DEVICE(0x8086, 0x811b), .driver_data = AZX_DRIVER_SCH },
2648 /* ATI SB 450/600 */ 2726 /* ATI SB 450/600 */
@@ -2670,29 +2748,10 @@ static struct pci_device_id azx_ids[] = {
2670 /* ULI M5461 */ 2748 /* ULI M5461 */
2671 { PCI_DEVICE(0x10b9, 0x5461), .driver_data = AZX_DRIVER_ULI }, 2749 { PCI_DEVICE(0x10b9, 0x5461), .driver_data = AZX_DRIVER_ULI },
2672 /* NVIDIA MCP */ 2750 /* NVIDIA MCP */
2673 { PCI_DEVICE(0x10de, 0x026c), .driver_data = AZX_DRIVER_NVIDIA }, 2751 { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID),
2674 { PCI_DEVICE(0x10de, 0x0371), .driver_data = AZX_DRIVER_NVIDIA }, 2752 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
2675 { PCI_DEVICE(0x10de, 0x03e4), .driver_data = AZX_DRIVER_NVIDIA }, 2753 .class_mask = 0xffffff,
2676 { PCI_DEVICE(0x10de, 0x03f0), .driver_data = AZX_DRIVER_NVIDIA }, 2754 .driver_data = AZX_DRIVER_NVIDIA },
2677 { PCI_DEVICE(0x10de, 0x044a), .driver_data = AZX_DRIVER_NVIDIA },
2678 { PCI_DEVICE(0x10de, 0x044b), .driver_data = AZX_DRIVER_NVIDIA },
2679 { PCI_DEVICE(0x10de, 0x055c), .driver_data = AZX_DRIVER_NVIDIA },
2680 { PCI_DEVICE(0x10de, 0x055d), .driver_data = AZX_DRIVER_NVIDIA },
2681 { PCI_DEVICE(0x10de, 0x0590), .driver_data = AZX_DRIVER_NVIDIA },
2682 { PCI_DEVICE(0x10de, 0x0774), .driver_data = AZX_DRIVER_NVIDIA },
2683 { PCI_DEVICE(0x10de, 0x0775), .driver_data = AZX_DRIVER_NVIDIA },
2684 { PCI_DEVICE(0x10de, 0x0776), .driver_data = AZX_DRIVER_NVIDIA },
2685 { PCI_DEVICE(0x10de, 0x0777), .driver_data = AZX_DRIVER_NVIDIA },
2686 { PCI_DEVICE(0x10de, 0x07fc), .driver_data = AZX_DRIVER_NVIDIA },
2687 { PCI_DEVICE(0x10de, 0x07fd), .driver_data = AZX_DRIVER_NVIDIA },
2688 { PCI_DEVICE(0x10de, 0x0ac0), .driver_data = AZX_DRIVER_NVIDIA },
2689 { PCI_DEVICE(0x10de, 0x0ac1), .driver_data = AZX_DRIVER_NVIDIA },
2690 { PCI_DEVICE(0x10de, 0x0ac2), .driver_data = AZX_DRIVER_NVIDIA },
2691 { PCI_DEVICE(0x10de, 0x0ac3), .driver_data = AZX_DRIVER_NVIDIA },
2692 { PCI_DEVICE(0x10de, 0x0d94), .driver_data = AZX_DRIVER_NVIDIA },
2693 { PCI_DEVICE(0x10de, 0x0d95), .driver_data = AZX_DRIVER_NVIDIA },
2694 { PCI_DEVICE(0x10de, 0x0d96), .driver_data = AZX_DRIVER_NVIDIA },
2695 { PCI_DEVICE(0x10de, 0x0d97), .driver_data = AZX_DRIVER_NVIDIA },
2696 /* Teradici */ 2755 /* Teradici */
2697 { PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA }, 2756 { PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA },
2698 /* Creative X-Fi (CA0110-IBG) */ 2757 /* Creative X-Fi (CA0110-IBG) */
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 5f1dcc59002b..7cee364976ff 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -23,6 +23,16 @@
23#ifndef __SOUND_HDA_LOCAL_H 23#ifndef __SOUND_HDA_LOCAL_H
24#define __SOUND_HDA_LOCAL_H 24#define __SOUND_HDA_LOCAL_H
25 25
26/* We abuse kcontrol_new.subdev field to pass the NID corresponding to
27 * the given new control. If id.subdev has a bit flag HDA_SUBDEV_NID_FLAG,
28 * snd_hda_ctl_add() takes the lower-bit subdev value as a valid NID.
29 *
30 * Note that the subdevice field is cleared again before the real registration
31 * in snd_hda_ctl_add(), so that this value won't appear in the outside.
32 */
33#define HDA_SUBDEV_NID_FLAG (1U << 31)
34#define HDA_SUBDEV_AMP_FLAG (1U << 30)
35
26/* 36/*
27 * for mixer controls 37 * for mixer controls
28 */ 38 */
@@ -33,6 +43,7 @@
33/* mono volume with index (index=0,1,...) (channel=1,2) */ 43/* mono volume with index (index=0,1,...) (channel=1,2) */
34#define HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \ 44#define HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \
35 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ 45 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \
46 .subdevice = HDA_SUBDEV_AMP_FLAG, \
36 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \ 47 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
37 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ 48 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
38 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, \ 49 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, \
@@ -53,6 +64,7 @@
53/* mono mute switch with index (index=0,1,...) (channel=1,2) */ 64/* mono mute switch with index (index=0,1,...) (channel=1,2) */
54#define HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \ 65#define HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \
55 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ 66 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \
67 .subdevice = HDA_SUBDEV_AMP_FLAG, \
56 .info = snd_hda_mixer_amp_switch_info, \ 68 .info = snd_hda_mixer_amp_switch_info, \
57 .get = snd_hda_mixer_amp_switch_get, \ 69 .get = snd_hda_mixer_amp_switch_get, \
58 .put = snd_hda_mixer_amp_switch_put, \ 70 .put = snd_hda_mixer_amp_switch_put, \
@@ -66,6 +78,28 @@
66/* stereo mute switch */ 78/* stereo mute switch */
67#define HDA_CODEC_MUTE(xname, nid, xindex, direction) \ 79#define HDA_CODEC_MUTE(xname, nid, xindex, direction) \
68 HDA_CODEC_MUTE_MONO(xname, nid, 3, xindex, direction) 80 HDA_CODEC_MUTE_MONO(xname, nid, 3, xindex, direction)
81#ifdef CONFIG_SND_HDA_INPUT_BEEP
82/* special beep mono mute switch with index (index=0,1,...) (channel=1,2) */
83#define HDA_CODEC_MUTE_BEEP_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \
84 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \
85 .subdevice = HDA_SUBDEV_AMP_FLAG, \
86 .info = snd_hda_mixer_amp_switch_info, \
87 .get = snd_hda_mixer_amp_switch_get, \
88 .put = snd_hda_mixer_amp_switch_put_beep, \
89 .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) }
90#else
91/* no digital beep - just the standard one */
92#define HDA_CODEC_MUTE_BEEP_MONO_IDX(xname, xcidx, nid, ch, xidx, dir) \
93 HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, ch, xidx, dir)
94#endif /* CONFIG_SND_HDA_INPUT_BEEP */
95/* special beep mono mute switch */
96#define HDA_CODEC_MUTE_BEEP_MONO(xname, nid, channel, xindex, direction) \
97 HDA_CODEC_MUTE_BEEP_MONO_IDX(xname, 0, nid, channel, xindex, direction)
98/* special beep stereo mute switch */
99#define HDA_CODEC_MUTE_BEEP(xname, nid, xindex, direction) \
100 HDA_CODEC_MUTE_BEEP_MONO(xname, nid, 3, xindex, direction)
101
102extern const char *snd_hda_pcm_type_name[];
69 103
70int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, 104int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol,
71 struct snd_ctl_elem_info *uinfo); 105 struct snd_ctl_elem_info *uinfo);
@@ -81,6 +115,10 @@ int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol,
81 struct snd_ctl_elem_value *ucontrol); 115 struct snd_ctl_elem_value *ucontrol);
82int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, 116int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol,
83 struct snd_ctl_elem_value *ucontrol); 117 struct snd_ctl_elem_value *ucontrol);
118#ifdef CONFIG_SND_HDA_INPUT_BEEP
119int snd_hda_mixer_amp_switch_put_beep(struct snd_kcontrol *kcontrol,
120 struct snd_ctl_elem_value *ucontrol);
121#endif
84/* lowlevel accessor with caching; use carefully */ 122/* lowlevel accessor with caching; use carefully */
85int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch, 123int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch,
86 int direction, int index); 124 int direction, int index);
@@ -424,8 +462,23 @@ u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction);
424int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir, 462int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
425 unsigned int caps); 463 unsigned int caps);
426u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid); 464u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid);
465u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid);
466int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid);
427 467
428int snd_hda_ctl_add(struct hda_codec *codec, struct snd_kcontrol *kctl); 468/* flags for hda_nid_item */
469#define HDA_NID_ITEM_AMP (1<<0)
470
471struct hda_nid_item {
472 struct snd_kcontrol *kctl;
473 unsigned int index;
474 hda_nid_t nid;
475 unsigned short flags;
476};
477
478int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid,
479 struct snd_kcontrol *kctl);
480int snd_hda_add_nid(struct hda_codec *codec, struct snd_kcontrol *kctl,
481 unsigned int index, hda_nid_t nid);
429void snd_hda_ctls_clear(struct hda_codec *codec); 482void snd_hda_ctls_clear(struct hda_codec *codec);
430 483
431/* 484/*
@@ -437,6 +490,15 @@ int snd_hda_create_hwdep(struct hda_codec *codec);
437static inline int snd_hda_create_hwdep(struct hda_codec *codec) { return 0; } 490static inline int snd_hda_create_hwdep(struct hda_codec *codec) { return 0; }
438#endif 491#endif
439 492
493#if defined(CONFIG_SND_HDA_POWER_SAVE) && defined(CONFIG_SND_HDA_HWDEP)
494int snd_hda_hwdep_add_power_sysfs(struct hda_codec *codec);
495#else
496static inline int snd_hda_hwdep_add_power_sysfs(struct hda_codec *codec)
497{
498 return 0;
499}
500#endif
501
440#ifdef CONFIG_SND_HDA_RECONFIG 502#ifdef CONFIG_SND_HDA_RECONFIG
441int snd_hda_hwdep_add_sysfs(struct hda_codec *codec); 503int snd_hda_hwdep_add_sysfs(struct hda_codec *codec);
442#else 504#else
@@ -490,7 +552,8 @@ int snd_hda_check_amp_list_power(struct hda_codec *codec,
490 * AMP control callbacks 552 * AMP control callbacks
491 */ 553 */
492/* retrieve parameters from private_value */ 554/* retrieve parameters from private_value */
493#define get_amp_nid(kc) ((kc)->private_value & 0xffff) 555#define get_amp_nid_(pv) ((pv) & 0xffff)
556#define get_amp_nid(kc) get_amp_nid_((kc)->private_value)
494#define get_amp_channels(kc) (((kc)->private_value >> 16) & 0x3) 557#define get_amp_channels(kc) (((kc)->private_value >> 16) & 0x3)
495#define get_amp_direction(kc) (((kc)->private_value >> 18) & 0x1) 558#define get_amp_direction(kc) (((kc)->private_value >> 18) & 0x1)
496#define get_amp_index(kc) (((kc)->private_value >> 19) & 0xf) 559#define get_amp_index(kc) (((kc)->private_value >> 19) & 0xf)
@@ -516,9 +579,11 @@ struct cea_sad {
516 * ELD: EDID Like Data 579 * ELD: EDID Like Data
517 */ 580 */
518struct hdmi_eld { 581struct hdmi_eld {
582 bool monitor_present;
583 bool eld_valid;
519 int eld_size; 584 int eld_size;
520 int baseline_len; 585 int baseline_len;
521 int eld_ver; /* (eld_ver == 0) indicates invalid ELD */ 586 int eld_ver;
522 int cea_edid_ver; 587 int cea_edid_ver;
523 char monitor_name[ELD_MAX_MNL + 1]; 588 char monitor_name[ELD_MAX_MNL + 1];
524 int manufacture_id; 589 int manufacture_id;
@@ -541,11 +606,13 @@ int snd_hdmi_get_eld(struct hdmi_eld *, struct hda_codec *, hda_nid_t);
541void snd_hdmi_show_eld(struct hdmi_eld *eld); 606void snd_hdmi_show_eld(struct hdmi_eld *eld);
542 607
543#ifdef CONFIG_PROC_FS 608#ifdef CONFIG_PROC_FS
544int snd_hda_eld_proc_new(struct hda_codec *codec, struct hdmi_eld *eld); 609int snd_hda_eld_proc_new(struct hda_codec *codec, struct hdmi_eld *eld,
610 int index);
545void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld); 611void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld);
546#else 612#else
547static inline int snd_hda_eld_proc_new(struct hda_codec *codec, 613static inline int snd_hda_eld_proc_new(struct hda_codec *codec,
548 struct hdmi_eld *eld) 614 struct hdmi_eld *eld,
615 int index)
549{ 616{
550 return 0; 617 return 0;
551} 618}
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
index 95f24e4729f8..f97d35de66c4 100644
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -26,6 +26,21 @@
26#include "hda_codec.h" 26#include "hda_codec.h"
27#include "hda_local.h" 27#include "hda_local.h"
28 28
29static char *bits_names(unsigned int bits, char *names[], int size)
30{
31 int i, n;
32 static char buf[128];
33
34 for (i = 0, n = 0; i < size; i++) {
35 if (bits & (1U<<i) && names[i])
36 n += snprintf(buf + n, sizeof(buf) - n, " %s",
37 names[i]);
38 }
39 buf[n] = '\0';
40
41 return buf;
42}
43
29static const char *get_wid_type_name(unsigned int wid_value) 44static const char *get_wid_type_name(unsigned int wid_value)
30{ 45{
31 static char *names[16] = { 46 static char *names[16] = {
@@ -46,6 +61,52 @@ static const char *get_wid_type_name(unsigned int wid_value)
46 return "UNKNOWN Widget"; 61 return "UNKNOWN Widget";
47} 62}
48 63
64static void print_nid_array(struct snd_info_buffer *buffer,
65 struct hda_codec *codec, hda_nid_t nid,
66 struct snd_array *array)
67{
68 int i;
69 struct hda_nid_item *items = array->list, *item;
70 struct snd_kcontrol *kctl;
71 for (i = 0; i < array->used; i++) {
72 item = &items[i];
73 if (item->nid == nid) {
74 kctl = item->kctl;
75 snd_iprintf(buffer,
76 " Control: name=\"%s\", index=%i, device=%i\n",
77 kctl->id.name, kctl->id.index + item->index,
78 kctl->id.device);
79 if (item->flags & HDA_NID_ITEM_AMP)
80 snd_iprintf(buffer,
81 " ControlAmp: chs=%lu, dir=%s, "
82 "idx=%lu, ofs=%lu\n",
83 get_amp_channels(kctl),
84 get_amp_direction(kctl) ? "Out" : "In",
85 get_amp_index(kctl),
86 get_amp_offset(kctl));
87 }
88 }
89}
90
91static void print_nid_pcms(struct snd_info_buffer *buffer,
92 struct hda_codec *codec, hda_nid_t nid)
93{
94 int pcm, type;
95 struct hda_pcm *cpcm;
96 for (pcm = 0; pcm < codec->num_pcms; pcm++) {
97 cpcm = &codec->pcm_info[pcm];
98 for (type = 0; type < 2; type++) {
99 if (cpcm->stream[type].nid != nid || cpcm->pcm == NULL)
100 continue;
101 snd_iprintf(buffer, " Device: name=\"%s\", "
102 "type=\"%s\", device=%i\n",
103 cpcm->name,
104 snd_hda_pcm_type_name[cpcm->pcm_type],
105 cpcm->pcm->device);
106 }
107 }
108}
109
49static void print_amp_caps(struct snd_info_buffer *buffer, 110static void print_amp_caps(struct snd_info_buffer *buffer,
50 struct hda_codec *codec, hda_nid_t nid, int dir) 111 struct hda_codec *codec, hda_nid_t nid, int dir)
51{ 112{
@@ -190,9 +251,14 @@ static void print_pin_caps(struct snd_info_buffer *buffer,
190 /* Realtek uses this bit as a different meaning */ 251 /* Realtek uses this bit as a different meaning */
191 if ((codec->vendor_id >> 16) == 0x10ec) 252 if ((codec->vendor_id >> 16) == 0x10ec)
192 snd_iprintf(buffer, " R/L"); 253 snd_iprintf(buffer, " R/L");
193 else 254 else {
255 if (caps & AC_PINCAP_HBR)
256 snd_iprintf(buffer, " HBR");
194 snd_iprintf(buffer, " HDMI"); 257 snd_iprintf(buffer, " HDMI");
258 }
195 } 259 }
260 if (caps & AC_PINCAP_DP)
261 snd_iprintf(buffer, " DP");
196 if (caps & AC_PINCAP_TRIG_REQ) 262 if (caps & AC_PINCAP_TRIG_REQ)
197 snd_iprintf(buffer, " Trigger"); 263 snd_iprintf(buffer, " Trigger");
198 if (caps & AC_PINCAP_IMP_SENSE) 264 if (caps & AC_PINCAP_IMP_SENSE)
@@ -363,8 +429,24 @@ static const char *get_pwr_state(u32 state)
363static void print_power_state(struct snd_info_buffer *buffer, 429static void print_power_state(struct snd_info_buffer *buffer,
364 struct hda_codec *codec, hda_nid_t nid) 430 struct hda_codec *codec, hda_nid_t nid)
365{ 431{
432 static char *names[] = {
433 [ilog2(AC_PWRST_D0SUP)] = "D0",
434 [ilog2(AC_PWRST_D1SUP)] = "D1",
435 [ilog2(AC_PWRST_D2SUP)] = "D2",
436 [ilog2(AC_PWRST_D3SUP)] = "D3",
437 [ilog2(AC_PWRST_D3COLDSUP)] = "D3cold",
438 [ilog2(AC_PWRST_S3D3COLDSUP)] = "S3D3cold",
439 [ilog2(AC_PWRST_CLKSTOP)] = "CLKSTOP",
440 [ilog2(AC_PWRST_EPSS)] = "EPSS",
441 };
442
443 int sup = snd_hda_param_read(codec, nid, AC_PAR_POWER_STATE);
366 int pwr = snd_hda_codec_read(codec, nid, 0, 444 int pwr = snd_hda_codec_read(codec, nid, 0,
367 AC_VERB_GET_POWER_STATE, 0); 445 AC_VERB_GET_POWER_STATE, 0);
446 if (sup)
447 snd_iprintf(buffer, " Power states: %s\n",
448 bits_names(sup, names, ARRAY_SIZE(names)));
449
368 snd_iprintf(buffer, " Power: setting=%s, actual=%s\n", 450 snd_iprintf(buffer, " Power: setting=%s, actual=%s\n",
369 get_pwr_state(pwr & AC_PWRST_SETTING), 451 get_pwr_state(pwr & AC_PWRST_SETTING),
370 get_pwr_state((pwr & AC_PWRST_ACTUAL) >> 452 get_pwr_state((pwr & AC_PWRST_ACTUAL) >>
@@ -457,6 +539,8 @@ static void print_gpio(struct snd_info_buffer *buffer,
457 (data & (1<<i)) ? 1 : 0, 539 (data & (1<<i)) ? 1 : 0,
458 (unsol & (1<<i)) ? 1 : 0); 540 (unsol & (1<<i)) ? 1 : 0);
459 /* FIXME: add GPO and GPI pin information */ 541 /* FIXME: add GPO and GPI pin information */
542 print_nid_array(buffer, codec, nid, &codec->mixers);
543 print_nid_array(buffer, codec, nid, &codec->nids);
460} 544}
461 545
462static void print_codec_info(struct snd_info_entry *entry, 546static void print_codec_info(struct snd_info_entry *entry,
@@ -536,6 +620,10 @@ static void print_codec_info(struct snd_info_entry *entry,
536 snd_iprintf(buffer, " CP"); 620 snd_iprintf(buffer, " CP");
537 snd_iprintf(buffer, "\n"); 621 snd_iprintf(buffer, "\n");
538 622
623 print_nid_array(buffer, codec, nid, &codec->mixers);
624 print_nid_array(buffer, codec, nid, &codec->nids);
625 print_nid_pcms(buffer, codec, nid);
626
539 /* volume knob is a special widget that always have connection 627 /* volume knob is a special widget that always have connection
540 * list 628 * list
541 */ 629 */
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 2d603f6aba63..e9fdfc4b1c57 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -72,7 +72,8 @@ struct ad198x_spec {
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; 75 unsigned int inv_jack_detect:1; /* inverted jack-detection */
76 unsigned int inv_eapd:1; /* inverted EAPD implementation */
76 77
77#ifdef CONFIG_SND_HDA_POWER_SAVE 78#ifdef CONFIG_SND_HDA_POWER_SAVE
78 struct hda_loopback_check loopback; 79 struct hda_loopback_check loopback;
@@ -156,19 +157,24 @@ static const char *ad_slave_sws[] = {
156 157
157static void ad198x_free_kctls(struct hda_codec *codec); 158static void ad198x_free_kctls(struct hda_codec *codec);
158 159
160#ifdef CONFIG_SND_HDA_INPUT_BEEP
159/* additional beep mixers; the actual parameters are overwritten at build */ 161/* additional beep mixers; the actual parameters are overwritten at build */
160static struct snd_kcontrol_new ad_beep_mixer[] = { 162static struct snd_kcontrol_new ad_beep_mixer[] = {
161 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_OUTPUT), 163 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_OUTPUT),
162 HDA_CODEC_MUTE("Beep Playback Switch", 0, 0, HDA_OUTPUT), 164 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_OUTPUT),
163 { } /* end */ 165 { } /* end */
164}; 166};
165 167
166#define set_beep_amp(spec, nid, idx, dir) \ 168#define set_beep_amp(spec, nid, idx, dir) \
167 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir)) /* mono */ 169 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir)) /* mono */
170#else
171#define set_beep_amp(spec, nid, idx, dir) /* NOP */
172#endif
168 173
169static int ad198x_build_controls(struct hda_codec *codec) 174static int ad198x_build_controls(struct hda_codec *codec)
170{ 175{
171 struct ad198x_spec *spec = codec->spec; 176 struct ad198x_spec *spec = codec->spec;
177 struct snd_kcontrol *kctl;
172 unsigned int i; 178 unsigned int i;
173 int err; 179 int err;
174 180
@@ -194,6 +200,7 @@ static int ad198x_build_controls(struct hda_codec *codec)
194 } 200 }
195 201
196 /* create beep controls if needed */ 202 /* create beep controls if needed */
203#ifdef CONFIG_SND_HDA_INPUT_BEEP
197 if (spec->beep_amp) { 204 if (spec->beep_amp) {
198 struct snd_kcontrol_new *knew; 205 struct snd_kcontrol_new *knew;
199 for (knew = ad_beep_mixer; knew->name; knew++) { 206 for (knew = ad_beep_mixer; knew->name; knew++) {
@@ -202,11 +209,12 @@ static int ad198x_build_controls(struct hda_codec *codec)
202 if (!kctl) 209 if (!kctl)
203 return -ENOMEM; 210 return -ENOMEM;
204 kctl->private_value = spec->beep_amp; 211 kctl->private_value = spec->beep_amp;
205 err = snd_hda_ctl_add(codec, kctl); 212 err = snd_hda_ctl_add(codec, 0, kctl);
206 if (err < 0) 213 if (err < 0)
207 return err; 214 return err;
208 } 215 }
209 } 216 }
217#endif
210 218
211 /* if we have no master control, let's create it */ 219 /* if we have no master control, let's create it */
212 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) { 220 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
@@ -230,6 +238,27 @@ static int ad198x_build_controls(struct hda_codec *codec)
230 } 238 }
231 239
232 ad198x_free_kctls(codec); /* no longer needed */ 240 ad198x_free_kctls(codec); /* no longer needed */
241
242 /* assign Capture Source enums to NID */
243 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
244 if (!kctl)
245 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
246 for (i = 0; kctl && i < kctl->count; i++) {
247 err = snd_hda_add_nid(codec, kctl, i, spec->capsrc_nids[i]);
248 if (err < 0)
249 return err;
250 }
251
252 /* assign IEC958 enums to NID */
253 kctl = snd_hda_find_mixer_ctl(codec,
254 SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source");
255 if (kctl) {
256 err = snd_hda_add_nid(codec, kctl, 0,
257 spec->multiout.dig_out_nid);
258 if (err < 0)
259 return err;
260 }
261
233 return 0; 262 return 0;
234} 263}
235 264
@@ -412,6 +441,11 @@ static int ad198x_build_pcms(struct hda_codec *codec)
412 return 0; 441 return 0;
413} 442}
414 443
444static inline void ad198x_shutup(struct hda_codec *codec)
445{
446 snd_hda_shutup_pins(codec);
447}
448
415static void ad198x_free_kctls(struct hda_codec *codec) 449static void ad198x_free_kctls(struct hda_codec *codec)
416{ 450{
417 struct ad198x_spec *spec = codec->spec; 451 struct ad198x_spec *spec = codec->spec;
@@ -425,6 +459,46 @@ static void ad198x_free_kctls(struct hda_codec *codec)
425 snd_array_free(&spec->kctls); 459 snd_array_free(&spec->kctls);
426} 460}
427 461
462static void ad198x_power_eapd_write(struct hda_codec *codec, hda_nid_t front,
463 hda_nid_t hp)
464{
465 struct ad198x_spec *spec = codec->spec;
466 snd_hda_codec_write(codec, front, 0, AC_VERB_SET_EAPD_BTLENABLE,
467 !spec->inv_eapd ? 0x00 : 0x02);
468 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_EAPD_BTLENABLE,
469 !spec->inv_eapd ? 0x00 : 0x02);
470}
471
472static void ad198x_power_eapd(struct hda_codec *codec)
473{
474 /* We currently only handle front, HP */
475 switch (codec->vendor_id) {
476 case 0x11d41882:
477 case 0x11d4882a:
478 case 0x11d41884:
479 case 0x11d41984:
480 case 0x11d41883:
481 case 0x11d4184a:
482 case 0x11d4194a:
483 case 0x11d4194b:
484 ad198x_power_eapd_write(codec, 0x12, 0x11);
485 break;
486 case 0x11d41981:
487 case 0x11d41983:
488 ad198x_power_eapd_write(codec, 0x05, 0x06);
489 break;
490 case 0x11d41986:
491 ad198x_power_eapd_write(codec, 0x1b, 0x1a);
492 break;
493 case 0x11d41988:
494 case 0x11d4198b:
495 case 0x11d4989a:
496 case 0x11d4989b:
497 ad198x_power_eapd_write(codec, 0x29, 0x22);
498 break;
499 }
500}
501
428static void ad198x_free(struct hda_codec *codec) 502static void ad198x_free(struct hda_codec *codec)
429{ 503{
430 struct ad198x_spec *spec = codec->spec; 504 struct ad198x_spec *spec = codec->spec;
@@ -432,11 +506,21 @@ static void ad198x_free(struct hda_codec *codec)
432 if (!spec) 506 if (!spec)
433 return; 507 return;
434 508
509 ad198x_shutup(codec);
435 ad198x_free_kctls(codec); 510 ad198x_free_kctls(codec);
436 kfree(spec); 511 kfree(spec);
437 snd_hda_detach_beep_device(codec); 512 snd_hda_detach_beep_device(codec);
438} 513}
439 514
515#ifdef SND_HDA_NEEDS_RESUME
516static int ad198x_suspend(struct hda_codec *codec, pm_message_t state)
517{
518 ad198x_shutup(codec);
519 ad198x_power_eapd(codec);
520 return 0;
521}
522#endif
523
440static struct hda_codec_ops ad198x_patch_ops = { 524static struct hda_codec_ops ad198x_patch_ops = {
441 .build_controls = ad198x_build_controls, 525 .build_controls = ad198x_build_controls,
442 .build_pcms = ad198x_build_pcms, 526 .build_pcms = ad198x_build_pcms,
@@ -445,12 +529,16 @@ static struct hda_codec_ops ad198x_patch_ops = {
445#ifdef CONFIG_SND_HDA_POWER_SAVE 529#ifdef CONFIG_SND_HDA_POWER_SAVE
446 .check_power_status = ad198x_check_power_status, 530 .check_power_status = ad198x_check_power_status,
447#endif 531#endif
532#ifdef SND_HDA_NEEDS_RESUME
533 .suspend = ad198x_suspend,
534#endif
535 .reboot_notify = ad198x_shutup,
448}; 536};
449 537
450 538
451/* 539/*
452 * EAPD control 540 * EAPD control
453 * the private value = nid | (invert << 8) 541 * the private value = nid
454 */ 542 */
455#define ad198x_eapd_info snd_ctl_boolean_mono_info 543#define ad198x_eapd_info snd_ctl_boolean_mono_info
456 544
@@ -459,8 +547,7 @@ static int ad198x_eapd_get(struct snd_kcontrol *kcontrol,
459{ 547{
460 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 548 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
461 struct ad198x_spec *spec = codec->spec; 549 struct ad198x_spec *spec = codec->spec;
462 int invert = (kcontrol->private_value >> 8) & 1; 550 if (spec->inv_eapd)
463 if (invert)
464 ucontrol->value.integer.value[0] = ! spec->cur_eapd; 551 ucontrol->value.integer.value[0] = ! spec->cur_eapd;
465 else 552 else
466 ucontrol->value.integer.value[0] = spec->cur_eapd; 553 ucontrol->value.integer.value[0] = spec->cur_eapd;
@@ -472,11 +559,10 @@ static int ad198x_eapd_put(struct snd_kcontrol *kcontrol,
472{ 559{
473 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 560 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
474 struct ad198x_spec *spec = codec->spec; 561 struct ad198x_spec *spec = codec->spec;
475 int invert = (kcontrol->private_value >> 8) & 1;
476 hda_nid_t nid = kcontrol->private_value & 0xff; 562 hda_nid_t nid = kcontrol->private_value & 0xff;
477 unsigned int eapd; 563 unsigned int eapd;
478 eapd = !!ucontrol->value.integer.value[0]; 564 eapd = !!ucontrol->value.integer.value[0];
479 if (invert) 565 if (spec->inv_eapd)
480 eapd = !eapd; 566 eapd = !eapd;
481 if (eapd == spec->cur_eapd) 567 if (eapd == spec->cur_eapd)
482 return 0; 568 return 0;
@@ -694,10 +780,11 @@ static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = {
694 { 780 {
695 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 781 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
696 .name = "External Amplifier", 782 .name = "External Amplifier",
783 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
697 .info = ad198x_eapd_info, 784 .info = ad198x_eapd_info,
698 .get = ad198x_eapd_get, 785 .get = ad198x_eapd_get,
699 .put = ad198x_eapd_put, 786 .put = ad198x_eapd_put,
700 .private_value = 0x1b | (1 << 8), /* port-D, inversed */ 787 .private_value = 0x1b, /* port-D */
701 }, 788 },
702 { } /* end */ 789 { } /* end */
703}; 790};
@@ -712,10 +799,10 @@ static struct snd_kcontrol_new ad1986a_laptop_intmic_mixers[] = {
712static void ad1986a_automic(struct hda_codec *codec) 799static void ad1986a_automic(struct hda_codec *codec)
713{ 800{
714 unsigned int present; 801 unsigned int present;
715 present = snd_hda_codec_read(codec, 0x1f, 0, AC_VERB_GET_PIN_SENSE, 0); 802 present = snd_hda_jack_detect(codec, 0x1f);
716 /* 0 = 0x1f, 2 = 0x1d, 4 = mixed */ 803 /* 0 = 0x1f, 2 = 0x1d, 4 = mixed */
717 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_CONNECT_SEL, 804 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_CONNECT_SEL,
718 (present & AC_PINSENSE_PRESENCE) ? 0 : 2); 805 present ? 0 : 2);
719} 806}
720 807
721#define AD1986A_MIC_EVENT 0x36 808#define AD1986A_MIC_EVENT 0x36
@@ -754,10 +841,8 @@ static void ad1986a_update_hp(struct hda_codec *codec)
754static void ad1986a_hp_automute(struct hda_codec *codec) 841static void ad1986a_hp_automute(struct hda_codec *codec)
755{ 842{
756 struct ad198x_spec *spec = codec->spec; 843 struct ad198x_spec *spec = codec->spec;
757 unsigned int present;
758 844
759 present = snd_hda_codec_read(codec, 0x1a, 0, AC_VERB_GET_PIN_SENSE, 0); 845 spec->jack_present = snd_hda_jack_detect(codec, 0x1a);
760 spec->jack_present = !!(present & 0x80000000);
761 if (spec->inv_jack_detect) 846 if (spec->inv_jack_detect)
762 spec->jack_present = !spec->jack_present; 847 spec->jack_present = !spec->jack_present;
763 ad1986a_update_hp(codec); 848 ad1986a_update_hp(codec);
@@ -803,6 +888,7 @@ static struct snd_kcontrol_new ad1986a_automute_master_mixers[] = {
803 { 888 {
804 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 889 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
805 .name = "Master Playback Switch", 890 .name = "Master Playback Switch",
891 .subdevice = HDA_SUBDEV_AMP_FLAG,
806 .info = snd_hda_mixer_amp_switch_info, 892 .info = snd_hda_mixer_amp_switch_info,
807 .get = snd_hda_mixer_amp_switch_get, 893 .get = snd_hda_mixer_amp_switch_get,
808 .put = ad1986a_hp_master_sw_put, 894 .put = ad1986a_hp_master_sw_put,
@@ -1003,7 +1089,7 @@ static struct snd_pci_quirk ad1986a_cfg_tbl[] = {
1003 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS M2N", AD1986A_3STACK), 1089 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS M2N", AD1986A_3STACK),
1004 SND_PCI_QUIRK(0x1043, 0x8234, "ASUS M2N", AD1986A_3STACK), 1090 SND_PCI_QUIRK(0x1043, 0x8234, "ASUS M2N", AD1986A_3STACK),
1005 SND_PCI_QUIRK(0x10de, 0xcb84, "ASUS A8N-VM", AD1986A_3STACK), 1091 SND_PCI_QUIRK(0x10de, 0xcb84, "ASUS A8N-VM", AD1986A_3STACK),
1006 SND_PCI_QUIRK(0x1179, 0xff40, "Toshiba", AD1986A_LAPTOP_EAPD), 1092 SND_PCI_QUIRK(0x1179, 0xff40, "Toshiba Satellite L40-10Q", AD1986A_3STACK),
1007 SND_PCI_QUIRK(0x144d, 0xb03c, "Samsung R55", AD1986A_3STACK), 1093 SND_PCI_QUIRK(0x144d, 0xb03c, "Samsung R55", AD1986A_3STACK),
1008 SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_LAPTOP), 1094 SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_LAPTOP),
1009 SND_PCI_QUIRK(0x144d, 0xc024, "Samsung P50", AD1986A_SAMSUNG_P50), 1095 SND_PCI_QUIRK(0x144d, 0xc024, "Samsung P50", AD1986A_SAMSUNG_P50),
@@ -1068,6 +1154,7 @@ static int patch_ad1986a(struct hda_codec *codec)
1068 spec->loopback.amplist = ad1986a_loopbacks; 1154 spec->loopback.amplist = ad1986a_loopbacks;
1069#endif 1155#endif
1070 spec->vmaster_nid = 0x1b; 1156 spec->vmaster_nid = 0x1b;
1157 spec->inv_eapd = 1; /* AD1986A has the inverted EAPD implementation */
1071 1158
1072 codec->patch_ops = ad198x_patch_ops; 1159 codec->patch_ops = ad198x_patch_ops;
1073 1160
@@ -1180,6 +1267,8 @@ static int patch_ad1986a(struct hda_codec *codec)
1180 */ 1267 */
1181 spec->multiout.no_share_stream = 1; 1268 spec->multiout.no_share_stream = 1;
1182 1269
1270 codec->no_trigger_sense = 1;
1271
1183 return 0; 1272 return 0;
1184} 1273}
1185 1274
@@ -1365,6 +1454,8 @@ static int patch_ad1983(struct hda_codec *codec)
1365 1454
1366 codec->patch_ops = ad198x_patch_ops; 1455 codec->patch_ops = ad198x_patch_ops;
1367 1456
1457 codec->no_trigger_sense = 1;
1458
1368 return 0; 1459 return 0;
1369} 1460}
1370 1461
@@ -1547,8 +1638,7 @@ static void ad1981_hp_automute(struct hda_codec *codec)
1547{ 1638{
1548 unsigned int present; 1639 unsigned int present;
1549 1640
1550 present = snd_hda_codec_read(codec, 0x06, 0, 1641 present = snd_hda_jack_detect(codec, 0x06);
1551 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1552 snd_hda_codec_amp_stereo(codec, 0x05, HDA_OUTPUT, 0, 1642 snd_hda_codec_amp_stereo(codec, 0x05, HDA_OUTPUT, 0,
1553 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 1643 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
1554} 1644}
@@ -1568,8 +1658,7 @@ static void ad1981_hp_automic(struct hda_codec *codec)
1568 }; 1658 };
1569 unsigned int present; 1659 unsigned int present;
1570 1660
1571 present = snd_hda_codec_read(codec, 0x08, 0, 1661 present = snd_hda_jack_detect(codec, 0x08);
1572 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1573 if (present) 1662 if (present)
1574 snd_hda_sequence_write(codec, mic_jack_on); 1663 snd_hda_sequence_write(codec, mic_jack_on);
1575 else 1664 else
@@ -1604,6 +1693,7 @@ static struct snd_kcontrol_new ad1981_hp_mixers[] = {
1604 HDA_BIND_VOL("Master Playback Volume", &ad1981_hp_bind_master_vol), 1693 HDA_BIND_VOL("Master Playback Volume", &ad1981_hp_bind_master_vol),
1605 { 1694 {
1606 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1695 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1696 .subdevice = HDA_SUBDEV_NID_FLAG | 0x05,
1607 .name = "Master Playback Switch", 1697 .name = "Master Playback Switch",
1608 .info = ad198x_eapd_info, 1698 .info = ad198x_eapd_info,
1609 .get = ad198x_eapd_get, 1699 .get = ad198x_eapd_get,
@@ -1785,10 +1875,26 @@ static int patch_ad1981(struct hda_codec *codec)
1785 1875
1786 codec->patch_ops.init = ad1981_hp_init; 1876 codec->patch_ops.init = ad1981_hp_init;
1787 codec->patch_ops.unsol_event = ad1981_hp_unsol_event; 1877 codec->patch_ops.unsol_event = ad1981_hp_unsol_event;
1878 /* set the upper-limit for mixer amp to 0dB for avoiding the
1879 * possible damage by overloading
1880 */
1881 snd_hda_override_amp_caps(codec, 0x11, HDA_INPUT,
1882 (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
1883 (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
1884 (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
1885 (1 << AC_AMPCAP_MUTE_SHIFT));
1788 break; 1886 break;
1789 case AD1981_THINKPAD: 1887 case AD1981_THINKPAD:
1790 spec->mixers[0] = ad1981_thinkpad_mixers; 1888 spec->mixers[0] = ad1981_thinkpad_mixers;
1791 spec->input_mux = &ad1981_thinkpad_capture_source; 1889 spec->input_mux = &ad1981_thinkpad_capture_source;
1890 /* set the upper-limit for mixer amp to 0dB for avoiding the
1891 * possible damage by overloading
1892 */
1893 snd_hda_override_amp_caps(codec, 0x11, HDA_INPUT,
1894 (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
1895 (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
1896 (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
1897 (1 << AC_AMPCAP_MUTE_SHIFT));
1792 break; 1898 break;
1793 case AD1981_TOSHIBA: 1899 case AD1981_TOSHIBA:
1794 spec->mixers[0] = ad1981_hp_mixers; 1900 spec->mixers[0] = ad1981_hp_mixers;
@@ -1801,6 +1907,9 @@ static int patch_ad1981(struct hda_codec *codec)
1801 codec->patch_ops.unsol_event = ad1981_hp_unsol_event; 1907 codec->patch_ops.unsol_event = ad1981_hp_unsol_event;
1802 break; 1908 break;
1803 } 1909 }
1910
1911 codec->no_trigger_sense = 1;
1912
1804 return 0; 1913 return 0;
1805} 1914}
1806 1915
@@ -2117,10 +2226,11 @@ static struct snd_kcontrol_new ad1988_laptop_mixers[] = {
2117 { 2226 {
2118 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2227 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2119 .name = "External Amplifier", 2228 .name = "External Amplifier",
2229 .subdevice = HDA_SUBDEV_NID_FLAG | 0x12,
2120 .info = ad198x_eapd_info, 2230 .info = ad198x_eapd_info,
2121 .get = ad198x_eapd_get, 2231 .get = ad198x_eapd_get,
2122 .put = ad198x_eapd_put, 2232 .put = ad198x_eapd_put,
2123 .private_value = 0x12 | (1 << 8), /* port-D, inversed */ 2233 .private_value = 0x12, /* port-D */
2124 }, 2234 },
2125 2235
2126 { } /* end */ 2236 { } /* end */
@@ -2238,6 +2348,7 @@ static struct snd_kcontrol_new ad1988_spdif_out_mixers[] = {
2238 { 2348 {
2239 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2349 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2240 .name = "IEC958 Playback Source", 2350 .name = "IEC958 Playback Source",
2351 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
2241 .info = ad1988_spdif_playback_source_info, 2352 .info = ad1988_spdif_playback_source_info,
2242 .get = ad1988_spdif_playback_source_get, 2353 .get = ad1988_spdif_playback_source_get,
2243 .put = ad1988_spdif_playback_source_put, 2354 .put = ad1988_spdif_playback_source_put,
@@ -2353,6 +2464,12 @@ static struct hda_verb ad1988_spdif_init_verbs[] = {
2353 { } 2464 { }
2354}; 2465};
2355 2466
2467static struct hda_verb ad1988_spdif_in_init_verbs[] = {
2468 /* unmute SPDIF input pin */
2469 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2470 { }
2471};
2472
2356/* AD1989 has no ADC -> SPDIF route */ 2473/* AD1989 has no ADC -> SPDIF route */
2357static struct hda_verb ad1989_spdif_init_verbs[] = { 2474static struct hda_verb ad1989_spdif_init_verbs[] = {
2358 /* SPDIF-1 out pin */ 2475 /* SPDIF-1 out pin */
@@ -2524,7 +2641,7 @@ static void ad1988_laptop_unsol_event(struct hda_codec *codec, unsigned int res)
2524{ 2641{
2525 if ((res >> 26) != AD1988_HP_EVENT) 2642 if ((res >> 26) != AD1988_HP_EVENT)
2526 return; 2643 return;
2527 if (snd_hda_codec_read(codec, 0x11, 0, AC_VERB_GET_PIN_SENSE, 0) & (1 << 31)) 2644 if (snd_hda_jack_detect(codec, 0x11))
2528 snd_hda_sequence_write(codec, ad1988_laptop_hp_on); 2645 snd_hda_sequence_write(codec, ad1988_laptop_hp_on);
2529 else 2646 else
2530 snd_hda_sequence_write(codec, ad1988_laptop_hp_off); 2647 snd_hda_sequence_write(codec, ad1988_laptop_hp_off);
@@ -2569,6 +2686,8 @@ static int add_control(struct ad198x_spec *spec, int type, const char *name,
2569 knew->name = kstrdup(name, GFP_KERNEL); 2686 knew->name = kstrdup(name, GFP_KERNEL);
2570 if (! knew->name) 2687 if (! knew->name)
2571 return -ENOMEM; 2688 return -ENOMEM;
2689 if (get_amp_nid_(val))
2690 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
2572 knew->private_value = val; 2691 knew->private_value = val;
2573 return 0; 2692 return 0;
2574} 2693}
@@ -3059,6 +3178,7 @@ static int patch_ad1988(struct hda_codec *codec)
3059 spec->input_mux = &ad1988_laptop_capture_source; 3178 spec->input_mux = &ad1988_laptop_capture_source;
3060 spec->num_mixers = 1; 3179 spec->num_mixers = 1;
3061 spec->mixers[0] = ad1988_laptop_mixers; 3180 spec->mixers[0] = ad1988_laptop_mixers;
3181 spec->inv_eapd = 1; /* inverted EAPD */
3062 spec->num_init_verbs = 1; 3182 spec->num_init_verbs = 1;
3063 spec->init_verbs[0] = ad1988_laptop_init_verbs; 3183 spec->init_verbs[0] = ad1988_laptop_init_verbs;
3064 if (board_config == AD1988_LAPTOP_DIG) 3184 if (board_config == AD1988_LAPTOP_DIG)
@@ -3085,8 +3205,11 @@ static int patch_ad1988(struct hda_codec *codec)
3085 ad1988_spdif_init_verbs; 3205 ad1988_spdif_init_verbs;
3086 } 3206 }
3087 } 3207 }
3088 if (spec->dig_in_nid && codec->vendor_id < 0x11d4989a) 3208 if (spec->dig_in_nid && codec->vendor_id < 0x11d4989a) {
3089 spec->mixers[spec->num_mixers++] = ad1988_spdif_in_mixers; 3209 spec->mixers[spec->num_mixers++] = ad1988_spdif_in_mixers;
3210 spec->init_verbs[spec->num_init_verbs++] =
3211 ad1988_spdif_in_init_verbs;
3212 }
3090 3213
3091 codec->patch_ops = ad198x_patch_ops; 3214 codec->patch_ops = ad198x_patch_ops;
3092 switch (board_config) { 3215 switch (board_config) {
@@ -3103,6 +3226,8 @@ static int patch_ad1988(struct hda_codec *codec)
3103#endif 3226#endif
3104 spec->vmaster_nid = 0x04; 3227 spec->vmaster_nid = 0x04;
3105 3228
3229 codec->no_trigger_sense = 1;
3230
3106 return 0; 3231 return 0;
3107} 3232}
3108 3233
@@ -3315,6 +3440,8 @@ static int patch_ad1884(struct hda_codec *codec)
3315 3440
3316 codec->patch_ops = ad198x_patch_ops; 3441 codec->patch_ops = ad198x_patch_ops;
3317 3442
3443 codec->no_trigger_sense = 1;
3444
3318 return 0; 3445 return 0;
3319} 3446}
3320 3447
@@ -3721,6 +3848,7 @@ static struct snd_kcontrol_new ad1884a_laptop_mixers[] = {
3721 { 3848 {
3722 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3849 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3723 .name = "Master Playback Switch", 3850 .name = "Master Playback Switch",
3851 .subdevice = HDA_SUBDEV_AMP_FLAG,
3724 .info = snd_hda_mixer_amp_switch_info, 3852 .info = snd_hda_mixer_amp_switch_info,
3725 .get = snd_hda_mixer_amp_switch_get, 3853 .get = snd_hda_mixer_amp_switch_get,
3726 .put = ad1884a_mobile_master_sw_put, 3854 .put = ad1884a_mobile_master_sw_put,
@@ -3749,6 +3877,7 @@ static struct snd_kcontrol_new ad1884a_mobile_mixers[] = {
3749 { 3877 {
3750 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3878 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3751 .name = "Master Playback Switch", 3879 .name = "Master Playback Switch",
3880 .subdevice = HDA_SUBDEV_AMP_FLAG,
3752 .info = snd_hda_mixer_amp_switch_info, 3881 .info = snd_hda_mixer_amp_switch_info,
3753 .get = snd_hda_mixer_amp_switch_get, 3882 .get = snd_hda_mixer_amp_switch_get,
3754 .put = ad1884a_mobile_master_sw_put, 3883 .put = ad1884a_mobile_master_sw_put,
@@ -3768,8 +3897,7 @@ static void ad1884a_hp_automute(struct hda_codec *codec)
3768{ 3897{
3769 unsigned int present; 3898 unsigned int present;
3770 3899
3771 present = snd_hda_codec_read(codec, 0x11, 0, 3900 present = snd_hda_jack_detect(codec, 0x11);
3772 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
3773 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, 3901 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
3774 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 3902 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
3775 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_EAPD_BTLENABLE, 3903 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_EAPD_BTLENABLE,
@@ -3781,8 +3909,7 @@ static void ad1884a_hp_automic(struct hda_codec *codec)
3781{ 3909{
3782 unsigned int present; 3910 unsigned int present;
3783 3911
3784 present = snd_hda_codec_read(codec, 0x14, 0, 3912 present = snd_hda_jack_detect(codec, 0x14);
3785 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
3786 snd_hda_codec_write(codec, 0x0c, 0, AC_VERB_SET_CONNECT_SEL, 3913 snd_hda_codec_write(codec, 0x0c, 0, AC_VERB_SET_CONNECT_SEL,
3787 present ? 0 : 1); 3914 present ? 0 : 1);
3788} 3915}
@@ -3817,13 +3944,9 @@ static void ad1884a_laptop_automute(struct hda_codec *codec)
3817{ 3944{
3818 unsigned int present; 3945 unsigned int present;
3819 3946
3820 present = snd_hda_codec_read(codec, 0x11, 0, AC_VERB_GET_PIN_SENSE, 0); 3947 present = snd_hda_jack_detect(codec, 0x11);
3821 present &= AC_PINSENSE_PRESENCE; 3948 if (!present)
3822 if (!present) { 3949 present = snd_hda_jack_detect(codec, 0x12);
3823 present = snd_hda_codec_read(codec, 0x12, 0,
3824 AC_VERB_GET_PIN_SENSE, 0);
3825 present &= AC_PINSENSE_PRESENCE;
3826 }
3827 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, 3950 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
3828 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 3951 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
3829 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_EAPD_BTLENABLE, 3952 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_EAPD_BTLENABLE,
@@ -3835,11 +3958,9 @@ static void ad1884a_laptop_automic(struct hda_codec *codec)
3835{ 3958{
3836 unsigned int idx; 3959 unsigned int idx;
3837 3960
3838 if (snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0) & 3961 if (snd_hda_jack_detect(codec, 0x14))
3839 AC_PINSENSE_PRESENCE)
3840 idx = 0; 3962 idx = 0;
3841 else if (snd_hda_codec_read(codec, 0x1c, 0, AC_VERB_GET_PIN_SENSE, 0) & 3963 else if (snd_hda_jack_detect(codec, 0x1c))
3842 AC_PINSENSE_PRESENCE)
3843 idx = 4; 3964 idx = 4;
3844 else 3965 else
3845 idx = 1; 3966 idx = 1;
@@ -4008,8 +4129,7 @@ static void ad1984a_thinkpad_automute(struct hda_codec *codec)
4008{ 4129{
4009 unsigned int present; 4130 unsigned int present;
4010 4131
4011 present = snd_hda_codec_read(codec, 0x11, 0, AC_VERB_GET_PIN_SENSE, 0) 4132 present = snd_hda_jack_detect(codec, 0x11);
4012 & AC_PINSENSE_PRESENCE;
4013 snd_hda_codec_amp_stereo(codec, 0x12, HDA_OUTPUT, 0, 4133 snd_hda_codec_amp_stereo(codec, 0x12, HDA_OUTPUT, 0,
4014 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 4134 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
4015} 4135}
@@ -4099,6 +4219,7 @@ static struct snd_kcontrol_new ad1984a_touchsmart_mixers[] = {
4099/* HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/ 4219/* HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/
4100 { 4220 {
4101 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 4221 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4222 .subdevice = HDA_SUBDEV_AMP_FLAG,
4102 .name = "Master Playback Switch", 4223 .name = "Master Playback Switch",
4103 .info = snd_hda_mixer_amp_switch_info, 4224 .info = snd_hda_mixer_amp_switch_info,
4104 .get = snd_hda_mixer_amp_switch_get, 4225 .get = snd_hda_mixer_amp_switch_get,
@@ -4117,14 +4238,12 @@ static struct snd_kcontrol_new ad1984a_touchsmart_mixers[] = {
4117/* switch to external mic if plugged */ 4238/* switch to external mic if plugged */
4118static void ad1984a_touchsmart_automic(struct hda_codec *codec) 4239static void ad1984a_touchsmart_automic(struct hda_codec *codec)
4119{ 4240{
4120 if (snd_hda_codec_read(codec, 0x1c, 0, 4241 if (snd_hda_jack_detect(codec, 0x1c))
4121 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000) {
4122 snd_hda_codec_write(codec, 0x0c, 0, 4242 snd_hda_codec_write(codec, 0x0c, 0,
4123 AC_VERB_SET_CONNECT_SEL, 0x4); 4243 AC_VERB_SET_CONNECT_SEL, 0x4);
4124 } else { 4244 else
4125 snd_hda_codec_write(codec, 0x0c, 0, 4245 snd_hda_codec_write(codec, 0x0c, 0,
4126 AC_VERB_SET_CONNECT_SEL, 0x5); 4246 AC_VERB_SET_CONNECT_SEL, 0x5);
4127 }
4128} 4247}
4129 4248
4130 4249
@@ -4283,6 +4402,8 @@ static int patch_ad1884a(struct hda_codec *codec)
4283 break; 4402 break;
4284 } 4403 }
4285 4404
4405 codec->no_trigger_sense = 1;
4406
4286 return 0; 4407 return 0;
4287} 4408}
4288 4409
@@ -4619,6 +4740,9 @@ static int patch_ad1882(struct hda_codec *codec)
4619 spec->mixers[2] = ad1882_6stack_mixers; 4740 spec->mixers[2] = ad1882_6stack_mixers;
4620 break; 4741 break;
4621 } 4742 }
4743
4744 codec->no_trigger_sense = 1;
4745
4622 return 0; 4746 return 0;
4623} 4747}
4624 4748
diff --git a/sound/pci/hda/patch_ca0110.c b/sound/pci/hda/patch_ca0110.c
index d08353d3bb7f..af478019088e 100644
--- a/sound/pci/hda/patch_ca0110.c
+++ b/sound/pci/hda/patch_ca0110.c
@@ -144,7 +144,7 @@ static int _add_switch(struct hda_codec *codec, hda_nid_t nid, const char *pfx,
144 struct snd_kcontrol_new knew = 144 struct snd_kcontrol_new knew =
145 HDA_CODEC_MUTE_MONO(namestr, nid, chan, 0, type); 145 HDA_CODEC_MUTE_MONO(namestr, nid, chan, 0, type);
146 sprintf(namestr, "%s %s Switch", pfx, dirstr[dir]); 146 sprintf(namestr, "%s %s Switch", pfx, dirstr[dir]);
147 return snd_hda_ctl_add(codec, snd_ctl_new1(&knew, codec)); 147 return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec));
148} 148}
149 149
150static int _add_volume(struct hda_codec *codec, hda_nid_t nid, const char *pfx, 150static int _add_volume(struct hda_codec *codec, hda_nid_t nid, const char *pfx,
@@ -155,7 +155,7 @@ static int _add_volume(struct hda_codec *codec, hda_nid_t nid, const char *pfx,
155 struct snd_kcontrol_new knew = 155 struct snd_kcontrol_new knew =
156 HDA_CODEC_VOLUME_MONO(namestr, nid, chan, 0, type); 156 HDA_CODEC_VOLUME_MONO(namestr, nid, chan, 0, type);
157 sprintf(namestr, "%s %s Volume", pfx, dirstr[dir]); 157 sprintf(namestr, "%s %s Volume", pfx, dirstr[dir]);
158 return snd_hda_ctl_add(codec, snd_ctl_new1(&knew, codec)); 158 return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec));
159} 159}
160 160
161#define add_out_switch(codec, nid, pfx) _add_switch(codec, nid, pfx, 3, 0) 161#define add_out_switch(codec, nid, pfx) _add_switch(codec, nid, pfx, 3, 0)
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index 8ba306856d38..350ee8ac4153 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -66,6 +66,7 @@ struct cs_spec {
66/* available models */ 66/* available models */
67enum { 67enum {
68 CS420X_MBP55, 68 CS420X_MBP55,
69 CS420X_IMAC27,
69 CS420X_AUTO, 70 CS420X_AUTO,
70 CS420X_MODELS 71 CS420X_MODELS
71}; 72};
@@ -500,7 +501,8 @@ static int add_mute(struct hda_codec *codec, const char *name, int index,
500 knew.private_value = pval; 501 knew.private_value = pval;
501 snprintf(tmp, sizeof(tmp), "%s %s Switch", name, dir_sfx[dir]); 502 snprintf(tmp, sizeof(tmp), "%s %s Switch", name, dir_sfx[dir]);
502 *kctlp = snd_ctl_new1(&knew, codec); 503 *kctlp = snd_ctl_new1(&knew, codec);
503 return snd_hda_ctl_add(codec, *kctlp); 504 (*kctlp)->id.subdevice = HDA_SUBDEV_AMP_FLAG;
505 return snd_hda_ctl_add(codec, 0, *kctlp);
504} 506}
505 507
506static int add_volume(struct hda_codec *codec, const char *name, 508static int add_volume(struct hda_codec *codec, const char *name,
@@ -513,7 +515,8 @@ static int add_volume(struct hda_codec *codec, const char *name,
513 knew.private_value = pval; 515 knew.private_value = pval;
514 snprintf(tmp, sizeof(tmp), "%s %s Volume", name, dir_sfx[dir]); 516 snprintf(tmp, sizeof(tmp), "%s %s Volume", name, dir_sfx[dir]);
515 *kctlp = snd_ctl_new1(&knew, codec); 517 *kctlp = snd_ctl_new1(&knew, codec);
516 return snd_hda_ctl_add(codec, *kctlp); 518 (*kctlp)->id.subdevice = HDA_SUBDEV_AMP_FLAG;
519 return snd_hda_ctl_add(codec, 0, *kctlp);
517} 520}
518 521
519static void fix_volume_caps(struct hda_codec *codec, hda_nid_t dac) 522static void fix_volume_caps(struct hda_codec *codec, hda_nid_t dac)
@@ -536,14 +539,14 @@ static int add_vmaster(struct hda_codec *codec, hda_nid_t dac)
536 539
537 spec->vmaster_sw = 540 spec->vmaster_sw =
538 snd_ctl_make_virtual_master("Master Playback Switch", NULL); 541 snd_ctl_make_virtual_master("Master Playback Switch", NULL);
539 err = snd_hda_ctl_add(codec, spec->vmaster_sw); 542 err = snd_hda_ctl_add(codec, dac, spec->vmaster_sw);
540 if (err < 0) 543 if (err < 0)
541 return err; 544 return err;
542 545
543 snd_hda_set_vmaster_tlv(codec, dac, HDA_OUTPUT, tlv); 546 snd_hda_set_vmaster_tlv(codec, dac, HDA_OUTPUT, tlv);
544 spec->vmaster_vol = 547 spec->vmaster_vol =
545 snd_ctl_make_virtual_master("Master Playback Volume", tlv); 548 snd_ctl_make_virtual_master("Master Playback Volume", tlv);
546 err = snd_hda_ctl_add(codec, spec->vmaster_vol); 549 err = snd_hda_ctl_add(codec, dac, spec->vmaster_vol);
547 if (err < 0) 550 if (err < 0)
548 return err; 551 return err;
549 return 0; 552 return 0;
@@ -750,19 +753,27 @@ static int build_input(struct hda_codec *codec)
750 spec->capture_bind[1] = make_bind_capture(codec, &snd_hda_bind_vol); 753 spec->capture_bind[1] = make_bind_capture(codec, &snd_hda_bind_vol);
751 for (i = 0; i < 2; i++) { 754 for (i = 0; i < 2; i++) {
752 struct snd_kcontrol *kctl; 755 struct snd_kcontrol *kctl;
756 int n;
753 if (!spec->capture_bind[i]) 757 if (!spec->capture_bind[i])
754 return -ENOMEM; 758 return -ENOMEM;
755 kctl = snd_ctl_new1(&cs_capture_ctls[i], codec); 759 kctl = snd_ctl_new1(&cs_capture_ctls[i], codec);
756 if (!kctl) 760 if (!kctl)
757 return -ENOMEM; 761 return -ENOMEM;
758 kctl->private_value = (long)spec->capture_bind[i]; 762 kctl->private_value = (long)spec->capture_bind[i];
759 err = snd_hda_ctl_add(codec, kctl); 763 err = snd_hda_ctl_add(codec, 0, kctl);
760 if (err < 0) 764 if (err < 0)
761 return err; 765 return err;
766 for (n = 0; n < AUTO_PIN_LAST; n++) {
767 if (!spec->adc_nid[n])
768 continue;
769 err = snd_hda_add_nid(codec, kctl, 0, spec->adc_nid[n]);
770 if (err < 0)
771 return err;
772 }
762 } 773 }
763 774
764 if (spec->num_inputs > 1 && !spec->mic_detect) { 775 if (spec->num_inputs > 1 && !spec->mic_detect) {
765 err = snd_hda_ctl_add(codec, 776 err = snd_hda_ctl_add(codec, 0,
766 snd_ctl_new1(&cs_capture_source, codec)); 777 snd_ctl_new1(&cs_capture_source, codec));
767 if (err < 0) 778 if (err < 0)
768 return err; 779 return err;
@@ -807,7 +818,7 @@ static void cs_automute(struct hda_codec *codec)
807{ 818{
808 struct cs_spec *spec = codec->spec; 819 struct cs_spec *spec = codec->spec;
809 struct auto_pin_cfg *cfg = &spec->autocfg; 820 struct auto_pin_cfg *cfg = &spec->autocfg;
810 unsigned int caps, present, hp_present; 821 unsigned int caps, hp_present;
811 hda_nid_t nid; 822 hda_nid_t nid;
812 int i; 823 int i;
813 824
@@ -817,12 +828,7 @@ static void cs_automute(struct hda_codec *codec)
817 caps = snd_hda_query_pin_caps(codec, nid); 828 caps = snd_hda_query_pin_caps(codec, nid);
818 if (!(caps & AC_PINCAP_PRES_DETECT)) 829 if (!(caps & AC_PINCAP_PRES_DETECT))
819 continue; 830 continue;
820 if (caps & AC_PINCAP_TRIG_REQ) 831 hp_present = snd_hda_jack_detect(codec, nid);
821 snd_hda_codec_read(codec, nid, 0,
822 AC_VERB_SET_PIN_SENSE, 0);
823 present = snd_hda_codec_read(codec, nid, 0,
824 AC_VERB_GET_PIN_SENSE, 0);
825 hp_present |= (present & AC_PINSENSE_PRESENCE) != 0;
826 if (hp_present) 832 if (hp_present)
827 break; 833 break;
828 } 834 }
@@ -832,7 +838,8 @@ static void cs_automute(struct hda_codec *codec)
832 AC_VERB_SET_PIN_WIDGET_CONTROL, 838 AC_VERB_SET_PIN_WIDGET_CONTROL,
833 hp_present ? 0 : PIN_OUT); 839 hp_present ? 0 : PIN_OUT);
834 } 840 }
835 if (spec->board_config == CS420X_MBP55) { 841 if (spec->board_config == CS420X_MBP55 ||
842 spec->board_config == CS420X_IMAC27) {
836 unsigned int gpio = hp_present ? 0x02 : 0x08; 843 unsigned int gpio = hp_present ? 0x02 : 0x08;
837 snd_hda_codec_write(codec, 0x01, 0, 844 snd_hda_codec_write(codec, 0x01, 0,
838 AC_VERB_SET_GPIO_DATA, gpio); 845 AC_VERB_SET_GPIO_DATA, gpio);
@@ -844,15 +851,11 @@ static void cs_automic(struct hda_codec *codec)
844 struct cs_spec *spec = codec->spec; 851 struct cs_spec *spec = codec->spec;
845 struct auto_pin_cfg *cfg = &spec->autocfg; 852 struct auto_pin_cfg *cfg = &spec->autocfg;
846 hda_nid_t nid; 853 hda_nid_t nid;
847 unsigned int caps, present; 854 unsigned int present;
848 855
849 nid = cfg->input_pins[spec->automic_idx]; 856 nid = cfg->input_pins[spec->automic_idx];
850 caps = snd_hda_query_pin_caps(codec, nid); 857 present = snd_hda_jack_detect(codec, nid);
851 if (caps & AC_PINCAP_TRIG_REQ) 858 if (present)
852 snd_hda_codec_read(codec, nid, 0, AC_VERB_SET_PIN_SENSE, 0);
853 present = snd_hda_codec_read(codec, nid, 0,
854 AC_VERB_GET_PIN_SENSE, 0);
855 if (present & AC_PINSENSE_PRESENCE)
856 change_cur_input(codec, spec->automic_idx, 0); 859 change_cur_input(codec, spec->automic_idx, 0);
857 else { 860 else {
858 unsigned int imic = (spec->automic_idx == AUTO_PIN_MIC) ? 861 unsigned int imic = (spec->automic_idx == AUTO_PIN_MIC) ?
@@ -947,7 +950,7 @@ static void init_input(struct hda_codec *codec)
947 coef |= 0x0500; /* DMIC2 enable 2 channels, disable GPIO1 */ 950 coef |= 0x0500; /* DMIC2 enable 2 channels, disable GPIO1 */
948 if (is_active_pin(codec, CS_DMIC1_PIN_NID)) 951 if (is_active_pin(codec, CS_DMIC1_PIN_NID))
949 coef |= 0x1800; /* DMIC1 enable 2 channels, disable GPIO0 952 coef |= 0x1800; /* DMIC1 enable 2 channels, disable GPIO0
950 * No effect if SPDIF_OUT2 is slected in 953 * No effect if SPDIF_OUT2 is selected in
951 * IDX_SPDIF_CTL. 954 * IDX_SPDIF_CTL.
952 */ 955 */
953 cs_vendor_coef_set(codec, IDX_ADC_CFG, coef); 956 cs_vendor_coef_set(codec, IDX_ADC_CFG, coef);
@@ -1078,12 +1081,14 @@ static int cs_parse_auto_config(struct hda_codec *codec)
1078 1081
1079static const char *cs420x_models[CS420X_MODELS] = { 1082static const char *cs420x_models[CS420X_MODELS] = {
1080 [CS420X_MBP55] = "mbp55", 1083 [CS420X_MBP55] = "mbp55",
1084 [CS420X_IMAC27] = "imac27",
1081 [CS420X_AUTO] = "auto", 1085 [CS420X_AUTO] = "auto",
1082}; 1086};
1083 1087
1084 1088
1085static struct snd_pci_quirk cs420x_cfg_tbl[] = { 1089static struct snd_pci_quirk cs420x_cfg_tbl[] = {
1086 SND_PCI_QUIRK(0x10de, 0xcb79, "MacBookPro 5,5", CS420X_MBP55), 1090 SND_PCI_QUIRK(0x10de, 0xcb79, "MacBookPro 5,5", CS420X_MBP55),
1091 SND_PCI_QUIRK(0x8086, 0x7270, "IMac 27 Inch", CS420X_IMAC27),
1087 {} /* terminator */ 1092 {} /* terminator */
1088}; 1093};
1089 1094
@@ -1106,8 +1111,23 @@ static struct cs_pincfg mbp55_pincfgs[] = {
1106 {} /* terminator */ 1111 {} /* terminator */
1107}; 1112};
1108 1113
1114static struct cs_pincfg imac27_pincfgs[] = {
1115 { 0x09, 0x012b4050 },
1116 { 0x0a, 0x90100140 },
1117 { 0x0b, 0x90100142 },
1118 { 0x0c, 0x018b3020 },
1119 { 0x0d, 0x90a00110 },
1120 { 0x0e, 0x400000f0 },
1121 { 0x0f, 0x01cbe030 },
1122 { 0x10, 0x014be060 },
1123 { 0x12, 0x01ab9070 },
1124 { 0x15, 0x400000f0 },
1125 {} /* terminator */
1126};
1127
1109static struct cs_pincfg *cs_pincfgs[CS420X_MODELS] = { 1128static struct cs_pincfg *cs_pincfgs[CS420X_MODELS] = {
1110 [CS420X_MBP55] = mbp55_pincfgs, 1129 [CS420X_MBP55] = mbp55_pincfgs,
1130 [CS420X_IMAC27] = imac27_pincfgs,
1111}; 1131};
1112 1132
1113static void fix_pincfg(struct hda_codec *codec, int model) 1133static void fix_pincfg(struct hda_codec *codec, int model)
@@ -1137,6 +1157,7 @@ static int patch_cs420x(struct hda_codec *codec)
1137 fix_pincfg(codec, spec->board_config); 1157 fix_pincfg(codec, spec->board_config);
1138 1158
1139 switch (spec->board_config) { 1159 switch (spec->board_config) {
1160 case CS420X_IMAC27:
1140 case CS420X_MBP55: 1161 case CS420X_MBP55:
1141 /* GPIO1 = headphones */ 1162 /* GPIO1 = headphones */
1142 /* GPIO3 = speakers */ 1163 /* GPIO3 = speakers */
diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c
index 780e1a72114a..ff60908f4554 100644
--- a/sound/pci/hda/patch_cmedia.c
+++ b/sound/pci/hda/patch_cmedia.c
@@ -66,7 +66,7 @@ struct cmi_spec {
66 66
67 struct hda_pcm pcm_rec[2]; /* PCM information */ 67 struct hda_pcm pcm_rec[2]; /* PCM information */
68 68
69 /* pin deafault configuration */ 69 /* pin default configuration */
70 hda_nid_t pin_nid[NUM_PINS]; 70 hda_nid_t pin_nid[NUM_PINS];
71 unsigned int def_conf[NUM_PINS]; 71 unsigned int def_conf[NUM_PINS];
72 unsigned int pin_def_confs; 72 unsigned int pin_def_confs;
@@ -197,8 +197,8 @@ static struct snd_kcontrol_new cmi9880_basic_mixer[] = {
197 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0, HDA_INPUT), 197 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0, HDA_INPUT),
198 HDA_CODEC_MUTE("Capture Switch", 0x08, 0, HDA_INPUT), 198 HDA_CODEC_MUTE("Capture Switch", 0x08, 0, HDA_INPUT),
199 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0, HDA_INPUT), 199 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0, HDA_INPUT),
200 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x23, 0, HDA_OUTPUT), 200 HDA_CODEC_VOLUME("Beep Playback Volume", 0x23, 0, HDA_OUTPUT),
201 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x23, 0, HDA_OUTPUT), 201 HDA_CODEC_MUTE("Beep Playback Switch", 0x23, 0, HDA_OUTPUT),
202 { } /* end */ 202 { } /* end */
203}; 203};
204 204
@@ -315,7 +315,8 @@ static struct hda_verb cmi9880_allout_init[] = {
315static int cmi9880_build_controls(struct hda_codec *codec) 315static int cmi9880_build_controls(struct hda_codec *codec)
316{ 316{
317 struct cmi_spec *spec = codec->spec; 317 struct cmi_spec *spec = codec->spec;
318 int err; 318 struct snd_kcontrol *kctl;
319 int i, err;
319 320
320 err = snd_hda_add_new_ctls(codec, cmi9880_basic_mixer); 321 err = snd_hda_add_new_ctls(codec, cmi9880_basic_mixer);
321 if (err < 0) 322 if (err < 0)
@@ -340,6 +341,14 @@ static int cmi9880_build_controls(struct hda_codec *codec)
340 if (err < 0) 341 if (err < 0)
341 return err; 342 return err;
342 } 343 }
344
345 /* assign Capture Source enums to NID */
346 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
347 for (i = 0; kctl && i < kctl->count; i++) {
348 err = snd_hda_add_nid(codec, kctl, i, spec->adc_nids[i]);
349 if (err < 0)
350 return err;
351 }
343 return 0; 352 return 0;
344} 353}
345 354
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 905859d4f4df..feabb44c7ca4 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -29,6 +29,7 @@
29 29
30#include "hda_codec.h" 30#include "hda_codec.h"
31#include "hda_local.h" 31#include "hda_local.h"
32#include "hda_beep.h"
32 33
33#define CXT_PIN_DIR_IN 0x00 34#define CXT_PIN_DIR_IN 0x00
34#define CXT_PIN_DIR_OUT 0x01 35#define CXT_PIN_DIR_OUT 0x01
@@ -41,10 +42,12 @@
41 42
42/* Conexant 5051 specific */ 43/* Conexant 5051 specific */
43 44
44#define CXT5051_SPDIF_OUT 0x1C 45#define CXT5051_SPDIF_OUT 0x12
45#define CXT5051_PORTB_EVENT 0x38 46#define CXT5051_PORTB_EVENT 0x38
46#define CXT5051_PORTC_EVENT 0x39 47#define CXT5051_PORTC_EVENT 0x39
47 48
49#define AUTO_MIC_PORTB (1 << 1)
50#define AUTO_MIC_PORTC (1 << 2)
48 51
49struct conexant_jack { 52struct conexant_jack {
50 53
@@ -73,7 +76,7 @@ struct conexant_spec {
73 */ 76 */
74 unsigned int cur_eapd; 77 unsigned int cur_eapd;
75 unsigned int hp_present; 78 unsigned int hp_present;
76 unsigned int no_auto_mic; 79 unsigned int auto_mic;
77 unsigned int need_dac_fix; 80 unsigned int need_dac_fix;
78 81
79 /* capture */ 82 /* capture */
@@ -110,7 +113,23 @@ struct conexant_spec {
110 113
111 unsigned int dell_automute; 114 unsigned int dell_automute;
112 unsigned int port_d_mode; 115 unsigned int port_d_mode;
113 unsigned char ext_mic_bias; 116 unsigned int dell_vostro:1;
117 unsigned int ideapad:1;
118
119 unsigned int ext_mic_present;
120 unsigned int recording;
121 void (*capture_prepare)(struct hda_codec *codec);
122 void (*capture_cleanup)(struct hda_codec *codec);
123
124 /* OLPC XO-1.5 supports DC input mode (e.g. for use with analog sensors)
125 * through the microphone jack.
126 * When the user enables this through a mixer switch, both internal and
127 * external microphones are disabled. Gain is fixed at 0dB. In this mode,
128 * we also allow the bias to be configured through a separate mixer
129 * control. */
130 unsigned int dc_enable;
131 unsigned int dc_input_bias; /* offset into cxt5066_olpc_dc_bias */
132 unsigned int mic_boost; /* offset into cxt5066_analog_mic_boost */
114}; 133};
115 134
116static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo, 135static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo,
@@ -183,6 +202,8 @@ static int conexant_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
183 struct snd_pcm_substream *substream) 202 struct snd_pcm_substream *substream)
184{ 203{
185 struct conexant_spec *spec = codec->spec; 204 struct conexant_spec *spec = codec->spec;
205 if (spec->capture_prepare)
206 spec->capture_prepare(codec);
186 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 207 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
187 stream_tag, 0, format); 208 stream_tag, 0, format);
188 return 0; 209 return 0;
@@ -194,6 +215,8 @@ static int conexant_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
194{ 215{
195 struct conexant_spec *spec = codec->spec; 216 struct conexant_spec *spec = codec->spec;
196 snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]); 217 snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]);
218 if (spec->capture_cleanup)
219 spec->capture_cleanup(codec);
197 return 0; 220 return 0;
198} 221}
199 222
@@ -397,9 +420,7 @@ static void conexant_report_jack(struct hda_codec *codec, hda_nid_t nid)
397 for (i = 0; i < spec->jacks.used; i++) { 420 for (i = 0; i < spec->jacks.used; i++) {
398 if (jacks->nid == nid) { 421 if (jacks->nid == nid) {
399 unsigned int present; 422 unsigned int present;
400 present = snd_hda_codec_read(codec, nid, 0, 423 present = snd_hda_jack_detect(codec, nid);
401 AC_VERB_GET_PIN_SENSE, 0) &
402 AC_PINSENSE_PRESENCE;
403 424
404 present = (present) ? jacks->type : 0 ; 425 present = (present) ? jacks->type : 0 ;
405 426
@@ -478,6 +499,7 @@ static void conexant_free(struct hda_codec *codec)
478 snd_array_free(&spec->jacks); 499 snd_array_free(&spec->jacks);
479 } 500 }
480#endif 501#endif
502 snd_hda_detach_beep_device(codec);
481 kfree(codec->spec); 503 kfree(codec->spec);
482} 504}
483 505
@@ -750,8 +772,7 @@ static void cxt5045_hp_automic(struct hda_codec *codec)
750 }; 772 };
751 unsigned int present; 773 unsigned int present;
752 774
753 present = snd_hda_codec_read(codec, 0x12, 0, 775 present = snd_hda_jack_detect(codec, 0x12);
754 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
755 if (present) 776 if (present)
756 snd_hda_sequence_write(codec, mic_jack_on); 777 snd_hda_sequence_write(codec, mic_jack_on);
757 else 778 else
@@ -765,8 +786,7 @@ static void cxt5045_hp_automute(struct hda_codec *codec)
765 struct conexant_spec *spec = codec->spec; 786 struct conexant_spec *spec = codec->spec;
766 unsigned int bits; 787 unsigned int bits;
767 788
768 spec->hp_present = snd_hda_codec_read(codec, 0x11, 0, 789 spec->hp_present = snd_hda_jack_detect(codec, 0x11);
769 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
770 790
771 bits = (spec->hp_present || !spec->cur_eapd) ? HDA_AMP_MUTE : 0; 791 bits = (spec->hp_present || !spec->cur_eapd) ? HDA_AMP_MUTE : 0;
772 snd_hda_codec_amp_stereo(codec, 0x10, HDA_OUTPUT, 0, 792 snd_hda_codec_amp_stereo(codec, 0x10, HDA_OUTPUT, 0,
@@ -1175,9 +1195,12 @@ static int patch_cxt5045(struct hda_codec *codec)
1175 1195
1176 switch (codec->subsystem_id >> 16) { 1196 switch (codec->subsystem_id >> 16) {
1177 case 0x103c: 1197 case 0x103c:
1178 /* HP laptop has a really bad sound over 0dB on NID 0x17. 1198 case 0x1631:
1179 * Fix max PCM level to 0 dB 1199 case 0x1734:
1180 * (originall it has 0x2b steps with 0dB offset 0x14) 1200 case 0x17aa:
1201 /* HP, Packard Bell, Fujitsu-Siemens & Lenovo laptops have
1202 * really bad sound over 0dB on NID 0x17. Fix max PCM level to
1203 * 0 dB (originally it has 0x2b steps with 0dB offset 0x14)
1181 */ 1204 */
1182 snd_hda_override_amp_caps(codec, 0x17, HDA_INPUT, 1205 snd_hda_override_amp_caps(codec, 0x17, HDA_INPUT,
1183 (0x14 << AC_AMPCAP_OFFSET_SHIFT) | 1206 (0x14 << AC_AMPCAP_OFFSET_SHIFT) |
@@ -1243,8 +1266,7 @@ static void cxt5047_hp_automute(struct hda_codec *codec)
1243 struct conexant_spec *spec = codec->spec; 1266 struct conexant_spec *spec = codec->spec;
1244 unsigned int bits; 1267 unsigned int bits;
1245 1268
1246 spec->hp_present = snd_hda_codec_read(codec, 0x13, 0, 1269 spec->hp_present = snd_hda_jack_detect(codec, 0x13);
1247 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1248 1270
1249 bits = (spec->hp_present || !spec->cur_eapd) ? HDA_AMP_MUTE : 0; 1271 bits = (spec->hp_present || !spec->cur_eapd) ? HDA_AMP_MUTE : 0;
1250 /* See the note in cxt5047_hp_master_sw_put */ 1272 /* See the note in cxt5047_hp_master_sw_put */
@@ -1267,8 +1289,7 @@ static void cxt5047_hp_automic(struct hda_codec *codec)
1267 }; 1289 };
1268 unsigned int present; 1290 unsigned int present;
1269 1291
1270 present = snd_hda_codec_read(codec, 0x15, 0, 1292 present = snd_hda_jack_detect(codec, 0x15);
1271 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1272 if (present) 1293 if (present)
1273 snd_hda_sequence_write(codec, mic_jack_on); 1294 snd_hda_sequence_write(codec, mic_jack_on);
1274 else 1295 else
@@ -1415,16 +1436,7 @@ static struct snd_kcontrol_new cxt5047_test_mixer[] = {
1415 .get = conexant_mux_enum_get, 1436 .get = conexant_mux_enum_get,
1416 .put = conexant_mux_enum_put, 1437 .put = conexant_mux_enum_put,
1417 }, 1438 },
1418 HDA_CODEC_VOLUME("Input-1 Volume", 0x1a, 0x0, HDA_INPUT), 1439 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1a, 0x0, HDA_OUTPUT),
1419 HDA_CODEC_MUTE("Input-1 Switch", 0x1a, 0x0, HDA_INPUT),
1420 HDA_CODEC_VOLUME("Input-2 Volume", 0x1a, 0x1, HDA_INPUT),
1421 HDA_CODEC_MUTE("Input-2 Switch", 0x1a, 0x1, HDA_INPUT),
1422 HDA_CODEC_VOLUME("Input-3 Volume", 0x1a, 0x2, HDA_INPUT),
1423 HDA_CODEC_MUTE("Input-3 Switch", 0x1a, 0x2, HDA_INPUT),
1424 HDA_CODEC_VOLUME("Input-4 Volume", 0x1a, 0x3, HDA_INPUT),
1425 HDA_CODEC_MUTE("Input-4 Switch", 0x1a, 0x3, HDA_INPUT),
1426 HDA_CODEC_VOLUME("Input-5 Volume", 0x1a, 0x4, HDA_INPUT),
1427 HDA_CODEC_MUTE("Input-5 Switch", 0x1a, 0x4, HDA_INPUT),
1428 1440
1429 { } /* end */ 1441 { } /* end */
1430}; 1442};
@@ -1581,6 +1593,21 @@ static int patch_cxt5047(struct hda_codec *codec)
1581#endif 1593#endif
1582 } 1594 }
1583 spec->vmaster_nid = 0x13; 1595 spec->vmaster_nid = 0x13;
1596
1597 switch (codec->subsystem_id >> 16) {
1598 case 0x103c:
1599 /* HP laptops have really bad sound over 0 dB on NID 0x10.
1600 * Fix max PCM level to 0 dB (originally it has 0x1e steps
1601 * with 0 dB offset 0x17)
1602 */
1603 snd_hda_override_amp_caps(codec, 0x10, HDA_INPUT,
1604 (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
1605 (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
1606 (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
1607 (1 << AC_AMPCAP_MUTE_SHIFT));
1608 break;
1609 }
1610
1584 return 0; 1611 return 0;
1585} 1612}
1586 1613
@@ -1596,6 +1623,11 @@ static void cxt5051_update_speaker(struct hda_codec *codec)
1596{ 1623{
1597 struct conexant_spec *spec = codec->spec; 1624 struct conexant_spec *spec = codec->spec;
1598 unsigned int pinctl; 1625 unsigned int pinctl;
1626 /* headphone pin */
1627 pinctl = (spec->hp_present && spec->cur_eapd) ? PIN_HP : 0;
1628 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
1629 pinctl);
1630 /* speaker pin */
1599 pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0; 1631 pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0;
1600 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 1632 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
1601 pinctl); 1633 pinctl);
@@ -1619,11 +1651,9 @@ static void cxt5051_portb_automic(struct hda_codec *codec)
1619 struct conexant_spec *spec = codec->spec; 1651 struct conexant_spec *spec = codec->spec;
1620 unsigned int present; 1652 unsigned int present;
1621 1653
1622 if (spec->no_auto_mic) 1654 if (!(spec->auto_mic & AUTO_MIC_PORTB))
1623 return; 1655 return;
1624 present = snd_hda_codec_read(codec, 0x17, 0, 1656 present = snd_hda_jack_detect(codec, 0x17);
1625 AC_VERB_GET_PIN_SENSE, 0) &
1626 AC_PINSENSE_PRESENCE;
1627 snd_hda_codec_write(codec, 0x14, 0, 1657 snd_hda_codec_write(codec, 0x14, 0,
1628 AC_VERB_SET_CONNECT_SEL, 1658 AC_VERB_SET_CONNECT_SEL,
1629 present ? 0x01 : 0x00); 1659 present ? 0x01 : 0x00);
@@ -1636,11 +1666,9 @@ static void cxt5051_portc_automic(struct hda_codec *codec)
1636 unsigned int present; 1666 unsigned int present;
1637 hda_nid_t new_adc; 1667 hda_nid_t new_adc;
1638 1668
1639 if (spec->no_auto_mic) 1669 if (!(spec->auto_mic & AUTO_MIC_PORTC))
1640 return; 1670 return;
1641 present = snd_hda_codec_read(codec, 0x18, 0, 1671 present = snd_hda_jack_detect(codec, 0x18);
1642 AC_VERB_GET_PIN_SENSE, 0) &
1643 AC_PINSENSE_PRESENCE;
1644 if (present) 1672 if (present)
1645 spec->cur_adc_idx = 1; 1673 spec->cur_adc_idx = 1;
1646 else 1674 else
@@ -1661,9 +1689,7 @@ static void cxt5051_hp_automute(struct hda_codec *codec)
1661{ 1689{
1662 struct conexant_spec *spec = codec->spec; 1690 struct conexant_spec *spec = codec->spec;
1663 1691
1664 spec->hp_present = snd_hda_codec_read(codec, 0x16, 0, 1692 spec->hp_present = snd_hda_jack_detect(codec, 0x16);
1665 AC_VERB_GET_PIN_SENSE, 0) &
1666 AC_PINSENSE_PRESENCE;
1667 cxt5051_update_speaker(codec); 1693 cxt5051_update_speaker(codec);
1668} 1694}
1669 1695
@@ -1686,13 +1712,7 @@ static void cxt5051_hp_unsol_event(struct hda_codec *codec,
1686 conexant_report_jack(codec, nid); 1712 conexant_report_jack(codec, nid);
1687} 1713}
1688 1714
1689static struct snd_kcontrol_new cxt5051_mixers[] = { 1715static struct snd_kcontrol_new cxt5051_playback_mixers[] = {
1690 HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1691 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1692 HDA_CODEC_VOLUME("External Mic Volume", 0x14, 0x01, HDA_INPUT),
1693 HDA_CODEC_MUTE("External Mic Switch", 0x14, 0x01, HDA_INPUT),
1694 HDA_CODEC_VOLUME("Docking Mic Volume", 0x15, 0x00, HDA_INPUT),
1695 HDA_CODEC_MUTE("Docking Mic Switch", 0x15, 0x00, HDA_INPUT),
1696 HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT), 1716 HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT),
1697 { 1717 {
1698 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1718 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -1702,7 +1722,16 @@ static struct snd_kcontrol_new cxt5051_mixers[] = {
1702 .put = cxt5051_hp_master_sw_put, 1722 .put = cxt5051_hp_master_sw_put,
1703 .private_value = 0x1a, 1723 .private_value = 0x1a,
1704 }, 1724 },
1725 {}
1726};
1705 1727
1728static struct snd_kcontrol_new cxt5051_capture_mixers[] = {
1729 HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1730 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1731 HDA_CODEC_VOLUME("External Mic Volume", 0x14, 0x01, HDA_INPUT),
1732 HDA_CODEC_MUTE("External Mic Switch", 0x14, 0x01, HDA_INPUT),
1733 HDA_CODEC_VOLUME("Docking Mic Volume", 0x15, 0x00, HDA_INPUT),
1734 HDA_CODEC_MUTE("Docking Mic Switch", 0x15, 0x00, HDA_INPUT),
1706 {} 1735 {}
1707}; 1736};
1708 1737
@@ -1711,32 +1740,26 @@ static struct snd_kcontrol_new cxt5051_hp_mixers[] = {
1711 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT), 1740 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1712 HDA_CODEC_VOLUME("External Mic Volume", 0x15, 0x00, HDA_INPUT), 1741 HDA_CODEC_VOLUME("External Mic Volume", 0x15, 0x00, HDA_INPUT),
1713 HDA_CODEC_MUTE("External Mic Switch", 0x15, 0x00, HDA_INPUT), 1742 HDA_CODEC_MUTE("External Mic Switch", 0x15, 0x00, HDA_INPUT),
1714 HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT),
1715 {
1716 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1717 .name = "Master Playback Switch",
1718 .info = cxt_eapd_info,
1719 .get = cxt_eapd_get,
1720 .put = cxt5051_hp_master_sw_put,
1721 .private_value = 0x1a,
1722 },
1723
1724 {} 1743 {}
1725}; 1744};
1726 1745
1727static struct snd_kcontrol_new cxt5051_hp_dv6736_mixers[] = { 1746static struct snd_kcontrol_new cxt5051_hp_dv6736_mixers[] = {
1728 HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x00, HDA_INPUT), 1747 HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x00, HDA_INPUT),
1729 HDA_CODEC_MUTE("Mic Switch", 0x14, 0x00, HDA_INPUT), 1748 HDA_CODEC_MUTE("Capture Switch", 0x14, 0x00, HDA_INPUT),
1730 HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT), 1749 {}
1731 { 1750};
1732 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1733 .name = "Master Playback Switch",
1734 .info = cxt_eapd_info,
1735 .get = cxt_eapd_get,
1736 .put = cxt5051_hp_master_sw_put,
1737 .private_value = 0x1a,
1738 },
1739 1751
1752static struct snd_kcontrol_new cxt5051_f700_mixers[] = {
1753 HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x01, HDA_INPUT),
1754 HDA_CODEC_MUTE("Capture Switch", 0x14, 0x01, HDA_INPUT),
1755 {}
1756};
1757
1758static struct snd_kcontrol_new cxt5051_toshiba_mixers[] = {
1759 HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1760 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1761 HDA_CODEC_VOLUME("External Mic Volume", 0x14, 0x01, HDA_INPUT),
1762 HDA_CODEC_MUTE("External Mic Switch", 0x14, 0x01, HDA_INPUT),
1740 {} 1763 {}
1741}; 1764};
1742 1765
@@ -1765,8 +1788,6 @@ static struct hda_verb cxt5051_init_verbs[] = {
1765 /* EAPD */ 1788 /* EAPD */
1766 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ 1789 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
1767 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT}, 1790 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1768 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTB_EVENT},
1769 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTC_EVENT},
1770 { } /* end */ 1791 { } /* end */
1771}; 1792};
1772 1793
@@ -1792,7 +1813,6 @@ static struct hda_verb cxt5051_hp_dv6736_init_verbs[] = {
1792 /* EAPD */ 1813 /* EAPD */
1793 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ 1814 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
1794 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT}, 1815 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1795 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTB_EVENT},
1796 { } /* end */ 1816 { } /* end */
1797}; 1817};
1798 1818
@@ -1824,17 +1844,60 @@ static struct hda_verb cxt5051_lenovo_x200_init_verbs[] = {
1824 /* EAPD */ 1844 /* EAPD */
1825 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ 1845 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
1826 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT}, 1846 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1827 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTB_EVENT},
1828 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTC_EVENT},
1829 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT}, 1847 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1830 { } /* end */ 1848 { } /* end */
1831}; 1849};
1832 1850
1851static struct hda_verb cxt5051_f700_init_verbs[] = {
1852 /* Line in, Mic */
1853 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1854 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1855 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0},
1856 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0},
1857 /* SPK */
1858 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1859 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
1860 /* HP, Amp */
1861 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1862 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
1863 /* DAC1 */
1864 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1865 /* Record selector: Int mic */
1866 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
1867 {0x14, AC_VERB_SET_CONNECT_SEL, 0x1},
1868 /* SPDIF route: PCM */
1869 {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0},
1870 /* EAPD */
1871 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
1872 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1873 { } /* end */
1874};
1875
1876static void cxt5051_init_mic_port(struct hda_codec *codec, hda_nid_t nid,
1877 unsigned int event)
1878{
1879 snd_hda_codec_write(codec, nid, 0,
1880 AC_VERB_SET_UNSOLICITED_ENABLE,
1881 AC_USRSP_EN | event);
1882#ifdef CONFIG_SND_HDA_INPUT_JACK
1883 conexant_add_jack(codec, nid, SND_JACK_MICROPHONE);
1884 conexant_report_jack(codec, nid);
1885#endif
1886}
1887
1833/* initialize jack-sensing, too */ 1888/* initialize jack-sensing, too */
1834static int cxt5051_init(struct hda_codec *codec) 1889static int cxt5051_init(struct hda_codec *codec)
1835{ 1890{
1891 struct conexant_spec *spec = codec->spec;
1892
1836 conexant_init(codec); 1893 conexant_init(codec);
1837 conexant_init_jacks(codec); 1894 conexant_init_jacks(codec);
1895
1896 if (spec->auto_mic & AUTO_MIC_PORTB)
1897 cxt5051_init_mic_port(codec, 0x17, CXT5051_PORTB_EVENT);
1898 if (spec->auto_mic & AUTO_MIC_PORTC)
1899 cxt5051_init_mic_port(codec, 0x18, CXT5051_PORTC_EVENT);
1900
1838 if (codec->patch_ops.unsol_event) { 1901 if (codec->patch_ops.unsol_event) {
1839 cxt5051_hp_automute(codec); 1902 cxt5051_hp_automute(codec);
1840 cxt5051_portb_automic(codec); 1903 cxt5051_portb_automic(codec);
@@ -1849,6 +1912,8 @@ enum {
1849 CXT5051_HP, /* no docking */ 1912 CXT5051_HP, /* no docking */
1850 CXT5051_HP_DV6736, /* HP without mic switch */ 1913 CXT5051_HP_DV6736, /* HP without mic switch */
1851 CXT5051_LENOVO_X200, /* Lenovo X200 laptop */ 1914 CXT5051_LENOVO_X200, /* Lenovo X200 laptop */
1915 CXT5051_F700, /* HP Compaq Presario F700 */
1916 CXT5051_TOSHIBA, /* Toshiba M300 & co */
1852 CXT5051_MODELS 1917 CXT5051_MODELS
1853}; 1918};
1854 1919
@@ -1857,11 +1922,15 @@ static const char *cxt5051_models[CXT5051_MODELS] = {
1857 [CXT5051_HP] = "hp", 1922 [CXT5051_HP] = "hp",
1858 [CXT5051_HP_DV6736] = "hp-dv6736", 1923 [CXT5051_HP_DV6736] = "hp-dv6736",
1859 [CXT5051_LENOVO_X200] = "lenovo-x200", 1924 [CXT5051_LENOVO_X200] = "lenovo-x200",
1925 [CXT5051_F700] = "hp-700",
1926 [CXT5051_TOSHIBA] = "toshiba",
1860}; 1927};
1861 1928
1862static struct snd_pci_quirk cxt5051_cfg_tbl[] = { 1929static struct snd_pci_quirk cxt5051_cfg_tbl[] = {
1863 SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV6736", CXT5051_HP_DV6736), 1930 SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV6736", CXT5051_HP_DV6736),
1864 SND_PCI_QUIRK(0x103c, 0x360b, "Compaq Presario CQ60", CXT5051_HP), 1931 SND_PCI_QUIRK(0x103c, 0x360b, "Compaq Presario CQ60", CXT5051_HP),
1932 SND_PCI_QUIRK(0x103c, 0x30ea, "Compaq Presario F700", CXT5051_F700),
1933 SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba M30x", CXT5051_TOSHIBA),
1865 SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board", 1934 SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board",
1866 CXT5051_LAPTOP), 1935 CXT5051_LAPTOP),
1867 SND_PCI_QUIRK(0x14f1, 0x5051, "HP Spartan 1.1", CXT5051_HP), 1936 SND_PCI_QUIRK(0x14f1, 0x5051, "HP Spartan 1.1", CXT5051_HP),
@@ -1889,8 +1958,9 @@ static int patch_cxt5051(struct hda_codec *codec)
1889 spec->multiout.dig_out_nid = CXT5051_SPDIF_OUT; 1958 spec->multiout.dig_out_nid = CXT5051_SPDIF_OUT;
1890 spec->num_adc_nids = 1; /* not 2; via auto-mic switch */ 1959 spec->num_adc_nids = 1; /* not 2; via auto-mic switch */
1891 spec->adc_nids = cxt5051_adc_nids; 1960 spec->adc_nids = cxt5051_adc_nids;
1892 spec->num_mixers = 1; 1961 spec->num_mixers = 2;
1893 spec->mixers[0] = cxt5051_mixers; 1962 spec->mixers[0] = cxt5051_capture_mixers;
1963 spec->mixers[1] = cxt5051_playback_mixers;
1894 spec->num_init_verbs = 1; 1964 spec->num_init_verbs = 1;
1895 spec->init_verbs[0] = cxt5051_init_verbs; 1965 spec->init_verbs[0] = cxt5051_init_verbs;
1896 spec->spdif_route = 0; 1966 spec->spdif_route = 0;
@@ -1904,6 +1974,7 @@ static int patch_cxt5051(struct hda_codec *codec)
1904 board_config = snd_hda_check_board_config(codec, CXT5051_MODELS, 1974 board_config = snd_hda_check_board_config(codec, CXT5051_MODELS,
1905 cxt5051_models, 1975 cxt5051_models,
1906 cxt5051_cfg_tbl); 1976 cxt5051_cfg_tbl);
1977 spec->auto_mic = AUTO_MIC_PORTB | AUTO_MIC_PORTC;
1907 switch (board_config) { 1978 switch (board_config) {
1908 case CXT5051_HP: 1979 case CXT5051_HP:
1909 spec->mixers[0] = cxt5051_hp_mixers; 1980 spec->mixers[0] = cxt5051_hp_mixers;
@@ -1911,11 +1982,20 @@ static int patch_cxt5051(struct hda_codec *codec)
1911 case CXT5051_HP_DV6736: 1982 case CXT5051_HP_DV6736:
1912 spec->init_verbs[0] = cxt5051_hp_dv6736_init_verbs; 1983 spec->init_verbs[0] = cxt5051_hp_dv6736_init_verbs;
1913 spec->mixers[0] = cxt5051_hp_dv6736_mixers; 1984 spec->mixers[0] = cxt5051_hp_dv6736_mixers;
1914 spec->no_auto_mic = 1; 1985 spec->auto_mic = 0;
1915 break; 1986 break;
1916 case CXT5051_LENOVO_X200: 1987 case CXT5051_LENOVO_X200:
1917 spec->init_verbs[0] = cxt5051_lenovo_x200_init_verbs; 1988 spec->init_verbs[0] = cxt5051_lenovo_x200_init_verbs;
1918 break; 1989 break;
1990 case CXT5051_F700:
1991 spec->init_verbs[0] = cxt5051_f700_init_verbs;
1992 spec->mixers[0] = cxt5051_f700_mixers;
1993 spec->auto_mic = 0;
1994 break;
1995 case CXT5051_TOSHIBA:
1996 spec->mixers[0] = cxt5051_toshiba_mixers;
1997 spec->auto_mic = AUTO_MIC_PORTB;
1998 break;
1919 } 1999 }
1920 2000
1921 return 0; 2001 return 0;
@@ -1983,36 +2063,147 @@ static int cxt5066_hp_master_sw_put(struct snd_kcontrol *kcontrol,
1983 return 1; 2063 return 1;
1984} 2064}
1985 2065
2066static const struct hda_input_mux cxt5066_olpc_dc_bias = {
2067 .num_items = 3,
2068 .items = {
2069 { "Off", PIN_IN },
2070 { "50%", PIN_VREF50 },
2071 { "80%", PIN_VREF80 },
2072 },
2073};
2074
2075static int cxt5066_set_olpc_dc_bias(struct hda_codec *codec)
2076{
2077 struct conexant_spec *spec = codec->spec;
2078 /* Even though port F is the DC input, the bias is controlled on port B.
2079 * we also leave that port as an active input (but unselected) in DC mode
2080 * just in case that is necessary to make the bias setting take effect. */
2081 return snd_hda_codec_write_cache(codec, 0x1a, 0,
2082 AC_VERB_SET_PIN_WIDGET_CONTROL,
2083 cxt5066_olpc_dc_bias.items[spec->dc_input_bias].index);
2084}
2085
2086/* OLPC defers mic widget control until when capture is started because the
2087 * microphone LED comes on as soon as these settings are put in place. if we
2088 * did this before recording, it would give the false indication that recording
2089 * is happening when it is not. */
2090static void cxt5066_olpc_select_mic(struct hda_codec *codec)
2091{
2092 struct conexant_spec *spec = codec->spec;
2093 if (!spec->recording)
2094 return;
2095
2096 if (spec->dc_enable) {
2097 /* in DC mode we ignore presence detection and just use the jack
2098 * through our special DC port */
2099 const struct hda_verb enable_dc_mode[] = {
2100 /* disble internal mic, port C */
2101 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2102
2103 /* enable DC capture, port F */
2104 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2105 {},
2106 };
2107
2108 snd_hda_sequence_write(codec, enable_dc_mode);
2109 /* port B input disabled (and bias set) through the following call */
2110 cxt5066_set_olpc_dc_bias(codec);
2111 return;
2112 }
2113
2114 /* disable DC (port F) */
2115 snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
2116
2117 /* external mic, port B */
2118 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
2119 spec->ext_mic_present ? CXT5066_OLPC_EXT_MIC_BIAS : 0);
2120
2121 /* internal mic, port C */
2122 snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
2123 spec->ext_mic_present ? 0 : PIN_VREF80);
2124}
2125
1986/* toggle input of built-in and mic jack appropriately */ 2126/* toggle input of built-in and mic jack appropriately */
1987static void cxt5066_automic(struct hda_codec *codec) 2127static void cxt5066_olpc_automic(struct hda_codec *codec)
1988{ 2128{
1989 struct conexant_spec *spec = codec->spec; 2129 struct conexant_spec *spec = codec->spec;
2130 unsigned int present;
2131
2132 if (spec->dc_enable) /* don't do presence detection in DC mode */
2133 return;
2134
2135 present = snd_hda_codec_read(codec, 0x1a, 0,
2136 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2137 if (present)
2138 snd_printdd("CXT5066: external microphone detected\n");
2139 else
2140 snd_printdd("CXT5066: external microphone absent\n");
2141
2142 snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_CONNECT_SEL,
2143 present ? 0 : 1);
2144 spec->ext_mic_present = !!present;
2145
2146 cxt5066_olpc_select_mic(codec);
2147}
2148
2149/* toggle input of built-in digital mic and mic jack appropriately */
2150static void cxt5066_vostro_automic(struct hda_codec *codec)
2151{
2152 unsigned int present;
2153
1990 struct hda_verb ext_mic_present[] = { 2154 struct hda_verb ext_mic_present[] = {
1991 /* enable external mic, port B */ 2155 /* enable external mic, port B */
1992 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, spec->ext_mic_bias}, 2156 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1993 2157
1994 /* switch to external mic input */ 2158 /* switch to external mic input */
1995 {0x17, AC_VERB_SET_CONNECT_SEL, 0}, 2159 {0x17, AC_VERB_SET_CONNECT_SEL, 0},
2160 {0x14, AC_VERB_SET_CONNECT_SEL, 0},
1996 2161
1997 /* disable internal mic, port C */ 2162 /* disable internal digital mic */
1998 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2163 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
1999 {} 2164 {}
2000 }; 2165 };
2001 static struct hda_verb ext_mic_absent[] = { 2166 static struct hda_verb ext_mic_absent[] = {
2002 /* enable internal mic, port C */ 2167 /* enable internal mic, port C */
2003 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2168 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2004 2169
2005 /* switch to internal mic input */ 2170 /* switch to internal mic input */
2006 {0x17, AC_VERB_SET_CONNECT_SEL, 1}, 2171 {0x14, AC_VERB_SET_CONNECT_SEL, 2},
2007 2172
2008 /* disable external mic, port B */ 2173 /* disable external mic, port B */
2009 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2174 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2010 {} 2175 {}
2011 }; 2176 };
2177
2178 present = snd_hda_jack_detect(codec, 0x1a);
2179 if (present) {
2180 snd_printdd("CXT5066: external microphone detected\n");
2181 snd_hda_sequence_write(codec, ext_mic_present);
2182 } else {
2183 snd_printdd("CXT5066: external microphone absent\n");
2184 snd_hda_sequence_write(codec, ext_mic_absent);
2185 }
2186}
2187
2188/* toggle input of built-in digital mic and mic jack appropriately */
2189static void cxt5066_ideapad_automic(struct hda_codec *codec)
2190{
2012 unsigned int present; 2191 unsigned int present;
2013 2192
2014 present = snd_hda_codec_read(codec, 0x1a, 0, 2193 struct hda_verb ext_mic_present[] = {
2015 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 2194 {0x14, AC_VERB_SET_CONNECT_SEL, 0},
2195 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2196 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2197 {}
2198 };
2199 static struct hda_verb ext_mic_absent[] = {
2200 {0x14, AC_VERB_SET_CONNECT_SEL, 2},
2201 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2202 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2203 {}
2204 };
2205
2206 present = snd_hda_jack_detect(codec, 0x1b);
2016 if (present) { 2207 if (present) {
2017 snd_printdd("CXT5066: external microphone detected\n"); 2208 snd_printdd("CXT5066: external microphone detected\n");
2018 snd_hda_sequence_write(codec, ext_mic_present); 2209 snd_hda_sequence_write(codec, ext_mic_present);
@@ -2029,12 +2220,10 @@ static void cxt5066_hp_automute(struct hda_codec *codec)
2029 unsigned int portA, portD; 2220 unsigned int portA, portD;
2030 2221
2031 /* Port A */ 2222 /* Port A */
2032 portA = snd_hda_codec_read(codec, 0x19, 0, AC_VERB_GET_PIN_SENSE, 0) 2223 portA = snd_hda_jack_detect(codec, 0x19);
2033 & AC_PINSENSE_PRESENCE;
2034 2224
2035 /* Port D */ 2225 /* Port D */
2036 portD = (snd_hda_codec_read(codec, 0x1c, 0, AC_VERB_GET_PIN_SENSE, 0) 2226 portD = snd_hda_jack_detect(codec, 0x1c);
2037 & AC_PINSENSE_PRESENCE) << 1;
2038 2227
2039 spec->hp_present = !!(portA | portD); 2228 spec->hp_present = !!(portA | portD);
2040 snd_printdd("CXT5066: hp automute portA=%x portD=%x present=%d\n", 2229 snd_printdd("CXT5066: hp automute portA=%x portD=%x present=%d\n",
@@ -2043,15 +2232,46 @@ static void cxt5066_hp_automute(struct hda_codec *codec)
2043} 2232}
2044 2233
2045/* unsolicited event for jack sensing */ 2234/* unsolicited event for jack sensing */
2046static void cxt5066_unsol_event(struct hda_codec *codec, unsigned int res) 2235static void cxt5066_olpc_unsol_event(struct hda_codec *codec, unsigned int res)
2047{ 2236{
2237 struct conexant_spec *spec = codec->spec;
2048 snd_printdd("CXT5066: unsol event %x (%x)\n", res, res >> 26); 2238 snd_printdd("CXT5066: unsol event %x (%x)\n", res, res >> 26);
2049 switch (res >> 26) { 2239 switch (res >> 26) {
2050 case CONEXANT_HP_EVENT: 2240 case CONEXANT_HP_EVENT:
2051 cxt5066_hp_automute(codec); 2241 cxt5066_hp_automute(codec);
2052 break; 2242 break;
2053 case CONEXANT_MIC_EVENT: 2243 case CONEXANT_MIC_EVENT:
2054 cxt5066_automic(codec); 2244 /* ignore mic events in DC mode; we're always using the jack */
2245 if (!spec->dc_enable)
2246 cxt5066_olpc_automic(codec);
2247 break;
2248 }
2249}
2250
2251/* unsolicited event for jack sensing */
2252static void cxt5066_vostro_event(struct hda_codec *codec, unsigned int res)
2253{
2254 snd_printdd("CXT5066_vostro: unsol event %x (%x)\n", res, res >> 26);
2255 switch (res >> 26) {
2256 case CONEXANT_HP_EVENT:
2257 cxt5066_hp_automute(codec);
2258 break;
2259 case CONEXANT_MIC_EVENT:
2260 cxt5066_vostro_automic(codec);
2261 break;
2262 }
2263}
2264
2265/* unsolicited event for jack sensing */
2266static void cxt5066_ideapad_event(struct hda_codec *codec, unsigned int res)
2267{
2268 snd_printdd("CXT5066_ideapad: unsol event %x (%x)\n", res, res >> 26);
2269 switch (res >> 26) {
2270 case CONEXANT_HP_EVENT:
2271 cxt5066_hp_automute(codec);
2272 break;
2273 case CONEXANT_MIC_EVENT:
2274 cxt5066_ideapad_automic(codec);
2055 break; 2275 break;
2056 } 2276 }
2057} 2277}
@@ -2067,6 +2287,23 @@ static const struct hda_input_mux cxt5066_analog_mic_boost = {
2067 }, 2287 },
2068}; 2288};
2069 2289
2290static void cxt5066_set_mic_boost(struct hda_codec *codec)
2291{
2292 struct conexant_spec *spec = codec->spec;
2293 snd_hda_codec_write_cache(codec, 0x17, 0,
2294 AC_VERB_SET_AMP_GAIN_MUTE,
2295 AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_OUTPUT |
2296 cxt5066_analog_mic_boost.items[spec->mic_boost].index);
2297 if (spec->ideapad) {
2298 /* adjust the internal mic as well...it is not through 0x17 */
2299 snd_hda_codec_write_cache(codec, 0x23, 0,
2300 AC_VERB_SET_AMP_GAIN_MUTE,
2301 AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_INPUT |
2302 cxt5066_analog_mic_boost.
2303 items[spec->mic_boost].index);
2304 }
2305}
2306
2070static int cxt5066_mic_boost_mux_enum_info(struct snd_kcontrol *kcontrol, 2307static int cxt5066_mic_boost_mux_enum_info(struct snd_kcontrol *kcontrol,
2071 struct snd_ctl_elem_info *uinfo) 2308 struct snd_ctl_elem_info *uinfo)
2072{ 2309{
@@ -2077,12 +2314,8 @@ static int cxt5066_mic_boost_mux_enum_get(struct snd_kcontrol *kcontrol,
2077 struct snd_ctl_elem_value *ucontrol) 2314 struct snd_ctl_elem_value *ucontrol)
2078{ 2315{
2079 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2316 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2080 int val; 2317 struct conexant_spec *spec = codec->spec;
2081 2318 ucontrol->value.enumerated.item[0] = spec->mic_boost;
2082 val = snd_hda_codec_read(codec, 0x17, 0,
2083 AC_VERB_GET_AMP_GAIN_MUTE, AC_AMP_GET_OUTPUT);
2084
2085 ucontrol->value.enumerated.item[0] = val & AC_AMP_GAIN;
2086 return 0; 2319 return 0;
2087} 2320}
2088 2321
@@ -2090,23 +2323,132 @@ static int cxt5066_mic_boost_mux_enum_put(struct snd_kcontrol *kcontrol,
2090 struct snd_ctl_elem_value *ucontrol) 2323 struct snd_ctl_elem_value *ucontrol)
2091{ 2324{
2092 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2325 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2326 struct conexant_spec *spec = codec->spec;
2093 const struct hda_input_mux *imux = &cxt5066_analog_mic_boost; 2327 const struct hda_input_mux *imux = &cxt5066_analog_mic_boost;
2094 unsigned int idx; 2328 unsigned int idx;
2329 idx = ucontrol->value.enumerated.item[0];
2330 if (idx >= imux->num_items)
2331 idx = imux->num_items - 1;
2095 2332
2096 if (!imux->num_items) 2333 spec->mic_boost = idx;
2334 if (!spec->dc_enable)
2335 cxt5066_set_mic_boost(codec);
2336 return 1;
2337}
2338
2339static void cxt5066_enable_dc(struct hda_codec *codec)
2340{
2341 const struct hda_verb enable_dc_mode[] = {
2342 /* disable gain */
2343 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2344
2345 /* switch to DC input */
2346 {0x17, AC_VERB_SET_CONNECT_SEL, 3},
2347 {}
2348 };
2349
2350 /* configure as input source */
2351 snd_hda_sequence_write(codec, enable_dc_mode);
2352 cxt5066_olpc_select_mic(codec); /* also sets configured bias */
2353}
2354
2355static void cxt5066_disable_dc(struct hda_codec *codec)
2356{
2357 /* reconfigure input source */
2358 cxt5066_set_mic_boost(codec);
2359 /* automic also selects the right mic if we're recording */
2360 cxt5066_olpc_automic(codec);
2361}
2362
2363static int cxt5066_olpc_dc_get(struct snd_kcontrol *kcontrol,
2364 struct snd_ctl_elem_value *ucontrol)
2365{
2366 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2367 struct conexant_spec *spec = codec->spec;
2368 ucontrol->value.integer.value[0] = spec->dc_enable;
2369 return 0;
2370}
2371
2372static int cxt5066_olpc_dc_put(struct snd_kcontrol *kcontrol,
2373 struct snd_ctl_elem_value *ucontrol)
2374{
2375 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2376 struct conexant_spec *spec = codec->spec;
2377 int dc_enable = !!ucontrol->value.integer.value[0];
2378
2379 if (dc_enable == spec->dc_enable)
2097 return 0; 2380 return 0;
2381
2382 spec->dc_enable = dc_enable;
2383 if (dc_enable)
2384 cxt5066_enable_dc(codec);
2385 else
2386 cxt5066_disable_dc(codec);
2387
2388 return 1;
2389}
2390
2391static int cxt5066_olpc_dc_bias_enum_info(struct snd_kcontrol *kcontrol,
2392 struct snd_ctl_elem_info *uinfo)
2393{
2394 return snd_hda_input_mux_info(&cxt5066_olpc_dc_bias, uinfo);
2395}
2396
2397static int cxt5066_olpc_dc_bias_enum_get(struct snd_kcontrol *kcontrol,
2398 struct snd_ctl_elem_value *ucontrol)
2399{
2400 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2401 struct conexant_spec *spec = codec->spec;
2402 ucontrol->value.enumerated.item[0] = spec->dc_input_bias;
2403 return 0;
2404}
2405
2406static int cxt5066_olpc_dc_bias_enum_put(struct snd_kcontrol *kcontrol,
2407 struct snd_ctl_elem_value *ucontrol)
2408{
2409 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2410 struct conexant_spec *spec = codec->spec;
2411 const struct hda_input_mux *imux = &cxt5066_analog_mic_boost;
2412 unsigned int idx;
2413
2098 idx = ucontrol->value.enumerated.item[0]; 2414 idx = ucontrol->value.enumerated.item[0];
2099 if (idx >= imux->num_items) 2415 if (idx >= imux->num_items)
2100 idx = imux->num_items - 1; 2416 idx = imux->num_items - 1;
2101 2417
2102 snd_hda_codec_write_cache(codec, 0x17, 0, 2418 spec->dc_input_bias = idx;
2103 AC_VERB_SET_AMP_GAIN_MUTE, 2419 if (spec->dc_enable)
2104 AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_OUTPUT | 2420 cxt5066_set_olpc_dc_bias(codec);
2105 imux->items[idx].index);
2106
2107 return 1; 2421 return 1;
2108} 2422}
2109 2423
2424static void cxt5066_olpc_capture_prepare(struct hda_codec *codec)
2425{
2426 struct conexant_spec *spec = codec->spec;
2427 /* mark as recording and configure the microphone widget so that the
2428 * recording LED comes on. */
2429 spec->recording = 1;
2430 cxt5066_olpc_select_mic(codec);
2431}
2432
2433static void cxt5066_olpc_capture_cleanup(struct hda_codec *codec)
2434{
2435 struct conexant_spec *spec = codec->spec;
2436 const struct hda_verb disable_mics[] = {
2437 /* disable external mic, port B */
2438 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2439
2440 /* disble internal mic, port C */
2441 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2442
2443 /* disable DC capture, port F */
2444 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2445 {},
2446 };
2447
2448 snd_hda_sequence_write(codec, disable_mics);
2449 spec->recording = 0;
2450}
2451
2110static struct hda_input_mux cxt5066_capture_source = { 2452static struct hda_input_mux cxt5066_capture_source = {
2111 .num_items = 4, 2453 .num_items = 4,
2112 .items = { 2454 .items = {
@@ -2147,6 +2489,7 @@ static struct snd_kcontrol_new cxt5066_mixer_master_olpc[] = {
2147 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | 2489 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
2148 SNDRV_CTL_ELEM_ACCESS_TLV_READ | 2490 SNDRV_CTL_ELEM_ACCESS_TLV_READ |
2149 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, 2491 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK,
2492 .subdevice = HDA_SUBDEV_AMP_FLAG,
2150 .info = snd_hda_mixer_amp_volume_info, 2493 .info = snd_hda_mixer_amp_volume_info,
2151 .get = snd_hda_mixer_amp_volume_get, 2494 .get = snd_hda_mixer_amp_volume_get,
2152 .put = snd_hda_mixer_amp_volume_put, 2495 .put = snd_hda_mixer_amp_volume_put,
@@ -2158,6 +2501,24 @@ static struct snd_kcontrol_new cxt5066_mixer_master_olpc[] = {
2158 {} 2501 {}
2159}; 2502};
2160 2503
2504static struct snd_kcontrol_new cxt5066_mixer_olpc_dc[] = {
2505 {
2506 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2507 .name = "DC Mode Enable Switch",
2508 .info = snd_ctl_boolean_mono_info,
2509 .get = cxt5066_olpc_dc_get,
2510 .put = cxt5066_olpc_dc_put,
2511 },
2512 {
2513 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2514 .name = "DC Input Bias Enum",
2515 .info = cxt5066_olpc_dc_bias_enum_info,
2516 .get = cxt5066_olpc_dc_bias_enum_get,
2517 .put = cxt5066_olpc_dc_bias_enum_put,
2518 },
2519 {}
2520};
2521
2161static struct snd_kcontrol_new cxt5066_mixers[] = { 2522static struct snd_kcontrol_new cxt5066_mixers[] = {
2162 { 2523 {
2163 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2524 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -2181,6 +2542,19 @@ static struct snd_kcontrol_new cxt5066_mixers[] = {
2181 {} 2542 {}
2182}; 2543};
2183 2544
2545static struct snd_kcontrol_new cxt5066_vostro_mixers[] = {
2546 {
2547 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2548 .name = "Int Mic Boost Capture Enum",
2549 .info = cxt5066_mic_boost_mux_enum_info,
2550 .get = cxt5066_mic_boost_mux_enum_get,
2551 .put = cxt5066_mic_boost_mux_enum_put,
2552 .private_value = 0x23 | 0x100,
2553 },
2554 HDA_CODEC_VOLUME_MONO("Beep Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
2555 {}
2556};
2557
2184static struct hda_verb cxt5066_init_verbs[] = { 2558static struct hda_verb cxt5066_init_verbs[] = {
2185 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */ 2559 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */
2186 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */ 2560 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */
@@ -2242,10 +2616,10 @@ static struct hda_verb cxt5066_init_verbs_olpc[] = {
2242 {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ 2616 {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2243 2617
2244 /* Port B: external microphone */ 2618 /* Port B: external microphone */
2245 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, CXT5066_OLPC_EXT_MIC_BIAS}, 2619 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2246 2620
2247 /* Port C: internal microphone */ 2621 /* Port C: internal microphone */
2248 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2622 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2249 2623
2250 /* Port D: unused */ 2624 /* Port D: unused */
2251 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2625 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
@@ -2254,7 +2628,7 @@ static struct hda_verb cxt5066_init_verbs_olpc[] = {
2254 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2628 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2255 {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ 2629 {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
2256 2630
2257 /* Port F: unused */ 2631 /* Port F: external DC input through microphone port */
2258 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 2632 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2259 2633
2260 /* Port G: internal speakers */ 2634 /* Port G: internal speakers */
@@ -2297,6 +2671,117 @@ static struct hda_verb cxt5066_init_verbs_olpc[] = {
2297 { } /* end */ 2671 { } /* end */
2298}; 2672};
2299 2673
2674static struct hda_verb cxt5066_init_verbs_vostro[] = {
2675 /* Port A: headphones */
2676 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2677 {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2678
2679 /* Port B: external microphone */
2680 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2681
2682 /* Port C: unused */
2683 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2684
2685 /* Port D: unused */
2686 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2687
2688 /* Port E: unused, but has primary EAPD */
2689 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2690 {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
2691
2692 /* Port F: unused */
2693 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2694
2695 /* Port G: internal speakers */
2696 {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2697 {0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2698
2699 /* DAC1 */
2700 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2701
2702 /* DAC2: unused */
2703 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2704
2705 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2706 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2707 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2708 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2709 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2710 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2711 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2712 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2713 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2714 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2715 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2716 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2717
2718 /* Digital microphone port */
2719 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2720
2721 /* Audio input selectors */
2722 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x3},
2723 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2724
2725 /* Disable SPDIF */
2726 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2727 {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2728
2729 /* enable unsolicited events for Port A and B */
2730 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
2731 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
2732 { } /* end */
2733};
2734
2735static struct hda_verb cxt5066_init_verbs_ideapad[] = {
2736 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */
2737 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */
2738 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */
2739 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port E */
2740
2741 /* Speakers */
2742 {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2743 {0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2744
2745 /* HP, Amp */
2746 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2747 {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2748
2749 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2750 {0x1c, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2751
2752 /* DAC1 */
2753 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2754
2755 /* Node 14 connections: 0x17 0x18 0x23 0x24 0x27 */
2756 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x50},
2757 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2758 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2) | 0x50},
2759 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2760 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2761 {0x14, AC_VERB_SET_CONNECT_SEL, 2}, /* default to internal mic */
2762
2763 /* Audio input selector */
2764 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x2},
2765 {0x17, AC_VERB_SET_CONNECT_SEL, 1}, /* route ext mic */
2766
2767 /* SPDIF route: PCM */
2768 {0x20, AC_VERB_SET_CONNECT_SEL, 0x0},
2769 {0x22, AC_VERB_SET_CONNECT_SEL, 0x0},
2770
2771 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2772 {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2773
2774 /* internal microphone */
2775 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* enable int mic */
2776
2777 /* EAPD */
2778 {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
2779
2780 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
2781 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
2782 { } /* end */
2783};
2784
2300static struct hda_verb cxt5066_init_verbs_portd_lo[] = { 2785static struct hda_verb cxt5066_init_verbs_portd_lo[] = {
2301 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2786 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2302 { } /* end */ 2787 { } /* end */
@@ -2305,11 +2790,32 @@ static struct hda_verb cxt5066_init_verbs_portd_lo[] = {
2305/* initialize jack-sensing, too */ 2790/* initialize jack-sensing, too */
2306static int cxt5066_init(struct hda_codec *codec) 2791static int cxt5066_init(struct hda_codec *codec)
2307{ 2792{
2793 struct conexant_spec *spec = codec->spec;
2794
2308 snd_printdd("CXT5066: init\n"); 2795 snd_printdd("CXT5066: init\n");
2309 conexant_init(codec); 2796 conexant_init(codec);
2310 if (codec->patch_ops.unsol_event) { 2797 if (codec->patch_ops.unsol_event) {
2311 cxt5066_hp_automute(codec); 2798 cxt5066_hp_automute(codec);
2312 cxt5066_automic(codec); 2799 if (spec->dell_vostro)
2800 cxt5066_vostro_automic(codec);
2801 else if (spec->ideapad)
2802 cxt5066_ideapad_automic(codec);
2803 }
2804 cxt5066_set_mic_boost(codec);
2805 return 0;
2806}
2807
2808static int cxt5066_olpc_init(struct hda_codec *codec)
2809{
2810 struct conexant_spec *spec = codec->spec;
2811 snd_printdd("CXT5066: init\n");
2812 conexant_init(codec);
2813 cxt5066_hp_automute(codec);
2814 if (!spec->dc_enable) {
2815 cxt5066_set_mic_boost(codec);
2816 cxt5066_olpc_automic(codec);
2817 } else {
2818 cxt5066_enable_dc(codec);
2313 } 2819 }
2314 return 0; 2820 return 0;
2315} 2821}
@@ -2318,6 +2824,8 @@ enum {
2318 CXT5066_LAPTOP, /* Laptops w/ EAPD support */ 2824 CXT5066_LAPTOP, /* Laptops w/ EAPD support */
2319 CXT5066_DELL_LAPTOP, /* Dell Laptop */ 2825 CXT5066_DELL_LAPTOP, /* Dell Laptop */
2320 CXT5066_OLPC_XO_1_5, /* OLPC XO 1.5 */ 2826 CXT5066_OLPC_XO_1_5, /* OLPC XO 1.5 */
2827 CXT5066_DELL_VOSTO, /* Dell Vostro 1015i */
2828 CXT5066_IDEAPAD, /* Lenovo IdeaPad U150 */
2321 CXT5066_MODELS 2829 CXT5066_MODELS
2322}; 2830};
2323 2831
@@ -2325,6 +2833,8 @@ static const char *cxt5066_models[CXT5066_MODELS] = {
2325 [CXT5066_LAPTOP] = "laptop", 2833 [CXT5066_LAPTOP] = "laptop",
2326 [CXT5066_DELL_LAPTOP] = "dell-laptop", 2834 [CXT5066_DELL_LAPTOP] = "dell-laptop",
2327 [CXT5066_OLPC_XO_1_5] = "olpc-xo-1_5", 2835 [CXT5066_OLPC_XO_1_5] = "olpc-xo-1_5",
2836 [CXT5066_DELL_VOSTO] = "dell-vostro",
2837 [CXT5066_IDEAPAD] = "ideapad",
2328}; 2838};
2329 2839
2330static struct snd_pci_quirk cxt5066_cfg_tbl[] = { 2840static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
@@ -2333,6 +2843,12 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
2333 SND_PCI_QUIRK(0x1028, 0x02f5, "Dell", 2843 SND_PCI_QUIRK(0x1028, 0x02f5, "Dell",
2334 CXT5066_DELL_LAPTOP), 2844 CXT5066_DELL_LAPTOP),
2335 SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5), 2845 SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5),
2846 SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTO),
2847 SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD),
2848 SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5),
2849 SND_PCI_QUIRK(0x1179, 0xffe0, "Toshiba Satellite Pro T130-15F", CXT5066_OLPC_XO_1_5),
2850 SND_PCI_QUIRK(0x17aa, 0x21b2, "Thinkpad X100e", CXT5066_IDEAPAD),
2851 SND_PCI_QUIRK(0x17aa, 0x3a0d, "ideapad", CXT5066_IDEAPAD),
2336 {} 2852 {}
2337}; 2853};
2338 2854
@@ -2347,7 +2863,7 @@ static int patch_cxt5066(struct hda_codec *codec)
2347 codec->spec = spec; 2863 codec->spec = spec;
2348 2864
2349 codec->patch_ops = conexant_patch_ops; 2865 codec->patch_ops = conexant_patch_ops;
2350 codec->patch_ops.init = cxt5066_init; 2866 codec->patch_ops.init = conexant_init;
2351 2867
2352 spec->dell_automute = 0; 2868 spec->dell_automute = 0;
2353 spec->multiout.max_channels = 2; 2869 spec->multiout.max_channels = 2;
@@ -2360,7 +2876,6 @@ static int patch_cxt5066(struct hda_codec *codec)
2360 spec->input_mux = &cxt5066_capture_source; 2876 spec->input_mux = &cxt5066_capture_source;
2361 2877
2362 spec->port_d_mode = PIN_HP; 2878 spec->port_d_mode = PIN_HP;
2363 spec->ext_mic_bias = PIN_VREF80;
2364 2879
2365 spec->num_init_verbs = 1; 2880 spec->num_init_verbs = 1;
2366 spec->init_verbs[0] = cxt5066_init_verbs; 2881 spec->init_verbs[0] = cxt5066_init_verbs;
@@ -2387,12 +2902,53 @@ static int patch_cxt5066(struct hda_codec *codec)
2387 spec->dell_automute = 1; 2902 spec->dell_automute = 1;
2388 break; 2903 break;
2389 case CXT5066_OLPC_XO_1_5: 2904 case CXT5066_OLPC_XO_1_5:
2390 codec->patch_ops.unsol_event = cxt5066_unsol_event; 2905 codec->patch_ops.init = cxt5066_olpc_init;
2906 codec->patch_ops.unsol_event = cxt5066_olpc_unsol_event;
2391 spec->init_verbs[0] = cxt5066_init_verbs_olpc; 2907 spec->init_verbs[0] = cxt5066_init_verbs_olpc;
2392 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc; 2908 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc;
2909 spec->mixers[spec->num_mixers++] = cxt5066_mixer_olpc_dc;
2910 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
2911 spec->port_d_mode = 0;
2912 spec->mic_boost = 3; /* default 30dB gain */
2913
2914 /* no S/PDIF out */
2915 spec->multiout.dig_out_nid = 0;
2916
2917 /* input source automatically selected */
2918 spec->input_mux = NULL;
2919
2920 /* our capture hooks which allow us to turn on the microphone LED
2921 * at the right time */
2922 spec->capture_prepare = cxt5066_olpc_capture_prepare;
2923 spec->capture_cleanup = cxt5066_olpc_capture_cleanup;
2924 break;
2925 case CXT5066_DELL_VOSTO:
2926 codec->patch_ops.init = cxt5066_init;
2927 codec->patch_ops.unsol_event = cxt5066_vostro_event;
2928 spec->init_verbs[0] = cxt5066_init_verbs_vostro;
2929 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc;
2393 spec->mixers[spec->num_mixers++] = cxt5066_mixers; 2930 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
2931 spec->mixers[spec->num_mixers++] = cxt5066_vostro_mixers;
2394 spec->port_d_mode = 0; 2932 spec->port_d_mode = 0;
2395 spec->ext_mic_bias = CXT5066_OLPC_EXT_MIC_BIAS; 2933 spec->dell_vostro = 1;
2934 spec->mic_boost = 3; /* default 30dB gain */
2935 snd_hda_attach_beep_device(codec, 0x13);
2936
2937 /* no S/PDIF out */
2938 spec->multiout.dig_out_nid = 0;
2939
2940 /* input source automatically selected */
2941 spec->input_mux = NULL;
2942 break;
2943 case CXT5066_IDEAPAD:
2944 codec->patch_ops.init = cxt5066_init;
2945 codec->patch_ops.unsol_event = cxt5066_ideapad_event;
2946 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
2947 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
2948 spec->init_verbs[0] = cxt5066_init_verbs_ideapad;
2949 spec->port_d_mode = 0;
2950 spec->ideapad = 1;
2951 spec->mic_boost = 2; /* default 20dB gain */
2396 2952
2397 /* no S/PDIF out */ 2953 /* no S/PDIF out */
2398 spec->multiout.dig_out_nid = 0; 2954 spec->multiout.dig_out_nid = 0;
@@ -2417,6 +2973,8 @@ static struct hda_codec_preset snd_hda_preset_conexant[] = {
2417 .patch = patch_cxt5051 }, 2973 .patch = patch_cxt5051 },
2418 { .id = 0x14f15066, .name = "CX20582 (Pebble)", 2974 { .id = 0x14f15066, .name = "CX20582 (Pebble)",
2419 .patch = patch_cxt5066 }, 2975 .patch = patch_cxt5066 },
2976 { .id = 0x14f15067, .name = "CX20583 (Pebble HSF)",
2977 .patch = patch_cxt5066 },
2420 {} /* terminator */ 2978 {} /* terminator */
2421}; 2979};
2422 2980
@@ -2424,6 +2982,7 @@ MODULE_ALIAS("snd-hda-codec-id:14f15045");
2424MODULE_ALIAS("snd-hda-codec-id:14f15047"); 2982MODULE_ALIAS("snd-hda-codec-id:14f15047");
2425MODULE_ALIAS("snd-hda-codec-id:14f15051"); 2983MODULE_ALIAS("snd-hda-codec-id:14f15051");
2426MODULE_ALIAS("snd-hda-codec-id:14f15066"); 2984MODULE_ALIAS("snd-hda-codec-id:14f15066");
2985MODULE_ALIAS("snd-hda-codec-id:14f15067");
2427 2986
2428MODULE_LICENSE("GPL"); 2987MODULE_LICENSE("GPL");
2429MODULE_DESCRIPTION("Conexant HD-audio codec"); 2988MODULE_DESCRIPTION("Conexant HD-audio codec");
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
new file mode 100644
index 000000000000..2c2bafbf0258
--- /dev/null
+++ b/sound/pci/hda/patch_hdmi.c
@@ -0,0 +1,849 @@
1/*
2 *
3 * patch_hdmi.c - routines for HDMI/DisplayPort codecs
4 *
5 * Copyright(c) 2008-2010 Intel Corporation. All rights reserved.
6 *
7 * Authors:
8 * Wu Fengguang <wfg@linux.intel.com>
9 *
10 * Maintained by:
11 * Wu Fengguang <wfg@linux.intel.com>
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the Free
15 * Software Foundation; either version 2 of the License, or (at your option)
16 * any later version.
17 *
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 * 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 Foundation,
25 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 */
27
28
29struct hdmi_spec {
30 int num_cvts;
31 int num_pins;
32 hda_nid_t cvt[MAX_HDMI_CVTS+1]; /* audio sources */
33 hda_nid_t pin[MAX_HDMI_PINS+1]; /* audio sinks */
34
35 /*
36 * source connection for each pin
37 */
38 hda_nid_t pin_cvt[MAX_HDMI_PINS+1];
39
40 /*
41 * HDMI sink attached to each pin
42 */
43 struct hdmi_eld sink_eld[MAX_HDMI_PINS];
44
45 /*
46 * export one pcm per pipe
47 */
48 struct hda_pcm pcm_rec[MAX_HDMI_CVTS];
49
50 /*
51 * nvhdmi specific
52 */
53 struct hda_multi_out multiout;
54 unsigned int codec_type;
55};
56
57
58struct hdmi_audio_infoframe {
59 u8 type; /* 0x84 */
60 u8 ver; /* 0x01 */
61 u8 len; /* 0x0a */
62
63 u8 checksum; /* PB0 */
64 u8 CC02_CT47; /* CC in bits 0:2, CT in 4:7 */
65 u8 SS01_SF24;
66 u8 CXT04;
67 u8 CA;
68 u8 LFEPBL01_LSV36_DM_INH7;
69 u8 reserved[5]; /* PB6 - PB10 */
70};
71
72/*
73 * CEA speaker placement:
74 *
75 * FLH FCH FRH
76 * FLW FL FLC FC FRC FR FRW
77 *
78 * LFE
79 * TC
80 *
81 * RL RLC RC RRC RR
82 *
83 * The Left/Right Surround channel _notions_ LS/RS in SMPTE 320M corresponds to
84 * CEA RL/RR; The SMPTE channel _assignment_ C/LFE is swapped to CEA LFE/FC.
85 */
86enum cea_speaker_placement {
87 FL = (1 << 0), /* Front Left */
88 FC = (1 << 1), /* Front Center */
89 FR = (1 << 2), /* Front Right */
90 FLC = (1 << 3), /* Front Left Center */
91 FRC = (1 << 4), /* Front Right Center */
92 RL = (1 << 5), /* Rear Left */
93 RC = (1 << 6), /* Rear Center */
94 RR = (1 << 7), /* Rear Right */
95 RLC = (1 << 8), /* Rear Left Center */
96 RRC = (1 << 9), /* Rear Right Center */
97 LFE = (1 << 10), /* Low Frequency Effect */
98 FLW = (1 << 11), /* Front Left Wide */
99 FRW = (1 << 12), /* Front Right Wide */
100 FLH = (1 << 13), /* Front Left High */
101 FCH = (1 << 14), /* Front Center High */
102 FRH = (1 << 15), /* Front Right High */
103 TC = (1 << 16), /* Top Center */
104};
105
106/*
107 * ELD SA bits in the CEA Speaker Allocation data block
108 */
109static int eld_speaker_allocation_bits[] = {
110 [0] = FL | FR,
111 [1] = LFE,
112 [2] = FC,
113 [3] = RL | RR,
114 [4] = RC,
115 [5] = FLC | FRC,
116 [6] = RLC | RRC,
117 /* the following are not defined in ELD yet */
118 [7] = FLW | FRW,
119 [8] = FLH | FRH,
120 [9] = TC,
121 [10] = FCH,
122};
123
124struct cea_channel_speaker_allocation {
125 int ca_index;
126 int speakers[8];
127
128 /* derived values, just for convenience */
129 int channels;
130 int spk_mask;
131};
132
133/*
134 * ALSA sequence is:
135 *
136 * surround40 surround41 surround50 surround51 surround71
137 * ch0 front left = = = =
138 * ch1 front right = = = =
139 * ch2 rear left = = = =
140 * ch3 rear right = = = =
141 * ch4 LFE center center center
142 * ch5 LFE LFE
143 * ch6 side left
144 * ch7 side right
145 *
146 * surround71 = {FL, FR, RLC, RRC, FC, LFE, RL, RR}
147 */
148static int hdmi_channel_mapping[0x32][8] = {
149 /* stereo */
150 [0x00] = { 0x00, 0x11, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7 },
151 /* 2.1 */
152 [0x01] = { 0x00, 0x11, 0x22, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7 },
153 /* Dolby Surround */
154 [0x02] = { 0x00, 0x11, 0x23, 0xf2, 0xf4, 0xf5, 0xf6, 0xf7 },
155 /* surround40 */
156 [0x08] = { 0x00, 0x11, 0x24, 0x35, 0xf3, 0xf2, 0xf6, 0xf7 },
157 /* 4ch */
158 [0x03] = { 0x00, 0x11, 0x23, 0x32, 0x44, 0xf5, 0xf6, 0xf7 },
159 /* surround41 */
160 [0x09] = { 0x00, 0x11, 0x24, 0x34, 0x43, 0xf2, 0xf6, 0xf7 },
161 /* surround50 */
162 [0x0a] = { 0x00, 0x11, 0x24, 0x35, 0x43, 0xf2, 0xf6, 0xf7 },
163 /* surround51 */
164 [0x0b] = { 0x00, 0x11, 0x24, 0x35, 0x43, 0x52, 0xf6, 0xf7 },
165 /* 7.1 */
166 [0x13] = { 0x00, 0x11, 0x26, 0x37, 0x43, 0x52, 0x64, 0x75 },
167};
168
169/*
170 * This is an ordered list!
171 *
172 * The preceding ones have better chances to be selected by
173 * hdmi_setup_channel_allocation().
174 */
175static struct cea_channel_speaker_allocation channel_allocations[] = {
176/* channel: 7 6 5 4 3 2 1 0 */
177{ .ca_index = 0x00, .speakers = { 0, 0, 0, 0, 0, 0, FR, FL } },
178 /* 2.1 */
179{ .ca_index = 0x01, .speakers = { 0, 0, 0, 0, 0, LFE, FR, FL } },
180 /* Dolby Surround */
181{ .ca_index = 0x02, .speakers = { 0, 0, 0, 0, FC, 0, FR, FL } },
182 /* surround40 */
183{ .ca_index = 0x08, .speakers = { 0, 0, RR, RL, 0, 0, FR, FL } },
184 /* surround41 */
185{ .ca_index = 0x09, .speakers = { 0, 0, RR, RL, 0, LFE, FR, FL } },
186 /* surround50 */
187{ .ca_index = 0x0a, .speakers = { 0, 0, RR, RL, FC, 0, FR, FL } },
188 /* surround51 */
189{ .ca_index = 0x0b, .speakers = { 0, 0, RR, RL, FC, LFE, FR, FL } },
190 /* 6.1 */
191{ .ca_index = 0x0f, .speakers = { 0, RC, RR, RL, FC, LFE, FR, FL } },
192 /* surround71 */
193{ .ca_index = 0x13, .speakers = { RRC, RLC, RR, RL, FC, LFE, FR, FL } },
194
195{ .ca_index = 0x03, .speakers = { 0, 0, 0, 0, FC, LFE, FR, FL } },
196{ .ca_index = 0x04, .speakers = { 0, 0, 0, RC, 0, 0, FR, FL } },
197{ .ca_index = 0x05, .speakers = { 0, 0, 0, RC, 0, LFE, FR, FL } },
198{ .ca_index = 0x06, .speakers = { 0, 0, 0, RC, FC, 0, FR, FL } },
199{ .ca_index = 0x07, .speakers = { 0, 0, 0, RC, FC, LFE, FR, FL } },
200{ .ca_index = 0x0c, .speakers = { 0, RC, RR, RL, 0, 0, FR, FL } },
201{ .ca_index = 0x0d, .speakers = { 0, RC, RR, RL, 0, LFE, FR, FL } },
202{ .ca_index = 0x0e, .speakers = { 0, RC, RR, RL, FC, 0, FR, FL } },
203{ .ca_index = 0x10, .speakers = { RRC, RLC, RR, RL, 0, 0, FR, FL } },
204{ .ca_index = 0x11, .speakers = { RRC, RLC, RR, RL, 0, LFE, FR, FL } },
205{ .ca_index = 0x12, .speakers = { RRC, RLC, RR, RL, FC, 0, FR, FL } },
206{ .ca_index = 0x14, .speakers = { FRC, FLC, 0, 0, 0, 0, FR, FL } },
207{ .ca_index = 0x15, .speakers = { FRC, FLC, 0, 0, 0, LFE, FR, FL } },
208{ .ca_index = 0x16, .speakers = { FRC, FLC, 0, 0, FC, 0, FR, FL } },
209{ .ca_index = 0x17, .speakers = { FRC, FLC, 0, 0, FC, LFE, FR, FL } },
210{ .ca_index = 0x18, .speakers = { FRC, FLC, 0, RC, 0, 0, FR, FL } },
211{ .ca_index = 0x19, .speakers = { FRC, FLC, 0, RC, 0, LFE, FR, FL } },
212{ .ca_index = 0x1a, .speakers = { FRC, FLC, 0, RC, FC, 0, FR, FL } },
213{ .ca_index = 0x1b, .speakers = { FRC, FLC, 0, RC, FC, LFE, FR, FL } },
214{ .ca_index = 0x1c, .speakers = { FRC, FLC, RR, RL, 0, 0, FR, FL } },
215{ .ca_index = 0x1d, .speakers = { FRC, FLC, RR, RL, 0, LFE, FR, FL } },
216{ .ca_index = 0x1e, .speakers = { FRC, FLC, RR, RL, FC, 0, FR, FL } },
217{ .ca_index = 0x1f, .speakers = { FRC, FLC, RR, RL, FC, LFE, FR, FL } },
218{ .ca_index = 0x20, .speakers = { 0, FCH, RR, RL, FC, 0, FR, FL } },
219{ .ca_index = 0x21, .speakers = { 0, FCH, RR, RL, FC, LFE, FR, FL } },
220{ .ca_index = 0x22, .speakers = { TC, 0, RR, RL, FC, 0, FR, FL } },
221{ .ca_index = 0x23, .speakers = { TC, 0, RR, RL, FC, LFE, FR, FL } },
222{ .ca_index = 0x24, .speakers = { FRH, FLH, RR, RL, 0, 0, FR, FL } },
223{ .ca_index = 0x25, .speakers = { FRH, FLH, RR, RL, 0, LFE, FR, FL } },
224{ .ca_index = 0x26, .speakers = { FRW, FLW, RR, RL, 0, 0, FR, FL } },
225{ .ca_index = 0x27, .speakers = { FRW, FLW, RR, RL, 0, LFE, FR, FL } },
226{ .ca_index = 0x28, .speakers = { TC, RC, RR, RL, FC, 0, FR, FL } },
227{ .ca_index = 0x29, .speakers = { TC, RC, RR, RL, FC, LFE, FR, FL } },
228{ .ca_index = 0x2a, .speakers = { FCH, RC, RR, RL, FC, 0, FR, FL } },
229{ .ca_index = 0x2b, .speakers = { FCH, RC, RR, RL, FC, LFE, FR, FL } },
230{ .ca_index = 0x2c, .speakers = { TC, FCH, RR, RL, FC, 0, FR, FL } },
231{ .ca_index = 0x2d, .speakers = { TC, FCH, RR, RL, FC, LFE, FR, FL } },
232{ .ca_index = 0x2e, .speakers = { FRH, FLH, RR, RL, FC, 0, FR, FL } },
233{ .ca_index = 0x2f, .speakers = { FRH, FLH, RR, RL, FC, LFE, FR, FL } },
234{ .ca_index = 0x30, .speakers = { FRW, FLW, RR, RL, FC, 0, FR, FL } },
235{ .ca_index = 0x31, .speakers = { FRW, FLW, RR, RL, FC, LFE, FR, FL } },
236};
237
238
239/*
240 * HDMI routines
241 */
242
243static int hda_node_index(hda_nid_t *nids, hda_nid_t nid)
244{
245 int i;
246
247 for (i = 0; nids[i]; i++)
248 if (nids[i] == nid)
249 return i;
250
251 snd_printk(KERN_WARNING "HDMI: nid %d not registered\n", nid);
252 return -EINVAL;
253}
254
255static void hdmi_get_show_eld(struct hda_codec *codec, hda_nid_t pin_nid,
256 struct hdmi_eld *eld)
257{
258 if (!snd_hdmi_get_eld(eld, codec, pin_nid))
259 snd_hdmi_show_eld(eld);
260}
261
262#ifdef BE_PARANOID
263static void hdmi_get_dip_index(struct hda_codec *codec, hda_nid_t pin_nid,
264 int *packet_index, int *byte_index)
265{
266 int val;
267
268 val = snd_hda_codec_read(codec, pin_nid, 0,
269 AC_VERB_GET_HDMI_DIP_INDEX, 0);
270
271 *packet_index = val >> 5;
272 *byte_index = val & 0x1f;
273}
274#endif
275
276static void hdmi_set_dip_index(struct hda_codec *codec, hda_nid_t pin_nid,
277 int packet_index, int byte_index)
278{
279 int val;
280
281 val = (packet_index << 5) | (byte_index & 0x1f);
282
283 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_INDEX, val);
284}
285
286static void hdmi_write_dip_byte(struct hda_codec *codec, hda_nid_t pin_nid,
287 unsigned char val)
288{
289 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_DATA, val);
290}
291
292static void hdmi_enable_output(struct hda_codec *codec, hda_nid_t pin_nid)
293{
294 /* Unmute */
295 if (get_wcaps(codec, pin_nid) & AC_WCAP_OUT_AMP)
296 snd_hda_codec_write(codec, pin_nid, 0,
297 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
298 /* Enable pin out */
299 snd_hda_codec_write(codec, pin_nid, 0,
300 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
301}
302
303static int hdmi_get_channel_count(struct hda_codec *codec, hda_nid_t nid)
304{
305 return 1 + snd_hda_codec_read(codec, nid, 0,
306 AC_VERB_GET_CVT_CHAN_COUNT, 0);
307}
308
309static void hdmi_set_channel_count(struct hda_codec *codec,
310 hda_nid_t nid, int chs)
311{
312 if (chs != hdmi_get_channel_count(codec, nid))
313 snd_hda_codec_write(codec, nid, 0,
314 AC_VERB_SET_CVT_CHAN_COUNT, chs - 1);
315}
316
317
318/*
319 * Channel mapping routines
320 */
321
322/*
323 * Compute derived values in channel_allocations[].
324 */
325static void init_channel_allocations(void)
326{
327 int i, j;
328 struct cea_channel_speaker_allocation *p;
329
330 for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
331 p = channel_allocations + i;
332 p->channels = 0;
333 p->spk_mask = 0;
334 for (j = 0; j < ARRAY_SIZE(p->speakers); j++)
335 if (p->speakers[j]) {
336 p->channels++;
337 p->spk_mask |= p->speakers[j];
338 }
339 }
340}
341
342/*
343 * The transformation takes two steps:
344 *
345 * eld->spk_alloc => (eld_speaker_allocation_bits[]) => spk_mask
346 * spk_mask => (channel_allocations[]) => ai->CA
347 *
348 * TODO: it could select the wrong CA from multiple candidates.
349*/
350static int hdmi_setup_channel_allocation(struct hda_codec *codec, hda_nid_t nid,
351 struct hdmi_audio_infoframe *ai)
352{
353 struct hdmi_spec *spec = codec->spec;
354 struct hdmi_eld *eld;
355 int i;
356 int spk_mask = 0;
357 int channels = 1 + (ai->CC02_CT47 & 0x7);
358 char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE];
359
360 /*
361 * CA defaults to 0 for basic stereo audio
362 */
363 if (channels <= 2)
364 return 0;
365
366 i = hda_node_index(spec->pin_cvt, nid);
367 if (i < 0)
368 return 0;
369 eld = &spec->sink_eld[i];
370
371 /*
372 * HDMI sink's ELD info cannot always be retrieved for now, e.g.
373 * in console or for audio devices. Assume the highest speakers
374 * configuration, to _not_ prohibit multi-channel audio playback.
375 */
376 if (!eld->spk_alloc)
377 eld->spk_alloc = 0xffff;
378
379 /*
380 * expand ELD's speaker allocation mask
381 *
382 * ELD tells the speaker mask in a compact(paired) form,
383 * expand ELD's notions to match the ones used by Audio InfoFrame.
384 */
385 for (i = 0; i < ARRAY_SIZE(eld_speaker_allocation_bits); i++) {
386 if (eld->spk_alloc & (1 << i))
387 spk_mask |= eld_speaker_allocation_bits[i];
388 }
389
390 /* search for the first working match in the CA table */
391 for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
392 if (channels == channel_allocations[i].channels &&
393 (spk_mask & channel_allocations[i].spk_mask) ==
394 channel_allocations[i].spk_mask) {
395 ai->CA = channel_allocations[i].ca_index;
396 break;
397 }
398 }
399
400 snd_print_channel_allocation(eld->spk_alloc, buf, sizeof(buf));
401 snd_printdd("HDMI: select CA 0x%x for %d-channel allocation: %s\n",
402 ai->CA, channels, buf);
403
404 return ai->CA;
405}
406
407static void hdmi_debug_channel_mapping(struct hda_codec *codec,
408 hda_nid_t pin_nid)
409{
410#ifdef CONFIG_SND_DEBUG_VERBOSE
411 int i;
412 int slot;
413
414 for (i = 0; i < 8; i++) {
415 slot = snd_hda_codec_read(codec, pin_nid, 0,
416 AC_VERB_GET_HDMI_CHAN_SLOT, i);
417 printk(KERN_DEBUG "HDMI: ASP channel %d => slot %d\n",
418 slot >> 4, slot & 0xf);
419 }
420#endif
421}
422
423
424static void hdmi_setup_channel_mapping(struct hda_codec *codec,
425 hda_nid_t pin_nid,
426 struct hdmi_audio_infoframe *ai)
427{
428 int i;
429 int ca = ai->CA;
430 int err;
431
432 if (hdmi_channel_mapping[ca][1] == 0) {
433 for (i = 0; i < channel_allocations[ca].channels; i++)
434 hdmi_channel_mapping[ca][i] = i | (i << 4);
435 for (; i < 8; i++)
436 hdmi_channel_mapping[ca][i] = 0xf | (i << 4);
437 }
438
439 for (i = 0; i < 8; i++) {
440 err = snd_hda_codec_write(codec, pin_nid, 0,
441 AC_VERB_SET_HDMI_CHAN_SLOT,
442 hdmi_channel_mapping[ca][i]);
443 if (err) {
444 snd_printdd(KERN_NOTICE
445 "HDMI: channel mapping failed\n");
446 break;
447 }
448 }
449
450 hdmi_debug_channel_mapping(codec, pin_nid);
451}
452
453
454/*
455 * Audio InfoFrame routines
456 */
457
458/*
459 * Enable Audio InfoFrame Transmission
460 */
461static void hdmi_start_infoframe_trans(struct hda_codec *codec,
462 hda_nid_t pin_nid)
463{
464 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
465 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_XMIT,
466 AC_DIPXMIT_BEST);
467}
468
469/*
470 * Disable Audio InfoFrame Transmission
471 */
472static void hdmi_stop_infoframe_trans(struct hda_codec *codec,
473 hda_nid_t pin_nid)
474{
475 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
476 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_XMIT,
477 AC_DIPXMIT_DISABLE);
478}
479
480static void hdmi_debug_dip_size(struct hda_codec *codec, hda_nid_t pin_nid)
481{
482#ifdef CONFIG_SND_DEBUG_VERBOSE
483 int i;
484 int size;
485
486 size = snd_hdmi_get_eld_size(codec, pin_nid);
487 printk(KERN_DEBUG "HDMI: ELD buf size is %d\n", size);
488
489 for (i = 0; i < 8; i++) {
490 size = snd_hda_codec_read(codec, pin_nid, 0,
491 AC_VERB_GET_HDMI_DIP_SIZE, i);
492 printk(KERN_DEBUG "HDMI: DIP GP[%d] buf size is %d\n", i, size);
493 }
494#endif
495}
496
497static void hdmi_clear_dip_buffers(struct hda_codec *codec, hda_nid_t pin_nid)
498{
499#ifdef BE_PARANOID
500 int i, j;
501 int size;
502 int pi, bi;
503 for (i = 0; i < 8; i++) {
504 size = snd_hda_codec_read(codec, pin_nid, 0,
505 AC_VERB_GET_HDMI_DIP_SIZE, i);
506 if (size == 0)
507 continue;
508
509 hdmi_set_dip_index(codec, pin_nid, i, 0x0);
510 for (j = 1; j < 1000; j++) {
511 hdmi_write_dip_byte(codec, pin_nid, 0x0);
512 hdmi_get_dip_index(codec, pin_nid, &pi, &bi);
513 if (pi != i)
514 snd_printd(KERN_INFO "dip index %d: %d != %d\n",
515 bi, pi, i);
516 if (bi == 0) /* byte index wrapped around */
517 break;
518 }
519 snd_printd(KERN_INFO
520 "HDMI: DIP GP[%d] buf reported size=%d, written=%d\n",
521 i, size, j);
522 }
523#endif
524}
525
526static void hdmi_checksum_audio_infoframe(struct hdmi_audio_infoframe *ai)
527{
528 u8 *bytes = (u8 *)ai;
529 u8 sum = 0;
530 int i;
531
532 ai->checksum = 0;
533
534 for (i = 0; i < sizeof(*ai); i++)
535 sum += bytes[i];
536
537 ai->checksum = -sum;
538}
539
540static void hdmi_fill_audio_infoframe(struct hda_codec *codec,
541 hda_nid_t pin_nid,
542 struct hdmi_audio_infoframe *ai)
543{
544 u8 *bytes = (u8 *)ai;
545 int i;
546
547 hdmi_debug_dip_size(codec, pin_nid);
548 hdmi_clear_dip_buffers(codec, pin_nid); /* be paranoid */
549
550 hdmi_checksum_audio_infoframe(ai);
551
552 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
553 for (i = 0; i < sizeof(*ai); i++)
554 hdmi_write_dip_byte(codec, pin_nid, bytes[i]);
555}
556
557static bool hdmi_infoframe_uptodate(struct hda_codec *codec, hda_nid_t pin_nid,
558 struct hdmi_audio_infoframe *ai)
559{
560 u8 *bytes = (u8 *)ai;
561 u8 val;
562 int i;
563
564 if (snd_hda_codec_read(codec, pin_nid, 0, AC_VERB_GET_HDMI_DIP_XMIT, 0)
565 != AC_DIPXMIT_BEST)
566 return false;
567
568 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
569 for (i = 0; i < sizeof(*ai); i++) {
570 val = snd_hda_codec_read(codec, pin_nid, 0,
571 AC_VERB_GET_HDMI_DIP_DATA, 0);
572 if (val != bytes[i])
573 return false;
574 }
575
576 return true;
577}
578
579static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid,
580 struct snd_pcm_substream *substream)
581{
582 struct hdmi_spec *spec = codec->spec;
583 hda_nid_t pin_nid;
584 int i;
585 struct hdmi_audio_infoframe ai = {
586 .type = 0x84,
587 .ver = 0x01,
588 .len = 0x0a,
589 .CC02_CT47 = substream->runtime->channels - 1,
590 };
591
592 hdmi_setup_channel_allocation(codec, nid, &ai);
593
594 for (i = 0; i < spec->num_pins; i++) {
595 if (spec->pin_cvt[i] != nid)
596 continue;
597 if (!spec->sink_eld[i].monitor_present)
598 continue;
599
600 pin_nid = spec->pin[i];
601 if (!hdmi_infoframe_uptodate(codec, pin_nid, &ai)) {
602 snd_printdd("hdmi_setup_audio_infoframe: "
603 "cvt=%d pin=%d channels=%d\n",
604 nid, pin_nid,
605 substream->runtime->channels);
606 hdmi_setup_channel_mapping(codec, pin_nid, &ai);
607 hdmi_stop_infoframe_trans(codec, pin_nid);
608 hdmi_fill_audio_infoframe(codec, pin_nid, &ai);
609 hdmi_start_infoframe_trans(codec, pin_nid);
610 }
611 }
612}
613
614
615/*
616 * Unsolicited events
617 */
618
619static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
620{
621 struct hdmi_spec *spec = codec->spec;
622 int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
623 int pind = !!(res & AC_UNSOL_RES_PD);
624 int eldv = !!(res & AC_UNSOL_RES_ELDV);
625 int index;
626
627 printk(KERN_INFO
628 "HDMI hot plug event: Pin=%d Presence_Detect=%d ELD_Valid=%d\n",
629 tag, pind, eldv);
630
631 index = hda_node_index(spec->pin, tag);
632 if (index < 0)
633 return;
634
635 spec->sink_eld[index].monitor_present = pind;
636 spec->sink_eld[index].eld_valid = eldv;
637
638 if (pind && eldv) {
639 hdmi_get_show_eld(codec, spec->pin[index],
640 &spec->sink_eld[index]);
641 /* TODO: do real things about ELD */
642 }
643}
644
645static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res)
646{
647 int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
648 int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT;
649 int cp_state = !!(res & AC_UNSOL_RES_CP_STATE);
650 int cp_ready = !!(res & AC_UNSOL_RES_CP_READY);
651
652 printk(KERN_INFO
653 "HDMI CP event: PIN=%d SUBTAG=0x%x CP_STATE=%d CP_READY=%d\n",
654 tag,
655 subtag,
656 cp_state,
657 cp_ready);
658
659 /* TODO */
660 if (cp_state)
661 ;
662 if (cp_ready)
663 ;
664}
665
666
667static void hdmi_unsol_event(struct hda_codec *codec, unsigned int res)
668{
669 struct hdmi_spec *spec = codec->spec;
670 int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
671 int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT;
672
673 if (hda_node_index(spec->pin, tag) < 0) {
674 snd_printd(KERN_INFO "Unexpected HDMI event tag 0x%x\n", tag);
675 return;
676 }
677
678 if (subtag == 0)
679 hdmi_intrinsic_event(codec, res);
680 else
681 hdmi_non_intrinsic_event(codec, res);
682}
683
684/*
685 * Callbacks
686 */
687
688static void hdmi_setup_stream(struct hda_codec *codec, hda_nid_t nid,
689 u32 stream_tag, int format)
690{
691 int tag;
692 int fmt;
693
694 tag = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0) >> 4;
695 fmt = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_STREAM_FORMAT, 0);
696
697 snd_printdd("hdmi_setup_stream: "
698 "NID=0x%x, %sstream=0x%x, %sformat=0x%x\n",
699 nid,
700 tag == stream_tag ? "" : "new-",
701 stream_tag,
702 fmt == format ? "" : "new-",
703 format);
704
705 if (tag != stream_tag)
706 snd_hda_codec_write(codec, nid, 0,
707 AC_VERB_SET_CHANNEL_STREAMID,
708 stream_tag << 4);
709 if (fmt != format)
710 snd_hda_codec_write(codec, nid, 0,
711 AC_VERB_SET_STREAM_FORMAT, format);
712}
713
714/*
715 * HDA/HDMI auto parsing
716 */
717
718static int hdmi_read_pin_conn(struct hda_codec *codec, hda_nid_t pin_nid)
719{
720 struct hdmi_spec *spec = codec->spec;
721 hda_nid_t conn_list[HDA_MAX_CONNECTIONS];
722 int conn_len, curr;
723 int index;
724
725 if (!(get_wcaps(codec, pin_nid) & AC_WCAP_CONN_LIST)) {
726 snd_printk(KERN_WARNING
727 "HDMI: pin %d wcaps %#x "
728 "does not support connection list\n",
729 pin_nid, get_wcaps(codec, pin_nid));
730 return -EINVAL;
731 }
732
733 conn_len = snd_hda_get_connections(codec, pin_nid, conn_list,
734 HDA_MAX_CONNECTIONS);
735 if (conn_len > 1)
736 curr = snd_hda_codec_read(codec, pin_nid, 0,
737 AC_VERB_GET_CONNECT_SEL, 0);
738 else
739 curr = 0;
740
741 index = hda_node_index(spec->pin, pin_nid);
742 if (index < 0)
743 return -EINVAL;
744
745 spec->pin_cvt[index] = conn_list[curr];
746
747 return 0;
748}
749
750static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid,
751 struct hdmi_eld *eld)
752{
753 int present = snd_hda_pin_sense(codec, pin_nid);
754
755 eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE);
756 eld->eld_valid = !!(present & AC_PINSENSE_ELDV);
757
758 if (present & AC_PINSENSE_ELDV)
759 hdmi_get_show_eld(codec, pin_nid, eld);
760}
761
762static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
763{
764 struct hdmi_spec *spec = codec->spec;
765
766 if (spec->num_pins >= MAX_HDMI_PINS) {
767 snd_printk(KERN_WARNING
768 "HDMI: no space for pin %d\n", pin_nid);
769 return -EINVAL;
770 }
771
772 hdmi_present_sense(codec, pin_nid, &spec->sink_eld[spec->num_pins]);
773
774 spec->pin[spec->num_pins] = pin_nid;
775 spec->num_pins++;
776
777 /*
778 * It is assumed that converter nodes come first in the node list and
779 * hence have been registered and usable now.
780 */
781 return hdmi_read_pin_conn(codec, pin_nid);
782}
783
784static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t nid)
785{
786 struct hdmi_spec *spec = codec->spec;
787
788 if (spec->num_cvts >= MAX_HDMI_CVTS) {
789 snd_printk(KERN_WARNING
790 "HDMI: no space for converter %d\n", nid);
791 return -EINVAL;
792 }
793
794 spec->cvt[spec->num_cvts] = nid;
795 spec->num_cvts++;
796
797 return 0;
798}
799
800static int hdmi_parse_codec(struct hda_codec *codec)
801{
802 hda_nid_t nid;
803 int i, nodes;
804
805 nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid);
806 if (!nid || nodes < 0) {
807 snd_printk(KERN_WARNING "HDMI: failed to get afg sub nodes\n");
808 return -EINVAL;
809 }
810
811 for (i = 0; i < nodes; i++, nid++) {
812 unsigned int caps;
813 unsigned int type;
814
815 caps = snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP);
816 type = get_wcaps_type(caps);
817
818 if (!(caps & AC_WCAP_DIGITAL))
819 continue;
820
821 switch (type) {
822 case AC_WID_AUD_OUT:
823 if (hdmi_add_cvt(codec, nid) < 0)
824 return -EINVAL;
825 break;
826 case AC_WID_PIN:
827 caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
828 if (!(caps & (AC_PINCAP_HDMI | AC_PINCAP_DP)))
829 continue;
830 if (hdmi_add_pin(codec, nid) < 0)
831 return -EINVAL;
832 break;
833 }
834 }
835
836 /*
837 * G45/IbexPeak don't support EPSS: the unsolicited pin hot plug event
838 * can be lost and presence sense verb will become inaccurate if the
839 * HDA link is powered off at hot plug or hw initialization time.
840 */
841#ifdef CONFIG_SND_HDA_POWER_SAVE
842 if (!(snd_hda_param_read(codec, codec->afg, AC_PAR_POWER_STATE) &
843 AC_PWRST_EPSS))
844 codec->bus->power_keep_link_on = 1;
845#endif
846
847 return 0;
848}
849
diff --git a/sound/pci/hda/patch_intelhdmi.c b/sound/pci/hda/patch_intelhdmi.c
index 01a18ed475ac..88d035104cc5 100644
--- a/sound/pci/hda/patch_intelhdmi.c
+++ b/sound/pci/hda/patch_intelhdmi.c
@@ -33,605 +33,121 @@
33#include "hda_codec.h" 33#include "hda_codec.h"
34#include "hda_local.h" 34#include "hda_local.h"
35 35
36static hda_nid_t cvt_nid; /* audio converter */
37static hda_nid_t pin_nid; /* HDMI output pin */
38
39#define INTEL_HDMI_EVENT_TAG 0x08
40
41struct intel_hdmi_spec {
42 struct hda_multi_out multiout;
43 struct hda_pcm pcm_rec;
44 struct hdmi_eld sink_eld;
45};
46
47struct hdmi_audio_infoframe {
48 u8 type; /* 0x84 */
49 u8 ver; /* 0x01 */
50 u8 len; /* 0x0a */
51
52 u8 checksum; /* PB0 */
53 u8 CC02_CT47; /* CC in bits 0:2, CT in 4:7 */
54 u8 SS01_SF24;
55 u8 CXT04;
56 u8 CA;
57 u8 LFEPBL01_LSV36_DM_INH7;
58 u8 reserved[5]; /* PB6 - PB10 */
59};
60
61/* 36/*
62 * CEA speaker placement: 37 * The HDMI/DisplayPort configuration can be highly dynamic. A graphics device
38 * could support two independent pipes, each of them can be connected to one or
39 * more ports (DVI, HDMI or DisplayPort).
63 * 40 *
64 * FLH FCH FRH 41 * The HDA correspondence of pipes/ports are converter/pin nodes.
65 * FLW FL FLC FC FRC FR FRW
66 *
67 * LFE
68 * TC
69 *
70 * RL RLC RC RRC RR
71 *
72 * The Left/Right Surround channel _notions_ LS/RS in SMPTE 320M corresponds to
73 * CEA RL/RR; The SMPTE channel _assignment_ C/LFE is swapped to CEA LFE/FC.
74 */
75enum cea_speaker_placement {
76 FL = (1 << 0), /* Front Left */
77 FC = (1 << 1), /* Front Center */
78 FR = (1 << 2), /* Front Right */
79 FLC = (1 << 3), /* Front Left Center */
80 FRC = (1 << 4), /* Front Right Center */
81 RL = (1 << 5), /* Rear Left */
82 RC = (1 << 6), /* Rear Center */
83 RR = (1 << 7), /* Rear Right */
84 RLC = (1 << 8), /* Rear Left Center */
85 RRC = (1 << 9), /* Rear Right Center */
86 LFE = (1 << 10), /* Low Frequency Effect */
87 FLW = (1 << 11), /* Front Left Wide */
88 FRW = (1 << 12), /* Front Right Wide */
89 FLH = (1 << 13), /* Front Left High */
90 FCH = (1 << 14), /* Front Center High */
91 FRH = (1 << 15), /* Front Right High */
92 TC = (1 << 16), /* Top Center */
93};
94
95/*
96 * ELD SA bits in the CEA Speaker Allocation data block
97 */ 42 */
98static int eld_speaker_allocation_bits[] = { 43#define MAX_HDMI_CVTS 2
99 [0] = FL | FR, 44#define MAX_HDMI_PINS 3
100 [1] = LFE,
101 [2] = FC,
102 [3] = RL | RR,
103 [4] = RC,
104 [5] = FLC | FRC,
105 [6] = RLC | RRC,
106 /* the following are not defined in ELD yet */
107 [7] = FLW | FRW,
108 [8] = FLH | FRH,
109 [9] = TC,
110 [10] = FCH,
111};
112 45
113struct cea_channel_speaker_allocation { 46#include "patch_hdmi.c"
114 int ca_index;
115 int speakers[8];
116 47
117 /* derived values, just for convenience */ 48static char *intel_hdmi_pcm_names[MAX_HDMI_CVTS] = {
118 int channels; 49 "INTEL HDMI 0",
119 int spk_mask; 50 "INTEL HDMI 1",
120}; 51};
121 52
122/* 53/*
123 * This is an ordered list! 54 * HDMI callbacks
124 *
125 * The preceding ones have better chances to be selected by
126 * hdmi_setup_channel_allocation().
127 */
128static struct cea_channel_speaker_allocation channel_allocations[] = {
129/* channel: 8 7 6 5 4 3 2 1 */
130{ .ca_index = 0x00, .speakers = { 0, 0, 0, 0, 0, 0, FR, FL } },
131 /* 2.1 */
132{ .ca_index = 0x01, .speakers = { 0, 0, 0, 0, 0, LFE, FR, FL } },
133 /* Dolby Surround */
134{ .ca_index = 0x02, .speakers = { 0, 0, 0, 0, FC, 0, FR, FL } },
135{ .ca_index = 0x03, .speakers = { 0, 0, 0, 0, FC, LFE, FR, FL } },
136{ .ca_index = 0x04, .speakers = { 0, 0, 0, RC, 0, 0, FR, FL } },
137{ .ca_index = 0x05, .speakers = { 0, 0, 0, RC, 0, LFE, FR, FL } },
138{ .ca_index = 0x06, .speakers = { 0, 0, 0, RC, FC, 0, FR, FL } },
139{ .ca_index = 0x07, .speakers = { 0, 0, 0, RC, FC, LFE, FR, FL } },
140{ .ca_index = 0x08, .speakers = { 0, 0, RR, RL, 0, 0, FR, FL } },
141{ .ca_index = 0x09, .speakers = { 0, 0, RR, RL, 0, LFE, FR, FL } },
142{ .ca_index = 0x0a, .speakers = { 0, 0, RR, RL, FC, 0, FR, FL } },
143 /* 5.1 */
144{ .ca_index = 0x0b, .speakers = { 0, 0, RR, RL, FC, LFE, FR, FL } },
145{ .ca_index = 0x0c, .speakers = { 0, RC, RR, RL, 0, 0, FR, FL } },
146{ .ca_index = 0x0d, .speakers = { 0, RC, RR, RL, 0, LFE, FR, FL } },
147{ .ca_index = 0x0e, .speakers = { 0, RC, RR, RL, FC, 0, FR, FL } },
148 /* 6.1 */
149{ .ca_index = 0x0f, .speakers = { 0, RC, RR, RL, FC, LFE, FR, FL } },
150{ .ca_index = 0x10, .speakers = { RRC, RLC, RR, RL, 0, 0, FR, FL } },
151{ .ca_index = 0x11, .speakers = { RRC, RLC, RR, RL, 0, LFE, FR, FL } },
152{ .ca_index = 0x12, .speakers = { RRC, RLC, RR, RL, FC, 0, FR, FL } },
153 /* 7.1 */
154{ .ca_index = 0x13, .speakers = { RRC, RLC, RR, RL, FC, LFE, FR, FL } },
155{ .ca_index = 0x14, .speakers = { FRC, FLC, 0, 0, 0, 0, FR, FL } },
156{ .ca_index = 0x15, .speakers = { FRC, FLC, 0, 0, 0, LFE, FR, FL } },
157{ .ca_index = 0x16, .speakers = { FRC, FLC, 0, 0, FC, 0, FR, FL } },
158{ .ca_index = 0x17, .speakers = { FRC, FLC, 0, 0, FC, LFE, FR, FL } },
159{ .ca_index = 0x18, .speakers = { FRC, FLC, 0, RC, 0, 0, FR, FL } },
160{ .ca_index = 0x19, .speakers = { FRC, FLC, 0, RC, 0, LFE, FR, FL } },
161{ .ca_index = 0x1a, .speakers = { FRC, FLC, 0, RC, FC, 0, FR, FL } },
162{ .ca_index = 0x1b, .speakers = { FRC, FLC, 0, RC, FC, LFE, FR, FL } },
163{ .ca_index = 0x1c, .speakers = { FRC, FLC, RR, RL, 0, 0, FR, FL } },
164{ .ca_index = 0x1d, .speakers = { FRC, FLC, RR, RL, 0, LFE, FR, FL } },
165{ .ca_index = 0x1e, .speakers = { FRC, FLC, RR, RL, FC, 0, FR, FL } },
166{ .ca_index = 0x1f, .speakers = { FRC, FLC, RR, RL, FC, LFE, FR, FL } },
167{ .ca_index = 0x20, .speakers = { 0, FCH, RR, RL, FC, 0, FR, FL } },
168{ .ca_index = 0x21, .speakers = { 0, FCH, RR, RL, FC, LFE, FR, FL } },
169{ .ca_index = 0x22, .speakers = { TC, 0, RR, RL, FC, 0, FR, FL } },
170{ .ca_index = 0x23, .speakers = { TC, 0, RR, RL, FC, LFE, FR, FL } },
171{ .ca_index = 0x24, .speakers = { FRH, FLH, RR, RL, 0, 0, FR, FL } },
172{ .ca_index = 0x25, .speakers = { FRH, FLH, RR, RL, 0, LFE, FR, FL } },
173{ .ca_index = 0x26, .speakers = { FRW, FLW, RR, RL, 0, 0, FR, FL } },
174{ .ca_index = 0x27, .speakers = { FRW, FLW, RR, RL, 0, LFE, FR, FL } },
175{ .ca_index = 0x28, .speakers = { TC, RC, RR, RL, FC, 0, FR, FL } },
176{ .ca_index = 0x29, .speakers = { TC, RC, RR, RL, FC, LFE, FR, FL } },
177{ .ca_index = 0x2a, .speakers = { FCH, RC, RR, RL, FC, 0, FR, FL } },
178{ .ca_index = 0x2b, .speakers = { FCH, RC, RR, RL, FC, LFE, FR, FL } },
179{ .ca_index = 0x2c, .speakers = { TC, FCH, RR, RL, FC, 0, FR, FL } },
180{ .ca_index = 0x2d, .speakers = { TC, FCH, RR, RL, FC, LFE, FR, FL } },
181{ .ca_index = 0x2e, .speakers = { FRH, FLH, RR, RL, FC, 0, FR, FL } },
182{ .ca_index = 0x2f, .speakers = { FRH, FLH, RR, RL, FC, LFE, FR, FL } },
183{ .ca_index = 0x30, .speakers = { FRW, FLW, RR, RL, FC, 0, FR, FL } },
184{ .ca_index = 0x31, .speakers = { FRW, FLW, RR, RL, FC, LFE, FR, FL } },
185};
186
187/*
188 * HDMI routines
189 */
190
191#ifdef BE_PARANOID
192static void hdmi_get_dip_index(struct hda_codec *codec, hda_nid_t nid,
193 int *packet_index, int *byte_index)
194{
195 int val;
196
197 val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_DIP_INDEX, 0);
198
199 *packet_index = val >> 5;
200 *byte_index = val & 0x1f;
201}
202#endif
203
204static void hdmi_set_dip_index(struct hda_codec *codec, hda_nid_t nid,
205 int packet_index, int byte_index)
206{
207 int val;
208
209 val = (packet_index << 5) | (byte_index & 0x1f);
210
211 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_HDMI_DIP_INDEX, val);
212}
213
214static void hdmi_write_dip_byte(struct hda_codec *codec, hda_nid_t nid,
215 unsigned char val)
216{
217 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_HDMI_DIP_DATA, val);
218}
219
220static void hdmi_enable_output(struct hda_codec *codec)
221{
222 /* Unmute */
223 if (get_wcaps(codec, pin_nid) & AC_WCAP_OUT_AMP)
224 snd_hda_codec_write(codec, pin_nid, 0,
225 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
226 /* Enable pin out */
227 snd_hda_codec_write(codec, pin_nid, 0,
228 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
229}
230
231/*
232 * Enable Audio InfoFrame Transmission
233 */
234static void hdmi_start_infoframe_trans(struct hda_codec *codec)
235{
236 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
237 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_XMIT,
238 AC_DIPXMIT_BEST);
239}
240
241/*
242 * Disable Audio InfoFrame Transmission
243 */
244static void hdmi_stop_infoframe_trans(struct hda_codec *codec)
245{
246 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
247 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_XMIT,
248 AC_DIPXMIT_DISABLE);
249}
250
251static int hdmi_get_channel_count(struct hda_codec *codec)
252{
253 return 1 + snd_hda_codec_read(codec, cvt_nid, 0,
254 AC_VERB_GET_CVT_CHAN_COUNT, 0);
255}
256
257static void hdmi_set_channel_count(struct hda_codec *codec, int chs)
258{
259 snd_hda_codec_write(codec, cvt_nid, 0,
260 AC_VERB_SET_CVT_CHAN_COUNT, chs - 1);
261
262 if (chs != hdmi_get_channel_count(codec))
263 snd_printd(KERN_INFO "HDMI channel count: expect %d, get %d\n",
264 chs, hdmi_get_channel_count(codec));
265}
266
267static void hdmi_debug_channel_mapping(struct hda_codec *codec)
268{
269#ifdef CONFIG_SND_DEBUG_VERBOSE
270 int i;
271 int slot;
272
273 for (i = 0; i < 8; i++) {
274 slot = snd_hda_codec_read(codec, cvt_nid, 0,
275 AC_VERB_GET_HDMI_CHAN_SLOT, i);
276 printk(KERN_DEBUG "HDMI: ASP channel %d => slot %d\n",
277 slot >> 4, slot & 0x7);
278 }
279#endif
280}
281
282static void hdmi_parse_eld(struct hda_codec *codec)
283{
284 struct intel_hdmi_spec *spec = codec->spec;
285 struct hdmi_eld *eld = &spec->sink_eld;
286
287 if (!snd_hdmi_get_eld(eld, codec, pin_nid))
288 snd_hdmi_show_eld(eld);
289}
290
291
292/*
293 * Audio InfoFrame routines
294 */
295
296static void hdmi_debug_dip_size(struct hda_codec *codec)
297{
298#ifdef CONFIG_SND_DEBUG_VERBOSE
299 int i;
300 int size;
301
302 size = snd_hdmi_get_eld_size(codec, pin_nid);
303 printk(KERN_DEBUG "HDMI: ELD buf size is %d\n", size);
304
305 for (i = 0; i < 8; i++) {
306 size = snd_hda_codec_read(codec, pin_nid, 0,
307 AC_VERB_GET_HDMI_DIP_SIZE, i);
308 printk(KERN_DEBUG "HDMI: DIP GP[%d] buf size is %d\n", i, size);
309 }
310#endif
311}
312
313static void hdmi_clear_dip_buffers(struct hda_codec *codec)
314{
315#ifdef BE_PARANOID
316 int i, j;
317 int size;
318 int pi, bi;
319 for (i = 0; i < 8; i++) {
320 size = snd_hda_codec_read(codec, pin_nid, 0,
321 AC_VERB_GET_HDMI_DIP_SIZE, i);
322 if (size == 0)
323 continue;
324
325 hdmi_set_dip_index(codec, pin_nid, i, 0x0);
326 for (j = 1; j < 1000; j++) {
327 hdmi_write_dip_byte(codec, pin_nid, 0x0);
328 hdmi_get_dip_index(codec, pin_nid, &pi, &bi);
329 if (pi != i)
330 snd_printd(KERN_INFO "dip index %d: %d != %d\n",
331 bi, pi, i);
332 if (bi == 0) /* byte index wrapped around */
333 break;
334 }
335 snd_printd(KERN_INFO
336 "HDMI: DIP GP[%d] buf reported size=%d, written=%d\n",
337 i, size, j);
338 }
339#endif
340}
341
342static void hdmi_fill_audio_infoframe(struct hda_codec *codec,
343 struct hdmi_audio_infoframe *ai)
344{
345 u8 *params = (u8 *)ai;
346 u8 sum = 0;
347 int i;
348
349 hdmi_debug_dip_size(codec);
350 hdmi_clear_dip_buffers(codec); /* be paranoid */
351
352 for (i = 0; i < sizeof(ai); i++)
353 sum += params[i];
354 ai->checksum = - sum;
355
356 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
357 for (i = 0; i < sizeof(ai); i++)
358 hdmi_write_dip_byte(codec, pin_nid, params[i]);
359}
360
361/*
362 * Compute derived values in channel_allocations[].
363 */
364static void init_channel_allocations(void)
365{
366 int i, j;
367 struct cea_channel_speaker_allocation *p;
368
369 for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
370 p = channel_allocations + i;
371 p->channels = 0;
372 p->spk_mask = 0;
373 for (j = 0; j < ARRAY_SIZE(p->speakers); j++)
374 if (p->speakers[j]) {
375 p->channels++;
376 p->spk_mask |= p->speakers[j];
377 }
378 }
379}
380
381/*
382 * The transformation takes two steps:
383 *
384 * eld->spk_alloc => (eld_speaker_allocation_bits[]) => spk_mask
385 * spk_mask => (channel_allocations[]) => ai->CA
386 *
387 * TODO: it could select the wrong CA from multiple candidates.
388*/
389static int hdmi_setup_channel_allocation(struct hda_codec *codec,
390 struct hdmi_audio_infoframe *ai)
391{
392 struct intel_hdmi_spec *spec = codec->spec;
393 struct hdmi_eld *eld = &spec->sink_eld;
394 int i;
395 int spk_mask = 0;
396 int channels = 1 + (ai->CC02_CT47 & 0x7);
397 char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE];
398
399 /*
400 * CA defaults to 0 for basic stereo audio
401 */
402 if (channels <= 2)
403 return 0;
404
405 /*
406 * HDMI sink's ELD info cannot always be retrieved for now, e.g.
407 * in console or for audio devices. Assume the highest speakers
408 * configuration, to _not_ prohibit multi-channel audio playback.
409 */
410 if (!eld->spk_alloc)
411 eld->spk_alloc = 0xffff;
412
413 /*
414 * expand ELD's speaker allocation mask
415 *
416 * ELD tells the speaker mask in a compact(paired) form,
417 * expand ELD's notions to match the ones used by Audio InfoFrame.
418 */
419 for (i = 0; i < ARRAY_SIZE(eld_speaker_allocation_bits); i++) {
420 if (eld->spk_alloc & (1 << i))
421 spk_mask |= eld_speaker_allocation_bits[i];
422 }
423
424 /* search for the first working match in the CA table */
425 for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
426 if (channels == channel_allocations[i].channels &&
427 (spk_mask & channel_allocations[i].spk_mask) ==
428 channel_allocations[i].spk_mask) {
429 ai->CA = channel_allocations[i].ca_index;
430 break;
431 }
432 }
433
434 snd_print_channel_allocation(eld->spk_alloc, buf, sizeof(buf));
435 snd_printdd(KERN_INFO
436 "HDMI: select CA 0x%x for %d-channel allocation: %s\n",
437 ai->CA, channels, buf);
438
439 return ai->CA;
440}
441
442static void hdmi_setup_channel_mapping(struct hda_codec *codec,
443 struct hdmi_audio_infoframe *ai)
444{
445 int i;
446
447 if (!ai->CA)
448 return;
449
450 /*
451 * TODO: adjust channel mapping if necessary
452 * ALSA sequence is front/surr/clfe/side?
453 */
454
455 for (i = 0; i < 8; i++)
456 snd_hda_codec_write(codec, cvt_nid, 0,
457 AC_VERB_SET_HDMI_CHAN_SLOT,
458 (i << 4) | i);
459
460 hdmi_debug_channel_mapping(codec);
461}
462
463
464static void hdmi_setup_audio_infoframe(struct hda_codec *codec,
465 struct snd_pcm_substream *substream)
466{
467 struct hdmi_audio_infoframe ai = {
468 .type = 0x84,
469 .ver = 0x01,
470 .len = 0x0a,
471 .CC02_CT47 = substream->runtime->channels - 1,
472 };
473
474 hdmi_setup_channel_allocation(codec, &ai);
475 hdmi_setup_channel_mapping(codec, &ai);
476
477 hdmi_fill_audio_infoframe(codec, &ai);
478 hdmi_start_infoframe_trans(codec);
479}
480
481
482/*
483 * Unsolicited events
484 */
485
486static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
487{
488 int pind = !!(res & AC_UNSOL_RES_PD);
489 int eldv = !!(res & AC_UNSOL_RES_ELDV);
490
491 printk(KERN_INFO
492 "HDMI hot plug event: Presence_Detect=%d ELD_Valid=%d\n",
493 pind, eldv);
494
495 if (pind && eldv) {
496 hdmi_parse_eld(codec);
497 /* TODO: do real things about ELD */
498 }
499}
500
501static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res)
502{
503 int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT;
504 int cp_state = !!(res & AC_UNSOL_RES_CP_STATE);
505 int cp_ready = !!(res & AC_UNSOL_RES_CP_READY);
506
507 printk(KERN_INFO
508 "HDMI content protection event: SUBTAG=0x%x CP_STATE=%d CP_READY=%d\n",
509 subtag,
510 cp_state,
511 cp_ready);
512
513 /* TODO */
514 if (cp_state)
515 ;
516 if (cp_ready)
517 ;
518}
519
520
521static void intel_hdmi_unsol_event(struct hda_codec *codec, unsigned int res)
522{
523 int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
524 int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT;
525
526 if (tag != INTEL_HDMI_EVENT_TAG) {
527 snd_printd(KERN_INFO "Unexpected HDMI event tag 0x%x\n", tag);
528 return;
529 }
530
531 if (subtag == 0)
532 hdmi_intrinsic_event(codec, res);
533 else
534 hdmi_non_intrinsic_event(codec, res);
535}
536
537/*
538 * Callbacks
539 */ 55 */
540 56
541static int intel_hdmi_playback_pcm_open(struct hda_pcm_stream *hinfo,
542 struct hda_codec *codec,
543 struct snd_pcm_substream *substream)
544{
545 struct intel_hdmi_spec *spec = codec->spec;
546
547 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
548}
549
550static int intel_hdmi_playback_pcm_close(struct hda_pcm_stream *hinfo,
551 struct hda_codec *codec,
552 struct snd_pcm_substream *substream)
553{
554 struct intel_hdmi_spec *spec = codec->spec;
555
556 hdmi_stop_infoframe_trans(codec);
557
558 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
559}
560
561static int intel_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 57static int intel_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
562 struct hda_codec *codec, 58 struct hda_codec *codec,
563 unsigned int stream_tag, 59 unsigned int stream_tag,
564 unsigned int format, 60 unsigned int format,
565 struct snd_pcm_substream *substream) 61 struct snd_pcm_substream *substream)
566{ 62{
567 struct intel_hdmi_spec *spec = codec->spec; 63 hdmi_set_channel_count(codec, hinfo->nid,
64 substream->runtime->channels);
568 65
569 snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag, 66 hdmi_setup_audio_infoframe(codec, hinfo->nid, substream);
570 format, substream);
571 67
572 hdmi_set_channel_count(codec, substream->runtime->channels); 68 hdmi_setup_stream(codec, hinfo->nid, stream_tag, format);
573 69 return 0;
574 hdmi_setup_audio_infoframe(codec, substream); 70}
575 71
72static int intel_hdmi_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
73 struct hda_codec *codec,
74 struct snd_pcm_substream *substream)
75{
576 return 0; 76 return 0;
577} 77}
578 78
579static struct hda_pcm_stream intel_hdmi_pcm_playback = { 79static struct hda_pcm_stream intel_hdmi_pcm_playback = {
580 .substreams = 1, 80 .substreams = 1,
581 .channels_min = 2, 81 .channels_min = 2,
582 .channels_max = 8,
583 .ops = { 82 .ops = {
584 .open = intel_hdmi_playback_pcm_open, 83 .prepare = intel_hdmi_playback_pcm_prepare,
585 .close = intel_hdmi_playback_pcm_close, 84 .cleanup = intel_hdmi_playback_pcm_cleanup,
586 .prepare = intel_hdmi_playback_pcm_prepare
587 }, 85 },
588}; 86};
589 87
590static int intel_hdmi_build_pcms(struct hda_codec *codec) 88static int intel_hdmi_build_pcms(struct hda_codec *codec)
591{ 89{
592 struct intel_hdmi_spec *spec = codec->spec; 90 struct hdmi_spec *spec = codec->spec;
593 struct hda_pcm *info = &spec->pcm_rec; 91 struct hda_pcm *info = spec->pcm_rec;
92 int i;
594 93
595 codec->num_pcms = 1; 94 codec->num_pcms = spec->num_cvts;
596 codec->pcm_info = info; 95 codec->pcm_info = info;
597 96
598 /* NID to query formats and rates and setup streams */ 97 for (i = 0; i < codec->num_pcms; i++, info++) {
599 intel_hdmi_pcm_playback.nid = cvt_nid; 98 unsigned int chans;
99
100 chans = get_wcaps(codec, spec->cvt[i]);
101 chans = get_wcaps_channels(chans);
600 102
601 info->name = "INTEL HDMI"; 103 info->name = intel_hdmi_pcm_names[i];
602 info->pcm_type = HDA_PCM_TYPE_HDMI; 104 info->pcm_type = HDA_PCM_TYPE_HDMI;
603 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = intel_hdmi_pcm_playback; 105 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
106 intel_hdmi_pcm_playback;
107 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->cvt[i];
108 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = chans;
109 }
604 110
605 return 0; 111 return 0;
606} 112}
607 113
608static int intel_hdmi_build_controls(struct hda_codec *codec) 114static int intel_hdmi_build_controls(struct hda_codec *codec)
609{ 115{
610 struct intel_hdmi_spec *spec = codec->spec; 116 struct hdmi_spec *spec = codec->spec;
611 int err; 117 int err;
118 int i;
612 119
613 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid); 120 for (i = 0; i < codec->num_pcms; i++) {
614 if (err < 0) 121 err = snd_hda_create_spdif_out_ctls(codec, spec->cvt[i]);
615 return err; 122 if (err < 0)
123 return err;
124 }
616 125
617 return 0; 126 return 0;
618} 127}
619 128
620static int intel_hdmi_init(struct hda_codec *codec) 129static int intel_hdmi_init(struct hda_codec *codec)
621{ 130{
622 hdmi_enable_output(codec); 131 struct hdmi_spec *spec = codec->spec;
132 int i;
623 133
624 snd_hda_codec_write(codec, pin_nid, 0, 134 for (i = 0; spec->pin[i]; i++) {
625 AC_VERB_SET_UNSOLICITED_ENABLE, 135 hdmi_enable_output(codec, spec->pin[i]);
626 AC_USRSP_EN | INTEL_HDMI_EVENT_TAG); 136 snd_hda_codec_write(codec, spec->pin[i], 0,
137 AC_VERB_SET_UNSOLICITED_ENABLE,
138 AC_USRSP_EN | spec->pin[i]);
139 }
627 return 0; 140 return 0;
628} 141}
629 142
630static void intel_hdmi_free(struct hda_codec *codec) 143static void intel_hdmi_free(struct hda_codec *codec)
631{ 144{
632 struct intel_hdmi_spec *spec = codec->spec; 145 struct hdmi_spec *spec = codec->spec;
146 int i;
147
148 for (i = 0; i < spec->num_pins; i++)
149 snd_hda_eld_proc_free(codec, &spec->sink_eld[i]);
633 150
634 snd_hda_eld_proc_free(codec, &spec->sink_eld);
635 kfree(spec); 151 kfree(spec);
636} 152}
637 153
@@ -640,52 +156,41 @@ static struct hda_codec_ops intel_hdmi_patch_ops = {
640 .free = intel_hdmi_free, 156 .free = intel_hdmi_free,
641 .build_pcms = intel_hdmi_build_pcms, 157 .build_pcms = intel_hdmi_build_pcms,
642 .build_controls = intel_hdmi_build_controls, 158 .build_controls = intel_hdmi_build_controls,
643 .unsol_event = intel_hdmi_unsol_event, 159 .unsol_event = hdmi_unsol_event,
644}; 160};
645 161
646static int do_patch_intel_hdmi(struct hda_codec *codec) 162static int patch_intel_hdmi(struct hda_codec *codec)
647{ 163{
648 struct intel_hdmi_spec *spec; 164 struct hdmi_spec *spec;
165 int i;
649 166
650 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 167 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
651 if (spec == NULL) 168 if (spec == NULL)
652 return -ENOMEM; 169 return -ENOMEM;
653 170
654 spec->multiout.num_dacs = 0; /* no analog */
655 spec->multiout.max_channels = 8;
656 spec->multiout.dig_out_nid = cvt_nid;
657
658 codec->spec = spec; 171 codec->spec = spec;
172 if (hdmi_parse_codec(codec) < 0) {
173 codec->spec = NULL;
174 kfree(spec);
175 return -EINVAL;
176 }
659 codec->patch_ops = intel_hdmi_patch_ops; 177 codec->patch_ops = intel_hdmi_patch_ops;
660 178
661 snd_hda_eld_proc_new(codec, &spec->sink_eld); 179 for (i = 0; i < spec->num_pins; i++)
180 snd_hda_eld_proc_new(codec, &spec->sink_eld[i], i);
662 181
663 init_channel_allocations(); 182 init_channel_allocations();
664 183
665 return 0; 184 return 0;
666} 185}
667 186
668static int patch_intel_hdmi(struct hda_codec *codec)
669{
670 cvt_nid = 0x02;
671 pin_nid = 0x03;
672 return do_patch_intel_hdmi(codec);
673}
674
675static int patch_intel_hdmi_ibexpeak(struct hda_codec *codec)
676{
677 cvt_nid = 0x02;
678 pin_nid = 0x04;
679 return do_patch_intel_hdmi(codec);
680}
681
682static struct hda_codec_preset snd_hda_preset_intelhdmi[] = { 187static struct hda_codec_preset snd_hda_preset_intelhdmi[] = {
683 { .id = 0x808629fb, .name = "G45 DEVCL", .patch = patch_intel_hdmi }, 188 { .id = 0x808629fb, .name = "G45 DEVCL", .patch = patch_intel_hdmi },
684 { .id = 0x80862801, .name = "G45 DEVBLC", .patch = patch_intel_hdmi }, 189 { .id = 0x80862801, .name = "G45 DEVBLC", .patch = patch_intel_hdmi },
685 { .id = 0x80862802, .name = "G45 DEVCTG", .patch = patch_intel_hdmi }, 190 { .id = 0x80862802, .name = "G45 DEVCTG", .patch = patch_intel_hdmi },
686 { .id = 0x80862803, .name = "G45 DEVELK", .patch = patch_intel_hdmi }, 191 { .id = 0x80862803, .name = "G45 DEVELK", .patch = patch_intel_hdmi },
687 { .id = 0x80862804, .name = "G45 DEVIBX", .patch = patch_intel_hdmi }, 192 { .id = 0x80862804, .name = "G45 DEVIBX", .patch = patch_intel_hdmi },
688 { .id = 0x80860054, .name = "Q57 DEVIBX", .patch = patch_intel_hdmi_ibexpeak }, 193 { .id = 0x80860054, .name = "Q57 DEVIBX", .patch = patch_intel_hdmi },
689 { .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_intel_hdmi }, 194 { .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_intel_hdmi },
690 {} /* terminator */ 195 {} /* terminator */
691}; 196};
diff --git a/sound/pci/hda/patch_nvhdmi.c b/sound/pci/hda/patch_nvhdmi.c
index 6afdab09bab7..3c10c0b149f4 100644
--- a/sound/pci/hda/patch_nvhdmi.c
+++ b/sound/pci/hda/patch_nvhdmi.c
@@ -29,13 +29,23 @@
29#include "hda_codec.h" 29#include "hda_codec.h"
30#include "hda_local.h" 30#include "hda_local.h"
31 31
32#define MAX_HDMI_CVTS 1
33#define MAX_HDMI_PINS 1
34
35#include "patch_hdmi.c"
36
37static char *nvhdmi_pcm_names[MAX_HDMI_CVTS] = {
38 "NVIDIA HDMI",
39};
40
32/* define below to restrict the supported rates and formats */ 41/* define below to restrict the supported rates and formats */
33/* #define LIMITED_RATE_FMT_SUPPORT */ 42/* #define LIMITED_RATE_FMT_SUPPORT */
34 43
35struct nvhdmi_spec { 44enum HDACodec {
36 struct hda_multi_out multiout; 45 HDA_CODEC_NVIDIA_MCP7X,
37 46 HDA_CODEC_NVIDIA_MCP89,
38 struct hda_pcm pcm_rec; 47 HDA_CODEC_NVIDIA_GT21X,
48 HDA_CODEC_INVALID
39}; 49};
40 50
41#define Nv_VERB_SET_Channel_Allocation 0xF79 51#define Nv_VERB_SET_Channel_Allocation 0xF79
@@ -43,15 +53,18 @@ struct nvhdmi_spec {
43#define Nv_VERB_SET_Audio_Protection_On 0xF98 53#define Nv_VERB_SET_Audio_Protection_On 0xF98
44#define Nv_VERB_SET_Audio_Protection_Off 0xF99 54#define Nv_VERB_SET_Audio_Protection_Off 0xF99
45 55
46#define Nv_Master_Convert_nid 0x04 56#define nvhdmi_master_con_nid_7x 0x04
47#define Nv_Master_Pin_nid 0x05 57#define nvhdmi_master_pin_nid_7x 0x05
48 58
49static hda_nid_t nvhdmi_convert_nids[4] = { 59#define nvhdmi_master_con_nid_89 0x04
60#define nvhdmi_master_pin_nid_89 0x05
61
62static hda_nid_t nvhdmi_con_nids_7x[4] = {
50 /*front, rear, clfe, rear_surr */ 63 /*front, rear, clfe, rear_surr */
51 0x6, 0x8, 0xa, 0xc, 64 0x6, 0x8, 0xa, 0xc,
52}; 65};
53 66
54static struct hda_verb nvhdmi_basic_init[] = { 67static struct hda_verb nvhdmi_basic_init_7x[] = {
55 /* set audio protect on */ 68 /* set audio protect on */
56 { 0x1, Nv_VERB_SET_Audio_Protection_On, 0x1}, 69 { 0x1, Nv_VERB_SET_Audio_Protection_On, 0x1},
57 /* enable digital output on pin widget */ 70 /* enable digital output on pin widget */
@@ -84,22 +97,60 @@ static struct hda_verb nvhdmi_basic_init[] = {
84 */ 97 */
85static int nvhdmi_build_controls(struct hda_codec *codec) 98static int nvhdmi_build_controls(struct hda_codec *codec)
86{ 99{
87 struct nvhdmi_spec *spec = codec->spec; 100 struct hdmi_spec *spec = codec->spec;
88 int err; 101 int err;
102 int i;
89 103
90 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid); 104 if ((spec->codec_type == HDA_CODEC_NVIDIA_MCP89)
91 if (err < 0) 105 || (spec->codec_type == HDA_CODEC_NVIDIA_GT21X)) {
92 return err; 106 for (i = 0; i < codec->num_pcms; i++) {
107 err = snd_hda_create_spdif_out_ctls(codec,
108 spec->cvt[i]);
109 if (err < 0)
110 return err;
111 }
112 } else {
113 err = snd_hda_create_spdif_out_ctls(codec,
114 spec->multiout.dig_out_nid);
115 if (err < 0)
116 return err;
117 }
93 118
94 return 0; 119 return 0;
95} 120}
96 121
97static int nvhdmi_init(struct hda_codec *codec) 122static int nvhdmi_init(struct hda_codec *codec)
98{ 123{
99 snd_hda_sequence_write(codec, nvhdmi_basic_init); 124 struct hdmi_spec *spec = codec->spec;
125 int i;
126 if ((spec->codec_type == HDA_CODEC_NVIDIA_MCP89)
127 || (spec->codec_type == HDA_CODEC_NVIDIA_GT21X)) {
128 for (i = 0; spec->pin[i]; i++) {
129 hdmi_enable_output(codec, spec->pin[i]);
130 snd_hda_codec_write(codec, spec->pin[i], 0,
131 AC_VERB_SET_UNSOLICITED_ENABLE,
132 AC_USRSP_EN | spec->pin[i]);
133 }
134 } else {
135 snd_hda_sequence_write(codec, nvhdmi_basic_init_7x);
136 }
100 return 0; 137 return 0;
101} 138}
102 139
140static void nvhdmi_free(struct hda_codec *codec)
141{
142 struct hdmi_spec *spec = codec->spec;
143 int i;
144
145 if ((spec->codec_type == HDA_CODEC_NVIDIA_MCP89)
146 || (spec->codec_type == HDA_CODEC_NVIDIA_GT21X)) {
147 for (i = 0; i < spec->num_pins; i++)
148 snd_hda_eld_proc_free(codec, &spec->sink_eld[i]);
149 }
150
151 kfree(spec);
152}
153
103/* 154/*
104 * Digital out 155 * Digital out
105 */ 156 */
@@ -107,25 +158,25 @@ static int nvhdmi_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
107 struct hda_codec *codec, 158 struct hda_codec *codec,
108 struct snd_pcm_substream *substream) 159 struct snd_pcm_substream *substream)
109{ 160{
110 struct nvhdmi_spec *spec = codec->spec; 161 struct hdmi_spec *spec = codec->spec;
111 return snd_hda_multi_out_dig_open(codec, &spec->multiout); 162 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
112} 163}
113 164
114static int nvhdmi_dig_playback_pcm_close_8ch(struct hda_pcm_stream *hinfo, 165static int nvhdmi_dig_playback_pcm_close_8ch_7x(struct hda_pcm_stream *hinfo,
115 struct hda_codec *codec, 166 struct hda_codec *codec,
116 struct snd_pcm_substream *substream) 167 struct snd_pcm_substream *substream)
117{ 168{
118 struct nvhdmi_spec *spec = codec->spec; 169 struct hdmi_spec *spec = codec->spec;
119 int i; 170 int i;
120 171
121 snd_hda_codec_write(codec, Nv_Master_Convert_nid, 172 snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x,
122 0, AC_VERB_SET_CHANNEL_STREAMID, 0); 173 0, AC_VERB_SET_CHANNEL_STREAMID, 0);
123 for (i = 0; i < 4; i++) { 174 for (i = 0; i < 4; i++) {
124 /* set the stream id */ 175 /* set the stream id */
125 snd_hda_codec_write(codec, nvhdmi_convert_nids[i], 0, 176 snd_hda_codec_write(codec, nvhdmi_con_nids_7x[i], 0,
126 AC_VERB_SET_CHANNEL_STREAMID, 0); 177 AC_VERB_SET_CHANNEL_STREAMID, 0);
127 /* set the stream format */ 178 /* set the stream format */
128 snd_hda_codec_write(codec, nvhdmi_convert_nids[i], 0, 179 snd_hda_codec_write(codec, nvhdmi_con_nids_7x[i], 0,
129 AC_VERB_SET_STREAM_FORMAT, 0); 180 AC_VERB_SET_STREAM_FORMAT, 0);
130 } 181 }
131 182
@@ -136,10 +187,25 @@ static int nvhdmi_dig_playback_pcm_close_2ch(struct hda_pcm_stream *hinfo,
136 struct hda_codec *codec, 187 struct hda_codec *codec,
137 struct snd_pcm_substream *substream) 188 struct snd_pcm_substream *substream)
138{ 189{
139 struct nvhdmi_spec *spec = codec->spec; 190 struct hdmi_spec *spec = codec->spec;
140 return snd_hda_multi_out_dig_close(codec, &spec->multiout); 191 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
141} 192}
142 193
194static int nvhdmi_dig_playback_pcm_prepare_8ch_89(struct hda_pcm_stream *hinfo,
195 struct hda_codec *codec,
196 unsigned int stream_tag,
197 unsigned int format,
198 struct snd_pcm_substream *substream)
199{
200 hdmi_set_channel_count(codec, hinfo->nid,
201 substream->runtime->channels);
202
203 hdmi_setup_audio_infoframe(codec, hinfo->nid, substream);
204
205 hdmi_setup_stream(codec, hinfo->nid, stream_tag, format);
206 return 0;
207}
208
143static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo, 209static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo,
144 struct hda_codec *codec, 210 struct hda_codec *codec,
145 unsigned int stream_tag, 211 unsigned int stream_tag,
@@ -181,29 +247,29 @@ static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo,
181 /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */ 247 /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
182 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) 248 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE))
183 snd_hda_codec_write(codec, 249 snd_hda_codec_write(codec,
184 Nv_Master_Convert_nid, 250 nvhdmi_master_con_nid_7x,
185 0, 251 0,
186 AC_VERB_SET_DIGI_CONVERT_1, 252 AC_VERB_SET_DIGI_CONVERT_1,
187 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff); 253 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff);
188 254
189 /* set the stream id */ 255 /* set the stream id */
190 snd_hda_codec_write(codec, Nv_Master_Convert_nid, 0, 256 snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x, 0,
191 AC_VERB_SET_CHANNEL_STREAMID, (stream_tag << 4) | 0x0); 257 AC_VERB_SET_CHANNEL_STREAMID, (stream_tag << 4) | 0x0);
192 258
193 /* set the stream format */ 259 /* set the stream format */
194 snd_hda_codec_write(codec, Nv_Master_Convert_nid, 0, 260 snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x, 0,
195 AC_VERB_SET_STREAM_FORMAT, format); 261 AC_VERB_SET_STREAM_FORMAT, format);
196 262
197 /* turn on again (if needed) */ 263 /* turn on again (if needed) */
198 /* enable and set the channel status audio/data flag */ 264 /* enable and set the channel status audio/data flag */
199 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) { 265 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) {
200 snd_hda_codec_write(codec, 266 snd_hda_codec_write(codec,
201 Nv_Master_Convert_nid, 267 nvhdmi_master_con_nid_7x,
202 0, 268 0,
203 AC_VERB_SET_DIGI_CONVERT_1, 269 AC_VERB_SET_DIGI_CONVERT_1,
204 codec->spdif_ctls & 0xff); 270 codec->spdif_ctls & 0xff);
205 snd_hda_codec_write(codec, 271 snd_hda_codec_write(codec,
206 Nv_Master_Convert_nid, 272 nvhdmi_master_con_nid_7x,
207 0, 273 0,
208 AC_VERB_SET_DIGI_CONVERT_2, dataDCC2); 274 AC_VERB_SET_DIGI_CONVERT_2, dataDCC2);
209 } 275 }
@@ -220,19 +286,19 @@ static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo,
220 if (codec->spdif_status_reset && 286 if (codec->spdif_status_reset &&
221 (codec->spdif_ctls & AC_DIG1_ENABLE)) 287 (codec->spdif_ctls & AC_DIG1_ENABLE))
222 snd_hda_codec_write(codec, 288 snd_hda_codec_write(codec,
223 nvhdmi_convert_nids[i], 289 nvhdmi_con_nids_7x[i],
224 0, 290 0,
225 AC_VERB_SET_DIGI_CONVERT_1, 291 AC_VERB_SET_DIGI_CONVERT_1,
226 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff); 292 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff);
227 /* set the stream id */ 293 /* set the stream id */
228 snd_hda_codec_write(codec, 294 snd_hda_codec_write(codec,
229 nvhdmi_convert_nids[i], 295 nvhdmi_con_nids_7x[i],
230 0, 296 0,
231 AC_VERB_SET_CHANNEL_STREAMID, 297 AC_VERB_SET_CHANNEL_STREAMID,
232 (stream_tag << 4) | channel_id); 298 (stream_tag << 4) | channel_id);
233 /* set the stream format */ 299 /* set the stream format */
234 snd_hda_codec_write(codec, 300 snd_hda_codec_write(codec,
235 nvhdmi_convert_nids[i], 301 nvhdmi_con_nids_7x[i],
236 0, 302 0,
237 AC_VERB_SET_STREAM_FORMAT, 303 AC_VERB_SET_STREAM_FORMAT,
238 format); 304 format);
@@ -241,12 +307,12 @@ static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo,
241 if (codec->spdif_status_reset && 307 if (codec->spdif_status_reset &&
242 (codec->spdif_ctls & AC_DIG1_ENABLE)) { 308 (codec->spdif_ctls & AC_DIG1_ENABLE)) {
243 snd_hda_codec_write(codec, 309 snd_hda_codec_write(codec,
244 nvhdmi_convert_nids[i], 310 nvhdmi_con_nids_7x[i],
245 0, 311 0,
246 AC_VERB_SET_DIGI_CONVERT_1, 312 AC_VERB_SET_DIGI_CONVERT_1,
247 codec->spdif_ctls & 0xff); 313 codec->spdif_ctls & 0xff);
248 snd_hda_codec_write(codec, 314 snd_hda_codec_write(codec,
249 nvhdmi_convert_nids[i], 315 nvhdmi_con_nids_7x[i],
250 0, 316 0,
251 AC_VERB_SET_DIGI_CONVERT_2, dataDCC2); 317 AC_VERB_SET_DIGI_CONVERT_2, dataDCC2);
252 } 318 }
@@ -261,28 +327,47 @@ static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo,
261 return 0; 327 return 0;
262} 328}
263 329
330static int nvhdmi_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
331 struct hda_codec *codec,
332 struct snd_pcm_substream *substream)
333{
334 return 0;
335}
336
264static int nvhdmi_dig_playback_pcm_prepare_2ch(struct hda_pcm_stream *hinfo, 337static int nvhdmi_dig_playback_pcm_prepare_2ch(struct hda_pcm_stream *hinfo,
265 struct hda_codec *codec, 338 struct hda_codec *codec,
266 unsigned int stream_tag, 339 unsigned int stream_tag,
267 unsigned int format, 340 unsigned int format,
268 struct snd_pcm_substream *substream) 341 struct snd_pcm_substream *substream)
269{ 342{
270 struct nvhdmi_spec *spec = codec->spec; 343 struct hdmi_spec *spec = codec->spec;
271 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag, 344 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
272 format, substream); 345 format, substream);
273} 346}
274 347
275static struct hda_pcm_stream nvhdmi_pcm_digital_playback_8ch = { 348static struct hda_pcm_stream nvhdmi_pcm_digital_playback_8ch_89 = {
349 .substreams = 1,
350 .channels_min = 2,
351 .rates = SUPPORTED_RATES,
352 .maxbps = SUPPORTED_MAXBPS,
353 .formats = SUPPORTED_FORMATS,
354 .ops = {
355 .prepare = nvhdmi_dig_playback_pcm_prepare_8ch_89,
356 .cleanup = nvhdmi_playback_pcm_cleanup,
357 },
358};
359
360static struct hda_pcm_stream nvhdmi_pcm_digital_playback_8ch_7x = {
276 .substreams = 1, 361 .substreams = 1,
277 .channels_min = 2, 362 .channels_min = 2,
278 .channels_max = 8, 363 .channels_max = 8,
279 .nid = Nv_Master_Convert_nid, 364 .nid = nvhdmi_master_con_nid_7x,
280 .rates = SUPPORTED_RATES, 365 .rates = SUPPORTED_RATES,
281 .maxbps = SUPPORTED_MAXBPS, 366 .maxbps = SUPPORTED_MAXBPS,
282 .formats = SUPPORTED_FORMATS, 367 .formats = SUPPORTED_FORMATS,
283 .ops = { 368 .ops = {
284 .open = nvhdmi_dig_playback_pcm_open, 369 .open = nvhdmi_dig_playback_pcm_open,
285 .close = nvhdmi_dig_playback_pcm_close_8ch, 370 .close = nvhdmi_dig_playback_pcm_close_8ch_7x,
286 .prepare = nvhdmi_dig_playback_pcm_prepare_8ch 371 .prepare = nvhdmi_dig_playback_pcm_prepare_8ch
287 }, 372 },
288}; 373};
@@ -291,7 +376,7 @@ static struct hda_pcm_stream nvhdmi_pcm_digital_playback_2ch = {
291 .substreams = 1, 376 .substreams = 1,
292 .channels_min = 2, 377 .channels_min = 2,
293 .channels_max = 2, 378 .channels_max = 2,
294 .nid = Nv_Master_Convert_nid, 379 .nid = nvhdmi_master_con_nid_7x,
295 .rates = SUPPORTED_RATES, 380 .rates = SUPPORTED_RATES,
296 .maxbps = SUPPORTED_MAXBPS, 381 .maxbps = SUPPORTED_MAXBPS,
297 .formats = SUPPORTED_FORMATS, 382 .formats = SUPPORTED_FORMATS,
@@ -302,10 +387,36 @@ static struct hda_pcm_stream nvhdmi_pcm_digital_playback_2ch = {
302 }, 387 },
303}; 388};
304 389
305static int nvhdmi_build_pcms_8ch(struct hda_codec *codec) 390static int nvhdmi_build_pcms_8ch_89(struct hda_codec *codec)
391{
392 struct hdmi_spec *spec = codec->spec;
393 struct hda_pcm *info = spec->pcm_rec;
394 int i;
395
396 codec->num_pcms = spec->num_cvts;
397 codec->pcm_info = info;
398
399 for (i = 0; i < codec->num_pcms; i++, info++) {
400 unsigned int chans;
401
402 chans = get_wcaps(codec, spec->cvt[i]);
403 chans = get_wcaps_channels(chans);
404
405 info->name = nvhdmi_pcm_names[i];
406 info->pcm_type = HDA_PCM_TYPE_HDMI;
407 info->stream[SNDRV_PCM_STREAM_PLAYBACK]
408 = nvhdmi_pcm_digital_playback_8ch_89;
409 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->cvt[i];
410 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = chans;
411 }
412
413 return 0;
414}
415
416static int nvhdmi_build_pcms_8ch_7x(struct hda_codec *codec)
306{ 417{
307 struct nvhdmi_spec *spec = codec->spec; 418 struct hdmi_spec *spec = codec->spec;
308 struct hda_pcm *info = &spec->pcm_rec; 419 struct hda_pcm *info = spec->pcm_rec;
309 420
310 codec->num_pcms = 1; 421 codec->num_pcms = 1;
311 codec->pcm_info = info; 422 codec->pcm_info = info;
@@ -313,15 +424,15 @@ static int nvhdmi_build_pcms_8ch(struct hda_codec *codec)
313 info->name = "NVIDIA HDMI"; 424 info->name = "NVIDIA HDMI";
314 info->pcm_type = HDA_PCM_TYPE_HDMI; 425 info->pcm_type = HDA_PCM_TYPE_HDMI;
315 info->stream[SNDRV_PCM_STREAM_PLAYBACK] 426 info->stream[SNDRV_PCM_STREAM_PLAYBACK]
316 = nvhdmi_pcm_digital_playback_8ch; 427 = nvhdmi_pcm_digital_playback_8ch_7x;
317 428
318 return 0; 429 return 0;
319} 430}
320 431
321static int nvhdmi_build_pcms_2ch(struct hda_codec *codec) 432static int nvhdmi_build_pcms_2ch(struct hda_codec *codec)
322{ 433{
323 struct nvhdmi_spec *spec = codec->spec; 434 struct hdmi_spec *spec = codec->spec;
324 struct hda_pcm *info = &spec->pcm_rec; 435 struct hda_pcm *info = spec->pcm_rec;
325 436
326 codec->num_pcms = 1; 437 codec->num_pcms = 1;
327 codec->pcm_info = info; 438 codec->pcm_info = info;
@@ -334,14 +445,17 @@ static int nvhdmi_build_pcms_2ch(struct hda_codec *codec)
334 return 0; 445 return 0;
335} 446}
336 447
337static void nvhdmi_free(struct hda_codec *codec) 448static struct hda_codec_ops nvhdmi_patch_ops_8ch_89 = {
338{ 449 .build_controls = nvhdmi_build_controls,
339 kfree(codec->spec); 450 .build_pcms = nvhdmi_build_pcms_8ch_89,
340} 451 .init = nvhdmi_init,
452 .free = nvhdmi_free,
453 .unsol_event = hdmi_unsol_event,
454};
341 455
342static struct hda_codec_ops nvhdmi_patch_ops_8ch = { 456static struct hda_codec_ops nvhdmi_patch_ops_8ch_7x = {
343 .build_controls = nvhdmi_build_controls, 457 .build_controls = nvhdmi_build_controls,
344 .build_pcms = nvhdmi_build_pcms_8ch, 458 .build_pcms = nvhdmi_build_pcms_8ch_7x,
345 .init = nvhdmi_init, 459 .init = nvhdmi_init,
346 .free = nvhdmi_free, 460 .free = nvhdmi_free,
347}; 461};
@@ -353,9 +467,36 @@ static struct hda_codec_ops nvhdmi_patch_ops_2ch = {
353 .free = nvhdmi_free, 467 .free = nvhdmi_free,
354}; 468};
355 469
356static int patch_nvhdmi_8ch(struct hda_codec *codec) 470static int patch_nvhdmi_8ch_89(struct hda_codec *codec)
471{
472 struct hdmi_spec *spec;
473 int i;
474
475 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
476 if (spec == NULL)
477 return -ENOMEM;
478
479 codec->spec = spec;
480 spec->codec_type = HDA_CODEC_NVIDIA_MCP89;
481
482 if (hdmi_parse_codec(codec) < 0) {
483 codec->spec = NULL;
484 kfree(spec);
485 return -EINVAL;
486 }
487 codec->patch_ops = nvhdmi_patch_ops_8ch_89;
488
489 for (i = 0; i < spec->num_pins; i++)
490 snd_hda_eld_proc_new(codec, &spec->sink_eld[i], i);
491
492 init_channel_allocations();
493
494 return 0;
495}
496
497static int patch_nvhdmi_8ch_7x(struct hda_codec *codec)
357{ 498{
358 struct nvhdmi_spec *spec; 499 struct hdmi_spec *spec;
359 500
360 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 501 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
361 if (spec == NULL) 502 if (spec == NULL)
@@ -365,16 +506,17 @@ static int patch_nvhdmi_8ch(struct hda_codec *codec)
365 506
366 spec->multiout.num_dacs = 0; /* no analog */ 507 spec->multiout.num_dacs = 0; /* no analog */
367 spec->multiout.max_channels = 8; 508 spec->multiout.max_channels = 8;
368 spec->multiout.dig_out_nid = Nv_Master_Convert_nid; 509 spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x;
510 spec->codec_type = HDA_CODEC_NVIDIA_MCP7X;
369 511
370 codec->patch_ops = nvhdmi_patch_ops_8ch; 512 codec->patch_ops = nvhdmi_patch_ops_8ch_7x;
371 513
372 return 0; 514 return 0;
373} 515}
374 516
375static int patch_nvhdmi_2ch(struct hda_codec *codec) 517static int patch_nvhdmi_2ch(struct hda_codec *codec)
376{ 518{
377 struct nvhdmi_spec *spec; 519 struct hdmi_spec *spec;
378 520
379 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 521 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
380 if (spec == NULL) 522 if (spec == NULL)
@@ -384,7 +526,8 @@ static int patch_nvhdmi_2ch(struct hda_codec *codec)
384 526
385 spec->multiout.num_dacs = 0; /* no analog */ 527 spec->multiout.num_dacs = 0; /* no analog */
386 spec->multiout.max_channels = 2; 528 spec->multiout.max_channels = 2;
387 spec->multiout.dig_out_nid = Nv_Master_Convert_nid; 529 spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x;
530 spec->codec_type = HDA_CODEC_NVIDIA_MCP7X;
388 531
389 codec->patch_ops = nvhdmi_patch_ops_2ch; 532 codec->patch_ops = nvhdmi_patch_ops_2ch;
390 533
@@ -395,11 +538,24 @@ static int patch_nvhdmi_2ch(struct hda_codec *codec)
395 * patch entries 538 * patch entries
396 */ 539 */
397static struct hda_codec_preset snd_hda_preset_nvhdmi[] = { 540static struct hda_codec_preset snd_hda_preset_nvhdmi[] = {
398 { .id = 0x10de0002, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch }, 541 { .id = 0x10de0002, .name = "MCP77/78 HDMI",
399 { .id = 0x10de0003, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch }, 542 .patch = patch_nvhdmi_8ch_7x },
400 { .id = 0x10de0005, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch }, 543 { .id = 0x10de0003, .name = "MCP77/78 HDMI",
401 { .id = 0x10de0006, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch }, 544 .patch = patch_nvhdmi_8ch_7x },
402 { .id = 0x10de0007, .name = "MCP7A HDMI", .patch = patch_nvhdmi_8ch }, 545 { .id = 0x10de0005, .name = "MCP77/78 HDMI",
546 .patch = patch_nvhdmi_8ch_7x },
547 { .id = 0x10de0006, .name = "MCP77/78 HDMI",
548 .patch = patch_nvhdmi_8ch_7x },
549 { .id = 0x10de0007, .name = "MCP79/7A HDMI",
550 .patch = patch_nvhdmi_8ch_7x },
551 { .id = 0x10de000a, .name = "GT220 HDMI",
552 .patch = patch_nvhdmi_8ch_89 },
553 { .id = 0x10de000b, .name = "GT21x HDMI",
554 .patch = patch_nvhdmi_8ch_89 },
555 { .id = 0x10de000c, .name = "MCP89 HDMI",
556 .patch = patch_nvhdmi_8ch_89 },
557 { .id = 0x10de000d, .name = "GT240 HDMI",
558 .patch = patch_nvhdmi_8ch_89 },
403 { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch }, 559 { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch },
404 { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch }, 560 { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch },
405 {} /* terminator */ 561 {} /* terminator */
@@ -410,11 +566,15 @@ MODULE_ALIAS("snd-hda-codec-id:10de0003");
410MODULE_ALIAS("snd-hda-codec-id:10de0005"); 566MODULE_ALIAS("snd-hda-codec-id:10de0005");
411MODULE_ALIAS("snd-hda-codec-id:10de0006"); 567MODULE_ALIAS("snd-hda-codec-id:10de0006");
412MODULE_ALIAS("snd-hda-codec-id:10de0007"); 568MODULE_ALIAS("snd-hda-codec-id:10de0007");
569MODULE_ALIAS("snd-hda-codec-id:10de000a");
570MODULE_ALIAS("snd-hda-codec-id:10de000b");
571MODULE_ALIAS("snd-hda-codec-id:10de000c");
572MODULE_ALIAS("snd-hda-codec-id:10de000d");
413MODULE_ALIAS("snd-hda-codec-id:10de0067"); 573MODULE_ALIAS("snd-hda-codec-id:10de0067");
414MODULE_ALIAS("snd-hda-codec-id:10de8001"); 574MODULE_ALIAS("snd-hda-codec-id:10de8001");
415 575
416MODULE_LICENSE("GPL"); 576MODULE_LICENSE("GPL");
417MODULE_DESCRIPTION("Nvidia HDMI HD-audio codec"); 577MODULE_DESCRIPTION("NVIDIA HDMI HD-audio codec");
418 578
419static struct hda_codec_preset_list nvhdmi_list = { 579static struct hda_codec_preset_list nvhdmi_list = {
420 .preset = snd_hda_preset_nvhdmi, 580 .preset = snd_hda_preset_nvhdmi,
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 70583719282b..886d8e46bb37 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -131,8 +131,10 @@ enum {
131enum { 131enum {
132 ALC269_BASIC, 132 ALC269_BASIC,
133 ALC269_QUANTA_FL1, 133 ALC269_QUANTA_FL1,
134 ALC269_ASUS_EEEPC_P703, 134 ALC269_AMIC,
135 ALC269_ASUS_EEEPC_P901, 135 ALC269_DMIC,
136 ALC269VB_AMIC,
137 ALC269VB_DMIC,
136 ALC269_FUJITSU, 138 ALC269_FUJITSU,
137 ALC269_LIFEBOOK, 139 ALC269_LIFEBOOK,
138 ALC269_AUTO, 140 ALC269_AUTO,
@@ -188,6 +190,8 @@ enum {
188 ALC663_ASUS_MODE4, 190 ALC663_ASUS_MODE4,
189 ALC663_ASUS_MODE5, 191 ALC663_ASUS_MODE5,
190 ALC663_ASUS_MODE6, 192 ALC663_ASUS_MODE6,
193 ALC663_ASUS_MODE7,
194 ALC663_ASUS_MODE8,
191 ALC272_DELL, 195 ALC272_DELL,
192 ALC272_DELL_ZM1, 196 ALC272_DELL_ZM1,
193 ALC272_SAMSUNG_NC10, 197 ALC272_SAMSUNG_NC10,
@@ -205,9 +209,12 @@ enum {
205 ALC882_ASUS_A7J, 209 ALC882_ASUS_A7J,
206 ALC882_ASUS_A7M, 210 ALC882_ASUS_A7M,
207 ALC885_MACPRO, 211 ALC885_MACPRO,
212 ALC885_MBA21,
208 ALC885_MBP3, 213 ALC885_MBP3,
209 ALC885_MB5, 214 ALC885_MB5,
215 ALC885_MACMINI3,
210 ALC885_IMAC24, 216 ALC885_IMAC24,
217 ALC885_IMAC91,
211 ALC883_3ST_2ch_DIG, 218 ALC883_3ST_2ch_DIG,
212 ALC883_3ST_6ch_DIG, 219 ALC883_3ST_6ch_DIG,
213 ALC883_3ST_6ch, 220 ALC883_3ST_6ch,
@@ -223,6 +230,7 @@ enum {
223 ALC888_ACER_ASPIRE_7730G, 230 ALC888_ACER_ASPIRE_7730G,
224 ALC883_MEDION, 231 ALC883_MEDION,
225 ALC883_MEDION_MD2, 232 ALC883_MEDION_MD2,
233 ALC883_MEDION_WIM2160,
226 ALC883_LAPTOP_EAPD, 234 ALC883_LAPTOP_EAPD,
227 ALC883_LENOVO_101E_2ch, 235 ALC883_LENOVO_101E_2ch,
228 ALC883_LENOVO_NB0763, 236 ALC883_LENOVO_NB0763,
@@ -334,6 +342,9 @@ struct alc_spec {
334 /* hooks */ 342 /* hooks */
335 void (*init_hook)(struct hda_codec *codec); 343 void (*init_hook)(struct hda_codec *codec);
336 void (*unsol_event)(struct hda_codec *codec, unsigned int res); 344 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
345#ifdef CONFIG_SND_HDA_POWER_SAVE
346 void (*power_hook)(struct hda_codec *codec);
347#endif
337 348
338 /* for pin sensing */ 349 /* for pin sensing */
339 unsigned int sense_updated: 1; 350 unsigned int sense_updated: 1;
@@ -385,6 +396,7 @@ struct alc_config_preset {
385 void (*init_hook)(struct hda_codec *); 396 void (*init_hook)(struct hda_codec *);
386#ifdef CONFIG_SND_HDA_POWER_SAVE 397#ifdef CONFIG_SND_HDA_POWER_SAVE
387 struct hda_amp_list *loopbacks; 398 struct hda_amp_list *loopbacks;
399 void (*power_hook)(struct hda_codec *codec);
388#endif 400#endif
389}; 401};
390 402
@@ -400,6 +412,8 @@ static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
400 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id); 412 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
401 if (mux_idx >= spec->num_mux_defs) 413 if (mux_idx >= spec->num_mux_defs)
402 mux_idx = 0; 414 mux_idx = 0;
415 if (!spec->input_mux[mux_idx].num_items && mux_idx > 0)
416 mux_idx = 0;
403 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo); 417 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
404} 418}
405 419
@@ -428,6 +442,8 @@ static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
428 442
429 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; 443 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
430 imux = &spec->input_mux[mux_idx]; 444 imux = &spec->input_mux[mux_idx];
445 if (!imux->num_items && mux_idx > 0)
446 imux = &spec->input_mux[0];
431 447
432 type = get_wcaps_type(get_wcaps(codec, nid)); 448 type = get_wcaps_type(get_wcaps(codec, nid));
433 if (type == AC_WID_AUD_MIX) { 449 if (type == AC_WID_AUD_MIX) {
@@ -626,6 +642,7 @@ static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
626 642
627#define ALC_PIN_MODE(xname, nid, dir) \ 643#define ALC_PIN_MODE(xname, nid, dir) \
628 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 644 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
645 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
629 .info = alc_pin_mode_info, \ 646 .info = alc_pin_mode_info, \
630 .get = alc_pin_mode_get, \ 647 .get = alc_pin_mode_get, \
631 .put = alc_pin_mode_put, \ 648 .put = alc_pin_mode_put, \
@@ -677,6 +694,7 @@ static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
677} 694}
678#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \ 695#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
679 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 696 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
697 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
680 .info = alc_gpio_data_info, \ 698 .info = alc_gpio_data_info, \
681 .get = alc_gpio_data_get, \ 699 .get = alc_gpio_data_get, \
682 .put = alc_gpio_data_put, \ 700 .put = alc_gpio_data_put, \
@@ -731,6 +749,7 @@ static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
731} 749}
732#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \ 750#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
733 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 751 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
752 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
734 .info = alc_spdif_ctrl_info, \ 753 .info = alc_spdif_ctrl_info, \
735 .get = alc_spdif_ctrl_get, \ 754 .get = alc_spdif_ctrl_get, \
736 .put = alc_spdif_ctrl_put, \ 755 .put = alc_spdif_ctrl_put, \
@@ -784,6 +803,7 @@ static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
784 803
785#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \ 804#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
786 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 805 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
806 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
787 .info = alc_eapd_ctrl_info, \ 807 .info = alc_eapd_ctrl_info, \
788 .get = alc_eapd_ctrl_get, \ 808 .get = alc_eapd_ctrl_get, \
789 .put = alc_eapd_ctrl_put, \ 809 .put = alc_eapd_ctrl_put, \
@@ -830,27 +850,6 @@ static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
830 spec->init_verbs[spec->num_init_verbs++] = verb; 850 spec->init_verbs[spec->num_init_verbs++] = verb;
831} 851}
832 852
833#ifdef CONFIG_PROC_FS
834/*
835 * hook for proc
836 */
837static void print_realtek_coef(struct snd_info_buffer *buffer,
838 struct hda_codec *codec, hda_nid_t nid)
839{
840 int coeff;
841
842 if (nid != 0x20)
843 return;
844 coeff = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
845 snd_iprintf(buffer, " Processing Coefficient: 0x%02x\n", coeff);
846 coeff = snd_hda_codec_read(codec, nid, 0,
847 AC_VERB_GET_COEF_INDEX, 0);
848 snd_iprintf(buffer, " Coefficient Index: 0x%02x\n", coeff);
849}
850#else
851#define print_realtek_coef NULL
852#endif
853
854/* 853/*
855 * set up from the preset table 854 * set up from the preset table
856 */ 855 */
@@ -897,6 +896,7 @@ static void setup_preset(struct hda_codec *codec,
897 spec->unsol_event = preset->unsol_event; 896 spec->unsol_event = preset->unsol_event;
898 spec->init_hook = preset->init_hook; 897 spec->init_hook = preset->init_hook;
899#ifdef CONFIG_SND_HDA_POWER_SAVE 898#ifdef CONFIG_SND_HDA_POWER_SAVE
899 spec->power_hook = preset->power_hook;
900 spec->loopback.amplist = preset->loopbacks; 900 spec->loopback.amplist = preset->loopbacks;
901#endif 901#endif
902 902
@@ -961,18 +961,12 @@ static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
961static void alc_automute_pin(struct hda_codec *codec) 961static void alc_automute_pin(struct hda_codec *codec)
962{ 962{
963 struct alc_spec *spec = codec->spec; 963 struct alc_spec *spec = codec->spec;
964 unsigned int present, pincap;
965 unsigned int nid = spec->autocfg.hp_pins[0]; 964 unsigned int nid = spec->autocfg.hp_pins[0];
966 int i; 965 int i;
967 966
968 if (!nid) 967 if (!nid)
969 return; 968 return;
970 pincap = snd_hda_query_pin_caps(codec, nid); 969 spec->jack_present = snd_hda_jack_detect(codec, nid);
971 if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */
972 snd_hda_codec_read(codec, nid, 0, AC_VERB_SET_PIN_SENSE, 0);
973 present = snd_hda_codec_read(codec, nid, 0,
974 AC_VERB_GET_PIN_SENSE, 0);
975 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
976 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) { 970 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
977 nid = spec->autocfg.speaker_pins[i]; 971 nid = spec->autocfg.speaker_pins[i];
978 if (!nid) 972 if (!nid)
@@ -1012,9 +1006,7 @@ static void alc_mic_automute(struct hda_codec *codec)
1012 1006
1013 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0]; 1007 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1014 1008
1015 present = snd_hda_codec_read(codec, spec->ext_mic.pin, 0, 1009 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1016 AC_VERB_GET_PIN_SENSE, 0);
1017 present &= AC_PINSENSE_PRESENCE;
1018 if (present) { 1010 if (present) {
1019 alive = &spec->ext_mic; 1011 alive = &spec->ext_mic;
1020 dead = &spec->int_mic; 1012 dead = &spec->int_mic;
@@ -1093,6 +1085,16 @@ static void alc889_coef_init(struct hda_codec *codec)
1093 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010); 1085 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
1094} 1086}
1095 1087
1088/* turn on/off EAPD control (only if available) */
1089static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
1090{
1091 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
1092 return;
1093 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
1094 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1095 on ? 2 : 0);
1096}
1097
1096static void alc_auto_init_amp(struct hda_codec *codec, int type) 1098static void alc_auto_init_amp(struct hda_codec *codec, int type)
1097{ 1099{
1098 unsigned int tmp; 1100 unsigned int tmp;
@@ -1110,25 +1112,22 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type)
1110 case ALC_INIT_DEFAULT: 1112 case ALC_INIT_DEFAULT:
1111 switch (codec->vendor_id) { 1113 switch (codec->vendor_id) {
1112 case 0x10ec0260: 1114 case 0x10ec0260:
1113 snd_hda_codec_write(codec, 0x0f, 0, 1115 set_eapd(codec, 0x0f, 1);
1114 AC_VERB_SET_EAPD_BTLENABLE, 2); 1116 set_eapd(codec, 0x10, 1);
1115 snd_hda_codec_write(codec, 0x10, 0,
1116 AC_VERB_SET_EAPD_BTLENABLE, 2);
1117 break; 1117 break;
1118 case 0x10ec0262: 1118 case 0x10ec0262:
1119 case 0x10ec0267: 1119 case 0x10ec0267:
1120 case 0x10ec0268: 1120 case 0x10ec0268:
1121 case 0x10ec0269: 1121 case 0x10ec0269:
1122 case 0x10ec0270:
1122 case 0x10ec0272: 1123 case 0x10ec0272:
1123 case 0x10ec0660: 1124 case 0x10ec0660:
1124 case 0x10ec0662: 1125 case 0x10ec0662:
1125 case 0x10ec0663: 1126 case 0x10ec0663:
1126 case 0x10ec0862: 1127 case 0x10ec0862:
1127 case 0x10ec0889: 1128 case 0x10ec0889:
1128 snd_hda_codec_write(codec, 0x14, 0, 1129 set_eapd(codec, 0x14, 1);
1129 AC_VERB_SET_EAPD_BTLENABLE, 2); 1130 set_eapd(codec, 0x15, 1);
1130 snd_hda_codec_write(codec, 0x15, 0,
1131 AC_VERB_SET_EAPD_BTLENABLE, 2);
1132 break; 1131 break;
1133 } 1132 }
1134 switch (codec->vendor_id) { 1133 switch (codec->vendor_id) {
@@ -1155,6 +1154,7 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type)
1155 case 0x10ec0888: 1154 case 0x10ec0888:
1156 alc888_coef_init(codec); 1155 alc888_coef_init(codec);
1157 break; 1156 break;
1157#if 0 /* XXX: This may cause the silent output on speaker on some machines */
1158 case 0x10ec0267: 1158 case 0x10ec0267:
1159 case 0x10ec0268: 1159 case 0x10ec0268:
1160 snd_hda_codec_write(codec, 0x20, 0, 1160 snd_hda_codec_write(codec, 0x20, 0,
@@ -1167,6 +1167,7 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type)
1167 AC_VERB_SET_PROC_COEF, 1167 AC_VERB_SET_PROC_COEF,
1168 tmp | 0x3000); 1168 tmp | 0x3000);
1169 break; 1169 break;
1170#endif /* XXX */
1170 } 1171 }
1171 break; 1172 break;
1172 } 1173 }
@@ -1230,6 +1231,8 @@ static void alc_init_auto_mic(struct hda_codec *codec)
1230 return; /* invalid entry */ 1231 return; /* invalid entry */
1231 } 1232 }
1232 } 1233 }
1234 if (!ext || !fixed)
1235 return;
1233 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP)) 1236 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP))
1234 return; /* no unsol support */ 1237 return; /* no unsol support */
1235 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n", 1238 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n",
@@ -1256,7 +1259,7 @@ static void alc_init_auto_mic(struct hda_codec *codec)
1256 */ 1259 */
1257static int alc_subsystem_id(struct hda_codec *codec, 1260static int alc_subsystem_id(struct hda_codec *codec,
1258 hda_nid_t porta, hda_nid_t porte, 1261 hda_nid_t porta, hda_nid_t porte,
1259 hda_nid_t portd) 1262 hda_nid_t portd, hda_nid_t porti)
1260{ 1263{
1261 unsigned int ass, tmp, i; 1264 unsigned int ass, tmp, i;
1262 unsigned nid; 1265 unsigned nid;
@@ -1282,7 +1285,7 @@ static int alc_subsystem_id(struct hda_codec *codec,
1282 snd_printd("realtek: No valid SSID, " 1285 snd_printd("realtek: No valid SSID, "
1283 "checking pincfg 0x%08x for NID 0x%x\n", 1286 "checking pincfg 0x%08x for NID 0x%x\n",
1284 ass, nid); 1287 ass, nid);
1285 if (!(ass & 1) && !(ass & 0x100000)) 1288 if (!(ass & 1))
1286 return 0; 1289 return 0;
1287 if ((ass >> 30) != 1) /* no physical connection */ 1290 if ((ass >> 30) != 1) /* no physical connection */
1288 return 0; 1291 return 0;
@@ -1342,6 +1345,8 @@ do_sku:
1342 nid = porte; 1345 nid = porte;
1343 else if (tmp == 2) 1346 else if (tmp == 2)
1344 nid = portd; 1347 nid = portd;
1348 else if (tmp == 3)
1349 nid = porti;
1345 else 1350 else
1346 return 1; 1351 return 1;
1347 for (i = 0; i < spec->autocfg.line_outs; i++) 1352 for (i = 0; i < spec->autocfg.line_outs; i++)
@@ -1356,9 +1361,10 @@ do_sku:
1356} 1361}
1357 1362
1358static void alc_ssid_check(struct hda_codec *codec, 1363static void alc_ssid_check(struct hda_codec *codec,
1359 hda_nid_t porta, hda_nid_t porte, hda_nid_t portd) 1364 hda_nid_t porta, hda_nid_t porte,
1365 hda_nid_t portd, hda_nid_t porti)
1360{ 1366{
1361 if (!alc_subsystem_id(codec, porta, porte, portd)) { 1367 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) {
1362 struct alc_spec *spec = codec->spec; 1368 struct alc_spec *spec = codec->spec;
1363 snd_printd("realtek: " 1369 snd_printd("realtek: "
1364 "Enable default setup for auto mode as fallback\n"); 1370 "Enable default setup for auto mode as fallback\n");
@@ -1384,22 +1390,42 @@ struct alc_fixup {
1384 1390
1385static void alc_pick_fixup(struct hda_codec *codec, 1391static void alc_pick_fixup(struct hda_codec *codec,
1386 const struct snd_pci_quirk *quirk, 1392 const struct snd_pci_quirk *quirk,
1387 const struct alc_fixup *fix) 1393 const struct alc_fixup *fix,
1394 int pre_init)
1388{ 1395{
1389 const struct alc_pincfg *cfg; 1396 const struct alc_pincfg *cfg;
1390 1397
1391 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk); 1398 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1392 if (!quirk) 1399 if (!quirk)
1393 return; 1400 return;
1394
1395 fix += quirk->value; 1401 fix += quirk->value;
1396 cfg = fix->pins; 1402 cfg = fix->pins;
1397 if (cfg) { 1403 if (pre_init && cfg) {
1404#ifdef CONFIG_SND_DEBUG_VERBOSE
1405 snd_printdd(KERN_INFO "hda_codec: %s: Apply pincfg for %s\n",
1406 codec->chip_name, quirk->name);
1407#endif
1398 for (; cfg->nid; cfg++) 1408 for (; cfg->nid; cfg++)
1399 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val); 1409 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
1400 } 1410 }
1401 if (fix->verbs) 1411 if (!pre_init && fix->verbs) {
1412#ifdef CONFIG_SND_DEBUG_VERBOSE
1413 snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-verbs for %s\n",
1414 codec->chip_name, quirk->name);
1415#endif
1402 add_verb(codec->spec, fix->verbs); 1416 add_verb(codec->spec, fix->verbs);
1417 }
1418}
1419
1420static int alc_read_coef_idx(struct hda_codec *codec,
1421 unsigned int coef_idx)
1422{
1423 unsigned int val;
1424 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
1425 coef_idx);
1426 val = snd_hda_codec_read(codec, 0x20, 0,
1427 AC_VERB_GET_PROC_COEF, 0);
1428 return val;
1403} 1429}
1404 1430
1405/* 1431/*
@@ -1513,7 +1539,7 @@ static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1513static void alc_automute_amp(struct hda_codec *codec) 1539static void alc_automute_amp(struct hda_codec *codec)
1514{ 1540{
1515 struct alc_spec *spec = codec->spec; 1541 struct alc_spec *spec = codec->spec;
1516 unsigned int val, mute, pincap; 1542 unsigned int mute;
1517 hda_nid_t nid; 1543 hda_nid_t nid;
1518 int i; 1544 int i;
1519 1545
@@ -1522,13 +1548,7 @@ static void alc_automute_amp(struct hda_codec *codec)
1522 nid = spec->autocfg.hp_pins[i]; 1548 nid = spec->autocfg.hp_pins[i];
1523 if (!nid) 1549 if (!nid)
1524 break; 1550 break;
1525 pincap = snd_hda_query_pin_caps(codec, nid); 1551 if (snd_hda_jack_detect(codec, nid)) {
1526 if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */
1527 snd_hda_codec_read(codec, nid, 0,
1528 AC_VERB_SET_PIN_SENSE, 0);
1529 val = snd_hda_codec_read(codec, nid, 0,
1530 AC_VERB_GET_PIN_SENSE, 0);
1531 if (val & AC_PINSENSE_PRESENCE) {
1532 spec->jack_present = 1; 1552 spec->jack_present = 1;
1533 break; 1553 break;
1534 } 1554 }
@@ -1611,6 +1631,11 @@ static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1611 */ 1631 */
1612 1632
1613static struct hda_verb alc888_acer_aspire_6530g_verbs[] = { 1633static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
1634/* Route to built-in subwoofer as well as speakers */
1635 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1636 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1637 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1638 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1614/* Bias voltage on for external mic port */ 1639/* Bias voltage on for external mic port */
1615 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80}, 1640 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
1616/* Front Mic: set to PIN_IN (empty by default) */ 1641/* Front Mic: set to PIN_IN (empty by default) */
@@ -1622,10 +1647,12 @@ static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
1622/* Enable speaker output */ 1647/* Enable speaker output */
1623 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1648 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1624 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1649 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1650 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
1625/* Enable headphone output */ 1651/* Enable headphone output */
1626 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP}, 1652 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
1627 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1653 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1628 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 1654 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1655 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
1629 { } 1656 { }
1630}; 1657};
1631 1658
@@ -1665,9 +1692,6 @@ static struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
1665/* some bit here disables the other DACs. Init=0x4900 */ 1692/* some bit here disables the other DACs. Init=0x4900 */
1666 {0x20, AC_VERB_SET_COEF_INDEX, 0x08}, 1693 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
1667 {0x20, AC_VERB_SET_PROC_COEF, 0x0000}, 1694 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
1668/* Enable amplifiers */
1669 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
1670 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
1671/* DMIC fix 1695/* DMIC fix
1672 * This laptop has a stereo digital microphone. The mics are only 1cm apart 1696 * This laptop has a stereo digital microphone. The mics are only 1cm apart
1673 * which makes the stereo useless. However, either the mic or the ALC889 1697 * which makes the stereo useless. However, either the mic or the ALC889
@@ -1780,12 +1804,33 @@ static struct snd_kcontrol_new alc888_base_mixer[] = {
1780 { } /* end */ 1804 { } /* end */
1781}; 1805};
1782 1806
1807static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
1808 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1809 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1810 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1811 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1812 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1813 HDA_OUTPUT),
1814 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1815 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1816 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1817 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1818 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1819 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1820 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1821 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1822 { } /* end */
1823};
1824
1825
1783static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec) 1826static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
1784{ 1827{
1785 struct alc_spec *spec = codec->spec; 1828 struct alc_spec *spec = codec->spec;
1786 1829
1787 spec->autocfg.hp_pins[0] = 0x15; 1830 spec->autocfg.hp_pins[0] = 0x15;
1788 spec->autocfg.speaker_pins[0] = 0x14; 1831 spec->autocfg.speaker_pins[0] = 0x14;
1832 spec->autocfg.speaker_pins[1] = 0x16;
1833 spec->autocfg.speaker_pins[2] = 0x17;
1789} 1834}
1790 1835
1791static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec) 1836static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
@@ -2401,6 +2446,8 @@ static const char *alc_slave_sws[] = {
2401 "Speaker Playback Switch", 2446 "Speaker Playback Switch",
2402 "Mono Playback Switch", 2447 "Mono Playback Switch",
2403 "IEC958 Playback Switch", 2448 "IEC958 Playback Switch",
2449 "Line-Out Playback Switch",
2450 "PCM Playback Switch",
2404 NULL, 2451 NULL,
2405}; 2452};
2406 2453
@@ -2408,20 +2455,34 @@ static const char *alc_slave_sws[] = {
2408 * build control elements 2455 * build control elements
2409 */ 2456 */
2410 2457
2458#define NID_MAPPING (-1)
2459
2460#define SUBDEV_SPEAKER_ (0 << 6)
2461#define SUBDEV_HP_ (1 << 6)
2462#define SUBDEV_LINE_ (2 << 6)
2463#define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f))
2464#define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f))
2465#define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f))
2466
2411static void alc_free_kctls(struct hda_codec *codec); 2467static void alc_free_kctls(struct hda_codec *codec);
2412 2468
2469#ifdef CONFIG_SND_HDA_INPUT_BEEP
2413/* additional beep mixers; the actual parameters are overwritten at build */ 2470/* additional beep mixers; the actual parameters are overwritten at build */
2414static struct snd_kcontrol_new alc_beep_mixer[] = { 2471static struct snd_kcontrol_new alc_beep_mixer[] = {
2415 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT), 2472 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
2416 HDA_CODEC_MUTE("Beep Playback Switch", 0, 0, HDA_INPUT), 2473 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
2417 { } /* end */ 2474 { } /* end */
2418}; 2475};
2476#endif
2419 2477
2420static int alc_build_controls(struct hda_codec *codec) 2478static int alc_build_controls(struct hda_codec *codec)
2421{ 2479{
2422 struct alc_spec *spec = codec->spec; 2480 struct alc_spec *spec = codec->spec;
2423 int err; 2481 struct snd_kcontrol *kctl;
2424 int i; 2482 struct snd_kcontrol_new *knew;
2483 int i, j, err;
2484 unsigned int u;
2485 hda_nid_t nid;
2425 2486
2426 for (i = 0; i < spec->num_mixers; i++) { 2487 for (i = 0; i < spec->num_mixers; i++) {
2427 err = snd_hda_add_new_ctls(codec, spec->mixers[i]); 2488 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
@@ -2452,6 +2513,7 @@ static int alc_build_controls(struct hda_codec *codec)
2452 return err; 2513 return err;
2453 } 2514 }
2454 2515
2516#ifdef CONFIG_SND_HDA_INPUT_BEEP
2455 /* create beep controls if needed */ 2517 /* create beep controls if needed */
2456 if (spec->beep_amp) { 2518 if (spec->beep_amp) {
2457 struct snd_kcontrol_new *knew; 2519 struct snd_kcontrol_new *knew;
@@ -2461,11 +2523,12 @@ static int alc_build_controls(struct hda_codec *codec)
2461 if (!kctl) 2523 if (!kctl)
2462 return -ENOMEM; 2524 return -ENOMEM;
2463 kctl->private_value = spec->beep_amp; 2525 kctl->private_value = spec->beep_amp;
2464 err = snd_hda_ctl_add(codec, kctl); 2526 err = snd_hda_ctl_add(codec, 0, kctl);
2465 if (err < 0) 2527 if (err < 0)
2466 return err; 2528 return err;
2467 } 2529 }
2468 } 2530 }
2531#endif
2469 2532
2470 /* if we have no master control, let's create it */ 2533 /* if we have no master control, let's create it */
2471 if (!spec->no_analog && 2534 if (!spec->no_analog &&
@@ -2486,7 +2549,77 @@ static int alc_build_controls(struct hda_codec *codec)
2486 return err; 2549 return err;
2487 } 2550 }
2488 2551
2552 /* assign Capture Source enums to NID */
2553 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
2554 if (!kctl)
2555 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
2556 for (i = 0; kctl && i < kctl->count; i++) {
2557 hda_nid_t *nids = spec->capsrc_nids;
2558 if (!nids)
2559 nids = spec->adc_nids;
2560 err = snd_hda_add_nid(codec, kctl, i, nids[i]);
2561 if (err < 0)
2562 return err;
2563 }
2564 if (spec->cap_mixer) {
2565 const char *kname = kctl ? kctl->id.name : NULL;
2566 for (knew = spec->cap_mixer; knew->name; knew++) {
2567 if (kname && strcmp(knew->name, kname) == 0)
2568 continue;
2569 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
2570 for (i = 0; kctl && i < kctl->count; i++) {
2571 err = snd_hda_add_nid(codec, kctl, i,
2572 spec->adc_nids[i]);
2573 if (err < 0)
2574 return err;
2575 }
2576 }
2577 }
2578
2579 /* other nid->control mapping */
2580 for (i = 0; i < spec->num_mixers; i++) {
2581 for (knew = spec->mixers[i]; knew->name; knew++) {
2582 if (knew->iface != NID_MAPPING)
2583 continue;
2584 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
2585 if (kctl == NULL)
2586 continue;
2587 u = knew->subdevice;
2588 for (j = 0; j < 4; j++, u >>= 8) {
2589 nid = u & 0x3f;
2590 if (nid == 0)
2591 continue;
2592 switch (u & 0xc0) {
2593 case SUBDEV_SPEAKER_:
2594 nid = spec->autocfg.speaker_pins[nid];
2595 break;
2596 case SUBDEV_LINE_:
2597 nid = spec->autocfg.line_out_pins[nid];
2598 break;
2599 case SUBDEV_HP_:
2600 nid = spec->autocfg.hp_pins[nid];
2601 break;
2602 default:
2603 continue;
2604 }
2605 err = snd_hda_add_nid(codec, kctl, 0, nid);
2606 if (err < 0)
2607 return err;
2608 }
2609 u = knew->private_value;
2610 for (j = 0; j < 4; j++, u >>= 8) {
2611 nid = u & 0xff;
2612 if (nid == 0)
2613 continue;
2614 err = snd_hda_add_nid(codec, kctl, 0, nid);
2615 if (err < 0)
2616 return err;
2617 }
2618 }
2619 }
2620
2489 alc_free_kctls(codec); /* no longer needed */ 2621 alc_free_kctls(codec); /* no longer needed */
2622
2490 return 0; 2623 return 0;
2491} 2624}
2492 2625
@@ -2779,8 +2912,7 @@ static void alc880_uniwill_mic_automute(struct hda_codec *codec)
2779 unsigned int present; 2912 unsigned int present;
2780 unsigned char bits; 2913 unsigned char bits;
2781 2914
2782 present = snd_hda_codec_read(codec, 0x18, 0, 2915 present = snd_hda_jack_detect(codec, 0x18);
2783 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2784 bits = present ? HDA_AMP_MUTE : 0; 2916 bits = present ? HDA_AMP_MUTE : 0;
2785 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits); 2917 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
2786} 2918}
@@ -3480,7 +3612,7 @@ static int alc_build_pcms(struct hda_codec *codec)
3480 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog), 3612 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
3481 "%s Analog", codec->chip_name); 3613 "%s Analog", codec->chip_name);
3482 info->name = spec->stream_name_analog; 3614 info->name = spec->stream_name_analog;
3483 3615
3484 if (spec->stream_analog_playback) { 3616 if (spec->stream_analog_playback) {
3485 if (snd_BUG_ON(!spec->multiout.dac_nids)) 3617 if (snd_BUG_ON(!spec->multiout.dac_nids))
3486 return -EINVAL; 3618 return -EINVAL;
@@ -3570,6 +3702,11 @@ static int alc_build_pcms(struct hda_codec *codec)
3570 return 0; 3702 return 0;
3571} 3703}
3572 3704
3705static inline void alc_shutup(struct hda_codec *codec)
3706{
3707 snd_hda_shutup_pins(codec);
3708}
3709
3573static void alc_free_kctls(struct hda_codec *codec) 3710static void alc_free_kctls(struct hda_codec *codec)
3574{ 3711{
3575 struct alc_spec *spec = codec->spec; 3712 struct alc_spec *spec = codec->spec;
@@ -3590,11 +3727,48 @@ static void alc_free(struct hda_codec *codec)
3590 if (!spec) 3727 if (!spec)
3591 return; 3728 return;
3592 3729
3730 alc_shutup(codec);
3593 alc_free_kctls(codec); 3731 alc_free_kctls(codec);
3594 kfree(spec); 3732 kfree(spec);
3595 snd_hda_detach_beep_device(codec); 3733 snd_hda_detach_beep_device(codec);
3596} 3734}
3597 3735
3736#ifdef CONFIG_SND_HDA_POWER_SAVE
3737static void alc_power_eapd(struct hda_codec *codec)
3738{
3739 /* We currently only handle front, HP */
3740 switch (codec->vendor_id) {
3741 case 0x10ec0260:
3742 set_eapd(codec, 0x0f, 0);
3743 set_eapd(codec, 0x10, 0);
3744 break;
3745 case 0x10ec0262:
3746 case 0x10ec0267:
3747 case 0x10ec0268:
3748 case 0x10ec0269:
3749 case 0x10ec0270:
3750 case 0x10ec0272:
3751 case 0x10ec0660:
3752 case 0x10ec0662:
3753 case 0x10ec0663:
3754 case 0x10ec0862:
3755 case 0x10ec0889:
3756 set_eapd(codec, 0x14, 0);
3757 set_eapd(codec, 0x15, 0);
3758 break;
3759 }
3760}
3761
3762static int alc_suspend(struct hda_codec *codec, pm_message_t state)
3763{
3764 struct alc_spec *spec = codec->spec;
3765 alc_shutup(codec);
3766 if (spec && spec->power_hook)
3767 spec->power_hook(codec);
3768 return 0;
3769}
3770#endif
3771
3598#ifdef SND_HDA_NEEDS_RESUME 3772#ifdef SND_HDA_NEEDS_RESUME
3599static int alc_resume(struct hda_codec *codec) 3773static int alc_resume(struct hda_codec *codec)
3600{ 3774{
@@ -3617,8 +3791,10 @@ static struct hda_codec_ops alc_patch_ops = {
3617 .resume = alc_resume, 3791 .resume = alc_resume,
3618#endif 3792#endif
3619#ifdef CONFIG_SND_HDA_POWER_SAVE 3793#ifdef CONFIG_SND_HDA_POWER_SAVE
3794 .suspend = alc_suspend,
3620 .check_power_status = alc_check_power_status, 3795 .check_power_status = alc_check_power_status,
3621#endif 3796#endif
3797 .reboot_notify = alc_shutup,
3622}; 3798};
3623 3799
3624 3800
@@ -3775,6 +3951,7 @@ static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3775#define PIN_CTL_TEST(xname,nid) { \ 3951#define PIN_CTL_TEST(xname,nid) { \
3776 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 3952 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3777 .name = xname, \ 3953 .name = xname, \
3954 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
3778 .info = alc_test_pin_ctl_info, \ 3955 .info = alc_test_pin_ctl_info, \
3779 .get = alc_test_pin_ctl_get, \ 3956 .get = alc_test_pin_ctl_get, \
3780 .put = alc_test_pin_ctl_put, \ 3957 .put = alc_test_pin_ctl_put, \
@@ -3784,6 +3961,7 @@ static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3784#define PIN_SRC_TEST(xname,nid) { \ 3961#define PIN_SRC_TEST(xname,nid) { \
3785 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 3962 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3786 .name = xname, \ 3963 .name = xname, \
3964 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
3787 .info = alc_test_pin_src_info, \ 3965 .info = alc_test_pin_src_info, \
3788 .get = alc_test_pin_src_get, \ 3966 .get = alc_test_pin_src_get, \
3789 .put = alc_test_pin_src_put, \ 3967 .put = alc_test_pin_src_put, \
@@ -3965,7 +4143,7 @@ static struct snd_pci_quirk alc880_cfg_tbl[] = {
3965 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG), 4143 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
3966 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734), 4144 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
3967 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU), 4145 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3968 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL), 4146 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
3969 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU), 4147 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
3970 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW), 4148 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
3971 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG), 4149 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
@@ -4322,10 +4500,26 @@ static int add_control(struct alc_spec *spec, int type, const char *name,
4322 knew->name = kstrdup(name, GFP_KERNEL); 4500 knew->name = kstrdup(name, GFP_KERNEL);
4323 if (!knew->name) 4501 if (!knew->name)
4324 return -ENOMEM; 4502 return -ENOMEM;
4503 if (get_amp_nid_(val))
4504 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
4325 knew->private_value = val; 4505 knew->private_value = val;
4326 return 0; 4506 return 0;
4327} 4507}
4328 4508
4509static int add_control_with_pfx(struct alc_spec *spec, int type,
4510 const char *pfx, const char *dir,
4511 const char *sfx, unsigned long val)
4512{
4513 char name[32];
4514 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
4515 return add_control(spec, type, name, val);
4516}
4517
4518#define add_pb_vol_ctrl(spec, type, pfx, val) \
4519 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", val)
4520#define add_pb_sw_ctrl(spec, type, pfx, val) \
4521 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", val)
4522
4329#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17) 4523#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
4330#define alc880_fixed_pin_idx(nid) ((nid) - 0x14) 4524#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
4331#define alc880_is_multi_pin(nid) ((nid) >= 0x18) 4525#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
@@ -4379,7 +4573,6 @@ static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
4379static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec, 4573static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
4380 const struct auto_pin_cfg *cfg) 4574 const struct auto_pin_cfg *cfg)
4381{ 4575{
4382 char name[32];
4383 static const char *chname[4] = { 4576 static const char *chname[4] = {
4384 "Front", "Surround", NULL /*CLFE*/, "Side" 4577 "Front", "Surround", NULL /*CLFE*/, "Side"
4385 }; 4578 };
@@ -4392,26 +4585,26 @@ static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
4392 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i])); 4585 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
4393 if (i == 2) { 4586 if (i == 2) {
4394 /* Center/LFE */ 4587 /* Center/LFE */
4395 err = add_control(spec, ALC_CTL_WIDGET_VOL, 4588 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
4396 "Center Playback Volume", 4589 "Center",
4397 HDA_COMPOSE_AMP_VAL(nid, 1, 0, 4590 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
4398 HDA_OUTPUT)); 4591 HDA_OUTPUT));
4399 if (err < 0) 4592 if (err < 0)
4400 return err; 4593 return err;
4401 err = add_control(spec, ALC_CTL_WIDGET_VOL, 4594 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
4402 "LFE Playback Volume", 4595 "LFE",
4403 HDA_COMPOSE_AMP_VAL(nid, 2, 0, 4596 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
4404 HDA_OUTPUT)); 4597 HDA_OUTPUT));
4405 if (err < 0) 4598 if (err < 0)
4406 return err; 4599 return err;
4407 err = add_control(spec, ALC_CTL_BIND_MUTE, 4600 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
4408 "Center Playback Switch", 4601 "Center",
4409 HDA_COMPOSE_AMP_VAL(nid, 1, 2, 4602 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
4410 HDA_INPUT)); 4603 HDA_INPUT));
4411 if (err < 0) 4604 if (err < 0)
4412 return err; 4605 return err;
4413 err = add_control(spec, ALC_CTL_BIND_MUTE, 4606 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
4414 "LFE Playback Switch", 4607 "LFE",
4415 HDA_COMPOSE_AMP_VAL(nid, 2, 2, 4608 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
4416 HDA_INPUT)); 4609 HDA_INPUT));
4417 if (err < 0) 4610 if (err < 0)
@@ -4423,14 +4616,12 @@ static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
4423 pfx = "Speaker"; 4616 pfx = "Speaker";
4424 else 4617 else
4425 pfx = chname[i]; 4618 pfx = chname[i];
4426 sprintf(name, "%s Playback Volume", pfx); 4619 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
4427 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4428 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 4620 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
4429 HDA_OUTPUT)); 4621 HDA_OUTPUT));
4430 if (err < 0) 4622 if (err < 0)
4431 return err; 4623 return err;
4432 sprintf(name, "%s Playback Switch", pfx); 4624 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
4433 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
4434 HDA_COMPOSE_AMP_VAL(nid, 3, 2, 4625 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
4435 HDA_INPUT)); 4626 HDA_INPUT));
4436 if (err < 0) 4627 if (err < 0)
@@ -4446,7 +4637,6 @@ static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
4446{ 4637{
4447 hda_nid_t nid; 4638 hda_nid_t nid;
4448 int err; 4639 int err;
4449 char name[32];
4450 4640
4451 if (!pin) 4641 if (!pin)
4452 return 0; 4642 return 0;
@@ -4460,21 +4650,18 @@ static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
4460 spec->multiout.extra_out_nid[0] = nid; 4650 spec->multiout.extra_out_nid[0] = nid;
4461 /* control HP volume/switch on the output mixer amp */ 4651 /* control HP volume/switch on the output mixer amp */
4462 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin)); 4652 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
4463 sprintf(name, "%s Playback Volume", pfx); 4653 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
4464 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4465 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); 4654 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
4466 if (err < 0) 4655 if (err < 0)
4467 return err; 4656 return err;
4468 sprintf(name, "%s Playback Switch", pfx); 4657 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
4469 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
4470 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT)); 4658 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
4471 if (err < 0) 4659 if (err < 0)
4472 return err; 4660 return err;
4473 } else if (alc880_is_multi_pin(pin)) { 4661 } else if (alc880_is_multi_pin(pin)) {
4474 /* set manual connection */ 4662 /* set manual connection */
4475 /* we have only a switch on HP-out PIN */ 4663 /* we have only a switch on HP-out PIN */
4476 sprintf(name, "%s Playback Switch", pfx); 4664 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
4477 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
4478 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 4665 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4479 if (err < 0) 4666 if (err < 0)
4480 return err; 4667 return err;
@@ -4487,16 +4674,13 @@ static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
4487 const char *ctlname, 4674 const char *ctlname,
4488 int idx, hda_nid_t mix_nid) 4675 int idx, hda_nid_t mix_nid)
4489{ 4676{
4490 char name[32];
4491 int err; 4677 int err;
4492 4678
4493 sprintf(name, "%s Playback Volume", ctlname); 4679 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
4494 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4495 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); 4680 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4496 if (err < 0) 4681 if (err < 0)
4497 return err; 4682 return err;
4498 sprintf(name, "%s Playback Switch", ctlname); 4683 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
4499 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
4500 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); 4684 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4501 if (err < 0) 4685 if (err < 0)
4502 return err; 4686 return err;
@@ -4634,6 +4818,25 @@ static void alc880_auto_init_analog_input(struct hda_codec *codec)
4634 } 4818 }
4635} 4819}
4636 4820
4821static void alc880_auto_init_input_src(struct hda_codec *codec)
4822{
4823 struct alc_spec *spec = codec->spec;
4824 int c;
4825
4826 for (c = 0; c < spec->num_adc_nids; c++) {
4827 unsigned int mux_idx;
4828 const struct hda_input_mux *imux;
4829 mux_idx = c >= spec->num_mux_defs ? 0 : c;
4830 imux = &spec->input_mux[mux_idx];
4831 if (!imux->num_items && mux_idx > 0)
4832 imux = &spec->input_mux[0];
4833 if (imux)
4834 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
4835 AC_VERB_SET_CONNECT_SEL,
4836 imux->items[0].index);
4837 }
4838}
4839
4637/* parse the BIOS configuration and set up the alc_spec */ 4840/* parse the BIOS configuration and set up the alc_spec */
4638/* return 1 if successful, 0 if the proper config is not found, 4841/* return 1 if successful, 0 if the proper config is not found,
4639 * or a negative error code 4842 * or a negative error code
@@ -4700,7 +4903,7 @@ static int alc880_parse_auto_config(struct hda_codec *codec)
4700 spec->num_mux_defs = 1; 4903 spec->num_mux_defs = 1;
4701 spec->input_mux = &spec->private_imux[0]; 4904 spec->input_mux = &spec->private_imux[0];
4702 4905
4703 alc_ssid_check(codec, 0x15, 0x1b, 0x14); 4906 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4704 4907
4705 return 1; 4908 return 1;
4706} 4909}
@@ -4712,6 +4915,7 @@ static void alc880_auto_init(struct hda_codec *codec)
4712 alc880_auto_init_multi_out(codec); 4915 alc880_auto_init_multi_out(codec);
4713 alc880_auto_init_extra_out(codec); 4916 alc880_auto_init_extra_out(codec);
4714 alc880_auto_init_analog_input(codec); 4917 alc880_auto_init_analog_input(codec);
4918 alc880_auto_init_input_src(codec);
4715 if (spec->unsol_event) 4919 if (spec->unsol_event)
4716 alc_inithook(codec); 4920 alc_inithook(codec);
4717} 4921}
@@ -4749,6 +4953,49 @@ static void fixup_automic_adc(struct hda_codec *codec)
4749 spec->auto_mic = 0; /* disable auto-mic to be sure */ 4953 spec->auto_mic = 0; /* disable auto-mic to be sure */
4750} 4954}
4751 4955
4956/* choose the ADC/MUX containing the input pin and initialize the setup */
4957static void fixup_single_adc(struct hda_codec *codec)
4958{
4959 struct alc_spec *spec = codec->spec;
4960 hda_nid_t pin = 0;
4961 int i;
4962
4963 /* search for the input pin; there must be only one */
4964 for (i = 0; i < AUTO_PIN_LAST; i++) {
4965 if (spec->autocfg.input_pins[i]) {
4966 pin = spec->autocfg.input_pins[i];
4967 break;
4968 }
4969 }
4970 if (!pin)
4971 return;
4972
4973 /* set the default connection to that pin */
4974 for (i = 0; i < spec->num_adc_nids; i++) {
4975 hda_nid_t cap = spec->capsrc_nids ?
4976 spec->capsrc_nids[i] : spec->adc_nids[i];
4977 int idx;
4978
4979 idx = get_connection_index(codec, cap, pin);
4980 if (idx < 0)
4981 continue;
4982 /* use only this ADC */
4983 if (spec->capsrc_nids)
4984 spec->capsrc_nids += i;
4985 spec->adc_nids += i;
4986 spec->num_adc_nids = 1;
4987 /* select or unmute this route */
4988 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
4989 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
4990 HDA_AMP_MUTE, 0);
4991 } else {
4992 snd_hda_codec_write_cache(codec, cap, 0,
4993 AC_VERB_SET_CONNECT_SEL, idx);
4994 }
4995 return;
4996 }
4997}
4998
4752static void set_capture_mixer(struct hda_codec *codec) 4999static void set_capture_mixer(struct hda_codec *codec)
4753{ 5000{
4754 struct alc_spec *spec = codec->spec; 5001 struct alc_spec *spec = codec->spec;
@@ -4761,20 +5008,89 @@ static void set_capture_mixer(struct hda_codec *codec)
4761 alc_capture_mixer3 }, 5008 alc_capture_mixer3 },
4762 }; 5009 };
4763 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) { 5010 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
4764 int mux; 5011 int mux = 0;
4765 if (spec->auto_mic) { 5012 if (spec->auto_mic)
4766 mux = 0;
4767 fixup_automic_adc(codec); 5013 fixup_automic_adc(codec);
4768 } else if (spec->input_mux && spec->input_mux->num_items > 1) 5014 else if (spec->input_mux) {
4769 mux = 1; 5015 if (spec->input_mux->num_items > 1)
4770 else 5016 mux = 1;
4771 mux = 0; 5017 else if (spec->input_mux->num_items == 1)
5018 fixup_single_adc(codec);
5019 }
4772 spec->cap_mixer = caps[mux][spec->num_adc_nids - 1]; 5020 spec->cap_mixer = caps[mux][spec->num_adc_nids - 1];
4773 } 5021 }
4774} 5022}
4775 5023
5024/* fill adc_nids (and capsrc_nids) containing all active input pins */
5025static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids,
5026 int num_nids)
5027{
5028 struct alc_spec *spec = codec->spec;
5029 int n;
5030 hda_nid_t fallback_adc = 0, fallback_cap = 0;
5031
5032 for (n = 0; n < num_nids; n++) {
5033 hda_nid_t adc, cap;
5034 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
5035 int nconns, i, j;
5036
5037 adc = nids[n];
5038 if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN)
5039 continue;
5040 cap = adc;
5041 nconns = snd_hda_get_connections(codec, cap, conn,
5042 ARRAY_SIZE(conn));
5043 if (nconns == 1) {
5044 cap = conn[0];
5045 nconns = snd_hda_get_connections(codec, cap, conn,
5046 ARRAY_SIZE(conn));
5047 }
5048 if (nconns <= 0)
5049 continue;
5050 if (!fallback_adc) {
5051 fallback_adc = adc;
5052 fallback_cap = cap;
5053 }
5054 for (i = 0; i < AUTO_PIN_LAST; i++) {
5055 hda_nid_t nid = spec->autocfg.input_pins[i];
5056 if (!nid)
5057 continue;
5058 for (j = 0; j < nconns; j++) {
5059 if (conn[j] == nid)
5060 break;
5061 }
5062 if (j >= nconns)
5063 break;
5064 }
5065 if (i >= AUTO_PIN_LAST) {
5066 int num_adcs = spec->num_adc_nids;
5067 spec->private_adc_nids[num_adcs] = adc;
5068 spec->private_capsrc_nids[num_adcs] = cap;
5069 spec->num_adc_nids++;
5070 spec->adc_nids = spec->private_adc_nids;
5071 if (adc != cap)
5072 spec->capsrc_nids = spec->private_capsrc_nids;
5073 }
5074 }
5075 if (!spec->num_adc_nids) {
5076 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
5077 " using fallback 0x%x\n",
5078 codec->chip_name, fallback_adc);
5079 spec->private_adc_nids[0] = fallback_adc;
5080 spec->adc_nids = spec->private_adc_nids;
5081 if (fallback_adc != fallback_cap) {
5082 spec->private_capsrc_nids[0] = fallback_cap;
5083 spec->capsrc_nids = spec->private_adc_nids;
5084 }
5085 }
5086}
5087
5088#ifdef CONFIG_SND_HDA_INPUT_BEEP
4776#define set_beep_amp(spec, nid, idx, dir) \ 5089#define set_beep_amp(spec, nid, idx, dir) \
4777 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir)) 5090 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
5091#else
5092#define set_beep_amp(spec, nid, idx, dir) /* NOP */
5093#endif
4778 5094
4779/* 5095/*
4780 * OK, here we have finally the patch for ALC880 5096 * OK, here we have finally the patch for ALC880
@@ -4856,7 +5172,6 @@ static int patch_alc880(struct hda_codec *codec)
4856 if (!spec->loopback.amplist) 5172 if (!spec->loopback.amplist)
4857 spec->loopback.amplist = alc880_loopbacks; 5173 spec->loopback.amplist = alc880_loopbacks;
4858#endif 5174#endif
4859 codec->proc_widget_hook = print_realtek_coef;
4860 5175
4861 return 0; 5176 return 0;
4862} 5177}
@@ -5064,6 +5379,7 @@ static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
5064 { 5379 {
5065 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5380 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5066 .name = "Master Playback Switch", 5381 .name = "Master Playback Switch",
5382 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
5067 .info = snd_ctl_boolean_mono_info, 5383 .info = snd_ctl_boolean_mono_info,
5068 .get = alc260_hp_master_sw_get, 5384 .get = alc260_hp_master_sw_get,
5069 .put = alc260_hp_master_sw_put, 5385 .put = alc260_hp_master_sw_put,
@@ -5087,11 +5403,8 @@ static struct hda_verb alc260_hp_unsol_verbs[] = {
5087static void alc260_hp_automute(struct hda_codec *codec) 5403static void alc260_hp_automute(struct hda_codec *codec)
5088{ 5404{
5089 struct alc_spec *spec = codec->spec; 5405 struct alc_spec *spec = codec->spec;
5090 unsigned int present;
5091 5406
5092 present = snd_hda_codec_read(codec, 0x10, 0, 5407 spec->jack_present = snd_hda_jack_detect(codec, 0x10);
5093 AC_VERB_GET_PIN_SENSE, 0);
5094 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
5095 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11); 5408 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
5096} 5409}
5097 5410
@@ -5105,6 +5418,7 @@ static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
5105 { 5418 {
5106 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5419 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5107 .name = "Master Playback Switch", 5420 .name = "Master Playback Switch",
5421 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
5108 .info = snd_ctl_boolean_mono_info, 5422 .info = snd_ctl_boolean_mono_info,
5109 .get = alc260_hp_master_sw_get, 5423 .get = alc260_hp_master_sw_get,
5110 .put = alc260_hp_master_sw_put, 5424 .put = alc260_hp_master_sw_put,
@@ -5156,11 +5470,8 @@ static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
5156static void alc260_hp_3013_automute(struct hda_codec *codec) 5470static void alc260_hp_3013_automute(struct hda_codec *codec)
5157{ 5471{
5158 struct alc_spec *spec = codec->spec; 5472 struct alc_spec *spec = codec->spec;
5159 unsigned int present;
5160 5473
5161 present = snd_hda_codec_read(codec, 0x15, 0, 5474 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
5162 AC_VERB_GET_PIN_SENSE, 0);
5163 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
5164 alc260_hp_master_update(codec, 0x15, 0x10, 0x11); 5475 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
5165} 5476}
5166 5477
@@ -5173,12 +5484,8 @@ static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
5173 5484
5174static void alc260_hp_3012_automute(struct hda_codec *codec) 5485static void alc260_hp_3012_automute(struct hda_codec *codec)
5175{ 5486{
5176 unsigned int present, bits; 5487 unsigned int bits = snd_hda_jack_detect(codec, 0x10) ? 0 : PIN_OUT;
5177 5488
5178 present = snd_hda_codec_read(codec, 0x10, 0,
5179 AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
5180
5181 bits = present ? 0 : PIN_OUT;
5182 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 5489 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5183 bits); 5490 bits);
5184 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 5491 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
@@ -5748,8 +6055,7 @@ static void alc260_replacer_672v_automute(struct hda_codec *codec)
5748 unsigned int present; 6055 unsigned int present;
5749 6056
5750 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */ 6057 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
5751 present = snd_hda_codec_read(codec, 0x0f, 0, 6058 present = snd_hda_jack_detect(codec, 0x0f);
5752 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5753 if (present) { 6059 if (present) {
5754 snd_hda_codec_write_cache(codec, 0x01, 0, 6060 snd_hda_codec_write_cache(codec, 0x01, 0,
5755 AC_VERB_SET_GPIO_DATA, 1); 6061 AC_VERB_SET_GPIO_DATA, 1);
@@ -5989,7 +6295,6 @@ static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
5989{ 6295{
5990 hda_nid_t nid_vol; 6296 hda_nid_t nid_vol;
5991 unsigned long vol_val, sw_val; 6297 unsigned long vol_val, sw_val;
5992 char name[32];
5993 int err; 6298 int err;
5994 6299
5995 if (nid >= 0x0f && nid < 0x11) { 6300 if (nid >= 0x0f && nid < 0x11) {
@@ -6009,14 +6314,12 @@ static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
6009 6314
6010 if (!(*vol_bits & (1 << nid_vol))) { 6315 if (!(*vol_bits & (1 << nid_vol))) {
6011 /* first control for the volume widget */ 6316 /* first control for the volume widget */
6012 snprintf(name, sizeof(name), "%s Playback Volume", pfx); 6317 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
6013 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
6014 if (err < 0) 6318 if (err < 0)
6015 return err; 6319 return err;
6016 *vol_bits |= (1 << nid_vol); 6320 *vol_bits |= (1 << nid_vol);
6017 } 6321 }
6018 snprintf(name, sizeof(name), "%s Playback Switch", pfx); 6322 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
6019 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
6020 if (err < 0) 6323 if (err < 0)
6021 return err; 6324 return err;
6022 return 1; 6325 return 1;
@@ -6124,6 +6427,8 @@ static void alc260_auto_init_analog_input(struct hda_codec *codec)
6124 } 6427 }
6125} 6428}
6126 6429
6430#define alc260_auto_init_input_src alc880_auto_init_input_src
6431
6127/* 6432/*
6128 * generic initialization of ADC, input mixers and output mixers 6433 * generic initialization of ADC, input mixers and output mixers
6129 */ 6434 */
@@ -6199,7 +6504,7 @@ static int alc260_parse_auto_config(struct hda_codec *codec)
6199 spec->num_mux_defs = 1; 6504 spec->num_mux_defs = 1;
6200 spec->input_mux = &spec->private_imux[0]; 6505 spec->input_mux = &spec->private_imux[0];
6201 6506
6202 alc_ssid_check(codec, 0x10, 0x15, 0x0f); 6507 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
6203 6508
6204 return 1; 6509 return 1;
6205} 6510}
@@ -6210,6 +6515,7 @@ static void alc260_auto_init(struct hda_codec *codec)
6210 struct alc_spec *spec = codec->spec; 6515 struct alc_spec *spec = codec->spec;
6211 alc260_auto_init_multi_out(codec); 6516 alc260_auto_init_multi_out(codec);
6212 alc260_auto_init_analog_input(codec); 6517 alc260_auto_init_analog_input(codec);
6518 alc260_auto_init_input_src(codec);
6213 if (spec->unsol_event) 6519 if (spec->unsol_event)
6214 alc_inithook(codec); 6520 alc_inithook(codec);
6215} 6521}
@@ -6246,6 +6552,7 @@ static const char *alc260_models[ALC260_MODEL_LAST] = {
6246 6552
6247static struct snd_pci_quirk alc260_cfg_tbl[] = { 6553static struct snd_pci_quirk alc260_cfg_tbl[] = {
6248 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER), 6554 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
6555 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
6249 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER), 6556 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
6250 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100), 6557 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
6251 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013), 6558 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
@@ -6275,7 +6582,7 @@ static struct alc_config_preset alc260_presets[] = {
6275 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 6582 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6276 .dac_nids = alc260_dac_nids, 6583 .dac_nids = alc260_dac_nids,
6277 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), 6584 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6278 .adc_nids = alc260_adc_nids, 6585 .adc_nids = alc260_dual_adc_nids,
6279 .num_channel_mode = ARRAY_SIZE(alc260_modes), 6586 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6280 .channel_mode = alc260_modes, 6587 .channel_mode = alc260_modes,
6281 .input_mux = &alc260_capture_source, 6588 .input_mux = &alc260_capture_source,
@@ -6477,7 +6784,6 @@ static int patch_alc260(struct hda_codec *codec)
6477 if (!spec->loopback.amplist) 6784 if (!spec->loopback.amplist)
6478 spec->loopback.amplist = alc260_loopbacks; 6785 spec->loopback.amplist = alc260_loopbacks;
6479#endif 6786#endif
6480 codec->proc_widget_hook = print_realtek_coef;
6481 6787
6482 return 0; 6788 return 0;
6483} 6789}
@@ -6559,6 +6865,14 @@ static struct hda_input_mux mb5_capture_source = {
6559 }, 6865 },
6560}; 6866};
6561 6867
6868static struct hda_input_mux macmini3_capture_source = {
6869 .num_items = 2,
6870 .items = {
6871 { "Line", 0x2 },
6872 { "CD", 0x4 },
6873 },
6874};
6875
6562static struct hda_input_mux alc883_3stack_6ch_intel = { 6876static struct hda_input_mux alc883_3stack_6ch_intel = {
6563 .num_items = 4, 6877 .num_items = 4,
6564 .items = { 6878 .items = {
@@ -6619,7 +6933,7 @@ static struct hda_input_mux alc889A_mb31_capture_source = {
6619 /* Front Mic (0x01) unused */ 6933 /* Front Mic (0x01) unused */
6620 { "Line", 0x2 }, 6934 { "Line", 0x2 },
6621 /* Line 2 (0x03) unused */ 6935 /* Line 2 (0x03) unused */
6622 /* CD (0x04) unsused? */ 6936 /* CD (0x04) unused? */
6623 }, 6937 },
6624}; 6938};
6625 6939
@@ -6747,6 +7061,13 @@ static struct hda_channel_mode alc882_sixstack_modes[2] = {
6747 { 8, alc882_sixstack_ch8_init }, 7061 { 8, alc882_sixstack_ch8_init },
6748}; 7062};
6749 7063
7064
7065/* Macbook Air 2,1 */
7066
7067static struct hda_channel_mode alc885_mba21_ch_modes[1] = {
7068 { 2, NULL },
7069};
7070
6750/* 7071/*
6751 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic 7072 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
6752 */ 7073 */
@@ -6807,6 +7128,7 @@ static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
6807 { 6, alc885_mb5_ch6_init }, 7128 { 6, alc885_mb5_ch6_init },
6808}; 7129};
6809 7130
7131#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
6810 7132
6811/* 7133/*
6812 * 2ch mode 7134 * 2ch mode
@@ -7018,6 +7340,15 @@ static struct snd_kcontrol_new alc882_base_mixer[] = {
7018 { } /* end */ 7340 { } /* end */
7019}; 7341};
7020 7342
7343/* Macbook Air 2,1 same control for HP and internal Speaker */
7344
7345static struct snd_kcontrol_new alc885_mba21_mixer[] = {
7346 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7347 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
7348 { }
7349};
7350
7351
7021static struct snd_kcontrol_new alc885_mbp3_mixer[] = { 7352static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
7022 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 7353 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7023 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT), 7354 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
@@ -7040,8 +7371,8 @@ static struct snd_kcontrol_new alc885_mb5_mixer[] = {
7040 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT), 7371 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7041 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT), 7372 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7042 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT), 7373 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
7043 HDA_CODEC_VOLUME("HP Playback Volume", 0x0f, 0x00, HDA_OUTPUT), 7374 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7044 HDA_BIND_MUTE ("HP Playback Switch", 0x0f, 0x02, HDA_INPUT), 7375 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
7045 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7376 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7046 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7377 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7047 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 7378 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
@@ -7051,6 +7382,35 @@ static struct snd_kcontrol_new alc885_mb5_mixer[] = {
7051 { } /* end */ 7382 { } /* end */
7052}; 7383};
7053 7384
7385static struct snd_kcontrol_new alc885_macmini3_mixer[] = {
7386 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7387 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7388 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7389 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7390 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7391 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
7392 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7393 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
7394 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7395 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
7396 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
7397 { } /* end */
7398};
7399
7400static struct snd_kcontrol_new alc885_imac91_mixer[] = {
7401 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7402 HDA_BIND_MUTE ("Line-Out Playback Switch", 0x0c, 0x02, HDA_INPUT),
7403 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
7404 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7405 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7406 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7407 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
7408 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
7409 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
7410 { } /* end */
7411};
7412
7413
7054static struct snd_kcontrol_new alc882_w2jc_mixer[] = { 7414static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
7055 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7415 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7056 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 7416 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
@@ -7128,29 +7488,18 @@ static struct snd_kcontrol_new alc882_chmode_mixer[] = {
7128 7488
7129static struct hda_verb alc882_base_init_verbs[] = { 7489static struct hda_verb alc882_base_init_verbs[] = {
7130 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 7490 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7131 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7132 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7491 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7133 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7492 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7134 /* Rear mixer */ 7493 /* Rear mixer */
7135 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7136 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7494 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7137 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7495 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7138 /* CLFE mixer */ 7496 /* CLFE mixer */
7139 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7140 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7497 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7141 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7498 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7142 /* Side mixer */ 7499 /* Side mixer */
7143 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7144 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7500 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7145 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7501 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7146 7502
7147 /* mute analog input loopbacks */
7148 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7149 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7150 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7151 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7152 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7153
7154 /* Front Pin: output 0 (0x0c) */ 7503 /* Front Pin: output 0 (0x0c) */
7155 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7504 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7156 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7505 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
@@ -7187,14 +7536,8 @@ static struct hda_verb alc882_base_init_verbs[] = {
7187 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 7536 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7188 /* Input mixer2 */ 7537 /* Input mixer2 */
7189 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7538 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7190 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7191 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7192 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7193 /* Input mixer3 */ 7539 /* Input mixer3 */
7194 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7540 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7195 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7196 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7197 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7198 /* ADC2: mute amp left and right */ 7541 /* ADC2: mute amp left and right */
7199 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7542 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7200 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 7543 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
@@ -7238,26 +7581,17 @@ static struct hda_verb alc_hp15_unsol_verbs[] = {
7238 7581
7239static struct hda_verb alc885_init_verbs[] = { 7582static struct hda_verb alc885_init_verbs[] = {
7240 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 7583 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7241 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7584 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7242 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7585 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7243 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7244 /* Rear mixer */ 7586 /* Rear mixer */
7245 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7587 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7246 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7588 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7247 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7248 /* CLFE mixer */ 7589 /* CLFE mixer */
7249 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7590 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7250 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7591 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7251 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7252 /* Side mixer */ 7592 /* Side mixer */
7253 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7593 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7254 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7594 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7255 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7256
7257 /* mute analog input loopbacks */
7258 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7259 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7260 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7261 7595
7262 /* Front HP Pin: output 0 (0x0c) */ 7596 /* Front HP Pin: output 0 (0x0c) */
7263 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7597 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
@@ -7291,17 +7625,11 @@ static struct hda_verb alc885_init_verbs[] = {
7291 7625
7292 /* Mixer elements: 0x18, , 0x1a, 0x1b */ 7626 /* Mixer elements: 0x18, , 0x1a, 0x1b */
7293 /* Input mixer1 */ 7627 /* Input mixer1 */
7294 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 7628 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7295 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7296 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7297 /* Input mixer2 */ 7629 /* Input mixer2 */
7298 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7630 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7299 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7300 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7301 /* Input mixer3 */ 7631 /* Input mixer3 */
7302 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 7632 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7303 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7304 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7305 /* ADC2: mute amp left and right */ 7633 /* ADC2: mute amp left and right */
7306 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7634 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7307 /* ADC3: mute amp left and right */ 7635 /* ADC3: mute amp left and right */
@@ -7336,8 +7664,8 @@ static struct snd_kcontrol_new alc882_macpro_mixer[] = {
7336 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), 7664 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
7337 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), 7665 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
7338 /* FIXME: this looks suspicious... 7666 /* FIXME: this looks suspicious...
7339 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT), 7667 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
7340 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT), 7668 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
7341 */ 7669 */
7342 { } /* end */ 7670 { } /* end */
7343}; 7671};
@@ -7428,6 +7756,7 @@ static struct hda_verb alc885_mb5_init_verbs[] = {
7428 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7756 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7429 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7757 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7430 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03}, 7758 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
7759 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7431 /* Front Mic pin: input vref at 80% */ 7760 /* Front Mic pin: input vref at 80% */
7432 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 7761 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7433 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 7762 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
@@ -7442,6 +7771,76 @@ static struct hda_verb alc885_mb5_init_verbs[] = {
7442 { } 7771 { }
7443}; 7772};
7444 7773
7774/* Macmini 3,1 */
7775static struct hda_verb alc885_macmini3_init_verbs[] = {
7776 /* DACs */
7777 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7778 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7779 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7780 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7781 /* Front mixer */
7782 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7783 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7784 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7785 /* Surround mixer */
7786 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7787 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7788 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7789 /* LFE mixer */
7790 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7791 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7792 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7793 /* HP mixer */
7794 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7795 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7796 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7797 /* Front Pin (0x0c) */
7798 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7799 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7800 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7801 /* LFE Pin (0x0e) */
7802 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7803 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7804 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
7805 /* HP Pin (0x0f) */
7806 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7807 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7808 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
7809 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7810 /* Line In pin */
7811 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7812 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7813
7814 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7815 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7816 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7817 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7818 { }
7819};
7820
7821
7822static struct hda_verb alc885_mba21_init_verbs[] = {
7823 /*Internal and HP Speaker Mixer*/
7824 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7825 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7826 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7827 /*Internal Speaker Pin (0x0c)*/
7828 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
7829 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7830 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7831 /* HP Pin: output 0 (0x0e) */
7832 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
7833 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7834 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7835 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
7836 /* Line in (is hp when jack connected)*/
7837 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
7838 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7839
7840 { }
7841 };
7842
7843
7445/* Macbook Pro rev3 */ 7844/* Macbook Pro rev3 */
7446static struct hda_verb alc885_mbp3_init_verbs[] = { 7845static struct hda_verb alc885_mbp3_init_verbs[] = {
7447 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 7846 /* Front mixer: unmute input/output amp left and right (volume = 0) */
@@ -7506,6 +7905,66 @@ static struct hda_verb alc885_mbp3_init_verbs[] = {
7506 { } 7905 { }
7507}; 7906};
7508 7907
7908/* iMac 9,1 */
7909static struct hda_verb alc885_imac91_init_verbs[] = {
7910 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
7911 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7912 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7913 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7914 /* Rear mixer */
7915 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7916 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7917 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7918 /* HP Pin: output 0 (0x0c) */
7919 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7920 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7921 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7922 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7923 /* Internal Speakers: output 0 (0x0d) */
7924 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7925 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7926 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7927 /* Mic (rear) pin: input vref at 80% */
7928 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7929 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7930 /* Front Mic pin: input vref at 80% */
7931 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7932 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7933 /* Line In pin: use output 1 when in LineOut mode */
7934 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7935 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7936 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
7937
7938 /* FIXME: use matrix-type input source selection */
7939 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7940 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7941 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7942 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7943 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7944 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7945 /* Input mixer2 */
7946 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7947 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7948 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7949 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7950 /* Input mixer3 */
7951 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7952 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7953 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7954 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7955 /* ADC1: mute amp left and right */
7956 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7957 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7958 /* ADC2: mute amp left and right */
7959 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7960 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7961 /* ADC3: mute amp left and right */
7962 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7963 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7964
7965 { }
7966};
7967
7509/* iMac 24 mixer. */ 7968/* iMac 24 mixer. */
7510static struct snd_kcontrol_new alc885_imac24_mixer[] = { 7969static struct snd_kcontrol_new alc885_imac24_mixer[] = {
7511 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 7970 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
@@ -7544,6 +8003,20 @@ static void alc885_imac24_setup(struct hda_codec *codec)
7544 spec->autocfg.speaker_pins[1] = 0x1a; 8003 spec->autocfg.speaker_pins[1] = 0x1a;
7545} 8004}
7546 8005
8006#define alc885_mb5_setup alc885_imac24_setup
8007#define alc885_macmini3_setup alc885_imac24_setup
8008
8009/* Macbook Air 2,1 */
8010static void alc885_mba21_setup(struct hda_codec *codec)
8011{
8012 struct alc_spec *spec = codec->spec;
8013
8014 spec->autocfg.hp_pins[0] = 0x14;
8015 spec->autocfg.speaker_pins[0] = 0x18;
8016}
8017
8018
8019
7547static void alc885_mbp3_setup(struct hda_codec *codec) 8020static void alc885_mbp3_setup(struct hda_codec *codec)
7548{ 8021{
7549 struct alc_spec *spec = codec->spec; 8022 struct alc_spec *spec = codec->spec;
@@ -7552,6 +8025,14 @@ static void alc885_mbp3_setup(struct hda_codec *codec)
7552 spec->autocfg.speaker_pins[0] = 0x14; 8025 spec->autocfg.speaker_pins[0] = 0x14;
7553} 8026}
7554 8027
8028static void alc885_imac91_setup(struct hda_codec *codec)
8029{
8030 struct alc_spec *spec = codec->spec;
8031
8032 spec->autocfg.hp_pins[0] = 0x14;
8033 spec->autocfg.speaker_pins[0] = 0x15;
8034 spec->autocfg.speaker_pins[1] = 0x1a;
8035}
7555 8036
7556static struct hda_verb alc882_targa_verbs[] = { 8037static struct hda_verb alc882_targa_verbs[] = {
7557 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8038 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
@@ -7685,18 +8166,6 @@ static struct hda_verb alc883_auto_init_verbs[] = {
7685 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 8166 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7686 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8167 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7687 8168
7688 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7689 * mixer widget
7690 * Note: PASD motherboards uses the Line In 2 as the input for
7691 * front panel mic (mic 2)
7692 */
7693 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7694 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7695 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7696 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7697 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7698 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7699
7700 /* 8169 /*
7701 * Set up output mixers (0x0c - 0x0f) 8170 * Set up output mixers (0x0c - 0x0f)
7702 */ 8171 */
@@ -7721,16 +8190,9 @@ static struct hda_verb alc883_auto_init_verbs[] = {
7721 /* FIXME: use matrix-type input source selection */ 8190 /* FIXME: use matrix-type input source selection */
7722 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 8191 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7723 /* Input mixer2 */ 8192 /* Input mixer2 */
7724 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 8193 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7725 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7726 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7727 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7728 /* Input mixer3 */ 8194 /* Input mixer3 */
7729 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 8195 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7730 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7731 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7732 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7733
7734 { } 8196 { }
7735}; 8197};
7736 8198
@@ -8026,6 +8488,42 @@ static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
8026 { } /* end */ 8488 { } /* end */
8027}; 8489};
8028 8490
8491static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
8492 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8493 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8494 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8495 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
8496 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
8497 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
8498 { } /* end */
8499};
8500
8501static struct hda_verb alc883_medion_wim2160_verbs[] = {
8502 /* Unmute front mixer */
8503 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8504 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8505
8506 /* Set speaker pin to front mixer */
8507 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8508
8509 /* Init headphone pin */
8510 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8511 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8512 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8513 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8514
8515 { } /* end */
8516};
8517
8518/* toggle speaker-output according to the hp-jack state */
8519static void alc883_medion_wim2160_setup(struct hda_codec *codec)
8520{
8521 struct alc_spec *spec = codec->spec;
8522
8523 spec->autocfg.hp_pins[0] = 0x1a;
8524 spec->autocfg.speaker_pins[0] = 0x15;
8525}
8526
8029static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = { 8527static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
8030 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8528 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8031 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8529 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
@@ -8040,9 +8538,7 @@ static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
8040 8538
8041static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = { 8539static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
8042 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8540 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8043 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8044 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 8541 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8045 HDA_BIND_MUTE("LFE Playback Switch", 0x0f, 2, HDA_INPUT),
8046 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8542 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8047 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8543 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8048 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8544 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
@@ -8184,12 +8680,8 @@ static void alc883_mitac_setup(struct hda_codec *codec)
8184/* 8680/*
8185static void alc883_mitac_mic_automute(struct hda_codec *codec) 8681static void alc883_mitac_mic_automute(struct hda_codec *codec)
8186{ 8682{
8187 unsigned int present; 8683 unsigned char bits = snd_hda_jack_detect(codec, 0x18) ? HDA_AMP_MUTE : 0;
8188 unsigned char bits;
8189 8684
8190 present = snd_hda_codec_read(codec, 0x18, 0,
8191 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8192 bits = present ? HDA_AMP_MUTE : 0;
8193 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits); 8685 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
8194} 8686}
8195*/ 8687*/
@@ -8411,10 +8903,8 @@ static struct hda_channel_mode alc888_3st_hp_modes[3] = {
8411/* toggle front-jack and RCA according to the hp-jack state */ 8903/* toggle front-jack and RCA according to the hp-jack state */
8412static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec) 8904static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
8413{ 8905{
8414 unsigned int present; 8906 unsigned int present = snd_hda_jack_detect(codec, 0x1b);
8415 8907
8416 present = snd_hda_codec_read(codec, 0x1b, 0,
8417 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8418 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 8908 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8419 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 8909 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8420 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 8910 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
@@ -8424,10 +8914,8 @@ static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
8424/* toggle RCA according to the front-jack state */ 8914/* toggle RCA according to the front-jack state */
8425static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec) 8915static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
8426{ 8916{
8427 unsigned int present; 8917 unsigned int present = snd_hda_jack_detect(codec, 0x14);
8428 8918
8429 present = snd_hda_codec_read(codec, 0x14, 0,
8430 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8431 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 8919 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8432 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 8920 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8433} 8921}
@@ -8468,8 +8956,7 @@ static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
8468{ 8956{
8469 unsigned int present; 8957 unsigned int present;
8470 8958
8471 present = snd_hda_codec_read(codec, 0x18, 0, 8959 present = snd_hda_jack_detect(codec, 0x18);
8472 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8473 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, 8960 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
8474 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 8961 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8475} 8962}
@@ -8520,24 +9007,16 @@ static void alc883_haier_w66_setup(struct hda_codec *codec)
8520 9007
8521static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec) 9008static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
8522{ 9009{
8523 unsigned int present; 9010 int bits = snd_hda_jack_detect(codec, 0x14) ? HDA_AMP_MUTE : 0;
8524 unsigned char bits;
8525 9011
8526 present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0)
8527 & AC_PINSENSE_PRESENCE;
8528 bits = present ? HDA_AMP_MUTE : 0;
8529 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 9012 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8530 HDA_AMP_MUTE, bits); 9013 HDA_AMP_MUTE, bits);
8531} 9014}
8532 9015
8533static void alc883_lenovo_101e_all_automute(struct hda_codec *codec) 9016static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
8534{ 9017{
8535 unsigned int present; 9018 int bits = snd_hda_jack_detect(codec, 0x1b) ? HDA_AMP_MUTE : 0;
8536 unsigned char bits;
8537 9019
8538 present = snd_hda_codec_read(codec, 0x1b, 0,
8539 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8540 bits = present ? HDA_AMP_MUTE : 0;
8541 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 9020 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8542 HDA_AMP_MUTE, bits); 9021 HDA_AMP_MUTE, bits);
8543 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 9022 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
@@ -8688,8 +9167,7 @@ static void alc889A_mb31_automute(struct hda_codec *codec)
8688 /* Mute only in 2ch or 4ch mode */ 9167 /* Mute only in 2ch or 4ch mode */
8689 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0) 9168 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
8690 == 0x00) { 9169 == 0x00) {
8691 present = snd_hda_codec_read(codec, 0x15, 0, 9170 present = snd_hda_jack_detect(codec, 0x15);
8692 AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
8693 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 9171 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8694 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 9172 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8695 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, 9173 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
@@ -8735,8 +9213,11 @@ static const char *alc882_models[ALC882_MODEL_LAST] = {
8735 [ALC882_ASUS_A7M] = "asus-a7m", 9213 [ALC882_ASUS_A7M] = "asus-a7m",
8736 [ALC885_MACPRO] = "macpro", 9214 [ALC885_MACPRO] = "macpro",
8737 [ALC885_MB5] = "mb5", 9215 [ALC885_MB5] = "mb5",
9216 [ALC885_MACMINI3] = "macmini3",
9217 [ALC885_MBA21] = "mba21",
8738 [ALC885_MBP3] = "mbp3", 9218 [ALC885_MBP3] = "mbp3",
8739 [ALC885_IMAC24] = "imac24", 9219 [ALC885_IMAC24] = "imac24",
9220 [ALC885_IMAC91] = "imac91",
8740 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig", 9221 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
8741 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig", 9222 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
8742 [ALC883_3ST_6ch] = "3stack-6ch", 9223 [ALC883_3ST_6ch] = "3stack-6ch",
@@ -8752,6 +9233,7 @@ static const char *alc882_models[ALC882_MODEL_LAST] = {
8752 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g", 9233 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
8753 [ALC883_MEDION] = "medion", 9234 [ALC883_MEDION] = "medion",
8754 [ALC883_MEDION_MD2] = "medion-md2", 9235 [ALC883_MEDION_MD2] = "medion-md2",
9236 [ALC883_MEDION_WIM2160] = "medion-wim2160",
8755 [ALC883_LAPTOP_EAPD] = "laptop-eapd", 9237 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
8756 [ALC883_LENOVO_101E_2ch] = "lenovo-101e", 9238 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
8757 [ALC883_LENOVO_NB0763] = "lenovo-nb0763", 9239 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
@@ -8839,7 +9321,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = {
8839 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG), 9321 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
8840 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG), 9322 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
8841 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */ 9323 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
8842 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG), 9324 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
8843 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG), 9325 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
8844 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG), 9326 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
8845 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG), 9327 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
@@ -8853,6 +9335,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = {
8853 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG), 9335 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
8854 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG), 9336 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
8855 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG), 9337 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
9338 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
8856 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG), 9339 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
8857 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG), 9340 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
8858 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG), 9341 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
@@ -8862,10 +9345,12 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = {
8862 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG), 9345 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
8863 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG), 9346 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
8864 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG), 9347 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
9348 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
8865 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG), 9349 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
8866 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG), 9350 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
8867 9351
8868 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG), 9352 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
9353 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
8869 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720), 9354 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
8870 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720), 9355 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
8871 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R), 9356 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
@@ -8893,7 +9378,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = {
8893 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL), 9378 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
8894 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL), 9379 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
8895 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL), 9380 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
8896 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch), 9381 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
8897 9382
8898 {} 9383 {}
8899}; 9384};
@@ -8910,12 +9395,14 @@ static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
8910 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31), 9395 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
8911 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3), 9396 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
8912 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24), 9397 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
9398 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
8913 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5), 9399 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
8914 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2, 9400 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
8915 * so apparently no perfect solution yet 9401 * so apparently no perfect solution yet
8916 */ 9402 */
8917 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5), 9403 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
8918 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5), 9404 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
9405 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
8919 {} /* terminator */ 9406 {} /* terminator */
8920}; 9407};
8921 9408
@@ -8967,6 +9454,18 @@ static struct alc_config_preset alc882_presets[] = {
8967 .input_mux = &alc882_capture_source, 9454 .input_mux = &alc882_capture_source,
8968 .dig_out_nid = ALC882_DIGOUT_NID, 9455 .dig_out_nid = ALC882_DIGOUT_NID,
8969 }, 9456 },
9457 [ALC885_MBA21] = {
9458 .mixers = { alc885_mba21_mixer },
9459 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
9460 .num_dacs = 2,
9461 .dac_nids = alc882_dac_nids,
9462 .channel_mode = alc885_mba21_ch_modes,
9463 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
9464 .input_mux = &alc882_capture_source,
9465 .unsol_event = alc_automute_amp_unsol_event,
9466 .setup = alc885_mba21_setup,
9467 .init_hook = alc_automute_amp,
9468 },
8970 [ALC885_MBP3] = { 9469 [ALC885_MBP3] = {
8971 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer }, 9470 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
8972 .init_verbs = { alc885_mbp3_init_verbs, 9471 .init_verbs = { alc885_mbp3_init_verbs,
@@ -8994,6 +9493,24 @@ static struct alc_config_preset alc882_presets[] = {
8994 .input_mux = &mb5_capture_source, 9493 .input_mux = &mb5_capture_source,
8995 .dig_out_nid = ALC882_DIGOUT_NID, 9494 .dig_out_nid = ALC882_DIGOUT_NID,
8996 .dig_in_nid = ALC882_DIGIN_NID, 9495 .dig_in_nid = ALC882_DIGIN_NID,
9496 .unsol_event = alc_automute_amp_unsol_event,
9497 .setup = alc885_mb5_setup,
9498 .init_hook = alc_automute_amp,
9499 },
9500 [ALC885_MACMINI3] = {
9501 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
9502 .init_verbs = { alc885_macmini3_init_verbs,
9503 alc880_gpio1_init_verbs },
9504 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9505 .dac_nids = alc882_dac_nids,
9506 .channel_mode = alc885_macmini3_6ch_modes,
9507 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
9508 .input_mux = &macmini3_capture_source,
9509 .dig_out_nid = ALC882_DIGOUT_NID,
9510 .dig_in_nid = ALC882_DIGIN_NID,
9511 .unsol_event = alc_automute_amp_unsol_event,
9512 .setup = alc885_macmini3_setup,
9513 .init_hook = alc_automute_amp,
8997 }, 9514 },
8998 [ALC885_MACPRO] = { 9515 [ALC885_MACPRO] = {
8999 .mixers = { alc882_macpro_mixer }, 9516 .mixers = { alc882_macpro_mixer },
@@ -9021,6 +9538,21 @@ static struct alc_config_preset alc882_presets[] = {
9021 .setup = alc885_imac24_setup, 9538 .setup = alc885_imac24_setup,
9022 .init_hook = alc885_imac24_init_hook, 9539 .init_hook = alc885_imac24_init_hook,
9023 }, 9540 },
9541 [ALC885_IMAC91] = {
9542 .mixers = { alc885_imac91_mixer, alc882_chmode_mixer },
9543 .init_verbs = { alc885_imac91_init_verbs,
9544 alc880_gpio1_init_verbs },
9545 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9546 .dac_nids = alc882_dac_nids,
9547 .channel_mode = alc885_mbp_4ch_modes,
9548 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
9549 .input_mux = &alc882_capture_source,
9550 .dig_out_nid = ALC882_DIGOUT_NID,
9551 .dig_in_nid = ALC882_DIGIN_NID,
9552 .unsol_event = alc_automute_amp_unsol_event,
9553 .setup = alc885_imac91_setup,
9554 .init_hook = alc_automute_amp,
9555 },
9024 [ALC882_TARGA] = { 9556 [ALC882_TARGA] = {
9025 .mixers = { alc882_targa_mixer, alc882_chmode_mixer }, 9557 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
9026 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, 9558 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
@@ -9187,6 +9719,7 @@ static struct alc_config_preset alc882_presets[] = {
9187 .dac_nids = alc883_dac_nids, 9719 .dac_nids = alc883_dac_nids,
9188 .adc_nids = alc883_adc_nids_alt, 9720 .adc_nids = alc883_adc_nids_alt,
9189 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt), 9721 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
9722 .capsrc_nids = alc883_capsrc_nids,
9190 .dig_out_nid = ALC883_DIGOUT_NID, 9723 .dig_out_nid = ALC883_DIGOUT_NID,
9191 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 9724 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9192 .channel_mode = alc883_3ST_2ch_modes, 9725 .channel_mode = alc883_3ST_2ch_modes,
@@ -9256,6 +9789,7 @@ static struct alc_config_preset alc882_presets[] = {
9256 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 9789 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9257 .channel_mode = alc883_3ST_6ch_modes, 9790 .channel_mode = alc883_3ST_6ch_modes,
9258 .need_dac_fix = 1, 9791 .need_dac_fix = 1,
9792 .const_channel_count = 6,
9259 .num_mux_defs = 9793 .num_mux_defs =
9260 ARRAY_SIZE(alc888_2_capture_sources), 9794 ARRAY_SIZE(alc888_2_capture_sources),
9261 .input_mux = alc888_2_capture_sources, 9795 .input_mux = alc888_2_capture_sources,
@@ -9283,10 +9817,11 @@ static struct alc_config_preset alc882_presets[] = {
9283 .init_hook = alc_automute_amp, 9817 .init_hook = alc_automute_amp,
9284 }, 9818 },
9285 [ALC888_ACER_ASPIRE_8930G] = { 9819 [ALC888_ACER_ASPIRE_8930G] = {
9286 .mixers = { alc888_base_mixer, 9820 .mixers = { alc889_acer_aspire_8930g_mixer,
9287 alc883_chmode_mixer }, 9821 alc883_chmode_mixer },
9288 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs, 9822 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9289 alc889_acer_aspire_8930g_verbs }, 9823 alc889_acer_aspire_8930g_verbs,
9824 alc889_eapd_verbs},
9290 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 9825 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9291 .dac_nids = alc883_dac_nids, 9826 .dac_nids = alc883_dac_nids,
9292 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids), 9827 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
@@ -9303,6 +9838,9 @@ static struct alc_config_preset alc882_presets[] = {
9303 .unsol_event = alc_automute_amp_unsol_event, 9838 .unsol_event = alc_automute_amp_unsol_event,
9304 .setup = alc889_acer_aspire_8930g_setup, 9839 .setup = alc889_acer_aspire_8930g_setup,
9305 .init_hook = alc_automute_amp, 9840 .init_hook = alc_automute_amp,
9841#ifdef CONFIG_SND_HDA_POWER_SAVE
9842 .power_hook = alc_power_eapd,
9843#endif
9306 }, 9844 },
9307 [ALC888_ACER_ASPIRE_7730G] = { 9845 [ALC888_ACER_ASPIRE_7730G] = {
9308 .mixers = { alc883_3ST_6ch_mixer, 9846 .mixers = { alc883_3ST_6ch_mixer,
@@ -9333,6 +9871,7 @@ static struct alc_config_preset alc882_presets[] = {
9333 .dac_nids = alc883_dac_nids, 9871 .dac_nids = alc883_dac_nids,
9334 .adc_nids = alc883_adc_nids_alt, 9872 .adc_nids = alc883_adc_nids_alt,
9335 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt), 9873 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
9874 .capsrc_nids = alc883_capsrc_nids,
9336 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 9875 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9337 .channel_mode = alc883_sixstack_modes, 9876 .channel_mode = alc883_sixstack_modes,
9338 .input_mux = &alc883_capture_source, 9877 .input_mux = &alc883_capture_source,
@@ -9350,6 +9889,21 @@ static struct alc_config_preset alc882_presets[] = {
9350 .setup = alc883_medion_md2_setup, 9889 .setup = alc883_medion_md2_setup,
9351 .init_hook = alc_automute_amp, 9890 .init_hook = alc_automute_amp,
9352 }, 9891 },
9892 [ALC883_MEDION_WIM2160] = {
9893 .mixers = { alc883_medion_wim2160_mixer },
9894 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
9895 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9896 .dac_nids = alc883_dac_nids,
9897 .dig_out_nid = ALC883_DIGOUT_NID,
9898 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
9899 .adc_nids = alc883_adc_nids,
9900 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9901 .channel_mode = alc883_3ST_2ch_modes,
9902 .input_mux = &alc883_capture_source,
9903 .unsol_event = alc_automute_amp_unsol_event,
9904 .setup = alc883_medion_wim2160_setup,
9905 .init_hook = alc_automute_amp,
9906 },
9353 [ALC883_LAPTOP_EAPD] = { 9907 [ALC883_LAPTOP_EAPD] = {
9354 .mixers = { alc883_base_mixer }, 9908 .mixers = { alc883_base_mixer },
9355 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs }, 9909 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
@@ -9394,6 +9948,7 @@ static struct alc_config_preset alc882_presets[] = {
9394 .dac_nids = alc883_dac_nids, 9948 .dac_nids = alc883_dac_nids,
9395 .adc_nids = alc883_adc_nids_alt, 9949 .adc_nids = alc883_adc_nids_alt,
9396 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt), 9950 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
9951 .capsrc_nids = alc883_capsrc_nids,
9397 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 9952 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9398 .channel_mode = alc883_3ST_2ch_modes, 9953 .channel_mode = alc883_3ST_2ch_modes,
9399 .input_mux = &alc883_lenovo_101e_capture_source, 9954 .input_mux = &alc883_lenovo_101e_capture_source,
@@ -9573,6 +10128,7 @@ static struct alc_config_preset alc882_presets[] = {
9573 alc880_gpio1_init_verbs }, 10128 alc880_gpio1_init_verbs },
9574 .adc_nids = alc883_adc_nids, 10129 .adc_nids = alc883_adc_nids,
9575 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 10130 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10131 .capsrc_nids = alc883_capsrc_nids,
9576 .dac_nids = alc883_dac_nids, 10132 .dac_nids = alc883_dac_nids,
9577 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10133 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9578 .channel_mode = alc889A_mb31_6ch_modes, 10134 .channel_mode = alc889A_mb31_6ch_modes,
@@ -9640,6 +10196,8 @@ static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
9640 int idx; 10196 int idx;
9641 10197
9642 alc_set_pin_output(codec, nid, pin_type); 10198 alc_set_pin_output(codec, nid, pin_type);
10199 if (dac_idx >= spec->multiout.num_dacs)
10200 return;
9643 if (spec->multiout.dac_nids[dac_idx] == 0x25) 10201 if (spec->multiout.dac_nids[dac_idx] == 0x25)
9644 idx = 4; 10202 idx = 4;
9645 else 10203 else
@@ -9711,6 +10269,8 @@ static void alc882_auto_init_input_src(struct hda_codec *codec)
9711 continue; 10269 continue;
9712 mux_idx = c >= spec->num_mux_defs ? 0 : c; 10270 mux_idx = c >= spec->num_mux_defs ? 0 : c;
9713 imux = &spec->input_mux[mux_idx]; 10271 imux = &spec->input_mux[mux_idx];
10272 if (!imux->num_items && mux_idx > 0)
10273 imux = &spec->input_mux[0];
9714 for (idx = 0; idx < conns; idx++) { 10274 for (idx = 0; idx < conns; idx++) {
9715 /* if the current connection is the selected one, 10275 /* if the current connection is the selected one,
9716 * unmute it as default - otherwise mute it 10276 * unmute it as default - otherwise mute it
@@ -9833,7 +10393,7 @@ static int alc882_parse_auto_config(struct hda_codec *codec)
9833 spec->num_mux_defs = 1; 10393 spec->num_mux_defs = 1;
9834 spec->input_mux = &spec->private_imux[0]; 10394 spec->input_mux = &spec->private_imux[0];
9835 10395
9836 alc_ssid_check(codec, 0x15, 0x1b, 0x14); 10396 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
9837 10397
9838 err = alc_auto_add_mic_boost(codec); 10398 err = alc_auto_add_mic_boost(codec);
9839 if (err < 0) 10399 if (err < 0)
@@ -9889,7 +10449,8 @@ static int patch_alc882(struct hda_codec *codec)
9889 board_config = ALC882_AUTO; 10449 board_config = ALC882_AUTO;
9890 } 10450 }
9891 10451
9892 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups); 10452 if (board_config == ALC882_AUTO)
10453 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 1);
9893 10454
9894 if (board_config == ALC882_AUTO) { 10455 if (board_config == ALC882_AUTO) {
9895 /* automatic parse from the BIOS config */ 10456 /* automatic parse from the BIOS config */
@@ -9927,10 +10488,12 @@ static int patch_alc882(struct hda_codec *codec)
9927 spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */ 10488 spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */
9928 10489
9929 if (!spec->adc_nids && spec->input_mux) { 10490 if (!spec->adc_nids && spec->input_mux) {
9930 int i; 10491 int i, j;
9931 spec->num_adc_nids = 0; 10492 spec->num_adc_nids = 0;
9932 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) { 10493 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
10494 const struct hda_input_mux *imux = spec->input_mux;
9933 hda_nid_t cap; 10495 hda_nid_t cap;
10496 hda_nid_t items[16];
9934 hda_nid_t nid = alc882_adc_nids[i]; 10497 hda_nid_t nid = alc882_adc_nids[i];
9935 unsigned int wcap = get_wcaps(codec, nid); 10498 unsigned int wcap = get_wcaps(codec, nid);
9936 /* get type */ 10499 /* get type */
@@ -9941,6 +10504,15 @@ static int patch_alc882(struct hda_codec *codec)
9941 err = snd_hda_get_connections(codec, nid, &cap, 1); 10504 err = snd_hda_get_connections(codec, nid, &cap, 1);
9942 if (err < 0) 10505 if (err < 0)
9943 continue; 10506 continue;
10507 err = snd_hda_get_connections(codec, cap, items,
10508 ARRAY_SIZE(items));
10509 if (err < 0)
10510 continue;
10511 for (j = 0; j < imux->num_items; j++)
10512 if (imux->items[j].index >= err)
10513 break;
10514 if (j < imux->num_items)
10515 continue;
9944 spec->private_capsrc_nids[spec->num_adc_nids] = cap; 10516 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
9945 spec->num_adc_nids++; 10517 spec->num_adc_nids++;
9946 } 10518 }
@@ -9951,6 +10523,9 @@ static int patch_alc882(struct hda_codec *codec)
9951 set_capture_mixer(codec); 10523 set_capture_mixer(codec);
9952 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 10524 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9953 10525
10526 if (board_config == ALC882_AUTO)
10527 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 0);
10528
9954 spec->vmaster_nid = 0x0c; 10529 spec->vmaster_nid = 0x0c;
9955 10530
9956 codec->patch_ops = alc_patch_ops; 10531 codec->patch_ops = alc_patch_ops;
@@ -9960,7 +10535,6 @@ static int patch_alc882(struct hda_codec *codec)
9960 if (!spec->loopback.amplist) 10535 if (!spec->loopback.amplist)
9961 spec->loopback.amplist = alc882_loopbacks; 10536 spec->loopback.amplist = alc882_loopbacks;
9962#endif 10537#endif
9963 codec->proc_widget_hook = print_realtek_coef;
9964 10538
9965 return 0; 10539 return 0;
9966} 10540}
@@ -10032,10 +10606,8 @@ static void alc262_hp_master_update(struct hda_codec *codec)
10032static void alc262_hp_bpc_automute(struct hda_codec *codec) 10606static void alc262_hp_bpc_automute(struct hda_codec *codec)
10033{ 10607{
10034 struct alc_spec *spec = codec->spec; 10608 struct alc_spec *spec = codec->spec;
10035 unsigned int presence; 10609
10036 presence = snd_hda_codec_read(codec, 0x1b, 0, 10610 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
10037 AC_VERB_GET_PIN_SENSE, 0);
10038 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
10039 alc262_hp_master_update(codec); 10611 alc262_hp_master_update(codec);
10040} 10612}
10041 10613
@@ -10049,10 +10621,8 @@ static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
10049static void alc262_hp_wildwest_automute(struct hda_codec *codec) 10621static void alc262_hp_wildwest_automute(struct hda_codec *codec)
10050{ 10622{
10051 struct alc_spec *spec = codec->spec; 10623 struct alc_spec *spec = codec->spec;
10052 unsigned int presence; 10624
10053 presence = snd_hda_codec_read(codec, 0x15, 0, 10625 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
10054 AC_VERB_GET_PIN_SENSE, 0);
10055 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
10056 alc262_hp_master_update(codec); 10626 alc262_hp_master_update(codec);
10057} 10627}
10058 10628
@@ -10087,8 +10657,14 @@ static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
10087 .info = snd_ctl_boolean_mono_info, \ 10657 .info = snd_ctl_boolean_mono_info, \
10088 .get = alc262_hp_master_sw_get, \ 10658 .get = alc262_hp_master_sw_get, \
10089 .put = alc262_hp_master_sw_put, \ 10659 .put = alc262_hp_master_sw_put, \
10660 }, \
10661 { \
10662 .iface = NID_MAPPING, \
10663 .name = "Master Playback Switch", \
10664 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
10090 } 10665 }
10091 10666
10667
10092static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { 10668static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
10093 ALC262_HP_MASTER_SWITCH, 10669 ALC262_HP_MASTER_SWITCH,
10094 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 10670 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
@@ -10146,7 +10722,7 @@ static void alc262_hp_t5735_setup(struct hda_codec *codec)
10146 struct alc_spec *spec = codec->spec; 10722 struct alc_spec *spec = codec->spec;
10147 10723
10148 spec->autocfg.hp_pins[0] = 0x15; 10724 spec->autocfg.hp_pins[0] = 0x15;
10149 spec->autocfg.speaker_pins[0] = 0x0c; /* HACK: not actually a pin */ 10725 spec->autocfg.speaker_pins[0] = 0x14;
10150} 10726}
10151 10727
10152static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = { 10728static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
@@ -10246,6 +10822,12 @@ static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
10246 .info = snd_ctl_boolean_mono_info, \ 10822 .info = snd_ctl_boolean_mono_info, \
10247 .get = alc262_hippo_master_sw_get, \ 10823 .get = alc262_hippo_master_sw_get, \
10248 .put = alc262_hippo_master_sw_put, \ 10824 .put = alc262_hippo_master_sw_put, \
10825 }, \
10826 { \
10827 .iface = NID_MAPPING, \
10828 .name = "Master Playback Switch", \
10829 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
10830 (SUBDEV_SPEAKER(0) << 16), \
10249 } 10831 }
10250 10832
10251static struct snd_kcontrol_new alc262_hippo_mixer[] = { 10833static struct snd_kcontrol_new alc262_hippo_mixer[] = {
@@ -10286,13 +10868,8 @@ static void alc262_hippo_automute(struct hda_codec *codec)
10286{ 10868{
10287 struct alc_spec *spec = codec->spec; 10869 struct alc_spec *spec = codec->spec;
10288 hda_nid_t hp_nid = spec->autocfg.hp_pins[0]; 10870 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
10289 unsigned int present;
10290 10871
10291 /* need to execute and sync at first */ 10872 spec->jack_present = snd_hda_jack_detect(codec, hp_nid);
10292 snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
10293 present = snd_hda_codec_read(codec, hp_nid, 0,
10294 AC_VERB_GET_PIN_SENSE, 0);
10295 spec->jack_present = (present & 0x80000000) != 0;
10296 alc262_hippo_master_update(codec); 10873 alc262_hippo_master_update(codec);
10297} 10874}
10298 10875
@@ -10581,6 +11158,13 @@ static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
10581 {} 11158 {}
10582}; 11159};
10583 11160
11161static struct hda_verb alc262_lenovo_3000_init_verbs[] = {
11162 /* Front Mic pin: input vref at 50% */
11163 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11164 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11165 {}
11166};
11167
10584static struct hda_input_mux alc262_fujitsu_capture_source = { 11168static struct hda_input_mux alc262_fujitsu_capture_source = {
10585 .num_items = 3, 11169 .num_items = 3,
10586 .items = { 11170 .items = {
@@ -10618,21 +11202,8 @@ static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
10618 unsigned int mute; 11202 unsigned int mute;
10619 11203
10620 if (force || !spec->sense_updated) { 11204 if (force || !spec->sense_updated) {
10621 unsigned int present; 11205 spec->jack_present = snd_hda_jack_detect(codec, 0x14) ||
10622 /* need to execute and sync at first */ 11206 snd_hda_jack_detect(codec, 0x1b);
10623 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
10624 /* check laptop HP jack */
10625 present = snd_hda_codec_read(codec, 0x14, 0,
10626 AC_VERB_GET_PIN_SENSE, 0);
10627 /* need to execute and sync at first */
10628 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
10629 /* check docking HP jack */
10630 present |= snd_hda_codec_read(codec, 0x1b, 0,
10631 AC_VERB_GET_PIN_SENSE, 0);
10632 if (present & AC_PINSENSE_PRESENCE)
10633 spec->jack_present = 1;
10634 else
10635 spec->jack_present = 0;
10636 spec->sense_updated = 1; 11207 spec->sense_updated = 1;
10637 } 11208 }
10638 /* unmute internal speaker only if both HPs are unplugged and 11209 /* unmute internal speaker only if both HPs are unplugged and
@@ -10677,12 +11248,7 @@ static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
10677 unsigned int mute; 11248 unsigned int mute;
10678 11249
10679 if (force || !spec->sense_updated) { 11250 if (force || !spec->sense_updated) {
10680 unsigned int present_int_hp; 11251 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
10681 /* need to execute and sync at first */
10682 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
10683 present_int_hp = snd_hda_codec_read(codec, 0x1b, 0,
10684 AC_VERB_GET_PIN_SENSE, 0);
10685 spec->jack_present = (present_int_hp & 0x80000000) != 0;
10686 spec->sense_updated = 1; 11252 spec->sense_updated = 1;
10687 } 11253 }
10688 if (spec->jack_present) { 11254 if (spec->jack_present) {
@@ -10742,11 +11308,17 @@ static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
10742 { 11308 {
10743 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11309 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10744 .name = "Master Playback Switch", 11310 .name = "Master Playback Switch",
11311 .subdevice = HDA_SUBDEV_AMP_FLAG,
10745 .info = snd_hda_mixer_amp_switch_info, 11312 .info = snd_hda_mixer_amp_switch_info,
10746 .get = snd_hda_mixer_amp_switch_get, 11313 .get = snd_hda_mixer_amp_switch_get,
10747 .put = alc262_fujitsu_master_sw_put, 11314 .put = alc262_fujitsu_master_sw_put,
10748 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 11315 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10749 }, 11316 },
11317 {
11318 .iface = NID_MAPPING,
11319 .name = "Master Playback Switch",
11320 .private_value = 0x1b,
11321 },
10750 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11322 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10751 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11323 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10752 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11324 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
@@ -10777,6 +11349,7 @@ static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
10777 { 11349 {
10778 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11350 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10779 .name = "Master Playback Switch", 11351 .name = "Master Playback Switch",
11352 .subdevice = HDA_SUBDEV_AMP_FLAG,
10780 .info = snd_hda_mixer_amp_switch_info, 11353 .info = snd_hda_mixer_amp_switch_info,
10781 .get = snd_hda_mixer_amp_switch_get, 11354 .get = snd_hda_mixer_amp_switch_get,
10782 .put = alc262_lenovo_3000_master_sw_put, 11355 .put = alc262_lenovo_3000_master_sw_put,
@@ -10874,12 +11447,7 @@ static void alc262_ultra_automute(struct hda_codec *codec)
10874 mute = 0; 11447 mute = 0;
10875 /* auto-mute only when HP is used as HP */ 11448 /* auto-mute only when HP is used as HP */
10876 if (!spec->cur_mux[0]) { 11449 if (!spec->cur_mux[0]) {
10877 unsigned int present; 11450 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
10878 /* need to execute and sync at first */
10879 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
10880 present = snd_hda_codec_read(codec, 0x15, 0,
10881 AC_VERB_GET_PIN_SENSE, 0);
10882 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
10883 if (spec->jack_present) 11451 if (spec->jack_present)
10884 mute = HDA_AMP_MUTE; 11452 mute = HDA_AMP_MUTE;
10885 } 11453 }
@@ -10936,6 +11504,11 @@ static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
10936 .get = alc_mux_enum_get, 11504 .get = alc_mux_enum_get,
10937 .put = alc262_ultra_mux_enum_put, 11505 .put = alc262_ultra_mux_enum_put,
10938 }, 11506 },
11507 {
11508 .iface = NID_MAPPING,
11509 .name = "Capture Source",
11510 .private_value = 0x15,
11511 },
10939 { } /* end */ 11512 { } /* end */
10940}; 11513};
10941 11514
@@ -10956,7 +11529,6 @@ static int alc262_check_volbit(hda_nid_t nid)
10956static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid, 11529static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
10957 const char *pfx, int *vbits) 11530 const char *pfx, int *vbits)
10958{ 11531{
10959 char name[32];
10960 unsigned long val; 11532 unsigned long val;
10961 int vbit; 11533 int vbit;
10962 11534
@@ -10966,28 +11538,25 @@ static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
10966 if (*vbits & vbit) /* a volume control for this mixer already there */ 11538 if (*vbits & vbit) /* a volume control for this mixer already there */
10967 return 0; 11539 return 0;
10968 *vbits |= vbit; 11540 *vbits |= vbit;
10969 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
10970 if (vbit == 2) 11541 if (vbit == 2)
10971 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT); 11542 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
10972 else 11543 else
10973 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT); 11544 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
10974 return add_control(spec, ALC_CTL_WIDGET_VOL, name, val); 11545 return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, val);
10975} 11546}
10976 11547
10977static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid, 11548static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
10978 const char *pfx) 11549 const char *pfx)
10979{ 11550{
10980 char name[32];
10981 unsigned long val; 11551 unsigned long val;
10982 11552
10983 if (!nid) 11553 if (!nid)
10984 return 0; 11554 return 0;
10985 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
10986 if (nid == 0x16) 11555 if (nid == 0x16)
10987 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT); 11556 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
10988 else 11557 else
10989 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); 11558 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
10990 return add_control(spec, ALC_CTL_WIDGET_MUTE, name, val); 11559 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, val);
10991} 11560}
10992 11561
10993/* add playback controls from the parsed DAC table */ 11562/* add playback controls from the parsed DAC table */
@@ -11043,7 +11612,7 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
11043} 11612}
11044 11613
11045#define alc262_auto_create_input_ctls \ 11614#define alc262_auto_create_input_ctls \
11046 alc880_auto_create_input_ctls 11615 alc882_auto_create_input_ctls
11047 11616
11048/* 11617/*
11049 * generic initialization of ADC, input mixers and output mixers 11618 * generic initialization of ADC, input mixers and output mixers
@@ -11386,7 +11955,7 @@ static int alc262_parse_auto_config(struct hda_codec *codec)
11386 if (err < 0) 11955 if (err < 0)
11387 return err; 11956 return err;
11388 11957
11389 alc_ssid_check(codec, 0x15, 0x14, 0x1b); 11958 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
11390 11959
11391 return 1; 11960 return 1;
11392} 11961}
@@ -11463,8 +12032,10 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = {
11463 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06), 12032 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
11464 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO), 12033 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
11465 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO), 12034 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
12035#if 0 /* disable the quirk since model=auto works better in recent versions */
11466 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO", 12036 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
11467 ALC262_SONY_ASSAMD), 12037 ALC262_SONY_ASSAMD),
12038#endif
11468 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1", 12039 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
11469 ALC262_TOSHIBA_RX1), 12040 ALC262_TOSHIBA_RX1),
11470 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06), 12041 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
@@ -11580,9 +12151,9 @@ static struct alc_config_preset alc262_presets[] = {
11580 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12151 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11581 .channel_mode = alc262_modes, 12152 .channel_mode = alc262_modes,
11582 .input_mux = &alc262_capture_source, 12153 .input_mux = &alc262_capture_source,
11583 .unsol_event = alc_automute_amp_unsol_event, 12154 .unsol_event = alc_sku_unsol_event,
11584 .setup = alc262_hp_t5735_setup, 12155 .setup = alc262_hp_t5735_setup,
11585 .init_hook = alc_automute_amp, 12156 .init_hook = alc_inithook,
11586 }, 12157 },
11587 [ALC262_HP_RP5700] = { 12158 [ALC262_HP_RP5700] = {
11588 .mixers = { alc262_hp_rp5700_mixer }, 12159 .mixers = { alc262_hp_rp5700_mixer },
@@ -11648,7 +12219,8 @@ static struct alc_config_preset alc262_presets[] = {
11648 [ALC262_LENOVO_3000] = { 12219 [ALC262_LENOVO_3000] = {
11649 .mixers = { alc262_lenovo_3000_mixer }, 12220 .mixers = { alc262_lenovo_3000_mixer },
11650 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs, 12221 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
11651 alc262_lenovo_3000_unsol_verbs }, 12222 alc262_lenovo_3000_unsol_verbs,
12223 alc262_lenovo_3000_init_verbs },
11652 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12224 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11653 .dac_nids = alc262_dac_nids, 12225 .dac_nids = alc262_dac_nids,
11654 .hp_nid = 0x03, 12226 .hp_nid = 0x03,
@@ -11826,7 +12398,6 @@ static int patch_alc262(struct hda_codec *codec)
11826 if (!spec->loopback.amplist) 12398 if (!spec->loopback.amplist)
11827 spec->loopback.amplist = alc262_loopbacks; 12399 spec->loopback.amplist = alc262_loopbacks;
11828#endif 12400#endif
11829 codec->proc_widget_hook = print_realtek_coef;
11830 12401
11831 return 0; 12402 return 0;
11832} 12403}
@@ -11923,10 +12494,7 @@ static void alc268_acer_automute(struct hda_codec *codec, int force)
11923 unsigned int mute; 12494 unsigned int mute;
11924 12495
11925 if (force || !spec->sense_updated) { 12496 if (force || !spec->sense_updated) {
11926 unsigned int present; 12497 spec->jack_present = snd_hda_jack_detect(codec, 0x14);
11927 present = snd_hda_codec_read(codec, 0x14, 0,
11928 AC_VERB_GET_PIN_SENSE, 0);
11929 spec->jack_present = (present & 0x80000000) != 0;
11930 spec->sense_updated = 1; 12498 spec->sense_updated = 1;
11931 } 12499 }
11932 if (spec->jack_present) 12500 if (spec->jack_present)
@@ -11958,6 +12526,7 @@ static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
11958 { 12526 {
11959 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12527 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11960 .name = "Master Playback Switch", 12528 .name = "Master Playback Switch",
12529 .subdevice = HDA_SUBDEV_AMP_FLAG,
11961 .info = snd_hda_mixer_amp_switch_info, 12530 .info = snd_hda_mixer_amp_switch_info,
11962 .get = snd_hda_mixer_amp_switch_get, 12531 .get = snd_hda_mixer_amp_switch_get,
11963 .put = alc268_acer_master_sw_put, 12532 .put = alc268_acer_master_sw_put,
@@ -11973,6 +12542,7 @@ static struct snd_kcontrol_new alc268_acer_mixer[] = {
11973 { 12542 {
11974 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12543 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11975 .name = "Master Playback Switch", 12544 .name = "Master Playback Switch",
12545 .subdevice = HDA_SUBDEV_AMP_FLAG,
11976 .info = snd_hda_mixer_amp_switch_info, 12546 .info = snd_hda_mixer_amp_switch_info,
11977 .get = snd_hda_mixer_amp_switch_get, 12547 .get = snd_hda_mixer_amp_switch_get,
11978 .put = alc268_acer_master_sw_put, 12548 .put = alc268_acer_master_sw_put,
@@ -11990,6 +12560,7 @@ static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
11990 { 12560 {
11991 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12561 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11992 .name = "Master Playback Switch", 12562 .name = "Master Playback Switch",
12563 .subdevice = HDA_SUBDEV_AMP_FLAG,
11993 .info = snd_hda_mixer_amp_switch_info, 12564 .info = snd_hda_mixer_amp_switch_info,
11994 .get = snd_hda_mixer_amp_switch_get, 12565 .get = snd_hda_mixer_amp_switch_get,
11995 .put = alc268_acer_master_sw_put, 12566 .put = alc268_acer_master_sw_put,
@@ -12045,13 +12616,12 @@ static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
12045 unsigned int present; 12616 unsigned int present;
12046 unsigned char bits; 12617 unsigned char bits;
12047 12618
12048 present = snd_hda_codec_read(codec, 0x15, 0, 12619 present = snd_hda_jack_detect(codec, 0x15);
12049 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 12620 bits = present ? HDA_AMP_MUTE : 0;
12050 bits = present ? AMP_IN_MUTE(0) : 0;
12051 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0, 12621 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
12052 AMP_IN_MUTE(0), bits); 12622 HDA_AMP_MUTE, bits);
12053 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1, 12623 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
12054 AMP_IN_MUTE(0), bits); 12624 HDA_AMP_MUTE, bits);
12055} 12625}
12056 12626
12057static void alc268_acer_lc_unsol_event(struct hda_codec *codec, 12627static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
@@ -12327,17 +12897,16 @@ static struct snd_kcontrol_new alc268_test_mixer[] = {
12327static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid, 12897static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
12328 const char *ctlname, int idx) 12898 const char *ctlname, int idx)
12329{ 12899{
12330 char name[32];
12331 hda_nid_t dac; 12900 hda_nid_t dac;
12332 int err; 12901 int err;
12333 12902
12334 sprintf(name, "%s Playback Volume", ctlname);
12335 switch (nid) { 12903 switch (nid) {
12336 case 0x14: 12904 case 0x14:
12337 case 0x16: 12905 case 0x16:
12338 dac = 0x02; 12906 dac = 0x02;
12339 break; 12907 break;
12340 case 0x15: 12908 case 0x15:
12909 case 0x21: /* ALC269vb has this pin, too */
12341 dac = 0x03; 12910 dac = 0x03;
12342 break; 12911 break;
12343 default: 12912 default:
@@ -12345,7 +12914,7 @@ static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
12345 } 12914 }
12346 if (spec->multiout.dac_nids[0] != dac && 12915 if (spec->multiout.dac_nids[0] != dac &&
12347 spec->multiout.dac_nids[1] != dac) { 12916 spec->multiout.dac_nids[1] != dac) {
12348 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 12917 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
12349 HDA_COMPOSE_AMP_VAL(dac, 3, idx, 12918 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
12350 HDA_OUTPUT)); 12919 HDA_OUTPUT));
12351 if (err < 0) 12920 if (err < 0)
@@ -12353,12 +12922,11 @@ static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
12353 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; 12922 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
12354 } 12923 }
12355 12924
12356 sprintf(name, "%s Playback Switch", ctlname);
12357 if (nid != 0x16) 12925 if (nid != 0x16)
12358 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, 12926 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
12359 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT)); 12927 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
12360 else /* mono */ 12928 else /* mono */
12361 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, 12929 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
12362 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT)); 12930 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
12363 if (err < 0) 12931 if (err < 0)
12364 return err; 12932 return err;
@@ -12388,8 +12956,7 @@ static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
12388 12956
12389 nid = cfg->speaker_pins[0]; 12957 nid = cfg->speaker_pins[0];
12390 if (nid == 0x1d) { 12958 if (nid == 0x1d) {
12391 err = add_control(spec, ALC_CTL_WIDGET_VOL, 12959 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
12392 "Speaker Playback Volume",
12393 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); 12960 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
12394 if (err < 0) 12961 if (err < 0)
12395 return err; 12962 return err;
@@ -12407,8 +12974,7 @@ static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
12407 12974
12408 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2]; 12975 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
12409 if (nid == 0x16) { 12976 if (nid == 0x16) {
12410 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 12977 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
12411 "Mono Playback Switch",
12412 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT)); 12978 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
12413 if (err < 0) 12979 if (err < 0)
12414 return err; 12980 return err;
@@ -12561,7 +13127,7 @@ static int alc268_parse_auto_config(struct hda_codec *codec)
12561 if (err < 0) 13127 if (err < 0)
12562 return err; 13128 return err;
12563 13129
12564 alc_ssid_check(codec, 0x15, 0x1b, 0x14); 13130 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
12565 13131
12566 return 1; 13132 return 1;
12567} 13133}
@@ -12794,7 +13360,7 @@ static int patch_alc268(struct hda_codec *codec)
12794 int board_config; 13360 int board_config;
12795 int i, has_beep, err; 13361 int i, has_beep, err;
12796 13362
12797 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); 13363 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12798 if (spec == NULL) 13364 if (spec == NULL)
12799 return -ENOMEM; 13365 return -ENOMEM;
12800 13366
@@ -12806,7 +13372,7 @@ static int patch_alc268(struct hda_codec *codec)
12806 13372
12807 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) 13373 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
12808 board_config = snd_hda_check_board_codec_sid_config(codec, 13374 board_config = snd_hda_check_board_codec_sid_config(codec,
12809 ALC882_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl); 13375 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
12810 13376
12811 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) { 13377 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
12812 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 13378 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
@@ -12898,8 +13464,6 @@ static int patch_alc268(struct hda_codec *codec)
12898 if (board_config == ALC268_AUTO) 13464 if (board_config == ALC268_AUTO)
12899 spec->init_hook = alc268_auto_init; 13465 spec->init_hook = alc268_auto_init;
12900 13466
12901 codec->proc_widget_hook = print_realtek_coef;
12902
12903 return 0; 13467 return 0;
12904} 13468}
12905 13469
@@ -12919,9 +13483,18 @@ static hda_nid_t alc269_capsrc_nids[1] = {
12919 0x23, 13483 0x23,
12920}; 13484};
12921 13485
12922/* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24), 13486static hda_nid_t alc269vb_adc_nids[1] = {
12923 * not a mux! 13487 /* ADC1 */
12924 */ 13488 0x09,
13489};
13490
13491static hda_nid_t alc269vb_capsrc_nids[1] = {
13492 0x22,
13493};
13494
13495static hda_nid_t alc269_adc_candidates[] = {
13496 0x08, 0x09, 0x07,
13497};
12925 13498
12926#define alc269_modes alc260_modes 13499#define alc269_modes alc260_modes
12927#define alc269_capture_source alc880_lg_lw_capture_source 13500#define alc269_capture_source alc880_lg_lw_capture_source
@@ -12948,6 +13521,7 @@ static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
12948 { 13521 {
12949 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13522 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12950 .name = "Master Playback Switch", 13523 .name = "Master Playback Switch",
13524 .subdevice = HDA_SUBDEV_AMP_FLAG,
12951 .info = snd_hda_mixer_amp_switch_info, 13525 .info = snd_hda_mixer_amp_switch_info,
12952 .get = snd_hda_mixer_amp_switch_get, 13526 .get = snd_hda_mixer_amp_switch_get,
12953 .put = alc268_acer_master_sw_put, 13527 .put = alc268_acer_master_sw_put,
@@ -12968,6 +13542,7 @@ static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
12968 { 13542 {
12969 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13543 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12970 .name = "Master Playback Switch", 13544 .name = "Master Playback Switch",
13545 .subdevice = HDA_SUBDEV_AMP_FLAG,
12971 .info = snd_hda_mixer_amp_switch_info, 13546 .info = snd_hda_mixer_amp_switch_info,
12972 .get = snd_hda_mixer_amp_switch_get, 13547 .get = snd_hda_mixer_amp_switch_get,
12973 .put = alc268_acer_master_sw_put, 13548 .put = alc268_acer_master_sw_put,
@@ -12985,7 +13560,7 @@ static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
12985 { } 13560 { }
12986}; 13561};
12987 13562
12988static struct snd_kcontrol_new alc269_eeepc_mixer[] = { 13563static struct snd_kcontrol_new alc269_laptop_mixer[] = {
12989 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 13564 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12990 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 13565 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12991 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 13566 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
@@ -12993,16 +13568,47 @@ static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
12993 { } /* end */ 13568 { } /* end */
12994}; 13569};
12995 13570
13571static struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
13572 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13573 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13574 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
13575 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13576 { } /* end */
13577};
13578
12996/* capture mixer elements */ 13579/* capture mixer elements */
12997static struct snd_kcontrol_new alc269_epc_capture_mixer[] = { 13580static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
12998 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 13581 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12999 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 13582 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13000 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 13583 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13584 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT),
13585 { } /* end */
13586};
13587
13588static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
13589 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13590 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13591 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13592 { } /* end */
13593};
13594
13595static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
13596 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13597 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13598 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13599 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT),
13600 { } /* end */
13601};
13602
13603static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
13604 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13605 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13606 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13001 { } /* end */ 13607 { } /* end */
13002}; 13608};
13003 13609
13004/* FSC amilo */ 13610/* FSC amilo */
13005#define alc269_fujitsu_mixer alc269_eeepc_mixer 13611#define alc269_fujitsu_mixer alc269_laptop_mixer
13006 13612
13007static struct hda_verb alc269_quanta_fl1_verbs[] = { 13613static struct hda_verb alc269_quanta_fl1_verbs[] = {
13008 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 13614 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
@@ -13034,13 +13640,12 @@ static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
13034 unsigned int present; 13640 unsigned int present;
13035 unsigned char bits; 13641 unsigned char bits;
13036 13642
13037 present = snd_hda_codec_read(codec, 0x15, 0, 13643 present = snd_hda_jack_detect(codec, 0x15);
13038 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 13644 bits = present ? HDA_AMP_MUTE : 0;
13039 bits = present ? AMP_IN_MUTE(0) : 0;
13040 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 13645 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
13041 AMP_IN_MUTE(0), bits); 13646 HDA_AMP_MUTE, bits);
13042 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 13647 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
13043 AMP_IN_MUTE(0), bits); 13648 HDA_AMP_MUTE, bits);
13044 13649
13045 snd_hda_codec_write(codec, 0x20, 0, 13650 snd_hda_codec_write(codec, 0x20, 0,
13046 AC_VERB_SET_COEF_INDEX, 0x0c); 13651 AC_VERB_SET_COEF_INDEX, 0x0c);
@@ -13060,18 +13665,16 @@ static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
13060 unsigned char bits; 13665 unsigned char bits;
13061 13666
13062 /* Check laptop headphone socket */ 13667 /* Check laptop headphone socket */
13063 present = snd_hda_codec_read(codec, 0x15, 0, 13668 present = snd_hda_jack_detect(codec, 0x15);
13064 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13065 13669
13066 /* Check port replicator headphone socket */ 13670 /* Check port replicator headphone socket */
13067 present |= snd_hda_codec_read(codec, 0x1a, 0, 13671 present |= snd_hda_jack_detect(codec, 0x1a);
13068 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13069 13672
13070 bits = present ? AMP_IN_MUTE(0) : 0; 13673 bits = present ? HDA_AMP_MUTE : 0;
13071 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 13674 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
13072 AMP_IN_MUTE(0), bits); 13675 HDA_AMP_MUTE, bits);
13073 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 13676 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
13074 AMP_IN_MUTE(0), bits); 13677 HDA_AMP_MUTE, bits);
13075 13678
13076 snd_hda_codec_write(codec, 0x20, 0, 13679 snd_hda_codec_write(codec, 0x20, 0,
13077 AC_VERB_SET_COEF_INDEX, 0x0c); 13680 AC_VERB_SET_COEF_INDEX, 0x0c);
@@ -13089,11 +13692,8 @@ static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
13089 unsigned int present_laptop; 13692 unsigned int present_laptop;
13090 unsigned int present_dock; 13693 unsigned int present_dock;
13091 13694
13092 present_laptop = snd_hda_codec_read(codec, 0x18, 0, 13695 present_laptop = snd_hda_jack_detect(codec, 0x18);
13093 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 13696 present_dock = snd_hda_jack_detect(codec, 0x1b);
13094
13095 present_dock = snd_hda_codec_read(codec, 0x1b, 0,
13096 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13097 13697
13098 /* Laptop mic port overrides dock mic port, design decision */ 13698 /* Laptop mic port overrides dock mic port, design decision */
13099 if (present_dock) 13699 if (present_dock)
@@ -13132,6 +13732,8 @@ static void alc269_lifebook_unsol_event(struct hda_codec *codec,
13132static void alc269_quanta_fl1_setup(struct hda_codec *codec) 13732static void alc269_quanta_fl1_setup(struct hda_codec *codec)
13133{ 13733{
13134 struct alc_spec *spec = codec->spec; 13734 struct alc_spec *spec = codec->spec;
13735 spec->autocfg.hp_pins[0] = 0x15;
13736 spec->autocfg.speaker_pins[0] = 0x14;
13135 spec->ext_mic.pin = 0x18; 13737 spec->ext_mic.pin = 0x18;
13136 spec->ext_mic.mux_idx = 0; 13738 spec->ext_mic.mux_idx = 0;
13137 spec->int_mic.pin = 0x19; 13739 spec->int_mic.pin = 0x19;
@@ -13151,7 +13753,7 @@ static void alc269_lifebook_init_hook(struct hda_codec *codec)
13151 alc269_lifebook_mic_autoswitch(codec); 13753 alc269_lifebook_mic_autoswitch(codec);
13152} 13754}
13153 13755
13154static struct hda_verb alc269_eeepc_dmic_init_verbs[] = { 13756static struct hda_verb alc269_laptop_dmic_init_verbs[] = {
13155 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 13757 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13156 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05}, 13758 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
13157 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 13759 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
@@ -13162,7 +13764,7 @@ static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
13162 {} 13764 {}
13163}; 13765};
13164 13766
13165static struct hda_verb alc269_eeepc_amic_init_verbs[] = { 13767static struct hda_verb alc269_laptop_amic_init_verbs[] = {
13166 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 13768 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13167 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01}, 13769 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
13168 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 13770 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
@@ -13172,23 +13774,46 @@ static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
13172 {} 13774 {}
13173}; 13775};
13174 13776
13777static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
13778 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
13779 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
13780 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13781 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
13782 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13783 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13784 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13785 {}
13786};
13787
13788static struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
13789 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
13790 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
13791 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13792 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
13793 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13794 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13795 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13796 {}
13797};
13798
13175/* toggle speaker-output according to the hp-jack state */ 13799/* toggle speaker-output according to the hp-jack state */
13176static void alc269_speaker_automute(struct hda_codec *codec) 13800static void alc269_speaker_automute(struct hda_codec *codec)
13177{ 13801{
13802 struct alc_spec *spec = codec->spec;
13803 unsigned int nid = spec->autocfg.hp_pins[0];
13178 unsigned int present; 13804 unsigned int present;
13179 unsigned char bits; 13805 unsigned char bits;
13180 13806
13181 present = snd_hda_codec_read(codec, 0x15, 0, 13807 present = snd_hda_jack_detect(codec, nid);
13182 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 13808 bits = present ? HDA_AMP_MUTE : 0;
13183 bits = present ? AMP_IN_MUTE(0) : 0;
13184 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 13809 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
13185 AMP_IN_MUTE(0), bits); 13810 HDA_AMP_MUTE, bits);
13186 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 13811 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
13187 AMP_IN_MUTE(0), bits); 13812 HDA_AMP_MUTE, bits);
13188} 13813}
13189 13814
13190/* unsolicited event for HP jack sensing */ 13815/* unsolicited event for HP jack sensing */
13191static void alc269_eeepc_unsol_event(struct hda_codec *codec, 13816static void alc269_laptop_unsol_event(struct hda_codec *codec,
13192 unsigned int res) 13817 unsigned int res)
13193{ 13818{
13194 switch (res >> 26) { 13819 switch (res >> 26) {
@@ -13201,9 +13826,23 @@ static void alc269_eeepc_unsol_event(struct hda_codec *codec,
13201 } 13826 }
13202} 13827}
13203 13828
13204static void alc269_eeepc_dmic_setup(struct hda_codec *codec) 13829static void alc269_laptop_amic_setup(struct hda_codec *codec)
13205{ 13830{
13206 struct alc_spec *spec = codec->spec; 13831 struct alc_spec *spec = codec->spec;
13832 spec->autocfg.hp_pins[0] = 0x15;
13833 spec->autocfg.speaker_pins[0] = 0x14;
13834 spec->ext_mic.pin = 0x18;
13835 spec->ext_mic.mux_idx = 0;
13836 spec->int_mic.pin = 0x19;
13837 spec->int_mic.mux_idx = 1;
13838 spec->auto_mic = 1;
13839}
13840
13841static void alc269_laptop_dmic_setup(struct hda_codec *codec)
13842{
13843 struct alc_spec *spec = codec->spec;
13844 spec->autocfg.hp_pins[0] = 0x15;
13845 spec->autocfg.speaker_pins[0] = 0x14;
13207 spec->ext_mic.pin = 0x18; 13846 spec->ext_mic.pin = 0x18;
13208 spec->ext_mic.mux_idx = 0; 13847 spec->ext_mic.mux_idx = 0;
13209 spec->int_mic.pin = 0x12; 13848 spec->int_mic.pin = 0x12;
@@ -13211,9 +13850,11 @@ static void alc269_eeepc_dmic_setup(struct hda_codec *codec)
13211 spec->auto_mic = 1; 13850 spec->auto_mic = 1;
13212} 13851}
13213 13852
13214static void alc269_eeepc_amic_setup(struct hda_codec *codec) 13853static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
13215{ 13854{
13216 struct alc_spec *spec = codec->spec; 13855 struct alc_spec *spec = codec->spec;
13856 spec->autocfg.hp_pins[0] = 0x21;
13857 spec->autocfg.speaker_pins[0] = 0x14;
13217 spec->ext_mic.pin = 0x18; 13858 spec->ext_mic.pin = 0x18;
13218 spec->ext_mic.mux_idx = 0; 13859 spec->ext_mic.mux_idx = 0;
13219 spec->int_mic.pin = 0x19; 13860 spec->int_mic.pin = 0x19;
@@ -13221,7 +13862,19 @@ static void alc269_eeepc_amic_setup(struct hda_codec *codec)
13221 spec->auto_mic = 1; 13862 spec->auto_mic = 1;
13222} 13863}
13223 13864
13224static void alc269_eeepc_inithook(struct hda_codec *codec) 13865static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
13866{
13867 struct alc_spec *spec = codec->spec;
13868 spec->autocfg.hp_pins[0] = 0x21;
13869 spec->autocfg.speaker_pins[0] = 0x14;
13870 spec->ext_mic.pin = 0x18;
13871 spec->ext_mic.mux_idx = 0;
13872 spec->int_mic.pin = 0x12;
13873 spec->int_mic.mux_idx = 6;
13874 spec->auto_mic = 1;
13875}
13876
13877static void alc269_laptop_inithook(struct hda_codec *codec)
13225{ 13878{
13226 alc269_speaker_automute(codec); 13879 alc269_speaker_automute(codec);
13227 alc_mic_automute(codec); 13880 alc_mic_automute(codec);
@@ -13234,22 +13887,10 @@ static struct hda_verb alc269_init_verbs[] = {
13234 /* 13887 /*
13235 * Unmute ADC0 and set the default input to mic-in 13888 * Unmute ADC0 and set the default input to mic-in
13236 */ 13889 */
13237 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13890 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13238
13239 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
13240 * analog-loopback mixer widget
13241 * Note: PASD motherboards uses the Line In 2 as the input for
13242 * front panel mic (mic 2)
13243 */
13244 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
13245 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13246 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13247 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13248 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13249 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13250 13891
13251 /* 13892 /*
13252 * Set up output mixers (0x0c - 0x0e) 13893 * Set up output mixers (0x02 - 0x03)
13253 */ 13894 */
13254 /* set vol=0 to output mixers */ 13895 /* set vol=0 to output mixers */
13255 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 13896 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
@@ -13274,26 +13915,57 @@ static struct hda_verb alc269_init_verbs[] = {
13274 13915
13275 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13916 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13276 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13917 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13277 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13278 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13279 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13280 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13281 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13282 13918
13283 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 13919 /* FIXME: use Mux-type input source selection */
13284 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 13920 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
13921 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
13922 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
13285 13923
13286 /* FIXME: use matrix-type input source selection */ 13924 /* set EAPD */
13925 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13926 { }
13927};
13928
13929static struct hda_verb alc269vb_init_verbs[] = {
13930 /*
13931 * Unmute ADC0 and set the default input to mic-in
13932 */
13933 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13934
13935 /*
13936 * Set up output mixers (0x02 - 0x03)
13937 */
13938 /* set vol=0 to output mixers */
13939 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13940 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13941
13942 /* set up input amps for analog loopback */
13943 /* Amp Indices: DAC = 0, mixer = 1 */
13944 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13945 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13946 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13947 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13948 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13949 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13950
13951 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13952 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13953 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13954 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13955 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13956 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13957 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13958
13959 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13960 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13961
13962 /* FIXME: use Mux-type input source selection */
13287 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */ 13963 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
13288 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 13964 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
13289 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 13965 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
13290 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13291 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13292 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13293 13966
13294 /* set EAPD */ 13967 /* set EAPD */
13295 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 13968 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13296 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13297 { } 13969 { }
13298}; 13970};
13299 13971
@@ -13362,11 +14034,21 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
13362 if (spec->kctls.list) 14034 if (spec->kctls.list)
13363 add_mixer(spec, spec->kctls.list); 14035 add_mixer(spec, spec->kctls.list);
13364 14036
13365 add_verb(spec, alc269_init_verbs); 14037 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010) {
14038 add_verb(spec, alc269vb_init_verbs);
14039 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
14040 } else {
14041 add_verb(spec, alc269_init_verbs);
14042 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
14043 }
14044
13366 spec->num_mux_defs = 1; 14045 spec->num_mux_defs = 1;
13367 spec->input_mux = &spec->private_imux[0]; 14046 spec->input_mux = &spec->private_imux[0];
14047 fillup_priv_adc_nids(codec, alc269_adc_candidates,
14048 sizeof(alc269_adc_candidates));
14049
13368 /* set default input source */ 14050 /* set default input source */
13369 snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0], 14051 snd_hda_codec_write_cache(codec, spec->capsrc_nids[0],
13370 0, AC_VERB_SET_CONNECT_SEL, 14052 0, AC_VERB_SET_CONNECT_SEL,
13371 spec->input_mux->items[0].index); 14053 spec->input_mux->items[0].index);
13372 14054
@@ -13377,8 +14059,6 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
13377 if (!spec->cap_mixer && !spec->no_analog) 14059 if (!spec->cap_mixer && !spec->no_analog)
13378 set_capture_mixer(codec); 14060 set_capture_mixer(codec);
13379 14061
13380 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
13381
13382 return 1; 14062 return 1;
13383} 14063}
13384 14064
@@ -13398,14 +14078,35 @@ static void alc269_auto_init(struct hda_codec *codec)
13398 alc_inithook(codec); 14078 alc_inithook(codec);
13399} 14079}
13400 14080
14081enum {
14082 ALC269_FIXUP_SONY_VAIO,
14083};
14084
14085const static struct hda_verb alc269_sony_vaio_fixup_verbs[] = {
14086 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14087 {}
14088};
14089
14090static const struct alc_fixup alc269_fixups[] = {
14091 [ALC269_FIXUP_SONY_VAIO] = {
14092 .verbs = alc269_sony_vaio_fixup_verbs
14093 },
14094};
14095
14096static struct snd_pci_quirk alc269_fixup_tbl[] = {
14097 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
14098 {}
14099};
14100
14101
13401/* 14102/*
13402 * configuration and preset 14103 * configuration and preset
13403 */ 14104 */
13404static const char *alc269_models[ALC269_MODEL_LAST] = { 14105static const char *alc269_models[ALC269_MODEL_LAST] = {
13405 [ALC269_BASIC] = "basic", 14106 [ALC269_BASIC] = "basic",
13406 [ALC269_QUANTA_FL1] = "quanta", 14107 [ALC269_QUANTA_FL1] = "quanta",
13407 [ALC269_ASUS_EEEPC_P703] = "eeepc-p703", 14108 [ALC269_AMIC] = "laptop-amic",
13408 [ALC269_ASUS_EEEPC_P901] = "eeepc-p901", 14109 [ALC269_DMIC] = "laptop-dmic",
13409 [ALC269_FUJITSU] = "fujitsu", 14110 [ALC269_FUJITSU] = "fujitsu",
13410 [ALC269_LIFEBOOK] = "lifebook", 14111 [ALC269_LIFEBOOK] = "lifebook",
13411 [ALC269_AUTO] = "auto", 14112 [ALC269_AUTO] = "auto",
@@ -13414,20 +14115,57 @@ static const char *alc269_models[ALC269_MODEL_LAST] = {
13414static struct snd_pci_quirk alc269_cfg_tbl[] = { 14115static struct snd_pci_quirk alc269_cfg_tbl[] = {
13415 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1), 14116 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
13416 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", 14117 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
13417 ALC269_ASUS_EEEPC_P703), 14118 ALC269_AMIC),
13418 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_ASUS_EEEPC_P703), 14119 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
13419 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_ASUS_EEEPC_P703), 14120 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
13420 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_ASUS_EEEPC_P703), 14121 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
13421 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_ASUS_EEEPC_P703), 14122 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
13422 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_ASUS_EEEPC_P703), 14123 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
13423 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_ASUS_EEEPC_P703), 14124 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
14125 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
14126 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
14127 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
14128 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82Jv", ALC269_AMIC),
14129 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
14130 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
14131 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
14132 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
14133 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
14134 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
14135 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
14136 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
14137 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
14138 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
14139 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
14140 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
14141 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
14142 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
14143 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
14144 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
14145 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
14146 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
14147 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
14148 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
14149 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
14150 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
14151 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
14152 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
14153 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
14154 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
13424 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901", 14155 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
13425 ALC269_ASUS_EEEPC_P901), 14156 ALC269_DMIC),
13426 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101", 14157 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
13427 ALC269_ASUS_EEEPC_P901), 14158 ALC269_DMIC),
13428 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_ASUS_EEEPC_P901), 14159 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
13429 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU), 14160 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
14161 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
13430 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK), 14162 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
14163 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
14164 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
14165 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
14166 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
14167 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
14168 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
13431 {} 14169 {}
13432}; 14170};
13433 14171
@@ -13455,47 +14193,75 @@ static struct alc_config_preset alc269_presets[] = {
13455 .setup = alc269_quanta_fl1_setup, 14193 .setup = alc269_quanta_fl1_setup,
13456 .init_hook = alc269_quanta_fl1_init_hook, 14194 .init_hook = alc269_quanta_fl1_init_hook,
13457 }, 14195 },
13458 [ALC269_ASUS_EEEPC_P703] = { 14196 [ALC269_AMIC] = {
13459 .mixers = { alc269_eeepc_mixer }, 14197 .mixers = { alc269_laptop_mixer },
13460 .cap_mixer = alc269_epc_capture_mixer, 14198 .cap_mixer = alc269_laptop_analog_capture_mixer,
13461 .init_verbs = { alc269_init_verbs, 14199 .init_verbs = { alc269_init_verbs,
13462 alc269_eeepc_amic_init_verbs }, 14200 alc269_laptop_amic_init_verbs },
13463 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 14201 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13464 .dac_nids = alc269_dac_nids, 14202 .dac_nids = alc269_dac_nids,
13465 .hp_nid = 0x03, 14203 .hp_nid = 0x03,
13466 .num_channel_mode = ARRAY_SIZE(alc269_modes), 14204 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13467 .channel_mode = alc269_modes, 14205 .channel_mode = alc269_modes,
13468 .unsol_event = alc269_eeepc_unsol_event, 14206 .unsol_event = alc269_laptop_unsol_event,
13469 .setup = alc269_eeepc_amic_setup, 14207 .setup = alc269_laptop_amic_setup,
13470 .init_hook = alc269_eeepc_inithook, 14208 .init_hook = alc269_laptop_inithook,
13471 }, 14209 },
13472 [ALC269_ASUS_EEEPC_P901] = { 14210 [ALC269_DMIC] = {
13473 .mixers = { alc269_eeepc_mixer }, 14211 .mixers = { alc269_laptop_mixer },
13474 .cap_mixer = alc269_epc_capture_mixer, 14212 .cap_mixer = alc269_laptop_digital_capture_mixer,
13475 .init_verbs = { alc269_init_verbs, 14213 .init_verbs = { alc269_init_verbs,
13476 alc269_eeepc_dmic_init_verbs }, 14214 alc269_laptop_dmic_init_verbs },
13477 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 14215 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13478 .dac_nids = alc269_dac_nids, 14216 .dac_nids = alc269_dac_nids,
13479 .hp_nid = 0x03, 14217 .hp_nid = 0x03,
13480 .num_channel_mode = ARRAY_SIZE(alc269_modes), 14218 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13481 .channel_mode = alc269_modes, 14219 .channel_mode = alc269_modes,
13482 .unsol_event = alc269_eeepc_unsol_event, 14220 .unsol_event = alc269_laptop_unsol_event,
13483 .setup = alc269_eeepc_dmic_setup, 14221 .setup = alc269_laptop_dmic_setup,
13484 .init_hook = alc269_eeepc_inithook, 14222 .init_hook = alc269_laptop_inithook,
14223 },
14224 [ALC269VB_AMIC] = {
14225 .mixers = { alc269vb_laptop_mixer },
14226 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
14227 .init_verbs = { alc269vb_init_verbs,
14228 alc269vb_laptop_amic_init_verbs },
14229 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14230 .dac_nids = alc269_dac_nids,
14231 .hp_nid = 0x03,
14232 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14233 .channel_mode = alc269_modes,
14234 .unsol_event = alc269_laptop_unsol_event,
14235 .setup = alc269vb_laptop_amic_setup,
14236 .init_hook = alc269_laptop_inithook,
14237 },
14238 [ALC269VB_DMIC] = {
14239 .mixers = { alc269vb_laptop_mixer },
14240 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
14241 .init_verbs = { alc269vb_init_verbs,
14242 alc269vb_laptop_dmic_init_verbs },
14243 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14244 .dac_nids = alc269_dac_nids,
14245 .hp_nid = 0x03,
14246 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14247 .channel_mode = alc269_modes,
14248 .unsol_event = alc269_laptop_unsol_event,
14249 .setup = alc269vb_laptop_dmic_setup,
14250 .init_hook = alc269_laptop_inithook,
13485 }, 14251 },
13486 [ALC269_FUJITSU] = { 14252 [ALC269_FUJITSU] = {
13487 .mixers = { alc269_fujitsu_mixer }, 14253 .mixers = { alc269_fujitsu_mixer },
13488 .cap_mixer = alc269_epc_capture_mixer, 14254 .cap_mixer = alc269_laptop_digital_capture_mixer,
13489 .init_verbs = { alc269_init_verbs, 14255 .init_verbs = { alc269_init_verbs,
13490 alc269_eeepc_dmic_init_verbs }, 14256 alc269_laptop_dmic_init_verbs },
13491 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 14257 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13492 .dac_nids = alc269_dac_nids, 14258 .dac_nids = alc269_dac_nids,
13493 .hp_nid = 0x03, 14259 .hp_nid = 0x03,
13494 .num_channel_mode = ARRAY_SIZE(alc269_modes), 14260 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13495 .channel_mode = alc269_modes, 14261 .channel_mode = alc269_modes,
13496 .unsol_event = alc269_eeepc_unsol_event, 14262 .unsol_event = alc269_laptop_unsol_event,
13497 .setup = alc269_eeepc_dmic_setup, 14263 .setup = alc269_laptop_dmic_setup,
13498 .init_hook = alc269_eeepc_inithook, 14264 .init_hook = alc269_laptop_inithook,
13499 }, 14265 },
13500 [ALC269_LIFEBOOK] = { 14266 [ALC269_LIFEBOOK] = {
13501 .mixers = { alc269_lifebook_mixer }, 14267 .mixers = { alc269_lifebook_mixer },
@@ -13516,6 +14282,7 @@ static int patch_alc269(struct hda_codec *codec)
13516 struct alc_spec *spec; 14282 struct alc_spec *spec;
13517 int board_config; 14283 int board_config;
13518 int err; 14284 int err;
14285 int is_alc269vb = 0;
13519 14286
13520 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 14287 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13521 if (spec == NULL) 14288 if (spec == NULL)
@@ -13525,6 +14292,16 @@ static int patch_alc269(struct hda_codec *codec)
13525 14292
13526 alc_fix_pll_init(codec, 0x20, 0x04, 15); 14293 alc_fix_pll_init(codec, 0x20, 0x04, 15);
13527 14294
14295 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010){
14296 kfree(codec->chip_name);
14297 codec->chip_name = kstrdup("ALC259", GFP_KERNEL);
14298 if (!codec->chip_name) {
14299 alc_free(codec);
14300 return -ENOMEM;
14301 }
14302 is_alc269vb = 1;
14303 }
14304
13528 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST, 14305 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
13529 alc269_models, 14306 alc269_models,
13530 alc269_cfg_tbl); 14307 alc269_cfg_tbl);
@@ -13535,6 +14312,9 @@ static int patch_alc269(struct hda_codec *codec)
13535 board_config = ALC269_AUTO; 14312 board_config = ALC269_AUTO;
13536 } 14313 }
13537 14314
14315 if (board_config == ALC269_AUTO)
14316 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 1);
14317
13538 if (board_config == ALC269_AUTO) { 14318 if (board_config == ALC269_AUTO) {
13539 /* automatic parse from the BIOS config */ 14319 /* automatic parse from the BIOS config */
13540 err = alc269_parse_auto_config(codec); 14320 err = alc269_parse_auto_config(codec);
@@ -13558,7 +14338,7 @@ static int patch_alc269(struct hda_codec *codec)
13558 if (board_config != ALC269_AUTO) 14338 if (board_config != ALC269_AUTO)
13559 setup_preset(codec, &alc269_presets[board_config]); 14339 setup_preset(codec, &alc269_presets[board_config]);
13560 14340
13561 if (codec->subsystem_id == 0x17aa3bf8) { 14341 if (board_config == ALC269_QUANTA_FL1) {
13562 /* Due to a hardware problem on Lenovo Ideadpad, we need to 14342 /* Due to a hardware problem on Lenovo Ideadpad, we need to
13563 * fix the sample rate of analog I/O to 44.1kHz 14343 * fix the sample rate of analog I/O to 44.1kHz
13564 */ 14344 */
@@ -13571,13 +14351,25 @@ static int patch_alc269(struct hda_codec *codec)
13571 spec->stream_digital_playback = &alc269_pcm_digital_playback; 14351 spec->stream_digital_playback = &alc269_pcm_digital_playback;
13572 spec->stream_digital_capture = &alc269_pcm_digital_capture; 14352 spec->stream_digital_capture = &alc269_pcm_digital_capture;
13573 14353
13574 spec->adc_nids = alc269_adc_nids; 14354 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
13575 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids); 14355 if (!is_alc269vb) {
13576 spec->capsrc_nids = alc269_capsrc_nids; 14356 spec->adc_nids = alc269_adc_nids;
14357 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
14358 spec->capsrc_nids = alc269_capsrc_nids;
14359 } else {
14360 spec->adc_nids = alc269vb_adc_nids;
14361 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
14362 spec->capsrc_nids = alc269vb_capsrc_nids;
14363 }
14364 }
14365
13577 if (!spec->cap_mixer) 14366 if (!spec->cap_mixer)
13578 set_capture_mixer(codec); 14367 set_capture_mixer(codec);
13579 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); 14368 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
13580 14369
14370 if (board_config == ALC269_AUTO)
14371 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 0);
14372
13581 spec->vmaster_nid = 0x02; 14373 spec->vmaster_nid = 0x02;
13582 14374
13583 codec->patch_ops = alc_patch_ops; 14375 codec->patch_ops = alc_patch_ops;
@@ -13587,7 +14379,6 @@ static int patch_alc269(struct hda_codec *codec)
13587 if (!spec->loopback.amplist) 14379 if (!spec->loopback.amplist)
13588 spec->loopback.amplist = alc269_loopbacks; 14380 spec->loopback.amplist = alc269_loopbacks;
13589#endif 14381#endif
13590 codec->proc_widget_hook = print_realtek_coef;
13591 14382
13592 return 0; 14383 return 0;
13593} 14384}
@@ -14157,10 +14948,8 @@ static struct hda_verb alc861_toshiba_init_verbs[] = {
14157/* toggle speaker-output according to the hp-jack state */ 14948/* toggle speaker-output according to the hp-jack state */
14158static void alc861_toshiba_automute(struct hda_codec *codec) 14949static void alc861_toshiba_automute(struct hda_codec *codec)
14159{ 14950{
14160 unsigned int present; 14951 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
14161 14952
14162 present = snd_hda_codec_read(codec, 0x0f, 0,
14163 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14164 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0, 14953 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
14165 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 14954 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
14166 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3, 14955 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
@@ -14260,9 +15049,7 @@ static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
14260static int alc861_create_out_sw(struct hda_codec *codec, const char *pfx, 15049static int alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
14261 hda_nid_t nid, unsigned int chs) 15050 hda_nid_t nid, unsigned int chs)
14262{ 15051{
14263 char name[32]; 15052 return add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx,
14264 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
14265 return add_control(codec->spec, ALC_CTL_WIDGET_MUTE, name,
14266 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); 15053 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
14267} 15054}
14268 15055
@@ -14454,7 +15241,7 @@ static int alc861_parse_auto_config(struct hda_codec *codec)
14454 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids); 15241 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
14455 set_capture_mixer(codec); 15242 set_capture_mixer(codec);
14456 15243
14457 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b); 15244 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
14458 15245
14459 return 1; 15246 return 1;
14460} 15247}
@@ -14627,6 +15414,27 @@ static struct alc_config_preset alc861_presets[] = {
14627 }, 15414 },
14628}; 15415};
14629 15416
15417/* Pin config fixes */
15418enum {
15419 PINFIX_FSC_AMILO_PI1505,
15420};
15421
15422static struct alc_pincfg alc861_fsc_amilo_pi1505_pinfix[] = {
15423 { 0x0b, 0x0221101f }, /* HP */
15424 { 0x0f, 0x90170310 }, /* speaker */
15425 { }
15426};
15427
15428static const struct alc_fixup alc861_fixups[] = {
15429 [PINFIX_FSC_AMILO_PI1505] = {
15430 .pins = alc861_fsc_amilo_pi1505_pinfix
15431 },
15432};
15433
15434static struct snd_pci_quirk alc861_fixup_tbl[] = {
15435 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
15436 {}
15437};
14630 15438
14631static int patch_alc861(struct hda_codec *codec) 15439static int patch_alc861(struct hda_codec *codec)
14632{ 15440{
@@ -14650,6 +15458,9 @@ static int patch_alc861(struct hda_codec *codec)
14650 board_config = ALC861_AUTO; 15458 board_config = ALC861_AUTO;
14651 } 15459 }
14652 15460
15461 if (board_config == ALC861_AUTO)
15462 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 1);
15463
14653 if (board_config == ALC861_AUTO) { 15464 if (board_config == ALC861_AUTO) {
14654 /* automatic parse from the BIOS config */ 15465 /* automatic parse from the BIOS config */
14655 err = alc861_parse_auto_config(codec); 15466 err = alc861_parse_auto_config(codec);
@@ -14679,18 +15490,26 @@ static int patch_alc861(struct hda_codec *codec)
14679 spec->stream_digital_playback = &alc861_pcm_digital_playback; 15490 spec->stream_digital_playback = &alc861_pcm_digital_playback;
14680 spec->stream_digital_capture = &alc861_pcm_digital_capture; 15491 spec->stream_digital_capture = &alc861_pcm_digital_capture;
14681 15492
15493 if (!spec->cap_mixer)
15494 set_capture_mixer(codec);
14682 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT); 15495 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
14683 15496
14684 spec->vmaster_nid = 0x03; 15497 spec->vmaster_nid = 0x03;
14685 15498
14686 codec->patch_ops = alc_patch_ops;
14687 if (board_config == ALC861_AUTO) 15499 if (board_config == ALC861_AUTO)
15500 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 0);
15501
15502 codec->patch_ops = alc_patch_ops;
15503 if (board_config == ALC861_AUTO) {
14688 spec->init_hook = alc861_auto_init; 15504 spec->init_hook = alc861_auto_init;
14689#ifdef CONFIG_SND_HDA_POWER_SAVE 15505#ifdef CONFIG_SND_HDA_POWER_SAVE
15506 spec->power_hook = alc_power_eapd;
15507#endif
15508 }
15509#ifdef CONFIG_SND_HDA_POWER_SAVE
14690 if (!spec->loopback.amplist) 15510 if (!spec->loopback.amplist)
14691 spec->loopback.amplist = alc861_loopbacks; 15511 spec->loopback.amplist = alc861_loopbacks;
14692#endif 15512#endif
14693 codec->proc_widget_hook = print_realtek_coef;
14694 15513
14695 return 0; 15514 return 0;
14696} 15515}
@@ -15067,9 +15886,9 @@ static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
15067 unsigned int present; 15886 unsigned int present;
15068 unsigned char bits; 15887 unsigned char bits;
15069 15888
15070 present = snd_hda_codec_read(codec, 0x18, 0, 15889 present = snd_hda_jack_detect(codec, 0x18);
15071 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15072 bits = present ? HDA_AMP_MUTE : 0; 15890 bits = present ? HDA_AMP_MUTE : 0;
15891
15073 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, 15892 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
15074 HDA_AMP_MUTE, bits); 15893 HDA_AMP_MUTE, bits);
15075} 15894}
@@ -15386,7 +16205,6 @@ static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
15386static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, 16205static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
15387 const struct auto_pin_cfg *cfg) 16206 const struct auto_pin_cfg *cfg)
15388{ 16207{
15389 char name[32];
15390 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"}; 16208 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
15391 hda_nid_t nid_v, nid_s; 16209 hda_nid_t nid_v, nid_s;
15392 int i, err; 16210 int i, err;
@@ -15403,26 +16221,26 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
15403 16221
15404 if (i == 2) { 16222 if (i == 2) {
15405 /* Center/LFE */ 16223 /* Center/LFE */
15406 err = add_control(spec, ALC_CTL_WIDGET_VOL, 16224 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
15407 "Center Playback Volume", 16225 "Center",
15408 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0, 16226 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
15409 HDA_OUTPUT)); 16227 HDA_OUTPUT));
15410 if (err < 0) 16228 if (err < 0)
15411 return err; 16229 return err;
15412 err = add_control(spec, ALC_CTL_WIDGET_VOL, 16230 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
15413 "LFE Playback Volume", 16231 "LFE",
15414 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0, 16232 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
15415 HDA_OUTPUT)); 16233 HDA_OUTPUT));
15416 if (err < 0) 16234 if (err < 0)
15417 return err; 16235 return err;
15418 err = add_control(spec, ALC_CTL_BIND_MUTE, 16236 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
15419 "Center Playback Switch", 16237 "Center",
15420 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2, 16238 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
15421 HDA_INPUT)); 16239 HDA_INPUT));
15422 if (err < 0) 16240 if (err < 0)
15423 return err; 16241 return err;
15424 err = add_control(spec, ALC_CTL_BIND_MUTE, 16242 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
15425 "LFE Playback Switch", 16243 "LFE",
15426 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2, 16244 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
15427 HDA_INPUT)); 16245 HDA_INPUT));
15428 if (err < 0) 16246 if (err < 0)
@@ -15437,8 +16255,7 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
15437 pfx = "PCM"; 16255 pfx = "PCM";
15438 } else 16256 } else
15439 pfx = chname[i]; 16257 pfx = chname[i];
15440 sprintf(name, "%s Playback Volume", pfx); 16258 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
15441 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
15442 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, 16259 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
15443 HDA_OUTPUT)); 16260 HDA_OUTPUT));
15444 if (err < 0) 16261 if (err < 0)
@@ -15446,8 +16263,7 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
15446 if (cfg->line_outs == 1 && 16263 if (cfg->line_outs == 1 &&
15447 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 16264 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
15448 pfx = "Speaker"; 16265 pfx = "Speaker";
15449 sprintf(name, "%s Playback Switch", pfx); 16266 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
15450 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
15451 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, 16267 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
15452 HDA_INPUT)); 16268 HDA_INPUT));
15453 if (err < 0) 16269 if (err < 0)
@@ -15465,7 +16281,6 @@ static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
15465{ 16281{
15466 hda_nid_t nid_v, nid_s; 16282 hda_nid_t nid_v, nid_s;
15467 int err; 16283 int err;
15468 char name[32];
15469 16284
15470 if (!pin) 16285 if (!pin)
15471 return 0; 16286 return 0;
@@ -15483,21 +16298,18 @@ static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
15483 nid_s = alc861vd_idx_to_mixer_switch( 16298 nid_s = alc861vd_idx_to_mixer_switch(
15484 alc880_fixed_pin_idx(pin)); 16299 alc880_fixed_pin_idx(pin));
15485 16300
15486 sprintf(name, "%s Playback Volume", pfx); 16301 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
15487 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
15488 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT)); 16302 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
15489 if (err < 0) 16303 if (err < 0)
15490 return err; 16304 return err;
15491 sprintf(name, "%s Playback Switch", pfx); 16305 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
15492 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
15493 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT)); 16306 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
15494 if (err < 0) 16307 if (err < 0)
15495 return err; 16308 return err;
15496 } else if (alc880_is_multi_pin(pin)) { 16309 } else if (alc880_is_multi_pin(pin)) {
15497 /* set manual connection */ 16310 /* set manual connection */
15498 /* we have only a switch on HP-out PIN */ 16311 /* we have only a switch on HP-out PIN */
15499 sprintf(name, "%s Playback Switch", pfx); 16312 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
15500 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
15501 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 16313 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
15502 if (err < 0) 16314 if (err < 0)
15503 return err; 16315 return err;
@@ -15560,7 +16372,7 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec)
15560 if (err < 0) 16372 if (err < 0)
15561 return err; 16373 return err;
15562 16374
15563 alc_ssid_check(codec, 0x15, 0x1b, 0x14); 16375 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
15564 16376
15565 return 1; 16377 return 1;
15566} 16378}
@@ -15621,7 +16433,8 @@ static int patch_alc861vd(struct hda_codec *codec)
15621 board_config = ALC861VD_AUTO; 16433 board_config = ALC861VD_AUTO;
15622 } 16434 }
15623 16435
15624 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups); 16436 if (board_config == ALC861VD_AUTO)
16437 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 1);
15625 16438
15626 if (board_config == ALC861VD_AUTO) { 16439 if (board_config == ALC861VD_AUTO) {
15627 /* automatic parse from the BIOS config */ 16440 /* automatic parse from the BIOS config */
@@ -15669,6 +16482,9 @@ static int patch_alc861vd(struct hda_codec *codec)
15669 16482
15670 spec->vmaster_nid = 0x02; 16483 spec->vmaster_nid = 0x02;
15671 16484
16485 if (board_config == ALC861VD_AUTO)
16486 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 0);
16487
15672 codec->patch_ops = alc_patch_ops; 16488 codec->patch_ops = alc_patch_ops;
15673 16489
15674 if (board_config == ALC861VD_AUTO) 16490 if (board_config == ALC861VD_AUTO)
@@ -15677,7 +16493,6 @@ static int patch_alc861vd(struct hda_codec *codec)
15677 if (!spec->loopback.amplist) 16493 if (!spec->loopback.amplist)
15678 spec->loopback.amplist = alc861vd_loopbacks; 16494 spec->loopback.amplist = alc861vd_loopbacks;
15679#endif 16495#endif
15680 codec->proc_widget_hook = print_realtek_coef;
15681 16496
15682 return 0; 16497 return 0;
15683} 16498}
@@ -16083,6 +16898,52 @@ static struct snd_kcontrol_new alc663_g50v_mixer[] = {
16083 { } /* end */ 16898 { } /* end */
16084}; 16899};
16085 16900
16901static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
16902 .ops = &snd_hda_bind_sw,
16903 .values = {
16904 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
16905 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
16906 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
16907 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
16908 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
16909 0
16910 },
16911};
16912
16913static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
16914 .ops = &snd_hda_bind_sw,
16915 .values = {
16916 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
16917 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
16918 0
16919 },
16920};
16921
16922static struct snd_kcontrol_new alc663_mode7_mixer[] = {
16923 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
16924 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
16925 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
16926 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16927 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16928 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16929 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16930 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16931 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16932 { } /* end */
16933};
16934
16935static struct snd_kcontrol_new alc663_mode8_mixer[] = {
16936 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
16937 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
16938 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
16939 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
16940 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16941 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16942 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16943 { } /* end */
16944};
16945
16946
16086static struct snd_kcontrol_new alc662_chmode_mixer[] = { 16947static struct snd_kcontrol_new alc662_chmode_mixer[] = {
16087 { 16948 {
16088 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 16949 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -16098,13 +16959,6 @@ static struct hda_verb alc662_init_verbs[] = {
16098 /* ADC: mute amp left and right */ 16959 /* ADC: mute amp left and right */
16099 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16960 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16100 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 16961 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16101 /* Front mixer: unmute input/output amp left and right (volume = 0) */
16102
16103 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16104 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16105 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16106 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16107 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16108 16962
16109 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 16963 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16110 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 16964 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
@@ -16154,6 +17008,28 @@ static struct hda_verb alc662_init_verbs[] = {
16154 { } 17008 { }
16155}; 17009};
16156 17010
17011static struct hda_verb alc663_init_verbs[] = {
17012 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17013 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17014 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17015 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17016 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17017 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17018 { }
17019};
17020
17021static struct hda_verb alc272_init_verbs[] = {
17022 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17023 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17024 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17025 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17026 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17027 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17028 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17029 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17030 { }
17031};
17032
16157static struct hda_verb alc662_sue_init_verbs[] = { 17033static struct hda_verb alc662_sue_init_verbs[] = {
16158 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT}, 17034 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
16159 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, 17035 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
@@ -16173,61 +17049,6 @@ static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
16173 {} 17049 {}
16174}; 17050};
16175 17051
16176/*
16177 * generic initialization of ADC, input mixers and output mixers
16178 */
16179static struct hda_verb alc662_auto_init_verbs[] = {
16180 /*
16181 * Unmute ADC and set the default input to mic-in
16182 */
16183 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16184 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16185
16186 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
16187 * mixer widget
16188 * Note: PASD motherboards uses the Line In 2 as the input for front
16189 * panel mic (mic 2)
16190 */
16191 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
16192 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16193 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16194 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16195 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16196 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16197
16198 /*
16199 * Set up output mixers (0x0c - 0x0f)
16200 */
16201 /* set vol=0 to output mixers */
16202 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16203 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16204 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16205
16206 /* set up input amps for analog loopback */
16207 /* Amp Indices: DAC = 0, mixer = 1 */
16208 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16209 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16210 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16211 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16212 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16213 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16214
16215
16216 /* FIXME: use matrix-type input source selection */
16217 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
16218 /* Input mixer */
16219 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16220 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16221 { }
16222};
16223
16224/* additional verbs for ALC663 */
16225static struct hda_verb alc663_auto_init_verbs[] = {
16226 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16227 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16228 { }
16229};
16230
16231static struct hda_verb alc663_m51va_init_verbs[] = { 17052static struct hda_verb alc663_m51va_init_verbs[] = {
16232 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17053 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16233 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17054 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
@@ -16370,6 +17191,45 @@ static struct hda_verb alc272_dell_init_verbs[] = {
16370 {} 17191 {}
16371}; 17192};
16372 17193
17194static struct hda_verb alc663_mode7_init_verbs[] = {
17195 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17196 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17197 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17198 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17199 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17200 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17201 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
17202 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17203 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17204 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17205 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17206 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17207 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17208 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17209 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17210 {}
17211};
17212
17213static struct hda_verb alc663_mode8_init_verbs[] = {
17214 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17215 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17216 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17217 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
17218 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17219 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17220 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17221 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17222 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17223 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17224 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17225 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17226 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17227 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17228 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17229 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17230 {}
17231};
17232
16373static struct snd_kcontrol_new alc662_auto_capture_mixer[] = { 17233static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
16374 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 17234 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
16375 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 17235 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
@@ -16387,9 +17247,9 @@ static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
16387 unsigned int present; 17247 unsigned int present;
16388 unsigned char bits; 17248 unsigned char bits;
16389 17249
16390 present = snd_hda_codec_read(codec, 0x14, 0, 17250 present = snd_hda_jack_detect(codec, 0x14);
16391 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
16392 bits = present ? HDA_AMP_MUTE : 0; 17251 bits = present ? HDA_AMP_MUTE : 0;
17252
16393 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 17253 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
16394 HDA_AMP_MUTE, bits); 17254 HDA_AMP_MUTE, bits);
16395} 17255}
@@ -16399,9 +17259,9 @@ static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
16399 unsigned int present; 17259 unsigned int present;
16400 unsigned char bits; 17260 unsigned char bits;
16401 17261
16402 present = snd_hda_codec_read(codec, 0x1b, 0, 17262 present = snd_hda_jack_detect(codec, 0x1b);
16403 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
16404 bits = present ? HDA_AMP_MUTE : 0; 17263 bits = present ? HDA_AMP_MUTE : 0;
17264
16405 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 17265 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
16406 HDA_AMP_MUTE, bits); 17266 HDA_AMP_MUTE, bits);
16407 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 17267 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
@@ -16460,14 +17320,12 @@ static void alc663_m51va_speaker_automute(struct hda_codec *codec)
16460 unsigned int present; 17320 unsigned int present;
16461 unsigned char bits; 17321 unsigned char bits;
16462 17322
16463 present = snd_hda_codec_read(codec, 0x21, 0, 17323 present = snd_hda_jack_detect(codec, 0x21);
16464 AC_VERB_GET_PIN_SENSE, 0)
16465 & AC_PINSENSE_PRESENCE;
16466 bits = present ? HDA_AMP_MUTE : 0; 17324 bits = present ? HDA_AMP_MUTE : 0;
16467 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 17325 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16468 AMP_IN_MUTE(0), bits); 17326 HDA_AMP_MUTE, bits);
16469 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 17327 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16470 AMP_IN_MUTE(0), bits); 17328 HDA_AMP_MUTE, bits);
16471} 17329}
16472 17330
16473static void alc663_21jd_two_speaker_automute(struct hda_codec *codec) 17331static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
@@ -16475,18 +17333,16 @@ static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
16475 unsigned int present; 17333 unsigned int present;
16476 unsigned char bits; 17334 unsigned char bits;
16477 17335
16478 present = snd_hda_codec_read(codec, 0x21, 0, 17336 present = snd_hda_jack_detect(codec, 0x21);
16479 AC_VERB_GET_PIN_SENSE, 0)
16480 & AC_PINSENSE_PRESENCE;
16481 bits = present ? HDA_AMP_MUTE : 0; 17337 bits = present ? HDA_AMP_MUTE : 0;
16482 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 17338 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16483 AMP_IN_MUTE(0), bits); 17339 HDA_AMP_MUTE, bits);
16484 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 17340 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16485 AMP_IN_MUTE(0), bits); 17341 HDA_AMP_MUTE, bits);
16486 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0, 17342 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
16487 AMP_IN_MUTE(0), bits); 17343 HDA_AMP_MUTE, bits);
16488 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1, 17344 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
16489 AMP_IN_MUTE(0), bits); 17345 HDA_AMP_MUTE, bits);
16490} 17346}
16491 17347
16492static void alc663_15jd_two_speaker_automute(struct hda_codec *codec) 17348static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
@@ -16494,18 +17350,16 @@ static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
16494 unsigned int present; 17350 unsigned int present;
16495 unsigned char bits; 17351 unsigned char bits;
16496 17352
16497 present = snd_hda_codec_read(codec, 0x15, 0, 17353 present = snd_hda_jack_detect(codec, 0x15);
16498 AC_VERB_GET_PIN_SENSE, 0)
16499 & AC_PINSENSE_PRESENCE;
16500 bits = present ? HDA_AMP_MUTE : 0; 17354 bits = present ? HDA_AMP_MUTE : 0;
16501 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 17355 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16502 AMP_IN_MUTE(0), bits); 17356 HDA_AMP_MUTE, bits);
16503 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 17357 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16504 AMP_IN_MUTE(0), bits); 17358 HDA_AMP_MUTE, bits);
16505 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0, 17359 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
16506 AMP_IN_MUTE(0), bits); 17360 HDA_AMP_MUTE, bits);
16507 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1, 17361 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
16508 AMP_IN_MUTE(0), bits); 17362 HDA_AMP_MUTE, bits);
16509} 17363}
16510 17364
16511static void alc662_f5z_speaker_automute(struct hda_codec *codec) 17365static void alc662_f5z_speaker_automute(struct hda_codec *codec)
@@ -16513,9 +17367,7 @@ static void alc662_f5z_speaker_automute(struct hda_codec *codec)
16513 unsigned int present; 17367 unsigned int present;
16514 unsigned char bits; 17368 unsigned char bits;
16515 17369
16516 present = snd_hda_codec_read(codec, 0x1b, 0, 17370 present = snd_hda_jack_detect(codec, 0x1b);
16517 AC_VERB_GET_PIN_SENSE, 0)
16518 & AC_PINSENSE_PRESENCE;
16519 bits = present ? 0 : PIN_OUT; 17371 bits = present ? 0 : PIN_OUT;
16520 snd_hda_codec_write(codec, 0x14, 0, 17372 snd_hda_codec_write(codec, 0x14, 0,
16521 AC_VERB_SET_PIN_WIDGET_CONTROL, bits); 17373 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
@@ -16525,12 +17377,8 @@ static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
16525{ 17377{
16526 unsigned int present1, present2; 17378 unsigned int present1, present2;
16527 17379
16528 present1 = snd_hda_codec_read(codec, 0x21, 0, 17380 present1 = snd_hda_jack_detect(codec, 0x21);
16529 AC_VERB_GET_PIN_SENSE, 0) 17381 present2 = snd_hda_jack_detect(codec, 0x15);
16530 & AC_PINSENSE_PRESENCE;
16531 present2 = snd_hda_codec_read(codec, 0x15, 0,
16532 AC_VERB_GET_PIN_SENSE, 0)
16533 & AC_PINSENSE_PRESENCE;
16534 17382
16535 if (present1 || present2) { 17383 if (present1 || present2) {
16536 snd_hda_codec_write_cache(codec, 0x14, 0, 17384 snd_hda_codec_write_cache(codec, 0x14, 0,
@@ -16545,23 +17393,67 @@ static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
16545{ 17393{
16546 unsigned int present1, present2; 17394 unsigned int present1, present2;
16547 17395
16548 present1 = snd_hda_codec_read(codec, 0x1b, 0, 17396 present1 = snd_hda_jack_detect(codec, 0x1b);
16549 AC_VERB_GET_PIN_SENSE, 0) 17397 present2 = snd_hda_jack_detect(codec, 0x15);
16550 & AC_PINSENSE_PRESENCE;
16551 present2 = snd_hda_codec_read(codec, 0x15, 0,
16552 AC_VERB_GET_PIN_SENSE, 0)
16553 & AC_PINSENSE_PRESENCE;
16554 17398
16555 if (present1 || present2) { 17399 if (present1 || present2) {
16556 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 17400 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16557 AMP_IN_MUTE(0), AMP_IN_MUTE(0)); 17401 HDA_AMP_MUTE, HDA_AMP_MUTE);
16558 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 17402 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16559 AMP_IN_MUTE(0), AMP_IN_MUTE(0)); 17403 HDA_AMP_MUTE, HDA_AMP_MUTE);
16560 } else { 17404 } else {
16561 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 17405 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16562 AMP_IN_MUTE(0), 0); 17406 HDA_AMP_MUTE, 0);
16563 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 17407 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16564 AMP_IN_MUTE(0), 0); 17408 HDA_AMP_MUTE, 0);
17409 }
17410}
17411
17412static void alc663_two_hp_m7_speaker_automute(struct hda_codec *codec)
17413{
17414 unsigned int present1, present2;
17415
17416 present1 = snd_hda_codec_read(codec, 0x1b, 0,
17417 AC_VERB_GET_PIN_SENSE, 0)
17418 & AC_PINSENSE_PRESENCE;
17419 present2 = snd_hda_codec_read(codec, 0x21, 0,
17420 AC_VERB_GET_PIN_SENSE, 0)
17421 & AC_PINSENSE_PRESENCE;
17422
17423 if (present1 || present2) {
17424 snd_hda_codec_write_cache(codec, 0x14, 0,
17425 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17426 snd_hda_codec_write_cache(codec, 0x17, 0,
17427 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17428 } else {
17429 snd_hda_codec_write_cache(codec, 0x14, 0,
17430 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17431 snd_hda_codec_write_cache(codec, 0x17, 0,
17432 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17433 }
17434}
17435
17436static void alc663_two_hp_m8_speaker_automute(struct hda_codec *codec)
17437{
17438 unsigned int present1, present2;
17439
17440 present1 = snd_hda_codec_read(codec, 0x21, 0,
17441 AC_VERB_GET_PIN_SENSE, 0)
17442 & AC_PINSENSE_PRESENCE;
17443 present2 = snd_hda_codec_read(codec, 0x15, 0,
17444 AC_VERB_GET_PIN_SENSE, 0)
17445 & AC_PINSENSE_PRESENCE;
17446
17447 if (present1 || present2) {
17448 snd_hda_codec_write_cache(codec, 0x14, 0,
17449 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17450 snd_hda_codec_write_cache(codec, 0x17, 0,
17451 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17452 } else {
17453 snd_hda_codec_write_cache(codec, 0x14, 0,
17454 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17455 snd_hda_codec_write_cache(codec, 0x17, 0,
17456 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
16565 } 17457 }
16566} 17458}
16567 17459
@@ -16584,7 +17476,7 @@ static void alc663_m51va_setup(struct hda_codec *codec)
16584 spec->ext_mic.pin = 0x18; 17476 spec->ext_mic.pin = 0x18;
16585 spec->ext_mic.mux_idx = 0; 17477 spec->ext_mic.mux_idx = 0;
16586 spec->int_mic.pin = 0x12; 17478 spec->int_mic.pin = 0x12;
16587 spec->int_mic.mux_idx = 1; 17479 spec->int_mic.mux_idx = 9;
16588 spec->auto_mic = 1; 17480 spec->auto_mic = 1;
16589} 17481}
16590 17482
@@ -16596,7 +17488,17 @@ static void alc663_m51va_inithook(struct hda_codec *codec)
16596 17488
16597/* ***************** Mode1 ******************************/ 17489/* ***************** Mode1 ******************************/
16598#define alc663_mode1_unsol_event alc663_m51va_unsol_event 17490#define alc663_mode1_unsol_event alc663_m51va_unsol_event
16599#define alc663_mode1_setup alc663_m51va_setup 17491
17492static void alc663_mode1_setup(struct hda_codec *codec)
17493{
17494 struct alc_spec *spec = codec->spec;
17495 spec->ext_mic.pin = 0x18;
17496 spec->ext_mic.mux_idx = 0;
17497 spec->int_mic.pin = 0x19;
17498 spec->int_mic.mux_idx = 1;
17499 spec->auto_mic = 1;
17500}
17501
16600#define alc663_mode1_inithook alc663_m51va_inithook 17502#define alc663_mode1_inithook alc663_m51va_inithook
16601 17503
16602/* ***************** Mode2 ******************************/ 17504/* ***************** Mode2 ******************************/
@@ -16613,7 +17515,7 @@ static void alc662_mode2_unsol_event(struct hda_codec *codec,
16613 } 17515 }
16614} 17516}
16615 17517
16616#define alc662_mode2_setup alc663_m51va_setup 17518#define alc662_mode2_setup alc663_mode1_setup
16617 17519
16618static void alc662_mode2_inithook(struct hda_codec *codec) 17520static void alc662_mode2_inithook(struct hda_codec *codec)
16619{ 17521{
@@ -16634,7 +17536,7 @@ static void alc663_mode3_unsol_event(struct hda_codec *codec,
16634 } 17536 }
16635} 17537}
16636 17538
16637#define alc663_mode3_setup alc663_m51va_setup 17539#define alc663_mode3_setup alc663_mode1_setup
16638 17540
16639static void alc663_mode3_inithook(struct hda_codec *codec) 17541static void alc663_mode3_inithook(struct hda_codec *codec)
16640{ 17542{
@@ -16655,7 +17557,7 @@ static void alc663_mode4_unsol_event(struct hda_codec *codec,
16655 } 17557 }
16656} 17558}
16657 17559
16658#define alc663_mode4_setup alc663_m51va_setup 17560#define alc663_mode4_setup alc663_mode1_setup
16659 17561
16660static void alc663_mode4_inithook(struct hda_codec *codec) 17562static void alc663_mode4_inithook(struct hda_codec *codec)
16661{ 17563{
@@ -16676,7 +17578,7 @@ static void alc663_mode5_unsol_event(struct hda_codec *codec,
16676 } 17578 }
16677} 17579}
16678 17580
16679#define alc663_mode5_setup alc663_m51va_setup 17581#define alc663_mode5_setup alc663_mode1_setup
16680 17582
16681static void alc663_mode5_inithook(struct hda_codec *codec) 17583static void alc663_mode5_inithook(struct hda_codec *codec)
16682{ 17584{
@@ -16697,7 +17599,7 @@ static void alc663_mode6_unsol_event(struct hda_codec *codec,
16697 } 17599 }
16698} 17600}
16699 17601
16700#define alc663_mode6_setup alc663_m51va_setup 17602#define alc663_mode6_setup alc663_mode1_setup
16701 17603
16702static void alc663_mode6_inithook(struct hda_codec *codec) 17604static void alc663_mode6_inithook(struct hda_codec *codec)
16703{ 17605{
@@ -16705,14 +17607,56 @@ static void alc663_mode6_inithook(struct hda_codec *codec)
16705 alc_mic_automute(codec); 17607 alc_mic_automute(codec);
16706} 17608}
16707 17609
17610/* ***************** Mode7 ******************************/
17611static void alc663_mode7_unsol_event(struct hda_codec *codec,
17612 unsigned int res)
17613{
17614 switch (res >> 26) {
17615 case ALC880_HP_EVENT:
17616 alc663_two_hp_m7_speaker_automute(codec);
17617 break;
17618 case ALC880_MIC_EVENT:
17619 alc_mic_automute(codec);
17620 break;
17621 }
17622}
17623
17624#define alc663_mode7_setup alc663_mode1_setup
17625
17626static void alc663_mode7_inithook(struct hda_codec *codec)
17627{
17628 alc663_two_hp_m7_speaker_automute(codec);
17629 alc_mic_automute(codec);
17630}
17631
17632/* ***************** Mode8 ******************************/
17633static void alc663_mode8_unsol_event(struct hda_codec *codec,
17634 unsigned int res)
17635{
17636 switch (res >> 26) {
17637 case ALC880_HP_EVENT:
17638 alc663_two_hp_m8_speaker_automute(codec);
17639 break;
17640 case ALC880_MIC_EVENT:
17641 alc_mic_automute(codec);
17642 break;
17643 }
17644}
17645
17646#define alc663_mode8_setup alc663_m51va_setup
17647
17648static void alc663_mode8_inithook(struct hda_codec *codec)
17649{
17650 alc663_two_hp_m8_speaker_automute(codec);
17651 alc_mic_automute(codec);
17652}
17653
16708static void alc663_g71v_hp_automute(struct hda_codec *codec) 17654static void alc663_g71v_hp_automute(struct hda_codec *codec)
16709{ 17655{
16710 unsigned int present; 17656 unsigned int present;
16711 unsigned char bits; 17657 unsigned char bits;
16712 17658
16713 present = snd_hda_codec_read(codec, 0x21, 0, 17659 present = snd_hda_jack_detect(codec, 0x21);
16714 AC_VERB_GET_PIN_SENSE, 0)
16715 & AC_PINSENSE_PRESENCE;
16716 bits = present ? HDA_AMP_MUTE : 0; 17660 bits = present ? HDA_AMP_MUTE : 0;
16717 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 17661 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
16718 HDA_AMP_MUTE, bits); 17662 HDA_AMP_MUTE, bits);
@@ -16725,9 +17669,7 @@ static void alc663_g71v_front_automute(struct hda_codec *codec)
16725 unsigned int present; 17669 unsigned int present;
16726 unsigned char bits; 17670 unsigned char bits;
16727 17671
16728 present = snd_hda_codec_read(codec, 0x15, 0, 17672 present = snd_hda_jack_detect(codec, 0x15);
16729 AC_VERB_GET_PIN_SENSE, 0)
16730 & AC_PINSENSE_PRESENCE;
16731 bits = present ? HDA_AMP_MUTE : 0; 17673 bits = present ? HDA_AMP_MUTE : 0;
16732 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 17674 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16733 HDA_AMP_MUTE, bits); 17675 HDA_AMP_MUTE, bits);
@@ -16843,6 +17785,8 @@ static const char *alc662_models[ALC662_MODEL_LAST] = {
16843 [ALC663_ASUS_MODE4] = "asus-mode4", 17785 [ALC663_ASUS_MODE4] = "asus-mode4",
16844 [ALC663_ASUS_MODE5] = "asus-mode5", 17786 [ALC663_ASUS_MODE5] = "asus-mode5",
16845 [ALC663_ASUS_MODE6] = "asus-mode6", 17787 [ALC663_ASUS_MODE6] = "asus-mode6",
17788 [ALC663_ASUS_MODE7] = "asus-mode7",
17789 [ALC663_ASUS_MODE8] = "asus-mode8",
16846 [ALC272_DELL] = "dell", 17790 [ALC272_DELL] = "dell",
16847 [ALC272_DELL_ZM1] = "dell-zm1", 17791 [ALC272_DELL_ZM1] = "dell-zm1",
16848 [ALC272_SAMSUNG_NC10] = "samsung-nc10", 17792 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
@@ -16855,16 +17799,27 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = {
16855 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1), 17799 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
16856 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1), 17800 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
16857 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3), 17801 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
17802 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
16858 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3), 17803 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
16859 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1), 17804 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
16860 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2), 17805 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
16861 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1), 17806 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
17807 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
17808 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
16862 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2), 17809 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
17810 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
17811 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
17812 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
17813 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
17814 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
16863 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2), 17815 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
17816 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
17817 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
16864 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2), 17818 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
16865 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6), 17819 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
16866 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6), 17820 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
16867 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2), 17821 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
17822 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
16868 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3), 17823 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
16869 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA), 17824 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
16870 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2), 17825 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
@@ -16880,6 +17835,7 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = {
16880 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3), 17835 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
16881 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3), 17836 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
16882 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1), 17837 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
17838 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
16883 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1), 17839 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
16884 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1), 17840 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
16885 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1), 17841 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
@@ -16903,10 +17859,11 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = {
16903 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS), 17859 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
16904 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K", 17860 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
16905 ALC662_3ST_6ch_DIG), 17861 ALC662_3ST_6ch_DIG),
16906 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB200", ALC663_ASUS_MODE4), 17862 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
16907 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10), 17863 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
16908 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L", 17864 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
16909 ALC662_3ST_6ch_DIG), 17865 ALC662_3ST_6ch_DIG),
17866 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
16910 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG), 17867 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
16911 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA), 17868 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
16912 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E), 17869 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
@@ -17147,6 +18104,36 @@ static struct alc_config_preset alc662_presets[] = {
17147 .setup = alc663_mode6_setup, 18104 .setup = alc663_mode6_setup,
17148 .init_hook = alc663_mode6_inithook, 18105 .init_hook = alc663_mode6_inithook,
17149 }, 18106 },
18107 [ALC663_ASUS_MODE7] = {
18108 .mixers = { alc663_mode7_mixer },
18109 .cap_mixer = alc662_auto_capture_mixer,
18110 .init_verbs = { alc662_init_verbs,
18111 alc663_mode7_init_verbs },
18112 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18113 .hp_nid = 0x03,
18114 .dac_nids = alc662_dac_nids,
18115 .dig_out_nid = ALC662_DIGOUT_NID,
18116 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18117 .channel_mode = alc662_3ST_2ch_modes,
18118 .unsol_event = alc663_mode7_unsol_event,
18119 .setup = alc663_mode7_setup,
18120 .init_hook = alc663_mode7_inithook,
18121 },
18122 [ALC663_ASUS_MODE8] = {
18123 .mixers = { alc663_mode8_mixer },
18124 .cap_mixer = alc662_auto_capture_mixer,
18125 .init_verbs = { alc662_init_verbs,
18126 alc663_mode8_init_verbs },
18127 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18128 .hp_nid = 0x03,
18129 .dac_nids = alc662_dac_nids,
18130 .dig_out_nid = ALC662_DIGOUT_NID,
18131 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18132 .channel_mode = alc662_3ST_2ch_modes,
18133 .unsol_event = alc663_mode8_unsol_event,
18134 .setup = alc663_mode8_setup,
18135 .init_hook = alc663_mode8_inithook,
18136 },
17150 [ALC272_DELL] = { 18137 [ALC272_DELL] = {
17151 .mixers = { alc663_m51va_mixer }, 18138 .mixers = { alc663_m51va_mixer },
17152 .cap_mixer = alc272_auto_capture_mixer, 18139 .cap_mixer = alc272_auto_capture_mixer,
@@ -17264,21 +18251,17 @@ static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
17264 return 0; 18251 return 0;
17265} 18252}
17266 18253
17267static int alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx, 18254static inline int alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
17268 hda_nid_t nid, unsigned int chs) 18255 hda_nid_t nid, unsigned int chs)
17269{ 18256{
17270 char name[32]; 18257 return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
17271 sprintf(name, "%s Playback Volume", pfx);
17272 return add_control(spec, ALC_CTL_WIDGET_VOL, name,
17273 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); 18258 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
17274} 18259}
17275 18260
17276static int alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx, 18261static inline int alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
17277 hda_nid_t nid, unsigned int chs) 18262 hda_nid_t nid, unsigned int chs)
17278{ 18263{
17279 char name[32]; 18264 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
17280 sprintf(name, "%s Playback Switch", pfx);
17281 return add_control(spec, ALC_CTL_WIDGET_MUTE, name,
17282 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT)); 18265 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
17283} 18266}
17284 18267
@@ -17356,13 +18339,11 @@ static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
17356 return 0; 18339 return 0;
17357 nid = alc662_look_for_dac(codec, pin); 18340 nid = alc662_look_for_dac(codec, pin);
17358 if (!nid) { 18341 if (!nid) {
17359 char name[32];
17360 /* the corresponding DAC is already occupied */ 18342 /* the corresponding DAC is already occupied */
17361 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP)) 18343 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
17362 return 0; /* no way */ 18344 return 0; /* no way */
17363 /* create a switch only */ 18345 /* create a switch only */
17364 sprintf(name, "%s Playback Switch", pfx); 18346 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
17365 return add_control(spec, ALC_CTL_WIDGET_MUTE, name,
17366 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 18347 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
17367 } 18348 }
17368 18349
@@ -17500,15 +18481,23 @@ static int alc662_parse_auto_config(struct hda_codec *codec)
17500 spec->num_mux_defs = 1; 18481 spec->num_mux_defs = 1;
17501 spec->input_mux = &spec->private_imux[0]; 18482 spec->input_mux = &spec->private_imux[0];
17502 18483
17503 add_verb(spec, alc662_auto_init_verbs); 18484 add_verb(spec, alc662_init_verbs);
17504 if (codec->vendor_id == 0x10ec0663) 18485 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
17505 add_verb(spec, alc663_auto_init_verbs); 18486 codec->vendor_id == 0x10ec0665)
18487 add_verb(spec, alc663_init_verbs);
18488
18489 if (codec->vendor_id == 0x10ec0272)
18490 add_verb(spec, alc272_init_verbs);
17506 18491
17507 err = alc_auto_add_mic_boost(codec); 18492 err = alc_auto_add_mic_boost(codec);
17508 if (err < 0) 18493 if (err < 0)
17509 return err; 18494 return err;
17510 18495
17511 alc_ssid_check(codec, 0x15, 0x1b, 0x14); 18496 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
18497 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
18498 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
18499 else
18500 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
17512 18501
17513 return 1; 18502 return 1;
17514} 18503}
@@ -17538,6 +18527,15 @@ static int patch_alc662(struct hda_codec *codec)
17538 18527
17539 alc_fix_pll_init(codec, 0x20, 0x04, 15); 18528 alc_fix_pll_init(codec, 0x20, 0x04, 15);
17540 18529
18530 if (alc_read_coef_idx(codec, 0)==0x8020){
18531 kfree(codec->chip_name);
18532 codec->chip_name = kstrdup("ALC661", GFP_KERNEL);
18533 if (!codec->chip_name) {
18534 alc_free(codec);
18535 return -ENOMEM;
18536 }
18537 }
18538
17541 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST, 18539 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
17542 alc662_models, 18540 alc662_models,
17543 alc662_cfg_tbl); 18541 alc662_cfg_tbl);
@@ -17585,11 +18583,20 @@ static int patch_alc662(struct hda_codec *codec)
17585 18583
17586 if (!spec->cap_mixer) 18584 if (!spec->cap_mixer)
17587 set_capture_mixer(codec); 18585 set_capture_mixer(codec);
17588 if (codec->vendor_id == 0x10ec0662) 18586
18587 switch (codec->vendor_id) {
18588 case 0x10ec0662:
17589 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 18589 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
17590 else 18590 break;
18591 case 0x10ec0272:
18592 case 0x10ec0663:
18593 case 0x10ec0665:
17591 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); 18594 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
17592 18595 break;
18596 case 0x10ec0273:
18597 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
18598 break;
18599 }
17593 spec->vmaster_nid = 0x02; 18600 spec->vmaster_nid = 0x02;
17594 18601
17595 codec->patch_ops = alc_patch_ops; 18602 codec->patch_ops = alc_patch_ops;
@@ -17599,11 +18606,24 @@ static int patch_alc662(struct hda_codec *codec)
17599 if (!spec->loopback.amplist) 18606 if (!spec->loopback.amplist)
17600 spec->loopback.amplist = alc662_loopbacks; 18607 spec->loopback.amplist = alc662_loopbacks;
17601#endif 18608#endif
17602 codec->proc_widget_hook = print_realtek_coef;
17603 18609
17604 return 0; 18610 return 0;
17605} 18611}
17606 18612
18613static int patch_alc888(struct hda_codec *codec)
18614{
18615 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
18616 kfree(codec->chip_name);
18617 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
18618 if (!codec->chip_name) {
18619 alc_free(codec);
18620 return -ENOMEM;
18621 }
18622 return patch_alc662(codec);
18623 }
18624 return patch_alc882(codec);
18625}
18626
17607/* 18627/*
17608 * patch entries 18628 * patch entries
17609 */ 18629 */
@@ -17613,7 +18633,9 @@ static struct hda_codec_preset snd_hda_preset_realtek[] = {
17613 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 }, 18633 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
17614 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 }, 18634 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
17615 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 }, 18635 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
18636 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
17616 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 }, 18637 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
18638 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
17617 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", 18639 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
17618 .patch = patch_alc861 }, 18640 .patch = patch_alc861 },
17619 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, 18641 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
@@ -17624,6 +18646,8 @@ static struct hda_codec_preset snd_hda_preset_realtek[] = {
17624 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1", 18646 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
17625 .patch = patch_alc662 }, 18647 .patch = patch_alc662 },
17626 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, 18648 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
18649 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
18650 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
17627 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, 18651 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
17628 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, 18652 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
17629 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 }, 18653 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
@@ -17635,8 +18659,9 @@ static struct hda_codec_preset snd_hda_preset_realtek[] = {
17635 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 }, 18659 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 },
17636 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200", 18660 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
17637 .patch = patch_alc882 }, 18661 .patch = patch_alc882 },
17638 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc882 }, 18662 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
17639 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 }, 18663 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
18664 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
17640 {} /* terminator */ 18665 {} /* terminator */
17641}; 18666};
17642 18667
diff --git a/sound/pci/hda/patch_si3054.c b/sound/pci/hda/patch_si3054.c
index 43b436c5d01b..f419ee8d75f0 100644
--- a/sound/pci/hda/patch_si3054.c
+++ b/sound/pci/hda/patch_si3054.c
@@ -122,6 +122,7 @@ static int si3054_switch_put(struct snd_kcontrol *kcontrol,
122#define SI3054_KCONTROL(kname,reg,mask) { \ 122#define SI3054_KCONTROL(kname,reg,mask) { \
123 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 123 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
124 .name = kname, \ 124 .name = kname, \
125 .subdevice = HDA_SUBDEV_NID_FLAG | reg, \
125 .info = si3054_switch_info, \ 126 .info = si3054_switch_info, \
126 .get = si3054_switch_get, \ 127 .get = si3054_switch_get, \
127 .put = si3054_switch_put, \ 128 .put = si3054_switch_put, \
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 86de305fc9f2..a0e06d82da1f 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -93,6 +93,7 @@ enum {
93 STAC_92HD83XXX_REF, 93 STAC_92HD83XXX_REF,
94 STAC_92HD83XXX_PWR_REF, 94 STAC_92HD83XXX_PWR_REF,
95 STAC_DELL_S14, 95 STAC_DELL_S14,
96 STAC_92HD83XXX_HP,
96 STAC_92HD83XXX_MODELS 97 STAC_92HD83XXX_MODELS
97}; 98};
98 99
@@ -103,6 +104,7 @@ enum {
103 STAC_DELL_M4_2, 104 STAC_DELL_M4_2,
104 STAC_DELL_M4_3, 105 STAC_DELL_M4_3,
105 STAC_HP_M4, 106 STAC_HP_M4,
107 STAC_HP_DV4,
106 STAC_HP_DV5, 108 STAC_HP_DV5,
107 STAC_HP_HDX, 109 STAC_HP_HDX,
108 STAC_HP_DV4_1222NR, 110 STAC_HP_DV4_1222NR,
@@ -208,6 +210,7 @@ struct sigmatel_spec {
208 unsigned int gpio_data; 210 unsigned int gpio_data;
209 unsigned int gpio_mute; 211 unsigned int gpio_mute;
210 unsigned int gpio_led; 212 unsigned int gpio_led;
213 unsigned int gpio_led_polarity;
211 214
212 /* stream */ 215 /* stream */
213 unsigned int stream_delay; 216 unsigned int stream_delay;
@@ -566,6 +569,11 @@ static hda_nid_t stac92hd83xxx_pin_nids[10] = {
566 0x0f, 0x10, 0x11, 0x1f, 0x20, 569 0x0f, 0x10, 0x11, 0x1f, 0x20,
567}; 570};
568 571
572static hda_nid_t stac92hd88xxx_pin_nids[10] = {
573 0x0a, 0x0b, 0x0c, 0x0d,
574 0x0f, 0x11, 0x1f, 0x20,
575};
576
569#define STAC92HD71BXX_NUM_PINS 13 577#define STAC92HD71BXX_NUM_PINS 13
570static hda_nid_t stac92hd71bxx_pin_nids_4port[STAC92HD71BXX_NUM_PINS] = { 578static hda_nid_t stac92hd71bxx_pin_nids_4port[STAC92HD71BXX_NUM_PINS] = {
571 0x0a, 0x0b, 0x0c, 0x0d, 0x00, 579 0x0a, 0x0b, 0x0c, 0x0d, 0x00,
@@ -1085,7 +1093,7 @@ static int stac92xx_build_controls(struct hda_codec *codec)
1085 if (!spec->auto_mic && spec->num_dmuxes > 0 && 1093 if (!spec->auto_mic && spec->num_dmuxes > 0 &&
1086 snd_hda_get_bool_hint(codec, "separate_dmux") == 1) { 1094 snd_hda_get_bool_hint(codec, "separate_dmux") == 1) {
1087 stac_dmux_mixer.count = spec->num_dmuxes; 1095 stac_dmux_mixer.count = spec->num_dmuxes;
1088 err = snd_hda_ctl_add(codec, 1096 err = snd_hda_ctl_add(codec, 0,
1089 snd_ctl_new1(&stac_dmux_mixer, codec)); 1097 snd_ctl_new1(&stac_dmux_mixer, codec));
1090 if (err < 0) 1098 if (err < 0)
1091 return err; 1099 return err;
@@ -1101,7 +1109,7 @@ static int stac92xx_build_controls(struct hda_codec *codec)
1101 spec->spdif_mute = 1; 1109 spec->spdif_mute = 1;
1102 } 1110 }
1103 stac_smux_mixer.count = spec->num_smuxes; 1111 stac_smux_mixer.count = spec->num_smuxes;
1104 err = snd_hda_ctl_add(codec, 1112 err = snd_hda_ctl_add(codec, 0,
1105 snd_ctl_new1(&stac_smux_mixer, codec)); 1113 snd_ctl_new1(&stac_smux_mixer, codec));
1106 if (err < 0) 1114 if (err < 0)
1107 return err; 1115 return err;
@@ -1537,6 +1545,11 @@ static unsigned int alienware_m17x_pin_configs[13] = {
1537 0x904601b0, 1545 0x904601b0,
1538}; 1546};
1539 1547
1548static unsigned int intel_dg45id_pin_configs[13] = {
1549 0x02214230, 0x02A19240, 0x01013214, 0x01014210,
1550 0x01A19250, 0x01011212, 0x01016211
1551};
1552
1540static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = { 1553static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = {
1541 [STAC_92HD73XX_REF] = ref92hd73xx_pin_configs, 1554 [STAC_92HD73XX_REF] = ref92hd73xx_pin_configs,
1542 [STAC_DELL_M6_AMIC] = dell_m6_pin_configs, 1555 [STAC_DELL_M6_AMIC] = dell_m6_pin_configs,
@@ -1544,6 +1557,7 @@ static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = {
1544 [STAC_DELL_M6_BOTH] = dell_m6_pin_configs, 1557 [STAC_DELL_M6_BOTH] = dell_m6_pin_configs,
1545 [STAC_DELL_EQ] = dell_m6_pin_configs, 1558 [STAC_DELL_EQ] = dell_m6_pin_configs,
1546 [STAC_ALIENWARE_M17X] = alienware_m17x_pin_configs, 1559 [STAC_ALIENWARE_M17X] = alienware_m17x_pin_configs,
1560 [STAC_92HD73XX_INTEL] = intel_dg45id_pin_configs,
1547}; 1561};
1548 1562
1549static const char *stac92hd73xx_models[STAC_92HD73XX_MODELS] = { 1563static const char *stac92hd73xx_models[STAC_92HD73XX_MODELS] = {
@@ -1592,6 +1606,10 @@ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = {
1592 "Dell Studio 1555", STAC_DELL_M6_DMIC), 1606 "Dell Studio 1555", STAC_DELL_M6_DMIC),
1593 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02bd, 1607 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02bd,
1594 "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),
1595 {} /* terminator */ 1613 {} /* terminator */
1596}; 1614};
1597 1615
@@ -1624,6 +1642,7 @@ static const char *stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = {
1624 [STAC_92HD83XXX_REF] = "ref", 1642 [STAC_92HD83XXX_REF] = "ref",
1625 [STAC_92HD83XXX_PWR_REF] = "mic-ref", 1643 [STAC_92HD83XXX_PWR_REF] = "mic-ref",
1626 [STAC_DELL_S14] = "dell-s14", 1644 [STAC_DELL_S14] = "dell-s14",
1645 [STAC_92HD83XXX_HP] = "hp",
1627}; 1646};
1628 1647
1629static struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { 1648static struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = {
@@ -1634,6 +1653,8 @@ static struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = {
1634 "DFI LanParty", STAC_92HD83XXX_REF), 1653 "DFI LanParty", STAC_92HD83XXX_REF),
1635 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ba, 1654 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ba,
1636 "unknown Dell", STAC_DELL_S14), 1655 "unknown Dell", STAC_DELL_S14),
1656 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x3600,
1657 "HP", STAC_92HD83XXX_HP),
1637 {} /* terminator */ 1658 {} /* terminator */
1638}; 1659};
1639 1660
@@ -1671,6 +1692,7 @@ static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = {
1671 [STAC_DELL_M4_2] = dell_m4_2_pin_configs, 1692 [STAC_DELL_M4_2] = dell_m4_2_pin_configs,
1672 [STAC_DELL_M4_3] = dell_m4_3_pin_configs, 1693 [STAC_DELL_M4_3] = dell_m4_3_pin_configs,
1673 [STAC_HP_M4] = NULL, 1694 [STAC_HP_M4] = NULL,
1695 [STAC_HP_DV4] = NULL,
1674 [STAC_HP_DV5] = NULL, 1696 [STAC_HP_DV5] = NULL,
1675 [STAC_HP_HDX] = NULL, 1697 [STAC_HP_HDX] = NULL,
1676 [STAC_HP_DV4_1222NR] = NULL, 1698 [STAC_HP_DV4_1222NR] = NULL,
@@ -1683,6 +1705,7 @@ static const char *stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = {
1683 [STAC_DELL_M4_2] = "dell-m4-2", 1705 [STAC_DELL_M4_2] = "dell-m4-2",
1684 [STAC_DELL_M4_3] = "dell-m4-3", 1706 [STAC_DELL_M4_3] = "dell-m4-3",
1685 [STAC_HP_M4] = "hp-m4", 1707 [STAC_HP_M4] = "hp-m4",
1708 [STAC_HP_DV4] = "hp-dv4",
1686 [STAC_HP_DV5] = "hp-dv5", 1709 [STAC_HP_DV5] = "hp-dv5",
1687 [STAC_HP_HDX] = "hp-hdx", 1710 [STAC_HP_HDX] = "hp-hdx",
1688 [STAC_HP_DV4_1222NR] = "hp-dv4-1222nr", 1711 [STAC_HP_DV4_1222NR] = "hp-dv4-1222nr",
@@ -1701,7 +1724,7 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = {
1701 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3080, 1724 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3080,
1702 "HP", STAC_HP_DV5), 1725 "HP", STAC_HP_DV5),
1703 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x30f0, 1726 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x30f0,
1704 "HP dv4-7", STAC_HP_DV5), 1727 "HP dv4-7", STAC_HP_DV4),
1705 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3600, 1728 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3600,
1706 "HP dv4-7", STAC_HP_DV5), 1729 "HP dv4-7", STAC_HP_DV5),
1707 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3610, 1730 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3610,
@@ -1712,6 +1735,8 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = {
1712 "HP HDX", STAC_HP_HDX), /* HDX16 */ 1735 "HP HDX", STAC_HP_HDX), /* HDX16 */
1713 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3620, 1736 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3620,
1714 "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 */
1715 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x7010, 1740 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x7010,
1716 "HP", STAC_HP_DV5), 1741 "HP", STAC_HP_DV5),
1717 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233, 1742 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233,
@@ -2091,6 +2116,7 @@ static unsigned int ref9205_pin_configs[12] = {
2091 10280204 2116 10280204
2092 1028021F 2117 1028021F
2093 10280228 (Dell Vostro 1500) 2118 10280228 (Dell Vostro 1500)
2119 10280229 (Dell Vostro 1700)
2094*/ 2120*/
2095static unsigned int dell_9205_m42_pin_configs[12] = { 2121static unsigned int dell_9205_m42_pin_configs[12] = {
2096 0x0321101F, 0x03A11020, 0x400003FA, 0x90170310, 2122 0x0321101F, 0x03A11020, 0x400003FA, 0x90170310,
@@ -2176,6 +2202,8 @@ static struct snd_pci_quirk stac9205_cfg_tbl[] = {
2176 "Dell Inspiron", STAC_9205_DELL_M44), 2202 "Dell Inspiron", STAC_9205_DELL_M44),
2177 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0228, 2203 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0228,
2178 "Dell Vostro 1500", STAC_9205_DELL_M42), 2204 "Dell Vostro 1500", STAC_9205_DELL_M42),
2205 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0229,
2206 "Dell Vostro 1700", STAC_9205_DELL_M42),
2179 /* Gateway */ 2207 /* Gateway */
2180 SND_PCI_QUIRK(0x107b, 0x0560, "Gateway T6834c", STAC_9205_EAPD), 2208 SND_PCI_QUIRK(0x107b, 0x0560, "Gateway T6834c", STAC_9205_EAPD),
2181 SND_PCI_QUIRK(0x107b, 0x0565, "Gateway T1616", STAC_9205_EAPD), 2209 SND_PCI_QUIRK(0x107b, 0x0565, "Gateway T1616", STAC_9205_EAPD),
@@ -2648,6 +2676,7 @@ static int stac92xx_clfe_switch_put(struct snd_kcontrol *kcontrol,
2648enum { 2676enum {
2649 STAC_CTL_WIDGET_VOL, 2677 STAC_CTL_WIDGET_VOL,
2650 STAC_CTL_WIDGET_MUTE, 2678 STAC_CTL_WIDGET_MUTE,
2679 STAC_CTL_WIDGET_MUTE_BEEP,
2651 STAC_CTL_WIDGET_MONO_MUX, 2680 STAC_CTL_WIDGET_MONO_MUX,
2652 STAC_CTL_WIDGET_HP_SWITCH, 2681 STAC_CTL_WIDGET_HP_SWITCH,
2653 STAC_CTL_WIDGET_IO_SWITCH, 2682 STAC_CTL_WIDGET_IO_SWITCH,
@@ -2658,6 +2687,7 @@ enum {
2658static struct snd_kcontrol_new stac92xx_control_templates[] = { 2687static struct snd_kcontrol_new stac92xx_control_templates[] = {
2659 HDA_CODEC_VOLUME(NULL, 0, 0, 0), 2688 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
2660 HDA_CODEC_MUTE(NULL, 0, 0, 0), 2689 HDA_CODEC_MUTE(NULL, 0, 0, 0),
2690 HDA_CODEC_MUTE_BEEP(NULL, 0, 0, 0),
2661 STAC_MONO_MUX, 2691 STAC_MONO_MUX,
2662 STAC_CODEC_HP_SWITCH(NULL), 2692 STAC_CODEC_HP_SWITCH(NULL),
2663 STAC_CODEC_IO_SWITCH(NULL, 0), 2693 STAC_CODEC_IO_SWITCH(NULL, 0),
@@ -2669,7 +2699,8 @@ static struct snd_kcontrol_new stac92xx_control_templates[] = {
2669static struct snd_kcontrol_new * 2699static struct snd_kcontrol_new *
2670stac_control_new(struct sigmatel_spec *spec, 2700stac_control_new(struct sigmatel_spec *spec,
2671 struct snd_kcontrol_new *ktemp, 2701 struct snd_kcontrol_new *ktemp,
2672 const char *name) 2702 const char *name,
2703 unsigned int subdev)
2673{ 2704{
2674 struct snd_kcontrol_new *knew; 2705 struct snd_kcontrol_new *knew;
2675 2706
@@ -2685,6 +2716,7 @@ stac_control_new(struct sigmatel_spec *spec,
2685 spec->kctls.alloced--; 2716 spec->kctls.alloced--;
2686 return NULL; 2717 return NULL;
2687 } 2718 }
2719 knew->subdevice = subdev;
2688 return knew; 2720 return knew;
2689} 2721}
2690 2722
@@ -2693,7 +2725,8 @@ static int stac92xx_add_control_temp(struct sigmatel_spec *spec,
2693 int idx, const char *name, 2725 int idx, const char *name,
2694 unsigned long val) 2726 unsigned long val)
2695{ 2727{
2696 struct snd_kcontrol_new *knew = stac_control_new(spec, ktemp, name); 2728 struct snd_kcontrol_new *knew = stac_control_new(spec, ktemp, name,
2729 HDA_SUBDEV_AMP_FLAG);
2697 if (!knew) 2730 if (!knew)
2698 return -ENOMEM; 2731 return -ENOMEM;
2699 knew->index = idx; 2732 knew->index = idx;
@@ -2764,7 +2797,7 @@ static int stac92xx_add_input_source(struct sigmatel_spec *spec)
2764 if (!spec->num_adcs || imux->num_items <= 1) 2797 if (!spec->num_adcs || imux->num_items <= 1)
2765 return 0; /* no need for input source control */ 2798 return 0; /* no need for input source control */
2766 knew = stac_control_new(spec, &stac_input_src_temp, 2799 knew = stac_control_new(spec, &stac_input_src_temp,
2767 stac_input_src_temp.name); 2800 stac_input_src_temp.name, 0);
2768 if (!knew) 2801 if (!knew)
2769 return -ENOMEM; 2802 return -ENOMEM;
2770 knew->count = spec->num_adcs; 2803 knew->count = spec->num_adcs;
@@ -2852,6 +2885,13 @@ static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t nid)
2852 2885
2853 conn_len = snd_hda_get_connections(codec, nid, conn, 2886 conn_len = snd_hda_get_connections(codec, nid, conn,
2854 HDA_MAX_CONNECTIONS); 2887 HDA_MAX_CONNECTIONS);
2888 /* 92HD88: trace back up the link of nids to find the DAC */
2889 while (conn_len == 1 && (get_wcaps_type(get_wcaps(codec, conn[0]))
2890 != AC_WID_AUD_OUT)) {
2891 nid = conn[0];
2892 conn_len = snd_hda_get_connections(codec, nid, conn,
2893 HDA_MAX_CONNECTIONS);
2894 }
2855 for (j = 0; j < conn_len; j++) { 2895 for (j = 0; j < conn_len; j++) {
2856 wcaps = get_wcaps(codec, conn[j]); 2896 wcaps = get_wcaps(codec, conn[j]);
2857 wtype = get_wcaps_type(wcaps); 2897 wtype = get_wcaps_type(wcaps);
@@ -3221,12 +3261,15 @@ static int stac92xx_auto_create_beep_ctls(struct hda_codec *codec,
3221{ 3261{
3222 struct sigmatel_spec *spec = codec->spec; 3262 struct sigmatel_spec *spec = codec->spec;
3223 u32 caps = query_amp_caps(codec, nid, HDA_OUTPUT); 3263 u32 caps = query_amp_caps(codec, nid, HDA_OUTPUT);
3224 int err; 3264 int err, type = STAC_CTL_WIDGET_MUTE_BEEP;
3265
3266 if (spec->anabeep_nid == nid)
3267 type = STAC_CTL_WIDGET_MUTE;
3225 3268
3226 /* check for mute support for the the amp */ 3269 /* check for mute support for the the amp */
3227 if ((caps & AC_AMPCAP_MUTE) >> AC_AMPCAP_MUTE_SHIFT) { 3270 if ((caps & AC_AMPCAP_MUTE) >> AC_AMPCAP_MUTE_SHIFT) {
3228 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, 3271 err = stac92xx_add_control(spec, type,
3229 "PC Beep Playback Switch", 3272 "Beep Playback Switch",
3230 HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT)); 3273 HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT));
3231 if (err < 0) 3274 if (err < 0)
3232 return err; 3275 return err;
@@ -3235,7 +3278,7 @@ static int stac92xx_auto_create_beep_ctls(struct hda_codec *codec,
3235 /* check to see if there is volume support for the amp */ 3278 /* check to see if there is volume support for the amp */
3236 if ((caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT) { 3279 if ((caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT) {
3237 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, 3280 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL,
3238 "PC Beep Playback Volume", 3281 "Beep Playback Volume",
3239 HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT)); 3282 HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT));
3240 if (err < 0) 3283 if (err < 0)
3241 return err; 3284 return err;
@@ -3258,12 +3301,7 @@ static int stac92xx_dig_beep_switch_put(struct snd_kcontrol *kcontrol,
3258 struct snd_ctl_elem_value *ucontrol) 3301 struct snd_ctl_elem_value *ucontrol)
3259{ 3302{
3260 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 3303 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3261 int enabled = !!ucontrol->value.integer.value[0]; 3304 return snd_hda_enable_beep_device(codec, ucontrol->value.integer.value[0]);
3262 if (codec->beep->enabled != enabled) {
3263 codec->beep->enabled = enabled;
3264 return 1;
3265 }
3266 return 0;
3267} 3305}
3268 3306
3269static struct snd_kcontrol_new stac92xx_dig_beep_ctrl = { 3307static struct snd_kcontrol_new stac92xx_dig_beep_ctrl = {
@@ -3276,7 +3314,7 @@ static struct snd_kcontrol_new stac92xx_dig_beep_ctrl = {
3276static int stac92xx_beep_switch_ctl(struct hda_codec *codec) 3314static int stac92xx_beep_switch_ctl(struct hda_codec *codec)
3277{ 3315{
3278 return stac92xx_add_control_temp(codec->spec, &stac92xx_dig_beep_ctrl, 3316 return stac92xx_add_control_temp(codec->spec, &stac92xx_dig_beep_ctrl,
3279 0, "PC Beep Playback Switch", 0); 3317 0, "Beep Playback Switch", 0);
3280} 3318}
3281#endif 3319#endif
3282 3320
@@ -3631,6 +3669,26 @@ static void stac92xx_auto_init_hp_out(struct hda_codec *codec)
3631 } 3669 }
3632} 3670}
3633 3671
3672static int is_dual_headphones(struct hda_codec *codec)
3673{
3674 struct sigmatel_spec *spec = codec->spec;
3675 int i, valid_hps;
3676
3677 if (spec->autocfg.line_out_type != AUTO_PIN_SPEAKER_OUT ||
3678 spec->autocfg.hp_outs <= 1)
3679 return 0;
3680 valid_hps = 0;
3681 for (i = 0; i < spec->autocfg.hp_outs; i++) {
3682 hda_nid_t nid = spec->autocfg.hp_pins[i];
3683 unsigned int cfg = snd_hda_codec_get_pincfg(codec, nid);
3684 if (get_defcfg_location(cfg) & AC_JACK_LOC_SEPARATE)
3685 continue;
3686 valid_hps++;
3687 }
3688 return (valid_hps > 1);
3689}
3690
3691
3634static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out, hda_nid_t dig_in) 3692static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out, hda_nid_t dig_in)
3635{ 3693{
3636 struct sigmatel_spec *spec = codec->spec; 3694 struct sigmatel_spec *spec = codec->spec;
@@ -3647,8 +3705,7 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
3647 /* If we have no real line-out pin and multiple hp-outs, HPs should 3705 /* If we have no real line-out pin and multiple hp-outs, HPs should
3648 * be set up as multi-channel outputs. 3706 * be set up as multi-channel outputs.
3649 */ 3707 */
3650 if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT && 3708 if (is_dual_headphones(codec)) {
3651 spec->autocfg.hp_outs > 1) {
3652 /* Copy hp_outs to line_outs, backup line_outs in 3709 /* Copy hp_outs to line_outs, backup line_outs in
3653 * speaker_outs so that the following routines can handle 3710 * speaker_outs so that the following routines can handle
3654 * HP pins as primary outputs. 3711 * HP pins as primary outputs.
@@ -3743,15 +3800,16 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
3743 err = snd_hda_attach_beep_device(codec, nid); 3800 err = snd_hda_attach_beep_device(codec, nid);
3744 if (err < 0) 3801 if (err < 0)
3745 return err; 3802 return err;
3746 /* IDT/STAC codecs have linear beep tone parameter */ 3803 if (codec->beep) {
3747 codec->beep->linear_tone = 1; 3804 /* IDT/STAC codecs have linear beep tone parameter */
3748 /* if no beep switch is available, make its own one */ 3805 codec->beep->linear_tone = 1;
3749 caps = query_amp_caps(codec, nid, HDA_OUTPUT); 3806 /* if no beep switch is available, make its own one */
3750 if (codec->beep && 3807 caps = query_amp_caps(codec, nid, HDA_OUTPUT);
3751 !((caps & AC_AMPCAP_MUTE) >> AC_AMPCAP_MUTE_SHIFT)) { 3808 if (!(caps & AC_AMPCAP_MUTE)) {
3752 err = stac92xx_beep_switch_ctl(codec); 3809 err = stac92xx_beep_switch_ctl(codec);
3753 if (err < 0) 3810 if (err < 0)
3754 return err; 3811 return err;
3812 }
3755 } 3813 }
3756 } 3814 }
3757#endif 3815#endif
@@ -4120,34 +4178,52 @@ static void stac92xx_power_down(struct hda_codec *codec)
4120static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid, 4178static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid,
4121 int enable); 4179 int enable);
4122 4180
4181static inline int get_int_hint(struct hda_codec *codec, const char *key,
4182 int *valp)
4183{
4184 const char *p;
4185 p = snd_hda_get_hint(codec, key);
4186 if (p) {
4187 unsigned long val;
4188 if (!strict_strtoul(p, 0, &val)) {
4189 *valp = val;
4190 return 1;
4191 }
4192 }
4193 return 0;
4194}
4195
4123/* override some hints from the hwdep entry */ 4196/* override some hints from the hwdep entry */
4124static void stac_store_hints(struct hda_codec *codec) 4197static void stac_store_hints(struct hda_codec *codec)
4125{ 4198{
4126 struct sigmatel_spec *spec = codec->spec; 4199 struct sigmatel_spec *spec = codec->spec;
4127 const char *p;
4128 int val; 4200 int val;
4129 4201
4130 val = snd_hda_get_bool_hint(codec, "hp_detect"); 4202 val = snd_hda_get_bool_hint(codec, "hp_detect");
4131 if (val >= 0) 4203 if (val >= 0)
4132 spec->hp_detect = val; 4204 spec->hp_detect = val;
4133 p = snd_hda_get_hint(codec, "gpio_mask"); 4205 if (get_int_hint(codec, "gpio_mask", &spec->gpio_mask)) {
4134 if (p) {
4135 spec->gpio_mask = simple_strtoul(p, NULL, 0);
4136 spec->eapd_mask = spec->gpio_dir = spec->gpio_data = 4206 spec->eapd_mask = spec->gpio_dir = spec->gpio_data =
4137 spec->gpio_mask; 4207 spec->gpio_mask;
4138 } 4208 }
4139 p = snd_hda_get_hint(codec, "gpio_dir"); 4209 if (get_int_hint(codec, "gpio_dir", &spec->gpio_dir))
4140 if (p) 4210 spec->gpio_mask &= spec->gpio_mask;
4141 spec->gpio_dir = simple_strtoul(p, NULL, 0) & spec->gpio_mask; 4211 if (get_int_hint(codec, "gpio_data", &spec->gpio_data))
4142 p = snd_hda_get_hint(codec, "gpio_data"); 4212 spec->gpio_dir &= spec->gpio_mask;
4143 if (p) 4213 if (get_int_hint(codec, "eapd_mask", &spec->eapd_mask))
4144 spec->gpio_data = simple_strtoul(p, NULL, 0) & spec->gpio_mask; 4214 spec->eapd_mask &= spec->gpio_mask;
4145 p = snd_hda_get_hint(codec, "eapd_mask"); 4215 if (get_int_hint(codec, "gpio_mute", &spec->gpio_mute))
4146 if (p) 4216 spec->gpio_mute &= spec->gpio_mask;
4147 spec->eapd_mask = simple_strtoul(p, NULL, 0) & spec->gpio_mask;
4148 val = snd_hda_get_bool_hint(codec, "eapd_switch"); 4217 val = snd_hda_get_bool_hint(codec, "eapd_switch");
4149 if (val >= 0) 4218 if (val >= 0)
4150 spec->eapd_switch = val; 4219 spec->eapd_switch = val;
4220 get_int_hint(codec, "gpio_led_polarity", &spec->gpio_led_polarity);
4221 if (get_int_hint(codec, "gpio_led", &spec->gpio_led)) {
4222 spec->gpio_mask |= spec->gpio_led;
4223 spec->gpio_dir |= spec->gpio_led;
4224 if (spec->gpio_led_polarity)
4225 spec->gpio_data |= spec->gpio_led;
4226 }
4151} 4227}
4152 4228
4153static int stac92xx_init(struct hda_codec *codec) 4229static int stac92xx_init(struct hda_codec *codec)
@@ -4294,6 +4370,12 @@ static int stac92xx_init(struct hda_codec *codec)
4294 if (enable_pin_detect(codec, nid, STAC_PWR_EVENT)) 4370 if (enable_pin_detect(codec, nid, STAC_PWR_EVENT))
4295 stac_issue_unsol_event(codec, nid); 4371 stac_issue_unsol_event(codec, nid);
4296 } 4372 }
4373
4374#ifdef CONFIG_SND_HDA_POWER_SAVE
4375 /* sync mute LED */
4376 if (spec->gpio_led && codec->patch_ops.check_power_status)
4377 codec->patch_ops.check_power_status(codec, 0x01);
4378#endif
4297 if (spec->dac_list) 4379 if (spec->dac_list)
4298 stac92xx_power_down(codec); 4380 stac92xx_power_down(codec);
4299 return 0; 4381 return 0;
@@ -4329,6 +4411,18 @@ static void stac92xx_free_kctls(struct hda_codec *codec)
4329 snd_array_free(&spec->kctls); 4411 snd_array_free(&spec->kctls);
4330} 4412}
4331 4413
4414static void stac92xx_shutup(struct hda_codec *codec)
4415{
4416 struct sigmatel_spec *spec = codec->spec;
4417
4418 snd_hda_shutup_pins(codec);
4419
4420 if (spec->eapd_mask)
4421 stac_gpio_set(codec, spec->gpio_mask,
4422 spec->gpio_dir, spec->gpio_data &
4423 ~spec->eapd_mask);
4424}
4425
4332static void stac92xx_free(struct hda_codec *codec) 4426static void stac92xx_free(struct hda_codec *codec)
4333{ 4427{
4334 struct sigmatel_spec *spec = codec->spec; 4428 struct sigmatel_spec *spec = codec->spec;
@@ -4336,6 +4430,7 @@ static void stac92xx_free(struct hda_codec *codec)
4336 if (! spec) 4430 if (! spec)
4337 return; 4431 return;
4338 4432
4433 stac92xx_shutup(codec);
4339 stac92xx_free_jacks(codec); 4434 stac92xx_free_jacks(codec);
4340 snd_array_free(&spec->events); 4435 snd_array_free(&spec->events);
4341 4436
@@ -4386,14 +4481,11 @@ static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid,
4386 pin_ctl & ~flag); 4481 pin_ctl & ~flag);
4387} 4482}
4388 4483
4389static int get_pin_presence(struct hda_codec *codec, hda_nid_t nid) 4484static inline int get_pin_presence(struct hda_codec *codec, hda_nid_t nid)
4390{ 4485{
4391 if (!nid) 4486 if (!nid)
4392 return 0; 4487 return 0;
4393 if (snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_SENSE, 0x00) 4488 return snd_hda_jack_detect(codec, nid);
4394 & (1 << 31))
4395 return 1;
4396 return 0;
4397} 4489}
4398 4490
4399static void stac92xx_line_out_detect(struct hda_codec *codec, 4491static void stac92xx_line_out_detect(struct hda_codec *codec,
@@ -4670,13 +4762,86 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
4670 } 4762 }
4671} 4763}
4672 4764
4673static int hp_bseries_system(u32 subsystem_id) 4765static int hp_blike_system(u32 subsystem_id);
4766
4767static void set_hp_led_gpio(struct hda_codec *codec)
4768{
4769 struct sigmatel_spec *spec = codec->spec;
4770 unsigned int gpio;
4771
4772 if (spec->gpio_led)
4773 return;
4774
4775 gpio = snd_hda_param_read(codec, codec->afg, AC_PAR_GPIO_CAP);
4776 gpio &= AC_GPIO_IO_COUNT;
4777 if (gpio > 3)
4778 spec->gpio_led = 0x08; /* GPIO 3 */
4779 else
4780 spec->gpio_led = 0x01; /* GPIO 0 */
4781}
4782
4783/*
4784 * This method searches for the mute LED GPIO configuration
4785 * provided as OEM string in SMBIOS. The format of that string
4786 * is HP_Mute_LED_P_G or HP_Mute_LED_P
4787 * where P can be 0 or 1 and defines mute LED GPIO control state (low/high)
4788 * that corresponds to the NOT muted state of the master volume
4789 * and G is the index of the GPIO to use as the mute LED control (0..9)
4790 * If _G portion is missing it is assigned based on the codec ID
4791 *
4792 * So, HP B-series like systems may have HP_Mute_LED_0 (current models)
4793 * or HP_Mute_LED_0_3 (future models) OEM SMBIOS strings
4794 *
4795 *
4796 * The dv-series laptops don't seem to have the HP_Mute_LED* strings in
4797 * SMBIOS - at least the ones I have seen do not have them - which include
4798 * my own system (HP Pavilion dv6-1110ax) and my cousin's
4799 * HP Pavilion dv9500t CTO.
4800 * Need more information on whether it is true across the entire series.
4801 * -- kunal
4802 */
4803static int find_mute_led_gpio(struct hda_codec *codec, int default_polarity)
4804{
4805 struct sigmatel_spec *spec = codec->spec;
4806 const struct dmi_device *dev = NULL;
4807
4808 if ((codec->subsystem_id >> 16) == PCI_VENDOR_ID_HP) {
4809 while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING,
4810 NULL, dev))) {
4811 if (sscanf(dev->name, "HP_Mute_LED_%d_%d",
4812 &spec->gpio_led_polarity,
4813 &spec->gpio_led) == 2) {
4814 spec->gpio_led = 1 << spec->gpio_led;
4815 return 1;
4816 }
4817 if (sscanf(dev->name, "HP_Mute_LED_%d",
4818 &spec->gpio_led_polarity) == 1) {
4819 set_hp_led_gpio(codec);
4820 return 1;
4821 }
4822 }
4823
4824 /*
4825 * Fallback case - if we don't find the DMI strings,
4826 * we statically set the GPIO - if not a B-series system.
4827 */
4828 if (!hp_blike_system(codec->subsystem_id)) {
4829 set_hp_led_gpio(codec);
4830 spec->gpio_led_polarity = default_polarity;
4831 return 1;
4832 }
4833 }
4834 return 0;
4835}
4836
4837static int hp_blike_system(u32 subsystem_id)
4674{ 4838{
4675 switch (subsystem_id) { 4839 switch (subsystem_id) {
4676 case 0x103c307e: 4840 case 0x103c1520:
4677 case 0x103c307f: 4841 case 0x103c1521:
4678 case 0x103c3080: 4842 case 0x103c1523:
4679 case 0x103c3081: 4843 case 0x103c1524:
4844 case 0x103c1525:
4680 case 0x103c1722: 4845 case 0x103c1722:
4681 case 0x103c1723: 4846 case 0x103c1723:
4682 case 0x103c1724: 4847 case 0x103c1724:
@@ -4685,6 +4850,14 @@ static int hp_bseries_system(u32 subsystem_id)
4685 case 0x103c1727: 4850 case 0x103c1727:
4686 case 0x103c1728: 4851 case 0x103c1728:
4687 case 0x103c1729: 4852 case 0x103c1729:
4853 case 0x103c172a:
4854 case 0x103c172b:
4855 case 0x103c307e:
4856 case 0x103c307f:
4857 case 0x103c3080:
4858 case 0x103c3081:
4859 case 0x103c7007:
4860 case 0x103c7008:
4688 return 1; 4861 return 1;
4689 } 4862 }
4690 return 0; 4863 return 0;
@@ -4752,6 +4925,11 @@ static int stac92xx_resume(struct hda_codec *codec)
4752 stac_issue_unsol_event(codec, 4925 stac_issue_unsol_event(codec,
4753 spec->autocfg.line_out_pins[0]); 4926 spec->autocfg.line_out_pins[0]);
4754 } 4927 }
4928#ifdef CONFIG_SND_HDA_POWER_SAVE
4929 /* sync mute LED */
4930 if (spec->gpio_led && codec->patch_ops.check_power_status)
4931 codec->patch_ops.check_power_status(codec, 0x01);
4932#endif
4755 return 0; 4933 return 0;
4756} 4934}
4757 4935
@@ -4771,48 +4949,34 @@ static int stac92xx_hp_check_power_status(struct hda_codec *codec,
4771 hda_nid_t nid) 4949 hda_nid_t nid)
4772{ 4950{
4773 struct sigmatel_spec *spec = codec->spec; 4951 struct sigmatel_spec *spec = codec->spec;
4952 int i, muted = 1;
4774 4953
4775 if (nid == 0x10) { 4954 for (i = 0; i < spec->multiout.num_dacs; i++) {
4776 if (snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) & 4955 nid = spec->multiout.dac_nids[i];
4777 HDA_AMP_MUTE) 4956 if (!(snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) &
4778 spec->gpio_data &= ~spec->gpio_led; /* orange */ 4957 HDA_AMP_MUTE)) {
4779 else 4958 muted = 0; /* something heard */
4780 spec->gpio_data |= spec->gpio_led; /* white */ 4959 break;
4781
4782 if (hp_bseries_system(codec->subsystem_id)) {
4783 /* LED state is inverted on these systems */
4784 spec->gpio_data ^= spec->gpio_led;
4785 } 4960 }
4961 }
4962 if (muted)
4963 spec->gpio_data &= ~spec->gpio_led; /* orange */
4964 else
4965 spec->gpio_data |= spec->gpio_led; /* white */
4786 4966
4787 stac_gpio_set(codec, spec->gpio_mask, 4967 if (!spec->gpio_led_polarity) {
4788 spec->gpio_dir, 4968 /* LED state is inverted on these systems */
4789 spec->gpio_data); 4969 spec->gpio_data ^= spec->gpio_led;
4790 } 4970 }
4791 4971
4972 stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data);
4792 return 0; 4973 return 0;
4793} 4974}
4794#endif 4975#endif
4795 4976
4796static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state) 4977static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state)
4797{ 4978{
4798 struct sigmatel_spec *spec = codec->spec; 4979 stac92xx_shutup(codec);
4799 int i;
4800 hda_nid_t nid;
4801
4802 /* reset each pin before powering down DAC/ADC to avoid click noise */
4803 nid = codec->start_nid;
4804 for (i = 0; i < codec->num_nodes; i++, nid++) {
4805 unsigned int wcaps = get_wcaps(codec, nid);
4806 unsigned int wid_type = get_wcaps_type(wcaps);
4807 if (wid_type == AC_WID_PIN)
4808 snd_hda_codec_read(codec, nid, 0,
4809 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
4810 }
4811
4812 if (spec->eapd_mask)
4813 stac_gpio_set(codec, spec->gpio_mask,
4814 spec->gpio_dir, spec->gpio_data &
4815 ~spec->eapd_mask);
4816 return 0; 4980 return 0;
4817} 4981}
4818#endif 4982#endif
@@ -4827,6 +4991,7 @@ static struct hda_codec_ops stac92xx_patch_ops = {
4827 .suspend = stac92xx_suspend, 4991 .suspend = stac92xx_suspend,
4828 .resume = stac92xx_resume, 4992 .resume = stac92xx_resume,
4829#endif 4993#endif
4994 .reboot_notify = stac92xx_shutup,
4830}; 4995};
4831 4996
4832static int patch_stac9200(struct hda_codec *codec) 4997static int patch_stac9200(struct hda_codec *codec)
@@ -4838,6 +5003,7 @@ static int patch_stac9200(struct hda_codec *codec)
4838 if (spec == NULL) 5003 if (spec == NULL)
4839 return -ENOMEM; 5004 return -ENOMEM;
4840 5005
5006 codec->no_trigger_sense = 1;
4841 codec->spec = spec; 5007 codec->spec = spec;
4842 spec->num_pins = ARRAY_SIZE(stac9200_pin_nids); 5008 spec->num_pins = ARRAY_SIZE(stac9200_pin_nids);
4843 spec->pin_nids = stac9200_pin_nids; 5009 spec->pin_nids = stac9200_pin_nids;
@@ -4900,6 +5066,7 @@ static int patch_stac925x(struct hda_codec *codec)
4900 if (spec == NULL) 5066 if (spec == NULL)
4901 return -ENOMEM; 5067 return -ENOMEM;
4902 5068
5069 codec->no_trigger_sense = 1;
4903 codec->spec = spec; 5070 codec->spec = spec;
4904 spec->num_pins = ARRAY_SIZE(stac925x_pin_nids); 5071 spec->num_pins = ARRAY_SIZE(stac925x_pin_nids);
4905 spec->pin_nids = stac925x_pin_nids; 5072 spec->pin_nids = stac925x_pin_nids;
@@ -4984,6 +5151,7 @@ static int patch_stac92hd73xx(struct hda_codec *codec)
4984 if (spec == NULL) 5151 if (spec == NULL)
4985 return -ENOMEM; 5152 return -ENOMEM;
4986 5153
5154 codec->no_trigger_sense = 1;
4987 codec->spec = spec; 5155 codec->spec = spec;
4988 codec->slave_dig_outs = stac92hd73xx_slave_dig_outs; 5156 codec->slave_dig_outs = stac92hd73xx_slave_dig_outs;
4989 spec->num_pins = ARRAY_SIZE(stac92hd73xx_pin_nids); 5157 spec->num_pins = ARRAY_SIZE(stac92hd73xx_pin_nids);
@@ -5125,12 +5293,12 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)
5125 hda_nid_t conn[STAC92HD83_DAC_COUNT + 1]; 5293 hda_nid_t conn[STAC92HD83_DAC_COUNT + 1];
5126 int err; 5294 int err;
5127 int num_dacs; 5295 int num_dacs;
5128 hda_nid_t nid;
5129 5296
5130 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 5297 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5131 if (spec == NULL) 5298 if (spec == NULL)
5132 return -ENOMEM; 5299 return -ENOMEM;
5133 5300
5301 codec->no_trigger_sense = 1;
5134 codec->spec = spec; 5302 codec->spec = spec;
5135 codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs; 5303 codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs;
5136 spec->digbeep_nid = 0x21; 5304 spec->digbeep_nid = 0x21;
@@ -5163,7 +5331,18 @@ again:
5163 stac92hd83xxx_brd_tbl[spec->board_config]); 5331 stac92hd83xxx_brd_tbl[spec->board_config]);
5164 5332
5165 switch (codec->vendor_id) { 5333 switch (codec->vendor_id) {
5334 case 0x111d7666:
5335 case 0x111d7667:
5336 case 0x111d7668:
5337 case 0x111d7669:
5338 spec->num_pins = ARRAY_SIZE(stac92hd88xxx_pin_nids);
5339 spec->pin_nids = stac92hd88xxx_pin_nids;
5340 spec->mono_nid = 0;
5341 spec->digbeep_nid = 0;
5342 spec->num_pwrs = 0;
5343 break;
5166 case 0x111d7604: 5344 case 0x111d7604:
5345 case 0x111d76d4:
5167 case 0x111d7605: 5346 case 0x111d7605:
5168 case 0x111d76d5: 5347 case 0x111d76d5:
5169 if (spec->board_config == STAC_92HD83XXX_PWR_REF) 5348 if (spec->board_config == STAC_92HD83XXX_PWR_REF)
@@ -5172,6 +5351,24 @@ again:
5172 break; 5351 break;
5173 } 5352 }
5174 5353
5354 codec->patch_ops = stac92xx_patch_ops;
5355
5356 if (find_mute_led_gpio(codec, 0))
5357 snd_printd("mute LED gpio %d polarity %d\n",
5358 spec->gpio_led,
5359 spec->gpio_led_polarity);
5360
5361#ifdef CONFIG_SND_HDA_POWER_SAVE
5362 if (spec->gpio_led) {
5363 spec->gpio_mask |= spec->gpio_led;
5364 spec->gpio_dir |= spec->gpio_led;
5365 spec->gpio_data |= spec->gpio_led;
5366 /* register check_power_status callback. */
5367 codec->patch_ops.check_power_status =
5368 stac92xx_hp_check_power_status;
5369 }
5370#endif
5371
5175 err = stac92xx_parse_auto_config(codec, 0x1d, 0); 5372 err = stac92xx_parse_auto_config(codec, 0x1d, 0);
5176 if (!err) { 5373 if (!err) {
5177 if (spec->board_config < 0) { 5374 if (spec->board_config < 0) {
@@ -5188,26 +5385,21 @@ again:
5188 return err; 5385 return err;
5189 } 5386 }
5190 5387
5191 switch (spec->board_config) { 5388 /* docking output support */
5192 case STAC_DELL_S14: 5389 num_dacs = snd_hda_get_connections(codec, 0xF,
5193 nid = 0xf;
5194 break;
5195 default:
5196 nid = 0xe;
5197 break;
5198 }
5199
5200 num_dacs = snd_hda_get_connections(codec, nid,
5201 conn, STAC92HD83_DAC_COUNT + 1) - 1; 5390 conn, STAC92HD83_DAC_COUNT + 1) - 1;
5202 if (num_dacs < 0) 5391 /* skip non-DAC connections */
5203 num_dacs = STAC92HD83_DAC_COUNT; 5392 while (num_dacs >= 0 &&
5204 5393 (get_wcaps_type(get_wcaps(codec, conn[num_dacs]))
5205 /* set port X to select the last DAC 5394 != AC_WID_AUD_OUT))
5206 */ 5395 num_dacs--;
5207 snd_hda_codec_write_cache(codec, nid, 0, 5396 /* set port E and F to select the last DAC */
5397 if (num_dacs >= 0) {
5398 snd_hda_codec_write_cache(codec, 0xE, 0,
5208 AC_VERB_SET_CONNECT_SEL, num_dacs); 5399 AC_VERB_SET_CONNECT_SEL, num_dacs);
5209 5400 snd_hda_codec_write_cache(codec, 0xF, 0,
5210 codec->patch_ops = stac92xx_patch_ops; 5401 AC_VERB_SET_CONNECT_SEL, num_dacs);
5402 }
5211 5403
5212 codec->proc_widget_hook = stac92hd_proc_hook; 5404 codec->proc_widget_hook = stac92hd_proc_hook;
5213 5405
@@ -5269,6 +5461,54 @@ static int stac92hd71bxx_connected_smuxes(struct hda_codec *codec,
5269 return 0; 5461 return 0;
5270} 5462}
5271 5463
5464/* HP dv7 bass switch - GPIO5 */
5465#define stac_hp_bass_gpio_info snd_ctl_boolean_mono_info
5466static int stac_hp_bass_gpio_get(struct snd_kcontrol *kcontrol,
5467 struct snd_ctl_elem_value *ucontrol)
5468{
5469 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5470 struct sigmatel_spec *spec = codec->spec;
5471 ucontrol->value.integer.value[0] = !!(spec->gpio_data & 0x20);
5472 return 0;
5473}
5474
5475static int stac_hp_bass_gpio_put(struct snd_kcontrol *kcontrol,
5476 struct snd_ctl_elem_value *ucontrol)
5477{
5478 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5479 struct sigmatel_spec *spec = codec->spec;
5480 unsigned int gpio_data;
5481
5482 gpio_data = (spec->gpio_data & ~0x20) |
5483 (ucontrol->value.integer.value[0] ? 0x20 : 0);
5484 if (gpio_data == spec->gpio_data)
5485 return 0;
5486 spec->gpio_data = gpio_data;
5487 stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data);
5488 return 1;
5489}
5490
5491static struct snd_kcontrol_new stac_hp_bass_sw_ctrl = {
5492 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5493 .info = stac_hp_bass_gpio_info,
5494 .get = stac_hp_bass_gpio_get,
5495 .put = stac_hp_bass_gpio_put,
5496};
5497
5498static int stac_add_hp_bass_switch(struct hda_codec *codec)
5499{
5500 struct sigmatel_spec *spec = codec->spec;
5501
5502 if (!stac_control_new(spec, &stac_hp_bass_sw_ctrl,
5503 "Bass Speaker Playback Switch", 0))
5504 return -ENOMEM;
5505
5506 spec->gpio_mask |= 0x20;
5507 spec->gpio_dir |= 0x20;
5508 spec->gpio_data |= 0x20;
5509 return 0;
5510}
5511
5272static int patch_stac92hd71bxx(struct hda_codec *codec) 5512static int patch_stac92hd71bxx(struct hda_codec *codec)
5273{ 5513{
5274 struct sigmatel_spec *spec; 5514 struct sigmatel_spec *spec;
@@ -5280,6 +5520,7 @@ static int patch_stac92hd71bxx(struct hda_codec *codec)
5280 if (spec == NULL) 5520 if (spec == NULL)
5281 return -ENOMEM; 5521 return -ENOMEM;
5282 5522
5523 codec->no_trigger_sense = 1;
5283 codec->spec = spec; 5524 codec->spec = spec;
5284 codec->patch_ops = stac92xx_patch_ops; 5525 codec->patch_ops = stac92xx_patch_ops;
5285 spec->num_pins = STAC92HD71BXX_NUM_PINS; 5526 spec->num_pins = STAC92HD71BXX_NUM_PINS;
@@ -5412,6 +5653,8 @@ again:
5412 spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); 5653 spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids);
5413 spec->num_smuxes = stac92hd71bxx_connected_smuxes(codec, 0x1e); 5654 spec->num_smuxes = stac92hd71bxx_connected_smuxes(codec, 0x1e);
5414 5655
5656 snd_printdd("Found board config: %d\n", spec->board_config);
5657
5415 switch (spec->board_config) { 5658 switch (spec->board_config) {
5416 case STAC_HP_M4: 5659 case STAC_HP_M4:
5417 /* enable internal microphone */ 5660 /* enable internal microphone */
@@ -5437,6 +5680,8 @@ again:
5437 */ 5680 */
5438 spec->num_smuxes = 1; 5681 spec->num_smuxes = 1;
5439 spec->num_dmuxes = 1; 5682 spec->num_dmuxes = 1;
5683 /* fallthrough */
5684 case STAC_HP_DV4:
5440 spec->gpio_led = 0x01; 5685 spec->gpio_led = 0x01;
5441 /* fallthrough */ 5686 /* fallthrough */
5442 case STAC_HP_DV5: 5687 case STAC_HP_DV5:
@@ -5452,12 +5697,11 @@ again:
5452 spec->num_dmics = 1; 5697 spec->num_dmics = 1;
5453 spec->num_dmuxes = 1; 5698 spec->num_dmuxes = 1;
5454 spec->num_smuxes = 1; 5699 spec->num_smuxes = 1;
5455 /* orange/white mute led on GPIO3, orange=0, white=1 */
5456 spec->gpio_led = 0x08; 5700 spec->gpio_led = 0x08;
5457 break; 5701 break;
5458 } 5702 }
5459 5703
5460 if (hp_bseries_system(codec->subsystem_id)) { 5704 if (hp_blike_system(codec->subsystem_id)) {
5461 pin_cfg = snd_hda_codec_get_pincfg(codec, 0x0f); 5705 pin_cfg = snd_hda_codec_get_pincfg(codec, 0x0f);
5462 if (get_defcfg_device(pin_cfg) == AC_JACK_LINE_OUT || 5706 if (get_defcfg_device(pin_cfg) == AC_JACK_LINE_OUT ||
5463 get_defcfg_device(pin_cfg) == AC_JACK_SPEAKER || 5707 get_defcfg_device(pin_cfg) == AC_JACK_SPEAKER ||
@@ -5475,26 +5719,10 @@ again:
5475 } 5719 }
5476 } 5720 }
5477 5721
5478 if ((codec->subsystem_id >> 16) == PCI_VENDOR_ID_HP) { 5722 if (find_mute_led_gpio(codec, 1))
5479 const struct dmi_device *dev = NULL; 5723 snd_printd("mute LED gpio %d polarity %d\n",
5480 while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, 5724 spec->gpio_led,
5481 NULL, dev))) { 5725 spec->gpio_led_polarity);
5482 if (strcmp(dev->name, "HP_Mute_LED_1")) {
5483 switch (codec->vendor_id) {
5484 case 0x111d7608:
5485 spec->gpio_led = 0x01;
5486 break;
5487 case 0x111d7600:
5488 case 0x111d7601:
5489 case 0x111d7602:
5490 case 0x111d7603:
5491 spec->gpio_led = 0x08;
5492 break;
5493 }
5494 break;
5495 }
5496 }
5497 }
5498 5726
5499#ifdef CONFIG_SND_HDA_POWER_SAVE 5727#ifdef CONFIG_SND_HDA_POWER_SAVE
5500 if (spec->gpio_led) { 5728 if (spec->gpio_led) {
@@ -5525,6 +5753,16 @@ again:
5525 return err; 5753 return err;
5526 } 5754 }
5527 5755
5756 /* enable bass on HP dv7 */
5757 if (spec->board_config == STAC_HP_DV4 ||
5758 spec->board_config == STAC_HP_DV5) {
5759 unsigned int cap;
5760 cap = snd_hda_param_read(codec, 0x1, AC_PAR_GPIO_CAP);
5761 cap &= AC_GPIO_IO_COUNT;
5762 if (cap >= 6)
5763 stac_add_hp_bass_switch(codec);
5764 }
5765
5528 codec->proc_widget_hook = stac92hd7x_proc_hook; 5766 codec->proc_widget_hook = stac92hd7x_proc_hook;
5529 5767
5530 return 0; 5768 return 0;
@@ -5539,6 +5777,7 @@ static int patch_stac922x(struct hda_codec *codec)
5539 if (spec == NULL) 5777 if (spec == NULL)
5540 return -ENOMEM; 5778 return -ENOMEM;
5541 5779
5780 codec->no_trigger_sense = 1;
5542 codec->spec = spec; 5781 codec->spec = spec;
5543 spec->num_pins = ARRAY_SIZE(stac922x_pin_nids); 5782 spec->num_pins = ARRAY_SIZE(stac922x_pin_nids);
5544 spec->pin_nids = stac922x_pin_nids; 5783 spec->pin_nids = stac922x_pin_nids;
@@ -5642,6 +5881,7 @@ static int patch_stac927x(struct hda_codec *codec)
5642 if (spec == NULL) 5881 if (spec == NULL)
5643 return -ENOMEM; 5882 return -ENOMEM;
5644 5883
5884 codec->no_trigger_sense = 1;
5645 codec->spec = spec; 5885 codec->spec = spec;
5646 codec->slave_dig_outs = stac927x_slave_dig_outs; 5886 codec->slave_dig_outs = stac927x_slave_dig_outs;
5647 spec->num_pins = ARRAY_SIZE(stac927x_pin_nids); 5887 spec->num_pins = ARRAY_SIZE(stac927x_pin_nids);
@@ -5776,6 +6016,7 @@ static int patch_stac9205(struct hda_codec *codec)
5776 if (spec == NULL) 6016 if (spec == NULL)
5777 return -ENOMEM; 6017 return -ENOMEM;
5778 6018
6019 codec->no_trigger_sense = 1;
5779 codec->spec = spec; 6020 codec->spec = spec;
5780 spec->num_pins = ARRAY_SIZE(stac9205_pin_nids); 6021 spec->num_pins = ARRAY_SIZE(stac9205_pin_nids);
5781 spec->pin_nids = stac9205_pin_nids; 6022 spec->pin_nids = stac9205_pin_nids;
@@ -5931,6 +6172,7 @@ static int patch_stac9872(struct hda_codec *codec)
5931 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 6172 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5932 if (spec == NULL) 6173 if (spec == NULL)
5933 return -ENOMEM; 6174 return -ENOMEM;
6175 codec->no_trigger_sense = 1;
5934 codec->spec = spec; 6176 codec->spec = spec;
5935 spec->num_pins = ARRAY_SIZE(stac9872_pin_nids); 6177 spec->num_pins = ARRAY_SIZE(stac9872_pin_nids);
5936 spec->pin_nids = stac9872_pin_nids; 6178 spec->pin_nids = stac9872_pin_nids;
@@ -6019,8 +6261,13 @@ static struct hda_codec_preset snd_hda_preset_sigmatel[] = {
6019 { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 }, 6261 { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 },
6020 { .id = 0x111d7603, .name = "92HD75B3X5", .patch = patch_stac92hd71bxx}, 6262 { .id = 0x111d7603, .name = "92HD75B3X5", .patch = patch_stac92hd71bxx},
6021 { .id = 0x111d7604, .name = "92HD83C1X5", .patch = patch_stac92hd83xxx}, 6263 { .id = 0x111d7604, .name = "92HD83C1X5", .patch = patch_stac92hd83xxx},
6264 { .id = 0x111d76d4, .name = "92HD83C1C5", .patch = patch_stac92hd83xxx},
6022 { .id = 0x111d7605, .name = "92HD81B1X5", .patch = patch_stac92hd83xxx}, 6265 { .id = 0x111d7605, .name = "92HD81B1X5", .patch = patch_stac92hd83xxx},
6023 { .id = 0x111d76d5, .name = "92HD81B1C5", .patch = patch_stac92hd83xxx}, 6266 { .id = 0x111d76d5, .name = "92HD81B1C5", .patch = patch_stac92hd83xxx},
6267 { .id = 0x111d7666, .name = "92HD88B3", .patch = patch_stac92hd83xxx},
6268 { .id = 0x111d7667, .name = "92HD88B1", .patch = patch_stac92hd83xxx},
6269 { .id = 0x111d7668, .name = "92HD88B2", .patch = patch_stac92hd83xxx},
6270 { .id = 0x111d7669, .name = "92HD88B4", .patch = patch_stac92hd83xxx},
6024 { .id = 0x111d7608, .name = "92HD75B2X5", .patch = patch_stac92hd71bxx}, 6271 { .id = 0x111d7608, .name = "92HD75B2X5", .patch = patch_stac92hd71bxx},
6025 { .id = 0x111d7674, .name = "92HD73D1X5", .patch = patch_stac92hd73xx }, 6272 { .id = 0x111d7674, .name = "92HD73D1X5", .patch = patch_stac92hd73xx },
6026 { .id = 0x111d7675, .name = "92HD73C1X5", .patch = patch_stac92hd73xx }, 6273 { .id = 0x111d7675, .name = "92HD73C1X5", .patch = patch_stac92hd73xx },
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index ee89db90c9b6..73453814e098 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -1,10 +1,10 @@
1/* 1/*
2 * Universal Interface for Intel High Definition Audio Codec 2 * Universal Interface for Intel High Definition Audio Codec
3 * 3 *
4 * HD audio interface patch for VIA VT1702/VT1708/VT1709 codec 4 * HD audio interface patch for VIA VT17xx/VT18xx/VT20xx codec
5 * 5 *
6 * Copyright (c) 2006-2008 Lydia Wang <lydiawang@viatech.com> 6 * (C) 2006-2009 VIA Technology, Inc.
7 * Takashi Iwai <tiwai@suse.de> 7 * (C) 2006-2008 Takashi Iwai <tiwai@suse.de>
8 * 8 *
9 * This driver is free software; you can redistribute it and/or modify 9 * This driver is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by 10 * it under the terms of the GNU General Public License as published by
@@ -22,21 +22,27 @@
22 */ 22 */
23 23
24/* * * * * * * * * * * * * * Release History * * * * * * * * * * * * * * * * */ 24/* * * * * * * * * * * * * * Release History * * * * * * * * * * * * * * * * */
25/* */ 25/* */
26/* 2006-03-03 Lydia Wang Create the basic patch to support VT1708 codec */ 26/* 2006-03-03 Lydia Wang Create the basic patch to support VT1708 codec */
27/* 2006-03-14 Lydia Wang Modify hard code for some pin widget nid */ 27/* 2006-03-14 Lydia Wang Modify hard code for some pin widget nid */
28/* 2006-08-02 Lydia Wang Add support to VT1709 codec */ 28/* 2006-08-02 Lydia Wang Add support to VT1709 codec */
29/* 2006-09-08 Lydia Wang Fix internal loopback recording source select bug */ 29/* 2006-09-08 Lydia Wang Fix internal loopback recording source select bug */
30/* 2007-09-12 Lydia Wang Add EAPD enable during driver initialization */ 30/* 2007-09-12 Lydia Wang Add EAPD enable during driver initialization */
31/* 2007-09-17 Lydia Wang Add VT1708B codec support */ 31/* 2007-09-17 Lydia Wang Add VT1708B codec support */
32/* 2007-11-14 Lydia Wang Add VT1708A codec HP and CD pin connect config */ 32/* 2007-11-14 Lydia Wang Add VT1708A codec HP and CD pin connect config */
33/* 2008-02-03 Lydia Wang Fix Rear channels and Back channels inverse issue */ 33/* 2008-02-03 Lydia Wang Fix Rear channels and Back channels inverse issue */
34/* 2008-03-06 Lydia Wang Add VT1702 codec and VT1708S codec support */ 34/* 2008-03-06 Lydia Wang Add VT1702 codec and VT1708S codec support */
35/* 2008-04-09 Lydia Wang Add mute front speaker when HP plugin */ 35/* 2008-04-09 Lydia Wang Add mute front speaker when HP plugin */
36/* 2008-04-09 Lydia Wang Add Independent HP feature */ 36/* 2008-04-09 Lydia Wang Add Independent HP feature */
37/* 2008-05-28 Lydia Wang Add second S/PDIF Out support for VT1702 */ 37/* 2008-05-28 Lydia Wang Add second S/PDIF Out support for VT1702 */
38/* 2008-09-15 Logan Li Add VT1708S Mic Boost workaround/backdoor */ 38/* 2008-09-15 Logan Li Add VT1708S Mic Boost workaround/backdoor */
39/* */ 39/* 2009-02-16 Logan Li Add support for VT1718S */
40/* 2009-03-13 Logan Li Add support for VT1716S */
41/* 2009-04-14 Lydai Wang Add support for VT1828S and VT2020 */
42/* 2009-07-08 Lydia Wang Add support for VT2002P */
43/* 2009-07-21 Lydia Wang Add support for VT1812 */
44/* 2009-09-19 Lydia Wang Add support for VT1818S */
45/* */
40/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 46/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
41 47
42 48
@@ -48,6 +54,8 @@
48#include "hda_codec.h" 54#include "hda_codec.h"
49#include "hda_local.h" 55#include "hda_local.h"
50 56
57#define NID_MAPPING (-1)
58
51/* amp values */ 59/* amp values */
52#define AMP_VAL_IDX_SHIFT 19 60#define AMP_VAL_IDX_SHIFT 19
53#define AMP_VAL_IDX_MASK (0x0f<<19) 61#define AMP_VAL_IDX_MASK (0x0f<<19)
@@ -76,14 +84,6 @@
76#define VT1702_HP_NID 0x17 84#define VT1702_HP_NID 0x17
77#define VT1702_DIGOUT_NID 0x11 85#define VT1702_DIGOUT_NID 0x11
78 86
79#define IS_VT1708_VENDORID(x) ((x) >= 0x11061708 && (x) <= 0x1106170b)
80#define IS_VT1709_10CH_VENDORID(x) ((x) >= 0x1106e710 && (x) <= 0x1106e713)
81#define IS_VT1709_6CH_VENDORID(x) ((x) >= 0x1106e714 && (x) <= 0x1106e717)
82#define IS_VT1708B_8CH_VENDORID(x) ((x) >= 0x1106e720 && (x) <= 0x1106e723)
83#define IS_VT1708B_4CH_VENDORID(x) ((x) >= 0x1106e724 && (x) <= 0x1106e727)
84#define IS_VT1708S_VENDORID(x) ((x) >= 0x11060397 && (x) <= 0x11067397)
85#define IS_VT1702_VENDORID(x) ((x) >= 0x11060398 && (x) <= 0x11067398)
86
87enum VIA_HDA_CODEC { 87enum VIA_HDA_CODEC {
88 UNKNOWN = -1, 88 UNKNOWN = -1,
89 VT1708, 89 VT1708,
@@ -92,12 +92,89 @@ enum VIA_HDA_CODEC {
92 VT1708B_8CH, 92 VT1708B_8CH,
93 VT1708B_4CH, 93 VT1708B_4CH,
94 VT1708S, 94 VT1708S,
95 VT1708BCE,
95 VT1702, 96 VT1702,
97 VT1718S,
98 VT1716S,
99 VT2002P,
100 VT1812,
96 CODEC_TYPES, 101 CODEC_TYPES,
97}; 102};
98 103
99static enum VIA_HDA_CODEC get_codec_type(u32 vendor_id) 104struct via_spec {
105 /* codec parameterization */
106 struct snd_kcontrol_new *mixers[6];
107 unsigned int num_mixers;
108
109 struct hda_verb *init_verbs[5];
110 unsigned int num_iverbs;
111
112 char *stream_name_analog;
113 struct hda_pcm_stream *stream_analog_playback;
114 struct hda_pcm_stream *stream_analog_capture;
115
116 char *stream_name_digital;
117 struct hda_pcm_stream *stream_digital_playback;
118 struct hda_pcm_stream *stream_digital_capture;
119
120 /* playback */
121 struct hda_multi_out multiout;
122 hda_nid_t slave_dig_outs[2];
123
124 /* capture */
125 unsigned int num_adc_nids;
126 hda_nid_t *adc_nids;
127 hda_nid_t mux_nids[3];
128 hda_nid_t dig_in_nid;
129 hda_nid_t dig_in_pin;
130
131 /* capture source */
132 const struct hda_input_mux *input_mux;
133 unsigned int cur_mux[3];
134
135 /* PCM information */
136 struct hda_pcm pcm_rec[3];
137
138 /* dynamic controls, init_verbs and input_mux */
139 struct auto_pin_cfg autocfg;
140 struct snd_array kctls;
141 struct hda_input_mux private_imux[2];
142 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
143
144 /* HP mode source */
145 const struct hda_input_mux *hp_mux;
146 unsigned int hp_independent_mode;
147 unsigned int hp_independent_mode_index;
148 unsigned int smart51_enabled;
149 unsigned int dmic_enabled;
150 enum VIA_HDA_CODEC codec_type;
151
152 /* work to check hp jack state */
153 struct hda_codec *codec;
154 struct delayed_work vt1708_hp_work;
155 int vt1708_jack_detectect;
156 int vt1708_hp_present;
157#ifdef CONFIG_SND_HDA_POWER_SAVE
158 struct hda_loopback_check loopback;
159#endif
160};
161
162static struct via_spec * via_new_spec(struct hda_codec *codec)
100{ 163{
164 struct via_spec *spec;
165
166 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
167 if (spec == NULL)
168 return NULL;
169
170 codec->spec = spec;
171 spec->codec = codec;
172 return spec;
173}
174
175static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec)
176{
177 u32 vendor_id = codec->vendor_id;
101 u16 ven_id = vendor_id >> 16; 178 u16 ven_id = vendor_id >> 16;
102 u16 dev_id = vendor_id & 0xffff; 179 u16 dev_id = vendor_id & 0xffff;
103 enum VIA_HDA_CODEC codec_type; 180 enum VIA_HDA_CODEC codec_type;
@@ -111,9 +188,11 @@ static enum VIA_HDA_CODEC get_codec_type(u32 vendor_id)
111 codec_type = VT1709_10CH; 188 codec_type = VT1709_10CH;
112 else if (dev_id >= 0xe714 && dev_id <= 0xe717) 189 else if (dev_id >= 0xe714 && dev_id <= 0xe717)
113 codec_type = VT1709_6CH; 190 codec_type = VT1709_6CH;
114 else if (dev_id >= 0xe720 && dev_id <= 0xe723) 191 else if (dev_id >= 0xe720 && dev_id <= 0xe723) {
115 codec_type = VT1708B_8CH; 192 codec_type = VT1708B_8CH;
116 else if (dev_id >= 0xe724 && dev_id <= 0xe727) 193 if (snd_hda_param_read(codec, 0x16, AC_PAR_CONNLIST_LEN) == 0x7)
194 codec_type = VT1708BCE;
195 } else if (dev_id >= 0xe724 && dev_id <= 0xe727)
117 codec_type = VT1708B_4CH; 196 codec_type = VT1708B_4CH;
118 else if ((dev_id & 0xfff) == 0x397 197 else if ((dev_id & 0xfff) == 0x397
119 && (dev_id >> 12) < 8) 198 && (dev_id >> 12) < 8)
@@ -121,6 +200,19 @@ static enum VIA_HDA_CODEC get_codec_type(u32 vendor_id)
121 else if ((dev_id & 0xfff) == 0x398 200 else if ((dev_id & 0xfff) == 0x398
122 && (dev_id >> 12) < 8) 201 && (dev_id >> 12) < 8)
123 codec_type = VT1702; 202 codec_type = VT1702;
203 else if ((dev_id & 0xfff) == 0x428
204 && (dev_id >> 12) < 8)
205 codec_type = VT1718S;
206 else if (dev_id == 0x0433 || dev_id == 0xa721)
207 codec_type = VT1716S;
208 else if (dev_id == 0x0441 || dev_id == 0x4441)
209 codec_type = VT1718S;
210 else if (dev_id == 0x0438 || dev_id == 0x4438)
211 codec_type = VT2002P;
212 else if (dev_id == 0x0448)
213 codec_type = VT1812;
214 else if (dev_id == 0x0440)
215 codec_type = VT1708S;
124 else 216 else
125 codec_type = UNKNOWN; 217 codec_type = UNKNOWN;
126 return codec_type; 218 return codec_type;
@@ -128,10 +220,16 @@ static enum VIA_HDA_CODEC get_codec_type(u32 vendor_id)
128 220
129#define VIA_HP_EVENT 0x01 221#define VIA_HP_EVENT 0x01
130#define VIA_GPIO_EVENT 0x02 222#define VIA_GPIO_EVENT 0x02
223#define VIA_JACK_EVENT 0x04
224#define VIA_MONO_EVENT 0x08
225#define VIA_SPEAKER_EVENT 0x10
226#define VIA_BIND_HP_EVENT 0x20
131 227
132enum { 228enum {
133 VIA_CTL_WIDGET_VOL, 229 VIA_CTL_WIDGET_VOL,
134 VIA_CTL_WIDGET_MUTE, 230 VIA_CTL_WIDGET_MUTE,
231 VIA_CTL_WIDGET_ANALOG_MUTE,
232 VIA_CTL_WIDGET_BIND_PIN_MUTE,
135}; 233};
136 234
137enum { 235enum {
@@ -141,99 +239,162 @@ enum {
141 AUTO_SEQ_SIDE 239 AUTO_SEQ_SIDE
142}; 240};
143 241
144/* Some VT1708S based boards gets the micboost setting wrong, so we have 242static void analog_low_current_mode(struct hda_codec *codec, int stream_idle);
145 * to apply some brute-force and re-write the TLV's by software. */ 243static void set_jack_power_state(struct hda_codec *codec);
146static int mic_boost_tlv(struct snd_kcontrol *kcontrol, int op_flag, 244static int is_aa_path_mute(struct hda_codec *codec);
147 unsigned int size, unsigned int __user *_tlv) 245
246static void vt1708_start_hp_work(struct via_spec *spec)
148{ 247{
149 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 248 if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0)
150 hda_nid_t nid = get_amp_nid(kcontrol); 249 return;
250 snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81,
251 !spec->vt1708_jack_detectect);
252 if (!delayed_work_pending(&spec->vt1708_hp_work))
253 schedule_delayed_work(&spec->vt1708_hp_work,
254 msecs_to_jiffies(100));
255}
151 256
152 if (get_codec_type(codec->vendor_id) == VT1708S 257static void vt1708_stop_hp_work(struct via_spec *spec)
153 && (nid == 0x1a || nid == 0x1e)) { 258{
154 if (size < 4 * sizeof(unsigned int)) 259 if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0)
155 return -ENOMEM; 260 return;
156 if (put_user(1, _tlv)) /* SNDRV_CTL_TLVT_DB_SCALE */ 261 if (snd_hda_get_bool_hint(spec->codec, "analog_loopback_hp_detect") == 1
157 return -EFAULT; 262 && !is_aa_path_mute(spec->codec))
158 if (put_user(2 * sizeof(unsigned int), _tlv + 1)) 263 return;
159 return -EFAULT; 264 snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81,
160 if (put_user(0, _tlv + 2)) /* offset = 0 */ 265 !spec->vt1708_jack_detectect);
161 return -EFAULT; 266 cancel_delayed_work(&spec->vt1708_hp_work);
162 if (put_user(1000, _tlv + 3)) /* step size = 10 dB */ 267 flush_scheduled_work();
163 return -EFAULT;
164 }
165 return 0;
166} 268}
167 269
168static int mic_boost_volume_info(struct snd_kcontrol *kcontrol, 270
169 struct snd_ctl_elem_info *uinfo) 271static int analog_input_switch_put(struct snd_kcontrol *kcontrol,
272 struct snd_ctl_elem_value *ucontrol)
170{ 273{
274 int change = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
171 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 275 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
172 hda_nid_t nid = get_amp_nid(kcontrol);
173 276
174 if (get_codec_type(codec->vendor_id) == VT1708S 277 set_jack_power_state(codec);
175 && (nid == 0x1a || nid == 0x1e)) { 278 analog_low_current_mode(snd_kcontrol_chip(kcontrol), -1);
176 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 279 if (snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") == 1) {
177 uinfo->count = 2; 280 if (is_aa_path_mute(codec))
178 uinfo->value.integer.min = 0; 281 vt1708_start_hp_work(codec->spec);
179 uinfo->value.integer.max = 3; 282 else
283 vt1708_stop_hp_work(codec->spec);
180 } 284 }
181 return 0; 285 return change;
182} 286}
183 287
184static struct snd_kcontrol_new vt1708_control_templates[] = { 288/* modify .put = snd_hda_mixer_amp_switch_put */
185 HDA_CODEC_VOLUME(NULL, 0, 0, 0), 289#define ANALOG_INPUT_MUTE \
186 HDA_CODEC_MUTE(NULL, 0, 0, 0), 290 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
187}; 291 .name = NULL, \
292 .index = 0, \
293 .info = snd_hda_mixer_amp_switch_info, \
294 .get = snd_hda_mixer_amp_switch_get, \
295 .put = analog_input_switch_put, \
296 .private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0) }
188 297
298static void via_hp_bind_automute(struct hda_codec *codec);
189 299
190struct via_spec { 300static int bind_pin_switch_put(struct snd_kcontrol *kcontrol,
191 /* codec parameterization */ 301 struct snd_ctl_elem_value *ucontrol)
192 struct snd_kcontrol_new *mixers[3]; 302{
193 unsigned int num_mixers; 303 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
194 304 struct via_spec *spec = codec->spec;
195 struct hda_verb *init_verbs[5]; 305 int i;
196 unsigned int num_iverbs; 306 int change = 0;
197
198 char *stream_name_analog;
199 struct hda_pcm_stream *stream_analog_playback;
200 struct hda_pcm_stream *stream_analog_capture;
201
202 char *stream_name_digital;
203 struct hda_pcm_stream *stream_digital_playback;
204 struct hda_pcm_stream *stream_digital_capture;
205
206 /* playback */
207 struct hda_multi_out multiout;
208 hda_nid_t slave_dig_outs[2];
209
210 /* capture */
211 unsigned int num_adc_nids;
212 hda_nid_t *adc_nids;
213 hda_nid_t mux_nids[3];
214 hda_nid_t dig_in_nid;
215 hda_nid_t dig_in_pin;
216 307
217 /* capture source */ 308 long *valp = ucontrol->value.integer.value;
218 const struct hda_input_mux *input_mux; 309 int lmute, rmute;
219 unsigned int cur_mux[3]; 310 if (strstr(kcontrol->id.name, "Switch") == NULL) {
311 snd_printd("Invalid control!\n");
312 return change;
313 }
314 change = snd_hda_mixer_amp_switch_put(kcontrol,
315 ucontrol);
316 /* Get mute value */
317 lmute = *valp ? 0 : HDA_AMP_MUTE;
318 valp++;
319 rmute = *valp ? 0 : HDA_AMP_MUTE;
320
321 /* Set hp pins */
322 if (!spec->hp_independent_mode) {
323 for (i = 0; i < spec->autocfg.hp_outs; i++) {
324 snd_hda_codec_amp_update(
325 codec, spec->autocfg.hp_pins[i],
326 0, HDA_OUTPUT, 0, HDA_AMP_MUTE,
327 lmute);
328 snd_hda_codec_amp_update(
329 codec, spec->autocfg.hp_pins[i],
330 1, HDA_OUTPUT, 0, HDA_AMP_MUTE,
331 rmute);
332 }
333 }
220 334
221 /* PCM information */ 335 if (!lmute && !rmute) {
222 struct hda_pcm pcm_rec[3]; 336 /* Line Outs */
337 for (i = 0; i < spec->autocfg.line_outs; i++)
338 snd_hda_codec_amp_stereo(
339 codec, spec->autocfg.line_out_pins[i],
340 HDA_OUTPUT, 0, HDA_AMP_MUTE, 0);
341 /* Speakers */
342 for (i = 0; i < spec->autocfg.speaker_outs; i++)
343 snd_hda_codec_amp_stereo(
344 codec, spec->autocfg.speaker_pins[i],
345 HDA_OUTPUT, 0, HDA_AMP_MUTE, 0);
346 /* unmute */
347 via_hp_bind_automute(codec);
223 348
224 /* dynamic controls, init_verbs and input_mux */ 349 } else {
225 struct auto_pin_cfg autocfg; 350 if (lmute) {
226 struct snd_array kctls; 351 /* Mute all left channels */
227 struct hda_input_mux private_imux[2]; 352 for (i = 1; i < spec->autocfg.line_outs; i++)
228 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; 353 snd_hda_codec_amp_update(
354 codec,
355 spec->autocfg.line_out_pins[i],
356 0, HDA_OUTPUT, 0, HDA_AMP_MUTE,
357 lmute);
358 for (i = 0; i < spec->autocfg.speaker_outs; i++)
359 snd_hda_codec_amp_update(
360 codec,
361 spec->autocfg.speaker_pins[i],
362 0, HDA_OUTPUT, 0, HDA_AMP_MUTE,
363 lmute);
364 }
365 if (rmute) {
366 /* mute all right channels */
367 for (i = 1; i < spec->autocfg.line_outs; i++)
368 snd_hda_codec_amp_update(
369 codec,
370 spec->autocfg.line_out_pins[i],
371 1, HDA_OUTPUT, 0, HDA_AMP_MUTE,
372 rmute);
373 for (i = 0; i < spec->autocfg.speaker_outs; i++)
374 snd_hda_codec_amp_update(
375 codec,
376 spec->autocfg.speaker_pins[i],
377 1, HDA_OUTPUT, 0, HDA_AMP_MUTE,
378 rmute);
379 }
380 }
381 return change;
382}
229 383
230 /* HP mode source */ 384#define BIND_PIN_MUTE \
231 const struct hda_input_mux *hp_mux; 385 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
232 unsigned int hp_independent_mode; 386 .name = NULL, \
387 .index = 0, \
388 .info = snd_hda_mixer_amp_switch_info, \
389 .get = snd_hda_mixer_amp_switch_get, \
390 .put = bind_pin_switch_put, \
391 .private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0) }
233 392
234#ifdef CONFIG_SND_HDA_POWER_SAVE 393static struct snd_kcontrol_new via_control_templates[] = {
235 struct hda_loopback_check loopback; 394 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
236#endif 395 HDA_CODEC_MUTE(NULL, 0, 0, 0),
396 ANALOG_INPUT_MUTE,
397 BIND_PIN_MUTE,
237}; 398};
238 399
239static hda_nid_t vt1708_adc_nids[2] = { 400static hda_nid_t vt1708_adc_nids[2] = {
@@ -261,6 +422,27 @@ static hda_nid_t vt1702_adc_nids[3] = {
261 0x12, 0x20, 0x1F 422 0x12, 0x20, 0x1F
262}; 423};
263 424
425static hda_nid_t vt1718S_adc_nids[2] = {
426 /* ADC1-2 */
427 0x10, 0x11
428};
429
430static hda_nid_t vt1716S_adc_nids[2] = {
431 /* ADC1-2 */
432 0x13, 0x14
433};
434
435static hda_nid_t vt2002P_adc_nids[2] = {
436 /* ADC1-2 */
437 0x10, 0x11
438};
439
440static hda_nid_t vt1812_adc_nids[2] = {
441 /* ADC1-2 */
442 0x10, 0x11
443};
444
445
264/* add dynamic controls */ 446/* add dynamic controls */
265static int via_add_control(struct via_spec *spec, int type, const char *name, 447static int via_add_control(struct via_spec *spec, int type, const char *name,
266 unsigned long val) 448 unsigned long val)
@@ -271,14 +453,32 @@ static int via_add_control(struct via_spec *spec, int type, const char *name,
271 knew = snd_array_new(&spec->kctls); 453 knew = snd_array_new(&spec->kctls);
272 if (!knew) 454 if (!knew)
273 return -ENOMEM; 455 return -ENOMEM;
274 *knew = vt1708_control_templates[type]; 456 *knew = via_control_templates[type];
275 knew->name = kstrdup(name, GFP_KERNEL); 457 knew->name = kstrdup(name, GFP_KERNEL);
276 if (!knew->name) 458 if (!knew->name)
277 return -ENOMEM; 459 return -ENOMEM;
460 if (get_amp_nid_(val))
461 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
278 knew->private_value = val; 462 knew->private_value = val;
279 return 0; 463 return 0;
280} 464}
281 465
466static struct snd_kcontrol_new *via_clone_control(struct via_spec *spec,
467 struct snd_kcontrol_new *tmpl)
468{
469 struct snd_kcontrol_new *knew;
470
471 snd_array_init(&spec->kctls, sizeof(*knew), 32);
472 knew = snd_array_new(&spec->kctls);
473 if (!knew)
474 return NULL;
475 *knew = *tmpl;
476 knew->name = kstrdup(tmpl->name, GFP_KERNEL);
477 if (!knew->name)
478 return NULL;
479 return knew;
480}
481
282static void via_free_kctls(struct hda_codec *codec) 482static void via_free_kctls(struct hda_codec *codec)
283{ 483{
284 struct via_spec *spec = codec->spec; 484 struct via_spec *spec = codec->spec;
@@ -293,8 +493,8 @@ static void via_free_kctls(struct hda_codec *codec)
293} 493}
294 494
295/* create input playback/capture controls for the given pin */ 495/* create input playback/capture controls for the given pin */
296static int via_new_analog_input(struct via_spec *spec, hda_nid_t pin, 496static int via_new_analog_input(struct via_spec *spec, const char *ctlname,
297 const char *ctlname, int idx, int mix_nid) 497 int idx, int mix_nid)
298{ 498{
299 char name[32]; 499 char name[32];
300 int err; 500 int err;
@@ -305,7 +505,7 @@ static int via_new_analog_input(struct via_spec *spec, hda_nid_t pin,
305 if (err < 0) 505 if (err < 0)
306 return err; 506 return err;
307 sprintf(name, "%s Playback Switch", ctlname); 507 sprintf(name, "%s Playback Switch", ctlname);
308 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name, 508 err = via_add_control(spec, VIA_CTL_WIDGET_ANALOG_MUTE, name,
309 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); 509 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
310 if (err < 0) 510 if (err < 0)
311 return err; 511 return err;
@@ -322,7 +522,7 @@ static void via_auto_set_output_and_unmute(struct hda_codec *codec,
322 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 522 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
323 AMP_OUT_UNMUTE); 523 AMP_OUT_UNMUTE);
324 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD) 524 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
325 snd_hda_codec_write(codec, nid, 0, 525 snd_hda_codec_write(codec, nid, 0,
326 AC_VERB_SET_EAPD_BTLENABLE, 0x02); 526 AC_VERB_SET_EAPD_BTLENABLE, 0x02);
327} 527}
328 528
@@ -343,10 +543,13 @@ static void via_auto_init_hp_out(struct hda_codec *codec)
343{ 543{
344 struct via_spec *spec = codec->spec; 544 struct via_spec *spec = codec->spec;
345 hda_nid_t pin; 545 hda_nid_t pin;
546 int i;
346 547
347 pin = spec->autocfg.hp_pins[0]; 548 for (i = 0; i < spec->autocfg.hp_outs; i++) {
348 if (pin) /* connect to front */ 549 pin = spec->autocfg.hp_pins[i];
349 via_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 550 if (pin) /* connect to front */
551 via_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
552 }
350} 553}
351 554
352static void via_auto_init_analog_input(struct hda_codec *codec) 555static void via_auto_init_analog_input(struct hda_codec *codec)
@@ -364,6 +567,502 @@ static void via_auto_init_analog_input(struct hda_codec *codec)
364 567
365 } 568 }
366} 569}
570
571static int is_smart51_pins(struct via_spec *spec, hda_nid_t pin);
572
573static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid,
574 unsigned int *affected_parm)
575{
576 unsigned parm;
577 unsigned def_conf = snd_hda_codec_get_pincfg(codec, nid);
578 unsigned no_presence = (def_conf & AC_DEFCFG_MISC)
579 >> AC_DEFCFG_MISC_SHIFT
580 & AC_DEFCFG_MISC_NO_PRESENCE; /* do not support pin sense */
581 unsigned present = snd_hda_jack_detect(codec, nid);
582 struct via_spec *spec = codec->spec;
583 if ((spec->smart51_enabled && is_smart51_pins(spec, nid))
584 || ((no_presence || present)
585 && get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE)) {
586 *affected_parm = AC_PWRST_D0; /* if it's connected */
587 parm = AC_PWRST_D0;
588 } else
589 parm = AC_PWRST_D3;
590
591 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, parm);
592}
593
594static void set_jack_power_state(struct hda_codec *codec)
595{
596 struct via_spec *spec = codec->spec;
597 int imux_is_smixer;
598 unsigned int parm;
599
600 if (spec->codec_type == VT1702) {
601 imux_is_smixer = snd_hda_codec_read(
602 codec, 0x13, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
603 /* inputs */
604 /* PW 1/2/5 (14h/15h/18h) */
605 parm = AC_PWRST_D3;
606 set_pin_power_state(codec, 0x14, &parm);
607 set_pin_power_state(codec, 0x15, &parm);
608 set_pin_power_state(codec, 0x18, &parm);
609 if (imux_is_smixer)
610 parm = AC_PWRST_D0; /* SW0 = stereo mixer (idx 3) */
611 /* SW0 (13h), AIW 0/1/2 (12h/1fh/20h) */
612 snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE,
613 parm);
614 snd_hda_codec_write(codec, 0x12, 0, AC_VERB_SET_POWER_STATE,
615 parm);
616 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE,
617 parm);
618 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_POWER_STATE,
619 parm);
620
621 /* outputs */
622 /* PW 3/4 (16h/17h) */
623 parm = AC_PWRST_D3;
624 set_pin_power_state(codec, 0x16, &parm);
625 set_pin_power_state(codec, 0x17, &parm);
626 /* MW0 (1ah), AOW 0/1 (10h/1dh) */
627 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE,
628 imux_is_smixer ? AC_PWRST_D0 : parm);
629 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
630 parm);
631 snd_hda_codec_write(codec, 0x1d, 0, AC_VERB_SET_POWER_STATE,
632 parm);
633 } else if (spec->codec_type == VT1708B_8CH
634 || spec->codec_type == VT1708B_4CH
635 || spec->codec_type == VT1708S) {
636 /* SW0 (17h) = stereo mixer */
637 int is_8ch = spec->codec_type != VT1708B_4CH;
638 imux_is_smixer = snd_hda_codec_read(
639 codec, 0x17, 0, AC_VERB_GET_CONNECT_SEL, 0x00)
640 == ((spec->codec_type == VT1708S) ? 5 : 0);
641 /* inputs */
642 /* PW 1/2/5 (1ah/1bh/1eh) */
643 parm = AC_PWRST_D3;
644 set_pin_power_state(codec, 0x1a, &parm);
645 set_pin_power_state(codec, 0x1b, &parm);
646 set_pin_power_state(codec, 0x1e, &parm);
647 if (imux_is_smixer)
648 parm = AC_PWRST_D0;
649 /* SW0 (17h), AIW 0/1 (13h/14h) */
650 snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE,
651 parm);
652 snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE,
653 parm);
654 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE,
655 parm);
656
657 /* outputs */
658 /* PW0 (19h), SW1 (18h), AOW1 (11h) */
659 parm = AC_PWRST_D3;
660 set_pin_power_state(codec, 0x19, &parm);
661 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE,
662 parm);
663 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE,
664 parm);
665
666 /* PW6 (22h), SW2 (26h), AOW2 (24h) */
667 if (is_8ch) {
668 parm = AC_PWRST_D3;
669 set_pin_power_state(codec, 0x22, &parm);
670 snd_hda_codec_write(codec, 0x26, 0,
671 AC_VERB_SET_POWER_STATE, parm);
672 snd_hda_codec_write(codec, 0x24, 0,
673 AC_VERB_SET_POWER_STATE, parm);
674 }
675
676 /* PW 3/4/7 (1ch/1dh/23h) */
677 parm = AC_PWRST_D3;
678 /* force to D0 for internal Speaker */
679 set_pin_power_state(codec, 0x1c, &parm);
680 set_pin_power_state(codec, 0x1d, &parm);
681 if (is_8ch)
682 set_pin_power_state(codec, 0x23, &parm);
683 /* MW0 (16h), Sw3 (27h), AOW 0/3 (10h/25h) */
684 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE,
685 imux_is_smixer ? AC_PWRST_D0 : parm);
686 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
687 parm);
688 if (is_8ch) {
689 snd_hda_codec_write(codec, 0x25, 0,
690 AC_VERB_SET_POWER_STATE, parm);
691 snd_hda_codec_write(codec, 0x27, 0,
692 AC_VERB_SET_POWER_STATE, parm);
693 }
694 } else if (spec->codec_type == VT1718S) {
695 /* MUX6 (1eh) = stereo mixer */
696 imux_is_smixer = snd_hda_codec_read(
697 codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
698 /* inputs */
699 /* PW 5/6/7 (29h/2ah/2bh) */
700 parm = AC_PWRST_D3;
701 set_pin_power_state(codec, 0x29, &parm);
702 set_pin_power_state(codec, 0x2a, &parm);
703 set_pin_power_state(codec, 0x2b, &parm);
704 if (imux_is_smixer)
705 parm = AC_PWRST_D0;
706 /* MUX6/7 (1eh/1fh), AIW 0/1 (10h/11h) */
707 snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE,
708 parm);
709 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE,
710 parm);
711 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
712 parm);
713 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE,
714 parm);
715
716 /* outputs */
717 /* PW3 (27h), MW2 (1ah), AOW3 (bh) */
718 parm = AC_PWRST_D3;
719 set_pin_power_state(codec, 0x27, &parm);
720 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE,
721 parm);
722 snd_hda_codec_write(codec, 0xb, 0, AC_VERB_SET_POWER_STATE,
723 parm);
724
725 /* PW2 (26h), AOW2 (ah) */
726 parm = AC_PWRST_D3;
727 set_pin_power_state(codec, 0x26, &parm);
728 snd_hda_codec_write(codec, 0xa, 0, AC_VERB_SET_POWER_STATE,
729 parm);
730
731 /* PW0/1 (24h/25h) */
732 parm = AC_PWRST_D3;
733 set_pin_power_state(codec, 0x24, &parm);
734 set_pin_power_state(codec, 0x25, &parm);
735 if (!spec->hp_independent_mode) /* check for redirected HP */
736 set_pin_power_state(codec, 0x28, &parm);
737 snd_hda_codec_write(codec, 0x8, 0, AC_VERB_SET_POWER_STATE,
738 parm);
739 snd_hda_codec_write(codec, 0x9, 0, AC_VERB_SET_POWER_STATE,
740 parm);
741 /* MW9 (21h), Mw2 (1ah), AOW0 (8h) */
742 snd_hda_codec_write(codec, 0x21, 0, AC_VERB_SET_POWER_STATE,
743 imux_is_smixer ? AC_PWRST_D0 : parm);
744 if (spec->hp_independent_mode) {
745 /* PW4 (28h), MW3 (1bh), MUX1(34h), AOW4 (ch) */
746 parm = AC_PWRST_D3;
747 set_pin_power_state(codec, 0x28, &parm);
748 snd_hda_codec_write(codec, 0x1b, 0,
749 AC_VERB_SET_POWER_STATE, parm);
750 snd_hda_codec_write(codec, 0x34, 0,
751 AC_VERB_SET_POWER_STATE, parm);
752 snd_hda_codec_write(codec, 0xc, 0,
753 AC_VERB_SET_POWER_STATE, parm);
754 }
755 } else if (spec->codec_type == VT1716S) {
756 unsigned int mono_out, present;
757 /* SW0 (17h) = stereo mixer */
758 imux_is_smixer = snd_hda_codec_read(
759 codec, 0x17, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
760 /* inputs */
761 /* PW 1/2/5 (1ah/1bh/1eh) */
762 parm = AC_PWRST_D3;
763 set_pin_power_state(codec, 0x1a, &parm);
764 set_pin_power_state(codec, 0x1b, &parm);
765 set_pin_power_state(codec, 0x1e, &parm);
766 if (imux_is_smixer)
767 parm = AC_PWRST_D0;
768 /* SW0 (17h), AIW0(13h) */
769 snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE,
770 parm);
771 snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE,
772 parm);
773
774 parm = AC_PWRST_D3;
775 set_pin_power_state(codec, 0x1e, &parm);
776 /* PW11 (22h) */
777 if (spec->dmic_enabled)
778 set_pin_power_state(codec, 0x22, &parm);
779 else
780 snd_hda_codec_write(
781 codec, 0x22, 0,
782 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
783
784 /* SW2(26h), AIW1(14h) */
785 snd_hda_codec_write(codec, 0x26, 0, AC_VERB_SET_POWER_STATE,
786 parm);
787 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE,
788 parm);
789
790 /* outputs */
791 /* PW0 (19h), SW1 (18h), AOW1 (11h) */
792 parm = AC_PWRST_D3;
793 set_pin_power_state(codec, 0x19, &parm);
794 /* Smart 5.1 PW2(1bh) */
795 if (spec->smart51_enabled)
796 set_pin_power_state(codec, 0x1b, &parm);
797 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE,
798 parm);
799 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE,
800 parm);
801
802 /* PW7 (23h), SW3 (27h), AOW3 (25h) */
803 parm = AC_PWRST_D3;
804 set_pin_power_state(codec, 0x23, &parm);
805 /* Smart 5.1 PW1(1ah) */
806 if (spec->smart51_enabled)
807 set_pin_power_state(codec, 0x1a, &parm);
808 snd_hda_codec_write(codec, 0x27, 0, AC_VERB_SET_POWER_STATE,
809 parm);
810
811 /* Smart 5.1 PW5(1eh) */
812 if (spec->smart51_enabled)
813 set_pin_power_state(codec, 0x1e, &parm);
814 snd_hda_codec_write(codec, 0x25, 0, AC_VERB_SET_POWER_STATE,
815 parm);
816
817 /* Mono out */
818 /* SW4(28h)->MW1(29h)-> PW12 (2ah)*/
819 present = snd_hda_jack_detect(codec, 0x1c);
820 if (present)
821 mono_out = 0;
822 else {
823 present = snd_hda_jack_detect(codec, 0x1d);
824 if (!spec->hp_independent_mode && present)
825 mono_out = 0;
826 else
827 mono_out = 1;
828 }
829 parm = mono_out ? AC_PWRST_D0 : AC_PWRST_D3;
830 snd_hda_codec_write(codec, 0x28, 0, AC_VERB_SET_POWER_STATE,
831 parm);
832 snd_hda_codec_write(codec, 0x29, 0, AC_VERB_SET_POWER_STATE,
833 parm);
834 snd_hda_codec_write(codec, 0x2a, 0, AC_VERB_SET_POWER_STATE,
835 parm);
836
837 /* PW 3/4 (1ch/1dh) */
838 parm = AC_PWRST_D3;
839 set_pin_power_state(codec, 0x1c, &parm);
840 set_pin_power_state(codec, 0x1d, &parm);
841 /* HP Independent Mode, power on AOW3 */
842 if (spec->hp_independent_mode)
843 snd_hda_codec_write(codec, 0x25, 0,
844 AC_VERB_SET_POWER_STATE, parm);
845
846 /* force to D0 for internal Speaker */
847 /* MW0 (16h), AOW0 (10h) */
848 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE,
849 imux_is_smixer ? AC_PWRST_D0 : parm);
850 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
851 mono_out ? AC_PWRST_D0 : parm);
852 } else if (spec->codec_type == VT2002P) {
853 unsigned int present;
854 /* MUX9 (1eh) = stereo mixer */
855 imux_is_smixer = snd_hda_codec_read(
856 codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
857 /* inputs */
858 /* PW 5/6/7 (29h/2ah/2bh) */
859 parm = AC_PWRST_D3;
860 set_pin_power_state(codec, 0x29, &parm);
861 set_pin_power_state(codec, 0x2a, &parm);
862 set_pin_power_state(codec, 0x2b, &parm);
863 if (imux_is_smixer)
864 parm = AC_PWRST_D0;
865 /* MUX9/10 (1eh/1fh), AIW 0/1 (10h/11h) */
866 snd_hda_codec_write(codec, 0x1e, 0,
867 AC_VERB_SET_POWER_STATE, parm);
868 snd_hda_codec_write(codec, 0x1f, 0,
869 AC_VERB_SET_POWER_STATE, parm);
870 snd_hda_codec_write(codec, 0x10, 0,
871 AC_VERB_SET_POWER_STATE, parm);
872 snd_hda_codec_write(codec, 0x11, 0,
873 AC_VERB_SET_POWER_STATE, parm);
874
875 /* outputs */
876 /* AOW0 (8h)*/
877 snd_hda_codec_write(codec, 0x8, 0,
878 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
879
880 /* PW4 (26h), MW4 (1ch), MUX4(37h) */
881 parm = AC_PWRST_D3;
882 set_pin_power_state(codec, 0x26, &parm);
883 snd_hda_codec_write(codec, 0x1c, 0,
884 AC_VERB_SET_POWER_STATE, parm);
885 snd_hda_codec_write(codec, 0x37,
886 0, AC_VERB_SET_POWER_STATE, parm);
887
888 /* PW1 (25h), MW1 (19h), MUX1(35h), AOW1 (9h) */
889 parm = AC_PWRST_D3;
890 set_pin_power_state(codec, 0x25, &parm);
891 snd_hda_codec_write(codec, 0x19, 0,
892 AC_VERB_SET_POWER_STATE, parm);
893 snd_hda_codec_write(codec, 0x35, 0,
894 AC_VERB_SET_POWER_STATE, parm);
895 if (spec->hp_independent_mode) {
896 snd_hda_codec_write(codec, 0x9, 0,
897 AC_VERB_SET_POWER_STATE, parm);
898 }
899
900 /* Class-D */
901 /* PW0 (24h), MW0(18h), MUX0(34h) */
902 present = snd_hda_jack_detect(codec, 0x25);
903 parm = AC_PWRST_D3;
904 set_pin_power_state(codec, 0x24, &parm);
905 if (present) {
906 snd_hda_codec_write(
907 codec, 0x18, 0,
908 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
909 snd_hda_codec_write(
910 codec, 0x34, 0,
911 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
912 } else {
913 snd_hda_codec_write(
914 codec, 0x18, 0,
915 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
916 snd_hda_codec_write(
917 codec, 0x34, 0,
918 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
919 }
920
921 /* Mono Out */
922 /* PW15 (31h), MW8(17h), MUX8(3bh) */
923 present = snd_hda_jack_detect(codec, 0x26);
924 parm = AC_PWRST_D3;
925 set_pin_power_state(codec, 0x31, &parm);
926 if (present) {
927 snd_hda_codec_write(
928 codec, 0x17, 0,
929 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
930 snd_hda_codec_write(
931 codec, 0x3b, 0,
932 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
933 } else {
934 snd_hda_codec_write(
935 codec, 0x17, 0,
936 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
937 snd_hda_codec_write(
938 codec, 0x3b, 0,
939 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
940 }
941
942 /* MW9 (21h) */
943 if (imux_is_smixer || !is_aa_path_mute(codec))
944 snd_hda_codec_write(
945 codec, 0x21, 0,
946 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
947 else
948 snd_hda_codec_write(
949 codec, 0x21, 0,
950 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
951 } else if (spec->codec_type == VT1812) {
952 unsigned int present;
953 /* MUX10 (1eh) = stereo mixer */
954 imux_is_smixer = snd_hda_codec_read(
955 codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
956 /* inputs */
957 /* PW 5/6/7 (29h/2ah/2bh) */
958 parm = AC_PWRST_D3;
959 set_pin_power_state(codec, 0x29, &parm);
960 set_pin_power_state(codec, 0x2a, &parm);
961 set_pin_power_state(codec, 0x2b, &parm);
962 if (imux_is_smixer)
963 parm = AC_PWRST_D0;
964 /* MUX10/11 (1eh/1fh), AIW 0/1 (10h/11h) */
965 snd_hda_codec_write(codec, 0x1e, 0,
966 AC_VERB_SET_POWER_STATE, parm);
967 snd_hda_codec_write(codec, 0x1f, 0,
968 AC_VERB_SET_POWER_STATE, parm);
969 snd_hda_codec_write(codec, 0x10, 0,
970 AC_VERB_SET_POWER_STATE, parm);
971 snd_hda_codec_write(codec, 0x11, 0,
972 AC_VERB_SET_POWER_STATE, parm);
973
974 /* outputs */
975 /* AOW0 (8h)*/
976 snd_hda_codec_write(codec, 0x8, 0,
977 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
978
979 /* PW4 (28h), MW4 (18h), MUX4(38h) */
980 parm = AC_PWRST_D3;
981 set_pin_power_state(codec, 0x28, &parm);
982 snd_hda_codec_write(codec, 0x18, 0,
983 AC_VERB_SET_POWER_STATE, parm);
984 snd_hda_codec_write(codec, 0x38, 0,
985 AC_VERB_SET_POWER_STATE, parm);
986
987 /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */
988 parm = AC_PWRST_D3;
989 set_pin_power_state(codec, 0x25, &parm);
990 snd_hda_codec_write(codec, 0x15, 0,
991 AC_VERB_SET_POWER_STATE, parm);
992 snd_hda_codec_write(codec, 0x35, 0,
993 AC_VERB_SET_POWER_STATE, parm);
994 if (spec->hp_independent_mode) {
995 snd_hda_codec_write(codec, 0x9, 0,
996 AC_VERB_SET_POWER_STATE, parm);
997 }
998
999 /* Internal Speaker */
1000 /* PW0 (24h), MW0(14h), MUX0(34h) */
1001 present = snd_hda_jack_detect(codec, 0x25);
1002 parm = AC_PWRST_D3;
1003 set_pin_power_state(codec, 0x24, &parm);
1004 if (present) {
1005 snd_hda_codec_write(codec, 0x14, 0,
1006 AC_VERB_SET_POWER_STATE,
1007 AC_PWRST_D3);
1008 snd_hda_codec_write(codec, 0x34, 0,
1009 AC_VERB_SET_POWER_STATE,
1010 AC_PWRST_D3);
1011 } else {
1012 snd_hda_codec_write(codec, 0x14, 0,
1013 AC_VERB_SET_POWER_STATE,
1014 AC_PWRST_D0);
1015 snd_hda_codec_write(codec, 0x34, 0,
1016 AC_VERB_SET_POWER_STATE,
1017 AC_PWRST_D0);
1018 }
1019 /* Mono Out */
1020 /* PW13 (31h), MW13(1ch), MUX13(3ch), MW14(3eh) */
1021 present = snd_hda_jack_detect(codec, 0x28);
1022 parm = AC_PWRST_D3;
1023 set_pin_power_state(codec, 0x31, &parm);
1024 if (present) {
1025 snd_hda_codec_write(codec, 0x1c, 0,
1026 AC_VERB_SET_POWER_STATE,
1027 AC_PWRST_D3);
1028 snd_hda_codec_write(codec, 0x3c, 0,
1029 AC_VERB_SET_POWER_STATE,
1030 AC_PWRST_D3);
1031 snd_hda_codec_write(codec, 0x3e, 0,
1032 AC_VERB_SET_POWER_STATE,
1033 AC_PWRST_D3);
1034 } else {
1035 snd_hda_codec_write(codec, 0x1c, 0,
1036 AC_VERB_SET_POWER_STATE,
1037 AC_PWRST_D0);
1038 snd_hda_codec_write(codec, 0x3c, 0,
1039 AC_VERB_SET_POWER_STATE,
1040 AC_PWRST_D0);
1041 snd_hda_codec_write(codec, 0x3e, 0,
1042 AC_VERB_SET_POWER_STATE,
1043 AC_PWRST_D0);
1044 }
1045
1046 /* PW15 (33h), MW15 (1dh), MUX15(3dh) */
1047 parm = AC_PWRST_D3;
1048 set_pin_power_state(codec, 0x33, &parm);
1049 snd_hda_codec_write(codec, 0x1d, 0,
1050 AC_VERB_SET_POWER_STATE, parm);
1051 snd_hda_codec_write(codec, 0x3d, 0,
1052 AC_VERB_SET_POWER_STATE, parm);
1053
1054 /* MW9 (21h) */
1055 if (imux_is_smixer || !is_aa_path_mute(codec))
1056 snd_hda_codec_write(
1057 codec, 0x21, 0,
1058 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
1059 else
1060 snd_hda_codec_write(
1061 codec, 0x21, 0,
1062 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
1063 }
1064}
1065
367/* 1066/*
368 * input MUX handling 1067 * input MUX handling
369 */ 1068 */
@@ -395,6 +1094,14 @@ static int via_mux_enum_put(struct snd_kcontrol *kcontrol,
395 1094
396 if (!spec->mux_nids[adc_idx]) 1095 if (!spec->mux_nids[adc_idx])
397 return -EINVAL; 1096 return -EINVAL;
1097 /* switch to D0 beofre change index */
1098 if (snd_hda_codec_read(codec, spec->mux_nids[adc_idx], 0,
1099 AC_VERB_GET_POWER_STATE, 0x00) != AC_PWRST_D0)
1100 snd_hda_codec_write(codec, spec->mux_nids[adc_idx], 0,
1101 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
1102 /* update jack power state */
1103 set_jack_power_state(codec);
1104
398 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, 1105 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
399 spec->mux_nids[adc_idx], 1106 spec->mux_nids[adc_idx],
400 &spec->cur_mux[adc_idx]); 1107 &spec->cur_mux[adc_idx]);
@@ -412,80 +1119,340 @@ static int via_independent_hp_get(struct snd_kcontrol *kcontrol,
412 struct snd_ctl_elem_value *ucontrol) 1119 struct snd_ctl_elem_value *ucontrol)
413{ 1120{
414 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1121 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
415 struct via_spec *spec = codec->spec; 1122 hda_nid_t nid = kcontrol->private_value;
416 hda_nid_t nid = spec->autocfg.hp_pins[0]; 1123 unsigned int pinsel;
417 unsigned int pinsel = snd_hda_codec_read(codec, nid, 0,
418 AC_VERB_GET_CONNECT_SEL,
419 0x00);
420 1124
1125 /* use !! to translate conn sel 2 for VT1718S */
1126 pinsel = !!snd_hda_codec_read(codec, nid, 0,
1127 AC_VERB_GET_CONNECT_SEL,
1128 0x00);
421 ucontrol->value.enumerated.item[0] = pinsel; 1129 ucontrol->value.enumerated.item[0] = pinsel;
422 1130
423 return 0; 1131 return 0;
424} 1132}
425 1133
1134static void activate_ctl(struct hda_codec *codec, const char *name, int active)
1135{
1136 struct snd_kcontrol *ctl = snd_hda_find_mixer_ctl(codec, name);
1137 if (ctl) {
1138 ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
1139 ctl->vd[0].access |= active
1140 ? 0 : SNDRV_CTL_ELEM_ACCESS_INACTIVE;
1141 snd_ctl_notify(codec->bus->card,
1142 SNDRV_CTL_EVENT_MASK_VALUE, &ctl->id);
1143 }
1144}
1145
1146static hda_nid_t side_mute_channel(struct via_spec *spec)
1147{
1148 switch (spec->codec_type) {
1149 case VT1708: return 0x1b;
1150 case VT1709_10CH: return 0x29;
1151 case VT1708B_8CH: /* fall thru */
1152 case VT1708S: return 0x27;
1153 default: return 0;
1154 }
1155}
1156
1157static int update_side_mute_status(struct hda_codec *codec)
1158{
1159 /* mute side channel */
1160 struct via_spec *spec = codec->spec;
1161 unsigned int parm = spec->hp_independent_mode
1162 ? AMP_OUT_MUTE : AMP_OUT_UNMUTE;
1163 hda_nid_t sw3 = side_mute_channel(spec);
1164
1165 if (sw3)
1166 snd_hda_codec_write(codec, sw3, 0, AC_VERB_SET_AMP_GAIN_MUTE,
1167 parm);
1168 return 0;
1169}
1170
426static int via_independent_hp_put(struct snd_kcontrol *kcontrol, 1171static int via_independent_hp_put(struct snd_kcontrol *kcontrol,
427 struct snd_ctl_elem_value *ucontrol) 1172 struct snd_ctl_elem_value *ucontrol)
428{ 1173{
429 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1174 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
430 struct via_spec *spec = codec->spec; 1175 struct via_spec *spec = codec->spec;
431 hda_nid_t nid = spec->autocfg.hp_pins[0]; 1176 hda_nid_t nid = kcontrol->private_value;
432 unsigned int pinsel = ucontrol->value.enumerated.item[0]; 1177 unsigned int pinsel = ucontrol->value.enumerated.item[0];
433 unsigned int con_nid = snd_hda_codec_read(codec, nid, 0, 1178 /* Get Independent Mode index of headphone pin widget */
434 AC_VERB_GET_CONNECT_LIST, 0) & 0xff; 1179 spec->hp_independent_mode = spec->hp_independent_mode_index == pinsel
435 1180 ? 1 : 0;
436 if (con_nid == spec->multiout.hp_nid) { 1181 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, pinsel);
437 if (pinsel == 0) { 1182
438 if (!spec->hp_independent_mode) { 1183 if (spec->multiout.hp_nid && spec->multiout.hp_nid
439 if (spec->multiout.num_dacs > 1) 1184 != spec->multiout.dac_nids[HDA_FRONT])
440 spec->multiout.num_dacs -= 1; 1185 snd_hda_codec_setup_stream(codec, spec->multiout.hp_nid,
441 spec->hp_independent_mode = 1; 1186 0, 0, 0);
442 } 1187
443 } else if (pinsel == 1) { 1188 update_side_mute_status(codec);
444 if (spec->hp_independent_mode) { 1189 /* update HP volume/swtich active state */
445 if (spec->multiout.num_dacs > 1) 1190 if (spec->codec_type == VT1708S
446 spec->multiout.num_dacs += 1; 1191 || spec->codec_type == VT1702
447 spec->hp_independent_mode = 0; 1192 || spec->codec_type == VT1718S
448 } 1193 || spec->codec_type == VT1716S
449 } 1194 || spec->codec_type == VT2002P
450 } else { 1195 || spec->codec_type == VT1812) {
451 if (pinsel == 0) { 1196 activate_ctl(codec, "Headphone Playback Volume",
452 if (spec->hp_independent_mode) { 1197 spec->hp_independent_mode);
453 if (spec->multiout.num_dacs > 1) 1198 activate_ctl(codec, "Headphone Playback Switch",
454 spec->multiout.num_dacs += 1; 1199 spec->hp_independent_mode);
455 spec->hp_independent_mode = 0;
456 }
457 } else if (pinsel == 1) {
458 if (!spec->hp_independent_mode) {
459 if (spec->multiout.num_dacs > 1)
460 spec->multiout.num_dacs -= 1;
461 spec->hp_independent_mode = 1;
462 }
463 }
464 } 1200 }
465 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL,
466 pinsel);
467
468 if (spec->multiout.hp_nid &&
469 spec->multiout.hp_nid != spec->multiout.dac_nids[HDA_FRONT])
470 snd_hda_codec_setup_stream(codec,
471 spec->multiout.hp_nid,
472 0, 0, 0);
473
474 return 0; 1201 return 0;
475} 1202}
476 1203
477static struct snd_kcontrol_new via_hp_mixer[] = { 1204static struct snd_kcontrol_new via_hp_mixer[2] = {
478 { 1205 {
479 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1206 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
480 .name = "Independent HP", 1207 .name = "Independent HP",
481 .count = 1,
482 .info = via_independent_hp_info, 1208 .info = via_independent_hp_info,
483 .get = via_independent_hp_get, 1209 .get = via_independent_hp_get,
484 .put = via_independent_hp_put, 1210 .put = via_independent_hp_put,
485 }, 1211 },
486 { } /* end */ 1212 {
1213 .iface = NID_MAPPING,
1214 .name = "Independent HP",
1215 },
1216};
1217
1218static int via_hp_build(struct hda_codec *codec)
1219{
1220 struct via_spec *spec = codec->spec;
1221 struct snd_kcontrol_new *knew;
1222 hda_nid_t nid;
1223 int nums;
1224 hda_nid_t conn[HDA_MAX_CONNECTIONS];
1225
1226 switch (spec->codec_type) {
1227 case VT1718S:
1228 nid = 0x34;
1229 break;
1230 case VT2002P:
1231 nid = 0x35;
1232 break;
1233 case VT1812:
1234 nid = 0x3d;
1235 break;
1236 default:
1237 nid = spec->autocfg.hp_pins[0];
1238 break;
1239 }
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
1249 knew->subdevice = HDA_SUBDEV_NID_FLAG | nid;
1250 knew->private_value = nid;
1251
1252 knew = via_clone_control(spec, &via_hp_mixer[1]);
1253 if (knew == NULL)
1254 return -ENOMEM;
1255 knew->subdevice = side_mute_channel(spec);
1256
1257 return 0;
1258}
1259
1260static void notify_aa_path_ctls(struct hda_codec *codec)
1261{
1262 int i;
1263 struct snd_ctl_elem_id id;
1264 const char *labels[] = {"Mic", "Front Mic", "Line"};
1265
1266 memset(&id, 0, sizeof(id));
1267 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1268 for (i = 0; i < ARRAY_SIZE(labels); i++) {
1269 sprintf(id.name, "%s Playback Volume", labels[i]);
1270 snd_ctl_notify(codec->bus->card, SNDRV_CTL_EVENT_MASK_VALUE,
1271 &id);
1272 }
1273}
1274
1275static void mute_aa_path(struct hda_codec *codec, int mute)
1276{
1277 struct via_spec *spec = codec->spec;
1278 hda_nid_t nid_mixer;
1279 int start_idx;
1280 int end_idx;
1281 int i;
1282 /* get nid of MW0 and start & end index */
1283 switch (spec->codec_type) {
1284 case VT1708:
1285 nid_mixer = 0x17;
1286 start_idx = 2;
1287 end_idx = 4;
1288 break;
1289 case VT1709_10CH:
1290 case VT1709_6CH:
1291 nid_mixer = 0x18;
1292 start_idx = 2;
1293 end_idx = 4;
1294 break;
1295 case VT1708B_8CH:
1296 case VT1708B_4CH:
1297 case VT1708S:
1298 case VT1716S:
1299 nid_mixer = 0x16;
1300 start_idx = 2;
1301 end_idx = 4;
1302 break;
1303 default:
1304 return;
1305 }
1306 /* check AA path's mute status */
1307 for (i = start_idx; i <= end_idx; i++) {
1308 int val = mute ? HDA_AMP_MUTE : HDA_AMP_UNMUTE;
1309 snd_hda_codec_amp_stereo(codec, nid_mixer, HDA_INPUT, i,
1310 HDA_AMP_MUTE, val);
1311 }
1312}
1313static int is_smart51_pins(struct via_spec *spec, hda_nid_t pin)
1314{
1315 int res = 0;
1316 int index;
1317 for (index = AUTO_PIN_MIC; index < AUTO_PIN_FRONT_LINE; index++) {
1318 if (pin == spec->autocfg.input_pins[index]) {
1319 res = 1;
1320 break;
1321 }
1322 }
1323 return res;
1324}
1325
1326static int via_smart51_info(struct snd_kcontrol *kcontrol,
1327 struct snd_ctl_elem_info *uinfo)
1328{
1329 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1330 uinfo->count = 1;
1331 uinfo->value.integer.min = 0;
1332 uinfo->value.integer.max = 1;
1333 return 0;
1334}
1335
1336static int via_smart51_get(struct snd_kcontrol *kcontrol,
1337 struct snd_ctl_elem_value *ucontrol)
1338{
1339 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1340 struct via_spec *spec = codec->spec;
1341 int index[] = { AUTO_PIN_MIC, AUTO_PIN_FRONT_MIC, AUTO_PIN_LINE };
1342 int on = 1;
1343 int i;
1344
1345 for (i = 0; i < ARRAY_SIZE(index); i++) {
1346 hda_nid_t nid = spec->autocfg.input_pins[index[i]];
1347 if (nid) {
1348 int ctl =
1349 snd_hda_codec_read(codec, nid, 0,
1350 AC_VERB_GET_PIN_WIDGET_CONTROL,
1351 0);
1352 if (i == AUTO_PIN_FRONT_MIC
1353 && spec->hp_independent_mode
1354 && spec->codec_type != VT1718S)
1355 continue; /* ignore FMic for independent HP */
1356 if (ctl & AC_PINCTL_IN_EN
1357 && !(ctl & AC_PINCTL_OUT_EN))
1358 on = 0;
1359 }
1360 }
1361 *ucontrol->value.integer.value = on;
1362 return 0;
1363}
1364
1365static int via_smart51_put(struct snd_kcontrol *kcontrol,
1366 struct snd_ctl_elem_value *ucontrol)
1367{
1368 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1369 struct via_spec *spec = codec->spec;
1370 int out_in = *ucontrol->value.integer.value
1371 ? AC_PINCTL_OUT_EN : AC_PINCTL_IN_EN;
1372 int index[] = { AUTO_PIN_MIC, AUTO_PIN_FRONT_MIC, AUTO_PIN_LINE };
1373 int i;
1374
1375 for (i = 0; i < ARRAY_SIZE(index); i++) {
1376 hda_nid_t nid = spec->autocfg.input_pins[index[i]];
1377 if (i == AUTO_PIN_FRONT_MIC
1378 && spec->hp_independent_mode
1379 && spec->codec_type != VT1718S)
1380 continue; /* don't retask FMic for independent HP */
1381 if (nid) {
1382 unsigned int parm = snd_hda_codec_read(
1383 codec, nid, 0,
1384 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1385 parm &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN);
1386 parm |= out_in;
1387 snd_hda_codec_write(codec, nid, 0,
1388 AC_VERB_SET_PIN_WIDGET_CONTROL,
1389 parm);
1390 if (out_in == AC_PINCTL_OUT_EN) {
1391 mute_aa_path(codec, 1);
1392 notify_aa_path_ctls(codec);
1393 }
1394 if (spec->codec_type == VT1718S)
1395 snd_hda_codec_amp_stereo(
1396 codec, nid, HDA_OUTPUT, 0, HDA_AMP_MUTE,
1397 HDA_AMP_UNMUTE);
1398 }
1399 if (i == AUTO_PIN_FRONT_MIC) {
1400 if (spec->codec_type == VT1708S
1401 || spec->codec_type == VT1716S) {
1402 /* input = index 1 (AOW3) */
1403 snd_hda_codec_write(
1404 codec, nid, 0,
1405 AC_VERB_SET_CONNECT_SEL, 1);
1406 snd_hda_codec_amp_stereo(
1407 codec, nid, HDA_OUTPUT,
1408 0, HDA_AMP_MUTE, HDA_AMP_UNMUTE);
1409 }
1410 }
1411 }
1412 spec->smart51_enabled = *ucontrol->value.integer.value;
1413 set_jack_power_state(codec);
1414 return 1;
1415}
1416
1417static struct snd_kcontrol_new via_smart51_mixer[2] = {
1418 {
1419 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1420 .name = "Smart 5.1",
1421 .count = 1,
1422 .info = via_smart51_info,
1423 .get = via_smart51_get,
1424 .put = via_smart51_put,
1425 },
1426 {
1427 .iface = NID_MAPPING,
1428 .name = "Smart 5.1",
1429 }
487}; 1430};
488 1431
1432static int via_smart51_build(struct via_spec *spec)
1433{
1434 struct snd_kcontrol_new *knew;
1435 int index[] = { AUTO_PIN_MIC, AUTO_PIN_FRONT_MIC, AUTO_PIN_LINE };
1436 hda_nid_t nid;
1437 int i;
1438
1439 knew = via_clone_control(spec, &via_smart51_mixer[0]);
1440 if (knew == NULL)
1441 return -ENOMEM;
1442
1443 for (i = 0; i < ARRAY_SIZE(index); i++) {
1444 nid = spec->autocfg.input_pins[index[i]];
1445 if (nid) {
1446 knew = via_clone_control(spec, &via_smart51_mixer[1]);
1447 if (knew == NULL)
1448 return -ENOMEM;
1449 knew->subdevice = nid;
1450 }
1451 }
1452
1453 return 0;
1454}
1455
489/* capture mixer elements */ 1456/* capture mixer elements */
490static struct snd_kcontrol_new vt1708_capture_mixer[] = { 1457static struct snd_kcontrol_new vt1708_capture_mixer[] = {
491 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT), 1458 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT),
@@ -506,6 +1473,112 @@ static struct snd_kcontrol_new vt1708_capture_mixer[] = {
506 }, 1473 },
507 { } /* end */ 1474 { } /* end */
508}; 1475};
1476
1477/* check AA path's mute statue */
1478static int is_aa_path_mute(struct hda_codec *codec)
1479{
1480 int mute = 1;
1481 hda_nid_t nid_mixer;
1482 int start_idx;
1483 int end_idx;
1484 int i;
1485 struct via_spec *spec = codec->spec;
1486 /* get nid of MW0 and start & end index */
1487 switch (spec->codec_type) {
1488 case VT1708B_8CH:
1489 case VT1708B_4CH:
1490 case VT1708S:
1491 case VT1716S:
1492 nid_mixer = 0x16;
1493 start_idx = 2;
1494 end_idx = 4;
1495 break;
1496 case VT1702:
1497 nid_mixer = 0x1a;
1498 start_idx = 1;
1499 end_idx = 3;
1500 break;
1501 case VT1718S:
1502 nid_mixer = 0x21;
1503 start_idx = 1;
1504 end_idx = 3;
1505 break;
1506 case VT2002P:
1507 case VT1812:
1508 nid_mixer = 0x21;
1509 start_idx = 0;
1510 end_idx = 2;
1511 break;
1512 default:
1513 return 0;
1514 }
1515 /* check AA path's mute status */
1516 for (i = start_idx; i <= end_idx; i++) {
1517 unsigned int con_list = snd_hda_codec_read(
1518 codec, nid_mixer, 0, AC_VERB_GET_CONNECT_LIST, i/4*4);
1519 int shift = 8 * (i % 4);
1520 hda_nid_t nid_pin = (con_list & (0xff << shift)) >> shift;
1521 unsigned int defconf = snd_hda_codec_get_pincfg(codec, nid_pin);
1522 if (get_defcfg_connect(defconf) == AC_JACK_PORT_COMPLEX) {
1523 /* check mute status while the pin is connected */
1524 int mute_l = snd_hda_codec_amp_read(codec, nid_mixer, 0,
1525 HDA_INPUT, i) >> 7;
1526 int mute_r = snd_hda_codec_amp_read(codec, nid_mixer, 1,
1527 HDA_INPUT, i) >> 7;
1528 if (!mute_l || !mute_r) {
1529 mute = 0;
1530 break;
1531 }
1532 }
1533 }
1534 return mute;
1535}
1536
1537/* enter/exit analog low-current mode */
1538static void analog_low_current_mode(struct hda_codec *codec, int stream_idle)
1539{
1540 struct via_spec *spec = codec->spec;
1541 static int saved_stream_idle = 1; /* saved stream idle status */
1542 int enable = is_aa_path_mute(codec);
1543 unsigned int verb = 0;
1544 unsigned int parm = 0;
1545
1546 if (stream_idle == -1) /* stream status did not change */
1547 enable = enable && saved_stream_idle;
1548 else {
1549 enable = enable && stream_idle;
1550 saved_stream_idle = stream_idle;
1551 }
1552
1553 /* decide low current mode's verb & parameter */
1554 switch (spec->codec_type) {
1555 case VT1708B_8CH:
1556 case VT1708B_4CH:
1557 verb = 0xf70;
1558 parm = enable ? 0x02 : 0x00; /* 0x02: 2/3x, 0x00: 1x */
1559 break;
1560 case VT1708S:
1561 case VT1718S:
1562 case VT1716S:
1563 verb = 0xf73;
1564 parm = enable ? 0x51 : 0xe1; /* 0x51: 4/28x, 0xe1: 1x */
1565 break;
1566 case VT1702:
1567 verb = 0xf73;
1568 parm = enable ? 0x01 : 0x1d; /* 0x01: 4/40x, 0x1d: 1x */
1569 break;
1570 case VT2002P:
1571 case VT1812:
1572 verb = 0xf93;
1573 parm = enable ? 0x00 : 0xe0; /* 0x00: 4/40x, 0xe0: 1x */
1574 break;
1575 default:
1576 return; /* other codecs are not supported */
1577 }
1578 /* send verb */
1579 snd_hda_codec_write(codec, codec->afg, 0, verb, parm);
1580}
1581
509/* 1582/*
510 * generic initialization of ADC, input mixers and output mixers 1583 * generic initialization of ADC, input mixers and output mixers
511 */ 1584 */
@@ -534,9 +1607,9 @@ static struct hda_verb vt1708_volume_init_verbs[] = {
534 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1607 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
535 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1608 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
536 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1609 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
537 1610
538 /* Setup default input to PW4 */ 1611 /* Setup default input MW0 to PW4 */
539 {0x20, AC_VERB_SET_CONNECT_SEL, 0x1}, 1612 {0x20, AC_VERB_SET_CONNECT_SEL, 0},
540 /* PW9 Output enable */ 1613 /* PW9 Output enable */
541 {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 1614 {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
542 { } 1615 { }
@@ -547,30 +1620,13 @@ static int via_playback_pcm_open(struct hda_pcm_stream *hinfo,
547 struct snd_pcm_substream *substream) 1620 struct snd_pcm_substream *substream)
548{ 1621{
549 struct via_spec *spec = codec->spec; 1622 struct via_spec *spec = codec->spec;
1623 int idle = substream->pstr->substream_opened == 1
1624 && substream->ref_count == 0;
1625 analog_low_current_mode(codec, idle);
550 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, 1626 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
551 hinfo); 1627 hinfo);
552} 1628}
553 1629
554static int via_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
555 struct hda_codec *codec,
556 unsigned int stream_tag,
557 unsigned int format,
558 struct snd_pcm_substream *substream)
559{
560 struct via_spec *spec = codec->spec;
561 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
562 stream_tag, format, substream);
563}
564
565static int via_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
566 struct hda_codec *codec,
567 struct snd_pcm_substream *substream)
568{
569 struct via_spec *spec = codec->spec;
570 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
571}
572
573
574static void playback_multi_pcm_prep_0(struct hda_codec *codec, 1630static void playback_multi_pcm_prep_0(struct hda_codec *codec,
575 unsigned int stream_tag, 1631 unsigned int stream_tag,
576 unsigned int format, 1632 unsigned int format,
@@ -615,8 +1671,8 @@ static void playback_multi_pcm_prep_0(struct hda_codec *codec,
615 snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag, 1671 snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag,
616 0, format); 1672 0, format);
617 1673
618 if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT] && 1674 if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT]
619 !spec->hp_independent_mode) 1675 && !spec->hp_independent_mode)
620 /* headphone out will just decode front left/right (stereo) */ 1676 /* headphone out will just decode front left/right (stereo) */
621 snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag, 1677 snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag,
622 0, format); 1678 0, format);
@@ -658,7 +1714,7 @@ static int via_playback_multi_pcm_prepare(struct hda_pcm_stream *hinfo,
658 snd_hda_codec_setup_stream(codec, mout->hp_nid, 1714 snd_hda_codec_setup_stream(codec, mout->hp_nid,
659 stream_tag, 0, format); 1715 stream_tag, 0, format);
660 } 1716 }
661 1717 vt1708_start_hp_work(spec);
662 return 0; 1718 return 0;
663} 1719}
664 1720
@@ -698,7 +1754,7 @@ static int via_playback_multi_pcm_cleanup(struct hda_pcm_stream *hinfo,
698 snd_hda_codec_setup_stream(codec, mout->hp_nid, 1754 snd_hda_codec_setup_stream(codec, mout->hp_nid,
699 0, 0, 0); 1755 0, 0, 0);
700 } 1756 }
701 1757 vt1708_stop_hp_work(spec);
702 return 0; 1758 return 0;
703} 1759}
704 1760
@@ -779,7 +1835,7 @@ static struct hda_pcm_stream vt1708_pcm_analog_playback = {
779}; 1835};
780 1836
781static struct hda_pcm_stream vt1708_pcm_analog_s16_playback = { 1837static struct hda_pcm_stream vt1708_pcm_analog_s16_playback = {
782 .substreams = 1, 1838 .substreams = 2,
783 .channels_min = 2, 1839 .channels_min = 2,
784 .channels_max = 8, 1840 .channels_max = 8,
785 .nid = 0x10, /* NID to query formats and rates */ 1841 .nid = 0x10, /* NID to query formats and rates */
@@ -790,8 +1846,8 @@ static struct hda_pcm_stream vt1708_pcm_analog_s16_playback = {
790 .formats = SNDRV_PCM_FMTBIT_S16_LE, 1846 .formats = SNDRV_PCM_FMTBIT_S16_LE,
791 .ops = { 1847 .ops = {
792 .open = via_playback_pcm_open, 1848 .open = via_playback_pcm_open,
793 .prepare = via_playback_pcm_prepare, 1849 .prepare = via_playback_multi_pcm_prepare,
794 .cleanup = via_playback_pcm_cleanup 1850 .cleanup = via_playback_multi_pcm_cleanup
795 }, 1851 },
796}; 1852};
797 1853
@@ -828,8 +1884,9 @@ static struct hda_pcm_stream vt1708_pcm_digital_capture = {
828static int via_build_controls(struct hda_codec *codec) 1884static int via_build_controls(struct hda_codec *codec)
829{ 1885{
830 struct via_spec *spec = codec->spec; 1886 struct via_spec *spec = codec->spec;
831 int err; 1887 struct snd_kcontrol *kctl;
832 int i; 1888 struct snd_kcontrol_new *knew;
1889 int err, i;
833 1890
834 for (i = 0; i < spec->num_mixers; i++) { 1891 for (i = 0; i < spec->num_mixers; i++) {
835 err = snd_hda_add_new_ctls(codec, spec->mixers[i]); 1892 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
@@ -853,6 +1910,32 @@ static int via_build_controls(struct hda_codec *codec)
853 if (err < 0) 1910 if (err < 0)
854 return err; 1911 return err;
855 } 1912 }
1913
1914 /* assign Capture Source enums to NID */
1915 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
1916 for (i = 0; kctl && i < kctl->count; i++) {
1917 err = snd_hda_add_nid(codec, kctl, i, spec->mux_nids[i]);
1918 if (err < 0)
1919 return err;
1920 }
1921
1922 /* other nid->control mapping */
1923 for (i = 0; i < spec->num_mixers; i++) {
1924 for (knew = spec->mixers[i]; knew->name; knew++) {
1925 if (knew->iface != NID_MAPPING)
1926 continue;
1927 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
1928 if (kctl == NULL)
1929 continue;
1930 err = snd_hda_add_nid(codec, kctl, 0,
1931 knew->subdevice);
1932 }
1933 }
1934
1935 /* init power states */
1936 set_jack_power_state(codec);
1937 analog_low_current_mode(codec, 1);
1938
856 via_free_kctls(codec); /* no longer needed */ 1939 via_free_kctls(codec); /* no longer needed */
857 return 0; 1940 return 0;
858} 1941}
@@ -866,8 +1949,10 @@ static int via_build_pcms(struct hda_codec *codec)
866 codec->pcm_info = info; 1949 codec->pcm_info = info;
867 1950
868 info->name = spec->stream_name_analog; 1951 info->name = spec->stream_name_analog;
869 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback); 1952 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
870 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0]; 1953 *(spec->stream_analog_playback);
1954 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
1955 spec->multiout.dac_nids[0];
871 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture); 1956 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
872 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; 1957 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
873 1958
@@ -904,20 +1989,58 @@ static void via_free(struct hda_codec *codec)
904 return; 1989 return;
905 1990
906 via_free_kctls(codec); 1991 via_free_kctls(codec);
1992 vt1708_stop_hp_work(spec);
907 kfree(codec->spec); 1993 kfree(codec->spec);
908} 1994}
909 1995
910/* mute internal speaker if HP is plugged */ 1996/* mute internal speaker if HP is plugged */
911static void via_hp_automute(struct hda_codec *codec) 1997static void via_hp_automute(struct hda_codec *codec)
912{ 1998{
913 unsigned int present; 1999 unsigned int present = 0;
914 struct via_spec *spec = codec->spec; 2000 struct via_spec *spec = codec->spec;
915 2001
916 present = snd_hda_codec_read(codec, spec->autocfg.hp_pins[0], 0, 2002 present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]);
917 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 2003
918 snd_hda_codec_amp_stereo(codec, spec->autocfg.line_out_pins[0], 2004 if (!spec->hp_independent_mode) {
919 HDA_OUTPUT, 0, HDA_AMP_MUTE, 2005 struct snd_ctl_elem_id id;
920 present ? HDA_AMP_MUTE : 0); 2006 /* auto mute */
2007 snd_hda_codec_amp_stereo(
2008 codec, spec->autocfg.line_out_pins[0], HDA_OUTPUT, 0,
2009 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
2010 /* notify change */
2011 memset(&id, 0, sizeof(id));
2012 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2013 strcpy(id.name, "Front Playback Switch");
2014 snd_ctl_notify(codec->bus->card, SNDRV_CTL_EVENT_MASK_VALUE,
2015 &id);
2016 }
2017}
2018
2019/* mute mono out if HP or Line out is plugged */
2020static void via_mono_automute(struct hda_codec *codec)
2021{
2022 unsigned int hp_present, lineout_present;
2023 struct via_spec *spec = codec->spec;
2024
2025 if (spec->codec_type != VT1716S)
2026 return;
2027
2028 lineout_present = snd_hda_jack_detect(codec,
2029 spec->autocfg.line_out_pins[0]);
2030
2031 /* Mute Mono Out if Line Out is plugged */
2032 if (lineout_present) {
2033 snd_hda_codec_amp_stereo(
2034 codec, 0x2A, HDA_OUTPUT, 0, HDA_AMP_MUTE, HDA_AMP_MUTE);
2035 return;
2036 }
2037
2038 hp_present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]);
2039
2040 if (!spec->hp_independent_mode)
2041 snd_hda_codec_amp_stereo(
2042 codec, 0x2A, HDA_OUTPUT, 0, HDA_AMP_MUTE,
2043 hp_present ? HDA_AMP_MUTE : 0);
921} 2044}
922 2045
923static void via_gpio_control(struct hda_codec *codec) 2046static void via_gpio_control(struct hda_codec *codec)
@@ -968,15 +2091,83 @@ static void via_gpio_control(struct hda_codec *codec)
968 } 2091 }
969} 2092}
970 2093
2094/* mute Internal-Speaker if HP is plugged */
2095static void via_speaker_automute(struct hda_codec *codec)
2096{
2097 unsigned int hp_present;
2098 struct via_spec *spec = codec->spec;
2099
2100 if (spec->codec_type != VT2002P && spec->codec_type != VT1812)
2101 return;
2102
2103 hp_present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]);
2104
2105 if (!spec->hp_independent_mode) {
2106 struct snd_ctl_elem_id id;
2107 snd_hda_codec_amp_stereo(
2108 codec, spec->autocfg.speaker_pins[0], HDA_OUTPUT, 0,
2109 HDA_AMP_MUTE, hp_present ? HDA_AMP_MUTE : 0);
2110 /* notify change */
2111 memset(&id, 0, sizeof(id));
2112 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2113 strcpy(id.name, "Speaker Playback Switch");
2114 snd_ctl_notify(codec->bus->card, SNDRV_CTL_EVENT_MASK_VALUE,
2115 &id);
2116 }
2117}
2118
2119/* mute line-out and internal speaker if HP is plugged */
2120static void via_hp_bind_automute(struct hda_codec *codec)
2121{
2122 /* use long instead of int below just to avoid an internal compiler
2123 * error with gcc 4.0.x
2124 */
2125 unsigned long hp_present, present = 0;
2126 struct via_spec *spec = codec->spec;
2127 int i;
2128
2129 if (!spec->autocfg.hp_pins[0] || !spec->autocfg.line_out_pins[0])
2130 return;
2131
2132 hp_present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]);
2133
2134 present = snd_hda_jack_detect(codec, spec->autocfg.line_out_pins[0]);
2135
2136 if (!spec->hp_independent_mode) {
2137 /* Mute Line-Outs */
2138 for (i = 0; i < spec->autocfg.line_outs; i++)
2139 snd_hda_codec_amp_stereo(
2140 codec, spec->autocfg.line_out_pins[i],
2141 HDA_OUTPUT, 0,
2142 HDA_AMP_MUTE, hp_present ? HDA_AMP_MUTE : 0);
2143 if (hp_present)
2144 present = hp_present;
2145 }
2146 /* Speakers */
2147 for (i = 0; i < spec->autocfg.speaker_outs; i++)
2148 snd_hda_codec_amp_stereo(
2149 codec, spec->autocfg.speaker_pins[i], HDA_OUTPUT, 0,
2150 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
2151}
2152
2153
971/* unsolicited event for jack sensing */ 2154/* unsolicited event for jack sensing */
972static void via_unsol_event(struct hda_codec *codec, 2155static void via_unsol_event(struct hda_codec *codec,
973 unsigned int res) 2156 unsigned int res)
974{ 2157{
975 res >>= 26; 2158 res >>= 26;
976 if (res == VIA_HP_EVENT) 2159 if (res & VIA_HP_EVENT)
977 via_hp_automute(codec); 2160 via_hp_automute(codec);
978 else if (res == VIA_GPIO_EVENT) 2161 if (res & VIA_GPIO_EVENT)
979 via_gpio_control(codec); 2162 via_gpio_control(codec);
2163 if (res & VIA_JACK_EVENT)
2164 set_jack_power_state(codec);
2165 if (res & VIA_MONO_EVENT)
2166 via_mono_automute(codec);
2167 if (res & VIA_SPEAKER_EVENT)
2168 via_speaker_automute(codec);
2169 if (res & VIA_BIND_HP_EVENT)
2170 via_hp_bind_automute(codec);
980} 2171}
981 2172
982static int via_init(struct hda_codec *codec) 2173static int via_init(struct hda_codec *codec)
@@ -986,6 +2177,10 @@ static int via_init(struct hda_codec *codec)
986 for (i = 0; i < spec->num_iverbs; i++) 2177 for (i = 0; i < spec->num_iverbs; i++)
987 snd_hda_sequence_write(codec, spec->init_verbs[i]); 2178 snd_hda_sequence_write(codec, spec->init_verbs[i]);
988 2179
2180 spec->codec_type = get_codec_type(codec);
2181 if (spec->codec_type == VT1708BCE)
2182 spec->codec_type = VT1708S; /* VT1708BCE & VT1708S are almost
2183 same */
989 /* Lydia Add for EAPD enable */ 2184 /* Lydia Add for EAPD enable */
990 if (!spec->dig_in_nid) { /* No Digital In connection */ 2185 if (!spec->dig_in_nid) { /* No Digital In connection */
991 if (spec->dig_in_pin) { 2186 if (spec->dig_in_pin) {
@@ -1003,9 +2198,18 @@ static int via_init(struct hda_codec *codec)
1003 if (spec->slave_dig_outs[0]) 2198 if (spec->slave_dig_outs[0])
1004 codec->slave_dig_outs = spec->slave_dig_outs; 2199 codec->slave_dig_outs = spec->slave_dig_outs;
1005 2200
1006 return 0; 2201 return 0;
1007} 2202}
1008 2203
2204#ifdef SND_HDA_NEEDS_RESUME
2205static int via_suspend(struct hda_codec *codec, pm_message_t state)
2206{
2207 struct via_spec *spec = codec->spec;
2208 vt1708_stop_hp_work(spec);
2209 return 0;
2210}
2211#endif
2212
1009#ifdef CONFIG_SND_HDA_POWER_SAVE 2213#ifdef CONFIG_SND_HDA_POWER_SAVE
1010static int via_check_power_status(struct hda_codec *codec, hda_nid_t nid) 2214static int via_check_power_status(struct hda_codec *codec, hda_nid_t nid)
1011{ 2215{
@@ -1021,6 +2225,9 @@ static struct hda_codec_ops via_patch_ops = {
1021 .build_pcms = via_build_pcms, 2225 .build_pcms = via_build_pcms,
1022 .init = via_init, 2226 .init = via_init,
1023 .free = via_free, 2227 .free = via_free,
2228#ifdef SND_HDA_NEEDS_RESUME
2229 .suspend = via_suspend,
2230#endif
1024#ifdef CONFIG_SND_HDA_POWER_SAVE 2231#ifdef CONFIG_SND_HDA_POWER_SAVE
1025 .check_power_status = via_check_power_status, 2232 .check_power_status = via_check_power_status,
1026#endif 2233#endif
@@ -1036,8 +2243,8 @@ static int vt1708_auto_fill_dac_nids(struct via_spec *spec,
1036 spec->multiout.num_dacs = cfg->line_outs; 2243 spec->multiout.num_dacs = cfg->line_outs;
1037 2244
1038 spec->multiout.dac_nids = spec->private_dac_nids; 2245 spec->multiout.dac_nids = spec->private_dac_nids;
1039 2246
1040 for(i = 0; i < 4; i++) { 2247 for (i = 0; i < 4; i++) {
1041 nid = cfg->line_out_pins[i]; 2248 nid = cfg->line_out_pins[i];
1042 if (nid) { 2249 if (nid) {
1043 /* config dac list */ 2250 /* config dac list */
@@ -1067,7 +2274,7 @@ static int vt1708_auto_create_multi_out_ctls(struct via_spec *spec,
1067{ 2274{
1068 char name[32]; 2275 char name[32];
1069 static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" }; 2276 static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
1070 hda_nid_t nid, nid_vol = 0; 2277 hda_nid_t nid, nid_vol, nid_vols[] = {0x17, 0x19, 0x1a, 0x1b};
1071 int i, err; 2278 int i, err;
1072 2279
1073 for (i = 0; i <= AUTO_SEQ_SIDE; i++) { 2280 for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
@@ -1075,9 +2282,8 @@ static int vt1708_auto_create_multi_out_ctls(struct via_spec *spec,
1075 2282
1076 if (!nid) 2283 if (!nid)
1077 continue; 2284 continue;
1078 2285
1079 if (i != AUTO_SEQ_FRONT) 2286 nid_vol = nid_vols[i];
1080 nid_vol = 0x18 + i;
1081 2287
1082 if (i == AUTO_SEQ_CENLFE) { 2288 if (i == AUTO_SEQ_CENLFE) {
1083 /* Center/LFE */ 2289 /* Center/LFE */
@@ -1105,21 +2311,21 @@ static int vt1708_auto_create_multi_out_ctls(struct via_spec *spec,
1105 HDA_OUTPUT)); 2311 HDA_OUTPUT));
1106 if (err < 0) 2312 if (err < 0)
1107 return err; 2313 return err;
1108 } else if (i == AUTO_SEQ_FRONT){ 2314 } else if (i == AUTO_SEQ_FRONT) {
1109 /* add control to mixer index 0 */ 2315 /* add control to mixer index 0 */
1110 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 2316 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1111 "Master Front Playback Volume", 2317 "Master Front Playback Volume",
1112 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, 2318 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
1113 HDA_INPUT)); 2319 HDA_INPUT));
1114 if (err < 0) 2320 if (err < 0)
1115 return err; 2321 return err;
1116 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 2322 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1117 "Master Front Playback Switch", 2323 "Master Front Playback Switch",
1118 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, 2324 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
1119 HDA_INPUT)); 2325 HDA_INPUT));
1120 if (err < 0) 2326 if (err < 0)
1121 return err; 2327 return err;
1122 2328
1123 /* add control to PW3 */ 2329 /* add control to PW3 */
1124 sprintf(name, "%s Playback Volume", chname[i]); 2330 sprintf(name, "%s Playback Volume", chname[i]);
1125 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, 2331 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
@@ -1178,6 +2384,7 @@ static int vt1708_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
1178 return 0; 2384 return 0;
1179 2385
1180 spec->multiout.hp_nid = VT1708_HP_NID; /* AOW3 */ 2386 spec->multiout.hp_nid = VT1708_HP_NID; /* AOW3 */
2387 spec->hp_independent_mode_index = 1;
1181 2388
1182 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 2389 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1183 "Headphone Playback Volume", 2390 "Headphone Playback Volume",
@@ -1218,7 +2425,7 @@ static int vt1708_auto_create_analog_input_ctls(struct via_spec *spec,
1218 case 0x1d: /* Mic */ 2425 case 0x1d: /* Mic */
1219 idx = 2; 2426 idx = 2;
1220 break; 2427 break;
1221 2428
1222 case 0x1e: /* Line In */ 2429 case 0x1e: /* Line In */
1223 idx = 3; 2430 idx = 3;
1224 break; 2431 break;
@@ -1231,8 +2438,7 @@ static int vt1708_auto_create_analog_input_ctls(struct via_spec *spec,
1231 idx = 1; 2438 idx = 1;
1232 break; 2439 break;
1233 } 2440 }
1234 err = via_new_analog_input(spec, cfg->input_pins[i], labels[i], 2441 err = via_new_analog_input(spec, labels[i], idx, 0x17);
1235 idx, 0x17);
1236 if (err < 0) 2442 if (err < 0)
1237 return err; 2443 return err;
1238 imux->items[imux->num_items].label = labels[i]; 2444 imux->items[imux->num_items].label = labels[i];
@@ -1260,16 +2466,60 @@ static void vt1708_set_pinconfig_connect(struct hda_codec *codec, hda_nid_t nid)
1260 def_conf = snd_hda_codec_get_pincfg(codec, nid); 2466 def_conf = snd_hda_codec_get_pincfg(codec, nid);
1261 seqassoc = (unsigned char) get_defcfg_association(def_conf); 2467 seqassoc = (unsigned char) get_defcfg_association(def_conf);
1262 seqassoc = (seqassoc << 4) | get_defcfg_sequence(def_conf); 2468 seqassoc = (seqassoc << 4) | get_defcfg_sequence(def_conf);
1263 if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) { 2469 if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE
1264 if (seqassoc == 0xff) { 2470 && (seqassoc == 0xf0 || seqassoc == 0xff)) {
1265 def_conf = def_conf & (~(AC_JACK_PORT_BOTH << 30)); 2471 def_conf = def_conf & (~(AC_JACK_PORT_BOTH << 30));
1266 snd_hda_codec_set_pincfg(codec, nid, def_conf); 2472 snd_hda_codec_set_pincfg(codec, nid, def_conf);
1267 }
1268 } 2473 }
1269 2474
1270 return; 2475 return;
1271} 2476}
1272 2477
2478static int vt1708_jack_detectect_get(struct snd_kcontrol *kcontrol,
2479 struct snd_ctl_elem_value *ucontrol)
2480{
2481 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2482 struct via_spec *spec = codec->spec;
2483
2484 if (spec->codec_type != VT1708)
2485 return 0;
2486 spec->vt1708_jack_detectect =
2487 !((snd_hda_codec_read(codec, 0x1, 0, 0xf84, 0) >> 8) & 0x1);
2488 ucontrol->value.integer.value[0] = spec->vt1708_jack_detectect;
2489 return 0;
2490}
2491
2492static int vt1708_jack_detectect_put(struct snd_kcontrol *kcontrol,
2493 struct snd_ctl_elem_value *ucontrol)
2494{
2495 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2496 struct via_spec *spec = codec->spec;
2497 int change;
2498
2499 if (spec->codec_type != VT1708)
2500 return 0;
2501 spec->vt1708_jack_detectect = ucontrol->value.integer.value[0];
2502 change = (0x1 & (snd_hda_codec_read(codec, 0x1, 0, 0xf84, 0) >> 8))
2503 == !spec->vt1708_jack_detectect;
2504 if (spec->vt1708_jack_detectect) {
2505 mute_aa_path(codec, 1);
2506 notify_aa_path_ctls(codec);
2507 }
2508 return change;
2509}
2510
2511static struct snd_kcontrol_new vt1708_jack_detectect[] = {
2512 {
2513 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2514 .name = "Jack Detect",
2515 .count = 1,
2516 .info = snd_ctl_boolean_mono_info,
2517 .get = vt1708_jack_detectect_get,
2518 .put = vt1708_jack_detectect_put,
2519 },
2520 {} /* end */
2521};
2522
1273static int vt1708_parse_auto_config(struct hda_codec *codec) 2523static int vt1708_parse_auto_config(struct hda_codec *codec)
1274{ 2524{
1275 struct via_spec *spec = codec->spec; 2525 struct via_spec *spec = codec->spec;
@@ -1297,6 +2547,10 @@ static int vt1708_parse_auto_config(struct hda_codec *codec)
1297 err = vt1708_auto_create_analog_input_ctls(spec, &spec->autocfg); 2547 err = vt1708_auto_create_analog_input_ctls(spec, &spec->autocfg);
1298 if (err < 0) 2548 if (err < 0)
1299 return err; 2549 return err;
2550 /* add jack detect on/off control */
2551 err = snd_hda_add_new_ctls(codec, vt1708_jack_detectect);
2552 if (err < 0)
2553 return err;
1300 2554
1301 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 2555 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
1302 2556
@@ -1314,21 +2568,46 @@ static int vt1708_parse_auto_config(struct hda_codec *codec)
1314 spec->input_mux = &spec->private_imux[0]; 2568 spec->input_mux = &spec->private_imux[0];
1315 2569
1316 if (spec->hp_mux) 2570 if (spec->hp_mux)
1317 spec->mixers[spec->num_mixers++] = via_hp_mixer; 2571 via_hp_build(codec);
1318 2572
2573 via_smart51_build(spec);
1319 return 1; 2574 return 1;
1320} 2575}
1321 2576
1322/* init callback for auto-configuration model -- overriding the default init */ 2577/* init callback for auto-configuration model -- overriding the default init */
1323static int via_auto_init(struct hda_codec *codec) 2578static int via_auto_init(struct hda_codec *codec)
1324{ 2579{
2580 struct via_spec *spec = codec->spec;
2581
1325 via_init(codec); 2582 via_init(codec);
1326 via_auto_init_multi_out(codec); 2583 via_auto_init_multi_out(codec);
1327 via_auto_init_hp_out(codec); 2584 via_auto_init_hp_out(codec);
1328 via_auto_init_analog_input(codec); 2585 via_auto_init_analog_input(codec);
2586 if (spec->codec_type == VT2002P || spec->codec_type == VT1812) {
2587 via_hp_bind_automute(codec);
2588 } else {
2589 via_hp_automute(codec);
2590 via_speaker_automute(codec);
2591 }
2592
1329 return 0; 2593 return 0;
1330} 2594}
1331 2595
2596static void vt1708_update_hp_jack_state(struct work_struct *work)
2597{
2598 struct via_spec *spec = container_of(work, struct via_spec,
2599 vt1708_hp_work.work);
2600 if (spec->codec_type != VT1708)
2601 return;
2602 /* if jack state toggled */
2603 if (spec->vt1708_hp_present
2604 != snd_hda_jack_detect(spec->codec, spec->autocfg.hp_pins[0])) {
2605 spec->vt1708_hp_present ^= 1;
2606 via_hp_automute(spec->codec);
2607 }
2608 vt1708_start_hp_work(spec);
2609}
2610
1332static int get_mux_nids(struct hda_codec *codec) 2611static int get_mux_nids(struct hda_codec *codec)
1333{ 2612{
1334 struct via_spec *spec = codec->spec; 2613 struct via_spec *spec = codec->spec;
@@ -1362,12 +2641,10 @@ static int patch_vt1708(struct hda_codec *codec)
1362 int err; 2641 int err;
1363 2642
1364 /* create a codec specific record */ 2643 /* create a codec specific record */
1365 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 2644 spec = via_new_spec(codec);
1366 if (spec == NULL) 2645 if (spec == NULL)
1367 return -ENOMEM; 2646 return -ENOMEM;
1368 2647
1369 codec->spec = spec;
1370
1371 /* automatic parse from the BIOS config */ 2648 /* automatic parse from the BIOS config */
1372 err = vt1708_parse_auto_config(codec); 2649 err = vt1708_parse_auto_config(codec);
1373 if (err < 0) { 2650 if (err < 0) {
@@ -1378,7 +2655,7 @@ static int patch_vt1708(struct hda_codec *codec)
1378 "from BIOS. Using genenic mode...\n"); 2655 "from BIOS. Using genenic mode...\n");
1379 } 2656 }
1380 2657
1381 2658
1382 spec->stream_name_analog = "VT1708 Analog"; 2659 spec->stream_name_analog = "VT1708 Analog";
1383 spec->stream_analog_playback = &vt1708_pcm_analog_playback; 2660 spec->stream_analog_playback = &vt1708_pcm_analog_playback;
1384 /* disable 32bit format on VT1708 */ 2661 /* disable 32bit format on VT1708 */
@@ -1390,7 +2667,7 @@ static int patch_vt1708(struct hda_codec *codec)
1390 spec->stream_digital_playback = &vt1708_pcm_digital_playback; 2667 spec->stream_digital_playback = &vt1708_pcm_digital_playback;
1391 spec->stream_digital_capture = &vt1708_pcm_digital_capture; 2668 spec->stream_digital_capture = &vt1708_pcm_digital_capture;
1392 2669
1393 2670
1394 if (!spec->adc_nids && spec->input_mux) { 2671 if (!spec->adc_nids && spec->input_mux) {
1395 spec->adc_nids = vt1708_adc_nids; 2672 spec->adc_nids = vt1708_adc_nids;
1396 spec->num_adc_nids = ARRAY_SIZE(vt1708_adc_nids); 2673 spec->num_adc_nids = ARRAY_SIZE(vt1708_adc_nids);
@@ -1405,7 +2682,7 @@ static int patch_vt1708(struct hda_codec *codec)
1405#ifdef CONFIG_SND_HDA_POWER_SAVE 2682#ifdef CONFIG_SND_HDA_POWER_SAVE
1406 spec->loopback.amplist = vt1708_loopbacks; 2683 spec->loopback.amplist = vt1708_loopbacks;
1407#endif 2684#endif
1408 2685 INIT_DELAYED_WORK(&spec->vt1708_hp_work, vt1708_update_hp_jack_state);
1409 return 0; 2686 return 0;
1410} 2687}
1411 2688
@@ -1433,7 +2710,8 @@ static struct snd_kcontrol_new vt1709_capture_mixer[] = {
1433}; 2710};
1434 2711
1435static struct hda_verb vt1709_uniwill_init_verbs[] = { 2712static struct hda_verb vt1709_uniwill_init_verbs[] = {
1436 {0x20, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_HP_EVENT}, 2713 {0x20, AC_VERB_SET_UNSOLICITED_ENABLE,
2714 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
1437 { } 2715 { }
1438}; 2716};
1439 2717
@@ -1473,8 +2751,8 @@ static struct hda_verb vt1709_10ch_volume_init_verbs[] = {
1473 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2751 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1474 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2752 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1475 2753
1476 /* Set input of PW4 as AOW4 */ 2754 /* Set input of PW4 as MW0 */
1477 {0x20, AC_VERB_SET_CONNECT_SEL, 0x1}, 2755 {0x20, AC_VERB_SET_CONNECT_SEL, 0},
1478 /* PW9 Output enable */ 2756 /* PW9 Output enable */
1479 {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 2757 {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1480 { } 2758 { }
@@ -1487,8 +2765,8 @@ static struct hda_pcm_stream vt1709_10ch_pcm_analog_playback = {
1487 .nid = 0x10, /* NID to query formats and rates */ 2765 .nid = 0x10, /* NID to query formats and rates */
1488 .ops = { 2766 .ops = {
1489 .open = via_playback_pcm_open, 2767 .open = via_playback_pcm_open,
1490 .prepare = via_playback_pcm_prepare, 2768 .prepare = via_playback_multi_pcm_prepare,
1491 .cleanup = via_playback_pcm_cleanup 2769 .cleanup = via_playback_multi_pcm_cleanup,
1492 }, 2770 },
1493}; 2771};
1494 2772
@@ -1499,8 +2777,8 @@ static struct hda_pcm_stream vt1709_6ch_pcm_analog_playback = {
1499 .nid = 0x10, /* NID to query formats and rates */ 2777 .nid = 0x10, /* NID to query formats and rates */
1500 .ops = { 2778 .ops = {
1501 .open = via_playback_pcm_open, 2779 .open = via_playback_pcm_open,
1502 .prepare = via_playback_pcm_prepare, 2780 .prepare = via_playback_multi_pcm_prepare,
1503 .cleanup = via_playback_pcm_cleanup 2781 .cleanup = via_playback_multi_pcm_cleanup,
1504 }, 2782 },
1505}; 2783};
1506 2784
@@ -1575,11 +2853,11 @@ static int vt1709_auto_fill_dac_nids(struct via_spec *spec,
1575 spec->multiout.dac_nids[cfg->line_outs] = 0x28; /* AOW4 */ 2853 spec->multiout.dac_nids[cfg->line_outs] = 0x28; /* AOW4 */
1576 2854
1577 } else if (cfg->line_outs == 3) { /* 6 channels */ 2855 } else if (cfg->line_outs == 3) { /* 6 channels */
1578 for(i = 0; i < cfg->line_outs; i++) { 2856 for (i = 0; i < cfg->line_outs; i++) {
1579 nid = cfg->line_out_pins[i]; 2857 nid = cfg->line_out_pins[i];
1580 if (nid) { 2858 if (nid) {
1581 /* config dac list */ 2859 /* config dac list */
1582 switch(i) { 2860 switch (i) {
1583 case AUTO_SEQ_FRONT: 2861 case AUTO_SEQ_FRONT:
1584 /* AOW0 */ 2862 /* AOW0 */
1585 spec->multiout.dac_nids[i] = 0x10; 2863 spec->multiout.dac_nids[i] = 0x10;
@@ -1608,56 +2886,58 @@ static int vt1709_auto_create_multi_out_ctls(struct via_spec *spec,
1608{ 2886{
1609 char name[32]; 2887 char name[32];
1610 static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" }; 2888 static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
1611 hda_nid_t nid = 0; 2889 hda_nid_t nid, nid_vol, nid_vols[] = {0x18, 0x1a, 0x1b, 0x29};
1612 int i, err; 2890 int i, err;
1613 2891
1614 for (i = 0; i <= AUTO_SEQ_SIDE; i++) { 2892 for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
1615 nid = cfg->line_out_pins[i]; 2893 nid = cfg->line_out_pins[i];
1616 2894
1617 if (!nid) 2895 if (!nid)
1618 continue; 2896 continue;
1619 2897
2898 nid_vol = nid_vols[i];
2899
1620 if (i == AUTO_SEQ_CENLFE) { 2900 if (i == AUTO_SEQ_CENLFE) {
1621 /* Center/LFE */ 2901 /* Center/LFE */
1622 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 2902 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1623 "Center Playback Volume", 2903 "Center Playback Volume",
1624 HDA_COMPOSE_AMP_VAL(0x1b, 1, 0, 2904 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
1625 HDA_OUTPUT)); 2905 HDA_OUTPUT));
1626 if (err < 0) 2906 if (err < 0)
1627 return err; 2907 return err;
1628 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 2908 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1629 "LFE Playback Volume", 2909 "LFE Playback Volume",
1630 HDA_COMPOSE_AMP_VAL(0x1b, 2, 0, 2910 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
1631 HDA_OUTPUT)); 2911 HDA_OUTPUT));
1632 if (err < 0) 2912 if (err < 0)
1633 return err; 2913 return err;
1634 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 2914 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1635 "Center Playback Switch", 2915 "Center Playback Switch",
1636 HDA_COMPOSE_AMP_VAL(0x1b, 1, 0, 2916 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
1637 HDA_OUTPUT)); 2917 HDA_OUTPUT));
1638 if (err < 0) 2918 if (err < 0)
1639 return err; 2919 return err;
1640 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 2920 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1641 "LFE Playback Switch", 2921 "LFE Playback Switch",
1642 HDA_COMPOSE_AMP_VAL(0x1b, 2, 0, 2922 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
1643 HDA_OUTPUT)); 2923 HDA_OUTPUT));
1644 if (err < 0) 2924 if (err < 0)
1645 return err; 2925 return err;
1646 } else if (i == AUTO_SEQ_FRONT){ 2926 } else if (i == AUTO_SEQ_FRONT) {
1647 /* add control to mixer index 0 */ 2927 /* ADD control to mixer index 0 */
1648 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 2928 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1649 "Master Front Playback Volume", 2929 "Master Front Playback Volume",
1650 HDA_COMPOSE_AMP_VAL(0x18, 3, 0, 2930 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
1651 HDA_INPUT)); 2931 HDA_INPUT));
1652 if (err < 0) 2932 if (err < 0)
1653 return err; 2933 return err;
1654 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 2934 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1655 "Master Front Playback Switch", 2935 "Master Front Playback Switch",
1656 HDA_COMPOSE_AMP_VAL(0x18, 3, 0, 2936 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
1657 HDA_INPUT)); 2937 HDA_INPUT));
1658 if (err < 0) 2938 if (err < 0)
1659 return err; 2939 return err;
1660 2940
1661 /* add control to PW3 */ 2941 /* add control to PW3 */
1662 sprintf(name, "%s Playback Volume", chname[i]); 2942 sprintf(name, "%s Playback Volume", chname[i]);
1663 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, 2943 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
@@ -1674,26 +2954,26 @@ static int vt1709_auto_create_multi_out_ctls(struct via_spec *spec,
1674 } else if (i == AUTO_SEQ_SURROUND) { 2954 } else if (i == AUTO_SEQ_SURROUND) {
1675 sprintf(name, "%s Playback Volume", chname[i]); 2955 sprintf(name, "%s Playback Volume", chname[i]);
1676 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, 2956 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
1677 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, 2957 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
1678 HDA_OUTPUT)); 2958 HDA_OUTPUT));
1679 if (err < 0) 2959 if (err < 0)
1680 return err; 2960 return err;
1681 sprintf(name, "%s Playback Switch", chname[i]); 2961 sprintf(name, "%s Playback Switch", chname[i]);
1682 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name, 2962 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
1683 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, 2963 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
1684 HDA_OUTPUT)); 2964 HDA_OUTPUT));
1685 if (err < 0) 2965 if (err < 0)
1686 return err; 2966 return err;
1687 } else if (i == AUTO_SEQ_SIDE) { 2967 } else if (i == AUTO_SEQ_SIDE) {
1688 sprintf(name, "%s Playback Volume", chname[i]); 2968 sprintf(name, "%s Playback Volume", chname[i]);
1689 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, 2969 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
1690 HDA_COMPOSE_AMP_VAL(0x29, 3, 0, 2970 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
1691 HDA_OUTPUT)); 2971 HDA_OUTPUT));
1692 if (err < 0) 2972 if (err < 0)
1693 return err; 2973 return err;
1694 sprintf(name, "%s Playback Switch", chname[i]); 2974 sprintf(name, "%s Playback Switch", chname[i]);
1695 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name, 2975 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
1696 HDA_COMPOSE_AMP_VAL(0x29, 3, 0, 2976 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
1697 HDA_OUTPUT)); 2977 HDA_OUTPUT));
1698 if (err < 0) 2978 if (err < 0)
1699 return err; 2979 return err;
@@ -1714,6 +2994,7 @@ static int vt1709_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
1714 spec->multiout.hp_nid = VT1709_HP_DAC_NID; 2994 spec->multiout.hp_nid = VT1709_HP_DAC_NID;
1715 else if (spec->multiout.num_dacs == 3) /* 6 channels */ 2995 else if (spec->multiout.num_dacs == 3) /* 6 channels */
1716 spec->multiout.hp_nid = 0; 2996 spec->multiout.hp_nid = 0;
2997 spec->hp_independent_mode_index = 1;
1717 2998
1718 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 2999 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1719 "Headphone Playback Volume", 3000 "Headphone Playback Volume",
@@ -1752,7 +3033,7 @@ static int vt1709_auto_create_analog_input_ctls(struct via_spec *spec,
1752 case 0x1d: /* Mic */ 3033 case 0x1d: /* Mic */
1753 idx = 2; 3034 idx = 2;
1754 break; 3035 break;
1755 3036
1756 case 0x1e: /* Line In */ 3037 case 0x1e: /* Line In */
1757 idx = 3; 3038 idx = 3;
1758 break; 3039 break;
@@ -1765,8 +3046,7 @@ static int vt1709_auto_create_analog_input_ctls(struct via_spec *spec,
1765 idx = 1; 3046 idx = 1;
1766 break; 3047 break;
1767 } 3048 }
1768 err = via_new_analog_input(spec, cfg->input_pins[i], labels[i], 3049 err = via_new_analog_input(spec, labels[i], idx, 0x18);
1769 idx, 0x18);
1770 if (err < 0) 3050 if (err < 0)
1771 return err; 3051 return err;
1772 imux->items[imux->num_items].label = labels[i]; 3052 imux->items[imux->num_items].label = labels[i];
@@ -1814,8 +3094,9 @@ static int vt1709_parse_auto_config(struct hda_codec *codec)
1814 spec->input_mux = &spec->private_imux[0]; 3094 spec->input_mux = &spec->private_imux[0];
1815 3095
1816 if (spec->hp_mux) 3096 if (spec->hp_mux)
1817 spec->mixers[spec->num_mixers++] = via_hp_mixer; 3097 via_hp_build(codec);
1818 3098
3099 via_smart51_build(spec);
1819 return 1; 3100 return 1;
1820} 3101}
1821 3102
@@ -1835,12 +3116,10 @@ static int patch_vt1709_10ch(struct hda_codec *codec)
1835 int err; 3116 int err;
1836 3117
1837 /* create a codec specific record */ 3118 /* create a codec specific record */
1838 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 3119 spec = via_new_spec(codec);
1839 if (spec == NULL) 3120 if (spec == NULL)
1840 return -ENOMEM; 3121 return -ENOMEM;
1841 3122
1842 codec->spec = spec;
1843
1844 err = vt1709_parse_auto_config(codec); 3123 err = vt1709_parse_auto_config(codec);
1845 if (err < 0) { 3124 if (err < 0) {
1846 via_free(codec); 3125 via_free(codec);
@@ -1861,7 +3140,7 @@ static int patch_vt1709_10ch(struct hda_codec *codec)
1861 spec->stream_digital_playback = &vt1709_pcm_digital_playback; 3140 spec->stream_digital_playback = &vt1709_pcm_digital_playback;
1862 spec->stream_digital_capture = &vt1709_pcm_digital_capture; 3141 spec->stream_digital_capture = &vt1709_pcm_digital_capture;
1863 3142
1864 3143
1865 if (!spec->adc_nids && spec->input_mux) { 3144 if (!spec->adc_nids && spec->input_mux) {
1866 spec->adc_nids = vt1709_adc_nids; 3145 spec->adc_nids = vt1709_adc_nids;
1867 spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids); 3146 spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids);
@@ -1929,12 +3208,10 @@ static int patch_vt1709_6ch(struct hda_codec *codec)
1929 int err; 3208 int err;
1930 3209
1931 /* create a codec specific record */ 3210 /* create a codec specific record */
1932 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 3211 spec = via_new_spec(codec);
1933 if (spec == NULL) 3212 if (spec == NULL)
1934 return -ENOMEM; 3213 return -ENOMEM;
1935 3214
1936 codec->spec = spec;
1937
1938 err = vt1709_parse_auto_config(codec); 3215 err = vt1709_parse_auto_config(codec);
1939 if (err < 0) { 3216 if (err < 0) {
1940 via_free(codec); 3217 via_free(codec);
@@ -1955,7 +3232,7 @@ static int patch_vt1709_6ch(struct hda_codec *codec)
1955 spec->stream_digital_playback = &vt1709_pcm_digital_playback; 3232 spec->stream_digital_playback = &vt1709_pcm_digital_playback;
1956 spec->stream_digital_capture = &vt1709_pcm_digital_capture; 3233 spec->stream_digital_capture = &vt1709_pcm_digital_capture;
1957 3234
1958 3235
1959 if (!spec->adc_nids && spec->input_mux) { 3236 if (!spec->adc_nids && spec->input_mux) {
1960 spec->adc_nids = vt1709_adc_nids; 3237 spec->adc_nids = vt1709_adc_nids;
1961 spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids); 3238 spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids);
@@ -2024,7 +3301,7 @@ static struct hda_verb vt1708B_8ch_volume_init_verbs[] = {
2024 {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3301 {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2025 3302
2026 /* Setup default input to PW4 */ 3303 /* Setup default input to PW4 */
2027 {0x1d, AC_VERB_SET_CONNECT_SEL, 0x1}, 3304 {0x1d, AC_VERB_SET_CONNECT_SEL, 0},
2028 /* PW9 Output enable */ 3305 /* PW9 Output enable */
2029 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 3306 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
2030 /* PW10 Input enable */ 3307 /* PW10 Input enable */
@@ -2068,10 +3345,29 @@ static struct hda_verb vt1708B_4ch_volume_init_verbs[] = {
2068}; 3345};
2069 3346
2070static struct hda_verb vt1708B_uniwill_init_verbs[] = { 3347static struct hda_verb vt1708B_uniwill_init_verbs[] = {
2071 {0x1D, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_HP_EVENT}, 3348 {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE,
3349 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
3350 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3351 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3352 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3353 {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3354 {0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3355 {0x22, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3356 {0x23, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
2072 { } 3357 { }
2073}; 3358};
2074 3359
3360static int via_pcm_open_close(struct hda_pcm_stream *hinfo,
3361 struct hda_codec *codec,
3362 struct snd_pcm_substream *substream)
3363{
3364 int idle = substream->pstr->substream_opened == 1
3365 && substream->ref_count == 0;
3366
3367 analog_low_current_mode(codec, idle);
3368 return 0;
3369}
3370
2075static struct hda_pcm_stream vt1708B_8ch_pcm_analog_playback = { 3371static struct hda_pcm_stream vt1708B_8ch_pcm_analog_playback = {
2076 .substreams = 2, 3372 .substreams = 2,
2077 .channels_min = 2, 3373 .channels_min = 2,
@@ -2080,7 +3376,8 @@ static struct hda_pcm_stream vt1708B_8ch_pcm_analog_playback = {
2080 .ops = { 3376 .ops = {
2081 .open = via_playback_pcm_open, 3377 .open = via_playback_pcm_open,
2082 .prepare = via_playback_multi_pcm_prepare, 3378 .prepare = via_playback_multi_pcm_prepare,
2083 .cleanup = via_playback_multi_pcm_cleanup 3379 .cleanup = via_playback_multi_pcm_cleanup,
3380 .close = via_pcm_open_close
2084 }, 3381 },
2085}; 3382};
2086 3383
@@ -2102,8 +3399,10 @@ static struct hda_pcm_stream vt1708B_pcm_analog_capture = {
2102 .channels_max = 2, 3399 .channels_max = 2,
2103 .nid = 0x13, /* NID to query formats and rates */ 3400 .nid = 0x13, /* NID to query formats and rates */
2104 .ops = { 3401 .ops = {
3402 .open = via_pcm_open_close,
2105 .prepare = via_capture_pcm_prepare, 3403 .prepare = via_capture_pcm_prepare,
2106 .cleanup = via_capture_pcm_cleanup 3404 .cleanup = via_capture_pcm_cleanup,
3405 .close = via_pcm_open_close
2107 }, 3406 },
2108}; 3407};
2109 3408
@@ -2260,6 +3559,7 @@ static int vt1708B_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
2260 return 0; 3559 return 0;
2261 3560
2262 spec->multiout.hp_nid = VT1708B_HP_NID; /* AOW3 */ 3561 spec->multiout.hp_nid = VT1708B_HP_NID; /* AOW3 */
3562 spec->hp_independent_mode_index = 1;
2263 3563
2264 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 3564 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2265 "Headphone Playback Volume", 3565 "Headphone Playback Volume",
@@ -2313,8 +3613,7 @@ static int vt1708B_auto_create_analog_input_ctls(struct via_spec *spec,
2313 idx = 1; 3613 idx = 1;
2314 break; 3614 break;
2315 } 3615 }
2316 err = via_new_analog_input(spec, cfg->input_pins[i], labels[i], 3616 err = via_new_analog_input(spec, labels[i], idx, 0x16);
2317 idx, 0x16);
2318 if (err < 0) 3617 if (err < 0)
2319 return err; 3618 return err;
2320 imux->items[imux->num_items].label = labels[i]; 3619 imux->items[imux->num_items].label = labels[i];
@@ -2362,8 +3661,9 @@ static int vt1708B_parse_auto_config(struct hda_codec *codec)
2362 spec->input_mux = &spec->private_imux[0]; 3661 spec->input_mux = &spec->private_imux[0];
2363 3662
2364 if (spec->hp_mux) 3663 if (spec->hp_mux)
2365 spec->mixers[spec->num_mixers++] = via_hp_mixer; 3664 via_hp_build(codec);
2366 3665
3666 via_smart51_build(spec);
2367 return 1; 3667 return 1;
2368} 3668}
2369 3669
@@ -2376,19 +3676,19 @@ static struct hda_amp_list vt1708B_loopbacks[] = {
2376 { } /* end */ 3676 { } /* end */
2377}; 3677};
2378#endif 3678#endif
2379 3679static int patch_vt1708S(struct hda_codec *codec);
2380static int patch_vt1708B_8ch(struct hda_codec *codec) 3680static int patch_vt1708B_8ch(struct hda_codec *codec)
2381{ 3681{
2382 struct via_spec *spec; 3682 struct via_spec *spec;
2383 int err; 3683 int err;
2384 3684
3685 if (get_codec_type(codec) == VT1708BCE)
3686 return patch_vt1708S(codec);
2385 /* create a codec specific record */ 3687 /* create a codec specific record */
2386 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 3688 spec = via_new_spec(codec);
2387 if (spec == NULL) 3689 if (spec == NULL)
2388 return -ENOMEM; 3690 return -ENOMEM;
2389 3691
2390 codec->spec = spec;
2391
2392 /* automatic parse from the BIOS config */ 3692 /* automatic parse from the BIOS config */
2393 err = vt1708B_parse_auto_config(codec); 3693 err = vt1708B_parse_auto_config(codec);
2394 if (err < 0) { 3694 if (err < 0) {
@@ -2435,12 +3735,10 @@ static int patch_vt1708B_4ch(struct hda_codec *codec)
2435 int err; 3735 int err;
2436 3736
2437 /* create a codec specific record */ 3737 /* create a codec specific record */
2438 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 3738 spec = via_new_spec(codec);
2439 if (spec == NULL) 3739 if (spec == NULL)
2440 return -ENOMEM; 3740 return -ENOMEM;
2441 3741
2442 codec->spec = spec;
2443
2444 /* automatic parse from the BIOS config */ 3742 /* automatic parse from the BIOS config */
2445 err = vt1708B_parse_auto_config(codec); 3743 err = vt1708B_parse_auto_config(codec);
2446 if (err < 0) { 3744 if (err < 0) {
@@ -2483,29 +3781,15 @@ static int patch_vt1708B_4ch(struct hda_codec *codec)
2483 3781
2484/* Patch for VT1708S */ 3782/* Patch for VT1708S */
2485 3783
2486/* VT1708S software backdoor based override for buggy hardware micboost
2487 * setting */
2488#define MIC_BOOST_VOLUME(xname, nid) { \
2489 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2490 .name = xname, \
2491 .index = 0, \
2492 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2493 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2494 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, \
2495 .info = mic_boost_volume_info, \
2496 .get = snd_hda_mixer_amp_volume_get, \
2497 .put = snd_hda_mixer_amp_volume_put, \
2498 .tlv = { .c = mic_boost_tlv }, \
2499 .private_value = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT) }
2500
2501/* capture mixer elements */ 3784/* capture mixer elements */
2502static struct snd_kcontrol_new vt1708S_capture_mixer[] = { 3785static struct snd_kcontrol_new vt1708S_capture_mixer[] = {
2503 HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT), 3786 HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT),
2504 HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT), 3787 HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT),
2505 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT), 3788 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT),
2506 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x14, 0x0, HDA_INPUT), 3789 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x14, 0x0, HDA_INPUT),
2507 MIC_BOOST_VOLUME("Mic Boost Capture Volume", 0x1A), 3790 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x1A, 0x0, HDA_INPUT),
2508 MIC_BOOST_VOLUME("Front Mic Boost Capture Volume", 0x1E), 3791 HDA_CODEC_VOLUME("Front Mic Boost Capture Volume", 0x1E, 0x0,
3792 HDA_INPUT),
2509 { 3793 {
2510 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3794 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2511 /* The multiple "Capture Source" controls confuse alsamixer 3795 /* The multiple "Capture Source" controls confuse alsamixer
@@ -2542,11 +3826,21 @@ static struct hda_verb vt1708S_volume_init_verbs[] = {
2542 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 3826 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
2543 /* Enable Mic Boost Volume backdoor */ 3827 /* Enable Mic Boost Volume backdoor */
2544 {0x1, 0xf98, 0x1}, 3828 {0x1, 0xf98, 0x1},
3829 /* don't bybass mixer */
3830 {0x1, 0xf88, 0xc0},
2545 { } 3831 { }
2546}; 3832};
2547 3833
2548static struct hda_verb vt1708S_uniwill_init_verbs[] = { 3834static struct hda_verb vt1708S_uniwill_init_verbs[] = {
2549 {0x1D, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_HP_EVENT}, 3835 {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE,
3836 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
3837 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3838 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3839 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3840 {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3841 {0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3842 {0x22, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3843 {0x23, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
2550 { } 3844 { }
2551}; 3845};
2552 3846
@@ -2557,8 +3851,9 @@ static struct hda_pcm_stream vt1708S_pcm_analog_playback = {
2557 .nid = 0x10, /* NID to query formats and rates */ 3851 .nid = 0x10, /* NID to query formats and rates */
2558 .ops = { 3852 .ops = {
2559 .open = via_playback_pcm_open, 3853 .open = via_playback_pcm_open,
2560 .prepare = via_playback_pcm_prepare, 3854 .prepare = via_playback_multi_pcm_prepare,
2561 .cleanup = via_playback_pcm_cleanup 3855 .cleanup = via_playback_multi_pcm_cleanup,
3856 .close = via_pcm_open_close
2562 }, 3857 },
2563}; 3858};
2564 3859
@@ -2568,8 +3863,10 @@ static struct hda_pcm_stream vt1708S_pcm_analog_capture = {
2568 .channels_max = 2, 3863 .channels_max = 2,
2569 .nid = 0x13, /* NID to query formats and rates */ 3864 .nid = 0x13, /* NID to query formats and rates */
2570 .ops = { 3865 .ops = {
3866 .open = via_pcm_open_close,
2571 .prepare = via_capture_pcm_prepare, 3867 .prepare = via_capture_pcm_prepare,
2572 .cleanup = via_capture_pcm_cleanup 3868 .cleanup = via_capture_pcm_cleanup,
3869 .close = via_pcm_open_close
2573 }, 3870 },
2574}; 3871};
2575 3872
@@ -2726,6 +4023,7 @@ static int vt1708S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
2726 return 0; 4023 return 0;
2727 4024
2728 spec->multiout.hp_nid = VT1708S_HP_NID; /* AOW3 */ 4025 spec->multiout.hp_nid = VT1708S_HP_NID; /* AOW3 */
4026 spec->hp_independent_mode_index = 1;
2729 4027
2730 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 4028 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2731 "Headphone Playback Volume", 4029 "Headphone Playback Volume",
@@ -2780,8 +4078,7 @@ static int vt1708S_auto_create_analog_input_ctls(struct via_spec *spec,
2780 idx = 1; 4078 idx = 1;
2781 break; 4079 break;
2782 } 4080 }
2783 err = via_new_analog_input(spec, cfg->input_pins[i], labels[i], 4081 err = via_new_analog_input(spec, labels[i], idx, 0x16);
2784 idx, 0x16);
2785 if (err < 0) 4082 if (err < 0)
2786 return err; 4083 return err;
2787 imux->items[imux->num_items].label = labels[i]; 4084 imux->items[imux->num_items].label = labels[i];
@@ -2850,8 +4147,9 @@ static int vt1708S_parse_auto_config(struct hda_codec *codec)
2850 spec->input_mux = &spec->private_imux[0]; 4147 spec->input_mux = &spec->private_imux[0];
2851 4148
2852 if (spec->hp_mux) 4149 if (spec->hp_mux)
2853 spec->mixers[spec->num_mixers++] = via_hp_mixer; 4150 via_hp_build(codec);
2854 4151
4152 via_smart51_build(spec);
2855 return 1; 4153 return 1;
2856} 4154}
2857 4155
@@ -2865,18 +4163,26 @@ static struct hda_amp_list vt1708S_loopbacks[] = {
2865}; 4163};
2866#endif 4164#endif
2867 4165
4166static void override_mic_boost(struct hda_codec *codec, hda_nid_t pin,
4167 int offset, int num_steps, int step_size)
4168{
4169 snd_hda_override_amp_caps(codec, pin, HDA_INPUT,
4170 (offset << AC_AMPCAP_OFFSET_SHIFT) |
4171 (num_steps << AC_AMPCAP_NUM_STEPS_SHIFT) |
4172 (step_size << AC_AMPCAP_STEP_SIZE_SHIFT) |
4173 (0 << AC_AMPCAP_MUTE_SHIFT));
4174}
4175
2868static int patch_vt1708S(struct hda_codec *codec) 4176static int patch_vt1708S(struct hda_codec *codec)
2869{ 4177{
2870 struct via_spec *spec; 4178 struct via_spec *spec;
2871 int err; 4179 int err;
2872 4180
2873 /* create a codec specific record */ 4181 /* create a codec specific record */
2874 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 4182 spec = via_new_spec(codec);
2875 if (spec == NULL) 4183 if (spec == NULL)
2876 return -ENOMEM; 4184 return -ENOMEM;
2877 4185
2878 codec->spec = spec;
2879
2880 /* automatic parse from the BIOS config */ 4186 /* automatic parse from the BIOS config */
2881 err = vt1708S_parse_auto_config(codec); 4187 err = vt1708S_parse_auto_config(codec);
2882 if (err < 0) { 4188 if (err < 0) {
@@ -2890,17 +4196,25 @@ static int patch_vt1708S(struct hda_codec *codec)
2890 spec->init_verbs[spec->num_iverbs++] = vt1708S_volume_init_verbs; 4196 spec->init_verbs[spec->num_iverbs++] = vt1708S_volume_init_verbs;
2891 spec->init_verbs[spec->num_iverbs++] = vt1708S_uniwill_init_verbs; 4197 spec->init_verbs[spec->num_iverbs++] = vt1708S_uniwill_init_verbs;
2892 4198
2893 spec->stream_name_analog = "VT1708S Analog"; 4199 if (codec->vendor_id == 0x11060440)
4200 spec->stream_name_analog = "VT1818S Analog";
4201 else
4202 spec->stream_name_analog = "VT1708S Analog";
2894 spec->stream_analog_playback = &vt1708S_pcm_analog_playback; 4203 spec->stream_analog_playback = &vt1708S_pcm_analog_playback;
2895 spec->stream_analog_capture = &vt1708S_pcm_analog_capture; 4204 spec->stream_analog_capture = &vt1708S_pcm_analog_capture;
2896 4205
2897 spec->stream_name_digital = "VT1708S Digital"; 4206 if (codec->vendor_id == 0x11060440)
4207 spec->stream_name_digital = "VT1818S Digital";
4208 else
4209 spec->stream_name_digital = "VT1708S Digital";
2898 spec->stream_digital_playback = &vt1708S_pcm_digital_playback; 4210 spec->stream_digital_playback = &vt1708S_pcm_digital_playback;
2899 4211
2900 if (!spec->adc_nids && spec->input_mux) { 4212 if (!spec->adc_nids && spec->input_mux) {
2901 spec->adc_nids = vt1708S_adc_nids; 4213 spec->adc_nids = vt1708S_adc_nids;
2902 spec->num_adc_nids = ARRAY_SIZE(vt1708S_adc_nids); 4214 spec->num_adc_nids = ARRAY_SIZE(vt1708S_adc_nids);
2903 get_mux_nids(codec); 4215 get_mux_nids(codec);
4216 override_mic_boost(codec, 0x1a, 0, 3, 40);
4217 override_mic_boost(codec, 0x1e, 0, 3, 40);
2904 spec->mixers[spec->num_mixers] = vt1708S_capture_mixer; 4218 spec->mixers[spec->num_mixers] = vt1708S_capture_mixer;
2905 spec->num_mixers++; 4219 spec->num_mixers++;
2906 } 4220 }
@@ -2913,6 +4227,16 @@ static int patch_vt1708S(struct hda_codec *codec)
2913 spec->loopback.amplist = vt1708S_loopbacks; 4227 spec->loopback.amplist = vt1708S_loopbacks;
2914#endif 4228#endif
2915 4229
4230 /* correct names for VT1708BCE */
4231 if (get_codec_type(codec) == VT1708BCE) {
4232 kfree(codec->chip_name);
4233 codec->chip_name = kstrdup("VT1708BCE", GFP_KERNEL);
4234 snprintf(codec->bus->card->mixername,
4235 sizeof(codec->bus->card->mixername),
4236 "%s %s", codec->vendor_name, codec->chip_name);
4237 spec->stream_name_analog = "VT1708BCE Analog";
4238 spec->stream_name_digital = "VT1708BCE Digital";
4239 }
2916 return 0; 4240 return 0;
2917} 4241}
2918 4242
@@ -2967,12 +4291,20 @@ static struct hda_verb vt1702_volume_init_verbs[] = {
2967 /* PW6 PW7 Output enable */ 4291 /* PW6 PW7 Output enable */
2968 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 4292 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
2969 {0x1C, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 4293 {0x1C, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4294 /* mixer enable */
4295 {0x1, 0xF88, 0x3},
4296 /* GPIO 0~2 */
4297 {0x1, 0xF82, 0x3F},
2970 { } 4298 { }
2971}; 4299};
2972 4300
2973static struct hda_verb vt1702_uniwill_init_verbs[] = { 4301static struct hda_verb vt1702_uniwill_init_verbs[] = {
2974 {0x01, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_GPIO_EVENT}, 4302 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE,
2975 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_HP_EVENT}, 4303 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
4304 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4305 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4306 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4307 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
2976 { } 4308 { }
2977}; 4309};
2978 4310
@@ -2984,7 +4316,8 @@ static struct hda_pcm_stream vt1702_pcm_analog_playback = {
2984 .ops = { 4316 .ops = {
2985 .open = via_playback_pcm_open, 4317 .open = via_playback_pcm_open,
2986 .prepare = via_playback_multi_pcm_prepare, 4318 .prepare = via_playback_multi_pcm_prepare,
2987 .cleanup = via_playback_multi_pcm_cleanup 4319 .cleanup = via_playback_multi_pcm_cleanup,
4320 .close = via_pcm_open_close
2988 }, 4321 },
2989}; 4322};
2990 4323
@@ -2994,8 +4327,10 @@ static struct hda_pcm_stream vt1702_pcm_analog_capture = {
2994 .channels_max = 2, 4327 .channels_max = 2,
2995 .nid = 0x12, /* NID to query formats and rates */ 4328 .nid = 0x12, /* NID to query formats and rates */
2996 .ops = { 4329 .ops = {
4330 .open = via_pcm_open_close,
2997 .prepare = via_capture_pcm_prepare, 4331 .prepare = via_capture_pcm_prepare,
2998 .cleanup = via_capture_pcm_cleanup 4332 .cleanup = via_capture_pcm_cleanup,
4333 .close = via_pcm_open_close
2999 }, 4334 },
3000}; 4335};
3001 4336
@@ -3065,12 +4400,13 @@ static int vt1702_auto_create_line_out_ctls(struct via_spec *spec,
3065 4400
3066static int vt1702_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) 4401static int vt1702_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
3067{ 4402{
3068 int err; 4403 int err, i;
3069 4404 struct hda_input_mux *imux;
4405 static const char *texts[] = { "ON", "OFF", NULL};
3070 if (!pin) 4406 if (!pin)
3071 return 0; 4407 return 0;
3072
3073 spec->multiout.hp_nid = 0x1D; 4408 spec->multiout.hp_nid = 0x1D;
4409 spec->hp_independent_mode_index = 0;
3074 4410
3075 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 4411 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3076 "Headphone Playback Volume", 4412 "Headphone Playback Volume",
@@ -3084,8 +4420,18 @@ static int vt1702_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
3084 if (err < 0) 4420 if (err < 0)
3085 return err; 4421 return err;
3086 4422
3087 create_hp_imux(spec); 4423 imux = &spec->private_imux[1];
4424
4425 /* for hp mode select */
4426 i = 0;
4427 while (texts[i] != NULL) {
4428 imux->items[imux->num_items].label = texts[i];
4429 imux->items[imux->num_items].index = i;
4430 imux->num_items++;
4431 i++;
4432 }
3088 4433
4434 spec->hp_mux = &spec->private_imux[1];
3089 return 0; 4435 return 0;
3090} 4436}
3091 4437
@@ -3121,8 +4467,7 @@ static int vt1702_auto_create_analog_input_ctls(struct via_spec *spec,
3121 idx = 3; 4467 idx = 3;
3122 break; 4468 break;
3123 } 4469 }
3124 err = via_new_analog_input(spec, cfg->input_pins[i], 4470 err = via_new_analog_input(spec, labels[i], idx, 0x1A);
3125 labels[i], idx, 0x1A);
3126 if (err < 0) 4471 if (err < 0)
3127 return err; 4472 return err;
3128 imux->items[imux->num_items].label = labels[i]; 4473 imux->items[imux->num_items].label = labels[i];
@@ -3152,6 +4497,12 @@ static int vt1702_parse_auto_config(struct hda_codec *codec)
3152 err = vt1702_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); 4497 err = vt1702_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
3153 if (err < 0) 4498 if (err < 0)
3154 return err; 4499 return err;
4500 /* limit AA path volume to 0 dB */
4501 snd_hda_override_amp_caps(codec, 0x1A, HDA_INPUT,
4502 (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
4503 (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
4504 (0x5 << AC_AMPCAP_STEP_SIZE_SHIFT) |
4505 (1 << AC_AMPCAP_MUTE_SHIFT));
3155 err = vt1702_auto_create_analog_input_ctls(spec, &spec->autocfg); 4506 err = vt1702_auto_create_analog_input_ctls(spec, &spec->autocfg);
3156 if (err < 0) 4507 if (err < 0)
3157 return err; 4508 return err;
@@ -3166,7 +4517,7 @@ static int vt1702_parse_auto_config(struct hda_codec *codec)
3166 spec->input_mux = &spec->private_imux[0]; 4517 spec->input_mux = &spec->private_imux[0];
3167 4518
3168 if (spec->hp_mux) 4519 if (spec->hp_mux)
3169 spec->mixers[spec->num_mixers++] = via_hp_mixer; 4520 via_hp_build(codec);
3170 4521
3171 return 1; 4522 return 1;
3172} 4523}
@@ -3185,16 +4536,12 @@ static int patch_vt1702(struct hda_codec *codec)
3185{ 4536{
3186 struct via_spec *spec; 4537 struct via_spec *spec;
3187 int err; 4538 int err;
3188 unsigned int response;
3189 unsigned char control;
3190 4539
3191 /* create a codec specific record */ 4540 /* create a codec specific record */
3192 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 4541 spec = via_new_spec(codec);
3193 if (spec == NULL) 4542 if (spec == NULL)
3194 return -ENOMEM; 4543 return -ENOMEM;
3195 4544
3196 codec->spec = spec;
3197
3198 /* automatic parse from the BIOS config */ 4545 /* automatic parse from the BIOS config */
3199 err = vt1702_parse_auto_config(codec); 4546 err = vt1702_parse_auto_config(codec);
3200 if (err < 0) { 4547 if (err < 0) {
@@ -3231,17 +4578,1631 @@ static int patch_vt1702(struct hda_codec *codec)
3231 spec->loopback.amplist = vt1702_loopbacks; 4578 spec->loopback.amplist = vt1702_loopbacks;
3232#endif 4579#endif
3233 4580
3234 /* Open backdoor */ 4581 return 0;
3235 response = snd_hda_codec_read(codec, codec->afg, 0, 0xF8C, 0); 4582}
3236 control = (unsigned char)(response & 0xff); 4583
3237 control |= 0x3; 4584/* Patch for VT1718S */
3238 snd_hda_codec_write(codec, codec->afg, 0, 0xF88, control); 4585
4586/* capture mixer elements */
4587static struct snd_kcontrol_new vt1718S_capture_mixer[] = {
4588 HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT),
4589 HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT),
4590 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT),
4591 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x11, 0x0, HDA_INPUT),
4592 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x2b, 0x0, HDA_INPUT),
4593 HDA_CODEC_VOLUME("Front Mic Boost Capture Volume", 0x29, 0x0,
4594 HDA_INPUT),
4595 {
4596 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4597 /* The multiple "Capture Source" controls confuse alsamixer
4598 * So call somewhat different..
4599 */
4600 .name = "Input Source",
4601 .count = 2,
4602 .info = via_mux_enum_info,
4603 .get = via_mux_enum_get,
4604 .put = via_mux_enum_put,
4605 },
4606 { } /* end */
4607};
4608
4609static struct hda_verb vt1718S_volume_init_verbs[] = {
4610 /*
4611 * Unmute ADC0-1 and set the default input to mic-in
4612 */
4613 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4614 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4615
4616
4617 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4618 * mixer widget
4619 */
4620 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
4621 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4622 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4623 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4624 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4625 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
4626
4627 /* Setup default input of Front HP to MW9 */
4628 {0x28, AC_VERB_SET_CONNECT_SEL, 0x1},
4629 /* PW9 PW10 Output enable */
4630 {0x2d, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_OUT_EN},
4631 {0x2e, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_OUT_EN},
4632 /* PW11 Input enable */
4633 {0x2f, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_IN_EN},
4634 /* Enable Boost Volume backdoor */
4635 {0x1, 0xf88, 0x8},
4636 /* MW0/1/2/3/4: un-mute index 0 (AOWx), mute index 1 (MW9) */
4637 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4638 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4639 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4640 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4641 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4642 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4643 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4644 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4645 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4646 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4647 /* set MUX1 = 2 (AOW4), MUX2 = 1 (AOW3) */
4648 {0x34, AC_VERB_SET_CONNECT_SEL, 0x2},
4649 {0x35, AC_VERB_SET_CONNECT_SEL, 0x1},
4650 /* Unmute MW4's index 0 */
4651 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4652 { }
4653};
4654
4655
4656static struct hda_verb vt1718S_uniwill_init_verbs[] = {
4657 {0x28, AC_VERB_SET_UNSOLICITED_ENABLE,
4658 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
4659 {0x24, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4660 {0x25, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4661 {0x26, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4662 {0x27, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4663 {0x29, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4664 {0x2a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4665 {0x2b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4666 { }
4667};
4668
4669static struct hda_pcm_stream vt1718S_pcm_analog_playback = {
4670 .substreams = 2,
4671 .channels_min = 2,
4672 .channels_max = 10,
4673 .nid = 0x8, /* NID to query formats and rates */
4674 .ops = {
4675 .open = via_playback_pcm_open,
4676 .prepare = via_playback_multi_pcm_prepare,
4677 .cleanup = via_playback_multi_pcm_cleanup,
4678 .close = via_pcm_open_close,
4679 },
4680};
4681
4682static struct hda_pcm_stream vt1718S_pcm_analog_capture = {
4683 .substreams = 2,
4684 .channels_min = 2,
4685 .channels_max = 2,
4686 .nid = 0x10, /* NID to query formats and rates */
4687 .ops = {
4688 .open = via_pcm_open_close,
4689 .prepare = via_capture_pcm_prepare,
4690 .cleanup = via_capture_pcm_cleanup,
4691 .close = via_pcm_open_close,
4692 },
4693};
4694
4695static struct hda_pcm_stream vt1718S_pcm_digital_playback = {
4696 .substreams = 2,
4697 .channels_min = 2,
4698 .channels_max = 2,
4699 /* NID is set in via_build_pcms */
4700 .ops = {
4701 .open = via_dig_playback_pcm_open,
4702 .close = via_dig_playback_pcm_close,
4703 .prepare = via_dig_playback_pcm_prepare,
4704 .cleanup = via_dig_playback_pcm_cleanup
4705 },
4706};
4707
4708static struct hda_pcm_stream vt1718S_pcm_digital_capture = {
4709 .substreams = 1,
4710 .channels_min = 2,
4711 .channels_max = 2,
4712};
4713
4714/* fill in the dac_nids table from the parsed pin configuration */
4715static int vt1718S_auto_fill_dac_nids(struct via_spec *spec,
4716 const struct auto_pin_cfg *cfg)
4717{
4718 int i;
4719 hda_nid_t nid;
4720
4721 spec->multiout.num_dacs = cfg->line_outs;
4722
4723 spec->multiout.dac_nids = spec->private_dac_nids;
4724
4725 for (i = 0; i < 4; i++) {
4726 nid = cfg->line_out_pins[i];
4727 if (nid) {
4728 /* config dac list */
4729 switch (i) {
4730 case AUTO_SEQ_FRONT:
4731 spec->multiout.dac_nids[i] = 0x8;
4732 break;
4733 case AUTO_SEQ_CENLFE:
4734 spec->multiout.dac_nids[i] = 0xa;
4735 break;
4736 case AUTO_SEQ_SURROUND:
4737 spec->multiout.dac_nids[i] = 0x9;
4738 break;
4739 case AUTO_SEQ_SIDE:
4740 spec->multiout.dac_nids[i] = 0xb;
4741 break;
4742 }
4743 }
4744 }
4745
4746 return 0;
4747}
4748
4749/* add playback controls from the parsed DAC table */
4750static int vt1718S_auto_create_multi_out_ctls(struct via_spec *spec,
4751 const struct auto_pin_cfg *cfg)
4752{
4753 char name[32];
4754 static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
4755 hda_nid_t nid_vols[] = {0x8, 0x9, 0xa, 0xb};
4756 hda_nid_t nid_mutes[] = {0x24, 0x25, 0x26, 0x27};
4757 hda_nid_t nid, nid_vol, nid_mute = 0;
4758 int i, err;
4759
4760 for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
4761 nid = cfg->line_out_pins[i];
4762
4763 if (!nid)
4764 continue;
4765 nid_vol = nid_vols[i];
4766 nid_mute = nid_mutes[i];
4767
4768 if (i == AUTO_SEQ_CENLFE) {
4769 /* Center/LFE */
4770 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
4771 "Center Playback Volume",
4772 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
4773 HDA_OUTPUT));
4774 if (err < 0)
4775 return err;
4776 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
4777 "LFE Playback Volume",
4778 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
4779 HDA_OUTPUT));
4780 if (err < 0)
4781 return err;
4782 err = via_add_control(
4783 spec, VIA_CTL_WIDGET_MUTE,
4784 "Center Playback Switch",
4785 HDA_COMPOSE_AMP_VAL(nid_mute, 1, 0,
4786 HDA_OUTPUT));
4787 if (err < 0)
4788 return err;
4789 err = via_add_control(
4790 spec, VIA_CTL_WIDGET_MUTE,
4791 "LFE Playback Switch",
4792 HDA_COMPOSE_AMP_VAL(nid_mute, 2, 0,
4793 HDA_OUTPUT));
4794 if (err < 0)
4795 return err;
4796 } else if (i == AUTO_SEQ_FRONT) {
4797 /* Front */
4798 sprintf(name, "%s Playback Volume", chname[i]);
4799 err = via_add_control(
4800 spec, VIA_CTL_WIDGET_VOL, name,
4801 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT));
4802 if (err < 0)
4803 return err;
4804 sprintf(name, "%s Playback Switch", chname[i]);
4805 err = via_add_control(
4806 spec, VIA_CTL_WIDGET_MUTE, name,
4807 HDA_COMPOSE_AMP_VAL(nid_mute, 3, 0,
4808 HDA_OUTPUT));
4809 if (err < 0)
4810 return err;
4811 } else {
4812 sprintf(name, "%s Playback Volume", chname[i]);
4813 err = via_add_control(
4814 spec, VIA_CTL_WIDGET_VOL, name,
4815 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT));
4816 if (err < 0)
4817 return err;
4818 sprintf(name, "%s Playback Switch", chname[i]);
4819 err = via_add_control(
4820 spec, VIA_CTL_WIDGET_MUTE, name,
4821 HDA_COMPOSE_AMP_VAL(nid_mute, 3, 0,
4822 HDA_OUTPUT));
4823 if (err < 0)
4824 return err;
4825 }
4826 }
4827 return 0;
4828}
4829
4830static int vt1718S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
4831{
4832 int err;
4833
4834 if (!pin)
4835 return 0;
4836
4837 spec->multiout.hp_nid = 0xc; /* AOW4 */
4838 spec->hp_independent_mode_index = 1;
4839
4840 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
4841 "Headphone Playback Volume",
4842 HDA_COMPOSE_AMP_VAL(0xc, 3, 0, HDA_OUTPUT));
4843 if (err < 0)
4844 return err;
4845
4846 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
4847 "Headphone Playback Switch",
4848 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4849 if (err < 0)
4850 return err;
4851
4852 create_hp_imux(spec);
4853 return 0;
4854}
4855
4856/* create playback/capture controls for input pins */
4857static int vt1718S_auto_create_analog_input_ctls(struct via_spec *spec,
4858 const struct auto_pin_cfg *cfg)
4859{
4860 static char *labels[] = {
4861 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
4862 };
4863 struct hda_input_mux *imux = &spec->private_imux[0];
4864 int i, err, idx = 0;
4865
4866 /* for internal loopback recording select */
4867 imux->items[imux->num_items].label = "Stereo Mixer";
4868 imux->items[imux->num_items].index = 5;
4869 imux->num_items++;
4870
4871 for (i = 0; i < AUTO_PIN_LAST; i++) {
4872 if (!cfg->input_pins[i])
4873 continue;
4874
4875 switch (cfg->input_pins[i]) {
4876 case 0x2b: /* Mic */
4877 idx = 1;
4878 break;
4879
4880 case 0x2a: /* Line In */
4881 idx = 2;
4882 break;
4883
4884 case 0x29: /* Front Mic */
4885 idx = 3;
4886 break;
4887
4888 case 0x2c: /* CD */
4889 idx = 0;
4890 break;
4891 }
4892 err = via_new_analog_input(spec, labels[i], idx, 0x21);
4893 if (err < 0)
4894 return err;
4895 imux->items[imux->num_items].label = labels[i];
4896 imux->items[imux->num_items].index = idx;
4897 imux->num_items++;
4898 }
4899 return 0;
4900}
4901
4902static int vt1718S_parse_auto_config(struct hda_codec *codec)
4903{
4904 struct via_spec *spec = codec->spec;
4905 int err;
4906
4907 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
4908
4909 if (err < 0)
4910 return err;
4911 err = vt1718S_auto_fill_dac_nids(spec, &spec->autocfg);
4912 if (err < 0)
4913 return err;
4914 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
4915 return 0; /* can't find valid BIOS pin config */
4916
4917 err = vt1718S_auto_create_multi_out_ctls(spec, &spec->autocfg);
4918 if (err < 0)
4919 return err;
4920 err = vt1718S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
4921 if (err < 0)
4922 return err;
4923 err = vt1718S_auto_create_analog_input_ctls(spec, &spec->autocfg);
4924 if (err < 0)
4925 return err;
4926
4927 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4928
4929 fill_dig_outs(codec);
4930
4931 if (spec->autocfg.dig_in_pin && codec->vendor_id == 0x11060428)
4932 spec->dig_in_nid = 0x13;
4933
4934 if (spec->kctls.list)
4935 spec->mixers[spec->num_mixers++] = spec->kctls.list;
4936
4937 spec->input_mux = &spec->private_imux[0];
4938
4939 if (spec->hp_mux)
4940 via_hp_build(codec);
4941
4942 via_smart51_build(spec);
4943
4944 return 1;
4945}
4946
4947#ifdef CONFIG_SND_HDA_POWER_SAVE
4948static struct hda_amp_list vt1718S_loopbacks[] = {
4949 { 0x21, HDA_INPUT, 1 },
4950 { 0x21, HDA_INPUT, 2 },
4951 { 0x21, HDA_INPUT, 3 },
4952 { 0x21, HDA_INPUT, 4 },
4953 { } /* end */
4954};
4955#endif
4956
4957static int patch_vt1718S(struct hda_codec *codec)
4958{
4959 struct via_spec *spec;
4960 int err;
4961
4962 /* create a codec specific record */
4963 spec = via_new_spec(codec);
4964 if (spec == NULL)
4965 return -ENOMEM;
4966
4967 /* automatic parse from the BIOS config */
4968 err = vt1718S_parse_auto_config(codec);
4969 if (err < 0) {
4970 via_free(codec);
4971 return err;
4972 } else if (!err) {
4973 printk(KERN_INFO "hda_codec: Cannot set up configuration "
4974 "from BIOS. Using genenic mode...\n");
4975 }
4976
4977 spec->init_verbs[spec->num_iverbs++] = vt1718S_volume_init_verbs;
4978 spec->init_verbs[spec->num_iverbs++] = vt1718S_uniwill_init_verbs;
4979
4980 if (codec->vendor_id == 0x11060441)
4981 spec->stream_name_analog = "VT2020 Analog";
4982 else if (codec->vendor_id == 0x11064441)
4983 spec->stream_name_analog = "VT1828S Analog";
4984 else
4985 spec->stream_name_analog = "VT1718S Analog";
4986 spec->stream_analog_playback = &vt1718S_pcm_analog_playback;
4987 spec->stream_analog_capture = &vt1718S_pcm_analog_capture;
4988
4989 if (codec->vendor_id == 0x11060441)
4990 spec->stream_name_digital = "VT2020 Digital";
4991 else if (codec->vendor_id == 0x11064441)
4992 spec->stream_name_digital = "VT1828S Digital";
4993 else
4994 spec->stream_name_digital = "VT1718S Digital";
4995 spec->stream_digital_playback = &vt1718S_pcm_digital_playback;
4996 if (codec->vendor_id == 0x11060428 || codec->vendor_id == 0x11060441)
4997 spec->stream_digital_capture = &vt1718S_pcm_digital_capture;
4998
4999 if (!spec->adc_nids && spec->input_mux) {
5000 spec->adc_nids = vt1718S_adc_nids;
5001 spec->num_adc_nids = ARRAY_SIZE(vt1718S_adc_nids);
5002 get_mux_nids(codec);
5003 override_mic_boost(codec, 0x2b, 0, 3, 40);
5004 override_mic_boost(codec, 0x29, 0, 3, 40);
5005 spec->mixers[spec->num_mixers] = vt1718S_capture_mixer;
5006 spec->num_mixers++;
5007 }
5008
5009 codec->patch_ops = via_patch_ops;
5010
5011 codec->patch_ops.init = via_auto_init;
5012 codec->patch_ops.unsol_event = via_unsol_event;
5013
5014#ifdef CONFIG_SND_HDA_POWER_SAVE
5015 spec->loopback.amplist = vt1718S_loopbacks;
5016#endif
5017
5018 return 0;
5019}
5020
5021/* Patch for VT1716S */
5022
5023static int vt1716s_dmic_info(struct snd_kcontrol *kcontrol,
5024 struct snd_ctl_elem_info *uinfo)
5025{
5026 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
5027 uinfo->count = 1;
5028 uinfo->value.integer.min = 0;
5029 uinfo->value.integer.max = 1;
5030 return 0;
5031}
5032
5033static int vt1716s_dmic_get(struct snd_kcontrol *kcontrol,
5034 struct snd_ctl_elem_value *ucontrol)
5035{
5036 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5037 int index = 0;
5038
5039 index = snd_hda_codec_read(codec, 0x26, 0,
5040 AC_VERB_GET_CONNECT_SEL, 0);
5041 if (index != -1)
5042 *ucontrol->value.integer.value = index;
5043
5044 return 0;
5045}
5046
5047static int vt1716s_dmic_put(struct snd_kcontrol *kcontrol,
5048 struct snd_ctl_elem_value *ucontrol)
5049{
5050 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5051 struct via_spec *spec = codec->spec;
5052 int index = *ucontrol->value.integer.value;
5053
5054 snd_hda_codec_write(codec, 0x26, 0,
5055 AC_VERB_SET_CONNECT_SEL, index);
5056 spec->dmic_enabled = index;
5057 set_jack_power_state(codec);
5058
5059 return 1;
5060}
5061
5062/* capture mixer elements */
5063static struct snd_kcontrol_new vt1716S_capture_mixer[] = {
5064 HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT),
5065 HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT),
5066 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT),
5067 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x14, 0x0, HDA_INPUT),
5068 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x1A, 0x0, HDA_INPUT),
5069 HDA_CODEC_VOLUME("Front Mic Boost Capture Volume", 0x1E, 0x0,
5070 HDA_INPUT),
5071 {
5072 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5073 .name = "Input Source",
5074 .count = 1,
5075 .info = via_mux_enum_info,
5076 .get = via_mux_enum_get,
5077 .put = via_mux_enum_put,
5078 },
5079 { } /* end */
5080};
5081
5082static struct snd_kcontrol_new vt1716s_dmic_mixer[] = {
5083 HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x22, 0x0, HDA_INPUT),
5084 {
5085 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5086 .name = "Digital Mic Capture Switch",
5087 .subdevice = HDA_SUBDEV_NID_FLAG | 0x26,
5088 .count = 1,
5089 .info = vt1716s_dmic_info,
5090 .get = vt1716s_dmic_get,
5091 .put = vt1716s_dmic_put,
5092 },
5093 {} /* end */
5094};
5095
5096
5097/* mono-out mixer elements */
5098static struct snd_kcontrol_new vt1716S_mono_out_mixer[] = {
5099 HDA_CODEC_MUTE("Mono Playback Switch", 0x2a, 0x0, HDA_OUTPUT),
5100 { } /* end */
5101};
5102
5103static struct hda_verb vt1716S_volume_init_verbs[] = {
5104 /*
5105 * Unmute ADC0-1 and set the default input to mic-in
5106 */
5107 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5108 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5109
5110
5111 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5112 * mixer widget
5113 */
5114 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
5115 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5116 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5117 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5118 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5119 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5120
5121 /* MUX Indices: Stereo Mixer = 5 */
5122 {0x17, AC_VERB_SET_CONNECT_SEL, 0x5},
5123
5124 /* Setup default input of PW4 to MW0 */
5125 {0x1d, AC_VERB_SET_CONNECT_SEL, 0x0},
5126
5127 /* Setup default input of SW1 as MW0 */
5128 {0x18, AC_VERB_SET_CONNECT_SEL, 0x1},
5129
5130 /* Setup default input of SW4 as AOW0 */
5131 {0x28, AC_VERB_SET_CONNECT_SEL, 0x1},
5132
5133 /* PW9 PW10 Output enable */
5134 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5135 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5136
5137 /* Unmute SW1, PW12 */
5138 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5139 {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5140 /* PW12 Output enable */
5141 {0x2a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5142 /* Enable Boost Volume backdoor */
5143 {0x1, 0xf8a, 0x80},
5144 /* don't bybass mixer */
5145 {0x1, 0xf88, 0xc0},
5146 /* Enable mono output */
5147 {0x1, 0xf90, 0x08},
5148 { }
5149};
5150
5151
5152static struct hda_verb vt1716S_uniwill_init_verbs[] = {
5153 {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE,
5154 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
5155 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5156 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5157 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5158 {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE,
5159 AC_USRSP_EN | VIA_MONO_EVENT | VIA_JACK_EVENT},
5160 {0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5161 {0x23, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5162 { }
5163};
5164
5165static struct hda_pcm_stream vt1716S_pcm_analog_playback = {
5166 .substreams = 2,
5167 .channels_min = 2,
5168 .channels_max = 6,
5169 .nid = 0x10, /* NID to query formats and rates */
5170 .ops = {
5171 .open = via_playback_pcm_open,
5172 .prepare = via_playback_multi_pcm_prepare,
5173 .cleanup = via_playback_multi_pcm_cleanup,
5174 .close = via_pcm_open_close,
5175 },
5176};
5177
5178static struct hda_pcm_stream vt1716S_pcm_analog_capture = {
5179 .substreams = 2,
5180 .channels_min = 2,
5181 .channels_max = 2,
5182 .nid = 0x13, /* NID to query formats and rates */
5183 .ops = {
5184 .open = via_pcm_open_close,
5185 .prepare = via_capture_pcm_prepare,
5186 .cleanup = via_capture_pcm_cleanup,
5187 .close = via_pcm_open_close,
5188 },
5189};
5190
5191static struct hda_pcm_stream vt1716S_pcm_digital_playback = {
5192 .substreams = 2,
5193 .channels_min = 2,
5194 .channels_max = 2,
5195 /* NID is set in via_build_pcms */
5196 .ops = {
5197 .open = via_dig_playback_pcm_open,
5198 .close = via_dig_playback_pcm_close,
5199 .prepare = via_dig_playback_pcm_prepare,
5200 .cleanup = via_dig_playback_pcm_cleanup
5201 },
5202};
5203
5204/* fill in the dac_nids table from the parsed pin configuration */
5205static int vt1716S_auto_fill_dac_nids(struct via_spec *spec,
5206 const struct auto_pin_cfg *cfg)
5207{ int i;
5208 hda_nid_t nid;
5209
5210 spec->multiout.num_dacs = cfg->line_outs;
5211
5212 spec->multiout.dac_nids = spec->private_dac_nids;
5213
5214 for (i = 0; i < 3; i++) {
5215 nid = cfg->line_out_pins[i];
5216 if (nid) {
5217 /* config dac list */
5218 switch (i) {
5219 case AUTO_SEQ_FRONT:
5220 spec->multiout.dac_nids[i] = 0x10;
5221 break;
5222 case AUTO_SEQ_CENLFE:
5223 spec->multiout.dac_nids[i] = 0x25;
5224 break;
5225 case AUTO_SEQ_SURROUND:
5226 spec->multiout.dac_nids[i] = 0x11;
5227 break;
5228 }
5229 }
5230 }
5231
5232 return 0;
5233}
5234
5235/* add playback controls from the parsed DAC table */
5236static int vt1716S_auto_create_multi_out_ctls(struct via_spec *spec,
5237 const struct auto_pin_cfg *cfg)
5238{
5239 char name[32];
5240 static const char *chname[3] = { "Front", "Surround", "C/LFE" };
5241 hda_nid_t nid_vols[] = {0x10, 0x11, 0x25};
5242 hda_nid_t nid_mutes[] = {0x1C, 0x18, 0x27};
5243 hda_nid_t nid, nid_vol, nid_mute;
5244 int i, err;
5245
5246 for (i = 0; i <= AUTO_SEQ_CENLFE; i++) {
5247 nid = cfg->line_out_pins[i];
5248
5249 if (!nid)
5250 continue;
5251
5252 nid_vol = nid_vols[i];
5253 nid_mute = nid_mutes[i];
5254
5255 if (i == AUTO_SEQ_CENLFE) {
5256 err = via_add_control(
5257 spec, VIA_CTL_WIDGET_VOL,
5258 "Center Playback Volume",
5259 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0, HDA_OUTPUT));
5260 if (err < 0)
5261 return err;
5262 err = via_add_control(
5263 spec, VIA_CTL_WIDGET_VOL,
5264 "LFE Playback Volume",
5265 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT));
5266 if (err < 0)
5267 return err;
5268 err = via_add_control(
5269 spec, VIA_CTL_WIDGET_MUTE,
5270 "Center Playback Switch",
5271 HDA_COMPOSE_AMP_VAL(nid_mute, 1, 0,
5272 HDA_OUTPUT));
5273 if (err < 0)
5274 return err;
5275 err = via_add_control(
5276 spec, VIA_CTL_WIDGET_MUTE,
5277 "LFE Playback Switch",
5278 HDA_COMPOSE_AMP_VAL(nid_mute, 2, 0,
5279 HDA_OUTPUT));
5280 if (err < 0)
5281 return err;
5282 } else if (i == AUTO_SEQ_FRONT) {
5283
5284 err = via_add_control(
5285 spec, VIA_CTL_WIDGET_VOL,
5286 "Master Front Playback Volume",
5287 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_INPUT));
5288 if (err < 0)
5289 return err;
5290 err = via_add_control(
5291 spec, VIA_CTL_WIDGET_MUTE,
5292 "Master Front Playback Switch",
5293 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_INPUT));
5294 if (err < 0)
5295 return err;
5296
5297 sprintf(name, "%s Playback Volume", chname[i]);
5298 err = via_add_control(
5299 spec, VIA_CTL_WIDGET_VOL, name,
5300 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT));
5301 if (err < 0)
5302 return err;
5303 sprintf(name, "%s Playback Switch", chname[i]);
5304 err = via_add_control(
5305 spec, VIA_CTL_WIDGET_MUTE, name,
5306 HDA_COMPOSE_AMP_VAL(nid_mute, 3, 0,
5307 HDA_OUTPUT));
5308 if (err < 0)
5309 return err;
5310 } else {
5311 sprintf(name, "%s Playback Volume", chname[i]);
5312 err = via_add_control(
5313 spec, VIA_CTL_WIDGET_VOL, name,
5314 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT));
5315 if (err < 0)
5316 return err;
5317 sprintf(name, "%s Playback Switch", chname[i]);
5318 err = via_add_control(
5319 spec, VIA_CTL_WIDGET_MUTE, name,
5320 HDA_COMPOSE_AMP_VAL(nid_mute, 3, 0,
5321 HDA_OUTPUT));
5322 if (err < 0)
5323 return err;
5324 }
5325 }
5326 return 0;
5327}
5328
5329static int vt1716S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
5330{
5331 int err;
5332
5333 if (!pin)
5334 return 0;
5335
5336 spec->multiout.hp_nid = 0x25; /* AOW3 */
5337 spec->hp_independent_mode_index = 1;
5338
5339 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
5340 "Headphone Playback Volume",
5341 HDA_COMPOSE_AMP_VAL(0x25, 3, 0, HDA_OUTPUT));
5342 if (err < 0)
5343 return err;
5344
5345 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
5346 "Headphone Playback Switch",
5347 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
5348 if (err < 0)
5349 return err;
5350
5351 create_hp_imux(spec);
5352 return 0;
5353}
5354
5355/* create playback/capture controls for input pins */
5356static int vt1716S_auto_create_analog_input_ctls(struct via_spec *spec,
5357 const struct auto_pin_cfg *cfg)
5358{
5359 static char *labels[] = {
5360 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
5361 };
5362 struct hda_input_mux *imux = &spec->private_imux[0];
5363 int i, err, idx = 0;
5364
5365 /* for internal loopback recording select */
5366 imux->items[imux->num_items].label = "Stereo Mixer";
5367 imux->items[imux->num_items].index = 5;
5368 imux->num_items++;
5369
5370 for (i = 0; i < AUTO_PIN_LAST; i++) {
5371 if (!cfg->input_pins[i])
5372 continue;
5373
5374 switch (cfg->input_pins[i]) {
5375 case 0x1a: /* Mic */
5376 idx = 2;
5377 break;
5378
5379 case 0x1b: /* Line In */
5380 idx = 3;
5381 break;
5382
5383 case 0x1e: /* Front Mic */
5384 idx = 4;
5385 break;
5386
5387 case 0x1f: /* CD */
5388 idx = 1;
5389 break;
5390 }
5391 err = via_new_analog_input(spec, labels[i], idx, 0x16);
5392 if (err < 0)
5393 return err;
5394 imux->items[imux->num_items].label = labels[i];
5395 imux->items[imux->num_items].index = idx-1;
5396 imux->num_items++;
5397 }
5398 return 0;
5399}
5400
5401static int vt1716S_parse_auto_config(struct hda_codec *codec)
5402{
5403 struct via_spec *spec = codec->spec;
5404 int err;
5405
5406 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
5407 if (err < 0)
5408 return err;
5409 err = vt1716S_auto_fill_dac_nids(spec, &spec->autocfg);
5410 if (err < 0)
5411 return err;
5412 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
5413 return 0; /* can't find valid BIOS pin config */
5414
5415 err = vt1716S_auto_create_multi_out_ctls(spec, &spec->autocfg);
5416 if (err < 0)
5417 return err;
5418 err = vt1716S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
5419 if (err < 0)
5420 return err;
5421 err = vt1716S_auto_create_analog_input_ctls(spec, &spec->autocfg);
5422 if (err < 0)
5423 return err;
5424
5425 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5426
5427 fill_dig_outs(codec);
5428
5429 if (spec->kctls.list)
5430 spec->mixers[spec->num_mixers++] = spec->kctls.list;
5431
5432 spec->input_mux = &spec->private_imux[0];
5433
5434 if (spec->hp_mux)
5435 via_hp_build(codec);
5436
5437 via_smart51_build(spec);
5438
5439 return 1;
5440}
5441
5442#ifdef CONFIG_SND_HDA_POWER_SAVE
5443static struct hda_amp_list vt1716S_loopbacks[] = {
5444 { 0x16, HDA_INPUT, 1 },
5445 { 0x16, HDA_INPUT, 2 },
5446 { 0x16, HDA_INPUT, 3 },
5447 { 0x16, HDA_INPUT, 4 },
5448 { } /* end */
5449};
5450#endif
5451
5452static int patch_vt1716S(struct hda_codec *codec)
5453{
5454 struct via_spec *spec;
5455 int err;
5456
5457 /* create a codec specific record */
5458 spec = via_new_spec(codec);
5459 if (spec == NULL)
5460 return -ENOMEM;
5461
5462 /* automatic parse from the BIOS config */
5463 err = vt1716S_parse_auto_config(codec);
5464 if (err < 0) {
5465 via_free(codec);
5466 return err;
5467 } else if (!err) {
5468 printk(KERN_INFO "hda_codec: Cannot set up configuration "
5469 "from BIOS. Using genenic mode...\n");
5470 }
5471
5472 spec->init_verbs[spec->num_iverbs++] = vt1716S_volume_init_verbs;
5473 spec->init_verbs[spec->num_iverbs++] = vt1716S_uniwill_init_verbs;
5474
5475 spec->stream_name_analog = "VT1716S Analog";
5476 spec->stream_analog_playback = &vt1716S_pcm_analog_playback;
5477 spec->stream_analog_capture = &vt1716S_pcm_analog_capture;
5478
5479 spec->stream_name_digital = "VT1716S Digital";
5480 spec->stream_digital_playback = &vt1716S_pcm_digital_playback;
5481
5482 if (!spec->adc_nids && spec->input_mux) {
5483 spec->adc_nids = vt1716S_adc_nids;
5484 spec->num_adc_nids = ARRAY_SIZE(vt1716S_adc_nids);
5485 get_mux_nids(codec);
5486 override_mic_boost(codec, 0x1a, 0, 3, 40);
5487 override_mic_boost(codec, 0x1e, 0, 3, 40);
5488 spec->mixers[spec->num_mixers] = vt1716S_capture_mixer;
5489 spec->num_mixers++;
5490 }
5491
5492 spec->mixers[spec->num_mixers] = vt1716s_dmic_mixer;
5493 spec->num_mixers++;
5494
5495 spec->mixers[spec->num_mixers++] = vt1716S_mono_out_mixer;
5496
5497 codec->patch_ops = via_patch_ops;
5498
5499 codec->patch_ops.init = via_auto_init;
5500 codec->patch_ops.unsol_event = via_unsol_event;
5501
5502#ifdef CONFIG_SND_HDA_POWER_SAVE
5503 spec->loopback.amplist = vt1716S_loopbacks;
5504#endif
5505
5506 return 0;
5507}
5508
5509/* for vt2002P */
5510
5511/* capture mixer elements */
5512static struct snd_kcontrol_new vt2002P_capture_mixer[] = {
5513 HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT),
5514 HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT),
5515 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT),
5516 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x11, 0x0, HDA_INPUT),
5517 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x2b, 0x0, HDA_INPUT),
5518 HDA_CODEC_VOLUME("Front Mic Boost Capture Volume", 0x29, 0x0,
5519 HDA_INPUT),
5520 {
5521 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5522 /* The multiple "Capture Source" controls confuse alsamixer
5523 * So call somewhat different..
5524 */
5525 /* .name = "Capture Source", */
5526 .name = "Input Source",
5527 .count = 2,
5528 .info = via_mux_enum_info,
5529 .get = via_mux_enum_get,
5530 .put = via_mux_enum_put,
5531 },
5532 { } /* end */
5533};
5534
5535static struct hda_verb vt2002P_volume_init_verbs[] = {
5536 /*
5537 * Unmute ADC0-1 and set the default input to mic-in
5538 */
5539 {0x8, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5540 {0x9, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5541
5542
5543 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5544 * mixer widget
5545 */
5546 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
5547 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5548 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5549 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5550 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5551 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5552
5553 /* MUX Indices: Mic = 0 */
5554 {0x1e, AC_VERB_SET_CONNECT_SEL, 0},
5555 {0x1f, AC_VERB_SET_CONNECT_SEL, 0},
5556
5557 /* PW9 Output enable */
5558 {0x2d, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_OUT_EN},
5559
5560 /* Enable Boost Volume backdoor */
5561 {0x1, 0xfb9, 0x24},
5562
5563 /* MW0/1/4/8: un-mute index 0 (MUXx), un-mute index 1 (MW9) */
5564 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5565 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5566 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5567 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5568 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5569 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5570 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5571 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5572
5573 /* set MUX0/1/4/8 = 0 (AOW0) */
5574 {0x34, AC_VERB_SET_CONNECT_SEL, 0},
5575 {0x35, AC_VERB_SET_CONNECT_SEL, 0},
5576 {0x37, AC_VERB_SET_CONNECT_SEL, 0},
5577 {0x3b, AC_VERB_SET_CONNECT_SEL, 0},
5578
5579 /* set PW0 index=0 (MW0) */
5580 {0x24, AC_VERB_SET_CONNECT_SEL, 0},
5581
5582 /* Enable AOW0 to MW9 */
5583 {0x1, 0xfb8, 0x88},
5584 { }
5585};
5586
5587
5588static struct hda_verb vt2002P_uniwill_init_verbs[] = {
5589 {0x25, AC_VERB_SET_UNSOLICITED_ENABLE,
5590 AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT},
5591 {0x26, AC_VERB_SET_UNSOLICITED_ENABLE,
5592 AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT},
5593 {0x29, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5594 {0x2a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5595 {0x2b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5596 { }
5597};
5598
5599static struct hda_pcm_stream vt2002P_pcm_analog_playback = {
5600 .substreams = 2,
5601 .channels_min = 2,
5602 .channels_max = 2,
5603 .nid = 0x8, /* NID to query formats and rates */
5604 .ops = {
5605 .open = via_playback_pcm_open,
5606 .prepare = via_playback_multi_pcm_prepare,
5607 .cleanup = via_playback_multi_pcm_cleanup,
5608 .close = via_pcm_open_close,
5609 },
5610};
5611
5612static struct hda_pcm_stream vt2002P_pcm_analog_capture = {
5613 .substreams = 2,
5614 .channels_min = 2,
5615 .channels_max = 2,
5616 .nid = 0x10, /* NID to query formats and rates */
5617 .ops = {
5618 .open = via_pcm_open_close,
5619 .prepare = via_capture_pcm_prepare,
5620 .cleanup = via_capture_pcm_cleanup,
5621 .close = via_pcm_open_close,
5622 },
5623};
5624
5625static struct hda_pcm_stream vt2002P_pcm_digital_playback = {
5626 .substreams = 1,
5627 .channels_min = 2,
5628 .channels_max = 2,
5629 /* NID is set in via_build_pcms */
5630 .ops = {
5631 .open = via_dig_playback_pcm_open,
5632 .close = via_dig_playback_pcm_close,
5633 .prepare = via_dig_playback_pcm_prepare,
5634 .cleanup = via_dig_playback_pcm_cleanup
5635 },
5636};
5637
5638/* fill in the dac_nids table from the parsed pin configuration */
5639static int vt2002P_auto_fill_dac_nids(struct via_spec *spec,
5640 const struct auto_pin_cfg *cfg)
5641{
5642 spec->multiout.num_dacs = 1;
5643 spec->multiout.dac_nids = spec->private_dac_nids;
5644 if (cfg->line_out_pins[0])
5645 spec->multiout.dac_nids[0] = 0x8;
5646 return 0;
5647}
5648
5649/* add playback controls from the parsed DAC table */
5650static int vt2002P_auto_create_multi_out_ctls(struct via_spec *spec,
5651 const struct auto_pin_cfg *cfg)
5652{
5653 int err;
5654
5655 if (!cfg->line_out_pins[0])
5656 return -1;
5657
5658
5659 /* Line-Out: PortE */
5660 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
5661 "Master Front Playback Volume",
5662 HDA_COMPOSE_AMP_VAL(0x8, 3, 0, HDA_OUTPUT));
5663 if (err < 0)
5664 return err;
5665 err = via_add_control(spec, VIA_CTL_WIDGET_BIND_PIN_MUTE,
5666 "Master Front Playback Switch",
5667 HDA_COMPOSE_AMP_VAL(0x26, 3, 0, HDA_OUTPUT));
5668 if (err < 0)
5669 return err;
5670
5671 return 0;
5672}
5673
5674static int vt2002P_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
5675{
5676 int err;
5677
5678 if (!pin)
5679 return 0;
5680
5681 spec->multiout.hp_nid = 0x9;
5682 spec->hp_independent_mode_index = 1;
5683
5684 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
5685 "Headphone Playback Volume",
5686 HDA_COMPOSE_AMP_VAL(
5687 spec->multiout.hp_nid, 3, 0, HDA_OUTPUT));
5688 if (err < 0)
5689 return err;
5690
5691 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
5692 "Headphone Playback Switch",
5693 HDA_COMPOSE_AMP_VAL(0x25, 3, 0, HDA_OUTPUT));
5694 if (err < 0)
5695 return err;
5696
5697 create_hp_imux(spec);
5698 return 0;
5699}
5700
5701/* create playback/capture controls for input pins */
5702static int vt2002P_auto_create_analog_input_ctls(struct via_spec *spec,
5703 const struct auto_pin_cfg *cfg)
5704{
5705 static char *labels[] = {
5706 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
5707 };
5708 struct hda_input_mux *imux = &spec->private_imux[0];
5709 int i, err, idx = 0;
5710
5711 for (i = 0; i < AUTO_PIN_LAST; i++) {
5712 if (!cfg->input_pins[i])
5713 continue;
5714
5715 switch (cfg->input_pins[i]) {
5716 case 0x2b: /* Mic */
5717 idx = 0;
5718 break;
5719
5720 case 0x2a: /* Line In */
5721 idx = 1;
5722 break;
5723
5724 case 0x29: /* Front Mic */
5725 idx = 2;
5726 break;
5727 }
5728 err = via_new_analog_input(spec, labels[i], idx, 0x21);
5729 if (err < 0)
5730 return err;
5731 imux->items[imux->num_items].label = labels[i];
5732 imux->items[imux->num_items].index = idx;
5733 imux->num_items++;
5734 }
5735
5736 /* build volume/mute control of loopback */
5737 err = via_new_analog_input(spec, "Stereo Mixer", 3, 0x21);
5738 if (err < 0)
5739 return err;
5740
5741 /* for internal loopback recording select */
5742 imux->items[imux->num_items].label = "Stereo Mixer";
5743 imux->items[imux->num_items].index = 3;
5744 imux->num_items++;
5745
5746 /* for digital mic select */
5747 imux->items[imux->num_items].label = "Digital Mic";
5748 imux->items[imux->num_items].index = 4;
5749 imux->num_items++;
5750
5751 return 0;
5752}
5753
5754static int vt2002P_parse_auto_config(struct hda_codec *codec)
5755{
5756 struct via_spec *spec = codec->spec;
5757 int err;
5758
5759
5760 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
5761 if (err < 0)
5762 return err;
5763
5764 err = vt2002P_auto_fill_dac_nids(spec, &spec->autocfg);
5765 if (err < 0)
5766 return err;
5767
5768 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
5769 return 0; /* can't find valid BIOS pin config */
5770
5771 err = vt2002P_auto_create_multi_out_ctls(spec, &spec->autocfg);
5772 if (err < 0)
5773 return err;
5774 err = vt2002P_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
5775 if (err < 0)
5776 return err;
5777 err = vt2002P_auto_create_analog_input_ctls(spec, &spec->autocfg);
5778 if (err < 0)
5779 return err;
5780
5781 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5782
5783 fill_dig_outs(codec);
5784
5785 if (spec->kctls.list)
5786 spec->mixers[spec->num_mixers++] = spec->kctls.list;
5787
5788 spec->input_mux = &spec->private_imux[0];
5789
5790 if (spec->hp_mux)
5791 via_hp_build(codec);
5792
5793 return 1;
5794}
5795
5796#ifdef CONFIG_SND_HDA_POWER_SAVE
5797static struct hda_amp_list vt2002P_loopbacks[] = {
5798 { 0x21, HDA_INPUT, 0 },
5799 { 0x21, HDA_INPUT, 1 },
5800 { 0x21, HDA_INPUT, 2 },
5801 { } /* end */
5802};
5803#endif
5804
5805
5806/* patch for vt2002P */
5807static int patch_vt2002P(struct hda_codec *codec)
5808{
5809 struct via_spec *spec;
5810 int err;
5811
5812 /* create a codec specific record */
5813 spec = via_new_spec(codec);
5814 if (spec == NULL)
5815 return -ENOMEM;
5816
5817 /* automatic parse from the BIOS config */
5818 err = vt2002P_parse_auto_config(codec);
5819 if (err < 0) {
5820 via_free(codec);
5821 return err;
5822 } else if (!err) {
5823 printk(KERN_INFO "hda_codec: Cannot set up configuration "
5824 "from BIOS. Using genenic mode...\n");
5825 }
5826
5827 spec->init_verbs[spec->num_iverbs++] = vt2002P_volume_init_verbs;
5828 spec->init_verbs[spec->num_iverbs++] = vt2002P_uniwill_init_verbs;
5829
5830 spec->stream_name_analog = "VT2002P Analog";
5831 spec->stream_analog_playback = &vt2002P_pcm_analog_playback;
5832 spec->stream_analog_capture = &vt2002P_pcm_analog_capture;
5833
5834 spec->stream_name_digital = "VT2002P Digital";
5835 spec->stream_digital_playback = &vt2002P_pcm_digital_playback;
5836
5837 if (!spec->adc_nids && spec->input_mux) {
5838 spec->adc_nids = vt2002P_adc_nids;
5839 spec->num_adc_nids = ARRAY_SIZE(vt2002P_adc_nids);
5840 get_mux_nids(codec);
5841 override_mic_boost(codec, 0x2b, 0, 3, 40);
5842 override_mic_boost(codec, 0x29, 0, 3, 40);
5843 spec->mixers[spec->num_mixers] = vt2002P_capture_mixer;
5844 spec->num_mixers++;
5845 }
5846
5847 codec->patch_ops = via_patch_ops;
5848
5849 codec->patch_ops.init = via_auto_init;
5850 codec->patch_ops.unsol_event = via_unsol_event;
5851
5852#ifdef CONFIG_SND_HDA_POWER_SAVE
5853 spec->loopback.amplist = vt2002P_loopbacks;
5854#endif
5855
5856 return 0;
5857}
5858
5859/* for vt1812 */
5860
5861/* capture mixer elements */
5862static struct snd_kcontrol_new vt1812_capture_mixer[] = {
5863 HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT),
5864 HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT),
5865 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT),
5866 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x11, 0x0, HDA_INPUT),
5867 HDA_CODEC_MUTE("Mic Boost Capture Volume", 0x2b, 0x0, HDA_INPUT),
5868 HDA_CODEC_MUTE("Front Mic Boost Capture Volume", 0x29, 0x0,
5869 HDA_INPUT),
5870 {
5871 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5872 /* The multiple "Capture Source" controls confuse alsamixer
5873 * So call somewhat different..
5874 */
5875 .name = "Input Source",
5876 .count = 2,
5877 .info = via_mux_enum_info,
5878 .get = via_mux_enum_get,
5879 .put = via_mux_enum_put,
5880 },
5881 { } /* end */
5882};
5883
5884static struct hda_verb vt1812_volume_init_verbs[] = {
5885 /*
5886 * Unmute ADC0-1 and set the default input to mic-in
5887 */
5888 {0x8, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5889 {0x9, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5890
5891
5892 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5893 * mixer widget
5894 */
5895 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
5896 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5897 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5898 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5899 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5900 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5901
5902 /* MUX Indices: Mic = 0 */
5903 {0x1e, AC_VERB_SET_CONNECT_SEL, 0},
5904 {0x1f, AC_VERB_SET_CONNECT_SEL, 0},
5905
5906 /* PW9 Output enable */
5907 {0x2d, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_OUT_EN},
5908
5909 /* Enable Boost Volume backdoor */
5910 {0x1, 0xfb9, 0x24},
5911
5912 /* MW0/1/4/13/15: un-mute index 0 (MUXx), un-mute index 1 (MW9) */
5913 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5914 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5915 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5916 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5917 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5918 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5919 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5920 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5921 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5922 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5923
5924 /* set MUX0/1/4/13/15 = 0 (AOW0) */
5925 {0x34, AC_VERB_SET_CONNECT_SEL, 0},
5926 {0x35, AC_VERB_SET_CONNECT_SEL, 0},
5927 {0x38, AC_VERB_SET_CONNECT_SEL, 0},
5928 {0x3c, AC_VERB_SET_CONNECT_SEL, 0},
5929 {0x3d, AC_VERB_SET_CONNECT_SEL, 0},
5930
5931 /* Enable AOW0 to MW9 */
5932 {0x1, 0xfb8, 0xa8},
5933 { }
5934};
5935
5936
5937static struct hda_verb vt1812_uniwill_init_verbs[] = {
5938 {0x33, AC_VERB_SET_UNSOLICITED_ENABLE,
5939 AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT},
5940 {0x25, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT },
5941 {0x28, AC_VERB_SET_UNSOLICITED_ENABLE,
5942 AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT},
5943 {0x29, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5944 {0x2a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5945 {0x2b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5946 { }
5947};
5948
5949static struct hda_pcm_stream vt1812_pcm_analog_playback = {
5950 .substreams = 2,
5951 .channels_min = 2,
5952 .channels_max = 2,
5953 .nid = 0x8, /* NID to query formats and rates */
5954 .ops = {
5955 .open = via_playback_pcm_open,
5956 .prepare = via_playback_multi_pcm_prepare,
5957 .cleanup = via_playback_multi_pcm_cleanup,
5958 .close = via_pcm_open_close,
5959 },
5960};
5961
5962static struct hda_pcm_stream vt1812_pcm_analog_capture = {
5963 .substreams = 2,
5964 .channels_min = 2,
5965 .channels_max = 2,
5966 .nid = 0x10, /* NID to query formats and rates */
5967 .ops = {
5968 .open = via_pcm_open_close,
5969 .prepare = via_capture_pcm_prepare,
5970 .cleanup = via_capture_pcm_cleanup,
5971 .close = via_pcm_open_close,
5972 },
5973};
5974
5975static struct hda_pcm_stream vt1812_pcm_digital_playback = {
5976 .substreams = 1,
5977 .channels_min = 2,
5978 .channels_max = 2,
5979 /* NID is set in via_build_pcms */
5980 .ops = {
5981 .open = via_dig_playback_pcm_open,
5982 .close = via_dig_playback_pcm_close,
5983 .prepare = via_dig_playback_pcm_prepare,
5984 .cleanup = via_dig_playback_pcm_cleanup
5985 },
5986};
5987/* fill in the dac_nids table from the parsed pin configuration */
5988static int vt1812_auto_fill_dac_nids(struct via_spec *spec,
5989 const struct auto_pin_cfg *cfg)
5990{
5991 spec->multiout.num_dacs = 1;
5992 spec->multiout.dac_nids = spec->private_dac_nids;
5993 if (cfg->line_out_pins[0])
5994 spec->multiout.dac_nids[0] = 0x8;
5995 return 0;
5996}
5997
5998
5999/* add playback controls from the parsed DAC table */
6000static int vt1812_auto_create_multi_out_ctls(struct via_spec *spec,
6001 const struct auto_pin_cfg *cfg)
6002{
6003 int err;
6004
6005 if (!cfg->line_out_pins[0])
6006 return -1;
6007
6008 /* Line-Out: PortE */
6009 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
6010 "Front Playback Volume",
6011 HDA_COMPOSE_AMP_VAL(0x8, 3, 0, HDA_OUTPUT));
6012 if (err < 0)
6013 return err;
6014 err = via_add_control(spec, VIA_CTL_WIDGET_BIND_PIN_MUTE,
6015 "Front Playback Switch",
6016 HDA_COMPOSE_AMP_VAL(0x28, 3, 0, HDA_OUTPUT));
6017 if (err < 0)
6018 return err;
6019
6020 return 0;
6021}
6022
6023static int vt1812_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
6024{
6025 int err;
6026
6027 if (!pin)
6028 return 0;
6029
6030 spec->multiout.hp_nid = 0x9;
6031 spec->hp_independent_mode_index = 1;
6032
6033
6034 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
6035 "Headphone Playback Volume",
6036 HDA_COMPOSE_AMP_VAL(
6037 spec->multiout.hp_nid, 3, 0, HDA_OUTPUT));
6038 if (err < 0)
6039 return err;
6040
6041 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
6042 "Headphone Playback Switch",
6043 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
6044 if (err < 0)
6045 return err;
6046
6047 create_hp_imux(spec);
6048 return 0;
6049}
6050
6051/* create playback/capture controls for input pins */
6052static int vt1812_auto_create_analog_input_ctls(struct via_spec *spec,
6053 const struct auto_pin_cfg *cfg)
6054{
6055 static char *labels[] = {
6056 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
6057 };
6058 struct hda_input_mux *imux = &spec->private_imux[0];
6059 int i, err, idx = 0;
6060
6061 for (i = 0; i < AUTO_PIN_LAST; i++) {
6062 if (!cfg->input_pins[i])
6063 continue;
6064
6065 switch (cfg->input_pins[i]) {
6066 case 0x2b: /* Mic */
6067 idx = 0;
6068 break;
6069
6070 case 0x2a: /* Line In */
6071 idx = 1;
6072 break;
6073
6074 case 0x29: /* Front Mic */
6075 idx = 2;
6076 break;
6077 }
6078 err = via_new_analog_input(spec, labels[i], idx, 0x21);
6079 if (err < 0)
6080 return err;
6081 imux->items[imux->num_items].label = labels[i];
6082 imux->items[imux->num_items].index = idx;
6083 imux->num_items++;
6084 }
6085 /* build volume/mute control of loopback */
6086 err = via_new_analog_input(spec, "Stereo Mixer", 5, 0x21);
6087 if (err < 0)
6088 return err;
6089
6090 /* for internal loopback recording select */
6091 imux->items[imux->num_items].label = "Stereo Mixer";
6092 imux->items[imux->num_items].index = 5;
6093 imux->num_items++;
6094
6095 /* for digital mic select */
6096 imux->items[imux->num_items].label = "Digital Mic";
6097 imux->items[imux->num_items].index = 6;
6098 imux->num_items++;
6099
6100 return 0;
6101}
6102
6103static int vt1812_parse_auto_config(struct hda_codec *codec)
6104{
6105 struct via_spec *spec = codec->spec;
6106 int err;
6107
6108
6109 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
6110 if (err < 0)
6111 return err;
6112 fill_dig_outs(codec);
6113 err = vt1812_auto_fill_dac_nids(spec, &spec->autocfg);
6114 if (err < 0)
6115 return err;
6116
6117 if (!spec->autocfg.line_outs && !spec->autocfg.hp_outs)
6118 return 0; /* can't find valid BIOS pin config */
6119
6120 err = vt1812_auto_create_multi_out_ctls(spec, &spec->autocfg);
6121 if (err < 0)
6122 return err;
6123 err = vt1812_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
6124 if (err < 0)
6125 return err;
6126 err = vt1812_auto_create_analog_input_ctls(spec, &spec->autocfg);
6127 if (err < 0)
6128 return err;
6129
6130 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
6131
6132 fill_dig_outs(codec);
6133
6134 if (spec->kctls.list)
6135 spec->mixers[spec->num_mixers++] = spec->kctls.list;
6136
6137 spec->input_mux = &spec->private_imux[0];
6138
6139 if (spec->hp_mux)
6140 via_hp_build(codec);
6141
6142 return 1;
6143}
6144
6145#ifdef CONFIG_SND_HDA_POWER_SAVE
6146static struct hda_amp_list vt1812_loopbacks[] = {
6147 { 0x21, HDA_INPUT, 0 },
6148 { 0x21, HDA_INPUT, 1 },
6149 { 0x21, HDA_INPUT, 2 },
6150 { } /* end */
6151};
6152#endif
6153
6154
6155/* patch for vt1812 */
6156static int patch_vt1812(struct hda_codec *codec)
6157{
6158 struct via_spec *spec;
6159 int err;
6160
6161 /* create a codec specific record */
6162 spec = via_new_spec(codec);
6163 if (spec == NULL)
6164 return -ENOMEM;
6165
6166 /* automatic parse from the BIOS config */
6167 err = vt1812_parse_auto_config(codec);
6168 if (err < 0) {
6169 via_free(codec);
6170 return err;
6171 } else if (!err) {
6172 printk(KERN_INFO "hda_codec: Cannot set up configuration "
6173 "from BIOS. Using genenic mode...\n");
6174 }
6175
6176
6177 spec->init_verbs[spec->num_iverbs++] = vt1812_volume_init_verbs;
6178 spec->init_verbs[spec->num_iverbs++] = vt1812_uniwill_init_verbs;
6179
6180 spec->stream_name_analog = "VT1812 Analog";
6181 spec->stream_analog_playback = &vt1812_pcm_analog_playback;
6182 spec->stream_analog_capture = &vt1812_pcm_analog_capture;
3239 6183
3240 /* Enable GPIO 0&1 for volume&mute control */ 6184 spec->stream_name_digital = "VT1812 Digital";
3241 /* Enable GPIO 2 for DMIC-DATA */ 6185 spec->stream_digital_playback = &vt1812_pcm_digital_playback;
3242 response = snd_hda_codec_read(codec, codec->afg, 0, 0xF84, 0); 6186
3243 control = (unsigned char)((response >> 16) & 0x3f); 6187
3244 snd_hda_codec_write(codec, codec->afg, 0, 0xF82, control); 6188 if (!spec->adc_nids && spec->input_mux) {
6189 spec->adc_nids = vt1812_adc_nids;
6190 spec->num_adc_nids = ARRAY_SIZE(vt1812_adc_nids);
6191 get_mux_nids(codec);
6192 override_mic_boost(codec, 0x2b, 0, 3, 40);
6193 override_mic_boost(codec, 0x29, 0, 3, 40);
6194 spec->mixers[spec->num_mixers] = vt1812_capture_mixer;
6195 spec->num_mixers++;
6196 }
6197
6198 codec->patch_ops = via_patch_ops;
6199
6200 codec->patch_ops.init = via_auto_init;
6201 codec->patch_ops.unsol_event = via_unsol_event;
6202
6203#ifdef CONFIG_SND_HDA_POWER_SAVE
6204 spec->loopback.amplist = vt1812_loopbacks;
6205#endif
3245 6206
3246 return 0; 6207 return 0;
3247} 6208}
@@ -3318,6 +6279,23 @@ static struct hda_codec_preset snd_hda_preset_via[] = {
3318 .patch = patch_vt1702}, 6279 .patch = patch_vt1702},
3319 { .id = 0x11067398, .name = "VT1702", 6280 { .id = 0x11067398, .name = "VT1702",
3320 .patch = patch_vt1702}, 6281 .patch = patch_vt1702},
6282 { .id = 0x11060428, .name = "VT1718S",
6283 .patch = patch_vt1718S},
6284 { .id = 0x11064428, .name = "VT1718S",
6285 .patch = patch_vt1718S},
6286 { .id = 0x11060441, .name = "VT2020",
6287 .patch = patch_vt1718S},
6288 { .id = 0x11064441, .name = "VT1828S",
6289 .patch = patch_vt1718S},
6290 { .id = 0x11060433, .name = "VT1716S",
6291 .patch = patch_vt1716S},
6292 { .id = 0x1106a721, .name = "VT1716S",
6293 .patch = patch_vt1716S},
6294 { .id = 0x11060438, .name = "VT2002P", .patch = patch_vt2002P},
6295 { .id = 0x11064438, .name = "VT2002P", .patch = patch_vt2002P},
6296 { .id = 0x11060448, .name = "VT1812", .patch = patch_vt1812},
6297 { .id = 0x11060440, .name = "VT1818S",
6298 .patch = patch_vt1708S},
3321 {} /* terminator */ 6299 {} /* terminator */
3322}; 6300};
3323 6301
diff --git a/sound/pci/ice1712/Makefile b/sound/pci/ice1712/Makefile
index 536eae2ccf94..f7ce33f00ea5 100644
--- a/sound/pci/ice1712/Makefile
+++ b/sound/pci/ice1712/Makefile
@@ -5,7 +5,7 @@
5 5
6snd-ice17xx-ak4xxx-objs := ak4xxx.o 6snd-ice17xx-ak4xxx-objs := ak4xxx.o
7snd-ice1712-objs := ice1712.o delta.o hoontech.o ews.o 7snd-ice1712-objs := ice1712.o delta.o hoontech.o ews.o
8snd-ice1724-objs := ice1724.o amp.o revo.o aureon.o vt1720_mobo.o pontis.o prodigy192.o prodigy_hifi.o juli.o phase.o wtm.o se.o maya44.o 8snd-ice1724-objs := ice1724.o amp.o revo.o aureon.o vt1720_mobo.o pontis.o prodigy192.o prodigy_hifi.o juli.o phase.o wtm.o se.o maya44.o quartet.o
9 9
10# Toplevel Module Dependency 10# Toplevel Module Dependency
11obj-$(CONFIG_SND_ICE1712) += snd-ice1712.o snd-ice17xx-ak4xxx.o 11obj-$(CONFIG_SND_ICE1712) += snd-ice1712.o snd-ice17xx-ak4xxx.o
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 110d16e52733..9e66f6d306f8 100644
--- a/sound/pci/ice1712/aureon.c
+++ b/sound/pci/ice1712/aureon.c
@@ -689,42 +689,27 @@ static int aureon_ac97_mmute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
689 return change; 689 return change;
690} 690}
691 691
692static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -12700, 100, 1); 692static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -10000, 100, 1);
693static const DECLARE_TLV_DB_SCALE(db_scale_wm_pcm, -6400, 50, 1); 693static const DECLARE_TLV_DB_SCALE(db_scale_wm_pcm, -6400, 50, 1);
694static const DECLARE_TLV_DB_SCALE(db_scale_wm_adc, -1200, 100, 0); 694static const DECLARE_TLV_DB_SCALE(db_scale_wm_adc, -1200, 100, 0);
695static const DECLARE_TLV_DB_SCALE(db_scale_ac97_master, -4650, 150, 0); 695static const DECLARE_TLV_DB_SCALE(db_scale_ac97_master, -4650, 150, 0);
696static const DECLARE_TLV_DB_SCALE(db_scale_ac97_gain, -3450, 150, 0); 696static const DECLARE_TLV_DB_SCALE(db_scale_ac97_gain, -3450, 150, 0);
697 697
698/* 698#define WM_VOL_MAX 100
699 * Logarithmic volume values for WM8770 699#define WM_VOL_CNT 101 /* 0dB .. -100dB */
700 * Computed as 20 * Log10(255 / x)
701 */
702static const unsigned char wm_vol[256] = {
703 127, 48, 42, 39, 36, 34, 33, 31, 30, 29, 28, 27, 27, 26, 25, 25, 24, 24, 23,
704 23, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 18, 17, 17, 17,
705 17, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 13, 13, 13,
706 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11,
707 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8,
708 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6,
709 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
710 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3,
711 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
712 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
713 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
714 0, 0
715};
716
717#define WM_VOL_MAX (sizeof(wm_vol) - 1)
718#define WM_VOL_MUTE 0x8000 700#define WM_VOL_MUTE 0x8000
719 701
720static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned short vol, unsigned short master) 702static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned short vol, unsigned short master)
721{ 703{
722 unsigned char nvol; 704 unsigned char nvol;
723 705
724 if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE)) 706 if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE)) {
725 nvol = 0; 707 nvol = 0;
726 else 708 } else {
727 nvol = 127 - wm_vol[(((vol & ~WM_VOL_MUTE) * (master & ~WM_VOL_MUTE)) / 127) & WM_VOL_MAX]; 709 nvol = ((vol % WM_VOL_CNT) * (master % WM_VOL_CNT)) /
710 WM_VOL_MAX;
711 nvol += 0x1b;
712 }
728 713
729 wm_put(ice, index, nvol); 714 wm_put(ice, index, nvol);
730 wm_put_nocache(ice, index, 0x180 | nvol); 715 wm_put_nocache(ice, index, 0x180 | nvol);
@@ -795,7 +780,7 @@ static int wm_master_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_
795 for (ch = 0; ch < 2; ch++) { 780 for (ch = 0; ch < 2; ch++) {
796 unsigned int vol = ucontrol->value.integer.value[ch]; 781 unsigned int vol = ucontrol->value.integer.value[ch];
797 if (vol > WM_VOL_MAX) 782 if (vol > WM_VOL_MAX)
798 continue; 783 vol = WM_VOL_MAX;
799 vol |= spec->master[ch] & WM_VOL_MUTE; 784 vol |= spec->master[ch] & WM_VOL_MUTE;
800 if (vol != spec->master[ch]) { 785 if (vol != spec->master[ch]) {
801 int dac; 786 int dac;
@@ -820,7 +805,7 @@ static int wm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *
820 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 805 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
821 uinfo->count = voices; 806 uinfo->count = voices;
822 uinfo->value.integer.min = 0; /* mute (-101dB) */ 807 uinfo->value.integer.min = 0; /* mute (-101dB) */
823 uinfo->value.integer.max = 0x7F; /* 0dB */ 808 uinfo->value.integer.max = WM_VOL_MAX; /* 0dB */
824 return 0; 809 return 0;
825} 810}
826 811
@@ -850,9 +835,9 @@ static int wm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *
850 snd_ice1712_save_gpio_status(ice); 835 snd_ice1712_save_gpio_status(ice);
851 for (i = 0; i < voices; i++) { 836 for (i = 0; i < voices; i++) {
852 unsigned int vol = ucontrol->value.integer.value[i]; 837 unsigned int vol = ucontrol->value.integer.value[i];
853 if (vol > 0x7f) 838 if (vol > WM_VOL_MAX)
854 continue; 839 vol = WM_VOL_MAX;
855 vol |= spec->vol[ofs+i]; 840 vol |= spec->vol[ofs+i] & WM_VOL_MUTE;
856 if (vol != spec->vol[ofs+i]) { 841 if (vol != spec->vol[ofs+i]) {
857 spec->vol[ofs+i] = vol; 842 spec->vol[ofs+i] = vol;
858 idx = WM_DAC_ATTEN + ofs + i; 843 idx = WM_DAC_ATTEN + ofs + i;
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
index d74033a2cfbe..4fc6d8bc637e 100644
--- a/sound/pci/ice1712/ice1712.c
+++ b/sound/pci/ice1712/ice1712.c
@@ -106,7 +106,7 @@ module_param_array(dxr_enable, int, NULL, 0444);
106MODULE_PARM_DESC(dxr_enable, "Enable DXR support for Terratec DMX6FIRE."); 106MODULE_PARM_DESC(dxr_enable, "Enable DXR support for Terratec DMX6FIRE.");
107 107
108 108
109static const struct pci_device_id snd_ice1712_ids[] = { 109static DEFINE_PCI_DEVICE_TABLE(snd_ice1712_ids) = {
110 { PCI_VDEVICE(ICE, PCI_DEVICE_ID_ICE_1712), 0 }, /* ICE1712 */ 110 { PCI_VDEVICE(ICE, PCI_DEVICE_ID_ICE_1712), 0 }, /* ICE1712 */
111 { 0, } 111 { 0, }
112}; 112};
@@ -298,6 +298,16 @@ static void snd_ice1712_set_gpio_dir(struct snd_ice1712 *ice, unsigned int data)
298 inb(ICEREG(ice, DATA)); /* dummy read for pci-posting */ 298 inb(ICEREG(ice, DATA)); /* dummy read for pci-posting */
299} 299}
300 300
301static unsigned int snd_ice1712_get_gpio_dir(struct snd_ice1712 *ice)
302{
303 return snd_ice1712_read(ice, ICE1712_IREG_GPIO_DIRECTION);
304}
305
306static unsigned int snd_ice1712_get_gpio_mask(struct snd_ice1712 *ice)
307{
308 return snd_ice1712_read(ice, ICE1712_IREG_GPIO_WRITE_MASK);
309}
310
301static void snd_ice1712_set_gpio_mask(struct snd_ice1712 *ice, unsigned int data) 311static void snd_ice1712_set_gpio_mask(struct snd_ice1712 *ice, unsigned int data)
302{ 312{
303 snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, data); 313 snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, data);
@@ -1170,6 +1180,10 @@ static int snd_ice1712_playback_pro_open(struct snd_pcm_substream *substream)
1170 snd_pcm_set_sync(substream); 1180 snd_pcm_set_sync(substream);
1171 snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); 1181 snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
1172 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates); 1182 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);
1183 if (is_pro_rate_locked(ice)) {
1184 runtime->hw.rate_min = PRO_RATE_DEFAULT;
1185 runtime->hw.rate_max = PRO_RATE_DEFAULT;
1186 }
1173 1187
1174 if (ice->spdif.ops.open) 1188 if (ice->spdif.ops.open)
1175 ice->spdif.ops.open(ice, substream); 1189 ice->spdif.ops.open(ice, substream);
@@ -1187,6 +1201,11 @@ static int snd_ice1712_capture_pro_open(struct snd_pcm_substream *substream)
1187 snd_pcm_set_sync(substream); 1201 snd_pcm_set_sync(substream);
1188 snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); 1202 snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
1189 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates); 1203 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);
1204 if (is_pro_rate_locked(ice)) {
1205 runtime->hw.rate_min = PRO_RATE_DEFAULT;
1206 runtime->hw.rate_max = PRO_RATE_DEFAULT;
1207 }
1208
1190 return 0; 1209 return 0;
1191} 1210}
1192 1211
@@ -2557,7 +2576,9 @@ static int __devinit snd_ice1712_create(struct snd_card *card,
2557 mutex_init(&ice->i2c_mutex); 2576 mutex_init(&ice->i2c_mutex);
2558 mutex_init(&ice->open_mutex); 2577 mutex_init(&ice->open_mutex);
2559 ice->gpio.set_mask = snd_ice1712_set_gpio_mask; 2578 ice->gpio.set_mask = snd_ice1712_set_gpio_mask;
2579 ice->gpio.get_mask = snd_ice1712_get_gpio_mask;
2560 ice->gpio.set_dir = snd_ice1712_set_gpio_dir; 2580 ice->gpio.set_dir = snd_ice1712_set_gpio_dir;
2581 ice->gpio.get_dir = snd_ice1712_get_gpio_dir;
2561 ice->gpio.set_data = snd_ice1712_set_gpio_data; 2582 ice->gpio.set_data = snd_ice1712_set_gpio_data;
2562 ice->gpio.get_data = snd_ice1712_get_gpio_data; 2583 ice->gpio.get_data = snd_ice1712_get_gpio_data;
2563 2584
diff --git a/sound/pci/ice1712/ice1712.h b/sound/pci/ice1712/ice1712.h
index d063149e7047..0da778a69ef8 100644
--- a/sound/pci/ice1712/ice1712.h
+++ b/sound/pci/ice1712/ice1712.h
@@ -359,7 +359,9 @@ struct snd_ice1712 {
359 unsigned int saved[2]; /* for ewx_i2c */ 359 unsigned int saved[2]; /* for ewx_i2c */
360 /* operators */ 360 /* operators */
361 void (*set_mask)(struct snd_ice1712 *ice, unsigned int data); 361 void (*set_mask)(struct snd_ice1712 *ice, unsigned int data);
362 unsigned int (*get_mask)(struct snd_ice1712 *ice);
362 void (*set_dir)(struct snd_ice1712 *ice, unsigned int data); 363 void (*set_dir)(struct snd_ice1712 *ice, unsigned int data);
364 unsigned int (*get_dir)(struct snd_ice1712 *ice);
363 void (*set_data)(struct snd_ice1712 *ice, unsigned int data); 365 void (*set_data)(struct snd_ice1712 *ice, unsigned int data);
364 unsigned int (*get_data)(struct snd_ice1712 *ice); 366 unsigned int (*get_data)(struct snd_ice1712 *ice);
365 /* misc operators - move to another place? */ 367 /* misc operators - move to another place? */
@@ -377,8 +379,11 @@ struct snd_ice1712 {
377 unsigned int (*get_rate)(struct snd_ice1712 *ice); 379 unsigned int (*get_rate)(struct snd_ice1712 *ice);
378 void (*set_rate)(struct snd_ice1712 *ice, unsigned int rate); 380 void (*set_rate)(struct snd_ice1712 *ice, unsigned int rate);
379 unsigned char (*set_mclk)(struct snd_ice1712 *ice, unsigned int rate); 381 unsigned char (*set_mclk)(struct snd_ice1712 *ice, unsigned int rate);
380 void (*set_spdif_clock)(struct snd_ice1712 *ice); 382 int (*set_spdif_clock)(struct snd_ice1712 *ice, int type);
381 383 int (*get_spdif_master_type)(struct snd_ice1712 *ice);
384 char **ext_clock_names;
385 int ext_clock_count;
386 void (*pro_open)(struct snd_ice1712 *, struct snd_pcm_substream *);
382#ifdef CONFIG_PM 387#ifdef CONFIG_PM
383 int (*pm_suspend)(struct snd_ice1712 *); 388 int (*pm_suspend)(struct snd_ice1712 *);
384 int (*pm_resume)(struct snd_ice1712 *); 389 int (*pm_resume)(struct snd_ice1712 *);
@@ -399,6 +404,11 @@ static inline void snd_ice1712_gpio_set_dir(struct snd_ice1712 *ice, unsigned in
399 ice->gpio.set_dir(ice, bits); 404 ice->gpio.set_dir(ice, bits);
400} 405}
401 406
407static inline unsigned int snd_ice1712_gpio_get_dir(struct snd_ice1712 *ice)
408{
409 return ice->gpio.get_dir(ice);
410}
411
402static inline void snd_ice1712_gpio_set_mask(struct snd_ice1712 *ice, unsigned int bits) 412static inline void snd_ice1712_gpio_set_mask(struct snd_ice1712 *ice, unsigned int bits)
403{ 413{
404 ice->gpio.set_mask(ice, bits); 414 ice->gpio.set_mask(ice, bits);
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index 10fc92c05574..c1498fa5545f 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -53,6 +53,7 @@
53#include "phase.h" 53#include "phase.h"
54#include "wtm.h" 54#include "wtm.h"
55#include "se.h" 55#include "se.h"
56#include "quartet.h"
56 57
57MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); 58MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
58MODULE_DESCRIPTION("VIA ICEnsemble ICE1724/1720 (Envy24HT/PT)"); 59MODULE_DESCRIPTION("VIA ICEnsemble ICE1724/1720 (Envy24HT/PT)");
@@ -70,6 +71,7 @@ MODULE_SUPPORTED_DEVICE("{"
70 PHASE_DEVICE_DESC 71 PHASE_DEVICE_DESC
71 WTM_DEVICE_DESC 72 WTM_DEVICE_DESC
72 SE_DEVICE_DESC 73 SE_DEVICE_DESC
74 QTET_DEVICE_DESC
73 "{VIA,VT1720}," 75 "{VIA,VT1720},"
74 "{VIA,VT1724}," 76 "{VIA,VT1724},"
75 "{ICEnsemble,Generic ICE1724}," 77 "{ICEnsemble,Generic ICE1724},"
@@ -92,7 +94,7 @@ MODULE_PARM_DESC(model, "Use the given board model.");
92 94
93 95
94/* Both VT1720 and VT1724 have the same PCI IDs */ 96/* Both VT1720 and VT1724 have the same PCI IDs */
95static const struct pci_device_id snd_vt1724_ids[] = { 97static DEFINE_PCI_DEVICE_TABLE(snd_vt1724_ids) = {
96 { PCI_VDEVICE(ICE, PCI_DEVICE_ID_VT1724), 0 }, 98 { PCI_VDEVICE(ICE, PCI_DEVICE_ID_VT1724), 0 },
97 { 0, } 99 { 0, }
98}; 100};
@@ -104,6 +106,8 @@ static int PRO_RATE_LOCKED;
104static int PRO_RATE_RESET = 1; 106static int PRO_RATE_RESET = 1;
105static unsigned int PRO_RATE_DEFAULT = 44100; 107static unsigned int PRO_RATE_DEFAULT = 44100;
106 108
109static char *ext_clock_names[1] = { "IEC958 In" };
110
107/* 111/*
108 * Basic I/O 112 * Basic I/O
109 */ 113 */
@@ -118,9 +122,12 @@ static inline int stdclock_is_spdif_master(struct snd_ice1712 *ice)
118 return (inb(ICEMT1724(ice, RATE)) & VT1724_SPDIF_MASTER) ? 1 : 0; 122 return (inb(ICEMT1724(ice, RATE)) & VT1724_SPDIF_MASTER) ? 1 : 0;
119} 123}
120 124
125/*
126 * locking rate makes sense only for internal clock mode
127 */
121static inline int is_pro_rate_locked(struct snd_ice1712 *ice) 128static inline int is_pro_rate_locked(struct snd_ice1712 *ice)
122{ 129{
123 return ice->is_spdif_master(ice) || PRO_RATE_LOCKED; 130 return (!ice->is_spdif_master(ice)) && PRO_RATE_LOCKED;
124} 131}
125 132
126/* 133/*
@@ -196,6 +203,12 @@ static void snd_vt1724_set_gpio_dir(struct snd_ice1712 *ice, unsigned int data)
196 inw(ICEREG1724(ice, GPIO_DIRECTION)); /* dummy read for pci-posting */ 203 inw(ICEREG1724(ice, GPIO_DIRECTION)); /* dummy read for pci-posting */
197} 204}
198 205
206/* get gpio direction 0 = read, 1 = write */
207static unsigned int snd_vt1724_get_gpio_dir(struct snd_ice1712 *ice)
208{
209 return inl(ICEREG1724(ice, GPIO_DIRECTION));
210}
211
199/* set the gpio mask (0 = writable) */ 212/* set the gpio mask (0 = writable) */
200static void snd_vt1724_set_gpio_mask(struct snd_ice1712 *ice, unsigned int data) 213static void snd_vt1724_set_gpio_mask(struct snd_ice1712 *ice, unsigned int data)
201{ 214{
@@ -205,6 +218,17 @@ static void snd_vt1724_set_gpio_mask(struct snd_ice1712 *ice, unsigned int data)
205 inw(ICEREG1724(ice, GPIO_WRITE_MASK)); /* dummy read for pci-posting */ 218 inw(ICEREG1724(ice, GPIO_WRITE_MASK)); /* dummy read for pci-posting */
206} 219}
207 220
221static unsigned int snd_vt1724_get_gpio_mask(struct snd_ice1712 *ice)
222{
223 unsigned int mask;
224 if (!ice->vt1720)
225 mask = (unsigned int)inb(ICEREG1724(ice, GPIO_WRITE_MASK_22));
226 else
227 mask = 0;
228 mask = (mask << 16) | inw(ICEREG1724(ice, GPIO_WRITE_MASK));
229 return mask;
230}
231
208static void snd_vt1724_set_gpio_data(struct snd_ice1712 *ice, unsigned int data) 232static void snd_vt1724_set_gpio_data(struct snd_ice1712 *ice, unsigned int data)
209{ 233{
210 outw(data, ICEREG1724(ice, GPIO_DATA)); 234 outw(data, ICEREG1724(ice, GPIO_DATA));
@@ -651,16 +675,22 @@ static int snd_vt1724_set_pro_rate(struct snd_ice1712 *ice, unsigned int rate,
651 return ((rate == ice->cur_rate) && !force) ? 0 : -EBUSY; 675 return ((rate == ice->cur_rate) && !force) ? 0 : -EBUSY;
652 } 676 }
653 if (!force && is_pro_rate_locked(ice)) { 677 if (!force && is_pro_rate_locked(ice)) {
678 /* comparing required and current rate - makes sense for
679 * internal clock only */
654 spin_unlock_irqrestore(&ice->reg_lock, flags); 680 spin_unlock_irqrestore(&ice->reg_lock, flags);
655 return (rate == ice->cur_rate) ? 0 : -EBUSY; 681 return (rate == ice->cur_rate) ? 0 : -EBUSY;
656 } 682 }
657 683
658 old_rate = ice->get_rate(ice); 684 if (force || !ice->is_spdif_master(ice)) {
659 if (force || (old_rate != rate)) 685 /* force means the rate was switched by ucontrol, otherwise
660 ice->set_rate(ice, rate); 686 * setting clock rate for internal clock mode */
661 else if (rate == ice->cur_rate) { 687 old_rate = ice->get_rate(ice);
662 spin_unlock_irqrestore(&ice->reg_lock, flags); 688 if (force || (old_rate != rate))
663 return 0; 689 ice->set_rate(ice, rate);
690 else if (rate == ice->cur_rate) {
691 spin_unlock_irqrestore(&ice->reg_lock, flags);
692 return 0;
693 }
664 } 694 }
665 695
666 ice->cur_rate = rate; 696 ice->cur_rate = rate;
@@ -1016,6 +1046,8 @@ static int snd_vt1724_playback_pro_open(struct snd_pcm_substream *substream)
1016 VT1724_BUFFER_ALIGN); 1046 VT1724_BUFFER_ALIGN);
1017 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 1047 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
1018 VT1724_BUFFER_ALIGN); 1048 VT1724_BUFFER_ALIGN);
1049 if (ice->pro_open)
1050 ice->pro_open(ice, substream);
1019 return 0; 1051 return 0;
1020} 1052}
1021 1053
@@ -1034,6 +1066,8 @@ static int snd_vt1724_capture_pro_open(struct snd_pcm_substream *substream)
1034 VT1724_BUFFER_ALIGN); 1066 VT1724_BUFFER_ALIGN);
1035 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 1067 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
1036 VT1724_BUFFER_ALIGN); 1068 VT1724_BUFFER_ALIGN);
1069 if (ice->pro_open)
1070 ice->pro_open(ice, substream);
1037 return 0; 1071 return 0;
1038} 1072}
1039 1073
@@ -1787,15 +1821,21 @@ static int snd_vt1724_pro_internal_clock_info(struct snd_kcontrol *kcontrol,
1787 struct snd_ctl_elem_info *uinfo) 1821 struct snd_ctl_elem_info *uinfo)
1788{ 1822{
1789 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 1823 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1790 1824 int hw_rates_count = ice->hw_rates->count;
1791 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 1825 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1792 uinfo->count = 1; 1826 uinfo->count = 1;
1793 uinfo->value.enumerated.items = ice->hw_rates->count + 1; 1827
1828 uinfo->value.enumerated.items = hw_rates_count + ice->ext_clock_count;
1829 /* upper limit - keep at top */
1794 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) 1830 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1795 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; 1831 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1796 if (uinfo->value.enumerated.item == uinfo->value.enumerated.items - 1) 1832 if (uinfo->value.enumerated.item >= hw_rates_count)
1797 strcpy(uinfo->value.enumerated.name, "IEC958 Input"); 1833 /* ext_clock items */
1834 strcpy(uinfo->value.enumerated.name,
1835 ice->ext_clock_names[
1836 uinfo->value.enumerated.item - hw_rates_count]);
1798 else 1837 else
1838 /* int clock items */
1799 sprintf(uinfo->value.enumerated.name, "%d", 1839 sprintf(uinfo->value.enumerated.name, "%d",
1800 ice->hw_rates->list[uinfo->value.enumerated.item]); 1840 ice->hw_rates->list[uinfo->value.enumerated.item]);
1801 return 0; 1841 return 0;
@@ -1809,7 +1849,8 @@ static int snd_vt1724_pro_internal_clock_get(struct snd_kcontrol *kcontrol,
1809 1849
1810 spin_lock_irq(&ice->reg_lock); 1850 spin_lock_irq(&ice->reg_lock);
1811 if (ice->is_spdif_master(ice)) { 1851 if (ice->is_spdif_master(ice)) {
1812 ucontrol->value.enumerated.item[0] = ice->hw_rates->count; 1852 ucontrol->value.enumerated.item[0] = ice->hw_rates->count +
1853 ice->get_spdif_master_type(ice);
1813 } else { 1854 } else {
1814 rate = ice->get_rate(ice); 1855 rate = ice->get_rate(ice);
1815 ucontrol->value.enumerated.item[0] = 0; 1856 ucontrol->value.enumerated.item[0] = 0;
@@ -1824,8 +1865,14 @@ static int snd_vt1724_pro_internal_clock_get(struct snd_kcontrol *kcontrol,
1824 return 0; 1865 return 0;
1825} 1866}
1826 1867
1868static int stdclock_get_spdif_master_type(struct snd_ice1712 *ice)
1869{
1870 /* standard external clock - only single type - SPDIF IN */
1871 return 0;
1872}
1873
1827/* setting clock to external - SPDIF */ 1874/* setting clock to external - SPDIF */
1828static void stdclock_set_spdif_clock(struct snd_ice1712 *ice) 1875static int stdclock_set_spdif_clock(struct snd_ice1712 *ice, int type)
1829{ 1876{
1830 unsigned char oval; 1877 unsigned char oval;
1831 unsigned char i2s_oval; 1878 unsigned char i2s_oval;
@@ -1834,27 +1881,30 @@ static void stdclock_set_spdif_clock(struct snd_ice1712 *ice)
1834 /* setting 256fs */ 1881 /* setting 256fs */
1835 i2s_oval = inb(ICEMT1724(ice, I2S_FORMAT)); 1882 i2s_oval = inb(ICEMT1724(ice, I2S_FORMAT));
1836 outb(i2s_oval & ~VT1724_MT_I2S_MCLK_128X, ICEMT1724(ice, I2S_FORMAT)); 1883 outb(i2s_oval & ~VT1724_MT_I2S_MCLK_128X, ICEMT1724(ice, I2S_FORMAT));
1884 return 0;
1837} 1885}
1838 1886
1887
1839static int snd_vt1724_pro_internal_clock_put(struct snd_kcontrol *kcontrol, 1888static int snd_vt1724_pro_internal_clock_put(struct snd_kcontrol *kcontrol,
1840 struct snd_ctl_elem_value *ucontrol) 1889 struct snd_ctl_elem_value *ucontrol)
1841{ 1890{
1842 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 1891 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1843 unsigned int old_rate, new_rate; 1892 unsigned int old_rate, new_rate;
1844 unsigned int item = ucontrol->value.enumerated.item[0]; 1893 unsigned int item = ucontrol->value.enumerated.item[0];
1845 unsigned int spdif = ice->hw_rates->count; 1894 unsigned int first_ext_clock = ice->hw_rates->count;
1846 1895
1847 if (item > spdif) 1896 if (item > first_ext_clock + ice->ext_clock_count - 1)
1848 return -EINVAL; 1897 return -EINVAL;
1849 1898
1899 /* if rate = 0 => external clock */
1850 spin_lock_irq(&ice->reg_lock); 1900 spin_lock_irq(&ice->reg_lock);
1851 if (ice->is_spdif_master(ice)) 1901 if (ice->is_spdif_master(ice))
1852 old_rate = 0; 1902 old_rate = 0;
1853 else 1903 else
1854 old_rate = ice->get_rate(ice); 1904 old_rate = ice->get_rate(ice);
1855 if (item == spdif) { 1905 if (item >= first_ext_clock) {
1856 /* switching to external clock via SPDIF */ 1906 /* switching to external clock */
1857 ice->set_spdif_clock(ice); 1907 ice->set_spdif_clock(ice, item - first_ext_clock);
1858 new_rate = 0; 1908 new_rate = 0;
1859 } else { 1909 } else {
1860 /* internal on-card clock */ 1910 /* internal on-card clock */
@@ -1866,7 +1916,7 @@ static int snd_vt1724_pro_internal_clock_put(struct snd_kcontrol *kcontrol,
1866 } 1916 }
1867 spin_unlock_irq(&ice->reg_lock); 1917 spin_unlock_irq(&ice->reg_lock);
1868 1918
1869 /* the first reset to the SPDIF master mode? */ 1919 /* the first switch to the ext. clock mode? */
1870 if (old_rate != new_rate && !new_rate) { 1920 if (old_rate != new_rate && !new_rate) {
1871 /* notify akm chips as well */ 1921 /* notify akm chips as well */
1872 unsigned int i; 1922 unsigned int i;
@@ -2136,6 +2186,7 @@ static struct snd_ice1712_card_info *card_tables[] __devinitdata = {
2136 snd_vt1724_phase_cards, 2186 snd_vt1724_phase_cards,
2137 snd_vt1724_wtm_cards, 2187 snd_vt1724_wtm_cards,
2138 snd_vt1724_se_cards, 2188 snd_vt1724_se_cards,
2189 snd_vt1724_qtet_cards,
2139 NULL, 2190 NULL,
2140}; 2191};
2141 2192
@@ -2434,7 +2485,9 @@ static int __devinit snd_vt1724_create(struct snd_card *card,
2434 mutex_init(&ice->open_mutex); 2485 mutex_init(&ice->open_mutex);
2435 mutex_init(&ice->i2c_mutex); 2486 mutex_init(&ice->i2c_mutex);
2436 ice->gpio.set_mask = snd_vt1724_set_gpio_mask; 2487 ice->gpio.set_mask = snd_vt1724_set_gpio_mask;
2488 ice->gpio.get_mask = snd_vt1724_get_gpio_mask;
2437 ice->gpio.set_dir = snd_vt1724_set_gpio_dir; 2489 ice->gpio.set_dir = snd_vt1724_set_gpio_dir;
2490 ice->gpio.get_dir = snd_vt1724_get_gpio_dir;
2438 ice->gpio.set_data = snd_vt1724_set_gpio_data; 2491 ice->gpio.set_data = snd_vt1724_set_gpio_data;
2439 ice->gpio.get_data = snd_vt1724_get_gpio_data; 2492 ice->gpio.get_data = snd_vt1724_get_gpio_data;
2440 ice->card = card; 2493 ice->card = card;
@@ -2522,6 +2575,9 @@ static int __devinit snd_vt1724_probe(struct pci_dev *pci,
2522 return err; 2575 return err;
2523 } 2576 }
2524 2577
2578 /* field init before calling chip_init */
2579 ice->ext_clock_count = 0;
2580
2525 for (tbl = card_tables; *tbl; tbl++) { 2581 for (tbl = card_tables; *tbl; tbl++) {
2526 for (c = *tbl; c->subvendor; c++) { 2582 for (c = *tbl; c->subvendor; c++) {
2527 if (c->subvendor == ice->eeprom.subvendor) { 2583 if (c->subvendor == ice->eeprom.subvendor) {
@@ -2560,6 +2616,13 @@ __found:
2560 ice->set_mclk = stdclock_set_mclk; 2616 ice->set_mclk = stdclock_set_mclk;
2561 if (!ice->set_spdif_clock) 2617 if (!ice->set_spdif_clock)
2562 ice->set_spdif_clock = stdclock_set_spdif_clock; 2618 ice->set_spdif_clock = stdclock_set_spdif_clock;
2619 if (!ice->get_spdif_master_type)
2620 ice->get_spdif_master_type = stdclock_get_spdif_master_type;
2621 if (!ice->ext_clock_names)
2622 ice->ext_clock_names = ext_clock_names;
2623 if (!ice->ext_clock_count)
2624 ice->ext_clock_count = ARRAY_SIZE(ext_clock_names);
2625
2563 if (!ice->hw_rates) 2626 if (!ice->hw_rates)
2564 set_std_hw_rates(ice); 2627 set_std_hw_rates(ice);
2565 2628
@@ -2719,7 +2782,7 @@ static int snd_vt1724_resume(struct pci_dev *pci)
2719 2782
2720 if (ice->pm_saved_is_spdif_master) { 2783 if (ice->pm_saved_is_spdif_master) {
2721 /* switching to external clock via SPDIF */ 2784 /* switching to external clock via SPDIF */
2722 ice->set_spdif_clock(ice); 2785 ice->set_spdif_clock(ice, 0);
2723 } else { 2786 } else {
2724 /* internal on-card clock */ 2787 /* internal on-card clock */
2725 snd_vt1724_set_pro_rate(ice, ice->pro_rate_default, 1); 2788 snd_vt1724_set_pro_rate(ice, ice->pro_rate_default, 1);
diff --git a/sound/pci/ice1712/juli.c b/sound/pci/ice1712/juli.c
index fd948bfd9aef..98bc3b7681b5 100644
--- a/sound/pci/ice1712/juli.c
+++ b/sound/pci/ice1712/juli.c
@@ -380,7 +380,7 @@ static struct snd_kcontrol_new juli_mute_controls[] __devinitdata = {
380 * inputs) are fed from Xilinx. 380 * inputs) are fed from Xilinx.
381 * 381 *
382 * I even checked traces on board and coded a support in driver for 382 * I even checked traces on board and coded a support in driver for
383 * an alternative possiblity - the unused I2S ICE output channels 383 * an alternative possibility - the unused I2S ICE output channels
384 * switched to HW-IN/SPDIF-IN and providing the monitoring signal to 384 * switched to HW-IN/SPDIF-IN and providing the monitoring signal to
385 * the DAC - to no avail. The I2S outputs seem to be unconnected. 385 * the DAC - to no avail. The I2S outputs seem to be unconnected.
386 * 386 *
@@ -412,25 +412,6 @@ static struct snd_kcontrol_new juli_mute_controls[] __devinitdata = {
412 }, 412 },
413}; 413};
414 414
415
416static void ak4358_proc_regs_read(struct snd_info_entry *entry,
417 struct snd_info_buffer *buffer)
418{
419 struct snd_ice1712 *ice = (struct snd_ice1712 *)entry->private_data;
420 int reg, val;
421 for (reg = 0; reg <= 0xf; reg++) {
422 val = snd_akm4xxx_get(ice->akm, 0, reg);
423 snd_iprintf(buffer, "0x%02x = 0x%02x\n", reg, val);
424 }
425}
426
427static void ak4358_proc_init(struct snd_ice1712 *ice)
428{
429 struct snd_info_entry *entry;
430 if (!snd_card_proc_new(ice->card, "ak4358_codec", &entry))
431 snd_info_set_text_ops(entry, ice, ak4358_proc_regs_read);
432}
433
434static char *slave_vols[] __devinitdata = { 415static char *slave_vols[] __devinitdata = {
435 PCM_VOLUME, 416 PCM_VOLUME,
436 MONITOR_AN_IN_VOLUME, 417 MONITOR_AN_IN_VOLUME,
@@ -496,14 +477,37 @@ static int __devinit juli_add_controls(struct snd_ice1712 *ice)
496 /* only capture SPDIF over AK4114 */ 477 /* only capture SPDIF over AK4114 */
497 err = snd_ak4114_build(spec->ak4114, NULL, 478 err = snd_ak4114_build(spec->ak4114, NULL,
498 ice->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream); 479 ice->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream);
499
500 ak4358_proc_init(ice);
501 if (err < 0) 480 if (err < 0)
502 return err; 481 return err;
503 return 0; 482 return 0;
504} 483}
505 484
506/* 485/*
486 * suspend/resume
487 * */
488
489#ifdef CONFIG_PM
490static int juli_resume(struct snd_ice1712 *ice)
491{
492 struct snd_akm4xxx *ak = ice->akm;
493 struct juli_spec *spec = ice->spec;
494 /* akm4358 un-reset, un-mute */
495 snd_akm4xxx_reset(ak, 0);
496 /* reinit ak4114 */
497 snd_ak4114_reinit(spec->ak4114);
498 return 0;
499}
500
501static int juli_suspend(struct snd_ice1712 *ice)
502{
503 struct snd_akm4xxx *ak = ice->akm;
504 /* akm4358 reset and soft-mute */
505 snd_akm4xxx_reset(ak, 1);
506 return 0;
507}
508#endif
509
510/*
507 * initialize the chip 511 * initialize the chip
508 */ 512 */
509 513
@@ -550,13 +554,14 @@ static inline unsigned char juli_set_mclk(struct snd_ice1712 *ice,
550} 554}
551 555
552/* setting clock to external - SPDIF */ 556/* setting clock to external - SPDIF */
553static void juli_set_spdif_clock(struct snd_ice1712 *ice) 557static int juli_set_spdif_clock(struct snd_ice1712 *ice, int type)
554{ 558{
555 unsigned int old; 559 unsigned int old;
556 old = ice->gpio.get_data(ice); 560 old = ice->gpio.get_data(ice);
557 /* external clock (= 0), multiply 1x, 48kHz */ 561 /* external clock (= 0), multiply 1x, 48kHz */
558 ice->gpio.set_data(ice, (old & ~GPIO_RATE_MASK) | GPIO_MULTI_1X | 562 ice->gpio.set_data(ice, (old & ~GPIO_RATE_MASK) | GPIO_MULTI_1X |
559 GPIO_FREQ_48KHZ); 563 GPIO_FREQ_48KHZ);
564 return 0;
560} 565}
561 566
562/* Called when ak4114 detects change in the input SPDIF stream */ 567/* Called when ak4114 detects change in the input SPDIF stream */
@@ -646,6 +651,13 @@ static int __devinit juli_init(struct snd_ice1712 *ice)
646 ice->set_spdif_clock = juli_set_spdif_clock; 651 ice->set_spdif_clock = juli_set_spdif_clock;
647 652
648 ice->spdif.ops.open = juli_spdif_in_open; 653 ice->spdif.ops.open = juli_spdif_in_open;
654
655#ifdef CONFIG_PM
656 ice->pm_resume = juli_resume;
657 ice->pm_suspend = juli_suspend;
658 ice->pm_suspend_enabled = 1;
659#endif
660
649 return 0; 661 return 0;
650} 662}
651 663
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/quartet.c b/sound/pci/ice1712/quartet.c
new file mode 100644
index 000000000000..1948632787e6
--- /dev/null
+++ b/sound/pci/ice1712/quartet.c
@@ -0,0 +1,1130 @@
1/*
2 * ALSA driver for ICEnsemble VT1724 (Envy24HT)
3 *
4 * Lowlevel functions for Infrasonic Quartet
5 *
6 * Copyright (c) 2009 Pavel Hofman <pavel.hofman@ivitera.com>
7 *
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 *
23 */
24
25#include <asm/io.h>
26#include <linux/delay.h>
27#include <linux/interrupt.h>
28#include <linux/init.h>
29#include <linux/slab.h>
30#include <sound/core.h>
31#include <sound/tlv.h>
32#include <sound/info.h>
33
34#include "ice1712.h"
35#include "envy24ht.h"
36#include <sound/ak4113.h>
37#include "quartet.h"
38
39struct qtet_spec {
40 struct ak4113 *ak4113;
41 unsigned int scr; /* system control register */
42 unsigned int mcr; /* monitoring control register */
43 unsigned int cpld; /* cpld register */
44};
45
46struct qtet_kcontrol_private {
47 unsigned int bit;
48 void (*set_register)(struct snd_ice1712 *ice, unsigned int val);
49 unsigned int (*get_register)(struct snd_ice1712 *ice);
50 unsigned char *texts[2];
51};
52
53enum {
54 IN12_SEL = 0,
55 IN34_SEL,
56 AIN34_SEL,
57 COAX_OUT,
58 IN12_MON12,
59 IN12_MON34,
60 IN34_MON12,
61 IN34_MON34,
62 OUT12_MON34,
63 OUT34_MON12,
64};
65
66static char *ext_clock_names[3] = {"IEC958 In", "Word Clock 1xFS",
67 "Word Clock 256xFS"};
68
69/* chip address on I2C bus */
70#define AK4113_ADDR 0x26 /* S/PDIF receiver */
71
72/* chip address on SPI bus */
73#define AK4620_ADDR 0x02 /* ADC/DAC */
74
75
76/*
77 * GPIO pins
78 */
79
80/* GPIO0 - O - DATA0, def. 0 */
81#define GPIO_D0 (1<<0)
82/* GPIO1 - I/O - DATA1, Jack Detect Input0 (0:present, 1:missing), def. 1 */
83#define GPIO_D1_JACKDTC0 (1<<1)
84/* GPIO2 - I/O - DATA2, Jack Detect Input1 (0:present, 1:missing), def. 1 */
85#define GPIO_D2_JACKDTC1 (1<<2)
86/* GPIO3 - I/O - DATA3, def. 1 */
87#define GPIO_D3 (1<<3)
88/* GPIO4 - I/O - DATA4, SPI CDTO, def. 1 */
89#define GPIO_D4_SPI_CDTO (1<<4)
90/* GPIO5 - I/O - DATA5, SPI CCLK, def. 1 */
91#define GPIO_D5_SPI_CCLK (1<<5)
92/* GPIO6 - I/O - DATA6, Cable Detect Input (0:detected, 1:not detected */
93#define GPIO_D6_CD (1<<6)
94/* GPIO7 - I/O - DATA7, Device Detect Input (0:detected, 1:not detected */
95#define GPIO_D7_DD (1<<7)
96/* GPIO8 - O - CPLD Chip Select, def. 1 */
97#define GPIO_CPLD_CSN (1<<8)
98/* GPIO9 - O - CPLD register read/write (0:write, 1:read), def. 0 */
99#define GPIO_CPLD_RW (1<<9)
100/* GPIO10 - O - SPI Chip Select for CODEC#0, def. 1 */
101#define GPIO_SPI_CSN0 (1<<10)
102/* GPIO11 - O - SPI Chip Select for CODEC#1, def. 1 */
103#define GPIO_SPI_CSN1 (1<<11)
104/* GPIO12 - O - Ex. Register Output Enable (0:enable, 1:disable), def. 1,
105 * init 0 */
106#define GPIO_EX_GPIOE (1<<12)
107/* GPIO13 - O - Ex. Register0 Chip Select for System Control Register,
108 * def. 1 */
109#define GPIO_SCR (1<<13)
110/* GPIO14 - O - Ex. Register1 Chip Select for Monitor Control Register,
111 * def. 1 */
112#define GPIO_MCR (1<<14)
113
114#define GPIO_SPI_ALL (GPIO_D4_SPI_CDTO | GPIO_D5_SPI_CCLK |\
115 GPIO_SPI_CSN0 | GPIO_SPI_CSN1)
116
117#define GPIO_DATA_MASK (GPIO_D0 | GPIO_D1_JACKDTC0 | \
118 GPIO_D2_JACKDTC1 | GPIO_D3 | \
119 GPIO_D4_SPI_CDTO | GPIO_D5_SPI_CCLK | \
120 GPIO_D6_CD | GPIO_D7_DD)
121
122/* System Control Register GPIO_SCR data bits */
123/* Mic/Line select relay (0:line, 1:mic) */
124#define SCR_RELAY GPIO_D0
125/* Phantom power drive control (0:5V, 1:48V) */
126#define SCR_PHP_V GPIO_D1_JACKDTC0
127/* H/W mute control (0:Normal, 1:Mute) */
128#define SCR_MUTE GPIO_D2_JACKDTC1
129/* Phantom power control (0:Phantom on, 1:off) */
130#define SCR_PHP GPIO_D3
131/* Analog input 1/2 Source Select */
132#define SCR_AIN12_SEL0 GPIO_D4_SPI_CDTO
133#define SCR_AIN12_SEL1 GPIO_D5_SPI_CCLK
134/* Analog input 3/4 Source Select (0:line, 1:hi-z) */
135#define SCR_AIN34_SEL GPIO_D6_CD
136/* Codec Power Down (0:power down, 1:normal) */
137#define SCR_CODEC_PDN GPIO_D7_DD
138
139#define SCR_AIN12_LINE (0)
140#define SCR_AIN12_MIC (SCR_AIN12_SEL0)
141#define SCR_AIN12_LOWCUT (SCR_AIN12_SEL1 | SCR_AIN12_SEL0)
142
143/* Monitor Control Register GPIO_MCR data bits */
144/* Input 1/2 to Monitor 1/2 (0:off, 1:on) */
145#define MCR_IN12_MON12 GPIO_D0
146/* Input 1/2 to Monitor 3/4 (0:off, 1:on) */
147#define MCR_IN12_MON34 GPIO_D1_JACKDTC0
148/* Input 3/4 to Monitor 1/2 (0:off, 1:on) */
149#define MCR_IN34_MON12 GPIO_D2_JACKDTC1
150/* Input 3/4 to Monitor 3/4 (0:off, 1:on) */
151#define MCR_IN34_MON34 GPIO_D3
152/* Output to Monitor 1/2 (0:off, 1:on) */
153#define MCR_OUT34_MON12 GPIO_D4_SPI_CDTO
154/* Output to Monitor 3/4 (0:off, 1:on) */
155#define MCR_OUT12_MON34 GPIO_D5_SPI_CCLK
156
157/* CPLD Register DATA bits */
158/* Clock Rate Select */
159#define CPLD_CKS0 GPIO_D0
160#define CPLD_CKS1 GPIO_D1_JACKDTC0
161#define CPLD_CKS2 GPIO_D2_JACKDTC1
162/* Sync Source Select (0:Internal, 1:External) */
163#define CPLD_SYNC_SEL GPIO_D3
164/* Word Clock FS Select (0:FS, 1:256FS) */
165#define CPLD_WORD_SEL GPIO_D4_SPI_CDTO
166/* Coaxial Output Source (IS-Link) (0:SPDIF, 1:I2S) */
167#define CPLD_COAX_OUT GPIO_D5_SPI_CCLK
168/* Input 1/2 Source Select (0:Analog12, 1:An34) */
169#define CPLD_IN12_SEL GPIO_D6_CD
170/* Input 3/4 Source Select (0:Analog34, 1:Digital In) */
171#define CPLD_IN34_SEL GPIO_D7_DD
172
173/* internal clock (CPLD_SYNC_SEL = 0) options */
174#define CPLD_CKS_44100HZ (0)
175#define CPLD_CKS_48000HZ (CPLD_CKS0)
176#define CPLD_CKS_88200HZ (CPLD_CKS1)
177#define CPLD_CKS_96000HZ (CPLD_CKS1 | CPLD_CKS0)
178#define CPLD_CKS_176400HZ (CPLD_CKS2)
179#define CPLD_CKS_192000HZ (CPLD_CKS2 | CPLD_CKS0)
180
181#define CPLD_CKS_MASK (CPLD_CKS0 | CPLD_CKS1 | CPLD_CKS2)
182
183/* external clock (CPLD_SYNC_SEL = 1) options */
184/* external clock - SPDIF */
185#define CPLD_EXT_SPDIF (0 | CPLD_SYNC_SEL)
186/* external clock - WordClock 1xfs */
187#define CPLD_EXT_WORDCLOCK_1FS (CPLD_CKS1 | CPLD_SYNC_SEL)
188/* external clock - WordClock 256xfs */
189#define CPLD_EXT_WORDCLOCK_256FS (CPLD_CKS1 | CPLD_WORD_SEL |\
190 CPLD_SYNC_SEL)
191
192#define EXT_SPDIF_TYPE 0
193#define EXT_WORDCLOCK_1FS_TYPE 1
194#define EXT_WORDCLOCK_256FS_TYPE 2
195
196#define AK4620_DFS0 (1<<0)
197#define AK4620_DFS1 (1<<1)
198#define AK4620_CKS0 (1<<2)
199#define AK4620_CKS1 (1<<3)
200/* Clock and Format Control register */
201#define AK4620_DFS_REG 0x02
202
203/* Deem and Volume Control register */
204#define AK4620_DEEMVOL_REG 0x03
205#define AK4620_SMUTE (1<<7)
206
207/*
208 * Conversion from int value to its binary form. Used for debugging.
209 * The output buffer must be allocated prior to calling the function.
210 */
211static char *get_binary(char *buffer, int value)
212{
213 int i, j, pos;
214 pos = 0;
215 for (i = 0; i < 4; ++i) {
216 for (j = 0; j < 8; ++j) {
217 if (value & (1 << (31-(i*8 + j))))
218 buffer[pos] = '1';
219 else
220 buffer[pos] = '0';
221 pos++;
222 }
223 if (i < 3) {
224 buffer[pos] = ' ';
225 pos++;
226 }
227 }
228 buffer[pos] = '\0';
229 return buffer;
230}
231
232/*
233 * Initial setup of the conversion array GPIO <-> rate
234 */
235static unsigned int qtet_rates[] = {
236 44100, 48000, 88200,
237 96000, 176400, 192000,
238};
239
240static unsigned int cks_vals[] = {
241 CPLD_CKS_44100HZ, CPLD_CKS_48000HZ, CPLD_CKS_88200HZ,
242 CPLD_CKS_96000HZ, CPLD_CKS_176400HZ, CPLD_CKS_192000HZ,
243};
244
245static struct snd_pcm_hw_constraint_list qtet_rates_info = {
246 .count = ARRAY_SIZE(qtet_rates),
247 .list = qtet_rates,
248 .mask = 0,
249};
250
251static void qtet_ak4113_write(void *private_data, unsigned char reg,
252 unsigned char val)
253{
254 snd_vt1724_write_i2c((struct snd_ice1712 *)private_data, AK4113_ADDR,
255 reg, val);
256}
257
258static unsigned char qtet_ak4113_read(void *private_data, unsigned char reg)
259{
260 return snd_vt1724_read_i2c((struct snd_ice1712 *)private_data,
261 AK4113_ADDR, reg);
262}
263
264
265/*
266 * AK4620 section
267 */
268
269/*
270 * Write data to addr register of ak4620
271 */
272static void qtet_akm_write(struct snd_akm4xxx *ak, int chip,
273 unsigned char addr, unsigned char data)
274{
275 unsigned int tmp, orig_dir;
276 int idx;
277 unsigned int addrdata;
278 struct snd_ice1712 *ice = ak->private_data[0];
279
280 if (snd_BUG_ON(chip < 0 || chip >= 4))
281 return;
282 /*printk(KERN_DEBUG "Writing to AK4620: chip=%d, addr=0x%x,
283 data=0x%x\n", chip, addr, data);*/
284 orig_dir = ice->gpio.get_dir(ice);
285 ice->gpio.set_dir(ice, orig_dir | GPIO_SPI_ALL);
286 /* set mask - only SPI bits */
287 ice->gpio.set_mask(ice, ~GPIO_SPI_ALL);
288
289 tmp = ice->gpio.get_data(ice);
290 /* high all */
291 tmp |= GPIO_SPI_ALL;
292 ice->gpio.set_data(ice, tmp);
293 udelay(100);
294 /* drop chip select */
295 if (chip)
296 /* CODEC 1 */
297 tmp &= ~GPIO_SPI_CSN1;
298 else
299 tmp &= ~GPIO_SPI_CSN0;
300 ice->gpio.set_data(ice, tmp);
301 udelay(100);
302
303 /* build I2C address + data byte */
304 addrdata = (AK4620_ADDR << 6) | 0x20 | (addr & 0x1f);
305 addrdata = (addrdata << 8) | data;
306 for (idx = 15; idx >= 0; idx--) {
307 /* drop clock */
308 tmp &= ~GPIO_D5_SPI_CCLK;
309 ice->gpio.set_data(ice, tmp);
310 udelay(100);
311 /* set data */
312 if (addrdata & (1 << idx))
313 tmp |= GPIO_D4_SPI_CDTO;
314 else
315 tmp &= ~GPIO_D4_SPI_CDTO;
316 ice->gpio.set_data(ice, tmp);
317 udelay(100);
318 /* raise clock */
319 tmp |= GPIO_D5_SPI_CCLK;
320 ice->gpio.set_data(ice, tmp);
321 udelay(100);
322 }
323 /* all back to 1 */
324 tmp |= GPIO_SPI_ALL;
325 ice->gpio.set_data(ice, tmp);
326 udelay(100);
327
328 /* return all gpios to non-writable */
329 ice->gpio.set_mask(ice, 0xffffff);
330 /* restore GPIOs direction */
331 ice->gpio.set_dir(ice, orig_dir);
332}
333
334static void qtet_akm_set_regs(struct snd_akm4xxx *ak, unsigned char addr,
335 unsigned char mask, unsigned char value)
336{
337 unsigned char tmp;
338 int chip;
339 for (chip = 0; chip < ak->num_chips; chip++) {
340 tmp = snd_akm4xxx_get(ak, chip, addr);
341 /* clear the bits */
342 tmp &= ~mask;
343 /* set the new bits */
344 tmp |= value;
345 snd_akm4xxx_write(ak, chip, addr, tmp);
346 }
347}
348
349/*
350 * change the rate of AK4620
351 */
352static void qtet_akm_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate)
353{
354 unsigned char ak4620_dfs;
355
356 if (rate == 0) /* no hint - S/PDIF input is master or the new spdif
357 input rate undetected, simply return */
358 return;
359
360 /* adjust DFS on codecs - see datasheet */
361 if (rate > 108000)
362 ak4620_dfs = AK4620_DFS1 | AK4620_CKS1;
363 else if (rate > 54000)
364 ak4620_dfs = AK4620_DFS0 | AK4620_CKS0;
365 else
366 ak4620_dfs = 0;
367
368 /* set new value */
369 qtet_akm_set_regs(ak, AK4620_DFS_REG, AK4620_DFS0 | AK4620_DFS1 |
370 AK4620_CKS0 | AK4620_CKS1, ak4620_dfs);
371}
372
373#define AK_CONTROL(xname, xch) { .name = xname, .num_channels = xch }
374
375#define PCM_12_PLAYBACK_VOLUME "PCM 1/2 Playback Volume"
376#define PCM_34_PLAYBACK_VOLUME "PCM 3/4 Playback Volume"
377#define PCM_12_CAPTURE_VOLUME "PCM 1/2 Capture Volume"
378#define PCM_34_CAPTURE_VOLUME "PCM 3/4 Capture Volume"
379
380static const struct snd_akm4xxx_dac_channel qtet_dac[] = {
381 AK_CONTROL(PCM_12_PLAYBACK_VOLUME, 2),
382 AK_CONTROL(PCM_34_PLAYBACK_VOLUME, 2),
383};
384
385static const struct snd_akm4xxx_adc_channel qtet_adc[] = {
386 AK_CONTROL(PCM_12_CAPTURE_VOLUME, 2),
387 AK_CONTROL(PCM_34_CAPTURE_VOLUME, 2),
388};
389
390static struct snd_akm4xxx akm_qtet_dac __devinitdata = {
391 .type = SND_AK4620,
392 .num_dacs = 4, /* DAC1 - Output 12
393 */
394 .num_adcs = 4, /* ADC1 - Input 12
395 */
396 .ops = {
397 .write = qtet_akm_write,
398 .set_rate_val = qtet_akm_set_rate_val,
399 },
400 .dac_info = qtet_dac,
401 .adc_info = qtet_adc,
402};
403
404/* Communication routines with the CPLD */
405
406
407/* Writes data to external register reg, both reg and data are
408 * GPIO representations */
409static void reg_write(struct snd_ice1712 *ice, unsigned int reg,
410 unsigned int data)
411{
412 unsigned int tmp;
413
414 mutex_lock(&ice->gpio_mutex);
415 /* set direction of used GPIOs*/
416 /* all outputs */
417 tmp = 0x00ffff;
418 ice->gpio.set_dir(ice, tmp);
419 /* mask - writable bits */
420 ice->gpio.set_mask(ice, ~(tmp));
421 /* write the data */
422 tmp = ice->gpio.get_data(ice);
423 tmp &= ~GPIO_DATA_MASK;
424 tmp |= data;
425 ice->gpio.set_data(ice, tmp);
426 udelay(100);
427 /* drop output enable */
428 tmp &= ~GPIO_EX_GPIOE;
429 ice->gpio.set_data(ice, tmp);
430 udelay(100);
431 /* drop the register gpio */
432 tmp &= ~reg;
433 ice->gpio.set_data(ice, tmp);
434 udelay(100);
435 /* raise the register GPIO */
436 tmp |= reg;
437 ice->gpio.set_data(ice, tmp);
438 udelay(100);
439
440 /* raise all data gpios */
441 tmp |= GPIO_DATA_MASK;
442 ice->gpio.set_data(ice, tmp);
443 /* mask - immutable bits */
444 ice->gpio.set_mask(ice, 0xffffff);
445 /* outputs only 8-15 */
446 ice->gpio.set_dir(ice, 0x00ff00);
447 mutex_unlock(&ice->gpio_mutex);
448}
449
450static unsigned int get_scr(struct snd_ice1712 *ice)
451{
452 struct qtet_spec *spec = ice->spec;
453 return spec->scr;
454}
455
456static unsigned int get_mcr(struct snd_ice1712 *ice)
457{
458 struct qtet_spec *spec = ice->spec;
459 return spec->mcr;
460}
461
462static unsigned int get_cpld(struct snd_ice1712 *ice)
463{
464 struct qtet_spec *spec = ice->spec;
465 return spec->cpld;
466}
467
468static void set_scr(struct snd_ice1712 *ice, unsigned int val)
469{
470 struct qtet_spec *spec = ice->spec;
471 reg_write(ice, GPIO_SCR, val);
472 spec->scr = val;
473}
474
475static void set_mcr(struct snd_ice1712 *ice, unsigned int val)
476{
477 struct qtet_spec *spec = ice->spec;
478 reg_write(ice, GPIO_MCR, val);
479 spec->mcr = val;
480}
481
482static void set_cpld(struct snd_ice1712 *ice, unsigned int val)
483{
484 struct qtet_spec *spec = ice->spec;
485 reg_write(ice, GPIO_CPLD_CSN, val);
486 spec->cpld = val;
487}
488#ifdef CONFIG_PROC_FS
489static void proc_regs_read(struct snd_info_entry *entry,
490 struct snd_info_buffer *buffer)
491{
492 struct snd_ice1712 *ice = entry->private_data;
493 char bin_buffer[36];
494
495 snd_iprintf(buffer, "SCR: %s\n", get_binary(bin_buffer,
496 get_scr(ice)));
497 snd_iprintf(buffer, "MCR: %s\n", get_binary(bin_buffer,
498 get_mcr(ice)));
499 snd_iprintf(buffer, "CPLD: %s\n", get_binary(bin_buffer,
500 get_cpld(ice)));
501}
502
503static void proc_init(struct snd_ice1712 *ice)
504{
505 struct snd_info_entry *entry;
506 if (!snd_card_proc_new(ice->card, "quartet", &entry))
507 snd_info_set_text_ops(entry, ice, proc_regs_read);
508}
509#else /* !CONFIG_PROC_FS */
510static void proc_init(struct snd_ice1712 *ice) {}
511#endif
512
513static int qtet_mute_get(struct snd_kcontrol *kcontrol,
514 struct snd_ctl_elem_value *ucontrol)
515{
516 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
517 unsigned int val;
518 val = get_scr(ice) & SCR_MUTE;
519 ucontrol->value.integer.value[0] = (val) ? 0 : 1;
520 return 0;
521}
522
523static int qtet_mute_put(struct snd_kcontrol *kcontrol,
524 struct snd_ctl_elem_value *ucontrol)
525{
526 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
527 unsigned int old, new, smute;
528 old = get_scr(ice) & SCR_MUTE;
529 if (ucontrol->value.integer.value[0]) {
530 /* unmute */
531 new = 0;
532 /* un-smuting DAC */
533 smute = 0;
534 } else {
535 /* mute */
536 new = SCR_MUTE;
537 /* smuting DAC */
538 smute = AK4620_SMUTE;
539 }
540 if (old != new) {
541 struct snd_akm4xxx *ak = ice->akm;
542 set_scr(ice, (get_scr(ice) & ~SCR_MUTE) | new);
543 /* set smute */
544 qtet_akm_set_regs(ak, AK4620_DEEMVOL_REG, AK4620_SMUTE, smute);
545 return 1;
546 }
547 /* no change */
548 return 0;
549}
550
551static int qtet_ain12_enum_info(struct snd_kcontrol *kcontrol,
552 struct snd_ctl_elem_info *uinfo)
553{
554 static char *texts[3] = {"Line In 1/2", "Mic", "Mic + Low-cut"};
555 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
556 uinfo->count = 1;
557 uinfo->value.enumerated.items = ARRAY_SIZE(texts);
558
559 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
560 uinfo->value.enumerated.item =
561 uinfo->value.enumerated.items - 1;
562 strcpy(uinfo->value.enumerated.name,
563 texts[uinfo->value.enumerated.item]);
564
565 return 0;
566}
567
568static int qtet_ain12_sw_get(struct snd_kcontrol *kcontrol,
569 struct snd_ctl_elem_value *ucontrol)
570{
571 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
572 unsigned int val, result;
573 val = get_scr(ice) & (SCR_AIN12_SEL1 | SCR_AIN12_SEL0);
574 switch (val) {
575 case SCR_AIN12_LINE:
576 result = 0;
577 break;
578 case SCR_AIN12_MIC:
579 result = 1;
580 break;
581 case SCR_AIN12_LOWCUT:
582 result = 2;
583 break;
584 default:
585 /* BUG - no other combinations allowed */
586 snd_BUG();
587 result = 0;
588 }
589 ucontrol->value.integer.value[0] = result;
590 return 0;
591}
592
593static int qtet_ain12_sw_put(struct snd_kcontrol *kcontrol,
594 struct snd_ctl_elem_value *ucontrol)
595{
596 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
597 unsigned int old, new, tmp, masked_old;
598 old = new = get_scr(ice);
599 masked_old = old & (SCR_AIN12_SEL1 | SCR_AIN12_SEL0);
600 tmp = ucontrol->value.integer.value[0];
601 if (tmp == 2)
602 tmp = 3; /* binary 10 is not supported */
603 tmp <<= 4; /* shifting to SCR_AIN12_SEL0 */
604 if (tmp != masked_old) {
605 /* change requested */
606 switch (tmp) {
607 case SCR_AIN12_LINE:
608 new = old & ~(SCR_AIN12_SEL1 | SCR_AIN12_SEL0);
609 set_scr(ice, new);
610 /* turn off relay */
611 new &= ~SCR_RELAY;
612 set_scr(ice, new);
613 break;
614 case SCR_AIN12_MIC:
615 /* turn on relay */
616 new = old | SCR_RELAY;
617 set_scr(ice, new);
618 new = (new & ~SCR_AIN12_SEL1) | SCR_AIN12_SEL0;
619 set_scr(ice, new);
620 break;
621 case SCR_AIN12_LOWCUT:
622 /* turn on relay */
623 new = old | SCR_RELAY;
624 set_scr(ice, new);
625 new |= SCR_AIN12_SEL1 | SCR_AIN12_SEL0;
626 set_scr(ice, new);
627 break;
628 default:
629 snd_BUG();
630 }
631 return 1;
632 }
633 /* no change */
634 return 0;
635}
636
637static int qtet_php_get(struct snd_kcontrol *kcontrol,
638 struct snd_ctl_elem_value *ucontrol)
639{
640 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
641 unsigned int val;
642 /* if phantom voltage =48V, phantom on */
643 val = get_scr(ice) & SCR_PHP_V;
644 ucontrol->value.integer.value[0] = val ? 1 : 0;
645 return 0;
646}
647
648static int qtet_php_put(struct snd_kcontrol *kcontrol,
649 struct snd_ctl_elem_value *ucontrol)
650{
651 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
652 unsigned int old, new;
653 old = new = get_scr(ice);
654 if (ucontrol->value.integer.value[0] /* phantom on requested */
655 && (~old & SCR_PHP_V)) /* 0 = voltage 5V */ {
656 /* is off, turn on */
657 /* turn voltage on first, = 1 */
658 new = old | SCR_PHP_V;
659 set_scr(ice, new);
660 /* turn phantom on, = 0 */
661 new &= ~SCR_PHP;
662 set_scr(ice, new);
663 } else if (!ucontrol->value.integer.value[0] && (old & SCR_PHP_V)) {
664 /* phantom off requested and 1 = voltage 48V */
665 /* is on, turn off */
666 /* turn voltage off first, = 0 */
667 new = old & ~SCR_PHP_V;
668 set_scr(ice, new);
669 /* turn phantom off, = 1 */
670 new |= SCR_PHP;
671 set_scr(ice, new);
672 }
673 if (old != new)
674 return 1;
675 /* no change */
676 return 0;
677}
678
679#define PRIV_SW(xid, xbit, xreg) [xid] = {.bit = xbit,\
680 .set_register = set_##xreg,\
681 .get_register = get_##xreg, }
682
683
684#define PRIV_ENUM2(xid, xbit, xreg, xtext1, xtext2) [xid] = {.bit = xbit,\
685 .set_register = set_##xreg,\
686 .get_register = get_##xreg,\
687 .texts = {xtext1, xtext2} }
688
689static struct qtet_kcontrol_private qtet_privates[] = {
690 PRIV_ENUM2(IN12_SEL, CPLD_IN12_SEL, cpld, "An In 1/2", "An In 3/4"),
691 PRIV_ENUM2(IN34_SEL, CPLD_IN34_SEL, cpld, "An In 3/4", "IEC958 In"),
692 PRIV_ENUM2(AIN34_SEL, SCR_AIN34_SEL, scr, "Line In 3/4", "Hi-Z"),
693 PRIV_ENUM2(COAX_OUT, CPLD_COAX_OUT, cpld, "IEC958", "I2S"),
694 PRIV_SW(IN12_MON12, MCR_IN12_MON12, mcr),
695 PRIV_SW(IN12_MON34, MCR_IN12_MON34, mcr),
696 PRIV_SW(IN34_MON12, MCR_IN34_MON12, mcr),
697 PRIV_SW(IN34_MON34, MCR_IN34_MON34, mcr),
698 PRIV_SW(OUT12_MON34, MCR_OUT12_MON34, mcr),
699 PRIV_SW(OUT34_MON12, MCR_OUT34_MON12, mcr),
700};
701
702static int qtet_enum_info(struct snd_kcontrol *kcontrol,
703 struct snd_ctl_elem_info *uinfo)
704{
705 struct qtet_kcontrol_private private =
706 qtet_privates[kcontrol->private_value];
707 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
708 uinfo->count = 1;
709 uinfo->value.enumerated.items = ARRAY_SIZE(private.texts);
710
711 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
712 uinfo->value.enumerated.item =
713 uinfo->value.enumerated.items - 1;
714 strcpy(uinfo->value.enumerated.name,
715 private.texts[uinfo->value.enumerated.item]);
716
717 return 0;
718}
719
720static int qtet_sw_get(struct snd_kcontrol *kcontrol,
721 struct snd_ctl_elem_value *ucontrol)
722{
723 struct qtet_kcontrol_private private =
724 qtet_privates[kcontrol->private_value];
725 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
726 ucontrol->value.integer.value[0] =
727 (private.get_register(ice) & private.bit) ? 1 : 0;
728 return 0;
729}
730
731static int qtet_sw_put(struct snd_kcontrol *kcontrol,
732 struct snd_ctl_elem_value *ucontrol)
733{
734 struct qtet_kcontrol_private private =
735 qtet_privates[kcontrol->private_value];
736 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
737 unsigned int old, new;
738 old = private.get_register(ice);
739 if (ucontrol->value.integer.value[0])
740 new = old | private.bit;
741 else
742 new = old & ~private.bit;
743 if (old != new) {
744 private.set_register(ice, new);
745 return 1;
746 }
747 /* no change */
748 return 0;
749}
750
751#define qtet_sw_info snd_ctl_boolean_mono_info
752
753#define QTET_CONTROL(xname, xtype, xpriv) \
754 {.iface = SNDRV_CTL_ELEM_IFACE_MIXER,\
755 .name = xname,\
756 .info = qtet_##xtype##_info,\
757 .get = qtet_sw_get,\
758 .put = qtet_sw_put,\
759 .private_value = xpriv }
760
761static struct snd_kcontrol_new qtet_controls[] __devinitdata = {
762 {
763 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
764 .name = "Master Playback Switch",
765 .info = qtet_sw_info,
766 .get = qtet_mute_get,
767 .put = qtet_mute_put,
768 .private_value = 0
769 },
770 {
771 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
772 .name = "Phantom Power",
773 .info = qtet_sw_info,
774 .get = qtet_php_get,
775 .put = qtet_php_put,
776 .private_value = 0
777 },
778 {
779 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
780 .name = "Analog In 1/2 Capture Switch",
781 .info = qtet_ain12_enum_info,
782 .get = qtet_ain12_sw_get,
783 .put = qtet_ain12_sw_put,
784 .private_value = 0
785 },
786 QTET_CONTROL("Analog In 3/4 Capture Switch", enum, AIN34_SEL),
787 QTET_CONTROL("PCM In 1/2 Capture Switch", enum, IN12_SEL),
788 QTET_CONTROL("PCM In 3/4 Capture Switch", enum, IN34_SEL),
789 QTET_CONTROL("Coax Output Source", enum, COAX_OUT),
790 QTET_CONTROL("Analog In 1/2 to Monitor 1/2", sw, IN12_MON12),
791 QTET_CONTROL("Analog In 1/2 to Monitor 3/4", sw, IN12_MON34),
792 QTET_CONTROL("Analog In 3/4 to Monitor 1/2", sw, IN34_MON12),
793 QTET_CONTROL("Analog In 3/4 to Monitor 3/4", sw, IN34_MON34),
794 QTET_CONTROL("Output 1/2 to Monitor 3/4", sw, OUT12_MON34),
795 QTET_CONTROL("Output 3/4 to Monitor 1/2", sw, OUT34_MON12),
796};
797
798static char *slave_vols[] __devinitdata = {
799 PCM_12_PLAYBACK_VOLUME,
800 PCM_34_PLAYBACK_VOLUME,
801 NULL
802};
803
804static __devinitdata
805DECLARE_TLV_DB_SCALE(qtet_master_db_scale, -6350, 50, 1);
806
807static struct snd_kcontrol __devinit *ctl_find(struct snd_card *card,
808 const char *name)
809{
810 struct snd_ctl_elem_id sid;
811 memset(&sid, 0, sizeof(sid));
812 /* FIXME: strcpy is bad. */
813 strcpy(sid.name, name);
814 sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
815 return snd_ctl_find_id(card, &sid);
816}
817
818static void __devinit add_slaves(struct snd_card *card,
819 struct snd_kcontrol *master, char **list)
820{
821 for (; *list; list++) {
822 struct snd_kcontrol *slave = ctl_find(card, *list);
823 if (slave)
824 snd_ctl_add_slave(master, slave);
825 }
826}
827
828static int __devinit qtet_add_controls(struct snd_ice1712 *ice)
829{
830 struct qtet_spec *spec = ice->spec;
831 int err, i;
832 struct snd_kcontrol *vmaster;
833 err = snd_ice1712_akm4xxx_build_controls(ice);
834 if (err < 0)
835 return err;
836 for (i = 0; i < ARRAY_SIZE(qtet_controls); i++) {
837 err = snd_ctl_add(ice->card,
838 snd_ctl_new1(&qtet_controls[i], ice));
839 if (err < 0)
840 return err;
841 }
842
843 /* Create virtual master control */
844 vmaster = snd_ctl_make_virtual_master("Master Playback Volume",
845 qtet_master_db_scale);
846 if (!vmaster)
847 return -ENOMEM;
848 add_slaves(ice->card, vmaster, slave_vols);
849 err = snd_ctl_add(ice->card, vmaster);
850 if (err < 0)
851 return err;
852 /* only capture SPDIF over AK4113 */
853 err = snd_ak4113_build(spec->ak4113,
854 ice->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream);
855 if (err < 0)
856 return err;
857 return 0;
858}
859
860static inline int qtet_is_spdif_master(struct snd_ice1712 *ice)
861{
862 /* CPLD_SYNC_SEL: 0 = internal, 1 = external (i.e. spdif master) */
863 return (get_cpld(ice) & CPLD_SYNC_SEL) ? 1 : 0;
864}
865
866static unsigned int qtet_get_rate(struct snd_ice1712 *ice)
867{
868 int i;
869 unsigned char result;
870
871 result = get_cpld(ice) & CPLD_CKS_MASK;
872 for (i = 0; i < ARRAY_SIZE(cks_vals); i++)
873 if (cks_vals[i] == result)
874 return qtet_rates[i];
875 return 0;
876}
877
878static int get_cks_val(int rate)
879{
880 int i;
881 for (i = 0; i < ARRAY_SIZE(qtet_rates); i++)
882 if (qtet_rates[i] == rate)
883 return cks_vals[i];
884 return 0;
885}
886
887/* setting new rate */
888static void qtet_set_rate(struct snd_ice1712 *ice, unsigned int rate)
889{
890 unsigned int new;
891 unsigned char val;
892 /* switching ice1724 to external clock - supplied by ext. circuits */
893 val = inb(ICEMT1724(ice, RATE));
894 outb(val | VT1724_SPDIF_MASTER, ICEMT1724(ice, RATE));
895
896 new = (get_cpld(ice) & ~CPLD_CKS_MASK) | get_cks_val(rate);
897 /* switch to internal clock, drop CPLD_SYNC_SEL */
898 new &= ~CPLD_SYNC_SEL;
899 /* printk(KERN_DEBUG "QT - set_rate: old %x, new %x\n",
900 get_cpld(ice), new); */
901 set_cpld(ice, new);
902}
903
904static inline unsigned char qtet_set_mclk(struct snd_ice1712 *ice,
905 unsigned int rate)
906{
907 /* no change in master clock */
908 return 0;
909}
910
911/* setting clock to external - SPDIF */
912static int qtet_set_spdif_clock(struct snd_ice1712 *ice, int type)
913{
914 unsigned int old, new;
915
916 old = new = get_cpld(ice);
917 new &= ~(CPLD_CKS_MASK | CPLD_WORD_SEL);
918 switch (type) {
919 case EXT_SPDIF_TYPE:
920 new |= CPLD_EXT_SPDIF;
921 break;
922 case EXT_WORDCLOCK_1FS_TYPE:
923 new |= CPLD_EXT_WORDCLOCK_1FS;
924 break;
925 case EXT_WORDCLOCK_256FS_TYPE:
926 new |= CPLD_EXT_WORDCLOCK_256FS;
927 break;
928 default:
929 snd_BUG();
930 }
931 if (old != new) {
932 set_cpld(ice, new);
933 /* changed */
934 return 1;
935 }
936 return 0;
937}
938
939static int qtet_get_spdif_master_type(struct snd_ice1712 *ice)
940{
941 unsigned int val;
942 int result;
943 val = get_cpld(ice);
944 /* checking only rate/clock-related bits */
945 val &= (CPLD_CKS_MASK | CPLD_WORD_SEL | CPLD_SYNC_SEL);
946 if (!(val & CPLD_SYNC_SEL)) {
947 /* switched to internal clock, is not any external type */
948 result = -1;
949 } else {
950 switch (val) {
951 case (CPLD_EXT_SPDIF):
952 result = EXT_SPDIF_TYPE;
953 break;
954 case (CPLD_EXT_WORDCLOCK_1FS):
955 result = EXT_WORDCLOCK_1FS_TYPE;
956 break;
957 case (CPLD_EXT_WORDCLOCK_256FS):
958 result = EXT_WORDCLOCK_256FS_TYPE;
959 break;
960 default:
961 /* undefined combination of external clock setup */
962 snd_BUG();
963 result = 0;
964 }
965 }
966 return result;
967}
968
969/* Called when ak4113 detects change in the input SPDIF stream */
970static void qtet_ak4113_change(struct ak4113 *ak4113, unsigned char c0,
971 unsigned char c1)
972{
973 struct snd_ice1712 *ice = ak4113->change_callback_private;
974 int rate;
975 if ((qtet_get_spdif_master_type(ice) == EXT_SPDIF_TYPE) &&
976 c1) {
977 /* only for SPDIF master mode, rate was changed */
978 rate = snd_ak4113_external_rate(ak4113);
979 /* printk(KERN_DEBUG "ak4113 - input rate changed to %d\n",
980 rate); */
981 qtet_akm_set_rate_val(ice->akm, rate);
982 }
983}
984
985/*
986 * If clock slaved to SPDIF-IN, setting runtime rate
987 * to the detected external rate
988 */
989static void qtet_spdif_in_open(struct snd_ice1712 *ice,
990 struct snd_pcm_substream *substream)
991{
992 struct qtet_spec *spec = ice->spec;
993 struct snd_pcm_runtime *runtime = substream->runtime;
994 int rate;
995
996 if (qtet_get_spdif_master_type(ice) != EXT_SPDIF_TYPE)
997 /* not external SPDIF, no rate limitation */
998 return;
999 /* only external SPDIF can detect incoming sample rate */
1000 rate = snd_ak4113_external_rate(spec->ak4113);
1001 if (rate >= runtime->hw.rate_min && rate <= runtime->hw.rate_max) {
1002 runtime->hw.rate_min = rate;
1003 runtime->hw.rate_max = rate;
1004 }
1005}
1006
1007/*
1008 * initialize the chip
1009 */
1010static int __devinit qtet_init(struct snd_ice1712 *ice)
1011{
1012 static const unsigned char ak4113_init_vals[] = {
1013 /* AK4113_REG_PWRDN */ AK4113_RST | AK4113_PWN |
1014 AK4113_OCKS0 | AK4113_OCKS1,
1015 /* AK4113_REQ_FORMAT */ AK4113_DIF_I24I2S | AK4113_VTX |
1016 AK4113_DEM_OFF | AK4113_DEAU,
1017 /* AK4113_REG_IO0 */ AK4113_OPS2 | AK4113_TXE |
1018 AK4113_XTL_24_576M,
1019 /* AK4113_REG_IO1 */ AK4113_EFH_1024LRCLK | AK4113_IPS(0),
1020 /* AK4113_REG_INT0_MASK */ 0,
1021 /* AK4113_REG_INT1_MASK */ 0,
1022 /* AK4113_REG_DATDTS */ 0,
1023 };
1024 int err;
1025 struct qtet_spec *spec;
1026 struct snd_akm4xxx *ak;
1027 unsigned char val;
1028
1029 /* switching ice1724 to external clock - supplied by ext. circuits */
1030 val = inb(ICEMT1724(ice, RATE));
1031 outb(val | VT1724_SPDIF_MASTER, ICEMT1724(ice, RATE));
1032
1033 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1034 if (!spec)
1035 return -ENOMEM;
1036 /* qtet is clocked by Xilinx array */
1037 ice->hw_rates = &qtet_rates_info;
1038 ice->is_spdif_master = qtet_is_spdif_master;
1039 ice->get_rate = qtet_get_rate;
1040 ice->set_rate = qtet_set_rate;
1041 ice->set_mclk = qtet_set_mclk;
1042 ice->set_spdif_clock = qtet_set_spdif_clock;
1043 ice->get_spdif_master_type = qtet_get_spdif_master_type;
1044 ice->ext_clock_names = ext_clock_names;
1045 ice->ext_clock_count = ARRAY_SIZE(ext_clock_names);
1046 /* since Qtet can detect correct SPDIF-in rate, all streams can be
1047 * limited to this specific rate */
1048 ice->spdif.ops.open = ice->pro_open = qtet_spdif_in_open;
1049 ice->spec = spec;
1050
1051 /* Mute Off */
1052 /* SCR Initialize*/
1053 /* keep codec power down first */
1054 set_scr(ice, SCR_PHP);
1055 udelay(1);
1056 /* codec power up */
1057 set_scr(ice, SCR_PHP | SCR_CODEC_PDN);
1058
1059 /* MCR Initialize */
1060 set_mcr(ice, 0);
1061
1062 /* CPLD Initialize */
1063 set_cpld(ice, 0);
1064
1065
1066 ice->num_total_dacs = 2;
1067 ice->num_total_adcs = 2;
1068
1069 ice->akm = kcalloc(2, sizeof(struct snd_akm4xxx), GFP_KERNEL);
1070 ak = ice->akm;
1071 if (!ak)
1072 return -ENOMEM;
1073 /* only one codec with two chips */
1074 ice->akm_codecs = 1;
1075 err = snd_ice1712_akm4xxx_init(ak, &akm_qtet_dac, NULL, ice);
1076 if (err < 0)
1077 return err;
1078 err = snd_ak4113_create(ice->card,
1079 qtet_ak4113_read,
1080 qtet_ak4113_write,
1081 ak4113_init_vals,
1082 ice, &spec->ak4113);
1083 if (err < 0)
1084 return err;
1085 /* callback for codecs rate setting */
1086 spec->ak4113->change_callback = qtet_ak4113_change;
1087 spec->ak4113->change_callback_private = ice;
1088 /* AK41143 in Quartet can detect external rate correctly
1089 * (i.e. check_flags = 0) */
1090 spec->ak4113->check_flags = 0;
1091
1092 proc_init(ice);
1093
1094 qtet_set_rate(ice, 44100);
1095 return 0;
1096}
1097
1098static unsigned char qtet_eeprom[] __devinitdata = {
1099 [ICE_EEP2_SYSCONF] = 0x28, /* clock 256(24MHz), mpu401, 1xADC,
1100 1xDACs, SPDIF in */
1101 [ICE_EEP2_ACLINK] = 0x80, /* I2S */
1102 [ICE_EEP2_I2S] = 0x78, /* 96k, 24bit, 192k */
1103 [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, in, out-ext */
1104 [ICE_EEP2_GPIO_DIR] = 0x00, /* 0-7 inputs, switched to output
1105 only during output operations */
1106 [ICE_EEP2_GPIO_DIR1] = 0xff, /* 8-15 outputs */
1107 [ICE_EEP2_GPIO_DIR2] = 0x00,
1108 [ICE_EEP2_GPIO_MASK] = 0xff, /* changed only for OUT operations */
1109 [ICE_EEP2_GPIO_MASK1] = 0x00,
1110 [ICE_EEP2_GPIO_MASK2] = 0xff,
1111
1112 [ICE_EEP2_GPIO_STATE] = 0x00, /* inputs */
1113 [ICE_EEP2_GPIO_STATE1] = 0x7d, /* all 1, but GPIO_CPLD_RW
1114 and GPIO15 always zero */
1115 [ICE_EEP2_GPIO_STATE2] = 0x00, /* inputs */
1116};
1117
1118/* entry point */
1119struct snd_ice1712_card_info snd_vt1724_qtet_cards[] __devinitdata = {
1120 {
1121 .subvendor = VT1724_SUBDEVICE_QTET,
1122 .name = "Infrasonic Quartet",
1123 .model = "quartet",
1124 .chip_init = qtet_init,
1125 .build_controls = qtet_add_controls,
1126 .eeprom_size = sizeof(qtet_eeprom),
1127 .eeprom_data = qtet_eeprom,
1128 },
1129 { } /* terminator */
1130};
diff --git a/sound/pci/ice1712/quartet.h b/sound/pci/ice1712/quartet.h
new file mode 100644
index 000000000000..80809b72439a
--- /dev/null
+++ b/sound/pci/ice1712/quartet.h
@@ -0,0 +1,10 @@
1#ifndef __SOUND_QTET_H
2#define __SOUND_QTET_H
3
4#define QTET_DEVICE_DESC "{Infrasonic,Quartet},"
5
6#define VT1724_SUBDEVICE_QTET 0x30305349 /* Infrasonic Quartet */
7
8extern struct snd_ice1712_card_info snd_vt1724_qtet_cards[];
9
10#endif /* __SOUND_QTET_H */
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/intel8x0.c b/sound/pci/intel8x0.c
index aac20fb4aad2..6433e65c9507 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -420,7 +420,7 @@ struct intel8x0 {
420 u32 int_sta_mask; /* interrupt status mask */ 420 u32 int_sta_mask; /* interrupt status mask */
421}; 421};
422 422
423static struct pci_device_id snd_intel8x0_ids[] = { 423static DEFINE_PCI_DEVICE_TABLE(snd_intel8x0_ids) = {
424 { PCI_VDEVICE(INTEL, 0x2415), DEVICE_INTEL }, /* 82801AA */ 424 { PCI_VDEVICE(INTEL, 0x2415), DEVICE_INTEL }, /* 82801AA */
425 { PCI_VDEVICE(INTEL, 0x2425), DEVICE_INTEL }, /* 82901AB */ 425 { PCI_VDEVICE(INTEL, 0x2425), DEVICE_INTEL }, /* 82901AB */
426 { PCI_VDEVICE(INTEL, 0x2445), DEVICE_INTEL }, /* 82801BA */ 426 { PCI_VDEVICE(INTEL, 0x2445), DEVICE_INTEL }, /* 82801BA */
@@ -2063,6 +2063,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
2063 .type = AC97_TUNE_HP_ONLY 2063 .type = AC97_TUNE_HP_ONLY
2064 }, 2064 },
2065 { 2065 {
2066 .subvendor = 0x161f,
2067 .subdevice = 0x203a,
2068 .name = "Gateway 4525GZ", /* AD1981B */
2069 .type = AC97_TUNE_INV_EAPD
2070 },
2071 {
2066 .subvendor = 0x1734, 2072 .subvendor = 0x1734,
2067 .subdevice = 0x0088, 2073 .subdevice = 0x0088,
2068 .name = "Fujitsu-Siemens D1522", /* AD1981 */ 2074 .name = "Fujitsu-Siemens D1522", /* AD1981 */
diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c
index 9e7d12e7673f..13cec1e5ced9 100644
--- a/sound/pci/intel8x0m.c
+++ b/sound/pci/intel8x0m.c
@@ -219,7 +219,7 @@ struct intel8x0m {
219 unsigned int pcm_pos_shift; 219 unsigned int pcm_pos_shift;
220}; 220};
221 221
222static struct pci_device_id snd_intel8x0m_ids[] = { 222static DEFINE_PCI_DEVICE_TABLE(snd_intel8x0m_ids) = {
223 { PCI_VDEVICE(INTEL, 0x2416), DEVICE_INTEL }, /* 82801AA */ 223 { PCI_VDEVICE(INTEL, 0x2416), DEVICE_INTEL }, /* 82801AA */
224 { PCI_VDEVICE(INTEL, 0x2426), DEVICE_INTEL }, /* 82901AB */ 224 { PCI_VDEVICE(INTEL, 0x2426), DEVICE_INTEL }, /* 82901AB */
225 { PCI_VDEVICE(INTEL, 0x2446), DEVICE_INTEL }, /* 82801BA */ 225 { PCI_VDEVICE(INTEL, 0x2446), DEVICE_INTEL }, /* 82801BA */
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c
index 7cc38a11e997..6d795700be79 100644
--- a/sound/pci/korg1212/korg1212.c
+++ b/sound/pci/korg1212/korg1212.c
@@ -418,7 +418,7 @@ module_param_array(enable, bool, NULL, 0444);
418MODULE_PARM_DESC(enable, "Enable Korg 1212 soundcard."); 418MODULE_PARM_DESC(enable, "Enable Korg 1212 soundcard.");
419MODULE_AUTHOR("Haroldo Gamal <gamal@alternex.com.br>"); 419MODULE_AUTHOR("Haroldo Gamal <gamal@alternex.com.br>");
420 420
421static struct pci_device_id snd_korg1212_ids[] = { 421static DEFINE_PCI_DEVICE_TABLE(snd_korg1212_ids) = {
422 { 422 {
423 .vendor = 0x10b5, 423 .vendor = 0x10b5,
424 .device = 0x906d, 424 .device = 0x906d,
diff --git a/sound/pci/lx6464es/lx6464es.c b/sound/pci/lx6464es/lx6464es.c
index 11b8c6514b3d..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>
@@ -55,7 +56,7 @@ static const char card_name[] = "LX6464ES";
55 56
56#define PCI_DEVICE_ID_PLX_LX6464ES PCI_DEVICE_ID_PLX_9056 57#define PCI_DEVICE_ID_PLX_LX6464ES PCI_DEVICE_ID_PLX_9056
57 58
58static struct pci_device_id snd_lx6464es_ids[] = { 59static DEFINE_PCI_DEVICE_TABLE(snd_lx6464es_ids) = {
59 { PCI_DEVICE(PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_LX6464ES), 60 { PCI_DEVICE(PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_LX6464ES),
60 .subvendor = PCI_VENDOR_ID_DIGIGRAM, 61 .subvendor = PCI_VENDOR_ID_DIGIGRAM,
61 .subdevice = PCI_SUBDEVICE_ID_DIGIGRAM_LX6464ES_SERIAL_SUBSYSTEM 62 .subdevice = PCI_SUBDEVICE_ID_DIGIGRAM_LX6464ES_SERIAL_SUBSYSTEM
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index 75283fbb4b3f..b56e33676780 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -849,6 +849,7 @@ struct snd_m3 {
849 struct snd_kcontrol *master_switch; 849 struct snd_kcontrol *master_switch;
850 struct snd_kcontrol *master_volume; 850 struct snd_kcontrol *master_volume;
851 struct tasklet_struct hwvol_tq; 851 struct tasklet_struct hwvol_tq;
852 unsigned int in_suspend;
852 853
853#ifdef CONFIG_PM 854#ifdef CONFIG_PM
854 u16 *suspend_mem; 855 u16 *suspend_mem;
@@ -861,7 +862,7 @@ struct snd_m3 {
861/* 862/*
862 * pci ids 863 * pci ids
863 */ 864 */
864static struct pci_device_id snd_m3_ids[] = { 865static DEFINE_PCI_DEVICE_TABLE(snd_m3_ids) = {
865 {PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ALLEGRO_1, PCI_ANY_ID, PCI_ANY_ID, 866 {PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ALLEGRO_1, PCI_ANY_ID, PCI_ANY_ID,
866 PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0}, 867 PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0},
867 {PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ALLEGRO, PCI_ANY_ID, PCI_ANY_ID, 868 {PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ALLEGRO, PCI_ANY_ID, PCI_ANY_ID,
@@ -884,6 +885,7 @@ static struct pci_device_id snd_m3_ids[] = {
884MODULE_DEVICE_TABLE(pci, snd_m3_ids); 885MODULE_DEVICE_TABLE(pci, snd_m3_ids);
885 886
886static struct snd_pci_quirk m3_amp_quirk_list[] __devinitdata = { 887static struct snd_pci_quirk m3_amp_quirk_list[] __devinitdata = {
888 SND_PCI_QUIRK(0x0E11, 0x0094, "Compaq Evo N600c", 0x0c),
887 SND_PCI_QUIRK(0x10f7, 0x833e, "Panasonic CF-28", 0x0d), 889 SND_PCI_QUIRK(0x10f7, 0x833e, "Panasonic CF-28", 0x0d),
888 SND_PCI_QUIRK(0x10f7, 0x833d, "Panasonic CF-72", 0x0d), 890 SND_PCI_QUIRK(0x10f7, 0x833d, "Panasonic CF-72", 0x0d),
889 SND_PCI_QUIRK(0x1033, 0x80f1, "NEC LM800J/7", 0x03), 891 SND_PCI_QUIRK(0x1033, 0x80f1, "NEC LM800J/7", 0x03),
@@ -1613,6 +1615,11 @@ static void snd_m3_update_hw_volume(unsigned long private_data)
1613 outb(0x88, chip->iobase + SHADOW_MIX_REG_MASTER); 1615 outb(0x88, chip->iobase + SHADOW_MIX_REG_MASTER);
1614 outb(0x88, chip->iobase + HW_VOL_COUNTER_MASTER); 1616 outb(0x88, chip->iobase + HW_VOL_COUNTER_MASTER);
1615 1617
1618 /* Ignore spurious HV interrupts during suspend / resume, this avoids
1619 mistaking them for a mute button press. */
1620 if (chip->in_suspend)
1621 return;
1622
1616 if (!chip->master_switch || !chip->master_volume) 1623 if (!chip->master_switch || !chip->master_volume)
1617 return; 1624 return;
1618 1625
@@ -2424,6 +2431,7 @@ static int m3_suspend(struct pci_dev *pci, pm_message_t state)
2424 if (chip->suspend_mem == NULL) 2431 if (chip->suspend_mem == NULL)
2425 return 0; 2432 return 0;
2426 2433
2434 chip->in_suspend = 1;
2427 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); 2435 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
2428 snd_pcm_suspend_all(chip->pcm); 2436 snd_pcm_suspend_all(chip->pcm);
2429 snd_ac97_suspend(chip->ac97); 2437 snd_ac97_suspend(chip->ac97);
@@ -2497,6 +2505,7 @@ static int m3_resume(struct pci_dev *pci)
2497 snd_m3_hv_init(chip); 2505 snd_m3_hv_init(chip);
2498 2506
2499 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 2507 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
2508 chip->in_suspend = 0;
2500 return 0; 2509 return 0;
2501} 2510}
2502#endif /* CONFIG_PM */ 2511#endif /* CONFIG_PM */
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c
index a83d1968a845..3be8f97c8bc0 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>
@@ -60,7 +61,7 @@ MODULE_PARM_DESC(enable, "Enable Digigram " CARD_NAME " soundcard.");
60/* 61/*
61 */ 62 */
62 63
63static struct pci_device_id snd_mixart_ids[] = { 64static DEFINE_PCI_DEVICE_TABLE(snd_mixart_ids) = {
64 { PCI_VDEVICE(MOTOROLA, 0x0003), 0, }, /* MC8240 */ 65 { PCI_VDEVICE(MOTOROLA, 0x0003), 0, }, /* MC8240 */
65 { 0, } 66 { 0, }
66}; 67};
@@ -1161,13 +1162,15 @@ static long snd_mixart_BA0_read(struct snd_info_entry *entry, void *file_private
1161 unsigned long count, unsigned long pos) 1162 unsigned long count, unsigned long pos)
1162{ 1163{
1163 struct mixart_mgr *mgr = entry->private_data; 1164 struct mixart_mgr *mgr = entry->private_data;
1165 unsigned long maxsize;
1164 1166
1165 count = count & ~3; /* make sure the read size is a multiple of 4 bytes */ 1167 if (pos >= MIXART_BA0_SIZE)
1166 if(count <= 0)
1167 return 0; 1168 return 0;
1168 if(pos + count > MIXART_BA0_SIZE) 1169 maxsize = MIXART_BA0_SIZE - pos;
1169 count = (long)(MIXART_BA0_SIZE - pos); 1170 if (count > maxsize)
1170 if(copy_to_user_fromio(buf, MIXART_MEM( mgr, pos ), count)) 1171 count = maxsize;
1172 count = count & ~3; /* make sure the read size is a multiple of 4 bytes */
1173 if (copy_to_user_fromio(buf, MIXART_MEM(mgr, pos), count))
1171 return -EFAULT; 1174 return -EFAULT;
1172 return count; 1175 return count;
1173} 1176}
@@ -1180,13 +1183,15 @@ static long snd_mixart_BA1_read(struct snd_info_entry *entry, void *file_private
1180 unsigned long count, unsigned long pos) 1183 unsigned long count, unsigned long pos)
1181{ 1184{
1182 struct mixart_mgr *mgr = entry->private_data; 1185 struct mixart_mgr *mgr = entry->private_data;
1186 unsigned long maxsize;
1183 1187
1184 count = count & ~3; /* make sure the read size is a multiple of 4 bytes */ 1188 if (pos > MIXART_BA1_SIZE)
1185 if(count <= 0)
1186 return 0; 1189 return 0;
1187 if(pos + count > MIXART_BA1_SIZE) 1190 maxsize = MIXART_BA1_SIZE - pos;
1188 count = (long)(MIXART_BA1_SIZE - pos); 1191 if (count > maxsize)
1189 if(copy_to_user_fromio(buf, MIXART_REG( mgr, pos ), count)) 1192 count = maxsize;
1193 count = count & ~3; /* make sure the read size is a multiple of 4 bytes */
1194 if (copy_to_user_fromio(buf, MIXART_REG(mgr, pos), count))
1190 return -EFAULT; 1195 return -EFAULT;
1191 return count; 1196 return count;
1192} 1197}
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/nm256/nm256.c b/sound/pci/nm256/nm256.c
index 97a0731331a1..5a60492ac7b3 100644
--- a/sound/pci/nm256/nm256.c
+++ b/sound/pci/nm256/nm256.c
@@ -262,7 +262,7 @@ struct nm256 {
262/* 262/*
263 * PCI ids 263 * PCI ids
264 */ 264 */
265static struct pci_device_id snd_nm256_ids[] = { 265static DEFINE_PCI_DEVICE_TABLE(snd_nm256_ids) = {
266 {PCI_VDEVICE(NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO), 0}, 266 {PCI_VDEVICE(NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO), 0},
267 {PCI_VDEVICE(NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO), 0}, 267 {PCI_VDEVICE(NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO), 0},
268 {PCI_VDEVICE(NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256XL_PLUS_AUDIO), 0}, 268 {PCI_VDEVICE(NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256XL_PLUS_AUDIO), 0},
diff --git a/sound/pci/oxygen/Makefile b/sound/pci/oxygen/Makefile
index 4ba07d42fd1d..acd8f15f7bff 100644
--- a/sound/pci/oxygen/Makefile
+++ b/sound/pci/oxygen/Makefile
@@ -1,7 +1,8 @@
1snd-oxygen-lib-objs := oxygen_io.o oxygen_lib.o oxygen_mixer.o oxygen_pcm.o 1snd-oxygen-lib-objs := oxygen_io.o oxygen_lib.o oxygen_mixer.o oxygen_pcm.o
2snd-hifier-objs := hifier.o 2snd-hifier-objs := hifier.o
3snd-oxygen-objs := oxygen.o 3snd-oxygen-objs := oxygen.o
4snd-virtuoso-objs := virtuoso.o 4snd-virtuoso-objs := virtuoso.o xonar_lib.o \
5 xonar_pcm179x.o xonar_cs43xx.o xonar_wm87x6.o xonar_hdmi.o
5 6
6obj-$(CONFIG_SND_OXYGEN_LIB) += snd-oxygen-lib.o 7obj-$(CONFIG_SND_OXYGEN_LIB) += snd-oxygen-lib.o
7obj-$(CONFIG_SND_HIFIER) += snd-hifier.o 8obj-$(CONFIG_SND_HIFIER) += snd-hifier.o
diff --git a/sound/pci/oxygen/cs2000.h b/sound/pci/oxygen/cs2000.h
new file mode 100644
index 000000000000..c3501bdb5edc
--- /dev/null
+++ b/sound/pci/oxygen/cs2000.h
@@ -0,0 +1,83 @@
1#ifndef CS2000_H_INCLUDED
2#define CS2000_H_INCLUDED
3
4#define CS2000_DEV_ID 0x01
5#define CS2000_DEV_CTRL 0x02
6#define CS2000_DEV_CFG_1 0x03
7#define CS2000_DEV_CFG_2 0x04
8#define CS2000_GLOBAL_CFG 0x05
9#define CS2000_RATIO_0 0x06 /* 32 bits, big endian */
10#define CS2000_RATIO_1 0x0a
11#define CS2000_RATIO_2 0x0e
12#define CS2000_RATIO_3 0x12
13#define CS2000_FUN_CFG_1 0x16
14#define CS2000_FUN_CFG_2 0x17
15#define CS2000_FUN_CFG_3 0x1e
16
17/* DEV_ID */
18#define CS2000_DEVICE_MASK 0xf8
19#define CS2000_REVISION_MASK 0x07
20
21/* DEV_CTRL */
22#define CS2000_UNLOCK 0x80
23#define CS2000_AUX_OUT_DIS 0x02
24#define CS2000_CLK_OUT_DIS 0x01
25
26/* DEV_CFG_1 */
27#define CS2000_R_MOD_SEL_MASK 0xe0
28#define CS2000_R_MOD_SEL_1 0x00
29#define CS2000_R_MOD_SEL_2 0x20
30#define CS2000_R_MOD_SEL_4 0x40
31#define CS2000_R_MOD_SEL_8 0x60
32#define CS2000_R_MOD_SEL_1_2 0x80
33#define CS2000_R_MOD_SEL_1_4 0xa0
34#define CS2000_R_MOD_SEL_1_8 0xc0
35#define CS2000_R_MOD_SEL_1_16 0xe0
36#define CS2000_R_SEL_MASK 0x18
37#define CS2000_R_SEL_SHIFT 3
38#define CS2000_AUX_OUT_SRC_MASK 0x06
39#define CS2000_AUX_OUT_SRC_REF_CLK 0x00
40#define CS2000_AUX_OUT_SRC_CLK_IN 0x02
41#define CS2000_AUX_OUT_SRC_CLK_OUT 0x04
42#define CS2000_AUX_OUT_SRC_PLL_LOCK 0x06
43#define CS2000_EN_DEV_CFG_1 0x01
44
45/* DEV_CFG_2 */
46#define CS2000_LOCK_CLK_MASK 0x06
47#define CS2000_LOCK_CLK_SHIFT 1
48#define CS2000_FRAC_N_SRC_MASK 0x01
49#define CS2000_FRAC_N_SRC_STATIC 0x00
50#define CS2000_FRAC_N_SRC_DYNAMIC 0x01
51
52/* GLOBAL_CFG */
53#define CS2000_FREEZE 0x08
54#define CS2000_EN_DEV_CFG_2 0x01
55
56/* FUN_CFG_1 */
57#define CS2000_CLK_SKIP_EN 0x80
58#define CS2000_AUX_LOCK_CFG_MASK 0x40
59#define CS2000_AUX_LOCK_CFG_PP_HIGH 0x00
60#define CS2000_AUX_LOCK_CFG_OD_LOW 0x40
61#define CS2000_REF_CLK_DIV_MASK 0x18
62#define CS2000_REF_CLK_DIV_4 0x00
63#define CS2000_REF_CLK_DIV_2 0x08
64#define CS2000_REF_CLK_DIV_1 0x10
65
66/* FUN_CFG_2 */
67#define CS2000_CLK_OUT_UNL 0x10
68#define CS2000_L_F_RATIO_CFG_MASK 0x08
69#define CS2000_L_F_RATIO_CFG_20_12 0x00
70#define CS2000_L_F_RATIO_CFG_12_20 0x08
71
72/* FUN_CFG_3 */
73#define CS2000_CLK_IN_BW_MASK 0x70
74#define CS2000_CLK_IN_BW_1 0x00
75#define CS2000_CLK_IN_BW_2 0x10
76#define CS2000_CLK_IN_BW_4 0x20
77#define CS2000_CLK_IN_BW_8 0x30
78#define CS2000_CLK_IN_BW_16 0x40
79#define CS2000_CLK_IN_BW_32 0x50
80#define CS2000_CLK_IN_BW_64 0x60
81#define CS2000_CLK_IN_BW_128 0x70
82
83#endif
diff --git a/sound/pci/oxygen/hifier.c b/sound/pci/oxygen/hifier.c
index 84ef13183419..5a87d683691f 100644
--- a/sound/pci/oxygen/hifier.c
+++ b/sound/pci/oxygen/hifier.c
@@ -17,6 +17,12 @@
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */ 18 */
19 19
20/*
21 * CMI8788:
22 *
23 * SPI 0 -> AK4396
24 */
25
20#include <linux/delay.h> 26#include <linux/delay.h>
21#include <linux/pci.h> 27#include <linux/pci.h>
22#include <sound/control.h> 28#include <sound/control.h>
@@ -42,7 +48,7 @@ MODULE_PARM_DESC(id, "ID string");
42module_param_array(enable, bool, NULL, 0444); 48module_param_array(enable, bool, NULL, 0444);
43MODULE_PARM_DESC(enable, "enable card"); 49MODULE_PARM_DESC(enable, "enable card");
44 50
45static struct pci_device_id hifier_ids[] __devinitdata = { 51static DEFINE_PCI_DEVICE_TABLE(hifier_ids) = {
46 { OXYGEN_PCI_SUBID(0x14c3, 0x1710) }, 52 { OXYGEN_PCI_SUBID(0x14c3, 0x1710) },
47 { OXYGEN_PCI_SUBID(0x14c3, 0x1711) }, 53 { OXYGEN_PCI_SUBID(0x14c3, 0x1711) },
48 { OXYGEN_PCI_SUBID_BROKEN_EEPROM }, 54 { OXYGEN_PCI_SUBID_BROKEN_EEPROM },
@@ -51,23 +57,28 @@ static struct pci_device_id hifier_ids[] __devinitdata = {
51MODULE_DEVICE_TABLE(pci, hifier_ids); 57MODULE_DEVICE_TABLE(pci, hifier_ids);
52 58
53struct hifier_data { 59struct hifier_data {
54 u8 ak4396_ctl2; 60 u8 ak4396_regs[5];
55}; 61};
56 62
57static void ak4396_write(struct oxygen *chip, u8 reg, u8 value) 63static void ak4396_write(struct oxygen *chip, u8 reg, u8 value)
58{ 64{
65 struct hifier_data *data = chip->model_data;
66
59 oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER | 67 oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
60 OXYGEN_SPI_DATA_LENGTH_2 | 68 OXYGEN_SPI_DATA_LENGTH_2 |
61 OXYGEN_SPI_CLOCK_160 | 69 OXYGEN_SPI_CLOCK_160 |
62 (0 << OXYGEN_SPI_CODEC_SHIFT) | 70 (0 << OXYGEN_SPI_CODEC_SHIFT) |
63 OXYGEN_SPI_CEN_LATCH_CLOCK_HI, 71 OXYGEN_SPI_CEN_LATCH_CLOCK_HI,
64 AK4396_WRITE | (reg << 8) | value); 72 AK4396_WRITE | (reg << 8) | value);
73 data->ak4396_regs[reg] = value;
65} 74}
66 75
67static void update_ak4396_volume(struct oxygen *chip) 76static void ak4396_write_cached(struct oxygen *chip, u8 reg, u8 value)
68{ 77{
69 ak4396_write(chip, AK4396_LCH_ATT, chip->dac_volume[0]); 78 struct hifier_data *data = chip->model_data;
70 ak4396_write(chip, AK4396_RCH_ATT, chip->dac_volume[1]); 79
80 if (value != data->ak4396_regs[reg])
81 ak4396_write(chip, reg, value);
71} 82}
72 83
73static void hifier_registers_init(struct oxygen *chip) 84static void hifier_registers_init(struct oxygen *chip)
@@ -75,16 +86,19 @@ static void hifier_registers_init(struct oxygen *chip)
75 struct hifier_data *data = chip->model_data; 86 struct hifier_data *data = chip->model_data;
76 87
77 ak4396_write(chip, AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN); 88 ak4396_write(chip, AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN);
78 ak4396_write(chip, AK4396_CONTROL_2, data->ak4396_ctl2); 89 ak4396_write(chip, AK4396_CONTROL_2,
90 data->ak4396_regs[AK4396_CONTROL_2]);
79 ak4396_write(chip, AK4396_CONTROL_3, AK4396_PCM); 91 ak4396_write(chip, AK4396_CONTROL_3, AK4396_PCM);
80 update_ak4396_volume(chip); 92 ak4396_write(chip, AK4396_LCH_ATT, chip->dac_volume[0]);
93 ak4396_write(chip, AK4396_RCH_ATT, chip->dac_volume[1]);
81} 94}
82 95
83static void hifier_init(struct oxygen *chip) 96static void hifier_init(struct oxygen *chip)
84{ 97{
85 struct hifier_data *data = chip->model_data; 98 struct hifier_data *data = chip->model_data;
86 99
87 data->ak4396_ctl2 = AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL; 100 data->ak4396_regs[AK4396_CONTROL_2] =
101 AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL;
88 hifier_registers_init(chip); 102 hifier_registers_init(chip);
89 103
90 snd_component_add(chip->card, "AK4396"); 104 snd_component_add(chip->card, "AK4396");
@@ -106,20 +120,29 @@ static void set_ak4396_params(struct oxygen *chip,
106 struct hifier_data *data = chip->model_data; 120 struct hifier_data *data = chip->model_data;
107 u8 value; 121 u8 value;
108 122
109 value = data->ak4396_ctl2 & ~AK4396_DFS_MASK; 123 value = data->ak4396_regs[AK4396_CONTROL_2] & ~AK4396_DFS_MASK;
110 if (params_rate(params) <= 54000) 124 if (params_rate(params) <= 54000)
111 value |= AK4396_DFS_NORMAL; 125 value |= AK4396_DFS_NORMAL;
112 else if (params_rate(params) <= 108000) 126 else if (params_rate(params) <= 108000)
113 value |= AK4396_DFS_DOUBLE; 127 value |= AK4396_DFS_DOUBLE;
114 else 128 else
115 value |= AK4396_DFS_QUAD; 129 value |= AK4396_DFS_QUAD;
116 data->ak4396_ctl2 = value;
117 130
118 msleep(1); /* wait for the new MCLK to become stable */ 131 msleep(1); /* wait for the new MCLK to become stable */
119 132
120 ak4396_write(chip, AK4396_CONTROL_1, AK4396_DIF_24_MSB); 133 if (value != data->ak4396_regs[AK4396_CONTROL_2]) {
121 ak4396_write(chip, AK4396_CONTROL_2, value); 134 ak4396_write(chip, AK4396_CONTROL_1,
122 ak4396_write(chip, AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN); 135 AK4396_DIF_24_MSB);
136 ak4396_write(chip, AK4396_CONTROL_2, value);
137 ak4396_write(chip, AK4396_CONTROL_1,
138 AK4396_DIF_24_MSB | AK4396_RSTN);
139 }
140}
141
142static void update_ak4396_volume(struct oxygen *chip)
143{
144 ak4396_write_cached(chip, AK4396_LCH_ATT, chip->dac_volume[0]);
145 ak4396_write_cached(chip, AK4396_RCH_ATT, chip->dac_volume[1]);
123} 146}
124 147
125static void update_ak4396_mute(struct oxygen *chip) 148static void update_ak4396_mute(struct oxygen *chip)
@@ -127,11 +150,10 @@ static void update_ak4396_mute(struct oxygen *chip)
127 struct hifier_data *data = chip->model_data; 150 struct hifier_data *data = chip->model_data;
128 u8 value; 151 u8 value;
129 152
130 value = data->ak4396_ctl2 & ~AK4396_SMUTE; 153 value = data->ak4396_regs[AK4396_CONTROL_2] & ~AK4396_SMUTE;
131 if (chip->dac_mute) 154 if (chip->dac_mute)
132 value |= AK4396_SMUTE; 155 value |= AK4396_SMUTE;
133 data->ak4396_ctl2 = value; 156 ak4396_write_cached(chip, AK4396_CONTROL_2, value);
134 ak4396_write(chip, AK4396_CONTROL_2, value);
135} 157}
136 158
137static void set_cs5340_params(struct oxygen *chip, 159static void set_cs5340_params(struct oxygen *chip,
@@ -141,21 +163,14 @@ static void set_cs5340_params(struct oxygen *chip,
141 163
142static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0); 164static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0);
143 165
144static int hifier_control_filter(struct snd_kcontrol_new *template)
145{
146 if (!strcmp(template->name, "Stereo Upmixing"))
147 return 1; /* stereo only - we don't need upmixing */
148 return 0;
149}
150
151static const struct oxygen_model model_hifier = { 166static const struct oxygen_model model_hifier = {
152 .shortname = "C-Media CMI8787", 167 .shortname = "C-Media CMI8787",
153 .longname = "C-Media Oxygen HD Audio", 168 .longname = "C-Media Oxygen HD Audio",
154 .chip = "CMI8788", 169 .chip = "CMI8788",
155 .init = hifier_init, 170 .init = hifier_init,
156 .control_filter = hifier_control_filter,
157 .cleanup = hifier_cleanup, 171 .cleanup = hifier_cleanup,
158 .resume = hifier_resume, 172 .resume = hifier_resume,
173 .get_i2s_mclk = oxygen_default_i2s_mclk,
159 .set_dac_params = set_ak4396_params, 174 .set_dac_params = set_ak4396_params,
160 .set_adc_params = set_cs5340_params, 175 .set_adc_params = set_cs5340_params,
161 .update_dac_volume = update_ak4396_volume, 176 .update_dac_volume = update_ak4396_volume,
diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c
index 72db4c39007f..289cb4dacfc7 100644
--- a/sound/pci/oxygen/oxygen.c
+++ b/sound/pci/oxygen/oxygen.c
@@ -18,6 +18,8 @@
18 */ 18 */
19 19
20/* 20/*
21 * CMI8788:
22 *
21 * SPI 0 -> 1st AK4396 (front) 23 * SPI 0 -> 1st AK4396 (front)
22 * SPI 1 -> 2nd AK4396 (surround) 24 * SPI 1 -> 2nd AK4396 (surround)
23 * SPI 2 -> 3rd AK4396 (center/LFE) 25 * SPI 2 -> 3rd AK4396 (center/LFE)
@@ -27,6 +29,10 @@
27 * GPIO 0 -> DFS0 of AK5385 29 * GPIO 0 -> DFS0 of AK5385
28 * GPIO 1 -> DFS1 of AK5385 30 * GPIO 1 -> DFS1 of AK5385
29 * GPIO 8 -> enable headphone amplifier on HT-Omega models 31 * GPIO 8 -> enable headphone amplifier on HT-Omega models
32 *
33 * CM9780:
34 *
35 * GPO 0 -> route line-in (0) or AC97 output (1) to ADC input
30 */ 36 */
31 37
32#include <linux/delay.h> 38#include <linux/delay.h>
@@ -66,7 +72,7 @@ enum {
66 MODEL_CLARO_HALO, /* HT-Omega Claro halo */ 72 MODEL_CLARO_HALO, /* HT-Omega Claro halo */
67}; 73};
68 74
69static struct pci_device_id oxygen_ids[] __devinitdata = { 75static DEFINE_PCI_DEVICE_TABLE(oxygen_ids) = {
70 { OXYGEN_PCI_SUBID(0x10b0, 0x0216), .driver_data = MODEL_CMEDIA_REF }, 76 { OXYGEN_PCI_SUBID(0x10b0, 0x0216), .driver_data = MODEL_CMEDIA_REF },
71 { OXYGEN_PCI_SUBID(0x10b0, 0x0218), .driver_data = MODEL_CMEDIA_REF }, 77 { OXYGEN_PCI_SUBID(0x10b0, 0x0218), .driver_data = MODEL_CMEDIA_REF },
72 { OXYGEN_PCI_SUBID(0x10b0, 0x0219), .driver_data = MODEL_CMEDIA_REF }, 78 { OXYGEN_PCI_SUBID(0x10b0, 0x0219), .driver_data = MODEL_CMEDIA_REF },
@@ -91,8 +97,8 @@ MODULE_DEVICE_TABLE(pci, oxygen_ids);
91#define GPIO_CLARO_HP 0x0100 97#define GPIO_CLARO_HP 0x0100
92 98
93struct generic_data { 99struct generic_data {
94 u8 ak4396_ctl2; 100 u8 ak4396_regs[4][5];
95 u16 saved_wm8785_registers[2]; 101 u16 wm8785_regs[3];
96}; 102};
97 103
98static void ak4396_write(struct oxygen *chip, unsigned int codec, 104static void ak4396_write(struct oxygen *chip, unsigned int codec,
@@ -102,12 +108,24 @@ static void ak4396_write(struct oxygen *chip, unsigned int codec,
102 static const u8 codec_spi_map[4] = { 108 static const u8 codec_spi_map[4] = {
103 0, 1, 2, 4 109 0, 1, 2, 4
104 }; 110 };
111 struct generic_data *data = chip->model_data;
112
105 oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER | 113 oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
106 OXYGEN_SPI_DATA_LENGTH_2 | 114 OXYGEN_SPI_DATA_LENGTH_2 |
107 OXYGEN_SPI_CLOCK_160 | 115 OXYGEN_SPI_CLOCK_160 |
108 (codec_spi_map[codec] << OXYGEN_SPI_CODEC_SHIFT) | 116 (codec_spi_map[codec] << OXYGEN_SPI_CODEC_SHIFT) |
109 OXYGEN_SPI_CEN_LATCH_CLOCK_HI, 117 OXYGEN_SPI_CEN_LATCH_CLOCK_HI,
110 AK4396_WRITE | (reg << 8) | value); 118 AK4396_WRITE | (reg << 8) | value);
119 data->ak4396_regs[codec][reg] = value;
120}
121
122static void ak4396_write_cached(struct oxygen *chip, unsigned int codec,
123 u8 reg, u8 value)
124{
125 struct generic_data *data = chip->model_data;
126
127 if (value != data->ak4396_regs[codec][reg])
128 ak4396_write(chip, codec, reg, value);
111} 129}
112 130
113static void wm8785_write(struct oxygen *chip, u8 reg, unsigned int value) 131static void wm8785_write(struct oxygen *chip, u8 reg, unsigned int value)
@@ -120,20 +138,8 @@ static void wm8785_write(struct oxygen *chip, u8 reg, unsigned int value)
120 (3 << OXYGEN_SPI_CODEC_SHIFT) | 138 (3 << OXYGEN_SPI_CODEC_SHIFT) |
121 OXYGEN_SPI_CEN_LATCH_CLOCK_LO, 139 OXYGEN_SPI_CEN_LATCH_CLOCK_LO,
122 (reg << 9) | value); 140 (reg << 9) | value);
123 if (reg < ARRAY_SIZE(data->saved_wm8785_registers)) 141 if (reg < ARRAY_SIZE(data->wm8785_regs))
124 data->saved_wm8785_registers[reg] = value; 142 data->wm8785_regs[reg] = value;
125}
126
127static void update_ak4396_volume(struct oxygen *chip)
128{
129 unsigned int i;
130
131 for (i = 0; i < 4; ++i) {
132 ak4396_write(chip, i,
133 AK4396_LCH_ATT, chip->dac_volume[i * 2]);
134 ak4396_write(chip, i,
135 AK4396_RCH_ATT, chip->dac_volume[i * 2 + 1]);
136 }
137} 143}
138 144
139static void ak4396_registers_init(struct oxygen *chip) 145static void ak4396_registers_init(struct oxygen *chip)
@@ -142,21 +148,25 @@ static void ak4396_registers_init(struct oxygen *chip)
142 unsigned int i; 148 unsigned int i;
143 149
144 for (i = 0; i < 4; ++i) { 150 for (i = 0; i < 4; ++i) {
145 ak4396_write(chip, i, 151 ak4396_write(chip, i, AK4396_CONTROL_1,
146 AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN); 152 AK4396_DIF_24_MSB | AK4396_RSTN);
147 ak4396_write(chip, i, 153 ak4396_write(chip, i, AK4396_CONTROL_2,
148 AK4396_CONTROL_2, data->ak4396_ctl2); 154 data->ak4396_regs[0][AK4396_CONTROL_2]);
149 ak4396_write(chip, i, 155 ak4396_write(chip, i, AK4396_CONTROL_3,
150 AK4396_CONTROL_3, AK4396_PCM); 156 AK4396_PCM);
157 ak4396_write(chip, i, AK4396_LCH_ATT,
158 chip->dac_volume[i * 2]);
159 ak4396_write(chip, i, AK4396_RCH_ATT,
160 chip->dac_volume[i * 2 + 1]);
151 } 161 }
152 update_ak4396_volume(chip);
153} 162}
154 163
155static void ak4396_init(struct oxygen *chip) 164static void ak4396_init(struct oxygen *chip)
156{ 165{
157 struct generic_data *data = chip->model_data; 166 struct generic_data *data = chip->model_data;
158 167
159 data->ak4396_ctl2 = AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL; 168 data->ak4396_regs[0][AK4396_CONTROL_2] =
169 AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL;
160 ak4396_registers_init(chip); 170 ak4396_registers_init(chip);
161 snd_component_add(chip->card, "AK4396"); 171 snd_component_add(chip->card, "AK4396");
162} 172}
@@ -173,17 +183,17 @@ static void wm8785_registers_init(struct oxygen *chip)
173 struct generic_data *data = chip->model_data; 183 struct generic_data *data = chip->model_data;
174 184
175 wm8785_write(chip, WM8785_R7, 0); 185 wm8785_write(chip, WM8785_R7, 0);
176 wm8785_write(chip, WM8785_R0, data->saved_wm8785_registers[0]); 186 wm8785_write(chip, WM8785_R0, data->wm8785_regs[0]);
177 wm8785_write(chip, WM8785_R1, data->saved_wm8785_registers[1]); 187 wm8785_write(chip, WM8785_R2, data->wm8785_regs[2]);
178} 188}
179 189
180static void wm8785_init(struct oxygen *chip) 190static void wm8785_init(struct oxygen *chip)
181{ 191{
182 struct generic_data *data = chip->model_data; 192 struct generic_data *data = chip->model_data;
183 193
184 data->saved_wm8785_registers[0] = WM8785_MCR_SLAVE | 194 data->wm8785_regs[0] =
185 WM8785_OSR_SINGLE | WM8785_FORMAT_LJUST; 195 WM8785_MCR_SLAVE | WM8785_OSR_SINGLE | WM8785_FORMAT_LJUST;
186 data->saved_wm8785_registers[1] = WM8785_WL_24; 196 data->wm8785_regs[2] = WM8785_HPFR | WM8785_HPFL;
187 wm8785_registers_init(chip); 197 wm8785_registers_init(chip);
188 snd_component_add(chip->card, "WM8785"); 198 snd_component_add(chip->card, "WM8785");
189} 199}
@@ -264,24 +274,36 @@ static void set_ak4396_params(struct oxygen *chip,
264 unsigned int i; 274 unsigned int i;
265 u8 value; 275 u8 value;
266 276
267 value = data->ak4396_ctl2 & ~AK4396_DFS_MASK; 277 value = data->ak4396_regs[0][AK4396_CONTROL_2] & ~AK4396_DFS_MASK;
268 if (params_rate(params) <= 54000) 278 if (params_rate(params) <= 54000)
269 value |= AK4396_DFS_NORMAL; 279 value |= AK4396_DFS_NORMAL;
270 else if (params_rate(params) <= 108000) 280 else if (params_rate(params) <= 108000)
271 value |= AK4396_DFS_DOUBLE; 281 value |= AK4396_DFS_DOUBLE;
272 else 282 else
273 value |= AK4396_DFS_QUAD; 283 value |= AK4396_DFS_QUAD;
274 data->ak4396_ctl2 = value;
275 284
276 msleep(1); /* wait for the new MCLK to become stable */ 285 msleep(1); /* wait for the new MCLK to become stable */
277 286
287 if (value != data->ak4396_regs[0][AK4396_CONTROL_2]) {
288 for (i = 0; i < 4; ++i) {
289 ak4396_write(chip, i, AK4396_CONTROL_1,
290 AK4396_DIF_24_MSB);
291 ak4396_write(chip, i, AK4396_CONTROL_2, value);
292 ak4396_write(chip, i, AK4396_CONTROL_1,
293 AK4396_DIF_24_MSB | AK4396_RSTN);
294 }
295 }
296}
297
298static void update_ak4396_volume(struct oxygen *chip)
299{
300 unsigned int i;
301
278 for (i = 0; i < 4; ++i) { 302 for (i = 0; i < 4; ++i) {
279 ak4396_write(chip, i, 303 ak4396_write_cached(chip, i, AK4396_LCH_ATT,
280 AK4396_CONTROL_1, AK4396_DIF_24_MSB); 304 chip->dac_volume[i * 2]);
281 ak4396_write(chip, i, 305 ak4396_write_cached(chip, i, AK4396_RCH_ATT,
282 AK4396_CONTROL_2, value); 306 chip->dac_volume[i * 2 + 1]);
283 ak4396_write(chip, i,
284 AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN);
285 } 307 }
286} 308}
287 309
@@ -291,21 +313,19 @@ static void update_ak4396_mute(struct oxygen *chip)
291 unsigned int i; 313 unsigned int i;
292 u8 value; 314 u8 value;
293 315
294 value = data->ak4396_ctl2 & ~AK4396_SMUTE; 316 value = data->ak4396_regs[0][AK4396_CONTROL_2] & ~AK4396_SMUTE;
295 if (chip->dac_mute) 317 if (chip->dac_mute)
296 value |= AK4396_SMUTE; 318 value |= AK4396_SMUTE;
297 data->ak4396_ctl2 = value;
298 for (i = 0; i < 4; ++i) 319 for (i = 0; i < 4; ++i)
299 ak4396_write(chip, i, AK4396_CONTROL_2, value); 320 ak4396_write_cached(chip, i, AK4396_CONTROL_2, value);
300} 321}
301 322
302static void set_wm8785_params(struct oxygen *chip, 323static void set_wm8785_params(struct oxygen *chip,
303 struct snd_pcm_hw_params *params) 324 struct snd_pcm_hw_params *params)
304{ 325{
326 struct generic_data *data = chip->model_data;
305 unsigned int value; 327 unsigned int value;
306 328
307 wm8785_write(chip, WM8785_R7, 0);
308
309 value = WM8785_MCR_SLAVE | WM8785_FORMAT_LJUST; 329 value = WM8785_MCR_SLAVE | WM8785_FORMAT_LJUST;
310 if (params_rate(params) <= 48000) 330 if (params_rate(params) <= 48000)
311 value |= WM8785_OSR_SINGLE; 331 value |= WM8785_OSR_SINGLE;
@@ -313,13 +333,11 @@ static void set_wm8785_params(struct oxygen *chip,
313 value |= WM8785_OSR_DOUBLE; 333 value |= WM8785_OSR_DOUBLE;
314 else 334 else
315 value |= WM8785_OSR_QUAD; 335 value |= WM8785_OSR_QUAD;
316 wm8785_write(chip, WM8785_R0, value); 336 if (value != data->wm8785_regs[0]) {
317 337 wm8785_write(chip, WM8785_R7, 0);
318 if (snd_pcm_format_width(params_format(params)) <= 16) 338 wm8785_write(chip, WM8785_R0, value);
319 value = WM8785_WL_16; 339 wm8785_write(chip, WM8785_R2, data->wm8785_regs[2]);
320 else 340 }
321 value = WM8785_WL_24;
322 wm8785_write(chip, WM8785_R1, value);
323} 341}
324 342
325static void set_ak5385_params(struct oxygen *chip, 343static void set_ak5385_params(struct oxygen *chip,
@@ -337,6 +355,134 @@ static void set_ak5385_params(struct oxygen *chip,
337 value, GPIO_AK5385_DFS_MASK); 355 value, GPIO_AK5385_DFS_MASK);
338} 356}
339 357
358static int rolloff_info(struct snd_kcontrol *ctl,
359 struct snd_ctl_elem_info *info)
360{
361 static const char *const names[2] = {
362 "Sharp Roll-off", "Slow Roll-off"
363 };
364
365 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
366 info->count = 1;
367 info->value.enumerated.items = 2;
368 if (info->value.enumerated.item >= 2)
369 info->value.enumerated.item = 1;
370 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
371 return 0;
372}
373
374static int rolloff_get(struct snd_kcontrol *ctl,
375 struct snd_ctl_elem_value *value)
376{
377 struct oxygen *chip = ctl->private_data;
378 struct generic_data *data = chip->model_data;
379
380 value->value.enumerated.item[0] =
381 (data->ak4396_regs[0][AK4396_CONTROL_2] & AK4396_SLOW) != 0;
382 return 0;
383}
384
385static int rolloff_put(struct snd_kcontrol *ctl,
386 struct snd_ctl_elem_value *value)
387{
388 struct oxygen *chip = ctl->private_data;
389 struct generic_data *data = chip->model_data;
390 unsigned int i;
391 int changed;
392 u8 reg;
393
394 mutex_lock(&chip->mutex);
395 reg = data->ak4396_regs[0][AK4396_CONTROL_2];
396 if (value->value.enumerated.item[0])
397 reg |= AK4396_SLOW;
398 else
399 reg &= ~AK4396_SLOW;
400 changed = reg != data->ak4396_regs[0][AK4396_CONTROL_2];
401 if (changed) {
402 for (i = 0; i < 4; ++i)
403 ak4396_write(chip, i, AK4396_CONTROL_2, reg);
404 }
405 mutex_unlock(&chip->mutex);
406 return changed;
407}
408
409static const struct snd_kcontrol_new rolloff_control = {
410 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
411 .name = "DAC Filter Playback Enum",
412 .info = rolloff_info,
413 .get = rolloff_get,
414 .put = rolloff_put,
415};
416
417static int hpf_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info)
418{
419 static const char *const names[2] = {
420 "None", "High-pass Filter"
421 };
422
423 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
424 info->count = 1;
425 info->value.enumerated.items = 2;
426 if (info->value.enumerated.item >= 2)
427 info->value.enumerated.item = 1;
428 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
429 return 0;
430}
431
432static int hpf_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
433{
434 struct oxygen *chip = ctl->private_data;
435 struct generic_data *data = chip->model_data;
436
437 value->value.enumerated.item[0] =
438 (data->wm8785_regs[WM8785_R2] & WM8785_HPFR) != 0;
439 return 0;
440}
441
442static int hpf_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
443{
444 struct oxygen *chip = ctl->private_data;
445 struct generic_data *data = chip->model_data;
446 unsigned int reg;
447 int changed;
448
449 mutex_lock(&chip->mutex);
450 reg = data->wm8785_regs[WM8785_R2] & ~(WM8785_HPFR | WM8785_HPFL);
451 if (value->value.enumerated.item[0])
452 reg |= WM8785_HPFR | WM8785_HPFL;
453 changed = reg != data->wm8785_regs[WM8785_R2];
454 if (changed)
455 wm8785_write(chip, WM8785_R2, reg);
456 mutex_unlock(&chip->mutex);
457 return changed;
458}
459
460static const struct snd_kcontrol_new hpf_control = {
461 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
462 .name = "ADC Filter Capture Enum",
463 .info = hpf_info,
464 .get = hpf_get,
465 .put = hpf_put,
466};
467
468static int generic_mixer_init(struct oxygen *chip)
469{
470 return snd_ctl_add(chip->card, snd_ctl_new1(&rolloff_control, chip));
471}
472
473static int generic_wm8785_mixer_init(struct oxygen *chip)
474{
475 int err;
476
477 err = generic_mixer_init(chip);
478 if (err < 0)
479 return err;
480 err = snd_ctl_add(chip->card, snd_ctl_new1(&hpf_control, chip));
481 if (err < 0)
482 return err;
483 return 0;
484}
485
340static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0); 486static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0);
341 487
342static const struct oxygen_model model_generic = { 488static const struct oxygen_model model_generic = {
@@ -344,8 +490,10 @@ static const struct oxygen_model model_generic = {
344 .longname = "C-Media Oxygen HD Audio", 490 .longname = "C-Media Oxygen HD Audio",
345 .chip = "CMI8788", 491 .chip = "CMI8788",
346 .init = generic_init, 492 .init = generic_init,
493 .mixer_init = generic_wm8785_mixer_init,
347 .cleanup = generic_cleanup, 494 .cleanup = generic_cleanup,
348 .resume = generic_resume, 495 .resume = generic_resume,
496 .get_i2s_mclk = oxygen_default_i2s_mclk,
349 .set_dac_params = set_ak4396_params, 497 .set_dac_params = set_ak4396_params,
350 .set_adc_params = set_wm8785_params, 498 .set_adc_params = set_wm8785_params,
351 .update_dac_volume = update_ak4396_volume, 499 .update_dac_volume = update_ak4396_volume,
@@ -374,6 +522,7 @@ static int __devinit get_oxygen_model(struct oxygen *chip,
374 switch (id->driver_data) { 522 switch (id->driver_data) {
375 case MODEL_MERIDIAN: 523 case MODEL_MERIDIAN:
376 chip->model.init = meridian_init; 524 chip->model.init = meridian_init;
525 chip->model.mixer_init = generic_mixer_init;
377 chip->model.resume = meridian_resume; 526 chip->model.resume = meridian_resume;
378 chip->model.set_adc_params = set_ak5385_params; 527 chip->model.set_adc_params = set_ak5385_params;
379 chip->model.device_config = PLAYBACK_0_TO_I2S | 528 chip->model.device_config = PLAYBACK_0_TO_I2S |
@@ -389,6 +538,7 @@ static int __devinit get_oxygen_model(struct oxygen *chip,
389 break; 538 break;
390 case MODEL_CLARO_HALO: 539 case MODEL_CLARO_HALO:
391 chip->model.init = claro_halo_init; 540 chip->model.init = claro_halo_init;
541 chip->model.mixer_init = generic_mixer_init;
392 chip->model.cleanup = claro_cleanup; 542 chip->model.cleanup = claro_cleanup;
393 chip->model.suspend = claro_suspend; 543 chip->model.suspend = claro_suspend;
394 chip->model.resume = claro_resume; 544 chip->model.resume = claro_resume;
diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h
index bd615dbffadb..6147216af744 100644
--- a/sound/pci/oxygen/oxygen.h
+++ b/sound/pci/oxygen/oxygen.h
@@ -78,12 +78,15 @@ struct oxygen_model {
78 void (*resume)(struct oxygen *chip); 78 void (*resume)(struct oxygen *chip);
79 void (*pcm_hardware_filter)(unsigned int channel, 79 void (*pcm_hardware_filter)(unsigned int channel,
80 struct snd_pcm_hardware *hardware); 80 struct snd_pcm_hardware *hardware);
81 unsigned int (*get_i2s_mclk)(struct oxygen *chip, unsigned int channel,
82 struct snd_pcm_hw_params *hw_params);
81 void (*set_dac_params)(struct oxygen *chip, 83 void (*set_dac_params)(struct oxygen *chip,
82 struct snd_pcm_hw_params *params); 84 struct snd_pcm_hw_params *params);
83 void (*set_adc_params)(struct oxygen *chip, 85 void (*set_adc_params)(struct oxygen *chip,
84 struct snd_pcm_hw_params *params); 86 struct snd_pcm_hw_params *params);
85 void (*update_dac_volume)(struct oxygen *chip); 87 void (*update_dac_volume)(struct oxygen *chip);
86 void (*update_dac_mute)(struct oxygen *chip); 88 void (*update_dac_mute)(struct oxygen *chip);
89 void (*update_center_lfe_mix)(struct oxygen *chip, bool mixed);
87 void (*gpio_changed)(struct oxygen *chip); 90 void (*gpio_changed)(struct oxygen *chip);
88 void (*uart_input)(struct oxygen *chip); 91 void (*uart_input)(struct oxygen *chip);
89 void (*ac97_switch)(struct oxygen *chip, 92 void (*ac97_switch)(struct oxygen *chip,
@@ -162,6 +165,8 @@ void oxygen_update_spdif_source(struct oxygen *chip);
162/* oxygen_pcm.c */ 165/* oxygen_pcm.c */
163 166
164int oxygen_pcm_init(struct oxygen *chip); 167int oxygen_pcm_init(struct oxygen *chip);
168unsigned int oxygen_default_i2s_mclk(struct oxygen *chip, unsigned int channel,
169 struct snd_pcm_hw_params *hw_params);
165 170
166/* oxygen_io.c */ 171/* oxygen_io.c */
167 172
diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c
index 9a8936e20744..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>
@@ -278,7 +279,11 @@ oxygen_search_pci_id(struct oxygen *chip, const struct pci_device_id ids[])
278static void oxygen_restore_eeprom(struct oxygen *chip, 279static void oxygen_restore_eeprom(struct oxygen *chip,
279 const struct pci_device_id *id) 280 const struct pci_device_id *id)
280{ 281{
281 if (oxygen_read_eeprom(chip, 0) != OXYGEN_EEPROM_ID) { 282 u16 eeprom_id;
283
284 eeprom_id = oxygen_read_eeprom(chip, 0);
285 if (eeprom_id != OXYGEN_EEPROM_ID &&
286 (eeprom_id != 0xffff || id->subdevice != 0x8788)) {
282 /* 287 /*
283 * This function gets called only when a known card model has 288 * This function gets called only when a known card model has
284 * been detected, i.e., we know there is a valid subsystem 289 * been detected, i.e., we know there is a valid subsystem
@@ -303,6 +308,28 @@ static void oxygen_restore_eeprom(struct oxygen *chip,
303 } 308 }
304} 309}
305 310
311static void pci_bridge_magic(void)
312{
313 struct pci_dev *pci = NULL;
314 u32 tmp;
315
316 for (;;) {
317 /* If there is any Pericom PI7C9X110 PCI-E/PCI bridge ... */
318 pci = pci_get_device(0x12d8, 0xe110, pci);
319 if (!pci)
320 break;
321 /*
322 * ... configure its secondary internal arbiter to park to
323 * the secondary port, instead of to the last master.
324 */
325 if (!pci_read_config_dword(pci, 0x40, &tmp)) {
326 tmp |= 1;
327 pci_write_config_dword(pci, 0x40, tmp);
328 }
329 /* Why? Try asking C-Media. */
330 }
331}
332
306static void oxygen_init(struct oxygen *chip) 333static void oxygen_init(struct oxygen *chip)
307{ 334{
308 unsigned int i; 335 unsigned int i;
@@ -581,6 +608,7 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
581 snd_card_set_dev(card, &pci->dev); 608 snd_card_set_dev(card, &pci->dev);
582 card->private_free = oxygen_card_free; 609 card->private_free = oxygen_card_free;
583 610
611 pci_bridge_magic();
584 oxygen_init(chip); 612 oxygen_init(chip);
585 chip->model.init(chip); 613 chip->model.init(chip);
586 614
diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c
index 5401c547c4e3..f375b8a27862 100644
--- a/sound/pci/oxygen/oxygen_mixer.c
+++ b/sound/pci/oxygen/oxygen_mixer.c
@@ -99,11 +99,15 @@ static int dac_mute_put(struct snd_kcontrol *ctl,
99 99
100static int upmix_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info) 100static int upmix_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info)
101{ 101{
102 static const char *const names[3] = { 102 static const char *const names[5] = {
103 "Front", "Front+Surround", "Front+Surround+Back" 103 "Front",
104 "Front+Surround",
105 "Front+Surround+Back",
106 "Front+Surround+Center/LFE",
107 "Front+Surround+Center/LFE+Back",
104 }; 108 };
105 struct oxygen *chip = ctl->private_data; 109 struct oxygen *chip = ctl->private_data;
106 unsigned int count = 2 + (chip->model.dac_channels == 8); 110 unsigned int count = chip->model.update_center_lfe_mix ? 5 : 3;
107 111
108 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 112 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
109 info->count = 1; 113 info->count = 1;
@@ -127,7 +131,7 @@ static int upmix_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
127void oxygen_update_dac_routing(struct oxygen *chip) 131void oxygen_update_dac_routing(struct oxygen *chip)
128{ 132{
129 /* DAC 0: front, DAC 1: surround, DAC 2: center/LFE, DAC 3: back */ 133 /* DAC 0: front, DAC 1: surround, DAC 2: center/LFE, DAC 3: back */
130 static const unsigned int reg_values[3] = { 134 static const unsigned int reg_values[5] = {
131 /* stereo -> front */ 135 /* stereo -> front */
132 (0 << OXYGEN_PLAY_DAC0_SOURCE_SHIFT) | 136 (0 << OXYGEN_PLAY_DAC0_SOURCE_SHIFT) |
133 (1 << OXYGEN_PLAY_DAC1_SOURCE_SHIFT) | 137 (1 << OXYGEN_PLAY_DAC1_SOURCE_SHIFT) |
@@ -143,6 +147,16 @@ void oxygen_update_dac_routing(struct oxygen *chip)
143 (0 << OXYGEN_PLAY_DAC1_SOURCE_SHIFT) | 147 (0 << OXYGEN_PLAY_DAC1_SOURCE_SHIFT) |
144 (2 << OXYGEN_PLAY_DAC2_SOURCE_SHIFT) | 148 (2 << OXYGEN_PLAY_DAC2_SOURCE_SHIFT) |
145 (0 << OXYGEN_PLAY_DAC3_SOURCE_SHIFT), 149 (0 << OXYGEN_PLAY_DAC3_SOURCE_SHIFT),
150 /* stereo -> front+surround+center/LFE */
151 (0 << OXYGEN_PLAY_DAC0_SOURCE_SHIFT) |
152 (0 << OXYGEN_PLAY_DAC1_SOURCE_SHIFT) |
153 (0 << OXYGEN_PLAY_DAC2_SOURCE_SHIFT) |
154 (3 << OXYGEN_PLAY_DAC3_SOURCE_SHIFT),
155 /* stereo -> front+surround+center/LFE+back */
156 (0 << OXYGEN_PLAY_DAC0_SOURCE_SHIFT) |
157 (0 << OXYGEN_PLAY_DAC1_SOURCE_SHIFT) |
158 (0 << OXYGEN_PLAY_DAC2_SOURCE_SHIFT) |
159 (0 << OXYGEN_PLAY_DAC3_SOURCE_SHIFT),
146 }; 160 };
147 u8 channels; 161 u8 channels;
148 unsigned int reg_value; 162 unsigned int reg_value;
@@ -167,22 +181,23 @@ void oxygen_update_dac_routing(struct oxygen *chip)
167 OXYGEN_PLAY_DAC1_SOURCE_MASK | 181 OXYGEN_PLAY_DAC1_SOURCE_MASK |
168 OXYGEN_PLAY_DAC2_SOURCE_MASK | 182 OXYGEN_PLAY_DAC2_SOURCE_MASK |
169 OXYGEN_PLAY_DAC3_SOURCE_MASK); 183 OXYGEN_PLAY_DAC3_SOURCE_MASK);
184 if (chip->model.update_center_lfe_mix)
185 chip->model.update_center_lfe_mix(chip, chip->dac_routing > 2);
170} 186}
171 187
172static int upmix_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) 188static int upmix_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
173{ 189{
174 struct oxygen *chip = ctl->private_data; 190 struct oxygen *chip = ctl->private_data;
175 unsigned int count = 2 + (chip->model.dac_channels == 8); 191 unsigned int count = chip->model.update_center_lfe_mix ? 5 : 3;
176 int changed; 192 int changed;
177 193
194 if (value->value.enumerated.item[0] >= count)
195 return -EINVAL;
178 mutex_lock(&chip->mutex); 196 mutex_lock(&chip->mutex);
179 changed = value->value.enumerated.item[0] != chip->dac_routing; 197 changed = value->value.enumerated.item[0] != chip->dac_routing;
180 if (changed) { 198 if (changed) {
181 chip->dac_routing = min(value->value.enumerated.item[0], 199 chip->dac_routing = value->value.enumerated.item[0];
182 count - 1);
183 spin_lock_irq(&chip->reg_lock);
184 oxygen_update_dac_routing(chip); 200 oxygen_update_dac_routing(chip);
185 spin_unlock_irq(&chip->reg_lock);
186 } 201 }
187 mutex_unlock(&chip->mutex); 202 mutex_unlock(&chip->mutex);
188 return changed; 203 return changed;
@@ -790,7 +805,7 @@ static const struct {
790 .controls = { 805 .controls = {
791 { 806 {
792 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 807 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
793 .name = "Analog Input Monitor Switch", 808 .name = "Analog Input Monitor Playback Switch",
794 .info = snd_ctl_boolean_mono_info, 809 .info = snd_ctl_boolean_mono_info,
795 .get = monitor_get, 810 .get = monitor_get,
796 .put = monitor_put, 811 .put = monitor_put,
@@ -798,7 +813,7 @@ static const struct {
798 }, 813 },
799 { 814 {
800 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 815 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
801 .name = "Analog Input Monitor Volume", 816 .name = "Analog Input Monitor Playback Volume",
802 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | 817 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
803 SNDRV_CTL_ELEM_ACCESS_TLV_READ, 818 SNDRV_CTL_ELEM_ACCESS_TLV_READ,
804 .info = monitor_volume_info, 819 .info = monitor_volume_info,
@@ -815,7 +830,7 @@ static const struct {
815 .controls = { 830 .controls = {
816 { 831 {
817 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 832 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
818 .name = "Analog Input Monitor Switch", 833 .name = "Analog Input Monitor Playback Switch",
819 .info = snd_ctl_boolean_mono_info, 834 .info = snd_ctl_boolean_mono_info,
820 .get = monitor_get, 835 .get = monitor_get,
821 .put = monitor_put, 836 .put = monitor_put,
@@ -823,7 +838,7 @@ static const struct {
823 }, 838 },
824 { 839 {
825 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 840 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
826 .name = "Analog Input Monitor Volume", 841 .name = "Analog Input Monitor Playback Volume",
827 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | 842 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
828 SNDRV_CTL_ELEM_ACCESS_TLV_READ, 843 SNDRV_CTL_ELEM_ACCESS_TLV_READ,
829 .info = monitor_volume_info, 844 .info = monitor_volume_info,
@@ -840,7 +855,7 @@ static const struct {
840 .controls = { 855 .controls = {
841 { 856 {
842 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 857 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
843 .name = "Analog Input Monitor Switch", 858 .name = "Analog Input Monitor Playback Switch",
844 .index = 1, 859 .index = 1,
845 .info = snd_ctl_boolean_mono_info, 860 .info = snd_ctl_boolean_mono_info,
846 .get = monitor_get, 861 .get = monitor_get,
@@ -849,7 +864,7 @@ static const struct {
849 }, 864 },
850 { 865 {
851 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 866 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
852 .name = "Analog Input Monitor Volume", 867 .name = "Analog Input Monitor Playback Volume",
853 .index = 1, 868 .index = 1,
854 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | 869 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
855 SNDRV_CTL_ELEM_ACCESS_TLV_READ, 870 SNDRV_CTL_ELEM_ACCESS_TLV_READ,
@@ -867,7 +882,7 @@ static const struct {
867 .controls = { 882 .controls = {
868 { 883 {
869 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 884 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
870 .name = "Digital Input Monitor Switch", 885 .name = "Digital Input Monitor Playback Switch",
871 .info = snd_ctl_boolean_mono_info, 886 .info = snd_ctl_boolean_mono_info,
872 .get = monitor_get, 887 .get = monitor_get,
873 .put = monitor_put, 888 .put = monitor_put,
@@ -875,7 +890,7 @@ static const struct {
875 }, 890 },
876 { 891 {
877 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 892 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
878 .name = "Digital Input Monitor Volume", 893 .name = "Digital Input Monitor Playback Volume",
879 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | 894 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
880 SNDRV_CTL_ELEM_ACCESS_TLV_READ, 895 SNDRV_CTL_ELEM_ACCESS_TLV_READ,
881 .info = monitor_volume_info, 896 .info = monitor_volume_info,
@@ -954,6 +969,9 @@ static int add_controls(struct oxygen *chip,
954 if (err == 1) 969 if (err == 1)
955 continue; 970 continue;
956 } 971 }
972 if (!strcmp(template.name, "Stereo Upmixing") &&
973 chip->model.dac_channels == 2)
974 continue;
957 if (!strcmp(template.name, "Master Playback Volume") && 975 if (!strcmp(template.name, "Master Playback Volume") &&
958 chip->model.dac_tlv) { 976 chip->model.dac_tlv) {
959 template.tlv.p = chip->model.dac_tlv; 977 template.tlv.p = chip->model.dac_tlv;
diff --git a/sound/pci/oxygen/oxygen_pcm.c b/sound/pci/oxygen/oxygen_pcm.c
index ef2345d82b86..9dff6954c397 100644
--- a/sound/pci/oxygen/oxygen_pcm.c
+++ b/sound/pci/oxygen/oxygen_pcm.c
@@ -271,13 +271,16 @@ static unsigned int oxygen_rate(struct snd_pcm_hw_params *hw_params)
271 } 271 }
272} 272}
273 273
274static unsigned int oxygen_i2s_mclk(struct snd_pcm_hw_params *hw_params) 274unsigned int oxygen_default_i2s_mclk(struct oxygen *chip,
275 unsigned int channel,
276 struct snd_pcm_hw_params *hw_params)
275{ 277{
276 if (params_rate(hw_params) <= 96000) 278 if (params_rate(hw_params) <= 96000)
277 return OXYGEN_I2S_MCLK_256; 279 return OXYGEN_I2S_MCLK_256;
278 else 280 else
279 return OXYGEN_I2S_MCLK_128; 281 return OXYGEN_I2S_MCLK_128;
280} 282}
283EXPORT_SYMBOL(oxygen_default_i2s_mclk);
281 284
282static unsigned int oxygen_i2s_bits(struct snd_pcm_hw_params *hw_params) 285static unsigned int oxygen_i2s_bits(struct snd_pcm_hw_params *hw_params)
283{ 286{
@@ -354,7 +357,7 @@ static int oxygen_rec_a_hw_params(struct snd_pcm_substream *substream,
354 OXYGEN_REC_FORMAT_A_MASK); 357 OXYGEN_REC_FORMAT_A_MASK);
355 oxygen_write16_masked(chip, OXYGEN_I2S_A_FORMAT, 358 oxygen_write16_masked(chip, OXYGEN_I2S_A_FORMAT,
356 oxygen_rate(hw_params) | 359 oxygen_rate(hw_params) |
357 oxygen_i2s_mclk(hw_params) | 360 chip->model.get_i2s_mclk(chip, PCM_A, hw_params) |
358 chip->model.adc_i2s_format | 361 chip->model.adc_i2s_format |
359 oxygen_i2s_bits(hw_params), 362 oxygen_i2s_bits(hw_params),
360 OXYGEN_I2S_RATE_MASK | 363 OXYGEN_I2S_RATE_MASK |
@@ -390,7 +393,8 @@ static int oxygen_rec_b_hw_params(struct snd_pcm_substream *substream,
390 if (!is_ac97) 393 if (!is_ac97)
391 oxygen_write16_masked(chip, OXYGEN_I2S_B_FORMAT, 394 oxygen_write16_masked(chip, OXYGEN_I2S_B_FORMAT,
392 oxygen_rate(hw_params) | 395 oxygen_rate(hw_params) |
393 oxygen_i2s_mclk(hw_params) | 396 chip->model.get_i2s_mclk(chip, PCM_B,
397 hw_params) |
394 chip->model.adc_i2s_format | 398 chip->model.adc_i2s_format |
395 oxygen_i2s_bits(hw_params), 399 oxygen_i2s_bits(hw_params),
396 OXYGEN_I2S_RATE_MASK | 400 OXYGEN_I2S_RATE_MASK |
@@ -435,6 +439,7 @@ static int oxygen_spdif_hw_params(struct snd_pcm_substream *substream,
435 if (err < 0) 439 if (err < 0)
436 return err; 440 return err;
437 441
442 mutex_lock(&chip->mutex);
438 spin_lock_irq(&chip->reg_lock); 443 spin_lock_irq(&chip->reg_lock);
439 oxygen_clear_bits32(chip, OXYGEN_SPDIF_CONTROL, 444 oxygen_clear_bits32(chip, OXYGEN_SPDIF_CONTROL,
440 OXYGEN_SPDIF_OUT_ENABLE); 445 OXYGEN_SPDIF_OUT_ENABLE);
@@ -446,6 +451,7 @@ static int oxygen_spdif_hw_params(struct snd_pcm_substream *substream,
446 OXYGEN_SPDIF_OUT_RATE_MASK); 451 OXYGEN_SPDIF_OUT_RATE_MASK);
447 oxygen_update_spdif_source(chip); 452 oxygen_update_spdif_source(chip);
448 spin_unlock_irq(&chip->reg_lock); 453 spin_unlock_irq(&chip->reg_lock);
454 mutex_unlock(&chip->mutex);
449 return 0; 455 return 0;
450} 456}
451 457
@@ -459,6 +465,7 @@ static int oxygen_multich_hw_params(struct snd_pcm_substream *substream,
459 if (err < 0) 465 if (err < 0)
460 return err; 466 return err;
461 467
468 mutex_lock(&chip->mutex);
462 spin_lock_irq(&chip->reg_lock); 469 spin_lock_irq(&chip->reg_lock);
463 oxygen_write8_masked(chip, OXYGEN_PLAY_CHANNELS, 470 oxygen_write8_masked(chip, OXYGEN_PLAY_CHANNELS,
464 oxygen_play_channels(hw_params), 471 oxygen_play_channels(hw_params),
@@ -469,18 +476,18 @@ static int oxygen_multich_hw_params(struct snd_pcm_substream *substream,
469 oxygen_write16_masked(chip, OXYGEN_I2S_MULTICH_FORMAT, 476 oxygen_write16_masked(chip, OXYGEN_I2S_MULTICH_FORMAT,
470 oxygen_rate(hw_params) | 477 oxygen_rate(hw_params) |
471 chip->model.dac_i2s_format | 478 chip->model.dac_i2s_format |
472 oxygen_i2s_mclk(hw_params) | 479 chip->model.get_i2s_mclk(chip, PCM_MULTICH,
480 hw_params) |
473 oxygen_i2s_bits(hw_params), 481 oxygen_i2s_bits(hw_params),
474 OXYGEN_I2S_RATE_MASK | 482 OXYGEN_I2S_RATE_MASK |
475 OXYGEN_I2S_FORMAT_MASK | 483 OXYGEN_I2S_FORMAT_MASK |
476 OXYGEN_I2S_MCLK_MASK | 484 OXYGEN_I2S_MCLK_MASK |
477 OXYGEN_I2S_BITS_MASK); 485 OXYGEN_I2S_BITS_MASK);
478 oxygen_update_dac_routing(chip);
479 oxygen_update_spdif_source(chip); 486 oxygen_update_spdif_source(chip);
480 spin_unlock_irq(&chip->reg_lock); 487 spin_unlock_irq(&chip->reg_lock);
481 488
482 mutex_lock(&chip->mutex);
483 chip->model.set_dac_params(chip, hw_params); 489 chip->model.set_dac_params(chip, hw_params);
490 oxygen_update_dac_routing(chip);
484 mutex_unlock(&chip->mutex); 491 mutex_unlock(&chip->mutex);
485 return 0; 492 return 0;
486} 493}
diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c
index 6ebcb6bdd712..f03a2f2cffee 100644
--- a/sound/pci/oxygen/virtuoso.c
+++ b/sound/pci/oxygen/virtuoso.c
@@ -17,145 +17,12 @@
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */ 18 */
19 19
20/*
21 * Xonar D2/D2X
22 * ------------
23 *
24 * CMI8788:
25 *
26 * SPI 0 -> 1st PCM1796 (front)
27 * SPI 1 -> 2nd PCM1796 (surround)
28 * SPI 2 -> 3rd PCM1796 (center/LFE)
29 * SPI 4 -> 4th PCM1796 (back)
30 *
31 * GPIO 2 -> M0 of CS5381
32 * GPIO 3 -> M1 of CS5381
33 * GPIO 5 <- external power present (D2X only)
34 * GPIO 7 -> ALT
35 * GPIO 8 -> enable output to speakers
36 */
37
38/*
39 * Xonar D1/DX
40 * -----------
41 *
42 * CMI8788:
43 *
44 * I²C <-> CS4398 (front)
45 * <-> CS4362A (surround, center/LFE, back)
46 *
47 * GPI 0 <- external power present (DX only)
48 *
49 * GPIO 0 -> enable output to speakers
50 * GPIO 1 -> enable front panel I/O
51 * GPIO 2 -> M0 of CS5361
52 * GPIO 3 -> M1 of CS5361
53 * GPIO 8 -> route input jack to line-in (0) or mic-in (1)
54 *
55 * CS4398:
56 *
57 * AD0 <- 1
58 * AD1 <- 1
59 *
60 * CS4362A:
61 *
62 * AD0 <- 0
63 */
64
65/*
66 * Xonar HDAV1.3 (Deluxe)
67 * ----------------------
68 *
69 * CMI8788:
70 *
71 * I²C <-> PCM1796 (front)
72 *
73 * GPI 0 <- external power present
74 *
75 * GPIO 0 -> enable output to speakers
76 * GPIO 2 -> M0 of CS5381
77 * GPIO 3 -> M1 of CS5381
78 * GPIO 8 -> route input jack to line-in (0) or mic-in (1)
79 *
80 * TXD -> HDMI controller
81 * RXD <- HDMI controller
82 *
83 * PCM1796 front: AD1,0 <- 0,0
84 *
85 * no daughterboard
86 * ----------------
87 *
88 * GPIO 4 <- 1
89 *
90 * H6 daughterboard
91 * ----------------
92 *
93 * GPIO 4 <- 0
94 * GPIO 5 <- 0
95 *
96 * I²C <-> PCM1796 (surround)
97 * <-> PCM1796 (center/LFE)
98 * <-> PCM1796 (back)
99 *
100 * PCM1796 surround: AD1,0 <- 0,1
101 * PCM1796 center/LFE: AD1,0 <- 1,0
102 * PCM1796 back: AD1,0 <- 1,1
103 *
104 * unknown daughterboard
105 * ---------------------
106 *
107 * GPIO 4 <- 0
108 * GPIO 5 <- 1
109 *
110 * I²C <-> CS4362A (surround, center/LFE, back)
111 *
112 * CS4362A: AD0 <- 0
113 */
114
115/*
116 * Xonar Essence ST (Deluxe)/STX
117 * -----------------------------
118 *
119 * CMI8788:
120 *
121 * I²C <-> PCM1792A
122 *
123 * GPI 0 <- external power present
124 *
125 * GPIO 0 -> enable output to speakers
126 * GPIO 1 -> route HP to front panel (0) or rear jack (1)
127 * GPIO 2 -> M0 of CS5381
128 * GPIO 3 -> M1 of CS5381
129 * GPIO 7 -> route output to speaker jacks (0) or HP (1)
130 * GPIO 8 -> route input jack to line-in (0) or mic-in (1)
131 *
132 * PCM1792A:
133 *
134 * AD0 <- 0
135 *
136 * H6 daughterboard
137 * ----------------
138 *
139 * GPIO 4 <- 0
140 * GPIO 5 <- 0
141 */
142
143#include <linux/pci.h> 20#include <linux/pci.h>
144#include <linux/delay.h> 21#include <linux/delay.h>
145#include <linux/mutex.h>
146#include <sound/ac97_codec.h>
147#include <sound/asoundef.h>
148#include <sound/control.h>
149#include <sound/core.h> 22#include <sound/core.h>
150#include <sound/initval.h> 23#include <sound/initval.h>
151#include <sound/pcm.h> 24#include <sound/pcm.h>
152#include <sound/pcm_params.h> 25#include "xonar.h"
153#include <sound/tlv.h>
154#include "oxygen.h"
155#include "cm9780.h"
156#include "pcm1796.h"
157#include "cs4398.h"
158#include "cs4362a.h"
159 26
160MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); 27MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
161MODULE_DESCRIPTION("Asus AVx00 driver"); 28MODULE_DESCRIPTION("Asus AVx00 driver");
@@ -173,972 +40,31 @@ MODULE_PARM_DESC(id, "ID string");
173module_param_array(enable, bool, NULL, 0444); 40module_param_array(enable, bool, NULL, 0444);
174MODULE_PARM_DESC(enable, "enable card"); 41MODULE_PARM_DESC(enable, "enable card");
175 42
176enum { 43static DEFINE_PCI_DEVICE_TABLE(xonar_ids) = {
177 MODEL_D2, 44 { OXYGEN_PCI_SUBID(0x1043, 0x8269) },
178 MODEL_D2X, 45 { OXYGEN_PCI_SUBID(0x1043, 0x8275) },
179 MODEL_D1, 46 { OXYGEN_PCI_SUBID(0x1043, 0x82b7) },
180 MODEL_DX, 47 { OXYGEN_PCI_SUBID(0x1043, 0x8314) },
181 MODEL_HDAV, /* without daughterboard */ 48 { OXYGEN_PCI_SUBID(0x1043, 0x8327) },
182 MODEL_HDAV_H6, /* with H6 daughterboard */ 49 { OXYGEN_PCI_SUBID(0x1043, 0x834f) },
183 MODEL_ST, 50 { OXYGEN_PCI_SUBID(0x1043, 0x835c) },
184 MODEL_ST_H6, 51 { OXYGEN_PCI_SUBID(0x1043, 0x835d) },
185 MODEL_STX, 52 { OXYGEN_PCI_SUBID(0x1043, 0x838e) },
186};
187
188static struct pci_device_id xonar_ids[] __devinitdata = {
189 { OXYGEN_PCI_SUBID(0x1043, 0x8269), .driver_data = MODEL_D2 },
190 { OXYGEN_PCI_SUBID(0x1043, 0x8275), .driver_data = MODEL_DX },
191 { OXYGEN_PCI_SUBID(0x1043, 0x82b7), .driver_data = MODEL_D2X },
192 { OXYGEN_PCI_SUBID(0x1043, 0x8314), .driver_data = MODEL_HDAV },
193 { OXYGEN_PCI_SUBID(0x1043, 0x8327), .driver_data = MODEL_DX },
194 { OXYGEN_PCI_SUBID(0x1043, 0x834f), .driver_data = MODEL_D1 },
195 { OXYGEN_PCI_SUBID(0x1043, 0x835c), .driver_data = MODEL_STX },
196 { OXYGEN_PCI_SUBID(0x1043, 0x835d), .driver_data = MODEL_ST },
197 { OXYGEN_PCI_SUBID_BROKEN_EEPROM }, 53 { OXYGEN_PCI_SUBID_BROKEN_EEPROM },
198 { } 54 { }
199}; 55};
200MODULE_DEVICE_TABLE(pci, xonar_ids); 56MODULE_DEVICE_TABLE(pci, xonar_ids);
201 57
202
203#define GPIO_CS53x1_M_MASK 0x000c
204#define GPIO_CS53x1_M_SINGLE 0x0000
205#define GPIO_CS53x1_M_DOUBLE 0x0004
206#define GPIO_CS53x1_M_QUAD 0x0008
207
208#define GPIO_D2X_EXT_POWER 0x0020
209#define GPIO_D2_ALT 0x0080
210#define GPIO_D2_OUTPUT_ENABLE 0x0100
211
212#define GPI_DX_EXT_POWER 0x01
213#define GPIO_DX_OUTPUT_ENABLE 0x0001
214#define GPIO_DX_FRONT_PANEL 0x0002
215#define GPIO_DX_INPUT_ROUTE 0x0100
216
217#define GPIO_DB_MASK 0x0030
218#define GPIO_DB_H6 0x0000
219#define GPIO_DB_XX 0x0020
220
221#define GPIO_ST_HP_REAR 0x0002
222#define GPIO_ST_HP 0x0080
223
224#define I2C_DEVICE_PCM1796(i) (0x98 + ((i) << 1)) /* 10011, ADx=i, /W=0 */
225#define I2C_DEVICE_CS4398 0x9e /* 10011, AD1=1, AD0=1, /W=0 */
226#define I2C_DEVICE_CS4362A 0x30 /* 001100, AD0=0, /W=0 */
227
228struct xonar_data {
229 unsigned int anti_pop_delay;
230 unsigned int dacs;
231 u16 output_enable_bit;
232 u8 ext_power_reg;
233 u8 ext_power_int_reg;
234 u8 ext_power_bit;
235 u8 has_power;
236 u8 pcm1796_oversampling;
237 u8 cs4398_fm;
238 u8 cs4362a_fm;
239 u8 hdmi_params[5];
240};
241
242static void xonar_gpio_changed(struct oxygen *chip);
243
244static inline void pcm1796_write_spi(struct oxygen *chip, unsigned int codec,
245 u8 reg, u8 value)
246{
247 /* maps ALSA channel pair number to SPI output */
248 static const u8 codec_map[4] = {
249 0, 1, 2, 4
250 };
251 oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
252 OXYGEN_SPI_DATA_LENGTH_2 |
253 OXYGEN_SPI_CLOCK_160 |
254 (codec_map[codec] << OXYGEN_SPI_CODEC_SHIFT) |
255 OXYGEN_SPI_CEN_LATCH_CLOCK_HI,
256 (reg << 8) | value);
257}
258
259static inline void pcm1796_write_i2c(struct oxygen *chip, unsigned int codec,
260 u8 reg, u8 value)
261{
262 oxygen_write_i2c(chip, I2C_DEVICE_PCM1796(codec), reg, value);
263}
264
265static void pcm1796_write(struct oxygen *chip, unsigned int codec,
266 u8 reg, u8 value)
267{
268 if ((chip->model.function_flags & OXYGEN_FUNCTION_2WIRE_SPI_MASK) ==
269 OXYGEN_FUNCTION_SPI)
270 pcm1796_write_spi(chip, codec, reg, value);
271 else
272 pcm1796_write_i2c(chip, codec, reg, value);
273}
274
275static void cs4398_write(struct oxygen *chip, u8 reg, u8 value)
276{
277 oxygen_write_i2c(chip, I2C_DEVICE_CS4398, reg, value);
278}
279
280static void cs4362a_write(struct oxygen *chip, u8 reg, u8 value)
281{
282 oxygen_write_i2c(chip, I2C_DEVICE_CS4362A, reg, value);
283}
284
285static void hdmi_write_command(struct oxygen *chip, u8 command,
286 unsigned int count, const u8 *params)
287{
288 unsigned int i;
289 u8 checksum;
290
291 oxygen_write_uart(chip, 0xfb);
292 oxygen_write_uart(chip, 0xef);
293 oxygen_write_uart(chip, command);
294 oxygen_write_uart(chip, count);
295 for (i = 0; i < count; ++i)
296 oxygen_write_uart(chip, params[i]);
297 checksum = 0xfb + 0xef + command + count;
298 for (i = 0; i < count; ++i)
299 checksum += params[i];
300 oxygen_write_uart(chip, checksum);
301}
302
303static void xonar_enable_output(struct oxygen *chip)
304{
305 struct xonar_data *data = chip->model_data;
306
307 msleep(data->anti_pop_delay);
308 oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, data->output_enable_bit);
309}
310
311static void xonar_common_init(struct oxygen *chip)
312{
313 struct xonar_data *data = chip->model_data;
314
315 if (data->ext_power_reg) {
316 oxygen_set_bits8(chip, data->ext_power_int_reg,
317 data->ext_power_bit);
318 chip->interrupt_mask |= OXYGEN_INT_GPIO;
319 chip->model.gpio_changed = xonar_gpio_changed;
320 data->has_power = !!(oxygen_read8(chip, data->ext_power_reg)
321 & data->ext_power_bit);
322 }
323 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
324 GPIO_CS53x1_M_MASK | data->output_enable_bit);
325 oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
326 GPIO_CS53x1_M_SINGLE, GPIO_CS53x1_M_MASK);
327 oxygen_ac97_set_bits(chip, 0, CM9780_JACK, CM9780_FMIC2MIC);
328 xonar_enable_output(chip);
329}
330
331static void update_pcm1796_volume(struct oxygen *chip)
332{
333 struct xonar_data *data = chip->model_data;
334 unsigned int i;
335
336 for (i = 0; i < data->dacs; ++i) {
337 pcm1796_write(chip, i, 16, chip->dac_volume[i * 2]);
338 pcm1796_write(chip, i, 17, chip->dac_volume[i * 2 + 1]);
339 }
340}
341
342static void update_pcm1796_mute(struct oxygen *chip)
343{
344 struct xonar_data *data = chip->model_data;
345 unsigned int i;
346 u8 value;
347
348 value = PCM1796_DMF_DISABLED | PCM1796_FMT_24_LJUST | PCM1796_ATLD;
349 if (chip->dac_mute)
350 value |= PCM1796_MUTE;
351 for (i = 0; i < data->dacs; ++i)
352 pcm1796_write(chip, i, 18, value);
353}
354
355static void pcm1796_init(struct oxygen *chip)
356{
357 struct xonar_data *data = chip->model_data;
358 unsigned int i;
359
360 for (i = 0; i < data->dacs; ++i) {
361 pcm1796_write(chip, i, 19, PCM1796_FLT_SHARP | PCM1796_ATS_1);
362 pcm1796_write(chip, i, 20, data->pcm1796_oversampling);
363 pcm1796_write(chip, i, 21, 0);
364 }
365 update_pcm1796_mute(chip); /* set ATLD before ATL/ATR */
366 update_pcm1796_volume(chip);
367}
368
369static void xonar_d2_init(struct oxygen *chip)
370{
371 struct xonar_data *data = chip->model_data;
372
373 data->anti_pop_delay = 300;
374 data->dacs = 4;
375 data->output_enable_bit = GPIO_D2_OUTPUT_ENABLE;
376 data->pcm1796_oversampling = PCM1796_OS_64;
377
378 pcm1796_init(chip);
379
380 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_D2_ALT);
381 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_D2_ALT);
382
383 xonar_common_init(chip);
384
385 snd_component_add(chip->card, "PCM1796");
386 snd_component_add(chip->card, "CS5381");
387}
388
389static void xonar_d2x_init(struct oxygen *chip)
390{
391 struct xonar_data *data = chip->model_data;
392
393 data->ext_power_reg = OXYGEN_GPIO_DATA;
394 data->ext_power_int_reg = OXYGEN_GPIO_INTERRUPT_MASK;
395 data->ext_power_bit = GPIO_D2X_EXT_POWER;
396 oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_D2X_EXT_POWER);
397
398 xonar_d2_init(chip);
399}
400
401static void update_cs4362a_volumes(struct oxygen *chip)
402{
403 u8 mute;
404
405 mute = chip->dac_mute ? CS4362A_MUTE : 0;
406 cs4362a_write(chip, 7, (127 - chip->dac_volume[2]) | mute);
407 cs4362a_write(chip, 8, (127 - chip->dac_volume[3]) | mute);
408 cs4362a_write(chip, 10, (127 - chip->dac_volume[4]) | mute);
409 cs4362a_write(chip, 11, (127 - chip->dac_volume[5]) | mute);
410 cs4362a_write(chip, 13, (127 - chip->dac_volume[6]) | mute);
411 cs4362a_write(chip, 14, (127 - chip->dac_volume[7]) | mute);
412}
413
414static void update_cs43xx_volume(struct oxygen *chip)
415{
416 cs4398_write(chip, 5, (127 - chip->dac_volume[0]) * 2);
417 cs4398_write(chip, 6, (127 - chip->dac_volume[1]) * 2);
418 update_cs4362a_volumes(chip);
419}
420
421static void update_cs43xx_mute(struct oxygen *chip)
422{
423 u8 reg;
424
425 reg = CS4398_MUTEP_LOW | CS4398_PAMUTE;
426 if (chip->dac_mute)
427 reg |= CS4398_MUTE_B | CS4398_MUTE_A;
428 cs4398_write(chip, 4, reg);
429 update_cs4362a_volumes(chip);
430}
431
432static void cs43xx_init(struct oxygen *chip)
433{
434 struct xonar_data *data = chip->model_data;
435
436 /* set CPEN (control port mode) and power down */
437 cs4398_write(chip, 8, CS4398_CPEN | CS4398_PDN);
438 cs4362a_write(chip, 0x01, CS4362A_PDN | CS4362A_CPEN);
439 /* configure */
440 cs4398_write(chip, 2, data->cs4398_fm);
441 cs4398_write(chip, 3, CS4398_ATAPI_B_R | CS4398_ATAPI_A_L);
442 cs4398_write(chip, 7, CS4398_RMP_DN | CS4398_RMP_UP |
443 CS4398_ZERO_CROSS | CS4398_SOFT_RAMP);
444 cs4362a_write(chip, 0x02, CS4362A_DIF_LJUST);
445 cs4362a_write(chip, 0x03, CS4362A_MUTEC_6 | CS4362A_AMUTE |
446 CS4362A_RMP_UP | CS4362A_ZERO_CROSS | CS4362A_SOFT_RAMP);
447 cs4362a_write(chip, 0x04, CS4362A_RMP_DN | CS4362A_DEM_NONE);
448 cs4362a_write(chip, 0x05, 0);
449 cs4362a_write(chip, 0x06, data->cs4362a_fm);
450 cs4362a_write(chip, 0x09, data->cs4362a_fm);
451 cs4362a_write(chip, 0x0c, data->cs4362a_fm);
452 update_cs43xx_volume(chip);
453 update_cs43xx_mute(chip);
454 /* clear power down */
455 cs4398_write(chip, 8, CS4398_CPEN);
456 cs4362a_write(chip, 0x01, CS4362A_CPEN);
457}
458
459static void xonar_d1_init(struct oxygen *chip)
460{
461 struct xonar_data *data = chip->model_data;
462
463 data->anti_pop_delay = 800;
464 data->output_enable_bit = GPIO_DX_OUTPUT_ENABLE;
465 data->cs4398_fm = CS4398_FM_SINGLE | CS4398_DEM_NONE | CS4398_DIF_LJUST;
466 data->cs4362a_fm = CS4362A_FM_SINGLE |
467 CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L;
468
469 oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS,
470 OXYGEN_2WIRE_LENGTH_8 |
471 OXYGEN_2WIRE_INTERRUPT_MASK |
472 OXYGEN_2WIRE_SPEED_FAST);
473
474 cs43xx_init(chip);
475
476 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
477 GPIO_DX_FRONT_PANEL | GPIO_DX_INPUT_ROUTE);
478 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA,
479 GPIO_DX_FRONT_PANEL | GPIO_DX_INPUT_ROUTE);
480
481 xonar_common_init(chip);
482
483 snd_component_add(chip->card, "CS4398");
484 snd_component_add(chip->card, "CS4362A");
485 snd_component_add(chip->card, "CS5361");
486}
487
488static void xonar_dx_init(struct oxygen *chip)
489{
490 struct xonar_data *data = chip->model_data;
491
492 data->ext_power_reg = OXYGEN_GPI_DATA;
493 data->ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK;
494 data->ext_power_bit = GPI_DX_EXT_POWER;
495
496 xonar_d1_init(chip);
497}
498
499static void xonar_hdav_init(struct oxygen *chip)
500{
501 struct xonar_data *data = chip->model_data;
502 u8 param;
503
504 oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS,
505 OXYGEN_2WIRE_LENGTH_8 |
506 OXYGEN_2WIRE_INTERRUPT_MASK |
507 OXYGEN_2WIRE_SPEED_FAST);
508
509 data->anti_pop_delay = 100;
510 data->dacs = chip->model.private_data == MODEL_HDAV_H6 ? 4 : 1;
511 data->output_enable_bit = GPIO_DX_OUTPUT_ENABLE;
512 data->ext_power_reg = OXYGEN_GPI_DATA;
513 data->ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK;
514 data->ext_power_bit = GPI_DX_EXT_POWER;
515 data->pcm1796_oversampling = PCM1796_OS_64;
516
517 pcm1796_init(chip);
518
519 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_DX_INPUT_ROUTE);
520 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_DX_INPUT_ROUTE);
521
522 oxygen_reset_uart(chip);
523 param = 0;
524 hdmi_write_command(chip, 0x61, 1, &param);
525 param = 1;
526 hdmi_write_command(chip, 0x74, 1, &param);
527 data->hdmi_params[1] = IEC958_AES3_CON_FS_48000;
528 data->hdmi_params[4] = 1;
529 hdmi_write_command(chip, 0x54, 5, data->hdmi_params);
530
531 xonar_common_init(chip);
532
533 snd_component_add(chip->card, "PCM1796");
534 snd_component_add(chip->card, "CS5381");
535}
536
537static void xonar_st_init(struct oxygen *chip)
538{
539 struct xonar_data *data = chip->model_data;
540
541 oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS,
542 OXYGEN_2WIRE_LENGTH_8 |
543 OXYGEN_2WIRE_INTERRUPT_MASK |
544 OXYGEN_2WIRE_SPEED_FAST);
545
546 if (chip->model.private_data == MODEL_ST_H6)
547 chip->model.dac_channels = 8;
548 data->anti_pop_delay = 100;
549 data->dacs = chip->model.private_data == MODEL_ST_H6 ? 4 : 1;
550 data->output_enable_bit = GPIO_DX_OUTPUT_ENABLE;
551 data->pcm1796_oversampling = PCM1796_OS_64;
552
553 pcm1796_init(chip);
554
555 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
556 GPIO_DX_INPUT_ROUTE | GPIO_ST_HP_REAR | GPIO_ST_HP);
557 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA,
558 GPIO_DX_INPUT_ROUTE | GPIO_ST_HP_REAR | GPIO_ST_HP);
559
560 xonar_common_init(chip);
561
562 snd_component_add(chip->card, "PCM1792A");
563 snd_component_add(chip->card, "CS5381");
564}
565
566static void xonar_stx_init(struct oxygen *chip)
567{
568 struct xonar_data *data = chip->model_data;
569
570 data->ext_power_reg = OXYGEN_GPI_DATA;
571 data->ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK;
572 data->ext_power_bit = GPI_DX_EXT_POWER;
573
574 xonar_st_init(chip);
575}
576
577static void xonar_disable_output(struct oxygen *chip)
578{
579 struct xonar_data *data = chip->model_data;
580
581 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, data->output_enable_bit);
582}
583
584static void xonar_d2_cleanup(struct oxygen *chip)
585{
586 xonar_disable_output(chip);
587}
588
589static void xonar_d1_cleanup(struct oxygen *chip)
590{
591 xonar_disable_output(chip);
592 cs4362a_write(chip, 0x01, CS4362A_PDN | CS4362A_CPEN);
593 oxygen_clear_bits8(chip, OXYGEN_FUNCTION, OXYGEN_FUNCTION_RESET_CODEC);
594}
595
596static void xonar_hdav_cleanup(struct oxygen *chip)
597{
598 u8 param = 0;
599
600 hdmi_write_command(chip, 0x74, 1, &param);
601 xonar_disable_output(chip);
602}
603
604static void xonar_st_cleanup(struct oxygen *chip)
605{
606 xonar_disable_output(chip);
607}
608
609static void xonar_d2_suspend(struct oxygen *chip)
610{
611 xonar_d2_cleanup(chip);
612}
613
614static void xonar_d1_suspend(struct oxygen *chip)
615{
616 xonar_d1_cleanup(chip);
617}
618
619static void xonar_hdav_suspend(struct oxygen *chip)
620{
621 xonar_hdav_cleanup(chip);
622 msleep(2);
623}
624
625static void xonar_st_suspend(struct oxygen *chip)
626{
627 xonar_st_cleanup(chip);
628}
629
630static void xonar_d2_resume(struct oxygen *chip)
631{
632 pcm1796_init(chip);
633 xonar_enable_output(chip);
634}
635
636static void xonar_d1_resume(struct oxygen *chip)
637{
638 oxygen_set_bits8(chip, OXYGEN_FUNCTION, OXYGEN_FUNCTION_RESET_CODEC);
639 msleep(1);
640 cs43xx_init(chip);
641 xonar_enable_output(chip);
642}
643
644static void xonar_hdav_resume(struct oxygen *chip)
645{
646 struct xonar_data *data = chip->model_data;
647 u8 param;
648
649 oxygen_reset_uart(chip);
650 param = 0;
651 hdmi_write_command(chip, 0x61, 1, &param);
652 param = 1;
653 hdmi_write_command(chip, 0x74, 1, &param);
654 hdmi_write_command(chip, 0x54, 5, data->hdmi_params);
655 pcm1796_init(chip);
656 xonar_enable_output(chip);
657}
658
659static void xonar_st_resume(struct oxygen *chip)
660{
661 pcm1796_init(chip);
662 xonar_enable_output(chip);
663}
664
665static void xonar_hdav_pcm_hardware_filter(unsigned int channel,
666 struct snd_pcm_hardware *hardware)
667{
668 if (channel == PCM_MULTICH) {
669 hardware->rates = SNDRV_PCM_RATE_44100 |
670 SNDRV_PCM_RATE_48000 |
671 SNDRV_PCM_RATE_96000 |
672 SNDRV_PCM_RATE_192000;
673 hardware->rate_min = 44100;
674 }
675}
676
677static void set_pcm1796_params(struct oxygen *chip,
678 struct snd_pcm_hw_params *params)
679{
680 struct xonar_data *data = chip->model_data;
681 unsigned int i;
682
683 data->pcm1796_oversampling =
684 params_rate(params) >= 96000 ? PCM1796_OS_32 : PCM1796_OS_64;
685 for (i = 0; i < data->dacs; ++i)
686 pcm1796_write(chip, i, 20, data->pcm1796_oversampling);
687}
688
689static void set_cs53x1_params(struct oxygen *chip,
690 struct snd_pcm_hw_params *params)
691{
692 unsigned int value;
693
694 if (params_rate(params) <= 54000)
695 value = GPIO_CS53x1_M_SINGLE;
696 else if (params_rate(params) <= 108000)
697 value = GPIO_CS53x1_M_DOUBLE;
698 else
699 value = GPIO_CS53x1_M_QUAD;
700 oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
701 value, GPIO_CS53x1_M_MASK);
702}
703
704static void set_cs43xx_params(struct oxygen *chip,
705 struct snd_pcm_hw_params *params)
706{
707 struct xonar_data *data = chip->model_data;
708
709 data->cs4398_fm = CS4398_DEM_NONE | CS4398_DIF_LJUST;
710 data->cs4362a_fm = CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L;
711 if (params_rate(params) <= 50000) {
712 data->cs4398_fm |= CS4398_FM_SINGLE;
713 data->cs4362a_fm |= CS4362A_FM_SINGLE;
714 } else if (params_rate(params) <= 100000) {
715 data->cs4398_fm |= CS4398_FM_DOUBLE;
716 data->cs4362a_fm |= CS4362A_FM_DOUBLE;
717 } else {
718 data->cs4398_fm |= CS4398_FM_QUAD;
719 data->cs4362a_fm |= CS4362A_FM_QUAD;
720 }
721 cs4398_write(chip, 2, data->cs4398_fm);
722 cs4362a_write(chip, 0x06, data->cs4362a_fm);
723 cs4362a_write(chip, 0x09, data->cs4362a_fm);
724 cs4362a_write(chip, 0x0c, data->cs4362a_fm);
725}
726
727static void set_hdmi_params(struct oxygen *chip,
728 struct snd_pcm_hw_params *params)
729{
730 struct xonar_data *data = chip->model_data;
731
732 data->hdmi_params[0] = 0; /* 1 = non-audio */
733 switch (params_rate(params)) {
734 case 44100:
735 data->hdmi_params[1] = IEC958_AES3_CON_FS_44100;
736 break;
737 case 48000:
738 data->hdmi_params[1] = IEC958_AES3_CON_FS_48000;
739 break;
740 default: /* 96000 */
741 data->hdmi_params[1] = IEC958_AES3_CON_FS_96000;
742 break;
743 case 192000:
744 data->hdmi_params[1] = IEC958_AES3_CON_FS_192000;
745 break;
746 }
747 data->hdmi_params[2] = params_channels(params) / 2 - 1;
748 if (params_format(params) == SNDRV_PCM_FORMAT_S16_LE)
749 data->hdmi_params[3] = 0;
750 else
751 data->hdmi_params[3] = 0xc0;
752 data->hdmi_params[4] = 1; /* ? */
753 hdmi_write_command(chip, 0x54, 5, data->hdmi_params);
754}
755
756static void set_hdav_params(struct oxygen *chip,
757 struct snd_pcm_hw_params *params)
758{
759 set_pcm1796_params(chip, params);
760 set_hdmi_params(chip, params);
761}
762
763static void xonar_gpio_changed(struct oxygen *chip)
764{
765 struct xonar_data *data = chip->model_data;
766 u8 has_power;
767
768 has_power = !!(oxygen_read8(chip, data->ext_power_reg)
769 & data->ext_power_bit);
770 if (has_power != data->has_power) {
771 data->has_power = has_power;
772 if (has_power) {
773 snd_printk(KERN_NOTICE "power restored\n");
774 } else {
775 snd_printk(KERN_CRIT
776 "Hey! Don't unplug the power cable!\n");
777 /* TODO: stop PCMs */
778 }
779 }
780}
781
782static void xonar_hdav_uart_input(struct oxygen *chip)
783{
784 if (chip->uart_input_count >= 2 &&
785 chip->uart_input[chip->uart_input_count - 2] == 'O' &&
786 chip->uart_input[chip->uart_input_count - 1] == 'K') {
787 printk(KERN_DEBUG "message from Xonar HDAV HDMI chip received:\n");
788 print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
789 chip->uart_input, chip->uart_input_count);
790 chip->uart_input_count = 0;
791 }
792}
793
794static int gpio_bit_switch_get(struct snd_kcontrol *ctl,
795 struct snd_ctl_elem_value *value)
796{
797 struct oxygen *chip = ctl->private_data;
798 u16 bit = ctl->private_value;
799
800 value->value.integer.value[0] =
801 !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) & bit);
802 return 0;
803}
804
805static int gpio_bit_switch_put(struct snd_kcontrol *ctl,
806 struct snd_ctl_elem_value *value)
807{
808 struct oxygen *chip = ctl->private_data;
809 u16 bit = ctl->private_value;
810 u16 old_bits, new_bits;
811 int changed;
812
813 spin_lock_irq(&chip->reg_lock);
814 old_bits = oxygen_read16(chip, OXYGEN_GPIO_DATA);
815 if (value->value.integer.value[0])
816 new_bits = old_bits | bit;
817 else
818 new_bits = old_bits & ~bit;
819 changed = new_bits != old_bits;
820 if (changed)
821 oxygen_write16(chip, OXYGEN_GPIO_DATA, new_bits);
822 spin_unlock_irq(&chip->reg_lock);
823 return changed;
824}
825
826static const struct snd_kcontrol_new alt_switch = {
827 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
828 .name = "Analog Loopback Switch",
829 .info = snd_ctl_boolean_mono_info,
830 .get = gpio_bit_switch_get,
831 .put = gpio_bit_switch_put,
832 .private_value = GPIO_D2_ALT,
833};
834
835static const struct snd_kcontrol_new front_panel_switch = {
836 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
837 .name = "Front Panel Switch",
838 .info = snd_ctl_boolean_mono_info,
839 .get = gpio_bit_switch_get,
840 .put = gpio_bit_switch_put,
841 .private_value = GPIO_DX_FRONT_PANEL,
842};
843
844static int st_output_switch_info(struct snd_kcontrol *ctl,
845 struct snd_ctl_elem_info *info)
846{
847 static const char *const names[3] = {
848 "Speakers", "Headphones", "FP Headphones"
849 };
850
851 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
852 info->count = 1;
853 info->value.enumerated.items = 3;
854 if (info->value.enumerated.item >= 3)
855 info->value.enumerated.item = 2;
856 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
857 return 0;
858}
859
860static int st_output_switch_get(struct snd_kcontrol *ctl,
861 struct snd_ctl_elem_value *value)
862{
863 struct oxygen *chip = ctl->private_data;
864 u16 gpio;
865
866 gpio = oxygen_read16(chip, OXYGEN_GPIO_DATA);
867 if (!(gpio & GPIO_ST_HP))
868 value->value.enumerated.item[0] = 0;
869 else if (gpio & GPIO_ST_HP_REAR)
870 value->value.enumerated.item[0] = 1;
871 else
872 value->value.enumerated.item[0] = 2;
873 return 0;
874}
875
876
877static int st_output_switch_put(struct snd_kcontrol *ctl,
878 struct snd_ctl_elem_value *value)
879{
880 struct oxygen *chip = ctl->private_data;
881 u16 gpio_old, gpio;
882
883 mutex_lock(&chip->mutex);
884 gpio_old = oxygen_read16(chip, OXYGEN_GPIO_DATA);
885 gpio = gpio_old;
886 switch (value->value.enumerated.item[0]) {
887 case 0:
888 gpio &= ~(GPIO_ST_HP | GPIO_ST_HP_REAR);
889 break;
890 case 1:
891 gpio |= GPIO_ST_HP | GPIO_ST_HP_REAR;
892 break;
893 case 2:
894 gpio = (gpio | GPIO_ST_HP) & ~GPIO_ST_HP_REAR;
895 break;
896 }
897 oxygen_write16(chip, OXYGEN_GPIO_DATA, gpio);
898 mutex_unlock(&chip->mutex);
899 return gpio != gpio_old;
900}
901
902static const struct snd_kcontrol_new st_output_switch = {
903 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
904 .name = "Analog Output",
905 .info = st_output_switch_info,
906 .get = st_output_switch_get,
907 .put = st_output_switch_put,
908};
909
910static void xonar_line_mic_ac97_switch(struct oxygen *chip,
911 unsigned int reg, unsigned int mute)
912{
913 if (reg == AC97_LINE) {
914 spin_lock_irq(&chip->reg_lock);
915 oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
916 mute ? GPIO_DX_INPUT_ROUTE : 0,
917 GPIO_DX_INPUT_ROUTE);
918 spin_unlock_irq(&chip->reg_lock);
919 }
920}
921
922static const DECLARE_TLV_DB_SCALE(pcm1796_db_scale, -6000, 50, 0);
923static const DECLARE_TLV_DB_SCALE(cs4362a_db_scale, -6000, 100, 0);
924
925static int xonar_d2_control_filter(struct snd_kcontrol_new *template)
926{
927 if (!strncmp(template->name, "CD Capture ", 11))
928 /* CD in is actually connected to the video in pin */
929 template->private_value ^= AC97_CD ^ AC97_VIDEO;
930 return 0;
931}
932
933static int xonar_d1_control_filter(struct snd_kcontrol_new *template)
934{
935 if (!strncmp(template->name, "CD Capture ", 11))
936 return 1; /* no CD input */
937 return 0;
938}
939
940static int xonar_st_control_filter(struct snd_kcontrol_new *template)
941{
942 if (!strncmp(template->name, "CD Capture ", 11))
943 return 1; /* no CD input */
944 if (!strcmp(template->name, "Stereo Upmixing"))
945 return 1; /* stereo only - we don't need upmixing */
946 return 0;
947}
948
949static int xonar_d2_mixer_init(struct oxygen *chip)
950{
951 return snd_ctl_add(chip->card, snd_ctl_new1(&alt_switch, chip));
952}
953
954static int xonar_d1_mixer_init(struct oxygen *chip)
955{
956 return snd_ctl_add(chip->card, snd_ctl_new1(&front_panel_switch, chip));
957}
958
959static int xonar_st_mixer_init(struct oxygen *chip)
960{
961 return snd_ctl_add(chip->card, snd_ctl_new1(&st_output_switch, chip));
962}
963
964static const struct oxygen_model model_xonar_d2 = {
965 .longname = "Asus Virtuoso 200",
966 .chip = "AV200",
967 .init = xonar_d2_init,
968 .control_filter = xonar_d2_control_filter,
969 .mixer_init = xonar_d2_mixer_init,
970 .cleanup = xonar_d2_cleanup,
971 .suspend = xonar_d2_suspend,
972 .resume = xonar_d2_resume,
973 .set_dac_params = set_pcm1796_params,
974 .set_adc_params = set_cs53x1_params,
975 .update_dac_volume = update_pcm1796_volume,
976 .update_dac_mute = update_pcm1796_mute,
977 .dac_tlv = pcm1796_db_scale,
978 .model_data_size = sizeof(struct xonar_data),
979 .device_config = PLAYBACK_0_TO_I2S |
980 PLAYBACK_1_TO_SPDIF |
981 CAPTURE_0_FROM_I2S_2 |
982 CAPTURE_1_FROM_SPDIF |
983 MIDI_OUTPUT |
984 MIDI_INPUT,
985 .dac_channels = 8,
986 .dac_volume_min = 255 - 2*60,
987 .dac_volume_max = 255,
988 .misc_flags = OXYGEN_MISC_MIDI,
989 .function_flags = OXYGEN_FUNCTION_SPI |
990 OXYGEN_FUNCTION_ENABLE_SPI_4_5,
991 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
992 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
993};
994
995static const struct oxygen_model model_xonar_d1 = {
996 .longname = "Asus Virtuoso 100",
997 .chip = "AV200",
998 .init = xonar_d1_init,
999 .control_filter = xonar_d1_control_filter,
1000 .mixer_init = xonar_d1_mixer_init,
1001 .cleanup = xonar_d1_cleanup,
1002 .suspend = xonar_d1_suspend,
1003 .resume = xonar_d1_resume,
1004 .set_dac_params = set_cs43xx_params,
1005 .set_adc_params = set_cs53x1_params,
1006 .update_dac_volume = update_cs43xx_volume,
1007 .update_dac_mute = update_cs43xx_mute,
1008 .ac97_switch = xonar_line_mic_ac97_switch,
1009 .dac_tlv = cs4362a_db_scale,
1010 .model_data_size = sizeof(struct xonar_data),
1011 .device_config = PLAYBACK_0_TO_I2S |
1012 PLAYBACK_1_TO_SPDIF |
1013 CAPTURE_0_FROM_I2S_2,
1014 .dac_channels = 8,
1015 .dac_volume_min = 127 - 60,
1016 .dac_volume_max = 127,
1017 .function_flags = OXYGEN_FUNCTION_2WIRE,
1018 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1019 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1020};
1021
1022static const struct oxygen_model model_xonar_hdav = {
1023 .longname = "Asus Virtuoso 200",
1024 .chip = "AV200",
1025 .init = xonar_hdav_init,
1026 .cleanup = xonar_hdav_cleanup,
1027 .suspend = xonar_hdav_suspend,
1028 .resume = xonar_hdav_resume,
1029 .pcm_hardware_filter = xonar_hdav_pcm_hardware_filter,
1030 .set_dac_params = set_hdav_params,
1031 .set_adc_params = set_cs53x1_params,
1032 .update_dac_volume = update_pcm1796_volume,
1033 .update_dac_mute = update_pcm1796_mute,
1034 .uart_input = xonar_hdav_uart_input,
1035 .ac97_switch = xonar_line_mic_ac97_switch,
1036 .dac_tlv = pcm1796_db_scale,
1037 .model_data_size = sizeof(struct xonar_data),
1038 .device_config = PLAYBACK_0_TO_I2S |
1039 PLAYBACK_1_TO_SPDIF |
1040 CAPTURE_0_FROM_I2S_2 |
1041 CAPTURE_1_FROM_SPDIF,
1042 .dac_channels = 8,
1043 .dac_volume_min = 255 - 2*60,
1044 .dac_volume_max = 255,
1045 .misc_flags = OXYGEN_MISC_MIDI,
1046 .function_flags = OXYGEN_FUNCTION_2WIRE,
1047 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1048 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1049};
1050
1051static const struct oxygen_model model_xonar_st = {
1052 .longname = "Asus Virtuoso 100",
1053 .chip = "AV200",
1054 .init = xonar_st_init,
1055 .control_filter = xonar_st_control_filter,
1056 .mixer_init = xonar_st_mixer_init,
1057 .cleanup = xonar_st_cleanup,
1058 .suspend = xonar_st_suspend,
1059 .resume = xonar_st_resume,
1060 .set_dac_params = set_pcm1796_params,
1061 .set_adc_params = set_cs53x1_params,
1062 .update_dac_volume = update_pcm1796_volume,
1063 .update_dac_mute = update_pcm1796_mute,
1064 .ac97_switch = xonar_line_mic_ac97_switch,
1065 .dac_tlv = pcm1796_db_scale,
1066 .model_data_size = sizeof(struct xonar_data),
1067 .device_config = PLAYBACK_0_TO_I2S |
1068 PLAYBACK_1_TO_SPDIF |
1069 CAPTURE_0_FROM_I2S_2,
1070 .dac_channels = 2,
1071 .dac_volume_min = 255 - 2*60,
1072 .dac_volume_max = 255,
1073 .function_flags = OXYGEN_FUNCTION_2WIRE,
1074 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1075 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1076};
1077
1078static int __devinit get_xonar_model(struct oxygen *chip, 58static int __devinit get_xonar_model(struct oxygen *chip,
1079 const struct pci_device_id *id) 59 const struct pci_device_id *id)
1080{ 60{
1081 static const struct oxygen_model *const models[] = { 61 if (get_xonar_pcm179x_model(chip, id) >= 0)
1082 [MODEL_D1] = &model_xonar_d1, 62 return 0;
1083 [MODEL_DX] = &model_xonar_d1, 63 if (get_xonar_cs43xx_model(chip, id) >= 0)
1084 [MODEL_D2] = &model_xonar_d2, 64 return 0;
1085 [MODEL_D2X] = &model_xonar_d2, 65 if (get_xonar_wm87x6_model(chip, id) >= 0)
1086 [MODEL_HDAV] = &model_xonar_hdav, 66 return 0;
1087 [MODEL_ST] = &model_xonar_st, 67 return -EINVAL;
1088 [MODEL_STX] = &model_xonar_st,
1089 };
1090 static const char *const names[] = {
1091 [MODEL_D1] = "Xonar D1",
1092 [MODEL_DX] = "Xonar DX",
1093 [MODEL_D2] = "Xonar D2",
1094 [MODEL_D2X] = "Xonar D2X",
1095 [MODEL_HDAV] = "Xonar HDAV1.3",
1096 [MODEL_HDAV_H6] = "Xonar HDAV1.3+H6",
1097 [MODEL_ST] = "Xonar Essence ST",
1098 [MODEL_ST_H6] = "Xonar Essence ST+H6",
1099 [MODEL_STX] = "Xonar Essence STX",
1100 };
1101 unsigned int model = id->driver_data;
1102
1103 if (model >= ARRAY_SIZE(models) || !models[model])
1104 return -EINVAL;
1105 chip->model = *models[model];
1106
1107 switch (model) {
1108 case MODEL_D2X:
1109 chip->model.init = xonar_d2x_init;
1110 break;
1111 case MODEL_DX:
1112 chip->model.init = xonar_dx_init;
1113 break;
1114 case MODEL_HDAV:
1115 oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_DB_MASK);
1116 switch (oxygen_read16(chip, OXYGEN_GPIO_DATA) & GPIO_DB_MASK) {
1117 case GPIO_DB_H6:
1118 model = MODEL_HDAV_H6;
1119 break;
1120 case GPIO_DB_XX:
1121 snd_printk(KERN_ERR "unknown daughterboard\n");
1122 return -ENODEV;
1123 }
1124 break;
1125 case MODEL_ST:
1126 oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_DB_MASK);
1127 switch (oxygen_read16(chip, OXYGEN_GPIO_DATA) & GPIO_DB_MASK) {
1128 case GPIO_DB_H6:
1129 model = MODEL_ST_H6;
1130 break;
1131 }
1132 break;
1133 case MODEL_STX:
1134 chip->model.init = xonar_stx_init;
1135 oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_DB_MASK);
1136 break;
1137 }
1138
1139 chip->model.shortname = names[model];
1140 chip->model.private_data = model;
1141 return 0;
1142} 68}
1143 69
1144static int __devinit xonar_probe(struct pci_dev *pci, 70static int __devinit xonar_probe(struct pci_dev *pci,
diff --git a/sound/pci/oxygen/wm8766.h b/sound/pci/oxygen/wm8766.h
new file mode 100644
index 000000000000..e0e849a7eaeb
--- /dev/null
+++ b/sound/pci/oxygen/wm8766.h
@@ -0,0 +1,73 @@
1#ifndef WM8766_H_INCLUDED
2#define WM8766_H_INCLUDED
3
4#define WM8766_LDA1 0x00
5#define WM8766_RDA1 0x01
6#define WM8766_DAC_CTRL 0x02
7#define WM8766_INT_CTRL 0x03
8#define WM8766_LDA2 0x04
9#define WM8766_RDA2 0x05
10#define WM8766_LDA3 0x06
11#define WM8766_RDA3 0x07
12#define WM8766_MASTDA 0x08
13#define WM8766_DAC_CTRL2 0x09
14#define WM8766_DAC_CTRL3 0x0a
15#define WM8766_MUTE1 0x0c
16#define WM8766_MUTE2 0x0f
17#define WM8766_RESET 0x1f
18
19/* LDAx/RDAx/MASTDA */
20#define WM8766_ATT_MASK 0x0ff
21#define WM8766_UPDATE 0x100
22/* DAC_CTRL */
23#define WM8766_MUTEALL 0x001
24#define WM8766_DEEMPALL 0x002
25#define WM8766_PWDN 0x004
26#define WM8766_ATC 0x008
27#define WM8766_IZD 0x010
28#define WM8766_PL_LEFT_MASK 0x060
29#define WM8766_PL_LEFT_MUTE 0x000
30#define WM8766_PL_LEFT_LEFT 0x020
31#define WM8766_PL_LEFT_RIGHT 0x040
32#define WM8766_PL_LEFT_LRMIX 0x060
33#define WM8766_PL_RIGHT_MASK 0x180
34#define WM8766_PL_RIGHT_MUTE 0x000
35#define WM8766_PL_RIGHT_LEFT 0x080
36#define WM8766_PL_RIGHT_RIGHT 0x100
37#define WM8766_PL_RIGHT_LRMIX 0x180
38/* INT_CTRL */
39#define WM8766_FMT_MASK 0x003
40#define WM8766_FMT_RJUST 0x000
41#define WM8766_FMT_LJUST 0x001
42#define WM8766_FMT_I2S 0x002
43#define WM8766_FMT_DSP 0x003
44#define WM8766_LRP 0x004
45#define WM8766_BCP 0x008
46#define WM8766_IWL_MASK 0x030
47#define WM8766_IWL_16 0x000
48#define WM8766_IWL_20 0x010
49#define WM8766_IWL_24 0x020
50#define WM8766_IWL_32 0x030
51#define WM8766_PHASE_MASK 0x1c0
52/* DAC_CTRL2 */
53#define WM8766_ZCD 0x001
54#define WM8766_DZFM_MASK 0x006
55#define WM8766_DMUTE_MASK 0x038
56#define WM8766_DEEMP_MASK 0x1c0
57/* DAC_CTRL3 */
58#define WM8766_DACPD_MASK 0x00e
59#define WM8766_PWRDNALL 0x010
60#define WM8766_MS 0x020
61#define WM8766_RATE_MASK 0x1c0
62#define WM8766_RATE_128 0x000
63#define WM8766_RATE_192 0x040
64#define WM8766_RATE_256 0x080
65#define WM8766_RATE_384 0x0c0
66#define WM8766_RATE_512 0x100
67#define WM8766_RATE_768 0x140
68/* MUTE1 */
69#define WM8766_MPD1 0x040
70/* MUTE2 */
71#define WM8766_MPD2 0x020
72
73#endif
diff --git a/sound/pci/oxygen/wm8776.h b/sound/pci/oxygen/wm8776.h
new file mode 100644
index 000000000000..1a96f5615727
--- /dev/null
+++ b/sound/pci/oxygen/wm8776.h
@@ -0,0 +1,177 @@
1#ifndef WM8776_H_INCLUDED
2#define WM8776_H_INCLUDED
3
4/*
5 * the following register names are from:
6 * wm8776.h -- WM8776 ASoC driver
7 *
8 * Copyright 2009 Wolfson Microelectronics plc
9 *
10 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 */
16
17#define WM8776_HPLVOL 0x00
18#define WM8776_HPRVOL 0x01
19#define WM8776_HPMASTER 0x02
20#define WM8776_DACLVOL 0x03
21#define WM8776_DACRVOL 0x04
22#define WM8776_DACMASTER 0x05
23#define WM8776_PHASESWAP 0x06
24#define WM8776_DACCTRL1 0x07
25#define WM8776_DACMUTE 0x08
26#define WM8776_DACCTRL2 0x09
27#define WM8776_DACIFCTRL 0x0a
28#define WM8776_ADCIFCTRL 0x0b
29#define WM8776_MSTRCTRL 0x0c
30#define WM8776_PWRDOWN 0x0d
31#define WM8776_ADCLVOL 0x0e
32#define WM8776_ADCRVOL 0x0f
33#define WM8776_ALCCTRL1 0x10
34#define WM8776_ALCCTRL2 0x11
35#define WM8776_ALCCTRL3 0x12
36#define WM8776_NOISEGATE 0x13
37#define WM8776_LIMITER 0x14
38#define WM8776_ADCMUX 0x15
39#define WM8776_OUTMUX 0x16
40#define WM8776_RESET 0x17
41
42
43/* HPLVOL/HPRVOL/HPMASTER */
44#define WM8776_HPATT_MASK 0x07f
45#define WM8776_HPZCEN 0x080
46#define WM8776_UPDATE 0x100
47
48/* DACLVOL/DACRVOL/DACMASTER */
49#define WM8776_DATT_MASK 0x0ff
50/*#define WM8776_UPDATE 0x100*/
51
52/* PHASESWAP */
53#define WM8776_PH_MASK 0x003
54
55/* DACCTRL1 */
56#define WM8776_DZCEN 0x001
57#define WM8776_ATC 0x002
58#define WM8776_IZD 0x004
59#define WM8776_TOD 0x008
60#define WM8776_PL_LEFT_MASK 0x030
61#define WM8776_PL_LEFT_MUTE 0x000
62#define WM8776_PL_LEFT_LEFT 0x010
63#define WM8776_PL_LEFT_RIGHT 0x020
64#define WM8776_PL_LEFT_LRMIX 0x030
65#define WM8776_PL_RIGHT_MASK 0x0c0
66#define WM8776_PL_RIGHT_MUTE 0x000
67#define WM8776_PL_RIGHT_LEFT 0x040
68#define WM8776_PL_RIGHT_RIGHT 0x080
69#define WM8776_PL_RIGHT_LRMIX 0x0c0
70
71/* DACMUTE */
72#define WM8776_DMUTE 0x001
73
74/* DACCTRL2 */
75#define WM8776_DEEMPH 0x001
76#define WM8776_DZFM_MASK 0x006
77#define WM8776_DZFM_NONE 0x000
78#define WM8776_DZFM_LR 0x002
79#define WM8776_DZFM_BOTH 0x004
80#define WM8776_DZFM_EITHER 0x006
81
82/* DACIFCTRL */
83#define WM8776_DACFMT_MASK 0x003
84#define WM8776_DACFMT_RJUST 0x000
85#define WM8776_DACFMT_LJUST 0x001
86#define WM8776_DACFMT_I2S 0x002
87#define WM8776_DACFMT_DSP 0x003
88#define WM8776_DACLRP 0x004
89#define WM8776_DACBCP 0x008
90#define WM8776_DACWL_MASK 0x030
91#define WM8776_DACWL_16 0x000
92#define WM8776_DACWL_20 0x010
93#define WM8776_DACWL_24 0x020
94#define WM8776_DACWL_32 0x030
95
96/* ADCIFCTRL */
97#define WM8776_ADCFMT_MASK 0x003
98#define WM8776_ADCFMT_RJUST 0x000
99#define WM8776_ADCFMT_LJUST 0x001
100#define WM8776_ADCFMT_I2S 0x002
101#define WM8776_ADCFMT_DSP 0x003
102#define WM8776_ADCLRP 0x004
103#define WM8776_ADCBCP 0x008
104#define WM8776_ADCWL_MASK 0x030
105#define WM8776_ADCWL_16 0x000
106#define WM8776_ADCWL_20 0x010
107#define WM8776_ADCWL_24 0x020
108#define WM8776_ADCWL_32 0x030
109#define WM8776_ADCMCLK 0x040
110#define WM8776_ADCHPD 0x100
111
112/* MSTRCTRL */
113#define WM8776_ADCRATE_MASK 0x007
114#define WM8776_ADCRATE_256 0x002
115#define WM8776_ADCRATE_384 0x003
116#define WM8776_ADCRATE_512 0x004
117#define WM8776_ADCRATE_768 0x005
118#define WM8776_ADCOSR 0x008
119#define WM8776_DACRATE_MASK 0x070
120#define WM8776_DACRATE_128 0x000
121#define WM8776_DACRATE_192 0x010
122#define WM8776_DACRATE_256 0x020
123#define WM8776_DACRATE_384 0x030
124#define WM8776_DACRATE_512 0x040
125#define WM8776_DACRATE_768 0x050
126#define WM8776_DACMS 0x080
127#define WM8776_ADCMS 0x100
128
129/* PWRDOWN */
130#define WM8776_PDWN 0x001
131#define WM8776_ADCPD 0x002
132#define WM8776_DACPD 0x004
133#define WM8776_HPPD 0x008
134#define WM8776_AINPD 0x040
135
136/* ADCLVOL/ADCRVOL */
137#define WM8776_AGMASK 0x0ff
138#define WM8776_ZCA 0x100
139
140/* ALCCTRL1 */
141#define WM8776_LCT_MASK 0x00f
142#define WM8776_MAXGAIN_MASK 0x070
143#define WM8776_LCSEL_MASK 0x180
144#define WM8776_LCSEL_LIMITER 0x000
145#define WM8776_LCSEL_ALC_RIGHT 0x080
146#define WM8776_LCSEL_ALC_LEFT 0x100
147#define WM8776_LCSEL_ALC_STEREO 0x180
148
149/* ALCCTRL2 */
150#define WM8776_HLD_MASK 0x00f
151#define WM8776_ALCZC 0x080
152#define WM8776_LCEN 0x100
153
154/* ALCCTRL3 */
155#define WM8776_ATK_MASK 0x00f
156#define WM8776_DCY_MASK 0x0f0
157
158/* NOISEGATE */
159#define WM8776_NGAT 0x001
160#define WM8776_NGTH_MASK 0x01c
161
162/* LIMITER */
163#define WM8776_MAXATTEN_MASK 0x00f
164#define WM8776_TRANWIN_MASK 0x070
165
166/* ADCMUX */
167#define WM8776_AMX_MASK 0x01f
168#define WM8776_MUTERA 0x040
169#define WM8776_MUTELA 0x080
170#define WM8776_LRBOTH 0x100
171
172/* OUTMUX */
173#define WM8776_MX_DAC 0x001
174#define WM8776_MX_AUX 0x002
175#define WM8776_MX_BYPASS 0x004
176
177#endif
diff --git a/sound/pci/oxygen/xonar.h b/sound/pci/oxygen/xonar.h
new file mode 100644
index 000000000000..b35343b0a9a5
--- /dev/null
+++ b/sound/pci/oxygen/xonar.h
@@ -0,0 +1,52 @@
1#ifndef XONAR_H_INCLUDED
2#define XONAR_H_INCLUDED
3
4#include "oxygen.h"
5
6struct xonar_generic {
7 unsigned int anti_pop_delay;
8 u16 output_enable_bit;
9 u8 ext_power_reg;
10 u8 ext_power_int_reg;
11 u8 ext_power_bit;
12 u8 has_power;
13};
14
15struct xonar_hdmi {
16 u8 params[5];
17};
18
19/* generic helper functions */
20
21void xonar_enable_output(struct oxygen *chip);
22void xonar_disable_output(struct oxygen *chip);
23void xonar_init_ext_power(struct oxygen *chip);
24void xonar_init_cs53x1(struct oxygen *chip);
25void xonar_set_cs53x1_params(struct oxygen *chip,
26 struct snd_pcm_hw_params *params);
27int xonar_gpio_bit_switch_get(struct snd_kcontrol *ctl,
28 struct snd_ctl_elem_value *value);
29int xonar_gpio_bit_switch_put(struct snd_kcontrol *ctl,
30 struct snd_ctl_elem_value *value);
31
32/* model-specific card drivers */
33
34int get_xonar_pcm179x_model(struct oxygen *chip,
35 const struct pci_device_id *id);
36int get_xonar_cs43xx_model(struct oxygen *chip,
37 const struct pci_device_id *id);
38int get_xonar_wm87x6_model(struct oxygen *chip,
39 const struct pci_device_id *id);
40
41/* HDMI helper functions */
42
43void xonar_hdmi_init(struct oxygen *chip, struct xonar_hdmi *data);
44void xonar_hdmi_cleanup(struct oxygen *chip);
45void xonar_hdmi_resume(struct oxygen *chip, struct xonar_hdmi *hdmi);
46void xonar_hdmi_pcm_hardware_filter(unsigned int channel,
47 struct snd_pcm_hardware *hardware);
48void xonar_set_hdmi_params(struct oxygen *chip, struct xonar_hdmi *hdmi,
49 struct snd_pcm_hw_params *params);
50void xonar_hdmi_uart_input(struct oxygen *chip);
51
52#endif
diff --git a/sound/pci/oxygen/xonar_cs43xx.c b/sound/pci/oxygen/xonar_cs43xx.c
new file mode 100644
index 000000000000..7c4986b27f2b
--- /dev/null
+++ b/sound/pci/oxygen/xonar_cs43xx.c
@@ -0,0 +1,437 @@
1/*
2 * card driver for models with CS4398/CS4362A DACs (Xonar D1/DX)
3 *
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5 *
6 *
7 * This driver is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License, version 2.
9 *
10 * This driver is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this driver; if not, see <http://www.gnu.org/licenses/>.
17 */
18
19/*
20 * Xonar D1/DX
21 * -----------
22 *
23 * CMI8788:
24 *
25 * I²C <-> CS4398 (front)
26 * <-> CS4362A (surround, center/LFE, back)
27 *
28 * GPI 0 <- external power present (DX only)
29 *
30 * GPIO 0 -> enable output to speakers
31 * GPIO 1 -> enable front panel I/O
32 * GPIO 2 -> M0 of CS5361
33 * GPIO 3 -> M1 of CS5361
34 * GPIO 8 -> route input jack to line-in (0) or mic-in (1)
35 *
36 * CS4398:
37 *
38 * AD0 <- 1
39 * AD1 <- 1
40 *
41 * CS4362A:
42 *
43 * AD0 <- 0
44 *
45 * CM9780:
46 *
47 * GPO 0 -> route line-in (0) or AC97 output (1) to CS5361 input
48 */
49
50#include <linux/pci.h>
51#include <linux/delay.h>
52#include <sound/ac97_codec.h>
53#include <sound/control.h>
54#include <sound/core.h>
55#include <sound/pcm.h>
56#include <sound/pcm_params.h>
57#include <sound/tlv.h>
58#include "xonar.h"
59#include "cm9780.h"
60#include "cs4398.h"
61#include "cs4362a.h"
62
63#define GPI_EXT_POWER 0x01
64#define GPIO_D1_OUTPUT_ENABLE 0x0001
65#define GPIO_D1_FRONT_PANEL 0x0002
66#define GPIO_D1_INPUT_ROUTE 0x0100
67
68#define I2C_DEVICE_CS4398 0x9e /* 10011, AD1=1, AD0=1, /W=0 */
69#define I2C_DEVICE_CS4362A 0x30 /* 001100, AD0=0, /W=0 */
70
71struct xonar_cs43xx {
72 struct xonar_generic generic;
73 u8 cs4398_regs[8];
74 u8 cs4362a_regs[15];
75};
76
77static void cs4398_write(struct oxygen *chip, u8 reg, u8 value)
78{
79 struct xonar_cs43xx *data = chip->model_data;
80
81 oxygen_write_i2c(chip, I2C_DEVICE_CS4398, reg, value);
82 if (reg < ARRAY_SIZE(data->cs4398_regs))
83 data->cs4398_regs[reg] = value;
84}
85
86static void cs4398_write_cached(struct oxygen *chip, u8 reg, u8 value)
87{
88 struct xonar_cs43xx *data = chip->model_data;
89
90 if (value != data->cs4398_regs[reg])
91 cs4398_write(chip, reg, value);
92}
93
94static void cs4362a_write(struct oxygen *chip, u8 reg, u8 value)
95{
96 struct xonar_cs43xx *data = chip->model_data;
97
98 oxygen_write_i2c(chip, I2C_DEVICE_CS4362A, reg, value);
99 if (reg < ARRAY_SIZE(data->cs4362a_regs))
100 data->cs4362a_regs[reg] = value;
101}
102
103static void cs4362a_write_cached(struct oxygen *chip, u8 reg, u8 value)
104{
105 struct xonar_cs43xx *data = chip->model_data;
106
107 if (value != data->cs4362a_regs[reg])
108 cs4362a_write(chip, reg, value);
109}
110
111static void cs43xx_registers_init(struct oxygen *chip)
112{
113 struct xonar_cs43xx *data = chip->model_data;
114 unsigned int i;
115
116 /* set CPEN (control port mode) and power down */
117 cs4398_write(chip, 8, CS4398_CPEN | CS4398_PDN);
118 cs4362a_write(chip, 0x01, CS4362A_PDN | CS4362A_CPEN);
119 /* configure */
120 cs4398_write(chip, 2, data->cs4398_regs[2]);
121 cs4398_write(chip, 3, CS4398_ATAPI_B_R | CS4398_ATAPI_A_L);
122 cs4398_write(chip, 4, data->cs4398_regs[4]);
123 cs4398_write(chip, 5, data->cs4398_regs[5]);
124 cs4398_write(chip, 6, data->cs4398_regs[6]);
125 cs4398_write(chip, 7, data->cs4398_regs[7]);
126 cs4362a_write(chip, 0x02, CS4362A_DIF_LJUST);
127 cs4362a_write(chip, 0x03, CS4362A_MUTEC_6 | CS4362A_AMUTE |
128 CS4362A_RMP_UP | CS4362A_ZERO_CROSS | CS4362A_SOFT_RAMP);
129 cs4362a_write(chip, 0x04, data->cs4362a_regs[0x04]);
130 cs4362a_write(chip, 0x05, 0);
131 for (i = 6; i <= 14; ++i)
132 cs4362a_write(chip, i, data->cs4362a_regs[i]);
133 /* clear power down */
134 cs4398_write(chip, 8, CS4398_CPEN);
135 cs4362a_write(chip, 0x01, CS4362A_CPEN);
136}
137
138static void xonar_d1_init(struct oxygen *chip)
139{
140 struct xonar_cs43xx *data = chip->model_data;
141
142 data->generic.anti_pop_delay = 800;
143 data->generic.output_enable_bit = GPIO_D1_OUTPUT_ENABLE;
144 data->cs4398_regs[2] =
145 CS4398_FM_SINGLE | CS4398_DEM_NONE | CS4398_DIF_LJUST;
146 data->cs4398_regs[4] = CS4398_MUTEP_LOW |
147 CS4398_MUTE_B | CS4398_MUTE_A | CS4398_PAMUTE;
148 data->cs4398_regs[5] = 60 * 2;
149 data->cs4398_regs[6] = 60 * 2;
150 data->cs4398_regs[7] = CS4398_RMP_DN | CS4398_RMP_UP |
151 CS4398_ZERO_CROSS | CS4398_SOFT_RAMP;
152 data->cs4362a_regs[4] = CS4362A_RMP_DN | CS4362A_DEM_NONE;
153 data->cs4362a_regs[6] = CS4362A_FM_SINGLE |
154 CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L;
155 data->cs4362a_regs[7] = 60 | CS4362A_MUTE;
156 data->cs4362a_regs[8] = 60 | CS4362A_MUTE;
157 data->cs4362a_regs[9] = data->cs4362a_regs[6];
158 data->cs4362a_regs[10] = 60 | CS4362A_MUTE;
159 data->cs4362a_regs[11] = 60 | CS4362A_MUTE;
160 data->cs4362a_regs[12] = data->cs4362a_regs[6];
161 data->cs4362a_regs[13] = 60 | CS4362A_MUTE;
162 data->cs4362a_regs[14] = 60 | CS4362A_MUTE;
163
164 oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS,
165 OXYGEN_2WIRE_LENGTH_8 |
166 OXYGEN_2WIRE_INTERRUPT_MASK |
167 OXYGEN_2WIRE_SPEED_FAST);
168
169 cs43xx_registers_init(chip);
170
171 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
172 GPIO_D1_FRONT_PANEL | GPIO_D1_INPUT_ROUTE);
173 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA,
174 GPIO_D1_FRONT_PANEL | GPIO_D1_INPUT_ROUTE);
175
176 oxygen_ac97_set_bits(chip, 0, CM9780_JACK, CM9780_FMIC2MIC);
177
178 xonar_init_cs53x1(chip);
179 xonar_enable_output(chip);
180
181 snd_component_add(chip->card, "CS4398");
182 snd_component_add(chip->card, "CS4362A");
183 snd_component_add(chip->card, "CS5361");
184}
185
186static void xonar_dx_init(struct oxygen *chip)
187{
188 struct xonar_cs43xx *data = chip->model_data;
189
190 data->generic.ext_power_reg = OXYGEN_GPI_DATA;
191 data->generic.ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK;
192 data->generic.ext_power_bit = GPI_EXT_POWER;
193 xonar_init_ext_power(chip);
194 xonar_d1_init(chip);
195}
196
197static void xonar_d1_cleanup(struct oxygen *chip)
198{
199 xonar_disable_output(chip);
200 cs4362a_write(chip, 0x01, CS4362A_PDN | CS4362A_CPEN);
201 oxygen_clear_bits8(chip, OXYGEN_FUNCTION, OXYGEN_FUNCTION_RESET_CODEC);
202}
203
204static void xonar_d1_suspend(struct oxygen *chip)
205{
206 xonar_d1_cleanup(chip);
207}
208
209static void xonar_d1_resume(struct oxygen *chip)
210{
211 oxygen_set_bits8(chip, OXYGEN_FUNCTION, OXYGEN_FUNCTION_RESET_CODEC);
212 msleep(1);
213 cs43xx_registers_init(chip);
214 xonar_enable_output(chip);
215}
216
217static void set_cs43xx_params(struct oxygen *chip,
218 struct snd_pcm_hw_params *params)
219{
220 struct xonar_cs43xx *data = chip->model_data;
221 u8 cs4398_fm, cs4362a_fm;
222
223 if (params_rate(params) <= 50000) {
224 cs4398_fm = CS4398_FM_SINGLE;
225 cs4362a_fm = CS4362A_FM_SINGLE;
226 } else if (params_rate(params) <= 100000) {
227 cs4398_fm = CS4398_FM_DOUBLE;
228 cs4362a_fm = CS4362A_FM_DOUBLE;
229 } else {
230 cs4398_fm = CS4398_FM_QUAD;
231 cs4362a_fm = CS4362A_FM_QUAD;
232 }
233 cs4398_fm |= CS4398_DEM_NONE | CS4398_DIF_LJUST;
234 cs4398_write_cached(chip, 2, cs4398_fm);
235 cs4362a_fm |= data->cs4362a_regs[6] & ~CS4362A_FM_MASK;
236 cs4362a_write_cached(chip, 6, cs4362a_fm);
237 cs4362a_write_cached(chip, 12, cs4362a_fm);
238 cs4362a_fm &= CS4362A_FM_MASK;
239 cs4362a_fm |= data->cs4362a_regs[9] & ~CS4362A_FM_MASK;
240 cs4362a_write_cached(chip, 9, cs4362a_fm);
241}
242
243static void update_cs4362a_volumes(struct oxygen *chip)
244{
245 unsigned int i;
246 u8 mute;
247
248 mute = chip->dac_mute ? CS4362A_MUTE : 0;
249 for (i = 0; i < 6; ++i)
250 cs4362a_write_cached(chip, 7 + i + i / 2,
251 (127 - chip->dac_volume[2 + i]) | mute);
252}
253
254static void update_cs43xx_volume(struct oxygen *chip)
255{
256 cs4398_write_cached(chip, 5, (127 - chip->dac_volume[0]) * 2);
257 cs4398_write_cached(chip, 6, (127 - chip->dac_volume[1]) * 2);
258 update_cs4362a_volumes(chip);
259}
260
261static void update_cs43xx_mute(struct oxygen *chip)
262{
263 u8 reg;
264
265 reg = CS4398_MUTEP_LOW | CS4398_PAMUTE;
266 if (chip->dac_mute)
267 reg |= CS4398_MUTE_B | CS4398_MUTE_A;
268 cs4398_write_cached(chip, 4, reg);
269 update_cs4362a_volumes(chip);
270}
271
272static void update_cs43xx_center_lfe_mix(struct oxygen *chip, bool mixed)
273{
274 struct xonar_cs43xx *data = chip->model_data;
275 u8 reg;
276
277 reg = data->cs4362a_regs[9] & ~CS4362A_ATAPI_MASK;
278 if (mixed)
279 reg |= CS4362A_ATAPI_B_LR | CS4362A_ATAPI_A_LR;
280 else
281 reg |= CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L;
282 cs4362a_write_cached(chip, 9, reg);
283}
284
285static const struct snd_kcontrol_new front_panel_switch = {
286 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
287 .name = "Front Panel Switch",
288 .info = snd_ctl_boolean_mono_info,
289 .get = xonar_gpio_bit_switch_get,
290 .put = xonar_gpio_bit_switch_put,
291 .private_value = GPIO_D1_FRONT_PANEL,
292};
293
294static int rolloff_info(struct snd_kcontrol *ctl,
295 struct snd_ctl_elem_info *info)
296{
297 static const char *const names[2] = {
298 "Fast Roll-off", "Slow Roll-off"
299 };
300
301 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
302 info->count = 1;
303 info->value.enumerated.items = 2;
304 if (info->value.enumerated.item >= 2)
305 info->value.enumerated.item = 1;
306 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
307 return 0;
308}
309
310static int rolloff_get(struct snd_kcontrol *ctl,
311 struct snd_ctl_elem_value *value)
312{
313 struct oxygen *chip = ctl->private_data;
314 struct xonar_cs43xx *data = chip->model_data;
315
316 value->value.enumerated.item[0] =
317 (data->cs4398_regs[7] & CS4398_FILT_SEL) != 0;
318 return 0;
319}
320
321static int rolloff_put(struct snd_kcontrol *ctl,
322 struct snd_ctl_elem_value *value)
323{
324 struct oxygen *chip = ctl->private_data;
325 struct xonar_cs43xx *data = chip->model_data;
326 int changed;
327 u8 reg;
328
329 mutex_lock(&chip->mutex);
330 reg = data->cs4398_regs[7];
331 if (value->value.enumerated.item[0])
332 reg |= CS4398_FILT_SEL;
333 else
334 reg &= ~CS4398_FILT_SEL;
335 changed = reg != data->cs4398_regs[7];
336 if (changed) {
337 cs4398_write(chip, 7, reg);
338 if (reg & CS4398_FILT_SEL)
339 reg = data->cs4362a_regs[0x04] | CS4362A_FILT_SEL;
340 else
341 reg = data->cs4362a_regs[0x04] & ~CS4362A_FILT_SEL;
342 cs4362a_write(chip, 0x04, reg);
343 }
344 mutex_unlock(&chip->mutex);
345 return changed;
346}
347
348static const struct snd_kcontrol_new rolloff_control = {
349 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
350 .name = "DAC Filter Playback Enum",
351 .info = rolloff_info,
352 .get = rolloff_get,
353 .put = rolloff_put,
354};
355
356static void xonar_d1_line_mic_ac97_switch(struct oxygen *chip,
357 unsigned int reg, unsigned int mute)
358{
359 if (reg == AC97_LINE) {
360 spin_lock_irq(&chip->reg_lock);
361 oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
362 mute ? GPIO_D1_INPUT_ROUTE : 0,
363 GPIO_D1_INPUT_ROUTE);
364 spin_unlock_irq(&chip->reg_lock);
365 }
366}
367
368static const DECLARE_TLV_DB_SCALE(cs4362a_db_scale, -6000, 100, 0);
369
370static int xonar_d1_control_filter(struct snd_kcontrol_new *template)
371{
372 if (!strncmp(template->name, "CD Capture ", 11))
373 return 1; /* no CD input */
374 return 0;
375}
376
377static int xonar_d1_mixer_init(struct oxygen *chip)
378{
379 int err;
380
381 err = snd_ctl_add(chip->card, snd_ctl_new1(&front_panel_switch, chip));
382 if (err < 0)
383 return err;
384 err = snd_ctl_add(chip->card, snd_ctl_new1(&rolloff_control, chip));
385 if (err < 0)
386 return err;
387 return 0;
388}
389
390static const struct oxygen_model model_xonar_d1 = {
391 .longname = "Asus Virtuoso 100",
392 .chip = "AV200",
393 .init = xonar_d1_init,
394 .control_filter = xonar_d1_control_filter,
395 .mixer_init = xonar_d1_mixer_init,
396 .cleanup = xonar_d1_cleanup,
397 .suspend = xonar_d1_suspend,
398 .resume = xonar_d1_resume,
399 .get_i2s_mclk = oxygen_default_i2s_mclk,
400 .set_dac_params = set_cs43xx_params,
401 .set_adc_params = xonar_set_cs53x1_params,
402 .update_dac_volume = update_cs43xx_volume,
403 .update_dac_mute = update_cs43xx_mute,
404 .update_center_lfe_mix = update_cs43xx_center_lfe_mix,
405 .ac97_switch = xonar_d1_line_mic_ac97_switch,
406 .dac_tlv = cs4362a_db_scale,
407 .model_data_size = sizeof(struct xonar_cs43xx),
408 .device_config = PLAYBACK_0_TO_I2S |
409 PLAYBACK_1_TO_SPDIF |
410 CAPTURE_0_FROM_I2S_2,
411 .dac_channels = 8,
412 .dac_volume_min = 127 - 60,
413 .dac_volume_max = 127,
414 .function_flags = OXYGEN_FUNCTION_2WIRE,
415 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
416 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
417};
418
419int __devinit get_xonar_cs43xx_model(struct oxygen *chip,
420 const struct pci_device_id *id)
421{
422 switch (id->subdevice) {
423 case 0x834f:
424 chip->model = model_xonar_d1;
425 chip->model.shortname = "Xonar D1";
426 break;
427 case 0x8275:
428 case 0x8327:
429 chip->model = model_xonar_d1;
430 chip->model.shortname = "Xonar DX";
431 chip->model.init = xonar_dx_init;
432 break;
433 default:
434 return -EINVAL;
435 }
436 return 0;
437}
diff --git a/sound/pci/oxygen/xonar_hdmi.c b/sound/pci/oxygen/xonar_hdmi.c
new file mode 100644
index 000000000000..b12db1f1cea9
--- /dev/null
+++ b/sound/pci/oxygen/xonar_hdmi.c
@@ -0,0 +1,128 @@
1/*
2 * helper functions for HDMI models (Xonar HDAV1.3)
3 *
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5 *
6 *
7 * This driver is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License, version 2.
9 *
10 * This driver is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this driver; if not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <linux/pci.h>
20#include <linux/delay.h>
21#include <sound/asoundef.h>
22#include <sound/control.h>
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26#include <sound/tlv.h>
27#include "xonar.h"
28
29static void hdmi_write_command(struct oxygen *chip, u8 command,
30 unsigned int count, const u8 *params)
31{
32 unsigned int i;
33 u8 checksum;
34
35 oxygen_write_uart(chip, 0xfb);
36 oxygen_write_uart(chip, 0xef);
37 oxygen_write_uart(chip, command);
38 oxygen_write_uart(chip, count);
39 for (i = 0; i < count; ++i)
40 oxygen_write_uart(chip, params[i]);
41 checksum = 0xfb + 0xef + command + count;
42 for (i = 0; i < count; ++i)
43 checksum += params[i];
44 oxygen_write_uart(chip, checksum);
45}
46
47static void xonar_hdmi_init_commands(struct oxygen *chip,
48 struct xonar_hdmi *hdmi)
49{
50 u8 param;
51
52 oxygen_reset_uart(chip);
53 param = 0;
54 hdmi_write_command(chip, 0x61, 1, &param);
55 param = 1;
56 hdmi_write_command(chip, 0x74, 1, &param);
57 hdmi_write_command(chip, 0x54, 5, hdmi->params);
58}
59
60void xonar_hdmi_init(struct oxygen *chip, struct xonar_hdmi *hdmi)
61{
62 hdmi->params[1] = IEC958_AES3_CON_FS_48000;
63 hdmi->params[4] = 1;
64 xonar_hdmi_init_commands(chip, hdmi);
65}
66
67void xonar_hdmi_cleanup(struct oxygen *chip)
68{
69 u8 param = 0;
70
71 hdmi_write_command(chip, 0x74, 1, &param);
72}
73
74void xonar_hdmi_resume(struct oxygen *chip, struct xonar_hdmi *hdmi)
75{
76 xonar_hdmi_init_commands(chip, hdmi);
77}
78
79void xonar_hdmi_pcm_hardware_filter(unsigned int channel,
80 struct snd_pcm_hardware *hardware)
81{
82 if (channel == PCM_MULTICH) {
83 hardware->rates = SNDRV_PCM_RATE_44100 |
84 SNDRV_PCM_RATE_48000 |
85 SNDRV_PCM_RATE_96000 |
86 SNDRV_PCM_RATE_192000;
87 hardware->rate_min = 44100;
88 }
89}
90
91void xonar_set_hdmi_params(struct oxygen *chip, struct xonar_hdmi *hdmi,
92 struct snd_pcm_hw_params *params)
93{
94 hdmi->params[0] = 0; /* 1 = non-audio */
95 switch (params_rate(params)) {
96 case 44100:
97 hdmi->params[1] = IEC958_AES3_CON_FS_44100;
98 break;
99 case 48000:
100 hdmi->params[1] = IEC958_AES3_CON_FS_48000;
101 break;
102 default: /* 96000 */
103 hdmi->params[1] = IEC958_AES3_CON_FS_96000;
104 break;
105 case 192000:
106 hdmi->params[1] = IEC958_AES3_CON_FS_192000;
107 break;
108 }
109 hdmi->params[2] = params_channels(params) / 2 - 1;
110 if (params_format(params) == SNDRV_PCM_FORMAT_S16_LE)
111 hdmi->params[3] = 0;
112 else
113 hdmi->params[3] = 0xc0;
114 hdmi->params[4] = 1; /* ? */
115 hdmi_write_command(chip, 0x54, 5, hdmi->params);
116}
117
118void xonar_hdmi_uart_input(struct oxygen *chip)
119{
120 if (chip->uart_input_count >= 2 &&
121 chip->uart_input[chip->uart_input_count - 2] == 'O' &&
122 chip->uart_input[chip->uart_input_count - 1] == 'K') {
123 printk(KERN_DEBUG "message from HDMI chip received:\n");
124 print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
125 chip->uart_input, chip->uart_input_count);
126 chip->uart_input_count = 0;
127 }
128}
diff --git a/sound/pci/oxygen/xonar_lib.c b/sound/pci/oxygen/xonar_lib.c
new file mode 100644
index 000000000000..b3ff71316653
--- /dev/null
+++ b/sound/pci/oxygen/xonar_lib.c
@@ -0,0 +1,132 @@
1/*
2 * helper functions for Asus Xonar cards
3 *
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5 *
6 *
7 * This driver is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License, version 2.
9 *
10 * This driver is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this driver; if not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <linux/delay.h>
20#include <sound/core.h>
21#include <sound/control.h>
22#include <sound/pcm.h>
23#include <sound/pcm_params.h>
24#include "xonar.h"
25
26
27#define GPIO_CS53x1_M_MASK 0x000c
28#define GPIO_CS53x1_M_SINGLE 0x0000
29#define GPIO_CS53x1_M_DOUBLE 0x0004
30#define GPIO_CS53x1_M_QUAD 0x0008
31
32
33void xonar_enable_output(struct oxygen *chip)
34{
35 struct xonar_generic *data = chip->model_data;
36
37 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, data->output_enable_bit);
38 msleep(data->anti_pop_delay);
39 oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, data->output_enable_bit);
40}
41
42void xonar_disable_output(struct oxygen *chip)
43{
44 struct xonar_generic *data = chip->model_data;
45
46 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, data->output_enable_bit);
47}
48
49static void xonar_ext_power_gpio_changed(struct oxygen *chip)
50{
51 struct xonar_generic *data = chip->model_data;
52 u8 has_power;
53
54 has_power = !!(oxygen_read8(chip, data->ext_power_reg)
55 & data->ext_power_bit);
56 if (has_power != data->has_power) {
57 data->has_power = has_power;
58 if (has_power) {
59 snd_printk(KERN_NOTICE "power restored\n");
60 } else {
61 snd_printk(KERN_CRIT
62 "Hey! Don't unplug the power cable!\n");
63 /* TODO: stop PCMs */
64 }
65 }
66}
67
68void xonar_init_ext_power(struct oxygen *chip)
69{
70 struct xonar_generic *data = chip->model_data;
71
72 oxygen_set_bits8(chip, data->ext_power_int_reg,
73 data->ext_power_bit);
74 chip->interrupt_mask |= OXYGEN_INT_GPIO;
75 chip->model.gpio_changed = xonar_ext_power_gpio_changed;
76 data->has_power = !!(oxygen_read8(chip, data->ext_power_reg)
77 & data->ext_power_bit);
78}
79
80void xonar_init_cs53x1(struct oxygen *chip)
81{
82 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_CS53x1_M_MASK);
83 oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
84 GPIO_CS53x1_M_SINGLE, GPIO_CS53x1_M_MASK);
85}
86
87void xonar_set_cs53x1_params(struct oxygen *chip,
88 struct snd_pcm_hw_params *params)
89{
90 unsigned int value;
91
92 if (params_rate(params) <= 54000)
93 value = GPIO_CS53x1_M_SINGLE;
94 else if (params_rate(params) <= 108000)
95 value = GPIO_CS53x1_M_DOUBLE;
96 else
97 value = GPIO_CS53x1_M_QUAD;
98 oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
99 value, GPIO_CS53x1_M_MASK);
100}
101
102int xonar_gpio_bit_switch_get(struct snd_kcontrol *ctl,
103 struct snd_ctl_elem_value *value)
104{
105 struct oxygen *chip = ctl->private_data;
106 u16 bit = ctl->private_value;
107
108 value->value.integer.value[0] =
109 !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) & bit);
110 return 0;
111}
112
113int xonar_gpio_bit_switch_put(struct snd_kcontrol *ctl,
114 struct snd_ctl_elem_value *value)
115{
116 struct oxygen *chip = ctl->private_data;
117 u16 bit = ctl->private_value;
118 u16 old_bits, new_bits;
119 int changed;
120
121 spin_lock_irq(&chip->reg_lock);
122 old_bits = oxygen_read16(chip, OXYGEN_GPIO_DATA);
123 if (value->value.integer.value[0])
124 new_bits = old_bits | bit;
125 else
126 new_bits = old_bits & ~bit;
127 changed = new_bits != old_bits;
128 if (changed)
129 oxygen_write16(chip, OXYGEN_GPIO_DATA, new_bits);
130 spin_unlock_irq(&chip->reg_lock);
131 return changed;
132}
diff --git a/sound/pci/oxygen/xonar_pcm179x.c b/sound/pci/oxygen/xonar_pcm179x.c
new file mode 100644
index 000000000000..ba18fb546b4f
--- /dev/null
+++ b/sound/pci/oxygen/xonar_pcm179x.c
@@ -0,0 +1,1115 @@
1/*
2 * card driver for models with PCM1796 DACs (Xonar D2/D2X/HDAV1.3/ST/STX)
3 *
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5 *
6 *
7 * This driver is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License, version 2.
9 *
10 * This driver is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this driver; if not, see <http://www.gnu.org/licenses/>.
17 */
18
19/*
20 * Xonar D2/D2X
21 * ------------
22 *
23 * CMI8788:
24 *
25 * SPI 0 -> 1st PCM1796 (front)
26 * SPI 1 -> 2nd PCM1796 (surround)
27 * SPI 2 -> 3rd PCM1796 (center/LFE)
28 * SPI 4 -> 4th PCM1796 (back)
29 *
30 * GPIO 2 -> M0 of CS5381
31 * GPIO 3 -> M1 of CS5381
32 * GPIO 5 <- external power present (D2X only)
33 * GPIO 7 -> ALT
34 * GPIO 8 -> enable output to speakers
35 *
36 * CM9780:
37 *
38 * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input
39 */
40
41/*
42 * Xonar HDAV1.3 (Deluxe)
43 * ----------------------
44 *
45 * CMI8788:
46 *
47 * I²C <-> PCM1796 (front)
48 *
49 * GPI 0 <- external power present
50 *
51 * GPIO 0 -> enable output to speakers
52 * GPIO 2 -> M0 of CS5381
53 * GPIO 3 -> M1 of CS5381
54 * GPIO 8 -> route input jack to line-in (0) or mic-in (1)
55 *
56 * TXD -> HDMI controller
57 * RXD <- HDMI controller
58 *
59 * PCM1796 front: AD1,0 <- 0,0
60 *
61 * CM9780:
62 *
63 * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input
64 *
65 * no daughterboard
66 * ----------------
67 *
68 * GPIO 4 <- 1
69 *
70 * H6 daughterboard
71 * ----------------
72 *
73 * GPIO 4 <- 0
74 * GPIO 5 <- 0
75 *
76 * I²C <-> PCM1796 (surround)
77 * <-> PCM1796 (center/LFE)
78 * <-> PCM1796 (back)
79 *
80 * PCM1796 surround: AD1,0 <- 0,1
81 * PCM1796 center/LFE: AD1,0 <- 1,0
82 * PCM1796 back: AD1,0 <- 1,1
83 *
84 * unknown daughterboard
85 * ---------------------
86 *
87 * GPIO 4 <- 0
88 * GPIO 5 <- 1
89 *
90 * I²C <-> CS4362A (surround, center/LFE, back)
91 *
92 * CS4362A: AD0 <- 0
93 */
94
95/*
96 * Xonar Essence ST (Deluxe)/STX
97 * -----------------------------
98 *
99 * CMI8788:
100 *
101 * I²C <-> PCM1792A
102 * <-> CS2000 (ST only)
103 *
104 * ADC1 MCLK -> REF_CLK of CS2000 (ST only)
105 *
106 * GPI 0 <- external power present (STX only)
107 *
108 * GPIO 0 -> enable output to speakers
109 * GPIO 1 -> route HP to front panel (0) or rear jack (1)
110 * GPIO 2 -> M0 of CS5381
111 * GPIO 3 -> M1 of CS5381
112 * GPIO 7 -> route output to speaker jacks (0) or HP (1)
113 * GPIO 8 -> route input jack to line-in (0) or mic-in (1)
114 *
115 * PCM1792A:
116 *
117 * AD1,0 <- 0,0
118 * SCK <- CLK_OUT of CS2000 (ST only)
119 *
120 * CS2000:
121 *
122 * AD0 <- 0
123 *
124 * CM9780:
125 *
126 * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input
127 *
128 * H6 daughterboard
129 * ----------------
130 *
131 * GPIO 4 <- 0
132 * GPIO 5 <- 0
133 */
134
135#include <linux/pci.h>
136#include <linux/delay.h>
137#include <linux/mutex.h>
138#include <sound/ac97_codec.h>
139#include <sound/control.h>
140#include <sound/core.h>
141#include <sound/pcm.h>
142#include <sound/pcm_params.h>
143#include <sound/tlv.h>
144#include "xonar.h"
145#include "cm9780.h"
146#include "pcm1796.h"
147#include "cs2000.h"
148
149
150#define GPIO_D2X_EXT_POWER 0x0020
151#define GPIO_D2_ALT 0x0080
152#define GPIO_D2_OUTPUT_ENABLE 0x0100
153
154#define GPI_EXT_POWER 0x01
155#define GPIO_INPUT_ROUTE 0x0100
156
157#define GPIO_HDAV_OUTPUT_ENABLE 0x0001
158
159#define GPIO_DB_MASK 0x0030
160#define GPIO_DB_H6 0x0000
161
162#define GPIO_ST_OUTPUT_ENABLE 0x0001
163#define GPIO_ST_HP_REAR 0x0002
164#define GPIO_ST_HP 0x0080
165
166#define I2C_DEVICE_PCM1796(i) (0x98 + ((i) << 1)) /* 10011, ii, /W=0 */
167#define I2C_DEVICE_CS2000 0x9c /* 100111, 0, /W=0 */
168
169#define PCM1796_REG_BASE 16
170
171
172struct xonar_pcm179x {
173 struct xonar_generic generic;
174 unsigned int dacs;
175 u8 pcm1796_regs[4][5];
176 unsigned int current_rate;
177 bool os_128;
178 bool hp_active;
179 s8 hp_gain_offset;
180 bool has_cs2000;
181 u8 cs2000_fun_cfg_1;
182};
183
184struct xonar_hdav {
185 struct xonar_pcm179x pcm179x;
186 struct xonar_hdmi hdmi;
187};
188
189
190static inline void pcm1796_write_spi(struct oxygen *chip, unsigned int codec,
191 u8 reg, u8 value)
192{
193 /* maps ALSA channel pair number to SPI output */
194 static const u8 codec_map[4] = {
195 0, 1, 2, 4
196 };
197 oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
198 OXYGEN_SPI_DATA_LENGTH_2 |
199 OXYGEN_SPI_CLOCK_160 |
200 (codec_map[codec] << OXYGEN_SPI_CODEC_SHIFT) |
201 OXYGEN_SPI_CEN_LATCH_CLOCK_HI,
202 (reg << 8) | value);
203}
204
205static inline void pcm1796_write_i2c(struct oxygen *chip, unsigned int codec,
206 u8 reg, u8 value)
207{
208 oxygen_write_i2c(chip, I2C_DEVICE_PCM1796(codec), reg, value);
209}
210
211static void pcm1796_write(struct oxygen *chip, unsigned int codec,
212 u8 reg, u8 value)
213{
214 struct xonar_pcm179x *data = chip->model_data;
215
216 if ((chip->model.function_flags & OXYGEN_FUNCTION_2WIRE_SPI_MASK) ==
217 OXYGEN_FUNCTION_SPI)
218 pcm1796_write_spi(chip, codec, reg, value);
219 else
220 pcm1796_write_i2c(chip, codec, reg, value);
221 if ((unsigned int)(reg - PCM1796_REG_BASE)
222 < ARRAY_SIZE(data->pcm1796_regs[codec]))
223 data->pcm1796_regs[codec][reg - PCM1796_REG_BASE] = value;
224}
225
226static void pcm1796_write_cached(struct oxygen *chip, unsigned int codec,
227 u8 reg, u8 value)
228{
229 struct xonar_pcm179x *data = chip->model_data;
230
231 if (value != data->pcm1796_regs[codec][reg - PCM1796_REG_BASE])
232 pcm1796_write(chip, codec, reg, value);
233}
234
235static void cs2000_write(struct oxygen *chip, u8 reg, u8 value)
236{
237 struct xonar_pcm179x *data = chip->model_data;
238
239 oxygen_write_i2c(chip, I2C_DEVICE_CS2000, reg, value);
240 if (reg == CS2000_FUN_CFG_1)
241 data->cs2000_fun_cfg_1 = value;
242}
243
244static void cs2000_write_cached(struct oxygen *chip, u8 reg, u8 value)
245{
246 struct xonar_pcm179x *data = chip->model_data;
247
248 if (reg != CS2000_FUN_CFG_1 ||
249 value != data->cs2000_fun_cfg_1)
250 cs2000_write(chip, reg, value);
251}
252
253static void pcm1796_registers_init(struct oxygen *chip)
254{
255 struct xonar_pcm179x *data = chip->model_data;
256 unsigned int i;
257 s8 gain_offset;
258
259 gain_offset = data->hp_active ? data->hp_gain_offset : 0;
260 for (i = 0; i < data->dacs; ++i) {
261 /* set ATLD before ATL/ATR */
262 pcm1796_write(chip, i, 18,
263 data->pcm1796_regs[0][18 - PCM1796_REG_BASE]);
264 pcm1796_write(chip, i, 16, chip->dac_volume[i * 2]
265 + gain_offset);
266 pcm1796_write(chip, i, 17, chip->dac_volume[i * 2 + 1]
267 + gain_offset);
268 pcm1796_write(chip, i, 19,
269 data->pcm1796_regs[0][19 - PCM1796_REG_BASE]);
270 pcm1796_write(chip, i, 20,
271 data->pcm1796_regs[0][20 - PCM1796_REG_BASE]);
272 pcm1796_write(chip, i, 21, 0);
273 }
274}
275
276static void pcm1796_init(struct oxygen *chip)
277{
278 struct xonar_pcm179x *data = chip->model_data;
279
280 data->pcm1796_regs[0][18 - PCM1796_REG_BASE] = PCM1796_MUTE |
281 PCM1796_DMF_DISABLED | PCM1796_FMT_24_LJUST | PCM1796_ATLD;
282 data->pcm1796_regs[0][19 - PCM1796_REG_BASE] =
283 PCM1796_FLT_SHARP | PCM1796_ATS_1;
284 data->pcm1796_regs[0][20 - PCM1796_REG_BASE] = PCM1796_OS_64;
285 pcm1796_registers_init(chip);
286 data->current_rate = 48000;
287}
288
289static void xonar_d2_init(struct oxygen *chip)
290{
291 struct xonar_pcm179x *data = chip->model_data;
292
293 data->generic.anti_pop_delay = 300;
294 data->generic.output_enable_bit = GPIO_D2_OUTPUT_ENABLE;
295 data->dacs = 4;
296
297 pcm1796_init(chip);
298
299 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_D2_ALT);
300 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_D2_ALT);
301
302 oxygen_ac97_set_bits(chip, 0, CM9780_JACK, CM9780_FMIC2MIC);
303
304 xonar_init_cs53x1(chip);
305 xonar_enable_output(chip);
306
307 snd_component_add(chip->card, "PCM1796");
308 snd_component_add(chip->card, "CS5381");
309}
310
311static void xonar_d2x_init(struct oxygen *chip)
312{
313 struct xonar_pcm179x *data = chip->model_data;
314
315 data->generic.ext_power_reg = OXYGEN_GPIO_DATA;
316 data->generic.ext_power_int_reg = OXYGEN_GPIO_INTERRUPT_MASK;
317 data->generic.ext_power_bit = GPIO_D2X_EXT_POWER;
318 oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_D2X_EXT_POWER);
319 xonar_init_ext_power(chip);
320 xonar_d2_init(chip);
321}
322
323static void xonar_hdav_init(struct oxygen *chip)
324{
325 struct xonar_hdav *data = chip->model_data;
326
327 oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS,
328 OXYGEN_2WIRE_LENGTH_8 |
329 OXYGEN_2WIRE_INTERRUPT_MASK |
330 OXYGEN_2WIRE_SPEED_FAST);
331
332 data->pcm179x.generic.anti_pop_delay = 100;
333 data->pcm179x.generic.output_enable_bit = GPIO_HDAV_OUTPUT_ENABLE;
334 data->pcm179x.generic.ext_power_reg = OXYGEN_GPI_DATA;
335 data->pcm179x.generic.ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK;
336 data->pcm179x.generic.ext_power_bit = GPI_EXT_POWER;
337 data->pcm179x.dacs = chip->model.private_data ? 4 : 1;
338
339 pcm1796_init(chip);
340
341 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_INPUT_ROUTE);
342 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_INPUT_ROUTE);
343
344 xonar_init_cs53x1(chip);
345 xonar_init_ext_power(chip);
346 xonar_hdmi_init(chip, &data->hdmi);
347 xonar_enable_output(chip);
348
349 snd_component_add(chip->card, "PCM1796");
350 snd_component_add(chip->card, "CS5381");
351}
352
353static void xonar_st_init_i2c(struct oxygen *chip)
354{
355 oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS,
356 OXYGEN_2WIRE_LENGTH_8 |
357 OXYGEN_2WIRE_INTERRUPT_MASK |
358 OXYGEN_2WIRE_SPEED_FAST);
359}
360
361static void xonar_st_init_common(struct oxygen *chip)
362{
363 struct xonar_pcm179x *data = chip->model_data;
364
365 data->generic.anti_pop_delay = 100;
366 data->generic.output_enable_bit = GPIO_ST_OUTPUT_ENABLE;
367 data->dacs = chip->model.private_data ? 4 : 1;
368 data->hp_gain_offset = 2*-18;
369
370 pcm1796_init(chip);
371
372 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
373 GPIO_INPUT_ROUTE | GPIO_ST_HP_REAR | GPIO_ST_HP);
374 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA,
375 GPIO_INPUT_ROUTE | GPIO_ST_HP_REAR | GPIO_ST_HP);
376
377 xonar_init_cs53x1(chip);
378 xonar_enable_output(chip);
379
380 snd_component_add(chip->card, "PCM1792A");
381 snd_component_add(chip->card, "CS5381");
382}
383
384static void cs2000_registers_init(struct oxygen *chip)
385{
386 struct xonar_pcm179x *data = chip->model_data;
387
388 cs2000_write(chip, CS2000_GLOBAL_CFG, CS2000_FREEZE);
389 cs2000_write(chip, CS2000_DEV_CTRL, 0);
390 cs2000_write(chip, CS2000_DEV_CFG_1,
391 CS2000_R_MOD_SEL_1 |
392 (0 << CS2000_R_SEL_SHIFT) |
393 CS2000_AUX_OUT_SRC_REF_CLK |
394 CS2000_EN_DEV_CFG_1);
395 cs2000_write(chip, CS2000_DEV_CFG_2,
396 (0 << CS2000_LOCK_CLK_SHIFT) |
397 CS2000_FRAC_N_SRC_STATIC);
398 cs2000_write(chip, CS2000_RATIO_0 + 0, 0x00); /* 1.0 */
399 cs2000_write(chip, CS2000_RATIO_0 + 1, 0x10);
400 cs2000_write(chip, CS2000_RATIO_0 + 2, 0x00);
401 cs2000_write(chip, CS2000_RATIO_0 + 3, 0x00);
402 cs2000_write(chip, CS2000_FUN_CFG_1, data->cs2000_fun_cfg_1);
403 cs2000_write(chip, CS2000_FUN_CFG_2, 0);
404 cs2000_write(chip, CS2000_GLOBAL_CFG, CS2000_EN_DEV_CFG_2);
405}
406
407static void xonar_st_init(struct oxygen *chip)
408{
409 struct xonar_pcm179x *data = chip->model_data;
410
411 data->has_cs2000 = 1;
412 data->cs2000_fun_cfg_1 = CS2000_REF_CLK_DIV_1;
413
414 oxygen_write16(chip, OXYGEN_I2S_A_FORMAT,
415 OXYGEN_RATE_48000 | OXYGEN_I2S_FORMAT_I2S |
416 OXYGEN_I2S_MCLK_128 | OXYGEN_I2S_BITS_16 |
417 OXYGEN_I2S_MASTER | OXYGEN_I2S_BCLK_64);
418
419 xonar_st_init_i2c(chip);
420 cs2000_registers_init(chip);
421 xonar_st_init_common(chip);
422
423 snd_component_add(chip->card, "CS2000");
424}
425
426static void xonar_stx_init(struct oxygen *chip)
427{
428 struct xonar_pcm179x *data = chip->model_data;
429
430 xonar_st_init_i2c(chip);
431 data->generic.ext_power_reg = OXYGEN_GPI_DATA;
432 data->generic.ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK;
433 data->generic.ext_power_bit = GPI_EXT_POWER;
434 xonar_init_ext_power(chip);
435 xonar_st_init_common(chip);
436}
437
438static void xonar_d2_cleanup(struct oxygen *chip)
439{
440 xonar_disable_output(chip);
441}
442
443static void xonar_hdav_cleanup(struct oxygen *chip)
444{
445 xonar_hdmi_cleanup(chip);
446 xonar_disable_output(chip);
447 msleep(2);
448}
449
450static void xonar_st_cleanup(struct oxygen *chip)
451{
452 xonar_disable_output(chip);
453}
454
455static void xonar_d2_suspend(struct oxygen *chip)
456{
457 xonar_d2_cleanup(chip);
458}
459
460static void xonar_hdav_suspend(struct oxygen *chip)
461{
462 xonar_hdav_cleanup(chip);
463}
464
465static void xonar_st_suspend(struct oxygen *chip)
466{
467 xonar_st_cleanup(chip);
468}
469
470static void xonar_d2_resume(struct oxygen *chip)
471{
472 pcm1796_registers_init(chip);
473 xonar_enable_output(chip);
474}
475
476static void xonar_hdav_resume(struct oxygen *chip)
477{
478 struct xonar_hdav *data = chip->model_data;
479
480 pcm1796_registers_init(chip);
481 xonar_hdmi_resume(chip, &data->hdmi);
482 xonar_enable_output(chip);
483}
484
485static void xonar_stx_resume(struct oxygen *chip)
486{
487 pcm1796_registers_init(chip);
488 xonar_enable_output(chip);
489}
490
491static void xonar_st_resume(struct oxygen *chip)
492{
493 cs2000_registers_init(chip);
494 xonar_stx_resume(chip);
495}
496
497static unsigned int mclk_from_rate(struct oxygen *chip, unsigned int rate)
498{
499 struct xonar_pcm179x *data = chip->model_data;
500
501 if (rate <= 32000)
502 return OXYGEN_I2S_MCLK_512;
503 else if (rate <= 48000 && data->os_128)
504 return OXYGEN_I2S_MCLK_512;
505 else if (rate <= 96000)
506 return OXYGEN_I2S_MCLK_256;
507 else
508 return OXYGEN_I2S_MCLK_128;
509}
510
511static unsigned int get_pcm1796_i2s_mclk(struct oxygen *chip,
512 unsigned int channel,
513 struct snd_pcm_hw_params *params)
514{
515 if (channel == PCM_MULTICH)
516 return mclk_from_rate(chip, params_rate(params));
517 else
518 return oxygen_default_i2s_mclk(chip, channel, params);
519}
520
521static void update_pcm1796_oversampling(struct oxygen *chip)
522{
523 struct xonar_pcm179x *data = chip->model_data;
524 unsigned int i;
525 u8 reg;
526
527 if (data->current_rate <= 32000)
528 reg = PCM1796_OS_128;
529 else if (data->current_rate <= 48000 && data->os_128)
530 reg = PCM1796_OS_128;
531 else if (data->current_rate <= 96000 || data->os_128)
532 reg = PCM1796_OS_64;
533 else
534 reg = PCM1796_OS_32;
535 for (i = 0; i < data->dacs; ++i)
536 pcm1796_write_cached(chip, i, 20, reg);
537}
538
539static void set_pcm1796_params(struct oxygen *chip,
540 struct snd_pcm_hw_params *params)
541{
542 struct xonar_pcm179x *data = chip->model_data;
543
544 data->current_rate = params_rate(params);
545 update_pcm1796_oversampling(chip);
546}
547
548static void update_pcm1796_volume(struct oxygen *chip)
549{
550 struct xonar_pcm179x *data = chip->model_data;
551 unsigned int i;
552 s8 gain_offset;
553
554 gain_offset = data->hp_active ? data->hp_gain_offset : 0;
555 for (i = 0; i < data->dacs; ++i) {
556 pcm1796_write_cached(chip, i, 16, chip->dac_volume[i * 2]
557 + gain_offset);
558 pcm1796_write_cached(chip, i, 17, chip->dac_volume[i * 2 + 1]
559 + gain_offset);
560 }
561}
562
563static void update_pcm1796_mute(struct oxygen *chip)
564{
565 struct xonar_pcm179x *data = chip->model_data;
566 unsigned int i;
567 u8 value;
568
569 value = PCM1796_DMF_DISABLED | PCM1796_FMT_24_LJUST | PCM1796_ATLD;
570 if (chip->dac_mute)
571 value |= PCM1796_MUTE;
572 for (i = 0; i < data->dacs; ++i)
573 pcm1796_write_cached(chip, i, 18, value);
574}
575
576static void update_cs2000_rate(struct oxygen *chip, unsigned int rate)
577{
578 struct xonar_pcm179x *data = chip->model_data;
579 u8 rate_mclk, reg;
580
581 switch (rate) {
582 /* XXX Why is the I2S A MCLK half the actual I2S MCLK? */
583 case 32000:
584 rate_mclk = OXYGEN_RATE_32000 | OXYGEN_I2S_MCLK_256;
585 break;
586 case 44100:
587 if (data->os_128)
588 rate_mclk = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_256;
589 else
590 rate_mclk = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_128;
591 break;
592 default: /* 48000 */
593 if (data->os_128)
594 rate_mclk = OXYGEN_RATE_48000 | OXYGEN_I2S_MCLK_256;
595 else
596 rate_mclk = OXYGEN_RATE_48000 | OXYGEN_I2S_MCLK_128;
597 break;
598 case 64000:
599 rate_mclk = OXYGEN_RATE_32000 | OXYGEN_I2S_MCLK_256;
600 break;
601 case 88200:
602 rate_mclk = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_256;
603 break;
604 case 96000:
605 rate_mclk = OXYGEN_RATE_48000 | OXYGEN_I2S_MCLK_256;
606 break;
607 case 176400:
608 rate_mclk = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_256;
609 break;
610 case 192000:
611 rate_mclk = OXYGEN_RATE_48000 | OXYGEN_I2S_MCLK_256;
612 break;
613 }
614 oxygen_write16_masked(chip, OXYGEN_I2S_A_FORMAT, rate_mclk,
615 OXYGEN_I2S_RATE_MASK | OXYGEN_I2S_MCLK_MASK);
616 if ((rate_mclk & OXYGEN_I2S_MCLK_MASK) <= OXYGEN_I2S_MCLK_128)
617 reg = CS2000_REF_CLK_DIV_1;
618 else
619 reg = CS2000_REF_CLK_DIV_2;
620 cs2000_write_cached(chip, CS2000_FUN_CFG_1, reg);
621}
622
623static void set_st_params(struct oxygen *chip,
624 struct snd_pcm_hw_params *params)
625{
626 update_cs2000_rate(chip, params_rate(params));
627 set_pcm1796_params(chip, params);
628}
629
630static void set_hdav_params(struct oxygen *chip,
631 struct snd_pcm_hw_params *params)
632{
633 struct xonar_hdav *data = chip->model_data;
634
635 set_pcm1796_params(chip, params);
636 xonar_set_hdmi_params(chip, &data->hdmi, params);
637}
638
639static const struct snd_kcontrol_new alt_switch = {
640 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
641 .name = "Analog Loopback Switch",
642 .info = snd_ctl_boolean_mono_info,
643 .get = xonar_gpio_bit_switch_get,
644 .put = xonar_gpio_bit_switch_put,
645 .private_value = GPIO_D2_ALT,
646};
647
648static int rolloff_info(struct snd_kcontrol *ctl,
649 struct snd_ctl_elem_info *info)
650{
651 static const char *const names[2] = {
652 "Sharp Roll-off", "Slow Roll-off"
653 };
654
655 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
656 info->count = 1;
657 info->value.enumerated.items = 2;
658 if (info->value.enumerated.item >= 2)
659 info->value.enumerated.item = 1;
660 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
661 return 0;
662}
663
664static int rolloff_get(struct snd_kcontrol *ctl,
665 struct snd_ctl_elem_value *value)
666{
667 struct oxygen *chip = ctl->private_data;
668 struct xonar_pcm179x *data = chip->model_data;
669
670 value->value.enumerated.item[0] =
671 (data->pcm1796_regs[0][19 - PCM1796_REG_BASE] &
672 PCM1796_FLT_MASK) != PCM1796_FLT_SHARP;
673 return 0;
674}
675
676static int rolloff_put(struct snd_kcontrol *ctl,
677 struct snd_ctl_elem_value *value)
678{
679 struct oxygen *chip = ctl->private_data;
680 struct xonar_pcm179x *data = chip->model_data;
681 unsigned int i;
682 int changed;
683 u8 reg;
684
685 mutex_lock(&chip->mutex);
686 reg = data->pcm1796_regs[0][19 - PCM1796_REG_BASE];
687 reg &= ~PCM1796_FLT_MASK;
688 if (!value->value.enumerated.item[0])
689 reg |= PCM1796_FLT_SHARP;
690 else
691 reg |= PCM1796_FLT_SLOW;
692 changed = reg != data->pcm1796_regs[0][19 - PCM1796_REG_BASE];
693 if (changed) {
694 for (i = 0; i < data->dacs; ++i)
695 pcm1796_write(chip, i, 19, reg);
696 }
697 mutex_unlock(&chip->mutex);
698 return changed;
699}
700
701static const struct snd_kcontrol_new rolloff_control = {
702 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
703 .name = "DAC Filter Playback Enum",
704 .info = rolloff_info,
705 .get = rolloff_get,
706 .put = rolloff_put,
707};
708
709static int os_128_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info)
710{
711 static const char *const names[2] = { "64x", "128x" };
712
713 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
714 info->count = 1;
715 info->value.enumerated.items = 2;
716 if (info->value.enumerated.item >= 2)
717 info->value.enumerated.item = 1;
718 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
719 return 0;
720}
721
722static int os_128_get(struct snd_kcontrol *ctl,
723 struct snd_ctl_elem_value *value)
724{
725 struct oxygen *chip = ctl->private_data;
726 struct xonar_pcm179x *data = chip->model_data;
727
728 value->value.enumerated.item[0] = data->os_128;
729 return 0;
730}
731
732static int os_128_put(struct snd_kcontrol *ctl,
733 struct snd_ctl_elem_value *value)
734{
735 struct oxygen *chip = ctl->private_data;
736 struct xonar_pcm179x *data = chip->model_data;
737 int changed;
738
739 mutex_lock(&chip->mutex);
740 changed = value->value.enumerated.item[0] != data->os_128;
741 if (changed) {
742 data->os_128 = value->value.enumerated.item[0];
743 if (data->has_cs2000)
744 update_cs2000_rate(chip, data->current_rate);
745 oxygen_write16_masked(chip, OXYGEN_I2S_MULTICH_FORMAT,
746 mclk_from_rate(chip, data->current_rate),
747 OXYGEN_I2S_MCLK_MASK);
748 update_pcm1796_oversampling(chip);
749 }
750 mutex_unlock(&chip->mutex);
751 return changed;
752}
753
754static const struct snd_kcontrol_new os_128_control = {
755 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
756 .name = "DAC Oversampling Playback Enum",
757 .info = os_128_info,
758 .get = os_128_get,
759 .put = os_128_put,
760};
761
762static int st_output_switch_info(struct snd_kcontrol *ctl,
763 struct snd_ctl_elem_info *info)
764{
765 static const char *const names[3] = {
766 "Speakers", "Headphones", "FP Headphones"
767 };
768
769 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
770 info->count = 1;
771 info->value.enumerated.items = 3;
772 if (info->value.enumerated.item >= 3)
773 info->value.enumerated.item = 2;
774 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
775 return 0;
776}
777
778static int st_output_switch_get(struct snd_kcontrol *ctl,
779 struct snd_ctl_elem_value *value)
780{
781 struct oxygen *chip = ctl->private_data;
782 u16 gpio;
783
784 gpio = oxygen_read16(chip, OXYGEN_GPIO_DATA);
785 if (!(gpio & GPIO_ST_HP))
786 value->value.enumerated.item[0] = 0;
787 else if (gpio & GPIO_ST_HP_REAR)
788 value->value.enumerated.item[0] = 1;
789 else
790 value->value.enumerated.item[0] = 2;
791 return 0;
792}
793
794
795static int st_output_switch_put(struct snd_kcontrol *ctl,
796 struct snd_ctl_elem_value *value)
797{
798 struct oxygen *chip = ctl->private_data;
799 struct xonar_pcm179x *data = chip->model_data;
800 u16 gpio_old, gpio;
801
802 mutex_lock(&chip->mutex);
803 gpio_old = oxygen_read16(chip, OXYGEN_GPIO_DATA);
804 gpio = gpio_old;
805 switch (value->value.enumerated.item[0]) {
806 case 0:
807 gpio &= ~(GPIO_ST_HP | GPIO_ST_HP_REAR);
808 break;
809 case 1:
810 gpio |= GPIO_ST_HP | GPIO_ST_HP_REAR;
811 break;
812 case 2:
813 gpio = (gpio | GPIO_ST_HP) & ~GPIO_ST_HP_REAR;
814 break;
815 }
816 oxygen_write16(chip, OXYGEN_GPIO_DATA, gpio);
817 data->hp_active = gpio & GPIO_ST_HP;
818 update_pcm1796_volume(chip);
819 mutex_unlock(&chip->mutex);
820 return gpio != gpio_old;
821}
822
823static int st_hp_volume_offset_info(struct snd_kcontrol *ctl,
824 struct snd_ctl_elem_info *info)
825{
826 static const char *const names[3] = {
827 "< 64 ohms", "64-300 ohms", "300-600 ohms"
828 };
829
830 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
831 info->count = 1;
832 info->value.enumerated.items = 3;
833 if (info->value.enumerated.item > 2)
834 info->value.enumerated.item = 2;
835 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
836 return 0;
837}
838
839static int st_hp_volume_offset_get(struct snd_kcontrol *ctl,
840 struct snd_ctl_elem_value *value)
841{
842 struct oxygen *chip = ctl->private_data;
843 struct xonar_pcm179x *data = chip->model_data;
844
845 mutex_lock(&chip->mutex);
846 if (data->hp_gain_offset < 2*-6)
847 value->value.enumerated.item[0] = 0;
848 else if (data->hp_gain_offset < 0)
849 value->value.enumerated.item[0] = 1;
850 else
851 value->value.enumerated.item[0] = 2;
852 mutex_unlock(&chip->mutex);
853 return 0;
854}
855
856
857static int st_hp_volume_offset_put(struct snd_kcontrol *ctl,
858 struct snd_ctl_elem_value *value)
859{
860 static const s8 offsets[] = { 2*-18, 2*-6, 0 };
861 struct oxygen *chip = ctl->private_data;
862 struct xonar_pcm179x *data = chip->model_data;
863 s8 offset;
864 int changed;
865
866 if (value->value.enumerated.item[0] > 2)
867 return -EINVAL;
868 offset = offsets[value->value.enumerated.item[0]];
869 mutex_lock(&chip->mutex);
870 changed = offset != data->hp_gain_offset;
871 if (changed) {
872 data->hp_gain_offset = offset;
873 update_pcm1796_volume(chip);
874 }
875 mutex_unlock(&chip->mutex);
876 return changed;
877}
878
879static const struct snd_kcontrol_new st_controls[] = {
880 {
881 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
882 .name = "Analog Output",
883 .info = st_output_switch_info,
884 .get = st_output_switch_get,
885 .put = st_output_switch_put,
886 },
887 {
888 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
889 .name = "Headphones Impedance Playback Enum",
890 .info = st_hp_volume_offset_info,
891 .get = st_hp_volume_offset_get,
892 .put = st_hp_volume_offset_put,
893 },
894};
895
896static void xonar_line_mic_ac97_switch(struct oxygen *chip,
897 unsigned int reg, unsigned int mute)
898{
899 if (reg == AC97_LINE) {
900 spin_lock_irq(&chip->reg_lock);
901 oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
902 mute ? GPIO_INPUT_ROUTE : 0,
903 GPIO_INPUT_ROUTE);
904 spin_unlock_irq(&chip->reg_lock);
905 }
906}
907
908static const DECLARE_TLV_DB_SCALE(pcm1796_db_scale, -6000, 50, 0);
909
910static int xonar_d2_control_filter(struct snd_kcontrol_new *template)
911{
912 if (!strncmp(template->name, "CD Capture ", 11))
913 /* CD in is actually connected to the video in pin */
914 template->private_value ^= AC97_CD ^ AC97_VIDEO;
915 return 0;
916}
917
918static int xonar_st_control_filter(struct snd_kcontrol_new *template)
919{
920 if (!strncmp(template->name, "CD Capture ", 11))
921 return 1; /* no CD input */
922 return 0;
923}
924
925static int add_pcm1796_controls(struct oxygen *chip)
926{
927 int err;
928
929 err = snd_ctl_add(chip->card, snd_ctl_new1(&rolloff_control, chip));
930 if (err < 0)
931 return err;
932 err = snd_ctl_add(chip->card, snd_ctl_new1(&os_128_control, chip));
933 if (err < 0)
934 return err;
935 return 0;
936}
937
938static int xonar_d2_mixer_init(struct oxygen *chip)
939{
940 int err;
941
942 err = snd_ctl_add(chip->card, snd_ctl_new1(&alt_switch, chip));
943 if (err < 0)
944 return err;
945 err = add_pcm1796_controls(chip);
946 if (err < 0)
947 return err;
948 return 0;
949}
950
951static int xonar_hdav_mixer_init(struct oxygen *chip)
952{
953 return add_pcm1796_controls(chip);
954}
955
956static int xonar_st_mixer_init(struct oxygen *chip)
957{
958 unsigned int i;
959 int err;
960
961 for (i = 0; i < ARRAY_SIZE(st_controls); ++i) {
962 err = snd_ctl_add(chip->card,
963 snd_ctl_new1(&st_controls[i], chip));
964 if (err < 0)
965 return err;
966 }
967 err = add_pcm1796_controls(chip);
968 if (err < 0)
969 return err;
970 return 0;
971}
972
973static const struct oxygen_model model_xonar_d2 = {
974 .longname = "Asus Virtuoso 200",
975 .chip = "AV200",
976 .init = xonar_d2_init,
977 .control_filter = xonar_d2_control_filter,
978 .mixer_init = xonar_d2_mixer_init,
979 .cleanup = xonar_d2_cleanup,
980 .suspend = xonar_d2_suspend,
981 .resume = xonar_d2_resume,
982 .get_i2s_mclk = get_pcm1796_i2s_mclk,
983 .set_dac_params = set_pcm1796_params,
984 .set_adc_params = xonar_set_cs53x1_params,
985 .update_dac_volume = update_pcm1796_volume,
986 .update_dac_mute = update_pcm1796_mute,
987 .dac_tlv = pcm1796_db_scale,
988 .model_data_size = sizeof(struct xonar_pcm179x),
989 .device_config = PLAYBACK_0_TO_I2S |
990 PLAYBACK_1_TO_SPDIF |
991 CAPTURE_0_FROM_I2S_2 |
992 CAPTURE_1_FROM_SPDIF |
993 MIDI_OUTPUT |
994 MIDI_INPUT,
995 .dac_channels = 8,
996 .dac_volume_min = 255 - 2*60,
997 .dac_volume_max = 255,
998 .misc_flags = OXYGEN_MISC_MIDI,
999 .function_flags = OXYGEN_FUNCTION_SPI |
1000 OXYGEN_FUNCTION_ENABLE_SPI_4_5,
1001 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1002 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1003};
1004
1005static const struct oxygen_model model_xonar_hdav = {
1006 .longname = "Asus Virtuoso 200",
1007 .chip = "AV200",
1008 .init = xonar_hdav_init,
1009 .mixer_init = xonar_hdav_mixer_init,
1010 .cleanup = xonar_hdav_cleanup,
1011 .suspend = xonar_hdav_suspend,
1012 .resume = xonar_hdav_resume,
1013 .pcm_hardware_filter = xonar_hdmi_pcm_hardware_filter,
1014 .get_i2s_mclk = get_pcm1796_i2s_mclk,
1015 .set_dac_params = set_hdav_params,
1016 .set_adc_params = xonar_set_cs53x1_params,
1017 .update_dac_volume = update_pcm1796_volume,
1018 .update_dac_mute = update_pcm1796_mute,
1019 .uart_input = xonar_hdmi_uart_input,
1020 .ac97_switch = xonar_line_mic_ac97_switch,
1021 .dac_tlv = pcm1796_db_scale,
1022 .model_data_size = sizeof(struct xonar_hdav),
1023 .device_config = PLAYBACK_0_TO_I2S |
1024 PLAYBACK_1_TO_SPDIF |
1025 CAPTURE_0_FROM_I2S_2 |
1026 CAPTURE_1_FROM_SPDIF,
1027 .dac_channels = 8,
1028 .dac_volume_min = 255 - 2*60,
1029 .dac_volume_max = 255,
1030 .misc_flags = OXYGEN_MISC_MIDI,
1031 .function_flags = OXYGEN_FUNCTION_2WIRE,
1032 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1033 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1034};
1035
1036static const struct oxygen_model model_xonar_st = {
1037 .longname = "Asus Virtuoso 100",
1038 .chip = "AV200",
1039 .init = xonar_st_init,
1040 .control_filter = xonar_st_control_filter,
1041 .mixer_init = xonar_st_mixer_init,
1042 .cleanup = xonar_st_cleanup,
1043 .suspend = xonar_st_suspend,
1044 .resume = xonar_st_resume,
1045 .get_i2s_mclk = get_pcm1796_i2s_mclk,
1046 .set_dac_params = set_st_params,
1047 .set_adc_params = xonar_set_cs53x1_params,
1048 .update_dac_volume = update_pcm1796_volume,
1049 .update_dac_mute = update_pcm1796_mute,
1050 .ac97_switch = xonar_line_mic_ac97_switch,
1051 .dac_tlv = pcm1796_db_scale,
1052 .model_data_size = sizeof(struct xonar_pcm179x),
1053 .device_config = PLAYBACK_0_TO_I2S |
1054 PLAYBACK_1_TO_SPDIF |
1055 CAPTURE_0_FROM_I2S_2,
1056 .dac_channels = 2,
1057 .dac_volume_min = 255 - 2*60,
1058 .dac_volume_max = 255,
1059 .function_flags = OXYGEN_FUNCTION_2WIRE,
1060 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1061 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1062};
1063
1064int __devinit get_xonar_pcm179x_model(struct oxygen *chip,
1065 const struct pci_device_id *id)
1066{
1067 switch (id->subdevice) {
1068 case 0x8269:
1069 chip->model = model_xonar_d2;
1070 chip->model.shortname = "Xonar D2";
1071 break;
1072 case 0x82b7:
1073 chip->model = model_xonar_d2;
1074 chip->model.shortname = "Xonar D2X";
1075 chip->model.init = xonar_d2x_init;
1076 break;
1077 case 0x8314:
1078 chip->model = model_xonar_hdav;
1079 oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_DB_MASK);
1080 switch (oxygen_read16(chip, OXYGEN_GPIO_DATA) & GPIO_DB_MASK) {
1081 default:
1082 chip->model.shortname = "Xonar HDAV1.3";
1083 break;
1084 case GPIO_DB_H6:
1085 chip->model.shortname = "Xonar HDAV1.3+H6";
1086 chip->model.private_data = 1;
1087 break;
1088 }
1089 break;
1090 case 0x835d:
1091 chip->model = model_xonar_st;
1092 oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_DB_MASK);
1093 switch (oxygen_read16(chip, OXYGEN_GPIO_DATA) & GPIO_DB_MASK) {
1094 default:
1095 chip->model.shortname = "Xonar ST";
1096 break;
1097 case GPIO_DB_H6:
1098 chip->model.shortname = "Xonar ST+H6";
1099 chip->model.dac_channels = 8;
1100 chip->model.private_data = 1;
1101 break;
1102 }
1103 break;
1104 case 0x835c:
1105 chip->model = model_xonar_st;
1106 chip->model.shortname = "Xonar STX";
1107 chip->model.init = xonar_stx_init;
1108 chip->model.resume = xonar_stx_resume;
1109 chip->model.set_dac_params = set_pcm1796_params;
1110 break;
1111 default:
1112 return -EINVAL;
1113 }
1114 return 0;
1115}
diff --git a/sound/pci/oxygen/xonar_wm87x6.c b/sound/pci/oxygen/xonar_wm87x6.c
new file mode 100644
index 000000000000..dbc4b89d74e4
--- /dev/null
+++ b/sound/pci/oxygen/xonar_wm87x6.c
@@ -0,0 +1,1021 @@
1/*
2 * card driver for models with WM8776/WM8766 DACs (Xonar DS)
3 *
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5 *
6 *
7 * This driver is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License, version 2.
9 *
10 * This driver is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this driver; if not, see <http://www.gnu.org/licenses/>.
17 */
18
19/*
20 * Xonar DS
21 * --------
22 *
23 * CMI8788:
24 *
25 * SPI 0 -> WM8766 (surround, center/LFE, back)
26 * SPI 1 -> WM8776 (front, input)
27 *
28 * GPIO 4 <- headphone detect
29 * GPIO 6 -> route input jack to input 1/2 (1/0)
30 * GPIO 7 -> enable output to speakers
31 * GPIO 8 -> enable output to speakers
32 */
33
34#include <linux/pci.h>
35#include <linux/delay.h>
36#include <sound/control.h>
37#include <sound/core.h>
38#include <sound/pcm.h>
39#include <sound/pcm_params.h>
40#include <sound/tlv.h>
41#include "xonar.h"
42#include "wm8776.h"
43#include "wm8766.h"
44
45#define GPIO_DS_HP_DETECT 0x0010
46#define GPIO_DS_INPUT_ROUTE 0x0040
47#define GPIO_DS_OUTPUT_ENABLE 0x0180
48
49#define LC_CONTROL_LIMITER 0x40000000
50#define LC_CONTROL_ALC 0x20000000
51
52struct xonar_wm87x6 {
53 struct xonar_generic generic;
54 u16 wm8776_regs[0x17];
55 u16 wm8766_regs[0x10];
56 struct snd_kcontrol *lc_controls[13];
57};
58
59static void wm8776_write(struct oxygen *chip,
60 unsigned int reg, unsigned int value)
61{
62 struct xonar_wm87x6 *data = chip->model_data;
63
64 oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
65 OXYGEN_SPI_DATA_LENGTH_2 |
66 OXYGEN_SPI_CLOCK_160 |
67 (1 << OXYGEN_SPI_CODEC_SHIFT) |
68 OXYGEN_SPI_CEN_LATCH_CLOCK_LO,
69 (reg << 9) | value);
70 if (reg < ARRAY_SIZE(data->wm8776_regs)) {
71 if (reg >= WM8776_HPLVOL && reg <= WM8776_DACMASTER)
72 value &= ~WM8776_UPDATE;
73 data->wm8776_regs[reg] = value;
74 }
75}
76
77static void wm8776_write_cached(struct oxygen *chip,
78 unsigned int reg, unsigned int value)
79{
80 struct xonar_wm87x6 *data = chip->model_data;
81
82 if (reg >= ARRAY_SIZE(data->wm8776_regs) ||
83 value != data->wm8776_regs[reg])
84 wm8776_write(chip, reg, value);
85}
86
87static void wm8766_write(struct oxygen *chip,
88 unsigned int reg, unsigned int value)
89{
90 struct xonar_wm87x6 *data = chip->model_data;
91
92 oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
93 OXYGEN_SPI_DATA_LENGTH_2 |
94 OXYGEN_SPI_CLOCK_160 |
95 (0 << OXYGEN_SPI_CODEC_SHIFT) |
96 OXYGEN_SPI_CEN_LATCH_CLOCK_LO,
97 (reg << 9) | value);
98 if (reg < ARRAY_SIZE(data->wm8766_regs))
99 data->wm8766_regs[reg] = value;
100}
101
102static void wm8766_write_cached(struct oxygen *chip,
103 unsigned int reg, unsigned int value)
104{
105 struct xonar_wm87x6 *data = chip->model_data;
106
107 if (reg >= ARRAY_SIZE(data->wm8766_regs) ||
108 value != data->wm8766_regs[reg]) {
109 if ((reg >= WM8766_LDA1 && reg <= WM8766_RDA1) ||
110 (reg >= WM8766_LDA2 && reg <= WM8766_MASTDA))
111 value &= ~WM8766_UPDATE;
112 wm8766_write(chip, reg, value);
113 }
114}
115
116static void wm8776_registers_init(struct oxygen *chip)
117{
118 struct xonar_wm87x6 *data = chip->model_data;
119
120 wm8776_write(chip, WM8776_RESET, 0);
121 wm8776_write(chip, WM8776_DACCTRL1, WM8776_DZCEN |
122 WM8776_PL_LEFT_LEFT | WM8776_PL_RIGHT_RIGHT);
123 wm8776_write(chip, WM8776_DACMUTE, chip->dac_mute ? WM8776_DMUTE : 0);
124 wm8776_write(chip, WM8776_DACIFCTRL,
125 WM8776_DACFMT_LJUST | WM8776_DACWL_24);
126 wm8776_write(chip, WM8776_ADCIFCTRL,
127 data->wm8776_regs[WM8776_ADCIFCTRL]);
128 wm8776_write(chip, WM8776_MSTRCTRL, data->wm8776_regs[WM8776_MSTRCTRL]);
129 wm8776_write(chip, WM8776_PWRDOWN, data->wm8776_regs[WM8776_PWRDOWN]);
130 wm8776_write(chip, WM8776_HPLVOL, data->wm8776_regs[WM8776_HPLVOL]);
131 wm8776_write(chip, WM8776_HPRVOL, data->wm8776_regs[WM8776_HPRVOL] |
132 WM8776_UPDATE);
133 wm8776_write(chip, WM8776_ADCLVOL, data->wm8776_regs[WM8776_ADCLVOL]);
134 wm8776_write(chip, WM8776_ADCRVOL, data->wm8776_regs[WM8776_ADCRVOL]);
135 wm8776_write(chip, WM8776_ADCMUX, data->wm8776_regs[WM8776_ADCMUX]);
136 wm8776_write(chip, WM8776_DACLVOL, chip->dac_volume[0]);
137 wm8776_write(chip, WM8776_DACRVOL, chip->dac_volume[1] | WM8776_UPDATE);
138}
139
140static void wm8766_registers_init(struct oxygen *chip)
141{
142 wm8766_write(chip, WM8766_RESET, 0);
143 wm8766_write(chip, WM8766_INT_CTRL, WM8766_FMT_LJUST | WM8766_IWL_24);
144 wm8766_write(chip, WM8766_DAC_CTRL2,
145 WM8766_ZCD | (chip->dac_mute ? WM8766_DMUTE_MASK : 0));
146 wm8766_write(chip, WM8766_LDA1, chip->dac_volume[2]);
147 wm8766_write(chip, WM8766_RDA1, chip->dac_volume[3]);
148 wm8766_write(chip, WM8766_LDA2, chip->dac_volume[4]);
149 wm8766_write(chip, WM8766_RDA2, chip->dac_volume[5]);
150 wm8766_write(chip, WM8766_LDA3, chip->dac_volume[6]);
151 wm8766_write(chip, WM8766_RDA3, chip->dac_volume[7] | WM8766_UPDATE);
152}
153
154static void wm8776_init(struct oxygen *chip)
155{
156 struct xonar_wm87x6 *data = chip->model_data;
157
158 data->wm8776_regs[WM8776_HPLVOL] = (0x79 - 60) | WM8776_HPZCEN;
159 data->wm8776_regs[WM8776_HPRVOL] = (0x79 - 60) | WM8776_HPZCEN;
160 data->wm8776_regs[WM8776_ADCIFCTRL] =
161 WM8776_ADCFMT_LJUST | WM8776_ADCWL_24 | WM8776_ADCMCLK;
162 data->wm8776_regs[WM8776_MSTRCTRL] =
163 WM8776_ADCRATE_256 | WM8776_DACRATE_256;
164 data->wm8776_regs[WM8776_PWRDOWN] = WM8776_HPPD;
165 data->wm8776_regs[WM8776_ADCLVOL] = 0xa5 | WM8776_ZCA;
166 data->wm8776_regs[WM8776_ADCRVOL] = 0xa5 | WM8776_ZCA;
167 data->wm8776_regs[WM8776_ADCMUX] = 0x001;
168 wm8776_registers_init(chip);
169}
170
171static void xonar_ds_init(struct oxygen *chip)
172{
173 struct xonar_wm87x6 *data = chip->model_data;
174
175 data->generic.anti_pop_delay = 300;
176 data->generic.output_enable_bit = GPIO_DS_OUTPUT_ENABLE;
177
178 wm8776_init(chip);
179 wm8766_registers_init(chip);
180
181 oxygen_write16_masked(chip, OXYGEN_GPIO_CONTROL, GPIO_DS_INPUT_ROUTE,
182 GPIO_DS_HP_DETECT | GPIO_DS_INPUT_ROUTE);
183 oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, GPIO_DS_INPUT_ROUTE);
184 oxygen_set_bits16(chip, OXYGEN_GPIO_INTERRUPT_MASK, GPIO_DS_HP_DETECT);
185 chip->interrupt_mask |= OXYGEN_INT_GPIO;
186
187 xonar_enable_output(chip);
188
189 snd_component_add(chip->card, "WM8776");
190 snd_component_add(chip->card, "WM8766");
191}
192
193static void xonar_ds_cleanup(struct oxygen *chip)
194{
195 xonar_disable_output(chip);
196}
197
198static void xonar_ds_suspend(struct oxygen *chip)
199{
200 xonar_ds_cleanup(chip);
201}
202
203static void xonar_ds_resume(struct oxygen *chip)
204{
205 wm8776_registers_init(chip);
206 wm8766_registers_init(chip);
207 xonar_enable_output(chip);
208}
209
210static void wm8776_adc_hardware_filter(unsigned int channel,
211 struct snd_pcm_hardware *hardware)
212{
213 if (channel == PCM_A) {
214 hardware->rates = SNDRV_PCM_RATE_32000 |
215 SNDRV_PCM_RATE_44100 |
216 SNDRV_PCM_RATE_48000 |
217 SNDRV_PCM_RATE_64000 |
218 SNDRV_PCM_RATE_88200 |
219 SNDRV_PCM_RATE_96000;
220 hardware->rate_max = 96000;
221 }
222}
223
224static void set_wm87x6_dac_params(struct oxygen *chip,
225 struct snd_pcm_hw_params *params)
226{
227}
228
229static void set_wm8776_adc_params(struct oxygen *chip,
230 struct snd_pcm_hw_params *params)
231{
232 u16 reg;
233
234 reg = WM8776_ADCRATE_256 | WM8776_DACRATE_256;
235 if (params_rate(params) > 48000)
236 reg |= WM8776_ADCOSR;
237 wm8776_write_cached(chip, WM8776_MSTRCTRL, reg);
238}
239
240static void update_wm8776_volume(struct oxygen *chip)
241{
242 struct xonar_wm87x6 *data = chip->model_data;
243 u8 to_change;
244
245 if (chip->dac_volume[0] == chip->dac_volume[1]) {
246 if (chip->dac_volume[0] != data->wm8776_regs[WM8776_DACLVOL] ||
247 chip->dac_volume[1] != data->wm8776_regs[WM8776_DACRVOL]) {
248 wm8776_write(chip, WM8776_DACMASTER,
249 chip->dac_volume[0] | WM8776_UPDATE);
250 data->wm8776_regs[WM8776_DACLVOL] = chip->dac_volume[0];
251 data->wm8776_regs[WM8776_DACRVOL] = chip->dac_volume[0];
252 }
253 } else {
254 to_change = (chip->dac_volume[0] !=
255 data->wm8776_regs[WM8776_DACLVOL]) << 0;
256 to_change |= (chip->dac_volume[1] !=
257 data->wm8776_regs[WM8776_DACLVOL]) << 1;
258 if (to_change & 1)
259 wm8776_write(chip, WM8776_DACLVOL, chip->dac_volume[0] |
260 ((to_change & 2) ? 0 : WM8776_UPDATE));
261 if (to_change & 2)
262 wm8776_write(chip, WM8776_DACRVOL,
263 chip->dac_volume[1] | WM8776_UPDATE);
264 }
265}
266
267static void update_wm87x6_volume(struct oxygen *chip)
268{
269 static const u8 wm8766_regs[6] = {
270 WM8766_LDA1, WM8766_RDA1,
271 WM8766_LDA2, WM8766_RDA2,
272 WM8766_LDA3, WM8766_RDA3,
273 };
274 struct xonar_wm87x6 *data = chip->model_data;
275 unsigned int i;
276 u8 to_change;
277
278 update_wm8776_volume(chip);
279 if (chip->dac_volume[2] == chip->dac_volume[3] &&
280 chip->dac_volume[2] == chip->dac_volume[4] &&
281 chip->dac_volume[2] == chip->dac_volume[5] &&
282 chip->dac_volume[2] == chip->dac_volume[6] &&
283 chip->dac_volume[2] == chip->dac_volume[7]) {
284 to_change = 0;
285 for (i = 0; i < 6; ++i)
286 if (chip->dac_volume[2] !=
287 data->wm8766_regs[wm8766_regs[i]])
288 to_change = 1;
289 if (to_change) {
290 wm8766_write(chip, WM8766_MASTDA,
291 chip->dac_volume[2] | WM8766_UPDATE);
292 for (i = 0; i < 6; ++i)
293 data->wm8766_regs[wm8766_regs[i]] =
294 chip->dac_volume[2];
295 }
296 } else {
297 to_change = 0;
298 for (i = 0; i < 6; ++i)
299 to_change |= (chip->dac_volume[2 + i] !=
300 data->wm8766_regs[wm8766_regs[i]]) << i;
301 for (i = 0; i < 6; ++i)
302 if (to_change & (1 << i))
303 wm8766_write(chip, wm8766_regs[i],
304 chip->dac_volume[2 + i] |
305 ((to_change & (0x3e << i))
306 ? 0 : WM8766_UPDATE));
307 }
308}
309
310static void update_wm8776_mute(struct oxygen *chip)
311{
312 wm8776_write_cached(chip, WM8776_DACMUTE,
313 chip->dac_mute ? WM8776_DMUTE : 0);
314}
315
316static void update_wm87x6_mute(struct oxygen *chip)
317{
318 update_wm8776_mute(chip);
319 wm8766_write_cached(chip, WM8766_DAC_CTRL2, WM8766_ZCD |
320 (chip->dac_mute ? WM8766_DMUTE_MASK : 0));
321}
322
323static void xonar_ds_gpio_changed(struct oxygen *chip)
324{
325 u16 bits;
326
327 bits = oxygen_read16(chip, OXYGEN_GPIO_DATA);
328 snd_printk(KERN_INFO "HP detect: %d\n", !!(bits & GPIO_DS_HP_DETECT));
329}
330
331static int wm8776_bit_switch_get(struct snd_kcontrol *ctl,
332 struct snd_ctl_elem_value *value)
333{
334 struct oxygen *chip = ctl->private_data;
335 struct xonar_wm87x6 *data = chip->model_data;
336 u16 bit = ctl->private_value & 0xffff;
337 unsigned int reg_index = (ctl->private_value >> 16) & 0xff;
338 bool invert = (ctl->private_value >> 24) & 1;
339
340 value->value.integer.value[0] =
341 ((data->wm8776_regs[reg_index] & bit) != 0) ^ invert;
342 return 0;
343}
344
345static int wm8776_bit_switch_put(struct snd_kcontrol *ctl,
346 struct snd_ctl_elem_value *value)
347{
348 struct oxygen *chip = ctl->private_data;
349 struct xonar_wm87x6 *data = chip->model_data;
350 u16 bit = ctl->private_value & 0xffff;
351 u16 reg_value;
352 unsigned int reg_index = (ctl->private_value >> 16) & 0xff;
353 bool invert = (ctl->private_value >> 24) & 1;
354 int changed;
355
356 mutex_lock(&chip->mutex);
357 reg_value = data->wm8776_regs[reg_index] & ~bit;
358 if (value->value.integer.value[0] ^ invert)
359 reg_value |= bit;
360 changed = reg_value != data->wm8776_regs[reg_index];
361 if (changed)
362 wm8776_write(chip, reg_index, reg_value);
363 mutex_unlock(&chip->mutex);
364 return changed;
365}
366
367static int wm8776_field_enum_info(struct snd_kcontrol *ctl,
368 struct snd_ctl_elem_info *info)
369{
370 static const char *const hld[16] = {
371 "0 ms", "2.67 ms", "5.33 ms", "10.6 ms",
372 "21.3 ms", "42.7 ms", "85.3 ms", "171 ms",
373 "341 ms", "683 ms", "1.37 s", "2.73 s",
374 "5.46 s", "10.9 s", "21.8 s", "43.7 s",
375 };
376 static const char *const atk_lim[11] = {
377 "0.25 ms", "0.5 ms", "1 ms", "2 ms",
378 "4 ms", "8 ms", "16 ms", "32 ms",
379 "64 ms", "128 ms", "256 ms",
380 };
381 static const char *const atk_alc[11] = {
382 "8.40 ms", "16.8 ms", "33.6 ms", "67.2 ms",
383 "134 ms", "269 ms", "538 ms", "1.08 s",
384 "2.15 s", "4.3 s", "8.6 s",
385 };
386 static const char *const dcy_lim[11] = {
387 "1.2 ms", "2.4 ms", "4.8 ms", "9.6 ms",
388 "19.2 ms", "38.4 ms", "76.8 ms", "154 ms",
389 "307 ms", "614 ms", "1.23 s",
390 };
391 static const char *const dcy_alc[11] = {
392 "33.5 ms", "67.0 ms", "134 ms", "268 ms",
393 "536 ms", "1.07 s", "2.14 s", "4.29 s",
394 "8.58 s", "17.2 s", "34.3 s",
395 };
396 static const char *const tranwin[8] = {
397 "0 us", "62.5 us", "125 us", "250 us",
398 "500 us", "1 ms", "2 ms", "4 ms",
399 };
400 u8 max;
401 const char *const *names;
402
403 max = (ctl->private_value >> 12) & 0xf;
404 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
405 info->count = 1;
406 info->value.enumerated.items = max + 1;
407 if (info->value.enumerated.item > max)
408 info->value.enumerated.item = max;
409 switch ((ctl->private_value >> 24) & 0x1f) {
410 case WM8776_ALCCTRL2:
411 names = hld;
412 break;
413 case WM8776_ALCCTRL3:
414 if (((ctl->private_value >> 20) & 0xf) == 0) {
415 if (ctl->private_value & LC_CONTROL_LIMITER)
416 names = atk_lim;
417 else
418 names = atk_alc;
419 } else {
420 if (ctl->private_value & LC_CONTROL_LIMITER)
421 names = dcy_lim;
422 else
423 names = dcy_alc;
424 }
425 break;
426 case WM8776_LIMITER:
427 names = tranwin;
428 break;
429 default:
430 return -ENXIO;
431 }
432 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
433 return 0;
434}
435
436static int wm8776_field_volume_info(struct snd_kcontrol *ctl,
437 struct snd_ctl_elem_info *info)
438{
439 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
440 info->count = 1;
441 info->value.integer.min = (ctl->private_value >> 8) & 0xf;
442 info->value.integer.max = (ctl->private_value >> 12) & 0xf;
443 return 0;
444}
445
446static void wm8776_field_set_from_ctl(struct snd_kcontrol *ctl)
447{
448 struct oxygen *chip = ctl->private_data;
449 struct xonar_wm87x6 *data = chip->model_data;
450 unsigned int value, reg_index, mode;
451 u8 min, max, shift;
452 u16 mask, reg_value;
453 bool invert;
454
455 if ((data->wm8776_regs[WM8776_ALCCTRL1] & WM8776_LCSEL_MASK) ==
456 WM8776_LCSEL_LIMITER)
457 mode = LC_CONTROL_LIMITER;
458 else
459 mode = LC_CONTROL_ALC;
460 if (!(ctl->private_value & mode))
461 return;
462
463 value = ctl->private_value & 0xf;
464 min = (ctl->private_value >> 8) & 0xf;
465 max = (ctl->private_value >> 12) & 0xf;
466 mask = (ctl->private_value >> 16) & 0xf;
467 shift = (ctl->private_value >> 20) & 0xf;
468 reg_index = (ctl->private_value >> 24) & 0x1f;
469 invert = (ctl->private_value >> 29) & 0x1;
470
471 if (invert)
472 value = max - (value - min);
473 reg_value = data->wm8776_regs[reg_index];
474 reg_value &= ~(mask << shift);
475 reg_value |= value << shift;
476 wm8776_write_cached(chip, reg_index, reg_value);
477}
478
479static int wm8776_field_set(struct snd_kcontrol *ctl, unsigned int value)
480{
481 struct oxygen *chip = ctl->private_data;
482 u8 min, max;
483 int changed;
484
485 min = (ctl->private_value >> 8) & 0xf;
486 max = (ctl->private_value >> 12) & 0xf;
487 if (value < min || value > max)
488 return -EINVAL;
489 mutex_lock(&chip->mutex);
490 changed = value != (ctl->private_value & 0xf);
491 if (changed) {
492 ctl->private_value = (ctl->private_value & ~0xf) | value;
493 wm8776_field_set_from_ctl(ctl);
494 }
495 mutex_unlock(&chip->mutex);
496 return changed;
497}
498
499static int wm8776_field_enum_get(struct snd_kcontrol *ctl,
500 struct snd_ctl_elem_value *value)
501{
502 value->value.enumerated.item[0] = ctl->private_value & 0xf;
503 return 0;
504}
505
506static int wm8776_field_volume_get(struct snd_kcontrol *ctl,
507 struct snd_ctl_elem_value *value)
508{
509 value->value.integer.value[0] = ctl->private_value & 0xf;
510 return 0;
511}
512
513static int wm8776_field_enum_put(struct snd_kcontrol *ctl,
514 struct snd_ctl_elem_value *value)
515{
516 return wm8776_field_set(ctl, value->value.enumerated.item[0]);
517}
518
519static int wm8776_field_volume_put(struct snd_kcontrol *ctl,
520 struct snd_ctl_elem_value *value)
521{
522 return wm8776_field_set(ctl, value->value.integer.value[0]);
523}
524
525static int wm8776_hp_vol_info(struct snd_kcontrol *ctl,
526 struct snd_ctl_elem_info *info)
527{
528 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
529 info->count = 2;
530 info->value.integer.min = 0x79 - 60;
531 info->value.integer.max = 0x7f;
532 return 0;
533}
534
535static int wm8776_hp_vol_get(struct snd_kcontrol *ctl,
536 struct snd_ctl_elem_value *value)
537{
538 struct oxygen *chip = ctl->private_data;
539 struct xonar_wm87x6 *data = chip->model_data;
540
541 mutex_lock(&chip->mutex);
542 value->value.integer.value[0] =
543 data->wm8776_regs[WM8776_HPLVOL] & WM8776_HPATT_MASK;
544 value->value.integer.value[1] =
545 data->wm8776_regs[WM8776_HPRVOL] & WM8776_HPATT_MASK;
546 mutex_unlock(&chip->mutex);
547 return 0;
548}
549
550static int wm8776_hp_vol_put(struct snd_kcontrol *ctl,
551 struct snd_ctl_elem_value *value)
552{
553 struct oxygen *chip = ctl->private_data;
554 struct xonar_wm87x6 *data = chip->model_data;
555 u8 to_update;
556
557 mutex_lock(&chip->mutex);
558 to_update = (value->value.integer.value[0] !=
559 (data->wm8776_regs[WM8776_HPLVOL] & WM8776_HPATT_MASK))
560 << 0;
561 to_update |= (value->value.integer.value[1] !=
562 (data->wm8776_regs[WM8776_HPRVOL] & WM8776_HPATT_MASK))
563 << 1;
564 if (value->value.integer.value[0] == value->value.integer.value[1]) {
565 if (to_update) {
566 wm8776_write(chip, WM8776_HPMASTER,
567 value->value.integer.value[0] |
568 WM8776_HPZCEN | WM8776_UPDATE);
569 data->wm8776_regs[WM8776_HPLVOL] =
570 value->value.integer.value[0] | WM8776_HPZCEN;
571 data->wm8776_regs[WM8776_HPRVOL] =
572 value->value.integer.value[0] | WM8776_HPZCEN;
573 }
574 } else {
575 if (to_update & 1)
576 wm8776_write(chip, WM8776_HPLVOL,
577 value->value.integer.value[0] |
578 WM8776_HPZCEN |
579 ((to_update & 2) ? 0 : WM8776_UPDATE));
580 if (to_update & 2)
581 wm8776_write(chip, WM8776_HPRVOL,
582 value->value.integer.value[1] |
583 WM8776_HPZCEN | WM8776_UPDATE);
584 }
585 mutex_unlock(&chip->mutex);
586 return to_update != 0;
587}
588
589static int wm8776_input_mux_get(struct snd_kcontrol *ctl,
590 struct snd_ctl_elem_value *value)
591{
592 struct oxygen *chip = ctl->private_data;
593 struct xonar_wm87x6 *data = chip->model_data;
594 unsigned int mux_bit = ctl->private_value;
595
596 value->value.integer.value[0] =
597 !!(data->wm8776_regs[WM8776_ADCMUX] & mux_bit);
598 return 0;
599}
600
601static int wm8776_input_mux_put(struct snd_kcontrol *ctl,
602 struct snd_ctl_elem_value *value)
603{
604 struct oxygen *chip = ctl->private_data;
605 struct xonar_wm87x6 *data = chip->model_data;
606 unsigned int mux_bit = ctl->private_value;
607 u16 reg;
608 int changed;
609
610 mutex_lock(&chip->mutex);
611 reg = data->wm8776_regs[WM8776_ADCMUX];
612 if (value->value.integer.value[0]) {
613 reg &= ~0x003;
614 reg |= mux_bit;
615 } else
616 reg &= ~mux_bit;
617 changed = reg != data->wm8776_regs[WM8776_ADCMUX];
618 if (changed) {
619 oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
620 reg & 1 ? GPIO_DS_INPUT_ROUTE : 0,
621 GPIO_DS_INPUT_ROUTE);
622 wm8776_write(chip, WM8776_ADCMUX, reg);
623 }
624 mutex_unlock(&chip->mutex);
625 return changed;
626}
627
628static int wm8776_input_vol_info(struct snd_kcontrol *ctl,
629 struct snd_ctl_elem_info *info)
630{
631 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
632 info->count = 2;
633 info->value.integer.min = 0xa5;
634 info->value.integer.max = 0xff;
635 return 0;
636}
637
638static int wm8776_input_vol_get(struct snd_kcontrol *ctl,
639 struct snd_ctl_elem_value *value)
640{
641 struct oxygen *chip = ctl->private_data;
642 struct xonar_wm87x6 *data = chip->model_data;
643
644 mutex_lock(&chip->mutex);
645 value->value.integer.value[0] =
646 data->wm8776_regs[WM8776_ADCLVOL] & WM8776_AGMASK;
647 value->value.integer.value[1] =
648 data->wm8776_regs[WM8776_ADCRVOL] & WM8776_AGMASK;
649 mutex_unlock(&chip->mutex);
650 return 0;
651}
652
653static int wm8776_input_vol_put(struct snd_kcontrol *ctl,
654 struct snd_ctl_elem_value *value)
655{
656 struct oxygen *chip = ctl->private_data;
657 struct xonar_wm87x6 *data = chip->model_data;
658 int changed = 0;
659
660 mutex_lock(&chip->mutex);
661 changed = (value->value.integer.value[0] !=
662 (data->wm8776_regs[WM8776_ADCLVOL] & WM8776_AGMASK)) ||
663 (value->value.integer.value[1] !=
664 (data->wm8776_regs[WM8776_ADCRVOL] & WM8776_AGMASK));
665 wm8776_write_cached(chip, WM8776_ADCLVOL,
666 value->value.integer.value[0] | WM8776_ZCA);
667 wm8776_write_cached(chip, WM8776_ADCRVOL,
668 value->value.integer.value[1] | WM8776_ZCA);
669 mutex_unlock(&chip->mutex);
670 return changed;
671}
672
673static int wm8776_level_control_info(struct snd_kcontrol *ctl,
674 struct snd_ctl_elem_info *info)
675{
676 static const char *const names[3] = {
677 "None", "Peak Limiter", "Automatic Level Control"
678 };
679 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
680 info->count = 1;
681 info->value.enumerated.items = 3;
682 if (info->value.enumerated.item >= 3)
683 info->value.enumerated.item = 2;
684 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
685 return 0;
686}
687
688static int wm8776_level_control_get(struct snd_kcontrol *ctl,
689 struct snd_ctl_elem_value *value)
690{
691 struct oxygen *chip = ctl->private_data;
692 struct xonar_wm87x6 *data = chip->model_data;
693
694 if (!(data->wm8776_regs[WM8776_ALCCTRL2] & WM8776_LCEN))
695 value->value.enumerated.item[0] = 0;
696 else if ((data->wm8776_regs[WM8776_ALCCTRL1] & WM8776_LCSEL_MASK) ==
697 WM8776_LCSEL_LIMITER)
698 value->value.enumerated.item[0] = 1;
699 else
700 value->value.enumerated.item[0] = 2;
701 return 0;
702}
703
704static void activate_control(struct oxygen *chip,
705 struct snd_kcontrol *ctl, unsigned int mode)
706{
707 unsigned int access;
708
709 if (ctl->private_value & mode)
710 access = 0;
711 else
712 access = SNDRV_CTL_ELEM_ACCESS_INACTIVE;
713 if ((ctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_INACTIVE) != access) {
714 ctl->vd[0].access ^= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
715 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_INFO, &ctl->id);
716 }
717}
718
719static int wm8776_level_control_put(struct snd_kcontrol *ctl,
720 struct snd_ctl_elem_value *value)
721{
722 struct oxygen *chip = ctl->private_data;
723 struct xonar_wm87x6 *data = chip->model_data;
724 unsigned int mode = 0, i;
725 u16 ctrl1, ctrl2;
726 int changed;
727
728 if (value->value.enumerated.item[0] >= 3)
729 return -EINVAL;
730 mutex_lock(&chip->mutex);
731 changed = value->value.enumerated.item[0] != ctl->private_value;
732 if (changed) {
733 ctl->private_value = value->value.enumerated.item[0];
734 ctrl1 = data->wm8776_regs[WM8776_ALCCTRL1];
735 ctrl2 = data->wm8776_regs[WM8776_ALCCTRL2];
736 switch (value->value.enumerated.item[0]) {
737 default:
738 wm8776_write_cached(chip, WM8776_ALCCTRL2,
739 ctrl2 & ~WM8776_LCEN);
740 break;
741 case 1:
742 wm8776_write_cached(chip, WM8776_ALCCTRL1,
743 (ctrl1 & ~WM8776_LCSEL_MASK) |
744 WM8776_LCSEL_LIMITER);
745 wm8776_write_cached(chip, WM8776_ALCCTRL2,
746 ctrl2 | WM8776_LCEN);
747 mode = LC_CONTROL_LIMITER;
748 break;
749 case 2:
750 wm8776_write_cached(chip, WM8776_ALCCTRL1,
751 (ctrl1 & ~WM8776_LCSEL_MASK) |
752 WM8776_LCSEL_ALC_STEREO);
753 wm8776_write_cached(chip, WM8776_ALCCTRL2,
754 ctrl2 | WM8776_LCEN);
755 mode = LC_CONTROL_ALC;
756 break;
757 }
758 for (i = 0; i < ARRAY_SIZE(data->lc_controls); ++i)
759 activate_control(chip, data->lc_controls[i], mode);
760 }
761 mutex_unlock(&chip->mutex);
762 return changed;
763}
764
765static int hpf_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info)
766{
767 static const char *const names[2] = {
768 "None", "High-pass Filter"
769 };
770
771 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
772 info->count = 1;
773 info->value.enumerated.items = 2;
774 if (info->value.enumerated.item >= 2)
775 info->value.enumerated.item = 1;
776 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
777 return 0;
778}
779
780static int hpf_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
781{
782 struct oxygen *chip = ctl->private_data;
783 struct xonar_wm87x6 *data = chip->model_data;
784
785 value->value.enumerated.item[0] =
786 !(data->wm8776_regs[WM8776_ADCIFCTRL] & WM8776_ADCHPD);
787 return 0;
788}
789
790static int hpf_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
791{
792 struct oxygen *chip = ctl->private_data;
793 struct xonar_wm87x6 *data = chip->model_data;
794 unsigned int reg;
795 int changed;
796
797 mutex_lock(&chip->mutex);
798 reg = data->wm8776_regs[WM8776_ADCIFCTRL] & ~WM8776_ADCHPD;
799 if (!value->value.enumerated.item[0])
800 reg |= WM8776_ADCHPD;
801 changed = reg != data->wm8776_regs[WM8776_ADCIFCTRL];
802 if (changed)
803 wm8776_write(chip, WM8776_ADCIFCTRL, reg);
804 mutex_unlock(&chip->mutex);
805 return changed;
806}
807
808#define WM8776_BIT_SWITCH(xname, reg, bit, invert, flags) { \
809 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
810 .name = xname, \
811 .info = snd_ctl_boolean_mono_info, \
812 .get = wm8776_bit_switch_get, \
813 .put = wm8776_bit_switch_put, \
814 .private_value = ((reg) << 16) | (bit) | ((invert) << 24) | (flags), \
815}
816#define _WM8776_FIELD_CTL(xname, reg, shift, initval, min, max, mask, flags) \
817 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
818 .name = xname, \
819 .private_value = (initval) | ((min) << 8) | ((max) << 12) | \
820 ((mask) << 16) | ((shift) << 20) | ((reg) << 24) | (flags)
821#define WM8776_FIELD_CTL_ENUM(xname, reg, shift, init, min, max, mask, flags) {\
822 _WM8776_FIELD_CTL(xname " Capture Enum", \
823 reg, shift, init, min, max, mask, flags), \
824 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
825 SNDRV_CTL_ELEM_ACCESS_INACTIVE, \
826 .info = wm8776_field_enum_info, \
827 .get = wm8776_field_enum_get, \
828 .put = wm8776_field_enum_put, \
829}
830#define WM8776_FIELD_CTL_VOLUME(a, b, c, d, e, f, g, h, tlv_p) { \
831 _WM8776_FIELD_CTL(a " Capture Volume", b, c, d, e, f, g, h), \
832 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
833 SNDRV_CTL_ELEM_ACCESS_INACTIVE | \
834 SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
835 .info = wm8776_field_volume_info, \
836 .get = wm8776_field_volume_get, \
837 .put = wm8776_field_volume_put, \
838 .tlv = { .p = tlv_p }, \
839}
840
841static const DECLARE_TLV_DB_SCALE(wm87x6_dac_db_scale, -6000, 50, 0);
842static const DECLARE_TLV_DB_SCALE(wm8776_adc_db_scale, -2100, 50, 0);
843static const DECLARE_TLV_DB_SCALE(wm8776_hp_db_scale, -6000, 100, 0);
844static const DECLARE_TLV_DB_SCALE(wm8776_lct_db_scale, -1600, 100, 0);
845static const DECLARE_TLV_DB_SCALE(wm8776_maxgain_db_scale, 0, 400, 0);
846static const DECLARE_TLV_DB_SCALE(wm8776_ngth_db_scale, -7800, 600, 0);
847static const DECLARE_TLV_DB_SCALE(wm8776_maxatten_lim_db_scale, -1200, 100, 0);
848static const DECLARE_TLV_DB_SCALE(wm8776_maxatten_alc_db_scale, -2100, 400, 0);
849
850static const struct snd_kcontrol_new ds_controls[] = {
851 {
852 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
853 .name = "Headphone Playback Volume",
854 .info = wm8776_hp_vol_info,
855 .get = wm8776_hp_vol_get,
856 .put = wm8776_hp_vol_put,
857 .tlv = { .p = wm8776_hp_db_scale },
858 },
859 WM8776_BIT_SWITCH("Headphone Playback Switch",
860 WM8776_PWRDOWN, WM8776_HPPD, 1, 0),
861 {
862 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
863 .name = "Input Capture Volume",
864 .info = wm8776_input_vol_info,
865 .get = wm8776_input_vol_get,
866 .put = wm8776_input_vol_put,
867 .tlv = { .p = wm8776_adc_db_scale },
868 },
869 {
870 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
871 .name = "Line Capture Switch",
872 .info = snd_ctl_boolean_mono_info,
873 .get = wm8776_input_mux_get,
874 .put = wm8776_input_mux_put,
875 .private_value = 1 << 0,
876 },
877 {
878 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
879 .name = "Mic Capture Switch",
880 .info = snd_ctl_boolean_mono_info,
881 .get = wm8776_input_mux_get,
882 .put = wm8776_input_mux_put,
883 .private_value = 1 << 1,
884 },
885 WM8776_BIT_SWITCH("Aux", WM8776_ADCMUX, 1 << 2, 0, 0),
886 {
887 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
888 .name = "ADC Filter Capture Enum",
889 .info = hpf_info,
890 .get = hpf_get,
891 .put = hpf_put,
892 },
893 {
894 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
895 .name = "Level Control Capture Enum",
896 .info = wm8776_level_control_info,
897 .get = wm8776_level_control_get,
898 .put = wm8776_level_control_put,
899 .private_value = 0,
900 },
901};
902static const struct snd_kcontrol_new lc_controls[] = {
903 WM8776_FIELD_CTL_VOLUME("Limiter Threshold",
904 WM8776_ALCCTRL1, 0, 11, 0, 15, 0xf,
905 LC_CONTROL_LIMITER, wm8776_lct_db_scale),
906 WM8776_FIELD_CTL_ENUM("Limiter Attack Time",
907 WM8776_ALCCTRL3, 0, 2, 0, 10, 0xf,
908 LC_CONTROL_LIMITER),
909 WM8776_FIELD_CTL_ENUM("Limiter Decay Time",
910 WM8776_ALCCTRL3, 4, 3, 0, 10, 0xf,
911 LC_CONTROL_LIMITER),
912 WM8776_FIELD_CTL_ENUM("Limiter Transient Window",
913 WM8776_LIMITER, 4, 2, 0, 7, 0x7,
914 LC_CONTROL_LIMITER),
915 WM8776_FIELD_CTL_VOLUME("Limiter Maximum Attenuation",
916 WM8776_LIMITER, 0, 6, 3, 12, 0xf,
917 LC_CONTROL_LIMITER,
918 wm8776_maxatten_lim_db_scale),
919 WM8776_FIELD_CTL_VOLUME("ALC Target Level",
920 WM8776_ALCCTRL1, 0, 11, 0, 15, 0xf,
921 LC_CONTROL_ALC, wm8776_lct_db_scale),
922 WM8776_FIELD_CTL_ENUM("ALC Attack Time",
923 WM8776_ALCCTRL3, 0, 2, 0, 10, 0xf,
924 LC_CONTROL_ALC),
925 WM8776_FIELD_CTL_ENUM("ALC Decay Time",
926 WM8776_ALCCTRL3, 4, 3, 0, 10, 0xf,
927 LC_CONTROL_ALC),
928 WM8776_FIELD_CTL_VOLUME("ALC Maximum Gain",
929 WM8776_ALCCTRL1, 4, 7, 1, 7, 0x7,
930 LC_CONTROL_ALC, wm8776_maxgain_db_scale),
931 WM8776_FIELD_CTL_VOLUME("ALC Maximum Attenuation",
932 WM8776_LIMITER, 0, 10, 10, 15, 0xf,
933 LC_CONTROL_ALC, wm8776_maxatten_alc_db_scale),
934 WM8776_FIELD_CTL_ENUM("ALC Hold Time",
935 WM8776_ALCCTRL2, 0, 0, 0, 15, 0xf,
936 LC_CONTROL_ALC),
937 WM8776_BIT_SWITCH("Noise Gate Capture Switch",
938 WM8776_NOISEGATE, WM8776_NGAT, 0,
939 LC_CONTROL_ALC),
940 WM8776_FIELD_CTL_VOLUME("Noise Gate Threshold",
941 WM8776_NOISEGATE, 2, 0, 0, 7, 0x7,
942 LC_CONTROL_ALC, wm8776_ngth_db_scale),
943};
944
945static int xonar_ds_control_filter(struct snd_kcontrol_new *template)
946{
947 if (!strncmp(template->name, "CD Capture ", 11))
948 return 1; /* no CD input */
949 return 0;
950}
951
952static int xonar_ds_mixer_init(struct oxygen *chip)
953{
954 struct xonar_wm87x6 *data = chip->model_data;
955 unsigned int i;
956 struct snd_kcontrol *ctl;
957 int err;
958
959 for (i = 0; i < ARRAY_SIZE(ds_controls); ++i) {
960 ctl = snd_ctl_new1(&ds_controls[i], chip);
961 if (!ctl)
962 return -ENOMEM;
963 err = snd_ctl_add(chip->card, ctl);
964 if (err < 0)
965 return err;
966 }
967 BUILD_BUG_ON(ARRAY_SIZE(lc_controls) != ARRAY_SIZE(data->lc_controls));
968 for (i = 0; i < ARRAY_SIZE(lc_controls); ++i) {
969 ctl = snd_ctl_new1(&lc_controls[i], chip);
970 if (!ctl)
971 return -ENOMEM;
972 err = snd_ctl_add(chip->card, ctl);
973 if (err < 0)
974 return err;
975 data->lc_controls[i] = ctl;
976 }
977 return 0;
978}
979
980static const struct oxygen_model model_xonar_ds = {
981 .shortname = "Xonar DS",
982 .longname = "Asus Virtuoso 200",
983 .chip = "AV200",
984 .init = xonar_ds_init,
985 .control_filter = xonar_ds_control_filter,
986 .mixer_init = xonar_ds_mixer_init,
987 .cleanup = xonar_ds_cleanup,
988 .suspend = xonar_ds_suspend,
989 .resume = xonar_ds_resume,
990 .pcm_hardware_filter = wm8776_adc_hardware_filter,
991 .get_i2s_mclk = oxygen_default_i2s_mclk,
992 .set_dac_params = set_wm87x6_dac_params,
993 .set_adc_params = set_wm8776_adc_params,
994 .update_dac_volume = update_wm87x6_volume,
995 .update_dac_mute = update_wm87x6_mute,
996 .gpio_changed = xonar_ds_gpio_changed,
997 .dac_tlv = wm87x6_dac_db_scale,
998 .model_data_size = sizeof(struct xonar_wm87x6),
999 .device_config = PLAYBACK_0_TO_I2S |
1000 PLAYBACK_1_TO_SPDIF |
1001 CAPTURE_0_FROM_I2S_1,
1002 .dac_channels = 8,
1003 .dac_volume_min = 255 - 2*60,
1004 .dac_volume_max = 255,
1005 .function_flags = OXYGEN_FUNCTION_SPI,
1006 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1007 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1008};
1009
1010int __devinit get_xonar_wm87x6_model(struct oxygen *chip,
1011 const struct pci_device_id *id)
1012{
1013 switch (id->subdevice) {
1014 case 0x838e:
1015 chip->model = model_xonar_ds;
1016 break;
1017 default:
1018 return -EINVAL;
1019 }
1020 return 0;
1021}
diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c
index 833e9c7b27c7..95cfde27d25c 100644
--- a/sound/pci/pcxhr/pcxhr.c
+++ b/sound/pci/pcxhr/pcxhr.c
@@ -94,7 +94,7 @@ enum {
94 PCI_ID_LAST 94 PCI_ID_LAST
95}; 95};
96 96
97static struct pci_device_id pcxhr_ids[] = { 97static DEFINE_PCI_DEVICE_TABLE(pcxhr_ids) = {
98 { 0x10b5, 0x9656, 0x1369, 0xb001, 0, 0, PCI_ID_VX882HR, }, 98 { 0x10b5, 0x9656, 0x1369, 0xb001, 0, 0, PCI_ID_VX882HR, },
99 { 0x10b5, 0x9656, 0x1369, 0xb101, 0, 0, PCI_ID_PCX882HR, }, 99 { 0x10b5, 0x9656, 0x1369, 0xb101, 0, 0, PCI_ID_PCX882HR, },
100 { 0x10b5, 0x9656, 0x1369, 0xb201, 0, 0, PCI_ID_VX881HR, }, 100 { 0x10b5, 0x9656, 0x1369, 0xb201, 0, 0, PCI_ID_VX881HR, },
diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c
index b5ca02e2038c..ad4462677615 100644
--- a/sound/pci/riptide/riptide.c
+++ b/sound/pci/riptide/riptide.c
@@ -506,7 +506,7 @@ static int riptide_reset(struct cmdif *cif, struct snd_riptide *chip);
506/* 506/*
507 */ 507 */
508 508
509static struct pci_device_id snd_riptide_ids[] = { 509static DEFINE_PCI_DEVICE_TABLE(snd_riptide_ids) = {
510 { PCI_DEVICE(0x127a, 0x4310) }, 510 { PCI_DEVICE(0x127a, 0x4310) },
511 { PCI_DEVICE(0x127a, 0x4320) }, 511 { PCI_DEVICE(0x127a, 0x4320) },
512 { PCI_DEVICE(0x127a, 0x4330) }, 512 { PCI_DEVICE(0x127a, 0x4330) },
@@ -515,7 +515,7 @@ static struct pci_device_id snd_riptide_ids[] = {
515}; 515};
516 516
517#ifdef SUPPORT_JOYSTICK 517#ifdef SUPPORT_JOYSTICK
518static struct pci_device_id snd_riptide_joystick_ids[] __devinitdata = { 518static DEFINE_PCI_DEVICE_TABLE(snd_riptide_joystick_ids) = {
519 { PCI_DEVICE(0x127a, 0x4312) }, 519 { PCI_DEVICE(0x127a, 0x4312) },
520 { PCI_DEVICE(0x127a, 0x4322) }, 520 { PCI_DEVICE(0x127a, 0x4322) },
521 { PCI_DEVICE(0x127a, 0x4332) }, 521 { PCI_DEVICE(0x127a, 0x4332) },
@@ -1058,7 +1058,7 @@ setsamplerate(struct cmdif *cif, unsigned char *intdec, unsigned int rate)
1058 rptr.retwords[2] != M && 1058 rptr.retwords[2] != M &&
1059 rptr.retwords[3] != N && 1059 rptr.retwords[3] != N &&
1060 i++ < MAX_WRITE_RETRY); 1060 i++ < MAX_WRITE_RETRY);
1061 if (i == MAX_WRITE_RETRY) { 1061 if (i > MAX_WRITE_RETRY) {
1062 snd_printdd("sent samplerate %d: %d failed\n", 1062 snd_printdd("sent samplerate %d: %d failed\n",
1063 *intdec, rate); 1063 *intdec, rate);
1064 return -EIO; 1064 return -EIO;
@@ -1974,9 +1974,9 @@ snd_riptide_proc_read(struct snd_info_entry *entry,
1974 } 1974 }
1975 snd_iprintf(buffer, "Paths:\n"); 1975 snd_iprintf(buffer, "Paths:\n");
1976 i = getpaths(cif, p); 1976 i = getpaths(cif, p);
1977 while (i--) { 1977 while (i >= 2) {
1978 snd_iprintf(buffer, "%x->%x ", p[i - 1], p[i]); 1978 i -= 2;
1979 i--; 1979 snd_iprintf(buffer, "%x->%x ", p[i], p[i + 1]);
1980 } 1980 }
1981 snd_iprintf(buffer, "\n"); 1981 snd_iprintf(buffer, "\n");
1982} 1982}
diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c
index f977dba7cbd0..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>
@@ -226,7 +226,7 @@ struct rme32 {
226 struct snd_kcontrol *spdif_ctl; 226 struct snd_kcontrol *spdif_ctl;
227}; 227};
228 228
229static struct pci_device_id snd_rme32_ids[] = { 229static DEFINE_PCI_DEVICE_TABLE(snd_rme32_ids) = {
230 {PCI_VDEVICE(XILINX_RME, PCI_DEVICE_ID_RME_DIGI32), 0,}, 230 {PCI_VDEVICE(XILINX_RME, PCI_DEVICE_ID_RME_DIGI32), 0,},
231 {PCI_VDEVICE(XILINX_RME, PCI_DEVICE_ID_RME_DIGI32_8), 0,}, 231 {PCI_VDEVICE(XILINX_RME, PCI_DEVICE_ID_RME_DIGI32_8), 0,},
232 {PCI_VDEVICE(XILINX_RME, PCI_DEVICE_ID_RME_DIGI32_PRO), 0,}, 232 {PCI_VDEVICE(XILINX_RME, PCI_DEVICE_ID_RME_DIGI32_PRO), 0,},
diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c
index 2ba5c0fd55db..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>
@@ -231,7 +230,7 @@ struct rme96 {
231 struct snd_kcontrol *spdif_ctl; 230 struct snd_kcontrol *spdif_ctl;
232}; 231};
233 232
234static struct pci_device_id snd_rme96_ids[] = { 233static DEFINE_PCI_DEVICE_TABLE(snd_rme96_ids) = {
235 { PCI_VDEVICE(XILINX, PCI_DEVICE_ID_RME_DIGI96), 0, }, 234 { PCI_VDEVICE(XILINX, PCI_DEVICE_ID_RME_DIGI96), 0, },
236 { PCI_VDEVICE(XILINX, PCI_DEVICE_ID_RME_DIGI96_8), 0, }, 235 { PCI_VDEVICE(XILINX, PCI_DEVICE_ID_RME_DIGI96_8), 0, },
237 { PCI_VDEVICE(XILINX, PCI_DEVICE_ID_RME_DIGI96_8_PRO), 0, }, 236 { PCI_VDEVICE(XILINX, PCI_DEVICE_ID_RME_DIGI96_8_PRO), 0, },
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 7bb827c7d806..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>
@@ -585,7 +584,7 @@ static void snd_hammerfall_free_buffer(struct snd_dma_buffer *dmab, struct pci_d
585} 584}
586 585
587 586
588static struct pci_device_id snd_hdsp_ids[] = { 587static DEFINE_PCI_DEVICE_TABLE(snd_hdsp_ids) = {
589 { 588 {
590 .vendor = PCI_VENDOR_ID_XILINX, 589 .vendor = PCI_VENDOR_ID_XILINX,
591 .device = PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP, 590 .device = PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP,
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index 0dce331a2a3b..547b713d7204 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -512,7 +512,7 @@ static char channel_map_madi_ss[HDSPM_MAX_CHANNELS] = {
512}; 512};
513 513
514 514
515static struct pci_device_id snd_hdspm_ids[] __devinitdata = { 515static DEFINE_PCI_DEVICE_TABLE(snd_hdspm_ids) = {
516 { 516 {
517 .vendor = PCI_VENDOR_ID_XILINX, 517 .vendor = PCI_VENDOR_ID_XILINX,
518 .device = PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP_MADI, 518 .device = PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP_MADI,
@@ -2479,7 +2479,7 @@ static int snd_hdspm_put_qs_wire(struct snd_kcontrol *kcontrol,
2479 on MADICARD 2479 on MADICARD
2480 - playback mixer matrix: [channelout+64] [output] [value] 2480 - playback mixer matrix: [channelout+64] [output] [value]
2481 - input(thru) mixer matrix: [channelin] [output] [value] 2481 - input(thru) mixer matrix: [channelin] [output] [value]
2482 (better do 2 kontrols for seperation ?) 2482 (better do 2 kontrols for separation ?)
2483*/ 2483*/
2484 2484
2485#define HDSPM_MIXER(xname, xindex) \ 2485#define HDSPM_MIXER(xname, xindex) \
@@ -3017,7 +3017,7 @@ snd_hdspm_proc_read_madi(struct snd_info_entry * entry,
3017 insel = "Coaxial"; 3017 insel = "Coaxial";
3018 break; 3018 break;
3019 default: 3019 default:
3020 insel = "Unkown"; 3020 insel = "Unknown";
3021 } 3021 }
3022 3022
3023 switch (hdspm->control_register & HDSPM_SyncRefMask) { 3023 switch (hdspm->control_register & HDSPM_SyncRefMask) {
@@ -3028,7 +3028,7 @@ snd_hdspm_proc_read_madi(struct snd_info_entry * entry,
3028 syncref = "MADI"; 3028 syncref = "MADI";
3029 break; 3029 break;
3030 default: 3030 default:
3031 syncref = "Unkown"; 3031 syncref = "Unknown";
3032 } 3032 }
3033 snd_iprintf(buffer, "Inputsel = %s, SyncRef = %s\n", insel, 3033 snd_iprintf(buffer, "Inputsel = %s, SyncRef = %s\n", insel,
3034 syncref); 3034 syncref);
diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c
index bc539abb2105..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>
@@ -314,7 +313,7 @@ static void snd_hammerfall_free_buffer(struct snd_dma_buffer *dmab, struct pci_d
314} 313}
315 314
316 315
317static struct pci_device_id snd_rme9652_ids[] = { 316static DEFINE_PCI_DEVICE_TABLE(snd_rme9652_ids) = {
318 { 317 {
319 .vendor = 0x10ee, 318 .vendor = 0x10ee,
320 .device = 0x3fc4, 319 .device = 0x3fc4,
diff --git a/sound/pci/sis7019.c b/sound/pci/sis7019.c
index 1a5ff0611072..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>
@@ -48,7 +49,7 @@ MODULE_PARM_DESC(id, "ID string for SiS7019 Audio Accelerator.");
48module_param(enable, bool, 0444); 49module_param(enable, bool, 0444);
49MODULE_PARM_DESC(enable, "Enable SiS7019 Audio Accelerator."); 50MODULE_PARM_DESC(enable, "Enable SiS7019 Audio Accelerator.");
50 51
51static struct pci_device_id snd_sis7019_ids[] = { 52static DEFINE_PCI_DEVICE_TABLE(snd_sis7019_ids) = {
52 { PCI_DEVICE(PCI_VENDOR_ID_SI, 0x7019) }, 53 { PCI_DEVICE(PCI_VENDOR_ID_SI, 0x7019) },
53 { 0, } 54 { 0, }
54}; 55};
diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c
index 1f6406c4534d..337b9facadfd 100644
--- a/sound/pci/sonicvibes.c
+++ b/sound/pci/sonicvibes.c
@@ -242,7 +242,7 @@ struct sonicvibes {
242#endif 242#endif
243}; 243};
244 244
245static struct pci_device_id snd_sonic_ids[] = { 245static DEFINE_PCI_DEVICE_TABLE(snd_sonic_ids) = {
246 { PCI_VDEVICE(S3, 0xca00), 0, }, 246 { PCI_VDEVICE(S3, 0xca00), 0, },
247 { 0, } 247 { 0, }
248}; 248};
diff --git a/sound/pci/trident/trident.c b/sound/pci/trident/trident.c
index 21cef97d478d..6d0581841d7a 100644
--- a/sound/pci/trident/trident.c
+++ b/sound/pci/trident/trident.c
@@ -62,7 +62,7 @@ MODULE_PARM_DESC(pcm_channels, "Number of hardware channels assigned for PCM.");
62module_param_array(wavetable_size, int, NULL, 0444); 62module_param_array(wavetable_size, int, NULL, 0444);
63MODULE_PARM_DESC(wavetable_size, "Maximum memory size in kB for wavetable synth."); 63MODULE_PARM_DESC(wavetable_size, "Maximum memory size in kB for wavetable synth.");
64 64
65static struct pci_device_id snd_trident_ids[] = { 65static DEFINE_PCI_DEVICE_TABLE(snd_trident_ids) = {
66 {PCI_DEVICE(PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_DX), 66 {PCI_DEVICE(PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_DX),
67 PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0}, 67 PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0},
68 {PCI_DEVICE(PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_NX), 68 {PCI_DEVICE(PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_NX),
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index 8a332d2f615c..7e494b6a1d0e 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -401,7 +401,7 @@ struct via82xx {
401#endif 401#endif
402}; 402};
403 403
404static struct pci_device_id snd_via82xx_ids[] = { 404static DEFINE_PCI_DEVICE_TABLE(snd_via82xx_ids) = {
405 /* 0x1106, 0x3058 */ 405 /* 0x1106, 0x3058 */
406 { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C686_5), TYPE_CARD_VIA686, }, /* 686A */ 406 { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C686_5), TYPE_CARD_VIA686, }, /* 686A */
407 /* 0x1106, 0x3059 */ 407 /* 0x1106, 0x3059 */
@@ -1791,6 +1791,12 @@ static struct ac97_quirk ac97_quirks[] = {
1791 .type = AC97_TUNE_HP_ONLY 1791 .type = AC97_TUNE_HP_ONLY
1792 }, 1792 },
1793 { 1793 {
1794 .subvendor = 0x110a,
1795 .subdevice = 0x0079,
1796 .name = "Fujitsu Siemens D1289",
1797 .type = AC97_TUNE_HP_ONLY
1798 },
1799 {
1794 .subvendor = 0x1019, 1800 .subvendor = 0x1019,
1795 .subdevice = 0x0a81, 1801 .subdevice = 0x0a81,
1796 .name = "ECS K7VTA3", 1802 .name = "ECS K7VTA3",
diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c
index 47eb61561dfc..f7e8bbbe3953 100644
--- a/sound/pci/via82xx_modem.c
+++ b/sound/pci/via82xx_modem.c
@@ -260,7 +260,7 @@ struct via82xx_modem {
260 struct snd_info_entry *proc_entry; 260 struct snd_info_entry *proc_entry;
261}; 261};
262 262
263static struct pci_device_id snd_via82xx_modem_ids[] = { 263static DEFINE_PCI_DEVICE_TABLE(snd_via82xx_modem_ids) = {
264 { PCI_VDEVICE(VIA, 0x3068), TYPE_CARD_VIA82XX_MODEM, }, 264 { PCI_VDEVICE(VIA, 0x3068), TYPE_CARD_VIA82XX_MODEM, },
265 { 0, } 265 { 0, }
266}; 266};
diff --git a/sound/pci/vx222/vx222.c b/sound/pci/vx222/vx222.c
index fc9136c3e0d7..99a9a814be0b 100644
--- a/sound/pci/vx222/vx222.c
+++ b/sound/pci/vx222/vx222.c
@@ -60,7 +60,7 @@ enum {
60 VX_PCI_VX222_NEW 60 VX_PCI_VX222_NEW
61}; 61};
62 62
63static struct pci_device_id snd_vx222_ids[] = { 63static DEFINE_PCI_DEVICE_TABLE(snd_vx222_ids) = {
64 { 0x10b5, 0x9050, 0x1369, PCI_ANY_ID, 0, 0, VX_PCI_VX222_OLD, }, /* PLX */ 64 { 0x10b5, 0x9050, 0x1369, PCI_ANY_ID, 0, 0, VX_PCI_VX222_OLD, }, /* PLX */
65 { 0x10b5, 0x9030, 0x1369, PCI_ANY_ID, 0, 0, VX_PCI_VX222_NEW, }, /* PLX */ 65 { 0x10b5, 0x9030, 0x1369, PCI_ANY_ID, 0, 0, VX_PCI_VX222_NEW, }, /* PLX */
66 { 0, } 66 { 0, }
diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c
index e6b18b90d451..80c682113381 100644
--- a/sound/pci/ymfpci/ymfpci.c
+++ b/sound/pci/ymfpci/ymfpci.c
@@ -66,7 +66,7 @@ MODULE_PARM_DESC(joystick_port, "Joystick port address");
66module_param_array(rear_switch, bool, NULL, 0444); 66module_param_array(rear_switch, bool, NULL, 0444);
67MODULE_PARM_DESC(rear_switch, "Enable shared rear/line-in switch"); 67MODULE_PARM_DESC(rear_switch, "Enable shared rear/line-in switch");
68 68
69static struct pci_device_id snd_ymfpci_ids[] = { 69static DEFINE_PCI_DEVICE_TABLE(snd_ymfpci_ids) = {
70 { PCI_VDEVICE(YAMAHA, 0x0004), 0, }, /* YMF724 */ 70 { PCI_VDEVICE(YAMAHA, 0x0004), 0, }, /* YMF724 */
71 { PCI_VDEVICE(YAMAHA, 0x000d), 0, }, /* YMF724F */ 71 { PCI_VDEVICE(YAMAHA, 0x000d), 0, }, /* YMF724F */
72 { PCI_VDEVICE(YAMAHA, 0x000a), 0, }, /* YMF740 */ 72 { PCI_VDEVICE(YAMAHA, 0x000a), 0, }, /* YMF740 */
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.c b/sound/pcmcia/pdaudiocf/pdaudiocf.c
index 64b859925c0b..edaa729126bb 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf.c
@@ -131,7 +131,7 @@ static int snd_pdacf_probe(struct pcmcia_device *link)
131 return err; 131 return err;
132 } 132 }
133 133
134 snd_card_set_dev(card, &handle_to_dev(link)); 134 snd_card_set_dev(card, &link->dev);
135 135
136 pdacf->index = i; 136 pdacf->index = i;
137 card_list[i] = card; 137 card_list[i] = card;
@@ -142,12 +142,11 @@ 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_HANDLE_PRESENT | IRQ_FORCED_PULSE; 145 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_FORCED_PULSE;
146 // link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED; 146 /* FIXME: This driver should be updated to allow for dynamic IRQ sharing */
147 /* link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_FORCED_PULSE; */
147 148
148 link->irq.IRQInfo1 = 0 /* | IRQ_LEVEL_ID */;
149 link->irq.Handler = pdacf_interrupt; 149 link->irq.Handler = pdacf_interrupt;
150 link->irq.Instance = pdacf;
151 link->conf.Attributes = CONF_ENABLE_IRQ; 150 link->conf.Attributes = CONF_ENABLE_IRQ;
152 link->conf.IntType = INT_MEMORY_AND_IO; 151 link->conf.IntType = INT_MEMORY_AND_IO;
153 link->conf.ConfigIndex = 1; 152 link->conf.ConfigIndex = 1;
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 d057e6489643..43f995a3f960 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c
@@ -20,8 +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/vmalloc.h>
25#include <linux/delay.h> 23#include <linux/delay.h>
26#include <sound/core.h> 24#include <sound/core.h>
27#include <sound/asoundef.h> 25#include <sound/asoundef.h>
@@ -29,49 +27,6 @@
29 27
30 28
31/* 29/*
32 * we use a vmalloc'ed (sg-)buffer
33 */
34
35/* get the physical page pointer on the given offset */
36static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs, unsigned long offset)
37{
38 void *pageptr = subs->runtime->dma_area + offset;
39 return vmalloc_to_page(pageptr);
40}
41
42/*
43 * hw_params callback
44 * NOTE: this may be called not only once per pcm open!
45 */
46static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, size_t size)
47{
48 struct snd_pcm_runtime *runtime = subs->runtime;
49 if (runtime->dma_area) {
50 if (runtime->dma_bytes >= size)
51 return 0; /* already enough large */
52 vfree(runtime->dma_area);
53 }
54 runtime->dma_area = vmalloc_32(size);
55 if (! runtime->dma_area)
56 return -ENOMEM;
57 runtime->dma_bytes = size;
58 return 0;
59}
60
61/*
62 * hw_free callback
63 * NOTE: this may be called not only once per pcm open!
64 */
65static int snd_pcm_free_vmalloc_buffer(struct snd_pcm_substream *subs)
66{
67 struct snd_pcm_runtime *runtime = subs->runtime;
68
69 vfree(runtime->dma_area);
70 runtime->dma_area = NULL;
71 return 0;
72}
73
74/*
75 * clear the SRAM contents 30 * clear the SRAM contents
76 */ 31 */
77static int pdacf_pcm_clear_sram(struct snd_pdacf *chip) 32static int pdacf_pcm_clear_sram(struct snd_pdacf *chip)
@@ -147,7 +102,8 @@ static int pdacf_pcm_trigger(struct snd_pcm_substream *subs, int cmd)
147static int pdacf_pcm_hw_params(struct snd_pcm_substream *subs, 102static int pdacf_pcm_hw_params(struct snd_pcm_substream *subs,
148 struct snd_pcm_hw_params *hw_params) 103 struct snd_pcm_hw_params *hw_params)
149{ 104{
150 return snd_pcm_alloc_vmalloc_buffer(subs, params_buffer_bytes(hw_params)); 105 return snd_pcm_lib_alloc_vmalloc_32_buffer
106 (subs, params_buffer_bytes(hw_params));
151} 107}
152 108
153/* 109/*
@@ -155,7 +111,7 @@ static int pdacf_pcm_hw_params(struct snd_pcm_substream *subs,
155 */ 111 */
156static int pdacf_pcm_hw_free(struct snd_pcm_substream *subs) 112static int pdacf_pcm_hw_free(struct snd_pcm_substream *subs)
157{ 113{
158 return snd_pcm_free_vmalloc_buffer(subs); 114 return snd_pcm_lib_free_vmalloc_buffer(subs);
159} 115}
160 116
161/* 117/*
@@ -319,7 +275,8 @@ static struct snd_pcm_ops pdacf_pcm_capture_ops = {
319 .prepare = pdacf_pcm_prepare, 275 .prepare = pdacf_pcm_prepare,
320 .trigger = pdacf_pcm_trigger, 276 .trigger = pdacf_pcm_trigger,
321 .pointer = pdacf_pcm_capture_pointer, 277 .pointer = pdacf_pcm_capture_pointer,
322 .page = snd_pcm_get_vmalloc_page, 278 .page = snd_pcm_lib_get_vmalloc_page,
279 .mmap = snd_pcm_lib_mmap_vmalloc,
323}; 280};
324 281
325 282
diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c
index 1492744ad67f..cfd1438bcc64 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,11 +162,9 @@ 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 | IRQ_HANDLE_PRESENT; 165 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
165 166
166 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
167 link->irq.Handler = &snd_vx_irq_handler; 167 link->irq.Handler = &snd_vx_irq_handler;
168 link->irq.Instance = chip;
169 168
170 link->conf.Attributes = CONF_ENABLE_IRQ; 169 link->conf.Attributes = CONF_ENABLE_IRQ;
171 link->conf.IntType = INT_MEMORY_AND_IO; 170 link->conf.IntType = INT_MEMORY_AND_IO;
@@ -244,7 +243,7 @@ static int vxpocket_config(struct pcmcia_device *link)
244 if (ret) 243 if (ret)
245 goto failed; 244 goto failed;
246 245
247 chip->dev = &handle_to_dev(link); 246 chip->dev = &link->dev;
248 snd_card_set_dev(chip->card, chip->dev); 247 snd_card_set_dev(chip->card, chip->dev);
249 248
250 if (snd_vxpocket_assign_resources(chip, link->io.BasePort1, link->irq.AssignedIRQ) < 0) 249 if (snd_vxpocket_assign_resources(chip, link->io.BasePort1, link->irq.AssignedIRQ) < 0)
diff --git a/sound/ppc/awacs.c b/sound/ppc/awacs.c
index 2cc0eda4f20e..b36679384b27 100644
--- a/sound/ppc/awacs.c
+++ b/sound/ppc/awacs.c
@@ -479,7 +479,7 @@ static int snd_pmac_awacs_put_master_amp(struct snd_kcontrol *kcontrol,
479 479
480static struct snd_kcontrol_new snd_pmac_awacs_amp_vol[] __devinitdata = { 480static struct snd_kcontrol_new snd_pmac_awacs_amp_vol[] __devinitdata = {
481 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 481 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
482 .name = "PC Speaker Playback Volume", 482 .name = "Speaker Playback Volume",
483 .info = snd_pmac_awacs_info_volume_amp, 483 .info = snd_pmac_awacs_info_volume_amp,
484 .get = snd_pmac_awacs_get_volume_amp, 484 .get = snd_pmac_awacs_get_volume_amp,
485 .put = snd_pmac_awacs_put_volume_amp, 485 .put = snd_pmac_awacs_put_volume_amp,
@@ -525,7 +525,7 @@ static struct snd_kcontrol_new snd_pmac_awacs_amp_hp_sw __devinitdata = {
525 525
526static struct snd_kcontrol_new snd_pmac_awacs_amp_spk_sw __devinitdata = { 526static struct snd_kcontrol_new snd_pmac_awacs_amp_spk_sw __devinitdata = {
527 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 527 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
528 .name = "PC Speaker Playback Switch", 528 .name = "Speaker Playback Switch",
529 .info = snd_pmac_boolean_stereo_info, 529 .info = snd_pmac_boolean_stereo_info,
530 .get = snd_pmac_awacs_get_switch_amp, 530 .get = snd_pmac_awacs_get_switch_amp,
531 .put = snd_pmac_awacs_put_switch_amp, 531 .put = snd_pmac_awacs_put_switch_amp,
@@ -696,17 +696,17 @@ static struct snd_kcontrol_new snd_pmac_screamer_mic_boost_imac[] __devinitdata
696}; 696};
697 697
698static struct snd_kcontrol_new snd_pmac_awacs_speaker_vol[] __devinitdata = { 698static struct snd_kcontrol_new snd_pmac_awacs_speaker_vol[] __devinitdata = {
699 AWACS_VOLUME("PC Speaker Playback Volume", 4, 6, 1), 699 AWACS_VOLUME("Speaker Playback Volume", 4, 6, 1),
700}; 700};
701 701
702static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw __devinitdata = 702static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw __devinitdata =
703AWACS_SWITCH("PC Speaker Playback Switch", 1, SHIFT_SPKMUTE, 1); 703AWACS_SWITCH("Speaker Playback Switch", 1, SHIFT_SPKMUTE, 1);
704 704
705static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw_imac1 __devinitdata = 705static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw_imac1 __devinitdata =
706AWACS_SWITCH("PC Speaker Playback Switch", 1, SHIFT_PAROUT1, 1); 706AWACS_SWITCH("Speaker Playback Switch", 1, SHIFT_PAROUT1, 1);
707 707
708static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw_imac2 __devinitdata = 708static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw_imac2 __devinitdata =
709AWACS_SWITCH("PC Speaker Playback Switch", 1, SHIFT_PAROUT1, 0); 709AWACS_SWITCH("Speaker Playback Switch", 1, SHIFT_PAROUT1, 0);
710 710
711 711
712/* 712/*
@@ -751,8 +751,8 @@ static void snd_pmac_awacs_suspend(struct snd_pmac *chip)
751 751
752static void snd_pmac_awacs_resume(struct snd_pmac *chip) 752static void snd_pmac_awacs_resume(struct snd_pmac *chip)
753{ 753{
754 if (machine_is_compatible("PowerBook3,1") 754 if (of_machine_is_compatible("PowerBook3,1")
755 || machine_is_compatible("PowerBook3,2")) { 755 || of_machine_is_compatible("PowerBook3,2")) {
756 msleep(100); 756 msleep(100);
757 snd_pmac_awacs_write_reg(chip, 1, 757 snd_pmac_awacs_write_reg(chip, 1,
758 chip->awacs_reg[1] & ~MASK_PAROUT); 758 chip->awacs_reg[1] & ~MASK_PAROUT);
@@ -780,16 +780,16 @@ static void snd_pmac_awacs_resume(struct snd_pmac *chip)
780} 780}
781#endif /* CONFIG_PM */ 781#endif /* CONFIG_PM */
782 782
783#define IS_PM7500 (machine_is_compatible("AAPL,7500") \ 783#define IS_PM7500 (of_machine_is_compatible("AAPL,7500") \
784 || machine_is_compatible("AAPL,8500") \ 784 || of_machine_is_compatible("AAPL,8500") \
785 || machine_is_compatible("AAPL,9500")) 785 || of_machine_is_compatible("AAPL,9500"))
786#define IS_PM5500 (machine_is_compatible("AAPL,e411")) 786#define IS_PM5500 (of_machine_is_compatible("AAPL,e411"))
787#define IS_BEIGE (machine_is_compatible("AAPL,Gossamer")) 787#define IS_BEIGE (of_machine_is_compatible("AAPL,Gossamer"))
788#define IS_IMAC1 (machine_is_compatible("PowerMac2,1")) 788#define IS_IMAC1 (of_machine_is_compatible("PowerMac2,1"))
789#define IS_IMAC2 (machine_is_compatible("PowerMac2,2") \ 789#define IS_IMAC2 (of_machine_is_compatible("PowerMac2,2") \
790 || machine_is_compatible("PowerMac4,1")) 790 || of_machine_is_compatible("PowerMac4,1"))
791#define IS_G4AGP (machine_is_compatible("PowerMac3,1")) 791#define IS_G4AGP (of_machine_is_compatible("PowerMac3,1"))
792#define IS_LOMBARD (machine_is_compatible("PowerBook1,1")) 792#define IS_LOMBARD (of_machine_is_compatible("PowerBook1,1"))
793 793
794static int imac1, imac2; 794static int imac1, imac2;
795 795
diff --git a/sound/ppc/burgundy.c b/sound/ppc/burgundy.c
index 16ed240e423c..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"
@@ -505,7 +504,7 @@ static struct snd_kcontrol_new snd_pmac_burgundy_mixers_imac[] __devinitdata = {
505 MASK_ADDR_BURGUNDY_GAINLINE, 1, 0), 504 MASK_ADDR_BURGUNDY_GAINLINE, 1, 0),
506 BURGUNDY_VOLUME_B("Mic Gain Capture Volume", 0, 505 BURGUNDY_VOLUME_B("Mic Gain Capture Volume", 0,
507 MASK_ADDR_BURGUNDY_GAINMIC, 1, 0), 506 MASK_ADDR_BURGUNDY_GAINMIC, 1, 0),
508 BURGUNDY_VOLUME_B("PC Speaker Playback Volume", 0, 507 BURGUNDY_VOLUME_B("Speaker Playback Volume", 0,
509 MASK_ADDR_BURGUNDY_ATTENSPEAKER, 1, 1), 508 MASK_ADDR_BURGUNDY_ATTENSPEAKER, 1, 1),
510 BURGUNDY_VOLUME_B("Line out Playback Volume", 0, 509 BURGUNDY_VOLUME_B("Line out Playback Volume", 0,
511 MASK_ADDR_BURGUNDY_ATTENLINEOUT, 1, 1), 510 MASK_ADDR_BURGUNDY_ATTENLINEOUT, 1, 1),
@@ -527,7 +526,7 @@ static struct snd_kcontrol_new snd_pmac_burgundy_mixers_pmac[] __devinitdata = {
527 MASK_ADDR_BURGUNDY_VOLMIC, 16), 526 MASK_ADDR_BURGUNDY_VOLMIC, 16),
528 BURGUNDY_VOLUME_B("Line in Gain Capture Volume", 0, 527 BURGUNDY_VOLUME_B("Line in Gain Capture Volume", 0,
529 MASK_ADDR_BURGUNDY_GAINMIC, 1, 0), 528 MASK_ADDR_BURGUNDY_GAINMIC, 1, 0),
530 BURGUNDY_VOLUME_B("PC Speaker Playback Volume", 0, 529 BURGUNDY_VOLUME_B("Speaker Playback Volume", 0,
531 MASK_ADDR_BURGUNDY_ATTENMONO, 0, 1), 530 MASK_ADDR_BURGUNDY_ATTENMONO, 0, 1),
532 BURGUNDY_VOLUME_B("Line out Playback Volume", 0, 531 BURGUNDY_VOLUME_B("Line out Playback Volume", 0,
533 MASK_ADDR_BURGUNDY_ATTENSPEAKER, 1, 1), 532 MASK_ADDR_BURGUNDY_ATTENSPEAKER, 1, 1),
@@ -549,11 +548,11 @@ BURGUNDY_SWITCH_B("Master Playback Switch", 0,
549 BURGUNDY_OUTPUT_INTERN 548 BURGUNDY_OUTPUT_INTERN
550 | BURGUNDY_OUTPUT_LEFT, BURGUNDY_OUTPUT_RIGHT, 1); 549 | BURGUNDY_OUTPUT_LEFT, BURGUNDY_OUTPUT_RIGHT, 1);
551static struct snd_kcontrol_new snd_pmac_burgundy_speaker_sw_imac __devinitdata = 550static struct snd_kcontrol_new snd_pmac_burgundy_speaker_sw_imac __devinitdata =
552BURGUNDY_SWITCH_B("PC Speaker Playback Switch", 0, 551BURGUNDY_SWITCH_B("Speaker Playback Switch", 0,
553 MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES, 552 MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES,
554 BURGUNDY_OUTPUT_LEFT, BURGUNDY_OUTPUT_RIGHT, 1); 553 BURGUNDY_OUTPUT_LEFT, BURGUNDY_OUTPUT_RIGHT, 1);
555static struct snd_kcontrol_new snd_pmac_burgundy_speaker_sw_pmac __devinitdata = 554static struct snd_kcontrol_new snd_pmac_burgundy_speaker_sw_pmac __devinitdata =
556BURGUNDY_SWITCH_B("PC Speaker Playback Switch", 0, 555BURGUNDY_SWITCH_B("Speaker Playback Switch", 0,
557 MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES, 556 MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES,
558 BURGUNDY_OUTPUT_INTERN, 0, 0); 557 BURGUNDY_OUTPUT_INTERN, 0, 0);
559static struct snd_kcontrol_new snd_pmac_burgundy_line_sw_imac __devinitdata = 558static struct snd_kcontrol_new snd_pmac_burgundy_line_sw_imac __devinitdata =
@@ -582,7 +581,7 @@ static int snd_pmac_burgundy_detect_headphone(struct snd_pmac *chip)
582static void snd_pmac_burgundy_update_automute(struct snd_pmac *chip, int do_notify) 581static void snd_pmac_burgundy_update_automute(struct snd_pmac *chip, int do_notify)
583{ 582{
584 if (chip->auto_mute) { 583 if (chip->auto_mute) {
585 int imac = machine_is_compatible("iMac"); 584 int imac = of_machine_is_compatible("iMac");
586 int reg, oreg; 585 int reg, oreg;
587 reg = oreg = snd_pmac_burgundy_rcb(chip, 586 reg = oreg = snd_pmac_burgundy_rcb(chip,
588 MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES); 587 MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES);
@@ -620,7 +619,7 @@ static void snd_pmac_burgundy_update_automute(struct snd_pmac *chip, int do_noti
620 */ 619 */
621int __devinit snd_pmac_burgundy_init(struct snd_pmac *chip) 620int __devinit snd_pmac_burgundy_init(struct snd_pmac *chip)
622{ 621{
623 int imac = machine_is_compatible("iMac"); 622 int imac = of_machine_is_compatible("iMac");
624 int i, err; 623 int i, err;
625 624
626 /* Checks to see the chip is alive and kicking */ 625 /* Checks to see the chip is alive and kicking */
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/pmac.c b/sound/ppc/pmac.c
index 7bc492ee77ec..85081172403f 100644
--- a/sound/ppc/pmac.c
+++ b/sound/ppc/pmac.c
@@ -922,11 +922,11 @@ static void __devinit detect_byte_swap(struct snd_pmac *chip)
922 } 922 }
923 923
924 /* it seems the Pismo & iBook can't byte-swap in hardware. */ 924 /* it seems the Pismo & iBook can't byte-swap in hardware. */
925 if (machine_is_compatible("PowerBook3,1") || 925 if (of_machine_is_compatible("PowerBook3,1") ||
926 machine_is_compatible("PowerBook2,1")) 926 of_machine_is_compatible("PowerBook2,1"))
927 chip->can_byte_swap = 0 ; 927 chip->can_byte_swap = 0 ;
928 928
929 if (machine_is_compatible("PowerBook2,1")) 929 if (of_machine_is_compatible("PowerBook2,1"))
930 chip->can_duplex = 0; 930 chip->can_duplex = 0;
931} 931}
932 932
@@ -959,11 +959,11 @@ static int __devinit snd_pmac_detect(struct snd_pmac *chip)
959 chip->control_mask = MASK_IEPC | MASK_IEE | 0x11; /* default */ 959 chip->control_mask = MASK_IEPC | MASK_IEE | 0x11; /* default */
960 960
961 /* check machine type */ 961 /* check machine type */
962 if (machine_is_compatible("AAPL,3400/2400") 962 if (of_machine_is_compatible("AAPL,3400/2400")
963 || machine_is_compatible("AAPL,3500")) 963 || of_machine_is_compatible("AAPL,3500"))
964 chip->is_pbook_3400 = 1; 964 chip->is_pbook_3400 = 1;
965 else if (machine_is_compatible("PowerBook1,1") 965 else if (of_machine_is_compatible("PowerBook1,1")
966 || machine_is_compatible("AAPL,PowerBook1998")) 966 || of_machine_is_compatible("AAPL,PowerBook1998"))
967 chip->is_pbook_G3 = 1; 967 chip->is_pbook_G3 = 1;
968 chip->node = of_find_node_by_name(NULL, "awacs"); 968 chip->node = of_find_node_by_name(NULL, "awacs");
969 sound = of_node_get(chip->node); 969 sound = of_node_get(chip->node);
@@ -1033,8 +1033,8 @@ static int __devinit snd_pmac_detect(struct snd_pmac *chip)
1033 } 1033 }
1034 if (of_device_is_compatible(sound, "tumbler")) { 1034 if (of_device_is_compatible(sound, "tumbler")) {
1035 chip->model = PMAC_TUMBLER; 1035 chip->model = PMAC_TUMBLER;
1036 chip->can_capture = machine_is_compatible("PowerMac4,2") 1036 chip->can_capture = of_machine_is_compatible("PowerMac4,2")
1037 || machine_is_compatible("PowerBook4,1"); 1037 || of_machine_is_compatible("PowerBook4,1");
1038 chip->can_duplex = 0; 1038 chip->can_duplex = 0;
1039 // chip->can_byte_swap = 0; /* FIXME: check this */ 1039 // chip->can_byte_swap = 0; /* FIXME: check this */
1040 chip->num_freqs = ARRAY_SIZE(tumbler_freqs); 1040 chip->num_freqs = ARRAY_SIZE(tumbler_freqs);
diff --git a/sound/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 08e584d1453a..789f44f4ac78 100644
--- a/sound/ppc/tumbler.c
+++ b/sound/ppc/tumbler.c
@@ -905,7 +905,7 @@ static struct snd_kcontrol_new tumbler_hp_sw __devinitdata = {
905}; 905};
906static struct snd_kcontrol_new tumbler_speaker_sw __devinitdata = { 906static struct snd_kcontrol_new tumbler_speaker_sw __devinitdata = {
907 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 907 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
908 .name = "PC Speaker Playback Switch", 908 .name = "Speaker Playback Switch",
909 .info = snd_pmac_boolean_mono_info, 909 .info = snd_pmac_boolean_mono_info,
910 .get = tumbler_get_mute_switch, 910 .get = tumbler_get_mute_switch,
911 .put = tumbler_put_mute_switch, 911 .put = tumbler_put_mute_switch,
diff --git a/sound/sh/Kconfig b/sound/sh/Kconfig
index aed0f90c3919..61139f3c1614 100644
--- a/sound/sh/Kconfig
+++ b/sound/sh/Kconfig
@@ -19,5 +19,13 @@ config SND_AICA
19 help 19 help
20 ALSA Sound driver for the SEGA Dreamcast console. 20 ALSA Sound driver for the SEGA Dreamcast console.
21 21
22config SND_SH_DAC_AUDIO
23 tristate "SuperH DAC audio support"
24 depends on SND
25 depends on CPU_SH3 && HIGH_RES_TIMERS
26 select SND_PCM
27 help
28 Say Y here to include support for the on-chip DAC.
29
22endif # SND_SUPERH 30endif # SND_SUPERH
23 31
diff --git a/sound/sh/Makefile b/sound/sh/Makefile
index 8fdcb6e26f00..7d09b5188cf7 100644
--- a/sound/sh/Makefile
+++ b/sound/sh/Makefile
@@ -3,6 +3,8 @@
3# 3#
4 4
5snd-aica-objs := aica.o 5snd-aica-objs := aica.o
6snd-sh_dac_audio-objs := sh_dac_audio.o
6 7
7# Toplevel Module Dependency 8# Toplevel Module Dependency
8obj-$(CONFIG_SND_AICA) += snd-aica.o 9obj-$(CONFIG_SND_AICA) += snd-aica.o
10obj-$(CONFIG_SND_SH_DAC_AUDIO) += snd-sh_dac_audio.o
diff --git a/sound/sh/sh_dac_audio.c b/sound/sh/sh_dac_audio.c
new file mode 100644
index 000000000000..68e0dee4ff05
--- /dev/null
+++ b/sound/sh/sh_dac_audio.c
@@ -0,0 +1,454 @@
1/*
2 * sh_dac_audio.c - SuperH DAC audio driver for ALSA
3 *
4 * Copyright (c) 2009 by Rafael Ignacio Zurita <rizurita@yahoo.com>
5 *
6 *
7 * Based on sh_dac_audio.c (Copyright (C) 2004, 2005 by Andriy Skulysh)
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 *
23 */
24
25#include <linux/hrtimer.h>
26#include <linux/interrupt.h>
27#include <linux/io.h>
28#include <linux/platform_device.h>
29#include <linux/slab.h>
30#include <sound/core.h>
31#include <sound/initval.h>
32#include <sound/pcm.h>
33#include <sound/sh_dac_audio.h>
34#include <asm/clock.h>
35#include <asm/hd64461.h>
36#include <mach/hp6xx.h>
37#include <cpu/dac.h>
38
39MODULE_AUTHOR("Rafael Ignacio Zurita <rizurita@yahoo.com>");
40MODULE_DESCRIPTION("SuperH DAC audio driver");
41MODULE_LICENSE("GPL");
42MODULE_SUPPORTED_DEVICE("{{SuperH DAC audio support}}");
43
44/* Module Parameters */
45static int index = SNDRV_DEFAULT_IDX1;
46static char *id = SNDRV_DEFAULT_STR1;
47module_param(index, int, 0444);
48MODULE_PARM_DESC(index, "Index value for SuperH DAC audio.");
49module_param(id, charp, 0444);
50MODULE_PARM_DESC(id, "ID string for SuperH DAC audio.");
51
52/* main struct */
53struct snd_sh_dac {
54 struct snd_card *card;
55 struct snd_pcm_substream *substream;
56 struct hrtimer hrtimer;
57 ktime_t wakeups_per_second;
58
59 int rate;
60 int empty;
61 char *data_buffer, *buffer_begin, *buffer_end;
62 int processed; /* bytes proccesed, to compare with period_size */
63 int buffer_size;
64 struct dac_audio_pdata *pdata;
65};
66
67
68static void dac_audio_start_timer(struct snd_sh_dac *chip)
69{
70 hrtimer_start(&chip->hrtimer, chip->wakeups_per_second,
71 HRTIMER_MODE_REL);
72}
73
74static void dac_audio_stop_timer(struct snd_sh_dac *chip)
75{
76 hrtimer_cancel(&chip->hrtimer);
77}
78
79static void dac_audio_reset(struct snd_sh_dac *chip)
80{
81 dac_audio_stop_timer(chip);
82 chip->buffer_begin = chip->buffer_end = chip->data_buffer;
83 chip->processed = 0;
84 chip->empty = 1;
85}
86
87static void dac_audio_set_rate(struct snd_sh_dac *chip)
88{
89 chip->wakeups_per_second = ktime_set(0, 1000000000 / chip->rate);
90}
91
92
93/* PCM INTERFACE */
94
95static struct snd_pcm_hardware snd_sh_dac_pcm_hw = {
96 .info = (SNDRV_PCM_INFO_MMAP |
97 SNDRV_PCM_INFO_MMAP_VALID |
98 SNDRV_PCM_INFO_INTERLEAVED |
99 SNDRV_PCM_INFO_HALF_DUPLEX),
100 .formats = SNDRV_PCM_FMTBIT_U8,
101 .rates = SNDRV_PCM_RATE_8000,
102 .rate_min = 8000,
103 .rate_max = 8000,
104 .channels_min = 1,
105 .channels_max = 1,
106 .buffer_bytes_max = (48*1024),
107 .period_bytes_min = 1,
108 .period_bytes_max = (48*1024),
109 .periods_min = 1,
110 .periods_max = 1024,
111};
112
113static int snd_sh_dac_pcm_open(struct snd_pcm_substream *substream)
114{
115 struct snd_sh_dac *chip = snd_pcm_substream_chip(substream);
116 struct snd_pcm_runtime *runtime = substream->runtime;
117
118 runtime->hw = snd_sh_dac_pcm_hw;
119
120 chip->substream = substream;
121 chip->buffer_begin = chip->buffer_end = chip->data_buffer;
122 chip->processed = 0;
123 chip->empty = 1;
124
125 chip->pdata->start(chip->pdata);
126
127 return 0;
128}
129
130static int snd_sh_dac_pcm_close(struct snd_pcm_substream *substream)
131{
132 struct snd_sh_dac *chip = snd_pcm_substream_chip(substream);
133
134 chip->substream = NULL;
135
136 dac_audio_stop_timer(chip);
137 chip->pdata->stop(chip->pdata);
138
139 return 0;
140}
141
142static int snd_sh_dac_pcm_hw_params(struct snd_pcm_substream *substream,
143 struct snd_pcm_hw_params *hw_params)
144{
145 return snd_pcm_lib_malloc_pages(substream,
146 params_buffer_bytes(hw_params));
147}
148
149static int snd_sh_dac_pcm_hw_free(struct snd_pcm_substream *substream)
150{
151 return snd_pcm_lib_free_pages(substream);
152}
153
154static int snd_sh_dac_pcm_prepare(struct snd_pcm_substream *substream)
155{
156 struct snd_sh_dac *chip = snd_pcm_substream_chip(substream);
157 struct snd_pcm_runtime *runtime = chip->substream->runtime;
158
159 chip->buffer_size = runtime->buffer_size;
160 memset(chip->data_buffer, 0, chip->pdata->buffer_size);
161
162 return 0;
163}
164
165static int snd_sh_dac_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
166{
167 struct snd_sh_dac *chip = snd_pcm_substream_chip(substream);
168
169 switch (cmd) {
170 case SNDRV_PCM_TRIGGER_START:
171 dac_audio_start_timer(chip);
172 break;
173 case SNDRV_PCM_TRIGGER_STOP:
174 chip->buffer_begin = chip->buffer_end = chip->data_buffer;
175 chip->processed = 0;
176 chip->empty = 1;
177 dac_audio_stop_timer(chip);
178 break;
179 default:
180 return -EINVAL;
181 }
182
183 return 0;
184}
185
186static int snd_sh_dac_pcm_copy(struct snd_pcm_substream *substream, int channel,
187 snd_pcm_uframes_t pos, void __user *src, snd_pcm_uframes_t count)
188{
189 /* channel is not used (interleaved data) */
190 struct snd_sh_dac *chip = snd_pcm_substream_chip(substream);
191 struct snd_pcm_runtime *runtime = substream->runtime;
192 ssize_t b_count = frames_to_bytes(runtime , count);
193 ssize_t b_pos = frames_to_bytes(runtime , pos);
194
195 if (count < 0)
196 return -EINVAL;
197
198 if (!count)
199 return 0;
200
201 memcpy_toio(chip->data_buffer + b_pos, src, b_count);
202 chip->buffer_end = chip->data_buffer + b_pos + b_count;
203
204 if (chip->empty) {
205 chip->empty = 0;
206 dac_audio_start_timer(chip);
207 }
208
209 return 0;
210}
211
212static int snd_sh_dac_pcm_silence(struct snd_pcm_substream *substream,
213 int channel, snd_pcm_uframes_t pos,
214 snd_pcm_uframes_t count)
215{
216 /* channel is not used (interleaved data) */
217 struct snd_sh_dac *chip = snd_pcm_substream_chip(substream);
218 struct snd_pcm_runtime *runtime = substream->runtime;
219 ssize_t b_count = frames_to_bytes(runtime , count);
220 ssize_t b_pos = frames_to_bytes(runtime , pos);
221
222 if (count < 0)
223 return -EINVAL;
224
225 if (!count)
226 return 0;
227
228 memset_io(chip->data_buffer + b_pos, 0, b_count);
229 chip->buffer_end = chip->data_buffer + b_pos + b_count;
230
231 if (chip->empty) {
232 chip->empty = 0;
233 dac_audio_start_timer(chip);
234 }
235
236 return 0;
237}
238
239static
240snd_pcm_uframes_t snd_sh_dac_pcm_pointer(struct snd_pcm_substream *substream)
241{
242 struct snd_sh_dac *chip = snd_pcm_substream_chip(substream);
243 int pointer = chip->buffer_begin - chip->data_buffer;
244
245 return pointer;
246}
247
248/* pcm ops */
249static struct snd_pcm_ops snd_sh_dac_pcm_ops = {
250 .open = snd_sh_dac_pcm_open,
251 .close = snd_sh_dac_pcm_close,
252 .ioctl = snd_pcm_lib_ioctl,
253 .hw_params = snd_sh_dac_pcm_hw_params,
254 .hw_free = snd_sh_dac_pcm_hw_free,
255 .prepare = snd_sh_dac_pcm_prepare,
256 .trigger = snd_sh_dac_pcm_trigger,
257 .pointer = snd_sh_dac_pcm_pointer,
258 .copy = snd_sh_dac_pcm_copy,
259 .silence = snd_sh_dac_pcm_silence,
260 .mmap = snd_pcm_lib_mmap_iomem,
261};
262
263static int __devinit snd_sh_dac_pcm(struct snd_sh_dac *chip, int device)
264{
265 int err;
266 struct snd_pcm *pcm;
267
268 /* device should be always 0 for us */
269 err = snd_pcm_new(chip->card, "SH_DAC PCM", device, 1, 0, &pcm);
270 if (err < 0)
271 return err;
272
273 pcm->private_data = chip;
274 strcpy(pcm->name, "SH_DAC PCM");
275 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_sh_dac_pcm_ops);
276
277 /* buffer size=48K */
278 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
279 snd_dma_continuous_data(GFP_KERNEL),
280 48 * 1024,
281 48 * 1024);
282
283 return 0;
284}
285/* END OF PCM INTERFACE */
286
287
288/* driver .remove -- destructor */
289static int snd_sh_dac_remove(struct platform_device *devptr)
290{
291 snd_card_free(platform_get_drvdata(devptr));
292 platform_set_drvdata(devptr, NULL);
293
294 return 0;
295}
296
297/* free -- it has been defined by create */
298static int snd_sh_dac_free(struct snd_sh_dac *chip)
299{
300 /* release the data */
301 kfree(chip->data_buffer);
302 kfree(chip);
303
304 return 0;
305}
306
307static int snd_sh_dac_dev_free(struct snd_device *device)
308{
309 struct snd_sh_dac *chip = device->device_data;
310
311 return snd_sh_dac_free(chip);
312}
313
314static enum hrtimer_restart sh_dac_audio_timer(struct hrtimer *handle)
315{
316 struct snd_sh_dac *chip = container_of(handle, struct snd_sh_dac,
317 hrtimer);
318 struct snd_pcm_runtime *runtime = chip->substream->runtime;
319 ssize_t b_ps = frames_to_bytes(runtime, runtime->period_size);
320
321 if (!chip->empty) {
322 sh_dac_output(*chip->buffer_begin, chip->pdata->channel);
323 chip->buffer_begin++;
324
325 chip->processed++;
326 if (chip->processed >= b_ps) {
327 chip->processed -= b_ps;
328 snd_pcm_period_elapsed(chip->substream);
329 }
330
331 if (chip->buffer_begin == (chip->data_buffer +
332 chip->buffer_size - 1))
333 chip->buffer_begin = chip->data_buffer;
334
335 if (chip->buffer_begin == chip->buffer_end)
336 chip->empty = 1;
337
338 }
339
340 if (!chip->empty)
341 hrtimer_start(&chip->hrtimer, chip->wakeups_per_second,
342 HRTIMER_MODE_REL);
343
344 return HRTIMER_NORESTART;
345}
346
347/* create -- chip-specific constructor for the cards components */
348static int __devinit snd_sh_dac_create(struct snd_card *card,
349 struct platform_device *devptr,
350 struct snd_sh_dac **rchip)
351{
352 struct snd_sh_dac *chip;
353 int err;
354
355 static struct snd_device_ops ops = {
356 .dev_free = snd_sh_dac_dev_free,
357 };
358
359 *rchip = NULL;
360
361 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
362 if (chip == NULL)
363 return -ENOMEM;
364
365 chip->card = card;
366
367 hrtimer_init(&chip->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
368 chip->hrtimer.function = sh_dac_audio_timer;
369
370 dac_audio_reset(chip);
371 chip->rate = 8000;
372 dac_audio_set_rate(chip);
373
374 chip->pdata = devptr->dev.platform_data;
375
376 chip->data_buffer = kmalloc(chip->pdata->buffer_size, GFP_KERNEL);
377 if (chip->data_buffer == NULL) {
378 kfree(chip);
379 return -ENOMEM;
380 }
381
382 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
383 if (err < 0) {
384 snd_sh_dac_free(chip);
385 return err;
386 }
387
388 *rchip = chip;
389
390 return 0;
391}
392
393/* driver .probe -- constructor */
394static int __devinit snd_sh_dac_probe(struct platform_device *devptr)
395{
396 struct snd_sh_dac *chip;
397 struct snd_card *card;
398 int err;
399
400 err = snd_card_create(index, id, THIS_MODULE, 0, &card);
401 if (err < 0) {
402 snd_printk(KERN_ERR "cannot allocate the card\n");
403 return err;
404 }
405
406 err = snd_sh_dac_create(card, devptr, &chip);
407 if (err < 0)
408 goto probe_error;
409
410 err = snd_sh_dac_pcm(chip, 0);
411 if (err < 0)
412 goto probe_error;
413
414 strcpy(card->driver, "snd_sh_dac");
415 strcpy(card->shortname, "SuperH DAC audio driver");
416 printk(KERN_INFO "%s %s", card->longname, card->shortname);
417
418 err = snd_card_register(card);
419 if (err < 0)
420 goto probe_error;
421
422 snd_printk("ALSA driver for SuperH DAC audio");
423
424 platform_set_drvdata(devptr, card);
425 return 0;
426
427probe_error:
428 snd_card_free(card);
429 return err;
430}
431
432/*
433 * "driver" definition
434 */
435static struct platform_driver driver = {
436 .probe = snd_sh_dac_probe,
437 .remove = snd_sh_dac_remove,
438 .driver = {
439 .name = "dac_audio",
440 },
441};
442
443static int __init sh_dac_init(void)
444{
445 return platform_driver_register(&driver);
446}
447
448static void __exit sh_dac_exit(void)
449{
450 platform_driver_unregister(&driver);
451}
452
453module_init(sh_dac_init);
454module_exit(sh_dac_exit);
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 0c5eac01bf2e..1470141d4167 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -1,4 +1,4 @@
1snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-cache.o 1snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-cache.o soc-utils.o
2 2
3obj-$(CONFIG_SND_SOC) += snd-soc-core.o 3obj-$(CONFIG_SND_SOC) += snd-soc-core.o
4obj-$(CONFIG_SND_SOC) += codecs/ 4obj-$(CONFIG_SND_SOC) += codecs/
diff --git a/sound/soc/atmel/atmel-pcm.c b/sound/soc/atmel/atmel-pcm.c
index 9ef6b96373f5..3e6628c8e665 100644
--- a/sound/soc/atmel/atmel-pcm.c
+++ b/sound/soc/atmel/atmel-pcm.c
@@ -180,7 +180,7 @@ static int atmel_pcm_hw_params(struct snd_pcm_substream *substream,
180 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); 180 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
181 runtime->dma_bytes = params_buffer_bytes(params); 181 runtime->dma_bytes = params_buffer_bytes(params);
182 182
183 prtd->params = rtd->dai->cpu_dai->dma_data; 183 prtd->params = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
184 prtd->params->dma_intr_handler = atmel_pcm_dma_irq; 184 prtd->params->dma_intr_handler = atmel_pcm_dma_irq;
185 185
186 prtd->dma_buffer = runtime->dma_addr; 186 prtd->dma_buffer = runtime->dma_addr;
diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c
index e588e63f18d2..0b59806905d1 100644
--- a/sound/soc/atmel/atmel_ssc_dai.c
+++ b/sound/soc/atmel/atmel_ssc_dai.c
@@ -363,12 +363,12 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
363 ssc_p->dma_params[dir] = dma_params; 363 ssc_p->dma_params[dir] = dma_params;
364 364
365 /* 365 /*
366 * The cpu_dai->dma_data field is only used to communicate the 366 * The snd_soc_pcm_stream->dma_data field is only used to communicate
367 * appropriate DMA parameters to the pcm driver hw_params() 367 * the appropriate DMA parameters to the pcm driver hw_params()
368 * function. It should not be used for other purposes 368 * function. It should not be used for other purposes
369 * as it is common to all substreams. 369 * as it is common to all substreams.
370 */ 370 */
371 rtd->dai->cpu_dai->dma_data = dma_params; 371 snd_soc_dai_set_dma_data(rtd->dai->cpu_dai, substream, dma_params);
372 372
373 channels = params_channels(params); 373 channels = params_channels(params);
374 374
diff --git a/sound/soc/atmel/playpaq_wm8510.c b/sound/soc/atmel/playpaq_wm8510.c
index 9eb610c2ba91..9df4c68ef000 100644
--- a/sound/soc/atmel/playpaq_wm8510.c
+++ b/sound/soc/atmel/playpaq_wm8510.c
@@ -268,7 +268,7 @@ static int playpaq_wm8510_hw_params(struct snd_pcm_substream *substream,
268#endif /* CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE */ 268#endif /* CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE */
269 269
270 270
271 ret = snd_soc_dai_set_pll(codec_dai, 0, 271 ret = snd_soc_dai_set_pll(codec_dai, 0, 0,
272 clk_get_rate(CODEC_CLK), pll_out); 272 clk_get_rate(CODEC_CLK), pll_out);
273 if (ret < 0) { 273 if (ret < 0) {
274 pr_warning("playpaq_wm8510: Failed to set CODEC DAI PLL (%d)\n", 274 pr_warning("playpaq_wm8510: Failed to set CODEC DAI PLL (%d)\n",
diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c
index 885ba012557e..e028744c32ce 100644
--- a/sound/soc/atmel/sam9g20_wm8731.c
+++ b/sound/soc/atmel/sam9g20_wm8731.c
@@ -207,7 +207,7 @@ static int __init at91sam9g20ek_init(void)
207 struct clk *pllb; 207 struct clk *pllb;
208 int ret; 208 int ret;
209 209
210 if (!machine_is_at91sam9g20ek()) 210 if (!(machine_is_at91sam9g20ek() || machine_is_at91sam9g20ek_2mmc()))
211 return -ENODEV; 211 return -ENODEV;
212 212
213 /* 213 /*
diff --git a/sound/soc/au1x/Kconfig b/sound/soc/au1x/Kconfig
index 410a893aa66b..4b67140fdec3 100644
--- a/sound/soc/au1x/Kconfig
+++ b/sound/soc/au1x/Kconfig
@@ -22,11 +22,13 @@ config SND_SOC_AU1XPSC_AC97
22## 22##
23## Boards 23## Boards
24## 24##
25config SND_SOC_SAMPLE_PSC_AC97 25config SND_SOC_DB1200
26 tristate "Sample Au12x0/Au1550 PSC AC97 sound machine" 26 tristate "DB1200 AC97+I2S audio support"
27 depends on SND_SOC_AU1XPSC 27 depends on SND_SOC_AU1XPSC
28 select SND_SOC_AU1XPSC_AC97 28 select SND_SOC_AU1XPSC_AC97
29 select SND_SOC_AC97_CODEC 29 select SND_SOC_AC97_CODEC
30 select SND_SOC_AU1XPSC_I2S
31 select SND_SOC_WM8731
30 help 32 help
31 This is a sample AC97 sound machine for use in Au12x0/Au1550 33 Select this option to enable audio (AC97 or I2S) on the
32 based systems which have audio on PSC1 (e.g. Db1200 demoboard). 34 Alchemy/AMD/RMI DB1200 demoboard.
diff --git a/sound/soc/au1x/Makefile b/sound/soc/au1x/Makefile
index 6c6950b8003a..16873076e8c4 100644
--- a/sound/soc/au1x/Makefile
+++ b/sound/soc/au1x/Makefile
@@ -8,6 +8,6 @@ obj-$(CONFIG_SND_SOC_AU1XPSC_I2S) += snd-soc-au1xpsc-i2s.o
8obj-$(CONFIG_SND_SOC_AU1XPSC_AC97) += snd-soc-au1xpsc-ac97.o 8obj-$(CONFIG_SND_SOC_AU1XPSC_AC97) += snd-soc-au1xpsc-ac97.o
9 9
10# Boards 10# Boards
11snd-soc-sample-ac97-objs := sample-ac97.o 11snd-soc-db1200-objs := db1200.o
12 12
13obj-$(CONFIG_SND_SOC_SAMPLE_PSC_AC97) += snd-soc-sample-ac97.o 13obj-$(CONFIG_SND_SOC_DB1200) += snd-soc-db1200.o
diff --git a/sound/soc/au1x/db1200.c b/sound/soc/au1x/db1200.c
new file mode 100644
index 000000000000..cdf7be1b9b91
--- /dev/null
+++ b/sound/soc/au1x/db1200.c
@@ -0,0 +1,141 @@
1/*
2 * DB1200 ASoC audio fabric support code.
3 *
4 * (c) 2008-9 Manuel Lauss <manuel.lauss@gmail.com>
5 *
6 */
7
8#include <linux/module.h>
9#include <linux/moduleparam.h>
10#include <linux/timer.h>
11#include <linux/interrupt.h>
12#include <linux/platform_device.h>
13#include <sound/core.h>
14#include <sound/pcm.h>
15#include <sound/soc.h>
16#include <sound/soc-dapm.h>
17#include <asm/mach-au1x00/au1000.h>
18#include <asm/mach-au1x00/au1xxx_psc.h>
19#include <asm/mach-au1x00/au1xxx_dbdma.h>
20#include <asm/mach-db1x00/bcsr.h>
21
22#include "../codecs/ac97.h"
23#include "../codecs/wm8731.h"
24#include "psc.h"
25
26/*------------------------- AC97 PART ---------------------------*/
27
28static struct snd_soc_dai_link db1200_ac97_dai = {
29 .name = "AC97",
30 .stream_name = "AC97 HiFi",
31 .cpu_dai = &au1xpsc_ac97_dai,
32 .codec_dai = &ac97_dai,
33};
34
35static struct snd_soc_card db1200_ac97_machine = {
36 .name = "DB1200_AC97",
37 .dai_link = &db1200_ac97_dai,
38 .num_links = 1,
39 .platform = &au1xpsc_soc_platform,
40};
41
42static struct snd_soc_device db1200_ac97_devdata = {
43 .card = &db1200_ac97_machine,
44 .codec_dev = &soc_codec_dev_ac97,
45};
46
47/*------------------------- I2S PART ---------------------------*/
48
49static int db1200_i2s_startup(struct snd_pcm_substream *substream)
50{
51 struct snd_soc_pcm_runtime *rtd = substream->private_data;
52 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
53 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
54 int ret;
55
56 /* WM8731 has its own 12MHz crystal */
57 snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK,
58 12000000, SND_SOC_CLOCK_IN);
59
60 /* codec is bitclock and lrclk master */
61 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_LEFT_J |
62 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
63 if (ret < 0)
64 goto out;
65
66 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_LEFT_J |
67 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
68 if (ret < 0)
69 goto out;
70
71 ret = 0;
72out:
73 return ret;
74}
75
76static struct snd_soc_ops db1200_i2s_wm8731_ops = {
77 .startup = db1200_i2s_startup,
78};
79
80static struct snd_soc_dai_link db1200_i2s_dai = {
81 .name = "WM8731",
82 .stream_name = "WM8731 PCM",
83 .cpu_dai = &au1xpsc_i2s_dai,
84 .codec_dai = &wm8731_dai,
85 .ops = &db1200_i2s_wm8731_ops,
86};
87
88static struct snd_soc_card db1200_i2s_machine = {
89 .name = "DB1200_I2S",
90 .dai_link = &db1200_i2s_dai,
91 .num_links = 1,
92 .platform = &au1xpsc_soc_platform,
93};
94
95static struct snd_soc_device db1200_i2s_devdata = {
96 .card = &db1200_i2s_machine,
97 .codec_dev = &soc_codec_dev_wm8731,
98};
99
100/*------------------------- COMMON PART ---------------------------*/
101
102static struct platform_device *db1200_asoc_dev;
103
104static int __init db1200_audio_load(void)
105{
106 int ret;
107
108 ret = -ENOMEM;
109 db1200_asoc_dev = platform_device_alloc("soc-audio", -1);
110 if (!db1200_asoc_dev)
111 goto out;
112
113 /* DB1200 board setup set PSC1MUX to preferred audio device */
114 if (bcsr_read(BCSR_RESETS) & BCSR_RESETS_PSC1MUX)
115 platform_set_drvdata(db1200_asoc_dev, &db1200_i2s_devdata);
116 else
117 platform_set_drvdata(db1200_asoc_dev, &db1200_ac97_devdata);
118
119 db1200_ac97_devdata.dev = &db1200_asoc_dev->dev;
120 db1200_i2s_devdata.dev = &db1200_asoc_dev->dev;
121 ret = platform_device_add(db1200_asoc_dev);
122
123 if (ret) {
124 platform_device_put(db1200_asoc_dev);
125 db1200_asoc_dev = NULL;
126 }
127out:
128 return ret;
129}
130
131static void __exit db1200_audio_unload(void)
132{
133 platform_device_unregister(db1200_asoc_dev);
134}
135
136module_init(db1200_audio_load);
137module_exit(db1200_audio_unload);
138
139MODULE_LICENSE("GPL");
140MODULE_DESCRIPTION("DB1200 ASoC audio support");
141MODULE_AUTHOR("Manuel Lauss");
diff --git a/sound/soc/au1x/dbdma2.c b/sound/soc/au1x/dbdma2.c
index 594c6c5b7838..6d9f4c624949 100644
--- a/sound/soc/au1x/dbdma2.c
+++ b/sound/soc/au1x/dbdma2.c
@@ -2,7 +2,7 @@
2 * Au12x0/Au1550 PSC ALSA ASoC audio support. 2 * Au12x0/Au1550 PSC ALSA ASoC audio support.
3 * 3 *
4 * (c) 2007-2008 MSC Vertriebsges.m.b.H., 4 * (c) 2007-2008 MSC Vertriebsges.m.b.H.,
5 * Manuel Lauss <mano@roarinelk.homelinux.net> 5 * Manuel Lauss <manuel.lauss@gmail.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as 8 * it under the terms of the GNU General Public License version 2 as
@@ -51,8 +51,8 @@ struct au1xpsc_audio_dmadata {
51 struct snd_pcm_substream *substream; 51 struct snd_pcm_substream *substream;
52 unsigned long curr_period; /* current segment DDMA is working on */ 52 unsigned long curr_period; /* current segment DDMA is working on */
53 unsigned long q_period; /* queue period(s) */ 53 unsigned long q_period; /* queue period(s) */
54 unsigned long dma_area; /* address of queued DMA area */ 54 dma_addr_t dma_area; /* address of queued DMA area */
55 unsigned long dma_area_s; /* start address of DMA area */ 55 dma_addr_t dma_area_s; /* start address of DMA area */
56 unsigned long pos; /* current byte position being played */ 56 unsigned long pos; /* current byte position being played */
57 unsigned long periods; /* number of SG segments in total */ 57 unsigned long periods; /* number of SG segments in total */
58 unsigned long period_bytes; /* size in bytes of one SG segment */ 58 unsigned long period_bytes; /* size in bytes of one SG segment */
@@ -94,8 +94,7 @@ static const struct snd_pcm_hardware au1xpsc_pcm_hardware = {
94 94
95static void au1x_pcm_queue_tx(struct au1xpsc_audio_dmadata *cd) 95static void au1x_pcm_queue_tx(struct au1xpsc_audio_dmadata *cd)
96{ 96{
97 au1xxx_dbdma_put_source_flags(cd->ddma_chan, 97 au1xxx_dbdma_put_source(cd->ddma_chan, cd->dma_area,
98 (void *)phys_to_virt(cd->dma_area),
99 cd->period_bytes, DDMA_FLAGS_IE); 98 cd->period_bytes, DDMA_FLAGS_IE);
100 99
101 /* update next-to-queue period */ 100 /* update next-to-queue period */
@@ -109,9 +108,8 @@ static void au1x_pcm_queue_tx(struct au1xpsc_audio_dmadata *cd)
109 108
110static void au1x_pcm_queue_rx(struct au1xpsc_audio_dmadata *cd) 109static void au1x_pcm_queue_rx(struct au1xpsc_audio_dmadata *cd)
111{ 110{
112 au1xxx_dbdma_put_dest_flags(cd->ddma_chan, 111 au1xxx_dbdma_put_dest(cd->ddma_chan, cd->dma_area,
113 (void *)phys_to_virt(cd->dma_area), 112 cd->period_bytes, DDMA_FLAGS_IE);
114 cd->period_bytes, DDMA_FLAGS_IE);
115 113
116 /* update next-to-queue period */ 114 /* update next-to-queue period */
117 ++cd->q_period; 115 ++cd->q_period;
@@ -233,7 +231,7 @@ static int au1xpsc_pcm_hw_params(struct snd_pcm_substream *substream,
233 pcd->substream = substream; 231 pcd->substream = substream;
234 pcd->period_bytes = params_period_bytes(params); 232 pcd->period_bytes = params_period_bytes(params);
235 pcd->periods = params_periods(params); 233 pcd->periods = params_periods(params);
236 pcd->dma_area_s = pcd->dma_area = (unsigned long)runtime->dma_addr; 234 pcd->dma_area_s = pcd->dma_area = runtime->dma_addr;
237 pcd->q_period = 0; 235 pcd->q_period = 0;
238 pcd->curr_period = 0; 236 pcd->curr_period = 0;
239 pcd->pos = 0; 237 pcd->pos = 0;
@@ -333,6 +331,30 @@ static int au1xpsc_pcm_new(struct snd_card *card,
333 331
334static int au1xpsc_pcm_probe(struct platform_device *pdev) 332static int au1xpsc_pcm_probe(struct platform_device *pdev)
335{ 333{
334 if (!au1xpsc_audio_pcmdma[PCM_TX] || !au1xpsc_audio_pcmdma[PCM_RX])
335 return -ENODEV;
336
337 return 0;
338}
339
340static int au1xpsc_pcm_remove(struct platform_device *pdev)
341{
342 return 0;
343}
344
345/* au1xpsc audio platform */
346struct snd_soc_platform au1xpsc_soc_platform = {
347 .name = "au1xpsc-pcm-dbdma",
348 .probe = au1xpsc_pcm_probe,
349 .remove = au1xpsc_pcm_remove,
350 .pcm_ops = &au1xpsc_pcm_ops,
351 .pcm_new = au1xpsc_pcm_new,
352 .pcm_free = au1xpsc_pcm_free_dma_buffers,
353};
354EXPORT_SYMBOL_GPL(au1xpsc_soc_platform);
355
356static int __devinit au1xpsc_pcm_drvprobe(struct platform_device *pdev)
357{
336 struct resource *r; 358 struct resource *r;
337 int ret; 359 int ret;
338 360
@@ -365,7 +387,9 @@ static int au1xpsc_pcm_probe(struct platform_device *pdev)
365 } 387 }
366 (au1xpsc_audio_pcmdma[PCM_RX])->ddma_id = r->start; 388 (au1xpsc_audio_pcmdma[PCM_RX])->ddma_id = r->start;
367 389
368 return 0; 390 ret = snd_soc_register_platform(&au1xpsc_soc_platform);
391 if (!ret)
392 return ret;
369 393
370out2: 394out2:
371 kfree(au1xpsc_audio_pcmdma[PCM_RX]); 395 kfree(au1xpsc_audio_pcmdma[PCM_RX]);
@@ -376,10 +400,12 @@ out1:
376 return ret; 400 return ret;
377} 401}
378 402
379static int au1xpsc_pcm_remove(struct platform_device *pdev) 403static int __devexit au1xpsc_pcm_drvremove(struct platform_device *pdev)
380{ 404{
381 int i; 405 int i;
382 406
407 snd_soc_unregister_platform(&au1xpsc_soc_platform);
408
383 for (i = 0; i < 2; i++) { 409 for (i = 0; i < 2; i++) {
384 if (au1xpsc_audio_pcmdma[i]) { 410 if (au1xpsc_audio_pcmdma[i]) {
385 au1x_pcm_dbdma_free(au1xpsc_audio_pcmdma[i]); 411 au1x_pcm_dbdma_free(au1xpsc_audio_pcmdma[i]);
@@ -391,32 +417,81 @@ static int au1xpsc_pcm_remove(struct platform_device *pdev)
391 return 0; 417 return 0;
392} 418}
393 419
394/* au1xpsc audio platform */ 420static struct platform_driver au1xpsc_pcm_driver = {
395struct snd_soc_platform au1xpsc_soc_platform = { 421 .driver = {
396 .name = "au1xpsc-pcm-dbdma", 422 .name = "au1xpsc-pcm",
397 .probe = au1xpsc_pcm_probe, 423 .owner = THIS_MODULE,
398 .remove = au1xpsc_pcm_remove, 424 },
399 .pcm_ops = &au1xpsc_pcm_ops, 425 .probe = au1xpsc_pcm_drvprobe,
400 .pcm_new = au1xpsc_pcm_new, 426 .remove = __devexit_p(au1xpsc_pcm_drvremove),
401 .pcm_free = au1xpsc_pcm_free_dma_buffers,
402}; 427};
403EXPORT_SYMBOL_GPL(au1xpsc_soc_platform);
404 428
405static int __init au1xpsc_audio_dbdma_init(void) 429static int __init au1xpsc_audio_dbdma_load(void)
406{ 430{
407 au1xpsc_audio_pcmdma[PCM_TX] = NULL; 431 au1xpsc_audio_pcmdma[PCM_TX] = NULL;
408 au1xpsc_audio_pcmdma[PCM_RX] = NULL; 432 au1xpsc_audio_pcmdma[PCM_RX] = NULL;
409 return snd_soc_register_platform(&au1xpsc_soc_platform); 433 return platform_driver_register(&au1xpsc_pcm_driver);
410} 434}
411 435
412static void __exit au1xpsc_audio_dbdma_exit(void) 436static void __exit au1xpsc_audio_dbdma_unload(void)
413{ 437{
414 snd_soc_unregister_platform(&au1xpsc_soc_platform); 438 platform_driver_unregister(&au1xpsc_pcm_driver);
439}
440
441module_init(au1xpsc_audio_dbdma_load);
442module_exit(au1xpsc_audio_dbdma_unload);
443
444
445struct platform_device *au1xpsc_pcm_add(struct platform_device *pdev)
446{
447 struct resource *res, *r;
448 struct platform_device *pd;
449 int id[2];
450 int ret;
451
452 r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
453 if (!r)
454 return NULL;
455 id[0] = r->start;
456
457 r = platform_get_resource(pdev, IORESOURCE_DMA, 1);
458 if (!r)
459 return NULL;
460 id[1] = r->start;
461
462 res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL);
463 if (!res)
464 return NULL;
465
466 res[0].start = res[0].end = id[0];
467 res[1].start = res[1].end = id[1];
468 res[0].flags = res[1].flags = IORESOURCE_DMA;
469
470 pd = platform_device_alloc("au1xpsc-pcm", -1);
471 if (!pd)
472 goto out;
473
474 pd->resource = res;
475 pd->num_resources = 2;
476
477 ret = platform_device_add(pd);
478 if (!ret)
479 return pd;
480
481 platform_device_put(pd);
482out:
483 kfree(res);
484 return NULL;
415} 485}
486EXPORT_SYMBOL_GPL(au1xpsc_pcm_add);
416 487
417module_init(au1xpsc_audio_dbdma_init); 488void au1xpsc_pcm_destroy(struct platform_device *dmapd)
418module_exit(au1xpsc_audio_dbdma_exit); 489{
490 if (dmapd)
491 platform_device_unregister(dmapd);
492}
493EXPORT_SYMBOL_GPL(au1xpsc_pcm_destroy);
419 494
420MODULE_LICENSE("GPL"); 495MODULE_LICENSE("GPL");
421MODULE_DESCRIPTION("Au12x0/Au1550 PSC Audio DMA driver"); 496MODULE_DESCRIPTION("Au12x0/Au1550 PSC Audio DMA driver");
422MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>"); 497MODULE_AUTHOR("Manuel Lauss");
diff --git a/sound/soc/au1x/psc-ac97.c b/sound/soc/au1x/psc-ac97.c
index a521aa90ddee..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>
@@ -61,7 +62,8 @@ static unsigned short au1xpsc_ac97_read(struct snd_ac97 *ac97,
61{ 62{
62 /* FIXME */ 63 /* FIXME */
63 struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata; 64 struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata;
64 unsigned short data, retry, tmo; 65 unsigned short retry, tmo;
66 unsigned long data;
65 67
66 au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata)); 68 au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata));
67 au_sync(); 69 au_sync();
@@ -74,20 +76,26 @@ static unsigned short au1xpsc_ac97_read(struct snd_ac97 *ac97,
74 AC97_CDC(pscdata)); 76 AC97_CDC(pscdata));
75 au_sync(); 77 au_sync();
76 78
77 tmo = 2000; 79 tmo = 20;
78 while ((!(au_readl(AC97_EVNT(pscdata)) & PSC_AC97EVNT_CD)) 80 do {
79 && --tmo) 81 udelay(21);
80 udelay(2); 82 if (au_readl(AC97_EVNT(pscdata)) & PSC_AC97EVNT_CD)
83 break;
84 } while (--tmo);
81 85
82 data = au_readl(AC97_CDC(pscdata)) & 0xffff; 86 data = au_readl(AC97_CDC(pscdata));
83 87
84 au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata)); 88 au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata));
85 au_sync(); 89 au_sync();
86 90
87 mutex_unlock(&pscdata->lock); 91 mutex_unlock(&pscdata->lock);
92
93 if (reg != ((data >> 16) & 0x7f))
94 tmo = 1; /* wrong register, try again */
95
88 } while (--retry && !tmo); 96 } while (--retry && !tmo);
89 97
90 return retry ? data : 0xffff; 98 return retry ? data & 0xffff : 0xffff;
91} 99}
92 100
93/* AC97 controller writes to codec register */ 101/* AC97 controller writes to codec register */
@@ -109,10 +117,12 @@ static void au1xpsc_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
109 AC97_CDC(pscdata)); 117 AC97_CDC(pscdata));
110 au_sync(); 118 au_sync();
111 119
112 tmo = 2000; 120 tmo = 20;
113 while ((!(au_readl(AC97_EVNT(pscdata)) & PSC_AC97EVNT_CD)) 121 do {
114 && --tmo) 122 udelay(21);
115 udelay(2); 123 if (au_readl(AC97_EVNT(pscdata)) & PSC_AC97EVNT_CD)
124 break;
125 } while (--tmo);
116 126
117 au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata)); 127 au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata));
118 au_sync(); 128 au_sync();
@@ -195,7 +205,7 @@ static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream,
195 /* FIXME */ 205 /* FIXME */
196 struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata; 206 struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata;
197 unsigned long r, ro, stat; 207 unsigned long r, ro, stat;
198 int chans, stype = SUBSTREAM_TYPE(substream); 208 int chans, t, stype = SUBSTREAM_TYPE(substream);
199 209
200 chans = params_channels(params); 210 chans = params_channels(params);
201 211
@@ -237,8 +247,12 @@ static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream,
237 au_sync(); 247 au_sync();
238 248
239 /* ...wait for it... */ 249 /* ...wait for it... */
240 while (au_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_DR) 250 t = 100;
241 asm volatile ("nop"); 251 while ((au_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_DR) && --t)
252 msleep(1);
253
254 if (!t)
255 printk(KERN_ERR "PSC-AC97: can't disable!\n");
242 256
243 /* ...write config... */ 257 /* ...write config... */
244 au_writel(r, AC97_CFG(pscdata)); 258 au_writel(r, AC97_CFG(pscdata));
@@ -249,8 +263,12 @@ static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream,
249 au_sync(); 263 au_sync();
250 264
251 /* ...and wait for ready bit */ 265 /* ...and wait for ready bit */
252 while (!(au_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_DR)) 266 t = 100;
253 asm volatile ("nop"); 267 while ((!(au_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_DR)) && --t)
268 msleep(1);
269
270 if (!t)
271 printk(KERN_ERR "PSC-AC97: can't enable!\n");
254 272
255 mutex_unlock(&pscdata->lock); 273 mutex_unlock(&pscdata->lock);
256 274
@@ -300,19 +318,55 @@ static int au1xpsc_ac97_trigger(struct snd_pcm_substream *substream,
300static int au1xpsc_ac97_probe(struct platform_device *pdev, 318static int au1xpsc_ac97_probe(struct platform_device *pdev,
301 struct snd_soc_dai *dai) 319 struct snd_soc_dai *dai)
302{ 320{
321 return au1xpsc_ac97_workdata ? 0 : -ENODEV;
322}
323
324static void au1xpsc_ac97_remove(struct platform_device *pdev,
325 struct snd_soc_dai *dai)
326{
327}
328
329static struct snd_soc_dai_ops au1xpsc_ac97_dai_ops = {
330 .trigger = au1xpsc_ac97_trigger,
331 .hw_params = au1xpsc_ac97_hw_params,
332};
333
334struct snd_soc_dai au1xpsc_ac97_dai = {
335 .name = "au1xpsc_ac97",
336 .ac97_control = 1,
337 .probe = au1xpsc_ac97_probe,
338 .remove = au1xpsc_ac97_remove,
339 .playback = {
340 .rates = AC97_RATES,
341 .formats = AC97_FMTS,
342 .channels_min = 2,
343 .channels_max = 2,
344 },
345 .capture = {
346 .rates = AC97_RATES,
347 .formats = AC97_FMTS,
348 .channels_min = 2,
349 .channels_max = 2,
350 },
351 .ops = &au1xpsc_ac97_dai_ops,
352};
353EXPORT_SYMBOL_GPL(au1xpsc_ac97_dai);
354
355static int __devinit au1xpsc_ac97_drvprobe(struct platform_device *pdev)
356{
303 int ret; 357 int ret;
304 struct resource *r; 358 struct resource *r;
305 unsigned long sel; 359 unsigned long sel;
360 struct au1xpsc_audio_data *wd;
306 361
307 if (au1xpsc_ac97_workdata) 362 if (au1xpsc_ac97_workdata)
308 return -EBUSY; 363 return -EBUSY;
309 364
310 au1xpsc_ac97_workdata = 365 wd = kzalloc(sizeof(struct au1xpsc_audio_data), GFP_KERNEL);
311 kzalloc(sizeof(struct au1xpsc_audio_data), GFP_KERNEL); 366 if (!wd)
312 if (!au1xpsc_ac97_workdata)
313 return -ENOMEM; 367 return -ENOMEM;
314 368
315 mutex_init(&au1xpsc_ac97_workdata->lock); 369 mutex_init(&wd->lock);
316 370
317 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 371 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
318 if (!r) { 372 if (!r) {
@@ -321,81 +375,95 @@ static int au1xpsc_ac97_probe(struct platform_device *pdev,
321 } 375 }
322 376
323 ret = -EBUSY; 377 ret = -EBUSY;
324 au1xpsc_ac97_workdata->ioarea = 378 wd->ioarea = request_mem_region(r->start, r->end - r->start + 1,
325 request_mem_region(r->start, r->end - r->start + 1,
326 "au1xpsc_ac97"); 379 "au1xpsc_ac97");
327 if (!au1xpsc_ac97_workdata->ioarea) 380 if (!wd->ioarea)
328 goto out0; 381 goto out0;
329 382
330 au1xpsc_ac97_workdata->mmio = ioremap(r->start, 0xffff); 383 wd->mmio = ioremap(r->start, 0xffff);
331 if (!au1xpsc_ac97_workdata->mmio) 384 if (!wd->mmio)
332 goto out1; 385 goto out1;
333 386
334 /* configuration: max dma trigger threshold, enable ac97 */ 387 /* configuration: max dma trigger threshold, enable ac97 */
335 au1xpsc_ac97_workdata->cfg = PSC_AC97CFG_RT_FIFO8 | 388 wd->cfg = PSC_AC97CFG_RT_FIFO8 | PSC_AC97CFG_TT_FIFO8 |
336 PSC_AC97CFG_TT_FIFO8 | 389 PSC_AC97CFG_DE_ENABLE;
337 PSC_AC97CFG_DE_ENABLE;
338 390
339 /* preserve PSC clock source set up by platform (dev.platform_data 391 /* preserve PSC clock source set up by platform */
340 * is already occupied by soc layer) 392 sel = au_readl(PSC_SEL(wd)) & PSC_SEL_CLK_MASK;
341 */ 393 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd));
342 sel = au_readl(PSC_SEL(au1xpsc_ac97_workdata)) & PSC_SEL_CLK_MASK;
343 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(au1xpsc_ac97_workdata));
344 au_sync(); 394 au_sync();
345 au_writel(0, PSC_SEL(au1xpsc_ac97_workdata)); 395 au_writel(0, PSC_SEL(wd));
346 au_sync(); 396 au_sync();
347 au_writel(PSC_SEL_PS_AC97MODE | sel, PSC_SEL(au1xpsc_ac97_workdata)); 397 au_writel(PSC_SEL_PS_AC97MODE | sel, PSC_SEL(wd));
348 au_sync(); 398 au_sync();
349 /* next up: cold reset. Dont check for PSC-ready now since
350 * there may not be any codec clock yet.
351 */
352 399
353 return 0; 400 ret = snd_soc_register_dai(&au1xpsc_ac97_dai);
401 if (ret)
402 goto out1;
354 403
404 wd->dmapd = au1xpsc_pcm_add(pdev);
405 if (wd->dmapd) {
406 platform_set_drvdata(pdev, wd);
407 au1xpsc_ac97_workdata = wd; /* MDEV */
408 return 0;
409 }
410
411 snd_soc_unregister_dai(&au1xpsc_ac97_dai);
355out1: 412out1:
356 release_resource(au1xpsc_ac97_workdata->ioarea); 413 release_resource(wd->ioarea);
357 kfree(au1xpsc_ac97_workdata->ioarea); 414 kfree(wd->ioarea);
358out0: 415out0:
359 kfree(au1xpsc_ac97_workdata); 416 kfree(wd);
360 au1xpsc_ac97_workdata = NULL;
361 return ret; 417 return ret;
362} 418}
363 419
364static void au1xpsc_ac97_remove(struct platform_device *pdev, 420static int __devexit au1xpsc_ac97_drvremove(struct platform_device *pdev)
365 struct snd_soc_dai *dai)
366{ 421{
422 struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev);
423
424 if (wd->dmapd)
425 au1xpsc_pcm_destroy(wd->dmapd);
426
427 snd_soc_unregister_dai(&au1xpsc_ac97_dai);
428
367 /* disable PSC completely */ 429 /* disable PSC completely */
368 au_writel(0, AC97_CFG(au1xpsc_ac97_workdata)); 430 au_writel(0, AC97_CFG(wd));
369 au_sync(); 431 au_sync();
370 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(au1xpsc_ac97_workdata)); 432 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd));
371 au_sync(); 433 au_sync();
372 434
373 iounmap(au1xpsc_ac97_workdata->mmio); 435 iounmap(wd->mmio);
374 release_resource(au1xpsc_ac97_workdata->ioarea); 436 release_resource(wd->ioarea);
375 kfree(au1xpsc_ac97_workdata->ioarea); 437 kfree(wd->ioarea);
376 kfree(au1xpsc_ac97_workdata); 438 kfree(wd);
377 au1xpsc_ac97_workdata = NULL; 439
440 au1xpsc_ac97_workdata = NULL; /* MDEV */
441
442 return 0;
378} 443}
379 444
380static int au1xpsc_ac97_suspend(struct snd_soc_dai *dai) 445#ifdef CONFIG_PM
446static int au1xpsc_ac97_drvsuspend(struct device *dev)
381{ 447{
448 struct au1xpsc_audio_data *wd = dev_get_drvdata(dev);
449
382 /* save interesting registers and disable PSC */ 450 /* save interesting registers and disable PSC */
383 au1xpsc_ac97_workdata->pm[0] = 451 wd->pm[0] = au_readl(PSC_SEL(wd));
384 au_readl(PSC_SEL(au1xpsc_ac97_workdata));
385 452
386 au_writel(0, AC97_CFG(au1xpsc_ac97_workdata)); 453 au_writel(0, AC97_CFG(wd));
387 au_sync(); 454 au_sync();
388 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(au1xpsc_ac97_workdata)); 455 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd));
389 au_sync(); 456 au_sync();
390 457
391 return 0; 458 return 0;
392} 459}
393 460
394static int au1xpsc_ac97_resume(struct snd_soc_dai *dai) 461static int au1xpsc_ac97_drvresume(struct device *dev)
395{ 462{
463 struct au1xpsc_audio_data *wd = dev_get_drvdata(dev);
464
396 /* restore PSC clock config */ 465 /* restore PSC clock config */
397 au_writel(au1xpsc_ac97_workdata->pm[0] | PSC_SEL_PS_AC97MODE, 466 au_writel(wd->pm[0] | PSC_SEL_PS_AC97MODE, PSC_SEL(wd));
398 PSC_SEL(au1xpsc_ac97_workdata));
399 au_sync(); 467 au_sync();
400 468
401 /* after this point the ac97 core will cold-reset the codec. 469 /* after this point the ac97 core will cold-reset the codec.
@@ -405,48 +473,44 @@ static int au1xpsc_ac97_resume(struct snd_soc_dai *dai)
405 return 0; 473 return 0;
406} 474}
407 475
408static struct snd_soc_dai_ops au1xpsc_ac97_dai_ops = { 476static struct dev_pm_ops au1xpscac97_pmops = {
409 .trigger = au1xpsc_ac97_trigger, 477 .suspend = au1xpsc_ac97_drvsuspend,
410 .hw_params = au1xpsc_ac97_hw_params, 478 .resume = au1xpsc_ac97_drvresume,
411}; 479};
412 480
413struct snd_soc_dai au1xpsc_ac97_dai = { 481#define AU1XPSCAC97_PMOPS &au1xpscac97_pmops
414 .name = "au1xpsc_ac97", 482
415 .ac97_control = 1, 483#else
416 .probe = au1xpsc_ac97_probe, 484
417 .remove = au1xpsc_ac97_remove, 485#define AU1XPSCAC97_PMOPS NULL
418 .suspend = au1xpsc_ac97_suspend, 486
419 .resume = au1xpsc_ac97_resume, 487#endif
420 .playback = { 488
421 .rates = AC97_RATES, 489static struct platform_driver au1xpsc_ac97_driver = {
422 .formats = AC97_FMTS, 490 .driver = {
423 .channels_min = 2, 491 .name = "au1xpsc_ac97",
424 .channels_max = 2, 492 .owner = THIS_MODULE,
425 }, 493 .pm = AU1XPSCAC97_PMOPS,
426 .capture = {
427 .rates = AC97_RATES,
428 .formats = AC97_FMTS,
429 .channels_min = 2,
430 .channels_max = 2,
431 }, 494 },
432 .ops = &au1xpsc_ac97_dai_ops, 495 .probe = au1xpsc_ac97_drvprobe,
496 .remove = __devexit_p(au1xpsc_ac97_drvremove),
433}; 497};
434EXPORT_SYMBOL_GPL(au1xpsc_ac97_dai);
435 498
436static int __init au1xpsc_ac97_init(void) 499static int __init au1xpsc_ac97_load(void)
437{ 500{
438 au1xpsc_ac97_workdata = NULL; 501 au1xpsc_ac97_workdata = NULL;
439 return snd_soc_register_dai(&au1xpsc_ac97_dai); 502 return platform_driver_register(&au1xpsc_ac97_driver);
440} 503}
441 504
442static void __exit au1xpsc_ac97_exit(void) 505static void __exit au1xpsc_ac97_unload(void)
443{ 506{
444 snd_soc_unregister_dai(&au1xpsc_ac97_dai); 507 platform_driver_unregister(&au1xpsc_ac97_driver);
445} 508}
446 509
447module_init(au1xpsc_ac97_init); 510module_init(au1xpsc_ac97_load);
448module_exit(au1xpsc_ac97_exit); 511module_exit(au1xpsc_ac97_unload);
449 512
450MODULE_LICENSE("GPL"); 513MODULE_LICENSE("GPL");
451MODULE_DESCRIPTION("Au12x0/Au1550 PSC AC97 ALSA ASoC audio driver"); 514MODULE_DESCRIPTION("Au12x0/Au1550 PSC AC97 ALSA ASoC audio driver");
452MODULE_AUTHOR("Manuel Lauss <manuel.lauss@gmail.com>"); 515MODULE_AUTHOR("Manuel Lauss");
516
diff --git a/sound/soc/au1x/psc-i2s.c b/sound/soc/au1x/psc-i2s.c
index bb589327ee32..495be6e71931 100644
--- a/sound/soc/au1x/psc-i2s.c
+++ b/sound/soc/au1x/psc-i2s.c
@@ -2,7 +2,7 @@
2 * Au12x0/Au1550 PSC ALSA ASoC audio support. 2 * Au12x0/Au1550 PSC ALSA ASoC audio support.
3 * 3 *
4 * (c) 2007-2008 MSC Vertriebsges.m.b.H., 4 * (c) 2007-2008 MSC Vertriebsges.m.b.H.,
5 * Manuel Lauss <mano@roarinelk.homelinux.net> 5 * Manuel Lauss <manuel.lauss@gmail.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as 8 * it under the terms of the GNU General Public License version 2 as
@@ -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>
@@ -265,16 +266,52 @@ static int au1xpsc_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
265static int au1xpsc_i2s_probe(struct platform_device *pdev, 266static int au1xpsc_i2s_probe(struct platform_device *pdev,
266 struct snd_soc_dai *dai) 267 struct snd_soc_dai *dai)
267{ 268{
269 return au1xpsc_i2s_workdata ? 0 : -ENODEV;
270}
271
272static void au1xpsc_i2s_remove(struct platform_device *pdev,
273 struct snd_soc_dai *dai)
274{
275}
276
277static struct snd_soc_dai_ops au1xpsc_i2s_dai_ops = {
278 .trigger = au1xpsc_i2s_trigger,
279 .hw_params = au1xpsc_i2s_hw_params,
280 .set_fmt = au1xpsc_i2s_set_fmt,
281};
282
283struct snd_soc_dai au1xpsc_i2s_dai = {
284 .name = "au1xpsc_i2s",
285 .probe = au1xpsc_i2s_probe,
286 .remove = au1xpsc_i2s_remove,
287 .playback = {
288 .rates = AU1XPSC_I2S_RATES,
289 .formats = AU1XPSC_I2S_FMTS,
290 .channels_min = 2,
291 .channels_max = 8, /* 2 without external help */
292 },
293 .capture = {
294 .rates = AU1XPSC_I2S_RATES,
295 .formats = AU1XPSC_I2S_FMTS,
296 .channels_min = 2,
297 .channels_max = 8, /* 2 without external help */
298 },
299 .ops = &au1xpsc_i2s_dai_ops,
300};
301EXPORT_SYMBOL(au1xpsc_i2s_dai);
302
303static int __init au1xpsc_i2s_drvprobe(struct platform_device *pdev)
304{
268 struct resource *r; 305 struct resource *r;
269 unsigned long sel; 306 unsigned long sel;
270 int ret; 307 int ret;
308 struct au1xpsc_audio_data *wd;
271 309
272 if (au1xpsc_i2s_workdata) 310 if (au1xpsc_i2s_workdata)
273 return -EBUSY; 311 return -EBUSY;
274 312
275 au1xpsc_i2s_workdata = 313 wd = kzalloc(sizeof(struct au1xpsc_audio_data), GFP_KERNEL);
276 kzalloc(sizeof(struct au1xpsc_audio_data), GFP_KERNEL); 314 if (!wd)
277 if (!au1xpsc_i2s_workdata)
278 return -ENOMEM; 315 return -ENOMEM;
279 316
280 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 317 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -284,131 +321,146 @@ static int au1xpsc_i2s_probe(struct platform_device *pdev,
284 } 321 }
285 322
286 ret = -EBUSY; 323 ret = -EBUSY;
287 au1xpsc_i2s_workdata->ioarea = 324 wd->ioarea = request_mem_region(r->start, r->end - r->start + 1,
288 request_mem_region(r->start, r->end - r->start + 1,
289 "au1xpsc_i2s"); 325 "au1xpsc_i2s");
290 if (!au1xpsc_i2s_workdata->ioarea) 326 if (!wd->ioarea)
291 goto out0; 327 goto out0;
292 328
293 au1xpsc_i2s_workdata->mmio = ioremap(r->start, 0xffff); 329 wd->mmio = ioremap(r->start, 0xffff);
294 if (!au1xpsc_i2s_workdata->mmio) 330 if (!wd->mmio)
295 goto out1; 331 goto out1;
296 332
297 /* preserve PSC clock source set up by platform (dev.platform_data 333 /* preserve PSC clock source set up by platform (dev.platform_data
298 * is already occupied by soc layer) 334 * is already occupied by soc layer)
299 */ 335 */
300 sel = au_readl(PSC_SEL(au1xpsc_i2s_workdata)) & PSC_SEL_CLK_MASK; 336 sel = au_readl(PSC_SEL(wd)) & PSC_SEL_CLK_MASK;
301 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(au1xpsc_i2s_workdata)); 337 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd));
302 au_sync(); 338 au_sync();
303 au_writel(PSC_SEL_PS_I2SMODE | sel, PSC_SEL(au1xpsc_i2s_workdata)); 339 au_writel(PSC_SEL_PS_I2SMODE | sel, PSC_SEL(wd));
304 au_writel(0, I2S_CFG(au1xpsc_i2s_workdata)); 340 au_writel(0, I2S_CFG(wd));
305 au_sync(); 341 au_sync();
306 342
307 /* preconfigure: set max rx/tx fifo depths */ 343 /* preconfigure: set max rx/tx fifo depths */
308 au1xpsc_i2s_workdata->cfg |= 344 wd->cfg |= PSC_I2SCFG_RT_FIFO8 | PSC_I2SCFG_TT_FIFO8;
309 PSC_I2SCFG_RT_FIFO8 | PSC_I2SCFG_TT_FIFO8;
310 345
311 /* don't wait for I2S core to become ready now; clocks may not 346 /* don't wait for I2S core to become ready now; clocks may not
312 * be running yet; depending on clock input for PSC a wait might 347 * be running yet; depending on clock input for PSC a wait might
313 * time out. 348 * time out.
314 */ 349 */
315 350
316 return 0; 351 ret = snd_soc_register_dai(&au1xpsc_i2s_dai);
352 if (ret)
353 goto out1;
317 354
355 /* finally add the DMA device for this PSC */
356 wd->dmapd = au1xpsc_pcm_add(pdev);
357 if (wd->dmapd) {
358 platform_set_drvdata(pdev, wd);
359 au1xpsc_i2s_workdata = wd;
360 return 0;
361 }
362
363 snd_soc_unregister_dai(&au1xpsc_i2s_dai);
318out1: 364out1:
319 release_resource(au1xpsc_i2s_workdata->ioarea); 365 release_resource(wd->ioarea);
320 kfree(au1xpsc_i2s_workdata->ioarea); 366 kfree(wd->ioarea);
321out0: 367out0:
322 kfree(au1xpsc_i2s_workdata); 368 kfree(wd);
323 au1xpsc_i2s_workdata = NULL;
324 return ret; 369 return ret;
325} 370}
326 371
327static void au1xpsc_i2s_remove(struct platform_device *pdev, 372static int __devexit au1xpsc_i2s_drvremove(struct platform_device *pdev)
328 struct snd_soc_dai *dai)
329{ 373{
330 au_writel(0, I2S_CFG(au1xpsc_i2s_workdata)); 374 struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev);
375
376 if (wd->dmapd)
377 au1xpsc_pcm_destroy(wd->dmapd);
378
379 snd_soc_unregister_dai(&au1xpsc_i2s_dai);
380
381 au_writel(0, I2S_CFG(wd));
331 au_sync(); 382 au_sync();
332 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(au1xpsc_i2s_workdata)); 383 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd));
333 au_sync(); 384 au_sync();
334 385
335 iounmap(au1xpsc_i2s_workdata->mmio); 386 iounmap(wd->mmio);
336 release_resource(au1xpsc_i2s_workdata->ioarea); 387 release_resource(wd->ioarea);
337 kfree(au1xpsc_i2s_workdata->ioarea); 388 kfree(wd->ioarea);
338 kfree(au1xpsc_i2s_workdata); 389 kfree(wd);
339 au1xpsc_i2s_workdata = NULL; 390
391 au1xpsc_i2s_workdata = NULL; /* MDEV */
392
393 return 0;
340} 394}
341 395
342static int au1xpsc_i2s_suspend(struct snd_soc_dai *cpu_dai) 396#ifdef CONFIG_PM
397static int au1xpsc_i2s_drvsuspend(struct device *dev)
343{ 398{
399 struct au1xpsc_audio_data *wd = dev_get_drvdata(dev);
400
344 /* save interesting register and disable PSC */ 401 /* save interesting register and disable PSC */
345 au1xpsc_i2s_workdata->pm[0] = 402 wd->pm[0] = au_readl(PSC_SEL(wd));
346 au_readl(PSC_SEL(au1xpsc_i2s_workdata));
347 403
348 au_writel(0, I2S_CFG(au1xpsc_i2s_workdata)); 404 au_writel(0, I2S_CFG(wd));
349 au_sync(); 405 au_sync();
350 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(au1xpsc_i2s_workdata)); 406 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd));
351 au_sync(); 407 au_sync();
352 408
353 return 0; 409 return 0;
354} 410}
355 411
356static int au1xpsc_i2s_resume(struct snd_soc_dai *cpu_dai) 412static int au1xpsc_i2s_drvresume(struct device *dev)
357{ 413{
414 struct au1xpsc_audio_data *wd = dev_get_drvdata(dev);
415
358 /* select I2S mode and PSC clock */ 416 /* select I2S mode and PSC clock */
359 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(au1xpsc_i2s_workdata)); 417 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd));
360 au_sync(); 418 au_sync();
361 au_writel(0, PSC_SEL(au1xpsc_i2s_workdata)); 419 au_writel(0, PSC_SEL(wd));
362 au_sync(); 420 au_sync();
363 au_writel(au1xpsc_i2s_workdata->pm[0], 421 au_writel(wd->pm[0], PSC_SEL(wd));
364 PSC_SEL(au1xpsc_i2s_workdata));
365 au_sync(); 422 au_sync();
366 423
367 return 0; 424 return 0;
368} 425}
369 426
370static struct snd_soc_dai_ops au1xpsc_i2s_dai_ops = { 427static struct dev_pm_ops au1xpsci2s_pmops = {
371 .trigger = au1xpsc_i2s_trigger, 428 .suspend = au1xpsc_i2s_drvsuspend,
372 .hw_params = au1xpsc_i2s_hw_params, 429 .resume = au1xpsc_i2s_drvresume,
373 .set_fmt = au1xpsc_i2s_set_fmt,
374}; 430};
375 431
376struct snd_soc_dai au1xpsc_i2s_dai = { 432#define AU1XPSCI2S_PMOPS &au1xpsci2s_pmops
377 .name = "au1xpsc_i2s", 433
378 .probe = au1xpsc_i2s_probe, 434#else
379 .remove = au1xpsc_i2s_remove, 435
380 .suspend = au1xpsc_i2s_suspend, 436#define AU1XPSCI2S_PMOPS NULL
381 .resume = au1xpsc_i2s_resume, 437
382 .playback = { 438#endif
383 .rates = AU1XPSC_I2S_RATES, 439
384 .formats = AU1XPSC_I2S_FMTS, 440static struct platform_driver au1xpsc_i2s_driver = {
385 .channels_min = 2, 441 .driver = {
386 .channels_max = 8, /* 2 without external help */ 442 .name = "au1xpsc_i2s",
387 }, 443 .owner = THIS_MODULE,
388 .capture = { 444 .pm = AU1XPSCI2S_PMOPS,
389 .rates = AU1XPSC_I2S_RATES,
390 .formats = AU1XPSC_I2S_FMTS,
391 .channels_min = 2,
392 .channels_max = 8, /* 2 without external help */
393 }, 445 },
394 .ops = &au1xpsc_i2s_dai_ops, 446 .probe = au1xpsc_i2s_drvprobe,
447 .remove = __devexit_p(au1xpsc_i2s_drvremove),
395}; 448};
396EXPORT_SYMBOL(au1xpsc_i2s_dai);
397 449
398static int __init au1xpsc_i2s_init(void) 450static int __init au1xpsc_i2s_load(void)
399{ 451{
400 au1xpsc_i2s_workdata = NULL; 452 au1xpsc_i2s_workdata = NULL;
401 return snd_soc_register_dai(&au1xpsc_i2s_dai); 453 return platform_driver_register(&au1xpsc_i2s_driver);
402} 454}
403 455
404static void __exit au1xpsc_i2s_exit(void) 456static void __exit au1xpsc_i2s_unload(void)
405{ 457{
406 snd_soc_unregister_dai(&au1xpsc_i2s_dai); 458 platform_driver_unregister(&au1xpsc_i2s_driver);
407} 459}
408 460
409module_init(au1xpsc_i2s_init); 461module_init(au1xpsc_i2s_load);
410module_exit(au1xpsc_i2s_exit); 462module_exit(au1xpsc_i2s_unload);
411 463
412MODULE_LICENSE("GPL"); 464MODULE_LICENSE("GPL");
413MODULE_DESCRIPTION("Au12x0/Au1550 PSC I2S ALSA ASoC audio driver"); 465MODULE_DESCRIPTION("Au12x0/Au1550 PSC I2S ALSA ASoC audio driver");
414MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>"); 466MODULE_AUTHOR("Manuel Lauss");
diff --git a/sound/soc/au1x/psc.h b/sound/soc/au1x/psc.h
index 3f474e8ed4f6..32d3807d3f5a 100644
--- a/sound/soc/au1x/psc.h
+++ b/sound/soc/au1x/psc.h
@@ -2,7 +2,7 @@
2 * Au12x0/Au1550 PSC ALSA ASoC audio support. 2 * Au12x0/Au1550 PSC ALSA ASoC audio support.
3 * 3 *
4 * (c) 2007-2008 MSC Vertriebsges.m.b.H., 4 * (c) 2007-2008 MSC Vertriebsges.m.b.H.,
5 * Manuel Lauss <mano@roarinelk.homelinux.net> 5 * Manuel Lauss <manuel.lauss@gmail.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as 8 * it under the terms of the GNU General Public License version 2 as
@@ -21,6 +21,10 @@ extern struct snd_soc_dai au1xpsc_i2s_dai;
21extern struct snd_soc_platform au1xpsc_soc_platform; 21extern struct snd_soc_platform au1xpsc_soc_platform;
22extern struct snd_ac97_bus_ops soc_ac97_ops; 22extern struct snd_ac97_bus_ops soc_ac97_ops;
23 23
24/* DBDMA helpers */
25extern struct platform_device *au1xpsc_pcm_add(struct platform_device *pdev);
26extern void au1xpsc_pcm_destroy(struct platform_device *dmapd);
27
24struct au1xpsc_audio_data { 28struct au1xpsc_audio_data {
25 void __iomem *mmio; 29 void __iomem *mmio;
26 30
@@ -30,6 +34,7 @@ struct au1xpsc_audio_data {
30 unsigned long pm[2]; 34 unsigned long pm[2];
31 struct resource *ioarea; 35 struct resource *ioarea;
32 struct mutex lock; 36 struct mutex lock;
37 struct platform_device *dmapd;
33}; 38};
34 39
35#define PCM_TX 0 40#define PCM_TX 0
diff --git a/sound/soc/au1x/sample-ac97.c b/sound/soc/au1x/sample-ac97.c
deleted file mode 100644
index 27683eb7905e..000000000000
--- a/sound/soc/au1x/sample-ac97.c
+++ /dev/null
@@ -1,144 +0,0 @@
1/*
2 * Sample Au12x0/Au1550 PSC AC97 sound machine.
3 *
4 * Copyright (c) 2007-2008 Manuel Lauss <mano@roarinelk.homelinux.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms outlined in the file COPYING at the root of this
8 * source archive.
9 *
10 * This is a very generic AC97 sound machine driver for boards which
11 * have (AC97) audio at PSC1 (e.g. DB1200 demoboards).
12 */
13
14#include <linux/module.h>
15#include <linux/moduleparam.h>
16#include <linux/timer.h>
17#include <linux/interrupt.h>
18#include <linux/platform_device.h>
19#include <sound/core.h>
20#include <sound/pcm.h>
21#include <sound/soc.h>
22#include <sound/soc-dapm.h>
23#include <asm/mach-au1x00/au1000.h>
24#include <asm/mach-au1x00/au1xxx_psc.h>
25#include <asm/mach-au1x00/au1xxx_dbdma.h>
26
27#include "../codecs/ac97.h"
28#include "psc.h"
29
30static int au1xpsc_sample_ac97_init(struct snd_soc_codec *codec)
31{
32 snd_soc_dapm_sync(codec);
33 return 0;
34}
35
36static struct snd_soc_dai_link au1xpsc_sample_ac97_dai = {
37 .name = "AC97",
38 .stream_name = "AC97 HiFi",
39 .cpu_dai = &au1xpsc_ac97_dai, /* see psc-ac97.c */
40 .codec_dai = &ac97_dai, /* see codecs/ac97.c */
41 .init = au1xpsc_sample_ac97_init,
42 .ops = NULL,
43};
44
45static struct snd_soc_card au1xpsc_sample_ac97_machine = {
46 .name = "Au1xxx PSC AC97 Audio",
47 .dai_link = &au1xpsc_sample_ac97_dai,
48 .num_links = 1,
49};
50
51static struct snd_soc_device au1xpsc_sample_ac97_devdata = {
52 .card = &au1xpsc_sample_ac97_machine,
53 .platform = &au1xpsc_soc_platform, /* see dbdma2.c */
54 .codec_dev = &soc_codec_dev_ac97,
55};
56
57static struct resource au1xpsc_psc1_res[] = {
58 [0] = {
59 .start = CPHYSADDR(PSC1_BASE_ADDR),
60 .end = CPHYSADDR(PSC1_BASE_ADDR) + 0x000fffff,
61 .flags = IORESOURCE_MEM,
62 },
63 [1] = {
64#ifdef CONFIG_SOC_AU1200
65 .start = AU1200_PSC1_INT,
66 .end = AU1200_PSC1_INT,
67#elif defined(CONFIG_SOC_AU1550)
68 .start = AU1550_PSC1_INT,
69 .end = AU1550_PSC1_INT,
70#endif
71 .flags = IORESOURCE_IRQ,
72 },
73 [2] = {
74 .start = DSCR_CMD0_PSC1_TX,
75 .end = DSCR_CMD0_PSC1_TX,
76 .flags = IORESOURCE_DMA,
77 },
78 [3] = {
79 .start = DSCR_CMD0_PSC1_RX,
80 .end = DSCR_CMD0_PSC1_RX,
81 .flags = IORESOURCE_DMA,
82 },
83};
84
85static struct platform_device *au1xpsc_sample_ac97_dev;
86
87static int __init au1xpsc_sample_ac97_load(void)
88{
89 int ret;
90
91#ifdef CONFIG_SOC_AU1200
92 unsigned long io;
93
94 /* modify sys_pinfunc for AC97 on PSC1 */
95 io = au_readl(SYS_PINFUNC);
96 io |= SYS_PINFUNC_P1C;
97 io &= ~(SYS_PINFUNC_P1A | SYS_PINFUNC_P1B);
98 au_writel(io, SYS_PINFUNC);
99 au_sync();
100#endif
101
102 ret = -ENOMEM;
103
104 /* setup PSC clock source for AC97 part: external clock provided
105 * by codec. The psc-ac97.c driver depends on this setting!
106 */
107 au_writel(PSC_SEL_CLK_SERCLK, PSC1_BASE_ADDR + PSC_SEL_OFFSET);
108 au_sync();
109
110 au1xpsc_sample_ac97_dev = platform_device_alloc("soc-audio", -1);
111 if (!au1xpsc_sample_ac97_dev)
112 goto out;
113
114 au1xpsc_sample_ac97_dev->resource =
115 kmemdup(au1xpsc_psc1_res, sizeof(struct resource) *
116 ARRAY_SIZE(au1xpsc_psc1_res), GFP_KERNEL);
117 au1xpsc_sample_ac97_dev->num_resources = ARRAY_SIZE(au1xpsc_psc1_res);
118 au1xpsc_sample_ac97_dev->id = 1;
119
120 platform_set_drvdata(au1xpsc_sample_ac97_dev,
121 &au1xpsc_sample_ac97_devdata);
122 au1xpsc_sample_ac97_devdata.dev = &au1xpsc_sample_ac97_dev->dev;
123 ret = platform_device_add(au1xpsc_sample_ac97_dev);
124
125 if (ret) {
126 platform_device_put(au1xpsc_sample_ac97_dev);
127 au1xpsc_sample_ac97_dev = NULL;
128 }
129
130out:
131 return ret;
132}
133
134static void __exit au1xpsc_sample_ac97_exit(void)
135{
136 platform_device_unregister(au1xpsc_sample_ac97_dev);
137}
138
139module_init(au1xpsc_sample_ac97_load);
140module_exit(au1xpsc_sample_ac97_exit);
141
142MODULE_LICENSE("GPL");
143MODULE_DESCRIPTION("Au1xxx PSC sample AC97 machine");
144MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>");
diff --git a/sound/soc/blackfin/bf5xx-ac97-pcm.c b/sound/soc/blackfin/bf5xx-ac97-pcm.c
index cf0dfb7ca221..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>
@@ -349,9 +349,7 @@ static int bf5xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
349 sport_handle->tx_dma_buf = dma_alloc_coherent(NULL, \ 349 sport_handle->tx_dma_buf = dma_alloc_coherent(NULL, \
350 size, &sport_handle->tx_dma_phy, GFP_KERNEL); 350 size, &sport_handle->tx_dma_phy, GFP_KERNEL);
351 if (!sport_handle->tx_dma_buf) { 351 if (!sport_handle->tx_dma_buf) {
352 pr_err("Failed to allocate memory for tx dma \ 352 pr_err("Failed to allocate memory for tx dma buf - Please increase uncached DMA memory region\n");
353 buf - Please increase uncached DMA \
354 memory region\n");
355 return -ENOMEM; 353 return -ENOMEM;
356 } else 354 } else
357 memset(sport_handle->tx_dma_buf, 0, size); 355 memset(sport_handle->tx_dma_buf, 0, size);
@@ -362,9 +360,7 @@ static int bf5xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
362 sport_handle->rx_dma_buf = dma_alloc_coherent(NULL, \ 360 sport_handle->rx_dma_buf = dma_alloc_coherent(NULL, \
363 size, &sport_handle->rx_dma_phy, GFP_KERNEL); 361 size, &sport_handle->rx_dma_phy, GFP_KERNEL);
364 if (!sport_handle->rx_dma_buf) { 362 if (!sport_handle->rx_dma_buf) {
365 pr_err("Failed to allocate memory for rx dma \ 363 pr_err("Failed to allocate memory for rx dma buf - Please increase uncached DMA memory region\n");
366 buf - Please increase uncached DMA \
367 memory region\n");
368 return -ENOMEM; 364 return -ENOMEM;
369 } else 365 } else
370 memset(sport_handle->rx_dma_buf, 0, size); 366 memset(sport_handle->rx_dma_buf, 0, size);
diff --git a/sound/soc/blackfin/bf5xx-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-ad1836.c b/sound/soc/blackfin/bf5xx-ad1836.c
index cd361e304b0f..0f45a3f56be8 100644
--- a/sound/soc/blackfin/bf5xx-ad1836.c
+++ b/sound/soc/blackfin/bf5xx-ad1836.c
@@ -52,6 +52,7 @@ static int bf5xx_ad1836_hw_params(struct snd_pcm_substream *substream,
52 struct snd_soc_pcm_runtime *rtd = substream->private_data; 52 struct snd_soc_pcm_runtime *rtd = substream->private_data;
53 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 53 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
54 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 54 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
55 unsigned int channel_map[] = {0, 4, 1, 5, 2, 6, 3, 7};
55 int ret = 0; 56 int ret = 0;
56 /* set cpu DAI configuration */ 57 /* set cpu DAI configuration */
57 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A | 58 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A |
@@ -65,6 +66,12 @@ static int bf5xx_ad1836_hw_params(struct snd_pcm_substream *substream,
65 if (ret < 0) 66 if (ret < 0)
66 return ret; 67 return ret;
67 68
69 /* set cpu DAI channel mapping */
70 ret = snd_soc_dai_set_channel_map(cpu_dai, ARRAY_SIZE(channel_map),
71 channel_map, ARRAY_SIZE(channel_map), channel_map);
72 if (ret < 0)
73 return ret;
74
68 return 0; 75 return 0;
69} 76}
70 77
diff --git a/sound/soc/blackfin/bf5xx-ad1938.c b/sound/soc/blackfin/bf5xx-ad1938.c
index 08269e91810c..2ef1e5013b8c 100644
--- a/sound/soc/blackfin/bf5xx-ad1938.c
+++ b/sound/soc/blackfin/bf5xx-ad1938.c
@@ -61,6 +61,7 @@ static int bf5xx_ad1938_hw_params(struct snd_pcm_substream *substream,
61 struct snd_soc_pcm_runtime *rtd = substream->private_data; 61 struct snd_soc_pcm_runtime *rtd = substream->private_data;
62 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 62 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
63 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 63 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
64 unsigned int channel_map[] = {0, 1, 2, 3, 4, 5, 6, 7};
64 int ret = 0; 65 int ret = 0;
65 /* set cpu DAI configuration */ 66 /* set cpu DAI configuration */
66 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A | 67 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A |
@@ -75,7 +76,13 @@ static int bf5xx_ad1938_hw_params(struct snd_pcm_substream *substream,
75 return ret; 76 return ret;
76 77
77 /* set codec DAI slots, 8 channels, all channels are enabled */ 78 /* set codec DAI slots, 8 channels, all channels are enabled */
78 ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xFF, 8); 79 ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xFF, 0xFF, 8, 32);
80 if (ret < 0)
81 return ret;
82
83 /* set cpu DAI channel mapping */
84 ret = snd_soc_dai_set_channel_map(cpu_dai, ARRAY_SIZE(channel_map),
85 channel_map, ARRAY_SIZE(channel_map), channel_map);
79 if (ret < 0) 86 if (ret < 0)
80 return ret; 87 return ret;
81 88
diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.c b/sound/soc/blackfin/bf5xx-i2s-pcm.c
index 62fbb8459569..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>
@@ -207,8 +207,7 @@ static int bf5xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
207 buf->area = dma_alloc_coherent(pcm->card->dev, size, 207 buf->area = dma_alloc_coherent(pcm->card->dev, size,
208 &buf->addr, GFP_KERNEL); 208 &buf->addr, GFP_KERNEL);
209 if (!buf->area) { 209 if (!buf->area) {
210 pr_err("Failed to allocate dma memory \ 210 pr_err("Failed to allocate dma memory - Please increase uncached DMA memory region\n");
211 Please increase uncached DMA memory region\n");
212 return -ENOMEM; 211 return -ENOMEM;
213 } 212 }
214 buf->bytes = size; 213 buf->bytes = size;
diff --git a/sound/soc/blackfin/bf5xx-i2s.c b/sound/soc/blackfin/bf5xx-i2s.c
index 084b68884ada..3e6ada0dd1c4 100644
--- a/sound/soc/blackfin/bf5xx-i2s.c
+++ b/sound/soc/blackfin/bf5xx-i2s.c
@@ -49,7 +49,6 @@ struct bf5xx_i2s_port {
49 u16 rcr1; 49 u16 rcr1;
50 u16 tcr2; 50 u16 tcr2;
51 u16 rcr2; 51 u16 rcr2;
52 int counter;
53 int configured; 52 int configured;
54}; 53};
55 54
@@ -133,16 +132,6 @@ static int bf5xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
133 return ret; 132 return ret;
134} 133}
135 134
136static int bf5xx_i2s_startup(struct snd_pcm_substream *substream,
137 struct snd_soc_dai *dai)
138{
139 pr_debug("%s enter\n", __func__);
140
141 /*this counter is used for counting how many pcm streams are opened*/
142 bf5xx_i2s.counter++;
143 return 0;
144}
145
146static int bf5xx_i2s_hw_params(struct snd_pcm_substream *substream, 135static int bf5xx_i2s_hw_params(struct snd_pcm_substream *substream,
147 struct snd_pcm_hw_params *params, 136 struct snd_pcm_hw_params *params,
148 struct snd_soc_dai *dai) 137 struct snd_soc_dai *dai)
@@ -201,9 +190,8 @@ static void bf5xx_i2s_shutdown(struct snd_pcm_substream *substream,
201 struct snd_soc_dai *dai) 190 struct snd_soc_dai *dai)
202{ 191{
203 pr_debug("%s enter\n", __func__); 192 pr_debug("%s enter\n", __func__);
204 bf5xx_i2s.counter--;
205 /* No active stream, SPORT is allowed to be configured again. */ 193 /* No active stream, SPORT is allowed to be configured again. */
206 if (!bf5xx_i2s.counter) 194 if (!dai->active)
207 bf5xx_i2s.configured = 0; 195 bf5xx_i2s.configured = 0;
208} 196}
209 197
@@ -284,7 +272,6 @@ static int bf5xx_i2s_resume(struct snd_soc_dai *dai)
284 SNDRV_PCM_FMTBIT_S32_LE) 272 SNDRV_PCM_FMTBIT_S32_LE)
285 273
286static struct snd_soc_dai_ops bf5xx_i2s_dai_ops = { 274static struct snd_soc_dai_ops bf5xx_i2s_dai_ops = {
287 .startup = bf5xx_i2s_startup,
288 .shutdown = bf5xx_i2s_shutdown, 275 .shutdown = bf5xx_i2s_shutdown,
289 .hw_params = bf5xx_i2s_hw_params, 276 .hw_params = bf5xx_i2s_hw_params,
290 .set_fmt = bf5xx_i2s_set_dai_fmt, 277 .set_fmt = bf5xx_i2s_set_dai_fmt,
diff --git a/sound/soc/blackfin/bf5xx-tdm-pcm.c b/sound/soc/blackfin/bf5xx-tdm-pcm.c
index ccb5e823bd18..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>
@@ -43,7 +43,7 @@
43#include "bf5xx-tdm.h" 43#include "bf5xx-tdm.h"
44#include "bf5xx-sport.h" 44#include "bf5xx-sport.h"
45 45
46#define PCM_BUFFER_MAX 0x10000 46#define PCM_BUFFER_MAX 0x8000
47#define FRAGMENT_SIZE_MIN (4*1024) 47#define FRAGMENT_SIZE_MIN (4*1024)
48#define FRAGMENTS_MIN 2 48#define FRAGMENTS_MIN 2
49#define FRAGMENTS_MAX 32 49#define FRAGMENTS_MAX 32
@@ -177,6 +177,9 @@ out:
177static int bf5xx_pcm_copy(struct snd_pcm_substream *substream, int channel, 177static int bf5xx_pcm_copy(struct snd_pcm_substream *substream, int channel,
178 snd_pcm_uframes_t pos, void *buf, snd_pcm_uframes_t count) 178 snd_pcm_uframes_t pos, void *buf, snd_pcm_uframes_t count)
179{ 179{
180 struct snd_pcm_runtime *runtime = substream->runtime;
181 struct sport_device *sport = runtime->private_data;
182 struct bf5xx_tdm_port *tdm_port = sport->private_data;
180 unsigned int *src; 183 unsigned int *src;
181 unsigned int *dst; 184 unsigned int *dst;
182 int i; 185 int i;
@@ -188,7 +191,7 @@ static int bf5xx_pcm_copy(struct snd_pcm_substream *substream, int channel,
188 dst += pos * 8; 191 dst += pos * 8;
189 while (count--) { 192 while (count--) {
190 for (i = 0; i < substream->runtime->channels; i++) 193 for (i = 0; i < substream->runtime->channels; i++)
191 *(dst + i) = *src++; 194 *(dst + tdm_port->tx_map[i]) = *src++;
192 dst += 8; 195 dst += 8;
193 } 196 }
194 } else { 197 } else {
@@ -198,7 +201,7 @@ static int bf5xx_pcm_copy(struct snd_pcm_substream *substream, int channel,
198 src += pos * 8; 201 src += pos * 8;
199 while (count--) { 202 while (count--) {
200 for (i = 0; i < substream->runtime->channels; i++) 203 for (i = 0; i < substream->runtime->channels; i++)
201 *dst++ = *(src+i); 204 *dst++ = *(src + tdm_port->rx_map[i]);
202 src += 8; 205 src += 8;
203 } 206 }
204 } 207 }
@@ -241,8 +244,7 @@ static int bf5xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
241 buf->area = dma_alloc_coherent(pcm->card->dev, size * 4, 244 buf->area = dma_alloc_coherent(pcm->card->dev, size * 4,
242 &buf->addr, GFP_KERNEL); 245 &buf->addr, GFP_KERNEL);
243 if (!buf->area) { 246 if (!buf->area) {
244 pr_err("Failed to allocate dma memory \ 247 pr_err("Failed to allocate dma memory - Please increase uncached DMA memory region\n");
245 Please increase uncached DMA memory region\n");
246 return -ENOMEM; 248 return -ENOMEM;
247 } 249 }
248 buf->bytes = size; 250 buf->bytes = size;
diff --git a/sound/soc/blackfin/bf5xx-tdm.c b/sound/soc/blackfin/bf5xx-tdm.c
index ff546e91a22e..4b360124083e 100644
--- a/sound/soc/blackfin/bf5xx-tdm.c
+++ b/sound/soc/blackfin/bf5xx-tdm.c
@@ -46,14 +46,6 @@
46#include "bf5xx-sport.h" 46#include "bf5xx-sport.h"
47#include "bf5xx-tdm.h" 47#include "bf5xx-tdm.h"
48 48
49struct bf5xx_tdm_port {
50 u16 tcr1;
51 u16 rcr1;
52 u16 tcr2;
53 u16 rcr2;
54 int configured;
55};
56
57static struct bf5xx_tdm_port bf5xx_tdm; 49static struct bf5xx_tdm_port bf5xx_tdm;
58static int sport_num = CONFIG_SND_BF5XX_SPORT_NUM; 50static int sport_num = CONFIG_SND_BF5XX_SPORT_NUM;
59 51
@@ -181,6 +173,40 @@ static void bf5xx_tdm_shutdown(struct snd_pcm_substream *substream,
181 bf5xx_tdm.configured = 0; 173 bf5xx_tdm.configured = 0;
182} 174}
183 175
176static int bf5xx_tdm_set_channel_map(struct snd_soc_dai *dai,
177 unsigned int tx_num, unsigned int *tx_slot,
178 unsigned int rx_num, unsigned int *rx_slot)
179{
180 int i;
181 unsigned int slot;
182 unsigned int tx_mapped = 0, rx_mapped = 0;
183
184 if ((tx_num > BFIN_TDM_DAI_MAX_SLOTS) ||
185 (rx_num > BFIN_TDM_DAI_MAX_SLOTS))
186 return -EINVAL;
187
188 for (i = 0; i < tx_num; i++) {
189 slot = tx_slot[i];
190 if ((slot < BFIN_TDM_DAI_MAX_SLOTS) &&
191 (!(tx_mapped & (1 << slot)))) {
192 bf5xx_tdm.tx_map[i] = slot;
193 tx_mapped |= 1 << slot;
194 } else
195 return -EINVAL;
196 }
197 for (i = 0; i < rx_num; i++) {
198 slot = rx_slot[i];
199 if ((slot < BFIN_TDM_DAI_MAX_SLOTS) &&
200 (!(rx_mapped & (1 << slot)))) {
201 bf5xx_tdm.rx_map[i] = slot;
202 rx_mapped |= 1 << slot;
203 } else
204 return -EINVAL;
205 }
206
207 return 0;
208}
209
184#ifdef CONFIG_PM 210#ifdef CONFIG_PM
185static int bf5xx_tdm_suspend(struct snd_soc_dai *dai) 211static int bf5xx_tdm_suspend(struct snd_soc_dai *dai)
186{ 212{
@@ -235,6 +261,7 @@ static struct snd_soc_dai_ops bf5xx_tdm_dai_ops = {
235 .hw_params = bf5xx_tdm_hw_params, 261 .hw_params = bf5xx_tdm_hw_params,
236 .set_fmt = bf5xx_tdm_set_dai_fmt, 262 .set_fmt = bf5xx_tdm_set_dai_fmt,
237 .shutdown = bf5xx_tdm_shutdown, 263 .shutdown = bf5xx_tdm_shutdown,
264 .set_channel_map = bf5xx_tdm_set_channel_map,
238}; 265};
239 266
240struct snd_soc_dai bf5xx_tdm_dai = { 267struct snd_soc_dai bf5xx_tdm_dai = {
@@ -300,6 +327,8 @@ static int __devinit bfin_tdm_probe(struct platform_device *pdev)
300 pr_err("Failed to register DAI: %d\n", ret); 327 pr_err("Failed to register DAI: %d\n", ret);
301 goto sport_config_err; 328 goto sport_config_err;
302 } 329 }
330
331 sport_handle->private_data = &bf5xx_tdm;
303 return 0; 332 return 0;
304 333
305sport_config_err: 334sport_config_err:
diff --git a/sound/soc/blackfin/bf5xx-tdm.h b/sound/soc/blackfin/bf5xx-tdm.h
index 618ec3d90cd4..04189a18c1ba 100644
--- a/sound/soc/blackfin/bf5xx-tdm.h
+++ b/sound/soc/blackfin/bf5xx-tdm.h
@@ -9,6 +9,17 @@
9#ifndef _BF5XX_TDM_H 9#ifndef _BF5XX_TDM_H
10#define _BF5XX_TDM_H 10#define _BF5XX_TDM_H
11 11
12#define BFIN_TDM_DAI_MAX_SLOTS 8
13struct bf5xx_tdm_port {
14 u16 tcr1;
15 u16 rcr1;
16 u16 tcr2;
17 u16 rcr2;
18 unsigned int tx_map[BFIN_TDM_DAI_MAX_SLOTS];
19 unsigned int rx_map[BFIN_TDM_DAI_MAX_SLOTS];
20 int configured;
21};
22
12extern struct snd_soc_dai bf5xx_tdm_dai; 23extern struct snd_soc_dai bf5xx_tdm_dai;
13 24
14#endif 25#endif
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 0edca93af3b0..1743d565e996 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -15,12 +15,15 @@ config SND_SOC_ALL_CODECS
15 select SND_SOC_AD1836 if SPI_MASTER 15 select SND_SOC_AD1836 if SPI_MASTER
16 select SND_SOC_AD1938 if SPI_MASTER 16 select SND_SOC_AD1938 if SPI_MASTER
17 select SND_SOC_AD1980 if SND_SOC_AC97_BUS 17 select SND_SOC_AD1980 if SND_SOC_AC97_BUS
18 select SND_SOC_ADS117X
18 select SND_SOC_AD73311 if I2C 19 select SND_SOC_AD73311 if I2C
19 select SND_SOC_AK4104 if SPI_MASTER 20 select SND_SOC_AK4104 if SPI_MASTER
20 select SND_SOC_AK4535 if I2C 21 select SND_SOC_AK4535 if I2C
21 select SND_SOC_AK4642 if I2C 22 select SND_SOC_AK4642 if I2C
23 select SND_SOC_AK4671 if I2C
22 select SND_SOC_CS4270 if I2C 24 select SND_SOC_CS4270 if I2C
23 select SND_SOC_MAX9877 if I2C 25 select SND_SOC_MAX9877 if I2C
26 select SND_SOC_DA7210 if I2C
24 select SND_SOC_PCM3008 27 select SND_SOC_PCM3008
25 select SND_SOC_SPDIF 28 select SND_SOC_SPDIF
26 select SND_SOC_SSM2602 if I2C 29 select SND_SOC_SSM2602 if I2C
@@ -28,14 +31,19 @@ config SND_SOC_ALL_CODECS
28 select SND_SOC_TLV320AIC23 if I2C 31 select SND_SOC_TLV320AIC23 if I2C
29 select SND_SOC_TLV320AIC26 if SPI_MASTER 32 select SND_SOC_TLV320AIC26 if SPI_MASTER
30 select SND_SOC_TLV320AIC3X if I2C 33 select SND_SOC_TLV320AIC3X if I2C
34 select SND_SOC_TPA6130A2 if I2C
35 select SND_SOC_TLV320DAC33 if I2C
31 select SND_SOC_TWL4030 if TWL4030_CORE 36 select SND_SOC_TWL4030 if TWL4030_CORE
32 select SND_SOC_UDA134X 37 select SND_SOC_UDA134X
33 select SND_SOC_UDA1380 if I2C 38 select SND_SOC_UDA1380 if I2C
39 select SND_SOC_WM2000 if I2C
34 select SND_SOC_WM8350 if MFD_WM8350 40 select SND_SOC_WM8350 if MFD_WM8350
35 select SND_SOC_WM8400 if MFD_WM8400 41 select SND_SOC_WM8400 if MFD_WM8400
36 select SND_SOC_WM8510 if SND_SOC_I2C_AND_SPI 42 select SND_SOC_WM8510 if SND_SOC_I2C_AND_SPI
37 select SND_SOC_WM8523 if I2C 43 select SND_SOC_WM8523 if I2C
38 select SND_SOC_WM8580 if I2C 44 select SND_SOC_WM8580 if I2C
45 select SND_SOC_WM8711 if SND_SOC_I2C_AND_SPI
46 select SND_SOC_WM8727
39 select SND_SOC_WM8728 if SND_SOC_I2C_AND_SPI 47 select SND_SOC_WM8728 if SND_SOC_I2C_AND_SPI
40 select SND_SOC_WM8731 if SND_SOC_I2C_AND_SPI 48 select SND_SOC_WM8731 if SND_SOC_I2C_AND_SPI
41 select SND_SOC_WM8750 if SND_SOC_I2C_AND_SPI 49 select SND_SOC_WM8750 if SND_SOC_I2C_AND_SPI
@@ -43,14 +51,18 @@ config SND_SOC_ALL_CODECS
43 select SND_SOC_WM8776 if SND_SOC_I2C_AND_SPI 51 select SND_SOC_WM8776 if SND_SOC_I2C_AND_SPI
44 select SND_SOC_WM8900 if I2C 52 select SND_SOC_WM8900 if I2C
45 select SND_SOC_WM8903 if I2C 53 select SND_SOC_WM8903 if I2C
54 select SND_SOC_WM8904 if I2C
46 select SND_SOC_WM8940 if I2C 55 select SND_SOC_WM8940 if I2C
56 select SND_SOC_WM8955 if I2C
47 select SND_SOC_WM8960 if I2C 57 select SND_SOC_WM8960 if I2C
48 select SND_SOC_WM8961 if I2C 58 select SND_SOC_WM8961 if I2C
49 select SND_SOC_WM8971 if I2C 59 select SND_SOC_WM8971 if I2C
50 select SND_SOC_WM8974 if I2C 60 select SND_SOC_WM8974 if I2C
61 select SND_SOC_WM8978 if I2C
51 select SND_SOC_WM8988 if SND_SOC_I2C_AND_SPI 62 select SND_SOC_WM8988 if SND_SOC_I2C_AND_SPI
52 select SND_SOC_WM8990 if I2C 63 select SND_SOC_WM8990 if I2C
53 select SND_SOC_WM8993 if I2C 64 select SND_SOC_WM8993 if I2C
65 select SND_SOC_WM8994 if MFD_WM8994
54 select SND_SOC_WM9081 if I2C 66 select SND_SOC_WM9081 if I2C
55 select SND_SOC_WM9705 if SND_SOC_AC97_BUS 67 select SND_SOC_WM9705 if SND_SOC_AC97_BUS
56 select SND_SOC_WM9712 if SND_SOC_AC97_BUS 68 select SND_SOC_WM9712 if SND_SOC_AC97_BUS
@@ -86,6 +98,9 @@ config SND_SOC_AD1980
86 98
87config SND_SOC_AD73311 99config SND_SOC_AD73311
88 tristate 100 tristate
101
102config SND_SOC_ADS117X
103 tristate
89 104
90config SND_SOC_AK4104 105config SND_SOC_AK4104
91 tristate 106 tristate
@@ -96,10 +111,16 @@ config SND_SOC_AK4535
96config SND_SOC_AK4642 111config SND_SOC_AK4642
97 tristate 112 tristate
98 113
114config SND_SOC_AK4671
115 tristate
116
99# Cirrus Logic CS4270 Codec 117# Cirrus Logic CS4270 Codec
100config SND_SOC_CS4270 118config SND_SOC_CS4270
101 tristate 119 tristate
102 120
121config SND_SOC_DA7210
122 tristate
123
103# Cirrus Logic CS4270 Codec VD = 3.3V Errata 124# Cirrus Logic CS4270 Codec VD = 3.3V Errata
104# Select if you are affected by the errata where the part will not function 125# Select if you are affected by the errata where the part will not function
105# if MCLK divide-by-1.5 is selected and VD is set to 3.3V. The driver will 126# if MCLK divide-by-1.5 is selected and VD is set to 3.3V. The driver will
@@ -136,7 +157,11 @@ config SND_SOC_TLV320AIC26
136config SND_SOC_TLV320AIC3X 157config SND_SOC_TLV320AIC3X
137 tristate 158 tristate
138 159
160config SND_SOC_TLV320DAC33
161 tristate
162
139config SND_SOC_TWL4030 163config SND_SOC_TWL4030
164 select TWL4030_CODEC
140 tristate 165 tristate
141 166
142config SND_SOC_UDA134X 167config SND_SOC_UDA134X
@@ -160,6 +185,12 @@ config SND_SOC_WM8523
160config SND_SOC_WM8580 185config SND_SOC_WM8580
161 tristate 186 tristate
162 187
188config SND_SOC_WM8711
189 tristate
190
191config SND_SOC_WM8727
192 tristate
193
163config SND_SOC_WM8728 194config SND_SOC_WM8728
164 tristate 195 tristate
165 196
@@ -181,9 +212,15 @@ config SND_SOC_WM8900
181config SND_SOC_WM8903 212config SND_SOC_WM8903
182 tristate 213 tristate
183 214
215config SND_SOC_WM8904
216 tristate
217
184config SND_SOC_WM8940 218config SND_SOC_WM8940
185 tristate 219 tristate
186 220
221config SND_SOC_WM8955
222 tristate
223
187config SND_SOC_WM8960 224config SND_SOC_WM8960
188 tristate 225 tristate
189 226
@@ -196,6 +233,9 @@ config SND_SOC_WM8971
196config SND_SOC_WM8974 233config SND_SOC_WM8974
197 tristate 234 tristate
198 235
236config SND_SOC_WM8978
237 tristate
238
199config SND_SOC_WM8988 239config SND_SOC_WM8988
200 tristate 240 tristate
201 241
@@ -205,6 +245,9 @@ config SND_SOC_WM8990
205config SND_SOC_WM8993 245config SND_SOC_WM8993
206 tristate 246 tristate
207 247
248config SND_SOC_WM8994
249 tristate
250
208config SND_SOC_WM9081 251config SND_SOC_WM9081
209 tristate 252 tristate
210 253
@@ -220,3 +263,9 @@ config SND_SOC_WM9713
220# Amp 263# Amp
221config SND_SOC_MAX9877 264config SND_SOC_MAX9877
222 tristate 265 tristate
266
267config SND_SOC_TPA6130A2
268 tristate
269
270config SND_SOC_WM2000
271 tristate
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index fb4af28486ba..dd5ce6df6292 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -3,11 +3,14 @@ snd-soc-ad1836-objs := ad1836.o
3snd-soc-ad1938-objs := ad1938.o 3snd-soc-ad1938-objs := ad1938.o
4snd-soc-ad1980-objs := ad1980.o 4snd-soc-ad1980-objs := ad1980.o
5snd-soc-ad73311-objs := ad73311.o 5snd-soc-ad73311-objs := ad73311.o
6snd-soc-ads117x-objs := ads117x.o
6snd-soc-ak4104-objs := ak4104.o 7snd-soc-ak4104-objs := ak4104.o
7snd-soc-ak4535-objs := ak4535.o 8snd-soc-ak4535-objs := ak4535.o
8snd-soc-ak4642-objs := ak4642.o 9snd-soc-ak4642-objs := ak4642.o
10snd-soc-ak4671-objs := ak4671.o
9snd-soc-cs4270-objs := cs4270.o 11snd-soc-cs4270-objs := cs4270.o
10snd-soc-cx20442-objs := cx20442.o 12snd-soc-cx20442-objs := cx20442.o
13snd-soc-da7210-objs := da7210.o
11snd-soc-l3-objs := l3.o 14snd-soc-l3-objs := l3.o
12snd-soc-pcm3008-objs := pcm3008.o 15snd-soc-pcm3008-objs := pcm3008.o
13snd-soc-spdif-objs := spdif_transciever.o 16snd-soc-spdif-objs := spdif_transciever.o
@@ -16,6 +19,7 @@ snd-soc-stac9766-objs := stac9766.o
16snd-soc-tlv320aic23-objs := tlv320aic23.o 19snd-soc-tlv320aic23-objs := tlv320aic23.o
17snd-soc-tlv320aic26-objs := tlv320aic26.o 20snd-soc-tlv320aic26-objs := tlv320aic26.o
18snd-soc-tlv320aic3x-objs := tlv320aic3x.o 21snd-soc-tlv320aic3x-objs := tlv320aic3x.o
22snd-soc-tlv320dac33-objs := tlv320dac33.o
19snd-soc-twl4030-objs := twl4030.o 23snd-soc-twl4030-objs := twl4030.o
20snd-soc-uda134x-objs := uda134x.o 24snd-soc-uda134x-objs := uda134x.o
21snd-soc-uda1380-objs := uda1380.o 25snd-soc-uda1380-objs := uda1380.o
@@ -24,6 +28,8 @@ snd-soc-wm8400-objs := wm8400.o
24snd-soc-wm8510-objs := wm8510.o 28snd-soc-wm8510-objs := wm8510.o
25snd-soc-wm8523-objs := wm8523.o 29snd-soc-wm8523-objs := wm8523.o
26snd-soc-wm8580-objs := wm8580.o 30snd-soc-wm8580-objs := wm8580.o
31snd-soc-wm8711-objs := wm8711.o
32snd-soc-wm8727-objs := wm8727.o
27snd-soc-wm8728-objs := wm8728.o 33snd-soc-wm8728-objs := wm8728.o
28snd-soc-wm8731-objs := wm8731.o 34snd-soc-wm8731-objs := wm8731.o
29snd-soc-wm8750-objs := wm8750.o 35snd-soc-wm8750-objs := wm8750.o
@@ -31,14 +37,18 @@ snd-soc-wm8753-objs := wm8753.o
31snd-soc-wm8776-objs := wm8776.o 37snd-soc-wm8776-objs := wm8776.o
32snd-soc-wm8900-objs := wm8900.o 38snd-soc-wm8900-objs := wm8900.o
33snd-soc-wm8903-objs := wm8903.o 39snd-soc-wm8903-objs := wm8903.o
40snd-soc-wm8904-objs := wm8904.o
34snd-soc-wm8940-objs := wm8940.o 41snd-soc-wm8940-objs := wm8940.o
42snd-soc-wm8955-objs := wm8955.o
35snd-soc-wm8960-objs := wm8960.o 43snd-soc-wm8960-objs := wm8960.o
36snd-soc-wm8961-objs := wm8961.o 44snd-soc-wm8961-objs := wm8961.o
37snd-soc-wm8971-objs := wm8971.o 45snd-soc-wm8971-objs := wm8971.o
38snd-soc-wm8974-objs := wm8974.o 46snd-soc-wm8974-objs := wm8974.o
47snd-soc-wm8978-objs := wm8978.o
39snd-soc-wm8988-objs := wm8988.o 48snd-soc-wm8988-objs := wm8988.o
40snd-soc-wm8990-objs := wm8990.o 49snd-soc-wm8990-objs := wm8990.o
41snd-soc-wm8993-objs := wm8993.o 50snd-soc-wm8993-objs := wm8993.o
51snd-soc-wm8994-objs := wm8994.o
42snd-soc-wm9081-objs := wm9081.o 52snd-soc-wm9081-objs := wm9081.o
43snd-soc-wm9705-objs := wm9705.o 53snd-soc-wm9705-objs := wm9705.o
44snd-soc-wm9712-objs := wm9712.o 54snd-soc-wm9712-objs := wm9712.o
@@ -47,17 +57,22 @@ snd-soc-wm-hubs-objs := wm_hubs.o
47 57
48# Amp 58# Amp
49snd-soc-max9877-objs := max9877.o 59snd-soc-max9877-objs := max9877.o
60snd-soc-tpa6130a2-objs := tpa6130a2.o
61snd-soc-wm2000-objs := wm2000.o
50 62
51obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o 63obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o
52obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o 64obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o
53obj-$(CONFIG_SND_SOC_AD1938) += snd-soc-ad1938.o 65obj-$(CONFIG_SND_SOC_AD1938) += snd-soc-ad1938.o
54obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o 66obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o
55obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o 67obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o
68obj-$(CONFIG_SND_SOC_ADS117X) += snd-soc-ads117x.o
56obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o 69obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o
57obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o 70obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o
58obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o 71obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o
72obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o
59obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o 73obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
60obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o 74obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o
75obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o
61obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o 76obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o
62obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o 77obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o
63obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o 78obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o
@@ -66,6 +81,7 @@ obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o
66obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o 81obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o
67obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o 82obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o
68obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o 83obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o
84obj-$(CONFIG_SND_SOC_TLV320DAC33) += snd-soc-tlv320dac33.o
69obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o 85obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o
70obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o 86obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o
71obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o 87obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o
@@ -74,6 +90,8 @@ obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o
74obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o 90obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o
75obj-$(CONFIG_SND_SOC_WM8523) += snd-soc-wm8523.o 91obj-$(CONFIG_SND_SOC_WM8523) += snd-soc-wm8523.o
76obj-$(CONFIG_SND_SOC_WM8580) += snd-soc-wm8580.o 92obj-$(CONFIG_SND_SOC_WM8580) += snd-soc-wm8580.o
93obj-$(CONFIG_SND_SOC_WM8711) += snd-soc-wm8711.o
94obj-$(CONFIG_SND_SOC_WM8727) += snd-soc-wm8727.o
77obj-$(CONFIG_SND_SOC_WM8728) += snd-soc-wm8728.o 95obj-$(CONFIG_SND_SOC_WM8728) += snd-soc-wm8728.o
78obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o 96obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o
79obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o 97obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o
@@ -81,14 +99,18 @@ obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o
81obj-$(CONFIG_SND_SOC_WM8776) += snd-soc-wm8776.o 99obj-$(CONFIG_SND_SOC_WM8776) += snd-soc-wm8776.o
82obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o 100obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o
83obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o 101obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o
84obj-$(CONFIG_SND_SOC_WM8971) += snd-soc-wm8971.o 102obj-$(CONFIG_SND_SOC_WM8904) += snd-soc-wm8904.o
85obj-$(CONFIG_SND_SOC_WM8974) += snd-soc-wm8974.o
86obj-$(CONFIG_SND_SOC_WM8940) += snd-soc-wm8940.o 103obj-$(CONFIG_SND_SOC_WM8940) += snd-soc-wm8940.o
104obj-$(CONFIG_SND_SOC_WM8955) += snd-soc-wm8955.o
87obj-$(CONFIG_SND_SOC_WM8960) += snd-soc-wm8960.o 105obj-$(CONFIG_SND_SOC_WM8960) += snd-soc-wm8960.o
88obj-$(CONFIG_SND_SOC_WM8961) += snd-soc-wm8961.o 106obj-$(CONFIG_SND_SOC_WM8961) += snd-soc-wm8961.o
107obj-$(CONFIG_SND_SOC_WM8971) += snd-soc-wm8971.o
108obj-$(CONFIG_SND_SOC_WM8974) += snd-soc-wm8974.o
109obj-$(CONFIG_SND_SOC_WM8978) += snd-soc-wm8978.o
89obj-$(CONFIG_SND_SOC_WM8988) += snd-soc-wm8988.o 110obj-$(CONFIG_SND_SOC_WM8988) += snd-soc-wm8988.o
90obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o 111obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o
91obj-$(CONFIG_SND_SOC_WM8993) += snd-soc-wm8993.o 112obj-$(CONFIG_SND_SOC_WM8993) += snd-soc-wm8993.o
113obj-$(CONFIG_SND_SOC_WM8994) += snd-soc-wm8994.o
92obj-$(CONFIG_SND_SOC_WM9081) += snd-soc-wm9081.o 114obj-$(CONFIG_SND_SOC_WM9081) += snd-soc-wm9081.o
93obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-wm9705.o 115obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-wm9705.o
94obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o 116obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o
@@ -97,3 +119,5 @@ obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o
97 119
98# Amp 120# Amp
99obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o 121obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o
122obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o
123obj-$(CONFIG_SND_SOC_WM2000) += snd-soc-wm2000.o
diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c
index 932299bb5d1e..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>
@@ -80,9 +81,11 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
80static int ac97_soc_probe(struct platform_device *pdev) 81static int ac97_soc_probe(struct platform_device *pdev)
81{ 82{
82 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 83 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
84 struct snd_soc_card *card = socdev->card;
83 struct snd_soc_codec *codec; 85 struct snd_soc_codec *codec;
84 struct snd_ac97_bus *ac97_bus; 86 struct snd_ac97_bus *ac97_bus;
85 struct snd_ac97_template ac97_template; 87 struct snd_ac97_template ac97_template;
88 int i;
86 int ret = 0; 89 int ret = 0;
87 90
88 printk(KERN_INFO "AC97 SoC Audio Codec %s\n", AC97_VERSION); 91 printk(KERN_INFO "AC97 SoC Audio Codec %s\n", AC97_VERSION);
@@ -117,9 +120,13 @@ static int ac97_soc_probe(struct platform_device *pdev)
117 if (ret < 0) 120 if (ret < 0)
118 goto bus_err; 121 goto bus_err;
119 122
120 ret = snd_soc_init_card(socdev); 123 for (i = 0; i < card->num_links; i++) {
121 if (ret < 0) 124 if (card->dai_link[i].codec_dai->ac97_control) {
122 goto bus_err; 125 snd_ac97_dev_add_pdata(codec->ac97,
126 card->dai_link[i].cpu_dai->ac97_pdata);
127 }
128 }
129
123 return 0; 130 return 0;
124 131
125bus_err: 132bus_err:
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c
index c48485f2c55d..11b62dee842c 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>
@@ -171,57 +172,35 @@ static int ad1836_hw_params(struct snd_pcm_substream *substream,
171 return 0; 172 return 0;
172} 173}
173 174
174 175#ifdef CONFIG_PM
175/* 176static int ad1836_soc_suspend(struct platform_device *pdev,
176 * interface to read/write ad1836 register 177 pm_message_t state)
177 */
178#define AD1836_SPI_REG_SHFT 12
179#define AD1836_SPI_READ (1 << 11)
180#define AD1836_SPI_VAL_MSK 0x3FF
181
182/*
183 * write to the ad1836 register space
184 */
185
186static int ad1836_write_reg(struct snd_soc_codec *codec, unsigned int reg,
187 unsigned int value)
188{ 178{
189 u16 *reg_cache = codec->reg_cache; 179 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
190 int ret = 0; 180 struct snd_soc_codec *codec = socdev->card->codec;
191 181
192 if (value != reg_cache[reg]) { 182 /* reset clock control mode */
193 unsigned short buf; 183 u16 adc_ctrl2 = snd_soc_read(codec, AD1836_ADC_CTRL2);
194 struct spi_transfer t = { 184 adc_ctrl2 &= ~AD1836_ADC_SERFMT_MASK;
195 .tx_buf = &buf,
196 .len = 2,
197 };
198 struct spi_message m;
199
200 buf = (reg << AD1836_SPI_REG_SHFT) |
201 (value & AD1836_SPI_VAL_MSK);
202 spi_message_init(&m);
203 spi_message_add_tail(&t, &m);
204 ret = spi_sync(codec->control_data, &m);
205 if (ret == 0)
206 reg_cache[reg] = value;
207 }
208 185
209 return ret; 186 return snd_soc_write(codec, AD1836_ADC_CTRL2, adc_ctrl2);
210} 187}
211 188
212/* 189static int ad1836_soc_resume(struct platform_device *pdev)
213 * read from the ad1836 register space cache
214 */
215static unsigned int ad1836_read_reg_cache(struct snd_soc_codec *codec,
216 unsigned int reg)
217{ 190{
218 u16 *reg_cache = codec->reg_cache; 191 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
192 struct snd_soc_codec *codec = socdev->card->codec;
219 193
220 if (reg >= codec->reg_cache_size) 194 /* restore clock control mode */
221 return -EINVAL; 195 u16 adc_ctrl2 = snd_soc_read(codec, AD1836_ADC_CTRL2);
196 adc_ctrl2 |= AD1836_ADC_AUX;
222 197
223 return reg_cache[reg]; 198 return snd_soc_write(codec, AD1836_ADC_CTRL2, adc_ctrl2);
224} 199}
200#else
201#define ad1836_soc_suspend NULL
202#define ad1836_soc_resume NULL
203#endif
225 204
226static int __devinit ad1836_spi_probe(struct spi_device *spi) 205static int __devinit ad1836_spi_probe(struct spi_device *spi)
227{ 206{
@@ -306,32 +285,38 @@ static int ad1836_register(struct ad1836_priv *ad1836)
306 codec->owner = THIS_MODULE; 285 codec->owner = THIS_MODULE;
307 codec->dai = &ad1836_dai; 286 codec->dai = &ad1836_dai;
308 codec->num_dai = 1; 287 codec->num_dai = 1;
309 codec->write = ad1836_write_reg;
310 codec->read = ad1836_read_reg_cache;
311 INIT_LIST_HEAD(&codec->dapm_widgets); 288 INIT_LIST_HEAD(&codec->dapm_widgets);
312 INIT_LIST_HEAD(&codec->dapm_paths); 289 INIT_LIST_HEAD(&codec->dapm_paths);
313 290
314 ad1836_dai.dev = codec->dev; 291 ad1836_dai.dev = codec->dev;
315 ad1836_codec = codec; 292 ad1836_codec = codec;
316 293
294 ret = snd_soc_codec_set_cache_io(codec, 4, 12, SND_SOC_SPI);
295 if (ret < 0) {
296 dev_err(codec->dev, "failed to set cache I/O: %d\n",
297 ret);
298 kfree(ad1836);
299 return ret;
300 }
301
317 /* default setting for ad1836 */ 302 /* default setting for ad1836 */
318 /* de-emphasis: 48kHz, power-on dac */ 303 /* de-emphasis: 48kHz, power-on dac */
319 codec->write(codec, AD1836_DAC_CTRL1, 0x300); 304 snd_soc_write(codec, AD1836_DAC_CTRL1, 0x300);
320 /* unmute dac channels */ 305 /* unmute dac channels */
321 codec->write(codec, AD1836_DAC_CTRL2, 0x0); 306 snd_soc_write(codec, AD1836_DAC_CTRL2, 0x0);
322 /* high-pass filter enable, power-on adc */ 307 /* high-pass filter enable, power-on adc */
323 codec->write(codec, AD1836_ADC_CTRL1, 0x100); 308 snd_soc_write(codec, AD1836_ADC_CTRL1, 0x100);
324 /* unmute adc channles, adc aux mode */ 309 /* unmute adc channles, adc aux mode */
325 codec->write(codec, AD1836_ADC_CTRL2, 0x180); 310 snd_soc_write(codec, AD1836_ADC_CTRL2, 0x180);
326 /* left/right diff:PGA/MUX */ 311 /* left/right diff:PGA/MUX */
327 codec->write(codec, AD1836_ADC_CTRL3, 0x3A); 312 snd_soc_write(codec, AD1836_ADC_CTRL3, 0x3A);
328 /* volume */ 313 /* volume */
329 codec->write(codec, AD1836_DAC_L1_VOL, 0x3FF); 314 snd_soc_write(codec, AD1836_DAC_L1_VOL, 0x3FF);
330 codec->write(codec, AD1836_DAC_R1_VOL, 0x3FF); 315 snd_soc_write(codec, AD1836_DAC_R1_VOL, 0x3FF);
331 codec->write(codec, AD1836_DAC_L2_VOL, 0x3FF); 316 snd_soc_write(codec, AD1836_DAC_L2_VOL, 0x3FF);
332 codec->write(codec, AD1836_DAC_R2_VOL, 0x3FF); 317 snd_soc_write(codec, AD1836_DAC_R2_VOL, 0x3FF);
333 codec->write(codec, AD1836_DAC_L3_VOL, 0x3FF); 318 snd_soc_write(codec, AD1836_DAC_L3_VOL, 0x3FF);
334 codec->write(codec, AD1836_DAC_R3_VOL, 0x3FF); 319 snd_soc_write(codec, AD1836_DAC_R3_VOL, 0x3FF);
335 320
336 ret = snd_soc_register_codec(codec); 321 ret = snd_soc_register_codec(codec);
337 if (ret != 0) { 322 if (ret != 0) {
@@ -385,19 +370,7 @@ static int ad1836_probe(struct platform_device *pdev)
385 snd_soc_dapm_new_controls(codec, ad1836_dapm_widgets, 370 snd_soc_dapm_new_controls(codec, ad1836_dapm_widgets,
386 ARRAY_SIZE(ad1836_dapm_widgets)); 371 ARRAY_SIZE(ad1836_dapm_widgets));
387 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); 372 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
388 snd_soc_dapm_new_widgets(codec);
389 373
390 ret = snd_soc_init_card(socdev);
391 if (ret < 0) {
392 dev_err(codec->dev, "failed to register card: %d\n", ret);
393 goto card_err;
394 }
395
396 return ret;
397
398card_err:
399 snd_soc_free_pcms(socdev);
400 snd_soc_dapm_free(socdev);
401pcm_err: 374pcm_err:
402 return ret; 375 return ret;
403} 376}
@@ -416,6 +389,8 @@ static int ad1836_remove(struct platform_device *pdev)
416struct snd_soc_codec_device soc_codec_dev_ad1836 = { 389struct snd_soc_codec_device soc_codec_dev_ad1836 = {
417 .probe = ad1836_probe, 390 .probe = ad1836_probe,
418 .remove = ad1836_remove, 391 .remove = ad1836_remove,
392 .suspend = ad1836_soc_suspend,
393 .resume = ad1836_soc_resume,
419}; 394};
420EXPORT_SYMBOL_GPL(soc_codec_dev_ad1836); 395EXPORT_SYMBOL_GPL(soc_codec_dev_ad1836);
421 396
diff --git a/sound/soc/codecs/ad1836.h b/sound/soc/codecs/ad1836.h
index 7660ee6973c0..e9d90d3951c5 100644
--- a/sound/soc/codecs/ad1836.h
+++ b/sound/soc/codecs/ad1836.h
@@ -54,6 +54,7 @@
54#define AD1836_ADC_SERFMT_MASK (7 << 6) 54#define AD1836_ADC_SERFMT_MASK (7 << 6)
55#define AD1836_ADC_SERFMT_PCK256 (0x4 << 6) 55#define AD1836_ADC_SERFMT_PCK256 (0x4 << 6)
56#define AD1836_ADC_SERFMT_PCK128 (0x5 << 6) 56#define AD1836_ADC_SERFMT_PCK128 (0x5 << 6)
57#define AD1836_ADC_AUX (0x6 << 6)
57 58
58#define AD1836_ADC_CTRL3 14 59#define AD1836_ADC_CTRL3 14
59 60
diff --git a/sound/soc/codecs/ad1938.c b/sound/soc/codecs/ad1938.c
index 34b30efc3cb0..240cd155b313 100644
--- a/sound/soc/codecs/ad1938.c
+++ b/sound/soc/codecs/ad1938.c
@@ -27,6 +27,7 @@
27 */ 27 */
28 28
29#include <linux/init.h> 29#include <linux/init.h>
30#include <linux/slab.h>
30#include <linux/module.h> 31#include <linux/module.h>
31#include <linux/kernel.h> 32#include <linux/kernel.h>
32#include <linux/device.h> 33#include <linux/device.h>
@@ -46,6 +47,11 @@ struct ad1938_priv {
46 u8 reg_cache[AD1938_NUM_REGS]; 47 u8 reg_cache[AD1938_NUM_REGS];
47}; 48};
48 49
50/* ad1938 register cache & default register settings */
51static const u8 ad1938_reg[AD1938_NUM_REGS] = {
52 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0,
53};
54
49static struct snd_soc_codec *ad1938_codec; 55static struct snd_soc_codec *ad1938_codec;
50struct snd_soc_codec_device soc_codec_dev_ad1938; 56struct snd_soc_codec_device soc_codec_dev_ad1938;
51static int ad1938_register(struct ad1938_priv *ad1938); 57static int ad1938_register(struct ad1938_priv *ad1938);
@@ -97,6 +103,7 @@ static const struct snd_kcontrol_new ad1938_snd_controls[] = {
97static const struct snd_soc_dapm_widget ad1938_dapm_widgets[] = { 103static const struct snd_soc_dapm_widget ad1938_dapm_widgets[] = {
98 SND_SOC_DAPM_DAC("DAC", "Playback", AD1938_DAC_CTRL0, 0, 1), 104 SND_SOC_DAPM_DAC("DAC", "Playback", AD1938_DAC_CTRL0, 0, 1),
99 SND_SOC_DAPM_ADC("ADC", "Capture", SND_SOC_NOPM, 0, 0), 105 SND_SOC_DAPM_ADC("ADC", "Capture", SND_SOC_NOPM, 0, 0),
106 SND_SOC_DAPM_SUPPLY("PLL_PWR", AD1938_PLL_CLK_CTRL0, 0, 1, NULL, 0),
100 SND_SOC_DAPM_SUPPLY("ADC_PWR", AD1938_ADC_CTRL0, 0, 1, NULL, 0), 107 SND_SOC_DAPM_SUPPLY("ADC_PWR", AD1938_ADC_CTRL0, 0, 1, NULL, 0),
101 SND_SOC_DAPM_OUTPUT("DAC1OUT"), 108 SND_SOC_DAPM_OUTPUT("DAC1OUT"),
102 SND_SOC_DAPM_OUTPUT("DAC2OUT"), 109 SND_SOC_DAPM_OUTPUT("DAC2OUT"),
@@ -107,6 +114,8 @@ static const struct snd_soc_dapm_widget ad1938_dapm_widgets[] = {
107}; 114};
108 115
109static const struct snd_soc_dapm_route audio_paths[] = { 116static const struct snd_soc_dapm_route audio_paths[] = {
117 { "DAC", NULL, "PLL_PWR" },
118 { "ADC", NULL, "PLL_PWR" },
110 { "DAC", NULL, "ADC_PWR" }, 119 { "DAC", NULL, "ADC_PWR" },
111 { "ADC", NULL, "ADC_PWR" }, 120 { "ADC", NULL, "ADC_PWR" },
112 { "DAC1OUT", "DAC1 Switch", "DAC" }, 121 { "DAC1OUT", "DAC1 Switch", "DAC" },
@@ -126,30 +135,20 @@ static int ad1938_mute(struct snd_soc_dai *dai, int mute)
126 struct snd_soc_codec *codec = dai->codec; 135 struct snd_soc_codec *codec = dai->codec;
127 int reg; 136 int reg;
128 137
129 reg = codec->read(codec, AD1938_DAC_CTRL2); 138 reg = snd_soc_read(codec, AD1938_DAC_CTRL2);
130 reg = (mute > 0) ? reg | AD1938_DAC_MASTER_MUTE : reg & 139 reg = (mute > 0) ? reg | AD1938_DAC_MASTER_MUTE : reg &
131 (~AD1938_DAC_MASTER_MUTE); 140 (~AD1938_DAC_MASTER_MUTE);
132 codec->write(codec, AD1938_DAC_CTRL2, reg); 141 snd_soc_write(codec, AD1938_DAC_CTRL2, reg);
133
134 return 0;
135}
136
137static inline int ad1938_pll_powerctrl(struct snd_soc_codec *codec, int cmd)
138{
139 int reg = codec->read(codec, AD1938_PLL_CLK_CTRL0);
140 reg = (cmd > 0) ? reg & (~AD1938_PLL_POWERDOWN) : reg |
141 AD1938_PLL_POWERDOWN;
142 codec->write(codec, AD1938_PLL_CLK_CTRL0, reg);
143 142
144 return 0; 143 return 0;
145} 144}
146 145
147static int ad1938_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, 146static int ad1938_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
148 unsigned int mask, int slots, int width) 147 unsigned int rx_mask, int slots, int width)
149{ 148{
150 struct snd_soc_codec *codec = dai->codec; 149 struct snd_soc_codec *codec = dai->codec;
151 int dac_reg = codec->read(codec, AD1938_DAC_CTRL1); 150 int dac_reg = snd_soc_read(codec, AD1938_DAC_CTRL1);
152 int adc_reg = codec->read(codec, AD1938_ADC_CTRL2); 151 int adc_reg = snd_soc_read(codec, AD1938_ADC_CTRL2);
153 152
154 dac_reg &= ~AD1938_DAC_CHAN_MASK; 153 dac_reg &= ~AD1938_DAC_CHAN_MASK;
155 adc_reg &= ~AD1938_ADC_CHAN_MASK; 154 adc_reg &= ~AD1938_ADC_CHAN_MASK;
@@ -175,8 +174,8 @@ static int ad1938_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
175 return -EINVAL; 174 return -EINVAL;
176 } 175 }
177 176
178 codec->write(codec, AD1938_DAC_CTRL1, dac_reg); 177 snd_soc_write(codec, AD1938_DAC_CTRL1, dac_reg);
179 codec->write(codec, AD1938_ADC_CTRL2, adc_reg); 178 snd_soc_write(codec, AD1938_ADC_CTRL2, adc_reg);
180 179
181 return 0; 180 return 0;
182} 181}
@@ -187,8 +186,8 @@ static int ad1938_set_dai_fmt(struct snd_soc_dai *codec_dai,
187 struct snd_soc_codec *codec = codec_dai->codec; 186 struct snd_soc_codec *codec = codec_dai->codec;
188 int adc_reg, dac_reg; 187 int adc_reg, dac_reg;
189 188
190 adc_reg = codec->read(codec, AD1938_ADC_CTRL2); 189 adc_reg = snd_soc_read(codec, AD1938_ADC_CTRL2);
191 dac_reg = codec->read(codec, AD1938_DAC_CTRL1); 190 dac_reg = snd_soc_read(codec, AD1938_DAC_CTRL1);
192 191
193 /* At present, the driver only support AUX ADC mode(SND_SOC_DAIFMT_I2S 192 /* At present, the driver only support AUX ADC mode(SND_SOC_DAIFMT_I2S
194 * with TDM) and ADC&DAC TDM mode(SND_SOC_DAIFMT_DSP_A) 193 * with TDM) and ADC&DAC TDM mode(SND_SOC_DAIFMT_DSP_A)
@@ -265,8 +264,8 @@ static int ad1938_set_dai_fmt(struct snd_soc_dai *codec_dai,
265 return -EINVAL; 264 return -EINVAL;
266 } 265 }
267 266
268 codec->write(codec, AD1938_ADC_CTRL2, adc_reg); 267 snd_soc_write(codec, AD1938_ADC_CTRL2, adc_reg);
269 codec->write(codec, AD1938_DAC_CTRL1, dac_reg); 268 snd_soc_write(codec, AD1938_DAC_CTRL1, dac_reg);
270 269
271 return 0; 270 return 0;
272} 271}
@@ -295,134 +294,13 @@ static int ad1938_hw_params(struct snd_pcm_substream *substream,
295 break; 294 break;
296 } 295 }
297 296
298 reg = codec->read(codec, AD1938_DAC_CTRL2); 297 reg = snd_soc_read(codec, AD1938_DAC_CTRL2);
299 reg = (reg & (~AD1938_DAC_WORD_LEN_MASK)) | word_len; 298 reg = (reg & (~AD1938_DAC_WORD_LEN_MASK)) | word_len;
300 codec->write(codec, AD1938_DAC_CTRL2, reg); 299 snd_soc_write(codec, AD1938_DAC_CTRL2, reg);
301 300
302 reg = codec->read(codec, AD1938_ADC_CTRL1); 301 reg = snd_soc_read(codec, AD1938_ADC_CTRL1);
303 reg = (reg & (~AD1938_ADC_WORD_LEN_MASK)) | word_len; 302 reg = (reg & (~AD1938_ADC_WORD_LEN_MASK)) | word_len;
304 codec->write(codec, AD1938_ADC_CTRL1, reg); 303 snd_soc_write(codec, AD1938_ADC_CTRL1, reg);
305
306 return 0;
307}
308
309static int ad1938_set_bias_level(struct snd_soc_codec *codec,
310 enum snd_soc_bias_level level)
311{
312 switch (level) {
313 case SND_SOC_BIAS_ON:
314 ad1938_pll_powerctrl(codec, 1);
315 break;
316 case SND_SOC_BIAS_PREPARE:
317 break;
318 case SND_SOC_BIAS_STANDBY:
319 case SND_SOC_BIAS_OFF:
320 ad1938_pll_powerctrl(codec, 0);
321 break;
322 }
323 codec->bias_level = level;
324 return 0;
325}
326
327/*
328 * interface to read/write ad1938 register
329 */
330
331#define AD1938_SPI_ADDR 0x4
332#define AD1938_SPI_READ 0x1
333#define AD1938_SPI_BUFLEN 3
334
335/*
336 * write to the ad1938 register space
337 */
338
339static int ad1938_write_reg(struct snd_soc_codec *codec, unsigned int reg,
340 unsigned int value)
341{
342 u8 *reg_cache = codec->reg_cache;
343 int ret = 0;
344
345 if (value != reg_cache[reg]) {
346 uint8_t buf[AD1938_SPI_BUFLEN];
347 struct spi_transfer t = {
348 .tx_buf = buf,
349 .len = AD1938_SPI_BUFLEN,
350 };
351 struct spi_message m;
352
353 buf[0] = AD1938_SPI_ADDR << 1;
354 buf[1] = reg;
355 buf[2] = value;
356 spi_message_init(&m);
357 spi_message_add_tail(&t, &m);
358 ret = spi_sync(codec->control_data, &m);
359 if (ret == 0)
360 reg_cache[reg] = value;
361 }
362
363 return ret;
364}
365
366/*
367 * read from the ad1938 register space cache
368 */
369
370static unsigned int ad1938_read_reg_cache(struct snd_soc_codec *codec,
371 unsigned int reg)
372{
373 u8 *reg_cache = codec->reg_cache;
374
375 if (reg >= codec->reg_cache_size)
376 return -EINVAL;
377
378 return reg_cache[reg];
379}
380
381/*
382 * read from the ad1938 register space
383 */
384
385static unsigned int ad1938_read_reg(struct snd_soc_codec *codec,
386 unsigned int reg)
387{
388 char w_buf[AD1938_SPI_BUFLEN];
389 char r_buf[AD1938_SPI_BUFLEN];
390 int ret;
391
392 struct spi_transfer t = {
393 .tx_buf = w_buf,
394 .rx_buf = r_buf,
395 .len = AD1938_SPI_BUFLEN,
396 };
397 struct spi_message m;
398
399 w_buf[0] = (AD1938_SPI_ADDR << 1) | AD1938_SPI_READ;
400 w_buf[1] = reg;
401 w_buf[2] = 0;
402
403 spi_message_init(&m);
404 spi_message_add_tail(&t, &m);
405 ret = spi_sync(codec->control_data, &m);
406 if (ret == 0)
407 return r_buf[2];
408 else
409 return -EIO;
410}
411
412static int ad1938_fill_cache(struct snd_soc_codec *codec)
413{
414 int i;
415 u8 *reg_cache = codec->reg_cache;
416 struct spi_device *spi = codec->control_data;
417
418 for (i = 0; i < codec->reg_cache_size; i++) {
419 int ret = ad1938_read_reg(codec, i);
420 if (ret == -EIO) {
421 dev_err(&spi->dev, "AD1938 SPI read failure\n");
422 return ret;
423 }
424 reg_cache[i] = ret;
425 }
426 304
427 return 0; 305 return 0;
428} 306}
@@ -512,32 +390,37 @@ static int ad1938_register(struct ad1938_priv *ad1938)
512 codec->owner = THIS_MODULE; 390 codec->owner = THIS_MODULE;
513 codec->dai = &ad1938_dai; 391 codec->dai = &ad1938_dai;
514 codec->num_dai = 1; 392 codec->num_dai = 1;
515 codec->write = ad1938_write_reg;
516 codec->read = ad1938_read_reg_cache;
517 codec->set_bias_level = ad1938_set_bias_level;
518 INIT_LIST_HEAD(&codec->dapm_widgets); 393 INIT_LIST_HEAD(&codec->dapm_widgets);
519 INIT_LIST_HEAD(&codec->dapm_paths); 394 INIT_LIST_HEAD(&codec->dapm_paths);
520 395
521 ad1938_dai.dev = codec->dev; 396 ad1938_dai.dev = codec->dev;
522 ad1938_codec = codec; 397 ad1938_codec = codec;
523 398
399 memcpy(codec->reg_cache, ad1938_reg, AD1938_NUM_REGS);
400
401 ret = snd_soc_codec_set_cache_io(codec, 16, 8, SND_SOC_SPI);
402 if (ret < 0) {
403 dev_err(codec->dev, "failed to set cache I/O: %d\n",
404 ret);
405 kfree(ad1938);
406 return ret;
407 }
408
524 /* default setting for ad1938 */ 409 /* default setting for ad1938 */
525 410
526 /* unmute dac channels */ 411 /* unmute dac channels */
527 codec->write(codec, AD1938_DAC_CHNL_MUTE, 0x0); 412 snd_soc_write(codec, AD1938_DAC_CHNL_MUTE, 0x0);
528 /* de-emphasis: 48kHz, powedown dac */ 413 /* de-emphasis: 48kHz, powedown dac */
529 codec->write(codec, AD1938_DAC_CTRL2, 0x1A); 414 snd_soc_write(codec, AD1938_DAC_CTRL2, 0x1A);
530 /* powerdown dac, dac in tdm mode */ 415 /* powerdown dac, dac in tdm mode */
531 codec->write(codec, AD1938_DAC_CTRL0, 0x41); 416 snd_soc_write(codec, AD1938_DAC_CTRL0, 0x41);
532 /* high-pass filter enable */ 417 /* high-pass filter enable */
533 codec->write(codec, AD1938_ADC_CTRL0, 0x3); 418 snd_soc_write(codec, AD1938_ADC_CTRL0, 0x3);
534 /* sata delay=1, adc aux mode */ 419 /* sata delay=1, adc aux mode */
535 codec->write(codec, AD1938_ADC_CTRL1, 0x43); 420 snd_soc_write(codec, AD1938_ADC_CTRL1, 0x43);
536 /* pll input: mclki/xi */ 421 /* pll input: mclki/xi */
537 codec->write(codec, AD1938_PLL_CLK_CTRL0, 0x9D); 422 snd_soc_write(codec, AD1938_PLL_CLK_CTRL0, 0x9D);
538 codec->write(codec, AD1938_PLL_CLK_CTRL1, 0x04); 423 snd_soc_write(codec, AD1938_PLL_CLK_CTRL1, 0x04);
539
540 ad1938_fill_cache(codec);
541 424
542 ret = snd_soc_register_codec(codec); 425 ret = snd_soc_register_codec(codec);
543 if (ret != 0) { 426 if (ret != 0) {
@@ -559,7 +442,6 @@ static int ad1938_register(struct ad1938_priv *ad1938)
559 442
560static void ad1938_unregister(struct ad1938_priv *ad1938) 443static void ad1938_unregister(struct ad1938_priv *ad1938)
561{ 444{
562 ad1938_set_bias_level(&ad1938->codec, SND_SOC_BIAS_OFF);
563 snd_soc_unregister_dai(&ad1938_dai); 445 snd_soc_unregister_dai(&ad1938_dai);
564 snd_soc_unregister_codec(&ad1938->codec); 446 snd_soc_unregister_codec(&ad1938->codec);
565 kfree(ad1938); 447 kfree(ad1938);
@@ -592,21 +474,8 @@ static int ad1938_probe(struct platform_device *pdev)
592 snd_soc_dapm_new_controls(codec, ad1938_dapm_widgets, 474 snd_soc_dapm_new_controls(codec, ad1938_dapm_widgets,
593 ARRAY_SIZE(ad1938_dapm_widgets)); 475 ARRAY_SIZE(ad1938_dapm_widgets));
594 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); 476 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
595 snd_soc_dapm_new_widgets(codec);
596 477
597 ad1938_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
598 478
599 ret = snd_soc_init_card(socdev);
600 if (ret < 0) {
601 dev_err(codec->dev, "failed to register card: %d\n", ret);
602 goto card_err;
603 }
604
605 return ret;
606
607card_err:
608 snd_soc_free_pcms(socdev);
609 snd_soc_dapm_free(socdev);
610pcm_err: 479pcm_err:
611 return ret; 480 return ret;
612} 481}
@@ -622,37 +491,9 @@ static int ad1938_remove(struct platform_device *pdev)
622 return 0; 491 return 0;
623} 492}
624 493
625#ifdef CONFIG_PM
626static int ad1938_suspend(struct platform_device *pdev,
627 pm_message_t state)
628{
629 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
630 struct snd_soc_codec *codec = socdev->card->codec;
631
632 ad1938_set_bias_level(codec, SND_SOC_BIAS_OFF);
633 return 0;
634}
635
636static int ad1938_resume(struct platform_device *pdev)
637{
638 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
639 struct snd_soc_codec *codec = socdev->card->codec;
640
641 if (codec->suspend_bias_level == SND_SOC_BIAS_ON)
642 ad1938_set_bias_level(codec, SND_SOC_BIAS_ON);
643
644 return 0;
645}
646#else
647#define ad1938_suspend NULL
648#define ad1938_resume NULL
649#endif
650
651struct snd_soc_codec_device soc_codec_dev_ad1938 = { 494struct snd_soc_codec_device soc_codec_dev_ad1938 = {
652 .probe = ad1938_probe, 495 .probe = ad1938_probe,
653 .remove = ad1938_remove, 496 .remove = ad1938_remove,
654 .suspend = ad1938_suspend,
655 .resume = ad1938_resume,
656}; 497};
657EXPORT_SYMBOL_GPL(soc_codec_dev_ad1938); 498EXPORT_SYMBOL_GPL(soc_codec_dev_ad1938);
658 499
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
index d7440a982d22..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>
@@ -257,11 +258,6 @@ static int ad1980_soc_probe(struct platform_device *pdev)
257 258
258 snd_soc_add_controls(codec, ad1980_snd_ac97_controls, 259 snd_soc_add_controls(codec, ad1980_snd_ac97_controls,
259 ARRAY_SIZE(ad1980_snd_ac97_controls)); 260 ARRAY_SIZE(ad1980_snd_ac97_controls));
260 ret = snd_soc_init_card(socdev);
261 if (ret < 0) {
262 printk(KERN_ERR "ad1980: failed to register card\n");
263 goto reset_err;
264 }
265 261
266 return 0; 262 return 0;
267 263
diff --git a/sound/soc/codecs/ad73311.c b/sound/soc/codecs/ad73311.c
index e61dac5e7b8f..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>
@@ -64,16 +65,8 @@ static int ad73311_soc_probe(struct platform_device *pdev)
64 goto pcm_err; 65 goto pcm_err;
65 } 66 }
66 67
67 ret = snd_soc_init_card(socdev);
68 if (ret < 0) {
69 printk(KERN_ERR "ad73311: failed to register card\n");
70 goto register_err;
71 }
72
73 return ret; 68 return ret;
74 69
75register_err:
76 snd_soc_free_pcms(socdev);
77pcm_err: 70pcm_err:
78 kfree(socdev->card->codec); 71 kfree(socdev->card->codec);
79 socdev->card->codec = NULL; 72 socdev->card->codec = NULL;
diff --git a/sound/soc/codecs/ads117x.c b/sound/soc/codecs/ads117x.c
new file mode 100644
index 000000000000..f8e75edb27b7
--- /dev/null
+++ b/sound/soc/codecs/ads117x.c
@@ -0,0 +1,124 @@
1/*
2 * ads117x.c -- Driver for ads1174/8 ADC chips
3 *
4 * Copyright 2009 ShotSpotter Inc.
5 * Author: Graeme Gregory <gg@slimlogic.co.uk>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/kernel.h>
14#include <linux/slab.h>
15#include <linux/init.h>
16#include <linux/device.h>
17#include <sound/core.h>
18#include <sound/pcm.h>
19#include <sound/initval.h>
20#include <sound/soc.h>
21
22#include "ads117x.h"
23
24#define ADS117X_RATES (SNDRV_PCM_RATE_8000_48000)
25
26#define ADS117X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
27
28struct snd_soc_dai ads117x_dai = {
29/* ADC */
30 .name = "ADS117X ADC",
31 .id = 1,
32 .capture = {
33 .stream_name = "Capture",
34 .channels_min = 1,
35 .channels_max = 32,
36 .rates = ADS117X_RATES,
37 .formats = ADS117X_FORMATS,},
38};
39EXPORT_SYMBOL_GPL(ads117x_dai);
40
41static int ads117x_probe(struct platform_device *pdev)
42{
43 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
44 struct snd_soc_codec *codec;
45 int ret;
46
47 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
48 if (codec == NULL)
49 return -ENOMEM;
50
51 socdev->card->codec = codec;
52 mutex_init(&codec->mutex);
53 INIT_LIST_HEAD(&codec->dapm_widgets);
54 INIT_LIST_HEAD(&codec->dapm_paths);
55 codec->name = "ADS117X";
56 codec->owner = THIS_MODULE;
57 codec->dai = &ads117x_dai;
58 codec->num_dai = 1;
59
60 /* register pcms */
61 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
62 if (ret < 0) {
63 printk(KERN_ERR "ads117x: failed to create pcms\n");
64 kfree(codec);
65 return ret;
66 }
67
68 return 0;
69}
70
71static int ads117x_remove(struct platform_device *pdev)
72{
73 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
74 struct snd_soc_codec *codec = socdev->card->codec;
75
76 snd_soc_free_pcms(socdev);
77 kfree(codec);
78
79 return 0;
80}
81
82struct snd_soc_codec_device soc_codec_dev_ads117x = {
83 .probe = ads117x_probe,
84 .remove = ads117x_remove,
85};
86EXPORT_SYMBOL_GPL(soc_codec_dev_ads117x);
87
88static __devinit int ads117x_platform_probe(struct platform_device *pdev)
89{
90 ads117x_dai.dev = &pdev->dev;
91 return snd_soc_register_dai(&ads117x_dai);
92}
93
94static int __devexit ads117x_platform_remove(struct platform_device *pdev)
95{
96 snd_soc_unregister_dai(&ads117x_dai);
97 return 0;
98}
99
100static struct platform_driver ads117x_codec_driver = {
101 .driver = {
102 .name = "ads117x",
103 .owner = THIS_MODULE,
104 },
105
106 .probe = ads117x_platform_probe,
107 .remove = __devexit_p(ads117x_platform_remove),
108};
109
110static int __init ads117x_init(void)
111{
112 return platform_driver_register(&ads117x_codec_driver);
113}
114module_init(ads117x_init);
115
116static void __exit ads117x_exit(void)
117{
118 platform_driver_unregister(&ads117x_codec_driver);
119}
120module_exit(ads117x_exit);
121
122MODULE_DESCRIPTION("ASoC ads117x driver");
123MODULE_AUTHOR("Graeme Gregory");
124MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ads117x.h b/sound/soc/codecs/ads117x.h
new file mode 100644
index 000000000000..dbcf50ec9bd1
--- /dev/null
+++ b/sound/soc/codecs/ads117x.h
@@ -0,0 +1,13 @@
1/*
2 * ads117x.h -- Driver for ads1174/8 ADC chips
3 *
4 * Copyright 2009 ShotSpotter Inc.
5 * Author: Graeme Gregory <gg@slimlogic.co.uk>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12extern struct snd_soc_dai ads117x_dai;
13extern struct snd_soc_codec_device soc_codec_dev_ads117x;
diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c
index 4d47bc4f7428..bdeb10dfd887 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>
@@ -90,12 +91,10 @@ static int ak4104_spi_write(struct snd_soc_codec *codec, unsigned int reg,
90 if (reg >= codec->reg_cache_size) 91 if (reg >= codec->reg_cache_size)
91 return -EINVAL; 92 return -EINVAL;
92 93
93 reg &= AK4104_REG_MASK;
94 reg |= AK4104_WRITE;
95
96 /* only write to the hardware if value has changed */ 94 /* only write to the hardware if value has changed */
97 if (cache[reg] != value) { 95 if (cache[reg] != value) {
98 u8 tmp[2] = { reg, value }; 96 u8 tmp[2] = { (reg & AK4104_REG_MASK) | AK4104_WRITE, value };
97
99 if (spi_write(spi, tmp, sizeof(tmp))) { 98 if (spi_write(spi, tmp, sizeof(tmp))) {
100 dev_err(&spi->dev, "SPI write failed\n"); 99 dev_err(&spi->dev, "SPI write failed\n");
101 return -EIO; 100 return -EIO;
@@ -185,9 +184,7 @@ struct snd_soc_dai ak4104_dai = {
185 .stream_name = "Playback", 184 .stream_name = "Playback",
186 .channels_min = 2, 185 .channels_min = 2,
187 .channels_max = 2, 186 .channels_max = 2,
188 .rates = SNDRV_PCM_RATE_44100 | 187 .rates = SNDRV_PCM_RATE_8000_192000,
189 SNDRV_PCM_RATE_48000 |
190 SNDRV_PCM_RATE_32000,
191 .formats = SNDRV_PCM_FMTBIT_S16_LE | 188 .formats = SNDRV_PCM_FMTBIT_S16_LE |
192 SNDRV_PCM_FMTBIT_S24_3LE | 189 SNDRV_PCM_FMTBIT_S24_3LE |
193 SNDRV_PCM_FMTBIT_S24_LE 190 SNDRV_PCM_FMTBIT_S24_LE
@@ -313,14 +310,6 @@ static int ak4104_probe(struct platform_device *pdev)
313 return ret; 310 return ret;
314 } 311 }
315 312
316 /* Register the socdev */
317 ret = snd_soc_init_card(socdev);
318 if (ret < 0) {
319 dev_err(codec->dev, "failed to register card\n");
320 snd_soc_free_pcms(socdev);
321 return ret;
322 }
323
324 return 0; 313 return 0;
325} 314}
326 315
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c
index 0abec0d29a96..352d1d08dbd9 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>
@@ -294,7 +295,6 @@ static int ak4535_add_widgets(struct snd_soc_codec *codec)
294 295
295 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 296 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
296 297
297 snd_soc_dapm_new_widgets(codec);
298 return 0; 298 return 0;
299} 299}
300 300
@@ -485,17 +485,9 @@ static int ak4535_init(struct snd_soc_device *socdev)
485 snd_soc_add_controls(codec, ak4535_snd_controls, 485 snd_soc_add_controls(codec, ak4535_snd_controls,
486 ARRAY_SIZE(ak4535_snd_controls)); 486 ARRAY_SIZE(ak4535_snd_controls));
487 ak4535_add_widgets(codec); 487 ak4535_add_widgets(codec);
488 ret = snd_soc_init_card(socdev);
489 if (ret < 0) {
490 printk(KERN_ERR "ak4535: failed to register card\n");
491 goto card_err;
492 }
493 488
494 return ret; 489 return ret;
495 490
496card_err:
497 snd_soc_free_pcms(socdev);
498 snd_soc_dapm_free(socdev);
499pcm_err: 491pcm_err:
500 kfree(codec->reg_cache); 492 kfree(codec->reg_cache);
501 493
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
index e057c7b578df..729859cf6ca8 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>
@@ -442,18 +443,9 @@ static int ak4642_probe(struct platform_device *pdev)
442 goto pcm_err; 443 goto pcm_err;
443 } 444 }
444 445
445 ret = snd_soc_init_card(socdev);
446 if (ret < 0) {
447 printk(KERN_ERR "ak4642: failed to register card\n");
448 goto card_err;
449 }
450
451 dev_info(&pdev->dev, "AK4642 Audio Codec %s", AK4642_VERSION); 446 dev_info(&pdev->dev, "AK4642 Audio Codec %s", AK4642_VERSION);
452 return ret; 447 return ret;
453 448
454card_err:
455 snd_soc_free_pcms(socdev);
456 snd_soc_dapm_free(socdev);
457pcm_err: 449pcm_err:
458 return ret; 450 return ret;
459 451
@@ -479,7 +471,7 @@ EXPORT_SYMBOL_GPL(soc_codec_dev_ak4642);
479 471
480static int __init ak4642_modinit(void) 472static int __init ak4642_modinit(void)
481{ 473{
482 int ret; 474 int ret = 0;
483#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 475#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
484 ret = i2c_add_driver(&ak4642_i2c_driver); 476 ret = i2c_add_driver(&ak4642_i2c_driver);
485#endif 477#endif
diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c
new file mode 100644
index 000000000000..926797a014c7
--- /dev/null
+++ b/sound/soc/codecs/ak4671.c
@@ -0,0 +1,816 @@
1/*
2 * ak4671.c -- audio driver for AK4671
3 *
4 * Copyright (C) 2009 Samsung Electronics Co.Ltd
5 * Author: Joonyoung Shim <jy0922.shim@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 */
13
14#include <linux/module.h>
15#include <linux/init.h>
16#include <linux/i2c.h>
17#include <linux/delay.h>
18#include <linux/slab.h>
19#include <sound/soc.h>
20#include <sound/soc-dapm.h>
21#include <sound/initval.h>
22#include <sound/tlv.h>
23
24#include "ak4671.h"
25
26static struct snd_soc_codec *ak4671_codec;
27
28/* codec private data */
29struct ak4671_priv {
30 struct snd_soc_codec codec;
31 u8 reg_cache[AK4671_CACHEREGNUM];
32};
33
34/* ak4671 register cache & default register settings */
35static const u8 ak4671_reg[AK4671_CACHEREGNUM] = {
36 0x00, /* AK4671_AD_DA_POWER_MANAGEMENT (0x00) */
37 0xf6, /* AK4671_PLL_MODE_SELECT0 (0x01) */
38 0x00, /* AK4671_PLL_MODE_SELECT1 (0x02) */
39 0x02, /* AK4671_FORMAT_SELECT (0x03) */
40 0x00, /* AK4671_MIC_SIGNAL_SELECT (0x04) */
41 0x55, /* AK4671_MIC_AMP_GAIN (0x05) */
42 0x00, /* AK4671_MIXING_POWER_MANAGEMENT0 (0x06) */
43 0x00, /* AK4671_MIXING_POWER_MANAGEMENT1 (0x07) */
44 0xb5, /* AK4671_OUTPUT_VOLUME_CONTROL (0x08) */
45 0x00, /* AK4671_LOUT1_SIGNAL_SELECT (0x09) */
46 0x00, /* AK4671_ROUT1_SIGNAL_SELECT (0x0a) */
47 0x00, /* AK4671_LOUT2_SIGNAL_SELECT (0x0b) */
48 0x00, /* AK4671_ROUT2_SIGNAL_SELECT (0x0c) */
49 0x00, /* AK4671_LOUT3_SIGNAL_SELECT (0x0d) */
50 0x00, /* AK4671_ROUT3_SIGNAL_SELECT (0x0e) */
51 0x00, /* AK4671_LOUT1_POWER_MANAGERMENT (0x0f) */
52 0x00, /* AK4671_LOUT2_POWER_MANAGERMENT (0x10) */
53 0x80, /* AK4671_LOUT3_POWER_MANAGERMENT (0x11) */
54 0x91, /* AK4671_LCH_INPUT_VOLUME_CONTROL (0x12) */
55 0x91, /* AK4671_RCH_INPUT_VOLUME_CONTROL (0x13) */
56 0xe1, /* AK4671_ALC_REFERENCE_SELECT (0x14) */
57 0x00, /* AK4671_DIGITAL_MIXING_CONTROL (0x15) */
58 0x00, /* AK4671_ALC_TIMER_SELECT (0x16) */
59 0x00, /* AK4671_ALC_MODE_CONTROL (0x17) */
60 0x02, /* AK4671_MODE_CONTROL1 (0x18) */
61 0x01, /* AK4671_MODE_CONTROL2 (0x19) */
62 0x18, /* AK4671_LCH_OUTPUT_VOLUME_CONTROL (0x1a) */
63 0x18, /* AK4671_RCH_OUTPUT_VOLUME_CONTROL (0x1b) */
64 0x00, /* AK4671_SIDETONE_A_CONTROL (0x1c) */
65 0x02, /* AK4671_DIGITAL_FILTER_SELECT (0x1d) */
66 0x00, /* AK4671_FIL3_COEFFICIENT0 (0x1e) */
67 0x00, /* AK4671_FIL3_COEFFICIENT1 (0x1f) */
68 0x00, /* AK4671_FIL3_COEFFICIENT2 (0x20) */
69 0x00, /* AK4671_FIL3_COEFFICIENT3 (0x21) */
70 0x00, /* AK4671_EQ_COEFFICIENT0 (0x22) */
71 0x00, /* AK4671_EQ_COEFFICIENT1 (0x23) */
72 0x00, /* AK4671_EQ_COEFFICIENT2 (0x24) */
73 0x00, /* AK4671_EQ_COEFFICIENT3 (0x25) */
74 0x00, /* AK4671_EQ_COEFFICIENT4 (0x26) */
75 0x00, /* AK4671_EQ_COEFFICIENT5 (0x27) */
76 0xa9, /* AK4671_FIL1_COEFFICIENT0 (0x28) */
77 0x1f, /* AK4671_FIL1_COEFFICIENT1 (0x29) */
78 0xad, /* AK4671_FIL1_COEFFICIENT2 (0x2a) */
79 0x20, /* AK4671_FIL1_COEFFICIENT3 (0x2b) */
80 0x00, /* AK4671_FIL2_COEFFICIENT0 (0x2c) */
81 0x00, /* AK4671_FIL2_COEFFICIENT1 (0x2d) */
82 0x00, /* AK4671_FIL2_COEFFICIENT2 (0x2e) */
83 0x00, /* AK4671_FIL2_COEFFICIENT3 (0x2f) */
84 0x00, /* AK4671_DIGITAL_FILTER_SELECT2 (0x30) */
85 0x00, /* this register not used */
86 0x00, /* AK4671_E1_COEFFICIENT0 (0x32) */
87 0x00, /* AK4671_E1_COEFFICIENT1 (0x33) */
88 0x00, /* AK4671_E1_COEFFICIENT2 (0x34) */
89 0x00, /* AK4671_E1_COEFFICIENT3 (0x35) */
90 0x00, /* AK4671_E1_COEFFICIENT4 (0x36) */
91 0x00, /* AK4671_E1_COEFFICIENT5 (0x37) */
92 0x00, /* AK4671_E2_COEFFICIENT0 (0x38) */
93 0x00, /* AK4671_E2_COEFFICIENT1 (0x39) */
94 0x00, /* AK4671_E2_COEFFICIENT2 (0x3a) */
95 0x00, /* AK4671_E2_COEFFICIENT3 (0x3b) */
96 0x00, /* AK4671_E2_COEFFICIENT4 (0x3c) */
97 0x00, /* AK4671_E2_COEFFICIENT5 (0x3d) */
98 0x00, /* AK4671_E3_COEFFICIENT0 (0x3e) */
99 0x00, /* AK4671_E3_COEFFICIENT1 (0x3f) */
100 0x00, /* AK4671_E3_COEFFICIENT2 (0x40) */
101 0x00, /* AK4671_E3_COEFFICIENT3 (0x41) */
102 0x00, /* AK4671_E3_COEFFICIENT4 (0x42) */
103 0x00, /* AK4671_E3_COEFFICIENT5 (0x43) */
104 0x00, /* AK4671_E4_COEFFICIENT0 (0x44) */
105 0x00, /* AK4671_E4_COEFFICIENT1 (0x45) */
106 0x00, /* AK4671_E4_COEFFICIENT2 (0x46) */
107 0x00, /* AK4671_E4_COEFFICIENT3 (0x47) */
108 0x00, /* AK4671_E4_COEFFICIENT4 (0x48) */
109 0x00, /* AK4671_E4_COEFFICIENT5 (0x49) */
110 0x00, /* AK4671_E5_COEFFICIENT0 (0x4a) */
111 0x00, /* AK4671_E5_COEFFICIENT1 (0x4b) */
112 0x00, /* AK4671_E5_COEFFICIENT2 (0x4c) */
113 0x00, /* AK4671_E5_COEFFICIENT3 (0x4d) */
114 0x00, /* AK4671_E5_COEFFICIENT4 (0x4e) */
115 0x00, /* AK4671_E5_COEFFICIENT5 (0x4f) */
116 0x88, /* AK4671_EQ_CONTROL_250HZ_100HZ (0x50) */
117 0x88, /* AK4671_EQ_CONTROL_3500HZ_1KHZ (0x51) */
118 0x08, /* AK4671_EQ_CONTRO_10KHZ (0x52) */
119 0x00, /* AK4671_PCM_IF_CONTROL0 (0x53) */
120 0x00, /* AK4671_PCM_IF_CONTROL1 (0x54) */
121 0x00, /* AK4671_PCM_IF_CONTROL2 (0x55) */
122 0x18, /* AK4671_DIGITAL_VOLUME_B_CONTROL (0x56) */
123 0x18, /* AK4671_DIGITAL_VOLUME_C_CONTROL (0x57) */
124 0x00, /* AK4671_SIDETONE_VOLUME_CONTROL (0x58) */
125 0x00, /* AK4671_DIGITAL_MIXING_CONTROL2 (0x59) */
126 0x00, /* AK4671_SAR_ADC_CONTROL (0x5a) */
127};
128
129/*
130 * LOUT1/ROUT1 output volume control:
131 * from -24 to 6 dB in 6 dB steps (mute instead of -30 dB)
132 */
133static DECLARE_TLV_DB_SCALE(out1_tlv, -3000, 600, 1);
134
135/*
136 * LOUT2/ROUT2 output volume control:
137 * from -33 to 6 dB in 3 dB steps (mute instead of -33 dB)
138 */
139static DECLARE_TLV_DB_SCALE(out2_tlv, -3300, 300, 1);
140
141/*
142 * LOUT3/ROUT3 output volume control:
143 * from -6 to 3 dB in 3 dB steps
144 */
145static DECLARE_TLV_DB_SCALE(out3_tlv, -600, 300, 0);
146
147/*
148 * Mic amp gain control:
149 * from -15 to 30 dB in 3 dB steps
150 * REVISIT: The actual min value(0x01) is -12 dB and the reg value 0x00 is not
151 * available
152 */
153static DECLARE_TLV_DB_SCALE(mic_amp_tlv, -1500, 300, 0);
154
155static const struct snd_kcontrol_new ak4671_snd_controls[] = {
156 /* Common playback gain controls */
157 SOC_SINGLE_TLV("Line Output1 Playback Volume",
158 AK4671_OUTPUT_VOLUME_CONTROL, 0, 0x6, 0, out1_tlv),
159 SOC_SINGLE_TLV("Headphone Output2 Playback Volume",
160 AK4671_OUTPUT_VOLUME_CONTROL, 4, 0xd, 0, out2_tlv),
161 SOC_SINGLE_TLV("Line Output3 Playback Volume",
162 AK4671_LOUT3_POWER_MANAGERMENT, 6, 0x3, 0, out3_tlv),
163
164 /* Common capture gain controls */
165 SOC_DOUBLE_TLV("Mic Amp Capture Volume",
166 AK4671_MIC_AMP_GAIN, 0, 4, 0xf, 0, mic_amp_tlv),
167};
168
169/* event handlers */
170static int ak4671_out2_event(struct snd_soc_dapm_widget *w,
171 struct snd_kcontrol *kcontrol, int event)
172{
173 struct snd_soc_codec *codec = w->codec;
174 u8 reg;
175
176 switch (event) {
177 case SND_SOC_DAPM_POST_PMU:
178 reg = snd_soc_read(codec, AK4671_LOUT2_POWER_MANAGERMENT);
179 reg |= AK4671_MUTEN;
180 snd_soc_write(codec, AK4671_LOUT2_POWER_MANAGERMENT, reg);
181 break;
182 case SND_SOC_DAPM_PRE_PMD:
183 reg = snd_soc_read(codec, AK4671_LOUT2_POWER_MANAGERMENT);
184 reg &= ~AK4671_MUTEN;
185 snd_soc_write(codec, AK4671_LOUT2_POWER_MANAGERMENT, reg);
186 break;
187 }
188
189 return 0;
190}
191
192/* Output Mixers */
193static const struct snd_kcontrol_new ak4671_lout1_mixer_controls[] = {
194 SOC_DAPM_SINGLE("DACL", AK4671_LOUT1_SIGNAL_SELECT, 0, 1, 0),
195 SOC_DAPM_SINGLE("LINL1", AK4671_LOUT1_SIGNAL_SELECT, 1, 1, 0),
196 SOC_DAPM_SINGLE("LINL2", AK4671_LOUT1_SIGNAL_SELECT, 2, 1, 0),
197 SOC_DAPM_SINGLE("LINL3", AK4671_LOUT1_SIGNAL_SELECT, 3, 1, 0),
198 SOC_DAPM_SINGLE("LINL4", AK4671_LOUT1_SIGNAL_SELECT, 4, 1, 0),
199 SOC_DAPM_SINGLE("LOOPL", AK4671_LOUT1_SIGNAL_SELECT, 5, 1, 0),
200};
201
202static const struct snd_kcontrol_new ak4671_rout1_mixer_controls[] = {
203 SOC_DAPM_SINGLE("DACR", AK4671_ROUT1_SIGNAL_SELECT, 0, 1, 0),
204 SOC_DAPM_SINGLE("RINR1", AK4671_ROUT1_SIGNAL_SELECT, 1, 1, 0),
205 SOC_DAPM_SINGLE("RINR2", AK4671_ROUT1_SIGNAL_SELECT, 2, 1, 0),
206 SOC_DAPM_SINGLE("RINR3", AK4671_ROUT1_SIGNAL_SELECT, 3, 1, 0),
207 SOC_DAPM_SINGLE("RINR4", AK4671_ROUT1_SIGNAL_SELECT, 4, 1, 0),
208 SOC_DAPM_SINGLE("LOOPR", AK4671_ROUT1_SIGNAL_SELECT, 5, 1, 0),
209};
210
211static const struct snd_kcontrol_new ak4671_lout2_mixer_controls[] = {
212 SOC_DAPM_SINGLE("DACHL", AK4671_LOUT2_SIGNAL_SELECT, 0, 1, 0),
213 SOC_DAPM_SINGLE("LINH1", AK4671_LOUT2_SIGNAL_SELECT, 1, 1, 0),
214 SOC_DAPM_SINGLE("LINH2", AK4671_LOUT2_SIGNAL_SELECT, 2, 1, 0),
215 SOC_DAPM_SINGLE("LINH3", AK4671_LOUT2_SIGNAL_SELECT, 3, 1, 0),
216 SOC_DAPM_SINGLE("LINH4", AK4671_LOUT2_SIGNAL_SELECT, 4, 1, 0),
217 SOC_DAPM_SINGLE("LOOPHL", AK4671_LOUT2_SIGNAL_SELECT, 5, 1, 0),
218};
219
220static const struct snd_kcontrol_new ak4671_rout2_mixer_controls[] = {
221 SOC_DAPM_SINGLE("DACHR", AK4671_ROUT2_SIGNAL_SELECT, 0, 1, 0),
222 SOC_DAPM_SINGLE("RINH1", AK4671_ROUT2_SIGNAL_SELECT, 1, 1, 0),
223 SOC_DAPM_SINGLE("RINH2", AK4671_ROUT2_SIGNAL_SELECT, 2, 1, 0),
224 SOC_DAPM_SINGLE("RINH3", AK4671_ROUT2_SIGNAL_SELECT, 3, 1, 0),
225 SOC_DAPM_SINGLE("RINH4", AK4671_ROUT2_SIGNAL_SELECT, 4, 1, 0),
226 SOC_DAPM_SINGLE("LOOPHR", AK4671_ROUT2_SIGNAL_SELECT, 5, 1, 0),
227};
228
229static const struct snd_kcontrol_new ak4671_lout3_mixer_controls[] = {
230 SOC_DAPM_SINGLE("DACSL", AK4671_LOUT3_SIGNAL_SELECT, 0, 1, 0),
231 SOC_DAPM_SINGLE("LINS1", AK4671_LOUT3_SIGNAL_SELECT, 1, 1, 0),
232 SOC_DAPM_SINGLE("LINS2", AK4671_LOUT3_SIGNAL_SELECT, 2, 1, 0),
233 SOC_DAPM_SINGLE("LINS3", AK4671_LOUT3_SIGNAL_SELECT, 3, 1, 0),
234 SOC_DAPM_SINGLE("LINS4", AK4671_LOUT3_SIGNAL_SELECT, 4, 1, 0),
235 SOC_DAPM_SINGLE("LOOPSL", AK4671_LOUT3_SIGNAL_SELECT, 5, 1, 0),
236};
237
238static const struct snd_kcontrol_new ak4671_rout3_mixer_controls[] = {
239 SOC_DAPM_SINGLE("DACSR", AK4671_ROUT3_SIGNAL_SELECT, 0, 1, 0),
240 SOC_DAPM_SINGLE("RINS1", AK4671_ROUT3_SIGNAL_SELECT, 1, 1, 0),
241 SOC_DAPM_SINGLE("RINS2", AK4671_ROUT3_SIGNAL_SELECT, 2, 1, 0),
242 SOC_DAPM_SINGLE("RINS3", AK4671_ROUT3_SIGNAL_SELECT, 3, 1, 0),
243 SOC_DAPM_SINGLE("RINS4", AK4671_ROUT3_SIGNAL_SELECT, 4, 1, 0),
244 SOC_DAPM_SINGLE("LOOPSR", AK4671_ROUT3_SIGNAL_SELECT, 5, 1, 0),
245};
246
247/* Input MUXs */
248static const char *ak4671_lin_mux_texts[] =
249 {"LIN1", "LIN2", "LIN3", "LIN4"};
250static const struct soc_enum ak4671_lin_mux_enum =
251 SOC_ENUM_SINGLE(AK4671_MIC_SIGNAL_SELECT, 0,
252 ARRAY_SIZE(ak4671_lin_mux_texts),
253 ak4671_lin_mux_texts);
254static const struct snd_kcontrol_new ak4671_lin_mux_control =
255 SOC_DAPM_ENUM("Route", ak4671_lin_mux_enum);
256
257static const char *ak4671_rin_mux_texts[] =
258 {"RIN1", "RIN2", "RIN3", "RIN4"};
259static const struct soc_enum ak4671_rin_mux_enum =
260 SOC_ENUM_SINGLE(AK4671_MIC_SIGNAL_SELECT, 2,
261 ARRAY_SIZE(ak4671_rin_mux_texts),
262 ak4671_rin_mux_texts);
263static const struct snd_kcontrol_new ak4671_rin_mux_control =
264 SOC_DAPM_ENUM("Route", ak4671_rin_mux_enum);
265
266static const struct snd_soc_dapm_widget ak4671_dapm_widgets[] = {
267 /* Inputs */
268 SND_SOC_DAPM_INPUT("LIN1"),
269 SND_SOC_DAPM_INPUT("RIN1"),
270 SND_SOC_DAPM_INPUT("LIN2"),
271 SND_SOC_DAPM_INPUT("RIN2"),
272 SND_SOC_DAPM_INPUT("LIN3"),
273 SND_SOC_DAPM_INPUT("RIN3"),
274 SND_SOC_DAPM_INPUT("LIN4"),
275 SND_SOC_DAPM_INPUT("RIN4"),
276
277 /* Outputs */
278 SND_SOC_DAPM_OUTPUT("LOUT1"),
279 SND_SOC_DAPM_OUTPUT("ROUT1"),
280 SND_SOC_DAPM_OUTPUT("LOUT2"),
281 SND_SOC_DAPM_OUTPUT("ROUT2"),
282 SND_SOC_DAPM_OUTPUT("LOUT3"),
283 SND_SOC_DAPM_OUTPUT("ROUT3"),
284
285 /* DAC */
286 SND_SOC_DAPM_DAC("DAC Left", "Left HiFi Playback",
287 AK4671_AD_DA_POWER_MANAGEMENT, 6, 0),
288 SND_SOC_DAPM_DAC("DAC Right", "Right HiFi Playback",
289 AK4671_AD_DA_POWER_MANAGEMENT, 7, 0),
290
291 /* ADC */
292 SND_SOC_DAPM_ADC("ADC Left", "Left HiFi Capture",
293 AK4671_AD_DA_POWER_MANAGEMENT, 4, 0),
294 SND_SOC_DAPM_ADC("ADC Right", "Right HiFi Capture",
295 AK4671_AD_DA_POWER_MANAGEMENT, 5, 0),
296
297 /* PGA */
298 SND_SOC_DAPM_PGA("LOUT2 Mix Amp",
299 AK4671_LOUT2_POWER_MANAGERMENT, 5, 0, NULL, 0),
300 SND_SOC_DAPM_PGA("ROUT2 Mix Amp",
301 AK4671_LOUT2_POWER_MANAGERMENT, 6, 0, NULL, 0),
302
303 SND_SOC_DAPM_PGA("LIN1 Mixing Circuit",
304 AK4671_MIXING_POWER_MANAGEMENT1, 0, 0, NULL, 0),
305 SND_SOC_DAPM_PGA("RIN1 Mixing Circuit",
306 AK4671_MIXING_POWER_MANAGEMENT1, 1, 0, NULL, 0),
307 SND_SOC_DAPM_PGA("LIN2 Mixing Circuit",
308 AK4671_MIXING_POWER_MANAGEMENT1, 2, 0, NULL, 0),
309 SND_SOC_DAPM_PGA("RIN2 Mixing Circuit",
310 AK4671_MIXING_POWER_MANAGEMENT1, 3, 0, NULL, 0),
311 SND_SOC_DAPM_PGA("LIN3 Mixing Circuit",
312 AK4671_MIXING_POWER_MANAGEMENT1, 4, 0, NULL, 0),
313 SND_SOC_DAPM_PGA("RIN3 Mixing Circuit",
314 AK4671_MIXING_POWER_MANAGEMENT1, 5, 0, NULL, 0),
315 SND_SOC_DAPM_PGA("LIN4 Mixing Circuit",
316 AK4671_MIXING_POWER_MANAGEMENT1, 6, 0, NULL, 0),
317 SND_SOC_DAPM_PGA("RIN4 Mixing Circuit",
318 AK4671_MIXING_POWER_MANAGEMENT1, 7, 0, NULL, 0),
319
320 /* Output Mixers */
321 SND_SOC_DAPM_MIXER("LOUT1 Mixer", AK4671_LOUT1_POWER_MANAGERMENT, 0, 0,
322 &ak4671_lout1_mixer_controls[0],
323 ARRAY_SIZE(ak4671_lout1_mixer_controls)),
324 SND_SOC_DAPM_MIXER("ROUT1 Mixer", AK4671_LOUT1_POWER_MANAGERMENT, 1, 0,
325 &ak4671_rout1_mixer_controls[0],
326 ARRAY_SIZE(ak4671_rout1_mixer_controls)),
327 SND_SOC_DAPM_MIXER_E("LOUT2 Mixer", AK4671_LOUT2_POWER_MANAGERMENT,
328 0, 0, &ak4671_lout2_mixer_controls[0],
329 ARRAY_SIZE(ak4671_lout2_mixer_controls),
330 ak4671_out2_event,
331 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_PRE_PMD),
332 SND_SOC_DAPM_MIXER_E("ROUT2 Mixer", AK4671_LOUT2_POWER_MANAGERMENT,
333 1, 0, &ak4671_rout2_mixer_controls[0],
334 ARRAY_SIZE(ak4671_rout2_mixer_controls),
335 ak4671_out2_event,
336 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_PRE_PMD),
337 SND_SOC_DAPM_MIXER("LOUT3 Mixer", AK4671_LOUT3_POWER_MANAGERMENT, 0, 0,
338 &ak4671_lout3_mixer_controls[0],
339 ARRAY_SIZE(ak4671_lout3_mixer_controls)),
340 SND_SOC_DAPM_MIXER("ROUT3 Mixer", AK4671_LOUT3_POWER_MANAGERMENT, 1, 0,
341 &ak4671_rout3_mixer_controls[0],
342 ARRAY_SIZE(ak4671_rout3_mixer_controls)),
343
344 /* Input MUXs */
345 SND_SOC_DAPM_MUX("LIN MUX", AK4671_AD_DA_POWER_MANAGEMENT, 2, 0,
346 &ak4671_lin_mux_control),
347 SND_SOC_DAPM_MUX("RIN MUX", AK4671_AD_DA_POWER_MANAGEMENT, 3, 0,
348 &ak4671_rin_mux_control),
349
350 /* Mic Power */
351 SND_SOC_DAPM_MICBIAS("Mic Bias", AK4671_AD_DA_POWER_MANAGEMENT, 1, 0),
352
353 /* Supply */
354 SND_SOC_DAPM_SUPPLY("PMPLL", AK4671_PLL_MODE_SELECT1, 0, 0, NULL, 0),
355};
356
357static const struct snd_soc_dapm_route intercon[] = {
358 {"DAC Left", "NULL", "PMPLL"},
359 {"DAC Right", "NULL", "PMPLL"},
360 {"ADC Left", "NULL", "PMPLL"},
361 {"ADC Right", "NULL", "PMPLL"},
362
363 /* Outputs */
364 {"LOUT1", "NULL", "LOUT1 Mixer"},
365 {"ROUT1", "NULL", "ROUT1 Mixer"},
366 {"LOUT2", "NULL", "LOUT2 Mix Amp"},
367 {"ROUT2", "NULL", "ROUT2 Mix Amp"},
368 {"LOUT3", "NULL", "LOUT3 Mixer"},
369 {"ROUT3", "NULL", "ROUT3 Mixer"},
370
371 {"LOUT1 Mixer", "DACL", "DAC Left"},
372 {"ROUT1 Mixer", "DACR", "DAC Right"},
373 {"LOUT2 Mixer", "DACHL", "DAC Left"},
374 {"ROUT2 Mixer", "DACHR", "DAC Right"},
375 {"LOUT2 Mix Amp", "NULL", "LOUT2 Mixer"},
376 {"ROUT2 Mix Amp", "NULL", "ROUT2 Mixer"},
377 {"LOUT3 Mixer", "DACSL", "DAC Left"},
378 {"ROUT3 Mixer", "DACSR", "DAC Right"},
379
380 /* Inputs */
381 {"LIN MUX", "LIN1", "LIN1"},
382 {"LIN MUX", "LIN2", "LIN2"},
383 {"LIN MUX", "LIN3", "LIN3"},
384 {"LIN MUX", "LIN4", "LIN4"},
385
386 {"RIN MUX", "RIN1", "RIN1"},
387 {"RIN MUX", "RIN2", "RIN2"},
388 {"RIN MUX", "RIN3", "RIN3"},
389 {"RIN MUX", "RIN4", "RIN4"},
390
391 {"LIN1", NULL, "Mic Bias"},
392 {"RIN1", NULL, "Mic Bias"},
393 {"LIN2", NULL, "Mic Bias"},
394 {"RIN2", NULL, "Mic Bias"},
395
396 {"ADC Left", "NULL", "LIN MUX"},
397 {"ADC Right", "NULL", "RIN MUX"},
398
399 /* Analog Loops */
400 {"LIN1 Mixing Circuit", "NULL", "LIN1"},
401 {"RIN1 Mixing Circuit", "NULL", "RIN1"},
402 {"LIN2 Mixing Circuit", "NULL", "LIN2"},
403 {"RIN2 Mixing Circuit", "NULL", "RIN2"},
404 {"LIN3 Mixing Circuit", "NULL", "LIN3"},
405 {"RIN3 Mixing Circuit", "NULL", "RIN3"},
406 {"LIN4 Mixing Circuit", "NULL", "LIN4"},
407 {"RIN4 Mixing Circuit", "NULL", "RIN4"},
408
409 {"LOUT1 Mixer", "LINL1", "LIN1 Mixing Circuit"},
410 {"ROUT1 Mixer", "RINR1", "RIN1 Mixing Circuit"},
411 {"LOUT2 Mixer", "LINH1", "LIN1 Mixing Circuit"},
412 {"ROUT2 Mixer", "RINH1", "RIN1 Mixing Circuit"},
413 {"LOUT3 Mixer", "LINS1", "LIN1 Mixing Circuit"},
414 {"ROUT3 Mixer", "RINS1", "RIN1 Mixing Circuit"},
415
416 {"LOUT1 Mixer", "LINL2", "LIN2 Mixing Circuit"},
417 {"ROUT1 Mixer", "RINR2", "RIN2 Mixing Circuit"},
418 {"LOUT2 Mixer", "LINH2", "LIN2 Mixing Circuit"},
419 {"ROUT2 Mixer", "RINH2", "RIN2 Mixing Circuit"},
420 {"LOUT3 Mixer", "LINS2", "LIN2 Mixing Circuit"},
421 {"ROUT3 Mixer", "RINS2", "RIN2 Mixing Circuit"},
422
423 {"LOUT1 Mixer", "LINL3", "LIN3 Mixing Circuit"},
424 {"ROUT1 Mixer", "RINR3", "RIN3 Mixing Circuit"},
425 {"LOUT2 Mixer", "LINH3", "LIN3 Mixing Circuit"},
426 {"ROUT2 Mixer", "RINH3", "RIN3 Mixing Circuit"},
427 {"LOUT3 Mixer", "LINS3", "LIN3 Mixing Circuit"},
428 {"ROUT3 Mixer", "RINS3", "RIN3 Mixing Circuit"},
429
430 {"LOUT1 Mixer", "LINL4", "LIN4 Mixing Circuit"},
431 {"ROUT1 Mixer", "RINR4", "RIN4 Mixing Circuit"},
432 {"LOUT2 Mixer", "LINH4", "LIN4 Mixing Circuit"},
433 {"ROUT2 Mixer", "RINH4", "RIN4 Mixing Circuit"},
434 {"LOUT3 Mixer", "LINS4", "LIN4 Mixing Circuit"},
435 {"ROUT3 Mixer", "RINS4", "RIN4 Mixing Circuit"},
436};
437
438static int ak4671_add_widgets(struct snd_soc_codec *codec)
439{
440 snd_soc_dapm_new_controls(codec, ak4671_dapm_widgets,
441 ARRAY_SIZE(ak4671_dapm_widgets));
442
443 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
444
445 return 0;
446}
447
448static int ak4671_hw_params(struct snd_pcm_substream *substream,
449 struct snd_pcm_hw_params *params,
450 struct snd_soc_dai *dai)
451{
452 struct snd_soc_codec *codec = dai->codec;
453 u8 fs;
454
455 fs = snd_soc_read(codec, AK4671_PLL_MODE_SELECT0);
456 fs &= ~AK4671_FS;
457
458 switch (params_rate(params)) {
459 case 8000:
460 fs |= AK4671_FS_8KHZ;
461 break;
462 case 12000:
463 fs |= AK4671_FS_12KHZ;
464 break;
465 case 16000:
466 fs |= AK4671_FS_16KHZ;
467 break;
468 case 24000:
469 fs |= AK4671_FS_24KHZ;
470 break;
471 case 11025:
472 fs |= AK4671_FS_11_025KHZ;
473 break;
474 case 22050:
475 fs |= AK4671_FS_22_05KHZ;
476 break;
477 case 32000:
478 fs |= AK4671_FS_32KHZ;
479 break;
480 case 44100:
481 fs |= AK4671_FS_44_1KHZ;
482 break;
483 case 48000:
484 fs |= AK4671_FS_48KHZ;
485 break;
486 default:
487 return -EINVAL;
488 }
489
490 snd_soc_write(codec, AK4671_PLL_MODE_SELECT0, fs);
491
492 return 0;
493}
494
495static int ak4671_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
496 unsigned int freq, int dir)
497{
498 struct snd_soc_codec *codec = dai->codec;
499 u8 pll;
500
501 pll = snd_soc_read(codec, AK4671_PLL_MODE_SELECT0);
502 pll &= ~AK4671_PLL;
503
504 switch (freq) {
505 case 11289600:
506 pll |= AK4671_PLL_11_2896MHZ;
507 break;
508 case 12000000:
509 pll |= AK4671_PLL_12MHZ;
510 break;
511 case 12288000:
512 pll |= AK4671_PLL_12_288MHZ;
513 break;
514 case 13000000:
515 pll |= AK4671_PLL_13MHZ;
516 break;
517 case 13500000:
518 pll |= AK4671_PLL_13_5MHZ;
519 break;
520 case 19200000:
521 pll |= AK4671_PLL_19_2MHZ;
522 break;
523 case 24000000:
524 pll |= AK4671_PLL_24MHZ;
525 break;
526 case 26000000:
527 pll |= AK4671_PLL_26MHZ;
528 break;
529 case 27000000:
530 pll |= AK4671_PLL_27MHZ;
531 break;
532 default:
533 return -EINVAL;
534 }
535
536 snd_soc_write(codec, AK4671_PLL_MODE_SELECT0, pll);
537
538 return 0;
539}
540
541static int ak4671_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
542{
543 struct snd_soc_codec *codec = dai->codec;
544 u8 mode;
545 u8 format;
546
547 /* set master/slave audio interface */
548 mode = snd_soc_read(codec, AK4671_PLL_MODE_SELECT1);
549
550 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
551 case SND_SOC_DAIFMT_CBM_CFM:
552 mode |= AK4671_M_S;
553 break;
554 case SND_SOC_DAIFMT_CBM_CFS:
555 mode &= ~(AK4671_M_S);
556 break;
557 default:
558 return -EINVAL;
559 }
560
561 /* interface format */
562 format = snd_soc_read(codec, AK4671_FORMAT_SELECT);
563 format &= ~AK4671_DIF;
564
565 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
566 case SND_SOC_DAIFMT_I2S:
567 format |= AK4671_DIF_I2S_MODE;
568 break;
569 case SND_SOC_DAIFMT_LEFT_J:
570 format |= AK4671_DIF_MSB_MODE;
571 break;
572 case SND_SOC_DAIFMT_DSP_A:
573 format |= AK4671_DIF_DSP_MODE;
574 format |= AK4671_BCKP;
575 format |= AK4671_MSBS;
576 break;
577 default:
578 return -EINVAL;
579 }
580
581 /* set mode and format */
582 snd_soc_write(codec, AK4671_PLL_MODE_SELECT1, mode);
583 snd_soc_write(codec, AK4671_FORMAT_SELECT, format);
584
585 return 0;
586}
587
588static int ak4671_set_bias_level(struct snd_soc_codec *codec,
589 enum snd_soc_bias_level level)
590{
591 u8 reg;
592
593 switch (level) {
594 case SND_SOC_BIAS_ON:
595 case SND_SOC_BIAS_PREPARE:
596 case SND_SOC_BIAS_STANDBY:
597 reg = snd_soc_read(codec, AK4671_AD_DA_POWER_MANAGEMENT);
598 snd_soc_write(codec, AK4671_AD_DA_POWER_MANAGEMENT,
599 reg | AK4671_PMVCM);
600 break;
601 case SND_SOC_BIAS_OFF:
602 snd_soc_write(codec, AK4671_AD_DA_POWER_MANAGEMENT, 0x00);
603 break;
604 }
605 codec->bias_level = level;
606 return 0;
607}
608
609#define AK4671_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
610 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
611 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
612 SNDRV_PCM_RATE_48000)
613
614#define AK4671_FORMATS SNDRV_PCM_FMTBIT_S16_LE
615
616static struct snd_soc_dai_ops ak4671_dai_ops = {
617 .hw_params = ak4671_hw_params,
618 .set_sysclk = ak4671_set_dai_sysclk,
619 .set_fmt = ak4671_set_dai_fmt,
620};
621
622struct snd_soc_dai ak4671_dai = {
623 .name = "AK4671",
624 .playback = {
625 .stream_name = "Playback",
626 .channels_min = 1,
627 .channels_max = 2,
628 .rates = AK4671_RATES,
629 .formats = AK4671_FORMATS,},
630 .capture = {
631 .stream_name = "Capture",
632 .channels_min = 1,
633 .channels_max = 2,
634 .rates = AK4671_RATES,
635 .formats = AK4671_FORMATS,},
636 .ops = &ak4671_dai_ops,
637};
638EXPORT_SYMBOL_GPL(ak4671_dai);
639
640static int ak4671_probe(struct platform_device *pdev)
641{
642 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
643 struct snd_soc_codec *codec;
644 int ret = 0;
645
646 if (ak4671_codec == NULL) {
647 dev_err(&pdev->dev, "Codec device not registered\n");
648 return -ENODEV;
649 }
650
651 socdev->card->codec = ak4671_codec;
652 codec = ak4671_codec;
653
654 /* register pcms */
655 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
656 if (ret < 0) {
657 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
658 goto pcm_err;
659 }
660
661 snd_soc_add_controls(codec, ak4671_snd_controls,
662 ARRAY_SIZE(ak4671_snd_controls));
663 ak4671_add_widgets(codec);
664
665 ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
666
667 return ret;
668
669pcm_err:
670 return ret;
671}
672
673static int ak4671_remove(struct platform_device *pdev)
674{
675 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
676
677 snd_soc_free_pcms(socdev);
678 snd_soc_dapm_free(socdev);
679
680 return 0;
681}
682
683struct snd_soc_codec_device soc_codec_dev_ak4671 = {
684 .probe = ak4671_probe,
685 .remove = ak4671_remove,
686};
687EXPORT_SYMBOL_GPL(soc_codec_dev_ak4671);
688
689static int ak4671_register(struct ak4671_priv *ak4671,
690 enum snd_soc_control_type control)
691{
692 int ret;
693 struct snd_soc_codec *codec = &ak4671->codec;
694
695 if (ak4671_codec) {
696 dev_err(codec->dev, "Another AK4671 is registered\n");
697 ret = -EINVAL;
698 goto err;
699 }
700
701 mutex_init(&codec->mutex);
702 INIT_LIST_HEAD(&codec->dapm_widgets);
703 INIT_LIST_HEAD(&codec->dapm_paths);
704
705 codec->private_data = ak4671;
706 codec->name = "AK4671";
707 codec->owner = THIS_MODULE;
708 codec->bias_level = SND_SOC_BIAS_OFF;
709 codec->set_bias_level = ak4671_set_bias_level;
710 codec->dai = &ak4671_dai;
711 codec->num_dai = 1;
712 codec->reg_cache_size = AK4671_CACHEREGNUM;
713 codec->reg_cache = &ak4671->reg_cache;
714
715 memcpy(codec->reg_cache, ak4671_reg, sizeof(ak4671_reg));
716
717 ret = snd_soc_codec_set_cache_io(codec, 8, 8, control);
718 if (ret < 0) {
719 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
720 goto err;
721 }
722
723 ak4671_dai.dev = codec->dev;
724 ak4671_codec = codec;
725
726 ret = snd_soc_register_codec(codec);
727 if (ret != 0) {
728 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
729 goto err;
730 }
731
732 ret = snd_soc_register_dai(&ak4671_dai);
733 if (ret != 0) {
734 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
735 goto err_codec;
736 }
737
738 return 0;
739
740err_codec:
741 snd_soc_unregister_codec(codec);
742err:
743 kfree(ak4671);
744 return ret;
745}
746
747static void ak4671_unregister(struct ak4671_priv *ak4671)
748{
749 ak4671_set_bias_level(&ak4671->codec, SND_SOC_BIAS_OFF);
750 snd_soc_unregister_dai(&ak4671_dai);
751 snd_soc_unregister_codec(&ak4671->codec);
752 kfree(ak4671);
753 ak4671_codec = NULL;
754}
755
756static int __devinit ak4671_i2c_probe(struct i2c_client *client,
757 const struct i2c_device_id *id)
758{
759 struct ak4671_priv *ak4671;
760 struct snd_soc_codec *codec;
761
762 ak4671 = kzalloc(sizeof(struct ak4671_priv), GFP_KERNEL);
763 if (ak4671 == NULL)
764 return -ENOMEM;
765
766 codec = &ak4671->codec;
767 codec->hw_write = (hw_write_t)i2c_master_send;
768
769 i2c_set_clientdata(client, ak4671);
770 codec->control_data = client;
771
772 codec->dev = &client->dev;
773
774 return ak4671_register(ak4671, SND_SOC_I2C);
775}
776
777static __devexit int ak4671_i2c_remove(struct i2c_client *client)
778{
779 struct ak4671_priv *ak4671 = i2c_get_clientdata(client);
780
781 ak4671_unregister(ak4671);
782
783 return 0;
784}
785
786static const struct i2c_device_id ak4671_i2c_id[] = {
787 { "ak4671", 0 },
788 { }
789};
790MODULE_DEVICE_TABLE(i2c, ak4671_i2c_id);
791
792static struct i2c_driver ak4671_i2c_driver = {
793 .driver = {
794 .name = "ak4671",
795 .owner = THIS_MODULE,
796 },
797 .probe = ak4671_i2c_probe,
798 .remove = __devexit_p(ak4671_i2c_remove),
799 .id_table = ak4671_i2c_id,
800};
801
802static int __init ak4671_modinit(void)
803{
804 return i2c_add_driver(&ak4671_i2c_driver);
805}
806module_init(ak4671_modinit);
807
808static void __exit ak4671_exit(void)
809{
810 i2c_del_driver(&ak4671_i2c_driver);
811}
812module_exit(ak4671_exit);
813
814MODULE_DESCRIPTION("ASoC AK4671 codec driver");
815MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
816MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ak4671.h b/sound/soc/codecs/ak4671.h
new file mode 100644
index 000000000000..e2fad964e88b
--- /dev/null
+++ b/sound/soc/codecs/ak4671.h
@@ -0,0 +1,156 @@
1/*
2 * ak4671.h -- audio driver for AK4671
3 *
4 * Copyright (C) 2009 Samsung Electronics Co.Ltd
5 * Author: Joonyoung Shim <jy0922.shim@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 */
13
14#ifndef _AK4671_H
15#define _AK4671_H
16
17#define AK4671_AD_DA_POWER_MANAGEMENT 0x00
18#define AK4671_PLL_MODE_SELECT0 0x01
19#define AK4671_PLL_MODE_SELECT1 0x02
20#define AK4671_FORMAT_SELECT 0x03
21#define AK4671_MIC_SIGNAL_SELECT 0x04
22#define AK4671_MIC_AMP_GAIN 0x05
23#define AK4671_MIXING_POWER_MANAGEMENT0 0x06
24#define AK4671_MIXING_POWER_MANAGEMENT1 0x07
25#define AK4671_OUTPUT_VOLUME_CONTROL 0x08
26#define AK4671_LOUT1_SIGNAL_SELECT 0x09
27#define AK4671_ROUT1_SIGNAL_SELECT 0x0a
28#define AK4671_LOUT2_SIGNAL_SELECT 0x0b
29#define AK4671_ROUT2_SIGNAL_SELECT 0x0c
30#define AK4671_LOUT3_SIGNAL_SELECT 0x0d
31#define AK4671_ROUT3_SIGNAL_SELECT 0x0e
32#define AK4671_LOUT1_POWER_MANAGERMENT 0x0f
33#define AK4671_LOUT2_POWER_MANAGERMENT 0x10
34#define AK4671_LOUT3_POWER_MANAGERMENT 0x11
35#define AK4671_LCH_INPUT_VOLUME_CONTROL 0x12
36#define AK4671_RCH_INPUT_VOLUME_CONTROL 0x13
37#define AK4671_ALC_REFERENCE_SELECT 0x14
38#define AK4671_DIGITAL_MIXING_CONTROL 0x15
39#define AK4671_ALC_TIMER_SELECT 0x16
40#define AK4671_ALC_MODE_CONTROL 0x17
41#define AK4671_MODE_CONTROL1 0x18
42#define AK4671_MODE_CONTROL2 0x19
43#define AK4671_LCH_OUTPUT_VOLUME_CONTROL 0x1a
44#define AK4671_RCH_OUTPUT_VOLUME_CONTROL 0x1b
45#define AK4671_SIDETONE_A_CONTROL 0x1c
46#define AK4671_DIGITAL_FILTER_SELECT 0x1d
47#define AK4671_FIL3_COEFFICIENT0 0x1e
48#define AK4671_FIL3_COEFFICIENT1 0x1f
49#define AK4671_FIL3_COEFFICIENT2 0x20
50#define AK4671_FIL3_COEFFICIENT3 0x21
51#define AK4671_EQ_COEFFICIENT0 0x22
52#define AK4671_EQ_COEFFICIENT1 0x23
53#define AK4671_EQ_COEFFICIENT2 0x24
54#define AK4671_EQ_COEFFICIENT3 0x25
55#define AK4671_EQ_COEFFICIENT4 0x26
56#define AK4671_EQ_COEFFICIENT5 0x27
57#define AK4671_FIL1_COEFFICIENT0 0x28
58#define AK4671_FIL1_COEFFICIENT1 0x29
59#define AK4671_FIL1_COEFFICIENT2 0x2a
60#define AK4671_FIL1_COEFFICIENT3 0x2b
61#define AK4671_FIL2_COEFFICIENT0 0x2c
62#define AK4671_FIL2_COEFFICIENT1 0x2d
63#define AK4671_FIL2_COEFFICIENT2 0x2e
64#define AK4671_FIL2_COEFFICIENT3 0x2f
65#define AK4671_DIGITAL_FILTER_SELECT2 0x30
66#define AK4671_E1_COEFFICIENT0 0x32
67#define AK4671_E1_COEFFICIENT1 0x33
68#define AK4671_E1_COEFFICIENT2 0x34
69#define AK4671_E1_COEFFICIENT3 0x35
70#define AK4671_E1_COEFFICIENT4 0x36
71#define AK4671_E1_COEFFICIENT5 0x37
72#define AK4671_E2_COEFFICIENT0 0x38
73#define AK4671_E2_COEFFICIENT1 0x39
74#define AK4671_E2_COEFFICIENT2 0x3a
75#define AK4671_E2_COEFFICIENT3 0x3b
76#define AK4671_E2_COEFFICIENT4 0x3c
77#define AK4671_E2_COEFFICIENT5 0x3d
78#define AK4671_E3_COEFFICIENT0 0x3e
79#define AK4671_E3_COEFFICIENT1 0x3f
80#define AK4671_E3_COEFFICIENT2 0x40
81#define AK4671_E3_COEFFICIENT3 0x41
82#define AK4671_E3_COEFFICIENT4 0x42
83#define AK4671_E3_COEFFICIENT5 0x43
84#define AK4671_E4_COEFFICIENT0 0x44
85#define AK4671_E4_COEFFICIENT1 0x45
86#define AK4671_E4_COEFFICIENT2 0x46
87#define AK4671_E4_COEFFICIENT3 0x47
88#define AK4671_E4_COEFFICIENT4 0x48
89#define AK4671_E4_COEFFICIENT5 0x49
90#define AK4671_E5_COEFFICIENT0 0x4a
91#define AK4671_E5_COEFFICIENT1 0x4b
92#define AK4671_E5_COEFFICIENT2 0x4c
93#define AK4671_E5_COEFFICIENT3 0x4d
94#define AK4671_E5_COEFFICIENT4 0x4e
95#define AK4671_E5_COEFFICIENT5 0x4f
96#define AK4671_EQ_CONTROL_250HZ_100HZ 0x50
97#define AK4671_EQ_CONTROL_3500HZ_1KHZ 0x51
98#define AK4671_EQ_CONTRO_10KHZ 0x52
99#define AK4671_PCM_IF_CONTROL0 0x53
100#define AK4671_PCM_IF_CONTROL1 0x54
101#define AK4671_PCM_IF_CONTROL2 0x55
102#define AK4671_DIGITAL_VOLUME_B_CONTROL 0x56
103#define AK4671_DIGITAL_VOLUME_C_CONTROL 0x57
104#define AK4671_SIDETONE_VOLUME_CONTROL 0x58
105#define AK4671_DIGITAL_MIXING_CONTROL2 0x59
106#define AK4671_SAR_ADC_CONTROL 0x5a
107
108#define AK4671_CACHEREGNUM (AK4671_SAR_ADC_CONTROL + 1)
109
110/* Bitfield Definitions */
111
112/* AK4671_AD_DA_POWER_MANAGEMENT (0x00) Fields */
113#define AK4671_PMVCM 0x01
114
115/* AK4671_PLL_MODE_SELECT0 (0x01) Fields */
116#define AK4671_PLL 0x0f
117#define AK4671_PLL_11_2896MHZ (4 << 0)
118#define AK4671_PLL_12_288MHZ (5 << 0)
119#define AK4671_PLL_12MHZ (6 << 0)
120#define AK4671_PLL_24MHZ (7 << 0)
121#define AK4671_PLL_19_2MHZ (8 << 0)
122#define AK4671_PLL_13_5MHZ (12 << 0)
123#define AK4671_PLL_27MHZ (13 << 0)
124#define AK4671_PLL_13MHZ (14 << 0)
125#define AK4671_PLL_26MHZ (15 << 0)
126#define AK4671_FS 0xf0
127#define AK4671_FS_8KHZ (0 << 4)
128#define AK4671_FS_12KHZ (1 << 4)
129#define AK4671_FS_16KHZ (2 << 4)
130#define AK4671_FS_24KHZ (3 << 4)
131#define AK4671_FS_11_025KHZ (5 << 4)
132#define AK4671_FS_22_05KHZ (7 << 4)
133#define AK4671_FS_32KHZ (10 << 4)
134#define AK4671_FS_48KHZ (11 << 4)
135#define AK4671_FS_44_1KHZ (15 << 4)
136
137/* AK4671_PLL_MODE_SELECT1 (0x02) Fields */
138#define AK4671_PMPLL 0x01
139#define AK4671_M_S 0x02
140
141/* AK4671_FORMAT_SELECT (0x03) Fields */
142#define AK4671_DIF 0x03
143#define AK4671_DIF_DSP_MODE (0 << 0)
144#define AK4671_DIF_MSB_MODE (2 << 0)
145#define AK4671_DIF_I2S_MODE (3 << 0)
146#define AK4671_BCKP 0x04
147#define AK4671_MSBS 0x08
148#define AK4671_SDOD 0x10
149
150/* AK4671_LOUT2_POWER_MANAGEMENT (0x10) Fields */
151#define AK4671_MUTEN 0x04
152
153extern struct snd_soc_dai ak4671_dai;
154extern struct snd_soc_codec_device soc_codec_dev_ak4671;
155
156#endif
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index ca1e24a8f12a..81a62d198b70 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -23,11 +23,13 @@
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>
29#include <linux/i2c.h> 30#include <linux/i2c.h>
30#include <linux/delay.h> 31#include <linux/delay.h>
32#include <linux/regulator/consumer.h>
31 33
32#include "cs4270.h" 34#include "cs4270.h"
33 35
@@ -106,6 +108,10 @@
106#define CS4270_MUTE_DAC_A 0x01 108#define CS4270_MUTE_DAC_A 0x01
107#define CS4270_MUTE_DAC_B 0x02 109#define CS4270_MUTE_DAC_B 0x02
108 110
111static const char *supply_names[] = {
112 "va", "vd", "vlc"
113};
114
109/* Private data for the CS4270 */ 115/* Private data for the CS4270 */
110struct cs4270_private { 116struct cs4270_private {
111 struct snd_soc_codec codec; 117 struct snd_soc_codec codec;
@@ -114,6 +120,9 @@ struct cs4270_private {
114 unsigned int mode; /* The mode (I2S or left-justified) */ 120 unsigned int mode; /* The mode (I2S or left-justified) */
115 unsigned int slave_mode; 121 unsigned int slave_mode;
116 unsigned int manual_mute; 122 unsigned int manual_mute;
123
124 /* power domain regulators */
125 struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)];
117}; 126};
118 127
119/** 128/**
@@ -192,6 +201,11 @@ static struct cs4270_mode_ratios cs4270_mode_ratios[] = {
192 * This function must be called by the machine driver's 'startup' function, 201 * This function must be called by the machine driver's 'startup' function,
193 * otherwise the list of supported sample rates will not be available in 202 * otherwise the list of supported sample rates will not be available in
194 * time for ALSA. 203 * time for ALSA.
204 *
205 * For setups with variable MCLKs, pass 0 as 'freq' argument. This will cause
206 * theoretically possible sample rates to be enabled. Call it again with a
207 * proper value set one the external clock is set (most probably you would do
208 * that from a machine's driver 'hw_param' hook.
195 */ 209 */
196static int cs4270_set_dai_sysclk(struct snd_soc_dai *codec_dai, 210static int cs4270_set_dai_sysclk(struct snd_soc_dai *codec_dai,
197 int clk_id, unsigned int freq, int dir) 211 int clk_id, unsigned int freq, int dir)
@@ -205,20 +219,27 @@ static int cs4270_set_dai_sysclk(struct snd_soc_dai *codec_dai,
205 219
206 cs4270->mclk = freq; 220 cs4270->mclk = freq;
207 221
208 for (i = 0; i < NUM_MCLK_RATIOS; i++) { 222 if (cs4270->mclk) {
209 unsigned int rate = freq / cs4270_mode_ratios[i].ratio; 223 for (i = 0; i < NUM_MCLK_RATIOS; i++) {
210 rates |= snd_pcm_rate_to_rate_bit(rate); 224 unsigned int rate = freq / cs4270_mode_ratios[i].ratio;
211 if (rate < rate_min) 225 rates |= snd_pcm_rate_to_rate_bit(rate);
212 rate_min = rate; 226 if (rate < rate_min)
213 if (rate > rate_max) 227 rate_min = rate;
214 rate_max = rate; 228 if (rate > rate_max)
215 } 229 rate_max = rate;
216 /* FIXME: soc should support a rate list */ 230 }
217 rates &= ~SNDRV_PCM_RATE_KNOT; 231 /* FIXME: soc should support a rate list */
232 rates &= ~SNDRV_PCM_RATE_KNOT;
218 233
219 if (!rates) { 234 if (!rates) {
220 dev_err(codec->dev, "could not find a valid sample rate\n"); 235 dev_err(codec->dev, "could not find a valid sample rate\n");
221 return -EINVAL; 236 return -EINVAL;
237 }
238 } else {
239 /* enable all possible rates */
240 rates = SNDRV_PCM_RATE_8000_192000;
241 rate_min = 8000;
242 rate_max = 192000;
222 } 243 }
223 244
224 codec_dai->playback.rates = rates; 245 codec_dai->playback.rates = rates;
@@ -520,6 +541,7 @@ static const struct snd_kcontrol_new cs4270_snd_controls[] = {
520 SOC_SINGLE("Digital Sidetone Switch", CS4270_FORMAT, 5, 1, 0), 541 SOC_SINGLE("Digital Sidetone Switch", CS4270_FORMAT, 5, 1, 0),
521 SOC_SINGLE("Soft Ramp Switch", CS4270_TRANS, 6, 1, 0), 542 SOC_SINGLE("Soft Ramp Switch", CS4270_TRANS, 6, 1, 0),
522 SOC_SINGLE("Zero Cross Switch", CS4270_TRANS, 5, 1, 0), 543 SOC_SINGLE("Zero Cross Switch", CS4270_TRANS, 5, 1, 0),
544 SOC_SINGLE("De-emphasis filter", CS4270_TRANS, 0, 1, 0),
523 SOC_SINGLE("Popguard Switch", CS4270_MODE, 0, 1, 1), 545 SOC_SINGLE("Popguard Switch", CS4270_MODE, 0, 1, 1),
524 SOC_SINGLE("Auto-Mute Switch", CS4270_MUTE, 5, 1, 0), 546 SOC_SINGLE("Auto-Mute Switch", CS4270_MUTE, 5, 1, 0),
525 SOC_DOUBLE("Master Capture Switch", CS4270_MUTE, 3, 4, 1, 1), 547 SOC_DOUBLE("Master Capture Switch", CS4270_MUTE, 3, 4, 1, 1),
@@ -578,7 +600,8 @@ static int cs4270_probe(struct platform_device *pdev)
578{ 600{
579 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 601 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
580 struct snd_soc_codec *codec = cs4270_codec; 602 struct snd_soc_codec *codec = cs4270_codec;
581 int ret; 603 struct cs4270_private *cs4270 = codec->private_data;
604 int i, ret;
582 605
583 /* Connect the codec to the socdev. snd_soc_new_pcms() needs this. */ 606 /* Connect the codec to the socdev. snd_soc_new_pcms() needs this. */
584 socdev->card->codec = codec; 607 socdev->card->codec = codec;
@@ -598,15 +621,26 @@ static int cs4270_probe(struct platform_device *pdev)
598 goto error_free_pcms; 621 goto error_free_pcms;
599 } 622 }
600 623
601 /* And finally, register the socdev */ 624 /* get the power supply regulators */
602 ret = snd_soc_init_card(socdev); 625 for (i = 0; i < ARRAY_SIZE(supply_names); i++)
603 if (ret < 0) { 626 cs4270->supplies[i].supply = supply_names[i];
604 dev_err(codec->dev, "failed to register card\n"); 627
628 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(cs4270->supplies),
629 cs4270->supplies);
630 if (ret < 0)
605 goto error_free_pcms; 631 goto error_free_pcms;
606 } 632
633 ret = regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies),
634 cs4270->supplies);
635 if (ret < 0)
636 goto error_free_regulators;
607 637
608 return 0; 638 return 0;
609 639
640error_free_regulators:
641 regulator_bulk_free(ARRAY_SIZE(cs4270->supplies),
642 cs4270->supplies);
643
610error_free_pcms: 644error_free_pcms:
611 snd_soc_free_pcms(socdev); 645 snd_soc_free_pcms(socdev);
612 646
@@ -622,8 +656,12 @@ error_free_pcms:
622static int cs4270_remove(struct platform_device *pdev) 656static int cs4270_remove(struct platform_device *pdev)
623{ 657{
624 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 658 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
659 struct snd_soc_codec *codec = cs4270_codec;
660 struct cs4270_private *cs4270 = codec->private_data;
625 661
626 snd_soc_free_pcms(socdev); 662 snd_soc_free_pcms(socdev);
663 regulator_bulk_disable(ARRAY_SIZE(cs4270->supplies), cs4270->supplies);
664 regulator_bulk_free(ARRAY_SIZE(cs4270->supplies), cs4270->supplies);
627 665
628 return 0; 666 return 0;
629}; 667};
@@ -802,36 +840,36 @@ MODULE_DEVICE_TABLE(i2c, cs4270_id);
802 * and all registers are written back to the hardware when resuming. 840 * and all registers are written back to the hardware when resuming.
803 */ 841 */
804 842
805static int cs4270_i2c_suspend(struct i2c_client *client, pm_message_t mesg) 843static int cs4270_soc_suspend(struct platform_device *pdev, pm_message_t mesg)
806{ 844{
807 struct cs4270_private *cs4270 = i2c_get_clientdata(client); 845 struct snd_soc_codec *codec = cs4270_codec;
808 struct snd_soc_codec *codec = &cs4270->codec; 846 struct cs4270_private *cs4270 = codec->private_data;
809 847 int reg, ret;
810 return snd_soc_suspend_device(codec->dev);
811}
812 848
813static int cs4270_i2c_resume(struct i2c_client *client) 849 reg = snd_soc_read(codec, CS4270_PWRCTL) | CS4270_PWRCTL_PDN_ALL;
814{ 850 if (reg < 0)
815 struct cs4270_private *cs4270 = i2c_get_clientdata(client); 851 return reg;
816 struct snd_soc_codec *codec = &cs4270->codec;
817 852
818 return snd_soc_resume_device(codec->dev); 853 ret = snd_soc_write(codec, CS4270_PWRCTL, reg);
819} 854 if (ret < 0)
855 return ret;
820 856
821static int cs4270_soc_suspend(struct platform_device *pdev, pm_message_t mesg) 857 regulator_bulk_disable(ARRAY_SIZE(cs4270->supplies),
822{ 858 cs4270->supplies);
823 struct snd_soc_codec *codec = cs4270_codec;
824 int reg = snd_soc_read(codec, CS4270_PWRCTL) | CS4270_PWRCTL_PDN_ALL;
825 859
826 return snd_soc_write(codec, CS4270_PWRCTL, reg); 860 return 0;
827} 861}
828 862
829static int cs4270_soc_resume(struct platform_device *pdev) 863static int cs4270_soc_resume(struct platform_device *pdev)
830{ 864{
831 struct snd_soc_codec *codec = cs4270_codec; 865 struct snd_soc_codec *codec = cs4270_codec;
866 struct cs4270_private *cs4270 = codec->private_data;
832 struct i2c_client *i2c_client = codec->control_data; 867 struct i2c_client *i2c_client = codec->control_data;
833 int reg; 868 int reg;
834 869
870 regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies),
871 cs4270->supplies);
872
835 /* In case the device was put to hard reset during sleep, we need to 873 /* In case the device was put to hard reset during sleep, we need to
836 * wait 500ns here before any I2C communication. */ 874 * wait 500ns here before any I2C communication. */
837 ndelay(500); 875 ndelay(500);
@@ -853,8 +891,6 @@ static int cs4270_soc_resume(struct platform_device *pdev)
853 return snd_soc_write(codec, CS4270_PWRCTL, reg); 891 return snd_soc_write(codec, CS4270_PWRCTL, reg);
854} 892}
855#else 893#else
856#define cs4270_i2c_suspend NULL
857#define cs4270_i2c_resume NULL
858#define cs4270_soc_suspend NULL 894#define cs4270_soc_suspend NULL
859#define cs4270_soc_resume NULL 895#define cs4270_soc_resume NULL
860#endif /* CONFIG_PM */ 896#endif /* CONFIG_PM */
@@ -873,8 +909,6 @@ static struct i2c_driver cs4270_i2c_driver = {
873 .id_table = cs4270_id, 909 .id_table = cs4270_id,
874 .probe = cs4270_i2c_probe, 910 .probe = cs4270_i2c_probe,
875 .remove = cs4270_i2c_remove, 911 .remove = cs4270_i2c_remove,
876 .suspend = cs4270_i2c_suspend,
877 .resume = cs4270_i2c_resume,
878}; 912};
879 913
880/* 914/*
diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c
index 38eac9c866e1..9f169c477108 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>
@@ -93,7 +94,6 @@ static int cx20442_add_widgets(struct snd_soc_codec *codec)
93 snd_soc_dapm_add_routes(codec, cx20442_audio_map, 94 snd_soc_dapm_add_routes(codec, cx20442_audio_map,
94 ARRAY_SIZE(cx20442_audio_map)); 95 ARRAY_SIZE(cx20442_audio_map));
95 96
96 snd_soc_dapm_new_widgets(codec);
97 return 0; 97 return 0;
98} 98}
99 99
@@ -355,17 +355,6 @@ static int cx20442_codec_probe(struct platform_device *pdev)
355 355
356 cx20442_add_widgets(codec); 356 cx20442_add_widgets(codec);
357 357
358 ret = snd_soc_init_card(socdev);
359 if (ret < 0) {
360 dev_err(&pdev->dev, "failed to register card\n");
361 goto card_err;
362 }
363
364 return ret;
365
366card_err:
367 snd_soc_free_pcms(socdev);
368 snd_soc_dapm_free(socdev);
369pcm_err: 358pcm_err:
370 return ret; 359 return ret;
371} 360}
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c
new file mode 100644
index 000000000000..366daf1d044e
--- /dev/null
+++ b/sound/soc/codecs/da7210.c
@@ -0,0 +1,590 @@
1/*
2 * DA7210 ALSA Soc codec driver
3 *
4 * Copyright (c) 2009 Dialog Semiconductor
5 * Written by David Chen <Dajun.chen@diasemi.com>
6 *
7 * Copyright (C) 2009 Renesas Solutions Corp.
8 * Cleanups by Kuninori Morimoto <morimoto.kuninori@renesas.com>
9 *
10 * Tested on SuperH Ecovec24 board with S16/S24 LE in 48KHz using I2S
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version.
16 */
17
18#include <linux/module.h>
19#include <linux/moduleparam.h>
20#include <linux/kernel.h>
21#include <linux/init.h>
22#include <linux/delay.h>
23#include <linux/pm.h>
24#include <linux/i2c.h>
25#include <linux/platform_device.h>
26#include <linux/slab.h>
27#include <sound/core.h>
28#include <sound/pcm.h>
29#include <sound/pcm_params.h>
30#include <sound/soc.h>
31#include <sound/soc-dapm.h>
32#include <sound/tlv.h>
33#include <sound/initval.h>
34#include <asm/div64.h>
35
36#include "da7210.h"
37
38/* DA7210 register space */
39#define DA7210_STATUS 0x02
40#define DA7210_STARTUP1 0x03
41#define DA7210_MIC_L 0x07
42#define DA7210_MIC_R 0x08
43#define DA7210_INMIX_L 0x0D
44#define DA7210_INMIX_R 0x0E
45#define DA7210_ADC_HPF 0x0F
46#define DA7210_ADC 0x10
47#define DA7210_DAC_HPF 0x14
48#define DA7210_DAC_L 0x15
49#define DA7210_DAC_R 0x16
50#define DA7210_DAC_SEL 0x17
51#define DA7210_OUTMIX_L 0x1C
52#define DA7210_OUTMIX_R 0x1D
53#define DA7210_HP_L_VOL 0x21
54#define DA7210_HP_R_VOL 0x22
55#define DA7210_HP_CFG 0x23
56#define DA7210_DAI_SRC_SEL 0x25
57#define DA7210_DAI_CFG1 0x26
58#define DA7210_DAI_CFG3 0x28
59#define DA7210_PLL_DIV3 0x2B
60#define DA7210_PLL 0x2C
61
62/* STARTUP1 bit fields */
63#define DA7210_SC_MST_EN (1 << 0)
64
65/* MIC_L bit fields */
66#define DA7210_MICBIAS_EN (1 << 6)
67#define DA7210_MIC_L_EN (1 << 7)
68
69/* MIC_R bit fields */
70#define DA7210_MIC_R_EN (1 << 7)
71
72/* INMIX_L bit fields */
73#define DA7210_IN_L_EN (1 << 7)
74
75/* INMIX_R bit fields */
76#define DA7210_IN_R_EN (1 << 7)
77
78/* ADC_HPF bit fields */
79#define DA7210_ADC_VOICE_EN (1 << 7)
80
81/* ADC bit fields */
82#define DA7210_ADC_L_EN (1 << 3)
83#define DA7210_ADC_R_EN (1 << 7)
84
85/* DAC_HPF fields */
86#define DA7210_DAC_VOICE_EN (1 << 7)
87
88/* DAC_SEL bit fields */
89#define DA7210_DAC_L_SRC_DAI_L (4 << 0)
90#define DA7210_DAC_L_EN (1 << 3)
91#define DA7210_DAC_R_SRC_DAI_R (5 << 4)
92#define DA7210_DAC_R_EN (1 << 7)
93
94/* OUTMIX_L bit fields */
95#define DA7210_OUT_L_EN (1 << 7)
96
97/* OUTMIX_R bit fields */
98#define DA7210_OUT_R_EN (1 << 7)
99
100/* HP_CFG bit fields */
101#define DA7210_HP_2CAP_MODE (1 << 1)
102#define DA7210_HP_SENSE_EN (1 << 2)
103#define DA7210_HP_L_EN (1 << 3)
104#define DA7210_HP_MODE (1 << 6)
105#define DA7210_HP_R_EN (1 << 7)
106
107/* DAI_SRC_SEL bit fields */
108#define DA7210_DAI_OUT_L_SRC (6 << 0)
109#define DA7210_DAI_OUT_R_SRC (7 << 4)
110
111/* DAI_CFG1 bit fields */
112#define DA7210_DAI_WORD_S16_LE (0 << 0)
113#define DA7210_DAI_WORD_S24_LE (2 << 0)
114#define DA7210_DAI_FLEN_64BIT (1 << 2)
115#define DA7210_DAI_MODE_MASTER (1 << 7)
116
117/* DAI_CFG3 bit fields */
118#define DA7210_DAI_FORMAT_I2SMODE (0 << 0)
119#define DA7210_DAI_OE (1 << 3)
120#define DA7210_DAI_EN (1 << 7)
121
122/*PLL_DIV3 bit fields */
123#define DA7210_MCLK_RANGE_10_20_MHZ (1 << 4)
124#define DA7210_PLL_BYP (1 << 6)
125
126/* PLL bit fields */
127#define DA7210_PLL_FS_48000 (11 << 0)
128
129#define DA7210_VERSION "0.0.1"
130
131/* Codec private data */
132struct da7210_priv {
133 struct snd_soc_codec codec;
134};
135
136static struct snd_soc_codec *da7210_codec;
137
138/*
139 * Register cache
140 */
141static const u8 da7210_reg[] = {
142 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R0 - R7 */
143 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, /* R8 - RF */
144 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x10, 0x54, /* R10 - R17 */
145 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R18 - R1F */
146 0x00, 0x00, 0x00, 0x02, 0x00, 0x76, 0x00, 0x00, /* R20 - R27 */
147 0x04, 0x00, 0x00, 0x30, 0x2A, 0x00, 0x40, 0x00, /* R28 - R2F */
148 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, /* R30 - R37 */
149 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, /* R38 - R3F */
150 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R40 - R4F */
151 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R48 - R4F */
152 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R50 - R57 */
153 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R58 - R5F */
154 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R60 - R67 */
155 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R68 - R6F */
156 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R70 - R77 */
157 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0x00, /* R78 - R7F */
158 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, /* R80 - R87 */
159 0x00, /* R88 */
160};
161
162/*
163 * Read da7210 register cache
164 */
165static inline u32 da7210_read_reg_cache(struct snd_soc_codec *codec, u32 reg)
166{
167 u8 *cache = codec->reg_cache;
168 BUG_ON(reg > ARRAY_SIZE(da7210_reg));
169 return cache[reg];
170}
171
172/*
173 * Write to the da7210 register space
174 */
175static int da7210_write(struct snd_soc_codec *codec, u32 reg, u32 value)
176{
177 u8 *cache = codec->reg_cache;
178 u8 data[2];
179
180 BUG_ON(codec->volatile_register);
181
182 data[0] = reg & 0xff;
183 data[1] = value & 0xff;
184
185 if (reg >= codec->reg_cache_size)
186 return -EIO;
187
188 if (2 != codec->hw_write(codec->control_data, data, 2))
189 return -EIO;
190
191 cache[reg] = value;
192 return 0;
193}
194
195/*
196 * Read from the da7210 register space.
197 */
198static inline u32 da7210_read(struct snd_soc_codec *codec, u32 reg)
199{
200 if (DA7210_STATUS == reg)
201 return i2c_smbus_read_byte_data(codec->control_data, reg);
202
203 return da7210_read_reg_cache(codec, reg);
204}
205
206static int da7210_startup(struct snd_pcm_substream *substream,
207 struct snd_soc_dai *dai)
208{
209 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
210 struct snd_soc_codec *codec = dai->codec;
211
212 if (is_play) {
213 /* PlayBack Volume 40 */
214 snd_soc_update_bits(codec, DA7210_HP_L_VOL, 0x3F, 40);
215 snd_soc_update_bits(codec, DA7210_HP_R_VOL, 0x3F, 40);
216
217 /* Enable Out */
218 snd_soc_update_bits(codec, DA7210_OUTMIX_L, 0x1F, 0x10);
219 snd_soc_update_bits(codec, DA7210_OUTMIX_R, 0x1F, 0x10);
220
221 } else {
222 /* Volume 7 */
223 snd_soc_update_bits(codec, DA7210_MIC_L, 0x7, 0x7);
224 snd_soc_update_bits(codec, DA7210_MIC_R, 0x7, 0x7);
225
226 /* Enable Mic */
227 snd_soc_update_bits(codec, DA7210_INMIX_L, 0x1F, 0x1);
228 snd_soc_update_bits(codec, DA7210_INMIX_R, 0x1F, 0x1);
229 }
230
231 return 0;
232}
233
234/*
235 * Set PCM DAI word length.
236 */
237static int da7210_hw_params(struct snd_pcm_substream *substream,
238 struct snd_pcm_hw_params *params,
239 struct snd_soc_dai *dai)
240{
241 struct snd_soc_pcm_runtime *rtd = substream->private_data;
242 struct snd_soc_device *socdev = rtd->socdev;
243 struct snd_soc_codec *codec = socdev->card->codec;
244 u32 dai_cfg1;
245 u32 reg, mask;
246
247 /* set DAI source to Left and Right ADC */
248 da7210_write(codec, DA7210_DAI_SRC_SEL,
249 DA7210_DAI_OUT_R_SRC | DA7210_DAI_OUT_L_SRC);
250
251 /* Enable DAI */
252 da7210_write(codec, DA7210_DAI_CFG3, DA7210_DAI_OE | DA7210_DAI_EN);
253
254 dai_cfg1 = 0xFC & da7210_read(codec, DA7210_DAI_CFG1);
255
256 switch (params_format(params)) {
257 case SNDRV_PCM_FORMAT_S16_LE:
258 dai_cfg1 |= DA7210_DAI_WORD_S16_LE;
259 break;
260 case SNDRV_PCM_FORMAT_S24_LE:
261 dai_cfg1 |= DA7210_DAI_WORD_S24_LE;
262 break;
263 default:
264 return -EINVAL;
265 }
266
267 da7210_write(codec, DA7210_DAI_CFG1, dai_cfg1);
268
269 /* FIXME
270 *
271 * It support 48K only now
272 */
273 switch (params_rate(params)) {
274 case 48000:
275 if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) {
276 reg = DA7210_DAC_HPF;
277 mask = DA7210_DAC_VOICE_EN;
278 } else {
279 reg = DA7210_ADC_HPF;
280 mask = DA7210_ADC_VOICE_EN;
281 }
282 break;
283 default:
284 return -EINVAL;
285 }
286
287 snd_soc_update_bits(codec, reg, mask, 0);
288
289 return 0;
290}
291
292/*
293 * Set DAI mode and Format
294 */
295static int da7210_set_dai_fmt(struct snd_soc_dai *codec_dai, u32 fmt)
296{
297 struct snd_soc_codec *codec = codec_dai->codec;
298 u32 dai_cfg1;
299 u32 dai_cfg3;
300
301 dai_cfg1 = 0x7f & da7210_read(codec, DA7210_DAI_CFG1);
302 dai_cfg3 = 0xfc & da7210_read(codec, DA7210_DAI_CFG3);
303
304 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
305 case SND_SOC_DAIFMT_CBM_CFM:
306 dai_cfg1 |= DA7210_DAI_MODE_MASTER;
307 break;
308 default:
309 return -EINVAL;
310 }
311
312 /* FIXME
313 *
314 * It support I2S only now
315 */
316 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
317 case SND_SOC_DAIFMT_I2S:
318 dai_cfg3 |= DA7210_DAI_FORMAT_I2SMODE;
319 break;
320 default:
321 return -EINVAL;
322 }
323
324 /* FIXME
325 *
326 * It support 64bit data transmission only now
327 */
328 dai_cfg1 |= DA7210_DAI_FLEN_64BIT;
329
330 da7210_write(codec, DA7210_DAI_CFG1, dai_cfg1);
331 da7210_write(codec, DA7210_DAI_CFG3, dai_cfg3);
332
333 return 0;
334}
335
336#define DA7210_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE)
337
338/* DAI operations */
339static struct snd_soc_dai_ops da7210_dai_ops = {
340 .startup = da7210_startup,
341 .hw_params = da7210_hw_params,
342 .set_fmt = da7210_set_dai_fmt,
343};
344
345struct snd_soc_dai da7210_dai = {
346 .name = "DA7210 IIS",
347 .id = 0,
348 /* playback capabilities */
349 .playback = {
350 .stream_name = "Playback",
351 .channels_min = 1,
352 .channels_max = 2,
353 .rates = SNDRV_PCM_RATE_8000_96000,
354 .formats = DA7210_FORMATS,
355 },
356 /* capture capabilities */
357 .capture = {
358 .stream_name = "Capture",
359 .channels_min = 1,
360 .channels_max = 2,
361 .rates = SNDRV_PCM_RATE_8000_96000,
362 .formats = DA7210_FORMATS,
363 },
364 .ops = &da7210_dai_ops,
365};
366EXPORT_SYMBOL_GPL(da7210_dai);
367
368/*
369 * Initialize the DA7210 driver
370 * register the mixer and dsp interfaces with the kernel
371 */
372static int da7210_init(struct da7210_priv *da7210)
373{
374 struct snd_soc_codec *codec = &da7210->codec;
375 int ret = 0;
376
377 if (da7210_codec) {
378 dev_err(codec->dev, "Another da7210 is registered\n");
379 return -EINVAL;
380 }
381
382 mutex_init(&codec->mutex);
383 INIT_LIST_HEAD(&codec->dapm_widgets);
384 INIT_LIST_HEAD(&codec->dapm_paths);
385
386 codec->private_data = da7210;
387 codec->name = "DA7210";
388 codec->owner = THIS_MODULE;
389 codec->read = da7210_read;
390 codec->write = da7210_write;
391 codec->dai = &da7210_dai;
392 codec->num_dai = 1;
393 codec->hw_write = (hw_write_t)i2c_master_send;
394 codec->reg_cache_size = ARRAY_SIZE(da7210_reg);
395 codec->reg_cache = kmemdup(da7210_reg,
396 sizeof(da7210_reg), GFP_KERNEL);
397
398 if (!codec->reg_cache)
399 return -ENOMEM;
400
401 da7210_dai.dev = codec->dev;
402 da7210_codec = codec;
403
404 ret = snd_soc_register_codec(codec);
405 if (ret) {
406 dev_err(codec->dev, "Failed to register CODEC: %d\n", ret);
407 goto init_err;
408 }
409
410 ret = snd_soc_register_dai(&da7210_dai);
411 if (ret) {
412 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
413 goto init_err;
414 }
415
416 /* FIXME
417 *
418 * This driver use fixed value here
419 */
420
421 /*
422 * ADC settings
423 */
424
425 /* Enable Left & Right MIC PGA and Mic Bias */
426 da7210_write(codec, DA7210_MIC_L, DA7210_MIC_L_EN | DA7210_MICBIAS_EN);
427 da7210_write(codec, DA7210_MIC_R, DA7210_MIC_R_EN);
428
429 /* Enable Left and Right input PGA */
430 da7210_write(codec, DA7210_INMIX_L, DA7210_IN_L_EN);
431 da7210_write(codec, DA7210_INMIX_R, DA7210_IN_R_EN);
432
433 /* Enable Left and Right ADC */
434 da7210_write(codec, DA7210_ADC, DA7210_ADC_L_EN | DA7210_ADC_R_EN);
435
436 /*
437 * DAC settings
438 */
439
440 /* Enable Left and Right DAC */
441 da7210_write(codec, DA7210_DAC_SEL,
442 DA7210_DAC_L_SRC_DAI_L | DA7210_DAC_L_EN |
443 DA7210_DAC_R_SRC_DAI_R | DA7210_DAC_R_EN);
444
445 /* Enable Left and Right out PGA */
446 da7210_write(codec, DA7210_OUTMIX_L, DA7210_OUT_L_EN);
447 da7210_write(codec, DA7210_OUTMIX_R, DA7210_OUT_R_EN);
448
449 /* Enable Left and Right HeadPhone PGA */
450 da7210_write(codec, DA7210_HP_CFG,
451 DA7210_HP_2CAP_MODE | DA7210_HP_SENSE_EN |
452 DA7210_HP_L_EN | DA7210_HP_MODE | DA7210_HP_R_EN);
453
454 /* Diable PLL and bypass it */
455 da7210_write(codec, DA7210_PLL, DA7210_PLL_FS_48000);
456
457 /* Bypass PLL and set MCLK freq rang to 10-20MHz */
458 da7210_write(codec, DA7210_PLL_DIV3,
459 DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP);
460
461 /* Activate all enabled subsystem */
462 da7210_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN);
463
464 return ret;
465
466init_err:
467 kfree(codec->reg_cache);
468 codec->reg_cache = NULL;
469
470 return ret;
471
472}
473
474#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
475static int __devinit da7210_i2c_probe(struct i2c_client *i2c,
476 const struct i2c_device_id *id)
477{
478 struct da7210_priv *da7210;
479 struct snd_soc_codec *codec;
480 int ret;
481
482 da7210 = kzalloc(sizeof(struct da7210_priv), GFP_KERNEL);
483 if (!da7210)
484 return -ENOMEM;
485
486 codec = &da7210->codec;
487 codec->dev = &i2c->dev;
488
489 i2c_set_clientdata(i2c, da7210);
490 codec->control_data = i2c;
491
492 ret = da7210_init(da7210);
493 if (ret < 0)
494 pr_err("Failed to initialise da7210 audio codec\n");
495
496 return ret;
497}
498
499static int __devexit da7210_i2c_remove(struct i2c_client *client)
500{
501 struct da7210_priv *da7210 = i2c_get_clientdata(client);
502
503 snd_soc_unregister_dai(&da7210_dai);
504 kfree(da7210->codec.reg_cache);
505 kfree(da7210);
506 da7210_codec = NULL;
507
508 return 0;
509}
510
511static const struct i2c_device_id da7210_i2c_id[] = {
512 { "da7210", 0 },
513 { }
514};
515MODULE_DEVICE_TABLE(i2c, da7210_i2c_id);
516
517/* I2C codec control layer */
518static struct i2c_driver da7210_i2c_driver = {
519 .driver = {
520 .name = "DA7210 I2C Codec",
521 .owner = THIS_MODULE,
522 },
523 .probe = da7210_i2c_probe,
524 .remove = __devexit_p(da7210_i2c_remove),
525 .id_table = da7210_i2c_id,
526};
527#endif
528
529static int da7210_probe(struct platform_device *pdev)
530{
531 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
532 struct snd_soc_codec *codec;
533 int ret;
534
535 if (!da7210_codec) {
536 dev_err(&pdev->dev, "Codec device not registered\n");
537 return -ENODEV;
538 }
539
540 socdev->card->codec = da7210_codec;
541 codec = da7210_codec;
542
543 /* Register pcms */
544 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
545 if (ret < 0)
546 goto pcm_err;
547
548 dev_info(&pdev->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION);
549
550pcm_err:
551 return ret;
552}
553
554static int da7210_remove(struct platform_device *pdev)
555{
556 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
557
558 snd_soc_free_pcms(socdev);
559 snd_soc_dapm_free(socdev);
560
561 return 0;
562}
563
564struct snd_soc_codec_device soc_codec_dev_da7210 = {
565 .probe = da7210_probe,
566 .remove = da7210_remove,
567};
568EXPORT_SYMBOL_GPL(soc_codec_dev_da7210);
569
570static int __init da7210_modinit(void)
571{
572 int ret = 0;
573#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
574 ret = i2c_add_driver(&da7210_i2c_driver);
575#endif
576 return ret;
577}
578module_init(da7210_modinit);
579
580static void __exit da7210_exit(void)
581{
582#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
583 i2c_del_driver(&da7210_i2c_driver);
584#endif
585}
586module_exit(da7210_exit);
587
588MODULE_DESCRIPTION("ASoC DA7210 driver");
589MODULE_AUTHOR("David Chen, Kuninori Morimoto");
590MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/da7210.h b/sound/soc/codecs/da7210.h
new file mode 100644
index 000000000000..390d621eb742
--- /dev/null
+++ b/sound/soc/codecs/da7210.h
@@ -0,0 +1,24 @@
1/*
2 * da7210.h -- audio driver for da7210
3 *
4 * Copyright (c) 2009 Dialog Semiconductor
5 * Written by David Chen <Dajun.chen@diasemi.com>
6 *
7 * Copyright (C) 2009 Renesas Solutions Corp.
8 * Cleanups by Kuninori Morimoto <morimoto.kuninori@renesas.com>
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 *
15 */
16
17#ifndef _DA7210_H
18#define _DA7210_H
19
20extern struct snd_soc_dai da7210_dai;
21extern struct snd_soc_codec_device soc_codec_dev_da7210;
22
23#endif
24
diff --git a/sound/soc/codecs/pcm3008.c b/sound/soc/codecs/pcm3008.c
index 5cda9e6b5a74..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>
@@ -90,13 +91,6 @@ static int pcm3008_soc_probe(struct platform_device *pdev)
90 goto pcm_err; 91 goto pcm_err;
91 } 92 }
92 93
93 /* Register Card. */
94 ret = snd_soc_init_card(socdev);
95 if (ret < 0) {
96 printk(KERN_ERR "pcm3008: failed to register card\n");
97 goto card_err;
98 }
99
100 /* DEM1 DEM0 DE-EMPHASIS_MODE 94 /* DEM1 DEM0 DE-EMPHASIS_MODE
101 * Low Low De-emphasis 44.1 kHz ON 95 * Low Low De-emphasis 44.1 kHz ON
102 * Low High De-emphasis OFF 96 * Low High De-emphasis OFF
@@ -136,8 +130,6 @@ static int pcm3008_soc_probe(struct platform_device *pdev)
136 130
137gpio_err: 131gpio_err:
138 pcm3008_gpio_free(setup); 132 pcm3008_gpio_free(setup);
139card_err:
140 snd_soc_free_pcms(socdev);
141pcm_err: 133pcm_err:
142 kfree(socdev->card->codec); 134 kfree(socdev->card->codec);
143 135
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c
index c550750c79c0..29d0906a924a 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>
@@ -210,7 +211,6 @@ static int ssm2602_add_widgets(struct snd_soc_codec *codec)
210 211
211 snd_soc_dapm_add_routes(codec, audio_conn, ARRAY_SIZE(audio_conn)); 212 snd_soc_dapm_add_routes(codec, audio_conn, ARRAY_SIZE(audio_conn));
212 213
213 snd_soc_dapm_new_widgets(codec);
214 return 0; 214 return 0;
215} 215}
216 216
@@ -613,17 +613,9 @@ static int ssm2602_init(struct snd_soc_device *socdev)
613 snd_soc_add_controls(codec, ssm2602_snd_controls, 613 snd_soc_add_controls(codec, ssm2602_snd_controls,
614 ARRAY_SIZE(ssm2602_snd_controls)); 614 ARRAY_SIZE(ssm2602_snd_controls));
615 ssm2602_add_widgets(codec); 615 ssm2602_add_widgets(codec);
616 ret = snd_soc_init_card(socdev);
617 if (ret < 0) {
618 pr_err("ssm2602: failed to register card\n");
619 goto card_err;
620 }
621 616
622 return ret; 617 return ret;
623 618
624card_err:
625 snd_soc_free_pcms(socdev);
626 snd_soc_dapm_free(socdev);
627pcm_err: 619pcm_err:
628 kfree(codec->reg_cache); 620 kfree(codec->reg_cache);
629 return ret; 621 return ret;
diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c
index befc6488c39a..3293629dcb3b 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>
@@ -191,6 +192,7 @@ static int ac97_analog_prepare(struct snd_pcm_substream *substream,
191 vra = stac9766_ac97_read(codec, AC97_EXTENDED_STATUS); 192 vra = stac9766_ac97_read(codec, AC97_EXTENDED_STATUS);
192 193
193 vra |= 0x1; /* enable variable rate audio */ 194 vra |= 0x1; /* enable variable rate audio */
195 vra &= ~0x4; /* disable SPDIF output */
194 196
195 stac9766_ac97_write(codec, AC97_EXTENDED_STATUS, vra); 197 stac9766_ac97_write(codec, AC97_EXTENDED_STATUS, vra);
196 198
@@ -221,22 +223,6 @@ static int ac97_digital_prepare(struct snd_pcm_substream *substream,
221 return stac9766_ac97_write(codec, reg, runtime->rate); 223 return stac9766_ac97_write(codec, reg, runtime->rate);
222} 224}
223 225
224static int ac97_digital_trigger(struct snd_pcm_substream *substream,
225 int cmd, struct snd_soc_dai *dai)
226{
227 struct snd_soc_codec *codec = dai->codec;
228 unsigned short vra;
229
230 switch (cmd) {
231 case SNDRV_PCM_TRIGGER_STOP:
232 vra = stac9766_ac97_read(codec, AC97_EXTENDED_STATUS);
233 vra &= !0x04;
234 stac9766_ac97_write(codec, AC97_EXTENDED_STATUS, vra);
235 break;
236 }
237 return 0;
238}
239
240static int stac9766_set_bias_level(struct snd_soc_codec *codec, 226static int stac9766_set_bias_level(struct snd_soc_codec *codec,
241 enum snd_soc_bias_level level) 227 enum snd_soc_bias_level level)
242{ 228{
@@ -315,7 +301,6 @@ static struct snd_soc_dai_ops stac9766_dai_ops_analog = {
315 301
316static struct snd_soc_dai_ops stac9766_dai_ops_digital = { 302static struct snd_soc_dai_ops stac9766_dai_ops_digital = {
317 .prepare = ac97_digital_prepare, 303 .prepare = ac97_digital_prepare,
318 .trigger = ac97_digital_trigger,
319}; 304};
320 305
321struct snd_soc_dai stac9766_dai[] = { 306struct snd_soc_dai stac9766_dai[] = {
@@ -418,9 +403,6 @@ static int stac9766_codec_probe(struct platform_device *pdev)
418 snd_soc_add_controls(codec, stac9766_snd_ac97_controls, 403 snd_soc_add_controls(codec, stac9766_snd_ac97_controls,
419 ARRAY_SIZE(stac9766_snd_ac97_controls)); 404 ARRAY_SIZE(stac9766_snd_ac97_controls));
420 405
421 ret = snd_soc_init_card(socdev);
422 if (ret < 0)
423 goto reset_err;
424 return 0; 406 return 0;
425 407
426reset_err: 408reset_err:
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index 90a0264f7538..776b79cde904 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>
@@ -85,7 +86,7 @@ static int tlv320aic23_write(struct snd_soc_codec *codec, unsigned int reg,
85 * of data into val 86 * of data into val
86 */ 87 */
87 88
88 if ((reg < 0 || reg > 9) && (reg != 15)) { 89 if (reg > 9 && reg != 15) {
89 printk(KERN_WARNING "%s Invalid register R%u\n", __func__, reg); 90 printk(KERN_WARNING "%s Invalid register R%u\n", __func__, reg);
90 return -1; 91 return -1;
91 } 92 }
@@ -395,7 +396,6 @@ static int tlv320aic23_add_widgets(struct snd_soc_codec *codec)
395 /* set up audio path interconnects */ 396 /* set up audio path interconnects */
396 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); 397 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
397 398
398 snd_soc_dapm_new_widgets(codec);
399 return 0; 399 return 0;
400} 400}
401 401
@@ -628,7 +628,7 @@ static int tlv320aic23_resume(struct platform_device *pdev)
628 u16 reg; 628 u16 reg;
629 629
630 /* Sync reg_cache with the hardware */ 630 /* Sync reg_cache with the hardware */
631 for (reg = 0; reg < TLV320AIC23_RESET; reg++) { 631 for (reg = 0; reg <= TLV320AIC23_ACTIVE; reg++) {
632 u16 val = tlv320aic23_read_reg_cache(codec, reg); 632 u16 val = tlv320aic23_read_reg_cache(codec, reg);
633 tlv320aic23_write(codec, reg, val); 633 tlv320aic23_write(codec, reg, val);
634 } 634 }
@@ -706,17 +706,9 @@ static int tlv320aic23_init(struct snd_soc_device *socdev)
706 snd_soc_add_controls(codec, tlv320aic23_snd_controls, 706 snd_soc_add_controls(codec, tlv320aic23_snd_controls,
707 ARRAY_SIZE(tlv320aic23_snd_controls)); 707 ARRAY_SIZE(tlv320aic23_snd_controls));
708 tlv320aic23_add_widgets(codec); 708 tlv320aic23_add_widgets(codec);
709 ret = snd_soc_init_card(socdev);
710 if (ret < 0) {
711 printk(KERN_ERR "tlv320aic23: failed to register card\n");
712 goto card_err;
713 }
714 709
715 return ret; 710 return ret;
716 711
717card_err:
718 snd_soc_free_pcms(socdev);
719 snd_soc_dapm_free(socdev);
720pcm_err: 712pcm_err:
721 kfree(codec->reg_cache); 713 kfree(codec->reg_cache);
722 return ret; 714 return ret;
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c
index 3387d9e736ea..b5b7d6a03844 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>
@@ -356,18 +357,7 @@ static int aic26_probe(struct platform_device *pdev)
356 ARRAY_SIZE(aic26_snd_controls)); 357 ARRAY_SIZE(aic26_snd_controls));
357 WARN_ON(err < 0); 358 WARN_ON(err < 0);
358 359
359 /* CODEC is setup, we can register the card now */
360 dev_dbg(&pdev->dev, "Registering card\n");
361 ret = snd_soc_init_card(socdev);
362 if (ret < 0) {
363 dev_err(&pdev->dev, "aic26: failed to register card\n");
364 goto card_err;
365 }
366 return 0; 360 return 0;
367
368 card_err:
369 snd_soc_free_pcms(socdev);
370 return ret;
371} 361}
372 362
373static int aic26_remove(struct platform_device *pdev) 363static int aic26_remove(struct platform_device *pdev)
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 3395cf945d56..4a6d56c3fed9 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -39,6 +39,7 @@
39#include <linux/pm.h> 39#include <linux/pm.h>
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/slab.h>
42#include <sound/core.h> 43#include <sound/core.h>
43#include <sound/pcm.h> 44#include <sound/pcm.h>
44#include <sound/pcm_params.h> 45#include <sound/pcm_params.h>
@@ -753,7 +754,6 @@ static int aic3x_add_widgets(struct snd_soc_codec *codec)
753 /* set up audio path interconnects */ 754 /* set up audio path interconnects */
754 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); 755 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
755 756
756 snd_soc_dapm_new_widgets(codec);
757 return 0; 757 return 0;
758} 758}
759 759
@@ -766,9 +766,10 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
766 struct snd_soc_codec *codec = socdev->card->codec; 766 struct snd_soc_codec *codec = socdev->card->codec;
767 struct aic3x_priv *aic3x = codec->private_data; 767 struct aic3x_priv *aic3x = codec->private_data;
768 int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0; 768 int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0;
769 u8 data, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1; 769 u8 data, j, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1;
770 u16 pll_d = 1; 770 u16 d, pll_d = 1;
771 u8 reg; 771 u8 reg;
772 int clk;
772 773
773 /* select data word length */ 774 /* select data word length */
774 data = 775 data =
@@ -834,48 +835,70 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
834 if (bypass_pll) 835 if (bypass_pll)
835 return 0; 836 return 0;
836 837
837 /* Use PLL 838 /* Use PLL, compute apropriate setup for j, d, r and p, the closest
838 * find an apropriate setup for j, d, r and p by iterating over 839 * one wins the game. Try with d==0 first, next with d!=0.
839 * p and r - j and d are calculated for each fraction. 840 * Constraints for j are according to the datasheet.
840 * Up to 128 values are probed, the closest one wins the game.
841 * The sysclk is divided by 1000 to prevent integer overflows. 841 * The sysclk is divided by 1000 to prevent integer overflows.
842 */ 842 */
843
843 codec_clk = (2048 * fsref) / (aic3x->sysclk / 1000); 844 codec_clk = (2048 * fsref) / (aic3x->sysclk / 1000);
844 845
845 for (r = 1; r <= 16; r++) 846 for (r = 1; r <= 16; r++)
846 for (p = 1; p <= 8; p++) { 847 for (p = 1; p <= 8; p++) {
847 int clk, tmp = (codec_clk * pll_r * 10) / pll_p; 848 for (j = 4; j <= 55; j++) {
848 u8 j = tmp / 10000; 849 /* This is actually 1000*((j+(d/10000))*r)/p
849 u16 d = tmp % 10000; 850 * The term had to be converted to get
851 * rid of the division by 10000; d = 0 here
852 */
853 int tmp_clk = (1000 * j * r) / p;
854
855 /* Check whether this values get closer than
856 * the best ones we had before
857 */
858 if (abs(codec_clk - tmp_clk) <
859 abs(codec_clk - last_clk)) {
860 pll_j = j; pll_d = 0;
861 pll_r = r; pll_p = p;
862 last_clk = tmp_clk;
863 }
864
865 /* Early exit for exact matches */
866 if (tmp_clk == codec_clk)
867 goto found;
868 }
869 }
850 870
851 if (j > 63) 871 /* try with d != 0 */
852 continue; 872 for (p = 1; p <= 8; p++) {
873 j = codec_clk * p / 1000;
853 874
854 if (d != 0 && aic3x->sysclk < 10000000) 875 if (j < 4 || j > 11)
855 continue; 876 continue;
856 877
857 /* This is actually 1000 * ((j + (d/10000)) * r) / p 878 /* do not use codec_clk here since we'd loose precision */
858 * The term had to be converted to get rid of the 879 d = ((2048 * p * fsref) - j * aic3x->sysclk)
859 * division by 10000 */ 880 * 100 / (aic3x->sysclk/100);
860 clk = ((10000 * j * r) + (d * r)) / (10 * p);
861 881
862 /* check whether this values get closer than the best 882 clk = (10000 * j + d) / (10 * p);
863 * ones we had before */
864 if (abs(codec_clk - clk) < abs(codec_clk - last_clk)) {
865 pll_j = j; pll_d = d; pll_r = r; pll_p = p;
866 last_clk = clk;
867 }
868 883
869 /* Early exit for exact matches */ 884 /* check whether this values get closer than the best
870 if (clk == codec_clk) 885 * ones we had before */
871 break; 886 if (abs(codec_clk - clk) < abs(codec_clk - last_clk)) {
887 pll_j = j; pll_d = d; pll_r = 1; pll_p = p;
888 last_clk = clk;
872 } 889 }
873 890
891 /* Early exit for exact matches */
892 if (clk == codec_clk)
893 goto found;
894 }
895
874 if (last_clk == 0) { 896 if (last_clk == 0) {
875 printk(KERN_ERR "%s(): unable to setup PLL\n", __func__); 897 printk(KERN_ERR "%s(): unable to setup PLL\n", __func__);
876 return -EINVAL; 898 return -EINVAL;
877 } 899 }
878 900
901found:
879 data = aic3x_read_reg_cache(codec, AIC3X_PLL_PROGA_REG); 902 data = aic3x_read_reg_cache(codec, AIC3X_PLL_PROGA_REG);
880 aic3x_write(codec, AIC3X_PLL_PROGA_REG, data | (pll_p << PLLP_SHIFT)); 903 aic3x_write(codec, AIC3X_PLL_PROGA_REG, data | (pll_p << PLLP_SHIFT));
881 aic3x_write(codec, AIC3X_OVRF_STATUS_AND_PLLR_REG, pll_r << PLLR_SHIFT); 904 aic3x_write(codec, AIC3X_OVRF_STATUS_AND_PLLR_REG, pll_r << PLLR_SHIFT);
@@ -1405,18 +1428,8 @@ static int aic3x_probe(struct platform_device *pdev)
1405 1428
1406 aic3x_add_widgets(codec); 1429 aic3x_add_widgets(codec);
1407 1430
1408 ret = snd_soc_init_card(socdev);
1409 if (ret < 0) {
1410 printk(KERN_ERR "aic3x: failed to register card\n");
1411 goto card_err;
1412 }
1413
1414 return ret; 1431 return ret;
1415 1432
1416card_err:
1417 snd_soc_free_pcms(socdev);
1418 snd_soc_dapm_free(socdev);
1419
1420pcm_err: 1433pcm_err:
1421 kfree(codec->reg_cache); 1434 kfree(codec->reg_cache);
1422 return ret; 1435 return ret;
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
new file mode 100644
index 000000000000..d1e0e81ef30c
--- /dev/null
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -0,0 +1,1423 @@
1/*
2 * ALSA SoC Texas Instruments TLV320DAC33 codec driver
3 *
4 * Author: Peter Ujfalusi <peter.ujfalusi@nokia.com>
5 *
6 * Copyright: (C) 2009 Nokia Corporation
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#include <linux/module.h>
25#include <linux/moduleparam.h>
26#include <linux/init.h>
27#include <linux/delay.h>
28#include <linux/pm.h>
29#include <linux/i2c.h>
30#include <linux/platform_device.h>
31#include <linux/interrupt.h>
32#include <linux/gpio.h>
33#include <linux/regulator/consumer.h>
34#include <linux/slab.h>
35#include <sound/core.h>
36#include <sound/pcm.h>
37#include <sound/pcm_params.h>
38#include <sound/soc.h>
39#include <sound/soc-dapm.h>
40#include <sound/initval.h>
41#include <sound/tlv.h>
42
43#include <sound/tlv320dac33-plat.h>
44#include "tlv320dac33.h"
45
46#define DAC33_BUFFER_SIZE_BYTES 24576 /* bytes, 12288 16 bit words,
47 * 6144 stereo */
48#define DAC33_BUFFER_SIZE_SAMPLES 6144
49
50#define NSAMPLE_MAX 5700
51
52#define LATENCY_TIME_MS 20
53
54static struct snd_soc_codec *tlv320dac33_codec;
55
56enum dac33_state {
57 DAC33_IDLE = 0,
58 DAC33_PREFILL,
59 DAC33_PLAYBACK,
60 DAC33_FLUSH,
61};
62
63enum dac33_fifo_modes {
64 DAC33_FIFO_BYPASS = 0,
65 DAC33_FIFO_MODE1,
66 DAC33_FIFO_MODE7,
67 DAC33_FIFO_LAST_MODE,
68};
69
70#define DAC33_NUM_SUPPLIES 3
71static const char *dac33_supply_names[DAC33_NUM_SUPPLIES] = {
72 "AVDD",
73 "DVDD",
74 "IOVDD",
75};
76
77struct tlv320dac33_priv {
78 struct mutex mutex;
79 struct workqueue_struct *dac33_wq;
80 struct work_struct work;
81 struct snd_soc_codec codec;
82 struct regulator_bulk_data supplies[DAC33_NUM_SUPPLIES];
83 int power_gpio;
84 int chip_power;
85 int irq;
86 unsigned int refclk;
87
88 unsigned int alarm_threshold; /* set to be half of LATENCY_TIME_MS */
89 unsigned int nsample_min; /* nsample should not be lower than
90 * this */
91 unsigned int nsample_max; /* nsample should not be higher than
92 * this */
93 enum dac33_fifo_modes fifo_mode;/* FIFO mode selection */
94 unsigned int nsample; /* burst read amount from host */
95 u8 burst_bclkdiv; /* BCLK divider value in burst mode */
96
97 enum dac33_state state;
98};
99
100static const u8 dac33_reg[DAC33_CACHEREGNUM] = {
1010x00, 0x00, 0x00, 0x00, /* 0x00 - 0x03 */
1020x00, 0x00, 0x00, 0x00, /* 0x04 - 0x07 */
1030x00, 0x00, 0x00, 0x00, /* 0x08 - 0x0b */
1040x00, 0x00, 0x00, 0x00, /* 0x0c - 0x0f */
1050x00, 0x00, 0x00, 0x00, /* 0x10 - 0x13 */
1060x00, 0x00, 0x00, 0x00, /* 0x14 - 0x17 */
1070x00, 0x00, 0x00, 0x00, /* 0x18 - 0x1b */
1080x00, 0x00, 0x00, 0x00, /* 0x1c - 0x1f */
1090x00, 0x00, 0x00, 0x00, /* 0x20 - 0x23 */
1100x00, 0x00, 0x00, 0x00, /* 0x24 - 0x27 */
1110x00, 0x00, 0x00, 0x00, /* 0x28 - 0x2b */
1120x00, 0x00, 0x00, 0x80, /* 0x2c - 0x2f */
1130x80, 0x00, 0x00, 0x00, /* 0x30 - 0x33 */
1140x00, 0x00, 0x00, 0x00, /* 0x34 - 0x37 */
1150x00, 0x00, /* 0x38 - 0x39 */
116/* Registers 0x3a - 0x3f are reserved */
117 0x00, 0x00, /* 0x3a - 0x3b */
1180x00, 0x00, 0x00, 0x00, /* 0x3c - 0x3f */
119
1200x00, 0x00, 0x00, 0x00, /* 0x40 - 0x43 */
1210x00, 0x80, /* 0x44 - 0x45 */
122/* Registers 0x46 - 0x47 are reserved */
123 0x80, 0x80, /* 0x46 - 0x47 */
124
1250x80, 0x00, 0x00, /* 0x48 - 0x4a */
126/* Registers 0x4b - 0x7c are reserved */
127 0x00, /* 0x4b */
1280x00, 0x00, 0x00, 0x00, /* 0x4c - 0x4f */
1290x00, 0x00, 0x00, 0x00, /* 0x50 - 0x53 */
1300x00, 0x00, 0x00, 0x00, /* 0x54 - 0x57 */
1310x00, 0x00, 0x00, 0x00, /* 0x58 - 0x5b */
1320x00, 0x00, 0x00, 0x00, /* 0x5c - 0x5f */
1330x00, 0x00, 0x00, 0x00, /* 0x60 - 0x63 */
1340x00, 0x00, 0x00, 0x00, /* 0x64 - 0x67 */
1350x00, 0x00, 0x00, 0x00, /* 0x68 - 0x6b */
1360x00, 0x00, 0x00, 0x00, /* 0x6c - 0x6f */
1370x00, 0x00, 0x00, 0x00, /* 0x70 - 0x73 */
1380x00, 0x00, 0x00, 0x00, /* 0x74 - 0x77 */
1390x00, 0x00, 0x00, 0x00, /* 0x78 - 0x7b */
1400x00, /* 0x7c */
141
142 0xda, 0x33, 0x03, /* 0x7d - 0x7f */
143};
144
145/* Register read and write */
146static inline unsigned int dac33_read_reg_cache(struct snd_soc_codec *codec,
147 unsigned reg)
148{
149 u8 *cache = codec->reg_cache;
150 if (reg >= DAC33_CACHEREGNUM)
151 return 0;
152
153 return cache[reg];
154}
155
156static inline void dac33_write_reg_cache(struct snd_soc_codec *codec,
157 u8 reg, u8 value)
158{
159 u8 *cache = codec->reg_cache;
160 if (reg >= DAC33_CACHEREGNUM)
161 return;
162
163 cache[reg] = value;
164}
165
166static int dac33_read(struct snd_soc_codec *codec, unsigned int reg,
167 u8 *value)
168{
169 struct tlv320dac33_priv *dac33 = codec->private_data;
170 int val;
171
172 *value = reg & 0xff;
173
174 /* If powered off, return the cached value */
175 if (dac33->chip_power) {
176 val = i2c_smbus_read_byte_data(codec->control_data, value[0]);
177 if (val < 0) {
178 dev_err(codec->dev, "Read failed (%d)\n", val);
179 value[0] = dac33_read_reg_cache(codec, reg);
180 } else {
181 value[0] = val;
182 dac33_write_reg_cache(codec, reg, val);
183 }
184 } else {
185 value[0] = dac33_read_reg_cache(codec, reg);
186 }
187
188 return 0;
189}
190
191static int dac33_write(struct snd_soc_codec *codec, unsigned int reg,
192 unsigned int value)
193{
194 struct tlv320dac33_priv *dac33 = codec->private_data;
195 u8 data[2];
196 int ret = 0;
197
198 /*
199 * data is
200 * D15..D8 dac33 register offset
201 * D7...D0 register data
202 */
203 data[0] = reg & 0xff;
204 data[1] = value & 0xff;
205
206 dac33_write_reg_cache(codec, data[0], data[1]);
207 if (dac33->chip_power) {
208 ret = codec->hw_write(codec->control_data, data, 2);
209 if (ret != 2)
210 dev_err(codec->dev, "Write failed (%d)\n", ret);
211 else
212 ret = 0;
213 }
214
215 return ret;
216}
217
218static int dac33_write_locked(struct snd_soc_codec *codec, unsigned int reg,
219 unsigned int value)
220{
221 struct tlv320dac33_priv *dac33 = codec->private_data;
222 int ret;
223
224 mutex_lock(&dac33->mutex);
225 ret = dac33_write(codec, reg, value);
226 mutex_unlock(&dac33->mutex);
227
228 return ret;
229}
230
231#define DAC33_I2C_ADDR_AUTOINC 0x80
232static int dac33_write16(struct snd_soc_codec *codec, unsigned int reg,
233 unsigned int value)
234{
235 struct tlv320dac33_priv *dac33 = codec->private_data;
236 u8 data[3];
237 int ret = 0;
238
239 /*
240 * data is
241 * D23..D16 dac33 register offset
242 * D15..D8 register data MSB
243 * D7...D0 register data LSB
244 */
245 data[0] = reg & 0xff;
246 data[1] = (value >> 8) & 0xff;
247 data[2] = value & 0xff;
248
249 dac33_write_reg_cache(codec, data[0], data[1]);
250 dac33_write_reg_cache(codec, data[0] + 1, data[2]);
251
252 if (dac33->chip_power) {
253 /* We need to set autoincrement mode for 16 bit writes */
254 data[0] |= DAC33_I2C_ADDR_AUTOINC;
255 ret = codec->hw_write(codec->control_data, data, 3);
256 if (ret != 3)
257 dev_err(codec->dev, "Write failed (%d)\n", ret);
258 else
259 ret = 0;
260 }
261
262 return ret;
263}
264
265static void dac33_restore_regs(struct snd_soc_codec *codec)
266{
267 struct tlv320dac33_priv *dac33 = codec->private_data;
268 u8 *cache = codec->reg_cache;
269 u8 data[2];
270 int i, ret;
271
272 if (!dac33->chip_power)
273 return;
274
275 for (i = DAC33_PWR_CTRL; i <= DAC33_INTP_CTRL_B; i++) {
276 data[0] = i;
277 data[1] = cache[i];
278 /* Skip the read only registers */
279 if ((i >= DAC33_INT_OSC_STATUS &&
280 i <= DAC33_INT_OSC_FREQ_RAT_READ_B) ||
281 (i >= DAC33_FIFO_WPTR_MSB && i <= DAC33_FIFO_IRQ_FLAG) ||
282 i == DAC33_DAC_STATUS_FLAGS ||
283 i == DAC33_SRC_EST_REF_CLK_RATIO_A ||
284 i == DAC33_SRC_EST_REF_CLK_RATIO_B)
285 continue;
286 ret = codec->hw_write(codec->control_data, data, 2);
287 if (ret != 2)
288 dev_err(codec->dev, "Write failed (%d)\n", ret);
289 }
290 for (i = DAC33_LDAC_PWR_CTRL; i <= DAC33_LINEL_TO_LLO_VOL; i++) {
291 data[0] = i;
292 data[1] = cache[i];
293 ret = codec->hw_write(codec->control_data, data, 2);
294 if (ret != 2)
295 dev_err(codec->dev, "Write failed (%d)\n", ret);
296 }
297 for (i = DAC33_LINER_TO_RLO_VOL; i <= DAC33_OSC_TRIM; i++) {
298 data[0] = i;
299 data[1] = cache[i];
300 ret = codec->hw_write(codec->control_data, data, 2);
301 if (ret != 2)
302 dev_err(codec->dev, "Write failed (%d)\n", ret);
303 }
304}
305
306static inline void dac33_soft_power(struct snd_soc_codec *codec, int power)
307{
308 u8 reg;
309
310 reg = dac33_read_reg_cache(codec, DAC33_PWR_CTRL);
311 if (power)
312 reg |= DAC33_PDNALLB;
313 else
314 reg &= ~DAC33_PDNALLB;
315 dac33_write(codec, DAC33_PWR_CTRL, reg);
316}
317
318static int dac33_hard_power(struct snd_soc_codec *codec, int power)
319{
320 struct tlv320dac33_priv *dac33 = codec->private_data;
321 int ret;
322
323 mutex_lock(&dac33->mutex);
324 if (power) {
325 ret = regulator_bulk_enable(ARRAY_SIZE(dac33->supplies),
326 dac33->supplies);
327 if (ret != 0) {
328 dev_err(codec->dev,
329 "Failed to enable supplies: %d\n", ret);
330 goto exit;
331 }
332
333 if (dac33->power_gpio >= 0)
334 gpio_set_value(dac33->power_gpio, 1);
335
336 dac33->chip_power = 1;
337
338 /* Restore registers */
339 dac33_restore_regs(codec);
340
341 dac33_soft_power(codec, 1);
342 } else {
343 dac33_soft_power(codec, 0);
344 if (dac33->power_gpio >= 0)
345 gpio_set_value(dac33->power_gpio, 0);
346
347 ret = regulator_bulk_disable(ARRAY_SIZE(dac33->supplies),
348 dac33->supplies);
349 if (ret != 0) {
350 dev_err(codec->dev,
351 "Failed to disable supplies: %d\n", ret);
352 goto exit;
353 }
354
355 dac33->chip_power = 0;
356 }
357
358exit:
359 mutex_unlock(&dac33->mutex);
360 return ret;
361}
362
363static int dac33_get_nsample(struct snd_kcontrol *kcontrol,
364 struct snd_ctl_elem_value *ucontrol)
365{
366 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
367 struct tlv320dac33_priv *dac33 = codec->private_data;
368
369 ucontrol->value.integer.value[0] = dac33->nsample;
370
371 return 0;
372}
373
374static int dac33_set_nsample(struct snd_kcontrol *kcontrol,
375 struct snd_ctl_elem_value *ucontrol)
376{
377 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
378 struct tlv320dac33_priv *dac33 = codec->private_data;
379 int ret = 0;
380
381 if (dac33->nsample == ucontrol->value.integer.value[0])
382 return 0;
383
384 if (ucontrol->value.integer.value[0] < dac33->nsample_min ||
385 ucontrol->value.integer.value[0] > dac33->nsample_max)
386 ret = -EINVAL;
387 else
388 dac33->nsample = ucontrol->value.integer.value[0];
389
390 return ret;
391}
392
393static int dac33_get_fifo_mode(struct snd_kcontrol *kcontrol,
394 struct snd_ctl_elem_value *ucontrol)
395{
396 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
397 struct tlv320dac33_priv *dac33 = codec->private_data;
398
399 ucontrol->value.integer.value[0] = dac33->fifo_mode;
400
401 return 0;
402}
403
404static int dac33_set_fifo_mode(struct snd_kcontrol *kcontrol,
405 struct snd_ctl_elem_value *ucontrol)
406{
407 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
408 struct tlv320dac33_priv *dac33 = codec->private_data;
409 int ret = 0;
410
411 if (dac33->fifo_mode == ucontrol->value.integer.value[0])
412 return 0;
413 /* Do not allow changes while stream is running*/
414 if (codec->active)
415 return -EPERM;
416
417 if (ucontrol->value.integer.value[0] < 0 ||
418 ucontrol->value.integer.value[0] >= DAC33_FIFO_LAST_MODE)
419 ret = -EINVAL;
420 else
421 dac33->fifo_mode = ucontrol->value.integer.value[0];
422
423 return ret;
424}
425
426/* Codec operation modes */
427static const char *dac33_fifo_mode_texts[] = {
428 "Bypass", "Mode 1", "Mode 7"
429};
430
431static const struct soc_enum dac33_fifo_mode_enum =
432 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(dac33_fifo_mode_texts),
433 dac33_fifo_mode_texts);
434
435/*
436 * DACL/R digital volume control:
437 * from 0 dB to -63.5 in 0.5 dB steps
438 * Need to be inverted later on:
439 * 0x00 == 0 dB
440 * 0x7f == -63.5 dB
441 */
442static DECLARE_TLV_DB_SCALE(dac_digivol_tlv, -6350, 50, 0);
443
444static const struct snd_kcontrol_new dac33_snd_controls[] = {
445 SOC_DOUBLE_R_TLV("DAC Digital Playback Volume",
446 DAC33_LDAC_DIG_VOL_CTRL, DAC33_RDAC_DIG_VOL_CTRL,
447 0, 0x7f, 1, dac_digivol_tlv),
448 SOC_DOUBLE_R("DAC Digital Playback Switch",
449 DAC33_LDAC_DIG_VOL_CTRL, DAC33_RDAC_DIG_VOL_CTRL, 7, 1, 1),
450 SOC_DOUBLE_R("Line to Line Out Volume",
451 DAC33_LINEL_TO_LLO_VOL, DAC33_LINER_TO_RLO_VOL, 0, 127, 1),
452};
453
454static const struct snd_kcontrol_new dac33_nsample_snd_controls[] = {
455 SOC_SINGLE_EXT("nSample", 0, 0, 5900, 0,
456 dac33_get_nsample, dac33_set_nsample),
457 SOC_ENUM_EXT("FIFO Mode", dac33_fifo_mode_enum,
458 dac33_get_fifo_mode, dac33_set_fifo_mode),
459};
460
461/* Analog bypass */
462static const struct snd_kcontrol_new dac33_dapm_abypassl_control =
463 SOC_DAPM_SINGLE("Switch", DAC33_LINEL_TO_LLO_VOL, 7, 1, 1);
464
465static const struct snd_kcontrol_new dac33_dapm_abypassr_control =
466 SOC_DAPM_SINGLE("Switch", DAC33_LINER_TO_RLO_VOL, 7, 1, 1);
467
468static const struct snd_soc_dapm_widget dac33_dapm_widgets[] = {
469 SND_SOC_DAPM_OUTPUT("LEFT_LO"),
470 SND_SOC_DAPM_OUTPUT("RIGHT_LO"),
471
472 SND_SOC_DAPM_INPUT("LINEL"),
473 SND_SOC_DAPM_INPUT("LINER"),
474
475 SND_SOC_DAPM_DAC("DACL", "Left Playback", DAC33_LDAC_PWR_CTRL, 2, 0),
476 SND_SOC_DAPM_DAC("DACR", "Right Playback", DAC33_RDAC_PWR_CTRL, 2, 0),
477
478 /* Analog bypass */
479 SND_SOC_DAPM_SWITCH("Analog Left Bypass", SND_SOC_NOPM, 0, 0,
480 &dac33_dapm_abypassl_control),
481 SND_SOC_DAPM_SWITCH("Analog Right Bypass", SND_SOC_NOPM, 0, 0,
482 &dac33_dapm_abypassr_control),
483
484 SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Left Amp Power",
485 DAC33_OUT_AMP_PWR_CTRL, 6, 3, 3, 0),
486 SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Right Amp Power",
487 DAC33_OUT_AMP_PWR_CTRL, 4, 3, 3, 0),
488};
489
490static const struct snd_soc_dapm_route audio_map[] = {
491 /* Analog bypass */
492 {"Analog Left Bypass", "Switch", "LINEL"},
493 {"Analog Right Bypass", "Switch", "LINER"},
494
495 {"Output Left Amp Power", NULL, "DACL"},
496 {"Output Right Amp Power", NULL, "DACR"},
497
498 {"Output Left Amp Power", NULL, "Analog Left Bypass"},
499 {"Output Right Amp Power", NULL, "Analog Right Bypass"},
500
501 /* output */
502 {"LEFT_LO", NULL, "Output Left Amp Power"},
503 {"RIGHT_LO", NULL, "Output Right Amp Power"},
504};
505
506static int dac33_add_widgets(struct snd_soc_codec *codec)
507{
508 snd_soc_dapm_new_controls(codec, dac33_dapm_widgets,
509 ARRAY_SIZE(dac33_dapm_widgets));
510
511 /* set up audio path interconnects */
512 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
513
514 return 0;
515}
516
517static int dac33_set_bias_level(struct snd_soc_codec *codec,
518 enum snd_soc_bias_level level)
519{
520 int ret;
521
522 switch (level) {
523 case SND_SOC_BIAS_ON:
524 dac33_soft_power(codec, 1);
525 break;
526 case SND_SOC_BIAS_PREPARE:
527 break;
528 case SND_SOC_BIAS_STANDBY:
529 if (codec->bias_level == SND_SOC_BIAS_OFF) {
530 ret = dac33_hard_power(codec, 1);
531 if (ret != 0)
532 return ret;
533 }
534
535 dac33_soft_power(codec, 0);
536 break;
537 case SND_SOC_BIAS_OFF:
538 ret = dac33_hard_power(codec, 0);
539 if (ret != 0)
540 return ret;
541
542 break;
543 }
544 codec->bias_level = level;
545
546 return 0;
547}
548
549static inline void dac33_prefill_handler(struct tlv320dac33_priv *dac33)
550{
551 struct snd_soc_codec *codec;
552
553 codec = &dac33->codec;
554
555 switch (dac33->fifo_mode) {
556 case DAC33_FIFO_MODE1:
557 dac33_write16(codec, DAC33_NSAMPLE_MSB,
558 DAC33_THRREG(dac33->nsample));
559 dac33_write16(codec, DAC33_PREFILL_MSB,
560 DAC33_THRREG(dac33->alarm_threshold));
561 break;
562 case DAC33_FIFO_MODE7:
563 dac33_write16(codec, DAC33_PREFILL_MSB,
564 DAC33_THRREG(10));
565 break;
566 default:
567 dev_warn(codec->dev, "Unhandled FIFO mode: %d\n",
568 dac33->fifo_mode);
569 break;
570 }
571}
572
573static inline void dac33_playback_handler(struct tlv320dac33_priv *dac33)
574{
575 struct snd_soc_codec *codec;
576
577 codec = &dac33->codec;
578
579 switch (dac33->fifo_mode) {
580 case DAC33_FIFO_MODE1:
581 dac33_write16(codec, DAC33_NSAMPLE_MSB,
582 DAC33_THRREG(dac33->nsample));
583 break;
584 case DAC33_FIFO_MODE7:
585 /* At the moment we are not using interrupts in mode7 */
586 break;
587 default:
588 dev_warn(codec->dev, "Unhandled FIFO mode: %d\n",
589 dac33->fifo_mode);
590 break;
591 }
592}
593
594static void dac33_work(struct work_struct *work)
595{
596 struct snd_soc_codec *codec;
597 struct tlv320dac33_priv *dac33;
598 u8 reg;
599
600 dac33 = container_of(work, struct tlv320dac33_priv, work);
601 codec = &dac33->codec;
602
603 mutex_lock(&dac33->mutex);
604 switch (dac33->state) {
605 case DAC33_PREFILL:
606 dac33->state = DAC33_PLAYBACK;
607 dac33_prefill_handler(dac33);
608 break;
609 case DAC33_PLAYBACK:
610 dac33_playback_handler(dac33);
611 break;
612 case DAC33_IDLE:
613 break;
614 case DAC33_FLUSH:
615 dac33->state = DAC33_IDLE;
616 /* Mask all interrupts from dac33 */
617 dac33_write(codec, DAC33_FIFO_IRQ_MASK, 0);
618
619 /* flush fifo */
620 reg = dac33_read_reg_cache(codec, DAC33_FIFO_CTRL_A);
621 reg |= DAC33_FIFOFLUSH;
622 dac33_write(codec, DAC33_FIFO_CTRL_A, reg);
623 break;
624 }
625 mutex_unlock(&dac33->mutex);
626}
627
628static irqreturn_t dac33_interrupt_handler(int irq, void *dev)
629{
630 struct snd_soc_codec *codec = dev;
631 struct tlv320dac33_priv *dac33 = codec->private_data;
632
633 queue_work(dac33->dac33_wq, &dac33->work);
634
635 return IRQ_HANDLED;
636}
637
638static void dac33_shutdown(struct snd_pcm_substream *substream,
639 struct snd_soc_dai *dai)
640{
641 struct snd_soc_pcm_runtime *rtd = substream->private_data;
642 struct snd_soc_device *socdev = rtd->socdev;
643 struct snd_soc_codec *codec = socdev->card->codec;
644 struct tlv320dac33_priv *dac33 = codec->private_data;
645 unsigned int pwr_ctrl;
646
647 /* Stop pending workqueue */
648 if (dac33->fifo_mode)
649 cancel_work_sync(&dac33->work);
650
651 mutex_lock(&dac33->mutex);
652 pwr_ctrl = dac33_read_reg_cache(codec, DAC33_PWR_CTRL);
653 pwr_ctrl &= ~(DAC33_OSCPDNB | DAC33_DACRPDNB | DAC33_DACLPDNB);
654 dac33_write(codec, DAC33_PWR_CTRL, pwr_ctrl);
655 mutex_unlock(&dac33->mutex);
656}
657
658static void dac33_oscwait(struct snd_soc_codec *codec)
659{
660 int timeout = 20;
661 u8 reg;
662
663 do {
664 msleep(1);
665 dac33_read(codec, DAC33_INT_OSC_STATUS, &reg);
666 } while (((reg & 0x03) != DAC33_OSCSTATUS_NORMAL) && timeout--);
667 if ((reg & 0x03) != DAC33_OSCSTATUS_NORMAL)
668 dev_err(codec->dev,
669 "internal oscillator calibration failed\n");
670}
671
672static int dac33_hw_params(struct snd_pcm_substream *substream,
673 struct snd_pcm_hw_params *params,
674 struct snd_soc_dai *dai)
675{
676 struct snd_soc_pcm_runtime *rtd = substream->private_data;
677 struct snd_soc_device *socdev = rtd->socdev;
678 struct snd_soc_codec *codec = socdev->card->codec;
679
680 /* Check parameters for validity */
681 switch (params_rate(params)) {
682 case 44100:
683 case 48000:
684 break;
685 default:
686 dev_err(codec->dev, "unsupported rate %d\n",
687 params_rate(params));
688 return -EINVAL;
689 }
690
691 switch (params_format(params)) {
692 case SNDRV_PCM_FORMAT_S16_LE:
693 break;
694 default:
695 dev_err(codec->dev, "unsupported format %d\n",
696 params_format(params));
697 return -EINVAL;
698 }
699
700 return 0;
701}
702
703#define CALC_OSCSET(rate, refclk) ( \
704 ((((rate * 10000) / refclk) * 4096) + 7000) / 10000)
705#define CALC_RATIOSET(rate, refclk) ( \
706 ((((refclk * 100000) / rate) * 16384) + 50000) / 100000)
707
708/*
709 * tlv320dac33 is strict on the sequence of the register writes, if the register
710 * writes happens in different order, than dac33 might end up in unknown state.
711 * Use the known, working sequence of register writes to initialize the dac33.
712 */
713static int dac33_prepare_chip(struct snd_pcm_substream *substream)
714{
715 struct snd_soc_pcm_runtime *rtd = substream->private_data;
716 struct snd_soc_device *socdev = rtd->socdev;
717 struct snd_soc_codec *codec = socdev->card->codec;
718 struct tlv320dac33_priv *dac33 = codec->private_data;
719 unsigned int oscset, ratioset, pwr_ctrl, reg_tmp;
720 u8 aictrl_a, aictrl_b, fifoctrl_a;
721
722 switch (substream->runtime->rate) {
723 case 44100:
724 case 48000:
725 oscset = CALC_OSCSET(substream->runtime->rate, dac33->refclk);
726 ratioset = CALC_RATIOSET(substream->runtime->rate,
727 dac33->refclk);
728 break;
729 default:
730 dev_err(codec->dev, "unsupported rate %d\n",
731 substream->runtime->rate);
732 return -EINVAL;
733 }
734
735
736 aictrl_a = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_A);
737 aictrl_a &= ~(DAC33_NCYCL_MASK | DAC33_WLEN_MASK);
738 /* Read FIFO control A, and clear FIFO flush bit */
739 fifoctrl_a = dac33_read_reg_cache(codec, DAC33_FIFO_CTRL_A);
740 fifoctrl_a &= ~DAC33_FIFOFLUSH;
741
742 fifoctrl_a &= ~DAC33_WIDTH;
743 switch (substream->runtime->format) {
744 case SNDRV_PCM_FORMAT_S16_LE:
745 aictrl_a |= (DAC33_NCYCL_16 | DAC33_WLEN_16);
746 fifoctrl_a |= DAC33_WIDTH;
747 break;
748 default:
749 dev_err(codec->dev, "unsupported format %d\n",
750 substream->runtime->format);
751 return -EINVAL;
752 }
753
754 mutex_lock(&dac33->mutex);
755 dac33_soft_power(codec, 1);
756
757 reg_tmp = dac33_read_reg_cache(codec, DAC33_INT_OSC_CTRL);
758 dac33_write(codec, DAC33_INT_OSC_CTRL, reg_tmp);
759
760 /* Write registers 0x08 and 0x09 (MSB, LSB) */
761 dac33_write16(codec, DAC33_INT_OSC_FREQ_RAT_A, oscset);
762
763 /* calib time: 128 is a nice number ;) */
764 dac33_write(codec, DAC33_CALIB_TIME, 128);
765
766 /* adjustment treshold & step */
767 dac33_write(codec, DAC33_INT_OSC_CTRL_B, DAC33_ADJTHRSHLD(2) |
768 DAC33_ADJSTEP(1));
769
770 /* div=4 / gain=1 / div */
771 dac33_write(codec, DAC33_INT_OSC_CTRL_C, DAC33_REFDIV(4));
772
773 pwr_ctrl = dac33_read_reg_cache(codec, DAC33_PWR_CTRL);
774 pwr_ctrl |= DAC33_OSCPDNB | DAC33_DACRPDNB | DAC33_DACLPDNB;
775 dac33_write(codec, DAC33_PWR_CTRL, pwr_ctrl);
776
777 dac33_oscwait(codec);
778
779 if (dac33->fifo_mode) {
780 /* Generic for all FIFO modes */
781 /* 50-51 : ASRC Control registers */
782 dac33_write(codec, DAC33_ASRC_CTRL_A, DAC33_SRCLKDIV(1));
783 dac33_write(codec, DAC33_ASRC_CTRL_B, 1); /* ??? */
784
785 /* Write registers 0x34 and 0x35 (MSB, LSB) */
786 dac33_write16(codec, DAC33_SRC_REF_CLK_RATIO_A, ratioset);
787
788 /* Set interrupts to high active */
789 dac33_write(codec, DAC33_INTP_CTRL_A, DAC33_INTPM_AHIGH);
790 } else {
791 /* FIFO bypass mode */
792 /* 50-51 : ASRC Control registers */
793 dac33_write(codec, DAC33_ASRC_CTRL_A, DAC33_SRCBYP);
794 dac33_write(codec, DAC33_ASRC_CTRL_B, 0); /* ??? */
795 }
796
797 /* Interrupt behaviour configuration */
798 switch (dac33->fifo_mode) {
799 case DAC33_FIFO_MODE1:
800 dac33_write(codec, DAC33_FIFO_IRQ_MODE_B,
801 DAC33_ATM(DAC33_FIFO_IRQ_MODE_LEVEL));
802 dac33_write(codec, DAC33_FIFO_IRQ_MASK, DAC33_MAT);
803 break;
804 case DAC33_FIFO_MODE7:
805 /* Disable all interrupts */
806 dac33_write(codec, DAC33_FIFO_IRQ_MASK, 0);
807 break;
808 default:
809 /* in FIFO bypass mode, the interrupts are not used */
810 break;
811 }
812
813 aictrl_b = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_B);
814
815 switch (dac33->fifo_mode) {
816 case DAC33_FIFO_MODE1:
817 /*
818 * For mode1:
819 * Disable the FIFO bypass (Enable the use of FIFO)
820 * Select nSample mode
821 * BCLK is only running when data is needed by DAC33
822 */
823 fifoctrl_a &= ~DAC33_FBYPAS;
824 fifoctrl_a &= ~DAC33_FAUTO;
825 aictrl_b &= ~DAC33_BCLKON;
826 break;
827 case DAC33_FIFO_MODE7:
828 /*
829 * For mode1:
830 * Disable the FIFO bypass (Enable the use of FIFO)
831 * Select Threshold mode
832 * BCLK is only running when data is needed by DAC33
833 */
834 fifoctrl_a &= ~DAC33_FBYPAS;
835 fifoctrl_a |= DAC33_FAUTO;
836 aictrl_b &= ~DAC33_BCLKON;
837 break;
838 default:
839 /*
840 * For FIFO bypass mode:
841 * Enable the FIFO bypass (Disable the FIFO use)
842 * Set the BCLK as continous
843 */
844 fifoctrl_a |= DAC33_FBYPAS;
845 aictrl_b |= DAC33_BCLKON;
846 break;
847 }
848
849 dac33_write(codec, DAC33_FIFO_CTRL_A, fifoctrl_a);
850 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_A, aictrl_a);
851 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_B, aictrl_b);
852
853 /*
854 * BCLK divide ratio
855 * 0: 1.5
856 * 1: 1
857 * 2: 2
858 * ...
859 * 254: 254
860 * 255: 255
861 */
862 if (dac33->fifo_mode)
863 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C,
864 dac33->burst_bclkdiv);
865 else
866 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C, 32);
867
868 switch (dac33->fifo_mode) {
869 case DAC33_FIFO_MODE1:
870 dac33_write16(codec, DAC33_ATHR_MSB,
871 DAC33_THRREG(dac33->alarm_threshold));
872 break;
873 case DAC33_FIFO_MODE7:
874 /*
875 * Configure the threshold levels, and leave 10 sample space
876 * at the bottom, and also at the top of the FIFO
877 */
878 dac33_write16(codec, DAC33_UTHR_MSB,
879 DAC33_THRREG(DAC33_BUFFER_SIZE_SAMPLES - 10));
880 dac33_write16(codec, DAC33_LTHR_MSB,
881 DAC33_THRREG(10));
882 break;
883 default:
884 break;
885 }
886
887 mutex_unlock(&dac33->mutex);
888
889 return 0;
890}
891
892static void dac33_calculate_times(struct snd_pcm_substream *substream)
893{
894 struct snd_soc_pcm_runtime *rtd = substream->private_data;
895 struct snd_soc_device *socdev = rtd->socdev;
896 struct snd_soc_codec *codec = socdev->card->codec;
897 struct tlv320dac33_priv *dac33 = codec->private_data;
898 unsigned int nsample_limit;
899
900 /* Number of samples (16bit, stereo) in one period */
901 dac33->nsample_min = snd_pcm_lib_period_bytes(substream) / 4;
902
903 /* Number of samples (16bit, stereo) in ALSA buffer */
904 dac33->nsample_max = snd_pcm_lib_buffer_bytes(substream) / 4;
905 /* Subtract one period from the total */
906 dac33->nsample_max -= dac33->nsample_min;
907
908 /* Number of samples for LATENCY_TIME_MS / 2 */
909 dac33->alarm_threshold = substream->runtime->rate /
910 (1000 / (LATENCY_TIME_MS / 2));
911
912 /* Find and fix up the lowest nsmaple limit */
913 nsample_limit = substream->runtime->rate / (1000 / LATENCY_TIME_MS);
914
915 if (dac33->nsample_min < nsample_limit)
916 dac33->nsample_min = nsample_limit;
917
918 if (dac33->nsample < dac33->nsample_min)
919 dac33->nsample = dac33->nsample_min;
920
921 /*
922 * Find and fix up the highest nsmaple limit
923 * In order to not overflow the DAC33 buffer substract the
924 * alarm_threshold value from the size of the DAC33 buffer
925 */
926 nsample_limit = DAC33_BUFFER_SIZE_SAMPLES - dac33->alarm_threshold;
927
928 if (dac33->nsample_max > nsample_limit)
929 dac33->nsample_max = nsample_limit;
930
931 if (dac33->nsample > dac33->nsample_max)
932 dac33->nsample = dac33->nsample_max;
933}
934
935static int dac33_pcm_prepare(struct snd_pcm_substream *substream,
936 struct snd_soc_dai *dai)
937{
938 dac33_calculate_times(substream);
939 dac33_prepare_chip(substream);
940
941 return 0;
942}
943
944static int dac33_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
945 struct snd_soc_dai *dai)
946{
947 struct snd_soc_pcm_runtime *rtd = substream->private_data;
948 struct snd_soc_device *socdev = rtd->socdev;
949 struct snd_soc_codec *codec = socdev->card->codec;
950 struct tlv320dac33_priv *dac33 = codec->private_data;
951 int ret = 0;
952
953 switch (cmd) {
954 case SNDRV_PCM_TRIGGER_START:
955 case SNDRV_PCM_TRIGGER_RESUME:
956 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
957 if (dac33->fifo_mode) {
958 dac33->state = DAC33_PREFILL;
959 queue_work(dac33->dac33_wq, &dac33->work);
960 }
961 break;
962 case SNDRV_PCM_TRIGGER_STOP:
963 case SNDRV_PCM_TRIGGER_SUSPEND:
964 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
965 if (dac33->fifo_mode) {
966 dac33->state = DAC33_FLUSH;
967 queue_work(dac33->dac33_wq, &dac33->work);
968 }
969 break;
970 default:
971 ret = -EINVAL;
972 }
973
974 return ret;
975}
976
977static int dac33_set_dai_sysclk(struct snd_soc_dai *codec_dai,
978 int clk_id, unsigned int freq, int dir)
979{
980 struct snd_soc_codec *codec = codec_dai->codec;
981 struct tlv320dac33_priv *dac33 = codec->private_data;
982 u8 ioc_reg, asrcb_reg;
983
984 ioc_reg = dac33_read_reg_cache(codec, DAC33_INT_OSC_CTRL);
985 asrcb_reg = dac33_read_reg_cache(codec, DAC33_ASRC_CTRL_B);
986 switch (clk_id) {
987 case TLV320DAC33_MCLK:
988 ioc_reg |= DAC33_REFSEL;
989 asrcb_reg |= DAC33_SRCREFSEL;
990 break;
991 case TLV320DAC33_SLEEPCLK:
992 ioc_reg &= ~DAC33_REFSEL;
993 asrcb_reg &= ~DAC33_SRCREFSEL;
994 break;
995 default:
996 dev_err(codec->dev, "Invalid clock ID (%d)\n", clk_id);
997 break;
998 }
999 dac33->refclk = freq;
1000
1001 dac33_write_reg_cache(codec, DAC33_INT_OSC_CTRL, ioc_reg);
1002 dac33_write_reg_cache(codec, DAC33_ASRC_CTRL_B, asrcb_reg);
1003
1004 return 0;
1005}
1006
1007static int dac33_set_dai_fmt(struct snd_soc_dai *codec_dai,
1008 unsigned int fmt)
1009{
1010 struct snd_soc_codec *codec = codec_dai->codec;
1011 struct tlv320dac33_priv *dac33 = codec->private_data;
1012 u8 aictrl_a, aictrl_b;
1013
1014 aictrl_a = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_A);
1015 aictrl_b = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_B);
1016 /* set master/slave audio interface */
1017 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1018 case SND_SOC_DAIFMT_CBM_CFM:
1019 /* Codec Master */
1020 aictrl_a |= (DAC33_MSBCLK | DAC33_MSWCLK);
1021 break;
1022 case SND_SOC_DAIFMT_CBS_CFS:
1023 /* Codec Slave */
1024 if (dac33->fifo_mode) {
1025 dev_err(codec->dev, "FIFO mode requires master mode\n");
1026 return -EINVAL;
1027 } else
1028 aictrl_a &= ~(DAC33_MSBCLK | DAC33_MSWCLK);
1029 break;
1030 default:
1031 return -EINVAL;
1032 }
1033
1034 aictrl_a &= ~DAC33_AFMT_MASK;
1035 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1036 case SND_SOC_DAIFMT_I2S:
1037 aictrl_a |= DAC33_AFMT_I2S;
1038 break;
1039 case SND_SOC_DAIFMT_DSP_A:
1040 aictrl_a |= DAC33_AFMT_DSP;
1041 aictrl_b &= ~DAC33_DATA_DELAY_MASK;
1042 aictrl_b |= DAC33_DATA_DELAY(0);
1043 break;
1044 case SND_SOC_DAIFMT_RIGHT_J:
1045 aictrl_a |= DAC33_AFMT_RIGHT_J;
1046 break;
1047 case SND_SOC_DAIFMT_LEFT_J:
1048 aictrl_a |= DAC33_AFMT_LEFT_J;
1049 break;
1050 default:
1051 dev_err(codec->dev, "Unsupported format (%u)\n",
1052 fmt & SND_SOC_DAIFMT_FORMAT_MASK);
1053 return -EINVAL;
1054 }
1055
1056 dac33_write_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_A, aictrl_a);
1057 dac33_write_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_B, aictrl_b);
1058
1059 return 0;
1060}
1061
1062static void dac33_init_chip(struct snd_soc_codec *codec)
1063{
1064 /* 44-46: DAC Control Registers */
1065 /* A : DAC sample rate Fsref/1.5 */
1066 dac33_write(codec, DAC33_DAC_CTRL_A, DAC33_DACRATE(0));
1067 /* B : DAC src=normal, not muted */
1068 dac33_write(codec, DAC33_DAC_CTRL_B, DAC33_DACSRCR_RIGHT |
1069 DAC33_DACSRCL_LEFT);
1070 /* C : (defaults) */
1071 dac33_write(codec, DAC33_DAC_CTRL_C, 0x00);
1072
1073 /* 64-65 : L&R DAC power control
1074 Line In -> OUT 1V/V Gain, DAC -> OUT 4V/V Gain*/
1075 dac33_write(codec, DAC33_LDAC_PWR_CTRL, DAC33_LROUT_GAIN(2));
1076 dac33_write(codec, DAC33_RDAC_PWR_CTRL, DAC33_LROUT_GAIN(2));
1077
1078 /* 73 : volume soft stepping control,
1079 clock source = internal osc (?) */
1080 dac33_write(codec, DAC33_ANA_VOL_SOFT_STEP_CTRL, DAC33_VOLCLKEN);
1081
1082 /* 66 : LOP/LOM Modes */
1083 dac33_write(codec, DAC33_OUT_AMP_CM_CTRL, 0xff);
1084
1085 /* 68 : LOM inverted from LOP */
1086 dac33_write(codec, DAC33_OUT_AMP_CTRL, (3<<2));
1087
1088 dac33_write(codec, DAC33_PWR_CTRL, DAC33_PDNALLB);
1089}
1090
1091static int dac33_soc_probe(struct platform_device *pdev)
1092{
1093 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1094 struct snd_soc_codec *codec;
1095 struct tlv320dac33_priv *dac33;
1096 int ret = 0;
1097
1098 BUG_ON(!tlv320dac33_codec);
1099
1100 codec = tlv320dac33_codec;
1101 socdev->card->codec = codec;
1102 dac33 = codec->private_data;
1103
1104 /* Power up the codec */
1105 dac33_hard_power(codec, 1);
1106 /* Set default configuration */
1107 dac33_init_chip(codec);
1108
1109 /* register pcms */
1110 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1111 if (ret < 0) {
1112 dev_err(codec->dev, "failed to create pcms\n");
1113 goto pcm_err;
1114 }
1115
1116 snd_soc_add_controls(codec, dac33_snd_controls,
1117 ARRAY_SIZE(dac33_snd_controls));
1118 /* Only add the nSample controls, if we have valid IRQ number */
1119 if (dac33->irq >= 0)
1120 snd_soc_add_controls(codec, dac33_nsample_snd_controls,
1121 ARRAY_SIZE(dac33_nsample_snd_controls));
1122
1123 dac33_add_widgets(codec);
1124
1125 /* power on device */
1126 dac33_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1127
1128 /* Bias level configuration has enabled regulator an extra time */
1129 regulator_bulk_disable(ARRAY_SIZE(dac33->supplies), dac33->supplies);
1130
1131 return 0;
1132
1133pcm_err:
1134 dac33_hard_power(codec, 0);
1135 return ret;
1136}
1137
1138static int dac33_soc_remove(struct platform_device *pdev)
1139{
1140 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1141 struct snd_soc_codec *codec = socdev->card->codec;
1142
1143 dac33_set_bias_level(codec, SND_SOC_BIAS_OFF);
1144
1145 snd_soc_free_pcms(socdev);
1146 snd_soc_dapm_free(socdev);
1147
1148 return 0;
1149}
1150
1151static int dac33_soc_suspend(struct platform_device *pdev, pm_message_t state)
1152{
1153 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1154 struct snd_soc_codec *codec = socdev->card->codec;
1155
1156 dac33_set_bias_level(codec, SND_SOC_BIAS_OFF);
1157
1158 return 0;
1159}
1160
1161static int dac33_soc_resume(struct platform_device *pdev)
1162{
1163 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1164 struct snd_soc_codec *codec = socdev->card->codec;
1165
1166 dac33_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1167 dac33_set_bias_level(codec, codec->suspend_bias_level);
1168
1169 return 0;
1170}
1171
1172struct snd_soc_codec_device soc_codec_dev_tlv320dac33 = {
1173 .probe = dac33_soc_probe,
1174 .remove = dac33_soc_remove,
1175 .suspend = dac33_soc_suspend,
1176 .resume = dac33_soc_resume,
1177};
1178EXPORT_SYMBOL_GPL(soc_codec_dev_tlv320dac33);
1179
1180#define DAC33_RATES (SNDRV_PCM_RATE_44100 | \
1181 SNDRV_PCM_RATE_48000)
1182#define DAC33_FORMATS SNDRV_PCM_FMTBIT_S16_LE
1183
1184static struct snd_soc_dai_ops dac33_dai_ops = {
1185 .shutdown = dac33_shutdown,
1186 .hw_params = dac33_hw_params,
1187 .prepare = dac33_pcm_prepare,
1188 .trigger = dac33_pcm_trigger,
1189 .set_sysclk = dac33_set_dai_sysclk,
1190 .set_fmt = dac33_set_dai_fmt,
1191};
1192
1193struct snd_soc_dai dac33_dai = {
1194 .name = "tlv320dac33",
1195 .playback = {
1196 .stream_name = "Playback",
1197 .channels_min = 2,
1198 .channels_max = 2,
1199 .rates = DAC33_RATES,
1200 .formats = DAC33_FORMATS,},
1201 .ops = &dac33_dai_ops,
1202};
1203EXPORT_SYMBOL_GPL(dac33_dai);
1204
1205static int __devinit dac33_i2c_probe(struct i2c_client *client,
1206 const struct i2c_device_id *id)
1207{
1208 struct tlv320dac33_platform_data *pdata;
1209 struct tlv320dac33_priv *dac33;
1210 struct snd_soc_codec *codec;
1211 int ret, i;
1212
1213 if (client->dev.platform_data == NULL) {
1214 dev_err(&client->dev, "Platform data not set\n");
1215 return -ENODEV;
1216 }
1217 pdata = client->dev.platform_data;
1218
1219 dac33 = kzalloc(sizeof(struct tlv320dac33_priv), GFP_KERNEL);
1220 if (dac33 == NULL)
1221 return -ENOMEM;
1222
1223 codec = &dac33->codec;
1224 codec->private_data = dac33;
1225 codec->control_data = client;
1226
1227 mutex_init(&codec->mutex);
1228 mutex_init(&dac33->mutex);
1229 INIT_LIST_HEAD(&codec->dapm_widgets);
1230 INIT_LIST_HEAD(&codec->dapm_paths);
1231
1232 codec->name = "tlv320dac33";
1233 codec->owner = THIS_MODULE;
1234 codec->read = dac33_read_reg_cache;
1235 codec->write = dac33_write_locked;
1236 codec->hw_write = (hw_write_t) i2c_master_send;
1237 codec->bias_level = SND_SOC_BIAS_OFF;
1238 codec->set_bias_level = dac33_set_bias_level;
1239 codec->dai = &dac33_dai;
1240 codec->num_dai = 1;
1241 codec->reg_cache_size = ARRAY_SIZE(dac33_reg);
1242 codec->reg_cache = kmemdup(dac33_reg, ARRAY_SIZE(dac33_reg),
1243 GFP_KERNEL);
1244 if (codec->reg_cache == NULL) {
1245 ret = -ENOMEM;
1246 goto error_reg;
1247 }
1248
1249 i2c_set_clientdata(client, dac33);
1250
1251 dac33->power_gpio = pdata->power_gpio;
1252 dac33->burst_bclkdiv = pdata->burst_bclkdiv;
1253 dac33->irq = client->irq;
1254 dac33->nsample = NSAMPLE_MAX;
1255 /* Disable FIFO use by default */
1256 dac33->fifo_mode = DAC33_FIFO_BYPASS;
1257
1258 tlv320dac33_codec = codec;
1259
1260 codec->dev = &client->dev;
1261 dac33_dai.dev = codec->dev;
1262
1263 /* Check if the reset GPIO number is valid and request it */
1264 if (dac33->power_gpio >= 0) {
1265 ret = gpio_request(dac33->power_gpio, "tlv320dac33 reset");
1266 if (ret < 0) {
1267 dev_err(codec->dev,
1268 "Failed to request reset GPIO (%d)\n",
1269 dac33->power_gpio);
1270 snd_soc_unregister_dai(&dac33_dai);
1271 snd_soc_unregister_codec(codec);
1272 goto error_gpio;
1273 }
1274 gpio_direction_output(dac33->power_gpio, 0);
1275 } else {
1276 dac33->chip_power = 1;
1277 }
1278
1279 /* Check if the IRQ number is valid and request it */
1280 if (dac33->irq >= 0) {
1281 ret = request_irq(dac33->irq, dac33_interrupt_handler,
1282 IRQF_TRIGGER_RISING | IRQF_DISABLED,
1283 codec->name, codec);
1284 if (ret < 0) {
1285 dev_err(codec->dev, "Could not request IRQ%d (%d)\n",
1286 dac33->irq, ret);
1287 dac33->irq = -1;
1288 }
1289 if (dac33->irq != -1) {
1290 /* Setup work queue */
1291 dac33->dac33_wq =
1292 create_singlethread_workqueue("tlv320dac33");
1293 if (dac33->dac33_wq == NULL) {
1294 free_irq(dac33->irq, &dac33->codec);
1295 ret = -ENOMEM;
1296 goto error_wq;
1297 }
1298
1299 INIT_WORK(&dac33->work, dac33_work);
1300 }
1301 }
1302
1303 for (i = 0; i < ARRAY_SIZE(dac33->supplies); i++)
1304 dac33->supplies[i].supply = dac33_supply_names[i];
1305
1306 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(dac33->supplies),
1307 dac33->supplies);
1308
1309 if (ret != 0) {
1310 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
1311 goto err_get;
1312 }
1313
1314 ret = regulator_bulk_enable(ARRAY_SIZE(dac33->supplies),
1315 dac33->supplies);
1316 if (ret != 0) {
1317 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
1318 goto err_enable;
1319 }
1320
1321 ret = snd_soc_register_codec(codec);
1322 if (ret != 0) {
1323 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
1324 goto error_codec;
1325 }
1326
1327 ret = snd_soc_register_dai(&dac33_dai);
1328 if (ret != 0) {
1329 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
1330 snd_soc_unregister_codec(codec);
1331 goto error_codec;
1332 }
1333
1334 /* Shut down the codec for now */
1335 dac33_hard_power(codec, 0);
1336
1337 return ret;
1338
1339error_codec:
1340 regulator_bulk_disable(ARRAY_SIZE(dac33->supplies), dac33->supplies);
1341err_enable:
1342 regulator_bulk_free(ARRAY_SIZE(dac33->supplies), dac33->supplies);
1343err_get:
1344 if (dac33->irq >= 0) {
1345 free_irq(dac33->irq, &dac33->codec);
1346 destroy_workqueue(dac33->dac33_wq);
1347 }
1348error_wq:
1349 if (dac33->power_gpio >= 0)
1350 gpio_free(dac33->power_gpio);
1351error_gpio:
1352 kfree(codec->reg_cache);
1353error_reg:
1354 tlv320dac33_codec = NULL;
1355 kfree(dac33);
1356
1357 return ret;
1358}
1359
1360static int __devexit dac33_i2c_remove(struct i2c_client *client)
1361{
1362 struct tlv320dac33_priv *dac33;
1363
1364 dac33 = i2c_get_clientdata(client);
1365 dac33_hard_power(&dac33->codec, 0);
1366
1367 if (dac33->power_gpio >= 0)
1368 gpio_free(dac33->power_gpio);
1369 if (dac33->irq >= 0)
1370 free_irq(dac33->irq, &dac33->codec);
1371
1372 regulator_bulk_free(ARRAY_SIZE(dac33->supplies), dac33->supplies);
1373
1374 destroy_workqueue(dac33->dac33_wq);
1375 snd_soc_unregister_dai(&dac33_dai);
1376 snd_soc_unregister_codec(&dac33->codec);
1377 kfree(dac33->codec.reg_cache);
1378 kfree(dac33);
1379 tlv320dac33_codec = NULL;
1380
1381 return 0;
1382}
1383
1384static const struct i2c_device_id tlv320dac33_i2c_id[] = {
1385 {
1386 .name = "tlv320dac33",
1387 .driver_data = 0,
1388 },
1389 { },
1390};
1391
1392static struct i2c_driver tlv320dac33_i2c_driver = {
1393 .driver = {
1394 .name = "tlv320dac33",
1395 .owner = THIS_MODULE,
1396 },
1397 .probe = dac33_i2c_probe,
1398 .remove = __devexit_p(dac33_i2c_remove),
1399 .id_table = tlv320dac33_i2c_id,
1400};
1401
1402static int __init dac33_module_init(void)
1403{
1404 int r;
1405 r = i2c_add_driver(&tlv320dac33_i2c_driver);
1406 if (r < 0) {
1407 printk(KERN_ERR "DAC33: driver registration failed\n");
1408 return r;
1409 }
1410 return 0;
1411}
1412module_init(dac33_module_init);
1413
1414static void __exit dac33_module_exit(void)
1415{
1416 i2c_del_driver(&tlv320dac33_i2c_driver);
1417}
1418module_exit(dac33_module_exit);
1419
1420
1421MODULE_DESCRIPTION("ASoC TLV320DAC33 codec driver");
1422MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@nokia.com>");
1423MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/tlv320dac33.h b/sound/soc/codecs/tlv320dac33.h
new file mode 100644
index 000000000000..eb8ae07f0bd2
--- /dev/null
+++ b/sound/soc/codecs/tlv320dac33.h
@@ -0,0 +1,267 @@
1/*
2 * ALSA SoC Texas Instruments TLV320DAC33 codec driver
3 *
4 * Author: Peter Ujfalusi <peter.ujfalusi@nokia.com>
5 *
6 * Copyright: (C) 2009 Nokia Corporation
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#ifndef __TLV320DAC33_H
25#define __TLV320DAC33_H
26
27#define DAC33_PAGE_SELECT 0x00
28#define DAC33_PWR_CTRL 0x01
29#define DAC33_PLL_CTRL_A 0x02
30#define DAC33_PLL_CTRL_B 0x03
31#define DAC33_PLL_CTRL_C 0x04
32#define DAC33_PLL_CTRL_D 0x05
33#define DAC33_PLL_CTRL_E 0x06
34#define DAC33_INT_OSC_CTRL 0x07
35#define DAC33_INT_OSC_FREQ_RAT_A 0x08
36#define DAC33_INT_OSC_FREQ_RAT_B 0x09
37#define DAC33_INT_OSC_DAC_RATIO_SET 0x0A
38#define DAC33_CALIB_TIME 0x0B
39#define DAC33_INT_OSC_CTRL_B 0x0C
40#define DAC33_INT_OSC_CTRL_C 0x0D
41#define DAC33_INT_OSC_STATUS 0x0E
42#define DAC33_INT_OSC_DAC_RATIO_READ 0x0F
43#define DAC33_INT_OSC_FREQ_RAT_READ_A 0x10
44#define DAC33_INT_OSC_FREQ_RAT_READ_B 0x11
45#define DAC33_SER_AUDIOIF_CTRL_A 0x12
46#define DAC33_SER_AUDIOIF_CTRL_B 0x13
47#define DAC33_SER_AUDIOIF_CTRL_C 0x14
48#define DAC33_FIFO_CTRL_A 0x15
49#define DAC33_UTHR_MSB 0x16
50#define DAC33_UTHR_LSB 0x17
51#define DAC33_ATHR_MSB 0x18
52#define DAC33_ATHR_LSB 0x19
53#define DAC33_LTHR_MSB 0x1A
54#define DAC33_LTHR_LSB 0x1B
55#define DAC33_PREFILL_MSB 0x1C
56#define DAC33_PREFILL_LSB 0x1D
57#define DAC33_NSAMPLE_MSB 0x1E
58#define DAC33_NSAMPLE_LSB 0x1F
59#define DAC33_FIFO_WPTR_MSB 0x20
60#define DAC33_FIFO_WPTR_LSB 0x21
61#define DAC33_FIFO_RPTR_MSB 0x22
62#define DAC33_FIFO_RPTR_LSB 0x23
63#define DAC33_FIFO_DEPTH_MSB 0x24
64#define DAC33_FIFO_DEPTH_LSB 0x25
65#define DAC33_SAMPLES_REMAINING_MSB 0x26
66#define DAC33_SAMPLES_REMAINING_LSB 0x27
67#define DAC33_FIFO_IRQ_FLAG 0x28
68#define DAC33_FIFO_IRQ_MASK 0x29
69#define DAC33_FIFO_IRQ_MODE_A 0x2A
70#define DAC33_FIFO_IRQ_MODE_B 0x2B
71#define DAC33_DAC_CTRL_A 0x2C
72#define DAC33_DAC_CTRL_B 0x2D
73#define DAC33_DAC_CTRL_C 0x2E
74#define DAC33_LDAC_DIG_VOL_CTRL 0x2F
75#define DAC33_RDAC_DIG_VOL_CTRL 0x30
76#define DAC33_DAC_STATUS_FLAGS 0x31
77#define DAC33_ASRC_CTRL_A 0x32
78#define DAC33_ASRC_CTRL_B 0x33
79#define DAC33_SRC_REF_CLK_RATIO_A 0x34
80#define DAC33_SRC_REF_CLK_RATIO_B 0x35
81#define DAC33_SRC_EST_REF_CLK_RATIO_A 0x36
82#define DAC33_SRC_EST_REF_CLK_RATIO_B 0x37
83#define DAC33_INTP_CTRL_A 0x38
84#define DAC33_INTP_CTRL_B 0x39
85/* Registers 0x3A - 0x3F Reserved */
86#define DAC33_LDAC_PWR_CTRL 0x40
87#define DAC33_RDAC_PWR_CTRL 0x41
88#define DAC33_OUT_AMP_CM_CTRL 0x42
89#define DAC33_OUT_AMP_PWR_CTRL 0x43
90#define DAC33_OUT_AMP_CTRL 0x44
91#define DAC33_LINEL_TO_LLO_VOL 0x45
92/* Registers 0x45 - 0x47 Reserved */
93#define DAC33_LINER_TO_RLO_VOL 0x48
94#define DAC33_ANA_VOL_SOFT_STEP_CTRL 0x49
95#define DAC33_OSC_TRIM 0x4A
96/* Registers 0x4B - 0x7C Reserved */
97#define DAC33_DEVICE_ID_MSB 0x7D
98#define DAC33_DEVICE_ID_LSB 0x7E
99#define DAC33_DEVICE_REV_ID 0x7F
100
101#define DAC33_CACHEREGNUM 128
102
103/* Bit definitions */
104
105/* DAC33_PWR_CTRL (0x01) */
106#define DAC33_DACRPDNB (0x01 << 0)
107#define DAC33_DACLPDNB (0x01 << 1)
108#define DAC33_OSCPDNB (0x01 << 2)
109#define DAC33_PLLPDNB (0x01 << 3)
110#define DAC33_PDNALLB (0x01 << 4)
111#define DAC33_SOFT_RESET (0x01 << 7)
112
113/* DAC33_INT_OSC_CTRL (0x07) */
114#define DAC33_REFSEL (0x01 << 1)
115
116/* DAC33_INT_OSC_CTRL_B (0x0C) */
117#define DAC33_ADJSTEP(x) (x << 0)
118#define DAC33_ADJTHRSHLD(x) (x << 4)
119
120/* DAC33_INT_OSC_CTRL_C (0x0D) */
121#define DAC33_REFDIV(x) (x << 4)
122
123/* DAC33_INT_OSC_STATUS (0x0E) */
124#define DAC33_OSCSTATUS_IDLE_CALIB (0x00)
125#define DAC33_OSCSTATUS_NORMAL (0x01)
126#define DAC33_OSCSTATUS_ADJUSTMENT (0x03)
127#define DAC33_OSCSTATUS_NOT_USED (0x02)
128
129/* DAC33_SER_AUDIOIF_CTRL_A (0x12) */
130#define DAC33_MSWCLK (0x01 << 0)
131#define DAC33_MSBCLK (0x01 << 1)
132#define DAC33_AFMT_MASK (0x03 << 2)
133#define DAC33_AFMT_I2S (0x00 << 2)
134#define DAC33_AFMT_DSP (0x01 << 2)
135#define DAC33_AFMT_RIGHT_J (0x02 << 2)
136#define DAC33_AFMT_LEFT_J (0x03 << 2)
137#define DAC33_WLEN_MASK (0x03 << 4)
138#define DAC33_WLEN_16 (0x00 << 4)
139#define DAC33_WLEN_20 (0x01 << 4)
140#define DAC33_WLEN_24 (0x02 << 4)
141#define DAC33_WLEN_32 (0x03 << 4)
142#define DAC33_NCYCL_MASK (0x03 << 6)
143#define DAC33_NCYCL_16 (0x00 << 6)
144#define DAC33_NCYCL_20 (0x01 << 6)
145#define DAC33_NCYCL_24 (0x02 << 6)
146#define DAC33_NCYCL_32 (0x03 << 6)
147
148/* DAC33_SER_AUDIOIF_CTRL_B (0x13) */
149#define DAC33_DATA_DELAY_MASK (0x03 << 2)
150#define DAC33_DATA_DELAY(x) (x << 2)
151#define DAC33_BCLKON (0x01 << 5)
152
153/* DAC33_FIFO_CTRL_A (0x15) */
154#define DAC33_WIDTH (0x01 << 0)
155#define DAC33_FBYPAS (0x01 << 1)
156#define DAC33_FAUTO (0x01 << 2)
157#define DAC33_FIFOFLUSH (0x01 << 3)
158
159/*
160 * UTHR, ATHR, LTHR, PREFILL, NSAMPLE (0x16 - 0x1F)
161 * 13-bit values
162*/
163#define DAC33_THRREG(x) (((x) & 0x1FFF) << 3)
164
165/* DAC33_FIFO_IRQ_MASK (0x29) */
166#define DAC33_MNS (0x01 << 0)
167#define DAC33_MPS (0x01 << 1)
168#define DAC33_MAT (0x01 << 2)
169#define DAC33_MLT (0x01 << 3)
170#define DAC33_MUT (0x01 << 4)
171#define DAC33_MUF (0x01 << 5)
172#define DAC33_MOF (0x01 << 6)
173
174#define DAC33_FIFO_IRQ_MODE_MASK (0x03)
175#define DAC33_FIFO_IRQ_MODE_RISING (0x00)
176#define DAC33_FIFO_IRQ_MODE_FALLING (0x01)
177#define DAC33_FIFO_IRQ_MODE_LEVEL (0x02)
178#define DAC33_FIFO_IRQ_MODE_EDGE (0x03)
179
180/* DAC33_FIFO_IRQ_MODE_A (0x2A) */
181#define DAC33_UTM(x) (x << 0)
182#define DAC33_UFM(x) (x << 2)
183#define DAC33_OFM(x) (x << 4)
184
185/* DAC33_FIFO_IRQ_MODE_B (0x2B) */
186#define DAC33_NSM(x) (x << 0)
187#define DAC33_PSM(x) (x << 2)
188#define DAC33_ATM(x) (x << 4)
189#define DAC33_LTM(x) (x << 6)
190
191/* DAC33_DAC_CTRL_A (0x2C) */
192#define DAC33_DACRATE(x) (x << 0)
193#define DAC33_DACDUAL (0x01 << 4)
194#define DAC33_DACLKSEL_MASK (0x03 << 5)
195#define DAC33_DACLKSEL_INTSOC (0x00 << 5)
196#define DAC33_DACLKSEL_PLL (0x01 << 5)
197#define DAC33_DACLKSEL_MCLK (0x02 << 5)
198#define DAC33_DACLKSEL_BCLK (0x03 << 5)
199
200/* DAC33_DAC_CTRL_B (0x2D) */
201#define DAC33_DACSRCR_MASK (0x03 << 0)
202#define DAC33_DACSRCR_MUTE (0x00 << 0)
203#define DAC33_DACSRCR_RIGHT (0x01 << 0)
204#define DAC33_DACSRCR_LEFT (0x02 << 0)
205#define DAC33_DACSRCR_MONOMIX (0x03 << 0)
206#define DAC33_DACSRCL_MASK (0x03 << 2)
207#define DAC33_DACSRCL_MUTE (0x00 << 2)
208#define DAC33_DACSRCL_LEFT (0x01 << 2)
209#define DAC33_DACSRCL_RIGHT (0x02 << 2)
210#define DAC33_DACSRCL_MONOMIX (0x03 << 2)
211#define DAC33_DVOLSTEP_MASK (0x03 << 4)
212#define DAC33_DVOLSTEP_SS_PERFS (0x00 << 4)
213#define DAC33_DVOLSTEP_SS_PER2FS (0x01 << 4)
214#define DAC33_DVOLSTEP_SS_DISABLED (0x02 << 4)
215#define DAC33_DVOLCTRL_MASK (0x03 << 6)
216#define DAC33_DVOLCTRL_LR_INDEPENDENT1 (0x00 << 6)
217#define DAC33_DVOLCTRL_LR_RIGHT_CONTROL (0x01 << 6)
218#define DAC33_DVOLCTRL_LR_LEFT_CONTROL (0x02 << 6)
219#define DAC33_DVOLCTRL_LR_INDEPENDENT2 (0x03 << 6)
220
221/* DAC33_DAC_CTRL_C (0x2E) */
222#define DAC33_DEEMENR (0x01 << 0)
223#define DAC33_EFFENR (0x01 << 1)
224#define DAC33_DEEMENL (0x01 << 2)
225#define DAC33_EFFENL (0x01 << 3)
226#define DAC33_EN3D (0x01 << 4)
227#define DAC33_RESYNMUTE (0x01 << 5)
228#define DAC33_RESYNEN (0x01 << 6)
229
230/* DAC33_ASRC_CTRL_A (0x32) */
231#define DAC33_SRCBYP (0x01 << 0)
232#define DAC33_SRCLKSEL_MASK (0x03 << 1)
233#define DAC33_SRCLKSEL_INTSOC (0x00 << 1)
234#define DAC33_SRCLKSEL_PLL (0x01 << 1)
235#define DAC33_SRCLKSEL_MCLK (0x02 << 1)
236#define DAC33_SRCLKSEL_BCLK (0x03 << 1)
237#define DAC33_SRCLKDIV(x) (x << 3)
238
239/* DAC33_ASRC_CTRL_B (0x33) */
240#define DAC33_SRCSETUP(x) (x << 0)
241#define DAC33_SRCREFSEL (0x01 << 4)
242#define DAC33_SRCREFDIV(x) (x << 5)
243
244/* DAC33_INTP_CTRL_A (0x38) */
245#define DAC33_INTPSEL (0x01 << 0)
246#define DAC33_INTPM_MASK (0x03 << 1)
247#define DAC33_INTPM_ALOW_OPENDRAIN (0x00 << 1)
248#define DAC33_INTPM_ALOW (0x01 << 1)
249#define DAC33_INTPM_AHIGH (0x02 << 1)
250
251/* DAC33_LDAC_PWR_CTRL (0x40) */
252/* DAC33_RDAC_PWR_CTRL (0x41) */
253#define DAC33_DACLRNUM (0x01 << 2)
254#define DAC33_LROUT_GAIN(x) (x << 0)
255
256/* DAC33_ANA_VOL_SOFT_STEP_CTRL (0x49) */
257#define DAC33_VOLCLKSEL (0x01 << 0)
258#define DAC33_VOLCLKEN (0x01 << 1)
259#define DAC33_VOLBYPASS (0x01 << 2)
260
261#define TLV320DAC33_MCLK 0
262#define TLV320DAC33_SLEEPCLK 1
263
264extern struct snd_soc_dai dac33_dai;
265extern struct snd_soc_codec_device soc_codec_dev_tlv320dac33;
266
267#endif /* __TLV320DAC33_H */
diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
new file mode 100644
index 000000000000..569ad8758a84
--- /dev/null
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -0,0 +1,531 @@
1/*
2 * ALSA SoC Texas Instruments TPA6130A2 headset stereo amplifier driver
3 *
4 * Copyright (C) Nokia Corporation
5 *
6 * Author: Peter Ujfalusi <peter.ujfalusi@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 */
22
23#include <linux/module.h>
24#include <linux/errno.h>
25#include <linux/device.h>
26#include <linux/i2c.h>
27#include <linux/gpio.h>
28#include <linux/regulator/consumer.h>
29#include <linux/slab.h>
30#include <sound/tpa6130a2-plat.h>
31#include <sound/soc.h>
32#include <sound/soc-dapm.h>
33#include <sound/tlv.h>
34
35#include "tpa6130a2.h"
36
37static struct i2c_client *tpa6130a2_client;
38
39#define TPA6130A2_NUM_SUPPLIES 2
40static const char *tpa6130a2_supply_names[TPA6130A2_NUM_SUPPLIES] = {
41 "CPVSS",
42 "Vdd",
43};
44
45static const char *tpa6140a2_supply_names[TPA6130A2_NUM_SUPPLIES] = {
46 "HPVdd",
47 "AVdd",
48};
49
50/* This struct is used to save the context */
51struct tpa6130a2_data {
52 struct mutex mutex;
53 unsigned char regs[TPA6130A2_CACHEREGNUM];
54 struct regulator_bulk_data supplies[TPA6130A2_NUM_SUPPLIES];
55 int power_gpio;
56 unsigned char power_state;
57};
58
59static int tpa6130a2_i2c_read(int reg)
60{
61 struct tpa6130a2_data *data;
62 int val;
63
64 BUG_ON(tpa6130a2_client == NULL);
65 data = i2c_get_clientdata(tpa6130a2_client);
66
67 /* If powered off, return the cached value */
68 if (data->power_state) {
69 val = i2c_smbus_read_byte_data(tpa6130a2_client, reg);
70 if (val < 0)
71 dev_err(&tpa6130a2_client->dev, "Read failed\n");
72 else
73 data->regs[reg] = val;
74 } else {
75 val = data->regs[reg];
76 }
77
78 return val;
79}
80
81static int tpa6130a2_i2c_write(int reg, u8 value)
82{
83 struct tpa6130a2_data *data;
84 int val = 0;
85
86 BUG_ON(tpa6130a2_client == NULL);
87 data = i2c_get_clientdata(tpa6130a2_client);
88
89 if (data->power_state) {
90 val = i2c_smbus_write_byte_data(tpa6130a2_client, reg, value);
91 if (val < 0)
92 dev_err(&tpa6130a2_client->dev, "Write failed\n");
93 }
94
95 /* Either powered on or off, we save the context */
96 data->regs[reg] = value;
97
98 return val;
99}
100
101static u8 tpa6130a2_read(int reg)
102{
103 struct tpa6130a2_data *data;
104
105 BUG_ON(tpa6130a2_client == NULL);
106 data = i2c_get_clientdata(tpa6130a2_client);
107
108 return data->regs[reg];
109}
110
111static void tpa6130a2_initialize(void)
112{
113 struct tpa6130a2_data *data;
114 int i;
115
116 BUG_ON(tpa6130a2_client == NULL);
117 data = i2c_get_clientdata(tpa6130a2_client);
118
119 for (i = 1; i < TPA6130A2_REG_VERSION; i++)
120 tpa6130a2_i2c_write(i, data->regs[i]);
121}
122
123static int tpa6130a2_power(int power)
124{
125 struct tpa6130a2_data *data;
126 u8 val;
127 int ret;
128
129 BUG_ON(tpa6130a2_client == NULL);
130 data = i2c_get_clientdata(tpa6130a2_client);
131
132 mutex_lock(&data->mutex);
133 if (power) {
134 /* Power on */
135 if (data->power_gpio >= 0)
136 gpio_set_value(data->power_gpio, 1);
137
138 ret = regulator_bulk_enable(ARRAY_SIZE(data->supplies),
139 data->supplies);
140 if (ret != 0) {
141 dev_err(&tpa6130a2_client->dev,
142 "Failed to enable supplies: %d\n", ret);
143 goto exit;
144 }
145
146 data->power_state = 1;
147 tpa6130a2_initialize();
148
149 /* Clear SWS */
150 val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
151 val &= ~TPA6130A2_SWS;
152 tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val);
153 } else {
154 /* set SWS */
155 val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
156 val |= TPA6130A2_SWS;
157 tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val);
158
159 /* Power off */
160 if (data->power_gpio >= 0)
161 gpio_set_value(data->power_gpio, 0);
162
163 ret = regulator_bulk_disable(ARRAY_SIZE(data->supplies),
164 data->supplies);
165 if (ret != 0) {
166 dev_err(&tpa6130a2_client->dev,
167 "Failed to disable supplies: %d\n", ret);
168 goto exit;
169 }
170
171 data->power_state = 0;
172 }
173
174exit:
175 mutex_unlock(&data->mutex);
176 return ret;
177}
178
179static int tpa6130a2_get_reg(struct snd_kcontrol *kcontrol,
180 struct snd_ctl_elem_value *ucontrol)
181{
182 struct soc_mixer_control *mc =
183 (struct soc_mixer_control *)kcontrol->private_value;
184 struct tpa6130a2_data *data;
185 unsigned int reg = mc->reg;
186 unsigned int shift = mc->shift;
187 unsigned int mask = mc->max;
188 unsigned int invert = mc->invert;
189
190 BUG_ON(tpa6130a2_client == NULL);
191 data = i2c_get_clientdata(tpa6130a2_client);
192
193 mutex_lock(&data->mutex);
194
195 ucontrol->value.integer.value[0] =
196 (tpa6130a2_read(reg) >> shift) & mask;
197
198 if (invert)
199 ucontrol->value.integer.value[0] =
200 mask - ucontrol->value.integer.value[0];
201
202 mutex_unlock(&data->mutex);
203 return 0;
204}
205
206static int tpa6130a2_set_reg(struct snd_kcontrol *kcontrol,
207 struct snd_ctl_elem_value *ucontrol)
208{
209 struct soc_mixer_control *mc =
210 (struct soc_mixer_control *)kcontrol->private_value;
211 struct tpa6130a2_data *data;
212 unsigned int reg = mc->reg;
213 unsigned int shift = mc->shift;
214 unsigned int mask = mc->max;
215 unsigned int invert = mc->invert;
216 unsigned int val = (ucontrol->value.integer.value[0] & mask);
217 unsigned int val_reg;
218
219 BUG_ON(tpa6130a2_client == NULL);
220 data = i2c_get_clientdata(tpa6130a2_client);
221
222 if (invert)
223 val = mask - val;
224
225 mutex_lock(&data->mutex);
226
227 val_reg = tpa6130a2_read(reg);
228 if (((val_reg >> shift) & mask) == val) {
229 mutex_unlock(&data->mutex);
230 return 0;
231 }
232
233 val_reg &= ~(mask << shift);
234 val_reg |= val << shift;
235 tpa6130a2_i2c_write(reg, val_reg);
236
237 mutex_unlock(&data->mutex);
238
239 return 1;
240}
241
242/*
243 * TPA6130 volume. From -59.5 to 4 dB with increasing step size when going
244 * down in gain.
245 */
246static const unsigned int tpa6130_tlv[] = {
247 TLV_DB_RANGE_HEAD(10),
248 0, 1, TLV_DB_SCALE_ITEM(-5950, 600, 0),
249 2, 3, TLV_DB_SCALE_ITEM(-5000, 250, 0),
250 4, 5, TLV_DB_SCALE_ITEM(-4550, 160, 0),
251 6, 7, TLV_DB_SCALE_ITEM(-4140, 190, 0),
252 8, 9, TLV_DB_SCALE_ITEM(-3650, 120, 0),
253 10, 11, TLV_DB_SCALE_ITEM(-3330, 160, 0),
254 12, 13, TLV_DB_SCALE_ITEM(-3040, 180, 0),
255 14, 20, TLV_DB_SCALE_ITEM(-2710, 110, 0),
256 21, 37, TLV_DB_SCALE_ITEM(-1960, 74, 0),
257 38, 63, TLV_DB_SCALE_ITEM(-720, 45, 0),
258};
259
260static const struct snd_kcontrol_new tpa6130a2_controls[] = {
261 SOC_SINGLE_EXT_TLV("TPA6130A2 Headphone Playback Volume",
262 TPA6130A2_REG_VOL_MUTE, 0, 0x3f, 0,
263 tpa6130a2_get_reg, tpa6130a2_set_reg,
264 tpa6130_tlv),
265};
266
267/*
268 * Enable or disable channel (left or right)
269 * The bit number for mute and amplifier are the same per channel:
270 * bit 6: Right channel
271 * bit 7: Left channel
272 * in both registers.
273 */
274static void tpa6130a2_channel_enable(u8 channel, int enable)
275{
276 u8 val;
277
278 if (enable) {
279 /* Enable channel */
280 /* Enable amplifier */
281 val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
282 val |= channel;
283 tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val);
284
285 /* Unmute channel */
286 val = tpa6130a2_read(TPA6130A2_REG_VOL_MUTE);
287 val &= ~channel;
288 tpa6130a2_i2c_write(TPA6130A2_REG_VOL_MUTE, val);
289 } else {
290 /* Disable channel */
291 /* Mute channel */
292 val = tpa6130a2_read(TPA6130A2_REG_VOL_MUTE);
293 val |= channel;
294 tpa6130a2_i2c_write(TPA6130A2_REG_VOL_MUTE, val);
295
296 /* Disable amplifier */
297 val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
298 val &= ~channel;
299 tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val);
300 }
301}
302
303static int tpa6130a2_left_event(struct snd_soc_dapm_widget *w,
304 struct snd_kcontrol *kcontrol, int event)
305{
306 switch (event) {
307 case SND_SOC_DAPM_POST_PMU:
308 tpa6130a2_channel_enable(TPA6130A2_HP_EN_L, 1);
309 break;
310 case SND_SOC_DAPM_POST_PMD:
311 tpa6130a2_channel_enable(TPA6130A2_HP_EN_L, 0);
312 break;
313 }
314 return 0;
315}
316
317static int tpa6130a2_right_event(struct snd_soc_dapm_widget *w,
318 struct snd_kcontrol *kcontrol, int event)
319{
320 switch (event) {
321 case SND_SOC_DAPM_POST_PMU:
322 tpa6130a2_channel_enable(TPA6130A2_HP_EN_R, 1);
323 break;
324 case SND_SOC_DAPM_POST_PMD:
325 tpa6130a2_channel_enable(TPA6130A2_HP_EN_R, 0);
326 break;
327 }
328 return 0;
329}
330
331static int tpa6130a2_supply_event(struct snd_soc_dapm_widget *w,
332 struct snd_kcontrol *kcontrol, int event)
333{
334 int ret = 0;
335
336 switch (event) {
337 case SND_SOC_DAPM_POST_PMU:
338 ret = tpa6130a2_power(1);
339 break;
340 case SND_SOC_DAPM_POST_PMD:
341 ret = tpa6130a2_power(0);
342 break;
343 }
344 return ret;
345}
346
347static const struct snd_soc_dapm_widget tpa6130a2_dapm_widgets[] = {
348 SND_SOC_DAPM_PGA_E("TPA6130A2 Left", SND_SOC_NOPM,
349 0, 0, NULL, 0, tpa6130a2_left_event,
350 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
351 SND_SOC_DAPM_PGA_E("TPA6130A2 Right", SND_SOC_NOPM,
352 0, 0, NULL, 0, tpa6130a2_right_event,
353 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
354 SND_SOC_DAPM_SUPPLY("TPA6130A2 Enable", SND_SOC_NOPM,
355 0, 0, tpa6130a2_supply_event,
356 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
357 /* Outputs */
358 SND_SOC_DAPM_HP("TPA6130A2 Headphone Left", NULL),
359 SND_SOC_DAPM_HP("TPA6130A2 Headphone Right", NULL),
360};
361
362static const struct snd_soc_dapm_route audio_map[] = {
363 {"TPA6130A2 Headphone Left", NULL, "TPA6130A2 Left"},
364 {"TPA6130A2 Headphone Right", NULL, "TPA6130A2 Right"},
365
366 {"TPA6130A2 Headphone Left", NULL, "TPA6130A2 Enable"},
367 {"TPA6130A2 Headphone Right", NULL, "TPA6130A2 Enable"},
368};
369
370int tpa6130a2_add_controls(struct snd_soc_codec *codec)
371{
372 snd_soc_dapm_new_controls(codec, tpa6130a2_dapm_widgets,
373 ARRAY_SIZE(tpa6130a2_dapm_widgets));
374
375 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
376
377 return snd_soc_add_controls(codec, tpa6130a2_controls,
378 ARRAY_SIZE(tpa6130a2_controls));
379
380}
381EXPORT_SYMBOL_GPL(tpa6130a2_add_controls);
382
383static int __devinit tpa6130a2_probe(struct i2c_client *client,
384 const struct i2c_device_id *id)
385{
386 struct device *dev;
387 struct tpa6130a2_data *data;
388 struct tpa6130a2_platform_data *pdata;
389 int i, ret;
390
391 dev = &client->dev;
392
393 if (client->dev.platform_data == NULL) {
394 dev_err(dev, "Platform data not set\n");
395 dump_stack();
396 return -ENODEV;
397 }
398
399 data = kzalloc(sizeof(*data), GFP_KERNEL);
400 if (data == NULL) {
401 dev_err(dev, "Can not allocate memory\n");
402 return -ENOMEM;
403 }
404
405 tpa6130a2_client = client;
406
407 i2c_set_clientdata(tpa6130a2_client, data);
408
409 pdata = client->dev.platform_data;
410 data->power_gpio = pdata->power_gpio;
411
412 mutex_init(&data->mutex);
413
414 /* Set default register values */
415 data->regs[TPA6130A2_REG_CONTROL] = TPA6130A2_SWS;
416 data->regs[TPA6130A2_REG_VOL_MUTE] = TPA6130A2_MUTE_R |
417 TPA6130A2_MUTE_L;
418
419 if (data->power_gpio >= 0) {
420 ret = gpio_request(data->power_gpio, "tpa6130a2 enable");
421 if (ret < 0) {
422 dev_err(dev, "Failed to request power GPIO (%d)\n",
423 data->power_gpio);
424 goto err_gpio;
425 }
426 gpio_direction_output(data->power_gpio, 0);
427 }
428
429 switch (pdata->id) {
430 case TPA6130A2:
431 for (i = 0; i < ARRAY_SIZE(data->supplies); i++)
432 data->supplies[i].supply = tpa6130a2_supply_names[i];
433 break;
434 case TPA6140A2:
435 for (i = 0; i < ARRAY_SIZE(data->supplies); i++)
436 data->supplies[i].supply = tpa6140a2_supply_names[i];;
437 break;
438 default:
439 dev_warn(dev, "Unknown TPA model (%d). Assuming 6130A2\n",
440 pdata->id);
441 for (i = 0; i < ARRAY_SIZE(data->supplies); i++)
442 data->supplies[i].supply = tpa6130a2_supply_names[i];
443 }
444
445 ret = regulator_bulk_get(dev, ARRAY_SIZE(data->supplies),
446 data->supplies);
447 if (ret != 0) {
448 dev_err(dev, "Failed to request supplies: %d\n", ret);
449 goto err_regulator;
450 }
451
452 ret = tpa6130a2_power(1);
453 if (ret != 0)
454 goto err_power;
455
456
457 /* Read version */
458 ret = tpa6130a2_i2c_read(TPA6130A2_REG_VERSION) &
459 TPA6130A2_VERSION_MASK;
460 if ((ret != 1) && (ret != 2))
461 dev_warn(dev, "UNTESTED version detected (%d)\n", ret);
462
463 /* Disable the chip */
464 ret = tpa6130a2_power(0);
465 if (ret != 0)
466 goto err_power;
467
468 return 0;
469
470err_power:
471 regulator_bulk_free(ARRAY_SIZE(data->supplies), data->supplies);
472err_regulator:
473 if (data->power_gpio >= 0)
474 gpio_free(data->power_gpio);
475err_gpio:
476 kfree(data);
477 i2c_set_clientdata(tpa6130a2_client, NULL);
478 tpa6130a2_client = NULL;
479
480 return ret;
481}
482
483static int __devexit tpa6130a2_remove(struct i2c_client *client)
484{
485 struct tpa6130a2_data *data = i2c_get_clientdata(client);
486
487 tpa6130a2_power(0);
488
489 if (data->power_gpio >= 0)
490 gpio_free(data->power_gpio);
491
492 regulator_bulk_free(ARRAY_SIZE(data->supplies), data->supplies);
493
494 kfree(data);
495 tpa6130a2_client = NULL;
496
497 return 0;
498}
499
500static const struct i2c_device_id tpa6130a2_id[] = {
501 { "tpa6130a2", 0 },
502 { }
503};
504MODULE_DEVICE_TABLE(i2c, tpa6130a2_id);
505
506static struct i2c_driver tpa6130a2_i2c_driver = {
507 .driver = {
508 .name = "tpa6130a2",
509 .owner = THIS_MODULE,
510 },
511 .probe = tpa6130a2_probe,
512 .remove = __devexit_p(tpa6130a2_remove),
513 .id_table = tpa6130a2_id,
514};
515
516static int __init tpa6130a2_init(void)
517{
518 return i2c_add_driver(&tpa6130a2_i2c_driver);
519}
520
521static void __exit tpa6130a2_exit(void)
522{
523 i2c_del_driver(&tpa6130a2_i2c_driver);
524}
525
526MODULE_AUTHOR("Peter Ujfalusi");
527MODULE_DESCRIPTION("TPA6130A2 Headphone amplifier driver");
528MODULE_LICENSE("GPL");
529
530module_init(tpa6130a2_init);
531module_exit(tpa6130a2_exit);
diff --git a/sound/soc/codecs/tpa6130a2.h b/sound/soc/codecs/tpa6130a2.h
new file mode 100644
index 000000000000..57e867fd86d1
--- /dev/null
+++ b/sound/soc/codecs/tpa6130a2.h
@@ -0,0 +1,61 @@
1/*
2 * ALSA SoC TPA6130A2 amplifier driver
3 *
4 * Copyright (C) Nokia Corporation
5 *
6 * Author: Peter Ujfalusi <peter.ujfalusi@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#ifndef __TPA6130A2_H__
25#define __TPA6130A2_H__
26
27/* Register addresses */
28#define TPA6130A2_REG_CONTROL 0x01
29#define TPA6130A2_REG_VOL_MUTE 0x02
30#define TPA6130A2_REG_OUT_IMPEDANCE 0x03
31#define TPA6130A2_REG_VERSION 0x04
32
33#define TPA6130A2_CACHEREGNUM (TPA6130A2_REG_VERSION + 1)
34
35/* Register bits */
36/* TPA6130A2_REG_CONTROL (0x01) */
37#define TPA6130A2_SWS (0x01 << 0)
38#define TPA6130A2_TERMAL (0x01 << 1)
39#define TPA6130A2_MODE(x) (x << 4)
40#define TPA6130A2_MODE_STEREO (0x00)
41#define TPA6130A2_MODE_DUAL_MONO (0x01)
42#define TPA6130A2_MODE_BRIDGE (0x02)
43#define TPA6130A2_MODE_MASK (0x03)
44#define TPA6130A2_HP_EN_R (0x01 << 6)
45#define TPA6130A2_HP_EN_L (0x01 << 7)
46
47/* TPA6130A2_REG_VOL_MUTE (0x02) */
48#define TPA6130A2_VOLUME(x) ((x & 0x3f) << 0)
49#define TPA6130A2_MUTE_R (0x01 << 6)
50#define TPA6130A2_MUTE_L (0x01 << 7)
51
52/* TPA6130A2_REG_OUT_IMPEDANCE (0x03) */
53#define TPA6130A2_HIZ_R (0x01 << 0)
54#define TPA6130A2_HIZ_L (0x01 << 1)
55
56/* TPA6130A2_REG_VERSION (0x04) */
57#define TPA6130A2_VERSION_MASK (0x0f)
58
59extern int tpa6130a2_add_controls(struct snd_soc_codec *codec);
60
61#endif /* __TPA6130A2_H__ */
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index 4df7c6c61c76..520ffd6536c3 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -26,7 +26,8 @@
26#include <linux/pm.h> 26#include <linux/pm.h>
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/twl4030.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>
@@ -55,7 +56,7 @@ static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = {
55 0x0c, /* REG_ATXR1PGA (0xB) */ 56 0x0c, /* REG_ATXR1PGA (0xB) */
56 0x00, /* REG_AVTXL2PGA (0xC) */ 57 0x00, /* REG_AVTXL2PGA (0xC) */
57 0x00, /* REG_AVTXR2PGA (0xD) */ 58 0x00, /* REG_AVTXR2PGA (0xD) */
58 0x01, /* REG_AUDIO_IF (0xE) */ 59 0x00, /* REG_AUDIO_IF (0xE) */
59 0x00, /* REG_VOICE_IF (0xF) */ 60 0x00, /* REG_VOICE_IF (0xF) */
60 0x00, /* REG_ARXR1PGA (0x10) */ 61 0x00, /* REG_ARXR1PGA (0x10) */
61 0x00, /* REG_ARXL1PGA (0x11) */ 62 0x00, /* REG_ARXL1PGA (0x11) */
@@ -64,19 +65,19 @@ static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = {
64 0x00, /* REG_VRXPGA (0x14) */ 65 0x00, /* REG_VRXPGA (0x14) */
65 0x00, /* REG_VSTPGA (0x15) */ 66 0x00, /* REG_VSTPGA (0x15) */
66 0x00, /* REG_VRX2ARXPGA (0x16) */ 67 0x00, /* REG_VRX2ARXPGA (0x16) */
67 0x0c, /* REG_AVDAC_CTL (0x17) */ 68 0x00, /* REG_AVDAC_CTL (0x17) */
68 0x00, /* REG_ARX2VTXPGA (0x18) */ 69 0x00, /* REG_ARX2VTXPGA (0x18) */
69 0x00, /* REG_ARXL1_APGA_CTL (0x19) */ 70 0x00, /* REG_ARXL1_APGA_CTL (0x19) */
70 0x00, /* REG_ARXR1_APGA_CTL (0x1A) */ 71 0x00, /* REG_ARXR1_APGA_CTL (0x1A) */
71 0x4b, /* REG_ARXL2_APGA_CTL (0x1B) */ 72 0x4a, /* REG_ARXL2_APGA_CTL (0x1B) */
72 0x4b, /* REG_ARXR2_APGA_CTL (0x1C) */ 73 0x4a, /* REG_ARXR2_APGA_CTL (0x1C) */
73 0x00, /* REG_ATX2ARXPGA (0x1D) */ 74 0x00, /* REG_ATX2ARXPGA (0x1D) */
74 0x00, /* REG_BT_IF (0x1E) */ 75 0x00, /* REG_BT_IF (0x1E) */
75 0x00, /* REG_BTPGA (0x1F) */ 76 0x00, /* REG_BTPGA (0x1F) */
76 0x00, /* REG_BTSTPGA (0x20) */ 77 0x00, /* REG_BTSTPGA (0x20) */
77 0x00, /* REG_EAR_CTL (0x21) */ 78 0x00, /* REG_EAR_CTL (0x21) */
78 0x24, /* REG_HS_SEL (0x22) */ 79 0x00, /* REG_HS_SEL (0x22) */
79 0x0a, /* REG_HS_GAIN_SET (0x23) */ 80 0x00, /* REG_HS_GAIN_SET (0x23) */
80 0x00, /* REG_HS_POPN_SET (0x24) */ 81 0x00, /* REG_HS_POPN_SET (0x24) */
81 0x00, /* REG_PREDL_CTL (0x25) */ 82 0x00, /* REG_PREDL_CTL (0x25) */
82 0x00, /* REG_PREDR_CTL (0x26) */ 83 0x00, /* REG_PREDR_CTL (0x26) */
@@ -99,7 +100,7 @@ static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = {
99 0x00, /* REG_I2S_RX_SCRAMBLE_H (0x37) */ 100 0x00, /* REG_I2S_RX_SCRAMBLE_H (0x37) */
100 0x00, /* REG_I2S_RX_SCRAMBLE_M (0x38) */ 101 0x00, /* REG_I2S_RX_SCRAMBLE_M (0x38) */
101 0x00, /* REG_I2S_RX_SCRAMBLE_L (0x39) */ 102 0x00, /* REG_I2S_RX_SCRAMBLE_L (0x39) */
102 0x16, /* REG_APLL_CTL (0x3A) */ 103 0x06, /* REG_APLL_CTL (0x3A) */
103 0x00, /* REG_DTMF_CTL (0x3B) */ 104 0x00, /* REG_DTMF_CTL (0x3B) */
104 0x00, /* REG_DTMF_PGA_CTL2 (0x3C) */ 105 0x00, /* REG_DTMF_PGA_CTL2 (0x3C) */
105 0x00, /* REG_DTMF_PGA_CTL1 (0x3D) */ 106 0x00, /* REG_DTMF_PGA_CTL1 (0x3D) */
@@ -120,9 +121,10 @@ static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = {
120 121
121/* codec private data */ 122/* codec private data */
122struct twl4030_priv { 123struct twl4030_priv {
123 unsigned int bypass_state; 124 struct snd_soc_codec codec;
125
124 unsigned int codec_powered; 126 unsigned int codec_powered;
125 unsigned int codec_muted; 127 unsigned int apll_enabled;
126 128
127 struct snd_pcm_substream *master_substream; 129 struct snd_pcm_substream *master_substream;
128 struct snd_pcm_substream *slave_substream; 130 struct snd_pcm_substream *slave_substream;
@@ -174,7 +176,7 @@ static int twl4030_write(struct snd_soc_codec *codec,
174{ 176{
175 twl4030_write_reg_cache(codec, reg, value); 177 twl4030_write_reg_cache(codec, reg, value);
176 if (likely(reg < TWL4030_REG_SW_SHADOW)) 178 if (likely(reg < TWL4030_REG_SW_SHADOW))
177 return twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, value, 179 return twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, value,
178 reg); 180 reg);
179 else 181 else
180 return 0; 182 return 0;
@@ -183,19 +185,20 @@ static int twl4030_write(struct snd_soc_codec *codec,
183static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable) 185static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable)
184{ 186{
185 struct twl4030_priv *twl4030 = codec->private_data; 187 struct twl4030_priv *twl4030 = codec->private_data;
186 u8 mode; 188 int mode;
187 189
188 if (enable == twl4030->codec_powered) 190 if (enable == twl4030->codec_powered)
189 return; 191 return;
190 192
191 mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE);
192 if (enable) 193 if (enable)
193 mode |= TWL4030_CODECPDZ; 194 mode = twl4030_codec_enable_resource(TWL4030_CODEC_RES_POWER);
194 else 195 else
195 mode &= ~TWL4030_CODECPDZ; 196 mode = twl4030_codec_disable_resource(TWL4030_CODEC_RES_POWER);
196 197
197 twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode); 198 if (mode >= 0) {
198 twl4030->codec_powered = enable; 199 twl4030_write_reg_cache(codec, TWL4030_REG_CODEC_MODE, mode);
200 twl4030->codec_powered = enable;
201 }
199 202
200 /* REVISIT: this delay is present in TI sample drivers */ 203 /* REVISIT: this delay is present in TI sample drivers */
201 /* but there seems to be no TRM requirement for it */ 204 /* but there seems to be no TRM requirement for it */
@@ -212,31 +215,30 @@ static void twl4030_init_chip(struct snd_soc_codec *codec)
212 215
213 /* set all audio section registers to reasonable defaults */ 216 /* set all audio section registers to reasonable defaults */
214 for (i = TWL4030_REG_OPTION; i <= TWL4030_REG_MISC_SET_2; i++) 217 for (i = TWL4030_REG_OPTION; i <= TWL4030_REG_MISC_SET_2; i++)
215 twl4030_write(codec, i, cache[i]); 218 if (i != TWL4030_REG_APLL_CTL)
219 twl4030_write(codec, i, cache[i]);
216 220
217} 221}
218 222
219static void twl4030_codec_mute(struct snd_soc_codec *codec, int mute) 223static void twl4030_apll_enable(struct snd_soc_codec *codec, int enable)
220{ 224{
221 struct twl4030_priv *twl4030 = codec->private_data; 225 struct twl4030_priv *twl4030 = codec->private_data;
222 u8 reg_val; 226 int status;
223 227
224 if (mute == twl4030->codec_muted) 228 if (enable == twl4030->apll_enabled)
225 return; 229 return;
226 230
227 if (mute) { 231 if (enable)
228 /* Disable PLL */
229 reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_APLL_CTL);
230 reg_val &= ~TWL4030_APLL_EN;
231 twl4030_write(codec, TWL4030_REG_APLL_CTL, reg_val);
232 } else {
233 /* Enable PLL */ 232 /* Enable PLL */
234 reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_APLL_CTL); 233 status = twl4030_codec_enable_resource(TWL4030_CODEC_RES_APLL);
235 reg_val |= TWL4030_APLL_EN; 234 else
236 twl4030_write(codec, TWL4030_REG_APLL_CTL, reg_val); 235 /* Disable PLL */
237 } 236 status = twl4030_codec_disable_resource(TWL4030_CODEC_RES_APLL);
237
238 if (status >= 0)
239 twl4030_write_reg_cache(codec, TWL4030_REG_APLL_CTL, status);
238 240
239 twl4030->codec_muted = mute; 241 twl4030->apll_enabled = enable;
240} 242}
241 243
242static void twl4030_power_up(struct snd_soc_codec *codec) 244static void twl4030_power_up(struct snd_soc_codec *codec)
@@ -260,7 +262,7 @@ static void twl4030_power_up(struct snd_soc_codec *codec)
260 do { 262 do {
261 /* this takes a little while, so don't slam i2c */ 263 /* this takes a little while, so don't slam i2c */
262 udelay(2000); 264 udelay(2000);
263 twl4030_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte, 265 twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte,
264 TWL4030_REG_ANAMICL); 266 TWL4030_REG_ANAMICL);
265 } while ((i++ < 100) && 267 } while ((i++ < 100) &&
266 ((byte & TWL4030_CNCL_OFFSET_START) == 268 ((byte & TWL4030_CNCL_OFFSET_START) ==
@@ -541,7 +543,7 @@ static int pin_name##pga_event(struct snd_soc_dapm_widget *w, \
541 break; \ 543 break; \
542 case SND_SOC_DAPM_POST_PMD: \ 544 case SND_SOC_DAPM_POST_PMD: \
543 reg_val = twl4030_read_reg_cache(w->codec, reg); \ 545 reg_val = twl4030_read_reg_cache(w->codec, reg); \
544 twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, \ 546 twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, \
545 reg_val & (~mask), \ 547 reg_val & (~mask), \
546 reg); \ 548 reg); \
547 break; \ 549 break; \
@@ -613,6 +615,27 @@ static int handsfreerpga_event(struct snd_soc_dapm_widget *w,
613 return 0; 615 return 0;
614} 616}
615 617
618static int vibramux_event(struct snd_soc_dapm_widget *w,
619 struct snd_kcontrol *kcontrol, int event)
620{
621 twl4030_write(w->codec, TWL4030_REG_VIBRA_SET, 0xff);
622 return 0;
623}
624
625static int apll_event(struct snd_soc_dapm_widget *w,
626 struct snd_kcontrol *kcontrol, int event)
627{
628 switch (event) {
629 case SND_SOC_DAPM_PRE_PMU:
630 twl4030_apll_enable(w->codec, 1);
631 break;
632 case SND_SOC_DAPM_POST_PMD:
633 twl4030_apll_enable(w->codec, 0);
634 break;
635 }
636 return 0;
637}
638
616static void headset_ramp(struct snd_soc_codec *codec, int ramp) 639static void headset_ramp(struct snd_soc_codec *codec, int ramp)
617{ 640{
618 struct snd_soc_device *socdev = codec->socdev; 641 struct snd_soc_device *socdev = codec->socdev;
@@ -657,7 +680,7 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
657 mdelay((ramp_base[(hs_pop & TWL4030_RAMP_DELAY) >> 2] / 680 mdelay((ramp_base[(hs_pop & TWL4030_RAMP_DELAY) >> 2] /
658 twl4030->sysclk) + 1); 681 twl4030->sysclk) + 1);
659 /* Bypass the reg_cache to mute the headset */ 682 /* Bypass the reg_cache to mute the headset */
660 twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, 683 twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
661 hs_gain & (~0x0f), 684 hs_gain & (~0x0f),
662 TWL4030_REG_HS_GAIN_SET); 685 TWL4030_REG_HS_GAIN_SET);
663 686
@@ -724,67 +747,6 @@ static int headsetrpga_event(struct snd_soc_dapm_widget *w,
724 return 0; 747 return 0;
725} 748}
726 749
727static int bypass_event(struct snd_soc_dapm_widget *w,
728 struct snd_kcontrol *kcontrol, int event)
729{
730 struct soc_mixer_control *m =
731 (struct soc_mixer_control *)w->kcontrols->private_value;
732 struct twl4030_priv *twl4030 = w->codec->private_data;
733 unsigned char reg, misc;
734
735 reg = twl4030_read_reg_cache(w->codec, m->reg);
736
737 /*
738 * bypass_state[0:3] - analog HiFi bypass
739 * bypass_state[4] - analog voice bypass
740 * bypass_state[5] - digital voice bypass
741 * bypass_state[6:7] - digital HiFi bypass
742 */
743 if (m->reg == TWL4030_REG_VSTPGA) {
744 /* Voice digital bypass */
745 if (reg)
746 twl4030->bypass_state |= (1 << 5);
747 else
748 twl4030->bypass_state &= ~(1 << 5);
749 } else if (m->reg <= TWL4030_REG_ARXR2_APGA_CTL) {
750 /* Analog bypass */
751 if (reg & (1 << m->shift))
752 twl4030->bypass_state |=
753 (1 << (m->reg - TWL4030_REG_ARXL1_APGA_CTL));
754 else
755 twl4030->bypass_state &=
756 ~(1 << (m->reg - TWL4030_REG_ARXL1_APGA_CTL));
757 } else if (m->reg == TWL4030_REG_VDL_APGA_CTL) {
758 /* Analog voice bypass */
759 if (reg & (1 << m->shift))
760 twl4030->bypass_state |= (1 << 4);
761 else
762 twl4030->bypass_state &= ~(1 << 4);
763 } else {
764 /* Digital bypass */
765 if (reg & (0x7 << m->shift))
766 twl4030->bypass_state |= (1 << (m->shift ? 7 : 6));
767 else
768 twl4030->bypass_state &= ~(1 << (m->shift ? 7 : 6));
769 }
770
771 /* Enable master analog loopback mode if any analog switch is enabled*/
772 misc = twl4030_read_reg_cache(w->codec, TWL4030_REG_MISC_SET_1);
773 if (twl4030->bypass_state & 0x1F)
774 misc |= TWL4030_FMLOOP_EN;
775 else
776 misc &= ~TWL4030_FMLOOP_EN;
777 twl4030_write(w->codec, TWL4030_REG_MISC_SET_1, misc);
778
779 if (w->codec->bias_level == SND_SOC_BIAS_STANDBY) {
780 if (twl4030->bypass_state)
781 twl4030_codec_mute(w->codec, 0);
782 else
783 twl4030_codec_mute(w->codec, 1);
784 }
785 return 0;
786}
787
788/* 750/*
789 * Some of the gain controls in TWL (mostly those which are associated with 751 * Some of the gain controls in TWL (mostly those which are associated with
790 * the outputs) are implemented in an interesting way: 752 * the outputs) are implemented in an interesting way:
@@ -1192,32 +1154,28 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1192 SND_SOC_NOPM, 0, 0), 1154 SND_SOC_NOPM, 0, 0),
1193 1155
1194 /* Analog bypasses */ 1156 /* Analog bypasses */
1195 SND_SOC_DAPM_SWITCH_E("Right1 Analog Loopback", SND_SOC_NOPM, 0, 0, 1157 SND_SOC_DAPM_SWITCH("Right1 Analog Loopback", SND_SOC_NOPM, 0, 0,
1196 &twl4030_dapm_abypassr1_control, bypass_event, 1158 &twl4030_dapm_abypassr1_control),
1197 SND_SOC_DAPM_POST_REG), 1159 SND_SOC_DAPM_SWITCH("Left1 Analog Loopback", SND_SOC_NOPM, 0, 0,
1198 SND_SOC_DAPM_SWITCH_E("Left1 Analog Loopback", SND_SOC_NOPM, 0, 0, 1160 &twl4030_dapm_abypassl1_control),
1199 &twl4030_dapm_abypassl1_control, 1161 SND_SOC_DAPM_SWITCH("Right2 Analog Loopback", SND_SOC_NOPM, 0, 0,
1200 bypass_event, SND_SOC_DAPM_POST_REG), 1162 &twl4030_dapm_abypassr2_control),
1201 SND_SOC_DAPM_SWITCH_E("Right2 Analog Loopback", SND_SOC_NOPM, 0, 0, 1163 SND_SOC_DAPM_SWITCH("Left2 Analog Loopback", SND_SOC_NOPM, 0, 0,
1202 &twl4030_dapm_abypassr2_control, 1164 &twl4030_dapm_abypassl2_control),
1203 bypass_event, SND_SOC_DAPM_POST_REG), 1165 SND_SOC_DAPM_SWITCH("Voice Analog Loopback", SND_SOC_NOPM, 0, 0,
1204 SND_SOC_DAPM_SWITCH_E("Left2 Analog Loopback", SND_SOC_NOPM, 0, 0, 1166 &twl4030_dapm_abypassv_control),
1205 &twl4030_dapm_abypassl2_control, 1167
1206 bypass_event, SND_SOC_DAPM_POST_REG), 1168 /* Master analog loopback switch */
1207 SND_SOC_DAPM_SWITCH_E("Voice Analog Loopback", SND_SOC_NOPM, 0, 0, 1169 SND_SOC_DAPM_SUPPLY("FM Loop Enable", TWL4030_REG_MISC_SET_1, 5, 0,
1208 &twl4030_dapm_abypassv_control, 1170 NULL, 0),
1209 bypass_event, SND_SOC_DAPM_POST_REG),
1210 1171
1211 /* Digital bypasses */ 1172 /* Digital bypasses */
1212 SND_SOC_DAPM_SWITCH_E("Left Digital Loopback", SND_SOC_NOPM, 0, 0, 1173 SND_SOC_DAPM_SWITCH("Left Digital Loopback", SND_SOC_NOPM, 0, 0,
1213 &twl4030_dapm_dbypassl_control, bypass_event, 1174 &twl4030_dapm_dbypassl_control),
1214 SND_SOC_DAPM_POST_REG), 1175 SND_SOC_DAPM_SWITCH("Right Digital Loopback", SND_SOC_NOPM, 0, 0,
1215 SND_SOC_DAPM_SWITCH_E("Right Digital Loopback", SND_SOC_NOPM, 0, 0, 1176 &twl4030_dapm_dbypassr_control),
1216 &twl4030_dapm_dbypassr_control, bypass_event, 1177 SND_SOC_DAPM_SWITCH("Voice Digital Loopback", SND_SOC_NOPM, 0, 0,
1217 SND_SOC_DAPM_POST_REG), 1178 &twl4030_dapm_dbypassv_control),
1218 SND_SOC_DAPM_SWITCH_E("Voice Digital Loopback", SND_SOC_NOPM, 0, 0,
1219 &twl4030_dapm_dbypassv_control, bypass_event,
1220 SND_SOC_DAPM_POST_REG),
1221 1179
1222 /* Digital mixers, power control for the physical DACs */ 1180 /* Digital mixers, power control for the physical DACs */
1223 SND_SOC_DAPM_MIXER("Digital R1 Playback Mixer", 1181 SND_SOC_DAPM_MIXER("Digital R1 Playback Mixer",
@@ -1243,6 +1201,11 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1243 SND_SOC_DAPM_MIXER("Analog Voice Playback Mixer", 1201 SND_SOC_DAPM_MIXER("Analog Voice Playback Mixer",
1244 TWL4030_REG_VDL_APGA_CTL, 0, 0, NULL, 0), 1202 TWL4030_REG_VDL_APGA_CTL, 0, 0, NULL, 0),
1245 1203
1204 SND_SOC_DAPM_SUPPLY("APLL Enable", SND_SOC_NOPM, 0, 0, apll_event,
1205 SND_SOC_DAPM_PRE_PMU|SND_SOC_DAPM_POST_PMD),
1206
1207 SND_SOC_DAPM_SUPPLY("AIF Enable", TWL4030_REG_AUDIO_IF, 0, 0, NULL, 0),
1208
1246 /* Output MIXER controls */ 1209 /* Output MIXER controls */
1247 /* Earpiece */ 1210 /* Earpiece */
1248 SND_SOC_DAPM_MIXER("Earpiece Mixer", SND_SOC_NOPM, 0, 0, 1211 SND_SOC_DAPM_MIXER("Earpiece Mixer", SND_SOC_NOPM, 0, 0,
@@ -1308,8 +1271,9 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1308 0, 0, NULL, 0, handsfreerpga_event, 1271 0, 0, NULL, 0, handsfreerpga_event,
1309 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), 1272 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1310 /* Vibra */ 1273 /* Vibra */
1311 SND_SOC_DAPM_MUX("Vibra Mux", TWL4030_REG_VIBRA_CTL, 0, 0, 1274 SND_SOC_DAPM_MUX_E("Vibra Mux", TWL4030_REG_VIBRA_CTL, 0, 0,
1312 &twl4030_dapm_vibra_control), 1275 &twl4030_dapm_vibra_control, vibramux_event,
1276 SND_SOC_DAPM_PRE_PMU),
1313 SND_SOC_DAPM_MUX("Vibra Route", SND_SOC_NOPM, 0, 0, 1277 SND_SOC_DAPM_MUX("Vibra Route", SND_SOC_NOPM, 0, 0,
1314 &twl4030_dapm_vibrapath_control), 1278 &twl4030_dapm_vibrapath_control),
1315 1279
@@ -1369,6 +1333,18 @@ static const struct snd_soc_dapm_route intercon[] = {
1369 {"Digital R2 Playback Mixer", NULL, "DAC Right2"}, 1333 {"Digital R2 Playback Mixer", NULL, "DAC Right2"},
1370 {"Digital Voice Playback Mixer", NULL, "DAC Voice"}, 1334 {"Digital Voice Playback Mixer", NULL, "DAC Voice"},
1371 1335
1336 /* Supply for the digital part (APLL) */
1337 {"Digital R1 Playback Mixer", NULL, "APLL Enable"},
1338 {"Digital L1 Playback Mixer", NULL, "APLL Enable"},
1339 {"Digital R2 Playback Mixer", NULL, "APLL Enable"},
1340 {"Digital L2 Playback Mixer", NULL, "APLL Enable"},
1341 {"Digital Voice Playback Mixer", NULL, "APLL Enable"},
1342
1343 {"Digital R1 Playback Mixer", NULL, "AIF Enable"},
1344 {"Digital L1 Playback Mixer", NULL, "AIF Enable"},
1345 {"Digital R2 Playback Mixer", NULL, "AIF Enable"},
1346 {"Digital L2 Playback Mixer", NULL, "AIF Enable"},
1347
1372 {"Analog L1 Playback Mixer", NULL, "Digital L1 Playback Mixer"}, 1348 {"Analog L1 Playback Mixer", NULL, "Digital L1 Playback Mixer"},
1373 {"Analog R1 Playback Mixer", NULL, "Digital R1 Playback Mixer"}, 1349 {"Analog R1 Playback Mixer", NULL, "Digital R1 Playback Mixer"},
1374 {"Analog L2 Playback Mixer", NULL, "Digital L2 Playback Mixer"}, 1350 {"Analog L2 Playback Mixer", NULL, "Digital L2 Playback Mixer"},
@@ -1482,6 +1458,16 @@ static const struct snd_soc_dapm_route intercon[] = {
1482 {"ADC Virtual Left2", NULL, "TX2 Capture Route"}, 1458 {"ADC Virtual Left2", NULL, "TX2 Capture Route"},
1483 {"ADC Virtual Right2", NULL, "TX2 Capture Route"}, 1459 {"ADC Virtual Right2", NULL, "TX2 Capture Route"},
1484 1460
1461 {"ADC Virtual Left1", NULL, "APLL Enable"},
1462 {"ADC Virtual Right1", NULL, "APLL Enable"},
1463 {"ADC Virtual Left2", NULL, "APLL Enable"},
1464 {"ADC Virtual Right2", NULL, "APLL Enable"},
1465
1466 {"ADC Virtual Left1", NULL, "AIF Enable"},
1467 {"ADC Virtual Right1", NULL, "AIF Enable"},
1468 {"ADC Virtual Left2", NULL, "AIF Enable"},
1469 {"ADC Virtual Right2", NULL, "AIF Enable"},
1470
1485 /* Analog bypass routes */ 1471 /* Analog bypass routes */
1486 {"Right1 Analog Loopback", "Switch", "Analog Right"}, 1472 {"Right1 Analog Loopback", "Switch", "Analog Right"},
1487 {"Left1 Analog Loopback", "Switch", "Analog Left"}, 1473 {"Left1 Analog Loopback", "Switch", "Analog Left"},
@@ -1489,6 +1475,13 @@ static const struct snd_soc_dapm_route intercon[] = {
1489 {"Left2 Analog Loopback", "Switch", "Analog Left"}, 1475 {"Left2 Analog Loopback", "Switch", "Analog Left"},
1490 {"Voice Analog Loopback", "Switch", "Analog Left"}, 1476 {"Voice Analog Loopback", "Switch", "Analog Left"},
1491 1477
1478 /* Supply for the Analog loopbacks */
1479 {"Right1 Analog Loopback", NULL, "FM Loop Enable"},
1480 {"Left1 Analog Loopback", NULL, "FM Loop Enable"},
1481 {"Right2 Analog Loopback", NULL, "FM Loop Enable"},
1482 {"Left2 Analog Loopback", NULL, "FM Loop Enable"},
1483 {"Voice Analog Loopback", NULL, "FM Loop Enable"},
1484
1492 {"Analog R1 Playback Mixer", NULL, "Right1 Analog Loopback"}, 1485 {"Analog R1 Playback Mixer", NULL, "Right1 Analog Loopback"},
1493 {"Analog L1 Playback Mixer", NULL, "Left1 Analog Loopback"}, 1486 {"Analog L1 Playback Mixer", NULL, "Left1 Analog Loopback"},
1494 {"Analog R2 Playback Mixer", NULL, "Right2 Analog Loopback"}, 1487 {"Analog R2 Playback Mixer", NULL, "Right2 Analog Loopback"},
@@ -1513,32 +1506,20 @@ static int twl4030_add_widgets(struct snd_soc_codec *codec)
1513 1506
1514 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); 1507 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
1515 1508
1516 snd_soc_dapm_new_widgets(codec);
1517 return 0; 1509 return 0;
1518} 1510}
1519 1511
1520static int twl4030_set_bias_level(struct snd_soc_codec *codec, 1512static int twl4030_set_bias_level(struct snd_soc_codec *codec,
1521 enum snd_soc_bias_level level) 1513 enum snd_soc_bias_level level)
1522{ 1514{
1523 struct twl4030_priv *twl4030 = codec->private_data;
1524
1525 switch (level) { 1515 switch (level) {
1526 case SND_SOC_BIAS_ON: 1516 case SND_SOC_BIAS_ON:
1527 twl4030_codec_mute(codec, 0);
1528 break; 1517 break;
1529 case SND_SOC_BIAS_PREPARE: 1518 case SND_SOC_BIAS_PREPARE:
1530 twl4030_power_up(codec);
1531 if (twl4030->bypass_state)
1532 twl4030_codec_mute(codec, 0);
1533 else
1534 twl4030_codec_mute(codec, 1);
1535 break; 1519 break;
1536 case SND_SOC_BIAS_STANDBY: 1520 case SND_SOC_BIAS_STANDBY:
1537 twl4030_power_up(codec); 1521 if (codec->bias_level == SND_SOC_BIAS_OFF)
1538 if (twl4030->bypass_state) 1522 twl4030_power_up(codec);
1539 twl4030_codec_mute(codec, 0);
1540 else
1541 twl4030_codec_mute(codec, 1);
1542 break; 1523 break;
1543 case SND_SOC_BIAS_OFF: 1524 case SND_SOC_BIAS_OFF:
1544 twl4030_power_down(codec); 1525 twl4030_power_down(codec);
@@ -1785,29 +1766,23 @@ static int twl4030_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1785{ 1766{
1786 struct snd_soc_codec *codec = codec_dai->codec; 1767 struct snd_soc_codec *codec = codec_dai->codec;
1787 struct twl4030_priv *twl4030 = codec->private_data; 1768 struct twl4030_priv *twl4030 = codec->private_data;
1788 u8 infreq;
1789 1769
1790 switch (freq) { 1770 switch (freq) {
1791 case 19200000: 1771 case 19200000:
1792 infreq = TWL4030_APLL_INFREQ_19200KHZ;
1793 twl4030->sysclk = 19200;
1794 break;
1795 case 26000000: 1772 case 26000000:
1796 infreq = TWL4030_APLL_INFREQ_26000KHZ;
1797 twl4030->sysclk = 26000;
1798 break;
1799 case 38400000: 1773 case 38400000:
1800 infreq = TWL4030_APLL_INFREQ_38400KHZ;
1801 twl4030->sysclk = 38400;
1802 break; 1774 break;
1803 default: 1775 default:
1804 printk(KERN_ERR "TWL4030 set sysclk: unknown rate %d\n", 1776 dev_err(codec->dev, "Unsupported APLL mclk: %u\n", freq);
1805 freq);
1806 return -EINVAL; 1777 return -EINVAL;
1807 } 1778 }
1808 1779
1809 infreq |= TWL4030_APLL_EN; 1780 if ((freq / 1000) != twl4030->sysclk) {
1810 twl4030_write(codec, TWL4030_REG_APLL_CTL, infreq); 1781 dev_err(codec->dev,
1782 "Mismatch in APLL mclk: %u (configured: %u)\n",
1783 freq, twl4030->sysclk * 1000);
1784 return -EINVAL;
1785 }
1811 1786
1812 return 0; 1787 return 0;
1813} 1788}
@@ -1905,18 +1880,16 @@ static int twl4030_voice_startup(struct snd_pcm_substream *substream,
1905 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1880 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1906 struct snd_soc_device *socdev = rtd->socdev; 1881 struct snd_soc_device *socdev = rtd->socdev;
1907 struct snd_soc_codec *codec = socdev->card->codec; 1882 struct snd_soc_codec *codec = socdev->card->codec;
1908 u8 infreq; 1883 struct twl4030_priv *twl4030 = codec->private_data;
1909 u8 mode; 1884 u8 mode;
1910 1885
1911 /* If the system master clock is not 26MHz, the voice PCM interface is 1886 /* If the system master clock is not 26MHz, the voice PCM interface is
1912 * not avilable. 1887 * not avilable.
1913 */ 1888 */
1914 infreq = twl4030_read_reg_cache(codec, TWL4030_REG_APLL_CTL) 1889 if (twl4030->sysclk != 26000) {
1915 & TWL4030_APLL_INFREQ; 1890 dev_err(codec->dev, "The board is configured for %u Hz, while"
1916 1891 "the Voice interface needs 26MHz APLL mclk\n",
1917 if (infreq != TWL4030_APLL_INFREQ_26000KHZ) { 1892 twl4030->sysclk * 1000);
1918 printk(KERN_ERR "TWL4030 voice startup: "
1919 "MCLK is not 26MHz, call set_sysclk() on init\n");
1920 return -EINVAL; 1893 return -EINVAL;
1921 } 1894 }
1922 1895
@@ -1989,21 +1962,19 @@ static int twl4030_voice_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1989 int clk_id, unsigned int freq, int dir) 1962 int clk_id, unsigned int freq, int dir)
1990{ 1963{
1991 struct snd_soc_codec *codec = codec_dai->codec; 1964 struct snd_soc_codec *codec = codec_dai->codec;
1992 u8 infreq; 1965 struct twl4030_priv *twl4030 = codec->private_data;
1993 1966
1994 switch (freq) { 1967 if (freq != 26000000) {
1995 case 26000000: 1968 dev_err(codec->dev, "Unsupported APLL mclk: %u, the Voice"
1996 infreq = TWL4030_APLL_INFREQ_26000KHZ; 1969 "interface needs 26MHz APLL mclk\n", freq);
1997 break; 1970 return -EINVAL;
1998 default: 1971 }
1999 printk(KERN_ERR "TWL4030 voice set sysclk: unknown rate %d\n", 1972 if ((freq / 1000) != twl4030->sysclk) {
2000 freq); 1973 dev_err(codec->dev,
1974 "Mismatch in APLL mclk: %u (configured: %u)\n",
1975 freq, twl4030->sysclk * 1000);
2001 return -EINVAL; 1976 return -EINVAL;
2002 } 1977 }
2003
2004 infreq |= TWL4030_APLL_EN;
2005 twl4030_write(codec, TWL4030_REG_APLL_CTL, infreq);
2006
2007 return 0; 1978 return 0;
2008} 1979}
2009 1980
@@ -2121,7 +2092,7 @@ struct snd_soc_dai twl4030_dai[] = {
2121}; 2092};
2122EXPORT_SYMBOL_GPL(twl4030_dai); 2093EXPORT_SYMBOL_GPL(twl4030_dai);
2123 2094
2124static int twl4030_suspend(struct platform_device *pdev, pm_message_t state) 2095static int twl4030_soc_suspend(struct platform_device *pdev, pm_message_t state)
2125{ 2096{
2126 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 2097 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2127 struct snd_soc_codec *codec = socdev->card->codec; 2098 struct snd_soc_codec *codec = socdev->card->codec;
@@ -2131,7 +2102,7 @@ static int twl4030_suspend(struct platform_device *pdev, pm_message_t state)
2131 return 0; 2102 return 0;
2132} 2103}
2133 2104
2134static int twl4030_resume(struct platform_device *pdev) 2105static int twl4030_soc_resume(struct platform_device *pdev)
2135{ 2106{
2136 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 2107 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2137 struct snd_soc_codec *codec = socdev->card->codec; 2108 struct snd_soc_codec *codec = socdev->card->codec;
@@ -2141,147 +2112,182 @@ static int twl4030_resume(struct platform_device *pdev)
2141 return 0; 2112 return 0;
2142} 2113}
2143 2114
2144/* 2115static struct snd_soc_codec *twl4030_codec;
2145 * initialize the driver
2146 * register the mixer and dsp interfaces with the kernel
2147 */
2148 2116
2149static int twl4030_init(struct snd_soc_device *socdev) 2117static int twl4030_soc_probe(struct platform_device *pdev)
2150{ 2118{
2151 struct snd_soc_codec *codec = socdev->card->codec; 2119 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2152 struct twl4030_setup_data *setup = socdev->codec_data; 2120 struct twl4030_setup_data *setup = socdev->codec_data;
2153 struct twl4030_priv *twl4030 = codec->private_data; 2121 struct snd_soc_codec *codec;
2154 int ret = 0; 2122 struct twl4030_priv *twl4030;
2123 int ret;
2155 2124
2156 printk(KERN_INFO "TWL4030 Audio Codec init \n"); 2125 BUG_ON(!twl4030_codec);
2157 2126
2158 codec->name = "twl4030"; 2127 codec = twl4030_codec;
2159 codec->owner = THIS_MODULE; 2128 twl4030 = codec->private_data;
2160 codec->read = twl4030_read_reg_cache; 2129 socdev->card->codec = codec;
2161 codec->write = twl4030_write;
2162 codec->set_bias_level = twl4030_set_bias_level;
2163 codec->dai = twl4030_dai;
2164 codec->num_dai = ARRAY_SIZE(twl4030_dai),
2165 codec->reg_cache_size = sizeof(twl4030_reg);
2166 codec->reg_cache = kmemdup(twl4030_reg, sizeof(twl4030_reg),
2167 GFP_KERNEL);
2168 if (codec->reg_cache == NULL)
2169 return -ENOMEM;
2170 2130
2171 /* Configuration for headset ramp delay from setup data */ 2131 /* Configuration for headset ramp delay from setup data */
2172 if (setup) { 2132 if (setup) {
2173 unsigned char hs_pop; 2133 unsigned char hs_pop;
2174 2134
2175 if (setup->sysclk) 2135 if (setup->sysclk != twl4030->sysclk)
2176 twl4030->sysclk = setup->sysclk; 2136 dev_warn(&pdev->dev,
2177 else 2137 "Mismatch in APLL mclk: %u (configured: %u)\n",
2178 twl4030->sysclk = 26000; 2138 setup->sysclk, twl4030->sysclk);
2179 2139
2180 hs_pop = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET); 2140 hs_pop = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET);
2181 hs_pop &= ~TWL4030_RAMP_DELAY; 2141 hs_pop &= ~TWL4030_RAMP_DELAY;
2182 hs_pop |= (setup->ramp_delay_value << 2); 2142 hs_pop |= (setup->ramp_delay_value << 2);
2183 twl4030_write_reg_cache(codec, TWL4030_REG_HS_POPN_SET, hs_pop); 2143 twl4030_write_reg_cache(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
2184 } else {
2185 twl4030->sysclk = 26000;
2186 } 2144 }
2187 2145
2188 /* register pcms */ 2146 /* register pcms */
2189 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 2147 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
2190 if (ret < 0) { 2148 if (ret < 0) {
2191 printk(KERN_ERR "twl4030: failed to create pcms\n"); 2149 dev_err(&pdev->dev, "failed to create pcms\n");
2192 goto pcm_err; 2150 return ret;
2193 } 2151 }
2194 2152
2195 twl4030_init_chip(codec);
2196
2197 /* power on device */
2198 twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2199
2200 snd_soc_add_controls(codec, twl4030_snd_controls, 2153 snd_soc_add_controls(codec, twl4030_snd_controls,
2201 ARRAY_SIZE(twl4030_snd_controls)); 2154 ARRAY_SIZE(twl4030_snd_controls));
2202 twl4030_add_widgets(codec); 2155 twl4030_add_widgets(codec);
2203 2156
2204 ret = snd_soc_init_card(socdev); 2157 return 0;
2205 if (ret < 0) { 2158}
2206 printk(KERN_ERR "twl4030: failed to register card\n");
2207 goto card_err;
2208 }
2209 2159
2210 return ret; 2160static int twl4030_soc_remove(struct platform_device *pdev)
2161{
2162 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2163 struct snd_soc_codec *codec = socdev->card->codec;
2211 2164
2212card_err: 2165 twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF);
2213 snd_soc_free_pcms(socdev); 2166 snd_soc_free_pcms(socdev);
2214 snd_soc_dapm_free(socdev); 2167 snd_soc_dapm_free(socdev);
2215pcm_err:
2216 kfree(codec->reg_cache);
2217 return ret;
2218}
2219 2168
2220static struct snd_soc_device *twl4030_socdev; 2169 return 0;
2170}
2221 2171
2222static int twl4030_probe(struct platform_device *pdev) 2172static int __devinit twl4030_codec_probe(struct platform_device *pdev)
2223{ 2173{
2224 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 2174 struct twl4030_codec_audio_data *pdata = pdev->dev.platform_data;
2225 struct snd_soc_codec *codec; 2175 struct snd_soc_codec *codec;
2226 struct twl4030_priv *twl4030; 2176 struct twl4030_priv *twl4030;
2177 int ret;
2227 2178
2228 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); 2179 if (!pdata) {
2229 if (codec == NULL) 2180 dev_err(&pdev->dev, "platform_data is missing\n");
2230 return -ENOMEM; 2181 return -EINVAL;
2182 }
2231 2183
2232 twl4030 = kzalloc(sizeof(struct twl4030_priv), GFP_KERNEL); 2184 twl4030 = kzalloc(sizeof(struct twl4030_priv), GFP_KERNEL);
2233 if (twl4030 == NULL) { 2185 if (twl4030 == NULL) {
2234 kfree(codec); 2186 dev_err(&pdev->dev, "Can not allocate memroy\n");
2235 return -ENOMEM; 2187 return -ENOMEM;
2236 } 2188 }
2237 2189
2190 codec = &twl4030->codec;
2238 codec->private_data = twl4030; 2191 codec->private_data = twl4030;
2239 socdev->card->codec = codec; 2192 codec->dev = &pdev->dev;
2193 twl4030_dai[0].dev = &pdev->dev;
2194 twl4030_dai[1].dev = &pdev->dev;
2195
2240 mutex_init(&codec->mutex); 2196 mutex_init(&codec->mutex);
2241 INIT_LIST_HEAD(&codec->dapm_widgets); 2197 INIT_LIST_HEAD(&codec->dapm_widgets);
2242 INIT_LIST_HEAD(&codec->dapm_paths); 2198 INIT_LIST_HEAD(&codec->dapm_paths);
2243 2199
2244 twl4030_socdev = socdev; 2200 codec->name = "twl4030";
2245 twl4030_init(socdev); 2201 codec->owner = THIS_MODULE;
2202 codec->read = twl4030_read_reg_cache;
2203 codec->write = twl4030_write;
2204 codec->set_bias_level = twl4030_set_bias_level;
2205 codec->dai = twl4030_dai;
2206 codec->num_dai = ARRAY_SIZE(twl4030_dai);
2207 codec->reg_cache_size = sizeof(twl4030_reg);
2208 codec->reg_cache = kmemdup(twl4030_reg, sizeof(twl4030_reg),
2209 GFP_KERNEL);
2210 if (codec->reg_cache == NULL) {
2211 ret = -ENOMEM;
2212 goto error_cache;
2213 }
2214
2215 platform_set_drvdata(pdev, twl4030);
2216 twl4030_codec = codec;
2217
2218 /* Set the defaults, and power up the codec */
2219 twl4030->sysclk = twl4030_codec_get_mclk() / 1000;
2220 twl4030_init_chip(codec);
2221 codec->bias_level = SND_SOC_BIAS_OFF;
2222 twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2223
2224 ret = snd_soc_register_codec(codec);
2225 if (ret != 0) {
2226 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
2227 goto error_codec;
2228 }
2229
2230 ret = snd_soc_register_dais(&twl4030_dai[0], ARRAY_SIZE(twl4030_dai));
2231 if (ret != 0) {
2232 dev_err(codec->dev, "Failed to register DAIs: %d\n", ret);
2233 snd_soc_unregister_codec(codec);
2234 goto error_codec;
2235 }
2246 2236
2247 return 0; 2237 return 0;
2238
2239error_codec:
2240 twl4030_power_down(codec);
2241 kfree(codec->reg_cache);
2242error_cache:
2243 kfree(twl4030);
2244 return ret;
2248} 2245}
2249 2246
2250static int twl4030_remove(struct platform_device *pdev) 2247static int __devexit twl4030_codec_remove(struct platform_device *pdev)
2251{ 2248{
2252 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 2249 struct twl4030_priv *twl4030 = platform_get_drvdata(pdev);
2253 struct snd_soc_codec *codec = socdev->card->codec;
2254 2250
2255 printk(KERN_INFO "TWL4030 Audio Codec remove\n"); 2251 snd_soc_unregister_dais(&twl4030_dai[0], ARRAY_SIZE(twl4030_dai));
2256 twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF); 2252 snd_soc_unregister_codec(&twl4030->codec);
2257 snd_soc_free_pcms(socdev); 2253 kfree(twl4030->codec.reg_cache);
2258 snd_soc_dapm_free(socdev); 2254 kfree(twl4030);
2259 kfree(codec->private_data);
2260 kfree(codec);
2261 2255
2256 twl4030_codec = NULL;
2262 return 0; 2257 return 0;
2263} 2258}
2264 2259
2265struct snd_soc_codec_device soc_codec_dev_twl4030 = { 2260MODULE_ALIAS("platform:twl4030_codec_audio");
2266 .probe = twl4030_probe, 2261
2267 .remove = twl4030_remove, 2262static struct platform_driver twl4030_codec_driver = {
2268 .suspend = twl4030_suspend, 2263 .probe = twl4030_codec_probe,
2269 .resume = twl4030_resume, 2264 .remove = __devexit_p(twl4030_codec_remove),
2265 .driver = {
2266 .name = "twl4030_codec_audio",
2267 .owner = THIS_MODULE,
2268 },
2270}; 2269};
2271EXPORT_SYMBOL_GPL(soc_codec_dev_twl4030);
2272 2270
2273static int __init twl4030_modinit(void) 2271static int __init twl4030_modinit(void)
2274{ 2272{
2275 return snd_soc_register_dais(&twl4030_dai[0], ARRAY_SIZE(twl4030_dai)); 2273 return platform_driver_register(&twl4030_codec_driver);
2276} 2274}
2277module_init(twl4030_modinit); 2275module_init(twl4030_modinit);
2278 2276
2279static void __exit twl4030_exit(void) 2277static void __exit twl4030_exit(void)
2280{ 2278{
2281 snd_soc_unregister_dais(&twl4030_dai[0], ARRAY_SIZE(twl4030_dai)); 2279 platform_driver_unregister(&twl4030_codec_driver);
2282} 2280}
2283module_exit(twl4030_exit); 2281module_exit(twl4030_exit);
2284 2282
2283struct snd_soc_codec_device soc_codec_dev_twl4030 = {
2284 .probe = twl4030_soc_probe,
2285 .remove = twl4030_soc_remove,
2286 .suspend = twl4030_soc_suspend,
2287 .resume = twl4030_soc_resume,
2288};
2289EXPORT_SYMBOL_GPL(soc_codec_dev_twl4030);
2290
2285MODULE_DESCRIPTION("ASoC TWL4030 codec driver"); 2291MODULE_DESCRIPTION("ASoC TWL4030 codec driver");
2286MODULE_AUTHOR("Steve Sakoman"); 2292MODULE_AUTHOR("Steve Sakoman");
2287MODULE_LICENSE("GPL"); 2293MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/twl4030.h b/sound/soc/codecs/twl4030.h
index 2b4bfa23f985..f206d242ca31 100644
--- a/sound/soc/codecs/twl4030.h
+++ b/sound/soc/codecs/twl4030.h
@@ -22,245 +22,13 @@
22#ifndef __TWL4030_AUDIO_H__ 22#ifndef __TWL4030_AUDIO_H__
23#define __TWL4030_AUDIO_H__ 23#define __TWL4030_AUDIO_H__
24 24
25#define TWL4030_REG_CODEC_MODE 0x1 25/* Register descriptions are here */
26#define TWL4030_REG_OPTION 0x2 26#include <linux/mfd/twl4030-codec.h>
27#define TWL4030_REG_UNKNOWN 0x3
28#define TWL4030_REG_MICBIAS_CTL 0x4
29#define TWL4030_REG_ANAMICL 0x5
30#define TWL4030_REG_ANAMICR 0x6
31#define TWL4030_REG_AVADC_CTL 0x7
32#define TWL4030_REG_ADCMICSEL 0x8
33#define TWL4030_REG_DIGMIXING 0x9
34#define TWL4030_REG_ATXL1PGA 0xA
35#define TWL4030_REG_ATXR1PGA 0xB
36#define TWL4030_REG_AVTXL2PGA 0xC
37#define TWL4030_REG_AVTXR2PGA 0xD
38#define TWL4030_REG_AUDIO_IF 0xE
39#define TWL4030_REG_VOICE_IF 0xF
40#define TWL4030_REG_ARXR1PGA 0x10
41#define TWL4030_REG_ARXL1PGA 0x11
42#define TWL4030_REG_ARXR2PGA 0x12
43#define TWL4030_REG_ARXL2PGA 0x13
44#define TWL4030_REG_VRXPGA 0x14
45#define TWL4030_REG_VSTPGA 0x15
46#define TWL4030_REG_VRX2ARXPGA 0x16
47#define TWL4030_REG_AVDAC_CTL 0x17
48#define TWL4030_REG_ARX2VTXPGA 0x18
49#define TWL4030_REG_ARXL1_APGA_CTL 0x19
50#define TWL4030_REG_ARXR1_APGA_CTL 0x1A
51#define TWL4030_REG_ARXL2_APGA_CTL 0x1B
52#define TWL4030_REG_ARXR2_APGA_CTL 0x1C
53#define TWL4030_REG_ATX2ARXPGA 0x1D
54#define TWL4030_REG_BT_IF 0x1E
55#define TWL4030_REG_BTPGA 0x1F
56#define TWL4030_REG_BTSTPGA 0x20
57#define TWL4030_REG_EAR_CTL 0x21
58#define TWL4030_REG_HS_SEL 0x22
59#define TWL4030_REG_HS_GAIN_SET 0x23
60#define TWL4030_REG_HS_POPN_SET 0x24
61#define TWL4030_REG_PREDL_CTL 0x25
62#define TWL4030_REG_PREDR_CTL 0x26
63#define TWL4030_REG_PRECKL_CTL 0x27
64#define TWL4030_REG_PRECKR_CTL 0x28
65#define TWL4030_REG_HFL_CTL 0x29
66#define TWL4030_REG_HFR_CTL 0x2A
67#define TWL4030_REG_ALC_CTL 0x2B
68#define TWL4030_REG_ALC_SET1 0x2C
69#define TWL4030_REG_ALC_SET2 0x2D
70#define TWL4030_REG_BOOST_CTL 0x2E
71#define TWL4030_REG_SOFTVOL_CTL 0x2F
72#define TWL4030_REG_DTMF_FREQSEL 0x30
73#define TWL4030_REG_DTMF_TONEXT1H 0x31
74#define TWL4030_REG_DTMF_TONEXT1L 0x32
75#define TWL4030_REG_DTMF_TONEXT2H 0x33
76#define TWL4030_REG_DTMF_TONEXT2L 0x34
77#define TWL4030_REG_DTMF_TONOFF 0x35
78#define TWL4030_REG_DTMF_WANONOFF 0x36
79#define TWL4030_REG_I2S_RX_SCRAMBLE_H 0x37
80#define TWL4030_REG_I2S_RX_SCRAMBLE_M 0x38
81#define TWL4030_REG_I2S_RX_SCRAMBLE_L 0x39
82#define TWL4030_REG_APLL_CTL 0x3A
83#define TWL4030_REG_DTMF_CTL 0x3B
84#define TWL4030_REG_DTMF_PGA_CTL2 0x3C
85#define TWL4030_REG_DTMF_PGA_CTL1 0x3D
86#define TWL4030_REG_MISC_SET_1 0x3E
87#define TWL4030_REG_PCMBTMUX 0x3F
88#define TWL4030_REG_RX_PATH_SEL 0x43
89#define TWL4030_REG_VDL_APGA_CTL 0x44
90#define TWL4030_REG_VIBRA_CTL 0x45
91#define TWL4030_REG_VIBRA_SET 0x46
92#define TWL4030_REG_VIBRA_PWM_SET 0x47
93#define TWL4030_REG_ANAMIC_GAIN 0x48
94#define TWL4030_REG_MISC_SET_2 0x49
95#define TWL4030_REG_SW_SHADOW 0x4A
96 27
28/* Shadow register used by the audio driver */
29#define TWL4030_REG_SW_SHADOW 0x4A
97#define TWL4030_CACHEREGNUM (TWL4030_REG_SW_SHADOW + 1) 30#define TWL4030_CACHEREGNUM (TWL4030_REG_SW_SHADOW + 1)
98 31
99/* Bitfield Definitions */
100
101/* TWL4030_CODEC_MODE (0x01) Fields */
102
103#define TWL4030_APLL_RATE 0xF0
104#define TWL4030_APLL_RATE_8000 0x00
105#define TWL4030_APLL_RATE_11025 0x10
106#define TWL4030_APLL_RATE_12000 0x20
107#define TWL4030_APLL_RATE_16000 0x40
108#define TWL4030_APLL_RATE_22050 0x50
109#define TWL4030_APLL_RATE_24000 0x60
110#define TWL4030_APLL_RATE_32000 0x80
111#define TWL4030_APLL_RATE_44100 0x90
112#define TWL4030_APLL_RATE_48000 0xA0
113#define TWL4030_APLL_RATE_96000 0xE0
114#define TWL4030_SEL_16K 0x08
115#define TWL4030_CODECPDZ 0x02
116#define TWL4030_OPT_MODE 0x01
117#define TWL4030_OPTION_1 (1 << 0)
118#define TWL4030_OPTION_2 (0 << 0)
119
120/* TWL4030_OPTION (0x02) Fields */
121
122#define TWL4030_ATXL1_EN (1 << 0)
123#define TWL4030_ATXR1_EN (1 << 1)
124#define TWL4030_ATXL2_VTXL_EN (1 << 2)
125#define TWL4030_ATXR2_VTXR_EN (1 << 3)
126#define TWL4030_ARXL1_VRX_EN (1 << 4)
127#define TWL4030_ARXR1_EN (1 << 5)
128#define TWL4030_ARXL2_EN (1 << 6)
129#define TWL4030_ARXR2_EN (1 << 7)
130
131/* TWL4030_REG_MICBIAS_CTL (0x04) Fields */
132
133#define TWL4030_MICBIAS2_CTL 0x40
134#define TWL4030_MICBIAS1_CTL 0x20
135#define TWL4030_HSMICBIAS_EN 0x04
136#define TWL4030_MICBIAS2_EN 0x02
137#define TWL4030_MICBIAS1_EN 0x01
138
139/* ANAMICL (0x05) Fields */
140
141#define TWL4030_CNCL_OFFSET_START 0x80
142#define TWL4030_OFFSET_CNCL_SEL 0x60
143#define TWL4030_OFFSET_CNCL_SEL_ARX1 0x00
144#define TWL4030_OFFSET_CNCL_SEL_ARX2 0x20
145#define TWL4030_OFFSET_CNCL_SEL_VRX 0x40
146#define TWL4030_OFFSET_CNCL_SEL_ALL 0x60
147#define TWL4030_MICAMPL_EN 0x10
148#define TWL4030_CKMIC_EN 0x08
149#define TWL4030_AUXL_EN 0x04
150#define TWL4030_HSMIC_EN 0x02
151#define TWL4030_MAINMIC_EN 0x01
152
153/* ANAMICR (0x06) Fields */
154
155#define TWL4030_MICAMPR_EN 0x10
156#define TWL4030_AUXR_EN 0x04
157#define TWL4030_SUBMIC_EN 0x01
158
159/* AVADC_CTL (0x07) Fields */
160
161#define TWL4030_ADCL_EN 0x08
162#define TWL4030_AVADC_CLK_PRIORITY 0x04
163#define TWL4030_ADCR_EN 0x02
164
165/* TWL4030_REG_ADCMICSEL (0x08) Fields */
166
167#define TWL4030_DIGMIC1_EN 0x08
168#define TWL4030_TX2IN_SEL 0x04
169#define TWL4030_DIGMIC0_EN 0x02
170#define TWL4030_TX1IN_SEL 0x01
171
172/* AUDIO_IF (0x0E) Fields */
173
174#define TWL4030_AIF_SLAVE_EN 0x80
175#define TWL4030_DATA_WIDTH 0x60
176#define TWL4030_DATA_WIDTH_16S_16W 0x00
177#define TWL4030_DATA_WIDTH_32S_16W 0x40
178#define TWL4030_DATA_WIDTH_32S_24W 0x60
179#define TWL4030_AIF_FORMAT 0x18
180#define TWL4030_AIF_FORMAT_CODEC 0x00
181#define TWL4030_AIF_FORMAT_LEFT 0x08
182#define TWL4030_AIF_FORMAT_RIGHT 0x10
183#define TWL4030_AIF_FORMAT_TDM 0x18
184#define TWL4030_AIF_TRI_EN 0x04
185#define TWL4030_CLK256FS_EN 0x02
186#define TWL4030_AIF_EN 0x01
187
188/* VOICE_IF (0x0F) Fields */
189
190#define TWL4030_VIF_SLAVE_EN 0x80
191#define TWL4030_VIF_DIN_EN 0x40
192#define TWL4030_VIF_DOUT_EN 0x20
193#define TWL4030_VIF_SWAP 0x10
194#define TWL4030_VIF_FORMAT 0x08
195#define TWL4030_VIF_TRI_EN 0x04
196#define TWL4030_VIF_SUB_EN 0x02
197#define TWL4030_VIF_EN 0x01
198
199/* EAR_CTL (0x21) */
200#define TWL4030_EAR_GAIN 0x30
201
202/* HS_GAIN_SET (0x23) Fields */
203
204#define TWL4030_HSR_GAIN 0x0C
205#define TWL4030_HSR_GAIN_PWR_DOWN 0x00
206#define TWL4030_HSR_GAIN_PLUS_6DB 0x04
207#define TWL4030_HSR_GAIN_0DB 0x08
208#define TWL4030_HSR_GAIN_MINUS_6DB 0x0C
209#define TWL4030_HSL_GAIN 0x03
210#define TWL4030_HSL_GAIN_PWR_DOWN 0x00
211#define TWL4030_HSL_GAIN_PLUS_6DB 0x01
212#define TWL4030_HSL_GAIN_0DB 0x02
213#define TWL4030_HSL_GAIN_MINUS_6DB 0x03
214
215/* HS_POPN_SET (0x24) Fields */
216
217#define TWL4030_VMID_EN 0x40
218#define TWL4030_EXTMUTE 0x20
219#define TWL4030_RAMP_DELAY 0x1C
220#define TWL4030_RAMP_DELAY_20MS 0x00
221#define TWL4030_RAMP_DELAY_40MS 0x04
222#define TWL4030_RAMP_DELAY_81MS 0x08
223#define TWL4030_RAMP_DELAY_161MS 0x0C
224#define TWL4030_RAMP_DELAY_323MS 0x10
225#define TWL4030_RAMP_DELAY_645MS 0x14
226#define TWL4030_RAMP_DELAY_1291MS 0x18
227#define TWL4030_RAMP_DELAY_2581MS 0x1C
228#define TWL4030_RAMP_EN 0x02
229
230/* PREDL_CTL (0x25) */
231#define TWL4030_PREDL_GAIN 0x30
232
233/* PREDR_CTL (0x26) */
234#define TWL4030_PREDR_GAIN 0x30
235
236/* PRECKL_CTL (0x27) */
237#define TWL4030_PRECKL_GAIN 0x30
238
239/* PRECKR_CTL (0x28) */
240#define TWL4030_PRECKR_GAIN 0x30
241
242/* HFL_CTL (0x29, 0x2A) Fields */
243#define TWL4030_HF_CTL_HB_EN 0x04
244#define TWL4030_HF_CTL_LOOP_EN 0x08
245#define TWL4030_HF_CTL_RAMP_EN 0x10
246#define TWL4030_HF_CTL_REF_EN 0x20
247
248/* APLL_CTL (0x3A) Fields */
249
250#define TWL4030_APLL_EN 0x10
251#define TWL4030_APLL_INFREQ 0x0F
252#define TWL4030_APLL_INFREQ_19200KHZ 0x05
253#define TWL4030_APLL_INFREQ_26000KHZ 0x06
254#define TWL4030_APLL_INFREQ_38400KHZ 0x0F
255
256/* REG_MISC_SET_1 (0x3E) Fields */
257
258#define TWL4030_CLK64_EN 0x80
259#define TWL4030_SCRAMBLE_EN 0x40
260#define TWL4030_FMLOOP_EN 0x20
261#define TWL4030_SMOOTH_ANAVOL_EN 0x02
262#define TWL4030_DIGMIC_LR_SWAP_EN 0x01
263
264/* TWL4030_REG_SW_SHADOW (0x4A) Fields */ 32/* TWL4030_REG_SW_SHADOW (0x4A) Fields */
265#define TWL4030_HFL_EN 0x01 33#define TWL4030_HFL_EN 0x01
266#define TWL4030_HFR_EN 0x02 34#define TWL4030_HFR_EN 0x02
@@ -279,3 +47,5 @@ struct twl4030_setup_data {
279}; 47};
280 48
281#endif /* End of __TWL4030_AUDIO_H__ */ 49#endif /* End of __TWL4030_AUDIO_H__ */
50
51
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c
index c33b92edbded..a8dcd5a5bbcb 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>
@@ -101,7 +102,7 @@ static int uda134x_write(struct snd_soc_codec *codec, unsigned int reg,
101 pr_debug("%s reg: %02X, value:%02X\n", __func__, reg, value); 102 pr_debug("%s reg: %02X, value:%02X\n", __func__, reg, value);
102 103
103 if (reg >= UDA134X_REGS_NUM) { 104 if (reg >= UDA134X_REGS_NUM) {
104 printk(KERN_ERR "%s unkown register: reg: %u", 105 printk(KERN_ERR "%s unknown register: reg: %u",
105 __func__, reg); 106 __func__, reg);
106 return -EINVAL; 107 return -EINVAL;
107 } 108 }
@@ -552,7 +553,7 @@ static int uda134x_soc_probe(struct platform_device *pdev)
552 ARRAY_SIZE(uda1341_snd_controls)); 553 ARRAY_SIZE(uda1341_snd_controls));
553 break; 554 break;
554 default: 555 default:
555 printk(KERN_ERR "%s unkown codec type: %d", 556 printk(KERN_ERR "%s unknown codec type: %d",
556 __func__, pd->model); 557 __func__, pd->model);
557 return -EINVAL; 558 return -EINVAL;
558 } 559 }
@@ -562,17 +563,8 @@ static int uda134x_soc_probe(struct platform_device *pdev)
562 goto pcm_err; 563 goto pcm_err;
563 } 564 }
564 565
565 ret = snd_soc_init_card(socdev);
566 if (ret < 0) {
567 printk(KERN_ERR "UDA134X: failed to register card\n");
568 goto card_err;
569 }
570
571 return 0; 566 return 0;
572 567
573card_err:
574 snd_soc_free_pcms(socdev);
575 snd_soc_dapm_free(socdev);
576pcm_err: 568pcm_err:
577 kfree(codec->reg_cache); 569 kfree(codec->reg_cache);
578reg_err: 570reg_err:
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c
index 92ec03442154..9cd0a66b7663 100644
--- a/sound/soc/codecs/uda1380.c
+++ b/sound/soc/codecs/uda1380.c
@@ -137,7 +137,7 @@ static void uda1380_flush_work(struct work_struct *work)
137{ 137{
138 int bit, reg; 138 int bit, reg;
139 139
140 for_each_bit(bit, &uda1380_cache_dirty, UDA1380_CACHEREGNUM - 0x10) { 140 for_each_set_bit(bit, &uda1380_cache_dirty, UDA1380_CACHEREGNUM - 0x10) {
141 reg = 0x10 + bit; 141 reg = 0x10 + bit;
142 pr_debug("uda1380: flush reg %x val %x:\n", reg, 142 pr_debug("uda1380: flush reg %x val %x:\n", reg,
143 uda1380_read_reg_cache(uda1380_codec, reg)); 143 uda1380_read_reg_cache(uda1380_codec, reg));
@@ -378,7 +378,6 @@ static int uda1380_add_widgets(struct snd_soc_codec *codec)
378 378
379 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 379 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
380 380
381 snd_soc_dapm_new_widgets(codec);
382 return 0; 381 return 0;
383} 382}
384 383
@@ -713,17 +712,9 @@ static int uda1380_probe(struct platform_device *pdev)
713 snd_soc_add_controls(codec, uda1380_snd_controls, 712 snd_soc_add_controls(codec, uda1380_snd_controls,
714 ARRAY_SIZE(uda1380_snd_controls)); 713 ARRAY_SIZE(uda1380_snd_controls));
715 uda1380_add_widgets(codec); 714 uda1380_add_widgets(codec);
716 ret = snd_soc_init_card(socdev);
717 if (ret < 0) {
718 dev_err(codec->dev, "failed to register card: %d\n", ret);
719 goto card_err;
720 }
721 715
722 return ret; 716 return ret;
723 717
724card_err:
725 snd_soc_free_pcms(socdev);
726 snd_soc_dapm_free(socdev);
727pcm_err: 718pcm_err:
728 return ret; 719 return ret;
729} 720}
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c
new file mode 100644
index 000000000000..002e289d1255
--- /dev/null
+++ b/sound/soc/codecs/wm2000.c
@@ -0,0 +1,888 @@
1/*
2 * wm2000.c -- WM2000 ALSA Soc Audio driver
3 *
4 * Copyright 2008-2010 Wolfson Microelectronics PLC.
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * The download image for the WM2000 will be requested as
13 * 'wm2000_anc.bin' by default (overridable via platform data) at
14 * runtime and is expected to be in flat binary format. This is
15 * generated by Wolfson configuration tools and includes
16 * system-specific callibration information. If supplied as a
17 * sequence of ASCII-encoded hexidecimal bytes this can be converted
18 * into a flat binary with a command such as this on the command line:
19 *
20 * perl -e 'while (<>) { s/[\r\n]+// ; printf("%c", hex($_)); }'
21 * < file > wm2000_anc.bin
22 */
23
24#include <linux/module.h>
25#include <linux/moduleparam.h>
26#include <linux/kernel.h>
27#include <linux/init.h>
28#include <linux/firmware.h>
29#include <linux/delay.h>
30#include <linux/pm.h>
31#include <linux/i2c.h>
32#include <linux/platform_device.h>
33#include <linux/debugfs.h>
34#include <linux/slab.h>
35#include <sound/core.h>
36#include <sound/pcm.h>
37#include <sound/pcm_params.h>
38#include <sound/soc.h>
39#include <sound/soc-dapm.h>
40#include <sound/initval.h>
41#include <sound/tlv.h>
42
43#include <sound/wm2000.h>
44
45#include "wm2000.h"
46
47enum wm2000_anc_mode {
48 ANC_ACTIVE = 0,
49 ANC_BYPASS = 1,
50 ANC_STANDBY = 2,
51 ANC_OFF = 3,
52};
53
54struct wm2000_priv {
55 struct i2c_client *i2c;
56
57 enum wm2000_anc_mode anc_mode;
58
59 unsigned int anc_active:1;
60 unsigned int anc_eng_ena:1;
61 unsigned int spk_ena:1;
62
63 unsigned int mclk_div:1;
64 unsigned int speech_clarity:1;
65
66 int anc_download_size;
67 char *anc_download;
68};
69
70static struct i2c_client *wm2000_i2c;
71
72static int wm2000_write(struct i2c_client *i2c, unsigned int reg,
73 unsigned int value)
74{
75 u8 data[3];
76 int ret;
77
78 data[0] = (reg >> 8) & 0xff;
79 data[1] = reg & 0xff;
80 data[2] = value & 0xff;
81
82 dev_vdbg(&i2c->dev, "write %x = %x\n", reg, value);
83
84 ret = i2c_master_send(i2c, data, 3);
85 if (ret == 3)
86 return 0;
87 if (ret < 0)
88 return ret;
89 else
90 return -EIO;
91}
92
93static unsigned int wm2000_read(struct i2c_client *i2c, unsigned int r)
94{
95 struct i2c_msg xfer[2];
96 u8 reg[2];
97 u8 data;
98 int ret;
99
100 /* Write register */
101 reg[0] = (r >> 8) & 0xff;
102 reg[1] = r & 0xff;
103 xfer[0].addr = i2c->addr;
104 xfer[0].flags = 0;
105 xfer[0].len = sizeof(reg);
106 xfer[0].buf = &reg[0];
107
108 /* Read data */
109 xfer[1].addr = i2c->addr;
110 xfer[1].flags = I2C_M_RD;
111 xfer[1].len = 1;
112 xfer[1].buf = &data;
113
114 ret = i2c_transfer(i2c->adapter, xfer, 2);
115 if (ret != 2) {
116 dev_err(&i2c->dev, "i2c_transfer() returned %d\n", ret);
117 return 0;
118 }
119
120 dev_vdbg(&i2c->dev, "read %x from %x\n", data, r);
121
122 return data;
123}
124
125static void wm2000_reset(struct wm2000_priv *wm2000)
126{
127 struct i2c_client *i2c = wm2000->i2c;
128
129 wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_ANC_ENG_CLR);
130 wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_RAM_CLR);
131 wm2000_write(i2c, WM2000_REG_ID1, 0);
132
133 wm2000->anc_mode = ANC_OFF;
134}
135
136static int wm2000_poll_bit(struct i2c_client *i2c,
137 unsigned int reg, u8 mask, int timeout)
138{
139 int val;
140
141 val = wm2000_read(i2c, reg);
142
143 while (!(val & mask) && --timeout) {
144 msleep(1);
145 val = wm2000_read(i2c, reg);
146 }
147
148 if (timeout == 0)
149 return 0;
150 else
151 return 1;
152}
153
154static int wm2000_power_up(struct i2c_client *i2c, int analogue)
155{
156 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
157 int ret, timeout;
158
159 BUG_ON(wm2000->anc_mode != ANC_OFF);
160
161 dev_dbg(&i2c->dev, "Beginning power up\n");
162
163 if (!wm2000->mclk_div) {
164 dev_dbg(&i2c->dev, "Disabling MCLK divider\n");
165 wm2000_write(i2c, WM2000_REG_SYS_CTL2,
166 WM2000_MCLK_DIV2_ENA_CLR);
167 } else {
168 dev_dbg(&i2c->dev, "Enabling MCLK divider\n");
169 wm2000_write(i2c, WM2000_REG_SYS_CTL2,
170 WM2000_MCLK_DIV2_ENA_SET);
171 }
172
173 wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_ANC_ENG_CLR);
174 wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_ANC_ENG_SET);
175
176 /* Wait for ANC engine to become ready */
177 if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT,
178 WM2000_ANC_ENG_IDLE, 1)) {
179 dev_err(&i2c->dev, "ANC engine failed to reset\n");
180 return -ETIMEDOUT;
181 }
182
183 if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
184 WM2000_STATUS_BOOT_COMPLETE, 1)) {
185 dev_err(&i2c->dev, "ANC engine failed to initialise\n");
186 return -ETIMEDOUT;
187 }
188
189 wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_RAM_SET);
190
191 /* Open code download of the data since it is the only bulk
192 * write we do. */
193 dev_dbg(&i2c->dev, "Downloading %d bytes\n",
194 wm2000->anc_download_size - 2);
195
196 ret = i2c_master_send(i2c, wm2000->anc_download,
197 wm2000->anc_download_size);
198 if (ret < 0) {
199 dev_err(&i2c->dev, "i2c_transfer() failed: %d\n", ret);
200 return ret;
201 }
202 if (ret != wm2000->anc_download_size) {
203 dev_err(&i2c->dev, "i2c_transfer() failed, %d != %d\n",
204 ret, wm2000->anc_download_size);
205 return -EIO;
206 }
207
208 dev_dbg(&i2c->dev, "Download complete\n");
209
210 if (analogue) {
211 timeout = 248;
212 wm2000_write(i2c, WM2000_REG_ANA_VMID_PU_TIME, timeout / 4);
213
214 wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
215 WM2000_MODE_ANA_SEQ_INCLUDE |
216 WM2000_MODE_MOUSE_ENABLE |
217 WM2000_MODE_THERMAL_ENABLE);
218 } else {
219 timeout = 10;
220
221 wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
222 WM2000_MODE_MOUSE_ENABLE |
223 WM2000_MODE_THERMAL_ENABLE);
224 }
225
226 ret = wm2000_read(i2c, WM2000_REG_SPEECH_CLARITY);
227 if (wm2000->speech_clarity)
228 ret &= ~WM2000_SPEECH_CLARITY;
229 else
230 ret |= WM2000_SPEECH_CLARITY;
231 wm2000_write(i2c, WM2000_REG_SPEECH_CLARITY, ret);
232
233 wm2000_write(i2c, WM2000_REG_SYS_START0, 0x33);
234 wm2000_write(i2c, WM2000_REG_SYS_START1, 0x02);
235
236 wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_ANC_INT_N_CLR);
237
238 if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
239 WM2000_STATUS_MOUSE_ACTIVE, timeout)) {
240 dev_err(&i2c->dev, "Timed out waiting for device after %dms\n",
241 timeout * 10);
242 return -ETIMEDOUT;
243 }
244
245 dev_dbg(&i2c->dev, "ANC active\n");
246 if (analogue)
247 dev_dbg(&i2c->dev, "Analogue active\n");
248 wm2000->anc_mode = ANC_ACTIVE;
249
250 return 0;
251}
252
253static int wm2000_power_down(struct i2c_client *i2c, int analogue)
254{
255 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
256 int timeout;
257
258 if (analogue) {
259 timeout = 248;
260 wm2000_write(i2c, WM2000_REG_ANA_VMID_PD_TIME, timeout / 4);
261 wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
262 WM2000_MODE_ANA_SEQ_INCLUDE |
263 WM2000_MODE_POWER_DOWN);
264 } else {
265 timeout = 10;
266 wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
267 WM2000_MODE_POWER_DOWN);
268 }
269
270 if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
271 WM2000_STATUS_POWER_DOWN_COMPLETE, timeout)) {
272 dev_err(&i2c->dev, "Timeout waiting for ANC power down\n");
273 return -ETIMEDOUT;
274 }
275
276 if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT,
277 WM2000_ANC_ENG_IDLE, 1)) {
278 dev_err(&i2c->dev, "Timeout waiting for ANC engine idle\n");
279 return -ETIMEDOUT;
280 }
281
282 dev_dbg(&i2c->dev, "powered off\n");
283 wm2000->anc_mode = ANC_OFF;
284
285 return 0;
286}
287
288static int wm2000_enter_bypass(struct i2c_client *i2c, int analogue)
289{
290 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
291
292 BUG_ON(wm2000->anc_mode != ANC_ACTIVE);
293
294 if (analogue) {
295 wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
296 WM2000_MODE_ANA_SEQ_INCLUDE |
297 WM2000_MODE_THERMAL_ENABLE |
298 WM2000_MODE_BYPASS_ENTRY);
299 } else {
300 wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
301 WM2000_MODE_THERMAL_ENABLE |
302 WM2000_MODE_BYPASS_ENTRY);
303 }
304
305 if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
306 WM2000_STATUS_ANC_DISABLED, 10)) {
307 dev_err(&i2c->dev, "Timeout waiting for ANC disable\n");
308 return -ETIMEDOUT;
309 }
310
311 if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT,
312 WM2000_ANC_ENG_IDLE, 1)) {
313 dev_err(&i2c->dev, "Timeout waiting for ANC engine idle\n");
314 return -ETIMEDOUT;
315 }
316
317 wm2000_write(i2c, WM2000_REG_SYS_CTL1, WM2000_SYS_STBY);
318 wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_RAM_CLR);
319
320 wm2000->anc_mode = ANC_BYPASS;
321 dev_dbg(&i2c->dev, "bypass enabled\n");
322
323 return 0;
324}
325
326static int wm2000_exit_bypass(struct i2c_client *i2c, int analogue)
327{
328 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
329
330 BUG_ON(wm2000->anc_mode != ANC_BYPASS);
331
332 wm2000_write(i2c, WM2000_REG_SYS_CTL1, 0);
333
334 if (analogue) {
335 wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
336 WM2000_MODE_ANA_SEQ_INCLUDE |
337 WM2000_MODE_MOUSE_ENABLE |
338 WM2000_MODE_THERMAL_ENABLE);
339 } else {
340 wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
341 WM2000_MODE_MOUSE_ENABLE |
342 WM2000_MODE_THERMAL_ENABLE);
343 }
344
345 wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_RAM_SET);
346 wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_ANC_INT_N_CLR);
347
348 if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
349 WM2000_STATUS_MOUSE_ACTIVE, 10)) {
350 dev_err(&i2c->dev, "Timed out waiting for MOUSE\n");
351 return -ETIMEDOUT;
352 }
353
354 wm2000->anc_mode = ANC_ACTIVE;
355 dev_dbg(&i2c->dev, "MOUSE active\n");
356
357 return 0;
358}
359
360static int wm2000_enter_standby(struct i2c_client *i2c, int analogue)
361{
362 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
363 int timeout;
364
365 BUG_ON(wm2000->anc_mode != ANC_ACTIVE);
366
367 if (analogue) {
368 timeout = 248;
369 wm2000_write(i2c, WM2000_REG_ANA_VMID_PD_TIME, timeout / 4);
370
371 wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
372 WM2000_MODE_ANA_SEQ_INCLUDE |
373 WM2000_MODE_THERMAL_ENABLE |
374 WM2000_MODE_STANDBY_ENTRY);
375 } else {
376 timeout = 10;
377
378 wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
379 WM2000_MODE_THERMAL_ENABLE |
380 WM2000_MODE_STANDBY_ENTRY);
381 }
382
383 if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
384 WM2000_STATUS_ANC_DISABLED, timeout)) {
385 dev_err(&i2c->dev,
386 "Timed out waiting for ANC disable after 1ms\n");
387 return -ETIMEDOUT;
388 }
389
390 if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT, WM2000_ANC_ENG_IDLE,
391 1)) {
392 dev_err(&i2c->dev,
393 "Timed out waiting for standby after %dms\n",
394 timeout * 10);
395 return -ETIMEDOUT;
396 }
397
398 wm2000_write(i2c, WM2000_REG_SYS_CTL1, WM2000_SYS_STBY);
399 wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_RAM_CLR);
400
401 wm2000->anc_mode = ANC_STANDBY;
402 dev_dbg(&i2c->dev, "standby\n");
403 if (analogue)
404 dev_dbg(&i2c->dev, "Analogue disabled\n");
405
406 return 0;
407}
408
409static int wm2000_exit_standby(struct i2c_client *i2c, int analogue)
410{
411 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
412 int timeout;
413
414 BUG_ON(wm2000->anc_mode != ANC_STANDBY);
415
416 wm2000_write(i2c, WM2000_REG_SYS_CTL1, 0);
417
418 if (analogue) {
419 timeout = 248;
420 wm2000_write(i2c, WM2000_REG_ANA_VMID_PU_TIME, timeout / 4);
421
422 wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
423 WM2000_MODE_ANA_SEQ_INCLUDE |
424 WM2000_MODE_THERMAL_ENABLE |
425 WM2000_MODE_MOUSE_ENABLE);
426 } else {
427 timeout = 10;
428
429 wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
430 WM2000_MODE_THERMAL_ENABLE |
431 WM2000_MODE_MOUSE_ENABLE);
432 }
433
434 wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_RAM_SET);
435 wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_ANC_INT_N_CLR);
436
437 if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
438 WM2000_STATUS_MOUSE_ACTIVE, timeout)) {
439 dev_err(&i2c->dev, "Timed out waiting for MOUSE after %dms\n",
440 timeout * 10);
441 return -ETIMEDOUT;
442 }
443
444 wm2000->anc_mode = ANC_ACTIVE;
445 dev_dbg(&i2c->dev, "MOUSE active\n");
446 if (analogue)
447 dev_dbg(&i2c->dev, "Analogue enabled\n");
448
449 return 0;
450}
451
452typedef int (*wm2000_mode_fn)(struct i2c_client *i2c, int analogue);
453
454static struct {
455 enum wm2000_anc_mode source;
456 enum wm2000_anc_mode dest;
457 int analogue;
458 wm2000_mode_fn step[2];
459} anc_transitions[] = {
460 {
461 .source = ANC_OFF,
462 .dest = ANC_ACTIVE,
463 .analogue = 1,
464 .step = {
465 wm2000_power_up,
466 },
467 },
468 {
469 .source = ANC_OFF,
470 .dest = ANC_STANDBY,
471 .step = {
472 wm2000_power_up,
473 wm2000_enter_standby,
474 },
475 },
476 {
477 .source = ANC_OFF,
478 .dest = ANC_BYPASS,
479 .analogue = 1,
480 .step = {
481 wm2000_power_up,
482 wm2000_enter_bypass,
483 },
484 },
485 {
486 .source = ANC_ACTIVE,
487 .dest = ANC_BYPASS,
488 .analogue = 1,
489 .step = {
490 wm2000_enter_bypass,
491 },
492 },
493 {
494 .source = ANC_ACTIVE,
495 .dest = ANC_STANDBY,
496 .analogue = 1,
497 .step = {
498 wm2000_enter_standby,
499 },
500 },
501 {
502 .source = ANC_ACTIVE,
503 .dest = ANC_OFF,
504 .analogue = 1,
505 .step = {
506 wm2000_power_down,
507 },
508 },
509 {
510 .source = ANC_BYPASS,
511 .dest = ANC_ACTIVE,
512 .analogue = 1,
513 .step = {
514 wm2000_exit_bypass,
515 },
516 },
517 {
518 .source = ANC_BYPASS,
519 .dest = ANC_STANDBY,
520 .analogue = 1,
521 .step = {
522 wm2000_exit_bypass,
523 wm2000_enter_standby,
524 },
525 },
526 {
527 .source = ANC_BYPASS,
528 .dest = ANC_OFF,
529 .step = {
530 wm2000_exit_bypass,
531 wm2000_power_down,
532 },
533 },
534 {
535 .source = ANC_STANDBY,
536 .dest = ANC_ACTIVE,
537 .analogue = 1,
538 .step = {
539 wm2000_exit_standby,
540 },
541 },
542 {
543 .source = ANC_STANDBY,
544 .dest = ANC_BYPASS,
545 .analogue = 1,
546 .step = {
547 wm2000_exit_standby,
548 wm2000_enter_bypass,
549 },
550 },
551 {
552 .source = ANC_STANDBY,
553 .dest = ANC_OFF,
554 .step = {
555 wm2000_exit_standby,
556 wm2000_power_down,
557 },
558 },
559};
560
561static int wm2000_anc_transition(struct wm2000_priv *wm2000,
562 enum wm2000_anc_mode mode)
563{
564 struct i2c_client *i2c = wm2000->i2c;
565 int i, j;
566 int ret;
567
568 if (wm2000->anc_mode == mode)
569 return 0;
570
571 for (i = 0; i < ARRAY_SIZE(anc_transitions); i++)
572 if (anc_transitions[i].source == wm2000->anc_mode &&
573 anc_transitions[i].dest == mode)
574 break;
575 if (i == ARRAY_SIZE(anc_transitions)) {
576 dev_err(&i2c->dev, "No transition for %d->%d\n",
577 wm2000->anc_mode, mode);
578 return -EINVAL;
579 }
580
581 for (j = 0; j < ARRAY_SIZE(anc_transitions[j].step); j++) {
582 if (!anc_transitions[i].step[j])
583 break;
584 ret = anc_transitions[i].step[j](i2c,
585 anc_transitions[i].analogue);
586 if (ret != 0)
587 return ret;
588 }
589
590 return 0;
591}
592
593static int wm2000_anc_set_mode(struct wm2000_priv *wm2000)
594{
595 struct i2c_client *i2c = wm2000->i2c;
596 enum wm2000_anc_mode mode;
597
598 if (wm2000->anc_eng_ena && wm2000->spk_ena)
599 if (wm2000->anc_active)
600 mode = ANC_ACTIVE;
601 else
602 mode = ANC_BYPASS;
603 else
604 mode = ANC_STANDBY;
605
606 dev_dbg(&i2c->dev, "Set mode %d (enabled %d, mute %d, active %d)\n",
607 mode, wm2000->anc_eng_ena, !wm2000->spk_ena,
608 wm2000->anc_active);
609
610 return wm2000_anc_transition(wm2000, mode);
611}
612
613static int wm2000_anc_mode_get(struct snd_kcontrol *kcontrol,
614 struct snd_ctl_elem_value *ucontrol)
615{
616 struct wm2000_priv *wm2000 = dev_get_drvdata(&wm2000_i2c->dev);
617
618 ucontrol->value.enumerated.item[0] = wm2000->anc_active;
619
620 return 0;
621}
622
623static int wm2000_anc_mode_put(struct snd_kcontrol *kcontrol,
624 struct snd_ctl_elem_value *ucontrol)
625{
626 struct wm2000_priv *wm2000 = dev_get_drvdata(&wm2000_i2c->dev);
627 int anc_active = ucontrol->value.enumerated.item[0];
628
629 if (anc_active > 1)
630 return -EINVAL;
631
632 wm2000->anc_active = anc_active;
633
634 return wm2000_anc_set_mode(wm2000);
635}
636
637static int wm2000_speaker_get(struct snd_kcontrol *kcontrol,
638 struct snd_ctl_elem_value *ucontrol)
639{
640 struct wm2000_priv *wm2000 = dev_get_drvdata(&wm2000_i2c->dev);
641
642 ucontrol->value.enumerated.item[0] = wm2000->spk_ena;
643
644 return 0;
645}
646
647static int wm2000_speaker_put(struct snd_kcontrol *kcontrol,
648 struct snd_ctl_elem_value *ucontrol)
649{
650 struct wm2000_priv *wm2000 = dev_get_drvdata(&wm2000_i2c->dev);
651 int val = ucontrol->value.enumerated.item[0];
652
653 if (val > 1)
654 return -EINVAL;
655
656 wm2000->spk_ena = val;
657
658 return wm2000_anc_set_mode(wm2000);
659}
660
661static const struct snd_kcontrol_new wm2000_controls[] = {
662 SOC_SINGLE_BOOL_EXT("WM2000 ANC Switch", 0,
663 wm2000_anc_mode_get,
664 wm2000_anc_mode_put),
665 SOC_SINGLE_BOOL_EXT("WM2000 Switch", 0,
666 wm2000_speaker_get,
667 wm2000_speaker_put),
668};
669
670static int wm2000_anc_power_event(struct snd_soc_dapm_widget *w,
671 struct snd_kcontrol *kcontrol, int event)
672{
673 struct wm2000_priv *wm2000 = dev_get_drvdata(&wm2000_i2c->dev);
674
675 if (SND_SOC_DAPM_EVENT_ON(event))
676 wm2000->anc_eng_ena = 1;
677
678 if (SND_SOC_DAPM_EVENT_OFF(event))
679 wm2000->anc_eng_ena = 0;
680
681 return wm2000_anc_set_mode(wm2000);
682}
683
684static const struct snd_soc_dapm_widget wm2000_dapm_widgets[] = {
685/* Externally visible pins */
686SND_SOC_DAPM_OUTPUT("WM2000 SPKN"),
687SND_SOC_DAPM_OUTPUT("WM2000 SPKP"),
688
689SND_SOC_DAPM_INPUT("WM2000 LINN"),
690SND_SOC_DAPM_INPUT("WM2000 LINP"),
691
692SND_SOC_DAPM_PGA_E("ANC Engine", SND_SOC_NOPM, 0, 0, NULL, 0,
693 wm2000_anc_power_event,
694 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
695};
696
697/* Target, Path, Source */
698static const struct snd_soc_dapm_route audio_map[] = {
699 { "WM2000 SPKN", NULL, "ANC Engine" },
700 { "WM2000 SPKP", NULL, "ANC Engine" },
701 { "ANC Engine", NULL, "WM2000 LINN" },
702 { "ANC Engine", NULL, "WM2000 LINP" },
703};
704
705/* Called from the machine driver */
706int wm2000_add_controls(struct snd_soc_codec *codec)
707{
708 int ret;
709
710 if (!wm2000_i2c) {
711 pr_err("WM2000 not yet probed\n");
712 return -ENODEV;
713 }
714
715 ret = snd_soc_dapm_new_controls(codec, wm2000_dapm_widgets,
716 ARRAY_SIZE(wm2000_dapm_widgets));
717 if (ret < 0)
718 return ret;
719
720 ret = snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
721 if (ret < 0)
722 return ret;
723
724 return snd_soc_add_controls(codec, wm2000_controls,
725 ARRAY_SIZE(wm2000_controls));
726}
727EXPORT_SYMBOL_GPL(wm2000_add_controls);
728
729static int __devinit wm2000_i2c_probe(struct i2c_client *i2c,
730 const struct i2c_device_id *i2c_id)
731{
732 struct wm2000_priv *wm2000;
733 struct wm2000_platform_data *pdata;
734 const char *filename;
735 const struct firmware *fw;
736 int reg, ret;
737 u16 id;
738
739 if (wm2000_i2c) {
740 dev_err(&i2c->dev, "Another WM2000 is already registered\n");
741 return -EINVAL;
742 }
743
744 wm2000 = kzalloc(sizeof(struct wm2000_priv), GFP_KERNEL);
745 if (wm2000 == NULL) {
746 dev_err(&i2c->dev, "Unable to allocate private data\n");
747 return -ENOMEM;
748 }
749
750 /* Verify that this is a WM2000 */
751 reg = wm2000_read(i2c, WM2000_REG_ID1);
752 id = reg << 8;
753 reg = wm2000_read(i2c, WM2000_REG_ID2);
754 id |= reg & 0xff;
755
756 if (id != 0x2000) {
757 dev_err(&i2c->dev, "Device is not a WM2000 - ID %x\n", id);
758 ret = -ENODEV;
759 goto err;
760 }
761
762 reg = wm2000_read(i2c, WM2000_REG_REVISON);
763 dev_info(&i2c->dev, "revision %c\n", reg + 'A');
764
765 filename = "wm2000_anc.bin";
766 pdata = dev_get_platdata(&i2c->dev);
767 if (pdata) {
768 wm2000->mclk_div = pdata->mclkdiv2;
769 wm2000->speech_clarity = !pdata->speech_enh_disable;
770
771 if (pdata->download_file)
772 filename = pdata->download_file;
773 }
774
775 ret = request_firmware(&fw, filename, &i2c->dev);
776 if (ret != 0) {
777 dev_err(&i2c->dev, "Failed to acquire ANC data: %d\n", ret);
778 goto err;
779 }
780
781 /* Pre-cook the concatenation of the register address onto the image */
782 wm2000->anc_download_size = fw->size + 2;
783 wm2000->anc_download = kmalloc(wm2000->anc_download_size, GFP_KERNEL);
784 if (wm2000->anc_download == NULL) {
785 dev_err(&i2c->dev, "Out of memory\n");
786 ret = -ENOMEM;
787 goto err_fw;
788 }
789
790 wm2000->anc_download[0] = 0x80;
791 wm2000->anc_download[1] = 0x00;
792 memcpy(wm2000->anc_download + 2, fw->data, fw->size);
793
794 release_firmware(fw);
795
796 dev_set_drvdata(&i2c->dev, wm2000);
797 wm2000->anc_eng_ena = 1;
798 wm2000->i2c = i2c;
799
800 wm2000_reset(wm2000);
801
802 /* This will trigger a transition to standby mode by default */
803 wm2000_anc_set_mode(wm2000);
804
805 wm2000_i2c = i2c;
806
807 return 0;
808
809err_fw:
810 release_firmware(fw);
811err:
812 kfree(wm2000);
813 return ret;
814}
815
816static __devexit int wm2000_i2c_remove(struct i2c_client *i2c)
817{
818 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
819
820 wm2000_anc_transition(wm2000, ANC_OFF);
821
822 wm2000_i2c = NULL;
823 kfree(wm2000->anc_download);
824 kfree(wm2000);
825
826 return 0;
827}
828
829static void wm2000_i2c_shutdown(struct i2c_client *i2c)
830{
831 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
832
833 wm2000_anc_transition(wm2000, ANC_OFF);
834}
835
836#ifdef CONFIG_PM
837static int wm2000_i2c_suspend(struct i2c_client *i2c, pm_message_t mesg)
838{
839 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
840
841 return wm2000_anc_transition(wm2000, ANC_OFF);
842}
843
844static int wm2000_i2c_resume(struct i2c_client *i2c)
845{
846 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
847
848 return wm2000_anc_set_mode(wm2000);
849}
850#else
851#define wm2000_i2c_suspend NULL
852#define wm2000_i2c_resume NULL
853#endif
854
855static const struct i2c_device_id wm2000_i2c_id[] = {
856 { "wm2000", 0 },
857 { }
858};
859MODULE_DEVICE_TABLE(i2c, wm2000_i2c_id);
860
861static struct i2c_driver wm2000_i2c_driver = {
862 .driver = {
863 .name = "wm2000",
864 .owner = THIS_MODULE,
865 },
866 .probe = wm2000_i2c_probe,
867 .remove = __devexit_p(wm2000_i2c_remove),
868 .suspend = wm2000_i2c_suspend,
869 .resume = wm2000_i2c_resume,
870 .shutdown = wm2000_i2c_shutdown,
871 .id_table = wm2000_i2c_id,
872};
873
874static int __init wm2000_init(void)
875{
876 return i2c_add_driver(&wm2000_i2c_driver);
877}
878module_init(wm2000_init);
879
880static void __exit wm2000_exit(void)
881{
882 i2c_del_driver(&wm2000_i2c_driver);
883}
884module_exit(wm2000_exit);
885
886MODULE_DESCRIPTION("ASoC WM2000 driver");
887MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfonmicro.com>");
888MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm2000.h b/sound/soc/codecs/wm2000.h
new file mode 100644
index 000000000000..c18e261c3c7f
--- /dev/null
+++ b/sound/soc/codecs/wm2000.h
@@ -0,0 +1,79 @@
1/*
2 * wm2000.h -- WM2000 Soc Audio driver
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#ifndef _WM2000_H
10#define _WM2000_H
11
12struct wm2000_setup_data {
13 unsigned short i2c_address;
14 int mclk_div; /* Set to a non-zero value if MCLK_DIV_2 required */
15};
16
17extern int wm2000_add_controls(struct snd_soc_codec *codec);
18
19extern struct snd_soc_dai wm2000_dai;
20extern struct snd_soc_codec_device soc_codec_dev_wm2000;
21
22#define WM2000_REG_SYS_START 0x8000
23#define WM2000_REG_SPEECH_CLARITY 0x8fef
24#define WM2000_REG_SYS_WATCHDOG 0x8ff6
25#define WM2000_REG_ANA_VMID_PD_TIME 0x8ff7
26#define WM2000_REG_ANA_VMID_PU_TIME 0x8ff8
27#define WM2000_REG_CAT_FLTR_INDX 0x8ff9
28#define WM2000_REG_CAT_GAIN_0 0x8ffa
29#define WM2000_REG_SYS_STATUS 0x8ffc
30#define WM2000_REG_SYS_MODE_CNTRL 0x8ffd
31#define WM2000_REG_SYS_START0 0x8ffe
32#define WM2000_REG_SYS_START1 0x8fff
33#define WM2000_REG_ID1 0xf000
34#define WM2000_REG_ID2 0xf001
35#define WM2000_REG_REVISON 0xf002
36#define WM2000_REG_SYS_CTL1 0xf003
37#define WM2000_REG_SYS_CTL2 0xf004
38#define WM2000_REG_ANC_STAT 0xf005
39#define WM2000_REG_IF_CTL 0xf006
40
41/* SPEECH_CLARITY */
42#define WM2000_SPEECH_CLARITY 0x01
43
44/* SYS_STATUS */
45#define WM2000_STATUS_MOUSE_ACTIVE 0x40
46#define WM2000_STATUS_CAT_FREQ_COMPLETE 0x20
47#define WM2000_STATUS_CAT_GAIN_COMPLETE 0x10
48#define WM2000_STATUS_THERMAL_SHUTDOWN_COMPLETE 0x08
49#define WM2000_STATUS_ANC_DISABLED 0x04
50#define WM2000_STATUS_POWER_DOWN_COMPLETE 0x02
51#define WM2000_STATUS_BOOT_COMPLETE 0x01
52
53/* SYS_MODE_CNTRL */
54#define WM2000_MODE_ANA_SEQ_INCLUDE 0x80
55#define WM2000_MODE_MOUSE_ENABLE 0x40
56#define WM2000_MODE_CAT_FREQ_ENABLE 0x20
57#define WM2000_MODE_CAT_GAIN_ENABLE 0x10
58#define WM2000_MODE_BYPASS_ENTRY 0x08
59#define WM2000_MODE_STANDBY_ENTRY 0x04
60#define WM2000_MODE_THERMAL_ENABLE 0x02
61#define WM2000_MODE_POWER_DOWN 0x01
62
63/* SYS_CTL1 */
64#define WM2000_SYS_STBY 0x01
65
66/* SYS_CTL2 */
67#define WM2000_MCLK_DIV2_ENA_CLR 0x80
68#define WM2000_MCLK_DIV2_ENA_SET 0x40
69#define WM2000_ANC_ENG_CLR 0x20
70#define WM2000_ANC_ENG_SET 0x10
71#define WM2000_ANC_INT_N_CLR 0x08
72#define WM2000_ANC_INT_N_SET 0x04
73#define WM2000_RAM_CLR 0x02
74#define WM2000_RAM_SET 0x01
75
76/* ANC_STAT */
77#define WM2000_ANC_ENG_IDLE 0x01
78
79#endif
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
index 593d5b9c9f03..2e0772f9c456 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>
@@ -800,7 +801,7 @@ static int wm8350_add_widgets(struct snd_soc_codec *codec)
800 return ret; 801 return ret;
801 } 802 }
802 803
803 return snd_soc_dapm_new_widgets(codec); 804 return 0;
804} 805}
805 806
806static int wm8350_set_dai_sysclk(struct snd_soc_dai *codec_dai, 807static int wm8350_set_dai_sysclk(struct snd_soc_dai *codec_dai,
@@ -925,7 +926,7 @@ static int wm8350_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
925 iface |= 0x3 << 8; 926 iface |= 0x3 << 8;
926 break; 927 break;
927 case SND_SOC_DAIFMT_DSP_B: 928 case SND_SOC_DAIFMT_DSP_B:
928 iface |= 0x3 << 8; /* lg not sure which mode */ 929 iface |= 0x3 << 8 | WM8350_AIF_LRCLK_INV;
929 break; 930 break;
930 default: 931 default:
931 return -EINVAL; 932 return -EINVAL;
@@ -1101,7 +1102,7 @@ static inline int fll_factors(struct _fll_div *fll_div, unsigned int input,
1101} 1102}
1102 1103
1103static int wm8350_set_fll(struct snd_soc_dai *codec_dai, 1104static int wm8350_set_fll(struct snd_soc_dai *codec_dai,
1104 int pll_id, unsigned int freq_in, 1105 int pll_id, int source, unsigned int freq_in,
1105 unsigned int freq_out) 1106 unsigned int freq_out)
1106{ 1107{
1107 struct snd_soc_codec *codec = codec_dai->codec; 1108 struct snd_soc_codec *codec = codec_dai->codec;
@@ -1340,15 +1341,16 @@ static int wm8350_resume(struct platform_device *pdev)
1340 return 0; 1341 return 0;
1341} 1342}
1342 1343
1343static void wm8350_hp_jack_handler(struct wm8350 *wm8350, int irq, void *data) 1344static irqreturn_t wm8350_hp_jack_handler(int irq, void *data)
1344{ 1345{
1345 struct wm8350_data *priv = data; 1346 struct wm8350_data *priv = data;
1347 struct wm8350 *wm8350 = priv->codec.control_data;
1346 u16 reg; 1348 u16 reg;
1347 int report; 1349 int report;
1348 int mask; 1350 int mask;
1349 struct wm8350_jack_data *jack = NULL; 1351 struct wm8350_jack_data *jack = NULL;
1350 1352
1351 switch (irq) { 1353 switch (irq - wm8350->irq_base) {
1352 case WM8350_IRQ_CODEC_JCK_DET_L: 1354 case WM8350_IRQ_CODEC_JCK_DET_L:
1353 jack = &priv->hpl; 1355 jack = &priv->hpl;
1354 mask = WM8350_JACK_L_LVL; 1356 mask = WM8350_JACK_L_LVL;
@@ -1365,7 +1367,7 @@ static void wm8350_hp_jack_handler(struct wm8350 *wm8350, int irq, void *data)
1365 1367
1366 if (!jack->jack) { 1368 if (!jack->jack) {
1367 dev_warn(wm8350->dev, "Jack interrupt called with no jack\n"); 1369 dev_warn(wm8350->dev, "Jack interrupt called with no jack\n");
1368 return; 1370 return IRQ_NONE;
1369 } 1371 }
1370 1372
1371 /* Debounce */ 1373 /* Debounce */
@@ -1378,6 +1380,8 @@ static void wm8350_hp_jack_handler(struct wm8350 *wm8350, int irq, void *data)
1378 report = 0; 1380 report = 0;
1379 1381
1380 snd_soc_jack_report(jack->jack, report, jack->report); 1382 snd_soc_jack_report(jack->jack, report, jack->report);
1383
1384 return IRQ_HANDLED;
1381} 1385}
1382 1386
1383/** 1387/**
@@ -1421,9 +1425,7 @@ int wm8350_hp_jack_detect(struct snd_soc_codec *codec, enum wm8350_jack which,
1421 wm8350_set_bits(wm8350, WM8350_JACK_DETECT, ena); 1425 wm8350_set_bits(wm8350, WM8350_JACK_DETECT, ena);
1422 1426
1423 /* Sync status */ 1427 /* Sync status */
1424 wm8350_hp_jack_handler(wm8350, irq, priv); 1428 wm8350_hp_jack_handler(irq + wm8350->irq_base, priv);
1425
1426 wm8350_unmask_irq(wm8350, irq);
1427 1429
1428 return 0; 1430 return 0;
1429} 1431}
@@ -1482,12 +1484,16 @@ static int wm8350_probe(struct platform_device *pdev)
1482 wm8350_set_bits(wm8350, WM8350_ROUT2_VOLUME, 1484 wm8350_set_bits(wm8350, WM8350_ROUT2_VOLUME,
1483 WM8350_OUT2_VU | WM8350_OUT2R_MUTE); 1485 WM8350_OUT2_VU | WM8350_OUT2R_MUTE);
1484 1486
1485 wm8350_mask_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L); 1487 /* Make sure jack detect is disabled to start off with */
1486 wm8350_mask_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R); 1488 wm8350_clear_bits(wm8350, WM8350_JACK_DETECT,
1489 WM8350_JDL_ENA | WM8350_JDR_ENA);
1490
1487 wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L, 1491 wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L,
1488 wm8350_hp_jack_handler, priv); 1492 wm8350_hp_jack_handler, 0, "Left jack detect",
1493 priv);
1489 wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R, 1494 wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R,
1490 wm8350_hp_jack_handler, priv); 1495 wm8350_hp_jack_handler, 0, "Right jack detect",
1496 priv);
1491 1497
1492 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 1498 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1493 if (ret < 0) { 1499 if (ret < 0) {
@@ -1501,18 +1507,7 @@ static int wm8350_probe(struct platform_device *pdev)
1501 1507
1502 wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1508 wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1503 1509
1504 ret = snd_soc_init_card(socdev);
1505 if (ret < 0) {
1506 dev_err(&pdev->dev, "failed to register card\n");
1507 goto card_err;
1508 }
1509
1510 return 0; 1510 return 0;
1511
1512card_err:
1513 snd_soc_free_pcms(socdev);
1514 snd_soc_dapm_free(socdev);
1515 return ret;
1516} 1511}
1517 1512
1518static int wm8350_remove(struct platform_device *pdev) 1513static int wm8350_remove(struct platform_device *pdev)
@@ -1527,10 +1522,8 @@ static int wm8350_remove(struct platform_device *pdev)
1527 WM8350_JDL_ENA | WM8350_JDR_ENA); 1522 WM8350_JDL_ENA | WM8350_JDR_ENA);
1528 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_TOCLK_ENA); 1523 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_TOCLK_ENA);
1529 1524
1530 wm8350_mask_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L); 1525 wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L, priv);
1531 wm8350_mask_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R); 1526 wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R, priv);
1532 wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L);
1533 wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R);
1534 1527
1535 priv->hpl.jack = NULL; 1528 priv->hpl.jack = NULL;
1536 priv->hpr.jack = NULL; 1529 priv->hpr.jack = NULL;
@@ -1680,21 +1673,6 @@ static int __devexit wm8350_codec_remove(struct platform_device *pdev)
1680 return 0; 1673 return 0;
1681} 1674}
1682 1675
1683#ifdef CONFIG_PM
1684static int wm8350_codec_suspend(struct platform_device *pdev, pm_message_t m)
1685{
1686 return snd_soc_suspend_device(&pdev->dev);
1687}
1688
1689static int wm8350_codec_resume(struct platform_device *pdev)
1690{
1691 return snd_soc_resume_device(&pdev->dev);
1692}
1693#else
1694#define wm8350_codec_suspend NULL
1695#define wm8350_codec_resume NULL
1696#endif
1697
1698static struct platform_driver wm8350_codec_driver = { 1676static struct platform_driver wm8350_codec_driver = {
1699 .driver = { 1677 .driver = {
1700 .name = "wm8350-codec", 1678 .name = "wm8350-codec",
@@ -1702,8 +1680,6 @@ static struct platform_driver wm8350_codec_driver = {
1702 }, 1680 },
1703 .probe = wm8350_codec_probe, 1681 .probe = wm8350_codec_probe,
1704 .remove = __devexit_p(wm8350_codec_remove), 1682 .remove = __devexit_p(wm8350_codec_remove),
1705 .suspend = wm8350_codec_suspend,
1706 .resume = wm8350_codec_resume,
1707}; 1683};
1708 1684
1709static __init int wm8350_init(void) 1685static __init int wm8350_init(void)
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c
index b9ef4d915221..6acc885cf9b7 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>
@@ -915,7 +916,6 @@ static int wm8400_add_widgets(struct snd_soc_codec *codec)
915 916
916 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 917 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
917 918
918 snd_soc_dapm_new_widgets(codec);
919 return 0; 919 return 0;
920} 920}
921 921
@@ -1011,7 +1011,8 @@ static int fll_factors(struct wm8400_priv *wm8400, struct fll_factors *factors,
1011} 1011}
1012 1012
1013static int wm8400_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, 1013static int wm8400_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
1014 unsigned int freq_in, unsigned int freq_out) 1014 int source, unsigned int freq_in,
1015 unsigned int freq_out)
1015{ 1016{
1016 struct snd_soc_codec *codec = codec_dai->codec; 1017 struct snd_soc_codec *codec = codec_dai->codec;
1017 struct wm8400_priv *wm8400 = codec->private_data; 1018 struct wm8400_priv *wm8400 = codec->private_data;
@@ -1399,17 +1400,6 @@ static int wm8400_probe(struct platform_device *pdev)
1399 wm8400_add_controls(codec); 1400 wm8400_add_controls(codec);
1400 wm8400_add_widgets(codec); 1401 wm8400_add_widgets(codec);
1401 1402
1402 ret = snd_soc_init_card(socdev);
1403 if (ret < 0) {
1404 dev_err(&pdev->dev, "failed to register card\n");
1405 goto card_err;
1406 }
1407
1408 return ret;
1409
1410card_err:
1411 snd_soc_free_pcms(socdev);
1412 snd_soc_dapm_free(socdev);
1413pcm_err: 1403pcm_err:
1414 return ret; 1404 return ret;
1415} 1405}
@@ -1558,21 +1548,6 @@ static int __exit wm8400_codec_remove(struct platform_device *dev)
1558 return 0; 1548 return 0;
1559} 1549}
1560 1550
1561#ifdef CONFIG_PM
1562static int wm8400_pdev_suspend(struct platform_device *pdev, pm_message_t msg)
1563{
1564 return snd_soc_suspend_device(&pdev->dev);
1565}
1566
1567static int wm8400_pdev_resume(struct platform_device *pdev)
1568{
1569 return snd_soc_resume_device(&pdev->dev);
1570}
1571#else
1572#define wm8400_pdev_suspend NULL
1573#define wm8400_pdev_resume NULL
1574#endif
1575
1576static struct platform_driver wm8400_codec_driver = { 1551static struct platform_driver wm8400_codec_driver = {
1577 .driver = { 1552 .driver = {
1578 .name = "wm8400-codec", 1553 .name = "wm8400-codec",
@@ -1580,8 +1555,6 @@ static struct platform_driver wm8400_codec_driver = {
1580 }, 1555 },
1581 .probe = wm8400_codec_probe, 1556 .probe = wm8400_codec_probe,
1582 .remove = __exit_p(wm8400_codec_remove), 1557 .remove = __exit_p(wm8400_codec_remove),
1583 .suspend = wm8400_pdev_suspend,
1584 .resume = wm8400_pdev_resume,
1585}; 1558};
1586 1559
1587static int __init wm8400_codec_init(void) 1560static int __init wm8400_codec_init(void)
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c
index 060d5d06ba95..9000b1d19afb 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>
@@ -219,7 +220,6 @@ static int wm8510_add_widgets(struct snd_soc_codec *codec)
219 220
220 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 221 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
221 222
222 snd_soc_dapm_new_widgets(codec);
223 return 0; 223 return 0;
224} 224}
225 225
@@ -271,8 +271,8 @@ static void pll_factors(unsigned int target, unsigned int source)
271 pll_div.k = K; 271 pll_div.k = K;
272} 272}
273 273
274static int wm8510_set_dai_pll(struct snd_soc_dai *codec_dai, 274static int wm8510_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
275 int pll_id, unsigned int freq_in, unsigned int freq_out) 275 int source, unsigned int freq_in, unsigned int freq_out)
276{ 276{
277 struct snd_soc_codec *codec = codec_dai->codec; 277 struct snd_soc_codec *codec = codec_dai->codec;
278 u16 reg; 278 u16 reg;
@@ -425,23 +425,23 @@ static int wm8510_pcm_hw_params(struct snd_pcm_substream *substream,
425 425
426 /* filter coefficient */ 426 /* filter coefficient */
427 switch (params_rate(params)) { 427 switch (params_rate(params)) {
428 case SNDRV_PCM_RATE_8000: 428 case 8000:
429 adn |= 0x5 << 1; 429 adn |= 0x5 << 1;
430 break; 430 break;
431 case SNDRV_PCM_RATE_11025: 431 case 11025:
432 adn |= 0x4 << 1; 432 adn |= 0x4 << 1;
433 break; 433 break;
434 case SNDRV_PCM_RATE_16000: 434 case 16000:
435 adn |= 0x3 << 1; 435 adn |= 0x3 << 1;
436 break; 436 break;
437 case SNDRV_PCM_RATE_22050: 437 case 22050:
438 adn |= 0x2 << 1; 438 adn |= 0x2 << 1;
439 break; 439 break;
440 case SNDRV_PCM_RATE_32000: 440 case 32000:
441 adn |= 0x1 << 1; 441 adn |= 0x1 << 1;
442 break; 442 break;
443 case SNDRV_PCM_RATE_44100: 443 case 44100:
444 case SNDRV_PCM_RATE_48000: 444 case 48000:
445 break; 445 break;
446 } 446 }
447 447
@@ -604,16 +604,9 @@ static int wm8510_init(struct snd_soc_device *socdev,
604 snd_soc_add_controls(codec, wm8510_snd_controls, 604 snd_soc_add_controls(codec, wm8510_snd_controls,
605 ARRAY_SIZE(wm8510_snd_controls)); 605 ARRAY_SIZE(wm8510_snd_controls));
606 wm8510_add_widgets(codec); 606 wm8510_add_widgets(codec);
607 ret = snd_soc_init_card(socdev); 607
608 if (ret < 0) {
609 printk(KERN_ERR "wm8510: failed to register card\n");
610 goto card_err;
611 }
612 return ret; 608 return ret;
613 609
614card_err:
615 snd_soc_free_pcms(socdev);
616 snd_soc_dapm_free(socdev);
617err: 610err:
618 kfree(codec->reg_cache); 611 kfree(codec->reg_cache);
619 return ret; 612 return ret;
diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c
index 25870a4652fb..19cd47293424 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>
@@ -117,7 +118,6 @@ static int wm8523_add_widgets(struct snd_soc_codec *codec)
117 118
118 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); 119 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
119 120
120 snd_soc_dapm_new_widgets(codec);
121 return 0; 121 return 0;
122} 122}
123 123
@@ -448,17 +448,9 @@ static int wm8523_probe(struct platform_device *pdev)
448 snd_soc_add_controls(codec, wm8523_snd_controls, 448 snd_soc_add_controls(codec, wm8523_snd_controls,
449 ARRAY_SIZE(wm8523_snd_controls)); 449 ARRAY_SIZE(wm8523_snd_controls));
450 wm8523_add_widgets(codec); 450 wm8523_add_widgets(codec);
451 ret = snd_soc_init_card(socdev);
452 if (ret < 0) {
453 dev_err(codec->dev, "failed to register card: %d\n", ret);
454 goto card_err;
455 }
456 451
457 return ret; 452 return ret;
458 453
459card_err:
460 snd_soc_free_pcms(socdev);
461 snd_soc_dapm_free(socdev);
462pcm_err: 454pcm_err:
463 return ret; 455 return ret;
464} 456}
@@ -638,21 +630,6 @@ static __devexit int wm8523_i2c_remove(struct i2c_client *client)
638 return 0; 630 return 0;
639} 631}
640 632
641#ifdef CONFIG_PM
642static int wm8523_i2c_suspend(struct i2c_client *i2c, pm_message_t msg)
643{
644 return snd_soc_suspend_device(&i2c->dev);
645}
646
647static int wm8523_i2c_resume(struct i2c_client *i2c)
648{
649 return snd_soc_resume_device(&i2c->dev);
650}
651#else
652#define wm8523_i2c_suspend NULL
653#define wm8523_i2c_resume NULL
654#endif
655
656static const struct i2c_device_id wm8523_i2c_id[] = { 633static const struct i2c_device_id wm8523_i2c_id[] = {
657 { "wm8523", 0 }, 634 { "wm8523", 0 },
658 { } 635 { }
@@ -666,8 +643,6 @@ static struct i2c_driver wm8523_i2c_driver = {
666 }, 643 },
667 .probe = wm8523_i2c_probe, 644 .probe = wm8523_i2c_probe,
668 .remove = __devexit_p(wm8523_i2c_remove), 645 .remove = __devexit_p(wm8523_i2c_remove),
669 .suspend = wm8523_i2c_suspend,
670 .resume = wm8523_i2c_resume,
671 .id_table = wm8523_i2c_id, 646 .id_table = wm8523_i2c_id,
672}; 647};
673#endif 648#endif
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c
index 6bded8c78150..8cc9042965eb 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>
@@ -315,7 +316,6 @@ static int wm8580_add_widgets(struct snd_soc_codec *codec)
315 316
316 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 317 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
317 318
318 snd_soc_dapm_new_widgets(codec);
319 return 0; 319 return 0;
320} 320}
321 321
@@ -407,8 +407,8 @@ static int pll_factors(struct _pll_div *pll_div, unsigned int target,
407 return 0; 407 return 0;
408} 408}
409 409
410static int wm8580_set_dai_pll(struct snd_soc_dai *codec_dai, 410static int wm8580_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
411 int pll_id, unsigned int freq_in, unsigned int freq_out) 411 int source, unsigned int freq_in, unsigned int freq_out)
412{ 412{
413 int offset; 413 int offset;
414 struct snd_soc_codec *codec = codec_dai->codec; 414 struct snd_soc_codec *codec = codec_dai->codec;
@@ -800,17 +800,9 @@ static int wm8580_probe(struct platform_device *pdev)
800 snd_soc_add_controls(codec, wm8580_snd_controls, 800 snd_soc_add_controls(codec, wm8580_snd_controls,
801 ARRAY_SIZE(wm8580_snd_controls)); 801 ARRAY_SIZE(wm8580_snd_controls));
802 wm8580_add_widgets(codec); 802 wm8580_add_widgets(codec);
803 ret = snd_soc_init_card(socdev);
804 if (ret < 0) {
805 dev_err(codec->dev, "failed to register card: %d\n", ret);
806 goto card_err;
807 }
808 803
809 return ret; 804 return ret;
810 805
811card_err:
812 snd_soc_free_pcms(socdev);
813 snd_soc_dapm_free(socdev);
814pcm_err: 806pcm_err:
815 return ret; 807 return ret;
816} 808}
@@ -961,21 +953,6 @@ static int wm8580_i2c_remove(struct i2c_client *client)
961 return 0; 953 return 0;
962} 954}
963 955
964#ifdef CONFIG_PM
965static int wm8580_i2c_suspend(struct i2c_client *client, pm_message_t msg)
966{
967 return snd_soc_suspend_device(&client->dev);
968}
969
970static int wm8580_i2c_resume(struct i2c_client *client)
971{
972 return snd_soc_resume_device(&client->dev);
973}
974#else
975#define wm8580_i2c_suspend NULL
976#define wm8580_i2c_resume NULL
977#endif
978
979static const struct i2c_device_id wm8580_i2c_id[] = { 956static const struct i2c_device_id wm8580_i2c_id[] = {
980 { "wm8580", 0 }, 957 { "wm8580", 0 },
981 { } 958 { }
@@ -989,8 +966,6 @@ static struct i2c_driver wm8580_i2c_driver = {
989 }, 966 },
990 .probe = wm8580_i2c_probe, 967 .probe = wm8580_i2c_probe,
991 .remove = wm8580_i2c_remove, 968 .remove = wm8580_i2c_remove,
992 .suspend = wm8580_i2c_suspend,
993 .resume = wm8580_i2c_resume,
994 .id_table = wm8580_i2c_id, 969 .id_table = wm8580_i2c_id,
995}; 970};
996#endif 971#endif
diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c
new file mode 100644
index 000000000000..8ca3812f2f2f
--- /dev/null
+++ b/sound/soc/codecs/wm8711.c
@@ -0,0 +1,634 @@
1/*
2 * wm8711.c -- WM8711 ALSA SoC Audio driver
3 *
4 * Copyright 2006 Wolfson Microelectronics
5 *
6 * Author: Mike Arthur <linux@wolfsonmicro.com>
7 *
8 * Based on wm8731.c by Richard Purdie
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/module.h>
16#include <linux/moduleparam.h>
17#include <linux/init.h>
18#include <linux/delay.h>
19#include <linux/pm.h>
20#include <linux/i2c.h>
21#include <linux/platform_device.h>
22#include <linux/spi/spi.h>
23#include <linux/slab.h>
24#include <sound/core.h>
25#include <sound/pcm.h>
26#include <sound/pcm_params.h>
27#include <sound/soc.h>
28#include <sound/soc-dapm.h>
29#include <sound/tlv.h>
30#include <sound/initval.h>
31
32#include "wm8711.h"
33
34static struct snd_soc_codec *wm8711_codec;
35
36/* codec private data */
37struct wm8711_priv {
38 struct snd_soc_codec codec;
39 u16 reg_cache[WM8711_CACHEREGNUM];
40 unsigned int sysclk;
41};
42
43/*
44 * wm8711 register cache
45 * We can't read the WM8711 register space when we are
46 * using 2 wire for device control, so we cache them instead.
47 * There is no point in caching the reset register
48 */
49static const u16 wm8711_reg[WM8711_CACHEREGNUM] = {
50 0x0079, 0x0079, 0x000a, 0x0008,
51 0x009f, 0x000a, 0x0000, 0x0000
52};
53
54#define wm8711_reset(c) snd_soc_write(c, WM8711_RESET, 0)
55
56static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1);
57
58static const struct snd_kcontrol_new wm8711_snd_controls[] = {
59
60SOC_DOUBLE_R_TLV("Master Playback Volume", WM8711_LOUT1V, WM8711_ROUT1V,
61 0, 127, 0, out_tlv),
62SOC_DOUBLE_R("Master Playback ZC Switch", WM8711_LOUT1V, WM8711_ROUT1V,
63 7, 1, 0),
64
65};
66
67/* Output Mixer */
68static const struct snd_kcontrol_new wm8711_output_mixer_controls[] = {
69SOC_DAPM_SINGLE("Line Bypass Switch", WM8711_APANA, 3, 1, 0),
70SOC_DAPM_SINGLE("HiFi Playback Switch", WM8711_APANA, 4, 1, 0),
71};
72
73static const struct snd_soc_dapm_widget wm8711_dapm_widgets[] = {
74SND_SOC_DAPM_MIXER("Output Mixer", WM8711_PWR, 4, 1,
75 &wm8711_output_mixer_controls[0],
76 ARRAY_SIZE(wm8711_output_mixer_controls)),
77SND_SOC_DAPM_DAC("DAC", "HiFi Playback", WM8711_PWR, 3, 1),
78SND_SOC_DAPM_OUTPUT("LOUT"),
79SND_SOC_DAPM_OUTPUT("LHPOUT"),
80SND_SOC_DAPM_OUTPUT("ROUT"),
81SND_SOC_DAPM_OUTPUT("RHPOUT"),
82};
83
84static const struct snd_soc_dapm_route intercon[] = {
85 /* output mixer */
86 {"Output Mixer", "Line Bypass Switch", "Line Input"},
87 {"Output Mixer", "HiFi Playback Switch", "DAC"},
88
89 /* outputs */
90 {"RHPOUT", NULL, "Output Mixer"},
91 {"ROUT", NULL, "Output Mixer"},
92 {"LHPOUT", NULL, "Output Mixer"},
93 {"LOUT", NULL, "Output Mixer"},
94};
95
96static int wm8711_add_widgets(struct snd_soc_codec *codec)
97{
98 snd_soc_dapm_new_controls(codec, wm8711_dapm_widgets,
99 ARRAY_SIZE(wm8711_dapm_widgets));
100
101 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
102
103 return 0;
104}
105
106struct _coeff_div {
107 u32 mclk;
108 u32 rate;
109 u16 fs;
110 u8 sr:4;
111 u8 bosr:1;
112 u8 usb:1;
113};
114
115/* codec mclk clock divider coefficients */
116static const struct _coeff_div coeff_div[] = {
117 /* 48k */
118 {12288000, 48000, 256, 0x0, 0x0, 0x0},
119 {18432000, 48000, 384, 0x0, 0x1, 0x0},
120 {12000000, 48000, 250, 0x0, 0x0, 0x1},
121
122 /* 32k */
123 {12288000, 32000, 384, 0x6, 0x0, 0x0},
124 {18432000, 32000, 576, 0x6, 0x1, 0x0},
125 {12000000, 32000, 375, 0x6, 0x0, 0x1},
126
127 /* 8k */
128 {12288000, 8000, 1536, 0x3, 0x0, 0x0},
129 {18432000, 8000, 2304, 0x3, 0x1, 0x0},
130 {11289600, 8000, 1408, 0xb, 0x0, 0x0},
131 {16934400, 8000, 2112, 0xb, 0x1, 0x0},
132 {12000000, 8000, 1500, 0x3, 0x0, 0x1},
133
134 /* 96k */
135 {12288000, 96000, 128, 0x7, 0x0, 0x0},
136 {18432000, 96000, 192, 0x7, 0x1, 0x0},
137 {12000000, 96000, 125, 0x7, 0x0, 0x1},
138
139 /* 44.1k */
140 {11289600, 44100, 256, 0x8, 0x0, 0x0},
141 {16934400, 44100, 384, 0x8, 0x1, 0x0},
142 {12000000, 44100, 272, 0x8, 0x1, 0x1},
143
144 /* 88.2k */
145 {11289600, 88200, 128, 0xf, 0x0, 0x0},
146 {16934400, 88200, 192, 0xf, 0x1, 0x0},
147 {12000000, 88200, 136, 0xf, 0x1, 0x1},
148};
149
150static inline int get_coeff(int mclk, int rate)
151{
152 int i;
153
154 for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
155 if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk)
156 return i;
157 }
158 return 0;
159}
160
161static int wm8711_hw_params(struct snd_pcm_substream *substream,
162 struct snd_pcm_hw_params *params,
163 struct snd_soc_dai *dai)
164{
165 struct snd_soc_codec *codec = dai->codec;
166 struct wm8711_priv *wm8711 = codec->private_data;
167 u16 iface = snd_soc_read(codec, WM8711_IFACE) & 0xfffc;
168 int i = get_coeff(wm8711->sysclk, params_rate(params));
169 u16 srate = (coeff_div[i].sr << 2) |
170 (coeff_div[i].bosr << 1) | coeff_div[i].usb;
171
172 snd_soc_write(codec, WM8711_SRATE, srate);
173
174 /* bit size */
175 switch (params_format(params)) {
176 case SNDRV_PCM_FORMAT_S16_LE:
177 break;
178 case SNDRV_PCM_FORMAT_S20_3LE:
179 iface |= 0x0004;
180 break;
181 case SNDRV_PCM_FORMAT_S24_LE:
182 iface |= 0x0008;
183 break;
184 }
185
186 snd_soc_write(codec, WM8711_IFACE, iface);
187 return 0;
188}
189
190static int wm8711_pcm_prepare(struct snd_pcm_substream *substream,
191 struct snd_soc_dai *dai)
192{
193 struct snd_soc_codec *codec = dai->codec;
194
195 /* set active */
196 snd_soc_write(codec, WM8711_ACTIVE, 0x0001);
197
198 return 0;
199}
200
201static void wm8711_shutdown(struct snd_pcm_substream *substream,
202 struct snd_soc_dai *dai)
203{
204 struct snd_soc_codec *codec = dai->codec;
205
206 /* deactivate */
207 if (!codec->active) {
208 udelay(50);
209 snd_soc_write(codec, WM8711_ACTIVE, 0x0);
210 }
211}
212
213static int wm8711_mute(struct snd_soc_dai *dai, int mute)
214{
215 struct snd_soc_codec *codec = dai->codec;
216 u16 mute_reg = snd_soc_read(codec, WM8711_APDIGI) & 0xfff7;
217
218 if (mute)
219 snd_soc_write(codec, WM8711_APDIGI, mute_reg | 0x8);
220 else
221 snd_soc_write(codec, WM8711_APDIGI, mute_reg);
222
223 return 0;
224}
225
226static int wm8711_set_dai_sysclk(struct snd_soc_dai *codec_dai,
227 int clk_id, unsigned int freq, int dir)
228{
229 struct snd_soc_codec *codec = codec_dai->codec;
230 struct wm8711_priv *wm8711 = codec->private_data;
231
232 switch (freq) {
233 case 11289600:
234 case 12000000:
235 case 12288000:
236 case 16934400:
237 case 18432000:
238 wm8711->sysclk = freq;
239 return 0;
240 }
241 return -EINVAL;
242}
243
244static int wm8711_set_dai_fmt(struct snd_soc_dai *codec_dai,
245 unsigned int fmt)
246{
247 struct snd_soc_codec *codec = codec_dai->codec;
248 u16 iface = 0;
249
250 /* set master/slave audio interface */
251 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
252 case SND_SOC_DAIFMT_CBM_CFM:
253 iface |= 0x0040;
254 break;
255 case SND_SOC_DAIFMT_CBS_CFS:
256 break;
257 default:
258 return -EINVAL;
259 }
260
261 /* interface format */
262 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
263 case SND_SOC_DAIFMT_I2S:
264 iface |= 0x0002;
265 break;
266 case SND_SOC_DAIFMT_RIGHT_J:
267 break;
268 case SND_SOC_DAIFMT_LEFT_J:
269 iface |= 0x0001;
270 break;
271 case SND_SOC_DAIFMT_DSP_A:
272 iface |= 0x0003;
273 break;
274 case SND_SOC_DAIFMT_DSP_B:
275 iface |= 0x0013;
276 break;
277 default:
278 return -EINVAL;
279 }
280
281 /* clock inversion */
282 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
283 case SND_SOC_DAIFMT_NB_NF:
284 break;
285 case SND_SOC_DAIFMT_IB_IF:
286 iface |= 0x0090;
287 break;
288 case SND_SOC_DAIFMT_IB_NF:
289 iface |= 0x0080;
290 break;
291 case SND_SOC_DAIFMT_NB_IF:
292 iface |= 0x0010;
293 break;
294 default:
295 return -EINVAL;
296 }
297
298 /* set iface */
299 snd_soc_write(codec, WM8711_IFACE, iface);
300 return 0;
301}
302
303
304static int wm8711_set_bias_level(struct snd_soc_codec *codec,
305 enum snd_soc_bias_level level)
306{
307 u16 reg = snd_soc_read(codec, WM8711_PWR) & 0xff7f;
308
309 switch (level) {
310 case SND_SOC_BIAS_ON:
311 snd_soc_write(codec, WM8711_PWR, reg);
312 break;
313 case SND_SOC_BIAS_PREPARE:
314 break;
315 case SND_SOC_BIAS_STANDBY:
316 snd_soc_write(codec, WM8711_PWR, reg | 0x0040);
317 break;
318 case SND_SOC_BIAS_OFF:
319 snd_soc_write(codec, WM8711_ACTIVE, 0x0);
320 snd_soc_write(codec, WM8711_PWR, 0xffff);
321 break;
322 }
323 codec->bias_level = level;
324 return 0;
325}
326
327#define WM8711_RATES SNDRV_PCM_RATE_8000_96000
328
329#define WM8711_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
330 SNDRV_PCM_FMTBIT_S24_LE)
331
332static struct snd_soc_dai_ops wm8711_ops = {
333 .prepare = wm8711_pcm_prepare,
334 .hw_params = wm8711_hw_params,
335 .shutdown = wm8711_shutdown,
336 .digital_mute = wm8711_mute,
337 .set_sysclk = wm8711_set_dai_sysclk,
338 .set_fmt = wm8711_set_dai_fmt,
339};
340
341struct snd_soc_dai wm8711_dai = {
342 .name = "WM8711",
343 .playback = {
344 .stream_name = "Playback",
345 .channels_min = 1,
346 .channels_max = 2,
347 .rates = WM8711_RATES,
348 .formats = WM8711_FORMATS,
349 },
350 .ops = &wm8711_ops,
351};
352EXPORT_SYMBOL_GPL(wm8711_dai);
353
354static int wm8711_suspend(struct platform_device *pdev, pm_message_t state)
355{
356 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
357 struct snd_soc_codec *codec = socdev->card->codec;
358
359 snd_soc_write(codec, WM8711_ACTIVE, 0x0);
360 wm8711_set_bias_level(codec, SND_SOC_BIAS_OFF);
361 return 0;
362}
363
364static int wm8711_resume(struct platform_device *pdev)
365{
366 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
367 struct snd_soc_codec *codec = socdev->card->codec;
368 int i;
369 u8 data[2];
370 u16 *cache = codec->reg_cache;
371
372 /* Sync reg_cache with the hardware */
373 for (i = 0; i < ARRAY_SIZE(wm8711_reg); i++) {
374 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
375 data[1] = cache[i] & 0x00ff;
376 codec->hw_write(codec->control_data, data, 2);
377 }
378 wm8711_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
379 wm8711_set_bias_level(codec, codec->suspend_bias_level);
380 return 0;
381}
382
383static int wm8711_probe(struct platform_device *pdev)
384{
385 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
386 struct snd_soc_codec *codec;
387 int ret = 0;
388
389 if (wm8711_codec == NULL) {
390 dev_err(&pdev->dev, "Codec device not registered\n");
391 return -ENODEV;
392 }
393
394 socdev->card->codec = wm8711_codec;
395 codec = wm8711_codec;
396
397 /* register pcms */
398 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
399 if (ret < 0) {
400 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
401 goto pcm_err;
402 }
403
404 snd_soc_add_controls(codec, wm8711_snd_controls,
405 ARRAY_SIZE(wm8711_snd_controls));
406 wm8711_add_widgets(codec);
407
408 return ret;
409
410pcm_err:
411 return ret;
412}
413
414/* power down chip */
415static int wm8711_remove(struct platform_device *pdev)
416{
417 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
418
419 snd_soc_free_pcms(socdev);
420 snd_soc_dapm_free(socdev);
421
422 return 0;
423}
424
425struct snd_soc_codec_device soc_codec_dev_wm8711 = {
426 .probe = wm8711_probe,
427 .remove = wm8711_remove,
428 .suspend = wm8711_suspend,
429 .resume = wm8711_resume,
430};
431EXPORT_SYMBOL_GPL(soc_codec_dev_wm8711);
432
433static int wm8711_register(struct wm8711_priv *wm8711,
434 enum snd_soc_control_type control)
435{
436 int ret;
437 struct snd_soc_codec *codec = &wm8711->codec;
438 u16 reg;
439
440 if (wm8711_codec) {
441 dev_err(codec->dev, "Another WM8711 is registered\n");
442 return -EINVAL;
443 }
444
445 mutex_init(&codec->mutex);
446 INIT_LIST_HEAD(&codec->dapm_widgets);
447 INIT_LIST_HEAD(&codec->dapm_paths);
448
449 codec->private_data = wm8711;
450 codec->name = "WM8711";
451 codec->owner = THIS_MODULE;
452 codec->bias_level = SND_SOC_BIAS_OFF;
453 codec->set_bias_level = wm8711_set_bias_level;
454 codec->dai = &wm8711_dai;
455 codec->num_dai = 1;
456 codec->reg_cache_size = WM8711_CACHEREGNUM;
457 codec->reg_cache = &wm8711->reg_cache;
458
459 memcpy(codec->reg_cache, wm8711_reg, sizeof(wm8711_reg));
460
461 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
462 if (ret < 0) {
463 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
464 goto err;
465 }
466
467 ret = wm8711_reset(codec);
468 if (ret < 0) {
469 dev_err(codec->dev, "Failed to issue reset\n");
470 goto err;
471 }
472
473 wm8711_dai.dev = codec->dev;
474
475 wm8711_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
476
477 /* Latch the update bits */
478 reg = snd_soc_read(codec, WM8711_LOUT1V);
479 snd_soc_write(codec, WM8711_LOUT1V, reg | 0x0100);
480 reg = snd_soc_read(codec, WM8711_ROUT1V);
481 snd_soc_write(codec, WM8711_ROUT1V, reg | 0x0100);
482
483 wm8711_codec = codec;
484
485 ret = snd_soc_register_codec(codec);
486 if (ret != 0) {
487 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
488 goto err;
489 }
490
491 ret = snd_soc_register_dai(&wm8711_dai);
492 if (ret != 0) {
493 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
494 goto err_codec;
495 }
496
497 return 0;
498
499err_codec:
500 snd_soc_unregister_codec(codec);
501err:
502 kfree(wm8711);
503 return ret;
504}
505
506static void wm8711_unregister(struct wm8711_priv *wm8711)
507{
508 wm8711_set_bias_level(&wm8711->codec, SND_SOC_BIAS_OFF);
509 snd_soc_unregister_dai(&wm8711_dai);
510 snd_soc_unregister_codec(&wm8711->codec);
511 kfree(wm8711);
512 wm8711_codec = NULL;
513}
514
515#if defined(CONFIG_SPI_MASTER)
516static int __devinit wm8711_spi_probe(struct spi_device *spi)
517{
518 struct snd_soc_codec *codec;
519 struct wm8711_priv *wm8711;
520
521 wm8711 = kzalloc(sizeof(struct wm8711_priv), GFP_KERNEL);
522 if (wm8711 == NULL)
523 return -ENOMEM;
524
525 codec = &wm8711->codec;
526 codec->control_data = spi;
527 codec->dev = &spi->dev;
528
529 dev_set_drvdata(&spi->dev, wm8711);
530
531 return wm8711_register(wm8711, SND_SOC_SPI);
532}
533
534static int __devexit wm8711_spi_remove(struct spi_device *spi)
535{
536 struct wm8711_priv *wm8711 = dev_get_drvdata(&spi->dev);
537
538 wm8711_unregister(wm8711);
539
540 return 0;
541}
542
543static struct spi_driver wm8711_spi_driver = {
544 .driver = {
545 .name = "wm8711",
546 .bus = &spi_bus_type,
547 .owner = THIS_MODULE,
548 },
549 .probe = wm8711_spi_probe,
550 .remove = __devexit_p(wm8711_spi_remove),
551};
552#endif /* CONFIG_SPI_MASTER */
553
554#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
555static __devinit int wm8711_i2c_probe(struct i2c_client *i2c,
556 const struct i2c_device_id *id)
557{
558 struct wm8711_priv *wm8711;
559 struct snd_soc_codec *codec;
560
561 wm8711 = kzalloc(sizeof(struct wm8711_priv), GFP_KERNEL);
562 if (wm8711 == NULL)
563 return -ENOMEM;
564
565 codec = &wm8711->codec;
566 codec->hw_write = (hw_write_t)i2c_master_send;
567
568 i2c_set_clientdata(i2c, wm8711);
569 codec->control_data = i2c;
570
571 codec->dev = &i2c->dev;
572
573 return wm8711_register(wm8711, SND_SOC_I2C);
574}
575
576static __devexit int wm8711_i2c_remove(struct i2c_client *client)
577{
578 struct wm8711_priv *wm8711 = i2c_get_clientdata(client);
579 wm8711_unregister(wm8711);
580 return 0;
581}
582
583static const struct i2c_device_id wm8711_i2c_id[] = {
584 { "wm8711", 0 },
585 { }
586};
587MODULE_DEVICE_TABLE(i2c, wm8711_i2c_id);
588
589static struct i2c_driver wm8711_i2c_driver = {
590 .driver = {
591 .name = "WM8711 I2C Codec",
592 .owner = THIS_MODULE,
593 },
594 .probe = wm8711_i2c_probe,
595 .remove = __devexit_p(wm8711_i2c_remove),
596 .id_table = wm8711_i2c_id,
597};
598#endif
599
600static int __init wm8711_modinit(void)
601{
602 int ret;
603#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
604 ret = i2c_add_driver(&wm8711_i2c_driver);
605 if (ret != 0) {
606 printk(KERN_ERR "Failed to register WM8711 I2C driver: %d\n",
607 ret);
608 }
609#endif
610#if defined(CONFIG_SPI_MASTER)
611 ret = spi_register_driver(&wm8711_spi_driver);
612 if (ret != 0) {
613 printk(KERN_ERR "Failed to register WM8711 SPI driver: %d\n",
614 ret);
615 }
616#endif
617 return 0;
618}
619module_init(wm8711_modinit);
620
621static void __exit wm8711_exit(void)
622{
623#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
624 i2c_del_driver(&wm8711_i2c_driver);
625#endif
626#if defined(CONFIG_SPI_MASTER)
627 spi_unregister_driver(&wm8711_spi_driver);
628#endif
629}
630module_exit(wm8711_exit);
631
632MODULE_DESCRIPTION("ASoC WM8711 driver");
633MODULE_AUTHOR("Mike Arthur");
634MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8711.h b/sound/soc/codecs/wm8711.h
new file mode 100644
index 000000000000..381e84a43816
--- /dev/null
+++ b/sound/soc/codecs/wm8711.h
@@ -0,0 +1,42 @@
1/*
2 * wm8711.h -- WM8711 Soc Audio driver
3 *
4 * Copyright 2006 Wolfson Microelectronics
5 *
6 * Author: Mike Arthur <linux@wolfsonmicro.com>
7 *
8 * Based on wm8731.h
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#ifndef _WM8711_H
16#define _WM8711_H
17
18/* WM8711 register space */
19
20#define WM8711_LOUT1V 0x02
21#define WM8711_ROUT1V 0x03
22#define WM8711_APANA 0x04
23#define WM8711_APDIGI 0x05
24#define WM8711_PWR 0x06
25#define WM8711_IFACE 0x07
26#define WM8711_SRATE 0x08
27#define WM8711_ACTIVE 0x09
28#define WM8711_RESET 0x0f
29
30#define WM8711_CACHEREGNUM 8
31
32#define WM8711_SYSCLK 0
33#define WM8711_DAI 0
34
35struct wm8711_setup_data {
36 unsigned short i2c_address;
37};
38
39extern struct snd_soc_dai wm8711_dai;
40extern struct snd_soc_codec_device soc_codec_dev_wm8711;
41
42#endif
diff --git a/sound/soc/codecs/wm8727.c b/sound/soc/codecs/wm8727.c
new file mode 100644
index 000000000000..1072621e93fd
--- /dev/null
+++ b/sound/soc/codecs/wm8727.c
@@ -0,0 +1,168 @@
1/*
2 * wm8727.c
3 *
4 * Created on: 15-Oct-2009
5 * Author: neil.jones@imgtec.com
6 *
7 * Copyright (C) 2009 Imagination Technologies Ltd.
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 */
14
15#include <linux/init.h>
16#include <linux/slab.h>
17#include <linux/module.h>
18#include <linux/kernel.h>
19#include <linux/device.h>
20#include <sound/core.h>
21#include <sound/pcm.h>
22#include <sound/ac97_codec.h>
23#include <sound/initval.h>
24#include <sound/soc.h>
25
26#include "wm8727.h"
27/*
28 * Note this is a simple chip with no configuration interface, sample rate is
29 * determined automatically by examining the Master clock and Bit clock ratios
30 */
31#define WM8727_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
32 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |\
33 SNDRV_PCM_RATE_192000)
34
35
36struct snd_soc_dai wm8727_dai = {
37 .name = "WM8727",
38 .playback = {
39 .stream_name = "Playback",
40 .channels_min = 2,
41 .channels_max = 2,
42 .rates = WM8727_RATES,
43 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
44 },
45};
46EXPORT_SYMBOL_GPL(wm8727_dai);
47
48static struct snd_soc_codec *wm8727_codec;
49
50static int wm8727_soc_probe(struct platform_device *pdev)
51{
52 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
53 int ret = 0;
54
55 BUG_ON(!wm8727_codec);
56
57 socdev->card->codec = wm8727_codec;
58
59 /* register pcms */
60 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
61 if (ret < 0) {
62 printk(KERN_ERR "wm8727: failed to create pcms\n");
63 goto pcm_err;
64 }
65
66 return ret;
67
68pcm_err:
69 kfree(socdev->card->codec);
70 socdev->card->codec = NULL;
71 return ret;
72}
73
74static int wm8727_soc_remove(struct platform_device *pdev)
75{
76 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
77
78 snd_soc_free_pcms(socdev);
79
80 return 0;
81}
82
83struct snd_soc_codec_device soc_codec_dev_wm8727 = {
84 .probe = wm8727_soc_probe,
85 .remove = wm8727_soc_remove,
86};
87EXPORT_SYMBOL_GPL(soc_codec_dev_wm8727);
88
89
90static __devinit int wm8727_platform_probe(struct platform_device *pdev)
91{
92 struct snd_soc_codec *codec;
93 int ret;
94
95 if (wm8727_codec) {
96 dev_err(&pdev->dev, "Another WM8727 is registered\n");
97 return -EBUSY;
98 }
99
100 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
101 if (codec == NULL)
102 return -ENOMEM;
103 wm8727_codec = codec;
104
105 platform_set_drvdata(pdev, codec);
106
107 mutex_init(&codec->mutex);
108 codec->dev = &pdev->dev;
109 codec->name = "WM8727";
110 codec->owner = THIS_MODULE;
111 codec->dai = &wm8727_dai;
112 codec->num_dai = 1;
113 INIT_LIST_HEAD(&codec->dapm_widgets);
114 INIT_LIST_HEAD(&codec->dapm_paths);
115
116 wm8727_dai.dev = &pdev->dev;
117
118 ret = snd_soc_register_codec(codec);
119 if (ret != 0) {
120 dev_err(&pdev->dev, "Failed to register CODEC: %d\n", ret);
121 goto err;
122 }
123
124 ret = snd_soc_register_dai(&wm8727_dai);
125 if (ret != 0) {
126 dev_err(&pdev->dev, "Failed to register DAI: %d\n", ret);
127 goto err_codec;
128 }
129
130err_codec:
131 snd_soc_unregister_codec(codec);
132err:
133 kfree(codec);
134 return ret;
135}
136
137static int __devexit wm8727_platform_remove(struct platform_device *pdev)
138{
139 snd_soc_unregister_dai(&wm8727_dai);
140 snd_soc_unregister_codec(platform_get_drvdata(pdev));
141 return 0;
142}
143
144static struct platform_driver wm8727_codec_driver = {
145 .driver = {
146 .name = "wm8727-codec",
147 .owner = THIS_MODULE,
148 },
149
150 .probe = wm8727_platform_probe,
151 .remove = __devexit_p(wm8727_platform_remove),
152};
153
154static int __init wm8727_init(void)
155{
156 return platform_driver_register(&wm8727_codec_driver);
157}
158module_init(wm8727_init);
159
160static void __exit wm8727_exit(void)
161{
162 platform_driver_unregister(&wm8727_codec_driver);
163}
164module_exit(wm8727_exit);
165
166MODULE_DESCRIPTION("ASoC wm8727 driver");
167MODULE_AUTHOR("Neil Jones");
168MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8727.h b/sound/soc/codecs/wm8727.h
new file mode 100644
index 000000000000..ee19aa71bcdc
--- /dev/null
+++ b/sound/soc/codecs/wm8727.h
@@ -0,0 +1,21 @@
1/*
2 * wm8727.h
3 *
4 * Created on: 15-Oct-2009
5 * Author: neil.jones@imgtec.com
6 *
7 * Copyright (C) 2009 Imagination Technologies Ltd.
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 */
14
15#ifndef WM8727_H_
16#define WM8727_H_
17
18extern struct snd_soc_dai wm8727_dai;
19extern struct snd_soc_codec_device soc_codec_dev_wm8727;
20
21#endif /* WM8727_H_ */
diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c
index 16e969a762c3..07adc375a706 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>
@@ -74,8 +75,6 @@ static int wm8728_add_widgets(struct snd_soc_codec *codec)
74 75
75 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); 76 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
76 77
77 snd_soc_dapm_new_widgets(codec);
78
79 return 0; 78 return 0;
80} 79}
81 80
@@ -287,17 +286,9 @@ static int wm8728_init(struct snd_soc_device *socdev,
287 snd_soc_add_controls(codec, wm8728_snd_controls, 286 snd_soc_add_controls(codec, wm8728_snd_controls,
288 ARRAY_SIZE(wm8728_snd_controls)); 287 ARRAY_SIZE(wm8728_snd_controls));
289 wm8728_add_widgets(codec); 288 wm8728_add_widgets(codec);
290 ret = snd_soc_init_card(socdev);
291 if (ret < 0) {
292 printk(KERN_ERR "wm8728: failed to register card\n");
293 goto card_err;
294 }
295 289
296 return ret; 290 return ret;
297 291
298card_err:
299 snd_soc_free_pcms(socdev);
300 snd_soc_dapm_free(socdev);
301err: 292err:
302 kfree(codec->reg_cache); 293 kfree(codec->reg_cache);
303 return ret; 294 return ret;
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index d3fd4f28d96e..e7c6bf163185 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -18,7 +18,9 @@
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>
23#include <linux/regulator/consumer.h>
22#include <linux/spi/spi.h> 24#include <linux/spi/spi.h>
23#include <sound/core.h> 25#include <sound/core.h>
24#include <sound/pcm.h> 26#include <sound/pcm.h>
@@ -33,9 +35,18 @@
33static struct snd_soc_codec *wm8731_codec; 35static struct snd_soc_codec *wm8731_codec;
34struct snd_soc_codec_device soc_codec_dev_wm8731; 36struct snd_soc_codec_device soc_codec_dev_wm8731;
35 37
38#define WM8731_NUM_SUPPLIES 4
39static const char *wm8731_supply_names[WM8731_NUM_SUPPLIES] = {
40 "AVDD",
41 "HPVDD",
42 "DCVDD",
43 "DBVDD",
44};
45
36/* codec private data */ 46/* codec private data */
37struct wm8731_priv { 47struct wm8731_priv {
38 struct snd_soc_codec codec; 48 struct snd_soc_codec codec;
49 struct regulator_bulk_data supplies[WM8731_NUM_SUPPLIES];
39 u16 reg_cache[WM8731_CACHEREGNUM]; 50 u16 reg_cache[WM8731_CACHEREGNUM];
40 unsigned int sysclk; 51 unsigned int sysclk;
41}; 52};
@@ -149,7 +160,6 @@ static int wm8731_add_widgets(struct snd_soc_codec *codec)
149 160
150 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); 161 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
151 162
152 snd_soc_dapm_new_widgets(codec);
153 return 0; 163 return 0;
154} 164}
155 165
@@ -422,9 +432,12 @@ static int wm8731_suspend(struct platform_device *pdev, pm_message_t state)
422{ 432{
423 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 433 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
424 struct snd_soc_codec *codec = socdev->card->codec; 434 struct snd_soc_codec *codec = socdev->card->codec;
435 struct wm8731_priv *wm8731 = codec->private_data;
425 436
426 snd_soc_write(codec, WM8731_ACTIVE, 0x0); 437 snd_soc_write(codec, WM8731_ACTIVE, 0x0);
427 wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF); 438 wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF);
439 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies),
440 wm8731->supplies);
428 return 0; 441 return 0;
429} 442}
430 443
@@ -432,18 +445,28 @@ static int wm8731_resume(struct platform_device *pdev)
432{ 445{
433 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 446 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
434 struct snd_soc_codec *codec = socdev->card->codec; 447 struct snd_soc_codec *codec = socdev->card->codec;
435 int i; 448 struct wm8731_priv *wm8731 = codec->private_data;
449 int i, ret;
436 u8 data[2]; 450 u8 data[2];
437 u16 *cache = codec->reg_cache; 451 u16 *cache = codec->reg_cache;
438 452
453 ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies),
454 wm8731->supplies);
455 if (ret != 0)
456 return ret;
457
439 /* Sync reg_cache with the hardware */ 458 /* Sync reg_cache with the hardware */
440 for (i = 0; i < ARRAY_SIZE(wm8731_reg); i++) { 459 for (i = 0; i < ARRAY_SIZE(wm8731_reg); i++) {
460 if (cache[i] == wm8731_reg[i])
461 continue;
462
441 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001); 463 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
442 data[1] = cache[i] & 0x00ff; 464 data[1] = cache[i] & 0x00ff;
443 codec->hw_write(codec->control_data, data, 2); 465 codec->hw_write(codec->control_data, data, 2);
444 } 466 }
445 wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 467 wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
446 wm8731_set_bias_level(codec, codec->suspend_bias_level); 468 wm8731_set_bias_level(codec, codec->suspend_bias_level);
469
447 return 0; 470 return 0;
448} 471}
449#else 472#else
@@ -475,17 +498,9 @@ static int wm8731_probe(struct platform_device *pdev)
475 snd_soc_add_controls(codec, wm8731_snd_controls, 498 snd_soc_add_controls(codec, wm8731_snd_controls,
476 ARRAY_SIZE(wm8731_snd_controls)); 499 ARRAY_SIZE(wm8731_snd_controls));
477 wm8731_add_widgets(codec); 500 wm8731_add_widgets(codec);
478 ret = snd_soc_init_card(socdev);
479 if (ret < 0) {
480 dev_err(codec->dev, "failed to register card: %d\n", ret);
481 goto card_err;
482 }
483 501
484 return ret; 502 return ret;
485 503
486card_err:
487 snd_soc_free_pcms(socdev);
488 snd_soc_dapm_free(socdev);
489pcm_err: 504pcm_err:
490 return ret; 505 return ret;
491} 506}
@@ -512,7 +527,7 @@ EXPORT_SYMBOL_GPL(soc_codec_dev_wm8731);
512static int wm8731_register(struct wm8731_priv *wm8731, 527static int wm8731_register(struct wm8731_priv *wm8731,
513 enum snd_soc_control_type control) 528 enum snd_soc_control_type control)
514{ 529{
515 int ret; 530 int ret, i;
516 struct snd_soc_codec *codec = &wm8731->codec; 531 struct snd_soc_codec *codec = &wm8731->codec;
517 532
518 if (wm8731_codec) { 533 if (wm8731_codec) {
@@ -543,10 +558,27 @@ static int wm8731_register(struct wm8731_priv *wm8731,
543 goto err; 558 goto err;
544 } 559 }
545 560
561 for (i = 0; i < ARRAY_SIZE(wm8731->supplies); i++)
562 wm8731->supplies[i].supply = wm8731_supply_names[i];
563
564 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8731->supplies),
565 wm8731->supplies);
566 if (ret != 0) {
567 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
568 goto err;
569 }
570
571 ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies),
572 wm8731->supplies);
573 if (ret != 0) {
574 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
575 goto err_regulator_get;
576 }
577
546 ret = wm8731_reset(codec); 578 ret = wm8731_reset(codec);
547 if (ret < 0) { 579 if (ret < 0) {
548 dev_err(codec->dev, "Failed to issue reset: %d\n", ret); 580 dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
549 goto err; 581 goto err_regulator_enable;
550 } 582 }
551 583
552 wm8731_dai.dev = codec->dev; 584 wm8731_dai.dev = codec->dev;
@@ -567,7 +599,7 @@ static int wm8731_register(struct wm8731_priv *wm8731,
567 ret = snd_soc_register_codec(codec); 599 ret = snd_soc_register_codec(codec);
568 if (ret != 0) { 600 if (ret != 0) {
569 dev_err(codec->dev, "Failed to register codec: %d\n", ret); 601 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
570 goto err; 602 goto err_regulator_enable;
571 } 603 }
572 604
573 ret = snd_soc_register_dai(&wm8731_dai); 605 ret = snd_soc_register_dai(&wm8731_dai);
@@ -581,6 +613,10 @@ static int wm8731_register(struct wm8731_priv *wm8731,
581 613
582err_codec: 614err_codec:
583 snd_soc_unregister_codec(codec); 615 snd_soc_unregister_codec(codec);
616err_regulator_enable:
617 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
618err_regulator_get:
619 regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
584err: 620err:
585 kfree(wm8731); 621 kfree(wm8731);
586 return ret; 622 return ret;
@@ -591,6 +627,8 @@ static void wm8731_unregister(struct wm8731_priv *wm8731)
591 wm8731_set_bias_level(&wm8731->codec, SND_SOC_BIAS_OFF); 627 wm8731_set_bias_level(&wm8731->codec, SND_SOC_BIAS_OFF);
592 snd_soc_unregister_dai(&wm8731_dai); 628 snd_soc_unregister_dai(&wm8731_dai);
593 snd_soc_unregister_codec(&wm8731->codec); 629 snd_soc_unregister_codec(&wm8731->codec);
630 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
631 regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
594 kfree(wm8731); 632 kfree(wm8731);
595 wm8731_codec = NULL; 633 wm8731_codec = NULL;
596} 634}
@@ -623,21 +661,6 @@ static int __devexit wm8731_spi_remove(struct spi_device *spi)
623 return 0; 661 return 0;
624} 662}
625 663
626#ifdef CONFIG_PM
627static int wm8731_spi_suspend(struct spi_device *spi, pm_message_t msg)
628{
629 return snd_soc_suspend_device(&spi->dev);
630}
631
632static int wm8731_spi_resume(struct spi_device *spi)
633{
634 return snd_soc_resume_device(&spi->dev);
635}
636#else
637#define wm8731_spi_suspend NULL
638#define wm8731_spi_resume NULL
639#endif
640
641static struct spi_driver wm8731_spi_driver = { 664static struct spi_driver wm8731_spi_driver = {
642 .driver = { 665 .driver = {
643 .name = "wm8731", 666 .name = "wm8731",
@@ -645,8 +668,6 @@ static struct spi_driver wm8731_spi_driver = {
645 .owner = THIS_MODULE, 668 .owner = THIS_MODULE,
646 }, 669 },
647 .probe = wm8731_spi_probe, 670 .probe = wm8731_spi_probe,
648 .suspend = wm8731_spi_suspend,
649 .resume = wm8731_spi_resume,
650 .remove = __devexit_p(wm8731_spi_remove), 671 .remove = __devexit_p(wm8731_spi_remove),
651}; 672};
652#endif /* CONFIG_SPI_MASTER */ 673#endif /* CONFIG_SPI_MASTER */
@@ -679,21 +700,6 @@ static __devexit int wm8731_i2c_remove(struct i2c_client *client)
679 return 0; 700 return 0;
680} 701}
681 702
682#ifdef CONFIG_PM
683static int wm8731_i2c_suspend(struct i2c_client *i2c, pm_message_t msg)
684{
685 return snd_soc_suspend_device(&i2c->dev);
686}
687
688static int wm8731_i2c_resume(struct i2c_client *i2c)
689{
690 return snd_soc_resume_device(&i2c->dev);
691}
692#else
693#define wm8731_i2c_suspend NULL
694#define wm8731_i2c_resume NULL
695#endif
696
697static const struct i2c_device_id wm8731_i2c_id[] = { 703static const struct i2c_device_id wm8731_i2c_id[] = {
698 { "wm8731", 0 }, 704 { "wm8731", 0 },
699 { } 705 { }
@@ -707,8 +713,6 @@ static struct i2c_driver wm8731_i2c_driver = {
707 }, 713 },
708 .probe = wm8731_i2c_probe, 714 .probe = wm8731_i2c_probe,
709 .remove = __devexit_p(wm8731_i2c_remove), 715 .remove = __devexit_p(wm8731_i2c_remove),
710 .suspend = wm8731_i2c_suspend,
711 .resume = wm8731_i2c_resume,
712 .id_table = wm8731_i2c_id, 716 .id_table = wm8731_i2c_id,
713}; 717};
714#endif 718#endif
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
index 4ba1e7e93fb4..2916ed4d3844 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>
@@ -403,7 +404,6 @@ static int wm8750_add_widgets(struct snd_soc_codec *codec)
403 404
404 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 405 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
405 406
406 snd_soc_dapm_new_widgets(codec);
407 return 0; 407 return 0;
408} 408}
409 409
@@ -772,16 +772,8 @@ static int wm8750_init(struct snd_soc_device *socdev,
772 snd_soc_add_controls(codec, wm8750_snd_controls, 772 snd_soc_add_controls(codec, wm8750_snd_controls,
773 ARRAY_SIZE(wm8750_snd_controls)); 773 ARRAY_SIZE(wm8750_snd_controls));
774 wm8750_add_widgets(codec); 774 wm8750_add_widgets(codec);
775 ret = snd_soc_init_card(socdev);
776 if (ret < 0) {
777 printk(KERN_ERR "wm8750: failed to register card\n");
778 goto card_err;
779 }
780 return ret; 775 return ret;
781 776
782card_err:
783 snd_soc_free_pcms(socdev);
784 snd_soc_dapm_free(socdev);
785err: 777err:
786 kfree(codec->reg_cache); 778 kfree(codec->reg_cache);
787 return ret; 779 return ret;
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index 5ad677ce80da..613199a0f799 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>
@@ -673,7 +674,6 @@ static int wm8753_add_widgets(struct snd_soc_codec *codec)
673 674
674 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 675 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
675 676
676 snd_soc_dapm_new_widgets(codec);
677 return 0; 677 return 0;
678} 678}
679 679
@@ -724,8 +724,8 @@ static void pll_factors(struct _pll_div *pll_div, unsigned int target,
724 pll_div->k = K; 724 pll_div->k = K;
725} 725}
726 726
727static int wm8753_set_dai_pll(struct snd_soc_dai *codec_dai, 727static int wm8753_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
728 int pll_id, unsigned int freq_in, unsigned int freq_out) 728 int source, unsigned int freq_in, unsigned int freq_out)
729{ 729{
730 u16 reg, enable; 730 u16 reg, enable;
731 int offset; 731 int offset;
@@ -1508,10 +1508,6 @@ static int wm8753_suspend(struct platform_device *pdev, pm_message_t state)
1508 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1508 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1509 struct snd_soc_codec *codec = socdev->card->codec; 1509 struct snd_soc_codec *codec = socdev->card->codec;
1510 1510
1511 /* we only need to suspend if we are a valid card */
1512 if (!codec->card)
1513 return 0;
1514
1515 wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF); 1511 wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF);
1516 return 0; 1512 return 0;
1517} 1513}
@@ -1524,10 +1520,6 @@ static int wm8753_resume(struct platform_device *pdev)
1524 u8 data[2]; 1520 u8 data[2];
1525 u16 *cache = codec->reg_cache; 1521 u16 *cache = codec->reg_cache;
1526 1522
1527 /* we only need to resume if we are a valid card */
1528 if (!codec->card)
1529 return 0;
1530
1531 /* Sync reg_cache with the hardware */ 1523 /* Sync reg_cache with the hardware */
1532 for (i = 0; i < ARRAY_SIZE(wm8753_reg); i++) { 1524 for (i = 0; i < ARRAY_SIZE(wm8753_reg); i++) {
1533 if (i + 1 == WM8753_RESET) 1525 if (i + 1 == WM8753_RESET)
@@ -1583,18 +1575,9 @@ static int wm8753_probe(struct platform_device *pdev)
1583 snd_soc_add_controls(codec, wm8753_snd_controls, 1575 snd_soc_add_controls(codec, wm8753_snd_controls,
1584 ARRAY_SIZE(wm8753_snd_controls)); 1576 ARRAY_SIZE(wm8753_snd_controls));
1585 wm8753_add_widgets(codec); 1577 wm8753_add_widgets(codec);
1586 ret = snd_soc_init_card(socdev);
1587 if (ret < 0) {
1588 printk(KERN_ERR "wm8753: failed to register card\n");
1589 goto card_err;
1590 }
1591 1578
1592 return 0; 1579 return 0;
1593 1580
1594card_err:
1595 snd_soc_free_pcms(socdev);
1596 snd_soc_dapm_free(socdev);
1597
1598pcm_err: 1581pcm_err:
1599 return ret; 1582 return ret;
1600} 1583}
@@ -1767,21 +1750,6 @@ static int wm8753_i2c_remove(struct i2c_client *client)
1767 return 0; 1750 return 0;
1768} 1751}
1769 1752
1770#ifdef CONFIG_PM
1771static int wm8753_i2c_suspend(struct i2c_client *client, pm_message_t msg)
1772{
1773 return snd_soc_suspend_device(&client->dev);
1774}
1775
1776static int wm8753_i2c_resume(struct i2c_client *client)
1777{
1778 return snd_soc_resume_device(&client->dev);
1779}
1780#else
1781#define wm8753_i2c_suspend NULL
1782#define wm8753_i2c_resume NULL
1783#endif
1784
1785static const struct i2c_device_id wm8753_i2c_id[] = { 1753static const struct i2c_device_id wm8753_i2c_id[] = {
1786 { "wm8753", 0 }, 1754 { "wm8753", 0 },
1787 { } 1755 { }
@@ -1795,8 +1763,6 @@ static struct i2c_driver wm8753_i2c_driver = {
1795 }, 1763 },
1796 .probe = wm8753_i2c_probe, 1764 .probe = wm8753_i2c_probe,
1797 .remove = wm8753_i2c_remove, 1765 .remove = wm8753_i2c_remove,
1798 .suspend = wm8753_i2c_suspend,
1799 .resume = wm8753_i2c_resume,
1800 .id_table = wm8753_i2c_id, 1766 .id_table = wm8753_i2c_id,
1801}; 1767};
1802#endif 1768#endif
@@ -1852,22 +1818,6 @@ static int __devexit wm8753_spi_remove(struct spi_device *spi)
1852 return 0; 1818 return 0;
1853} 1819}
1854 1820
1855#ifdef CONFIG_PM
1856static int wm8753_spi_suspend(struct spi_device *spi, pm_message_t msg)
1857{
1858 return snd_soc_suspend_device(&spi->dev);
1859}
1860
1861static int wm8753_spi_resume(struct spi_device *spi)
1862{
1863 return snd_soc_resume_device(&spi->dev);
1864}
1865
1866#else
1867#define wm8753_spi_suspend NULL
1868#define wm8753_spi_resume NULL
1869#endif
1870
1871static struct spi_driver wm8753_spi_driver = { 1821static struct spi_driver wm8753_spi_driver = {
1872 .driver = { 1822 .driver = {
1873 .name = "wm8753", 1823 .name = "wm8753",
@@ -1876,8 +1826,6 @@ static struct spi_driver wm8753_spi_driver = {
1876 }, 1826 },
1877 .probe = wm8753_spi_probe, 1827 .probe = wm8753_spi_probe,
1878 .remove = __devexit_p(wm8753_spi_remove), 1828 .remove = __devexit_p(wm8753_spi_remove),
1879 .suspend = wm8753_spi_suspend,
1880 .resume = wm8753_spi_resume,
1881}; 1829};
1882#endif 1830#endif
1883 1831
diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c
index a9829aa26e53..60b1b3e1094b 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>
@@ -406,6 +407,8 @@ static int wm8776_resume(struct platform_device *pdev)
406 407
407 /* Sync reg_cache with the hardware */ 408 /* Sync reg_cache with the hardware */
408 for (i = 0; i < ARRAY_SIZE(wm8776_reg); i++) { 409 for (i = 0; i < ARRAY_SIZE(wm8776_reg); i++) {
410 if (cache[i] == wm8776_reg[i])
411 continue;
409 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001); 412 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
410 data[1] = cache[i] & 0x00ff; 413 data[1] = cache[i] & 0x00ff;
411 codec->hw_write(codec->control_data, data, 2); 414 codec->hw_write(codec->control_data, data, 2);
@@ -447,17 +450,8 @@ static int wm8776_probe(struct platform_device *pdev)
447 ARRAY_SIZE(wm8776_dapm_widgets)); 450 ARRAY_SIZE(wm8776_dapm_widgets));
448 snd_soc_dapm_add_routes(codec, routes, ARRAY_SIZE(routes)); 451 snd_soc_dapm_add_routes(codec, routes, ARRAY_SIZE(routes));
449 452
450 ret = snd_soc_init_card(socdev);
451 if (ret < 0) {
452 dev_err(codec->dev, "failed to register card: %d\n", ret);
453 goto card_err;
454 }
455
456 return ret; 453 return ret;
457 454
458card_err:
459 snd_soc_free_pcms(socdev);
460 snd_soc_dapm_free(socdev);
461pcm_err: 455pcm_err:
462 return ret; 456 return ret;
463} 457}
@@ -616,21 +610,6 @@ static int __devexit wm8776_spi_remove(struct spi_device *spi)
616 return 0; 610 return 0;
617} 611}
618 612
619#ifdef CONFIG_PM
620static int wm8776_spi_suspend(struct spi_device *spi, pm_message_t msg)
621{
622 return snd_soc_suspend_device(&spi->dev);
623}
624
625static int wm8776_spi_resume(struct spi_device *spi)
626{
627 return snd_soc_resume_device(&spi->dev);
628}
629#else
630#define wm8776_spi_suspend NULL
631#define wm8776_spi_resume NULL
632#endif
633
634static struct spi_driver wm8776_spi_driver = { 613static struct spi_driver wm8776_spi_driver = {
635 .driver = { 614 .driver = {
636 .name = "wm8776", 615 .name = "wm8776",
@@ -638,8 +617,6 @@ static struct spi_driver wm8776_spi_driver = {
638 .owner = THIS_MODULE, 617 .owner = THIS_MODULE,
639 }, 618 },
640 .probe = wm8776_spi_probe, 619 .probe = wm8776_spi_probe,
641 .suspend = wm8776_spi_suspend,
642 .resume = wm8776_spi_resume,
643 .remove = __devexit_p(wm8776_spi_remove), 620 .remove = __devexit_p(wm8776_spi_remove),
644}; 621};
645#endif /* CONFIG_SPI_MASTER */ 622#endif /* CONFIG_SPI_MASTER */
@@ -673,21 +650,6 @@ static __devexit int wm8776_i2c_remove(struct i2c_client *client)
673 return 0; 650 return 0;
674} 651}
675 652
676#ifdef CONFIG_PM
677static int wm8776_i2c_suspend(struct i2c_client *i2c, pm_message_t msg)
678{
679 return snd_soc_suspend_device(&i2c->dev);
680}
681
682static int wm8776_i2c_resume(struct i2c_client *i2c)
683{
684 return snd_soc_resume_device(&i2c->dev);
685}
686#else
687#define wm8776_i2c_suspend NULL
688#define wm8776_i2c_resume NULL
689#endif
690
691static const struct i2c_device_id wm8776_i2c_id[] = { 653static const struct i2c_device_id wm8776_i2c_id[] = {
692 { "wm8776", 0 }, 654 { "wm8776", 0 },
693 { } 655 { }
@@ -701,8 +663,6 @@ static struct i2c_driver wm8776_i2c_driver = {
701 }, 663 },
702 .probe = wm8776_i2c_probe, 664 .probe = wm8776_i2c_probe,
703 .remove = __devexit_p(wm8776_i2c_remove), 665 .remove = __devexit_p(wm8776_i2c_remove),
704 .suspend = wm8776_i2c_suspend,
705 .resume = wm8776_i2c_resume,
706 .id_table = wm8776_i2c_id, 666 .id_table = wm8776_i2c_id,
707}; 667};
708#endif 668#endif
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c
index 5e9c855c0036..b7fd96adac64 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>
@@ -199,7 +200,7 @@ static void wm8900_reset(struct snd_soc_codec *codec)
199 snd_soc_write(codec, WM8900_REG_RESET, 0); 200 snd_soc_write(codec, WM8900_REG_RESET, 0);
200 201
201 memcpy(codec->reg_cache, wm8900_reg_defaults, 202 memcpy(codec->reg_cache, wm8900_reg_defaults,
202 sizeof(codec->reg_cache)); 203 sizeof(wm8900_reg_defaults));
203} 204}
204 205
205static int wm8900_hp_event(struct snd_soc_dapm_widget *w, 206static int wm8900_hp_event(struct snd_soc_dapm_widget *w,
@@ -618,8 +619,6 @@ static int wm8900_add_widgets(struct snd_soc_codec *codec)
618 619
619 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 620 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
620 621
621 snd_soc_dapm_new_widgets(codec);
622
623 return 0; 622 return 0;
624} 623}
625 624
@@ -814,8 +813,8 @@ reenable:
814 return 0; 813 return 0;
815} 814}
816 815
817static int wm8900_set_dai_pll(struct snd_soc_dai *codec_dai, 816static int wm8900_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
818 int pll_id, unsigned int freq_in, unsigned int freq_out) 817 int source, unsigned int freq_in, unsigned int freq_out)
819{ 818{
820 return wm8900_set_fll(codec_dai->codec, pll_id, freq_in, freq_out); 819 return wm8900_set_fll(codec_dai->codec, pll_id, freq_in, freq_out);
821} 820}
@@ -1312,21 +1311,6 @@ static __devexit int wm8900_i2c_remove(struct i2c_client *client)
1312 return 0; 1311 return 0;
1313} 1312}
1314 1313
1315#ifdef CONFIG_PM
1316static int wm8900_i2c_suspend(struct i2c_client *client, pm_message_t msg)
1317{
1318 return snd_soc_suspend_device(&client->dev);
1319}
1320
1321static int wm8900_i2c_resume(struct i2c_client *client)
1322{
1323 return snd_soc_resume_device(&client->dev);
1324}
1325#else
1326#define wm8900_i2c_suspend NULL
1327#define wm8900_i2c_resume NULL
1328#endif
1329
1330static const struct i2c_device_id wm8900_i2c_id[] = { 1314static const struct i2c_device_id wm8900_i2c_id[] = {
1331 { "wm8900", 0 }, 1315 { "wm8900", 0 },
1332 { } 1316 { }
@@ -1340,8 +1324,6 @@ static struct i2c_driver wm8900_i2c_driver = {
1340 }, 1324 },
1341 .probe = wm8900_i2c_probe, 1325 .probe = wm8900_i2c_probe,
1342 .remove = __devexit_p(wm8900_i2c_remove), 1326 .remove = __devexit_p(wm8900_i2c_remove),
1343 .suspend = wm8900_i2c_suspend,
1344 .resume = wm8900_i2c_resume,
1345 .id_table = wm8900_i2c_id, 1327 .id_table = wm8900_i2c_id,
1346}; 1328};
1347 1329
@@ -1370,17 +1352,6 @@ static int wm8900_probe(struct platform_device *pdev)
1370 ARRAY_SIZE(wm8900_snd_controls)); 1352 ARRAY_SIZE(wm8900_snd_controls));
1371 wm8900_add_widgets(codec); 1353 wm8900_add_widgets(codec);
1372 1354
1373 ret = snd_soc_init_card(socdev);
1374 if (ret < 0) {
1375 dev_err(&pdev->dev, "Failed to register card\n");
1376 goto card_err;
1377 }
1378
1379 return ret;
1380
1381card_err:
1382 snd_soc_free_pcms(socdev);
1383 snd_soc_dapm_free(socdev);
1384pcm_err: 1355pcm_err:
1385 return ret; 1356 return ret;
1386} 1357}
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index fe1307b500cf..fa5f99fde68b 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.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>
@@ -607,7 +608,7 @@ SOC_SINGLE("Right Input PGA Common Mode Switch", WM8903_ANALOGUE_RIGHT_INPUT_1,
607SOC_SINGLE("DRC Switch", WM8903_DRC_0, 15, 1, 0), 608SOC_SINGLE("DRC Switch", WM8903_DRC_0, 15, 1, 0),
608SOC_ENUM("DRC Compressor Slope R0", drc_slope_r0), 609SOC_ENUM("DRC Compressor Slope R0", drc_slope_r0),
609SOC_ENUM("DRC Compressor Slope R1", drc_slope_r1), 610SOC_ENUM("DRC Compressor Slope R1", drc_slope_r1),
610SOC_SINGLE_TLV("DRC Compressor Threashold Volume", WM8903_DRC_3, 5, 124, 1, 611SOC_SINGLE_TLV("DRC Compressor Threshold Volume", WM8903_DRC_3, 5, 124, 1,
611 drc_tlv_thresh), 612 drc_tlv_thresh),
612SOC_SINGLE_TLV("DRC Volume", WM8903_DRC_3, 0, 30, 1, drc_tlv_amp), 613SOC_SINGLE_TLV("DRC Volume", WM8903_DRC_3, 0, 30, 1, drc_tlv_amp),
613SOC_SINGLE_TLV("DRC Minimum Gain Volume", WM8903_DRC_1, 2, 3, 1, drc_tlv_min), 614SOC_SINGLE_TLV("DRC Minimum Gain Volume", WM8903_DRC_1, 2, 3, 1, drc_tlv_min),
@@ -617,11 +618,11 @@ SOC_ENUM("DRC Decay Rate", drc_decay),
617SOC_ENUM("DRC FF Delay", drc_ff_delay), 618SOC_ENUM("DRC FF Delay", drc_ff_delay),
618SOC_SINGLE("DRC Anticlip Switch", WM8903_DRC_0, 1, 1, 0), 619SOC_SINGLE("DRC Anticlip Switch", WM8903_DRC_0, 1, 1, 0),
619SOC_SINGLE("DRC QR Switch", WM8903_DRC_0, 2, 1, 0), 620SOC_SINGLE("DRC QR Switch", WM8903_DRC_0, 2, 1, 0),
620SOC_SINGLE_TLV("DRC QR Threashold Volume", WM8903_DRC_0, 6, 3, 0, drc_tlv_max), 621SOC_SINGLE_TLV("DRC QR Threshold Volume", WM8903_DRC_0, 6, 3, 0, drc_tlv_max),
621SOC_ENUM("DRC QR Decay Rate", drc_qr_decay), 622SOC_ENUM("DRC QR Decay Rate", drc_qr_decay),
622SOC_SINGLE("DRC Smoothing Switch", WM8903_DRC_0, 3, 1, 0), 623SOC_SINGLE("DRC Smoothing Switch", WM8903_DRC_0, 3, 1, 0),
623SOC_SINGLE("DRC Smoothing Hysteresis Switch", WM8903_DRC_0, 0, 1, 0), 624SOC_SINGLE("DRC Smoothing Hysteresis Switch", WM8903_DRC_0, 0, 1, 0),
624SOC_ENUM("DRC Smoothing Threashold", drc_smoothing), 625SOC_ENUM("DRC Smoothing Threshold", drc_smoothing),
625SOC_SINGLE_TLV("DRC Startup Volume", WM8903_DRC_0, 6, 18, 0, drc_tlv_startup), 626SOC_SINGLE_TLV("DRC Startup Volume", WM8903_DRC_0, 6, 18, 0, drc_tlv_startup),
626 627
627SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8903_ADC_DIGITAL_VOLUME_LEFT, 628SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8903_ADC_DIGITAL_VOLUME_LEFT,
@@ -919,8 +920,6 @@ static int wm8903_add_widgets(struct snd_soc_codec *codec)
919 920
920 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); 921 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
921 922
922 snd_soc_dapm_new_widgets(codec);
923
924 return 0; 923 return 0;
925} 924}
926 925
@@ -1506,7 +1505,7 @@ static int wm8903_resume(struct platform_device *pdev)
1506 struct i2c_client *i2c = codec->control_data; 1505 struct i2c_client *i2c = codec->control_data;
1507 int i; 1506 int i;
1508 u16 *reg_cache = codec->reg_cache; 1507 u16 *reg_cache = codec->reg_cache;
1509 u16 *tmp_cache = kmemdup(codec->reg_cache, sizeof(wm8903_reg_defaults), 1508 u16 *tmp_cache = kmemdup(reg_cache, sizeof(wm8903_reg_defaults),
1510 GFP_KERNEL); 1509 GFP_KERNEL);
1511 1510
1512 /* Bring the codec back up to standby first to minimise pop/clicks */ 1511 /* Bring the codec back up to standby first to minimise pop/clicks */
@@ -1518,6 +1517,7 @@ static int wm8903_resume(struct platform_device *pdev)
1518 for (i = 2; i < ARRAY_SIZE(wm8903_reg_defaults); i++) 1517 for (i = 2; i < ARRAY_SIZE(wm8903_reg_defaults); i++)
1519 if (tmp_cache[i] != reg_cache[i]) 1518 if (tmp_cache[i] != reg_cache[i])
1520 snd_soc_write(codec, i, tmp_cache[i]); 1519 snd_soc_write(codec, i, tmp_cache[i]);
1520 kfree(tmp_cache);
1521 } else { 1521 } else {
1522 dev_err(&i2c->dev, "Failed to allocate temporary cache\n"); 1522 dev_err(&i2c->dev, "Failed to allocate temporary cache\n");
1523 } 1523 }
@@ -1655,21 +1655,6 @@ static __devexit int wm8903_i2c_remove(struct i2c_client *client)
1655 return 0; 1655 return 0;
1656} 1656}
1657 1657
1658#ifdef CONFIG_PM
1659static int wm8903_i2c_suspend(struct i2c_client *client, pm_message_t msg)
1660{
1661 return snd_soc_suspend_device(&client->dev);
1662}
1663
1664static int wm8903_i2c_resume(struct i2c_client *client)
1665{
1666 return snd_soc_resume_device(&client->dev);
1667}
1668#else
1669#define wm8903_i2c_suspend NULL
1670#define wm8903_i2c_resume NULL
1671#endif
1672
1673/* i2c codec control layer */ 1658/* i2c codec control layer */
1674static const struct i2c_device_id wm8903_i2c_id[] = { 1659static const struct i2c_device_id wm8903_i2c_id[] = {
1675 { "wm8903", 0 }, 1660 { "wm8903", 0 },
@@ -1684,8 +1669,6 @@ static struct i2c_driver wm8903_i2c_driver = {
1684 }, 1669 },
1685 .probe = wm8903_i2c_probe, 1670 .probe = wm8903_i2c_probe,
1686 .remove = __devexit_p(wm8903_i2c_remove), 1671 .remove = __devexit_p(wm8903_i2c_remove),
1687 .suspend = wm8903_i2c_suspend,
1688 .resume = wm8903_i2c_resume,
1689 .id_table = wm8903_i2c_id, 1672 .id_table = wm8903_i2c_id,
1690}; 1673};
1691 1674
@@ -1712,17 +1695,8 @@ static int wm8903_probe(struct platform_device *pdev)
1712 ARRAY_SIZE(wm8903_snd_controls)); 1695 ARRAY_SIZE(wm8903_snd_controls));
1713 wm8903_add_widgets(socdev->card->codec); 1696 wm8903_add_widgets(socdev->card->codec);
1714 1697
1715 ret = snd_soc_init_card(socdev);
1716 if (ret < 0) {
1717 dev_err(&pdev->dev, "wm8903: failed to register card\n");
1718 goto card_err;
1719 }
1720
1721 return ret; 1698 return ret;
1722 1699
1723card_err:
1724 snd_soc_free_pcms(socdev);
1725 snd_soc_dapm_free(socdev);
1726err: 1700err:
1727 return ret; 1701 return ret;
1728} 1702}
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
new file mode 100644
index 000000000000..c6f0abcc5711
--- /dev/null
+++ b/sound/soc/codecs/wm8904.c
@@ -0,0 +1,2657 @@
1/*
2 * wm8904.c -- WM8904 ALSA SoC Audio driver
3 *
4 * Copyright 2009 Wolfson Microelectronics plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/module.h>
15#include <linux/moduleparam.h>
16#include <linux/init.h>
17#include <linux/delay.h>
18#include <linux/pm.h>
19#include <linux/i2c.h>
20#include <linux/platform_device.h>
21#include <linux/regulator/consumer.h>
22#include <linux/slab.h>
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/initval.h>
29#include <sound/tlv.h>
30#include <sound/wm8904.h>
31
32#include "wm8904.h"
33
34static struct snd_soc_codec *wm8904_codec;
35struct snd_soc_codec_device soc_codec_dev_wm8904;
36
37enum wm8904_type {
38 WM8904,
39 WM8912,
40};
41
42#define WM8904_NUM_DCS_CHANNELS 4
43
44#define WM8904_NUM_SUPPLIES 5
45static const char *wm8904_supply_names[WM8904_NUM_SUPPLIES] = {
46 "DCVDD",
47 "DBVDD",
48 "AVDD",
49 "CPVDD",
50 "MICVDD",
51};
52
53/* codec private data */
54struct wm8904_priv {
55 struct snd_soc_codec codec;
56 u16 reg_cache[WM8904_MAX_REGISTER + 1];
57
58 enum wm8904_type devtype;
59
60 struct regulator_bulk_data supplies[WM8904_NUM_SUPPLIES];
61
62 struct wm8904_pdata *pdata;
63
64 int deemph;
65
66 /* Platform provided DRC configuration */
67 const char **drc_texts;
68 int drc_cfg;
69 struct soc_enum drc_enum;
70
71 /* Platform provided ReTune mobile configuration */
72 int num_retune_mobile_texts;
73 const char **retune_mobile_texts;
74 int retune_mobile_cfg;
75 struct soc_enum retune_mobile_enum;
76
77 /* FLL setup */
78 int fll_src;
79 int fll_fref;
80 int fll_fout;
81
82 /* Clocking configuration */
83 unsigned int mclk_rate;
84 int sysclk_src;
85 unsigned int sysclk_rate;
86
87 int tdm_width;
88 int tdm_slots;
89 int bclk;
90 int fs;
91
92 /* DC servo configuration - cached offset values */
93 int dcs_state[WM8904_NUM_DCS_CHANNELS];
94};
95
96static const u16 wm8904_reg[WM8904_MAX_REGISTER + 1] = {
97 0x8904, /* R0 - SW Reset and ID */
98 0x0000, /* R1 - Revision */
99 0x0000, /* R2 */
100 0x0000, /* R3 */
101 0x0018, /* R4 - Bias Control 0 */
102 0x0000, /* R5 - VMID Control 0 */
103 0x0000, /* R6 - Mic Bias Control 0 */
104 0x0000, /* R7 - Mic Bias Control 1 */
105 0x0001, /* R8 - Analogue DAC 0 */
106 0x9696, /* R9 - mic Filter Control */
107 0x0001, /* R10 - Analogue ADC 0 */
108 0x0000, /* R11 */
109 0x0000, /* R12 - Power Management 0 */
110 0x0000, /* R13 */
111 0x0000, /* R14 - Power Management 2 */
112 0x0000, /* R15 - Power Management 3 */
113 0x0000, /* R16 */
114 0x0000, /* R17 */
115 0x0000, /* R18 - Power Management 6 */
116 0x0000, /* R19 */
117 0x945E, /* R20 - Clock Rates 0 */
118 0x0C05, /* R21 - Clock Rates 1 */
119 0x0006, /* R22 - Clock Rates 2 */
120 0x0000, /* R23 */
121 0x0050, /* R24 - Audio Interface 0 */
122 0x000A, /* R25 - Audio Interface 1 */
123 0x00E4, /* R26 - Audio Interface 2 */
124 0x0040, /* R27 - Audio Interface 3 */
125 0x0000, /* R28 */
126 0x0000, /* R29 */
127 0x00C0, /* R30 - DAC Digital Volume Left */
128 0x00C0, /* R31 - DAC Digital Volume Right */
129 0x0000, /* R32 - DAC Digital 0 */
130 0x0008, /* R33 - DAC Digital 1 */
131 0x0000, /* R34 */
132 0x0000, /* R35 */
133 0x00C0, /* R36 - ADC Digital Volume Left */
134 0x00C0, /* R37 - ADC Digital Volume Right */
135 0x0010, /* R38 - ADC Digital 0 */
136 0x0000, /* R39 - Digital Microphone 0 */
137 0x01AF, /* R40 - DRC 0 */
138 0x3248, /* R41 - DRC 1 */
139 0x0000, /* R42 - DRC 2 */
140 0x0000, /* R43 - DRC 3 */
141 0x0085, /* R44 - Analogue Left Input 0 */
142 0x0085, /* R45 - Analogue Right Input 0 */
143 0x0044, /* R46 - Analogue Left Input 1 */
144 0x0044, /* R47 - Analogue Right Input 1 */
145 0x0000, /* R48 */
146 0x0000, /* R49 */
147 0x0000, /* R50 */
148 0x0000, /* R51 */
149 0x0000, /* R52 */
150 0x0000, /* R53 */
151 0x0000, /* R54 */
152 0x0000, /* R55 */
153 0x0000, /* R56 */
154 0x002D, /* R57 - Analogue OUT1 Left */
155 0x002D, /* R58 - Analogue OUT1 Right */
156 0x0039, /* R59 - Analogue OUT2 Left */
157 0x0039, /* R60 - Analogue OUT2 Right */
158 0x0000, /* R61 - Analogue OUT12 ZC */
159 0x0000, /* R62 */
160 0x0000, /* R63 */
161 0x0000, /* R64 */
162 0x0000, /* R65 */
163 0x0000, /* R66 */
164 0x0000, /* R67 - DC Servo 0 */
165 0x0000, /* R68 - DC Servo 1 */
166 0xAAAA, /* R69 - DC Servo 2 */
167 0x0000, /* R70 */
168 0xAAAA, /* R71 - DC Servo 4 */
169 0xAAAA, /* R72 - DC Servo 5 */
170 0x0000, /* R73 - DC Servo 6 */
171 0x0000, /* R74 - DC Servo 7 */
172 0x0000, /* R75 - DC Servo 8 */
173 0x0000, /* R76 - DC Servo 9 */
174 0x0000, /* R77 - DC Servo Readback 0 */
175 0x0000, /* R78 */
176 0x0000, /* R79 */
177 0x0000, /* R80 */
178 0x0000, /* R81 */
179 0x0000, /* R82 */
180 0x0000, /* R83 */
181 0x0000, /* R84 */
182 0x0000, /* R85 */
183 0x0000, /* R86 */
184 0x0000, /* R87 */
185 0x0000, /* R88 */
186 0x0000, /* R89 */
187 0x0000, /* R90 - Analogue HP 0 */
188 0x0000, /* R91 */
189 0x0000, /* R92 */
190 0x0000, /* R93 */
191 0x0000, /* R94 - Analogue Lineout 0 */
192 0x0000, /* R95 */
193 0x0000, /* R96 */
194 0x0000, /* R97 */
195 0x0000, /* R98 - Charge Pump 0 */
196 0x0000, /* R99 */
197 0x0000, /* R100 */
198 0x0000, /* R101 */
199 0x0000, /* R102 */
200 0x0000, /* R103 */
201 0x0004, /* R104 - Class W 0 */
202 0x0000, /* R105 */
203 0x0000, /* R106 */
204 0x0000, /* R107 */
205 0x0000, /* R108 - Write Sequencer 0 */
206 0x0000, /* R109 - Write Sequencer 1 */
207 0x0000, /* R110 - Write Sequencer 2 */
208 0x0000, /* R111 - Write Sequencer 3 */
209 0x0000, /* R112 - Write Sequencer 4 */
210 0x0000, /* R113 */
211 0x0000, /* R114 */
212 0x0000, /* R115 */
213 0x0000, /* R116 - FLL Control 1 */
214 0x0007, /* R117 - FLL Control 2 */
215 0x0000, /* R118 - FLL Control 3 */
216 0x2EE0, /* R119 - FLL Control 4 */
217 0x0004, /* R120 - FLL Control 5 */
218 0x0014, /* R121 - GPIO Control 1 */
219 0x0010, /* R122 - GPIO Control 2 */
220 0x0010, /* R123 - GPIO Control 3 */
221 0x0000, /* R124 - GPIO Control 4 */
222 0x0000, /* R125 */
223 0x0000, /* R126 - Digital Pulls */
224 0x0000, /* R127 - Interrupt Status */
225 0xFFFF, /* R128 - Interrupt Status Mask */
226 0x0000, /* R129 - Interrupt Polarity */
227 0x0000, /* R130 - Interrupt Debounce */
228 0x0000, /* R131 */
229 0x0000, /* R132 */
230 0x0000, /* R133 */
231 0x0000, /* R134 - EQ1 */
232 0x000C, /* R135 - EQ2 */
233 0x000C, /* R136 - EQ3 */
234 0x000C, /* R137 - EQ4 */
235 0x000C, /* R138 - EQ5 */
236 0x000C, /* R139 - EQ6 */
237 0x0FCA, /* R140 - EQ7 */
238 0x0400, /* R141 - EQ8 */
239 0x00D8, /* R142 - EQ9 */
240 0x1EB5, /* R143 - EQ10 */
241 0xF145, /* R144 - EQ11 */
242 0x0B75, /* R145 - EQ12 */
243 0x01C5, /* R146 - EQ13 */
244 0x1C58, /* R147 - EQ14 */
245 0xF373, /* R148 - EQ15 */
246 0x0A54, /* R149 - EQ16 */
247 0x0558, /* R150 - EQ17 */
248 0x168E, /* R151 - EQ18 */
249 0xF829, /* R152 - EQ19 */
250 0x07AD, /* R153 - EQ20 */
251 0x1103, /* R154 - EQ21 */
252 0x0564, /* R155 - EQ22 */
253 0x0559, /* R156 - EQ23 */
254 0x4000, /* R157 - EQ24 */
255 0x0000, /* R158 */
256 0x0000, /* R159 */
257 0x0000, /* R160 */
258 0x0000, /* R161 - Control Interface Test 1 */
259 0x0000, /* R162 */
260 0x0000, /* R163 */
261 0x0000, /* R164 */
262 0x0000, /* R165 */
263 0x0000, /* R166 */
264 0x0000, /* R167 */
265 0x0000, /* R168 */
266 0x0000, /* R169 */
267 0x0000, /* R170 */
268 0x0000, /* R171 */
269 0x0000, /* R172 */
270 0x0000, /* R173 */
271 0x0000, /* R174 */
272 0x0000, /* R175 */
273 0x0000, /* R176 */
274 0x0000, /* R177 */
275 0x0000, /* R178 */
276 0x0000, /* R179 */
277 0x0000, /* R180 */
278 0x0000, /* R181 */
279 0x0000, /* R182 */
280 0x0000, /* R183 */
281 0x0000, /* R184 */
282 0x0000, /* R185 */
283 0x0000, /* R186 */
284 0x0000, /* R187 */
285 0x0000, /* R188 */
286 0x0000, /* R189 */
287 0x0000, /* R190 */
288 0x0000, /* R191 */
289 0x0000, /* R192 */
290 0x0000, /* R193 */
291 0x0000, /* R194 */
292 0x0000, /* R195 */
293 0x0000, /* R196 */
294 0x0000, /* R197 */
295 0x0000, /* R198 */
296 0x0000, /* R199 */
297 0x0000, /* R200 */
298 0x0000, /* R201 */
299 0x0000, /* R202 */
300 0x0000, /* R203 */
301 0x0000, /* R204 - Analogue Output Bias 0 */
302 0x0000, /* R205 */
303 0x0000, /* R206 */
304 0x0000, /* R207 */
305 0x0000, /* R208 */
306 0x0000, /* R209 */
307 0x0000, /* R210 */
308 0x0000, /* R211 */
309 0x0000, /* R212 */
310 0x0000, /* R213 */
311 0x0000, /* R214 */
312 0x0000, /* R215 */
313 0x0000, /* R216 */
314 0x0000, /* R217 */
315 0x0000, /* R218 */
316 0x0000, /* R219 */
317 0x0000, /* R220 */
318 0x0000, /* R221 */
319 0x0000, /* R222 */
320 0x0000, /* R223 */
321 0x0000, /* R224 */
322 0x0000, /* R225 */
323 0x0000, /* R226 */
324 0x0000, /* R227 */
325 0x0000, /* R228 */
326 0x0000, /* R229 */
327 0x0000, /* R230 */
328 0x0000, /* R231 */
329 0x0000, /* R232 */
330 0x0000, /* R233 */
331 0x0000, /* R234 */
332 0x0000, /* R235 */
333 0x0000, /* R236 */
334 0x0000, /* R237 */
335 0x0000, /* R238 */
336 0x0000, /* R239 */
337 0x0000, /* R240 */
338 0x0000, /* R241 */
339 0x0000, /* R242 */
340 0x0000, /* R243 */
341 0x0000, /* R244 */
342 0x0000, /* R245 */
343 0x0000, /* R246 */
344 0x0000, /* R247 - FLL NCO Test 0 */
345 0x0019, /* R248 - FLL NCO Test 1 */
346};
347
348static struct {
349 int readable;
350 int writable;
351 int vol;
352} wm8904_access[] = {
353 { 0xFFFF, 0xFFFF, 1 }, /* R0 - SW Reset and ID */
354 { 0x0000, 0x0000, 0 }, /* R1 - Revision */
355 { 0x0000, 0x0000, 0 }, /* R2 */
356 { 0x0000, 0x0000, 0 }, /* R3 */
357 { 0x001F, 0x001F, 0 }, /* R4 - Bias Control 0 */
358 { 0x0047, 0x0047, 0 }, /* R5 - VMID Control 0 */
359 { 0x007F, 0x007F, 0 }, /* R6 - Mic Bias Control 0 */
360 { 0xC007, 0xC007, 0 }, /* R7 - Mic Bias Control 1 */
361 { 0x001E, 0x001E, 0 }, /* R8 - Analogue DAC 0 */
362 { 0xFFFF, 0xFFFF, 0 }, /* R9 - mic Filter Control */
363 { 0x0001, 0x0001, 0 }, /* R10 - Analogue ADC 0 */
364 { 0x0000, 0x0000, 0 }, /* R11 */
365 { 0x0003, 0x0003, 0 }, /* R12 - Power Management 0 */
366 { 0x0000, 0x0000, 0 }, /* R13 */
367 { 0x0003, 0x0003, 0 }, /* R14 - Power Management 2 */
368 { 0x0003, 0x0003, 0 }, /* R15 - Power Management 3 */
369 { 0x0000, 0x0000, 0 }, /* R16 */
370 { 0x0000, 0x0000, 0 }, /* R17 */
371 { 0x000F, 0x000F, 0 }, /* R18 - Power Management 6 */
372 { 0x0000, 0x0000, 0 }, /* R19 */
373 { 0x7001, 0x7001, 0 }, /* R20 - Clock Rates 0 */
374 { 0x3C07, 0x3C07, 0 }, /* R21 - Clock Rates 1 */
375 { 0xD00F, 0xD00F, 0 }, /* R22 - Clock Rates 2 */
376 { 0x0000, 0x0000, 0 }, /* R23 */
377 { 0x1FFF, 0x1FFF, 0 }, /* R24 - Audio Interface 0 */
378 { 0x3DDF, 0x3DDF, 0 }, /* R25 - Audio Interface 1 */
379 { 0x0F1F, 0x0F1F, 0 }, /* R26 - Audio Interface 2 */
380 { 0x0FFF, 0x0FFF, 0 }, /* R27 - Audio Interface 3 */
381 { 0x0000, 0x0000, 0 }, /* R28 */
382 { 0x0000, 0x0000, 0 }, /* R29 */
383 { 0x00FF, 0x01FF, 0 }, /* R30 - DAC Digital Volume Left */
384 { 0x00FF, 0x01FF, 0 }, /* R31 - DAC Digital Volume Right */
385 { 0x0FFF, 0x0FFF, 0 }, /* R32 - DAC Digital 0 */
386 { 0x1E4E, 0x1E4E, 0 }, /* R33 - DAC Digital 1 */
387 { 0x0000, 0x0000, 0 }, /* R34 */
388 { 0x0000, 0x0000, 0 }, /* R35 */
389 { 0x00FF, 0x01FF, 0 }, /* R36 - ADC Digital Volume Left */
390 { 0x00FF, 0x01FF, 0 }, /* R37 - ADC Digital Volume Right */
391 { 0x0073, 0x0073, 0 }, /* R38 - ADC Digital 0 */
392 { 0x1800, 0x1800, 0 }, /* R39 - Digital Microphone 0 */
393 { 0xDFEF, 0xDFEF, 0 }, /* R40 - DRC 0 */
394 { 0xFFFF, 0xFFFF, 0 }, /* R41 - DRC 1 */
395 { 0x003F, 0x003F, 0 }, /* R42 - DRC 2 */
396 { 0x07FF, 0x07FF, 0 }, /* R43 - DRC 3 */
397 { 0x009F, 0x009F, 0 }, /* R44 - Analogue Left Input 0 */
398 { 0x009F, 0x009F, 0 }, /* R45 - Analogue Right Input 0 */
399 { 0x007F, 0x007F, 0 }, /* R46 - Analogue Left Input 1 */
400 { 0x007F, 0x007F, 0 }, /* R47 - Analogue Right Input 1 */
401 { 0x0000, 0x0000, 0 }, /* R48 */
402 { 0x0000, 0x0000, 0 }, /* R49 */
403 { 0x0000, 0x0000, 0 }, /* R50 */
404 { 0x0000, 0x0000, 0 }, /* R51 */
405 { 0x0000, 0x0000, 0 }, /* R52 */
406 { 0x0000, 0x0000, 0 }, /* R53 */
407 { 0x0000, 0x0000, 0 }, /* R54 */
408 { 0x0000, 0x0000, 0 }, /* R55 */
409 { 0x0000, 0x0000, 0 }, /* R56 */
410 { 0x017F, 0x01FF, 0 }, /* R57 - Analogue OUT1 Left */
411 { 0x017F, 0x01FF, 0 }, /* R58 - Analogue OUT1 Right */
412 { 0x017F, 0x01FF, 0 }, /* R59 - Analogue OUT2 Left */
413 { 0x017F, 0x01FF, 0 }, /* R60 - Analogue OUT2 Right */
414 { 0x000F, 0x000F, 0 }, /* R61 - Analogue OUT12 ZC */
415 { 0x0000, 0x0000, 0 }, /* R62 */
416 { 0x0000, 0x0000, 0 }, /* R63 */
417 { 0x0000, 0x0000, 0 }, /* R64 */
418 { 0x0000, 0x0000, 0 }, /* R65 */
419 { 0x0000, 0x0000, 0 }, /* R66 */
420 { 0x000F, 0x000F, 0 }, /* R67 - DC Servo 0 */
421 { 0xFFFF, 0xFFFF, 1 }, /* R68 - DC Servo 1 */
422 { 0x0F0F, 0x0F0F, 0 }, /* R69 - DC Servo 2 */
423 { 0x0000, 0x0000, 0 }, /* R70 */
424 { 0x007F, 0x007F, 0 }, /* R71 - DC Servo 4 */
425 { 0x007F, 0x007F, 0 }, /* R72 - DC Servo 5 */
426 { 0x00FF, 0x00FF, 1 }, /* R73 - DC Servo 6 */
427 { 0x00FF, 0x00FF, 1 }, /* R74 - DC Servo 7 */
428 { 0x00FF, 0x00FF, 1 }, /* R75 - DC Servo 8 */
429 { 0x00FF, 0x00FF, 1 }, /* R76 - DC Servo 9 */
430 { 0x0FFF, 0x0000, 1 }, /* R77 - DC Servo Readback 0 */
431 { 0x0000, 0x0000, 0 }, /* R78 */
432 { 0x0000, 0x0000, 0 }, /* R79 */
433 { 0x0000, 0x0000, 0 }, /* R80 */
434 { 0x0000, 0x0000, 0 }, /* R81 */
435 { 0x0000, 0x0000, 0 }, /* R82 */
436 { 0x0000, 0x0000, 0 }, /* R83 */
437 { 0x0000, 0x0000, 0 }, /* R84 */
438 { 0x0000, 0x0000, 0 }, /* R85 */
439 { 0x0000, 0x0000, 0 }, /* R86 */
440 { 0x0000, 0x0000, 0 }, /* R87 */
441 { 0x0000, 0x0000, 0 }, /* R88 */
442 { 0x0000, 0x0000, 0 }, /* R89 */
443 { 0x00FF, 0x00FF, 0 }, /* R90 - Analogue HP 0 */
444 { 0x0000, 0x0000, 0 }, /* R91 */
445 { 0x0000, 0x0000, 0 }, /* R92 */
446 { 0x0000, 0x0000, 0 }, /* R93 */
447 { 0x00FF, 0x00FF, 0 }, /* R94 - Analogue Lineout 0 */
448 { 0x0000, 0x0000, 0 }, /* R95 */
449 { 0x0000, 0x0000, 0 }, /* R96 */
450 { 0x0000, 0x0000, 0 }, /* R97 */
451 { 0x0001, 0x0001, 0 }, /* R98 - Charge Pump 0 */
452 { 0x0000, 0x0000, 0 }, /* R99 */
453 { 0x0000, 0x0000, 0 }, /* R100 */
454 { 0x0000, 0x0000, 0 }, /* R101 */
455 { 0x0000, 0x0000, 0 }, /* R102 */
456 { 0x0000, 0x0000, 0 }, /* R103 */
457 { 0x0001, 0x0001, 0 }, /* R104 - Class W 0 */
458 { 0x0000, 0x0000, 0 }, /* R105 */
459 { 0x0000, 0x0000, 0 }, /* R106 */
460 { 0x0000, 0x0000, 0 }, /* R107 */
461 { 0x011F, 0x011F, 0 }, /* R108 - Write Sequencer 0 */
462 { 0x7FFF, 0x7FFF, 0 }, /* R109 - Write Sequencer 1 */
463 { 0x4FFF, 0x4FFF, 0 }, /* R110 - Write Sequencer 2 */
464 { 0x003F, 0x033F, 0 }, /* R111 - Write Sequencer 3 */
465 { 0x03F1, 0x0000, 0 }, /* R112 - Write Sequencer 4 */
466 { 0x0000, 0x0000, 0 }, /* R113 */
467 { 0x0000, 0x0000, 0 }, /* R114 */
468 { 0x0000, 0x0000, 0 }, /* R115 */
469 { 0x0007, 0x0007, 0 }, /* R116 - FLL Control 1 */
470 { 0x3F77, 0x3F77, 0 }, /* R117 - FLL Control 2 */
471 { 0xFFFF, 0xFFFF, 0 }, /* R118 - FLL Control 3 */
472 { 0x7FEF, 0x7FEF, 0 }, /* R119 - FLL Control 4 */
473 { 0x001B, 0x001B, 0 }, /* R120 - FLL Control 5 */
474 { 0x003F, 0x003F, 0 }, /* R121 - GPIO Control 1 */
475 { 0x003F, 0x003F, 0 }, /* R122 - GPIO Control 2 */
476 { 0x003F, 0x003F, 0 }, /* R123 - GPIO Control 3 */
477 { 0x038F, 0x038F, 0 }, /* R124 - GPIO Control 4 */
478 { 0x0000, 0x0000, 0 }, /* R125 */
479 { 0x00FF, 0x00FF, 0 }, /* R126 - Digital Pulls */
480 { 0x07FF, 0x03FF, 1 }, /* R127 - Interrupt Status */
481 { 0x03FF, 0x03FF, 0 }, /* R128 - Interrupt Status Mask */
482 { 0x03FF, 0x03FF, 0 }, /* R129 - Interrupt Polarity */
483 { 0x03FF, 0x03FF, 0 }, /* R130 - Interrupt Debounce */
484 { 0x0000, 0x0000, 0 }, /* R131 */
485 { 0x0000, 0x0000, 0 }, /* R132 */
486 { 0x0000, 0x0000, 0 }, /* R133 */
487 { 0x0001, 0x0001, 0 }, /* R134 - EQ1 */
488 { 0x001F, 0x001F, 0 }, /* R135 - EQ2 */
489 { 0x001F, 0x001F, 0 }, /* R136 - EQ3 */
490 { 0x001F, 0x001F, 0 }, /* R137 - EQ4 */
491 { 0x001F, 0x001F, 0 }, /* R138 - EQ5 */
492 { 0x001F, 0x001F, 0 }, /* R139 - EQ6 */
493 { 0xFFFF, 0xFFFF, 0 }, /* R140 - EQ7 */
494 { 0xFFFF, 0xFFFF, 0 }, /* R141 - EQ8 */
495 { 0xFFFF, 0xFFFF, 0 }, /* R142 - EQ9 */
496 { 0xFFFF, 0xFFFF, 0 }, /* R143 - EQ10 */
497 { 0xFFFF, 0xFFFF, 0 }, /* R144 - EQ11 */
498 { 0xFFFF, 0xFFFF, 0 }, /* R145 - EQ12 */
499 { 0xFFFF, 0xFFFF, 0 }, /* R146 - EQ13 */
500 { 0xFFFF, 0xFFFF, 0 }, /* R147 - EQ14 */
501 { 0xFFFF, 0xFFFF, 0 }, /* R148 - EQ15 */
502 { 0xFFFF, 0xFFFF, 0 }, /* R149 - EQ16 */
503 { 0xFFFF, 0xFFFF, 0 }, /* R150 - EQ17 */
504 { 0xFFFF, 0xFFFF, 0 }, /* R151wm8523_dai - EQ18 */
505 { 0xFFFF, 0xFFFF, 0 }, /* R152 - EQ19 */
506 { 0xFFFF, 0xFFFF, 0 }, /* R153 - EQ20 */
507 { 0xFFFF, 0xFFFF, 0 }, /* R154 - EQ21 */
508 { 0xFFFF, 0xFFFF, 0 }, /* R155 - EQ22 */
509 { 0xFFFF, 0xFFFF, 0 }, /* R156 - EQ23 */
510 { 0xFFFF, 0xFFFF, 0 }, /* R157 - EQ24 */
511 { 0x0000, 0x0000, 0 }, /* R158 */
512 { 0x0000, 0x0000, 0 }, /* R159 */
513 { 0x0000, 0x0000, 0 }, /* R160 */
514 { 0x0002, 0x0002, 0 }, /* R161 - Control Interface Test 1 */
515 { 0x0000, 0x0000, 0 }, /* R162 */
516 { 0x0000, 0x0000, 0 }, /* R163 */
517 { 0x0000, 0x0000, 0 }, /* R164 */
518 { 0x0000, 0x0000, 0 }, /* R165 */
519 { 0x0000, 0x0000, 0 }, /* R166 */
520 { 0x0000, 0x0000, 0 }, /* R167 */
521 { 0x0000, 0x0000, 0 }, /* R168 */
522 { 0x0000, 0x0000, 0 }, /* R169 */
523 { 0x0000, 0x0000, 0 }, /* R170 */
524 { 0x0000, 0x0000, 0 }, /* R171 */
525 { 0x0000, 0x0000, 0 }, /* R172 */
526 { 0x0000, 0x0000, 0 }, /* R173 */
527 { 0x0000, 0x0000, 0 }, /* R174 */
528 { 0x0000, 0x0000, 0 }, /* R175 */
529 { 0x0000, 0x0000, 0 }, /* R176 */
530 { 0x0000, 0x0000, 0 }, /* R177 */
531 { 0x0000, 0x0000, 0 }, /* R178 */
532 { 0x0000, 0x0000, 0 }, /* R179 */
533 { 0x0000, 0x0000, 0 }, /* R180 */
534 { 0x0000, 0x0000, 0 }, /* R181 */
535 { 0x0000, 0x0000, 0 }, /* R182 */
536 { 0x0000, 0x0000, 0 }, /* R183 */
537 { 0x0000, 0x0000, 0 }, /* R184 */
538 { 0x0000, 0x0000, 0 }, /* R185 */
539 { 0x0000, 0x0000, 0 }, /* R186 */
540 { 0x0000, 0x0000, 0 }, /* R187 */
541 { 0x0000, 0x0000, 0 }, /* R188 */
542 { 0x0000, 0x0000, 0 }, /* R189 */
543 { 0x0000, 0x0000, 0 }, /* R190 */
544 { 0x0000, 0x0000, 0 }, /* R191 */
545 { 0x0000, 0x0000, 0 }, /* R192 */
546 { 0x0000, 0x0000, 0 }, /* R193 */
547 { 0x0000, 0x0000, 0 }, /* R194 */
548 { 0x0000, 0x0000, 0 }, /* R195 */
549 { 0x0000, 0x0000, 0 }, /* R196 */
550 { 0x0000, 0x0000, 0 }, /* R197 */
551 { 0x0000, 0x0000, 0 }, /* R198 */
552 { 0x0000, 0x0000, 0 }, /* R199 */
553 { 0x0000, 0x0000, 0 }, /* R200 */
554 { 0x0000, 0x0000, 0 }, /* R201 */
555 { 0x0000, 0x0000, 0 }, /* R202 */
556 { 0x0000, 0x0000, 0 }, /* R203 */
557 { 0x0070, 0x0070, 0 }, /* R204 - Analogue Output Bias 0 */
558 { 0x0000, 0x0000, 0 }, /* R205 */
559 { 0x0000, 0x0000, 0 }, /* R206 */
560 { 0x0000, 0x0000, 0 }, /* R207 */
561 { 0x0000, 0x0000, 0 }, /* R208 */
562 { 0x0000, 0x0000, 0 }, /* R209 */
563 { 0x0000, 0x0000, 0 }, /* R210 */
564 { 0x0000, 0x0000, 0 }, /* R211 */
565 { 0x0000, 0x0000, 0 }, /* R212 */
566 { 0x0000, 0x0000, 0 }, /* R213 */
567 { 0x0000, 0x0000, 0 }, /* R214 */
568 { 0x0000, 0x0000, 0 }, /* R215 */
569 { 0x0000, 0x0000, 0 }, /* R216 */
570 { 0x0000, 0x0000, 0 }, /* R217 */
571 { 0x0000, 0x0000, 0 }, /* R218 */
572 { 0x0000, 0x0000, 0 }, /* R219 */
573 { 0x0000, 0x0000, 0 }, /* R220 */
574 { 0x0000, 0x0000, 0 }, /* R221 */
575 { 0x0000, 0x0000, 0 }, /* R222 */
576 { 0x0000, 0x0000, 0 }, /* R223 */
577 { 0x0000, 0x0000, 0 }, /* R224 */
578 { 0x0000, 0x0000, 0 }, /* R225 */
579 { 0x0000, 0x0000, 0 }, /* R226 */
580 { 0x0000, 0x0000, 0 }, /* R227 */
581 { 0x0000, 0x0000, 0 }, /* R228 */
582 { 0x0000, 0x0000, 0 }, /* R229 */
583 { 0x0000, 0x0000, 0 }, /* R230 */
584 { 0x0000, 0x0000, 0 }, /* R231 */
585 { 0x0000, 0x0000, 0 }, /* R232 */
586 { 0x0000, 0x0000, 0 }, /* R233 */
587 { 0x0000, 0x0000, 0 }, /* R234 */
588 { 0x0000, 0x0000, 0 }, /* R235 */
589 { 0x0000, 0x0000, 0 }, /* R236 */
590 { 0x0000, 0x0000, 0 }, /* R237 */
591 { 0x0000, 0x0000, 0 }, /* R238 */
592 { 0x0000, 0x0000, 0 }, /* R239 */
593 { 0x0000, 0x0000, 0 }, /* R240 */
594 { 0x0000, 0x0000, 0 }, /* R241 */
595 { 0x0000, 0x0000, 0 }, /* R242 */
596 { 0x0000, 0x0000, 0 }, /* R243 */
597 { 0x0000, 0x0000, 0 }, /* R244 */
598 { 0x0000, 0x0000, 0 }, /* R245 */
599 { 0x0000, 0x0000, 0 }, /* R246 */
600 { 0x0001, 0x0001, 0 }, /* R247 - FLL NCO Test 0 */
601 { 0x003F, 0x003F, 0 }, /* R248 - FLL NCO Test 1 */
602};
603
604static int wm8904_volatile_register(unsigned int reg)
605{
606 return wm8904_access[reg].vol;
607}
608
609static int wm8904_reset(struct snd_soc_codec *codec)
610{
611 return snd_soc_write(codec, WM8904_SW_RESET_AND_ID, 0);
612}
613
614static int wm8904_configure_clocking(struct snd_soc_codec *codec)
615{
616 struct wm8904_priv *wm8904 = codec->private_data;
617 unsigned int clock0, clock2, rate;
618
619 /* Gate the clock while we're updating to avoid misclocking */
620 clock2 = snd_soc_read(codec, WM8904_CLOCK_RATES_2);
621 snd_soc_update_bits(codec, WM8904_CLOCK_RATES_2,
622 WM8904_SYSCLK_SRC, 0);
623
624 /* This should be done on init() for bypass paths */
625 switch (wm8904->sysclk_src) {
626 case WM8904_CLK_MCLK:
627 dev_dbg(codec->dev, "Using %dHz MCLK\n", wm8904->mclk_rate);
628
629 clock2 &= ~WM8904_SYSCLK_SRC;
630 rate = wm8904->mclk_rate;
631
632 /* Ensure the FLL is stopped */
633 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
634 WM8904_FLL_OSC_ENA | WM8904_FLL_ENA, 0);
635 break;
636
637 case WM8904_CLK_FLL:
638 dev_dbg(codec->dev, "Using %dHz FLL clock\n",
639 wm8904->fll_fout);
640
641 clock2 |= WM8904_SYSCLK_SRC;
642 rate = wm8904->fll_fout;
643 break;
644
645 default:
646 dev_err(codec->dev, "System clock not configured\n");
647 return -EINVAL;
648 }
649
650 /* SYSCLK shouldn't be over 13.5MHz */
651 if (rate > 13500000) {
652 clock0 = WM8904_MCLK_DIV;
653 wm8904->sysclk_rate = rate / 2;
654 } else {
655 clock0 = 0;
656 wm8904->sysclk_rate = rate;
657 }
658
659 snd_soc_update_bits(codec, WM8904_CLOCK_RATES_0, WM8904_MCLK_DIV,
660 clock0);
661
662 snd_soc_update_bits(codec, WM8904_CLOCK_RATES_2,
663 WM8904_CLK_SYS_ENA | WM8904_SYSCLK_SRC, clock2);
664
665 dev_dbg(codec->dev, "CLK_SYS is %dHz\n", wm8904->sysclk_rate);
666
667 return 0;
668}
669
670static void wm8904_set_drc(struct snd_soc_codec *codec)
671{
672 struct wm8904_priv *wm8904 = codec->private_data;
673 struct wm8904_pdata *pdata = wm8904->pdata;
674 int save, i;
675
676 /* Save any enables; the configuration should clear them. */
677 save = snd_soc_read(codec, WM8904_DRC_0);
678
679 for (i = 0; i < WM8904_DRC_REGS; i++)
680 snd_soc_update_bits(codec, WM8904_DRC_0 + i, 0xffff,
681 pdata->drc_cfgs[wm8904->drc_cfg].regs[i]);
682
683 /* Reenable the DRC */
684 snd_soc_update_bits(codec, WM8904_DRC_0,
685 WM8904_DRC_ENA | WM8904_DRC_DAC_PATH, save);
686}
687
688static int wm8904_put_drc_enum(struct snd_kcontrol *kcontrol,
689 struct snd_ctl_elem_value *ucontrol)
690{
691 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
692 struct wm8904_priv *wm8904 = codec->private_data;
693 struct wm8904_pdata *pdata = wm8904->pdata;
694 int value = ucontrol->value.integer.value[0];
695
696 if (value >= pdata->num_drc_cfgs)
697 return -EINVAL;
698
699 wm8904->drc_cfg = value;
700
701 wm8904_set_drc(codec);
702
703 return 0;
704}
705
706static int wm8904_get_drc_enum(struct snd_kcontrol *kcontrol,
707 struct snd_ctl_elem_value *ucontrol)
708{
709 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
710 struct wm8904_priv *wm8904 = codec->private_data;
711
712 ucontrol->value.enumerated.item[0] = wm8904->drc_cfg;
713
714 return 0;
715}
716
717static void wm8904_set_retune_mobile(struct snd_soc_codec *codec)
718{
719 struct wm8904_priv *wm8904 = codec->private_data;
720 struct wm8904_pdata *pdata = wm8904->pdata;
721 int best, best_val, save, i, cfg;
722
723 if (!pdata || !wm8904->num_retune_mobile_texts)
724 return;
725
726 /* Find the version of the currently selected configuration
727 * with the nearest sample rate. */
728 cfg = wm8904->retune_mobile_cfg;
729 best = 0;
730 best_val = INT_MAX;
731 for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) {
732 if (strcmp(pdata->retune_mobile_cfgs[i].name,
733 wm8904->retune_mobile_texts[cfg]) == 0 &&
734 abs(pdata->retune_mobile_cfgs[i].rate
735 - wm8904->fs) < best_val) {
736 best = i;
737 best_val = abs(pdata->retune_mobile_cfgs[i].rate
738 - wm8904->fs);
739 }
740 }
741
742 dev_dbg(codec->dev, "ReTune Mobile %s/%dHz for %dHz sample rate\n",
743 pdata->retune_mobile_cfgs[best].name,
744 pdata->retune_mobile_cfgs[best].rate,
745 wm8904->fs);
746
747 /* The EQ will be disabled while reconfiguring it, remember the
748 * current configuration.
749 */
750 save = snd_soc_read(codec, WM8904_EQ1);
751
752 for (i = 0; i < WM8904_EQ_REGS; i++)
753 snd_soc_update_bits(codec, WM8904_EQ1 + i, 0xffff,
754 pdata->retune_mobile_cfgs[best].regs[i]);
755
756 snd_soc_update_bits(codec, WM8904_EQ1, WM8904_EQ_ENA, save);
757}
758
759static int wm8904_put_retune_mobile_enum(struct snd_kcontrol *kcontrol,
760 struct snd_ctl_elem_value *ucontrol)
761{
762 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
763 struct wm8904_priv *wm8904 = codec->private_data;
764 struct wm8904_pdata *pdata = wm8904->pdata;
765 int value = ucontrol->value.integer.value[0];
766
767 if (value >= pdata->num_retune_mobile_cfgs)
768 return -EINVAL;
769
770 wm8904->retune_mobile_cfg = value;
771
772 wm8904_set_retune_mobile(codec);
773
774 return 0;
775}
776
777static int wm8904_get_retune_mobile_enum(struct snd_kcontrol *kcontrol,
778 struct snd_ctl_elem_value *ucontrol)
779{
780 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
781 struct wm8904_priv *wm8904 = codec->private_data;
782
783 ucontrol->value.enumerated.item[0] = wm8904->retune_mobile_cfg;
784
785 return 0;
786}
787
788static int deemph_settings[] = { 0, 32000, 44100, 48000 };
789
790static int wm8904_set_deemph(struct snd_soc_codec *codec)
791{
792 struct wm8904_priv *wm8904 = codec->private_data;
793 int val, i, best;
794
795 /* If we're using deemphasis select the nearest available sample
796 * rate.
797 */
798 if (wm8904->deemph) {
799 best = 1;
800 for (i = 2; i < ARRAY_SIZE(deemph_settings); i++) {
801 if (abs(deemph_settings[i] - wm8904->fs) <
802 abs(deemph_settings[best] - wm8904->fs))
803 best = i;
804 }
805
806 val = best << WM8904_DEEMPH_SHIFT;
807 } else {
808 val = 0;
809 }
810
811 dev_dbg(codec->dev, "Set deemphasis %d\n", val);
812
813 return snd_soc_update_bits(codec, WM8904_DAC_DIGITAL_1,
814 WM8904_DEEMPH_MASK, val);
815}
816
817static int wm8904_get_deemph(struct snd_kcontrol *kcontrol,
818 struct snd_ctl_elem_value *ucontrol)
819{
820 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
821 struct wm8904_priv *wm8904 = codec->private_data;
822
823 return wm8904->deemph;
824}
825
826static int wm8904_put_deemph(struct snd_kcontrol *kcontrol,
827 struct snd_ctl_elem_value *ucontrol)
828{
829 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
830 struct wm8904_priv *wm8904 = codec->private_data;
831 int deemph = ucontrol->value.enumerated.item[0];
832
833 if (deemph > 1)
834 return -EINVAL;
835
836 wm8904->deemph = deemph;
837
838 return wm8904_set_deemph(codec);
839}
840
841static const DECLARE_TLV_DB_SCALE(dac_boost_tlv, 0, 600, 0);
842static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
843static const DECLARE_TLV_DB_SCALE(out_tlv, -5700, 100, 0);
844static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -3600, 300, 0);
845static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
846
847static const char *input_mode_text[] = {
848 "Single-Ended", "Differential Line", "Differential Mic"
849};
850
851static const struct soc_enum lin_mode =
852 SOC_ENUM_SINGLE(WM8904_ANALOGUE_LEFT_INPUT_1, 0, 3, input_mode_text);
853
854static const struct soc_enum rin_mode =
855 SOC_ENUM_SINGLE(WM8904_ANALOGUE_RIGHT_INPUT_1, 0, 3, input_mode_text);
856
857static const char *hpf_mode_text[] = {
858 "Hi-fi", "Voice 1", "Voice 2", "Voice 3"
859};
860
861static const struct soc_enum hpf_mode =
862 SOC_ENUM_SINGLE(WM8904_ADC_DIGITAL_0, 5, 4, hpf_mode_text);
863
864static const struct snd_kcontrol_new wm8904_adc_snd_controls[] = {
865SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8904_ADC_DIGITAL_VOLUME_LEFT,
866 WM8904_ADC_DIGITAL_VOLUME_RIGHT, 1, 119, 0, digital_tlv),
867
868SOC_ENUM("Left Caputure Mode", lin_mode),
869SOC_ENUM("Right Capture Mode", rin_mode),
870
871/* No TLV since it depends on mode */
872SOC_DOUBLE_R("Capture Volume", WM8904_ANALOGUE_LEFT_INPUT_0,
873 WM8904_ANALOGUE_RIGHT_INPUT_0, 0, 31, 0),
874SOC_DOUBLE_R("Capture Switch", WM8904_ANALOGUE_LEFT_INPUT_0,
875 WM8904_ANALOGUE_RIGHT_INPUT_0, 7, 1, 0),
876
877SOC_SINGLE("High Pass Filter Switch", WM8904_ADC_DIGITAL_0, 4, 1, 0),
878SOC_ENUM("High Pass Filter Mode", hpf_mode),
879
880SOC_SINGLE("ADC 128x OSR Switch", WM8904_ANALOGUE_ADC_0, 0, 1, 0),
881};
882
883static const char *drc_path_text[] = {
884 "ADC", "DAC"
885};
886
887static const struct soc_enum drc_path =
888 SOC_ENUM_SINGLE(WM8904_DRC_0, 14, 2, drc_path_text);
889
890static const struct snd_kcontrol_new wm8904_dac_snd_controls[] = {
891SOC_SINGLE_TLV("Digital Playback Boost Volume",
892 WM8904_AUDIO_INTERFACE_0, 9, 3, 0, dac_boost_tlv),
893SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8904_DAC_DIGITAL_VOLUME_LEFT,
894 WM8904_DAC_DIGITAL_VOLUME_RIGHT, 1, 96, 0, digital_tlv),
895
896SOC_DOUBLE_R_TLV("Headphone Volume", WM8904_ANALOGUE_OUT1_LEFT,
897 WM8904_ANALOGUE_OUT1_RIGHT, 0, 63, 0, out_tlv),
898SOC_DOUBLE_R("Headphone Switch", WM8904_ANALOGUE_OUT1_LEFT,
899 WM8904_ANALOGUE_OUT1_RIGHT, 8, 1, 1),
900SOC_DOUBLE_R("Headphone ZC Switch", WM8904_ANALOGUE_OUT1_LEFT,
901 WM8904_ANALOGUE_OUT1_RIGHT, 6, 1, 0),
902
903SOC_DOUBLE_R_TLV("Line Output Volume", WM8904_ANALOGUE_OUT2_LEFT,
904 WM8904_ANALOGUE_OUT2_RIGHT, 0, 63, 0, out_tlv),
905SOC_DOUBLE_R("Line Output Switch", WM8904_ANALOGUE_OUT2_LEFT,
906 WM8904_ANALOGUE_OUT2_RIGHT, 8, 1, 1),
907SOC_DOUBLE_R("Line Output ZC Switch", WM8904_ANALOGUE_OUT2_LEFT,
908 WM8904_ANALOGUE_OUT2_RIGHT, 6, 1, 0),
909
910SOC_SINGLE("EQ Switch", WM8904_EQ1, 0, 1, 0),
911SOC_SINGLE("DRC Switch", WM8904_DRC_0, 15, 1, 0),
912SOC_ENUM("DRC Path", drc_path),
913SOC_SINGLE("DAC OSRx2 Switch", WM8904_DAC_DIGITAL_1, 6, 1, 0),
914SOC_SINGLE_BOOL_EXT("DAC Deemphasis Switch", 0,
915 wm8904_get_deemph, wm8904_put_deemph),
916};
917
918static const struct snd_kcontrol_new wm8904_snd_controls[] = {
919SOC_DOUBLE_TLV("Digital Sidetone Volume", WM8904_DAC_DIGITAL_0, 4, 8, 15, 0,
920 sidetone_tlv),
921};
922
923static const struct snd_kcontrol_new wm8904_eq_controls[] = {
924SOC_SINGLE_TLV("EQ1 Volume", WM8904_EQ2, 0, 24, 0, eq_tlv),
925SOC_SINGLE_TLV("EQ2 Volume", WM8904_EQ3, 0, 24, 0, eq_tlv),
926SOC_SINGLE_TLV("EQ3 Volume", WM8904_EQ4, 0, 24, 0, eq_tlv),
927SOC_SINGLE_TLV("EQ4 Volume", WM8904_EQ5, 0, 24, 0, eq_tlv),
928SOC_SINGLE_TLV("EQ5 Volume", WM8904_EQ6, 0, 24, 0, eq_tlv),
929};
930
931static int cp_event(struct snd_soc_dapm_widget *w,
932 struct snd_kcontrol *kcontrol, int event)
933{
934 BUG_ON(event != SND_SOC_DAPM_POST_PMU);
935
936 /* Maximum startup time */
937 udelay(500);
938
939 return 0;
940}
941
942static int sysclk_event(struct snd_soc_dapm_widget *w,
943 struct snd_kcontrol *kcontrol, int event)
944{
945 struct snd_soc_codec *codec = w->codec;
946 struct wm8904_priv *wm8904 = codec->private_data;
947
948 switch (event) {
949 case SND_SOC_DAPM_PRE_PMU:
950 /* If we're using the FLL then we only start it when
951 * required; we assume that the configuration has been
952 * done previously and all we need to do is kick it
953 * off.
954 */
955 switch (wm8904->sysclk_src) {
956 case WM8904_CLK_FLL:
957 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
958 WM8904_FLL_OSC_ENA,
959 WM8904_FLL_OSC_ENA);
960
961 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
962 WM8904_FLL_ENA,
963 WM8904_FLL_ENA);
964 break;
965
966 default:
967 break;
968 }
969 break;
970
971 case SND_SOC_DAPM_POST_PMD:
972 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
973 WM8904_FLL_OSC_ENA | WM8904_FLL_ENA, 0);
974 break;
975 }
976
977 return 0;
978}
979
980static int out_pga_event(struct snd_soc_dapm_widget *w,
981 struct snd_kcontrol *kcontrol, int event)
982{
983 struct snd_soc_codec *codec = w->codec;
984 struct wm8904_priv *wm8904 = codec->private_data;
985 int reg, val;
986 int dcs_mask;
987 int dcs_l, dcs_r;
988 int dcs_l_reg, dcs_r_reg;
989 int timeout;
990 int pwr_reg;
991
992 /* This code is shared between HP and LINEOUT; we do all our
993 * power management in stereo pairs to avoid latency issues so
994 * we reuse shift to identify which rather than strcmp() the
995 * name. */
996 reg = w->shift;
997
998 switch (reg) {
999 case WM8904_ANALOGUE_HP_0:
1000 pwr_reg = WM8904_POWER_MANAGEMENT_2;
1001 dcs_mask = WM8904_DCS_ENA_CHAN_0 | WM8904_DCS_ENA_CHAN_1;
1002 dcs_r_reg = WM8904_DC_SERVO_8;
1003 dcs_l_reg = WM8904_DC_SERVO_9;
1004 dcs_l = 0;
1005 dcs_r = 1;
1006 break;
1007 case WM8904_ANALOGUE_LINEOUT_0:
1008 pwr_reg = WM8904_POWER_MANAGEMENT_3;
1009 dcs_mask = WM8904_DCS_ENA_CHAN_2 | WM8904_DCS_ENA_CHAN_3;
1010 dcs_r_reg = WM8904_DC_SERVO_6;
1011 dcs_l_reg = WM8904_DC_SERVO_7;
1012 dcs_l = 2;
1013 dcs_r = 3;
1014 break;
1015 default:
1016 BUG();
1017 return -EINVAL;
1018 }
1019
1020 switch (event) {
1021 case SND_SOC_DAPM_PRE_PMU:
1022 /* Power on the PGAs */
1023 snd_soc_update_bits(codec, pwr_reg,
1024 WM8904_HPL_PGA_ENA | WM8904_HPR_PGA_ENA,
1025 WM8904_HPL_PGA_ENA | WM8904_HPR_PGA_ENA);
1026
1027 /* Power on the amplifier */
1028 snd_soc_update_bits(codec, reg,
1029 WM8904_HPL_ENA | WM8904_HPR_ENA,
1030 WM8904_HPL_ENA | WM8904_HPR_ENA);
1031
1032
1033 /* Enable the first stage */
1034 snd_soc_update_bits(codec, reg,
1035 WM8904_HPL_ENA_DLY | WM8904_HPR_ENA_DLY,
1036 WM8904_HPL_ENA_DLY | WM8904_HPR_ENA_DLY);
1037
1038 /* Power up the DC servo */
1039 snd_soc_update_bits(codec, WM8904_DC_SERVO_0,
1040 dcs_mask, dcs_mask);
1041
1042 /* Either calibrate the DC servo or restore cached state
1043 * if we have that.
1044 */
1045 if (wm8904->dcs_state[dcs_l] || wm8904->dcs_state[dcs_r]) {
1046 dev_dbg(codec->dev, "Restoring DC servo state\n");
1047
1048 snd_soc_write(codec, dcs_l_reg,
1049 wm8904->dcs_state[dcs_l]);
1050 snd_soc_write(codec, dcs_r_reg,
1051 wm8904->dcs_state[dcs_r]);
1052
1053 snd_soc_write(codec, WM8904_DC_SERVO_1, dcs_mask);
1054
1055 timeout = 20;
1056 } else {
1057 dev_dbg(codec->dev, "Calibrating DC servo\n");
1058
1059 snd_soc_write(codec, WM8904_DC_SERVO_1,
1060 dcs_mask << WM8904_DCS_TRIG_STARTUP_0_SHIFT);
1061
1062 timeout = 500;
1063 }
1064
1065 /* Wait for DC servo to complete */
1066 dcs_mask <<= WM8904_DCS_CAL_COMPLETE_SHIFT;
1067 do {
1068 val = snd_soc_read(codec, WM8904_DC_SERVO_READBACK_0);
1069 if ((val & dcs_mask) == dcs_mask)
1070 break;
1071
1072 msleep(1);
1073 } while (--timeout);
1074
1075 if ((val & dcs_mask) != dcs_mask)
1076 dev_warn(codec->dev, "DC servo timed out\n");
1077 else
1078 dev_dbg(codec->dev, "DC servo ready\n");
1079
1080 /* Enable the output stage */
1081 snd_soc_update_bits(codec, reg,
1082 WM8904_HPL_ENA_OUTP | WM8904_HPR_ENA_OUTP,
1083 WM8904_HPL_ENA_OUTP | WM8904_HPR_ENA_OUTP);
1084 break;
1085
1086 case SND_SOC_DAPM_POST_PMU:
1087 /* Unshort the output itself */
1088 snd_soc_update_bits(codec, reg,
1089 WM8904_HPL_RMV_SHORT |
1090 WM8904_HPR_RMV_SHORT,
1091 WM8904_HPL_RMV_SHORT |
1092 WM8904_HPR_RMV_SHORT);
1093
1094 break;
1095
1096 case SND_SOC_DAPM_PRE_PMD:
1097 /* Short the output */
1098 snd_soc_update_bits(codec, reg,
1099 WM8904_HPL_RMV_SHORT |
1100 WM8904_HPR_RMV_SHORT, 0);
1101 break;
1102
1103 case SND_SOC_DAPM_POST_PMD:
1104 /* Cache the DC servo configuration; this will be
1105 * invalidated if we change the configuration. */
1106 wm8904->dcs_state[dcs_l] = snd_soc_read(codec, dcs_l_reg);
1107 wm8904->dcs_state[dcs_r] = snd_soc_read(codec, dcs_r_reg);
1108
1109 snd_soc_update_bits(codec, WM8904_DC_SERVO_0,
1110 dcs_mask, 0);
1111
1112 /* Disable the amplifier input and output stages */
1113 snd_soc_update_bits(codec, reg,
1114 WM8904_HPL_ENA | WM8904_HPR_ENA |
1115 WM8904_HPL_ENA_DLY | WM8904_HPR_ENA_DLY |
1116 WM8904_HPL_ENA_OUTP | WM8904_HPR_ENA_OUTP,
1117 0);
1118
1119 /* PGAs too */
1120 snd_soc_update_bits(codec, pwr_reg,
1121 WM8904_HPL_PGA_ENA | WM8904_HPR_PGA_ENA,
1122 0);
1123 break;
1124 }
1125
1126 return 0;
1127}
1128
1129static const char *lin_text[] = {
1130 "IN1L", "IN2L", "IN3L"
1131};
1132
1133static const struct soc_enum lin_enum =
1134 SOC_ENUM_SINGLE(WM8904_ANALOGUE_LEFT_INPUT_1, 2, 3, lin_text);
1135
1136static const struct snd_kcontrol_new lin_mux =
1137 SOC_DAPM_ENUM("Left Capture Mux", lin_enum);
1138
1139static const struct soc_enum lin_inv_enum =
1140 SOC_ENUM_SINGLE(WM8904_ANALOGUE_LEFT_INPUT_1, 4, 3, lin_text);
1141
1142static const struct snd_kcontrol_new lin_inv_mux =
1143 SOC_DAPM_ENUM("Left Capture Inveting Mux", lin_inv_enum);
1144
1145static const char *rin_text[] = {
1146 "IN1R", "IN2R", "IN3R"
1147};
1148
1149static const struct soc_enum rin_enum =
1150 SOC_ENUM_SINGLE(WM8904_ANALOGUE_RIGHT_INPUT_1, 2, 3, rin_text);
1151
1152static const struct snd_kcontrol_new rin_mux =
1153 SOC_DAPM_ENUM("Right Capture Mux", rin_enum);
1154
1155static const struct soc_enum rin_inv_enum =
1156 SOC_ENUM_SINGLE(WM8904_ANALOGUE_RIGHT_INPUT_1, 4, 3, rin_text);
1157
1158static const struct snd_kcontrol_new rin_inv_mux =
1159 SOC_DAPM_ENUM("Right Capture Inveting Mux", rin_inv_enum);
1160
1161static const char *aif_text[] = {
1162 "Left", "Right"
1163};
1164
1165static const struct soc_enum aifoutl_enum =
1166 SOC_ENUM_SINGLE(WM8904_AUDIO_INTERFACE_0, 7, 2, aif_text);
1167
1168static const struct snd_kcontrol_new aifoutl_mux =
1169 SOC_DAPM_ENUM("AIFOUTL Mux", aifoutl_enum);
1170
1171static const struct soc_enum aifoutr_enum =
1172 SOC_ENUM_SINGLE(WM8904_AUDIO_INTERFACE_0, 6, 2, aif_text);
1173
1174static const struct snd_kcontrol_new aifoutr_mux =
1175 SOC_DAPM_ENUM("AIFOUTR Mux", aifoutr_enum);
1176
1177static const struct soc_enum aifinl_enum =
1178 SOC_ENUM_SINGLE(WM8904_AUDIO_INTERFACE_0, 5, 2, aif_text);
1179
1180static const struct snd_kcontrol_new aifinl_mux =
1181 SOC_DAPM_ENUM("AIFINL Mux", aifinl_enum);
1182
1183static const struct soc_enum aifinr_enum =
1184 SOC_ENUM_SINGLE(WM8904_AUDIO_INTERFACE_0, 4, 2, aif_text);
1185
1186static const struct snd_kcontrol_new aifinr_mux =
1187 SOC_DAPM_ENUM("AIFINR Mux", aifinr_enum);
1188
1189static const struct snd_soc_dapm_widget wm8904_core_dapm_widgets[] = {
1190SND_SOC_DAPM_SUPPLY("SYSCLK", WM8904_CLOCK_RATES_2, 2, 0, sysclk_event,
1191 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1192SND_SOC_DAPM_SUPPLY("CLK_DSP", WM8904_CLOCK_RATES_2, 1, 0, NULL, 0),
1193SND_SOC_DAPM_SUPPLY("TOCLK", WM8904_CLOCK_RATES_2, 0, 0, NULL, 0),
1194};
1195
1196static const struct snd_soc_dapm_widget wm8904_adc_dapm_widgets[] = {
1197SND_SOC_DAPM_INPUT("IN1L"),
1198SND_SOC_DAPM_INPUT("IN1R"),
1199SND_SOC_DAPM_INPUT("IN2L"),
1200SND_SOC_DAPM_INPUT("IN2R"),
1201SND_SOC_DAPM_INPUT("IN3L"),
1202SND_SOC_DAPM_INPUT("IN3R"),
1203
1204SND_SOC_DAPM_MICBIAS("MICBIAS", WM8904_MIC_BIAS_CONTROL_0, 0, 0),
1205
1206SND_SOC_DAPM_MUX("Left Capture Mux", SND_SOC_NOPM, 0, 0, &lin_mux),
1207SND_SOC_DAPM_MUX("Left Capture Inverting Mux", SND_SOC_NOPM, 0, 0,
1208 &lin_inv_mux),
1209SND_SOC_DAPM_MUX("Right Capture Mux", SND_SOC_NOPM, 0, 0, &rin_mux),
1210SND_SOC_DAPM_MUX("Right Capture Inverting Mux", SND_SOC_NOPM, 0, 0,
1211 &rin_inv_mux),
1212
1213SND_SOC_DAPM_PGA("Left Capture PGA", WM8904_POWER_MANAGEMENT_0, 1, 0,
1214 NULL, 0),
1215SND_SOC_DAPM_PGA("Right Capture PGA", WM8904_POWER_MANAGEMENT_0, 0, 0,
1216 NULL, 0),
1217
1218SND_SOC_DAPM_ADC("ADCL", NULL, WM8904_POWER_MANAGEMENT_6, 1, 0),
1219SND_SOC_DAPM_ADC("ADCR", NULL, WM8904_POWER_MANAGEMENT_6, 0, 0),
1220
1221SND_SOC_DAPM_MUX("AIFOUTL Mux", SND_SOC_NOPM, 0, 0, &aifoutl_mux),
1222SND_SOC_DAPM_MUX("AIFOUTR Mux", SND_SOC_NOPM, 0, 0, &aifoutr_mux),
1223
1224SND_SOC_DAPM_AIF_OUT("AIFOUTL", "Capture", 0, SND_SOC_NOPM, 0, 0),
1225SND_SOC_DAPM_AIF_OUT("AIFOUTR", "Capture", 1, SND_SOC_NOPM, 0, 0),
1226};
1227
1228static const struct snd_soc_dapm_widget wm8904_dac_dapm_widgets[] = {
1229SND_SOC_DAPM_AIF_IN("AIFINL", "Playback", 0, SND_SOC_NOPM, 0, 0),
1230SND_SOC_DAPM_AIF_IN("AIFINR", "Playback", 1, SND_SOC_NOPM, 0, 0),
1231
1232SND_SOC_DAPM_MUX("DACL Mux", SND_SOC_NOPM, 0, 0, &aifinl_mux),
1233SND_SOC_DAPM_MUX("DACR Mux", SND_SOC_NOPM, 0, 0, &aifinr_mux),
1234
1235SND_SOC_DAPM_DAC("DACL", NULL, WM8904_POWER_MANAGEMENT_6, 3, 0),
1236SND_SOC_DAPM_DAC("DACR", NULL, WM8904_POWER_MANAGEMENT_6, 2, 0),
1237
1238SND_SOC_DAPM_SUPPLY("Charge pump", WM8904_CHARGE_PUMP_0, 0, 0, cp_event,
1239 SND_SOC_DAPM_POST_PMU),
1240
1241SND_SOC_DAPM_PGA("HPL PGA", SND_SOC_NOPM, 1, 0, NULL, 0),
1242SND_SOC_DAPM_PGA("HPR PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
1243
1244SND_SOC_DAPM_PGA("LINEL PGA", SND_SOC_NOPM, 1, 0, NULL, 0),
1245SND_SOC_DAPM_PGA("LINER PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
1246
1247SND_SOC_DAPM_PGA_E("Headphone Output", SND_SOC_NOPM, WM8904_ANALOGUE_HP_0,
1248 0, NULL, 0, out_pga_event,
1249 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1250 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
1251SND_SOC_DAPM_PGA_E("Line Output", SND_SOC_NOPM, WM8904_ANALOGUE_LINEOUT_0,
1252 0, NULL, 0, out_pga_event,
1253 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1254 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
1255
1256SND_SOC_DAPM_OUTPUT("HPOUTL"),
1257SND_SOC_DAPM_OUTPUT("HPOUTR"),
1258SND_SOC_DAPM_OUTPUT("LINEOUTL"),
1259SND_SOC_DAPM_OUTPUT("LINEOUTR"),
1260};
1261
1262static const char *out_mux_text[] = {
1263 "DAC", "Bypass"
1264};
1265
1266static const struct soc_enum hpl_enum =
1267 SOC_ENUM_SINGLE(WM8904_ANALOGUE_OUT12_ZC, 3, 2, out_mux_text);
1268
1269static const struct snd_kcontrol_new hpl_mux =
1270 SOC_DAPM_ENUM("HPL Mux", hpl_enum);
1271
1272static const struct soc_enum hpr_enum =
1273 SOC_ENUM_SINGLE(WM8904_ANALOGUE_OUT12_ZC, 2, 2, out_mux_text);
1274
1275static const struct snd_kcontrol_new hpr_mux =
1276 SOC_DAPM_ENUM("HPR Mux", hpr_enum);
1277
1278static const struct soc_enum linel_enum =
1279 SOC_ENUM_SINGLE(WM8904_ANALOGUE_OUT12_ZC, 1, 2, out_mux_text);
1280
1281static const struct snd_kcontrol_new linel_mux =
1282 SOC_DAPM_ENUM("LINEL Mux", linel_enum);
1283
1284static const struct soc_enum liner_enum =
1285 SOC_ENUM_SINGLE(WM8904_ANALOGUE_OUT12_ZC, 0, 2, out_mux_text);
1286
1287static const struct snd_kcontrol_new liner_mux =
1288 SOC_DAPM_ENUM("LINEL Mux", liner_enum);
1289
1290static const char *sidetone_text[] = {
1291 "None", "Left", "Right"
1292};
1293
1294static const struct soc_enum dacl_sidetone_enum =
1295 SOC_ENUM_SINGLE(WM8904_DAC_DIGITAL_0, 2, 3, sidetone_text);
1296
1297static const struct snd_kcontrol_new dacl_sidetone_mux =
1298 SOC_DAPM_ENUM("Left Sidetone Mux", dacl_sidetone_enum);
1299
1300static const struct soc_enum dacr_sidetone_enum =
1301 SOC_ENUM_SINGLE(WM8904_DAC_DIGITAL_0, 0, 3, sidetone_text);
1302
1303static const struct snd_kcontrol_new dacr_sidetone_mux =
1304 SOC_DAPM_ENUM("Right Sidetone Mux", dacr_sidetone_enum);
1305
1306static const struct snd_soc_dapm_widget wm8904_dapm_widgets[] = {
1307SND_SOC_DAPM_SUPPLY("Class G", WM8904_CLASS_W_0, 0, 1, NULL, 0),
1308SND_SOC_DAPM_PGA("Left Bypass", SND_SOC_NOPM, 0, 0, NULL, 0),
1309SND_SOC_DAPM_PGA("Right Bypass", SND_SOC_NOPM, 0, 0, NULL, 0),
1310
1311SND_SOC_DAPM_MUX("Left Sidetone", SND_SOC_NOPM, 0, 0, &dacl_sidetone_mux),
1312SND_SOC_DAPM_MUX("Right Sidetone", SND_SOC_NOPM, 0, 0, &dacr_sidetone_mux),
1313
1314SND_SOC_DAPM_MUX("HPL Mux", SND_SOC_NOPM, 0, 0, &hpl_mux),
1315SND_SOC_DAPM_MUX("HPR Mux", SND_SOC_NOPM, 0, 0, &hpr_mux),
1316SND_SOC_DAPM_MUX("LINEL Mux", SND_SOC_NOPM, 0, 0, &linel_mux),
1317SND_SOC_DAPM_MUX("LINER Mux", SND_SOC_NOPM, 0, 0, &liner_mux),
1318};
1319
1320static const struct snd_soc_dapm_route core_intercon[] = {
1321 { "CLK_DSP", NULL, "SYSCLK" },
1322 { "TOCLK", NULL, "SYSCLK" },
1323};
1324
1325static const struct snd_soc_dapm_route adc_intercon[] = {
1326 { "Left Capture Mux", "IN1L", "IN1L" },
1327 { "Left Capture Mux", "IN2L", "IN2L" },
1328 { "Left Capture Mux", "IN3L", "IN3L" },
1329
1330 { "Left Capture Inverting Mux", "IN1L", "IN1L" },
1331 { "Left Capture Inverting Mux", "IN2L", "IN2L" },
1332 { "Left Capture Inverting Mux", "IN3L", "IN3L" },
1333
1334 { "Right Capture Mux", "IN1R", "IN1R" },
1335 { "Right Capture Mux", "IN2R", "IN2R" },
1336 { "Right Capture Mux", "IN3R", "IN3R" },
1337
1338 { "Right Capture Inverting Mux", "IN1R", "IN1R" },
1339 { "Right Capture Inverting Mux", "IN2R", "IN2R" },
1340 { "Right Capture Inverting Mux", "IN3R", "IN3R" },
1341
1342 { "Left Capture PGA", NULL, "Left Capture Mux" },
1343 { "Left Capture PGA", NULL, "Left Capture Inverting Mux" },
1344
1345 { "Right Capture PGA", NULL, "Right Capture Mux" },
1346 { "Right Capture PGA", NULL, "Right Capture Inverting Mux" },
1347
1348 { "AIFOUTL", "Left", "ADCL" },
1349 { "AIFOUTL", "Right", "ADCR" },
1350 { "AIFOUTR", "Left", "ADCL" },
1351 { "AIFOUTR", "Right", "ADCR" },
1352
1353 { "ADCL", NULL, "CLK_DSP" },
1354 { "ADCL", NULL, "Left Capture PGA" },
1355
1356 { "ADCR", NULL, "CLK_DSP" },
1357 { "ADCR", NULL, "Right Capture PGA" },
1358};
1359
1360static const struct snd_soc_dapm_route dac_intercon[] = {
1361 { "DACL", "Right", "AIFINR" },
1362 { "DACL", "Left", "AIFINL" },
1363 { "DACL", NULL, "CLK_DSP" },
1364
1365 { "DACR", "Right", "AIFINR" },
1366 { "DACR", "Left", "AIFINL" },
1367 { "DACR", NULL, "CLK_DSP" },
1368
1369 { "Charge pump", NULL, "SYSCLK" },
1370
1371 { "Headphone Output", NULL, "HPL PGA" },
1372 { "Headphone Output", NULL, "HPR PGA" },
1373 { "Headphone Output", NULL, "Charge pump" },
1374 { "Headphone Output", NULL, "TOCLK" },
1375
1376 { "Line Output", NULL, "LINEL PGA" },
1377 { "Line Output", NULL, "LINER PGA" },
1378 { "Line Output", NULL, "Charge pump" },
1379 { "Line Output", NULL, "TOCLK" },
1380
1381 { "HPOUTL", NULL, "Headphone Output" },
1382 { "HPOUTR", NULL, "Headphone Output" },
1383
1384 { "LINEOUTL", NULL, "Line Output" },
1385 { "LINEOUTR", NULL, "Line Output" },
1386};
1387
1388static const struct snd_soc_dapm_route wm8904_intercon[] = {
1389 { "Left Sidetone", "Left", "ADCL" },
1390 { "Left Sidetone", "Right", "ADCR" },
1391 { "DACL", NULL, "Left Sidetone" },
1392
1393 { "Right Sidetone", "Left", "ADCL" },
1394 { "Right Sidetone", "Right", "ADCR" },
1395 { "DACR", NULL, "Right Sidetone" },
1396
1397 { "Left Bypass", NULL, "Class G" },
1398 { "Left Bypass", NULL, "Left Capture PGA" },
1399
1400 { "Right Bypass", NULL, "Class G" },
1401 { "Right Bypass", NULL, "Right Capture PGA" },
1402
1403 { "HPL Mux", "DAC", "DACL" },
1404 { "HPL Mux", "Bypass", "Left Bypass" },
1405
1406 { "HPR Mux", "DAC", "DACR" },
1407 { "HPR Mux", "Bypass", "Right Bypass" },
1408
1409 { "LINEL Mux", "DAC", "DACL" },
1410 { "LINEL Mux", "Bypass", "Left Bypass" },
1411
1412 { "LINER Mux", "DAC", "DACR" },
1413 { "LINER Mux", "Bypass", "Right Bypass" },
1414
1415 { "HPL PGA", NULL, "HPL Mux" },
1416 { "HPR PGA", NULL, "HPR Mux" },
1417
1418 { "LINEL PGA", NULL, "LINEL Mux" },
1419 { "LINER PGA", NULL, "LINER Mux" },
1420};
1421
1422static const struct snd_soc_dapm_route wm8912_intercon[] = {
1423 { "HPL PGA", NULL, "DACL" },
1424 { "HPR PGA", NULL, "DACR" },
1425
1426 { "LINEL PGA", NULL, "DACL" },
1427 { "LINER PGA", NULL, "DACR" },
1428};
1429
1430static int wm8904_add_widgets(struct snd_soc_codec *codec)
1431{
1432 struct wm8904_priv *wm8904 = codec->private_data;
1433
1434 snd_soc_dapm_new_controls(codec, wm8904_core_dapm_widgets,
1435 ARRAY_SIZE(wm8904_core_dapm_widgets));
1436 snd_soc_dapm_add_routes(codec, core_intercon,
1437 ARRAY_SIZE(core_intercon));
1438
1439 switch (wm8904->devtype) {
1440 case WM8904:
1441 snd_soc_add_controls(codec, wm8904_adc_snd_controls,
1442 ARRAY_SIZE(wm8904_adc_snd_controls));
1443 snd_soc_add_controls(codec, wm8904_dac_snd_controls,
1444 ARRAY_SIZE(wm8904_dac_snd_controls));
1445 snd_soc_add_controls(codec, wm8904_snd_controls,
1446 ARRAY_SIZE(wm8904_snd_controls));
1447
1448 snd_soc_dapm_new_controls(codec, wm8904_adc_dapm_widgets,
1449 ARRAY_SIZE(wm8904_adc_dapm_widgets));
1450 snd_soc_dapm_new_controls(codec, wm8904_dac_dapm_widgets,
1451 ARRAY_SIZE(wm8904_dac_dapm_widgets));
1452 snd_soc_dapm_new_controls(codec, wm8904_dapm_widgets,
1453 ARRAY_SIZE(wm8904_dapm_widgets));
1454
1455 snd_soc_dapm_add_routes(codec, core_intercon,
1456 ARRAY_SIZE(core_intercon));
1457 snd_soc_dapm_add_routes(codec, adc_intercon,
1458 ARRAY_SIZE(adc_intercon));
1459 snd_soc_dapm_add_routes(codec, dac_intercon,
1460 ARRAY_SIZE(dac_intercon));
1461 snd_soc_dapm_add_routes(codec, wm8904_intercon,
1462 ARRAY_SIZE(wm8904_intercon));
1463 break;
1464
1465 case WM8912:
1466 snd_soc_add_controls(codec, wm8904_dac_snd_controls,
1467 ARRAY_SIZE(wm8904_dac_snd_controls));
1468
1469 snd_soc_dapm_new_controls(codec, wm8904_dac_dapm_widgets,
1470 ARRAY_SIZE(wm8904_dac_dapm_widgets));
1471
1472 snd_soc_dapm_add_routes(codec, dac_intercon,
1473 ARRAY_SIZE(dac_intercon));
1474 snd_soc_dapm_add_routes(codec, wm8912_intercon,
1475 ARRAY_SIZE(wm8912_intercon));
1476 break;
1477 }
1478
1479 snd_soc_dapm_new_widgets(codec);
1480 return 0;
1481}
1482
1483static struct {
1484 int ratio;
1485 unsigned int clk_sys_rate;
1486} clk_sys_rates[] = {
1487 { 64, 0 },
1488 { 128, 1 },
1489 { 192, 2 },
1490 { 256, 3 },
1491 { 384, 4 },
1492 { 512, 5 },
1493 { 786, 6 },
1494 { 1024, 7 },
1495 { 1408, 8 },
1496 { 1536, 9 },
1497};
1498
1499static struct {
1500 int rate;
1501 int sample_rate;
1502} sample_rates[] = {
1503 { 8000, 0 },
1504 { 11025, 1 },
1505 { 12000, 1 },
1506 { 16000, 2 },
1507 { 22050, 3 },
1508 { 24000, 3 },
1509 { 32000, 4 },
1510 { 44100, 5 },
1511 { 48000, 5 },
1512};
1513
1514static struct {
1515 int div; /* *10 due to .5s */
1516 int bclk_div;
1517} bclk_divs[] = {
1518 { 10, 0 },
1519 { 15, 1 },
1520 { 20, 2 },
1521 { 30, 3 },
1522 { 40, 4 },
1523 { 50, 5 },
1524 { 55, 6 },
1525 { 60, 7 },
1526 { 80, 8 },
1527 { 100, 9 },
1528 { 110, 10 },
1529 { 120, 11 },
1530 { 160, 12 },
1531 { 200, 13 },
1532 { 220, 14 },
1533 { 240, 16 },
1534 { 200, 17 },
1535 { 320, 18 },
1536 { 440, 19 },
1537 { 480, 20 },
1538};
1539
1540
1541static int wm8904_hw_params(struct snd_pcm_substream *substream,
1542 struct snd_pcm_hw_params *params,
1543 struct snd_soc_dai *dai)
1544{
1545 struct snd_soc_codec *codec = dai->codec;
1546 struct wm8904_priv *wm8904 = codec->private_data;
1547 int ret, i, best, best_val, cur_val;
1548 unsigned int aif1 = 0;
1549 unsigned int aif2 = 0;
1550 unsigned int aif3 = 0;
1551 unsigned int clock1 = 0;
1552 unsigned int dac_digital1 = 0;
1553
1554 /* What BCLK do we need? */
1555 wm8904->fs = params_rate(params);
1556 if (wm8904->tdm_slots) {
1557 dev_dbg(codec->dev, "Configuring for %d %d bit TDM slots\n",
1558 wm8904->tdm_slots, wm8904->tdm_width);
1559 wm8904->bclk = snd_soc_calc_bclk(wm8904->fs,
1560 wm8904->tdm_width, 2,
1561 wm8904->tdm_slots);
1562 } else {
1563 wm8904->bclk = snd_soc_params_to_bclk(params);
1564 }
1565
1566 switch (params_format(params)) {
1567 case SNDRV_PCM_FORMAT_S16_LE:
1568 break;
1569 case SNDRV_PCM_FORMAT_S20_3LE:
1570 aif1 |= 0x40;
1571 break;
1572 case SNDRV_PCM_FORMAT_S24_LE:
1573 aif1 |= 0x80;
1574 break;
1575 case SNDRV_PCM_FORMAT_S32_LE:
1576 aif1 |= 0xc0;
1577 break;
1578 default:
1579 return -EINVAL;
1580 }
1581
1582
1583 dev_dbg(codec->dev, "Target BCLK is %dHz\n", wm8904->bclk);
1584
1585 ret = wm8904_configure_clocking(codec);
1586 if (ret != 0)
1587 return ret;
1588
1589 /* Select nearest CLK_SYS_RATE */
1590 best = 0;
1591 best_val = abs((wm8904->sysclk_rate / clk_sys_rates[0].ratio)
1592 - wm8904->fs);
1593 for (i = 1; i < ARRAY_SIZE(clk_sys_rates); i++) {
1594 cur_val = abs((wm8904->sysclk_rate /
1595 clk_sys_rates[i].ratio) - wm8904->fs);;
1596 if (cur_val < best_val) {
1597 best = i;
1598 best_val = cur_val;
1599 }
1600 }
1601 dev_dbg(codec->dev, "Selected CLK_SYS_RATIO of %d\n",
1602 clk_sys_rates[best].ratio);
1603 clock1 |= (clk_sys_rates[best].clk_sys_rate
1604 << WM8904_CLK_SYS_RATE_SHIFT);
1605
1606 /* SAMPLE_RATE */
1607 best = 0;
1608 best_val = abs(wm8904->fs - sample_rates[0].rate);
1609 for (i = 1; i < ARRAY_SIZE(sample_rates); i++) {
1610 /* Closest match */
1611 cur_val = abs(wm8904->fs - sample_rates[i].rate);
1612 if (cur_val < best_val) {
1613 best = i;
1614 best_val = cur_val;
1615 }
1616 }
1617 dev_dbg(codec->dev, "Selected SAMPLE_RATE of %dHz\n",
1618 sample_rates[best].rate);
1619 clock1 |= (sample_rates[best].sample_rate
1620 << WM8904_SAMPLE_RATE_SHIFT);
1621
1622 /* Enable sloping stopband filter for low sample rates */
1623 if (wm8904->fs <= 24000)
1624 dac_digital1 |= WM8904_DAC_SB_FILT;
1625
1626 /* BCLK_DIV */
1627 best = 0;
1628 best_val = INT_MAX;
1629 for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) {
1630 cur_val = ((wm8904->sysclk_rate * 10) / bclk_divs[i].div)
1631 - wm8904->bclk;
1632 if (cur_val < 0) /* Table is sorted */
1633 break;
1634 if (cur_val < best_val) {
1635 best = i;
1636 best_val = cur_val;
1637 }
1638 }
1639 wm8904->bclk = (wm8904->sysclk_rate * 10) / bclk_divs[best].div;
1640 dev_dbg(codec->dev, "Selected BCLK_DIV of %d for %dHz BCLK\n",
1641 bclk_divs[best].div, wm8904->bclk);
1642 aif2 |= bclk_divs[best].bclk_div;
1643
1644 /* LRCLK is a simple fraction of BCLK */
1645 dev_dbg(codec->dev, "LRCLK_RATE is %d\n", wm8904->bclk / wm8904->fs);
1646 aif3 |= wm8904->bclk / wm8904->fs;
1647
1648 /* Apply the settings */
1649 snd_soc_update_bits(codec, WM8904_DAC_DIGITAL_1,
1650 WM8904_DAC_SB_FILT, dac_digital1);
1651 snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_1,
1652 WM8904_AIF_WL_MASK, aif1);
1653 snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_2,
1654 WM8904_BCLK_DIV_MASK, aif2);
1655 snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_3,
1656 WM8904_LRCLK_RATE_MASK, aif3);
1657 snd_soc_update_bits(codec, WM8904_CLOCK_RATES_1,
1658 WM8904_SAMPLE_RATE_MASK |
1659 WM8904_CLK_SYS_RATE_MASK, clock1);
1660
1661 /* Update filters for the new settings */
1662 wm8904_set_retune_mobile(codec);
1663 wm8904_set_deemph(codec);
1664
1665 return 0;
1666}
1667
1668
1669static int wm8904_set_sysclk(struct snd_soc_dai *dai, int clk_id,
1670 unsigned int freq, int dir)
1671{
1672 struct snd_soc_codec *codec = dai->codec;
1673 struct wm8904_priv *priv = codec->private_data;
1674
1675 switch (clk_id) {
1676 case WM8904_CLK_MCLK:
1677 priv->sysclk_src = clk_id;
1678 priv->mclk_rate = freq;
1679 break;
1680
1681 case WM8904_CLK_FLL:
1682 priv->sysclk_src = clk_id;
1683 break;
1684
1685 default:
1686 return -EINVAL;
1687 }
1688
1689 dev_dbg(dai->dev, "Clock source is %d at %uHz\n", clk_id, freq);
1690
1691 wm8904_configure_clocking(codec);
1692
1693 return 0;
1694}
1695
1696static int wm8904_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1697{
1698 struct snd_soc_codec *codec = dai->codec;
1699 unsigned int aif1 = 0;
1700 unsigned int aif3 = 0;
1701
1702 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1703 case SND_SOC_DAIFMT_CBS_CFS:
1704 break;
1705 case SND_SOC_DAIFMT_CBS_CFM:
1706 aif3 |= WM8904_LRCLK_DIR;
1707 break;
1708 case SND_SOC_DAIFMT_CBM_CFS:
1709 aif1 |= WM8904_BCLK_DIR;
1710 break;
1711 case SND_SOC_DAIFMT_CBM_CFM:
1712 aif1 |= WM8904_BCLK_DIR;
1713 aif3 |= WM8904_LRCLK_DIR;
1714 break;
1715 default:
1716 return -EINVAL;
1717 }
1718
1719 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1720 case SND_SOC_DAIFMT_DSP_B:
1721 aif1 |= WM8904_AIF_LRCLK_INV;
1722 case SND_SOC_DAIFMT_DSP_A:
1723 aif1 |= 0x3;
1724 break;
1725 case SND_SOC_DAIFMT_I2S:
1726 aif1 |= 0x2;
1727 break;
1728 case SND_SOC_DAIFMT_RIGHT_J:
1729 break;
1730 case SND_SOC_DAIFMT_LEFT_J:
1731 aif1 |= 0x1;
1732 break;
1733 default:
1734 return -EINVAL;
1735 }
1736
1737 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1738 case SND_SOC_DAIFMT_DSP_A:
1739 case SND_SOC_DAIFMT_DSP_B:
1740 /* frame inversion not valid for DSP modes */
1741 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1742 case SND_SOC_DAIFMT_NB_NF:
1743 break;
1744 case SND_SOC_DAIFMT_IB_NF:
1745 aif1 |= WM8904_AIF_BCLK_INV;
1746 break;
1747 default:
1748 return -EINVAL;
1749 }
1750 break;
1751
1752 case SND_SOC_DAIFMT_I2S:
1753 case SND_SOC_DAIFMT_RIGHT_J:
1754 case SND_SOC_DAIFMT_LEFT_J:
1755 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1756 case SND_SOC_DAIFMT_NB_NF:
1757 break;
1758 case SND_SOC_DAIFMT_IB_IF:
1759 aif1 |= WM8904_AIF_BCLK_INV | WM8904_AIF_LRCLK_INV;
1760 break;
1761 case SND_SOC_DAIFMT_IB_NF:
1762 aif1 |= WM8904_AIF_BCLK_INV;
1763 break;
1764 case SND_SOC_DAIFMT_NB_IF:
1765 aif1 |= WM8904_AIF_LRCLK_INV;
1766 break;
1767 default:
1768 return -EINVAL;
1769 }
1770 break;
1771 default:
1772 return -EINVAL;
1773 }
1774
1775 snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_1,
1776 WM8904_AIF_BCLK_INV | WM8904_AIF_LRCLK_INV |
1777 WM8904_AIF_FMT_MASK | WM8904_BCLK_DIR, aif1);
1778 snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_3,
1779 WM8904_LRCLK_DIR, aif3);
1780
1781 return 0;
1782}
1783
1784
1785static int wm8904_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
1786 unsigned int rx_mask, int slots, int slot_width)
1787{
1788 struct snd_soc_codec *codec = dai->codec;
1789 struct wm8904_priv *wm8904 = codec->private_data;
1790 int aif1 = 0;
1791
1792 /* Don't need to validate anything if we're turning off TDM */
1793 if (slots == 0)
1794 goto out;
1795
1796 /* Note that we allow configurations we can't handle ourselves -
1797 * for example, we can generate clocks for slots 2 and up even if
1798 * we can't use those slots ourselves.
1799 */
1800 aif1 |= WM8904_AIFADC_TDM | WM8904_AIFDAC_TDM;
1801
1802 switch (rx_mask) {
1803 case 3:
1804 break;
1805 case 0xc:
1806 aif1 |= WM8904_AIFADC_TDM_CHAN;
1807 break;
1808 default:
1809 return -EINVAL;
1810 }
1811
1812
1813 switch (tx_mask) {
1814 case 3:
1815 break;
1816 case 0xc:
1817 aif1 |= WM8904_AIFDAC_TDM_CHAN;
1818 break;
1819 default:
1820 return -EINVAL;
1821 }
1822
1823out:
1824 wm8904->tdm_width = slot_width;
1825 wm8904->tdm_slots = slots / 2;
1826
1827 snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_1,
1828 WM8904_AIFADC_TDM | WM8904_AIFADC_TDM_CHAN |
1829 WM8904_AIFDAC_TDM | WM8904_AIFDAC_TDM_CHAN, aif1);
1830
1831 return 0;
1832}
1833
1834struct _fll_div {
1835 u16 fll_fratio;
1836 u16 fll_outdiv;
1837 u16 fll_clk_ref_div;
1838 u16 n;
1839 u16 k;
1840};
1841
1842/* The size in bits of the FLL divide multiplied by 10
1843 * to allow rounding later */
1844#define FIXED_FLL_SIZE ((1 << 16) * 10)
1845
1846static struct {
1847 unsigned int min;
1848 unsigned int max;
1849 u16 fll_fratio;
1850 int ratio;
1851} fll_fratios[] = {
1852 { 0, 64000, 4, 16 },
1853 { 64000, 128000, 3, 8 },
1854 { 128000, 256000, 2, 4 },
1855 { 256000, 1000000, 1, 2 },
1856 { 1000000, 13500000, 0, 1 },
1857};
1858
1859static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
1860 unsigned int Fout)
1861{
1862 u64 Kpart;
1863 unsigned int K, Ndiv, Nmod, target;
1864 unsigned int div;
1865 int i;
1866
1867 /* Fref must be <=13.5MHz */
1868 div = 1;
1869 fll_div->fll_clk_ref_div = 0;
1870 while ((Fref / div) > 13500000) {
1871 div *= 2;
1872 fll_div->fll_clk_ref_div++;
1873
1874 if (div > 8) {
1875 pr_err("Can't scale %dMHz input down to <=13.5MHz\n",
1876 Fref);
1877 return -EINVAL;
1878 }
1879 }
1880
1881 pr_debug("Fref=%u Fout=%u\n", Fref, Fout);
1882
1883 /* Apply the division for our remaining calculations */
1884 Fref /= div;
1885
1886 /* Fvco should be 90-100MHz; don't check the upper bound */
1887 div = 4;
1888 while (Fout * div < 90000000) {
1889 div++;
1890 if (div > 64) {
1891 pr_err("Unable to find FLL_OUTDIV for Fout=%uHz\n",
1892 Fout);
1893 return -EINVAL;
1894 }
1895 }
1896 target = Fout * div;
1897 fll_div->fll_outdiv = div - 1;
1898
1899 pr_debug("Fvco=%dHz\n", target);
1900
1901 /* Find an appropraite FLL_FRATIO and factor it out of the target */
1902 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
1903 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
1904 fll_div->fll_fratio = fll_fratios[i].fll_fratio;
1905 target /= fll_fratios[i].ratio;
1906 break;
1907 }
1908 }
1909 if (i == ARRAY_SIZE(fll_fratios)) {
1910 pr_err("Unable to find FLL_FRATIO for Fref=%uHz\n", Fref);
1911 return -EINVAL;
1912 }
1913
1914 /* Now, calculate N.K */
1915 Ndiv = target / Fref;
1916
1917 fll_div->n = Ndiv;
1918 Nmod = target % Fref;
1919 pr_debug("Nmod=%d\n", Nmod);
1920
1921 /* Calculate fractional part - scale up so we can round. */
1922 Kpart = FIXED_FLL_SIZE * (long long)Nmod;
1923
1924 do_div(Kpart, Fref);
1925
1926 K = Kpart & 0xFFFFFFFF;
1927
1928 if ((K % 10) >= 5)
1929 K += 5;
1930
1931 /* Move down to proper range now rounding is done */
1932 fll_div->k = K / 10;
1933
1934 pr_debug("N=%x K=%x FLL_FRATIO=%x FLL_OUTDIV=%x FLL_CLK_REF_DIV=%x\n",
1935 fll_div->n, fll_div->k,
1936 fll_div->fll_fratio, fll_div->fll_outdiv,
1937 fll_div->fll_clk_ref_div);
1938
1939 return 0;
1940}
1941
1942static int wm8904_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
1943 unsigned int Fref, unsigned int Fout)
1944{
1945 struct snd_soc_codec *codec = dai->codec;
1946 struct wm8904_priv *wm8904 = codec->private_data;
1947 struct _fll_div fll_div;
1948 int ret, val;
1949 int clock2, fll1;
1950
1951 /* Any change? */
1952 if (source == wm8904->fll_src && Fref == wm8904->fll_fref &&
1953 Fout == wm8904->fll_fout)
1954 return 0;
1955
1956 clock2 = snd_soc_read(codec, WM8904_CLOCK_RATES_2);
1957
1958 if (Fout == 0) {
1959 dev_dbg(codec->dev, "FLL disabled\n");
1960
1961 wm8904->fll_fref = 0;
1962 wm8904->fll_fout = 0;
1963
1964 /* Gate SYSCLK to avoid glitches */
1965 snd_soc_update_bits(codec, WM8904_CLOCK_RATES_2,
1966 WM8904_CLK_SYS_ENA, 0);
1967
1968 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
1969 WM8904_FLL_OSC_ENA | WM8904_FLL_ENA, 0);
1970
1971 goto out;
1972 }
1973
1974 /* Validate the FLL ID */
1975 switch (source) {
1976 case WM8904_FLL_MCLK:
1977 case WM8904_FLL_LRCLK:
1978 case WM8904_FLL_BCLK:
1979 ret = fll_factors(&fll_div, Fref, Fout);
1980 if (ret != 0)
1981 return ret;
1982 break;
1983
1984 case WM8904_FLL_FREE_RUNNING:
1985 dev_dbg(codec->dev, "Using free running FLL\n");
1986 /* Force 12MHz and output/4 for now */
1987 Fout = 12000000;
1988 Fref = 12000000;
1989
1990 memset(&fll_div, 0, sizeof(fll_div));
1991 fll_div.fll_outdiv = 3;
1992 break;
1993
1994 default:
1995 dev_err(codec->dev, "Unknown FLL ID %d\n", fll_id);
1996 return -EINVAL;
1997 }
1998
1999 /* Save current state then disable the FLL and SYSCLK to avoid
2000 * misclocking */
2001 fll1 = snd_soc_read(codec, WM8904_FLL_CONTROL_1);
2002 snd_soc_update_bits(codec, WM8904_CLOCK_RATES_2,
2003 WM8904_CLK_SYS_ENA, 0);
2004 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
2005 WM8904_FLL_OSC_ENA | WM8904_FLL_ENA, 0);
2006
2007 /* Unlock forced oscilator control to switch it on/off */
2008 snd_soc_update_bits(codec, WM8904_CONTROL_INTERFACE_TEST_1,
2009 WM8904_USER_KEY, WM8904_USER_KEY);
2010
2011 if (fll_id == WM8904_FLL_FREE_RUNNING) {
2012 val = WM8904_FLL_FRC_NCO;
2013 } else {
2014 val = 0;
2015 }
2016
2017 snd_soc_update_bits(codec, WM8904_FLL_NCO_TEST_1, WM8904_FLL_FRC_NCO,
2018 val);
2019 snd_soc_update_bits(codec, WM8904_CONTROL_INTERFACE_TEST_1,
2020 WM8904_USER_KEY, 0);
2021
2022 switch (fll_id) {
2023 case WM8904_FLL_MCLK:
2024 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_5,
2025 WM8904_FLL_CLK_REF_SRC_MASK, 0);
2026 break;
2027
2028 case WM8904_FLL_LRCLK:
2029 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_5,
2030 WM8904_FLL_CLK_REF_SRC_MASK, 1);
2031 break;
2032
2033 case WM8904_FLL_BCLK:
2034 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_5,
2035 WM8904_FLL_CLK_REF_SRC_MASK, 2);
2036 break;
2037 }
2038
2039 if (fll_div.k)
2040 val = WM8904_FLL_FRACN_ENA;
2041 else
2042 val = 0;
2043 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
2044 WM8904_FLL_FRACN_ENA, val);
2045
2046 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_2,
2047 WM8904_FLL_OUTDIV_MASK | WM8904_FLL_FRATIO_MASK,
2048 (fll_div.fll_outdiv << WM8904_FLL_OUTDIV_SHIFT) |
2049 (fll_div.fll_fratio << WM8904_FLL_FRATIO_SHIFT));
2050
2051 snd_soc_write(codec, WM8904_FLL_CONTROL_3, fll_div.k);
2052
2053 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_4, WM8904_FLL_N_MASK,
2054 fll_div.n << WM8904_FLL_N_SHIFT);
2055
2056 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_5,
2057 WM8904_FLL_CLK_REF_DIV_MASK,
2058 fll_div.fll_clk_ref_div
2059 << WM8904_FLL_CLK_REF_DIV_SHIFT);
2060
2061 dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout);
2062
2063 wm8904->fll_fref = Fref;
2064 wm8904->fll_fout = Fout;
2065 wm8904->fll_src = source;
2066
2067 /* Enable the FLL if it was previously active */
2068 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
2069 WM8904_FLL_OSC_ENA, fll1);
2070 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
2071 WM8904_FLL_ENA, fll1);
2072
2073out:
2074 /* Reenable SYSCLK if it was previously active */
2075 snd_soc_update_bits(codec, WM8904_CLOCK_RATES_2,
2076 WM8904_CLK_SYS_ENA, clock2);
2077
2078 return 0;
2079}
2080
2081static int wm8904_digital_mute(struct snd_soc_dai *codec_dai, int mute)
2082{
2083 struct snd_soc_codec *codec = codec_dai->codec;
2084 int val;
2085
2086 if (mute)
2087 val = WM8904_DAC_MUTE;
2088 else
2089 val = 0;
2090
2091 snd_soc_update_bits(codec, WM8904_DAC_DIGITAL_1, WM8904_DAC_MUTE, val);
2092
2093 return 0;
2094}
2095
2096static void wm8904_sync_cache(struct snd_soc_codec *codec)
2097{
2098 struct wm8904_priv *wm8904 = codec->private_data;
2099 int i;
2100
2101 if (!codec->cache_sync)
2102 return;
2103
2104 codec->cache_only = 0;
2105
2106 /* Sync back cached values if they're different from the
2107 * hardware default.
2108 */
2109 for (i = 1; i < ARRAY_SIZE(wm8904->reg_cache); i++) {
2110 if (!wm8904_access[i].writable)
2111 continue;
2112
2113 if (wm8904->reg_cache[i] == wm8904_reg[i])
2114 continue;
2115
2116 snd_soc_write(codec, i, wm8904->reg_cache[i]);
2117 }
2118
2119 codec->cache_sync = 0;
2120}
2121
2122static int wm8904_set_bias_level(struct snd_soc_codec *codec,
2123 enum snd_soc_bias_level level)
2124{
2125 struct wm8904_priv *wm8904 = codec->private_data;
2126 int ret;
2127
2128 switch (level) {
2129 case SND_SOC_BIAS_ON:
2130 break;
2131
2132 case SND_SOC_BIAS_PREPARE:
2133 /* VMID resistance 2*50k */
2134 snd_soc_update_bits(codec, WM8904_VMID_CONTROL_0,
2135 WM8904_VMID_RES_MASK,
2136 0x1 << WM8904_VMID_RES_SHIFT);
2137
2138 /* Normal bias current */
2139 snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0,
2140 WM8904_ISEL_MASK, 2 << WM8904_ISEL_SHIFT);
2141 break;
2142
2143 case SND_SOC_BIAS_STANDBY:
2144 if (codec->bias_level == SND_SOC_BIAS_OFF) {
2145 ret = regulator_bulk_enable(ARRAY_SIZE(wm8904->supplies),
2146 wm8904->supplies);
2147 if (ret != 0) {
2148 dev_err(codec->dev,
2149 "Failed to enable supplies: %d\n",
2150 ret);
2151 return ret;
2152 }
2153
2154 wm8904_sync_cache(codec);
2155
2156 /* Enable bias */
2157 snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0,
2158 WM8904_BIAS_ENA, WM8904_BIAS_ENA);
2159
2160 /* Enable VMID, VMID buffering, 2*5k resistance */
2161 snd_soc_update_bits(codec, WM8904_VMID_CONTROL_0,
2162 WM8904_VMID_ENA |
2163 WM8904_VMID_RES_MASK,
2164 WM8904_VMID_ENA |
2165 0x3 << WM8904_VMID_RES_SHIFT);
2166
2167 /* Let VMID ramp */
2168 msleep(1);
2169 }
2170
2171 /* Maintain VMID with 2*250k */
2172 snd_soc_update_bits(codec, WM8904_VMID_CONTROL_0,
2173 WM8904_VMID_RES_MASK,
2174 0x2 << WM8904_VMID_RES_SHIFT);
2175
2176 /* Bias current *0.5 */
2177 snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0,
2178 WM8904_ISEL_MASK, 0);
2179 break;
2180
2181 case SND_SOC_BIAS_OFF:
2182 /* Turn off VMID */
2183 snd_soc_update_bits(codec, WM8904_VMID_CONTROL_0,
2184 WM8904_VMID_RES_MASK | WM8904_VMID_ENA, 0);
2185
2186 /* Stop bias generation */
2187 snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0,
2188 WM8904_BIAS_ENA, 0);
2189
2190#ifdef CONFIG_REGULATOR
2191 /* Post 2.6.34 we will be able to get a callback when
2192 * the regulators are disabled which we can use but
2193 * for now just assume that the power will be cut if
2194 * the regulator API is in use.
2195 */
2196 codec->cache_sync = 1;
2197#endif
2198
2199 regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies),
2200 wm8904->supplies);
2201 break;
2202 }
2203 codec->bias_level = level;
2204 return 0;
2205}
2206
2207#define WM8904_RATES SNDRV_PCM_RATE_8000_96000
2208
2209#define WM8904_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
2210 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
2211
2212static struct snd_soc_dai_ops wm8904_dai_ops = {
2213 .set_sysclk = wm8904_set_sysclk,
2214 .set_fmt = wm8904_set_fmt,
2215 .set_tdm_slot = wm8904_set_tdm_slot,
2216 .set_pll = wm8904_set_fll,
2217 .hw_params = wm8904_hw_params,
2218 .digital_mute = wm8904_digital_mute,
2219};
2220
2221struct snd_soc_dai wm8904_dai = {
2222 .name = "WM8904",
2223 .playback = {
2224 .stream_name = "Playback",
2225 .channels_min = 2,
2226 .channels_max = 2,
2227 .rates = WM8904_RATES,
2228 .formats = WM8904_FORMATS,
2229 },
2230 .capture = {
2231 .stream_name = "Capture",
2232 .channels_min = 2,
2233 .channels_max = 2,
2234 .rates = WM8904_RATES,
2235 .formats = WM8904_FORMATS,
2236 },
2237 .ops = &wm8904_dai_ops,
2238 .symmetric_rates = 1,
2239};
2240EXPORT_SYMBOL_GPL(wm8904_dai);
2241
2242#ifdef CONFIG_PM
2243static int wm8904_suspend(struct platform_device *pdev, pm_message_t state)
2244{
2245 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2246 struct snd_soc_codec *codec = socdev->card->codec;
2247
2248 wm8904_set_bias_level(codec, SND_SOC_BIAS_OFF);
2249
2250 return 0;
2251}
2252
2253static int wm8904_resume(struct platform_device *pdev)
2254{
2255 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2256 struct snd_soc_codec *codec = socdev->card->codec;
2257
2258 wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2259
2260 return 0;
2261}
2262#else
2263#define wm8904_suspend NULL
2264#define wm8904_resume NULL
2265#endif
2266
2267static void wm8904_handle_retune_mobile_pdata(struct wm8904_priv *wm8904)
2268{
2269 struct snd_soc_codec *codec = &wm8904->codec;
2270 struct wm8904_pdata *pdata = wm8904->pdata;
2271 struct snd_kcontrol_new control =
2272 SOC_ENUM_EXT("EQ Mode",
2273 wm8904->retune_mobile_enum,
2274 wm8904_get_retune_mobile_enum,
2275 wm8904_put_retune_mobile_enum);
2276 int ret, i, j;
2277 const char **t;
2278
2279 /* We need an array of texts for the enum API but the number
2280 * of texts is likely to be less than the number of
2281 * configurations due to the sample rate dependency of the
2282 * configurations. */
2283 wm8904->num_retune_mobile_texts = 0;
2284 wm8904->retune_mobile_texts = NULL;
2285 for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) {
2286 for (j = 0; j < wm8904->num_retune_mobile_texts; j++) {
2287 if (strcmp(pdata->retune_mobile_cfgs[i].name,
2288 wm8904->retune_mobile_texts[j]) == 0)
2289 break;
2290 }
2291
2292 if (j != wm8904->num_retune_mobile_texts)
2293 continue;
2294
2295 /* Expand the array... */
2296 t = krealloc(wm8904->retune_mobile_texts,
2297 sizeof(char *) *
2298 (wm8904->num_retune_mobile_texts + 1),
2299 GFP_KERNEL);
2300 if (t == NULL)
2301 continue;
2302
2303 /* ...store the new entry... */
2304 t[wm8904->num_retune_mobile_texts] =
2305 pdata->retune_mobile_cfgs[i].name;
2306
2307 /* ...and remember the new version. */
2308 wm8904->num_retune_mobile_texts++;
2309 wm8904->retune_mobile_texts = t;
2310 }
2311
2312 dev_dbg(codec->dev, "Allocated %d unique ReTune Mobile names\n",
2313 wm8904->num_retune_mobile_texts);
2314
2315 wm8904->retune_mobile_enum.max = wm8904->num_retune_mobile_texts;
2316 wm8904->retune_mobile_enum.texts = wm8904->retune_mobile_texts;
2317
2318 ret = snd_soc_add_controls(&wm8904->codec, &control, 1);
2319 if (ret != 0)
2320 dev_err(wm8904->codec.dev,
2321 "Failed to add ReTune Mobile control: %d\n", ret);
2322}
2323
2324static void wm8904_handle_pdata(struct wm8904_priv *wm8904)
2325{
2326 struct snd_soc_codec *codec = &wm8904->codec;
2327 struct wm8904_pdata *pdata = wm8904->pdata;
2328 int ret, i;
2329
2330 if (!pdata) {
2331 snd_soc_add_controls(&wm8904->codec, wm8904_eq_controls,
2332 ARRAY_SIZE(wm8904_eq_controls));
2333 return;
2334 }
2335
2336 dev_dbg(codec->dev, "%d DRC configurations\n", pdata->num_drc_cfgs);
2337
2338 if (pdata->num_drc_cfgs) {
2339 struct snd_kcontrol_new control =
2340 SOC_ENUM_EXT("DRC Mode", wm8904->drc_enum,
2341 wm8904_get_drc_enum, wm8904_put_drc_enum);
2342
2343 /* We need an array of texts for the enum API */
2344 wm8904->drc_texts = kmalloc(sizeof(char *)
2345 * pdata->num_drc_cfgs, GFP_KERNEL);
2346 if (!wm8904->drc_texts) {
2347 dev_err(wm8904->codec.dev,
2348 "Failed to allocate %d DRC config texts\n",
2349 pdata->num_drc_cfgs);
2350 return;
2351 }
2352
2353 for (i = 0; i < pdata->num_drc_cfgs; i++)
2354 wm8904->drc_texts[i] = pdata->drc_cfgs[i].name;
2355
2356 wm8904->drc_enum.max = pdata->num_drc_cfgs;
2357 wm8904->drc_enum.texts = wm8904->drc_texts;
2358
2359 ret = snd_soc_add_controls(&wm8904->codec, &control, 1);
2360 if (ret != 0)
2361 dev_err(wm8904->codec.dev,
2362 "Failed to add DRC mode control: %d\n", ret);
2363
2364 wm8904_set_drc(codec);
2365 }
2366
2367 dev_dbg(codec->dev, "%d ReTune Mobile configurations\n",
2368 pdata->num_retune_mobile_cfgs);
2369
2370 if (pdata->num_retune_mobile_cfgs)
2371 wm8904_handle_retune_mobile_pdata(wm8904);
2372 else
2373 snd_soc_add_controls(&wm8904->codec, wm8904_eq_controls,
2374 ARRAY_SIZE(wm8904_eq_controls));
2375}
2376
2377static int wm8904_probe(struct platform_device *pdev)
2378{
2379 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2380 struct snd_soc_codec *codec;
2381 int ret = 0;
2382
2383 if (wm8904_codec == NULL) {
2384 dev_err(&pdev->dev, "Codec device not registered\n");
2385 return -ENODEV;
2386 }
2387
2388 socdev->card->codec = wm8904_codec;
2389 codec = wm8904_codec;
2390
2391 /* register pcms */
2392 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
2393 if (ret < 0) {
2394 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
2395 goto pcm_err;
2396 }
2397
2398 wm8904_handle_pdata(codec->private_data);
2399
2400 wm8904_add_widgets(codec);
2401
2402 return ret;
2403
2404pcm_err:
2405 return ret;
2406}
2407
2408static int wm8904_remove(struct platform_device *pdev)
2409{
2410 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2411
2412 snd_soc_free_pcms(socdev);
2413 snd_soc_dapm_free(socdev);
2414
2415 return 0;
2416}
2417
2418struct snd_soc_codec_device soc_codec_dev_wm8904 = {
2419 .probe = wm8904_probe,
2420 .remove = wm8904_remove,
2421 .suspend = wm8904_suspend,
2422 .resume = wm8904_resume,
2423};
2424EXPORT_SYMBOL_GPL(soc_codec_dev_wm8904);
2425
2426static int wm8904_register(struct wm8904_priv *wm8904,
2427 enum snd_soc_control_type control)
2428{
2429 int ret;
2430 struct snd_soc_codec *codec = &wm8904->codec;
2431 int i;
2432
2433 if (wm8904_codec) {
2434 dev_err(codec->dev, "Another WM8904 is registered\n");
2435 return -EINVAL;
2436 }
2437
2438 mutex_init(&codec->mutex);
2439 INIT_LIST_HEAD(&codec->dapm_widgets);
2440 INIT_LIST_HEAD(&codec->dapm_paths);
2441
2442 codec->private_data = wm8904;
2443 codec->name = "WM8904";
2444 codec->owner = THIS_MODULE;
2445 codec->bias_level = SND_SOC_BIAS_OFF;
2446 codec->set_bias_level = wm8904_set_bias_level;
2447 codec->dai = &wm8904_dai;
2448 codec->num_dai = 1;
2449 codec->reg_cache_size = WM8904_MAX_REGISTER;
2450 codec->reg_cache = &wm8904->reg_cache;
2451 codec->volatile_register = wm8904_volatile_register;
2452 codec->cache_sync = 1;
2453 codec->idle_bias_off = 1;
2454
2455 switch (wm8904->devtype) {
2456 case WM8904:
2457 break;
2458 case WM8912:
2459 memset(&wm8904_dai.capture, 0, sizeof(wm8904_dai.capture));
2460 break;
2461 default:
2462 dev_err(codec->dev, "Unknown device type %d\n",
2463 wm8904->devtype);
2464 return -EINVAL;
2465 }
2466
2467 memcpy(codec->reg_cache, wm8904_reg, sizeof(wm8904_reg));
2468
2469 ret = snd_soc_codec_set_cache_io(codec, 8, 16, control);
2470 if (ret != 0) {
2471 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
2472 goto err;
2473 }
2474
2475 for (i = 0; i < ARRAY_SIZE(wm8904->supplies); i++)
2476 wm8904->supplies[i].supply = wm8904_supply_names[i];
2477
2478 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8904->supplies),
2479 wm8904->supplies);
2480 if (ret != 0) {
2481 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
2482 goto err;
2483 }
2484
2485 ret = regulator_bulk_enable(ARRAY_SIZE(wm8904->supplies),
2486 wm8904->supplies);
2487 if (ret != 0) {
2488 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
2489 goto err_get;
2490 }
2491
2492 ret = snd_soc_read(codec, WM8904_SW_RESET_AND_ID);
2493 if (ret < 0) {
2494 dev_err(codec->dev, "Failed to read ID register\n");
2495 goto err_enable;
2496 }
2497 if (ret != wm8904_reg[WM8904_SW_RESET_AND_ID]) {
2498 dev_err(codec->dev, "Device is not a WM8904, ID is %x\n", ret);
2499 ret = -EINVAL;
2500 goto err_enable;
2501 }
2502
2503 ret = snd_soc_read(codec, WM8904_REVISION);
2504 if (ret < 0) {
2505 dev_err(codec->dev, "Failed to read device revision: %d\n",
2506 ret);
2507 goto err_enable;
2508 }
2509 dev_info(codec->dev, "revision %c\n", ret + 'A');
2510
2511 ret = wm8904_reset(codec);
2512 if (ret < 0) {
2513 dev_err(codec->dev, "Failed to issue reset\n");
2514 goto err_enable;
2515 }
2516
2517 wm8904_dai.dev = codec->dev;
2518
2519 /* Change some default settings - latch VU and enable ZC */
2520 wm8904->reg_cache[WM8904_ADC_DIGITAL_VOLUME_LEFT] |= WM8904_ADC_VU;
2521 wm8904->reg_cache[WM8904_ADC_DIGITAL_VOLUME_RIGHT] |= WM8904_ADC_VU;
2522 wm8904->reg_cache[WM8904_DAC_DIGITAL_VOLUME_LEFT] |= WM8904_DAC_VU;
2523 wm8904->reg_cache[WM8904_DAC_DIGITAL_VOLUME_RIGHT] |= WM8904_DAC_VU;
2524 wm8904->reg_cache[WM8904_ANALOGUE_OUT1_LEFT] |= WM8904_HPOUT_VU |
2525 WM8904_HPOUTLZC;
2526 wm8904->reg_cache[WM8904_ANALOGUE_OUT1_RIGHT] |= WM8904_HPOUT_VU |
2527 WM8904_HPOUTRZC;
2528 wm8904->reg_cache[WM8904_ANALOGUE_OUT2_LEFT] |= WM8904_LINEOUT_VU |
2529 WM8904_LINEOUTLZC;
2530 wm8904->reg_cache[WM8904_ANALOGUE_OUT2_RIGHT] |= WM8904_LINEOUT_VU |
2531 WM8904_LINEOUTRZC;
2532 wm8904->reg_cache[WM8904_CLOCK_RATES_0] &= ~WM8904_SR_MODE;
2533
2534 /* Set Class W by default - this will be managed by the Class
2535 * G widget at runtime where bypass paths are available.
2536 */
2537 wm8904->reg_cache[WM8904_CLASS_W_0] |= WM8904_CP_DYN_PWR;
2538
2539 /* Use normal bias source */
2540 wm8904->reg_cache[WM8904_BIAS_CONTROL_0] &= ~WM8904_POBCTRL;
2541
2542 wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2543
2544 /* Bias level configuration will have done an extra enable */
2545 regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2546
2547 wm8904_codec = codec;
2548
2549 ret = snd_soc_register_codec(codec);
2550 if (ret != 0) {
2551 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
2552 return ret;
2553 }
2554
2555 ret = snd_soc_register_dai(&wm8904_dai);
2556 if (ret != 0) {
2557 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
2558 snd_soc_unregister_codec(codec);
2559 return ret;
2560 }
2561
2562 return 0;
2563
2564err_enable:
2565 regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2566err_get:
2567 regulator_bulk_free(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2568err:
2569 kfree(wm8904);
2570 return ret;
2571}
2572
2573static void wm8904_unregister(struct wm8904_priv *wm8904)
2574{
2575 wm8904_set_bias_level(&wm8904->codec, SND_SOC_BIAS_OFF);
2576 regulator_bulk_free(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2577 snd_soc_unregister_dai(&wm8904_dai);
2578 snd_soc_unregister_codec(&wm8904->codec);
2579 kfree(wm8904);
2580 wm8904_codec = NULL;
2581}
2582
2583#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
2584static __devinit int wm8904_i2c_probe(struct i2c_client *i2c,
2585 const struct i2c_device_id *id)
2586{
2587 struct wm8904_priv *wm8904;
2588 struct snd_soc_codec *codec;
2589
2590 wm8904 = kzalloc(sizeof(struct wm8904_priv), GFP_KERNEL);
2591 if (wm8904 == NULL)
2592 return -ENOMEM;
2593
2594 codec = &wm8904->codec;
2595 codec->hw_write = (hw_write_t)i2c_master_send;
2596
2597 wm8904->devtype = id->driver_data;
2598
2599 i2c_set_clientdata(i2c, wm8904);
2600 codec->control_data = i2c;
2601 wm8904->pdata = i2c->dev.platform_data;
2602
2603 codec->dev = &i2c->dev;
2604
2605 return wm8904_register(wm8904, SND_SOC_I2C);
2606}
2607
2608static __devexit int wm8904_i2c_remove(struct i2c_client *client)
2609{
2610 struct wm8904_priv *wm8904 = i2c_get_clientdata(client);
2611 wm8904_unregister(wm8904);
2612 return 0;
2613}
2614
2615static const struct i2c_device_id wm8904_i2c_id[] = {
2616 { "wm8904", WM8904 },
2617 { "wm8912", WM8912 },
2618 { }
2619};
2620MODULE_DEVICE_TABLE(i2c, wm8904_i2c_id);
2621
2622static struct i2c_driver wm8904_i2c_driver = {
2623 .driver = {
2624 .name = "WM8904",
2625 .owner = THIS_MODULE,
2626 },
2627 .probe = wm8904_i2c_probe,
2628 .remove = __devexit_p(wm8904_i2c_remove),
2629 .id_table = wm8904_i2c_id,
2630};
2631#endif
2632
2633static int __init wm8904_modinit(void)
2634{
2635 int ret;
2636#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
2637 ret = i2c_add_driver(&wm8904_i2c_driver);
2638 if (ret != 0) {
2639 printk(KERN_ERR "Failed to register WM8904 I2C driver: %d\n",
2640 ret);
2641 }
2642#endif
2643 return 0;
2644}
2645module_init(wm8904_modinit);
2646
2647static void __exit wm8904_exit(void)
2648{
2649#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
2650 i2c_del_driver(&wm8904_i2c_driver);
2651#endif
2652}
2653module_exit(wm8904_exit);
2654
2655MODULE_DESCRIPTION("ASoC WM8904 driver");
2656MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
2657MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8904.h b/sound/soc/codecs/wm8904.h
new file mode 100644
index 000000000000..b68886df34e4
--- /dev/null
+++ b/sound/soc/codecs/wm8904.h
@@ -0,0 +1,1681 @@
1/*
2 * wm8904.h -- WM8904 ASoC driver
3 *
4 * Copyright 2009 Wolfson Microelectronics, plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef _WM8904_H
14#define _WM8904_H
15
16#define WM8904_CLK_MCLK 1
17#define WM8904_CLK_FLL 2
18
19#define WM8904_FLL_MCLK 1
20#define WM8904_FLL_BCLK 2
21#define WM8904_FLL_LRCLK 3
22#define WM8904_FLL_FREE_RUNNING 4
23
24extern struct snd_soc_dai wm8904_dai;
25extern struct snd_soc_codec_device soc_codec_dev_wm8904;
26
27/*
28 * Register values.
29 */
30#define WM8904_SW_RESET_AND_ID 0x00
31#define WM8904_REVISION 0x01
32#define WM8904_BIAS_CONTROL_0 0x04
33#define WM8904_VMID_CONTROL_0 0x05
34#define WM8904_MIC_BIAS_CONTROL_0 0x06
35#define WM8904_MIC_BIAS_CONTROL_1 0x07
36#define WM8904_ANALOGUE_DAC_0 0x08
37#define WM8904_MIC_FILTER_CONTROL 0x09
38#define WM8904_ANALOGUE_ADC_0 0x0A
39#define WM8904_POWER_MANAGEMENT_0 0x0C
40#define WM8904_POWER_MANAGEMENT_2 0x0E
41#define WM8904_POWER_MANAGEMENT_3 0x0F
42#define WM8904_POWER_MANAGEMENT_6 0x12
43#define WM8904_CLOCK_RATES_0 0x14
44#define WM8904_CLOCK_RATES_1 0x15
45#define WM8904_CLOCK_RATES_2 0x16
46#define WM8904_AUDIO_INTERFACE_0 0x18
47#define WM8904_AUDIO_INTERFACE_1 0x19
48#define WM8904_AUDIO_INTERFACE_2 0x1A
49#define WM8904_AUDIO_INTERFACE_3 0x1B
50#define WM8904_DAC_DIGITAL_VOLUME_LEFT 0x1E
51#define WM8904_DAC_DIGITAL_VOLUME_RIGHT 0x1F
52#define WM8904_DAC_DIGITAL_0 0x20
53#define WM8904_DAC_DIGITAL_1 0x21
54#define WM8904_ADC_DIGITAL_VOLUME_LEFT 0x24
55#define WM8904_ADC_DIGITAL_VOLUME_RIGHT 0x25
56#define WM8904_ADC_DIGITAL_0 0x26
57#define WM8904_DIGITAL_MICROPHONE_0 0x27
58#define WM8904_DRC_0 0x28
59#define WM8904_DRC_1 0x29
60#define WM8904_DRC_2 0x2A
61#define WM8904_DRC_3 0x2B
62#define WM8904_ANALOGUE_LEFT_INPUT_0 0x2C
63#define WM8904_ANALOGUE_RIGHT_INPUT_0 0x2D
64#define WM8904_ANALOGUE_LEFT_INPUT_1 0x2E
65#define WM8904_ANALOGUE_RIGHT_INPUT_1 0x2F
66#define WM8904_ANALOGUE_OUT1_LEFT 0x39
67#define WM8904_ANALOGUE_OUT1_RIGHT 0x3A
68#define WM8904_ANALOGUE_OUT2_LEFT 0x3B
69#define WM8904_ANALOGUE_OUT2_RIGHT 0x3C
70#define WM8904_ANALOGUE_OUT12_ZC 0x3D
71#define WM8904_DC_SERVO_0 0x43
72#define WM8904_DC_SERVO_1 0x44
73#define WM8904_DC_SERVO_2 0x45
74#define WM8904_DC_SERVO_4 0x47
75#define WM8904_DC_SERVO_5 0x48
76#define WM8904_DC_SERVO_6 0x49
77#define WM8904_DC_SERVO_7 0x4A
78#define WM8904_DC_SERVO_8 0x4B
79#define WM8904_DC_SERVO_9 0x4C
80#define WM8904_DC_SERVO_READBACK_0 0x4D
81#define WM8904_ANALOGUE_HP_0 0x5A
82#define WM8904_ANALOGUE_LINEOUT_0 0x5E
83#define WM8904_CHARGE_PUMP_0 0x62
84#define WM8904_CLASS_W_0 0x68
85#define WM8904_WRITE_SEQUENCER_0 0x6C
86#define WM8904_WRITE_SEQUENCER_1 0x6D
87#define WM8904_WRITE_SEQUENCER_2 0x6E
88#define WM8904_WRITE_SEQUENCER_3 0x6F
89#define WM8904_WRITE_SEQUENCER_4 0x70
90#define WM8904_FLL_CONTROL_1 0x74
91#define WM8904_FLL_CONTROL_2 0x75
92#define WM8904_FLL_CONTROL_3 0x76
93#define WM8904_FLL_CONTROL_4 0x77
94#define WM8904_FLL_CONTROL_5 0x78
95#define WM8904_GPIO_CONTROL_1 0x79
96#define WM8904_GPIO_CONTROL_2 0x7A
97#define WM8904_GPIO_CONTROL_3 0x7B
98#define WM8904_GPIO_CONTROL_4 0x7C
99#define WM8904_DIGITAL_PULLS 0x7E
100#define WM8904_INTERRUPT_STATUS 0x7F
101#define WM8904_INTERRUPT_STATUS_MASK 0x80
102#define WM8904_INTERRUPT_POLARITY 0x81
103#define WM8904_INTERRUPT_DEBOUNCE 0x82
104#define WM8904_EQ1 0x86
105#define WM8904_EQ2 0x87
106#define WM8904_EQ3 0x88
107#define WM8904_EQ4 0x89
108#define WM8904_EQ5 0x8A
109#define WM8904_EQ6 0x8B
110#define WM8904_EQ7 0x8C
111#define WM8904_EQ8 0x8D
112#define WM8904_EQ9 0x8E
113#define WM8904_EQ10 0x8F
114#define WM8904_EQ11 0x90
115#define WM8904_EQ12 0x91
116#define WM8904_EQ13 0x92
117#define WM8904_EQ14 0x93
118#define WM8904_EQ15 0x94
119#define WM8904_EQ16 0x95
120#define WM8904_EQ17 0x96
121#define WM8904_EQ18 0x97
122#define WM8904_EQ19 0x98
123#define WM8904_EQ20 0x99
124#define WM8904_EQ21 0x9A
125#define WM8904_EQ22 0x9B
126#define WM8904_EQ23 0x9C
127#define WM8904_EQ24 0x9D
128#define WM8904_CONTROL_INTERFACE_TEST_1 0xA1
129#define WM8904_ANALOGUE_OUTPUT_BIAS_0 0xCC
130#define WM8904_FLL_NCO_TEST_0 0xF7
131#define WM8904_FLL_NCO_TEST_1 0xF8
132
133#define WM8904_REGISTER_COUNT 101
134#define WM8904_MAX_REGISTER 0xF8
135
136/*
137 * Field Definitions.
138 */
139
140/*
141 * R0 (0x00) - SW Reset and ID
142 */
143#define WM8904_SW_RST_DEV_ID1_MASK 0xFFFF /* SW_RST_DEV_ID1 - [15:0] */
144#define WM8904_SW_RST_DEV_ID1_SHIFT 0 /* SW_RST_DEV_ID1 - [15:0] */
145#define WM8904_SW_RST_DEV_ID1_WIDTH 16 /* SW_RST_DEV_ID1 - [15:0] */
146
147/*
148 * R1 (0x01) - Revision
149 */
150#define WM8904_REVISION_MASK 0x000F /* REVISION - [3:0] */
151#define WM8904_REVISION_SHIFT 0 /* REVISION - [3:0] */
152#define WM8904_REVISION_WIDTH 16 /* REVISION - [3:0] */
153
154/*
155 * R4 (0x04) - Bias Control 0
156 */
157#define WM8904_POBCTRL 0x0010 /* POBCTRL */
158#define WM8904_POBCTRL_MASK 0x0010 /* POBCTRL */
159#define WM8904_POBCTRL_SHIFT 4 /* POBCTRL */
160#define WM8904_POBCTRL_WIDTH 1 /* POBCTRL */
161#define WM8904_ISEL_MASK 0x000C /* ISEL - [3:2] */
162#define WM8904_ISEL_SHIFT 2 /* ISEL - [3:2] */
163#define WM8904_ISEL_WIDTH 2 /* ISEL - [3:2] */
164#define WM8904_STARTUP_BIAS_ENA 0x0002 /* STARTUP_BIAS_ENA */
165#define WM8904_STARTUP_BIAS_ENA_MASK 0x0002 /* STARTUP_BIAS_ENA */
166#define WM8904_STARTUP_BIAS_ENA_SHIFT 1 /* STARTUP_BIAS_ENA */
167#define WM8904_STARTUP_BIAS_ENA_WIDTH 1 /* STARTUP_BIAS_ENA */
168#define WM8904_BIAS_ENA 0x0001 /* BIAS_ENA */
169#define WM8904_BIAS_ENA_MASK 0x0001 /* BIAS_ENA */
170#define WM8904_BIAS_ENA_SHIFT 0 /* BIAS_ENA */
171#define WM8904_BIAS_ENA_WIDTH 1 /* BIAS_ENA */
172
173/*
174 * R5 (0x05) - VMID Control 0
175 */
176#define WM8904_VMID_BUF_ENA 0x0040 /* VMID_BUF_ENA */
177#define WM8904_VMID_BUF_ENA_MASK 0x0040 /* VMID_BUF_ENA */
178#define WM8904_VMID_BUF_ENA_SHIFT 6 /* VMID_BUF_ENA */
179#define WM8904_VMID_BUF_ENA_WIDTH 1 /* VMID_BUF_ENA */
180#define WM8904_VMID_RES_MASK 0x0006 /* VMID_RES - [2:1] */
181#define WM8904_VMID_RES_SHIFT 1 /* VMID_RES - [2:1] */
182#define WM8904_VMID_RES_WIDTH 2 /* VMID_RES - [2:1] */
183#define WM8904_VMID_ENA 0x0001 /* VMID_ENA */
184#define WM8904_VMID_ENA_MASK 0x0001 /* VMID_ENA */
185#define WM8904_VMID_ENA_SHIFT 0 /* VMID_ENA */
186#define WM8904_VMID_ENA_WIDTH 1 /* VMID_ENA */
187
188/*
189 * R6 (0x06) - Mic Bias Control 0
190 */
191#define WM8904_MICDET_THR_MASK 0x0070 /* MICDET_THR - [6:4] */
192#define WM8904_MICDET_THR_SHIFT 4 /* MICDET_THR - [6:4] */
193#define WM8904_MICDET_THR_WIDTH 3 /* MICDET_THR - [6:4] */
194#define WM8904_MICSHORT_THR_MASK 0x000C /* MICSHORT_THR - [3:2] */
195#define WM8904_MICSHORT_THR_SHIFT 2 /* MICSHORT_THR - [3:2] */
196#define WM8904_MICSHORT_THR_WIDTH 2 /* MICSHORT_THR - [3:2] */
197#define WM8904_MICDET_ENA 0x0002 /* MICDET_ENA */
198#define WM8904_MICDET_ENA_MASK 0x0002 /* MICDET_ENA */
199#define WM8904_MICDET_ENA_SHIFT 1 /* MICDET_ENA */
200#define WM8904_MICDET_ENA_WIDTH 1 /* MICDET_ENA */
201#define WM8904_MICBIAS_ENA 0x0001 /* MICBIAS_ENA */
202#define WM8904_MICBIAS_ENA_MASK 0x0001 /* MICBIAS_ENA */
203#define WM8904_MICBIAS_ENA_SHIFT 0 /* MICBIAS_ENA */
204#define WM8904_MICBIAS_ENA_WIDTH 1 /* MICBIAS_ENA */
205
206/*
207 * R7 (0x07) - Mic Bias Control 1
208 */
209#define WM8904_MIC_DET_FILTER_ENA 0x8000 /* MIC_DET_FILTER_ENA */
210#define WM8904_MIC_DET_FILTER_ENA_MASK 0x8000 /* MIC_DET_FILTER_ENA */
211#define WM8904_MIC_DET_FILTER_ENA_SHIFT 15 /* MIC_DET_FILTER_ENA */
212#define WM8904_MIC_DET_FILTER_ENA_WIDTH 1 /* MIC_DET_FILTER_ENA */
213#define WM8904_MIC_SHORT_FILTER_ENA 0x4000 /* MIC_SHORT_FILTER_ENA */
214#define WM8904_MIC_SHORT_FILTER_ENA_MASK 0x4000 /* MIC_SHORT_FILTER_ENA */
215#define WM8904_MIC_SHORT_FILTER_ENA_SHIFT 14 /* MIC_SHORT_FILTER_ENA */
216#define WM8904_MIC_SHORT_FILTER_ENA_WIDTH 1 /* MIC_SHORT_FILTER_ENA */
217#define WM8904_MICBIAS_SEL_MASK 0x0007 /* MICBIAS_SEL - [2:0] */
218#define WM8904_MICBIAS_SEL_SHIFT 0 /* MICBIAS_SEL - [2:0] */
219#define WM8904_MICBIAS_SEL_WIDTH 3 /* MICBIAS_SEL - [2:0] */
220
221/*
222 * R8 (0x08) - Analogue DAC 0
223 */
224#define WM8904_DAC_BIAS_SEL_MASK 0x0018 /* DAC_BIAS_SEL - [4:3] */
225#define WM8904_DAC_BIAS_SEL_SHIFT 3 /* DAC_BIAS_SEL - [4:3] */
226#define WM8904_DAC_BIAS_SEL_WIDTH 2 /* DAC_BIAS_SEL - [4:3] */
227#define WM8904_DAC_VMID_BIAS_SEL_MASK 0x0006 /* DAC_VMID_BIAS_SEL - [2:1] */
228#define WM8904_DAC_VMID_BIAS_SEL_SHIFT 1 /* DAC_VMID_BIAS_SEL - [2:1] */
229#define WM8904_DAC_VMID_BIAS_SEL_WIDTH 2 /* DAC_VMID_BIAS_SEL - [2:1] */
230
231/*
232 * R9 (0x09) - mic Filter Control
233 */
234#define WM8904_MIC_DET_SET_THRESHOLD_MASK 0xF000 /* MIC_DET_SET_THRESHOLD - [15:12] */
235#define WM8904_MIC_DET_SET_THRESHOLD_SHIFT 12 /* MIC_DET_SET_THRESHOLD - [15:12] */
236#define WM8904_MIC_DET_SET_THRESHOLD_WIDTH 4 /* MIC_DET_SET_THRESHOLD - [15:12] */
237#define WM8904_MIC_DET_RESET_THRESHOLD_MASK 0x0F00 /* MIC_DET_RESET_THRESHOLD - [11:8] */
238#define WM8904_MIC_DET_RESET_THRESHOLD_SHIFT 8 /* MIC_DET_RESET_THRESHOLD - [11:8] */
239#define WM8904_MIC_DET_RESET_THRESHOLD_WIDTH 4 /* MIC_DET_RESET_THRESHOLD - [11:8] */
240#define WM8904_MIC_SHORT_SET_THRESHOLD_MASK 0x00F0 /* MIC_SHORT_SET_THRESHOLD - [7:4] */
241#define WM8904_MIC_SHORT_SET_THRESHOLD_SHIFT 4 /* MIC_SHORT_SET_THRESHOLD - [7:4] */
242#define WM8904_MIC_SHORT_SET_THRESHOLD_WIDTH 4 /* MIC_SHORT_SET_THRESHOLD - [7:4] */
243#define WM8904_MIC_SHORT_RESET_THRESHOLD_MASK 0x000F /* MIC_SHORT_RESET_THRESHOLD - [3:0] */
244#define WM8904_MIC_SHORT_RESET_THRESHOLD_SHIFT 0 /* MIC_SHORT_RESET_THRESHOLD - [3:0] */
245#define WM8904_MIC_SHORT_RESET_THRESHOLD_WIDTH 4 /* MIC_SHORT_RESET_THRESHOLD - [3:0] */
246
247/*
248 * R10 (0x0A) - Analogue ADC 0
249 */
250#define WM8904_ADC_OSR128 0x0001 /* ADC_OSR128 */
251#define WM8904_ADC_OSR128_MASK 0x0001 /* ADC_OSR128 */
252#define WM8904_ADC_OSR128_SHIFT 0 /* ADC_OSR128 */
253#define WM8904_ADC_OSR128_WIDTH 1 /* ADC_OSR128 */
254
255/*
256 * R12 (0x0C) - Power Management 0
257 */
258#define WM8904_INL_ENA 0x0002 /* INL_ENA */
259#define WM8904_INL_ENA_MASK 0x0002 /* INL_ENA */
260#define WM8904_INL_ENA_SHIFT 1 /* INL_ENA */
261#define WM8904_INL_ENA_WIDTH 1 /* INL_ENA */
262#define WM8904_INR_ENA 0x0001 /* INR_ENA */
263#define WM8904_INR_ENA_MASK 0x0001 /* INR_ENA */
264#define WM8904_INR_ENA_SHIFT 0 /* INR_ENA */
265#define WM8904_INR_ENA_WIDTH 1 /* INR_ENA */
266
267/*
268 * R14 (0x0E) - Power Management 2
269 */
270#define WM8904_HPL_PGA_ENA 0x0002 /* HPL_PGA_ENA */
271#define WM8904_HPL_PGA_ENA_MASK 0x0002 /* HPL_PGA_ENA */
272#define WM8904_HPL_PGA_ENA_SHIFT 1 /* HPL_PGA_ENA */
273#define WM8904_HPL_PGA_ENA_WIDTH 1 /* HPL_PGA_ENA */
274#define WM8904_HPR_PGA_ENA 0x0001 /* HPR_PGA_ENA */
275#define WM8904_HPR_PGA_ENA_MASK 0x0001 /* HPR_PGA_ENA */
276#define WM8904_HPR_PGA_ENA_SHIFT 0 /* HPR_PGA_ENA */
277#define WM8904_HPR_PGA_ENA_WIDTH 1 /* HPR_PGA_ENA */
278
279/*
280 * R15 (0x0F) - Power Management 3
281 */
282#define WM8904_LINEOUTL_PGA_ENA 0x0002 /* LINEOUTL_PGA_ENA */
283#define WM8904_LINEOUTL_PGA_ENA_MASK 0x0002 /* LINEOUTL_PGA_ENA */
284#define WM8904_LINEOUTL_PGA_ENA_SHIFT 1 /* LINEOUTL_PGA_ENA */
285#define WM8904_LINEOUTL_PGA_ENA_WIDTH 1 /* LINEOUTL_PGA_ENA */
286#define WM8904_LINEOUTR_PGA_ENA 0x0001 /* LINEOUTR_PGA_ENA */
287#define WM8904_LINEOUTR_PGA_ENA_MASK 0x0001 /* LINEOUTR_PGA_ENA */
288#define WM8904_LINEOUTR_PGA_ENA_SHIFT 0 /* LINEOUTR_PGA_ENA */
289#define WM8904_LINEOUTR_PGA_ENA_WIDTH 1 /* LINEOUTR_PGA_ENA */
290
291/*
292 * R18 (0x12) - Power Management 6
293 */
294#define WM8904_DACL_ENA 0x0008 /* DACL_ENA */
295#define WM8904_DACL_ENA_MASK 0x0008 /* DACL_ENA */
296#define WM8904_DACL_ENA_SHIFT 3 /* DACL_ENA */
297#define WM8904_DACL_ENA_WIDTH 1 /* DACL_ENA */
298#define WM8904_DACR_ENA 0x0004 /* DACR_ENA */
299#define WM8904_DACR_ENA_MASK 0x0004 /* DACR_ENA */
300#define WM8904_DACR_ENA_SHIFT 2 /* DACR_ENA */
301#define WM8904_DACR_ENA_WIDTH 1 /* DACR_ENA */
302#define WM8904_ADCL_ENA 0x0002 /* ADCL_ENA */
303#define WM8904_ADCL_ENA_MASK 0x0002 /* ADCL_ENA */
304#define WM8904_ADCL_ENA_SHIFT 1 /* ADCL_ENA */
305#define WM8904_ADCL_ENA_WIDTH 1 /* ADCL_ENA */
306#define WM8904_ADCR_ENA 0x0001 /* ADCR_ENA */
307#define WM8904_ADCR_ENA_MASK 0x0001 /* ADCR_ENA */
308#define WM8904_ADCR_ENA_SHIFT 0 /* ADCR_ENA */
309#define WM8904_ADCR_ENA_WIDTH 1 /* ADCR_ENA */
310
311/*
312 * R20 (0x14) - Clock Rates 0
313 */
314#define WM8904_TOCLK_RATE_DIV16 0x4000 /* TOCLK_RATE_DIV16 */
315#define WM8904_TOCLK_RATE_DIV16_MASK 0x4000 /* TOCLK_RATE_DIV16 */
316#define WM8904_TOCLK_RATE_DIV16_SHIFT 14 /* TOCLK_RATE_DIV16 */
317#define WM8904_TOCLK_RATE_DIV16_WIDTH 1 /* TOCLK_RATE_DIV16 */
318#define WM8904_TOCLK_RATE_X4 0x2000 /* TOCLK_RATE_X4 */
319#define WM8904_TOCLK_RATE_X4_MASK 0x2000 /* TOCLK_RATE_X4 */
320#define WM8904_TOCLK_RATE_X4_SHIFT 13 /* TOCLK_RATE_X4 */
321#define WM8904_TOCLK_RATE_X4_WIDTH 1 /* TOCLK_RATE_X4 */
322#define WM8904_SR_MODE 0x1000 /* SR_MODE */
323#define WM8904_SR_MODE_MASK 0x1000 /* SR_MODE */
324#define WM8904_SR_MODE_SHIFT 12 /* SR_MODE */
325#define WM8904_SR_MODE_WIDTH 1 /* SR_MODE */
326#define WM8904_MCLK_DIV 0x0001 /* MCLK_DIV */
327#define WM8904_MCLK_DIV_MASK 0x0001 /* MCLK_DIV */
328#define WM8904_MCLK_DIV_SHIFT 0 /* MCLK_DIV */
329#define WM8904_MCLK_DIV_WIDTH 1 /* MCLK_DIV */
330
331/*
332 * R21 (0x15) - Clock Rates 1
333 */
334#define WM8904_CLK_SYS_RATE_MASK 0x3C00 /* CLK_SYS_RATE - [13:10] */
335#define WM8904_CLK_SYS_RATE_SHIFT 10 /* CLK_SYS_RATE - [13:10] */
336#define WM8904_CLK_SYS_RATE_WIDTH 4 /* CLK_SYS_RATE - [13:10] */
337#define WM8904_SAMPLE_RATE_MASK 0x0007 /* SAMPLE_RATE - [2:0] */
338#define WM8904_SAMPLE_RATE_SHIFT 0 /* SAMPLE_RATE - [2:0] */
339#define WM8904_SAMPLE_RATE_WIDTH 3 /* SAMPLE_RATE - [2:0] */
340
341/*
342 * R22 (0x16) - Clock Rates 2
343 */
344#define WM8904_MCLK_INV 0x8000 /* MCLK_INV */
345#define WM8904_MCLK_INV_MASK 0x8000 /* MCLK_INV */
346#define WM8904_MCLK_INV_SHIFT 15 /* MCLK_INV */
347#define WM8904_MCLK_INV_WIDTH 1 /* MCLK_INV */
348#define WM8904_SYSCLK_SRC 0x4000 /* SYSCLK_SRC */
349#define WM8904_SYSCLK_SRC_MASK 0x4000 /* SYSCLK_SRC */
350#define WM8904_SYSCLK_SRC_SHIFT 14 /* SYSCLK_SRC */
351#define WM8904_SYSCLK_SRC_WIDTH 1 /* SYSCLK_SRC */
352#define WM8904_TOCLK_RATE 0x1000 /* TOCLK_RATE */
353#define WM8904_TOCLK_RATE_MASK 0x1000 /* TOCLK_RATE */
354#define WM8904_TOCLK_RATE_SHIFT 12 /* TOCLK_RATE */
355#define WM8904_TOCLK_RATE_WIDTH 1 /* TOCLK_RATE */
356#define WM8904_OPCLK_ENA 0x0008 /* OPCLK_ENA */
357#define WM8904_OPCLK_ENA_MASK 0x0008 /* OPCLK_ENA */
358#define WM8904_OPCLK_ENA_SHIFT 3 /* OPCLK_ENA */
359#define WM8904_OPCLK_ENA_WIDTH 1 /* OPCLK_ENA */
360#define WM8904_CLK_SYS_ENA 0x0004 /* CLK_SYS_ENA */
361#define WM8904_CLK_SYS_ENA_MASK 0x0004 /* CLK_SYS_ENA */
362#define WM8904_CLK_SYS_ENA_SHIFT 2 /* CLK_SYS_ENA */
363#define WM8904_CLK_SYS_ENA_WIDTH 1 /* CLK_SYS_ENA */
364#define WM8904_CLK_DSP_ENA 0x0002 /* CLK_DSP_ENA */
365#define WM8904_CLK_DSP_ENA_MASK 0x0002 /* CLK_DSP_ENA */
366#define WM8904_CLK_DSP_ENA_SHIFT 1 /* CLK_DSP_ENA */
367#define WM8904_CLK_DSP_ENA_WIDTH 1 /* CLK_DSP_ENA */
368#define WM8904_TOCLK_ENA 0x0001 /* TOCLK_ENA */
369#define WM8904_TOCLK_ENA_MASK 0x0001 /* TOCLK_ENA */
370#define WM8904_TOCLK_ENA_SHIFT 0 /* TOCLK_ENA */
371#define WM8904_TOCLK_ENA_WIDTH 1 /* TOCLK_ENA */
372
373/*
374 * R24 (0x18) - Audio Interface 0
375 */
376#define WM8904_DACL_DATINV 0x1000 /* DACL_DATINV */
377#define WM8904_DACL_DATINV_MASK 0x1000 /* DACL_DATINV */
378#define WM8904_DACL_DATINV_SHIFT 12 /* DACL_DATINV */
379#define WM8904_DACL_DATINV_WIDTH 1 /* DACL_DATINV */
380#define WM8904_DACR_DATINV 0x0800 /* DACR_DATINV */
381#define WM8904_DACR_DATINV_MASK 0x0800 /* DACR_DATINV */
382#define WM8904_DACR_DATINV_SHIFT 11 /* DACR_DATINV */
383#define WM8904_DACR_DATINV_WIDTH 1 /* DACR_DATINV */
384#define WM8904_DAC_BOOST_MASK 0x0600 /* DAC_BOOST - [10:9] */
385#define WM8904_DAC_BOOST_SHIFT 9 /* DAC_BOOST - [10:9] */
386#define WM8904_DAC_BOOST_WIDTH 2 /* DAC_BOOST - [10:9] */
387#define WM8904_LOOPBACK 0x0100 /* LOOPBACK */
388#define WM8904_LOOPBACK_MASK 0x0100 /* LOOPBACK */
389#define WM8904_LOOPBACK_SHIFT 8 /* LOOPBACK */
390#define WM8904_LOOPBACK_WIDTH 1 /* LOOPBACK */
391#define WM8904_AIFADCL_SRC 0x0080 /* AIFADCL_SRC */
392#define WM8904_AIFADCL_SRC_MASK 0x0080 /* AIFADCL_SRC */
393#define WM8904_AIFADCL_SRC_SHIFT 7 /* AIFADCL_SRC */
394#define WM8904_AIFADCL_SRC_WIDTH 1 /* AIFADCL_SRC */
395#define WM8904_AIFADCR_SRC 0x0040 /* AIFADCR_SRC */
396#define WM8904_AIFADCR_SRC_MASK 0x0040 /* AIFADCR_SRC */
397#define WM8904_AIFADCR_SRC_SHIFT 6 /* AIFADCR_SRC */
398#define WM8904_AIFADCR_SRC_WIDTH 1 /* AIFADCR_SRC */
399#define WM8904_AIFDACL_SRC 0x0020 /* AIFDACL_SRC */
400#define WM8904_AIFDACL_SRC_MASK 0x0020 /* AIFDACL_SRC */
401#define WM8904_AIFDACL_SRC_SHIFT 5 /* AIFDACL_SRC */
402#define WM8904_AIFDACL_SRC_WIDTH 1 /* AIFDACL_SRC */
403#define WM8904_AIFDACR_SRC 0x0010 /* AIFDACR_SRC */
404#define WM8904_AIFDACR_SRC_MASK 0x0010 /* AIFDACR_SRC */
405#define WM8904_AIFDACR_SRC_SHIFT 4 /* AIFDACR_SRC */
406#define WM8904_AIFDACR_SRC_WIDTH 1 /* AIFDACR_SRC */
407#define WM8904_ADC_COMP 0x0008 /* ADC_COMP */
408#define WM8904_ADC_COMP_MASK 0x0008 /* ADC_COMP */
409#define WM8904_ADC_COMP_SHIFT 3 /* ADC_COMP */
410#define WM8904_ADC_COMP_WIDTH 1 /* ADC_COMP */
411#define WM8904_ADC_COMPMODE 0x0004 /* ADC_COMPMODE */
412#define WM8904_ADC_COMPMODE_MASK 0x0004 /* ADC_COMPMODE */
413#define WM8904_ADC_COMPMODE_SHIFT 2 /* ADC_COMPMODE */
414#define WM8904_ADC_COMPMODE_WIDTH 1 /* ADC_COMPMODE */
415#define WM8904_DAC_COMP 0x0002 /* DAC_COMP */
416#define WM8904_DAC_COMP_MASK 0x0002 /* DAC_COMP */
417#define WM8904_DAC_COMP_SHIFT 1 /* DAC_COMP */
418#define WM8904_DAC_COMP_WIDTH 1 /* DAC_COMP */
419#define WM8904_DAC_COMPMODE 0x0001 /* DAC_COMPMODE */
420#define WM8904_DAC_COMPMODE_MASK 0x0001 /* DAC_COMPMODE */
421#define WM8904_DAC_COMPMODE_SHIFT 0 /* DAC_COMPMODE */
422#define WM8904_DAC_COMPMODE_WIDTH 1 /* DAC_COMPMODE */
423
424/*
425 * R25 (0x19) - Audio Interface 1
426 */
427#define WM8904_AIFDAC_TDM 0x2000 /* AIFDAC_TDM */
428#define WM8904_AIFDAC_TDM_MASK 0x2000 /* AIFDAC_TDM */
429#define WM8904_AIFDAC_TDM_SHIFT 13 /* AIFDAC_TDM */
430#define WM8904_AIFDAC_TDM_WIDTH 1 /* AIFDAC_TDM */
431#define WM8904_AIFDAC_TDM_CHAN 0x1000 /* AIFDAC_TDM_CHAN */
432#define WM8904_AIFDAC_TDM_CHAN_MASK 0x1000 /* AIFDAC_TDM_CHAN */
433#define WM8904_AIFDAC_TDM_CHAN_SHIFT 12 /* AIFDAC_TDM_CHAN */
434#define WM8904_AIFDAC_TDM_CHAN_WIDTH 1 /* AIFDAC_TDM_CHAN */
435#define WM8904_AIFADC_TDM 0x0800 /* AIFADC_TDM */
436#define WM8904_AIFADC_TDM_MASK 0x0800 /* AIFADC_TDM */
437#define WM8904_AIFADC_TDM_SHIFT 11 /* AIFADC_TDM */
438#define WM8904_AIFADC_TDM_WIDTH 1 /* AIFADC_TDM */
439#define WM8904_AIFADC_TDM_CHAN 0x0400 /* AIFADC_TDM_CHAN */
440#define WM8904_AIFADC_TDM_CHAN_MASK 0x0400 /* AIFADC_TDM_CHAN */
441#define WM8904_AIFADC_TDM_CHAN_SHIFT 10 /* AIFADC_TDM_CHAN */
442#define WM8904_AIFADC_TDM_CHAN_WIDTH 1 /* AIFADC_TDM_CHAN */
443#define WM8904_AIF_TRIS 0x0100 /* AIF_TRIS */
444#define WM8904_AIF_TRIS_MASK 0x0100 /* AIF_TRIS */
445#define WM8904_AIF_TRIS_SHIFT 8 /* AIF_TRIS */
446#define WM8904_AIF_TRIS_WIDTH 1 /* AIF_TRIS */
447#define WM8904_AIF_BCLK_INV 0x0080 /* AIF_BCLK_INV */
448#define WM8904_AIF_BCLK_INV_MASK 0x0080 /* AIF_BCLK_INV */
449#define WM8904_AIF_BCLK_INV_SHIFT 7 /* AIF_BCLK_INV */
450#define WM8904_AIF_BCLK_INV_WIDTH 1 /* AIF_BCLK_INV */
451#define WM8904_BCLK_DIR 0x0040 /* BCLK_DIR */
452#define WM8904_BCLK_DIR_MASK 0x0040 /* BCLK_DIR */
453#define WM8904_BCLK_DIR_SHIFT 6 /* BCLK_DIR */
454#define WM8904_BCLK_DIR_WIDTH 1 /* BCLK_DIR */
455#define WM8904_AIF_LRCLK_INV 0x0010 /* AIF_LRCLK_INV */
456#define WM8904_AIF_LRCLK_INV_MASK 0x0010 /* AIF_LRCLK_INV */
457#define WM8904_AIF_LRCLK_INV_SHIFT 4 /* AIF_LRCLK_INV */
458#define WM8904_AIF_LRCLK_INV_WIDTH 1 /* AIF_LRCLK_INV */
459#define WM8904_AIF_WL_MASK 0x000C /* AIF_WL - [3:2] */
460#define WM8904_AIF_WL_SHIFT 2 /* AIF_WL - [3:2] */
461#define WM8904_AIF_WL_WIDTH 2 /* AIF_WL - [3:2] */
462#define WM8904_AIF_FMT_MASK 0x0003 /* AIF_FMT - [1:0] */
463#define WM8904_AIF_FMT_SHIFT 0 /* AIF_FMT - [1:0] */
464#define WM8904_AIF_FMT_WIDTH 2 /* AIF_FMT - [1:0] */
465
466/*
467 * R26 (0x1A) - Audio Interface 2
468 */
469#define WM8904_OPCLK_DIV_MASK 0x0F00 /* OPCLK_DIV - [11:8] */
470#define WM8904_OPCLK_DIV_SHIFT 8 /* OPCLK_DIV - [11:8] */
471#define WM8904_OPCLK_DIV_WIDTH 4 /* OPCLK_DIV - [11:8] */
472#define WM8904_BCLK_DIV_MASK 0x001F /* BCLK_DIV - [4:0] */
473#define WM8904_BCLK_DIV_SHIFT 0 /* BCLK_DIV - [4:0] */
474#define WM8904_BCLK_DIV_WIDTH 5 /* BCLK_DIV - [4:0] */
475
476/*
477 * R27 (0x1B) - Audio Interface 3
478 */
479#define WM8904_LRCLK_DIR 0x0800 /* LRCLK_DIR */
480#define WM8904_LRCLK_DIR_MASK 0x0800 /* LRCLK_DIR */
481#define WM8904_LRCLK_DIR_SHIFT 11 /* LRCLK_DIR */
482#define WM8904_LRCLK_DIR_WIDTH 1 /* LRCLK_DIR */
483#define WM8904_LRCLK_RATE_MASK 0x07FF /* LRCLK_RATE - [10:0] */
484#define WM8904_LRCLK_RATE_SHIFT 0 /* LRCLK_RATE - [10:0] */
485#define WM8904_LRCLK_RATE_WIDTH 11 /* LRCLK_RATE - [10:0] */
486
487/*
488 * R30 (0x1E) - DAC Digital Volume Left
489 */
490#define WM8904_DAC_VU 0x0100 /* DAC_VU */
491#define WM8904_DAC_VU_MASK 0x0100 /* DAC_VU */
492#define WM8904_DAC_VU_SHIFT 8 /* DAC_VU */
493#define WM8904_DAC_VU_WIDTH 1 /* DAC_VU */
494#define WM8904_DACL_VOL_MASK 0x00FF /* DACL_VOL - [7:0] */
495#define WM8904_DACL_VOL_SHIFT 0 /* DACL_VOL - [7:0] */
496#define WM8904_DACL_VOL_WIDTH 8 /* DACL_VOL - [7:0] */
497
498/*
499 * R31 (0x1F) - DAC Digital Volume Right
500 */
501#define WM8904_DAC_VU 0x0100 /* DAC_VU */
502#define WM8904_DAC_VU_MASK 0x0100 /* DAC_VU */
503#define WM8904_DAC_VU_SHIFT 8 /* DAC_VU */
504#define WM8904_DAC_VU_WIDTH 1 /* DAC_VU */
505#define WM8904_DACR_VOL_MASK 0x00FF /* DACR_VOL - [7:0] */
506#define WM8904_DACR_VOL_SHIFT 0 /* DACR_VOL - [7:0] */
507#define WM8904_DACR_VOL_WIDTH 8 /* DACR_VOL - [7:0] */
508
509/*
510 * R32 (0x20) - DAC Digital 0
511 */
512#define WM8904_ADCL_DAC_SVOL_MASK 0x0F00 /* ADCL_DAC_SVOL - [11:8] */
513#define WM8904_ADCL_DAC_SVOL_SHIFT 8 /* ADCL_DAC_SVOL - [11:8] */
514#define WM8904_ADCL_DAC_SVOL_WIDTH 4 /* ADCL_DAC_SVOL - [11:8] */
515#define WM8904_ADCR_DAC_SVOL_MASK 0x00F0 /* ADCR_DAC_SVOL - [7:4] */
516#define WM8904_ADCR_DAC_SVOL_SHIFT 4 /* ADCR_DAC_SVOL - [7:4] */
517#define WM8904_ADCR_DAC_SVOL_WIDTH 4 /* ADCR_DAC_SVOL - [7:4] */
518#define WM8904_ADC_TO_DACL_MASK 0x000C /* ADC_TO_DACL - [3:2] */
519#define WM8904_ADC_TO_DACL_SHIFT 2 /* ADC_TO_DACL - [3:2] */
520#define WM8904_ADC_TO_DACL_WIDTH 2 /* ADC_TO_DACL - [3:2] */
521#define WM8904_ADC_TO_DACR_MASK 0x0003 /* ADC_TO_DACR - [1:0] */
522#define WM8904_ADC_TO_DACR_SHIFT 0 /* ADC_TO_DACR - [1:0] */
523#define WM8904_ADC_TO_DACR_WIDTH 2 /* ADC_TO_DACR - [1:0] */
524
525/*
526 * R33 (0x21) - DAC Digital 1
527 */
528#define WM8904_DAC_MONO 0x1000 /* DAC_MONO */
529#define WM8904_DAC_MONO_MASK 0x1000 /* DAC_MONO */
530#define WM8904_DAC_MONO_SHIFT 12 /* DAC_MONO */
531#define WM8904_DAC_MONO_WIDTH 1 /* DAC_MONO */
532#define WM8904_DAC_SB_FILT 0x0800 /* DAC_SB_FILT */
533#define WM8904_DAC_SB_FILT_MASK 0x0800 /* DAC_SB_FILT */
534#define WM8904_DAC_SB_FILT_SHIFT 11 /* DAC_SB_FILT */
535#define WM8904_DAC_SB_FILT_WIDTH 1 /* DAC_SB_FILT */
536#define WM8904_DAC_MUTERATE 0x0400 /* DAC_MUTERATE */
537#define WM8904_DAC_MUTERATE_MASK 0x0400 /* DAC_MUTERATE */
538#define WM8904_DAC_MUTERATE_SHIFT 10 /* DAC_MUTERATE */
539#define WM8904_DAC_MUTERATE_WIDTH 1 /* DAC_MUTERATE */
540#define WM8904_DAC_UNMUTE_RAMP 0x0200 /* DAC_UNMUTE_RAMP */
541#define WM8904_DAC_UNMUTE_RAMP_MASK 0x0200 /* DAC_UNMUTE_RAMP */
542#define WM8904_DAC_UNMUTE_RAMP_SHIFT 9 /* DAC_UNMUTE_RAMP */
543#define WM8904_DAC_UNMUTE_RAMP_WIDTH 1 /* DAC_UNMUTE_RAMP */
544#define WM8904_DAC_OSR128 0x0040 /* DAC_OSR128 */
545#define WM8904_DAC_OSR128_MASK 0x0040 /* DAC_OSR128 */
546#define WM8904_DAC_OSR128_SHIFT 6 /* DAC_OSR128 */
547#define WM8904_DAC_OSR128_WIDTH 1 /* DAC_OSR128 */
548#define WM8904_DAC_MUTE 0x0008 /* DAC_MUTE */
549#define WM8904_DAC_MUTE_MASK 0x0008 /* DAC_MUTE */
550#define WM8904_DAC_MUTE_SHIFT 3 /* DAC_MUTE */
551#define WM8904_DAC_MUTE_WIDTH 1 /* DAC_MUTE */
552#define WM8904_DEEMPH_MASK 0x0006 /* DEEMPH - [2:1] */
553#define WM8904_DEEMPH_SHIFT 1 /* DEEMPH - [2:1] */
554#define WM8904_DEEMPH_WIDTH 2 /* DEEMPH - [2:1] */
555
556/*
557 * R36 (0x24) - ADC Digital Volume Left
558 */
559#define WM8904_ADC_VU 0x0100 /* ADC_VU */
560#define WM8904_ADC_VU_MASK 0x0100 /* ADC_VU */
561#define WM8904_ADC_VU_SHIFT 8 /* ADC_VU */
562#define WM8904_ADC_VU_WIDTH 1 /* ADC_VU */
563#define WM8904_ADCL_VOL_MASK 0x00FF /* ADCL_VOL - [7:0] */
564#define WM8904_ADCL_VOL_SHIFT 0 /* ADCL_VOL - [7:0] */
565#define WM8904_ADCL_VOL_WIDTH 8 /* ADCL_VOL - [7:0] */
566
567/*
568 * R37 (0x25) - ADC Digital Volume Right
569 */
570#define WM8904_ADC_VU 0x0100 /* ADC_VU */
571#define WM8904_ADC_VU_MASK 0x0100 /* ADC_VU */
572#define WM8904_ADC_VU_SHIFT 8 /* ADC_VU */
573#define WM8904_ADC_VU_WIDTH 1 /* ADC_VU */
574#define WM8904_ADCR_VOL_MASK 0x00FF /* ADCR_VOL - [7:0] */
575#define WM8904_ADCR_VOL_SHIFT 0 /* ADCR_VOL - [7:0] */
576#define WM8904_ADCR_VOL_WIDTH 8 /* ADCR_VOL - [7:0] */
577
578/*
579 * R38 (0x26) - ADC Digital 0
580 */
581#define WM8904_ADC_HPF_CUT_MASK 0x0060 /* ADC_HPF_CUT - [6:5] */
582#define WM8904_ADC_HPF_CUT_SHIFT 5 /* ADC_HPF_CUT - [6:5] */
583#define WM8904_ADC_HPF_CUT_WIDTH 2 /* ADC_HPF_CUT - [6:5] */
584#define WM8904_ADC_HPF 0x0010 /* ADC_HPF */
585#define WM8904_ADC_HPF_MASK 0x0010 /* ADC_HPF */
586#define WM8904_ADC_HPF_SHIFT 4 /* ADC_HPF */
587#define WM8904_ADC_HPF_WIDTH 1 /* ADC_HPF */
588#define WM8904_ADCL_DATINV 0x0002 /* ADCL_DATINV */
589#define WM8904_ADCL_DATINV_MASK 0x0002 /* ADCL_DATINV */
590#define WM8904_ADCL_DATINV_SHIFT 1 /* ADCL_DATINV */
591#define WM8904_ADCL_DATINV_WIDTH 1 /* ADCL_DATINV */
592#define WM8904_ADCR_DATINV 0x0001 /* ADCR_DATINV */
593#define WM8904_ADCR_DATINV_MASK 0x0001 /* ADCR_DATINV */
594#define WM8904_ADCR_DATINV_SHIFT 0 /* ADCR_DATINV */
595#define WM8904_ADCR_DATINV_WIDTH 1 /* ADCR_DATINV */
596
597/*
598 * R39 (0x27) - Digital Microphone 0
599 */
600#define WM8904_DMIC_ENA 0x1000 /* DMIC_ENA */
601#define WM8904_DMIC_ENA_MASK 0x1000 /* DMIC_ENA */
602#define WM8904_DMIC_ENA_SHIFT 12 /* DMIC_ENA */
603#define WM8904_DMIC_ENA_WIDTH 1 /* DMIC_ENA */
604#define WM8904_DMIC_SRC 0x0800 /* DMIC_SRC */
605#define WM8904_DMIC_SRC_MASK 0x0800 /* DMIC_SRC */
606#define WM8904_DMIC_SRC_SHIFT 11 /* DMIC_SRC */
607#define WM8904_DMIC_SRC_WIDTH 1 /* DMIC_SRC */
608
609/*
610 * R40 (0x28) - DRC 0
611 */
612#define WM8904_DRC_ENA 0x8000 /* DRC_ENA */
613#define WM8904_DRC_ENA_MASK 0x8000 /* DRC_ENA */
614#define WM8904_DRC_ENA_SHIFT 15 /* DRC_ENA */
615#define WM8904_DRC_ENA_WIDTH 1 /* DRC_ENA */
616#define WM8904_DRC_DAC_PATH 0x4000 /* DRC_DAC_PATH */
617#define WM8904_DRC_DAC_PATH_MASK 0x4000 /* DRC_DAC_PATH */
618#define WM8904_DRC_DAC_PATH_SHIFT 14 /* DRC_DAC_PATH */
619#define WM8904_DRC_DAC_PATH_WIDTH 1 /* DRC_DAC_PATH */
620#define WM8904_DRC_GS_HYST_LVL_MASK 0x1800 /* DRC_GS_HYST_LVL - [12:11] */
621#define WM8904_DRC_GS_HYST_LVL_SHIFT 11 /* DRC_GS_HYST_LVL - [12:11] */
622#define WM8904_DRC_GS_HYST_LVL_WIDTH 2 /* DRC_GS_HYST_LVL - [12:11] */
623#define WM8904_DRC_STARTUP_GAIN_MASK 0x07C0 /* DRC_STARTUP_GAIN - [10:6] */
624#define WM8904_DRC_STARTUP_GAIN_SHIFT 6 /* DRC_STARTUP_GAIN - [10:6] */
625#define WM8904_DRC_STARTUP_GAIN_WIDTH 5 /* DRC_STARTUP_GAIN - [10:6] */
626#define WM8904_DRC_FF_DELAY 0x0020 /* DRC_FF_DELAY */
627#define WM8904_DRC_FF_DELAY_MASK 0x0020 /* DRC_FF_DELAY */
628#define WM8904_DRC_FF_DELAY_SHIFT 5 /* DRC_FF_DELAY */
629#define WM8904_DRC_FF_DELAY_WIDTH 1 /* DRC_FF_DELAY */
630#define WM8904_DRC_GS_ENA 0x0008 /* DRC_GS_ENA */
631#define WM8904_DRC_GS_ENA_MASK 0x0008 /* DRC_GS_ENA */
632#define WM8904_DRC_GS_ENA_SHIFT 3 /* DRC_GS_ENA */
633#define WM8904_DRC_GS_ENA_WIDTH 1 /* DRC_GS_ENA */
634#define WM8904_DRC_QR 0x0004 /* DRC_QR */
635#define WM8904_DRC_QR_MASK 0x0004 /* DRC_QR */
636#define WM8904_DRC_QR_SHIFT 2 /* DRC_QR */
637#define WM8904_DRC_QR_WIDTH 1 /* DRC_QR */
638#define WM8904_DRC_ANTICLIP 0x0002 /* DRC_ANTICLIP */
639#define WM8904_DRC_ANTICLIP_MASK 0x0002 /* DRC_ANTICLIP */
640#define WM8904_DRC_ANTICLIP_SHIFT 1 /* DRC_ANTICLIP */
641#define WM8904_DRC_ANTICLIP_WIDTH 1 /* DRC_ANTICLIP */
642#define WM8904_DRC_GS_HYST 0x0001 /* DRC_GS_HYST */
643#define WM8904_DRC_GS_HYST_MASK 0x0001 /* DRC_GS_HYST */
644#define WM8904_DRC_GS_HYST_SHIFT 0 /* DRC_GS_HYST */
645#define WM8904_DRC_GS_HYST_WIDTH 1 /* DRC_GS_HYST */
646
647/*
648 * R41 (0x29) - DRC 1
649 */
650#define WM8904_DRC_ATK_MASK 0xF000 /* DRC_ATK - [15:12] */
651#define WM8904_DRC_ATK_SHIFT 12 /* DRC_ATK - [15:12] */
652#define WM8904_DRC_ATK_WIDTH 4 /* DRC_ATK - [15:12] */
653#define WM8904_DRC_DCY_MASK 0x0F00 /* DRC_DCY - [11:8] */
654#define WM8904_DRC_DCY_SHIFT 8 /* DRC_DCY - [11:8] */
655#define WM8904_DRC_DCY_WIDTH 4 /* DRC_DCY - [11:8] */
656#define WM8904_DRC_QR_THR_MASK 0x00C0 /* DRC_QR_THR - [7:6] */
657#define WM8904_DRC_QR_THR_SHIFT 6 /* DRC_QR_THR - [7:6] */
658#define WM8904_DRC_QR_THR_WIDTH 2 /* DRC_QR_THR - [7:6] */
659#define WM8904_DRC_QR_DCY_MASK 0x0030 /* DRC_QR_DCY - [5:4] */
660#define WM8904_DRC_QR_DCY_SHIFT 4 /* DRC_QR_DCY - [5:4] */
661#define WM8904_DRC_QR_DCY_WIDTH 2 /* DRC_QR_DCY - [5:4] */
662#define WM8904_DRC_MINGAIN_MASK 0x000C /* DRC_MINGAIN - [3:2] */
663#define WM8904_DRC_MINGAIN_SHIFT 2 /* DRC_MINGAIN - [3:2] */
664#define WM8904_DRC_MINGAIN_WIDTH 2 /* DRC_MINGAIN - [3:2] */
665#define WM8904_DRC_MAXGAIN_MASK 0x0003 /* DRC_MAXGAIN - [1:0] */
666#define WM8904_DRC_MAXGAIN_SHIFT 0 /* DRC_MAXGAIN - [1:0] */
667#define WM8904_DRC_MAXGAIN_WIDTH 2 /* DRC_MAXGAIN - [1:0] */
668
669/*
670 * R42 (0x2A) - DRC 2
671 */
672#define WM8904_DRC_HI_COMP_MASK 0x0038 /* DRC_HI_COMP - [5:3] */
673#define WM8904_DRC_HI_COMP_SHIFT 3 /* DRC_HI_COMP - [5:3] */
674#define WM8904_DRC_HI_COMP_WIDTH 3 /* DRC_HI_COMP - [5:3] */
675#define WM8904_DRC_LO_COMP_MASK 0x0007 /* DRC_LO_COMP - [2:0] */
676#define WM8904_DRC_LO_COMP_SHIFT 0 /* DRC_LO_COMP - [2:0] */
677#define WM8904_DRC_LO_COMP_WIDTH 3 /* DRC_LO_COMP - [2:0] */
678
679/*
680 * R43 (0x2B) - DRC 3
681 */
682#define WM8904_DRC_KNEE_IP_MASK 0x07E0 /* DRC_KNEE_IP - [10:5] */
683#define WM8904_DRC_KNEE_IP_SHIFT 5 /* DRC_KNEE_IP - [10:5] */
684#define WM8904_DRC_KNEE_IP_WIDTH 6 /* DRC_KNEE_IP - [10:5] */
685#define WM8904_DRC_KNEE_OP_MASK 0x001F /* DRC_KNEE_OP - [4:0] */
686#define WM8904_DRC_KNEE_OP_SHIFT 0 /* DRC_KNEE_OP - [4:0] */
687#define WM8904_DRC_KNEE_OP_WIDTH 5 /* DRC_KNEE_OP - [4:0] */
688
689/*
690 * R44 (0x2C) - Analogue Left Input 0
691 */
692#define WM8904_LINMUTE 0x0080 /* LINMUTE */
693#define WM8904_LINMUTE_MASK 0x0080 /* LINMUTE */
694#define WM8904_LINMUTE_SHIFT 7 /* LINMUTE */
695#define WM8904_LINMUTE_WIDTH 1 /* LINMUTE */
696#define WM8904_LIN_VOL_MASK 0x001F /* LIN_VOL - [4:0] */
697#define WM8904_LIN_VOL_SHIFT 0 /* LIN_VOL - [4:0] */
698#define WM8904_LIN_VOL_WIDTH 5 /* LIN_VOL - [4:0] */
699
700/*
701 * R45 (0x2D) - Analogue Right Input 0
702 */
703#define WM8904_RINMUTE 0x0080 /* RINMUTE */
704#define WM8904_RINMUTE_MASK 0x0080 /* RINMUTE */
705#define WM8904_RINMUTE_SHIFT 7 /* RINMUTE */
706#define WM8904_RINMUTE_WIDTH 1 /* RINMUTE */
707#define WM8904_RIN_VOL_MASK 0x001F /* RIN_VOL - [4:0] */
708#define WM8904_RIN_VOL_SHIFT 0 /* RIN_VOL - [4:0] */
709#define WM8904_RIN_VOL_WIDTH 5 /* RIN_VOL - [4:0] */
710
711/*
712 * R46 (0x2E) - Analogue Left Input 1
713 */
714#define WM8904_INL_CM_ENA 0x0040 /* INL_CM_ENA */
715#define WM8904_INL_CM_ENA_MASK 0x0040 /* INL_CM_ENA */
716#define WM8904_INL_CM_ENA_SHIFT 6 /* INL_CM_ENA */
717#define WM8904_INL_CM_ENA_WIDTH 1 /* INL_CM_ENA */
718#define WM8904_L_IP_SEL_N_MASK 0x0030 /* L_IP_SEL_N - [5:4] */
719#define WM8904_L_IP_SEL_N_SHIFT 4 /* L_IP_SEL_N - [5:4] */
720#define WM8904_L_IP_SEL_N_WIDTH 2 /* L_IP_SEL_N - [5:4] */
721#define WM8904_L_IP_SEL_P_MASK 0x000C /* L_IP_SEL_P - [3:2] */
722#define WM8904_L_IP_SEL_P_SHIFT 2 /* L_IP_SEL_P - [3:2] */
723#define WM8904_L_IP_SEL_P_WIDTH 2 /* L_IP_SEL_P - [3:2] */
724#define WM8904_L_MODE_MASK 0x0003 /* L_MODE - [1:0] */
725#define WM8904_L_MODE_SHIFT 0 /* L_MODE - [1:0] */
726#define WM8904_L_MODE_WIDTH 2 /* L_MODE - [1:0] */
727
728/*
729 * R47 (0x2F) - Analogue Right Input 1
730 */
731#define WM8904_INR_CM_ENA 0x0040 /* INR_CM_ENA */
732#define WM8904_INR_CM_ENA_MASK 0x0040 /* INR_CM_ENA */
733#define WM8904_INR_CM_ENA_SHIFT 6 /* INR_CM_ENA */
734#define WM8904_INR_CM_ENA_WIDTH 1 /* INR_CM_ENA */
735#define WM8904_R_IP_SEL_N_MASK 0x0030 /* R_IP_SEL_N - [5:4] */
736#define WM8904_R_IP_SEL_N_SHIFT 4 /* R_IP_SEL_N - [5:4] */
737#define WM8904_R_IP_SEL_N_WIDTH 2 /* R_IP_SEL_N - [5:4] */
738#define WM8904_R_IP_SEL_P_MASK 0x000C /* R_IP_SEL_P - [3:2] */
739#define WM8904_R_IP_SEL_P_SHIFT 2 /* R_IP_SEL_P - [3:2] */
740#define WM8904_R_IP_SEL_P_WIDTH 2 /* R_IP_SEL_P - [3:2] */
741#define WM8904_R_MODE_MASK 0x0003 /* R_MODE - [1:0] */
742#define WM8904_R_MODE_SHIFT 0 /* R_MODE - [1:0] */
743#define WM8904_R_MODE_WIDTH 2 /* R_MODE - [1:0] */
744
745/*
746 * R57 (0x39) - Analogue OUT1 Left
747 */
748#define WM8904_HPOUTL_MUTE 0x0100 /* HPOUTL_MUTE */
749#define WM8904_HPOUTL_MUTE_MASK 0x0100 /* HPOUTL_MUTE */
750#define WM8904_HPOUTL_MUTE_SHIFT 8 /* HPOUTL_MUTE */
751#define WM8904_HPOUTL_MUTE_WIDTH 1 /* HPOUTL_MUTE */
752#define WM8904_HPOUT_VU 0x0080 /* HPOUT_VU */
753#define WM8904_HPOUT_VU_MASK 0x0080 /* HPOUT_VU */
754#define WM8904_HPOUT_VU_SHIFT 7 /* HPOUT_VU */
755#define WM8904_HPOUT_VU_WIDTH 1 /* HPOUT_VU */
756#define WM8904_HPOUTLZC 0x0040 /* HPOUTLZC */
757#define WM8904_HPOUTLZC_MASK 0x0040 /* HPOUTLZC */
758#define WM8904_HPOUTLZC_SHIFT 6 /* HPOUTLZC */
759#define WM8904_HPOUTLZC_WIDTH 1 /* HPOUTLZC */
760#define WM8904_HPOUTL_VOL_MASK 0x003F /* HPOUTL_VOL - [5:0] */
761#define WM8904_HPOUTL_VOL_SHIFT 0 /* HPOUTL_VOL - [5:0] */
762#define WM8904_HPOUTL_VOL_WIDTH 6 /* HPOUTL_VOL - [5:0] */
763
764/*
765 * R58 (0x3A) - Analogue OUT1 Right
766 */
767#define WM8904_HPOUTR_MUTE 0x0100 /* HPOUTR_MUTE */
768#define WM8904_HPOUTR_MUTE_MASK 0x0100 /* HPOUTR_MUTE */
769#define WM8904_HPOUTR_MUTE_SHIFT 8 /* HPOUTR_MUTE */
770#define WM8904_HPOUTR_MUTE_WIDTH 1 /* HPOUTR_MUTE */
771#define WM8904_HPOUT_VU 0x0080 /* HPOUT_VU */
772#define WM8904_HPOUT_VU_MASK 0x0080 /* HPOUT_VU */
773#define WM8904_HPOUT_VU_SHIFT 7 /* HPOUT_VU */
774#define WM8904_HPOUT_VU_WIDTH 1 /* HPOUT_VU */
775#define WM8904_HPOUTRZC 0x0040 /* HPOUTRZC */
776#define WM8904_HPOUTRZC_MASK 0x0040 /* HPOUTRZC */
777#define WM8904_HPOUTRZC_SHIFT 6 /* HPOUTRZC */
778#define WM8904_HPOUTRZC_WIDTH 1 /* HPOUTRZC */
779#define WM8904_HPOUTR_VOL_MASK 0x003F /* HPOUTR_VOL - [5:0] */
780#define WM8904_HPOUTR_VOL_SHIFT 0 /* HPOUTR_VOL - [5:0] */
781#define WM8904_HPOUTR_VOL_WIDTH 6 /* HPOUTR_VOL - [5:0] */
782
783/*
784 * R59 (0x3B) - Analogue OUT2 Left
785 */
786#define WM8904_LINEOUTL_MUTE 0x0100 /* LINEOUTL_MUTE */
787#define WM8904_LINEOUTL_MUTE_MASK 0x0100 /* LINEOUTL_MUTE */
788#define WM8904_LINEOUTL_MUTE_SHIFT 8 /* LINEOUTL_MUTE */
789#define WM8904_LINEOUTL_MUTE_WIDTH 1 /* LINEOUTL_MUTE */
790#define WM8904_LINEOUT_VU 0x0080 /* LINEOUT_VU */
791#define WM8904_LINEOUT_VU_MASK 0x0080 /* LINEOUT_VU */
792#define WM8904_LINEOUT_VU_SHIFT 7 /* LINEOUT_VU */
793#define WM8904_LINEOUT_VU_WIDTH 1 /* LINEOUT_VU */
794#define WM8904_LINEOUTLZC 0x0040 /* LINEOUTLZC */
795#define WM8904_LINEOUTLZC_MASK 0x0040 /* LINEOUTLZC */
796#define WM8904_LINEOUTLZC_SHIFT 6 /* LINEOUTLZC */
797#define WM8904_LINEOUTLZC_WIDTH 1 /* LINEOUTLZC */
798#define WM8904_LINEOUTL_VOL_MASK 0x003F /* LINEOUTL_VOL - [5:0] */
799#define WM8904_LINEOUTL_VOL_SHIFT 0 /* LINEOUTL_VOL - [5:0] */
800#define WM8904_LINEOUTL_VOL_WIDTH 6 /* LINEOUTL_VOL - [5:0] */
801
802/*
803 * R60 (0x3C) - Analogue OUT2 Right
804 */
805#define WM8904_LINEOUTR_MUTE 0x0100 /* LINEOUTR_MUTE */
806#define WM8904_LINEOUTR_MUTE_MASK 0x0100 /* LINEOUTR_MUTE */
807#define WM8904_LINEOUTR_MUTE_SHIFT 8 /* LINEOUTR_MUTE */
808#define WM8904_LINEOUTR_MUTE_WIDTH 1 /* LINEOUTR_MUTE */
809#define WM8904_LINEOUT_VU 0x0080 /* LINEOUT_VU */
810#define WM8904_LINEOUT_VU_MASK 0x0080 /* LINEOUT_VU */
811#define WM8904_LINEOUT_VU_SHIFT 7 /* LINEOUT_VU */
812#define WM8904_LINEOUT_VU_WIDTH 1 /* LINEOUT_VU */
813#define WM8904_LINEOUTRZC 0x0040 /* LINEOUTRZC */
814#define WM8904_LINEOUTRZC_MASK 0x0040 /* LINEOUTRZC */
815#define WM8904_LINEOUTRZC_SHIFT 6 /* LINEOUTRZC */
816#define WM8904_LINEOUTRZC_WIDTH 1 /* LINEOUTRZC */
817#define WM8904_LINEOUTR_VOL_MASK 0x003F /* LINEOUTR_VOL - [5:0] */
818#define WM8904_LINEOUTR_VOL_SHIFT 0 /* LINEOUTR_VOL - [5:0] */
819#define WM8904_LINEOUTR_VOL_WIDTH 6 /* LINEOUTR_VOL - [5:0] */
820
821/*
822 * R61 (0x3D) - Analogue OUT12 ZC
823 */
824#define WM8904_HPL_BYP_ENA 0x0008 /* HPL_BYP_ENA */
825#define WM8904_HPL_BYP_ENA_MASK 0x0008 /* HPL_BYP_ENA */
826#define WM8904_HPL_BYP_ENA_SHIFT 3 /* HPL_BYP_ENA */
827#define WM8904_HPL_BYP_ENA_WIDTH 1 /* HPL_BYP_ENA */
828#define WM8904_HPR_BYP_ENA 0x0004 /* HPR_BYP_ENA */
829#define WM8904_HPR_BYP_ENA_MASK 0x0004 /* HPR_BYP_ENA */
830#define WM8904_HPR_BYP_ENA_SHIFT 2 /* HPR_BYP_ENA */
831#define WM8904_HPR_BYP_ENA_WIDTH 1 /* HPR_BYP_ENA */
832#define WM8904_LINEOUTL_BYP_ENA 0x0002 /* LINEOUTL_BYP_ENA */
833#define WM8904_LINEOUTL_BYP_ENA_MASK 0x0002 /* LINEOUTL_BYP_ENA */
834#define WM8904_LINEOUTL_BYP_ENA_SHIFT 1 /* LINEOUTL_BYP_ENA */
835#define WM8904_LINEOUTL_BYP_ENA_WIDTH 1 /* LINEOUTL_BYP_ENA */
836#define WM8904_LINEOUTR_BYP_ENA 0x0001 /* LINEOUTR_BYP_ENA */
837#define WM8904_LINEOUTR_BYP_ENA_MASK 0x0001 /* LINEOUTR_BYP_ENA */
838#define WM8904_LINEOUTR_BYP_ENA_SHIFT 0 /* LINEOUTR_BYP_ENA */
839#define WM8904_LINEOUTR_BYP_ENA_WIDTH 1 /* LINEOUTR_BYP_ENA */
840
841/*
842 * R67 (0x43) - DC Servo 0
843 */
844#define WM8904_DCS_ENA_CHAN_3 0x0008 /* DCS_ENA_CHAN_3 */
845#define WM8904_DCS_ENA_CHAN_3_MASK 0x0008 /* DCS_ENA_CHAN_3 */
846#define WM8904_DCS_ENA_CHAN_3_SHIFT 3 /* DCS_ENA_CHAN_3 */
847#define WM8904_DCS_ENA_CHAN_3_WIDTH 1 /* DCS_ENA_CHAN_3 */
848#define WM8904_DCS_ENA_CHAN_2 0x0004 /* DCS_ENA_CHAN_2 */
849#define WM8904_DCS_ENA_CHAN_2_MASK 0x0004 /* DCS_ENA_CHAN_2 */
850#define WM8904_DCS_ENA_CHAN_2_SHIFT 2 /* DCS_ENA_CHAN_2 */
851#define WM8904_DCS_ENA_CHAN_2_WIDTH 1 /* DCS_ENA_CHAN_2 */
852#define WM8904_DCS_ENA_CHAN_1 0x0002 /* DCS_ENA_CHAN_1 */
853#define WM8904_DCS_ENA_CHAN_1_MASK 0x0002 /* DCS_ENA_CHAN_1 */
854#define WM8904_DCS_ENA_CHAN_1_SHIFT 1 /* DCS_ENA_CHAN_1 */
855#define WM8904_DCS_ENA_CHAN_1_WIDTH 1 /* DCS_ENA_CHAN_1 */
856#define WM8904_DCS_ENA_CHAN_0 0x0001 /* DCS_ENA_CHAN_0 */
857#define WM8904_DCS_ENA_CHAN_0_MASK 0x0001 /* DCS_ENA_CHAN_0 */
858#define WM8904_DCS_ENA_CHAN_0_SHIFT 0 /* DCS_ENA_CHAN_0 */
859#define WM8904_DCS_ENA_CHAN_0_WIDTH 1 /* DCS_ENA_CHAN_0 */
860
861/*
862 * R68 (0x44) - DC Servo 1
863 */
864#define WM8904_DCS_TRIG_SINGLE_3 0x8000 /* DCS_TRIG_SINGLE_3 */
865#define WM8904_DCS_TRIG_SINGLE_3_MASK 0x8000 /* DCS_TRIG_SINGLE_3 */
866#define WM8904_DCS_TRIG_SINGLE_3_SHIFT 15 /* DCS_TRIG_SINGLE_3 */
867#define WM8904_DCS_TRIG_SINGLE_3_WIDTH 1 /* DCS_TRIG_SINGLE_3 */
868#define WM8904_DCS_TRIG_SINGLE_2 0x4000 /* DCS_TRIG_SINGLE_2 */
869#define WM8904_DCS_TRIG_SINGLE_2_MASK 0x4000 /* DCS_TRIG_SINGLE_2 */
870#define WM8904_DCS_TRIG_SINGLE_2_SHIFT 14 /* DCS_TRIG_SINGLE_2 */
871#define WM8904_DCS_TRIG_SINGLE_2_WIDTH 1 /* DCS_TRIG_SINGLE_2 */
872#define WM8904_DCS_TRIG_SINGLE_1 0x2000 /* DCS_TRIG_SINGLE_1 */
873#define WM8904_DCS_TRIG_SINGLE_1_MASK 0x2000 /* DCS_TRIG_SINGLE_1 */
874#define WM8904_DCS_TRIG_SINGLE_1_SHIFT 13 /* DCS_TRIG_SINGLE_1 */
875#define WM8904_DCS_TRIG_SINGLE_1_WIDTH 1 /* DCS_TRIG_SINGLE_1 */
876#define WM8904_DCS_TRIG_SINGLE_0 0x1000 /* DCS_TRIG_SINGLE_0 */
877#define WM8904_DCS_TRIG_SINGLE_0_MASK 0x1000 /* DCS_TRIG_SINGLE_0 */
878#define WM8904_DCS_TRIG_SINGLE_0_SHIFT 12 /* DCS_TRIG_SINGLE_0 */
879#define WM8904_DCS_TRIG_SINGLE_0_WIDTH 1 /* DCS_TRIG_SINGLE_0 */
880#define WM8904_DCS_TRIG_SERIES_3 0x0800 /* DCS_TRIG_SERIES_3 */
881#define WM8904_DCS_TRIG_SERIES_3_MASK 0x0800 /* DCS_TRIG_SERIES_3 */
882#define WM8904_DCS_TRIG_SERIES_3_SHIFT 11 /* DCS_TRIG_SERIES_3 */
883#define WM8904_DCS_TRIG_SERIES_3_WIDTH 1 /* DCS_TRIG_SERIES_3 */
884#define WM8904_DCS_TRIG_SERIES_2 0x0400 /* DCS_TRIG_SERIES_2 */
885#define WM8904_DCS_TRIG_SERIES_2_MASK 0x0400 /* DCS_TRIG_SERIES_2 */
886#define WM8904_DCS_TRIG_SERIES_2_SHIFT 10 /* DCS_TRIG_SERIES_2 */
887#define WM8904_DCS_TRIG_SERIES_2_WIDTH 1 /* DCS_TRIG_SERIES_2 */
888#define WM8904_DCS_TRIG_SERIES_1 0x0200 /* DCS_TRIG_SERIES_1 */
889#define WM8904_DCS_TRIG_SERIES_1_MASK 0x0200 /* DCS_TRIG_SERIES_1 */
890#define WM8904_DCS_TRIG_SERIES_1_SHIFT 9 /* DCS_TRIG_SERIES_1 */
891#define WM8904_DCS_TRIG_SERIES_1_WIDTH 1 /* DCS_TRIG_SERIES_1 */
892#define WM8904_DCS_TRIG_SERIES_0 0x0100 /* DCS_TRIG_SERIES_0 */
893#define WM8904_DCS_TRIG_SERIES_0_MASK 0x0100 /* DCS_TRIG_SERIES_0 */
894#define WM8904_DCS_TRIG_SERIES_0_SHIFT 8 /* DCS_TRIG_SERIES_0 */
895#define WM8904_DCS_TRIG_SERIES_0_WIDTH 1 /* DCS_TRIG_SERIES_0 */
896#define WM8904_DCS_TRIG_STARTUP_3 0x0080 /* DCS_TRIG_STARTUP_3 */
897#define WM8904_DCS_TRIG_STARTUP_3_MASK 0x0080 /* DCS_TRIG_STARTUP_3 */
898#define WM8904_DCS_TRIG_STARTUP_3_SHIFT 7 /* DCS_TRIG_STARTUP_3 */
899#define WM8904_DCS_TRIG_STARTUP_3_WIDTH 1 /* DCS_TRIG_STARTUP_3 */
900#define WM8904_DCS_TRIG_STARTUP_2 0x0040 /* DCS_TRIG_STARTUP_2 */
901#define WM8904_DCS_TRIG_STARTUP_2_MASK 0x0040 /* DCS_TRIG_STARTUP_2 */
902#define WM8904_DCS_TRIG_STARTUP_2_SHIFT 6 /* DCS_TRIG_STARTUP_2 */
903#define WM8904_DCS_TRIG_STARTUP_2_WIDTH 1 /* DCS_TRIG_STARTUP_2 */
904#define WM8904_DCS_TRIG_STARTUP_1 0x0020 /* DCS_TRIG_STARTUP_1 */
905#define WM8904_DCS_TRIG_STARTUP_1_MASK 0x0020 /* DCS_TRIG_STARTUP_1 */
906#define WM8904_DCS_TRIG_STARTUP_1_SHIFT 5 /* DCS_TRIG_STARTUP_1 */
907#define WM8904_DCS_TRIG_STARTUP_1_WIDTH 1 /* DCS_TRIG_STARTUP_1 */
908#define WM8904_DCS_TRIG_STARTUP_0 0x0010 /* DCS_TRIG_STARTUP_0 */
909#define WM8904_DCS_TRIG_STARTUP_0_MASK 0x0010 /* DCS_TRIG_STARTUP_0 */
910#define WM8904_DCS_TRIG_STARTUP_0_SHIFT 4 /* DCS_TRIG_STARTUP_0 */
911#define WM8904_DCS_TRIG_STARTUP_0_WIDTH 1 /* DCS_TRIG_STARTUP_0 */
912#define WM8904_DCS_TRIG_DAC_WR_3 0x0008 /* DCS_TRIG_DAC_WR_3 */
913#define WM8904_DCS_TRIG_DAC_WR_3_MASK 0x0008 /* DCS_TRIG_DAC_WR_3 */
914#define WM8904_DCS_TRIG_DAC_WR_3_SHIFT 3 /* DCS_TRIG_DAC_WR_3 */
915#define WM8904_DCS_TRIG_DAC_WR_3_WIDTH 1 /* DCS_TRIG_DAC_WR_3 */
916#define WM8904_DCS_TRIG_DAC_WR_2 0x0004 /* DCS_TRIG_DAC_WR_2 */
917#define WM8904_DCS_TRIG_DAC_WR_2_MASK 0x0004 /* DCS_TRIG_DAC_WR_2 */
918#define WM8904_DCS_TRIG_DAC_WR_2_SHIFT 2 /* DCS_TRIG_DAC_WR_2 */
919#define WM8904_DCS_TRIG_DAC_WR_2_WIDTH 1 /* DCS_TRIG_DAC_WR_2 */
920#define WM8904_DCS_TRIG_DAC_WR_1 0x0002 /* DCS_TRIG_DAC_WR_1 */
921#define WM8904_DCS_TRIG_DAC_WR_1_MASK 0x0002 /* DCS_TRIG_DAC_WR_1 */
922#define WM8904_DCS_TRIG_DAC_WR_1_SHIFT 1 /* DCS_TRIG_DAC_WR_1 */
923#define WM8904_DCS_TRIG_DAC_WR_1_WIDTH 1 /* DCS_TRIG_DAC_WR_1 */
924#define WM8904_DCS_TRIG_DAC_WR_0 0x0001 /* DCS_TRIG_DAC_WR_0 */
925#define WM8904_DCS_TRIG_DAC_WR_0_MASK 0x0001 /* DCS_TRIG_DAC_WR_0 */
926#define WM8904_DCS_TRIG_DAC_WR_0_SHIFT 0 /* DCS_TRIG_DAC_WR_0 */
927#define WM8904_DCS_TRIG_DAC_WR_0_WIDTH 1 /* DCS_TRIG_DAC_WR_0 */
928
929/*
930 * R69 (0x45) - DC Servo 2
931 */
932#define WM8904_DCS_TIMER_PERIOD_23_MASK 0x0F00 /* DCS_TIMER_PERIOD_23 - [11:8] */
933#define WM8904_DCS_TIMER_PERIOD_23_SHIFT 8 /* DCS_TIMER_PERIOD_23 - [11:8] */
934#define WM8904_DCS_TIMER_PERIOD_23_WIDTH 4 /* DCS_TIMER_PERIOD_23 - [11:8] */
935#define WM8904_DCS_TIMER_PERIOD_01_MASK 0x000F /* DCS_TIMER_PERIOD_01 - [3:0] */
936#define WM8904_DCS_TIMER_PERIOD_01_SHIFT 0 /* DCS_TIMER_PERIOD_01 - [3:0] */
937#define WM8904_DCS_TIMER_PERIOD_01_WIDTH 4 /* DCS_TIMER_PERIOD_01 - [3:0] */
938
939/*
940 * R71 (0x47) - DC Servo 4
941 */
942#define WM8904_DCS_SERIES_NO_23_MASK 0x007F /* DCS_SERIES_NO_23 - [6:0] */
943#define WM8904_DCS_SERIES_NO_23_SHIFT 0 /* DCS_SERIES_NO_23 - [6:0] */
944#define WM8904_DCS_SERIES_NO_23_WIDTH 7 /* DCS_SERIES_NO_23 - [6:0] */
945
946/*
947 * R72 (0x48) - DC Servo 5
948 */
949#define WM8904_DCS_SERIES_NO_01_MASK 0x007F /* DCS_SERIES_NO_01 - [6:0] */
950#define WM8904_DCS_SERIES_NO_01_SHIFT 0 /* DCS_SERIES_NO_01 - [6:0] */
951#define WM8904_DCS_SERIES_NO_01_WIDTH 7 /* DCS_SERIES_NO_01 - [6:0] */
952
953/*
954 * R73 (0x49) - DC Servo 6
955 */
956#define WM8904_DCS_DAC_WR_VAL_3_MASK 0x00FF /* DCS_DAC_WR_VAL_3 - [7:0] */
957#define WM8904_DCS_DAC_WR_VAL_3_SHIFT 0 /* DCS_DAC_WR_VAL_3 - [7:0] */
958#define WM8904_DCS_DAC_WR_VAL_3_WIDTH 8 /* DCS_DAC_WR_VAL_3 - [7:0] */
959
960/*
961 * R74 (0x4A) - DC Servo 7
962 */
963#define WM8904_DCS_DAC_WR_VAL_2_MASK 0x00FF /* DCS_DAC_WR_VAL_2 - [7:0] */
964#define WM8904_DCS_DAC_WR_VAL_2_SHIFT 0 /* DCS_DAC_WR_VAL_2 - [7:0] */
965#define WM8904_DCS_DAC_WR_VAL_2_WIDTH 8 /* DCS_DAC_WR_VAL_2 - [7:0] */
966
967/*
968 * R75 (0x4B) - DC Servo 8
969 */
970#define WM8904_DCS_DAC_WR_VAL_1_MASK 0x00FF /* DCS_DAC_WR_VAL_1 - [7:0] */
971#define WM8904_DCS_DAC_WR_VAL_1_SHIFT 0 /* DCS_DAC_WR_VAL_1 - [7:0] */
972#define WM8904_DCS_DAC_WR_VAL_1_WIDTH 8 /* DCS_DAC_WR_VAL_1 - [7:0] */
973
974/*
975 * R76 (0x4C) - DC Servo 9
976 */
977#define WM8904_DCS_DAC_WR_VAL_0_MASK 0x00FF /* DCS_DAC_WR_VAL_0 - [7:0] */
978#define WM8904_DCS_DAC_WR_VAL_0_SHIFT 0 /* DCS_DAC_WR_VAL_0 - [7:0] */
979#define WM8904_DCS_DAC_WR_VAL_0_WIDTH 8 /* DCS_DAC_WR_VAL_0 - [7:0] */
980
981/*
982 * R77 (0x4D) - DC Servo Readback 0
983 */
984#define WM8904_DCS_CAL_COMPLETE_MASK 0x0F00 /* DCS_CAL_COMPLETE - [11:8] */
985#define WM8904_DCS_CAL_COMPLETE_SHIFT 8 /* DCS_CAL_COMPLETE - [11:8] */
986#define WM8904_DCS_CAL_COMPLETE_WIDTH 4 /* DCS_CAL_COMPLETE - [11:8] */
987#define WM8904_DCS_DAC_WR_COMPLETE_MASK 0x00F0 /* DCS_DAC_WR_COMPLETE - [7:4] */
988#define WM8904_DCS_DAC_WR_COMPLETE_SHIFT 4 /* DCS_DAC_WR_COMPLETE - [7:4] */
989#define WM8904_DCS_DAC_WR_COMPLETE_WIDTH 4 /* DCS_DAC_WR_COMPLETE - [7:4] */
990#define WM8904_DCS_STARTUP_COMPLETE_MASK 0x000F /* DCS_STARTUP_COMPLETE - [3:0] */
991#define WM8904_DCS_STARTUP_COMPLETE_SHIFT 0 /* DCS_STARTUP_COMPLETE - [3:0] */
992#define WM8904_DCS_STARTUP_COMPLETE_WIDTH 4 /* DCS_STARTUP_COMPLETE - [3:0] */
993
994/*
995 * R90 (0x5A) - Analogue HP 0
996 */
997#define WM8904_HPL_RMV_SHORT 0x0080 /* HPL_RMV_SHORT */
998#define WM8904_HPL_RMV_SHORT_MASK 0x0080 /* HPL_RMV_SHORT */
999#define WM8904_HPL_RMV_SHORT_SHIFT 7 /* HPL_RMV_SHORT */
1000#define WM8904_HPL_RMV_SHORT_WIDTH 1 /* HPL_RMV_SHORT */
1001#define WM8904_HPL_ENA_OUTP 0x0040 /* HPL_ENA_OUTP */
1002#define WM8904_HPL_ENA_OUTP_MASK 0x0040 /* HPL_ENA_OUTP */
1003#define WM8904_HPL_ENA_OUTP_SHIFT 6 /* HPL_ENA_OUTP */
1004#define WM8904_HPL_ENA_OUTP_WIDTH 1 /* HPL_ENA_OUTP */
1005#define WM8904_HPL_ENA_DLY 0x0020 /* HPL_ENA_DLY */
1006#define WM8904_HPL_ENA_DLY_MASK 0x0020 /* HPL_ENA_DLY */
1007#define WM8904_HPL_ENA_DLY_SHIFT 5 /* HPL_ENA_DLY */
1008#define WM8904_HPL_ENA_DLY_WIDTH 1 /* HPL_ENA_DLY */
1009#define WM8904_HPL_ENA 0x0010 /* HPL_ENA */
1010#define WM8904_HPL_ENA_MASK 0x0010 /* HPL_ENA */
1011#define WM8904_HPL_ENA_SHIFT 4 /* HPL_ENA */
1012#define WM8904_HPL_ENA_WIDTH 1 /* HPL_ENA */
1013#define WM8904_HPR_RMV_SHORT 0x0008 /* HPR_RMV_SHORT */
1014#define WM8904_HPR_RMV_SHORT_MASK 0x0008 /* HPR_RMV_SHORT */
1015#define WM8904_HPR_RMV_SHORT_SHIFT 3 /* HPR_RMV_SHORT */
1016#define WM8904_HPR_RMV_SHORT_WIDTH 1 /* HPR_RMV_SHORT */
1017#define WM8904_HPR_ENA_OUTP 0x0004 /* HPR_ENA_OUTP */
1018#define WM8904_HPR_ENA_OUTP_MASK 0x0004 /* HPR_ENA_OUTP */
1019#define WM8904_HPR_ENA_OUTP_SHIFT 2 /* HPR_ENA_OUTP */
1020#define WM8904_HPR_ENA_OUTP_WIDTH 1 /* HPR_ENA_OUTP */
1021#define WM8904_HPR_ENA_DLY 0x0002 /* HPR_ENA_DLY */
1022#define WM8904_HPR_ENA_DLY_MASK 0x0002 /* HPR_ENA_DLY */
1023#define WM8904_HPR_ENA_DLY_SHIFT 1 /* HPR_ENA_DLY */
1024#define WM8904_HPR_ENA_DLY_WIDTH 1 /* HPR_ENA_DLY */
1025#define WM8904_HPR_ENA 0x0001 /* HPR_ENA */
1026#define WM8904_HPR_ENA_MASK 0x0001 /* HPR_ENA */
1027#define WM8904_HPR_ENA_SHIFT 0 /* HPR_ENA */
1028#define WM8904_HPR_ENA_WIDTH 1 /* HPR_ENA */
1029
1030/*
1031 * R94 (0x5E) - Analogue Lineout 0
1032 */
1033#define WM8904_LINEOUTL_RMV_SHORT 0x0080 /* LINEOUTL_RMV_SHORT */
1034#define WM8904_LINEOUTL_RMV_SHORT_MASK 0x0080 /* LINEOUTL_RMV_SHORT */
1035#define WM8904_LINEOUTL_RMV_SHORT_SHIFT 7 /* LINEOUTL_RMV_SHORT */
1036#define WM8904_LINEOUTL_RMV_SHORT_WIDTH 1 /* LINEOUTL_RMV_SHORT */
1037#define WM8904_LINEOUTL_ENA_OUTP 0x0040 /* LINEOUTL_ENA_OUTP */
1038#define WM8904_LINEOUTL_ENA_OUTP_MASK 0x0040 /* LINEOUTL_ENA_OUTP */
1039#define WM8904_LINEOUTL_ENA_OUTP_SHIFT 6 /* LINEOUTL_ENA_OUTP */
1040#define WM8904_LINEOUTL_ENA_OUTP_WIDTH 1 /* LINEOUTL_ENA_OUTP */
1041#define WM8904_LINEOUTL_ENA_DLY 0x0020 /* LINEOUTL_ENA_DLY */
1042#define WM8904_LINEOUTL_ENA_DLY_MASK 0x0020 /* LINEOUTL_ENA_DLY */
1043#define WM8904_LINEOUTL_ENA_DLY_SHIFT 5 /* LINEOUTL_ENA_DLY */
1044#define WM8904_LINEOUTL_ENA_DLY_WIDTH 1 /* LINEOUTL_ENA_DLY */
1045#define WM8904_LINEOUTL_ENA 0x0010 /* LINEOUTL_ENA */
1046#define WM8904_LINEOUTL_ENA_MASK 0x0010 /* LINEOUTL_ENA */
1047#define WM8904_LINEOUTL_ENA_SHIFT 4 /* LINEOUTL_ENA */
1048#define WM8904_LINEOUTL_ENA_WIDTH 1 /* LINEOUTL_ENA */
1049#define WM8904_LINEOUTR_RMV_SHORT 0x0008 /* LINEOUTR_RMV_SHORT */
1050#define WM8904_LINEOUTR_RMV_SHORT_MASK 0x0008 /* LINEOUTR_RMV_SHORT */
1051#define WM8904_LINEOUTR_RMV_SHORT_SHIFT 3 /* LINEOUTR_RMV_SHORT */
1052#define WM8904_LINEOUTR_RMV_SHORT_WIDTH 1 /* LINEOUTR_RMV_SHORT */
1053#define WM8904_LINEOUTR_ENA_OUTP 0x0004 /* LINEOUTR_ENA_OUTP */
1054#define WM8904_LINEOUTR_ENA_OUTP_MASK 0x0004 /* LINEOUTR_ENA_OUTP */
1055#define WM8904_LINEOUTR_ENA_OUTP_SHIFT 2 /* LINEOUTR_ENA_OUTP */
1056#define WM8904_LINEOUTR_ENA_OUTP_WIDTH 1 /* LINEOUTR_ENA_OUTP */
1057#define WM8904_LINEOUTR_ENA_DLY 0x0002 /* LINEOUTR_ENA_DLY */
1058#define WM8904_LINEOUTR_ENA_DLY_MASK 0x0002 /* LINEOUTR_ENA_DLY */
1059#define WM8904_LINEOUTR_ENA_DLY_SHIFT 1 /* LINEOUTR_ENA_DLY */
1060#define WM8904_LINEOUTR_ENA_DLY_WIDTH 1 /* LINEOUTR_ENA_DLY */
1061#define WM8904_LINEOUTR_ENA 0x0001 /* LINEOUTR_ENA */
1062#define WM8904_LINEOUTR_ENA_MASK 0x0001 /* LINEOUTR_ENA */
1063#define WM8904_LINEOUTR_ENA_SHIFT 0 /* LINEOUTR_ENA */
1064#define WM8904_LINEOUTR_ENA_WIDTH 1 /* LINEOUTR_ENA */
1065
1066/*
1067 * R98 (0x62) - Charge Pump 0
1068 */
1069#define WM8904_CP_ENA 0x0001 /* CP_ENA */
1070#define WM8904_CP_ENA_MASK 0x0001 /* CP_ENA */
1071#define WM8904_CP_ENA_SHIFT 0 /* CP_ENA */
1072#define WM8904_CP_ENA_WIDTH 1 /* CP_ENA */
1073
1074/*
1075 * R104 (0x68) - Class W 0
1076 */
1077#define WM8904_CP_DYN_PWR 0x0001 /* CP_DYN_PWR */
1078#define WM8904_CP_DYN_PWR_MASK 0x0001 /* CP_DYN_PWR */
1079#define WM8904_CP_DYN_PWR_SHIFT 0 /* CP_DYN_PWR */
1080#define WM8904_CP_DYN_PWR_WIDTH 1 /* CP_DYN_PWR */
1081
1082/*
1083 * R108 (0x6C) - Write Sequencer 0
1084 */
1085#define WM8904_WSEQ_ENA 0x0100 /* WSEQ_ENA */
1086#define WM8904_WSEQ_ENA_MASK 0x0100 /* WSEQ_ENA */
1087#define WM8904_WSEQ_ENA_SHIFT 8 /* WSEQ_ENA */
1088#define WM8904_WSEQ_ENA_WIDTH 1 /* WSEQ_ENA */
1089#define WM8904_WSEQ_WRITE_INDEX_MASK 0x001F /* WSEQ_WRITE_INDEX - [4:0] */
1090#define WM8904_WSEQ_WRITE_INDEX_SHIFT 0 /* WSEQ_WRITE_INDEX - [4:0] */
1091#define WM8904_WSEQ_WRITE_INDEX_WIDTH 5 /* WSEQ_WRITE_INDEX - [4:0] */
1092
1093/*
1094 * R109 (0x6D) - Write Sequencer 1
1095 */
1096#define WM8904_WSEQ_DATA_WIDTH_MASK 0x7000 /* WSEQ_DATA_WIDTH - [14:12] */
1097#define WM8904_WSEQ_DATA_WIDTH_SHIFT 12 /* WSEQ_DATA_WIDTH - [14:12] */
1098#define WM8904_WSEQ_DATA_WIDTH_WIDTH 3 /* WSEQ_DATA_WIDTH - [14:12] */
1099#define WM8904_WSEQ_DATA_START_MASK 0x0F00 /* WSEQ_DATA_START - [11:8] */
1100#define WM8904_WSEQ_DATA_START_SHIFT 8 /* WSEQ_DATA_START - [11:8] */
1101#define WM8904_WSEQ_DATA_START_WIDTH 4 /* WSEQ_DATA_START - [11:8] */
1102#define WM8904_WSEQ_ADDR_MASK 0x00FF /* WSEQ_ADDR - [7:0] */
1103#define WM8904_WSEQ_ADDR_SHIFT 0 /* WSEQ_ADDR - [7:0] */
1104#define WM8904_WSEQ_ADDR_WIDTH 8 /* WSEQ_ADDR - [7:0] */
1105
1106/*
1107 * R110 (0x6E) - Write Sequencer 2
1108 */
1109#define WM8904_WSEQ_EOS 0x4000 /* WSEQ_EOS */
1110#define WM8904_WSEQ_EOS_MASK 0x4000 /* WSEQ_EOS */
1111#define WM8904_WSEQ_EOS_SHIFT 14 /* WSEQ_EOS */
1112#define WM8904_WSEQ_EOS_WIDTH 1 /* WSEQ_EOS */
1113#define WM8904_WSEQ_DELAY_MASK 0x0F00 /* WSEQ_DELAY - [11:8] */
1114#define WM8904_WSEQ_DELAY_SHIFT 8 /* WSEQ_DELAY - [11:8] */
1115#define WM8904_WSEQ_DELAY_WIDTH 4 /* WSEQ_DELAY - [11:8] */
1116#define WM8904_WSEQ_DATA_MASK 0x00FF /* WSEQ_DATA - [7:0] */
1117#define WM8904_WSEQ_DATA_SHIFT 0 /* WSEQ_DATA - [7:0] */
1118#define WM8904_WSEQ_DATA_WIDTH 8 /* WSEQ_DATA - [7:0] */
1119
1120/*
1121 * R111 (0x6F) - Write Sequencer 3
1122 */
1123#define WM8904_WSEQ_ABORT 0x0200 /* WSEQ_ABORT */
1124#define WM8904_WSEQ_ABORT_MASK 0x0200 /* WSEQ_ABORT */
1125#define WM8904_WSEQ_ABORT_SHIFT 9 /* WSEQ_ABORT */
1126#define WM8904_WSEQ_ABORT_WIDTH 1 /* WSEQ_ABORT */
1127#define WM8904_WSEQ_START 0x0100 /* WSEQ_START */
1128#define WM8904_WSEQ_START_MASK 0x0100 /* WSEQ_START */
1129#define WM8904_WSEQ_START_SHIFT 8 /* WSEQ_START */
1130#define WM8904_WSEQ_START_WIDTH 1 /* WSEQ_START */
1131#define WM8904_WSEQ_START_INDEX_MASK 0x003F /* WSEQ_START_INDEX - [5:0] */
1132#define WM8904_WSEQ_START_INDEX_SHIFT 0 /* WSEQ_START_INDEX - [5:0] */
1133#define WM8904_WSEQ_START_INDEX_WIDTH 6 /* WSEQ_START_INDEX - [5:0] */
1134
1135/*
1136 * R112 (0x70) - Write Sequencer 4
1137 */
1138#define WM8904_WSEQ_CURRENT_INDEX_MASK 0x03F0 /* WSEQ_CURRENT_INDEX - [9:4] */
1139#define WM8904_WSEQ_CURRENT_INDEX_SHIFT 4 /* WSEQ_CURRENT_INDEX - [9:4] */
1140#define WM8904_WSEQ_CURRENT_INDEX_WIDTH 6 /* WSEQ_CURRENT_INDEX - [9:4] */
1141#define WM8904_WSEQ_BUSY 0x0001 /* WSEQ_BUSY */
1142#define WM8904_WSEQ_BUSY_MASK 0x0001 /* WSEQ_BUSY */
1143#define WM8904_WSEQ_BUSY_SHIFT 0 /* WSEQ_BUSY */
1144#define WM8904_WSEQ_BUSY_WIDTH 1 /* WSEQ_BUSY */
1145
1146/*
1147 * R116 (0x74) - FLL Control 1
1148 */
1149#define WM8904_FLL_FRACN_ENA 0x0004 /* FLL_FRACN_ENA */
1150#define WM8904_FLL_FRACN_ENA_MASK 0x0004 /* FLL_FRACN_ENA */
1151#define WM8904_FLL_FRACN_ENA_SHIFT 2 /* FLL_FRACN_ENA */
1152#define WM8904_FLL_FRACN_ENA_WIDTH 1 /* FLL_FRACN_ENA */
1153#define WM8904_FLL_OSC_ENA 0x0002 /* FLL_OSC_ENA */
1154#define WM8904_FLL_OSC_ENA_MASK 0x0002 /* FLL_OSC_ENA */
1155#define WM8904_FLL_OSC_ENA_SHIFT 1 /* FLL_OSC_ENA */
1156#define WM8904_FLL_OSC_ENA_WIDTH 1 /* FLL_OSC_ENA */
1157#define WM8904_FLL_ENA 0x0001 /* FLL_ENA */
1158#define WM8904_FLL_ENA_MASK 0x0001 /* FLL_ENA */
1159#define WM8904_FLL_ENA_SHIFT 0 /* FLL_ENA */
1160#define WM8904_FLL_ENA_WIDTH 1 /* FLL_ENA */
1161
1162/*
1163 * R117 (0x75) - FLL Control 2
1164 */
1165#define WM8904_FLL_OUTDIV_MASK 0x3F00 /* FLL_OUTDIV - [13:8] */
1166#define WM8904_FLL_OUTDIV_SHIFT 8 /* FLL_OUTDIV - [13:8] */
1167#define WM8904_FLL_OUTDIV_WIDTH 6 /* FLL_OUTDIV - [13:8] */
1168#define WM8904_FLL_CTRL_RATE_MASK 0x0070 /* FLL_CTRL_RATE - [6:4] */
1169#define WM8904_FLL_CTRL_RATE_SHIFT 4 /* FLL_CTRL_RATE - [6:4] */
1170#define WM8904_FLL_CTRL_RATE_WIDTH 3 /* FLL_CTRL_RATE - [6:4] */
1171#define WM8904_FLL_FRATIO_MASK 0x0007 /* FLL_FRATIO - [2:0] */
1172#define WM8904_FLL_FRATIO_SHIFT 0 /* FLL_FRATIO - [2:0] */
1173#define WM8904_FLL_FRATIO_WIDTH 3 /* FLL_FRATIO - [2:0] */
1174
1175/*
1176 * R118 (0x76) - FLL Control 3
1177 */
1178#define WM8904_FLL_K_MASK 0xFFFF /* FLL_K - [15:0] */
1179#define WM8904_FLL_K_SHIFT 0 /* FLL_K - [15:0] */
1180#define WM8904_FLL_K_WIDTH 16 /* FLL_K - [15:0] */
1181
1182/*
1183 * R119 (0x77) - FLL Control 4
1184 */
1185#define WM8904_FLL_N_MASK 0x7FE0 /* FLL_N - [14:5] */
1186#define WM8904_FLL_N_SHIFT 5 /* FLL_N - [14:5] */
1187#define WM8904_FLL_N_WIDTH 10 /* FLL_N - [14:5] */
1188#define WM8904_FLL_GAIN_MASK 0x000F /* FLL_GAIN - [3:0] */
1189#define WM8904_FLL_GAIN_SHIFT 0 /* FLL_GAIN - [3:0] */
1190#define WM8904_FLL_GAIN_WIDTH 4 /* FLL_GAIN - [3:0] */
1191
1192/*
1193 * R120 (0x78) - FLL Control 5
1194 */
1195#define WM8904_FLL_CLK_REF_DIV_MASK 0x0018 /* FLL_CLK_REF_DIV - [4:3] */
1196#define WM8904_FLL_CLK_REF_DIV_SHIFT 3 /* FLL_CLK_REF_DIV - [4:3] */
1197#define WM8904_FLL_CLK_REF_DIV_WIDTH 2 /* FLL_CLK_REF_DIV - [4:3] */
1198#define WM8904_FLL_CLK_REF_SRC_MASK 0x0003 /* FLL_CLK_REF_SRC - [1:0] */
1199#define WM8904_FLL_CLK_REF_SRC_SHIFT 0 /* FLL_CLK_REF_SRC - [1:0] */
1200#define WM8904_FLL_CLK_REF_SRC_WIDTH 2 /* FLL_CLK_REF_SRC - [1:0] */
1201
1202/*
1203 * R121 (0x79) - GPIO Control 1
1204 */
1205#define WM8904_GPIO1_PU 0x0020 /* GPIO1_PU */
1206#define WM8904_GPIO1_PU_MASK 0x0020 /* GPIO1_PU */
1207#define WM8904_GPIO1_PU_SHIFT 5 /* GPIO1_PU */
1208#define WM8904_GPIO1_PU_WIDTH 1 /* GPIO1_PU */
1209#define WM8904_GPIO1_PD 0x0010 /* GPIO1_PD */
1210#define WM8904_GPIO1_PD_MASK 0x0010 /* GPIO1_PD */
1211#define WM8904_GPIO1_PD_SHIFT 4 /* GPIO1_PD */
1212#define WM8904_GPIO1_PD_WIDTH 1 /* GPIO1_PD */
1213#define WM8904_GPIO1_SEL_MASK 0x000F /* GPIO1_SEL - [3:0] */
1214#define WM8904_GPIO1_SEL_SHIFT 0 /* GPIO1_SEL - [3:0] */
1215#define WM8904_GPIO1_SEL_WIDTH 4 /* GPIO1_SEL - [3:0] */
1216
1217/*
1218 * R122 (0x7A) - GPIO Control 2
1219 */
1220#define WM8904_GPIO2_PU 0x0020 /* GPIO2_PU */
1221#define WM8904_GPIO2_PU_MASK 0x0020 /* GPIO2_PU */
1222#define WM8904_GPIO2_PU_SHIFT 5 /* GPIO2_PU */
1223#define WM8904_GPIO2_PU_WIDTH 1 /* GPIO2_PU */
1224#define WM8904_GPIO2_PD 0x0010 /* GPIO2_PD */
1225#define WM8904_GPIO2_PD_MASK 0x0010 /* GPIO2_PD */
1226#define WM8904_GPIO2_PD_SHIFT 4 /* GPIO2_PD */
1227#define WM8904_GPIO2_PD_WIDTH 1 /* GPIO2_PD */
1228#define WM8904_GPIO2_SEL_MASK 0x000F /* GPIO2_SEL - [3:0] */
1229#define WM8904_GPIO2_SEL_SHIFT 0 /* GPIO2_SEL - [3:0] */
1230#define WM8904_GPIO2_SEL_WIDTH 4 /* GPIO2_SEL - [3:0] */
1231
1232/*
1233 * R123 (0x7B) - GPIO Control 3
1234 */
1235#define WM8904_GPIO3_PU 0x0020 /* GPIO3_PU */
1236#define WM8904_GPIO3_PU_MASK 0x0020 /* GPIO3_PU */
1237#define WM8904_GPIO3_PU_SHIFT 5 /* GPIO3_PU */
1238#define WM8904_GPIO3_PU_WIDTH 1 /* GPIO3_PU */
1239#define WM8904_GPIO3_PD 0x0010 /* GPIO3_PD */
1240#define WM8904_GPIO3_PD_MASK 0x0010 /* GPIO3_PD */
1241#define WM8904_GPIO3_PD_SHIFT 4 /* GPIO3_PD */
1242#define WM8904_GPIO3_PD_WIDTH 1 /* GPIO3_PD */
1243#define WM8904_GPIO3_SEL_MASK 0x000F /* GPIO3_SEL - [3:0] */
1244#define WM8904_GPIO3_SEL_SHIFT 0 /* GPIO3_SEL - [3:0] */
1245#define WM8904_GPIO3_SEL_WIDTH 4 /* GPIO3_SEL - [3:0] */
1246
1247/*
1248 * R124 (0x7C) - GPIO Control 4
1249 */
1250#define WM8904_GPI7_ENA 0x0200 /* GPI7_ENA */
1251#define WM8904_GPI7_ENA_MASK 0x0200 /* GPI7_ENA */
1252#define WM8904_GPI7_ENA_SHIFT 9 /* GPI7_ENA */
1253#define WM8904_GPI7_ENA_WIDTH 1 /* GPI7_ENA */
1254#define WM8904_GPI8_ENA 0x0100 /* GPI8_ENA */
1255#define WM8904_GPI8_ENA_MASK 0x0100 /* GPI8_ENA */
1256#define WM8904_GPI8_ENA_SHIFT 8 /* GPI8_ENA */
1257#define WM8904_GPI8_ENA_WIDTH 1 /* GPI8_ENA */
1258#define WM8904_GPIO_BCLK_MODE_ENA 0x0080 /* GPIO_BCLK_MODE_ENA */
1259#define WM8904_GPIO_BCLK_MODE_ENA_MASK 0x0080 /* GPIO_BCLK_MODE_ENA */
1260#define WM8904_GPIO_BCLK_MODE_ENA_SHIFT 7 /* GPIO_BCLK_MODE_ENA */
1261#define WM8904_GPIO_BCLK_MODE_ENA_WIDTH 1 /* GPIO_BCLK_MODE_ENA */
1262#define WM8904_GPIO_BCLK_SEL_MASK 0x000F /* GPIO_BCLK_SEL - [3:0] */
1263#define WM8904_GPIO_BCLK_SEL_SHIFT 0 /* GPIO_BCLK_SEL - [3:0] */
1264#define WM8904_GPIO_BCLK_SEL_WIDTH 4 /* GPIO_BCLK_SEL - [3:0] */
1265
1266/*
1267 * R126 (0x7E) - Digital Pulls
1268 */
1269#define WM8904_MCLK_PU 0x0080 /* MCLK_PU */
1270#define WM8904_MCLK_PU_MASK 0x0080 /* MCLK_PU */
1271#define WM8904_MCLK_PU_SHIFT 7 /* MCLK_PU */
1272#define WM8904_MCLK_PU_WIDTH 1 /* MCLK_PU */
1273#define WM8904_MCLK_PD 0x0040 /* MCLK_PD */
1274#define WM8904_MCLK_PD_MASK 0x0040 /* MCLK_PD */
1275#define WM8904_MCLK_PD_SHIFT 6 /* MCLK_PD */
1276#define WM8904_MCLK_PD_WIDTH 1 /* MCLK_PD */
1277#define WM8904_DACDAT_PU 0x0020 /* DACDAT_PU */
1278#define WM8904_DACDAT_PU_MASK 0x0020 /* DACDAT_PU */
1279#define WM8904_DACDAT_PU_SHIFT 5 /* DACDAT_PU */
1280#define WM8904_DACDAT_PU_WIDTH 1 /* DACDAT_PU */
1281#define WM8904_DACDAT_PD 0x0010 /* DACDAT_PD */
1282#define WM8904_DACDAT_PD_MASK 0x0010 /* DACDAT_PD */
1283#define WM8904_DACDAT_PD_SHIFT 4 /* DACDAT_PD */
1284#define WM8904_DACDAT_PD_WIDTH 1 /* DACDAT_PD */
1285#define WM8904_LRCLK_PU 0x0008 /* LRCLK_PU */
1286#define WM8904_LRCLK_PU_MASK 0x0008 /* LRCLK_PU */
1287#define WM8904_LRCLK_PU_SHIFT 3 /* LRCLK_PU */
1288#define WM8904_LRCLK_PU_WIDTH 1 /* LRCLK_PU */
1289#define WM8904_LRCLK_PD 0x0004 /* LRCLK_PD */
1290#define WM8904_LRCLK_PD_MASK 0x0004 /* LRCLK_PD */
1291#define WM8904_LRCLK_PD_SHIFT 2 /* LRCLK_PD */
1292#define WM8904_LRCLK_PD_WIDTH 1 /* LRCLK_PD */
1293#define WM8904_BCLK_PU 0x0002 /* BCLK_PU */
1294#define WM8904_BCLK_PU_MASK 0x0002 /* BCLK_PU */
1295#define WM8904_BCLK_PU_SHIFT 1 /* BCLK_PU */
1296#define WM8904_BCLK_PU_WIDTH 1 /* BCLK_PU */
1297#define WM8904_BCLK_PD 0x0001 /* BCLK_PD */
1298#define WM8904_BCLK_PD_MASK 0x0001 /* BCLK_PD */
1299#define WM8904_BCLK_PD_SHIFT 0 /* BCLK_PD */
1300#define WM8904_BCLK_PD_WIDTH 1 /* BCLK_PD */
1301
1302/*
1303 * R127 (0x7F) - Interrupt Status
1304 */
1305#define WM8904_IRQ 0x0400 /* IRQ */
1306#define WM8904_IRQ_MASK 0x0400 /* IRQ */
1307#define WM8904_IRQ_SHIFT 10 /* IRQ */
1308#define WM8904_IRQ_WIDTH 1 /* IRQ */
1309#define WM8904_GPIO_BCLK_EINT 0x0200 /* GPIO_BCLK_EINT */
1310#define WM8904_GPIO_BCLK_EINT_MASK 0x0200 /* GPIO_BCLK_EINT */
1311#define WM8904_GPIO_BCLK_EINT_SHIFT 9 /* GPIO_BCLK_EINT */
1312#define WM8904_GPIO_BCLK_EINT_WIDTH 1 /* GPIO_BCLK_EINT */
1313#define WM8904_WSEQ_EINT 0x0100 /* WSEQ_EINT */
1314#define WM8904_WSEQ_EINT_MASK 0x0100 /* WSEQ_EINT */
1315#define WM8904_WSEQ_EINT_SHIFT 8 /* WSEQ_EINT */
1316#define WM8904_WSEQ_EINT_WIDTH 1 /* WSEQ_EINT */
1317#define WM8904_GPIO3_EINT 0x0080 /* GPIO3_EINT */
1318#define WM8904_GPIO3_EINT_MASK 0x0080 /* GPIO3_EINT */
1319#define WM8904_GPIO3_EINT_SHIFT 7 /* GPIO3_EINT */
1320#define WM8904_GPIO3_EINT_WIDTH 1 /* GPIO3_EINT */
1321#define WM8904_GPIO2_EINT 0x0040 /* GPIO2_EINT */
1322#define WM8904_GPIO2_EINT_MASK 0x0040 /* GPIO2_EINT */
1323#define WM8904_GPIO2_EINT_SHIFT 6 /* GPIO2_EINT */
1324#define WM8904_GPIO2_EINT_WIDTH 1 /* GPIO2_EINT */
1325#define WM8904_GPIO1_EINT 0x0020 /* GPIO1_EINT */
1326#define WM8904_GPIO1_EINT_MASK 0x0020 /* GPIO1_EINT */
1327#define WM8904_GPIO1_EINT_SHIFT 5 /* GPIO1_EINT */
1328#define WM8904_GPIO1_EINT_WIDTH 1 /* GPIO1_EINT */
1329#define WM8904_GPI8_EINT 0x0010 /* GPI8_EINT */
1330#define WM8904_GPI8_EINT_MASK 0x0010 /* GPI8_EINT */
1331#define WM8904_GPI8_EINT_SHIFT 4 /* GPI8_EINT */
1332#define WM8904_GPI8_EINT_WIDTH 1 /* GPI8_EINT */
1333#define WM8904_GPI7_EINT 0x0008 /* GPI7_EINT */
1334#define WM8904_GPI7_EINT_MASK 0x0008 /* GPI7_EINT */
1335#define WM8904_GPI7_EINT_SHIFT 3 /* GPI7_EINT */
1336#define WM8904_GPI7_EINT_WIDTH 1 /* GPI7_EINT */
1337#define WM8904_FLL_LOCK_EINT 0x0004 /* FLL_LOCK_EINT */
1338#define WM8904_FLL_LOCK_EINT_MASK 0x0004 /* FLL_LOCK_EINT */
1339#define WM8904_FLL_LOCK_EINT_SHIFT 2 /* FLL_LOCK_EINT */
1340#define WM8904_FLL_LOCK_EINT_WIDTH 1 /* FLL_LOCK_EINT */
1341#define WM8904_MIC_SHRT_EINT 0x0002 /* MIC_SHRT_EINT */
1342#define WM8904_MIC_SHRT_EINT_MASK 0x0002 /* MIC_SHRT_EINT */
1343#define WM8904_MIC_SHRT_EINT_SHIFT 1 /* MIC_SHRT_EINT */
1344#define WM8904_MIC_SHRT_EINT_WIDTH 1 /* MIC_SHRT_EINT */
1345#define WM8904_MIC_DET_EINT 0x0001 /* MIC_DET_EINT */
1346#define WM8904_MIC_DET_EINT_MASK 0x0001 /* MIC_DET_EINT */
1347#define WM8904_MIC_DET_EINT_SHIFT 0 /* MIC_DET_EINT */
1348#define WM8904_MIC_DET_EINT_WIDTH 1 /* MIC_DET_EINT */
1349
1350/*
1351 * R128 (0x80) - Interrupt Status Mask
1352 */
1353#define WM8904_IM_GPIO_BCLK_EINT 0x0200 /* IM_GPIO_BCLK_EINT */
1354#define WM8904_IM_GPIO_BCLK_EINT_MASK 0x0200 /* IM_GPIO_BCLK_EINT */
1355#define WM8904_IM_GPIO_BCLK_EINT_SHIFT 9 /* IM_GPIO_BCLK_EINT */
1356#define WM8904_IM_GPIO_BCLK_EINT_WIDTH 1 /* IM_GPIO_BCLK_EINT */
1357#define WM8904_IM_WSEQ_EINT 0x0100 /* IM_WSEQ_EINT */
1358#define WM8904_IM_WSEQ_EINT_MASK 0x0100 /* IM_WSEQ_EINT */
1359#define WM8904_IM_WSEQ_EINT_SHIFT 8 /* IM_WSEQ_EINT */
1360#define WM8904_IM_WSEQ_EINT_WIDTH 1 /* IM_WSEQ_EINT */
1361#define WM8904_IM_GPIO3_EINT 0x0080 /* IM_GPIO3_EINT */
1362#define WM8904_IM_GPIO3_EINT_MASK 0x0080 /* IM_GPIO3_EINT */
1363#define WM8904_IM_GPIO3_EINT_SHIFT 7 /* IM_GPIO3_EINT */
1364#define WM8904_IM_GPIO3_EINT_WIDTH 1 /* IM_GPIO3_EINT */
1365#define WM8904_IM_GPIO2_EINT 0x0040 /* IM_GPIO2_EINT */
1366#define WM8904_IM_GPIO2_EINT_MASK 0x0040 /* IM_GPIO2_EINT */
1367#define WM8904_IM_GPIO2_EINT_SHIFT 6 /* IM_GPIO2_EINT */
1368#define WM8904_IM_GPIO2_EINT_WIDTH 1 /* IM_GPIO2_EINT */
1369#define WM8904_IM_GPIO1_EINT 0x0020 /* IM_GPIO1_EINT */
1370#define WM8904_IM_GPIO1_EINT_MASK 0x0020 /* IM_GPIO1_EINT */
1371#define WM8904_IM_GPIO1_EINT_SHIFT 5 /* IM_GPIO1_EINT */
1372#define WM8904_IM_GPIO1_EINT_WIDTH 1 /* IM_GPIO1_EINT */
1373#define WM8904_IM_GPI8_EINT 0x0010 /* IM_GPI8_EINT */
1374#define WM8904_IM_GPI8_EINT_MASK 0x0010 /* IM_GPI8_EINT */
1375#define WM8904_IM_GPI8_EINT_SHIFT 4 /* IM_GPI8_EINT */
1376#define WM8904_IM_GPI8_EINT_WIDTH 1 /* IM_GPI8_EINT */
1377#define WM8904_IM_GPI7_EINT 0x0008 /* IM_GPI7_EINT */
1378#define WM8904_IM_GPI7_EINT_MASK 0x0008 /* IM_GPI7_EINT */
1379#define WM8904_IM_GPI7_EINT_SHIFT 3 /* IM_GPI7_EINT */
1380#define WM8904_IM_GPI7_EINT_WIDTH 1 /* IM_GPI7_EINT */
1381#define WM8904_IM_FLL_LOCK_EINT 0x0004 /* IM_FLL_LOCK_EINT */
1382#define WM8904_IM_FLL_LOCK_EINT_MASK 0x0004 /* IM_FLL_LOCK_EINT */
1383#define WM8904_IM_FLL_LOCK_EINT_SHIFT 2 /* IM_FLL_LOCK_EINT */
1384#define WM8904_IM_FLL_LOCK_EINT_WIDTH 1 /* IM_FLL_LOCK_EINT */
1385#define WM8904_IM_MIC_SHRT_EINT 0x0002 /* IM_MIC_SHRT_EINT */
1386#define WM8904_IM_MIC_SHRT_EINT_MASK 0x0002 /* IM_MIC_SHRT_EINT */
1387#define WM8904_IM_MIC_SHRT_EINT_SHIFT 1 /* IM_MIC_SHRT_EINT */
1388#define WM8904_IM_MIC_SHRT_EINT_WIDTH 1 /* IM_MIC_SHRT_EINT */
1389#define WM8904_IM_MIC_DET_EINT 0x0001 /* IM_MIC_DET_EINT */
1390#define WM8904_IM_MIC_DET_EINT_MASK 0x0001 /* IM_MIC_DET_EINT */
1391#define WM8904_IM_MIC_DET_EINT_SHIFT 0 /* IM_MIC_DET_EINT */
1392#define WM8904_IM_MIC_DET_EINT_WIDTH 1 /* IM_MIC_DET_EINT */
1393
1394/*
1395 * R129 (0x81) - Interrupt Polarity
1396 */
1397#define WM8904_GPIO_BCLK_EINT_POL 0x0200 /* GPIO_BCLK_EINT_POL */
1398#define WM8904_GPIO_BCLK_EINT_POL_MASK 0x0200 /* GPIO_BCLK_EINT_POL */
1399#define WM8904_GPIO_BCLK_EINT_POL_SHIFT 9 /* GPIO_BCLK_EINT_POL */
1400#define WM8904_GPIO_BCLK_EINT_POL_WIDTH 1 /* GPIO_BCLK_EINT_POL */
1401#define WM8904_WSEQ_EINT_POL 0x0100 /* WSEQ_EINT_POL */
1402#define WM8904_WSEQ_EINT_POL_MASK 0x0100 /* WSEQ_EINT_POL */
1403#define WM8904_WSEQ_EINT_POL_SHIFT 8 /* WSEQ_EINT_POL */
1404#define WM8904_WSEQ_EINT_POL_WIDTH 1 /* WSEQ_EINT_POL */
1405#define WM8904_GPIO3_EINT_POL 0x0080 /* GPIO3_EINT_POL */
1406#define WM8904_GPIO3_EINT_POL_MASK 0x0080 /* GPIO3_EINT_POL */
1407#define WM8904_GPIO3_EINT_POL_SHIFT 7 /* GPIO3_EINT_POL */
1408#define WM8904_GPIO3_EINT_POL_WIDTH 1 /* GPIO3_EINT_POL */
1409#define WM8904_GPIO2_EINT_POL 0x0040 /* GPIO2_EINT_POL */
1410#define WM8904_GPIO2_EINT_POL_MASK 0x0040 /* GPIO2_EINT_POL */
1411#define WM8904_GPIO2_EINT_POL_SHIFT 6 /* GPIO2_EINT_POL */
1412#define WM8904_GPIO2_EINT_POL_WIDTH 1 /* GPIO2_EINT_POL */
1413#define WM8904_GPIO1_EINT_POL 0x0020 /* GPIO1_EINT_POL */
1414#define WM8904_GPIO1_EINT_POL_MASK 0x0020 /* GPIO1_EINT_POL */
1415#define WM8904_GPIO1_EINT_POL_SHIFT 5 /* GPIO1_EINT_POL */
1416#define WM8904_GPIO1_EINT_POL_WIDTH 1 /* GPIO1_EINT_POL */
1417#define WM8904_GPI8_EINT_POL 0x0010 /* GPI8_EINT_POL */
1418#define WM8904_GPI8_EINT_POL_MASK 0x0010 /* GPI8_EINT_POL */
1419#define WM8904_GPI8_EINT_POL_SHIFT 4 /* GPI8_EINT_POL */
1420#define WM8904_GPI8_EINT_POL_WIDTH 1 /* GPI8_EINT_POL */
1421#define WM8904_GPI7_EINT_POL 0x0008 /* GPI7_EINT_POL */
1422#define WM8904_GPI7_EINT_POL_MASK 0x0008 /* GPI7_EINT_POL */
1423#define WM8904_GPI7_EINT_POL_SHIFT 3 /* GPI7_EINT_POL */
1424#define WM8904_GPI7_EINT_POL_WIDTH 1 /* GPI7_EINT_POL */
1425#define WM8904_FLL_LOCK_EINT_POL 0x0004 /* FLL_LOCK_EINT_POL */
1426#define WM8904_FLL_LOCK_EINT_POL_MASK 0x0004 /* FLL_LOCK_EINT_POL */
1427#define WM8904_FLL_LOCK_EINT_POL_SHIFT 2 /* FLL_LOCK_EINT_POL */
1428#define WM8904_FLL_LOCK_EINT_POL_WIDTH 1 /* FLL_LOCK_EINT_POL */
1429#define WM8904_MIC_SHRT_EINT_POL 0x0002 /* MIC_SHRT_EINT_POL */
1430#define WM8904_MIC_SHRT_EINT_POL_MASK 0x0002 /* MIC_SHRT_EINT_POL */
1431#define WM8904_MIC_SHRT_EINT_POL_SHIFT 1 /* MIC_SHRT_EINT_POL */
1432#define WM8904_MIC_SHRT_EINT_POL_WIDTH 1 /* MIC_SHRT_EINT_POL */
1433#define WM8904_MIC_DET_EINT_POL 0x0001 /* MIC_DET_EINT_POL */
1434#define WM8904_MIC_DET_EINT_POL_MASK 0x0001 /* MIC_DET_EINT_POL */
1435#define WM8904_MIC_DET_EINT_POL_SHIFT 0 /* MIC_DET_EINT_POL */
1436#define WM8904_MIC_DET_EINT_POL_WIDTH 1 /* MIC_DET_EINT_POL */
1437
1438/*
1439 * R130 (0x82) - Interrupt Debounce
1440 */
1441#define WM8904_GPIO_BCLK_EINT_DB 0x0200 /* GPIO_BCLK_EINT_DB */
1442#define WM8904_GPIO_BCLK_EINT_DB_MASK 0x0200 /* GPIO_BCLK_EINT_DB */
1443#define WM8904_GPIO_BCLK_EINT_DB_SHIFT 9 /* GPIO_BCLK_EINT_DB */
1444#define WM8904_GPIO_BCLK_EINT_DB_WIDTH 1 /* GPIO_BCLK_EINT_DB */
1445#define WM8904_WSEQ_EINT_DB 0x0100 /* WSEQ_EINT_DB */
1446#define WM8904_WSEQ_EINT_DB_MASK 0x0100 /* WSEQ_EINT_DB */
1447#define WM8904_WSEQ_EINT_DB_SHIFT 8 /* WSEQ_EINT_DB */
1448#define WM8904_WSEQ_EINT_DB_WIDTH 1 /* WSEQ_EINT_DB */
1449#define WM8904_GPIO3_EINT_DB 0x0080 /* GPIO3_EINT_DB */
1450#define WM8904_GPIO3_EINT_DB_MASK 0x0080 /* GPIO3_EINT_DB */
1451#define WM8904_GPIO3_EINT_DB_SHIFT 7 /* GPIO3_EINT_DB */
1452#define WM8904_GPIO3_EINT_DB_WIDTH 1 /* GPIO3_EINT_DB */
1453#define WM8904_GPIO2_EINT_DB 0x0040 /* GPIO2_EINT_DB */
1454#define WM8904_GPIO2_EINT_DB_MASK 0x0040 /* GPIO2_EINT_DB */
1455#define WM8904_GPIO2_EINT_DB_SHIFT 6 /* GPIO2_EINT_DB */
1456#define WM8904_GPIO2_EINT_DB_WIDTH 1 /* GPIO2_EINT_DB */
1457#define WM8904_GPIO1_EINT_DB 0x0020 /* GPIO1_EINT_DB */
1458#define WM8904_GPIO1_EINT_DB_MASK 0x0020 /* GPIO1_EINT_DB */
1459#define WM8904_GPIO1_EINT_DB_SHIFT 5 /* GPIO1_EINT_DB */
1460#define WM8904_GPIO1_EINT_DB_WIDTH 1 /* GPIO1_EINT_DB */
1461#define WM8904_GPI8_EINT_DB 0x0010 /* GPI8_EINT_DB */
1462#define WM8904_GPI8_EINT_DB_MASK 0x0010 /* GPI8_EINT_DB */
1463#define WM8904_GPI8_EINT_DB_SHIFT 4 /* GPI8_EINT_DB */
1464#define WM8904_GPI8_EINT_DB_WIDTH 1 /* GPI8_EINT_DB */
1465#define WM8904_GPI7_EINT_DB 0x0008 /* GPI7_EINT_DB */
1466#define WM8904_GPI7_EINT_DB_MASK 0x0008 /* GPI7_EINT_DB */
1467#define WM8904_GPI7_EINT_DB_SHIFT 3 /* GPI7_EINT_DB */
1468#define WM8904_GPI7_EINT_DB_WIDTH 1 /* GPI7_EINT_DB */
1469#define WM8904_FLL_LOCK_EINT_DB 0x0004 /* FLL_LOCK_EINT_DB */
1470#define WM8904_FLL_LOCK_EINT_DB_MASK 0x0004 /* FLL_LOCK_EINT_DB */
1471#define WM8904_FLL_LOCK_EINT_DB_SHIFT 2 /* FLL_LOCK_EINT_DB */
1472#define WM8904_FLL_LOCK_EINT_DB_WIDTH 1 /* FLL_LOCK_EINT_DB */
1473#define WM8904_MIC_SHRT_EINT_DB 0x0002 /* MIC_SHRT_EINT_DB */
1474#define WM8904_MIC_SHRT_EINT_DB_MASK 0x0002 /* MIC_SHRT_EINT_DB */
1475#define WM8904_MIC_SHRT_EINT_DB_SHIFT 1 /* MIC_SHRT_EINT_DB */
1476#define WM8904_MIC_SHRT_EINT_DB_WIDTH 1 /* MIC_SHRT_EINT_DB */
1477#define WM8904_MIC_DET_EINT_DB 0x0001 /* MIC_DET_EINT_DB */
1478#define WM8904_MIC_DET_EINT_DB_MASK 0x0001 /* MIC_DET_EINT_DB */
1479#define WM8904_MIC_DET_EINT_DB_SHIFT 0 /* MIC_DET_EINT_DB */
1480#define WM8904_MIC_DET_EINT_DB_WIDTH 1 /* MIC_DET_EINT_DB */
1481
1482/*
1483 * R134 (0x86) - EQ1
1484 */
1485#define WM8904_EQ_ENA 0x0001 /* EQ_ENA */
1486#define WM8904_EQ_ENA_MASK 0x0001 /* EQ_ENA */
1487#define WM8904_EQ_ENA_SHIFT 0 /* EQ_ENA */
1488#define WM8904_EQ_ENA_WIDTH 1 /* EQ_ENA */
1489
1490/*
1491 * R135 (0x87) - EQ2
1492 */
1493#define WM8904_EQ_B1_GAIN_MASK 0x001F /* EQ_B1_GAIN - [4:0] */
1494#define WM8904_EQ_B1_GAIN_SHIFT 0 /* EQ_B1_GAIN - [4:0] */
1495#define WM8904_EQ_B1_GAIN_WIDTH 5 /* EQ_B1_GAIN - [4:0] */
1496
1497/*
1498 * R136 (0x88) - EQ3
1499 */
1500#define WM8904_EQ_B2_GAIN_MASK 0x001F /* EQ_B2_GAIN - [4:0] */
1501#define WM8904_EQ_B2_GAIN_SHIFT 0 /* EQ_B2_GAIN - [4:0] */
1502#define WM8904_EQ_B2_GAIN_WIDTH 5 /* EQ_B2_GAIN - [4:0] */
1503
1504/*
1505 * R137 (0x89) - EQ4
1506 */
1507#define WM8904_EQ_B3_GAIN_MASK 0x001F /* EQ_B3_GAIN - [4:0] */
1508#define WM8904_EQ_B3_GAIN_SHIFT 0 /* EQ_B3_GAIN - [4:0] */
1509#define WM8904_EQ_B3_GAIN_WIDTH 5 /* EQ_B3_GAIN - [4:0] */
1510
1511/*
1512 * R138 (0x8A) - EQ5
1513 */
1514#define WM8904_EQ_B4_GAIN_MASK 0x001F /* EQ_B4_GAIN - [4:0] */
1515#define WM8904_EQ_B4_GAIN_SHIFT 0 /* EQ_B4_GAIN - [4:0] */
1516#define WM8904_EQ_B4_GAIN_WIDTH 5 /* EQ_B4_GAIN - [4:0] */
1517
1518/*
1519 * R139 (0x8B) - EQ6
1520 */
1521#define WM8904_EQ_B5_GAIN_MASK 0x001F /* EQ_B5_GAIN - [4:0] */
1522#define WM8904_EQ_B5_GAIN_SHIFT 0 /* EQ_B5_GAIN - [4:0] */
1523#define WM8904_EQ_B5_GAIN_WIDTH 5 /* EQ_B5_GAIN - [4:0] */
1524
1525/*
1526 * R140 (0x8C) - EQ7
1527 */
1528#define WM8904_EQ_B1_A_MASK 0xFFFF /* EQ_B1_A - [15:0] */
1529#define WM8904_EQ_B1_A_SHIFT 0 /* EQ_B1_A - [15:0] */
1530#define WM8904_EQ_B1_A_WIDTH 16 /* EQ_B1_A - [15:0] */
1531
1532/*
1533 * R141 (0x8D) - EQ8
1534 */
1535#define WM8904_EQ_B1_B_MASK 0xFFFF /* EQ_B1_B - [15:0] */
1536#define WM8904_EQ_B1_B_SHIFT 0 /* EQ_B1_B - [15:0] */
1537#define WM8904_EQ_B1_B_WIDTH 16 /* EQ_B1_B - [15:0] */
1538
1539/*
1540 * R142 (0x8E) - EQ9
1541 */
1542#define WM8904_EQ_B1_PG_MASK 0xFFFF /* EQ_B1_PG - [15:0] */
1543#define WM8904_EQ_B1_PG_SHIFT 0 /* EQ_B1_PG - [15:0] */
1544#define WM8904_EQ_B1_PG_WIDTH 16 /* EQ_B1_PG - [15:0] */
1545
1546/*
1547 * R143 (0x8F) - EQ10
1548 */
1549#define WM8904_EQ_B2_A_MASK 0xFFFF /* EQ_B2_A - [15:0] */
1550#define WM8904_EQ_B2_A_SHIFT 0 /* EQ_B2_A - [15:0] */
1551#define WM8904_EQ_B2_A_WIDTH 16 /* EQ_B2_A - [15:0] */
1552
1553/*
1554 * R144 (0x90) - EQ11
1555 */
1556#define WM8904_EQ_B2_B_MASK 0xFFFF /* EQ_B2_B - [15:0] */
1557#define WM8904_EQ_B2_B_SHIFT 0 /* EQ_B2_B - [15:0] */
1558#define WM8904_EQ_B2_B_WIDTH 16 /* EQ_B2_B - [15:0] */
1559
1560/*
1561 * R145 (0x91) - EQ12
1562 */
1563#define WM8904_EQ_B2_C_MASK 0xFFFF /* EQ_B2_C - [15:0] */
1564#define WM8904_EQ_B2_C_SHIFT 0 /* EQ_B2_C - [15:0] */
1565#define WM8904_EQ_B2_C_WIDTH 16 /* EQ_B2_C - [15:0] */
1566
1567/*
1568 * R146 (0x92) - EQ13
1569 */
1570#define WM8904_EQ_B2_PG_MASK 0xFFFF /* EQ_B2_PG - [15:0] */
1571#define WM8904_EQ_B2_PG_SHIFT 0 /* EQ_B2_PG - [15:0] */
1572#define WM8904_EQ_B2_PG_WIDTH 16 /* EQ_B2_PG - [15:0] */
1573
1574/*
1575 * R147 (0x93) - EQ14
1576 */
1577#define WM8904_EQ_B3_A_MASK 0xFFFF /* EQ_B3_A - [15:0] */
1578#define WM8904_EQ_B3_A_SHIFT 0 /* EQ_B3_A - [15:0] */
1579#define WM8904_EQ_B3_A_WIDTH 16 /* EQ_B3_A - [15:0] */
1580
1581/*
1582 * R148 (0x94) - EQ15
1583 */
1584#define WM8904_EQ_B3_B_MASK 0xFFFF /* EQ_B3_B - [15:0] */
1585#define WM8904_EQ_B3_B_SHIFT 0 /* EQ_B3_B - [15:0] */
1586#define WM8904_EQ_B3_B_WIDTH 16 /* EQ_B3_B - [15:0] */
1587
1588/*
1589 * R149 (0x95) - EQ16
1590 */
1591#define WM8904_EQ_B3_C_MASK 0xFFFF /* EQ_B3_C - [15:0] */
1592#define WM8904_EQ_B3_C_SHIFT 0 /* EQ_B3_C - [15:0] */
1593#define WM8904_EQ_B3_C_WIDTH 16 /* EQ_B3_C - [15:0] */
1594
1595/*
1596 * R150 (0x96) - EQ17
1597 */
1598#define WM8904_EQ_B3_PG_MASK 0xFFFF /* EQ_B3_PG - [15:0] */
1599#define WM8904_EQ_B3_PG_SHIFT 0 /* EQ_B3_PG - [15:0] */
1600#define WM8904_EQ_B3_PG_WIDTH 16 /* EQ_B3_PG - [15:0] */
1601
1602/*
1603 * R151 (0x97) - EQ18
1604 */
1605#define WM8904_EQ_B4_A_MASK 0xFFFF /* EQ_B4_A - [15:0] */
1606#define WM8904_EQ_B4_A_SHIFT 0 /* EQ_B4_A - [15:0] */
1607#define WM8904_EQ_B4_A_WIDTH 16 /* EQ_B4_A - [15:0] */
1608
1609/*
1610 * R152 (0x98) - EQ19
1611 */
1612#define WM8904_EQ_B4_B_MASK 0xFFFF /* EQ_B4_B - [15:0] */
1613#define WM8904_EQ_B4_B_SHIFT 0 /* EQ_B4_B - [15:0] */
1614#define WM8904_EQ_B4_B_WIDTH 16 /* EQ_B4_B - [15:0] */
1615
1616/*
1617 * R153 (0x99) - EQ20
1618 */
1619#define WM8904_EQ_B4_C_MASK 0xFFFF /* EQ_B4_C - [15:0] */
1620#define WM8904_EQ_B4_C_SHIFT 0 /* EQ_B4_C - [15:0] */
1621#define WM8904_EQ_B4_C_WIDTH 16 /* EQ_B4_C - [15:0] */
1622
1623/*
1624 * R154 (0x9A) - EQ21
1625 */
1626#define WM8904_EQ_B4_PG_MASK 0xFFFF /* EQ_B4_PG - [15:0] */
1627#define WM8904_EQ_B4_PG_SHIFT 0 /* EQ_B4_PG - [15:0] */
1628#define WM8904_EQ_B4_PG_WIDTH 16 /* EQ_B4_PG - [15:0] */
1629
1630/*
1631 * R155 (0x9B) - EQ22
1632 */
1633#define WM8904_EQ_B5_A_MASK 0xFFFF /* EQ_B5_A - [15:0] */
1634#define WM8904_EQ_B5_A_SHIFT 0 /* EQ_B5_A - [15:0] */
1635#define WM8904_EQ_B5_A_WIDTH 16 /* EQ_B5_A - [15:0] */
1636
1637/*
1638 * R156 (0x9C) - EQ23
1639 */
1640#define WM8904_EQ_B5_B_MASK 0xFFFF /* EQ_B5_B - [15:0] */
1641#define WM8904_EQ_B5_B_SHIFT 0 /* EQ_B5_B - [15:0] */
1642#define WM8904_EQ_B5_B_WIDTH 16 /* EQ_B5_B - [15:0] */
1643
1644/*
1645 * R157 (0x9D) - EQ24
1646 */
1647#define WM8904_EQ_B5_PG_MASK 0xFFFF /* EQ_B5_PG - [15:0] */
1648#define WM8904_EQ_B5_PG_SHIFT 0 /* EQ_B5_PG - [15:0] */
1649#define WM8904_EQ_B5_PG_WIDTH 16 /* EQ_B5_PG - [15:0] */
1650
1651/*
1652 * R161 (0xA1) - Control Interface Test 1
1653 */
1654#define WM8904_USER_KEY 0x0002 /* USER_KEY */
1655#define WM8904_USER_KEY_MASK 0x0002 /* USER_KEY */
1656#define WM8904_USER_KEY_SHIFT 1 /* USER_KEY */
1657#define WM8904_USER_KEY_WIDTH 1 /* USER_KEY */
1658
1659/*
1660 * R204 (0xCC) - Analogue Output Bias 0
1661 */
1662#define WM8904_PGA_BIAS_MASK 0x0070 /* PGA_BIAS - [6:4] */
1663#define WM8904_PGA_BIAS_SHIFT 4 /* PGA_BIAS - [6:4] */
1664#define WM8904_PGA_BIAS_WIDTH 3 /* PGA_BIAS - [6:4] */
1665
1666/*
1667 * R247 (0xF7) - FLL NCO Test 0
1668 */
1669#define WM8904_FLL_FRC_NCO 0x0001 /* FLL_FRC_NCO */
1670#define WM8904_FLL_FRC_NCO_MASK 0x0001 /* FLL_FRC_NCO */
1671#define WM8904_FLL_FRC_NCO_SHIFT 0 /* FLL_FRC_NCO */
1672#define WM8904_FLL_FRC_NCO_WIDTH 1 /* FLL_FRC_NCO */
1673
1674/*
1675 * R248 (0xF8) - FLL NCO Test 1
1676 */
1677#define WM8904_FLL_FRC_NCO_VAL_MASK 0x003F /* FLL_FRC_NCO_VAL - [5:0] */
1678#define WM8904_FLL_FRC_NCO_VAL_SHIFT 0 /* FLL_FRC_NCO_VAL - [5:0] */
1679#define WM8904_FLL_FRC_NCO_VAL_WIDTH 6 /* FLL_FRC_NCO_VAL - [5:0] */
1680
1681#endif
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c
index 1ef2454c5205..0c04b476487f 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>
@@ -298,7 +299,6 @@ static int wm8940_add_widgets(struct snd_soc_codec *codec)
298 ret = snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 299 ret = snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
299 if (ret) 300 if (ret)
300 goto error_ret; 301 goto error_ret;
301 ret = snd_soc_dapm_new_widgets(codec);
302 302
303error_ret: 303error_ret:
304 return ret; 304 return ret;
@@ -379,23 +379,23 @@ static int wm8940_i2s_hw_params(struct snd_pcm_substream *substream,
379 iface |= (1 << 9); 379 iface |= (1 << 9);
380 380
381 switch (params_rate(params)) { 381 switch (params_rate(params)) {
382 case SNDRV_PCM_RATE_8000: 382 case 8000:
383 addcntrl |= (0x5 << 1); 383 addcntrl |= (0x5 << 1);
384 break; 384 break;
385 case SNDRV_PCM_RATE_11025: 385 case 11025:
386 addcntrl |= (0x4 << 1); 386 addcntrl |= (0x4 << 1);
387 break; 387 break;
388 case SNDRV_PCM_RATE_16000: 388 case 16000:
389 addcntrl |= (0x3 << 1); 389 addcntrl |= (0x3 << 1);
390 break; 390 break;
391 case SNDRV_PCM_RATE_22050: 391 case 22050:
392 addcntrl |= (0x2 << 1); 392 addcntrl |= (0x2 << 1);
393 break; 393 break;
394 case SNDRV_PCM_RATE_32000: 394 case 32000:
395 addcntrl |= (0x1 << 1); 395 addcntrl |= (0x1 << 1);
396 break; 396 break;
397 case SNDRV_PCM_RATE_44100: 397 case 44100:
398 case SNDRV_PCM_RATE_48000: 398 case 48000:
399 break; 399 break;
400 } 400 }
401 ret = snd_soc_write(codec, WM8940_ADDCNTRL, addcntrl); 401 ret = snd_soc_write(codec, WM8940_ADDCNTRL, addcntrl);
@@ -536,8 +536,8 @@ static void pll_factors(unsigned int target, unsigned int source)
536} 536}
537 537
538/* Untested at the moment */ 538/* Untested at the moment */
539static int wm8940_set_dai_pll(struct snd_soc_dai *codec_dai, 539static int wm8940_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
540 int pll_id, unsigned int freq_in, unsigned int freq_out) 540 int source, unsigned int freq_in, unsigned int freq_out)
541{ 541{
542 struct snd_soc_codec *codec = codec_dai->codec; 542 struct snd_soc_codec *codec = codec_dai->codec;
543 u16 reg; 543 u16 reg;
@@ -731,12 +731,6 @@ static int wm8940_probe(struct platform_device *pdev)
731 if (ret) 731 if (ret)
732 goto error_free_pcms; 732 goto error_free_pcms;
733 733
734 ret = snd_soc_init_card(socdev);
735 if (ret < 0) {
736 dev_err(codec->dev, "failed to register card: %d\n", ret);
737 goto error_free_pcms;
738 }
739
740 return ret; 734 return ret;
741 735
742error_free_pcms: 736error_free_pcms:
@@ -877,21 +871,6 @@ static int __devexit wm8940_i2c_remove(struct i2c_client *client)
877 return 0; 871 return 0;
878} 872}
879 873
880#ifdef CONFIG_PM
881static int wm8940_i2c_suspend(struct i2c_client *client, pm_message_t msg)
882{
883 return snd_soc_suspend_device(&client->dev);
884}
885
886static int wm8940_i2c_resume(struct i2c_client *client)
887{
888 return snd_soc_resume_device(&client->dev);
889}
890#else
891#define wm8940_i2c_suspend NULL
892#define wm8940_i2c_resume NULL
893#endif
894
895static const struct i2c_device_id wm8940_i2c_id[] = { 874static const struct i2c_device_id wm8940_i2c_id[] = {
896 { "wm8940", 0 }, 875 { "wm8940", 0 },
897 { } 876 { }
@@ -905,8 +884,6 @@ static struct i2c_driver wm8940_i2c_driver = {
905 }, 884 },
906 .probe = wm8940_i2c_probe, 885 .probe = wm8940_i2c_probe,
907 .remove = __devexit_p(wm8940_i2c_remove), 886 .remove = __devexit_p(wm8940_i2c_remove),
908 .suspend = wm8940_i2c_suspend,
909 .resume = wm8940_i2c_resume,
910 .id_table = wm8940_i2c_id, 887 .id_table = wm8940_i2c_id,
911}; 888};
912 889
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c
new file mode 100644
index 000000000000..c8d7a809af4d
--- /dev/null
+++ b/sound/soc/codecs/wm8955.c
@@ -0,0 +1,1152 @@
1/*
2 * wm8955.c -- WM8955 ALSA SoC Audio driver
3 *
4 * Copyright 2009 Wolfson Microelectronics plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/init.h>
16#include <linux/delay.h>
17#include <linux/pm.h>
18#include <linux/i2c.h>
19#include <linux/platform_device.h>
20#include <linux/regulator/consumer.h>
21#include <linux/slab.h>
22#include <sound/core.h>
23#include <sound/pcm.h>
24#include <sound/pcm_params.h>
25#include <sound/soc.h>
26#include <sound/soc-dapm.h>
27#include <sound/initval.h>
28#include <sound/tlv.h>
29#include <sound/wm8955.h>
30
31#include "wm8955.h"
32
33static struct snd_soc_codec *wm8955_codec;
34struct snd_soc_codec_device soc_codec_dev_wm8955;
35
36#define WM8955_NUM_SUPPLIES 4
37static const char *wm8955_supply_names[WM8955_NUM_SUPPLIES] = {
38 "DCVDD",
39 "DBVDD",
40 "HPVDD",
41 "AVDD",
42};
43
44/* codec private data */
45struct wm8955_priv {
46 struct snd_soc_codec codec;
47 u16 reg_cache[WM8955_MAX_REGISTER + 1];
48
49 unsigned int mclk_rate;
50
51 int deemph;
52 int fs;
53
54 struct regulator_bulk_data supplies[WM8955_NUM_SUPPLIES];
55
56 struct wm8955_pdata *pdata;
57};
58
59static const u16 wm8955_reg[WM8955_MAX_REGISTER + 1] = {
60 0x0000, /* R0 */
61 0x0000, /* R1 */
62 0x0079, /* R2 - LOUT1 volume */
63 0x0079, /* R3 - ROUT1 volume */
64 0x0000, /* R4 */
65 0x0008, /* R5 - DAC Control */
66 0x0000, /* R6 */
67 0x000A, /* R7 - Audio Interface */
68 0x0000, /* R8 - Sample Rate */
69 0x0000, /* R9 */
70 0x00FF, /* R10 - Left DAC volume */
71 0x00FF, /* R11 - Right DAC volume */
72 0x000F, /* R12 - Bass control */
73 0x000F, /* R13 - Treble control */
74 0x0000, /* R14 */
75 0x0000, /* R15 - Reset */
76 0x0000, /* R16 */
77 0x0000, /* R17 */
78 0x0000, /* R18 */
79 0x0000, /* R19 */
80 0x0000, /* R20 */
81 0x0000, /* R21 */
82 0x0000, /* R22 */
83 0x00C1, /* R23 - Additional control (1) */
84 0x0000, /* R24 - Additional control (2) */
85 0x0000, /* R25 - Power Management (1) */
86 0x0000, /* R26 - Power Management (2) */
87 0x0000, /* R27 - Additional Control (3) */
88 0x0000, /* R28 */
89 0x0000, /* R29 */
90 0x0000, /* R30 */
91 0x0000, /* R31 */
92 0x0000, /* R32 */
93 0x0000, /* R33 */
94 0x0050, /* R34 - Left out Mix (1) */
95 0x0050, /* R35 - Left out Mix (2) */
96 0x0050, /* R36 - Right out Mix (1) */
97 0x0050, /* R37 - Right Out Mix (2) */
98 0x0050, /* R38 - Mono out Mix (1) */
99 0x0050, /* R39 - Mono out Mix (2) */
100 0x0079, /* R40 - LOUT2 volume */
101 0x0079, /* R41 - ROUT2 volume */
102 0x0079, /* R42 - MONOOUT volume */
103 0x0000, /* R43 - Clocking / PLL */
104 0x0103, /* R44 - PLL Control 1 */
105 0x0024, /* R45 - PLL Control 2 */
106 0x01BA, /* R46 - PLL Control 3 */
107 0x0000, /* R47 */
108 0x0000, /* R48 */
109 0x0000, /* R49 */
110 0x0000, /* R50 */
111 0x0000, /* R51 */
112 0x0000, /* R52 */
113 0x0000, /* R53 */
114 0x0000, /* R54 */
115 0x0000, /* R55 */
116 0x0000, /* R56 */
117 0x0000, /* R57 */
118 0x0000, /* R58 */
119 0x0000, /* R59 - PLL Control 4 */
120};
121
122static int wm8955_reset(struct snd_soc_codec *codec)
123{
124 return snd_soc_write(codec, WM8955_RESET, 0);
125}
126
127struct pll_factors {
128 int n;
129 int k;
130 int outdiv;
131};
132
133/* The size in bits of the FLL divide multiplied by 10
134 * to allow rounding later */
135#define FIXED_FLL_SIZE ((1 << 22) * 10)
136
137static int wm8995_pll_factors(struct device *dev,
138 int Fref, int Fout, struct pll_factors *pll)
139{
140 u64 Kpart;
141 unsigned int K, Ndiv, Nmod, target;
142
143 dev_dbg(dev, "Fref=%u Fout=%u\n", Fref, Fout);
144
145 /* The oscilator should run at should be 90-100MHz, and
146 * there's a divide by 4 plus an optional divide by 2 in the
147 * output path to generate the system clock. The clock table
148 * is sortd so we should always generate a suitable target. */
149 target = Fout * 4;
150 if (target < 90000000) {
151 pll->outdiv = 1;
152 target *= 2;
153 } else {
154 pll->outdiv = 0;
155 }
156
157 WARN_ON(target < 90000000 || target > 100000000);
158
159 dev_dbg(dev, "Fvco=%dHz\n", target);
160
161 /* Now, calculate N.K */
162 Ndiv = target / Fref;
163
164 pll->n = Ndiv;
165 Nmod = target % Fref;
166 dev_dbg(dev, "Nmod=%d\n", Nmod);
167
168 /* Calculate fractional part - scale up so we can round. */
169 Kpart = FIXED_FLL_SIZE * (long long)Nmod;
170
171 do_div(Kpart, Fref);
172
173 K = Kpart & 0xFFFFFFFF;
174
175 if ((K % 10) >= 5)
176 K += 5;
177
178 /* Move down to proper range now rounding is done */
179 pll->k = K / 10;
180
181 dev_dbg(dev, "N=%x K=%x OUTDIV=%x\n", pll->n, pll->k, pll->outdiv);
182
183 return 0;
184}
185
186/* Lookup table specifiying SRATE (table 25 in datasheet); some of the
187 * output frequencies have been rounded to the standard frequencies
188 * they are intended to match where the error is slight. */
189static struct {
190 int mclk;
191 int fs;
192 int usb;
193 int sr;
194} clock_cfgs[] = {
195 { 18432000, 8000, 0, 3, },
196 { 18432000, 12000, 0, 9, },
197 { 18432000, 16000, 0, 11, },
198 { 18432000, 24000, 0, 29, },
199 { 18432000, 32000, 0, 13, },
200 { 18432000, 48000, 0, 1, },
201 { 18432000, 96000, 0, 15, },
202
203 { 16934400, 8018, 0, 19, },
204 { 16934400, 11025, 0, 25, },
205 { 16934400, 22050, 0, 27, },
206 { 16934400, 44100, 0, 17, },
207 { 16934400, 88200, 0, 31, },
208
209 { 12000000, 8000, 1, 2, },
210 { 12000000, 11025, 1, 25, },
211 { 12000000, 12000, 1, 8, },
212 { 12000000, 16000, 1, 10, },
213 { 12000000, 22050, 1, 27, },
214 { 12000000, 24000, 1, 28, },
215 { 12000000, 32000, 1, 12, },
216 { 12000000, 44100, 1, 17, },
217 { 12000000, 48000, 1, 0, },
218 { 12000000, 88200, 1, 31, },
219 { 12000000, 96000, 1, 14, },
220
221 { 12288000, 8000, 0, 2, },
222 { 12288000, 12000, 0, 8, },
223 { 12288000, 16000, 0, 10, },
224 { 12288000, 24000, 0, 28, },
225 { 12288000, 32000, 0, 12, },
226 { 12288000, 48000, 0, 0, },
227 { 12288000, 96000, 0, 14, },
228
229 { 12289600, 8018, 0, 18, },
230 { 12289600, 11025, 0, 24, },
231 { 12289600, 22050, 0, 26, },
232 { 11289600, 44100, 0, 16, },
233 { 11289600, 88200, 0, 31, },
234};
235
236static int wm8955_configure_clocking(struct snd_soc_codec *codec)
237{
238 struct wm8955_priv *wm8955 = codec->private_data;
239 int i, ret, val;
240 int clocking = 0;
241 int srate = 0;
242 int sr = -1;
243 struct pll_factors pll;
244
245 /* If we're not running a sample rate currently just pick one */
246 if (wm8955->fs == 0)
247 wm8955->fs = 8000;
248
249 /* Can we generate an exact output? */
250 for (i = 0; i < ARRAY_SIZE(clock_cfgs); i++) {
251 if (wm8955->fs != clock_cfgs[i].fs)
252 continue;
253 sr = i;
254
255 if (wm8955->mclk_rate == clock_cfgs[i].mclk)
256 break;
257 }
258
259 /* We should never get here with an unsupported sample rate */
260 if (sr == -1) {
261 dev_err(codec->dev, "Sample rate %dHz unsupported\n",
262 wm8955->fs);
263 WARN_ON(sr == -1);
264 return -EINVAL;
265 }
266
267 if (i == ARRAY_SIZE(clock_cfgs)) {
268 /* If we can't generate the right clock from MCLK then
269 * we should configure the PLL to supply us with an
270 * appropriate clock.
271 */
272 clocking |= WM8955_MCLKSEL;
273
274 /* Use the last divider configuration we saw for the
275 * sample rate. */
276 ret = wm8995_pll_factors(codec->dev, wm8955->mclk_rate,
277 clock_cfgs[sr].mclk, &pll);
278 if (ret != 0) {
279 dev_err(codec->dev,
280 "Unable to generate %dHz from %dHz MCLK\n",
281 wm8955->fs, wm8955->mclk_rate);
282 return -EINVAL;
283 }
284
285 snd_soc_update_bits(codec, WM8955_PLL_CONTROL_1,
286 WM8955_N_MASK | WM8955_K_21_18_MASK,
287 (pll.n << WM8955_N_SHIFT) |
288 pll.k >> 18);
289 snd_soc_update_bits(codec, WM8955_PLL_CONTROL_2,
290 WM8955_K_17_9_MASK,
291 (pll.k >> 9) & WM8955_K_17_9_MASK);
292 snd_soc_update_bits(codec, WM8955_PLL_CONTROL_2,
293 WM8955_K_8_0_MASK,
294 pll.k & WM8955_K_8_0_MASK);
295 if (pll.k)
296 snd_soc_update_bits(codec, WM8955_PLL_CONTROL_4,
297 WM8955_KEN, WM8955_KEN);
298 else
299 snd_soc_update_bits(codec, WM8955_PLL_CONTROL_4,
300 WM8955_KEN, 0);
301
302 if (pll.outdiv)
303 val = WM8955_PLL_RB | WM8955_PLLOUTDIV2;
304 else
305 val = WM8955_PLL_RB;
306
307 /* Now start the PLL running */
308 snd_soc_update_bits(codec, WM8955_CLOCKING_PLL,
309 WM8955_PLL_RB | WM8955_PLLOUTDIV2, val);
310 snd_soc_update_bits(codec, WM8955_CLOCKING_PLL,
311 WM8955_PLLEN, WM8955_PLLEN);
312 }
313
314 srate = clock_cfgs[sr].usb | (clock_cfgs[sr].sr << WM8955_SR_SHIFT);
315
316 snd_soc_update_bits(codec, WM8955_SAMPLE_RATE,
317 WM8955_USB | WM8955_SR_MASK, srate);
318 snd_soc_update_bits(codec, WM8955_CLOCKING_PLL,
319 WM8955_MCLKSEL, clocking);
320
321 return 0;
322}
323
324static int wm8955_sysclk(struct snd_soc_dapm_widget *w,
325 struct snd_kcontrol *kcontrol, int event)
326{
327 struct snd_soc_codec *codec = w->codec;
328 int ret = 0;
329
330 /* Always disable the clocks - if we're doing reconfiguration this
331 * avoids misclocking.
332 */
333 snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1,
334 WM8955_DIGENB, 0);
335 snd_soc_update_bits(codec, WM8955_CLOCKING_PLL,
336 WM8955_PLL_RB | WM8955_PLLEN, 0);
337
338 switch (event) {
339 case SND_SOC_DAPM_POST_PMD:
340 break;
341 case SND_SOC_DAPM_PRE_PMU:
342 ret = wm8955_configure_clocking(codec);
343 break;
344 default:
345 ret = -EINVAL;
346 break;
347 }
348
349 return ret;
350}
351
352static int deemph_settings[] = { 0, 32000, 44100, 48000 };
353
354static int wm8955_set_deemph(struct snd_soc_codec *codec)
355{
356 struct wm8955_priv *wm8955 = codec->private_data;
357 int val, i, best;
358
359 /* If we're using deemphasis select the nearest available sample
360 * rate.
361 */
362 if (wm8955->deemph) {
363 best = 1;
364 for (i = 2; i < ARRAY_SIZE(deemph_settings); i++) {
365 if (abs(deemph_settings[i] - wm8955->fs) <
366 abs(deemph_settings[best] - wm8955->fs))
367 best = i;
368 }
369
370 val = best << WM8955_DEEMPH_SHIFT;
371 } else {
372 val = 0;
373 }
374
375 dev_dbg(codec->dev, "Set deemphasis %d\n", val);
376
377 return snd_soc_update_bits(codec, WM8955_DAC_CONTROL,
378 WM8955_DEEMPH_MASK, val);
379}
380
381static int wm8955_get_deemph(struct snd_kcontrol *kcontrol,
382 struct snd_ctl_elem_value *ucontrol)
383{
384 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
385 struct wm8955_priv *wm8955 = codec->private_data;
386
387 return wm8955->deemph;
388}
389
390static int wm8955_put_deemph(struct snd_kcontrol *kcontrol,
391 struct snd_ctl_elem_value *ucontrol)
392{
393 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
394 struct wm8955_priv *wm8955 = codec->private_data;
395 int deemph = ucontrol->value.enumerated.item[0];
396
397 if (deemph > 1)
398 return -EINVAL;
399
400 wm8955->deemph = deemph;
401
402 return wm8955_set_deemph(codec);
403}
404
405static const char *bass_mode_text[] = {
406 "Linear", "Adaptive",
407};
408
409static const struct soc_enum bass_mode =
410 SOC_ENUM_SINGLE(WM8955_BASS_CONTROL, 7, 2, bass_mode_text);
411
412static const char *bass_cutoff_text[] = {
413 "Low", "High"
414};
415
416static const struct soc_enum bass_cutoff =
417 SOC_ENUM_SINGLE(WM8955_BASS_CONTROL, 6, 2, bass_cutoff_text);
418
419static const char *treble_cutoff_text[] = {
420 "High", "Low"
421};
422
423static const struct soc_enum treble_cutoff =
424 SOC_ENUM_SINGLE(WM8955_TREBLE_CONTROL, 6, 2, treble_cutoff_text);
425
426static const DECLARE_TLV_DB_SCALE(digital_tlv, -12750, 50, 1);
427static const DECLARE_TLV_DB_SCALE(atten_tlv, -600, 600, 0);
428static const DECLARE_TLV_DB_SCALE(bypass_tlv, -1500, 300, 0);
429static const DECLARE_TLV_DB_SCALE(mono_tlv, -2100, 300, 0);
430static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1);
431static const DECLARE_TLV_DB_SCALE(treble_tlv, -1200, 150, 1);
432
433static const struct snd_kcontrol_new wm8955_snd_controls[] = {
434SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8955_LEFT_DAC_VOLUME,
435 WM8955_RIGHT_DAC_VOLUME, 0, 255, 0, digital_tlv),
436SOC_SINGLE_TLV("Playback Attenuation Volume", WM8955_DAC_CONTROL, 7, 1, 1,
437 atten_tlv),
438SOC_SINGLE_BOOL_EXT("DAC Deemphasis Switch", 0,
439 wm8955_get_deemph, wm8955_put_deemph),
440
441SOC_ENUM("Bass Mode", bass_mode),
442SOC_ENUM("Bass Cutoff", bass_cutoff),
443SOC_SINGLE("Bass Volume", WM8955_BASS_CONTROL, 0, 15, 1),
444
445SOC_ENUM("Treble Cutoff", treble_cutoff),
446SOC_SINGLE_TLV("Treble Volume", WM8955_TREBLE_CONTROL, 0, 14, 1, treble_tlv),
447
448SOC_SINGLE_TLV("Left Bypass Volume", WM8955_LEFT_OUT_MIX_1, 4, 7, 1,
449 bypass_tlv),
450SOC_SINGLE_TLV("Left Mono Volume", WM8955_LEFT_OUT_MIX_2, 4, 7, 1,
451 bypass_tlv),
452
453SOC_SINGLE_TLV("Right Mono Volume", WM8955_RIGHT_OUT_MIX_1, 4, 7, 1,
454 bypass_tlv),
455SOC_SINGLE_TLV("Right Bypass Volume", WM8955_RIGHT_OUT_MIX_2, 4, 7, 1,
456 bypass_tlv),
457
458/* Not a stereo pair so they line up with the DAPM switches */
459SOC_SINGLE_TLV("Mono Left Bypass Volume", WM8955_MONO_OUT_MIX_1, 4, 7, 1,
460 mono_tlv),
461SOC_SINGLE_TLV("Mono Right Bypass Volume", WM8955_MONO_OUT_MIX_2, 4, 7, 1,
462 mono_tlv),
463
464SOC_DOUBLE_R_TLV("Headphone Volume", WM8955_LOUT1_VOLUME,
465 WM8955_ROUT1_VOLUME, 0, 127, 0, out_tlv),
466SOC_DOUBLE_R("Headphone ZC Switch", WM8955_LOUT1_VOLUME,
467 WM8955_ROUT1_VOLUME, 7, 1, 0),
468
469SOC_DOUBLE_R_TLV("Speaker Volume", WM8955_LOUT2_VOLUME,
470 WM8955_ROUT2_VOLUME, 0, 127, 0, out_tlv),
471SOC_DOUBLE_R("Speaker ZC Switch", WM8955_LOUT2_VOLUME,
472 WM8955_ROUT2_VOLUME, 7, 1, 0),
473
474SOC_SINGLE_TLV("Mono Volume", WM8955_MONOOUT_VOLUME, 0, 127, 0, out_tlv),
475SOC_SINGLE("Mono ZC Switch", WM8955_MONOOUT_VOLUME, 7, 1, 0),
476};
477
478static const struct snd_kcontrol_new lmixer[] = {
479SOC_DAPM_SINGLE("Playback Switch", WM8955_LEFT_OUT_MIX_1, 8, 1, 0),
480SOC_DAPM_SINGLE("Bypass Switch", WM8955_LEFT_OUT_MIX_1, 7, 1, 0),
481SOC_DAPM_SINGLE("Right Playback Switch", WM8955_LEFT_OUT_MIX_2, 8, 1, 0),
482SOC_DAPM_SINGLE("Mono Switch", WM8955_LEFT_OUT_MIX_2, 7, 1, 0),
483};
484
485static const struct snd_kcontrol_new rmixer[] = {
486SOC_DAPM_SINGLE("Left Playback Switch", WM8955_RIGHT_OUT_MIX_1, 8, 1, 0),
487SOC_DAPM_SINGLE("Mono Switch", WM8955_RIGHT_OUT_MIX_1, 7, 1, 0),
488SOC_DAPM_SINGLE("Playback Switch", WM8955_RIGHT_OUT_MIX_2, 8, 1, 0),
489SOC_DAPM_SINGLE("Bypass Switch", WM8955_RIGHT_OUT_MIX_2, 7, 1, 0),
490};
491
492static const struct snd_kcontrol_new mmixer[] = {
493SOC_DAPM_SINGLE("Left Playback Switch", WM8955_MONO_OUT_MIX_1, 8, 1, 0),
494SOC_DAPM_SINGLE("Left Bypass Switch", WM8955_MONO_OUT_MIX_1, 7, 1, 0),
495SOC_DAPM_SINGLE("Right Playback Switch", WM8955_MONO_OUT_MIX_2, 8, 1, 0),
496SOC_DAPM_SINGLE("Right Bypass Switch", WM8955_MONO_OUT_MIX_2, 7, 1, 0),
497};
498
499static const struct snd_soc_dapm_widget wm8955_dapm_widgets[] = {
500SND_SOC_DAPM_INPUT("MONOIN-"),
501SND_SOC_DAPM_INPUT("MONOIN+"),
502SND_SOC_DAPM_INPUT("LINEINR"),
503SND_SOC_DAPM_INPUT("LINEINL"),
504
505SND_SOC_DAPM_PGA("Mono Input", SND_SOC_NOPM, 0, 0, NULL, 0),
506
507SND_SOC_DAPM_SUPPLY("SYSCLK", WM8955_POWER_MANAGEMENT_1, 0, 1, wm8955_sysclk,
508 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
509SND_SOC_DAPM_SUPPLY("TSDEN", WM8955_ADDITIONAL_CONTROL_1, 8, 0, NULL, 0),
510
511SND_SOC_DAPM_DAC("DACL", "Playback", WM8955_POWER_MANAGEMENT_2, 8, 0),
512SND_SOC_DAPM_DAC("DACR", "Playback", WM8955_POWER_MANAGEMENT_2, 7, 0),
513
514SND_SOC_DAPM_PGA("LOUT1 PGA", WM8955_POWER_MANAGEMENT_2, 6, 0, NULL, 0),
515SND_SOC_DAPM_PGA("ROUT1 PGA", WM8955_POWER_MANAGEMENT_2, 5, 0, NULL, 0),
516SND_SOC_DAPM_PGA("LOUT2 PGA", WM8955_POWER_MANAGEMENT_2, 4, 0, NULL, 0),
517SND_SOC_DAPM_PGA("ROUT2 PGA", WM8955_POWER_MANAGEMENT_2, 3, 0, NULL, 0),
518SND_SOC_DAPM_PGA("MOUT PGA", WM8955_POWER_MANAGEMENT_2, 2, 0, NULL, 0),
519SND_SOC_DAPM_PGA("OUT3 PGA", WM8955_POWER_MANAGEMENT_2, 1, 0, NULL, 0),
520
521/* The names are chosen to make the control names nice */
522SND_SOC_DAPM_MIXER("Left", SND_SOC_NOPM, 0, 0,
523 lmixer, ARRAY_SIZE(lmixer)),
524SND_SOC_DAPM_MIXER("Right", SND_SOC_NOPM, 0, 0,
525 rmixer, ARRAY_SIZE(rmixer)),
526SND_SOC_DAPM_MIXER("Mono", SND_SOC_NOPM, 0, 0,
527 mmixer, ARRAY_SIZE(mmixer)),
528
529SND_SOC_DAPM_OUTPUT("LOUT1"),
530SND_SOC_DAPM_OUTPUT("ROUT1"),
531SND_SOC_DAPM_OUTPUT("LOUT2"),
532SND_SOC_DAPM_OUTPUT("ROUT2"),
533SND_SOC_DAPM_OUTPUT("MONOOUT"),
534SND_SOC_DAPM_OUTPUT("OUT3"),
535};
536
537static const struct snd_soc_dapm_route wm8955_intercon[] = {
538 { "DACL", NULL, "SYSCLK" },
539 { "DACR", NULL, "SYSCLK" },
540
541 { "Mono Input", NULL, "MONOIN-" },
542 { "Mono Input", NULL, "MONOIN+" },
543
544 { "Left", "Playback Switch", "DACL" },
545 { "Left", "Right Playback Switch", "DACR" },
546 { "Left", "Bypass Switch", "LINEINL" },
547 { "Left", "Mono Switch", "Mono Input" },
548
549 { "Right", "Playback Switch", "DACR" },
550 { "Right", "Left Playback Switch", "DACL" },
551 { "Right", "Bypass Switch", "LINEINR" },
552 { "Right", "Mono Switch", "Mono Input" },
553
554 { "Mono", "Left Playback Switch", "DACL" },
555 { "Mono", "Right Playback Switch", "DACR" },
556 { "Mono", "Left Bypass Switch", "LINEINL" },
557 { "Mono", "Right Bypass Switch", "LINEINR" },
558
559 { "LOUT1 PGA", NULL, "Left" },
560 { "LOUT1", NULL, "TSDEN" },
561 { "LOUT1", NULL, "LOUT1 PGA" },
562
563 { "ROUT1 PGA", NULL, "Right" },
564 { "ROUT1", NULL, "TSDEN" },
565 { "ROUT1", NULL, "ROUT1 PGA" },
566
567 { "LOUT2 PGA", NULL, "Left" },
568 { "LOUT2", NULL, "TSDEN" },
569 { "LOUT2", NULL, "LOUT2 PGA" },
570
571 { "ROUT2 PGA", NULL, "Right" },
572 { "ROUT2", NULL, "TSDEN" },
573 { "ROUT2", NULL, "ROUT2 PGA" },
574
575 { "MOUT PGA", NULL, "Mono" },
576 { "MONOOUT", NULL, "MOUT PGA" },
577
578 /* OUT3 not currently implemented */
579 { "OUT3", NULL, "OUT3 PGA" },
580};
581
582static int wm8955_add_widgets(struct snd_soc_codec *codec)
583{
584 snd_soc_add_controls(codec, wm8955_snd_controls,
585 ARRAY_SIZE(wm8955_snd_controls));
586
587 snd_soc_dapm_new_controls(codec, wm8955_dapm_widgets,
588 ARRAY_SIZE(wm8955_dapm_widgets));
589
590 snd_soc_dapm_add_routes(codec, wm8955_intercon,
591 ARRAY_SIZE(wm8955_intercon));
592
593 return 0;
594}
595
596static int wm8955_hw_params(struct snd_pcm_substream *substream,
597 struct snd_pcm_hw_params *params,
598 struct snd_soc_dai *dai)
599{
600 struct snd_soc_codec *codec = dai->codec;
601 struct wm8955_priv *wm8955 = codec->private_data;
602 int ret;
603 int wl;
604
605 switch (params_format(params)) {
606 case SNDRV_PCM_FORMAT_S16_LE:
607 wl = 0;
608 break;
609 case SNDRV_PCM_FORMAT_S20_3LE:
610 wl = 0x4;
611 break;
612 case SNDRV_PCM_FORMAT_S24_LE:
613 wl = 0x8;
614 break;
615 case SNDRV_PCM_FORMAT_S32_LE:
616 wl = 0xc;
617 break;
618 default:
619 return -EINVAL;
620 }
621 snd_soc_update_bits(codec, WM8955_AUDIO_INTERFACE,
622 WM8955_WL_MASK, wl);
623
624 wm8955->fs = params_rate(params);
625 wm8955_set_deemph(codec);
626
627 /* If the chip is clocked then disable the clocks and force a
628 * reconfiguration, otherwise DAPM will power up the
629 * clocks for us later. */
630 ret = snd_soc_read(codec, WM8955_POWER_MANAGEMENT_1);
631 if (ret < 0)
632 return ret;
633 if (ret & WM8955_DIGENB) {
634 snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1,
635 WM8955_DIGENB, 0);
636 snd_soc_update_bits(codec, WM8955_CLOCKING_PLL,
637 WM8955_PLL_RB | WM8955_PLLEN, 0);
638
639 wm8955_configure_clocking(codec);
640 }
641
642 return 0;
643}
644
645
646static int wm8955_set_sysclk(struct snd_soc_dai *dai, int clk_id,
647 unsigned int freq, int dir)
648{
649 struct snd_soc_codec *codec = dai->codec;
650 struct wm8955_priv *priv = codec->private_data;
651 int div;
652
653 switch (clk_id) {
654 case WM8955_CLK_MCLK:
655 if (freq > 15000000) {
656 priv->mclk_rate = freq /= 2;
657 div = WM8955_MCLKDIV2;
658 } else {
659 priv->mclk_rate = freq;
660 div = 0;
661 }
662
663 snd_soc_update_bits(codec, WM8955_SAMPLE_RATE,
664 WM8955_MCLKDIV2, div);
665 break;
666
667 default:
668 return -EINVAL;
669 }
670
671 dev_dbg(dai->dev, "Clock source is %d at %uHz\n", clk_id, freq);
672
673 return 0;
674}
675
676static int wm8955_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
677{
678 struct snd_soc_codec *codec = dai->codec;
679 u16 aif = 0;
680
681 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
682 case SND_SOC_DAIFMT_CBS_CFS:
683 break;
684 case SND_SOC_DAIFMT_CBM_CFM:
685 aif |= WM8955_MS;
686 break;
687 default:
688 return -EINVAL;
689 }
690
691 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
692 case SND_SOC_DAIFMT_DSP_B:
693 aif |= WM8955_LRP;
694 case SND_SOC_DAIFMT_DSP_A:
695 aif |= 0x3;
696 break;
697 case SND_SOC_DAIFMT_I2S:
698 aif |= 0x2;
699 break;
700 case SND_SOC_DAIFMT_RIGHT_J:
701 break;
702 case SND_SOC_DAIFMT_LEFT_J:
703 aif |= 0x1;
704 break;
705 default:
706 return -EINVAL;
707 }
708
709 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
710 case SND_SOC_DAIFMT_DSP_A:
711 case SND_SOC_DAIFMT_DSP_B:
712 /* frame inversion not valid for DSP modes */
713 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
714 case SND_SOC_DAIFMT_NB_NF:
715 break;
716 case SND_SOC_DAIFMT_IB_NF:
717 aif |= WM8955_BCLKINV;
718 break;
719 default:
720 return -EINVAL;
721 }
722 break;
723
724 case SND_SOC_DAIFMT_I2S:
725 case SND_SOC_DAIFMT_RIGHT_J:
726 case SND_SOC_DAIFMT_LEFT_J:
727 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
728 case SND_SOC_DAIFMT_NB_NF:
729 break;
730 case SND_SOC_DAIFMT_IB_IF:
731 aif |= WM8955_BCLKINV | WM8955_LRP;
732 break;
733 case SND_SOC_DAIFMT_IB_NF:
734 aif |= WM8955_BCLKINV;
735 break;
736 case SND_SOC_DAIFMT_NB_IF:
737 aif |= WM8955_LRP;
738 break;
739 default:
740 return -EINVAL;
741 }
742 break;
743 default:
744 return -EINVAL;
745 }
746
747 snd_soc_update_bits(codec, WM8955_AUDIO_INTERFACE,
748 WM8955_MS | WM8955_FORMAT_MASK | WM8955_BCLKINV |
749 WM8955_LRP, aif);
750
751 return 0;
752}
753
754
755static int wm8955_digital_mute(struct snd_soc_dai *codec_dai, int mute)
756{
757 struct snd_soc_codec *codec = codec_dai->codec;
758 int val;
759
760 if (mute)
761 val = WM8955_DACMU;
762 else
763 val = 0;
764
765 snd_soc_update_bits(codec, WM8955_DAC_CONTROL, WM8955_DACMU, val);
766
767 return 0;
768}
769
770static int wm8955_set_bias_level(struct snd_soc_codec *codec,
771 enum snd_soc_bias_level level)
772{
773 struct wm8955_priv *wm8955 = codec->private_data;
774 int ret, i;
775
776 switch (level) {
777 case SND_SOC_BIAS_ON:
778 break;
779
780 case SND_SOC_BIAS_PREPARE:
781 /* VMID resistance 2*50k */
782 snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1,
783 WM8955_VMIDSEL_MASK,
784 0x1 << WM8955_VMIDSEL_SHIFT);
785
786 /* Default bias current */
787 snd_soc_update_bits(codec, WM8955_ADDITIONAL_CONTROL_1,
788 WM8955_VSEL_MASK,
789 0x2 << WM8955_VSEL_SHIFT);
790 break;
791
792 case SND_SOC_BIAS_STANDBY:
793 if (codec->bias_level == SND_SOC_BIAS_OFF) {
794 ret = regulator_bulk_enable(ARRAY_SIZE(wm8955->supplies),
795 wm8955->supplies);
796 if (ret != 0) {
797 dev_err(codec->dev,
798 "Failed to enable supplies: %d\n",
799 ret);
800 return ret;
801 }
802
803 /* Sync back cached values if they're
804 * different from the hardware default.
805 */
806 for (i = 0; i < ARRAY_SIZE(wm8955->reg_cache); i++) {
807 if (i == WM8955_RESET)
808 continue;
809
810 if (wm8955->reg_cache[i] == wm8955_reg[i])
811 continue;
812
813 snd_soc_write(codec, i, wm8955->reg_cache[i]);
814 }
815
816 /* Enable VREF and VMID */
817 snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1,
818 WM8955_VREF |
819 WM8955_VMIDSEL_MASK,
820 WM8955_VREF |
821 0x3 << WM8955_VREF_SHIFT);
822
823 /* Let VMID ramp */
824 msleep(500);
825
826 /* High resistance VROI to maintain outputs */
827 snd_soc_update_bits(codec,
828 WM8955_ADDITIONAL_CONTROL_3,
829 WM8955_VROI, WM8955_VROI);
830 }
831
832 /* Maintain VMID with 2*250k */
833 snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1,
834 WM8955_VMIDSEL_MASK,
835 0x2 << WM8955_VMIDSEL_SHIFT);
836
837 /* Minimum bias current */
838 snd_soc_update_bits(codec, WM8955_ADDITIONAL_CONTROL_1,
839 WM8955_VSEL_MASK, 0);
840 break;
841
842 case SND_SOC_BIAS_OFF:
843 /* Low resistance VROI to help discharge */
844 snd_soc_update_bits(codec,
845 WM8955_ADDITIONAL_CONTROL_3,
846 WM8955_VROI, 0);
847
848 /* Turn off VMID and VREF */
849 snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1,
850 WM8955_VREF |
851 WM8955_VMIDSEL_MASK, 0);
852
853 regulator_bulk_disable(ARRAY_SIZE(wm8955->supplies),
854 wm8955->supplies);
855 break;
856 }
857 codec->bias_level = level;
858 return 0;
859}
860
861#define WM8955_RATES SNDRV_PCM_RATE_8000_96000
862
863#define WM8955_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
864 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
865
866static struct snd_soc_dai_ops wm8955_dai_ops = {
867 .set_sysclk = wm8955_set_sysclk,
868 .set_fmt = wm8955_set_fmt,
869 .hw_params = wm8955_hw_params,
870 .digital_mute = wm8955_digital_mute,
871};
872
873struct snd_soc_dai wm8955_dai = {
874 .name = "WM8955",
875 .playback = {
876 .stream_name = "Playback",
877 .channels_min = 2,
878 .channels_max = 2,
879 .rates = WM8955_RATES,
880 .formats = WM8955_FORMATS,
881 },
882 .ops = &wm8955_dai_ops,
883};
884EXPORT_SYMBOL_GPL(wm8955_dai);
885
886#ifdef CONFIG_PM
887static int wm8955_suspend(struct platform_device *pdev, pm_message_t state)
888{
889 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
890 struct snd_soc_codec *codec = socdev->card->codec;
891
892 wm8955_set_bias_level(codec, SND_SOC_BIAS_OFF);
893
894 return 0;
895}
896
897static int wm8955_resume(struct platform_device *pdev)
898{
899 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
900 struct snd_soc_codec *codec = socdev->card->codec;
901
902 wm8955_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
903
904 return 0;
905}
906#else
907#define wm8955_suspend NULL
908#define wm8955_resume NULL
909#endif
910
911static int wm8955_probe(struct platform_device *pdev)
912{
913 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
914 struct snd_soc_codec *codec;
915 int ret = 0;
916
917 if (wm8955_codec == NULL) {
918 dev_err(&pdev->dev, "Codec device not registered\n");
919 return -ENODEV;
920 }
921
922 socdev->card->codec = wm8955_codec;
923 codec = wm8955_codec;
924
925 /* register pcms */
926 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
927 if (ret < 0) {
928 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
929 goto pcm_err;
930 }
931
932 wm8955_add_widgets(codec);
933
934 return ret;
935
936pcm_err:
937 return ret;
938}
939
940static int wm8955_remove(struct platform_device *pdev)
941{
942 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
943
944 snd_soc_free_pcms(socdev);
945 snd_soc_dapm_free(socdev);
946
947 return 0;
948}
949
950struct snd_soc_codec_device soc_codec_dev_wm8955 = {
951 .probe = wm8955_probe,
952 .remove = wm8955_remove,
953 .suspend = wm8955_suspend,
954 .resume = wm8955_resume,
955};
956EXPORT_SYMBOL_GPL(soc_codec_dev_wm8955);
957
958static int wm8955_register(struct wm8955_priv *wm8955,
959 enum snd_soc_control_type control)
960{
961 int ret;
962 struct snd_soc_codec *codec = &wm8955->codec;
963 int i;
964
965 if (wm8955_codec) {
966 dev_err(codec->dev, "Another WM8955 is registered\n");
967 return -EINVAL;
968 }
969
970 mutex_init(&codec->mutex);
971 INIT_LIST_HEAD(&codec->dapm_widgets);
972 INIT_LIST_HEAD(&codec->dapm_paths);
973
974 codec->private_data = wm8955;
975 codec->name = "WM8955";
976 codec->owner = THIS_MODULE;
977 codec->bias_level = SND_SOC_BIAS_OFF;
978 codec->set_bias_level = wm8955_set_bias_level;
979 codec->dai = &wm8955_dai;
980 codec->num_dai = 1;
981 codec->reg_cache_size = WM8955_MAX_REGISTER;
982 codec->reg_cache = &wm8955->reg_cache;
983
984 memcpy(codec->reg_cache, wm8955_reg, sizeof(wm8955_reg));
985
986 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
987 if (ret != 0) {
988 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
989 goto err;
990 }
991
992 for (i = 0; i < ARRAY_SIZE(wm8955->supplies); i++)
993 wm8955->supplies[i].supply = wm8955_supply_names[i];
994
995 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8955->supplies),
996 wm8955->supplies);
997 if (ret != 0) {
998 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
999 goto err;
1000 }
1001
1002 ret = regulator_bulk_enable(ARRAY_SIZE(wm8955->supplies),
1003 wm8955->supplies);
1004 if (ret != 0) {
1005 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
1006 goto err_get;
1007 }
1008
1009 ret = wm8955_reset(codec);
1010 if (ret < 0) {
1011 dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
1012 goto err_enable;
1013 }
1014
1015 wm8955_dai.dev = codec->dev;
1016
1017 /* Change some default settings - latch VU and enable ZC */
1018 wm8955->reg_cache[WM8955_LEFT_DAC_VOLUME] |= WM8955_LDVU;
1019 wm8955->reg_cache[WM8955_RIGHT_DAC_VOLUME] |= WM8955_RDVU;
1020 wm8955->reg_cache[WM8955_LOUT1_VOLUME] |= WM8955_LO1VU | WM8955_LO1ZC;
1021 wm8955->reg_cache[WM8955_ROUT1_VOLUME] |= WM8955_RO1VU | WM8955_RO1ZC;
1022 wm8955->reg_cache[WM8955_LOUT2_VOLUME] |= WM8955_LO2VU | WM8955_LO2ZC;
1023 wm8955->reg_cache[WM8955_ROUT2_VOLUME] |= WM8955_RO2VU | WM8955_RO2ZC;
1024 wm8955->reg_cache[WM8955_MONOOUT_VOLUME] |= WM8955_MOZC;
1025
1026 /* Also enable adaptive bass boost by default */
1027 wm8955->reg_cache[WM8955_BASS_CONTROL] |= WM8955_BB;
1028
1029 /* Set platform data values */
1030 if (wm8955->pdata) {
1031 if (wm8955->pdata->out2_speaker)
1032 wm8955->reg_cache[WM8955_ADDITIONAL_CONTROL_2]
1033 |= WM8955_ROUT2INV;
1034
1035 if (wm8955->pdata->monoin_diff)
1036 wm8955->reg_cache[WM8955_MONO_OUT_MIX_1]
1037 |= WM8955_DMEN;
1038 }
1039
1040 wm8955_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1041
1042 /* Bias level configuration will have done an extra enable */
1043 regulator_bulk_disable(ARRAY_SIZE(wm8955->supplies), wm8955->supplies);
1044
1045 wm8955_codec = codec;
1046
1047 ret = snd_soc_register_codec(codec);
1048 if (ret != 0) {
1049 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
1050 return ret;
1051 }
1052
1053 ret = snd_soc_register_dai(&wm8955_dai);
1054 if (ret != 0) {
1055 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
1056 snd_soc_unregister_codec(codec);
1057 return ret;
1058 }
1059
1060 return 0;
1061
1062err_enable:
1063 regulator_bulk_disable(ARRAY_SIZE(wm8955->supplies), wm8955->supplies);
1064err_get:
1065 regulator_bulk_free(ARRAY_SIZE(wm8955->supplies), wm8955->supplies);
1066err:
1067 kfree(wm8955);
1068 return ret;
1069}
1070
1071static void wm8955_unregister(struct wm8955_priv *wm8955)
1072{
1073 wm8955_set_bias_level(&wm8955->codec, SND_SOC_BIAS_OFF);
1074 regulator_bulk_free(ARRAY_SIZE(wm8955->supplies), wm8955->supplies);
1075 snd_soc_unregister_dai(&wm8955_dai);
1076 snd_soc_unregister_codec(&wm8955->codec);
1077 kfree(wm8955);
1078 wm8955_codec = NULL;
1079}
1080
1081#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1082static __devinit int wm8955_i2c_probe(struct i2c_client *i2c,
1083 const struct i2c_device_id *id)
1084{
1085 struct wm8955_priv *wm8955;
1086 struct snd_soc_codec *codec;
1087
1088 wm8955 = kzalloc(sizeof(struct wm8955_priv), GFP_KERNEL);
1089 if (wm8955 == NULL)
1090 return -ENOMEM;
1091
1092 codec = &wm8955->codec;
1093 codec->hw_write = (hw_write_t)i2c_master_send;
1094
1095 i2c_set_clientdata(i2c, wm8955);
1096 codec->control_data = i2c;
1097 wm8955->pdata = i2c->dev.platform_data;
1098
1099 codec->dev = &i2c->dev;
1100
1101 return wm8955_register(wm8955, SND_SOC_I2C);
1102}
1103
1104static __devexit int wm8955_i2c_remove(struct i2c_client *client)
1105{
1106 struct wm8955_priv *wm8955 = i2c_get_clientdata(client);
1107 wm8955_unregister(wm8955);
1108 return 0;
1109}
1110
1111static const struct i2c_device_id wm8955_i2c_id[] = {
1112 { "wm8955", 0 },
1113 { }
1114};
1115MODULE_DEVICE_TABLE(i2c, wm8955_i2c_id);
1116
1117static struct i2c_driver wm8955_i2c_driver = {
1118 .driver = {
1119 .name = "wm8955",
1120 .owner = THIS_MODULE,
1121 },
1122 .probe = wm8955_i2c_probe,
1123 .remove = __devexit_p(wm8955_i2c_remove),
1124 .id_table = wm8955_i2c_id,
1125};
1126#endif
1127
1128static int __init wm8955_modinit(void)
1129{
1130 int ret;
1131#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1132 ret = i2c_add_driver(&wm8955_i2c_driver);
1133 if (ret != 0) {
1134 printk(KERN_ERR "Failed to register WM8955 I2C driver: %d\n",
1135 ret);
1136 }
1137#endif
1138 return 0;
1139}
1140module_init(wm8955_modinit);
1141
1142static void __exit wm8955_exit(void)
1143{
1144#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1145 i2c_del_driver(&wm8955_i2c_driver);
1146#endif
1147}
1148module_exit(wm8955_exit);
1149
1150MODULE_DESCRIPTION("ASoC WM8955 driver");
1151MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
1152MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8955.h b/sound/soc/codecs/wm8955.h
new file mode 100644
index 000000000000..ae349c8531f6
--- /dev/null
+++ b/sound/soc/codecs/wm8955.h
@@ -0,0 +1,489 @@
1/*
2 * wm8955.h -- WM8904 ASoC driver
3 *
4 * Copyright 2009 Wolfson Microelectronics, plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef _WM8955_H
14#define _WM8955_H
15
16#define WM8955_CLK_MCLK 1
17
18extern struct snd_soc_dai wm8955_dai;
19extern struct snd_soc_codec_device soc_codec_dev_wm8955;
20
21/*
22 * Register values.
23 */
24#define WM8955_LOUT1_VOLUME 0x02
25#define WM8955_ROUT1_VOLUME 0x03
26#define WM8955_DAC_CONTROL 0x05
27#define WM8955_AUDIO_INTERFACE 0x07
28#define WM8955_SAMPLE_RATE 0x08
29#define WM8955_LEFT_DAC_VOLUME 0x0A
30#define WM8955_RIGHT_DAC_VOLUME 0x0B
31#define WM8955_BASS_CONTROL 0x0C
32#define WM8955_TREBLE_CONTROL 0x0D
33#define WM8955_RESET 0x0F
34#define WM8955_ADDITIONAL_CONTROL_1 0x17
35#define WM8955_ADDITIONAL_CONTROL_2 0x18
36#define WM8955_POWER_MANAGEMENT_1 0x19
37#define WM8955_POWER_MANAGEMENT_2 0x1A
38#define WM8955_ADDITIONAL_CONTROL_3 0x1B
39#define WM8955_LEFT_OUT_MIX_1 0x22
40#define WM8955_LEFT_OUT_MIX_2 0x23
41#define WM8955_RIGHT_OUT_MIX_1 0x24
42#define WM8955_RIGHT_OUT_MIX_2 0x25
43#define WM8955_MONO_OUT_MIX_1 0x26
44#define WM8955_MONO_OUT_MIX_2 0x27
45#define WM8955_LOUT2_VOLUME 0x28
46#define WM8955_ROUT2_VOLUME 0x29
47#define WM8955_MONOOUT_VOLUME 0x2A
48#define WM8955_CLOCKING_PLL 0x2B
49#define WM8955_PLL_CONTROL_1 0x2C
50#define WM8955_PLL_CONTROL_2 0x2D
51#define WM8955_PLL_CONTROL_3 0x2E
52#define WM8955_PLL_CONTROL_4 0x3B
53
54#define WM8955_REGISTER_COUNT 29
55#define WM8955_MAX_REGISTER 0x3B
56
57/*
58 * Field Definitions.
59 */
60
61/*
62 * R2 (0x02) - LOUT1 volume
63 */
64#define WM8955_LO1VU 0x0100 /* LO1VU */
65#define WM8955_LO1VU_MASK 0x0100 /* LO1VU */
66#define WM8955_LO1VU_SHIFT 8 /* LO1VU */
67#define WM8955_LO1VU_WIDTH 1 /* LO1VU */
68#define WM8955_LO1ZC 0x0080 /* LO1ZC */
69#define WM8955_LO1ZC_MASK 0x0080 /* LO1ZC */
70#define WM8955_LO1ZC_SHIFT 7 /* LO1ZC */
71#define WM8955_LO1ZC_WIDTH 1 /* LO1ZC */
72#define WM8955_LOUTVOL_MASK 0x007F /* LOUTVOL - [6:0] */
73#define WM8955_LOUTVOL_SHIFT 0 /* LOUTVOL - [6:0] */
74#define WM8955_LOUTVOL_WIDTH 7 /* LOUTVOL - [6:0] */
75
76/*
77 * R3 (0x03) - ROUT1 volume
78 */
79#define WM8955_RO1VU 0x0100 /* RO1VU */
80#define WM8955_RO1VU_MASK 0x0100 /* RO1VU */
81#define WM8955_RO1VU_SHIFT 8 /* RO1VU */
82#define WM8955_RO1VU_WIDTH 1 /* RO1VU */
83#define WM8955_RO1ZC 0x0080 /* RO1ZC */
84#define WM8955_RO1ZC_MASK 0x0080 /* RO1ZC */
85#define WM8955_RO1ZC_SHIFT 7 /* RO1ZC */
86#define WM8955_RO1ZC_WIDTH 1 /* RO1ZC */
87#define WM8955_ROUTVOL_MASK 0x007F /* ROUTVOL - [6:0] */
88#define WM8955_ROUTVOL_SHIFT 0 /* ROUTVOL - [6:0] */
89#define WM8955_ROUTVOL_WIDTH 7 /* ROUTVOL - [6:0] */
90
91/*
92 * R5 (0x05) - DAC Control
93 */
94#define WM8955_DAT 0x0080 /* DAT */
95#define WM8955_DAT_MASK 0x0080 /* DAT */
96#define WM8955_DAT_SHIFT 7 /* DAT */
97#define WM8955_DAT_WIDTH 1 /* DAT */
98#define WM8955_DACMU 0x0008 /* DACMU */
99#define WM8955_DACMU_MASK 0x0008 /* DACMU */
100#define WM8955_DACMU_SHIFT 3 /* DACMU */
101#define WM8955_DACMU_WIDTH 1 /* DACMU */
102#define WM8955_DEEMPH_MASK 0x0006 /* DEEMPH - [2:1] */
103#define WM8955_DEEMPH_SHIFT 1 /* DEEMPH - [2:1] */
104#define WM8955_DEEMPH_WIDTH 2 /* DEEMPH - [2:1] */
105
106/*
107 * R7 (0x07) - Audio Interface
108 */
109#define WM8955_BCLKINV 0x0080 /* BCLKINV */
110#define WM8955_BCLKINV_MASK 0x0080 /* BCLKINV */
111#define WM8955_BCLKINV_SHIFT 7 /* BCLKINV */
112#define WM8955_BCLKINV_WIDTH 1 /* BCLKINV */
113#define WM8955_MS 0x0040 /* MS */
114#define WM8955_MS_MASK 0x0040 /* MS */
115#define WM8955_MS_SHIFT 6 /* MS */
116#define WM8955_MS_WIDTH 1 /* MS */
117#define WM8955_LRSWAP 0x0020 /* LRSWAP */
118#define WM8955_LRSWAP_MASK 0x0020 /* LRSWAP */
119#define WM8955_LRSWAP_SHIFT 5 /* LRSWAP */
120#define WM8955_LRSWAP_WIDTH 1 /* LRSWAP */
121#define WM8955_LRP 0x0010 /* LRP */
122#define WM8955_LRP_MASK 0x0010 /* LRP */
123#define WM8955_LRP_SHIFT 4 /* LRP */
124#define WM8955_LRP_WIDTH 1 /* LRP */
125#define WM8955_WL_MASK 0x000C /* WL - [3:2] */
126#define WM8955_WL_SHIFT 2 /* WL - [3:2] */
127#define WM8955_WL_WIDTH 2 /* WL - [3:2] */
128#define WM8955_FORMAT_MASK 0x0003 /* FORMAT - [1:0] */
129#define WM8955_FORMAT_SHIFT 0 /* FORMAT - [1:0] */
130#define WM8955_FORMAT_WIDTH 2 /* FORMAT - [1:0] */
131
132/*
133 * R8 (0x08) - Sample Rate
134 */
135#define WM8955_BCLKDIV2 0x0080 /* BCLKDIV2 */
136#define WM8955_BCLKDIV2_MASK 0x0080 /* BCLKDIV2 */
137#define WM8955_BCLKDIV2_SHIFT 7 /* BCLKDIV2 */
138#define WM8955_BCLKDIV2_WIDTH 1 /* BCLKDIV2 */
139#define WM8955_MCLKDIV2 0x0040 /* MCLKDIV2 */
140#define WM8955_MCLKDIV2_MASK 0x0040 /* MCLKDIV2 */
141#define WM8955_MCLKDIV2_SHIFT 6 /* MCLKDIV2 */
142#define WM8955_MCLKDIV2_WIDTH 1 /* MCLKDIV2 */
143#define WM8955_SR_MASK 0x003E /* SR - [5:1] */
144#define WM8955_SR_SHIFT 1 /* SR - [5:1] */
145#define WM8955_SR_WIDTH 5 /* SR - [5:1] */
146#define WM8955_USB 0x0001 /* USB */
147#define WM8955_USB_MASK 0x0001 /* USB */
148#define WM8955_USB_SHIFT 0 /* USB */
149#define WM8955_USB_WIDTH 1 /* USB */
150
151/*
152 * R10 (0x0A) - Left DAC volume
153 */
154#define WM8955_LDVU 0x0100 /* LDVU */
155#define WM8955_LDVU_MASK 0x0100 /* LDVU */
156#define WM8955_LDVU_SHIFT 8 /* LDVU */
157#define WM8955_LDVU_WIDTH 1 /* LDVU */
158#define WM8955_LDACVOL_MASK 0x00FF /* LDACVOL - [7:0] */
159#define WM8955_LDACVOL_SHIFT 0 /* LDACVOL - [7:0] */
160#define WM8955_LDACVOL_WIDTH 8 /* LDACVOL - [7:0] */
161
162/*
163 * R11 (0x0B) - Right DAC volume
164 */
165#define WM8955_RDVU 0x0100 /* RDVU */
166#define WM8955_RDVU_MASK 0x0100 /* RDVU */
167#define WM8955_RDVU_SHIFT 8 /* RDVU */
168#define WM8955_RDVU_WIDTH 1 /* RDVU */
169#define WM8955_RDACVOL_MASK 0x00FF /* RDACVOL - [7:0] */
170#define WM8955_RDACVOL_SHIFT 0 /* RDACVOL - [7:0] */
171#define WM8955_RDACVOL_WIDTH 8 /* RDACVOL - [7:0] */
172
173/*
174 * R12 (0x0C) - Bass control
175 */
176#define WM8955_BB 0x0080 /* BB */
177#define WM8955_BB_MASK 0x0080 /* BB */
178#define WM8955_BB_SHIFT 7 /* BB */
179#define WM8955_BB_WIDTH 1 /* BB */
180#define WM8955_BC 0x0040 /* BC */
181#define WM8955_BC_MASK 0x0040 /* BC */
182#define WM8955_BC_SHIFT 6 /* BC */
183#define WM8955_BC_WIDTH 1 /* BC */
184#define WM8955_BASS_MASK 0x000F /* BASS - [3:0] */
185#define WM8955_BASS_SHIFT 0 /* BASS - [3:0] */
186#define WM8955_BASS_WIDTH 4 /* BASS - [3:0] */
187
188/*
189 * R13 (0x0D) - Treble control
190 */
191#define WM8955_TC 0x0040 /* TC */
192#define WM8955_TC_MASK 0x0040 /* TC */
193#define WM8955_TC_SHIFT 6 /* TC */
194#define WM8955_TC_WIDTH 1 /* TC */
195#define WM8955_TRBL_MASK 0x000F /* TRBL - [3:0] */
196#define WM8955_TRBL_SHIFT 0 /* TRBL - [3:0] */
197#define WM8955_TRBL_WIDTH 4 /* TRBL - [3:0] */
198
199/*
200 * R15 (0x0F) - Reset
201 */
202#define WM8955_RESET_MASK 0x01FF /* RESET - [8:0] */
203#define WM8955_RESET_SHIFT 0 /* RESET - [8:0] */
204#define WM8955_RESET_WIDTH 9 /* RESET - [8:0] */
205
206/*
207 * R23 (0x17) - Additional control (1)
208 */
209#define WM8955_TSDEN 0x0100 /* TSDEN */
210#define WM8955_TSDEN_MASK 0x0100 /* TSDEN */
211#define WM8955_TSDEN_SHIFT 8 /* TSDEN */
212#define WM8955_TSDEN_WIDTH 1 /* TSDEN */
213#define WM8955_VSEL_MASK 0x00C0 /* VSEL - [7:6] */
214#define WM8955_VSEL_SHIFT 6 /* VSEL - [7:6] */
215#define WM8955_VSEL_WIDTH 2 /* VSEL - [7:6] */
216#define WM8955_DMONOMIX_MASK 0x0030 /* DMONOMIX - [5:4] */
217#define WM8955_DMONOMIX_SHIFT 4 /* DMONOMIX - [5:4] */
218#define WM8955_DMONOMIX_WIDTH 2 /* DMONOMIX - [5:4] */
219#define WM8955_DACINV 0x0002 /* DACINV */
220#define WM8955_DACINV_MASK 0x0002 /* DACINV */
221#define WM8955_DACINV_SHIFT 1 /* DACINV */
222#define WM8955_DACINV_WIDTH 1 /* DACINV */
223#define WM8955_TOEN 0x0001 /* TOEN */
224#define WM8955_TOEN_MASK 0x0001 /* TOEN */
225#define WM8955_TOEN_SHIFT 0 /* TOEN */
226#define WM8955_TOEN_WIDTH 1 /* TOEN */
227
228/*
229 * R24 (0x18) - Additional control (2)
230 */
231#define WM8955_OUT3SW_MASK 0x0180 /* OUT3SW - [8:7] */
232#define WM8955_OUT3SW_SHIFT 7 /* OUT3SW - [8:7] */
233#define WM8955_OUT3SW_WIDTH 2 /* OUT3SW - [8:7] */
234#define WM8955_ROUT2INV 0x0010 /* ROUT2INV */
235#define WM8955_ROUT2INV_MASK 0x0010 /* ROUT2INV */
236#define WM8955_ROUT2INV_SHIFT 4 /* ROUT2INV */
237#define WM8955_ROUT2INV_WIDTH 1 /* ROUT2INV */
238#define WM8955_DACOSR 0x0001 /* DACOSR */
239#define WM8955_DACOSR_MASK 0x0001 /* DACOSR */
240#define WM8955_DACOSR_SHIFT 0 /* DACOSR */
241#define WM8955_DACOSR_WIDTH 1 /* DACOSR */
242
243/*
244 * R25 (0x19) - Power Management (1)
245 */
246#define WM8955_VMIDSEL_MASK 0x0180 /* VMIDSEL - [8:7] */
247#define WM8955_VMIDSEL_SHIFT 7 /* VMIDSEL - [8:7] */
248#define WM8955_VMIDSEL_WIDTH 2 /* VMIDSEL - [8:7] */
249#define WM8955_VREF 0x0040 /* VREF */
250#define WM8955_VREF_MASK 0x0040 /* VREF */
251#define WM8955_VREF_SHIFT 6 /* VREF */
252#define WM8955_VREF_WIDTH 1 /* VREF */
253#define WM8955_DIGENB 0x0001 /* DIGENB */
254#define WM8955_DIGENB_MASK 0x0001 /* DIGENB */
255#define WM8955_DIGENB_SHIFT 0 /* DIGENB */
256#define WM8955_DIGENB_WIDTH 1 /* DIGENB */
257
258/*
259 * R26 (0x1A) - Power Management (2)
260 */
261#define WM8955_DACL 0x0100 /* DACL */
262#define WM8955_DACL_MASK 0x0100 /* DACL */
263#define WM8955_DACL_SHIFT 8 /* DACL */
264#define WM8955_DACL_WIDTH 1 /* DACL */
265#define WM8955_DACR 0x0080 /* DACR */
266#define WM8955_DACR_MASK 0x0080 /* DACR */
267#define WM8955_DACR_SHIFT 7 /* DACR */
268#define WM8955_DACR_WIDTH 1 /* DACR */
269#define WM8955_LOUT1 0x0040 /* LOUT1 */
270#define WM8955_LOUT1_MASK 0x0040 /* LOUT1 */
271#define WM8955_LOUT1_SHIFT 6 /* LOUT1 */
272#define WM8955_LOUT1_WIDTH 1 /* LOUT1 */
273#define WM8955_ROUT1 0x0020 /* ROUT1 */
274#define WM8955_ROUT1_MASK 0x0020 /* ROUT1 */
275#define WM8955_ROUT1_SHIFT 5 /* ROUT1 */
276#define WM8955_ROUT1_WIDTH 1 /* ROUT1 */
277#define WM8955_LOUT2 0x0010 /* LOUT2 */
278#define WM8955_LOUT2_MASK 0x0010 /* LOUT2 */
279#define WM8955_LOUT2_SHIFT 4 /* LOUT2 */
280#define WM8955_LOUT2_WIDTH 1 /* LOUT2 */
281#define WM8955_ROUT2 0x0008 /* ROUT2 */
282#define WM8955_ROUT2_MASK 0x0008 /* ROUT2 */
283#define WM8955_ROUT2_SHIFT 3 /* ROUT2 */
284#define WM8955_ROUT2_WIDTH 1 /* ROUT2 */
285#define WM8955_MONO 0x0004 /* MONO */
286#define WM8955_MONO_MASK 0x0004 /* MONO */
287#define WM8955_MONO_SHIFT 2 /* MONO */
288#define WM8955_MONO_WIDTH 1 /* MONO */
289#define WM8955_OUT3 0x0002 /* OUT3 */
290#define WM8955_OUT3_MASK 0x0002 /* OUT3 */
291#define WM8955_OUT3_SHIFT 1 /* OUT3 */
292#define WM8955_OUT3_WIDTH 1 /* OUT3 */
293
294/*
295 * R27 (0x1B) - Additional Control (3)
296 */
297#define WM8955_VROI 0x0040 /* VROI */
298#define WM8955_VROI_MASK 0x0040 /* VROI */
299#define WM8955_VROI_SHIFT 6 /* VROI */
300#define WM8955_VROI_WIDTH 1 /* VROI */
301
302/*
303 * R34 (0x22) - Left out Mix (1)
304 */
305#define WM8955_LD2LO 0x0100 /* LD2LO */
306#define WM8955_LD2LO_MASK 0x0100 /* LD2LO */
307#define WM8955_LD2LO_SHIFT 8 /* LD2LO */
308#define WM8955_LD2LO_WIDTH 1 /* LD2LO */
309#define WM8955_LI2LO 0x0080 /* LI2LO */
310#define WM8955_LI2LO_MASK 0x0080 /* LI2LO */
311#define WM8955_LI2LO_SHIFT 7 /* LI2LO */
312#define WM8955_LI2LO_WIDTH 1 /* LI2LO */
313#define WM8955_LI2LOVOL_MASK 0x0070 /* LI2LOVOL - [6:4] */
314#define WM8955_LI2LOVOL_SHIFT 4 /* LI2LOVOL - [6:4] */
315#define WM8955_LI2LOVOL_WIDTH 3 /* LI2LOVOL - [6:4] */
316
317/*
318 * R35 (0x23) - Left out Mix (2)
319 */
320#define WM8955_RD2LO 0x0100 /* RD2LO */
321#define WM8955_RD2LO_MASK 0x0100 /* RD2LO */
322#define WM8955_RD2LO_SHIFT 8 /* RD2LO */
323#define WM8955_RD2LO_WIDTH 1 /* RD2LO */
324#define WM8955_RI2LO 0x0080 /* RI2LO */
325#define WM8955_RI2LO_MASK 0x0080 /* RI2LO */
326#define WM8955_RI2LO_SHIFT 7 /* RI2LO */
327#define WM8955_RI2LO_WIDTH 1 /* RI2LO */
328#define WM8955_RI2LOVOL_MASK 0x0070 /* RI2LOVOL - [6:4] */
329#define WM8955_RI2LOVOL_SHIFT 4 /* RI2LOVOL - [6:4] */
330#define WM8955_RI2LOVOL_WIDTH 3 /* RI2LOVOL - [6:4] */
331
332/*
333 * R36 (0x24) - Right out Mix (1)
334 */
335#define WM8955_LD2RO 0x0100 /* LD2RO */
336#define WM8955_LD2RO_MASK 0x0100 /* LD2RO */
337#define WM8955_LD2RO_SHIFT 8 /* LD2RO */
338#define WM8955_LD2RO_WIDTH 1 /* LD2RO */
339#define WM8955_LI2RO 0x0080 /* LI2RO */
340#define WM8955_LI2RO_MASK 0x0080 /* LI2RO */
341#define WM8955_LI2RO_SHIFT 7 /* LI2RO */
342#define WM8955_LI2RO_WIDTH 1 /* LI2RO */
343#define WM8955_LI2ROVOL_MASK 0x0070 /* LI2ROVOL - [6:4] */
344#define WM8955_LI2ROVOL_SHIFT 4 /* LI2ROVOL - [6:4] */
345#define WM8955_LI2ROVOL_WIDTH 3 /* LI2ROVOL - [6:4] */
346
347/*
348 * R37 (0x25) - Right Out Mix (2)
349 */
350#define WM8955_RD2RO 0x0100 /* RD2RO */
351#define WM8955_RD2RO_MASK 0x0100 /* RD2RO */
352#define WM8955_RD2RO_SHIFT 8 /* RD2RO */
353#define WM8955_RD2RO_WIDTH 1 /* RD2RO */
354#define WM8955_RI2RO 0x0080 /* RI2RO */
355#define WM8955_RI2RO_MASK 0x0080 /* RI2RO */
356#define WM8955_RI2RO_SHIFT 7 /* RI2RO */
357#define WM8955_RI2RO_WIDTH 1 /* RI2RO */
358#define WM8955_RI2ROVOL_MASK 0x0070 /* RI2ROVOL - [6:4] */
359#define WM8955_RI2ROVOL_SHIFT 4 /* RI2ROVOL - [6:4] */
360#define WM8955_RI2ROVOL_WIDTH 3 /* RI2ROVOL - [6:4] */
361
362/*
363 * R38 (0x26) - Mono out Mix (1)
364 */
365#define WM8955_LD2MO 0x0100 /* LD2MO */
366#define WM8955_LD2MO_MASK 0x0100 /* LD2MO */
367#define WM8955_LD2MO_SHIFT 8 /* LD2MO */
368#define WM8955_LD2MO_WIDTH 1 /* LD2MO */
369#define WM8955_LI2MO 0x0080 /* LI2MO */
370#define WM8955_LI2MO_MASK 0x0080 /* LI2MO */
371#define WM8955_LI2MO_SHIFT 7 /* LI2MO */
372#define WM8955_LI2MO_WIDTH 1 /* LI2MO */
373#define WM8955_LI2MOVOL_MASK 0x0070 /* LI2MOVOL - [6:4] */
374#define WM8955_LI2MOVOL_SHIFT 4 /* LI2MOVOL - [6:4] */
375#define WM8955_LI2MOVOL_WIDTH 3 /* LI2MOVOL - [6:4] */
376#define WM8955_DMEN 0x0001 /* DMEN */
377#define WM8955_DMEN_MASK 0x0001 /* DMEN */
378#define WM8955_DMEN_SHIFT 0 /* DMEN */
379#define WM8955_DMEN_WIDTH 1 /* DMEN */
380
381/*
382 * R39 (0x27) - Mono out Mix (2)
383 */
384#define WM8955_RD2MO 0x0100 /* RD2MO */
385#define WM8955_RD2MO_MASK 0x0100 /* RD2MO */
386#define WM8955_RD2MO_SHIFT 8 /* RD2MO */
387#define WM8955_RD2MO_WIDTH 1 /* RD2MO */
388#define WM8955_RI2MO 0x0080 /* RI2MO */
389#define WM8955_RI2MO_MASK 0x0080 /* RI2MO */
390#define WM8955_RI2MO_SHIFT 7 /* RI2MO */
391#define WM8955_RI2MO_WIDTH 1 /* RI2MO */
392#define WM8955_RI2MOVOL_MASK 0x0070 /* RI2MOVOL - [6:4] */
393#define WM8955_RI2MOVOL_SHIFT 4 /* RI2MOVOL - [6:4] */
394#define WM8955_RI2MOVOL_WIDTH 3 /* RI2MOVOL - [6:4] */
395
396/*
397 * R40 (0x28) - LOUT2 volume
398 */
399#define WM8955_LO2VU 0x0100 /* LO2VU */
400#define WM8955_LO2VU_MASK 0x0100 /* LO2VU */
401#define WM8955_LO2VU_SHIFT 8 /* LO2VU */
402#define WM8955_LO2VU_WIDTH 1 /* LO2VU */
403#define WM8955_LO2ZC 0x0080 /* LO2ZC */
404#define WM8955_LO2ZC_MASK 0x0080 /* LO2ZC */
405#define WM8955_LO2ZC_SHIFT 7 /* LO2ZC */
406#define WM8955_LO2ZC_WIDTH 1 /* LO2ZC */
407#define WM8955_LOUT2VOL_MASK 0x007F /* LOUT2VOL - [6:0] */
408#define WM8955_LOUT2VOL_SHIFT 0 /* LOUT2VOL - [6:0] */
409#define WM8955_LOUT2VOL_WIDTH 7 /* LOUT2VOL - [6:0] */
410
411/*
412 * R41 (0x29) - ROUT2 volume
413 */
414#define WM8955_RO2VU 0x0100 /* RO2VU */
415#define WM8955_RO2VU_MASK 0x0100 /* RO2VU */
416#define WM8955_RO2VU_SHIFT 8 /* RO2VU */
417#define WM8955_RO2VU_WIDTH 1 /* RO2VU */
418#define WM8955_RO2ZC 0x0080 /* RO2ZC */
419#define WM8955_RO2ZC_MASK 0x0080 /* RO2ZC */
420#define WM8955_RO2ZC_SHIFT 7 /* RO2ZC */
421#define WM8955_RO2ZC_WIDTH 1 /* RO2ZC */
422#define WM8955_ROUT2VOL_MASK 0x007F /* ROUT2VOL - [6:0] */
423#define WM8955_ROUT2VOL_SHIFT 0 /* ROUT2VOL - [6:0] */
424#define WM8955_ROUT2VOL_WIDTH 7 /* ROUT2VOL - [6:0] */
425
426/*
427 * R42 (0x2A) - MONOOUT volume
428 */
429#define WM8955_MOZC 0x0080 /* MOZC */
430#define WM8955_MOZC_MASK 0x0080 /* MOZC */
431#define WM8955_MOZC_SHIFT 7 /* MOZC */
432#define WM8955_MOZC_WIDTH 1 /* MOZC */
433#define WM8955_MOUTVOL_MASK 0x007F /* MOUTVOL - [6:0] */
434#define WM8955_MOUTVOL_SHIFT 0 /* MOUTVOL - [6:0] */
435#define WM8955_MOUTVOL_WIDTH 7 /* MOUTVOL - [6:0] */
436
437/*
438 * R43 (0x2B) - Clocking / PLL
439 */
440#define WM8955_MCLKSEL 0x0100 /* MCLKSEL */
441#define WM8955_MCLKSEL_MASK 0x0100 /* MCLKSEL */
442#define WM8955_MCLKSEL_SHIFT 8 /* MCLKSEL */
443#define WM8955_MCLKSEL_WIDTH 1 /* MCLKSEL */
444#define WM8955_PLLOUTDIV2 0x0020 /* PLLOUTDIV2 */
445#define WM8955_PLLOUTDIV2_MASK 0x0020 /* PLLOUTDIV2 */
446#define WM8955_PLLOUTDIV2_SHIFT 5 /* PLLOUTDIV2 */
447#define WM8955_PLLOUTDIV2_WIDTH 1 /* PLLOUTDIV2 */
448#define WM8955_PLL_RB 0x0010 /* PLL_RB */
449#define WM8955_PLL_RB_MASK 0x0010 /* PLL_RB */
450#define WM8955_PLL_RB_SHIFT 4 /* PLL_RB */
451#define WM8955_PLL_RB_WIDTH 1 /* PLL_RB */
452#define WM8955_PLLEN 0x0008 /* PLLEN */
453#define WM8955_PLLEN_MASK 0x0008 /* PLLEN */
454#define WM8955_PLLEN_SHIFT 3 /* PLLEN */
455#define WM8955_PLLEN_WIDTH 1 /* PLLEN */
456
457/*
458 * R44 (0x2C) - PLL Control 1
459 */
460#define WM8955_N_MASK 0x01E0 /* N - [8:5] */
461#define WM8955_N_SHIFT 5 /* N - [8:5] */
462#define WM8955_N_WIDTH 4 /* N - [8:5] */
463#define WM8955_K_21_18_MASK 0x000F /* K(21:18) - [3:0] */
464#define WM8955_K_21_18_SHIFT 0 /* K(21:18) - [3:0] */
465#define WM8955_K_21_18_WIDTH 4 /* K(21:18) - [3:0] */
466
467/*
468 * R45 (0x2D) - PLL Control 2
469 */
470#define WM8955_K_17_9_MASK 0x01FF /* K(17:9) - [8:0] */
471#define WM8955_K_17_9_SHIFT 0 /* K(17:9) - [8:0] */
472#define WM8955_K_17_9_WIDTH 9 /* K(17:9) - [8:0] */
473
474/*
475 * R46 (0x2E) - PLL Control 3
476 */
477#define WM8955_K_8_0_MASK 0x01FF /* K(8:0) - [8:0] */
478#define WM8955_K_8_0_SHIFT 0 /* K(8:0) - [8:0] */
479#define WM8955_K_8_0_WIDTH 9 /* K(8:0) - [8:0] */
480
481/*
482 * R59 (0x3B) - PLL Control 4
483 */
484#define WM8955_KEN 0x0080 /* KEN */
485#define WM8955_KEN_MASK 0x0080 /* KEN */
486#define WM8955_KEN_SHIFT 7 /* KEN */
487#define WM8955_KEN_WIDTH 1 /* KEN */
488
489#endif
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index f59703be61c8..f1e63e01b04d 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>
@@ -307,7 +308,6 @@ static int wm8960_add_widgets(struct snd_soc_codec *codec)
307 308
308 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); 309 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
309 310
310 snd_soc_dapm_new_widgets(codec);
311 return 0; 311 return 0;
312} 312}
313 313
@@ -540,8 +540,8 @@ static int pll_factors(unsigned int source, unsigned int target,
540 return 0; 540 return 0;
541} 541}
542 542
543static int wm8960_set_dai_pll(struct snd_soc_dai *codec_dai, 543static int wm8960_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
544 int pll_id, unsigned int freq_in, unsigned int freq_out) 544 int source, unsigned int freq_in, unsigned int freq_out)
545{ 545{
546 struct snd_soc_codec *codec = codec_dai->codec; 546 struct snd_soc_codec *codec = codec_dai->codec;
547 u16 reg; 547 u16 reg;
@@ -713,17 +713,9 @@ static int wm8960_probe(struct platform_device *pdev)
713 snd_soc_add_controls(codec, wm8960_snd_controls, 713 snd_soc_add_controls(codec, wm8960_snd_controls,
714 ARRAY_SIZE(wm8960_snd_controls)); 714 ARRAY_SIZE(wm8960_snd_controls));
715 wm8960_add_widgets(codec); 715 wm8960_add_widgets(codec);
716 ret = snd_soc_init_card(socdev);
717 if (ret < 0) {
718 dev_err(codec->dev, "failed to register card: %d\n", ret);
719 goto card_err;
720 }
721 716
722 return ret; 717 return ret;
723 718
724card_err:
725 snd_soc_free_pcms(socdev);
726 snd_soc_dapm_free(socdev);
727pcm_err: 719pcm_err:
728 return ret; 720 return ret;
729} 721}
@@ -883,21 +875,6 @@ static __devexit int wm8960_i2c_remove(struct i2c_client *client)
883 return 0; 875 return 0;
884} 876}
885 877
886#ifdef CONFIG_PM
887static int wm8960_i2c_suspend(struct i2c_client *client, pm_message_t msg)
888{
889 return snd_soc_suspend_device(&client->dev);
890}
891
892static int wm8960_i2c_resume(struct i2c_client *client)
893{
894 return snd_soc_resume_device(&client->dev);
895}
896#else
897#define wm8960_i2c_suspend NULL
898#define wm8960_i2c_resume NULL
899#endif
900
901static const struct i2c_device_id wm8960_i2c_id[] = { 878static const struct i2c_device_id wm8960_i2c_id[] = {
902 { "wm8960", 0 }, 879 { "wm8960", 0 },
903 { } 880 { }
@@ -911,8 +888,6 @@ static struct i2c_driver wm8960_i2c_driver = {
911 }, 888 },
912 .probe = wm8960_i2c_probe, 889 .probe = wm8960_i2c_probe,
913 .remove = __devexit_p(wm8960_i2c_remove), 890 .remove = __devexit_p(wm8960_i2c_remove),
914 .suspend = wm8960_i2c_suspend,
915 .resume = wm8960_i2c_resume,
916 .id_table = wm8960_i2c_id, 891 .id_table = wm8960_i2c_id,
917}; 892};
918 893
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c
index 503032085899..50634ab76a5c 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>
@@ -986,19 +987,9 @@ static int wm8961_probe(struct platform_device *pdev)
986 snd_soc_dapm_new_controls(codec, wm8961_dapm_widgets, 987 snd_soc_dapm_new_controls(codec, wm8961_dapm_widgets,
987 ARRAY_SIZE(wm8961_dapm_widgets)); 988 ARRAY_SIZE(wm8961_dapm_widgets));
988 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); 989 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
989 snd_soc_dapm_new_widgets(codec);
990
991 ret = snd_soc_init_card(socdev);
992 if (ret < 0) {
993 dev_err(codec->dev, "failed to register card: %d\n", ret);
994 goto card_err;
995 }
996 990
997 return ret; 991 return ret;
998 992
999card_err:
1000 snd_soc_free_pcms(socdev);
1001 snd_soc_dapm_free(socdev);
1002pcm_err: 993pcm_err:
1003 return ret; 994 return ret;
1004} 995}
@@ -1032,6 +1023,9 @@ static int wm8961_resume(struct platform_device *pdev)
1032 int i; 1023 int i;
1033 1024
1034 for (i = 0; i < codec->reg_cache_size; i++) { 1025 for (i = 0; i < codec->reg_cache_size; i++) {
1026 if (reg_cache[i] == wm8961_reg_defaults[i])
1027 continue;
1028
1035 if (i == WM8961_SOFTWARE_RESET) 1029 if (i == WM8961_SOFTWARE_RESET)
1036 continue; 1030 continue;
1037 1031
@@ -1206,21 +1200,6 @@ static __devexit int wm8961_i2c_remove(struct i2c_client *client)
1206 return 0; 1200 return 0;
1207} 1201}
1208 1202
1209#ifdef CONFIG_PM
1210static int wm8961_i2c_suspend(struct i2c_client *client, pm_message_t state)
1211{
1212 return snd_soc_suspend_device(&client->dev);
1213}
1214
1215static int wm8961_i2c_resume(struct i2c_client *client)
1216{
1217 return snd_soc_resume_device(&client->dev);
1218}
1219#else
1220#define wm8961_i2c_suspend NULL
1221#define wm8961_i2c_resume NULL
1222#endif
1223
1224static const struct i2c_device_id wm8961_i2c_id[] = { 1203static const struct i2c_device_id wm8961_i2c_id[] = {
1225 { "wm8961", 0 }, 1204 { "wm8961", 0 },
1226 { } 1205 { }
@@ -1234,8 +1213,6 @@ static struct i2c_driver wm8961_i2c_driver = {
1234 }, 1213 },
1235 .probe = wm8961_i2c_probe, 1214 .probe = wm8961_i2c_probe,
1236 .remove = __devexit_p(wm8961_i2c_remove), 1215 .remove = __devexit_p(wm8961_i2c_remove),
1237 .suspend = wm8961_i2c_suspend,
1238 .resume = wm8961_i2c_resume,
1239 .id_table = wm8961_i2c_id, 1216 .id_table = wm8961_i2c_id,
1240}; 1217};
1241 1218
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c
index d66efb0546ea..a65b781af512 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>
@@ -338,8 +339,6 @@ static int wm8971_add_widgets(struct snd_soc_codec *codec)
338 339
339 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 340 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
340 341
341 snd_soc_dapm_new_widgets(codec);
342
343 return 0; 342 return 0;
344} 343}
345 344
@@ -703,16 +702,9 @@ static int wm8971_init(struct snd_soc_device *socdev,
703 snd_soc_add_controls(codec, wm8971_snd_controls, 702 snd_soc_add_controls(codec, wm8971_snd_controls,
704 ARRAY_SIZE(wm8971_snd_controls)); 703 ARRAY_SIZE(wm8971_snd_controls));
705 wm8971_add_widgets(codec); 704 wm8971_add_widgets(codec);
706 ret = snd_soc_init_card(socdev); 705
707 if (ret < 0) {
708 printk(KERN_ERR "wm8971: failed to register card\n");
709 goto card_err;
710 }
711 return ret; 706 return ret;
712 707
713card_err:
714 snd_soc_free_pcms(socdev);
715 snd_soc_dapm_free(socdev);
716err: 708err:
717 kfree(codec->reg_cache); 709 kfree(codec->reg_cache);
718 return ret; 710 return ret;
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c
index 98d663afc97d..69708c4cc004 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>
@@ -47,7 +48,7 @@ static const u16 wm8974_reg[WM8974_CACHEREGNUM] = {
47}; 48};
48 49
49#define WM8974_POWER1_BIASEN 0x08 50#define WM8974_POWER1_BIASEN 0x08
50#define WM8974_POWER1_BUFIOEN 0x10 51#define WM8974_POWER1_BUFIOEN 0x04
51 52
52struct wm8974_priv { 53struct wm8974_priv {
53 struct snd_soc_codec codec; 54 struct snd_soc_codec codec;
@@ -170,6 +171,10 @@ SOC_ENUM("Aux Mode", wm8974_auxmode),
170 171
171SOC_SINGLE("Capture Boost(+20dB)", WM8974_ADCBOOST, 8, 1, 0), 172SOC_SINGLE("Capture Boost(+20dB)", WM8974_ADCBOOST, 8, 1, 0),
172SOC_SINGLE("Mono Playback Switch", WM8974_MONOMIX, 6, 1, 1), 173SOC_SINGLE("Mono Playback Switch", WM8974_MONOMIX, 6, 1, 1),
174
175/* DAC / ADC oversampling */
176SOC_SINGLE("DAC 128x Oversampling Switch", WM8974_DAC, 8, 1, 0),
177SOC_SINGLE("ADC 128x Oversampling Switch", WM8974_ADC, 8, 1, 0),
173}; 178};
174 179
175/* Speaker Output Mixer */ 180/* Speaker Output Mixer */
@@ -276,41 +281,42 @@ static int wm8974_add_widgets(struct snd_soc_codec *codec)
276 281
277 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 282 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
278 283
279 snd_soc_dapm_new_widgets(codec);
280 return 0; 284 return 0;
281} 285}
282 286
283struct pll_ { 287struct pll_ {
284 unsigned int pre_div:4; /* prescale - 1 */ 288 unsigned int pre_div:1;
285 unsigned int n:4; 289 unsigned int n:4;
286 unsigned int k; 290 unsigned int k;
287}; 291};
288 292
289static struct pll_ pll_div;
290
291/* The size in bits of the pll divide multiplied by 10 293/* The size in bits of the pll divide multiplied by 10
292 * to allow rounding later */ 294 * to allow rounding later */
293#define FIXED_PLL_SIZE ((1 << 24) * 10) 295#define FIXED_PLL_SIZE ((1 << 24) * 10)
294 296
295static void pll_factors(unsigned int target, unsigned int source) 297static void pll_factors(struct pll_ *pll_div,
298 unsigned int target, unsigned int source)
296{ 299{
297 unsigned long long Kpart; 300 unsigned long long Kpart;
298 unsigned int K, Ndiv, Nmod; 301 unsigned int K, Ndiv, Nmod;
299 302
303 /* There is a fixed divide by 4 in the output path */
304 target *= 4;
305
300 Ndiv = target / source; 306 Ndiv = target / source;
301 if (Ndiv < 6) { 307 if (Ndiv < 6) {
302 source >>= 1; 308 source /= 2;
303 pll_div.pre_div = 1; 309 pll_div->pre_div = 1;
304 Ndiv = target / source; 310 Ndiv = target / source;
305 } else 311 } else
306 pll_div.pre_div = 0; 312 pll_div->pre_div = 0;
307 313
308 if ((Ndiv < 6) || (Ndiv > 12)) 314 if ((Ndiv < 6) || (Ndiv > 12))
309 printk(KERN_WARNING 315 printk(KERN_WARNING
310 "WM8974 N value %u outwith recommended range!\n", 316 "WM8974 N value %u outwith recommended range!\n",
311 Ndiv); 317 Ndiv);
312 318
313 pll_div.n = Ndiv; 319 pll_div->n = Ndiv;
314 Nmod = target % source; 320 Nmod = target % source;
315 Kpart = FIXED_PLL_SIZE * (long long)Nmod; 321 Kpart = FIXED_PLL_SIZE * (long long)Nmod;
316 322
@@ -325,13 +331,14 @@ static void pll_factors(unsigned int target, unsigned int source)
325 /* Move down to proper range now rounding is done */ 331 /* Move down to proper range now rounding is done */
326 K /= 10; 332 K /= 10;
327 333
328 pll_div.k = K; 334 pll_div->k = K;
329} 335}
330 336
331static int wm8974_set_dai_pll(struct snd_soc_dai *codec_dai, 337static int wm8974_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
332 int pll_id, unsigned int freq_in, unsigned int freq_out) 338 int source, unsigned int freq_in, unsigned int freq_out)
333{ 339{
334 struct snd_soc_codec *codec = codec_dai->codec; 340 struct snd_soc_codec *codec = codec_dai->codec;
341 struct pll_ pll_div;
335 u16 reg; 342 u16 reg;
336 343
337 if (freq_in == 0 || freq_out == 0) { 344 if (freq_in == 0 || freq_out == 0) {
@@ -345,7 +352,7 @@ static int wm8974_set_dai_pll(struct snd_soc_dai *codec_dai,
345 return 0; 352 return 0;
346 } 353 }
347 354
348 pll_factors(freq_out*4, freq_in); 355 pll_factors(&pll_div, freq_out, freq_in);
349 356
350 snd_soc_write(codec, WM8974_PLLN, (pll_div.pre_div << 4) | pll_div.n); 357 snd_soc_write(codec, WM8974_PLLN, (pll_div.pre_div << 4) | pll_div.n);
351 snd_soc_write(codec, WM8974_PLLK1, pll_div.k >> 18); 358 snd_soc_write(codec, WM8974_PLLK1, pll_div.k >> 18);
@@ -379,14 +386,6 @@ static int wm8974_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
379 reg = snd_soc_read(codec, WM8974_CLOCK) & 0x11f; 386 reg = snd_soc_read(codec, WM8974_CLOCK) & 0x11f;
380 snd_soc_write(codec, WM8974_CLOCK, reg | div); 387 snd_soc_write(codec, WM8974_CLOCK, reg | div);
381 break; 388 break;
382 case WM8974_ADCCLK:
383 reg = snd_soc_read(codec, WM8974_ADC) & 0x1f7;
384 snd_soc_write(codec, WM8974_ADC, reg | div);
385 break;
386 case WM8974_DACCLK:
387 reg = snd_soc_read(codec, WM8974_DAC) & 0x1f7;
388 snd_soc_write(codec, WM8974_DAC, reg | div);
389 break;
390 case WM8974_BCLKDIV: 389 case WM8974_BCLKDIV:
391 reg = snd_soc_read(codec, WM8974_CLOCK) & 0x1e3; 390 reg = snd_soc_read(codec, WM8974_CLOCK) & 0x1e3;
392 snd_soc_write(codec, WM8974_CLOCK, reg | div); 391 snd_soc_write(codec, WM8974_CLOCK, reg | div);
@@ -480,23 +479,23 @@ static int wm8974_pcm_hw_params(struct snd_pcm_substream *substream,
480 479
481 /* filter coefficient */ 480 /* filter coefficient */
482 switch (params_rate(params)) { 481 switch (params_rate(params)) {
483 case SNDRV_PCM_RATE_8000: 482 case 8000:
484 adn |= 0x5 << 1; 483 adn |= 0x5 << 1;
485 break; 484 break;
486 case SNDRV_PCM_RATE_11025: 485 case 11025:
487 adn |= 0x4 << 1; 486 adn |= 0x4 << 1;
488 break; 487 break;
489 case SNDRV_PCM_RATE_16000: 488 case 16000:
490 adn |= 0x3 << 1; 489 adn |= 0x3 << 1;
491 break; 490 break;
492 case SNDRV_PCM_RATE_22050: 491 case 22050:
493 adn |= 0x2 << 1; 492 adn |= 0x2 << 1;
494 break; 493 break;
495 case SNDRV_PCM_RATE_32000: 494 case 32000:
496 adn |= 0x1 << 1; 495 adn |= 0x1 << 1;
497 break; 496 break;
498 case SNDRV_PCM_RATE_44100: 497 case 44100:
499 case SNDRV_PCM_RATE_48000: 498 case 48000:
500 break; 499 break;
501 } 500 }
502 501
@@ -638,17 +637,9 @@ static int wm8974_probe(struct platform_device *pdev)
638 snd_soc_add_controls(codec, wm8974_snd_controls, 637 snd_soc_add_controls(codec, wm8974_snd_controls,
639 ARRAY_SIZE(wm8974_snd_controls)); 638 ARRAY_SIZE(wm8974_snd_controls));
640 wm8974_add_widgets(codec); 639 wm8974_add_widgets(codec);
641 ret = snd_soc_init_card(socdev);
642 if (ret < 0) {
643 dev_err(codec->dev, "failed to register card: %d\n", ret);
644 goto card_err;
645 }
646 640
647 return ret; 641 return ret;
648 642
649card_err:
650 snd_soc_free_pcms(socdev);
651 snd_soc_dapm_free(socdev);
652pcm_err: 643pcm_err:
653 return ret; 644 return ret;
654} 645}
diff --git a/sound/soc/codecs/wm8974.h b/sound/soc/codecs/wm8974.h
index 98de9562d4d2..896a7f0f3fc4 100644
--- a/sound/soc/codecs/wm8974.h
+++ b/sound/soc/codecs/wm8974.h
@@ -57,17 +57,7 @@
57/* Clock divider Id's */ 57/* Clock divider Id's */
58#define WM8974_OPCLKDIV 0 58#define WM8974_OPCLKDIV 0
59#define WM8974_MCLKDIV 1 59#define WM8974_MCLKDIV 1
60#define WM8974_ADCCLK 2 60#define WM8974_BCLKDIV 2
61#define WM8974_DACCLK 3
62#define WM8974_BCLKDIV 4
63
64/* DAC clock dividers */
65#define WM8974_DACCLK_F2 (1 << 3)
66#define WM8974_DACCLK_F4 (0 << 3)
67
68/* ADC clock dividers */
69#define WM8974_ADCCLK_F2 (1 << 3)
70#define WM8974_ADCCLK_F4 (0 << 3)
71 61
72/* PLL Out dividers */ 62/* PLL Out dividers */
73#define WM8974_OPCLKDIV_1 (0 << 4) 63#define WM8974_OPCLKDIV_1 (0 << 4)
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c
new file mode 100644
index 000000000000..526f56b09066
--- /dev/null
+++ b/sound/soc/codecs/wm8978.c
@@ -0,0 +1,1150 @@
1/*
2 * wm8978.c -- WM8978 ALSA SoC Audio Codec driver
3 *
4 * Copyright (C) 2009-2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
5 * Copyright (C) 2007 Carlos Munoz <carlos@kenati.com>
6 * Copyright 2006-2009 Wolfson Microelectronics PLC.
7 * Based on wm8974 and wm8990 by Liam Girdwood <lrg@slimlogic.co.uk>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/module.h>
15#include <linux/moduleparam.h>
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/delay.h>
19#include <linux/pm.h>
20#include <linux/i2c.h>
21#include <linux/platform_device.h>
22#include <linux/slab.h>
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/initval.h>
29#include <sound/tlv.h>
30#include <asm/div64.h>
31
32#include "wm8978.h"
33
34static struct snd_soc_codec *wm8978_codec;
35
36/* wm8978 register cache. Note that register 0 is not included in the cache. */
37static const u16 wm8978_reg[WM8978_CACHEREGNUM] = {
38 0x0000, 0x0000, 0x0000, 0x0000, /* 0x00...0x03 */
39 0x0050, 0x0000, 0x0140, 0x0000, /* 0x04...0x07 */
40 0x0000, 0x0000, 0x0000, 0x00ff, /* 0x08...0x0b */
41 0x00ff, 0x0000, 0x0100, 0x00ff, /* 0x0c...0x0f */
42 0x00ff, 0x0000, 0x012c, 0x002c, /* 0x10...0x13 */
43 0x002c, 0x002c, 0x002c, 0x0000, /* 0x14...0x17 */
44 0x0032, 0x0000, 0x0000, 0x0000, /* 0x18...0x1b */
45 0x0000, 0x0000, 0x0000, 0x0000, /* 0x1c...0x1f */
46 0x0038, 0x000b, 0x0032, 0x0000, /* 0x20...0x23 */
47 0x0008, 0x000c, 0x0093, 0x00e9, /* 0x24...0x27 */
48 0x0000, 0x0000, 0x0000, 0x0000, /* 0x28...0x2b */
49 0x0033, 0x0010, 0x0010, 0x0100, /* 0x2c...0x2f */
50 0x0100, 0x0002, 0x0001, 0x0001, /* 0x30...0x33 */
51 0x0039, 0x0039, 0x0039, 0x0039, /* 0x34...0x37 */
52 0x0001, 0x0001, /* 0x38...0x3b */
53};
54
55/* codec private data */
56struct wm8978_priv {
57 struct snd_soc_codec codec;
58 unsigned int f_pllout;
59 unsigned int f_mclk;
60 unsigned int f_256fs;
61 unsigned int f_opclk;
62 int mclk_idx;
63 enum wm8978_sysclk_src sysclk;
64 u16 reg_cache[WM8978_CACHEREGNUM];
65};
66
67static const char *wm8978_companding[] = {"Off", "NC", "u-law", "A-law"};
68static const char *wm8978_eqmode[] = {"Capture", "Playback"};
69static const char *wm8978_bw[] = {"Narrow", "Wide"};
70static const char *wm8978_eq1[] = {"80Hz", "105Hz", "135Hz", "175Hz"};
71static const char *wm8978_eq2[] = {"230Hz", "300Hz", "385Hz", "500Hz"};
72static const char *wm8978_eq3[] = {"650Hz", "850Hz", "1.1kHz", "1.4kHz"};
73static const char *wm8978_eq4[] = {"1.8kHz", "2.4kHz", "3.2kHz", "4.1kHz"};
74static const char *wm8978_eq5[] = {"5.3kHz", "6.9kHz", "9kHz", "11.7kHz"};
75static const char *wm8978_alc3[] = {"ALC", "Limiter"};
76static const char *wm8978_alc1[] = {"Off", "Right", "Left", "Both"};
77
78static const SOC_ENUM_SINGLE_DECL(adc_compand, WM8978_COMPANDING_CONTROL, 1,
79 wm8978_companding);
80static const SOC_ENUM_SINGLE_DECL(dac_compand, WM8978_COMPANDING_CONTROL, 3,
81 wm8978_companding);
82static const SOC_ENUM_SINGLE_DECL(eqmode, WM8978_EQ1, 8, wm8978_eqmode);
83static const SOC_ENUM_SINGLE_DECL(eq1, WM8978_EQ1, 5, wm8978_eq1);
84static const SOC_ENUM_SINGLE_DECL(eq2bw, WM8978_EQ2, 8, wm8978_bw);
85static const SOC_ENUM_SINGLE_DECL(eq2, WM8978_EQ2, 5, wm8978_eq2);
86static const SOC_ENUM_SINGLE_DECL(eq3bw, WM8978_EQ3, 8, wm8978_bw);
87static const SOC_ENUM_SINGLE_DECL(eq3, WM8978_EQ3, 5, wm8978_eq3);
88static const SOC_ENUM_SINGLE_DECL(eq4bw, WM8978_EQ4, 8, wm8978_bw);
89static const SOC_ENUM_SINGLE_DECL(eq4, WM8978_EQ4, 5, wm8978_eq4);
90static const SOC_ENUM_SINGLE_DECL(eq5, WM8978_EQ5, 5, wm8978_eq5);
91static const SOC_ENUM_SINGLE_DECL(alc3, WM8978_ALC_CONTROL_3, 8, wm8978_alc3);
92static const SOC_ENUM_SINGLE_DECL(alc1, WM8978_ALC_CONTROL_1, 7, wm8978_alc1);
93
94static const DECLARE_TLV_DB_SCALE(digital_tlv, -12750, 50, 1);
95static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
96static const DECLARE_TLV_DB_SCALE(inpga_tlv, -1200, 75, 0);
97static const DECLARE_TLV_DB_SCALE(spk_tlv, -5700, 100, 0);
98static const DECLARE_TLV_DB_SCALE(boost_tlv, -1500, 300, 1);
99
100static const struct snd_kcontrol_new wm8978_snd_controls[] = {
101
102 SOC_SINGLE("Digital Loopback Switch",
103 WM8978_COMPANDING_CONTROL, 0, 1, 0),
104
105 SOC_ENUM("ADC Companding", adc_compand),
106 SOC_ENUM("DAC Companding", dac_compand),
107
108 SOC_DOUBLE("DAC Inversion Switch", WM8978_DAC_CONTROL, 0, 1, 1, 0),
109
110 SOC_DOUBLE_R_TLV("PCM Volume",
111 WM8978_LEFT_DAC_DIGITAL_VOLUME, WM8978_RIGHT_DAC_DIGITAL_VOLUME,
112 0, 255, 0, digital_tlv),
113
114 SOC_SINGLE("High Pass Filter Switch", WM8978_ADC_CONTROL, 8, 1, 0),
115 SOC_SINGLE("High Pass Cut Off", WM8978_ADC_CONTROL, 4, 7, 0),
116 SOC_DOUBLE("ADC Inversion Switch", WM8978_ADC_CONTROL, 0, 1, 1, 0),
117
118 SOC_DOUBLE_R_TLV("ADC Volume",
119 WM8978_LEFT_ADC_DIGITAL_VOLUME, WM8978_RIGHT_ADC_DIGITAL_VOLUME,
120 0, 255, 0, digital_tlv),
121
122 SOC_ENUM("Equaliser Function", eqmode),
123 SOC_ENUM("EQ1 Cut Off", eq1),
124 SOC_SINGLE_TLV("EQ1 Volume", WM8978_EQ1, 0, 24, 1, eq_tlv),
125
126 SOC_ENUM("Equaliser EQ2 Bandwith", eq2bw),
127 SOC_ENUM("EQ2 Cut Off", eq2),
128 SOC_SINGLE_TLV("EQ2 Volume", WM8978_EQ2, 0, 24, 1, eq_tlv),
129
130 SOC_ENUM("Equaliser EQ3 Bandwith", eq3bw),
131 SOC_ENUM("EQ3 Cut Off", eq3),
132 SOC_SINGLE_TLV("EQ3 Volume", WM8978_EQ3, 0, 24, 1, eq_tlv),
133
134 SOC_ENUM("Equaliser EQ4 Bandwith", eq4bw),
135 SOC_ENUM("EQ4 Cut Off", eq4),
136 SOC_SINGLE_TLV("EQ4 Volume", WM8978_EQ4, 0, 24, 1, eq_tlv),
137
138 SOC_ENUM("EQ5 Cut Off", eq5),
139 SOC_SINGLE_TLV("EQ5 Volume", WM8978_EQ5, 0, 24, 1, eq_tlv),
140
141 SOC_SINGLE("DAC Playback Limiter Switch",
142 WM8978_DAC_LIMITER_1, 8, 1, 0),
143 SOC_SINGLE("DAC Playback Limiter Decay",
144 WM8978_DAC_LIMITER_1, 4, 15, 0),
145 SOC_SINGLE("DAC Playback Limiter Attack",
146 WM8978_DAC_LIMITER_1, 0, 15, 0),
147
148 SOC_SINGLE("DAC Playback Limiter Threshold",
149 WM8978_DAC_LIMITER_2, 4, 7, 0),
150 SOC_SINGLE("DAC Playback Limiter Boost",
151 WM8978_DAC_LIMITER_2, 0, 15, 0),
152
153 SOC_ENUM("ALC Enable Switch", alc1),
154 SOC_SINGLE("ALC Capture Min Gain", WM8978_ALC_CONTROL_1, 0, 7, 0),
155 SOC_SINGLE("ALC Capture Max Gain", WM8978_ALC_CONTROL_1, 3, 7, 0),
156
157 SOC_SINGLE("ALC Capture Hold", WM8978_ALC_CONTROL_2, 4, 7, 0),
158 SOC_SINGLE("ALC Capture Target", WM8978_ALC_CONTROL_2, 0, 15, 0),
159
160 SOC_ENUM("ALC Capture Mode", alc3),
161 SOC_SINGLE("ALC Capture Decay", WM8978_ALC_CONTROL_3, 4, 15, 0),
162 SOC_SINGLE("ALC Capture Attack", WM8978_ALC_CONTROL_3, 0, 15, 0),
163
164 SOC_SINGLE("ALC Capture Noise Gate Switch", WM8978_NOISE_GATE, 3, 1, 0),
165 SOC_SINGLE("ALC Capture Noise Gate Threshold",
166 WM8978_NOISE_GATE, 0, 7, 0),
167
168 SOC_DOUBLE_R("Capture PGA ZC Switch",
169 WM8978_LEFT_INP_PGA_CONTROL, WM8978_RIGHT_INP_PGA_CONTROL,
170 7, 1, 0),
171
172 /* OUT1 - Headphones */
173 SOC_DOUBLE_R("Headphone Playback ZC Switch",
174 WM8978_LOUT1_HP_CONTROL, WM8978_ROUT1_HP_CONTROL, 7, 1, 0),
175
176 SOC_DOUBLE_R_TLV("Headphone Playback Volume",
177 WM8978_LOUT1_HP_CONTROL, WM8978_ROUT1_HP_CONTROL,
178 0, 63, 0, spk_tlv),
179
180 /* OUT2 - Speakers */
181 SOC_DOUBLE_R("Speaker Playback ZC Switch",
182 WM8978_LOUT2_SPK_CONTROL, WM8978_ROUT2_SPK_CONTROL, 7, 1, 0),
183
184 SOC_DOUBLE_R_TLV("Speaker Playback Volume",
185 WM8978_LOUT2_SPK_CONTROL, WM8978_ROUT2_SPK_CONTROL,
186 0, 63, 0, spk_tlv),
187
188 /* OUT3/4 - Line Output */
189 SOC_DOUBLE_R("Line Playback Switch",
190 WM8978_OUT3_MIXER_CONTROL, WM8978_OUT4_MIXER_CONTROL, 6, 1, 1),
191
192 /* Mixer #3: Boost (Input) mixer */
193 SOC_DOUBLE_R("PGA Boost (+20dB)",
194 WM8978_LEFT_ADC_BOOST_CONTROL, WM8978_RIGHT_ADC_BOOST_CONTROL,
195 8, 1, 0),
196 SOC_DOUBLE_R_TLV("L2/R2 Boost Volume",
197 WM8978_LEFT_ADC_BOOST_CONTROL, WM8978_RIGHT_ADC_BOOST_CONTROL,
198 4, 7, 0, boost_tlv),
199 SOC_DOUBLE_R_TLV("Aux Boost Volume",
200 WM8978_LEFT_ADC_BOOST_CONTROL, WM8978_RIGHT_ADC_BOOST_CONTROL,
201 0, 7, 0, boost_tlv),
202
203 /* Input PGA volume */
204 SOC_DOUBLE_R_TLV("Input PGA Volume",
205 WM8978_LEFT_INP_PGA_CONTROL, WM8978_RIGHT_INP_PGA_CONTROL,
206 0, 63, 0, inpga_tlv),
207
208 /* Headphone */
209 SOC_DOUBLE_R("Headphone Switch",
210 WM8978_LOUT1_HP_CONTROL, WM8978_ROUT1_HP_CONTROL, 6, 1, 1),
211
212 /* Speaker */
213 SOC_DOUBLE_R("Speaker Switch",
214 WM8978_LOUT2_SPK_CONTROL, WM8978_ROUT2_SPK_CONTROL, 6, 1, 1),
215
216 /* DAC / ADC oversampling */
217 SOC_SINGLE("DAC 128x Oversampling Switch", WM8978_DAC_CONTROL, 8, 1, 0),
218 SOC_SINGLE("ADC 128x Oversampling Switch", WM8978_ADC_CONTROL, 8, 1, 0),
219};
220
221/* Mixer #1: Output (OUT1, OUT2) Mixer: mix AUX, Input mixer output and DAC */
222static const struct snd_kcontrol_new wm8978_left_out_mixer[] = {
223 SOC_DAPM_SINGLE("Line Bypass Switch", WM8978_LEFT_MIXER_CONTROL, 1, 1, 0),
224 SOC_DAPM_SINGLE("Aux Playback Switch", WM8978_LEFT_MIXER_CONTROL, 5, 1, 0),
225 SOC_DAPM_SINGLE("PCM Playback Switch", WM8978_LEFT_MIXER_CONTROL, 0, 1, 0),
226};
227
228static const struct snd_kcontrol_new wm8978_right_out_mixer[] = {
229 SOC_DAPM_SINGLE("Line Bypass Switch", WM8978_RIGHT_MIXER_CONTROL, 1, 1, 0),
230 SOC_DAPM_SINGLE("Aux Playback Switch", WM8978_RIGHT_MIXER_CONTROL, 5, 1, 0),
231 SOC_DAPM_SINGLE("PCM Playback Switch", WM8978_RIGHT_MIXER_CONTROL, 0, 1, 0),
232};
233
234/* OUT3/OUT4 Mixer not implemented */
235
236/* Mixer #2: Input PGA Mute */
237static const struct snd_kcontrol_new wm8978_left_input_mixer[] = {
238 SOC_DAPM_SINGLE("L2 Switch", WM8978_INPUT_CONTROL, 2, 1, 0),
239 SOC_DAPM_SINGLE("MicN Switch", WM8978_INPUT_CONTROL, 1, 1, 0),
240 SOC_DAPM_SINGLE("MicP Switch", WM8978_INPUT_CONTROL, 0, 1, 0),
241};
242static const struct snd_kcontrol_new wm8978_right_input_mixer[] = {
243 SOC_DAPM_SINGLE("R2 Switch", WM8978_INPUT_CONTROL, 6, 1, 0),
244 SOC_DAPM_SINGLE("MicN Switch", WM8978_INPUT_CONTROL, 5, 1, 0),
245 SOC_DAPM_SINGLE("MicP Switch", WM8978_INPUT_CONTROL, 4, 1, 0),
246};
247
248static const struct snd_soc_dapm_widget wm8978_dapm_widgets[] = {
249 SND_SOC_DAPM_DAC("Left DAC", "Left HiFi Playback",
250 WM8978_POWER_MANAGEMENT_3, 0, 0),
251 SND_SOC_DAPM_DAC("Right DAC", "Right HiFi Playback",
252 WM8978_POWER_MANAGEMENT_3, 1, 0),
253 SND_SOC_DAPM_ADC("Left ADC", "Left HiFi Capture",
254 WM8978_POWER_MANAGEMENT_2, 0, 0),
255 SND_SOC_DAPM_ADC("Right ADC", "Right HiFi Capture",
256 WM8978_POWER_MANAGEMENT_2, 1, 0),
257
258 /* Mixer #1: OUT1,2 */
259 SOC_MIXER_ARRAY("Left Output Mixer", WM8978_POWER_MANAGEMENT_3,
260 2, 0, wm8978_left_out_mixer),
261 SOC_MIXER_ARRAY("Right Output Mixer", WM8978_POWER_MANAGEMENT_3,
262 3, 0, wm8978_right_out_mixer),
263
264 SOC_MIXER_ARRAY("Left Input Mixer", WM8978_POWER_MANAGEMENT_2,
265 2, 0, wm8978_left_input_mixer),
266 SOC_MIXER_ARRAY("Right Input Mixer", WM8978_POWER_MANAGEMENT_2,
267 3, 0, wm8978_right_input_mixer),
268
269 SND_SOC_DAPM_PGA("Left Boost Mixer", WM8978_POWER_MANAGEMENT_2,
270 4, 0, NULL, 0),
271 SND_SOC_DAPM_PGA("Right Boost Mixer", WM8978_POWER_MANAGEMENT_2,
272 5, 0, NULL, 0),
273
274 SND_SOC_DAPM_PGA("Left Capture PGA", WM8978_LEFT_INP_PGA_CONTROL,
275 6, 1, NULL, 0),
276 SND_SOC_DAPM_PGA("Right Capture PGA", WM8978_RIGHT_INP_PGA_CONTROL,
277 6, 1, NULL, 0),
278
279 SND_SOC_DAPM_PGA("Left Headphone Out", WM8978_POWER_MANAGEMENT_2,
280 7, 0, NULL, 0),
281 SND_SOC_DAPM_PGA("Right Headphone Out", WM8978_POWER_MANAGEMENT_2,
282 8, 0, NULL, 0),
283
284 SND_SOC_DAPM_PGA("Left Speaker Out", WM8978_POWER_MANAGEMENT_3,
285 6, 0, NULL, 0),
286 SND_SOC_DAPM_PGA("Right Speaker Out", WM8978_POWER_MANAGEMENT_3,
287 5, 0, NULL, 0),
288
289 SND_SOC_DAPM_MIXER("OUT4 VMID", WM8978_POWER_MANAGEMENT_3,
290 8, 0, NULL, 0),
291
292 SND_SOC_DAPM_MICBIAS("Mic Bias", WM8978_POWER_MANAGEMENT_1, 4, 0),
293
294 SND_SOC_DAPM_INPUT("LMICN"),
295 SND_SOC_DAPM_INPUT("LMICP"),
296 SND_SOC_DAPM_INPUT("RMICN"),
297 SND_SOC_DAPM_INPUT("RMICP"),
298 SND_SOC_DAPM_INPUT("LAUX"),
299 SND_SOC_DAPM_INPUT("RAUX"),
300 SND_SOC_DAPM_INPUT("L2"),
301 SND_SOC_DAPM_INPUT("R2"),
302 SND_SOC_DAPM_OUTPUT("LHP"),
303 SND_SOC_DAPM_OUTPUT("RHP"),
304 SND_SOC_DAPM_OUTPUT("LSPK"),
305 SND_SOC_DAPM_OUTPUT("RSPK"),
306};
307
308static const struct snd_soc_dapm_route audio_map[] = {
309 /* Output mixer */
310 {"Right Output Mixer", "PCM Playback Switch", "Right DAC"},
311 {"Right Output Mixer", "Aux Playback Switch", "RAUX"},
312 {"Right Output Mixer", "Line Bypass Switch", "Right Boost Mixer"},
313
314 {"Left Output Mixer", "PCM Playback Switch", "Left DAC"},
315 {"Left Output Mixer", "Aux Playback Switch", "LAUX"},
316 {"Left Output Mixer", "Line Bypass Switch", "Left Boost Mixer"},
317
318 /* Outputs */
319 {"Right Headphone Out", NULL, "Right Output Mixer"},
320 {"RHP", NULL, "Right Headphone Out"},
321
322 {"Left Headphone Out", NULL, "Left Output Mixer"},
323 {"LHP", NULL, "Left Headphone Out"},
324
325 {"Right Speaker Out", NULL, "Right Output Mixer"},
326 {"RSPK", NULL, "Right Speaker Out"},
327
328 {"Left Speaker Out", NULL, "Left Output Mixer"},
329 {"LSPK", NULL, "Left Speaker Out"},
330
331 /* Boost Mixer */
332 {"Right ADC", NULL, "Right Boost Mixer"},
333
334 {"Right Boost Mixer", NULL, "RAUX"},
335 {"Right Boost Mixer", NULL, "Right Capture PGA"},
336 {"Right Boost Mixer", NULL, "R2"},
337
338 {"Left ADC", NULL, "Left Boost Mixer"},
339
340 {"Left Boost Mixer", NULL, "LAUX"},
341 {"Left Boost Mixer", NULL, "Left Capture PGA"},
342 {"Left Boost Mixer", NULL, "L2"},
343
344 /* Input PGA */
345 {"Right Capture PGA", NULL, "Right Input Mixer"},
346 {"Left Capture PGA", NULL, "Left Input Mixer"},
347
348 {"Right Input Mixer", "R2 Switch", "R2"},
349 {"Right Input Mixer", "MicN Switch", "RMICN"},
350 {"Right Input Mixer", "MicP Switch", "RMICP"},
351
352 {"Left Input Mixer", "L2 Switch", "L2"},
353 {"Left Input Mixer", "MicN Switch", "LMICN"},
354 {"Left Input Mixer", "MicP Switch", "LMICP"},
355};
356
357static int wm8978_add_widgets(struct snd_soc_codec *codec)
358{
359 snd_soc_dapm_new_controls(codec, wm8978_dapm_widgets,
360 ARRAY_SIZE(wm8978_dapm_widgets));
361
362 /* set up the WM8978 audio map */
363 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
364
365 return 0;
366}
367
368/* PLL divisors */
369struct wm8978_pll_div {
370 u32 k;
371 u8 n;
372 u8 div2;
373};
374
375#define FIXED_PLL_SIZE (1 << 24)
376
377static void pll_factors(struct wm8978_pll_div *pll_div, unsigned int target,
378 unsigned int source)
379{
380 u64 k_part;
381 unsigned int k, n_div, n_mod;
382
383 n_div = target / source;
384 if (n_div < 6) {
385 source >>= 1;
386 pll_div->div2 = 1;
387 n_div = target / source;
388 } else {
389 pll_div->div2 = 0;
390 }
391
392 if (n_div < 6 || n_div > 12)
393 dev_warn(wm8978_codec->dev,
394 "WM8978 N value exceeds recommended range! N = %u\n",
395 n_div);
396
397 pll_div->n = n_div;
398 n_mod = target - source * n_div;
399 k_part = FIXED_PLL_SIZE * (long long)n_mod + source / 2;
400
401 do_div(k_part, source);
402
403 k = k_part & 0xFFFFFFFF;
404
405 pll_div->k = k;
406}
407
408/* MCLK dividers */
409static const int mclk_numerator[] = {1, 3, 2, 3, 4, 6, 8, 12};
410static const int mclk_denominator[] = {1, 2, 1, 1, 1, 1, 1, 1};
411
412/*
413 * find index >= idx, such that, for a given f_out,
414 * 3 * f_mclk / 4 <= f_PLLOUT < 13 * f_mclk / 4
415 * f_out can be f_256fs or f_opclk, currently only used for f_256fs. Can be
416 * generalised for f_opclk with suitable coefficient arrays, but currently
417 * the OPCLK divisor is calculated directly, not iteratively.
418 */
419static int wm8978_enum_mclk(unsigned int f_out, unsigned int f_mclk,
420 unsigned int *f_pllout)
421{
422 int i;
423
424 for (i = 0; i < ARRAY_SIZE(mclk_numerator); i++) {
425 unsigned int f_pllout_x4 = 4 * f_out * mclk_numerator[i] /
426 mclk_denominator[i];
427 if (3 * f_mclk <= f_pllout_x4 && f_pllout_x4 < 13 * f_mclk) {
428 *f_pllout = f_pllout_x4 / 4;
429 return i;
430 }
431 }
432
433 return -EINVAL;
434}
435
436/*
437 * Calculate internal frequencies and dividers, according to Figure 40
438 * "PLL and Clock Select Circuit" in WM8978 datasheet Rev. 2.6
439 */
440static int wm8978_configure_pll(struct snd_soc_codec *codec)
441{
442 struct wm8978_priv *wm8978 = codec->private_data;
443 struct wm8978_pll_div pll_div;
444 unsigned int f_opclk = wm8978->f_opclk, f_mclk = wm8978->f_mclk,
445 f_256fs = wm8978->f_256fs;
446 unsigned int f2;
447
448 if (!f_mclk)
449 return -EINVAL;
450
451 if (f_opclk) {
452 unsigned int opclk_div;
453 /* Cannot set up MCLK divider now, do later */
454 wm8978->mclk_idx = -1;
455
456 /*
457 * The user needs OPCLK. Choose OPCLKDIV to put
458 * 6 <= R = f2 / f1 < 13, 1 <= OPCLKDIV <= 4.
459 * f_opclk = f_mclk * prescale * R / 4 / OPCLKDIV, where
460 * prescale = 1, or prescale = 2. Prescale is calculated inside
461 * pll_factors(). We have to select f_PLLOUT, such that
462 * f_mclk * 3 / 4 <= f_PLLOUT < f_mclk * 13 / 4. Must be
463 * f_mclk * 3 / 16 <= f_opclk < f_mclk * 13 / 4.
464 */
465 if (16 * f_opclk < 3 * f_mclk || 4 * f_opclk >= 13 * f_mclk)
466 return -EINVAL;
467
468 if (4 * f_opclk < 3 * f_mclk)
469 /* Have to use OPCLKDIV */
470 opclk_div = (3 * f_mclk / 4 + f_opclk - 1) / f_opclk;
471 else
472 opclk_div = 1;
473
474 dev_dbg(codec->dev, "%s: OPCLKDIV=%d\n", __func__, opclk_div);
475
476 snd_soc_update_bits(codec, WM8978_GPIO_CONTROL, 0x30,
477 (opclk_div - 1) << 4);
478
479 wm8978->f_pllout = f_opclk * opclk_div;
480 } else if (f_256fs) {
481 /*
482 * Not using OPCLK, but PLL is used for the codec, choose R:
483 * 6 <= R = f2 / f1 < 13, to put 1 <= MCLKDIV <= 12.
484 * f_256fs = f_mclk * prescale * R / 4 / MCLKDIV, where
485 * prescale = 1, or prescale = 2. Prescale is calculated inside
486 * pll_factors(). We have to select f_PLLOUT, such that
487 * f_mclk * 3 / 4 <= f_PLLOUT < f_mclk * 13 / 4. Must be
488 * f_mclk * 3 / 48 <= f_256fs < f_mclk * 13 / 4. This means MCLK
489 * must be 3.781MHz <= f_MCLK <= 32.768MHz
490 */
491 int idx = wm8978_enum_mclk(f_256fs, f_mclk, &wm8978->f_pllout);
492 if (idx < 0)
493 return idx;
494
495 wm8978->mclk_idx = idx;
496
497 /* GPIO1 into default mode as input - before configuring PLL */
498 snd_soc_update_bits(codec, WM8978_GPIO_CONTROL, 7, 0);
499 } else {
500 return -EINVAL;
501 }
502
503 f2 = wm8978->f_pllout * 4;
504
505 dev_dbg(codec->dev, "%s: f_MCLK=%uHz, f_PLLOUT=%uHz\n", __func__,
506 wm8978->f_mclk, wm8978->f_pllout);
507
508 pll_factors(&pll_div, f2, wm8978->f_mclk);
509
510 dev_dbg(codec->dev, "%s: calculated PLL N=0x%x, K=0x%x, div2=%d\n",
511 __func__, pll_div.n, pll_div.k, pll_div.div2);
512
513 /* Turn PLL off for configuration... */
514 snd_soc_update_bits(codec, WM8978_POWER_MANAGEMENT_1, 0x20, 0);
515
516 snd_soc_write(codec, WM8978_PLL_N, (pll_div.div2 << 4) | pll_div.n);
517 snd_soc_write(codec, WM8978_PLL_K1, pll_div.k >> 18);
518 snd_soc_write(codec, WM8978_PLL_K2, (pll_div.k >> 9) & 0x1ff);
519 snd_soc_write(codec, WM8978_PLL_K3, pll_div.k & 0x1ff);
520
521 /* ...and on again */
522 snd_soc_update_bits(codec, WM8978_POWER_MANAGEMENT_1, 0x20, 0x20);
523
524 if (f_opclk)
525 /* Output PLL (OPCLK) to GPIO1 */
526 snd_soc_update_bits(codec, WM8978_GPIO_CONTROL, 7, 4);
527
528 return 0;
529}
530
531/*
532 * Configure WM8978 clock dividers.
533 */
534static int wm8978_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
535 int div_id, int div)
536{
537 struct snd_soc_codec *codec = codec_dai->codec;
538 struct wm8978_priv *wm8978 = codec->private_data;
539 int ret = 0;
540
541 switch (div_id) {
542 case WM8978_OPCLKRATE:
543 wm8978->f_opclk = div;
544
545 if (wm8978->f_mclk)
546 /*
547 * We know the MCLK frequency, the user has requested
548 * OPCLK, configure the PLL based on that and start it
549 * and OPCLK immediately. We will configure PLL to match
550 * user-requested OPCLK frquency as good as possible.
551 * In fact, it is likely, that matching the sampling
552 * rate, when it becomes known, is more important, and
553 * we will not be reconfiguring PLL then, because we
554 * must not interrupt OPCLK. But it should be fine,
555 * because typically the user will request OPCLK to run
556 * at 256fs or 512fs, and for these cases we will also
557 * find an exact MCLK divider configuration - it will
558 * be equal to or double the OPCLK divisor.
559 */
560 ret = wm8978_configure_pll(codec);
561 break;
562 case WM8978_BCLKDIV:
563 if (div & ~0x1c)
564 return -EINVAL;
565 snd_soc_update_bits(codec, WM8978_CLOCKING, 0x1c, div);
566 break;
567 default:
568 return -EINVAL;
569 }
570
571 dev_dbg(codec->dev, "%s: ID %d, value %u\n", __func__, div_id, div);
572
573 return ret;
574}
575
576/*
577 * @freq: when .set_pll() us not used, freq is codec MCLK input frequency
578 */
579static int wm8978_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id,
580 unsigned int freq, int dir)
581{
582 struct snd_soc_codec *codec = codec_dai->codec;
583 struct wm8978_priv *wm8978 = codec->private_data;
584 int ret = 0;
585
586 dev_dbg(codec->dev, "%s: ID %d, freq %u\n", __func__, clk_id, freq);
587
588 if (freq) {
589 wm8978->f_mclk = freq;
590
591 /* Even if MCLK is used for system clock, might have to drive OPCLK */
592 if (wm8978->f_opclk)
593 ret = wm8978_configure_pll(codec);
594
595 /* Our sysclk is fixed to 256 * fs, will configure in .hw_params() */
596
597 if (!ret)
598 wm8978->sysclk = clk_id;
599 }
600
601 if (wm8978->sysclk == WM8978_PLL && (!freq || clk_id == WM8978_MCLK)) {
602 /* Clock CODEC directly from MCLK */
603 snd_soc_update_bits(codec, WM8978_CLOCKING, 0x100, 0);
604
605 /* GPIO1 into default mode as input - before configuring PLL */
606 snd_soc_update_bits(codec, WM8978_GPIO_CONTROL, 7, 0);
607
608 /* Turn off PLL */
609 snd_soc_update_bits(codec, WM8978_POWER_MANAGEMENT_1, 0x20, 0);
610 wm8978->sysclk = WM8978_MCLK;
611 wm8978->f_pllout = 0;
612 wm8978->f_opclk = 0;
613 }
614
615 return ret;
616}
617
618/*
619 * Set ADC and Voice DAC format.
620 */
621static int wm8978_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
622{
623 struct snd_soc_codec *codec = codec_dai->codec;
624 /*
625 * BCLK polarity mask = 0x100, LRC clock polarity mask = 0x80,
626 * Data Format mask = 0x18: all will be calculated anew
627 */
628 u16 iface = snd_soc_read(codec, WM8978_AUDIO_INTERFACE) & ~0x198;
629 u16 clk = snd_soc_read(codec, WM8978_CLOCKING);
630
631 dev_dbg(codec->dev, "%s\n", __func__);
632
633 /* set master/slave audio interface */
634 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
635 case SND_SOC_DAIFMT_CBM_CFM:
636 clk |= 1;
637 break;
638 case SND_SOC_DAIFMT_CBS_CFS:
639 clk &= ~1;
640 break;
641 default:
642 return -EINVAL;
643 }
644
645 /* interface format */
646 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
647 case SND_SOC_DAIFMT_I2S:
648 iface |= 0x10;
649 break;
650 case SND_SOC_DAIFMT_RIGHT_J:
651 break;
652 case SND_SOC_DAIFMT_LEFT_J:
653 iface |= 0x8;
654 break;
655 case SND_SOC_DAIFMT_DSP_A:
656 iface |= 0x18;
657 break;
658 default:
659 return -EINVAL;
660 }
661
662 /* clock inversion */
663 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
664 case SND_SOC_DAIFMT_NB_NF:
665 break;
666 case SND_SOC_DAIFMT_IB_IF:
667 iface |= 0x180;
668 break;
669 case SND_SOC_DAIFMT_IB_NF:
670 iface |= 0x100;
671 break;
672 case SND_SOC_DAIFMT_NB_IF:
673 iface |= 0x80;
674 break;
675 default:
676 return -EINVAL;
677 }
678
679 snd_soc_write(codec, WM8978_AUDIO_INTERFACE, iface);
680 snd_soc_write(codec, WM8978_CLOCKING, clk);
681
682 return 0;
683}
684
685/*
686 * Set PCM DAI bit size and sample rate.
687 */
688static int wm8978_hw_params(struct snd_pcm_substream *substream,
689 struct snd_pcm_hw_params *params,
690 struct snd_soc_dai *dai)
691{
692 struct snd_soc_pcm_runtime *rtd = substream->private_data;
693 struct snd_soc_device *socdev = rtd->socdev;
694 struct snd_soc_codec *codec = socdev->card->codec;
695 struct wm8978_priv *wm8978 = codec->private_data;
696 /* Word length mask = 0x60 */
697 u16 iface_ctl = snd_soc_read(codec, WM8978_AUDIO_INTERFACE) & ~0x60;
698 /* Sampling rate mask = 0xe (for filters) */
699 u16 add_ctl = snd_soc_read(codec, WM8978_ADDITIONAL_CONTROL) & ~0xe;
700 u16 clking = snd_soc_read(codec, WM8978_CLOCKING);
701 enum wm8978_sysclk_src current_clk_id = clking & 0x100 ?
702 WM8978_PLL : WM8978_MCLK;
703 unsigned int f_sel, diff, diff_best = INT_MAX;
704 int i, best = 0;
705
706 if (!wm8978->f_mclk)
707 return -EINVAL;
708
709 /* bit size */
710 switch (params_format(params)) {
711 case SNDRV_PCM_FORMAT_S16_LE:
712 break;
713 case SNDRV_PCM_FORMAT_S20_3LE:
714 iface_ctl |= 0x20;
715 break;
716 case SNDRV_PCM_FORMAT_S24_LE:
717 iface_ctl |= 0x40;
718 break;
719 case SNDRV_PCM_FORMAT_S32_LE:
720 iface_ctl |= 0x60;
721 break;
722 }
723
724 /* filter coefficient */
725 switch (params_rate(params)) {
726 case 8000:
727 add_ctl |= 0x5 << 1;
728 break;
729 case 11025:
730 add_ctl |= 0x4 << 1;
731 break;
732 case 16000:
733 add_ctl |= 0x3 << 1;
734 break;
735 case 22050:
736 add_ctl |= 0x2 << 1;
737 break;
738 case 32000:
739 add_ctl |= 0x1 << 1;
740 break;
741 case 44100:
742 case 48000:
743 break;
744 }
745
746 /* Sampling rate is known now, can configure the MCLK divider */
747 wm8978->f_256fs = params_rate(params) * 256;
748
749 if (wm8978->sysclk == WM8978_MCLK) {
750 wm8978->mclk_idx = -1;
751 f_sel = wm8978->f_mclk;
752 } else {
753 if (!wm8978->f_pllout) {
754 /* We only enter here, if OPCLK is not used */
755 int ret = wm8978_configure_pll(codec);
756 if (ret < 0)
757 return ret;
758 }
759 f_sel = wm8978->f_pllout;
760 }
761
762 if (wm8978->mclk_idx < 0) {
763 /* Either MCLK is used directly, or OPCLK is used */
764 if (f_sel < wm8978->f_256fs || f_sel > 12 * wm8978->f_256fs)
765 return -EINVAL;
766
767 for (i = 0; i < ARRAY_SIZE(mclk_numerator); i++) {
768 diff = abs(wm8978->f_256fs * 3 -
769 f_sel * 3 * mclk_denominator[i] / mclk_numerator[i]);
770
771 if (diff < diff_best) {
772 diff_best = diff;
773 best = i;
774 }
775
776 if (!diff)
777 break;
778 }
779 } else {
780 /* OPCLK not used, codec driven by PLL */
781 best = wm8978->mclk_idx;
782 diff = 0;
783 }
784
785 if (diff)
786 dev_warn(codec->dev, "Imprecise sampling rate: %uHz%s\n",
787 f_sel * mclk_denominator[best] / mclk_numerator[best] / 256,
788 wm8978->sysclk == WM8978_MCLK ?
789 ", consider using PLL" : "");
790
791 dev_dbg(codec->dev, "%s: fmt %d, rate %u, MCLK divisor #%d\n", __func__,
792 params_format(params), params_rate(params), best);
793
794 /* MCLK divisor mask = 0xe0 */
795 snd_soc_update_bits(codec, WM8978_CLOCKING, 0xe0, best << 5);
796
797 snd_soc_write(codec, WM8978_AUDIO_INTERFACE, iface_ctl);
798 snd_soc_write(codec, WM8978_ADDITIONAL_CONTROL, add_ctl);
799
800 if (wm8978->sysclk != current_clk_id) {
801 if (wm8978->sysclk == WM8978_PLL)
802 /* Run CODEC from PLL instead of MCLK */
803 snd_soc_update_bits(codec, WM8978_CLOCKING,
804 0x100, 0x100);
805 else
806 /* Clock CODEC directly from MCLK */
807 snd_soc_update_bits(codec, WM8978_CLOCKING, 0x100, 0);
808 }
809
810 return 0;
811}
812
813static int wm8978_mute(struct snd_soc_dai *dai, int mute)
814{
815 struct snd_soc_codec *codec = dai->codec;
816
817 dev_dbg(codec->dev, "%s: %d\n", __func__, mute);
818
819 if (mute)
820 snd_soc_update_bits(codec, WM8978_DAC_CONTROL, 0x40, 0x40);
821 else
822 snd_soc_update_bits(codec, WM8978_DAC_CONTROL, 0x40, 0);
823
824 return 0;
825}
826
827static int wm8978_set_bias_level(struct snd_soc_codec *codec,
828 enum snd_soc_bias_level level)
829{
830 u16 power1 = snd_soc_read(codec, WM8978_POWER_MANAGEMENT_1) & ~3;
831
832 switch (level) {
833 case SND_SOC_BIAS_ON:
834 case SND_SOC_BIAS_PREPARE:
835 power1 |= 1; /* VMID 75k */
836 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1, power1);
837 break;
838 case SND_SOC_BIAS_STANDBY:
839 /* bit 3: enable bias, bit 2: enable I/O tie off buffer */
840 power1 |= 0xc;
841
842 if (codec->bias_level == SND_SOC_BIAS_OFF) {
843 /* Initial cap charge at VMID 5k */
844 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1,
845 power1 | 0x3);
846 mdelay(100);
847 }
848
849 power1 |= 0x2; /* VMID 500k */
850 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1, power1);
851 break;
852 case SND_SOC_BIAS_OFF:
853 /* Preserve PLL - OPCLK may be used by someone */
854 snd_soc_update_bits(codec, WM8978_POWER_MANAGEMENT_1, ~0x20, 0);
855 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_2, 0);
856 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_3, 0);
857 break;
858 }
859
860 dev_dbg(codec->dev, "%s: %d, %x\n", __func__, level, power1);
861
862 codec->bias_level = level;
863 return 0;
864}
865
866#define WM8978_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
867 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
868
869static struct snd_soc_dai_ops wm8978_dai_ops = {
870 .hw_params = wm8978_hw_params,
871 .digital_mute = wm8978_mute,
872 .set_fmt = wm8978_set_dai_fmt,
873 .set_clkdiv = wm8978_set_dai_clkdiv,
874 .set_sysclk = wm8978_set_dai_sysclk,
875};
876
877/* Also supports 12kHz */
878struct snd_soc_dai wm8978_dai = {
879 .name = "WM8978 HiFi",
880 .id = 1,
881 .playback = {
882 .stream_name = "Playback",
883 .channels_min = 1,
884 .channels_max = 2,
885 .rates = SNDRV_PCM_RATE_8000_48000,
886 .formats = WM8978_FORMATS,
887 },
888 .capture = {
889 .stream_name = "Capture",
890 .channels_min = 1,
891 .channels_max = 2,
892 .rates = SNDRV_PCM_RATE_8000_48000,
893 .formats = WM8978_FORMATS,
894 },
895 .ops = &wm8978_dai_ops,
896};
897EXPORT_SYMBOL_GPL(wm8978_dai);
898
899static int wm8978_suspend(struct platform_device *pdev, pm_message_t state)
900{
901 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
902 struct snd_soc_codec *codec = socdev->card->codec;
903
904 wm8978_set_bias_level(codec, SND_SOC_BIAS_OFF);
905 /* Also switch PLL off */
906 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1, 0);
907
908 return 0;
909}
910
911static int wm8978_resume(struct platform_device *pdev)
912{
913 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
914 struct snd_soc_codec *codec = socdev->card->codec;
915 struct wm8978_priv *wm8978 = codec->private_data;
916 int i;
917 u16 *cache = codec->reg_cache;
918
919 /* Sync reg_cache with the hardware */
920 for (i = 0; i < ARRAY_SIZE(wm8978_reg); i++) {
921 if (i == WM8978_RESET)
922 continue;
923 if (cache[i] != wm8978_reg[i])
924 snd_soc_write(codec, i, cache[i]);
925 }
926
927 wm8978_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
928
929 if (wm8978->f_pllout)
930 /* Switch PLL on */
931 snd_soc_update_bits(codec, WM8978_POWER_MANAGEMENT_1, 0x20, 0x20);
932
933 return 0;
934}
935
936static int wm8978_probe(struct platform_device *pdev)
937{
938 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
939 struct snd_soc_codec *codec;
940 int ret = 0;
941
942 if (wm8978_codec == NULL) {
943 dev_err(&pdev->dev, "Codec device not registered\n");
944 return -ENODEV;
945 }
946
947 socdev->card->codec = wm8978_codec;
948 codec = wm8978_codec;
949
950 /* register pcms */
951 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
952 if (ret < 0) {
953 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
954 goto pcm_err;
955 }
956
957 snd_soc_add_controls(codec, wm8978_snd_controls,
958 ARRAY_SIZE(wm8978_snd_controls));
959 wm8978_add_widgets(codec);
960
961pcm_err:
962 return ret;
963}
964
965/* power down chip */
966static int wm8978_remove(struct platform_device *pdev)
967{
968 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
969
970 snd_soc_free_pcms(socdev);
971 snd_soc_dapm_free(socdev);
972
973 return 0;
974}
975
976struct snd_soc_codec_device soc_codec_dev_wm8978 = {
977 .probe = wm8978_probe,
978 .remove = wm8978_remove,
979 .suspend = wm8978_suspend,
980 .resume = wm8978_resume,
981};
982EXPORT_SYMBOL_GPL(soc_codec_dev_wm8978);
983
984/*
985 * These registers contain an "update" bit - bit 8. This means, for example,
986 * that one can write new DAC digital volume for both channels, but only when
987 * the update bit is set, will also the volume be updated - simultaneously for
988 * both channels.
989 */
990static const int update_reg[] = {
991 WM8978_LEFT_DAC_DIGITAL_VOLUME,
992 WM8978_RIGHT_DAC_DIGITAL_VOLUME,
993 WM8978_LEFT_ADC_DIGITAL_VOLUME,
994 WM8978_RIGHT_ADC_DIGITAL_VOLUME,
995 WM8978_LEFT_INP_PGA_CONTROL,
996 WM8978_RIGHT_INP_PGA_CONTROL,
997 WM8978_LOUT1_HP_CONTROL,
998 WM8978_ROUT1_HP_CONTROL,
999 WM8978_LOUT2_SPK_CONTROL,
1000 WM8978_ROUT2_SPK_CONTROL,
1001};
1002
1003static __devinit int wm8978_register(struct wm8978_priv *wm8978)
1004{
1005 int ret, i;
1006 struct snd_soc_codec *codec = &wm8978->codec;
1007
1008 if (wm8978_codec) {
1009 dev_err(codec->dev, "Another WM8978 is registered\n");
1010 return -EINVAL;
1011 }
1012
1013 /*
1014 * Set default system clock to PLL, it is more precise, this is also the
1015 * default hardware setting
1016 */
1017 wm8978->sysclk = WM8978_PLL;
1018
1019 mutex_init(&codec->mutex);
1020 INIT_LIST_HEAD(&codec->dapm_widgets);
1021 INIT_LIST_HEAD(&codec->dapm_paths);
1022
1023 codec->private_data = wm8978;
1024 codec->name = "WM8978";
1025 codec->owner = THIS_MODULE;
1026 codec->bias_level = SND_SOC_BIAS_OFF;
1027 codec->set_bias_level = wm8978_set_bias_level;
1028 codec->dai = &wm8978_dai;
1029 codec->num_dai = 1;
1030 codec->reg_cache_size = WM8978_CACHEREGNUM;
1031 codec->reg_cache = &wm8978->reg_cache;
1032
1033 ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_I2C);
1034 if (ret < 0) {
1035 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1036 goto err;
1037 }
1038
1039 memcpy(codec->reg_cache, wm8978_reg, sizeof(wm8978_reg));
1040
1041 /*
1042 * Set the update bit in all registers, that have one. This way all
1043 * writes to those registers will also cause the update bit to be
1044 * written.
1045 */
1046 for (i = 0; i < ARRAY_SIZE(update_reg); i++)
1047 ((u16 *)codec->reg_cache)[update_reg[i]] |= 0x100;
1048
1049 /* Reset the codec */
1050 ret = snd_soc_write(codec, WM8978_RESET, 0);
1051 if (ret < 0) {
1052 dev_err(codec->dev, "Failed to issue reset\n");
1053 goto err;
1054 }
1055
1056 wm8978_dai.dev = codec->dev;
1057
1058 wm8978_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1059
1060 wm8978_codec = codec;
1061
1062 ret = snd_soc_register_codec(codec);
1063 if (ret != 0) {
1064 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
1065 goto err;
1066 }
1067
1068 ret = snd_soc_register_dai(&wm8978_dai);
1069 if (ret != 0) {
1070 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
1071 goto err_codec;
1072 }
1073
1074 return 0;
1075
1076err_codec:
1077 snd_soc_unregister_codec(codec);
1078err:
1079 kfree(wm8978);
1080 return ret;
1081}
1082
1083static __devexit void wm8978_unregister(struct wm8978_priv *wm8978)
1084{
1085 wm8978_set_bias_level(&wm8978->codec, SND_SOC_BIAS_OFF);
1086 snd_soc_unregister_dai(&wm8978_dai);
1087 snd_soc_unregister_codec(&wm8978->codec);
1088 kfree(wm8978);
1089 wm8978_codec = NULL;
1090}
1091
1092static __devinit int wm8978_i2c_probe(struct i2c_client *i2c,
1093 const struct i2c_device_id *id)
1094{
1095 struct wm8978_priv *wm8978;
1096 struct snd_soc_codec *codec;
1097
1098 wm8978 = kzalloc(sizeof(struct wm8978_priv), GFP_KERNEL);
1099 if (wm8978 == NULL)
1100 return -ENOMEM;
1101
1102 codec = &wm8978->codec;
1103 codec->hw_write = (hw_write_t)i2c_master_send;
1104
1105 i2c_set_clientdata(i2c, wm8978);
1106 codec->control_data = i2c;
1107
1108 codec->dev = &i2c->dev;
1109
1110 return wm8978_register(wm8978);
1111}
1112
1113static __devexit int wm8978_i2c_remove(struct i2c_client *client)
1114{
1115 struct wm8978_priv *wm8978 = i2c_get_clientdata(client);
1116 wm8978_unregister(wm8978);
1117 return 0;
1118}
1119
1120static const struct i2c_device_id wm8978_i2c_id[] = {
1121 { "wm8978", 0 },
1122 { }
1123};
1124MODULE_DEVICE_TABLE(i2c, wm8978_i2c_id);
1125
1126static struct i2c_driver wm8978_i2c_driver = {
1127 .driver = {
1128 .name = "WM8978",
1129 .owner = THIS_MODULE,
1130 },
1131 .probe = wm8978_i2c_probe,
1132 .remove = __devexit_p(wm8978_i2c_remove),
1133 .id_table = wm8978_i2c_id,
1134};
1135
1136static int __init wm8978_modinit(void)
1137{
1138 return i2c_add_driver(&wm8978_i2c_driver);
1139}
1140module_init(wm8978_modinit);
1141
1142static void __exit wm8978_exit(void)
1143{
1144 i2c_del_driver(&wm8978_i2c_driver);
1145}
1146module_exit(wm8978_exit);
1147
1148MODULE_DESCRIPTION("ASoC WM8978 codec driver");
1149MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
1150MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8978.h b/sound/soc/codecs/wm8978.h
new file mode 100644
index 000000000000..56ec83270917
--- /dev/null
+++ b/sound/soc/codecs/wm8978.h
@@ -0,0 +1,86 @@
1/*
2 * wm8978.h -- codec driver for WM8978
3 *
4 * Copyright 2009 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef __WM8978_H__
12#define __WM8978_H__
13
14/*
15 * Register values.
16 */
17#define WM8978_RESET 0x00
18#define WM8978_POWER_MANAGEMENT_1 0x01
19#define WM8978_POWER_MANAGEMENT_2 0x02
20#define WM8978_POWER_MANAGEMENT_3 0x03
21#define WM8978_AUDIO_INTERFACE 0x04
22#define WM8978_COMPANDING_CONTROL 0x05
23#define WM8978_CLOCKING 0x06
24#define WM8978_ADDITIONAL_CONTROL 0x07
25#define WM8978_GPIO_CONTROL 0x08
26#define WM8978_JACK_DETECT_CONTROL_1 0x09
27#define WM8978_DAC_CONTROL 0x0A
28#define WM8978_LEFT_DAC_DIGITAL_VOLUME 0x0B
29#define WM8978_RIGHT_DAC_DIGITAL_VOLUME 0x0C
30#define WM8978_JACK_DETECT_CONTROL_2 0x0D
31#define WM8978_ADC_CONTROL 0x0E
32#define WM8978_LEFT_ADC_DIGITAL_VOLUME 0x0F
33#define WM8978_RIGHT_ADC_DIGITAL_VOLUME 0x10
34#define WM8978_EQ1 0x12
35#define WM8978_EQ2 0x13
36#define WM8978_EQ3 0x14
37#define WM8978_EQ4 0x15
38#define WM8978_EQ5 0x16
39#define WM8978_DAC_LIMITER_1 0x18
40#define WM8978_DAC_LIMITER_2 0x19
41#define WM8978_NOTCH_FILTER_1 0x1b
42#define WM8978_NOTCH_FILTER_2 0x1c
43#define WM8978_NOTCH_FILTER_3 0x1d
44#define WM8978_NOTCH_FILTER_4 0x1e
45#define WM8978_ALC_CONTROL_1 0x20
46#define WM8978_ALC_CONTROL_2 0x21
47#define WM8978_ALC_CONTROL_3 0x22
48#define WM8978_NOISE_GATE 0x23
49#define WM8978_PLL_N 0x24
50#define WM8978_PLL_K1 0x25
51#define WM8978_PLL_K2 0x26
52#define WM8978_PLL_K3 0x27
53#define WM8978_3D_CONTROL 0x29
54#define WM8978_BEEP_CONTROL 0x2b
55#define WM8978_INPUT_CONTROL 0x2c
56#define WM8978_LEFT_INP_PGA_CONTROL 0x2d
57#define WM8978_RIGHT_INP_PGA_CONTROL 0x2e
58#define WM8978_LEFT_ADC_BOOST_CONTROL 0x2f
59#define WM8978_RIGHT_ADC_BOOST_CONTROL 0x30
60#define WM8978_OUTPUT_CONTROL 0x31
61#define WM8978_LEFT_MIXER_CONTROL 0x32
62#define WM8978_RIGHT_MIXER_CONTROL 0x33
63#define WM8978_LOUT1_HP_CONTROL 0x34
64#define WM8978_ROUT1_HP_CONTROL 0x35
65#define WM8978_LOUT2_SPK_CONTROL 0x36
66#define WM8978_ROUT2_SPK_CONTROL 0x37
67#define WM8978_OUT3_MIXER_CONTROL 0x38
68#define WM8978_OUT4_MIXER_CONTROL 0x39
69
70#define WM8978_CACHEREGNUM 58
71
72/* Clock divider Id's */
73enum wm8978_clk_id {
74 WM8978_OPCLKRATE,
75 WM8978_BCLKDIV,
76};
77
78enum wm8978_sysclk_src {
79 WM8978_PLL,
80 WM8978_MCLK
81};
82
83extern struct snd_soc_dai wm8978_dai;
84extern struct snd_soc_codec_device soc_codec_dev_wm8978;
85
86#endif /* __WM8978_H__ */
diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c
index 3f530f8a972a..bb18c3ecfeb9 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>
@@ -790,19 +791,9 @@ static int wm8988_probe(struct platform_device *pdev)
790 snd_soc_dapm_new_controls(codec, wm8988_dapm_widgets, 791 snd_soc_dapm_new_controls(codec, wm8988_dapm_widgets,
791 ARRAY_SIZE(wm8988_dapm_widgets)); 792 ARRAY_SIZE(wm8988_dapm_widgets));
792 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 793 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
793 snd_soc_dapm_new_widgets(codec);
794
795 ret = snd_soc_init_card(socdev);
796 if (ret < 0) {
797 dev_err(codec->dev, "failed to register card: %d\n", ret);
798 goto card_err;
799 }
800 794
801 return ret; 795 return ret;
802 796
803card_err:
804 snd_soc_free_pcms(socdev);
805 snd_soc_dapm_free(socdev);
806pcm_err: 797pcm_err:
807 return ret; 798 return ret;
808} 799}
@@ -944,21 +935,6 @@ static int wm8988_i2c_remove(struct i2c_client *client)
944 return 0; 935 return 0;
945} 936}
946 937
947#ifdef CONFIG_PM
948static int wm8988_i2c_suspend(struct i2c_client *client, pm_message_t msg)
949{
950 return snd_soc_suspend_device(&client->dev);
951}
952
953static int wm8988_i2c_resume(struct i2c_client *client)
954{
955 return snd_soc_resume_device(&client->dev);
956}
957#else
958#define wm8988_i2c_suspend NULL
959#define wm8988_i2c_resume NULL
960#endif
961
962static const struct i2c_device_id wm8988_i2c_id[] = { 938static const struct i2c_device_id wm8988_i2c_id[] = {
963 { "wm8988", 0 }, 939 { "wm8988", 0 },
964 { } 940 { }
@@ -972,8 +948,6 @@ static struct i2c_driver wm8988_i2c_driver = {
972 }, 948 },
973 .probe = wm8988_i2c_probe, 949 .probe = wm8988_i2c_probe,
974 .remove = wm8988_i2c_remove, 950 .remove = wm8988_i2c_remove,
975 .suspend = wm8988_i2c_suspend,
976 .resume = wm8988_i2c_resume,
977 .id_table = wm8988_i2c_id, 951 .id_table = wm8988_i2c_id,
978}; 952};
979#endif 953#endif
@@ -1006,21 +980,6 @@ static int __devexit wm8988_spi_remove(struct spi_device *spi)
1006 return 0; 980 return 0;
1007} 981}
1008 982
1009#ifdef CONFIG_PM
1010static int wm8988_spi_suspend(struct spi_device *spi, pm_message_t msg)
1011{
1012 return snd_soc_suspend_device(&spi->dev);
1013}
1014
1015static int wm8988_spi_resume(struct spi_device *spi)
1016{
1017 return snd_soc_resume_device(&spi->dev);
1018}
1019#else
1020#define wm8988_spi_suspend NULL
1021#define wm8988_spi_resume NULL
1022#endif
1023
1024static struct spi_driver wm8988_spi_driver = { 983static struct spi_driver wm8988_spi_driver = {
1025 .driver = { 984 .driver = {
1026 .name = "wm8988", 985 .name = "wm8988",
@@ -1029,8 +988,6 @@ static struct spi_driver wm8988_spi_driver = {
1029 }, 988 },
1030 .probe = wm8988_spi_probe, 989 .probe = wm8988_spi_probe,
1031 .remove = __devexit_p(wm8988_spi_remove), 990 .remove = __devexit_p(wm8988_spi_remove),
1032 .suspend = wm8988_spi_suspend,
1033 .resume = wm8988_spi_resume,
1034}; 991};
1035#endif 992#endif
1036 993
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index 2d702db4131d..831f4730bfd5 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>
@@ -920,7 +921,6 @@ static int wm8990_add_widgets(struct snd_soc_codec *codec)
920 /* set up the WM8990 audio map */ 921 /* set up the WM8990 audio map */
921 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 922 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
922 923
923 snd_soc_dapm_new_widgets(codec);
924 return 0; 924 return 0;
925} 925}
926 926
@@ -972,8 +972,8 @@ static void pll_factors(struct _pll_div *pll_div, unsigned int target,
972 pll_div->k = K; 972 pll_div->k = K;
973} 973}
974 974
975static int wm8990_set_dai_pll(struct snd_soc_dai *codec_dai, 975static int wm8990_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
976 int pll_id, unsigned int freq_in, unsigned int freq_out) 976 int source, unsigned int freq_in, unsigned int freq_out)
977{ 977{
978 u16 reg; 978 u16 reg;
979 struct snd_soc_codec *codec = codec_dai->codec; 979 struct snd_soc_codec *codec = codec_dai->codec;
@@ -991,7 +991,7 @@ static int wm8990_set_dai_pll(struct snd_soc_dai *codec_dai,
991 reg = snd_soc_read(codec, WM8990_CLOCKING_2); 991 reg = snd_soc_read(codec, WM8990_CLOCKING_2);
992 snd_soc_write(codec, WM8990_CLOCKING_2, reg | WM8990_SYSCLK_SRC); 992 snd_soc_write(codec, WM8990_CLOCKING_2, reg | WM8990_SYSCLK_SRC);
993 993
994 /* set up N , fractional mode and pre-divisor if neccessary */ 994 /* set up N , fractional mode and pre-divisor if necessary */
995 snd_soc_write(codec, WM8990_PLL1, pll_div.n | WM8990_SDM | 995 snd_soc_write(codec, WM8990_PLL1, pll_div.n | WM8990_SDM |
996 (pll_div.div2?WM8990_PRESCALE:0)); 996 (pll_div.div2?WM8990_PRESCALE:0));
997 snd_soc_write(codec, WM8990_PLL2, (u8)(pll_div.k>>8)); 997 snd_soc_write(codec, WM8990_PLL2, (u8)(pll_div.k>>8));
@@ -1320,10 +1320,6 @@ static int wm8990_suspend(struct platform_device *pdev, pm_message_t state)
1320 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1320 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1321 struct snd_soc_codec *codec = socdev->card->codec; 1321 struct snd_soc_codec *codec = socdev->card->codec;
1322 1322
1323 /* we only need to suspend if we are a valid card */
1324 if (!codec->card)
1325 return 0;
1326
1327 wm8990_set_bias_level(codec, SND_SOC_BIAS_OFF); 1323 wm8990_set_bias_level(codec, SND_SOC_BIAS_OFF);
1328 return 0; 1324 return 0;
1329} 1325}
@@ -1336,10 +1332,6 @@ static int wm8990_resume(struct platform_device *pdev)
1336 u8 data[2]; 1332 u8 data[2];
1337 u16 *cache = codec->reg_cache; 1333 u16 *cache = codec->reg_cache;
1338 1334
1339 /* we only need to resume if we are a valid card */
1340 if (!codec->card)
1341 return 0;
1342
1343 /* Sync reg_cache with the hardware */ 1335 /* Sync reg_cache with the hardware */
1344 for (i = 0; i < ARRAY_SIZE(wm8990_reg); i++) { 1336 for (i = 0; i < ARRAY_SIZE(wm8990_reg); i++) {
1345 if (i + 1 == WM8990_RESET) 1337 if (i + 1 == WM8990_RESET)
@@ -1409,16 +1401,9 @@ static int wm8990_init(struct snd_soc_device *socdev)
1409 snd_soc_add_controls(codec, wm8990_snd_controls, 1401 snd_soc_add_controls(codec, wm8990_snd_controls,
1410 ARRAY_SIZE(wm8990_snd_controls)); 1402 ARRAY_SIZE(wm8990_snd_controls));
1411 wm8990_add_widgets(codec); 1403 wm8990_add_widgets(codec);
1412 ret = snd_soc_init_card(socdev); 1404
1413 if (ret < 0) {
1414 printk(KERN_ERR "wm8990: failed to register card\n");
1415 goto card_err;
1416 }
1417 return ret; 1405 return ret;
1418 1406
1419card_err:
1420 snd_soc_free_pcms(socdev);
1421 snd_soc_dapm_free(socdev);
1422pcm_err: 1407pcm_err:
1423 kfree(codec->reg_cache); 1408 kfree(codec->reg_cache);
1424 return ret; 1409 return ret;
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c
index d9987999e92c..03e8b1a6a56c 100644
--- a/sound/soc/codecs/wm8993.c
+++ b/sound/soc/codecs/wm8993.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * wm8993.c -- WM8993 ALSA SoC audio driver 2 * wm8993.c -- WM8993 ALSA SoC audio driver
3 * 3 *
4 * Copyright 2009 Wolfson Microelectronics plc 4 * Copyright 2009, 2010 Wolfson Microelectronics plc
5 * 5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 * 7 *
@@ -16,7 +16,9 @@
16#include <linux/delay.h> 16#include <linux/delay.h>
17#include <linux/pm.h> 17#include <linux/pm.h>
18#include <linux/i2c.h> 18#include <linux/i2c.h>
19#include <linux/regulator/consumer.h>
19#include <linux/spi/spi.h> 20#include <linux/spi/spi.h>
21#include <linux/slab.h>
20#include <sound/core.h> 22#include <sound/core.h>
21#include <sound/pcm.h> 23#include <sound/pcm.h>
22#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
@@ -29,6 +31,16 @@
29#include "wm8993.h" 31#include "wm8993.h"
30#include "wm_hubs.h" 32#include "wm_hubs.h"
31 33
34#define WM8993_NUM_SUPPLIES 6
35static const char *wm8993_supply_names[WM8993_NUM_SUPPLIES] = {
36 "DCVDD",
37 "DBVDD",
38 "AVDD1",
39 "AVDD2",
40 "CPVDD",
41 "SPKVDD",
42};
43
32static u16 wm8993_reg_defaults[WM8993_REGISTER_COUNT] = { 44static u16 wm8993_reg_defaults[WM8993_REGISTER_COUNT] = {
33 0x8993, /* R0 - Software Reset */ 45 0x8993, /* R0 - Software Reset */
34 0x0000, /* R1 - Power Management (1) */ 46 0x0000, /* R1 - Power Management (1) */
@@ -213,7 +225,9 @@ static struct {
213}; 225};
214 226
215struct wm8993_priv { 227struct wm8993_priv {
228 struct wm_hubs_data hubs_data;
216 u16 reg_cache[WM8993_REGISTER_COUNT]; 229 u16 reg_cache[WM8993_REGISTER_COUNT];
230 struct regulator_bulk_data supplies[WM8993_NUM_SUPPLIES];
217 struct wm8993_platform_data pdata; 231 struct wm8993_platform_data pdata;
218 struct snd_soc_codec codec; 232 struct snd_soc_codec codec;
219 int master; 233 int master;
@@ -227,36 +241,9 @@ struct wm8993_priv {
227 int class_w_users; 241 int class_w_users;
228 unsigned int fll_fref; 242 unsigned int fll_fref;
229 unsigned int fll_fout; 243 unsigned int fll_fout;
244 int fll_src;
230}; 245};
231 246
232static unsigned int wm8993_read_hw(struct snd_soc_codec *codec, u8 reg)
233{
234 struct i2c_msg xfer[2];
235 u16 data;
236 int ret;
237 struct i2c_client *i2c = codec->control_data;
238
239 /* Write register */
240 xfer[0].addr = i2c->addr;
241 xfer[0].flags = 0;
242 xfer[0].len = 1;
243 xfer[0].buf = &reg;
244
245 /* Read data */
246 xfer[1].addr = i2c->addr;
247 xfer[1].flags = I2C_M_RD;
248 xfer[1].len = 2;
249 xfer[1].buf = (u8 *)&data;
250
251 ret = i2c_transfer(i2c->adapter, xfer, 2);
252 if (ret != 2) {
253 dev_err(codec->dev, "Failed to read 0x%x: %d\n", reg, ret);
254 return 0;
255 }
256
257 return (data >> 8) | ((data & 0xff) << 8);
258}
259
260static int wm8993_volatile(unsigned int reg) 247static int wm8993_volatile(unsigned int reg)
261{ 248{
262 switch (reg) { 249 switch (reg) {
@@ -271,48 +258,6 @@ static int wm8993_volatile(unsigned int reg)
271 } 258 }
272} 259}
273 260
274static unsigned int wm8993_read(struct snd_soc_codec *codec,
275 unsigned int reg)
276{
277 u16 *reg_cache = codec->reg_cache;
278
279 BUG_ON(reg > WM8993_MAX_REGISTER);
280
281 if (wm8993_volatile(reg))
282 return wm8993_read_hw(codec, reg);
283 else
284 return reg_cache[reg];
285}
286
287static int wm8993_write(struct snd_soc_codec *codec, unsigned int reg,
288 unsigned int value)
289{
290 u16 *reg_cache = codec->reg_cache;
291 u8 data[3];
292 int ret;
293
294 BUG_ON(reg > WM8993_MAX_REGISTER);
295
296 /* data is
297 * D15..D9 WM8993 register offset
298 * D8...D0 register data
299 */
300 data[0] = reg;
301 data[1] = value >> 8;
302 data[2] = value & 0x00ff;
303
304 if (!wm8993_volatile(reg))
305 reg_cache[reg] = value;
306
307 ret = codec->hw_write(codec->control_data, data, 3);
308
309 if (ret == 3)
310 return 0;
311 if (ret < 0)
312 return ret;
313 return -EIO;
314}
315
316struct _fll_div { 261struct _fll_div {
317 u16 fll_fratio; 262 u16 fll_fratio;
318 u16 fll_outdiv; 263 u16 fll_outdiv;
@@ -422,7 +367,7 @@ static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
422 return 0; 367 return 0;
423} 368}
424 369
425static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id, 370static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
426 unsigned int Fref, unsigned int Fout) 371 unsigned int Fref, unsigned int Fout)
427{ 372{
428 struct snd_soc_codec *codec = dai->codec; 373 struct snd_soc_codec *codec = dai->codec;
@@ -441,9 +386,9 @@ static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id,
441 wm8993->fll_fref = 0; 386 wm8993->fll_fref = 0;
442 wm8993->fll_fout = 0; 387 wm8993->fll_fout = 0;
443 388
444 reg1 = wm8993_read(codec, WM8993_FLL_CONTROL_1); 389 reg1 = snd_soc_read(codec, WM8993_FLL_CONTROL_1);
445 reg1 &= ~WM8993_FLL_ENA; 390 reg1 &= ~WM8993_FLL_ENA;
446 wm8993_write(codec, WM8993_FLL_CONTROL_1, reg1); 391 snd_soc_write(codec, WM8993_FLL_CONTROL_1, reg1);
447 392
448 return 0; 393 return 0;
449 } 394 }
@@ -452,7 +397,7 @@ static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id,
452 if (ret != 0) 397 if (ret != 0)
453 return ret; 398 return ret;
454 399
455 reg5 = wm8993_read(codec, WM8993_FLL_CONTROL_5); 400 reg5 = snd_soc_read(codec, WM8993_FLL_CONTROL_5);
456 reg5 &= ~WM8993_FLL_CLK_SRC_MASK; 401 reg5 &= ~WM8993_FLL_CLK_SRC_MASK;
457 402
458 switch (fll_id) { 403 switch (fll_id) {
@@ -474,38 +419,39 @@ static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id,
474 419
475 /* Any FLL configuration change requires that the FLL be 420 /* Any FLL configuration change requires that the FLL be
476 * disabled first. */ 421 * disabled first. */
477 reg1 = wm8993_read(codec, WM8993_FLL_CONTROL_1); 422 reg1 = snd_soc_read(codec, WM8993_FLL_CONTROL_1);
478 reg1 &= ~WM8993_FLL_ENA; 423 reg1 &= ~WM8993_FLL_ENA;
479 wm8993_write(codec, WM8993_FLL_CONTROL_1, reg1); 424 snd_soc_write(codec, WM8993_FLL_CONTROL_1, reg1);
480 425
481 /* Apply the configuration */ 426 /* Apply the configuration */
482 if (fll_div.k) 427 if (fll_div.k)
483 reg1 |= WM8993_FLL_FRAC_MASK; 428 reg1 |= WM8993_FLL_FRAC_MASK;
484 else 429 else
485 reg1 &= ~WM8993_FLL_FRAC_MASK; 430 reg1 &= ~WM8993_FLL_FRAC_MASK;
486 wm8993_write(codec, WM8993_FLL_CONTROL_1, reg1); 431 snd_soc_write(codec, WM8993_FLL_CONTROL_1, reg1);
487 432
488 wm8993_write(codec, WM8993_FLL_CONTROL_2, 433 snd_soc_write(codec, WM8993_FLL_CONTROL_2,
489 (fll_div.fll_outdiv << WM8993_FLL_OUTDIV_SHIFT) | 434 (fll_div.fll_outdiv << WM8993_FLL_OUTDIV_SHIFT) |
490 (fll_div.fll_fratio << WM8993_FLL_FRATIO_SHIFT)); 435 (fll_div.fll_fratio << WM8993_FLL_FRATIO_SHIFT));
491 wm8993_write(codec, WM8993_FLL_CONTROL_3, fll_div.k); 436 snd_soc_write(codec, WM8993_FLL_CONTROL_3, fll_div.k);
492 437
493 reg4 = wm8993_read(codec, WM8993_FLL_CONTROL_4); 438 reg4 = snd_soc_read(codec, WM8993_FLL_CONTROL_4);
494 reg4 &= ~WM8993_FLL_N_MASK; 439 reg4 &= ~WM8993_FLL_N_MASK;
495 reg4 |= fll_div.n << WM8993_FLL_N_SHIFT; 440 reg4 |= fll_div.n << WM8993_FLL_N_SHIFT;
496 wm8993_write(codec, WM8993_FLL_CONTROL_4, reg4); 441 snd_soc_write(codec, WM8993_FLL_CONTROL_4, reg4);
497 442
498 reg5 &= ~WM8993_FLL_CLK_REF_DIV_MASK; 443 reg5 &= ~WM8993_FLL_CLK_REF_DIV_MASK;
499 reg5 |= fll_div.fll_clk_ref_div << WM8993_FLL_CLK_REF_DIV_SHIFT; 444 reg5 |= fll_div.fll_clk_ref_div << WM8993_FLL_CLK_REF_DIV_SHIFT;
500 wm8993_write(codec, WM8993_FLL_CONTROL_5, reg5); 445 snd_soc_write(codec, WM8993_FLL_CONTROL_5, reg5);
501 446
502 /* Enable the FLL */ 447 /* Enable the FLL */
503 wm8993_write(codec, WM8993_FLL_CONTROL_1, reg1 | WM8993_FLL_ENA); 448 snd_soc_write(codec, WM8993_FLL_CONTROL_1, reg1 | WM8993_FLL_ENA);
504 449
505 dev_dbg(codec->dev, "FLL enabled at %dHz->%dHz\n", Fref, Fout); 450 dev_dbg(codec->dev, "FLL enabled at %dHz->%dHz\n", Fref, Fout);
506 451
507 wm8993->fll_fref = Fref; 452 wm8993->fll_fref = Fref;
508 wm8993->fll_fout = Fout; 453 wm8993->fll_fout = Fout;
454 wm8993->fll_src = source;
509 455
510 return 0; 456 return 0;
511} 457}
@@ -520,7 +466,7 @@ static int configure_clock(struct snd_soc_codec *codec)
520 case WM8993_SYSCLK_MCLK: 466 case WM8993_SYSCLK_MCLK:
521 dev_dbg(codec->dev, "Using %dHz MCLK\n", wm8993->mclk_rate); 467 dev_dbg(codec->dev, "Using %dHz MCLK\n", wm8993->mclk_rate);
522 468
523 reg = wm8993_read(codec, WM8993_CLOCKING_2); 469 reg = snd_soc_read(codec, WM8993_CLOCKING_2);
524 reg &= ~(WM8993_MCLK_DIV | WM8993_SYSCLK_SRC); 470 reg &= ~(WM8993_MCLK_DIV | WM8993_SYSCLK_SRC);
525 if (wm8993->mclk_rate > 13500000) { 471 if (wm8993->mclk_rate > 13500000) {
526 reg |= WM8993_MCLK_DIV; 472 reg |= WM8993_MCLK_DIV;
@@ -529,14 +475,14 @@ static int configure_clock(struct snd_soc_codec *codec)
529 reg &= ~WM8993_MCLK_DIV; 475 reg &= ~WM8993_MCLK_DIV;
530 wm8993->sysclk_rate = wm8993->mclk_rate; 476 wm8993->sysclk_rate = wm8993->mclk_rate;
531 } 477 }
532 wm8993_write(codec, WM8993_CLOCKING_2, reg); 478 snd_soc_write(codec, WM8993_CLOCKING_2, reg);
533 break; 479 break;
534 480
535 case WM8993_SYSCLK_FLL: 481 case WM8993_SYSCLK_FLL:
536 dev_dbg(codec->dev, "Using %dHz FLL clock\n", 482 dev_dbg(codec->dev, "Using %dHz FLL clock\n",
537 wm8993->fll_fout); 483 wm8993->fll_fout);
538 484
539 reg = wm8993_read(codec, WM8993_CLOCKING_2); 485 reg = snd_soc_read(codec, WM8993_CLOCKING_2);
540 reg |= WM8993_SYSCLK_SRC; 486 reg |= WM8993_SYSCLK_SRC;
541 if (wm8993->fll_fout > 13500000) { 487 if (wm8993->fll_fout > 13500000) {
542 reg |= WM8993_MCLK_DIV; 488 reg |= WM8993_MCLK_DIV;
@@ -545,7 +491,7 @@ static int configure_clock(struct snd_soc_codec *codec)
545 reg &= ~WM8993_MCLK_DIV; 491 reg &= ~WM8993_MCLK_DIV;
546 wm8993->sysclk_rate = wm8993->fll_fout; 492 wm8993->sysclk_rate = wm8993->fll_fout;
547 } 493 }
548 wm8993_write(codec, WM8993_CLOCKING_2, reg); 494 snd_soc_write(codec, WM8993_CLOCKING_2, reg);
549 break; 495 break;
550 496
551 default: 497 default:
@@ -689,7 +635,7 @@ SOC_DOUBLE_TLV("Digital Sidetone Volume", WM8993_DIGITAL_SIDE_TONE,
689 635
690SOC_SINGLE("DRC Switch", WM8993_DRC_CONTROL_1, 15, 1, 0), 636SOC_SINGLE("DRC Switch", WM8993_DRC_CONTROL_1, 15, 1, 0),
691SOC_ENUM("DRC Path", drc_path), 637SOC_ENUM("DRC Path", drc_path),
692SOC_SINGLE_TLV("DRC Compressor Threashold Volume", WM8993_DRC_CONTROL_2, 638SOC_SINGLE_TLV("DRC Compressor Threshold Volume", WM8993_DRC_CONTROL_2,
693 2, 60, 1, drc_comp_threash), 639 2, 60, 1, drc_comp_threash),
694SOC_SINGLE_TLV("DRC Compressor Amplitude Volume", WM8993_DRC_CONTROL_3, 640SOC_SINGLE_TLV("DRC Compressor Amplitude Volume", WM8993_DRC_CONTROL_3,
695 11, 30, 1, drc_comp_amp), 641 11, 30, 1, drc_comp_amp),
@@ -709,7 +655,7 @@ SOC_SINGLE_TLV("DRC Quick Release Volume", WM8993_DRC_CONTROL_3, 2, 3, 0,
709SOC_ENUM("DRC Quick Release Rate", drc_qr_rate), 655SOC_ENUM("DRC Quick Release Rate", drc_qr_rate),
710SOC_SINGLE("DRC Smoothing Switch", WM8993_DRC_CONTROL_1, 11, 1, 0), 656SOC_SINGLE("DRC Smoothing Switch", WM8993_DRC_CONTROL_1, 11, 1, 0),
711SOC_SINGLE("DRC Smoothing Hysteresis Switch", WM8993_DRC_CONTROL_1, 8, 1, 0), 657SOC_SINGLE("DRC Smoothing Hysteresis Switch", WM8993_DRC_CONTROL_1, 8, 1, 0),
712SOC_ENUM("DRC Smoothing Hysteresis Threashold", drc_smooth), 658SOC_ENUM("DRC Smoothing Hysteresis Threshold", drc_smooth),
713SOC_SINGLE_TLV("DRC Startup Volume", WM8993_DRC_CONTROL_4, 8, 18, 0, 659SOC_SINGLE_TLV("DRC Startup Volume", WM8993_DRC_CONTROL_4, 8, 18, 0,
714 drc_startup_tlv), 660 drc_startup_tlv),
715 661
@@ -978,10 +924,33 @@ static const struct snd_soc_dapm_route routes[] = {
978 { "Right Headphone Mux", "DAC", "DACR" }, 924 { "Right Headphone Mux", "DAC", "DACR" },
979}; 925};
980 926
927static void wm8993_cache_restore(struct snd_soc_codec *codec)
928{
929 u16 *cache = codec->reg_cache;
930 int i;
931
932 if (!codec->cache_sync)
933 return;
934
935 /* Reenable hardware writes */
936 codec->cache_only = 0;
937
938 /* Restore the register settings */
939 for (i = 1; i < WM8993_MAX_REGISTER; i++) {
940 if (cache[i] == wm8993_reg_defaults[i])
941 continue;
942 snd_soc_write(codec, i, cache[i]);
943 }
944
945 /* We're in sync again */
946 codec->cache_sync = 0;
947}
948
981static int wm8993_set_bias_level(struct snd_soc_codec *codec, 949static int wm8993_set_bias_level(struct snd_soc_codec *codec,
982 enum snd_soc_bias_level level) 950 enum snd_soc_bias_level level)
983{ 951{
984 struct wm8993_priv *wm8993 = codec->private_data; 952 struct wm8993_priv *wm8993 = codec->private_data;
953 int ret;
985 954
986 switch (level) { 955 switch (level) {
987 case SND_SOC_BIAS_ON: 956 case SND_SOC_BIAS_ON:
@@ -995,6 +964,18 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec,
995 964
996 case SND_SOC_BIAS_STANDBY: 965 case SND_SOC_BIAS_STANDBY:
997 if (codec->bias_level == SND_SOC_BIAS_OFF) { 966 if (codec->bias_level == SND_SOC_BIAS_OFF) {
967 ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies),
968 wm8993->supplies);
969 if (ret != 0)
970 return ret;
971
972 wm8993_cache_restore(codec);
973
974 /* Tune DC servo configuration */
975 snd_soc_write(codec, 0x44, 3);
976 snd_soc_write(codec, 0x56, 3);
977 snd_soc_write(codec, 0x44, 0);
978
998 /* Bring up VMID with fast soft start */ 979 /* Bring up VMID with fast soft start */
999 snd_soc_update_bits(codec, WM8993_ANTIPOP2, 980 snd_soc_update_bits(codec, WM8993_ANTIPOP2,
1000 WM8993_STARTUP_BIAS_ENA | 981 WM8993_STARTUP_BIAS_ENA |
@@ -1042,6 +1023,18 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec,
1042 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1, 1023 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
1043 WM8993_VMID_SEL_MASK | WM8993_BIAS_ENA, 1024 WM8993_VMID_SEL_MASK | WM8993_BIAS_ENA,
1044 0); 1025 0);
1026
1027#ifdef CONFIG_REGULATOR
1028 /* Post 2.6.34 we will be able to get a callback when
1029 * the regulators are disabled which we can use but
1030 * for now just assume that the power will be cut if
1031 * the regulator API is in use.
1032 */
1033 codec->cache_sync = 1;
1034#endif
1035
1036 regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies),
1037 wm8993->supplies);
1045 break; 1038 break;
1046 } 1039 }
1047 1040
@@ -1075,8 +1068,8 @@ static int wm8993_set_dai_fmt(struct snd_soc_dai *dai,
1075{ 1068{
1076 struct snd_soc_codec *codec = dai->codec; 1069 struct snd_soc_codec *codec = dai->codec;
1077 struct wm8993_priv *wm8993 = codec->private_data; 1070 struct wm8993_priv *wm8993 = codec->private_data;
1078 unsigned int aif1 = wm8993_read(codec, WM8993_AUDIO_INTERFACE_1); 1071 unsigned int aif1 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_1);
1079 unsigned int aif4 = wm8993_read(codec, WM8993_AUDIO_INTERFACE_4); 1072 unsigned int aif4 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_4);
1080 1073
1081 aif1 &= ~(WM8993_BCLK_DIR | WM8993_AIF_BCLK_INV | 1074 aif1 &= ~(WM8993_BCLK_DIR | WM8993_AIF_BCLK_INV |
1082 WM8993_AIF_LRCLK_INV | WM8993_AIF_FMT_MASK); 1075 WM8993_AIF_LRCLK_INV | WM8993_AIF_FMT_MASK);
@@ -1159,8 +1152,8 @@ static int wm8993_set_dai_fmt(struct snd_soc_dai *dai,
1159 return -EINVAL; 1152 return -EINVAL;
1160 } 1153 }
1161 1154
1162 wm8993_write(codec, WM8993_AUDIO_INTERFACE_1, aif1); 1155 snd_soc_write(codec, WM8993_AUDIO_INTERFACE_1, aif1);
1163 wm8993_write(codec, WM8993_AUDIO_INTERFACE_4, aif4); 1156 snd_soc_write(codec, WM8993_AUDIO_INTERFACE_4, aif4);
1164 1157
1165 return 0; 1158 return 0;
1166} 1159}
@@ -1174,16 +1167,16 @@ static int wm8993_hw_params(struct snd_pcm_substream *substream,
1174 int ret, i, best, best_val, cur_val; 1167 int ret, i, best, best_val, cur_val;
1175 unsigned int clocking1, clocking3, aif1, aif4; 1168 unsigned int clocking1, clocking3, aif1, aif4;
1176 1169
1177 clocking1 = wm8993_read(codec, WM8993_CLOCKING_1); 1170 clocking1 = snd_soc_read(codec, WM8993_CLOCKING_1);
1178 clocking1 &= ~WM8993_BCLK_DIV_MASK; 1171 clocking1 &= ~WM8993_BCLK_DIV_MASK;
1179 1172
1180 clocking3 = wm8993_read(codec, WM8993_CLOCKING_3); 1173 clocking3 = snd_soc_read(codec, WM8993_CLOCKING_3);
1181 clocking3 &= ~(WM8993_CLK_SYS_RATE_MASK | WM8993_SAMPLE_RATE_MASK); 1174 clocking3 &= ~(WM8993_CLK_SYS_RATE_MASK | WM8993_SAMPLE_RATE_MASK);
1182 1175
1183 aif1 = wm8993_read(codec, WM8993_AUDIO_INTERFACE_1); 1176 aif1 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_1);
1184 aif1 &= ~WM8993_AIF_WL_MASK; 1177 aif1 &= ~WM8993_AIF_WL_MASK;
1185 1178
1186 aif4 = wm8993_read(codec, WM8993_AUDIO_INTERFACE_4); 1179 aif4 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_4);
1187 aif4 &= ~WM8993_LRCLK_RATE_MASK; 1180 aif4 &= ~WM8993_LRCLK_RATE_MASK;
1188 1181
1189 /* What BCLK do we need? */ 1182 /* What BCLK do we need? */
@@ -1276,14 +1269,14 @@ static int wm8993_hw_params(struct snd_pcm_substream *substream,
1276 dev_dbg(codec->dev, "LRCLK_RATE is %d\n", wm8993->bclk / wm8993->fs); 1269 dev_dbg(codec->dev, "LRCLK_RATE is %d\n", wm8993->bclk / wm8993->fs);
1277 aif4 |= wm8993->bclk / wm8993->fs; 1270 aif4 |= wm8993->bclk / wm8993->fs;
1278 1271
1279 wm8993_write(codec, WM8993_CLOCKING_1, clocking1); 1272 snd_soc_write(codec, WM8993_CLOCKING_1, clocking1);
1280 wm8993_write(codec, WM8993_CLOCKING_3, clocking3); 1273 snd_soc_write(codec, WM8993_CLOCKING_3, clocking3);
1281 wm8993_write(codec, WM8993_AUDIO_INTERFACE_1, aif1); 1274 snd_soc_write(codec, WM8993_AUDIO_INTERFACE_1, aif1);
1282 wm8993_write(codec, WM8993_AUDIO_INTERFACE_4, aif4); 1275 snd_soc_write(codec, WM8993_AUDIO_INTERFACE_4, aif4);
1283 1276
1284 /* ReTune Mobile? */ 1277 /* ReTune Mobile? */
1285 if (wm8993->pdata.num_retune_configs) { 1278 if (wm8993->pdata.num_retune_configs) {
1286 u16 eq1 = wm8993_read(codec, WM8993_EQ1); 1279 u16 eq1 = snd_soc_read(codec, WM8993_EQ1);
1287 struct wm8993_retune_mobile_setting *s; 1280 struct wm8993_retune_mobile_setting *s;
1288 1281
1289 best = 0; 1282 best = 0;
@@ -1306,7 +1299,7 @@ static int wm8993_hw_params(struct snd_pcm_substream *substream,
1306 snd_soc_update_bits(codec, WM8993_EQ1, WM8993_EQ_ENA, 0); 1299 snd_soc_update_bits(codec, WM8993_EQ1, WM8993_EQ_ENA, 0);
1307 1300
1308 for (i = 1; i < ARRAY_SIZE(s->config); i++) 1301 for (i = 1; i < ARRAY_SIZE(s->config); i++)
1309 wm8993_write(codec, WM8993_EQ1 + i, s->config[i]); 1302 snd_soc_write(codec, WM8993_EQ1 + i, s->config[i]);
1310 1303
1311 snd_soc_update_bits(codec, WM8993_EQ1, WM8993_EQ_ENA, eq1); 1304 snd_soc_update_bits(codec, WM8993_EQ1, WM8993_EQ_ENA, eq1);
1312 } 1305 }
@@ -1319,14 +1312,14 @@ static int wm8993_digital_mute(struct snd_soc_dai *codec_dai, int mute)
1319 struct snd_soc_codec *codec = codec_dai->codec; 1312 struct snd_soc_codec *codec = codec_dai->codec;
1320 unsigned int reg; 1313 unsigned int reg;
1321 1314
1322 reg = wm8993_read(codec, WM8993_DAC_CTRL); 1315 reg = snd_soc_read(codec, WM8993_DAC_CTRL);
1323 1316
1324 if (mute) 1317 if (mute)
1325 reg |= WM8993_DAC_MUTE; 1318 reg |= WM8993_DAC_MUTE;
1326 else 1319 else
1327 reg &= ~WM8993_DAC_MUTE; 1320 reg &= ~WM8993_DAC_MUTE;
1328 1321
1329 wm8993_write(codec, WM8993_DAC_CTRL, reg); 1322 snd_soc_write(codec, WM8993_DAC_CTRL, reg);
1330 1323
1331 return 0; 1324 return 0;
1332} 1325}
@@ -1464,19 +1457,8 @@ static int wm8993_probe(struct platform_device *pdev)
1464 wm_hubs_add_analogue_routes(codec, wm8993->pdata.lineout1_diff, 1457 wm_hubs_add_analogue_routes(codec, wm8993->pdata.lineout1_diff,
1465 wm8993->pdata.lineout2_diff); 1458 wm8993->pdata.lineout2_diff);
1466 1459
1467 snd_soc_dapm_new_widgets(codec);
1468
1469 ret = snd_soc_init_card(socdev);
1470 if (ret < 0) {
1471 dev_err(codec->dev, "failed to register card\n");
1472 goto card_err;
1473 }
1474
1475 return ret; 1460 return ret;
1476 1461
1477card_err:
1478 snd_soc_free_pcms(socdev);
1479 snd_soc_dapm_free(socdev);
1480err: 1462err:
1481 return ret; 1463 return ret;
1482} 1464}
@@ -1491,9 +1473,66 @@ static int wm8993_remove(struct platform_device *pdev)
1491 return 0; 1473 return 0;
1492} 1474}
1493 1475
1476#ifdef CONFIG_PM
1477static int wm8993_suspend(struct platform_device *pdev, pm_message_t state)
1478{
1479 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1480 struct snd_soc_codec *codec = socdev->card->codec;
1481 struct wm8993_priv *wm8993 = codec->private_data;
1482 int fll_fout = wm8993->fll_fout;
1483 int fll_fref = wm8993->fll_fref;
1484 int ret;
1485
1486 /* Stop the FLL in an orderly fashion */
1487 ret = wm8993_set_fll(codec->dai, 0, 0, 0, 0);
1488 if (ret != 0) {
1489 dev_err(&pdev->dev, "Failed to stop FLL\n");
1490 return ret;
1491 }
1492
1493 wm8993->fll_fout = fll_fout;
1494 wm8993->fll_fref = fll_fref;
1495
1496 wm8993_set_bias_level(codec, SND_SOC_BIAS_OFF);
1497
1498 return 0;
1499}
1500
1501static int wm8993_resume(struct platform_device *pdev)
1502{
1503 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1504 struct snd_soc_codec *codec = socdev->card->codec;
1505 struct wm8993_priv *wm8993 = codec->private_data;
1506 int ret;
1507
1508 wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1509
1510 /* Restart the FLL? */
1511 if (wm8993->fll_fout) {
1512 int fll_fout = wm8993->fll_fout;
1513 int fll_fref = wm8993->fll_fref;
1514
1515 wm8993->fll_fref = 0;
1516 wm8993->fll_fout = 0;
1517
1518 ret = wm8993_set_fll(codec->dai, 0, wm8993->fll_src,
1519 fll_fref, fll_fout);
1520 if (ret != 0)
1521 dev_err(codec->dev, "Failed to restart FLL\n");
1522 }
1523
1524 return 0;
1525}
1526#else
1527#define wm8993_suspend NULL
1528#define wm8993_resume NULL
1529#endif
1530
1494struct snd_soc_codec_device soc_codec_dev_wm8993 = { 1531struct snd_soc_codec_device soc_codec_dev_wm8993 = {
1495 .probe = wm8993_probe, 1532 .probe = wm8993_probe,
1496 .remove = wm8993_remove, 1533 .remove = wm8993_remove,
1534 .suspend = wm8993_suspend,
1535 .resume = wm8993_resume,
1497}; 1536};
1498EXPORT_SYMBOL_GPL(soc_codec_dev_wm8993); 1537EXPORT_SYMBOL_GPL(soc_codec_dev_wm8993);
1499 1538
@@ -1504,6 +1543,7 @@ static int wm8993_i2c_probe(struct i2c_client *i2c,
1504 struct snd_soc_codec *codec; 1543 struct snd_soc_codec *codec;
1505 unsigned int val; 1544 unsigned int val;
1506 int ret; 1545 int ret;
1546 int i;
1507 1547
1508 if (wm8993_codec) { 1548 if (wm8993_codec) {
1509 dev_err(&i2c->dev, "A WM8993 is already registered\n"); 1549 dev_err(&i2c->dev, "A WM8993 is already registered\n");
@@ -1524,9 +1564,7 @@ static int wm8993_i2c_probe(struct i2c_client *i2c,
1524 INIT_LIST_HEAD(&codec->dapm_paths); 1564 INIT_LIST_HEAD(&codec->dapm_paths);
1525 1565
1526 codec->name = "WM8993"; 1566 codec->name = "WM8993";
1527 codec->read = wm8993_read; 1567 codec->volatile_register = wm8993_volatile;
1528 codec->write = wm8993_write;
1529 codec->hw_write = (hw_write_t)i2c_master_send;
1530 codec->reg_cache = wm8993->reg_cache; 1568 codec->reg_cache = wm8993->reg_cache;
1531 codec->reg_cache_size = ARRAY_SIZE(wm8993->reg_cache); 1569 codec->reg_cache_size = ARRAY_SIZE(wm8993->reg_cache);
1532 codec->bias_level = SND_SOC_BIAS_OFF; 1570 codec->bias_level = SND_SOC_BIAS_OFF;
@@ -1535,25 +1573,53 @@ static int wm8993_i2c_probe(struct i2c_client *i2c,
1535 codec->num_dai = 1; 1573 codec->num_dai = 1;
1536 codec->private_data = wm8993; 1574 codec->private_data = wm8993;
1537 1575
1576 wm8993->hubs_data.hp_startup_mode = 1;
1577 wm8993->hubs_data.dcs_codes = -2;
1578
1538 memcpy(wm8993->reg_cache, wm8993_reg_defaults, 1579 memcpy(wm8993->reg_cache, wm8993_reg_defaults,
1539 sizeof(wm8993->reg_cache)); 1580 sizeof(wm8993->reg_cache));
1540 1581
1582 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
1583 if (ret != 0) {
1584 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1585 goto err;
1586 }
1587
1541 i2c_set_clientdata(i2c, wm8993); 1588 i2c_set_clientdata(i2c, wm8993);
1542 codec->control_data = i2c; 1589 codec->control_data = i2c;
1543 wm8993_codec = codec; 1590 wm8993_codec = codec;
1544 1591
1545 codec->dev = &i2c->dev; 1592 codec->dev = &i2c->dev;
1546 1593
1547 val = wm8993_read_hw(codec, WM8993_SOFTWARE_RESET); 1594 for (i = 0; i < ARRAY_SIZE(wm8993->supplies); i++)
1595 wm8993->supplies[i].supply = wm8993_supply_names[i];
1596
1597 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8993->supplies),
1598 wm8993->supplies);
1599 if (ret != 0) {
1600 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
1601 goto err;
1602 }
1603
1604 ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies),
1605 wm8993->supplies);
1606 if (ret != 0) {
1607 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
1608 goto err_get;
1609 }
1610
1611 val = snd_soc_read(codec, WM8993_SOFTWARE_RESET);
1548 if (val != wm8993_reg_defaults[WM8993_SOFTWARE_RESET]) { 1612 if (val != wm8993_reg_defaults[WM8993_SOFTWARE_RESET]) {
1549 dev_err(codec->dev, "Invalid ID register value %x\n", val); 1613 dev_err(codec->dev, "Invalid ID register value %x\n", val);
1550 ret = -EINVAL; 1614 ret = -EINVAL;
1551 goto err; 1615 goto err_enable;
1552 } 1616 }
1553 1617
1554 ret = wm8993_write(codec, WM8993_SOFTWARE_RESET, 0xffff); 1618 ret = snd_soc_write(codec, WM8993_SOFTWARE_RESET, 0xffff);
1555 if (ret != 0) 1619 if (ret != 0)
1556 goto err; 1620 goto err_enable;
1621
1622 codec->cache_only = 1;
1557 1623
1558 /* By default we're using the output mixers */ 1624 /* By default we're using the output mixers */
1559 wm8993->class_w_users = 2; 1625 wm8993->class_w_users = 2;
@@ -1572,36 +1638,18 @@ static int wm8993_i2c_probe(struct i2c_client *i2c,
1572 /* Use automatic clock configuration */ 1638 /* Use automatic clock configuration */
1573 snd_soc_update_bits(codec, WM8993_CLOCKING_4, WM8993_SR_MODE, 0); 1639 snd_soc_update_bits(codec, WM8993_CLOCKING_4, WM8993_SR_MODE, 0);
1574 1640
1575 if (!wm8993->pdata.lineout1_diff) 1641 wm_hubs_handle_analogue_pdata(codec, wm8993->pdata.lineout1_diff,
1576 snd_soc_update_bits(codec, WM8993_LINE_MIXER1, 1642 wm8993->pdata.lineout2_diff,
1577 WM8993_LINEOUT1_MODE, 1643 wm8993->pdata.lineout1fb,
1578 WM8993_LINEOUT1_MODE); 1644 wm8993->pdata.lineout2fb,
1579 if (!wm8993->pdata.lineout2_diff) 1645 wm8993->pdata.jd_scthr,
1580 snd_soc_update_bits(codec, WM8993_LINE_MIXER2, 1646 wm8993->pdata.jd_thr,
1581 WM8993_LINEOUT2_MODE, 1647 wm8993->pdata.micbias1_lvl,
1582 WM8993_LINEOUT2_MODE); 1648 wm8993->pdata.micbias2_lvl);
1583 1649
1584 if (wm8993->pdata.lineout1fb)
1585 snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL,
1586 WM8993_LINEOUT1_FB, WM8993_LINEOUT1_FB);
1587
1588 if (wm8993->pdata.lineout2fb)
1589 snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL,
1590 WM8993_LINEOUT2_FB, WM8993_LINEOUT2_FB);
1591
1592 /* Apply the microphone bias/detection configuration - the
1593 * platform data is directly applicable to the register. */
1594 snd_soc_update_bits(codec, WM8993_MICBIAS,
1595 WM8993_JD_SCTHR_MASK | WM8993_JD_THR_MASK |
1596 WM8993_MICB1_LVL | WM8993_MICB2_LVL,
1597 wm8993->pdata.jd_scthr << WM8993_JD_SCTHR_SHIFT |
1598 wm8993->pdata.jd_thr << WM8993_JD_THR_SHIFT |
1599 wm8993->pdata.micbias1_lvl |
1600 wm8993->pdata.micbias1_lvl << 1);
1601
1602 ret = wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1650 ret = wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1603 if (ret != 0) 1651 if (ret != 0)
1604 goto err; 1652 goto err_enable;
1605 1653
1606 wm8993_dai.dev = codec->dev; 1654 wm8993_dai.dev = codec->dev;
1607 1655
@@ -1615,6 +1663,10 @@ static int wm8993_i2c_probe(struct i2c_client *i2c,
1615 1663
1616err_bias: 1664err_bias:
1617 wm8993_set_bias_level(codec, SND_SOC_BIAS_OFF); 1665 wm8993_set_bias_level(codec, SND_SOC_BIAS_OFF);
1666err_enable:
1667 regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
1668err_get:
1669 regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
1618err: 1670err:
1619 wm8993_codec = NULL; 1671 wm8993_codec = NULL;
1620 kfree(wm8993); 1672 kfree(wm8993);
@@ -1629,6 +1681,7 @@ static int wm8993_i2c_remove(struct i2c_client *client)
1629 snd_soc_unregister_dai(&wm8993_dai); 1681 snd_soc_unregister_dai(&wm8993_dai);
1630 1682
1631 wm8993_set_bias_level(&wm8993->codec, SND_SOC_BIAS_OFF); 1683 wm8993_set_bias_level(&wm8993->codec, SND_SOC_BIAS_OFF);
1684 regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
1632 kfree(wm8993); 1685 kfree(wm8993);
1633 1686
1634 return 0; 1687 return 0;
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
new file mode 100644
index 000000000000..9da0724cd47a
--- /dev/null
+++ b/sound/soc/codecs/wm8994.c
@@ -0,0 +1,3874 @@
1/*
2 * wm8994.c -- WM8994 ALSA SoC Audio driver
3 *
4 * Copyright 2009 Wolfson Microelectronics plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/module.h>
15#include <linux/moduleparam.h>
16#include <linux/init.h>
17#include <linux/delay.h>
18#include <linux/pm.h>
19#include <linux/i2c.h>
20#include <linux/platform_device.h>
21#include <linux/regulator/consumer.h>
22#include <linux/slab.h>
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/initval.h>
29#include <sound/tlv.h>
30
31#include <linux/mfd/wm8994/core.h>
32#include <linux/mfd/wm8994/registers.h>
33#include <linux/mfd/wm8994/pdata.h>
34#include <linux/mfd/wm8994/gpio.h>
35
36#include "wm8994.h"
37#include "wm_hubs.h"
38
39static struct snd_soc_codec *wm8994_codec;
40struct snd_soc_codec_device soc_codec_dev_wm8994;
41
42struct fll_config {
43 int src;
44 int in;
45 int out;
46};
47
48#define WM8994_NUM_DRC 3
49#define WM8994_NUM_EQ 3
50
51static int wm8994_drc_base[] = {
52 WM8994_AIF1_DRC1_1,
53 WM8994_AIF1_DRC2_1,
54 WM8994_AIF2_DRC_1,
55};
56
57static int wm8994_retune_mobile_base[] = {
58 WM8994_AIF1_DAC1_EQ_GAINS_1,
59 WM8994_AIF1_DAC2_EQ_GAINS_1,
60 WM8994_AIF2_EQ_GAINS_1,
61};
62
63#define WM8994_REG_CACHE_SIZE 0x621
64
65/* codec private data */
66struct wm8994_priv {
67 struct wm_hubs_data hubs;
68 struct snd_soc_codec codec;
69 u16 reg_cache[WM8994_REG_CACHE_SIZE + 1];
70 int sysclk[2];
71 int sysclk_rate[2];
72 int mclk[2];
73 int aifclk[2];
74 struct fll_config fll[2], fll_suspend[2];
75
76 int dac_rates[2];
77 int lrclk_shared[2];
78
79 /* Platform dependant DRC configuration */
80 const char **drc_texts;
81 int drc_cfg[WM8994_NUM_DRC];
82 struct soc_enum drc_enum;
83
84 /* Platform dependant ReTune mobile configuration */
85 int num_retune_mobile_texts;
86 const char **retune_mobile_texts;
87 int retune_mobile_cfg[WM8994_NUM_EQ];
88 struct soc_enum retune_mobile_enum;
89
90 struct wm8994_pdata *pdata;
91};
92
93static struct {
94 unsigned short readable; /* Mask of readable bits */
95 unsigned short writable; /* Mask of writable bits */
96 unsigned short vol; /* Mask of volatile bits */
97} access_masks[] = {
98 { 0xFFFF, 0xFFFF, 0x0000 }, /* R0 - Software Reset */
99 { 0x3B37, 0x3B37, 0x0000 }, /* R1 - Power Management (1) */
100 { 0x6BF0, 0x6BF0, 0x0000 }, /* R2 - Power Management (2) */
101 { 0x3FF0, 0x3FF0, 0x0000 }, /* R3 - Power Management (3) */
102 { 0x3F3F, 0x3F3F, 0x0000 }, /* R4 - Power Management (4) */
103 { 0x3F0F, 0x3F0F, 0x0000 }, /* R5 - Power Management (5) */
104 { 0x003F, 0x003F, 0x0000 }, /* R6 - Power Management (6) */
105 { 0x0000, 0x0000, 0x0000 }, /* R7 */
106 { 0x0000, 0x0000, 0x0000 }, /* R8 */
107 { 0x0000, 0x0000, 0x0000 }, /* R9 */
108 { 0x0000, 0x0000, 0x0000 }, /* R10 */
109 { 0x0000, 0x0000, 0x0000 }, /* R11 */
110 { 0x0000, 0x0000, 0x0000 }, /* R12 */
111 { 0x0000, 0x0000, 0x0000 }, /* R13 */
112 { 0x0000, 0x0000, 0x0000 }, /* R14 */
113 { 0x0000, 0x0000, 0x0000 }, /* R15 */
114 { 0x0000, 0x0000, 0x0000 }, /* R16 */
115 { 0x0000, 0x0000, 0x0000 }, /* R17 */
116 { 0x0000, 0x0000, 0x0000 }, /* R18 */
117 { 0x0000, 0x0000, 0x0000 }, /* R19 */
118 { 0x0000, 0x0000, 0x0000 }, /* R20 */
119 { 0x01C0, 0x01C0, 0x0000 }, /* R21 - Input Mixer (1) */
120 { 0x0000, 0x0000, 0x0000 }, /* R22 */
121 { 0x0000, 0x0000, 0x0000 }, /* R23 */
122 { 0x00DF, 0x01DF, 0x0000 }, /* R24 - Left Line Input 1&2 Volume */
123 { 0x00DF, 0x01DF, 0x0000 }, /* R25 - Left Line Input 3&4 Volume */
124 { 0x00DF, 0x01DF, 0x0000 }, /* R26 - Right Line Input 1&2 Volume */
125 { 0x00DF, 0x01DF, 0x0000 }, /* R27 - Right Line Input 3&4 Volume */
126 { 0x00FF, 0x01FF, 0x0000 }, /* R28 - Left Output Volume */
127 { 0x00FF, 0x01FF, 0x0000 }, /* R29 - Right Output Volume */
128 { 0x0077, 0x0077, 0x0000 }, /* R30 - Line Outputs Volume */
129 { 0x0030, 0x0030, 0x0000 }, /* R31 - HPOUT2 Volume */
130 { 0x00FF, 0x01FF, 0x0000 }, /* R32 - Left OPGA Volume */
131 { 0x00FF, 0x01FF, 0x0000 }, /* R33 - Right OPGA Volume */
132 { 0x007F, 0x007F, 0x0000 }, /* R34 - SPKMIXL Attenuation */
133 { 0x017F, 0x017F, 0x0000 }, /* R35 - SPKMIXR Attenuation */
134 { 0x003F, 0x003F, 0x0000 }, /* R36 - SPKOUT Mixers */
135 { 0x003F, 0x003F, 0x0000 }, /* R37 - ClassD */
136 { 0x00FF, 0x01FF, 0x0000 }, /* R38 - Speaker Volume Left */
137 { 0x00FF, 0x01FF, 0x0000 }, /* R39 - Speaker Volume Right */
138 { 0x00FF, 0x00FF, 0x0000 }, /* R40 - Input Mixer (2) */
139 { 0x01B7, 0x01B7, 0x0000 }, /* R41 - Input Mixer (3) */
140 { 0x01B7, 0x01B7, 0x0000 }, /* R42 - Input Mixer (4) */
141 { 0x01C7, 0x01C7, 0x0000 }, /* R43 - Input Mixer (5) */
142 { 0x01C7, 0x01C7, 0x0000 }, /* R44 - Input Mixer (6) */
143 { 0x01FF, 0x01FF, 0x0000 }, /* R45 - Output Mixer (1) */
144 { 0x01FF, 0x01FF, 0x0000 }, /* R46 - Output Mixer (2) */
145 { 0x0FFF, 0x0FFF, 0x0000 }, /* R47 - Output Mixer (3) */
146 { 0x0FFF, 0x0FFF, 0x0000 }, /* R48 - Output Mixer (4) */
147 { 0x0FFF, 0x0FFF, 0x0000 }, /* R49 - Output Mixer (5) */
148 { 0x0FFF, 0x0FFF, 0x0000 }, /* R50 - Output Mixer (6) */
149 { 0x0038, 0x0038, 0x0000 }, /* R51 - HPOUT2 Mixer */
150 { 0x0077, 0x0077, 0x0000 }, /* R52 - Line Mixer (1) */
151 { 0x0077, 0x0077, 0x0000 }, /* R53 - Line Mixer (2) */
152 { 0x03FF, 0x03FF, 0x0000 }, /* R54 - Speaker Mixer */
153 { 0x00C1, 0x00C1, 0x0000 }, /* R55 - Additional Control */
154 { 0x00F0, 0x00F0, 0x0000 }, /* R56 - AntiPOP (1) */
155 { 0x01EF, 0x01EF, 0x0000 }, /* R57 - AntiPOP (2) */
156 { 0x00FF, 0x00FF, 0x0000 }, /* R58 - MICBIAS */
157 { 0x000F, 0x000F, 0x0000 }, /* R59 - LDO 1 */
158 { 0x0007, 0x0007, 0x0000 }, /* R60 - LDO 2 */
159 { 0x0000, 0x0000, 0x0000 }, /* R61 */
160 { 0x0000, 0x0000, 0x0000 }, /* R62 */
161 { 0x0000, 0x0000, 0x0000 }, /* R63 */
162 { 0x0000, 0x0000, 0x0000 }, /* R64 */
163 { 0x0000, 0x0000, 0x0000 }, /* R65 */
164 { 0x0000, 0x0000, 0x0000 }, /* R66 */
165 { 0x0000, 0x0000, 0x0000 }, /* R67 */
166 { 0x0000, 0x0000, 0x0000 }, /* R68 */
167 { 0x0000, 0x0000, 0x0000 }, /* R69 */
168 { 0x0000, 0x0000, 0x0000 }, /* R70 */
169 { 0x0000, 0x0000, 0x0000 }, /* R71 */
170 { 0x0000, 0x0000, 0x0000 }, /* R72 */
171 { 0x0000, 0x0000, 0x0000 }, /* R73 */
172 { 0x0000, 0x0000, 0x0000 }, /* R74 */
173 { 0x0000, 0x0000, 0x0000 }, /* R75 */
174 { 0x8000, 0x8000, 0x0000 }, /* R76 - Charge Pump (1) */
175 { 0x0000, 0x0000, 0x0000 }, /* R77 */
176 { 0x0000, 0x0000, 0x0000 }, /* R78 */
177 { 0x0000, 0x0000, 0x0000 }, /* R79 */
178 { 0x0000, 0x0000, 0x0000 }, /* R80 */
179 { 0x0301, 0x0301, 0x0000 }, /* R81 - Class W (1) */
180 { 0x0000, 0x0000, 0x0000 }, /* R82 */
181 { 0x0000, 0x0000, 0x0000 }, /* R83 */
182 { 0x333F, 0x333F, 0x0000 }, /* R84 - DC Servo (1) */
183 { 0x0FEF, 0x0FEF, 0x0000 }, /* R85 - DC Servo (2) */
184 { 0x0000, 0x0000, 0x0000 }, /* R86 */
185 { 0xFFFF, 0xFFFF, 0x0000 }, /* R87 - DC Servo (4) */
186 { 0x0333, 0x0000, 0x0000 }, /* R88 - DC Servo Readback */
187 { 0x0000, 0x0000, 0x0000 }, /* R89 */
188 { 0x0000, 0x0000, 0x0000 }, /* R90 */
189 { 0x0000, 0x0000, 0x0000 }, /* R91 */
190 { 0x0000, 0x0000, 0x0000 }, /* R92 */
191 { 0x0000, 0x0000, 0x0000 }, /* R93 */
192 { 0x0000, 0x0000, 0x0000 }, /* R94 */
193 { 0x0000, 0x0000, 0x0000 }, /* R95 */
194 { 0x00EE, 0x00EE, 0x0000 }, /* R96 - Analogue HP (1) */
195 { 0x0000, 0x0000, 0x0000 }, /* R97 */
196 { 0x0000, 0x0000, 0x0000 }, /* R98 */
197 { 0x0000, 0x0000, 0x0000 }, /* R99 */
198 { 0x0000, 0x0000, 0x0000 }, /* R100 */
199 { 0x0000, 0x0000, 0x0000 }, /* R101 */
200 { 0x0000, 0x0000, 0x0000 }, /* R102 */
201 { 0x0000, 0x0000, 0x0000 }, /* R103 */
202 { 0x0000, 0x0000, 0x0000 }, /* R104 */
203 { 0x0000, 0x0000, 0x0000 }, /* R105 */
204 { 0x0000, 0x0000, 0x0000 }, /* R106 */
205 { 0x0000, 0x0000, 0x0000 }, /* R107 */
206 { 0x0000, 0x0000, 0x0000 }, /* R108 */
207 { 0x0000, 0x0000, 0x0000 }, /* R109 */
208 { 0x0000, 0x0000, 0x0000 }, /* R110 */
209 { 0x0000, 0x0000, 0x0000 }, /* R111 */
210 { 0x0000, 0x0000, 0x0000 }, /* R112 */
211 { 0x0000, 0x0000, 0x0000 }, /* R113 */
212 { 0x0000, 0x0000, 0x0000 }, /* R114 */
213 { 0x0000, 0x0000, 0x0000 }, /* R115 */
214 { 0x0000, 0x0000, 0x0000 }, /* R116 */
215 { 0x0000, 0x0000, 0x0000 }, /* R117 */
216 { 0x0000, 0x0000, 0x0000 }, /* R118 */
217 { 0x0000, 0x0000, 0x0000 }, /* R119 */
218 { 0x0000, 0x0000, 0x0000 }, /* R120 */
219 { 0x0000, 0x0000, 0x0000 }, /* R121 */
220 { 0x0000, 0x0000, 0x0000 }, /* R122 */
221 { 0x0000, 0x0000, 0x0000 }, /* R123 */
222 { 0x0000, 0x0000, 0x0000 }, /* R124 */
223 { 0x0000, 0x0000, 0x0000 }, /* R125 */
224 { 0x0000, 0x0000, 0x0000 }, /* R126 */
225 { 0x0000, 0x0000, 0x0000 }, /* R127 */
226 { 0x0000, 0x0000, 0x0000 }, /* R128 */
227 { 0x0000, 0x0000, 0x0000 }, /* R129 */
228 { 0x0000, 0x0000, 0x0000 }, /* R130 */
229 { 0x0000, 0x0000, 0x0000 }, /* R131 */
230 { 0x0000, 0x0000, 0x0000 }, /* R132 */
231 { 0x0000, 0x0000, 0x0000 }, /* R133 */
232 { 0x0000, 0x0000, 0x0000 }, /* R134 */
233 { 0x0000, 0x0000, 0x0000 }, /* R135 */
234 { 0x0000, 0x0000, 0x0000 }, /* R136 */
235 { 0x0000, 0x0000, 0x0000 }, /* R137 */
236 { 0x0000, 0x0000, 0x0000 }, /* R138 */
237 { 0x0000, 0x0000, 0x0000 }, /* R139 */
238 { 0x0000, 0x0000, 0x0000 }, /* R140 */
239 { 0x0000, 0x0000, 0x0000 }, /* R141 */
240 { 0x0000, 0x0000, 0x0000 }, /* R142 */
241 { 0x0000, 0x0000, 0x0000 }, /* R143 */
242 { 0x0000, 0x0000, 0x0000 }, /* R144 */
243 { 0x0000, 0x0000, 0x0000 }, /* R145 */
244 { 0x0000, 0x0000, 0x0000 }, /* R146 */
245 { 0x0000, 0x0000, 0x0000 }, /* R147 */
246 { 0x0000, 0x0000, 0x0000 }, /* R148 */
247 { 0x0000, 0x0000, 0x0000 }, /* R149 */
248 { 0x0000, 0x0000, 0x0000 }, /* R150 */
249 { 0x0000, 0x0000, 0x0000 }, /* R151 */
250 { 0x0000, 0x0000, 0x0000 }, /* R152 */
251 { 0x0000, 0x0000, 0x0000 }, /* R153 */
252 { 0x0000, 0x0000, 0x0000 }, /* R154 */
253 { 0x0000, 0x0000, 0x0000 }, /* R155 */
254 { 0x0000, 0x0000, 0x0000 }, /* R156 */
255 { 0x0000, 0x0000, 0x0000 }, /* R157 */
256 { 0x0000, 0x0000, 0x0000 }, /* R158 */
257 { 0x0000, 0x0000, 0x0000 }, /* R159 */
258 { 0x0000, 0x0000, 0x0000 }, /* R160 */
259 { 0x0000, 0x0000, 0x0000 }, /* R161 */
260 { 0x0000, 0x0000, 0x0000 }, /* R162 */
261 { 0x0000, 0x0000, 0x0000 }, /* R163 */
262 { 0x0000, 0x0000, 0x0000 }, /* R164 */
263 { 0x0000, 0x0000, 0x0000 }, /* R165 */
264 { 0x0000, 0x0000, 0x0000 }, /* R166 */
265 { 0x0000, 0x0000, 0x0000 }, /* R167 */
266 { 0x0000, 0x0000, 0x0000 }, /* R168 */
267 { 0x0000, 0x0000, 0x0000 }, /* R169 */
268 { 0x0000, 0x0000, 0x0000 }, /* R170 */
269 { 0x0000, 0x0000, 0x0000 }, /* R171 */
270 { 0x0000, 0x0000, 0x0000 }, /* R172 */
271 { 0x0000, 0x0000, 0x0000 }, /* R173 */
272 { 0x0000, 0x0000, 0x0000 }, /* R174 */
273 { 0x0000, 0x0000, 0x0000 }, /* R175 */
274 { 0x0000, 0x0000, 0x0000 }, /* R176 */
275 { 0x0000, 0x0000, 0x0000 }, /* R177 */
276 { 0x0000, 0x0000, 0x0000 }, /* R178 */
277 { 0x0000, 0x0000, 0x0000 }, /* R179 */
278 { 0x0000, 0x0000, 0x0000 }, /* R180 */
279 { 0x0000, 0x0000, 0x0000 }, /* R181 */
280 { 0x0000, 0x0000, 0x0000 }, /* R182 */
281 { 0x0000, 0x0000, 0x0000 }, /* R183 */
282 { 0x0000, 0x0000, 0x0000 }, /* R184 */
283 { 0x0000, 0x0000, 0x0000 }, /* R185 */
284 { 0x0000, 0x0000, 0x0000 }, /* R186 */
285 { 0x0000, 0x0000, 0x0000 }, /* R187 */
286 { 0x0000, 0x0000, 0x0000 }, /* R188 */
287 { 0x0000, 0x0000, 0x0000 }, /* R189 */
288 { 0x0000, 0x0000, 0x0000 }, /* R190 */
289 { 0x0000, 0x0000, 0x0000 }, /* R191 */
290 { 0x0000, 0x0000, 0x0000 }, /* R192 */
291 { 0x0000, 0x0000, 0x0000 }, /* R193 */
292 { 0x0000, 0x0000, 0x0000 }, /* R194 */
293 { 0x0000, 0x0000, 0x0000 }, /* R195 */
294 { 0x0000, 0x0000, 0x0000 }, /* R196 */
295 { 0x0000, 0x0000, 0x0000 }, /* R197 */
296 { 0x0000, 0x0000, 0x0000 }, /* R198 */
297 { 0x0000, 0x0000, 0x0000 }, /* R199 */
298 { 0x0000, 0x0000, 0x0000 }, /* R200 */
299 { 0x0000, 0x0000, 0x0000 }, /* R201 */
300 { 0x0000, 0x0000, 0x0000 }, /* R202 */
301 { 0x0000, 0x0000, 0x0000 }, /* R203 */
302 { 0x0000, 0x0000, 0x0000 }, /* R204 */
303 { 0x0000, 0x0000, 0x0000 }, /* R205 */
304 { 0x0000, 0x0000, 0x0000 }, /* R206 */
305 { 0x0000, 0x0000, 0x0000 }, /* R207 */
306 { 0x0000, 0x0000, 0x0000 }, /* R208 */
307 { 0x0000, 0x0000, 0x0000 }, /* R209 */
308 { 0x0000, 0x0000, 0x0000 }, /* R210 */
309 { 0x0000, 0x0000, 0x0000 }, /* R211 */
310 { 0x0000, 0x0000, 0x0000 }, /* R212 */
311 { 0x0000, 0x0000, 0x0000 }, /* R213 */
312 { 0x0000, 0x0000, 0x0000 }, /* R214 */
313 { 0x0000, 0x0000, 0x0000 }, /* R215 */
314 { 0x0000, 0x0000, 0x0000 }, /* R216 */
315 { 0x0000, 0x0000, 0x0000 }, /* R217 */
316 { 0x0000, 0x0000, 0x0000 }, /* R218 */
317 { 0x0000, 0x0000, 0x0000 }, /* R219 */
318 { 0x0000, 0x0000, 0x0000 }, /* R220 */
319 { 0x0000, 0x0000, 0x0000 }, /* R221 */
320 { 0x0000, 0x0000, 0x0000 }, /* R222 */
321 { 0x0000, 0x0000, 0x0000 }, /* R223 */
322 { 0x0000, 0x0000, 0x0000 }, /* R224 */
323 { 0x0000, 0x0000, 0x0000 }, /* R225 */
324 { 0x0000, 0x0000, 0x0000 }, /* R226 */
325 { 0x0000, 0x0000, 0x0000 }, /* R227 */
326 { 0x0000, 0x0000, 0x0000 }, /* R228 */
327 { 0x0000, 0x0000, 0x0000 }, /* R229 */
328 { 0x0000, 0x0000, 0x0000 }, /* R230 */
329 { 0x0000, 0x0000, 0x0000 }, /* R231 */
330 { 0x0000, 0x0000, 0x0000 }, /* R232 */
331 { 0x0000, 0x0000, 0x0000 }, /* R233 */
332 { 0x0000, 0x0000, 0x0000 }, /* R234 */
333 { 0x0000, 0x0000, 0x0000 }, /* R235 */
334 { 0x0000, 0x0000, 0x0000 }, /* R236 */
335 { 0x0000, 0x0000, 0x0000 }, /* R237 */
336 { 0x0000, 0x0000, 0x0000 }, /* R238 */
337 { 0x0000, 0x0000, 0x0000 }, /* R239 */
338 { 0x0000, 0x0000, 0x0000 }, /* R240 */
339 { 0x0000, 0x0000, 0x0000 }, /* R241 */
340 { 0x0000, 0x0000, 0x0000 }, /* R242 */
341 { 0x0000, 0x0000, 0x0000 }, /* R243 */
342 { 0x0000, 0x0000, 0x0000 }, /* R244 */
343 { 0x0000, 0x0000, 0x0000 }, /* R245 */
344 { 0x0000, 0x0000, 0x0000 }, /* R246 */
345 { 0x0000, 0x0000, 0x0000 }, /* R247 */
346 { 0x0000, 0x0000, 0x0000 }, /* R248 */
347 { 0x0000, 0x0000, 0x0000 }, /* R249 */
348 { 0x0000, 0x0000, 0x0000 }, /* R250 */
349 { 0x0000, 0x0000, 0x0000 }, /* R251 */
350 { 0x0000, 0x0000, 0x0000 }, /* R252 */
351 { 0x0000, 0x0000, 0x0000 }, /* R253 */
352 { 0x0000, 0x0000, 0x0000 }, /* R254 */
353 { 0x0000, 0x0000, 0x0000 }, /* R255 */
354 { 0x000F, 0x0000, 0x0000 }, /* R256 - Chip Revision */
355 { 0x0074, 0x0074, 0x0000 }, /* R257 - Control Interface */
356 { 0x0000, 0x0000, 0x0000 }, /* R258 */
357 { 0x0000, 0x0000, 0x0000 }, /* R259 */
358 { 0x0000, 0x0000, 0x0000 }, /* R260 */
359 { 0x0000, 0x0000, 0x0000 }, /* R261 */
360 { 0x0000, 0x0000, 0x0000 }, /* R262 */
361 { 0x0000, 0x0000, 0x0000 }, /* R263 */
362 { 0x0000, 0x0000, 0x0000 }, /* R264 */
363 { 0x0000, 0x0000, 0x0000 }, /* R265 */
364 { 0x0000, 0x0000, 0x0000 }, /* R266 */
365 { 0x0000, 0x0000, 0x0000 }, /* R267 */
366 { 0x0000, 0x0000, 0x0000 }, /* R268 */
367 { 0x0000, 0x0000, 0x0000 }, /* R269 */
368 { 0x0000, 0x0000, 0x0000 }, /* R270 */
369 { 0x0000, 0x0000, 0x0000 }, /* R271 */
370 { 0x807F, 0x837F, 0x0000 }, /* R272 - Write Sequencer Ctrl (1) */
371 { 0x017F, 0x0000, 0x0000 }, /* R273 - Write Sequencer Ctrl (2) */
372 { 0x0000, 0x0000, 0x0000 }, /* R274 */
373 { 0x0000, 0x0000, 0x0000 }, /* R275 */
374 { 0x0000, 0x0000, 0x0000 }, /* R276 */
375 { 0x0000, 0x0000, 0x0000 }, /* R277 */
376 { 0x0000, 0x0000, 0x0000 }, /* R278 */
377 { 0x0000, 0x0000, 0x0000 }, /* R279 */
378 { 0x0000, 0x0000, 0x0000 }, /* R280 */
379 { 0x0000, 0x0000, 0x0000 }, /* R281 */
380 { 0x0000, 0x0000, 0x0000 }, /* R282 */
381 { 0x0000, 0x0000, 0x0000 }, /* R283 */
382 { 0x0000, 0x0000, 0x0000 }, /* R284 */
383 { 0x0000, 0x0000, 0x0000 }, /* R285 */
384 { 0x0000, 0x0000, 0x0000 }, /* R286 */
385 { 0x0000, 0x0000, 0x0000 }, /* R287 */
386 { 0x0000, 0x0000, 0x0000 }, /* R288 */
387 { 0x0000, 0x0000, 0x0000 }, /* R289 */
388 { 0x0000, 0x0000, 0x0000 }, /* R290 */
389 { 0x0000, 0x0000, 0x0000 }, /* R291 */
390 { 0x0000, 0x0000, 0x0000 }, /* R292 */
391 { 0x0000, 0x0000, 0x0000 }, /* R293 */
392 { 0x0000, 0x0000, 0x0000 }, /* R294 */
393 { 0x0000, 0x0000, 0x0000 }, /* R295 */
394 { 0x0000, 0x0000, 0x0000 }, /* R296 */
395 { 0x0000, 0x0000, 0x0000 }, /* R297 */
396 { 0x0000, 0x0000, 0x0000 }, /* R298 */
397 { 0x0000, 0x0000, 0x0000 }, /* R299 */
398 { 0x0000, 0x0000, 0x0000 }, /* R300 */
399 { 0x0000, 0x0000, 0x0000 }, /* R301 */
400 { 0x0000, 0x0000, 0x0000 }, /* R302 */
401 { 0x0000, 0x0000, 0x0000 }, /* R303 */
402 { 0x0000, 0x0000, 0x0000 }, /* R304 */
403 { 0x0000, 0x0000, 0x0000 }, /* R305 */
404 { 0x0000, 0x0000, 0x0000 }, /* R306 */
405 { 0x0000, 0x0000, 0x0000 }, /* R307 */
406 { 0x0000, 0x0000, 0x0000 }, /* R308 */
407 { 0x0000, 0x0000, 0x0000 }, /* R309 */
408 { 0x0000, 0x0000, 0x0000 }, /* R310 */
409 { 0x0000, 0x0000, 0x0000 }, /* R311 */
410 { 0x0000, 0x0000, 0x0000 }, /* R312 */
411 { 0x0000, 0x0000, 0x0000 }, /* R313 */
412 { 0x0000, 0x0000, 0x0000 }, /* R314 */
413 { 0x0000, 0x0000, 0x0000 }, /* R315 */
414 { 0x0000, 0x0000, 0x0000 }, /* R316 */
415 { 0x0000, 0x0000, 0x0000 }, /* R317 */
416 { 0x0000, 0x0000, 0x0000 }, /* R318 */
417 { 0x0000, 0x0000, 0x0000 }, /* R319 */
418 { 0x0000, 0x0000, 0x0000 }, /* R320 */
419 { 0x0000, 0x0000, 0x0000 }, /* R321 */
420 { 0x0000, 0x0000, 0x0000 }, /* R322 */
421 { 0x0000, 0x0000, 0x0000 }, /* R323 */
422 { 0x0000, 0x0000, 0x0000 }, /* R324 */
423 { 0x0000, 0x0000, 0x0000 }, /* R325 */
424 { 0x0000, 0x0000, 0x0000 }, /* R326 */
425 { 0x0000, 0x0000, 0x0000 }, /* R327 */
426 { 0x0000, 0x0000, 0x0000 }, /* R328 */
427 { 0x0000, 0x0000, 0x0000 }, /* R329 */
428 { 0x0000, 0x0000, 0x0000 }, /* R330 */
429 { 0x0000, 0x0000, 0x0000 }, /* R331 */
430 { 0x0000, 0x0000, 0x0000 }, /* R332 */
431 { 0x0000, 0x0000, 0x0000 }, /* R333 */
432 { 0x0000, 0x0000, 0x0000 }, /* R334 */
433 { 0x0000, 0x0000, 0x0000 }, /* R335 */
434 { 0x0000, 0x0000, 0x0000 }, /* R336 */
435 { 0x0000, 0x0000, 0x0000 }, /* R337 */
436 { 0x0000, 0x0000, 0x0000 }, /* R338 */
437 { 0x0000, 0x0000, 0x0000 }, /* R339 */
438 { 0x0000, 0x0000, 0x0000 }, /* R340 */
439 { 0x0000, 0x0000, 0x0000 }, /* R341 */
440 { 0x0000, 0x0000, 0x0000 }, /* R342 */
441 { 0x0000, 0x0000, 0x0000 }, /* R343 */
442 { 0x0000, 0x0000, 0x0000 }, /* R344 */
443 { 0x0000, 0x0000, 0x0000 }, /* R345 */
444 { 0x0000, 0x0000, 0x0000 }, /* R346 */
445 { 0x0000, 0x0000, 0x0000 }, /* R347 */
446 { 0x0000, 0x0000, 0x0000 }, /* R348 */
447 { 0x0000, 0x0000, 0x0000 }, /* R349 */
448 { 0x0000, 0x0000, 0x0000 }, /* R350 */
449 { 0x0000, 0x0000, 0x0000 }, /* R351 */
450 { 0x0000, 0x0000, 0x0000 }, /* R352 */
451 { 0x0000, 0x0000, 0x0000 }, /* R353 */
452 { 0x0000, 0x0000, 0x0000 }, /* R354 */
453 { 0x0000, 0x0000, 0x0000 }, /* R355 */
454 { 0x0000, 0x0000, 0x0000 }, /* R356 */
455 { 0x0000, 0x0000, 0x0000 }, /* R357 */
456 { 0x0000, 0x0000, 0x0000 }, /* R358 */
457 { 0x0000, 0x0000, 0x0000 }, /* R359 */
458 { 0x0000, 0x0000, 0x0000 }, /* R360 */
459 { 0x0000, 0x0000, 0x0000 }, /* R361 */
460 { 0x0000, 0x0000, 0x0000 }, /* R362 */
461 { 0x0000, 0x0000, 0x0000 }, /* R363 */
462 { 0x0000, 0x0000, 0x0000 }, /* R364 */
463 { 0x0000, 0x0000, 0x0000 }, /* R365 */
464 { 0x0000, 0x0000, 0x0000 }, /* R366 */
465 { 0x0000, 0x0000, 0x0000 }, /* R367 */
466 { 0x0000, 0x0000, 0x0000 }, /* R368 */
467 { 0x0000, 0x0000, 0x0000 }, /* R369 */
468 { 0x0000, 0x0000, 0x0000 }, /* R370 */
469 { 0x0000, 0x0000, 0x0000 }, /* R371 */
470 { 0x0000, 0x0000, 0x0000 }, /* R372 */
471 { 0x0000, 0x0000, 0x0000 }, /* R373 */
472 { 0x0000, 0x0000, 0x0000 }, /* R374 */
473 { 0x0000, 0x0000, 0x0000 }, /* R375 */
474 { 0x0000, 0x0000, 0x0000 }, /* R376 */
475 { 0x0000, 0x0000, 0x0000 }, /* R377 */
476 { 0x0000, 0x0000, 0x0000 }, /* R378 */
477 { 0x0000, 0x0000, 0x0000 }, /* R379 */
478 { 0x0000, 0x0000, 0x0000 }, /* R380 */
479 { 0x0000, 0x0000, 0x0000 }, /* R381 */
480 { 0x0000, 0x0000, 0x0000 }, /* R382 */
481 { 0x0000, 0x0000, 0x0000 }, /* R383 */
482 { 0x0000, 0x0000, 0x0000 }, /* R384 */
483 { 0x0000, 0x0000, 0x0000 }, /* R385 */
484 { 0x0000, 0x0000, 0x0000 }, /* R386 */
485 { 0x0000, 0x0000, 0x0000 }, /* R387 */
486 { 0x0000, 0x0000, 0x0000 }, /* R388 */
487 { 0x0000, 0x0000, 0x0000 }, /* R389 */
488 { 0x0000, 0x0000, 0x0000 }, /* R390 */
489 { 0x0000, 0x0000, 0x0000 }, /* R391 */
490 { 0x0000, 0x0000, 0x0000 }, /* R392 */
491 { 0x0000, 0x0000, 0x0000 }, /* R393 */
492 { 0x0000, 0x0000, 0x0000 }, /* R394 */
493 { 0x0000, 0x0000, 0x0000 }, /* R395 */
494 { 0x0000, 0x0000, 0x0000 }, /* R396 */
495 { 0x0000, 0x0000, 0x0000 }, /* R397 */
496 { 0x0000, 0x0000, 0x0000 }, /* R398 */
497 { 0x0000, 0x0000, 0x0000 }, /* R399 */
498 { 0x0000, 0x0000, 0x0000 }, /* R400 */
499 { 0x0000, 0x0000, 0x0000 }, /* R401 */
500 { 0x0000, 0x0000, 0x0000 }, /* R402 */
501 { 0x0000, 0x0000, 0x0000 }, /* R403 */
502 { 0x0000, 0x0000, 0x0000 }, /* R404 */
503 { 0x0000, 0x0000, 0x0000 }, /* R405 */
504 { 0x0000, 0x0000, 0x0000 }, /* R406 */
505 { 0x0000, 0x0000, 0x0000 }, /* R407 */
506 { 0x0000, 0x0000, 0x0000 }, /* R408 */
507 { 0x0000, 0x0000, 0x0000 }, /* R409 */
508 { 0x0000, 0x0000, 0x0000 }, /* R410 */
509 { 0x0000, 0x0000, 0x0000 }, /* R411 */
510 { 0x0000, 0x0000, 0x0000 }, /* R412 */
511 { 0x0000, 0x0000, 0x0000 }, /* R413 */
512 { 0x0000, 0x0000, 0x0000 }, /* R414 */
513 { 0x0000, 0x0000, 0x0000 }, /* R415 */
514 { 0x0000, 0x0000, 0x0000 }, /* R416 */
515 { 0x0000, 0x0000, 0x0000 }, /* R417 */
516 { 0x0000, 0x0000, 0x0000 }, /* R418 */
517 { 0x0000, 0x0000, 0x0000 }, /* R419 */
518 { 0x0000, 0x0000, 0x0000 }, /* R420 */
519 { 0x0000, 0x0000, 0x0000 }, /* R421 */
520 { 0x0000, 0x0000, 0x0000 }, /* R422 */
521 { 0x0000, 0x0000, 0x0000 }, /* R423 */
522 { 0x0000, 0x0000, 0x0000 }, /* R424 */
523 { 0x0000, 0x0000, 0x0000 }, /* R425 */
524 { 0x0000, 0x0000, 0x0000 }, /* R426 */
525 { 0x0000, 0x0000, 0x0000 }, /* R427 */
526 { 0x0000, 0x0000, 0x0000 }, /* R428 */
527 { 0x0000, 0x0000, 0x0000 }, /* R429 */
528 { 0x0000, 0x0000, 0x0000 }, /* R430 */
529 { 0x0000, 0x0000, 0x0000 }, /* R431 */
530 { 0x0000, 0x0000, 0x0000 }, /* R432 */
531 { 0x0000, 0x0000, 0x0000 }, /* R433 */
532 { 0x0000, 0x0000, 0x0000 }, /* R434 */
533 { 0x0000, 0x0000, 0x0000 }, /* R435 */
534 { 0x0000, 0x0000, 0x0000 }, /* R436 */
535 { 0x0000, 0x0000, 0x0000 }, /* R437 */
536 { 0x0000, 0x0000, 0x0000 }, /* R438 */
537 { 0x0000, 0x0000, 0x0000 }, /* R439 */
538 { 0x0000, 0x0000, 0x0000 }, /* R440 */
539 { 0x0000, 0x0000, 0x0000 }, /* R441 */
540 { 0x0000, 0x0000, 0x0000 }, /* R442 */
541 { 0x0000, 0x0000, 0x0000 }, /* R443 */
542 { 0x0000, 0x0000, 0x0000 }, /* R444 */
543 { 0x0000, 0x0000, 0x0000 }, /* R445 */
544 { 0x0000, 0x0000, 0x0000 }, /* R446 */
545 { 0x0000, 0x0000, 0x0000 }, /* R447 */
546 { 0x0000, 0x0000, 0x0000 }, /* R448 */
547 { 0x0000, 0x0000, 0x0000 }, /* R449 */
548 { 0x0000, 0x0000, 0x0000 }, /* R450 */
549 { 0x0000, 0x0000, 0x0000 }, /* R451 */
550 { 0x0000, 0x0000, 0x0000 }, /* R452 */
551 { 0x0000, 0x0000, 0x0000 }, /* R453 */
552 { 0x0000, 0x0000, 0x0000 }, /* R454 */
553 { 0x0000, 0x0000, 0x0000 }, /* R455 */
554 { 0x0000, 0x0000, 0x0000 }, /* R456 */
555 { 0x0000, 0x0000, 0x0000 }, /* R457 */
556 { 0x0000, 0x0000, 0x0000 }, /* R458 */
557 { 0x0000, 0x0000, 0x0000 }, /* R459 */
558 { 0x0000, 0x0000, 0x0000 }, /* R460 */
559 { 0x0000, 0x0000, 0x0000 }, /* R461 */
560 { 0x0000, 0x0000, 0x0000 }, /* R462 */
561 { 0x0000, 0x0000, 0x0000 }, /* R463 */
562 { 0x0000, 0x0000, 0x0000 }, /* R464 */
563 { 0x0000, 0x0000, 0x0000 }, /* R465 */
564 { 0x0000, 0x0000, 0x0000 }, /* R466 */
565 { 0x0000, 0x0000, 0x0000 }, /* R467 */
566 { 0x0000, 0x0000, 0x0000 }, /* R468 */
567 { 0x0000, 0x0000, 0x0000 }, /* R469 */
568 { 0x0000, 0x0000, 0x0000 }, /* R470 */
569 { 0x0000, 0x0000, 0x0000 }, /* R471 */
570 { 0x0000, 0x0000, 0x0000 }, /* R472 */
571 { 0x0000, 0x0000, 0x0000 }, /* R473 */
572 { 0x0000, 0x0000, 0x0000 }, /* R474 */
573 { 0x0000, 0x0000, 0x0000 }, /* R475 */
574 { 0x0000, 0x0000, 0x0000 }, /* R476 */
575 { 0x0000, 0x0000, 0x0000 }, /* R477 */
576 { 0x0000, 0x0000, 0x0000 }, /* R478 */
577 { 0x0000, 0x0000, 0x0000 }, /* R479 */
578 { 0x0000, 0x0000, 0x0000 }, /* R480 */
579 { 0x0000, 0x0000, 0x0000 }, /* R481 */
580 { 0x0000, 0x0000, 0x0000 }, /* R482 */
581 { 0x0000, 0x0000, 0x0000 }, /* R483 */
582 { 0x0000, 0x0000, 0x0000 }, /* R484 */
583 { 0x0000, 0x0000, 0x0000 }, /* R485 */
584 { 0x0000, 0x0000, 0x0000 }, /* R486 */
585 { 0x0000, 0x0000, 0x0000 }, /* R487 */
586 { 0x0000, 0x0000, 0x0000 }, /* R488 */
587 { 0x0000, 0x0000, 0x0000 }, /* R489 */
588 { 0x0000, 0x0000, 0x0000 }, /* R490 */
589 { 0x0000, 0x0000, 0x0000 }, /* R491 */
590 { 0x0000, 0x0000, 0x0000 }, /* R492 */
591 { 0x0000, 0x0000, 0x0000 }, /* R493 */
592 { 0x0000, 0x0000, 0x0000 }, /* R494 */
593 { 0x0000, 0x0000, 0x0000 }, /* R495 */
594 { 0x0000, 0x0000, 0x0000 }, /* R496 */
595 { 0x0000, 0x0000, 0x0000 }, /* R497 */
596 { 0x0000, 0x0000, 0x0000 }, /* R498 */
597 { 0x0000, 0x0000, 0x0000 }, /* R499 */
598 { 0x0000, 0x0000, 0x0000 }, /* R500 */
599 { 0x0000, 0x0000, 0x0000 }, /* R501 */
600 { 0x0000, 0x0000, 0x0000 }, /* R502 */
601 { 0x0000, 0x0000, 0x0000 }, /* R503 */
602 { 0x0000, 0x0000, 0x0000 }, /* R504 */
603 { 0x0000, 0x0000, 0x0000 }, /* R505 */
604 { 0x0000, 0x0000, 0x0000 }, /* R506 */
605 { 0x0000, 0x0000, 0x0000 }, /* R507 */
606 { 0x0000, 0x0000, 0x0000 }, /* R508 */
607 { 0x0000, 0x0000, 0x0000 }, /* R509 */
608 { 0x0000, 0x0000, 0x0000 }, /* R510 */
609 { 0x0000, 0x0000, 0x0000 }, /* R511 */
610 { 0x001F, 0x001F, 0x0000 }, /* R512 - AIF1 Clocking (1) */
611 { 0x003F, 0x003F, 0x0000 }, /* R513 - AIF1 Clocking (2) */
612 { 0x0000, 0x0000, 0x0000 }, /* R514 */
613 { 0x0000, 0x0000, 0x0000 }, /* R515 */
614 { 0x001F, 0x001F, 0x0000 }, /* R516 - AIF2 Clocking (1) */
615 { 0x003F, 0x003F, 0x0000 }, /* R517 - AIF2 Clocking (2) */
616 { 0x0000, 0x0000, 0x0000 }, /* R518 */
617 { 0x0000, 0x0000, 0x0000 }, /* R519 */
618 { 0x001F, 0x001F, 0x0000 }, /* R520 - Clocking (1) */
619 { 0x0777, 0x0777, 0x0000 }, /* R521 - Clocking (2) */
620 { 0x0000, 0x0000, 0x0000 }, /* R522 */
621 { 0x0000, 0x0000, 0x0000 }, /* R523 */
622 { 0x0000, 0x0000, 0x0000 }, /* R524 */
623 { 0x0000, 0x0000, 0x0000 }, /* R525 */
624 { 0x0000, 0x0000, 0x0000 }, /* R526 */
625 { 0x0000, 0x0000, 0x0000 }, /* R527 */
626 { 0x00FF, 0x00FF, 0x0000 }, /* R528 - AIF1 Rate */
627 { 0x00FF, 0x00FF, 0x0000 }, /* R529 - AIF2 Rate */
628 { 0x000F, 0x0000, 0x0000 }, /* R530 - Rate Status */
629 { 0x0000, 0x0000, 0x0000 }, /* R531 */
630 { 0x0000, 0x0000, 0x0000 }, /* R532 */
631 { 0x0000, 0x0000, 0x0000 }, /* R533 */
632 { 0x0000, 0x0000, 0x0000 }, /* R534 */
633 { 0x0000, 0x0000, 0x0000 }, /* R535 */
634 { 0x0000, 0x0000, 0x0000 }, /* R536 */
635 { 0x0000, 0x0000, 0x0000 }, /* R537 */
636 { 0x0000, 0x0000, 0x0000 }, /* R538 */
637 { 0x0000, 0x0000, 0x0000 }, /* R539 */
638 { 0x0000, 0x0000, 0x0000 }, /* R540 */
639 { 0x0000, 0x0000, 0x0000 }, /* R541 */
640 { 0x0000, 0x0000, 0x0000 }, /* R542 */
641 { 0x0000, 0x0000, 0x0000 }, /* R543 */
642 { 0x0007, 0x0007, 0x0000 }, /* R544 - FLL1 Control (1) */
643 { 0x3F77, 0x3F77, 0x0000 }, /* R545 - FLL1 Control (2) */
644 { 0xFFFF, 0xFFFF, 0x0000 }, /* R546 - FLL1 Control (3) */
645 { 0x7FEF, 0x7FEF, 0x0000 }, /* R547 - FLL1 Control (4) */
646 { 0x1FDB, 0x1FDB, 0x0000 }, /* R548 - FLL1 Control (5) */
647 { 0x0000, 0x0000, 0x0000 }, /* R549 */
648 { 0x0000, 0x0000, 0x0000 }, /* R550 */
649 { 0x0000, 0x0000, 0x0000 }, /* R551 */
650 { 0x0000, 0x0000, 0x0000 }, /* R552 */
651 { 0x0000, 0x0000, 0x0000 }, /* R553 */
652 { 0x0000, 0x0000, 0x0000 }, /* R554 */
653 { 0x0000, 0x0000, 0x0000 }, /* R555 */
654 { 0x0000, 0x0000, 0x0000 }, /* R556 */
655 { 0x0000, 0x0000, 0x0000 }, /* R557 */
656 { 0x0000, 0x0000, 0x0000 }, /* R558 */
657 { 0x0000, 0x0000, 0x0000 }, /* R559 */
658 { 0x0000, 0x0000, 0x0000 }, /* R560 */
659 { 0x0000, 0x0000, 0x0000 }, /* R561 */
660 { 0x0000, 0x0000, 0x0000 }, /* R562 */
661 { 0x0000, 0x0000, 0x0000 }, /* R563 */
662 { 0x0000, 0x0000, 0x0000 }, /* R564 */
663 { 0x0000, 0x0000, 0x0000 }, /* R565 */
664 { 0x0000, 0x0000, 0x0000 }, /* R566 */
665 { 0x0000, 0x0000, 0x0000 }, /* R567 */
666 { 0x0000, 0x0000, 0x0000 }, /* R568 */
667 { 0x0000, 0x0000, 0x0000 }, /* R569 */
668 { 0x0000, 0x0000, 0x0000 }, /* R570 */
669 { 0x0000, 0x0000, 0x0000 }, /* R571 */
670 { 0x0000, 0x0000, 0x0000 }, /* R572 */
671 { 0x0000, 0x0000, 0x0000 }, /* R573 */
672 { 0x0000, 0x0000, 0x0000 }, /* R574 */
673 { 0x0000, 0x0000, 0x0000 }, /* R575 */
674 { 0x0007, 0x0007, 0x0000 }, /* R576 - FLL2 Control (1) */
675 { 0x3F77, 0x3F77, 0x0000 }, /* R577 - FLL2 Control (2) */
676 { 0xFFFF, 0xFFFF, 0x0000 }, /* R578 - FLL2 Control (3) */
677 { 0x7FEF, 0x7FEF, 0x0000 }, /* R579 - FLL2 Control (4) */
678 { 0x1FDB, 0x1FDB, 0x0000 }, /* R580 - FLL2 Control (5) */
679 { 0x0000, 0x0000, 0x0000 }, /* R581 */
680 { 0x0000, 0x0000, 0x0000 }, /* R582 */
681 { 0x0000, 0x0000, 0x0000 }, /* R583 */
682 { 0x0000, 0x0000, 0x0000 }, /* R584 */
683 { 0x0000, 0x0000, 0x0000 }, /* R585 */
684 { 0x0000, 0x0000, 0x0000 }, /* R586 */
685 { 0x0000, 0x0000, 0x0000 }, /* R587 */
686 { 0x0000, 0x0000, 0x0000 }, /* R588 */
687 { 0x0000, 0x0000, 0x0000 }, /* R589 */
688 { 0x0000, 0x0000, 0x0000 }, /* R590 */
689 { 0x0000, 0x0000, 0x0000 }, /* R591 */
690 { 0x0000, 0x0000, 0x0000 }, /* R592 */
691 { 0x0000, 0x0000, 0x0000 }, /* R593 */
692 { 0x0000, 0x0000, 0x0000 }, /* R594 */
693 { 0x0000, 0x0000, 0x0000 }, /* R595 */
694 { 0x0000, 0x0000, 0x0000 }, /* R596 */
695 { 0x0000, 0x0000, 0x0000 }, /* R597 */
696 { 0x0000, 0x0000, 0x0000 }, /* R598 */
697 { 0x0000, 0x0000, 0x0000 }, /* R599 */
698 { 0x0000, 0x0000, 0x0000 }, /* R600 */
699 { 0x0000, 0x0000, 0x0000 }, /* R601 */
700 { 0x0000, 0x0000, 0x0000 }, /* R602 */
701 { 0x0000, 0x0000, 0x0000 }, /* R603 */
702 { 0x0000, 0x0000, 0x0000 }, /* R604 */
703 { 0x0000, 0x0000, 0x0000 }, /* R605 */
704 { 0x0000, 0x0000, 0x0000 }, /* R606 */
705 { 0x0000, 0x0000, 0x0000 }, /* R607 */
706 { 0x0000, 0x0000, 0x0000 }, /* R608 */
707 { 0x0000, 0x0000, 0x0000 }, /* R609 */
708 { 0x0000, 0x0000, 0x0000 }, /* R610 */
709 { 0x0000, 0x0000, 0x0000 }, /* R611 */
710 { 0x0000, 0x0000, 0x0000 }, /* R612 */
711 { 0x0000, 0x0000, 0x0000 }, /* R613 */
712 { 0x0000, 0x0000, 0x0000 }, /* R614 */
713 { 0x0000, 0x0000, 0x0000 }, /* R615 */
714 { 0x0000, 0x0000, 0x0000 }, /* R616 */
715 { 0x0000, 0x0000, 0x0000 }, /* R617 */
716 { 0x0000, 0x0000, 0x0000 }, /* R618 */
717 { 0x0000, 0x0000, 0x0000 }, /* R619 */
718 { 0x0000, 0x0000, 0x0000 }, /* R620 */
719 { 0x0000, 0x0000, 0x0000 }, /* R621 */
720 { 0x0000, 0x0000, 0x0000 }, /* R622 */
721 { 0x0000, 0x0000, 0x0000 }, /* R623 */
722 { 0x0000, 0x0000, 0x0000 }, /* R624 */
723 { 0x0000, 0x0000, 0x0000 }, /* R625 */
724 { 0x0000, 0x0000, 0x0000 }, /* R626 */
725 { 0x0000, 0x0000, 0x0000 }, /* R627 */
726 { 0x0000, 0x0000, 0x0000 }, /* R628 */
727 { 0x0000, 0x0000, 0x0000 }, /* R629 */
728 { 0x0000, 0x0000, 0x0000 }, /* R630 */
729 { 0x0000, 0x0000, 0x0000 }, /* R631 */
730 { 0x0000, 0x0000, 0x0000 }, /* R632 */
731 { 0x0000, 0x0000, 0x0000 }, /* R633 */
732 { 0x0000, 0x0000, 0x0000 }, /* R634 */
733 { 0x0000, 0x0000, 0x0000 }, /* R635 */
734 { 0x0000, 0x0000, 0x0000 }, /* R636 */
735 { 0x0000, 0x0000, 0x0000 }, /* R637 */
736 { 0x0000, 0x0000, 0x0000 }, /* R638 */
737 { 0x0000, 0x0000, 0x0000 }, /* R639 */
738 { 0x0000, 0x0000, 0x0000 }, /* R640 */
739 { 0x0000, 0x0000, 0x0000 }, /* R641 */
740 { 0x0000, 0x0000, 0x0000 }, /* R642 */
741 { 0x0000, 0x0000, 0x0000 }, /* R643 */
742 { 0x0000, 0x0000, 0x0000 }, /* R644 */
743 { 0x0000, 0x0000, 0x0000 }, /* R645 */
744 { 0x0000, 0x0000, 0x0000 }, /* R646 */
745 { 0x0000, 0x0000, 0x0000 }, /* R647 */
746 { 0x0000, 0x0000, 0x0000 }, /* R648 */
747 { 0x0000, 0x0000, 0x0000 }, /* R649 */
748 { 0x0000, 0x0000, 0x0000 }, /* R650 */
749 { 0x0000, 0x0000, 0x0000 }, /* R651 */
750 { 0x0000, 0x0000, 0x0000 }, /* R652 */
751 { 0x0000, 0x0000, 0x0000 }, /* R653 */
752 { 0x0000, 0x0000, 0x0000 }, /* R654 */
753 { 0x0000, 0x0000, 0x0000 }, /* R655 */
754 { 0x0000, 0x0000, 0x0000 }, /* R656 */
755 { 0x0000, 0x0000, 0x0000 }, /* R657 */
756 { 0x0000, 0x0000, 0x0000 }, /* R658 */
757 { 0x0000, 0x0000, 0x0000 }, /* R659 */
758 { 0x0000, 0x0000, 0x0000 }, /* R660 */
759 { 0x0000, 0x0000, 0x0000 }, /* R661 */
760 { 0x0000, 0x0000, 0x0000 }, /* R662 */
761 { 0x0000, 0x0000, 0x0000 }, /* R663 */
762 { 0x0000, 0x0000, 0x0000 }, /* R664 */
763 { 0x0000, 0x0000, 0x0000 }, /* R665 */
764 { 0x0000, 0x0000, 0x0000 }, /* R666 */
765 { 0x0000, 0x0000, 0x0000 }, /* R667 */
766 { 0x0000, 0x0000, 0x0000 }, /* R668 */
767 { 0x0000, 0x0000, 0x0000 }, /* R669 */
768 { 0x0000, 0x0000, 0x0000 }, /* R670 */
769 { 0x0000, 0x0000, 0x0000 }, /* R671 */
770 { 0x0000, 0x0000, 0x0000 }, /* R672 */
771 { 0x0000, 0x0000, 0x0000 }, /* R673 */
772 { 0x0000, 0x0000, 0x0000 }, /* R674 */
773 { 0x0000, 0x0000, 0x0000 }, /* R675 */
774 { 0x0000, 0x0000, 0x0000 }, /* R676 */
775 { 0x0000, 0x0000, 0x0000 }, /* R677 */
776 { 0x0000, 0x0000, 0x0000 }, /* R678 */
777 { 0x0000, 0x0000, 0x0000 }, /* R679 */
778 { 0x0000, 0x0000, 0x0000 }, /* R680 */
779 { 0x0000, 0x0000, 0x0000 }, /* R681 */
780 { 0x0000, 0x0000, 0x0000 }, /* R682 */
781 { 0x0000, 0x0000, 0x0000 }, /* R683 */
782 { 0x0000, 0x0000, 0x0000 }, /* R684 */
783 { 0x0000, 0x0000, 0x0000 }, /* R685 */
784 { 0x0000, 0x0000, 0x0000 }, /* R686 */
785 { 0x0000, 0x0000, 0x0000 }, /* R687 */
786 { 0x0000, 0x0000, 0x0000 }, /* R688 */
787 { 0x0000, 0x0000, 0x0000 }, /* R689 */
788 { 0x0000, 0x0000, 0x0000 }, /* R690 */
789 { 0x0000, 0x0000, 0x0000 }, /* R691 */
790 { 0x0000, 0x0000, 0x0000 }, /* R692 */
791 { 0x0000, 0x0000, 0x0000 }, /* R693 */
792 { 0x0000, 0x0000, 0x0000 }, /* R694 */
793 { 0x0000, 0x0000, 0x0000 }, /* R695 */
794 { 0x0000, 0x0000, 0x0000 }, /* R696 */
795 { 0x0000, 0x0000, 0x0000 }, /* R697 */
796 { 0x0000, 0x0000, 0x0000 }, /* R698 */
797 { 0x0000, 0x0000, 0x0000 }, /* R699 */
798 { 0x0000, 0x0000, 0x0000 }, /* R700 */
799 { 0x0000, 0x0000, 0x0000 }, /* R701 */
800 { 0x0000, 0x0000, 0x0000 }, /* R702 */
801 { 0x0000, 0x0000, 0x0000 }, /* R703 */
802 { 0x0000, 0x0000, 0x0000 }, /* R704 */
803 { 0x0000, 0x0000, 0x0000 }, /* R705 */
804 { 0x0000, 0x0000, 0x0000 }, /* R706 */
805 { 0x0000, 0x0000, 0x0000 }, /* R707 */
806 { 0x0000, 0x0000, 0x0000 }, /* R708 */
807 { 0x0000, 0x0000, 0x0000 }, /* R709 */
808 { 0x0000, 0x0000, 0x0000 }, /* R710 */
809 { 0x0000, 0x0000, 0x0000 }, /* R711 */
810 { 0x0000, 0x0000, 0x0000 }, /* R712 */
811 { 0x0000, 0x0000, 0x0000 }, /* R713 */
812 { 0x0000, 0x0000, 0x0000 }, /* R714 */
813 { 0x0000, 0x0000, 0x0000 }, /* R715 */
814 { 0x0000, 0x0000, 0x0000 }, /* R716 */
815 { 0x0000, 0x0000, 0x0000 }, /* R717 */
816 { 0x0000, 0x0000, 0x0000 }, /* R718 */
817 { 0x0000, 0x0000, 0x0000 }, /* R719 */
818 { 0x0000, 0x0000, 0x0000 }, /* R720 */
819 { 0x0000, 0x0000, 0x0000 }, /* R721 */
820 { 0x0000, 0x0000, 0x0000 }, /* R722 */
821 { 0x0000, 0x0000, 0x0000 }, /* R723 */
822 { 0x0000, 0x0000, 0x0000 }, /* R724 */
823 { 0x0000, 0x0000, 0x0000 }, /* R725 */
824 { 0x0000, 0x0000, 0x0000 }, /* R726 */
825 { 0x0000, 0x0000, 0x0000 }, /* R727 */
826 { 0x0000, 0x0000, 0x0000 }, /* R728 */
827 { 0x0000, 0x0000, 0x0000 }, /* R729 */
828 { 0x0000, 0x0000, 0x0000 }, /* R730 */
829 { 0x0000, 0x0000, 0x0000 }, /* R731 */
830 { 0x0000, 0x0000, 0x0000 }, /* R732 */
831 { 0x0000, 0x0000, 0x0000 }, /* R733 */
832 { 0x0000, 0x0000, 0x0000 }, /* R734 */
833 { 0x0000, 0x0000, 0x0000 }, /* R735 */
834 { 0x0000, 0x0000, 0x0000 }, /* R736 */
835 { 0x0000, 0x0000, 0x0000 }, /* R737 */
836 { 0x0000, 0x0000, 0x0000 }, /* R738 */
837 { 0x0000, 0x0000, 0x0000 }, /* R739 */
838 { 0x0000, 0x0000, 0x0000 }, /* R740 */
839 { 0x0000, 0x0000, 0x0000 }, /* R741 */
840 { 0x0000, 0x0000, 0x0000 }, /* R742 */
841 { 0x0000, 0x0000, 0x0000 }, /* R743 */
842 { 0x0000, 0x0000, 0x0000 }, /* R744 */
843 { 0x0000, 0x0000, 0x0000 }, /* R745 */
844 { 0x0000, 0x0000, 0x0000 }, /* R746 */
845 { 0x0000, 0x0000, 0x0000 }, /* R747 */
846 { 0x0000, 0x0000, 0x0000 }, /* R748 */
847 { 0x0000, 0x0000, 0x0000 }, /* R749 */
848 { 0x0000, 0x0000, 0x0000 }, /* R750 */
849 { 0x0000, 0x0000, 0x0000 }, /* R751 */
850 { 0x0000, 0x0000, 0x0000 }, /* R752 */
851 { 0x0000, 0x0000, 0x0000 }, /* R753 */
852 { 0x0000, 0x0000, 0x0000 }, /* R754 */
853 { 0x0000, 0x0000, 0x0000 }, /* R755 */
854 { 0x0000, 0x0000, 0x0000 }, /* R756 */
855 { 0x0000, 0x0000, 0x0000 }, /* R757 */
856 { 0x0000, 0x0000, 0x0000 }, /* R758 */
857 { 0x0000, 0x0000, 0x0000 }, /* R759 */
858 { 0x0000, 0x0000, 0x0000 }, /* R760 */
859 { 0x0000, 0x0000, 0x0000 }, /* R761 */
860 { 0x0000, 0x0000, 0x0000 }, /* R762 */
861 { 0x0000, 0x0000, 0x0000 }, /* R763 */
862 { 0x0000, 0x0000, 0x0000 }, /* R764 */
863 { 0x0000, 0x0000, 0x0000 }, /* R765 */
864 { 0x0000, 0x0000, 0x0000 }, /* R766 */
865 { 0x0000, 0x0000, 0x0000 }, /* R767 */
866 { 0xE1F8, 0xE1F8, 0x0000 }, /* R768 - AIF1 Control (1) */
867 { 0xCD1F, 0xCD1F, 0x0000 }, /* R769 - AIF1 Control (2) */
868 { 0xF000, 0xF000, 0x0000 }, /* R770 - AIF1 Master/Slave */
869 { 0x01F0, 0x01F0, 0x0000 }, /* R771 - AIF1 BCLK */
870 { 0x0FFF, 0x0FFF, 0x0000 }, /* R772 - AIF1ADC LRCLK */
871 { 0x0FFF, 0x0FFF, 0x0000 }, /* R773 - AIF1DAC LRCLK */
872 { 0x0003, 0x0003, 0x0000 }, /* R774 - AIF1DAC Data */
873 { 0x0003, 0x0003, 0x0000 }, /* R775 - AIF1ADC Data */
874 { 0x0000, 0x0000, 0x0000 }, /* R776 */
875 { 0x0000, 0x0000, 0x0000 }, /* R777 */
876 { 0x0000, 0x0000, 0x0000 }, /* R778 */
877 { 0x0000, 0x0000, 0x0000 }, /* R779 */
878 { 0x0000, 0x0000, 0x0000 }, /* R780 */
879 { 0x0000, 0x0000, 0x0000 }, /* R781 */
880 { 0x0000, 0x0000, 0x0000 }, /* R782 */
881 { 0x0000, 0x0000, 0x0000 }, /* R783 */
882 { 0xF1F8, 0xF1F8, 0x0000 }, /* R784 - AIF2 Control (1) */
883 { 0xFD1F, 0xFD1F, 0x0000 }, /* R785 - AIF2 Control (2) */
884 { 0xF000, 0xF000, 0x0000 }, /* R786 - AIF2 Master/Slave */
885 { 0x01F0, 0x01F0, 0x0000 }, /* R787 - AIF2 BCLK */
886 { 0x0FFF, 0x0FFF, 0x0000 }, /* R788 - AIF2ADC LRCLK */
887 { 0x0FFF, 0x0FFF, 0x0000 }, /* R789 - AIF2DAC LRCLK */
888 { 0x0003, 0x0003, 0x0000 }, /* R790 - AIF2DAC Data */
889 { 0x0003, 0x0003, 0x0000 }, /* R791 - AIF2ADC Data */
890 { 0x0000, 0x0000, 0x0000 }, /* R792 */
891 { 0x0000, 0x0000, 0x0000 }, /* R793 */
892 { 0x0000, 0x0000, 0x0000 }, /* R794 */
893 { 0x0000, 0x0000, 0x0000 }, /* R795 */
894 { 0x0000, 0x0000, 0x0000 }, /* R796 */
895 { 0x0000, 0x0000, 0x0000 }, /* R797 */
896 { 0x0000, 0x0000, 0x0000 }, /* R798 */
897 { 0x0000, 0x0000, 0x0000 }, /* R799 */
898 { 0x0000, 0x0000, 0x0000 }, /* R800 */
899 { 0x0000, 0x0000, 0x0000 }, /* R801 */
900 { 0x0000, 0x0000, 0x0000 }, /* R802 */
901 { 0x0000, 0x0000, 0x0000 }, /* R803 */
902 { 0x0000, 0x0000, 0x0000 }, /* R804 */
903 { 0x0000, 0x0000, 0x0000 }, /* R805 */
904 { 0x0000, 0x0000, 0x0000 }, /* R806 */
905 { 0x0000, 0x0000, 0x0000 }, /* R807 */
906 { 0x0000, 0x0000, 0x0000 }, /* R808 */
907 { 0x0000, 0x0000, 0x0000 }, /* R809 */
908 { 0x0000, 0x0000, 0x0000 }, /* R810 */
909 { 0x0000, 0x0000, 0x0000 }, /* R811 */
910 { 0x0000, 0x0000, 0x0000 }, /* R812 */
911 { 0x0000, 0x0000, 0x0000 }, /* R813 */
912 { 0x0000, 0x0000, 0x0000 }, /* R814 */
913 { 0x0000, 0x0000, 0x0000 }, /* R815 */
914 { 0x0000, 0x0000, 0x0000 }, /* R816 */
915 { 0x0000, 0x0000, 0x0000 }, /* R817 */
916 { 0x0000, 0x0000, 0x0000 }, /* R818 */
917 { 0x0000, 0x0000, 0x0000 }, /* R819 */
918 { 0x0000, 0x0000, 0x0000 }, /* R820 */
919 { 0x0000, 0x0000, 0x0000 }, /* R821 */
920 { 0x0000, 0x0000, 0x0000 }, /* R822 */
921 { 0x0000, 0x0000, 0x0000 }, /* R823 */
922 { 0x0000, 0x0000, 0x0000 }, /* R824 */
923 { 0x0000, 0x0000, 0x0000 }, /* R825 */
924 { 0x0000, 0x0000, 0x0000 }, /* R826 */
925 { 0x0000, 0x0000, 0x0000 }, /* R827 */
926 { 0x0000, 0x0000, 0x0000 }, /* R828 */
927 { 0x0000, 0x0000, 0x0000 }, /* R829 */
928 { 0x0000, 0x0000, 0x0000 }, /* R830 */
929 { 0x0000, 0x0000, 0x0000 }, /* R831 */
930 { 0x0000, 0x0000, 0x0000 }, /* R832 */
931 { 0x0000, 0x0000, 0x0000 }, /* R833 */
932 { 0x0000, 0x0000, 0x0000 }, /* R834 */
933 { 0x0000, 0x0000, 0x0000 }, /* R835 */
934 { 0x0000, 0x0000, 0x0000 }, /* R836 */
935 { 0x0000, 0x0000, 0x0000 }, /* R837 */
936 { 0x0000, 0x0000, 0x0000 }, /* R838 */
937 { 0x0000, 0x0000, 0x0000 }, /* R839 */
938 { 0x0000, 0x0000, 0x0000 }, /* R840 */
939 { 0x0000, 0x0000, 0x0000 }, /* R841 */
940 { 0x0000, 0x0000, 0x0000 }, /* R842 */
941 { 0x0000, 0x0000, 0x0000 }, /* R843 */
942 { 0x0000, 0x0000, 0x0000 }, /* R844 */
943 { 0x0000, 0x0000, 0x0000 }, /* R845 */
944 { 0x0000, 0x0000, 0x0000 }, /* R846 */
945 { 0x0000, 0x0000, 0x0000 }, /* R847 */
946 { 0x0000, 0x0000, 0x0000 }, /* R848 */
947 { 0x0000, 0x0000, 0x0000 }, /* R849 */
948 { 0x0000, 0x0000, 0x0000 }, /* R850 */
949 { 0x0000, 0x0000, 0x0000 }, /* R851 */
950 { 0x0000, 0x0000, 0x0000 }, /* R852 */
951 { 0x0000, 0x0000, 0x0000 }, /* R853 */
952 { 0x0000, 0x0000, 0x0000 }, /* R854 */
953 { 0x0000, 0x0000, 0x0000 }, /* R855 */
954 { 0x0000, 0x0000, 0x0000 }, /* R856 */
955 { 0x0000, 0x0000, 0x0000 }, /* R857 */
956 { 0x0000, 0x0000, 0x0000 }, /* R858 */
957 { 0x0000, 0x0000, 0x0000 }, /* R859 */
958 { 0x0000, 0x0000, 0x0000 }, /* R860 */
959 { 0x0000, 0x0000, 0x0000 }, /* R861 */
960 { 0x0000, 0x0000, 0x0000 }, /* R862 */
961 { 0x0000, 0x0000, 0x0000 }, /* R863 */
962 { 0x0000, 0x0000, 0x0000 }, /* R864 */
963 { 0x0000, 0x0000, 0x0000 }, /* R865 */
964 { 0x0000, 0x0000, 0x0000 }, /* R866 */
965 { 0x0000, 0x0000, 0x0000 }, /* R867 */
966 { 0x0000, 0x0000, 0x0000 }, /* R868 */
967 { 0x0000, 0x0000, 0x0000 }, /* R869 */
968 { 0x0000, 0x0000, 0x0000 }, /* R870 */
969 { 0x0000, 0x0000, 0x0000 }, /* R871 */
970 { 0x0000, 0x0000, 0x0000 }, /* R872 */
971 { 0x0000, 0x0000, 0x0000 }, /* R873 */
972 { 0x0000, 0x0000, 0x0000 }, /* R874 */
973 { 0x0000, 0x0000, 0x0000 }, /* R875 */
974 { 0x0000, 0x0000, 0x0000 }, /* R876 */
975 { 0x0000, 0x0000, 0x0000 }, /* R877 */
976 { 0x0000, 0x0000, 0x0000 }, /* R878 */
977 { 0x0000, 0x0000, 0x0000 }, /* R879 */
978 { 0x0000, 0x0000, 0x0000 }, /* R880 */
979 { 0x0000, 0x0000, 0x0000 }, /* R881 */
980 { 0x0000, 0x0000, 0x0000 }, /* R882 */
981 { 0x0000, 0x0000, 0x0000 }, /* R883 */
982 { 0x0000, 0x0000, 0x0000 }, /* R884 */
983 { 0x0000, 0x0000, 0x0000 }, /* R885 */
984 { 0x0000, 0x0000, 0x0000 }, /* R886 */
985 { 0x0000, 0x0000, 0x0000 }, /* R887 */
986 { 0x0000, 0x0000, 0x0000 }, /* R888 */
987 { 0x0000, 0x0000, 0x0000 }, /* R889 */
988 { 0x0000, 0x0000, 0x0000 }, /* R890 */
989 { 0x0000, 0x0000, 0x0000 }, /* R891 */
990 { 0x0000, 0x0000, 0x0000 }, /* R892 */
991 { 0x0000, 0x0000, 0x0000 }, /* R893 */
992 { 0x0000, 0x0000, 0x0000 }, /* R894 */
993 { 0x0000, 0x0000, 0x0000 }, /* R895 */
994 { 0x0000, 0x0000, 0x0000 }, /* R896 */
995 { 0x0000, 0x0000, 0x0000 }, /* R897 */
996 { 0x0000, 0x0000, 0x0000 }, /* R898 */
997 { 0x0000, 0x0000, 0x0000 }, /* R899 */
998 { 0x0000, 0x0000, 0x0000 }, /* R900 */
999 { 0x0000, 0x0000, 0x0000 }, /* R901 */
1000 { 0x0000, 0x0000, 0x0000 }, /* R902 */
1001 { 0x0000, 0x0000, 0x0000 }, /* R903 */
1002 { 0x0000, 0x0000, 0x0000 }, /* R904 */
1003 { 0x0000, 0x0000, 0x0000 }, /* R905 */
1004 { 0x0000, 0x0000, 0x0000 }, /* R906 */
1005 { 0x0000, 0x0000, 0x0000 }, /* R907 */
1006 { 0x0000, 0x0000, 0x0000 }, /* R908 */
1007 { 0x0000, 0x0000, 0x0000 }, /* R909 */
1008 { 0x0000, 0x0000, 0x0000 }, /* R910 */
1009 { 0x0000, 0x0000, 0x0000 }, /* R911 */
1010 { 0x0000, 0x0000, 0x0000 }, /* R912 */
1011 { 0x0000, 0x0000, 0x0000 }, /* R913 */
1012 { 0x0000, 0x0000, 0x0000 }, /* R914 */
1013 { 0x0000, 0x0000, 0x0000 }, /* R915 */
1014 { 0x0000, 0x0000, 0x0000 }, /* R916 */
1015 { 0x0000, 0x0000, 0x0000 }, /* R917 */
1016 { 0x0000, 0x0000, 0x0000 }, /* R918 */
1017 { 0x0000, 0x0000, 0x0000 }, /* R919 */
1018 { 0x0000, 0x0000, 0x0000 }, /* R920 */
1019 { 0x0000, 0x0000, 0x0000 }, /* R921 */
1020 { 0x0000, 0x0000, 0x0000 }, /* R922 */
1021 { 0x0000, 0x0000, 0x0000 }, /* R923 */
1022 { 0x0000, 0x0000, 0x0000 }, /* R924 */
1023 { 0x0000, 0x0000, 0x0000 }, /* R925 */
1024 { 0x0000, 0x0000, 0x0000 }, /* R926 */
1025 { 0x0000, 0x0000, 0x0000 }, /* R927 */
1026 { 0x0000, 0x0000, 0x0000 }, /* R928 */
1027 { 0x0000, 0x0000, 0x0000 }, /* R929 */
1028 { 0x0000, 0x0000, 0x0000 }, /* R930 */
1029 { 0x0000, 0x0000, 0x0000 }, /* R931 */
1030 { 0x0000, 0x0000, 0x0000 }, /* R932 */
1031 { 0x0000, 0x0000, 0x0000 }, /* R933 */
1032 { 0x0000, 0x0000, 0x0000 }, /* R934 */
1033 { 0x0000, 0x0000, 0x0000 }, /* R935 */
1034 { 0x0000, 0x0000, 0x0000 }, /* R936 */
1035 { 0x0000, 0x0000, 0x0000 }, /* R937 */
1036 { 0x0000, 0x0000, 0x0000 }, /* R938 */
1037 { 0x0000, 0x0000, 0x0000 }, /* R939 */
1038 { 0x0000, 0x0000, 0x0000 }, /* R940 */
1039 { 0x0000, 0x0000, 0x0000 }, /* R941 */
1040 { 0x0000, 0x0000, 0x0000 }, /* R942 */
1041 { 0x0000, 0x0000, 0x0000 }, /* R943 */
1042 { 0x0000, 0x0000, 0x0000 }, /* R944 */
1043 { 0x0000, 0x0000, 0x0000 }, /* R945 */
1044 { 0x0000, 0x0000, 0x0000 }, /* R946 */
1045 { 0x0000, 0x0000, 0x0000 }, /* R947 */
1046 { 0x0000, 0x0000, 0x0000 }, /* R948 */
1047 { 0x0000, 0x0000, 0x0000 }, /* R949 */
1048 { 0x0000, 0x0000, 0x0000 }, /* R950 */
1049 { 0x0000, 0x0000, 0x0000 }, /* R951 */
1050 { 0x0000, 0x0000, 0x0000 }, /* R952 */
1051 { 0x0000, 0x0000, 0x0000 }, /* R953 */
1052 { 0x0000, 0x0000, 0x0000 }, /* R954 */
1053 { 0x0000, 0x0000, 0x0000 }, /* R955 */
1054 { 0x0000, 0x0000, 0x0000 }, /* R956 */
1055 { 0x0000, 0x0000, 0x0000 }, /* R957 */
1056 { 0x0000, 0x0000, 0x0000 }, /* R958 */
1057 { 0x0000, 0x0000, 0x0000 }, /* R959 */
1058 { 0x0000, 0x0000, 0x0000 }, /* R960 */
1059 { 0x0000, 0x0000, 0x0000 }, /* R961 */
1060 { 0x0000, 0x0000, 0x0000 }, /* R962 */
1061 { 0x0000, 0x0000, 0x0000 }, /* R963 */
1062 { 0x0000, 0x0000, 0x0000 }, /* R964 */
1063 { 0x0000, 0x0000, 0x0000 }, /* R965 */
1064 { 0x0000, 0x0000, 0x0000 }, /* R966 */
1065 { 0x0000, 0x0000, 0x0000 }, /* R967 */
1066 { 0x0000, 0x0000, 0x0000 }, /* R968 */
1067 { 0x0000, 0x0000, 0x0000 }, /* R969 */
1068 { 0x0000, 0x0000, 0x0000 }, /* R970 */
1069 { 0x0000, 0x0000, 0x0000 }, /* R971 */
1070 { 0x0000, 0x0000, 0x0000 }, /* R972 */
1071 { 0x0000, 0x0000, 0x0000 }, /* R973 */
1072 { 0x0000, 0x0000, 0x0000 }, /* R974 */
1073 { 0x0000, 0x0000, 0x0000 }, /* R975 */
1074 { 0x0000, 0x0000, 0x0000 }, /* R976 */
1075 { 0x0000, 0x0000, 0x0000 }, /* R977 */
1076 { 0x0000, 0x0000, 0x0000 }, /* R978 */
1077 { 0x0000, 0x0000, 0x0000 }, /* R979 */
1078 { 0x0000, 0x0000, 0x0000 }, /* R980 */
1079 { 0x0000, 0x0000, 0x0000 }, /* R981 */
1080 { 0x0000, 0x0000, 0x0000 }, /* R982 */
1081 { 0x0000, 0x0000, 0x0000 }, /* R983 */
1082 { 0x0000, 0x0000, 0x0000 }, /* R984 */
1083 { 0x0000, 0x0000, 0x0000 }, /* R985 */
1084 { 0x0000, 0x0000, 0x0000 }, /* R986 */
1085 { 0x0000, 0x0000, 0x0000 }, /* R987 */
1086 { 0x0000, 0x0000, 0x0000 }, /* R988 */
1087 { 0x0000, 0x0000, 0x0000 }, /* R989 */
1088 { 0x0000, 0x0000, 0x0000 }, /* R990 */
1089 { 0x0000, 0x0000, 0x0000 }, /* R991 */
1090 { 0x0000, 0x0000, 0x0000 }, /* R992 */
1091 { 0x0000, 0x0000, 0x0000 }, /* R993 */
1092 { 0x0000, 0x0000, 0x0000 }, /* R994 */
1093 { 0x0000, 0x0000, 0x0000 }, /* R995 */
1094 { 0x0000, 0x0000, 0x0000 }, /* R996 */
1095 { 0x0000, 0x0000, 0x0000 }, /* R997 */
1096 { 0x0000, 0x0000, 0x0000 }, /* R998 */
1097 { 0x0000, 0x0000, 0x0000 }, /* R999 */
1098 { 0x0000, 0x0000, 0x0000 }, /* R1000 */
1099 { 0x0000, 0x0000, 0x0000 }, /* R1001 */
1100 { 0x0000, 0x0000, 0x0000 }, /* R1002 */
1101 { 0x0000, 0x0000, 0x0000 }, /* R1003 */
1102 { 0x0000, 0x0000, 0x0000 }, /* R1004 */
1103 { 0x0000, 0x0000, 0x0000 }, /* R1005 */
1104 { 0x0000, 0x0000, 0x0000 }, /* R1006 */
1105 { 0x0000, 0x0000, 0x0000 }, /* R1007 */
1106 { 0x0000, 0x0000, 0x0000 }, /* R1008 */
1107 { 0x0000, 0x0000, 0x0000 }, /* R1009 */
1108 { 0x0000, 0x0000, 0x0000 }, /* R1010 */
1109 { 0x0000, 0x0000, 0x0000 }, /* R1011 */
1110 { 0x0000, 0x0000, 0x0000 }, /* R1012 */
1111 { 0x0000, 0x0000, 0x0000 }, /* R1013 */
1112 { 0x0000, 0x0000, 0x0000 }, /* R1014 */
1113 { 0x0000, 0x0000, 0x0000 }, /* R1015 */
1114 { 0x0000, 0x0000, 0x0000 }, /* R1016 */
1115 { 0x0000, 0x0000, 0x0000 }, /* R1017 */
1116 { 0x0000, 0x0000, 0x0000 }, /* R1018 */
1117 { 0x0000, 0x0000, 0x0000 }, /* R1019 */
1118 { 0x0000, 0x0000, 0x0000 }, /* R1020 */
1119 { 0x0000, 0x0000, 0x0000 }, /* R1021 */
1120 { 0x0000, 0x0000, 0x0000 }, /* R1022 */
1121 { 0x0000, 0x0000, 0x0000 }, /* R1023 */
1122 { 0x00FF, 0x01FF, 0x0000 }, /* R1024 - AIF1 ADC1 Left Volume */
1123 { 0x00FF, 0x01FF, 0x0000 }, /* R1025 - AIF1 ADC1 Right Volume */
1124 { 0x00FF, 0x01FF, 0x0000 }, /* R1026 - AIF1 DAC1 Left Volume */
1125 { 0x00FF, 0x01FF, 0x0000 }, /* R1027 - AIF1 DAC1 Right Volume */
1126 { 0x00FF, 0x01FF, 0x0000 }, /* R1028 - AIF1 ADC2 Left Volume */
1127 { 0x00FF, 0x01FF, 0x0000 }, /* R1029 - AIF1 ADC2 Right Volume */
1128 { 0x00FF, 0x01FF, 0x0000 }, /* R1030 - AIF1 DAC2 Left Volume */
1129 { 0x00FF, 0x01FF, 0x0000 }, /* R1031 - AIF1 DAC2 Right Volume */
1130 { 0x0000, 0x0000, 0x0000 }, /* R1032 */
1131 { 0x0000, 0x0000, 0x0000 }, /* R1033 */
1132 { 0x0000, 0x0000, 0x0000 }, /* R1034 */
1133 { 0x0000, 0x0000, 0x0000 }, /* R1035 */
1134 { 0x0000, 0x0000, 0x0000 }, /* R1036 */
1135 { 0x0000, 0x0000, 0x0000 }, /* R1037 */
1136 { 0x0000, 0x0000, 0x0000 }, /* R1038 */
1137 { 0x0000, 0x0000, 0x0000 }, /* R1039 */
1138 { 0xF800, 0xF800, 0x0000 }, /* R1040 - AIF1 ADC1 Filters */
1139 { 0x7800, 0x7800, 0x0000 }, /* R1041 - AIF1 ADC2 Filters */
1140 { 0x0000, 0x0000, 0x0000 }, /* R1042 */
1141 { 0x0000, 0x0000, 0x0000 }, /* R1043 */
1142 { 0x0000, 0x0000, 0x0000 }, /* R1044 */
1143 { 0x0000, 0x0000, 0x0000 }, /* R1045 */
1144 { 0x0000, 0x0000, 0x0000 }, /* R1046 */
1145 { 0x0000, 0x0000, 0x0000 }, /* R1047 */
1146 { 0x0000, 0x0000, 0x0000 }, /* R1048 */
1147 { 0x0000, 0x0000, 0x0000 }, /* R1049 */
1148 { 0x0000, 0x0000, 0x0000 }, /* R1050 */
1149 { 0x0000, 0x0000, 0x0000 }, /* R1051 */
1150 { 0x0000, 0x0000, 0x0000 }, /* R1052 */
1151 { 0x0000, 0x0000, 0x0000 }, /* R1053 */
1152 { 0x0000, 0x0000, 0x0000 }, /* R1054 */
1153 { 0x0000, 0x0000, 0x0000 }, /* R1055 */
1154 { 0x02B6, 0x02B6, 0x0000 }, /* R1056 - AIF1 DAC1 Filters (1) */
1155 { 0x3F00, 0x3F00, 0x0000 }, /* R1057 - AIF1 DAC1 Filters (2) */
1156 { 0x02B6, 0x02B6, 0x0000 }, /* R1058 - AIF1 DAC2 Filters (1) */
1157 { 0x3F00, 0x3F00, 0x0000 }, /* R1059 - AIF1 DAC2 Filters (2) */
1158 { 0x0000, 0x0000, 0x0000 }, /* R1060 */
1159 { 0x0000, 0x0000, 0x0000 }, /* R1061 */
1160 { 0x0000, 0x0000, 0x0000 }, /* R1062 */
1161 { 0x0000, 0x0000, 0x0000 }, /* R1063 */
1162 { 0x0000, 0x0000, 0x0000 }, /* R1064 */
1163 { 0x0000, 0x0000, 0x0000 }, /* R1065 */
1164 { 0x0000, 0x0000, 0x0000 }, /* R1066 */
1165 { 0x0000, 0x0000, 0x0000 }, /* R1067 */
1166 { 0x0000, 0x0000, 0x0000 }, /* R1068 */
1167 { 0x0000, 0x0000, 0x0000 }, /* R1069 */
1168 { 0x0000, 0x0000, 0x0000 }, /* R1070 */
1169 { 0x0000, 0x0000, 0x0000 }, /* R1071 */
1170 { 0x0000, 0x0000, 0x0000 }, /* R1072 */
1171 { 0x0000, 0x0000, 0x0000 }, /* R1073 */
1172 { 0x0000, 0x0000, 0x0000 }, /* R1074 */
1173 { 0x0000, 0x0000, 0x0000 }, /* R1075 */
1174 { 0x0000, 0x0000, 0x0000 }, /* R1076 */
1175 { 0x0000, 0x0000, 0x0000 }, /* R1077 */
1176 { 0x0000, 0x0000, 0x0000 }, /* R1078 */
1177 { 0x0000, 0x0000, 0x0000 }, /* R1079 */
1178 { 0x0000, 0x0000, 0x0000 }, /* R1080 */
1179 { 0x0000, 0x0000, 0x0000 }, /* R1081 */
1180 { 0x0000, 0x0000, 0x0000 }, /* R1082 */
1181 { 0x0000, 0x0000, 0x0000 }, /* R1083 */
1182 { 0x0000, 0x0000, 0x0000 }, /* R1084 */
1183 { 0x0000, 0x0000, 0x0000 }, /* R1085 */
1184 { 0x0000, 0x0000, 0x0000 }, /* R1086 */
1185 { 0x0000, 0x0000, 0x0000 }, /* R1087 */
1186 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1088 - AIF1 DRC1 (1) */
1187 { 0x1FFF, 0x1FFF, 0x0000 }, /* R1089 - AIF1 DRC1 (2) */
1188 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1090 - AIF1 DRC1 (3) */
1189 { 0x07FF, 0x07FF, 0x0000 }, /* R1091 - AIF1 DRC1 (4) */
1190 { 0x03FF, 0x03FF, 0x0000 }, /* R1092 - AIF1 DRC1 (5) */
1191 { 0x0000, 0x0000, 0x0000 }, /* R1093 */
1192 { 0x0000, 0x0000, 0x0000 }, /* R1094 */
1193 { 0x0000, 0x0000, 0x0000 }, /* R1095 */
1194 { 0x0000, 0x0000, 0x0000 }, /* R1096 */
1195 { 0x0000, 0x0000, 0x0000 }, /* R1097 */
1196 { 0x0000, 0x0000, 0x0000 }, /* R1098 */
1197 { 0x0000, 0x0000, 0x0000 }, /* R1099 */
1198 { 0x0000, 0x0000, 0x0000 }, /* R1100 */
1199 { 0x0000, 0x0000, 0x0000 }, /* R1101 */
1200 { 0x0000, 0x0000, 0x0000 }, /* R1102 */
1201 { 0x0000, 0x0000, 0x0000 }, /* R1103 */
1202 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1104 - AIF1 DRC2 (1) */
1203 { 0x1FFF, 0x1FFF, 0x0000 }, /* R1105 - AIF1 DRC2 (2) */
1204 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1106 - AIF1 DRC2 (3) */
1205 { 0x07FF, 0x07FF, 0x0000 }, /* R1107 - AIF1 DRC2 (4) */
1206 { 0x03FF, 0x03FF, 0x0000 }, /* R1108 - AIF1 DRC2 (5) */
1207 { 0x0000, 0x0000, 0x0000 }, /* R1109 */
1208 { 0x0000, 0x0000, 0x0000 }, /* R1110 */
1209 { 0x0000, 0x0000, 0x0000 }, /* R1111 */
1210 { 0x0000, 0x0000, 0x0000 }, /* R1112 */
1211 { 0x0000, 0x0000, 0x0000 }, /* R1113 */
1212 { 0x0000, 0x0000, 0x0000 }, /* R1114 */
1213 { 0x0000, 0x0000, 0x0000 }, /* R1115 */
1214 { 0x0000, 0x0000, 0x0000 }, /* R1116 */
1215 { 0x0000, 0x0000, 0x0000 }, /* R1117 */
1216 { 0x0000, 0x0000, 0x0000 }, /* R1118 */
1217 { 0x0000, 0x0000, 0x0000 }, /* R1119 */
1218 { 0x0000, 0x0000, 0x0000 }, /* R1120 */
1219 { 0x0000, 0x0000, 0x0000 }, /* R1121 */
1220 { 0x0000, 0x0000, 0x0000 }, /* R1122 */
1221 { 0x0000, 0x0000, 0x0000 }, /* R1123 */
1222 { 0x0000, 0x0000, 0x0000 }, /* R1124 */
1223 { 0x0000, 0x0000, 0x0000 }, /* R1125 */
1224 { 0x0000, 0x0000, 0x0000 }, /* R1126 */
1225 { 0x0000, 0x0000, 0x0000 }, /* R1127 */
1226 { 0x0000, 0x0000, 0x0000 }, /* R1128 */
1227 { 0x0000, 0x0000, 0x0000 }, /* R1129 */
1228 { 0x0000, 0x0000, 0x0000 }, /* R1130 */
1229 { 0x0000, 0x0000, 0x0000 }, /* R1131 */
1230 { 0x0000, 0x0000, 0x0000 }, /* R1132 */
1231 { 0x0000, 0x0000, 0x0000 }, /* R1133 */
1232 { 0x0000, 0x0000, 0x0000 }, /* R1134 */
1233 { 0x0000, 0x0000, 0x0000 }, /* R1135 */
1234 { 0x0000, 0x0000, 0x0000 }, /* R1136 */
1235 { 0x0000, 0x0000, 0x0000 }, /* R1137 */
1236 { 0x0000, 0x0000, 0x0000 }, /* R1138 */
1237 { 0x0000, 0x0000, 0x0000 }, /* R1139 */
1238 { 0x0000, 0x0000, 0x0000 }, /* R1140 */
1239 { 0x0000, 0x0000, 0x0000 }, /* R1141 */
1240 { 0x0000, 0x0000, 0x0000 }, /* R1142 */
1241 { 0x0000, 0x0000, 0x0000 }, /* R1143 */
1242 { 0x0000, 0x0000, 0x0000 }, /* R1144 */
1243 { 0x0000, 0x0000, 0x0000 }, /* R1145 */
1244 { 0x0000, 0x0000, 0x0000 }, /* R1146 */
1245 { 0x0000, 0x0000, 0x0000 }, /* R1147 */
1246 { 0x0000, 0x0000, 0x0000 }, /* R1148 */
1247 { 0x0000, 0x0000, 0x0000 }, /* R1149 */
1248 { 0x0000, 0x0000, 0x0000 }, /* R1150 */
1249 { 0x0000, 0x0000, 0x0000 }, /* R1151 */
1250 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1152 - AIF1 DAC1 EQ Gains (1) */
1251 { 0xFFC0, 0xFFC0, 0x0000 }, /* R1153 - AIF1 DAC1 EQ Gains (2) */
1252 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1154 - AIF1 DAC1 EQ Band 1 A */
1253 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1155 - AIF1 DAC1 EQ Band 1 B */
1254 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1156 - AIF1 DAC1 EQ Band 1 PG */
1255 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1157 - AIF1 DAC1 EQ Band 2 A */
1256 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1158 - AIF1 DAC1 EQ Band 2 B */
1257 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1159 - AIF1 DAC1 EQ Band 2 C */
1258 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1160 - AIF1 DAC1 EQ Band 2 PG */
1259 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1161 - AIF1 DAC1 EQ Band 3 A */
1260 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1162 - AIF1 DAC1 EQ Band 3 B */
1261 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1163 - AIF1 DAC1 EQ Band 3 C */
1262 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1164 - AIF1 DAC1 EQ Band 3 PG */
1263 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1165 - AIF1 DAC1 EQ Band 4 A */
1264 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1166 - AIF1 DAC1 EQ Band 4 B */
1265 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1167 - AIF1 DAC1 EQ Band 4 C */
1266 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1168 - AIF1 DAC1 EQ Band 4 PG */
1267 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1169 - AIF1 DAC1 EQ Band 5 A */
1268 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1170 - AIF1 DAC1 EQ Band 5 B */
1269 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1171 - AIF1 DAC1 EQ Band 5 PG */
1270 { 0x0000, 0x0000, 0x0000 }, /* R1172 */
1271 { 0x0000, 0x0000, 0x0000 }, /* R1173 */
1272 { 0x0000, 0x0000, 0x0000 }, /* R1174 */
1273 { 0x0000, 0x0000, 0x0000 }, /* R1175 */
1274 { 0x0000, 0x0000, 0x0000 }, /* R1176 */
1275 { 0x0000, 0x0000, 0x0000 }, /* R1177 */
1276 { 0x0000, 0x0000, 0x0000 }, /* R1178 */
1277 { 0x0000, 0x0000, 0x0000 }, /* R1179 */
1278 { 0x0000, 0x0000, 0x0000 }, /* R1180 */
1279 { 0x0000, 0x0000, 0x0000 }, /* R1181 */
1280 { 0x0000, 0x0000, 0x0000 }, /* R1182 */
1281 { 0x0000, 0x0000, 0x0000 }, /* R1183 */
1282 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1184 - AIF1 DAC2 EQ Gains (1) */
1283 { 0xFFC0, 0xFFC0, 0x0000 }, /* R1185 - AIF1 DAC2 EQ Gains (2) */
1284 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1186 - AIF1 DAC2 EQ Band 1 A */
1285 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1187 - AIF1 DAC2 EQ Band 1 B */
1286 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1188 - AIF1 DAC2 EQ Band 1 PG */
1287 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1189 - AIF1 DAC2 EQ Band 2 A */
1288 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1190 - AIF1 DAC2 EQ Band 2 B */
1289 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1191 - AIF1 DAC2 EQ Band 2 C */
1290 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1192 - AIF1 DAC2 EQ Band 2 PG */
1291 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1193 - AIF1 DAC2 EQ Band 3 A */
1292 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1194 - AIF1 DAC2 EQ Band 3 B */
1293 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1195 - AIF1 DAC2 EQ Band 3 C */
1294 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1196 - AIF1 DAC2 EQ Band 3 PG */
1295 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1197 - AIF1 DAC2 EQ Band 4 A */
1296 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1198 - AIF1 DAC2 EQ Band 4 B */
1297 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1199 - AIF1 DAC2 EQ Band 4 C */
1298 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1200 - AIF1 DAC2 EQ Band 4 PG */
1299 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1201 - AIF1 DAC2 EQ Band 5 A */
1300 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1202 - AIF1 DAC2 EQ Band 5 B */
1301 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1203 - AIF1 DAC2 EQ Band 5 PG */
1302 { 0x0000, 0x0000, 0x0000 }, /* R1204 */
1303 { 0x0000, 0x0000, 0x0000 }, /* R1205 */
1304 { 0x0000, 0x0000, 0x0000 }, /* R1206 */
1305 { 0x0000, 0x0000, 0x0000 }, /* R1207 */
1306 { 0x0000, 0x0000, 0x0000 }, /* R1208 */
1307 { 0x0000, 0x0000, 0x0000 }, /* R1209 */
1308 { 0x0000, 0x0000, 0x0000 }, /* R1210 */
1309 { 0x0000, 0x0000, 0x0000 }, /* R1211 */
1310 { 0x0000, 0x0000, 0x0000 }, /* R1212 */
1311 { 0x0000, 0x0000, 0x0000 }, /* R1213 */
1312 { 0x0000, 0x0000, 0x0000 }, /* R1214 */
1313 { 0x0000, 0x0000, 0x0000 }, /* R1215 */
1314 { 0x0000, 0x0000, 0x0000 }, /* R1216 */
1315 { 0x0000, 0x0000, 0x0000 }, /* R1217 */
1316 { 0x0000, 0x0000, 0x0000 }, /* R1218 */
1317 { 0x0000, 0x0000, 0x0000 }, /* R1219 */
1318 { 0x0000, 0x0000, 0x0000 }, /* R1220 */
1319 { 0x0000, 0x0000, 0x0000 }, /* R1221 */
1320 { 0x0000, 0x0000, 0x0000 }, /* R1222 */
1321 { 0x0000, 0x0000, 0x0000 }, /* R1223 */
1322 { 0x0000, 0x0000, 0x0000 }, /* R1224 */
1323 { 0x0000, 0x0000, 0x0000 }, /* R1225 */
1324 { 0x0000, 0x0000, 0x0000 }, /* R1226 */
1325 { 0x0000, 0x0000, 0x0000 }, /* R1227 */
1326 { 0x0000, 0x0000, 0x0000 }, /* R1228 */
1327 { 0x0000, 0x0000, 0x0000 }, /* R1229 */
1328 { 0x0000, 0x0000, 0x0000 }, /* R1230 */
1329 { 0x0000, 0x0000, 0x0000 }, /* R1231 */
1330 { 0x0000, 0x0000, 0x0000 }, /* R1232 */
1331 { 0x0000, 0x0000, 0x0000 }, /* R1233 */
1332 { 0x0000, 0x0000, 0x0000 }, /* R1234 */
1333 { 0x0000, 0x0000, 0x0000 }, /* R1235 */
1334 { 0x0000, 0x0000, 0x0000 }, /* R1236 */
1335 { 0x0000, 0x0000, 0x0000 }, /* R1237 */
1336 { 0x0000, 0x0000, 0x0000 }, /* R1238 */
1337 { 0x0000, 0x0000, 0x0000 }, /* R1239 */
1338 { 0x0000, 0x0000, 0x0000 }, /* R1240 */
1339 { 0x0000, 0x0000, 0x0000 }, /* R1241 */
1340 { 0x0000, 0x0000, 0x0000 }, /* R1242 */
1341 { 0x0000, 0x0000, 0x0000 }, /* R1243 */
1342 { 0x0000, 0x0000, 0x0000 }, /* R1244 */
1343 { 0x0000, 0x0000, 0x0000 }, /* R1245 */
1344 { 0x0000, 0x0000, 0x0000 }, /* R1246 */
1345 { 0x0000, 0x0000, 0x0000 }, /* R1247 */
1346 { 0x0000, 0x0000, 0x0000 }, /* R1248 */
1347 { 0x0000, 0x0000, 0x0000 }, /* R1249 */
1348 { 0x0000, 0x0000, 0x0000 }, /* R1250 */
1349 { 0x0000, 0x0000, 0x0000 }, /* R1251 */
1350 { 0x0000, 0x0000, 0x0000 }, /* R1252 */
1351 { 0x0000, 0x0000, 0x0000 }, /* R1253 */
1352 { 0x0000, 0x0000, 0x0000 }, /* R1254 */
1353 { 0x0000, 0x0000, 0x0000 }, /* R1255 */
1354 { 0x0000, 0x0000, 0x0000 }, /* R1256 */
1355 { 0x0000, 0x0000, 0x0000 }, /* R1257 */
1356 { 0x0000, 0x0000, 0x0000 }, /* R1258 */
1357 { 0x0000, 0x0000, 0x0000 }, /* R1259 */
1358 { 0x0000, 0x0000, 0x0000 }, /* R1260 */
1359 { 0x0000, 0x0000, 0x0000 }, /* R1261 */
1360 { 0x0000, 0x0000, 0x0000 }, /* R1262 */
1361 { 0x0000, 0x0000, 0x0000 }, /* R1263 */
1362 { 0x0000, 0x0000, 0x0000 }, /* R1264 */
1363 { 0x0000, 0x0000, 0x0000 }, /* R1265 */
1364 { 0x0000, 0x0000, 0x0000 }, /* R1266 */
1365 { 0x0000, 0x0000, 0x0000 }, /* R1267 */
1366 { 0x0000, 0x0000, 0x0000 }, /* R1268 */
1367 { 0x0000, 0x0000, 0x0000 }, /* R1269 */
1368 { 0x0000, 0x0000, 0x0000 }, /* R1270 */
1369 { 0x0000, 0x0000, 0x0000 }, /* R1271 */
1370 { 0x0000, 0x0000, 0x0000 }, /* R1272 */
1371 { 0x0000, 0x0000, 0x0000 }, /* R1273 */
1372 { 0x0000, 0x0000, 0x0000 }, /* R1274 */
1373 { 0x0000, 0x0000, 0x0000 }, /* R1275 */
1374 { 0x0000, 0x0000, 0x0000 }, /* R1276 */
1375 { 0x0000, 0x0000, 0x0000 }, /* R1277 */
1376 { 0x0000, 0x0000, 0x0000 }, /* R1278 */
1377 { 0x0000, 0x0000, 0x0000 }, /* R1279 */
1378 { 0x00FF, 0x01FF, 0x0000 }, /* R1280 - AIF2 ADC Left Volume */
1379 { 0x00FF, 0x01FF, 0x0000 }, /* R1281 - AIF2 ADC Right Volume */
1380 { 0x00FF, 0x01FF, 0x0000 }, /* R1282 - AIF2 DAC Left Volume */
1381 { 0x00FF, 0x01FF, 0x0000 }, /* R1283 - AIF2 DAC Right Volume */
1382 { 0x0000, 0x0000, 0x0000 }, /* R1284 */
1383 { 0x0000, 0x0000, 0x0000 }, /* R1285 */
1384 { 0x0000, 0x0000, 0x0000 }, /* R1286 */
1385 { 0x0000, 0x0000, 0x0000 }, /* R1287 */
1386 { 0x0000, 0x0000, 0x0000 }, /* R1288 */
1387 { 0x0000, 0x0000, 0x0000 }, /* R1289 */
1388 { 0x0000, 0x0000, 0x0000 }, /* R1290 */
1389 { 0x0000, 0x0000, 0x0000 }, /* R1291 */
1390 { 0x0000, 0x0000, 0x0000 }, /* R1292 */
1391 { 0x0000, 0x0000, 0x0000 }, /* R1293 */
1392 { 0x0000, 0x0000, 0x0000 }, /* R1294 */
1393 { 0x0000, 0x0000, 0x0000 }, /* R1295 */
1394 { 0xF800, 0xF800, 0x0000 }, /* R1296 - AIF2 ADC Filters */
1395 { 0x0000, 0x0000, 0x0000 }, /* R1297 */
1396 { 0x0000, 0x0000, 0x0000 }, /* R1298 */
1397 { 0x0000, 0x0000, 0x0000 }, /* R1299 */
1398 { 0x0000, 0x0000, 0x0000 }, /* R1300 */
1399 { 0x0000, 0x0000, 0x0000 }, /* R1301 */
1400 { 0x0000, 0x0000, 0x0000 }, /* R1302 */
1401 { 0x0000, 0x0000, 0x0000 }, /* R1303 */
1402 { 0x0000, 0x0000, 0x0000 }, /* R1304 */
1403 { 0x0000, 0x0000, 0x0000 }, /* R1305 */
1404 { 0x0000, 0x0000, 0x0000 }, /* R1306 */
1405 { 0x0000, 0x0000, 0x0000 }, /* R1307 */
1406 { 0x0000, 0x0000, 0x0000 }, /* R1308 */
1407 { 0x0000, 0x0000, 0x0000 }, /* R1309 */
1408 { 0x0000, 0x0000, 0x0000 }, /* R1310 */
1409 { 0x0000, 0x0000, 0x0000 }, /* R1311 */
1410 { 0x02B6, 0x02B6, 0x0000 }, /* R1312 - AIF2 DAC Filters (1) */
1411 { 0x3F00, 0x3F00, 0x0000 }, /* R1313 - AIF2 DAC Filters (2) */
1412 { 0x0000, 0x0000, 0x0000 }, /* R1314 */
1413 { 0x0000, 0x0000, 0x0000 }, /* R1315 */
1414 { 0x0000, 0x0000, 0x0000 }, /* R1316 */
1415 { 0x0000, 0x0000, 0x0000 }, /* R1317 */
1416 { 0x0000, 0x0000, 0x0000 }, /* R1318 */
1417 { 0x0000, 0x0000, 0x0000 }, /* R1319 */
1418 { 0x0000, 0x0000, 0x0000 }, /* R1320 */
1419 { 0x0000, 0x0000, 0x0000 }, /* R1321 */
1420 { 0x0000, 0x0000, 0x0000 }, /* R1322 */
1421 { 0x0000, 0x0000, 0x0000 }, /* R1323 */
1422 { 0x0000, 0x0000, 0x0000 }, /* R1324 */
1423 { 0x0000, 0x0000, 0x0000 }, /* R1325 */
1424 { 0x0000, 0x0000, 0x0000 }, /* R1326 */
1425 { 0x0000, 0x0000, 0x0000 }, /* R1327 */
1426 { 0x0000, 0x0000, 0x0000 }, /* R1328 */
1427 { 0x0000, 0x0000, 0x0000 }, /* R1329 */
1428 { 0x0000, 0x0000, 0x0000 }, /* R1330 */
1429 { 0x0000, 0x0000, 0x0000 }, /* R1331 */
1430 { 0x0000, 0x0000, 0x0000 }, /* R1332 */
1431 { 0x0000, 0x0000, 0x0000 }, /* R1333 */
1432 { 0x0000, 0x0000, 0x0000 }, /* R1334 */
1433 { 0x0000, 0x0000, 0x0000 }, /* R1335 */
1434 { 0x0000, 0x0000, 0x0000 }, /* R1336 */
1435 { 0x0000, 0x0000, 0x0000 }, /* R1337 */
1436 { 0x0000, 0x0000, 0x0000 }, /* R1338 */
1437 { 0x0000, 0x0000, 0x0000 }, /* R1339 */
1438 { 0x0000, 0x0000, 0x0000 }, /* R1340 */
1439 { 0x0000, 0x0000, 0x0000 }, /* R1341 */
1440 { 0x0000, 0x0000, 0x0000 }, /* R1342 */
1441 { 0x0000, 0x0000, 0x0000 }, /* R1343 */
1442 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1344 - AIF2 DRC (1) */
1443 { 0x1FFF, 0x1FFF, 0x0000 }, /* R1345 - AIF2 DRC (2) */
1444 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1346 - AIF2 DRC (3) */
1445 { 0x07FF, 0x07FF, 0x0000 }, /* R1347 - AIF2 DRC (4) */
1446 { 0x03FF, 0x03FF, 0x0000 }, /* R1348 - AIF2 DRC (5) */
1447 { 0x0000, 0x0000, 0x0000 }, /* R1349 */
1448 { 0x0000, 0x0000, 0x0000 }, /* R1350 */
1449 { 0x0000, 0x0000, 0x0000 }, /* R1351 */
1450 { 0x0000, 0x0000, 0x0000 }, /* R1352 */
1451 { 0x0000, 0x0000, 0x0000 }, /* R1353 */
1452 { 0x0000, 0x0000, 0x0000 }, /* R1354 */
1453 { 0x0000, 0x0000, 0x0000 }, /* R1355 */
1454 { 0x0000, 0x0000, 0x0000 }, /* R1356 */
1455 { 0x0000, 0x0000, 0x0000 }, /* R1357 */
1456 { 0x0000, 0x0000, 0x0000 }, /* R1358 */
1457 { 0x0000, 0x0000, 0x0000 }, /* R1359 */
1458 { 0x0000, 0x0000, 0x0000 }, /* R1360 */
1459 { 0x0000, 0x0000, 0x0000 }, /* R1361 */
1460 { 0x0000, 0x0000, 0x0000 }, /* R1362 */
1461 { 0x0000, 0x0000, 0x0000 }, /* R1363 */
1462 { 0x0000, 0x0000, 0x0000 }, /* R1364 */
1463 { 0x0000, 0x0000, 0x0000 }, /* R1365 */
1464 { 0x0000, 0x0000, 0x0000 }, /* R1366 */
1465 { 0x0000, 0x0000, 0x0000 }, /* R1367 */
1466 { 0x0000, 0x0000, 0x0000 }, /* R1368 */
1467 { 0x0000, 0x0000, 0x0000 }, /* R1369 */
1468 { 0x0000, 0x0000, 0x0000 }, /* R1370 */
1469 { 0x0000, 0x0000, 0x0000 }, /* R1371 */
1470 { 0x0000, 0x0000, 0x0000 }, /* R1372 */
1471 { 0x0000, 0x0000, 0x0000 }, /* R1373 */
1472 { 0x0000, 0x0000, 0x0000 }, /* R1374 */
1473 { 0x0000, 0x0000, 0x0000 }, /* R1375 */
1474 { 0x0000, 0x0000, 0x0000 }, /* R1376 */
1475 { 0x0000, 0x0000, 0x0000 }, /* R1377 */
1476 { 0x0000, 0x0000, 0x0000 }, /* R1378 */
1477 { 0x0000, 0x0000, 0x0000 }, /* R1379 */
1478 { 0x0000, 0x0000, 0x0000 }, /* R1380 */
1479 { 0x0000, 0x0000, 0x0000 }, /* R1381 */
1480 { 0x0000, 0x0000, 0x0000 }, /* R1382 */
1481 { 0x0000, 0x0000, 0x0000 }, /* R1383 */
1482 { 0x0000, 0x0000, 0x0000 }, /* R1384 */
1483 { 0x0000, 0x0000, 0x0000 }, /* R1385 */
1484 { 0x0000, 0x0000, 0x0000 }, /* R1386 */
1485 { 0x0000, 0x0000, 0x0000 }, /* R1387 */
1486 { 0x0000, 0x0000, 0x0000 }, /* R1388 */
1487 { 0x0000, 0x0000, 0x0000 }, /* R1389 */
1488 { 0x0000, 0x0000, 0x0000 }, /* R1390 */
1489 { 0x0000, 0x0000, 0x0000 }, /* R1391 */
1490 { 0x0000, 0x0000, 0x0000 }, /* R1392 */
1491 { 0x0000, 0x0000, 0x0000 }, /* R1393 */
1492 { 0x0000, 0x0000, 0x0000 }, /* R1394 */
1493 { 0x0000, 0x0000, 0x0000 }, /* R1395 */
1494 { 0x0000, 0x0000, 0x0000 }, /* R1396 */
1495 { 0x0000, 0x0000, 0x0000 }, /* R1397 */
1496 { 0x0000, 0x0000, 0x0000 }, /* R1398 */
1497 { 0x0000, 0x0000, 0x0000 }, /* R1399 */
1498 { 0x0000, 0x0000, 0x0000 }, /* R1400 */
1499 { 0x0000, 0x0000, 0x0000 }, /* R1401 */
1500 { 0x0000, 0x0000, 0x0000 }, /* R1402 */
1501 { 0x0000, 0x0000, 0x0000 }, /* R1403 */
1502 { 0x0000, 0x0000, 0x0000 }, /* R1404 */
1503 { 0x0000, 0x0000, 0x0000 }, /* R1405 */
1504 { 0x0000, 0x0000, 0x0000 }, /* R1406 */
1505 { 0x0000, 0x0000, 0x0000 }, /* R1407 */
1506 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1408 - AIF2 EQ Gains (1) */
1507 { 0xFFC0, 0xFFC0, 0x0000 }, /* R1409 - AIF2 EQ Gains (2) */
1508 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1410 - AIF2 EQ Band 1 A */
1509 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1411 - AIF2 EQ Band 1 B */
1510 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1412 - AIF2 EQ Band 1 PG */
1511 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1413 - AIF2 EQ Band 2 A */
1512 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1414 - AIF2 EQ Band 2 B */
1513 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1415 - AIF2 EQ Band 2 C */
1514 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1416 - AIF2 EQ Band 2 PG */
1515 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1417 - AIF2 EQ Band 3 A */
1516 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1418 - AIF2 EQ Band 3 B */
1517 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1419 - AIF2 EQ Band 3 C */
1518 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1420 - AIF2 EQ Band 3 PG */
1519 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1421 - AIF2 EQ Band 4 A */
1520 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1422 - AIF2 EQ Band 4 B */
1521 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1423 - AIF2 EQ Band 4 C */
1522 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1424 - AIF2 EQ Band 4 PG */
1523 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1425 - AIF2 EQ Band 5 A */
1524 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1426 - AIF2 EQ Band 5 B */
1525 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1427 - AIF2 EQ Band 5 PG */
1526 { 0x0000, 0x0000, 0x0000 }, /* R1428 */
1527 { 0x0000, 0x0000, 0x0000 }, /* R1429 */
1528 { 0x0000, 0x0000, 0x0000 }, /* R1430 */
1529 { 0x0000, 0x0000, 0x0000 }, /* R1431 */
1530 { 0x0000, 0x0000, 0x0000 }, /* R1432 */
1531 { 0x0000, 0x0000, 0x0000 }, /* R1433 */
1532 { 0x0000, 0x0000, 0x0000 }, /* R1434 */
1533 { 0x0000, 0x0000, 0x0000 }, /* R1435 */
1534 { 0x0000, 0x0000, 0x0000 }, /* R1436 */
1535 { 0x0000, 0x0000, 0x0000 }, /* R1437 */
1536 { 0x0000, 0x0000, 0x0000 }, /* R1438 */
1537 { 0x0000, 0x0000, 0x0000 }, /* R1439 */
1538 { 0x0000, 0x0000, 0x0000 }, /* R1440 */
1539 { 0x0000, 0x0000, 0x0000 }, /* R1441 */
1540 { 0x0000, 0x0000, 0x0000 }, /* R1442 */
1541 { 0x0000, 0x0000, 0x0000 }, /* R1443 */
1542 { 0x0000, 0x0000, 0x0000 }, /* R1444 */
1543 { 0x0000, 0x0000, 0x0000 }, /* R1445 */
1544 { 0x0000, 0x0000, 0x0000 }, /* R1446 */
1545 { 0x0000, 0x0000, 0x0000 }, /* R1447 */
1546 { 0x0000, 0x0000, 0x0000 }, /* R1448 */
1547 { 0x0000, 0x0000, 0x0000 }, /* R1449 */
1548 { 0x0000, 0x0000, 0x0000 }, /* R1450 */
1549 { 0x0000, 0x0000, 0x0000 }, /* R1451 */
1550 { 0x0000, 0x0000, 0x0000 }, /* R1452 */
1551 { 0x0000, 0x0000, 0x0000 }, /* R1453 */
1552 { 0x0000, 0x0000, 0x0000 }, /* R1454 */
1553 { 0x0000, 0x0000, 0x0000 }, /* R1455 */
1554 { 0x0000, 0x0000, 0x0000 }, /* R1456 */
1555 { 0x0000, 0x0000, 0x0000 }, /* R1457 */
1556 { 0x0000, 0x0000, 0x0000 }, /* R1458 */
1557 { 0x0000, 0x0000, 0x0000 }, /* R1459 */
1558 { 0x0000, 0x0000, 0x0000 }, /* R1460 */
1559 { 0x0000, 0x0000, 0x0000 }, /* R1461 */
1560 { 0x0000, 0x0000, 0x0000 }, /* R1462 */
1561 { 0x0000, 0x0000, 0x0000 }, /* R1463 */
1562 { 0x0000, 0x0000, 0x0000 }, /* R1464 */
1563 { 0x0000, 0x0000, 0x0000 }, /* R1465 */
1564 { 0x0000, 0x0000, 0x0000 }, /* R1466 */
1565 { 0x0000, 0x0000, 0x0000 }, /* R1467 */
1566 { 0x0000, 0x0000, 0x0000 }, /* R1468 */
1567 { 0x0000, 0x0000, 0x0000 }, /* R1469 */
1568 { 0x0000, 0x0000, 0x0000 }, /* R1470 */
1569 { 0x0000, 0x0000, 0x0000 }, /* R1471 */
1570 { 0x0000, 0x0000, 0x0000 }, /* R1472 */
1571 { 0x0000, 0x0000, 0x0000 }, /* R1473 */
1572 { 0x0000, 0x0000, 0x0000 }, /* R1474 */
1573 { 0x0000, 0x0000, 0x0000 }, /* R1475 */
1574 { 0x0000, 0x0000, 0x0000 }, /* R1476 */
1575 { 0x0000, 0x0000, 0x0000 }, /* R1477 */
1576 { 0x0000, 0x0000, 0x0000 }, /* R1478 */
1577 { 0x0000, 0x0000, 0x0000 }, /* R1479 */
1578 { 0x0000, 0x0000, 0x0000 }, /* R1480 */
1579 { 0x0000, 0x0000, 0x0000 }, /* R1481 */
1580 { 0x0000, 0x0000, 0x0000 }, /* R1482 */
1581 { 0x0000, 0x0000, 0x0000 }, /* R1483 */
1582 { 0x0000, 0x0000, 0x0000 }, /* R1484 */
1583 { 0x0000, 0x0000, 0x0000 }, /* R1485 */
1584 { 0x0000, 0x0000, 0x0000 }, /* R1486 */
1585 { 0x0000, 0x0000, 0x0000 }, /* R1487 */
1586 { 0x0000, 0x0000, 0x0000 }, /* R1488 */
1587 { 0x0000, 0x0000, 0x0000 }, /* R1489 */
1588 { 0x0000, 0x0000, 0x0000 }, /* R1490 */
1589 { 0x0000, 0x0000, 0x0000 }, /* R1491 */
1590 { 0x0000, 0x0000, 0x0000 }, /* R1492 */
1591 { 0x0000, 0x0000, 0x0000 }, /* R1493 */
1592 { 0x0000, 0x0000, 0x0000 }, /* R1494 */
1593 { 0x0000, 0x0000, 0x0000 }, /* R1495 */
1594 { 0x0000, 0x0000, 0x0000 }, /* R1496 */
1595 { 0x0000, 0x0000, 0x0000 }, /* R1497 */
1596 { 0x0000, 0x0000, 0x0000 }, /* R1498 */
1597 { 0x0000, 0x0000, 0x0000 }, /* R1499 */
1598 { 0x0000, 0x0000, 0x0000 }, /* R1500 */
1599 { 0x0000, 0x0000, 0x0000 }, /* R1501 */
1600 { 0x0000, 0x0000, 0x0000 }, /* R1502 */
1601 { 0x0000, 0x0000, 0x0000 }, /* R1503 */
1602 { 0x0000, 0x0000, 0x0000 }, /* R1504 */
1603 { 0x0000, 0x0000, 0x0000 }, /* R1505 */
1604 { 0x0000, 0x0000, 0x0000 }, /* R1506 */
1605 { 0x0000, 0x0000, 0x0000 }, /* R1507 */
1606 { 0x0000, 0x0000, 0x0000 }, /* R1508 */
1607 { 0x0000, 0x0000, 0x0000 }, /* R1509 */
1608 { 0x0000, 0x0000, 0x0000 }, /* R1510 */
1609 { 0x0000, 0x0000, 0x0000 }, /* R1511 */
1610 { 0x0000, 0x0000, 0x0000 }, /* R1512 */
1611 { 0x0000, 0x0000, 0x0000 }, /* R1513 */
1612 { 0x0000, 0x0000, 0x0000 }, /* R1514 */
1613 { 0x0000, 0x0000, 0x0000 }, /* R1515 */
1614 { 0x0000, 0x0000, 0x0000 }, /* R1516 */
1615 { 0x0000, 0x0000, 0x0000 }, /* R1517 */
1616 { 0x0000, 0x0000, 0x0000 }, /* R1518 */
1617 { 0x0000, 0x0000, 0x0000 }, /* R1519 */
1618 { 0x0000, 0x0000, 0x0000 }, /* R1520 */
1619 { 0x0000, 0x0000, 0x0000 }, /* R1521 */
1620 { 0x0000, 0x0000, 0x0000 }, /* R1522 */
1621 { 0x0000, 0x0000, 0x0000 }, /* R1523 */
1622 { 0x0000, 0x0000, 0x0000 }, /* R1524 */
1623 { 0x0000, 0x0000, 0x0000 }, /* R1525 */
1624 { 0x0000, 0x0000, 0x0000 }, /* R1526 */
1625 { 0x0000, 0x0000, 0x0000 }, /* R1527 */
1626 { 0x0000, 0x0000, 0x0000 }, /* R1528 */
1627 { 0x0000, 0x0000, 0x0000 }, /* R1529 */
1628 { 0x0000, 0x0000, 0x0000 }, /* R1530 */
1629 { 0x0000, 0x0000, 0x0000 }, /* R1531 */
1630 { 0x0000, 0x0000, 0x0000 }, /* R1532 */
1631 { 0x0000, 0x0000, 0x0000 }, /* R1533 */
1632 { 0x0000, 0x0000, 0x0000 }, /* R1534 */
1633 { 0x0000, 0x0000, 0x0000 }, /* R1535 */
1634 { 0x01EF, 0x01EF, 0x0000 }, /* R1536 - DAC1 Mixer Volumes */
1635 { 0x0037, 0x0037, 0x0000 }, /* R1537 - DAC1 Left Mixer Routing */
1636 { 0x0037, 0x0037, 0x0000 }, /* R1538 - DAC1 Right Mixer Routing */
1637 { 0x01EF, 0x01EF, 0x0000 }, /* R1539 - DAC2 Mixer Volumes */
1638 { 0x0037, 0x0037, 0x0000 }, /* R1540 - DAC2 Left Mixer Routing */
1639 { 0x0037, 0x0037, 0x0000 }, /* R1541 - DAC2 Right Mixer Routing */
1640 { 0x0003, 0x0003, 0x0000 }, /* R1542 - AIF1 ADC1 Left Mixer Routing */
1641 { 0x0003, 0x0003, 0x0000 }, /* R1543 - AIF1 ADC1 Right Mixer Routing */
1642 { 0x0003, 0x0003, 0x0000 }, /* R1544 - AIF1 ADC2 Left Mixer Routing */
1643 { 0x0003, 0x0003, 0x0000 }, /* R1545 - AIF1 ADC2 Right mixer Routing */
1644 { 0x0000, 0x0000, 0x0000 }, /* R1546 */
1645 { 0x0000, 0x0000, 0x0000 }, /* R1547 */
1646 { 0x0000, 0x0000, 0x0000 }, /* R1548 */
1647 { 0x0000, 0x0000, 0x0000 }, /* R1549 */
1648 { 0x0000, 0x0000, 0x0000 }, /* R1550 */
1649 { 0x0000, 0x0000, 0x0000 }, /* R1551 */
1650 { 0x02FF, 0x03FF, 0x0000 }, /* R1552 - DAC1 Left Volume */
1651 { 0x02FF, 0x03FF, 0x0000 }, /* R1553 - DAC1 Right Volume */
1652 { 0x02FF, 0x03FF, 0x0000 }, /* R1554 - DAC2 Left Volume */
1653 { 0x02FF, 0x03FF, 0x0000 }, /* R1555 - DAC2 Right Volume */
1654 { 0x0003, 0x0003, 0x0000 }, /* R1556 - DAC Softmute */
1655 { 0x0000, 0x0000, 0x0000 }, /* R1557 */
1656 { 0x0000, 0x0000, 0x0000 }, /* R1558 */
1657 { 0x0000, 0x0000, 0x0000 }, /* R1559 */
1658 { 0x0000, 0x0000, 0x0000 }, /* R1560 */
1659 { 0x0000, 0x0000, 0x0000 }, /* R1561 */
1660 { 0x0000, 0x0000, 0x0000 }, /* R1562 */
1661 { 0x0000, 0x0000, 0x0000 }, /* R1563 */
1662 { 0x0000, 0x0000, 0x0000 }, /* R1564 */
1663 { 0x0000, 0x0000, 0x0000 }, /* R1565 */
1664 { 0x0000, 0x0000, 0x0000 }, /* R1566 */
1665 { 0x0000, 0x0000, 0x0000 }, /* R1567 */
1666 { 0x0003, 0x0003, 0x0000 }, /* R1568 - Oversampling */
1667 { 0x03C3, 0x03C3, 0x0000 }, /* R1569 - Sidetone */
1668};
1669
1670static int wm8994_readable(unsigned int reg)
1671{
1672 if (reg >= ARRAY_SIZE(access_masks))
1673 return 0;
1674 return access_masks[reg].readable != 0;
1675}
1676
1677static int wm8994_volatile(unsigned int reg)
1678{
1679 if (reg >= WM8994_REG_CACHE_SIZE)
1680 return 1;
1681
1682 switch (reg) {
1683 case WM8994_SOFTWARE_RESET:
1684 case WM8994_CHIP_REVISION:
1685 case WM8994_DC_SERVO_1:
1686 case WM8994_DC_SERVO_READBACK:
1687 case WM8994_RATE_STATUS:
1688 case WM8994_LDO_1:
1689 case WM8994_LDO_2:
1690 return 1;
1691 default:
1692 return 0;
1693 }
1694}
1695
1696static int wm8994_write(struct snd_soc_codec *codec, unsigned int reg,
1697 unsigned int value)
1698{
1699 struct wm8994_priv *wm8994 = codec->private_data;
1700
1701 BUG_ON(reg > WM8994_MAX_REGISTER);
1702
1703 if (!wm8994_volatile(reg))
1704 wm8994->reg_cache[reg] = value;
1705
1706 return wm8994_reg_write(codec->control_data, reg, value);
1707}
1708
1709static unsigned int wm8994_read(struct snd_soc_codec *codec,
1710 unsigned int reg)
1711{
1712 u16 *reg_cache = codec->reg_cache;
1713
1714 BUG_ON(reg > WM8994_MAX_REGISTER);
1715
1716 if (wm8994_volatile(reg))
1717 return wm8994_reg_read(codec->control_data, reg);
1718 else
1719 return reg_cache[reg];
1720}
1721
1722static int configure_aif_clock(struct snd_soc_codec *codec, int aif)
1723{
1724 struct wm8994_priv *wm8994 = codec->private_data;
1725 int rate;
1726 int reg1 = 0;
1727 int offset;
1728
1729 if (aif)
1730 offset = 4;
1731 else
1732 offset = 0;
1733
1734 switch (wm8994->sysclk[aif]) {
1735 case WM8994_SYSCLK_MCLK1:
1736 rate = wm8994->mclk[0];
1737 break;
1738
1739 case WM8994_SYSCLK_MCLK2:
1740 reg1 |= 0x8;
1741 rate = wm8994->mclk[1];
1742 break;
1743
1744 case WM8994_SYSCLK_FLL1:
1745 reg1 |= 0x10;
1746 rate = wm8994->fll[0].out;
1747 break;
1748
1749 case WM8994_SYSCLK_FLL2:
1750 reg1 |= 0x18;
1751 rate = wm8994->fll[1].out;
1752 break;
1753
1754 default:
1755 return -EINVAL;
1756 }
1757
1758 if (rate >= 13500000) {
1759 rate /= 2;
1760 reg1 |= WM8994_AIF1CLK_DIV;
1761
1762 dev_dbg(codec->dev, "Dividing AIF%d clock to %dHz\n",
1763 aif + 1, rate);
1764 }
1765 wm8994->aifclk[aif] = rate;
1766
1767 snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1 + offset,
1768 WM8994_AIF1CLK_SRC_MASK | WM8994_AIF1CLK_DIV,
1769 reg1);
1770
1771 return 0;
1772}
1773
1774static int configure_clock(struct snd_soc_codec *codec)
1775{
1776 struct wm8994_priv *wm8994 = codec->private_data;
1777 int old, new;
1778
1779 /* Bring up the AIF clocks first */
1780 configure_aif_clock(codec, 0);
1781 configure_aif_clock(codec, 1);
1782
1783 /* Then switch CLK_SYS over to the higher of them; a change
1784 * can only happen as a result of a clocking change which can
1785 * only be made outside of DAPM so we can safely redo the
1786 * clocking.
1787 */
1788
1789 /* If they're equal it doesn't matter which is used */
1790 if (wm8994->aifclk[0] == wm8994->aifclk[1])
1791 return 0;
1792
1793 if (wm8994->aifclk[0] < wm8994->aifclk[1])
1794 new = WM8994_SYSCLK_SRC;
1795 else
1796 new = 0;
1797
1798 old = snd_soc_read(codec, WM8994_CLOCKING_1) & WM8994_SYSCLK_SRC;
1799
1800 /* If there's no change then we're done. */
1801 if (old == new)
1802 return 0;
1803
1804 snd_soc_update_bits(codec, WM8994_CLOCKING_1, WM8994_SYSCLK_SRC, new);
1805
1806 snd_soc_dapm_sync(codec);
1807
1808 return 0;
1809}
1810
1811static int check_clk_sys(struct snd_soc_dapm_widget *source,
1812 struct snd_soc_dapm_widget *sink)
1813{
1814 int reg = snd_soc_read(source->codec, WM8994_CLOCKING_1);
1815 const char *clk;
1816
1817 /* Check what we're currently using for CLK_SYS */
1818 if (reg & WM8994_SYSCLK_SRC)
1819 clk = "AIF2CLK";
1820 else
1821 clk = "AIF1CLK";
1822
1823 return strcmp(source->name, clk) == 0;
1824}
1825
1826static const char *sidetone_hpf_text[] = {
1827 "2.7kHz", "1.35kHz", "675Hz", "370Hz", "180Hz", "90Hz", "45Hz"
1828};
1829
1830static const struct soc_enum sidetone_hpf =
1831 SOC_ENUM_SINGLE(WM8994_SIDETONE, 7, 7, sidetone_hpf_text);
1832
1833static const DECLARE_TLV_DB_SCALE(aif_tlv, 0, 600, 0);
1834static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
1835static const DECLARE_TLV_DB_SCALE(st_tlv, -3600, 300, 0);
1836static const DECLARE_TLV_DB_SCALE(wm8994_3d_tlv, -1600, 183, 0);
1837static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
1838
1839#define WM8994_DRC_SWITCH(xname, reg, shift) \
1840{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
1841 .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\
1842 .put = wm8994_put_drc_sw, \
1843 .private_value = SOC_SINGLE_VALUE(reg, shift, 1, 0) }
1844
1845static int wm8994_put_drc_sw(struct snd_kcontrol *kcontrol,
1846 struct snd_ctl_elem_value *ucontrol)
1847{
1848 struct soc_mixer_control *mc =
1849 (struct soc_mixer_control *)kcontrol->private_value;
1850 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1851 int mask, ret;
1852
1853 /* Can't enable both ADC and DAC paths simultaneously */
1854 if (mc->shift == WM8994_AIF1DAC1_DRC_ENA_SHIFT)
1855 mask = WM8994_AIF1ADC1L_DRC_ENA_MASK |
1856 WM8994_AIF1ADC1R_DRC_ENA_MASK;
1857 else
1858 mask = WM8994_AIF1DAC1_DRC_ENA_MASK;
1859
1860 ret = snd_soc_read(codec, mc->reg);
1861 if (ret < 0)
1862 return ret;
1863 if (ret & mask)
1864 return -EINVAL;
1865
1866 return snd_soc_put_volsw(kcontrol, ucontrol);
1867}
1868
1869
1870
1871static void wm8994_set_drc(struct snd_soc_codec *codec, int drc)
1872{
1873 struct wm8994_priv *wm8994 = codec->private_data;
1874 struct wm8994_pdata *pdata = wm8994->pdata;
1875 int base = wm8994_drc_base[drc];
1876 int cfg = wm8994->drc_cfg[drc];
1877 int save, i;
1878
1879 /* Save any enables; the configuration should clear them. */
1880 save = snd_soc_read(codec, base);
1881 save &= WM8994_AIF1DAC1_DRC_ENA | WM8994_AIF1ADC1L_DRC_ENA |
1882 WM8994_AIF1ADC1R_DRC_ENA;
1883
1884 for (i = 0; i < WM8994_DRC_REGS; i++)
1885 snd_soc_update_bits(codec, base + i, 0xffff,
1886 pdata->drc_cfgs[cfg].regs[i]);
1887
1888 snd_soc_update_bits(codec, base, WM8994_AIF1DAC1_DRC_ENA |
1889 WM8994_AIF1ADC1L_DRC_ENA |
1890 WM8994_AIF1ADC1R_DRC_ENA, save);
1891}
1892
1893/* Icky as hell but saves code duplication */
1894static int wm8994_get_drc(const char *name)
1895{
1896 if (strcmp(name, "AIF1DRC1 Mode") == 0)
1897 return 0;
1898 if (strcmp(name, "AIF1DRC2 Mode") == 0)
1899 return 1;
1900 if (strcmp(name, "AIF2DRC Mode") == 0)
1901 return 2;
1902 return -EINVAL;
1903}
1904
1905static int wm8994_put_drc_enum(struct snd_kcontrol *kcontrol,
1906 struct snd_ctl_elem_value *ucontrol)
1907{
1908 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1909 struct wm8994_priv *wm8994 = codec->private_data;
1910 struct wm8994_pdata *pdata = wm8994->pdata;
1911 int drc = wm8994_get_drc(kcontrol->id.name);
1912 int value = ucontrol->value.integer.value[0];
1913
1914 if (drc < 0)
1915 return drc;
1916
1917 if (value >= pdata->num_drc_cfgs)
1918 return -EINVAL;
1919
1920 wm8994->drc_cfg[drc] = value;
1921
1922 wm8994_set_drc(codec, drc);
1923
1924 return 0;
1925}
1926
1927static int wm8994_get_drc_enum(struct snd_kcontrol *kcontrol,
1928 struct snd_ctl_elem_value *ucontrol)
1929{
1930 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1931 struct wm8994_priv *wm8994 = codec->private_data;
1932 int drc = wm8994_get_drc(kcontrol->id.name);
1933
1934 ucontrol->value.enumerated.item[0] = wm8994->drc_cfg[drc];
1935
1936 return 0;
1937}
1938
1939static void wm8994_set_retune_mobile(struct snd_soc_codec *codec, int block)
1940{
1941 struct wm8994_priv *wm8994 = codec->private_data;
1942 struct wm8994_pdata *pdata = wm8994->pdata;
1943 int base = wm8994_retune_mobile_base[block];
1944 int iface, best, best_val, save, i, cfg;
1945
1946 if (!pdata || !wm8994->num_retune_mobile_texts)
1947 return;
1948
1949 switch (block) {
1950 case 0:
1951 case 1:
1952 iface = 0;
1953 break;
1954 case 2:
1955 iface = 1;
1956 break;
1957 default:
1958 return;
1959 }
1960
1961 /* Find the version of the currently selected configuration
1962 * with the nearest sample rate. */
1963 cfg = wm8994->retune_mobile_cfg[block];
1964 best = 0;
1965 best_val = INT_MAX;
1966 for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) {
1967 if (strcmp(pdata->retune_mobile_cfgs[i].name,
1968 wm8994->retune_mobile_texts[cfg]) == 0 &&
1969 abs(pdata->retune_mobile_cfgs[i].rate
1970 - wm8994->dac_rates[iface]) < best_val) {
1971 best = i;
1972 best_val = abs(pdata->retune_mobile_cfgs[i].rate
1973 - wm8994->dac_rates[iface]);
1974 }
1975 }
1976
1977 dev_dbg(codec->dev, "ReTune Mobile %d %s/%dHz for %dHz sample rate\n",
1978 block,
1979 pdata->retune_mobile_cfgs[best].name,
1980 pdata->retune_mobile_cfgs[best].rate,
1981 wm8994->dac_rates[iface]);
1982
1983 /* The EQ will be disabled while reconfiguring it, remember the
1984 * current configuration.
1985 */
1986 save = snd_soc_read(codec, base);
1987 save &= WM8994_AIF1DAC1_EQ_ENA;
1988
1989 for (i = 0; i < WM8994_EQ_REGS; i++)
1990 snd_soc_update_bits(codec, base + i, 0xffff,
1991 pdata->retune_mobile_cfgs[best].regs[i]);
1992
1993 snd_soc_update_bits(codec, base, WM8994_AIF1DAC1_EQ_ENA, save);
1994}
1995
1996/* Icky as hell but saves code duplication */
1997static int wm8994_get_retune_mobile_block(const char *name)
1998{
1999 if (strcmp(name, "AIF1.1 EQ Mode") == 0)
2000 return 0;
2001 if (strcmp(name, "AIF1.2 EQ Mode") == 0)
2002 return 1;
2003 if (strcmp(name, "AIF2 EQ Mode") == 0)
2004 return 2;
2005 return -EINVAL;
2006}
2007
2008static int wm8994_put_retune_mobile_enum(struct snd_kcontrol *kcontrol,
2009 struct snd_ctl_elem_value *ucontrol)
2010{
2011 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2012 struct wm8994_priv *wm8994 = codec->private_data;
2013 struct wm8994_pdata *pdata = wm8994->pdata;
2014 int block = wm8994_get_retune_mobile_block(kcontrol->id.name);
2015 int value = ucontrol->value.integer.value[0];
2016
2017 if (block < 0)
2018 return block;
2019
2020 if (value >= pdata->num_retune_mobile_cfgs)
2021 return -EINVAL;
2022
2023 wm8994->retune_mobile_cfg[block] = value;
2024
2025 wm8994_set_retune_mobile(codec, block);
2026
2027 return 0;
2028}
2029
2030static int wm8994_get_retune_mobile_enum(struct snd_kcontrol *kcontrol,
2031 struct snd_ctl_elem_value *ucontrol)
2032{
2033 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2034 struct wm8994_priv *wm8994 = codec->private_data;
2035 int block = wm8994_get_retune_mobile_block(kcontrol->id.name);
2036
2037 ucontrol->value.enumerated.item[0] = wm8994->retune_mobile_cfg[block];
2038
2039 return 0;
2040}
2041
2042static const struct snd_kcontrol_new wm8994_snd_controls[] = {
2043SOC_DOUBLE_R_TLV("AIF1ADC1 Volume", WM8994_AIF1_ADC1_LEFT_VOLUME,
2044 WM8994_AIF1_ADC1_RIGHT_VOLUME,
2045 1, 119, 0, digital_tlv),
2046SOC_DOUBLE_R_TLV("AIF1ADC2 Volume", WM8994_AIF1_ADC2_LEFT_VOLUME,
2047 WM8994_AIF1_ADC2_RIGHT_VOLUME,
2048 1, 119, 0, digital_tlv),
2049SOC_DOUBLE_R_TLV("AIF2ADC Volume", WM8994_AIF2_ADC_LEFT_VOLUME,
2050 WM8994_AIF2_ADC_RIGHT_VOLUME,
2051 1, 119, 0, digital_tlv),
2052
2053SOC_DOUBLE_R_TLV("AIF1DAC1 Volume", WM8994_AIF1_DAC1_LEFT_VOLUME,
2054 WM8994_AIF1_DAC1_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
2055SOC_DOUBLE_R_TLV("AIF1DAC2 Volume", WM8994_AIF1_DAC2_LEFT_VOLUME,
2056 WM8994_AIF1_DAC2_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
2057SOC_DOUBLE_R_TLV("AIF2DAC Volume", WM8994_AIF2_DAC_LEFT_VOLUME,
2058 WM8994_AIF2_DAC_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
2059
2060SOC_SINGLE_TLV("AIF1 Boost Volume", WM8994_AIF1_CONTROL_2, 10, 3, 0, aif_tlv),
2061SOC_SINGLE_TLV("AIF2 Boost Volume", WM8994_AIF2_CONTROL_2, 10, 3, 0, aif_tlv),
2062
2063SOC_SINGLE("AIF1DAC1 EQ Switch", WM8994_AIF1_DAC1_EQ_GAINS_1, 0, 1, 0),
2064SOC_SINGLE("AIF1DAC2 EQ Switch", WM8994_AIF1_DAC2_EQ_GAINS_1, 0, 1, 0),
2065SOC_SINGLE("AIF2 EQ Switch", WM8994_AIF2_EQ_GAINS_1, 0, 1, 0),
2066
2067WM8994_DRC_SWITCH("AIF1DAC1 DRC Switch", WM8994_AIF1_DRC1_1, 2),
2068WM8994_DRC_SWITCH("AIF1ADC1L DRC Switch", WM8994_AIF1_DRC1_1, 1),
2069WM8994_DRC_SWITCH("AIF1ADC1R DRC Switch", WM8994_AIF1_DRC1_1, 0),
2070
2071WM8994_DRC_SWITCH("AIF1DAC2 DRC Switch", WM8994_AIF1_DRC2_1, 2),
2072WM8994_DRC_SWITCH("AIF1ADC2L DRC Switch", WM8994_AIF1_DRC2_1, 1),
2073WM8994_DRC_SWITCH("AIF1ADC2R DRC Switch", WM8994_AIF1_DRC2_1, 0),
2074
2075WM8994_DRC_SWITCH("AIF2DAC DRC Switch", WM8994_AIF2_DRC_1, 2),
2076WM8994_DRC_SWITCH("AIF2ADCL DRC Switch", WM8994_AIF2_DRC_1, 1),
2077WM8994_DRC_SWITCH("AIF2ADCR DRC Switch", WM8994_AIF2_DRC_1, 0),
2078
2079SOC_SINGLE_TLV("DAC1 Right Sidetone Volume", WM8994_DAC1_MIXER_VOLUMES,
2080 5, 12, 0, st_tlv),
2081SOC_SINGLE_TLV("DAC1 Left Sidetone Volume", WM8994_DAC1_MIXER_VOLUMES,
2082 0, 12, 0, st_tlv),
2083SOC_SINGLE_TLV("DAC2 Right Sidetone Volume", WM8994_DAC2_MIXER_VOLUMES,
2084 5, 12, 0, st_tlv),
2085SOC_SINGLE_TLV("DAC2 Left Sidetone Volume", WM8994_DAC2_MIXER_VOLUMES,
2086 0, 12, 0, st_tlv),
2087SOC_ENUM("Sidetone HPF Mux", sidetone_hpf),
2088SOC_SINGLE("Sidetone HPF Switch", WM8994_SIDETONE, 6, 1, 0),
2089
2090SOC_DOUBLE_R_TLV("DAC1 Volume", WM8994_DAC1_LEFT_VOLUME,
2091 WM8994_DAC1_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
2092SOC_DOUBLE_R("DAC1 Switch", WM8994_DAC1_LEFT_VOLUME,
2093 WM8994_DAC1_RIGHT_VOLUME, 9, 1, 1),
2094
2095SOC_DOUBLE_R_TLV("DAC2 Volume", WM8994_DAC2_LEFT_VOLUME,
2096 WM8994_DAC2_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
2097SOC_DOUBLE_R("DAC2 Switch", WM8994_DAC2_LEFT_VOLUME,
2098 WM8994_DAC2_RIGHT_VOLUME, 9, 1, 1),
2099
2100SOC_SINGLE_TLV("SPKL DAC2 Volume", WM8994_SPKMIXL_ATTENUATION,
2101 6, 1, 1, wm_hubs_spkmix_tlv),
2102SOC_SINGLE_TLV("SPKL DAC1 Volume", WM8994_SPKMIXL_ATTENUATION,
2103 2, 1, 1, wm_hubs_spkmix_tlv),
2104
2105SOC_SINGLE_TLV("SPKR DAC2 Volume", WM8994_SPKMIXR_ATTENUATION,
2106 6, 1, 1, wm_hubs_spkmix_tlv),
2107SOC_SINGLE_TLV("SPKR DAC1 Volume", WM8994_SPKMIXR_ATTENUATION,
2108 2, 1, 1, wm_hubs_spkmix_tlv),
2109
2110SOC_SINGLE_TLV("AIF1DAC1 3D Stereo Volume", WM8994_AIF1_DAC1_FILTERS_2,
2111 10, 15, 0, wm8994_3d_tlv),
2112SOC_SINGLE("AIF1DAC1 3D Stereo Switch", WM8994_AIF1_DAC2_FILTERS_2,
2113 8, 1, 0),
2114SOC_SINGLE_TLV("AIF1DAC2 3D Stereo Volume", WM8994_AIF1_DAC2_FILTERS_2,
2115 10, 15, 0, wm8994_3d_tlv),
2116SOC_SINGLE("AIF1DAC2 3D Stereo Switch", WM8994_AIF1_DAC2_FILTERS_2,
2117 8, 1, 0),
2118SOC_SINGLE_TLV("AIF2DAC 3D Stereo Volume", WM8994_AIF1_DAC1_FILTERS_2,
2119 10, 15, 0, wm8994_3d_tlv),
2120SOC_SINGLE("AIF2DAC 3D Stereo Switch", WM8994_AIF1_DAC2_FILTERS_2,
2121 8, 1, 0),
2122};
2123
2124static const struct snd_kcontrol_new wm8994_eq_controls[] = {
2125SOC_SINGLE_TLV("AIF1DAC1 EQ1 Volume", WM8994_AIF1_DAC1_EQ_GAINS_1, 11, 31, 0,
2126 eq_tlv),
2127SOC_SINGLE_TLV("AIF1DAC1 EQ2 Volume", WM8994_AIF1_DAC1_EQ_GAINS_1, 6, 31, 0,
2128 eq_tlv),
2129SOC_SINGLE_TLV("AIF1DAC1 EQ3 Volume", WM8994_AIF1_DAC1_EQ_GAINS_1, 1, 31, 0,
2130 eq_tlv),
2131SOC_SINGLE_TLV("AIF1DAC1 EQ4 Volume", WM8994_AIF1_DAC1_EQ_GAINS_2, 11, 31, 0,
2132 eq_tlv),
2133SOC_SINGLE_TLV("AIF1DAC1 EQ5 Volume", WM8994_AIF1_DAC1_EQ_GAINS_2, 6, 31, 0,
2134 eq_tlv),
2135
2136SOC_SINGLE_TLV("AIF1DAC2 EQ1 Volume", WM8994_AIF1_DAC2_EQ_GAINS_1, 11, 31, 0,
2137 eq_tlv),
2138SOC_SINGLE_TLV("AIF1DAC2 EQ2 Volume", WM8994_AIF1_DAC2_EQ_GAINS_1, 6, 31, 0,
2139 eq_tlv),
2140SOC_SINGLE_TLV("AIF1DAC2 EQ3 Volume", WM8994_AIF1_DAC2_EQ_GAINS_1, 1, 31, 0,
2141 eq_tlv),
2142SOC_SINGLE_TLV("AIF1DAC2 EQ4 Volume", WM8994_AIF1_DAC2_EQ_GAINS_2, 11, 31, 0,
2143 eq_tlv),
2144SOC_SINGLE_TLV("AIF1DAC2 EQ5 Volume", WM8994_AIF1_DAC2_EQ_GAINS_2, 6, 31, 0,
2145 eq_tlv),
2146
2147SOC_SINGLE_TLV("AIF2 EQ1 Volume", WM8994_AIF2_EQ_GAINS_1, 11, 31, 0,
2148 eq_tlv),
2149SOC_SINGLE_TLV("AIF2 EQ2 Volume", WM8994_AIF2_EQ_GAINS_1, 6, 31, 0,
2150 eq_tlv),
2151SOC_SINGLE_TLV("AIF2 EQ3 Volume", WM8994_AIF2_EQ_GAINS_1, 1, 31, 0,
2152 eq_tlv),
2153SOC_SINGLE_TLV("AIF2 EQ4 Volume", WM8994_AIF2_EQ_GAINS_2, 11, 31, 0,
2154 eq_tlv),
2155SOC_SINGLE_TLV("AIF2 EQ5 Volume", WM8994_AIF2_EQ_GAINS_2, 6, 31, 0,
2156 eq_tlv),
2157};
2158
2159static int clk_sys_event(struct snd_soc_dapm_widget *w,
2160 struct snd_kcontrol *kcontrol, int event)
2161{
2162 struct snd_soc_codec *codec = w->codec;
2163
2164 switch (event) {
2165 case SND_SOC_DAPM_PRE_PMU:
2166 return configure_clock(codec);
2167
2168 case SND_SOC_DAPM_POST_PMD:
2169 configure_clock(codec);
2170 break;
2171 }
2172
2173 return 0;
2174}
2175
2176static void wm8994_update_class_w(struct snd_soc_codec *codec)
2177{
2178 int enable = 1;
2179 int source = 0; /* GCC flow analysis can't track enable */
2180 int reg, reg_r;
2181
2182 /* Only support direct DAC->headphone paths */
2183 reg = snd_soc_read(codec, WM8994_OUTPUT_MIXER_1);
2184 if (!(reg & WM8994_DAC1L_TO_HPOUT1L)) {
2185 dev_dbg(codec->dev, "HPL connected to output mixer\n");
2186 enable = 0;
2187 }
2188
2189 reg = snd_soc_read(codec, WM8994_OUTPUT_MIXER_2);
2190 if (!(reg & WM8994_DAC1R_TO_HPOUT1R)) {
2191 dev_dbg(codec->dev, "HPR connected to output mixer\n");
2192 enable = 0;
2193 }
2194
2195 /* We also need the same setting for L/R and only one path */
2196 reg = snd_soc_read(codec, WM8994_DAC1_LEFT_MIXER_ROUTING);
2197 switch (reg) {
2198 case WM8994_AIF2DACL_TO_DAC1L:
2199 dev_dbg(codec->dev, "Class W source AIF2DAC\n");
2200 source = 2 << WM8994_CP_DYN_SRC_SEL_SHIFT;
2201 break;
2202 case WM8994_AIF1DAC2L_TO_DAC1L:
2203 dev_dbg(codec->dev, "Class W source AIF1DAC2\n");
2204 source = 1 << WM8994_CP_DYN_SRC_SEL_SHIFT;
2205 break;
2206 case WM8994_AIF1DAC1L_TO_DAC1L:
2207 dev_dbg(codec->dev, "Class W source AIF1DAC1\n");
2208 source = 0 << WM8994_CP_DYN_SRC_SEL_SHIFT;
2209 break;
2210 default:
2211 dev_dbg(codec->dev, "DAC mixer setting: %x\n", reg);
2212 enable = 0;
2213 break;
2214 }
2215
2216 reg_r = snd_soc_read(codec, WM8994_DAC1_RIGHT_MIXER_ROUTING);
2217 if (reg_r != reg) {
2218 dev_dbg(codec->dev, "Left and right DAC mixers different\n");
2219 enable = 0;
2220 }
2221
2222 if (enable) {
2223 dev_dbg(codec->dev, "Class W enabled\n");
2224 snd_soc_update_bits(codec, WM8994_CLASS_W_1,
2225 WM8994_CP_DYN_PWR |
2226 WM8994_CP_DYN_SRC_SEL_MASK,
2227 source | WM8994_CP_DYN_PWR);
2228
2229 } else {
2230 dev_dbg(codec->dev, "Class W disabled\n");
2231 snd_soc_update_bits(codec, WM8994_CLASS_W_1,
2232 WM8994_CP_DYN_PWR, 0);
2233 }
2234}
2235
2236static const char *hp_mux_text[] = {
2237 "Mixer",
2238 "DAC",
2239};
2240
2241#define WM8994_HP_ENUM(xname, xenum) \
2242{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
2243 .info = snd_soc_info_enum_double, \
2244 .get = snd_soc_dapm_get_enum_double, \
2245 .put = wm8994_put_hp_enum, \
2246 .private_value = (unsigned long)&xenum }
2247
2248static int wm8994_put_hp_enum(struct snd_kcontrol *kcontrol,
2249 struct snd_ctl_elem_value *ucontrol)
2250{
2251 struct snd_soc_dapm_widget *w = snd_kcontrol_chip(kcontrol);
2252 struct snd_soc_codec *codec = w->codec;
2253 int ret;
2254
2255 ret = snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
2256
2257 wm8994_update_class_w(codec);
2258
2259 return ret;
2260}
2261
2262static const struct soc_enum hpl_enum =
2263 SOC_ENUM_SINGLE(WM8994_OUTPUT_MIXER_1, 8, 2, hp_mux_text);
2264
2265static const struct snd_kcontrol_new hpl_mux =
2266 WM8994_HP_ENUM("Left Headphone Mux", hpl_enum);
2267
2268static const struct soc_enum hpr_enum =
2269 SOC_ENUM_SINGLE(WM8994_OUTPUT_MIXER_2, 8, 2, hp_mux_text);
2270
2271static const struct snd_kcontrol_new hpr_mux =
2272 WM8994_HP_ENUM("Right Headphone Mux", hpr_enum);
2273
2274static const char *adc_mux_text[] = {
2275 "ADC",
2276 "DMIC",
2277};
2278
2279static const struct soc_enum adc_enum =
2280 SOC_ENUM_SINGLE(0, 0, 2, adc_mux_text);
2281
2282static const struct snd_kcontrol_new adcl_mux =
2283 SOC_DAPM_ENUM_VIRT("ADCL Mux", adc_enum);
2284
2285static const struct snd_kcontrol_new adcr_mux =
2286 SOC_DAPM_ENUM_VIRT("ADCR Mux", adc_enum);
2287
2288static const struct snd_kcontrol_new left_speaker_mixer[] = {
2289SOC_DAPM_SINGLE("DAC2 Switch", WM8994_SPEAKER_MIXER, 9, 1, 0),
2290SOC_DAPM_SINGLE("Input Switch", WM8994_SPEAKER_MIXER, 7, 1, 0),
2291SOC_DAPM_SINGLE("IN1LP Switch", WM8994_SPEAKER_MIXER, 5, 1, 0),
2292SOC_DAPM_SINGLE("Output Switch", WM8994_SPEAKER_MIXER, 3, 1, 0),
2293SOC_DAPM_SINGLE("DAC1 Switch", WM8994_SPEAKER_MIXER, 1, 1, 0),
2294};
2295
2296static const struct snd_kcontrol_new right_speaker_mixer[] = {
2297SOC_DAPM_SINGLE("DAC2 Switch", WM8994_SPEAKER_MIXER, 8, 1, 0),
2298SOC_DAPM_SINGLE("Input Switch", WM8994_SPEAKER_MIXER, 6, 1, 0),
2299SOC_DAPM_SINGLE("IN1RP Switch", WM8994_SPEAKER_MIXER, 4, 1, 0),
2300SOC_DAPM_SINGLE("Output Switch", WM8994_SPEAKER_MIXER, 2, 1, 0),
2301SOC_DAPM_SINGLE("DAC1 Switch", WM8994_SPEAKER_MIXER, 0, 1, 0),
2302};
2303
2304/* Debugging; dump chip status after DAPM transitions */
2305static int post_ev(struct snd_soc_dapm_widget *w,
2306 struct snd_kcontrol *kcontrol, int event)
2307{
2308 struct snd_soc_codec *codec = w->codec;
2309 dev_dbg(codec->dev, "SRC status: %x\n",
2310 snd_soc_read(codec,
2311 WM8994_RATE_STATUS));
2312 return 0;
2313}
2314
2315static const struct snd_kcontrol_new aif1adc1l_mix[] = {
2316SOC_DAPM_SINGLE("ADC/DMIC Switch", WM8994_AIF1_ADC1_LEFT_MIXER_ROUTING,
2317 1, 1, 0),
2318SOC_DAPM_SINGLE("AIF2 Switch", WM8994_AIF1_ADC1_LEFT_MIXER_ROUTING,
2319 0, 1, 0),
2320};
2321
2322static const struct snd_kcontrol_new aif1adc1r_mix[] = {
2323SOC_DAPM_SINGLE("ADC/DMIC Switch", WM8994_AIF1_ADC1_RIGHT_MIXER_ROUTING,
2324 1, 1, 0),
2325SOC_DAPM_SINGLE("AIF2 Switch", WM8994_AIF1_ADC1_RIGHT_MIXER_ROUTING,
2326 0, 1, 0),
2327};
2328
2329static const struct snd_kcontrol_new aif2dac2l_mix[] = {
2330SOC_DAPM_SINGLE("Right Sidetone Switch", WM8994_DAC2_LEFT_MIXER_ROUTING,
2331 5, 1, 0),
2332SOC_DAPM_SINGLE("Left Sidetone Switch", WM8994_DAC2_LEFT_MIXER_ROUTING,
2333 4, 1, 0),
2334SOC_DAPM_SINGLE("AIF2 Switch", WM8994_DAC2_LEFT_MIXER_ROUTING,
2335 2, 1, 0),
2336SOC_DAPM_SINGLE("AIF1.2 Switch", WM8994_DAC2_LEFT_MIXER_ROUTING,
2337 1, 1, 0),
2338SOC_DAPM_SINGLE("AIF1.1 Switch", WM8994_DAC2_LEFT_MIXER_ROUTING,
2339 0, 1, 0),
2340};
2341
2342static const struct snd_kcontrol_new aif2dac2r_mix[] = {
2343SOC_DAPM_SINGLE("Right Sidetone Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING,
2344 5, 1, 0),
2345SOC_DAPM_SINGLE("Left Sidetone Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING,
2346 4, 1, 0),
2347SOC_DAPM_SINGLE("AIF2 Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING,
2348 2, 1, 0),
2349SOC_DAPM_SINGLE("AIF1.2 Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING,
2350 1, 1, 0),
2351SOC_DAPM_SINGLE("AIF1.1 Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING,
2352 0, 1, 0),
2353};
2354
2355#define WM8994_CLASS_W_SWITCH(xname, reg, shift, max, invert) \
2356{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
2357 .info = snd_soc_info_volsw, \
2358 .get = snd_soc_dapm_get_volsw, .put = wm8994_put_class_w, \
2359 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
2360
2361static int wm8994_put_class_w(struct snd_kcontrol *kcontrol,
2362 struct snd_ctl_elem_value *ucontrol)
2363{
2364 struct snd_soc_dapm_widget *w = snd_kcontrol_chip(kcontrol);
2365 struct snd_soc_codec *codec = w->codec;
2366 int ret;
2367
2368 ret = snd_soc_dapm_put_volsw(kcontrol, ucontrol);
2369
2370 wm8994_update_class_w(codec);
2371
2372 return ret;
2373}
2374
2375static const struct snd_kcontrol_new dac1l_mix[] = {
2376WM8994_CLASS_W_SWITCH("Right Sidetone Switch", WM8994_DAC1_LEFT_MIXER_ROUTING,
2377 5, 1, 0),
2378WM8994_CLASS_W_SWITCH("Left Sidetone Switch", WM8994_DAC1_LEFT_MIXER_ROUTING,
2379 4, 1, 0),
2380WM8994_CLASS_W_SWITCH("AIF2 Switch", WM8994_DAC1_LEFT_MIXER_ROUTING,
2381 2, 1, 0),
2382WM8994_CLASS_W_SWITCH("AIF1.2 Switch", WM8994_DAC1_LEFT_MIXER_ROUTING,
2383 1, 1, 0),
2384WM8994_CLASS_W_SWITCH("AIF1.1 Switch", WM8994_DAC1_LEFT_MIXER_ROUTING,
2385 0, 1, 0),
2386};
2387
2388static const struct snd_kcontrol_new dac1r_mix[] = {
2389WM8994_CLASS_W_SWITCH("Right Sidetone Switch", WM8994_DAC1_RIGHT_MIXER_ROUTING,
2390 5, 1, 0),
2391WM8994_CLASS_W_SWITCH("Left Sidetone Switch", WM8994_DAC1_RIGHT_MIXER_ROUTING,
2392 4, 1, 0),
2393WM8994_CLASS_W_SWITCH("AIF2 Switch", WM8994_DAC1_RIGHT_MIXER_ROUTING,
2394 2, 1, 0),
2395WM8994_CLASS_W_SWITCH("AIF1.2 Switch", WM8994_DAC1_RIGHT_MIXER_ROUTING,
2396 1, 1, 0),
2397WM8994_CLASS_W_SWITCH("AIF1.1 Switch", WM8994_DAC1_RIGHT_MIXER_ROUTING,
2398 0, 1, 0),
2399};
2400
2401static const char *sidetone_text[] = {
2402 "ADC/DMIC1", "DMIC2",
2403};
2404
2405static const struct soc_enum sidetone1_enum =
2406 SOC_ENUM_SINGLE(WM8994_SIDETONE, 0, 2, sidetone_text);
2407
2408static const struct snd_kcontrol_new sidetone1_mux =
2409 SOC_DAPM_ENUM("Left Sidetone Mux", sidetone1_enum);
2410
2411static const struct soc_enum sidetone2_enum =
2412 SOC_ENUM_SINGLE(WM8994_SIDETONE, 1, 2, sidetone_text);
2413
2414static const struct snd_kcontrol_new sidetone2_mux =
2415 SOC_DAPM_ENUM("Right Sidetone Mux", sidetone2_enum);
2416
2417static const char *aif1dac_text[] = {
2418 "AIF1DACDAT", "AIF3DACDAT",
2419};
2420
2421static const struct soc_enum aif1dac_enum =
2422 SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 0, 2, aif1dac_text);
2423
2424static const struct snd_kcontrol_new aif1dac_mux =
2425 SOC_DAPM_ENUM("AIF1DAC Mux", aif1dac_enum);
2426
2427static const char *aif2dac_text[] = {
2428 "AIF2DACDAT", "AIF3DACDAT",
2429};
2430
2431static const struct soc_enum aif2dac_enum =
2432 SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 1, 2, aif2dac_text);
2433
2434static const struct snd_kcontrol_new aif2dac_mux =
2435 SOC_DAPM_ENUM("AIF2DAC Mux", aif2dac_enum);
2436
2437static const char *aif2adc_text[] = {
2438 "AIF2ADCDAT", "AIF3DACDAT",
2439};
2440
2441static const struct soc_enum aif2adc_enum =
2442 SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 2, 2, aif2adc_text);
2443
2444static const struct snd_kcontrol_new aif2adc_mux =
2445 SOC_DAPM_ENUM("AIF2ADC Mux", aif2adc_enum);
2446
2447static const char *aif3adc_text[] = {
2448 "AIF1ADCDAT", "AIF2ADCDAT", "AIF2DACDAT",
2449};
2450
2451static const struct soc_enum aif3adc_enum =
2452 SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 3, 3, aif3adc_text);
2453
2454static const struct snd_kcontrol_new aif3adc_mux =
2455 SOC_DAPM_ENUM("AIF3ADC Mux", aif3adc_enum);
2456
2457static const struct snd_soc_dapm_widget wm8994_dapm_widgets[] = {
2458SND_SOC_DAPM_INPUT("DMIC1DAT"),
2459SND_SOC_DAPM_INPUT("DMIC2DAT"),
2460
2461SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event,
2462 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
2463
2464SND_SOC_DAPM_SUPPLY("DSP1CLK", WM8994_CLOCKING_1, 3, 0, NULL, 0),
2465SND_SOC_DAPM_SUPPLY("DSP2CLK", WM8994_CLOCKING_1, 2, 0, NULL, 0),
2466SND_SOC_DAPM_SUPPLY("DSPINTCLK", WM8994_CLOCKING_1, 1, 0, NULL, 0),
2467
2468SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8994_AIF1_CLOCKING_1, 0, 0, NULL, 0),
2469SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8994_AIF2_CLOCKING_1, 0, 0, NULL, 0),
2470
2471SND_SOC_DAPM_AIF_OUT("AIF1ADC1L", "AIF1 Capture",
2472 0, WM8994_POWER_MANAGEMENT_4, 9, 0),
2473SND_SOC_DAPM_AIF_OUT("AIF1ADC1R", "AIF1 Capture",
2474 0, WM8994_POWER_MANAGEMENT_4, 8, 0),
2475SND_SOC_DAPM_AIF_IN("AIF1DAC1L", NULL, 0,
2476 WM8994_POWER_MANAGEMENT_5, 9, 0),
2477SND_SOC_DAPM_AIF_IN("AIF1DAC1R", NULL, 0,
2478 WM8994_POWER_MANAGEMENT_5, 8, 0),
2479
2480SND_SOC_DAPM_AIF_OUT("AIF1ADC2L", "AIF1 Capture",
2481 0, WM8994_POWER_MANAGEMENT_4, 11, 0),
2482SND_SOC_DAPM_AIF_OUT("AIF1ADC2R", "AIF1 Capture",
2483 0, WM8994_POWER_MANAGEMENT_4, 10, 0),
2484SND_SOC_DAPM_AIF_IN("AIF1DAC2L", NULL, 0,
2485 WM8994_POWER_MANAGEMENT_5, 11, 0),
2486SND_SOC_DAPM_AIF_IN("AIF1DAC2R", NULL, 0,
2487 WM8994_POWER_MANAGEMENT_5, 10, 0),
2488
2489SND_SOC_DAPM_MIXER("AIF1ADC1L Mixer", SND_SOC_NOPM, 0, 0,
2490 aif1adc1l_mix, ARRAY_SIZE(aif1adc1l_mix)),
2491SND_SOC_DAPM_MIXER("AIF1ADC1R Mixer", SND_SOC_NOPM, 0, 0,
2492 aif1adc1r_mix, ARRAY_SIZE(aif1adc1r_mix)),
2493
2494SND_SOC_DAPM_MIXER("AIF2DAC2L Mixer", SND_SOC_NOPM, 0, 0,
2495 aif2dac2l_mix, ARRAY_SIZE(aif2dac2l_mix)),
2496SND_SOC_DAPM_MIXER("AIF2DAC2R Mixer", SND_SOC_NOPM, 0, 0,
2497 aif2dac2r_mix, ARRAY_SIZE(aif2dac2r_mix)),
2498
2499SND_SOC_DAPM_MUX("Left Sidetone", SND_SOC_NOPM, 0, 0, &sidetone1_mux),
2500SND_SOC_DAPM_MUX("Right Sidetone", SND_SOC_NOPM, 0, 0, &sidetone2_mux),
2501
2502SND_SOC_DAPM_MIXER("DAC1L Mixer", SND_SOC_NOPM, 0, 0,
2503 dac1l_mix, ARRAY_SIZE(dac1l_mix)),
2504SND_SOC_DAPM_MIXER("DAC1R Mixer", SND_SOC_NOPM, 0, 0,
2505 dac1r_mix, ARRAY_SIZE(dac1r_mix)),
2506
2507SND_SOC_DAPM_AIF_OUT("AIF2ADCL", NULL, 0,
2508 WM8994_POWER_MANAGEMENT_4, 13, 0),
2509SND_SOC_DAPM_AIF_OUT("AIF2ADCR", NULL, 0,
2510 WM8994_POWER_MANAGEMENT_4, 12, 0),
2511SND_SOC_DAPM_AIF_IN("AIF2DACL", NULL, 0,
2512 WM8994_POWER_MANAGEMENT_5, 13, 0),
2513SND_SOC_DAPM_AIF_IN("AIF2DACR", NULL, 0,
2514 WM8994_POWER_MANAGEMENT_5, 12, 0),
2515
2516SND_SOC_DAPM_AIF_IN("AIF1DACDAT", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
2517SND_SOC_DAPM_AIF_IN("AIF2DACDAT", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0),
2518SND_SOC_DAPM_AIF_OUT("AIF2ADCDAT", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0),
2519
2520SND_SOC_DAPM_MUX("AIF1DAC Mux", SND_SOC_NOPM, 0, 0, &aif1dac_mux),
2521SND_SOC_DAPM_MUX("AIF2DAC Mux", SND_SOC_NOPM, 0, 0, &aif2dac_mux),
2522SND_SOC_DAPM_MUX("AIF2ADC Mux", SND_SOC_NOPM, 0, 0, &aif2adc_mux),
2523SND_SOC_DAPM_MUX("AIF3ADC Mux", SND_SOC_NOPM, 0, 0, &aif3adc_mux),
2524
2525SND_SOC_DAPM_AIF_IN("AIF3DACDAT", "AIF3 Playback", 0, SND_SOC_NOPM, 0, 0),
2526SND_SOC_DAPM_AIF_IN("AIF3ADCDAT", "AIF3 Capture", 0, SND_SOC_NOPM, 0, 0),
2527
2528SND_SOC_DAPM_SUPPLY("TOCLK", WM8994_CLOCKING_1, 4, 0, NULL, 0),
2529
2530SND_SOC_DAPM_ADC("DMIC2L", NULL, WM8994_POWER_MANAGEMENT_4, 5, 0),
2531SND_SOC_DAPM_ADC("DMIC2R", NULL, WM8994_POWER_MANAGEMENT_4, 4, 0),
2532SND_SOC_DAPM_ADC("DMIC1L", NULL, WM8994_POWER_MANAGEMENT_4, 3, 0),
2533SND_SOC_DAPM_ADC("DMIC1R", NULL, WM8994_POWER_MANAGEMENT_4, 2, 0),
2534
2535/* Power is done with the muxes since the ADC power also controls the
2536 * downsampling chain, the chip will automatically manage the analogue
2537 * specific portions.
2538 */
2539SND_SOC_DAPM_ADC("ADCL", NULL, SND_SOC_NOPM, 1, 0),
2540SND_SOC_DAPM_ADC("ADCR", NULL, SND_SOC_NOPM, 0, 0),
2541
2542SND_SOC_DAPM_MUX("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux),
2543SND_SOC_DAPM_MUX("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux),
2544
2545SND_SOC_DAPM_DAC("DAC2L", NULL, WM8994_POWER_MANAGEMENT_5, 3, 0),
2546SND_SOC_DAPM_DAC("DAC2R", NULL, WM8994_POWER_MANAGEMENT_5, 2, 0),
2547SND_SOC_DAPM_DAC("DAC1L", NULL, WM8994_POWER_MANAGEMENT_5, 1, 0),
2548SND_SOC_DAPM_DAC("DAC1R", NULL, WM8994_POWER_MANAGEMENT_5, 0, 0),
2549
2550SND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM, 0, 0, &hpl_mux),
2551SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0, &hpr_mux),
2552
2553SND_SOC_DAPM_MIXER("SPKL", WM8994_POWER_MANAGEMENT_3, 8, 0,
2554 left_speaker_mixer, ARRAY_SIZE(left_speaker_mixer)),
2555SND_SOC_DAPM_MIXER("SPKR", WM8994_POWER_MANAGEMENT_3, 9, 0,
2556 right_speaker_mixer, ARRAY_SIZE(right_speaker_mixer)),
2557
2558SND_SOC_DAPM_POST("Debug log", post_ev),
2559};
2560
2561static const struct snd_soc_dapm_route intercon[] = {
2562
2563 { "CLK_SYS", NULL, "AIF1CLK", check_clk_sys },
2564 { "CLK_SYS", NULL, "AIF2CLK", check_clk_sys },
2565
2566 { "DSP1CLK", NULL, "CLK_SYS" },
2567 { "DSP2CLK", NULL, "CLK_SYS" },
2568 { "DSPINTCLK", NULL, "CLK_SYS" },
2569
2570 { "AIF1ADC1L", NULL, "AIF1CLK" },
2571 { "AIF1ADC1L", NULL, "DSP1CLK" },
2572 { "AIF1ADC1R", NULL, "AIF1CLK" },
2573 { "AIF1ADC1R", NULL, "DSP1CLK" },
2574 { "AIF1ADC1R", NULL, "DSPINTCLK" },
2575
2576 { "AIF1DAC1L", NULL, "AIF1CLK" },
2577 { "AIF1DAC1L", NULL, "DSP1CLK" },
2578 { "AIF1DAC1R", NULL, "AIF1CLK" },
2579 { "AIF1DAC1R", NULL, "DSP1CLK" },
2580 { "AIF1DAC1R", NULL, "DSPINTCLK" },
2581
2582 { "AIF1ADC2L", NULL, "AIF1CLK" },
2583 { "AIF1ADC2L", NULL, "DSP1CLK" },
2584 { "AIF1ADC2R", NULL, "AIF1CLK" },
2585 { "AIF1ADC2R", NULL, "DSP1CLK" },
2586 { "AIF1ADC2R", NULL, "DSPINTCLK" },
2587
2588 { "AIF1DAC2L", NULL, "AIF1CLK" },
2589 { "AIF1DAC2L", NULL, "DSP1CLK" },
2590 { "AIF1DAC2R", NULL, "AIF1CLK" },
2591 { "AIF1DAC2R", NULL, "DSP1CLK" },
2592 { "AIF1DAC2R", NULL, "DSPINTCLK" },
2593
2594 { "AIF2ADCL", NULL, "AIF2CLK" },
2595 { "AIF2ADCL", NULL, "DSP2CLK" },
2596 { "AIF2ADCR", NULL, "AIF2CLK" },
2597 { "AIF2ADCR", NULL, "DSP2CLK" },
2598 { "AIF2ADCR", NULL, "DSPINTCLK" },
2599
2600 { "AIF2DACL", NULL, "AIF2CLK" },
2601 { "AIF2DACL", NULL, "DSP2CLK" },
2602 { "AIF2DACR", NULL, "AIF2CLK" },
2603 { "AIF2DACR", NULL, "DSP2CLK" },
2604 { "AIF2DACR", NULL, "DSPINTCLK" },
2605
2606 { "DMIC1L", NULL, "DMIC1DAT" },
2607 { "DMIC1L", NULL, "CLK_SYS" },
2608 { "DMIC1R", NULL, "DMIC1DAT" },
2609 { "DMIC1R", NULL, "CLK_SYS" },
2610 { "DMIC2L", NULL, "DMIC2DAT" },
2611 { "DMIC2L", NULL, "CLK_SYS" },
2612 { "DMIC2R", NULL, "DMIC2DAT" },
2613 { "DMIC2R", NULL, "CLK_SYS" },
2614
2615 { "ADCL", NULL, "AIF1CLK" },
2616 { "ADCL", NULL, "DSP1CLK" },
2617 { "ADCL", NULL, "DSPINTCLK" },
2618
2619 { "ADCR", NULL, "AIF1CLK" },
2620 { "ADCR", NULL, "DSP1CLK" },
2621 { "ADCR", NULL, "DSPINTCLK" },
2622
2623 { "ADCL Mux", "ADC", "ADCL" },
2624 { "ADCL Mux", "DMIC", "DMIC1L" },
2625 { "ADCR Mux", "ADC", "ADCR" },
2626 { "ADCR Mux", "DMIC", "DMIC1R" },
2627
2628 { "DAC1L", NULL, "AIF1CLK" },
2629 { "DAC1L", NULL, "DSP1CLK" },
2630 { "DAC1L", NULL, "DSPINTCLK" },
2631
2632 { "DAC1R", NULL, "AIF1CLK" },
2633 { "DAC1R", NULL, "DSP1CLK" },
2634 { "DAC1R", NULL, "DSPINTCLK" },
2635
2636 { "DAC2L", NULL, "AIF2CLK" },
2637 { "DAC2L", NULL, "DSP2CLK" },
2638 { "DAC2L", NULL, "DSPINTCLK" },
2639
2640 { "DAC2R", NULL, "AIF2DACR" },
2641 { "DAC2R", NULL, "AIF2CLK" },
2642 { "DAC2R", NULL, "DSP2CLK" },
2643 { "DAC2R", NULL, "DSPINTCLK" },
2644
2645 { "TOCLK", NULL, "CLK_SYS" },
2646
2647 /* AIF1 outputs */
2648 { "AIF1ADC1L", NULL, "AIF1ADC1L Mixer" },
2649 { "AIF1ADC1L Mixer", "ADC/DMIC Switch", "ADCL Mux" },
2650 { "AIF1ADC1L Mixer", "AIF2 Switch", "AIF2DACL" },
2651
2652 { "AIF1ADC1R", NULL, "AIF1ADC1R Mixer" },
2653 { "AIF1ADC1R Mixer", "ADC/DMIC Switch", "ADCR Mux" },
2654 { "AIF1ADC1R Mixer", "AIF2 Switch", "AIF2DACR" },
2655
2656 /* Pin level routing for AIF3 */
2657 { "AIF1DAC1L", NULL, "AIF1DAC Mux" },
2658 { "AIF1DAC1R", NULL, "AIF1DAC Mux" },
2659 { "AIF1DAC2L", NULL, "AIF1DAC Mux" },
2660 { "AIF1DAC2R", NULL, "AIF1DAC Mux" },
2661
2662 { "AIF2DACL", NULL, "AIF2DAC Mux" },
2663 { "AIF2DACR", NULL, "AIF2DAC Mux" },
2664
2665 { "AIF1DAC Mux", "AIF1DACDAT", "AIF1DACDAT" },
2666 { "AIF1DAC Mux", "AIF3DACDAT", "AIF3DACDAT" },
2667 { "AIF2DAC Mux", "AIF2DACDAT", "AIF2DACDAT" },
2668 { "AIF2DAC Mux", "AIF3DACDAT", "AIF3DACDAT" },
2669 { "AIF2ADC Mux", "AIF2ADCDAT", "AIF2ADCL" },
2670 { "AIF2ADC Mux", "AIF2ADCDAT", "AIF2ADCR" },
2671 { "AIF2ADC Mux", "AIF3DACDAT", "AIF3ADCDAT" },
2672
2673 /* DAC1 inputs */
2674 { "DAC1L", NULL, "DAC1L Mixer" },
2675 { "DAC1L Mixer", "AIF2 Switch", "AIF2DACL" },
2676 { "DAC1L Mixer", "AIF1.2 Switch", "AIF1DAC2L" },
2677 { "DAC1L Mixer", "AIF1.1 Switch", "AIF1DAC1L" },
2678 { "DAC1L Mixer", "Left Sidetone Switch", "Left Sidetone" },
2679 { "DAC1L Mixer", "Right Sidetone Switch", "Right Sidetone" },
2680
2681 { "DAC1R", NULL, "DAC1R Mixer" },
2682 { "DAC1R Mixer", "AIF2 Switch", "AIF2DACR" },
2683 { "DAC1R Mixer", "AIF1.2 Switch", "AIF1DAC2R" },
2684 { "DAC1R Mixer", "AIF1.1 Switch", "AIF1DAC1R" },
2685 { "DAC1R Mixer", "Left Sidetone Switch", "Left Sidetone" },
2686 { "DAC1R Mixer", "Right Sidetone Switch", "Right Sidetone" },
2687
2688 /* DAC2/AIF2 outputs */
2689 { "AIF2ADCL", NULL, "AIF2DAC2L Mixer" },
2690 { "DAC2L", NULL, "AIF2DAC2L Mixer" },
2691 { "AIF2DAC2L Mixer", "AIF2 Switch", "AIF2DACL" },
2692 { "AIF2DAC2L Mixer", "AIF1.2 Switch", "AIF1DAC2L" },
2693 { "AIF2DAC2L Mixer", "AIF1.1 Switch", "AIF1DAC1L" },
2694 { "AIF2DAC2L Mixer", "Left Sidetone Switch", "Left Sidetone" },
2695 { "AIF2DAC2L Mixer", "Right Sidetone Switch", "Right Sidetone" },
2696
2697 { "AIF2ADCR", NULL, "AIF2DAC2R Mixer" },
2698 { "DAC2R", NULL, "AIF2DAC2R Mixer" },
2699 { "AIF2DAC2R Mixer", "AIF2 Switch", "AIF2DACR" },
2700 { "AIF2DAC2R Mixer", "AIF1.2 Switch", "AIF1DAC2R" },
2701 { "AIF2DAC2R Mixer", "AIF1.1 Switch", "AIF1DAC1R" },
2702 { "AIF2DAC2R Mixer", "Left Sidetone Switch", "Left Sidetone" },
2703 { "AIF2DAC2R Mixer", "Right Sidetone Switch", "Right Sidetone" },
2704
2705 { "AIF2ADCDAT", NULL, "AIF2ADC Mux" },
2706
2707 /* AIF3 output */
2708 { "AIF3ADCDAT", "AIF1ADCDAT", "AIF1ADC1L" },
2709 { "AIF3ADCDAT", "AIF1ADCDAT", "AIF1ADC1R" },
2710 { "AIF3ADCDAT", "AIF1ADCDAT", "AIF1ADC2L" },
2711 { "AIF3ADCDAT", "AIF1ADCDAT", "AIF1ADC2R" },
2712 { "AIF3ADCDAT", "AIF2ADCDAT", "AIF2ADCL" },
2713 { "AIF3ADCDAT", "AIF2ADCDAT", "AIF2ADCR" },
2714 { "AIF3ADCDAT", "AIF2DACDAT", "AIF2DACL" },
2715 { "AIF3ADCDAT", "AIF2DACDAT", "AIF2DACR" },
2716
2717 /* Sidetone */
2718 { "Left Sidetone", "ADC/DMIC1", "ADCL Mux" },
2719 { "Left Sidetone", "DMIC2", "DMIC2L" },
2720 { "Right Sidetone", "ADC/DMIC1", "ADCR Mux" },
2721 { "Right Sidetone", "DMIC2", "DMIC2R" },
2722
2723 /* Output stages */
2724 { "Left Output Mixer", "DAC Switch", "DAC1L" },
2725 { "Right Output Mixer", "DAC Switch", "DAC1R" },
2726
2727 { "SPKL", "DAC1 Switch", "DAC1L" },
2728 { "SPKL", "DAC2 Switch", "DAC2L" },
2729
2730 { "SPKR", "DAC1 Switch", "DAC1R" },
2731 { "SPKR", "DAC2 Switch", "DAC2R" },
2732
2733 { "Left Headphone Mux", "DAC", "DAC1L" },
2734 { "Right Headphone Mux", "DAC", "DAC1R" },
2735};
2736
2737/* The size in bits of the FLL divide multiplied by 10
2738 * to allow rounding later */
2739#define FIXED_FLL_SIZE ((1 << 16) * 10)
2740
2741struct fll_div {
2742 u16 outdiv;
2743 u16 n;
2744 u16 k;
2745 u16 clk_ref_div;
2746 u16 fll_fratio;
2747};
2748
2749static int wm8994_get_fll_config(struct fll_div *fll,
2750 int freq_in, int freq_out)
2751{
2752 u64 Kpart;
2753 unsigned int K, Ndiv, Nmod;
2754
2755 pr_debug("FLL input=%dHz, output=%dHz\n", freq_in, freq_out);
2756
2757 /* Scale the input frequency down to <= 13.5MHz */
2758 fll->clk_ref_div = 0;
2759 while (freq_in > 13500000) {
2760 fll->clk_ref_div++;
2761 freq_in /= 2;
2762
2763 if (fll->clk_ref_div > 3)
2764 return -EINVAL;
2765 }
2766 pr_debug("CLK_REF_DIV=%d, Fref=%dHz\n", fll->clk_ref_div, freq_in);
2767
2768 /* Scale the output to give 90MHz<=Fvco<=100MHz */
2769 fll->outdiv = 3;
2770 while (freq_out * (fll->outdiv + 1) < 90000000) {
2771 fll->outdiv++;
2772 if (fll->outdiv > 63)
2773 return -EINVAL;
2774 }
2775 freq_out *= fll->outdiv + 1;
2776 pr_debug("OUTDIV=%d, Fvco=%dHz\n", fll->outdiv, freq_out);
2777
2778 if (freq_in > 1000000) {
2779 fll->fll_fratio = 0;
2780 } else {
2781 fll->fll_fratio = 3;
2782 freq_in *= 8;
2783 }
2784 pr_debug("FLL_FRATIO=%d, Fref=%dHz\n", fll->fll_fratio, freq_in);
2785
2786 /* Now, calculate N.K */
2787 Ndiv = freq_out / freq_in;
2788
2789 fll->n = Ndiv;
2790 Nmod = freq_out % freq_in;
2791 pr_debug("Nmod=%d\n", Nmod);
2792
2793 /* Calculate fractional part - scale up so we can round. */
2794 Kpart = FIXED_FLL_SIZE * (long long)Nmod;
2795
2796 do_div(Kpart, freq_in);
2797
2798 K = Kpart & 0xFFFFFFFF;
2799
2800 if ((K % 10) >= 5)
2801 K += 5;
2802
2803 /* Move down to proper range now rounding is done */
2804 fll->k = K / 10;
2805
2806 pr_debug("N=%x K=%x\n", fll->n, fll->k);
2807
2808 return 0;
2809}
2810
2811static int wm8994_set_fll(struct snd_soc_dai *dai, int id, int src,
2812 unsigned int freq_in, unsigned int freq_out)
2813{
2814 struct snd_soc_codec *codec = dai->codec;
2815 struct wm8994_priv *wm8994 = codec->private_data;
2816 int reg_offset, ret;
2817 struct fll_div fll;
2818 u16 reg, aif1, aif2;
2819
2820 aif1 = snd_soc_read(codec, WM8994_AIF1_CLOCKING_1)
2821 & WM8994_AIF1CLK_ENA;
2822
2823 aif2 = snd_soc_read(codec, WM8994_AIF2_CLOCKING_1)
2824 & WM8994_AIF2CLK_ENA;
2825
2826 switch (id) {
2827 case WM8994_FLL1:
2828 reg_offset = 0;
2829 id = 0;
2830 break;
2831 case WM8994_FLL2:
2832 reg_offset = 0x20;
2833 id = 1;
2834 break;
2835 default:
2836 return -EINVAL;
2837 }
2838
2839 /* Are we changing anything? */
2840 if (wm8994->fll[id].src == src &&
2841 wm8994->fll[id].in == freq_in && wm8994->fll[id].out == freq_out)
2842 return 0;
2843
2844 /* If we're stopping the FLL redo the old config - no
2845 * registers will actually be written but we avoid GCC flow
2846 * analysis bugs spewing warnings.
2847 */
2848 if (freq_out)
2849 ret = wm8994_get_fll_config(&fll, freq_in, freq_out);
2850 else
2851 ret = wm8994_get_fll_config(&fll, wm8994->fll[id].in,
2852 wm8994->fll[id].out);
2853 if (ret < 0)
2854 return ret;
2855
2856 /* Gate the AIF clocks while we reclock */
2857 snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1,
2858 WM8994_AIF1CLK_ENA, 0);
2859 snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1,
2860 WM8994_AIF2CLK_ENA, 0);
2861
2862 /* We always need to disable the FLL while reconfiguring */
2863 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_1 + reg_offset,
2864 WM8994_FLL1_ENA, 0);
2865
2866 reg = (fll.outdiv << WM8994_FLL1_OUTDIV_SHIFT) |
2867 (fll.fll_fratio << WM8994_FLL1_FRATIO_SHIFT);
2868 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_2 + reg_offset,
2869 WM8994_FLL1_OUTDIV_MASK |
2870 WM8994_FLL1_FRATIO_MASK, reg);
2871
2872 snd_soc_write(codec, WM8994_FLL1_CONTROL_3 + reg_offset, fll.k);
2873
2874 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_4 + reg_offset,
2875 WM8994_FLL1_N_MASK,
2876 fll.n << WM8994_FLL1_N_SHIFT);
2877
2878 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_5 + reg_offset,
2879 WM8994_FLL1_REFCLK_DIV_MASK,
2880 fll.clk_ref_div << WM8994_FLL1_REFCLK_DIV_SHIFT);
2881
2882 /* Enable (with fractional mode if required) */
2883 if (freq_out) {
2884 if (fll.k)
2885 reg = WM8994_FLL1_ENA | WM8994_FLL1_FRAC;
2886 else
2887 reg = WM8994_FLL1_ENA;
2888 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_1 + reg_offset,
2889 WM8994_FLL1_ENA | WM8994_FLL1_FRAC,
2890 reg);
2891 }
2892
2893 wm8994->fll[id].in = freq_in;
2894 wm8994->fll[id].out = freq_out;
2895
2896 /* Enable any gated AIF clocks */
2897 snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1,
2898 WM8994_AIF1CLK_ENA, aif1);
2899 snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1,
2900 WM8994_AIF2CLK_ENA, aif2);
2901
2902 configure_clock(codec);
2903
2904 return 0;
2905}
2906
2907static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai,
2908 int clk_id, unsigned int freq, int dir)
2909{
2910 struct snd_soc_codec *codec = dai->codec;
2911 struct wm8994_priv *wm8994 = codec->private_data;
2912
2913 switch (dai->id) {
2914 case 1:
2915 case 2:
2916 break;
2917
2918 default:
2919 /* AIF3 shares clocking with AIF1/2 */
2920 return -EINVAL;
2921 }
2922
2923 switch (clk_id) {
2924 case WM8994_SYSCLK_MCLK1:
2925 wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_MCLK1;
2926 wm8994->mclk[0] = freq;
2927 dev_dbg(dai->dev, "AIF%d using MCLK1 at %uHz\n",
2928 dai->id, freq);
2929 break;
2930
2931 case WM8994_SYSCLK_MCLK2:
2932 /* TODO: Set GPIO AF */
2933 wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_MCLK2;
2934 wm8994->mclk[1] = freq;
2935 dev_dbg(dai->dev, "AIF%d using MCLK2 at %uHz\n",
2936 dai->id, freq);
2937 break;
2938
2939 case WM8994_SYSCLK_FLL1:
2940 wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_FLL1;
2941 dev_dbg(dai->dev, "AIF%d using FLL1\n", dai->id);
2942 break;
2943
2944 case WM8994_SYSCLK_FLL2:
2945 wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_FLL2;
2946 dev_dbg(dai->dev, "AIF%d using FLL2\n", dai->id);
2947 break;
2948
2949 default:
2950 return -EINVAL;
2951 }
2952
2953 configure_clock(codec);
2954
2955 return 0;
2956}
2957
2958static int wm8994_set_bias_level(struct snd_soc_codec *codec,
2959 enum snd_soc_bias_level level)
2960{
2961 switch (level) {
2962 case SND_SOC_BIAS_ON:
2963 break;
2964
2965 case SND_SOC_BIAS_PREPARE:
2966 /* VMID=2x40k */
2967 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
2968 WM8994_VMID_SEL_MASK, 0x2);
2969 break;
2970
2971 case SND_SOC_BIAS_STANDBY:
2972 if (codec->bias_level == SND_SOC_BIAS_OFF) {
2973 /* Tweak DC servo configuration for improved
2974 * performance. */
2975 snd_soc_write(codec, 0x102, 0x3);
2976 snd_soc_write(codec, 0x56, 0x3);
2977 snd_soc_write(codec, 0x102, 0);
2978
2979 /* Discharge LINEOUT1 & 2 */
2980 snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
2981 WM8994_LINEOUT1_DISCH |
2982 WM8994_LINEOUT2_DISCH,
2983 WM8994_LINEOUT1_DISCH |
2984 WM8994_LINEOUT2_DISCH);
2985
2986 /* Startup bias, VMID ramp & buffer */
2987 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
2988 WM8994_STARTUP_BIAS_ENA |
2989 WM8994_VMID_BUF_ENA |
2990 WM8994_VMID_RAMP_MASK,
2991 WM8994_STARTUP_BIAS_ENA |
2992 WM8994_VMID_BUF_ENA |
2993 (0x11 << WM8994_VMID_RAMP_SHIFT));
2994
2995 /* Main bias enable, VMID=2x40k */
2996 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
2997 WM8994_BIAS_ENA |
2998 WM8994_VMID_SEL_MASK,
2999 WM8994_BIAS_ENA | 0x2);
3000
3001 msleep(20);
3002 }
3003
3004 /* VMID=2x500k */
3005 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
3006 WM8994_VMID_SEL_MASK, 0x4);
3007
3008 break;
3009
3010 case SND_SOC_BIAS_OFF:
3011 if (codec->bias_level == SND_SOC_BIAS_STANDBY) {
3012 /* Switch over to startup biases */
3013 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
3014 WM8994_BIAS_SRC |
3015 WM8994_STARTUP_BIAS_ENA |
3016 WM8994_VMID_BUF_ENA |
3017 WM8994_VMID_RAMP_MASK,
3018 WM8994_BIAS_SRC |
3019 WM8994_STARTUP_BIAS_ENA |
3020 WM8994_VMID_BUF_ENA |
3021 (1 << WM8994_VMID_RAMP_SHIFT));
3022
3023 /* Disable main biases */
3024 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
3025 WM8994_BIAS_ENA |
3026 WM8994_VMID_SEL_MASK, 0);
3027
3028 /* Discharge line */
3029 snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
3030 WM8994_LINEOUT1_DISCH |
3031 WM8994_LINEOUT2_DISCH,
3032 WM8994_LINEOUT1_DISCH |
3033 WM8994_LINEOUT2_DISCH);
3034
3035 msleep(5);
3036
3037 /* Switch off startup biases */
3038 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
3039 WM8994_BIAS_SRC |
3040 WM8994_STARTUP_BIAS_ENA |
3041 WM8994_VMID_BUF_ENA |
3042 WM8994_VMID_RAMP_MASK, 0);
3043 }
3044 break;
3045 }
3046 codec->bias_level = level;
3047 return 0;
3048}
3049
3050static int wm8994_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
3051{
3052 struct snd_soc_codec *codec = dai->codec;
3053 int ms_reg;
3054 int aif1_reg;
3055 int ms = 0;
3056 int aif1 = 0;
3057
3058 switch (dai->id) {
3059 case 1:
3060 ms_reg = WM8994_AIF1_MASTER_SLAVE;
3061 aif1_reg = WM8994_AIF1_CONTROL_1;
3062 break;
3063 case 2:
3064 ms_reg = WM8994_AIF2_MASTER_SLAVE;
3065 aif1_reg = WM8994_AIF2_CONTROL_1;
3066 break;
3067 default:
3068 return -EINVAL;
3069 }
3070
3071 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
3072 case SND_SOC_DAIFMT_CBS_CFS:
3073 break;
3074 case SND_SOC_DAIFMT_CBM_CFM:
3075 ms = WM8994_AIF1_MSTR;
3076 break;
3077 default:
3078 return -EINVAL;
3079 }
3080
3081 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
3082 case SND_SOC_DAIFMT_DSP_B:
3083 aif1 |= WM8994_AIF1_LRCLK_INV;
3084 case SND_SOC_DAIFMT_DSP_A:
3085 aif1 |= 0x18;
3086 break;
3087 case SND_SOC_DAIFMT_I2S:
3088 aif1 |= 0x10;
3089 break;
3090 case SND_SOC_DAIFMT_RIGHT_J:
3091 break;
3092 case SND_SOC_DAIFMT_LEFT_J:
3093 aif1 |= 0x8;
3094 break;
3095 default:
3096 return -EINVAL;
3097 }
3098
3099 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
3100 case SND_SOC_DAIFMT_DSP_A:
3101 case SND_SOC_DAIFMT_DSP_B:
3102 /* frame inversion not valid for DSP modes */
3103 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
3104 case SND_SOC_DAIFMT_NB_NF:
3105 break;
3106 case SND_SOC_DAIFMT_IB_NF:
3107 aif1 |= WM8994_AIF1_BCLK_INV;
3108 break;
3109 default:
3110 return -EINVAL;
3111 }
3112 break;
3113
3114 case SND_SOC_DAIFMT_I2S:
3115 case SND_SOC_DAIFMT_RIGHT_J:
3116 case SND_SOC_DAIFMT_LEFT_J:
3117 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
3118 case SND_SOC_DAIFMT_NB_NF:
3119 break;
3120 case SND_SOC_DAIFMT_IB_IF:
3121 aif1 |= WM8994_AIF1_BCLK_INV | WM8994_AIF1_LRCLK_INV;
3122 break;
3123 case SND_SOC_DAIFMT_IB_NF:
3124 aif1 |= WM8994_AIF1_BCLK_INV;
3125 break;
3126 case SND_SOC_DAIFMT_NB_IF:
3127 aif1 |= WM8994_AIF1_LRCLK_INV;
3128 break;
3129 default:
3130 return -EINVAL;
3131 }
3132 break;
3133 default:
3134 return -EINVAL;
3135 }
3136
3137 snd_soc_update_bits(codec, aif1_reg,
3138 WM8994_AIF1_BCLK_INV | WM8994_AIF1_LRCLK_INV |
3139 WM8994_AIF1_FMT_MASK,
3140 aif1);
3141 snd_soc_update_bits(codec, ms_reg, WM8994_AIF1_MSTR,
3142 ms);
3143
3144 return 0;
3145}
3146
3147static struct {
3148 int val, rate;
3149} srs[] = {
3150 { 0, 8000 },
3151 { 1, 11025 },
3152 { 2, 12000 },
3153 { 3, 16000 },
3154 { 4, 22050 },
3155 { 5, 24000 },
3156 { 6, 32000 },
3157 { 7, 44100 },
3158 { 8, 48000 },
3159 { 9, 88200 },
3160 { 10, 96000 },
3161};
3162
3163static int fs_ratios[] = {
3164 64, 128, 192, 256, 348, 512, 768, 1024, 1408, 1536
3165};
3166
3167static int bclk_divs[] = {
3168 10, 15, 20, 30, 40, 50, 60, 80, 110, 120, 160, 220, 240, 320, 440, 480,
3169 640, 880, 960, 1280, 1760, 1920
3170};
3171
3172static int wm8994_hw_params(struct snd_pcm_substream *substream,
3173 struct snd_pcm_hw_params *params,
3174 struct snd_soc_dai *dai)
3175{
3176 struct snd_soc_codec *codec = dai->codec;
3177 struct wm8994_priv *wm8994 = codec->private_data;
3178 int aif1_reg;
3179 int bclk_reg;
3180 int lrclk_reg;
3181 int rate_reg;
3182 int aif1 = 0;
3183 int bclk = 0;
3184 int lrclk = 0;
3185 int rate_val = 0;
3186 int id = dai->id - 1;
3187
3188 int i, cur_val, best_val, bclk_rate, best;
3189
3190 switch (dai->id) {
3191 case 1:
3192 aif1_reg = WM8994_AIF1_CONTROL_1;
3193 bclk_reg = WM8994_AIF1_BCLK;
3194 rate_reg = WM8994_AIF1_RATE;
3195 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
3196 wm8994->lrclk_shared[0])
3197 lrclk_reg = WM8994_AIF1DAC_LRCLK;
3198 else
3199 lrclk_reg = WM8994_AIF1ADC_LRCLK;
3200 break;
3201 case 2:
3202 aif1_reg = WM8994_AIF2_CONTROL_1;
3203 bclk_reg = WM8994_AIF2_BCLK;
3204 rate_reg = WM8994_AIF2_RATE;
3205 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
3206 wm8994->lrclk_shared[1])
3207 lrclk_reg = WM8994_AIF2DAC_LRCLK;
3208 else
3209 lrclk_reg = WM8994_AIF2ADC_LRCLK;
3210 break;
3211 default:
3212 return -EINVAL;
3213 }
3214
3215 bclk_rate = params_rate(params) * 2;
3216 switch (params_format(params)) {
3217 case SNDRV_PCM_FORMAT_S16_LE:
3218 bclk_rate *= 16;
3219 break;
3220 case SNDRV_PCM_FORMAT_S20_3LE:
3221 bclk_rate *= 20;
3222 aif1 |= 0x20;
3223 break;
3224 case SNDRV_PCM_FORMAT_S24_LE:
3225 bclk_rate *= 24;
3226 aif1 |= 0x40;
3227 break;
3228 case SNDRV_PCM_FORMAT_S32_LE:
3229 bclk_rate *= 32;
3230 aif1 |= 0x60;
3231 break;
3232 default:
3233 return -EINVAL;
3234 }
3235
3236 /* Try to find an appropriate sample rate; look for an exact match. */
3237 for (i = 0; i < ARRAY_SIZE(srs); i++)
3238 if (srs[i].rate == params_rate(params))
3239 break;
3240 if (i == ARRAY_SIZE(srs))
3241 return -EINVAL;
3242 rate_val |= srs[i].val << WM8994_AIF1_SR_SHIFT;
3243
3244 dev_dbg(dai->dev, "Sample rate is %dHz\n", srs[i].rate);
3245 dev_dbg(dai->dev, "AIF%dCLK is %dHz, target BCLK %dHz\n",
3246 dai->id, wm8994->aifclk[id], bclk_rate);
3247
3248 if (wm8994->aifclk[id] == 0) {
3249 dev_err(dai->dev, "AIF%dCLK not configured\n", dai->id);
3250 return -EINVAL;
3251 }
3252
3253 /* AIFCLK/fs ratio; look for a close match in either direction */
3254 best = 0;
3255 best_val = abs((fs_ratios[0] * params_rate(params))
3256 - wm8994->aifclk[id]);
3257 for (i = 1; i < ARRAY_SIZE(fs_ratios); i++) {
3258 cur_val = abs((fs_ratios[i] * params_rate(params))
3259 - wm8994->aifclk[id]);
3260 if (cur_val >= best_val)
3261 continue;
3262 best = i;
3263 best_val = cur_val;
3264 }
3265 dev_dbg(dai->dev, "Selected AIF%dCLK/fs = %d\n",
3266 dai->id, fs_ratios[best]);
3267 rate_val |= best;
3268
3269 /* We may not get quite the right frequency if using
3270 * approximate clocks so look for the closest match that is
3271 * higher than the target (we need to ensure that there enough
3272 * BCLKs to clock out the samples).
3273 */
3274 best = 0;
3275 for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) {
3276 cur_val = (wm8994->aifclk[id] * 10 / bclk_divs[i]) - bclk_rate;
3277 if (cur_val < 0) /* BCLK table is sorted */
3278 break;
3279 best = i;
3280 }
3281 bclk_rate = wm8994->aifclk[id] * 10 / bclk_divs[best];
3282 dev_dbg(dai->dev, "Using BCLK_DIV %d for actual BCLK %dHz\n",
3283 bclk_divs[best], bclk_rate);
3284 bclk |= best << WM8994_AIF1_BCLK_DIV_SHIFT;
3285
3286 lrclk = bclk_rate / params_rate(params);
3287 dev_dbg(dai->dev, "Using LRCLK rate %d for actual LRCLK %dHz\n",
3288 lrclk, bclk_rate / lrclk);
3289
3290 snd_soc_update_bits(codec, aif1_reg, WM8994_AIF1_WL_MASK, aif1);
3291 snd_soc_update_bits(codec, bclk_reg, WM8994_AIF1_BCLK_DIV_MASK, bclk);
3292 snd_soc_update_bits(codec, lrclk_reg, WM8994_AIF1DAC_RATE_MASK,
3293 lrclk);
3294 snd_soc_update_bits(codec, rate_reg, WM8994_AIF1_SR_MASK |
3295 WM8994_AIF1CLK_RATE_MASK, rate_val);
3296
3297 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
3298 switch (dai->id) {
3299 case 1:
3300 wm8994->dac_rates[0] = params_rate(params);
3301 wm8994_set_retune_mobile(codec, 0);
3302 wm8994_set_retune_mobile(codec, 1);
3303 break;
3304 case 2:
3305 wm8994->dac_rates[1] = params_rate(params);
3306 wm8994_set_retune_mobile(codec, 2);
3307 break;
3308 }
3309 }
3310
3311 return 0;
3312}
3313
3314static int wm8994_aif_mute(struct snd_soc_dai *codec_dai, int mute)
3315{
3316 struct snd_soc_codec *codec = codec_dai->codec;
3317 int mute_reg;
3318 int reg;
3319
3320 switch (codec_dai->id) {
3321 case 1:
3322 mute_reg = WM8994_AIF1_DAC1_FILTERS_1;
3323 break;
3324 case 2:
3325 mute_reg = WM8994_AIF2_DAC_FILTERS_1;
3326 break;
3327 default:
3328 return -EINVAL;
3329 }
3330
3331 if (mute)
3332 reg = WM8994_AIF1DAC1_MUTE;
3333 else
3334 reg = 0;
3335
3336 snd_soc_update_bits(codec, mute_reg, WM8994_AIF1DAC1_MUTE, reg);
3337
3338 return 0;
3339}
3340
3341#define WM8994_RATES SNDRV_PCM_RATE_8000_96000
3342
3343#define WM8994_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
3344 SNDRV_PCM_FMTBIT_S24_LE)
3345
3346static struct snd_soc_dai_ops wm8994_aif1_dai_ops = {
3347 .set_sysclk = wm8994_set_dai_sysclk,
3348 .set_fmt = wm8994_set_dai_fmt,
3349 .hw_params = wm8994_hw_params,
3350 .digital_mute = wm8994_aif_mute,
3351 .set_pll = wm8994_set_fll,
3352};
3353
3354static struct snd_soc_dai_ops wm8994_aif2_dai_ops = {
3355 .set_sysclk = wm8994_set_dai_sysclk,
3356 .set_fmt = wm8994_set_dai_fmt,
3357 .hw_params = wm8994_hw_params,
3358 .digital_mute = wm8994_aif_mute,
3359 .set_pll = wm8994_set_fll,
3360};
3361
3362struct snd_soc_dai wm8994_dai[] = {
3363 {
3364 .name = "WM8994 AIF1",
3365 .id = 1,
3366 .playback = {
3367 .stream_name = "AIF1 Playback",
3368 .channels_min = 2,
3369 .channels_max = 2,
3370 .rates = WM8994_RATES,
3371 .formats = WM8994_FORMATS,
3372 },
3373 .capture = {
3374 .stream_name = "AIF1 Capture",
3375 .channels_min = 2,
3376 .channels_max = 2,
3377 .rates = WM8994_RATES,
3378 .formats = WM8994_FORMATS,
3379 },
3380 .ops = &wm8994_aif1_dai_ops,
3381 },
3382 {
3383 .name = "WM8994 AIF2",
3384 .id = 2,
3385 .playback = {
3386 .stream_name = "AIF2 Playback",
3387 .channels_min = 2,
3388 .channels_max = 2,
3389 .rates = WM8994_RATES,
3390 .formats = WM8994_FORMATS,
3391 },
3392 .capture = {
3393 .stream_name = "AIF2 Capture",
3394 .channels_min = 2,
3395 .channels_max = 2,
3396 .rates = WM8994_RATES,
3397 .formats = WM8994_FORMATS,
3398 },
3399 .ops = &wm8994_aif2_dai_ops,
3400 },
3401 {
3402 .name = "WM8994 AIF3",
3403 .playback = {
3404 .stream_name = "AIF3 Playback",
3405 .channels_min = 2,
3406 .channels_max = 2,
3407 .rates = WM8994_RATES,
3408 .formats = WM8994_FORMATS,
3409 },
3410 .capture = {
3411 .stream_name = "AIF3 Capture",
3412 .channels_min = 2,
3413 .channels_max = 2,
3414 .rates = WM8994_RATES,
3415 .formats = WM8994_FORMATS,
3416 },
3417 }
3418};
3419EXPORT_SYMBOL_GPL(wm8994_dai);
3420
3421#ifdef CONFIG_PM
3422static int wm8994_suspend(struct platform_device *pdev, pm_message_t state)
3423{
3424 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
3425 struct snd_soc_codec *codec = socdev->card->codec;
3426 struct wm8994_priv *wm8994 = codec->private_data;
3427 int i, ret;
3428
3429 for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) {
3430 memcpy(&wm8994->fll_suspend[i], &wm8994->fll[i],
3431 sizeof(struct fll_config));
3432 ret = wm8994_set_fll(&codec->dai[0], i + 1, 0, 0, 0);
3433 if (ret < 0)
3434 dev_warn(codec->dev, "Failed to stop FLL%d: %d\n",
3435 i + 1, ret);
3436 }
3437
3438 wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF);
3439
3440 return 0;
3441}
3442
3443static int wm8994_resume(struct platform_device *pdev)
3444{
3445 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
3446 struct snd_soc_codec *codec = socdev->card->codec;
3447 struct wm8994_priv *wm8994 = codec->private_data;
3448 u16 *reg_cache = codec->reg_cache;
3449 int i, ret;
3450
3451 /* Restore the registers */
3452 for (i = 1; i < ARRAY_SIZE(wm8994->reg_cache); i++) {
3453 switch (i) {
3454 case WM8994_LDO_1:
3455 case WM8994_LDO_2:
3456 case WM8994_SOFTWARE_RESET:
3457 /* Handled by other MFD drivers */
3458 continue;
3459 default:
3460 break;
3461 }
3462
3463 if (!access_masks[i].writable)
3464 continue;
3465
3466 wm8994_reg_write(codec->control_data, i, reg_cache[i]);
3467 }
3468
3469 wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
3470
3471 for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) {
3472 ret = wm8994_set_fll(&codec->dai[0], i + 1,
3473 wm8994->fll_suspend[i].src,
3474 wm8994->fll_suspend[i].in,
3475 wm8994->fll_suspend[i].out);
3476 if (ret < 0)
3477 dev_warn(codec->dev, "Failed to restore FLL%d: %d\n",
3478 i + 1, ret);
3479 }
3480
3481 return 0;
3482}
3483#else
3484#define wm8994_suspend NULL
3485#define wm8994_resume NULL
3486#endif
3487
3488static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994)
3489{
3490 struct snd_soc_codec *codec = &wm8994->codec;
3491 struct wm8994_pdata *pdata = wm8994->pdata;
3492 struct snd_kcontrol_new controls[] = {
3493 SOC_ENUM_EXT("AIF1.1 EQ Mode",
3494 wm8994->retune_mobile_enum,
3495 wm8994_get_retune_mobile_enum,
3496 wm8994_put_retune_mobile_enum),
3497 SOC_ENUM_EXT("AIF1.2 EQ Mode",
3498 wm8994->retune_mobile_enum,
3499 wm8994_get_retune_mobile_enum,
3500 wm8994_put_retune_mobile_enum),
3501 SOC_ENUM_EXT("AIF2 EQ Mode",
3502 wm8994->retune_mobile_enum,
3503 wm8994_get_retune_mobile_enum,
3504 wm8994_put_retune_mobile_enum),
3505 };
3506 int ret, i, j;
3507 const char **t;
3508
3509 /* We need an array of texts for the enum API but the number
3510 * of texts is likely to be less than the number of
3511 * configurations due to the sample rate dependency of the
3512 * configurations. */
3513 wm8994->num_retune_mobile_texts = 0;
3514 wm8994->retune_mobile_texts = NULL;
3515 for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) {
3516 for (j = 0; j < wm8994->num_retune_mobile_texts; j++) {
3517 if (strcmp(pdata->retune_mobile_cfgs[i].name,
3518 wm8994->retune_mobile_texts[j]) == 0)
3519 break;
3520 }
3521
3522 if (j != wm8994->num_retune_mobile_texts)
3523 continue;
3524
3525 /* Expand the array... */
3526 t = krealloc(wm8994->retune_mobile_texts,
3527 sizeof(char *) *
3528 (wm8994->num_retune_mobile_texts + 1),
3529 GFP_KERNEL);
3530 if (t == NULL)
3531 continue;
3532
3533 /* ...store the new entry... */
3534 t[wm8994->num_retune_mobile_texts] =
3535 pdata->retune_mobile_cfgs[i].name;
3536
3537 /* ...and remember the new version. */
3538 wm8994->num_retune_mobile_texts++;
3539 wm8994->retune_mobile_texts = t;
3540 }
3541
3542 dev_dbg(codec->dev, "Allocated %d unique ReTune Mobile names\n",
3543 wm8994->num_retune_mobile_texts);
3544
3545 wm8994->retune_mobile_enum.max = wm8994->num_retune_mobile_texts;
3546 wm8994->retune_mobile_enum.texts = wm8994->retune_mobile_texts;
3547
3548 ret = snd_soc_add_controls(&wm8994->codec, controls,
3549 ARRAY_SIZE(controls));
3550 if (ret != 0)
3551 dev_err(wm8994->codec.dev,
3552 "Failed to add ReTune Mobile controls: %d\n", ret);
3553}
3554
3555static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
3556{
3557 struct snd_soc_codec *codec = &wm8994->codec;
3558 struct wm8994_pdata *pdata = wm8994->pdata;
3559 int ret, i;
3560
3561 if (!pdata)
3562 return;
3563
3564 wm_hubs_handle_analogue_pdata(codec, pdata->lineout1_diff,
3565 pdata->lineout2_diff,
3566 pdata->lineout1fb,
3567 pdata->lineout2fb,
3568 pdata->jd_scthr,
3569 pdata->jd_thr,
3570 pdata->micbias1_lvl,
3571 pdata->micbias2_lvl);
3572
3573 dev_dbg(codec->dev, "%d DRC configurations\n", pdata->num_drc_cfgs);
3574
3575 if (pdata->num_drc_cfgs) {
3576 struct snd_kcontrol_new controls[] = {
3577 SOC_ENUM_EXT("AIF1DRC1 Mode", wm8994->drc_enum,
3578 wm8994_get_drc_enum, wm8994_put_drc_enum),
3579 SOC_ENUM_EXT("AIF1DRC2 Mode", wm8994->drc_enum,
3580 wm8994_get_drc_enum, wm8994_put_drc_enum),
3581 SOC_ENUM_EXT("AIF2DRC Mode", wm8994->drc_enum,
3582 wm8994_get_drc_enum, wm8994_put_drc_enum),
3583 };
3584
3585 /* We need an array of texts for the enum API */
3586 wm8994->drc_texts = kmalloc(sizeof(char *)
3587 * pdata->num_drc_cfgs, GFP_KERNEL);
3588 if (!wm8994->drc_texts) {
3589 dev_err(wm8994->codec.dev,
3590 "Failed to allocate %d DRC config texts\n",
3591 pdata->num_drc_cfgs);
3592 return;
3593 }
3594
3595 for (i = 0; i < pdata->num_drc_cfgs; i++)
3596 wm8994->drc_texts[i] = pdata->drc_cfgs[i].name;
3597
3598 wm8994->drc_enum.max = pdata->num_drc_cfgs;
3599 wm8994->drc_enum.texts = wm8994->drc_texts;
3600
3601 ret = snd_soc_add_controls(&wm8994->codec, controls,
3602 ARRAY_SIZE(controls));
3603 if (ret != 0)
3604 dev_err(wm8994->codec.dev,
3605 "Failed to add DRC mode controls: %d\n", ret);
3606
3607 for (i = 0; i < WM8994_NUM_DRC; i++)
3608 wm8994_set_drc(codec, i);
3609 }
3610
3611 dev_dbg(codec->dev, "%d ReTune Mobile configurations\n",
3612 pdata->num_retune_mobile_cfgs);
3613
3614 if (pdata->num_retune_mobile_cfgs)
3615 wm8994_handle_retune_mobile_pdata(wm8994);
3616 else
3617 snd_soc_add_controls(&wm8994->codec, wm8994_eq_controls,
3618 ARRAY_SIZE(wm8994_eq_controls));
3619}
3620
3621static int wm8994_probe(struct platform_device *pdev)
3622{
3623 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
3624 struct snd_soc_codec *codec;
3625 int ret = 0;
3626
3627 if (wm8994_codec == NULL) {
3628 dev_err(&pdev->dev, "Codec device not registered\n");
3629 return -ENODEV;
3630 }
3631
3632 socdev->card->codec = wm8994_codec;
3633 codec = wm8994_codec;
3634
3635 /* register pcms */
3636 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
3637 if (ret < 0) {
3638 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
3639 return ret;
3640 }
3641
3642 wm8994_handle_pdata(codec->private_data);
3643
3644 wm_hubs_add_analogue_controls(codec);
3645 snd_soc_add_controls(codec, wm8994_snd_controls,
3646 ARRAY_SIZE(wm8994_snd_controls));
3647 snd_soc_dapm_new_controls(codec, wm8994_dapm_widgets,
3648 ARRAY_SIZE(wm8994_dapm_widgets));
3649 wm_hubs_add_analogue_routes(codec, 0, 0);
3650 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
3651
3652 return 0;
3653}
3654
3655static int wm8994_remove(struct platform_device *pdev)
3656{
3657 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
3658
3659 snd_soc_free_pcms(socdev);
3660 snd_soc_dapm_free(socdev);
3661
3662 return 0;
3663}
3664
3665struct snd_soc_codec_device soc_codec_dev_wm8994 = {
3666 .probe = wm8994_probe,
3667 .remove = wm8994_remove,
3668 .suspend = wm8994_suspend,
3669 .resume = wm8994_resume,
3670};
3671EXPORT_SYMBOL_GPL(soc_codec_dev_wm8994);
3672
3673static int wm8994_codec_probe(struct platform_device *pdev)
3674{
3675 int ret;
3676 struct wm8994_priv *wm8994;
3677 struct snd_soc_codec *codec;
3678 int i;
3679 u16 rev;
3680
3681 if (wm8994_codec) {
3682 dev_err(&pdev->dev, "Another WM8994 is registered\n");
3683 return -EINVAL;
3684 }
3685
3686 wm8994 = kzalloc(sizeof(struct wm8994_priv), GFP_KERNEL);
3687 if (!wm8994) {
3688 dev_err(&pdev->dev, "Failed to allocate private data\n");
3689 return -ENOMEM;
3690 }
3691
3692 codec = &wm8994->codec;
3693
3694 mutex_init(&codec->mutex);
3695 INIT_LIST_HEAD(&codec->dapm_widgets);
3696 INIT_LIST_HEAD(&codec->dapm_paths);
3697
3698 codec->private_data = wm8994;
3699 codec->control_data = dev_get_drvdata(pdev->dev.parent);
3700 codec->name = "WM8994";
3701 codec->owner = THIS_MODULE;
3702 codec->read = wm8994_read;
3703 codec->write = wm8994_write;
3704 codec->readable_register = wm8994_readable;
3705 codec->bias_level = SND_SOC_BIAS_OFF;
3706 codec->set_bias_level = wm8994_set_bias_level;
3707 codec->dai = &wm8994_dai[0];
3708 codec->num_dai = 3;
3709 codec->reg_cache_size = WM8994_MAX_REGISTER;
3710 codec->reg_cache = &wm8994->reg_cache;
3711 codec->dev = &pdev->dev;
3712
3713 wm8994->pdata = pdev->dev.parent->platform_data;
3714
3715 /* Fill the cache with physical values we inherited; don't reset */
3716 ret = wm8994_bulk_read(codec->control_data, 0,
3717 ARRAY_SIZE(wm8994->reg_cache) - 1,
3718 codec->reg_cache);
3719 if (ret < 0) {
3720 dev_err(codec->dev, "Failed to fill register cache: %d\n",
3721 ret);
3722 goto err;
3723 }
3724
3725 /* Clear the cached values for unreadable/volatile registers to
3726 * avoid potential confusion.
3727 */
3728 for (i = 0; i < ARRAY_SIZE(wm8994->reg_cache); i++)
3729 if (wm8994_volatile(i) || !wm8994_readable(i))
3730 wm8994->reg_cache[i] = 0;
3731
3732 /* Set revision-specific configuration */
3733 rev = snd_soc_read(codec, WM8994_CHIP_REVISION);
3734 switch (rev) {
3735 case 2:
3736 case 3:
3737 wm8994->hubs.dcs_codes = -5;
3738 wm8994->hubs.hp_startup_mode = 1;
3739 wm8994->hubs.dcs_readback_mode = 1;
3740 break;
3741 default:
3742 wm8994->hubs.dcs_readback_mode = 1;
3743 break;
3744 }
3745
3746 /* Remember if AIFnLRCLK is configured as a GPIO. This should be
3747 * configured on init - if a system wants to do this dynamically
3748 * at runtime we can deal with that then.
3749 */
3750 ret = wm8994_reg_read(codec->control_data, WM8994_GPIO_1);
3751 if (ret < 0) {
3752 dev_err(codec->dev, "Failed to read GPIO1 state: %d\n", ret);
3753 goto err;
3754 }
3755 if ((ret & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) {
3756 wm8994->lrclk_shared[0] = 1;
3757 wm8994_dai[0].symmetric_rates = 1;
3758 } else {
3759 wm8994->lrclk_shared[0] = 0;
3760 }
3761
3762 ret = wm8994_reg_read(codec->control_data, WM8994_GPIO_6);
3763 if (ret < 0) {
3764 dev_err(codec->dev, "Failed to read GPIO6 state: %d\n", ret);
3765 goto err;
3766 }
3767 if ((ret & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) {
3768 wm8994->lrclk_shared[1] = 1;
3769 wm8994_dai[1].symmetric_rates = 1;
3770 } else {
3771 wm8994->lrclk_shared[1] = 0;
3772 }
3773
3774 for (i = 0; i < ARRAY_SIZE(wm8994_dai); i++)
3775 wm8994_dai[i].dev = codec->dev;
3776
3777 wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
3778
3779 wm8994_codec = codec;
3780
3781 /* Latch volume updates (right only; we always do left then right). */
3782 snd_soc_update_bits(codec, WM8994_AIF1_DAC1_RIGHT_VOLUME,
3783 WM8994_AIF1DAC1_VU, WM8994_AIF1DAC1_VU);
3784 snd_soc_update_bits(codec, WM8994_AIF1_DAC2_RIGHT_VOLUME,
3785 WM8994_AIF1DAC2_VU, WM8994_AIF1DAC2_VU);
3786 snd_soc_update_bits(codec, WM8994_AIF2_DAC_RIGHT_VOLUME,
3787 WM8994_AIF2DAC_VU, WM8994_AIF2DAC_VU);
3788 snd_soc_update_bits(codec, WM8994_AIF1_ADC1_RIGHT_VOLUME,
3789 WM8994_AIF1ADC1_VU, WM8994_AIF1ADC1_VU);
3790 snd_soc_update_bits(codec, WM8994_AIF1_ADC2_RIGHT_VOLUME,
3791 WM8994_AIF1ADC2_VU, WM8994_AIF1ADC2_VU);
3792 snd_soc_update_bits(codec, WM8994_AIF2_ADC_RIGHT_VOLUME,
3793 WM8994_AIF2ADC_VU, WM8994_AIF1ADC2_VU);
3794 snd_soc_update_bits(codec, WM8994_DAC1_RIGHT_VOLUME,
3795 WM8994_DAC1_VU, WM8994_DAC1_VU);
3796 snd_soc_update_bits(codec, WM8994_DAC2_RIGHT_VOLUME,
3797 WM8994_DAC2_VU, WM8994_DAC2_VU);
3798
3799 /* Set the low bit of the 3D stereo depth so TLV matches */
3800 snd_soc_update_bits(codec, WM8994_AIF1_DAC1_FILTERS_2,
3801 1 << WM8994_AIF1DAC1_3D_GAIN_SHIFT,
3802 1 << WM8994_AIF1DAC1_3D_GAIN_SHIFT);
3803 snd_soc_update_bits(codec, WM8994_AIF1_DAC2_FILTERS_2,
3804 1 << WM8994_AIF1DAC2_3D_GAIN_SHIFT,
3805 1 << WM8994_AIF1DAC2_3D_GAIN_SHIFT);
3806 snd_soc_update_bits(codec, WM8994_AIF2_DAC_FILTERS_2,
3807 1 << WM8994_AIF2DAC_3D_GAIN_SHIFT,
3808 1 << WM8994_AIF2DAC_3D_GAIN_SHIFT);
3809
3810 wm8994_update_class_w(codec);
3811
3812 ret = snd_soc_register_codec(codec);
3813 if (ret != 0) {
3814 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
3815 goto err;
3816 }
3817
3818 ret = snd_soc_register_dais(wm8994_dai, ARRAY_SIZE(wm8994_dai));
3819 if (ret != 0) {
3820 dev_err(codec->dev, "Failed to register DAIs: %d\n", ret);
3821 goto err_codec;
3822 }
3823
3824 platform_set_drvdata(pdev, wm8994);
3825
3826 return 0;
3827
3828err_codec:
3829 snd_soc_unregister_codec(codec);
3830err:
3831 kfree(wm8994);
3832 return ret;
3833}
3834
3835static int __devexit wm8994_codec_remove(struct platform_device *pdev)
3836{
3837 struct wm8994_priv *wm8994 = platform_get_drvdata(pdev);
3838 struct snd_soc_codec *codec = &wm8994->codec;
3839
3840 wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF);
3841 snd_soc_unregister_dais(wm8994_dai, ARRAY_SIZE(wm8994_dai));
3842 snd_soc_unregister_codec(&wm8994->codec);
3843 kfree(wm8994);
3844 wm8994_codec = NULL;
3845
3846 return 0;
3847}
3848
3849static struct platform_driver wm8994_codec_driver = {
3850 .driver = {
3851 .name = "wm8994-codec",
3852 .owner = THIS_MODULE,
3853 },
3854 .probe = wm8994_codec_probe,
3855 .remove = __devexit_p(wm8994_codec_remove),
3856};
3857
3858static __init int wm8994_init(void)
3859{
3860 return platform_driver_register(&wm8994_codec_driver);
3861}
3862module_init(wm8994_init);
3863
3864static __exit void wm8994_exit(void)
3865{
3866 platform_driver_unregister(&wm8994_codec_driver);
3867}
3868module_exit(wm8994_exit);
3869
3870
3871MODULE_DESCRIPTION("ASoC WM8994 driver");
3872MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
3873MODULE_LICENSE("GPL");
3874MODULE_ALIAS("platform:wm8994-codec");
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h
new file mode 100644
index 000000000000..0a5e1424dea0
--- /dev/null
+++ b/sound/soc/codecs/wm8994.h
@@ -0,0 +1,26 @@
1/*
2 * wm8994.h -- WM8994 Soc Audio driver
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#ifndef _WM8994_H
10#define _WM8994_H
11
12#include <sound/soc.h>
13
14extern struct snd_soc_codec_device soc_codec_dev_wm8994;
15extern struct snd_soc_dai wm8994_dai[];
16
17/* Sources for AIF1/2 SYSCLK - use with set_dai_sysclk() */
18#define WM8994_SYSCLK_MCLK1 1
19#define WM8994_SYSCLK_MCLK2 2
20#define WM8994_SYSCLK_FLL1 3
21#define WM8994_SYSCLK_FLL2 4
22
23#define WM8994_FLL1 1
24#define WM8994_FLL2 2
25
26#endif
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c
index 686e5aa97206..3a184fcb702b 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>
@@ -1262,19 +1263,9 @@ static int wm9081_probe(struct platform_device *pdev)
1262 snd_soc_dapm_new_controls(codec, wm9081_dapm_widgets, 1263 snd_soc_dapm_new_controls(codec, wm9081_dapm_widgets,
1263 ARRAY_SIZE(wm9081_dapm_widgets)); 1264 ARRAY_SIZE(wm9081_dapm_widgets));
1264 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); 1265 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
1265 snd_soc_dapm_new_widgets(codec);
1266
1267 ret = snd_soc_init_card(socdev);
1268 if (ret < 0) {
1269 dev_err(codec->dev, "failed to register card: %d\n", ret);
1270 goto card_err;
1271 }
1272 1266
1273 return ret; 1267 return ret;
1274 1268
1275card_err:
1276 snd_soc_free_pcms(socdev);
1277 snd_soc_dapm_free(socdev);
1278pcm_err: 1269pcm_err:
1279 return ret; 1270 return ret;
1280} 1271}
@@ -1452,21 +1443,6 @@ static __devexit int wm9081_i2c_remove(struct i2c_client *client)
1452 return 0; 1443 return 0;
1453} 1444}
1454 1445
1455#ifdef CONFIG_PM
1456static int wm9081_i2c_suspend(struct i2c_client *client, pm_message_t msg)
1457{
1458 return snd_soc_suspend_device(&client->dev);
1459}
1460
1461static int wm9081_i2c_resume(struct i2c_client *client)
1462{
1463 return snd_soc_resume_device(&client->dev);
1464}
1465#else
1466#define wm9081_i2c_suspend NULL
1467#define wm9081_i2c_resume NULL
1468#endif
1469
1470static const struct i2c_device_id wm9081_i2c_id[] = { 1446static const struct i2c_device_id wm9081_i2c_id[] = {
1471 { "wm9081", 0 }, 1447 { "wm9081", 0 },
1472 { } 1448 { }
@@ -1480,8 +1456,6 @@ static struct i2c_driver wm9081_i2c_driver = {
1480 }, 1456 },
1481 .probe = wm9081_i2c_probe, 1457 .probe = wm9081_i2c_probe,
1482 .remove = __devexit_p(wm9081_i2c_remove), 1458 .remove = __devexit_p(wm9081_i2c_remove),
1483 .suspend = wm9081_i2c_suspend,
1484 .resume = wm9081_i2c_resume,
1485 .id_table = wm9081_i2c_id, 1459 .id_table = wm9081_i2c_id,
1486}; 1460};
1487 1461
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c
index e7d2840d9e59..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>
@@ -205,7 +206,6 @@ static int wm9705_add_widgets(struct snd_soc_codec *codec)
205 snd_soc_dapm_new_controls(codec, wm9705_dapm_widgets, 206 snd_soc_dapm_new_controls(codec, wm9705_dapm_widgets,
206 ARRAY_SIZE(wm9705_dapm_widgets)); 207 ARRAY_SIZE(wm9705_dapm_widgets));
207 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 208 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
208 snd_soc_dapm_new_widgets(codec);
209 209
210 return 0; 210 return 0;
211} 211}
@@ -403,12 +403,6 @@ static int wm9705_soc_probe(struct platform_device *pdev)
403 ARRAY_SIZE(wm9705_snd_ac97_controls)); 403 ARRAY_SIZE(wm9705_snd_ac97_controls));
404 wm9705_add_widgets(codec); 404 wm9705_add_widgets(codec);
405 405
406 ret = snd_soc_init_card(socdev);
407 if (ret < 0) {
408 printk(KERN_ERR "wm9705: failed to register card\n");
409 goto reset_err;
410 }
411
412 return 0; 406 return 0;
413 407
414reset_err: 408reset_err:
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index 1fd4e88f50cf..2f48a8aae22c 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>
@@ -436,7 +437,6 @@ static int wm9712_add_widgets(struct snd_soc_codec *codec)
436 437
437 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 438 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
438 439
439 snd_soc_dapm_new_widgets(codec);
440 return 0; 440 return 0;
441} 441}
442 442
@@ -464,7 +464,8 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
464{ 464{
465 u16 *cache = codec->reg_cache; 465 u16 *cache = codec->reg_cache;
466 466
467 soc_ac97_ops.write(codec->ac97, reg, val); 467 if (reg < 0x7c)
468 soc_ac97_ops.write(codec->ac97, reg, val);
468 reg = reg >> 1; 469 reg = reg >> 1;
469 if (reg < (ARRAY_SIZE(wm9712_reg))) 470 if (reg < (ARRAY_SIZE(wm9712_reg)))
470 cache[reg] = val; 471 cache[reg] = val;
@@ -695,17 +696,11 @@ static int wm9712_soc_probe(struct platform_device *pdev)
695 snd_soc_add_controls(codec, wm9712_snd_ac97_controls, 696 snd_soc_add_controls(codec, wm9712_snd_ac97_controls,
696 ARRAY_SIZE(wm9712_snd_ac97_controls)); 697 ARRAY_SIZE(wm9712_snd_ac97_controls));
697 wm9712_add_widgets(codec); 698 wm9712_add_widgets(codec);
698 ret = snd_soc_init_card(socdev);
699 if (ret < 0) {
700 printk(KERN_ERR "wm9712: failed to register card\n");
701 goto reset_err;
702 }
703 699
704 return 0; 700 return 0;
705 701
706reset_err: 702reset_err:
707 snd_soc_free_pcms(socdev); 703 snd_soc_free_pcms(socdev);
708
709pcm_err: 704pcm_err:
710 snd_soc_free_ac97_codec(codec); 705 snd_soc_free_ac97_codec(codec);
711 706
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index abed37acf787..2fca514fde58 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>
@@ -23,13 +24,12 @@
23#include <sound/ac97_codec.h> 24#include <sound/ac97_codec.h>
24#include <sound/initval.h> 25#include <sound/initval.h>
25#include <sound/pcm_params.h> 26#include <sound/pcm_params.h>
27#include <sound/tlv.h>
26#include <sound/soc.h> 28#include <sound/soc.h>
27#include <sound/soc-dapm.h> 29#include <sound/soc-dapm.h>
28 30
29#include "wm9713.h" 31#include "wm9713.h"
30 32
31#define WM9713_VERSION "0.15"
32
33struct wm9713_priv { 33struct wm9713_priv {
34 u32 pll_in; /* PLL input frequency */ 34 u32 pll_in; /* PLL input frequency */
35}; 35};
@@ -115,15 +115,27 @@ SOC_ENUM_SINGLE(AC97_3D_CONTROL, 12, 3, wm9713_mic_select), /* mic selection 18
115SOC_ENUM_SINGLE(MICB_MUX, 0, 2, wm9713_micb_select), /* mic selection 19 */ 115SOC_ENUM_SINGLE(MICB_MUX, 0, 2, wm9713_micb_select), /* mic selection 19 */
116}; 116};
117 117
118static const DECLARE_TLV_DB_SCALE(out_tlv, -4650, 150, 0);
119static const DECLARE_TLV_DB_SCALE(main_tlv, -3450, 150, 0);
120static const DECLARE_TLV_DB_SCALE(misc_tlv, -1500, 300, 0);
121static unsigned int mic_tlv[] = {
122 TLV_DB_RANGE_HEAD(2),
123 0, 2, TLV_DB_SCALE_ITEM(1200, 600, 0),
124 3, 3, TLV_DB_SCALE_ITEM(3000, 0, 0),
125};
126
118static const struct snd_kcontrol_new wm9713_snd_ac97_controls[] = { 127static const struct snd_kcontrol_new wm9713_snd_ac97_controls[] = {
119SOC_DOUBLE("Speaker Playback Volume", AC97_MASTER, 8, 0, 31, 1), 128SOC_DOUBLE_TLV("Speaker Playback Volume", AC97_MASTER, 8, 0, 31, 1, out_tlv),
120SOC_DOUBLE("Speaker Playback Switch", AC97_MASTER, 15, 7, 1, 1), 129SOC_DOUBLE("Speaker Playback Switch", AC97_MASTER, 15, 7, 1, 1),
121SOC_DOUBLE("Headphone Playback Volume", AC97_HEADPHONE, 8, 0, 31, 1), 130SOC_DOUBLE_TLV("Headphone Playback Volume", AC97_HEADPHONE, 8, 0, 31, 1,
131 out_tlv),
122SOC_DOUBLE("Headphone Playback Switch", AC97_HEADPHONE, 15, 7, 1, 1), 132SOC_DOUBLE("Headphone Playback Switch", AC97_HEADPHONE, 15, 7, 1, 1),
123SOC_DOUBLE("Line In Volume", AC97_PC_BEEP, 8, 0, 31, 1), 133SOC_DOUBLE_TLV("Line In Volume", AC97_PC_BEEP, 8, 0, 31, 1, main_tlv),
124SOC_DOUBLE("PCM Playback Volume", AC97_PHONE, 8, 0, 31, 1), 134SOC_DOUBLE_TLV("PCM Playback Volume", AC97_PHONE, 8, 0, 31, 1, main_tlv),
125SOC_SINGLE("Mic 1 Volume", AC97_MIC, 8, 31, 1), 135SOC_SINGLE_TLV("Mic 1 Volume", AC97_MIC, 8, 31, 1, main_tlv),
126SOC_SINGLE("Mic 2 Volume", AC97_MIC, 0, 31, 1), 136SOC_SINGLE_TLV("Mic 2 Volume", AC97_MIC, 0, 31, 1, main_tlv),
137SOC_SINGLE_TLV("Mic 1 Preamp Volume", AC97_3D_CONTROL, 10, 3, 0, mic_tlv),
138SOC_SINGLE_TLV("Mic 2 Preamp Volume", AC97_3D_CONTROL, 12, 3, 0, mic_tlv),
127 139
128SOC_SINGLE("Mic Boost (+20dB) Switch", AC97_LINE, 5, 1, 0), 140SOC_SINGLE("Mic Boost (+20dB) Switch", AC97_LINE, 5, 1, 0),
129SOC_SINGLE("Mic Headphone Mixer Volume", AC97_LINE, 0, 7, 1), 141SOC_SINGLE("Mic Headphone Mixer Volume", AC97_LINE, 0, 7, 1),
@@ -133,7 +145,7 @@ SOC_ENUM("Capture Volume Steps", wm9713_enum[5]),
133SOC_DOUBLE("Capture Volume", AC97_CD, 8, 0, 31, 0), 145SOC_DOUBLE("Capture Volume", AC97_CD, 8, 0, 31, 0),
134SOC_SINGLE("Capture ZC Switch", AC97_CD, 7, 1, 0), 146SOC_SINGLE("Capture ZC Switch", AC97_CD, 7, 1, 0),
135 147
136SOC_SINGLE("Capture to Headphone Volume", AC97_VIDEO, 11, 7, 1), 148SOC_SINGLE_TLV("Capture to Headphone Volume", AC97_VIDEO, 11, 7, 1, misc_tlv),
137SOC_SINGLE("Capture to Mono Boost (+20dB) Switch", AC97_VIDEO, 8, 1, 0), 149SOC_SINGLE("Capture to Mono Boost (+20dB) Switch", AC97_VIDEO, 8, 1, 0),
138SOC_SINGLE("Capture ADC Boost (+20dB) Switch", AC97_VIDEO, 6, 1, 0), 150SOC_SINGLE("Capture ADC Boost (+20dB) Switch", AC97_VIDEO, 6, 1, 0),
139 151
@@ -154,28 +166,43 @@ SOC_DOUBLE("Headphone Playback ZC Switch", AC97_HEADPHONE, 14, 6, 1, 0),
154 166
155SOC_SINGLE("Out4 Playback Switch", AC97_MASTER_MONO, 15, 1, 1), 167SOC_SINGLE("Out4 Playback Switch", AC97_MASTER_MONO, 15, 1, 1),
156SOC_SINGLE("Out4 Playback ZC Switch", AC97_MASTER_MONO, 14, 1, 0), 168SOC_SINGLE("Out4 Playback ZC Switch", AC97_MASTER_MONO, 14, 1, 0),
157SOC_SINGLE("Out4 Playback Volume", AC97_MASTER_MONO, 8, 63, 1), 169SOC_SINGLE_TLV("Out4 Playback Volume", AC97_MASTER_MONO, 8, 31, 1, out_tlv),
158 170
159SOC_SINGLE("Out3 Playback Switch", AC97_MASTER_MONO, 7, 1, 1), 171SOC_SINGLE("Out3 Playback Switch", AC97_MASTER_MONO, 7, 1, 1),
160SOC_SINGLE("Out3 Playback ZC Switch", AC97_MASTER_MONO, 6, 1, 0), 172SOC_SINGLE("Out3 Playback ZC Switch", AC97_MASTER_MONO, 6, 1, 0),
161SOC_SINGLE("Out3 Playback Volume", AC97_MASTER_MONO, 0, 63, 1), 173SOC_SINGLE_TLV("Out3 Playback Volume", AC97_MASTER_MONO, 0, 31, 1, out_tlv),
162 174
163SOC_SINGLE("Mono Capture Volume", AC97_MASTER_TONE, 8, 31, 1), 175SOC_SINGLE_TLV("Mono Capture Volume", AC97_MASTER_TONE, 8, 31, 1, main_tlv),
164SOC_SINGLE("Mono Playback Switch", AC97_MASTER_TONE, 7, 1, 1), 176SOC_SINGLE("Mono Playback Switch", AC97_MASTER_TONE, 7, 1, 1),
165SOC_SINGLE("Mono Playback ZC Switch", AC97_MASTER_TONE, 6, 1, 0), 177SOC_SINGLE("Mono Playback ZC Switch", AC97_MASTER_TONE, 6, 1, 0),
166SOC_SINGLE("Mono Playback Volume", AC97_MASTER_TONE, 0, 31, 1), 178SOC_SINGLE_TLV("Mono Playback Volume", AC97_MASTER_TONE, 0, 31, 1, out_tlv),
167 179
168SOC_SINGLE("PC Beep Playback Headphone Volume", AC97_AUX, 12, 7, 1), 180SOC_SINGLE_TLV("Headphone Mixer Beep Playback Volume", AC97_AUX, 12, 7, 1,
169SOC_SINGLE("PC Beep Playback Speaker Volume", AC97_AUX, 8, 7, 1), 181 misc_tlv),
170SOC_SINGLE("PC Beep Playback Mono Volume", AC97_AUX, 4, 7, 1), 182SOC_SINGLE_TLV("Speaker Mixer Beep Playback Volume", AC97_AUX, 8, 7, 1,
183 misc_tlv),
184SOC_SINGLE_TLV("Mono Mixer Beep Playback Volume", AC97_AUX, 4, 7, 1, misc_tlv),
171 185
172SOC_SINGLE("Voice Playback Headphone Volume", AC97_PCM, 12, 7, 1), 186SOC_SINGLE_TLV("Voice Playback Headphone Volume", AC97_PCM, 12, 7, 1,
187 misc_tlv),
173SOC_SINGLE("Voice Playback Master Volume", AC97_PCM, 8, 7, 1), 188SOC_SINGLE("Voice Playback Master Volume", AC97_PCM, 8, 7, 1),
174SOC_SINGLE("Voice Playback Mono Volume", AC97_PCM, 4, 7, 1), 189SOC_SINGLE("Voice Playback Mono Volume", AC97_PCM, 4, 7, 1),
175 190
191SOC_SINGLE_TLV("Headphone Mixer Aux Playback Volume", AC97_REC_SEL, 12, 7, 1,
192 misc_tlv),
193
194SOC_SINGLE_TLV("Speaker Mixer Voice Playback Volume", AC97_PCM, 8, 7, 1,
195 misc_tlv),
196SOC_SINGLE_TLV("Speaker Mixer Aux Playback Volume", AC97_REC_SEL, 8, 7, 1,
197 misc_tlv),
198
199SOC_SINGLE_TLV("Mono Mixer Voice Playback Volume", AC97_PCM, 4, 7, 1,
200 misc_tlv),
201SOC_SINGLE_TLV("Mono Mixer Aux Playback Volume", AC97_REC_SEL, 4, 7, 1,
202 misc_tlv),
203
176SOC_SINGLE("Aux Playback Headphone Volume", AC97_REC_SEL, 12, 7, 1), 204SOC_SINGLE("Aux Playback Headphone Volume", AC97_REC_SEL, 12, 7, 1),
177SOC_SINGLE("Aux Playback Master Volume", AC97_REC_SEL, 8, 7, 1), 205SOC_SINGLE("Aux Playback Master Volume", AC97_REC_SEL, 8, 7, 1),
178SOC_SINGLE("Aux Playback Mono Volume", AC97_REC_SEL, 4, 7, 1),
179 206
180SOC_ENUM("Bass Control", wm9713_enum[16]), 207SOC_ENUM("Bass Control", wm9713_enum[16]),
181SOC_SINGLE("Bass Cut-off Switch", AC97_GENERAL_PURPOSE, 12, 1, 1), 208SOC_SINGLE("Bass Cut-off Switch", AC97_GENERAL_PURPOSE, 12, 1, 1),
@@ -266,7 +293,7 @@ static int mixer_event(struct snd_soc_dapm_widget *w,
266 293
267/* Left Headphone Mixers */ 294/* Left Headphone Mixers */
268static const struct snd_kcontrol_new wm9713_hpl_mixer_controls[] = { 295static const struct snd_kcontrol_new wm9713_hpl_mixer_controls[] = {
269SOC_DAPM_SINGLE("PC Beep Playback Switch", HPL_MIXER, 5, 1, 0), 296SOC_DAPM_SINGLE("Beep Playback Switch", HPL_MIXER, 5, 1, 0),
270SOC_DAPM_SINGLE("Voice Playback Switch", HPL_MIXER, 4, 1, 0), 297SOC_DAPM_SINGLE("Voice Playback Switch", HPL_MIXER, 4, 1, 0),
271SOC_DAPM_SINGLE("Aux Playback Switch", HPL_MIXER, 3, 1, 0), 298SOC_DAPM_SINGLE("Aux Playback Switch", HPL_MIXER, 3, 1, 0),
272SOC_DAPM_SINGLE("PCM Playback Switch", HPL_MIXER, 2, 1, 0), 299SOC_DAPM_SINGLE("PCM Playback Switch", HPL_MIXER, 2, 1, 0),
@@ -276,7 +303,7 @@ SOC_DAPM_SINGLE("Bypass Playback Switch", HPL_MIXER, 0, 1, 0),
276 303
277/* Right Headphone Mixers */ 304/* Right Headphone Mixers */
278static const struct snd_kcontrol_new wm9713_hpr_mixer_controls[] = { 305static const struct snd_kcontrol_new wm9713_hpr_mixer_controls[] = {
279SOC_DAPM_SINGLE("PC Beep Playback Switch", HPR_MIXER, 5, 1, 0), 306SOC_DAPM_SINGLE("Beep Playback Switch", HPR_MIXER, 5, 1, 0),
280SOC_DAPM_SINGLE("Voice Playback Switch", HPR_MIXER, 4, 1, 0), 307SOC_DAPM_SINGLE("Voice Playback Switch", HPR_MIXER, 4, 1, 0),
281SOC_DAPM_SINGLE("Aux Playback Switch", HPR_MIXER, 3, 1, 0), 308SOC_DAPM_SINGLE("Aux Playback Switch", HPR_MIXER, 3, 1, 0),
282SOC_DAPM_SINGLE("PCM Playback Switch", HPR_MIXER, 2, 1, 0), 309SOC_DAPM_SINGLE("PCM Playback Switch", HPR_MIXER, 2, 1, 0),
@@ -294,7 +321,7 @@ SOC_DAPM_ENUM("Route", wm9713_enum[0]);
294 321
295/* Speaker Mixer */ 322/* Speaker Mixer */
296static const struct snd_kcontrol_new wm9713_speaker_mixer_controls[] = { 323static const struct snd_kcontrol_new wm9713_speaker_mixer_controls[] = {
297SOC_DAPM_SINGLE("PC Beep Playback Switch", AC97_AUX, 11, 1, 1), 324SOC_DAPM_SINGLE("Beep Playback Switch", AC97_AUX, 11, 1, 1),
298SOC_DAPM_SINGLE("Voice Playback Switch", AC97_PCM, 11, 1, 1), 325SOC_DAPM_SINGLE("Voice Playback Switch", AC97_PCM, 11, 1, 1),
299SOC_DAPM_SINGLE("Aux Playback Switch", AC97_REC_SEL, 11, 1, 1), 326SOC_DAPM_SINGLE("Aux Playback Switch", AC97_REC_SEL, 11, 1, 1),
300SOC_DAPM_SINGLE("PCM Playback Switch", AC97_PHONE, 14, 1, 1), 327SOC_DAPM_SINGLE("PCM Playback Switch", AC97_PHONE, 14, 1, 1),
@@ -304,7 +331,7 @@ SOC_DAPM_SINGLE("Bypass Playback Switch", AC97_PC_BEEP, 14, 1, 1),
304 331
305/* Mono Mixer */ 332/* Mono Mixer */
306static const struct snd_kcontrol_new wm9713_mono_mixer_controls[] = { 333static const struct snd_kcontrol_new wm9713_mono_mixer_controls[] = {
307SOC_DAPM_SINGLE("PC Beep Playback Switch", AC97_AUX, 7, 1, 1), 334SOC_DAPM_SINGLE("Beep Playback Switch", AC97_AUX, 7, 1, 1),
308SOC_DAPM_SINGLE("Voice Playback Switch", AC97_PCM, 7, 1, 1), 335SOC_DAPM_SINGLE("Voice Playback Switch", AC97_PCM, 7, 1, 1),
309SOC_DAPM_SINGLE("Aux Playback Switch", AC97_REC_SEL, 7, 1, 1), 336SOC_DAPM_SINGLE("Aux Playback Switch", AC97_REC_SEL, 7, 1, 1),
310SOC_DAPM_SINGLE("PCM Playback Switch", AC97_PHONE, 13, 1, 1), 337SOC_DAPM_SINGLE("PCM Playback Switch", AC97_PHONE, 13, 1, 1),
@@ -463,7 +490,7 @@ SND_SOC_DAPM_VMID("VMID"),
463 490
464static const struct snd_soc_dapm_route audio_map[] = { 491static const struct snd_soc_dapm_route audio_map[] = {
465 /* left HP mixer */ 492 /* left HP mixer */
466 {"Left HP Mixer", "PC Beep Playback Switch", "PCBEEP"}, 493 {"Left HP Mixer", "Beep Playback Switch", "PCBEEP"},
467 {"Left HP Mixer", "Voice Playback Switch", "Voice DAC"}, 494 {"Left HP Mixer", "Voice Playback Switch", "Voice DAC"},
468 {"Left HP Mixer", "Aux Playback Switch", "Aux DAC"}, 495 {"Left HP Mixer", "Aux Playback Switch", "Aux DAC"},
469 {"Left HP Mixer", "Bypass Playback Switch", "Left Line In"}, 496 {"Left HP Mixer", "Bypass Playback Switch", "Left Line In"},
@@ -472,7 +499,7 @@ static const struct snd_soc_dapm_route audio_map[] = {
472 {"Left HP Mixer", NULL, "Capture Headphone Mux"}, 499 {"Left HP Mixer", NULL, "Capture Headphone Mux"},
473 500
474 /* right HP mixer */ 501 /* right HP mixer */
475 {"Right HP Mixer", "PC Beep Playback Switch", "PCBEEP"}, 502 {"Right HP Mixer", "Beep Playback Switch", "PCBEEP"},
476 {"Right HP Mixer", "Voice Playback Switch", "Voice DAC"}, 503 {"Right HP Mixer", "Voice Playback Switch", "Voice DAC"},
477 {"Right HP Mixer", "Aux Playback Switch", "Aux DAC"}, 504 {"Right HP Mixer", "Aux Playback Switch", "Aux DAC"},
478 {"Right HP Mixer", "Bypass Playback Switch", "Right Line In"}, 505 {"Right HP Mixer", "Bypass Playback Switch", "Right Line In"},
@@ -491,7 +518,7 @@ static const struct snd_soc_dapm_route audio_map[] = {
491 {"Capture Mixer", NULL, "Right Capture Source"}, 518 {"Capture Mixer", NULL, "Right Capture Source"},
492 519
493 /* speaker mixer */ 520 /* speaker mixer */
494 {"Speaker Mixer", "PC Beep Playback Switch", "PCBEEP"}, 521 {"Speaker Mixer", "Beep Playback Switch", "PCBEEP"},
495 {"Speaker Mixer", "Voice Playback Switch", "Voice DAC"}, 522 {"Speaker Mixer", "Voice Playback Switch", "Voice DAC"},
496 {"Speaker Mixer", "Aux Playback Switch", "Aux DAC"}, 523 {"Speaker Mixer", "Aux Playback Switch", "Aux DAC"},
497 {"Speaker Mixer", "Bypass Playback Switch", "Line Mixer"}, 524 {"Speaker Mixer", "Bypass Playback Switch", "Line Mixer"},
@@ -499,7 +526,7 @@ static const struct snd_soc_dapm_route audio_map[] = {
499 {"Speaker Mixer", "MonoIn Playback Switch", "Mono In"}, 526 {"Speaker Mixer", "MonoIn Playback Switch", "Mono In"},
500 527
501 /* mono mixer */ 528 /* mono mixer */
502 {"Mono Mixer", "PC Beep Playback Switch", "PCBEEP"}, 529 {"Mono Mixer", "Beep Playback Switch", "PCBEEP"},
503 {"Mono Mixer", "Voice Playback Switch", "Voice DAC"}, 530 {"Mono Mixer", "Voice Playback Switch", "Voice DAC"},
504 {"Mono Mixer", "Aux Playback Switch", "Aux DAC"}, 531 {"Mono Mixer", "Aux Playback Switch", "Aux DAC"},
505 {"Mono Mixer", "Bypass Playback Switch", "Line Mixer"}, 532 {"Mono Mixer", "Bypass Playback Switch", "Line Mixer"},
@@ -625,7 +652,6 @@ static int wm9713_add_widgets(struct snd_soc_codec *codec)
625 652
626 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 653 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
627 654
628 snd_soc_dapm_new_widgets(codec);
629 return 0; 655 return 0;
630} 656}
631 657
@@ -800,8 +826,8 @@ static int wm9713_set_pll(struct snd_soc_codec *codec,
800 return 0; 826 return 0;
801} 827}
802 828
803static int wm9713_set_dai_pll(struct snd_soc_dai *codec_dai, 829static int wm9713_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
804 int pll_id, unsigned int freq_in, unsigned int freq_out) 830 int source, unsigned int freq_in, unsigned int freq_out)
805{ 831{
806 struct snd_soc_codec *codec = codec_dai->codec; 832 struct snd_soc_codec *codec = codec_dai->codec;
807 return wm9713_set_pll(codec, pll_id, freq_in, freq_out); 833 return wm9713_set_pll(codec, pll_id, freq_in, freq_out);
@@ -1187,8 +1213,6 @@ static int wm9713_soc_probe(struct platform_device *pdev)
1187 struct snd_soc_codec *codec; 1213 struct snd_soc_codec *codec;
1188 int ret = 0, reg; 1214 int ret = 0, reg;
1189 1215
1190 printk(KERN_INFO "WM9713/WM9714 SoC Audio Codec %s\n", WM9713_VERSION);
1191
1192 socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), 1216 socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec),
1193 GFP_KERNEL); 1217 GFP_KERNEL);
1194 if (socdev->card->codec == NULL) 1218 if (socdev->card->codec == NULL)
@@ -1247,14 +1271,11 @@ static int wm9713_soc_probe(struct platform_device *pdev)
1247 snd_soc_add_controls(codec, wm9713_snd_ac97_controls, 1271 snd_soc_add_controls(codec, wm9713_snd_ac97_controls,
1248 ARRAY_SIZE(wm9713_snd_ac97_controls)); 1272 ARRAY_SIZE(wm9713_snd_ac97_controls));
1249 wm9713_add_widgets(codec); 1273 wm9713_add_widgets(codec);
1250 ret = snd_soc_init_card(socdev); 1274
1251 if (ret < 0)
1252 goto reset_err;
1253 return 0; 1275 return 0;
1254 1276
1255reset_err: 1277reset_err:
1256 snd_soc_free_pcms(socdev); 1278 snd_soc_free_pcms(socdev);
1257
1258pcm_err: 1279pcm_err:
1259 snd_soc_free_ac97_codec(codec); 1280 snd_soc_free_ac97_codec(codec);
1260 1281
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index e542027eea89..e1f225a3ac46 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -62,36 +62,108 @@ static const char *speaker_mode_text[] = {
62static const struct soc_enum speaker_mode = 62static const struct soc_enum speaker_mode =
63 SOC_ENUM_SINGLE(WM8993_SPKMIXR_ATTENUATION, 8, 2, speaker_mode_text); 63 SOC_ENUM_SINGLE(WM8993_SPKMIXR_ATTENUATION, 8, 2, speaker_mode_text);
64 64
65static void wait_for_dc_servo(struct snd_soc_codec *codec) 65static void wait_for_dc_servo(struct snd_soc_codec *codec, unsigned int op)
66{ 66{
67 unsigned int reg; 67 unsigned int reg;
68 int count = 0; 68 int count = 0;
69 unsigned int val;
70
71 val = op | WM8993_DCS_ENA_CHAN_0 | WM8993_DCS_ENA_CHAN_1;
72
73 /* Trigger the command */
74 snd_soc_write(codec, WM8993_DC_SERVO_0, val);
69 75
70 dev_dbg(codec->dev, "Waiting for DC servo...\n"); 76 dev_dbg(codec->dev, "Waiting for DC servo...\n");
77
71 do { 78 do {
72 count++; 79 count++;
73 msleep(1); 80 msleep(1);
74 reg = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_0); 81 reg = snd_soc_read(codec, WM8993_DC_SERVO_0);
75 dev_dbg(codec->dev, "DC servo status: %x\n", reg); 82 dev_dbg(codec->dev, "DC servo: %x\n", reg);
76 } while ((reg & WM8993_DCS_CAL_COMPLETE_MASK) 83 } while (reg & op && count < 400);
77 != WM8993_DCS_CAL_COMPLETE_MASK && count < 1000);
78 84
79 if ((reg & WM8993_DCS_CAL_COMPLETE_MASK) 85 if (reg & op)
80 != WM8993_DCS_CAL_COMPLETE_MASK)
81 dev_err(codec->dev, "Timed out waiting for DC Servo\n"); 86 dev_err(codec->dev, "Timed out waiting for DC Servo\n");
82} 87}
83 88
84/* 89/*
90 * Startup calibration of the DC servo
91 */
92static void calibrate_dc_servo(struct snd_soc_codec *codec)
93{
94 struct wm_hubs_data *hubs = codec->private_data;
95 u16 reg, reg_l, reg_r, dcs_cfg;
96
97 /* Set for 32 series updates */
98 snd_soc_update_bits(codec, WM8993_DC_SERVO_1,
99 WM8993_DCS_SERIES_NO_01_MASK,
100 32 << WM8993_DCS_SERIES_NO_01_SHIFT);
101 wait_for_dc_servo(codec,
102 WM8993_DCS_TRIG_SERIES_0 | WM8993_DCS_TRIG_SERIES_1);
103
104 /* Apply correction to DC servo result */
105 if (hubs->dcs_codes) {
106 dev_dbg(codec->dev, "Applying %d code DC servo correction\n",
107 hubs->dcs_codes);
108
109 /* Different chips in the family support different
110 * readback methods.
111 */
112 switch (hubs->dcs_readback_mode) {
113 case 0:
114 reg_l = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_1)
115 & WM8993_DCS_INTEG_CHAN_0_MASK;;
116 reg_r = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2)
117 & WM8993_DCS_INTEG_CHAN_1_MASK;
118 break;
119 case 1:
120 reg = snd_soc_read(codec, WM8993_DC_SERVO_3);
121 reg_l = (reg & WM8993_DCS_DAC_WR_VAL_1_MASK)
122 >> WM8993_DCS_DAC_WR_VAL_1_SHIFT;
123 reg_r = reg & WM8993_DCS_DAC_WR_VAL_0_MASK;
124 break;
125 default:
126 WARN(1, "Unknown DCS readback method");
127 break;
128 }
129
130 /* HPOUT1L */
131 if (reg_l + hubs->dcs_codes > 0 &&
132 reg_l + hubs->dcs_codes < 0xff)
133 reg_l += hubs->dcs_codes;
134 dcs_cfg = reg_l << WM8993_DCS_DAC_WR_VAL_1_SHIFT;
135
136 /* HPOUT1R */
137 if (reg_r + hubs->dcs_codes > 0 &&
138 reg_r + hubs->dcs_codes < 0xff)
139 reg_r += hubs->dcs_codes;
140 dcs_cfg |= reg_r;
141
142 /* Do it */
143 snd_soc_write(codec, WM8993_DC_SERVO_3, dcs_cfg);
144 wait_for_dc_servo(codec,
145 WM8993_DCS_TRIG_DAC_WR_0 |
146 WM8993_DCS_TRIG_DAC_WR_1);
147 }
148}
149
150/*
85 * Update the DC servo calibration on gain changes 151 * Update the DC servo calibration on gain changes
86 */ 152 */
87static int wm8993_put_dc_servo(struct snd_kcontrol *kcontrol, 153static int wm8993_put_dc_servo(struct snd_kcontrol *kcontrol,
88 struct snd_ctl_elem_value *ucontrol) 154 struct snd_ctl_elem_value *ucontrol)
89{ 155{
90 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 156 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
157 struct wm_hubs_data *hubs = codec->private_data;
91 int ret; 158 int ret;
92 159
93 ret = snd_soc_put_volsw_2r(kcontrol, ucontrol); 160 ret = snd_soc_put_volsw_2r(kcontrol, ucontrol);
94 161
162 /* If we're applying an offset correction then updating the
163 * callibration would be likely to introduce further offsets. */
164 if (hubs->dcs_codes)
165 return ret;
166
95 /* Only need to do this if the outputs are active */ 167 /* Only need to do this if the outputs are active */
96 if (snd_soc_read(codec, WM8993_POWER_MANAGEMENT_1) 168 if (snd_soc_read(codec, WM8993_POWER_MANAGEMENT_1)
97 & (WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA)) 169 & (WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA))
@@ -251,6 +323,47 @@ SOC_SINGLE_TLV("LINEOUT2 Volume", WM8993_LINE_OUTPUTS_VOLUME, 0, 1, 1,
251 line_tlv), 323 line_tlv),
252}; 324};
253 325
326static int hp_supply_event(struct snd_soc_dapm_widget *w,
327 struct snd_kcontrol *kcontrol, int event)
328{
329 struct snd_soc_codec *codec = w->codec;
330 struct wm_hubs_data *hubs = codec->private_data;
331
332 switch (event) {
333 case SND_SOC_DAPM_PRE_PMU:
334 switch (hubs->hp_startup_mode) {
335 case 0:
336 break;
337 case 1:
338 /* Enable the headphone amp */
339 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
340 WM8993_HPOUT1L_ENA |
341 WM8993_HPOUT1R_ENA,
342 WM8993_HPOUT1L_ENA |
343 WM8993_HPOUT1R_ENA);
344
345 /* Enable the second stage */
346 snd_soc_update_bits(codec, WM8993_ANALOGUE_HP_0,
347 WM8993_HPOUT1L_DLY |
348 WM8993_HPOUT1R_DLY,
349 WM8993_HPOUT1L_DLY |
350 WM8993_HPOUT1R_DLY);
351 break;
352 default:
353 dev_err(codec->dev, "Unknown HP startup mode %d\n",
354 hubs->hp_startup_mode);
355 break;
356 }
357
358 case SND_SOC_DAPM_PRE_PMD:
359 snd_soc_update_bits(codec, WM8993_CHARGE_PUMP_1,
360 WM8993_CP_ENA, 0);
361 break;
362 }
363
364 return 0;
365}
366
254static int hp_event(struct snd_soc_dapm_widget *w, 367static int hp_event(struct snd_soc_dapm_widget *w,
255 struct snd_kcontrol *kcontrol, int event) 368 struct snd_kcontrol *kcontrol, int event)
256{ 369{
@@ -271,14 +384,11 @@ static int hp_event(struct snd_soc_dapm_widget *w,
271 reg |= WM8993_HPOUT1L_DLY | WM8993_HPOUT1R_DLY; 384 reg |= WM8993_HPOUT1L_DLY | WM8993_HPOUT1R_DLY;
272 snd_soc_write(codec, WM8993_ANALOGUE_HP_0, reg); 385 snd_soc_write(codec, WM8993_ANALOGUE_HP_0, reg);
273 386
274 /* Start the DC servo */ 387 /* Smallest supported update interval */
275 snd_soc_update_bits(codec, WM8993_DC_SERVO_0, 388 snd_soc_update_bits(codec, WM8993_DC_SERVO_1,
276 0xFFFF, 389 WM8993_DCS_TIMER_PERIOD_01_MASK, 1);
277 WM8993_DCS_ENA_CHAN_0 | 390
278 WM8993_DCS_ENA_CHAN_1 | 391 calibrate_dc_servo(codec);
279 WM8993_DCS_TRIG_STARTUP_1 |
280 WM8993_DCS_TRIG_STARTUP_0);
281 wait_for_dc_servo(codec);
282 392
283 reg |= WM8993_HPOUT1R_OUTP | WM8993_HPOUT1R_RMV_SHORT | 393 reg |= WM8993_HPOUT1R_OUTP | WM8993_HPOUT1R_RMV_SHORT |
284 WM8993_HPOUT1L_OUTP | WM8993_HPOUT1L_RMV_SHORT; 394 WM8993_HPOUT1L_OUTP | WM8993_HPOUT1L_RMV_SHORT;
@@ -286,23 +396,19 @@ static int hp_event(struct snd_soc_dapm_widget *w,
286 break; 396 break;
287 397
288 case SND_SOC_DAPM_PRE_PMD: 398 case SND_SOC_DAPM_PRE_PMD:
289 reg &= ~(WM8993_HPOUT1L_RMV_SHORT | 399 snd_soc_update_bits(codec, WM8993_ANALOGUE_HP_0,
290 WM8993_HPOUT1L_DLY | 400 WM8993_HPOUT1L_DLY |
291 WM8993_HPOUT1L_OUTP | 401 WM8993_HPOUT1R_DLY |
292 WM8993_HPOUT1R_RMV_SHORT | 402 WM8993_HPOUT1L_RMV_SHORT |
293 WM8993_HPOUT1R_DLY | 403 WM8993_HPOUT1R_RMV_SHORT, 0);
294 WM8993_HPOUT1R_OUTP);
295 404
296 snd_soc_update_bits(codec, WM8993_DC_SERVO_0, 405 snd_soc_update_bits(codec, WM8993_ANALOGUE_HP_0,
297 0xffff, 0); 406 WM8993_HPOUT1L_OUTP |
407 WM8993_HPOUT1R_OUTP, 0);
298 408
299 snd_soc_write(codec, WM8993_ANALOGUE_HP_0, reg);
300 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1, 409 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
301 WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA, 410 WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA,
302 0); 411 0);
303
304 snd_soc_update_bits(codec, WM8993_CHARGE_PUMP_1,
305 WM8993_CP_ENA, 0);
306 break; 412 break;
307 } 413 }
308 414
@@ -438,11 +544,11 @@ static const struct snd_soc_dapm_widget analogue_dapm_widgets[] = {
438SND_SOC_DAPM_INPUT("IN1LN"), 544SND_SOC_DAPM_INPUT("IN1LN"),
439SND_SOC_DAPM_INPUT("IN1LP"), 545SND_SOC_DAPM_INPUT("IN1LP"),
440SND_SOC_DAPM_INPUT("IN2LN"), 546SND_SOC_DAPM_INPUT("IN2LN"),
441SND_SOC_DAPM_INPUT("IN2LP/VXRN"), 547SND_SOC_DAPM_INPUT("IN2LP:VXRN"),
442SND_SOC_DAPM_INPUT("IN1RN"), 548SND_SOC_DAPM_INPUT("IN1RN"),
443SND_SOC_DAPM_INPUT("IN1RP"), 549SND_SOC_DAPM_INPUT("IN1RP"),
444SND_SOC_DAPM_INPUT("IN2RN"), 550SND_SOC_DAPM_INPUT("IN2RN"),
445SND_SOC_DAPM_INPUT("IN2RP/VXRP"), 551SND_SOC_DAPM_INPUT("IN2RP:VXRP"),
446 552
447SND_SOC_DAPM_MICBIAS("MICBIAS2", WM8993_POWER_MANAGEMENT_1, 5, 0), 553SND_SOC_DAPM_MICBIAS("MICBIAS2", WM8993_POWER_MANAGEMENT_1, 5, 0),
448SND_SOC_DAPM_MICBIAS("MICBIAS1", WM8993_POWER_MANAGEMENT_1, 4, 0), 554SND_SOC_DAPM_MICBIAS("MICBIAS1", WM8993_POWER_MANAGEMENT_1, 4, 0),
@@ -473,6 +579,8 @@ SND_SOC_DAPM_MIXER("Right Output Mixer", WM8993_POWER_MANAGEMENT_3, 4, 0,
473SND_SOC_DAPM_PGA("Left Output PGA", WM8993_POWER_MANAGEMENT_3, 7, 0, NULL, 0), 579SND_SOC_DAPM_PGA("Left Output PGA", WM8993_POWER_MANAGEMENT_3, 7, 0, NULL, 0),
474SND_SOC_DAPM_PGA("Right Output PGA", WM8993_POWER_MANAGEMENT_3, 6, 0, NULL, 0), 580SND_SOC_DAPM_PGA("Right Output PGA", WM8993_POWER_MANAGEMENT_3, 6, 0, NULL, 0),
475 581
582SND_SOC_DAPM_SUPPLY("Headphone Supply", SND_SOC_NOPM, 0, 0, hp_supply_event,
583 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
476SND_SOC_DAPM_PGA_E("Headphone PGA", SND_SOC_NOPM, 0, 0, 584SND_SOC_DAPM_PGA_E("Headphone PGA", SND_SOC_NOPM, 0, 0,
477 NULL, 0, 585 NULL, 0,
478 hp_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 586 hp_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
@@ -537,14 +645,14 @@ static const struct snd_soc_dapm_route analogue_routes[] = {
537 { "IN1R PGA", "IN1RP Switch", "IN1RP" }, 645 { "IN1R PGA", "IN1RP Switch", "IN1RP" },
538 { "IN1R PGA", "IN1RN Switch", "IN1RN" }, 646 { "IN1R PGA", "IN1RN Switch", "IN1RN" },
539 647
540 { "IN2L PGA", "IN2LP Switch", "IN2LP/VXRN" }, 648 { "IN2L PGA", "IN2LP Switch", "IN2LP:VXRN" },
541 { "IN2L PGA", "IN2LN Switch", "IN2LN" }, 649 { "IN2L PGA", "IN2LN Switch", "IN2LN" },
542 650
543 { "IN2R PGA", "IN2RP Switch", "IN2RP/VXRP" }, 651 { "IN2R PGA", "IN2RP Switch", "IN2RP:VXRP" },
544 { "IN2R PGA", "IN2RN Switch", "IN2RN" }, 652 { "IN2R PGA", "IN2RN Switch", "IN2RN" },
545 653
546 { "Direct Voice", NULL, "IN2LP/VXRN" }, 654 { "Direct Voice", NULL, "IN2LP:VXRN" },
547 { "Direct Voice", NULL, "IN2RP/VXRP" }, 655 { "Direct Voice", NULL, "IN2RP:VXRP" },
548 656
549 { "MIXINL", "IN1L Switch", "IN1L PGA" }, 657 { "MIXINL", "IN1L Switch", "IN1L PGA" },
550 { "MIXINL", "IN2L Switch", "IN2L PGA" }, 658 { "MIXINL", "IN2L Switch", "IN2L PGA" },
@@ -565,7 +673,7 @@ static const struct snd_soc_dapm_route analogue_routes[] = {
565 { "Left Output Mixer", "Right Input Switch", "MIXINR" }, 673 { "Left Output Mixer", "Right Input Switch", "MIXINR" },
566 { "Left Output Mixer", "IN2RN Switch", "IN2RN" }, 674 { "Left Output Mixer", "IN2RN Switch", "IN2RN" },
567 { "Left Output Mixer", "IN2LN Switch", "IN2LN" }, 675 { "Left Output Mixer", "IN2LN Switch", "IN2LN" },
568 { "Left Output Mixer", "IN2LP Switch", "IN2LP/VXRN" }, 676 { "Left Output Mixer", "IN2LP Switch", "IN2LP:VXRN" },
569 { "Left Output Mixer", "IN1L Switch", "IN1L PGA" }, 677 { "Left Output Mixer", "IN1L Switch", "IN1L PGA" },
570 { "Left Output Mixer", "IN1R Switch", "IN1R PGA" }, 678 { "Left Output Mixer", "IN1R Switch", "IN1R PGA" },
571 679
@@ -573,7 +681,7 @@ static const struct snd_soc_dapm_route analogue_routes[] = {
573 { "Right Output Mixer", "Right Input Switch", "MIXINR" }, 681 { "Right Output Mixer", "Right Input Switch", "MIXINR" },
574 { "Right Output Mixer", "IN2LN Switch", "IN2LN" }, 682 { "Right Output Mixer", "IN2LN Switch", "IN2LN" },
575 { "Right Output Mixer", "IN2RN Switch", "IN2RN" }, 683 { "Right Output Mixer", "IN2RN Switch", "IN2RN" },
576 { "Right Output Mixer", "IN2RP Switch", "IN2RP/VXRP" }, 684 { "Right Output Mixer", "IN2RP Switch", "IN2RP:VXRP" },
577 { "Right Output Mixer", "IN1L Switch", "IN1L PGA" }, 685 { "Right Output Mixer", "IN1L Switch", "IN1L PGA" },
578 { "Right Output Mixer", "IN1R Switch", "IN1R PGA" }, 686 { "Right Output Mixer", "IN1R Switch", "IN1R PGA" },
579 687
@@ -626,6 +734,7 @@ static const struct snd_soc_dapm_route analogue_routes[] = {
626 { "Headphone PGA", NULL, "Left Headphone Mux" }, 734 { "Headphone PGA", NULL, "Left Headphone Mux" },
627 { "Headphone PGA", NULL, "Right Headphone Mux" }, 735 { "Headphone PGA", NULL, "Right Headphone Mux" },
628 { "Headphone PGA", NULL, "CLK_SYS" }, 736 { "Headphone PGA", NULL, "CLK_SYS" },
737 { "Headphone PGA", NULL, "Headphone Supply" },
629 738
630 { "HPOUT1L", NULL, "Headphone PGA" }, 739 { "HPOUT1L", NULL, "Headphone PGA" },
631 { "HPOUT1R", NULL, "Headphone PGA" }, 740 { "HPOUT1R", NULL, "Headphone PGA" },
@@ -738,6 +847,47 @@ int wm_hubs_add_analogue_routes(struct snd_soc_codec *codec,
738} 847}
739EXPORT_SYMBOL_GPL(wm_hubs_add_analogue_routes); 848EXPORT_SYMBOL_GPL(wm_hubs_add_analogue_routes);
740 849
850int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *codec,
851 int lineout1_diff, int lineout2_diff,
852 int lineout1fb, int lineout2fb,
853 int jd_scthr, int jd_thr, int micbias1_lvl,
854 int micbias2_lvl)
855{
856 if (!lineout1_diff)
857 snd_soc_update_bits(codec, WM8993_LINE_MIXER1,
858 WM8993_LINEOUT1_MODE,
859 WM8993_LINEOUT1_MODE);
860 if (!lineout2_diff)
861 snd_soc_update_bits(codec, WM8993_LINE_MIXER2,
862 WM8993_LINEOUT2_MODE,
863 WM8993_LINEOUT2_MODE);
864
865 /* If the line outputs are differential then we aren't presenting
866 * VMID as an output and can disable it.
867 */
868 if (lineout1_diff && lineout2_diff)
869 codec->idle_bias_off = 1;
870
871 if (lineout1fb)
872 snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL,
873 WM8993_LINEOUT1_FB, WM8993_LINEOUT1_FB);
874
875 if (lineout2fb)
876 snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL,
877 WM8993_LINEOUT2_FB, WM8993_LINEOUT2_FB);
878
879 snd_soc_update_bits(codec, WM8993_MICBIAS,
880 WM8993_JD_SCTHR_MASK | WM8993_JD_THR_MASK |
881 WM8993_MICB1_LVL | WM8993_MICB2_LVL,
882 jd_scthr << WM8993_JD_SCTHR_SHIFT |
883 jd_thr << WM8993_JD_THR_SHIFT |
884 micbias1_lvl |
885 micbias2_lvl << WM8993_MICB2_LVL_SHIFT);
886
887 return 0;
888}
889EXPORT_SYMBOL_GPL(wm_hubs_handle_analogue_pdata);
890
741MODULE_DESCRIPTION("Shared support for Wolfson hubs products"); 891MODULE_DESCRIPTION("Shared support for Wolfson hubs products");
742MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 892MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
743MODULE_LICENSE("GPL"); 893MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm_hubs.h b/sound/soc/codecs/wm_hubs.h
index ec09cb6a2939..e51c16683589 100644
--- a/sound/soc/codecs/wm_hubs.h
+++ b/sound/soc/codecs/wm_hubs.h
@@ -18,7 +18,19 @@ struct snd_soc_codec;
18 18
19extern const unsigned int wm_hubs_spkmix_tlv[]; 19extern const unsigned int wm_hubs_spkmix_tlv[];
20 20
21/* This *must* be the first element of the codec->private_data struct */
22struct wm_hubs_data {
23 int dcs_codes;
24 int dcs_readback_mode;
25 int hp_startup_mode;
26};
27
21extern int wm_hubs_add_analogue_controls(struct snd_soc_codec *); 28extern int wm_hubs_add_analogue_controls(struct snd_soc_codec *);
22extern int wm_hubs_add_analogue_routes(struct snd_soc_codec *, int, int); 29extern int wm_hubs_add_analogue_routes(struct snd_soc_codec *, int, int);
30extern int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *,
31 int lineout1_diff, int lineout2_diff,
32 int lineout1fb, int lineout2fb,
33 int jd_scthr, int jd_thr,
34 int micbias1_lvl, int micbias2_lvl);
23 35
24#endif 36#endif
diff --git a/sound/soc/davinci/Kconfig b/sound/soc/davinci/Kconfig
index 4dfd4ad9d90e..047ee39418c0 100644
--- a/sound/soc/davinci/Kconfig
+++ b/sound/soc/davinci/Kconfig
@@ -13,9 +13,9 @@ config SND_DAVINCI_SOC_MCASP
13 tristate 13 tristate
14 14
15config SND_DAVINCI_SOC_EVM 15config SND_DAVINCI_SOC_EVM
16 tristate "SoC Audio support for DaVinci DM6446 or DM355 EVM" 16 tristate "SoC Audio support for DaVinci DM6446, DM355 or DM365 EVM"
17 depends on SND_DAVINCI_SOC 17 depends on SND_DAVINCI_SOC
18 depends on MACH_DAVINCI_EVM || MACH_DAVINCI_DM355_EVM 18 depends on MACH_DAVINCI_EVM || MACH_DAVINCI_DM355_EVM || MACH_DAVINCI_DM365_EVM
19 select SND_DAVINCI_SOC_I2S 19 select SND_DAVINCI_SOC_I2S
20 select SND_SOC_TLV320AIC3X 20 select SND_SOC_TLV320AIC3X
21 help 21 help
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c
index 67414f659405..7ccbe6684fc2 100644
--- a/sound/soc/davinci/davinci-evm.c
+++ b/sound/soc/davinci/davinci-evm.c
@@ -45,7 +45,8 @@ static int evm_hw_params(struct snd_pcm_substream *substream,
45 unsigned sysclk; 45 unsigned sysclk;
46 46
47 /* ASP1 on DM355 EVM is clocked by an external oscillator */ 47 /* ASP1 on DM355 EVM is clocked by an external oscillator */
48 if (machine_is_davinci_dm355_evm() || machine_is_davinci_dm6467_evm()) 48 if (machine_is_davinci_dm355_evm() || machine_is_davinci_dm6467_evm() ||
49 machine_is_davinci_dm365_evm())
49 sysclk = 27000000; 50 sysclk = 27000000;
50 51
51 /* ASP0 in DM6446 EVM is clocked by U55, as configured by 52 /* ASP0 in DM6446 EVM is clocked by U55, as configured by
@@ -176,7 +177,7 @@ static struct snd_soc_dai_link da8xx_evm_dai = {
176 .ops = &evm_ops, 177 .ops = &evm_ops,
177}; 178};
178 179
179/* davinci-evm audio machine driver */ 180/* davinci dm6446, dm355 or dm365 evm audio machine driver */
180static struct snd_soc_card snd_soc_card_evm = { 181static struct snd_soc_card snd_soc_card_evm = {
181 .name = "DaVinci EVM", 182 .name = "DaVinci EVM",
182 .platform = &davinci_soc_platform, 183 .platform = &davinci_soc_platform,
@@ -243,7 +244,7 @@ static int __init evm_init(void)
243 int index; 244 int index;
244 int ret; 245 int ret;
245 246
246 if (machine_is_davinci_evm()) { 247 if (machine_is_davinci_evm() || machine_is_davinci_dm365_evm()) {
247 evm_snd_dev_data = &evm_snd_devdata; 248 evm_snd_dev_data = &evm_snd_devdata;
248 index = 0; 249 index = 0;
249 } else if (machine_is_davinci_dm355_evm()) { 250 } else if (machine_is_davinci_dm355_evm()) {
diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c
index 4ae707048021..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>
@@ -97,12 +98,24 @@ enum {
97 DAVINCI_MCBSP_WORD_32, 98 DAVINCI_MCBSP_WORD_32,
98}; 99};
99 100
101static const unsigned char data_type[SNDRV_PCM_FORMAT_S32_LE + 1] = {
102 [SNDRV_PCM_FORMAT_S8] = 1,
103 [SNDRV_PCM_FORMAT_S16_LE] = 2,
104 [SNDRV_PCM_FORMAT_S32_LE] = 4,
105};
106
107static const unsigned char asp_word_length[SNDRV_PCM_FORMAT_S32_LE + 1] = {
108 [SNDRV_PCM_FORMAT_S8] = DAVINCI_MCBSP_WORD_8,
109 [SNDRV_PCM_FORMAT_S16_LE] = DAVINCI_MCBSP_WORD_16,
110 [SNDRV_PCM_FORMAT_S32_LE] = DAVINCI_MCBSP_WORD_32,
111};
112
113static const unsigned char double_fmt[SNDRV_PCM_FORMAT_S32_LE + 1] = {
114 [SNDRV_PCM_FORMAT_S8] = SNDRV_PCM_FORMAT_S16_LE,
115 [SNDRV_PCM_FORMAT_S16_LE] = SNDRV_PCM_FORMAT_S32_LE,
116};
117
100struct davinci_mcbsp_dev { 118struct davinci_mcbsp_dev {
101 /*
102 * dma_params must be first because rtd->dai->cpu_dai->private_data
103 * is cast to a pointer of an array of struct davinci_pcm_dma_params in
104 * davinci_pcm_open.
105 */
106 struct davinci_pcm_dma_params dma_params[2]; 119 struct davinci_pcm_dma_params dma_params[2];
107 void __iomem *base; 120 void __iomem *base;
108#define MOD_DSP_A 0 121#define MOD_DSP_A 0
@@ -110,6 +123,27 @@ struct davinci_mcbsp_dev {
110 int mode; 123 int mode;
111 u32 pcr; 124 u32 pcr;
112 struct clk *clk; 125 struct clk *clk;
126 /*
127 * Combining both channels into 1 element will at least double the
128 * amount of time between servicing the dma channel, increase
129 * effiency, and reduce the chance of overrun/underrun. But,
130 * it will result in the left & right channels being swapped.
131 *
132 * If relabeling the left and right channels is not possible,
133 * you may want to let the codec know to swap them back.
134 *
135 * It may allow x10 the amount of time to service dma requests,
136 * if the codec is master and is using an unnecessarily fast bit clock
137 * (ie. tlvaic23b), independent of the sample rate. So, having an
138 * entire frame at once means it can be serviced at the sample rate
139 * instead of the bit clock rate.
140 *
141 * In the now unlikely case that an underrun still
142 * occurs, both the left and right samples will be repeated
143 * so that no pops are heard, and the left and right channels
144 * won't end up being swapped because of the underrun.
145 */
146 unsigned enable_channel_combine:1;
113}; 147};
114 148
115static inline void davinci_mcbsp_write_reg(struct davinci_mcbsp_dev *dev, 149static inline void davinci_mcbsp_write_reg(struct davinci_mcbsp_dev *dev,
@@ -349,6 +383,8 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
349 int mcbsp_word_length; 383 int mcbsp_word_length;
350 unsigned int rcr, xcr, srgr; 384 unsigned int rcr, xcr, srgr;
351 u32 spcr; 385 u32 spcr;
386 snd_pcm_format_t fmt;
387 unsigned element_cnt = 1;
352 388
353 /* general line settings */ 389 /* general line settings */
354 spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG); 390 spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
@@ -378,27 +414,24 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
378 xcr |= DAVINCI_MCBSP_XCR_XDATDLY(1); 414 xcr |= DAVINCI_MCBSP_XCR_XDATDLY(1);
379 } 415 }
380 /* Determine xfer data type */ 416 /* Determine xfer data type */
381 switch (params_format(params)) { 417 fmt = params_format(params);
382 case SNDRV_PCM_FORMAT_S8: 418 if ((fmt > SNDRV_PCM_FORMAT_S32_LE) || !data_type[fmt]) {
383 dma_params->data_type = 1;
384 mcbsp_word_length = DAVINCI_MCBSP_WORD_8;
385 break;
386 case SNDRV_PCM_FORMAT_S16_LE:
387 dma_params->data_type = 2;
388 mcbsp_word_length = DAVINCI_MCBSP_WORD_16;
389 break;
390 case SNDRV_PCM_FORMAT_S32_LE:
391 dma_params->data_type = 4;
392 mcbsp_word_length = DAVINCI_MCBSP_WORD_32;
393 break;
394 default:
395 printk(KERN_WARNING "davinci-i2s: unsupported PCM format\n"); 419 printk(KERN_WARNING "davinci-i2s: unsupported PCM format\n");
396 return -EINVAL; 420 return -EINVAL;
397 } 421 }
398 422
399 dma_params->acnt = dma_params->data_type; 423 if (params_channels(params) == 2) {
400 rcr |= DAVINCI_MCBSP_RCR_RFRLEN1(1); 424 element_cnt = 2;
401 xcr |= DAVINCI_MCBSP_XCR_XFRLEN1(1); 425 if (double_fmt[fmt] && dev->enable_channel_combine) {
426 element_cnt = 1;
427 fmt = double_fmt[fmt];
428 }
429 }
430 dma_params->acnt = dma_params->data_type = data_type[fmt];
431 dma_params->fifo_level = 0;
432 mcbsp_word_length = asp_word_length[fmt];
433 rcr |= DAVINCI_MCBSP_RCR_RFRLEN1(element_cnt - 1);
434 xcr |= DAVINCI_MCBSP_XCR_XFRLEN1(element_cnt - 1);
402 435
403 rcr |= DAVINCI_MCBSP_RCR_RWDLEN1(mcbsp_word_length) | 436 rcr |= DAVINCI_MCBSP_RCR_RWDLEN1(mcbsp_word_length) |
404 DAVINCI_MCBSP_RCR_RWDLEN2(mcbsp_word_length); 437 DAVINCI_MCBSP_RCR_RWDLEN2(mcbsp_word_length);
@@ -513,7 +546,13 @@ static int davinci_i2s_probe(struct platform_device *pdev)
513 ret = -ENOMEM; 546 ret = -ENOMEM;
514 goto err_release_region; 547 goto err_release_region;
515 } 548 }
516 549 if (pdata) {
550 dev->enable_channel_combine = pdata->enable_channel_combine;
551 dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].sram_size =
552 pdata->sram_size_playback;
553 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].sram_size =
554 pdata->sram_size_capture;
555 }
517 dev->clk = clk_get(&pdev->dev, NULL); 556 dev->clk = clk_get(&pdev->dev, NULL);
518 if (IS_ERR(dev->clk)) { 557 if (IS_ERR(dev->clk)) {
519 ret = -ENODEV; 558 ret = -ENODEV;
@@ -547,6 +586,8 @@ static int davinci_i2s_probe(struct platform_device *pdev)
547 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].channel = res->start; 586 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].channel = res->start;
548 587
549 davinci_i2s_dai.private_data = dev; 588 davinci_i2s_dai.private_data = dev;
589 davinci_i2s_dai.capture.dma_data = dev->dma_params;
590 davinci_i2s_dai.playback.dma_data = dev->dma_params;
550 ret = snd_soc_register_dai(&davinci_i2s_dai); 591 ret = snd_soc_register_dai(&davinci_i2s_dai);
551 if (ret != 0) 592 if (ret != 0)
552 goto err_free_mem; 593 goto err_free_mem;
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index 5d1f98a4c978..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>
@@ -714,16 +715,13 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
714 struct davinci_pcm_dma_params *dma_params = 715 struct davinci_pcm_dma_params *dma_params =
715 &dev->dma_params[substream->stream]; 716 &dev->dma_params[substream->stream];
716 int word_length; 717 int word_length;
717 u8 numevt; 718 u8 fifo_level;
718 719
719 davinci_hw_common_param(dev, substream->stream); 720 davinci_hw_common_param(dev, substream->stream);
720 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 721 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
721 numevt = dev->txnumevt; 722 fifo_level = dev->txnumevt;
722 else 723 else
723 numevt = dev->rxnumevt; 724 fifo_level = dev->rxnumevt;
724
725 if (!numevt)
726 numevt = 1;
727 725
728 if (dev->op_mode == DAVINCI_MCASP_DIT_MODE) 726 if (dev->op_mode == DAVINCI_MCASP_DIT_MODE)
729 davinci_hw_dit_param(dev); 727 davinci_hw_dit_param(dev);
@@ -751,12 +749,12 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
751 return -EINVAL; 749 return -EINVAL;
752 } 750 }
753 751
754 if (dev->version == MCASP_VERSION_2) { 752 if (dev->version == MCASP_VERSION_2 && !fifo_level)
755 dma_params->data_type *= numevt; 753 dma_params->acnt = 4;
756 dma_params->acnt = 4 * numevt; 754 else
757 } else
758 dma_params->acnt = dma_params->data_type; 755 dma_params->acnt = dma_params->data_type;
759 756
757 dma_params->fifo_level = fifo_level;
760 davinci_config_channel_size(dev, word_length); 758 davinci_config_channel_size(dev, word_length);
761 759
762 return 0; 760 return 0;
@@ -770,14 +768,26 @@ static int davinci_mcasp_trigger(struct snd_pcm_substream *substream,
770 int ret = 0; 768 int ret = 0;
771 769
772 switch (cmd) { 770 switch (cmd) {
773 case SNDRV_PCM_TRIGGER_START:
774 case SNDRV_PCM_TRIGGER_RESUME: 771 case SNDRV_PCM_TRIGGER_RESUME:
772 case SNDRV_PCM_TRIGGER_START:
775 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 773 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
774 if (!dev->clk_active) {
775 clk_enable(dev->clk);
776 dev->clk_active = 1;
777 }
776 davinci_mcasp_start(dev, substream->stream); 778 davinci_mcasp_start(dev, substream->stream);
777 break; 779 break;
778 780
779 case SNDRV_PCM_TRIGGER_STOP:
780 case SNDRV_PCM_TRIGGER_SUSPEND: 781 case SNDRV_PCM_TRIGGER_SUSPEND:
782 davinci_mcasp_stop(dev, substream->stream);
783 if (dev->clk_active) {
784 clk_disable(dev->clk);
785 dev->clk_active = 0;
786 }
787
788 break;
789
790 case SNDRV_PCM_TRIGGER_STOP:
781 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 791 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
782 davinci_mcasp_stop(dev, substream->stream); 792 davinci_mcasp_stop(dev, substream->stream);
783 break; 793 break;
@@ -869,6 +879,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
869 } 879 }
870 880
871 clk_enable(dev->clk); 881 clk_enable(dev->clk);
882 dev->clk_active = 1;
872 883
873 dev->base = (void __iomem *)IO_ADDRESS(mem->start); 884 dev->base = (void __iomem *)IO_ADDRESS(mem->start);
874 dev->op_mode = pdata->op_mode; 885 dev->op_mode = pdata->op_mode;
@@ -907,6 +918,8 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
907 918
908 dma_data->channel = res->start; 919 dma_data->channel = res->start;
909 davinci_mcasp_dai[pdata->op_mode].private_data = dev; 920 davinci_mcasp_dai[pdata->op_mode].private_data = dev;
921 davinci_mcasp_dai[pdata->op_mode].capture.dma_data = dev->dma_params;
922 davinci_mcasp_dai[pdata->op_mode].playback.dma_data = dev->dma_params;
910 davinci_mcasp_dai[pdata->op_mode].dev = &pdev->dev; 923 davinci_mcasp_dai[pdata->op_mode].dev = &pdev->dev;
911 ret = snd_soc_register_dai(&davinci_mcasp_dai[pdata->op_mode]); 924 ret = snd_soc_register_dai(&davinci_mcasp_dai[pdata->op_mode]);
912 925
diff --git a/sound/soc/davinci/davinci-mcasp.h b/sound/soc/davinci/davinci-mcasp.h
index 9d179cc88f7b..e755b5121ec7 100644
--- a/sound/soc/davinci/davinci-mcasp.h
+++ b/sound/soc/davinci/davinci-mcasp.h
@@ -39,16 +39,12 @@ enum {
39}; 39};
40 40
41struct davinci_audio_dev { 41struct davinci_audio_dev {
42 /*
43 * dma_params must be first because rtd->dai->cpu_dai->private_data
44 * is cast to a pointer of an array of struct davinci_pcm_dma_params in
45 * davinci_pcm_open.
46 */
47 struct davinci_pcm_dma_params dma_params[2]; 42 struct davinci_pcm_dma_params dma_params[2];
48 void __iomem *base; 43 void __iomem *base;
49 int sample_rate; 44 int sample_rate;
50 struct clk *clk; 45 struct clk *clk;
51 unsigned int codec_fmt; 46 unsigned int codec_fmt;
47 u8 clk_active;
52 48
53 /* McASP specific data */ 49 /* McASP specific data */
54 int tdm_slots; 50 int tdm_slots;
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c
index c73a915f233f..2dc406f42fe7 100644
--- a/sound/soc/davinci/davinci-pcm.c
+++ b/sound/soc/davinci/davinci-pcm.c
@@ -3,6 +3,7 @@
3 * 3 *
4 * Author: Vladimir Barinov, <vbarinov@embeddedalley.com> 4 * Author: Vladimir Barinov, <vbarinov@embeddedalley.com>
5 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com> 5 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com>
6 * added SRAM ping/pong (C) 2008 Troy Kisky <troy.kisky@boundarydevices.com>
6 * 7 *
7 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
@@ -23,10 +24,51 @@
23 24
24#include <asm/dma.h> 25#include <asm/dma.h>
25#include <mach/edma.h> 26#include <mach/edma.h>
27#include <mach/sram.h>
26 28
27#include "davinci-pcm.h" 29#include "davinci-pcm.h"
28 30
29static struct snd_pcm_hardware davinci_pcm_hardware = { 31#ifdef DEBUG
32static void print_buf_info(int slot, char *name)
33{
34 struct edmacc_param p;
35 if (slot < 0)
36 return;
37 edma_read_slot(slot, &p);
38 printk(KERN_DEBUG "%s: 0x%x, opt=%x, src=%x, a_b_cnt=%x dst=%x\n",
39 name, slot, p.opt, p.src, p.a_b_cnt, p.dst);
40 printk(KERN_DEBUG " src_dst_bidx=%x link_bcntrld=%x src_dst_cidx=%x ccnt=%x\n",
41 p.src_dst_bidx, p.link_bcntrld, p.src_dst_cidx, p.ccnt);
42}
43#else
44static void print_buf_info(int slot, char *name)
45{
46}
47#endif
48
49static struct snd_pcm_hardware pcm_hardware_playback = {
50 .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
51 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
52 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
53 .formats = (SNDRV_PCM_FMTBIT_S16_LE),
54 .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
55 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 |
56 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
57 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
58 SNDRV_PCM_RATE_KNOT),
59 .rate_min = 8000,
60 .rate_max = 96000,
61 .channels_min = 2,
62 .channels_max = 2,
63 .buffer_bytes_max = 128 * 1024,
64 .period_bytes_min = 32,
65 .period_bytes_max = 8 * 1024,
66 .periods_min = 16,
67 .periods_max = 255,
68 .fifo_size = 0,
69};
70
71static struct snd_pcm_hardware pcm_hardware_capture = {
30 .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | 72 .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
31 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | 73 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
32 SNDRV_PCM_INFO_PAUSE), 74 SNDRV_PCM_INFO_PAUSE),
@@ -48,102 +90,410 @@ static struct snd_pcm_hardware davinci_pcm_hardware = {
48 .fifo_size = 0, 90 .fifo_size = 0,
49}; 91};
50 92
93/*
94 * How ping/pong works....
95 *
96 * Playback:
97 * ram_params - copys 2*ping_size from start of SDRAM to iram,
98 * links to ram_link2
99 * ram_link2 - copys rest of SDRAM to iram in ping_size units,
100 * links to ram_link
101 * ram_link - copys entire SDRAM to iram in ping_size uints,
102 * links to self
103 *
104 * asp_params - same as asp_link[0]
105 * asp_link[0] - copys from lower half of iram to asp port
106 * links to asp_link[1], triggers iram copy event on completion
107 * asp_link[1] - copys from upper half of iram to asp port
108 * links to asp_link[0], triggers iram copy event on completion
109 * triggers interrupt only needed to let upper SOC levels update position
110 * in stream on completion
111 *
112 * When playback is started:
113 * ram_params started
114 * asp_params started
115 *
116 * Capture:
117 * ram_params - same as ram_link,
118 * links to ram_link
119 * ram_link - same as playback
120 * links to self
121 *
122 * asp_params - same as playback
123 * asp_link[0] - same as playback
124 * asp_link[1] - same as playback
125 *
126 * When capture is started:
127 * asp_params started
128 */
51struct davinci_runtime_data { 129struct davinci_runtime_data {
52 spinlock_t lock; 130 spinlock_t lock;
53 int period; /* current DMA period */ 131 int period; /* current DMA period */
54 int master_lch; /* Master DMA channel */ 132 int asp_channel; /* Master DMA channel */
55 int slave_lch; /* linked parameter RAM reload slot */ 133 int asp_link[2]; /* asp parameter link channel, ping/pong */
56 struct davinci_pcm_dma_params *params; /* DMA params */ 134 struct davinci_pcm_dma_params *params; /* DMA params */
135 int ram_channel;
136 int ram_link;
137 int ram_link2;
138 struct edmacc_param asp_params;
139 struct edmacc_param ram_params;
57}; 140};
58 141
142/*
143 * Not used with ping/pong
144 */
59static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream) 145static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream)
60{ 146{
61 struct davinci_runtime_data *prtd = substream->runtime->private_data; 147 struct davinci_runtime_data *prtd = substream->runtime->private_data;
62 struct snd_pcm_runtime *runtime = substream->runtime; 148 struct snd_pcm_runtime *runtime = substream->runtime;
63 int lch = prtd->slave_lch; 149 int link = prtd->asp_link[0];
64 unsigned int period_size; 150 unsigned int period_size;
65 unsigned int dma_offset; 151 unsigned int dma_offset;
66 dma_addr_t dma_pos; 152 dma_addr_t dma_pos;
67 dma_addr_t src, dst; 153 dma_addr_t src, dst;
68 unsigned short src_bidx, dst_bidx; 154 unsigned short src_bidx, dst_bidx;
155 unsigned short src_cidx, dst_cidx;
69 unsigned int data_type; 156 unsigned int data_type;
70 unsigned short acnt; 157 unsigned short acnt;
71 unsigned int count; 158 unsigned int count;
159 unsigned int fifo_level;
72 160
73 period_size = snd_pcm_lib_period_bytes(substream); 161 period_size = snd_pcm_lib_period_bytes(substream);
74 dma_offset = prtd->period * period_size; 162 dma_offset = prtd->period * period_size;
75 dma_pos = runtime->dma_addr + dma_offset; 163 dma_pos = runtime->dma_addr + dma_offset;
164 fifo_level = prtd->params->fifo_level;
76 165
77 pr_debug("davinci_pcm: audio_set_dma_params_play channel = %d " 166 pr_debug("davinci_pcm: audio_set_dma_params_play channel = %d "
78 "dma_ptr = %x period_size=%x\n", lch, dma_pos, period_size); 167 "dma_ptr = %x period_size=%x\n", link, dma_pos, period_size);
79 168
80 data_type = prtd->params->data_type; 169 data_type = prtd->params->data_type;
81 count = period_size / data_type; 170 count = period_size / data_type;
171 if (fifo_level)
172 count /= fifo_level;
82 173
83 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 174 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
84 src = dma_pos; 175 src = dma_pos;
85 dst = prtd->params->dma_addr; 176 dst = prtd->params->dma_addr;
86 src_bidx = data_type; 177 src_bidx = data_type;
87 dst_bidx = 0; 178 dst_bidx = 0;
179 src_cidx = data_type * fifo_level;
180 dst_cidx = 0;
88 } else { 181 } else {
89 src = prtd->params->dma_addr; 182 src = prtd->params->dma_addr;
90 dst = dma_pos; 183 dst = dma_pos;
91 src_bidx = 0; 184 src_bidx = 0;
92 dst_bidx = data_type; 185 dst_bidx = data_type;
186 src_cidx = 0;
187 dst_cidx = data_type * fifo_level;
93 } 188 }
94 189
95 acnt = prtd->params->acnt; 190 acnt = prtd->params->acnt;
96 edma_set_src(lch, src, INCR, W8BIT); 191 edma_set_src(link, src, INCR, W8BIT);
97 edma_set_dest(lch, dst, INCR, W8BIT); 192 edma_set_dest(link, dst, INCR, W8BIT);
98 edma_set_src_index(lch, src_bidx, 0); 193
99 edma_set_dest_index(lch, dst_bidx, 0); 194 edma_set_src_index(link, src_bidx, src_cidx);
100 edma_set_transfer_params(lch, acnt, count, 1, 0, ASYNC); 195 edma_set_dest_index(link, dst_bidx, dst_cidx);
196
197 if (!fifo_level)
198 edma_set_transfer_params(link, acnt, count, 1, 0, ASYNC);
199 else
200 edma_set_transfer_params(link, acnt, fifo_level, count,
201 fifo_level, ABSYNC);
101 202
102 prtd->period++; 203 prtd->period++;
103 if (unlikely(prtd->period >= runtime->periods)) 204 if (unlikely(prtd->period >= runtime->periods))
104 prtd->period = 0; 205 prtd->period = 0;
105} 206}
106 207
107static void davinci_pcm_dma_irq(unsigned lch, u16 ch_status, void *data) 208static void davinci_pcm_dma_irq(unsigned link, u16 ch_status, void *data)
108{ 209{
109 struct snd_pcm_substream *substream = data; 210 struct snd_pcm_substream *substream = data;
110 struct davinci_runtime_data *prtd = substream->runtime->private_data; 211 struct davinci_runtime_data *prtd = substream->runtime->private_data;
111 212
112 pr_debug("davinci_pcm: lch=%d, status=0x%x\n", lch, ch_status); 213 print_buf_info(prtd->ram_channel, "i ram_channel");
214 pr_debug("davinci_pcm: link=%d, status=0x%x\n", link, ch_status);
113 215
114 if (unlikely(ch_status != DMA_COMPLETE)) 216 if (unlikely(ch_status != DMA_COMPLETE))
115 return; 217 return;
116 218
117 if (snd_pcm_running(substream)) { 219 if (snd_pcm_running(substream)) {
220 if (prtd->ram_channel < 0) {
221 /* No ping/pong must fix up link dma data*/
222 spin_lock(&prtd->lock);
223 davinci_pcm_enqueue_dma(substream);
224 spin_unlock(&prtd->lock);
225 }
118 snd_pcm_period_elapsed(substream); 226 snd_pcm_period_elapsed(substream);
227 }
228}
229
230static int allocate_sram(struct snd_pcm_substream *substream, unsigned size,
231 struct snd_pcm_hardware *ppcm)
232{
233 struct snd_dma_buffer *buf = &substream->dma_buffer;
234 struct snd_dma_buffer *iram_dma = NULL;
235 dma_addr_t iram_phys = 0;
236 void *iram_virt = NULL;
237
238 if (buf->private_data || !size)
239 return 0;
240
241 ppcm->period_bytes_max = size;
242 iram_virt = sram_alloc(size, &iram_phys);
243 if (!iram_virt)
244 goto exit1;
245 iram_dma = kzalloc(sizeof(*iram_dma), GFP_KERNEL);
246 if (!iram_dma)
247 goto exit2;
248 iram_dma->area = iram_virt;
249 iram_dma->addr = iram_phys;
250 memset(iram_dma->area, 0, size);
251 iram_dma->bytes = size;
252 buf->private_data = iram_dma;
253 return 0;
254exit2:
255 if (iram_virt)
256 sram_free(iram_virt, size);
257exit1:
258 return -ENOMEM;
259}
260
261/*
262 * Only used with ping/pong.
263 * This is called after runtime->dma_addr, period_bytes and data_type are valid
264 */
265static int ping_pong_dma_setup(struct snd_pcm_substream *substream)
266{
267 unsigned short ram_src_cidx, ram_dst_cidx;
268 struct snd_pcm_runtime *runtime = substream->runtime;
269 struct davinci_runtime_data *prtd = runtime->private_data;
270 struct snd_dma_buffer *iram_dma =
271 (struct snd_dma_buffer *)substream->dma_buffer.private_data;
272 struct davinci_pcm_dma_params *params = prtd->params;
273 unsigned int data_type = params->data_type;
274 unsigned int acnt = params->acnt;
275 /* divide by 2 for ping/pong */
276 unsigned int ping_size = snd_pcm_lib_period_bytes(substream) >> 1;
277 int link = prtd->asp_link[1];
278 unsigned int fifo_level = prtd->params->fifo_level;
279 unsigned int count;
280 if ((data_type == 0) || (data_type > 4)) {
281 printk(KERN_ERR "%s: data_type=%i\n", __func__, data_type);
282 return -EINVAL;
283 }
284 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
285 dma_addr_t asp_src_pong = iram_dma->addr + ping_size;
286 ram_src_cidx = ping_size;
287 ram_dst_cidx = -ping_size;
288 edma_set_src(link, asp_src_pong, INCR, W8BIT);
289
290 link = prtd->asp_link[0];
291 edma_set_src_index(link, data_type, data_type * fifo_level);
292 link = prtd->asp_link[1];
293 edma_set_src_index(link, data_type, data_type * fifo_level);
294
295 link = prtd->ram_link;
296 edma_set_src(link, runtime->dma_addr, INCR, W32BIT);
297 } else {
298 dma_addr_t asp_dst_pong = iram_dma->addr + ping_size;
299 ram_src_cidx = -ping_size;
300 ram_dst_cidx = ping_size;
301 edma_set_dest(link, asp_dst_pong, INCR, W8BIT);
302
303 link = prtd->asp_link[0];
304 edma_set_dest_index(link, data_type, data_type * fifo_level);
305 link = prtd->asp_link[1];
306 edma_set_dest_index(link, data_type, data_type * fifo_level);
307
308 link = prtd->ram_link;
309 edma_set_dest(link, runtime->dma_addr, INCR, W32BIT);
310 }
311
312 if (!fifo_level) {
313 count = ping_size / data_type;
314 edma_set_transfer_params(prtd->asp_link[0], acnt, count,
315 1, 0, ASYNC);
316 edma_set_transfer_params(prtd->asp_link[1], acnt, count,
317 1, 0, ASYNC);
318 } else {
319 count = ping_size / (data_type * fifo_level);
320 edma_set_transfer_params(prtd->asp_link[0], acnt, fifo_level,
321 count, fifo_level, ABSYNC);
322 edma_set_transfer_params(prtd->asp_link[1], acnt, fifo_level,
323 count, fifo_level, ABSYNC);
324 }
325
326 link = prtd->ram_link;
327 edma_set_src_index(link, ping_size, ram_src_cidx);
328 edma_set_dest_index(link, ping_size, ram_dst_cidx);
329 edma_set_transfer_params(link, ping_size, 2,
330 runtime->periods, 2, ASYNC);
119 331
120 spin_lock(&prtd->lock); 332 /* init master params */
121 davinci_pcm_enqueue_dma(substream); 333 edma_read_slot(prtd->asp_link[0], &prtd->asp_params);
122 spin_unlock(&prtd->lock); 334 edma_read_slot(prtd->ram_link, &prtd->ram_params);
335 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
336 struct edmacc_param p_ram;
337 /* Copy entire iram buffer before playback started */
338 prtd->ram_params.a_b_cnt = (1 << 16) | (ping_size << 1);
339 /* 0 dst_bidx */
340 prtd->ram_params.src_dst_bidx = (ping_size << 1);
341 /* 0 dst_cidx */
342 prtd->ram_params.src_dst_cidx = (ping_size << 1);
343 prtd->ram_params.ccnt = 1;
344
345 /* Skip 1st period */
346 edma_read_slot(prtd->ram_link, &p_ram);
347 p_ram.src += (ping_size << 1);
348 p_ram.ccnt -= 1;
349 edma_write_slot(prtd->ram_link2, &p_ram);
350 /*
351 * When 1st started, ram -> iram dma channel will fill the
352 * entire iram. Then, whenever a ping/pong asp buffer finishes,
353 * 1/2 iram will be filled.
354 */
355 prtd->ram_params.link_bcntrld =
356 EDMA_CHAN_SLOT(prtd->ram_link2) << 5;
123 } 357 }
358 return 0;
359}
360
361/* 1 asp tx or rx channel using 2 parameter channels
362 * 1 ram to/from iram channel using 1 parameter channel
363 *
364 * Playback
365 * ram copy channel kicks off first,
366 * 1st ram copy of entire iram buffer completion kicks off asp channel
367 * asp tcc always kicks off ram copy of 1/2 iram buffer
368 *
369 * Record
370 * asp channel starts, tcc kicks off ram copy
371 */
372static int request_ping_pong(struct snd_pcm_substream *substream,
373 struct davinci_runtime_data *prtd,
374 struct snd_dma_buffer *iram_dma)
375{
376 dma_addr_t asp_src_ping;
377 dma_addr_t asp_dst_ping;
378 int link;
379 struct davinci_pcm_dma_params *params = prtd->params;
380
381 /* Request ram master channel */
382 link = prtd->ram_channel = edma_alloc_channel(EDMA_CHANNEL_ANY,
383 davinci_pcm_dma_irq, substream,
384 EVENTQ_1);
385 if (link < 0)
386 goto exit1;
387
388 /* Request ram link channel */
389 link = prtd->ram_link = edma_alloc_slot(
390 EDMA_CTLR(prtd->ram_channel), EDMA_SLOT_ANY);
391 if (link < 0)
392 goto exit2;
393
394 link = prtd->asp_link[1] = edma_alloc_slot(
395 EDMA_CTLR(prtd->asp_channel), EDMA_SLOT_ANY);
396 if (link < 0)
397 goto exit3;
398
399 prtd->ram_link2 = -1;
400 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
401 link = prtd->ram_link2 = edma_alloc_slot(
402 EDMA_CTLR(prtd->ram_channel), EDMA_SLOT_ANY);
403 if (link < 0)
404 goto exit4;
405 }
406 /* circle ping-pong buffers */
407 edma_link(prtd->asp_link[0], prtd->asp_link[1]);
408 edma_link(prtd->asp_link[1], prtd->asp_link[0]);
409 /* circle ram buffers */
410 edma_link(prtd->ram_link, prtd->ram_link);
411
412 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
413 asp_src_ping = iram_dma->addr;
414 asp_dst_ping = params->dma_addr; /* fifo */
415 } else {
416 asp_src_ping = params->dma_addr; /* fifo */
417 asp_dst_ping = iram_dma->addr;
418 }
419 /* ping */
420 link = prtd->asp_link[0];
421 edma_set_src(link, asp_src_ping, INCR, W16BIT);
422 edma_set_dest(link, asp_dst_ping, INCR, W16BIT);
423 edma_set_src_index(link, 0, 0);
424 edma_set_dest_index(link, 0, 0);
425
426 edma_read_slot(link, &prtd->asp_params);
427 prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f) | TCINTEN);
428 prtd->asp_params.opt |= TCCHEN | EDMA_TCC(prtd->ram_channel & 0x3f);
429 edma_write_slot(link, &prtd->asp_params);
430
431 /* pong */
432 link = prtd->asp_link[1];
433 edma_set_src(link, asp_src_ping, INCR, W16BIT);
434 edma_set_dest(link, asp_dst_ping, INCR, W16BIT);
435 edma_set_src_index(link, 0, 0);
436 edma_set_dest_index(link, 0, 0);
437
438 edma_read_slot(link, &prtd->asp_params);
439 prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f));
440 /* interrupt after every pong completion */
441 prtd->asp_params.opt |= TCINTEN | TCCHEN |
442 EDMA_TCC(EDMA_CHAN_SLOT(prtd->ram_channel));
443 edma_write_slot(link, &prtd->asp_params);
444
445 /* ram */
446 link = prtd->ram_link;
447 edma_set_src(link, iram_dma->addr, INCR, W32BIT);
448 edma_set_dest(link, iram_dma->addr, INCR, W32BIT);
449 pr_debug("%s: audio dma channels/slots in use for ram:%u %u %u,"
450 "for asp:%u %u %u\n", __func__,
451 prtd->ram_channel, prtd->ram_link, prtd->ram_link2,
452 prtd->asp_channel, prtd->asp_link[0],
453 prtd->asp_link[1]);
454 return 0;
455exit4:
456 edma_free_channel(prtd->asp_link[1]);
457 prtd->asp_link[1] = -1;
458exit3:
459 edma_free_channel(prtd->ram_link);
460 prtd->ram_link = -1;
461exit2:
462 edma_free_channel(prtd->ram_channel);
463 prtd->ram_channel = -1;
464exit1:
465 return link;
124} 466}
125 467
126static int davinci_pcm_dma_request(struct snd_pcm_substream *substream) 468static int davinci_pcm_dma_request(struct snd_pcm_substream *substream)
127{ 469{
470 struct snd_dma_buffer *iram_dma;
128 struct davinci_runtime_data *prtd = substream->runtime->private_data; 471 struct davinci_runtime_data *prtd = substream->runtime->private_data;
129 struct edmacc_param p_ram; 472 struct davinci_pcm_dma_params *params = prtd->params;
130 int ret; 473 int link;
131 474
132 /* Request master DMA channel */ 475 if (!params)
133 ret = edma_alloc_channel(prtd->params->channel, 476 return -ENODEV;
134 davinci_pcm_dma_irq, substream,
135 EVENTQ_0);
136 if (ret < 0)
137 return ret;
138 prtd->master_lch = ret;
139 477
140 /* Request parameter RAM reload slot */ 478 /* Request asp master DMA channel */
141 ret = edma_alloc_slot(EDMA_CTLR(prtd->master_lch), EDMA_SLOT_ANY); 479 link = prtd->asp_channel = edma_alloc_channel(params->channel,
142 if (ret < 0) { 480 davinci_pcm_dma_irq, substream, EVENTQ_0);
143 edma_free_channel(prtd->master_lch); 481 if (link < 0)
144 return ret; 482 goto exit1;
483
484 /* Request asp link channels */
485 link = prtd->asp_link[0] = edma_alloc_slot(
486 EDMA_CTLR(prtd->asp_channel), EDMA_SLOT_ANY);
487 if (link < 0)
488 goto exit2;
489
490 iram_dma = (struct snd_dma_buffer *)substream->dma_buffer.private_data;
491 if (iram_dma) {
492 if (request_ping_pong(substream, prtd, iram_dma) == 0)
493 return 0;
494 printk(KERN_WARNING "%s: dma channel allocation failed,"
495 "not using sram\n", __func__);
145 } 496 }
146 prtd->slave_lch = ret;
147 497
148 /* Issue transfer completion IRQ when the channel completes a 498 /* Issue transfer completion IRQ when the channel completes a
149 * transfer, then always reload from the same slot (by a kind 499 * transfer, then always reload from the same slot (by a kind
@@ -154,12 +504,17 @@ static int davinci_pcm_dma_request(struct snd_pcm_substream *substream)
154 * the buffer and its length (ccnt) ... use it as a template 504 * the buffer and its length (ccnt) ... use it as a template
155 * so davinci_pcm_enqueue_dma() takes less time in IRQ. 505 * so davinci_pcm_enqueue_dma() takes less time in IRQ.
156 */ 506 */
157 edma_read_slot(prtd->slave_lch, &p_ram); 507 edma_read_slot(link, &prtd->asp_params);
158 p_ram.opt |= TCINTEN | EDMA_TCC(EDMA_CHAN_SLOT(prtd->master_lch)); 508 prtd->asp_params.opt |= TCINTEN |
159 p_ram.link_bcntrld = EDMA_CHAN_SLOT(prtd->slave_lch) << 5; 509 EDMA_TCC(EDMA_CHAN_SLOT(prtd->asp_channel));
160 edma_write_slot(prtd->slave_lch, &p_ram); 510 prtd->asp_params.link_bcntrld = EDMA_CHAN_SLOT(link) << 5;
161 511 edma_write_slot(link, &prtd->asp_params);
162 return 0; 512 return 0;
513exit2:
514 edma_free_channel(prtd->asp_channel);
515 prtd->asp_channel = -1;
516exit1:
517 return link;
163} 518}
164 519
165static int davinci_pcm_trigger(struct snd_pcm_substream *substream, int cmd) 520static int davinci_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
@@ -173,12 +528,12 @@ static int davinci_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
173 case SNDRV_PCM_TRIGGER_START: 528 case SNDRV_PCM_TRIGGER_START:
174 case SNDRV_PCM_TRIGGER_RESUME: 529 case SNDRV_PCM_TRIGGER_RESUME:
175 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 530 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
176 edma_start(prtd->master_lch); 531 edma_resume(prtd->asp_channel);
177 break; 532 break;
178 case SNDRV_PCM_TRIGGER_STOP: 533 case SNDRV_PCM_TRIGGER_STOP:
179 case SNDRV_PCM_TRIGGER_SUSPEND: 534 case SNDRV_PCM_TRIGGER_SUSPEND:
180 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 535 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
181 edma_stop(prtd->master_lch); 536 edma_pause(prtd->asp_channel);
182 break; 537 break;
183 default: 538 default:
184 ret = -EINVAL; 539 ret = -EINVAL;
@@ -193,15 +548,37 @@ static int davinci_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
193static int davinci_pcm_prepare(struct snd_pcm_substream *substream) 548static int davinci_pcm_prepare(struct snd_pcm_substream *substream)
194{ 549{
195 struct davinci_runtime_data *prtd = substream->runtime->private_data; 550 struct davinci_runtime_data *prtd = substream->runtime->private_data;
196 struct edmacc_param temp;
197 551
552 if (prtd->ram_channel >= 0) {
553 int ret = ping_pong_dma_setup(substream);
554 if (ret < 0)
555 return ret;
556
557 edma_write_slot(prtd->ram_channel, &prtd->ram_params);
558 edma_write_slot(prtd->asp_channel, &prtd->asp_params);
559
560 print_buf_info(prtd->ram_channel, "ram_channel");
561 print_buf_info(prtd->ram_link, "ram_link");
562 print_buf_info(prtd->ram_link2, "ram_link2");
563 print_buf_info(prtd->asp_channel, "asp_channel");
564 print_buf_info(prtd->asp_link[0], "asp_link[0]");
565 print_buf_info(prtd->asp_link[1], "asp_link[1]");
566
567 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
568 /* copy 1st iram buffer */
569 edma_start(prtd->ram_channel);
570 }
571 edma_start(prtd->asp_channel);
572 return 0;
573 }
198 prtd->period = 0; 574 prtd->period = 0;
199 davinci_pcm_enqueue_dma(substream); 575 davinci_pcm_enqueue_dma(substream);
200 576
201 /* Copy self-linked parameter RAM entry into master channel */ 577 /* Copy self-linked parameter RAM entry into master channel */
202 edma_read_slot(prtd->slave_lch, &temp); 578 edma_read_slot(prtd->asp_link[0], &prtd->asp_params);
203 edma_write_slot(prtd->master_lch, &temp); 579 edma_write_slot(prtd->asp_channel, &prtd->asp_params);
204 davinci_pcm_enqueue_dma(substream); 580 davinci_pcm_enqueue_dma(substream);
581 edma_start(prtd->asp_channel);
205 582
206 return 0; 583 return 0;
207} 584}
@@ -212,20 +589,53 @@ davinci_pcm_pointer(struct snd_pcm_substream *substream)
212 struct snd_pcm_runtime *runtime = substream->runtime; 589 struct snd_pcm_runtime *runtime = substream->runtime;
213 struct davinci_runtime_data *prtd = runtime->private_data; 590 struct davinci_runtime_data *prtd = runtime->private_data;
214 unsigned int offset; 591 unsigned int offset;
215 dma_addr_t count; 592 int asp_count;
216 dma_addr_t src, dst; 593 dma_addr_t asp_src, asp_dst;
217 594
218 spin_lock(&prtd->lock); 595 spin_lock(&prtd->lock);
219 596 if (prtd->ram_channel >= 0) {
220 edma_get_position(prtd->master_lch, &src, &dst); 597 int ram_count;
221 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 598 int mod_ram;
222 count = src - runtime->dma_addr; 599 dma_addr_t ram_src, ram_dst;
223 else 600 unsigned int period_size = snd_pcm_lib_period_bytes(substream);
224 count = dst - runtime->dma_addr; 601 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
225 602 /* reading ram before asp should be safe
603 * as long as the asp transfers less than a ping size
604 * of bytes between the 2 reads
605 */
606 edma_get_position(prtd->ram_channel,
607 &ram_src, &ram_dst);
608 edma_get_position(prtd->asp_channel,
609 &asp_src, &asp_dst);
610 asp_count = asp_src - prtd->asp_params.src;
611 ram_count = ram_src - prtd->ram_params.src;
612 mod_ram = ram_count % period_size;
613 mod_ram -= asp_count;
614 if (mod_ram < 0)
615 mod_ram += period_size;
616 else if (mod_ram == 0) {
617 if (snd_pcm_running(substream))
618 mod_ram += period_size;
619 }
620 ram_count -= mod_ram;
621 if (ram_count < 0)
622 ram_count += period_size * runtime->periods;
623 } else {
624 edma_get_position(prtd->ram_channel,
625 &ram_src, &ram_dst);
626 ram_count = ram_dst - prtd->ram_params.dst;
627 }
628 asp_count = ram_count;
629 } else {
630 edma_get_position(prtd->asp_channel, &asp_src, &asp_dst);
631 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
632 asp_count = asp_src - runtime->dma_addr;
633 else
634 asp_count = asp_dst - runtime->dma_addr;
635 }
226 spin_unlock(&prtd->lock); 636 spin_unlock(&prtd->lock);
227 637
228 offset = bytes_to_frames(runtime, count); 638 offset = bytes_to_frames(runtime, asp_count);
229 if (offset >= runtime->buffer_size) 639 if (offset >= runtime->buffer_size)
230 offset = 0; 640 offset = 0;
231 641
@@ -236,14 +646,21 @@ static int davinci_pcm_open(struct snd_pcm_substream *substream)
236{ 646{
237 struct snd_pcm_runtime *runtime = substream->runtime; 647 struct snd_pcm_runtime *runtime = substream->runtime;
238 struct davinci_runtime_data *prtd; 648 struct davinci_runtime_data *prtd;
649 struct snd_pcm_hardware *ppcm;
239 int ret = 0; 650 int ret = 0;
240 struct snd_soc_pcm_runtime *rtd = substream->private_data; 651 struct snd_soc_pcm_runtime *rtd = substream->private_data;
241 struct davinci_pcm_dma_params *pa = rtd->dai->cpu_dai->private_data; 652 struct davinci_pcm_dma_params *pa;
242 struct davinci_pcm_dma_params *params = &pa[substream->stream]; 653 struct davinci_pcm_dma_params *params;
243 if (!params) 654
655 pa = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
656 if (!pa)
244 return -ENODEV; 657 return -ENODEV;
658 params = &pa[substream->stream];
245 659
246 snd_soc_set_runtime_hwparams(substream, &davinci_pcm_hardware); 660 ppcm = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
661 &pcm_hardware_playback : &pcm_hardware_capture;
662 allocate_sram(substream, params->sram_size, ppcm);
663 snd_soc_set_runtime_hwparams(substream, ppcm);
247 /* ensure that buffer size is a multiple of period size */ 664 /* ensure that buffer size is a multiple of period size */
248 ret = snd_pcm_hw_constraint_integer(runtime, 665 ret = snd_pcm_hw_constraint_integer(runtime,
249 SNDRV_PCM_HW_PARAM_PERIODS); 666 SNDRV_PCM_HW_PARAM_PERIODS);
@@ -256,6 +673,11 @@ static int davinci_pcm_open(struct snd_pcm_substream *substream)
256 673
257 spin_lock_init(&prtd->lock); 674 spin_lock_init(&prtd->lock);
258 prtd->params = params; 675 prtd->params = params;
676 prtd->asp_channel = -1;
677 prtd->asp_link[0] = prtd->asp_link[1] = -1;
678 prtd->ram_channel = -1;
679 prtd->ram_link = -1;
680 prtd->ram_link2 = -1;
259 681
260 runtime->private_data = prtd; 682 runtime->private_data = prtd;
261 683
@@ -273,10 +695,29 @@ static int davinci_pcm_close(struct snd_pcm_substream *substream)
273 struct snd_pcm_runtime *runtime = substream->runtime; 695 struct snd_pcm_runtime *runtime = substream->runtime;
274 struct davinci_runtime_data *prtd = runtime->private_data; 696 struct davinci_runtime_data *prtd = runtime->private_data;
275 697
276 edma_unlink(prtd->slave_lch); 698 if (prtd->ram_channel >= 0)
277 699 edma_stop(prtd->ram_channel);
278 edma_free_slot(prtd->slave_lch); 700 if (prtd->asp_channel >= 0)
279 edma_free_channel(prtd->master_lch); 701 edma_stop(prtd->asp_channel);
702 if (prtd->asp_link[0] >= 0)
703 edma_unlink(prtd->asp_link[0]);
704 if (prtd->asp_link[1] >= 0)
705 edma_unlink(prtd->asp_link[1]);
706 if (prtd->ram_link >= 0)
707 edma_unlink(prtd->ram_link);
708
709 if (prtd->asp_link[0] >= 0)
710 edma_free_slot(prtd->asp_link[0]);
711 if (prtd->asp_link[1] >= 0)
712 edma_free_slot(prtd->asp_link[1]);
713 if (prtd->asp_channel >= 0)
714 edma_free_channel(prtd->asp_channel);
715 if (prtd->ram_link >= 0)
716 edma_free_slot(prtd->ram_link);
717 if (prtd->ram_link2 >= 0)
718 edma_free_slot(prtd->ram_link2);
719 if (prtd->ram_channel >= 0)
720 edma_free_channel(prtd->ram_channel);
280 721
281 kfree(prtd); 722 kfree(prtd);
282 723
@@ -318,11 +759,11 @@ static struct snd_pcm_ops davinci_pcm_ops = {
318 .mmap = davinci_pcm_mmap, 759 .mmap = davinci_pcm_mmap,
319}; 760};
320 761
321static int davinci_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) 762static int davinci_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream,
763 size_t size)
322{ 764{
323 struct snd_pcm_substream *substream = pcm->streams[stream].substream; 765 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
324 struct snd_dma_buffer *buf = &substream->dma_buffer; 766 struct snd_dma_buffer *buf = &substream->dma_buffer;
325 size_t size = davinci_pcm_hardware.buffer_bytes_max;
326 767
327 buf->dev.type = SNDRV_DMA_TYPE_DEV; 768 buf->dev.type = SNDRV_DMA_TYPE_DEV;
328 buf->dev.dev = pcm->card->dev; 769 buf->dev.dev = pcm->card->dev;
@@ -347,6 +788,7 @@ static void davinci_pcm_free(struct snd_pcm *pcm)
347 int stream; 788 int stream;
348 789
349 for (stream = 0; stream < 2; stream++) { 790 for (stream = 0; stream < 2; stream++) {
791 struct snd_dma_buffer *iram_dma;
350 substream = pcm->streams[stream].substream; 792 substream = pcm->streams[stream].substream;
351 if (!substream) 793 if (!substream)
352 continue; 794 continue;
@@ -358,6 +800,11 @@ static void davinci_pcm_free(struct snd_pcm *pcm)
358 dma_free_writecombine(pcm->card->dev, buf->bytes, 800 dma_free_writecombine(pcm->card->dev, buf->bytes,
359 buf->area, buf->addr); 801 buf->area, buf->addr);
360 buf->area = NULL; 802 buf->area = NULL;
803 iram_dma = (struct snd_dma_buffer *)buf->private_data;
804 if (iram_dma) {
805 sram_free(iram_dma->area, iram_dma->bytes);
806 kfree(iram_dma);
807 }
361 } 808 }
362} 809}
363 810
@@ -375,14 +822,16 @@ static int davinci_pcm_new(struct snd_card *card,
375 822
376 if (dai->playback.channels_min) { 823 if (dai->playback.channels_min) {
377 ret = davinci_pcm_preallocate_dma_buffer(pcm, 824 ret = davinci_pcm_preallocate_dma_buffer(pcm,
378 SNDRV_PCM_STREAM_PLAYBACK); 825 SNDRV_PCM_STREAM_PLAYBACK,
826 pcm_hardware_playback.buffer_bytes_max);
379 if (ret) 827 if (ret)
380 return ret; 828 return ret;
381 } 829 }
382 830
383 if (dai->capture.channels_min) { 831 if (dai->capture.channels_min) {
384 ret = davinci_pcm_preallocate_dma_buffer(pcm, 832 ret = davinci_pcm_preallocate_dma_buffer(pcm,
385 SNDRV_PCM_STREAM_CAPTURE); 833 SNDRV_PCM_STREAM_CAPTURE,
834 pcm_hardware_capture.buffer_bytes_max);
386 if (ret) 835 if (ret)
387 return ret; 836 return ret;
388 } 837 }
diff --git a/sound/soc/davinci/davinci-pcm.h b/sound/soc/davinci/davinci-pcm.h
index 8746606efc89..0764944cf10f 100644
--- a/sound/soc/davinci/davinci-pcm.h
+++ b/sound/soc/davinci/davinci-pcm.h
@@ -20,9 +20,11 @@ struct davinci_pcm_dma_params {
20 int channel; /* sync dma channel ID */ 20 int channel; /* sync dma channel ID */
21 unsigned short acnt; 21 unsigned short acnt;
22 dma_addr_t dma_addr; /* device physical address for DMA */ 22 dma_addr_t dma_addr; /* device physical address for DMA */
23 unsigned sram_size;
23 enum dma_event_q eventq_no; /* event queue number */ 24 enum dma_event_q eventq_no; /* event queue number */
24 unsigned char data_type; /* xfer data type */ 25 unsigned char data_type; /* xfer data type */
25 unsigned char convert_mono_stereo; 26 unsigned char convert_mono_stereo;
27 unsigned int fifo_level;
26}; 28};
27 29
28 30
diff --git a/sound/soc/fsl/efika-audio-fabric.c b/sound/soc/fsl/efika-audio-fabric.c
index 3326e2a1e863..1a5b8e0d6a34 100644
--- a/sound/soc/fsl/efika-audio-fabric.c
+++ b/sound/soc/fsl/efika-audio-fabric.c
@@ -55,7 +55,7 @@ static __init int efika_fabric_init(void)
55 struct platform_device *pdev; 55 struct platform_device *pdev;
56 int rc; 56 int rc;
57 57
58 if (!machine_is_compatible("bplan,efika")) 58 if (!of_machine_is_compatible("bplan,efika"))
59 return -ENODEV; 59 return -ENODEV;
60 60
61 card.platform = &mpc5200_audio_dma_platform; 61 card.platform = &mpc5200_audio_dma_platform;
diff --git a/sound/soc/fsl/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 6096d22283e6..d639e55c5124 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
@@ -58,47 +59,15 @@ static void psc_dma_bcom_enqueue_next_buffer(struct psc_dma_stream *s)
58 /* Prepare and enqueue the next buffer descriptor */ 59 /* Prepare and enqueue the next buffer descriptor */
59 bd = bcom_prepare_next_buffer(s->bcom_task); 60 bd = bcom_prepare_next_buffer(s->bcom_task);
60 bd->status = s->period_bytes; 61 bd->status = s->period_bytes;
61 bd->data[0] = s->period_next_pt; 62 bd->data[0] = s->runtime->dma_addr + (s->period_next * s->period_bytes);
62 bcom_submit_next_buffer(s->bcom_task, NULL); 63 bcom_submit_next_buffer(s->bcom_task, NULL);
63 64
64 /* Update for next period */ 65 /* Update for next period */
65 s->period_next_pt += s->period_bytes; 66 s->period_next = (s->period_next + 1) % s->runtime->periods;
66 if (s->period_next_pt >= s->period_end)
67 s->period_next_pt = s->period_start;
68}
69
70static void psc_dma_bcom_enqueue_tx(struct psc_dma_stream *s)
71{
72 if (s->appl_ptr > s->runtime->control->appl_ptr) {
73 /*
74 * In this case s->runtime->control->appl_ptr has wrapped around.
75 * Play the data to the end of the boundary, then wrap our own
76 * appl_ptr back around.
77 */
78 while (s->appl_ptr < s->runtime->boundary) {
79 if (bcom_queue_full(s->bcom_task))
80 return;
81
82 s->appl_ptr += s->period_size;
83
84 psc_dma_bcom_enqueue_next_buffer(s);
85 }
86 s->appl_ptr -= s->runtime->boundary;
87 }
88
89 while (s->appl_ptr < s->runtime->control->appl_ptr) {
90
91 if (bcom_queue_full(s->bcom_task))
92 return;
93
94 s->appl_ptr += s->period_size;
95
96 psc_dma_bcom_enqueue_next_buffer(s);
97 }
98} 67}
99 68
100/* Bestcomm DMA irq handler */ 69/* Bestcomm DMA irq handler */
101static irqreturn_t psc_dma_bcom_irq_tx(int irq, void *_psc_dma_stream) 70static irqreturn_t psc_dma_bcom_irq(int irq, void *_psc_dma_stream)
102{ 71{
103 struct psc_dma_stream *s = _psc_dma_stream; 72 struct psc_dma_stream *s = _psc_dma_stream;
104 73
@@ -108,34 +77,8 @@ static irqreturn_t psc_dma_bcom_irq_tx(int irq, void *_psc_dma_stream)
108 while (bcom_buffer_done(s->bcom_task)) { 77 while (bcom_buffer_done(s->bcom_task)) {
109 bcom_retrieve_buffer(s->bcom_task, NULL, NULL); 78 bcom_retrieve_buffer(s->bcom_task, NULL, NULL);
110 79
111 s->period_current_pt += s->period_bytes; 80 s->period_current = (s->period_current+1) % s->runtime->periods;
112 if (s->period_current_pt >= s->period_end) 81 s->period_count++;
113 s->period_current_pt = s->period_start;
114 }
115 psc_dma_bcom_enqueue_tx(s);
116 spin_unlock(&s->psc_dma->lock);
117
118 /* If the stream is active, then also inform the PCM middle layer
119 * of the period finished event. */
120 if (s->active)
121 snd_pcm_period_elapsed(s->stream);
122
123 return IRQ_HANDLED;
124}
125
126static irqreturn_t psc_dma_bcom_irq_rx(int irq, void *_psc_dma_stream)
127{
128 struct psc_dma_stream *s = _psc_dma_stream;
129
130 spin_lock(&s->psc_dma->lock);
131 /* For each finished period, dequeue the completed period buffer
132 * and enqueue a new one in it's place. */
133 while (bcom_buffer_done(s->bcom_task)) {
134 bcom_retrieve_buffer(s->bcom_task, NULL, NULL);
135
136 s->period_current_pt += s->period_bytes;
137 if (s->period_current_pt >= s->period_end)
138 s->period_current_pt = s->period_start;
139 82
140 psc_dma_bcom_enqueue_next_buffer(s); 83 psc_dma_bcom_enqueue_next_buffer(s);
141 } 84 }
@@ -166,54 +109,38 @@ static int psc_dma_trigger(struct snd_pcm_substream *substream, int cmd)
166 struct snd_soc_pcm_runtime *rtd = substream->private_data; 109 struct snd_soc_pcm_runtime *rtd = substream->private_data;
167 struct psc_dma *psc_dma = rtd->dai->cpu_dai->private_data; 110 struct psc_dma *psc_dma = rtd->dai->cpu_dai->private_data;
168 struct snd_pcm_runtime *runtime = substream->runtime; 111 struct snd_pcm_runtime *runtime = substream->runtime;
169 struct psc_dma_stream *s; 112 struct psc_dma_stream *s = to_psc_dma_stream(substream, psc_dma);
170 struct mpc52xx_psc __iomem *regs = psc_dma->psc_regs; 113 struct mpc52xx_psc __iomem *regs = psc_dma->psc_regs;
171 u16 imr; 114 u16 imr;
172 unsigned long flags; 115 unsigned long flags;
173 int i; 116 int i;
174 117
175 if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE)
176 s = &psc_dma->capture;
177 else
178 s = &psc_dma->playback;
179
180 dev_dbg(psc_dma->dev, "psc_dma_trigger(substream=%p, cmd=%i)"
181 " stream_id=%i\n",
182 substream, cmd, substream->pstr->stream);
183
184 switch (cmd) { 118 switch (cmd) {
185 case SNDRV_PCM_TRIGGER_START: 119 case SNDRV_PCM_TRIGGER_START:
120 dev_dbg(psc_dma->dev, "START: stream=%i fbits=%u ps=%u #p=%u\n",
121 substream->pstr->stream, runtime->frame_bits,
122 (int)runtime->period_size, runtime->periods);
186 s->period_bytes = frames_to_bytes(runtime, 123 s->period_bytes = frames_to_bytes(runtime,
187 runtime->period_size); 124 runtime->period_size);
188 s->period_start = virt_to_phys(runtime->dma_area); 125 s->period_next = 0;
189 s->period_end = s->period_start + 126 s->period_current = 0;
190 (s->period_bytes * runtime->periods);
191 s->period_next_pt = s->period_start;
192 s->period_current_pt = s->period_start;
193 s->period_size = runtime->period_size;
194 s->active = 1; 127 s->active = 1;
195 128 s->period_count = 0;
196 /* track appl_ptr so that we have a better chance of detecting
197 * end of stream and not over running it.
198 */
199 s->runtime = runtime; 129 s->runtime = runtime;
200 s->appl_ptr = s->runtime->control->appl_ptr -
201 (runtime->period_size * runtime->periods);
202 130
203 /* Fill up the bestcomm bd queue and enable DMA. 131 /* Fill up the bestcomm bd queue and enable DMA.
204 * This will begin filling the PSC's fifo. 132 * This will begin filling the PSC's fifo.
205 */ 133 */
206 spin_lock_irqsave(&psc_dma->lock, flags); 134 spin_lock_irqsave(&psc_dma->lock, flags);
207 135
208 if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE) { 136 if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE)
209 bcom_gen_bd_rx_reset(s->bcom_task); 137 bcom_gen_bd_rx_reset(s->bcom_task);
210 for (i = 0; i < runtime->periods; i++) 138 else
211 if (!bcom_queue_full(s->bcom_task))
212 psc_dma_bcom_enqueue_next_buffer(s);
213 } else {
214 bcom_gen_bd_tx_reset(s->bcom_task); 139 bcom_gen_bd_tx_reset(s->bcom_task);
215 psc_dma_bcom_enqueue_tx(s); 140
216 } 141 for (i = 0; i < runtime->periods; i++)
142 if (!bcom_queue_full(s->bcom_task))
143 psc_dma_bcom_enqueue_next_buffer(s);
217 144
218 bcom_enable(s->bcom_task); 145 bcom_enable(s->bcom_task);
219 spin_unlock_irqrestore(&psc_dma->lock, flags); 146 spin_unlock_irqrestore(&psc_dma->lock, flags);
@@ -223,6 +150,8 @@ static int psc_dma_trigger(struct snd_pcm_substream *substream, int cmd)
223 break; 150 break;
224 151
225 case SNDRV_PCM_TRIGGER_STOP: 152 case SNDRV_PCM_TRIGGER_STOP:
153 dev_dbg(psc_dma->dev, "STOP: stream=%i periods_count=%i\n",
154 substream->pstr->stream, s->period_count);
226 s->active = 0; 155 s->active = 0;
227 156
228 spin_lock_irqsave(&psc_dma->lock, flags); 157 spin_lock_irqsave(&psc_dma->lock, flags);
@@ -236,7 +165,8 @@ static int psc_dma_trigger(struct snd_pcm_substream *substream, int cmd)
236 break; 165 break;
237 166
238 default: 167 default:
239 dev_dbg(psc_dma->dev, "invalid command\n"); 168 dev_dbg(psc_dma->dev, "unhandled trigger: stream=%i cmd=%i\n",
169 substream->pstr->stream, cmd);
240 return -EINVAL; 170 return -EINVAL;
241 } 171 }
242 172
@@ -343,7 +273,7 @@ psc_dma_pointer(struct snd_pcm_substream *substream)
343 else 273 else
344 s = &psc_dma->playback; 274 s = &psc_dma->playback;
345 275
346 count = s->period_current_pt - s->period_start; 276 count = s->period_current * s->period_bytes;
347 277
348 return bytes_to_frames(substream->runtime, count); 278 return bytes_to_frames(substream->runtime, count);
349} 279}
@@ -532,11 +462,9 @@ int mpc5200_audio_dma_create(struct of_device *op)
532 462
533 rc = request_irq(psc_dma->irq, &psc_dma_status_irq, IRQF_SHARED, 463 rc = request_irq(psc_dma->irq, &psc_dma_status_irq, IRQF_SHARED,
534 "psc-dma-status", psc_dma); 464 "psc-dma-status", psc_dma);
535 rc |= request_irq(psc_dma->capture.irq, 465 rc |= request_irq(psc_dma->capture.irq, &psc_dma_bcom_irq, IRQF_SHARED,
536 &psc_dma_bcom_irq_rx, IRQF_SHARED,
537 "psc-dma-capture", &psc_dma->capture); 466 "psc-dma-capture", &psc_dma->capture);
538 rc |= request_irq(psc_dma->playback.irq, 467 rc |= request_irq(psc_dma->playback.irq, &psc_dma_bcom_irq, IRQF_SHARED,
539 &psc_dma_bcom_irq_tx, IRQF_SHARED,
540 "psc-dma-playback", &psc_dma->playback); 468 "psc-dma-playback", &psc_dma->playback);
541 if (rc) { 469 if (rc) {
542 ret = -ENODEV; 470 ret = -ENODEV;
diff --git a/sound/soc/fsl/mpc5200_dma.h b/sound/soc/fsl/mpc5200_dma.h
index 8d396bb9d9fe..22208b373fb9 100644
--- a/sound/soc/fsl/mpc5200_dma.h
+++ b/sound/soc/fsl/mpc5200_dma.h
@@ -13,26 +13,25 @@
13 * @psc_dma: pointer back to parent psc_dma data structure 13 * @psc_dma: pointer back to parent psc_dma data structure
14 * @bcom_task: bestcomm task structure 14 * @bcom_task: bestcomm task structure
15 * @irq: irq number for bestcomm task 15 * @irq: irq number for bestcomm task
16 * @period_start: physical address of start of DMA region
17 * @period_end: physical address of end of DMA region 16 * @period_end: physical address of end of DMA region
18 * @period_next_pt: physical address of next DMA buffer to enqueue 17 * @period_next_pt: physical address of next DMA buffer to enqueue
19 * @period_bytes: size of DMA period in bytes 18 * @period_bytes: size of DMA period in bytes
19 * @ac97_slot_bits: Enable bits for turning on the correct AC97 slot
20 */ 20 */
21struct psc_dma_stream { 21struct psc_dma_stream {
22 struct snd_pcm_runtime *runtime; 22 struct snd_pcm_runtime *runtime;
23 snd_pcm_uframes_t appl_ptr;
24
25 int active; 23 int active;
26 struct psc_dma *psc_dma; 24 struct psc_dma *psc_dma;
27 struct bcom_task *bcom_task; 25 struct bcom_task *bcom_task;
28 int irq; 26 int irq;
29 struct snd_pcm_substream *stream; 27 struct snd_pcm_substream *stream;
30 dma_addr_t period_start; 28 int period_next;
31 dma_addr_t period_end; 29 int period_current;
32 dma_addr_t period_next_pt;
33 dma_addr_t period_current_pt;
34 int period_bytes; 30 int period_bytes;
35 int period_size; 31 int period_count;
32
33 /* AC97 state */
34 u32 ac97_slot_bits;
36}; 35};
37 36
38/** 37/**
@@ -73,6 +72,15 @@ struct psc_dma {
73 } stats; 72 } stats;
74}; 73};
75 74
75/* Utility for retrieving psc_dma_stream structure from a substream */
76inline struct psc_dma_stream *
77to_psc_dma_stream(struct snd_pcm_substream *substream, struct psc_dma *psc_dma)
78{
79 if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE)
80 return &psc_dma->capture;
81 return &psc_dma->playback;
82}
83
76int mpc5200_audio_dma_create(struct of_device *op); 84int mpc5200_audio_dma_create(struct of_device *op);
77int mpc5200_audio_dma_destroy(struct of_device *op); 85int mpc5200_audio_dma_destroy(struct of_device *op);
78 86
diff --git a/sound/soc/fsl/mpc5200_psc_ac97.c b/sound/soc/fsl/mpc5200_psc_ac97.c
index c4ae3e096bb9..3dbc7f7cd7b9 100644
--- a/sound/soc/fsl/mpc5200_psc_ac97.c
+++ b/sound/soc/fsl/mpc5200_psc_ac97.c
@@ -130,6 +130,7 @@ static int psc_ac97_hw_analog_params(struct snd_pcm_substream *substream,
130 struct snd_soc_dai *cpu_dai) 130 struct snd_soc_dai *cpu_dai)
131{ 131{
132 struct psc_dma *psc_dma = cpu_dai->private_data; 132 struct psc_dma *psc_dma = cpu_dai->private_data;
133 struct psc_dma_stream *s = to_psc_dma_stream(substream, psc_dma);
133 134
134 dev_dbg(psc_dma->dev, "%s(substream=%p) p_size=%i p_bytes=%i" 135 dev_dbg(psc_dma->dev, "%s(substream=%p) p_size=%i p_bytes=%i"
135 " periods=%i buffer_size=%i buffer_bytes=%i channels=%i" 136 " periods=%i buffer_size=%i buffer_bytes=%i channels=%i"
@@ -140,20 +141,10 @@ static int psc_ac97_hw_analog_params(struct snd_pcm_substream *substream,
140 params_channels(params), params_rate(params), 141 params_channels(params), params_rate(params),
141 params_format(params)); 142 params_format(params));
142 143
143 144 /* Determine the set of enable bits to turn on */
144 if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE) { 145 s->ac97_slot_bits = (params_channels(params) == 1) ? 0x100 : 0x300;
145 if (params_channels(params) == 1) 146 if (substream->pstr->stream != SNDRV_PCM_STREAM_CAPTURE)
146 psc_dma->slots |= 0x00000100; 147 s->ac97_slot_bits <<= 16;
147 else
148 psc_dma->slots |= 0x00000300;
149 } else {
150 if (params_channels(params) == 1)
151 psc_dma->slots |= 0x01000000;
152 else
153 psc_dma->slots |= 0x03000000;
154 }
155 out_be32(&psc_dma->psc_regs->ac97_slots, psc_dma->slots);
156
157 return 0; 148 return 0;
158} 149}
159 150
@@ -163,6 +154,8 @@ static int psc_ac97_hw_digital_params(struct snd_pcm_substream *substream,
163{ 154{
164 struct psc_dma *psc_dma = cpu_dai->private_data; 155 struct psc_dma *psc_dma = cpu_dai->private_data;
165 156
157 dev_dbg(psc_dma->dev, "%s(substream=%p)\n", __func__, substream);
158
166 if (params_channels(params) == 1) 159 if (params_channels(params) == 1)
167 out_be32(&psc_dma->psc_regs->ac97_slots, 0x01000000); 160 out_be32(&psc_dma->psc_regs->ac97_slots, 0x01000000);
168 else 161 else
@@ -176,14 +169,24 @@ static int psc_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
176{ 169{
177 struct snd_soc_pcm_runtime *rtd = substream->private_data; 170 struct snd_soc_pcm_runtime *rtd = substream->private_data;
178 struct psc_dma *psc_dma = rtd->dai->cpu_dai->private_data; 171 struct psc_dma *psc_dma = rtd->dai->cpu_dai->private_data;
172 struct psc_dma_stream *s = to_psc_dma_stream(substream, psc_dma);
179 173
180 switch (cmd) { 174 switch (cmd) {
175 case SNDRV_PCM_TRIGGER_START:
176 dev_dbg(psc_dma->dev, "AC97 START: stream=%i\n",
177 substream->pstr->stream);
178
179 /* Set the slot enable bits */
180 psc_dma->slots |= s->ac97_slot_bits;
181 out_be32(&psc_dma->psc_regs->ac97_slots, psc_dma->slots);
182 break;
183
181 case SNDRV_PCM_TRIGGER_STOP: 184 case SNDRV_PCM_TRIGGER_STOP:
182 if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE) 185 dev_dbg(psc_dma->dev, "AC97 STOP: stream=%i\n",
183 psc_dma->slots &= 0xFFFF0000; 186 substream->pstr->stream);
184 else
185 psc_dma->slots &= 0x0000FFFF;
186 187
188 /* Clear the slot enable bits */
189 psc_dma->slots &= ~(s->ac97_slot_bits);
187 out_be32(&psc_dma->psc_regs->ac97_slots, psc_dma->slots); 190 out_be32(&psc_dma->psc_regs->ac97_slots, psc_dma->slots);
188 break; 191 break;
189 } 192 }
diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c
index ef67d1cdffe7..83de1c81c8c4 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>
diff --git a/sound/soc/fsl/pcm030-audio-fabric.c b/sound/soc/fsl/pcm030-audio-fabric.c
index b928ef7d28eb..6644cba7cbf2 100644
--- a/sound/soc/fsl/pcm030-audio-fabric.c
+++ b/sound/soc/fsl/pcm030-audio-fabric.c
@@ -55,7 +55,7 @@ static __init int pcm030_fabric_init(void)
55 struct platform_device *pdev; 55 struct platform_device *pdev;
56 int rc; 56 int rc;
57 57
58 if (!machine_is_compatible("phytec,pcm030")) 58 if (!of_machine_is_compatible("phytec,pcm030"))
59 return -ENODEV; 59 return -ENODEV;
60 60
61 card.platform = &mpc5200_audio_dma_platform; 61 card.platform = &mpc5200_audio_dma_platform;
diff --git a/sound/soc/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/Kconfig b/sound/soc/imx/Kconfig
index a700562e8692..7174b4c710de 100644
--- a/sound/soc/imx/Kconfig
+++ b/sound/soc/imx/Kconfig
@@ -1,21 +1,13 @@
1config SND_MX1_MX2_SOC 1config SND_IMX_SOC
2 tristate "SoC Audio for Freecale i.MX1x i.MX2x CPUs" 2 tristate "SoC Audio for Freescale i.MX CPUs"
3 depends on ARCH_MX2 || ARCH_MX1 3 depends on ARCH_MXC
4 select SND_PCM 4 select SND_PCM
5 select FIQ
6 select SND_SOC_AC97_BUS
5 help 7 help
6 Say Y or M if you want to add support for codecs attached to 8 Say Y or M if you want to add support for codecs attached to
7 the MX1 or MX2 SSI interface. 9 the i.MX SSI interface.
8 10
9config SND_MXC_SOC_SSI 11config SND_MXC_SOC_SSI
10 tristate 12 tristate
11 13
12config SND_SOC_MX27VIS_WM8974
13 tristate "SoC Audio support for MX27 - WM8974 Visstrim_sm10 board"
14 depends on SND_MX1_MX2_SOC && MACH_MX27 && MACH_IMX27_VISSTRIM_M10
15 select SND_MXC_SOC_SSI
16 select SND_SOC_WM8974
17 help
18 Say Y if you want to add support for SoC audio on Visstrim SM10
19 board with WM8974.
20
21
diff --git a/sound/soc/imx/Makefile b/sound/soc/imx/Makefile
index c2ffd2c8df5a..9f8bb92ddfcc 100644
--- a/sound/soc/imx/Makefile
+++ b/sound/soc/imx/Makefile
@@ -1,10 +1,12 @@
1# i.MX Platform Support 1# i.MX Platform Support
2snd-soc-mx1_mx2-objs := mx1_mx2-pcm.o 2snd-soc-imx-objs := imx-ssi.o imx-pcm-fiq.o
3snd-soc-mxc-ssi-objs := mxc-ssi.o
4 3
5obj-$(CONFIG_SND_MX1_MX2_SOC) += snd-soc-mx1_mx2.o 4ifdef CONFIG_MACH_MX27
6obj-$(CONFIG_SND_MXC_SOC_SSI) += snd-soc-mxc-ssi.o 5snd-soc-imx-objs += imx-pcm-dma-mx2.o
6endif
7
8obj-$(CONFIG_SND_IMX_SOC) += snd-soc-imx.o
7 9
8# i.MX Machine Support 10# i.MX Machine Support
9snd-soc-mx27vis-wm8974-objs := mx27vis_wm8974.o 11snd-soc-phycore-ac97-objs := phycore-ac97.o
10obj-$(CONFIG_SND_SOC_MX27VIS_WM8974) += snd-soc-mx27vis-wm8974.o 12obj-$(CONFIG_SND_SOC_PHYCORE_AC97) += snd-soc-phycore-ac97.o
diff --git a/sound/soc/imx/imx-pcm-dma-mx2.c b/sound/soc/imx/imx-pcm-dma-mx2.c
new file mode 100644
index 000000000000..2b31ac673ea4
--- /dev/null
+++ b/sound/soc/imx/imx-pcm-dma-mx2.c
@@ -0,0 +1,331 @@
1/*
2 * imx-pcm-dma-mx2.c -- ALSA Soc Audio Layer
3 *
4 * Copyright 2009 Sascha Hauer <s.hauer@pengutronix.de>
5 *
6 * This code is based on code copyrighted by Freescale,
7 * Liam Girdwood, Javier Martin and probably others.
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 */
14#include <linux/clk.h>
15#include <linux/delay.h>
16#include <linux/device.h>
17#include <linux/dma-mapping.h>
18#include <linux/init.h>
19#include <linux/interrupt.h>
20#include <linux/module.h>
21#include <linux/platform_device.h>
22#include <linux/slab.h>
23
24#include <sound/core.h>
25#include <sound/initval.h>
26#include <sound/pcm.h>
27#include <sound/pcm_params.h>
28#include <sound/soc.h>
29
30#include <mach/dma-mx1-mx2.h>
31
32#include "imx-ssi.h"
33
34struct imx_pcm_runtime_data {
35 int sg_count;
36 struct scatterlist *sg_list;
37 int period;
38 int periods;
39 unsigned long dma_addr;
40 int dma;
41 struct snd_pcm_substream *substream;
42 unsigned long offset;
43 unsigned long size;
44 unsigned long period_cnt;
45 void *buf;
46 int period_time;
47};
48
49/* Called by the DMA framework when a period has elapsed */
50static void imx_ssi_dma_progression(int channel, void *data,
51 struct scatterlist *sg)
52{
53 struct snd_pcm_substream *substream = data;
54 struct snd_pcm_runtime *runtime = substream->runtime;
55 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
56
57 if (!sg)
58 return;
59
60 runtime = iprtd->substream->runtime;
61
62 iprtd->offset = sg->dma_address - runtime->dma_addr;
63
64 snd_pcm_period_elapsed(iprtd->substream);
65}
66
67static void imx_ssi_dma_callback(int channel, void *data)
68{
69 pr_err("%s shouldn't be called\n", __func__);
70}
71
72static void snd_imx_dma_err_callback(int channel, void *data, int err)
73{
74 struct snd_pcm_substream *substream = data;
75 struct snd_soc_pcm_runtime *rtd = substream->private_data;
76 struct imx_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data;
77 struct snd_pcm_runtime *runtime = substream->runtime;
78 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
79 int ret;
80
81 pr_err("DMA timeout on channel %d -%s%s%s%s\n",
82 channel,
83 err & IMX_DMA_ERR_BURST ? " burst" : "",
84 err & IMX_DMA_ERR_REQUEST ? " request" : "",
85 err & IMX_DMA_ERR_TRANSFER ? " transfer" : "",
86 err & IMX_DMA_ERR_BUFFER ? " buffer" : "");
87
88 imx_dma_disable(iprtd->dma);
89 ret = imx_dma_setup_sg(iprtd->dma, iprtd->sg_list, iprtd->sg_count,
90 IMX_DMA_LENGTH_LOOP, dma_params->dma_addr,
91 substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
92 DMA_MODE_WRITE : DMA_MODE_READ);
93 if (!ret)
94 imx_dma_enable(iprtd->dma);
95}
96
97static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream)
98{
99 struct snd_soc_pcm_runtime *rtd = substream->private_data;
100 struct imx_pcm_dma_params *dma_params;
101 struct snd_pcm_runtime *runtime = substream->runtime;
102 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
103 int ret;
104
105 dma_params = snd_soc_get_dma_data(rtd->dai->cpu_dai, substream);
106
107 iprtd->dma = imx_dma_request_by_prio(DRV_NAME, DMA_PRIO_HIGH);
108 if (iprtd->dma < 0) {
109 pr_err("Failed to claim the audio DMA\n");
110 return -ENODEV;
111 }
112
113 ret = imx_dma_setup_handlers(iprtd->dma,
114 imx_ssi_dma_callback,
115 snd_imx_dma_err_callback, substream);
116 if (ret)
117 goto out;
118
119 ret = imx_dma_setup_progression_handler(iprtd->dma,
120 imx_ssi_dma_progression);
121 if (ret) {
122 pr_err("Failed to setup the DMA handler\n");
123 goto out;
124 }
125
126 ret = imx_dma_config_channel(iprtd->dma,
127 IMX_DMA_MEMSIZE_16 | IMX_DMA_TYPE_FIFO,
128 IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR,
129 dma_params->dma, 1);
130 if (ret < 0) {
131 pr_err("Cannot configure DMA channel: %d\n", ret);
132 goto out;
133 }
134
135 imx_dma_config_burstlen(iprtd->dma, dma_params->burstsize * 2);
136
137 return 0;
138out:
139 imx_dma_free(iprtd->dma);
140 return ret;
141}
142
143static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream,
144 struct snd_pcm_hw_params *params)
145{
146 struct snd_pcm_runtime *runtime = substream->runtime;
147 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
148 int i;
149 unsigned long dma_addr;
150
151 imx_ssi_dma_alloc(substream);
152
153 iprtd->size = params_buffer_bytes(params);
154 iprtd->periods = params_periods(params);
155 iprtd->period = params_period_bytes(params);
156 iprtd->offset = 0;
157 iprtd->period_time = HZ / (params_rate(params) /
158 params_period_size(params));
159
160 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
161
162 if (iprtd->sg_count != iprtd->periods) {
163 kfree(iprtd->sg_list);
164
165 iprtd->sg_list = kcalloc(iprtd->periods + 1,
166 sizeof(struct scatterlist), GFP_KERNEL);
167 if (!iprtd->sg_list)
168 return -ENOMEM;
169 iprtd->sg_count = iprtd->periods + 1;
170 }
171
172 sg_init_table(iprtd->sg_list, iprtd->sg_count);
173 dma_addr = runtime->dma_addr;
174
175 for (i = 0; i < iprtd->periods; i++) {
176 iprtd->sg_list[i].page_link = 0;
177 iprtd->sg_list[i].offset = 0;
178 iprtd->sg_list[i].dma_address = dma_addr;
179 iprtd->sg_list[i].length = iprtd->period;
180 dma_addr += iprtd->period;
181 }
182
183 /* close the loop */
184 iprtd->sg_list[iprtd->sg_count - 1].offset = 0;
185 iprtd->sg_list[iprtd->sg_count - 1].length = 0;
186 iprtd->sg_list[iprtd->sg_count - 1].page_link =
187 ((unsigned long) iprtd->sg_list | 0x01) & ~0x02;
188 return 0;
189}
190
191static int snd_imx_pcm_hw_free(struct snd_pcm_substream *substream)
192{
193 struct snd_pcm_runtime *runtime = substream->runtime;
194 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
195
196 if (iprtd->dma >= 0) {
197 imx_dma_free(iprtd->dma);
198 iprtd->dma = -EINVAL;
199 }
200
201 kfree(iprtd->sg_list);
202 iprtd->sg_list = NULL;
203
204 return 0;
205}
206
207static int snd_imx_pcm_prepare(struct snd_pcm_substream *substream)
208{
209 struct snd_pcm_runtime *runtime = substream->runtime;
210 struct snd_soc_pcm_runtime *rtd = substream->private_data;
211 struct imx_pcm_dma_params *dma_params;
212 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
213 int err;
214
215 dma_params = snd_soc_get_dma_data(rtd->dai->cpu_dai, substream);
216
217 iprtd->substream = substream;
218 iprtd->buf = (unsigned int *)substream->dma_buffer.area;
219 iprtd->period_cnt = 0;
220
221 pr_debug("%s: buf: %p period: %d periods: %d\n",
222 __func__, iprtd->buf, iprtd->period, iprtd->periods);
223
224 err = imx_dma_setup_sg(iprtd->dma, iprtd->sg_list, iprtd->sg_count,
225 IMX_DMA_LENGTH_LOOP, dma_params->dma_addr,
226 substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
227 DMA_MODE_WRITE : DMA_MODE_READ);
228 if (err)
229 return err;
230
231 return 0;
232}
233
234static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
235{
236 struct snd_pcm_runtime *runtime = substream->runtime;
237 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
238
239 switch (cmd) {
240 case SNDRV_PCM_TRIGGER_START:
241 case SNDRV_PCM_TRIGGER_RESUME:
242 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
243 imx_dma_enable(iprtd->dma);
244
245 break;
246
247 case SNDRV_PCM_TRIGGER_STOP:
248 case SNDRV_PCM_TRIGGER_SUSPEND:
249 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
250 imx_dma_disable(iprtd->dma);
251
252 break;
253 default:
254 return -EINVAL;
255 }
256
257 return 0;
258}
259
260static snd_pcm_uframes_t snd_imx_pcm_pointer(struct snd_pcm_substream *substream)
261{
262 struct snd_pcm_runtime *runtime = substream->runtime;
263 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
264
265 return bytes_to_frames(substream->runtime, iprtd->offset);
266}
267
268static struct snd_pcm_hardware snd_imx_hardware = {
269 .info = SNDRV_PCM_INFO_INTERLEAVED |
270 SNDRV_PCM_INFO_BLOCK_TRANSFER |
271 SNDRV_PCM_INFO_MMAP |
272 SNDRV_PCM_INFO_MMAP_VALID |
273 SNDRV_PCM_INFO_PAUSE |
274 SNDRV_PCM_INFO_RESUME,
275 .formats = SNDRV_PCM_FMTBIT_S16_LE,
276 .rate_min = 8000,
277 .channels_min = 2,
278 .channels_max = 2,
279 .buffer_bytes_max = IMX_SSI_DMABUF_SIZE,
280 .period_bytes_min = 128,
281 .period_bytes_max = 16 * 1024,
282 .periods_min = 2,
283 .periods_max = 255,
284 .fifo_size = 0,
285};
286
287static int snd_imx_open(struct snd_pcm_substream *substream)
288{
289 struct snd_pcm_runtime *runtime = substream->runtime;
290 struct imx_pcm_runtime_data *iprtd;
291 int ret;
292
293 iprtd = kzalloc(sizeof(*iprtd), GFP_KERNEL);
294 runtime->private_data = iprtd;
295
296 ret = snd_pcm_hw_constraint_integer(substream->runtime,
297 SNDRV_PCM_HW_PARAM_PERIODS);
298 if (ret < 0)
299 return ret;
300
301 snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware);
302 return 0;
303}
304
305static struct snd_pcm_ops imx_pcm_ops = {
306 .open = snd_imx_open,
307 .ioctl = snd_pcm_lib_ioctl,
308 .hw_params = snd_imx_pcm_hw_params,
309 .hw_free = snd_imx_pcm_hw_free,
310 .prepare = snd_imx_pcm_prepare,
311 .trigger = snd_imx_pcm_trigger,
312 .pointer = snd_imx_pcm_pointer,
313 .mmap = snd_imx_pcm_mmap,
314};
315
316static struct snd_soc_platform imx_soc_platform_dma = {
317 .name = "imx-audio",
318 .pcm_ops = &imx_pcm_ops,
319 .pcm_new = imx_pcm_new,
320 .pcm_free = imx_pcm_free,
321};
322
323struct snd_soc_platform *imx_ssi_dma_mx2_init(struct platform_device *pdev,
324 struct imx_ssi *ssi)
325{
326 ssi->dma_params_tx.burstsize = DMA_TXFIFO_BURST;
327 ssi->dma_params_rx.burstsize = DMA_RXFIFO_BURST;
328
329 return &imx_soc_platform_dma;
330}
331
diff --git a/sound/soc/imx/imx-pcm-fiq.c b/sound/soc/imx/imx-pcm-fiq.c
new file mode 100644
index 000000000000..6b518e07eea9
--- /dev/null
+++ b/sound/soc/imx/imx-pcm-fiq.c
@@ -0,0 +1,301 @@
1/*
2 * imx-pcm-fiq.c -- ALSA Soc Audio Layer
3 *
4 * Copyright 2009 Sascha Hauer <s.hauer@pengutronix.de>
5 *
6 * This code is based on code copyrighted by Freescale,
7 * Liam Girdwood, Javier Martin and probably others.
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 */
14#include <linux/clk.h>
15#include <linux/delay.h>
16#include <linux/device.h>
17#include <linux/dma-mapping.h>
18#include <linux/init.h>
19#include <linux/interrupt.h>
20#include <linux/module.h>
21#include <linux/platform_device.h>
22#include <linux/slab.h>
23
24#include <sound/core.h>
25#include <sound/initval.h>
26#include <sound/pcm.h>
27#include <sound/pcm_params.h>
28#include <sound/soc.h>
29
30#include <asm/fiq.h>
31
32#include <mach/ssi.h>
33
34#include "imx-ssi.h"
35
36struct imx_pcm_runtime_data {
37 int period;
38 int periods;
39 unsigned long offset;
40 unsigned long last_offset;
41 unsigned long size;
42 struct hrtimer hrt;
43 int poll_time_ns;
44 struct snd_pcm_substream *substream;
45 atomic_t running;
46};
47
48static enum hrtimer_restart snd_hrtimer_callback(struct hrtimer *hrt)
49{
50 struct imx_pcm_runtime_data *iprtd =
51 container_of(hrt, struct imx_pcm_runtime_data, hrt);
52 struct snd_pcm_substream *substream = iprtd->substream;
53 struct snd_pcm_runtime *runtime = substream->runtime;
54 struct pt_regs regs;
55 unsigned long delta;
56
57 if (!atomic_read(&iprtd->running))
58 return HRTIMER_NORESTART;
59
60 get_fiq_regs(&regs);
61
62 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
63 iprtd->offset = regs.ARM_r8 & 0xffff;
64 else
65 iprtd->offset = regs.ARM_r9 & 0xffff;
66
67 /* How much data have we transferred since the last period report? */
68 if (iprtd->offset >= iprtd->last_offset)
69 delta = iprtd->offset - iprtd->last_offset;
70 else
71 delta = runtime->buffer_size + iprtd->offset
72 - iprtd->last_offset;
73
74 /* If we've transferred at least a period then report it and
75 * reset our poll time */
76 if (delta >= iprtd->period) {
77 snd_pcm_period_elapsed(substream);
78 iprtd->last_offset = iprtd->offset;
79 }
80
81 hrtimer_forward_now(hrt, ns_to_ktime(iprtd->poll_time_ns));
82
83 return HRTIMER_RESTART;
84}
85
86static struct fiq_handler fh = {
87 .name = DRV_NAME,
88};
89
90static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream,
91 struct snd_pcm_hw_params *params)
92{
93 struct snd_pcm_runtime *runtime = substream->runtime;
94 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
95
96 iprtd->size = params_buffer_bytes(params);
97 iprtd->periods = params_periods(params);
98 iprtd->period = params_period_bytes(params) ;
99 iprtd->offset = 0;
100 iprtd->last_offset = 0;
101 iprtd->poll_time_ns = 1000000000 / params_rate(params) *
102 params_period_size(params);
103 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
104
105 return 0;
106}
107
108static int snd_imx_pcm_prepare(struct snd_pcm_substream *substream)
109{
110 struct snd_pcm_runtime *runtime = substream->runtime;
111 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
112 struct pt_regs regs;
113
114 get_fiq_regs(&regs);
115 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
116 regs.ARM_r8 = (iprtd->period * iprtd->periods - 1) << 16;
117 else
118 regs.ARM_r9 = (iprtd->period * iprtd->periods - 1) << 16;
119
120 set_fiq_regs(&regs);
121
122 return 0;
123}
124
125static int fiq_enable;
126static int imx_pcm_fiq;
127
128static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
129{
130 struct snd_pcm_runtime *runtime = substream->runtime;
131 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
132
133 switch (cmd) {
134 case SNDRV_PCM_TRIGGER_START:
135 case SNDRV_PCM_TRIGGER_RESUME:
136 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
137 atomic_set(&iprtd->running, 1);
138 hrtimer_start(&iprtd->hrt, ns_to_ktime(iprtd->poll_time_ns),
139 HRTIMER_MODE_REL);
140 if (++fiq_enable == 1)
141 enable_fiq(imx_pcm_fiq);
142
143 break;
144
145 case SNDRV_PCM_TRIGGER_STOP:
146 case SNDRV_PCM_TRIGGER_SUSPEND:
147 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
148 atomic_set(&iprtd->running, 0);
149
150 if (--fiq_enable == 0)
151 disable_fiq(imx_pcm_fiq);
152
153 break;
154 default:
155 return -EINVAL;
156 }
157
158 return 0;
159}
160
161static snd_pcm_uframes_t snd_imx_pcm_pointer(struct snd_pcm_substream *substream)
162{
163 struct snd_pcm_runtime *runtime = substream->runtime;
164 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
165
166 return bytes_to_frames(substream->runtime, iprtd->offset);
167}
168
169static struct snd_pcm_hardware snd_imx_hardware = {
170 .info = SNDRV_PCM_INFO_INTERLEAVED |
171 SNDRV_PCM_INFO_BLOCK_TRANSFER |
172 SNDRV_PCM_INFO_MMAP |
173 SNDRV_PCM_INFO_MMAP_VALID |
174 SNDRV_PCM_INFO_PAUSE |
175 SNDRV_PCM_INFO_RESUME,
176 .formats = SNDRV_PCM_FMTBIT_S16_LE,
177 .rate_min = 8000,
178 .channels_min = 2,
179 .channels_max = 2,
180 .buffer_bytes_max = IMX_SSI_DMABUF_SIZE,
181 .period_bytes_min = 128,
182 .period_bytes_max = 16 * 1024,
183 .periods_min = 4,
184 .periods_max = 255,
185 .fifo_size = 0,
186};
187
188static int snd_imx_open(struct snd_pcm_substream *substream)
189{
190 struct snd_pcm_runtime *runtime = substream->runtime;
191 struct imx_pcm_runtime_data *iprtd;
192 int ret;
193
194 iprtd = kzalloc(sizeof(*iprtd), GFP_KERNEL);
195 runtime->private_data = iprtd;
196
197 iprtd->substream = substream;
198
199 atomic_set(&iprtd->running, 0);
200 hrtimer_init(&iprtd->hrt, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
201 iprtd->hrt.function = snd_hrtimer_callback;
202
203 ret = snd_pcm_hw_constraint_integer(substream->runtime,
204 SNDRV_PCM_HW_PARAM_PERIODS);
205 if (ret < 0)
206 return ret;
207
208 snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware);
209 return 0;
210}
211
212static int snd_imx_close(struct snd_pcm_substream *substream)
213{
214 struct snd_pcm_runtime *runtime = substream->runtime;
215 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
216
217 hrtimer_cancel(&iprtd->hrt);
218
219 kfree(iprtd);
220
221 return 0;
222}
223
224static struct snd_pcm_ops imx_pcm_ops = {
225 .open = snd_imx_open,
226 .close = snd_imx_close,
227 .ioctl = snd_pcm_lib_ioctl,
228 .hw_params = snd_imx_pcm_hw_params,
229 .prepare = snd_imx_pcm_prepare,
230 .trigger = snd_imx_pcm_trigger,
231 .pointer = snd_imx_pcm_pointer,
232 .mmap = snd_imx_pcm_mmap,
233};
234
235static int imx_pcm_fiq_new(struct snd_card *card, struct snd_soc_dai *dai,
236 struct snd_pcm *pcm)
237{
238 int ret;
239
240 ret = imx_pcm_new(card, dai, pcm);
241 if (ret)
242 return ret;
243
244 if (dai->playback.channels_min) {
245 struct snd_pcm_substream *substream =
246 pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
247 struct snd_dma_buffer *buf = &substream->dma_buffer;
248
249 imx_ssi_fiq_tx_buffer = (unsigned long)buf->area;
250 }
251
252 if (dai->capture.channels_min) {
253 struct snd_pcm_substream *substream =
254 pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
255 struct snd_dma_buffer *buf = &substream->dma_buffer;
256
257 imx_ssi_fiq_rx_buffer = (unsigned long)buf->area;
258 }
259
260 set_fiq_handler(&imx_ssi_fiq_start,
261 &imx_ssi_fiq_end - &imx_ssi_fiq_start);
262
263 return 0;
264}
265
266static struct snd_soc_platform imx_soc_platform_fiq = {
267 .pcm_ops = &imx_pcm_ops,
268 .pcm_new = imx_pcm_fiq_new,
269 .pcm_free = imx_pcm_free,
270};
271
272struct snd_soc_platform *imx_ssi_fiq_init(struct platform_device *pdev,
273 struct imx_ssi *ssi)
274{
275 int ret = 0;
276
277 ret = claim_fiq(&fh);
278 if (ret) {
279 dev_err(&pdev->dev, "failed to claim fiq: %d", ret);
280 return ERR_PTR(ret);
281 }
282
283 mxc_set_irq_fiq(ssi->irq, 1);
284
285 imx_pcm_fiq = ssi->irq;
286
287 imx_ssi_fiq_base = (unsigned long)ssi->base;
288
289 ssi->dma_params_tx.burstsize = 4;
290 ssi->dma_params_rx.burstsize = 6;
291
292 return &imx_soc_platform_fiq;
293}
294
295void imx_ssi_fiq_exit(struct platform_device *pdev,
296 struct imx_ssi *ssi)
297{
298 mxc_set_irq_fiq(ssi->irq, 0);
299 release_fiq(&fh);
300}
301
diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c
new file mode 100644
index 000000000000..80b4fee2442b
--- /dev/null
+++ b/sound/soc/imx/imx-ssi.c
@@ -0,0 +1,763 @@
1/*
2 * imx-ssi.c -- ALSA Soc Audio Layer
3 *
4 * Copyright 2009 Sascha Hauer <s.hauer@pengutronix.de>
5 *
6 * This code is based on code copyrighted by Freescale,
7 * Liam Girdwood, Javier Martin and probably others.
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 *
14 *
15 * The i.MX SSI core has some nasty limitations in AC97 mode. While most
16 * sane processor vendors have a FIFO per AC97 slot, the i.MX has only
17 * one FIFO which combines all valid receive slots. We cannot even select
18 * which slots we want to receive. The WM9712 with which this driver
19 * was developped with always sends GPIO status data in slot 12 which
20 * we receive in our (PCM-) data stream. The only chance we have is to
21 * manually skip this data in the FIQ handler. With sampling rates different
22 * from 48000Hz not every frame has valid receive data, so the ratio
23 * between pcm data and GPIO status data changes. Our FIQ handler is not
24 * able to handle this, hence this driver only works with 48000Hz sampling
25 * rate.
26 * Reading and writing AC97 registers is another challange. The core
27 * provides us status bits when the read register is updated with *another*
28 * value. When we read the same register two times (and the register still
29 * contains the same value) these status bits are not set. We work
30 * around this by not polling these bits but only wait a fixed delay.
31 *
32 */
33
34#include <linux/clk.h>
35#include <linux/delay.h>
36#include <linux/device.h>
37#include <linux/dma-mapping.h>
38#include <linux/init.h>
39#include <linux/interrupt.h>
40#include <linux/module.h>
41#include <linux/platform_device.h>
42#include <linux/slab.h>
43
44#include <sound/core.h>
45#include <sound/initval.h>
46#include <sound/pcm.h>
47#include <sound/pcm_params.h>
48#include <sound/soc.h>
49
50#include <mach/ssi.h>
51#include <mach/hardware.h>
52
53#include "imx-ssi.h"
54
55#define SSI_SACNT_DEFAULT (SSI_SACNT_AC97EN | SSI_SACNT_FV)
56
57/*
58 * SSI Network Mode or TDM slots configuration.
59 * Should only be called when port is inactive (i.e. SSIEN = 0).
60 */
61static int imx_ssi_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai,
62 unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
63{
64 struct imx_ssi *ssi = cpu_dai->private_data;
65 u32 sccr;
66
67 sccr = readl(ssi->base + SSI_STCCR);
68 sccr &= ~SSI_STCCR_DC_MASK;
69 sccr |= SSI_STCCR_DC(slots - 1);
70 writel(sccr, ssi->base + SSI_STCCR);
71
72 sccr = readl(ssi->base + SSI_SRCCR);
73 sccr &= ~SSI_STCCR_DC_MASK;
74 sccr |= SSI_STCCR_DC(slots - 1);
75 writel(sccr, ssi->base + SSI_SRCCR);
76
77 writel(tx_mask, ssi->base + SSI_STMSK);
78 writel(rx_mask, ssi->base + SSI_SRMSK);
79
80 return 0;
81}
82
83/*
84 * SSI DAI format configuration.
85 * Should only be called when port is inactive (i.e. SSIEN = 0).
86 * Note: We don't use the I2S modes but instead manually configure the
87 * SSI for I2S because the I2S mode is only a register preset.
88 */
89static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
90{
91 struct imx_ssi *ssi = cpu_dai->private_data;
92 u32 strcr = 0, scr;
93
94 scr = readl(ssi->base + SSI_SCR) & ~(SSI_SCR_SYN | SSI_SCR_NET);
95
96 /* DAI mode */
97 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
98 case SND_SOC_DAIFMT_I2S:
99 /* data on rising edge of bclk, frame low 1clk before data */
100 strcr |= SSI_STCR_TFSI | SSI_STCR_TEFS | SSI_STCR_TXBIT0;
101 scr |= SSI_SCR_NET;
102 break;
103 case SND_SOC_DAIFMT_LEFT_J:
104 /* data on rising edge of bclk, frame high with data */
105 strcr |= SSI_STCR_TXBIT0;
106 break;
107 case SND_SOC_DAIFMT_DSP_B:
108 /* data on rising edge of bclk, frame high with data */
109 strcr |= SSI_STCR_TFSL;
110 break;
111 case SND_SOC_DAIFMT_DSP_A:
112 /* data on rising edge of bclk, frame high 1clk before data */
113 strcr |= SSI_STCR_TFSL | SSI_STCR_TEFS;
114 break;
115 }
116
117 /* DAI clock inversion */
118 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
119 case SND_SOC_DAIFMT_IB_IF:
120 strcr |= SSI_STCR_TFSI;
121 strcr &= ~SSI_STCR_TSCKP;
122 break;
123 case SND_SOC_DAIFMT_IB_NF:
124 strcr &= ~(SSI_STCR_TSCKP | SSI_STCR_TFSI);
125 break;
126 case SND_SOC_DAIFMT_NB_IF:
127 strcr |= SSI_STCR_TFSI | SSI_STCR_TSCKP;
128 break;
129 case SND_SOC_DAIFMT_NB_NF:
130 strcr &= ~SSI_STCR_TFSI;
131 strcr |= SSI_STCR_TSCKP;
132 break;
133 }
134
135 /* DAI clock master masks */
136 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
137 case SND_SOC_DAIFMT_CBM_CFM:
138 break;
139 default:
140 /* Master mode not implemented, needs handling of clocks. */
141 return -EINVAL;
142 }
143
144 strcr |= SSI_STCR_TFEN0;
145
146 writel(strcr, ssi->base + SSI_STCR);
147 writel(strcr, ssi->base + SSI_SRCR);
148 writel(scr, ssi->base + SSI_SCR);
149
150 return 0;
151}
152
153/*
154 * SSI system clock configuration.
155 * Should only be called when port is inactive (i.e. SSIEN = 0).
156 */
157static int imx_ssi_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
158 int clk_id, unsigned int freq, int dir)
159{
160 struct imx_ssi *ssi = cpu_dai->private_data;
161 u32 scr;
162
163 scr = readl(ssi->base + SSI_SCR);
164
165 switch (clk_id) {
166 case IMX_SSP_SYS_CLK:
167 if (dir == SND_SOC_CLOCK_OUT)
168 scr |= SSI_SCR_SYS_CLK_EN;
169 else
170 scr &= ~SSI_SCR_SYS_CLK_EN;
171 break;
172 default:
173 return -EINVAL;
174 }
175
176 writel(scr, ssi->base + SSI_SCR);
177
178 return 0;
179}
180
181/*
182 * SSI Clock dividers
183 * Should only be called when port is inactive (i.e. SSIEN = 0).
184 */
185static int imx_ssi_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
186 int div_id, int div)
187{
188 struct imx_ssi *ssi = cpu_dai->private_data;
189 u32 stccr, srccr;
190
191 stccr = readl(ssi->base + SSI_STCCR);
192 srccr = readl(ssi->base + SSI_SRCCR);
193
194 switch (div_id) {
195 case IMX_SSI_TX_DIV_2:
196 stccr &= ~SSI_STCCR_DIV2;
197 stccr |= div;
198 break;
199 case IMX_SSI_TX_DIV_PSR:
200 stccr &= ~SSI_STCCR_PSR;
201 stccr |= div;
202 break;
203 case IMX_SSI_TX_DIV_PM:
204 stccr &= ~0xff;
205 stccr |= SSI_STCCR_PM(div);
206 break;
207 case IMX_SSI_RX_DIV_2:
208 stccr &= ~SSI_STCCR_DIV2;
209 stccr |= div;
210 break;
211 case IMX_SSI_RX_DIV_PSR:
212 stccr &= ~SSI_STCCR_PSR;
213 stccr |= div;
214 break;
215 case IMX_SSI_RX_DIV_PM:
216 stccr &= ~0xff;
217 stccr |= SSI_STCCR_PM(div);
218 break;
219 default:
220 return -EINVAL;
221 }
222
223 writel(stccr, ssi->base + SSI_STCCR);
224 writel(srccr, ssi->base + SSI_SRCCR);
225
226 return 0;
227}
228
229/*
230 * Should only be called when port is inactive (i.e. SSIEN = 0),
231 * although can be called multiple times by upper layers.
232 */
233static int imx_ssi_hw_params(struct snd_pcm_substream *substream,
234 struct snd_pcm_hw_params *params,
235 struct snd_soc_dai *cpu_dai)
236{
237 struct imx_ssi *ssi = cpu_dai->private_data;
238 struct imx_pcm_dma_params *dma_data;
239 u32 reg, sccr;
240
241 /* Tx/Rx config */
242 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
243 reg = SSI_STCCR;
244 dma_data = &ssi->dma_params_tx;
245 } else {
246 reg = SSI_SRCCR;
247 dma_data = &ssi->dma_params_rx;
248 }
249
250 snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
251
252 sccr = readl(ssi->base + reg) & ~SSI_STCCR_WL_MASK;
253
254 /* DAI data (word) size */
255 switch (params_format(params)) {
256 case SNDRV_PCM_FORMAT_S16_LE:
257 sccr |= SSI_SRCCR_WL(16);
258 break;
259 case SNDRV_PCM_FORMAT_S20_3LE:
260 sccr |= SSI_SRCCR_WL(20);
261 break;
262 case SNDRV_PCM_FORMAT_S24_LE:
263 sccr |= SSI_SRCCR_WL(24);
264 break;
265 }
266
267 writel(sccr, ssi->base + reg);
268
269 return 0;
270}
271
272static int imx_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
273 struct snd_soc_dai *dai)
274{
275 struct snd_soc_pcm_runtime *rtd = substream->private_data;
276 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
277 struct imx_ssi *ssi = cpu_dai->private_data;
278 unsigned int sier_bits, sier;
279 unsigned int scr;
280
281 scr = readl(ssi->base + SSI_SCR);
282 sier = readl(ssi->base + SSI_SIER);
283
284 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
285 if (ssi->flags & IMX_SSI_DMA)
286 sier_bits = SSI_SIER_TDMAE;
287 else
288 sier_bits = SSI_SIER_TIE | SSI_SIER_TFE0_EN;
289 } else {
290 if (ssi->flags & IMX_SSI_DMA)
291 sier_bits = SSI_SIER_RDMAE;
292 else
293 sier_bits = SSI_SIER_RIE | SSI_SIER_RFF0_EN;
294 }
295
296 switch (cmd) {
297 case SNDRV_PCM_TRIGGER_START:
298 case SNDRV_PCM_TRIGGER_RESUME:
299 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
300 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
301 scr |= SSI_SCR_TE;
302 else
303 scr |= SSI_SCR_RE;
304 sier |= sier_bits;
305
306 if (++ssi->enabled == 1)
307 scr |= SSI_SCR_SSIEN;
308
309 break;
310
311 case SNDRV_PCM_TRIGGER_STOP:
312 case SNDRV_PCM_TRIGGER_SUSPEND:
313 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
314 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
315 scr &= ~SSI_SCR_TE;
316 else
317 scr &= ~SSI_SCR_RE;
318 sier &= ~sier_bits;
319
320 if (--ssi->enabled == 0)
321 scr &= ~SSI_SCR_SSIEN;
322
323 break;
324 default:
325 return -EINVAL;
326 }
327
328 if (!(ssi->flags & IMX_SSI_USE_AC97))
329 /* rx/tx are always enabled to access ac97 registers */
330 writel(scr, ssi->base + SSI_SCR);
331
332 writel(sier, ssi->base + SSI_SIER);
333
334 return 0;
335}
336
337static struct snd_soc_dai_ops imx_ssi_pcm_dai_ops = {
338 .hw_params = imx_ssi_hw_params,
339 .set_fmt = imx_ssi_set_dai_fmt,
340 .set_clkdiv = imx_ssi_set_dai_clkdiv,
341 .set_sysclk = imx_ssi_set_dai_sysclk,
342 .set_tdm_slot = imx_ssi_set_dai_tdm_slot,
343 .trigger = imx_ssi_trigger,
344};
345
346static struct snd_soc_dai imx_ssi_dai = {
347 .playback = {
348 .channels_min = 2,
349 .channels_max = 2,
350 .rates = SNDRV_PCM_RATE_8000_96000,
351 .formats = SNDRV_PCM_FMTBIT_S16_LE,
352 },
353 .capture = {
354 .channels_min = 2,
355 .channels_max = 2,
356 .rates = SNDRV_PCM_RATE_8000_96000,
357 .formats = SNDRV_PCM_FMTBIT_S16_LE,
358 },
359 .ops = &imx_ssi_pcm_dai_ops,
360};
361
362int snd_imx_pcm_mmap(struct snd_pcm_substream *substream,
363 struct vm_area_struct *vma)
364{
365 struct snd_pcm_runtime *runtime = substream->runtime;
366 int ret;
367
368 ret = dma_mmap_coherent(NULL, vma, runtime->dma_area,
369 runtime->dma_addr, runtime->dma_bytes);
370
371 pr_debug("%s: ret: %d %p 0x%08x 0x%08x\n", __func__, ret,
372 runtime->dma_area,
373 runtime->dma_addr,
374 runtime->dma_bytes);
375 return ret;
376}
377
378static int imx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
379{
380 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
381 struct snd_dma_buffer *buf = &substream->dma_buffer;
382 size_t size = IMX_SSI_DMABUF_SIZE;
383
384 buf->dev.type = SNDRV_DMA_TYPE_DEV;
385 buf->dev.dev = pcm->card->dev;
386 buf->private_data = NULL;
387 buf->area = dma_alloc_writecombine(pcm->card->dev, size,
388 &buf->addr, GFP_KERNEL);
389 if (!buf->area)
390 return -ENOMEM;
391 buf->bytes = size;
392
393 return 0;
394}
395
396static u64 imx_pcm_dmamask = DMA_BIT_MASK(32);
397
398int imx_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
399 struct snd_pcm *pcm)
400{
401
402 int ret = 0;
403
404 if (!card->dev->dma_mask)
405 card->dev->dma_mask = &imx_pcm_dmamask;
406 if (!card->dev->coherent_dma_mask)
407 card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
408 if (dai->playback.channels_min) {
409 ret = imx_pcm_preallocate_dma_buffer(pcm,
410 SNDRV_PCM_STREAM_PLAYBACK);
411 if (ret)
412 goto out;
413 }
414
415 if (dai->capture.channels_min) {
416 ret = imx_pcm_preallocate_dma_buffer(pcm,
417 SNDRV_PCM_STREAM_CAPTURE);
418 if (ret)
419 goto out;
420 }
421
422out:
423 return ret;
424}
425
426void imx_pcm_free(struct snd_pcm *pcm)
427{
428 struct snd_pcm_substream *substream;
429 struct snd_dma_buffer *buf;
430 int stream;
431
432 for (stream = 0; stream < 2; stream++) {
433 substream = pcm->streams[stream].substream;
434 if (!substream)
435 continue;
436
437 buf = &substream->dma_buffer;
438 if (!buf->area)
439 continue;
440
441 dma_free_writecombine(pcm->card->dev, buf->bytes,
442 buf->area, buf->addr);
443 buf->area = NULL;
444 }
445}
446
447struct snd_soc_platform imx_soc_platform = {
448 .name = "imx-audio",
449};
450EXPORT_SYMBOL_GPL(imx_soc_platform);
451
452static struct snd_soc_dai imx_ac97_dai = {
453 .name = "AC97",
454 .ac97_control = 1,
455 .playback = {
456 .stream_name = "AC97 Playback",
457 .channels_min = 2,
458 .channels_max = 2,
459 .rates = SNDRV_PCM_RATE_48000,
460 .formats = SNDRV_PCM_FMTBIT_S16_LE,
461 },
462 .capture = {
463 .stream_name = "AC97 Capture",
464 .channels_min = 2,
465 .channels_max = 2,
466 .rates = SNDRV_PCM_RATE_48000,
467 .formats = SNDRV_PCM_FMTBIT_S16_LE,
468 },
469 .ops = &imx_ssi_pcm_dai_ops,
470};
471
472static void setup_channel_to_ac97(struct imx_ssi *imx_ssi)
473{
474 void __iomem *base = imx_ssi->base;
475
476 writel(0x0, base + SSI_SCR);
477 writel(0x0, base + SSI_STCR);
478 writel(0x0, base + SSI_SRCR);
479
480 writel(SSI_SCR_SYN | SSI_SCR_NET, base + SSI_SCR);
481
482 writel(SSI_SFCSR_RFWM0(8) |
483 SSI_SFCSR_TFWM0(8) |
484 SSI_SFCSR_RFWM1(8) |
485 SSI_SFCSR_TFWM1(8), base + SSI_SFCSR);
486
487 writel(SSI_STCCR_WL(16) | SSI_STCCR_DC(12), base + SSI_STCCR);
488 writel(SSI_STCCR_WL(16) | SSI_STCCR_DC(12), base + SSI_SRCCR);
489
490 writel(SSI_SCR_SYN | SSI_SCR_NET | SSI_SCR_SSIEN, base + SSI_SCR);
491 writel(SSI_SOR_WAIT(3), base + SSI_SOR);
492
493 writel(SSI_SCR_SYN | SSI_SCR_NET | SSI_SCR_SSIEN |
494 SSI_SCR_TE | SSI_SCR_RE,
495 base + SSI_SCR);
496
497 writel(SSI_SACNT_DEFAULT, base + SSI_SACNT);
498 writel(0xff, base + SSI_SACCDIS);
499 writel(0x300, base + SSI_SACCEN);
500}
501
502static struct imx_ssi *ac97_ssi;
503
504static void imx_ssi_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
505 unsigned short val)
506{
507 struct imx_ssi *imx_ssi = ac97_ssi;
508 void __iomem *base = imx_ssi->base;
509 unsigned int lreg;
510 unsigned int lval;
511
512 if (reg > 0x7f)
513 return;
514
515 pr_debug("%s: 0x%02x 0x%04x\n", __func__, reg, val);
516
517 lreg = reg << 12;
518 writel(lreg, base + SSI_SACADD);
519
520 lval = val << 4;
521 writel(lval , base + SSI_SACDAT);
522
523 writel(SSI_SACNT_DEFAULT | SSI_SACNT_WR, base + SSI_SACNT);
524 udelay(100);
525}
526
527static unsigned short imx_ssi_ac97_read(struct snd_ac97 *ac97,
528 unsigned short reg)
529{
530 struct imx_ssi *imx_ssi = ac97_ssi;
531 void __iomem *base = imx_ssi->base;
532
533 unsigned short val = -1;
534 unsigned int lreg;
535
536 lreg = (reg & 0x7f) << 12 ;
537 writel(lreg, base + SSI_SACADD);
538 writel(SSI_SACNT_DEFAULT | SSI_SACNT_RD, base + SSI_SACNT);
539
540 udelay(100);
541
542 val = (readl(base + SSI_SACDAT) >> 4) & 0xffff;
543
544 pr_debug("%s: 0x%02x 0x%04x\n", __func__, reg, val);
545
546 return val;
547}
548
549static void imx_ssi_ac97_reset(struct snd_ac97 *ac97)
550{
551 struct imx_ssi *imx_ssi = ac97_ssi;
552
553 if (imx_ssi->ac97_reset)
554 imx_ssi->ac97_reset(ac97);
555}
556
557static void imx_ssi_ac97_warm_reset(struct snd_ac97 *ac97)
558{
559 struct imx_ssi *imx_ssi = ac97_ssi;
560
561 if (imx_ssi->ac97_warm_reset)
562 imx_ssi->ac97_warm_reset(ac97);
563}
564
565struct snd_ac97_bus_ops soc_ac97_ops = {
566 .read = imx_ssi_ac97_read,
567 .write = imx_ssi_ac97_write,
568 .reset = imx_ssi_ac97_reset,
569 .warm_reset = imx_ssi_ac97_warm_reset
570};
571EXPORT_SYMBOL_GPL(soc_ac97_ops);
572
573struct snd_soc_dai imx_ssi_pcm_dai[2];
574EXPORT_SYMBOL_GPL(imx_ssi_pcm_dai);
575
576static int imx_ssi_probe(struct platform_device *pdev)
577{
578 struct resource *res;
579 struct imx_ssi *ssi;
580 struct imx_ssi_platform_data *pdata = pdev->dev.platform_data;
581 struct snd_soc_platform *platform;
582 int ret = 0;
583 unsigned int val;
584 struct snd_soc_dai *dai = &imx_ssi_pcm_dai[pdev->id];
585
586 if (dai->id >= ARRAY_SIZE(imx_ssi_pcm_dai))
587 return -EINVAL;
588
589 ssi = kzalloc(sizeof(*ssi), GFP_KERNEL);
590 if (!ssi)
591 return -ENOMEM;
592
593 if (pdata) {
594 ssi->ac97_reset = pdata->ac97_reset;
595 ssi->ac97_warm_reset = pdata->ac97_warm_reset;
596 ssi->flags = pdata->flags;
597 }
598
599 ssi->irq = platform_get_irq(pdev, 0);
600
601 ssi->clk = clk_get(&pdev->dev, NULL);
602 if (IS_ERR(ssi->clk)) {
603 ret = PTR_ERR(ssi->clk);
604 dev_err(&pdev->dev, "Cannot get the clock: %d\n",
605 ret);
606 goto failed_clk;
607 }
608 clk_enable(ssi->clk);
609
610 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
611 if (!res) {
612 ret = -ENODEV;
613 goto failed_get_resource;
614 }
615
616 if (!request_mem_region(res->start, resource_size(res), DRV_NAME)) {
617 dev_err(&pdev->dev, "request_mem_region failed\n");
618 ret = -EBUSY;
619 goto failed_get_resource;
620 }
621
622 ssi->base = ioremap(res->start, resource_size(res));
623 if (!ssi->base) {
624 dev_err(&pdev->dev, "ioremap failed\n");
625 ret = -ENODEV;
626 goto failed_ioremap;
627 }
628
629 if (ssi->flags & IMX_SSI_USE_AC97) {
630 if (ac97_ssi) {
631 ret = -EBUSY;
632 goto failed_ac97;
633 }
634 ac97_ssi = ssi;
635 setup_channel_to_ac97(ssi);
636 memcpy(dai, &imx_ac97_dai, sizeof(imx_ac97_dai));
637 } else
638 memcpy(dai, &imx_ssi_dai, sizeof(imx_ssi_dai));
639
640 writel(0x0, ssi->base + SSI_SIER);
641
642 ssi->dma_params_rx.dma_addr = res->start + SSI_SRX0;
643 ssi->dma_params_tx.dma_addr = res->start + SSI_STX0;
644
645 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx0");
646 if (res)
647 ssi->dma_params_tx.dma = res->start;
648
649 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx0");
650 if (res)
651 ssi->dma_params_rx.dma = res->start;
652
653 dai->id = pdev->id;
654 dai->dev = &pdev->dev;
655 dai->name = kasprintf(GFP_KERNEL, "imx-ssi.%d", pdev->id);
656 dai->private_data = ssi;
657
658 if ((cpu_is_mx27() || cpu_is_mx21()) &&
659 !(ssi->flags & IMX_SSI_USE_AC97) &&
660 (ssi->flags & IMX_SSI_DMA)) {
661 ssi->flags |= IMX_SSI_DMA;
662 platform = imx_ssi_dma_mx2_init(pdev, ssi);
663 } else
664 platform = imx_ssi_fiq_init(pdev, ssi);
665
666 imx_soc_platform.pcm_ops = platform->pcm_ops;
667 imx_soc_platform.pcm_new = platform->pcm_new;
668 imx_soc_platform.pcm_free = platform->pcm_free;
669
670 val = SSI_SFCSR_TFWM0(ssi->dma_params_tx.burstsize) |
671 SSI_SFCSR_RFWM0(ssi->dma_params_rx.burstsize);
672 writel(val, ssi->base + SSI_SFCSR);
673
674 ret = snd_soc_register_dai(dai);
675 if (ret) {
676 dev_err(&pdev->dev, "register DAI failed\n");
677 goto failed_register;
678 }
679
680 platform_set_drvdata(pdev, ssi);
681
682 return 0;
683
684failed_register:
685failed_ac97:
686 iounmap(ssi->base);
687failed_ioremap:
688 release_mem_region(res->start, resource_size(res));
689failed_get_resource:
690 clk_disable(ssi->clk);
691 clk_put(ssi->clk);
692failed_clk:
693 kfree(ssi);
694
695 return ret;
696}
697
698static int __devexit imx_ssi_remove(struct platform_device *pdev)
699{
700 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
701 struct imx_ssi *ssi = platform_get_drvdata(pdev);
702 struct snd_soc_dai *dai = &imx_ssi_pcm_dai[pdev->id];
703
704 snd_soc_unregister_dai(dai);
705
706 if (ssi->flags & IMX_SSI_USE_AC97)
707 ac97_ssi = NULL;
708
709 if (!(ssi->flags & IMX_SSI_DMA))
710 imx_ssi_fiq_exit(pdev, ssi);
711
712 iounmap(ssi->base);
713 release_mem_region(res->start, resource_size(res));
714 clk_disable(ssi->clk);
715 clk_put(ssi->clk);
716 kfree(ssi);
717
718 return 0;
719}
720
721static struct platform_driver imx_ssi_driver = {
722 .probe = imx_ssi_probe,
723 .remove = __devexit_p(imx_ssi_remove),
724
725 .driver = {
726 .name = DRV_NAME,
727 .owner = THIS_MODULE,
728 },
729};
730
731static int __init imx_ssi_init(void)
732{
733 int ret;
734
735 ret = snd_soc_register_platform(&imx_soc_platform);
736 if (ret) {
737 pr_err("failed to register soc platform: %d\n", ret);
738 return ret;
739 }
740
741 ret = platform_driver_register(&imx_ssi_driver);
742 if (ret) {
743 snd_soc_unregister_platform(&imx_soc_platform);
744 return ret;
745 }
746
747 return 0;
748}
749
750static void __exit imx_ssi_exit(void)
751{
752 platform_driver_unregister(&imx_ssi_driver);
753 snd_soc_unregister_platform(&imx_soc_platform);
754}
755
756module_init(imx_ssi_init);
757module_exit(imx_ssi_exit);
758
759/* Module information */
760MODULE_AUTHOR("Sascha Hauer, <s.hauer@pengutronix.de>");
761MODULE_DESCRIPTION("i.MX I2S/ac97 SoC Interface");
762MODULE_LICENSE("GPL");
763
diff --git a/sound/soc/imx/imx-ssi.h b/sound/soc/imx/imx-ssi.h
new file mode 100644
index 000000000000..55f26ebcd8c2
--- /dev/null
+++ b/sound/soc/imx/imx-ssi.h
@@ -0,0 +1,237 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License version 2 as
4 * published by the Free Software Foundation.
5 */
6
7#ifndef _IMX_SSI_H
8#define _IMX_SSI_H
9
10#define SSI_STX0 0x00
11#define SSI_STX1 0x04
12#define SSI_SRX0 0x08
13#define SSI_SRX1 0x0c
14
15#define SSI_SCR 0x10
16#define SSI_SCR_CLK_IST (1 << 9)
17#define SSI_SCR_CLK_IST_SHIFT 9
18#define SSI_SCR_TCH_EN (1 << 8)
19#define SSI_SCR_SYS_CLK_EN (1 << 7)
20#define SSI_SCR_I2S_MODE_NORM (0 << 5)
21#define SSI_SCR_I2S_MODE_MSTR (1 << 5)
22#define SSI_SCR_I2S_MODE_SLAVE (2 << 5)
23#define SSI_I2S_MODE_MASK (3 << 5)
24#define SSI_SCR_SYN (1 << 4)
25#define SSI_SCR_NET (1 << 3)
26#define SSI_SCR_RE (1 << 2)
27#define SSI_SCR_TE (1 << 1)
28#define SSI_SCR_SSIEN (1 << 0)
29
30#define SSI_SISR 0x14
31#define SSI_SISR_MASK ((1 << 19) - 1)
32#define SSI_SISR_CMDAU (1 << 18)
33#define SSI_SISR_CMDDU (1 << 17)
34#define SSI_SISR_RXT (1 << 16)
35#define SSI_SISR_RDR1 (1 << 15)
36#define SSI_SISR_RDR0 (1 << 14)
37#define SSI_SISR_TDE1 (1 << 13)
38#define SSI_SISR_TDE0 (1 << 12)
39#define SSI_SISR_ROE1 (1 << 11)
40#define SSI_SISR_ROE0 (1 << 10)
41#define SSI_SISR_TUE1 (1 << 9)
42#define SSI_SISR_TUE0 (1 << 8)
43#define SSI_SISR_TFS (1 << 7)
44#define SSI_SISR_RFS (1 << 6)
45#define SSI_SISR_TLS (1 << 5)
46#define SSI_SISR_RLS (1 << 4)
47#define SSI_SISR_RFF1 (1 << 3)
48#define SSI_SISR_RFF0 (1 << 2)
49#define SSI_SISR_TFE1 (1 << 1)
50#define SSI_SISR_TFE0 (1 << 0)
51
52#define SSI_SIER 0x18
53#define SSI_SIER_RDMAE (1 << 22)
54#define SSI_SIER_RIE (1 << 21)
55#define SSI_SIER_TDMAE (1 << 20)
56#define SSI_SIER_TIE (1 << 19)
57#define SSI_SIER_CMDAU_EN (1 << 18)
58#define SSI_SIER_CMDDU_EN (1 << 17)
59#define SSI_SIER_RXT_EN (1 << 16)
60#define SSI_SIER_RDR1_EN (1 << 15)
61#define SSI_SIER_RDR0_EN (1 << 14)
62#define SSI_SIER_TDE1_EN (1 << 13)
63#define SSI_SIER_TDE0_EN (1 << 12)
64#define SSI_SIER_ROE1_EN (1 << 11)
65#define SSI_SIER_ROE0_EN (1 << 10)
66#define SSI_SIER_TUE1_EN (1 << 9)
67#define SSI_SIER_TUE0_EN (1 << 8)
68#define SSI_SIER_TFS_EN (1 << 7)
69#define SSI_SIER_RFS_EN (1 << 6)
70#define SSI_SIER_TLS_EN (1 << 5)
71#define SSI_SIER_RLS_EN (1 << 4)
72#define SSI_SIER_RFF1_EN (1 << 3)
73#define SSI_SIER_RFF0_EN (1 << 2)
74#define SSI_SIER_TFE1_EN (1 << 1)
75#define SSI_SIER_TFE0_EN (1 << 0)
76
77#define SSI_STCR 0x1c
78#define SSI_STCR_TXBIT0 (1 << 9)
79#define SSI_STCR_TFEN1 (1 << 8)
80#define SSI_STCR_TFEN0 (1 << 7)
81#define SSI_FIFO_ENABLE_0_SHIFT 7
82#define SSI_STCR_TFDIR (1 << 6)
83#define SSI_STCR_TXDIR (1 << 5)
84#define SSI_STCR_TSHFD (1 << 4)
85#define SSI_STCR_TSCKP (1 << 3)
86#define SSI_STCR_TFSI (1 << 2)
87#define SSI_STCR_TFSL (1 << 1)
88#define SSI_STCR_TEFS (1 << 0)
89
90#define SSI_SRCR 0x20
91#define SSI_SRCR_RXBIT0 (1 << 9)
92#define SSI_SRCR_RFEN1 (1 << 8)
93#define SSI_SRCR_RFEN0 (1 << 7)
94#define SSI_FIFO_ENABLE_0_SHIFT 7
95#define SSI_SRCR_RFDIR (1 << 6)
96#define SSI_SRCR_RXDIR (1 << 5)
97#define SSI_SRCR_RSHFD (1 << 4)
98#define SSI_SRCR_RSCKP (1 << 3)
99#define SSI_SRCR_RFSI (1 << 2)
100#define SSI_SRCR_RFSL (1 << 1)
101#define SSI_SRCR_REFS (1 << 0)
102
103#define SSI_SRCCR 0x28
104#define SSI_SRCCR_DIV2 (1 << 18)
105#define SSI_SRCCR_PSR (1 << 17)
106#define SSI_SRCCR_WL(x) ((((x) - 2) >> 1) << 13)
107#define SSI_SRCCR_DC(x) (((x) & 0x1f) << 8)
108#define SSI_SRCCR_PM(x) (((x) & 0xff) << 0)
109#define SSI_SRCCR_WL_MASK (0xf << 13)
110#define SSI_SRCCR_DC_MASK (0x1f << 8)
111#define SSI_SRCCR_PM_MASK (0xff << 0)
112
113#define SSI_STCCR 0x24
114#define SSI_STCCR_DIV2 (1 << 18)
115#define SSI_STCCR_PSR (1 << 17)
116#define SSI_STCCR_WL(x) ((((x) - 2) >> 1) << 13)
117#define SSI_STCCR_DC(x) (((x) & 0x1f) << 8)
118#define SSI_STCCR_PM(x) (((x) & 0xff) << 0)
119#define SSI_STCCR_WL_MASK (0xf << 13)
120#define SSI_STCCR_DC_MASK (0x1f << 8)
121#define SSI_STCCR_PM_MASK (0xff << 0)
122
123#define SSI_SFCSR 0x2c
124#define SSI_SFCSR_RFCNT1(x) (((x) & 0xf) << 28)
125#define SSI_RX_FIFO_1_COUNT_SHIFT 28
126#define SSI_SFCSR_TFCNT1(x) (((x) & 0xf) << 24)
127#define SSI_TX_FIFO_1_COUNT_SHIFT 24
128#define SSI_SFCSR_RFWM1(x) (((x) & 0xf) << 20)
129#define SSI_SFCSR_TFWM1(x) (((x) & 0xf) << 16)
130#define SSI_SFCSR_RFCNT0(x) (((x) & 0xf) << 12)
131#define SSI_RX_FIFO_0_COUNT_SHIFT 12
132#define SSI_SFCSR_TFCNT0(x) (((x) & 0xf) << 8)
133#define SSI_TX_FIFO_0_COUNT_SHIFT 8
134#define SSI_SFCSR_RFWM0(x) (((x) & 0xf) << 4)
135#define SSI_SFCSR_TFWM0(x) (((x) & 0xf) << 0)
136#define SSI_SFCSR_RFWM0_MASK (0xf << 4)
137#define SSI_SFCSR_TFWM0_MASK (0xf << 0)
138
139#define SSI_STR 0x30
140#define SSI_STR_TEST (1 << 15)
141#define SSI_STR_RCK2TCK (1 << 14)
142#define SSI_STR_RFS2TFS (1 << 13)
143#define SSI_STR_RXSTATE(x) (((x) & 0xf) << 8)
144#define SSI_STR_TXD2RXD (1 << 7)
145#define SSI_STR_TCK2RCK (1 << 6)
146#define SSI_STR_TFS2RFS (1 << 5)
147#define SSI_STR_TXSTATE(x) (((x) & 0xf) << 0)
148
149#define SSI_SOR 0x34
150#define SSI_SOR_CLKOFF (1 << 6)
151#define SSI_SOR_RX_CLR (1 << 5)
152#define SSI_SOR_TX_CLR (1 << 4)
153#define SSI_SOR_INIT (1 << 3)
154#define SSI_SOR_WAIT(x) (((x) & 0x3) << 1)
155#define SSI_SOR_WAIT_MASK (0x3 << 1)
156#define SSI_SOR_SYNRST (1 << 0)
157
158#define SSI_SACNT 0x38
159#define SSI_SACNT_FRDIV(x) (((x) & 0x3f) << 5)
160#define SSI_SACNT_WR (1 << 4)
161#define SSI_SACNT_RD (1 << 3)
162#define SSI_SACNT_TIF (1 << 2)
163#define SSI_SACNT_FV (1 << 1)
164#define SSI_SACNT_AC97EN (1 << 0)
165
166#define SSI_SACADD 0x3c
167#define SSI_SACDAT 0x40
168#define SSI_SATAG 0x44
169#define SSI_STMSK 0x48
170#define SSI_SRMSK 0x4c
171#define SSI_SACCST 0x50
172#define SSI_SACCEN 0x54
173#define SSI_SACCDIS 0x58
174
175/* SSI clock sources */
176#define IMX_SSP_SYS_CLK 0
177
178/* SSI audio dividers */
179#define IMX_SSI_TX_DIV_2 0
180#define IMX_SSI_TX_DIV_PSR 1
181#define IMX_SSI_TX_DIV_PM 2
182#define IMX_SSI_RX_DIV_2 3
183#define IMX_SSI_RX_DIV_PSR 4
184#define IMX_SSI_RX_DIV_PM 5
185
186extern struct snd_soc_dai imx_ssi_pcm_dai[2];
187extern struct snd_soc_platform imx_soc_platform;
188
189#define DRV_NAME "imx-ssi"
190
191struct imx_pcm_dma_params {
192 int dma;
193 unsigned long dma_addr;
194 int burstsize;
195};
196
197struct imx_ssi {
198 struct platform_device *ac97_dev;
199
200 struct snd_soc_device imx_ac97;
201 struct clk *clk;
202 void __iomem *base;
203 int irq;
204 int fiq_enable;
205 unsigned int offset;
206
207 unsigned int flags;
208
209 void (*ac97_reset) (struct snd_ac97 *ac97);
210 void (*ac97_warm_reset)(struct snd_ac97 *ac97);
211
212 struct imx_pcm_dma_params dma_params_rx;
213 struct imx_pcm_dma_params dma_params_tx;
214
215 int enabled;
216};
217
218struct snd_soc_platform *imx_ssi_fiq_init(struct platform_device *pdev,
219 struct imx_ssi *ssi);
220void imx_ssi_fiq_exit(struct platform_device *pdev, struct imx_ssi *ssi);
221struct snd_soc_platform *imx_ssi_dma_mx2_init(struct platform_device *pdev,
222 struct imx_ssi *ssi);
223
224int snd_imx_pcm_mmap(struct snd_pcm_substream *substream, struct vm_area_struct *vma);
225int imx_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
226 struct snd_pcm *pcm);
227void imx_pcm_free(struct snd_pcm *pcm);
228
229/*
230 * Do not change this as the FIQ handler depends on this size
231 */
232#define IMX_SSI_DMABUF_SIZE (64 * 1024)
233
234#define DMA_RXFIFO_BURST 0x4
235#define DMA_TXFIFO_BURST 0x6
236
237#endif /* _IMX_SSI_H */
diff --git a/sound/soc/imx/mx1_mx2-pcm.c b/sound/soc/imx/mx1_mx2-pcm.c
deleted file mode 100644
index b83866529397..000000000000
--- a/sound/soc/imx/mx1_mx2-pcm.c
+++ /dev/null
@@ -1,488 +0,0 @@
1/*
2 * mx1_mx2-pcm.c -- ALSA SoC interface for Freescale i.MX1x, i.MX2x CPUs
3 *
4 * Copyright 2009 Vista Silicon S.L.
5 * Author: Javier Martin
6 * javier.martin@vista-silicon.com
7 *
8 * Based on mxc-pcm.c by Liam Girdwood.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 *
15 */
16
17#include <linux/module.h>
18#include <linux/init.h>
19#include <linux/platform_device.h>
20#include <linux/slab.h>
21#include <linux/dma-mapping.h>
22#include <sound/core.h>
23#include <sound/pcm.h>
24#include <sound/pcm_params.h>
25#include <sound/soc.h>
26#include <asm/dma.h>
27#include <mach/hardware.h>
28#include <mach/dma-mx1-mx2.h>
29
30#include "mx1_mx2-pcm.h"
31
32
33static const struct snd_pcm_hardware mx1_mx2_pcm_hardware = {
34 .info = (SNDRV_PCM_INFO_INTERLEAVED |
35 SNDRV_PCM_INFO_BLOCK_TRANSFER |
36 SNDRV_PCM_INFO_MMAP |
37 SNDRV_PCM_INFO_MMAP_VALID),
38 .formats = SNDRV_PCM_FMTBIT_S16_LE,
39 .buffer_bytes_max = 32 * 1024,
40 .period_bytes_min = 64,
41 .period_bytes_max = 8 * 1024,
42 .periods_min = 2,
43 .periods_max = 255,
44 .fifo_size = 0,
45};
46
47struct mx1_mx2_runtime_data {
48 int dma_ch;
49 int active;
50 unsigned int period;
51 unsigned int periods;
52 int tx_spin;
53 spinlock_t dma_lock;
54 struct mx1_mx2_pcm_dma_params *dma_params;
55};
56
57
58/**
59 * This function stops the current dma transfer for playback
60 * and clears the dma pointers.
61 *
62 * @param substream pointer to the structure of the current stream.
63 *
64 */
65static int audio_stop_dma(struct snd_pcm_substream *substream)
66{
67 struct snd_pcm_runtime *runtime = substream->runtime;
68 struct mx1_mx2_runtime_data *prtd = runtime->private_data;
69 unsigned long flags;
70
71 spin_lock_irqsave(&prtd->dma_lock, flags);
72
73 pr_debug("%s\n", __func__);
74
75 prtd->active = 0;
76 prtd->period = 0;
77 prtd->periods = 0;
78
79 /* this stops the dma channel and clears the buffer ptrs */
80
81 imx_dma_disable(prtd->dma_ch);
82
83 spin_unlock_irqrestore(&prtd->dma_lock, flags);
84
85 return 0;
86}
87
88/**
89 * This function is called whenever a new audio block needs to be
90 * transferred to the codec. The function receives the address and the size
91 * of the new block and start a new DMA transfer.
92 *
93 * @param substream pointer to the structure of the current stream.
94 *
95 */
96static int dma_new_period(struct snd_pcm_substream *substream)
97{
98 struct snd_pcm_runtime *runtime = substream->runtime;
99 struct mx1_mx2_runtime_data *prtd = runtime->private_data;
100 unsigned int dma_size;
101 unsigned int offset;
102 int ret = 0;
103 dma_addr_t mem_addr;
104 unsigned int dev_addr;
105
106 if (prtd->active) {
107 dma_size = frames_to_bytes(runtime, runtime->period_size);
108 offset = dma_size * prtd->period;
109
110 pr_debug("%s: period (%d) out of (%d)\n", __func__,
111 prtd->period,
112 runtime->periods);
113 pr_debug("period_size %d frames\n offset %d bytes\n",
114 (unsigned int)runtime->period_size,
115 offset);
116 pr_debug("dma_size %d bytes\n", dma_size);
117
118 snd_BUG_ON(dma_size > mx1_mx2_pcm_hardware.period_bytes_max);
119
120 mem_addr = (dma_addr_t)(runtime->dma_addr + offset);
121 dev_addr = prtd->dma_params->per_address;
122 pr_debug("%s: mem_addr is %x\n dev_addr is %x\n",
123 __func__, mem_addr, dev_addr);
124
125 ret = imx_dma_setup_single(prtd->dma_ch, mem_addr,
126 dma_size, dev_addr,
127 prtd->dma_params->transfer_type);
128 if (ret < 0) {
129 printk(KERN_ERR "Error %d configuring DMA\n", ret);
130 return ret;
131 }
132 imx_dma_enable(prtd->dma_ch);
133
134 pr_debug("%s: transfer enabled\nmem_addr = %x\n",
135 __func__, (unsigned int) mem_addr);
136 pr_debug("dev_addr = %x\ndma_size = %d\n",
137 (unsigned int) dev_addr, dma_size);
138
139 prtd->tx_spin = 1; /* FGA little trick to retrieve DMA pos */
140 prtd->period++;
141 prtd->period %= runtime->periods;
142 }
143 return ret;
144}
145
146
147/**
148 * This is a callback which will be called
149 * when a TX transfer finishes. The call occurs
150 * in interrupt context.
151 *
152 * @param dat pointer to the structure of the current stream.
153 *
154 */
155static void audio_dma_irq(int channel, void *data)
156{
157 struct snd_pcm_substream *substream;
158 struct snd_pcm_runtime *runtime;
159 struct mx1_mx2_runtime_data *prtd;
160 unsigned int dma_size;
161 unsigned int previous_period;
162 unsigned int offset;
163
164 substream = data;
165 runtime = substream->runtime;
166 prtd = runtime->private_data;
167 previous_period = prtd->periods;
168 dma_size = frames_to_bytes(runtime, runtime->period_size);
169 offset = dma_size * previous_period;
170
171 prtd->tx_spin = 0;
172 prtd->periods++;
173 prtd->periods %= runtime->periods;
174
175 pr_debug("%s: irq per %d offset %x\n", __func__, prtd->periods, offset);
176
177 /*
178 * If we are getting a callback for an active stream then we inform
179 * the PCM middle layer we've finished a period
180 */
181 if (prtd->active)
182 snd_pcm_period_elapsed(substream);
183
184 /*
185 * Trig next DMA transfer
186 */
187 dma_new_period(substream);
188}
189
190/**
191 * This function configures the hardware to allow audio
192 * playback operations. It is called by ALSA framework.
193 *
194 * @param substream pointer to the structure of the current stream.
195 *
196 * @return 0 on success, -1 otherwise.
197 */
198static int
199snd_mx1_mx2_prepare(struct snd_pcm_substream *substream)
200{
201 struct snd_pcm_runtime *runtime = substream->runtime;
202 struct mx1_mx2_runtime_data *prtd = runtime->private_data;
203
204 prtd->period = 0;
205 prtd->periods = 0;
206
207 return 0;
208}
209
210static int mx1_mx2_pcm_hw_params(struct snd_pcm_substream *substream,
211 struct snd_pcm_hw_params *hw_params)
212{
213 struct snd_pcm_runtime *runtime = substream->runtime;
214 int ret;
215
216 ret = snd_pcm_lib_malloc_pages(substream,
217 params_buffer_bytes(hw_params));
218 if (ret < 0) {
219 printk(KERN_ERR "%s: Error %d failed to malloc pcm pages \n",
220 __func__, ret);
221 return ret;
222 }
223
224 pr_debug("%s: snd_imx1_mx2_audio_hw_params runtime->dma_addr 0x(%x)\n",
225 __func__, (unsigned int)runtime->dma_addr);
226 pr_debug("%s: snd_imx1_mx2_audio_hw_params runtime->dma_area 0x(%x)\n",
227 __func__, (unsigned int)runtime->dma_area);
228 pr_debug("%s: snd_imx1_mx2_audio_hw_params runtime->dma_bytes 0x(%x)\n",
229 __func__, (unsigned int)runtime->dma_bytes);
230
231 return ret;
232}
233
234static int mx1_mx2_pcm_hw_free(struct snd_pcm_substream *substream)
235{
236 struct snd_pcm_runtime *runtime = substream->runtime;
237 struct mx1_mx2_runtime_data *prtd = runtime->private_data;
238
239 imx_dma_free(prtd->dma_ch);
240
241 snd_pcm_lib_free_pages(substream);
242
243 return 0;
244}
245
246static int mx1_mx2_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
247{
248 struct mx1_mx2_runtime_data *prtd = substream->runtime->private_data;
249 int ret = 0;
250
251 switch (cmd) {
252 case SNDRV_PCM_TRIGGER_START:
253 prtd->tx_spin = 0;
254 /* requested stream startup */
255 prtd->active = 1;
256 pr_debug("%s: starting dma_new_period\n", __func__);
257 ret = dma_new_period(substream);
258 break;
259 case SNDRV_PCM_TRIGGER_STOP:
260 /* requested stream shutdown */
261 pr_debug("%s: stopping dma transfer\n", __func__);
262 ret = audio_stop_dma(substream);
263 break;
264 default:
265 ret = -EINVAL;
266 break;
267 }
268
269 return ret;
270}
271
272static snd_pcm_uframes_t
273mx1_mx2_pcm_pointer(struct snd_pcm_substream *substream)
274{
275 struct snd_pcm_runtime *runtime = substream->runtime;
276 struct mx1_mx2_runtime_data *prtd = runtime->private_data;
277 unsigned int offset = 0;
278
279 /* tx_spin value is used here to check if a transfer is active */
280 if (prtd->tx_spin) {
281 offset = (runtime->period_size * (prtd->periods)) +
282 (runtime->period_size >> 1);
283 if (offset >= runtime->buffer_size)
284 offset = runtime->period_size >> 1;
285 } else {
286 offset = (runtime->period_size * (prtd->periods));
287 if (offset >= runtime->buffer_size)
288 offset = 0;
289 }
290 pr_debug("%s: pointer offset %x\n", __func__, offset);
291
292 return offset;
293}
294
295static int mx1_mx2_pcm_open(struct snd_pcm_substream *substream)
296{
297 struct snd_pcm_runtime *runtime = substream->runtime;
298 struct mx1_mx2_runtime_data *prtd;
299 struct snd_soc_pcm_runtime *rtd = substream->private_data;
300 struct mx1_mx2_pcm_dma_params *dma_data = rtd->dai->cpu_dai->dma_data;
301 int ret;
302
303 snd_soc_set_runtime_hwparams(substream, &mx1_mx2_pcm_hardware);
304
305 ret = snd_pcm_hw_constraint_integer(runtime,
306 SNDRV_PCM_HW_PARAM_PERIODS);
307 if (ret < 0)
308 return ret;
309
310 prtd = kzalloc(sizeof(struct mx1_mx2_runtime_data), GFP_KERNEL);
311 if (prtd == NULL) {
312 ret = -ENOMEM;
313 goto out;
314 }
315
316 runtime->private_data = prtd;
317
318 if (!dma_data)
319 return -ENODEV;
320
321 prtd->dma_params = dma_data;
322
323 pr_debug("%s: Requesting dma channel (%s)\n", __func__,
324 prtd->dma_params->name);
325 prtd->dma_ch = imx_dma_request_by_prio(prtd->dma_params->name,
326 DMA_PRIO_HIGH);
327 if (prtd->dma_ch < 0) {
328 printk(KERN_ERR "Error %d requesting dma channel\n", ret);
329 return ret;
330 }
331 imx_dma_config_burstlen(prtd->dma_ch,
332 prtd->dma_params->watermark_level);
333
334 ret = imx_dma_config_channel(prtd->dma_ch,
335 prtd->dma_params->per_config,
336 prtd->dma_params->mem_config,
337 prtd->dma_params->event_id, 0);
338
339 if (ret) {
340 pr_debug(KERN_ERR "Error %d configuring dma channel %d\n",
341 ret, prtd->dma_ch);
342 return ret;
343 }
344
345 pr_debug("%s: Setting tx dma callback function\n", __func__);
346 ret = imx_dma_setup_handlers(prtd->dma_ch,
347 audio_dma_irq, NULL,
348 (void *)substream);
349 if (ret < 0) {
350 printk(KERN_ERR "Error %d setting dma callback function\n", ret);
351 return ret;
352 }
353 return 0;
354
355 out:
356 return ret;
357}
358
359static int mx1_mx2_pcm_close(struct snd_pcm_substream *substream)
360{
361 struct snd_pcm_runtime *runtime = substream->runtime;
362 struct mx1_mx2_runtime_data *prtd = runtime->private_data;
363
364 kfree(prtd);
365
366 return 0;
367}
368
369static int mx1_mx2_pcm_mmap(struct snd_pcm_substream *substream,
370 struct vm_area_struct *vma)
371{
372 struct snd_pcm_runtime *runtime = substream->runtime;
373 return dma_mmap_writecombine(substream->pcm->card->dev, vma,
374 runtime->dma_area,
375 runtime->dma_addr,
376 runtime->dma_bytes);
377}
378
379static struct snd_pcm_ops mx1_mx2_pcm_ops = {
380 .open = mx1_mx2_pcm_open,
381 .close = mx1_mx2_pcm_close,
382 .ioctl = snd_pcm_lib_ioctl,
383 .hw_params = mx1_mx2_pcm_hw_params,
384 .hw_free = mx1_mx2_pcm_hw_free,
385 .prepare = snd_mx1_mx2_prepare,
386 .trigger = mx1_mx2_pcm_trigger,
387 .pointer = mx1_mx2_pcm_pointer,
388 .mmap = mx1_mx2_pcm_mmap,
389};
390
391static u64 mx1_mx2_pcm_dmamask = 0xffffffff;
392
393static int mx1_mx2_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
394{
395 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
396 struct snd_dma_buffer *buf = &substream->dma_buffer;
397 size_t size = mx1_mx2_pcm_hardware.buffer_bytes_max;
398 buf->dev.type = SNDRV_DMA_TYPE_DEV;
399 buf->dev.dev = pcm->card->dev;
400 buf->private_data = NULL;
401
402 /* Reserve uncached-buffered memory area for DMA */
403 buf->area = dma_alloc_writecombine(pcm->card->dev, size,
404 &buf->addr, GFP_KERNEL);
405
406 pr_debug("%s: preallocate_dma_buffer: area=%p, addr=%p, size=%d\n",
407 __func__, (void *) buf->area, (void *) buf->addr, size);
408
409 if (!buf->area)
410 return -ENOMEM;
411
412 buf->bytes = size;
413 return 0;
414}
415
416static void mx1_mx2_pcm_free_dma_buffers(struct snd_pcm *pcm)
417{
418 struct snd_pcm_substream *substream;
419 struct snd_dma_buffer *buf;
420 int stream;
421
422 for (stream = 0; stream < 2; stream++) {
423 substream = pcm->streams[stream].substream;
424 if (!substream)
425 continue;
426
427 buf = &substream->dma_buffer;
428 if (!buf->area)
429 continue;
430
431 dma_free_writecombine(pcm->card->dev, buf->bytes,
432 buf->area, buf->addr);
433 buf->area = NULL;
434 }
435}
436
437static int mx1_mx2_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
438 struct snd_pcm *pcm)
439{
440 int ret = 0;
441
442 if (!card->dev->dma_mask)
443 card->dev->dma_mask = &mx1_mx2_pcm_dmamask;
444 if (!card->dev->coherent_dma_mask)
445 card->dev->coherent_dma_mask = 0xffffffff;
446
447 if (dai->playback.channels_min) {
448 ret = mx1_mx2_pcm_preallocate_dma_buffer(pcm,
449 SNDRV_PCM_STREAM_PLAYBACK);
450 pr_debug("%s: preallocate playback buffer\n", __func__);
451 if (ret)
452 goto out;
453 }
454
455 if (dai->capture.channels_min) {
456 ret = mx1_mx2_pcm_preallocate_dma_buffer(pcm,
457 SNDRV_PCM_STREAM_CAPTURE);
458 pr_debug("%s: preallocate capture buffer\n", __func__);
459 if (ret)
460 goto out;
461 }
462 out:
463 return ret;
464}
465
466struct snd_soc_platform mx1_mx2_soc_platform = {
467 .name = "mx1_mx2-audio",
468 .pcm_ops = &mx1_mx2_pcm_ops,
469 .pcm_new = mx1_mx2_pcm_new,
470 .pcm_free = mx1_mx2_pcm_free_dma_buffers,
471};
472EXPORT_SYMBOL_GPL(mx1_mx2_soc_platform);
473
474static int __init mx1_mx2_soc_platform_init(void)
475{
476 return snd_soc_register_platform(&mx1_mx2_soc_platform);
477}
478module_init(mx1_mx2_soc_platform_init);
479
480static void __exit mx1_mx2_soc_platform_exit(void)
481{
482 snd_soc_unregister_platform(&mx1_mx2_soc_platform);
483}
484module_exit(mx1_mx2_soc_platform_exit);
485
486MODULE_AUTHOR("Javier Martin, javier.martin@vista-silicon.com");
487MODULE_DESCRIPTION("Freescale i.MX2x, i.MX1x PCM DMA module");
488MODULE_LICENSE("GPL");
diff --git a/sound/soc/imx/mx1_mx2-pcm.h b/sound/soc/imx/mx1_mx2-pcm.h
deleted file mode 100644
index 2e528106570b..000000000000
--- a/sound/soc/imx/mx1_mx2-pcm.h
+++ /dev/null
@@ -1,26 +0,0 @@
1/*
2 * mx1_mx2-pcm.h :- ASoC platform header for Freescale i.MX1x, i.MX2x
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#ifndef _MX1_MX2_PCM_H
10#define _MX1_MX2_PCM_H
11
12/* DMA information for mx1_mx2 platforms */
13struct mx1_mx2_pcm_dma_params {
14 char *name; /* stream identifier */
15 unsigned int transfer_type; /* READ or WRITE DMA transfer */
16 dma_addr_t per_address; /* physical address of SSI fifo */
17 int event_id; /* fixed DMA number for SSI fifo */
18 int watermark_level; /* SSI fifo watermark level */
19 int per_config; /* DMA Config flags for peripheral */
20 int mem_config; /* DMA Config flags for RAM */
21 };
22
23/* platform data */
24extern struct snd_soc_platform mx1_mx2_soc_platform;
25
26#endif
diff --git a/sound/soc/imx/mx27vis_wm8974.c b/sound/soc/imx/mx27vis_wm8974.c
deleted file mode 100644
index e4dcb539108a..000000000000
--- a/sound/soc/imx/mx27vis_wm8974.c
+++ /dev/null
@@ -1,317 +0,0 @@
1/*
2 * mx27vis_wm8974.c -- SoC audio for mx27vis
3 *
4 * Copyright 2009 Vista Silicon S.L.
5 * Author: Javier Martin
6 * javier.martin@vista-silicon.com
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 */
14
15#include <linux/module.h>
16#include <linux/moduleparam.h>
17#include <linux/device.h>
18#include <linux/i2c.h>
19#include <sound/core.h>
20#include <sound/pcm.h>
21#include <sound/soc.h>
22#include <sound/soc-dapm.h>
23
24
25#include "../codecs/wm8974.h"
26#include "mx1_mx2-pcm.h"
27#include "mxc-ssi.h"
28#include <mach/gpio.h>
29#include <mach/iomux.h>
30
31#define IGNORED_ARG 0
32
33
34static struct snd_soc_card mx27vis;
35
36/**
37 * This function connects SSI1 (HPCR1) as slave to
38 * SSI1 external signals (PPCR1)
39 * As slave, HPCR1 must set TFSDIR and TCLKDIR as inputs from
40 * port 4
41 */
42void audmux_connect_1_4(void)
43{
44 pr_debug("AUDMUX: normal operation mode\n");
45 /* Reset HPCR1 and PPCR1 */
46
47 DAM_HPCR1 = 0x00000000;
48 DAM_PPCR1 = 0x00000000;
49
50 /* set to synchronous */
51 DAM_HPCR1 |= AUDMUX_HPCR_SYN;
52 DAM_PPCR1 |= AUDMUX_PPCR_SYN;
53
54
55 /* set Rx sources 1 <--> 4 */
56 DAM_HPCR1 |= AUDMUX_HPCR_RXDSEL(3); /* port 4 */
57 DAM_PPCR1 |= AUDMUX_PPCR_RXDSEL(0); /* port 1 */
58
59 /* set Tx frame and Clock direction and source 4 --> 1 output */
60 DAM_HPCR1 |= AUDMUX_HPCR_TFSDIR | AUDMUX_HPCR_TCLKDIR;
61 DAM_HPCR1 |= AUDMUX_HPCR_TFCSEL(3); /* TxDS and TxCclk from port 4 */
62
63 return;
64}
65
66static int mx27vis_hifi_hw_params(struct snd_pcm_substream *substream,
67 struct snd_pcm_hw_params *params)
68{
69 struct snd_soc_pcm_runtime *rtd = substream->private_data;
70 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
71 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
72 unsigned int pll_out = 0, bclk = 0, fmt = 0, mclk = 0;
73 int ret = 0;
74
75 /*
76 * The WM8974 is better at generating accurate audio clocks than the
77 * MX27 SSI controller, so we will use it as master when we can.
78 */
79 switch (params_rate(params)) {
80 case 8000:
81 fmt = SND_SOC_DAIFMT_CBM_CFM;
82 mclk = WM8974_MCLKDIV_12;
83 pll_out = 24576000;
84 break;
85 case 16000:
86 fmt = SND_SOC_DAIFMT_CBM_CFM;
87 pll_out = 12288000;
88 break;
89 case 48000:
90 fmt = SND_SOC_DAIFMT_CBM_CFM;
91 bclk = WM8974_BCLKDIV_4;
92 pll_out = 12288000;
93 break;
94 case 96000:
95 fmt = SND_SOC_DAIFMT_CBM_CFM;
96 bclk = WM8974_BCLKDIV_2;
97 pll_out = 12288000;
98 break;
99 case 11025:
100 fmt = SND_SOC_DAIFMT_CBM_CFM;
101 bclk = WM8974_BCLKDIV_16;
102 pll_out = 11289600;
103 break;
104 case 22050:
105 fmt = SND_SOC_DAIFMT_CBM_CFM;
106 bclk = WM8974_BCLKDIV_8;
107 pll_out = 11289600;
108 break;
109 case 44100:
110 fmt = SND_SOC_DAIFMT_CBM_CFM;
111 bclk = WM8974_BCLKDIV_4;
112 mclk = WM8974_MCLKDIV_2;
113 pll_out = 11289600;
114 break;
115 case 88200:
116 fmt = SND_SOC_DAIFMT_CBM_CFM;
117 bclk = WM8974_BCLKDIV_2;
118 pll_out = 11289600;
119 break;
120 }
121
122 /* set codec DAI configuration */
123 ret = codec_dai->ops->set_fmt(codec_dai,
124 SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_IF |
125 SND_SOC_DAIFMT_SYNC | fmt);
126 if (ret < 0) {
127 printk(KERN_ERR "Error from codec DAI configuration\n");
128 return ret;
129 }
130
131 /* set cpu DAI configuration */
132 ret = cpu_dai->ops->set_fmt(cpu_dai,
133 SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
134 SND_SOC_DAIFMT_SYNC | fmt);
135 if (ret < 0) {
136 printk(KERN_ERR "Error from cpu DAI configuration\n");
137 return ret;
138 }
139
140 /* Put DC field of STCCR to 1 (not zero) */
141 ret = cpu_dai->ops->set_tdm_slot(cpu_dai, 0, 2);
142
143 /* set the SSI system clock as input */
144 ret = cpu_dai->ops->set_sysclk(cpu_dai, IMX_SSP_SYS_CLK, 0,
145 SND_SOC_CLOCK_IN);
146 if (ret < 0) {
147 printk(KERN_ERR "Error when setting system SSI clk\n");
148 return ret;
149 }
150
151 /* set codec BCLK division for sample rate */
152 ret = codec_dai->ops->set_clkdiv(codec_dai, WM8974_BCLKDIV, bclk);
153 if (ret < 0) {
154 printk(KERN_ERR "Error when setting BCLK division\n");
155 return ret;
156 }
157
158
159 /* codec PLL input is 25 MHz */
160 ret = codec_dai->ops->set_pll(codec_dai, IGNORED_ARG,
161 25000000, pll_out);
162 if (ret < 0) {
163 printk(KERN_ERR "Error when setting PLL input\n");
164 return ret;
165 }
166
167 /*set codec MCLK division for sample rate */
168 ret = codec_dai->ops->set_clkdiv(codec_dai, WM8974_MCLKDIV, mclk);
169 if (ret < 0) {
170 printk(KERN_ERR "Error when setting MCLK division\n");
171 return ret;
172 }
173
174 return 0;
175}
176
177static int mx27vis_hifi_hw_free(struct snd_pcm_substream *substream)
178{
179 struct snd_soc_pcm_runtime *rtd = substream->private_data;
180 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
181
182 /* disable the PLL */
183 return codec_dai->ops->set_pll(codec_dai, IGNORED_ARG, 0, 0);
184}
185
186/*
187 * mx27vis WM8974 HiFi DAI opserations.
188 */
189static struct snd_soc_ops mx27vis_hifi_ops = {
190 .hw_params = mx27vis_hifi_hw_params,
191 .hw_free = mx27vis_hifi_hw_free,
192};
193
194
195static int mx27vis_suspend(struct platform_device *pdev, pm_message_t state)
196{
197 return 0;
198}
199
200static int mx27vis_resume(struct platform_device *pdev)
201{
202 return 0;
203}
204
205static int mx27vis_probe(struct platform_device *pdev)
206{
207 int ret = 0;
208
209 ret = get_ssi_clk(0, &pdev->dev);
210
211 if (ret < 0) {
212 printk(KERN_ERR "%s: cant get ssi clock\n", __func__);
213 return ret;
214 }
215
216
217 return 0;
218}
219
220static int mx27vis_remove(struct platform_device *pdev)
221{
222 put_ssi_clk(0);
223 return 0;
224}
225
226static struct snd_soc_dai_link mx27vis_dai[] = {
227{ /* Hifi Playback*/
228 .name = "WM8974",
229 .stream_name = "WM8974 HiFi",
230 .cpu_dai = &imx_ssi_pcm_dai[0],
231 .codec_dai = &wm8974_dai,
232 .ops = &mx27vis_hifi_ops,
233},
234};
235
236static struct snd_soc_card mx27vis = {
237 .name = "mx27vis",
238 .platform = &mx1_mx2_soc_platform,
239 .probe = mx27vis_probe,
240 .remove = mx27vis_remove,
241 .suspend_pre = mx27vis_suspend,
242 .resume_post = mx27vis_resume,
243 .dai_link = mx27vis_dai,
244 .num_links = ARRAY_SIZE(mx27vis_dai),
245};
246
247static struct snd_soc_device mx27vis_snd_devdata = {
248 .card = &mx27vis,
249 .codec_dev = &soc_codec_dev_wm8974,
250};
251
252static struct platform_device *mx27vis_snd_device;
253
254/* Temporal definition of board specific behaviour */
255void gpio_ssi_active(int ssi_num)
256{
257 int ret = 0;
258
259 unsigned int ssi1_pins[] = {
260 PC20_PF_SSI1_FS,
261 PC21_PF_SSI1_RXD,
262 PC22_PF_SSI1_TXD,
263 PC23_PF_SSI1_CLK,
264 };
265 unsigned int ssi2_pins[] = {
266 PC24_PF_SSI2_FS,
267 PC25_PF_SSI2_RXD,
268 PC26_PF_SSI2_TXD,
269 PC27_PF_SSI2_CLK,
270 };
271 if (ssi_num == 0)
272 ret = mxc_gpio_setup_multiple_pins(ssi1_pins,
273 ARRAY_SIZE(ssi1_pins), "USB OTG");
274 else
275 ret = mxc_gpio_setup_multiple_pins(ssi2_pins,
276 ARRAY_SIZE(ssi2_pins), "USB OTG");
277 if (ret)
278 printk(KERN_ERR "Error requesting ssi %x pins\n", ssi_num);
279}
280
281
282static int __init mx27vis_init(void)
283{
284 int ret;
285
286 mx27vis_snd_device = platform_device_alloc("soc-audio", -1);
287 if (!mx27vis_snd_device)
288 return -ENOMEM;
289
290 platform_set_drvdata(mx27vis_snd_device, &mx27vis_snd_devdata);
291 mx27vis_snd_devdata.dev = &mx27vis_snd_device->dev;
292 ret = platform_device_add(mx27vis_snd_device);
293
294 if (ret) {
295 printk(KERN_ERR "ASoC: Platform device allocation failed\n");
296 platform_device_put(mx27vis_snd_device);
297 }
298
299 /* WM8974 uses SSI1 (HPCR1) via AUDMUX port 4 for audio (PPCR1) */
300 gpio_ssi_active(0);
301 audmux_connect_1_4();
302
303 return ret;
304}
305
306static void __exit mx27vis_exit(void)
307{
308 /* We should call some "ssi_gpio_inactive()" properly */
309}
310
311module_init(mx27vis_init);
312module_exit(mx27vis_exit);
313
314
315MODULE_AUTHOR("Javier Martin, javier.martin@vista-silicon.com");
316MODULE_DESCRIPTION("ALSA SoC WM8974 mx27vis");
317MODULE_LICENSE("GPL");
diff --git a/sound/soc/imx/mxc-ssi.c b/sound/soc/imx/mxc-ssi.c
deleted file mode 100644
index ccdefe60e752..000000000000
--- a/sound/soc/imx/mxc-ssi.c
+++ /dev/null
@@ -1,860 +0,0 @@
1/*
2 * mxc-ssi.c -- SSI driver for Freescale IMX
3 *
4 * Copyright 2006 Wolfson Microelectronics PLC.
5 * Author: Liam Girdwood
6 * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
7 *
8 * Based on mxc-alsa-mc13783 (C) 2006 Freescale.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 *
15 * TODO:
16 * Need to rework SSI register defs when new defs go into mainline.
17 * Add support for TDM and FIFO 1.
18 * Add support for i.mx3x DMA interface.
19 *
20 */
21
22
23#include <linux/module.h>
24#include <linux/init.h>
25#include <linux/platform_device.h>
26#include <linux/slab.h>
27#include <linux/dma-mapping.h>
28#include <linux/clk.h>
29#include <sound/core.h>
30#include <sound/pcm.h>
31#include <sound/pcm_params.h>
32#include <sound/soc.h>
33#include <mach/dma-mx1-mx2.h>
34#include <asm/mach-types.h>
35
36#include "mxc-ssi.h"
37#include "mx1_mx2-pcm.h"
38
39#define SSI1_PORT 0
40#define SSI2_PORT 1
41
42static int ssi_active[2] = {0, 0};
43
44/* DMA information for mx1_mx2 platforms */
45static struct mx1_mx2_pcm_dma_params imx_ssi1_pcm_stereo_out0 = {
46 .name = "SSI1 PCM Stereo out 0",
47 .transfer_type = DMA_MODE_WRITE,
48 .per_address = SSI1_BASE_ADDR + STX0,
49 .event_id = DMA_REQ_SSI1_TX0,
50 .watermark_level = TXFIFO_WATERMARK,
51 .per_config = IMX_DMA_MEMSIZE_16 | IMX_DMA_TYPE_FIFO,
52 .mem_config = IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR,
53};
54
55static struct mx1_mx2_pcm_dma_params imx_ssi1_pcm_stereo_out1 = {
56 .name = "SSI1 PCM Stereo out 1",
57 .transfer_type = DMA_MODE_WRITE,
58 .per_address = SSI1_BASE_ADDR + STX1,
59 .event_id = DMA_REQ_SSI1_TX1,
60 .watermark_level = TXFIFO_WATERMARK,
61 .per_config = IMX_DMA_MEMSIZE_16 | IMX_DMA_TYPE_FIFO,
62 .mem_config = IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR,
63};
64
65static struct mx1_mx2_pcm_dma_params imx_ssi1_pcm_stereo_in0 = {
66 .name = "SSI1 PCM Stereo in 0",
67 .transfer_type = DMA_MODE_READ,
68 .per_address = SSI1_BASE_ADDR + SRX0,
69 .event_id = DMA_REQ_SSI1_RX0,
70 .watermark_level = RXFIFO_WATERMARK,
71 .per_config = IMX_DMA_MEMSIZE_16 | IMX_DMA_TYPE_FIFO,
72 .mem_config = IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR,
73};
74
75static struct mx1_mx2_pcm_dma_params imx_ssi1_pcm_stereo_in1 = {
76 .name = "SSI1 PCM Stereo in 1",
77 .transfer_type = DMA_MODE_READ,
78 .per_address = SSI1_BASE_ADDR + SRX1,
79 .event_id = DMA_REQ_SSI1_RX1,
80 .watermark_level = RXFIFO_WATERMARK,
81 .per_config = IMX_DMA_MEMSIZE_16 | IMX_DMA_TYPE_FIFO,
82 .mem_config = IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR,
83};
84
85static struct mx1_mx2_pcm_dma_params imx_ssi2_pcm_stereo_out0 = {
86 .name = "SSI2 PCM Stereo out 0",
87 .transfer_type = DMA_MODE_WRITE,
88 .per_address = SSI2_BASE_ADDR + STX0,
89 .event_id = DMA_REQ_SSI2_TX0,
90 .watermark_level = TXFIFO_WATERMARK,
91 .per_config = IMX_DMA_MEMSIZE_16 | IMX_DMA_TYPE_FIFO,
92 .mem_config = IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR,
93};
94
95static struct mx1_mx2_pcm_dma_params imx_ssi2_pcm_stereo_out1 = {
96 .name = "SSI2 PCM Stereo out 1",
97 .transfer_type = DMA_MODE_WRITE,
98 .per_address = SSI2_BASE_ADDR + STX1,
99 .event_id = DMA_REQ_SSI2_TX1,
100 .watermark_level = TXFIFO_WATERMARK,
101 .per_config = IMX_DMA_MEMSIZE_16 | IMX_DMA_TYPE_FIFO,
102 .mem_config = IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR,
103};
104
105static struct mx1_mx2_pcm_dma_params imx_ssi2_pcm_stereo_in0 = {
106 .name = "SSI2 PCM Stereo in 0",
107 .transfer_type = DMA_MODE_READ,
108 .per_address = SSI2_BASE_ADDR + SRX0,
109 .event_id = DMA_REQ_SSI2_RX0,
110 .watermark_level = RXFIFO_WATERMARK,
111 .per_config = IMX_DMA_MEMSIZE_16 | IMX_DMA_TYPE_FIFO,
112 .mem_config = IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR,
113};
114
115static struct mx1_mx2_pcm_dma_params imx_ssi2_pcm_stereo_in1 = {
116 .name = "SSI2 PCM Stereo in 1",
117 .transfer_type = DMA_MODE_READ,
118 .per_address = SSI2_BASE_ADDR + SRX1,
119 .event_id = DMA_REQ_SSI2_RX1,
120 .watermark_level = RXFIFO_WATERMARK,
121 .per_config = IMX_DMA_MEMSIZE_16 | IMX_DMA_TYPE_FIFO,
122 .mem_config = IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR,
123};
124
125static struct clk *ssi_clk0, *ssi_clk1;
126
127int get_ssi_clk(int ssi, struct device *dev)
128{
129 switch (ssi) {
130 case 0:
131 ssi_clk0 = clk_get(dev, "ssi1");
132 if (IS_ERR(ssi_clk0))
133 return PTR_ERR(ssi_clk0);
134 return 0;
135 case 1:
136 ssi_clk1 = clk_get(dev, "ssi2");
137 if (IS_ERR(ssi_clk1))
138 return PTR_ERR(ssi_clk1);
139 return 0;
140 default:
141 return -EINVAL;
142 }
143}
144EXPORT_SYMBOL(get_ssi_clk);
145
146void put_ssi_clk(int ssi)
147{
148 switch (ssi) {
149 case 0:
150 clk_put(ssi_clk0);
151 ssi_clk0 = NULL;
152 break;
153 case 1:
154 clk_put(ssi_clk1);
155 ssi_clk1 = NULL;
156 break;
157 }
158}
159EXPORT_SYMBOL(put_ssi_clk);
160
161/*
162 * SSI system clock configuration.
163 * Should only be called when port is inactive (i.e. SSIEN = 0).
164 */
165static int imx_ssi_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
166 int clk_id, unsigned int freq, int dir)
167{
168 u32 scr;
169
170 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
171 scr = SSI1_SCR;
172 pr_debug("%s: SCR for SSI1 is %x\n", __func__, scr);
173 } else {
174 scr = SSI2_SCR;
175 pr_debug("%s: SCR for SSI2 is %x\n", __func__, scr);
176 }
177
178 if (scr & SSI_SCR_SSIEN) {
179 printk(KERN_WARNING "Warning ssi already enabled\n");
180 return 0;
181 }
182
183 switch (clk_id) {
184 case IMX_SSP_SYS_CLK:
185 if (dir == SND_SOC_CLOCK_OUT) {
186 scr |= SSI_SCR_SYS_CLK_EN;
187 pr_debug("%s: clk of is output\n", __func__);
188 } else {
189 scr &= ~SSI_SCR_SYS_CLK_EN;
190 pr_debug("%s: clk of is input\n", __func__);
191 }
192 break;
193 default:
194 return -EINVAL;
195 }
196
197 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
198 pr_debug("%s: writeback of SSI1_SCR\n", __func__);
199 SSI1_SCR = scr;
200 } else {
201 pr_debug("%s: writeback of SSI2_SCR\n", __func__);
202 SSI2_SCR = scr;
203 }
204
205 return 0;
206}
207
208/*
209 * SSI Clock dividers
210 * Should only be called when port is inactive (i.e. SSIEN = 0).
211 */
212static int imx_ssi_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
213 int div_id, int div)
214{
215 u32 stccr, srccr;
216
217 pr_debug("%s\n", __func__);
218 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
219 if (SSI1_SCR & SSI_SCR_SSIEN)
220 return 0;
221 srccr = SSI1_STCCR;
222 stccr = SSI1_STCCR;
223 } else {
224 if (SSI2_SCR & SSI_SCR_SSIEN)
225 return 0;
226 srccr = SSI2_STCCR;
227 stccr = SSI2_STCCR;
228 }
229
230 switch (div_id) {
231 case IMX_SSI_TX_DIV_2:
232 stccr &= ~SSI_STCCR_DIV2;
233 stccr |= div;
234 break;
235 case IMX_SSI_TX_DIV_PSR:
236 stccr &= ~SSI_STCCR_PSR;
237 stccr |= div;
238 break;
239 case IMX_SSI_TX_DIV_PM:
240 stccr &= ~0xff;
241 stccr |= SSI_STCCR_PM(div);
242 break;
243 case IMX_SSI_RX_DIV_2:
244 stccr &= ~SSI_STCCR_DIV2;
245 stccr |= div;
246 break;
247 case IMX_SSI_RX_DIV_PSR:
248 stccr &= ~SSI_STCCR_PSR;
249 stccr |= div;
250 break;
251 case IMX_SSI_RX_DIV_PM:
252 stccr &= ~0xff;
253 stccr |= SSI_STCCR_PM(div);
254 break;
255 default:
256 return -EINVAL;
257 }
258
259 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
260 SSI1_STCCR = stccr;
261 SSI1_SRCCR = srccr;
262 } else {
263 SSI2_STCCR = stccr;
264 SSI2_SRCCR = srccr;
265 }
266 return 0;
267}
268
269/*
270 * SSI Network Mode or TDM slots configuration.
271 * Should only be called when port is inactive (i.e. SSIEN = 0).
272 */
273static int imx_ssi_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai,
274 unsigned int mask, int slots)
275{
276 u32 stmsk, srmsk, stccr;
277
278 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
279 if (SSI1_SCR & SSI_SCR_SSIEN) {
280 printk(KERN_WARNING "Warning ssi already enabled\n");
281 return 0;
282 }
283 stccr = SSI1_STCCR;
284 } else {
285 if (SSI2_SCR & SSI_SCR_SSIEN) {
286 printk(KERN_WARNING "Warning ssi already enabled\n");
287 return 0;
288 }
289 stccr = SSI2_STCCR;
290 }
291
292 stmsk = srmsk = mask;
293 stccr &= ~SSI_STCCR_DC_MASK;
294 stccr |= SSI_STCCR_DC(slots - 1);
295
296 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
297 SSI1_STMSK = stmsk;
298 SSI1_SRMSK = srmsk;
299 SSI1_SRCCR = SSI1_STCCR = stccr;
300 } else {
301 SSI2_STMSK = stmsk;
302 SSI2_SRMSK = srmsk;
303 SSI2_SRCCR = SSI2_STCCR = stccr;
304 }
305
306 return 0;
307}
308
309/*
310 * SSI DAI format configuration.
311 * Should only be called when port is inactive (i.e. SSIEN = 0).
312 * Note: We don't use the I2S modes but instead manually configure the
313 * SSI for I2S.
314 */
315static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai,
316 unsigned int fmt)
317{
318 u32 stcr = 0, srcr = 0, scr;
319
320 /*
321 * This is done to avoid this function to modify
322 * previous set values in stcr
323 */
324 stcr = SSI1_STCR;
325
326 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2)
327 scr = SSI1_SCR & ~(SSI_SCR_SYN | SSI_SCR_NET);
328 else
329 scr = SSI2_SCR & ~(SSI_SCR_SYN | SSI_SCR_NET);
330
331 if (scr & SSI_SCR_SSIEN) {
332 printk(KERN_WARNING "Warning ssi already enabled\n");
333 return 0;
334 }
335
336 /* DAI mode */
337 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
338 case SND_SOC_DAIFMT_I2S:
339 /* data on rising edge of bclk, frame low 1clk before data */
340 stcr |= SSI_STCR_TFSI | SSI_STCR_TEFS | SSI_STCR_TXBIT0;
341 srcr |= SSI_SRCR_RFSI | SSI_SRCR_REFS | SSI_SRCR_RXBIT0;
342 break;
343 case SND_SOC_DAIFMT_LEFT_J:
344 /* data on rising edge of bclk, frame high with data */
345 stcr |= SSI_STCR_TXBIT0;
346 srcr |= SSI_SRCR_RXBIT0;
347 break;
348 case SND_SOC_DAIFMT_DSP_B:
349 /* data on rising edge of bclk, frame high with data */
350 stcr |= SSI_STCR_TFSL;
351 srcr |= SSI_SRCR_RFSL;
352 break;
353 case SND_SOC_DAIFMT_DSP_A:
354 /* data on rising edge of bclk, frame high 1clk before data */
355 stcr |= SSI_STCR_TFSL | SSI_STCR_TEFS;
356 srcr |= SSI_SRCR_RFSL | SSI_SRCR_REFS;
357 break;
358 }
359
360 /* DAI clock inversion */
361 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
362 case SND_SOC_DAIFMT_IB_IF:
363 stcr |= SSI_STCR_TFSI;
364 stcr &= ~SSI_STCR_TSCKP;
365 srcr |= SSI_SRCR_RFSI;
366 srcr &= ~SSI_SRCR_RSCKP;
367 break;
368 case SND_SOC_DAIFMT_IB_NF:
369 stcr &= ~(SSI_STCR_TSCKP | SSI_STCR_TFSI);
370 srcr &= ~(SSI_SRCR_RSCKP | SSI_SRCR_RFSI);
371 break;
372 case SND_SOC_DAIFMT_NB_IF:
373 stcr |= SSI_STCR_TFSI | SSI_STCR_TSCKP;
374 srcr |= SSI_SRCR_RFSI | SSI_SRCR_RSCKP;
375 break;
376 case SND_SOC_DAIFMT_NB_NF:
377 stcr &= ~SSI_STCR_TFSI;
378 stcr |= SSI_STCR_TSCKP;
379 srcr &= ~SSI_SRCR_RFSI;
380 srcr |= SSI_SRCR_RSCKP;
381 break;
382 }
383
384 /* DAI clock master masks */
385 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
386 case SND_SOC_DAIFMT_CBS_CFS:
387 stcr |= SSI_STCR_TFDIR | SSI_STCR_TXDIR;
388 srcr |= SSI_SRCR_RFDIR | SSI_SRCR_RXDIR;
389 break;
390 case SND_SOC_DAIFMT_CBM_CFS:
391 stcr |= SSI_STCR_TFDIR;
392 srcr |= SSI_SRCR_RFDIR;
393 break;
394 case SND_SOC_DAIFMT_CBS_CFM:
395 stcr |= SSI_STCR_TXDIR;
396 srcr |= SSI_SRCR_RXDIR;
397 break;
398 }
399
400 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
401 SSI1_STCR = stcr;
402 SSI1_SRCR = srcr;
403 SSI1_SCR = scr;
404 } else {
405 SSI2_STCR = stcr;
406 SSI2_SRCR = srcr;
407 SSI2_SCR = scr;
408 }
409
410 return 0;
411}
412
413static int imx_ssi_startup(struct snd_pcm_substream *substream,
414 struct snd_soc_dai *dai)
415{
416 struct snd_soc_pcm_runtime *rtd = substream->private_data;
417 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
418
419 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
420 /* set up TX DMA params */
421 switch (cpu_dai->id) {
422 case IMX_DAI_SSI0:
423 cpu_dai->dma_data = &imx_ssi1_pcm_stereo_out0;
424 break;
425 case IMX_DAI_SSI1:
426 cpu_dai->dma_data = &imx_ssi1_pcm_stereo_out1;
427 break;
428 case IMX_DAI_SSI2:
429 cpu_dai->dma_data = &imx_ssi2_pcm_stereo_out0;
430 break;
431 case IMX_DAI_SSI3:
432 cpu_dai->dma_data = &imx_ssi2_pcm_stereo_out1;
433 }
434 pr_debug("%s: (playback)\n", __func__);
435 } else {
436 /* set up RX DMA params */
437 switch (cpu_dai->id) {
438 case IMX_DAI_SSI0:
439 cpu_dai->dma_data = &imx_ssi1_pcm_stereo_in0;
440 break;
441 case IMX_DAI_SSI1:
442 cpu_dai->dma_data = &imx_ssi1_pcm_stereo_in1;
443 break;
444 case IMX_DAI_SSI2:
445 cpu_dai->dma_data = &imx_ssi2_pcm_stereo_in0;
446 break;
447 case IMX_DAI_SSI3:
448 cpu_dai->dma_data = &imx_ssi2_pcm_stereo_in1;
449 }
450 pr_debug("%s: (capture)\n", __func__);
451 }
452
453 /*
454 * we cant really change any SSI values after SSI is enabled
455 * need to fix in software for max flexibility - lrg
456 */
457 if (cpu_dai->active) {
458 printk(KERN_WARNING "Warning ssi already enabled\n");
459 return 0;
460 }
461
462 /* reset the SSI port - Sect 45.4.4 */
463 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
464
465 if (!ssi_clk0)
466 return -EINVAL;
467
468 if (ssi_active[SSI1_PORT]++) {
469 pr_debug("%s: exit before reset\n", __func__);
470 return 0;
471 }
472
473 /* SSI1 Reset */
474 SSI1_SCR = 0;
475
476 SSI1_SFCSR = SSI_SFCSR_RFWM1(RXFIFO_WATERMARK) |
477 SSI_SFCSR_RFWM0(RXFIFO_WATERMARK) |
478 SSI_SFCSR_TFWM1(TXFIFO_WATERMARK) |
479 SSI_SFCSR_TFWM0(TXFIFO_WATERMARK);
480 } else {
481
482 if (!ssi_clk1)
483 return -EINVAL;
484
485 if (ssi_active[SSI2_PORT]++) {
486 pr_debug("%s: exit before reset\n", __func__);
487 return 0;
488 }
489
490 /* SSI2 Reset */
491 SSI2_SCR = 0;
492
493 SSI2_SFCSR = SSI_SFCSR_RFWM1(RXFIFO_WATERMARK) |
494 SSI_SFCSR_RFWM0(RXFIFO_WATERMARK) |
495 SSI_SFCSR_TFWM1(TXFIFO_WATERMARK) |
496 SSI_SFCSR_TFWM0(TXFIFO_WATERMARK);
497 }
498
499 return 0;
500}
501
502int imx_ssi_hw_tx_params(struct snd_pcm_substream *substream,
503 struct snd_pcm_hw_params *params)
504{
505 struct snd_soc_pcm_runtime *rtd = substream->private_data;
506 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
507 u32 stccr, stcr, sier;
508
509 pr_debug("%s\n", __func__);
510
511 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
512 stccr = SSI1_STCCR & ~SSI_STCCR_WL_MASK;
513 stcr = SSI1_STCR;
514 sier = SSI1_SIER;
515 } else {
516 stccr = SSI2_STCCR & ~SSI_STCCR_WL_MASK;
517 stcr = SSI2_STCR;
518 sier = SSI2_SIER;
519 }
520
521 /* DAI data (word) size */
522 switch (params_format(params)) {
523 case SNDRV_PCM_FORMAT_S16_LE:
524 stccr |= SSI_STCCR_WL(16);
525 break;
526 case SNDRV_PCM_FORMAT_S20_3LE:
527 stccr |= SSI_STCCR_WL(20);
528 break;
529 case SNDRV_PCM_FORMAT_S24_LE:
530 stccr |= SSI_STCCR_WL(24);
531 break;
532 }
533
534 /* enable interrupts */
535 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2)
536 stcr |= SSI_STCR_TFEN0;
537 else
538 stcr |= SSI_STCR_TFEN1;
539 sier |= SSI_SIER_TDMAE;
540
541 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
542 SSI1_STCR = stcr;
543 SSI1_STCCR = stccr;
544 SSI1_SIER = sier;
545 } else {
546 SSI2_STCR = stcr;
547 SSI2_STCCR = stccr;
548 SSI2_SIER = sier;
549 }
550
551 return 0;
552}
553
554int imx_ssi_hw_rx_params(struct snd_pcm_substream *substream,
555 struct snd_pcm_hw_params *params)
556{
557 struct snd_soc_pcm_runtime *rtd = substream->private_data;
558 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
559 u32 srccr, srcr, sier;
560
561 pr_debug("%s\n", __func__);
562
563 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
564 srccr = SSI1_SRCCR & ~SSI_SRCCR_WL_MASK;
565 srcr = SSI1_SRCR;
566 sier = SSI1_SIER;
567 } else {
568 srccr = SSI2_SRCCR & ~SSI_SRCCR_WL_MASK;
569 srcr = SSI2_SRCR;
570 sier = SSI2_SIER;
571 }
572
573 /* DAI data (word) size */
574 switch (params_format(params)) {
575 case SNDRV_PCM_FORMAT_S16_LE:
576 srccr |= SSI_SRCCR_WL(16);
577 break;
578 case SNDRV_PCM_FORMAT_S20_3LE:
579 srccr |= SSI_SRCCR_WL(20);
580 break;
581 case SNDRV_PCM_FORMAT_S24_LE:
582 srccr |= SSI_SRCCR_WL(24);
583 break;
584 }
585
586 /* enable interrupts */
587 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2)
588 srcr |= SSI_SRCR_RFEN0;
589 else
590 srcr |= SSI_SRCR_RFEN1;
591 sier |= SSI_SIER_RDMAE;
592
593 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
594 SSI1_SRCR = srcr;
595 SSI1_SRCCR = srccr;
596 SSI1_SIER = sier;
597 } else {
598 SSI2_SRCR = srcr;
599 SSI2_SRCCR = srccr;
600 SSI2_SIER = sier;
601 }
602
603 return 0;
604}
605
606/*
607 * Should only be called when port is inactive (i.e. SSIEN = 0),
608 * although can be called multiple times by upper layers.
609 */
610int imx_ssi_hw_params(struct snd_pcm_substream *substream,
611 struct snd_pcm_hw_params *params,
612 struct snd_soc_dai *dai)
613{
614 struct snd_soc_pcm_runtime *rtd = substream->private_data;
615 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
616
617 int ret;
618
619 /* cant change any parameters when SSI is running */
620 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
621 if (SSI1_SCR & SSI_SCR_SSIEN) {
622 printk(KERN_WARNING "Warning ssi already enabled\n");
623 return 0;
624 }
625 } else {
626 if (SSI2_SCR & SSI_SCR_SSIEN) {
627 printk(KERN_WARNING "Warning ssi already enabled\n");
628 return 0;
629 }
630 }
631
632 /*
633 * Configure both tx and rx params with the same settings. This is
634 * really a harware restriction because SSI must be disabled until
635 * we can change those values. If there is an active audio stream in
636 * one direction, enabling the other direction with different
637 * settings would mean disturbing the running one.
638 */
639 ret = imx_ssi_hw_tx_params(substream, params);
640 if (ret < 0)
641 return ret;
642 return imx_ssi_hw_rx_params(substream, params);
643}
644
645int imx_ssi_prepare(struct snd_pcm_substream *substream,
646 struct snd_soc_dai *dai)
647{
648 struct snd_soc_pcm_runtime *rtd = substream->private_data;
649 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
650 int ret;
651
652 pr_debug("%s\n", __func__);
653
654 /* Enable clks here to follow SSI recommended init sequence */
655 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
656 ret = clk_enable(ssi_clk0);
657 if (ret < 0)
658 printk(KERN_ERR "Unable to enable ssi_clk0\n");
659 } else {
660 ret = clk_enable(ssi_clk1);
661 if (ret < 0)
662 printk(KERN_ERR "Unable to enable ssi_clk1\n");
663 }
664
665 return 0;
666}
667
668static int imx_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
669 struct snd_soc_dai *dai)
670{
671 struct snd_soc_pcm_runtime *rtd = substream->private_data;
672 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
673 u32 scr;
674
675 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2)
676 scr = SSI1_SCR;
677 else
678 scr = SSI2_SCR;
679
680 switch (cmd) {
681 case SNDRV_PCM_TRIGGER_START:
682 case SNDRV_PCM_TRIGGER_RESUME:
683 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
684 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
685 scr |= SSI_SCR_TE | SSI_SCR_SSIEN;
686 else
687 scr |= SSI_SCR_RE | SSI_SCR_SSIEN;
688 break;
689 case SNDRV_PCM_TRIGGER_SUSPEND:
690 case SNDRV_PCM_TRIGGER_STOP:
691 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
692 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
693 scr &= ~SSI_SCR_TE;
694 else
695 scr &= ~SSI_SCR_RE;
696 break;
697 default:
698 return -EINVAL;
699 }
700
701 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2)
702 SSI1_SCR = scr;
703 else
704 SSI2_SCR = scr;
705
706 return 0;
707}
708
709static void imx_ssi_shutdown(struct snd_pcm_substream *substream,
710 struct snd_soc_dai *dai)
711{
712 struct snd_soc_pcm_runtime *rtd = substream->private_data;
713 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
714
715 /* shutdown SSI if neither Tx or Rx is active */
716 if (!cpu_dai->active) {
717
718 if (cpu_dai->id == IMX_DAI_SSI0 ||
719 cpu_dai->id == IMX_DAI_SSI2) {
720
721 if (--ssi_active[SSI1_PORT] > 1)
722 return;
723
724 SSI1_SCR = 0;
725 clk_disable(ssi_clk0);
726 } else {
727 if (--ssi_active[SSI2_PORT])
728 return;
729 SSI2_SCR = 0;
730 clk_disable(ssi_clk1);
731 }
732 }
733}
734
735#ifdef CONFIG_PM
736static int imx_ssi_suspend(struct platform_device *dev,
737 struct snd_soc_dai *dai)
738{
739 return 0;
740}
741
742static int imx_ssi_resume(struct platform_device *pdev,
743 struct snd_soc_dai *dai)
744{
745 return 0;
746}
747
748#else
749#define imx_ssi_suspend NULL
750#define imx_ssi_resume NULL
751#endif
752
753#define IMX_SSI_RATES \
754 (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | \
755 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \
756 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
757 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | \
758 SNDRV_PCM_RATE_96000)
759
760#define IMX_SSI_BITS \
761 (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
762 SNDRV_PCM_FMTBIT_S24_LE)
763
764static struct snd_soc_dai_ops imx_ssi_pcm_dai_ops = {
765 .startup = imx_ssi_startup,
766 .shutdown = imx_ssi_shutdown,
767 .trigger = imx_ssi_trigger,
768 .prepare = imx_ssi_prepare,
769 .hw_params = imx_ssi_hw_params,
770 .set_sysclk = imx_ssi_set_dai_sysclk,
771 .set_clkdiv = imx_ssi_set_dai_clkdiv,
772 .set_fmt = imx_ssi_set_dai_fmt,
773 .set_tdm_slot = imx_ssi_set_dai_tdm_slot,
774};
775
776struct snd_soc_dai imx_ssi_pcm_dai[] = {
777{
778 .name = "imx-i2s-1-0",
779 .id = IMX_DAI_SSI0,
780 .suspend = imx_ssi_suspend,
781 .resume = imx_ssi_resume,
782 .playback = {
783 .channels_min = 1,
784 .channels_max = 2,
785 .formats = IMX_SSI_BITS,
786 .rates = IMX_SSI_RATES,},
787 .capture = {
788 .channels_min = 1,
789 .channels_max = 2,
790 .formats = IMX_SSI_BITS,
791 .rates = IMX_SSI_RATES,},
792 .ops = &imx_ssi_pcm_dai_ops,
793},
794{
795 .name = "imx-i2s-2-0",
796 .id = IMX_DAI_SSI1,
797 .playback = {
798 .channels_min = 1,
799 .channels_max = 2,
800 .formats = IMX_SSI_BITS,
801 .rates = IMX_SSI_RATES,},
802 .capture = {
803 .channels_min = 1,
804 .channels_max = 2,
805 .formats = IMX_SSI_BITS,
806 .rates = IMX_SSI_RATES,},
807 .ops = &imx_ssi_pcm_dai_ops,
808},
809{
810 .name = "imx-i2s-1-1",
811 .id = IMX_DAI_SSI2,
812 .suspend = imx_ssi_suspend,
813 .resume = imx_ssi_resume,
814 .playback = {
815 .channels_min = 1,
816 .channels_max = 2,
817 .formats = IMX_SSI_BITS,
818 .rates = IMX_SSI_RATES,},
819 .capture = {
820 .channels_min = 1,
821 .channels_max = 2,
822 .formats = IMX_SSI_BITS,
823 .rates = IMX_SSI_RATES,},
824 .ops = &imx_ssi_pcm_dai_ops,
825},
826{
827 .name = "imx-i2s-2-1",
828 .id = IMX_DAI_SSI3,
829 .playback = {
830 .channels_min = 1,
831 .channels_max = 2,
832 .formats = IMX_SSI_BITS,
833 .rates = IMX_SSI_RATES,},
834 .capture = {
835 .channels_min = 1,
836 .channels_max = 2,
837 .formats = IMX_SSI_BITS,
838 .rates = IMX_SSI_RATES,},
839 .ops = &imx_ssi_pcm_dai_ops,
840},
841};
842EXPORT_SYMBOL_GPL(imx_ssi_pcm_dai);
843
844static int __init imx_ssi_init(void)
845{
846 return snd_soc_register_dais(imx_ssi_pcm_dai,
847 ARRAY_SIZE(imx_ssi_pcm_dai));
848}
849
850static void __exit imx_ssi_exit(void)
851{
852 snd_soc_unregister_dais(imx_ssi_pcm_dai,
853 ARRAY_SIZE(imx_ssi_pcm_dai));
854}
855
856module_init(imx_ssi_init);
857module_exit(imx_ssi_exit);
858MODULE_AUTHOR("Liam Girdwood, liam.girdwood@wolfsonmicro.com");
859MODULE_DESCRIPTION("i.MX ASoC I2S driver");
860MODULE_LICENSE("GPL");
diff --git a/sound/soc/imx/mxc-ssi.h b/sound/soc/imx/mxc-ssi.h
deleted file mode 100644
index 12bbdc9c7ecd..000000000000
--- a/sound/soc/imx/mxc-ssi.h
+++ /dev/null
@@ -1,238 +0,0 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License version 2 as
4 * published by the Free Software Foundation.
5 */
6
7#ifndef _IMX_SSI_H
8#define _IMX_SSI_H
9
10#include <mach/hardware.h>
11
12/* SSI regs definition - MOVE to /arch/arm/plat-mxc/include/mach/ when stable */
13#define SSI1_IO_BASE_ADDR IO_ADDRESS(SSI1_BASE_ADDR)
14#define SSI2_IO_BASE_ADDR IO_ADDRESS(SSI2_BASE_ADDR)
15
16#define STX0 0x00
17#define STX1 0x04
18#define SRX0 0x08
19#define SRX1 0x0c
20#define SCR 0x10
21#define SISR 0x14
22#define SIER 0x18
23#define STCR 0x1c
24#define SRCR 0x20
25#define STCCR 0x24
26#define SRCCR 0x28
27#define SFCSR 0x2c
28#define STR 0x30
29#define SOR 0x34
30#define SACNT 0x38
31#define SACADD 0x3c
32#define SACDAT 0x40
33#define SATAG 0x44
34#define STMSK 0x48
35#define SRMSK 0x4c
36
37#define SSI1_STX0 (*((volatile u32 *)(SSI1_IO_BASE_ADDR + STX0)))
38#define SSI1_STX1 (*((volatile u32 *)(SSI1_IO_BASE_ADDR + STX1)))
39#define SSI1_SRX0 (*((volatile u32 *)(SSI1_IO_BASE_ADDR + SRX0)))
40#define SSI1_SRX1 (*((volatile u32 *)(SSI1_IO_BASE_ADDR + SRX1)))
41#define SSI1_SCR (*((volatile u32 *)(SSI1_IO_BASE_ADDR + SCR)))
42#define SSI1_SISR (*((volatile u32 *)(SSI1_IO_BASE_ADDR + SISR)))
43#define SSI1_SIER (*((volatile u32 *)(SSI1_IO_BASE_ADDR + SIER)))
44#define SSI1_STCR (*((volatile u32 *)(SSI1_IO_BASE_ADDR + STCR)))
45#define SSI1_SRCR (*((volatile u32 *)(SSI1_IO_BASE_ADDR + SRCR)))
46#define SSI1_STCCR (*((volatile u32 *)(SSI1_IO_BASE_ADDR + STCCR)))
47#define SSI1_SRCCR (*((volatile u32 *)(SSI1_IO_BASE_ADDR + SRCCR)))
48#define SSI1_SFCSR (*((volatile u32 *)(SSI1_IO_BASE_ADDR + SFCSR)))
49#define SSI1_STR (*((volatile u32 *)(SSI1_IO_BASE_ADDR + STR)))
50#define SSI1_SOR (*((volatile u32 *)(SSI1_IO_BASE_ADDR + SOR)))
51#define SSI1_SACNT (*((volatile u32 *)(SSI1_IO_BASE_ADDR + SACNT)))
52#define SSI1_SACADD (*((volatile u32 *)(SSI1_IO_BASE_ADDR + SACADD)))
53#define SSI1_SACDAT (*((volatile u32 *)(SSI1_IO_BASE_ADDR + SACDAT)))
54#define SSI1_SATAG (*((volatile u32 *)(SSI1_IO_BASE_ADDR + SATAG)))
55#define SSI1_STMSK (*((volatile u32 *)(SSI1_IO_BASE_ADDR + STMSK)))
56#define SSI1_SRMSK (*((volatile u32 *)(SSI1_IO_BASE_ADDR + SRMSK)))
57
58
59#define SSI2_STX0 (*((volatile u32 *)(SSI2_IO_BASE_ADDR + STX0)))
60#define SSI2_STX1 (*((volatile u32 *)(SSI2_IO_BASE_ADDR + STX1)))
61#define SSI2_SRX0 (*((volatile u32 *)(SSI2_IO_BASE_ADDR + SRX0)))
62#define SSI2_SRX1 (*((volatile u32 *)(SSI2_IO_BASE_ADDR + SRX1)))
63#define SSI2_SCR (*((volatile u32 *)(SSI2_IO_BASE_ADDR + SCR)))
64#define SSI2_SISR (*((volatile u32 *)(SSI2_IO_BASE_ADDR + SISR)))
65#define SSI2_SIER (*((volatile u32 *)(SSI2_IO_BASE_ADDR + SIER)))
66#define SSI2_STCR (*((volatile u32 *)(SSI2_IO_BASE_ADDR + STCR)))
67#define SSI2_SRCR (*((volatile u32 *)(SSI2_IO_BASE_ADDR + SRCR)))
68#define SSI2_STCCR (*((volatile u32 *)(SSI2_IO_BASE_ADDR + STCCR)))
69#define SSI2_SRCCR (*((volatile u32 *)(SSI2_IO_BASE_ADDR + SRCCR)))
70#define SSI2_SFCSR (*((volatile u32 *)(SSI2_IO_BASE_ADDR + SFCSR)))
71#define SSI2_STR (*((volatile u32 *)(SSI2_IO_BASE_ADDR + STR)))
72#define SSI2_SOR (*((volatile u32 *)(SSI2_IO_BASE_ADDR + SOR)))
73#define SSI2_SACNT (*((volatile u32 *)(SSI2_IO_BASE_ADDR + SACNT)))
74#define SSI2_SACADD (*((volatile u32 *)(SSI2_IO_BASE_ADDR + SACADD)))
75#define SSI2_SACDAT (*((volatile u32 *)(SSI2_IO_BASE_ADDR + SACDAT)))
76#define SSI2_SATAG (*((volatile u32 *)(SSI2_IO_BASE_ADDR + SATAG)))
77#define SSI2_STMSK (*((volatile u32 *)(SSI2_IO_BASE_ADDR + STMSK)))
78#define SSI2_SRMSK (*((volatile u32 *)(SSI2_IO_BASE_ADDR + SRMSK)))
79
80#define SSI_SCR_CLK_IST (1 << 9)
81#define SSI_SCR_TCH_EN (1 << 8)
82#define SSI_SCR_SYS_CLK_EN (1 << 7)
83#define SSI_SCR_I2S_MODE_NORM (0 << 5)
84#define SSI_SCR_I2S_MODE_MSTR (1 << 5)
85#define SSI_SCR_I2S_MODE_SLAVE (2 << 5)
86#define SSI_SCR_SYN (1 << 4)
87#define SSI_SCR_NET (1 << 3)
88#define SSI_SCR_RE (1 << 2)
89#define SSI_SCR_TE (1 << 1)
90#define SSI_SCR_SSIEN (1 << 0)
91
92#define SSI_SISR_CMDAU (1 << 18)
93#define SSI_SISR_CMDDU (1 << 17)
94#define SSI_SISR_RXT (1 << 16)
95#define SSI_SISR_RDR1 (1 << 15)
96#define SSI_SISR_RDR0 (1 << 14)
97#define SSI_SISR_TDE1 (1 << 13)
98#define SSI_SISR_TDE0 (1 << 12)
99#define SSI_SISR_ROE1 (1 << 11)
100#define SSI_SISR_ROE0 (1 << 10)
101#define SSI_SISR_TUE1 (1 << 9)
102#define SSI_SISR_TUE0 (1 << 8)
103#define SSI_SISR_TFS (1 << 7)
104#define SSI_SISR_RFS (1 << 6)
105#define SSI_SISR_TLS (1 << 5)
106#define SSI_SISR_RLS (1 << 4)
107#define SSI_SISR_RFF1 (1 << 3)
108#define SSI_SISR_RFF0 (1 << 2)
109#define SSI_SISR_TFE1 (1 << 1)
110#define SSI_SISR_TFE0 (1 << 0)
111
112#define SSI_SIER_RDMAE (1 << 22)
113#define SSI_SIER_RIE (1 << 21)
114#define SSI_SIER_TDMAE (1 << 20)
115#define SSI_SIER_TIE (1 << 19)
116#define SSI_SIER_CMDAU_EN (1 << 18)
117#define SSI_SIER_CMDDU_EN (1 << 17)
118#define SSI_SIER_RXT_EN (1 << 16)
119#define SSI_SIER_RDR1_EN (1 << 15)
120#define SSI_SIER_RDR0_EN (1 << 14)
121#define SSI_SIER_TDE1_EN (1 << 13)
122#define SSI_SIER_TDE0_EN (1 << 12)
123#define SSI_SIER_ROE1_EN (1 << 11)
124#define SSI_SIER_ROE0_EN (1 << 10)
125#define SSI_SIER_TUE1_EN (1 << 9)
126#define SSI_SIER_TUE0_EN (1 << 8)
127#define SSI_SIER_TFS_EN (1 << 7)
128#define SSI_SIER_RFS_EN (1 << 6)
129#define SSI_SIER_TLS_EN (1 << 5)
130#define SSI_SIER_RLS_EN (1 << 4)
131#define SSI_SIER_RFF1_EN (1 << 3)
132#define SSI_SIER_RFF0_EN (1 << 2)
133#define SSI_SIER_TFE1_EN (1 << 1)
134#define SSI_SIER_TFE0_EN (1 << 0)
135
136#define SSI_STCR_TXBIT0 (1 << 9)
137#define SSI_STCR_TFEN1 (1 << 8)
138#define SSI_STCR_TFEN0 (1 << 7)
139#define SSI_STCR_TFDIR (1 << 6)
140#define SSI_STCR_TXDIR (1 << 5)
141#define SSI_STCR_TSHFD (1 << 4)
142#define SSI_STCR_TSCKP (1 << 3)
143#define SSI_STCR_TFSI (1 << 2)
144#define SSI_STCR_TFSL (1 << 1)
145#define SSI_STCR_TEFS (1 << 0)
146
147#define SSI_SRCR_RXBIT0 (1 << 9)
148#define SSI_SRCR_RFEN1 (1 << 8)
149#define SSI_SRCR_RFEN0 (1 << 7)
150#define SSI_SRCR_RFDIR (1 << 6)
151#define SSI_SRCR_RXDIR (1 << 5)
152#define SSI_SRCR_RSHFD (1 << 4)
153#define SSI_SRCR_RSCKP (1 << 3)
154#define SSI_SRCR_RFSI (1 << 2)
155#define SSI_SRCR_RFSL (1 << 1)
156#define SSI_SRCR_REFS (1 << 0)
157
158#define SSI_STCCR_DIV2 (1 << 18)
159#define SSI_STCCR_PSR (1 << 15)
160#define SSI_STCCR_WL(x) ((((x) - 2) >> 1) << 13)
161#define SSI_STCCR_DC(x) (((x) & 0x1f) << 8)
162#define SSI_STCCR_PM(x) (((x) & 0xff) << 0)
163#define SSI_STCCR_WL_MASK (0xf << 13)
164#define SSI_STCCR_DC_MASK (0x1f << 8)
165#define SSI_STCCR_PM_MASK (0xff << 0)
166
167#define SSI_SRCCR_DIV2 (1 << 18)
168#define SSI_SRCCR_PSR (1 << 15)
169#define SSI_SRCCR_WL(x) ((((x) - 2) >> 1) << 13)
170#define SSI_SRCCR_DC(x) (((x) & 0x1f) << 8)
171#define SSI_SRCCR_PM(x) (((x) & 0xff) << 0)
172#define SSI_SRCCR_WL_MASK (0xf << 13)
173#define SSI_SRCCR_DC_MASK (0x1f << 8)
174#define SSI_SRCCR_PM_MASK (0xff << 0)
175
176
177#define SSI_SFCSR_RFCNT1(x) (((x) & 0xf) << 28)
178#define SSI_SFCSR_TFCNT1(x) (((x) & 0xf) << 24)
179#define SSI_SFCSR_RFWM1(x) (((x) & 0xf) << 20)
180#define SSI_SFCSR_TFWM1(x) (((x) & 0xf) << 16)
181#define SSI_SFCSR_RFCNT0(x) (((x) & 0xf) << 12)
182#define SSI_SFCSR_TFCNT0(x) (((x) & 0xf) << 8)
183#define SSI_SFCSR_RFWM0(x) (((x) & 0xf) << 4)
184#define SSI_SFCSR_TFWM0(x) (((x) & 0xf) << 0)
185
186#define SSI_STR_TEST (1 << 15)
187#define SSI_STR_RCK2TCK (1 << 14)
188#define SSI_STR_RFS2TFS (1 << 13)
189#define SSI_STR_RXSTATE(x) (((x) & 0xf) << 8)
190#define SSI_STR_TXD2RXD (1 << 7)
191#define SSI_STR_TCK2RCK (1 << 6)
192#define SSI_STR_TFS2RFS (1 << 5)
193#define SSI_STR_TXSTATE(x) (((x) & 0xf) << 0)
194
195#define SSI_SOR_CLKOFF (1 << 6)
196#define SSI_SOR_RX_CLR (1 << 5)
197#define SSI_SOR_TX_CLR (1 << 4)
198#define SSI_SOR_INIT (1 << 3)
199#define SSI_SOR_WAIT(x) (((x) & 0x3) << 1)
200#define SSI_SOR_SYNRST (1 << 0)
201
202#define SSI_SACNT_FRDIV(x) (((x) & 0x3f) << 5)
203#define SSI_SACNT_WR (x << 4)
204#define SSI_SACNT_RD (x << 3)
205#define SSI_SACNT_TIF (x << 2)
206#define SSI_SACNT_FV (x << 1)
207#define SSI_SACNT_AC97EN (x << 0)
208
209/* Watermarks for FIFO's */
210#define TXFIFO_WATERMARK 0x4
211#define RXFIFO_WATERMARK 0x4
212
213/* i.MX DAI SSP ID's */
214#define IMX_DAI_SSI0 0 /* SSI1 FIFO 0 */
215#define IMX_DAI_SSI1 1 /* SSI1 FIFO 1 */
216#define IMX_DAI_SSI2 2 /* SSI2 FIFO 0 */
217#define IMX_DAI_SSI3 3 /* SSI2 FIFO 1 */
218
219/* SSI clock sources */
220#define IMX_SSP_SYS_CLK 0
221
222/* SSI audio dividers */
223#define IMX_SSI_TX_DIV_2 0
224#define IMX_SSI_TX_DIV_PSR 1
225#define IMX_SSI_TX_DIV_PM 2
226#define IMX_SSI_RX_DIV_2 3
227#define IMX_SSI_RX_DIV_PSR 4
228#define IMX_SSI_RX_DIV_PM 5
229
230
231/* SSI Div 2 */
232#define IMX_SSI_DIV_2_OFF (~SSI_STCCR_DIV2)
233#define IMX_SSI_DIV_2_ON SSI_STCCR_DIV2
234
235extern struct snd_soc_dai imx_ssi_pcm_dai[4];
236extern int get_ssi_clk(int ssi, struct device *dev);
237extern void put_ssi_clk(int ssi);
238#endif
diff --git a/sound/soc/imx/phycore-ac97.c b/sound/soc/imx/phycore-ac97.c
new file mode 100644
index 000000000000..a8307d55c70e
--- /dev/null
+++ b/sound/soc/imx/phycore-ac97.c
@@ -0,0 +1,90 @@
1/*
2 * phycore-ac97.c -- SoC audio for imx_phycore in AC97 mode
3 *
4 * Copyright 2009 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 */
12
13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/device.h>
16#include <linux/i2c.h>
17#include <sound/core.h>
18#include <sound/pcm.h>
19#include <sound/soc.h>
20#include <sound/soc-dapm.h>
21#include <asm/mach-types.h>
22
23#include "../codecs/wm9712.h"
24#include "imx-ssi.h"
25
26static struct snd_soc_card imx_phycore;
27
28static struct snd_soc_ops imx_phycore_hifi_ops = {
29};
30
31static struct snd_soc_dai_link imx_phycore_dai_ac97[] = {
32 {
33 .name = "HiFi",
34 .stream_name = "HiFi",
35 .codec_dai = &wm9712_dai[WM9712_DAI_AC97_HIFI],
36 .ops = &imx_phycore_hifi_ops,
37 },
38};
39
40static struct snd_soc_card imx_phycore = {
41 .name = "PhyCORE-audio",
42 .platform = &imx_soc_platform,
43 .dai_link = imx_phycore_dai_ac97,
44 .num_links = ARRAY_SIZE(imx_phycore_dai_ac97),
45};
46
47static struct snd_soc_device imx_phycore_snd_devdata = {
48 .card = &imx_phycore,
49 .codec_dev = &soc_codec_dev_wm9712,
50};
51
52static struct platform_device *imx_phycore_snd_device;
53
54static int __init imx_phycore_init(void)
55{
56 int ret;
57
58 if (!machine_is_pcm043() && !machine_is_pca100())
59 /* return happy. We might run on a totally different machine */
60 return 0;
61
62 imx_phycore_snd_device = platform_device_alloc("soc-audio", -1);
63 if (!imx_phycore_snd_device)
64 return -ENOMEM;
65
66 imx_phycore_dai_ac97[0].cpu_dai = &imx_ssi_pcm_dai[0];
67
68 platform_set_drvdata(imx_phycore_snd_device, &imx_phycore_snd_devdata);
69 imx_phycore_snd_devdata.dev = &imx_phycore_snd_device->dev;
70 ret = platform_device_add(imx_phycore_snd_device);
71
72 if (ret) {
73 printk(KERN_ERR "ASoC: Platform device allocation failed\n");
74 platform_device_put(imx_phycore_snd_device);
75 }
76
77 return ret;
78}
79
80static void __exit imx_phycore_exit(void)
81{
82 platform_device_unregister(imx_phycore_snd_device);
83}
84
85late_initcall(imx_phycore_init);
86module_exit(imx_phycore_exit);
87
88MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
89MODULE_DESCRIPTION("PhyCORE ALSA SoC driver");
90MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
index 653a362425df..f11963c21873 100644
--- a/sound/soc/omap/Kconfig
+++ b/sound/soc/omap/Kconfig
@@ -6,6 +6,9 @@ config SND_OMAP_SOC_MCBSP
6 tristate 6 tristate
7 select OMAP_MCBSP 7 select OMAP_MCBSP
8 8
9config SND_OMAP_SOC_MCPDM
10 tristate
11
9config SND_OMAP_SOC_N810 12config SND_OMAP_SOC_N810
10 tristate "SoC Audio support for Nokia N810" 13 tristate "SoC Audio support for Nokia N810"
11 depends on SND_OMAP_SOC && MACH_NOKIA_N810 && I2C 14 depends on SND_OMAP_SOC && MACH_NOKIA_N810 && I2C
@@ -43,12 +46,13 @@ config SND_OMAP_SOC_OSK5912
43 Say Y if you want to add support for SoC audio on osk5912. 46 Say Y if you want to add support for SoC audio on osk5912.
44 47
45config SND_OMAP_SOC_OVERO 48config SND_OMAP_SOC_OVERO
46 tristate "SoC Audio support for Gumstix Overo" 49 tristate "SoC Audio support for Gumstix Overo and CompuLab CM-T35"
47 depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OVERO 50 depends on TWL4030_CORE && SND_OMAP_SOC && (MACH_OVERO || MACH_CM_T35)
48 select SND_OMAP_SOC_MCBSP 51 select SND_OMAP_SOC_MCBSP
49 select SND_SOC_TWL4030 52 select SND_SOC_TWL4030
50 help 53 help
51 Say Y if you want to add support for SoC audio on the Gumstix Overo. 54 Say Y if you want to add support for SoC audio on the
55 Gumstix Overo or CompuLab CM-T35
52 56
53config SND_OMAP_SOC_OMAP2EVM 57config SND_OMAP_SOC_OMAP2EVM
54 tristate "SoC Audio support for OMAP2EVM board" 58 tristate "SoC Audio support for OMAP2EVM board"
@@ -66,6 +70,15 @@ config SND_OMAP_SOC_OMAP3EVM
66 help 70 help
67 Say Y if you want to add support for SoC audio on the omap3evm board. 71 Say Y if you want to add support for SoC audio on the omap3evm board.
68 72
73config SND_OMAP_SOC_AM3517EVM
74 tristate "SoC Audio support for OMAP3517 / AM3517 EVM"
75 depends on SND_OMAP_SOC && MACH_OMAP3517EVM && I2C
76 select SND_OMAP_SOC_MCBSP
77 select SND_SOC_TLV320AIC23
78 help
79 Say Y if you want to add support for SoC audio on the OMAP3517 / AM3517
80 EVM.
81
69config SND_OMAP_SOC_SDP3430 82config SND_OMAP_SOC_SDP3430
70 tristate "SoC Audio support for Texas Instruments SDP3430" 83 tristate "SoC Audio support for Texas Instruments SDP3430"
71 depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP_3430SDP 84 depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP_3430SDP
@@ -84,12 +97,14 @@ config SND_OMAP_SOC_OMAP3_PANDORA
84 Say Y if you want to add support for SoC audio on the OMAP3 Pandora. 97 Say Y if you want to add support for SoC audio on the OMAP3 Pandora.
85 98
86config SND_OMAP_SOC_OMAP3_BEAGLE 99config SND_OMAP_SOC_OMAP3_BEAGLE
87 tristate "SoC Audio support for OMAP3 Beagle" 100 tristate "SoC Audio support for OMAP3 Beagle and Devkit8000"
88 depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP3_BEAGLE 101 depends on TWL4030_CORE && SND_OMAP_SOC
102 depends on (MACH_OMAP3_BEAGLE || MACH_DEVKIT8000)
89 select SND_OMAP_SOC_MCBSP 103 select SND_OMAP_SOC_MCBSP
90 select SND_SOC_TWL4030 104 select SND_SOC_TWL4030
91 help 105 help
92 Say Y if you want to add support for SoC audio on the Beagleboard. 106 Say Y if you want to add support for SoC audio on the Beagleboard or
107 the clone Devkit8000.
93 108
94config SND_OMAP_SOC_ZOOM2 109config SND_OMAP_SOC_ZOOM2
95 tristate "SoC Audio support for Zoom2" 110 tristate "SoC Audio support for Zoom2"
@@ -99,3 +114,10 @@ config SND_OMAP_SOC_ZOOM2
99 help 114 help
100 Say Y if you want to add support for Soc audio on Zoom2 board. 115 Say Y if you want to add support for Soc audio on Zoom2 board.
101 116
117config SND_OMAP_SOC_IGEP0020
118 tristate "SoC Audio support for IGEP v2"
119 depends on TWL4030_CORE && SND_OMAP_SOC && MACH_IGEP0020
120 select SND_OMAP_SOC_MCBSP
121 select SND_SOC_TWL4030
122 help
123 Say Y if you want to add support for Soc audio on IGEP v2 board.
diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile
index 02d69471dcb5..0bc00ca14b37 100644
--- a/sound/soc/omap/Makefile
+++ b/sound/soc/omap/Makefile
@@ -1,9 +1,11 @@
1# OMAP Platform Support 1# OMAP Platform Support
2snd-soc-omap-objs := omap-pcm.o 2snd-soc-omap-objs := omap-pcm.o
3snd-soc-omap-mcbsp-objs := omap-mcbsp.o 3snd-soc-omap-mcbsp-objs := omap-mcbsp.o
4snd-soc-omap-mcpdm-objs := omap-mcpdm.o mcpdm.o
4 5
5obj-$(CONFIG_SND_OMAP_SOC) += snd-soc-omap.o 6obj-$(CONFIG_SND_OMAP_SOC) += snd-soc-omap.o
6obj-$(CONFIG_SND_OMAP_SOC_MCBSP) += snd-soc-omap-mcbsp.o 7obj-$(CONFIG_SND_OMAP_SOC_MCBSP) += snd-soc-omap-mcbsp.o
8obj-$(CONFIG_SND_OMAP_SOC_MCPDM) += snd-soc-omap-mcpdm.o
7 9
8# OMAP Machine Support 10# OMAP Machine Support
9snd-soc-n810-objs := n810.o 11snd-soc-n810-objs := n810.o
@@ -12,18 +14,22 @@ snd-soc-osk5912-objs := osk5912.o
12snd-soc-overo-objs := overo.o 14snd-soc-overo-objs := overo.o
13snd-soc-omap2evm-objs := omap2evm.o 15snd-soc-omap2evm-objs := omap2evm.o
14snd-soc-omap3evm-objs := omap3evm.o 16snd-soc-omap3evm-objs := omap3evm.o
17snd-soc-am3517evm-objs := am3517evm.o
15snd-soc-sdp3430-objs := sdp3430.o 18snd-soc-sdp3430-objs := sdp3430.o
16snd-soc-omap3pandora-objs := omap3pandora.o 19snd-soc-omap3pandora-objs := omap3pandora.o
17snd-soc-omap3beagle-objs := omap3beagle.o 20snd-soc-omap3beagle-objs := omap3beagle.o
18snd-soc-zoom2-objs := zoom2.o 21snd-soc-zoom2-objs := zoom2.o
22snd-soc-igep0020-objs := igep0020.o
19 23
20obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o 24obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o
21obj-$(CONFIG_SND_OMAP_SOC_AMS_DELTA) += snd-soc-ams-delta.o 25obj-$(CONFIG_SND_OMAP_SOC_AMS_DELTA) += snd-soc-ams-delta.o
22obj-$(CONFIG_SND_OMAP_SOC_OSK5912) += snd-soc-osk5912.o 26obj-$(CONFIG_SND_OMAP_SOC_OSK5912) += snd-soc-osk5912.o
23obj-$(CONFIG_SND_OMAP_SOC_OVERO) += snd-soc-overo.o 27obj-$(CONFIG_SND_OMAP_SOC_OVERO) += snd-soc-overo.o
24obj-$(CONFIG_MACH_OMAP2EVM) += snd-soc-omap2evm.o 28obj-$(CONFIG_SND_OMAP_SOC_OMAP2EVM) += snd-soc-omap2evm.o
25obj-$(CONFIG_MACH_OMAP3EVM) += snd-soc-omap3evm.o 29obj-$(CONFIG_SND_OMAP_SOC_OMAP3EVM) += snd-soc-omap3evm.o
30obj-$(CONFIG_SND_OMAP_SOC_AM3517EVM) += snd-soc-am3517evm.o
26obj-$(CONFIG_SND_OMAP_SOC_SDP3430) += snd-soc-sdp3430.o 31obj-$(CONFIG_SND_OMAP_SOC_SDP3430) += snd-soc-sdp3430.o
27obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o 32obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o
28obj-$(CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE) += snd-soc-omap3beagle.o 33obj-$(CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE) += snd-soc-omap3beagle.o
29obj-$(CONFIG_SND_OMAP_SOC_ZOOM2) += snd-soc-zoom2.o 34obj-$(CONFIG_SND_OMAP_SOC_ZOOM2) += snd-soc-zoom2.o
35obj-$(CONFIG_SND_OMAP_SOC_IGEP0020) += snd-soc-igep0020.o
diff --git a/sound/soc/omap/am3517evm.c b/sound/soc/omap/am3517evm.c
new file mode 100644
index 000000000000..135901b2ea11
--- /dev/null
+++ b/sound/soc/omap/am3517evm.c
@@ -0,0 +1,202 @@
1/*
2 * am3517evm.c -- ALSA SoC support for OMAP3517 / AM3517 EVM
3 *
4 * Author: Anuj Aggarwal <anuj.aggarwal@ti.com>
5 *
6 * Based on sound/soc/omap/beagle.c by Steve Sakoman
7 *
8 * Copyright (C) 2009 Texas Instruments Incorporated
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation version 2.
13 *
14 * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
15 * whether express or implied; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 */
19
20#include <linux/clk.h>
21#include <linux/platform_device.h>
22#include <sound/core.h>
23#include <sound/pcm.h>
24#include <sound/soc.h>
25#include <sound/soc-dapm.h>
26
27#include <asm/mach-types.h>
28#include <mach/hardware.h>
29#include <mach/gpio.h>
30#include <plat/mcbsp.h>
31
32#include "omap-mcbsp.h"
33#include "omap-pcm.h"
34
35#include "../codecs/tlv320aic23.h"
36
37#define CODEC_CLOCK 12000000
38
39static int am3517evm_hw_params(struct snd_pcm_substream *substream,
40 struct snd_pcm_hw_params *params)
41{
42 struct snd_soc_pcm_runtime *rtd = substream->private_data;
43 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
44 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
45 int ret;
46
47 /* Set codec DAI configuration */
48 ret = snd_soc_dai_set_fmt(codec_dai,
49 SND_SOC_DAIFMT_DSP_B |
50 SND_SOC_DAIFMT_NB_NF |
51 SND_SOC_DAIFMT_CBM_CFM);
52 if (ret < 0) {
53 printk(KERN_ERR "can't set codec DAI configuration\n");
54 return ret;
55 }
56
57 /* Set cpu DAI configuration */
58 ret = snd_soc_dai_set_fmt(cpu_dai,
59 SND_SOC_DAIFMT_DSP_B |
60 SND_SOC_DAIFMT_NB_NF |
61 SND_SOC_DAIFMT_CBM_CFM);
62 if (ret < 0) {
63 printk(KERN_ERR "can't set cpu DAI configuration\n");
64 return ret;
65 }
66
67 /* Set the codec system clock for DAC and ADC */
68 ret = snd_soc_dai_set_sysclk(codec_dai, 0,
69 CODEC_CLOCK, SND_SOC_CLOCK_IN);
70 if (ret < 0) {
71 printk(KERN_ERR "can't set codec system clock\n");
72 return ret;
73 }
74
75 ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_CLKR_SRC_CLKX, 0,
76 SND_SOC_CLOCK_IN);
77 if (ret < 0) {
78 printk(KERN_ERR "can't set CPU system clock OMAP_MCBSP_CLKR_SRC_CLKX\n");
79 return ret;
80 }
81
82 snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_FSR_SRC_FSX, 0,
83 SND_SOC_CLOCK_IN);
84 if (ret < 0) {
85 printk(KERN_ERR "can't set CPU system clock OMAP_MCBSP_FSR_SRC_FSX\n");
86 return ret;
87 }
88
89 return 0;
90}
91
92static struct snd_soc_ops am3517evm_ops = {
93 .hw_params = am3517evm_hw_params,
94};
95
96/* am3517evm machine dapm widgets */
97static const struct snd_soc_dapm_widget tlv320aic23_dapm_widgets[] = {
98 SND_SOC_DAPM_HP("Line Out", NULL),
99 SND_SOC_DAPM_LINE("Line In", NULL),
100 SND_SOC_DAPM_MIC("Mic In", NULL),
101};
102
103static const struct snd_soc_dapm_route audio_map[] = {
104 /* Line Out connected to LLOUT, RLOUT */
105 {"Line Out", NULL, "LOUT"},
106 {"Line Out", NULL, "ROUT"},
107
108 {"LLINEIN", NULL, "Line In"},
109 {"RLINEIN", NULL, "Line In"},
110
111 {"MICIN", NULL, "Mic In"},
112};
113
114static int am3517evm_aic23_init(struct snd_soc_codec *codec)
115{
116 /* Add am3517-evm specific widgets */
117 snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets,
118 ARRAY_SIZE(tlv320aic23_dapm_widgets));
119
120 /* Set up davinci-evm specific audio path audio_map */
121 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
122
123 /* always connected */
124 snd_soc_dapm_enable_pin(codec, "Line Out");
125 snd_soc_dapm_enable_pin(codec, "Line In");
126 snd_soc_dapm_enable_pin(codec, "Mic In");
127
128 snd_soc_dapm_sync(codec);
129
130 return 0;
131}
132
133/* Digital audio interface glue - connects codec <--> CPU */
134static struct snd_soc_dai_link am3517evm_dai = {
135 .name = "TLV320AIC23",
136 .stream_name = "AIC23",
137 .cpu_dai = &omap_mcbsp_dai[0],
138 .codec_dai = &tlv320aic23_dai,
139 .init = am3517evm_aic23_init,
140 .ops = &am3517evm_ops,
141};
142
143/* Audio machine driver */
144static struct snd_soc_card snd_soc_am3517evm = {
145 .name = "am3517evm",
146 .platform = &omap_soc_platform,
147 .dai_link = &am3517evm_dai,
148 .num_links = 1,
149};
150
151/* Audio subsystem */
152static struct snd_soc_device am3517evm_snd_devdata = {
153 .card = &snd_soc_am3517evm,
154 .codec_dev = &soc_codec_dev_tlv320aic23,
155};
156
157static struct platform_device *am3517evm_snd_device;
158
159static int __init am3517evm_soc_init(void)
160{
161 int ret;
162
163 if (!machine_is_omap3517evm()) {
164 pr_err("Not OMAP3517 / AM3517 EVM!\n");
165 return -ENODEV;
166 }
167 pr_info("OMAP3517 / AM3517 EVM SoC init\n");
168
169 am3517evm_snd_device = platform_device_alloc("soc-audio", -1);
170 if (!am3517evm_snd_device) {
171 printk(KERN_ERR "Platform device allocation failed\n");
172 return -ENOMEM;
173 }
174
175 platform_set_drvdata(am3517evm_snd_device, &am3517evm_snd_devdata);
176 am3517evm_snd_devdata.dev = &am3517evm_snd_device->dev;
177 *(unsigned int *)am3517evm_dai.cpu_dai->private_data = 0; /* McBSP1 */
178
179 ret = platform_device_add(am3517evm_snd_device);
180 if (ret)
181 goto err1;
182
183 return 0;
184
185err1:
186 printk(KERN_ERR "Unable to add platform device\n");
187 platform_device_put(am3517evm_snd_device);
188
189 return ret;
190}
191
192static void __exit am3517evm_soc_exit(void)
193{
194 platform_device_unregister(am3517evm_snd_device);
195}
196
197module_init(am3517evm_soc_init);
198module_exit(am3517evm_soc_exit);
199
200MODULE_AUTHOR("Anuj Aggarwal <anuj.aggarwal@ti.com>");
201MODULE_DESCRIPTION("ALSA SoC OMAP3517 / AM3517 EVM");
202MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c
index 5a5166ac7279..b0f618e44840 100644
--- a/sound/soc/omap/ams-delta.c
+++ b/sound/soc/omap/ams-delta.c
@@ -31,8 +31,8 @@
31 31
32#include <asm/mach-types.h> 32#include <asm/mach-types.h>
33 33
34#include <mach/board-ams-delta.h> 34#include <plat/board-ams-delta.h>
35#include <mach/mcbsp.h> 35#include <plat/mcbsp.h>
36 36
37#include "omap-mcbsp.h" 37#include "omap-mcbsp.h"
38#include "omap-pcm.h" 38#include "omap-pcm.h"
@@ -40,7 +40,7 @@
40 40
41 41
42/* Board specific DAPM widgets */ 42/* Board specific DAPM widgets */
43 const struct snd_soc_dapm_widget ams_delta_dapm_widgets[] = { 43static const struct snd_soc_dapm_widget ams_delta_dapm_widgets[] = {
44 /* Handset */ 44 /* Handset */
45 SND_SOC_DAPM_MIC("Mouthpiece", NULL), 45 SND_SOC_DAPM_MIC("Mouthpiece", NULL),
46 SND_SOC_DAPM_HP("Earpiece", NULL), 46 SND_SOC_DAPM_HP("Earpiece", NULL),
@@ -81,7 +81,7 @@ static const char *ams_delta_audio_mode[] =
81 (1 << AMS_DELTA_SPEAKER)) 81 (1 << AMS_DELTA_SPEAKER))
82#define AMS_DELTA_SPEAKERPHONE (AMS_DELTA_HANDSFREE | (1 << AMS_DELTA_AGC)) 82#define AMS_DELTA_SPEAKERPHONE (AMS_DELTA_HANDSFREE | (1 << AMS_DELTA_AGC))
83 83
84unsigned short ams_delta_audio_mode_pins[] = { 84static const unsigned short ams_delta_audio_mode_pins[] = {
85 AMS_DELTA_MIXED, 85 AMS_DELTA_MIXED,
86 AMS_DELTA_HANDSET, 86 AMS_DELTA_HANDSET,
87 AMS_DELTA_HANDSFREE, 87 AMS_DELTA_HANDSFREE,
diff --git a/sound/soc/omap/igep0020.c b/sound/soc/omap/igep0020.c
new file mode 100644
index 000000000000..3583c429f9be
--- /dev/null
+++ b/sound/soc/omap/igep0020.c
@@ -0,0 +1,148 @@
1/*
2 * igep0020.c -- SoC audio for IGEP v2
3 *
4 * Based on sound/soc/omap/overo.c by Steve Sakoman
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 */
21
22#include <linux/clk.h>
23#include <linux/platform_device.h>
24#include <sound/core.h>
25#include <sound/pcm.h>
26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28
29#include <asm/mach-types.h>
30#include <mach/hardware.h>
31#include <mach/gpio.h>
32#include <plat/mcbsp.h>
33
34#include "omap-mcbsp.h"
35#include "omap-pcm.h"
36#include "../codecs/twl4030.h"
37
38static int igep2_hw_params(struct snd_pcm_substream *substream,
39 struct snd_pcm_hw_params *params)
40{
41 struct snd_soc_pcm_runtime *rtd = substream->private_data;
42 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
43 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
44 int ret;
45
46 /* Set codec DAI configuration */
47 ret = snd_soc_dai_set_fmt(codec_dai,
48 SND_SOC_DAIFMT_I2S |
49 SND_SOC_DAIFMT_NB_NF |
50 SND_SOC_DAIFMT_CBM_CFM);
51 if (ret < 0) {
52 printk(KERN_ERR "can't set codec DAI configuration\n");
53 return ret;
54 }
55
56 /* Set cpu DAI configuration */
57 ret = snd_soc_dai_set_fmt(cpu_dai,
58 SND_SOC_DAIFMT_I2S |
59 SND_SOC_DAIFMT_NB_NF |
60 SND_SOC_DAIFMT_CBM_CFM);
61 if (ret < 0) {
62 printk(KERN_ERR "can't set cpu DAI configuration\n");
63 return ret;
64 }
65
66 /* Set the codec system clock for DAC and ADC */
67 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
68 SND_SOC_CLOCK_IN);
69 if (ret < 0) {
70 printk(KERN_ERR "can't set codec system clock\n");
71 return ret;
72 }
73
74 return 0;
75}
76
77static struct snd_soc_ops igep2_ops = {
78 .hw_params = igep2_hw_params,
79};
80
81/* Digital audio interface glue - connects codec <--> CPU */
82static struct snd_soc_dai_link igep2_dai = {
83 .name = "TWL4030",
84 .stream_name = "TWL4030",
85 .cpu_dai = &omap_mcbsp_dai[0],
86 .codec_dai = &twl4030_dai[TWL4030_DAI_HIFI],
87 .ops = &igep2_ops,
88};
89
90/* Audio machine driver */
91static struct snd_soc_card snd_soc_card_igep2 = {
92 .name = "igep2",
93 .platform = &omap_soc_platform,
94 .dai_link = &igep2_dai,
95 .num_links = 1,
96};
97
98/* Audio subsystem */
99static struct snd_soc_device igep2_snd_devdata = {
100 .card = &snd_soc_card_igep2,
101 .codec_dev = &soc_codec_dev_twl4030,
102};
103
104static struct platform_device *igep2_snd_device;
105
106static int __init igep2_soc_init(void)
107{
108 int ret;
109
110 if (!machine_is_igep0020()) {
111 pr_debug("Not IGEP v2!\n");
112 return -ENODEV;
113 }
114 printk(KERN_INFO "IGEP v2 SoC init\n");
115
116 igep2_snd_device = platform_device_alloc("soc-audio", -1);
117 if (!igep2_snd_device) {
118 printk(KERN_ERR "Platform device allocation failed\n");
119 return -ENOMEM;
120 }
121
122 platform_set_drvdata(igep2_snd_device, &igep2_snd_devdata);
123 igep2_snd_devdata.dev = &igep2_snd_device->dev;
124 *(unsigned int *)igep2_dai.cpu_dai->private_data = 1; /* McBSP2 */
125
126 ret = platform_device_add(igep2_snd_device);
127 if (ret)
128 goto err1;
129
130 return 0;
131
132err1:
133 printk(KERN_ERR "Unable to add platform device\n");
134 platform_device_put(igep2_snd_device);
135
136 return ret;
137}
138module_init(igep2_soc_init);
139
140static void __exit igep2_soc_exit(void)
141{
142 platform_device_unregister(igep2_snd_device);
143}
144module_exit(igep2_soc_exit);
145
146MODULE_AUTHOR("Enric Balletbo i Serra <eballetbo@iseebcn.com>");
147MODULE_DESCRIPTION("ALSA SoC IGEP v2");
148MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/mcpdm.c b/sound/soc/omap/mcpdm.c
new file mode 100644
index 000000000000..1dab4c14874d
--- /dev/null
+++ b/sound/soc/omap/mcpdm.c
@@ -0,0 +1,485 @@
1/*
2 * mcpdm.c -- McPDM interface driver
3 *
4 * Author: Jorge Eduardo Candelaria <x0107209@ti.com>
5 * Copyright (C) 2009 - Texas Instruments, Inc.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19 * 02110-1301 USA
20 *
21 */
22
23#include <linux/module.h>
24#include <linux/init.h>
25#include <linux/device.h>
26#include <linux/platform_device.h>
27#include <linux/wait.h>
28#include <linux/slab.h>
29#include <linux/interrupt.h>
30#include <linux/err.h>
31#include <linux/clk.h>
32#include <linux/delay.h>
33#include <linux/io.h>
34#include <linux/irq.h>
35
36#include "mcpdm.h"
37
38static struct omap_mcpdm *mcpdm;
39
40static inline void omap_mcpdm_write(u16 reg, u32 val)
41{
42 __raw_writel(val, mcpdm->io_base + reg);
43}
44
45static inline int omap_mcpdm_read(u16 reg)
46{
47 return __raw_readl(mcpdm->io_base + reg);
48}
49
50static void omap_mcpdm_reg_dump(void)
51{
52 dev_dbg(mcpdm->dev, "***********************\n");
53 dev_dbg(mcpdm->dev, "IRQSTATUS_RAW: 0x%04x\n",
54 omap_mcpdm_read(MCPDM_IRQSTATUS_RAW));
55 dev_dbg(mcpdm->dev, "IRQSTATUS: 0x%04x\n",
56 omap_mcpdm_read(MCPDM_IRQSTATUS));
57 dev_dbg(mcpdm->dev, "IRQENABLE_SET: 0x%04x\n",
58 omap_mcpdm_read(MCPDM_IRQENABLE_SET));
59 dev_dbg(mcpdm->dev, "IRQENABLE_CLR: 0x%04x\n",
60 omap_mcpdm_read(MCPDM_IRQENABLE_CLR));
61 dev_dbg(mcpdm->dev, "IRQWAKE_EN: 0x%04x\n",
62 omap_mcpdm_read(MCPDM_IRQWAKE_EN));
63 dev_dbg(mcpdm->dev, "DMAENABLE_SET: 0x%04x\n",
64 omap_mcpdm_read(MCPDM_DMAENABLE_SET));
65 dev_dbg(mcpdm->dev, "DMAENABLE_CLR: 0x%04x\n",
66 omap_mcpdm_read(MCPDM_DMAENABLE_CLR));
67 dev_dbg(mcpdm->dev, "DMAWAKEEN: 0x%04x\n",
68 omap_mcpdm_read(MCPDM_DMAWAKEEN));
69 dev_dbg(mcpdm->dev, "CTRL: 0x%04x\n",
70 omap_mcpdm_read(MCPDM_CTRL));
71 dev_dbg(mcpdm->dev, "DN_DATA: 0x%04x\n",
72 omap_mcpdm_read(MCPDM_DN_DATA));
73 dev_dbg(mcpdm->dev, "UP_DATA: 0x%04x\n",
74 omap_mcpdm_read(MCPDM_UP_DATA));
75 dev_dbg(mcpdm->dev, "FIFO_CTRL_DN: 0x%04x\n",
76 omap_mcpdm_read(MCPDM_FIFO_CTRL_DN));
77 dev_dbg(mcpdm->dev, "FIFO_CTRL_UP: 0x%04x\n",
78 omap_mcpdm_read(MCPDM_FIFO_CTRL_UP));
79 dev_dbg(mcpdm->dev, "DN_OFFSET: 0x%04x\n",
80 omap_mcpdm_read(MCPDM_DN_OFFSET));
81 dev_dbg(mcpdm->dev, "***********************\n");
82}
83
84/*
85 * Takes the McPDM module in and out of reset state.
86 * Uplink and downlink can be reset individually.
87 */
88static void omap_mcpdm_reset_capture(int reset)
89{
90 int ctrl = omap_mcpdm_read(MCPDM_CTRL);
91
92 if (reset)
93 ctrl |= SW_UP_RST;
94 else
95 ctrl &= ~SW_UP_RST;
96
97 omap_mcpdm_write(MCPDM_CTRL, ctrl);
98}
99
100static void omap_mcpdm_reset_playback(int reset)
101{
102 int ctrl = omap_mcpdm_read(MCPDM_CTRL);
103
104 if (reset)
105 ctrl |= SW_DN_RST;
106 else
107 ctrl &= ~SW_DN_RST;
108
109 omap_mcpdm_write(MCPDM_CTRL, ctrl);
110}
111
112/*
113 * Enables the transfer through the PDM interface to/from the Phoenix
114 * codec by enabling the corresponding UP or DN channels.
115 */
116void omap_mcpdm_start(int stream)
117{
118 int ctrl = omap_mcpdm_read(MCPDM_CTRL);
119
120 if (stream)
121 ctrl |= mcpdm->up_channels;
122 else
123 ctrl |= mcpdm->dn_channels;
124
125 omap_mcpdm_write(MCPDM_CTRL, ctrl);
126}
127
128/*
129 * Disables the transfer through the PDM interface to/from the Phoenix
130 * codec by disabling the corresponding UP or DN channels.
131 */
132void omap_mcpdm_stop(int stream)
133{
134 int ctrl = omap_mcpdm_read(MCPDM_CTRL);
135
136 if (stream)
137 ctrl &= ~mcpdm->up_channels;
138 else
139 ctrl &= ~mcpdm->dn_channels;
140
141 omap_mcpdm_write(MCPDM_CTRL, ctrl);
142}
143
144/*
145 * Configures McPDM uplink for audio recording.
146 * This function should be called before omap_mcpdm_start.
147 */
148int omap_mcpdm_capture_open(struct omap_mcpdm_link *uplink)
149{
150 int irq_mask = 0;
151 int ctrl;
152
153 if (!uplink)
154 return -EINVAL;
155
156 mcpdm->uplink = uplink;
157
158 /* Enable irq request generation */
159 irq_mask |= uplink->irq_mask & MCPDM_UPLINK_IRQ_MASK;
160 omap_mcpdm_write(MCPDM_IRQENABLE_SET, irq_mask);
161
162 /* Configure uplink threshold */
163 if (uplink->threshold > UP_THRES_MAX)
164 uplink->threshold = UP_THRES_MAX;
165
166 omap_mcpdm_write(MCPDM_FIFO_CTRL_UP, uplink->threshold);
167
168 /* Configure DMA controller */
169 omap_mcpdm_write(MCPDM_DMAENABLE_SET, DMA_UP_ENABLE);
170
171 /* Set pdm out format */
172 ctrl = omap_mcpdm_read(MCPDM_CTRL);
173 ctrl &= ~PDMOUTFORMAT;
174 ctrl |= uplink->format & PDMOUTFORMAT;
175
176 /* Uplink channels */
177 mcpdm->up_channels = uplink->channels & (PDM_UP_MASK | PDM_STATUS_MASK);
178
179 omap_mcpdm_write(MCPDM_CTRL, ctrl);
180
181 return 0;
182}
183
184/*
185 * Configures McPDM downlink for audio playback.
186 * This function should be called before omap_mcpdm_start.
187 */
188int omap_mcpdm_playback_open(struct omap_mcpdm_link *downlink)
189{
190 int irq_mask = 0;
191 int ctrl;
192
193 if (!downlink)
194 return -EINVAL;
195
196 mcpdm->downlink = downlink;
197
198 /* Enable irq request generation */
199 irq_mask |= downlink->irq_mask & MCPDM_DOWNLINK_IRQ_MASK;
200 omap_mcpdm_write(MCPDM_IRQENABLE_SET, irq_mask);
201
202 /* Configure uplink threshold */
203 if (downlink->threshold > DN_THRES_MAX)
204 downlink->threshold = DN_THRES_MAX;
205
206 omap_mcpdm_write(MCPDM_FIFO_CTRL_DN, downlink->threshold);
207
208 /* Enable DMA request generation */
209 omap_mcpdm_write(MCPDM_DMAENABLE_SET, DMA_DN_ENABLE);
210
211 /* Set pdm out format */
212 ctrl = omap_mcpdm_read(MCPDM_CTRL);
213 ctrl &= ~PDMOUTFORMAT;
214 ctrl |= downlink->format & PDMOUTFORMAT;
215
216 /* Downlink channels */
217 mcpdm->dn_channels = downlink->channels & (PDM_DN_MASK | PDM_CMD_MASK);
218
219 omap_mcpdm_write(MCPDM_CTRL, ctrl);
220
221 return 0;
222}
223
224/*
225 * Cleans McPDM uplink configuration.
226 * This function should be called when the stream is closed.
227 */
228int omap_mcpdm_capture_close(struct omap_mcpdm_link *uplink)
229{
230 int irq_mask = 0;
231
232 if (!uplink)
233 return -EINVAL;
234
235 /* Disable irq request generation */
236 irq_mask |= uplink->irq_mask & MCPDM_UPLINK_IRQ_MASK;
237 omap_mcpdm_write(MCPDM_IRQENABLE_CLR, irq_mask);
238
239 /* Disable DMA request generation */
240 omap_mcpdm_write(MCPDM_DMAENABLE_CLR, DMA_UP_ENABLE);
241
242 /* Clear Downlink channels */
243 mcpdm->up_channels = 0;
244
245 mcpdm->uplink = NULL;
246
247 return 0;
248}
249
250/*
251 * Cleans McPDM downlink configuration.
252 * This function should be called when the stream is closed.
253 */
254int omap_mcpdm_playback_close(struct omap_mcpdm_link *downlink)
255{
256 int irq_mask = 0;
257
258 if (!downlink)
259 return -EINVAL;
260
261 /* Disable irq request generation */
262 irq_mask |= downlink->irq_mask & MCPDM_DOWNLINK_IRQ_MASK;
263 omap_mcpdm_write(MCPDM_IRQENABLE_CLR, irq_mask);
264
265 /* Disable DMA request generation */
266 omap_mcpdm_write(MCPDM_DMAENABLE_CLR, DMA_DN_ENABLE);
267
268 /* clear Downlink channels */
269 mcpdm->dn_channels = 0;
270
271 mcpdm->downlink = NULL;
272
273 return 0;
274}
275
276static irqreturn_t omap_mcpdm_irq_handler(int irq, void *dev_id)
277{
278 struct omap_mcpdm *mcpdm_irq = dev_id;
279 int irq_status;
280
281 irq_status = omap_mcpdm_read(MCPDM_IRQSTATUS);
282
283 /* Acknowledge irq event */
284 omap_mcpdm_write(MCPDM_IRQSTATUS, irq_status);
285
286 if (irq & MCPDM_DN_IRQ_FULL) {
287 dev_err(mcpdm_irq->dev, "DN FIFO error %x\n", irq_status);
288 omap_mcpdm_reset_playback(1);
289 omap_mcpdm_playback_open(mcpdm_irq->downlink);
290 omap_mcpdm_reset_playback(0);
291 }
292
293 if (irq & MCPDM_DN_IRQ_EMPTY) {
294 dev_err(mcpdm_irq->dev, "DN FIFO error %x\n", irq_status);
295 omap_mcpdm_reset_playback(1);
296 omap_mcpdm_playback_open(mcpdm_irq->downlink);
297 omap_mcpdm_reset_playback(0);
298 }
299
300 if (irq & MCPDM_DN_IRQ) {
301 dev_dbg(mcpdm_irq->dev, "DN write request\n");
302 }
303
304 if (irq & MCPDM_UP_IRQ_FULL) {
305 dev_err(mcpdm_irq->dev, "UP FIFO error %x\n", irq_status);
306 omap_mcpdm_reset_capture(1);
307 omap_mcpdm_capture_open(mcpdm_irq->uplink);
308 omap_mcpdm_reset_capture(0);
309 }
310
311 if (irq & MCPDM_UP_IRQ_EMPTY) {
312 dev_err(mcpdm_irq->dev, "UP FIFO error %x\n", irq_status);
313 omap_mcpdm_reset_capture(1);
314 omap_mcpdm_capture_open(mcpdm_irq->uplink);
315 omap_mcpdm_reset_capture(0);
316 }
317
318 if (irq & MCPDM_UP_IRQ) {
319 dev_dbg(mcpdm_irq->dev, "UP write request\n");
320 }
321
322 return IRQ_HANDLED;
323}
324
325int omap_mcpdm_request(void)
326{
327 int ret;
328
329 clk_enable(mcpdm->clk);
330
331 spin_lock(&mcpdm->lock);
332
333 if (!mcpdm->free) {
334 dev_err(mcpdm->dev, "McPDM interface is in use\n");
335 spin_unlock(&mcpdm->lock);
336 ret = -EBUSY;
337 goto err;
338 }
339 mcpdm->free = 0;
340
341 spin_unlock(&mcpdm->lock);
342
343 /* Disable lines while request is ongoing */
344 omap_mcpdm_write(MCPDM_CTRL, 0x00);
345
346 ret = request_irq(mcpdm->irq, omap_mcpdm_irq_handler,
347 0, "McPDM", (void *)mcpdm);
348 if (ret) {
349 dev_err(mcpdm->dev, "Request for McPDM IRQ failed\n");
350 goto err;
351 }
352
353 return 0;
354
355err:
356 clk_disable(mcpdm->clk);
357 return ret;
358}
359
360void omap_mcpdm_free(void)
361{
362 spin_lock(&mcpdm->lock);
363 if (mcpdm->free) {
364 dev_err(mcpdm->dev, "McPDM interface is already free\n");
365 spin_unlock(&mcpdm->lock);
366 return;
367 }
368 mcpdm->free = 1;
369 spin_unlock(&mcpdm->lock);
370
371 clk_disable(mcpdm->clk);
372
373 free_irq(mcpdm->irq, (void *)mcpdm);
374}
375
376/* Enable/disable DC offset cancelation for the analog
377 * headset path (PDM channels 1 and 2).
378 */
379int omap_mcpdm_set_offset(int offset1, int offset2)
380{
381 int offset;
382
383 if ((offset1 > DN_OFST_MAX) || (offset2 > DN_OFST_MAX))
384 return -EINVAL;
385
386 offset = (offset1 << DN_OFST_RX1) | (offset2 << DN_OFST_RX2);
387
388 /* offset cancellation for channel 1 */
389 if (offset1)
390 offset |= DN_OFST_RX1_EN;
391 else
392 offset &= ~DN_OFST_RX1_EN;
393
394 /* offset cancellation for channel 2 */
395 if (offset2)
396 offset |= DN_OFST_RX2_EN;
397 else
398 offset &= ~DN_OFST_RX2_EN;
399
400 omap_mcpdm_write(MCPDM_DN_OFFSET, offset);
401
402 return 0;
403}
404
405static int __devinit omap_mcpdm_probe(struct platform_device *pdev)
406{
407 struct resource *res;
408 int ret = 0;
409
410 mcpdm = kzalloc(sizeof(struct omap_mcpdm), GFP_KERNEL);
411 if (!mcpdm) {
412 ret = -ENOMEM;
413 goto exit;
414 }
415
416 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
417 if (res == NULL) {
418 dev_err(&pdev->dev, "no resource\n");
419 goto err_resource;
420 }
421
422 spin_lock_init(&mcpdm->lock);
423 mcpdm->free = 1;
424 mcpdm->io_base = ioremap(res->start, resource_size(res));
425 if (!mcpdm->io_base) {
426 ret = -ENOMEM;
427 goto err_resource;
428 }
429
430 mcpdm->irq = platform_get_irq(pdev, 0);
431
432 mcpdm->clk = clk_get(&pdev->dev, "pdm_ck");
433 if (IS_ERR(mcpdm->clk)) {
434 ret = PTR_ERR(mcpdm->clk);
435 dev_err(&pdev->dev, "unable to get pdm_ck: %d\n", ret);
436 goto err_clk;
437 }
438
439 mcpdm->dev = &pdev->dev;
440 platform_set_drvdata(pdev, mcpdm);
441
442 return 0;
443
444err_clk:
445 iounmap(mcpdm->io_base);
446err_resource:
447 kfree(mcpdm);
448exit:
449 return ret;
450}
451
452static int __devexit omap_mcpdm_remove(struct platform_device *pdev)
453{
454 struct omap_mcpdm *mcpdm_ptr = platform_get_drvdata(pdev);
455
456 platform_set_drvdata(pdev, NULL);
457
458 clk_put(mcpdm_ptr->clk);
459
460 iounmap(mcpdm_ptr->io_base);
461
462 mcpdm_ptr->clk = NULL;
463 mcpdm_ptr->free = 0;
464 mcpdm_ptr->dev = NULL;
465
466 kfree(mcpdm_ptr);
467
468 return 0;
469}
470
471static struct platform_driver omap_mcpdm_driver = {
472 .probe = omap_mcpdm_probe,
473 .remove = __devexit_p(omap_mcpdm_remove),
474 .driver = {
475 .name = "omap-mcpdm",
476 },
477};
478
479static struct platform_device *omap_mcpdm_device;
480
481static int __init omap_mcpdm_init(void)
482{
483 return platform_driver_register(&omap_mcpdm_driver);
484}
485arch_initcall(omap_mcpdm_init);
diff --git a/sound/soc/omap/mcpdm.h b/sound/soc/omap/mcpdm.h
new file mode 100644
index 000000000000..7bb326ef0886
--- /dev/null
+++ b/sound/soc/omap/mcpdm.h
@@ -0,0 +1,151 @@
1/*
2 * mcpdm.h -- Defines for McPDM driver
3 *
4 * Author: Jorge Eduardo Candelaria <x0107209@ti.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 */
21
22/* McPDM registers */
23
24#define MCPDM_REVISION 0x00
25#define MCPDM_SYSCONFIG 0x10
26#define MCPDM_IRQSTATUS_RAW 0x24
27#define MCPDM_IRQSTATUS 0x28
28#define MCPDM_IRQENABLE_SET 0x2C
29#define MCPDM_IRQENABLE_CLR 0x30
30#define MCPDM_IRQWAKE_EN 0x34
31#define MCPDM_DMAENABLE_SET 0x38
32#define MCPDM_DMAENABLE_CLR 0x3C
33#define MCPDM_DMAWAKEEN 0x40
34#define MCPDM_CTRL 0x44
35#define MCPDM_DN_DATA 0x48
36#define MCPDM_UP_DATA 0x4C
37#define MCPDM_FIFO_CTRL_DN 0x50
38#define MCPDM_FIFO_CTRL_UP 0x54
39#define MCPDM_DN_OFFSET 0x58
40
41/*
42 * MCPDM_IRQ bit fields
43 * IRQSTATUS_RAW, IRQSTATUS, IRQENABLE_SET, IRQENABLE_CLR
44 */
45
46#define MCPDM_DN_IRQ (1 << 0)
47#define MCPDM_DN_IRQ_EMPTY (1 << 1)
48#define MCPDM_DN_IRQ_ALMST_EMPTY (1 << 2)
49#define MCPDM_DN_IRQ_FULL (1 << 3)
50
51#define MCPDM_UP_IRQ (1 << 8)
52#define MCPDM_UP_IRQ_EMPTY (1 << 9)
53#define MCPDM_UP_IRQ_ALMST_FULL (1 << 10)
54#define MCPDM_UP_IRQ_FULL (1 << 11)
55
56#define MCPDM_DOWNLINK_IRQ_MASK 0x00F
57#define MCPDM_UPLINK_IRQ_MASK 0xF00
58
59/*
60 * MCPDM_DMAENABLE bit fields
61 */
62
63#define DMA_DN_ENABLE 0x1
64#define DMA_UP_ENABLE 0x2
65
66/*
67 * MCPDM_CTRL bit fields
68 */
69
70#define PDM_UP1_EN 0x0001
71#define PDM_UP2_EN 0x0002
72#define PDM_UP3_EN 0x0004
73#define PDM_DN1_EN 0x0008
74#define PDM_DN2_EN 0x0010
75#define PDM_DN3_EN 0x0020
76#define PDM_DN4_EN 0x0040
77#define PDM_DN5_EN 0x0080
78#define PDMOUTFORMAT 0x0100
79#define CMD_INT 0x0200
80#define STATUS_INT 0x0400
81#define SW_UP_RST 0x0800
82#define SW_DN_RST 0x1000
83#define PDM_UP_MASK 0x007
84#define PDM_DN_MASK 0x0F8
85#define PDM_CMD_MASK 0x200
86#define PDM_STATUS_MASK 0x400
87
88
89#define PDMOUTFORMAT_LJUST (0 << 8)
90#define PDMOUTFORMAT_RJUST (1 << 8)
91
92/*
93 * MCPDM_FIFO_CTRL bit fields
94 */
95
96#define UP_THRES_MAX 0xF
97#define DN_THRES_MAX 0xF
98
99/*
100 * MCPDM_DN_OFFSET bit fields
101 */
102
103#define DN_OFST_RX1_EN 0x0001
104#define DN_OFST_RX2_EN 0x0100
105
106#define DN_OFST_RX1 1
107#define DN_OFST_RX2 9
108#define DN_OFST_MAX 0x1F
109
110#define MCPDM_UPLINK 1
111#define MCPDM_DOWNLINK 2
112
113struct omap_mcpdm_link {
114 int irq_mask;
115 int threshold;
116 int format;
117 int channels;
118};
119
120struct omap_mcpdm_platform_data {
121 unsigned long phys_base;
122 u16 irq;
123};
124
125struct omap_mcpdm {
126 struct device *dev;
127 unsigned long phys_base;
128 void __iomem *io_base;
129 u8 free;
130 int irq;
131
132 spinlock_t lock;
133 struct omap_mcpdm_platform_data *pdata;
134 struct clk *clk;
135 struct omap_mcpdm_link *downlink;
136 struct omap_mcpdm_link *uplink;
137 struct completion irq_completion;
138
139 int dn_channels;
140 int up_channels;
141};
142
143extern void omap_mcpdm_start(int stream);
144extern void omap_mcpdm_stop(int stream);
145extern int omap_mcpdm_capture_open(struct omap_mcpdm_link *uplink);
146extern int omap_mcpdm_playback_open(struct omap_mcpdm_link *downlink);
147extern int omap_mcpdm_capture_close(struct omap_mcpdm_link *uplink);
148extern int omap_mcpdm_playback_close(struct omap_mcpdm_link *downlink);
149extern int omap_mcpdm_request(void);
150extern void omap_mcpdm_free(void);
151extern int omap_mcpdm_set_offset(int offset1, int offset2);
diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c
index 0a505938e42b..08e09d72790f 100644
--- a/sound/soc/omap/n810.c
+++ b/sound/soc/omap/n810.c
@@ -32,7 +32,7 @@
32#include <asm/mach-types.h> 32#include <asm/mach-types.h>
33#include <mach/hardware.h> 33#include <mach/hardware.h>
34#include <linux/gpio.h> 34#include <linux/gpio.h>
35#include <mach/mcbsp.h> 35#include <plat/mcbsp.h>
36 36
37#include "omap-mcbsp.h" 37#include "omap-mcbsp.h"
38#include "omap-pcm.h" 38#include "omap-pcm.h"
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index 3341f49402ca..8ad9dc901007 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -31,14 +31,22 @@
31#include <sound/initval.h> 31#include <sound/initval.h>
32#include <sound/soc.h> 32#include <sound/soc.h>
33 33
34#include <mach/control.h> 34#include <plat/control.h>
35#include <mach/dma.h> 35#include <plat/dma.h>
36#include <mach/mcbsp.h> 36#include <plat/mcbsp.h>
37#include "omap-mcbsp.h" 37#include "omap-mcbsp.h"
38#include "omap-pcm.h" 38#include "omap-pcm.h"
39 39
40#define OMAP_MCBSP_RATES (SNDRV_PCM_RATE_8000_96000) 40#define OMAP_MCBSP_RATES (SNDRV_PCM_RATE_8000_96000)
41 41
42#define OMAP_MCBSP_SOC_SINGLE_S16_EXT(xname, xmin, xmax, \
43 xhandler_get, xhandler_put) \
44{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
45 .info = omap_mcbsp_st_info_volsw, \
46 .get = xhandler_get, .put = xhandler_put, \
47 .private_value = (unsigned long) &(struct soc_mixer_control) \
48 {.min = xmin, .max = xmax} }
49
42struct omap_mcbsp_data { 50struct omap_mcbsp_data {
43 unsigned int bus_id; 51 unsigned int bus_id;
44 struct omap_mcbsp_reg_cfg regs; 52 struct omap_mcbsp_reg_cfg regs;
@@ -49,6 +57,8 @@ struct omap_mcbsp_data {
49 */ 57 */
50 int active; 58 int active;
51 int configured; 59 int configured;
60 unsigned int in_freq;
61 int clk_div;
52}; 62};
53 63
54#define to_mcbsp(priv) container_of((priv), struct omap_mcbsp_data, bus_id) 64#define to_mcbsp(priv) container_of((priv), struct omap_mcbsp_data, bus_id)
@@ -80,11 +90,11 @@ static const int omap1_dma_reqs[][2] = {};
80static const unsigned long omap1_mcbsp_port[][2] = {}; 90static const unsigned long omap1_mcbsp_port[][2] = {};
81#endif 91#endif
82 92
83#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) 93#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
84static const int omap24xx_dma_reqs[][2] = { 94static const int omap24xx_dma_reqs[][2] = {
85 { OMAP24XX_DMA_MCBSP1_TX, OMAP24XX_DMA_MCBSP1_RX }, 95 { OMAP24XX_DMA_MCBSP1_TX, OMAP24XX_DMA_MCBSP1_RX },
86 { OMAP24XX_DMA_MCBSP2_TX, OMAP24XX_DMA_MCBSP2_RX }, 96 { OMAP24XX_DMA_MCBSP2_TX, OMAP24XX_DMA_MCBSP2_RX },
87#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP34XX) 97#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3)
88 { OMAP24XX_DMA_MCBSP3_TX, OMAP24XX_DMA_MCBSP3_RX }, 98 { OMAP24XX_DMA_MCBSP3_TX, OMAP24XX_DMA_MCBSP3_RX },
89 { OMAP24XX_DMA_MCBSP4_TX, OMAP24XX_DMA_MCBSP4_RX }, 99 { OMAP24XX_DMA_MCBSP4_TX, OMAP24XX_DMA_MCBSP4_RX },
90 { OMAP24XX_DMA_MCBSP5_TX, OMAP24XX_DMA_MCBSP5_RX }, 100 { OMAP24XX_DMA_MCBSP5_TX, OMAP24XX_DMA_MCBSP5_RX },
@@ -122,7 +132,7 @@ static const unsigned long omap2430_mcbsp_port[][2] = {
122static const unsigned long omap2430_mcbsp_port[][2] = {}; 132static const unsigned long omap2430_mcbsp_port[][2] = {};
123#endif 133#endif
124 134
125#if defined(CONFIG_ARCH_OMAP34XX) 135#if defined(CONFIG_ARCH_OMAP3)
126static const unsigned long omap34xx_mcbsp_port[][2] = { 136static const unsigned long omap34xx_mcbsp_port[][2] = {
127 { OMAP34XX_MCBSP1_BASE + OMAP_MCBSP_REG_DXR, 137 { OMAP34XX_MCBSP1_BASE + OMAP_MCBSP_REG_DXR,
128 OMAP34XX_MCBSP1_BASE + OMAP_MCBSP_REG_DRR }, 138 OMAP34XX_MCBSP1_BASE + OMAP_MCBSP_REG_DRR },
@@ -257,7 +267,7 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
257 int dma, bus_id = mcbsp_data->bus_id, id = cpu_dai->id; 267 int dma, bus_id = mcbsp_data->bus_id, id = cpu_dai->id;
258 int wlen, channels, wpf, sync_mode = OMAP_DMA_SYNC_ELEMENT; 268 int wlen, channels, wpf, sync_mode = OMAP_DMA_SYNC_ELEMENT;
259 unsigned long port; 269 unsigned long port;
260 unsigned int format; 270 unsigned int format, div, framesize, master;
261 271
262 if (cpu_class_is_omap1()) { 272 if (cpu_class_is_omap1()) {
263 dma = omap1_dma_reqs[bus_id][substream->stream]; 273 dma = omap1_dma_reqs[bus_id][substream->stream];
@@ -285,7 +295,11 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
285 omap_mcbsp_dai_dma_params[id][substream->stream].dma_req = dma; 295 omap_mcbsp_dai_dma_params[id][substream->stream].dma_req = dma;
286 omap_mcbsp_dai_dma_params[id][substream->stream].port_addr = port; 296 omap_mcbsp_dai_dma_params[id][substream->stream].port_addr = port;
287 omap_mcbsp_dai_dma_params[id][substream->stream].sync_mode = sync_mode; 297 omap_mcbsp_dai_dma_params[id][substream->stream].sync_mode = sync_mode;
288 cpu_dai->dma_data = &omap_mcbsp_dai_dma_params[id][substream->stream]; 298 omap_mcbsp_dai_dma_params[id][substream->stream].data_type =
299 OMAP_DMA_DATA_TYPE_S16;
300
301 snd_soc_dai_set_dma_data(cpu_dai, substream,
302 &omap_mcbsp_dai_dma_params[id][substream->stream]);
289 303
290 if (mcbsp_data->configured) { 304 if (mcbsp_data->configured) {
291 /* McBSP already configured by another stream */ 305 /* McBSP already configured by another stream */
@@ -294,28 +308,19 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
294 308
295 format = mcbsp_data->fmt & SND_SOC_DAIFMT_FORMAT_MASK; 309 format = mcbsp_data->fmt & SND_SOC_DAIFMT_FORMAT_MASK;
296 wpf = channels = params_channels(params); 310 wpf = channels = params_channels(params);
297 switch (channels) { 311 if (channels == 2 && format == SND_SOC_DAIFMT_I2S) {
298 case 2: 312 /* Use dual-phase frames */
299 if (format == SND_SOC_DAIFMT_I2S) { 313 regs->rcr2 |= RPHASE;
300 /* Use dual-phase frames */ 314 regs->xcr2 |= XPHASE;
301 regs->rcr2 |= RPHASE; 315 /* Set 1 word per (McBSP) frame for phase1 and phase2 */
302 regs->xcr2 |= XPHASE; 316 wpf--;
303 /* Set 1 word per (McBSP) frame for phase1 and phase2 */ 317 regs->rcr2 |= RFRLEN2(wpf - 1);
304 wpf--; 318 regs->xcr2 |= XFRLEN2(wpf - 1);
305 regs->rcr2 |= RFRLEN2(wpf - 1);
306 regs->xcr2 |= XFRLEN2(wpf - 1);
307 }
308 case 1:
309 case 4:
310 /* Set word per (McBSP) frame for phase1 */
311 regs->rcr1 |= RFRLEN1(wpf - 1);
312 regs->xcr1 |= XFRLEN1(wpf - 1);
313 break;
314 default:
315 /* Unsupported number of channels */
316 return -EINVAL;
317 } 319 }
318 320
321 regs->rcr1 |= RFRLEN1(wpf - 1);
322 regs->xcr1 |= XFRLEN1(wpf - 1);
323
319 switch (params_format(params)) { 324 switch (params_format(params)) {
320 case SNDRV_PCM_FORMAT_S16_LE: 325 case SNDRV_PCM_FORMAT_S16_LE:
321 /* Set word lengths */ 326 /* Set word lengths */
@@ -330,15 +335,30 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
330 return -EINVAL; 335 return -EINVAL;
331 } 336 }
332 337
338 /* In McBSP master modes, FRAME (i.e. sample rate) is generated
339 * by _counting_ BCLKs. Calculate frame size in BCLKs */
340 master = mcbsp_data->fmt & SND_SOC_DAIFMT_MASTER_MASK;
341 if (master == SND_SOC_DAIFMT_CBS_CFS) {
342 div = mcbsp_data->clk_div ? mcbsp_data->clk_div : 1;
343 framesize = (mcbsp_data->in_freq / div) / params_rate(params);
344
345 if (framesize < wlen * channels) {
346 printk(KERN_ERR "%s: not enough bandwidth for desired rate and "
347 "channels\n", __func__);
348 return -EINVAL;
349 }
350 } else
351 framesize = wlen * channels;
352
333 /* Set FS period and length in terms of bit clock periods */ 353 /* Set FS period and length in terms of bit clock periods */
334 switch (format) { 354 switch (format) {
335 case SND_SOC_DAIFMT_I2S: 355 case SND_SOC_DAIFMT_I2S:
336 regs->srgr2 |= FPER(wlen * channels - 1); 356 regs->srgr2 |= FPER(framesize - 1);
337 regs->srgr1 |= FWID(wlen - 1); 357 regs->srgr1 |= FWID((framesize >> 1) - 1);
338 break; 358 break;
339 case SND_SOC_DAIFMT_DSP_A: 359 case SND_SOC_DAIFMT_DSP_A:
340 case SND_SOC_DAIFMT_DSP_B: 360 case SND_SOC_DAIFMT_DSP_B:
341 regs->srgr2 |= FPER(wlen * channels - 1); 361 regs->srgr2 |= FPER(framesize - 1);
342 regs->srgr1 |= FWID(0); 362 regs->srgr1 |= FWID(0);
343 break; 363 break;
344 } 364 }
@@ -454,6 +474,7 @@ static int omap_mcbsp_dai_set_clkdiv(struct snd_soc_dai *cpu_dai,
454 if (div_id != OMAP_MCBSP_CLKGDV) 474 if (div_id != OMAP_MCBSP_CLKGDV)
455 return -ENODEV; 475 return -ENODEV;
456 476
477 mcbsp_data->clk_div = div;
457 regs->srgr1 |= CLKGDV(div - 1); 478 regs->srgr1 |= CLKGDV(div - 1);
458 479
459 return 0; 480 return 0;
@@ -554,6 +575,8 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
554 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs; 575 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs;
555 int err = 0; 576 int err = 0;
556 577
578 mcbsp_data->in_freq = freq;
579
557 switch (clk_id) { 580 switch (clk_id) {
558 case OMAP_MCBSP_SYSCLK_CLK: 581 case OMAP_MCBSP_SYSCLK_CLK:
559 regs->srgr2 |= CLKSM; 582 regs->srgr2 |= CLKSM;
@@ -598,13 +621,13 @@ static struct snd_soc_dai_ops omap_mcbsp_dai_ops = {
598 .id = (link_id), \ 621 .id = (link_id), \
599 .playback = { \ 622 .playback = { \
600 .channels_min = 1, \ 623 .channels_min = 1, \
601 .channels_max = 4, \ 624 .channels_max = 16, \
602 .rates = OMAP_MCBSP_RATES, \ 625 .rates = OMAP_MCBSP_RATES, \
603 .formats = SNDRV_PCM_FMTBIT_S16_LE, \ 626 .formats = SNDRV_PCM_FMTBIT_S16_LE, \
604 }, \ 627 }, \
605 .capture = { \ 628 .capture = { \
606 .channels_min = 1, \ 629 .channels_min = 1, \
607 .channels_max = 4, \ 630 .channels_max = 16, \
608 .rates = OMAP_MCBSP_RATES, \ 631 .rates = OMAP_MCBSP_RATES, \
609 .formats = SNDRV_PCM_FMTBIT_S16_LE, \ 632 .formats = SNDRV_PCM_FMTBIT_S16_LE, \
610 }, \ 633 }, \
@@ -626,6 +649,136 @@ struct snd_soc_dai omap_mcbsp_dai[] = {
626 649
627EXPORT_SYMBOL_GPL(omap_mcbsp_dai); 650EXPORT_SYMBOL_GPL(omap_mcbsp_dai);
628 651
652int omap_mcbsp_st_info_volsw(struct snd_kcontrol *kcontrol,
653 struct snd_ctl_elem_info *uinfo)
654{
655 struct soc_mixer_control *mc =
656 (struct soc_mixer_control *)kcontrol->private_value;
657 int max = mc->max;
658 int min = mc->min;
659
660 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
661 uinfo->count = 1;
662 uinfo->value.integer.min = min;
663 uinfo->value.integer.max = max;
664 return 0;
665}
666
667#define OMAP_MCBSP_ST_SET_CHANNEL_VOLUME(id, channel) \
668static int \
669omap_mcbsp##id##_set_st_ch##channel##_volume(struct snd_kcontrol *kc, \
670 struct snd_ctl_elem_value *uc) \
671{ \
672 struct soc_mixer_control *mc = \
673 (struct soc_mixer_control *)kc->private_value; \
674 int max = mc->max; \
675 int min = mc->min; \
676 int val = uc->value.integer.value[0]; \
677 \
678 if (val < min || val > max) \
679 return -EINVAL; \
680 \
681 /* OMAP McBSP implementation uses index values 0..4 */ \
682 return omap_st_set_chgain((id)-1, channel, val); \
683}
684
685#define OMAP_MCBSP_ST_GET_CHANNEL_VOLUME(id, channel) \
686static int \
687omap_mcbsp##id##_get_st_ch##channel##_volume(struct snd_kcontrol *kc, \
688 struct snd_ctl_elem_value *uc) \
689{ \
690 s16 chgain; \
691 \
692 if (omap_st_get_chgain((id)-1, channel, &chgain)) \
693 return -EAGAIN; \
694 \
695 uc->value.integer.value[0] = chgain; \
696 return 0; \
697}
698
699OMAP_MCBSP_ST_SET_CHANNEL_VOLUME(2, 0)
700OMAP_MCBSP_ST_SET_CHANNEL_VOLUME(2, 1)
701OMAP_MCBSP_ST_SET_CHANNEL_VOLUME(3, 0)
702OMAP_MCBSP_ST_SET_CHANNEL_VOLUME(3, 1)
703OMAP_MCBSP_ST_GET_CHANNEL_VOLUME(2, 0)
704OMAP_MCBSP_ST_GET_CHANNEL_VOLUME(2, 1)
705OMAP_MCBSP_ST_GET_CHANNEL_VOLUME(3, 0)
706OMAP_MCBSP_ST_GET_CHANNEL_VOLUME(3, 1)
707
708static int omap_mcbsp_st_put_mode(struct snd_kcontrol *kcontrol,
709 struct snd_ctl_elem_value *ucontrol)
710{
711 struct soc_mixer_control *mc =
712 (struct soc_mixer_control *)kcontrol->private_value;
713 u8 value = ucontrol->value.integer.value[0];
714
715 if (value == omap_st_is_enabled(mc->reg))
716 return 0;
717
718 if (value)
719 omap_st_enable(mc->reg);
720 else
721 omap_st_disable(mc->reg);
722
723 return 1;
724}
725
726static int omap_mcbsp_st_get_mode(struct snd_kcontrol *kcontrol,
727 struct snd_ctl_elem_value *ucontrol)
728{
729 struct soc_mixer_control *mc =
730 (struct soc_mixer_control *)kcontrol->private_value;
731
732 ucontrol->value.integer.value[0] = omap_st_is_enabled(mc->reg);
733 return 0;
734}
735
736static const struct snd_kcontrol_new omap_mcbsp2_st_controls[] = {
737 SOC_SINGLE_EXT("McBSP2 Sidetone Switch", 1, 0, 1, 0,
738 omap_mcbsp_st_get_mode, omap_mcbsp_st_put_mode),
739 OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP2 Sidetone Channel 0 Volume",
740 -32768, 32767,
741 omap_mcbsp2_get_st_ch0_volume,
742 omap_mcbsp2_set_st_ch0_volume),
743 OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP2 Sidetone Channel 1 Volume",
744 -32768, 32767,
745 omap_mcbsp2_get_st_ch1_volume,
746 omap_mcbsp2_set_st_ch1_volume),
747};
748
749static const struct snd_kcontrol_new omap_mcbsp3_st_controls[] = {
750 SOC_SINGLE_EXT("McBSP3 Sidetone Switch", 2, 0, 1, 0,
751 omap_mcbsp_st_get_mode, omap_mcbsp_st_put_mode),
752 OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP3 Sidetone Channel 0 Volume",
753 -32768, 32767,
754 omap_mcbsp3_get_st_ch0_volume,
755 omap_mcbsp3_set_st_ch0_volume),
756 OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP3 Sidetone Channel 1 Volume",
757 -32768, 32767,
758 omap_mcbsp3_get_st_ch1_volume,
759 omap_mcbsp3_set_st_ch1_volume),
760};
761
762int omap_mcbsp_st_add_controls(struct snd_soc_codec *codec, int mcbsp_id)
763{
764 if (!cpu_is_omap34xx())
765 return -ENODEV;
766
767 switch (mcbsp_id) {
768 case 1: /* McBSP 2 */
769 return snd_soc_add_controls(codec, omap_mcbsp2_st_controls,
770 ARRAY_SIZE(omap_mcbsp2_st_controls));
771 case 2: /* McBSP 3 */
772 return snd_soc_add_controls(codec, omap_mcbsp3_st_controls,
773 ARRAY_SIZE(omap_mcbsp3_st_controls));
774 default:
775 break;
776 }
777
778 return -EINVAL;
779}
780EXPORT_SYMBOL_GPL(omap_mcbsp_st_add_controls);
781
629static int __init snd_omap_mcbsp_init(void) 782static int __init snd_omap_mcbsp_init(void)
630{ 783{
631 return snd_soc_register_dais(omap_mcbsp_dai, 784 return snd_soc_register_dais(omap_mcbsp_dai,
diff --git a/sound/soc/omap/omap-mcbsp.h b/sound/soc/omap/omap-mcbsp.h
index 647d2f981ab0..6c363e5f4387 100644
--- a/sound/soc/omap/omap-mcbsp.h
+++ b/sound/soc/omap/omap-mcbsp.h
@@ -50,11 +50,13 @@ enum omap_mcbsp_div {
50#undef NUM_LINKS 50#undef NUM_LINKS
51#define NUM_LINKS 3 51#define NUM_LINKS 3
52#endif 52#endif
53#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP34XX) 53#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3)
54#undef NUM_LINKS 54#undef NUM_LINKS
55#define NUM_LINKS 5 55#define NUM_LINKS 5
56#endif 56#endif
57 57
58extern struct snd_soc_dai omap_mcbsp_dai[NUM_LINKS]; 58extern struct snd_soc_dai omap_mcbsp_dai[NUM_LINKS];
59 59
60int omap_mcbsp_st_add_controls(struct snd_soc_codec *codec, int mcbsp_id);
61
60#endif 62#endif
diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c
new file mode 100644
index 000000000000..b7f4f7e015f3
--- /dev/null
+++ b/sound/soc/omap/omap-mcpdm.c
@@ -0,0 +1,252 @@
1/*
2 * omap-mcpdm.c -- OMAP ALSA SoC DAI driver using McPDM port
3 *
4 * Copyright (C) 2009 Texas Instruments
5 *
6 * Author: Misael Lopez Cruz <x0052729@ti.com>
7 * Contact: Jorge Eduardo Candelaria <x0107209@ti.com>
8 * Margarita Olaya <magi.olaya@ti.com>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * version 2 as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22 * 02110-1301 USA
23 *
24 */
25
26#include <linux/init.h>
27#include <linux/module.h>
28#include <linux/device.h>
29#include <sound/core.h>
30#include <sound/pcm.h>
31#include <sound/pcm_params.h>
32#include <sound/initval.h>
33#include <sound/soc.h>
34
35#include <plat/control.h>
36#include <plat/dma.h>
37#include <plat/mcbsp.h>
38#include "mcpdm.h"
39#include "omap-mcpdm.h"
40#include "omap-pcm.h"
41
42struct omap_mcpdm_data {
43 struct omap_mcpdm_link *links;
44 int active;
45};
46
47static struct omap_mcpdm_link omap_mcpdm_links[] = {
48 /* downlink */
49 {
50 .irq_mask = MCPDM_DN_IRQ_EMPTY | MCPDM_DN_IRQ_FULL,
51 .threshold = 1,
52 .format = PDMOUTFORMAT_LJUST,
53 },
54 /* uplink */
55 {
56 .irq_mask = MCPDM_UP_IRQ_EMPTY | MCPDM_UP_IRQ_FULL,
57 .threshold = 1,
58 .format = PDMOUTFORMAT_LJUST,
59 },
60};
61
62static struct omap_mcpdm_data mcpdm_data = {
63 .links = omap_mcpdm_links,
64 .active = 0,
65};
66
67/*
68 * Stream DMA parameters
69 */
70static struct omap_pcm_dma_data omap_mcpdm_dai_dma_params[] = {
71 {
72 .name = "Audio playback",
73 .dma_req = OMAP44XX_DMA_MCPDM_DL,
74 .data_type = OMAP_DMA_DATA_TYPE_S32,
75 .sync_mode = OMAP_DMA_SYNC_PACKET,
76 .packet_size = 16,
77 .port_addr = OMAP44XX_MCPDM_L3_BASE + MCPDM_DN_DATA,
78 },
79 {
80 .name = "Audio capture",
81 .dma_req = OMAP44XX_DMA_MCPDM_UP,
82 .data_type = OMAP_DMA_DATA_TYPE_S32,
83 .sync_mode = OMAP_DMA_SYNC_PACKET,
84 .packet_size = 16,
85 .port_addr = OMAP44XX_MCPDM_L3_BASE + MCPDM_UP_DATA,
86 },
87};
88
89static int omap_mcpdm_dai_startup(struct snd_pcm_substream *substream,
90 struct snd_soc_dai *dai)
91{
92 struct snd_soc_pcm_runtime *rtd = substream->private_data;
93 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
94 int err = 0;
95
96 if (!cpu_dai->active)
97 err = omap_mcpdm_request();
98
99 return err;
100}
101
102static void omap_mcpdm_dai_shutdown(struct snd_pcm_substream *substream,
103 struct snd_soc_dai *dai)
104{
105 struct snd_soc_pcm_runtime *rtd = substream->private_data;
106 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
107
108 if (!cpu_dai->active)
109 omap_mcpdm_free();
110}
111
112static int omap_mcpdm_dai_trigger(struct snd_pcm_substream *substream, int cmd,
113 struct snd_soc_dai *dai)
114{
115 struct snd_soc_pcm_runtime *rtd = substream->private_data;
116 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
117 struct omap_mcpdm_data *mcpdm_priv = cpu_dai->private_data;
118 int stream = substream->stream;
119 int err = 0;
120
121 switch (cmd) {
122 case SNDRV_PCM_TRIGGER_START:
123 case SNDRV_PCM_TRIGGER_RESUME:
124 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
125 if (!mcpdm_priv->active++)
126 omap_mcpdm_start(stream);
127 break;
128
129 case SNDRV_PCM_TRIGGER_STOP:
130 case SNDRV_PCM_TRIGGER_SUSPEND:
131 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
132 if (!--mcpdm_priv->active)
133 omap_mcpdm_stop(stream);
134 break;
135 default:
136 err = -EINVAL;
137 }
138
139 return err;
140}
141
142static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream,
143 struct snd_pcm_hw_params *params,
144 struct snd_soc_dai *dai)
145{
146 struct snd_soc_pcm_runtime *rtd = substream->private_data;
147 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
148 struct omap_mcpdm_data *mcpdm_priv = cpu_dai->private_data;
149 struct omap_mcpdm_link *mcpdm_links = mcpdm_priv->links;
150 int stream = substream->stream;
151 int channels, err, link_mask = 0;
152
153 snd_soc_dai_set_dma_data(cpu_dai, substream,
154 &omap_mcpdm_dai_dma_params[stream]);
155
156 channels = params_channels(params);
157 switch (channels) {
158 case 4:
159 if (stream == SNDRV_PCM_STREAM_CAPTURE)
160 /* up to 2 channels for capture */
161 return -EINVAL;
162 link_mask |= 1 << 3;
163 case 3:
164 if (stream == SNDRV_PCM_STREAM_CAPTURE)
165 /* up to 2 channels for capture */
166 return -EINVAL;
167 link_mask |= 1 << 2;
168 case 2:
169 link_mask |= 1 << 1;
170 case 1:
171 link_mask |= 1 << 0;
172 break;
173 default:
174 /* unsupported number of channels */
175 return -EINVAL;
176 }
177
178 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
179 mcpdm_links[stream].channels = link_mask << 3;
180 err = omap_mcpdm_playback_open(&mcpdm_links[stream]);
181 } else {
182 mcpdm_links[stream].channels = link_mask << 0;
183 err = omap_mcpdm_capture_open(&mcpdm_links[stream]);
184 }
185
186 return err;
187}
188
189static int omap_mcpdm_dai_hw_free(struct snd_pcm_substream *substream,
190 struct snd_soc_dai *dai)
191{
192 struct snd_soc_pcm_runtime *rtd = substream->private_data;
193 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
194 struct omap_mcpdm_data *mcpdm_priv = cpu_dai->private_data;
195 struct omap_mcpdm_link *mcpdm_links = mcpdm_priv->links;
196 int stream = substream->stream;
197 int err;
198
199 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
200 err = omap_mcpdm_playback_close(&mcpdm_links[stream]);
201 else
202 err = omap_mcpdm_capture_close(&mcpdm_links[stream]);
203
204 return err;
205}
206
207static struct snd_soc_dai_ops omap_mcpdm_dai_ops = {
208 .startup = omap_mcpdm_dai_startup,
209 .shutdown = omap_mcpdm_dai_shutdown,
210 .trigger = omap_mcpdm_dai_trigger,
211 .hw_params = omap_mcpdm_dai_hw_params,
212 .hw_free = omap_mcpdm_dai_hw_free,
213};
214
215#define OMAP_MCPDM_RATES (SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
216#define OMAP_MCPDM_FORMATS (SNDRV_PCM_FMTBIT_S32_LE)
217
218struct snd_soc_dai omap_mcpdm_dai = {
219 .name = "omap-mcpdm",
220 .id = -1,
221 .playback = {
222 .channels_min = 1,
223 .channels_max = 4,
224 .rates = OMAP_MCPDM_RATES,
225 .formats = OMAP_MCPDM_FORMATS,
226 },
227 .capture = {
228 .channels_min = 1,
229 .channels_max = 2,
230 .rates = OMAP_MCPDM_RATES,
231 .formats = OMAP_MCPDM_FORMATS,
232 },
233 .ops = &omap_mcpdm_dai_ops,
234 .private_data = &mcpdm_data,
235};
236EXPORT_SYMBOL_GPL(omap_mcpdm_dai);
237
238static int __init snd_omap_mcpdm_init(void)
239{
240 return snd_soc_register_dai(&omap_mcpdm_dai);
241}
242module_init(snd_omap_mcpdm_init);
243
244static void __exit snd_omap_mcpdm_exit(void)
245{
246 snd_soc_unregister_dai(&omap_mcpdm_dai);
247}
248module_exit(snd_omap_mcpdm_exit);
249
250MODULE_AUTHOR("Misael Lopez Cruz <x0052729@ti.com>");
251MODULE_DESCRIPTION("OMAP PDM SoC Interface");
252MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/omap-mcpdm.h b/sound/soc/omap/omap-mcpdm.h
new file mode 100644
index 000000000000..73b80d559345
--- /dev/null
+++ b/sound/soc/omap/omap-mcpdm.h
@@ -0,0 +1,29 @@
1/*
2 * omap-mcpdm.h
3 *
4 * Copyright (C) 2009 Texas Instruments
5 *
6 * Contact: Misael Lopez Cruz <x0052729@ti.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#ifndef __OMAP_MCPDM_H__
25#define __OMAP_MCPDM_H__
26
27extern struct snd_soc_dai omap_mcpdm_dai;
28
29#endif /* End of __OMAP_MCPDM_H__ */
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c
index 6a829eef2a4f..1e521904ea64 100644
--- a/sound/soc/omap/omap-pcm.c
+++ b/sound/soc/omap/omap-pcm.c
@@ -23,12 +23,13 @@
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>
29#include <sound/soc.h> 30#include <sound/soc.h>
30 31
31#include <mach/dma.h> 32#include <plat/dma.h>
32#include "omap-pcm.h" 33#include "omap-pcm.h"
33 34
34static const struct snd_pcm_hardware omap_pcm_hardware = { 35static const struct snd_pcm_hardware omap_pcm_hardware = {
@@ -37,7 +38,8 @@ static const struct snd_pcm_hardware omap_pcm_hardware = {
37 SNDRV_PCM_INFO_INTERLEAVED | 38 SNDRV_PCM_INFO_INTERLEAVED |
38 SNDRV_PCM_INFO_PAUSE | 39 SNDRV_PCM_INFO_PAUSE |
39 SNDRV_PCM_INFO_RESUME, 40 SNDRV_PCM_INFO_RESUME,
40 .formats = SNDRV_PCM_FMTBIT_S16_LE, 41 .formats = SNDRV_PCM_FMTBIT_S16_LE |
42 SNDRV_PCM_FMTBIT_S32_LE,
41 .period_bytes_min = 32, 43 .period_bytes_min = 32,
42 .period_bytes_max = 64 * 1024, 44 .period_bytes_max = 64 * 1024,
43 .periods_min = 2, 45 .periods_min = 2,
@@ -59,12 +61,11 @@ static void omap_pcm_dma_irq(int ch, u16 stat, void *data)
59 struct omap_runtime_data *prtd = runtime->private_data; 61 struct omap_runtime_data *prtd = runtime->private_data;
60 unsigned long flags; 62 unsigned long flags;
61 63
62 if ((cpu_is_omap1510()) && 64 if ((cpu_is_omap1510())) {
63 (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)) {
64 /* 65 /*
65 * OMAP1510 doesn't fully support DMA progress counter 66 * OMAP1510 doesn't fully support DMA progress counter
66 * and there is no software emulation implemented yet, 67 * and there is no software emulation implemented yet,
67 * so have to maintain our own playback progress counter 68 * so have to maintain our own progress counters
68 * that can be used by omap_pcm_pointer() instead. 69 * that can be used by omap_pcm_pointer() instead.
69 */ 70 */
70 spin_lock_irqsave(&prtd->lock, flags); 71 spin_lock_irqsave(&prtd->lock, flags);
@@ -99,9 +100,11 @@ static int omap_pcm_hw_params(struct snd_pcm_substream *substream,
99 struct snd_pcm_runtime *runtime = substream->runtime; 100 struct snd_pcm_runtime *runtime = substream->runtime;
100 struct snd_soc_pcm_runtime *rtd = substream->private_data; 101 struct snd_soc_pcm_runtime *rtd = substream->private_data;
101 struct omap_runtime_data *prtd = runtime->private_data; 102 struct omap_runtime_data *prtd = runtime->private_data;
102 struct omap_pcm_dma_data *dma_data = rtd->dai->cpu_dai->dma_data; 103 struct omap_pcm_dma_data *dma_data;
103 int err = 0; 104 int err = 0;
104 105
106 dma_data = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
107
105 /* return if this is a bufferless transfer e.g. 108 /* return if this is a bufferless transfer e.g.
106 * codec <--> BT codec or GSM modem -- lg FIXME */ 109 * codec <--> BT codec or GSM modem -- lg FIXME */
107 if (!dma_data) 110 if (!dma_data)
@@ -149,6 +152,7 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream)
149 struct omap_runtime_data *prtd = runtime->private_data; 152 struct omap_runtime_data *prtd = runtime->private_data;
150 struct omap_pcm_dma_data *dma_data = prtd->dma_data; 153 struct omap_pcm_dma_data *dma_data = prtd->dma_data;
151 struct omap_dma_channel_params dma_params; 154 struct omap_dma_channel_params dma_params;
155 int bytes;
152 156
153 /* return if this is a bufferless transfer e.g. 157 /* return if this is a bufferless transfer e.g.
154 * codec <--> BT codec or GSM modem -- lg FIXME */ 158 * codec <--> BT codec or GSM modem -- lg FIXME */
@@ -156,11 +160,7 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream)
156 return 0; 160 return 0;
157 161
158 memset(&dma_params, 0, sizeof(dma_params)); 162 memset(&dma_params, 0, sizeof(dma_params));
159 /* 163 dma_params.data_type = dma_data->data_type;
160 * Note: Regardless of interface data formats supported by OMAP McBSP
161 * or EAC blocks, internal representation is always fixed 16-bit/sample
162 */
163 dma_params.data_type = OMAP_DMA_DATA_TYPE_S16;
164 dma_params.trigger = dma_data->dma_req; 164 dma_params.trigger = dma_data->dma_req;
165 dma_params.sync_mode = dma_data->sync_mode; 165 dma_params.sync_mode = dma_data->sync_mode;
166 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 166 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
@@ -170,6 +170,7 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream)
170 dma_params.src_start = runtime->dma_addr; 170 dma_params.src_start = runtime->dma_addr;
171 dma_params.dst_start = dma_data->port_addr; 171 dma_params.dst_start = dma_data->port_addr;
172 dma_params.dst_port = OMAP_DMA_PORT_MPUI; 172 dma_params.dst_port = OMAP_DMA_PORT_MPUI;
173 dma_params.dst_fi = dma_data->packet_size;
173 } else { 174 } else {
174 dma_params.src_amode = OMAP_DMA_AMODE_CONSTANT; 175 dma_params.src_amode = OMAP_DMA_AMODE_CONSTANT;
175 dma_params.dst_amode = OMAP_DMA_AMODE_POST_INC; 176 dma_params.dst_amode = OMAP_DMA_AMODE_POST_INC;
@@ -177,6 +178,7 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream)
177 dma_params.src_start = dma_data->port_addr; 178 dma_params.src_start = dma_data->port_addr;
178 dma_params.dst_start = runtime->dma_addr; 179 dma_params.dst_start = runtime->dma_addr;
179 dma_params.src_port = OMAP_DMA_PORT_MPUI; 180 dma_params.src_port = OMAP_DMA_PORT_MPUI;
181 dma_params.src_fi = dma_data->packet_size;
180 } 182 }
181 /* 183 /*
182 * Set DMA transfer frame size equal to ALSA period size and frame 184 * Set DMA transfer frame size equal to ALSA period size and frame
@@ -184,12 +186,12 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream)
184 * we can transfer the whole ALSA buffer with single DMA transfer but 186 * we can transfer the whole ALSA buffer with single DMA transfer but
185 * still can get an interrupt at each period bounary 187 * still can get an interrupt at each period bounary
186 */ 188 */
187 dma_params.elem_count = snd_pcm_lib_period_bytes(substream) / 2; 189 bytes = snd_pcm_lib_period_bytes(substream);
190 dma_params.elem_count = bytes >> dma_data->data_type;
188 dma_params.frame_count = runtime->periods; 191 dma_params.frame_count = runtime->periods;
189 omap_set_dma_params(prtd->dma_ch, &dma_params); 192 omap_set_dma_params(prtd->dma_ch, &dma_params);
190 193
191 if ((cpu_is_omap1510()) && 194 if ((cpu_is_omap1510()))
192 (substream->stream == SNDRV_PCM_STREAM_PLAYBACK))
193 omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ | 195 omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ |
194 OMAP_DMA_LAST_IRQ | OMAP_DMA_BLOCK_IRQ); 196 OMAP_DMA_LAST_IRQ | OMAP_DMA_BLOCK_IRQ);
195 else 197 else
@@ -247,14 +249,15 @@ static snd_pcm_uframes_t omap_pcm_pointer(struct snd_pcm_substream *substream)
247 dma_addr_t ptr; 249 dma_addr_t ptr;
248 snd_pcm_uframes_t offset; 250 snd_pcm_uframes_t offset;
249 251
250 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { 252 if (cpu_is_omap1510()) {
253 offset = prtd->period_index * runtime->period_size;
254 } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
251 ptr = omap_get_dma_dst_pos(prtd->dma_ch); 255 ptr = omap_get_dma_dst_pos(prtd->dma_ch);
252 offset = bytes_to_frames(runtime, ptr - runtime->dma_addr); 256 offset = bytes_to_frames(runtime, ptr - runtime->dma_addr);
253 } else if (!(cpu_is_omap1510())) { 257 } else {
254 ptr = omap_get_dma_src_pos(prtd->dma_ch); 258 ptr = omap_get_dma_src_pos(prtd->dma_ch);
255 offset = bytes_to_frames(runtime, ptr - runtime->dma_addr); 259 offset = bytes_to_frames(runtime, ptr - runtime->dma_addr);
256 } else 260 }
257 offset = prtd->period_index * runtime->period_size;
258 261
259 if (offset >= runtime->buffer_size) 262 if (offset >= runtime->buffer_size)
260 offset = 0; 263 offset = 0;
diff --git a/sound/soc/omap/omap-pcm.h b/sound/soc/omap/omap-pcm.h
index 38a821dd4118..b19975d26907 100644
--- a/sound/soc/omap/omap-pcm.h
+++ b/sound/soc/omap/omap-pcm.h
@@ -29,8 +29,10 @@ struct omap_pcm_dma_data {
29 char *name; /* stream identifier */ 29 char *name; /* stream identifier */
30 int dma_req; /* DMA request line */ 30 int dma_req; /* DMA request line */
31 unsigned long port_addr; /* transmit/receive register */ 31 unsigned long port_addr; /* transmit/receive register */
32 int sync_mode; /* DMA sync mode */
33 void (*set_threshold)(struct snd_pcm_substream *substream); 32 void (*set_threshold)(struct snd_pcm_substream *substream);
33 int data_type; /* data type 8,16,32 */
34 int sync_mode; /* DMA sync mode */
35 int packet_size; /* packet size only in PACKET mode */
34}; 36};
35 37
36extern struct snd_soc_platform omap_soc_platform; 38extern struct snd_soc_platform omap_soc_platform;
diff --git a/sound/soc/omap/omap2evm.c b/sound/soc/omap/omap2evm.c
index 027e1a40f8a1..c7adea38274c 100644
--- a/sound/soc/omap/omap2evm.c
+++ b/sound/soc/omap/omap2evm.c
@@ -31,7 +31,7 @@
31#include <asm/mach-types.h> 31#include <asm/mach-types.h>
32#include <mach/hardware.h> 32#include <mach/hardware.h>
33#include <mach/gpio.h> 33#include <mach/gpio.h>
34#include <mach/mcbsp.h> 34#include <plat/mcbsp.h>
35 35
36#include "omap-mcbsp.h" 36#include "omap-mcbsp.h"
37#include "omap-pcm.h" 37#include "omap-pcm.h"
diff --git a/sound/soc/omap/omap3beagle.c b/sound/soc/omap/omap3beagle.c
index b0cff9f33b7e..240e0975dd6a 100644
--- a/sound/soc/omap/omap3beagle.c
+++ b/sound/soc/omap/omap3beagle.c
@@ -29,7 +29,7 @@
29#include <asm/mach-types.h> 29#include <asm/mach-types.h>
30#include <mach/hardware.h> 30#include <mach/hardware.h>
31#include <mach/gpio.h> 31#include <mach/gpio.h>
32#include <mach/mcbsp.h> 32#include <plat/mcbsp.h>
33 33
34#include "omap-mcbsp.h" 34#include "omap-mcbsp.h"
35#include "omap-pcm.h" 35#include "omap-pcm.h"
@@ -117,11 +117,11 @@ static int __init omap3beagle_soc_init(void)
117{ 117{
118 int ret; 118 int ret;
119 119
120 if (!machine_is_omap3_beagle()) { 120 if (!(machine_is_omap3_beagle() || machine_is_devkit8000())) {
121 pr_debug("Not OMAP3 Beagle!\n"); 121 pr_debug("Not OMAP3 Beagle or Devkit8000!\n");
122 return -ENODEV; 122 return -ENODEV;
123 } 123 }
124 pr_info("OMAP3 Beagle SoC init\n"); 124 pr_info("OMAP3 Beagle/Devkit8000 SoC init\n");
125 125
126 omap3beagle_snd_device = platform_device_alloc("soc-audio", -1); 126 omap3beagle_snd_device = platform_device_alloc("soc-audio", -1);
127 if (!omap3beagle_snd_device) { 127 if (!omap3beagle_snd_device) {
diff --git a/sound/soc/omap/omap3evm.c b/sound/soc/omap/omap3evm.c
index 13aa380de162..dfcb344092e4 100644
--- a/sound/soc/omap/omap3evm.c
+++ b/sound/soc/omap/omap3evm.c
@@ -27,7 +27,7 @@
27#include <asm/mach-types.h> 27#include <asm/mach-types.h>
28#include <mach/hardware.h> 28#include <mach/hardware.h>
29#include <mach/gpio.h> 29#include <mach/gpio.h>
30#include <mach/mcbsp.h> 30#include <plat/mcbsp.h>
31 31
32#include "omap-mcbsp.h" 32#include "omap-mcbsp.h"
33#include "omap-pcm.h" 33#include "omap-pcm.h"
@@ -93,10 +93,17 @@ static struct snd_soc_card snd_soc_omap3evm = {
93 .num_links = 1, 93 .num_links = 1,
94}; 94};
95 95
96/* twl4030 setup */
97static struct twl4030_setup_data twl4030_setup = {
98 .ramp_delay_value = 4,
99 .sysclk = 26000,
100};
101
96/* Audio subsystem */ 102/* Audio subsystem */
97static struct snd_soc_device omap3evm_snd_devdata = { 103static struct snd_soc_device omap3evm_snd_devdata = {
98 .card = &snd_soc_omap3evm, 104 .card = &snd_soc_omap3evm,
99 .codec_dev = &soc_codec_dev_twl4030, 105 .codec_dev = &soc_codec_dev_twl4030,
106 .codec_data = &twl4030_setup,
100}; 107};
101 108
102static struct platform_device *omap3evm_snd_device; 109static struct platform_device *omap3evm_snd_device;
diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c
index 0cd06f5dd356..de10f76baded 100644
--- a/sound/soc/omap/omap3pandora.c
+++ b/sound/soc/omap/omap3pandora.c
@@ -23,6 +23,7 @@
23#include <linux/platform_device.h> 23#include <linux/platform_device.h>
24#include <linux/gpio.h> 24#include <linux/gpio.h>
25#include <linux/delay.h> 25#include <linux/delay.h>
26#include <linux/regulator/consumer.h>
26 27
27#include <sound/core.h> 28#include <sound/core.h>
28#include <sound/pcm.h> 29#include <sound/pcm.h>
@@ -40,9 +41,14 @@
40 41
41#define PREFIX "ASoC omap3pandora: " 42#define PREFIX "ASoC omap3pandora: "
42 43
43static int omap3pandora_cmn_hw_params(struct snd_soc_dai *codec_dai, 44static struct regulator *omap3pandora_dac_reg;
44 struct snd_soc_dai *cpu_dai, unsigned int fmt) 45
46static int omap3pandora_cmn_hw_params(struct snd_pcm_substream *substream,
47 struct snd_pcm_hw_params *params, unsigned int fmt)
45{ 48{
49 struct snd_soc_pcm_runtime *rtd = substream->private_data;
50 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
51 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
46 int ret; 52 int ret;
47 53
48 /* Set codec DAI configuration */ 54 /* Set codec DAI configuration */
@@ -68,8 +74,9 @@ static int omap3pandora_cmn_hw_params(struct snd_soc_dai *codec_dai,
68 } 74 }
69 75
70 /* Set McBSP clock to external */ 76 /* Set McBSP clock to external */
71 ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_SYSCLK_CLKS_EXT, 0, 77 ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_SYSCLK_CLKS_EXT,
72 SND_SOC_CLOCK_IN); 78 256 * params_rate(params),
79 SND_SOC_CLOCK_IN);
73 if (ret < 0) { 80 if (ret < 0) {
74 pr_err(PREFIX "can't set cpu system clock\n"); 81 pr_err(PREFIX "can't set cpu system clock\n");
75 return ret; 82 return ret;
@@ -87,11 +94,7 @@ static int omap3pandora_cmn_hw_params(struct snd_soc_dai *codec_dai,
87static int omap3pandora_out_hw_params(struct snd_pcm_substream *substream, 94static int omap3pandora_out_hw_params(struct snd_pcm_substream *substream,
88 struct snd_pcm_hw_params *params) 95 struct snd_pcm_hw_params *params)
89{ 96{
90 struct snd_soc_pcm_runtime *rtd = substream->private_data; 97 return omap3pandora_cmn_hw_params(substream, params,
91 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
92 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
93
94 return omap3pandora_cmn_hw_params(codec_dai, cpu_dai,
95 SND_SOC_DAIFMT_I2S | 98 SND_SOC_DAIFMT_I2S |
96 SND_SOC_DAIFMT_IB_NF | 99 SND_SOC_DAIFMT_IB_NF |
97 SND_SOC_DAIFMT_CBS_CFS); 100 SND_SOC_DAIFMT_CBS_CFS);
@@ -100,31 +103,43 @@ static int omap3pandora_out_hw_params(struct snd_pcm_substream *substream,
100static int omap3pandora_in_hw_params(struct snd_pcm_substream *substream, 103static int omap3pandora_in_hw_params(struct snd_pcm_substream *substream,
101 struct snd_pcm_hw_params *params) 104 struct snd_pcm_hw_params *params)
102{ 105{
103 struct snd_soc_pcm_runtime *rtd = substream->private_data; 106 return omap3pandora_cmn_hw_params(substream, params,
104 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
105 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
106
107 return omap3pandora_cmn_hw_params(codec_dai, cpu_dai,
108 SND_SOC_DAIFMT_I2S | 107 SND_SOC_DAIFMT_I2S |
109 SND_SOC_DAIFMT_NB_NF | 108 SND_SOC_DAIFMT_NB_NF |
110 SND_SOC_DAIFMT_CBS_CFS); 109 SND_SOC_DAIFMT_CBS_CFS);
111} 110}
112 111
113static int omap3pandora_hp_event(struct snd_soc_dapm_widget *w, 112static int omap3pandora_dac_event(struct snd_soc_dapm_widget *w,
114 struct snd_kcontrol *k, int event) 113 struct snd_kcontrol *k, int event)
115{ 114{
115 /*
116 * The PCM1773 DAC datasheet requires 1ms delay between switching
117 * VCC power on/off and /PD pin high/low
118 */
116 if (SND_SOC_DAPM_EVENT_ON(event)) { 119 if (SND_SOC_DAPM_EVENT_ON(event)) {
120 regulator_enable(omap3pandora_dac_reg);
121 mdelay(1);
117 gpio_set_value(OMAP3_PANDORA_DAC_POWER_GPIO, 1); 122 gpio_set_value(OMAP3_PANDORA_DAC_POWER_GPIO, 1);
118 gpio_set_value(OMAP3_PANDORA_AMP_POWER_GPIO, 1);
119 } else { 123 } else {
120 gpio_set_value(OMAP3_PANDORA_AMP_POWER_GPIO, 0);
121 mdelay(1);
122 gpio_set_value(OMAP3_PANDORA_DAC_POWER_GPIO, 0); 124 gpio_set_value(OMAP3_PANDORA_DAC_POWER_GPIO, 0);
125 mdelay(1);
126 regulator_disable(omap3pandora_dac_reg);
123 } 127 }
124 128
125 return 0; 129 return 0;
126} 130}
127 131
132static int omap3pandora_hp_event(struct snd_soc_dapm_widget *w,
133 struct snd_kcontrol *k, int event)
134{
135 if (SND_SOC_DAPM_EVENT_ON(event))
136 gpio_set_value(OMAP3_PANDORA_AMP_POWER_GPIO, 1);
137 else
138 gpio_set_value(OMAP3_PANDORA_AMP_POWER_GPIO, 0);
139
140 return 0;
141}
142
128/* 143/*
129 * Audio paths on Pandora board: 144 * Audio paths on Pandora board:
130 * 145 *
@@ -134,7 +149,9 @@ static int omap3pandora_hp_event(struct snd_soc_dapm_widget *w,
134 * |P| <--- TWL4030 <--------- Line In and MICs 149 * |P| <--- TWL4030 <--------- Line In and MICs
135 */ 150 */
136static const struct snd_soc_dapm_widget omap3pandora_out_dapm_widgets[] = { 151static const struct snd_soc_dapm_widget omap3pandora_out_dapm_widgets[] = {
137 SND_SOC_DAPM_DAC("PCM DAC", "HiFi Playback", SND_SOC_NOPM, 0, 0), 152 SND_SOC_DAPM_DAC_E("PCM DAC", "HiFi Playback", SND_SOC_NOPM,
153 0, 0, omap3pandora_dac_event,
154 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
138 SND_SOC_DAPM_PGA_E("Headphone Amplifier", SND_SOC_NOPM, 155 SND_SOC_DAPM_PGA_E("Headphone Amplifier", SND_SOC_NOPM,
139 0, 0, NULL, 0, omap3pandora_hp_event, 156 0, 0, NULL, 0, omap3pandora_hp_event,
140 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 157 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
@@ -149,6 +166,7 @@ static const struct snd_soc_dapm_widget omap3pandora_in_dapm_widgets[] = {
149}; 166};
150 167
151static const struct snd_soc_dapm_route omap3pandora_out_map[] = { 168static const struct snd_soc_dapm_route omap3pandora_out_map[] = {
169 {"PCM DAC", NULL, "APLL Enable"},
152 {"Headphone Amplifier", NULL, "PCM DAC"}, 170 {"Headphone Amplifier", NULL, "PCM DAC"},
153 {"Line Out", NULL, "PCM DAC"}, 171 {"Line Out", NULL, "PCM DAC"},
154 {"Headphone Jack", NULL, "Headphone Amplifier"}, 172 {"Headphone Jack", NULL, "Headphone Amplifier"},
@@ -309,8 +327,18 @@ static int __init omap3pandora_soc_init(void)
309 goto fail2; 327 goto fail2;
310 } 328 }
311 329
330 omap3pandora_dac_reg = regulator_get(&omap3pandora_snd_device->dev, "vcc");
331 if (IS_ERR(omap3pandora_dac_reg)) {
332 pr_err(PREFIX "Failed to get DAC regulator from %s: %ld\n",
333 dev_name(&omap3pandora_snd_device->dev),
334 PTR_ERR(omap3pandora_dac_reg));
335 goto fail3;
336 }
337
312 return 0; 338 return 0;
313 339
340fail3:
341 platform_device_del(omap3pandora_snd_device);
314fail2: 342fail2:
315 platform_device_put(omap3pandora_snd_device); 343 platform_device_put(omap3pandora_snd_device);
316fail1: 344fail1:
@@ -323,6 +351,7 @@ module_init(omap3pandora_soc_init);
323 351
324static void __exit omap3pandora_soc_exit(void) 352static void __exit omap3pandora_soc_exit(void)
325{ 353{
354 regulator_put(omap3pandora_dac_reg);
326 platform_device_unregister(omap3pandora_snd_device); 355 platform_device_unregister(omap3pandora_snd_device);
327 gpio_free(OMAP3_PANDORA_AMP_POWER_GPIO); 356 gpio_free(OMAP3_PANDORA_AMP_POWER_GPIO);
328 gpio_free(OMAP3_PANDORA_DAC_POWER_GPIO); 357 gpio_free(OMAP3_PANDORA_DAC_POWER_GPIO);
diff --git a/sound/soc/omap/osk5912.c b/sound/soc/omap/osk5912.c
index a4e149b7f0eb..498ca2e03519 100644
--- a/sound/soc/omap/osk5912.c
+++ b/sound/soc/omap/osk5912.c
@@ -31,7 +31,7 @@
31#include <asm/mach-types.h> 31#include <asm/mach-types.h>
32#include <mach/hardware.h> 32#include <mach/hardware.h>
33#include <linux/gpio.h> 33#include <linux/gpio.h>
34#include <mach/mcbsp.h> 34#include <plat/mcbsp.h>
35 35
36#include "omap-mcbsp.h" 36#include "omap-mcbsp.h"
37#include "omap-pcm.h" 37#include "omap-pcm.h"
diff --git a/sound/soc/omap/overo.c b/sound/soc/omap/overo.c
index ec4f8fd8b3a2..c25f5276ad6f 100644
--- a/sound/soc/omap/overo.c
+++ b/sound/soc/omap/overo.c
@@ -29,7 +29,7 @@
29#include <asm/mach-types.h> 29#include <asm/mach-types.h>
30#include <mach/hardware.h> 30#include <mach/hardware.h>
31#include <mach/gpio.h> 31#include <mach/gpio.h>
32#include <mach/mcbsp.h> 32#include <plat/mcbsp.h>
33 33
34#include "omap-mcbsp.h" 34#include "omap-mcbsp.h"
35#include "omap-pcm.h" 35#include "omap-pcm.h"
@@ -107,8 +107,8 @@ static int __init overo_soc_init(void)
107{ 107{
108 int ret; 108 int ret;
109 109
110 if (!machine_is_overo()) { 110 if (!(machine_is_overo() || machine_is_cm_t35())) {
111 pr_debug("Not Overo!\n"); 111 pr_debug("Incomatible machine!\n");
112 return -ENODEV; 112 return -ENODEV;
113 } 113 }
114 printk(KERN_INFO "overo SoC init\n"); 114 printk(KERN_INFO "overo SoC init\n");
diff --git a/sound/soc/omap/sdp3430.c b/sound/soc/omap/sdp3430.c
index 4a3f62d1f295..3c85c0f92823 100644
--- a/sound/soc/omap/sdp3430.c
+++ b/sound/soc/omap/sdp3430.c
@@ -24,7 +24,7 @@
24 24
25#include <linux/clk.h> 25#include <linux/clk.h>
26#include <linux/platform_device.h> 26#include <linux/platform_device.h>
27#include <linux/i2c/twl4030.h> 27#include <linux/i2c/twl.h>
28#include <sound/core.h> 28#include <sound/core.h>
29#include <sound/pcm.h> 29#include <sound/pcm.h>
30#include <sound/soc.h> 30#include <sound/soc.h>
@@ -34,7 +34,7 @@
34#include <asm/mach-types.h> 34#include <asm/mach-types.h>
35#include <mach/hardware.h> 35#include <mach/hardware.h>
36#include <mach/gpio.h> 36#include <mach/gpio.h>
37#include <mach/mcbsp.h> 37#include <plat/mcbsp.h>
38 38
39#include "omap-mcbsp.h" 39#include "omap-mcbsp.h"
40#include "omap-pcm.h" 40#include "omap-pcm.h"
@@ -321,11 +321,11 @@ static int __init sdp3430_soc_init(void)
321 *(unsigned int *)sdp3430_dai[1].cpu_dai->private_data = 2; /* McBSP3 */ 321 *(unsigned int *)sdp3430_dai[1].cpu_dai->private_data = 2; /* McBSP3 */
322 322
323 /* Set TWL4030 GPIO6 as EXTMUTE signal */ 323 /* Set TWL4030 GPIO6 as EXTMUTE signal */
324 twl4030_i2c_read_u8(TWL4030_MODULE_INTBR, &pin_mux, 324 twl_i2c_read_u8(TWL4030_MODULE_INTBR, &pin_mux,
325 TWL4030_INTBR_PMBR1); 325 TWL4030_INTBR_PMBR1);
326 pin_mux &= ~TWL4030_GPIO6_PWM0_MUTE(0x03); 326 pin_mux &= ~TWL4030_GPIO6_PWM0_MUTE(0x03);
327 pin_mux |= TWL4030_GPIO6_PWM0_MUTE(0x02); 327 pin_mux |= TWL4030_GPIO6_PWM0_MUTE(0x02);
328 twl4030_i2c_write_u8(TWL4030_MODULE_INTBR, pin_mux, 328 twl_i2c_write_u8(TWL4030_MODULE_INTBR, pin_mux,
329 TWL4030_INTBR_PMBR1); 329 TWL4030_INTBR_PMBR1);
330 330
331 ret = platform_device_add(sdp3430_snd_device); 331 ret = platform_device_add(sdp3430_snd_device);
diff --git a/sound/soc/omap/zoom2.c b/sound/soc/omap/zoom2.c
index f90b45f56220..f90a2ac888cf 100644
--- a/sound/soc/omap/zoom2.c
+++ b/sound/soc/omap/zoom2.c
@@ -29,7 +29,7 @@
29#include <asm/mach-types.h> 29#include <asm/mach-types.h>
30#include <mach/hardware.h> 30#include <mach/hardware.h>
31#include <mach/gpio.h> 31#include <mach/gpio.h>
32#include <mach/mcbsp.h> 32#include <plat/mcbsp.h>
33 33
34#include "omap-mcbsp.h" 34#include "omap-mcbsp.h"
35#include "omap-pcm.h" 35#include "omap-pcm.h"
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig
index dcb3181bb340..376e14a9c273 100644
--- a/sound/soc/pxa/Kconfig
+++ b/sound/soc/pxa/Kconfig
@@ -90,7 +90,8 @@ config SND_PXA2XX_SOC_E800
90 90
91config SND_PXA2XX_SOC_EM_X270 91config SND_PXA2XX_SOC_EM_X270
92 tristate "SoC Audio support for CompuLab EM-x270, eXeda and CM-X300" 92 tristate "SoC Audio support for CompuLab EM-x270, eXeda and CM-X300"
93 depends on SND_PXA2XX_SOC && MACH_EM_X270 93 depends on SND_PXA2XX_SOC && (MACH_EM_X270 || MACH_EXEDA || \
94 MACH_CM_X300)
94 select SND_PXA2XX_SOC_AC97 95 select SND_PXA2XX_SOC_AC97
95 select SND_SOC_WM9712 96 select SND_SOC_WM9712
96 help 97 help
@@ -117,6 +118,15 @@ config SND_SOC_ZYLONITE
117 Say Y if you want to add support for SoC audio on the 118 Say Y if you want to add support for SoC audio on the
118 Marvell Zylonite reference platform. 119 Marvell Zylonite reference platform.
119 120
121config SND_SOC_RAUMFELD
122 tristate "SoC Audio support Raumfeld audio adapter"
123 depends on SND_PXA2XX_SOC && (MACH_RAUMFELD_SPEAKER || MACH_RAUMFELD_CONNECTOR)
124 select SND_PXA_SOC_SSP
125 select SND_SOC_CS4270
126 select SND_SOC_AK4104
127 help
128 Say Y if you want to add support for SoC audio on Raumfeld devices
129
120config SND_PXA2XX_SOC_MAGICIAN 130config SND_PXA2XX_SOC_MAGICIAN
121 tristate "SoC Audio support for HTC Magician" 131 tristate "SoC Audio support for HTC Magician"
122 depends on SND_PXA2XX_SOC && MACH_MAGICIAN 132 depends on SND_PXA2XX_SOC && MACH_MAGICIAN
diff --git a/sound/soc/pxa/Makefile b/sound/soc/pxa/Makefile
index 6e096b480335..f3e08fd40ca2 100644
--- a/sound/soc/pxa/Makefile
+++ b/sound/soc/pxa/Makefile
@@ -23,6 +23,7 @@ snd-soc-zylonite-objs := zylonite.o
23snd-soc-magician-objs := magician.o 23snd-soc-magician-objs := magician.o
24snd-soc-mioa701-objs := mioa701_wm9713.o 24snd-soc-mioa701-objs := mioa701_wm9713.o
25snd-soc-imote2-objs := imote2.o 25snd-soc-imote2-objs := imote2.o
26snd-soc-raumfeld-objs := raumfeld.o
26 27
27obj-$(CONFIG_SND_PXA2XX_SOC_CORGI) += snd-soc-corgi.o 28obj-$(CONFIG_SND_PXA2XX_SOC_CORGI) += snd-soc-corgi.o
28obj-$(CONFIG_SND_PXA2XX_SOC_POODLE) += snd-soc-poodle.o 29obj-$(CONFIG_SND_PXA2XX_SOC_POODLE) += snd-soc-poodle.o
@@ -37,3 +38,4 @@ obj-$(CONFIG_SND_PXA2XX_SOC_MAGICIAN) += snd-soc-magician.o
37obj-$(CONFIG_SND_PXA2XX_SOC_MIOA701) += snd-soc-mioa701.o 38obj-$(CONFIG_SND_PXA2XX_SOC_MIOA701) += snd-soc-mioa701.o
38obj-$(CONFIG_SND_SOC_ZYLONITE) += snd-soc-zylonite.o 39obj-$(CONFIG_SND_SOC_ZYLONITE) += snd-soc-zylonite.o
39obj-$(CONFIG_SND_PXA2XX_SOC_IMOTE2) += snd-soc-imote2.o 40obj-$(CONFIG_SND_PXA2XX_SOC_IMOTE2) += snd-soc-imote2.o
41obj-$(CONFIG_SND_SOC_RAUMFELD) += snd-soc-raumfeld.o
diff --git a/sound/soc/pxa/magician.c b/sound/soc/pxa/magician.c
index 9f7c61e23daf..4c8d99a8d386 100644
--- a/sound/soc/pxa/magician.c
+++ b/sound/soc/pxa/magician.c
@@ -213,7 +213,7 @@ static int magician_playback_hw_params(struct snd_pcm_substream *substream,
213 return ret; 213 return ret;
214 214
215 /* set SSP audio pll clock */ 215 /* set SSP audio pll clock */
216 ret = snd_soc_dai_set_pll(cpu_dai, 0, 0, acps); 216 ret = snd_soc_dai_set_pll(cpu_dai, 0, 0, 0, acps);
217 if (ret < 0) 217 if (ret < 0)
218 return ret; 218 return ret;
219 219
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
index d11a6d7e384a..544fd9566f4d 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>
@@ -42,11 +43,14 @@
42 * SSP audio private data 43 * SSP audio private data
43 */ 44 */
44struct ssp_priv { 45struct ssp_priv {
45 struct ssp_dev dev; 46 struct ssp_device *ssp;
46 unsigned int sysclk; 47 unsigned int sysclk;
47 int dai_fmt; 48 int dai_fmt;
48#ifdef CONFIG_PM 49#ifdef CONFIG_PM
49 struct ssp_state state; 50 uint32_t cr0;
51 uint32_t cr1;
52 uint32_t to;
53 uint32_t psp;
50#endif 54#endif
51}; 55};
52 56
@@ -61,6 +65,22 @@ static void dump_registers(struct ssp_device *ssp)
61 ssp_read_reg(ssp, SSACD)); 65 ssp_read_reg(ssp, SSACD));
62} 66}
63 67
68static void ssp_enable(struct ssp_device *ssp)
69{
70 uint32_t sscr0;
71
72 sscr0 = __raw_readl(ssp->mmio_base + SSCR0) | SSCR0_SSE;
73 __raw_writel(sscr0, ssp->mmio_base + SSCR0);
74}
75
76static void ssp_disable(struct ssp_device *ssp)
77{
78 uint32_t sscr0;
79
80 sscr0 = __raw_readl(ssp->mmio_base + SSCR0) & ~SSCR0_SSE;
81 __raw_writel(sscr0, ssp->mmio_base + SSCR0);
82}
83
64struct pxa2xx_pcm_dma_data { 84struct pxa2xx_pcm_dma_data {
65 struct pxa2xx_pcm_dma_params params; 85 struct pxa2xx_pcm_dma_params params;
66 char name[20]; 86 char name[20];
@@ -94,19 +114,17 @@ static int pxa_ssp_startup(struct snd_pcm_substream *substream,
94 struct snd_soc_pcm_runtime *rtd = substream->private_data; 114 struct snd_soc_pcm_runtime *rtd = substream->private_data;
95 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 115 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
96 struct ssp_priv *priv = cpu_dai->private_data; 116 struct ssp_priv *priv = cpu_dai->private_data;
117 struct ssp_device *ssp = priv->ssp;
97 int ret = 0; 118 int ret = 0;
98 119
99 if (!cpu_dai->active) { 120 if (!cpu_dai->active) {
100 priv->dev.port = cpu_dai->id + 1; 121 clk_enable(ssp->clk);
101 priv->dev.irq = NO_IRQ; 122 ssp_disable(ssp);
102 clk_enable(priv->dev.ssp->clk);
103 ssp_disable(&priv->dev);
104 } 123 }
105 124
106 if (cpu_dai->dma_data) { 125 kfree(snd_soc_dai_get_dma_data(cpu_dai, substream));
107 kfree(cpu_dai->dma_data); 126 snd_soc_dai_set_dma_data(cpu_dai, substream, NULL);
108 cpu_dai->dma_data = NULL; 127
109 }
110 return ret; 128 return ret;
111} 129}
112 130
@@ -116,16 +134,15 @@ static void pxa_ssp_shutdown(struct snd_pcm_substream *substream,
116 struct snd_soc_pcm_runtime *rtd = substream->private_data; 134 struct snd_soc_pcm_runtime *rtd = substream->private_data;
117 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 135 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
118 struct ssp_priv *priv = cpu_dai->private_data; 136 struct ssp_priv *priv = cpu_dai->private_data;
137 struct ssp_device *ssp = priv->ssp;
119 138
120 if (!cpu_dai->active) { 139 if (!cpu_dai->active) {
121 ssp_disable(&priv->dev); 140 ssp_disable(ssp);
122 clk_disable(priv->dev.ssp->clk); 141 clk_disable(ssp->clk);
123 } 142 }
124 143
125 if (cpu_dai->dma_data) { 144 kfree(snd_soc_dai_get_dma_data(cpu_dai, substream));
126 kfree(cpu_dai->dma_data); 145 snd_soc_dai_set_dma_data(cpu_dai, substream, NULL);
127 cpu_dai->dma_data = NULL;
128 }
129} 146}
130 147
131#ifdef CONFIG_PM 148#ifdef CONFIG_PM
@@ -133,25 +150,39 @@ static void pxa_ssp_shutdown(struct snd_pcm_substream *substream,
133static int pxa_ssp_suspend(struct snd_soc_dai *cpu_dai) 150static int pxa_ssp_suspend(struct snd_soc_dai *cpu_dai)
134{ 151{
135 struct ssp_priv *priv = cpu_dai->private_data; 152 struct ssp_priv *priv = cpu_dai->private_data;
153 struct ssp_device *ssp = priv->ssp;
136 154
137 if (!cpu_dai->active) 155 if (!cpu_dai->active)
138 return 0; 156 clk_enable(ssp->clk);
157
158 priv->cr0 = __raw_readl(ssp->mmio_base + SSCR0);
159 priv->cr1 = __raw_readl(ssp->mmio_base + SSCR1);
160 priv->to = __raw_readl(ssp->mmio_base + SSTO);
161 priv->psp = __raw_readl(ssp->mmio_base + SSPSP);
139 162
140 ssp_save_state(&priv->dev, &priv->state); 163 ssp_disable(ssp);
141 clk_disable(priv->dev.ssp->clk); 164 clk_disable(ssp->clk);
142 return 0; 165 return 0;
143} 166}
144 167
145static int pxa_ssp_resume(struct snd_soc_dai *cpu_dai) 168static int pxa_ssp_resume(struct snd_soc_dai *cpu_dai)
146{ 169{
147 struct ssp_priv *priv = cpu_dai->private_data; 170 struct ssp_priv *priv = cpu_dai->private_data;
171 struct ssp_device *ssp = priv->ssp;
172 uint32_t sssr = SSSR_ROR | SSSR_TUR | SSSR_BCE;
148 173
149 if (!cpu_dai->active) 174 clk_enable(ssp->clk);
150 return 0;
151 175
152 clk_enable(priv->dev.ssp->clk); 176 __raw_writel(sssr, ssp->mmio_base + SSSR);
153 ssp_restore_state(&priv->dev, &priv->state); 177 __raw_writel(priv->cr0 & ~SSCR0_SSE, ssp->mmio_base + SSCR0);
154 ssp_enable(&priv->dev); 178 __raw_writel(priv->cr1, ssp->mmio_base + SSCR1);
179 __raw_writel(priv->to, ssp->mmio_base + SSTO);
180 __raw_writel(priv->psp, ssp->mmio_base + SSPSP);
181
182 if (cpu_dai->active)
183 ssp_enable(ssp);
184 else
185 clk_disable(ssp->clk);
155 186
156 return 0; 187 return 0;
157} 188}
@@ -201,7 +232,7 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
201 int clk_id, unsigned int freq, int dir) 232 int clk_id, unsigned int freq, int dir)
202{ 233{
203 struct ssp_priv *priv = cpu_dai->private_data; 234 struct ssp_priv *priv = cpu_dai->private_data;
204 struct ssp_device *ssp = priv->dev.ssp; 235 struct ssp_device *ssp = priv->ssp;
205 int val; 236 int val;
206 237
207 u32 sscr0 = ssp_read_reg(ssp, SSCR0) & 238 u32 sscr0 = ssp_read_reg(ssp, SSCR0) &
@@ -242,11 +273,11 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
242 /* The SSP clock must be disabled when changing SSP clock mode 273 /* The SSP clock must be disabled when changing SSP clock mode
243 * on PXA2xx. On PXA3xx it must be enabled when doing so. */ 274 * on PXA2xx. On PXA3xx it must be enabled when doing so. */
244 if (!cpu_is_pxa3xx()) 275 if (!cpu_is_pxa3xx())
245 clk_disable(priv->dev.ssp->clk); 276 clk_disable(ssp->clk);
246 val = ssp_read_reg(ssp, SSCR0) | sscr0; 277 val = ssp_read_reg(ssp, SSCR0) | sscr0;
247 ssp_write_reg(ssp, SSCR0, val); 278 ssp_write_reg(ssp, SSCR0, val);
248 if (!cpu_is_pxa3xx()) 279 if (!cpu_is_pxa3xx())
249 clk_enable(priv->dev.ssp->clk); 280 clk_enable(ssp->clk);
250 281
251 return 0; 282 return 0;
252} 283}
@@ -258,7 +289,7 @@ static int pxa_ssp_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
258 int div_id, int div) 289 int div_id, int div)
259{ 290{
260 struct ssp_priv *priv = cpu_dai->private_data; 291 struct ssp_priv *priv = cpu_dai->private_data;
261 struct ssp_device *ssp = priv->dev.ssp; 292 struct ssp_device *ssp = priv->ssp;
262 int val; 293 int val;
263 294
264 switch (div_id) { 295 switch (div_id) {
@@ -305,11 +336,11 @@ static int pxa_ssp_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
305/* 336/*
306 * Configure the PLL frequency pxa27x and (afaik - pxa320 only) 337 * Configure the PLL frequency pxa27x and (afaik - pxa320 only)
307 */ 338 */
308static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, 339static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id,
309 int pll_id, unsigned int freq_in, unsigned int freq_out) 340 int source, unsigned int freq_in, unsigned int freq_out)
310{ 341{
311 struct ssp_priv *priv = cpu_dai->private_data; 342 struct ssp_priv *priv = cpu_dai->private_data;
312 struct ssp_device *ssp = priv->dev.ssp; 343 struct ssp_device *ssp = priv->ssp;
313 u32 ssacd = ssp_read_reg(ssp, SSACD) & ~0x70; 344 u32 ssacd = ssp_read_reg(ssp, SSACD) & ~0x70;
314 345
315#if defined(CONFIG_PXA3xx) 346#if defined(CONFIG_PXA3xx)
@@ -378,7 +409,7 @@ static int pxa_ssp_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai,
378 unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width) 409 unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
379{ 410{
380 struct ssp_priv *priv = cpu_dai->private_data; 411 struct ssp_priv *priv = cpu_dai->private_data;
381 struct ssp_device *ssp = priv->dev.ssp; 412 struct ssp_device *ssp = priv->ssp;
382 u32 sscr0; 413 u32 sscr0;
383 414
384 sscr0 = ssp_read_reg(ssp, SSCR0); 415 sscr0 = ssp_read_reg(ssp, SSCR0);
@@ -413,7 +444,7 @@ static int pxa_ssp_set_dai_tristate(struct snd_soc_dai *cpu_dai,
413 int tristate) 444 int tristate)
414{ 445{
415 struct ssp_priv *priv = cpu_dai->private_data; 446 struct ssp_priv *priv = cpu_dai->private_data;
416 struct ssp_device *ssp = priv->dev.ssp; 447 struct ssp_device *ssp = priv->ssp;
417 u32 sscr1; 448 u32 sscr1;
418 449
419 sscr1 = ssp_read_reg(ssp, SSCR1); 450 sscr1 = ssp_read_reg(ssp, SSCR1);
@@ -435,7 +466,7 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
435 unsigned int fmt) 466 unsigned int fmt)
436{ 467{
437 struct ssp_priv *priv = cpu_dai->private_data; 468 struct ssp_priv *priv = cpu_dai->private_data;
438 struct ssp_device *ssp = priv->dev.ssp; 469 struct ssp_device *ssp = priv->ssp;
439 u32 sscr0; 470 u32 sscr0;
440 u32 sscr1; 471 u32 sscr1;
441 u32 sspsp; 472 u32 sspsp;
@@ -530,25 +561,29 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
530 struct snd_soc_pcm_runtime *rtd = substream->private_data; 561 struct snd_soc_pcm_runtime *rtd = substream->private_data;
531 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 562 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
532 struct ssp_priv *priv = cpu_dai->private_data; 563 struct ssp_priv *priv = cpu_dai->private_data;
533 struct ssp_device *ssp = priv->dev.ssp; 564 struct ssp_device *ssp = priv->ssp;
534 int chn = params_channels(params); 565 int chn = params_channels(params);
535 u32 sscr0; 566 u32 sscr0;
536 u32 sspsp; 567 u32 sspsp;
537 int width = snd_pcm_format_physical_width(params_format(params)); 568 int width = snd_pcm_format_physical_width(params_format(params));
538 int ttsa = ssp_read_reg(ssp, SSTSA) & 0xf; 569 int ttsa = ssp_read_reg(ssp, SSTSA) & 0xf;
570 struct pxa2xx_pcm_dma_params *dma_data;
571
572 dma_data = snd_soc_dai_get_dma_data(dai, substream);
539 573
540 /* generate correct DMA params */ 574 /* generate correct DMA params */
541 if (cpu_dai->dma_data) 575 kfree(dma_data);
542 kfree(cpu_dai->dma_data);
543 576
544 /* Network mode with one active slot (ttsa == 1) can be used 577 /* Network mode with one active slot (ttsa == 1) can be used
545 * to force 16-bit frame width on the wire (for S16_LE), even 578 * to force 16-bit frame width on the wire (for S16_LE), even
546 * with two channels. Use 16-bit DMA transfers for this case. 579 * with two channels. Use 16-bit DMA transfers for this case.
547 */ 580 */
548 cpu_dai->dma_data = ssp_get_dma_params(ssp, 581 dma_data = ssp_get_dma_params(ssp,
549 ((chn == 2) && (ttsa != 1)) || (width == 32), 582 ((chn == 2) && (ttsa != 1)) || (width == 32),
550 substream->stream == SNDRV_PCM_STREAM_PLAYBACK); 583 substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
551 584
585 snd_soc_dai_set_dma_data(dai, substream, dma_data);
586
552 /* we can only change the settings if the port is not in use */ 587 /* we can only change the settings if the port is not in use */
553 if (ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) 588 if (ssp_read_reg(ssp, SSCR0) & SSCR0_SSE)
554 return 0; 589 return 0;
@@ -640,12 +675,12 @@ static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd,
640 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 675 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
641 int ret = 0; 676 int ret = 0;
642 struct ssp_priv *priv = cpu_dai->private_data; 677 struct ssp_priv *priv = cpu_dai->private_data;
643 struct ssp_device *ssp = priv->dev.ssp; 678 struct ssp_device *ssp = priv->ssp;
644 int val; 679 int val;
645 680
646 switch (cmd) { 681 switch (cmd) {
647 case SNDRV_PCM_TRIGGER_RESUME: 682 case SNDRV_PCM_TRIGGER_RESUME:
648 ssp_enable(&priv->dev); 683 ssp_enable(ssp);
649 break; 684 break;
650 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 685 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
651 val = ssp_read_reg(ssp, SSCR1); 686 val = ssp_read_reg(ssp, SSCR1);
@@ -664,7 +699,7 @@ static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd,
664 else 699 else
665 val |= SSCR1_RSRE; 700 val |= SSCR1_RSRE;
666 ssp_write_reg(ssp, SSCR1, val); 701 ssp_write_reg(ssp, SSCR1, val);
667 ssp_enable(&priv->dev); 702 ssp_enable(ssp);
668 break; 703 break;
669 case SNDRV_PCM_TRIGGER_STOP: 704 case SNDRV_PCM_TRIGGER_STOP:
670 val = ssp_read_reg(ssp, SSCR1); 705 val = ssp_read_reg(ssp, SSCR1);
@@ -675,7 +710,7 @@ static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd,
675 ssp_write_reg(ssp, SSCR1, val); 710 ssp_write_reg(ssp, SSCR1, val);
676 break; 711 break;
677 case SNDRV_PCM_TRIGGER_SUSPEND: 712 case SNDRV_PCM_TRIGGER_SUSPEND:
678 ssp_disable(&priv->dev); 713 ssp_disable(ssp);
679 break; 714 break;
680 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 715 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
681 val = ssp_read_reg(ssp, SSCR1); 716 val = ssp_read_reg(ssp, SSCR1);
@@ -705,8 +740,8 @@ static int pxa_ssp_probe(struct platform_device *pdev,
705 if (!priv) 740 if (!priv)
706 return -ENOMEM; 741 return -ENOMEM;
707 742
708 priv->dev.ssp = ssp_request(dai->id + 1, "SoC audio"); 743 priv->ssp = ssp_request(dai->id + 1, "SoC audio");
709 if (priv->dev.ssp == NULL) { 744 if (priv->ssp == NULL) {
710 ret = -ENODEV; 745 ret = -ENODEV;
711 goto err_priv; 746 goto err_priv;
712 } 747 }
@@ -725,7 +760,7 @@ static void pxa_ssp_remove(struct platform_device *pdev,
725 struct snd_soc_dai *dai) 760 struct snd_soc_dai *dai)
726{ 761{
727 struct ssp_priv *priv = dai->private_data; 762 struct ssp_priv *priv = dai->private_data;
728 ssp_free(priv->dev.ssp); 763 ssp_free(priv->ssp);
729} 764}
730 765
731#define PXA_SSP_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ 766#define PXA_SSP_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
@@ -760,13 +795,13 @@ struct snd_soc_dai pxa_ssp_dai[] = {
760 .resume = pxa_ssp_resume, 795 .resume = pxa_ssp_resume,
761 .playback = { 796 .playback = {
762 .channels_min = 1, 797 .channels_min = 1,
763 .channels_max = 2, 798 .channels_max = 8,
764 .rates = PXA_SSP_RATES, 799 .rates = PXA_SSP_RATES,
765 .formats = PXA_SSP_FORMATS, 800 .formats = PXA_SSP_FORMATS,
766 }, 801 },
767 .capture = { 802 .capture = {
768 .channels_min = 1, 803 .channels_min = 1,
769 .channels_max = 2, 804 .channels_max = 8,
770 .rates = PXA_SSP_RATES, 805 .rates = PXA_SSP_RATES,
771 .formats = PXA_SSP_FORMATS, 806 .formats = PXA_SSP_FORMATS,
772 }, 807 },
@@ -780,13 +815,13 @@ struct snd_soc_dai pxa_ssp_dai[] = {
780 .resume = pxa_ssp_resume, 815 .resume = pxa_ssp_resume,
781 .playback = { 816 .playback = {
782 .channels_min = 1, 817 .channels_min = 1,
783 .channels_max = 2, 818 .channels_max = 8,
784 .rates = PXA_SSP_RATES, 819 .rates = PXA_SSP_RATES,
785 .formats = PXA_SSP_FORMATS, 820 .formats = PXA_SSP_FORMATS,
786 }, 821 },
787 .capture = { 822 .capture = {
788 .channels_min = 1, 823 .channels_min = 1,
789 .channels_max = 2, 824 .channels_max = 8,
790 .rates = PXA_SSP_RATES, 825 .rates = PXA_SSP_RATES,
791 .formats = PXA_SSP_FORMATS, 826 .formats = PXA_SSP_FORMATS,
792 }, 827 },
@@ -801,13 +836,13 @@ struct snd_soc_dai pxa_ssp_dai[] = {
801 .resume = pxa_ssp_resume, 836 .resume = pxa_ssp_resume,
802 .playback = { 837 .playback = {
803 .channels_min = 1, 838 .channels_min = 1,
804 .channels_max = 2, 839 .channels_max = 8,
805 .rates = PXA_SSP_RATES, 840 .rates = PXA_SSP_RATES,
806 .formats = PXA_SSP_FORMATS, 841 .formats = PXA_SSP_FORMATS,
807 }, 842 },
808 .capture = { 843 .capture = {
809 .channels_min = 1, 844 .channels_min = 1,
810 .channels_max = 2, 845 .channels_max = 8,
811 .rates = PXA_SSP_RATES, 846 .rates = PXA_SSP_RATES,
812 .formats = PXA_SSP_FORMATS, 847 .formats = PXA_SSP_FORMATS,
813 }, 848 },
@@ -822,13 +857,13 @@ struct snd_soc_dai pxa_ssp_dai[] = {
822 .resume = pxa_ssp_resume, 857 .resume = pxa_ssp_resume,
823 .playback = { 858 .playback = {
824 .channels_min = 1, 859 .channels_min = 1,
825 .channels_max = 2, 860 .channels_max = 8,
826 .rates = PXA_SSP_RATES, 861 .rates = PXA_SSP_RATES,
827 .formats = PXA_SSP_FORMATS, 862 .formats = PXA_SSP_FORMATS,
828 }, 863 },
829 .capture = { 864 .capture = {
830 .channels_min = 1, 865 .channels_min = 1,
831 .channels_max = 2, 866 .channels_max = 8,
832 .rates = PXA_SSP_RATES, 867 .rates = PXA_SSP_RATES,
833 .formats = PXA_SSP_FORMATS, 868 .formats = PXA_SSP_FORMATS,
834 }, 869 },
diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c
index e9ae7b3a7e00..d314115e3dd7 100644
--- a/sound/soc/pxa/pxa2xx-ac97.c
+++ b/sound/soc/pxa/pxa2xx-ac97.c
@@ -122,11 +122,14 @@ static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream,
122{ 122{
123 struct snd_soc_pcm_runtime *rtd = substream->private_data; 123 struct snd_soc_pcm_runtime *rtd = substream->private_data;
124 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 124 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
125 struct pxa2xx_pcm_dma_params *dma_data;
125 126
126 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 127 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
127 cpu_dai->dma_data = &pxa2xx_ac97_pcm_stereo_out; 128 dma_data = &pxa2xx_ac97_pcm_stereo_out;
128 else 129 else
129 cpu_dai->dma_data = &pxa2xx_ac97_pcm_stereo_in; 130 dma_data = &pxa2xx_ac97_pcm_stereo_in;
131
132 snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
130 133
131 return 0; 134 return 0;
132} 135}
@@ -137,11 +140,14 @@ static int pxa2xx_ac97_hw_aux_params(struct snd_pcm_substream *substream,
137{ 140{
138 struct snd_soc_pcm_runtime *rtd = substream->private_data; 141 struct snd_soc_pcm_runtime *rtd = substream->private_data;
139 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 142 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
143 struct pxa2xx_pcm_dma_params *dma_data;
140 144
141 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 145 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
142 cpu_dai->dma_data = &pxa2xx_ac97_pcm_aux_mono_out; 146 dma_data = &pxa2xx_ac97_pcm_aux_mono_out;
143 else 147 else
144 cpu_dai->dma_data = &pxa2xx_ac97_pcm_aux_mono_in; 148 dma_data = &pxa2xx_ac97_pcm_aux_mono_in;
149
150 snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
145 151
146 return 0; 152 return 0;
147} 153}
@@ -156,7 +162,8 @@ static int pxa2xx_ac97_hw_mic_params(struct snd_pcm_substream *substream,
156 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 162 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
157 return -ENODEV; 163 return -ENODEV;
158 else 164 else
159 cpu_dai->dma_data = &pxa2xx_ac97_pcm_mic_mono_in; 165 snd_soc_dai_set_dma_data(cpu_dai, substream,
166 &pxa2xx_ac97_pcm_mic_mono_in);
160 167
161 return 0; 168 return 0;
162} 169}
diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c
index 6b8f655d1ad8..c1a5275721e4 100644
--- a/sound/soc/pxa/pxa2xx-i2s.c
+++ b/sound/soc/pxa/pxa2xx-i2s.c
@@ -164,6 +164,7 @@ static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream,
164{ 164{
165 struct snd_soc_pcm_runtime *rtd = substream->private_data; 165 struct snd_soc_pcm_runtime *rtd = substream->private_data;
166 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 166 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
167 struct pxa2xx_pcm_dma_params *dma_data;
167 168
168 BUG_ON(IS_ERR(clk_i2s)); 169 BUG_ON(IS_ERR(clk_i2s));
169 clk_enable(clk_i2s); 170 clk_enable(clk_i2s);
@@ -171,9 +172,11 @@ static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream,
171 pxa_i2s_wait(); 172 pxa_i2s_wait();
172 173
173 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 174 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
174 cpu_dai->dma_data = &pxa2xx_i2s_pcm_stereo_out; 175 dma_data = &pxa2xx_i2s_pcm_stereo_out;
175 else 176 else
176 cpu_dai->dma_data = &pxa2xx_i2s_pcm_stereo_in; 177 dma_data = &pxa2xx_i2s_pcm_stereo_in;
178
179 snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
177 180
178 /* is port used by another stream */ 181 /* is port used by another stream */
179 if (!(SACR0 & SACR0_ENB)) { 182 if (!(SACR0 & SACR0_ENB)) {
diff --git a/sound/soc/pxa/pxa2xx-pcm.c b/sound/soc/pxa/pxa2xx-pcm.c
index d38e39575f51..adc7e6f15f93 100644
--- a/sound/soc/pxa/pxa2xx-pcm.c
+++ b/sound/soc/pxa/pxa2xx-pcm.c
@@ -25,9 +25,11 @@ static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
25 struct snd_pcm_runtime *runtime = substream->runtime; 25 struct snd_pcm_runtime *runtime = substream->runtime;
26 struct pxa2xx_runtime_data *prtd = runtime->private_data; 26 struct pxa2xx_runtime_data *prtd = runtime->private_data;
27 struct snd_soc_pcm_runtime *rtd = substream->private_data; 27 struct snd_soc_pcm_runtime *rtd = substream->private_data;
28 struct pxa2xx_pcm_dma_params *dma = rtd->dai->cpu_dai->dma_data; 28 struct pxa2xx_pcm_dma_params *dma;
29 int ret; 29 int ret;
30 30
31 dma = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
32
31 /* return if this is a bufferless transfer e.g. 33 /* return if this is a bufferless transfer e.g.
32 * codec <--> BT codec or GSM modem -- lg FIXME */ 34 * codec <--> BT codec or GSM modem -- lg FIXME */
33 if (!dma) 35 if (!dma)
diff --git a/sound/soc/pxa/raumfeld.c b/sound/soc/pxa/raumfeld.c
new file mode 100644
index 000000000000..7e3f41696c41
--- /dev/null
+++ b/sound/soc/pxa/raumfeld.c
@@ -0,0 +1,354 @@
1/*
2 * raumfeld_audio.c -- SoC audio for Raumfeld audio devices
3 *
4 * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
5 *
6 * based on code from:
7 *
8 * Wolfson Microelectronics PLC.
9 * Openedhand Ltd.
10 * Liam Girdwood <lrg@slimlogic.co.uk>
11 * Richard Purdie <richard@openedhand.com>
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version.
17 */
18
19#include <linux/module.h>
20#include <linux/i2c.h>
21#include <linux/delay.h>
22#include <linux/gpio.h>
23#include <sound/pcm.h>
24#include <sound/soc.h>
25#include <sound/soc-dapm.h>
26
27#include <asm/mach-types.h>
28
29#include "../codecs/cs4270.h"
30#include "../codecs/ak4104.h"
31#include "pxa2xx-pcm.h"
32#include "pxa-ssp.h"
33
34#define GPIO_SPDIF_RESET (38)
35#define GPIO_MCLK_RESET (111)
36#define GPIO_CODEC_RESET (120)
37
38static struct i2c_client *max9486_client;
39static struct i2c_board_info max9486_hwmon_info = {
40 I2C_BOARD_INFO("max9485", 0x63),
41};
42
43#define MAX9485_MCLK_FREQ_112896 0x22
44#define MAX9485_MCLK_FREQ_122880 0x23
45#define MAX9485_MCLK_FREQ_225792 0x32
46#define MAX9485_MCLK_FREQ_245760 0x33
47
48static void set_max9485_clk(char clk)
49{
50 i2c_master_send(max9486_client, &clk, 1);
51}
52
53static void raumfeld_enable_audio(bool en)
54{
55 if (en) {
56 gpio_set_value(GPIO_MCLK_RESET, 1);
57
58 /* wait some time to let the clocks become stable */
59 msleep(100);
60
61 gpio_set_value(GPIO_SPDIF_RESET, 1);
62 gpio_set_value(GPIO_CODEC_RESET, 1);
63 } else {
64 gpio_set_value(GPIO_MCLK_RESET, 0);
65 gpio_set_value(GPIO_SPDIF_RESET, 0);
66 gpio_set_value(GPIO_CODEC_RESET, 0);
67 }
68}
69
70/* CS4270 */
71static int raumfeld_cs4270_startup(struct snd_pcm_substream *substream)
72{
73 struct snd_soc_pcm_runtime *rtd = substream->private_data;
74 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
75
76 /* set freq to 0 to enable all possible codec sample rates */
77 return snd_soc_dai_set_sysclk(codec_dai, 0, 0, 0);
78}
79
80static void raumfeld_cs4270_shutdown(struct snd_pcm_substream *substream)
81{
82 struct snd_soc_pcm_runtime *rtd = substream->private_data;
83 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
84
85 /* set freq to 0 to enable all possible codec sample rates */
86 snd_soc_dai_set_sysclk(codec_dai, 0, 0, 0);
87}
88
89static int raumfeld_cs4270_hw_params(struct snd_pcm_substream *substream,
90 struct snd_pcm_hw_params *params)
91{
92 struct snd_soc_pcm_runtime *rtd = substream->private_data;
93 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
94 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
95 unsigned int fmt, clk = 0;
96 int ret = 0;
97
98 switch (params_rate(params)) {
99 case 44100:
100 set_max9485_clk(MAX9485_MCLK_FREQ_112896);
101 clk = 11289600;
102 break;
103 case 48000:
104 set_max9485_clk(MAX9485_MCLK_FREQ_122880);
105 clk = 12288000;
106 break;
107 case 88200:
108 set_max9485_clk(MAX9485_MCLK_FREQ_225792);
109 clk = 22579200;
110 break;
111 case 96000:
112 set_max9485_clk(MAX9485_MCLK_FREQ_245760);
113 clk = 24576000;
114 break;
115 default:
116 return -EINVAL;
117 }
118
119 fmt = SND_SOC_DAIFMT_I2S |
120 SND_SOC_DAIFMT_NB_NF |
121 SND_SOC_DAIFMT_CBS_CFS;
122
123 /* setup the CODEC DAI */
124 ret = snd_soc_dai_set_fmt(codec_dai, fmt);
125 if (ret < 0)
126 return ret;
127
128 ret = snd_soc_dai_set_sysclk(codec_dai, 0, clk, 0);
129 if (ret < 0)
130 return ret;
131
132 /* setup the CPU DAI */
133 ret = snd_soc_dai_set_pll(cpu_dai, 0, 0, 0, clk);
134 if (ret < 0)
135 return ret;
136
137 ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
138 if (ret < 0)
139 return ret;
140
141 ret = snd_soc_dai_set_clkdiv(cpu_dai, PXA_SSP_DIV_SCR, 4);
142 if (ret < 0)
143 return ret;
144
145 ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_EXT, clk, 1);
146 if (ret < 0)
147 return ret;
148
149 return 0;
150}
151
152static struct snd_soc_ops raumfeld_cs4270_ops = {
153 .startup = raumfeld_cs4270_startup,
154 .shutdown = raumfeld_cs4270_shutdown,
155 .hw_params = raumfeld_cs4270_hw_params,
156};
157
158static int raumfeld_line_suspend(struct platform_device *pdev, pm_message_t state)
159{
160 raumfeld_enable_audio(false);
161 return 0;
162}
163
164static int raumfeld_line_resume(struct platform_device *pdev)
165{
166 raumfeld_enable_audio(true);
167 return 0;
168}
169
170static struct snd_soc_dai_link raumfeld_line_dai = {
171 .name = "CS4270",
172 .stream_name = "CS4270",
173 .cpu_dai = &pxa_ssp_dai[PXA_DAI_SSP1],
174 .codec_dai = &cs4270_dai,
175 .ops = &raumfeld_cs4270_ops,
176};
177
178static struct snd_soc_card snd_soc_line_raumfeld = {
179 .name = "Raumfeld analog",
180 .platform = &pxa2xx_soc_platform,
181 .dai_link = &raumfeld_line_dai,
182 .suspend_post = raumfeld_line_suspend,
183 .resume_pre = raumfeld_line_resume,
184 .num_links = 1,
185};
186
187
188/* AK4104 */
189
190static int raumfeld_ak4104_hw_params(struct snd_pcm_substream *substream,
191 struct snd_pcm_hw_params *params)
192{
193 struct snd_soc_pcm_runtime *rtd = substream->private_data;
194 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
195 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
196 int fmt, ret = 0, clk = 0;
197
198 switch (params_rate(params)) {
199 case 44100:
200 set_max9485_clk(MAX9485_MCLK_FREQ_112896);
201 clk = 11289600;
202 break;
203 case 48000:
204 set_max9485_clk(MAX9485_MCLK_FREQ_122880);
205 clk = 12288000;
206 break;
207 case 88200:
208 set_max9485_clk(MAX9485_MCLK_FREQ_225792);
209 clk = 22579200;
210 break;
211 case 96000:
212 set_max9485_clk(MAX9485_MCLK_FREQ_245760);
213 clk = 24576000;
214 break;
215 default:
216 return -EINVAL;
217 }
218
219 fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF;
220
221 /* setup the CODEC DAI */
222 ret = snd_soc_dai_set_fmt(codec_dai, fmt | SND_SOC_DAIFMT_CBS_CFS);
223 if (ret < 0)
224 return ret;
225
226 /* setup the CPU DAI */
227 ret = snd_soc_dai_set_pll(cpu_dai, 0, 0, 0, clk);
228 if (ret < 0)
229 return ret;
230
231 ret = snd_soc_dai_set_fmt(cpu_dai, fmt | SND_SOC_DAIFMT_CBS_CFS);
232 if (ret < 0)
233 return ret;
234
235 ret = snd_soc_dai_set_clkdiv(cpu_dai, PXA_SSP_DIV_SCR, 4);
236 if (ret < 0)
237 return ret;
238
239 ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_EXT, clk, 1);
240 if (ret < 0)
241 return ret;
242
243 return 0;
244}
245
246static struct snd_soc_ops raumfeld_ak4104_ops = {
247 .hw_params = raumfeld_ak4104_hw_params,
248};
249
250static struct snd_soc_dai_link raumfeld_spdif_dai = {
251 .name = "ak4104",
252 .stream_name = "Playback",
253 .cpu_dai = &pxa_ssp_dai[PXA_DAI_SSP2],
254 .codec_dai = &ak4104_dai,
255 .ops = &raumfeld_ak4104_ops,
256};
257
258static struct snd_soc_card snd_soc_spdif_raumfeld = {
259 .name = "Raumfeld S/PDIF",
260 .platform = &pxa2xx_soc_platform,
261 .dai_link = &raumfeld_spdif_dai,
262 .num_links = 1
263};
264
265/* raumfeld_audio audio subsystem */
266static struct snd_soc_device raumfeld_line_devdata = {
267 .card = &snd_soc_line_raumfeld,
268 .codec_dev = &soc_codec_device_cs4270,
269};
270
271static struct snd_soc_device raumfeld_spdif_devdata = {
272 .card = &snd_soc_spdif_raumfeld,
273 .codec_dev = &soc_codec_device_ak4104,
274};
275
276static struct platform_device *raumfeld_audio_line_device;
277static struct platform_device *raumfeld_audio_spdif_device;
278
279static int __init raumfeld_audio_init(void)
280{
281 int ret;
282
283 if (!machine_is_raumfeld_speaker() &&
284 !machine_is_raumfeld_connector())
285 return 0;
286
287 max9486_client = i2c_new_device(i2c_get_adapter(0),
288 &max9486_hwmon_info);
289
290 if (!max9486_client)
291 return -ENOMEM;
292
293 set_max9485_clk(MAX9485_MCLK_FREQ_122880);
294
295 /* LINE */
296 raumfeld_audio_line_device = platform_device_alloc("soc-audio", 0);
297 if (!raumfeld_audio_line_device)
298 return -ENOMEM;
299
300 platform_set_drvdata(raumfeld_audio_line_device,
301 &raumfeld_line_devdata);
302 raumfeld_line_devdata.dev = &raumfeld_audio_line_device->dev;
303 ret = platform_device_add(raumfeld_audio_line_device);
304 if (ret)
305 platform_device_put(raumfeld_audio_line_device);
306
307 /* no S/PDIF on Speakers */
308 if (machine_is_raumfeld_speaker())
309 return ret;
310
311 /* S/PDIF */
312 raumfeld_audio_spdif_device = platform_device_alloc("soc-audio", 1);
313 if (!raumfeld_audio_spdif_device) {
314 platform_device_put(raumfeld_audio_line_device);
315 return -ENOMEM;
316 }
317
318 platform_set_drvdata(raumfeld_audio_spdif_device,
319 &raumfeld_spdif_devdata);
320 raumfeld_spdif_devdata.dev = &raumfeld_audio_spdif_device->dev;
321 ret = platform_device_add(raumfeld_audio_spdif_device);
322 if (ret) {
323 platform_device_put(raumfeld_audio_line_device);
324 platform_device_put(raumfeld_audio_spdif_device);
325 }
326
327 raumfeld_enable_audio(true);
328
329 return ret;
330}
331
332static void __exit raumfeld_audio_exit(void)
333{
334 raumfeld_enable_audio(false);
335
336 platform_device_unregister(raumfeld_audio_line_device);
337
338 if (machine_is_raumfeld_connector())
339 platform_device_unregister(raumfeld_audio_spdif_device);
340
341 i2c_unregister_device(max9486_client);
342
343 gpio_free(GPIO_MCLK_RESET);
344 gpio_free(GPIO_CODEC_RESET);
345 gpio_free(GPIO_SPDIF_RESET);
346}
347
348module_init(raumfeld_audio_init);
349module_exit(raumfeld_audio_exit);
350
351/* Module information */
352MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
353MODULE_DESCRIPTION("Raumfeld audio SoC");
354MODULE_LICENSE("GPL");
diff --git a/sound/soc/pxa/zylonite.c b/sound/soc/pxa/zylonite.c
index 9a386b4c4ed1..dd678ae24398 100644
--- a/sound/soc/pxa/zylonite.c
+++ b/sound/soc/pxa/zylonite.c
@@ -74,7 +74,8 @@ static const struct snd_soc_dapm_route audio_map[] = {
74static int zylonite_wm9713_init(struct snd_soc_codec *codec) 74static int zylonite_wm9713_init(struct snd_soc_codec *codec)
75{ 75{
76 if (clk_pout) 76 if (clk_pout)
77 snd_soc_dai_set_pll(&codec->dai[0], 0, clk_get_rate(pout), 0); 77 snd_soc_dai_set_pll(&codec->dai[0], 0, 0,
78 clk_get_rate(pout), 0);
78 79
79 snd_soc_dapm_new_controls(codec, zylonite_dapm_widgets, 80 snd_soc_dapm_new_controls(codec, zylonite_dapm_widgets,
80 ARRAY_SIZE(zylonite_dapm_widgets)); 81 ARRAY_SIZE(zylonite_dapm_widgets));
@@ -128,7 +129,7 @@ static int zylonite_voice_hw_params(struct snd_pcm_substream *substream,
128 if (ret < 0) 129 if (ret < 0)
129 return ret; 130 return ret;
130 131
131 ret = snd_soc_dai_set_pll(cpu_dai, 0, 0, pll_out); 132 ret = snd_soc_dai_set_pll(cpu_dai, 0, 0, 0, pll_out);
132 if (ret < 0) 133 if (ret < 0)
133 return ret; 134 return ret;
134 135
diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig
index 923428fc1adb..15fe57e5a232 100644
--- a/sound/soc/s3c24xx/Kconfig
+++ b/sound/soc/s3c24xx/Kconfig
@@ -24,12 +24,13 @@ config SND_S3C64XX_SOC_I2S
24 select SND_S3C_I2SV2_SOC 24 select SND_S3C_I2SV2_SOC
25 select S3C64XX_DMA 25 select S3C64XX_DMA
26 26
27config SND_S3C2443_SOC_AC97 27config SND_S3C_SOC_PCM
28 tristate
29
30config SND_S3C_SOC_AC97
28 tristate 31 tristate
29 select S3C2410_DMA
30 select AC97_BUS
31 select SND_SOC_AC97_BUS 32 select SND_SOC_AC97_BUS
32 33
33config SND_S3C24XX_SOC_NEO1973_WM8753 34config SND_S3C24XX_SOC_NEO1973_WM8753
34 tristate "SoC I2S Audio support for NEO1973 - WM8753" 35 tristate "SoC I2S Audio support for NEO1973 - WM8753"
35 depends on SND_S3C24XX_SOC && MACH_NEO1973_GTA01 36 depends on SND_S3C24XX_SOC && MACH_NEO1973_GTA01
@@ -56,11 +57,22 @@ config SND_S3C24XX_SOC_JIVE_WM8750
56 help 57 help
57 Sat Y if you want to add support for SoC audio on the Jive. 58 Sat Y if you want to add support for SoC audio on the Jive.
58 59
60config SND_S3C64XX_SOC_WM8580
61 tristate "SoC I2S Audio support for WM8580 on SMDK64XX"
62 depends on SND_S3C24XX_SOC && (MACH_SMDK6400 || MACH_SMDK6410)
63 depends on BROKEN
64 select SND_SOC_WM8580
65 select SND_S3C64XX_SOC_I2S
66 help
67 Sat Y if you want to add support for SoC audio on the SMDK64XX.
68
59config SND_S3C24XX_SOC_SMDK2443_WM9710 69config SND_S3C24XX_SOC_SMDK2443_WM9710
60 tristate "SoC AC97 Audio support for SMDK2443 - WM9710" 70 tristate "SoC AC97 Audio support for SMDK2443 - WM9710"
61 depends on SND_S3C24XX_SOC && MACH_SMDK2443 71 depends on SND_S3C24XX_SOC && MACH_SMDK2443
62 select SND_S3C2443_SOC_AC97 72 select S3C2410_DMA
73 select AC97_BUS
63 select SND_SOC_AC97_CODEC 74 select SND_SOC_AC97_CODEC
75 select SND_S3C_SOC_AC97
64 help 76 help
65 Say Y if you want to add support for SoC audio on smdk2443 77 Say Y if you want to add support for SoC audio on smdk2443
66 with the WM9710. 78 with the WM9710.
@@ -68,8 +80,10 @@ config SND_S3C24XX_SOC_SMDK2443_WM9710
68config SND_S3C24XX_SOC_LN2440SBC_ALC650 80config SND_S3C24XX_SOC_LN2440SBC_ALC650
69 tristate "SoC AC97 Audio support for LN2440SBC - ALC650" 81 tristate "SoC AC97 Audio support for LN2440SBC - ALC650"
70 depends on SND_S3C24XX_SOC && ARCH_S3C2410 82 depends on SND_S3C24XX_SOC && ARCH_S3C2410
71 select SND_S3C2443_SOC_AC97 83 select S3C2410_DMA
84 select AC97_BUS
72 select SND_SOC_AC97_CODEC 85 select SND_SOC_AC97_CODEC
86 select SND_S3C_SOC_AC97
73 help 87 help
74 Say Y if you want to add support for SoC audio on ln2440sbc 88 Say Y if you want to add support for SoC audio on ln2440sbc
75 with the ALC650. 89 with the ALC650.
@@ -99,3 +113,11 @@ config SND_S3C24XX_SOC_SIMTEC_HERMES
99 select SND_S3C24XX_SOC_I2S 113 select SND_S3C24XX_SOC_I2S
100 select SND_SOC_TLV320AIC3X 114 select SND_SOC_TLV320AIC3X
101 select SND_S3C24XX_SOC_SIMTEC 115 select SND_S3C24XX_SOC_SIMTEC
116
117config SND_SOC_SMDK_WM9713
118 tristate "SoC AC97 Audio support for SMDK with WM9713"
119 depends on SND_S3C24XX_SOC && MACH_SMDK6410
120 select SND_SOC_WM9713
121 select SND_S3C_SOC_AC97
122 help
123 Sat Y if you want to add support for SoC audio on the SMDK.
diff --git a/sound/soc/s3c24xx/Makefile b/sound/soc/s3c24xx/Makefile
index 99f5a7dd3fc6..df071a376fa2 100644
--- a/sound/soc/s3c24xx/Makefile
+++ b/sound/soc/s3c24xx/Makefile
@@ -1,17 +1,19 @@
1# S3c24XX Platform Support 1# S3c24XX Platform Support
2snd-soc-s3c24xx-objs := s3c24xx-pcm.o 2snd-soc-s3c24xx-objs := s3c-dma.o
3snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o 3snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o
4snd-soc-s3c2412-i2s-objs := s3c2412-i2s.o 4snd-soc-s3c2412-i2s-objs := s3c2412-i2s.o
5snd-soc-s3c64xx-i2s-objs := s3c64xx-i2s.o 5snd-soc-s3c64xx-i2s-objs := s3c64xx-i2s.o
6snd-soc-s3c2443-ac97-objs := s3c2443-ac97.o 6snd-soc-s3c-ac97-objs := s3c-ac97.o
7snd-soc-s3c-i2s-v2-objs := s3c-i2s-v2.o 7snd-soc-s3c-i2s-v2-objs := s3c-i2s-v2.o
8snd-soc-s3c-pcm-objs := s3c-pcm.o
8 9
9obj-$(CONFIG_SND_S3C24XX_SOC) += snd-soc-s3c24xx.o 10obj-$(CONFIG_SND_S3C24XX_SOC) += snd-soc-s3c24xx.o
10obj-$(CONFIG_SND_S3C24XX_SOC_I2S) += snd-soc-s3c24xx-i2s.o 11obj-$(CONFIG_SND_S3C24XX_SOC_I2S) += snd-soc-s3c24xx-i2s.o
11obj-$(CONFIG_SND_S3C2443_SOC_AC97) += snd-soc-s3c2443-ac97.o 12obj-$(CONFIG_SND_S3C_SOC_AC97) += snd-soc-s3c-ac97.o
12obj-$(CONFIG_SND_S3C2412_SOC_I2S) += snd-soc-s3c2412-i2s.o 13obj-$(CONFIG_SND_S3C2412_SOC_I2S) += snd-soc-s3c2412-i2s.o
13obj-$(CONFIG_SND_S3C64XX_SOC_I2S) += snd-soc-s3c64xx-i2s.o 14obj-$(CONFIG_SND_S3C64XX_SOC_I2S) += snd-soc-s3c64xx-i2s.o
14obj-$(CONFIG_SND_S3C_I2SV2_SOC) += snd-soc-s3c-i2s-v2.o 15obj-$(CONFIG_SND_S3C_I2SV2_SOC) += snd-soc-s3c-i2s-v2.o
16obj-$(CONFIG_SND_S3C_SOC_PCM) += snd-soc-s3c-pcm.o
15 17
16# S3C24XX Machine Support 18# S3C24XX Machine Support
17snd-soc-jive-wm8750-objs := jive_wm8750.o 19snd-soc-jive-wm8750-objs := jive_wm8750.o
@@ -23,6 +25,8 @@ snd-soc-s3c24xx-uda134x-objs := s3c24xx_uda134x.o
23snd-soc-s3c24xx-simtec-objs := s3c24xx_simtec.o 25snd-soc-s3c24xx-simtec-objs := s3c24xx_simtec.o
24snd-soc-s3c24xx-simtec-hermes-objs := s3c24xx_simtec_hermes.o 26snd-soc-s3c24xx-simtec-hermes-objs := s3c24xx_simtec_hermes.o
25snd-soc-s3c24xx-simtec-tlv320aic23-objs := s3c24xx_simtec_tlv320aic23.o 27snd-soc-s3c24xx-simtec-tlv320aic23-objs := s3c24xx_simtec_tlv320aic23.o
28snd-soc-smdk64xx-wm8580-objs := smdk64xx_wm8580.o
29snd-soc-smdk-wm9713-objs := smdk_wm9713.o
26 30
27obj-$(CONFIG_SND_S3C24XX_SOC_JIVE_WM8750) += snd-soc-jive-wm8750.o 31obj-$(CONFIG_SND_S3C24XX_SOC_JIVE_WM8750) += snd-soc-jive-wm8750.o
28obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o 32obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o
@@ -33,4 +37,5 @@ obj-$(CONFIG_SND_S3C24XX_SOC_S3C24XX_UDA134X) += snd-soc-s3c24xx-uda134x.o
33obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC) += snd-soc-s3c24xx-simtec.o 37obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC) += snd-soc-s3c24xx-simtec.o
34obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC_HERMES) += snd-soc-s3c24xx-simtec-hermes.o 38obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC_HERMES) += snd-soc-s3c24xx-simtec-hermes.o
35obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC_TLV320AIC23) += snd-soc-s3c24xx-simtec-tlv320aic23.o 39obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC_TLV320AIC23) += snd-soc-s3c24xx-simtec-tlv320aic23.o
36 40obj-$(CONFIG_SND_S3C64XX_SOC_WM8580) += snd-soc-smdk64xx-wm8580.o
41obj-$(CONFIG_SND_SOC_SMDK_WM9713) += snd-soc-smdk-wm9713.o
diff --git a/sound/soc/s3c24xx/jive_wm8750.c b/sound/soc/s3c24xx/jive_wm8750.c
index 93e6c87b7399..59dc2c6b56d9 100644
--- a/sound/soc/s3c24xx/jive_wm8750.c
+++ b/sound/soc/s3c24xx/jive_wm8750.c
@@ -25,7 +25,7 @@
25 25
26#include <asm/mach-types.h> 26#include <asm/mach-types.h>
27 27
28#include "s3c24xx-pcm.h" 28#include "s3c-dma.h"
29#include "s3c2412-i2s.h" 29#include "s3c2412-i2s.h"
30 30
31#include "../codecs/wm8750.h" 31#include "../codecs/wm8750.h"
diff --git a/sound/soc/s3c24xx/ln2440sbc_alc650.c b/sound/soc/s3c24xx/ln2440sbc_alc650.c
index 12c71482d258..ffa954fe6931 100644
--- a/sound/soc/s3c24xx/ln2440sbc_alc650.c
+++ b/sound/soc/s3c24xx/ln2440sbc_alc650.c
@@ -24,8 +24,8 @@
24#include <sound/soc-dapm.h> 24#include <sound/soc-dapm.h>
25 25
26#include "../codecs/ac97.h" 26#include "../codecs/ac97.h"
27#include "s3c24xx-pcm.h" 27#include "s3c-dma.h"
28#include "s3c24xx-ac97.h" 28#include "s3c-ac97.h"
29 29
30static struct snd_soc_card ln2440sbc; 30static struct snd_soc_card ln2440sbc;
31 31
@@ -33,7 +33,7 @@ static struct snd_soc_dai_link ln2440sbc_dai[] = {
33{ 33{
34 .name = "AC97", 34 .name = "AC97",
35 .stream_name = "AC97 HiFi", 35 .stream_name = "AC97 HiFi",
36 .cpu_dai = &s3c2443_ac97_dai[0], 36 .cpu_dai = &s3c_ac97_dai[S3C_AC97_DAI_PCM],
37 .codec_dai = &ac97_dai, 37 .codec_dai = &ac97_dai,
38}, 38},
39}; 39};
diff --git a/sound/soc/s3c24xx/neo1973_gta02_wm8753.c b/sound/soc/s3c24xx/neo1973_gta02_wm8753.c
index 0c52e36ddd87..dea83d30a5c9 100644
--- a/sound/soc/s3c24xx/neo1973_gta02_wm8753.c
+++ b/sound/soc/s3c24xx/neo1973_gta02_wm8753.c
@@ -32,7 +32,7 @@
32#include <asm/io.h> 32#include <asm/io.h>
33#include <mach/gta02.h> 33#include <mach/gta02.h>
34#include "../codecs/wm8753.h" 34#include "../codecs/wm8753.h"
35#include "s3c24xx-pcm.h" 35#include "s3c-dma.h"
36#include "s3c24xx-i2s.h" 36#include "s3c24xx-i2s.h"
37 37
38static struct snd_soc_card neo1973_gta02; 38static struct snd_soc_card neo1973_gta02;
@@ -119,7 +119,7 @@ static int neo1973_gta02_hifi_hw_params(struct snd_pcm_substream *substream,
119 return ret; 119 return ret;
120 120
121 /* codec PLL input is PCLK/4 */ 121 /* codec PLL input is PCLK/4 */
122 ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 122 ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0,
123 iis_clkrate / 4, pll_out); 123 iis_clkrate / 4, pll_out);
124 if (ret < 0) 124 if (ret < 0)
125 return ret; 125 return ret;
@@ -133,7 +133,7 @@ static int neo1973_gta02_hifi_hw_free(struct snd_pcm_substream *substream)
133 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 133 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
134 134
135 /* disable the PLL */ 135 /* disable the PLL */
136 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, 0); 136 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, 0, 0);
137} 137}
138 138
139/* 139/*
@@ -183,7 +183,7 @@ static int neo1973_gta02_voice_hw_params(
183 return ret; 183 return ret;
184 184
185 /* configue and enable PLL for 12.288MHz output */ 185 /* configue and enable PLL for 12.288MHz output */
186 ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 186 ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0,
187 iis_clkrate / 4, 12288000); 187 iis_clkrate / 4, 12288000);
188 if (ret < 0) 188 if (ret < 0)
189 return ret; 189 return ret;
@@ -197,7 +197,7 @@ static int neo1973_gta02_voice_hw_free(struct snd_pcm_substream *substream)
197 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 197 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
198 198
199 /* disable the PLL */ 199 /* disable the PLL */
200 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 0); 200 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 0, 0);
201} 201}
202 202
203static struct snd_soc_ops neo1973_gta02_voice_ops = { 203static struct snd_soc_ops neo1973_gta02_voice_ops = {
diff --git a/sound/soc/s3c24xx/neo1973_wm8753.c b/sound/soc/s3c24xx/neo1973_wm8753.c
index 906709e6dd5f..0cb4f86f6d1e 100644
--- a/sound/soc/s3c24xx/neo1973_wm8753.c
+++ b/sound/soc/s3c24xx/neo1973_wm8753.c
@@ -29,7 +29,6 @@
29#include <mach/regs-clock.h> 29#include <mach/regs-clock.h>
30#include <mach/regs-gpio.h> 30#include <mach/regs-gpio.h>
31#include <mach/hardware.h> 31#include <mach/hardware.h>
32#include <plat/audio.h>
33#include <linux/io.h> 32#include <linux/io.h>
34#include <mach/spi-gpio.h> 33#include <mach/spi-gpio.h>
35 34
@@ -37,7 +36,7 @@
37 36
38#include "../codecs/wm8753.h" 37#include "../codecs/wm8753.h"
39#include "lm4857.h" 38#include "lm4857.h"
40#include "s3c24xx-pcm.h" 39#include "s3c-dma.h"
41#include "s3c24xx-i2s.h" 40#include "s3c24xx-i2s.h"
42 41
43/* define the scenarios */ 42/* define the scenarios */
@@ -137,7 +136,7 @@ static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream,
137 return ret; 136 return ret;
138 137
139 /* codec PLL input is PCLK/4 */ 138 /* codec PLL input is PCLK/4 */
140 ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 139 ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0,
141 iis_clkrate / 4, pll_out); 140 iis_clkrate / 4, pll_out);
142 if (ret < 0) 141 if (ret < 0)
143 return ret; 142 return ret;
@@ -153,7 +152,7 @@ static int neo1973_hifi_hw_free(struct snd_pcm_substream *substream)
153 pr_debug("Entered %s\n", __func__); 152 pr_debug("Entered %s\n", __func__);
154 153
155 /* disable the PLL */ 154 /* disable the PLL */
156 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, 0); 155 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, 0, 0);
157} 156}
158 157
159/* 158/*
@@ -203,7 +202,7 @@ static int neo1973_voice_hw_params(struct snd_pcm_substream *substream,
203 return ret; 202 return ret;
204 203
205 /* configue and enable PLL for 12.288MHz output */ 204 /* configue and enable PLL for 12.288MHz output */
206 ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 205 ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0,
207 iis_clkrate / 4, 12288000); 206 iis_clkrate / 4, 12288000);
208 if (ret < 0) 207 if (ret < 0)
209 return ret; 208 return ret;
@@ -219,7 +218,7 @@ static int neo1973_voice_hw_free(struct snd_pcm_substream *substream)
219 pr_debug("Entered %s\n", __func__); 218 pr_debug("Entered %s\n", __func__);
220 219
221 /* disable the PLL */ 220 /* disable the PLL */
222 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 0); 221 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 0, 0);
223} 222}
224 223
225static struct snd_soc_ops neo1973_voice_ops = { 224static struct snd_soc_ops neo1973_voice_ops = {
diff --git a/sound/soc/s3c24xx/s3c-ac97.c b/sound/soc/s3c24xx/s3c-ac97.c
new file mode 100644
index 000000000000..ecf4fd04ae96
--- /dev/null
+++ b/sound/soc/s3c24xx/s3c-ac97.c
@@ -0,0 +1,521 @@
1/* sound/soc/s3c24xx/s3c-ac97.c
2 *
3 * ALSA SoC Audio Layer - S3C AC97 Controller driver
4 * Evolved from s3c2443-ac97.c
5 *
6 * Copyright (c) 2010 Samsung Electronics Co. Ltd
7 * Author: Jaswinder Singh <jassi.brar@samsung.com>
8 * Credits: Graeme Gregory, Sean Choi
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/init.h>
16#include <linux/module.h>
17#include <linux/io.h>
18#include <linux/delay.h>
19#include <linux/clk.h>
20
21#include <sound/soc.h>
22
23#include <plat/regs-ac97.h>
24#include <mach/dma.h>
25#include <plat/audio.h>
26
27#include "s3c-dma.h"
28#include "s3c-ac97.h"
29
30#define AC_CMD_ADDR(x) (x << 16)
31#define AC_CMD_DATA(x) (x & 0xffff)
32
33struct s3c_ac97_info {
34 unsigned state;
35 struct clk *ac97_clk;
36 void __iomem *regs;
37 struct mutex lock;
38 struct completion done;
39};
40static struct s3c_ac97_info s3c_ac97;
41
42static struct s3c2410_dma_client s3c_dma_client_out = {
43 .name = "AC97 PCMOut"
44};
45
46static struct s3c2410_dma_client s3c_dma_client_in = {
47 .name = "AC97 PCMIn"
48};
49
50static struct s3c2410_dma_client s3c_dma_client_micin = {
51 .name = "AC97 MicIn"
52};
53
54static struct s3c_dma_params s3c_ac97_pcm_out = {
55 .client = &s3c_dma_client_out,
56 .dma_size = 4,
57};
58
59static struct s3c_dma_params s3c_ac97_pcm_in = {
60 .client = &s3c_dma_client_in,
61 .dma_size = 4,
62};
63
64static struct s3c_dma_params s3c_ac97_mic_in = {
65 .client = &s3c_dma_client_micin,
66 .dma_size = 4,
67};
68
69static void s3c_ac97_activate(struct snd_ac97 *ac97)
70{
71 u32 ac_glbctrl, stat;
72
73 stat = readl(s3c_ac97.regs + S3C_AC97_GLBSTAT) & 0x7;
74 if (stat == S3C_AC97_GLBSTAT_MAINSTATE_ACTIVE)
75 return; /* Return if already active */
76
77 INIT_COMPLETION(s3c_ac97.done);
78
79 ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL);
80 ac_glbctrl = S3C_AC97_GLBCTRL_ACLINKON;
81 writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
82 msleep(1);
83
84 ac_glbctrl |= S3C_AC97_GLBCTRL_TRANSFERDATAENABLE;
85 writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
86 msleep(1);
87
88 ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL);
89 ac_glbctrl |= S3C_AC97_GLBCTRL_CODECREADYIE;
90 writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
91
92 if (!wait_for_completion_timeout(&s3c_ac97.done, HZ))
93 printk(KERN_ERR "AC97: Unable to activate!");
94}
95
96static unsigned short s3c_ac97_read(struct snd_ac97 *ac97,
97 unsigned short reg)
98{
99 u32 ac_glbctrl, ac_codec_cmd;
100 u32 stat, addr, data;
101
102 mutex_lock(&s3c_ac97.lock);
103
104 s3c_ac97_activate(ac97);
105
106 INIT_COMPLETION(s3c_ac97.done);
107
108 ac_codec_cmd = readl(s3c_ac97.regs + S3C_AC97_CODEC_CMD);
109 ac_codec_cmd = S3C_AC97_CODEC_CMD_READ | AC_CMD_ADDR(reg);
110 writel(ac_codec_cmd, s3c_ac97.regs + S3C_AC97_CODEC_CMD);
111
112 udelay(50);
113
114 ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL);
115 ac_glbctrl |= S3C_AC97_GLBCTRL_CODECREADYIE;
116 writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
117
118 if (!wait_for_completion_timeout(&s3c_ac97.done, HZ))
119 printk(KERN_ERR "AC97: Unable to read!");
120
121 stat = readl(s3c_ac97.regs + S3C_AC97_STAT);
122 addr = (stat >> 16) & 0x7f;
123 data = (stat & 0xffff);
124
125 if (addr != reg)
126 printk(KERN_ERR "s3c-ac97: req addr = %02x, rep addr = %02x\n", reg, addr);
127
128 mutex_unlock(&s3c_ac97.lock);
129
130 return (unsigned short)data;
131}
132
133static void s3c_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
134 unsigned short val)
135{
136 u32 ac_glbctrl, ac_codec_cmd;
137
138 mutex_lock(&s3c_ac97.lock);
139
140 s3c_ac97_activate(ac97);
141
142 INIT_COMPLETION(s3c_ac97.done);
143
144 ac_codec_cmd = readl(s3c_ac97.regs + S3C_AC97_CODEC_CMD);
145 ac_codec_cmd = AC_CMD_ADDR(reg) | AC_CMD_DATA(val);
146 writel(ac_codec_cmd, s3c_ac97.regs + S3C_AC97_CODEC_CMD);
147
148 udelay(50);
149
150 ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL);
151 ac_glbctrl |= S3C_AC97_GLBCTRL_CODECREADYIE;
152 writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
153
154 if (!wait_for_completion_timeout(&s3c_ac97.done, HZ))
155 printk(KERN_ERR "AC97: Unable to write!");
156
157 ac_codec_cmd = readl(s3c_ac97.regs + S3C_AC97_CODEC_CMD);
158 ac_codec_cmd |= S3C_AC97_CODEC_CMD_READ;
159 writel(ac_codec_cmd, s3c_ac97.regs + S3C_AC97_CODEC_CMD);
160
161 mutex_unlock(&s3c_ac97.lock);
162}
163
164static void s3c_ac97_cold_reset(struct snd_ac97 *ac97)
165{
166 writel(S3C_AC97_GLBCTRL_COLDRESET,
167 s3c_ac97.regs + S3C_AC97_GLBCTRL);
168 msleep(1);
169
170 writel(0, s3c_ac97.regs + S3C_AC97_GLBCTRL);
171 msleep(1);
172}
173
174static void s3c_ac97_warm_reset(struct snd_ac97 *ac97)
175{
176 u32 stat;
177
178 stat = readl(s3c_ac97.regs + S3C_AC97_GLBSTAT) & 0x7;
179 if (stat == S3C_AC97_GLBSTAT_MAINSTATE_ACTIVE)
180 return; /* Return if already active */
181
182 writel(S3C_AC97_GLBCTRL_WARMRESET, s3c_ac97.regs + S3C_AC97_GLBCTRL);
183 msleep(1);
184
185 writel(0, s3c_ac97.regs + S3C_AC97_GLBCTRL);
186 msleep(1);
187
188 s3c_ac97_activate(ac97);
189}
190
191static irqreturn_t s3c_ac97_irq(int irq, void *dev_id)
192{
193 u32 ac_glbctrl, ac_glbstat;
194
195 ac_glbstat = readl(s3c_ac97.regs + S3C_AC97_GLBSTAT);
196
197 if (ac_glbstat & S3C_AC97_GLBSTAT_CODECREADY) {
198
199 ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL);
200 ac_glbctrl &= ~S3C_AC97_GLBCTRL_CODECREADYIE;
201 writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
202
203 complete(&s3c_ac97.done);
204 }
205
206 ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL);
207 ac_glbctrl |= (1<<30); /* Clear interrupt */
208 writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
209
210 return IRQ_HANDLED;
211}
212
213struct snd_ac97_bus_ops soc_ac97_ops = {
214 .read = s3c_ac97_read,
215 .write = s3c_ac97_write,
216 .warm_reset = s3c_ac97_warm_reset,
217 .reset = s3c_ac97_cold_reset,
218};
219EXPORT_SYMBOL_GPL(soc_ac97_ops);
220
221static int s3c_ac97_hw_params(struct snd_pcm_substream *substream,
222 struct snd_pcm_hw_params *params,
223 struct snd_soc_dai *dai)
224{
225 struct snd_soc_pcm_runtime *rtd = substream->private_data;
226 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
227 struct s3c_dma_params *dma_data;
228
229 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
230 dma_data = &s3c_ac97_pcm_out;
231 else
232 dma_data = &s3c_ac97_pcm_in;
233
234 snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
235
236 return 0;
237}
238
239static int s3c_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
240 struct snd_soc_dai *dai)
241{
242 u32 ac_glbctrl;
243 struct snd_soc_pcm_runtime *rtd = substream->private_data;
244 struct s3c_dma_params *dma_data =
245 snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
246
247 ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL);
248 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
249 ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMINTM_MASK;
250 else
251 ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMOUTTM_MASK;
252
253 switch (cmd) {
254 case SNDRV_PCM_TRIGGER_START:
255 case SNDRV_PCM_TRIGGER_RESUME:
256 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
257 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
258 ac_glbctrl |= S3C_AC97_GLBCTRL_PCMINTM_DMA;
259 else
260 ac_glbctrl |= S3C_AC97_GLBCTRL_PCMOUTTM_DMA;
261 break;
262
263 case SNDRV_PCM_TRIGGER_STOP:
264 case SNDRV_PCM_TRIGGER_SUSPEND:
265 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
266 break;
267 }
268
269 writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
270
271 s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED);
272
273 return 0;
274}
275
276static int s3c_ac97_hw_mic_params(struct snd_pcm_substream *substream,
277 struct snd_pcm_hw_params *params,
278 struct snd_soc_dai *dai)
279{
280 struct snd_soc_pcm_runtime *rtd = substream->private_data;
281 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
282
283 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
284 return -ENODEV;
285 else
286 snd_soc_dai_set_dma_data(cpu_dai, substream, &s3c_ac97_mic_in);
287
288 return 0;
289}
290
291static int s3c_ac97_mic_trigger(struct snd_pcm_substream *substream,
292 int cmd, struct snd_soc_dai *dai)
293{
294 u32 ac_glbctrl;
295 struct snd_soc_pcm_runtime *rtd = substream->private_data;
296 struct s3c_dma_params *dma_data =
297 snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
298
299 ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL);
300 ac_glbctrl &= ~S3C_AC97_GLBCTRL_MICINTM_MASK;
301
302 switch (cmd) {
303 case SNDRV_PCM_TRIGGER_START:
304 case SNDRV_PCM_TRIGGER_RESUME:
305 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
306 ac_glbctrl |= S3C_AC97_GLBCTRL_MICINTM_DMA;
307 break;
308
309 case SNDRV_PCM_TRIGGER_STOP:
310 case SNDRV_PCM_TRIGGER_SUSPEND:
311 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
312 break;
313 }
314
315 writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
316
317 s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED);
318
319 return 0;
320}
321
322static struct snd_soc_dai_ops s3c_ac97_dai_ops = {
323 .hw_params = s3c_ac97_hw_params,
324 .trigger = s3c_ac97_trigger,
325};
326
327static struct snd_soc_dai_ops s3c_ac97_mic_dai_ops = {
328 .hw_params = s3c_ac97_hw_mic_params,
329 .trigger = s3c_ac97_mic_trigger,
330};
331
332struct snd_soc_dai s3c_ac97_dai[] = {
333 [S3C_AC97_DAI_PCM] = {
334 .name = "s3c-ac97",
335 .id = S3C_AC97_DAI_PCM,
336 .ac97_control = 1,
337 .playback = {
338 .stream_name = "AC97 Playback",
339 .channels_min = 2,
340 .channels_max = 2,
341 .rates = SNDRV_PCM_RATE_8000_48000,
342 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
343 .capture = {
344 .stream_name = "AC97 Capture",
345 .channels_min = 2,
346 .channels_max = 2,
347 .rates = SNDRV_PCM_RATE_8000_48000,
348 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
349 .ops = &s3c_ac97_dai_ops,
350 },
351 [S3C_AC97_DAI_MIC] = {
352 .name = "s3c-ac97-mic",
353 .id = S3C_AC97_DAI_MIC,
354 .ac97_control = 1,
355 .capture = {
356 .stream_name = "AC97 Mic Capture",
357 .channels_min = 1,
358 .channels_max = 1,
359 .rates = SNDRV_PCM_RATE_8000_48000,
360 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
361 .ops = &s3c_ac97_mic_dai_ops,
362 },
363};
364EXPORT_SYMBOL_GPL(s3c_ac97_dai);
365
366static __devinit int s3c_ac97_probe(struct platform_device *pdev)
367{
368 struct resource *mem_res, *dmatx_res, *dmarx_res, *dmamic_res, *irq_res;
369 struct s3c_audio_pdata *ac97_pdata;
370 int ret;
371
372 ac97_pdata = pdev->dev.platform_data;
373 if (!ac97_pdata || !ac97_pdata->cfg_gpio) {
374 dev_err(&pdev->dev, "cfg_gpio callback not provided!\n");
375 return -EINVAL;
376 }
377
378 /* Check for availability of necessary resource */
379 dmatx_res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
380 if (!dmatx_res) {
381 dev_err(&pdev->dev, "Unable to get AC97-TX dma resource\n");
382 return -ENXIO;
383 }
384
385 dmarx_res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
386 if (!dmarx_res) {
387 dev_err(&pdev->dev, "Unable to get AC97-RX dma resource\n");
388 return -ENXIO;
389 }
390
391 dmamic_res = platform_get_resource(pdev, IORESOURCE_DMA, 2);
392 if (!dmamic_res) {
393 dev_err(&pdev->dev, "Unable to get AC97-MIC dma resource\n");
394 return -ENXIO;
395 }
396
397 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
398 if (!mem_res) {
399 dev_err(&pdev->dev, "Unable to get register resource\n");
400 return -ENXIO;
401 }
402
403 irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
404 if (!irq_res) {
405 dev_err(&pdev->dev, "AC97 IRQ not provided!\n");
406 return -ENXIO;
407 }
408
409 if (!request_mem_region(mem_res->start,
410 resource_size(mem_res), "s3c-ac97")) {
411 dev_err(&pdev->dev, "Unable to request register region\n");
412 return -EBUSY;
413 }
414
415 s3c_ac97_pcm_out.channel = dmatx_res->start;
416 s3c_ac97_pcm_out.dma_addr = mem_res->start + S3C_AC97_PCM_DATA;
417 s3c_ac97_pcm_in.channel = dmarx_res->start;
418 s3c_ac97_pcm_in.dma_addr = mem_res->start + S3C_AC97_PCM_DATA;
419 s3c_ac97_mic_in.channel = dmamic_res->start;
420 s3c_ac97_mic_in.dma_addr = mem_res->start + S3C_AC97_MIC_DATA;
421
422 init_completion(&s3c_ac97.done);
423 mutex_init(&s3c_ac97.lock);
424
425 s3c_ac97.regs = ioremap(mem_res->start, resource_size(mem_res));
426 if (s3c_ac97.regs == NULL) {
427 dev_err(&pdev->dev, "Unable to ioremap register region\n");
428 ret = -ENXIO;
429 goto err1;
430 }
431
432 s3c_ac97.ac97_clk = clk_get(&pdev->dev, "ac97");
433 if (IS_ERR(s3c_ac97.ac97_clk)) {
434 dev_err(&pdev->dev, "s3c-ac97 failed to get ac97_clock\n");
435 ret = -ENODEV;
436 goto err2;
437 }
438 clk_enable(s3c_ac97.ac97_clk);
439
440 if (ac97_pdata->cfg_gpio(pdev)) {
441 dev_err(&pdev->dev, "Unable to configure gpio\n");
442 ret = -EINVAL;
443 goto err3;
444 }
445
446 ret = request_irq(irq_res->start, s3c_ac97_irq,
447 IRQF_DISABLED, "AC97", NULL);
448 if (ret < 0) {
449 printk(KERN_ERR "s3c-ac97: interrupt request failed.\n");
450 goto err4;
451 }
452
453 s3c_ac97_dai[S3C_AC97_DAI_PCM].dev = &pdev->dev;
454 s3c_ac97_dai[S3C_AC97_DAI_MIC].dev = &pdev->dev;
455
456 ret = snd_soc_register_dais(s3c_ac97_dai, ARRAY_SIZE(s3c_ac97_dai));
457 if (ret)
458 goto err5;
459
460 return 0;
461
462err5:
463 free_irq(irq_res->start, NULL);
464err4:
465err3:
466 clk_disable(s3c_ac97.ac97_clk);
467 clk_put(s3c_ac97.ac97_clk);
468err2:
469 iounmap(s3c_ac97.regs);
470err1:
471 release_mem_region(mem_res->start, resource_size(mem_res));
472
473 return ret;
474}
475
476static __devexit int s3c_ac97_remove(struct platform_device *pdev)
477{
478 struct resource *mem_res, *irq_res;
479
480 snd_soc_unregister_dais(s3c_ac97_dai, ARRAY_SIZE(s3c_ac97_dai));
481
482 irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
483 if (irq_res)
484 free_irq(irq_res->start, NULL);
485
486 clk_disable(s3c_ac97.ac97_clk);
487 clk_put(s3c_ac97.ac97_clk);
488
489 iounmap(s3c_ac97.regs);
490
491 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
492 if (mem_res)
493 release_mem_region(mem_res->start, resource_size(mem_res));
494
495 return 0;
496}
497
498static struct platform_driver s3c_ac97_driver = {
499 .probe = s3c_ac97_probe,
500 .remove = s3c_ac97_remove,
501 .driver = {
502 .name = "s3c-ac97",
503 .owner = THIS_MODULE,
504 },
505};
506
507static int __init s3c_ac97_init(void)
508{
509 return platform_driver_register(&s3c_ac97_driver);
510}
511module_init(s3c_ac97_init);
512
513static void __exit s3c_ac97_exit(void)
514{
515 platform_driver_unregister(&s3c_ac97_driver);
516}
517module_exit(s3c_ac97_exit);
518
519MODULE_AUTHOR("Jaswinder Singh, <jassi.brar@samsung.com>");
520MODULE_DESCRIPTION("AC97 driver for the Samsung SoC");
521MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/s3c-ac97.h b/sound/soc/s3c24xx/s3c-ac97.h
new file mode 100644
index 000000000000..278198379def
--- /dev/null
+++ b/sound/soc/s3c24xx/s3c-ac97.h
@@ -0,0 +1,23 @@
1/* sound/soc/s3c24xx/s3c-ac97.h
2 *
3 * ALSA SoC Audio Layer - S3C AC97 Controller driver
4 * Evolved from s3c2443-ac97.h
5 *
6 * Copyright (c) 2010 Samsung Electronics Co. Ltd
7 * Author: Jaswinder Singh <jassi.brar@samsung.com>
8 * Credits: Graeme Gregory, Sean Choi
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#ifndef __S3C_AC97_H_
16#define __S3C_AC97_H_
17
18#define S3C_AC97_DAI_PCM 0
19#define S3C_AC97_DAI_MIC 1
20
21extern struct snd_soc_dai s3c_ac97_dai[];
22
23#endif /* __S3C_AC97_H_ */
diff --git a/sound/soc/s3c24xx/s3c24xx-pcm.c b/sound/soc/s3c24xx/s3c-dma.c
index 1f35c6fcf5fd..1b61c23ff300 100644
--- a/sound/soc/s3c24xx/s3c24xx-pcm.c
+++ b/sound/soc/s3c24xx/s3c-dma.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * s3c24xx-pcm.c -- ALSA Soc Audio Layer 2 * s3c-dma.c -- ALSA Soc Audio Layer
3 * 3 *
4 * (c) 2006 Wolfson Microelectronics PLC. 4 * (c) 2006 Wolfson Microelectronics PLC.
5 * Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com 5 * Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
@@ -29,11 +29,10 @@
29#include <asm/dma.h> 29#include <asm/dma.h>
30#include <mach/hardware.h> 30#include <mach/hardware.h>
31#include <mach/dma.h> 31#include <mach/dma.h>
32#include <plat/audio.h>
33 32
34#include "s3c24xx-pcm.h" 33#include "s3c-dma.h"
35 34
36static const struct snd_pcm_hardware s3c24xx_pcm_hardware = { 35static const struct snd_pcm_hardware s3c_dma_hardware = {
37 .info = SNDRV_PCM_INFO_INTERLEAVED | 36 .info = SNDRV_PCM_INFO_INTERLEAVED |
38 SNDRV_PCM_INFO_BLOCK_TRANSFER | 37 SNDRV_PCM_INFO_BLOCK_TRANSFER |
39 SNDRV_PCM_INFO_MMAP | 38 SNDRV_PCM_INFO_MMAP |
@@ -63,15 +62,15 @@ struct s3c24xx_runtime_data {
63 dma_addr_t dma_start; 62 dma_addr_t dma_start;
64 dma_addr_t dma_pos; 63 dma_addr_t dma_pos;
65 dma_addr_t dma_end; 64 dma_addr_t dma_end;
66 struct s3c24xx_pcm_dma_params *params; 65 struct s3c_dma_params *params;
67}; 66};
68 67
69/* s3c24xx_pcm_enqueue 68/* s3c_dma_enqueue
70 * 69 *
71 * place a dma buffer onto the queue for the dma system 70 * place a dma buffer onto the queue for the dma system
72 * to handle. 71 * to handle.
73*/ 72*/
74static void s3c24xx_pcm_enqueue(struct snd_pcm_substream *substream) 73static void s3c_dma_enqueue(struct snd_pcm_substream *substream)
75{ 74{
76 struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; 75 struct s3c24xx_runtime_data *prtd = substream->runtime->private_data;
77 dma_addr_t pos = prtd->dma_pos; 76 dma_addr_t pos = prtd->dma_pos;
@@ -80,12 +79,13 @@ static void s3c24xx_pcm_enqueue(struct snd_pcm_substream *substream)
80 79
81 pr_debug("Entered %s\n", __func__); 80 pr_debug("Entered %s\n", __func__);
82 81
83 if (s3c_dma_has_circular()) { 82 if (s3c_dma_has_circular())
84 limit = (prtd->dma_end - prtd->dma_start) / prtd->dma_period; 83 limit = (prtd->dma_end - prtd->dma_start) / prtd->dma_period;
85 } else 84 else
86 limit = prtd->dma_limit; 85 limit = prtd->dma_limit;
87 86
88 pr_debug("%s: loaded %d, limit %d\n", __func__, prtd->dma_loaded, limit); 87 pr_debug("%s: loaded %d, limit %d\n",
88 __func__, prtd->dma_loaded, limit);
89 89
90 while (prtd->dma_loaded < limit) { 90 while (prtd->dma_loaded < limit) {
91 unsigned long len = prtd->dma_period; 91 unsigned long len = prtd->dma_period;
@@ -133,22 +133,24 @@ static void s3c24xx_audio_buffdone(struct s3c2410_dma_chan *channel,
133 spin_lock(&prtd->lock); 133 spin_lock(&prtd->lock);
134 if (prtd->state & ST_RUNNING && !s3c_dma_has_circular()) { 134 if (prtd->state & ST_RUNNING && !s3c_dma_has_circular()) {
135 prtd->dma_loaded--; 135 prtd->dma_loaded--;
136 s3c24xx_pcm_enqueue(substream); 136 s3c_dma_enqueue(substream);
137 } 137 }
138 138
139 spin_unlock(&prtd->lock); 139 spin_unlock(&prtd->lock);
140} 140}
141 141
142static int s3c24xx_pcm_hw_params(struct snd_pcm_substream *substream, 142static int s3c_dma_hw_params(struct snd_pcm_substream *substream,
143 struct snd_pcm_hw_params *params) 143 struct snd_pcm_hw_params *params)
144{ 144{
145 struct snd_pcm_runtime *runtime = substream->runtime; 145 struct snd_pcm_runtime *runtime = substream->runtime;
146 struct s3c24xx_runtime_data *prtd = runtime->private_data; 146 struct s3c24xx_runtime_data *prtd = runtime->private_data;
147 struct snd_soc_pcm_runtime *rtd = substream->private_data; 147 struct snd_soc_pcm_runtime *rtd = substream->private_data;
148 struct s3c24xx_pcm_dma_params *dma = rtd->dai->cpu_dai->dma_data;
149 unsigned long totbytes = params_buffer_bytes(params); 148 unsigned long totbytes = params_buffer_bytes(params);
149 struct s3c_dma_params *dma =
150 snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
150 int ret = 0; 151 int ret = 0;
151 152
153
152 pr_debug("Entered %s\n", __func__); 154 pr_debug("Entered %s\n", __func__);
153 155
154 /* return if this is a bufferless transfer e.g. 156 /* return if this is a bufferless transfer e.g.
@@ -198,7 +200,7 @@ static int s3c24xx_pcm_hw_params(struct snd_pcm_substream *substream,
198 return 0; 200 return 0;
199} 201}
200 202
201static int s3c24xx_pcm_hw_free(struct snd_pcm_substream *substream) 203static int s3c_dma_hw_free(struct snd_pcm_substream *substream)
202{ 204{
203 struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; 205 struct s3c24xx_runtime_data *prtd = substream->runtime->private_data;
204 206
@@ -215,7 +217,7 @@ static int s3c24xx_pcm_hw_free(struct snd_pcm_substream *substream)
215 return 0; 217 return 0;
216} 218}
217 219
218static int s3c24xx_pcm_prepare(struct snd_pcm_substream *substream) 220static int s3c_dma_prepare(struct snd_pcm_substream *substream)
219{ 221{
220 struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; 222 struct s3c24xx_runtime_data *prtd = substream->runtime->private_data;
221 int ret = 0; 223 int ret = 0;
@@ -248,12 +250,12 @@ static int s3c24xx_pcm_prepare(struct snd_pcm_substream *substream)
248 prtd->dma_pos = prtd->dma_start; 250 prtd->dma_pos = prtd->dma_start;
249 251
250 /* enqueue dma buffers */ 252 /* enqueue dma buffers */
251 s3c24xx_pcm_enqueue(substream); 253 s3c_dma_enqueue(substream);
252 254
253 return ret; 255 return ret;
254} 256}
255 257
256static int s3c24xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) 258static int s3c_dma_trigger(struct snd_pcm_substream *substream, int cmd)
257{ 259{
258 struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; 260 struct s3c24xx_runtime_data *prtd = substream->runtime->private_data;
259 int ret = 0; 261 int ret = 0;
@@ -288,7 +290,7 @@ static int s3c24xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
288} 290}
289 291
290static snd_pcm_uframes_t 292static snd_pcm_uframes_t
291s3c24xx_pcm_pointer(struct snd_pcm_substream *substream) 293s3c_dma_pointer(struct snd_pcm_substream *substream)
292{ 294{
293 struct snd_pcm_runtime *runtime = substream->runtime; 295 struct snd_pcm_runtime *runtime = substream->runtime;
294 struct s3c24xx_runtime_data *prtd = runtime->private_data; 296 struct s3c24xx_runtime_data *prtd = runtime->private_data;
@@ -323,7 +325,7 @@ s3c24xx_pcm_pointer(struct snd_pcm_substream *substream)
323 return bytes_to_frames(substream->runtime, res); 325 return bytes_to_frames(substream->runtime, res);
324} 326}
325 327
326static int s3c24xx_pcm_open(struct snd_pcm_substream *substream) 328static int s3c_dma_open(struct snd_pcm_substream *substream)
327{ 329{
328 struct snd_pcm_runtime *runtime = substream->runtime; 330 struct snd_pcm_runtime *runtime = substream->runtime;
329 struct s3c24xx_runtime_data *prtd; 331 struct s3c24xx_runtime_data *prtd;
@@ -331,7 +333,7 @@ static int s3c24xx_pcm_open(struct snd_pcm_substream *substream)
331 pr_debug("Entered %s\n", __func__); 333 pr_debug("Entered %s\n", __func__);
332 334
333 snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); 335 snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
334 snd_soc_set_runtime_hwparams(substream, &s3c24xx_pcm_hardware); 336 snd_soc_set_runtime_hwparams(substream, &s3c_dma_hardware);
335 337
336 prtd = kzalloc(sizeof(struct s3c24xx_runtime_data), GFP_KERNEL); 338 prtd = kzalloc(sizeof(struct s3c24xx_runtime_data), GFP_KERNEL);
337 if (prtd == NULL) 339 if (prtd == NULL)
@@ -343,7 +345,7 @@ static int s3c24xx_pcm_open(struct snd_pcm_substream *substream)
343 return 0; 345 return 0;
344} 346}
345 347
346static int s3c24xx_pcm_close(struct snd_pcm_substream *substream) 348static int s3c_dma_close(struct snd_pcm_substream *substream)
347{ 349{
348 struct snd_pcm_runtime *runtime = substream->runtime; 350 struct snd_pcm_runtime *runtime = substream->runtime;
349 struct s3c24xx_runtime_data *prtd = runtime->private_data; 351 struct s3c24xx_runtime_data *prtd = runtime->private_data;
@@ -351,14 +353,14 @@ static int s3c24xx_pcm_close(struct snd_pcm_substream *substream)
351 pr_debug("Entered %s\n", __func__); 353 pr_debug("Entered %s\n", __func__);
352 354
353 if (!prtd) 355 if (!prtd)
354 pr_debug("s3c24xx_pcm_close called with prtd == NULL\n"); 356 pr_debug("s3c_dma_close called with prtd == NULL\n");
355 357
356 kfree(prtd); 358 kfree(prtd);
357 359
358 return 0; 360 return 0;
359} 361}
360 362
361static int s3c24xx_pcm_mmap(struct snd_pcm_substream *substream, 363static int s3c_dma_mmap(struct snd_pcm_substream *substream,
362 struct vm_area_struct *vma) 364 struct vm_area_struct *vma)
363{ 365{
364 struct snd_pcm_runtime *runtime = substream->runtime; 366 struct snd_pcm_runtime *runtime = substream->runtime;
@@ -371,23 +373,23 @@ static int s3c24xx_pcm_mmap(struct snd_pcm_substream *substream,
371 runtime->dma_bytes); 373 runtime->dma_bytes);
372} 374}
373 375
374static struct snd_pcm_ops s3c24xx_pcm_ops = { 376static struct snd_pcm_ops s3c_dma_ops = {
375 .open = s3c24xx_pcm_open, 377 .open = s3c_dma_open,
376 .close = s3c24xx_pcm_close, 378 .close = s3c_dma_close,
377 .ioctl = snd_pcm_lib_ioctl, 379 .ioctl = snd_pcm_lib_ioctl,
378 .hw_params = s3c24xx_pcm_hw_params, 380 .hw_params = s3c_dma_hw_params,
379 .hw_free = s3c24xx_pcm_hw_free, 381 .hw_free = s3c_dma_hw_free,
380 .prepare = s3c24xx_pcm_prepare, 382 .prepare = s3c_dma_prepare,
381 .trigger = s3c24xx_pcm_trigger, 383 .trigger = s3c_dma_trigger,
382 .pointer = s3c24xx_pcm_pointer, 384 .pointer = s3c_dma_pointer,
383 .mmap = s3c24xx_pcm_mmap, 385 .mmap = s3c_dma_mmap,
384}; 386};
385 387
386static int s3c24xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) 388static int s3c_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
387{ 389{
388 struct snd_pcm_substream *substream = pcm->streams[stream].substream; 390 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
389 struct snd_dma_buffer *buf = &substream->dma_buffer; 391 struct snd_dma_buffer *buf = &substream->dma_buffer;
390 size_t size = s3c24xx_pcm_hardware.buffer_bytes_max; 392 size_t size = s3c_dma_hardware.buffer_bytes_max;
391 393
392 pr_debug("Entered %s\n", __func__); 394 pr_debug("Entered %s\n", __func__);
393 395
@@ -402,7 +404,7 @@ static int s3c24xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
402 return 0; 404 return 0;
403} 405}
404 406
405static void s3c24xx_pcm_free_dma_buffers(struct snd_pcm *pcm) 407static void s3c_dma_free_dma_buffers(struct snd_pcm *pcm)
406{ 408{
407 struct snd_pcm_substream *substream; 409 struct snd_pcm_substream *substream;
408 struct snd_dma_buffer *buf; 410 struct snd_dma_buffer *buf;
@@ -425,9 +427,9 @@ static void s3c24xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
425 } 427 }
426} 428}
427 429
428static u64 s3c24xx_pcm_dmamask = DMA_BIT_MASK(32); 430static u64 s3c_dma_mask = DMA_BIT_MASK(32);
429 431
430static int s3c24xx_pcm_new(struct snd_card *card, 432static int s3c_dma_new(struct snd_card *card,
431 struct snd_soc_dai *dai, struct snd_pcm *pcm) 433 struct snd_soc_dai *dai, struct snd_pcm *pcm)
432{ 434{
433 int ret = 0; 435 int ret = 0;
@@ -435,19 +437,19 @@ static int s3c24xx_pcm_new(struct snd_card *card,
435 pr_debug("Entered %s\n", __func__); 437 pr_debug("Entered %s\n", __func__);
436 438
437 if (!card->dev->dma_mask) 439 if (!card->dev->dma_mask)
438 card->dev->dma_mask = &s3c24xx_pcm_dmamask; 440 card->dev->dma_mask = &s3c_dma_mask;
439 if (!card->dev->coherent_dma_mask) 441 if (!card->dev->coherent_dma_mask)
440 card->dev->coherent_dma_mask = 0xffffffff; 442 card->dev->coherent_dma_mask = 0xffffffff;
441 443
442 if (dai->playback.channels_min) { 444 if (dai->playback.channels_min) {
443 ret = s3c24xx_pcm_preallocate_dma_buffer(pcm, 445 ret = s3c_preallocate_dma_buffer(pcm,
444 SNDRV_PCM_STREAM_PLAYBACK); 446 SNDRV_PCM_STREAM_PLAYBACK);
445 if (ret) 447 if (ret)
446 goto out; 448 goto out;
447 } 449 }
448 450
449 if (dai->capture.channels_min) { 451 if (dai->capture.channels_min) {
450 ret = s3c24xx_pcm_preallocate_dma_buffer(pcm, 452 ret = s3c_preallocate_dma_buffer(pcm,
451 SNDRV_PCM_STREAM_CAPTURE); 453 SNDRV_PCM_STREAM_CAPTURE);
452 if (ret) 454 if (ret)
453 goto out; 455 goto out;
@@ -458,9 +460,9 @@ static int s3c24xx_pcm_new(struct snd_card *card,
458 460
459struct snd_soc_platform s3c24xx_soc_platform = { 461struct snd_soc_platform s3c24xx_soc_platform = {
460 .name = "s3c24xx-audio", 462 .name = "s3c24xx-audio",
461 .pcm_ops = &s3c24xx_pcm_ops, 463 .pcm_ops = &s3c_dma_ops,
462 .pcm_new = s3c24xx_pcm_new, 464 .pcm_new = s3c_dma_new,
463 .pcm_free = s3c24xx_pcm_free_dma_buffers, 465 .pcm_free = s3c_dma_free_dma_buffers,
464}; 466};
465EXPORT_SYMBOL_GPL(s3c24xx_soc_platform); 467EXPORT_SYMBOL_GPL(s3c24xx_soc_platform);
466 468
@@ -477,5 +479,5 @@ static void __exit s3c24xx_soc_platform_exit(void)
477module_exit(s3c24xx_soc_platform_exit); 479module_exit(s3c24xx_soc_platform_exit);
478 480
479MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); 481MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
480MODULE_DESCRIPTION("Samsung S3C24XX PCM DMA module"); 482MODULE_DESCRIPTION("Samsung S3C Audio DMA module");
481MODULE_LICENSE("GPL"); 483MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/s3c24xx-pcm.h b/sound/soc/s3c24xx/s3c-dma.h
index 0088c79822ea..69bb6bf6fc1c 100644
--- a/sound/soc/s3c24xx/s3c24xx-pcm.h
+++ b/sound/soc/s3c24xx/s3c-dma.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * s3c24xx-pcm.h -- 2 * s3c-dma.h --
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the 5 * under the terms of the GNU General Public License as published by the
@@ -9,13 +9,13 @@
9 * ALSA PCM interface for the Samsung S3C24xx CPU 9 * ALSA PCM interface for the Samsung S3C24xx CPU
10 */ 10 */
11 11
12#ifndef _S3C24XX_PCM_H 12#ifndef _S3C_AUDIO_H
13#define _S3C24XX_PCM_H 13#define _S3C_AUDIO_H
14 14
15#define ST_RUNNING (1<<0) 15#define ST_RUNNING (1<<0)
16#define ST_OPENED (1<<1) 16#define ST_OPENED (1<<1)
17 17
18struct s3c24xx_pcm_dma_params { 18struct s3c_dma_params {
19 struct s3c2410_dma_client *client; /* stream identifier */ 19 struct s3c2410_dma_client *client; /* stream identifier */
20 int channel; /* Channel ID */ 20 int channel; /* Channel ID */
21 dma_addr_t dma_addr; 21 dma_addr_t dma_addr;
diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.c b/sound/soc/s3c24xx/s3c-i2s-v2.c
index 9bc4aa35caab..88515946b6c0 100644
--- a/sound/soc/s3c24xx/s3c-i2s-v2.c
+++ b/sound/soc/s3c24xx/s3c-i2s-v2.c
@@ -32,11 +32,10 @@
32 32
33#include <plat/regs-s3c2412-iis.h> 33#include <plat/regs-s3c2412-iis.h>
34 34
35#include <plat/audio.h>
36#include <mach/dma.h> 35#include <mach/dma.h>
37 36
38#include "s3c-i2s-v2.h" 37#include "s3c-i2s-v2.h"
39#include "s3c24xx-pcm.h" 38#include "s3c-dma.h"
40 39
41#undef S3C_IIS_V2_SUPPORTED 40#undef S3C_IIS_V2_SUPPORTED
42 41
@@ -312,12 +311,15 @@ static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
312 311
313 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 312 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
314 case SND_SOC_DAIFMT_RIGHT_J: 313 case SND_SOC_DAIFMT_RIGHT_J:
314 iismod |= S3C2412_IISMOD_LR_RLOW;
315 iismod |= S3C2412_IISMOD_SDF_MSB; 315 iismod |= S3C2412_IISMOD_SDF_MSB;
316 break; 316 break;
317 case SND_SOC_DAIFMT_LEFT_J: 317 case SND_SOC_DAIFMT_LEFT_J:
318 iismod |= S3C2412_IISMOD_LR_RLOW;
318 iismod |= S3C2412_IISMOD_SDF_LSB; 319 iismod |= S3C2412_IISMOD_SDF_LSB;
319 break; 320 break;
320 case SND_SOC_DAIFMT_I2S: 321 case SND_SOC_DAIFMT_I2S:
322 iismod &= ~S3C2412_IISMOD_LR_RLOW;
321 iismod |= S3C2412_IISMOD_SDF_IIS; 323 iismod |= S3C2412_IISMOD_SDF_IIS;
322 break; 324 break;
323 default: 325 default:
@@ -337,14 +339,17 @@ static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream,
337 struct snd_soc_pcm_runtime *rtd = substream->private_data; 339 struct snd_soc_pcm_runtime *rtd = substream->private_data;
338 struct snd_soc_dai_link *dai = rtd->dai; 340 struct snd_soc_dai_link *dai = rtd->dai;
339 struct s3c_i2sv2_info *i2s = to_info(dai->cpu_dai); 341 struct s3c_i2sv2_info *i2s = to_info(dai->cpu_dai);
342 struct s3c_dma_params *dma_data;
340 u32 iismod; 343 u32 iismod;
341 344
342 pr_debug("Entered %s\n", __func__); 345 pr_debug("Entered %s\n", __func__);
343 346
344 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 347 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
345 dai->cpu_dai->dma_data = i2s->dma_playback; 348 dma_data = i2s->dma_playback;
346 else 349 else
347 dai->cpu_dai->dma_data = i2s->dma_capture; 350 dma_data = i2s->dma_capture;
351
352 snd_soc_dai_set_dma_data(dai->cpu_dai, substream, dma_data);
348 353
349 /* Working copies of register */ 354 /* Working copies of register */
350 iismod = readl(i2s->regs + S3C2412_IISMOD); 355 iismod = readl(i2s->regs + S3C2412_IISMOD);
@@ -392,8 +397,8 @@ static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
392 int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); 397 int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
393 unsigned long irqs; 398 unsigned long irqs;
394 int ret = 0; 399 int ret = 0;
395 int channel = ((struct s3c24xx_pcm_dma_params *) 400 struct s3c_dma_params *dma_data =
396 rtd->dai->cpu_dai->dma_data)->channel; 401 snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
397 402
398 pr_debug("Entered %s\n", __func__); 403 pr_debug("Entered %s\n", __func__);
399 404
@@ -429,7 +434,7 @@ static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
429 * of the auto reload mechanism of S3C24XX. 434 * of the auto reload mechanism of S3C24XX.
430 * This call won't bother S3C64XX. 435 * This call won't bother S3C64XX.
431 */ 436 */
432 s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED); 437 s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED);
433 438
434 break; 439 break;
435 440
@@ -467,6 +472,31 @@ static int s3c2412_i2s_set_clkdiv(struct snd_soc_dai *cpu_dai,
467 472
468 switch (div_id) { 473 switch (div_id) {
469 case S3C_I2SV2_DIV_BCLK: 474 case S3C_I2SV2_DIV_BCLK:
475 if (div > 3) {
476 /* convert value to bit field */
477
478 switch (div) {
479 case 16:
480 div = S3C2412_IISMOD_BCLK_16FS;
481 break;
482
483 case 32:
484 div = S3C2412_IISMOD_BCLK_32FS;
485 break;
486
487 case 24:
488 div = S3C2412_IISMOD_BCLK_24FS;
489 break;
490
491 case 48:
492 div = S3C2412_IISMOD_BCLK_48FS;
493 break;
494
495 default:
496 return -EINVAL;
497 }
498 }
499
470 reg = readl(i2s->regs + S3C2412_IISMOD); 500 reg = readl(i2s->regs + S3C2412_IISMOD);
471 reg &= ~S3C2412_IISMOD_BCLK_MASK; 501 reg &= ~S3C2412_IISMOD_BCLK_MASK;
472 writel(reg | div, i2s->regs + S3C2412_IISMOD); 502 writel(reg | div, i2s->regs + S3C2412_IISMOD);
@@ -626,7 +656,7 @@ int s3c_i2sv2_probe(struct platform_device *pdev,
626 } 656 }
627 657
628 i2s->iis_pclk = clk_get(dev, "iis"); 658 i2s->iis_pclk = clk_get(dev, "iis");
629 if (i2s->iis_pclk == NULL) { 659 if (IS_ERR(i2s->iis_pclk)) {
630 dev_err(dev, "failed to get iis_clock\n"); 660 dev_err(dev, "failed to get iis_clock\n");
631 iounmap(i2s->regs); 661 iounmap(i2s->regs);
632 return -ENOENT; 662 return -ENOENT;
diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.h b/sound/soc/s3c24xx/s3c-i2s-v2.h
index f66854a77fb2..ecf8eaaed1db 100644
--- a/sound/soc/s3c24xx/s3c-i2s-v2.h
+++ b/sound/soc/s3c24xx/s3c-i2s-v2.h
@@ -49,8 +49,8 @@ struct s3c_i2sv2_info {
49 49
50 unsigned char master; 50 unsigned char master;
51 51
52 struct s3c24xx_pcm_dma_params *dma_playback; 52 struct s3c_dma_params *dma_playback;
53 struct s3c24xx_pcm_dma_params *dma_capture; 53 struct s3c_dma_params *dma_capture;
54 54
55 u32 suspend_iismod; 55 u32 suspend_iismod;
56 u32 suspend_iiscon; 56 u32 suspend_iiscon;
diff --git a/sound/soc/s3c24xx/s3c-pcm.c b/sound/soc/s3c24xx/s3c-pcm.c
new file mode 100644
index 000000000000..326f0a9e7e30
--- /dev/null
+++ b/sound/soc/s3c24xx/s3c-pcm.c
@@ -0,0 +1,554 @@
1/* sound/soc/s3c24xx/s3c-pcm.c
2 *
3 * ALSA SoC Audio Layer - S3C PCM-Controller driver
4 *
5 * Copyright (c) 2009 Samsung Electronics Co. Ltd
6 * Author: Jaswinder Singh <jassi.brar@samsung.com>
7 * based upon I2S drivers by Ben Dooks.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/init.h>
15#include <linux/module.h>
16#include <linux/device.h>
17#include <linux/delay.h>
18#include <linux/clk.h>
19#include <linux/kernel.h>
20#include <linux/gpio.h>
21#include <linux/io.h>
22
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26#include <sound/initval.h>
27#include <sound/soc.h>
28
29#include <plat/audio.h>
30#include <plat/dma.h>
31
32#include "s3c-dma.h"
33#include "s3c-pcm.h"
34
35static struct s3c2410_dma_client s3c_pcm_dma_client_out = {
36 .name = "PCM Stereo out"
37};
38
39static struct s3c2410_dma_client s3c_pcm_dma_client_in = {
40 .name = "PCM Stereo in"
41};
42
43static struct s3c_dma_params s3c_pcm_stereo_out[] = {
44 [0] = {
45 .client = &s3c_pcm_dma_client_out,
46 .dma_size = 4,
47 },
48 [1] = {
49 .client = &s3c_pcm_dma_client_out,
50 .dma_size = 4,
51 },
52};
53
54static struct s3c_dma_params s3c_pcm_stereo_in[] = {
55 [0] = {
56 .client = &s3c_pcm_dma_client_in,
57 .dma_size = 4,
58 },
59 [1] = {
60 .client = &s3c_pcm_dma_client_in,
61 .dma_size = 4,
62 },
63};
64
65static struct s3c_pcm_info s3c_pcm[2];
66
67static inline struct s3c_pcm_info *to_info(struct snd_soc_dai *cpu_dai)
68{
69 return cpu_dai->private_data;
70}
71
72static void s3c_pcm_snd_txctrl(struct s3c_pcm_info *pcm, int on)
73{
74 void __iomem *regs = pcm->regs;
75 u32 ctl, clkctl;
76
77 clkctl = readl(regs + S3C_PCM_CLKCTL);
78 ctl = readl(regs + S3C_PCM_CTL);
79 ctl &= ~(S3C_PCM_CTL_TXDIPSTICK_MASK
80 << S3C_PCM_CTL_TXDIPSTICK_SHIFT);
81
82 if (on) {
83 ctl |= S3C_PCM_CTL_TXDMA_EN;
84 ctl |= S3C_PCM_CTL_TXFIFO_EN;
85 ctl |= S3C_PCM_CTL_ENABLE;
86 ctl |= (0x20<<S3C_PCM_CTL_TXDIPSTICK_SHIFT);
87 clkctl |= S3C_PCM_CLKCTL_SERCLK_EN;
88 } else {
89 ctl &= ~S3C_PCM_CTL_TXDMA_EN;
90 ctl &= ~S3C_PCM_CTL_TXFIFO_EN;
91
92 if (!(ctl & S3C_PCM_CTL_RXFIFO_EN)) {
93 ctl &= ~S3C_PCM_CTL_ENABLE;
94 if (!pcm->idleclk)
95 clkctl |= S3C_PCM_CLKCTL_SERCLK_EN;
96 }
97 }
98
99 writel(clkctl, regs + S3C_PCM_CLKCTL);
100 writel(ctl, regs + S3C_PCM_CTL);
101}
102
103static void s3c_pcm_snd_rxctrl(struct s3c_pcm_info *pcm, int on)
104{
105 void __iomem *regs = pcm->regs;
106 u32 ctl, clkctl;
107
108 ctl = readl(regs + S3C_PCM_CTL);
109 clkctl = readl(regs + S3C_PCM_CLKCTL);
110
111 if (on) {
112 ctl |= S3C_PCM_CTL_RXDMA_EN;
113 ctl |= S3C_PCM_CTL_RXFIFO_EN;
114 ctl |= S3C_PCM_CTL_ENABLE;
115 clkctl |= S3C_PCM_CLKCTL_SERCLK_EN;
116 } else {
117 ctl &= ~S3C_PCM_CTL_RXDMA_EN;
118 ctl &= ~S3C_PCM_CTL_RXFIFO_EN;
119
120 if (!(ctl & S3C_PCM_CTL_TXFIFO_EN)) {
121 ctl &= ~S3C_PCM_CTL_ENABLE;
122 if (!pcm->idleclk)
123 clkctl |= S3C_PCM_CLKCTL_SERCLK_EN;
124 }
125 }
126
127 writel(clkctl, regs + S3C_PCM_CLKCTL);
128 writel(ctl, regs + S3C_PCM_CTL);
129}
130
131static int s3c_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
132 struct snd_soc_dai *dai)
133{
134 struct snd_soc_pcm_runtime *rtd = substream->private_data;
135 struct s3c_pcm_info *pcm = to_info(rtd->dai->cpu_dai);
136 unsigned long flags;
137
138 dev_dbg(pcm->dev, "Entered %s\n", __func__);
139
140 switch (cmd) {
141 case SNDRV_PCM_TRIGGER_START:
142 case SNDRV_PCM_TRIGGER_RESUME:
143 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
144 spin_lock_irqsave(&pcm->lock, flags);
145
146 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
147 s3c_pcm_snd_rxctrl(pcm, 1);
148 else
149 s3c_pcm_snd_txctrl(pcm, 1);
150
151 spin_unlock_irqrestore(&pcm->lock, flags);
152 break;
153
154 case SNDRV_PCM_TRIGGER_STOP:
155 case SNDRV_PCM_TRIGGER_SUSPEND:
156 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
157 spin_lock_irqsave(&pcm->lock, flags);
158
159 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
160 s3c_pcm_snd_rxctrl(pcm, 0);
161 else
162 s3c_pcm_snd_txctrl(pcm, 0);
163
164 spin_unlock_irqrestore(&pcm->lock, flags);
165 break;
166
167 default:
168 return -EINVAL;
169 }
170
171 return 0;
172}
173
174static int s3c_pcm_hw_params(struct snd_pcm_substream *substream,
175 struct snd_pcm_hw_params *params,
176 struct snd_soc_dai *socdai)
177{
178 struct snd_soc_pcm_runtime *rtd = substream->private_data;
179 struct snd_soc_dai_link *dai = rtd->dai;
180 struct s3c_pcm_info *pcm = to_info(dai->cpu_dai);
181 struct s3c_dma_params *dma_data;
182 void __iomem *regs = pcm->regs;
183 struct clk *clk;
184 int sclk_div, sync_div;
185 unsigned long flags;
186 u32 clkctl;
187
188 dev_dbg(pcm->dev, "Entered %s\n", __func__);
189
190 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
191 dma_data = pcm->dma_playback;
192 else
193 dma_data = pcm->dma_capture;
194
195 snd_soc_dai_set_dma_data(dai->cpu_dai, substream, dma_data);
196
197 /* Strictly check for sample size */
198 switch (params_format(params)) {
199 case SNDRV_PCM_FORMAT_S16_LE:
200 break;
201 default:
202 return -EINVAL;
203 }
204
205 spin_lock_irqsave(&pcm->lock, flags);
206
207 /* Get hold of the PCMSOURCE_CLK */
208 clkctl = readl(regs + S3C_PCM_CLKCTL);
209 if (clkctl & S3C_PCM_CLKCTL_SERCLKSEL_PCLK)
210 clk = pcm->pclk;
211 else
212 clk = pcm->cclk;
213
214 /* Set the SCLK divider */
215 sclk_div = clk_get_rate(clk) / pcm->sclk_per_fs /
216 params_rate(params) / 2 - 1;
217
218 clkctl &= ~(S3C_PCM_CLKCTL_SCLKDIV_MASK
219 << S3C_PCM_CLKCTL_SCLKDIV_SHIFT);
220 clkctl |= ((sclk_div & S3C_PCM_CLKCTL_SCLKDIV_MASK)
221 << S3C_PCM_CLKCTL_SCLKDIV_SHIFT);
222
223 /* Set the SYNC divider */
224 sync_div = pcm->sclk_per_fs - 1;
225
226 clkctl &= ~(S3C_PCM_CLKCTL_SYNCDIV_MASK
227 << S3C_PCM_CLKCTL_SYNCDIV_SHIFT);
228 clkctl |= ((sync_div & S3C_PCM_CLKCTL_SYNCDIV_MASK)
229 << S3C_PCM_CLKCTL_SYNCDIV_SHIFT);
230
231 writel(clkctl, regs + S3C_PCM_CLKCTL);
232
233 spin_unlock_irqrestore(&pcm->lock, flags);
234
235 dev_dbg(pcm->dev, "PCMSOURCE_CLK-%lu SCLK=%ufs SCLK_DIV=%d SYNC_DIV=%d\n",
236 clk_get_rate(clk), pcm->sclk_per_fs,
237 sclk_div, sync_div);
238
239 return 0;
240}
241
242static int s3c_pcm_set_fmt(struct snd_soc_dai *cpu_dai,
243 unsigned int fmt)
244{
245 struct s3c_pcm_info *pcm = to_info(cpu_dai);
246 void __iomem *regs = pcm->regs;
247 unsigned long flags;
248 int ret = 0;
249 u32 ctl;
250
251 dev_dbg(pcm->dev, "Entered %s\n", __func__);
252
253 spin_lock_irqsave(&pcm->lock, flags);
254
255 ctl = readl(regs + S3C_PCM_CTL);
256
257 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
258 case SND_SOC_DAIFMT_NB_NF:
259 /* Nothing to do, NB_NF by default */
260 break;
261 default:
262 dev_err(pcm->dev, "Unsupported clock inversion!\n");
263 ret = -EINVAL;
264 goto exit;
265 }
266
267 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
268 case SND_SOC_DAIFMT_CBS_CFS:
269 /* Nothing to do, Master by default */
270 break;
271 default:
272 dev_err(pcm->dev, "Unsupported master/slave format!\n");
273 ret = -EINVAL;
274 goto exit;
275 }
276
277 switch (fmt & SND_SOC_DAIFMT_CLOCK_MASK) {
278 case SND_SOC_DAIFMT_CONT:
279 pcm->idleclk = 1;
280 break;
281 case SND_SOC_DAIFMT_GATED:
282 pcm->idleclk = 0;
283 break;
284 default:
285 dev_err(pcm->dev, "Invalid Clock gating request!\n");
286 ret = -EINVAL;
287 goto exit;
288 }
289
290 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
291 case SND_SOC_DAIFMT_DSP_A:
292 ctl |= S3C_PCM_CTL_TXMSB_AFTER_FSYNC;
293 ctl |= S3C_PCM_CTL_RXMSB_AFTER_FSYNC;
294 break;
295 case SND_SOC_DAIFMT_DSP_B:
296 ctl &= ~S3C_PCM_CTL_TXMSB_AFTER_FSYNC;
297 ctl &= ~S3C_PCM_CTL_RXMSB_AFTER_FSYNC;
298 break;
299 default:
300 dev_err(pcm->dev, "Unsupported data format!\n");
301 ret = -EINVAL;
302 goto exit;
303 }
304
305 writel(ctl, regs + S3C_PCM_CTL);
306
307exit:
308 spin_unlock_irqrestore(&pcm->lock, flags);
309
310 return ret;
311}
312
313static int s3c_pcm_set_clkdiv(struct snd_soc_dai *cpu_dai,
314 int div_id, int div)
315{
316 struct s3c_pcm_info *pcm = to_info(cpu_dai);
317
318 switch (div_id) {
319 case S3C_PCM_SCLK_PER_FS:
320 pcm->sclk_per_fs = div;
321 break;
322
323 default:
324 return -EINVAL;
325 }
326
327 return 0;
328}
329
330static int s3c_pcm_set_sysclk(struct snd_soc_dai *cpu_dai,
331 int clk_id, unsigned int freq, int dir)
332{
333 struct s3c_pcm_info *pcm = to_info(cpu_dai);
334 void __iomem *regs = pcm->regs;
335 u32 clkctl = readl(regs + S3C_PCM_CLKCTL);
336
337 switch (clk_id) {
338 case S3C_PCM_CLKSRC_PCLK:
339 clkctl |= S3C_PCM_CLKCTL_SERCLKSEL_PCLK;
340 break;
341
342 case S3C_PCM_CLKSRC_MUX:
343 clkctl &= ~S3C_PCM_CLKCTL_SERCLKSEL_PCLK;
344
345 if (clk_get_rate(pcm->cclk) != freq)
346 clk_set_rate(pcm->cclk, freq);
347
348 break;
349
350 default:
351 return -EINVAL;
352 }
353
354 writel(clkctl, regs + S3C_PCM_CLKCTL);
355
356 return 0;
357}
358
359static struct snd_soc_dai_ops s3c_pcm_dai_ops = {
360 .set_sysclk = s3c_pcm_set_sysclk,
361 .set_clkdiv = s3c_pcm_set_clkdiv,
362 .trigger = s3c_pcm_trigger,
363 .hw_params = s3c_pcm_hw_params,
364 .set_fmt = s3c_pcm_set_fmt,
365};
366
367#define S3C_PCM_RATES SNDRV_PCM_RATE_8000_96000
368
369#define S3C_PCM_DECLARE(n) \
370{ \
371 .name = "samsung-pcm", \
372 .id = (n), \
373 .symmetric_rates = 1, \
374 .ops = &s3c_pcm_dai_ops, \
375 .playback = { \
376 .channels_min = 2, \
377 .channels_max = 2, \
378 .rates = S3C_PCM_RATES, \
379 .formats = SNDRV_PCM_FMTBIT_S16_LE, \
380 }, \
381 .capture = { \
382 .channels_min = 2, \
383 .channels_max = 2, \
384 .rates = S3C_PCM_RATES, \
385 .formats = SNDRV_PCM_FMTBIT_S16_LE, \
386 }, \
387}
388
389struct snd_soc_dai s3c_pcm_dai[] = {
390 S3C_PCM_DECLARE(0),
391 S3C_PCM_DECLARE(1),
392};
393EXPORT_SYMBOL_GPL(s3c_pcm_dai);
394
395static __devinit int s3c_pcm_dev_probe(struct platform_device *pdev)
396{
397 struct s3c_pcm_info *pcm;
398 struct snd_soc_dai *dai;
399 struct resource *mem_res, *dmatx_res, *dmarx_res;
400 struct s3c_audio_pdata *pcm_pdata;
401 int ret;
402
403 /* Check for valid device index */
404 if ((pdev->id < 0) || pdev->id >= ARRAY_SIZE(s3c_pcm)) {
405 dev_err(&pdev->dev, "id %d out of range\n", pdev->id);
406 return -EINVAL;
407 }
408
409 pcm_pdata = pdev->dev.platform_data;
410
411 /* Check for availability of necessary resource */
412 dmatx_res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
413 if (!dmatx_res) {
414 dev_err(&pdev->dev, "Unable to get PCM-TX dma resource\n");
415 return -ENXIO;
416 }
417
418 dmarx_res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
419 if (!dmarx_res) {
420 dev_err(&pdev->dev, "Unable to get PCM-RX dma resource\n");
421 return -ENXIO;
422 }
423
424 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
425 if (!mem_res) {
426 dev_err(&pdev->dev, "Unable to get register resource\n");
427 return -ENXIO;
428 }
429
430 if (pcm_pdata && pcm_pdata->cfg_gpio && pcm_pdata->cfg_gpio(pdev)) {
431 dev_err(&pdev->dev, "Unable to configure gpio\n");
432 return -EINVAL;
433 }
434
435 pcm = &s3c_pcm[pdev->id];
436 pcm->dev = &pdev->dev;
437
438 spin_lock_init(&pcm->lock);
439
440 dai = &s3c_pcm_dai[pdev->id];
441 dai->dev = &pdev->dev;
442
443 /* Default is 128fs */
444 pcm->sclk_per_fs = 128;
445
446 pcm->cclk = clk_get(&pdev->dev, "audio-bus");
447 if (IS_ERR(pcm->cclk)) {
448 dev_err(&pdev->dev, "failed to get audio-bus\n");
449 ret = PTR_ERR(pcm->cclk);
450 goto err1;
451 }
452 clk_enable(pcm->cclk);
453
454 /* record our pcm structure for later use in the callbacks */
455 dai->private_data = pcm;
456
457 if (!request_mem_region(mem_res->start,
458 resource_size(mem_res), "samsung-pcm")) {
459 dev_err(&pdev->dev, "Unable to request register region\n");
460 ret = -EBUSY;
461 goto err2;
462 }
463
464 pcm->regs = ioremap(mem_res->start, 0x100);
465 if (pcm->regs == NULL) {
466 dev_err(&pdev->dev, "cannot ioremap registers\n");
467 ret = -ENXIO;
468 goto err3;
469 }
470
471 pcm->pclk = clk_get(&pdev->dev, "pcm");
472 if (IS_ERR(pcm->pclk)) {
473 dev_err(&pdev->dev, "failed to get pcm_clock\n");
474 ret = -ENOENT;
475 goto err4;
476 }
477 clk_enable(pcm->pclk);
478
479 ret = snd_soc_register_dai(dai);
480 if (ret != 0) {
481 dev_err(&pdev->dev, "failed to get pcm_clock\n");
482 goto err5;
483 }
484
485 s3c_pcm_stereo_in[pdev->id].dma_addr = mem_res->start
486 + S3C_PCM_RXFIFO;
487 s3c_pcm_stereo_out[pdev->id].dma_addr = mem_res->start
488 + S3C_PCM_TXFIFO;
489
490 s3c_pcm_stereo_in[pdev->id].channel = dmarx_res->start;
491 s3c_pcm_stereo_out[pdev->id].channel = dmatx_res->start;
492
493 pcm->dma_capture = &s3c_pcm_stereo_in[pdev->id];
494 pcm->dma_playback = &s3c_pcm_stereo_out[pdev->id];
495
496 return 0;
497
498err5:
499 clk_disable(pcm->pclk);
500 clk_put(pcm->pclk);
501err4:
502 iounmap(pcm->regs);
503err3:
504 release_mem_region(mem_res->start, resource_size(mem_res));
505err2:
506 clk_disable(pcm->cclk);
507 clk_put(pcm->cclk);
508err1:
509 return ret;
510}
511
512static __devexit int s3c_pcm_dev_remove(struct platform_device *pdev)
513{
514 struct s3c_pcm_info *pcm = &s3c_pcm[pdev->id];
515 struct resource *mem_res;
516
517 iounmap(pcm->regs);
518
519 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
520 release_mem_region(mem_res->start, resource_size(mem_res));
521
522 clk_disable(pcm->cclk);
523 clk_disable(pcm->pclk);
524 clk_put(pcm->pclk);
525 clk_put(pcm->cclk);
526
527 return 0;
528}
529
530static struct platform_driver s3c_pcm_driver = {
531 .probe = s3c_pcm_dev_probe,
532 .remove = s3c_pcm_dev_remove,
533 .driver = {
534 .name = "samsung-pcm",
535 .owner = THIS_MODULE,
536 },
537};
538
539static int __init s3c_pcm_init(void)
540{
541 return platform_driver_register(&s3c_pcm_driver);
542}
543module_init(s3c_pcm_init);
544
545static void __exit s3c_pcm_exit(void)
546{
547 platform_driver_unregister(&s3c_pcm_driver);
548}
549module_exit(s3c_pcm_exit);
550
551/* Module information */
552MODULE_AUTHOR("Jaswinder Singh, <jassi.brar@samsung.com>");
553MODULE_DESCRIPTION("S3C PCM Controller Driver");
554MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/s3c-pcm.h b/sound/soc/s3c24xx/s3c-pcm.h
new file mode 100644
index 000000000000..69ff9971692f
--- /dev/null
+++ b/sound/soc/s3c24xx/s3c-pcm.h
@@ -0,0 +1,123 @@
1/* sound/soc/s3c24xx/s3c-pcm.h
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 as
5 * published by the Free Software Foundation.
6 *
7 */
8
9#ifndef __S3C_PCM_H
10#define __S3C_PCM_H __FILE__
11
12/*Register Offsets */
13#define S3C_PCM_CTL (0x00)
14#define S3C_PCM_CLKCTL (0x04)
15#define S3C_PCM_TXFIFO (0x08)
16#define S3C_PCM_RXFIFO (0x0C)
17#define S3C_PCM_IRQCTL (0x10)
18#define S3C_PCM_IRQSTAT (0x14)
19#define S3C_PCM_FIFOSTAT (0x18)
20#define S3C_PCM_CLRINT (0x20)
21
22/* PCM_CTL Bit-Fields */
23#define S3C_PCM_CTL_TXDIPSTICK_MASK (0x3f)
24#define S3C_PCM_CTL_TXDIPSTICK_SHIFT (13)
25#define S3C_PCM_CTL_RXDIPSTICK_MSK (0x3f<<7)
26#define S3C_PCM_CTL_TXDMA_EN (0x1<<6)
27#define S3C_PCM_CTL_RXDMA_EN (0x1<<5)
28#define S3C_PCM_CTL_TXMSB_AFTER_FSYNC (0x1<<4)
29#define S3C_PCM_CTL_RXMSB_AFTER_FSYNC (0x1<<3)
30#define S3C_PCM_CTL_TXFIFO_EN (0x1<<2)
31#define S3C_PCM_CTL_RXFIFO_EN (0x1<<1)
32#define S3C_PCM_CTL_ENABLE (0x1<<0)
33
34/* PCM_CLKCTL Bit-Fields */
35#define S3C_PCM_CLKCTL_SERCLK_EN (0x1<<19)
36#define S3C_PCM_CLKCTL_SERCLKSEL_PCLK (0x1<<18)
37#define S3C_PCM_CLKCTL_SCLKDIV_MASK (0x1ff)
38#define S3C_PCM_CLKCTL_SYNCDIV_MASK (0x1ff)
39#define S3C_PCM_CLKCTL_SCLKDIV_SHIFT (9)
40#define S3C_PCM_CLKCTL_SYNCDIV_SHIFT (0)
41
42/* PCM_TXFIFO Bit-Fields */
43#define S3C_PCM_TXFIFO_DVALID (0x1<<16)
44#define S3C_PCM_TXFIFO_DATA_MSK (0xffff<<0)
45
46/* PCM_RXFIFO Bit-Fields */
47#define S3C_PCM_RXFIFO_DVALID (0x1<<16)
48#define S3C_PCM_RXFIFO_DATA_MSK (0xffff<<0)
49
50/* PCM_IRQCTL Bit-Fields */
51#define S3C_PCM_IRQCTL_IRQEN (0x1<<14)
52#define S3C_PCM_IRQCTL_WRDEN (0x1<<12)
53#define S3C_PCM_IRQCTL_TXEMPTYEN (0x1<<11)
54#define S3C_PCM_IRQCTL_TXALMSTEMPTYEN (0x1<<10)
55#define S3C_PCM_IRQCTL_TXFULLEN (0x1<<9)
56#define S3C_PCM_IRQCTL_TXALMSTFULLEN (0x1<<8)
57#define S3C_PCM_IRQCTL_TXSTARVEN (0x1<<7)
58#define S3C_PCM_IRQCTL_TXERROVRFLEN (0x1<<6)
59#define S3C_PCM_IRQCTL_RXEMPTEN (0x1<<5)
60#define S3C_PCM_IRQCTL_RXALMSTEMPTEN (0x1<<4)
61#define S3C_PCM_IRQCTL_RXFULLEN (0x1<<3)
62#define S3C_PCM_IRQCTL_RXALMSTFULLEN (0x1<<2)
63#define S3C_PCM_IRQCTL_RXSTARVEN (0x1<<1)
64#define S3C_PCM_IRQCTL_RXERROVRFLEN (0x1<<0)
65
66/* PCM_IRQSTAT Bit-Fields */
67#define S3C_PCM_IRQSTAT_IRQPND (0x1<<13)
68#define S3C_PCM_IRQSTAT_WRD_XFER (0x1<<12)
69#define S3C_PCM_IRQSTAT_TXEMPTY (0x1<<11)
70#define S3C_PCM_IRQSTAT_TXALMSTEMPTY (0x1<<10)
71#define S3C_PCM_IRQSTAT_TXFULL (0x1<<9)
72#define S3C_PCM_IRQSTAT_TXALMSTFULL (0x1<<8)
73#define S3C_PCM_IRQSTAT_TXSTARV (0x1<<7)
74#define S3C_PCM_IRQSTAT_TXERROVRFL (0x1<<6)
75#define S3C_PCM_IRQSTAT_RXEMPT (0x1<<5)
76#define S3C_PCM_IRQSTAT_RXALMSTEMPT (0x1<<4)
77#define S3C_PCM_IRQSTAT_RXFULL (0x1<<3)
78#define S3C_PCM_IRQSTAT_RXALMSTFULL (0x1<<2)
79#define S3C_PCM_IRQSTAT_RXSTARV (0x1<<1)
80#define S3C_PCM_IRQSTAT_RXERROVRFL (0x1<<0)
81
82/* PCM_FIFOSTAT Bit-Fields */
83#define S3C_PCM_FIFOSTAT_TXCNT_MSK (0x3f<<14)
84#define S3C_PCM_FIFOSTAT_TXFIFOEMPTY (0x1<<13)
85#define S3C_PCM_FIFOSTAT_TXFIFOALMSTEMPTY (0x1<<12)
86#define S3C_PCM_FIFOSTAT_TXFIFOFULL (0x1<<11)
87#define S3C_PCM_FIFOSTAT_TXFIFOALMSTFULL (0x1<<10)
88#define S3C_PCM_FIFOSTAT_RXCNT_MSK (0x3f<<4)
89#define S3C_PCM_FIFOSTAT_RXFIFOEMPTY (0x1<<3)
90#define S3C_PCM_FIFOSTAT_RXFIFOALMSTEMPTY (0x1<<2)
91#define S3C_PCM_FIFOSTAT_RXFIFOFULL (0x1<<1)
92#define S3C_PCM_FIFOSTAT_RXFIFOALMSTFULL (0x1<<0)
93
94#define S3C_PCM_CLKSRC_PCLK 0
95#define S3C_PCM_CLKSRC_MUX 1
96
97#define S3C_PCM_SCLK_PER_FS 0
98
99/**
100 * struct s3c_pcm_info - S3C PCM Controller information
101 * @dev: The parent device passed to use from the probe.
102 * @regs: The pointer to the device register block.
103 * @dma_playback: DMA information for playback channel.
104 * @dma_capture: DMA information for capture channel.
105 */
106struct s3c_pcm_info {
107 spinlock_t lock;
108 struct device *dev;
109 void __iomem *regs;
110
111 unsigned int sclk_per_fs;
112
113 /* Whether to keep PCMSCLK enabled even when idle(no active xfer) */
114 unsigned int idleclk;
115
116 struct clk *pclk;
117 struct clk *cclk;
118
119 struct s3c_dma_params *dma_playback;
120 struct s3c_dma_params *dma_capture;
121};
122
123#endif /* __S3C_PCM_H */
diff --git a/sound/soc/s3c24xx/s3c2412-i2s.c b/sound/soc/s3c24xx/s3c2412-i2s.c
index a587ec40b449..359e59346ba2 100644
--- a/sound/soc/s3c24xx/s3c2412-i2s.c
+++ b/sound/soc/s3c24xx/s3c2412-i2s.c
@@ -34,11 +34,10 @@
34 34
35#include <plat/regs-s3c2412-iis.h> 35#include <plat/regs-s3c2412-iis.h>
36 36
37#include <plat/audio.h>
38#include <mach/regs-gpio.h> 37#include <mach/regs-gpio.h>
39#include <mach/dma.h> 38#include <mach/dma.h>
40 39
41#include "s3c24xx-pcm.h" 40#include "s3c-dma.h"
42#include "s3c2412-i2s.h" 41#include "s3c2412-i2s.h"
43 42
44#define S3C2412_I2S_DEBUG 0 43#define S3C2412_I2S_DEBUG 0
@@ -51,14 +50,14 @@ static struct s3c2410_dma_client s3c2412_dma_client_in = {
51 .name = "I2S PCM Stereo in" 50 .name = "I2S PCM Stereo in"
52}; 51};
53 52
54static struct s3c24xx_pcm_dma_params s3c2412_i2s_pcm_stereo_out = { 53static struct s3c_dma_params s3c2412_i2s_pcm_stereo_out = {
55 .client = &s3c2412_dma_client_out, 54 .client = &s3c2412_dma_client_out,
56 .channel = DMACH_I2S_OUT, 55 .channel = DMACH_I2S_OUT,
57 .dma_addr = S3C2410_PA_IIS + S3C2412_IISTXD, 56 .dma_addr = S3C2410_PA_IIS + S3C2412_IISTXD,
58 .dma_size = 4, 57 .dma_size = 4,
59}; 58};
60 59
61static struct s3c24xx_pcm_dma_params s3c2412_i2s_pcm_stereo_in = { 60static struct s3c_dma_params s3c2412_i2s_pcm_stereo_in = {
62 .client = &s3c2412_dma_client_in, 61 .client = &s3c2412_dma_client_in,
63 .channel = DMACH_I2S_IN, 62 .channel = DMACH_I2S_IN,
64 .dma_addr = S3C2410_PA_IIS + S3C2412_IISRXD, 63 .dma_addr = S3C2410_PA_IIS + S3C2412_IISRXD,
diff --git a/sound/soc/s3c24xx/s3c2443-ac97.c b/sound/soc/s3c24xx/s3c2443-ac97.c
deleted file mode 100644
index fc1beb0930b9..000000000000
--- a/sound/soc/s3c24xx/s3c2443-ac97.c
+++ /dev/null
@@ -1,433 +0,0 @@
1/*
2 * s3c2443-ac97.c -- ALSA Soc Audio Layer
3 *
4 * (c) 2007 Wolfson Microelectronics PLC.
5 * Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
6 *
7 * Copyright (C) 2005, Sean Choi <sh428.choi@samsung.com>
8 * All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/init.h>
16#include <linux/module.h>
17#include <linux/platform_device.h>
18#include <linux/interrupt.h>
19#include <linux/io.h>
20#include <linux/wait.h>
21#include <linux/delay.h>
22#include <linux/gpio.h>
23#include <linux/clk.h>
24
25#include <sound/core.h>
26#include <sound/pcm.h>
27#include <sound/ac97_codec.h>
28#include <sound/initval.h>
29#include <sound/soc.h>
30
31#include <mach/hardware.h>
32#include <plat/regs-ac97.h>
33#include <mach/regs-gpio.h>
34#include <mach/regs-clock.h>
35#include <plat/audio.h>
36#include <asm/dma.h>
37#include <mach/dma.h>
38
39#include "s3c24xx-pcm.h"
40#include "s3c24xx-ac97.h"
41
42struct s3c24xx_ac97_info {
43 void __iomem *regs;
44 struct clk *ac97_clk;
45};
46static struct s3c24xx_ac97_info s3c24xx_ac97;
47
48static DECLARE_COMPLETION(ac97_completion);
49static u32 codec_ready;
50static DEFINE_MUTEX(ac97_mutex);
51
52static unsigned short s3c2443_ac97_read(struct snd_ac97 *ac97,
53 unsigned short reg)
54{
55 u32 ac_glbctrl;
56 u32 ac_codec_cmd;
57 u32 stat, addr, data;
58
59 mutex_lock(&ac97_mutex);
60
61 codec_ready = S3C_AC97_GLBSTAT_CODECREADY;
62 ac_codec_cmd = readl(s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD);
63 ac_codec_cmd = S3C_AC97_CODEC_CMD_READ | AC_CMD_ADDR(reg);
64 writel(ac_codec_cmd, s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD);
65
66 udelay(50);
67
68 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
69 ac_glbctrl |= S3C_AC97_GLBCTRL_CODECREADYIE;
70 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
71
72 wait_for_completion(&ac97_completion);
73
74 stat = readl(s3c24xx_ac97.regs + S3C_AC97_STAT);
75 addr = (stat >> 16) & 0x7f;
76 data = (stat & 0xffff);
77
78 if (addr != reg)
79 printk(KERN_ERR "s3c24xx-ac97: req addr = %02x,"
80 " rep addr = %02x\n", reg, addr);
81
82 mutex_unlock(&ac97_mutex);
83
84 return (unsigned short)data;
85}
86
87static void s3c2443_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
88 unsigned short val)
89{
90 u32 ac_glbctrl;
91 u32 ac_codec_cmd;
92
93 mutex_lock(&ac97_mutex);
94
95 codec_ready = S3C_AC97_GLBSTAT_CODECREADY;
96 ac_codec_cmd = readl(s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD);
97 ac_codec_cmd = AC_CMD_ADDR(reg) | AC_CMD_DATA(val);
98 writel(ac_codec_cmd, s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD);
99
100 udelay(50);
101
102 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
103 ac_glbctrl |= S3C_AC97_GLBCTRL_CODECREADYIE;
104 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
105
106 wait_for_completion(&ac97_completion);
107
108 ac_codec_cmd = readl(s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD);
109 ac_codec_cmd |= S3C_AC97_CODEC_CMD_READ;
110 writel(ac_codec_cmd, s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD);
111
112 mutex_unlock(&ac97_mutex);
113
114}
115
116static void s3c2443_ac97_warm_reset(struct snd_ac97 *ac97)
117{
118 u32 ac_glbctrl;
119
120 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
121 ac_glbctrl = S3C_AC97_GLBCTRL_WARMRESET;
122 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
123 msleep(1);
124
125 ac_glbctrl = 0;
126 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
127 msleep(1);
128}
129
130static void s3c2443_ac97_cold_reset(struct snd_ac97 *ac97)
131{
132 u32 ac_glbctrl;
133
134 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
135 ac_glbctrl = S3C_AC97_GLBCTRL_COLDRESET;
136 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
137 msleep(1);
138
139 ac_glbctrl = 0;
140 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
141 msleep(1);
142
143 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
144 ac_glbctrl = S3C_AC97_GLBCTRL_ACLINKON;
145 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
146 msleep(1);
147
148 ac_glbctrl |= S3C_AC97_GLBCTRL_TRANSFERDATAENABLE;
149 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
150 msleep(1);
151
152 ac_glbctrl |= S3C_AC97_GLBCTRL_PCMOUTTM_DMA |
153 S3C_AC97_GLBCTRL_PCMINTM_DMA | S3C_AC97_GLBCTRL_MICINTM_DMA;
154 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
155}
156
157static irqreturn_t s3c2443_ac97_irq(int irq, void *dev_id)
158{
159 int status;
160 u32 ac_glbctrl;
161
162 status = readl(s3c24xx_ac97.regs + S3C_AC97_GLBSTAT) & codec_ready;
163
164 if (status) {
165 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
166 ac_glbctrl &= ~S3C_AC97_GLBCTRL_CODECREADYIE;
167 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
168 complete(&ac97_completion);
169 }
170 return IRQ_HANDLED;
171}
172
173struct snd_ac97_bus_ops soc_ac97_ops = {
174 .read = s3c2443_ac97_read,
175 .write = s3c2443_ac97_write,
176 .warm_reset = s3c2443_ac97_warm_reset,
177 .reset = s3c2443_ac97_cold_reset,
178};
179
180static struct s3c2410_dma_client s3c2443_dma_client_out = {
181 .name = "AC97 PCM Stereo out"
182};
183
184static struct s3c2410_dma_client s3c2443_dma_client_in = {
185 .name = "AC97 PCM Stereo in"
186};
187
188static struct s3c2410_dma_client s3c2443_dma_client_micin = {
189 .name = "AC97 Mic Mono in"
190};
191
192static struct s3c24xx_pcm_dma_params s3c2443_ac97_pcm_stereo_out = {
193 .client = &s3c2443_dma_client_out,
194 .channel = DMACH_PCM_OUT,
195 .dma_addr = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA,
196 .dma_size = 4,
197};
198
199static struct s3c24xx_pcm_dma_params s3c2443_ac97_pcm_stereo_in = {
200 .client = &s3c2443_dma_client_in,
201 .channel = DMACH_PCM_IN,
202 .dma_addr = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA,
203 .dma_size = 4,
204};
205
206static struct s3c24xx_pcm_dma_params s3c2443_ac97_mic_mono_in = {
207 .client = &s3c2443_dma_client_micin,
208 .channel = DMACH_MIC_IN,
209 .dma_addr = S3C2440_PA_AC97 + S3C_AC97_MIC_DATA,
210 .dma_size = 4,
211};
212
213static int s3c2443_ac97_probe(struct platform_device *pdev,
214 struct snd_soc_dai *dai)
215{
216 int ret;
217 u32 ac_glbctrl;
218
219 s3c24xx_ac97.regs = ioremap(S3C2440_PA_AC97, 0x100);
220 if (s3c24xx_ac97.regs == NULL)
221 return -ENXIO;
222
223 s3c24xx_ac97.ac97_clk = clk_get(&pdev->dev, "ac97");
224 if (s3c24xx_ac97.ac97_clk == NULL) {
225 printk(KERN_ERR "s3c2443-ac97 failed to get ac97_clock\n");
226 iounmap(s3c24xx_ac97.regs);
227 return -ENODEV;
228 }
229 clk_enable(s3c24xx_ac97.ac97_clk);
230
231 s3c2410_gpio_cfgpin(S3C2410_GPE0, S3C2443_GPE0_AC_nRESET);
232 s3c2410_gpio_cfgpin(S3C2410_GPE1, S3C2443_GPE1_AC_SYNC);
233 s3c2410_gpio_cfgpin(S3C2410_GPE2, S3C2443_GPE2_AC_BITCLK);
234 s3c2410_gpio_cfgpin(S3C2410_GPE3, S3C2443_GPE3_AC_SDI);
235 s3c2410_gpio_cfgpin(S3C2410_GPE4, S3C2443_GPE4_AC_SDO);
236
237 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
238 ac_glbctrl = S3C_AC97_GLBCTRL_COLDRESET;
239 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
240 msleep(1);
241
242 ac_glbctrl = 0;
243 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
244 msleep(1);
245
246 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
247 ac_glbctrl = S3C_AC97_GLBCTRL_ACLINKON;
248 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
249 msleep(1);
250
251 ac_glbctrl |= S3C_AC97_GLBCTRL_TRANSFERDATAENABLE;
252 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
253
254 ret = request_irq(IRQ_S3C244x_AC97, s3c2443_ac97_irq,
255 IRQF_DISABLED, "AC97", NULL);
256 if (ret < 0) {
257 printk(KERN_ERR "s3c24xx-ac97: interrupt request failed.\n");
258 clk_disable(s3c24xx_ac97.ac97_clk);
259 clk_put(s3c24xx_ac97.ac97_clk);
260 iounmap(s3c24xx_ac97.regs);
261 }
262 return ret;
263}
264
265static void s3c2443_ac97_remove(struct platform_device *pdev,
266 struct snd_soc_dai *dai)
267{
268 free_irq(IRQ_S3C244x_AC97, NULL);
269 clk_disable(s3c24xx_ac97.ac97_clk);
270 clk_put(s3c24xx_ac97.ac97_clk);
271 iounmap(s3c24xx_ac97.regs);
272}
273
274static int s3c2443_ac97_hw_params(struct snd_pcm_substream *substream,
275 struct snd_pcm_hw_params *params,
276 struct snd_soc_dai *dai)
277{
278 struct snd_soc_pcm_runtime *rtd = substream->private_data;
279 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
280
281 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
282 cpu_dai->dma_data = &s3c2443_ac97_pcm_stereo_out;
283 else
284 cpu_dai->dma_data = &s3c2443_ac97_pcm_stereo_in;
285
286 return 0;
287}
288
289static int s3c2443_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
290 struct snd_soc_dai *dai)
291{
292 u32 ac_glbctrl;
293 struct snd_soc_pcm_runtime *rtd = substream->private_data;
294 int channel = ((struct s3c24xx_pcm_dma_params *)
295 rtd->dai->cpu_dai->dma_data)->channel;
296
297 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
298 switch (cmd) {
299 case SNDRV_PCM_TRIGGER_START:
300 case SNDRV_PCM_TRIGGER_RESUME:
301 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
302 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
303 ac_glbctrl |= S3C_AC97_GLBCTRL_PCMINTM_DMA;
304 else
305 ac_glbctrl |= S3C_AC97_GLBCTRL_PCMOUTTM_DMA;
306 break;
307 case SNDRV_PCM_TRIGGER_STOP:
308 case SNDRV_PCM_TRIGGER_SUSPEND:
309 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
310 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
311 ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMINTM_MASK;
312 else
313 ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMOUTTM_MASK;
314 break;
315 }
316 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
317
318 s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED);
319
320 return 0;
321}
322
323static int s3c2443_ac97_hw_mic_params(struct snd_pcm_substream *substream,
324 struct snd_pcm_hw_params *params,
325 struct snd_soc_dai *dai)
326{
327 struct snd_soc_pcm_runtime *rtd = substream->private_data;
328 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
329
330 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
331 return -ENODEV;
332 else
333 cpu_dai->dma_data = &s3c2443_ac97_mic_mono_in;
334
335 return 0;
336}
337
338static int s3c2443_ac97_mic_trigger(struct snd_pcm_substream *substream,
339 int cmd, struct snd_soc_dai *dai)
340{
341 u32 ac_glbctrl;
342 struct snd_soc_pcm_runtime *rtd = substream->private_data;
343 int channel = ((struct s3c24xx_pcm_dma_params *)
344 rtd->dai->cpu_dai->dma_data)->channel;
345
346 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
347 switch (cmd) {
348 case SNDRV_PCM_TRIGGER_START:
349 case SNDRV_PCM_TRIGGER_RESUME:
350 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
351 ac_glbctrl |= S3C_AC97_GLBCTRL_PCMINTM_DMA;
352 break;
353 case SNDRV_PCM_TRIGGER_STOP:
354 case SNDRV_PCM_TRIGGER_SUSPEND:
355 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
356 ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMINTM_MASK;
357 }
358 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
359
360 s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED);
361
362 return 0;
363}
364
365#define s3c2443_AC97_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
366 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \
367 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
368
369static struct snd_soc_dai_ops s3c2443_ac97_dai_ops = {
370 .hw_params = s3c2443_ac97_hw_params,
371 .trigger = s3c2443_ac97_trigger,
372};
373
374static struct snd_soc_dai_ops s3c2443_ac97_mic_dai_ops = {
375 .hw_params = s3c2443_ac97_hw_mic_params,
376 .trigger = s3c2443_ac97_mic_trigger,
377};
378
379struct snd_soc_dai s3c2443_ac97_dai[] = {
380{
381 .name = "s3c2443-ac97",
382 .id = 0,
383 .ac97_control = 1,
384 .probe = s3c2443_ac97_probe,
385 .remove = s3c2443_ac97_remove,
386 .playback = {
387 .stream_name = "AC97 Playback",
388 .channels_min = 2,
389 .channels_max = 2,
390 .rates = s3c2443_AC97_RATES,
391 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
392 .capture = {
393 .stream_name = "AC97 Capture",
394 .channels_min = 2,
395 .channels_max = 2,
396 .rates = s3c2443_AC97_RATES,
397 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
398 .ops = &s3c2443_ac97_dai_ops,
399},
400{
401 .name = "pxa2xx-ac97-mic",
402 .id = 1,
403 .ac97_control = 1,
404 .capture = {
405 .stream_name = "AC97 Mic Capture",
406 .channels_min = 1,
407 .channels_max = 1,
408 .rates = s3c2443_AC97_RATES,
409 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
410 .ops = &s3c2443_ac97_mic_dai_ops,
411},
412};
413EXPORT_SYMBOL_GPL(s3c2443_ac97_dai);
414EXPORT_SYMBOL_GPL(soc_ac97_ops);
415
416static int __init s3c2443_ac97_init(void)
417{
418 return snd_soc_register_dais(s3c2443_ac97_dai,
419 ARRAY_SIZE(s3c2443_ac97_dai));
420}
421module_init(s3c2443_ac97_init);
422
423static void __exit s3c2443_ac97_exit(void)
424{
425 snd_soc_unregister_dais(s3c2443_ac97_dai,
426 ARRAY_SIZE(s3c2443_ac97_dai));
427}
428module_exit(s3c2443_ac97_exit);
429
430
431MODULE_AUTHOR("Graeme Gregory");
432MODULE_DESCRIPTION("AC97 driver for the Samsung s3c2443 chip");
433MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/s3c24xx-ac97.h b/sound/soc/s3c24xx/s3c24xx-ac97.h
deleted file mode 100644
index e96f941a810b..000000000000
--- a/sound/soc/s3c24xx/s3c24xx-ac97.h
+++ /dev/null
@@ -1,25 +0,0 @@
1/*
2 * s3c24xx-ac97.c -- ALSA Soc Audio Layer
3 *
4 * (c) 2007 Wolfson Microelectronics PLC.
5 * Author: Graeme Gregory
6 * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 * Revision history
14 * 10th Nov 2006 Initial version.
15 */
16
17#ifndef S3C24XXAC97_H_
18#define S3C24XXAC97_H_
19
20#define AC_CMD_ADDR(x) (x << 16)
21#define AC_CMD_DATA(x) (x & 0xffff)
22
23extern struct snd_soc_dai s3c2443_ac97_dai[];
24
25#endif /*S3C24XXAC97_H_*/
diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.c b/sound/soc/s3c24xx/s3c24xx-i2s.c
index 40e2c4790f0d..c3ac890a3986 100644
--- a/sound/soc/s3c24xx/s3c24xx-i2s.c
+++ b/sound/soc/s3c24xx/s3c24xx-i2s.c
@@ -32,13 +32,13 @@
32#include <mach/hardware.h> 32#include <mach/hardware.h>
33#include <mach/regs-gpio.h> 33#include <mach/regs-gpio.h>
34#include <mach/regs-clock.h> 34#include <mach/regs-clock.h>
35#include <plat/audio.h> 35
36#include <asm/dma.h> 36#include <asm/dma.h>
37#include <mach/dma.h> 37#include <mach/dma.h>
38 38
39#include <plat/regs-iis.h> 39#include <plat/regs-iis.h>
40 40
41#include "s3c24xx-pcm.h" 41#include "s3c-dma.h"
42#include "s3c24xx-i2s.h" 42#include "s3c24xx-i2s.h"
43 43
44static struct s3c2410_dma_client s3c24xx_dma_client_out = { 44static struct s3c2410_dma_client s3c24xx_dma_client_out = {
@@ -49,14 +49,14 @@ static struct s3c2410_dma_client s3c24xx_dma_client_in = {
49 .name = "I2S PCM Stereo in" 49 .name = "I2S PCM Stereo in"
50}; 50};
51 51
52static struct s3c24xx_pcm_dma_params s3c24xx_i2s_pcm_stereo_out = { 52static struct s3c_dma_params s3c24xx_i2s_pcm_stereo_out = {
53 .client = &s3c24xx_dma_client_out, 53 .client = &s3c24xx_dma_client_out,
54 .channel = DMACH_I2S_OUT, 54 .channel = DMACH_I2S_OUT,
55 .dma_addr = S3C2410_PA_IIS + S3C2410_IISFIFO, 55 .dma_addr = S3C2410_PA_IIS + S3C2410_IISFIFO,
56 .dma_size = 2, 56 .dma_size = 2,
57}; 57};
58 58
59static struct s3c24xx_pcm_dma_params s3c24xx_i2s_pcm_stereo_in = { 59static struct s3c_dma_params s3c24xx_i2s_pcm_stereo_in = {
60 .client = &s3c24xx_dma_client_in, 60 .client = &s3c24xx_dma_client_in,
61 .channel = DMACH_I2S_IN, 61 .channel = DMACH_I2S_IN,
62 .dma_addr = S3C2410_PA_IIS + S3C2410_IISFIFO, 62 .dma_addr = S3C2410_PA_IIS + S3C2410_IISFIFO,
@@ -242,14 +242,17 @@ static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream,
242 struct snd_soc_dai *dai) 242 struct snd_soc_dai *dai)
243{ 243{
244 struct snd_soc_pcm_runtime *rtd = substream->private_data; 244 struct snd_soc_pcm_runtime *rtd = substream->private_data;
245 struct s3c_dma_params *dma_data;
245 u32 iismod; 246 u32 iismod;
246 247
247 pr_debug("Entered %s\n", __func__); 248 pr_debug("Entered %s\n", __func__);
248 249
249 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 250 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
250 rtd->dai->cpu_dai->dma_data = &s3c24xx_i2s_pcm_stereo_out; 251 dma_data = &s3c24xx_i2s_pcm_stereo_out;
251 else 252 else
252 rtd->dai->cpu_dai->dma_data = &s3c24xx_i2s_pcm_stereo_in; 253 dma_data = &s3c24xx_i2s_pcm_stereo_in;
254
255 snd_soc_dai_set_dma_data(rtd->dai->cpu_dai, substream, dma_data);
253 256
254 /* Working copies of register */ 257 /* Working copies of register */
255 iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); 258 iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD);
@@ -258,13 +261,11 @@ static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream,
258 switch (params_format(params)) { 261 switch (params_format(params)) {
259 case SNDRV_PCM_FORMAT_S8: 262 case SNDRV_PCM_FORMAT_S8:
260 iismod &= ~S3C2410_IISMOD_16BIT; 263 iismod &= ~S3C2410_IISMOD_16BIT;
261 ((struct s3c24xx_pcm_dma_params *) 264 dma_data->dma_size = 1;
262 rtd->dai->cpu_dai->dma_data)->dma_size = 1;
263 break; 265 break;
264 case SNDRV_PCM_FORMAT_S16_LE: 266 case SNDRV_PCM_FORMAT_S16_LE:
265 iismod |= S3C2410_IISMOD_16BIT; 267 iismod |= S3C2410_IISMOD_16BIT;
266 ((struct s3c24xx_pcm_dma_params *) 268 dma_data->dma_size = 2;
267 rtd->dai->cpu_dai->dma_data)->dma_size = 2;
268 break; 269 break;
269 default: 270 default:
270 return -EINVAL; 271 return -EINVAL;
@@ -280,8 +281,8 @@ static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
280{ 281{
281 int ret = 0; 282 int ret = 0;
282 struct snd_soc_pcm_runtime *rtd = substream->private_data; 283 struct snd_soc_pcm_runtime *rtd = substream->private_data;
283 int channel = ((struct s3c24xx_pcm_dma_params *) 284 struct s3c_dma_params *dma_data =
284 rtd->dai->cpu_dai->dma_data)->channel; 285 snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
285 286
286 pr_debug("Entered %s\n", __func__); 287 pr_debug("Entered %s\n", __func__);
287 288
@@ -300,7 +301,7 @@ static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
300 else 301 else
301 s3c24xx_snd_txctrl(1); 302 s3c24xx_snd_txctrl(1);
302 303
303 s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED); 304 s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED);
304 break; 305 break;
305 case SNDRV_PCM_TRIGGER_STOP: 306 case SNDRV_PCM_TRIGGER_STOP:
306 case SNDRV_PCM_TRIGGER_SUSPEND: 307 case SNDRV_PCM_TRIGGER_SUSPEND:
diff --git a/sound/soc/s3c24xx/s3c24xx_simtec.c b/sound/soc/s3c24xx/s3c24xx_simtec.c
index 1966e0d5652d..4984754f3298 100644
--- a/sound/soc/s3c24xx/s3c24xx_simtec.c
+++ b/sound/soc/s3c24xx/s3c24xx_simtec.c
@@ -21,7 +21,7 @@
21 21
22#include <plat/audio-simtec.h> 22#include <plat/audio-simtec.h>
23 23
24#include "s3c24xx-pcm.h" 24#include "s3c-dma.h"
25#include "s3c24xx-i2s.h" 25#include "s3c24xx-i2s.h"
26#include "s3c24xx_simtec.h" 26#include "s3c24xx_simtec.h"
27 27
@@ -270,7 +270,7 @@ static int attach_gpio_amp(struct device *dev,
270 gpio_direction_output(pd->amp_gain[1], 0); 270 gpio_direction_output(pd->amp_gain[1], 0);
271 } 271 }
272 272
273 /* note, curently we assume GPA0 isn't valid amp */ 273 /* note, currently we assume GPA0 isn't valid amp */
274 if (pdata->amp_gpio > 0) { 274 if (pdata->amp_gpio > 0) {
275 ret = gpio_request(pd->amp_gpio, "gpio-amp"); 275 ret = gpio_request(pd->amp_gpio, "gpio-amp");
276 if (ret) { 276 if (ret) {
@@ -312,7 +312,7 @@ int simtec_audio_resume(struct device *dev)
312 return 0; 312 return 0;
313} 313}
314 314
315struct dev_pm_ops simtec_audio_pmops = { 315const struct dev_pm_ops simtec_audio_pmops = {
316 .resume = simtec_audio_resume, 316 .resume = simtec_audio_resume,
317}; 317};
318EXPORT_SYMBOL_GPL(simtec_audio_pmops); 318EXPORT_SYMBOL_GPL(simtec_audio_pmops);
diff --git a/sound/soc/s3c24xx/s3c24xx_simtec.h b/sound/soc/s3c24xx/s3c24xx_simtec.h
index 2714203af161..e18faee30cce 100644
--- a/sound/soc/s3c24xx/s3c24xx_simtec.h
+++ b/sound/soc/s3c24xx/s3c24xx_simtec.h
@@ -15,7 +15,7 @@ extern int simtec_audio_core_probe(struct platform_device *pdev,
15extern int simtec_audio_remove(struct platform_device *pdev); 15extern int simtec_audio_remove(struct platform_device *pdev);
16 16
17#ifdef CONFIG_PM 17#ifdef CONFIG_PM
18extern struct dev_pm_ops simtec_audio_pmops; 18extern const struct dev_pm_ops simtec_audio_pmops;
19#define simtec_audio_pm &simtec_audio_pmops 19#define simtec_audio_pm &simtec_audio_pmops
20#else 20#else
21#define simtec_audio_pm NULL 21#define simtec_audio_pm NULL
diff --git a/sound/soc/s3c24xx/s3c24xx_simtec_hermes.c b/sound/soc/s3c24xx/s3c24xx_simtec_hermes.c
index 8346bd96eaf5..bdf8951af8e3 100644
--- a/sound/soc/s3c24xx/s3c24xx_simtec_hermes.c
+++ b/sound/soc/s3c24xx/s3c24xx_simtec_hermes.c
@@ -18,7 +18,7 @@
18 18
19#include <plat/audio-simtec.h> 19#include <plat/audio-simtec.h>
20 20
21#include "s3c24xx-pcm.h" 21#include "s3c-dma.h"
22#include "s3c24xx-i2s.h" 22#include "s3c24xx-i2s.h"
23#include "s3c24xx_simtec.h" 23#include "s3c24xx_simtec.h"
24 24
diff --git a/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c b/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c
index 25797e096175..185c0acb5ce6 100644
--- a/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c
+++ b/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c
@@ -18,7 +18,7 @@
18 18
19#include <plat/audio-simtec.h> 19#include <plat/audio-simtec.h>
20 20
21#include "s3c24xx-pcm.h" 21#include "s3c-dma.h"
22#include "s3c24xx-i2s.h" 22#include "s3c24xx-i2s.h"
23#include "s3c24xx_simtec.h" 23#include "s3c24xx_simtec.h"
24 24
diff --git a/sound/soc/s3c24xx/s3c24xx_uda134x.c b/sound/soc/s3c24xx/s3c24xx_uda134x.c
index c215d32d6322..052d59659c29 100644
--- a/sound/soc/s3c24xx/s3c24xx_uda134x.c
+++ b/sound/soc/s3c24xx/s3c24xx_uda134x.c
@@ -24,7 +24,7 @@
24 24
25#include <plat/regs-iis.h> 25#include <plat/regs-iis.h>
26 26
27#include "s3c24xx-pcm.h" 27#include "s3c-dma.h"
28#include "s3c24xx-i2s.h" 28#include "s3c24xx-i2s.h"
29#include "../codecs/uda134x.h" 29#include "../codecs/uda134x.h"
30 30
diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.c b/sound/soc/s3c24xx/s3c64xx-i2s.c
index 105a77eeded0..a72c251401ac 100644
--- a/sound/soc/s3c24xx/s3c64xx-i2s.c
+++ b/sound/soc/s3c24xx/s3c64xx-i2s.c
@@ -15,30 +15,28 @@
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/device.h> 17#include <linux/device.h>
18#include <linux/delay.h>
19#include <linux/clk.h> 18#include <linux/clk.h>
20#include <linux/kernel.h>
21#include <linux/gpio.h> 19#include <linux/gpio.h>
22#include <linux/io.h> 20#include <linux/io.h>
23 21
24#include <sound/core.h>
25#include <sound/pcm.h>
26#include <sound/pcm_params.h>
27#include <sound/initval.h>
28#include <sound/soc.h> 22#include <sound/soc.h>
29 23
30#include <plat/regs-s3c2412-iis.h> 24#include <plat/regs-s3c2412-iis.h>
31#include <plat/gpio-bank-d.h> 25#include <mach/gpio-bank-d.h>
32#include <plat/gpio-bank-e.h> 26#include <mach/gpio-bank-e.h>
33#include <plat/gpio-cfg.h> 27#include <plat/gpio-cfg.h>
34#include <plat/audio.h>
35 28
36#include <mach/map.h> 29#include <mach/map.h>
37#include <mach/dma.h> 30#include <mach/dma.h>
38 31
39#include "s3c24xx-pcm.h" 32#include "s3c-dma.h"
40#include "s3c64xx-i2s.h" 33#include "s3c64xx-i2s.h"
41 34
35/* The value should be set to maximum of the total number
36 * of I2Sv3 controllers that any supported SoC has.
37 */
38#define MAX_I2SV3 2
39
42static struct s3c2410_dma_client s3c64xx_dma_client_out = { 40static struct s3c2410_dma_client s3c64xx_dma_client_out = {
43 .name = "I2S PCM Stereo out" 41 .name = "I2S PCM Stereo out"
44}; 42};
@@ -47,37 +45,12 @@ static struct s3c2410_dma_client s3c64xx_dma_client_in = {
47 .name = "I2S PCM Stereo in" 45 .name = "I2S PCM Stereo in"
48}; 46};
49 47
50static struct s3c24xx_pcm_dma_params s3c64xx_i2s_pcm_stereo_out[2] = { 48static struct s3c_dma_params s3c64xx_i2s_pcm_stereo_out[MAX_I2SV3];
51 [0] = { 49static struct s3c_dma_params s3c64xx_i2s_pcm_stereo_in[MAX_I2SV3];
52 .channel = DMACH_I2S0_OUT, 50static struct s3c_i2sv2_info s3c64xx_i2s[MAX_I2SV3];
53 .client = &s3c64xx_dma_client_out,
54 .dma_addr = S3C64XX_PA_IIS0 + S3C2412_IISTXD,
55 .dma_size = 4,
56 },
57 [1] = {
58 .channel = DMACH_I2S1_OUT,
59 .client = &s3c64xx_dma_client_out,
60 .dma_addr = S3C64XX_PA_IIS1 + S3C2412_IISTXD,
61 .dma_size = 4,
62 },
63};
64 51
65static struct s3c24xx_pcm_dma_params s3c64xx_i2s_pcm_stereo_in[2] = { 52struct snd_soc_dai s3c64xx_i2s_dai[MAX_I2SV3];
66 [0] = { 53EXPORT_SYMBOL_GPL(s3c64xx_i2s_dai);
67 .channel = DMACH_I2S0_IN,
68 .client = &s3c64xx_dma_client_in,
69 .dma_addr = S3C64XX_PA_IIS0 + S3C2412_IISRXD,
70 .dma_size = 4,
71 },
72 [1] = {
73 .channel = DMACH_I2S1_IN,
74 .client = &s3c64xx_dma_client_in,
75 .dma_addr = S3C64XX_PA_IIS1 + S3C2412_IISRXD,
76 .dma_size = 4,
77 },
78};
79
80static struct s3c_i2sv2_info s3c64xx_i2s[2];
81 54
82static inline struct s3c_i2sv2_info *to_info(struct snd_soc_dai *cpu_dai) 55static inline struct s3c_i2sv2_info *to_info(struct snd_soc_dai *cpu_dai)
83{ 56{
@@ -99,6 +72,19 @@ static int s3c64xx_i2s_set_sysclk(struct snd_soc_dai *cpu_dai,
99 iismod |= S3C64XX_IISMOD_IMS_SYSMUX; 72 iismod |= S3C64XX_IISMOD_IMS_SYSMUX;
100 break; 73 break;
101 74
75 case S3C64XX_CLKSRC_CDCLK:
76 switch (dir) {
77 case SND_SOC_CLOCK_IN:
78 iismod |= S3C64XX_IISMOD_CDCLKCON;
79 break;
80 case SND_SOC_CLOCK_OUT:
81 iismod &= ~S3C64XX_IISMOD_CDCLKCON;
82 break;
83 default:
84 return -EINVAL;
85 }
86 break;
87
102 default: 88 default:
103 return -EINVAL; 89 return -EINVAL;
104 } 90 }
@@ -111,8 +97,12 @@ static int s3c64xx_i2s_set_sysclk(struct snd_soc_dai *cpu_dai,
111struct clk *s3c64xx_i2s_get_clock(struct snd_soc_dai *dai) 97struct clk *s3c64xx_i2s_get_clock(struct snd_soc_dai *dai)
112{ 98{
113 struct s3c_i2sv2_info *i2s = to_info(dai); 99 struct s3c_i2sv2_info *i2s = to_info(dai);
100 u32 iismod = readl(i2s->regs + S3C2412_IISMOD);
114 101
115 return i2s->iis_cclk; 102 if (iismod & S3C64XX_IISMOD_IMS_SYSMUX)
103 return i2s->iis_cclk;
104 else
105 return i2s->iis_pclk;
116} 106}
117EXPORT_SYMBOL_GPL(s3c64xx_i2s_get_clock); 107EXPORT_SYMBOL_GPL(s3c64xx_i2s_get_clock);
118 108
@@ -153,55 +143,13 @@ static struct snd_soc_dai_ops s3c64xx_i2s_dai_ops = {
153 .set_sysclk = s3c64xx_i2s_set_sysclk, 143 .set_sysclk = s3c64xx_i2s_set_sysclk,
154}; 144};
155 145
156struct snd_soc_dai s3c64xx_i2s_dai[] = {
157 {
158 .name = "s3c64xx-i2s",
159 .id = 0,
160 .probe = s3c64xx_i2s_probe,
161 .playback = {
162 .channels_min = 2,
163 .channels_max = 2,
164 .rates = S3C64XX_I2S_RATES,
165 .formats = S3C64XX_I2S_FMTS,
166 },
167 .capture = {
168 .channels_min = 2,
169 .channels_max = 2,
170 .rates = S3C64XX_I2S_RATES,
171 .formats = S3C64XX_I2S_FMTS,
172 },
173 .ops = &s3c64xx_i2s_dai_ops,
174 .symmetric_rates = 1,
175 },
176 {
177 .name = "s3c64xx-i2s",
178 .id = 1,
179 .probe = s3c64xx_i2s_probe,
180 .playback = {
181 .channels_min = 2,
182 .channels_max = 2,
183 .rates = S3C64XX_I2S_RATES,
184 .formats = S3C64XX_I2S_FMTS,
185 },
186 .capture = {
187 .channels_min = 2,
188 .channels_max = 2,
189 .rates = S3C64XX_I2S_RATES,
190 .formats = S3C64XX_I2S_FMTS,
191 },
192 .ops = &s3c64xx_i2s_dai_ops,
193 .symmetric_rates = 1,
194 },
195};
196EXPORT_SYMBOL_GPL(s3c64xx_i2s_dai);
197
198static __devinit int s3c64xx_iis_dev_probe(struct platform_device *pdev) 146static __devinit int s3c64xx_iis_dev_probe(struct platform_device *pdev)
199{ 147{
200 struct s3c_i2sv2_info *i2s; 148 struct s3c_i2sv2_info *i2s;
201 struct snd_soc_dai *dai; 149 struct snd_soc_dai *dai;
202 int ret; 150 int ret;
203 151
204 if (pdev->id >= ARRAY_SIZE(s3c64xx_i2s)) { 152 if (pdev->id >= MAX_I2SV3) {
205 dev_err(&pdev->dev, "id %d out of range\n", pdev->id); 153 dev_err(&pdev->dev, "id %d out of range\n", pdev->id);
206 return -EINVAL; 154 return -EINVAL;
207 } 155 }
@@ -209,10 +157,40 @@ static __devinit int s3c64xx_iis_dev_probe(struct platform_device *pdev)
209 i2s = &s3c64xx_i2s[pdev->id]; 157 i2s = &s3c64xx_i2s[pdev->id];
210 dai = &s3c64xx_i2s_dai[pdev->id]; 158 dai = &s3c64xx_i2s_dai[pdev->id];
211 dai->dev = &pdev->dev; 159 dai->dev = &pdev->dev;
160 dai->name = "s3c64xx-i2s";
161 dai->id = pdev->id;
162 dai->symmetric_rates = 1;
163 dai->playback.channels_min = 2;
164 dai->playback.channels_max = 2;
165 dai->playback.rates = S3C64XX_I2S_RATES;
166 dai->playback.formats = S3C64XX_I2S_FMTS;
167 dai->capture.channels_min = 2;
168 dai->capture.channels_max = 2;
169 dai->capture.rates = S3C64XX_I2S_RATES;
170 dai->capture.formats = S3C64XX_I2S_FMTS;
171 dai->probe = s3c64xx_i2s_probe;
172 dai->ops = &s3c64xx_i2s_dai_ops;
212 173
213 i2s->dma_capture = &s3c64xx_i2s_pcm_stereo_in[pdev->id]; 174 i2s->dma_capture = &s3c64xx_i2s_pcm_stereo_in[pdev->id];
214 i2s->dma_playback = &s3c64xx_i2s_pcm_stereo_out[pdev->id]; 175 i2s->dma_playback = &s3c64xx_i2s_pcm_stereo_out[pdev->id];
215 176
177 if (pdev->id == 0) {
178 i2s->dma_capture->channel = DMACH_I2S0_IN;
179 i2s->dma_capture->dma_addr = S3C64XX_PA_IIS0 + S3C2412_IISRXD;
180 i2s->dma_playback->channel = DMACH_I2S0_OUT;
181 i2s->dma_playback->dma_addr = S3C64XX_PA_IIS0 + S3C2412_IISTXD;
182 } else {
183 i2s->dma_capture->channel = DMACH_I2S1_IN;
184 i2s->dma_capture->dma_addr = S3C64XX_PA_IIS1 + S3C2412_IISRXD;
185 i2s->dma_playback->channel = DMACH_I2S1_OUT;
186 i2s->dma_playback->dma_addr = S3C64XX_PA_IIS1 + S3C2412_IISTXD;
187 }
188
189 i2s->dma_capture->client = &s3c64xx_dma_client_in;
190 i2s->dma_capture->dma_size = 4;
191 i2s->dma_playback->client = &s3c64xx_dma_client_out;
192 i2s->dma_playback->dma_size = 4;
193
216 i2s->iis_cclk = clk_get(&pdev->dev, "audio-bus"); 194 i2s->iis_cclk = clk_get(&pdev->dev, "audio-bus");
217 if (IS_ERR(i2s->iis_cclk)) { 195 if (IS_ERR(i2s->iis_cclk)) {
218 dev_err(&pdev->dev, "failed to get audio-bus\n"); 196 dev_err(&pdev->dev, "failed to get audio-bus\n");
diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.h b/sound/soc/s3c24xx/s3c64xx-i2s.h
index 02148cee2613..abe7253b55fc 100644
--- a/sound/soc/s3c24xx/s3c64xx-i2s.h
+++ b/sound/soc/s3c24xx/s3c64xx-i2s.h
@@ -25,6 +25,7 @@ struct clk;
25 25
26#define S3C64XX_CLKSRC_PCLK (0) 26#define S3C64XX_CLKSRC_PCLK (0)
27#define S3C64XX_CLKSRC_MUX (1) 27#define S3C64XX_CLKSRC_MUX (1)
28#define S3C64XX_CLKSRC_CDCLK (2)
28 29
29extern struct snd_soc_dai s3c64xx_i2s_dai[]; 30extern struct snd_soc_dai s3c64xx_i2s_dai[];
30 31
diff --git a/sound/soc/s3c24xx/smdk2443_wm9710.c b/sound/soc/s3c24xx/smdk2443_wm9710.c
index a2a4f5323c17..362258835e8d 100644
--- a/sound/soc/s3c24xx/smdk2443_wm9710.c
+++ b/sound/soc/s3c24xx/smdk2443_wm9710.c
@@ -20,8 +20,8 @@
20#include <sound/soc-dapm.h> 20#include <sound/soc-dapm.h>
21 21
22#include "../codecs/ac97.h" 22#include "../codecs/ac97.h"
23#include "s3c24xx-pcm.h" 23#include "s3c-dma.h"
24#include "s3c24xx-ac97.h" 24#include "s3c-ac97.h"
25 25
26static struct snd_soc_card smdk2443; 26static struct snd_soc_card smdk2443;
27 27
@@ -29,7 +29,7 @@ static struct snd_soc_dai_link smdk2443_dai[] = {
29{ 29{
30 .name = "AC97", 30 .name = "AC97",
31 .stream_name = "AC97 HiFi", 31 .stream_name = "AC97 HiFi",
32 .cpu_dai = &s3c2443_ac97_dai[0], 32 .cpu_dai = &s3c_ac97_dai[S3C_AC97_DAI_PCM],
33 .codec_dai = &ac97_dai, 33 .codec_dai = &ac97_dai,
34}, 34},
35}; 35};
diff --git a/sound/soc/s3c24xx/smdk64xx_wm8580.c b/sound/soc/s3c24xx/smdk64xx_wm8580.c
new file mode 100644
index 000000000000..efe4901213a3
--- /dev/null
+++ b/sound/soc/s3c24xx/smdk64xx_wm8580.c
@@ -0,0 +1,268 @@
1/*
2 * smdk64xx_wm8580.c
3 *
4 * Copyright (c) 2009 Samsung Electronics Co. Ltd
5 * Author: Jaswinder Singh <jassi.brar@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/platform_device.h>
14#include <linux/clk.h>
15#include <sound/core.h>
16#include <sound/pcm.h>
17#include <sound/pcm_params.h>
18#include <sound/soc.h>
19#include <sound/soc-dapm.h>
20
21#include "../codecs/wm8580.h"
22#include "s3c-dma.h"
23#include "s3c64xx-i2s.h"
24
25#define S3C64XX_I2S_V4 2
26
27/* SMDK64XX has a 12MHZ crystal attached to WM8580 */
28#define SMDK64XX_WM8580_FREQ 12000000
29
30static int smdk64xx_hw_params(struct snd_pcm_substream *substream,
31 struct snd_pcm_hw_params *params)
32{
33 struct snd_soc_pcm_runtime *rtd = substream->private_data;
34 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
35 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
36 unsigned int pll_out;
37 int bfs, rfs, ret;
38
39 switch (params_format(params)) {
40 case SNDRV_PCM_FORMAT_U8:
41 case SNDRV_PCM_FORMAT_S8:
42 bfs = 16;
43 break;
44 case SNDRV_PCM_FORMAT_U16_LE:
45 case SNDRV_PCM_FORMAT_S16_LE:
46 bfs = 32;
47 break;
48 default:
49 return -EINVAL;
50 }
51
52 /* The Fvco for WM8580 PLLs must fall within [90,100]MHz.
53 * This criterion can't be met if we request PLL output
54 * as {8000x256, 64000x256, 11025x256}Hz.
55 * As a wayout, we rather change rfs to a minimum value that
56 * results in (params_rate(params) * rfs), and itself, acceptable
57 * to both - the CODEC and the CPU.
58 */
59 switch (params_rate(params)) {
60 case 16000:
61 case 22050:
62 case 32000:
63 case 44100:
64 case 48000:
65 case 88200:
66 case 96000:
67 rfs = 256;
68 break;
69 case 64000:
70 rfs = 384;
71 break;
72 case 8000:
73 case 11025:
74 rfs = 512;
75 break;
76 default:
77 return -EINVAL;
78 }
79 pll_out = params_rate(params) * rfs;
80
81 /* Set the Codec DAI configuration */
82 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S
83 | SND_SOC_DAIFMT_NB_NF
84 | SND_SOC_DAIFMT_CBM_CFM);
85 if (ret < 0)
86 return ret;
87
88 /* Set the AP DAI configuration */
89 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S
90 | SND_SOC_DAIFMT_NB_NF
91 | SND_SOC_DAIFMT_CBM_CFM);
92 if (ret < 0)
93 return ret;
94
95 ret = snd_soc_dai_set_sysclk(cpu_dai, S3C64XX_CLKSRC_CDCLK,
96 0, SND_SOC_CLOCK_IN);
97 if (ret < 0)
98 return ret;
99
100 /* We use PCLK for basic ops in SoC-Slave mode */
101 ret = snd_soc_dai_set_sysclk(cpu_dai, S3C64XX_CLKSRC_PCLK,
102 0, SND_SOC_CLOCK_IN);
103 if (ret < 0)
104 return ret;
105
106 /* Set WM8580 to drive MCLK from its PLLA */
107 ret = snd_soc_dai_set_clkdiv(codec_dai, WM8580_MCLK,
108 WM8580_CLKSRC_PLLA);
109 if (ret < 0)
110 return ret;
111
112 /* Explicitly set WM8580-DAC to source from MCLK */
113 ret = snd_soc_dai_set_clkdiv(codec_dai, WM8580_DAC_CLKSEL,
114 WM8580_CLKSRC_MCLK);
115 if (ret < 0)
116 return ret;
117
118 ret = snd_soc_dai_set_pll(codec_dai, WM8580_PLLA, 0,
119 SMDK64XX_WM8580_FREQ, pll_out);
120 if (ret < 0)
121 return ret;
122
123 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_I2SV2_DIV_BCLK, bfs);
124 if (ret < 0)
125 return ret;
126
127 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_I2SV2_DIV_RCLK, rfs);
128 if (ret < 0)
129 return ret;
130
131 return 0;
132}
133
134/*
135 * SMDK64XX WM8580 DAI operations.
136 */
137static struct snd_soc_ops smdk64xx_ops = {
138 .hw_params = smdk64xx_hw_params,
139};
140
141/* SMDK64xx Playback widgets */
142static const struct snd_soc_dapm_widget wm8580_dapm_widgets_pbk[] = {
143 SND_SOC_DAPM_HP("Front-L/R", NULL),
144 SND_SOC_DAPM_HP("Center/Sub", NULL),
145 SND_SOC_DAPM_HP("Rear-L/R", NULL),
146};
147
148/* SMDK64xx Capture widgets */
149static const struct snd_soc_dapm_widget wm8580_dapm_widgets_cpt[] = {
150 SND_SOC_DAPM_MIC("MicIn", NULL),
151 SND_SOC_DAPM_LINE("LineIn", NULL),
152};
153
154/* SMDK-PAIFTX connections */
155static const struct snd_soc_dapm_route audio_map_tx[] = {
156 /* MicIn feeds AINL */
157 {"AINL", NULL, "MicIn"},
158
159 /* LineIn feeds AINL/R */
160 {"AINL", NULL, "LineIn"},
161 {"AINR", NULL, "LineIn"},
162};
163
164/* SMDK-PAIFRX connections */
165static const struct snd_soc_dapm_route audio_map_rx[] = {
166 /* Front Left/Right are fed VOUT1L/R */
167 {"Front-L/R", NULL, "VOUT1L"},
168 {"Front-L/R", NULL, "VOUT1R"},
169
170 /* Center/Sub are fed VOUT2L/R */
171 {"Center/Sub", NULL, "VOUT2L"},
172 {"Center/Sub", NULL, "VOUT2R"},
173
174 /* Rear Left/Right are fed VOUT3L/R */
175 {"Rear-L/R", NULL, "VOUT3L"},
176 {"Rear-L/R", NULL, "VOUT3R"},
177};
178
179static int smdk64xx_wm8580_init_paiftx(struct snd_soc_codec *codec)
180{
181 /* Add smdk64xx specific Capture widgets */
182 snd_soc_dapm_new_controls(codec, wm8580_dapm_widgets_cpt,
183 ARRAY_SIZE(wm8580_dapm_widgets_cpt));
184
185 /* Set up PAIFTX audio path */
186 snd_soc_dapm_add_routes(codec, audio_map_tx, ARRAY_SIZE(audio_map_tx));
187
188 /* Enabling the microphone requires the fitting of a 0R
189 * resistor to connect the line from the microphone jack.
190 */
191 snd_soc_dapm_disable_pin(codec, "MicIn");
192
193 /* signal a DAPM event */
194 snd_soc_dapm_sync(codec);
195
196 return 0;
197}
198
199static int smdk64xx_wm8580_init_paifrx(struct snd_soc_codec *codec)
200{
201 /* Add smdk64xx specific Playback widgets */
202 snd_soc_dapm_new_controls(codec, wm8580_dapm_widgets_pbk,
203 ARRAY_SIZE(wm8580_dapm_widgets_pbk));
204
205 /* Set up PAIFRX audio path */
206 snd_soc_dapm_add_routes(codec, audio_map_rx, ARRAY_SIZE(audio_map_rx));
207
208 /* signal a DAPM event */
209 snd_soc_dapm_sync(codec);
210
211 return 0;
212}
213
214static struct snd_soc_dai_link smdk64xx_dai[] = {
215{ /* Primary Playback i/f */
216 .name = "WM8580 PAIF RX",
217 .stream_name = "Playback",
218 .cpu_dai = &s3c64xx_i2s_dai[S3C64XX_I2S_V4],
219 .codec_dai = &wm8580_dai[WM8580_DAI_PAIFRX],
220 .init = smdk64xx_wm8580_init_paifrx,
221 .ops = &smdk64xx_ops,
222},
223{ /* Primary Capture i/f */
224 .name = "WM8580 PAIF TX",
225 .stream_name = "Capture",
226 .cpu_dai = &s3c64xx_i2s_dai[S3C64XX_I2S_V4],
227 .codec_dai = &wm8580_dai[WM8580_DAI_PAIFTX],
228 .init = smdk64xx_wm8580_init_paiftx,
229 .ops = &smdk64xx_ops,
230},
231};
232
233static struct snd_soc_card smdk64xx = {
234 .name = "smdk64xx",
235 .platform = &s3c24xx_soc_platform,
236 .dai_link = smdk64xx_dai,
237 .num_links = ARRAY_SIZE(smdk64xx_dai),
238};
239
240static struct snd_soc_device smdk64xx_snd_devdata = {
241 .card = &smdk64xx,
242 .codec_dev = &soc_codec_dev_wm8580,
243};
244
245static struct platform_device *smdk64xx_snd_device;
246
247static int __init smdk64xx_audio_init(void)
248{
249 int ret;
250
251 smdk64xx_snd_device = platform_device_alloc("soc-audio", -1);
252 if (!smdk64xx_snd_device)
253 return -ENOMEM;
254
255 platform_set_drvdata(smdk64xx_snd_device, &smdk64xx_snd_devdata);
256 smdk64xx_snd_devdata.dev = &smdk64xx_snd_device->dev;
257 ret = platform_device_add(smdk64xx_snd_device);
258
259 if (ret)
260 platform_device_put(smdk64xx_snd_device);
261
262 return ret;
263}
264module_init(smdk64xx_audio_init);
265
266MODULE_AUTHOR("Jaswinder Singh, jassi.brar@samsung.com");
267MODULE_DESCRIPTION("ALSA SoC SMDK64XX WM8580");
268MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/smdk_wm9713.c b/sound/soc/s3c24xx/smdk_wm9713.c
new file mode 100644
index 000000000000..24fd39f38ccb
--- /dev/null
+++ b/sound/soc/s3c24xx/smdk_wm9713.c
@@ -0,0 +1,94 @@
1/*
2 * smdk_wm9713.c -- SoC audio for SMDK
3 *
4 * Copyright 2010 Samsung Electronics Co. Ltd.
5 * Author: Jaswinder Singh Brar <jassi.brar@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of the
10 * License, or (at your option) any later version.
11 *
12 */
13
14#include <linux/module.h>
15#include <linux/device.h>
16#include <sound/soc.h>
17
18#include "../codecs/wm9713.h"
19#include "s3c-dma.h"
20#include "s3c-ac97.h"
21
22static struct snd_soc_card smdk;
23
24/*
25 * Default CFG switch settings to use this driver:
26 *
27 * SMDK6410: Set CFG1 1-3 On, CFG2 1-4 Off
28 */
29
30/*
31 Playback (HeadPhone):-
32 $ amixer sset 'Headphone' unmute
33 $ amixer sset 'Right Headphone Out Mux' 'Headphone'
34 $ amixer sset 'Left Headphone Out Mux' 'Headphone'
35 $ amixer sset 'Right HP Mixer PCM' unmute
36 $ amixer sset 'Left HP Mixer PCM' unmute
37
38 Capture (LineIn):-
39 $ amixer sset 'Right Capture Source' 'Line'
40 $ amixer sset 'Left Capture Source' 'Line'
41*/
42
43static struct snd_soc_dai_link smdk_dai = {
44 .name = "AC97",
45 .stream_name = "AC97 PCM",
46 .cpu_dai = &s3c_ac97_dai[S3C_AC97_DAI_PCM],
47 .codec_dai = &wm9713_dai[WM9713_DAI_AC97_HIFI],
48};
49
50static struct snd_soc_card smdk = {
51 .name = "SMDK",
52 .platform = &s3c24xx_soc_platform,
53 .dai_link = &smdk_dai,
54 .num_links = 1,
55};
56
57static struct snd_soc_device smdk_snd_ac97_devdata = {
58 .card = &smdk,
59 .codec_dev = &soc_codec_dev_wm9713,
60};
61
62static struct platform_device *smdk_snd_ac97_device;
63
64static int __init smdk_init(void)
65{
66 int ret;
67
68 smdk_snd_ac97_device = platform_device_alloc("soc-audio", -1);
69 if (!smdk_snd_ac97_device)
70 return -ENOMEM;
71
72 platform_set_drvdata(smdk_snd_ac97_device,
73 &smdk_snd_ac97_devdata);
74 smdk_snd_ac97_devdata.dev = &smdk_snd_ac97_device->dev;
75
76 ret = platform_device_add(smdk_snd_ac97_device);
77 if (ret)
78 platform_device_put(smdk_snd_ac97_device);
79
80 return ret;
81}
82
83static void __exit smdk_exit(void)
84{
85 platform_device_unregister(smdk_snd_ac97_device);
86}
87
88module_init(smdk_init);
89module_exit(smdk_exit);
90
91/* Module information */
92MODULE_AUTHOR("Jaswinder Singh Brar, jassi.brar@samsung.com");
93MODULE_DESCRIPTION("ALSA SoC SMDK+WM9713");
94MODULE_LICENSE("GPL");
diff --git a/sound/soc/s6000/s6000-i2s.c b/sound/soc/s6000/s6000-i2s.c
index c5cda187ecab..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>
@@ -518,7 +519,8 @@ static int __devinit s6000_i2s_probe(struct platform_device *pdev)
518 519
519 s6000_i2s_dai.dev = &pdev->dev; 520 s6000_i2s_dai.dev = &pdev->dev;
520 s6000_i2s_dai.private_data = dev; 521 s6000_i2s_dai.private_data = dev;
521 s6000_i2s_dai.dma_data = &dev->dma_params; 522 s6000_i2s_dai.capture.dma_data = &dev->dma_params;
523 s6000_i2s_dai.playback.dma_data = &dev->dma_params;
522 524
523 dev->sifbase = sifmem->start; 525 dev->sifbase = sifmem->start;
524 dev->scbbase = mmio; 526 dev->scbbase = mmio;
diff --git a/sound/soc/s6000/s6000-pcm.c b/sound/soc/s6000/s6000-pcm.c
index 83b8028e209d..9c7f7f00cebb 100644
--- a/sound/soc/s6000/s6000-pcm.c
+++ b/sound/soc/s6000/s6000-pcm.c
@@ -58,13 +58,15 @@ static void s6000_pcm_enqueue_dma(struct snd_pcm_substream *substream)
58 struct snd_pcm_runtime *runtime = substream->runtime; 58 struct snd_pcm_runtime *runtime = substream->runtime;
59 struct s6000_runtime_data *prtd = runtime->private_data; 59 struct s6000_runtime_data *prtd = runtime->private_data;
60 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; 60 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
61 struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data; 61 struct s6000_pcm_dma_params *par;
62 int channel; 62 int channel;
63 unsigned int period_size; 63 unsigned int period_size;
64 unsigned int dma_offset; 64 unsigned int dma_offset;
65 dma_addr_t dma_pos; 65 dma_addr_t dma_pos;
66 dma_addr_t src, dst; 66 dma_addr_t src, dst;
67 67
68 par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
69
68 period_size = snd_pcm_lib_period_bytes(substream); 70 period_size = snd_pcm_lib_period_bytes(substream);
69 dma_offset = prtd->period * period_size; 71 dma_offset = prtd->period * period_size;
70 dma_pos = runtime->dma_addr + dma_offset; 72 dma_pos = runtime->dma_addr + dma_offset;
@@ -101,7 +103,8 @@ static irqreturn_t s6000_pcm_irq(int irq, void *data)
101{ 103{
102 struct snd_pcm *pcm = data; 104 struct snd_pcm *pcm = data;
103 struct snd_soc_pcm_runtime *runtime = pcm->private_data; 105 struct snd_soc_pcm_runtime *runtime = pcm->private_data;
104 struct s6000_pcm_dma_params *params = runtime->dai->cpu_dai->dma_data; 106 struct s6000_pcm_dma_params *params =
107 snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
105 struct s6000_runtime_data *prtd; 108 struct s6000_runtime_data *prtd;
106 unsigned int has_xrun; 109 unsigned int has_xrun;
107 int i, ret = IRQ_NONE; 110 int i, ret = IRQ_NONE;
@@ -172,11 +175,13 @@ static int s6000_pcm_start(struct snd_pcm_substream *substream)
172{ 175{
173 struct s6000_runtime_data *prtd = substream->runtime->private_data; 176 struct s6000_runtime_data *prtd = substream->runtime->private_data;
174 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; 177 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
175 struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data; 178 struct s6000_pcm_dma_params *par;
176 unsigned long flags; 179 unsigned long flags;
177 int srcinc; 180 int srcinc;
178 u32 dma; 181 u32 dma;
179 182
183 par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
184
180 spin_lock_irqsave(&prtd->lock, flags); 185 spin_lock_irqsave(&prtd->lock, flags);
181 186
182 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 187 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
@@ -196,7 +201,7 @@ static int s6000_pcm_start(struct snd_pcm_substream *substream)
196 0 /* destination skip after chunk (impossible) */, 201 0 /* destination skip after chunk (impossible) */,
197 4 /* 16 byte burst size */, 202 4 /* 16 byte burst size */,
198 -1 /* don't conserve bandwidth */, 203 -1 /* don't conserve bandwidth */,
199 0 /* low watermark irq descriptor theshold */, 204 0 /* low watermark irq descriptor threshold */,
200 0 /* disable hardware timestamps */, 205 0 /* disable hardware timestamps */,
201 1 /* enable channel */); 206 1 /* enable channel */);
202 207
@@ -212,10 +217,12 @@ static int s6000_pcm_stop(struct snd_pcm_substream *substream)
212{ 217{
213 struct s6000_runtime_data *prtd = substream->runtime->private_data; 218 struct s6000_runtime_data *prtd = substream->runtime->private_data;
214 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; 219 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
215 struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data; 220 struct s6000_pcm_dma_params *par;
216 unsigned long flags; 221 unsigned long flags;
217 u32 channel; 222 u32 channel;
218 223
224 par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
225
219 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 226 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
220 channel = par->dma_out; 227 channel = par->dma_out;
221 else 228 else
@@ -236,9 +243,11 @@ static int s6000_pcm_stop(struct snd_pcm_substream *substream)
236static int s6000_pcm_trigger(struct snd_pcm_substream *substream, int cmd) 243static int s6000_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
237{ 244{
238 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; 245 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
239 struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data; 246 struct s6000_pcm_dma_params *par;
240 int ret; 247 int ret;
241 248
249 par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
250
242 ret = par->trigger(substream, cmd, 0); 251 ret = par->trigger(substream, cmd, 0);
243 if (ret < 0) 252 if (ret < 0)
244 return ret; 253 return ret;
@@ -275,13 +284,15 @@ static int s6000_pcm_prepare(struct snd_pcm_substream *substream)
275static snd_pcm_uframes_t s6000_pcm_pointer(struct snd_pcm_substream *substream) 284static snd_pcm_uframes_t s6000_pcm_pointer(struct snd_pcm_substream *substream)
276{ 285{
277 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; 286 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
278 struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data; 287 struct s6000_pcm_dma_params *par;
279 struct snd_pcm_runtime *runtime = substream->runtime; 288 struct snd_pcm_runtime *runtime = substream->runtime;
280 struct s6000_runtime_data *prtd = runtime->private_data; 289 struct s6000_runtime_data *prtd = runtime->private_data;
281 unsigned long flags; 290 unsigned long flags;
282 unsigned int offset; 291 unsigned int offset;
283 dma_addr_t count; 292 dma_addr_t count;
284 293
294 par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
295
285 spin_lock_irqsave(&prtd->lock, flags); 296 spin_lock_irqsave(&prtd->lock, flags);
286 297
287 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 298 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -305,11 +316,12 @@ static snd_pcm_uframes_t s6000_pcm_pointer(struct snd_pcm_substream *substream)
305static int s6000_pcm_open(struct snd_pcm_substream *substream) 316static int s6000_pcm_open(struct snd_pcm_substream *substream)
306{ 317{
307 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; 318 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
308 struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data; 319 struct s6000_pcm_dma_params *par;
309 struct snd_pcm_runtime *runtime = substream->runtime; 320 struct snd_pcm_runtime *runtime = substream->runtime;
310 struct s6000_runtime_data *prtd; 321 struct s6000_runtime_data *prtd;
311 int ret; 322 int ret;
312 323
324 par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
313 snd_soc_set_runtime_hwparams(substream, &s6000_pcm_hardware); 325 snd_soc_set_runtime_hwparams(substream, &s6000_pcm_hardware);
314 326
315 ret = snd_pcm_hw_constraint_step(runtime, 0, 327 ret = snd_pcm_hw_constraint_step(runtime, 0,
@@ -364,7 +376,7 @@ static int s6000_pcm_hw_params(struct snd_pcm_substream *substream,
364 struct snd_pcm_hw_params *hw_params) 376 struct snd_pcm_hw_params *hw_params)
365{ 377{
366 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; 378 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
367 struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data; 379 struct s6000_pcm_dma_params *par;
368 int ret; 380 int ret;
369 ret = snd_pcm_lib_malloc_pages(substream, 381 ret = snd_pcm_lib_malloc_pages(substream,
370 params_buffer_bytes(hw_params)); 382 params_buffer_bytes(hw_params));
@@ -373,6 +385,8 @@ static int s6000_pcm_hw_params(struct snd_pcm_substream *substream,
373 return ret; 385 return ret;
374 } 386 }
375 387
388 par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
389
376 if (par->same_rate) { 390 if (par->same_rate) {
377 spin_lock(&par->lock); 391 spin_lock(&par->lock);
378 if (par->rate == -1 || 392 if (par->rate == -1 ||
@@ -392,7 +406,8 @@ static int s6000_pcm_hw_params(struct snd_pcm_substream *substream,
392static int s6000_pcm_hw_free(struct snd_pcm_substream *substream) 406static int s6000_pcm_hw_free(struct snd_pcm_substream *substream)
393{ 407{
394 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; 408 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
395 struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data; 409 struct s6000_pcm_dma_params *par =
410 snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
396 411
397 spin_lock(&par->lock); 412 spin_lock(&par->lock);
398 par->in_use &= ~(1 << substream->stream); 413 par->in_use &= ~(1 << substream->stream);
@@ -417,25 +432,28 @@ static struct snd_pcm_ops s6000_pcm_ops = {
417static void s6000_pcm_free(struct snd_pcm *pcm) 432static void s6000_pcm_free(struct snd_pcm *pcm)
418{ 433{
419 struct snd_soc_pcm_runtime *runtime = pcm->private_data; 434 struct snd_soc_pcm_runtime *runtime = pcm->private_data;
420 struct s6000_pcm_dma_params *params = runtime->dai->cpu_dai->dma_data; 435 struct s6000_pcm_dma_params *params =
436 snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
421 437
422 free_irq(params->irq, pcm); 438 free_irq(params->irq, pcm);
423 snd_pcm_lib_preallocate_free_for_all(pcm); 439 snd_pcm_lib_preallocate_free_for_all(pcm);
424} 440}
425 441
426static u64 s6000_pcm_dmamask = DMA_32BIT_MASK; 442static u64 s6000_pcm_dmamask = DMA_BIT_MASK(32);
427 443
428static int s6000_pcm_new(struct snd_card *card, 444static int s6000_pcm_new(struct snd_card *card,
429 struct snd_soc_dai *dai, struct snd_pcm *pcm) 445 struct snd_soc_dai *dai, struct snd_pcm *pcm)
430{ 446{
431 struct snd_soc_pcm_runtime *runtime = pcm->private_data; 447 struct snd_soc_pcm_runtime *runtime = pcm->private_data;
432 struct s6000_pcm_dma_params *params = runtime->dai->cpu_dai->dma_data; 448 struct s6000_pcm_dma_params *params;
433 int res; 449 int res;
434 450
451 params = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
452
435 if (!card->dev->dma_mask) 453 if (!card->dev->dma_mask)
436 card->dev->dma_mask = &s6000_pcm_dmamask; 454 card->dev->dma_mask = &s6000_pcm_dmamask;
437 if (!card->dev->coherent_dma_mask) 455 if (!card->dev->coherent_dma_mask)
438 card->dev->coherent_dma_mask = DMA_32BIT_MASK; 456 card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
439 457
440 if (params->dma_in) { 458 if (params->dma_in) {
441 s6dmac_disable_chan(DMA_MASK_DMAC(params->dma_in), 459 s6dmac_disable_chan(DMA_MASK_DMAC(params->dma_in),
diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig
index 9154b4363db3..f07f6d8b93e1 100644
--- a/sound/soc/sh/Kconfig
+++ b/sound/soc/sh/Kconfig
@@ -23,10 +23,17 @@ config SND_SOC_SH4_SSI
23config SND_SOC_SH4_FSI 23config SND_SOC_SH4_FSI
24 tristate "SH4 FSI support" 24 tristate "SH4 FSI support"
25 depends on CPU_SUBTYPE_SH7724 25 depends on CPU_SUBTYPE_SH7724
26 select SH_DMA
27 help 26 help
28 This option enables FSI sound support 27 This option enables FSI sound support
29 28
29config SND_SOC_SH4_SIU
30 tristate
31 depends on (SUPERH || ARCH_SHMOBILE) && HAVE_CLK
32 select DMA_ENGINE
33 select DMADEVICES
34 select SH_DMAE
35 select FW_LOADER
36
30## 37##
31## Boards 38## Boards
32## 39##
@@ -48,4 +55,20 @@ config SND_FSI_AK4642
48 This option enables generic sound support for the 55 This option enables generic sound support for the
49 FSI - AK4642 unit 56 FSI - AK4642 unit
50 57
58config SND_FSI_DA7210
59 bool "FSI-DA7210 sound support"
60 depends on SND_SOC_SH4_FSI
61 select SND_SOC_DA7210
62 help
63 This option enables generic sound support for the
64 FSI - DA7210 unit
65
66config SND_SIU_MIGOR
67 tristate "SIU sound support on Migo-R"
68 depends on SH_MIGOR
69 select SND_SOC_SH4_SIU
70 select SND_SOC_WM8978
71 help
72 This option enables sound support for the SH7722 Migo-R board
73
51endmenu 74endmenu
diff --git a/sound/soc/sh/Makefile b/sound/soc/sh/Makefile
index a6997872f24e..8a5a19293bda 100644
--- a/sound/soc/sh/Makefile
+++ b/sound/soc/sh/Makefile
@@ -6,13 +6,19 @@ obj-$(CONFIG_SND_SOC_PCM_SH7760) += snd-soc-dma-sh7760.o
6snd-soc-hac-objs := hac.o 6snd-soc-hac-objs := hac.o
7snd-soc-ssi-objs := ssi.o 7snd-soc-ssi-objs := ssi.o
8snd-soc-fsi-objs := fsi.o 8snd-soc-fsi-objs := fsi.o
9snd-soc-siu-objs := siu_pcm.o siu_dai.o
9obj-$(CONFIG_SND_SOC_SH4_HAC) += snd-soc-hac.o 10obj-$(CONFIG_SND_SOC_SH4_HAC) += snd-soc-hac.o
10obj-$(CONFIG_SND_SOC_SH4_SSI) += snd-soc-ssi.o 11obj-$(CONFIG_SND_SOC_SH4_SSI) += snd-soc-ssi.o
11obj-$(CONFIG_SND_SOC_SH4_FSI) += snd-soc-fsi.o 12obj-$(CONFIG_SND_SOC_SH4_FSI) += snd-soc-fsi.o
13obj-$(CONFIG_SND_SOC_SH4_SIU) += snd-soc-siu.o
12 14
13## boards 15## boards
14snd-soc-sh7760-ac97-objs := sh7760-ac97.o 16snd-soc-sh7760-ac97-objs := sh7760-ac97.o
15snd-soc-fsi-ak4642-objs := fsi-ak4642.o 17snd-soc-fsi-ak4642-objs := fsi-ak4642.o
18snd-soc-fsi-da7210-objs := fsi-da7210.o
19snd-soc-migor-objs := migor.o
16 20
17obj-$(CONFIG_SND_SH7760_AC97) += snd-soc-sh7760-ac97.o 21obj-$(CONFIG_SND_SH7760_AC97) += snd-soc-sh7760-ac97.o
18obj-$(CONFIG_SND_FSI_AK4642) += snd-soc-fsi-ak4642.o 22obj-$(CONFIG_SND_FSI_AK4642) += snd-soc-fsi-ak4642.o
23obj-$(CONFIG_SND_FSI_DA7210) += snd-soc-fsi-da7210.o
24obj-$(CONFIG_SND_SIU_MIGOR) += snd-soc-migor.o
diff --git a/sound/soc/sh/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-ak4642.c b/sound/soc/sh/fsi-ak4642.c
index c7af09729c6e..5263ab18f827 100644
--- a/sound/soc/sh/fsi-ak4642.c
+++ b/sound/soc/sh/fsi-ak4642.c
@@ -42,42 +42,12 @@ static struct snd_soc_device fsi_snd_devdata = {
42 .codec_dev = &soc_codec_dev_ak4642, 42 .codec_dev = &soc_codec_dev_ak4642,
43}; 43};
44 44
45#define AK4642_BUS 0
46#define AK4642_ADR 0x12
47static int ak4642_add_i2c_device(void)
48{
49 struct i2c_board_info info;
50 struct i2c_adapter *adapter;
51 struct i2c_client *client;
52
53 memset(&info, 0, sizeof(struct i2c_board_info));
54 info.addr = AK4642_ADR;
55 strlcpy(info.type, "ak4642", I2C_NAME_SIZE);
56
57 adapter = i2c_get_adapter(AK4642_BUS);
58 if (!adapter) {
59 printk(KERN_DEBUG "can't get i2c adapter\n");
60 return -ENODEV;
61 }
62
63 client = i2c_new_device(adapter, &info);
64 i2c_put_adapter(adapter);
65 if (!client) {
66 printk(KERN_DEBUG "can't add i2c device\n");
67 return -ENODEV;
68 }
69
70 return 0;
71}
72
73static struct platform_device *fsi_snd_device; 45static struct platform_device *fsi_snd_device;
74 46
75static int __init fsi_ak4642_init(void) 47static int __init fsi_ak4642_init(void)
76{ 48{
77 int ret = -ENOMEM; 49 int ret = -ENOMEM;
78 50
79 ak4642_add_i2c_device();
80
81 fsi_snd_device = platform_device_alloc("soc-audio", -1); 51 fsi_snd_device = platform_device_alloc("soc-audio", -1);
82 if (!fsi_snd_device) 52 if (!fsi_snd_device)
83 goto out; 53 goto out;
diff --git a/sound/soc/sh/fsi-da7210.c b/sound/soc/sh/fsi-da7210.c
new file mode 100644
index 000000000000..33b4d177f466
--- /dev/null
+++ b/sound/soc/sh/fsi-da7210.c
@@ -0,0 +1,83 @@
1/*
2 * fsi-da7210.c
3 *
4 * Copyright (C) 2009 Renesas Solutions Corp.
5 * Kuninori Morimoto <morimoto.kuninori@renesas.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/interrupt.h>
14#include <linux/platform_device.h>
15#include <linux/io.h>
16#include <linux/i2c.h>
17#include <sound/core.h>
18#include <sound/pcm.h>
19#include <sound/pcm_params.h>
20#include <sound/soc.h>
21#include <sound/soc-dapm.h>
22
23#include <sound/sh_fsi.h>
24#include "../codecs/da7210.h"
25
26static int fsi_da7210_init(struct snd_soc_codec *codec)
27{
28 return snd_soc_dai_set_fmt(&da7210_dai,
29 SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
30 SND_SOC_DAIFMT_CBM_CFM);
31}
32
33static struct snd_soc_dai_link fsi_da7210_dai = {
34 .name = "DA7210",
35 .stream_name = "DA7210",
36 .cpu_dai = &fsi_soc_dai[1], /* FSI B */
37 .codec_dai = &da7210_dai,
38 .init = fsi_da7210_init,
39};
40
41static struct snd_soc_card fsi_soc_card = {
42 .name = "FSI",
43 .platform = &fsi_soc_platform,
44 .dai_link = &fsi_da7210_dai,
45 .num_links = 1,
46};
47
48static struct snd_soc_device fsi_da7210_snd_devdata = {
49 .card = &fsi_soc_card,
50 .codec_dev = &soc_codec_dev_da7210,
51};
52
53static struct platform_device *fsi_da7210_snd_device;
54
55static int __init fsi_da7210_sound_init(void)
56{
57 int ret;
58
59 fsi_da7210_snd_device = platform_device_alloc("soc-audio", -1);
60 if (!fsi_da7210_snd_device)
61 return -ENOMEM;
62
63 platform_set_drvdata(fsi_da7210_snd_device, &fsi_da7210_snd_devdata);
64 fsi_da7210_snd_devdata.dev = &fsi_da7210_snd_device->dev;
65 ret = platform_device_add(fsi_da7210_snd_device);
66 if (ret)
67 platform_device_put(fsi_da7210_snd_device);
68
69 return ret;
70}
71
72static void __exit fsi_da7210_sound_exit(void)
73{
74 platform_device_unregister(fsi_da7210_snd_device);
75}
76
77module_init(fsi_da7210_sound_init);
78module_exit(fsi_da7210_sound_exit);
79
80/* Module information */
81MODULE_DESCRIPTION("ALSA SoC FSI DA2710");
82MODULE_AUTHOR("Kuninori Morimoto <morimoto.kuninori@renesas.com>");
83MODULE_LICENSE("GPL");
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 44123248b630..8dc966f45c36 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -17,8 +17,9 @@
17#include <linux/platform_device.h> 17#include <linux/platform_device.h>
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/list.h> 19#include <linux/list.h>
20#include <linux/clk.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>
@@ -26,8 +27,6 @@
26#include <sound/pcm_params.h> 27#include <sound/pcm_params.h>
27#include <sound/sh_fsi.h> 28#include <sound/sh_fsi.h>
28#include <asm/atomic.h> 29#include <asm/atomic.h>
29#include <asm/dma.h>
30#include <asm/dma-sh.h>
31 30
32#define DO_FMT 0x0000 31#define DO_FMT 0x0000
33#define DOFF_CTL 0x0004 32#define DOFF_CTL 0x0004
@@ -69,6 +68,7 @@
69/* DOFF_ST */ 68/* DOFF_ST */
70#define ERR_OVER 0x00000010 69#define ERR_OVER 0x00000010
71#define ERR_UNDER 0x00000001 70#define ERR_UNDER 0x00000001
71#define ST_ERR (ERR_OVER | ERR_UNDER)
72 72
73/* CLK_RST */ 73/* CLK_RST */
74#define B_CLK 0x00000010 74#define B_CLK 0x00000010
@@ -94,10 +94,10 @@
94struct fsi_priv { 94struct fsi_priv {
95 void __iomem *base; 95 void __iomem *base;
96 struct snd_pcm_substream *substream; 96 struct snd_pcm_substream *substream;
97 struct fsi_master *master;
97 98
98 int fifo_max; 99 int fifo_max;
99 int chan; 100 int chan;
100 int dma_chan;
101 101
102 int byte_offset; 102 int byte_offset;
103 int period_len; 103 int period_len;
@@ -108,14 +108,12 @@ struct fsi_priv {
108struct fsi_master { 108struct fsi_master {
109 void __iomem *base; 109 void __iomem *base;
110 int irq; 110 int irq;
111 struct clk *clk;
112 struct fsi_priv fsia; 111 struct fsi_priv fsia;
113 struct fsi_priv fsib; 112 struct fsi_priv fsib;
114 struct sh_fsi_platform_info *info; 113 struct sh_fsi_platform_info *info;
114 spinlock_t lock;
115}; 115};
116 116
117static struct fsi_master *master;
118
119/************************************************************************ 117/************************************************************************
120 118
121 119
@@ -123,35 +121,35 @@ static struct fsi_master *master;
123 121
124 122
125************************************************************************/ 123************************************************************************/
126static int __fsi_reg_write(u32 reg, u32 data) 124static void __fsi_reg_write(u32 reg, u32 data)
127{ 125{
128 /* valid data area is 24bit */ 126 /* valid data area is 24bit */
129 data &= 0x00ffffff; 127 data &= 0x00ffffff;
130 128
131 return ctrl_outl(data, reg); 129 __raw_writel(data, reg);
132} 130}
133 131
134static u32 __fsi_reg_read(u32 reg) 132static u32 __fsi_reg_read(u32 reg)
135{ 133{
136 return ctrl_inl(reg); 134 return __raw_readl(reg);
137} 135}
138 136
139static int __fsi_reg_mask_set(u32 reg, u32 mask, u32 data) 137static void __fsi_reg_mask_set(u32 reg, u32 mask, u32 data)
140{ 138{
141 u32 val = __fsi_reg_read(reg); 139 u32 val = __fsi_reg_read(reg);
142 140
143 val &= ~mask; 141 val &= ~mask;
144 val |= data & mask; 142 val |= data & mask;
145 143
146 return __fsi_reg_write(reg, val); 144 __fsi_reg_write(reg, val);
147} 145}
148 146
149static int fsi_reg_write(struct fsi_priv *fsi, u32 reg, u32 data) 147static void fsi_reg_write(struct fsi_priv *fsi, u32 reg, u32 data)
150{ 148{
151 if (reg > REG_END) 149 if (reg > REG_END)
152 return -1; 150 return;
153 151
154 return __fsi_reg_write((u32)(fsi->base + reg), data); 152 __fsi_reg_write((u32)(fsi->base + reg), data);
155} 153}
156 154
157static u32 fsi_reg_read(struct fsi_priv *fsi, u32 reg) 155static u32 fsi_reg_read(struct fsi_priv *fsi, u32 reg)
@@ -162,39 +160,55 @@ static u32 fsi_reg_read(struct fsi_priv *fsi, u32 reg)
162 return __fsi_reg_read((u32)(fsi->base + reg)); 160 return __fsi_reg_read((u32)(fsi->base + reg));
163} 161}
164 162
165static int fsi_reg_mask_set(struct fsi_priv *fsi, u32 reg, u32 mask, u32 data) 163static void fsi_reg_mask_set(struct fsi_priv *fsi, u32 reg, u32 mask, u32 data)
166{ 164{
167 if (reg > REG_END) 165 if (reg > REG_END)
168 return -1; 166 return;
169 167
170 return __fsi_reg_mask_set((u32)(fsi->base + reg), mask, data); 168 __fsi_reg_mask_set((u32)(fsi->base + reg), mask, data);
171} 169}
172 170
173static int fsi_master_write(u32 reg, u32 data) 171static void fsi_master_write(struct fsi_master *master, u32 reg, u32 data)
174{ 172{
173 unsigned long flags;
174
175 if ((reg < MREG_START) || 175 if ((reg < MREG_START) ||
176 (reg > MREG_END)) 176 (reg > MREG_END))
177 return -1; 177 return;
178 178
179 return __fsi_reg_write((u32)(master->base + reg), data); 179 spin_lock_irqsave(&master->lock, flags);
180 __fsi_reg_write((u32)(master->base + reg), data);
181 spin_unlock_irqrestore(&master->lock, flags);
180} 182}
181 183
182static u32 fsi_master_read(u32 reg) 184static u32 fsi_master_read(struct fsi_master *master, u32 reg)
183{ 185{
186 u32 ret;
187 unsigned long flags;
188
184 if ((reg < MREG_START) || 189 if ((reg < MREG_START) ||
185 (reg > MREG_END)) 190 (reg > MREG_END))
186 return 0; 191 return 0;
187 192
188 return __fsi_reg_read((u32)(master->base + reg)); 193 spin_lock_irqsave(&master->lock, flags);
194 ret = __fsi_reg_read((u32)(master->base + reg));
195 spin_unlock_irqrestore(&master->lock, flags);
196
197 return ret;
189} 198}
190 199
191static int fsi_master_mask_set(u32 reg, u32 mask, u32 data) 200static void fsi_master_mask_set(struct fsi_master *master,
201 u32 reg, u32 mask, u32 data)
192{ 202{
203 unsigned long flags;
204
193 if ((reg < MREG_START) || 205 if ((reg < MREG_START) ||
194 (reg > MREG_END)) 206 (reg > MREG_END))
195 return -1; 207 return;
196 208
197 return __fsi_reg_mask_set((u32)(master->base + reg), mask, data); 209 spin_lock_irqsave(&master->lock, flags);
210 __fsi_reg_mask_set((u32)(master->base + reg), mask, data);
211 spin_unlock_irqrestore(&master->lock, flags);
198} 212}
199 213
200/************************************************************************ 214/************************************************************************
@@ -204,43 +218,35 @@ static int fsi_master_mask_set(u32 reg, u32 mask, u32 data)
204 218
205 219
206************************************************************************/ 220************************************************************************/
207static struct fsi_priv *fsi_get(struct snd_pcm_substream *substream) 221static struct fsi_master *fsi_get_master(struct fsi_priv *fsi)
208{ 222{
209 struct snd_soc_pcm_runtime *rtd; 223 return fsi->master;
210 struct fsi_priv *fsi = NULL; 224}
211 225
212 if (!substream || !master) 226static int fsi_is_port_a(struct fsi_priv *fsi)
213 return NULL; 227{
228 return fsi->master->base == fsi->base;
229}
214 230
215 rtd = substream->private_data; 231static struct snd_soc_dai *fsi_get_dai(struct snd_pcm_substream *substream)
216 switch (rtd->dai->cpu_dai->id) { 232{
217 case 0: 233 struct snd_soc_pcm_runtime *rtd = substream->private_data;
218 fsi = &master->fsia; 234 struct snd_soc_dai_link *machine = rtd->dai;
219 break;
220 case 1:
221 fsi = &master->fsib;
222 break;
223 }
224 235
225 return fsi; 236 return machine->cpu_dai;
226} 237}
227 238
228static int fsi_is_port_a(struct fsi_priv *fsi) 239static struct fsi_priv *fsi_get_priv(struct snd_pcm_substream *substream)
229{ 240{
230 /* return 241 struct snd_soc_dai *dai = fsi_get_dai(substream);
231 * 1 : port a
232 * 0 : port b
233 */
234
235 if (fsi == &master->fsia)
236 return 1;
237 242
238 return 0; 243 return dai->private_data;
239} 244}
240 245
241static u32 fsi_get_info_flags(struct fsi_priv *fsi) 246static u32 fsi_get_info_flags(struct fsi_priv *fsi)
242{ 247{
243 int is_porta = fsi_is_port_a(fsi); 248 int is_porta = fsi_is_port_a(fsi);
249 struct fsi_master *master = fsi_get_master(fsi);
244 250
245 return is_porta ? master->info->porta_flags : 251 return is_porta ? master->info->porta_flags :
246 master->info->portb_flags; 252 master->info->portb_flags;
@@ -308,62 +314,6 @@ static int fsi_get_fifo_residue(struct fsi_priv *fsi, int is_play)
308 return residue; 314 return residue;
309} 315}
310 316
311static int fsi_get_residue(struct fsi_priv *fsi, int is_play)
312{
313 int residue;
314 int width;
315 struct snd_pcm_runtime *runtime;
316
317 runtime = fsi->substream->runtime;
318
319 /* get 1 channel data width */
320 width = frames_to_bytes(runtime, 1) / fsi->chan;
321
322 if (2 == width)
323 residue = fsi_get_fifo_residue(fsi, is_play);
324 else
325 residue = get_dma_residue(fsi->dma_chan);
326
327 return residue;
328}
329
330/************************************************************************
331
332
333 basic dma function
334
335
336************************************************************************/
337#define PORTA_DMA 0
338#define PORTB_DMA 1
339
340static int fsi_get_dma_chan(void)
341{
342 if (0 != request_dma(PORTA_DMA, "fsia"))
343 return -EIO;
344
345 if (0 != request_dma(PORTB_DMA, "fsib")) {
346 free_dma(PORTA_DMA);
347 return -EIO;
348 }
349
350 master->fsia.dma_chan = PORTA_DMA;
351 master->fsib.dma_chan = PORTB_DMA;
352
353 return 0;
354}
355
356static void fsi_free_dma_chan(void)
357{
358 dma_wait_for_completion(PORTA_DMA);
359 dma_wait_for_completion(PORTB_DMA);
360 free_dma(PORTA_DMA);
361 free_dma(PORTB_DMA);
362
363 master->fsia.dma_chan = -1;
364 master->fsib.dma_chan = -1;
365}
366
367/************************************************************************ 317/************************************************************************
368 318
369 319
@@ -374,27 +324,30 @@ static void fsi_free_dma_chan(void)
374static void fsi_irq_enable(struct fsi_priv *fsi, int is_play) 324static void fsi_irq_enable(struct fsi_priv *fsi, int is_play)
375{ 325{
376 u32 data = fsi_port_ab_io_bit(fsi, is_play); 326 u32 data = fsi_port_ab_io_bit(fsi, is_play);
327 struct fsi_master *master = fsi_get_master(fsi);
377 328
378 fsi_master_mask_set(IMSK, data, data); 329 fsi_master_mask_set(master, IMSK, data, data);
379 fsi_master_mask_set(IEMSK, data, data); 330 fsi_master_mask_set(master, IEMSK, data, data);
380} 331}
381 332
382static void fsi_irq_disable(struct fsi_priv *fsi, int is_play) 333static void fsi_irq_disable(struct fsi_priv *fsi, int is_play)
383{ 334{
384 u32 data = fsi_port_ab_io_bit(fsi, is_play); 335 u32 data = fsi_port_ab_io_bit(fsi, is_play);
336 struct fsi_master *master = fsi_get_master(fsi);
385 337
386 fsi_master_mask_set(IMSK, data, 0); 338 fsi_master_mask_set(master, IMSK, data, 0);
387 fsi_master_mask_set(IEMSK, data, 0); 339 fsi_master_mask_set(master, IEMSK, data, 0);
388} 340}
389 341
390static void fsi_clk_ctrl(struct fsi_priv *fsi, int enable) 342static void fsi_clk_ctrl(struct fsi_priv *fsi, int enable)
391{ 343{
392 u32 val = fsi_is_port_a(fsi) ? (1 << 0) : (1 << 4); 344 u32 val = fsi_is_port_a(fsi) ? (1 << 0) : (1 << 4);
345 struct fsi_master *master = fsi_get_master(fsi);
393 346
394 if (enable) 347 if (enable)
395 fsi_master_mask_set(CLK_RST, val, val); 348 fsi_master_mask_set(master, CLK_RST, val, val);
396 else 349 else
397 fsi_master_mask_set(CLK_RST, val, 0); 350 fsi_master_mask_set(master, CLK_RST, val, 0);
398} 351}
399 352
400static void fsi_irq_init(struct fsi_priv *fsi, int is_play) 353static void fsi_irq_init(struct fsi_priv *fsi, int is_play)
@@ -415,79 +368,46 @@ static void fsi_irq_init(struct fsi_priv *fsi, int is_play)
415 fsi_reg_mask_set(fsi, ctrl, FIFO_CLR, FIFO_CLR); 368 fsi_reg_mask_set(fsi, ctrl, FIFO_CLR, FIFO_CLR);
416 369
417 /* clear interrupt factor */ 370 /* clear interrupt factor */
418 fsi_master_mask_set(INT_ST, data, 0); 371 fsi_master_mask_set(fsi_get_master(fsi), INT_ST, data, 0);
419} 372}
420 373
421static void fsi_soft_all_reset(void) 374static void fsi_soft_all_reset(struct fsi_master *master)
422{ 375{
423 u32 status = fsi_master_read(SOFT_RST); 376 u32 status = fsi_master_read(master, SOFT_RST);
424 377
425 /* port AB reset */ 378 /* port AB reset */
426 status &= 0x000000ff; 379 status &= 0x000000ff;
427 fsi_master_write(SOFT_RST, status); 380 fsi_master_write(master, SOFT_RST, status);
428 mdelay(10); 381 mdelay(10);
429 382
430 /* soft reset */ 383 /* soft reset */
431 status &= 0x000000f0; 384 status &= 0x000000f0;
432 fsi_master_write(SOFT_RST, status); 385 fsi_master_write(master, SOFT_RST, status);
433 status |= 0x00000001; 386 status |= 0x00000001;
434 fsi_master_write(SOFT_RST, status); 387 fsi_master_write(master, SOFT_RST, status);
435 mdelay(10); 388 mdelay(10);
436} 389}
437 390
438static void fsi_16data_push(struct fsi_priv *fsi,
439 struct snd_pcm_runtime *runtime,
440 int send)
441{
442 u16 *dma_start;
443 u32 snd;
444 int i;
445
446 /* get dma start position for FSI */
447 dma_start = (u16 *)runtime->dma_area;
448 dma_start += fsi->byte_offset / 2;
449
450 /*
451 * soft dma
452 * FSI can not use DMA when 16bpp
453 */
454 for (i = 0; i < send; i++) {
455 snd = (u32)dma_start[i];
456 fsi_reg_write(fsi, DODT, snd << 8);
457 }
458}
459
460static void fsi_32data_push(struct fsi_priv *fsi,
461 struct snd_pcm_runtime *runtime,
462 int send)
463{
464 u32 *dma_start;
465
466 /* get dma start position for FSI */
467 dma_start = (u32 *)runtime->dma_area;
468 dma_start += fsi->byte_offset / 4;
469
470 dma_wait_for_completion(fsi->dma_chan);
471 dma_configure_channel(fsi->dma_chan, (SM_INC|0x400|TS_32|TM_BUR));
472 dma_write(fsi->dma_chan, (u32)dma_start,
473 (u32)(fsi->base + DODT), send * 4);
474}
475
476/* playback interrupt */ 391/* playback interrupt */
477static int fsi_data_push(struct fsi_priv *fsi) 392static int fsi_data_push(struct fsi_priv *fsi, int startup)
478{ 393{
479 struct snd_pcm_runtime *runtime; 394 struct snd_pcm_runtime *runtime;
480 struct snd_pcm_substream *substream = NULL; 395 struct snd_pcm_substream *substream = NULL;
396 u32 status;
481 int send; 397 int send;
482 int fifo_free; 398 int fifo_free;
483 int width; 399 int width;
400 u8 *start;
401 int i, over_period;
484 402
485 if (!fsi || 403 if (!fsi ||
486 !fsi->substream || 404 !fsi->substream ||
487 !fsi->substream->runtime) 405 !fsi->substream->runtime)
488 return -EINVAL; 406 return -EINVAL;
489 407
490 runtime = fsi->substream->runtime; 408 over_period = 0;
409 substream = fsi->substream;
410 runtime = substream->runtime;
491 411
492 /* FSI FIFO has limit. 412 /* FSI FIFO has limit.
493 * So, this driver can not send periods data at a time 413 * So, this driver can not send periods data at a time
@@ -495,7 +415,7 @@ static int fsi_data_push(struct fsi_priv *fsi)
495 if (fsi->byte_offset >= 415 if (fsi->byte_offset >=
496 fsi->period_len * (fsi->periods + 1)) { 416 fsi->period_len * (fsi->periods + 1)) {
497 417
498 substream = fsi->substream; 418 over_period = 1;
499 fsi->periods = (fsi->periods + 1) % runtime->periods; 419 fsi->periods = (fsi->periods + 1) % runtime->periods;
500 420
501 if (0 == fsi->periods) 421 if (0 == fsi->periods)
@@ -515,18 +435,122 @@ static int fsi_data_push(struct fsi_priv *fsi)
515 if (fifo_free < send) 435 if (fifo_free < send)
516 send = fifo_free; 436 send = fifo_free;
517 437
518 if (2 == width) 438 start = runtime->dma_area;
519 fsi_16data_push(fsi, runtime, send); 439 start += fsi->byte_offset;
520 else if (4 == width) 440
521 fsi_32data_push(fsi, runtime, send); 441 switch (width) {
522 else 442 case 2:
443 for (i = 0; i < send; i++)
444 fsi_reg_write(fsi, DODT,
445 ((u32)*((u16 *)start + i) << 8));
446 break;
447 case 4:
448 for (i = 0; i < send; i++)
449 fsi_reg_write(fsi, DODT, *((u32 *)start + i));
450 break;
451 default:
523 return -EINVAL; 452 return -EINVAL;
453 }
524 454
525 fsi->byte_offset += send * width; 455 fsi->byte_offset += send * width;
526 456
457 status = fsi_reg_read(fsi, DOFF_ST);
458 if (!startup) {
459 struct snd_soc_dai *dai = fsi_get_dai(substream);
460
461 if (status & ERR_OVER)
462 dev_err(dai->dev, "over run\n");
463 if (status & ERR_UNDER)
464 dev_err(dai->dev, "under run\n");
465 }
466 fsi_reg_write(fsi, DOFF_ST, 0);
467
527 fsi_irq_enable(fsi, 1); 468 fsi_irq_enable(fsi, 1);
528 469
529 if (substream) 470 if (over_period)
471 snd_pcm_period_elapsed(substream);
472
473 return 0;
474}
475
476static int fsi_data_pop(struct fsi_priv *fsi, int startup)
477{
478 struct snd_pcm_runtime *runtime;
479 struct snd_pcm_substream *substream = NULL;
480 u32 status;
481 int free;
482 int fifo_fill;
483 int width;
484 u8 *start;
485 int i, over_period;
486
487 if (!fsi ||
488 !fsi->substream ||
489 !fsi->substream->runtime)
490 return -EINVAL;
491
492 over_period = 0;
493 substream = fsi->substream;
494 runtime = substream->runtime;
495
496 /* FSI FIFO has limit.
497 * So, this driver can not send periods data at a time
498 */
499 if (fsi->byte_offset >=
500 fsi->period_len * (fsi->periods + 1)) {
501
502 over_period = 1;
503 fsi->periods = (fsi->periods + 1) % runtime->periods;
504
505 if (0 == fsi->periods)
506 fsi->byte_offset = 0;
507 }
508
509 /* get 1 channel data width */
510 width = frames_to_bytes(runtime, 1) / fsi->chan;
511
512 /* get free space for alsa */
513 free = (fsi->buffer_len - fsi->byte_offset) / width;
514
515 /* get recv size */
516 fifo_fill = fsi_get_fifo_residue(fsi, 0);
517
518 if (free < fifo_fill)
519 fifo_fill = free;
520
521 start = runtime->dma_area;
522 start += fsi->byte_offset;
523
524 switch (width) {
525 case 2:
526 for (i = 0; i < fifo_fill; i++)
527 *((u16 *)start + i) =
528 (u16)(fsi_reg_read(fsi, DIDT) >> 8);
529 break;
530 case 4:
531 for (i = 0; i < fifo_fill; i++)
532 *((u32 *)start + i) = fsi_reg_read(fsi, DIDT);
533 break;
534 default:
535 return -EINVAL;
536 }
537
538 fsi->byte_offset += fifo_fill * width;
539
540 status = fsi_reg_read(fsi, DIFF_ST);
541 if (!startup) {
542 struct snd_soc_dai *dai = fsi_get_dai(substream);
543
544 if (status & ERR_OVER)
545 dev_err(dai->dev, "over run\n");
546 if (status & ERR_UNDER)
547 dev_err(dai->dev, "under run\n");
548 }
549 fsi_reg_write(fsi, DIFF_ST, 0);
550
551 fsi_irq_enable(fsi, 0);
552
553 if (over_period)
530 snd_pcm_period_elapsed(substream); 554 snd_pcm_period_elapsed(substream);
531 555
532 return 0; 556 return 0;
@@ -534,19 +558,24 @@ static int fsi_data_push(struct fsi_priv *fsi)
534 558
535static irqreturn_t fsi_interrupt(int irq, void *data) 559static irqreturn_t fsi_interrupt(int irq, void *data)
536{ 560{
537 u32 status = fsi_master_read(SOFT_RST) & ~0x00000010; 561 struct fsi_master *master = data;
538 u32 int_st = fsi_master_read(INT_ST); 562 u32 status = fsi_master_read(master, SOFT_RST) & ~0x00000010;
563 u32 int_st = fsi_master_read(master, INT_ST);
539 564
540 /* clear irq status */ 565 /* clear irq status */
541 fsi_master_write(SOFT_RST, status); 566 fsi_master_write(master, SOFT_RST, status);
542 fsi_master_write(SOFT_RST, status | 0x00000010); 567 fsi_master_write(master, SOFT_RST, status | 0x00000010);
543 568
544 if (int_st & INT_A_OUT) 569 if (int_st & INT_A_OUT)
545 fsi_data_push(&master->fsia); 570 fsi_data_push(&master->fsia, 0);
546 if (int_st & INT_B_OUT) 571 if (int_st & INT_B_OUT)
547 fsi_data_push(&master->fsib); 572 fsi_data_push(&master->fsib, 0);
573 if (int_st & INT_A_IN)
574 fsi_data_pop(&master->fsia, 0);
575 if (int_st & INT_B_IN)
576 fsi_data_pop(&master->fsib, 0);
548 577
549 fsi_master_write(INT_ST, 0x0000000); 578 fsi_master_write(master, INT_ST, 0x0000000);
550 579
551 return IRQ_HANDLED; 580 return IRQ_HANDLED;
552} 581}
@@ -561,7 +590,7 @@ static irqreturn_t fsi_interrupt(int irq, void *data)
561static int fsi_dai_startup(struct snd_pcm_substream *substream, 590static int fsi_dai_startup(struct snd_pcm_substream *substream,
562 struct snd_soc_dai *dai) 591 struct snd_soc_dai *dai)
563{ 592{
564 struct fsi_priv *fsi = fsi_get(substream); 593 struct fsi_priv *fsi = fsi_get_priv(substream);
565 const char *msg; 594 const char *msg;
566 u32 flags = fsi_get_info_flags(fsi); 595 u32 flags = fsi_get_info_flags(fsi);
567 u32 fmt; 596 u32 fmt;
@@ -571,7 +600,7 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
571 int is_master; 600 int is_master;
572 int ret = 0; 601 int ret = 0;
573 602
574 clk_enable(master->clk); 603 pm_runtime_get_sync(dai->dev);
575 604
576 /* CKG1 */ 605 /* CKG1 */
577 data = is_play ? (1 << 0) : (1 << 4); 606 data = is_play ? (1 << 0) : (1 << 4);
@@ -664,8 +693,6 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
664 } 693 }
665 694
666 fsi_reg_write(fsi, reg, data); 695 fsi_reg_write(fsi, reg, data);
667 dev_dbg(dai->dev, "use %s format (%d channel) use %d DMAC\n",
668 msg, fsi->chan, fsi->dma_chan);
669 696
670 /* 697 /*
671 * clear clk reset if master mode 698 * clear clk reset if master mode
@@ -682,33 +709,29 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
682static void fsi_dai_shutdown(struct snd_pcm_substream *substream, 709static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
683 struct snd_soc_dai *dai) 710 struct snd_soc_dai *dai)
684{ 711{
685 struct fsi_priv *fsi = fsi_get(substream); 712 struct fsi_priv *fsi = fsi_get_priv(substream);
686 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 713 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
687 714
688 fsi_irq_disable(fsi, is_play); 715 fsi_irq_disable(fsi, is_play);
689 fsi_clk_ctrl(fsi, 0); 716 fsi_clk_ctrl(fsi, 0);
690 717
691 clk_disable(master->clk); 718 pm_runtime_put_sync(dai->dev);
692} 719}
693 720
694static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd, 721static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
695 struct snd_soc_dai *dai) 722 struct snd_soc_dai *dai)
696{ 723{
697 struct fsi_priv *fsi = fsi_get(substream); 724 struct fsi_priv *fsi = fsi_get_priv(substream);
698 struct snd_pcm_runtime *runtime = substream->runtime; 725 struct snd_pcm_runtime *runtime = substream->runtime;
699 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 726 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
700 int ret = 0; 727 int ret = 0;
701 728
702 /* capture not supported */
703 if (!is_play)
704 return -ENODEV;
705
706 switch (cmd) { 729 switch (cmd) {
707 case SNDRV_PCM_TRIGGER_START: 730 case SNDRV_PCM_TRIGGER_START:
708 fsi_stream_push(fsi, substream, 731 fsi_stream_push(fsi, substream,
709 frames_to_bytes(runtime, runtime->buffer_size), 732 frames_to_bytes(runtime, runtime->buffer_size),
710 frames_to_bytes(runtime, runtime->period_size)); 733 frames_to_bytes(runtime, runtime->period_size));
711 ret = fsi_data_push(fsi); 734 ret = is_play ? fsi_data_push(fsi, 1) : fsi_data_pop(fsi, 1);
712 break; 735 break;
713 case SNDRV_PCM_TRIGGER_STOP: 736 case SNDRV_PCM_TRIGGER_STOP:
714 fsi_irq_disable(fsi, is_play); 737 fsi_irq_disable(fsi, is_play);
@@ -779,11 +802,10 @@ static int fsi_hw_free(struct snd_pcm_substream *substream)
779static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream) 802static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream)
780{ 803{
781 struct snd_pcm_runtime *runtime = substream->runtime; 804 struct snd_pcm_runtime *runtime = substream->runtime;
782 struct fsi_priv *fsi = fsi_get(substream); 805 struct fsi_priv *fsi = fsi_get_priv(substream);
783 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
784 long location; 806 long location;
785 807
786 location = (fsi->byte_offset - 1) - fsi_get_residue(fsi, is_play); 808 location = (fsi->byte_offset - 1);
787 if (location < 0) 809 if (location < 0)
788 location = 0; 810 location = 0;
789 811
@@ -845,7 +867,12 @@ struct snd_soc_dai fsi_soc_dai[] = {
845 .channels_min = 1, 867 .channels_min = 1,
846 .channels_max = 8, 868 .channels_max = 8,
847 }, 869 },
848 /* capture not supported */ 870 .capture = {
871 .rates = FSI_RATES,
872 .formats = FSI_FMTS,
873 .channels_min = 1,
874 .channels_max = 8,
875 },
849 .ops = &fsi_dai_ops, 876 .ops = &fsi_dai_ops,
850 }, 877 },
851 { 878 {
@@ -857,7 +884,12 @@ struct snd_soc_dai fsi_soc_dai[] = {
857 .channels_min = 1, 884 .channels_min = 1,
858 .channels_max = 8, 885 .channels_max = 8,
859 }, 886 },
860 /* capture not supported */ 887 .capture = {
888 .rates = FSI_RATES,
889 .formats = FSI_FMTS,
890 .channels_min = 1,
891 .channels_max = 8,
892 },
861 .ops = &fsi_dai_ops, 893 .ops = &fsi_dai_ops,
862 }, 894 },
863}; 895};
@@ -880,14 +912,19 @@ EXPORT_SYMBOL_GPL(fsi_soc_platform);
880************************************************************************/ 912************************************************************************/
881static int fsi_probe(struct platform_device *pdev) 913static int fsi_probe(struct platform_device *pdev)
882{ 914{
915 struct fsi_master *master;
883 struct resource *res; 916 struct resource *res;
884 char clk_name[8];
885 unsigned int irq; 917 unsigned int irq;
886 int ret; 918 int ret;
887 919
920 if (0 != pdev->id) {
921 dev_err(&pdev->dev, "current fsi support id 0 only now\n");
922 return -ENODEV;
923 }
924
888 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 925 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
889 irq = platform_get_irq(pdev, 0); 926 irq = platform_get_irq(pdev, 0);
890 if (!res || !irq) { 927 if (!res || (int)irq <= 0) {
891 dev_err(&pdev->dev, "Not enough FSI platform resources.\n"); 928 dev_err(&pdev->dev, "Not enough FSI platform resources.\n");
892 ret = -ENODEV; 929 ret = -ENODEV;
893 goto exit; 930 goto exit;
@@ -910,35 +947,25 @@ static int fsi_probe(struct platform_device *pdev)
910 master->irq = irq; 947 master->irq = irq;
911 master->info = pdev->dev.platform_data; 948 master->info = pdev->dev.platform_data;
912 master->fsia.base = master->base; 949 master->fsia.base = master->base;
950 master->fsia.master = master;
913 master->fsib.base = master->base + 0x40; 951 master->fsib.base = master->base + 0x40;
952 master->fsib.master = master;
953 spin_lock_init(&master->lock);
914 954
915 master->fsia.dma_chan = -1; 955 pm_runtime_enable(&pdev->dev);
916 master->fsib.dma_chan = -1; 956 pm_runtime_resume(&pdev->dev);
917
918 ret = fsi_get_dma_chan();
919 if (ret < 0) {
920 dev_err(&pdev->dev, "cannot get dma api\n");
921 goto exit_iounmap;
922 }
923
924 /* FSI is based on SPU mstp */
925 snprintf(clk_name, sizeof(clk_name), "spu%d", pdev->id);
926 master->clk = clk_get(NULL, clk_name);
927 if (IS_ERR(master->clk)) {
928 dev_err(&pdev->dev, "cannot get %s mstp\n", clk_name);
929 ret = -EIO;
930 goto exit_free_dma;
931 }
932 957
933 fsi_soc_dai[0].dev = &pdev->dev; 958 fsi_soc_dai[0].dev = &pdev->dev;
959 fsi_soc_dai[0].private_data = &master->fsia;
934 fsi_soc_dai[1].dev = &pdev->dev; 960 fsi_soc_dai[1].dev = &pdev->dev;
961 fsi_soc_dai[1].private_data = &master->fsib;
935 962
936 fsi_soft_all_reset(); 963 fsi_soft_all_reset(master);
937 964
938 ret = request_irq(irq, &fsi_interrupt, IRQF_DISABLED, "fsi", master); 965 ret = request_irq(irq, &fsi_interrupt, IRQF_DISABLED, "fsi", master);
939 if (ret) { 966 if (ret) {
940 dev_err(&pdev->dev, "irq request err\n"); 967 dev_err(&pdev->dev, "irq request err\n");
941 goto exit_free_dma; 968 goto exit_iounmap;
942 } 969 }
943 970
944 ret = snd_soc_register_platform(&fsi_soc_platform); 971 ret = snd_soc_register_platform(&fsi_soc_platform);
@@ -951,10 +978,9 @@ static int fsi_probe(struct platform_device *pdev)
951 978
952exit_free_irq: 979exit_free_irq:
953 free_irq(irq, master); 980 free_irq(irq, master);
954exit_free_dma:
955 fsi_free_dma_chan();
956exit_iounmap: 981exit_iounmap:
957 iounmap(master->base); 982 iounmap(master->base);
983 pm_runtime_disable(&pdev->dev);
958exit_kfree: 984exit_kfree:
959 kfree(master); 985 kfree(master);
960 master = NULL; 986 master = NULL;
@@ -964,24 +990,49 @@ exit:
964 990
965static int fsi_remove(struct platform_device *pdev) 991static int fsi_remove(struct platform_device *pdev)
966{ 992{
993 struct fsi_master *master;
994
995 master = fsi_get_master(fsi_soc_dai[0].private_data);
996
967 snd_soc_unregister_dais(fsi_soc_dai, ARRAY_SIZE(fsi_soc_dai)); 997 snd_soc_unregister_dais(fsi_soc_dai, ARRAY_SIZE(fsi_soc_dai));
968 snd_soc_unregister_platform(&fsi_soc_platform); 998 snd_soc_unregister_platform(&fsi_soc_platform);
969 999
970 clk_put(master->clk); 1000 pm_runtime_disable(&pdev->dev);
971
972 fsi_free_dma_chan();
973 1001
974 free_irq(master->irq, master); 1002 free_irq(master->irq, master);
975 1003
976 iounmap(master->base); 1004 iounmap(master->base);
977 kfree(master); 1005 kfree(master);
978 master = NULL; 1006
1007 fsi_soc_dai[0].dev = NULL;
1008 fsi_soc_dai[0].private_data = NULL;
1009 fsi_soc_dai[1].dev = NULL;
1010 fsi_soc_dai[1].private_data = NULL;
1011
1012 return 0;
1013}
1014
1015static int fsi_runtime_nop(struct device *dev)
1016{
1017 /* Runtime PM callback shared between ->runtime_suspend()
1018 * and ->runtime_resume(). Simply returns success.
1019 *
1020 * This driver re-initializes all registers after
1021 * pm_runtime_get_sync() anyway so there is no need
1022 * to save and restore registers here.
1023 */
979 return 0; 1024 return 0;
980} 1025}
981 1026
1027static struct dev_pm_ops fsi_pm_ops = {
1028 .runtime_suspend = fsi_runtime_nop,
1029 .runtime_resume = fsi_runtime_nop,
1030};
1031
982static struct platform_driver fsi_driver = { 1032static struct platform_driver fsi_driver = {
983 .driver = { 1033 .driver = {
984 .name = "sh_fsi", 1034 .name = "sh_fsi",
1035 .pm = &fsi_pm_ops,
985 }, 1036 },
986 .probe = fsi_probe, 1037 .probe = fsi_probe,
987 .remove = fsi_remove, 1038 .remove = fsi_remove,
diff --git a/sound/soc/sh/migor.c b/sound/soc/sh/migor.c
new file mode 100644
index 000000000000..b823a5c9b9bc
--- /dev/null
+++ b/sound/soc/sh/migor.c
@@ -0,0 +1,218 @@
1/*
2 * ALSA SoC driver for Migo-R
3 *
4 * Copyright (C) 2009-2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/device.h>
12#include <linux/firmware.h>
13#include <linux/module.h>
14
15#include <asm/clock.h>
16
17#include <cpu/sh7722.h>
18
19#include <sound/core.h>
20#include <sound/pcm.h>
21#include <sound/soc.h>
22#include <sound/soc-dapm.h>
23
24#include "../codecs/wm8978.h"
25#include "siu.h"
26
27/* Default 8000Hz sampling frequency */
28static unsigned long codec_freq = 8000 * 512;
29
30static unsigned int use_count;
31
32/* External clock, sourced from the codec at the SIUMCKB pin */
33static unsigned long siumckb_recalc(struct clk *clk)
34{
35 return codec_freq;
36}
37
38static struct clk_ops siumckb_clk_ops = {
39 .recalc = siumckb_recalc,
40};
41
42static struct clk siumckb_clk = {
43 .name = "siumckb_clk",
44 .id = -1,
45 .ops = &siumckb_clk_ops,
46 .rate = 0, /* initialised at run-time */
47};
48
49static int migor_hw_params(struct snd_pcm_substream *substream,
50 struct snd_pcm_hw_params *params)
51{
52 struct snd_soc_pcm_runtime *rtd = substream->private_data;
53 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
54 int ret;
55 unsigned int rate = params_rate(params);
56
57 ret = snd_soc_dai_set_sysclk(codec_dai, WM8978_PLL, 13000000,
58 SND_SOC_CLOCK_IN);
59 if (ret < 0)
60 return ret;
61
62 ret = snd_soc_dai_set_clkdiv(codec_dai, WM8978_OPCLKRATE, rate * 512);
63 if (ret < 0)
64 return ret;
65
66 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_NB_IF |
67 SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS);
68 if (ret < 0)
69 return ret;
70
71 ret = snd_soc_dai_set_fmt(rtd->dai->cpu_dai, SND_SOC_DAIFMT_NB_IF |
72 SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS);
73 if (ret < 0)
74 return ret;
75
76 codec_freq = rate * 512;
77 /*
78 * This propagates the parent frequency change to children and
79 * recalculates the frequency table
80 */
81 clk_set_rate(&siumckb_clk, codec_freq);
82 dev_dbg(codec_dai->dev, "%s: configure %luHz\n", __func__, codec_freq);
83
84 ret = snd_soc_dai_set_sysclk(rtd->dai->cpu_dai, SIU_CLKB_EXT,
85 codec_freq / 2, SND_SOC_CLOCK_IN);
86
87 if (!ret)
88 use_count++;
89
90 return ret;
91}
92
93static int migor_hw_free(struct snd_pcm_substream *substream)
94{
95 struct snd_soc_pcm_runtime *rtd = substream->private_data;
96 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
97
98 if (use_count) {
99 use_count--;
100
101 if (!use_count)
102 snd_soc_dai_set_sysclk(codec_dai, WM8978_PLL, 0,
103 SND_SOC_CLOCK_IN);
104 } else {
105 dev_dbg(codec_dai->dev, "Unbalanced hw_free!\n");
106 }
107
108 return 0;
109}
110
111static struct snd_soc_ops migor_dai_ops = {
112 .hw_params = migor_hw_params,
113 .hw_free = migor_hw_free,
114};
115
116static const struct snd_soc_dapm_widget migor_dapm_widgets[] = {
117 SND_SOC_DAPM_HP("Headphone", NULL),
118 SND_SOC_DAPM_MIC("Onboard Microphone", NULL),
119 SND_SOC_DAPM_MIC("External Microphone", NULL),
120};
121
122static const struct snd_soc_dapm_route audio_map[] = {
123 /* Headphone output connected to LHP/RHP, enable OUT4 for VMID */
124 { "Headphone", NULL, "OUT4 VMID" },
125 { "OUT4 VMID", NULL, "LHP" },
126 { "OUT4 VMID", NULL, "RHP" },
127
128 /* On-board microphone */
129 { "RMICN", NULL, "Mic Bias" },
130 { "RMICP", NULL, "Mic Bias" },
131 { "Mic Bias", NULL, "Onboard Microphone" },
132
133 /* External microphone */
134 { "LMICN", NULL, "Mic Bias" },
135 { "LMICP", NULL, "Mic Bias" },
136 { "Mic Bias", NULL, "External Microphone" },
137};
138
139static int migor_dai_init(struct snd_soc_codec *codec)
140{
141 snd_soc_dapm_new_controls(codec, migor_dapm_widgets,
142 ARRAY_SIZE(migor_dapm_widgets));
143
144 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
145
146 return 0;
147}
148
149/* migor digital audio interface glue - connects codec <--> CPU */
150static struct snd_soc_dai_link migor_dai = {
151 .name = "wm8978",
152 .stream_name = "WM8978",
153 .cpu_dai = &siu_i2s_dai,
154 .codec_dai = &wm8978_dai,
155 .ops = &migor_dai_ops,
156 .init = migor_dai_init,
157};
158
159/* migor audio machine driver */
160static struct snd_soc_card snd_soc_migor = {
161 .name = "Migo-R",
162 .platform = &siu_platform,
163 .dai_link = &migor_dai,
164 .num_links = 1,
165};
166
167/* migor audio subsystem */
168static struct snd_soc_device migor_snd_devdata = {
169 .card = &snd_soc_migor,
170 .codec_dev = &soc_codec_dev_wm8978,
171};
172
173static struct platform_device *migor_snd_device;
174
175static int __init migor_init(void)
176{
177 int ret;
178
179 ret = clk_register(&siumckb_clk);
180 if (ret < 0)
181 return ret;
182
183 /* Port number used on this machine: port B */
184 migor_snd_device = platform_device_alloc("soc-audio", 1);
185 if (!migor_snd_device) {
186 ret = -ENOMEM;
187 goto epdevalloc;
188 }
189
190 platform_set_drvdata(migor_snd_device, &migor_snd_devdata);
191
192 migor_snd_devdata.dev = &migor_snd_device->dev;
193
194 ret = platform_device_add(migor_snd_device);
195 if (ret)
196 goto epdevadd;
197
198 return 0;
199
200epdevadd:
201 platform_device_put(migor_snd_device);
202epdevalloc:
203 clk_unregister(&siumckb_clk);
204 return ret;
205}
206
207static void __exit migor_exit(void)
208{
209 clk_unregister(&siumckb_clk);
210 platform_device_unregister(migor_snd_device);
211}
212
213module_init(migor_init);
214module_exit(migor_exit);
215
216MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
217MODULE_DESCRIPTION("ALSA SoC Migor");
218MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/sh/siu.h b/sound/soc/sh/siu.h
new file mode 100644
index 000000000000..c0bfab8fed3d
--- /dev/null
+++ b/sound/soc/sh/siu.h
@@ -0,0 +1,193 @@
1/*
2 * siu.h - ALSA SoC driver for Renesas SH7343, SH7722 SIU peripheral.
3 *
4 * Copyright (C) 2009-2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
5 * Copyright (C) 2006 Carlos Munoz <carlos@kenati.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#ifndef SIU_H
23#define SIU_H
24
25/* Common kernel and user-space firmware-building defines and types */
26
27#define YRAM0_SIZE (0x0040 / 4) /* 16 */
28#define YRAM1_SIZE (0x0080 / 4) /* 32 */
29#define YRAM2_SIZE (0x0040 / 4) /* 16 */
30#define YRAM3_SIZE (0x0080 / 4) /* 32 */
31#define YRAM4_SIZE (0x0080 / 4) /* 32 */
32#define YRAM_DEF_SIZE (YRAM0_SIZE + YRAM1_SIZE + YRAM2_SIZE + \
33 YRAM3_SIZE + YRAM4_SIZE)
34#define YRAM_FIR_SIZE (0x0400 / 4) /* 256 */
35#define YRAM_IIR_SIZE (0x0200 / 4) /* 128 */
36
37#define XRAM0_SIZE (0x0400 / 4) /* 256 */
38#define XRAM1_SIZE (0x0200 / 4) /* 128 */
39#define XRAM2_SIZE (0x0200 / 4) /* 128 */
40
41/* PRAM program array size */
42#define PRAM0_SIZE (0x0100 / 4) /* 64 */
43#define PRAM1_SIZE ((0x2000 - 0x0100) / 4) /* 1984 */
44
45#include <linux/types.h>
46
47struct siu_spb_param {
48 __u32 ab1a; /* input FIFO address */
49 __u32 ab0a; /* output FIFO address */
50 __u32 dir; /* 0=the ather except CPUOUTPUT, 1=CPUINPUT */
51 __u32 event; /* SPB program starting conditions */
52 __u32 stfifo; /* STFIFO register setting value */
53 __u32 trdat; /* TRDAT register setting value */
54};
55
56struct siu_firmware {
57 __u32 yram_fir_coeff[YRAM_FIR_SIZE];
58 __u32 pram0[PRAM0_SIZE];
59 __u32 pram1[PRAM1_SIZE];
60 __u32 yram0[YRAM0_SIZE];
61 __u32 yram1[YRAM1_SIZE];
62 __u32 yram2[YRAM2_SIZE];
63 __u32 yram3[YRAM3_SIZE];
64 __u32 yram4[YRAM4_SIZE];
65 __u32 spbpar_num;
66 struct siu_spb_param spbpar[32];
67};
68
69#ifdef __KERNEL__
70
71#include <linux/dmaengine.h>
72#include <linux/interrupt.h>
73#include <linux/io.h>
74
75#include <asm/dmaengine.h>
76
77#include <sound/core.h>
78#include <sound/pcm.h>
79#include <sound/soc-dai.h>
80
81#define SIU_PERIOD_BYTES_MAX 8192 /* DMA transfer/period size */
82#define SIU_PERIOD_BYTES_MIN 256 /* DMA transfer/period size */
83#define SIU_PERIODS_MAX 64 /* Max periods in buffer */
84#define SIU_PERIODS_MIN 4 /* Min periods in buffer */
85#define SIU_BUFFER_BYTES_MAX (SIU_PERIOD_BYTES_MAX * SIU_PERIODS_MAX)
86
87/* SIU ports: only one can be used at a time */
88enum {
89 SIU_PORT_A,
90 SIU_PORT_B,
91 SIU_PORT_NUM,
92};
93
94/* SIU clock configuration */
95enum {
96 SIU_CLKA_PLL,
97 SIU_CLKA_EXT,
98 SIU_CLKB_PLL,
99 SIU_CLKB_EXT
100};
101
102struct siu_info {
103 int port_id;
104 u32 __iomem *pram;
105 u32 __iomem *xram;
106 u32 __iomem *yram;
107 u32 __iomem *reg;
108 struct siu_firmware fw;
109};
110
111struct siu_stream {
112 struct tasklet_struct tasklet;
113 struct snd_pcm_substream *substream;
114 snd_pcm_format_t format;
115 size_t buf_bytes;
116 size_t period_bytes;
117 int cur_period; /* Period currently in dma */
118 u32 volume;
119 snd_pcm_sframes_t xfer_cnt; /* Number of frames */
120 u8 rw_flg; /* transfer status */
121 /* DMA status */
122 struct dma_chan *chan; /* DMA channel */
123 struct dma_async_tx_descriptor *tx_desc;
124 dma_cookie_t cookie;
125 struct sh_dmae_slave param;
126};
127
128struct siu_port {
129 unsigned long play_cap; /* Used to track full duplex */
130 struct snd_pcm *pcm;
131 struct siu_stream playback;
132 struct siu_stream capture;
133 u32 stfifo; /* STFIFO value from firmware */
134 u32 trdat; /* TRDAT value from firmware */
135};
136
137extern struct siu_port *siu_ports[SIU_PORT_NUM];
138
139static inline struct siu_port *siu_port_info(struct snd_pcm_substream *substream)
140{
141 struct platform_device *pdev =
142 to_platform_device(substream->pcm->card->dev);
143 return siu_ports[pdev->id];
144}
145
146/* Register access */
147static inline void siu_write32(u32 __iomem *addr, u32 val)
148{
149 __raw_writel(val, addr);
150}
151
152static inline u32 siu_read32(u32 __iomem *addr)
153{
154 return __raw_readl(addr);
155}
156
157/* SIU registers */
158#define SIU_IFCTL (0x000 / sizeof(u32))
159#define SIU_SRCTL (0x004 / sizeof(u32))
160#define SIU_SFORM (0x008 / sizeof(u32))
161#define SIU_CKCTL (0x00c / sizeof(u32))
162#define SIU_TRDAT (0x010 / sizeof(u32))
163#define SIU_STFIFO (0x014 / sizeof(u32))
164#define SIU_DPAK (0x01c / sizeof(u32))
165#define SIU_CKREV (0x020 / sizeof(u32))
166#define SIU_EVNTC (0x028 / sizeof(u32))
167#define SIU_SBCTL (0x040 / sizeof(u32))
168#define SIU_SBPSET (0x044 / sizeof(u32))
169#define SIU_SBFSTS (0x068 / sizeof(u32))
170#define SIU_SBDVCA (0x06c / sizeof(u32))
171#define SIU_SBDVCB (0x070 / sizeof(u32))
172#define SIU_SBACTIV (0x074 / sizeof(u32))
173#define SIU_DMAIA (0x090 / sizeof(u32))
174#define SIU_DMAIB (0x094 / sizeof(u32))
175#define SIU_DMAOA (0x098 / sizeof(u32))
176#define SIU_DMAOB (0x09c / sizeof(u32))
177#define SIU_DMAML (0x0a0 / sizeof(u32))
178#define SIU_SPSTS (0x0cc / sizeof(u32))
179#define SIU_SPCTL (0x0d0 / sizeof(u32))
180#define SIU_BRGASEL (0x100 / sizeof(u32))
181#define SIU_BRRA (0x104 / sizeof(u32))
182#define SIU_BRGBSEL (0x108 / sizeof(u32))
183#define SIU_BRRB (0x10c / sizeof(u32))
184
185extern struct snd_soc_platform siu_platform;
186extern struct snd_soc_dai siu_i2s_dai;
187
188int siu_init_port(int port, struct siu_port **port_info, struct snd_card *card);
189void siu_free_port(struct siu_port *port_info);
190
191#endif
192
193#endif /* SIU_H */
diff --git a/sound/soc/sh/siu_dai.c b/sound/soc/sh/siu_dai.c
new file mode 100644
index 000000000000..d86ee1bfc03a
--- /dev/null
+++ b/sound/soc/sh/siu_dai.c
@@ -0,0 +1,848 @@
1/*
2 * siu_dai.c - ALSA SoC driver for Renesas SH7343, SH7722 SIU peripheral.
3 *
4 * Copyright (C) 2009-2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
5 * Copyright (C) 2006 Carlos Munoz <carlos@kenati.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <linux/delay.h>
23#include <linux/firmware.h>
24#include <linux/pm_runtime.h>
25#include <linux/slab.h>
26
27#include <asm/clock.h>
28#include <asm/siu.h>
29
30#include <sound/control.h>
31#include <sound/soc-dai.h>
32
33#include "siu.h"
34
35/* Board specifics */
36#if defined(CONFIG_CPU_SUBTYPE_SH7722)
37# define SIU_MAX_VOLUME 0x1000
38#else
39# define SIU_MAX_VOLUME 0x7fff
40#endif
41
42#define PRAM_SIZE 0x2000
43#define XRAM_SIZE 0x800
44#define YRAM_SIZE 0x800
45
46#define XRAM_OFFSET 0x4000
47#define YRAM_OFFSET 0x6000
48#define REG_OFFSET 0xc000
49
50#define PLAYBACK_ENABLED 1
51#define CAPTURE_ENABLED 2
52
53#define VOLUME_CAPTURE 0
54#define VOLUME_PLAYBACK 1
55#define DFLT_VOLUME_LEVEL 0x08000800
56
57/*
58 * SPDIF is only available on port A and on some SIU implementations it is only
59 * available for input. Due to the lack of hardware to test it, SPDIF is left
60 * disabled in this driver version
61 */
62struct format_flag {
63 u32 i2s;
64 u32 pcm;
65 u32 spdif;
66 u32 mask;
67};
68
69struct port_flag {
70 struct format_flag playback;
71 struct format_flag capture;
72};
73
74static struct port_flag siu_flags[SIU_PORT_NUM] = {
75 [SIU_PORT_A] = {
76 .playback = {
77 .i2s = 0x50000000,
78 .pcm = 0x40000000,
79 .spdif = 0x80000000, /* not on all SIU versions */
80 .mask = 0xd0000000,
81 },
82 .capture = {
83 .i2s = 0x05000000,
84 .pcm = 0x04000000,
85 .spdif = 0x08000000,
86 .mask = 0x0d000000,
87 },
88 },
89 [SIU_PORT_B] = {
90 .playback = {
91 .i2s = 0x00500000,
92 .pcm = 0x00400000,
93 .spdif = 0, /* impossible - turn off */
94 .mask = 0x00500000,
95 },
96 .capture = {
97 .i2s = 0x00050000,
98 .pcm = 0x00040000,
99 .spdif = 0, /* impossible - turn off */
100 .mask = 0x00050000,
101 },
102 },
103};
104
105static void siu_dai_start(struct siu_port *port_info)
106{
107 struct siu_info *info = siu_i2s_dai.private_data;
108 u32 __iomem *base = info->reg;
109
110 dev_dbg(port_info->pcm->card->dev, "%s\n", __func__);
111
112 /* Turn on SIU clock */
113 pm_runtime_get_sync(siu_i2s_dai.dev);
114
115 /* Issue software reset to siu */
116 siu_write32(base + SIU_SRCTL, 0);
117
118 /* Wait for the reset to take effect */
119 udelay(1);
120
121 port_info->stfifo = 0;
122 port_info->trdat = 0;
123
124 /* portA, portB, SIU operate */
125 siu_write32(base + SIU_SRCTL, 0x301);
126
127 /* portA=256fs, portB=256fs */
128 siu_write32(base + SIU_CKCTL, 0x40400000);
129
130 /* portA's BRG does not divide SIUCKA */
131 siu_write32(base + SIU_BRGASEL, 0);
132 siu_write32(base + SIU_BRRA, 0);
133
134 /* portB's BRG divides SIUCKB by half */
135 siu_write32(base + SIU_BRGBSEL, 1);
136 siu_write32(base + SIU_BRRB, 0);
137
138 siu_write32(base + SIU_IFCTL, 0x44440000);
139
140 /* portA: 32 bit/fs, master; portB: 32 bit/fs, master */
141 siu_write32(base + SIU_SFORM, 0x0c0c0000);
142
143 /*
144 * Volume levels: looks like the DSP firmware implements volume controls
145 * differently from what's described in the datasheet
146 */
147 siu_write32(base + SIU_SBDVCA, port_info->playback.volume);
148 siu_write32(base + SIU_SBDVCB, port_info->capture.volume);
149}
150
151static void siu_dai_stop(void)
152{
153 struct siu_info *info = siu_i2s_dai.private_data;
154 u32 __iomem *base = info->reg;
155
156 /* SIU software reset */
157 siu_write32(base + SIU_SRCTL, 0);
158
159 /* Turn off SIU clock */
160 pm_runtime_put_sync(siu_i2s_dai.dev);
161}
162
163static void siu_dai_spbAselect(struct siu_port *port_info)
164{
165 struct siu_info *info = siu_i2s_dai.private_data;
166 struct siu_firmware *fw = &info->fw;
167 u32 *ydef = fw->yram0;
168 u32 idx;
169
170 /* path A use */
171 if (!info->port_id)
172 idx = 1; /* portA */
173 else
174 idx = 2; /* portB */
175
176 ydef[0] = (fw->spbpar[idx].ab1a << 16) |
177 (fw->spbpar[idx].ab0a << 8) |
178 (fw->spbpar[idx].dir << 7) | 3;
179 ydef[1] = fw->yram0[1]; /* 0x03000300 */
180 ydef[2] = (16 / 2) << 24;
181 ydef[3] = fw->yram0[3]; /* 0 */
182 ydef[4] = fw->yram0[4]; /* 0 */
183 ydef[7] = fw->spbpar[idx].event;
184 port_info->stfifo |= fw->spbpar[idx].stfifo;
185 port_info->trdat |= fw->spbpar[idx].trdat;
186}
187
188static void siu_dai_spbBselect(struct siu_port *port_info)
189{
190 struct siu_info *info = siu_i2s_dai.private_data;
191 struct siu_firmware *fw = &info->fw;
192 u32 *ydef = fw->yram0;
193 u32 idx;
194
195 /* path B use */
196 if (!info->port_id)
197 idx = 7; /* portA */
198 else
199 idx = 8; /* portB */
200
201 ydef[5] = (fw->spbpar[idx].ab1a << 16) |
202 (fw->spbpar[idx].ab0a << 8) | 1;
203 ydef[6] = fw->spbpar[idx].event;
204 port_info->stfifo |= fw->spbpar[idx].stfifo;
205 port_info->trdat |= fw->spbpar[idx].trdat;
206}
207
208static void siu_dai_open(struct siu_stream *siu_stream)
209{
210 struct siu_info *info = siu_i2s_dai.private_data;
211 u32 __iomem *base = info->reg;
212 u32 srctl, ifctl;
213
214 srctl = siu_read32(base + SIU_SRCTL);
215 ifctl = siu_read32(base + SIU_IFCTL);
216
217 switch (info->port_id) {
218 case SIU_PORT_A:
219 /* portA operates */
220 srctl |= 0x200;
221 ifctl &= ~0xc2;
222 break;
223 case SIU_PORT_B:
224 /* portB operates */
225 srctl |= 0x100;
226 ifctl &= ~0x31;
227 break;
228 }
229
230 siu_write32(base + SIU_SRCTL, srctl);
231 /* Unmute and configure portA */
232 siu_write32(base + SIU_IFCTL, ifctl);
233}
234
235/*
236 * At the moment only fixed Left-upper, Left-lower, Right-upper, Right-lower
237 * packing is supported
238 */
239static void siu_dai_pcmdatapack(struct siu_stream *siu_stream)
240{
241 struct siu_info *info = siu_i2s_dai.private_data;
242 u32 __iomem *base = info->reg;
243 u32 dpak;
244
245 dpak = siu_read32(base + SIU_DPAK);
246
247 switch (info->port_id) {
248 case SIU_PORT_A:
249 dpak &= ~0xc0000000;
250 break;
251 case SIU_PORT_B:
252 dpak &= ~0x00c00000;
253 break;
254 }
255
256 siu_write32(base + SIU_DPAK, dpak);
257}
258
259static int siu_dai_spbstart(struct siu_port *port_info)
260{
261 struct siu_info *info = siu_i2s_dai.private_data;
262 u32 __iomem *base = info->reg;
263 struct siu_firmware *fw = &info->fw;
264 u32 *ydef = fw->yram0;
265 int cnt;
266 u32 __iomem *add;
267 u32 *ptr;
268
269 /* Load SPB Program in PRAM */
270 ptr = fw->pram0;
271 add = info->pram;
272 for (cnt = 0; cnt < PRAM0_SIZE; cnt++, add++, ptr++)
273 siu_write32(add, *ptr);
274
275 ptr = fw->pram1;
276 add = info->pram + (0x0100 / sizeof(u32));
277 for (cnt = 0; cnt < PRAM1_SIZE; cnt++, add++, ptr++)
278 siu_write32(add, *ptr);
279
280 /* XRAM initialization */
281 add = info->xram;
282 for (cnt = 0; cnt < XRAM0_SIZE + XRAM1_SIZE + XRAM2_SIZE; cnt++, add++)
283 siu_write32(add, 0);
284
285 /* YRAM variable area initialization */
286 add = info->yram;
287 for (cnt = 0; cnt < YRAM_DEF_SIZE; cnt++, add++)
288 siu_write32(add, ydef[cnt]);
289
290 /* YRAM FIR coefficient area initialization */
291 add = info->yram + (0x0200 / sizeof(u32));
292 for (cnt = 0; cnt < YRAM_FIR_SIZE; cnt++, add++)
293 siu_write32(add, fw->yram_fir_coeff[cnt]);
294
295 /* YRAM IIR coefficient area initialization */
296 add = info->yram + (0x0600 / sizeof(u32));
297 for (cnt = 0; cnt < YRAM_IIR_SIZE; cnt++, add++)
298 siu_write32(add, 0);
299
300 siu_write32(base + SIU_TRDAT, port_info->trdat);
301 port_info->trdat = 0x0;
302
303
304 /* SPB start condition: software */
305 siu_write32(base + SIU_SBACTIV, 0);
306 /* Start SPB */
307 siu_write32(base + SIU_SBCTL, 0xc0000000);
308 /* Wait for program to halt */
309 cnt = 0x10000;
310 while (--cnt && siu_read32(base + SIU_SBCTL) != 0x80000000)
311 cpu_relax();
312
313 if (!cnt)
314 return -EBUSY;
315
316 /* SPB program start address setting */
317 siu_write32(base + SIU_SBPSET, 0x00400000);
318 /* SPB hardware start(FIFOCTL source) */
319 siu_write32(base + SIU_SBACTIV, 0xc0000000);
320
321 return 0;
322}
323
324static void siu_dai_spbstop(struct siu_port *port_info)
325{
326 struct siu_info *info = siu_i2s_dai.private_data;
327 u32 __iomem *base = info->reg;
328
329 siu_write32(base + SIU_SBACTIV, 0);
330 /* SPB stop */
331 siu_write32(base + SIU_SBCTL, 0);
332
333 port_info->stfifo = 0;
334}
335
336/* API functions */
337
338/* Playback and capture hardware properties are identical */
339static struct snd_pcm_hardware siu_dai_pcm_hw = {
340 .info = SNDRV_PCM_INFO_INTERLEAVED,
341 .formats = SNDRV_PCM_FMTBIT_S16,
342 .rates = SNDRV_PCM_RATE_8000_48000,
343 .rate_min = 8000,
344 .rate_max = 48000,
345 .channels_min = 2,
346 .channels_max = 2,
347 .buffer_bytes_max = SIU_BUFFER_BYTES_MAX,
348 .period_bytes_min = SIU_PERIOD_BYTES_MIN,
349 .period_bytes_max = SIU_PERIOD_BYTES_MAX,
350 .periods_min = SIU_PERIODS_MIN,
351 .periods_max = SIU_PERIODS_MAX,
352};
353
354static int siu_dai_info_volume(struct snd_kcontrol *kctrl,
355 struct snd_ctl_elem_info *uinfo)
356{
357 struct siu_port *port_info = snd_kcontrol_chip(kctrl);
358
359 dev_dbg(port_info->pcm->card->dev, "%s\n", __func__);
360
361 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
362 uinfo->count = 2;
363 uinfo->value.integer.min = 0;
364 uinfo->value.integer.max = SIU_MAX_VOLUME;
365
366 return 0;
367}
368
369static int siu_dai_get_volume(struct snd_kcontrol *kctrl,
370 struct snd_ctl_elem_value *ucontrol)
371{
372 struct siu_port *port_info = snd_kcontrol_chip(kctrl);
373 struct device *dev = port_info->pcm->card->dev;
374 u32 vol;
375
376 dev_dbg(dev, "%s\n", __func__);
377
378 switch (kctrl->private_value) {
379 case VOLUME_PLAYBACK:
380 /* Playback is always on port 0 */
381 vol = port_info->playback.volume;
382 ucontrol->value.integer.value[0] = vol & 0xffff;
383 ucontrol->value.integer.value[1] = vol >> 16 & 0xffff;
384 break;
385 case VOLUME_CAPTURE:
386 /* Capture is always on port 1 */
387 vol = port_info->capture.volume;
388 ucontrol->value.integer.value[0] = vol & 0xffff;
389 ucontrol->value.integer.value[1] = vol >> 16 & 0xffff;
390 break;
391 default:
392 dev_err(dev, "%s() invalid private_value=%ld\n",
393 __func__, kctrl->private_value);
394 return -EINVAL;
395 }
396
397 return 0;
398}
399
400static int siu_dai_put_volume(struct snd_kcontrol *kctrl,
401 struct snd_ctl_elem_value *ucontrol)
402{
403 struct siu_port *port_info = snd_kcontrol_chip(kctrl);
404 struct device *dev = port_info->pcm->card->dev;
405 struct siu_info *info = siu_i2s_dai.private_data;
406 u32 __iomem *base = info->reg;
407 u32 new_vol;
408 u32 cur_vol;
409
410 dev_dbg(dev, "%s\n", __func__);
411
412 if (ucontrol->value.integer.value[0] < 0 ||
413 ucontrol->value.integer.value[0] > SIU_MAX_VOLUME ||
414 ucontrol->value.integer.value[1] < 0 ||
415 ucontrol->value.integer.value[1] > SIU_MAX_VOLUME)
416 return -EINVAL;
417
418 new_vol = ucontrol->value.integer.value[0] |
419 ucontrol->value.integer.value[1] << 16;
420
421 /* See comment above - DSP firmware implementation */
422 switch (kctrl->private_value) {
423 case VOLUME_PLAYBACK:
424 /* Playback is always on port 0 */
425 cur_vol = port_info->playback.volume;
426 siu_write32(base + SIU_SBDVCA, new_vol);
427 port_info->playback.volume = new_vol;
428 break;
429 case VOLUME_CAPTURE:
430 /* Capture is always on port 1 */
431 cur_vol = port_info->capture.volume;
432 siu_write32(base + SIU_SBDVCB, new_vol);
433 port_info->capture.volume = new_vol;
434 break;
435 default:
436 dev_err(dev, "%s() invalid private_value=%ld\n",
437 __func__, kctrl->private_value);
438 return -EINVAL;
439 }
440
441 if (cur_vol != new_vol)
442 return 1;
443
444 return 0;
445}
446
447static struct snd_kcontrol_new playback_controls = {
448 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
449 .name = "PCM Playback Volume",
450 .index = 0,
451 .info = siu_dai_info_volume,
452 .get = siu_dai_get_volume,
453 .put = siu_dai_put_volume,
454 .private_value = VOLUME_PLAYBACK,
455};
456
457static struct snd_kcontrol_new capture_controls = {
458 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
459 .name = "PCM Capture Volume",
460 .index = 0,
461 .info = siu_dai_info_volume,
462 .get = siu_dai_get_volume,
463 .put = siu_dai_put_volume,
464 .private_value = VOLUME_CAPTURE,
465};
466
467int siu_init_port(int port, struct siu_port **port_info, struct snd_card *card)
468{
469 struct device *dev = card->dev;
470 struct snd_kcontrol *kctrl;
471 int ret;
472
473 *port_info = kzalloc(sizeof(**port_info), GFP_KERNEL);
474 if (!*port_info)
475 return -ENOMEM;
476
477 dev_dbg(dev, "%s: port #%d@%p\n", __func__, port, *port_info);
478
479 (*port_info)->playback.volume = DFLT_VOLUME_LEVEL;
480 (*port_info)->capture.volume = DFLT_VOLUME_LEVEL;
481
482 /*
483 * Add mixer support. The SPB is used to change the volume. Both
484 * ports use the same SPB. Therefore, we only register one
485 * control instance since it will be used by both channels.
486 * In error case we continue without controls.
487 */
488 kctrl = snd_ctl_new1(&playback_controls, *port_info);
489 ret = snd_ctl_add(card, kctrl);
490 if (ret < 0)
491 dev_err(dev,
492 "failed to add playback controls %p port=%d err=%d\n",
493 kctrl, port, ret);
494
495 kctrl = snd_ctl_new1(&capture_controls, *port_info);
496 ret = snd_ctl_add(card, kctrl);
497 if (ret < 0)
498 dev_err(dev,
499 "failed to add capture controls %p port=%d err=%d\n",
500 kctrl, port, ret);
501
502 return 0;
503}
504
505void siu_free_port(struct siu_port *port_info)
506{
507 kfree(port_info);
508}
509
510static int siu_dai_startup(struct snd_pcm_substream *substream,
511 struct snd_soc_dai *dai)
512{
513 struct siu_info *info = siu_i2s_dai.private_data;
514 struct snd_pcm_runtime *rt = substream->runtime;
515 struct siu_port *port_info = siu_port_info(substream);
516 int ret;
517
518 dev_dbg(substream->pcm->card->dev, "%s: port=%d@%p\n", __func__,
519 info->port_id, port_info);
520
521 snd_soc_set_runtime_hwparams(substream, &siu_dai_pcm_hw);
522
523 ret = snd_pcm_hw_constraint_integer(rt, SNDRV_PCM_HW_PARAM_PERIODS);
524 if (unlikely(ret < 0))
525 return ret;
526
527 siu_dai_start(port_info);
528
529 return 0;
530}
531
532static void siu_dai_shutdown(struct snd_pcm_substream *substream,
533 struct snd_soc_dai *dai)
534{
535 struct siu_info *info = siu_i2s_dai.private_data;
536 struct siu_port *port_info = siu_port_info(substream);
537
538 dev_dbg(substream->pcm->card->dev, "%s: port=%d@%p\n", __func__,
539 info->port_id, port_info);
540
541 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
542 port_info->play_cap &= ~PLAYBACK_ENABLED;
543 else
544 port_info->play_cap &= ~CAPTURE_ENABLED;
545
546 /* Stop the siu if the other stream is not using it */
547 if (!port_info->play_cap) {
548 /* during stmread or stmwrite ? */
549 BUG_ON(port_info->playback.rw_flg || port_info->capture.rw_flg);
550 siu_dai_spbstop(port_info);
551 siu_dai_stop();
552 }
553}
554
555/* PCM part of siu_dai_playback_prepare() / siu_dai_capture_prepare() */
556static int siu_dai_prepare(struct snd_pcm_substream *substream,
557 struct snd_soc_dai *dai)
558{
559 struct siu_info *info = siu_i2s_dai.private_data;
560 struct snd_pcm_runtime *rt = substream->runtime;
561 struct siu_port *port_info = siu_port_info(substream);
562 struct siu_stream *siu_stream;
563 int self, ret;
564
565 dev_dbg(substream->pcm->card->dev,
566 "%s: port %d, active streams %lx, %d channels\n",
567 __func__, info->port_id, port_info->play_cap, rt->channels);
568
569 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
570 self = PLAYBACK_ENABLED;
571 siu_stream = &port_info->playback;
572 } else {
573 self = CAPTURE_ENABLED;
574 siu_stream = &port_info->capture;
575 }
576
577 /* Set up the siu if not already done */
578 if (!port_info->play_cap) {
579 siu_stream->rw_flg = 0; /* stream-data transfer flag */
580
581 siu_dai_spbAselect(port_info);
582 siu_dai_spbBselect(port_info);
583
584 siu_dai_open(siu_stream);
585
586 siu_dai_pcmdatapack(siu_stream);
587
588 ret = siu_dai_spbstart(port_info);
589 if (ret < 0)
590 goto fail;
591 }
592
593 port_info->play_cap |= self;
594
595fail:
596 return ret;
597}
598
599/*
600 * SIU can set bus format to I2S / PCM / SPDIF independently for playback and
601 * capture, however, the current API sets the bus format globally for a DAI.
602 */
603static int siu_dai_set_fmt(struct snd_soc_dai *dai,
604 unsigned int fmt)
605{
606 struct siu_info *info = siu_i2s_dai.private_data;
607 u32 __iomem *base = info->reg;
608 u32 ifctl;
609
610 dev_dbg(dai->dev, "%s: fmt 0x%x on port %d\n",
611 __func__, fmt, info->port_id);
612
613 if (info->port_id < 0)
614 return -ENODEV;
615
616 /* Here select between I2S / PCM / SPDIF */
617 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
618 case SND_SOC_DAIFMT_I2S:
619 ifctl = siu_flags[info->port_id].playback.i2s |
620 siu_flags[info->port_id].capture.i2s;
621 break;
622 case SND_SOC_DAIFMT_LEFT_J:
623 ifctl = siu_flags[info->port_id].playback.pcm |
624 siu_flags[info->port_id].capture.pcm;
625 break;
626 /* SPDIF disabled - see comment at the top */
627 default:
628 return -EINVAL;
629 }
630
631 ifctl |= ~(siu_flags[info->port_id].playback.mask |
632 siu_flags[info->port_id].capture.mask) &
633 siu_read32(base + SIU_IFCTL);
634 siu_write32(base + SIU_IFCTL, ifctl);
635
636 return 0;
637}
638
639static int siu_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
640 unsigned int freq, int dir)
641{
642 struct clk *siu_clk, *parent_clk;
643 char *siu_name, *parent_name;
644 int ret;
645
646 if (dir != SND_SOC_CLOCK_IN)
647 return -EINVAL;
648
649 dev_dbg(dai->dev, "%s: using clock %d\n", __func__, clk_id);
650
651 switch (clk_id) {
652 case SIU_CLKA_PLL:
653 siu_name = "siua_clk";
654 parent_name = "pll_clk";
655 break;
656 case SIU_CLKA_EXT:
657 siu_name = "siua_clk";
658 parent_name = "siumcka_clk";
659 break;
660 case SIU_CLKB_PLL:
661 siu_name = "siub_clk";
662 parent_name = "pll_clk";
663 break;
664 case SIU_CLKB_EXT:
665 siu_name = "siub_clk";
666 parent_name = "siumckb_clk";
667 break;
668 default:
669 return -EINVAL;
670 }
671
672 siu_clk = clk_get(siu_i2s_dai.dev, siu_name);
673 if (IS_ERR(siu_clk))
674 return PTR_ERR(siu_clk);
675
676 parent_clk = clk_get(siu_i2s_dai.dev, parent_name);
677 if (!IS_ERR(parent_clk)) {
678 ret = clk_set_parent(siu_clk, parent_clk);
679 if (!ret)
680 clk_set_rate(siu_clk, freq);
681 clk_put(parent_clk);
682 }
683
684 clk_put(siu_clk);
685
686 return 0;
687}
688
689static struct snd_soc_dai_ops siu_dai_ops = {
690 .startup = siu_dai_startup,
691 .shutdown = siu_dai_shutdown,
692 .prepare = siu_dai_prepare,
693 .set_sysclk = siu_dai_set_sysclk,
694 .set_fmt = siu_dai_set_fmt,
695};
696
697struct snd_soc_dai siu_i2s_dai = {
698 .name = "sh-siu",
699 .id = 0,
700 .playback = {
701 .channels_min = 2,
702 .channels_max = 2,
703 .formats = SNDRV_PCM_FMTBIT_S16,
704 .rates = SNDRV_PCM_RATE_8000_48000,
705 },
706 .capture = {
707 .channels_min = 2,
708 .channels_max = 2,
709 .formats = SNDRV_PCM_FMTBIT_S16,
710 .rates = SNDRV_PCM_RATE_8000_48000,
711 },
712 .ops = &siu_dai_ops,
713};
714EXPORT_SYMBOL_GPL(siu_i2s_dai);
715
716static int __devinit siu_probe(struct platform_device *pdev)
717{
718 const struct firmware *fw_entry;
719 struct resource *res, *region;
720 struct siu_info *info;
721 int ret;
722
723 info = kmalloc(sizeof(*info), GFP_KERNEL);
724 if (!info)
725 return -ENOMEM;
726
727 ret = request_firmware(&fw_entry, "siu_spb.bin", &pdev->dev);
728 if (ret)
729 goto ereqfw;
730
731 /*
732 * Loaded firmware is "const" - read only, but we have to modify it in
733 * snd_siu_sh7343_spbAselect() and snd_siu_sh7343_spbBselect()
734 */
735 memcpy(&info->fw, fw_entry->data, fw_entry->size);
736
737 release_firmware(fw_entry);
738
739 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
740 if (!res) {
741 ret = -ENODEV;
742 goto egetres;
743 }
744
745 region = request_mem_region(res->start, resource_size(res),
746 pdev->name);
747 if (!region) {
748 dev_err(&pdev->dev, "SIU region already claimed\n");
749 ret = -EBUSY;
750 goto ereqmemreg;
751 }
752
753 ret = -ENOMEM;
754 info->pram = ioremap(res->start, PRAM_SIZE);
755 if (!info->pram)
756 goto emappram;
757 info->xram = ioremap(res->start + XRAM_OFFSET, XRAM_SIZE);
758 if (!info->xram)
759 goto emapxram;
760 info->yram = ioremap(res->start + YRAM_OFFSET, YRAM_SIZE);
761 if (!info->yram)
762 goto emapyram;
763 info->reg = ioremap(res->start + REG_OFFSET, resource_size(res) -
764 REG_OFFSET);
765 if (!info->reg)
766 goto emapreg;
767
768 siu_i2s_dai.dev = &pdev->dev;
769 siu_i2s_dai.private_data = info;
770
771 ret = snd_soc_register_dais(&siu_i2s_dai, 1);
772 if (ret < 0)
773 goto edaiinit;
774
775 ret = snd_soc_register_platform(&siu_platform);
776 if (ret < 0)
777 goto esocregp;
778
779 pm_runtime_enable(&pdev->dev);
780
781 return ret;
782
783esocregp:
784 snd_soc_unregister_dais(&siu_i2s_dai, 1);
785edaiinit:
786 iounmap(info->reg);
787emapreg:
788 iounmap(info->yram);
789emapyram:
790 iounmap(info->xram);
791emapxram:
792 iounmap(info->pram);
793emappram:
794 release_mem_region(res->start, resource_size(res));
795ereqmemreg:
796egetres:
797ereqfw:
798 kfree(info);
799
800 return ret;
801}
802
803static int __devexit siu_remove(struct platform_device *pdev)
804{
805 struct siu_info *info = siu_i2s_dai.private_data;
806 struct resource *res;
807
808 pm_runtime_disable(&pdev->dev);
809
810 snd_soc_unregister_platform(&siu_platform);
811 snd_soc_unregister_dais(&siu_i2s_dai, 1);
812
813 iounmap(info->reg);
814 iounmap(info->yram);
815 iounmap(info->xram);
816 iounmap(info->pram);
817 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
818 if (res)
819 release_mem_region(res->start, resource_size(res));
820 kfree(info);
821
822 return 0;
823}
824
825static struct platform_driver siu_driver = {
826 .driver = {
827 .name = "sh_siu",
828 },
829 .probe = siu_probe,
830 .remove = __devexit_p(siu_remove),
831};
832
833static int __init siu_init(void)
834{
835 return platform_driver_register(&siu_driver);
836}
837
838static void __exit siu_exit(void)
839{
840 platform_driver_unregister(&siu_driver);
841}
842
843module_init(siu_init)
844module_exit(siu_exit)
845
846MODULE_AUTHOR("Carlos Munoz <carlos@kenati.com>");
847MODULE_DESCRIPTION("ALSA SoC SH7722 SIU driver");
848MODULE_LICENSE("GPL");
diff --git a/sound/soc/sh/siu_pcm.c b/sound/soc/sh/siu_pcm.c
new file mode 100644
index 000000000000..8f85719212f9
--- /dev/null
+++ b/sound/soc/sh/siu_pcm.c
@@ -0,0 +1,615 @@
1/*
2 * siu_pcm.c - ALSA driver for Renesas SH7343, SH7722 SIU peripheral.
3 *
4 * Copyright (C) 2009-2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
5 * Copyright (C) 2006 Carlos Munoz <carlos@kenati.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21#include <linux/delay.h>
22#include <linux/dma-mapping.h>
23#include <linux/dmaengine.h>
24#include <linux/interrupt.h>
25#include <linux/module.h>
26#include <linux/platform_device.h>
27
28#include <sound/control.h>
29#include <sound/core.h>
30#include <sound/pcm.h>
31#include <sound/pcm_params.h>
32#include <sound/soc-dai.h>
33
34#include <asm/dmaengine.h>
35#include <asm/siu.h>
36
37#include "siu.h"
38
39#define GET_MAX_PERIODS(buf_bytes, period_bytes) \
40 ((buf_bytes) / (period_bytes))
41#define PERIOD_OFFSET(buf_addr, period_num, period_bytes) \
42 ((buf_addr) + ((period_num) * (period_bytes)))
43
44#define RWF_STM_RD 0x01 /* Read in progress */
45#define RWF_STM_WT 0x02 /* Write in progress */
46
47struct siu_port *siu_ports[SIU_PORT_NUM];
48
49/* transfersize is number of u32 dma transfers per period */
50static int siu_pcm_stmwrite_stop(struct siu_port *port_info)
51{
52 struct siu_info *info = siu_i2s_dai.private_data;
53 u32 __iomem *base = info->reg;
54 struct siu_stream *siu_stream = &port_info->playback;
55 u32 stfifo;
56
57 if (!siu_stream->rw_flg)
58 return -EPERM;
59
60 /* output FIFO disable */
61 stfifo = siu_read32(base + SIU_STFIFO);
62 siu_write32(base + SIU_STFIFO, stfifo & ~0x0c180c18);
63 pr_debug("%s: STFIFO %x -> %x\n", __func__,
64 stfifo, stfifo & ~0x0c180c18);
65
66 /* during stmwrite clear */
67 siu_stream->rw_flg = 0;
68
69 return 0;
70}
71
72static int siu_pcm_stmwrite_start(struct siu_port *port_info)
73{
74 struct siu_stream *siu_stream = &port_info->playback;
75
76 if (siu_stream->rw_flg)
77 return -EPERM;
78
79 /* Current period in buffer */
80 port_info->playback.cur_period = 0;
81
82 /* during stmwrite flag set */
83 siu_stream->rw_flg = RWF_STM_WT;
84
85 /* DMA transfer start */
86 tasklet_schedule(&siu_stream->tasklet);
87
88 return 0;
89}
90
91static void siu_dma_tx_complete(void *arg)
92{
93 struct siu_stream *siu_stream = arg;
94
95 if (!siu_stream->rw_flg)
96 return;
97
98 /* Update completed period count */
99 if (++siu_stream->cur_period >=
100 GET_MAX_PERIODS(siu_stream->buf_bytes,
101 siu_stream->period_bytes))
102 siu_stream->cur_period = 0;
103
104 pr_debug("%s: done period #%d (%u/%u bytes), cookie %d\n",
105 __func__, siu_stream->cur_period,
106 siu_stream->cur_period * siu_stream->period_bytes,
107 siu_stream->buf_bytes, siu_stream->cookie);
108
109 tasklet_schedule(&siu_stream->tasklet);
110
111 /* Notify alsa: a period is done */
112 snd_pcm_period_elapsed(siu_stream->substream);
113}
114
115static int siu_pcm_wr_set(struct siu_port *port_info,
116 dma_addr_t buff, u32 size)
117{
118 struct siu_info *info = siu_i2s_dai.private_data;
119 u32 __iomem *base = info->reg;
120 struct siu_stream *siu_stream = &port_info->playback;
121 struct snd_pcm_substream *substream = siu_stream->substream;
122 struct device *dev = substream->pcm->card->dev;
123 struct dma_async_tx_descriptor *desc;
124 dma_cookie_t cookie;
125 struct scatterlist sg;
126 u32 stfifo;
127
128 sg_init_table(&sg, 1);
129 sg_set_page(&sg, pfn_to_page(PFN_DOWN(buff)),
130 size, offset_in_page(buff));
131 sg_dma_address(&sg) = buff;
132
133 desc = siu_stream->chan->device->device_prep_slave_sg(siu_stream->chan,
134 &sg, 1, DMA_TO_DEVICE, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
135 if (!desc) {
136 dev_err(dev, "Failed to allocate a dma descriptor\n");
137 return -ENOMEM;
138 }
139
140 desc->callback = siu_dma_tx_complete;
141 desc->callback_param = siu_stream;
142 cookie = desc->tx_submit(desc);
143 if (cookie < 0) {
144 dev_err(dev, "Failed to submit a dma transfer\n");
145 return cookie;
146 }
147
148 siu_stream->tx_desc = desc;
149 siu_stream->cookie = cookie;
150
151 dma_async_issue_pending(siu_stream->chan);
152
153 /* only output FIFO enable */
154 stfifo = siu_read32(base + SIU_STFIFO);
155 siu_write32(base + SIU_STFIFO, stfifo | (port_info->stfifo & 0x0c180c18));
156 dev_dbg(dev, "%s: STFIFO %x -> %x\n", __func__,
157 stfifo, stfifo | (port_info->stfifo & 0x0c180c18));
158
159 return 0;
160}
161
162static int siu_pcm_rd_set(struct siu_port *port_info,
163 dma_addr_t buff, size_t size)
164{
165 struct siu_info *info = siu_i2s_dai.private_data;
166 u32 __iomem *base = info->reg;
167 struct siu_stream *siu_stream = &port_info->capture;
168 struct snd_pcm_substream *substream = siu_stream->substream;
169 struct device *dev = substream->pcm->card->dev;
170 struct dma_async_tx_descriptor *desc;
171 dma_cookie_t cookie;
172 struct scatterlist sg;
173 u32 stfifo;
174
175 dev_dbg(dev, "%s: %u@%llx\n", __func__, size, (unsigned long long)buff);
176
177 sg_init_table(&sg, 1);
178 sg_set_page(&sg, pfn_to_page(PFN_DOWN(buff)),
179 size, offset_in_page(buff));
180 sg_dma_address(&sg) = buff;
181
182 desc = siu_stream->chan->device->device_prep_slave_sg(siu_stream->chan,
183 &sg, 1, DMA_FROM_DEVICE, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
184 if (!desc) {
185 dev_err(dev, "Failed to allocate dma descriptor\n");
186 return -ENOMEM;
187 }
188
189 desc->callback = siu_dma_tx_complete;
190 desc->callback_param = siu_stream;
191 cookie = desc->tx_submit(desc);
192 if (cookie < 0) {
193 dev_err(dev, "Failed to submit dma descriptor\n");
194 return cookie;
195 }
196
197 siu_stream->tx_desc = desc;
198 siu_stream->cookie = cookie;
199
200 dma_async_issue_pending(siu_stream->chan);
201
202 /* only input FIFO enable */
203 stfifo = siu_read32(base + SIU_STFIFO);
204 siu_write32(base + SIU_STFIFO, siu_read32(base + SIU_STFIFO) |
205 (port_info->stfifo & 0x13071307));
206 dev_dbg(dev, "%s: STFIFO %x -> %x\n", __func__,
207 stfifo, stfifo | (port_info->stfifo & 0x13071307));
208
209 return 0;
210}
211
212static void siu_io_tasklet(unsigned long data)
213{
214 struct siu_stream *siu_stream = (struct siu_stream *)data;
215 struct snd_pcm_substream *substream = siu_stream->substream;
216 struct device *dev = substream->pcm->card->dev;
217 struct snd_pcm_runtime *rt = substream->runtime;
218 struct siu_port *port_info = siu_port_info(substream);
219
220 dev_dbg(dev, "%s: flags %x\n", __func__, siu_stream->rw_flg);
221
222 if (!siu_stream->rw_flg) {
223 dev_dbg(dev, "%s: stream inactive\n", __func__);
224 return;
225 }
226
227 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
228 dma_addr_t buff;
229 size_t count;
230 u8 *virt;
231
232 buff = (dma_addr_t)PERIOD_OFFSET(rt->dma_addr,
233 siu_stream->cur_period,
234 siu_stream->period_bytes);
235 virt = PERIOD_OFFSET(rt->dma_area,
236 siu_stream->cur_period,
237 siu_stream->period_bytes);
238 count = siu_stream->period_bytes;
239
240 /* DMA transfer start */
241 siu_pcm_rd_set(port_info, buff, count);
242 } else {
243 siu_pcm_wr_set(port_info,
244 (dma_addr_t)PERIOD_OFFSET(rt->dma_addr,
245 siu_stream->cur_period,
246 siu_stream->period_bytes),
247 siu_stream->period_bytes);
248 }
249}
250
251/* Capture */
252static int siu_pcm_stmread_start(struct siu_port *port_info)
253{
254 struct siu_stream *siu_stream = &port_info->capture;
255
256 if (siu_stream->xfer_cnt > 0x1000000)
257 return -EINVAL;
258 if (siu_stream->rw_flg)
259 return -EPERM;
260
261 /* Current period in buffer */
262 siu_stream->cur_period = 0;
263
264 /* during stmread flag set */
265 siu_stream->rw_flg = RWF_STM_RD;
266
267 tasklet_schedule(&siu_stream->tasklet);
268
269 return 0;
270}
271
272static int siu_pcm_stmread_stop(struct siu_port *port_info)
273{
274 struct siu_info *info = siu_i2s_dai.private_data;
275 u32 __iomem *base = info->reg;
276 struct siu_stream *siu_stream = &port_info->capture;
277 struct device *dev = siu_stream->substream->pcm->card->dev;
278 u32 stfifo;
279
280 if (!siu_stream->rw_flg)
281 return -EPERM;
282
283 /* input FIFO disable */
284 stfifo = siu_read32(base + SIU_STFIFO);
285 siu_write32(base + SIU_STFIFO, stfifo & ~0x13071307);
286 dev_dbg(dev, "%s: STFIFO %x -> %x\n", __func__,
287 stfifo, stfifo & ~0x13071307);
288
289 /* during stmread flag clear */
290 siu_stream->rw_flg = 0;
291
292 return 0;
293}
294
295static int siu_pcm_hw_params(struct snd_pcm_substream *ss,
296 struct snd_pcm_hw_params *hw_params)
297{
298 struct siu_info *info = siu_i2s_dai.private_data;
299 struct device *dev = ss->pcm->card->dev;
300 int ret;
301
302 dev_dbg(dev, "%s: port=%d\n", __func__, info->port_id);
303
304 ret = snd_pcm_lib_malloc_pages(ss, params_buffer_bytes(hw_params));
305 if (ret < 0)
306 dev_err(dev, "snd_pcm_lib_malloc_pages() failed\n");
307
308 return ret;
309}
310
311static int siu_pcm_hw_free(struct snd_pcm_substream *ss)
312{
313 struct siu_info *info = siu_i2s_dai.private_data;
314 struct siu_port *port_info = siu_port_info(ss);
315 struct device *dev = ss->pcm->card->dev;
316 struct siu_stream *siu_stream;
317
318 if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK)
319 siu_stream = &port_info->playback;
320 else
321 siu_stream = &port_info->capture;
322
323 dev_dbg(dev, "%s: port=%d\n", __func__, info->port_id);
324
325 return snd_pcm_lib_free_pages(ss);
326}
327
328static bool filter(struct dma_chan *chan, void *slave)
329{
330 struct sh_dmae_slave *param = slave;
331
332 pr_debug("%s: slave ID %d\n", __func__, param->slave_id);
333
334 if (unlikely(param->dma_dev != chan->device->dev))
335 return false;
336
337 chan->private = param;
338 return true;
339}
340
341static int siu_pcm_open(struct snd_pcm_substream *ss)
342{
343 /* Playback / Capture */
344 struct siu_info *info = siu_i2s_dai.private_data;
345 struct siu_port *port_info = siu_port_info(ss);
346 struct siu_stream *siu_stream;
347 u32 port = info->port_id;
348 struct siu_platform *pdata = siu_i2s_dai.dev->platform_data;
349 struct device *dev = ss->pcm->card->dev;
350 dma_cap_mask_t mask;
351 struct sh_dmae_slave *param;
352
353 dma_cap_zero(mask);
354 dma_cap_set(DMA_SLAVE, mask);
355
356 dev_dbg(dev, "%s, port=%d@%p\n", __func__, port, port_info);
357
358 if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK) {
359 siu_stream = &port_info->playback;
360 param = &siu_stream->param;
361 param->slave_id = port ? SHDMA_SLAVE_SIUB_TX :
362 SHDMA_SLAVE_SIUA_TX;
363 } else {
364 siu_stream = &port_info->capture;
365 param = &siu_stream->param;
366 param->slave_id = port ? SHDMA_SLAVE_SIUB_RX :
367 SHDMA_SLAVE_SIUA_RX;
368 }
369
370 param->dma_dev = pdata->dma_dev;
371 /* Get DMA channel */
372 siu_stream->chan = dma_request_channel(mask, filter, param);
373 if (!siu_stream->chan) {
374 dev_err(dev, "DMA channel allocation failed!\n");
375 return -EBUSY;
376 }
377
378 siu_stream->substream = ss;
379
380 return 0;
381}
382
383static int siu_pcm_close(struct snd_pcm_substream *ss)
384{
385 struct siu_info *info = siu_i2s_dai.private_data;
386 struct device *dev = ss->pcm->card->dev;
387 struct siu_port *port_info = siu_port_info(ss);
388 struct siu_stream *siu_stream;
389
390 dev_dbg(dev, "%s: port=%d\n", __func__, info->port_id);
391
392 if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK)
393 siu_stream = &port_info->playback;
394 else
395 siu_stream = &port_info->capture;
396
397 dma_release_channel(siu_stream->chan);
398 siu_stream->chan = NULL;
399
400 siu_stream->substream = NULL;
401
402 return 0;
403}
404
405static int siu_pcm_prepare(struct snd_pcm_substream *ss)
406{
407 struct siu_info *info = siu_i2s_dai.private_data;
408 struct siu_port *port_info = siu_port_info(ss);
409 struct device *dev = ss->pcm->card->dev;
410 struct snd_pcm_runtime *rt = ss->runtime;
411 struct siu_stream *siu_stream;
412 snd_pcm_sframes_t xfer_cnt;
413
414 if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK)
415 siu_stream = &port_info->playback;
416 else
417 siu_stream = &port_info->capture;
418
419 rt = siu_stream->substream->runtime;
420
421 siu_stream->buf_bytes = snd_pcm_lib_buffer_bytes(ss);
422 siu_stream->period_bytes = snd_pcm_lib_period_bytes(ss);
423
424 dev_dbg(dev, "%s: port=%d, %d channels, period=%u bytes\n", __func__,
425 info->port_id, rt->channels, siu_stream->period_bytes);
426
427 /* We only support buffers that are multiples of the period */
428 if (siu_stream->buf_bytes % siu_stream->period_bytes) {
429 dev_err(dev, "%s() - buffer=%d not multiple of period=%d\n",
430 __func__, siu_stream->buf_bytes,
431 siu_stream->period_bytes);
432 return -EINVAL;
433 }
434
435 xfer_cnt = bytes_to_frames(rt, siu_stream->period_bytes);
436 if (!xfer_cnt || xfer_cnt > 0x1000000)
437 return -EINVAL;
438
439 siu_stream->format = rt->format;
440 siu_stream->xfer_cnt = xfer_cnt;
441
442 dev_dbg(dev, "port=%d buf=%lx buf_bytes=%d period_bytes=%d "
443 "format=%d channels=%d xfer_cnt=%d\n", info->port_id,
444 (unsigned long)rt->dma_addr, siu_stream->buf_bytes,
445 siu_stream->period_bytes,
446 siu_stream->format, rt->channels, (int)xfer_cnt);
447
448 return 0;
449}
450
451static int siu_pcm_trigger(struct snd_pcm_substream *ss, int cmd)
452{
453 struct siu_info *info = siu_i2s_dai.private_data;
454 struct device *dev = ss->pcm->card->dev;
455 struct siu_port *port_info = siu_port_info(ss);
456 int ret;
457
458 dev_dbg(dev, "%s: port=%d@%p, cmd=%d\n", __func__,
459 info->port_id, port_info, cmd);
460
461 switch (cmd) {
462 case SNDRV_PCM_TRIGGER_START:
463 if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK)
464 ret = siu_pcm_stmwrite_start(port_info);
465 else
466 ret = siu_pcm_stmread_start(port_info);
467
468 if (ret < 0)
469 dev_warn(dev, "%s: start failed on port=%d\n",
470 __func__, info->port_id);
471
472 break;
473 case SNDRV_PCM_TRIGGER_STOP:
474 if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK)
475 siu_pcm_stmwrite_stop(port_info);
476 else
477 siu_pcm_stmread_stop(port_info);
478 ret = 0;
479
480 break;
481 default:
482 dev_err(dev, "%s() unsupported cmd=%d\n", __func__, cmd);
483 ret = -EINVAL;
484 }
485
486 return ret;
487}
488
489/*
490 * So far only resolution of one period is supported, subject to extending the
491 * dmangine API
492 */
493static snd_pcm_uframes_t siu_pcm_pointer_dma(struct snd_pcm_substream *ss)
494{
495 struct device *dev = ss->pcm->card->dev;
496 struct siu_info *info = siu_i2s_dai.private_data;
497 u32 __iomem *base = info->reg;
498 struct siu_port *port_info = siu_port_info(ss);
499 struct snd_pcm_runtime *rt = ss->runtime;
500 size_t ptr;
501 struct siu_stream *siu_stream;
502
503 if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK)
504 siu_stream = &port_info->playback;
505 else
506 siu_stream = &port_info->capture;
507
508 /*
509 * ptr is the offset into the buffer where the dma is currently at. We
510 * check if the dma buffer has just wrapped.
511 */
512 ptr = PERIOD_OFFSET(rt->dma_addr,
513 siu_stream->cur_period,
514 siu_stream->period_bytes) - rt->dma_addr;
515
516 dev_dbg(dev,
517 "%s: port=%d, events %x, FSTS %x, xferred %u/%u, cookie %d\n",
518 __func__, info->port_id, siu_read32(base + SIU_EVNTC),
519 siu_read32(base + SIU_SBFSTS), ptr, siu_stream->buf_bytes,
520 siu_stream->cookie);
521
522 if (ptr >= siu_stream->buf_bytes)
523 ptr = 0;
524
525 return bytes_to_frames(ss->runtime, ptr);
526}
527
528static int siu_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
529 struct snd_pcm *pcm)
530{
531 /* card->dev == socdev->dev, see snd_soc_new_pcms() */
532 struct siu_info *info = siu_i2s_dai.private_data;
533 struct platform_device *pdev = to_platform_device(card->dev);
534 int ret;
535 int i;
536
537 /* pdev->id selects between SIUA and SIUB */
538 if (pdev->id < 0 || pdev->id >= SIU_PORT_NUM)
539 return -EINVAL;
540
541 info->port_id = pdev->id;
542
543 /*
544 * While the siu has 2 ports, only one port can be on at a time (only 1
545 * SPB). So far all the boards using the siu had only one of the ports
546 * wired to a codec. To simplify things, we only register one port with
547 * alsa. In case both ports are needed, it should be changed here
548 */
549 for (i = pdev->id; i < pdev->id + 1; i++) {
550 struct siu_port **port_info = &siu_ports[i];
551
552 ret = siu_init_port(i, port_info, card);
553 if (ret < 0)
554 return ret;
555
556 ret = snd_pcm_lib_preallocate_pages_for_all(pcm,
557 SNDRV_DMA_TYPE_DEV, NULL,
558 SIU_BUFFER_BYTES_MAX, SIU_BUFFER_BYTES_MAX);
559 if (ret < 0) {
560 dev_err(card->dev,
561 "snd_pcm_lib_preallocate_pages_for_all() err=%d",
562 ret);
563 goto fail;
564 }
565
566 (*port_info)->pcm = pcm;
567
568 /* IO tasklets */
569 tasklet_init(&(*port_info)->playback.tasklet, siu_io_tasklet,
570 (unsigned long)&(*port_info)->playback);
571 tasklet_init(&(*port_info)->capture.tasklet, siu_io_tasklet,
572 (unsigned long)&(*port_info)->capture);
573 }
574
575 dev_info(card->dev, "SuperH SIU driver initialized.\n");
576 return 0;
577
578fail:
579 siu_free_port(siu_ports[pdev->id]);
580 dev_err(card->dev, "SIU: failed to initialize.\n");
581 return ret;
582}
583
584static void siu_pcm_free(struct snd_pcm *pcm)
585{
586 struct platform_device *pdev = to_platform_device(pcm->card->dev);
587 struct siu_port *port_info = siu_ports[pdev->id];
588
589 tasklet_kill(&port_info->capture.tasklet);
590 tasklet_kill(&port_info->playback.tasklet);
591
592 siu_free_port(port_info);
593 snd_pcm_lib_preallocate_free_for_all(pcm);
594
595 dev_dbg(pcm->card->dev, "%s\n", __func__);
596}
597
598static struct snd_pcm_ops siu_pcm_ops = {
599 .open = siu_pcm_open,
600 .close = siu_pcm_close,
601 .ioctl = snd_pcm_lib_ioctl,
602 .hw_params = siu_pcm_hw_params,
603 .hw_free = siu_pcm_hw_free,
604 .prepare = siu_pcm_prepare,
605 .trigger = siu_pcm_trigger,
606 .pointer = siu_pcm_pointer_dma,
607};
608
609struct snd_soc_platform siu_platform = {
610 .name = "siu-audio",
611 .pcm_ops = &siu_pcm_ops,
612 .pcm_new = siu_pcm_new,
613 .pcm_free = siu_pcm_free,
614};
615EXPORT_SYMBOL_GPL(siu_platform);
diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c
index c8ceddc2a26c..5869dc3be781 100644
--- a/sound/soc/soc-cache.c
+++ b/sound/soc/soc-cache.c
@@ -15,6 +15,74 @@
15#include <linux/spi/spi.h> 15#include <linux/spi/spi.h>
16#include <sound/soc.h> 16#include <sound/soc.h>
17 17
18static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec,
19 unsigned int reg)
20{
21 u16 *cache = codec->reg_cache;
22 if (reg >= codec->reg_cache_size)
23 return -1;
24 return cache[reg];
25}
26
27static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg,
28 unsigned int value)
29{
30 u16 *cache = codec->reg_cache;
31 u8 data[2];
32 int ret;
33
34 BUG_ON(codec->volatile_register);
35
36 data[0] = (reg << 4) | ((value >> 8) & 0x000f);
37 data[1] = value & 0x00ff;
38
39 if (reg < codec->reg_cache_size)
40 cache[reg] = value;
41
42 if (codec->cache_only) {
43 codec->cache_sync = 1;
44 return 0;
45 }
46
47 ret = codec->hw_write(codec->control_data, data, 2);
48 if (ret == 2)
49 return 0;
50 if (ret < 0)
51 return ret;
52 else
53 return -EIO;
54}
55
56#if defined(CONFIG_SPI_MASTER)
57static int snd_soc_4_12_spi_write(void *control_data, const char *data,
58 int len)
59{
60 struct spi_device *spi = control_data;
61 struct spi_transfer t;
62 struct spi_message m;
63 u8 msg[2];
64
65 if (len <= 0)
66 return 0;
67
68 msg[0] = data[1];
69 msg[1] = data[0];
70
71 spi_message_init(&m);
72 memset(&t, 0, (sizeof t));
73
74 t.tx_buf = &msg[0];
75 t.len = len;
76
77 spi_message_add_tail(&t, &m);
78 spi_sync(spi, &m);
79
80 return len;
81}
82#else
83#define snd_soc_4_12_spi_write NULL
84#endif
85
18static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec, 86static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec,
19 unsigned int reg) 87 unsigned int reg)
20{ 88{
@@ -38,6 +106,12 @@ static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg,
38 106
39 if (reg < codec->reg_cache_size) 107 if (reg < codec->reg_cache_size)
40 cache[reg] = value; 108 cache[reg] = value;
109
110 if (codec->cache_only) {
111 codec->cache_sync = 1;
112 return 0;
113 }
114
41 ret = codec->hw_write(codec->control_data, data, 2); 115 ret = codec->hw_write(codec->control_data, data, 2);
42 if (ret == 2) 116 if (ret == 2)
43 return 0; 117 return 0;
@@ -77,6 +151,40 @@ static int snd_soc_7_9_spi_write(void *control_data, const char *data,
77#define snd_soc_7_9_spi_write NULL 151#define snd_soc_7_9_spi_write NULL
78#endif 152#endif
79 153
154static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg,
155 unsigned int value)
156{
157 u8 *cache = codec->reg_cache;
158 u8 data[2];
159
160 BUG_ON(codec->volatile_register);
161
162 data[0] = reg & 0xff;
163 data[1] = value & 0xff;
164
165 if (reg < codec->reg_cache_size)
166 cache[reg] = value;
167
168 if (codec->cache_only) {
169 codec->cache_sync = 1;
170 return 0;
171 }
172
173 if (codec->hw_write(codec->control_data, data, 2) == 2)
174 return 0;
175 else
176 return -EIO;
177}
178
179static unsigned int snd_soc_8_8_read(struct snd_soc_codec *codec,
180 unsigned int reg)
181{
182 u8 *cache = codec->reg_cache;
183 if (reg >= codec->reg_cache_size)
184 return -1;
185 return cache[reg];
186}
187
80static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg, 188static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg,
81 unsigned int value) 189 unsigned int value)
82{ 190{
@@ -90,6 +198,11 @@ static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg,
90 if (!snd_soc_codec_volatile_register(codec, reg)) 198 if (!snd_soc_codec_volatile_register(codec, reg))
91 reg_cache[reg] = value; 199 reg_cache[reg] = value;
92 200
201 if (codec->cache_only) {
202 codec->cache_sync = 1;
203 return 0;
204 }
205
93 if (codec->hw_write(codec->control_data, data, 3) == 3) 206 if (codec->hw_write(codec->control_data, data, 3) == 3)
94 return 0; 207 return 0;
95 else 208 else
@@ -102,10 +215,14 @@ static unsigned int snd_soc_8_16_read(struct snd_soc_codec *codec,
102 u16 *cache = codec->reg_cache; 215 u16 *cache = codec->reg_cache;
103 216
104 if (reg >= codec->reg_cache_size || 217 if (reg >= codec->reg_cache_size ||
105 snd_soc_codec_volatile_register(codec, reg)) 218 snd_soc_codec_volatile_register(codec, reg)) {
219 if (codec->cache_only)
220 return -EINVAL;
221
106 return codec->hw_read(codec, reg); 222 return codec->hw_read(codec, reg);
107 else 223 } else {
108 return cache[reg]; 224 return cache[reg];
225 }
109} 226}
110 227
111#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) 228#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
@@ -142,6 +259,114 @@ static unsigned int snd_soc_8_16_read_i2c(struct snd_soc_codec *codec,
142#define snd_soc_8_16_read_i2c NULL 259#define snd_soc_8_16_read_i2c NULL
143#endif 260#endif
144 261
262#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
263static unsigned int snd_soc_16_8_read_i2c(struct snd_soc_codec *codec,
264 unsigned int r)
265{
266 struct i2c_msg xfer[2];
267 u16 reg = r;
268 u8 data;
269 int ret;
270 struct i2c_client *client = codec->control_data;
271
272 /* Write register */
273 xfer[0].addr = client->addr;
274 xfer[0].flags = 0;
275 xfer[0].len = 2;
276 xfer[0].buf = (u8 *)&reg;
277
278 /* Read data */
279 xfer[1].addr = client->addr;
280 xfer[1].flags = I2C_M_RD;
281 xfer[1].len = 1;
282 xfer[1].buf = &data;
283
284 ret = i2c_transfer(client->adapter, xfer, 2);
285 if (ret != 2) {
286 dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
287 return 0;
288 }
289
290 return data;
291}
292#else
293#define snd_soc_16_8_read_i2c NULL
294#endif
295
296static unsigned int snd_soc_16_8_read(struct snd_soc_codec *codec,
297 unsigned int reg)
298{
299 u16 *cache = codec->reg_cache;
300
301 reg &= 0xff;
302 if (reg >= codec->reg_cache_size)
303 return -1;
304 return cache[reg];
305}
306
307static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg,
308 unsigned int value)
309{
310 u16 *cache = codec->reg_cache;
311 u8 data[3];
312 int ret;
313
314 BUG_ON(codec->volatile_register);
315
316 data[0] = (reg >> 8) & 0xff;
317 data[1] = reg & 0xff;
318 data[2] = value;
319
320 reg &= 0xff;
321 if (reg < codec->reg_cache_size)
322 cache[reg] = value;
323
324 if (codec->cache_only) {
325 codec->cache_sync = 1;
326 return 0;
327 }
328
329 ret = codec->hw_write(codec->control_data, data, 3);
330 if (ret == 3)
331 return 0;
332 if (ret < 0)
333 return ret;
334 else
335 return -EIO;
336}
337
338#if defined(CONFIG_SPI_MASTER)
339static int snd_soc_16_8_spi_write(void *control_data, const char *data,
340 int len)
341{
342 struct spi_device *spi = control_data;
343 struct spi_transfer t;
344 struct spi_message m;
345 u8 msg[3];
346
347 if (len <= 0)
348 return 0;
349
350 msg[0] = data[0];
351 msg[1] = data[1];
352 msg[2] = data[2];
353
354 spi_message_init(&m);
355 memset(&t, 0, (sizeof t));
356
357 t.tx_buf = &msg[0];
358 t.len = len;
359
360 spi_message_add_tail(&t, &m);
361 spi_sync(spi, &m);
362
363 return len;
364}
365#else
366#define snd_soc_16_8_spi_write NULL
367#endif
368
369
145static struct { 370static struct {
146 int addr_bits; 371 int addr_bits;
147 int data_bits; 372 int data_bits;
@@ -150,9 +375,31 @@ static struct {
150 unsigned int (*read)(struct snd_soc_codec *, unsigned int); 375 unsigned int (*read)(struct snd_soc_codec *, unsigned int);
151 unsigned int (*i2c_read)(struct snd_soc_codec *, unsigned int); 376 unsigned int (*i2c_read)(struct snd_soc_codec *, unsigned int);
152} io_types[] = { 377} io_types[] = {
153 { 7, 9, snd_soc_7_9_write, snd_soc_7_9_spi_write, snd_soc_7_9_read }, 378 {
154 { 8, 16, snd_soc_8_16_write, NULL, snd_soc_8_16_read, 379 .addr_bits = 4, .data_bits = 12,
155 snd_soc_8_16_read_i2c }, 380 .write = snd_soc_4_12_write, .read = snd_soc_4_12_read,
381 .spi_write = snd_soc_4_12_spi_write,
382 },
383 {
384 .addr_bits = 7, .data_bits = 9,
385 .write = snd_soc_7_9_write, .read = snd_soc_7_9_read,
386 .spi_write = snd_soc_7_9_spi_write,
387 },
388 {
389 .addr_bits = 8, .data_bits = 8,
390 .write = snd_soc_8_8_write, .read = snd_soc_8_8_read,
391 },
392 {
393 .addr_bits = 8, .data_bits = 16,
394 .write = snd_soc_8_16_write, .read = snd_soc_8_16_read,
395 .i2c_read = snd_soc_8_16_read_i2c,
396 },
397 {
398 .addr_bits = 16, .data_bits = 8,
399 .write = snd_soc_16_8_write, .read = snd_soc_16_8_read,
400 .i2c_read = snd_soc_16_8_read_i2c,
401 .spi_write = snd_soc_16_8_spi_write,
402 },
156}; 403};
157 404
158/** 405/**
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 0a1b2f64bbee..ad7f9528d751 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>
@@ -37,7 +38,6 @@
37#include <sound/initval.h> 38#include <sound/initval.h>
38 39
39static DEFINE_MUTEX(pcm_mutex); 40static DEFINE_MUTEX(pcm_mutex);
40static DEFINE_MUTEX(io_mutex);
41static DECLARE_WAIT_QUEUE_HEAD(soc_pm_waitq); 41static DECLARE_WAIT_QUEUE_HEAD(soc_pm_waitq);
42 42
43#ifdef CONFIG_DEBUG_FS 43#ifdef CONFIG_DEBUG_FS
@@ -81,6 +81,196 @@ static int run_delayed_work(struct delayed_work *dwork)
81 return ret; 81 return ret;
82} 82}
83 83
84/* codec register dump */
85static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf)
86{
87 int i, step = 1, count = 0;
88
89 if (!codec->reg_cache_size)
90 return 0;
91
92 if (codec->reg_cache_step)
93 step = codec->reg_cache_step;
94
95 count += sprintf(buf, "%s registers\n", codec->name);
96 for (i = 0; i < codec->reg_cache_size; i += step) {
97 if (codec->readable_register && !codec->readable_register(i))
98 continue;
99
100 count += sprintf(buf + count, "%2x: ", i);
101 if (count >= PAGE_SIZE - 1)
102 break;
103
104 if (codec->display_register)
105 count += codec->display_register(codec, buf + count,
106 PAGE_SIZE - count, i);
107 else
108 count += snprintf(buf + count, PAGE_SIZE - count,
109 "%4x", codec->read(codec, i));
110
111 if (count >= PAGE_SIZE - 1)
112 break;
113
114 count += snprintf(buf + count, PAGE_SIZE - count, "\n");
115 if (count >= PAGE_SIZE - 1)
116 break;
117 }
118
119 /* Truncate count; min() would cause a warning */
120 if (count >= PAGE_SIZE)
121 count = PAGE_SIZE - 1;
122
123 return count;
124}
125static ssize_t codec_reg_show(struct device *dev,
126 struct device_attribute *attr, char *buf)
127{
128 struct snd_soc_device *devdata = dev_get_drvdata(dev);
129 return soc_codec_reg_show(devdata->card->codec, buf);
130}
131
132static DEVICE_ATTR(codec_reg, 0444, codec_reg_show, NULL);
133
134static ssize_t pmdown_time_show(struct device *dev,
135 struct device_attribute *attr, char *buf)
136{
137 struct snd_soc_device *socdev = dev_get_drvdata(dev);
138 struct snd_soc_card *card = socdev->card;
139
140 return sprintf(buf, "%ld\n", card->pmdown_time);
141}
142
143static ssize_t pmdown_time_set(struct device *dev,
144 struct device_attribute *attr,
145 const char *buf, size_t count)
146{
147 struct snd_soc_device *socdev = dev_get_drvdata(dev);
148 struct snd_soc_card *card = socdev->card;
149
150 strict_strtol(buf, 10, &card->pmdown_time);
151
152 return count;
153}
154
155static DEVICE_ATTR(pmdown_time, 0644, pmdown_time_show, pmdown_time_set);
156
157#ifdef CONFIG_DEBUG_FS
158static int codec_reg_open_file(struct inode *inode, struct file *file)
159{
160 file->private_data = inode->i_private;
161 return 0;
162}
163
164static ssize_t codec_reg_read_file(struct file *file, char __user *user_buf,
165 size_t count, loff_t *ppos)
166{
167 ssize_t ret;
168 struct snd_soc_codec *codec = file->private_data;
169 char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
170 if (!buf)
171 return -ENOMEM;
172 ret = soc_codec_reg_show(codec, buf);
173 if (ret >= 0)
174 ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
175 kfree(buf);
176 return ret;
177}
178
179static ssize_t codec_reg_write_file(struct file *file,
180 const char __user *user_buf, size_t count, loff_t *ppos)
181{
182 char buf[32];
183 int buf_size;
184 char *start = buf;
185 unsigned long reg, value;
186 int step = 1;
187 struct snd_soc_codec *codec = file->private_data;
188
189 buf_size = min(count, (sizeof(buf)-1));
190 if (copy_from_user(buf, user_buf, buf_size))
191 return -EFAULT;
192 buf[buf_size] = 0;
193
194 if (codec->reg_cache_step)
195 step = codec->reg_cache_step;
196
197 while (*start == ' ')
198 start++;
199 reg = simple_strtoul(start, &start, 16);
200 if ((reg >= codec->reg_cache_size) || (reg % step))
201 return -EINVAL;
202 while (*start == ' ')
203 start++;
204 if (strict_strtoul(start, 16, &value))
205 return -EINVAL;
206 codec->write(codec, reg, value);
207 return buf_size;
208}
209
210static const struct file_operations codec_reg_fops = {
211 .open = codec_reg_open_file,
212 .read = codec_reg_read_file,
213 .write = codec_reg_write_file,
214};
215
216static void soc_init_codec_debugfs(struct snd_soc_codec *codec)
217{
218 char codec_root[128];
219
220 if (codec->dev)
221 snprintf(codec_root, sizeof(codec_root),
222 "%s.%s", codec->name, dev_name(codec->dev));
223 else
224 snprintf(codec_root, sizeof(codec_root),
225 "%s", codec->name);
226
227 codec->debugfs_codec_root = debugfs_create_dir(codec_root,
228 debugfs_root);
229 if (!codec->debugfs_codec_root) {
230 printk(KERN_WARNING
231 "ASoC: Failed to create codec debugfs directory\n");
232 return;
233 }
234
235 codec->debugfs_reg = debugfs_create_file("codec_reg", 0644,
236 codec->debugfs_codec_root,
237 codec, &codec_reg_fops);
238 if (!codec->debugfs_reg)
239 printk(KERN_WARNING
240 "ASoC: Failed to create codec register debugfs file\n");
241
242 codec->debugfs_pop_time = debugfs_create_u32("dapm_pop_time", 0744,
243 codec->debugfs_codec_root,
244 &codec->pop_time);
245 if (!codec->debugfs_pop_time)
246 printk(KERN_WARNING
247 "Failed to create pop time debugfs file\n");
248
249 codec->debugfs_dapm = debugfs_create_dir("dapm",
250 codec->debugfs_codec_root);
251 if (!codec->debugfs_dapm)
252 printk(KERN_WARNING
253 "Failed to create DAPM debugfs directory\n");
254
255 snd_soc_dapm_debugfs_init(codec);
256}
257
258static void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec)
259{
260 debugfs_remove_recursive(codec->debugfs_codec_root);
261}
262
263#else
264
265static inline void soc_init_codec_debugfs(struct snd_soc_codec *codec)
266{
267}
268
269static inline void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec)
270{
271}
272#endif
273
84#ifdef CONFIG_SND_SOC_AC97_BUS 274#ifdef CONFIG_SND_SOC_AC97_BUS
85/* unregister ac97 codec */ 275/* unregister ac97 codec */
86static int soc_ac97_dev_unregister(struct snd_soc_codec *codec) 276static int soc_ac97_dev_unregister(struct snd_soc_codec *codec)
@@ -238,24 +428,24 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
238 if (!runtime->hw.rates) { 428 if (!runtime->hw.rates) {
239 printk(KERN_ERR "asoc: %s <-> %s No matching rates\n", 429 printk(KERN_ERR "asoc: %s <-> %s No matching rates\n",
240 codec_dai->name, cpu_dai->name); 430 codec_dai->name, cpu_dai->name);
241 goto machine_err; 431 goto config_err;
242 } 432 }
243 if (!runtime->hw.formats) { 433 if (!runtime->hw.formats) {
244 printk(KERN_ERR "asoc: %s <-> %s No matching formats\n", 434 printk(KERN_ERR "asoc: %s <-> %s No matching formats\n",
245 codec_dai->name, cpu_dai->name); 435 codec_dai->name, cpu_dai->name);
246 goto machine_err; 436 goto config_err;
247 } 437 }
248 if (!runtime->hw.channels_min || !runtime->hw.channels_max) { 438 if (!runtime->hw.channels_min || !runtime->hw.channels_max) {
249 printk(KERN_ERR "asoc: %s <-> %s No matching channels\n", 439 printk(KERN_ERR "asoc: %s <-> %s No matching channels\n",
250 codec_dai->name, cpu_dai->name); 440 codec_dai->name, cpu_dai->name);
251 goto machine_err; 441 goto config_err;
252 } 442 }
253 443
254 /* Symmetry only applies if we've already got an active stream. */ 444 /* Symmetry only applies if we've already got an active stream. */
255 if (cpu_dai->active || codec_dai->active) { 445 if (cpu_dai->active || codec_dai->active) {
256 ret = soc_pcm_apply_symmetry(substream); 446 ret = soc_pcm_apply_symmetry(substream);
257 if (ret != 0) 447 if (ret != 0)
258 goto machine_err; 448 goto config_err;
259 } 449 }
260 450
261 pr_debug("asoc: %s <-> %s info:\n", codec_dai->name, cpu_dai->name); 451 pr_debug("asoc: %s <-> %s info:\n", codec_dai->name, cpu_dai->name);
@@ -275,10 +465,14 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
275 mutex_unlock(&pcm_mutex); 465 mutex_unlock(&pcm_mutex);
276 return 0; 466 return 0;
277 467
278machine_err: 468config_err:
279 if (machine->ops && machine->ops->shutdown) 469 if (machine->ops && machine->ops->shutdown)
280 machine->ops->shutdown(substream); 470 machine->ops->shutdown(substream);
281 471
472machine_err:
473 if (codec_dai->ops->shutdown)
474 codec_dai->ops->shutdown(substream, codec_dai);
475
282codec_dai_err: 476codec_dai_err:
283 if (platform->pcm_ops->close) 477 if (platform->pcm_ops->close)
284 platform->pcm_ops->close(substream); 478 platform->pcm_ops->close(substream);
@@ -376,7 +570,7 @@ static int soc_codec_close(struct snd_pcm_substream *substream)
376 /* start delayed pop wq here for playback streams */ 570 /* start delayed pop wq here for playback streams */
377 codec_dai->pop_wait = 1; 571 codec_dai->pop_wait = 1;
378 schedule_delayed_work(&card->delayed_work, 572 schedule_delayed_work(&card->delayed_work,
379 msecs_to_jiffies(pmdown_time)); 573 msecs_to_jiffies(card->pmdown_time));
380 } else { 574 } else {
381 /* capture streams can be powered down now */ 575 /* capture streams can be powered down now */
382 snd_soc_dapm_stream_event(codec, 576 snd_soc_dapm_stream_event(codec,
@@ -774,6 +968,12 @@ static int soc_resume(struct device *dev)
774 struct snd_soc_card *card = socdev->card; 968 struct snd_soc_card *card = socdev->card;
775 struct snd_soc_dai *cpu_dai = card->dai_link[0].cpu_dai; 969 struct snd_soc_dai *cpu_dai = card->dai_link[0].cpu_dai;
776 970
971 /* If the initialization of this soc device failed, there is no codec
972 * associated with it. Just bail out in this case.
973 */
974 if (!card->codec)
975 return 0;
976
777 /* AC97 devices might have other drivers hanging off them so 977 /* AC97 devices might have other drivers hanging off them so
778 * need to resume immediately. Other drivers don't have that 978 * need to resume immediately. Other drivers don't have that
779 * problem and may take a substantial amount of time to resume 979 * problem and may take a substantial amount of time to resume
@@ -790,45 +990,6 @@ static int soc_resume(struct device *dev)
790 990
791 return 0; 991 return 0;
792} 992}
793
794/**
795 * snd_soc_suspend_device: Notify core of device suspend
796 *
797 * @dev: Device being suspended.
798 *
799 * In order to ensure that the entire audio subsystem is suspended in a
800 * coordinated fashion ASoC devices should suspend themselves when
801 * called by ASoC. When the standard kernel suspend process asks the
802 * device to suspend it should call this function to initiate a suspend
803 * of the entire ASoC card.
804 *
805 * \note Currently this function is stubbed out.
806 */
807int snd_soc_suspend_device(struct device *dev)
808{
809 return 0;
810}
811EXPORT_SYMBOL_GPL(snd_soc_suspend_device);
812
813/**
814 * snd_soc_resume_device: Notify core of device resume
815 *
816 * @dev: Device being resumed.
817 *
818 * In order to ensure that the entire audio subsystem is resumed in a
819 * coordinated fashion ASoC devices should resume themselves when called
820 * by ASoC. When the standard kernel resume process asks the device
821 * to resume it should call this function. Once all the components of
822 * the card have notified that they are ready to be resumed the card
823 * will be resumed.
824 *
825 * \note Currently this function is stubbed out.
826 */
827int snd_soc_resume_device(struct device *dev)
828{
829 return 0;
830}
831EXPORT_SYMBOL_GPL(snd_soc_resume_device);
832#else 993#else
833#define soc_suspend NULL 994#define soc_suspend NULL
834#define soc_resume NULL 995#define soc_resume NULL
@@ -843,6 +1004,7 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
843 struct platform_device, 1004 struct platform_device,
844 dev); 1005 dev);
845 struct snd_soc_codec_device *codec_dev = card->socdev->codec_dev; 1006 struct snd_soc_codec_device *codec_dev = card->socdev->codec_dev;
1007 struct snd_soc_codec *codec;
846 struct snd_soc_platform *platform; 1008 struct snd_soc_platform *platform;
847 struct snd_soc_dai *dai; 1009 struct snd_soc_dai *dai;
848 int i, found, ret, ac97; 1010 int i, found, ret, ac97;
@@ -911,6 +1073,8 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
911 dev_dbg(card->dev, "All components present, instantiating\n"); 1073 dev_dbg(card->dev, "All components present, instantiating\n");
912 1074
913 /* Found everything, bring it up */ 1075 /* Found everything, bring it up */
1076 card->pmdown_time = pmdown_time;
1077
914 if (card->probe) { 1078 if (card->probe) {
915 ret = card->probe(pdev); 1079 ret = card->probe(pdev);
916 if (ret < 0) 1080 if (ret < 0)
@@ -931,6 +1095,7 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
931 if (ret < 0) 1095 if (ret < 0)
932 goto cpu_dai_err; 1096 goto cpu_dai_err;
933 } 1097 }
1098 codec = card->codec;
934 1099
935 if (platform->probe) { 1100 if (platform->probe) {
936 ret = platform->probe(pdev); 1101 ret = platform->probe(pdev);
@@ -945,10 +1110,73 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
945 INIT_WORK(&card->deferred_resume_work, soc_resume_deferred); 1110 INIT_WORK(&card->deferred_resume_work, soc_resume_deferred);
946#endif 1111#endif
947 1112
1113 for (i = 0; i < card->num_links; i++) {
1114 if (card->dai_link[i].init) {
1115 ret = card->dai_link[i].init(codec);
1116 if (ret < 0) {
1117 printk(KERN_ERR "asoc: failed to init %s\n",
1118 card->dai_link[i].stream_name);
1119 continue;
1120 }
1121 }
1122 if (card->dai_link[i].codec_dai->ac97_control)
1123 ac97 = 1;
1124 }
1125
1126 snprintf(codec->card->shortname, sizeof(codec->card->shortname),
1127 "%s", card->name);
1128 snprintf(codec->card->longname, sizeof(codec->card->longname),
1129 "%s (%s)", card->name, codec->name);
1130
1131 /* Make sure all DAPM widgets are instantiated */
1132 snd_soc_dapm_new_widgets(codec);
1133
1134 ret = snd_card_register(codec->card);
1135 if (ret < 0) {
1136 printk(KERN_ERR "asoc: failed to register soundcard for %s\n",
1137 codec->name);
1138 goto card_err;
1139 }
1140
1141 mutex_lock(&codec->mutex);
1142#ifdef CONFIG_SND_SOC_AC97_BUS
1143 /* Only instantiate AC97 if not already done by the adaptor
1144 * for the generic AC97 subsystem.
1145 */
1146 if (ac97 && strcmp(codec->name, "AC97") != 0) {
1147 ret = soc_ac97_dev_register(codec);
1148 if (ret < 0) {
1149 printk(KERN_ERR "asoc: AC97 device register failed\n");
1150 snd_card_free(codec->card);
1151 mutex_unlock(&codec->mutex);
1152 goto card_err;
1153 }
1154 }
1155#endif
1156
1157 ret = snd_soc_dapm_sys_add(card->socdev->dev);
1158 if (ret < 0)
1159 printk(KERN_WARNING "asoc: failed to add dapm sysfs entries\n");
1160
1161 ret = device_create_file(card->socdev->dev, &dev_attr_pmdown_time);
1162 if (ret < 0)
1163 printk(KERN_WARNING "asoc: failed to add pmdown_time sysfs\n");
1164
1165 ret = device_create_file(card->socdev->dev, &dev_attr_codec_reg);
1166 if (ret < 0)
1167 printk(KERN_WARNING "asoc: failed to add codec sysfs files\n");
1168
1169 soc_init_codec_debugfs(codec);
1170 mutex_unlock(&codec->mutex);
1171
948 card->instantiated = 1; 1172 card->instantiated = 1;
949 1173
950 return; 1174 return;
951 1175
1176card_err:
1177 if (platform->remove)
1178 platform->remove(pdev);
1179
952platform_err: 1180platform_err:
953 if (codec_dev->remove) 1181 if (codec_dev->remove)
954 codec_dev->remove(pdev); 1182 codec_dev->remove(pdev);
@@ -1048,7 +1276,7 @@ static int soc_poweroff(struct device *dev)
1048 return 0; 1276 return 0;
1049} 1277}
1050 1278
1051static struct dev_pm_ops soc_pm_ops = { 1279static const struct dev_pm_ops soc_pm_ops = {
1052 .suspend = soc_suspend, 1280 .suspend = soc_suspend,
1053 .resume = soc_resume, 1281 .resume = soc_resume,
1054 .poweroff = soc_poweroff, 1282 .poweroff = soc_poweroff,
@@ -1088,8 +1316,8 @@ static int soc_new_pcm(struct snd_soc_device *socdev,
1088 codec_dai->codec = card->codec; 1316 codec_dai->codec = card->codec;
1089 1317
1090 /* check client and interface hw capabilities */ 1318 /* check client and interface hw capabilities */
1091 sprintf(new_name, "%s %s-%d", dai_link->stream_name, codec_dai->name, 1319 snprintf(new_name, sizeof(new_name), "%s %s-%d",
1092 num); 1320 dai_link->stream_name, codec_dai->name, num);
1093 1321
1094 if (codec_dai->playback.channels_min) 1322 if (codec_dai->playback.channels_min)
1095 playback = 1; 1323 playback = 1;
@@ -1151,157 +1379,6 @@ int snd_soc_codec_volatile_register(struct snd_soc_codec *codec, int reg)
1151} 1379}
1152EXPORT_SYMBOL_GPL(snd_soc_codec_volatile_register); 1380EXPORT_SYMBOL_GPL(snd_soc_codec_volatile_register);
1153 1381
1154/* codec register dump */
1155static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf)
1156{
1157 int i, step = 1, count = 0;
1158
1159 if (!codec->reg_cache_size)
1160 return 0;
1161
1162 if (codec->reg_cache_step)
1163 step = codec->reg_cache_step;
1164
1165 count += sprintf(buf, "%s registers\n", codec->name);
1166 for (i = 0; i < codec->reg_cache_size; i += step) {
1167 if (codec->readable_register && !codec->readable_register(i))
1168 continue;
1169
1170 count += sprintf(buf + count, "%2x: ", i);
1171 if (count >= PAGE_SIZE - 1)
1172 break;
1173
1174 if (codec->display_register)
1175 count += codec->display_register(codec, buf + count,
1176 PAGE_SIZE - count, i);
1177 else
1178 count += snprintf(buf + count, PAGE_SIZE - count,
1179 "%4x", codec->read(codec, i));
1180
1181 if (count >= PAGE_SIZE - 1)
1182 break;
1183
1184 count += snprintf(buf + count, PAGE_SIZE - count, "\n");
1185 if (count >= PAGE_SIZE - 1)
1186 break;
1187 }
1188
1189 /* Truncate count; min() would cause a warning */
1190 if (count >= PAGE_SIZE)
1191 count = PAGE_SIZE - 1;
1192
1193 return count;
1194}
1195static ssize_t codec_reg_show(struct device *dev,
1196 struct device_attribute *attr, char *buf)
1197{
1198 struct snd_soc_device *devdata = dev_get_drvdata(dev);
1199 return soc_codec_reg_show(devdata->card->codec, buf);
1200}
1201
1202static DEVICE_ATTR(codec_reg, 0444, codec_reg_show, NULL);
1203
1204#ifdef CONFIG_DEBUG_FS
1205static int codec_reg_open_file(struct inode *inode, struct file *file)
1206{
1207 file->private_data = inode->i_private;
1208 return 0;
1209}
1210
1211static ssize_t codec_reg_read_file(struct file *file, char __user *user_buf,
1212 size_t count, loff_t *ppos)
1213{
1214 ssize_t ret;
1215 struct snd_soc_codec *codec = file->private_data;
1216 char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
1217 if (!buf)
1218 return -ENOMEM;
1219 ret = soc_codec_reg_show(codec, buf);
1220 if (ret >= 0)
1221 ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
1222 kfree(buf);
1223 return ret;
1224}
1225
1226static ssize_t codec_reg_write_file(struct file *file,
1227 const char __user *user_buf, size_t count, loff_t *ppos)
1228{
1229 char buf[32];
1230 int buf_size;
1231 char *start = buf;
1232 unsigned long reg, value;
1233 int step = 1;
1234 struct snd_soc_codec *codec = file->private_data;
1235
1236 buf_size = min(count, (sizeof(buf)-1));
1237 if (copy_from_user(buf, user_buf, buf_size))
1238 return -EFAULT;
1239 buf[buf_size] = 0;
1240
1241 if (codec->reg_cache_step)
1242 step = codec->reg_cache_step;
1243
1244 while (*start == ' ')
1245 start++;
1246 reg = simple_strtoul(start, &start, 16);
1247 if ((reg >= codec->reg_cache_size) || (reg % step))
1248 return -EINVAL;
1249 while (*start == ' ')
1250 start++;
1251 if (strict_strtoul(start, 16, &value))
1252 return -EINVAL;
1253 codec->write(codec, reg, value);
1254 return buf_size;
1255}
1256
1257static const struct file_operations codec_reg_fops = {
1258 .open = codec_reg_open_file,
1259 .read = codec_reg_read_file,
1260 .write = codec_reg_write_file,
1261};
1262
1263static void soc_init_codec_debugfs(struct snd_soc_codec *codec)
1264{
1265 codec->debugfs_reg = debugfs_create_file("codec_reg", 0644,
1266 debugfs_root, codec,
1267 &codec_reg_fops);
1268 if (!codec->debugfs_reg)
1269 printk(KERN_WARNING
1270 "ASoC: Failed to create codec register debugfs file\n");
1271
1272 codec->debugfs_pop_time = debugfs_create_u32("dapm_pop_time", 0744,
1273 debugfs_root,
1274 &codec->pop_time);
1275 if (!codec->debugfs_pop_time)
1276 printk(KERN_WARNING
1277 "Failed to create pop time debugfs file\n");
1278
1279 codec->debugfs_dapm = debugfs_create_dir("dapm", debugfs_root);
1280 if (!codec->debugfs_dapm)
1281 printk(KERN_WARNING
1282 "Failed to create DAPM debugfs directory\n");
1283
1284 snd_soc_dapm_debugfs_init(codec);
1285}
1286
1287static void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec)
1288{
1289 debugfs_remove_recursive(codec->debugfs_dapm);
1290 debugfs_remove(codec->debugfs_pop_time);
1291 debugfs_remove(codec->debugfs_reg);
1292}
1293
1294#else
1295
1296static inline void soc_init_codec_debugfs(struct snd_soc_codec *codec)
1297{
1298}
1299
1300static inline void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec)
1301{
1302}
1303#endif
1304
1305/** 1382/**
1306 * snd_soc_new_ac97_codec - initailise AC97 device 1383 * snd_soc_new_ac97_codec - initailise AC97 device
1307 * @codec: audio codec 1384 * @codec: audio codec
@@ -1331,6 +1408,7 @@ int snd_soc_new_ac97_codec(struct snd_soc_codec *codec,
1331 1408
1332 codec->ac97->bus->ops = ops; 1409 codec->ac97->bus->ops = ops;
1333 codec->ac97->num = num; 1410 codec->ac97->num = num;
1411 codec->dev = &codec->ac97->dev;
1334 mutex_unlock(&codec->mutex); 1412 mutex_unlock(&codec->mutex);
1335 return 0; 1413 return 0;
1336} 1414}
@@ -1369,19 +1447,42 @@ int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg,
1369 int change; 1447 int change;
1370 unsigned int old, new; 1448 unsigned int old, new;
1371 1449
1372 mutex_lock(&io_mutex);
1373 old = snd_soc_read(codec, reg); 1450 old = snd_soc_read(codec, reg);
1374 new = (old & ~mask) | value; 1451 new = (old & ~mask) | value;
1375 change = old != new; 1452 change = old != new;
1376 if (change) 1453 if (change)
1377 snd_soc_write(codec, reg, new); 1454 snd_soc_write(codec, reg, new);
1378 1455
1379 mutex_unlock(&io_mutex);
1380 return change; 1456 return change;
1381} 1457}
1382EXPORT_SYMBOL_GPL(snd_soc_update_bits); 1458EXPORT_SYMBOL_GPL(snd_soc_update_bits);
1383 1459
1384/** 1460/**
1461 * snd_soc_update_bits_locked - update codec register bits
1462 * @codec: audio codec
1463 * @reg: codec register
1464 * @mask: register mask
1465 * @value: new value
1466 *
1467 * Writes new register value, and takes the codec mutex.
1468 *
1469 * Returns 1 for change else 0.
1470 */
1471int snd_soc_update_bits_locked(struct snd_soc_codec *codec,
1472 unsigned short reg, unsigned int mask,
1473 unsigned int value)
1474{
1475 int change;
1476
1477 mutex_lock(&codec->mutex);
1478 change = snd_soc_update_bits(codec, reg, mask, value);
1479 mutex_unlock(&codec->mutex);
1480
1481 return change;
1482}
1483EXPORT_SYMBOL_GPL(snd_soc_update_bits_locked);
1484
1485/**
1385 * snd_soc_test_bits - test register for change 1486 * snd_soc_test_bits - test register for change
1386 * @codec: audio codec 1487 * @codec: audio codec
1387 * @reg: codec register 1488 * @reg: codec register
@@ -1399,11 +1500,9 @@ int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned short reg,
1399 int change; 1500 int change;
1400 unsigned int old, new; 1501 unsigned int old, new;
1401 1502
1402 mutex_lock(&io_mutex);
1403 old = snd_soc_read(codec, reg); 1503 old = snd_soc_read(codec, reg);
1404 new = (old & ~mask) | value; 1504 new = (old & ~mask) | value;
1405 change = old != new; 1505 change = old != new;
1406 mutex_unlock(&io_mutex);
1407 1506
1408 return change; 1507 return change;
1409} 1508}
@@ -1450,89 +1549,17 @@ int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid)
1450 mutex_unlock(&codec->mutex); 1549 mutex_unlock(&codec->mutex);
1451 return ret; 1550 return ret;
1452 } 1551 }
1453 } 1552 /* Check for codec->ac97 to handle the ac97.c fun */
1454 1553 if (card->dai_link[i].codec_dai->ac97_control && codec->ac97) {
1455 mutex_unlock(&codec->mutex);
1456 return ret;
1457}
1458EXPORT_SYMBOL_GPL(snd_soc_new_pcms);
1459
1460/**
1461 * snd_soc_init_card - register sound card
1462 * @socdev: the SoC audio device
1463 *
1464 * Register a SoC sound card. Also registers an AC97 device if the
1465 * codec is AC97 for ad hoc devices.
1466 *
1467 * Returns 0 for success, else error.
1468 */
1469int snd_soc_init_card(struct snd_soc_device *socdev)
1470{
1471 struct snd_soc_card *card = socdev->card;
1472 struct snd_soc_codec *codec = card->codec;
1473 int ret = 0, i, ac97 = 0, err = 0;
1474
1475 for (i = 0; i < card->num_links; i++) {
1476 if (card->dai_link[i].init) {
1477 err = card->dai_link[i].init(codec);
1478 if (err < 0) {
1479 printk(KERN_ERR "asoc: failed to init %s\n",
1480 card->dai_link[i].stream_name);
1481 continue;
1482 }
1483 }
1484 if (card->dai_link[i].codec_dai->ac97_control) {
1485 ac97 = 1;
1486 snd_ac97_dev_add_pdata(codec->ac97, 1554 snd_ac97_dev_add_pdata(codec->ac97,
1487 card->dai_link[i].cpu_dai->ac97_pdata); 1555 card->dai_link[i].cpu_dai->ac97_pdata);
1488 } 1556 }
1489 } 1557 }
1490 snprintf(codec->card->shortname, sizeof(codec->card->shortname),
1491 "%s", card->name);
1492 snprintf(codec->card->longname, sizeof(codec->card->longname),
1493 "%s (%s)", card->name, codec->name);
1494
1495 /* Make sure all DAPM widgets are instantiated */
1496 snd_soc_dapm_new_widgets(codec);
1497
1498 ret = snd_card_register(codec->card);
1499 if (ret < 0) {
1500 printk(KERN_ERR "asoc: failed to register soundcard for %s\n",
1501 codec->name);
1502 goto out;
1503 }
1504 1558
1505 mutex_lock(&codec->mutex);
1506#ifdef CONFIG_SND_SOC_AC97_BUS
1507 /* Only instantiate AC97 if not already done by the adaptor
1508 * for the generic AC97 subsystem.
1509 */
1510 if (ac97 && strcmp(codec->name, "AC97") != 0) {
1511 ret = soc_ac97_dev_register(codec);
1512 if (ret < 0) {
1513 printk(KERN_ERR "asoc: AC97 device register failed\n");
1514 snd_card_free(codec->card);
1515 mutex_unlock(&codec->mutex);
1516 goto out;
1517 }
1518 }
1519#endif
1520
1521 err = snd_soc_dapm_sys_add(socdev->dev);
1522 if (err < 0)
1523 printk(KERN_WARNING "asoc: failed to add dapm sysfs entries\n");
1524
1525 err = device_create_file(socdev->dev, &dev_attr_codec_reg);
1526 if (err < 0)
1527 printk(KERN_WARNING "asoc: failed to add codec sysfs files\n");
1528
1529 soc_init_codec_debugfs(codec);
1530 mutex_unlock(&codec->mutex); 1559 mutex_unlock(&codec->mutex);
1531
1532out:
1533 return ret; 1560 return ret;
1534} 1561}
1535EXPORT_SYMBOL_GPL(snd_soc_init_card); 1562EXPORT_SYMBOL_GPL(snd_soc_new_pcms);
1536 1563
1537/** 1564/**
1538 * snd_soc_free_pcms - free sound card and pcms 1565 * snd_soc_free_pcms - free sound card and pcms
@@ -1734,7 +1761,7 @@ int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol,
1734 mask |= (bitmask - 1) << e->shift_r; 1761 mask |= (bitmask - 1) << e->shift_r;
1735 } 1762 }
1736 1763
1737 return snd_soc_update_bits(codec, e->reg, mask, val); 1764 return snd_soc_update_bits_locked(codec, e->reg, mask, val);
1738} 1765}
1739EXPORT_SYMBOL_GPL(snd_soc_put_enum_double); 1766EXPORT_SYMBOL_GPL(snd_soc_put_enum_double);
1740 1767
@@ -1808,7 +1835,7 @@ int snd_soc_put_value_enum_double(struct snd_kcontrol *kcontrol,
1808 mask |= e->mask << e->shift_r; 1835 mask |= e->mask << e->shift_r;
1809 } 1836 }
1810 1837
1811 return snd_soc_update_bits(codec, e->reg, mask, val); 1838 return snd_soc_update_bits_locked(codec, e->reg, mask, val);
1812} 1839}
1813EXPORT_SYMBOL_GPL(snd_soc_put_value_enum_double); 1840EXPORT_SYMBOL_GPL(snd_soc_put_value_enum_double);
1814 1841
@@ -1969,7 +1996,7 @@ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
1969 val_mask |= mask << rshift; 1996 val_mask |= mask << rshift;
1970 val |= val2 << rshift; 1997 val |= val2 << rshift;
1971 } 1998 }
1972 return snd_soc_update_bits(codec, reg, val_mask, val); 1999 return snd_soc_update_bits_locked(codec, reg, val_mask, val);
1973} 2000}
1974EXPORT_SYMBOL_GPL(snd_soc_put_volsw); 2001EXPORT_SYMBOL_GPL(snd_soc_put_volsw);
1975 2002
@@ -2075,11 +2102,11 @@ int snd_soc_put_volsw_2r(struct snd_kcontrol *kcontrol,
2075 val = val << shift; 2102 val = val << shift;
2076 val2 = val2 << shift; 2103 val2 = val2 << shift;
2077 2104
2078 err = snd_soc_update_bits(codec, reg, val_mask, val); 2105 err = snd_soc_update_bits_locked(codec, reg, val_mask, val);
2079 if (err < 0) 2106 if (err < 0)
2080 return err; 2107 return err;
2081 2108
2082 err = snd_soc_update_bits(codec, reg2, val_mask, val2); 2109 err = snd_soc_update_bits_locked(codec, reg2, val_mask, val2);
2083 return err; 2110 return err;
2084} 2111}
2085EXPORT_SYMBOL_GPL(snd_soc_put_volsw_2r); 2112EXPORT_SYMBOL_GPL(snd_soc_put_volsw_2r);
@@ -2158,7 +2185,7 @@ int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol,
2158 val = (ucontrol->value.integer.value[0]+min) & 0xff; 2185 val = (ucontrol->value.integer.value[0]+min) & 0xff;
2159 val |= ((ucontrol->value.integer.value[1]+min) & 0xff) << 8; 2186 val |= ((ucontrol->value.integer.value[1]+min) & 0xff) << 8;
2160 2187
2161 return snd_soc_update_bits(codec, reg, 0xffff, val); 2188 return snd_soc_update_bits_locked(codec, reg, 0xffff, val);
2162} 2189}
2163EXPORT_SYMBOL_GPL(snd_soc_put_volsw_s8); 2190EXPORT_SYMBOL_GPL(snd_soc_put_volsw_s8);
2164 2191
@@ -2205,16 +2232,18 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_clkdiv);
2205 * snd_soc_dai_set_pll - configure DAI PLL. 2232 * snd_soc_dai_set_pll - configure DAI PLL.
2206 * @dai: DAI 2233 * @dai: DAI
2207 * @pll_id: DAI specific PLL ID 2234 * @pll_id: DAI specific PLL ID
2235 * @source: DAI specific source for the PLL
2208 * @freq_in: PLL input clock frequency in Hz 2236 * @freq_in: PLL input clock frequency in Hz
2209 * @freq_out: requested PLL output clock frequency in Hz 2237 * @freq_out: requested PLL output clock frequency in Hz
2210 * 2238 *
2211 * Configures and enables PLL to generate output clock based on input clock. 2239 * Configures and enables PLL to generate output clock based on input clock.
2212 */ 2240 */
2213int snd_soc_dai_set_pll(struct snd_soc_dai *dai, 2241int snd_soc_dai_set_pll(struct snd_soc_dai *dai, int pll_id, int source,
2214 int pll_id, unsigned int freq_in, unsigned int freq_out) 2242 unsigned int freq_in, unsigned int freq_out)
2215{ 2243{
2216 if (dai->ops && dai->ops->set_pll) 2244 if (dai->ops && dai->ops->set_pll)
2217 return dai->ops->set_pll(dai, pll_id, freq_in, freq_out); 2245 return dai->ops->set_pll(dai, pll_id, source,
2246 freq_in, freq_out);
2218 else 2247 else
2219 return -EINVAL; 2248 return -EINVAL;
2220} 2249}
@@ -2259,6 +2288,30 @@ int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
2259EXPORT_SYMBOL_GPL(snd_soc_dai_set_tdm_slot); 2288EXPORT_SYMBOL_GPL(snd_soc_dai_set_tdm_slot);
2260 2289
2261/** 2290/**
2291 * snd_soc_dai_set_channel_map - configure DAI audio channel map
2292 * @dai: DAI
2293 * @tx_num: how many TX channels
2294 * @tx_slot: pointer to an array which imply the TX slot number channel
2295 * 0~num-1 uses
2296 * @rx_num: how many RX channels
2297 * @rx_slot: pointer to an array which imply the RX slot number channel
2298 * 0~num-1 uses
2299 *
2300 * configure the relationship between channel number and TDM slot number.
2301 */
2302int snd_soc_dai_set_channel_map(struct snd_soc_dai *dai,
2303 unsigned int tx_num, unsigned int *tx_slot,
2304 unsigned int rx_num, unsigned int *rx_slot)
2305{
2306 if (dai->ops && dai->ops->set_channel_map)
2307 return dai->ops->set_channel_map(dai, tx_num, tx_slot,
2308 rx_num, rx_slot);
2309 else
2310 return -EINVAL;
2311}
2312EXPORT_SYMBOL_GPL(snd_soc_dai_set_channel_map);
2313
2314/**
2262 * snd_soc_dai_set_tristate - configure DAI system or master clock. 2315 * snd_soc_dai_set_tristate - configure DAI system or master clock.
2263 * @dai: DAI 2316 * @dai: DAI
2264 * @tristate: tristate enable 2317 * @tristate: tristate enable
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 66d4c165f99b..7c28f401f436 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -38,19 +38,13 @@
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>
44#include <sound/soc-dapm.h> 45#include <sound/soc-dapm.h>
45#include <sound/initval.h> 46#include <sound/initval.h>
46 47
47/* debug */
48#ifdef DEBUG
49#define dump_dapm(codec, action) dbg_dump_dapm(codec, action)
50#else
51#define dump_dapm(codec, action)
52#endif
53
54/* dapm power sequences - make this per codec in the future */ 48/* dapm power sequences - make this per codec in the future */
55static int dapm_up_seq[] = { 49static int dapm_up_seq[] = {
56 [snd_soc_dapm_pre] = 0, 50 [snd_soc_dapm_pre] = 0,
@@ -719,6 +713,10 @@ static int dapm_supply_check_power(struct snd_soc_dapm_widget *w)
719 713
720 /* Check if one of our outputs is connected */ 714 /* Check if one of our outputs is connected */
721 list_for_each_entry(path, &w->sinks, list_source) { 715 list_for_each_entry(path, &w->sinks, list_source) {
716 if (path->connected &&
717 !path->connected(path->source, path->sink))
718 continue;
719
722 if (path->sink && path->sink->power_check && 720 if (path->sink && path->sink->power_check &&
723 path->sink->power_check(path->sink)) { 721 path->sink->power_check(path->sink)) {
724 power = 1; 722 power = 1;
@@ -735,6 +733,8 @@ static int dapm_seq_compare(struct snd_soc_dapm_widget *a,
735 struct snd_soc_dapm_widget *b, 733 struct snd_soc_dapm_widget *b,
736 int sort[]) 734 int sort[])
737{ 735{
736 if (a->codec != b->codec)
737 return (unsigned long)a - (unsigned long)b;
738 if (sort[a->id] != sort[b->id]) 738 if (sort[a->id] != sort[b->id])
739 return sort[a->id] - sort[b->id]; 739 return sort[a->id] - sort[b->id];
740 if (a->reg != b->reg) 740 if (a->reg != b->reg)
@@ -1013,13 +1013,28 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
1013 sys_power = 0; 1013 sys_power = 0;
1014 break; 1014 break;
1015 case SND_SOC_DAPM_STREAM_NOP: 1015 case SND_SOC_DAPM_STREAM_NOP:
1016 sys_power = codec->bias_level != SND_SOC_BIAS_STANDBY; 1016 switch (codec->bias_level) {
1017 case SND_SOC_BIAS_STANDBY:
1018 case SND_SOC_BIAS_OFF:
1019 sys_power = 0;
1020 break;
1021 default:
1022 sys_power = 1;
1023 break;
1024 }
1017 break; 1025 break;
1018 default: 1026 default:
1019 break; 1027 break;
1020 } 1028 }
1021 } 1029 }
1022 1030
1031 if (sys_power && codec->bias_level == SND_SOC_BIAS_OFF) {
1032 ret = snd_soc_dapm_set_bias_level(socdev,
1033 SND_SOC_BIAS_STANDBY);
1034 if (ret != 0)
1035 pr_err("Failed to turn on bias: %d\n", ret);
1036 }
1037
1023 /* If we're changing to all on or all off then prepare */ 1038 /* If we're changing to all on or all off then prepare */
1024 if ((sys_power && codec->bias_level == SND_SOC_BIAS_STANDBY) || 1039 if ((sys_power && codec->bias_level == SND_SOC_BIAS_STANDBY) ||
1025 (!sys_power && codec->bias_level == SND_SOC_BIAS_ON)) { 1040 (!sys_power && codec->bias_level == SND_SOC_BIAS_ON)) {
@@ -1043,6 +1058,14 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
1043 pr_err("Failed to apply standby bias: %d\n", ret); 1058 pr_err("Failed to apply standby bias: %d\n", ret);
1044 } 1059 }
1045 1060
1061 /* If we're in standby and can support bias off then do that */
1062 if (codec->bias_level == SND_SOC_BIAS_STANDBY &&
1063 codec->idle_bias_off) {
1064 ret = snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_OFF);
1065 if (ret != 0)
1066 pr_err("Failed to turn off bias: %d\n", ret);
1067 }
1068
1046 /* If we just powered up then move to active bias */ 1069 /* If we just powered up then move to active bias */
1047 if (codec->bias_level == SND_SOC_BIAS_PREPARE && sys_power) { 1070 if (codec->bias_level == SND_SOC_BIAS_PREPARE && sys_power) {
1048 ret = snd_soc_dapm_set_bias_level(socdev, 1071 ret = snd_soc_dapm_set_bias_level(socdev,
@@ -1057,66 +1080,6 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
1057 return 0; 1080 return 0;
1058} 1081}
1059 1082
1060#ifdef DEBUG
1061static void dbg_dump_dapm(struct snd_soc_codec* codec, const char *action)
1062{
1063 struct snd_soc_dapm_widget *w;
1064 struct snd_soc_dapm_path *p = NULL;
1065 int in, out;
1066
1067 printk("DAPM %s %s\n", codec->name, action);
1068
1069 list_for_each_entry(w, &codec->dapm_widgets, list) {
1070
1071 /* only display widgets that effect routing */
1072 switch (w->id) {
1073 case snd_soc_dapm_pre:
1074 case snd_soc_dapm_post:
1075 case snd_soc_dapm_vmid:
1076 continue;
1077 case snd_soc_dapm_mux:
1078 case snd_soc_dapm_value_mux:
1079 case snd_soc_dapm_output:
1080 case snd_soc_dapm_input:
1081 case snd_soc_dapm_switch:
1082 case snd_soc_dapm_hp:
1083 case snd_soc_dapm_mic:
1084 case snd_soc_dapm_spk:
1085 case snd_soc_dapm_line:
1086 case snd_soc_dapm_micbias:
1087 case snd_soc_dapm_dac:
1088 case snd_soc_dapm_adc:
1089 case snd_soc_dapm_pga:
1090 case snd_soc_dapm_mixer:
1091 case snd_soc_dapm_mixer_named_ctl:
1092 case snd_soc_dapm_supply:
1093 case snd_soc_dapm_aif_in:
1094 case snd_soc_dapm_aif_out:
1095 if (w->name) {
1096 in = is_connected_input_ep(w);
1097 dapm_clear_walk(w->codec);
1098 out = is_connected_output_ep(w);
1099 dapm_clear_walk(w->codec);
1100 printk("%s: %s in %d out %d\n", w->name,
1101 w->power ? "On":"Off",in, out);
1102
1103 list_for_each_entry(p, &w->sources, list_sink) {
1104 if (p->connect)
1105 printk(" in %s %s\n", p->name ? p->name : "static",
1106 p->source->name);
1107 }
1108 list_for_each_entry(p, &w->sinks, list_source) {
1109 if (p->connect)
1110 printk(" out %s %s\n", p->name ? p->name : "static",
1111 p->sink->name);
1112 }
1113 }
1114 break;
1115 }
1116 }
1117}
1118#endif
1119
1120#ifdef CONFIG_DEBUG_FS 1083#ifdef CONFIG_DEBUG_FS
1121static int dapm_widget_power_open_file(struct inode *inode, struct file *file) 1084static int dapm_widget_power_open_file(struct inode *inode, struct file *file)
1122{ 1085{
@@ -1143,15 +1106,25 @@ static ssize_t dapm_widget_power_read_file(struct file *file,
1143 out = is_connected_output_ep(w); 1106 out = is_connected_output_ep(w);
1144 dapm_clear_walk(w->codec); 1107 dapm_clear_walk(w->codec);
1145 1108
1146 ret = snprintf(buf, PAGE_SIZE, "%s: %s in %d out %d\n", 1109 ret = snprintf(buf, PAGE_SIZE, "%s: %s in %d out %d",
1147 w->name, w->power ? "On" : "Off", in, out); 1110 w->name, w->power ? "On" : "Off", in, out);
1148 1111
1112 if (w->reg >= 0)
1113 ret += snprintf(buf + ret, PAGE_SIZE - ret,
1114 " - R%d(0x%x) bit %d",
1115 w->reg, w->reg, w->shift);
1116
1117 ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n");
1118
1149 if (w->sname) 1119 if (w->sname)
1150 ret += snprintf(buf + ret, PAGE_SIZE - ret, " stream %s %s\n", 1120 ret += snprintf(buf + ret, PAGE_SIZE - ret, " stream %s %s\n",
1151 w->sname, 1121 w->sname,
1152 w->active ? "active" : "inactive"); 1122 w->active ? "active" : "inactive");
1153 1123
1154 list_for_each_entry(p, &w->sources, list_sink) { 1124 list_for_each_entry(p, &w->sources, list_sink) {
1125 if (p->connected && !p->connected(w, p->sink))
1126 continue;
1127
1155 if (p->connect) 1128 if (p->connect)
1156 ret += snprintf(buf + ret, PAGE_SIZE - ret, 1129 ret += snprintf(buf + ret, PAGE_SIZE - ret,
1157 " in %s %s\n", 1130 " in %s %s\n",
@@ -1159,6 +1132,9 @@ static ssize_t dapm_widget_power_read_file(struct file *file,
1159 p->source->name); 1132 p->source->name);
1160 } 1133 }
1161 list_for_each_entry(p, &w->sinks, list_source) { 1134 list_for_each_entry(p, &w->sinks, list_source) {
1135 if (p->connected && !p->connected(w, p->sink))
1136 continue;
1137
1162 if (p->connect) 1138 if (p->connect)
1163 ret += snprintf(buf + ret, PAGE_SIZE - ret, 1139 ret += snprintf(buf + ret, PAGE_SIZE - ret,
1164 " out %s %s\n", 1140 " out %s %s\n",
@@ -1206,8 +1182,8 @@ void snd_soc_dapm_debugfs_init(struct snd_soc_codec *codec)
1206 1182
1207/* test and update the power status of a mux widget */ 1183/* test and update the power status of a mux widget */
1208static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget, 1184static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
1209 struct snd_kcontrol *kcontrol, int mask, 1185 struct snd_kcontrol *kcontrol, int change,
1210 int mux, int val, struct soc_enum *e) 1186 int mux, struct soc_enum *e)
1211{ 1187{
1212 struct snd_soc_dapm_path *path; 1188 struct snd_soc_dapm_path *path;
1213 int found = 0; 1189 int found = 0;
@@ -1216,7 +1192,7 @@ static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
1216 widget->id != snd_soc_dapm_value_mux) 1192 widget->id != snd_soc_dapm_value_mux)
1217 return -ENODEV; 1193 return -ENODEV;
1218 1194
1219 if (!snd_soc_test_bits(widget->codec, e->reg, mask, val)) 1195 if (!change)
1220 return 0; 1196 return 0;
1221 1197
1222 /* find dapm widget path assoc with kcontrol */ 1198 /* find dapm widget path assoc with kcontrol */
@@ -1235,18 +1211,15 @@ static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
1235 path->connect = 0; /* old connection must be powered down */ 1211 path->connect = 0; /* old connection must be powered down */
1236 } 1212 }
1237 1213
1238 if (found) { 1214 if (found)
1239 dapm_power_widgets(widget->codec, SND_SOC_DAPM_STREAM_NOP); 1215 dapm_power_widgets(widget->codec, SND_SOC_DAPM_STREAM_NOP);
1240 dump_dapm(widget->codec, "mux power update");
1241 }
1242 1216
1243 return 0; 1217 return 0;
1244} 1218}
1245 1219
1246/* test and update the power status of a mixer or switch widget */ 1220/* test and update the power status of a mixer or switch widget */
1247static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget, 1221static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
1248 struct snd_kcontrol *kcontrol, int reg, 1222 struct snd_kcontrol *kcontrol, int connect)
1249 int val_mask, int val, int invert)
1250{ 1223{
1251 struct snd_soc_dapm_path *path; 1224 struct snd_soc_dapm_path *path;
1252 int found = 0; 1225 int found = 0;
@@ -1256,9 +1229,6 @@ static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
1256 widget->id != snd_soc_dapm_switch) 1229 widget->id != snd_soc_dapm_switch)
1257 return -ENODEV; 1230 return -ENODEV;
1258 1231
1259 if (!snd_soc_test_bits(widget->codec, reg, val_mask, val))
1260 return 0;
1261
1262 /* find dapm widget path assoc with kcontrol */ 1232 /* find dapm widget path assoc with kcontrol */
1263 list_for_each_entry(path, &widget->codec->dapm_paths, list) { 1233 list_for_each_entry(path, &widget->codec->dapm_paths, list) {
1264 if (path->kcontrol != kcontrol) 1234 if (path->kcontrol != kcontrol)
@@ -1266,19 +1236,12 @@ static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
1266 1236
1267 /* found, now check type */ 1237 /* found, now check type */
1268 found = 1; 1238 found = 1;
1269 if (val) 1239 path->connect = connect;
1270 /* new connection */
1271 path->connect = invert ? 0:1;
1272 else
1273 /* old connection must be powered down */
1274 path->connect = invert ? 1:0;
1275 break; 1240 break;
1276 } 1241 }
1277 1242
1278 if (found) { 1243 if (found)
1279 dapm_power_widgets(widget->codec, SND_SOC_DAPM_STREAM_NOP); 1244 dapm_power_widgets(widget->codec, SND_SOC_DAPM_STREAM_NOP);
1280 dump_dapm(widget->codec, "mixer power update");
1281 }
1282 1245
1283 return 0; 1246 return 0;
1284} 1247}
@@ -1394,17 +1357,18 @@ static int snd_soc_dapm_set_pin(struct snd_soc_codec *codec,
1394 */ 1357 */
1395int snd_soc_dapm_sync(struct snd_soc_codec *codec) 1358int snd_soc_dapm_sync(struct snd_soc_codec *codec)
1396{ 1359{
1397 int ret = dapm_power_widgets(codec, SND_SOC_DAPM_STREAM_NOP); 1360 return dapm_power_widgets(codec, SND_SOC_DAPM_STREAM_NOP);
1398 dump_dapm(codec, "sync");
1399 return ret;
1400} 1361}
1401EXPORT_SYMBOL_GPL(snd_soc_dapm_sync); 1362EXPORT_SYMBOL_GPL(snd_soc_dapm_sync);
1402 1363
1403static int snd_soc_dapm_add_route(struct snd_soc_codec *codec, 1364static int snd_soc_dapm_add_route(struct snd_soc_codec *codec,
1404 const char *sink, const char *control, const char *source) 1365 const struct snd_soc_dapm_route *route)
1405{ 1366{
1406 struct snd_soc_dapm_path *path; 1367 struct snd_soc_dapm_path *path;
1407 struct snd_soc_dapm_widget *wsource = NULL, *wsink = NULL, *w; 1368 struct snd_soc_dapm_widget *wsource = NULL, *wsink = NULL, *w;
1369 const char *sink = route->sink;
1370 const char *control = route->control;
1371 const char *source = route->source;
1408 int ret = 0; 1372 int ret = 0;
1409 1373
1410 /* find src and dest widgets */ 1374 /* find src and dest widgets */
@@ -1428,6 +1392,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec,
1428 1392
1429 path->source = wsource; 1393 path->source = wsource;
1430 path->sink = wsink; 1394 path->sink = wsink;
1395 path->connected = route->connected;
1431 INIT_LIST_HEAD(&path->list); 1396 INIT_LIST_HEAD(&path->list);
1432 INIT_LIST_HEAD(&path->list_source); 1397 INIT_LIST_HEAD(&path->list_source);
1433 INIT_LIST_HEAD(&path->list_sink); 1398 INIT_LIST_HEAD(&path->list_sink);
@@ -1528,8 +1493,7 @@ int snd_soc_dapm_add_routes(struct snd_soc_codec *codec,
1528 int i, ret; 1493 int i, ret;
1529 1494
1530 for (i = 0; i < num; i++) { 1495 for (i = 0; i < num; i++) {
1531 ret = snd_soc_dapm_add_route(codec, route->sink, 1496 ret = snd_soc_dapm_add_route(codec, route);
1532 route->control, route->source);
1533 if (ret < 0) { 1497 if (ret < 0) {
1534 printk(KERN_ERR "Failed to add route %s->%s\n", 1498 printk(KERN_ERR "Failed to add route %s->%s\n",
1535 route->source, 1499 route->source,
@@ -1675,6 +1639,7 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
1675 unsigned int mask = (1 << fls(max)) - 1; 1639 unsigned int mask = (1 << fls(max)) - 1;
1676 unsigned int invert = mc->invert; 1640 unsigned int invert = mc->invert;
1677 unsigned int val, val2, val_mask; 1641 unsigned int val, val2, val_mask;
1642 int connect;
1678 int ret; 1643 int ret;
1679 1644
1680 val = (ucontrol->value.integer.value[0] & mask); 1645 val = (ucontrol->value.integer.value[0] & mask);
@@ -1701,7 +1666,17 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
1701 return 1; 1666 return 1;
1702 } 1667 }
1703 1668
1704 dapm_mixer_update_power(widget, kcontrol, reg, val_mask, val, invert); 1669 if (snd_soc_test_bits(widget->codec, reg, val_mask, val)) {
1670 if (val)
1671 /* new connection */
1672 connect = invert ? 0:1;
1673 else
1674 /* old connection must be powered down */
1675 connect = invert ? 1:0;
1676
1677 dapm_mixer_update_power(widget, kcontrol, connect);
1678 }
1679
1705 if (widget->event) { 1680 if (widget->event) {
1706 if (widget->event_flags & SND_SOC_DAPM_PRE_REG) { 1681 if (widget->event_flags & SND_SOC_DAPM_PRE_REG) {
1707 ret = widget->event(widget, kcontrol, 1682 ret = widget->event(widget, kcontrol,
@@ -1766,7 +1741,7 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
1766{ 1741{
1767 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 1742 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
1768 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 1743 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1769 unsigned int val, mux; 1744 unsigned int val, mux, change;
1770 unsigned int mask, bitmask; 1745 unsigned int mask, bitmask;
1771 int ret = 0; 1746 int ret = 0;
1772 1747
@@ -1786,20 +1761,21 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
1786 1761
1787 mutex_lock(&widget->codec->mutex); 1762 mutex_lock(&widget->codec->mutex);
1788 widget->value = val; 1763 widget->value = val;
1789 dapm_mux_update_power(widget, kcontrol, mask, mux, val, e); 1764 change = snd_soc_test_bits(widget->codec, e->reg, mask, val);
1790 if (widget->event) { 1765 dapm_mux_update_power(widget, kcontrol, change, mux, e);
1791 if (widget->event_flags & SND_SOC_DAPM_PRE_REG) { 1766
1792 ret = widget->event(widget, 1767 if (widget->event_flags & SND_SOC_DAPM_PRE_REG) {
1793 kcontrol, SND_SOC_DAPM_PRE_REG); 1768 ret = widget->event(widget,
1794 if (ret < 0) 1769 kcontrol, SND_SOC_DAPM_PRE_REG);
1795 goto out; 1770 if (ret < 0)
1796 } 1771 goto out;
1797 ret = snd_soc_update_bits(widget->codec, e->reg, mask, val); 1772 }
1798 if (widget->event_flags & SND_SOC_DAPM_POST_REG) 1773
1799 ret = widget->event(widget, 1774 ret = snd_soc_update_bits(widget->codec, e->reg, mask, val);
1800 kcontrol, SND_SOC_DAPM_POST_REG); 1775
1801 } else 1776 if (widget->event_flags & SND_SOC_DAPM_POST_REG)
1802 ret = snd_soc_update_bits(widget->codec, e->reg, mask, val); 1777 ret = widget->event(widget,
1778 kcontrol, SND_SOC_DAPM_POST_REG);
1803 1779
1804out: 1780out:
1805 mutex_unlock(&widget->codec->mutex); 1781 mutex_unlock(&widget->codec->mutex);
@@ -1808,6 +1784,54 @@ out:
1808EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_double); 1784EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_double);
1809 1785
1810/** 1786/**
1787 * snd_soc_dapm_get_enum_virt - Get virtual DAPM mux
1788 * @kcontrol: mixer control
1789 * @ucontrol: control element information
1790 *
1791 * Returns 0 for success.
1792 */
1793int snd_soc_dapm_get_enum_virt(struct snd_kcontrol *kcontrol,
1794 struct snd_ctl_elem_value *ucontrol)
1795{
1796 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
1797
1798 ucontrol->value.enumerated.item[0] = widget->value;
1799
1800 return 0;
1801}
1802EXPORT_SYMBOL_GPL(snd_soc_dapm_get_enum_virt);
1803
1804/**
1805 * snd_soc_dapm_put_enum_virt - Set virtual DAPM mux
1806 * @kcontrol: mixer control
1807 * @ucontrol: control element information
1808 *
1809 * Returns 0 for success.
1810 */
1811int snd_soc_dapm_put_enum_virt(struct snd_kcontrol *kcontrol,
1812 struct snd_ctl_elem_value *ucontrol)
1813{
1814 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
1815 struct soc_enum *e =
1816 (struct soc_enum *)kcontrol->private_value;
1817 int change;
1818 int ret = 0;
1819
1820 if (ucontrol->value.enumerated.item[0] >= e->max)
1821 return -EINVAL;
1822
1823 mutex_lock(&widget->codec->mutex);
1824
1825 change = widget->value != ucontrol->value.enumerated.item[0];
1826 widget->value = ucontrol->value.enumerated.item[0];
1827 dapm_mux_update_power(widget, kcontrol, change, widget->value, e);
1828
1829 mutex_unlock(&widget->codec->mutex);
1830 return ret;
1831}
1832EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_virt);
1833
1834/**
1811 * snd_soc_dapm_get_value_enum_double - dapm semi enumerated double mixer get 1835 * snd_soc_dapm_get_value_enum_double - dapm semi enumerated double mixer get
1812 * callback 1836 * callback
1813 * @kcontrol: mixer control 1837 * @kcontrol: mixer control
@@ -1865,7 +1889,7 @@ int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
1865{ 1889{
1866 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 1890 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
1867 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 1891 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1868 unsigned int val, mux; 1892 unsigned int val, mux, change;
1869 unsigned int mask; 1893 unsigned int mask;
1870 int ret = 0; 1894 int ret = 0;
1871 1895
@@ -1883,20 +1907,21 @@ int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
1883 1907
1884 mutex_lock(&widget->codec->mutex); 1908 mutex_lock(&widget->codec->mutex);
1885 widget->value = val; 1909 widget->value = val;
1886 dapm_mux_update_power(widget, kcontrol, mask, mux, val, e); 1910 change = snd_soc_test_bits(widget->codec, e->reg, mask, val);
1887 if (widget->event) { 1911 dapm_mux_update_power(widget, kcontrol, change, mux, e);
1888 if (widget->event_flags & SND_SOC_DAPM_PRE_REG) { 1912
1889 ret = widget->event(widget, 1913 if (widget->event_flags & SND_SOC_DAPM_PRE_REG) {
1890 kcontrol, SND_SOC_DAPM_PRE_REG); 1914 ret = widget->event(widget,
1891 if (ret < 0) 1915 kcontrol, SND_SOC_DAPM_PRE_REG);
1892 goto out; 1916 if (ret < 0)
1893 } 1917 goto out;
1894 ret = snd_soc_update_bits(widget->codec, e->reg, mask, val); 1918 }
1895 if (widget->event_flags & SND_SOC_DAPM_POST_REG) 1919
1896 ret = widget->event(widget, 1920 ret = snd_soc_update_bits(widget->codec, e->reg, mask, val);
1897 kcontrol, SND_SOC_DAPM_POST_REG); 1921
1898 } else 1922 if (widget->event_flags & SND_SOC_DAPM_POST_REG)
1899 ret = snd_soc_update_bits(widget->codec, e->reg, mask, val); 1923 ret = widget->event(widget,
1924 kcontrol, SND_SOC_DAPM_POST_REG);
1900 1925
1901out: 1926out:
1902 mutex_unlock(&widget->codec->mutex); 1927 mutex_unlock(&widget->codec->mutex);
@@ -2089,7 +2114,6 @@ int snd_soc_dapm_stream_event(struct snd_soc_codec *codec,
2089 2114
2090 dapm_power_widgets(codec, event); 2115 dapm_power_widgets(codec, event);
2091 mutex_unlock(&codec->mutex); 2116 mutex_unlock(&codec->mutex);
2092 dump_dapm(codec, __func__);
2093 return 0; 2117 return 0;
2094} 2118}
2095EXPORT_SYMBOL_GPL(snd_soc_dapm_stream_event); 2119EXPORT_SYMBOL_GPL(snd_soc_dapm_stream_event);
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c
index 1d455ab79490..3c07a94c2e30 100644
--- a/sound/soc/soc-jack.c
+++ b/sound/soc/soc-jack.c
@@ -58,7 +58,7 @@ EXPORT_SYMBOL_GPL(snd_soc_jack_new);
58 */ 58 */
59void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask) 59void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
60{ 60{
61 struct snd_soc_codec *codec = jack->card->codec; 61 struct snd_soc_codec *codec;
62 struct snd_soc_jack_pin *pin; 62 struct snd_soc_jack_pin *pin;
63 int enable; 63 int enable;
64 int oldstatus; 64 int oldstatus;
@@ -67,6 +67,7 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
67 WARN_ON_ONCE(!jack); 67 WARN_ON_ONCE(!jack);
68 return; 68 return;
69 } 69 }
70 codec = jack->card->codec;
70 71
71 mutex_lock(&codec->mutex); 72 mutex_lock(&codec->mutex);
72 73
@@ -162,6 +163,9 @@ static void snd_soc_jack_gpio_detect(struct snd_soc_jack_gpio *gpio)
162 else 163 else
163 report = 0; 164 report = 0;
164 165
166 if (gpio->jack_status_check)
167 report = gpio->jack_status_check();
168
165 snd_soc_jack_report(jack, report, gpio->report); 169 snd_soc_jack_report(jack, report, gpio->report);
166} 170}
167 171
diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c
new file mode 100644
index 000000000000..1d07b931f3d8
--- /dev/null
+++ b/sound/soc/soc-utils.c
@@ -0,0 +1,74 @@
1/*
2 * soc-util.c -- ALSA SoC Audio Layer utility functions
3 *
4 * Copyright 2009 Wolfson Microelectronics PLC.
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 * Liam Girdwood <lrg@slimlogic.co.uk>
8 *
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 */
15
16#include <sound/core.h>
17#include <sound/pcm.h>
18#include <sound/pcm_params.h>
19#include <sound/soc.h>
20
21int snd_soc_calc_frame_size(int sample_size, int channels, int tdm_slots)
22{
23 return sample_size * channels * tdm_slots;
24}
25EXPORT_SYMBOL_GPL(snd_soc_calc_frame_size);
26
27int snd_soc_params_to_frame_size(struct snd_pcm_hw_params *params)
28{
29 int sample_size;
30
31 switch (params_format(params)) {
32 case SNDRV_PCM_FORMAT_S16_LE:
33 case SNDRV_PCM_FORMAT_S16_BE:
34 sample_size = 16;
35 break;
36 case SNDRV_PCM_FORMAT_S20_3LE:
37 case SNDRV_PCM_FORMAT_S20_3BE:
38 sample_size = 20;
39 break;
40 case SNDRV_PCM_FORMAT_S24_LE:
41 case SNDRV_PCM_FORMAT_S24_BE:
42 sample_size = 24;
43 break;
44 case SNDRV_PCM_FORMAT_S32_LE:
45 case SNDRV_PCM_FORMAT_S32_BE:
46 sample_size = 32;
47 break;
48 default:
49 return -ENOTSUPP;
50 }
51
52 return snd_soc_calc_frame_size(sample_size, params_channels(params),
53 1);
54}
55EXPORT_SYMBOL_GPL(snd_soc_params_to_frame_size);
56
57int snd_soc_calc_bclk(int fs, int sample_size, int channels, int tdm_slots)
58{
59 return fs * snd_soc_calc_frame_size(sample_size, channels, tdm_slots);
60}
61EXPORT_SYMBOL_GPL(snd_soc_calc_bclk);
62
63int snd_soc_params_to_bclk(struct snd_pcm_hw_params *params)
64{
65 int ret;
66
67 ret = snd_soc_params_to_frame_size(params);
68
69 if (ret > 0)
70 return ret * params_rate(params);
71 else
72 return ret;
73}
74EXPORT_SYMBOL_GPL(snd_soc_params_to_bclk);
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..49cc7ea9a518 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>
diff --git a/sound/sound_core.c b/sound/sound_core.c
index 49c998186592..7c2d677a2df5 100644
--- a/sound/sound_core.c
+++ b/sound/sound_core.c
@@ -61,7 +61,7 @@ static void __exit cleanup_soundcore(void)
61 class_destroy(sound_class); 61 class_destroy(sound_class);
62} 62}
63 63
64module_init(init_soundcore); 64subsys_initcall(init_soundcore);
65module_exit(cleanup_soundcore); 65module_exit(cleanup_soundcore);
66 66
67 67
@@ -353,7 +353,7 @@ static struct sound_unit *chains[SOUND_STEP];
353 * @dev: device pointer 353 * @dev: device pointer
354 * 354 *
355 * Allocate a special sound device by minor number from the sound 355 * Allocate a special sound device by minor number from the sound
356 * subsystem. The allocated number is returned on succes. On failure 356 * subsystem. The allocated number is returned on success. On failure
357 * a negative error code is returned. 357 * a negative error code is returned.
358 */ 358 */
359 359
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/cs4231.c b/sound/sparc/cs4231.c
index 8d13d933087d..7dcc06512e86 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>
diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c
index 1d2e51b3f918..2eab6ce48852 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>
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/synth/emux/soundfont.c b/sound/synth/emux/soundfont.c
index 63c8f45c0c22..67c91230c197 100644
--- a/sound/synth/emux/soundfont.c
+++ b/sound/synth/emux/soundfont.c
@@ -374,7 +374,7 @@ sf_zone_new(struct snd_sf_list *sflist, struct snd_soundfont *sf)
374 374
375 375
376/* 376/*
377 * increment sample couter 377 * increment sample counter
378 */ 378 */
379static void 379static void
380set_sample_counter(struct snd_sf_list *sflist, struct snd_soundfont *sf, 380set_sample_counter(struct snd_sf_list *sflist, struct snd_soundfont *sf,
diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig
index 73525c048e7f..c570ae3e6d55 100644
--- a/sound/usb/Kconfig
+++ b/sound/usb/Kconfig
@@ -21,6 +21,18 @@ config SND_USB_AUDIO
21 To compile this driver as a module, choose M here: the module 21 To compile this driver as a module, choose M here: the module
22 will be called snd-usb-audio. 22 will be called snd-usb-audio.
23 23
24config SND_USB_UA101
25 tristate "Edirol UA-101/UA-1000 driver (EXPERIMENTAL)"
26 depends on EXPERIMENTAL
27 select SND_PCM
28 select SND_RAWMIDI
29 help
30 Say Y here to include support for the Edirol UA-101 and UA-1000
31 audio/MIDI interfaces.
32
33 To compile this driver as a module, choose M here: the module
34 will be called snd-ua101.
35
24config SND_USB_USX2Y 36config SND_USB_USX2Y
25 tristate "Tascam US-122, US-224 and US-428 USB driver" 37 tristate "Tascam US-122, US-224 and US-428 USB driver"
26 depends on X86 || PPC || ALPHA 38 depends on X86 || PPC || ALPHA
diff --git a/sound/usb/Makefile b/sound/usb/Makefile
index abb288bfe35d..5bf64aef9558 100644
--- a/sound/usb/Makefile
+++ b/sound/usb/Makefile
@@ -4,9 +4,11 @@
4 4
5snd-usb-audio-objs := usbaudio.o usbmixer.o 5snd-usb-audio-objs := usbaudio.o usbmixer.o
6snd-usb-lib-objs := usbmidi.o 6snd-usb-lib-objs := usbmidi.o
7snd-ua101-objs := ua101.o
7 8
8# Toplevel Module Dependency 9# Toplevel Module Dependency
9obj-$(CONFIG_SND_USB_AUDIO) += snd-usb-audio.o snd-usb-lib.o 10obj-$(CONFIG_SND_USB_AUDIO) += snd-usb-audio.o snd-usb-lib.o
11obj-$(CONFIG_SND_USB_UA101) += snd-ua101.o snd-usb-lib.o
10obj-$(CONFIG_SND_USB_USX2Y) += snd-usb-lib.o 12obj-$(CONFIG_SND_USB_USX2Y) += snd-usb-lib.o
11obj-$(CONFIG_SND_USB_US122L) += snd-usb-lib.o 13obj-$(CONFIG_SND_USB_US122L) += snd-usb-lib.o
12 14
diff --git a/sound/usb/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/device.c b/sound/usb/caiaq/device.c
index a3f02dd97440..afc5aeb68005 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>
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/caiaq/midi.h b/sound/usb/caiaq/midi.h
index 9d16db027fc3..380f984babc9 100644
--- a/sound/usb/caiaq/midi.h
+++ b/sound/usb/caiaq/midi.h
@@ -3,6 +3,6 @@
3 3
4int snd_usb_caiaq_midi_init(struct snd_usb_caiaqdev *dev); 4int snd_usb_caiaq_midi_init(struct snd_usb_caiaqdev *dev);
5void snd_usb_caiaq_midi_handle_input(struct snd_usb_caiaqdev *dev, int port, const char *buf, int len); 5void snd_usb_caiaq_midi_handle_input(struct snd_usb_caiaqdev *dev, int port, const char *buf, int len);
6void snd_usb_caiaq_midi_output_done(struct urb* urb); 6void snd_usb_caiaq_midi_output_done(struct urb *urb);
7 7
8#endif /* CAIAQ_MIDI_H */ 8#endif /* CAIAQ_MIDI_H */
diff --git a/sound/usb/ua101.c b/sound/usb/ua101.c
new file mode 100644
index 000000000000..3d458d3b9962
--- /dev/null
+++ b/sound/usb/ua101.c
@@ -0,0 +1,1387 @@
1/*
2 * Edirol UA-101/UA-1000 driver
3 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
4 *
5 * This driver is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License, version 2.
7 *
8 * This driver is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this driver. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include <linux/init.h>
18#include <linux/module.h>
19#include <linux/slab.h>
20#include <linux/usb.h>
21#include <linux/usb/audio.h>
22#include <sound/core.h>
23#include <sound/initval.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26#include "usbaudio.h"
27
28MODULE_DESCRIPTION("Edirol UA-101/1000 driver");
29MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
30MODULE_LICENSE("GPL v2");
31MODULE_SUPPORTED_DEVICE("{{Edirol,UA-101},{Edirol,UA-1000}}");
32
33/*
34 * Should not be lower than the minimum scheduling delay of the host
35 * controller. Some Intel controllers need more than one frame; as long as
36 * that driver doesn't tell us about this, use 1.5 frames just to be sure.
37 */
38#define MIN_QUEUE_LENGTH 12
39/* Somewhat random. */
40#define MAX_QUEUE_LENGTH 30
41/*
42 * 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 * that usb_buffer_alloc() uses.
45 */
46#define DEFAULT_QUEUE_LENGTH 21
47
48#define MAX_PACKET_SIZE 672 /* hardware specific */
49#define MAX_MEMORY_BUFFERS DIV_ROUND_UP(MAX_QUEUE_LENGTH, \
50 PAGE_SIZE / MAX_PACKET_SIZE)
51
52static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
53static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
54static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
55static unsigned int queue_length = 21;
56
57module_param_array(index, int, NULL, 0444);
58MODULE_PARM_DESC(index, "card index");
59module_param_array(id, charp, NULL, 0444);
60MODULE_PARM_DESC(id, "ID string");
61module_param_array(enable, bool, NULL, 0444);
62MODULE_PARM_DESC(enable, "enable card");
63module_param(queue_length, uint, 0644);
64MODULE_PARM_DESC(queue_length, "USB queue length in microframes, "
65 __stringify(MIN_QUEUE_LENGTH)"-"__stringify(MAX_QUEUE_LENGTH));
66
67enum {
68 INTF_PLAYBACK,
69 INTF_CAPTURE,
70 INTF_MIDI,
71
72 INTF_COUNT
73};
74
75/* bits in struct ua101::states */
76enum {
77 USB_CAPTURE_RUNNING,
78 USB_PLAYBACK_RUNNING,
79 ALSA_CAPTURE_OPEN,
80 ALSA_PLAYBACK_OPEN,
81 ALSA_CAPTURE_RUNNING,
82 ALSA_PLAYBACK_RUNNING,
83 CAPTURE_URB_COMPLETED,
84 PLAYBACK_URB_COMPLETED,
85 DISCONNECTED,
86};
87
88struct ua101 {
89 struct usb_device *dev;
90 struct snd_card *card;
91 struct usb_interface *intf[INTF_COUNT];
92 int card_index;
93 struct snd_pcm *pcm;
94 struct list_head midi_list;
95 u64 format_bit;
96 unsigned int rate;
97 unsigned int packets_per_second;
98 spinlock_t lock;
99 struct mutex mutex;
100 unsigned long states;
101
102 /* FIFO to synchronize playback rate to capture rate */
103 unsigned int rate_feedback_start;
104 unsigned int rate_feedback_count;
105 u8 rate_feedback[MAX_QUEUE_LENGTH];
106
107 struct list_head ready_playback_urbs;
108 struct tasklet_struct playback_tasklet;
109 wait_queue_head_t alsa_capture_wait;
110 wait_queue_head_t rate_feedback_wait;
111 wait_queue_head_t alsa_playback_wait;
112 struct ua101_stream {
113 struct snd_pcm_substream *substream;
114 unsigned int usb_pipe;
115 unsigned int channels;
116 unsigned int frame_bytes;
117 unsigned int max_packet_bytes;
118 unsigned int period_pos;
119 unsigned int buffer_pos;
120 unsigned int queue_length;
121 struct ua101_urb {
122 struct urb urb;
123 struct usb_iso_packet_descriptor iso_frame_desc[1];
124 struct list_head ready_list;
125 } *urbs[MAX_QUEUE_LENGTH];
126 struct {
127 unsigned int size;
128 void *addr;
129 dma_addr_t dma;
130 } buffers[MAX_MEMORY_BUFFERS];
131 } capture, playback;
132};
133
134static DEFINE_MUTEX(devices_mutex);
135static unsigned int devices_used;
136static struct usb_driver ua101_driver;
137
138static void abort_alsa_playback(struct ua101 *ua);
139static void abort_alsa_capture(struct ua101 *ua);
140
141static const char *usb_error_string(int err)
142{
143 switch (err) {
144 case -ENODEV:
145 return "no device";
146 case -ENOENT:
147 return "endpoint not enabled";
148 case -EPIPE:
149 return "endpoint stalled";
150 case -ENOSPC:
151 return "not enough bandwidth";
152 case -ESHUTDOWN:
153 return "device disabled";
154 case -EHOSTUNREACH:
155 return "device suspended";
156 case -EINVAL:
157 case -EAGAIN:
158 case -EFBIG:
159 case -EMSGSIZE:
160 return "internal error";
161 default:
162 return "unknown error";
163 }
164}
165
166static void abort_usb_capture(struct ua101 *ua)
167{
168 if (test_and_clear_bit(USB_CAPTURE_RUNNING, &ua->states)) {
169 wake_up(&ua->alsa_capture_wait);
170 wake_up(&ua->rate_feedback_wait);
171 }
172}
173
174static void abort_usb_playback(struct ua101 *ua)
175{
176 if (test_and_clear_bit(USB_PLAYBACK_RUNNING, &ua->states))
177 wake_up(&ua->alsa_playback_wait);
178}
179
180static void playback_urb_complete(struct urb *usb_urb)
181{
182 struct ua101_urb *urb = (struct ua101_urb *)usb_urb;
183 struct ua101 *ua = urb->urb.context;
184 unsigned long flags;
185
186 if (unlikely(urb->urb.status == -ENOENT || /* unlinked */
187 urb->urb.status == -ENODEV || /* device removed */
188 urb->urb.status == -ECONNRESET || /* unlinked */
189 urb->urb.status == -ESHUTDOWN)) { /* device disabled */
190 abort_usb_playback(ua);
191 abort_alsa_playback(ua);
192 return;
193 }
194
195 if (test_bit(USB_PLAYBACK_RUNNING, &ua->states)) {
196 /* append URB to FIFO */
197 spin_lock_irqsave(&ua->lock, flags);
198 list_add_tail(&urb->ready_list, &ua->ready_playback_urbs);
199 if (ua->rate_feedback_count > 0)
200 tasklet_schedule(&ua->playback_tasklet);
201 ua->playback.substream->runtime->delay -=
202 urb->urb.iso_frame_desc[0].length /
203 ua->playback.frame_bytes;
204 spin_unlock_irqrestore(&ua->lock, flags);
205 }
206}
207
208static void first_playback_urb_complete(struct urb *urb)
209{
210 struct ua101 *ua = urb->context;
211
212 urb->complete = playback_urb_complete;
213 playback_urb_complete(urb);
214
215 set_bit(PLAYBACK_URB_COMPLETED, &ua->states);
216 wake_up(&ua->alsa_playback_wait);
217}
218
219/* copy data from the ALSA ring buffer into the URB buffer */
220static bool copy_playback_data(struct ua101_stream *stream, struct urb *urb,
221 unsigned int frames)
222{
223 struct snd_pcm_runtime *runtime;
224 unsigned int frame_bytes, frames1;
225 const u8 *source;
226
227 runtime = stream->substream->runtime;
228 frame_bytes = stream->frame_bytes;
229 source = runtime->dma_area + stream->buffer_pos * frame_bytes;
230 if (stream->buffer_pos + frames <= runtime->buffer_size) {
231 memcpy(urb->transfer_buffer, source, frames * frame_bytes);
232 } else {
233 /* wrap around at end of ring buffer */
234 frames1 = runtime->buffer_size - stream->buffer_pos;
235 memcpy(urb->transfer_buffer, source, frames1 * frame_bytes);
236 memcpy(urb->transfer_buffer + frames1 * frame_bytes,
237 runtime->dma_area, (frames - frames1) * frame_bytes);
238 }
239
240 stream->buffer_pos += frames;
241 if (stream->buffer_pos >= runtime->buffer_size)
242 stream->buffer_pos -= runtime->buffer_size;
243 stream->period_pos += frames;
244 if (stream->period_pos >= runtime->period_size) {
245 stream->period_pos -= runtime->period_size;
246 return true;
247 }
248 return false;
249}
250
251static inline void add_with_wraparound(struct ua101 *ua,
252 unsigned int *value, unsigned int add)
253{
254 *value += add;
255 if (*value >= ua->playback.queue_length)
256 *value -= ua->playback.queue_length;
257}
258
259static void playback_tasklet(unsigned long data)
260{
261 struct ua101 *ua = (void *)data;
262 unsigned long flags;
263 unsigned int frames;
264 struct ua101_urb *urb;
265 bool do_period_elapsed = false;
266 int err;
267
268 if (unlikely(!test_bit(USB_PLAYBACK_RUNNING, &ua->states)))
269 return;
270
271 /*
272 * Synchronizing the playback rate to the capture rate is done by using
273 * the same sequence of packet sizes for both streams.
274 * Submitting a playback URB therefore requires both a ready URB and
275 * the size of the corresponding capture packet, i.e., both playback
276 * and capture URBs must have been completed. Since the USB core does
277 * not guarantee that playback and capture complete callbacks are
278 * called alternately, we use two FIFOs for packet sizes and read URBs;
279 * submitting playback URBs is possible as long as both FIFOs are
280 * nonempty.
281 */
282 spin_lock_irqsave(&ua->lock, flags);
283 while (ua->rate_feedback_count > 0 &&
284 !list_empty(&ua->ready_playback_urbs)) {
285 /* take packet size out of FIFO */
286 frames = ua->rate_feedback[ua->rate_feedback_start];
287 add_with_wraparound(ua, &ua->rate_feedback_start, 1);
288 ua->rate_feedback_count--;
289
290 /* take URB out of FIFO */
291 urb = list_first_entry(&ua->ready_playback_urbs,
292 struct ua101_urb, ready_list);
293 list_del(&urb->ready_list);
294
295 /* fill packet with data or silence */
296 urb->urb.iso_frame_desc[0].length =
297 frames * ua->playback.frame_bytes;
298 if (test_bit(ALSA_PLAYBACK_RUNNING, &ua->states))
299 do_period_elapsed |= copy_playback_data(&ua->playback,
300 &urb->urb,
301 frames);
302 else
303 memset(urb->urb.transfer_buffer, 0,
304 urb->urb.iso_frame_desc[0].length);
305
306 /* and off you go ... */
307 err = usb_submit_urb(&urb->urb, GFP_ATOMIC);
308 if (unlikely(err < 0)) {
309 spin_unlock_irqrestore(&ua->lock, flags);
310 abort_usb_playback(ua);
311 abort_alsa_playback(ua);
312 dev_err(&ua->dev->dev, "USB request error %d: %s\n",
313 err, usb_error_string(err));
314 return;
315 }
316 ua->playback.substream->runtime->delay += frames;
317 }
318 spin_unlock_irqrestore(&ua->lock, flags);
319 if (do_period_elapsed)
320 snd_pcm_period_elapsed(ua->playback.substream);
321}
322
323/* copy data from the URB buffer into the ALSA ring buffer */
324static bool copy_capture_data(struct ua101_stream *stream, struct urb *urb,
325 unsigned int frames)
326{
327 struct snd_pcm_runtime *runtime;
328 unsigned int frame_bytes, frames1;
329 u8 *dest;
330
331 runtime = stream->substream->runtime;
332 frame_bytes = stream->frame_bytes;
333 dest = runtime->dma_area + stream->buffer_pos * frame_bytes;
334 if (stream->buffer_pos + frames <= runtime->buffer_size) {
335 memcpy(dest, urb->transfer_buffer, frames * frame_bytes);
336 } else {
337 /* wrap around at end of ring buffer */
338 frames1 = runtime->buffer_size - stream->buffer_pos;
339 memcpy(dest, urb->transfer_buffer, frames1 * frame_bytes);
340 memcpy(runtime->dma_area,
341 urb->transfer_buffer + frames1 * frame_bytes,
342 (frames - frames1) * frame_bytes);
343 }
344
345 stream->buffer_pos += frames;
346 if (stream->buffer_pos >= runtime->buffer_size)
347 stream->buffer_pos -= runtime->buffer_size;
348 stream->period_pos += frames;
349 if (stream->period_pos >= runtime->period_size) {
350 stream->period_pos -= runtime->period_size;
351 return true;
352 }
353 return false;
354}
355
356static void capture_urb_complete(struct urb *urb)
357{
358 struct ua101 *ua = urb->context;
359 struct ua101_stream *stream = &ua->capture;
360 unsigned long flags;
361 unsigned int frames, write_ptr;
362 bool do_period_elapsed;
363 int err;
364
365 if (unlikely(urb->status == -ENOENT || /* unlinked */
366 urb->status == -ENODEV || /* device removed */
367 urb->status == -ECONNRESET || /* unlinked */
368 urb->status == -ESHUTDOWN)) /* device disabled */
369 goto stream_stopped;
370
371 if (urb->status >= 0 && urb->iso_frame_desc[0].status >= 0)
372 frames = urb->iso_frame_desc[0].actual_length /
373 stream->frame_bytes;
374 else
375 frames = 0;
376
377 spin_lock_irqsave(&ua->lock, flags);
378
379 if (frames > 0 && test_bit(ALSA_CAPTURE_RUNNING, &ua->states))
380 do_period_elapsed = copy_capture_data(stream, urb, frames);
381 else
382 do_period_elapsed = false;
383
384 if (test_bit(USB_CAPTURE_RUNNING, &ua->states)) {
385 err = usb_submit_urb(urb, GFP_ATOMIC);
386 if (unlikely(err < 0)) {
387 spin_unlock_irqrestore(&ua->lock, flags);
388 dev_err(&ua->dev->dev, "USB request error %d: %s\n",
389 err, usb_error_string(err));
390 goto stream_stopped;
391 }
392
393 /* append packet size to FIFO */
394 write_ptr = ua->rate_feedback_start;
395 add_with_wraparound(ua, &write_ptr, ua->rate_feedback_count);
396 ua->rate_feedback[write_ptr] = frames;
397 if (ua->rate_feedback_count < ua->playback.queue_length) {
398 ua->rate_feedback_count++;
399 if (ua->rate_feedback_count ==
400 ua->playback.queue_length)
401 wake_up(&ua->rate_feedback_wait);
402 } else {
403 /*
404 * Ring buffer overflow; this happens when the playback
405 * stream is not running. Throw away the oldest entry,
406 * so that the playback stream, when it starts, sees
407 * the most recent packet sizes.
408 */
409 add_with_wraparound(ua, &ua->rate_feedback_start, 1);
410 }
411 if (test_bit(USB_PLAYBACK_RUNNING, &ua->states) &&
412 !list_empty(&ua->ready_playback_urbs))
413 tasklet_schedule(&ua->playback_tasklet);
414 }
415
416 spin_unlock_irqrestore(&ua->lock, flags);
417
418 if (do_period_elapsed)
419 snd_pcm_period_elapsed(stream->substream);
420
421 return;
422
423stream_stopped:
424 abort_usb_playback(ua);
425 abort_usb_capture(ua);
426 abort_alsa_playback(ua);
427 abort_alsa_capture(ua);
428}
429
430static void first_capture_urb_complete(struct urb *urb)
431{
432 struct ua101 *ua = urb->context;
433
434 urb->complete = capture_urb_complete;
435 capture_urb_complete(urb);
436
437 set_bit(CAPTURE_URB_COMPLETED, &ua->states);
438 wake_up(&ua->alsa_capture_wait);
439}
440
441static int submit_stream_urbs(struct ua101 *ua, struct ua101_stream *stream)
442{
443 unsigned int i;
444
445 for (i = 0; i < stream->queue_length; ++i) {
446 int err = usb_submit_urb(&stream->urbs[i]->urb, GFP_KERNEL);
447 if (err < 0) {
448 dev_err(&ua->dev->dev, "USB request error %d: %s\n",
449 err, usb_error_string(err));
450 return err;
451 }
452 }
453 return 0;
454}
455
456static void kill_stream_urbs(struct ua101_stream *stream)
457{
458 unsigned int i;
459
460 for (i = 0; i < stream->queue_length; ++i)
461 usb_kill_urb(&stream->urbs[i]->urb);
462}
463
464static int enable_iso_interface(struct ua101 *ua, unsigned int intf_index)
465{
466 struct usb_host_interface *alts;
467
468 alts = ua->intf[intf_index]->cur_altsetting;
469 if (alts->desc.bAlternateSetting != 1) {
470 int err = usb_set_interface(ua->dev,
471 alts->desc.bInterfaceNumber, 1);
472 if (err < 0) {
473 dev_err(&ua->dev->dev,
474 "cannot initialize interface; error %d: %s\n",
475 err, usb_error_string(err));
476 return err;
477 }
478 }
479 return 0;
480}
481
482static void disable_iso_interface(struct ua101 *ua, unsigned int intf_index)
483{
484 struct usb_host_interface *alts;
485
486 alts = ua->intf[intf_index]->cur_altsetting;
487 if (alts->desc.bAlternateSetting != 0) {
488 int err = usb_set_interface(ua->dev,
489 alts->desc.bInterfaceNumber, 0);
490 if (err < 0 && !test_bit(DISCONNECTED, &ua->states))
491 dev_warn(&ua->dev->dev,
492 "interface reset failed; error %d: %s\n",
493 err, usb_error_string(err));
494 }
495}
496
497static void stop_usb_capture(struct ua101 *ua)
498{
499 clear_bit(USB_CAPTURE_RUNNING, &ua->states);
500
501 kill_stream_urbs(&ua->capture);
502
503 disable_iso_interface(ua, INTF_CAPTURE);
504}
505
506static int start_usb_capture(struct ua101 *ua)
507{
508 int err;
509
510 if (test_bit(DISCONNECTED, &ua->states))
511 return -ENODEV;
512
513 if (test_bit(USB_CAPTURE_RUNNING, &ua->states))
514 return 0;
515
516 kill_stream_urbs(&ua->capture);
517
518 err = enable_iso_interface(ua, INTF_CAPTURE);
519 if (err < 0)
520 return err;
521
522 clear_bit(CAPTURE_URB_COMPLETED, &ua->states);
523 ua->capture.urbs[0]->urb.complete = first_capture_urb_complete;
524 ua->rate_feedback_start = 0;
525 ua->rate_feedback_count = 0;
526
527 set_bit(USB_CAPTURE_RUNNING, &ua->states);
528 err = submit_stream_urbs(ua, &ua->capture);
529 if (err < 0)
530 stop_usb_capture(ua);
531 return err;
532}
533
534static void stop_usb_playback(struct ua101 *ua)
535{
536 clear_bit(USB_PLAYBACK_RUNNING, &ua->states);
537
538 kill_stream_urbs(&ua->playback);
539
540 tasklet_kill(&ua->playback_tasklet);
541
542 disable_iso_interface(ua, INTF_PLAYBACK);
543}
544
545static int start_usb_playback(struct ua101 *ua)
546{
547 unsigned int i, frames;
548 struct urb *urb;
549 int err = 0;
550
551 if (test_bit(DISCONNECTED, &ua->states))
552 return -ENODEV;
553
554 if (test_bit(USB_PLAYBACK_RUNNING, &ua->states))
555 return 0;
556
557 kill_stream_urbs(&ua->playback);
558 tasklet_kill(&ua->playback_tasklet);
559
560 err = enable_iso_interface(ua, INTF_PLAYBACK);
561 if (err < 0)
562 return err;
563
564 clear_bit(PLAYBACK_URB_COMPLETED, &ua->states);
565 ua->playback.urbs[0]->urb.complete =
566 first_playback_urb_complete;
567 spin_lock_irq(&ua->lock);
568 INIT_LIST_HEAD(&ua->ready_playback_urbs);
569 spin_unlock_irq(&ua->lock);
570
571 /*
572 * We submit the initial URBs all at once, so we have to wait for the
573 * packet size FIFO to be full.
574 */
575 wait_event(ua->rate_feedback_wait,
576 ua->rate_feedback_count >= ua->playback.queue_length ||
577 !test_bit(USB_CAPTURE_RUNNING, &ua->states) ||
578 test_bit(DISCONNECTED, &ua->states));
579 if (test_bit(DISCONNECTED, &ua->states)) {
580 stop_usb_playback(ua);
581 return -ENODEV;
582 }
583 if (!test_bit(USB_CAPTURE_RUNNING, &ua->states)) {
584 stop_usb_playback(ua);
585 return -EIO;
586 }
587
588 for (i = 0; i < ua->playback.queue_length; ++i) {
589 /* all initial URBs contain silence */
590 spin_lock_irq(&ua->lock);
591 frames = ua->rate_feedback[ua->rate_feedback_start];
592 add_with_wraparound(ua, &ua->rate_feedback_start, 1);
593 ua->rate_feedback_count--;
594 spin_unlock_irq(&ua->lock);
595 urb = &ua->playback.urbs[i]->urb;
596 urb->iso_frame_desc[0].length =
597 frames * ua->playback.frame_bytes;
598 memset(urb->transfer_buffer, 0,
599 urb->iso_frame_desc[0].length);
600 }
601
602 set_bit(USB_PLAYBACK_RUNNING, &ua->states);
603 err = submit_stream_urbs(ua, &ua->playback);
604 if (err < 0)
605 stop_usb_playback(ua);
606 return err;
607}
608
609static void abort_alsa_capture(struct ua101 *ua)
610{
611 if (test_bit(ALSA_CAPTURE_RUNNING, &ua->states))
612 snd_pcm_stop(ua->capture.substream, SNDRV_PCM_STATE_XRUN);
613}
614
615static void abort_alsa_playback(struct ua101 *ua)
616{
617 if (test_bit(ALSA_PLAYBACK_RUNNING, &ua->states))
618 snd_pcm_stop(ua->playback.substream, SNDRV_PCM_STATE_XRUN);
619}
620
621static int set_stream_hw(struct ua101 *ua, struct snd_pcm_substream *substream,
622 unsigned int channels)
623{
624 int err;
625
626 substream->runtime->hw.info =
627 SNDRV_PCM_INFO_MMAP |
628 SNDRV_PCM_INFO_MMAP_VALID |
629 SNDRV_PCM_INFO_BATCH |
630 SNDRV_PCM_INFO_INTERLEAVED |
631 SNDRV_PCM_INFO_BLOCK_TRANSFER |
632 SNDRV_PCM_INFO_FIFO_IN_FRAMES;
633 substream->runtime->hw.formats = ua->format_bit;
634 substream->runtime->hw.rates = snd_pcm_rate_to_rate_bit(ua->rate);
635 substream->runtime->hw.rate_min = ua->rate;
636 substream->runtime->hw.rate_max = ua->rate;
637 substream->runtime->hw.channels_min = channels;
638 substream->runtime->hw.channels_max = channels;
639 substream->runtime->hw.buffer_bytes_max = 45000 * 1024;
640 substream->runtime->hw.period_bytes_min = 1;
641 substream->runtime->hw.period_bytes_max = UINT_MAX;
642 substream->runtime->hw.periods_min = 2;
643 substream->runtime->hw.periods_max = UINT_MAX;
644 err = snd_pcm_hw_constraint_minmax(substream->runtime,
645 SNDRV_PCM_HW_PARAM_PERIOD_TIME,
646 1500000 / ua->packets_per_second,
647 8192000);
648 if (err < 0)
649 return err;
650 err = snd_pcm_hw_constraint_msbits(substream->runtime, 0, 32, 24);
651 return err;
652}
653
654static int capture_pcm_open(struct snd_pcm_substream *substream)
655{
656 struct ua101 *ua = substream->private_data;
657 int err;
658
659 ua->capture.substream = substream;
660 err = set_stream_hw(ua, substream, ua->capture.channels);
661 if (err < 0)
662 return err;
663 substream->runtime->hw.fifo_size =
664 DIV_ROUND_CLOSEST(ua->rate, ua->packets_per_second);
665 substream->runtime->delay = substream->runtime->hw.fifo_size;
666
667 mutex_lock(&ua->mutex);
668 err = start_usb_capture(ua);
669 if (err >= 0)
670 set_bit(ALSA_CAPTURE_OPEN, &ua->states);
671 mutex_unlock(&ua->mutex);
672 return err;
673}
674
675static int playback_pcm_open(struct snd_pcm_substream *substream)
676{
677 struct ua101 *ua = substream->private_data;
678 int err;
679
680 ua->playback.substream = substream;
681 err = set_stream_hw(ua, substream, ua->playback.channels);
682 if (err < 0)
683 return err;
684 substream->runtime->hw.fifo_size =
685 DIV_ROUND_CLOSEST(ua->rate * ua->playback.queue_length,
686 ua->packets_per_second);
687
688 mutex_lock(&ua->mutex);
689 err = start_usb_capture(ua);
690 if (err < 0)
691 goto error;
692 err = start_usb_playback(ua);
693 if (err < 0) {
694 if (!test_bit(ALSA_CAPTURE_OPEN, &ua->states))
695 stop_usb_capture(ua);
696 goto error;
697 }
698 set_bit(ALSA_PLAYBACK_OPEN, &ua->states);
699error:
700 mutex_unlock(&ua->mutex);
701 return err;
702}
703
704static int capture_pcm_close(struct snd_pcm_substream *substream)
705{
706 struct ua101 *ua = substream->private_data;
707
708 mutex_lock(&ua->mutex);
709 clear_bit(ALSA_CAPTURE_OPEN, &ua->states);
710 if (!test_bit(ALSA_PLAYBACK_OPEN, &ua->states))
711 stop_usb_capture(ua);
712 mutex_unlock(&ua->mutex);
713 return 0;
714}
715
716static int playback_pcm_close(struct snd_pcm_substream *substream)
717{
718 struct ua101 *ua = substream->private_data;
719
720 mutex_lock(&ua->mutex);
721 stop_usb_playback(ua);
722 clear_bit(ALSA_PLAYBACK_OPEN, &ua->states);
723 if (!test_bit(ALSA_CAPTURE_OPEN, &ua->states))
724 stop_usb_capture(ua);
725 mutex_unlock(&ua->mutex);
726 return 0;
727}
728
729static int capture_pcm_hw_params(struct snd_pcm_substream *substream,
730 struct snd_pcm_hw_params *hw_params)
731{
732 struct ua101 *ua = substream->private_data;
733 int err;
734
735 mutex_lock(&ua->mutex);
736 err = start_usb_capture(ua);
737 mutex_unlock(&ua->mutex);
738 if (err < 0)
739 return err;
740
741 return snd_pcm_lib_alloc_vmalloc_buffer(substream,
742 params_buffer_bytes(hw_params));
743}
744
745static int playback_pcm_hw_params(struct snd_pcm_substream *substream,
746 struct snd_pcm_hw_params *hw_params)
747{
748 struct ua101 *ua = substream->private_data;
749 int err;
750
751 mutex_lock(&ua->mutex);
752 err = start_usb_capture(ua);
753 if (err >= 0)
754 err = start_usb_playback(ua);
755 mutex_unlock(&ua->mutex);
756 if (err < 0)
757 return err;
758
759 return snd_pcm_lib_alloc_vmalloc_buffer(substream,
760 params_buffer_bytes(hw_params));
761}
762
763static int ua101_pcm_hw_free(struct snd_pcm_substream *substream)
764{
765 return snd_pcm_lib_free_vmalloc_buffer(substream);
766}
767
768static int capture_pcm_prepare(struct snd_pcm_substream *substream)
769{
770 struct ua101 *ua = substream->private_data;
771 int err;
772
773 mutex_lock(&ua->mutex);
774 err = start_usb_capture(ua);
775 mutex_unlock(&ua->mutex);
776 if (err < 0)
777 return err;
778
779 /*
780 * The EHCI driver schedules the first packet of an iso stream at 10 ms
781 * in the future, i.e., no data is actually captured for that long.
782 * Take the wait here so that the stream is known to be actually
783 * running when the start trigger has been called.
784 */
785 wait_event(ua->alsa_capture_wait,
786 test_bit(CAPTURE_URB_COMPLETED, &ua->states) ||
787 !test_bit(USB_CAPTURE_RUNNING, &ua->states));
788 if (test_bit(DISCONNECTED, &ua->states))
789 return -ENODEV;
790 if (!test_bit(USB_CAPTURE_RUNNING, &ua->states))
791 return -EIO;
792
793 ua->capture.period_pos = 0;
794 ua->capture.buffer_pos = 0;
795 return 0;
796}
797
798static int playback_pcm_prepare(struct snd_pcm_substream *substream)
799{
800 struct ua101 *ua = substream->private_data;
801 int err;
802
803 mutex_lock(&ua->mutex);
804 err = start_usb_capture(ua);
805 if (err >= 0)
806 err = start_usb_playback(ua);
807 mutex_unlock(&ua->mutex);
808 if (err < 0)
809 return err;
810
811 /* see the comment in capture_pcm_prepare() */
812 wait_event(ua->alsa_playback_wait,
813 test_bit(PLAYBACK_URB_COMPLETED, &ua->states) ||
814 !test_bit(USB_PLAYBACK_RUNNING, &ua->states));
815 if (test_bit(DISCONNECTED, &ua->states))
816 return -ENODEV;
817 if (!test_bit(USB_PLAYBACK_RUNNING, &ua->states))
818 return -EIO;
819
820 substream->runtime->delay = 0;
821 ua->playback.period_pos = 0;
822 ua->playback.buffer_pos = 0;
823 return 0;
824}
825
826static int capture_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
827{
828 struct ua101 *ua = substream->private_data;
829
830 switch (cmd) {
831 case SNDRV_PCM_TRIGGER_START:
832 if (!test_bit(USB_CAPTURE_RUNNING, &ua->states))
833 return -EIO;
834 set_bit(ALSA_CAPTURE_RUNNING, &ua->states);
835 return 0;
836 case SNDRV_PCM_TRIGGER_STOP:
837 clear_bit(ALSA_CAPTURE_RUNNING, &ua->states);
838 return 0;
839 default:
840 return -EINVAL;
841 }
842}
843
844static int playback_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
845{
846 struct ua101 *ua = substream->private_data;
847
848 switch (cmd) {
849 case SNDRV_PCM_TRIGGER_START:
850 if (!test_bit(USB_PLAYBACK_RUNNING, &ua->states))
851 return -EIO;
852 set_bit(ALSA_PLAYBACK_RUNNING, &ua->states);
853 return 0;
854 case SNDRV_PCM_TRIGGER_STOP:
855 clear_bit(ALSA_PLAYBACK_RUNNING, &ua->states);
856 return 0;
857 default:
858 return -EINVAL;
859 }
860}
861
862static inline snd_pcm_uframes_t ua101_pcm_pointer(struct ua101 *ua,
863 struct ua101_stream *stream)
864{
865 unsigned long flags;
866 unsigned int pos;
867
868 spin_lock_irqsave(&ua->lock, flags);
869 pos = stream->buffer_pos;
870 spin_unlock_irqrestore(&ua->lock, flags);
871 return pos;
872}
873
874static snd_pcm_uframes_t capture_pcm_pointer(struct snd_pcm_substream *subs)
875{
876 struct ua101 *ua = subs->private_data;
877
878 return ua101_pcm_pointer(ua, &ua->capture);
879}
880
881static snd_pcm_uframes_t playback_pcm_pointer(struct snd_pcm_substream *subs)
882{
883 struct ua101 *ua = subs->private_data;
884
885 return ua101_pcm_pointer(ua, &ua->playback);
886}
887
888static struct snd_pcm_ops capture_pcm_ops = {
889 .open = capture_pcm_open,
890 .close = capture_pcm_close,
891 .ioctl = snd_pcm_lib_ioctl,
892 .hw_params = capture_pcm_hw_params,
893 .hw_free = ua101_pcm_hw_free,
894 .prepare = capture_pcm_prepare,
895 .trigger = capture_pcm_trigger,
896 .pointer = capture_pcm_pointer,
897 .page = snd_pcm_lib_get_vmalloc_page,
898 .mmap = snd_pcm_lib_mmap_vmalloc,
899};
900
901static struct snd_pcm_ops playback_pcm_ops = {
902 .open = playback_pcm_open,
903 .close = playback_pcm_close,
904 .ioctl = snd_pcm_lib_ioctl,
905 .hw_params = playback_pcm_hw_params,
906 .hw_free = ua101_pcm_hw_free,
907 .prepare = playback_pcm_prepare,
908 .trigger = playback_pcm_trigger,
909 .pointer = playback_pcm_pointer,
910 .page = snd_pcm_lib_get_vmalloc_page,
911 .mmap = snd_pcm_lib_mmap_vmalloc,
912};
913
914static const struct uac_format_type_i_discrete_descriptor *
915find_format_descriptor(struct usb_interface *interface)
916{
917 struct usb_host_interface *alt;
918 u8 *extra;
919 int extralen;
920
921 if (interface->num_altsetting != 2) {
922 dev_err(&interface->dev, "invalid num_altsetting\n");
923 return NULL;
924 }
925
926 alt = &interface->altsetting[0];
927 if (alt->desc.bNumEndpoints != 0) {
928 dev_err(&interface->dev, "invalid bNumEndpoints\n");
929 return NULL;
930 }
931
932 alt = &interface->altsetting[1];
933 if (alt->desc.bNumEndpoints != 1) {
934 dev_err(&interface->dev, "invalid bNumEndpoints\n");
935 return NULL;
936 }
937
938 extra = alt->extra;
939 extralen = alt->extralen;
940 while (extralen >= sizeof(struct usb_descriptor_header)) {
941 struct uac_format_type_i_discrete_descriptor *desc;
942
943 desc = (struct uac_format_type_i_discrete_descriptor *)extra;
944 if (desc->bLength > extralen) {
945 dev_err(&interface->dev, "descriptor overflow\n");
946 return NULL;
947 }
948 if (desc->bLength == UAC_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(1) &&
949 desc->bDescriptorType == USB_DT_CS_INTERFACE &&
950 desc->bDescriptorSubtype == UAC_FORMAT_TYPE) {
951 if (desc->bFormatType != UAC_FORMAT_TYPE_I_PCM ||
952 desc->bSamFreqType != 1) {
953 dev_err(&interface->dev,
954 "invalid format type\n");
955 return NULL;
956 }
957 return desc;
958 }
959 extralen -= desc->bLength;
960 extra += desc->bLength;
961 }
962 dev_err(&interface->dev, "sample format descriptor not found\n");
963 return NULL;
964}
965
966static int detect_usb_format(struct ua101 *ua)
967{
968 const struct uac_format_type_i_discrete_descriptor *fmt_capture;
969 const struct uac_format_type_i_discrete_descriptor *fmt_playback;
970 const struct usb_endpoint_descriptor *epd;
971 unsigned int rate2;
972
973 fmt_capture = find_format_descriptor(ua->intf[INTF_CAPTURE]);
974 fmt_playback = find_format_descriptor(ua->intf[INTF_PLAYBACK]);
975 if (!fmt_capture || !fmt_playback)
976 return -ENXIO;
977
978 switch (fmt_capture->bSubframeSize) {
979 case 3:
980 ua->format_bit = SNDRV_PCM_FMTBIT_S24_3LE;
981 break;
982 case 4:
983 ua->format_bit = SNDRV_PCM_FMTBIT_S32_LE;
984 break;
985 default:
986 dev_err(&ua->dev->dev, "sample width is not 24 or 32 bits\n");
987 return -ENXIO;
988 }
989 if (fmt_capture->bSubframeSize != fmt_playback->bSubframeSize) {
990 dev_err(&ua->dev->dev,
991 "playback/capture sample widths do not match\n");
992 return -ENXIO;
993 }
994
995 if (fmt_capture->bBitResolution != 24 ||
996 fmt_playback->bBitResolution != 24) {
997 dev_err(&ua->dev->dev, "sample width is not 24 bits\n");
998 return -ENXIO;
999 }
1000
1001 ua->rate = combine_triple(fmt_capture->tSamFreq[0]);
1002 rate2 = combine_triple(fmt_playback->tSamFreq[0]);
1003 if (ua->rate != rate2) {
1004 dev_err(&ua->dev->dev,
1005 "playback/capture rates do not match: %u/%u\n",
1006 rate2, ua->rate);
1007 return -ENXIO;
1008 }
1009
1010 switch (ua->dev->speed) {
1011 case USB_SPEED_FULL:
1012 ua->packets_per_second = 1000;
1013 break;
1014 case USB_SPEED_HIGH:
1015 ua->packets_per_second = 8000;
1016 break;
1017 default:
1018 dev_err(&ua->dev->dev, "unknown device speed\n");
1019 return -ENXIO;
1020 }
1021
1022 ua->capture.channels = fmt_capture->bNrChannels;
1023 ua->playback.channels = fmt_playback->bNrChannels;
1024 ua->capture.frame_bytes =
1025 fmt_capture->bSubframeSize * ua->capture.channels;
1026 ua->playback.frame_bytes =
1027 fmt_playback->bSubframeSize * ua->playback.channels;
1028
1029 epd = &ua->intf[INTF_CAPTURE]->altsetting[1].endpoint[0].desc;
1030 if (!usb_endpoint_is_isoc_in(epd)) {
1031 dev_err(&ua->dev->dev, "invalid capture endpoint\n");
1032 return -ENXIO;
1033 }
1034 ua->capture.usb_pipe = usb_rcvisocpipe(ua->dev, usb_endpoint_num(epd));
1035 ua->capture.max_packet_bytes = le16_to_cpu(epd->wMaxPacketSize);
1036
1037 epd = &ua->intf[INTF_PLAYBACK]->altsetting[1].endpoint[0].desc;
1038 if (!usb_endpoint_is_isoc_out(epd)) {
1039 dev_err(&ua->dev->dev, "invalid playback endpoint\n");
1040 return -ENXIO;
1041 }
1042 ua->playback.usb_pipe = usb_sndisocpipe(ua->dev, usb_endpoint_num(epd));
1043 ua->playback.max_packet_bytes = le16_to_cpu(epd->wMaxPacketSize);
1044 return 0;
1045}
1046
1047static int alloc_stream_buffers(struct ua101 *ua, struct ua101_stream *stream)
1048{
1049 unsigned int remaining_packets, packets, packets_per_page, i;
1050 size_t size;
1051
1052 stream->queue_length = queue_length;
1053 stream->queue_length = max(stream->queue_length,
1054 (unsigned int)MIN_QUEUE_LENGTH);
1055 stream->queue_length = min(stream->queue_length,
1056 (unsigned int)MAX_QUEUE_LENGTH);
1057
1058 /*
1059 * The cache pool sizes used by usb_buffer_alloc() (128, 512, 2048) are
1060 * 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 * a smaller buffer only for the last chunk.
1063 */
1064 remaining_packets = stream->queue_length;
1065 packets_per_page = PAGE_SIZE / stream->max_packet_bytes;
1066 for (i = 0; i < ARRAY_SIZE(stream->buffers); ++i) {
1067 packets = min(remaining_packets, packets_per_page);
1068 size = packets * stream->max_packet_bytes;
1069 stream->buffers[i].addr =
1070 usb_buffer_alloc(ua->dev, size, GFP_KERNEL,
1071 &stream->buffers[i].dma);
1072 if (!stream->buffers[i].addr)
1073 return -ENOMEM;
1074 stream->buffers[i].size = size;
1075 remaining_packets -= packets;
1076 if (!remaining_packets)
1077 break;
1078 }
1079 if (remaining_packets) {
1080 dev_err(&ua->dev->dev, "too many packets\n");
1081 return -ENXIO;
1082 }
1083 return 0;
1084}
1085
1086static void free_stream_buffers(struct ua101 *ua, struct ua101_stream *stream)
1087{
1088 unsigned int i;
1089
1090 for (i = 0; i < ARRAY_SIZE(stream->buffers); ++i)
1091 usb_buffer_free(ua->dev,
1092 stream->buffers[i].size,
1093 stream->buffers[i].addr,
1094 stream->buffers[i].dma);
1095}
1096
1097static int alloc_stream_urbs(struct ua101 *ua, struct ua101_stream *stream,
1098 void (*urb_complete)(struct urb *))
1099{
1100 unsigned max_packet_size = stream->max_packet_bytes;
1101 struct ua101_urb *urb;
1102 unsigned int b, u = 0;
1103
1104 for (b = 0; b < ARRAY_SIZE(stream->buffers); ++b) {
1105 unsigned int size = stream->buffers[b].size;
1106 u8 *addr = stream->buffers[b].addr;
1107 dma_addr_t dma = stream->buffers[b].dma;
1108
1109 while (size >= max_packet_size) {
1110 if (u >= stream->queue_length)
1111 goto bufsize_error;
1112 urb = kmalloc(sizeof(*urb), GFP_KERNEL);
1113 if (!urb)
1114 return -ENOMEM;
1115 usb_init_urb(&urb->urb);
1116 urb->urb.dev = ua->dev;
1117 urb->urb.pipe = stream->usb_pipe;
1118 urb->urb.transfer_flags = URB_ISO_ASAP |
1119 URB_NO_TRANSFER_DMA_MAP;
1120 urb->urb.transfer_buffer = addr;
1121 urb->urb.transfer_dma = dma;
1122 urb->urb.transfer_buffer_length = max_packet_size;
1123 urb->urb.number_of_packets = 1;
1124 urb->urb.interval = 1;
1125 urb->urb.context = ua;
1126 urb->urb.complete = urb_complete;
1127 urb->urb.iso_frame_desc[0].offset = 0;
1128 urb->urb.iso_frame_desc[0].length = max_packet_size;
1129 stream->urbs[u++] = urb;
1130 size -= max_packet_size;
1131 addr += max_packet_size;
1132 dma += max_packet_size;
1133 }
1134 }
1135 if (u == stream->queue_length)
1136 return 0;
1137bufsize_error:
1138 dev_err(&ua->dev->dev, "internal buffer size error\n");
1139 return -ENXIO;
1140}
1141
1142static void free_stream_urbs(struct ua101_stream *stream)
1143{
1144 unsigned int i;
1145
1146 for (i = 0; i < stream->queue_length; ++i)
1147 kfree(stream->urbs[i]);
1148}
1149
1150static void free_usb_related_resources(struct ua101 *ua,
1151 struct usb_interface *interface)
1152{
1153 unsigned int i;
1154
1155 free_stream_urbs(&ua->capture);
1156 free_stream_urbs(&ua->playback);
1157 free_stream_buffers(ua, &ua->capture);
1158 free_stream_buffers(ua, &ua->playback);
1159
1160 for (i = 0; i < ARRAY_SIZE(ua->intf); ++i)
1161 if (ua->intf[i]) {
1162 usb_set_intfdata(ua->intf[i], NULL);
1163 if (ua->intf[i] != interface)
1164 usb_driver_release_interface(&ua101_driver,
1165 ua->intf[i]);
1166 }
1167}
1168
1169static void ua101_card_free(struct snd_card *card)
1170{
1171 struct ua101 *ua = card->private_data;
1172
1173 mutex_destroy(&ua->mutex);
1174}
1175
1176static int ua101_probe(struct usb_interface *interface,
1177 const struct usb_device_id *usb_id)
1178{
1179 static const struct snd_usb_midi_endpoint_info midi_ep = {
1180 .out_cables = 0x0001,
1181 .in_cables = 0x0001
1182 };
1183 static const struct snd_usb_audio_quirk midi_quirk = {
1184 .type = QUIRK_MIDI_FIXED_ENDPOINT,
1185 .data = &midi_ep
1186 };
1187 static const int intf_numbers[2][3] = {
1188 { /* UA-101 */
1189 [INTF_PLAYBACK] = 0,
1190 [INTF_CAPTURE] = 1,
1191 [INTF_MIDI] = 2,
1192 },
1193 { /* UA-1000 */
1194 [INTF_CAPTURE] = 1,
1195 [INTF_PLAYBACK] = 2,
1196 [INTF_MIDI] = 3,
1197 },
1198 };
1199 struct snd_card *card;
1200 struct ua101 *ua;
1201 unsigned int card_index, i;
1202 int is_ua1000;
1203 const char *name;
1204 char usb_path[32];
1205 int err;
1206
1207 is_ua1000 = usb_id->idProduct == 0x0044;
1208
1209 if (interface->altsetting->desc.bInterfaceNumber !=
1210 intf_numbers[is_ua1000][0])
1211 return -ENODEV;
1212
1213 mutex_lock(&devices_mutex);
1214
1215 for (card_index = 0; card_index < SNDRV_CARDS; ++card_index)
1216 if (enable[card_index] && !(devices_used & (1 << card_index)))
1217 break;
1218 if (card_index >= SNDRV_CARDS) {
1219 mutex_unlock(&devices_mutex);
1220 return -ENOENT;
1221 }
1222 err = snd_card_create(index[card_index], id[card_index], THIS_MODULE,
1223 sizeof(*ua), &card);
1224 if (err < 0) {
1225 mutex_unlock(&devices_mutex);
1226 return err;
1227 }
1228 card->private_free = ua101_card_free;
1229 ua = card->private_data;
1230 ua->dev = interface_to_usbdev(interface);
1231 ua->card = card;
1232 ua->card_index = card_index;
1233 INIT_LIST_HEAD(&ua->midi_list);
1234 spin_lock_init(&ua->lock);
1235 mutex_init(&ua->mutex);
1236 INIT_LIST_HEAD(&ua->ready_playback_urbs);
1237 tasklet_init(&ua->playback_tasklet,
1238 playback_tasklet, (unsigned long)ua);
1239 init_waitqueue_head(&ua->alsa_capture_wait);
1240 init_waitqueue_head(&ua->rate_feedback_wait);
1241 init_waitqueue_head(&ua->alsa_playback_wait);
1242
1243 ua->intf[0] = interface;
1244 for (i = 1; i < ARRAY_SIZE(ua->intf); ++i) {
1245 ua->intf[i] = usb_ifnum_to_if(ua->dev,
1246 intf_numbers[is_ua1000][i]);
1247 if (!ua->intf[i]) {
1248 dev_err(&ua->dev->dev, "interface %u not found\n",
1249 intf_numbers[is_ua1000][i]);
1250 err = -ENXIO;
1251 goto probe_error;
1252 }
1253 err = usb_driver_claim_interface(&ua101_driver,
1254 ua->intf[i], ua);
1255 if (err < 0) {
1256 ua->intf[i] = NULL;
1257 err = -EBUSY;
1258 goto probe_error;
1259 }
1260 }
1261
1262 snd_card_set_dev(card, &interface->dev);
1263
1264 err = detect_usb_format(ua);
1265 if (err < 0)
1266 goto probe_error;
1267
1268 name = usb_id->idProduct == 0x0044 ? "UA-1000" : "UA-101";
1269 strcpy(card->driver, "UA-101");
1270 strcpy(card->shortname, name);
1271 usb_make_path(ua->dev, usb_path, sizeof(usb_path));
1272 snprintf(ua->card->longname, sizeof(ua->card->longname),
1273 "EDIROL %s (serial %s), %u Hz at %s, %s speed", name,
1274 ua->dev->serial ? ua->dev->serial : "?", ua->rate, usb_path,
1275 ua->dev->speed == USB_SPEED_HIGH ? "high" : "full");
1276
1277 err = alloc_stream_buffers(ua, &ua->capture);
1278 if (err < 0)
1279 goto probe_error;
1280 err = alloc_stream_buffers(ua, &ua->playback);
1281 if (err < 0)
1282 goto probe_error;
1283
1284 err = alloc_stream_urbs(ua, &ua->capture, capture_urb_complete);
1285 if (err < 0)
1286 goto probe_error;
1287 err = alloc_stream_urbs(ua, &ua->playback, playback_urb_complete);
1288 if (err < 0)
1289 goto probe_error;
1290
1291 err = snd_pcm_new(card, name, 0, 1, 1, &ua->pcm);
1292 if (err < 0)
1293 goto probe_error;
1294 ua->pcm->private_data = ua;
1295 strcpy(ua->pcm->name, name);
1296 snd_pcm_set_ops(ua->pcm, SNDRV_PCM_STREAM_PLAYBACK, &playback_pcm_ops);
1297 snd_pcm_set_ops(ua->pcm, SNDRV_PCM_STREAM_CAPTURE, &capture_pcm_ops);
1298
1299 err = snd_usbmidi_create(card, ua->intf[INTF_MIDI],
1300 &ua->midi_list, &midi_quirk);
1301 if (err < 0)
1302 goto probe_error;
1303
1304 err = snd_card_register(card);
1305 if (err < 0)
1306 goto probe_error;
1307
1308 usb_set_intfdata(interface, ua);
1309 devices_used |= 1 << card_index;
1310
1311 mutex_unlock(&devices_mutex);
1312 return 0;
1313
1314probe_error:
1315 free_usb_related_resources(ua, interface);
1316 snd_card_free(card);
1317 mutex_unlock(&devices_mutex);
1318 return err;
1319}
1320
1321static void ua101_disconnect(struct usb_interface *interface)
1322{
1323 struct ua101 *ua = usb_get_intfdata(interface);
1324 struct list_head *midi;
1325
1326 if (!ua)
1327 return;
1328
1329 mutex_lock(&devices_mutex);
1330
1331 set_bit(DISCONNECTED, &ua->states);
1332 wake_up(&ua->rate_feedback_wait);
1333
1334 /* make sure that userspace cannot create new requests */
1335 snd_card_disconnect(ua->card);
1336
1337 /* make sure that there are no pending USB requests */
1338 __list_for_each(midi, &ua->midi_list)
1339 snd_usbmidi_disconnect(midi);
1340 abort_alsa_playback(ua);
1341 abort_alsa_capture(ua);
1342 mutex_lock(&ua->mutex);
1343 stop_usb_playback(ua);
1344 stop_usb_capture(ua);
1345 mutex_unlock(&ua->mutex);
1346
1347 free_usb_related_resources(ua, interface);
1348
1349 devices_used &= ~(1 << ua->card_index);
1350
1351 snd_card_free_when_closed(ua->card);
1352
1353 mutex_unlock(&devices_mutex);
1354}
1355
1356static struct usb_device_id ua101_ids[] = {
1357 { USB_DEVICE(0x0582, 0x0044) }, /* UA-1000 high speed */
1358 { USB_DEVICE(0x0582, 0x007d) }, /* UA-101 high speed */
1359 { USB_DEVICE(0x0582, 0x008d) }, /* UA-101 full speed */
1360 { }
1361};
1362MODULE_DEVICE_TABLE(usb, ua101_ids);
1363
1364static struct usb_driver ua101_driver = {
1365 .name = "snd-ua101",
1366 .id_table = ua101_ids,
1367 .probe = ua101_probe,
1368 .disconnect = ua101_disconnect,
1369#if 0
1370 .suspend = ua101_suspend,
1371 .resume = ua101_resume,
1372#endif
1373};
1374
1375static int __init alsa_card_ua101_init(void)
1376{
1377 return usb_register(&ua101_driver);
1378}
1379
1380static void __exit alsa_card_ua101_exit(void)
1381{
1382 usb_deregister(&ua101_driver);
1383 mutex_destroy(&devices_mutex);
1384}
1385
1386module_init(alsa_card_ua101_init);
1387module_exit(alsa_card_ua101_exit);
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index 8db0374e10d5..11b0826b8fe6 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -44,9 +44,11 @@
44#include <linux/slab.h> 44#include <linux/slab.h>
45#include <linux/string.h> 45#include <linux/string.h>
46#include <linux/usb.h> 46#include <linux/usb.h>
47#include <linux/vmalloc.h>
48#include <linux/moduleparam.h> 47#include <linux/moduleparam.h>
49#include <linux/mutex.h> 48#include <linux/mutex.h>
49#include <linux/usb/audio.h>
50#include <linux/usb/ch9.h>
51
50#include <sound/core.h> 52#include <sound/core.h>
51#include <sound/info.h> 53#include <sound/info.h>
52#include <sound/pcm.h> 54#include <sound/pcm.h>
@@ -170,11 +172,12 @@ struct snd_usb_substream {
170 unsigned int curpacksize; /* current packet size in bytes (for capture) */ 172 unsigned int curpacksize; /* current packet size in bytes (for capture) */
171 unsigned int curframesize; /* current packet size in frames (for capture) */ 173 unsigned int curframesize; /* current packet size in frames (for capture) */
172 unsigned int fill_max: 1; /* fill max packet size always */ 174 unsigned int fill_max: 1; /* fill max packet size always */
175 unsigned int txfr_quirk:1; /* allow sub-frame alignment */
173 unsigned int fmt_type; /* USB audio format type (1-3) */ 176 unsigned int fmt_type; /* USB audio format type (1-3) */
174 177
175 unsigned int running: 1; /* running status */ 178 unsigned int running: 1; /* running status */
176 179
177 unsigned int hwptr_done; /* processed frame position in the buffer */ 180 unsigned int hwptr_done; /* processed byte position in the buffer */
178 unsigned int transfer_done; /* processed frames since last period update */ 181 unsigned int transfer_done; /* processed frames since last period update */
179 unsigned long active_mask; /* bitmask of active urbs */ 182 unsigned long active_mask; /* bitmask of active urbs */
180 unsigned long unlink_mask; /* bitmask of unlinked urbs */ 183 unsigned long unlink_mask; /* bitmask of unlinked urbs */
@@ -343,7 +346,7 @@ static int retire_capture_urb(struct snd_usb_substream *subs,
343 unsigned long flags; 346 unsigned long flags;
344 unsigned char *cp; 347 unsigned char *cp;
345 int i; 348 int i;
346 unsigned int stride, len, oldptr; 349 unsigned int stride, frames, bytes, oldptr;
347 int period_elapsed = 0; 350 int period_elapsed = 0;
348 351
349 stride = runtime->frame_bits >> 3; 352 stride = runtime->frame_bits >> 3;
@@ -354,29 +357,39 @@ static int retire_capture_urb(struct snd_usb_substream *subs,
354 snd_printd(KERN_ERR "frame %d active: %d\n", i, urb->iso_frame_desc[i].status); 357 snd_printd(KERN_ERR "frame %d active: %d\n", i, urb->iso_frame_desc[i].status);
355 // continue; 358 // continue;
356 } 359 }
357 len = urb->iso_frame_desc[i].actual_length / stride; 360 bytes = urb->iso_frame_desc[i].actual_length;
358 if (! len) 361 frames = bytes / stride;
359 continue; 362 if (!subs->txfr_quirk)
363 bytes = frames * stride;
364 if (bytes % (runtime->sample_bits >> 3) != 0) {
365#ifdef CONFIG_SND_DEBUG_VERBOSE
366 int oldbytes = bytes;
367#endif
368 bytes = frames * stride;
369 snd_printdd(KERN_ERR "Corrected urb data len. %d->%d\n",
370 oldbytes, bytes);
371 }
360 /* update the current pointer */ 372 /* update the current pointer */
361 spin_lock_irqsave(&subs->lock, flags); 373 spin_lock_irqsave(&subs->lock, flags);
362 oldptr = subs->hwptr_done; 374 oldptr = subs->hwptr_done;
363 subs->hwptr_done += len; 375 subs->hwptr_done += bytes;
364 if (subs->hwptr_done >= runtime->buffer_size) 376 if (subs->hwptr_done >= runtime->buffer_size * stride)
365 subs->hwptr_done -= runtime->buffer_size; 377 subs->hwptr_done -= runtime->buffer_size * stride;
366 subs->transfer_done += len; 378 frames = (bytes + (oldptr % stride)) / stride;
379 subs->transfer_done += frames;
367 if (subs->transfer_done >= runtime->period_size) { 380 if (subs->transfer_done >= runtime->period_size) {
368 subs->transfer_done -= runtime->period_size; 381 subs->transfer_done -= runtime->period_size;
369 period_elapsed = 1; 382 period_elapsed = 1;
370 } 383 }
371 spin_unlock_irqrestore(&subs->lock, flags); 384 spin_unlock_irqrestore(&subs->lock, flags);
372 /* copy a data chunk */ 385 /* copy a data chunk */
373 if (oldptr + len > runtime->buffer_size) { 386 if (oldptr + bytes > runtime->buffer_size * stride) {
374 unsigned int cnt = runtime->buffer_size - oldptr; 387 unsigned int bytes1 =
375 unsigned int blen = cnt * stride; 388 runtime->buffer_size * stride - oldptr;
376 memcpy(runtime->dma_area + oldptr * stride, cp, blen); 389 memcpy(runtime->dma_area + oldptr, cp, bytes1);
377 memcpy(runtime->dma_area, cp + blen, len * stride - blen); 390 memcpy(runtime->dma_area, cp + bytes1, bytes - bytes1);
378 } else { 391 } else {
379 memcpy(runtime->dma_area + oldptr * stride, cp, len * stride); 392 memcpy(runtime->dma_area + oldptr, cp, bytes);
380 } 393 }
381 } 394 }
382 if (period_elapsed) 395 if (period_elapsed)
@@ -563,34 +576,34 @@ static int prepare_playback_urb(struct snd_usb_substream *subs,
563 struct snd_pcm_runtime *runtime, 576 struct snd_pcm_runtime *runtime,
564 struct urb *urb) 577 struct urb *urb)
565{ 578{
566 int i, stride, offs; 579 int i, stride;
567 unsigned int counts; 580 unsigned int counts, frames, bytes;
568 unsigned long flags; 581 unsigned long flags;
569 int period_elapsed = 0; 582 int period_elapsed = 0;
570 struct snd_urb_ctx *ctx = urb->context; 583 struct snd_urb_ctx *ctx = urb->context;
571 584
572 stride = runtime->frame_bits >> 3; 585 stride = runtime->frame_bits >> 3;
573 586
574 offs = 0; 587 frames = 0;
575 urb->dev = ctx->subs->dev; /* we need to set this at each time */ 588 urb->dev = ctx->subs->dev; /* we need to set this at each time */
576 urb->number_of_packets = 0; 589 urb->number_of_packets = 0;
577 spin_lock_irqsave(&subs->lock, flags); 590 spin_lock_irqsave(&subs->lock, flags);
578 for (i = 0; i < ctx->packets; i++) { 591 for (i = 0; i < ctx->packets; i++) {
579 counts = snd_usb_audio_next_packet_size(subs); 592 counts = snd_usb_audio_next_packet_size(subs);
580 /* set up descriptor */ 593 /* set up descriptor */
581 urb->iso_frame_desc[i].offset = offs * stride; 594 urb->iso_frame_desc[i].offset = frames * stride;
582 urb->iso_frame_desc[i].length = counts * stride; 595 urb->iso_frame_desc[i].length = counts * stride;
583 offs += counts; 596 frames += counts;
584 urb->number_of_packets++; 597 urb->number_of_packets++;
585 subs->transfer_done += counts; 598 subs->transfer_done += counts;
586 if (subs->transfer_done >= runtime->period_size) { 599 if (subs->transfer_done >= runtime->period_size) {
587 subs->transfer_done -= runtime->period_size; 600 subs->transfer_done -= runtime->period_size;
588 period_elapsed = 1; 601 period_elapsed = 1;
589 if (subs->fmt_type == USB_FORMAT_TYPE_II) { 602 if (subs->fmt_type == UAC_FORMAT_TYPE_II) {
590 if (subs->transfer_done > 0) { 603 if (subs->transfer_done > 0) {
591 /* FIXME: fill-max mode is not 604 /* FIXME: fill-max mode is not
592 * supported yet */ 605 * supported yet */
593 offs -= subs->transfer_done; 606 frames -= subs->transfer_done;
594 counts -= subs->transfer_done; 607 counts -= subs->transfer_done;
595 urb->iso_frame_desc[i].length = 608 urb->iso_frame_desc[i].length =
596 counts * stride; 609 counts * stride;
@@ -600,7 +613,7 @@ static int prepare_playback_urb(struct snd_usb_substream *subs,
600 if (i < ctx->packets) { 613 if (i < ctx->packets) {
601 /* add a transfer delimiter */ 614 /* add a transfer delimiter */
602 urb->iso_frame_desc[i].offset = 615 urb->iso_frame_desc[i].offset =
603 offs * stride; 616 frames * stride;
604 urb->iso_frame_desc[i].length = 0; 617 urb->iso_frame_desc[i].length = 0;
605 urb->number_of_packets++; 618 urb->number_of_packets++;
606 } 619 }
@@ -610,26 +623,25 @@ static int prepare_playback_urb(struct snd_usb_substream *subs,
610 if (period_elapsed) /* finish at the period boundary */ 623 if (period_elapsed) /* finish at the period boundary */
611 break; 624 break;
612 } 625 }
613 if (subs->hwptr_done + offs > runtime->buffer_size) { 626 bytes = frames * stride;
627 if (subs->hwptr_done + bytes > runtime->buffer_size * stride) {
614 /* err, the transferred area goes over buffer boundary. */ 628 /* err, the transferred area goes over buffer boundary. */
615 unsigned int len = runtime->buffer_size - subs->hwptr_done; 629 unsigned int bytes1 =
630 runtime->buffer_size * stride - subs->hwptr_done;
616 memcpy(urb->transfer_buffer, 631 memcpy(urb->transfer_buffer,
617 runtime->dma_area + subs->hwptr_done * stride, 632 runtime->dma_area + subs->hwptr_done, bytes1);
618 len * stride); 633 memcpy(urb->transfer_buffer + bytes1,
619 memcpy(urb->transfer_buffer + len * stride, 634 runtime->dma_area, bytes - bytes1);
620 runtime->dma_area,
621 (offs - len) * stride);
622 } else { 635 } else {
623 memcpy(urb->transfer_buffer, 636 memcpy(urb->transfer_buffer,
624 runtime->dma_area + subs->hwptr_done * stride, 637 runtime->dma_area + subs->hwptr_done, bytes);
625 offs * stride);
626 } 638 }
627 subs->hwptr_done += offs; 639 subs->hwptr_done += bytes;
628 if (subs->hwptr_done >= runtime->buffer_size) 640 if (subs->hwptr_done >= runtime->buffer_size * stride)
629 subs->hwptr_done -= runtime->buffer_size; 641 subs->hwptr_done -= runtime->buffer_size * stride;
630 runtime->delay += offs; 642 runtime->delay += frames;
631 spin_unlock_irqrestore(&subs->lock, flags); 643 spin_unlock_irqrestore(&subs->lock, flags);
632 urb->transfer_buffer_length = offs * stride; 644 urb->transfer_buffer_length = bytes;
633 if (period_elapsed) 645 if (period_elapsed)
634 snd_pcm_period_elapsed(subs->pcm_substream); 646 snd_pcm_period_elapsed(subs->pcm_substream);
635 return 0; 647 return 0;
@@ -735,41 +747,6 @@ static void snd_complete_sync_urb(struct urb *urb)
735} 747}
736 748
737 749
738/* get the physical page pointer at the given offset */
739static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs,
740 unsigned long offset)
741{
742 void *pageptr = subs->runtime->dma_area + offset;
743 return vmalloc_to_page(pageptr);
744}
745
746/* allocate virtual buffer; may be called more than once */
747static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, size_t size)
748{
749 struct snd_pcm_runtime *runtime = subs->runtime;
750 if (runtime->dma_area) {
751 if (runtime->dma_bytes >= size)
752 return 0; /* already large enough */
753 vfree(runtime->dma_area);
754 }
755 runtime->dma_area = vmalloc(size);
756 if (!runtime->dma_area)
757 return -ENOMEM;
758 runtime->dma_bytes = size;
759 return 0;
760}
761
762/* free virtual buffer; may be called more than once */
763static int snd_pcm_free_vmalloc_buffer(struct snd_pcm_substream *subs)
764{
765 struct snd_pcm_runtime *runtime = subs->runtime;
766
767 vfree(runtime->dma_area);
768 runtime->dma_area = NULL;
769 return 0;
770}
771
772
773/* 750/*
774 * unlink active urbs. 751 * unlink active urbs.
775 */ 752 */
@@ -937,18 +914,18 @@ static int wait_clear_urbs(struct snd_usb_substream *subs)
937 914
938 915
939/* 916/*
940 * return the current pcm pointer. just return the hwptr_done value. 917 * return the current pcm pointer. just based on the hwptr_done value.
941 */ 918 */
942static snd_pcm_uframes_t snd_usb_pcm_pointer(struct snd_pcm_substream *substream) 919static snd_pcm_uframes_t snd_usb_pcm_pointer(struct snd_pcm_substream *substream)
943{ 920{
944 struct snd_usb_substream *subs; 921 struct snd_usb_substream *subs;
945 snd_pcm_uframes_t hwptr_done; 922 unsigned int hwptr_done;
946 923
947 subs = (struct snd_usb_substream *)substream->runtime->private_data; 924 subs = (struct snd_usb_substream *)substream->runtime->private_data;
948 spin_lock(&subs->lock); 925 spin_lock(&subs->lock);
949 hwptr_done = subs->hwptr_done; 926 hwptr_done = subs->hwptr_done;
950 spin_unlock(&subs->lock); 927 spin_unlock(&subs->lock);
951 return hwptr_done; 928 return hwptr_done / (substream->runtime->frame_bits >> 3);
952} 929}
953 930
954 931
@@ -1130,7 +1107,7 @@ static int init_substream_urbs(struct snd_usb_substream *subs, unsigned int peri
1130 u->packets = (i + 1) * total_packs / subs->nurbs 1107 u->packets = (i + 1) * total_packs / subs->nurbs
1131 - i * total_packs / subs->nurbs; 1108 - i * total_packs / subs->nurbs;
1132 u->buffer_size = maxsize * u->packets; 1109 u->buffer_size = maxsize * u->packets;
1133 if (subs->fmt_type == USB_FORMAT_TYPE_II) 1110 if (subs->fmt_type == UAC_FORMAT_TYPE_II)
1134 u->packets++; /* for transfer delimiter */ 1111 u->packets++; /* for transfer delimiter */
1135 u->urb = usb_alloc_urb(u->packets, GFP_KERNEL); 1112 u->urb = usb_alloc_urb(u->packets, GFP_KERNEL);
1136 if (!u->urb) 1113 if (!u->urb)
@@ -1206,7 +1183,7 @@ static struct audioformat *find_format(struct snd_usb_substream *subs, unsigned
1206 if (i >= fp->nr_rates) 1183 if (i >= fp->nr_rates)
1207 continue; 1184 continue;
1208 } 1185 }
1209 attr = fp->ep_attr & EP_ATTR_MASK; 1186 attr = fp->ep_attr & USB_ENDPOINT_SYNCTYPE;
1210 if (! found) { 1187 if (! found) {
1211 found = fp; 1188 found = fp;
1212 cur_attr = attr; 1189 cur_attr = attr;
@@ -1218,14 +1195,14 @@ static struct audioformat *find_format(struct snd_usb_substream *subs, unsigned
1218 * M-audio audiophile USB. 1195 * M-audio audiophile USB.
1219 */ 1196 */
1220 if (attr != cur_attr) { 1197 if (attr != cur_attr) {
1221 if ((attr == EP_ATTR_ASYNC && 1198 if ((attr == USB_ENDPOINT_SYNC_ASYNC &&
1222 subs->direction == SNDRV_PCM_STREAM_PLAYBACK) || 1199 subs->direction == SNDRV_PCM_STREAM_PLAYBACK) ||
1223 (attr == EP_ATTR_ADAPTIVE && 1200 (attr == USB_ENDPOINT_SYNC_ADAPTIVE &&
1224 subs->direction == SNDRV_PCM_STREAM_CAPTURE)) 1201 subs->direction == SNDRV_PCM_STREAM_CAPTURE))
1225 continue; 1202 continue;
1226 if ((cur_attr == EP_ATTR_ASYNC && 1203 if ((cur_attr == USB_ENDPOINT_SYNC_ASYNC &&
1227 subs->direction == SNDRV_PCM_STREAM_PLAYBACK) || 1204 subs->direction == SNDRV_PCM_STREAM_PLAYBACK) ||
1228 (cur_attr == EP_ATTR_ADAPTIVE && 1205 (cur_attr == USB_ENDPOINT_SYNC_ADAPTIVE &&
1229 subs->direction == SNDRV_PCM_STREAM_CAPTURE)) { 1206 subs->direction == SNDRV_PCM_STREAM_CAPTURE)) {
1230 found = fp; 1207 found = fp;
1231 cur_attr = attr; 1208 cur_attr = attr;
@@ -1255,11 +1232,11 @@ static int init_usb_pitch(struct usb_device *dev, int iface,
1255 1232
1256 ep = get_endpoint(alts, 0)->bEndpointAddress; 1233 ep = get_endpoint(alts, 0)->bEndpointAddress;
1257 /* if endpoint has pitch control, enable it */ 1234 /* if endpoint has pitch control, enable it */
1258 if (fmt->attributes & EP_CS_ATTR_PITCH_CONTROL) { 1235 if (fmt->attributes & UAC_EP_CS_ATTR_PITCH_CONTROL) {
1259 data[0] = 1; 1236 data[0] = 1;
1260 if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, 1237 if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR,
1261 USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, 1238 USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT,
1262 PITCH_CONTROL << 8, ep, data, 1, 1000)) < 0) { 1239 UAC_EP_CS_ATTR_PITCH_CONTROL << 8, ep, data, 1, 1000)) < 0) {
1263 snd_printk(KERN_ERR "%d:%d:%d: cannot set enable PITCH\n", 1240 snd_printk(KERN_ERR "%d:%d:%d: cannot set enable PITCH\n",
1264 dev->devnum, iface, ep); 1241 dev->devnum, iface, ep);
1265 return err; 1242 return err;
@@ -1278,21 +1255,21 @@ static int init_usb_sample_rate(struct usb_device *dev, int iface,
1278 1255
1279 ep = get_endpoint(alts, 0)->bEndpointAddress; 1256 ep = get_endpoint(alts, 0)->bEndpointAddress;
1280 /* if endpoint has sampling rate control, set it */ 1257 /* if endpoint has sampling rate control, set it */
1281 if (fmt->attributes & EP_CS_ATTR_SAMPLE_RATE) { 1258 if (fmt->attributes & UAC_EP_CS_ATTR_SAMPLE_RATE) {
1282 int crate; 1259 int crate;
1283 data[0] = rate; 1260 data[0] = rate;
1284 data[1] = rate >> 8; 1261 data[1] = rate >> 8;
1285 data[2] = rate >> 16; 1262 data[2] = rate >> 16;
1286 if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, 1263 if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR,
1287 USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, 1264 USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT,
1288 SAMPLING_FREQ_CONTROL << 8, ep, data, 3, 1000)) < 0) { 1265 UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep, data, 3, 1000)) < 0) {
1289 snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d to ep %#x\n", 1266 snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d to ep %#x\n",
1290 dev->devnum, iface, fmt->altsetting, rate, ep); 1267 dev->devnum, iface, fmt->altsetting, rate, ep);
1291 return err; 1268 return err;
1292 } 1269 }
1293 if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, 1270 if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC_GET_CUR,
1294 USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_IN, 1271 USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_IN,
1295 SAMPLING_FREQ_CONTROL << 8, ep, data, 3, 1000)) < 0) { 1272 UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep, data, 3, 1000)) < 0) {
1296 snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq at ep %#x\n", 1273 snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq at ep %#x\n",
1297 dev->devnum, iface, fmt->altsetting, ep); 1274 dev->devnum, iface, fmt->altsetting, ep);
1298 return 0; /* some devices don't support reading */ 1275 return 0; /* some devices don't support reading */
@@ -1307,6 +1284,47 @@ static int init_usb_sample_rate(struct usb_device *dev, int iface,
1307} 1284}
1308 1285
1309/* 1286/*
1287 * For E-Mu 0404USB/0202USB/TrackerPre sample rate should be set for device,
1288 * not for interface.
1289 */
1290static void set_format_emu_quirk(struct snd_usb_substream *subs,
1291 struct audioformat *fmt)
1292{
1293 unsigned char emu_samplerate_id = 0;
1294
1295 /* When capture is active
1296 * sample rate shouldn't be changed
1297 * by playback substream
1298 */
1299 if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) {
1300 if (subs->stream->substream[SNDRV_PCM_STREAM_CAPTURE].interface != -1)
1301 return;
1302 }
1303
1304 switch (fmt->rate_min) {
1305 case 48000:
1306 emu_samplerate_id = EMU_QUIRK_SR_48000HZ;
1307 break;
1308 case 88200:
1309 emu_samplerate_id = EMU_QUIRK_SR_88200HZ;
1310 break;
1311 case 96000:
1312 emu_samplerate_id = EMU_QUIRK_SR_96000HZ;
1313 break;
1314 case 176400:
1315 emu_samplerate_id = EMU_QUIRK_SR_176400HZ;
1316 break;
1317 case 192000:
1318 emu_samplerate_id = EMU_QUIRK_SR_192000HZ;
1319 break;
1320 default:
1321 emu_samplerate_id = EMU_QUIRK_SR_44100HZ;
1322 break;
1323 }
1324 snd_emuusb_set_samplerate(subs->stream->chip, emu_samplerate_id);
1325}
1326
1327/*
1310 * find a matching format and set up the interface 1328 * find a matching format and set up the interface
1311 */ 1329 */
1312static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt) 1330static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
@@ -1369,9 +1387,9 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
1369 * descriptors which fool us. if it has only one EP, 1387 * descriptors which fool us. if it has only one EP,
1370 * assume it as adaptive-out or sync-in. 1388 * assume it as adaptive-out or sync-in.
1371 */ 1389 */
1372 attr = fmt->ep_attr & EP_ATTR_MASK; 1390 attr = fmt->ep_attr & USB_ENDPOINT_SYNCTYPE;
1373 if (((is_playback && attr == EP_ATTR_ASYNC) || 1391 if (((is_playback && attr == USB_ENDPOINT_SYNC_ASYNC) ||
1374 (! is_playback && attr == EP_ATTR_ADAPTIVE)) && 1392 (! is_playback && attr == USB_ENDPOINT_SYNC_ADAPTIVE)) &&
1375 altsd->bNumEndpoints >= 2) { 1393 altsd->bNumEndpoints >= 2) {
1376 /* check sync-pipe endpoint */ 1394 /* check sync-pipe endpoint */
1377 /* ... and check descriptor size before accessing bSynchAddress 1395 /* ... and check descriptor size before accessing bSynchAddress
@@ -1411,7 +1429,7 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
1411 } 1429 }
1412 1430
1413 /* always fill max packet size */ 1431 /* always fill max packet size */
1414 if (fmt->attributes & EP_CS_ATTR_FILL_MAX) 1432 if (fmt->attributes & UAC_EP_CS_ATTR_FILL_MAX)
1415 subs->fill_max = 1; 1433 subs->fill_max = 1;
1416 1434
1417 if ((err = init_usb_pitch(dev, subs->interface, alts, fmt)) < 0) 1435 if ((err = init_usb_pitch(dev, subs->interface, alts, fmt)) < 0)
@@ -1419,6 +1437,14 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
1419 1437
1420 subs->cur_audiofmt = fmt; 1438 subs->cur_audiofmt = fmt;
1421 1439
1440 switch (subs->stream->chip->usb_id) {
1441 case USB_ID(0x041e, 0x3f02): /* E-Mu 0202 USB */
1442 case USB_ID(0x041e, 0x3f04): /* E-Mu 0404 USB */
1443 case USB_ID(0x041e, 0x3f0a): /* E-Mu Tracker Pre */
1444 set_format_emu_quirk(subs, fmt);
1445 break;
1446 }
1447
1422#if 0 1448#if 0
1423 printk(KERN_DEBUG 1449 printk(KERN_DEBUG
1424 "setting done: format = %d, rate = %d..%d, channels = %d\n", 1450 "setting done: format = %d, rate = %d..%d, channels = %d\n",
@@ -1449,8 +1475,8 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream,
1449 unsigned int channels, rate, format; 1475 unsigned int channels, rate, format;
1450 int ret, changed; 1476 int ret, changed;
1451 1477
1452 ret = snd_pcm_alloc_vmalloc_buffer(substream, 1478 ret = snd_pcm_lib_alloc_vmalloc_buffer(substream,
1453 params_buffer_bytes(hw_params)); 1479 params_buffer_bytes(hw_params));
1454 if (ret < 0) 1480 if (ret < 0)
1455 return ret; 1481 return ret;
1456 1482
@@ -1507,7 +1533,7 @@ static int snd_usb_hw_free(struct snd_pcm_substream *substream)
1507 subs->period_bytes = 0; 1533 subs->period_bytes = 0;
1508 if (!subs->stream->chip->shutdown) 1534 if (!subs->stream->chip->shutdown)
1509 release_substream_urbs(subs, 0); 1535 release_substream_urbs(subs, 0);
1510 return snd_pcm_free_vmalloc_buffer(substream); 1536 return snd_pcm_lib_free_vmalloc_buffer(substream);
1511} 1537}
1512 1538
1513/* 1539/*
@@ -1861,7 +1887,7 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre
1861 runtime->hw.channels_min = fp->channels; 1887 runtime->hw.channels_min = fp->channels;
1862 if (runtime->hw.channels_max < fp->channels) 1888 if (runtime->hw.channels_max < fp->channels)
1863 runtime->hw.channels_max = fp->channels; 1889 runtime->hw.channels_max = fp->channels;
1864 if (fp->fmt_type == USB_FORMAT_TYPE_II && fp->frame_size > 0) { 1890 if (fp->fmt_type == UAC_FORMAT_TYPE_II && fp->frame_size > 0) {
1865 /* FIXME: there might be more than one audio formats... */ 1891 /* FIXME: there might be more than one audio formats... */
1866 runtime->hw.period_bytes_min = runtime->hw.period_bytes_max = 1892 runtime->hw.period_bytes_min = runtime->hw.period_bytes_max =
1867 fp->frame_size; 1893 fp->frame_size;
@@ -1936,7 +1962,7 @@ static int snd_usb_pcm_close(struct snd_pcm_substream *substream, int direction)
1936 struct snd_usb_stream *as = snd_pcm_substream_chip(substream); 1962 struct snd_usb_stream *as = snd_pcm_substream_chip(substream);
1937 struct snd_usb_substream *subs = &as->substream[direction]; 1963 struct snd_usb_substream *subs = &as->substream[direction];
1938 1964
1939 if (subs->interface >= 0) { 1965 if (!as->chip->shutdown && subs->interface >= 0) {
1940 usb_set_interface(subs->dev, subs->interface, 0); 1966 usb_set_interface(subs->dev, subs->interface, 0);
1941 subs->interface = -1; 1967 subs->interface = -1;
1942 } 1968 }
@@ -1973,7 +1999,8 @@ static struct snd_pcm_ops snd_usb_playback_ops = {
1973 .prepare = snd_usb_pcm_prepare, 1999 .prepare = snd_usb_pcm_prepare,
1974 .trigger = snd_usb_pcm_playback_trigger, 2000 .trigger = snd_usb_pcm_playback_trigger,
1975 .pointer = snd_usb_pcm_pointer, 2001 .pointer = snd_usb_pcm_pointer,
1976 .page = snd_pcm_get_vmalloc_page, 2002 .page = snd_pcm_lib_get_vmalloc_page,
2003 .mmap = snd_pcm_lib_mmap_vmalloc,
1977}; 2004};
1978 2005
1979static struct snd_pcm_ops snd_usb_capture_ops = { 2006static struct snd_pcm_ops snd_usb_capture_ops = {
@@ -1985,7 +2012,8 @@ static struct snd_pcm_ops snd_usb_capture_ops = {
1985 .prepare = snd_usb_pcm_prepare, 2012 .prepare = snd_usb_pcm_prepare,
1986 .trigger = snd_usb_pcm_capture_trigger, 2013 .trigger = snd_usb_pcm_capture_trigger,
1987 .pointer = snd_usb_pcm_pointer, 2014 .pointer = snd_usb_pcm_pointer,
1988 .page = snd_pcm_get_vmalloc_page, 2015 .page = snd_pcm_lib_get_vmalloc_page,
2016 .mmap = snd_pcm_lib_mmap_vmalloc,
1989}; 2017};
1990 2018
1991 2019
@@ -2093,7 +2121,7 @@ static struct usb_device_id usb_audio_ids [] = {
2093#include "usbquirks.h" 2121#include "usbquirks.h"
2094 { .match_flags = (USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS), 2122 { .match_flags = (USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS),
2095 .bInterfaceClass = USB_CLASS_AUDIO, 2123 .bInterfaceClass = USB_CLASS_AUDIO,
2096 .bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL }, 2124 .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL },
2097 { } /* Terminating entry */ 2125 { } /* Terminating entry */
2098}; 2126};
2099 2127
@@ -2132,7 +2160,7 @@ static void proc_dump_substream_formats(struct snd_usb_substream *subs, struct s
2132 snd_iprintf(buffer, " Endpoint: %d %s (%s)\n", 2160 snd_iprintf(buffer, " Endpoint: %d %s (%s)\n",
2133 fp->endpoint & USB_ENDPOINT_NUMBER_MASK, 2161 fp->endpoint & USB_ENDPOINT_NUMBER_MASK,
2134 fp->endpoint & USB_DIR_IN ? "IN" : "OUT", 2162 fp->endpoint & USB_DIR_IN ? "IN" : "OUT",
2135 sync_types[(fp->ep_attr & EP_ATTR_MASK) >> 2]); 2163 sync_types[(fp->ep_attr & USB_ENDPOINT_SYNCTYPE) >> 2]);
2136 if (fp->rates & SNDRV_PCM_RATE_CONTINUOUS) { 2164 if (fp->rates & SNDRV_PCM_RATE_CONTINUOUS) {
2137 snd_iprintf(buffer, " Rates: %d - %d (continuous)\n", 2165 snd_iprintf(buffer, " Rates: %d - %d (continuous)\n",
2138 fp->rate_min, fp->rate_max); 2166 fp->rate_min, fp->rate_max);
@@ -2227,6 +2255,7 @@ static void init_substream(struct snd_usb_stream *as, int stream, struct audiofo
2227 subs->stream = as; 2255 subs->stream = as;
2228 subs->direction = stream; 2256 subs->direction = stream;
2229 subs->dev = as->chip->dev; 2257 subs->dev = as->chip->dev;
2258 subs->txfr_quirk = as->chip->txfr_quirk;
2230 if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) { 2259 if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) {
2231 subs->ops = audio_urb_ops[stream]; 2260 subs->ops = audio_urb_ops[stream];
2232 } else { 2261 } else {
@@ -2394,29 +2423,67 @@ static int is_big_endian_format(struct snd_usb_audio *chip, struct audioformat *
2394 * @format: the format tag (wFormatTag) 2423 * @format: the format tag (wFormatTag)
2395 * @fmt: the format type descriptor 2424 * @fmt: the format type descriptor
2396 */ 2425 */
2397static int parse_audio_format_i_type(struct snd_usb_audio *chip, struct audioformat *fp, 2426static int parse_audio_format_i_type(struct snd_usb_audio *chip,
2398 int format, unsigned char *fmt) 2427 struct audioformat *fp,
2428 int format, void *_fmt,
2429 int protocol)
2399{ 2430{
2400 int pcm_format; 2431 int pcm_format, i;
2401 int sample_width, sample_bytes; 2432 int sample_width, sample_bytes;
2402 2433
2434 switch (protocol) {
2435 case UAC_VERSION_1: {
2436 struct uac_format_type_i_discrete_descriptor *fmt = _fmt;
2437 sample_width = fmt->bBitResolution;
2438 sample_bytes = fmt->bSubframeSize;
2439 break;
2440 }
2441
2442 case UAC_VERSION_2: {
2443 struct uac_format_type_i_ext_descriptor *fmt = _fmt;
2444 sample_width = fmt->bBitResolution;
2445 sample_bytes = fmt->bSubslotSize;
2446
2447 /*
2448 * FIXME
2449 * USB audio class v2 devices specify a bitmap of possible
2450 * audio formats rather than one fix value. For now, we just
2451 * pick one of them and report that as the only possible
2452 * value for this setting.
2453 * The bit allocation map is in fact compatible to the
2454 * wFormatTag of the v1 AS streaming descriptors, which is why
2455 * we can simply map the matrix.
2456 */
2457
2458 for (i = 0; i < 5; i++)
2459 if (format & (1UL << i)) {
2460 format = i + 1;
2461 break;
2462 }
2463
2464 break;
2465 }
2466
2467 default:
2468 return -EINVAL;
2469 }
2470
2403 /* FIXME: correct endianess and sign? */ 2471 /* FIXME: correct endianess and sign? */
2404 pcm_format = -1; 2472 pcm_format = -1;
2405 sample_width = fmt[6]; 2473
2406 sample_bytes = fmt[5];
2407 switch (format) { 2474 switch (format) {
2408 case 0: /* some devices don't define this correctly... */ 2475 case UAC_FORMAT_TYPE_I_UNDEFINED: /* some devices don't define this correctly... */
2409 snd_printdd(KERN_INFO "%d:%u:%d : format type 0 is detected, processed as PCM\n", 2476 snd_printdd(KERN_INFO "%d:%u:%d : format type 0 is detected, processed as PCM\n",
2410 chip->dev->devnum, fp->iface, fp->altsetting); 2477 chip->dev->devnum, fp->iface, fp->altsetting);
2411 /* fall-through */ 2478 /* fall-through */
2412 case USB_AUDIO_FORMAT_PCM: 2479 case UAC_FORMAT_TYPE_I_PCM:
2413 if (sample_width > sample_bytes * 8) { 2480 if (sample_width > sample_bytes * 8) {
2414 snd_printk(KERN_INFO "%d:%u:%d : sample bitwidth %d in over sample bytes %d\n", 2481 snd_printk(KERN_INFO "%d:%u:%d : sample bitwidth %d in over sample bytes %d\n",
2415 chip->dev->devnum, fp->iface, fp->altsetting, 2482 chip->dev->devnum, fp->iface, fp->altsetting,
2416 sample_width, sample_bytes); 2483 sample_width, sample_bytes);
2417 } 2484 }
2418 /* check the format byte size */ 2485 /* check the format byte size */
2419 switch (fmt[5]) { 2486 switch (sample_bytes) {
2420 case 1: 2487 case 1:
2421 pcm_format = SNDRV_PCM_FORMAT_S8; 2488 pcm_format = SNDRV_PCM_FORMAT_S8;
2422 break; 2489 break;
@@ -2437,12 +2504,12 @@ static int parse_audio_format_i_type(struct snd_usb_audio *chip, struct audiofor
2437 break; 2504 break;
2438 default: 2505 default:
2439 snd_printk(KERN_INFO "%d:%u:%d : unsupported sample bitwidth %d in %d bytes\n", 2506 snd_printk(KERN_INFO "%d:%u:%d : unsupported sample bitwidth %d in %d bytes\n",
2440 chip->dev->devnum, fp->iface, 2507 chip->dev->devnum, fp->iface, fp->altsetting,
2441 fp->altsetting, sample_width, sample_bytes); 2508 sample_width, sample_bytes);
2442 break; 2509 break;
2443 } 2510 }
2444 break; 2511 break;
2445 case USB_AUDIO_FORMAT_PCM8: 2512 case UAC_FORMAT_TYPE_I_PCM8:
2446 pcm_format = SNDRV_PCM_FORMAT_U8; 2513 pcm_format = SNDRV_PCM_FORMAT_U8;
2447 2514
2448 /* Dallas DS4201 workaround: it advertises U8 format, but really 2515 /* Dallas DS4201 workaround: it advertises U8 format, but really
@@ -2450,13 +2517,13 @@ static int parse_audio_format_i_type(struct snd_usb_audio *chip, struct audiofor
2450 if (chip->usb_id == USB_ID(0x04fa, 0x4201)) 2517 if (chip->usb_id == USB_ID(0x04fa, 0x4201))
2451 pcm_format = SNDRV_PCM_FORMAT_S8; 2518 pcm_format = SNDRV_PCM_FORMAT_S8;
2452 break; 2519 break;
2453 case USB_AUDIO_FORMAT_IEEE_FLOAT: 2520 case UAC_FORMAT_TYPE_I_IEEE_FLOAT:
2454 pcm_format = SNDRV_PCM_FORMAT_FLOAT_LE; 2521 pcm_format = SNDRV_PCM_FORMAT_FLOAT_LE;
2455 break; 2522 break;
2456 case USB_AUDIO_FORMAT_ALAW: 2523 case UAC_FORMAT_TYPE_I_ALAW:
2457 pcm_format = SNDRV_PCM_FORMAT_A_LAW; 2524 pcm_format = SNDRV_PCM_FORMAT_A_LAW;
2458 break; 2525 break;
2459 case USB_AUDIO_FORMAT_MU_LAW: 2526 case UAC_FORMAT_TYPE_I_MULAW:
2460 pcm_format = SNDRV_PCM_FORMAT_MU_LAW; 2527 pcm_format = SNDRV_PCM_FORMAT_MU_LAW;
2461 break; 2528 break;
2462 default: 2529 default:
@@ -2470,7 +2537,7 @@ static int parse_audio_format_i_type(struct snd_usb_audio *chip, struct audiofor
2470 2537
2471/* 2538/*
2472 * parse the format descriptor and stores the possible sample rates 2539 * parse the format descriptor and stores the possible sample rates
2473 * on the audioformat table. 2540 * on the audioformat table (audio class v1).
2474 * 2541 *
2475 * @dev: usb device 2542 * @dev: usb device
2476 * @fp: audioformat record 2543 * @fp: audioformat record
@@ -2478,13 +2545,13 @@ static int parse_audio_format_i_type(struct snd_usb_audio *chip, struct audiofor
2478 * @offset: the start offset of descriptor pointing the rate type 2545 * @offset: the start offset of descriptor pointing the rate type
2479 * (7 for type I and II, 8 for type II) 2546 * (7 for type I and II, 8 for type II)
2480 */ 2547 */
2481static int parse_audio_format_rates(struct snd_usb_audio *chip, struct audioformat *fp, 2548static int parse_audio_format_rates_v1(struct snd_usb_audio *chip, struct audioformat *fp,
2482 unsigned char *fmt, int offset) 2549 unsigned char *fmt, int offset)
2483{ 2550{
2484 int nr_rates = fmt[offset]; 2551 int nr_rates = fmt[offset];
2485 2552
2486 if (fmt[0] < offset + 1 + 3 * (nr_rates ? nr_rates : 2)) { 2553 if (fmt[0] < offset + 1 + 3 * (nr_rates ? nr_rates : 2)) {
2487 snd_printk(KERN_ERR "%d:%u:%d : invalid FORMAT_TYPE desc\n", 2554 snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n",
2488 chip->dev->devnum, fp->iface, fp->altsetting); 2555 chip->dev->devnum, fp->iface, fp->altsetting);
2489 return -1; 2556 return -1;
2490 } 2557 }
@@ -2513,6 +2580,9 @@ static int parse_audio_format_rates(struct snd_usb_audio *chip, struct audioform
2513 chip->usb_id == USB_ID(0x0d8c, 0x0102)) && 2580 chip->usb_id == USB_ID(0x0d8c, 0x0102)) &&
2514 fp->altsetting == 5 && fp->maxpacksize == 392) 2581 fp->altsetting == 5 && fp->maxpacksize == 392)
2515 rate = 96000; 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;
2516 fp->rate_table[fp->nr_rates] = rate; 2586 fp->rate_table[fp->nr_rates] = rate;
2517 if (!fp->rate_min || rate < fp->rate_min) 2587 if (!fp->rate_min || rate < fp->rate_min)
2518 fp->rate_min = rate; 2588 fp->rate_min = rate;
@@ -2535,14 +2605,87 @@ static int parse_audio_format_rates(struct snd_usb_audio *chip, struct audioform
2535} 2605}
2536 2606
2537/* 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/*
2538 * parse the format type I and III descriptors 2676 * parse the format type I and III descriptors
2539 */ 2677 */
2540static int parse_audio_format_i(struct snd_usb_audio *chip, struct audioformat *fp, 2678static int parse_audio_format_i(struct snd_usb_audio *chip,
2541 int format, unsigned char *fmt) 2679 struct audioformat *fp,
2680 int format, void *_fmt,
2681 struct usb_host_interface *iface)
2542{ 2682{
2543 int pcm_format; 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;
2544 2687
2545 if (fmt[3] == USB_FORMAT_TYPE_III) { 2688 if (fmt->bFormatType == UAC_FORMAT_TYPE_III) {
2546 /* FIXME: the format type is really IECxxx 2689 /* FIXME: the format type is really IECxxx
2547 * but we give normal PCM format to get the existing 2690 * but we give normal PCM format to get the existing
2548 * apps working... 2691 * apps working...
@@ -2560,34 +2703,57 @@ static int parse_audio_format_i(struct snd_usb_audio *chip, struct audioformat *
2560 pcm_format = SNDRV_PCM_FORMAT_S16_LE; 2703 pcm_format = SNDRV_PCM_FORMAT_S16_LE;
2561 } 2704 }
2562 } else { 2705 } else {
2563 pcm_format = parse_audio_format_i_type(chip, fp, format, fmt); 2706 pcm_format = parse_audio_format_i_type(chip, fp, format, fmt, protocol);
2564 if (pcm_format < 0) 2707 if (pcm_format < 0)
2565 return -1; 2708 return -1;
2566 } 2709 }
2710
2567 fp->format = pcm_format; 2711 fp->format = pcm_format;
2568 fp->channels = fmt[4]; 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
2569 if (fp->channels < 1) { 2729 if (fp->channels < 1) {
2570 snd_printk(KERN_ERR "%d:%u:%d : invalid channels %d\n", 2730 snd_printk(KERN_ERR "%d:%u:%d : invalid channels %d\n",
2571 chip->dev->devnum, fp->iface, fp->altsetting, fp->channels); 2731 chip->dev->devnum, fp->iface, fp->altsetting, fp->channels);
2572 return -1; 2732 return -1;
2573 } 2733 }
2574 return parse_audio_format_rates(chip, fp, fmt, 7); 2734
2735 return ret;
2575} 2736}
2576 2737
2577/* 2738/*
2578 * prase the format type II descriptor 2739 * parse the format type II descriptor
2579 */ 2740 */
2580static int parse_audio_format_ii(struct snd_usb_audio *chip, struct audioformat *fp, 2741static int parse_audio_format_ii(struct snd_usb_audio *chip,
2581 int format, unsigned char *fmt) 2742 struct audioformat *fp,
2743 int format, void *_fmt,
2744 struct usb_host_interface *iface)
2582{ 2745{
2583 int brate, framesize; 2746 int brate, framesize, ret;
2747 struct usb_interface_descriptor *altsd = get_iface_desc(iface);
2748 int protocol = altsd->bInterfaceProtocol;
2749
2584 switch (format) { 2750 switch (format) {
2585 case USB_AUDIO_FORMAT_AC3: 2751 case UAC_FORMAT_TYPE_II_AC3:
2586 /* FIXME: there is no AC3 format defined yet */ 2752 /* FIXME: there is no AC3 format defined yet */
2587 // fp->format = SNDRV_PCM_FORMAT_AC3; 2753 // fp->format = SNDRV_PCM_FORMAT_AC3;
2588 fp->format = SNDRV_PCM_FORMAT_U8; /* temporarily hack to receive byte streams */ 2754 fp->format = SNDRV_PCM_FORMAT_U8; /* temporarily hack to receive byte streams */
2589 break; 2755 break;
2590 case USB_AUDIO_FORMAT_MPEG: 2756 case UAC_FORMAT_TYPE_II_MPEG:
2591 fp->format = SNDRV_PCM_FORMAT_MPEG; 2757 fp->format = SNDRV_PCM_FORMAT_MPEG;
2592 break; 2758 break;
2593 default: 2759 default:
@@ -2596,26 +2762,46 @@ static int parse_audio_format_ii(struct snd_usb_audio *chip, struct audioformat
2596 fp->format = SNDRV_PCM_FORMAT_MPEG; 2762 fp->format = SNDRV_PCM_FORMAT_MPEG;
2597 break; 2763 break;
2598 } 2764 }
2765
2599 fp->channels = 1; 2766 fp->channels = 1;
2600 brate = combine_word(&fmt[4]); /* fmt[4,5] : wMaxBitRate (in kbps) */ 2767
2601 framesize = combine_word(&fmt[6]); /* fmt[6,7]: wSamplesPerFrame */ 2768 switch (protocol) {
2602 snd_printd(KERN_INFO "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize); 2769 case UAC_VERSION_1: {
2603 fp->frame_size = framesize; 2770 struct uac_format_type_ii_discrete_descriptor *fmt = _fmt;
2604 return parse_audio_format_rates(chip, fp, fmt, 8); /* fmt[8..] sample rates */ 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;
2605} 2790}
2606 2791
2607static int parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp, 2792static int parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp,
2608 int format, unsigned char *fmt, int stream) 2793 int format, unsigned char *fmt, int stream,
2794 struct usb_host_interface *iface)
2609{ 2795{
2610 int err; 2796 int err;
2611 2797
2612 switch (fmt[3]) { 2798 switch (fmt[3]) {
2613 case USB_FORMAT_TYPE_I: 2799 case UAC_FORMAT_TYPE_I:
2614 case USB_FORMAT_TYPE_III: 2800 case UAC_FORMAT_TYPE_III:
2615 err = parse_audio_format_i(chip, fp, format, fmt); 2801 err = parse_audio_format_i(chip, fp, format, fmt, iface);
2616 break; 2802 break;
2617 case USB_FORMAT_TYPE_II: 2803 case UAC_FORMAT_TYPE_II:
2618 err = parse_audio_format_ii(chip, fp, format, fmt); 2804 err = parse_audio_format_ii(chip, fp, format, fmt, iface);
2619 break; 2805 break;
2620 default: 2806 default:
2621 snd_printd(KERN_INFO "%d:%u:%d : format type %d is not supported yet\n", 2807 snd_printd(KERN_INFO "%d:%u:%d : format type %d is not supported yet\n",
@@ -2633,7 +2819,7 @@ static int parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp
2633 if (chip->usb_id == USB_ID(0x041e, 0x3000) || 2819 if (chip->usb_id == USB_ID(0x041e, 0x3000) ||
2634 chip->usb_id == USB_ID(0x041e, 0x3020) || 2820 chip->usb_id == USB_ID(0x041e, 0x3020) ||
2635 chip->usb_id == USB_ID(0x041e, 0x3061)) { 2821 chip->usb_id == USB_ID(0x041e, 0x3061)) {
2636 if (fmt[3] == USB_FORMAT_TYPE_I && 2822 if (fmt[3] == UAC_FORMAT_TYPE_I &&
2637 fp->rates != SNDRV_PCM_RATE_48000 && 2823 fp->rates != SNDRV_PCM_RATE_48000 &&
2638 fp->rates != SNDRV_PCM_RATE_96000) 2824 fp->rates != SNDRV_PCM_RATE_96000)
2639 return -1; 2825 return -1;
@@ -2662,10 +2848,10 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
2662 struct usb_host_interface *alts; 2848 struct usb_host_interface *alts;
2663 struct usb_interface_descriptor *altsd; 2849 struct usb_interface_descriptor *altsd;
2664 int i, altno, err, stream; 2850 int i, altno, err, stream;
2665 int format; 2851 int format = 0, num_channels = 0;
2666 struct audioformat *fp = NULL; 2852 struct audioformat *fp = NULL;
2667 unsigned char *fmt, *csep; 2853 unsigned char *fmt, *csep;
2668 int num; 2854 int num, protocol;
2669 2855
2670 dev = chip->dev; 2856 dev = chip->dev;
2671 2857
@@ -2684,10 +2870,11 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
2684 for (i = 0; i < num; i++) { 2870 for (i = 0; i < num; i++) {
2685 alts = &iface->altsetting[i]; 2871 alts = &iface->altsetting[i];
2686 altsd = get_iface_desc(alts); 2872 altsd = get_iface_desc(alts);
2873 protocol = altsd->bInterfaceProtocol;
2687 /* skip invalid one */ 2874 /* skip invalid one */
2688 if ((altsd->bInterfaceClass != USB_CLASS_AUDIO && 2875 if ((altsd->bInterfaceClass != USB_CLASS_AUDIO &&
2689 altsd->bInterfaceClass != USB_CLASS_VENDOR_SPEC) || 2876 altsd->bInterfaceClass != USB_CLASS_VENDOR_SPEC) ||
2690 (altsd->bInterfaceSubClass != USB_SUBCLASS_AUDIO_STREAMING && 2877 (altsd->bInterfaceSubClass != USB_SUBCLASS_AUDIOSTREAMING &&
2691 altsd->bInterfaceSubClass != USB_SUBCLASS_VENDOR_SPEC) || 2878 altsd->bInterfaceSubClass != USB_SUBCLASS_VENDOR_SPEC) ||
2692 altsd->bNumEndpoints < 1 || 2879 altsd->bNumEndpoints < 1 ||
2693 le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) == 0) 2880 le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) == 0)
@@ -2708,30 +2895,65 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
2708 continue; 2895 continue;
2709 2896
2710 /* get audio formats */ 2897 /* get audio formats */
2711 fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, AS_GENERAL); 2898 switch (protocol) {
2712 if (!fmt) { 2899 case UAC_VERSION_1: {
2713 snd_printk(KERN_ERR "%d:%u:%d : AS_GENERAL descriptor not found\n", 2900 struct uac_as_header_descriptor_v1 *as =
2714 dev->devnum, iface_no, altno); 2901 snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL);
2715 continue; 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;
2716 } 2917 }
2717 2918
2718 if (fmt[0] < 7) { 2919 case UAC_VERSION_2: {
2719 snd_printk(KERN_ERR "%d:%u:%d : invalid AS_GENERAL desc\n", 2920 struct uac_as_header_descriptor_v2 *as =
2720 dev->devnum, iface_no, altno); 2921 snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL);
2721 continue; 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;
2722 } 2939 }
2723 2940
2724 format = (fmt[6] << 8) | fmt[5]; /* remember the format value */ 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 }
2725 2946
2726 /* get format type */ 2947 /* get format type */
2727 fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, FORMAT_TYPE); 2948 fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_FORMAT_TYPE);
2728 if (!fmt) { 2949 if (!fmt) {
2729 snd_printk(KERN_ERR "%d:%u:%d : no FORMAT_TYPE desc\n", 2950 snd_printk(KERN_ERR "%d:%u:%d : no UAC_FORMAT_TYPE desc\n",
2730 dev->devnum, iface_no, altno); 2951 dev->devnum, iface_no, altno);
2731 continue; 2952 continue;
2732 } 2953 }
2733 if (fmt[0] < 8) { 2954 if (((protocol == UAC_VERSION_1) && (fmt[0] < 8)) ||
2734 snd_printk(KERN_ERR "%d:%u:%d : invalid FORMAT_TYPE desc\n", 2955 ((protocol == UAC_VERSION_2) && (fmt[0] != 6))) {
2956 snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n",
2735 dev->devnum, iface_no, altno); 2957 dev->devnum, iface_no, altno);
2736 continue; 2958 continue;
2737 } 2959 }
@@ -2744,6 +2966,7 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
2744 if (fmt[4] == 1 && fmt[5] == 2 && altno == 2 && num == 3 && 2966 if (fmt[4] == 1 && fmt[5] == 2 && altno == 2 && num == 3 &&
2745 fp && fp->altsetting == 1 && fp->channels == 1 && 2967 fp && fp->altsetting == 1 && fp->channels == 1 &&
2746 fp->format == SNDRV_PCM_FORMAT_S16_LE && 2968 fp->format == SNDRV_PCM_FORMAT_S16_LE &&
2969 protocol == UAC_VERSION_1 &&
2747 le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) == 2970 le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) ==
2748 fp->maxpacksize * 2) 2971 fp->maxpacksize * 2)
2749 continue; 2972 continue;
@@ -2752,7 +2975,7 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
2752 /* Creamware Noah has this descriptor after the 2nd endpoint */ 2975 /* Creamware Noah has this descriptor after the 2nd endpoint */
2753 if (!csep && altsd->bNumEndpoints >= 2) 2976 if (!csep && altsd->bNumEndpoints >= 2)
2754 csep = snd_usb_find_desc(alts->endpoint[1].extra, alts->endpoint[1].extralen, NULL, USB_DT_CS_ENDPOINT); 2977 csep = snd_usb_find_desc(alts->endpoint[1].extra, alts->endpoint[1].extralen, NULL, USB_DT_CS_ENDPOINT);
2755 if (!csep || csep[0] < 7 || csep[2] != EP_GENERAL) { 2978 if (!csep || csep[0] < 7 || csep[2] != UAC_EP_GENERAL) {
2756 snd_printk(KERN_WARNING "%d:%u:%d : no or invalid" 2979 snd_printk(KERN_WARNING "%d:%u:%d : no or invalid"
2757 " class specific endpoint descriptor\n", 2980 " class specific endpoint descriptor\n",
2758 dev->devnum, iface_no, altno); 2981 dev->devnum, iface_no, altno);
@@ -2772,6 +2995,8 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
2772 fp->ep_attr = get_endpoint(alts, 0)->bmAttributes; 2995 fp->ep_attr = get_endpoint(alts, 0)->bmAttributes;
2773 fp->datainterval = parse_datainterval(chip, alts); 2996 fp->datainterval = parse_datainterval(chip, alts);
2774 fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize); 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;
2775 if (snd_usb_get_speed(dev) == USB_SPEED_HIGH) 3000 if (snd_usb_get_speed(dev) == USB_SPEED_HIGH)
2776 fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1) 3001 fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1)
2777 * (fp->maxpacksize & 0x7ff); 3002 * (fp->maxpacksize & 0x7ff);
@@ -2784,12 +3009,12 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
2784 /* Optoplay sets the sample rate attribute although 3009 /* Optoplay sets the sample rate attribute although
2785 * it seems not supporting it in fact. 3010 * it seems not supporting it in fact.
2786 */ 3011 */
2787 fp->attributes &= ~EP_CS_ATTR_SAMPLE_RATE; 3012 fp->attributes &= ~UAC_EP_CS_ATTR_SAMPLE_RATE;
2788 break; 3013 break;
2789 case USB_ID(0x041e, 0x3020): /* Creative SB Audigy 2 NX */ 3014 case USB_ID(0x041e, 0x3020): /* Creative SB Audigy 2 NX */
2790 case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */ 3015 case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
2791 /* doesn't set the sample rate attribute, but supports it */ 3016 /* doesn't set the sample rate attribute, but supports it */
2792 fp->attributes |= EP_CS_ATTR_SAMPLE_RATE; 3017 fp->attributes |= UAC_EP_CS_ATTR_SAMPLE_RATE;
2793 break; 3018 break;
2794 case USB_ID(0x047f, 0x0ca1): /* plantronics headset */ 3019 case USB_ID(0x047f, 0x0ca1): /* plantronics headset */
2795 case USB_ID(0x077d, 0x07af): /* Griffin iMic (note that there is 3020 case USB_ID(0x077d, 0x07af): /* Griffin iMic (note that there is
@@ -2798,16 +3023,16 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
2798 * plantronics headset and Griffin iMic have set adaptive-in 3023 * plantronics headset and Griffin iMic have set adaptive-in
2799 * although it's really not... 3024 * although it's really not...
2800 */ 3025 */
2801 fp->ep_attr &= ~EP_ATTR_MASK; 3026 fp->ep_attr &= ~USB_ENDPOINT_SYNCTYPE;
2802 if (stream == SNDRV_PCM_STREAM_PLAYBACK) 3027 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
2803 fp->ep_attr |= EP_ATTR_ADAPTIVE; 3028 fp->ep_attr |= USB_ENDPOINT_SYNC_ADAPTIVE;
2804 else 3029 else
2805 fp->ep_attr |= EP_ATTR_SYNC; 3030 fp->ep_attr |= USB_ENDPOINT_SYNC_SYNC;
2806 break; 3031 break;
2807 } 3032 }
2808 3033
2809 /* ok, let's parse further... */ 3034 /* ok, let's parse further... */
2810 if (parse_audio_format(chip, fp, format, fmt, stream) < 0) { 3035 if (parse_audio_format(chip, fp, format, fmt, stream, alts) < 0) {
2811 kfree(fp->rate_table); 3036 kfree(fp->rate_table);
2812 kfree(fp); 3037 kfree(fp);
2813 continue; 3038 continue;
@@ -2849,6 +3074,65 @@ static void snd_usb_stream_disconnect(struct list_head *head)
2849 } 3074 }
2850} 3075}
2851 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
2852/* 3136/*
2853 * parse audio control descriptor and create pcm/midi streams 3137 * parse audio control descriptor and create pcm/midi streams
2854 */ 3138 */
@@ -2856,65 +3140,81 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
2856{ 3140{
2857 struct usb_device *dev = chip->dev; 3141 struct usb_device *dev = chip->dev;
2858 struct usb_host_interface *host_iface; 3142 struct usb_host_interface *host_iface;
2859 struct usb_interface *iface; 3143 struct usb_interface_descriptor *altsd;
2860 unsigned char *p1; 3144 void *control_header;
2861 int i, j; 3145 int i, protocol;
2862 3146
2863 /* find audiocontrol interface */ 3147 /* find audiocontrol interface */
2864 host_iface = &usb_ifnum_to_if(dev, ctrlif)->altsetting[0]; 3148 host_iface = &usb_ifnum_to_if(dev, ctrlif)->altsetting[0];
2865 if (!(p1 = snd_usb_find_csint_desc(host_iface->extra, host_iface->extralen, NULL, HEADER))) { 3149 control_header = snd_usb_find_csint_desc(host_iface->extra,
2866 snd_printk(KERN_ERR "cannot find HEADER\n"); 3150 host_iface->extralen,
2867 return -EINVAL; 3151 NULL, UAC_HEADER);
2868 } 3152 altsd = get_iface_desc(host_iface);
2869 if (! p1[7] || p1[0] < 8 + p1[7]) { 3153 protocol = altsd->bInterfaceProtocol;
2870 snd_printk(KERN_ERR "invalid HEADER\n"); 3154
3155 if (!control_header) {
3156 snd_printk(KERN_ERR "cannot find UAC_HEADER\n");
2871 return -EINVAL; 3157 return -EINVAL;
2872 } 3158 }
2873 3159
2874 /* 3160 switch (protocol) {
2875 * parse all USB audio streaming interfaces 3161 case UAC_VERSION_1: {
2876 */ 3162 struct uac_ac_header_descriptor_v1 *h1 = control_header;
2877 for (i = 0; i < p1[7]; i++) { 3163
2878 struct usb_host_interface *alts; 3164 if (!h1->bInCollection) {
2879 struct usb_interface_descriptor *altsd; 3165 snd_printk(KERN_INFO "skipping empty audio interface (v1)\n");
2880 j = p1[8 + i]; 3166 return -EINVAL;
2881 iface = usb_ifnum_to_if(dev, j);
2882 if (!iface) {
2883 snd_printk(KERN_ERR "%d:%u:%d : does not exist\n",
2884 dev->devnum, ctrlif, j);
2885 continue;
2886 }
2887 if (usb_interface_claimed(iface)) {
2888 snd_printdd(KERN_INFO "%d:%d:%d: skipping, already claimed\n", dev->devnum, ctrlif, j);
2889 continue;
2890 } 3167 }
2891 alts = &iface->altsetting[0]; 3168
2892 altsd = get_iface_desc(alts); 3169 if (h1->bLength < sizeof(*h1) + h1->bInCollection) {
2893 if ((altsd->bInterfaceClass == USB_CLASS_AUDIO || 3170 snd_printk(KERN_ERR "invalid UAC_HEADER (v1)\n");
2894 altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC) && 3171 return -EINVAL;
2895 altsd->bInterfaceSubClass == USB_SUBCLASS_MIDI_STREAMING) {
2896 if (snd_usb_create_midi_interface(chip, iface, NULL) < 0) {
2897 snd_printk(KERN_ERR "%d:%u:%d: cannot create sequencer device\n", dev->devnum, ctrlif, j);
2898 continue;
2899 }
2900 usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L);
2901 continue;
2902 } 3172 }
2903 if ((altsd->bInterfaceClass != USB_CLASS_AUDIO && 3173
2904 altsd->bInterfaceClass != USB_CLASS_VENDOR_SPEC) || 3174 for (i = 0; i < h1->bInCollection; i++)
2905 altsd->bInterfaceSubClass != USB_SUBCLASS_AUDIO_STREAMING) { 3175 snd_usb_create_stream(chip, ctrlif, h1->baInterfaceNr[i]);
2906 snd_printdd(KERN_ERR "%d:%u:%d: skipping non-supported interface %d\n", dev->devnum, ctrlif, j, altsd->bInterfaceClass); 3176
2907 /* skip non-supported classes */ 3177 break;
2908 continue; 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;
2909 } 3188 }
2910 if (snd_usb_get_speed(dev) == USB_SPEED_LOW) { 3189
2911 snd_printk(KERN_ERR "low speed audio streaming not supported\n"); 3190 /* FIXME: for now, we expect there is at least one clock source
2912 continue; 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;
2913 } 3201 }
2914 if (! parse_audio_endpoints(chip, j)) { 3202
2915 usb_set_interface(dev, j, 0); /* reset the current interface */ 3203 chip->clock_id = cs->bClockID;
2916 usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L); 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);
2917 } 3210 }
3211
3212 break;
3213 }
3214
3215 default:
3216 snd_printk(KERN_ERR "unknown protocol version 0x%02x\n", protocol);
3217 return -EINVAL;
2918 } 3218 }
2919 3219
2920 return 0; 3220 return 0;
@@ -3005,7 +3305,7 @@ static int create_uaxx_quirk(struct snd_usb_audio *chip,
3005 static const struct audioformat ua_format = { 3305 static const struct audioformat ua_format = {
3006 .format = SNDRV_PCM_FORMAT_S24_3LE, 3306 .format = SNDRV_PCM_FORMAT_S24_3LE,
3007 .channels = 2, 3307 .channels = 2,
3008 .fmt_type = USB_FORMAT_TYPE_I, 3308 .fmt_type = UAC_FORMAT_TYPE_I,
3009 .altsetting = 1, 3309 .altsetting = 1,
3010 .altset_idx = 1, 3310 .altset_idx = 1,
3011 .rates = SNDRV_PCM_RATE_CONTINUOUS, 3311 .rates = SNDRV_PCM_RATE_CONTINUOUS,
@@ -3038,12 +3338,11 @@ static int create_uaxx_quirk(struct snd_usb_audio *chip,
3038 .type = QUIRK_MIDI_FIXED_ENDPOINT, 3338 .type = QUIRK_MIDI_FIXED_ENDPOINT,
3039 .data = &uaxx_ep 3339 .data = &uaxx_ep
3040 }; 3340 };
3041 if (chip->usb_id == USB_ID(0x0582, 0x002b)) 3341 const struct snd_usb_audio_quirk *quirk =
3042 return snd_usb_create_midi_interface(chip, iface, 3342 chip->usb_id == USB_ID(0x0582, 0x002b)
3043 &ua700_quirk); 3343 ? &ua700_quirk : &uaxx_quirk;
3044 else 3344 return snd_usbmidi_create(chip->card, iface,
3045 return snd_usb_create_midi_interface(chip, iface, 3345 &chip->midi_list, quirk);
3046 &uaxx_quirk);
3047 } 3346 }
3048 3347
3049 if (altsd->bNumEndpoints != 1) 3348 if (altsd->bNumEndpoints != 1)
@@ -3089,111 +3388,6 @@ static int create_uaxx_quirk(struct snd_usb_audio *chip,
3089 return 0; 3388 return 0;
3090} 3389}
3091 3390
3092/*
3093 * Create a stream for an Edirol UA-1000 interface.
3094 */
3095static int create_ua1000_quirk(struct snd_usb_audio *chip,
3096 struct usb_interface *iface,
3097 const struct snd_usb_audio_quirk *quirk)
3098{
3099 static const struct audioformat ua1000_format = {
3100 .format = SNDRV_PCM_FORMAT_S32_LE,
3101 .fmt_type = USB_FORMAT_TYPE_I,
3102 .altsetting = 1,
3103 .altset_idx = 1,
3104 .attributes = 0,
3105 .rates = SNDRV_PCM_RATE_CONTINUOUS,
3106 };
3107 struct usb_host_interface *alts;
3108 struct usb_interface_descriptor *altsd;
3109 struct audioformat *fp;
3110 int stream, err;
3111
3112 if (iface->num_altsetting != 2)
3113 return -ENXIO;
3114 alts = &iface->altsetting[1];
3115 altsd = get_iface_desc(alts);
3116 if (alts->extralen != 11 || alts->extra[1] != USB_DT_CS_INTERFACE ||
3117 altsd->bNumEndpoints != 1)
3118 return -ENXIO;
3119
3120 fp = kmemdup(&ua1000_format, sizeof(*fp), GFP_KERNEL);
3121 if (!fp)
3122 return -ENOMEM;
3123
3124 fp->channels = alts->extra[4];
3125 fp->iface = altsd->bInterfaceNumber;
3126 fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress;
3127 fp->ep_attr = get_endpoint(alts, 0)->bmAttributes;
3128 fp->datainterval = parse_datainterval(chip, alts);
3129 fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
3130 fp->rate_max = fp->rate_min = combine_triple(&alts->extra[8]);
3131
3132 stream = (fp->endpoint & USB_DIR_IN)
3133 ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
3134 err = add_audio_endpoint(chip, stream, fp);
3135 if (err < 0) {
3136 kfree(fp);
3137 return err;
3138 }
3139 /* FIXME: playback must be synchronized to capture */
3140 usb_set_interface(chip->dev, fp->iface, 0);
3141 return 0;
3142}
3143
3144/*
3145 * Create a stream for an Edirol UA-101 interface.
3146 * Copy, paste and modify from Edirol UA-1000
3147 */
3148static int create_ua101_quirk(struct snd_usb_audio *chip,
3149 struct usb_interface *iface,
3150 const struct snd_usb_audio_quirk *quirk)
3151{
3152 static const struct audioformat ua101_format = {
3153 .format = SNDRV_PCM_FORMAT_S32_LE,
3154 .fmt_type = USB_FORMAT_TYPE_I,
3155 .altsetting = 1,
3156 .altset_idx = 1,
3157 .attributes = 0,
3158 .rates = SNDRV_PCM_RATE_CONTINUOUS,
3159 };
3160 struct usb_host_interface *alts;
3161 struct usb_interface_descriptor *altsd;
3162 struct audioformat *fp;
3163 int stream, err;
3164
3165 if (iface->num_altsetting != 2)
3166 return -ENXIO;
3167 alts = &iface->altsetting[1];
3168 altsd = get_iface_desc(alts);
3169 if (alts->extralen != 18 || alts->extra[1] != USB_DT_CS_INTERFACE ||
3170 altsd->bNumEndpoints != 1)
3171 return -ENXIO;
3172
3173 fp = kmemdup(&ua101_format, sizeof(*fp), GFP_KERNEL);
3174 if (!fp)
3175 return -ENOMEM;
3176
3177 fp->channels = alts->extra[11];
3178 fp->iface = altsd->bInterfaceNumber;
3179 fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress;
3180 fp->ep_attr = get_endpoint(alts, 0)->bmAttributes;
3181 fp->datainterval = parse_datainterval(chip, alts);
3182 fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
3183 fp->rate_max = fp->rate_min = combine_triple(&alts->extra[15]);
3184
3185 stream = (fp->endpoint & USB_DIR_IN)
3186 ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
3187 err = add_audio_endpoint(chip, stream, fp);
3188 if (err < 0) {
3189 kfree(fp);
3190 return err;
3191 }
3192 /* FIXME: playback must be synchronized to capture */
3193 usb_set_interface(chip->dev, fp->iface, 0);
3194 return 0;
3195}
3196
3197static int snd_usb_create_quirk(struct snd_usb_audio *chip, 3391static int snd_usb_create_quirk(struct snd_usb_audio *chip,
3198 struct usb_interface *iface, 3392 struct usb_interface *iface,
3199 const struct snd_usb_audio_quirk *quirk); 3393 const struct snd_usb_audio_quirk *quirk);
@@ -3231,6 +3425,18 @@ static int ignore_interface_quirk(struct snd_usb_audio *chip,
3231 return 0; 3425 return 0;
3232} 3426}
3233 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
3234 3440
3235/* 3441/*
3236 * boot quirks 3442 * boot quirks
@@ -3326,6 +3532,32 @@ static int snd_usb_cm6206_boot_quirk(struct usb_device *dev)
3326} 3532}
3327 3533
3328/* 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/*
3329 * Setup quirks 3561 * Setup quirks
3330 */ 3562 */
3331#define AUDIOPHILE_SET 0x01 /* if set, parse device_setup */ 3563#define AUDIOPHILE_SET 0x01 /* if set, parse device_setup */
@@ -3370,6 +3602,13 @@ static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip,
3370 return 0; /* keep this altsetting */ 3602 return 0; /* keep this altsetting */
3371} 3603}
3372 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
3373/* 3612/*
3374 * audio-interface quirks 3613 * audio-interface quirks
3375 * 3614 *
@@ -3387,19 +3626,18 @@ static int snd_usb_create_quirk(struct snd_usb_audio *chip,
3387 static const quirk_func_t quirk_funcs[] = { 3626 static const quirk_func_t quirk_funcs[] = {
3388 [QUIRK_IGNORE_INTERFACE] = ignore_interface_quirk, 3627 [QUIRK_IGNORE_INTERFACE] = ignore_interface_quirk,
3389 [QUIRK_COMPOSITE] = create_composite_quirk, 3628 [QUIRK_COMPOSITE] = create_composite_quirk,
3390 [QUIRK_MIDI_STANDARD_INTERFACE] = snd_usb_create_midi_interface, 3629 [QUIRK_MIDI_STANDARD_INTERFACE] = create_any_midi_quirk,
3391 [QUIRK_MIDI_FIXED_ENDPOINT] = snd_usb_create_midi_interface, 3630 [QUIRK_MIDI_FIXED_ENDPOINT] = create_any_midi_quirk,
3392 [QUIRK_MIDI_YAMAHA] = snd_usb_create_midi_interface, 3631 [QUIRK_MIDI_YAMAHA] = create_any_midi_quirk,
3393 [QUIRK_MIDI_MIDIMAN] = snd_usb_create_midi_interface, 3632 [QUIRK_MIDI_MIDIMAN] = create_any_midi_quirk,
3394 [QUIRK_MIDI_NOVATION] = snd_usb_create_midi_interface, 3633 [QUIRK_MIDI_NOVATION] = create_any_midi_quirk,
3395 [QUIRK_MIDI_FASTLANE] = snd_usb_create_midi_interface, 3634 [QUIRK_MIDI_FASTLANE] = create_any_midi_quirk,
3396 [QUIRK_MIDI_EMAGIC] = snd_usb_create_midi_interface, 3635 [QUIRK_MIDI_EMAGIC] = create_any_midi_quirk,
3397 [QUIRK_MIDI_CME] = snd_usb_create_midi_interface, 3636 [QUIRK_MIDI_CME] = create_any_midi_quirk,
3398 [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk, 3637 [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk,
3399 [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk, 3638 [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk,
3400 [QUIRK_AUDIO_EDIROL_UA1000] = create_ua1000_quirk, 3639 [QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk,
3401 [QUIRK_AUDIO_EDIROL_UA101] = create_ua101_quirk, 3640 [QUIRK_AUDIO_ALIGN_TRANSFER] = create_align_transfer_quirk
3402 [QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk
3403 }; 3641 };
3404 3642
3405 if (quirk->type < QUIRK_TYPE_COUNT) { 3643 if (quirk->type < QUIRK_TYPE_COUNT) {
@@ -3588,7 +3826,6 @@ static void *snd_usb_audio_probe(struct usb_device *dev,
3588 ifnum = get_iface_desc(alts)->bInterfaceNumber; 3826 ifnum = get_iface_desc(alts)->bInterfaceNumber;
3589 id = USB_ID(le16_to_cpu(dev->descriptor.idVendor), 3827 id = USB_ID(le16_to_cpu(dev->descriptor.idVendor),
3590 le16_to_cpu(dev->descriptor.idProduct)); 3828 le16_to_cpu(dev->descriptor.idProduct));
3591
3592 if (quirk && quirk->ifnum >= 0 && ifnum != quirk->ifnum) 3829 if (quirk && quirk->ifnum >= 0 && ifnum != quirk->ifnum)
3593 goto __err_val; 3830 goto __err_val;
3594 3831
@@ -3616,6 +3853,12 @@ static void *snd_usb_audio_probe(struct usb_device *dev,
3616 goto __err_val; 3853 goto __err_val;
3617 } 3854 }
3618 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
3619 /* 3862 /*
3620 * found a config. now register to ALSA 3863 * found a config. now register to ALSA
3621 */ 3864 */
@@ -3653,6 +3896,7 @@ static void *snd_usb_audio_probe(struct usb_device *dev,
3653 } 3896 }
3654 } 3897 }
3655 3898
3899 chip->txfr_quirk = 0;
3656 err = 1; /* continue */ 3900 err = 1; /* continue */
3657 if (quirk && quirk->ifnum != QUIRK_NO_INTERFACE) { 3901 if (quirk && quirk->ifnum != QUIRK_NO_INTERFACE) {
3658 /* need some special handlings */ 3902 /* need some special handlings */
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
index e9a3a9dca15c..42c299cbf63a 100644
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -21,93 +21,6 @@
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */ 22 */
23 23
24
25/*
26 */
27
28#define USB_SUBCLASS_AUDIO_CONTROL 0x01
29#define USB_SUBCLASS_AUDIO_STREAMING 0x02
30#define USB_SUBCLASS_MIDI_STREAMING 0x03
31#define USB_SUBCLASS_VENDOR_SPEC 0xff
32
33#define HEADER 0x01
34#define INPUT_TERMINAL 0x02
35#define OUTPUT_TERMINAL 0x03
36#define MIXER_UNIT 0x04
37#define SELECTOR_UNIT 0x05
38#define FEATURE_UNIT 0x06
39#define PROCESSING_UNIT 0x07
40#define EXTENSION_UNIT 0x08
41
42#define AS_GENERAL 0x01
43#define FORMAT_TYPE 0x02
44#define FORMAT_SPECIFIC 0x03
45
46#define EP_GENERAL 0x01
47
48#define MS_GENERAL 0x01
49#define MIDI_IN_JACK 0x02
50#define MIDI_OUT_JACK 0x03
51
52/* endpoint attributes */
53#define EP_ATTR_MASK 0x0c
54#define EP_ATTR_ASYNC 0x04
55#define EP_ATTR_ADAPTIVE 0x08
56#define EP_ATTR_SYNC 0x0c
57
58/* cs endpoint attributes */
59#define EP_CS_ATTR_SAMPLE_RATE 0x01
60#define EP_CS_ATTR_PITCH_CONTROL 0x02
61#define EP_CS_ATTR_FILL_MAX 0x80
62
63/* Audio Class specific Request Codes */
64
65#define SET_CUR 0x01
66#define GET_CUR 0x81
67#define SET_MIN 0x02
68#define GET_MIN 0x82
69#define SET_MAX 0x03
70#define GET_MAX 0x83
71#define SET_RES 0x04
72#define GET_RES 0x84
73#define SET_MEM 0x05
74#define GET_MEM 0x85
75#define GET_STAT 0xff
76
77/* Terminal Control Selectors */
78
79#define COPY_PROTECT_CONTROL 0x01
80
81/* Endpoint Control Selectors */
82
83#define SAMPLING_FREQ_CONTROL 0x01
84#define PITCH_CONTROL 0x02
85
86/* Format Types */
87#define USB_FORMAT_TYPE_I 0x01
88#define USB_FORMAT_TYPE_II 0x02
89#define USB_FORMAT_TYPE_III 0x03
90
91/* type I */
92#define USB_AUDIO_FORMAT_PCM 0x01
93#define USB_AUDIO_FORMAT_PCM8 0x02
94#define USB_AUDIO_FORMAT_IEEE_FLOAT 0x03
95#define USB_AUDIO_FORMAT_ALAW 0x04
96#define USB_AUDIO_FORMAT_MU_LAW 0x05
97
98/* type II */
99#define USB_AUDIO_FORMAT_MPEG 0x1001
100#define USB_AUDIO_FORMAT_AC3 0x1002
101
102/* type III */
103#define USB_AUDIO_FORMAT_IEC1937_AC3 0x2001
104#define USB_AUDIO_FORMAT_IEC1937_MPEG1_LAYER1 0x2002
105#define USB_AUDIO_FORMAT_IEC1937_MPEG2_NOEXT 0x2003
106#define USB_AUDIO_FORMAT_IEC1937_MPEG2_EXT 0x2004
107#define USB_AUDIO_FORMAT_IEC1937_MPEG2_LAYER1_LS 0x2005
108#define USB_AUDIO_FORMAT_IEC1937_MPEG2_LAYER23_LS 0x2006
109
110
111/* maximum number of endpoints per interface */ 24/* maximum number of endpoints per interface */
112#define MIDI_MAX_ENDPOINTS 2 25#define MIDI_MAX_ENDPOINTS 2
113 26
@@ -125,14 +38,17 @@ struct snd_usb_audio {
125 struct snd_card *card; 38 struct snd_card *card;
126 u32 usb_id; 39 u32 usb_id;
127 int shutdown; 40 int shutdown;
41 unsigned int txfr_quirk:1; /* Subframe boundaries on transfers */
128 int num_interfaces; 42 int num_interfaces;
129 int num_suspended_intf; 43 int num_suspended_intf;
130 44
45 /* for audio class v2 */
46 int clock_id;
47
131 struct list_head pcm_list; /* list of pcm streams */ 48 struct list_head pcm_list; /* list of pcm streams */
132 int pcm_devs; 49 int pcm_devs;
133 50
134 struct list_head midi_list; /* list of midi interfaces */ 51 struct list_head midi_list; /* list of midi interfaces */
135 int next_midi_device;
136 52
137 struct list_head mixer_list; /* list of mixer interfaces */ 53 struct list_head mixer_list; /* list of mixer interfaces */
138}; 54};
@@ -159,9 +75,8 @@ enum quirk_type {
159 QUIRK_MIDI_US122L, 75 QUIRK_MIDI_US122L,
160 QUIRK_AUDIO_STANDARD_INTERFACE, 76 QUIRK_AUDIO_STANDARD_INTERFACE,
161 QUIRK_AUDIO_FIXED_ENDPOINT, 77 QUIRK_AUDIO_FIXED_ENDPOINT,
162 QUIRK_AUDIO_EDIROL_UA1000,
163 QUIRK_AUDIO_EDIROL_UA101,
164 QUIRK_AUDIO_EDIROL_UAXX, 78 QUIRK_AUDIO_EDIROL_UAXX,
79 QUIRK_AUDIO_ALIGN_TRANSFER,
165 80
166 QUIRK_TYPE_COUNT 81 QUIRK_TYPE_COUNT
167}; 82};
@@ -196,7 +111,7 @@ struct snd_usb_midi_endpoint_info {
196 111
197/* for QUIRK_AUDIO/MIDI_STANDARD_INTERFACE, data is NULL */ 112/* for QUIRK_AUDIO/MIDI_STANDARD_INTERFACE, data is NULL */
198 113
199/* for QUIRK_AUDIO_EDIROL_UA700_UA25/UA1000, data is NULL */ 114/* for QUIRK_AUDIO_EDIROL_UAXX, data is NULL */
200 115
201/* for QUIRK_IGNORE_INTERFACE, data is NULL */ 116/* for QUIRK_IGNORE_INTERFACE, data is NULL */
202 117
@@ -210,6 +125,16 @@ struct snd_usb_midi_endpoint_info {
210/* 125/*
211 */ 126 */
212 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
213#define combine_word(s) ((*(s)) | ((unsigned int)(s)[1] << 8)) 138#define combine_word(s) ((*(s)) | ((unsigned int)(s)[1] << 8))
214#define combine_triple(s) (combine_word(s) | ((unsigned int)(s)[2] << 16)) 139#define combine_triple(s) (combine_word(s) | ((unsigned int)(s)[2] << 16))
215#define combine_quad(s) (combine_triple(s) | ((unsigned int)(s)[3] << 24)) 140#define combine_quad(s) (combine_triple(s) | ((unsigned int)(s)[3] << 24))
@@ -227,12 +152,17 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
227 int ignore_error); 152 int ignore_error);
228void snd_usb_mixer_disconnect(struct list_head *p); 153void snd_usb_mixer_disconnect(struct list_head *p);
229 154
230int snd_usb_create_midi_interface(struct snd_usb_audio *chip, struct usb_interface *iface, 155int snd_usbmidi_create(struct snd_card *card,
231 const struct snd_usb_audio_quirk *quirk); 156 struct usb_interface *iface,
157 struct list_head *midi_list,
158 const struct snd_usb_audio_quirk *quirk);
232void snd_usbmidi_input_stop(struct list_head* p); 159void snd_usbmidi_input_stop(struct list_head* p);
233void snd_usbmidi_input_start(struct list_head* p); 160void snd_usbmidi_input_start(struct list_head* p);
234void snd_usbmidi_disconnect(struct list_head *p); 161void snd_usbmidi_disconnect(struct list_head *p);
235 162
163void snd_emuusb_set_samplerate(struct snd_usb_audio *chip,
164 unsigned char samplerate_id);
165
236/* 166/*
237 * retrieve usb_interface descriptor from the host interface 167 * retrieve usb_interface descriptor from the host interface
238 * (conditional for compatibility with the older API) 168 * (conditional for compatibility with the older API)
diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c
index 0eff19ceb7e1..9e28b20cb2ce 100644
--- a/sound/usb/usbmidi.c
+++ b/sound/usb/usbmidi.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * usbmidi.c - ALSA USB MIDI driver 2 * usbmidi.c - ALSA USB MIDI driver
3 * 3 *
4 * Copyright (c) 2002-2007 Clemens Ladisch 4 * Copyright (c) 2002-2009 Clemens Ladisch
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Based on the OSS usb-midi driver by NAGANO Daisuke, 7 * Based on the OSS usb-midi driver by NAGANO Daisuke,
@@ -46,7 +46,10 @@
46#include <linux/timer.h> 46#include <linux/timer.h>
47#include <linux/usb.h> 47#include <linux/usb.h>
48#include <linux/wait.h> 48#include <linux/wait.h>
49#include <linux/usb/audio.h>
50
49#include <sound/core.h> 51#include <sound/core.h>
52#include <sound/control.h>
50#include <sound/rawmidi.h> 53#include <sound/rawmidi.h>
51#include <sound/asequencer.h> 54#include <sound/asequencer.h>
52#include "usbaudio.h" 55#include "usbaudio.h"
@@ -101,7 +104,8 @@ struct usb_protocol_ops {
101}; 104};
102 105
103struct snd_usb_midi { 106struct snd_usb_midi {
104 struct snd_usb_audio *chip; 107 struct usb_device *dev;
108 struct snd_card *card;
105 struct usb_interface *iface; 109 struct usb_interface *iface;
106 const struct snd_usb_audio_quirk *quirk; 110 const struct snd_usb_audio_quirk *quirk;
107 struct snd_rawmidi *rmidi; 111 struct snd_rawmidi *rmidi;
@@ -109,13 +113,19 @@ struct snd_usb_midi {
109 struct list_head list; 113 struct list_head list;
110 struct timer_list error_timer; 114 struct timer_list error_timer;
111 spinlock_t disc_lock; 115 spinlock_t disc_lock;
116 struct mutex mutex;
117 u32 usb_id;
118 int next_midi_device;
112 119
113 struct snd_usb_midi_endpoint { 120 struct snd_usb_midi_endpoint {
114 struct snd_usb_midi_out_endpoint *out; 121 struct snd_usb_midi_out_endpoint *out;
115 struct snd_usb_midi_in_endpoint *in; 122 struct snd_usb_midi_in_endpoint *in;
116 } endpoints[MIDI_MAX_ENDPOINTS]; 123 } endpoints[MIDI_MAX_ENDPOINTS];
117 unsigned long input_triggered; 124 unsigned long input_triggered;
125 unsigned int opened;
118 unsigned char disconnected; 126 unsigned char disconnected;
127
128 struct snd_kcontrol *roland_load_ctl;
119}; 129};
120 130
121struct snd_usb_midi_out_endpoint { 131struct snd_usb_midi_out_endpoint {
@@ -255,7 +265,7 @@ static void snd_usbmidi_in_urb_complete(struct urb* urb)
255 } 265 }
256 } 266 }
257 267
258 urb->dev = ep->umidi->chip->dev; 268 urb->dev = ep->umidi->dev;
259 snd_usbmidi_submit_urb(urb, GFP_ATOMIC); 269 snd_usbmidi_submit_urb(urb, GFP_ATOMIC);
260} 270}
261 271
@@ -296,7 +306,7 @@ static void snd_usbmidi_do_output(struct snd_usb_midi_out_endpoint* ep)
296 unsigned long flags; 306 unsigned long flags;
297 307
298 spin_lock_irqsave(&ep->buffer_lock, flags); 308 spin_lock_irqsave(&ep->buffer_lock, flags);
299 if (ep->umidi->chip->shutdown) { 309 if (ep->umidi->disconnected) {
300 spin_unlock_irqrestore(&ep->buffer_lock, flags); 310 spin_unlock_irqrestore(&ep->buffer_lock, flags);
301 return; 311 return;
302 } 312 }
@@ -312,7 +322,7 @@ static void snd_usbmidi_do_output(struct snd_usb_midi_out_endpoint* ep)
312 322
313 dump_urb("sending", urb->transfer_buffer, 323 dump_urb("sending", urb->transfer_buffer,
314 urb->transfer_buffer_length); 324 urb->transfer_buffer_length);
315 urb->dev = ep->umidi->chip->dev; 325 urb->dev = ep->umidi->dev;
316 if (snd_usbmidi_submit_urb(urb, GFP_ATOMIC) < 0) 326 if (snd_usbmidi_submit_urb(urb, GFP_ATOMIC) < 0)
317 break; 327 break;
318 ep->active_urbs |= 1 << urb_index; 328 ep->active_urbs |= 1 << urb_index;
@@ -349,7 +359,7 @@ static void snd_usbmidi_error_timer(unsigned long data)
349 if (in && in->error_resubmit) { 359 if (in && in->error_resubmit) {
350 in->error_resubmit = 0; 360 in->error_resubmit = 0;
351 for (j = 0; j < INPUT_URBS; ++j) { 361 for (j = 0; j < INPUT_URBS; ++j) {
352 in->urbs[j]->dev = umidi->chip->dev; 362 in->urbs[j]->dev = umidi->dev;
353 snd_usbmidi_submit_urb(in->urbs[j], GFP_ATOMIC); 363 snd_usbmidi_submit_urb(in->urbs[j], GFP_ATOMIC);
354 } 364 }
355 } 365 }
@@ -369,7 +379,7 @@ static int send_bulk_static_data(struct snd_usb_midi_out_endpoint* ep,
369 return -ENOMEM; 379 return -ENOMEM;
370 dump_urb("sending", buf, len); 380 dump_urb("sending", buf, len);
371 if (ep->urbs[0].urb) 381 if (ep->urbs[0].urb)
372 err = usb_bulk_msg(ep->umidi->chip->dev, ep->urbs[0].urb->pipe, 382 err = usb_bulk_msg(ep->umidi->dev, ep->urbs[0].urb->pipe,
373 buf, len, NULL, 250); 383 buf, len, NULL, 250);
374 kfree(buf); 384 kfree(buf);
375 return err; 385 return err;
@@ -724,8 +734,7 @@ static void snd_usbmidi_us122l_output(struct snd_usb_midi_out_endpoint *ep,
724 734
725 if (!ep->ports[0].active) 735 if (!ep->ports[0].active)
726 return; 736 return;
727 count = snd_usb_get_speed(ep->umidi->chip->dev) == USB_SPEED_HIGH 737 count = snd_usb_get_speed(ep->umidi->dev) == USB_SPEED_HIGH ? 1 : 2;
728 ? 1 : 2;
729 count = snd_rawmidi_transmit(ep->ports[0].substream, 738 count = snd_rawmidi_transmit(ep->ports[0].substream,
730 urb->transfer_buffer, 739 urb->transfer_buffer,
731 count); 740 count);
@@ -879,6 +888,50 @@ static struct usb_protocol_ops snd_usbmidi_emagic_ops = {
879}; 888};
880 889
881 890
891static void update_roland_altsetting(struct snd_usb_midi* umidi)
892{
893 struct usb_interface *intf;
894 struct usb_host_interface *hostif;
895 struct usb_interface_descriptor *intfd;
896 int is_light_load;
897
898 intf = umidi->iface;
899 is_light_load = intf->cur_altsetting != intf->altsetting;
900 if (umidi->roland_load_ctl->private_value == is_light_load)
901 return;
902 hostif = &intf->altsetting[umidi->roland_load_ctl->private_value];
903 intfd = get_iface_desc(hostif);
904 snd_usbmidi_input_stop(&umidi->list);
905 usb_set_interface(umidi->dev, intfd->bInterfaceNumber,
906 intfd->bAlternateSetting);
907 snd_usbmidi_input_start(&umidi->list);
908}
909
910static void substream_open(struct snd_rawmidi_substream *substream, int open)
911{
912 struct snd_usb_midi* umidi = substream->rmidi->private_data;
913 struct snd_kcontrol *ctl;
914
915 mutex_lock(&umidi->mutex);
916 if (open) {
917 if (umidi->opened++ == 0 && umidi->roland_load_ctl) {
918 ctl = umidi->roland_load_ctl;
919 ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
920 snd_ctl_notify(umidi->card,
921 SNDRV_CTL_EVENT_MASK_INFO, &ctl->id);
922 update_roland_altsetting(umidi);
923 }
924 } else {
925 if (--umidi->opened == 0 && umidi->roland_load_ctl) {
926 ctl = umidi->roland_load_ctl;
927 ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
928 snd_ctl_notify(umidi->card,
929 SNDRV_CTL_EVENT_MASK_INFO, &ctl->id);
930 }
931 }
932 mutex_unlock(&umidi->mutex);
933}
934
882static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream) 935static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream)
883{ 936{
884 struct snd_usb_midi* umidi = substream->rmidi->private_data; 937 struct snd_usb_midi* umidi = substream->rmidi->private_data;
@@ -898,11 +951,13 @@ static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream)
898 } 951 }
899 substream->runtime->private_data = port; 952 substream->runtime->private_data = port;
900 port->state = STATE_UNKNOWN; 953 port->state = STATE_UNKNOWN;
954 substream_open(substream, 1);
901 return 0; 955 return 0;
902} 956}
903 957
904static int snd_usbmidi_output_close(struct snd_rawmidi_substream *substream) 958static int snd_usbmidi_output_close(struct snd_rawmidi_substream *substream)
905{ 959{
960 substream_open(substream, 0);
906 return 0; 961 return 0;
907} 962}
908 963
@@ -912,7 +967,7 @@ static void snd_usbmidi_output_trigger(struct snd_rawmidi_substream *substream,
912 967
913 port->active = up; 968 port->active = up;
914 if (up) { 969 if (up) {
915 if (port->ep->umidi->chip->shutdown) { 970 if (port->ep->umidi->disconnected) {
916 /* gobble up remaining bytes to prevent wait in 971 /* gobble up remaining bytes to prevent wait in
917 * snd_rawmidi_drain_output */ 972 * snd_rawmidi_drain_output */
918 while (!snd_rawmidi_transmit_empty(substream)) 973 while (!snd_rawmidi_transmit_empty(substream))
@@ -931,6 +986,8 @@ static void snd_usbmidi_output_drain(struct snd_rawmidi_substream *substream)
931 DEFINE_WAIT(wait); 986 DEFINE_WAIT(wait);
932 long timeout = msecs_to_jiffies(50); 987 long timeout = msecs_to_jiffies(50);
933 988
989 if (ep->umidi->disconnected)
990 return;
934 /* 991 /*
935 * The substream buffer is empty, but some data might still be in the 992 * The substream buffer is empty, but some data might still be in the
936 * currently active URBs, so we have to wait for those to complete. 993 * currently active URBs, so we have to wait for those to complete.
@@ -954,11 +1011,13 @@ static void snd_usbmidi_output_drain(struct snd_rawmidi_substream *substream)
954 1011
955static int snd_usbmidi_input_open(struct snd_rawmidi_substream *substream) 1012static int snd_usbmidi_input_open(struct snd_rawmidi_substream *substream)
956{ 1013{
1014 substream_open(substream, 1);
957 return 0; 1015 return 0;
958} 1016}
959 1017
960static int snd_usbmidi_input_close(struct snd_rawmidi_substream *substream) 1018static int snd_usbmidi_input_close(struct snd_rawmidi_substream *substream)
961{ 1019{
1020 substream_open(substream, 0);
962 return 0; 1021 return 0;
963} 1022}
964 1023
@@ -988,7 +1047,7 @@ static struct snd_rawmidi_ops snd_usbmidi_input_ops = {
988static void free_urb_and_buffer(struct snd_usb_midi *umidi, struct urb *urb, 1047static void free_urb_and_buffer(struct snd_usb_midi *umidi, struct urb *urb,
989 unsigned int buffer_length) 1048 unsigned int buffer_length)
990{ 1049{
991 usb_buffer_free(umidi->chip->dev, buffer_length, 1050 usb_buffer_free(umidi->dev, buffer_length,
992 urb->transfer_buffer, urb->transfer_dma); 1051 urb->transfer_buffer, urb->transfer_dma);
993 usb_free_urb(urb); 1052 usb_free_urb(urb);
994} 1053}
@@ -1035,24 +1094,24 @@ static int snd_usbmidi_in_endpoint_create(struct snd_usb_midi* umidi,
1035 } 1094 }
1036 } 1095 }
1037 if (ep_info->in_interval) 1096 if (ep_info->in_interval)
1038 pipe = usb_rcvintpipe(umidi->chip->dev, ep_info->in_ep); 1097 pipe = usb_rcvintpipe(umidi->dev, ep_info->in_ep);
1039 else 1098 else
1040 pipe = usb_rcvbulkpipe(umidi->chip->dev, ep_info->in_ep); 1099 pipe = usb_rcvbulkpipe(umidi->dev, ep_info->in_ep);
1041 length = usb_maxpacket(umidi->chip->dev, pipe, 0); 1100 length = usb_maxpacket(umidi->dev, pipe, 0);
1042 for (i = 0; i < INPUT_URBS; ++i) { 1101 for (i = 0; i < INPUT_URBS; ++i) {
1043 buffer = usb_buffer_alloc(umidi->chip->dev, length, GFP_KERNEL, 1102 buffer = usb_buffer_alloc(umidi->dev, length, GFP_KERNEL,
1044 &ep->urbs[i]->transfer_dma); 1103 &ep->urbs[i]->transfer_dma);
1045 if (!buffer) { 1104 if (!buffer) {
1046 snd_usbmidi_in_endpoint_delete(ep); 1105 snd_usbmidi_in_endpoint_delete(ep);
1047 return -ENOMEM; 1106 return -ENOMEM;
1048 } 1107 }
1049 if (ep_info->in_interval) 1108 if (ep_info->in_interval)
1050 usb_fill_int_urb(ep->urbs[i], umidi->chip->dev, 1109 usb_fill_int_urb(ep->urbs[i], umidi->dev,
1051 pipe, buffer, length, 1110 pipe, buffer, length,
1052 snd_usbmidi_in_urb_complete, 1111 snd_usbmidi_in_urb_complete,
1053 ep, ep_info->in_interval); 1112 ep, ep_info->in_interval);
1054 else 1113 else
1055 usb_fill_bulk_urb(ep->urbs[i], umidi->chip->dev, 1114 usb_fill_bulk_urb(ep->urbs[i], umidi->dev,
1056 pipe, buffer, length, 1115 pipe, buffer, length,
1057 snd_usbmidi_in_urb_complete, ep); 1116 snd_usbmidi_in_urb_complete, ep);
1058 ep->urbs[i]->transfer_flags = URB_NO_TRANSFER_DMA_MAP; 1117 ep->urbs[i]->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
@@ -1062,27 +1121,25 @@ static int snd_usbmidi_in_endpoint_create(struct snd_usb_midi* umidi,
1062 return 0; 1121 return 0;
1063} 1122}
1064 1123
1065static unsigned int snd_usbmidi_count_bits(unsigned int x)
1066{
1067 unsigned int bits;
1068
1069 for (bits = 0; x; ++bits)
1070 x &= x - 1;
1071 return bits;
1072}
1073
1074/* 1124/*
1075 * Frees an output endpoint. 1125 * Frees an output endpoint.
1076 * May be called when ep hasn't been initialized completely. 1126 * May be called when ep hasn't been initialized completely.
1077 */ 1127 */
1078static void snd_usbmidi_out_endpoint_delete(struct snd_usb_midi_out_endpoint* ep) 1128static void snd_usbmidi_out_endpoint_clear(struct snd_usb_midi_out_endpoint *ep)
1079{ 1129{
1080 unsigned int i; 1130 unsigned int i;
1081 1131
1082 for (i = 0; i < OUTPUT_URBS; ++i) 1132 for (i = 0; i < OUTPUT_URBS; ++i)
1083 if (ep->urbs[i].urb) 1133 if (ep->urbs[i].urb) {
1084 free_urb_and_buffer(ep->umidi, ep->urbs[i].urb, 1134 free_urb_and_buffer(ep->umidi, ep->urbs[i].urb,
1085 ep->max_transfer); 1135 ep->max_transfer);
1136 ep->urbs[i].urb = NULL;
1137 }
1138}
1139
1140static void snd_usbmidi_out_endpoint_delete(struct snd_usb_midi_out_endpoint *ep)
1141{
1142 snd_usbmidi_out_endpoint_clear(ep);
1086 kfree(ep); 1143 kfree(ep);
1087} 1144}
1088 1145
@@ -1113,15 +1170,27 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi* umidi,
1113 ep->urbs[i].ep = ep; 1170 ep->urbs[i].ep = ep;
1114 } 1171 }
1115 if (ep_info->out_interval) 1172 if (ep_info->out_interval)
1116 pipe = usb_sndintpipe(umidi->chip->dev, ep_info->out_ep); 1173 pipe = usb_sndintpipe(umidi->dev, ep_info->out_ep);
1117 else 1174 else
1118 pipe = usb_sndbulkpipe(umidi->chip->dev, ep_info->out_ep); 1175 pipe = usb_sndbulkpipe(umidi->dev, ep_info->out_ep);
1119 if (umidi->chip->usb_id == USB_ID(0x0a92, 0x1020)) /* ESI M4U */ 1176 switch (umidi->usb_id) {
1177 default:
1178 ep->max_transfer = usb_maxpacket(umidi->dev, pipe, 1);
1179 break;
1180 /*
1181 * Various chips declare a packet size larger than 4 bytes, but
1182 * do not actually work with larger packets:
1183 */
1184 case USB_ID(0x0a92, 0x1020): /* ESI M4U */
1185 case USB_ID(0x1430, 0x474b): /* RedOctane GH MIDI INTERFACE */
1186 case USB_ID(0x15ca, 0x0101): /* Textech USB Midi Cable */
1187 case USB_ID(0x15ca, 0x1806): /* Textech USB Midi Cable */
1188 case USB_ID(0x1a86, 0x752d): /* QinHeng CH345 "USB2.0-MIDI" */
1120 ep->max_transfer = 4; 1189 ep->max_transfer = 4;
1121 else 1190 break;
1122 ep->max_transfer = usb_maxpacket(umidi->chip->dev, pipe, 1); 1191 }
1123 for (i = 0; i < OUTPUT_URBS; ++i) { 1192 for (i = 0; i < OUTPUT_URBS; ++i) {
1124 buffer = usb_buffer_alloc(umidi->chip->dev, 1193 buffer = usb_buffer_alloc(umidi->dev,
1125 ep->max_transfer, GFP_KERNEL, 1194 ep->max_transfer, GFP_KERNEL,
1126 &ep->urbs[i].urb->transfer_dma); 1195 &ep->urbs[i].urb->transfer_dma);
1127 if (!buffer) { 1196 if (!buffer) {
@@ -1129,12 +1198,12 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi* umidi,
1129 return -ENOMEM; 1198 return -ENOMEM;
1130 } 1199 }
1131 if (ep_info->out_interval) 1200 if (ep_info->out_interval)
1132 usb_fill_int_urb(ep->urbs[i].urb, umidi->chip->dev, 1201 usb_fill_int_urb(ep->urbs[i].urb, umidi->dev,
1133 pipe, buffer, ep->max_transfer, 1202 pipe, buffer, ep->max_transfer,
1134 snd_usbmidi_out_urb_complete, 1203 snd_usbmidi_out_urb_complete,
1135 &ep->urbs[i], ep_info->out_interval); 1204 &ep->urbs[i], ep_info->out_interval);
1136 else 1205 else
1137 usb_fill_bulk_urb(ep->urbs[i].urb, umidi->chip->dev, 1206 usb_fill_bulk_urb(ep->urbs[i].urb, umidi->dev,
1138 pipe, buffer, ep->max_transfer, 1207 pipe, buffer, ep->max_transfer,
1139 snd_usbmidi_out_urb_complete, 1208 snd_usbmidi_out_urb_complete,
1140 &ep->urbs[i]); 1209 &ep->urbs[i]);
@@ -1172,6 +1241,7 @@ static void snd_usbmidi_free(struct snd_usb_midi* umidi)
1172 if (ep->in) 1241 if (ep->in)
1173 snd_usbmidi_in_endpoint_delete(ep->in); 1242 snd_usbmidi_in_endpoint_delete(ep->in);
1174 } 1243 }
1244 mutex_destroy(&umidi->mutex);
1175 kfree(umidi); 1245 kfree(umidi);
1176} 1246}
1177 1247
@@ -1201,15 +1271,18 @@ void snd_usbmidi_disconnect(struct list_head* p)
1201 usb_kill_urb(ep->out->urbs[j].urb); 1271 usb_kill_urb(ep->out->urbs[j].urb);
1202 if (umidi->usb_protocol_ops->finish_out_endpoint) 1272 if (umidi->usb_protocol_ops->finish_out_endpoint)
1203 umidi->usb_protocol_ops->finish_out_endpoint(ep->out); 1273 umidi->usb_protocol_ops->finish_out_endpoint(ep->out);
1274 ep->out->active_urbs = 0;
1275 if (ep->out->drain_urbs) {
1276 ep->out->drain_urbs = 0;
1277 wake_up(&ep->out->drain_wait);
1278 }
1204 } 1279 }
1205 if (ep->in) 1280 if (ep->in)
1206 for (j = 0; j < INPUT_URBS; ++j) 1281 for (j = 0; j < INPUT_URBS; ++j)
1207 usb_kill_urb(ep->in->urbs[j]); 1282 usb_kill_urb(ep->in->urbs[j]);
1208 /* free endpoints here; later call can result in Oops */ 1283 /* free endpoints here; later call can result in Oops */
1209 if (ep->out) { 1284 if (ep->out)
1210 snd_usbmidi_out_endpoint_delete(ep->out); 1285 snd_usbmidi_out_endpoint_clear(ep->out);
1211 ep->out = NULL;
1212 }
1213 if (ep->in) { 1286 if (ep->in) {
1214 snd_usbmidi_in_endpoint_delete(ep->in); 1287 snd_usbmidi_in_endpoint_delete(ep->in);
1215 ep->in = NULL; 1288 ep->in = NULL;
@@ -1360,6 +1433,12 @@ static struct port_info {
1360 EXTERNAL_PORT(0x086a, 0x0001, 8, "%s Broadcast"), 1433 EXTERNAL_PORT(0x086a, 0x0001, 8, "%s Broadcast"),
1361 EXTERNAL_PORT(0x086a, 0x0002, 8, "%s Broadcast"), 1434 EXTERNAL_PORT(0x086a, 0x0002, 8, "%s Broadcast"),
1362 EXTERNAL_PORT(0x086a, 0x0003, 4, "%s Broadcast"), 1435 EXTERNAL_PORT(0x086a, 0x0003, 4, "%s Broadcast"),
1436 /* Access Music Virus TI */
1437 EXTERNAL_PORT(0x133e, 0x0815, 0, "%s MIDI"),
1438 PORT_INFO(0x133e, 0x0815, 1, "%s Synth", 0,
1439 SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC |
1440 SNDRV_SEQ_PORT_TYPE_HARDWARE |
1441 SNDRV_SEQ_PORT_TYPE_SYNTHESIZER),
1363}; 1442};
1364 1443
1365static struct port_info *find_port_info(struct snd_usb_midi* umidi, int number) 1444static struct port_info *find_port_info(struct snd_usb_midi* umidi, int number)
@@ -1367,7 +1446,7 @@ static struct port_info *find_port_info(struct snd_usb_midi* umidi, int number)
1367 int i; 1446 int i;
1368 1447
1369 for (i = 0; i < ARRAY_SIZE(snd_usbmidi_port_info); ++i) { 1448 for (i = 0; i < ARRAY_SIZE(snd_usbmidi_port_info); ++i) {
1370 if (snd_usbmidi_port_info[i].id == umidi->chip->usb_id && 1449 if (snd_usbmidi_port_info[i].id == umidi->usb_id &&
1371 snd_usbmidi_port_info[i].port == number) 1450 snd_usbmidi_port_info[i].port == number)
1372 return &snd_usbmidi_port_info[i]; 1451 return &snd_usbmidi_port_info[i];
1373 } 1452 }
@@ -1405,7 +1484,7 @@ static void snd_usbmidi_init_substream(struct snd_usb_midi* umidi,
1405 port_info = find_port_info(umidi, number); 1484 port_info = find_port_info(umidi, number);
1406 name_format = port_info ? port_info->name : "%s MIDI %d"; 1485 name_format = port_info ? port_info->name : "%s MIDI %d";
1407 snprintf(substream->name, sizeof(substream->name), 1486 snprintf(substream->name, sizeof(substream->name),
1408 name_format, umidi->chip->card->shortname, number + 1); 1487 name_format, umidi->card->shortname, number + 1);
1409 1488
1410 *rsubstream = substream; 1489 *rsubstream = substream;
1411} 1490}
@@ -1475,7 +1554,7 @@ static int snd_usbmidi_get_ms_info(struct snd_usb_midi* umidi,
1475 if (hostif->extralen >= 7 && 1554 if (hostif->extralen >= 7 &&
1476 ms_header->bLength >= 7 && 1555 ms_header->bLength >= 7 &&
1477 ms_header->bDescriptorType == USB_DT_CS_INTERFACE && 1556 ms_header->bDescriptorType == USB_DT_CS_INTERFACE &&
1478 ms_header->bDescriptorSubtype == HEADER) 1557 ms_header->bDescriptorSubtype == UAC_HEADER)
1479 snd_printdd(KERN_INFO "MIDIStreaming version %02x.%02x\n", 1558 snd_printdd(KERN_INFO "MIDIStreaming version %02x.%02x\n",
1480 ms_header->bcdMSC[1], ms_header->bcdMSC[0]); 1559 ms_header->bcdMSC[1], ms_header->bcdMSC[0]);
1481 else 1560 else
@@ -1491,7 +1570,7 @@ static int snd_usbmidi_get_ms_info(struct snd_usb_midi* umidi,
1491 if (hostep->extralen < 4 || 1570 if (hostep->extralen < 4 ||
1492 ms_ep->bLength < 4 || 1571 ms_ep->bLength < 4 ||
1493 ms_ep->bDescriptorType != USB_DT_CS_ENDPOINT || 1572 ms_ep->bDescriptorType != USB_DT_CS_ENDPOINT ||
1494 ms_ep->bDescriptorSubtype != MS_GENERAL) 1573 ms_ep->bDescriptorSubtype != UAC_MS_GENERAL)
1495 continue; 1574 continue;
1496 if (usb_endpoint_dir_out(ep)) { 1575 if (usb_endpoint_dir_out(ep)) {
1497 if (endpoints[epidx].out_ep) { 1576 if (endpoints[epidx].out_ep) {
@@ -1503,7 +1582,7 @@ static int snd_usbmidi_get_ms_info(struct snd_usb_midi* umidi,
1503 endpoints[epidx].out_ep = usb_endpoint_num(ep); 1582 endpoints[epidx].out_ep = usb_endpoint_num(ep);
1504 if (usb_endpoint_xfer_int(ep)) 1583 if (usb_endpoint_xfer_int(ep))
1505 endpoints[epidx].out_interval = ep->bInterval; 1584 endpoints[epidx].out_interval = ep->bInterval;
1506 else if (snd_usb_get_speed(umidi->chip->dev) == USB_SPEED_LOW) 1585 else if (snd_usb_get_speed(umidi->dev) == USB_SPEED_LOW)
1507 /* 1586 /*
1508 * Low speed bulk transfers don't exist, so 1587 * Low speed bulk transfers don't exist, so
1509 * force interrupt transfers for devices like 1588 * force interrupt transfers for devices like
@@ -1523,7 +1602,7 @@ static int snd_usbmidi_get_ms_info(struct snd_usb_midi* umidi,
1523 endpoints[epidx].in_ep = usb_endpoint_num(ep); 1602 endpoints[epidx].in_ep = usb_endpoint_num(ep);
1524 if (usb_endpoint_xfer_int(ep)) 1603 if (usb_endpoint_xfer_int(ep))
1525 endpoints[epidx].in_interval = ep->bInterval; 1604 endpoints[epidx].in_interval = ep->bInterval;
1526 else if (snd_usb_get_speed(umidi->chip->dev) == USB_SPEED_LOW) 1605 else if (snd_usb_get_speed(umidi->dev) == USB_SPEED_LOW)
1527 endpoints[epidx].in_interval = 1; 1606 endpoints[epidx].in_interval = 1;
1528 endpoints[epidx].in_cables = (1 << ms_ep->bNumEmbMIDIJack) - 1; 1607 endpoints[epidx].in_cables = (1 << ms_ep->bNumEmbMIDIJack) - 1;
1529 snd_printdd(KERN_INFO "EP %02X: %d jack(s)\n", 1608 snd_printdd(KERN_INFO "EP %02X: %d jack(s)\n",
@@ -1533,6 +1612,52 @@ static int snd_usbmidi_get_ms_info(struct snd_usb_midi* umidi,
1533 return 0; 1612 return 0;
1534} 1613}
1535 1614
1615static int roland_load_info(struct snd_kcontrol *kcontrol,
1616 struct snd_ctl_elem_info *info)
1617{
1618 static const char *const names[] = { "High Load", "Light Load" };
1619
1620 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1621 info->count = 1;
1622 info->value.enumerated.items = 2;
1623 if (info->value.enumerated.item > 1)
1624 info->value.enumerated.item = 1;
1625 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
1626 return 0;
1627}
1628
1629static int roland_load_get(struct snd_kcontrol *kcontrol,
1630 struct snd_ctl_elem_value *value)
1631{
1632 value->value.enumerated.item[0] = kcontrol->private_value;
1633 return 0;
1634}
1635
1636static int roland_load_put(struct snd_kcontrol *kcontrol,
1637 struct snd_ctl_elem_value *value)
1638{
1639 struct snd_usb_midi* umidi = kcontrol->private_data;
1640 int changed;
1641
1642 if (value->value.enumerated.item[0] > 1)
1643 return -EINVAL;
1644 mutex_lock(&umidi->mutex);
1645 changed = value->value.enumerated.item[0] != kcontrol->private_value;
1646 if (changed)
1647 kcontrol->private_value = value->value.enumerated.item[0];
1648 mutex_unlock(&umidi->mutex);
1649 return changed;
1650}
1651
1652static struct snd_kcontrol_new roland_load_ctl = {
1653 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1654 .name = "MIDI Input Mode",
1655 .info = roland_load_info,
1656 .get = roland_load_get,
1657 .put = roland_load_put,
1658 .private_value = 1,
1659};
1660
1536/* 1661/*
1537 * On Roland devices, use the second alternate setting to be able to use 1662 * On Roland devices, use the second alternate setting to be able to use
1538 * the interrupt input endpoint. 1663 * the interrupt input endpoint.
@@ -1556,8 +1681,12 @@ static void snd_usbmidi_switch_roland_altsetting(struct snd_usb_midi* umidi)
1556 1681
1557 snd_printdd(KERN_INFO "switching to altsetting %d with int ep\n", 1682 snd_printdd(KERN_INFO "switching to altsetting %d with int ep\n",
1558 intfd->bAlternateSetting); 1683 intfd->bAlternateSetting);
1559 usb_set_interface(umidi->chip->dev, intfd->bInterfaceNumber, 1684 usb_set_interface(umidi->dev, intfd->bInterfaceNumber,
1560 intfd->bAlternateSetting); 1685 intfd->bAlternateSetting);
1686
1687 umidi->roland_load_ctl = snd_ctl_new1(&roland_load_ctl, umidi);
1688 if (snd_ctl_add(umidi->card, umidi->roland_load_ctl) < 0)
1689 umidi->roland_load_ctl = NULL;
1561} 1690}
1562 1691
1563/* 1692/*
@@ -1573,7 +1702,7 @@ static int snd_usbmidi_detect_endpoints(struct snd_usb_midi* umidi,
1573 struct usb_endpoint_descriptor* epd; 1702 struct usb_endpoint_descriptor* epd;
1574 int i, out_eps = 0, in_eps = 0; 1703 int i, out_eps = 0, in_eps = 0;
1575 1704
1576 if (USB_ID_VENDOR(umidi->chip->usb_id) == 0x0582) 1705 if (USB_ID_VENDOR(umidi->usb_id) == 0x0582)
1577 snd_usbmidi_switch_roland_altsetting(umidi); 1706 snd_usbmidi_switch_roland_altsetting(umidi);
1578 1707
1579 if (endpoint[0].out_ep || endpoint[0].in_ep) 1708 if (endpoint[0].out_ep || endpoint[0].in_ep)
@@ -1653,9 +1782,9 @@ static int snd_usbmidi_detect_yamaha(struct snd_usb_midi* umidi,
1653 cs_desc < hostif->extra + hostif->extralen && cs_desc[0] >= 2; 1782 cs_desc < hostif->extra + hostif->extralen && cs_desc[0] >= 2;
1654 cs_desc += cs_desc[0]) { 1783 cs_desc += cs_desc[0]) {
1655 if (cs_desc[1] == USB_DT_CS_INTERFACE) { 1784 if (cs_desc[1] == USB_DT_CS_INTERFACE) {
1656 if (cs_desc[2] == MIDI_IN_JACK) 1785 if (cs_desc[2] == UAC_MIDI_IN_JACK)
1657 endpoint->in_cables = (endpoint->in_cables << 1) | 1; 1786 endpoint->in_cables = (endpoint->in_cables << 1) | 1;
1658 else if (cs_desc[2] == MIDI_OUT_JACK) 1787 else if (cs_desc[2] == UAC_MIDI_OUT_JACK)
1659 endpoint->out_cables = (endpoint->out_cables << 1) | 1; 1788 endpoint->out_cables = (endpoint->out_cables << 1) | 1;
1660 } 1789 }
1661 } 1790 }
@@ -1760,12 +1889,12 @@ static int snd_usbmidi_create_rawmidi(struct snd_usb_midi* umidi,
1760 struct snd_rawmidi *rmidi; 1889 struct snd_rawmidi *rmidi;
1761 int err; 1890 int err;
1762 1891
1763 err = snd_rawmidi_new(umidi->chip->card, "USB MIDI", 1892 err = snd_rawmidi_new(umidi->card, "USB MIDI",
1764 umidi->chip->next_midi_device++, 1893 umidi->next_midi_device++,
1765 out_ports, in_ports, &rmidi); 1894 out_ports, in_ports, &rmidi);
1766 if (err < 0) 1895 if (err < 0)
1767 return err; 1896 return err;
1768 strcpy(rmidi->name, umidi->chip->card->shortname); 1897 strcpy(rmidi->name, umidi->card->shortname);
1769 rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT | 1898 rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT |
1770 SNDRV_RAWMIDI_INFO_INPUT | 1899 SNDRV_RAWMIDI_INFO_INPUT |
1771 SNDRV_RAWMIDI_INFO_DUPLEX; 1900 SNDRV_RAWMIDI_INFO_DUPLEX;
@@ -1804,7 +1933,7 @@ static void snd_usbmidi_input_start_ep(struct snd_usb_midi_in_endpoint* ep)
1804 return; 1933 return;
1805 for (i = 0; i < INPUT_URBS; ++i) { 1934 for (i = 0; i < INPUT_URBS; ++i) {
1806 struct urb* urb = ep->urbs[i]; 1935 struct urb* urb = ep->urbs[i];
1807 urb->dev = ep->umidi->chip->dev; 1936 urb->dev = ep->umidi->dev;
1808 snd_usbmidi_submit_urb(urb, GFP_KERNEL); 1937 snd_usbmidi_submit_urb(urb, GFP_KERNEL);
1809 } 1938 }
1810} 1939}
@@ -1825,9 +1954,10 @@ void snd_usbmidi_input_start(struct list_head* p)
1825/* 1954/*
1826 * Creates and registers everything needed for a MIDI streaming interface. 1955 * Creates and registers everything needed for a MIDI streaming interface.
1827 */ 1956 */
1828int snd_usb_create_midi_interface(struct snd_usb_audio* chip, 1957int snd_usbmidi_create(struct snd_card *card,
1829 struct usb_interface* iface, 1958 struct usb_interface* iface,
1830 const struct snd_usb_audio_quirk* quirk) 1959 struct list_head *midi_list,
1960 const struct snd_usb_audio_quirk* quirk)
1831{ 1961{
1832 struct snd_usb_midi* umidi; 1962 struct snd_usb_midi* umidi;
1833 struct snd_usb_midi_endpoint_info endpoints[MIDI_MAX_ENDPOINTS]; 1963 struct snd_usb_midi_endpoint_info endpoints[MIDI_MAX_ENDPOINTS];
@@ -1837,12 +1967,16 @@ int snd_usb_create_midi_interface(struct snd_usb_audio* chip,
1837 umidi = kzalloc(sizeof(*umidi), GFP_KERNEL); 1967 umidi = kzalloc(sizeof(*umidi), GFP_KERNEL);
1838 if (!umidi) 1968 if (!umidi)
1839 return -ENOMEM; 1969 return -ENOMEM;
1840 umidi->chip = chip; 1970 umidi->dev = interface_to_usbdev(iface);
1971 umidi->card = card;
1841 umidi->iface = iface; 1972 umidi->iface = iface;
1842 umidi->quirk = quirk; 1973 umidi->quirk = quirk;
1843 umidi->usb_protocol_ops = &snd_usbmidi_standard_ops; 1974 umidi->usb_protocol_ops = &snd_usbmidi_standard_ops;
1844 init_timer(&umidi->error_timer); 1975 init_timer(&umidi->error_timer);
1845 spin_lock_init(&umidi->disc_lock); 1976 spin_lock_init(&umidi->disc_lock);
1977 mutex_init(&umidi->mutex);
1978 umidi->usb_id = USB_ID(le16_to_cpu(umidi->dev->descriptor.idVendor),
1979 le16_to_cpu(umidi->dev->descriptor.idProduct));
1846 umidi->error_timer.function = snd_usbmidi_error_timer; 1980 umidi->error_timer.function = snd_usbmidi_error_timer;
1847 umidi->error_timer.data = (unsigned long)umidi; 1981 umidi->error_timer.data = (unsigned long)umidi;
1848 1982
@@ -1851,7 +1985,7 @@ int snd_usb_create_midi_interface(struct snd_usb_audio* chip,
1851 switch (quirk ? quirk->type : QUIRK_MIDI_STANDARD_INTERFACE) { 1985 switch (quirk ? quirk->type : QUIRK_MIDI_STANDARD_INTERFACE) {
1852 case QUIRK_MIDI_STANDARD_INTERFACE: 1986 case QUIRK_MIDI_STANDARD_INTERFACE:
1853 err = snd_usbmidi_get_ms_info(umidi, endpoints); 1987 err = snd_usbmidi_get_ms_info(umidi, endpoints);
1854 if (chip->usb_id == USB_ID(0x0763, 0x0150)) /* M-Audio Uno */ 1988 if (umidi->usb_id == USB_ID(0x0763, 0x0150)) /* M-Audio Uno */
1855 umidi->usb_protocol_ops = 1989 umidi->usb_protocol_ops =
1856 &snd_usbmidi_maudio_broken_running_status_ops; 1990 &snd_usbmidi_maudio_broken_running_status_ops;
1857 break; 1991 break;
@@ -1887,7 +2021,7 @@ int snd_usb_create_midi_interface(struct snd_usb_audio* chip,
1887 * interface 0, so we have to make sure that the USB core looks 2021 * interface 0, so we have to make sure that the USB core looks
1888 * again at interface 0 by calling usb_set_interface() on it. 2022 * again at interface 0 by calling usb_set_interface() on it.
1889 */ 2023 */
1890 usb_set_interface(umidi->chip->dev, 0, 0); 2024 usb_set_interface(umidi->dev, 0, 0);
1891 err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); 2025 err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
1892 break; 2026 break;
1893 case QUIRK_MIDI_EMAGIC: 2027 case QUIRK_MIDI_EMAGIC:
@@ -1914,8 +2048,8 @@ int snd_usb_create_midi_interface(struct snd_usb_audio* chip,
1914 out_ports = 0; 2048 out_ports = 0;
1915 in_ports = 0; 2049 in_ports = 0;
1916 for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) { 2050 for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
1917 out_ports += snd_usbmidi_count_bits(endpoints[i].out_cables); 2051 out_ports += hweight16(endpoints[i].out_cables);
1918 in_ports += snd_usbmidi_count_bits(endpoints[i].in_cables); 2052 in_ports += hweight16(endpoints[i].in_cables);
1919 } 2053 }
1920 err = snd_usbmidi_create_rawmidi(umidi, out_ports, in_ports); 2054 err = snd_usbmidi_create_rawmidi(umidi, out_ports, in_ports);
1921 if (err < 0) { 2055 if (err < 0) {
@@ -1933,14 +2067,14 @@ int snd_usb_create_midi_interface(struct snd_usb_audio* chip,
1933 return err; 2067 return err;
1934 } 2068 }
1935 2069
1936 list_add(&umidi->list, &umidi->chip->midi_list); 2070 list_add_tail(&umidi->list, midi_list);
1937 2071
1938 for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) 2072 for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i)
1939 snd_usbmidi_input_start_ep(umidi->endpoints[i].in); 2073 snd_usbmidi_input_start_ep(umidi->endpoints[i].in);
1940 return 0; 2074 return 0;
1941} 2075}
1942 2076
1943EXPORT_SYMBOL(snd_usb_create_midi_interface); 2077EXPORT_SYMBOL(snd_usbmidi_create);
1944EXPORT_SYMBOL(snd_usbmidi_input_stop); 2078EXPORT_SYMBOL(snd_usbmidi_input_stop);
1945EXPORT_SYMBOL(snd_usbmidi_input_start); 2079EXPORT_SYMBOL(snd_usbmidi_input_start);
1946EXPORT_SYMBOL(snd_usbmidi_disconnect); 2080EXPORT_SYMBOL(snd_usbmidi_disconnect);
diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c
index c998220b99c6..8e8f871b74ca 100644
--- a/sound/usb/usbmixer.c
+++ b/sound/usb/usbmixer.c
@@ -32,6 +32,8 @@
32#include <linux/slab.h> 32#include <linux/slab.h>
33#include <linux/string.h> 33#include <linux/string.h>
34#include <linux/usb.h> 34#include <linux/usb.h>
35#include <linux/usb/audio.h>
36
35#include <sound/core.h> 37#include <sound/core.h>
36#include <sound/control.h> 38#include <sound/control.h>
37#include <sound/hwdep.h> 39#include <sound/hwdep.h>
@@ -69,13 +71,16 @@ static const struct rc_config {
69 { USB_ID(0x041e, 0x3048), 2, 2, 6, 6, 2, 0x6e91 }, /* Toshiba SB0500 */ 71 { USB_ID(0x041e, 0x3048), 2, 2, 6, 6, 2, 0x6e91 }, /* Toshiba SB0500 */
70}; 72};
71 73
74#define MAX_ID_ELEMS 256
75
72struct usb_mixer_interface { 76struct usb_mixer_interface {
73 struct snd_usb_audio *chip; 77 struct snd_usb_audio *chip;
74 unsigned int ctrlif; 78 unsigned int ctrlif;
75 struct list_head list; 79 struct list_head list;
76 unsigned int ignore_ctl_error; 80 unsigned int ignore_ctl_error;
77 struct urb *urb; 81 struct urb *urb;
78 struct usb_mixer_elem_info **id_elems; /* array[256], indexed by unit id */ 82 /* array[MAX_ID_ELEMS], indexed by unit id */
83 struct usb_mixer_elem_info **id_elems;
79 84
80 /* Sound Blaster remote control stuff */ 85 /* Sound Blaster remote control stuff */
81 const struct rc_config *rc_cfg; 86 const struct rc_config *rc_cfg;
@@ -105,7 +110,7 @@ struct mixer_build {
105 struct usb_mixer_interface *mixer; 110 struct usb_mixer_interface *mixer;
106 unsigned char *buffer; 111 unsigned char *buffer;
107 unsigned int buflen; 112 unsigned int buflen;
108 DECLARE_BITMAP(unitbitmap, 256); 113 DECLARE_BITMAP(unitbitmap, MAX_ID_ELEMS);
109 struct usb_audio_term oterm; 114 struct usb_audio_term oterm;
110 const struct usbmix_name_map *map; 115 const struct usbmix_name_map *map;
111 const struct usbmix_selector_map *selector_map; 116 const struct usbmix_selector_map *selector_map;
@@ -123,6 +128,7 @@ struct usb_mixer_elem_info {
123 int channels; 128 int channels;
124 int val_type; 129 int val_type;
125 int min, max, res; 130 int min, max, res;
131 int dBmin, dBmax;
126 int cached; 132 int cached;
127 int cache_val[MAX_CHANNELS]; 133 int cache_val[MAX_CHANNELS];
128 u8 initialized; 134 u8 initialized;
@@ -186,6 +192,21 @@ enum {
186 USB_PROC_DCR_RELEASE = 6, 192 USB_PROC_DCR_RELEASE = 6,
187}; 193};
188 194
195/*E-mu 0202(0404) eXtension Unit(XU) control*/
196enum {
197 USB_XU_CLOCK_RATE = 0xe301,
198 USB_XU_CLOCK_SOURCE = 0xe302,
199 USB_XU_DIGITAL_IO_STATUS = 0xe303,
200 USB_XU_DEVICE_OPTIONS = 0xe304,
201 USB_XU_DIRECT_MONITORING = 0xe305,
202 USB_XU_METERING = 0xe306
203};
204enum {
205 USB_XU_CLOCK_SOURCE_SELECTOR = 0x02, /* clock source*/
206 USB_XU_CLOCK_RATE_SELECTOR = 0x03, /* clock rate */
207 USB_XU_DIGITAL_FORMAT_SELECTOR = 0x01, /* the spdif format */
208 USB_XU_SOFT_LIMIT_SELECTOR = 0x03 /* soft limiter */
209};
189 210
190/* 211/*
191 * manual mapping of mixer names 212 * manual mapping of mixer names
@@ -194,42 +215,50 @@ enum {
194 */ 215 */
195#include "usbmixer_maps.c" 216#include "usbmixer_maps.c"
196 217
197/* get the mapped name if the unit matches */ 218static const struct usbmix_name_map *
198static int check_mapped_name(struct mixer_build *state, int unitid, int control, char *buf, int buflen) 219find_map(struct mixer_build *state, int unitid, int control)
199{ 220{
200 const struct usbmix_name_map *p; 221 const struct usbmix_name_map *p = state->map;
201 222
202 if (! state->map) 223 if (!p)
203 return 0; 224 return NULL;
204 225
205 for (p = state->map; p->id; p++) { 226 for (p = state->map; p->id; p++) {
206 if (p->id == unitid && p->name && 227 if (p->id == unitid &&
207 (! control || ! p->control || control == p->control)) { 228 (!control || !p->control || control == p->control))
208 buflen--; 229 return p;
209 return strlcpy(buf, p->name, buflen);
210 }
211 } 230 }
212 return 0; 231 return NULL;
213} 232}
214 233
215/* check whether the control should be ignored */ 234/* get the mapped name if the unit matches */
216static int check_ignored_ctl(struct mixer_build *state, int unitid, int control) 235static int
236check_mapped_name(const struct usbmix_name_map *p, char *buf, int buflen)
217{ 237{
218 const struct usbmix_name_map *p; 238 if (!p || !p->name)
239 return 0;
240
241 buflen--;
242 return strlcpy(buf, p->name, buflen);
243}
219 244
220 if (! state->map) 245/* check whether the control should be ignored */
246static inline int
247check_ignored_ctl(const struct usbmix_name_map *p)
248{
249 if (!p || p->name || p->dB)
221 return 0; 250 return 0;
222 for (p = state->map; p->id; p++) { 251 return 1;
223 if (p->id == unitid && ! p->name && 252}
224 (! control || ! p->control || control == p->control)) { 253
225 /* 254/* dB mapping */
226 printk(KERN_DEBUG "ignored control %d:%d\n", 255static inline void check_mapped_dB(const struct usbmix_name_map *p,
227 unitid, control); 256 struct usb_mixer_elem_info *cval)
228 */ 257{
229 return 1; 258 if (p && p->dB) {
230 } 259 cval->dBmin = p->dB->min;
260 cval->dBmax = p->dB->max;
231 } 261 }
232 return 0;
233} 262}
234 263
235/* get the mapped selector source name */ 264/* get the mapped selector source name */
@@ -257,7 +286,7 @@ static void *find_audio_control_unit(struct mixer_build *state, unsigned char un
257 p = NULL; 286 p = NULL;
258 while ((p = snd_usb_find_desc(state->buffer, state->buflen, p, 287 while ((p = snd_usb_find_desc(state->buffer, state->buflen, p,
259 USB_DT_CS_INTERFACE)) != NULL) { 288 USB_DT_CS_INTERFACE)) != NULL) {
260 if (p[0] >= 4 && p[2] >= INPUT_TERMINAL && p[2] <= EXTENSION_UNIT && p[3] == unit) 289 if (p[0] >= 4 && p[2] >= UAC_INPUT_TERMINAL && p[2] <= UAC_EXTENSION_UNIT_V1 && p[3] == unit)
261 return p; 290 return p;
262 } 291 }
263 return NULL; 292 return NULL;
@@ -378,14 +407,14 @@ static int get_ctl_value(struct usb_mixer_elem_info *cval, int request, int vali
378 407
379static int get_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int *value) 408static int get_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int *value)
380{ 409{
381 return get_ctl_value(cval, GET_CUR, validx, value); 410 return get_ctl_value(cval, UAC_GET_CUR, validx, value);
382} 411}
383 412
384/* channel = 0: master, 1 = first channel */ 413/* channel = 0: master, 1 = first channel */
385static inline int get_cur_mix_raw(struct usb_mixer_elem_info *cval, 414static inline int get_cur_mix_raw(struct usb_mixer_elem_info *cval,
386 int channel, int *value) 415 int channel, int *value)
387{ 416{
388 return get_ctl_value(cval, GET_CUR, (cval->control << 8) | channel, value); 417 return get_ctl_value(cval, UAC_GET_CUR, (cval->control << 8) | channel, value);
389} 418}
390 419
391static int get_cur_mix_value(struct usb_mixer_elem_info *cval, 420static int get_cur_mix_value(struct usb_mixer_elem_info *cval,
@@ -439,14 +468,14 @@ static int set_ctl_value(struct usb_mixer_elem_info *cval, int request, int vali
439 468
440static int set_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int value) 469static int set_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int value)
441{ 470{
442 return set_ctl_value(cval, SET_CUR, validx, value); 471 return set_ctl_value(cval, UAC_SET_CUR, validx, value);
443} 472}
444 473
445static int set_cur_mix_value(struct usb_mixer_elem_info *cval, int channel, 474static int set_cur_mix_value(struct usb_mixer_elem_info *cval, int channel,
446 int index, int value) 475 int index, int value)
447{ 476{
448 int err; 477 int err;
449 err = set_ctl_value(cval, SET_CUR, (cval->control << 8) | channel, 478 err = set_ctl_value(cval, UAC_SET_CUR, (cval->control << 8) | channel,
450 value); 479 value);
451 if (err < 0) 480 if (err < 0)
452 return err; 481 return err;
@@ -466,20 +495,8 @@ static int mixer_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
466 495
467 if (size < sizeof(scale)) 496 if (size < sizeof(scale))
468 return -ENOMEM; 497 return -ENOMEM;
469 /* USB descriptions contain the dB scale in 1/256 dB unit 498 scale[2] = cval->dBmin;
470 * while ALSA TLV contains in 1/100 dB unit 499 scale[3] = cval->dBmax;
471 */
472 scale[2] = (convert_signed_value(cval, cval->min) * 100) / 256;
473 scale[3] = (convert_signed_value(cval, cval->max) * 100) / 256;
474 if (scale[3] <= scale[2]) {
475 /* something is wrong; assume it's either from/to 0dB */
476 if (scale[2] < 0)
477 scale[3] = 0;
478 else if (scale[2] > 0)
479 scale[2] = 0;
480 else /* totally crap, return an error */
481 return -EINVAL;
482 }
483 if (copy_to_user(_tlv, scale, sizeof(scale))) 500 if (copy_to_user(_tlv, scale, sizeof(scale)))
484 return -EFAULT; 501 return -EFAULT;
485 return 0; 502 return 0;
@@ -588,13 +605,13 @@ static int get_term_name(struct mixer_build *state, struct usb_audio_term *iterm
588 if (term_only) 605 if (term_only)
589 return 0; 606 return 0;
590 switch (iterm->type >> 16) { 607 switch (iterm->type >> 16) {
591 case SELECTOR_UNIT: 608 case UAC_SELECTOR_UNIT:
592 strcpy(name, "Selector"); return 8; 609 strcpy(name, "Selector"); return 8;
593 case PROCESSING_UNIT: 610 case UAC_PROCESSING_UNIT_V1:
594 strcpy(name, "Process Unit"); return 12; 611 strcpy(name, "Process Unit"); return 12;
595 case EXTENSION_UNIT: 612 case UAC_EXTENSION_UNIT_V1:
596 strcpy(name, "Ext Unit"); return 8; 613 strcpy(name, "Ext Unit"); return 8;
597 case MIXER_UNIT: 614 case UAC_MIXER_UNIT:
598 strcpy(name, "Mixer"); return 5; 615 strcpy(name, "Mixer"); return 5;
599 default: 616 default:
600 return sprintf(name, "Unit %d", iterm->id); 617 return sprintf(name, "Unit %d", iterm->id);
@@ -633,22 +650,22 @@ static int check_input_term(struct mixer_build *state, int id, struct usb_audio_
633 while ((p1 = find_audio_control_unit(state, id)) != NULL) { 650 while ((p1 = find_audio_control_unit(state, id)) != NULL) {
634 term->id = id; 651 term->id = id;
635 switch (p1[2]) { 652 switch (p1[2]) {
636 case INPUT_TERMINAL: 653 case UAC_INPUT_TERMINAL:
637 term->type = combine_word(p1 + 4); 654 term->type = combine_word(p1 + 4);
638 term->channels = p1[7]; 655 term->channels = p1[7];
639 term->chconfig = combine_word(p1 + 8); 656 term->chconfig = combine_word(p1 + 8);
640 term->name = p1[11]; 657 term->name = p1[11];
641 return 0; 658 return 0;
642 case FEATURE_UNIT: 659 case UAC_FEATURE_UNIT:
643 id = p1[4]; 660 id = p1[4];
644 break; /* continue to parse */ 661 break; /* continue to parse */
645 case MIXER_UNIT: 662 case UAC_MIXER_UNIT:
646 term->type = p1[2] << 16; /* virtual type */ 663 term->type = p1[2] << 16; /* virtual type */
647 term->channels = p1[5 + p1[4]]; 664 term->channels = p1[5 + p1[4]];
648 term->chconfig = combine_word(p1 + 6 + p1[4]); 665 term->chconfig = combine_word(p1 + 6 + p1[4]);
649 term->name = p1[p1[0] - 1]; 666 term->name = p1[p1[0] - 1];
650 return 0; 667 return 0;
651 case SELECTOR_UNIT: 668 case UAC_SELECTOR_UNIT:
652 /* call recursively to retrieve the channel info */ 669 /* call recursively to retrieve the channel info */
653 if (check_input_term(state, p1[5], term) < 0) 670 if (check_input_term(state, p1[5], term) < 0)
654 return -ENODEV; 671 return -ENODEV;
@@ -656,8 +673,8 @@ static int check_input_term(struct mixer_build *state, int id, struct usb_audio_
656 term->id = id; 673 term->id = id;
657 term->name = p1[9 + p1[0] - 1]; 674 term->name = p1[9 + p1[0] - 1];
658 return 0; 675 return 0;
659 case PROCESSING_UNIT: 676 case UAC_PROCESSING_UNIT_V1:
660 case EXTENSION_UNIT: 677 case UAC_EXTENSION_UNIT_V1:
661 if (p1[6] == 1) { 678 if (p1[6] == 1) {
662 id = p1[7]; 679 id = p1[7];
663 break; /* continue to parse */ 680 break; /* continue to parse */
@@ -720,6 +737,7 @@ static int get_min_max(struct usb_mixer_elem_info *cval, int default_min)
720 cval->min = default_min; 737 cval->min = default_min;
721 cval->max = cval->min + 1; 738 cval->max = cval->min + 1;
722 cval->res = 1; 739 cval->res = 1;
740 cval->dBmin = cval->dBmax = 0;
723 741
724 if (cval->val_type == USB_MIXER_BOOLEAN || 742 if (cval->val_type == USB_MIXER_BOOLEAN ||
725 cval->val_type == USB_MIXER_INV_BOOLEAN) { 743 cval->val_type == USB_MIXER_INV_BOOLEAN) {
@@ -734,23 +752,23 @@ static int get_min_max(struct usb_mixer_elem_info *cval, int default_min)
734 break; 752 break;
735 } 753 }
736 } 754 }
737 if (get_ctl_value(cval, GET_MAX, (cval->control << 8) | minchn, &cval->max) < 0 || 755 if (get_ctl_value(cval, UAC_GET_MAX, (cval->control << 8) | minchn, &cval->max) < 0 ||
738 get_ctl_value(cval, GET_MIN, (cval->control << 8) | minchn, &cval->min) < 0) { 756 get_ctl_value(cval, UAC_GET_MIN, (cval->control << 8) | minchn, &cval->min) < 0) {
739 snd_printd(KERN_ERR "%d:%d: cannot get min/max values for control %d (id %d)\n", 757 snd_printd(KERN_ERR "%d:%d: cannot get min/max values for control %d (id %d)\n",
740 cval->id, cval->mixer->ctrlif, cval->control, cval->id); 758 cval->id, cval->mixer->ctrlif, cval->control, cval->id);
741 return -EINVAL; 759 return -EINVAL;
742 } 760 }
743 if (get_ctl_value(cval, GET_RES, (cval->control << 8) | minchn, &cval->res) < 0) { 761 if (get_ctl_value(cval, UAC_GET_RES, (cval->control << 8) | minchn, &cval->res) < 0) {
744 cval->res = 1; 762 cval->res = 1;
745 } else { 763 } else {
746 int last_valid_res = cval->res; 764 int last_valid_res = cval->res;
747 765
748 while (cval->res > 1) { 766 while (cval->res > 1) {
749 if (set_ctl_value(cval, SET_RES, (cval->control << 8) | minchn, cval->res / 2) < 0) 767 if (set_ctl_value(cval, UAC_SET_RES, (cval->control << 8) | minchn, cval->res / 2) < 0)
750 break; 768 break;
751 cval->res /= 2; 769 cval->res /= 2;
752 } 770 }
753 if (get_ctl_value(cval, GET_RES, (cval->control << 8) | minchn, &cval->res) < 0) 771 if (get_ctl_value(cval, UAC_GET_RES, (cval->control << 8) | minchn, &cval->res) < 0)
754 cval->res = last_valid_res; 772 cval->res = last_valid_res;
755 } 773 }
756 if (cval->res == 0) 774 if (cval->res == 0)
@@ -787,6 +805,24 @@ static int get_min_max(struct usb_mixer_elem_info *cval, int default_min)
787 805
788 cval->initialized = 1; 806 cval->initialized = 1;
789 } 807 }
808
809 /* USB descriptions contain the dB scale in 1/256 dB unit
810 * while ALSA TLV contains in 1/100 dB unit
811 */
812 cval->dBmin = (convert_signed_value(cval, cval->min) * 100) / 256;
813 cval->dBmax = (convert_signed_value(cval, cval->max) * 100) / 256;
814 if (cval->dBmin > cval->dBmax) {
815 /* something is wrong; assume it's either from/to 0dB */
816 if (cval->dBmin < 0)
817 cval->dBmax = 0;
818 else if (cval->dBmin > 0)
819 cval->dBmin = 0;
820 if (cval->dBmin > cval->dBmax) {
821 /* totally crap, return an error */
822 return -EINVAL;
823 }
824 }
825
790 return 0; 826 return 0;
791} 827}
792 828
@@ -912,6 +948,7 @@ static void build_feature_ctl(struct mixer_build *state, unsigned char *desc,
912 int nameid = desc[desc[0] - 1]; 948 int nameid = desc[desc[0] - 1];
913 struct snd_kcontrol *kctl; 949 struct snd_kcontrol *kctl;
914 struct usb_mixer_elem_info *cval; 950 struct usb_mixer_elem_info *cval;
951 const struct usbmix_name_map *map;
915 952
916 control++; /* change from zero-based to 1-based value */ 953 control++; /* change from zero-based to 1-based value */
917 954
@@ -920,7 +957,8 @@ static void build_feature_ctl(struct mixer_build *state, unsigned char *desc,
920 return; 957 return;
921 } 958 }
922 959
923 if (check_ignored_ctl(state, unitid, control)) 960 map = find_map(state, unitid, control);
961 if (check_ignored_ctl(map))
924 return; 962 return;
925 963
926 cval = kzalloc(sizeof(*cval), GFP_KERNEL); 964 cval = kzalloc(sizeof(*cval), GFP_KERNEL);
@@ -954,10 +992,11 @@ static void build_feature_ctl(struct mixer_build *state, unsigned char *desc,
954 } 992 }
955 kctl->private_free = usb_mixer_elem_free; 993 kctl->private_free = usb_mixer_elem_free;
956 994
957 len = check_mapped_name(state, unitid, control, kctl->id.name, sizeof(kctl->id.name)); 995 len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name));
958 mapped_name = len != 0; 996 mapped_name = len != 0;
959 if (! len && nameid) 997 if (! len && nameid)
960 len = snd_usb_copy_string_desc(state, nameid, kctl->id.name, sizeof(kctl->id.name)); 998 len = snd_usb_copy_string_desc(state, nameid,
999 kctl->id.name, sizeof(kctl->id.name));
961 1000
962 switch (control) { 1001 switch (control) {
963 case USB_FEATURE_MUTE: 1002 case USB_FEATURE_MUTE:
@@ -995,6 +1034,7 @@ static void build_feature_ctl(struct mixer_build *state, unsigned char *desc,
995 kctl->vd[0].access |= 1034 kctl->vd[0].access |=
996 SNDRV_CTL_ELEM_ACCESS_TLV_READ | 1035 SNDRV_CTL_ELEM_ACCESS_TLV_READ |
997 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK; 1036 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
1037 check_mapped_dB(map, cval);
998 } 1038 }
999 break; 1039 break;
1000 1040
@@ -1048,29 +1088,30 @@ static void build_feature_ctl(struct mixer_build *state, unsigned char *desc,
1048 * 1088 *
1049 * most of controlls are defined here. 1089 * most of controlls are defined here.
1050 */ 1090 */
1051static int parse_audio_feature_unit(struct mixer_build *state, int unitid, unsigned char *ftr) 1091static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void *_ftr)
1052{ 1092{
1053 int channels, i, j; 1093 int channels, i, j;
1054 struct usb_audio_term iterm; 1094 struct usb_audio_term iterm;
1055 unsigned int master_bits, first_ch_bits; 1095 unsigned int master_bits, first_ch_bits;
1056 int err, csize; 1096 int err, csize;
1097 struct uac_feature_unit_descriptor *ftr = _ftr;
1057 1098
1058 if (ftr[0] < 7 || ! (csize = ftr[5]) || ftr[0] < 7 + csize) { 1099 if (ftr->bLength < 7 || ! (csize = ftr->bControlSize) || ftr->bLength < 7 + csize) {
1059 snd_printk(KERN_ERR "usbaudio: unit %u: invalid FEATURE_UNIT descriptor\n", unitid); 1100 snd_printk(KERN_ERR "usbaudio: unit %u: invalid UAC_FEATURE_UNIT descriptor\n", unitid);
1060 return -EINVAL; 1101 return -EINVAL;
1061 } 1102 }
1062 1103
1063 /* parse the source unit */ 1104 /* parse the source unit */
1064 if ((err = parse_audio_unit(state, ftr[4])) < 0) 1105 if ((err = parse_audio_unit(state, ftr->bSourceID)) < 0)
1065 return err; 1106 return err;
1066 1107
1067 /* determine the input source type and name */ 1108 /* determine the input source type and name */
1068 if (check_input_term(state, ftr[4], &iterm) < 0) 1109 if (check_input_term(state, ftr->bSourceID, &iterm) < 0)
1069 return -EINVAL; 1110 return -EINVAL;
1070 1111
1071 channels = (ftr[0] - 7) / csize - 1; 1112 channels = (ftr->bLength - 7) / csize - 1;
1072 1113
1073 master_bits = snd_usb_combine_bytes(ftr + 6, csize); 1114 master_bits = snd_usb_combine_bytes(ftr->controls, csize);
1074 /* master configuration quirks */ 1115 /* master configuration quirks */
1075 switch (state->chip->usb_id) { 1116 switch (state->chip->usb_id) {
1076 case USB_ID(0x08bb, 0x2702): 1117 case USB_ID(0x08bb, 0x2702):
@@ -1081,21 +1122,21 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, unsig
1081 break; 1122 break;
1082 } 1123 }
1083 if (channels > 0) 1124 if (channels > 0)
1084 first_ch_bits = snd_usb_combine_bytes(ftr + 6 + csize, csize); 1125 first_ch_bits = snd_usb_combine_bytes(ftr->controls + csize, csize);
1085 else 1126 else
1086 first_ch_bits = 0; 1127 first_ch_bits = 0;
1087 /* check all control types */ 1128 /* check all control types */
1088 for (i = 0; i < 10; i++) { 1129 for (i = 0; i < 10; i++) {
1089 unsigned int ch_bits = 0; 1130 unsigned int ch_bits = 0;
1090 for (j = 0; j < channels; j++) { 1131 for (j = 0; j < channels; j++) {
1091 unsigned int mask = snd_usb_combine_bytes(ftr + 6 + csize * (j+1), csize); 1132 unsigned int mask = snd_usb_combine_bytes(ftr->controls + csize * (j+1), csize);
1092 if (mask & (1 << i)) 1133 if (mask & (1 << i))
1093 ch_bits |= (1 << j); 1134 ch_bits |= (1 << j);
1094 } 1135 }
1095 if (ch_bits & 1) /* the first channel must be set (for ease of programming) */ 1136 if (ch_bits & 1) /* the first channel must be set (for ease of programming) */
1096 build_feature_ctl(state, ftr, ch_bits, i, &iterm, unitid); 1137 build_feature_ctl(state, _ftr, ch_bits, i, &iterm, unitid);
1097 if (master_bits & (1 << i)) 1138 if (master_bits & (1 << i))
1098 build_feature_ctl(state, ftr, 0, i, &iterm, unitid); 1139 build_feature_ctl(state, _ftr, 0, i, &iterm, unitid);
1099 } 1140 }
1100 1141
1101 return 0; 1142 return 0;
@@ -1122,8 +1163,10 @@ static void build_mixer_unit_ctl(struct mixer_build *state, unsigned char *desc,
1122 unsigned int num_outs = desc[5 + input_pins]; 1163 unsigned int num_outs = desc[5 + input_pins];
1123 unsigned int i, len; 1164 unsigned int i, len;
1124 struct snd_kcontrol *kctl; 1165 struct snd_kcontrol *kctl;
1166 const struct usbmix_name_map *map;
1125 1167
1126 if (check_ignored_ctl(state, unitid, 0)) 1168 map = find_map(state, unitid, 0);
1169 if (check_ignored_ctl(map))
1127 return; 1170 return;
1128 1171
1129 cval = kzalloc(sizeof(*cval), GFP_KERNEL); 1172 cval = kzalloc(sizeof(*cval), GFP_KERNEL);
@@ -1152,7 +1195,7 @@ static void build_mixer_unit_ctl(struct mixer_build *state, unsigned char *desc,
1152 } 1195 }
1153 kctl->private_free = usb_mixer_elem_free; 1196 kctl->private_free = usb_mixer_elem_free;
1154 1197
1155 len = check_mapped_name(state, unitid, 0, kctl->id.name, sizeof(kctl->id.name)); 1198 len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name));
1156 if (! len) 1199 if (! len)
1157 len = get_term_name(state, iterm, kctl->id.name, sizeof(kctl->id.name), 0); 1200 len = get_term_name(state, iterm, kctl->id.name, sizeof(kctl->id.name), 0);
1158 if (! len) 1201 if (! len)
@@ -1330,7 +1373,32 @@ static struct procunit_info procunits[] = {
1330 { USB_PROC_DCR, "DCR", dcr_proc_info }, 1373 { USB_PROC_DCR, "DCR", dcr_proc_info },
1331 { 0 }, 1374 { 0 },
1332}; 1375};
1333 1376/*
1377 * predefined data for extension units
1378 */
1379static struct procunit_value_info clock_rate_xu_info[] = {
1380 { USB_XU_CLOCK_RATE_SELECTOR, "Selector", USB_MIXER_U8, 0 },
1381 { 0 }
1382};
1383static struct procunit_value_info clock_source_xu_info[] = {
1384 { USB_XU_CLOCK_SOURCE_SELECTOR, "External", USB_MIXER_BOOLEAN },
1385 { 0 }
1386};
1387static struct procunit_value_info spdif_format_xu_info[] = {
1388 { USB_XU_DIGITAL_FORMAT_SELECTOR, "SPDIF/AC3", USB_MIXER_BOOLEAN },
1389 { 0 }
1390};
1391static struct procunit_value_info soft_limit_xu_info[] = {
1392 { USB_XU_SOFT_LIMIT_SELECTOR, " ", USB_MIXER_BOOLEAN },
1393 { 0 }
1394};
1395static struct procunit_info extunits[] = {
1396 { USB_XU_CLOCK_RATE, "Clock rate", clock_rate_xu_info },
1397 { USB_XU_CLOCK_SOURCE, "DigitalIn CLK source", clock_source_xu_info },
1398 { USB_XU_DIGITAL_IO_STATUS, "DigitalOut format:", spdif_format_xu_info },
1399 { USB_XU_DEVICE_OPTIONS, "AnalogueIn Soft Limit", soft_limit_xu_info },
1400 { 0 }
1401};
1334/* 1402/*
1335 * build a processing/extension unit 1403 * build a processing/extension unit
1336 */ 1404 */
@@ -1342,6 +1410,7 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned
1342 int i, err, nameid, type, len; 1410 int i, err, nameid, type, len;
1343 struct procunit_info *info; 1411 struct procunit_info *info;
1344 struct procunit_value_info *valinfo; 1412 struct procunit_value_info *valinfo;
1413 const struct usbmix_name_map *map;
1345 static struct procunit_value_info default_value_info[] = { 1414 static struct procunit_value_info default_value_info[] = {
1346 { 0x01, "Switch", USB_MIXER_BOOLEAN }, 1415 { 0x01, "Switch", USB_MIXER_BOOLEAN },
1347 { 0 } 1416 { 0 }
@@ -1371,7 +1440,8 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned
1371 /* FIXME: bitmap might be longer than 8bit */ 1440 /* FIXME: bitmap might be longer than 8bit */
1372 if (! (dsc[12 + num_ins] & (1 << (valinfo->control - 1)))) 1441 if (! (dsc[12 + num_ins] & (1 << (valinfo->control - 1))))
1373 continue; 1442 continue;
1374 if (check_ignored_ctl(state, unitid, valinfo->control)) 1443 map = find_map(state, unitid, valinfo->control);
1444 if (check_ignored_ctl(map))
1375 continue; 1445 continue;
1376 cval = kzalloc(sizeof(*cval), GFP_KERNEL); 1446 cval = kzalloc(sizeof(*cval), GFP_KERNEL);
1377 if (! cval) { 1447 if (! cval) {
@@ -1391,8 +1461,18 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned
1391 cval->max = dsc[15]; 1461 cval->max = dsc[15];
1392 cval->res = 1; 1462 cval->res = 1;
1393 cval->initialized = 1; 1463 cval->initialized = 1;
1394 } else 1464 } else {
1395 get_min_max(cval, valinfo->min_value); 1465 if (type == USB_XU_CLOCK_RATE) {
1466 /* E-Mu USB 0404/0202/TrackerPre
1467 * samplerate control quirk
1468 */
1469 cval->min = 0;
1470 cval->max = 5;
1471 cval->res = 1;
1472 cval->initialized = 1;
1473 } else
1474 get_min_max(cval, valinfo->min_value);
1475 }
1396 1476
1397 kctl = snd_ctl_new1(&mixer_procunit_ctl, cval); 1477 kctl = snd_ctl_new1(&mixer_procunit_ctl, cval);
1398 if (! kctl) { 1478 if (! kctl) {
@@ -1402,8 +1482,9 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned
1402 } 1482 }
1403 kctl->private_free = usb_mixer_elem_free; 1483 kctl->private_free = usb_mixer_elem_free;
1404 1484
1405 if (check_mapped_name(state, unitid, cval->control, kctl->id.name, sizeof(kctl->id.name))) 1485 if (check_mapped_name(map, kctl->id.name,
1406 ; 1486 sizeof(kctl->id.name)))
1487 /* nothing */ ;
1407 else if (info->name) 1488 else if (info->name)
1408 strlcpy(kctl->id.name, info->name, sizeof(kctl->id.name)); 1489 strlcpy(kctl->id.name, info->name, sizeof(kctl->id.name));
1409 else { 1490 else {
@@ -1433,7 +1514,7 @@ static int parse_audio_processing_unit(struct mixer_build *state, int unitid, un
1433 1514
1434static int parse_audio_extension_unit(struct mixer_build *state, int unitid, unsigned char *desc) 1515static int parse_audio_extension_unit(struct mixer_build *state, int unitid, unsigned char *desc)
1435{ 1516{
1436 return build_audio_procunit(state, unitid, desc, NULL, "Extension Unit"); 1517 return build_audio_procunit(state, unitid, desc, extunits, "Extension Unit");
1437} 1518}
1438 1519
1439 1520
@@ -1542,6 +1623,7 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsi
1542 int err; 1623 int err;
1543 struct usb_mixer_elem_info *cval; 1624 struct usb_mixer_elem_info *cval;
1544 struct snd_kcontrol *kctl; 1625 struct snd_kcontrol *kctl;
1626 const struct usbmix_name_map *map;
1545 char **namelist; 1627 char **namelist;
1546 1628
1547 if (! num_ins || desc[0] < 5 + num_ins) { 1629 if (! num_ins || desc[0] < 5 + num_ins) {
@@ -1557,7 +1639,8 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsi
1557 if (num_ins == 1) /* only one ? nonsense! */ 1639 if (num_ins == 1) /* only one ? nonsense! */
1558 return 0; 1640 return 0;
1559 1641
1560 if (check_ignored_ctl(state, unitid, 0)) 1642 map = find_map(state, unitid, 0);
1643 if (check_ignored_ctl(map))
1561 return 0; 1644 return 0;
1562 1645
1563 cval = kzalloc(sizeof(*cval), GFP_KERNEL); 1646 cval = kzalloc(sizeof(*cval), GFP_KERNEL);
@@ -1612,7 +1695,7 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsi
1612 kctl->private_free = usb_mixer_selector_elem_free; 1695 kctl->private_free = usb_mixer_selector_elem_free;
1613 1696
1614 nameid = desc[desc[0] - 1]; 1697 nameid = desc[desc[0] - 1];
1615 len = check_mapped_name(state, unitid, 0, kctl->id.name, sizeof(kctl->id.name)); 1698 len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name));
1616 if (len) 1699 if (len)
1617 ; 1700 ;
1618 else if (nameid) 1701 else if (nameid)
@@ -1656,17 +1739,17 @@ static int parse_audio_unit(struct mixer_build *state, int unitid)
1656 } 1739 }
1657 1740
1658 switch (p1[2]) { 1741 switch (p1[2]) {
1659 case INPUT_TERMINAL: 1742 case UAC_INPUT_TERMINAL:
1660 return 0; /* NOP */ 1743 return 0; /* NOP */
1661 case MIXER_UNIT: 1744 case UAC_MIXER_UNIT:
1662 return parse_audio_mixer_unit(state, unitid, p1); 1745 return parse_audio_mixer_unit(state, unitid, p1);
1663 case SELECTOR_UNIT: 1746 case UAC_SELECTOR_UNIT:
1664 return parse_audio_selector_unit(state, unitid, p1); 1747 return parse_audio_selector_unit(state, unitid, p1);
1665 case FEATURE_UNIT: 1748 case UAC_FEATURE_UNIT:
1666 return parse_audio_feature_unit(state, unitid, p1); 1749 return parse_audio_feature_unit(state, unitid, p1);
1667 case PROCESSING_UNIT: 1750 case UAC_PROCESSING_UNIT_V1:
1668 return parse_audio_processing_unit(state, unitid, p1); 1751 return parse_audio_processing_unit(state, unitid, p1);
1669 case EXTENSION_UNIT: 1752 case UAC_EXTENSION_UNIT_V1:
1670 return parse_audio_extension_unit(state, unitid, p1); 1753 return parse_audio_extension_unit(state, unitid, p1);
1671 default: 1754 default:
1672 snd_printk(KERN_ERR "usbaudio: unit %u: unexpected type 0x%02x\n", unitid, p1[2]); 1755 snd_printk(KERN_ERR "usbaudio: unit %u: unexpected type 0x%02x\n", unitid, p1[2]);
@@ -1696,11 +1779,11 @@ static int snd_usb_mixer_dev_free(struct snd_device *device)
1696/* 1779/*
1697 * create mixer controls 1780 * create mixer controls
1698 * 1781 *
1699 * walk through all OUTPUT_TERMINAL descriptors to search for mixers 1782 * walk through all UAC_OUTPUT_TERMINAL descriptors to search for mixers
1700 */ 1783 */
1701static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer) 1784static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
1702{ 1785{
1703 unsigned char *desc; 1786 struct uac_output_terminal_descriptor_v1 *desc;
1704 struct mixer_build state; 1787 struct mixer_build state;
1705 int err; 1788 int err;
1706 const struct usbmix_ctl_map *map; 1789 const struct usbmix_ctl_map *map;
@@ -1724,14 +1807,14 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
1724 } 1807 }
1725 1808
1726 desc = NULL; 1809 desc = NULL;
1727 while ((desc = snd_usb_find_csint_desc(hostif->extra, hostif->extralen, desc, OUTPUT_TERMINAL)) != NULL) { 1810 while ((desc = snd_usb_find_csint_desc(hostif->extra, hostif->extralen, desc, UAC_OUTPUT_TERMINAL)) != NULL) {
1728 if (desc[0] < 9) 1811 if (desc->bLength < 9)
1729 continue; /* invalid descriptor? */ 1812 continue; /* invalid descriptor? */
1730 set_bit(desc[3], state.unitbitmap); /* mark terminal ID as visited */ 1813 set_bit(desc->bTerminalID, state.unitbitmap); /* mark terminal ID as visited */
1731 state.oterm.id = desc[3]; 1814 state.oterm.id = desc->bTerminalID;
1732 state.oterm.type = combine_word(&desc[4]); 1815 state.oterm.type = le16_to_cpu(desc->wTerminalType);
1733 state.oterm.name = desc[8]; 1816 state.oterm.name = desc->iTerminal;
1734 err = parse_audio_unit(&state, desc[7]); 1817 err = parse_audio_unit(&state, desc->bSourceID);
1735 if (err < 0) 1818 if (err < 0)
1736 return err; 1819 return err;
1737 } 1820 }
@@ -1748,6 +1831,46 @@ static void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer,
1748 info->elem_id); 1831 info->elem_id);
1749} 1832}
1750 1833
1834static void snd_usb_mixer_dump_cval(struct snd_info_buffer *buffer,
1835 int unitid,
1836 struct usb_mixer_elem_info *cval)
1837{
1838 static char *val_types[] = {"BOOLEAN", "INV_BOOLEAN",
1839 "S8", "U8", "S16", "U16"};
1840 snd_iprintf(buffer, " Unit: %i\n", unitid);
1841 if (cval->elem_id)
1842 snd_iprintf(buffer, " Control: name=\"%s\", index=%i\n",
1843 cval->elem_id->name, cval->elem_id->index);
1844 snd_iprintf(buffer, " Info: id=%i, control=%i, cmask=0x%x, "
1845 "channels=%i, type=\"%s\"\n", cval->id,
1846 cval->control, cval->cmask, cval->channels,
1847 val_types[cval->val_type]);
1848 snd_iprintf(buffer, " Volume: min=%i, max=%i, dBmin=%i, dBmax=%i\n",
1849 cval->min, cval->max, cval->dBmin, cval->dBmax);
1850}
1851
1852static void snd_usb_mixer_proc_read(struct snd_info_entry *entry,
1853 struct snd_info_buffer *buffer)
1854{
1855 struct snd_usb_audio *chip = entry->private_data;
1856 struct usb_mixer_interface *mixer;
1857 struct usb_mixer_elem_info *cval;
1858 int unitid;
1859
1860 list_for_each_entry(mixer, &chip->mixer_list, list) {
1861 snd_iprintf(buffer,
1862 "USB Mixer: usb_id=0x%08x, ctrlif=%i, ctlerr=%i\n",
1863 chip->usb_id, mixer->ctrlif,
1864 mixer->ignore_ctl_error);
1865 snd_iprintf(buffer, "Card: %s\n", chip->card->longname);
1866 for (unitid = 0; unitid < MAX_ID_ELEMS; unitid++) {
1867 for (cval = mixer->id_elems[unitid]; cval;
1868 cval = cval->next_id_elem)
1869 snd_usb_mixer_dump_cval(buffer, unitid, cval);
1870 }
1871 }
1872}
1873
1751static void snd_usb_mixer_memory_change(struct usb_mixer_interface *mixer, 1874static void snd_usb_mixer_memory_change(struct usb_mixer_interface *mixer,
1752 int unitid) 1875 int unitid)
1753{ 1876{
@@ -1924,7 +2047,7 @@ static int snd_usb_soundblaster_remote_init(struct usb_mixer_interface *mixer)
1924 } 2047 }
1925 mixer->rc_setup_packet->bRequestType = 2048 mixer->rc_setup_packet->bRequestType =
1926 USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE; 2049 USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
1927 mixer->rc_setup_packet->bRequest = GET_MEM; 2050 mixer->rc_setup_packet->bRequest = UAC_GET_MEM;
1928 mixer->rc_setup_packet->wValue = cpu_to_le16(0); 2051 mixer->rc_setup_packet->wValue = cpu_to_le16(0);
1929 mixer->rc_setup_packet->wIndex = cpu_to_le16(0); 2052 mixer->rc_setup_packet->wIndex = cpu_to_le16(0);
1930 mixer->rc_setup_packet->wLength = cpu_to_le16(len); 2053 mixer->rc_setup_packet->wLength = cpu_to_le16(len);
@@ -2047,7 +2170,7 @@ static void snd_audigy2nx_proc_read(struct snd_info_entry *entry,
2047 snd_iprintf(buffer, "%s: ", jacks[i].name); 2170 snd_iprintf(buffer, "%s: ", jacks[i].name);
2048 err = snd_usb_ctl_msg(mixer->chip->dev, 2171 err = snd_usb_ctl_msg(mixer->chip->dev,
2049 usb_rcvctrlpipe(mixer->chip->dev, 0), 2172 usb_rcvctrlpipe(mixer->chip->dev, 0),
2050 GET_MEM, USB_DIR_IN | USB_TYPE_CLASS | 2173 UAC_GET_MEM, USB_DIR_IN | USB_TYPE_CLASS |
2051 USB_RECIP_INTERFACE, 0, 2174 USB_RECIP_INTERFACE, 0,
2052 jacks[i].unitid << 8, buf, 3, 100); 2175 jacks[i].unitid << 8, buf, 3, 100);
2053 if (err == 3 && (buf[0] == 3 || buf[0] == 6)) 2176 if (err == 3 && (buf[0] == 3 || buf[0] == 6))
@@ -2109,6 +2232,24 @@ static int snd_xonar_u1_controls_create(struct usb_mixer_interface *mixer)
2109 return 0; 2232 return 0;
2110} 2233}
2111 2234
2235void snd_emuusb_set_samplerate(struct snd_usb_audio *chip,
2236 unsigned char samplerate_id)
2237{
2238 struct usb_mixer_interface *mixer;
2239 struct usb_mixer_elem_info *cval;
2240 int unitid = 12; /* SamleRate ExtensionUnit ID */
2241
2242 list_for_each_entry(mixer, &chip->mixer_list, list) {
2243 cval = mixer->id_elems[unitid];
2244 if (cval) {
2245 set_cur_ctl_value(cval, cval->control << 8,
2246 samplerate_id);
2247 snd_usb_mixer_notify_id(mixer, unitid);
2248 }
2249 break;
2250 }
2251}
2252
2112int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif, 2253int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
2113 int ignore_error) 2254 int ignore_error)
2114{ 2255{
@@ -2116,7 +2257,9 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
2116 .dev_free = snd_usb_mixer_dev_free 2257 .dev_free = snd_usb_mixer_dev_free
2117 }; 2258 };
2118 struct usb_mixer_interface *mixer; 2259 struct usb_mixer_interface *mixer;
2119 int err; 2260 struct snd_info_entry *entry;
2261 struct usb_host_interface *host_iface;
2262 int err, protocol;
2120 2263
2121 strcpy(chip->card->mixername, "USB Mixer"); 2264 strcpy(chip->card->mixername, "USB Mixer");
2122 2265
@@ -2126,12 +2269,23 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
2126 mixer->chip = chip; 2269 mixer->chip = chip;
2127 mixer->ctrlif = ctrlif; 2270 mixer->ctrlif = ctrlif;
2128 mixer->ignore_ctl_error = ignore_error; 2271 mixer->ignore_ctl_error = ignore_error;
2129 mixer->id_elems = kcalloc(256, sizeof(*mixer->id_elems), GFP_KERNEL); 2272 mixer->id_elems = kcalloc(MAX_ID_ELEMS, sizeof(*mixer->id_elems),
2273 GFP_KERNEL);
2130 if (!mixer->id_elems) { 2274 if (!mixer->id_elems) {
2131 kfree(mixer); 2275 kfree(mixer);
2132 return -ENOMEM; 2276 return -ENOMEM;
2133 } 2277 }
2134 2278
2279 host_iface = &usb_ifnum_to_if(chip->dev, ctrlif)->altsetting[0];
2280 protocol = host_iface->desc.bInterfaceProtocol;
2281
2282 /* FIXME! */
2283 if (protocol != UAC_VERSION_1) {
2284 snd_printk(KERN_WARNING "mixer interface protocol 0x%02x not yet supported\n",
2285 protocol);
2286 return 0;
2287 }
2288
2135 if ((err = snd_usb_mixer_controls(mixer)) < 0 || 2289 if ((err = snd_usb_mixer_controls(mixer)) < 0 ||
2136 (err = snd_usb_mixer_status_create(mixer)) < 0) 2290 (err = snd_usb_mixer_status_create(mixer)) < 0)
2137 goto _error; 2291 goto _error;
@@ -2142,8 +2296,6 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
2142 if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020) || 2296 if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020) ||
2143 mixer->chip->usb_id == USB_ID(0x041e, 0x3040) || 2297 mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
2144 mixer->chip->usb_id == USB_ID(0x041e, 0x3048)) { 2298 mixer->chip->usb_id == USB_ID(0x041e, 0x3048)) {
2145 struct snd_info_entry *entry;
2146
2147 if ((err = snd_audigy2nx_controls_create(mixer)) < 0) 2299 if ((err = snd_audigy2nx_controls_create(mixer)) < 0)
2148 goto _error; 2300 goto _error;
2149 if (!snd_card_proc_new(chip->card, "audigy2nx", &entry)) 2301 if (!snd_card_proc_new(chip->card, "audigy2nx", &entry))
@@ -2161,6 +2313,11 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
2161 err = snd_device_new(chip->card, SNDRV_DEV_LOWLEVEL, mixer, &dev_ops); 2313 err = snd_device_new(chip->card, SNDRV_DEV_LOWLEVEL, mixer, &dev_ops);
2162 if (err < 0) 2314 if (err < 0)
2163 goto _error; 2315 goto _error;
2316
2317 if (list_empty(&chip->mixer_list) &&
2318 !snd_card_proc_new(chip->card, "usbmixer", &entry))
2319 snd_info_set_text_ops(entry, chip, snd_usb_mixer_proc_read);
2320
2164 list_add(&mixer->list, &chip->mixer_list); 2321 list_add(&mixer->list, &chip->mixer_list);
2165 return 0; 2322 return 0;
2166 2323
diff --git a/sound/usb/usbmixer_maps.c b/sound/usb/usbmixer_maps.c
index 3e5d66cf1f5a..79e903a60862 100644
--- a/sound/usb/usbmixer_maps.c
+++ b/sound/usb/usbmixer_maps.c
@@ -19,11 +19,16 @@
19 * 19 *
20 */ 20 */
21 21
22struct usbmix_dB_map {
23 u32 min;
24 u32 max;
25};
22 26
23struct usbmix_name_map { 27struct usbmix_name_map {
24 int id; 28 int id;
25 const char *name; 29 const char *name;
26 int control; 30 int control;
31 struct usbmix_dB_map *dB;
27}; 32};
28 33
29struct usbmix_selector_map { 34struct usbmix_selector_map {
@@ -72,7 +77,7 @@ static struct usbmix_name_map extigy_map[] = {
72 { 8, "Line Playback" }, /* FU */ 77 { 8, "Line Playback" }, /* FU */
73 /* 9: IT mic */ 78 /* 9: IT mic */
74 { 10, "Mic Playback" }, /* FU */ 79 { 10, "Mic Playback" }, /* FU */
75 { 11, "Capture Input Source" }, /* SU */ 80 { 11, "Capture Source" }, /* SU */
76 { 12, "Capture" }, /* FU */ 81 { 12, "Capture" }, /* FU */
77 /* 13: OT pcm capture */ 82 /* 13: OT pcm capture */
78 /* 14: MU (w/o controls) */ 83 /* 14: MU (w/o controls) */
@@ -102,6 +107,9 @@ static struct usbmix_name_map extigy_map[] = {
102 * e.g. no Master and fake PCM volume 107 * e.g. no Master and fake PCM volume
103 * Pavel Mihaylov <bin@bash.info> 108 * Pavel Mihaylov <bin@bash.info>
104 */ 109 */
110static struct usbmix_dB_map mp3plus_dB_1 = {-4781, 0}; /* just guess */
111static struct usbmix_dB_map mp3plus_dB_2 = {-1781, 618}; /* just guess */
112
105static struct usbmix_name_map mp3plus_map[] = { 113static struct usbmix_name_map mp3plus_map[] = {
106 /* 1: IT pcm */ 114 /* 1: IT pcm */
107 /* 2: IT mic */ 115 /* 2: IT mic */
@@ -110,16 +118,19 @@ static struct usbmix_name_map mp3plus_map[] = {
110 /* 5: OT digital out */ 118 /* 5: OT digital out */
111 /* 6: OT speaker */ 119 /* 6: OT speaker */
112 /* 7: OT pcm capture */ 120 /* 7: OT pcm capture */
113 { 8, "Capture Input Source" }, /* FU, default PCM Capture Source */ 121 { 8, "Capture Source" }, /* FU, default PCM Capture Source */
114 /* (Mic, Input 1 = Line input, Input 2 = Optical input) */ 122 /* (Mic, Input 1 = Line input, Input 2 = Optical input) */
115 { 9, "Master Playback" }, /* FU, default Speaker 1 */ 123 { 9, "Master Playback" }, /* FU, default Speaker 1 */
116 /* { 10, "Mic Capture", 1 }, */ /* FU, Mic Capture */ 124 /* { 10, "Mic Capture", 1 }, */ /* FU, Mic Capture */
117 /* { 10, "Mic Capture", 2 }, */ /* FU, Mic Capture */ 125 { 10, /* "Mic Capture", */ NULL, 2, .dB = &mp3plus_dB_2 },
126 /* FU, Mic Capture */
118 { 10, "Mic Boost", 7 }, /* FU, default Auto Gain Input */ 127 { 10, "Mic Boost", 7 }, /* FU, default Auto Gain Input */
119 { 11, "Line Capture" }, /* FU, default PCM Capture */ 128 { 11, "Line Capture", .dB = &mp3plus_dB_2 },
129 /* FU, default PCM Capture */
120 { 12, "Digital In Playback" }, /* FU, default PCM 1 */ 130 { 12, "Digital In Playback" }, /* FU, default PCM 1 */
121 /* { 13, "Mic Playback" }, */ /* FU, default Mic Playback */ 131 { 13, /* "Mic Playback", */ .dB = &mp3plus_dB_1 },
122 { 14, "Line Playback" }, /* FU, default Speaker */ 132 /* FU, default Mic Playback */
133 { 14, "Line Playback", .dB = &mp3plus_dB_1 }, /* FU, default Speaker */
123 /* 15: MU */ 134 /* 15: MU */
124 { 0 } /* terminator */ 135 { 0 } /* terminator */
125}; 136};
@@ -277,6 +288,22 @@ static struct usbmix_name_map scratch_live_map[] = {
277 { 0 } /* terminator */ 288 { 0 } /* terminator */
278}; 289};
279 290
291/* "Gamesurround Muse Pocket LT" looks same like "Sound Blaster MP3+"
292 * most importand difference is SU[8], it should be set to "Capture Source"
293 * to make alsamixer and PA working properly.
294 * FIXME: or mp3plus_map should use "Capture Source" too,
295 * so this maps can be merget
296 */
297static struct usbmix_name_map hercules_usb51_map[] = {
298 { 8, "Capture Source" }, /* SU, default "PCM Capture Source" */
299 { 9, "Master Playback" }, /* FU, default "Speaker Playback" */
300 { 10, "Mic Boost", 7 }, /* FU, default "Auto Gain Input" */
301 { 11, "Line Capture" }, /* FU, default "PCM Capture" */
302 { 13, "Mic Bypass Playback" }, /* FU, default "Mic Playback" */
303 { 14, "Line Bypass Playback" }, /* FU, default "Line Playback" */
304 { 0 } /* terminator */
305};
306
280/* 307/*
281 * Control map entries 308 * Control map entries
282 */ 309 */
@@ -316,6 +343,13 @@ static struct usbmix_ctl_map usbmix_ctl_maps[] = {
316 .ignore_ctl_error = 1, 343 .ignore_ctl_error = 1,
317 }, 344 },
318 { 345 {
346 /* Hercules Gamesurround Muse Pocket LT
347 * (USB 5.1 Channel Audio Adapter)
348 */
349 .id = USB_ID(0x06f8, 0xc000),
350 .map = hercules_usb51_map,
351 },
352 {
319 .id = USB_ID(0x08bb, 0x2702), 353 .id = USB_ID(0x08bb, 0x2702),
320 .map = linex_map, 354 .map = linex_map,
321 .ignore_ctl_error = 1, 355 .ignore_ctl_error = 1,
diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h
index f6f201eb24ce..2b426c1fd0e8 100644
--- a/sound/usb/usbquirks.h
+++ b/sound/usb/usbquirks.h
@@ -91,7 +91,7 @@
91 .idVendor = 0x046d, 91 .idVendor = 0x046d,
92 .idProduct = 0x0850, 92 .idProduct = 0x0850,
93 .bInterfaceClass = USB_CLASS_AUDIO, 93 .bInterfaceClass = USB_CLASS_AUDIO,
94 .bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL 94 .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL
95}, 95},
96{ 96{
97 .match_flags = USB_DEVICE_ID_MATCH_DEVICE | 97 .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
@@ -100,7 +100,7 @@
100 .idVendor = 0x046d, 100 .idVendor = 0x046d,
101 .idProduct = 0x08ae, 101 .idProduct = 0x08ae,
102 .bInterfaceClass = USB_CLASS_AUDIO, 102 .bInterfaceClass = USB_CLASS_AUDIO,
103 .bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL 103 .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL
104}, 104},
105{ 105{
106 .match_flags = USB_DEVICE_ID_MATCH_DEVICE | 106 .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
@@ -109,7 +109,7 @@
109 .idVendor = 0x046d, 109 .idVendor = 0x046d,
110 .idProduct = 0x08c6, 110 .idProduct = 0x08c6,
111 .bInterfaceClass = USB_CLASS_AUDIO, 111 .bInterfaceClass = USB_CLASS_AUDIO,
112 .bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL 112 .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL
113}, 113},
114{ 114{
115 .match_flags = USB_DEVICE_ID_MATCH_DEVICE | 115 .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
@@ -118,7 +118,7 @@
118 .idVendor = 0x046d, 118 .idVendor = 0x046d,
119 .idProduct = 0x08f0, 119 .idProduct = 0x08f0,
120 .bInterfaceClass = USB_CLASS_AUDIO, 120 .bInterfaceClass = USB_CLASS_AUDIO,
121 .bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL 121 .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL
122}, 122},
123{ 123{
124 .match_flags = USB_DEVICE_ID_MATCH_DEVICE | 124 .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
@@ -127,7 +127,7 @@
127 .idVendor = 0x046d, 127 .idVendor = 0x046d,
128 .idProduct = 0x08f5, 128 .idProduct = 0x08f5,
129 .bInterfaceClass = USB_CLASS_AUDIO, 129 .bInterfaceClass = USB_CLASS_AUDIO,
130 .bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL 130 .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL
131}, 131},
132{ 132{
133 .match_flags = USB_DEVICE_ID_MATCH_DEVICE | 133 .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
@@ -136,7 +136,7 @@
136 .idVendor = 0x046d, 136 .idVendor = 0x046d,
137 .idProduct = 0x08f6, 137 .idProduct = 0x08f6,
138 .bInterfaceClass = USB_CLASS_AUDIO, 138 .bInterfaceClass = USB_CLASS_AUDIO,
139 .bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL 139 .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL
140}, 140},
141{ 141{
142 USB_DEVICE(0x046d, 0x0990), 142 USB_DEVICE(0x046d, 0x0990),
@@ -301,7 +301,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
301 .iface = 1, 301 .iface = 1,
302 .altsetting = 1, 302 .altsetting = 1,
303 .altset_idx = 1, 303 .altset_idx = 1,
304 .attributes = EP_CS_ATTR_FILL_MAX, 304 .attributes = UAC_EP_CS_ATTR_FILL_MAX,
305 .endpoint = 0x81, 305 .endpoint = 0x81,
306 .ep_attr = 0x05, 306 .ep_attr = 0x05,
307 .rates = SNDRV_PCM_RATE_CONTINUOUS, 307 .rates = SNDRV_PCM_RATE_CONTINUOUS,
@@ -1016,36 +1016,6 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1016 } 1016 }
1017}, 1017},
1018{ 1018{
1019 USB_DEVICE(0x0582, 0x0044),
1020 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1021 .vendor_name = "Roland",
1022 .product_name = "UA-1000",
1023 .ifnum = QUIRK_ANY_INTERFACE,
1024 .type = QUIRK_COMPOSITE,
1025 .data = (const struct snd_usb_audio_quirk[]) {
1026 {
1027 .ifnum = 1,
1028 .type = QUIRK_AUDIO_EDIROL_UA1000
1029 },
1030 {
1031 .ifnum = 2,
1032 .type = QUIRK_AUDIO_EDIROL_UA1000
1033 },
1034 {
1035 .ifnum = 3,
1036 .type = QUIRK_MIDI_FIXED_ENDPOINT,
1037 .data = & (const struct snd_usb_midi_endpoint_info) {
1038 .out_cables = 0x0003,
1039 .in_cables = 0x0003
1040 }
1041 },
1042 {
1043 .ifnum = -1
1044 }
1045 }
1046 }
1047},
1048{
1049 /* has ID 0x0049 when not in "Advanced Driver" mode */ 1019 /* has ID 0x0049 when not in "Advanced Driver" mode */
1050 USB_DEVICE(0x0582, 0x0047), 1020 USB_DEVICE(0x0582, 0x0047),
1051 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { 1021 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
@@ -1266,37 +1236,6 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1266 } 1236 }
1267 } 1237 }
1268}, 1238},
1269/* Roland UA-101 in High-Speed Mode only */
1270{
1271 USB_DEVICE(0x0582, 0x007d),
1272 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1273 .vendor_name = "Roland",
1274 .product_name = "UA-101",
1275 .ifnum = QUIRK_ANY_INTERFACE,
1276 .type = QUIRK_COMPOSITE,
1277 .data = (const struct snd_usb_audio_quirk[]) {
1278 {
1279 .ifnum = 0,
1280 .type = QUIRK_AUDIO_EDIROL_UA101
1281 },
1282 {
1283 .ifnum = 1,
1284 .type = QUIRK_AUDIO_EDIROL_UA101
1285 },
1286 {
1287 .ifnum = 2,
1288 .type = QUIRK_MIDI_FIXED_ENDPOINT,
1289 .data = & (const struct snd_usb_midi_endpoint_info) {
1290 .out_cables = 0x0001,
1291 .in_cables = 0x0001
1292 }
1293 },
1294 {
1295 .ifnum = -1
1296 }
1297 }
1298 }
1299},
1300{ 1239{
1301 /* has ID 0x0081 when not in "Advanced Driver" mode */ 1240 /* has ID 0x0081 when not in "Advanced Driver" mode */
1302 USB_DEVICE(0x0582, 0x0080), 1241 USB_DEVICE(0x0582, 0x0080),
@@ -1563,6 +1502,29 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1563 } 1502 }
1564 } 1503 }
1565}, 1504},
1505{
1506 /* has ID 0x00ea when not in Advanced Driver mode */
1507 USB_DEVICE_VENDOR_SPEC(0x0582, 0x00e9),
1508 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1509 /* .vendor_name = "Roland", */
1510 /* .product_name = "UA-1G", */
1511 .ifnum = QUIRK_ANY_INTERFACE,
1512 .type = QUIRK_COMPOSITE,
1513 .data = (const struct snd_usb_audio_quirk[]) {
1514 {
1515 .ifnum = 0,
1516 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1517 },
1518 {
1519 .ifnum = 1,
1520 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1521 },
1522 {
1523 .ifnum = -1
1524 }
1525 }
1526 }
1527},
1566 1528
1567/* Guillemot devices */ 1529/* Guillemot devices */
1568{ 1530{
@@ -2050,6 +2012,33 @@ YAMAHA_DEVICE(0x7010, "UB99"),
2050 } 2012 }
2051}, 2013},
2052 2014
2015/* Access Music devices */
2016{
2017 /* VirusTI Desktop */
2018 USB_DEVICE_VENDOR_SPEC(0x133e, 0x0815),
2019 .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
2020 .ifnum = QUIRK_ANY_INTERFACE,
2021 .type = QUIRK_COMPOSITE,
2022 .data = &(const struct snd_usb_audio_quirk[]) {
2023 {
2024 .ifnum = 3,
2025 .type = QUIRK_MIDI_FIXED_ENDPOINT,
2026 .data = &(const struct snd_usb_midi_endpoint_info) {
2027 .out_cables = 0x0003,
2028 .in_cables = 0x0003
2029 }
2030 },
2031 {
2032 .ifnum = 4,
2033 .type = QUIRK_IGNORE_INTERFACE
2034 },
2035 {
2036 .ifnum = -1
2037 }
2038 }
2039 }
2040},
2041
2053/* */ 2042/* */
2054{ 2043{
2055 /* aka. Serato Scratch Live DJ Box */ 2044 /* aka. Serato Scratch Live DJ Box */
@@ -2082,6 +2071,165 @@ YAMAHA_DEVICE(0x7010, "UB99"),
2082 } 2071 }
2083}, 2072},
2084 2073
2074/* Hauppauge HVR-950Q and HVR-850 */
2075{
2076 USB_DEVICE_VENDOR_SPEC(0x2040, 0x7200),
2077 .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
2078 USB_DEVICE_ID_MATCH_INT_CLASS |
2079 USB_DEVICE_ID_MATCH_INT_SUBCLASS,
2080 .bInterfaceClass = USB_CLASS_AUDIO,
2081 .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
2082 .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
2083 .vendor_name = "Hauppauge",
2084 .product_name = "HVR-950Q",
2085 .ifnum = QUIRK_ANY_INTERFACE,
2086 .type = QUIRK_AUDIO_ALIGN_TRANSFER,
2087 }
2088},
2089{
2090 USB_DEVICE_VENDOR_SPEC(0x2040, 0x7201),
2091 .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
2092 USB_DEVICE_ID_MATCH_INT_CLASS |
2093 USB_DEVICE_ID_MATCH_INT_SUBCLASS,
2094 .bInterfaceClass = USB_CLASS_AUDIO,
2095 .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
2096 .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
2097 .vendor_name = "Hauppauge",
2098 .product_name = "HVR-950Q",
2099 .ifnum = QUIRK_ANY_INTERFACE,
2100 .type = QUIRK_AUDIO_ALIGN_TRANSFER,
2101 }
2102},
2103{
2104 USB_DEVICE_VENDOR_SPEC(0x2040, 0x7202),
2105 .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
2106 USB_DEVICE_ID_MATCH_INT_CLASS |
2107 USB_DEVICE_ID_MATCH_INT_SUBCLASS,
2108 .bInterfaceClass = USB_CLASS_AUDIO,
2109 .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
2110 .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
2111 .vendor_name = "Hauppauge",
2112 .product_name = "HVR-950Q",
2113 .ifnum = QUIRK_ANY_INTERFACE,
2114 .type = QUIRK_AUDIO_ALIGN_TRANSFER,
2115 }
2116},
2117{
2118 USB_DEVICE_VENDOR_SPEC(0x2040, 0x7203),
2119 .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
2120 USB_DEVICE_ID_MATCH_INT_CLASS |
2121 USB_DEVICE_ID_MATCH_INT_SUBCLASS,
2122 .bInterfaceClass = USB_CLASS_AUDIO,
2123 .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
2124 .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
2125 .vendor_name = "Hauppauge",
2126 .product_name = "HVR-950Q",
2127 .ifnum = QUIRK_ANY_INTERFACE,
2128 .type = QUIRK_AUDIO_ALIGN_TRANSFER,
2129 }
2130},
2131{
2132 USB_DEVICE_VENDOR_SPEC(0x2040, 0x7204),
2133 .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
2134 USB_DEVICE_ID_MATCH_INT_CLASS |
2135 USB_DEVICE_ID_MATCH_INT_SUBCLASS,
2136 .bInterfaceClass = USB_CLASS_AUDIO,
2137 .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
2138 .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
2139 .vendor_name = "Hauppauge",
2140 .product_name = "HVR-950Q",
2141 .ifnum = QUIRK_ANY_INTERFACE,
2142 .type = QUIRK_AUDIO_ALIGN_TRANSFER,
2143 }
2144},
2145{
2146 USB_DEVICE_VENDOR_SPEC(0x2040, 0x7205),
2147 .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
2148 USB_DEVICE_ID_MATCH_INT_CLASS |
2149 USB_DEVICE_ID_MATCH_INT_SUBCLASS,
2150 .bInterfaceClass = USB_CLASS_AUDIO,
2151 .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
2152 .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
2153 .vendor_name = "Hauppauge",
2154 .product_name = "HVR-950Q",
2155 .ifnum = QUIRK_ANY_INTERFACE,
2156 .type = QUIRK_AUDIO_ALIGN_TRANSFER,
2157 }
2158},
2159{
2160 USB_DEVICE_VENDOR_SPEC(0x2040, 0x7250),
2161 .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
2162 USB_DEVICE_ID_MATCH_INT_CLASS |
2163 USB_DEVICE_ID_MATCH_INT_SUBCLASS,
2164 .bInterfaceClass = USB_CLASS_AUDIO,
2165 .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
2166 .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
2167 .vendor_name = "Hauppauge",
2168 .product_name = "HVR-950Q",
2169 .ifnum = QUIRK_ANY_INTERFACE,
2170 .type = QUIRK_AUDIO_ALIGN_TRANSFER,
2171 }
2172},
2173{
2174 USB_DEVICE_VENDOR_SPEC(0x2040, 0x7230),
2175 .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
2176 USB_DEVICE_ID_MATCH_INT_CLASS |
2177 USB_DEVICE_ID_MATCH_INT_SUBCLASS,
2178 .bInterfaceClass = USB_CLASS_AUDIO,
2179 .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
2180 .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
2181 .vendor_name = "Hauppauge",
2182 .product_name = "HVR-850",
2183 .ifnum = QUIRK_ANY_INTERFACE,
2184 .type = QUIRK_AUDIO_ALIGN_TRANSFER,
2185 }
2186},
2187
2188/* Digidesign Mbox */
2189{
2190 /* Thanks to Clemens Ladisch <clemens@ladisch.de> */
2191 USB_DEVICE(0x0dba, 0x1000),
2192 .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
2193 .vendor_name = "Digidesign",
2194 .product_name = "MBox",
2195 .ifnum = QUIRK_ANY_INTERFACE,
2196 .type = QUIRK_COMPOSITE,
2197 .data = (const struct snd_usb_audio_quirk[]){
2198 {
2199 .ifnum = 0,
2200 .type = QUIRK_IGNORE_INTERFACE,
2201 },
2202 {
2203 .ifnum = 1,
2204 .type = QUIRK_AUDIO_FIXED_ENDPOINT,
2205 .data = &(const struct audioformat) {
2206 .format = SNDRV_PCM_FORMAT_S24_3BE,
2207 .channels = 2,
2208 .iface = 1,
2209 .altsetting = 1,
2210 .altset_idx = 1,
2211 .attributes = UAC_EP_CS_ATTR_SAMPLE_RATE,
2212 .endpoint = 0x02,
2213 .ep_attr = 0x01,
2214 .maxpacksize = 0x130,
2215 .rates = SNDRV_PCM_RATE_44100 |
2216 SNDRV_PCM_RATE_48000,
2217 .rate_min = 44100,
2218 .rate_max = 48000,
2219 .nr_rates = 2,
2220 .rate_table = (unsigned int[]) {
2221 44100, 48000
2222 }
2223 }
2224 },
2225 {
2226 .ifnum = -1
2227 }
2228 }
2229
2230 }
2231},
2232
2085{ 2233{
2086 /* 2234 /*
2087 * Some USB MIDI devices don't have an audio control interface, 2235 * Some USB MIDI devices don't have an audio control interface,
@@ -2090,7 +2238,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
2090 .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS | 2238 .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS |
2091 USB_DEVICE_ID_MATCH_INT_SUBCLASS, 2239 USB_DEVICE_ID_MATCH_INT_SUBCLASS,
2092 .bInterfaceClass = USB_CLASS_AUDIO, 2240 .bInterfaceClass = USB_CLASS_AUDIO,
2093 .bInterfaceSubClass = USB_SUBCLASS_MIDI_STREAMING, 2241 .bInterfaceSubClass = USB_SUBCLASS_MIDISTREAMING,
2094 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { 2242 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
2095 .ifnum = QUIRK_ANY_INTERFACE, 2243 .ifnum = QUIRK_ANY_INTERFACE,
2096 .type = QUIRK_MIDI_STANDARD_INTERFACE 2244 .type = QUIRK_MIDI_STANDARD_INTERFACE
diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c
index 99f33766cd51..9ca9a13a78da 100644
--- a/sound/usb/usx2y/us122l.c
+++ b/sound/usb/usx2y/us122l.c
@@ -16,6 +16,9 @@
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>
20#include <linux/usb.h>
21#include <linux/usb/audio.h>
19#include <sound/core.h> 22#include <sound/core.h>
20#include <sound/hwdep.h> 23#include <sound/hwdep.h>
21#include <sound/pcm.h> 24#include <sound/pcm.h>
@@ -59,11 +62,33 @@ static int us122l_create_usbmidi(struct snd_card *card)
59 .type = QUIRK_MIDI_US122L, 62 .type = QUIRK_MIDI_US122L,
60 .data = &quirk_data 63 .data = &quirk_data
61 }; 64 };
62 struct usb_device *dev = US122L(card)->chip.dev; 65 struct usb_device *dev = US122L(card)->dev;
63 struct usb_interface *iface = usb_ifnum_to_if(dev, 1); 66 struct usb_interface *iface = usb_ifnum_to_if(dev, 1);
64 67
65 return snd_usb_create_midi_interface(&US122L(card)->chip, 68 return snd_usbmidi_create(card, iface,
66 iface, &quirk); 69 &US122L(card)->midi_list, &quirk);
70}
71
72static int us144_create_usbmidi(struct snd_card *card)
73{
74 static struct snd_usb_midi_endpoint_info quirk_data = {
75 .out_ep = 4,
76 .in_ep = 3,
77 .out_cables = 0x001,
78 .in_cables = 0x001
79 };
80 static struct snd_usb_audio_quirk quirk = {
81 .vendor_name = "US144",
82 .product_name = NAME_ALLCAPS,
83 .ifnum = 0,
84 .type = QUIRK_MIDI_US122L,
85 .data = &quirk_data
86 };
87 struct usb_device *dev = US122L(card)->dev;
88 struct usb_interface *iface = usb_ifnum_to_if(dev, 0);
89
90 return snd_usbmidi_create(card, iface,
91 &US122L(card)->midi_list, &quirk);
67} 92}
68 93
69/* 94/*
@@ -171,7 +196,13 @@ static int usb_stream_hwdep_open(struct snd_hwdep *hw, struct file *file)
171 196
172 if (!us122l->first) 197 if (!us122l->first)
173 us122l->first = file; 198 us122l->first = file;
174 iface = usb_ifnum_to_if(us122l->chip.dev, 1); 199
200 if (us122l->dev->descriptor.idProduct == USB_ID_US144 ||
201 us122l->dev->descriptor.idProduct == USB_ID_US144MKII) {
202 iface = usb_ifnum_to_if(us122l->dev, 0);
203 usb_autopm_get_interface(iface);
204 }
205 iface = usb_ifnum_to_if(us122l->dev, 1);
175 usb_autopm_get_interface(iface); 206 usb_autopm_get_interface(iface);
176 return 0; 207 return 0;
177} 208}
@@ -179,8 +210,15 @@ static int usb_stream_hwdep_open(struct snd_hwdep *hw, struct file *file)
179static int usb_stream_hwdep_release(struct snd_hwdep *hw, struct file *file) 210static int usb_stream_hwdep_release(struct snd_hwdep *hw, struct file *file)
180{ 211{
181 struct us122l *us122l = hw->private_data; 212 struct us122l *us122l = hw->private_data;
182 struct usb_interface *iface = usb_ifnum_to_if(us122l->chip.dev, 1); 213 struct usb_interface *iface;
183 snd_printdd(KERN_DEBUG "%p %p\n", hw, file); 214 snd_printdd(KERN_DEBUG "%p %p\n", hw, file);
215
216 if (us122l->dev->descriptor.idProduct == USB_ID_US144 ||
217 us122l->dev->descriptor.idProduct == USB_ID_US144MKII) {
218 iface = usb_ifnum_to_if(us122l->dev, 0);
219 usb_autopm_put_interface(iface);
220 }
221 iface = usb_ifnum_to_if(us122l->dev, 1);
184 usb_autopm_put_interface(iface); 222 usb_autopm_put_interface(iface);
185 if (us122l->first == file) 223 if (us122l->first == file)
186 us122l->first = NULL; 224 us122l->first = NULL;
@@ -264,7 +302,7 @@ static unsigned int usb_stream_hwdep_poll(struct snd_hwdep *hw,
264static void us122l_stop(struct us122l *us122l) 302static void us122l_stop(struct us122l *us122l)
265{ 303{
266 struct list_head *p; 304 struct list_head *p;
267 list_for_each(p, &us122l->chip.midi_list) 305 list_for_each(p, &us122l->midi_list)
268 snd_usbmidi_input_stop(p); 306 snd_usbmidi_input_stop(p);
269 307
270 usb_stream_stop(&us122l->sk); 308 usb_stream_stop(&us122l->sk);
@@ -280,9 +318,9 @@ static int us122l_set_sample_rate(struct usb_device *dev, int rate)
280 data[0] = rate; 318 data[0] = rate;
281 data[1] = rate >> 8; 319 data[1] = rate >> 8;
282 data[2] = rate >> 16; 320 data[2] = rate >> 16;
283 err = us122l_ctl_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, 321 err = us122l_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR,
284 USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, 322 USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT,
285 SAMPLING_FREQ_CONTROL << 8, ep, data, 3, 1000); 323 UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep, data, 3, 1000);
286 if (err < 0) 324 if (err < 0)
287 snd_printk(KERN_ERR "%d: cannot set freq %d to ep 0x%x\n", 325 snd_printk(KERN_ERR "%d: cannot set freq %d to ep 0x%x\n",
288 dev->devnum, rate, ep); 326 dev->devnum, rate, ep);
@@ -297,7 +335,7 @@ static bool us122l_start(struct us122l *us122l,
297 unsigned use_packsize = 0; 335 unsigned use_packsize = 0;
298 bool success = false; 336 bool success = false;
299 337
300 if (us122l->chip.dev->speed == USB_SPEED_HIGH) { 338 if (us122l->dev->speed == USB_SPEED_HIGH) {
301 /* The us-122l's descriptor defaults to iso max_packsize 78, 339 /* The us-122l's descriptor defaults to iso max_packsize 78,
302 which isn't needed for samplerates <= 48000. 340 which isn't needed for samplerates <= 48000.
303 Lets save some memory: 341 Lets save some memory:
@@ -314,11 +352,11 @@ static bool us122l_start(struct us122l *us122l,
314 break; 352 break;
315 } 353 }
316 } 354 }
317 if (!usb_stream_new(&us122l->sk, us122l->chip.dev, 1, 2, 355 if (!usb_stream_new(&us122l->sk, us122l->dev, 1, 2,
318 rate, use_packsize, period_frames, 6)) 356 rate, use_packsize, period_frames, 6))
319 goto out; 357 goto out;
320 358
321 err = us122l_set_sample_rate(us122l->chip.dev, rate); 359 err = us122l_set_sample_rate(us122l->dev, rate);
322 if (err < 0) { 360 if (err < 0) {
323 us122l_stop(us122l); 361 us122l_stop(us122l);
324 snd_printk(KERN_ERR "us122l_set_sample_rate error \n"); 362 snd_printk(KERN_ERR "us122l_set_sample_rate error \n");
@@ -330,7 +368,7 @@ static bool us122l_start(struct us122l *us122l,
330 snd_printk(KERN_ERR "us122l_start error %i \n", err); 368 snd_printk(KERN_ERR "us122l_start error %i \n", err);
331 goto out; 369 goto out;
332 } 370 }
333 list_for_each(p, &us122l->chip.midi_list) 371 list_for_each(p, &us122l->midi_list)
334 snd_usbmidi_input_start(p); 372 snd_usbmidi_input_start(p);
335 success = true; 373 success = true;
336out: 374out:
@@ -357,7 +395,7 @@ static int usb_stream_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
357 err = -ENXIO; 395 err = -ENXIO;
358 goto free; 396 goto free;
359 } 397 }
360 high_speed = us122l->chip.dev->speed == USB_SPEED_HIGH; 398 high_speed = us122l->dev->speed == USB_SPEED_HIGH;
361 if ((cfg->sample_rate != 44100 && cfg->sample_rate != 48000 && 399 if ((cfg->sample_rate != 44100 && cfg->sample_rate != 48000 &&
362 (!high_speed || 400 (!high_speed ||
363 (cfg->sample_rate != 88200 && cfg->sample_rate != 96000))) || 401 (cfg->sample_rate != 88200 && cfg->sample_rate != 96000))) ||
@@ -417,7 +455,7 @@ static int usb_stream_hwdep_new(struct snd_card *card)
417{ 455{
418 int err; 456 int err;
419 struct snd_hwdep *hw; 457 struct snd_hwdep *hw;
420 struct usb_device *dev = US122L(card)->chip.dev; 458 struct usb_device *dev = US122L(card)->dev;
421 459
422 err = snd_hwdep_new(card, SND_USB_STREAM_ID, 0, &hw); 460 err = snd_hwdep_new(card, SND_USB_STREAM_ID, 0, &hw);
423 if (err < 0) 461 if (err < 0)
@@ -443,19 +481,31 @@ static bool us122l_create_card(struct snd_card *card)
443 int err; 481 int err;
444 struct us122l *us122l = US122L(card); 482 struct us122l *us122l = US122L(card);
445 483
446 err = usb_set_interface(us122l->chip.dev, 1, 1); 484 if (us122l->dev->descriptor.idProduct == USB_ID_US144 ||
485 us122l->dev->descriptor.idProduct == USB_ID_US144MKII) {
486 err = usb_set_interface(us122l->dev, 0, 1);
487 if (err) {
488 snd_printk(KERN_ERR "usb_set_interface error \n");
489 return false;
490 }
491 }
492 err = usb_set_interface(us122l->dev, 1, 1);
447 if (err) { 493 if (err) {
448 snd_printk(KERN_ERR "usb_set_interface error \n"); 494 snd_printk(KERN_ERR "usb_set_interface error \n");
449 return false; 495 return false;
450 } 496 }
451 497
452 pt_info_set(us122l->chip.dev, 0x11); 498 pt_info_set(us122l->dev, 0x11);
453 pt_info_set(us122l->chip.dev, 0x10); 499 pt_info_set(us122l->dev, 0x10);
454 500
455 if (!us122l_start(us122l, 44100, 256)) 501 if (!us122l_start(us122l, 44100, 256))
456 return false; 502 return false;
457 503
458 err = us122l_create_usbmidi(card); 504 if (us122l->dev->descriptor.idProduct == USB_ID_US144 ||
505 us122l->dev->descriptor.idProduct == USB_ID_US144MKII)
506 err = us144_create_usbmidi(card);
507 else
508 err = us122l_create_usbmidi(card);
459 if (err < 0) { 509 if (err < 0) {
460 snd_printk(KERN_ERR "us122l_create_usbmidi error %i \n", err); 510 snd_printk(KERN_ERR "us122l_create_usbmidi error %i \n", err);
461 us122l_stop(us122l); 511 us122l_stop(us122l);
@@ -465,7 +515,7 @@ static bool us122l_create_card(struct snd_card *card)
465 if (err < 0) { 515 if (err < 0) {
466/* release the midi resources */ 516/* release the midi resources */
467 struct list_head *p; 517 struct list_head *p;
468 list_for_each(p, &us122l->chip.midi_list) 518 list_for_each(p, &us122l->midi_list)
469 snd_usbmidi_disconnect(p); 519 snd_usbmidi_disconnect(p);
470 520
471 us122l_stop(us122l); 521 us122l_stop(us122l);
@@ -477,7 +527,7 @@ static bool us122l_create_card(struct snd_card *card)
477static void snd_us122l_free(struct snd_card *card) 527static void snd_us122l_free(struct snd_card *card)
478{ 528{
479 struct us122l *us122l = US122L(card); 529 struct us122l *us122l = US122L(card);
480 int index = us122l->chip.index; 530 int index = us122l->card_index;
481 if (index >= 0 && index < SNDRV_CARDS) 531 if (index >= 0 && index < SNDRV_CARDS)
482 snd_us122l_card_used[index] = 0; 532 snd_us122l_card_used[index] = 0;
483} 533}
@@ -497,13 +547,12 @@ static int usx2y_create_card(struct usb_device *device, struct snd_card **cardp)
497 sizeof(struct us122l), &card); 547 sizeof(struct us122l), &card);
498 if (err < 0) 548 if (err < 0)
499 return err; 549 return err;
500 snd_us122l_card_used[US122L(card)->chip.index = dev] = 1; 550 snd_us122l_card_used[US122L(card)->card_index = dev] = 1;
501 card->private_free = snd_us122l_free; 551 card->private_free = snd_us122l_free;
502 US122L(card)->chip.dev = device; 552 US122L(card)->dev = device;
503 US122L(card)->chip.card = card;
504 mutex_init(&US122L(card)->mutex); 553 mutex_init(&US122L(card)->mutex);
505 init_waitqueue_head(&US122L(card)->sk.sleep); 554 init_waitqueue_head(&US122L(card)->sk.sleep);
506 INIT_LIST_HEAD(&US122L(card)->chip.midi_list); 555 INIT_LIST_HEAD(&US122L(card)->midi_list);
507 strcpy(card->driver, "USB "NAME_ALLCAPS""); 556 strcpy(card->driver, "USB "NAME_ALLCAPS"");
508 sprintf(card->shortname, "TASCAM "NAME_ALLCAPS""); 557 sprintf(card->shortname, "TASCAM "NAME_ALLCAPS"");
509 sprintf(card->longname, "%s (%x:%x if %d at %03d/%03d)", 558 sprintf(card->longname, "%s (%x:%x if %d at %03d/%03d)",
@@ -511,8 +560,8 @@ static int usx2y_create_card(struct usb_device *device, struct snd_card **cardp)
511 le16_to_cpu(device->descriptor.idVendor), 560 le16_to_cpu(device->descriptor.idVendor),
512 le16_to_cpu(device->descriptor.idProduct), 561 le16_to_cpu(device->descriptor.idProduct),
513 0, 562 0,
514 US122L(card)->chip.dev->bus->busnum, 563 US122L(card)->dev->bus->busnum,
515 US122L(card)->chip.dev->devnum 564 US122L(card)->dev->devnum
516 ); 565 );
517 *cardp = card; 566 *cardp = card;
518 return 0; 567 return 0;
@@ -542,6 +591,7 @@ static int us122l_usb_probe(struct usb_interface *intf,
542 return err; 591 return err;
543 } 592 }
544 593
594 usb_get_intf(usb_ifnum_to_if(device, 0));
545 usb_get_dev(device); 595 usb_get_dev(device);
546 *cardp = card; 596 *cardp = card;
547 return 0; 597 return 0;
@@ -550,9 +600,17 @@ static int us122l_usb_probe(struct usb_interface *intf,
550static int snd_us122l_probe(struct usb_interface *intf, 600static int snd_us122l_probe(struct usb_interface *intf,
551 const struct usb_device_id *id) 601 const struct usb_device_id *id)
552{ 602{
603 struct usb_device *device = interface_to_usbdev(intf);
553 struct snd_card *card; 604 struct snd_card *card;
554 int err; 605 int err;
555 606
607 if ((device->descriptor.idProduct == USB_ID_US144 ||
608 device->descriptor.idProduct == USB_ID_US144MKII)
609 && device->speed == USB_SPEED_HIGH) {
610 snd_printk(KERN_ERR "disable ehci-hcd to run US-144 \n");
611 return -ENODEV;
612 }
613
556 snd_printdd(KERN_DEBUG"%p:%i\n", 614 snd_printdd(KERN_DEBUG"%p:%i\n",
557 intf, intf->cur_altsetting->desc.bInterfaceNumber); 615 intf, intf->cur_altsetting->desc.bInterfaceNumber);
558 if (intf->cur_altsetting->desc.bInterfaceNumber != 1) 616 if (intf->cur_altsetting->desc.bInterfaceNumber != 1)
@@ -584,15 +642,15 @@ static void snd_us122l_disconnect(struct usb_interface *intf)
584 mutex_lock(&us122l->mutex); 642 mutex_lock(&us122l->mutex);
585 us122l_stop(us122l); 643 us122l_stop(us122l);
586 mutex_unlock(&us122l->mutex); 644 mutex_unlock(&us122l->mutex);
587 us122l->chip.shutdown = 1;
588 645
589/* release the midi resources */ 646/* release the midi resources */
590 list_for_each(p, &us122l->chip.midi_list) { 647 list_for_each(p, &us122l->midi_list) {
591 snd_usbmidi_disconnect(p); 648 snd_usbmidi_disconnect(p);
592 } 649 }
593 650
594 usb_put_intf(intf); 651 usb_put_intf(usb_ifnum_to_if(us122l->dev, 0));
595 usb_put_dev(us122l->chip.dev); 652 usb_put_intf(usb_ifnum_to_if(us122l->dev, 1));
653 usb_put_dev(us122l->dev);
596 654
597 while (atomic_read(&us122l->mmap_count)) 655 while (atomic_read(&us122l->mmap_count))
598 msleep(500); 656 msleep(500);
@@ -615,7 +673,7 @@ static int snd_us122l_suspend(struct usb_interface *intf, pm_message_t message)
615 if (!us122l) 673 if (!us122l)
616 return 0; 674 return 0;
617 675
618 list_for_each(p, &us122l->chip.midi_list) 676 list_for_each(p, &us122l->midi_list)
619 snd_usbmidi_input_stop(p); 677 snd_usbmidi_input_stop(p);
620 678
621 mutex_lock(&us122l->mutex); 679 mutex_lock(&us122l->mutex);
@@ -642,16 +700,24 @@ static int snd_us122l_resume(struct usb_interface *intf)
642 700
643 mutex_lock(&us122l->mutex); 701 mutex_lock(&us122l->mutex);
644 /* needed, doesn't restart without: */ 702 /* needed, doesn't restart without: */
645 err = usb_set_interface(us122l->chip.dev, 1, 1); 703 if (us122l->dev->descriptor.idProduct == USB_ID_US144 ||
704 us122l->dev->descriptor.idProduct == USB_ID_US144MKII) {
705 err = usb_set_interface(us122l->dev, 0, 1);
706 if (err) {
707 snd_printk(KERN_ERR "usb_set_interface error \n");
708 goto unlock;
709 }
710 }
711 err = usb_set_interface(us122l->dev, 1, 1);
646 if (err) { 712 if (err) {
647 snd_printk(KERN_ERR "usb_set_interface error \n"); 713 snd_printk(KERN_ERR "usb_set_interface error \n");
648 goto unlock; 714 goto unlock;
649 } 715 }
650 716
651 pt_info_set(us122l->chip.dev, 0x11); 717 pt_info_set(us122l->dev, 0x11);
652 pt_info_set(us122l->chip.dev, 0x10); 718 pt_info_set(us122l->dev, 0x10);
653 719
654 err = us122l_set_sample_rate(us122l->chip.dev, 720 err = us122l_set_sample_rate(us122l->dev,
655 us122l->sk.s->cfg.sample_rate); 721 us122l->sk.s->cfg.sample_rate);
656 if (err < 0) { 722 if (err < 0) {
657 snd_printk(KERN_ERR "us122l_set_sample_rate error \n"); 723 snd_printk(KERN_ERR "us122l_set_sample_rate error \n");
@@ -661,7 +727,7 @@ static int snd_us122l_resume(struct usb_interface *intf)
661 if (err) 727 if (err)
662 goto unlock; 728 goto unlock;
663 729
664 list_for_each(p, &us122l->chip.midi_list) 730 list_for_each(p, &us122l->midi_list)
665 snd_usbmidi_input_start(p); 731 snd_usbmidi_input_start(p);
666unlock: 732unlock:
667 mutex_unlock(&us122l->mutex); 733 mutex_unlock(&us122l->mutex);
@@ -675,11 +741,21 @@ static struct usb_device_id snd_us122l_usb_id_table[] = {
675 .idVendor = 0x0644, 741 .idVendor = 0x0644,
676 .idProduct = USB_ID_US122L 742 .idProduct = USB_ID_US122L
677 }, 743 },
678/* { */ /* US-144 maybe works when @USB1.1. Untested. */ 744 { /* US-144 only works at USB1.1! Disable module ehci-hcd. */
679/* .match_flags = USB_DEVICE_ID_MATCH_DEVICE, */ 745 .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
680/* .idVendor = 0x0644, */ 746 .idVendor = 0x0644,
681/* .idProduct = USB_ID_US144 */ 747 .idProduct = USB_ID_US144
682/* }, */ 748 },
749 {
750 .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
751 .idVendor = 0x0644,
752 .idProduct = USB_ID_US122MKII
753 },
754 {
755 .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
756 .idVendor = 0x0644,
757 .idProduct = USB_ID_US144MKII
758 },
683 { /* terminator */ } 759 { /* terminator */ }
684}; 760};
685 761
diff --git a/sound/usb/usx2y/us122l.h b/sound/usb/usx2y/us122l.h
index 3d10c4b2a0f5..f263b3f96c86 100644
--- a/sound/usb/usx2y/us122l.h
+++ b/sound/usb/usx2y/us122l.h
@@ -3,7 +3,8 @@
3 3
4 4
5struct us122l { 5struct us122l {
6 struct snd_usb_audio chip; 6 struct usb_device *dev;
7 int card_index;
7 int stride; 8 int stride;
8 struct usb_stream_kernel sk; 9 struct usb_stream_kernel sk;
9 10
@@ -12,6 +13,7 @@ struct us122l {
12 unsigned second_periods_polled; 13 unsigned second_periods_polled;
13 struct file *master; 14 struct file *master;
14 struct file *slave; 15 struct file *slave;
16 struct list_head midi_list;
15 17
16 atomic_t mmap_count; 18 atomic_t mmap_count;
17}; 19};
@@ -23,5 +25,7 @@ struct us122l {
23 25
24#define USB_ID_US122L 0x800E 26#define USB_ID_US122L 0x800E
25#define USB_ID_US144 0x800F 27#define USB_ID_US144 0x800F
28#define USB_ID_US122MKII 0x8021
29#define USB_ID_US144MKII 0x8020
26 30
27#endif 31#endif
diff --git a/sound/usb/usx2y/usX2Yhwdep.c b/sound/usb/usx2y/usX2Yhwdep.c
index 52e04b2f35d3..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>
@@ -114,7 +115,7 @@ static int snd_usX2Y_hwdep_dsp_status(struct snd_hwdep *hw,
114 struct usX2Ydev *us428 = hw->private_data; 115 struct usX2Ydev *us428 = hw->private_data;
115 int id = -1; 116 int id = -1;
116 117
117 switch (le16_to_cpu(us428->chip.dev->descriptor.idProduct)) { 118 switch (le16_to_cpu(us428->dev->descriptor.idProduct)) {
118 case USB_ID_US122: 119 case USB_ID_US122:
119 id = USX2Y_TYPE_122; 120 id = USX2Y_TYPE_122;
120 break; 121 break;
@@ -164,14 +165,14 @@ static int usX2Y_create_usbmidi(struct snd_card *card)
164 .type = QUIRK_MIDI_FIXED_ENDPOINT, 165 .type = QUIRK_MIDI_FIXED_ENDPOINT,
165 .data = &quirk_data_2 166 .data = &quirk_data_2
166 }; 167 };
167 struct usb_device *dev = usX2Y(card)->chip.dev; 168 struct usb_device *dev = usX2Y(card)->dev;
168 struct usb_interface *iface = usb_ifnum_to_if(dev, 0); 169 struct usb_interface *iface = usb_ifnum_to_if(dev, 0);
169 struct snd_usb_audio_quirk *quirk = 170 struct snd_usb_audio_quirk *quirk =
170 le16_to_cpu(dev->descriptor.idProduct) == USB_ID_US428 ? 171 le16_to_cpu(dev->descriptor.idProduct) == USB_ID_US428 ?
171 &quirk_2 : &quirk_1; 172 &quirk_2 : &quirk_1;
172 173
173 snd_printdd("usX2Y_create_usbmidi \n"); 174 snd_printdd("usX2Y_create_usbmidi \n");
174 return snd_usb_create_midi_interface(&usX2Y(card)->chip, iface, quirk); 175 return snd_usbmidi_create(card, iface, &usX2Y(card)->midi_list, quirk);
175} 176}
176 177
177static int usX2Y_create_alsa_devices(struct snd_card *card) 178static int usX2Y_create_alsa_devices(struct snd_card *card)
@@ -202,7 +203,7 @@ static int snd_usX2Y_hwdep_dsp_load(struct snd_hwdep *hw,
202 snd_printdd( "dsp_load %s\n", dsp->name); 203 snd_printdd( "dsp_load %s\n", dsp->name);
203 204
204 if (access_ok(VERIFY_READ, dsp->image, dsp->length)) { 205 if (access_ok(VERIFY_READ, dsp->image, dsp->length)) {
205 struct usb_device* dev = priv->chip.dev; 206 struct usb_device* dev = priv->dev;
206 char *buf; 207 char *buf;
207 208
208 buf = memdup_user(dsp->image, dsp->length); 209 buf = memdup_user(dsp->image, dsp->length);
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 cb4bb8373ca2..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>
@@ -239,8 +240,8 @@ static void i_usX2Y_In04Int(struct urb *urb)
239 for (j = 0; j < URBS_AsyncSeq && !err; ++j) 240 for (j = 0; j < URBS_AsyncSeq && !err; ++j)
240 if (0 == usX2Y->AS04.urb[j]->status) { 241 if (0 == usX2Y->AS04.urb[j]->status) {
241 struct us428_p4out *p4out = us428ctls->p4out + send; // FIXME if more than 1 p4out is new, 1 gets lost. 242 struct us428_p4out *p4out = us428ctls->p4out + send; // FIXME if more than 1 p4out is new, 1 gets lost.
242 usb_fill_bulk_urb(usX2Y->AS04.urb[j], usX2Y->chip.dev, 243 usb_fill_bulk_urb(usX2Y->AS04.urb[j], usX2Y->dev,
243 usb_sndbulkpipe(usX2Y->chip.dev, 0x04), &p4out->val.vol, 244 usb_sndbulkpipe(usX2Y->dev, 0x04), &p4out->val.vol,
244 p4out->type == eLT_Light ? sizeof(struct us428_lights) : 5, 245 p4out->type == eLT_Light ? sizeof(struct us428_lights) : 5,
245 i_usX2Y_Out04Int, usX2Y); 246 i_usX2Y_Out04Int, usX2Y);
246 err = usb_submit_urb(usX2Y->AS04.urb[j], GFP_ATOMIC); 247 err = usb_submit_urb(usX2Y->AS04.urb[j], GFP_ATOMIC);
@@ -253,7 +254,7 @@ static void i_usX2Y_In04Int(struct urb *urb)
253 if (err) 254 if (err)
254 snd_printk(KERN_ERR "In04Int() usb_submit_urb err=%i\n", err); 255 snd_printk(KERN_ERR "In04Int() usb_submit_urb err=%i\n", err);
255 256
256 urb->dev = usX2Y->chip.dev; 257 urb->dev = usX2Y->dev;
257 usb_submit_urb(urb, GFP_ATOMIC); 258 usb_submit_urb(urb, GFP_ATOMIC);
258} 259}
259 260
@@ -273,8 +274,8 @@ int usX2Y_AsyncSeq04_init(struct usX2Ydev *usX2Y)
273 err = -ENOMEM; 274 err = -ENOMEM;
274 break; 275 break;
275 } 276 }
276 usb_fill_bulk_urb( usX2Y->AS04.urb[i], usX2Y->chip.dev, 277 usb_fill_bulk_urb( usX2Y->AS04.urb[i], usX2Y->dev,
277 usb_sndbulkpipe(usX2Y->chip.dev, 0x04), 278 usb_sndbulkpipe(usX2Y->dev, 0x04),
278 usX2Y->AS04.buffer + URB_DataLen_AsyncSeq*i, 0, 279 usX2Y->AS04.buffer + URB_DataLen_AsyncSeq*i, 0,
279 i_usX2Y_Out04Int, usX2Y 280 i_usX2Y_Out04Int, usX2Y
280 ); 281 );
@@ -293,7 +294,7 @@ int usX2Y_In04_init(struct usX2Ydev *usX2Y)
293 } 294 }
294 295
295 init_waitqueue_head(&usX2Y->In04WaitQueue); 296 init_waitqueue_head(&usX2Y->In04WaitQueue);
296 usb_fill_int_urb(usX2Y->In04urb, usX2Y->chip.dev, usb_rcvintpipe(usX2Y->chip.dev, 0x4), 297 usb_fill_int_urb(usX2Y->In04urb, usX2Y->dev, usb_rcvintpipe(usX2Y->dev, 0x4),
297 usX2Y->In04Buf, 21, 298 usX2Y->In04Buf, 21,
298 i_usX2Y_In04Int, usX2Y, 299 i_usX2Y_In04Int, usX2Y,
299 10); 300 10);
@@ -348,13 +349,12 @@ static int usX2Y_create_card(struct usb_device *device, struct snd_card **cardp)
348 sizeof(struct usX2Ydev), &card); 349 sizeof(struct usX2Ydev), &card);
349 if (err < 0) 350 if (err < 0)
350 return err; 351 return err;
351 snd_usX2Y_card_used[usX2Y(card)->chip.index = dev] = 1; 352 snd_usX2Y_card_used[usX2Y(card)->card_index = dev] = 1;
352 card->private_free = snd_usX2Y_card_private_free; 353 card->private_free = snd_usX2Y_card_private_free;
353 usX2Y(card)->chip.dev = device; 354 usX2Y(card)->dev = device;
354 usX2Y(card)->chip.card = card;
355 init_waitqueue_head(&usX2Y(card)->prepare_wait_queue); 355 init_waitqueue_head(&usX2Y(card)->prepare_wait_queue);
356 mutex_init(&usX2Y(card)->prepare_mutex); 356 mutex_init(&usX2Y(card)->prepare_mutex);
357 INIT_LIST_HEAD(&usX2Y(card)->chip.midi_list); 357 INIT_LIST_HEAD(&usX2Y(card)->midi_list);
358 strcpy(card->driver, "USB "NAME_ALLCAPS""); 358 strcpy(card->driver, "USB "NAME_ALLCAPS"");
359 sprintf(card->shortname, "TASCAM "NAME_ALLCAPS""); 359 sprintf(card->shortname, "TASCAM "NAME_ALLCAPS"");
360 sprintf(card->longname, "%s (%x:%x if %d at %03d/%03d)", 360 sprintf(card->longname, "%s (%x:%x if %d at %03d/%03d)",
@@ -362,7 +362,7 @@ static int usX2Y_create_card(struct usb_device *device, struct snd_card **cardp)
362 le16_to_cpu(device->descriptor.idVendor), 362 le16_to_cpu(device->descriptor.idVendor),
363 le16_to_cpu(device->descriptor.idProduct), 363 le16_to_cpu(device->descriptor.idProduct),
364 0,//us428(card)->usbmidi.ifnum, 364 0,//us428(card)->usbmidi.ifnum,
365 usX2Y(card)->chip.dev->bus->busnum, usX2Y(card)->chip.dev->devnum 365 usX2Y(card)->dev->bus->busnum, usX2Y(card)->dev->devnum
366 ); 366 );
367 *cardp = card; 367 *cardp = card;
368 return 0; 368 return 0;
@@ -432,8 +432,8 @@ static void snd_usX2Y_card_private_free(struct snd_card *card)
432 usb_free_urb(usX2Y(card)->In04urb); 432 usb_free_urb(usX2Y(card)->In04urb);
433 if (usX2Y(card)->us428ctls_sharedmem) 433 if (usX2Y(card)->us428ctls_sharedmem)
434 snd_free_pages(usX2Y(card)->us428ctls_sharedmem, sizeof(*usX2Y(card)->us428ctls_sharedmem)); 434 snd_free_pages(usX2Y(card)->us428ctls_sharedmem, sizeof(*usX2Y(card)->us428ctls_sharedmem));
435 if (usX2Y(card)->chip.index >= 0 && usX2Y(card)->chip.index < SNDRV_CARDS) 435 if (usX2Y(card)->card_index >= 0 && usX2Y(card)->card_index < SNDRV_CARDS)
436 snd_usX2Y_card_used[usX2Y(card)->chip.index] = 0; 436 snd_usX2Y_card_used[usX2Y(card)->card_index] = 0;
437} 437}
438 438
439/* 439/*
@@ -445,13 +445,12 @@ static void usX2Y_usb_disconnect(struct usb_device *device, void* ptr)
445 struct snd_card *card = ptr; 445 struct snd_card *card = ptr;
446 struct usX2Ydev *usX2Y = usX2Y(card); 446 struct usX2Ydev *usX2Y = usX2Y(card);
447 struct list_head *p; 447 struct list_head *p;
448 usX2Y->chip.shutdown = 1;
449 usX2Y->chip_status = USX2Y_STAT_CHIP_HUP; 448 usX2Y->chip_status = USX2Y_STAT_CHIP_HUP;
450 usX2Y_unlinkSeq(&usX2Y->AS04); 449 usX2Y_unlinkSeq(&usX2Y->AS04);
451 usb_kill_urb(usX2Y->In04urb); 450 usb_kill_urb(usX2Y->In04urb);
452 snd_card_disconnect(card); 451 snd_card_disconnect(card);
453 /* release the midi resources */ 452 /* release the midi resources */
454 list_for_each(p, &usX2Y->chip.midi_list) { 453 list_for_each(p, &usX2Y->midi_list) {
455 snd_usbmidi_disconnect(p); 454 snd_usbmidi_disconnect(p);
456 } 455 }
457 if (usX2Y->us428ctls_sharedmem) 456 if (usX2Y->us428ctls_sharedmem)
diff --git a/sound/usb/usx2y/usbusx2y.h b/sound/usb/usx2y/usbusx2y.h
index 456b5fdbc339..1d174cea352b 100644
--- a/sound/usb/usx2y/usbusx2y.h
+++ b/sound/usb/usx2y/usbusx2y.h
@@ -22,7 +22,8 @@ struct snd_usX2Y_urbSeq {
22#include "usx2yhwdeppcm.h" 22#include "usx2yhwdeppcm.h"
23 23
24struct usX2Ydev { 24struct usX2Ydev {
25 struct snd_usb_audio chip; 25 struct usb_device *dev;
26 int card_index;
26 int stride; 27 int stride;
27 struct urb *In04urb; 28 struct urb *In04urb;
28 void *In04Buf; 29 void *In04Buf;
@@ -42,6 +43,9 @@ struct usX2Ydev {
42 struct snd_usX2Y_substream *subs[4]; 43 struct snd_usX2Y_substream *subs[4];
43 struct snd_usX2Y_substream * volatile prepare_subs; 44 struct snd_usX2Y_substream * volatile prepare_subs;
44 wait_queue_head_t prepare_wait_queue; 45 wait_queue_head_t prepare_wait_queue;
46 struct list_head midi_list;
47 struct list_head pcm_list;
48 int pcm_devs;
45}; 49};
46 50
47 51
diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c
index 9efd27f6b52f..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>
@@ -199,7 +200,7 @@ static int usX2Y_urb_submit(struct snd_usX2Y_substream *subs, struct urb *urb, i
199 return -ENODEV; 200 return -ENODEV;
200 urb->start_frame = (frame + NRURBS * nr_of_packs()); // let hcd do rollover sanity checks 201 urb->start_frame = (frame + NRURBS * nr_of_packs()); // let hcd do rollover sanity checks
201 urb->hcpriv = NULL; 202 urb->hcpriv = NULL;
202 urb->dev = subs->usX2Y->chip.dev; /* we need to set this at each time */ 203 urb->dev = subs->usX2Y->dev; /* we need to set this at each time */
203 if ((err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) { 204 if ((err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
204 snd_printk(KERN_ERR "usb_submit_urb() returned %i\n", err); 205 snd_printk(KERN_ERR "usb_submit_urb() returned %i\n", err);
205 return err; 206 return err;
@@ -300,7 +301,7 @@ static void usX2Y_error_sequence(struct usX2Ydev *usX2Y,
300"Sequence Error!(hcd_frame=%i ep=%i%s;wait=%i,frame=%i).\n" 301"Sequence Error!(hcd_frame=%i ep=%i%s;wait=%i,frame=%i).\n"
301"Most propably some urb of usb-frame %i is still missing.\n" 302"Most propably some urb of usb-frame %i is still missing.\n"
302"Cause could be too long delays in usb-hcd interrupt handling.\n", 303"Cause could be too long delays in usb-hcd interrupt handling.\n",
303 usb_get_current_frame_number(usX2Y->chip.dev), 304 usb_get_current_frame_number(usX2Y->dev),
304 subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out", 305 subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out",
305 usX2Y->wait_iso_frame, urb->start_frame, usX2Y->wait_iso_frame); 306 usX2Y->wait_iso_frame, urb->start_frame, usX2Y->wait_iso_frame);
306 usX2Y_clients_stop(usX2Y); 307 usX2Y_clients_stop(usX2Y);
@@ -313,7 +314,7 @@ static void i_usX2Y_urb_complete(struct urb *urb)
313 314
314 if (unlikely(atomic_read(&subs->state) < state_PREPARED)) { 315 if (unlikely(atomic_read(&subs->state) < state_PREPARED)) {
315 snd_printdd("hcd_frame=%i ep=%i%s status=%i start_frame=%i\n", 316 snd_printdd("hcd_frame=%i ep=%i%s status=%i start_frame=%i\n",
316 usb_get_current_frame_number(usX2Y->chip.dev), 317 usb_get_current_frame_number(usX2Y->dev),
317 subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out", 318 subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out",
318 urb->status, urb->start_frame); 319 urb->status, urb->start_frame);
319 return; 320 return;
@@ -424,7 +425,7 @@ static int usX2Y_urbs_allocate(struct snd_usX2Y_substream *subs)
424 int i; 425 int i;
425 unsigned int pipe; 426 unsigned int pipe;
426 int is_playback = subs == subs->usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK]; 427 int is_playback = subs == subs->usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK];
427 struct usb_device *dev = subs->usX2Y->chip.dev; 428 struct usb_device *dev = subs->usX2Y->dev;
428 429
429 pipe = is_playback ? usb_sndisocpipe(dev, subs->endpoint) : 430 pipe = is_playback ? usb_sndisocpipe(dev, subs->endpoint) :
430 usb_rcvisocpipe(dev, subs->endpoint); 431 usb_rcvisocpipe(dev, subs->endpoint);
@@ -500,7 +501,7 @@ static int usX2Y_urbs_start(struct snd_usX2Y_substream *subs)
500 unsigned long pack; 501 unsigned long pack;
501 if (0 == i) 502 if (0 == i)
502 atomic_set(&subs->state, state_STARTING3); 503 atomic_set(&subs->state, state_STARTING3);
503 urb->dev = usX2Y->chip.dev; 504 urb->dev = usX2Y->dev;
504 urb->transfer_flags = URB_ISO_ASAP; 505 urb->transfer_flags = URB_ISO_ASAP;
505 for (pack = 0; pack < nr_of_packs(); pack++) { 506 for (pack = 0; pack < nr_of_packs(); pack++) {
506 urb->iso_frame_desc[pack].offset = subs->maxpacksize * pack; 507 urb->iso_frame_desc[pack].offset = subs->maxpacksize * pack;
@@ -692,7 +693,7 @@ static int usX2Y_rate_set(struct usX2Ydev *usX2Y, int rate)
692 } 693 }
693 ((char*)(usbdata + i))[0] = ra[i].c1; 694 ((char*)(usbdata + i))[0] = ra[i].c1;
694 ((char*)(usbdata + i))[1] = ra[i].c2; 695 ((char*)(usbdata + i))[1] = ra[i].c2;
695 usb_fill_bulk_urb(us->urb[i], usX2Y->chip.dev, usb_sndbulkpipe(usX2Y->chip.dev, 4), 696 usb_fill_bulk_urb(us->urb[i], usX2Y->dev, usb_sndbulkpipe(usX2Y->dev, 4),
696 usbdata + i, 2, i_usX2Y_04Int, usX2Y); 697 usbdata + i, 2, i_usX2Y_04Int, usX2Y);
697#ifdef OLD_USB 698#ifdef OLD_USB
698 us->urb[i]->transfer_flags = USB_QUEUE_BULK; 699 us->urb[i]->transfer_flags = USB_QUEUE_BULK;
@@ -740,17 +741,17 @@ static int usX2Y_format_set(struct usX2Ydev *usX2Y, snd_pcm_format_t format)
740 alternate = 1; 741 alternate = 1;
741 usX2Y->stride = 4; 742 usX2Y->stride = 4;
742 } 743 }
743 list_for_each(p, &usX2Y->chip.midi_list) { 744 list_for_each(p, &usX2Y->midi_list) {
744 snd_usbmidi_input_stop(p); 745 snd_usbmidi_input_stop(p);
745 } 746 }
746 usb_kill_urb(usX2Y->In04urb); 747 usb_kill_urb(usX2Y->In04urb);
747 if ((err = usb_set_interface(usX2Y->chip.dev, 0, alternate))) { 748 if ((err = usb_set_interface(usX2Y->dev, 0, alternate))) {
748 snd_printk(KERN_ERR "usb_set_interface error \n"); 749 snd_printk(KERN_ERR "usb_set_interface error \n");
749 return err; 750 return err;
750 } 751 }
751 usX2Y->In04urb->dev = usX2Y->chip.dev; 752 usX2Y->In04urb->dev = usX2Y->dev;
752 err = usb_submit_urb(usX2Y->In04urb, GFP_KERNEL); 753 err = usb_submit_urb(usX2Y->In04urb, GFP_KERNEL);
753 list_for_each(p, &usX2Y->chip.midi_list) { 754 list_for_each(p, &usX2Y->midi_list) {
754 snd_usbmidi_input_start(p); 755 snd_usbmidi_input_start(p);
755 } 756 }
756 usX2Y->format = format; 757 usX2Y->format = format;
@@ -955,7 +956,7 @@ static int usX2Y_audio_stream_new(struct snd_card *card, int playback_endpoint,
955 struct snd_pcm *pcm; 956 struct snd_pcm *pcm;
956 int err, i; 957 int err, i;
957 struct snd_usX2Y_substream **usX2Y_substream = 958 struct snd_usX2Y_substream **usX2Y_substream =
958 usX2Y(card)->subs + 2 * usX2Y(card)->chip.pcm_devs; 959 usX2Y(card)->subs + 2 * usX2Y(card)->pcm_devs;
959 960
960 for (i = playback_endpoint ? SNDRV_PCM_STREAM_PLAYBACK : SNDRV_PCM_STREAM_CAPTURE; 961 for (i = playback_endpoint ? SNDRV_PCM_STREAM_PLAYBACK : SNDRV_PCM_STREAM_CAPTURE;
961 i <= SNDRV_PCM_STREAM_CAPTURE; ++i) { 962 i <= SNDRV_PCM_STREAM_CAPTURE; ++i) {
@@ -971,7 +972,7 @@ static int usX2Y_audio_stream_new(struct snd_card *card, int playback_endpoint,
971 usX2Y_substream[SNDRV_PCM_STREAM_PLAYBACK]->endpoint = playback_endpoint; 972 usX2Y_substream[SNDRV_PCM_STREAM_PLAYBACK]->endpoint = playback_endpoint;
972 usX2Y_substream[SNDRV_PCM_STREAM_CAPTURE]->endpoint = capture_endpoint; 973 usX2Y_substream[SNDRV_PCM_STREAM_CAPTURE]->endpoint = capture_endpoint;
973 974
974 err = snd_pcm_new(card, NAME_ALLCAPS" Audio", usX2Y(card)->chip.pcm_devs, 975 err = snd_pcm_new(card, NAME_ALLCAPS" Audio", usX2Y(card)->pcm_devs,
975 playback_endpoint ? 1 : 0, 1, 976 playback_endpoint ? 1 : 0, 1,
976 &pcm); 977 &pcm);
977 if (err < 0) { 978 if (err < 0) {
@@ -987,7 +988,7 @@ static int usX2Y_audio_stream_new(struct snd_card *card, int playback_endpoint,
987 pcm->private_free = snd_usX2Y_pcm_private_free; 988 pcm->private_free = snd_usX2Y_pcm_private_free;
988 pcm->info_flags = 0; 989 pcm->info_flags = 0;
989 990
990 sprintf(pcm->name, NAME_ALLCAPS" Audio #%d", usX2Y(card)->chip.pcm_devs); 991 sprintf(pcm->name, NAME_ALLCAPS" Audio #%d", usX2Y(card)->pcm_devs);
991 992
992 if ((playback_endpoint && 993 if ((playback_endpoint &&
993 0 > (err = snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream, 994 0 > (err = snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream,
@@ -1001,7 +1002,7 @@ static int usX2Y_audio_stream_new(struct snd_card *card, int playback_endpoint,
1001 snd_usX2Y_pcm_private_free(pcm); 1002 snd_usX2Y_pcm_private_free(pcm);
1002 return err; 1003 return err;
1003 } 1004 }
1004 usX2Y(card)->chip.pcm_devs++; 1005 usX2Y(card)->pcm_devs++;
1005 1006
1006 return 0; 1007 return 0;
1007} 1008}
@@ -1013,14 +1014,14 @@ int usX2Y_audio_create(struct snd_card *card)
1013{ 1014{
1014 int err = 0; 1015 int err = 0;
1015 1016
1016 INIT_LIST_HEAD(&usX2Y(card)->chip.pcm_list); 1017 INIT_LIST_HEAD(&usX2Y(card)->pcm_list);
1017 1018
1018 if (0 > (err = usX2Y_audio_stream_new(card, 0xA, 0x8))) 1019 if (0 > (err = usX2Y_audio_stream_new(card, 0xA, 0x8)))
1019 return err; 1020 return err;
1020 if (le16_to_cpu(usX2Y(card)->chip.dev->descriptor.idProduct) == USB_ID_US428) 1021 if (le16_to_cpu(usX2Y(card)->dev->descriptor.idProduct) == USB_ID_US428)
1021 if (0 > (err = usX2Y_audio_stream_new(card, 0, 0xA))) 1022 if (0 > (err = usX2Y_audio_stream_new(card, 0, 0xA)))
1022 return err; 1023 return err;
1023 if (le16_to_cpu(usX2Y(card)->chip.dev->descriptor.idProduct) != USB_ID_US122) 1024 if (le16_to_cpu(usX2Y(card)->dev->descriptor.idProduct) != USB_ID_US122)
1024 err = usX2Y_rate_set(usX2Y(card), 44100); // Lets us428 recognize output-volume settings, disturbs us122. 1025 err = usX2Y_rate_set(usX2Y(card), 44100); // Lets us428 recognize output-volume settings, disturbs us122.
1025 return err; 1026 return err;
1026} 1027}
diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c
index 4b2304c2e02d..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)
@@ -234,7 +235,7 @@ static void i_usX2Y_usbpcm_urb_complete(struct urb *urb)
234 235
235 if (unlikely(atomic_read(&subs->state) < state_PREPARED)) { 236 if (unlikely(atomic_read(&subs->state) < state_PREPARED)) {
236 snd_printdd("hcd_frame=%i ep=%i%s status=%i start_frame=%i\n", 237 snd_printdd("hcd_frame=%i ep=%i%s status=%i start_frame=%i\n",
237 usb_get_current_frame_number(usX2Y->chip.dev), 238 usb_get_current_frame_number(usX2Y->dev),
238 subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out", 239 subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out",
239 urb->status, urb->start_frame); 240 urb->status, urb->start_frame);
240 return; 241 return;
@@ -318,7 +319,7 @@ static int usX2Y_usbpcm_urbs_allocate(struct snd_usX2Y_substream *subs)
318 int i; 319 int i;
319 unsigned int pipe; 320 unsigned int pipe;
320 int is_playback = subs == subs->usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK]; 321 int is_playback = subs == subs->usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK];
321 struct usb_device *dev = subs->usX2Y->chip.dev; 322 struct usb_device *dev = subs->usX2Y->dev;
322 323
323 pipe = is_playback ? usb_sndisocpipe(dev, subs->endpoint) : 324 pipe = is_playback ? usb_sndisocpipe(dev, subs->endpoint) :
324 usb_rcvisocpipe(dev, subs->endpoint); 325 usb_rcvisocpipe(dev, subs->endpoint);
@@ -441,7 +442,7 @@ static int usX2Y_usbpcm_urbs_start(struct snd_usX2Y_substream *subs)
441 unsigned long pack; 442 unsigned long pack;
442 if (0 == u) 443 if (0 == u)
443 atomic_set(&subs->state, state_STARTING3); 444 atomic_set(&subs->state, state_STARTING3);
444 urb->dev = usX2Y->chip.dev; 445 urb->dev = usX2Y->dev;
445 urb->transfer_flags = URB_ISO_ASAP; 446 urb->transfer_flags = URB_ISO_ASAP;
446 for (pack = 0; pack < nr_of_packs(); pack++) { 447 for (pack = 0; pack < nr_of_packs(); pack++) {
447 urb->iso_frame_desc[pack].offset = subs->maxpacksize * (pack + u * nr_of_packs()); 448 urb->iso_frame_desc[pack].offset = subs->maxpacksize * (pack + u * nr_of_packs());
@@ -741,7 +742,7 @@ int usX2Y_hwdep_pcm_new(struct snd_card *card)
741 int err; 742 int err;
742 struct snd_hwdep *hw; 743 struct snd_hwdep *hw;
743 struct snd_pcm *pcm; 744 struct snd_pcm *pcm;
744 struct usb_device *dev = usX2Y(card)->chip.dev; 745 struct usb_device *dev = usX2Y(card)->dev;
745 if (1 != nr_of_packs()) 746 if (1 != nr_of_packs())
746 return 0; 747 return 0;
747 748